yg-team-cli 2.6.4 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +911 -21
- package/dist/cli.js.map +1 -1
- package/dist/index.js +906 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/lib/logger.ts","../src/lib/utils.ts","../src/lib/claude.ts","../src/lib/template-version.ts","../src/lib/module-registry.ts","../src/commands/init.ts","../src/commands/breakdown.ts","../src/commands/dev.ts","../src/commands/add-feature.ts","../src/commands/split-prd.ts","../src/commands/bugfix.ts","../src/commands/accept.ts","../src/commands/add-module.ts","../src/commands/lint.ts","../src/commands/status.ts","../src/commands/detect-deps.ts","../src/commands/sync-memory.ts","../src/commands/check-api.ts","../src/commands/logs.ts","../src/lib/user-config.ts","../src/lib/gitlab-api.ts","../src/commands/update.ts","../src/commands/config.ts","../src/commands/diff.ts","../src/index.ts","../src/cli.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import chalk from 'chalk';\nimport ora, { Ora } from 'ora';\n\n/**\n * 颜色输出类\n */\nexport class Logger {\n private spinner: Ora | null = null;\n\n /**\n * 打印标题(加粗)\n */\n header(text: string): void {\n console.log(chalk.bold(text));\n }\n\n /**\n * 打印成功信息(绿色)\n */\n success(text: string): void {\n console.log(chalk.green('✓'), text);\n }\n\n /**\n * 打印错误信息(红色)\n */\n error(text: string): void {\n console.error(chalk.red('✗'), text);\n }\n\n /**\n * 打印警告信息(黄色)\n */\n warn(text: string): void {\n console.warn(chalk.yellow('⚠'), text);\n }\n\n /**\n * 打印信息(蓝色)\n */\n info(text: string): void {\n console.info(chalk.blue('ℹ'), text);\n }\n\n /**\n * 打印步骤信息\n */\n step(text: string): void {\n console.log(chalk.cyan('→'), text);\n }\n\n /**\n * 打印空行\n */\n newLine(): void {\n console.log('');\n }\n\n /**\n * 打印分隔线\n */\n separator(char = '─', length = 50): void {\n console.log(chalk.gray(char.repeat(length)));\n }\n\n /**\n * 开始加载动画\n */\n startLoading(text: string): Ora {\n this.spinner = ora({\n text,\n color: 'cyan',\n }).start();\n return this.spinner;\n }\n\n /**\n * 更新加载文本\n */\n updateLoading(text: string): void {\n if (this.spinner) {\n this.spinner.text = text;\n }\n }\n\n /**\n * 停止加载并显示成功\n */\n succeedLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.succeed(text);\n this.spinner = null;\n }\n }\n\n /**\n * 停止加载并显示失败\n */\n failLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.fail(text);\n this.spinner = null;\n }\n }\n\n /**\n * 停止加载并显示警告\n */\n warnLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.warn(text);\n this.spinner = null;\n }\n }\n\n /**\n * 停止加载并显示信息\n */\n infoLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.info(text);\n this.spinner = null;\n }\n }\n\n /**\n * 打印表格\n */\n table(headers: string[], rows: string[][]): void {\n const columnWidths = headers.map((h, i) => {\n const maxWidth = Math.max(\n h.length,\n ...rows.map((row) => (row[i] || '').length)\n );\n return maxWidth + 2;\n });\n\n // 打印表头\n const headerRow = headers\n .map((h, i) => chalk.bold(h.padEnd(columnWidths[i])))\n .join('');\n console.log(headerRow);\n\n // 打印分隔线\n const separator = columnWidths.map((w) => '─'.repeat(w)).join('┼');\n console.log(chalk.gray(separator));\n\n // 打印数据行\n rows.forEach((row) => {\n const dataRow = row\n .map((cell, i) => (cell || '').padEnd(columnWidths[i]))\n .join('');\n console.log(dataRow);\n });\n }\n\n /**\n * 打印代码块\n */\n code(code: string, language = ''): void {\n if (language) {\n console.log(chalk.gray(`\\`\\`\\`${language}`));\n }\n console.log(chalk.gray(code));\n if (language) {\n console.log(chalk.gray('```'));\n }\n }\n\n /**\n * 打印列表\n */\n list(items: string[], indent = 2): void {\n items.forEach((item) => {\n console.log(' '.repeat(indent) + chalk.gray('•') + ' ' + item);\n });\n }\n\n /**\n * 打印带标签的文本\n */\n labeled(label: string, text: string, labelColor = 'blue'): void {\n const coloredLabel = chalk[labelColor as keyof typeof chalk](`[${label}]`);\n console.log(`${coloredLabel} ${text}`);\n }\n\n /**\n * 打印调试信息(灰色,仅在 DEBUG 模式下显示)\n */\n debug(text: string): void {\n if (process.env.DEBUG) {\n console.debug(chalk.gray(`[DEBUG] ${text}`));\n }\n }\n}\n\n// 导出单例\nexport const logger = new Logger();\n\n/**\n * 确认提示(用于重要操作)\n */\nexport async function confirm(message: string): Promise<boolean> {\n const inquirer = await import('inquirer');\n const { confirm } = await inquirer.default.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message,\n default: false,\n },\n ]);\n return confirm;\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { glob } from 'glob';\nimport type { Spec } from '../types/index.js';\n\n/**\n * 文件工具类\n */\nexport class FileUtils {\n /**\n * 确保目录存在\n */\n static async ensureDir(dir: string): Promise<void> {\n await fs.ensureDir(dir);\n }\n\n /**\n * 读取文件内容\n */\n static async read(file: string): Promise<string> {\n return await fs.readFile(file, 'utf-8');\n }\n\n /**\n * 写入文件内容(自动创建父目录)\n */\n static async write(file: string, content: string): Promise<void> {\n const dir = path.dirname(file);\n await fs.ensureDir(dir);\n await fs.writeFile(file, content, 'utf-8');\n }\n\n /**\n * 检查文件是否存在\n */\n static async exists(file: string): Promise<boolean> {\n return await fs.pathExists(file);\n }\n\n /**\n * 复制文件\n */\n static async copy(src: string, dest: string): Promise<void> {\n await fs.copy(src, dest);\n }\n\n /**\n * 删除文件或目录\n */\n static async remove(file: string): Promise<void> {\n await fs.remove(file);\n }\n\n /**\n * 移动文件\n */\n static async move(src: string, dest: string): Promise<void> {\n await fs.move(src, dest);\n }\n\n /**\n * 使用 glob 查找文件\n */\n static async findFiles(pattern: string, cwd?: string): Promise<string[]> {\n return await glob(pattern, {\n cwd,\n absolute: false,\n nodir: true,\n });\n }\n\n /**\n * 读取 JSON 文件\n */\n static async readJson<T = any>(file: string): Promise<T> {\n return await fs.readJson(file);\n }\n\n /**\n * 写入 JSON 文件\n */\n static async writeJson(file: string, data: any): Promise<void> {\n await fs.writeJson(file, data, { spaces: 2 });\n }\n\n /**\n * 获取路径的目录名 (ESM 兼容)\n */\n static getDirName(url: string): string {\n return path.dirname(new URL(url).pathname);\n }\n}\n\n/**\n * 字符串工具类\n */\nexport class StringUtils {\n /**\n * 转换为 kebab-case\n */\n static toKebabCase(str: string): string {\n return str\n .toLowerCase()\n .replace(/[\\s_]+/g, '-')\n .replace(/[^\\w\\-]/g, '')\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '');\n }\n\n /**\n * 转换为 PascalCase\n */\n static toPascalCase(str: string): string {\n return str\n .replace(/[-_\\s](\\w)/g, (_, c) => c.toUpperCase())\n .replace(/^\\w/, (c) => c.toUpperCase());\n }\n\n /**\n * 转换为 camelCase\n */\n static toCamelCase(str: string): string {\n const pascal = this.toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n }\n\n /**\n * 转换为 snake_case\n */\n static toSnakeCase(str: string): string {\n return str\n .replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)\n .replace(/^_/, '')\n .replace(/-+/g, '_')\n .replace(/[\\s]+/g, '_');\n }\n\n /**\n * 首字母大写\n */\n static capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n }\n\n /**\n * 截断字符串\n */\n static truncate(str: string, length: number, suffix = '...'): string {\n if (str.length <= length) return str;\n return str.slice(0, length - suffix.length) + suffix;\n }\n\n /**\n * 生成 slug\n */\n static slugify(str: string): string {\n return str\n .toLowerCase()\n .trim()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/[\\s_-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n }\n\n /**\n * 验证项目名称\n */\n static validateProjectName(name: string): boolean {\n return /^[a-z0-9-]+$/.test(name);\n }\n}\n\n/**\n * 数组工具类\n */\nexport class ArrayUtils {\n /**\n * 数组去重\n */\n static unique<T>(arr: T[]): T[] {\n return Array.from(new Set(arr));\n }\n\n /**\n * 数组分组\n */\n static groupBy<T>(arr: T[], keyFn: (item: T) => string): Record<string, T[]> {\n return arr.reduce((result, item) => {\n const key = keyFn(item);\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(item);\n return result;\n }, {} as Record<string, T[]>);\n }\n\n /**\n * 数组分块\n */\n static chunk<T>(arr: T[], size: number): T[][] {\n const chunks: T[][] = [];\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size));\n }\n return chunks;\n }\n\n /**\n * 数组乱序\n */\n static shuffle<T>(arr: T[]): T[] {\n const result = [...arr];\n for (let i = result.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [result[i], result[j]] = [result[j], result[i]];\n }\n return result;\n }\n}\n\n/**\n * 日期工具类\n */\nexport class DateUtils {\n /**\n * 格式化日期\n */\n static format(date: Date = new Date(), format = 'YYYY-MM-DD HH:mm:ss'): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n const seconds = String(date.getSeconds()).padStart(2, '0');\n\n return format\n .replace('YYYY', String(year))\n .replace('MM', month)\n .replace('DD', day)\n .replace('HH', hours)\n .replace('mm', minutes)\n .replace('ss', seconds);\n }\n\n /**\n * 获取相对时间\n */\n static relative(date: Date): string {\n const now = new Date();\n const diff = now.getTime() - date.getTime();\n const seconds = Math.floor(diff / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (days > 7) {\n return DateUtils.format(date, 'YYYY-MM-DD');\n } else if (days > 0) {\n return `${days} 天前`;\n } else if (hours > 0) {\n return `${hours} 小时前`;\n } else if (minutes > 0) {\n return `${minutes} 分钟前`;\n } else {\n return '刚刚';\n }\n }\n}\n\n/**\n * Milestone 信息接口\n */\nexport interface MilestoneInfo {\n title: string;\n todos: string[];\n completedCount: number;\n}\n\n/**\n * Todo 项接口(增强版 - 支持前后端分类)\n */\nexport interface TodoItem {\n raw: string; // 原始文本\n content: string; // 任务内容\n type: 'frontend' | 'backend' | 'integration' | 'general'; // 任务类型\n apiAssociation?: string; // API 关联 (后端任务)\n dependencies?: string[]; // 依赖关系 (联调任务)\n isCompleted: boolean; // 是否完成\n}\n\n/**\n * 增强版 Milestone 信息\n */\nexport interface EnhancedMilestoneInfo {\n title: string;\n todos: TodoItem[];\n frontendTodos: TodoItem[];\n backendTodos: TodoItem[];\n integrationTodos: TodoItem[];\n generalTodos: TodoItem[];\n completedCount: number;\n totalCount: number;\n}\n\n/**\n * Git 工具类\n */\nexport class GitUtils {\n /**\n * 检查是否在 Git 仓库中\n */\n static async isGitRepo(cwd: string = process.cwd()): Promise<boolean> {\n const gitDir = path.join(cwd, '.git');\n return await FileUtils.exists(gitDir);\n }\n\n /**\n * 获取当前分支名\n */\n static async getCurrentBranch(cwd: string = process.cwd()): Promise<string> {\n const { execa } = await import('execa');\n const { stdout } = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {\n cwd,\n });\n return stdout.trim();\n }\n\n /**\n * 获取当前 commit hash\n */\n static async getCurrentCommit(cwd: string = process.cwd()): Promise<string> {\n const { execa } = await import('execa');\n const { stdout } = await execa('git', ['rev-parse', 'HEAD'], { cwd });\n return stdout.trim().slice(0, 7);\n }\n}\n\n/**\n * Spec 解析工具类\n */\nexport class SpecUtils {\n /**\n * 解析 spec 文件\n */\n static async parseSpec(file: string): Promise<Partial<Spec>> {\n const content = await FileUtils.read(file);\n const spec: Partial<Spec> = {};\n\n // 解析标题\n const titleMatch = content.match(/^#\\s+(.+)$/m);\n if (titleMatch) {\n spec.title = titleMatch[1];\n }\n\n // 解析功能名称\n const nameMatch = content.match(/\\*\\*功能名称\\*\\*:\\s*(.+)$/m);\n if (nameMatch) {\n spec.name = nameMatch[1];\n }\n\n // 解析优先级\n const priorityMatch = content.match(/\\*\\*优先级\\*\\*:\\s*(P[0-2])/);\n if (priorityMatch) {\n spec.priority = priorityMatch[1] as 'P0' | 'P1' | 'P2';\n }\n\n // 解析状态\n const statusMatch = content.match(/\\*\\*状态\\*\\*:\\s*(.+)$/m);\n if (statusMatch) {\n spec.status = statusMatch[1] as Spec['status'];\n }\n\n // 解析依赖\n const depSection = content.match(/## 依赖关系\\s+([\\s\\S]+?)##/m);\n if (depSection) {\n const depMatches = depSection[1].matchAll(/- \\[([ x])\\]\\s*(.+)$/gm);\n spec.dependencies = Array.from(depMatches).map((m) => ({\n completed: m[1] === 'x',\n name: m[2],\n }));\n }\n\n return spec;\n }\n\n /**\n * 解析里程碑信息\n */\n static parseMilestones(content: string): MilestoneInfo[] {\n const milestones: MilestoneInfo[] = [];\n const lines = content.split('\\n');\n let currentMilestone: MilestoneInfo | null = null;\n let inMilestone = false;\n\n for (const line of lines) {\n if (line.match(/^###\\s+Milestone\\s+\\d+:/)) {\n if (currentMilestone) {\n milestones.push(currentMilestone);\n }\n const title = line.replace(/^###\\s+/, '').trim();\n currentMilestone = { title, todos: [], completedCount: 0 };\n inMilestone = true;\n continue;\n }\n\n if (inMilestone && currentMilestone) {\n if (line.match(/^###\\s+Milestone/)) {\n milestones.push(currentMilestone);\n currentMilestone = null;\n continue;\n }\n\n const todoMatch = line.match(/^-\\s+\\[([ xX])\\]\\s*(.+)/);\n if (todoMatch) {\n const isCompleted = todoMatch[1].toLowerCase() === 'x';\n if (isCompleted) {\n currentMilestone.completedCount++;\n }\n currentMilestone.todos.push(todoMatch[2].trim());\n }\n }\n }\n\n if (currentMilestone) {\n milestones.push(currentMilestone);\n }\n\n return milestones;\n }\n\n /**\n * 解析增强版里程碑信息(支持 [F]/[B]/[I] 前缀分类)\n */\n static parseMilestonesEnhanced(content: string): EnhancedMilestoneInfo[] {\n const milestones: EnhancedMilestoneInfo[] = [];\n const lines = content.split('\\n');\n let currentMilestone: EnhancedMilestoneInfo | null = null;\n let inMilestone = false;\n\n for (const line of lines) {\n if (line.match(/^###\\s+Milestone\\s+\\d+:/)) {\n if (currentMilestone) {\n currentMilestone.totalCount = currentMilestone.todos.length;\n milestones.push(currentMilestone);\n }\n const title = line.replace(/^###\\s+/, '').trim();\n currentMilestone = {\n title,\n todos: [],\n frontendTodos: [],\n backendTodos: [],\n integrationTodos: [],\n generalTodos: [],\n completedCount: 0,\n totalCount: 0,\n };\n inMilestone = true;\n continue;\n }\n\n if (inMilestone && currentMilestone) {\n if (line.match(/^###\\s+Milestone/)) {\n currentMilestone.totalCount = currentMilestone.todos.length;\n milestones.push(currentMilestone);\n currentMilestone = null;\n const title = line.replace(/^###\\s+/, '').trim();\n currentMilestone = {\n title,\n todos: [],\n frontendTodos: [],\n backendTodos: [],\n integrationTodos: [],\n generalTodos: [],\n completedCount: 0,\n totalCount: 0,\n };\n continue;\n }\n\n const todoMatch = line.match(/^-\\s+\\[([ xX])\\]\\s*(\\[[FBIN]\\])?\\s*(.+)/);\n if (todoMatch) {\n const isCompleted = todoMatch[1].toLowerCase() === 'x';\n const prefix = todoMatch[2]?.trim() || '';\n const rawContent = todoMatch[3].trim();\n\n let type: TodoItem['type'] = 'general';\n let apiAssociation: string | undefined;\n let dependencies: string[] | undefined;\n\n // 解析前缀确定任务类型\n if (prefix === '[F]') {\n type = 'frontend';\n } else if (prefix === '[B]') {\n type = 'backend';\n // 解析 API 关联\n const apiMatch = rawContent.match(/\\(关联 API:\\s*`([^`]+)`\\)/);\n if (apiMatch) {\n apiAssociation = apiMatch[1];\n }\n } else if (prefix === '[I]') {\n type = 'integration';\n // 解析依赖关系\n const depMatch = rawContent.match(/\\(依赖:\\s*([^)]+)\\)/);\n if (depMatch) {\n dependencies = depMatch[1]\n .split(',')\n .map((d) => d.trim())\n .filter((d) => d.length > 0);\n }\n }\n\n const todoItem: TodoItem = {\n raw: line.trim(),\n content: rawContent\n .replace(/\\s*\\(关联 API:\\s*`[^`]+`\\)/, '')\n .replace(/\\s*\\(依赖:\\s*[^)]+\\)/, '')\n .trim(),\n type,\n apiAssociation,\n dependencies,\n isCompleted,\n };\n\n currentMilestone.todos.push(todoItem);\n if (isCompleted) {\n currentMilestone.completedCount++;\n }\n\n // 按类型分类\n switch (type) {\n case 'frontend':\n currentMilestone.frontendTodos.push(todoItem);\n break;\n case 'backend':\n currentMilestone.backendTodos.push(todoItem);\n break;\n case 'integration':\n currentMilestone.integrationTodos.push(todoItem);\n break;\n default:\n currentMilestone.generalTodos.push(todoItem);\n }\n }\n }\n }\n\n if (currentMilestone) {\n currentMilestone.totalCount = currentMilestone.todos.length;\n milestones.push(currentMilestone);\n }\n\n return milestones;\n }\n\n /**\n * 解析增强版里程碑(向后兼容版 - 优先尝试增强解析,失败回退到简单解析)\n */\n static parseMilestonesEnhancedWithFallback(content: string): {\n enhanced: EnhancedMilestoneInfo[];\n isEnhanced: boolean;\n } {\n const enhanced = this.parseMilestonesEnhanced(content);\n // 检查是否包含增强格式的任务\n const hasEnhancedFormat = enhanced.some((m) =>\n m.todos.some(\n (t) => t.type !== 'general' || t.apiAssociation || t.dependencies\n )\n );\n return { enhanced, isEnhanced: hasEnhancedFormat };\n }\n\n /**\n * 解析 spec 状态(基于进度动态推导)\n */\n static parseSpecStatus(content: string): '未开始' | '进行中' | '已拆分' | '已完成' {\n const milestones = this.parseMilestones(content);\n \n if (milestones.length > 0) {\n const totalTodos = milestones.reduce((sum, m) => sum + m.todos.length, 0);\n const completedTodos = milestones.reduce((sum, m) => sum + m.completedCount, 0);\n\n if (totalTodos > 0) {\n if (completedTodos === totalTodos) return '已完成';\n if (completedTodos > 0) return '进行中';\n }\n return '已拆分';\n }\n\n const statusMatch = content.match(/状态.*[::]\\s*(.+)/);\n if (statusMatch) {\n const status = statusMatch[1].replace(/\\*\\*/g, '').trim();\n if (status.includes('已完成')) return '已完成';\n if (status.includes('进行中')) return '进行中';\n if (status.includes('已拆分')) return '已拆分';\n }\n return '未开始';\n }\n\n /**\n * 获取进度字符串\n */\n static getProgress(content: string): string {\n const milestones = this.parseMilestones(content);\n if (milestones.length === 0) return '-';\n \n const totalTodos = milestones.reduce((sum, m) => sum + m.todos.length, 0);\n const completedTodos = milestones.reduce((sum, m) => sum + m.completedCount, 0);\n \n if (totalTodos === 0) return '-';\n return `${completedTodos}/${totalTodos}`;\n }\n\n /**\n * 获取带图标的状态\n */\n static getStatusWithIcon(status: string): string {\n if (status.includes('已完成')) return '✓ 已完成';\n if (status.includes('进行中')) return '⟳ 进行中';\n if (status.includes('已拆分')) return '◉ 已拆分';\n return '○ 未开始';\n }\n\n /**\n * 获取 spec 状态 (原始版本兼容)\n */\n static async getSpecStatus(file: string): Promise<string> {\n try {\n const spec = await this.parseSpec(file);\n return spec.status || '未知';\n } catch {\n return '错误';\n }\n }\n}\n\n/**\n * 模板工具类\n */\nexport class TemplateUtils {\n /**\n * 渲染模板(简单变量替换)\n */\n static render(template: string, data: Record<string, any>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) => {\n return data[key] !== undefined ? String(data[key]) : '';\n });\n }\n\n /**\n * 渲染 Handlebars 模板\n */\n static async renderHandlebars(\n template: string,\n data: Record<string, any>\n ): Promise<string> {\n const Handlebars = await import('handlebars');\n const compiled = Handlebars.default.compile(template);\n return compiled(data);\n }\n}\n\n/**\n * 验证工具类\n */\nexport class ValidationUtils {\n /**\n * 验证项目名称\n */\n static validateProjectName(name: string): boolean {\n return /^[a-z0-9-]+$/.test(name);\n }\n\n /**\n * 验证邮箱\n */\n static validateEmail(email: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n }\n\n /**\n * 验证 URL\n */\n static validateUrl(url: string): boolean {\n try {\n new URL(url);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import { execa } from 'execa';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport os from 'os';\nimport { logger } from './logger.js';\nimport { FileUtils, StringUtils } from './utils.js';\n\n/**\n * Claude AI 集成类\n */\nexport class ClaudeAI {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n private verbose: boolean;\n\n constructor(verbose = false) {\n this.verbose = verbose;\n }\n\n async checkInstalled(): Promise<boolean> {\n try {\n // 使用 which 检查,更轻量且不会触发 CLI 的任何初始化逻辑\n const { exitCode } = await execa('which', ['claude'], { stdio: 'ignore', reject: false });\n return exitCode === 0;\n } catch {\n return false;\n }\n }\n\n /**\n * 获取 Claude 版本\n */\n async getVersion(): Promise<string> {\n try {\n const { stdout } = await execa('claude', ['--version'], { stdio: 'pipe' });\n return stdout.trim();\n } catch {\n throw new Error('无法获取 Claude 版本');\n }\n }\n\n /**\n * 发送 prompt 到 Claude\n */\n async prompt(promptText: string, options?: PromptOptions): Promise<string> {\n // 创建临时文件来存储 prompt(避免命令行参数过长)\n const tempDir = os.tmpdir();\n const tempFile = path.join(tempDir, `team-cli-prompt-${Date.now()}.txt`);\n\n try {\n // 构建最终的 prompt(包含上下文文件内容)\n let finalPrompt = promptText;\n const validContextFiles: string[] = [];\n\n // 验证并读取上下文文件\n if (options?.contextFiles && options.contextFiles.length > 0) {\n for (const file of options.contextFiles) {\n const exists = await FileUtils.exists(file);\n if (exists) {\n validContextFiles.push(file);\n } else {\n logger.warn(`上下文文件不存在,已跳过: ${file}`);\n }\n }\n\n // 将上下文文件内容添加到 prompt 开头\n if (validContextFiles.length > 0) {\n const contextParts: string[] = [];\n for (const file of validContextFiles) {\n try {\n const content = await FileUtils.read(file);\n const fileName = path.basename(file);\n contextParts.push(`## Context from ${fileName}\\n\\n${content}`);\n } catch (error) {\n logger.warn(`无法读取文件 ${file},已跳过`);\n }\n }\n\n if (contextParts.length > 0) {\n finalPrompt = `${contextParts.join('\\n\\n---\\n\\n')}\\n\\n---\\n\\n${promptText}`;\n }\n }\n }\n\n // 将 prompt 写入临时文件\n await fs.writeFile(tempFile, finalPrompt, 'utf-8');\n\n // 使用 -p 参数以 print 模式运行 Claude(非交互式,直接输出结果)\n // 通过 stdin 传递 prompt 内容,避免命令行参数过长\n // 添加 --dangerously-skip-permissions 跳过权限确认\n const result = await execa('claude', ['--dangerously-skip-permissions', '-p'], {\n input: finalPrompt, // 通过 stdin 传递 prompt\n timeout: options?.timeout || 300000, // 5 分钟超时\n maxBuffer: 1024 * 1024 * 10, // 10MB buffer\n });\n\n return result.stdout || '';\n } finally {\n // 清理临时文件\n try {\n await fs.remove(tempFile);\n } catch {\n // 忽略清理失败\n }\n }\n }\n\n /**\n * 使用 prompt 模板和参数发送请求\n */\n async promptWithTemplate(\n template: string,\n data: Record<string, any>,\n options?: PromptOptions\n ): Promise<string> {\n // 简单的模板替换\n let promptText = template;\n for (const [key, value] of Object.entries(data)) {\n const regex = new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g');\n promptText = promptText.replace(regex, String(value));\n }\n\n return await this.prompt(promptText, options);\n }\n\n /**\n * 启动交互式会话\n */\n async runTerminal(promptText: string): Promise<void> {\n logger.info('正在启动交互式 Claude 会话...');\n\n try {\n // 仅保留最核心的参数,避免多余参数干扰 CLI 启动\n await execa('claude', ['--dangerously-skip-permissions', promptText], {\n stdio: 'inherit',\n env: { ...process.env, FORCE_COLOR: '1' }\n });\n } catch (error: any) {\n if (error.signal !== 'SIGINT') {\n throw error;\n }\n }\n }\n\n /**\n * 发送对话(支持上下文)\n */\n async chat(messages: ChatMessage[], options?: PromptOptions): Promise<string> {\n // 构建完整的 prompt\n const fullPrompt = messages\n .map((msg) => {\n const role = msg.role === 'system' ? '系统指令' : `${msg.role === 'user' ? '用户' : '助手'}`;\n return `[${role}]: ${msg.content}`;\n })\n .join('\\n\\n');\n\n // 使用 -p 参数以 print 模式运行 Claude,通过 stdin 传递 prompt\n // 添加 --dangerously-skip-permissions 跳过权限确认\n const result = await execa('claude', ['--dangerously-skip-permissions', '-p'], {\n input: fullPrompt, // 通过 stdin 传递 prompt\n timeout: options?.timeout || 300000,\n maxBuffer: 1024 * 1024 * 10,\n });\n\n return result.stdout || '';\n }\n\n /**\n * 分析代码\n */\n async analyzeCode(code: string, language: string, question?: string): Promise<string> {\n const prompt = `请分析以下 ${language} 代码:${question ? `并回答:${question}` : ''}\n\n\\`\\`\\`${language}\n${code}\n\\`\\`\\`\n\n请提供:\n1. 代码功能概述\n2. 潜在问题\n3. 改进建议\n`;\n\n return await this.prompt(prompt);\n }\n\n /**\n * 生成代码\n */\n async generateCode(\n description: string,\n language: string,\n context?: string\n ): Promise<string> {\n let prompt = `请用 ${language} 编写代码实现以下功能:\\n\\n${description}\\n\\n`;\n\n if (context) {\n prompt += `参考上下文:\\n\\n${context}\\n\\n`;\n }\n\n prompt += `要求:\n1. 代码简洁易读\n2. 包含必要的注释\n3. 遵循最佳实践\n4. 只返回代码,不要额外解释\n`;\n\n return await this.prompt(prompt);\n }\n\n /**\n * 审查代码\n */\n async reviewCode(code: string, language: string): Promise<CodeReviewResult> {\n const prompt = `请审查以下 ${language} 代码,提供详细反馈:\n\n\\`\\`\\`${language}\n${code}\n\\`\\`\\`\n\n请按以下格式回复:\n## 发现的问题\n- [严重程度] 问题描述\n\n## 改进建议\n- 建议内容\n\n## 亮点\n- 做得好的地方\n\n请用 JSON 格式回复:\n{\n \"issues\": [{\"severity\": \"high|medium|low\", \"message\": \"问题描述\"}],\n \"suggestions\": [\"建议1\", \"建议2\"],\n \"highlights\": [\"亮点1\", \"亮点2\"]\n}\n`;\n\n const response = await this.prompt(prompt);\n try {\n // 尝试从响应中提取 JSON\n const jsonMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n return JSON.parse(jsonMatch[0]);\n }\n } catch {\n // 如果解析失败,返回默认结构\n }\n\n return {\n issues: [],\n suggestions: [response],\n highlights: [],\n };\n }\n\n /**\n * 生成 Spec 文档\n */\n async generateSpec(\n featureName: string,\n description: string,\n projectContext: string,\n dependencies?: string[]\n ): Promise<string> {\n let prompt = `Role: Senior Fullstack Developer\n\n你是一个资深的全栈工程师,现在需要为一个新功能生成规格文档(Spec)。\n\n## 功能名称\n${featureName}\n\n## 功能描述\n${description}\n`;\n\n if (dependencies && dependencies.length > 0) {\n prompt += `\n## 依赖功能\n此功能依赖以下已完成的功能:${dependencies.join('、')}\n`;\n }\n\n prompt += `\n## 项目技术栈\n后端: Java 17 + Spring Boot 3 + MyBatis Plus + MySQL 8.0\n前端: Next.js 14 (App Router) + TypeScript + Tailwind CSS\n\n## 项目当前状态\n${projectContext}\n\n## 任务\n请根据功能描述,生成一个完整的功能规格文档 Spec。\n\n## Spec 文档格式要求\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: [功能中文名]\n**优先级**: P0/P1/P2 (根据功能重要性判断)\n**预估工时**: X 天 (根据复杂度评估:简单1-2天,中等3-5天,复杂5-10天)\n**状态**: 待拆分\n**创建日期**: {{DATE}}\n\n## 依赖关系\n**前置依赖**:\n${dependencies ? dependencies.map((d) => `- [x] ${d}`).join('\\n') : '- (无)'}\n\n**被依赖于**:\n- (自动生成,表示哪些 spec 依赖本功能)\n\n## 背景与目标\n[根据功能描述,简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n列出 3-8 个主要功能点,每个功能点用一句话描述。\n\n## 技术设计\n### API 设计\n列出主要的 API 端点,格式:\n- \\`METHOD /api/path\\` - 简短说明\n\n### 数据模型\n列出需要的数据表,格式:\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n> 注: 使用 \\`team-cli breakdown ${StringUtils.toKebabCase(featureName)}.md\\` 拆分此 spec 为 milestones 和 todos\n\n----\n*生成于: {{TIMESTAMP}} by Claude*\n\\`\\`\\`\n\n## 注意事项\n1. 只生成 Spec 文档,不要实现任何代码\n2. 优先级判断标准:\n - P0: 核心功能,阻塞其他功能\n - P1: 重要功能,影响用户体验\n - P2: 增强功能,锦上添花\n3. 工时评估标准:\n - 简单功能: 1-2 天\n - 中等功能: 3-5 天\n - 复杂功能: 5-10 天\n4. 功能点要具体可执行,避免过于抽象\n5. API 和数据模型要符合实际技术栈\n`;\n\n return await this.prompt(prompt, { timeout: 180000 });\n }\n\n /**\n * 生成 Bugfix 报告\n */\n async generateBugfixReport(\n bugDescription: string,\n reproductionSteps: string[],\n projectContext: string\n ): Promise<string> {\n const prompt = `Role: Senior Fullstack Developer\n\n用户报告了一个 Bug,需要你生成 Bugfix 规格文档。\n\n## Bug 描述\n${bugDescription}\n\n## 复现步骤\n${reproductionSteps.map((step, i) => `${i + 1}. ${step}`).join('\\n')}\n\n## 项目当前状态\n${projectContext}\n\n## 任务\n请生成一个完整的 Bugfix 报告,包括:\n1. 问题分析\n2. 根本原因推测\n3. 修复建议\n4. 测试计划\n`;\n\n return await this.prompt(prompt, { timeout: 120000 });\n }\n}\n\n/**\n * Prompt 选项\n */\nexport interface PromptOptions {\n contextFiles?: string[];\n timeout?: number;\n model?: string;\n}\n\n/**\n * 聊天消息\n */\nexport interface ChatMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\n/**\n * 代码审查结果\n */\nexport interface CodeReviewResult {\n issues: Array<{\n severity: 'high' | 'medium' | 'low';\n message: string;\n }>;\n suggestions: string[];\n highlights: string[];\n}\n\n// 导出单例\nexport const claudeAI = new ClaudeAI();\n","import { execa } from 'execa';\nimport path from 'path';\nimport { FileUtils } from './utils.js';\nimport { logger } from './logger.js';\n\n/**\n * 模板类型\n */\nexport type TemplateType = 'frontend' | 'backend';\n\n/**\n * 模板信息接口\n */\nexport interface TemplateInfo {\n type: TemplateType;\n repository: string;\n currentCommit?: string;\n currentTag?: string;\n latestCommit?: string;\n latestTag?: string;\n needsUpdate: boolean;\n}\n\n/**\n * 模板版本信息接口\n */\nexport interface TemplateVersionInfo {\n commit: string;\n tag?: string;\n branch?: string;\n lastUpdate?: string;\n}\n\n/**\n * 模板配置接口\n */\nexport interface TemplateConfig {\n frontend: {\n repository: string;\n commit?: string;\n tag?: string;\n branch?: string;\n lastUpdate?: string;\n };\n backend: {\n repository: string;\n commit?: string;\n tag?: string;\n branch?: string;\n lastUpdate?: string;\n };\n}\n\n/**\n * 默认模板配置\n */\nconst DEFAULT_TEMPLATES: TemplateConfig = {\n frontend: {\n repository: 'git@gitlab.yungu-inc.org:static/fe-tpl-ai.git',\n },\n backend: {\n repository: 'git@gitlab.yungu-inc.org:yungu-app/java-scaffold-template.git',\n },\n};\n\n/**\n * 获取项目配置文件路径\n */\nfunction getConfigPath(projectPath: string): string {\n return path.join(projectPath, '.team-cli', 'template.json');\n}\n\n/**\n * 读取项目的模板配置\n */\nexport async function readTemplateConfig(projectPath: string): Promise<TemplateConfig | null> {\n const configPath = getConfigPath(projectPath);\n const exists = await FileUtils.exists(configPath);\n\n if (!exists) {\n return null;\n }\n\n try {\n const content = await FileUtils.read(configPath);\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\n/**\n * 保存项目的模板配置\n */\nexport async function saveTemplateConfig(projectPath: string, config: TemplateConfig): Promise<void> {\n const configDir = path.join(projectPath, '.team-cli');\n await FileUtils.ensureDir(configDir);\n\n const configPath = getConfigPath(projectPath);\n const content = JSON.stringify(config, null, 2);\n await FileUtils.write(configPath, content);\n}\n\n/**\n * 初始化模板配置\n */\nexport async function initTemplateConfig(projectPath: string): Promise<void> {\n const config = await readTemplateConfig(projectPath);\n\n if (config) {\n return; // 已存在配置\n }\n\n // 保存当前使用的模板信息\n await saveTemplateConfig(projectPath, DEFAULT_TEMPLATES);\n}\n\n/**\n * 获取远程仓库的最新 commit\n */\nexport async function getLatestCommit(repository: string): Promise<string> {\n try {\n // 使用 git ls-remote 获取最新 commit\n const { stdout } = await execa('git', ['ls-remote', repository, 'HEAD'], {\n stdio: 'pipe',\n });\n\n const commit = stdout.split('\\t')[0];\n return commit;\n } catch (error) {\n logger.debug(`获取 ${repository} 最新 commit 失败: ${error}`);\n return '';\n }\n}\n\n/**\n * 获取远程仓库的最新 tag\n */\nexport async function getLatestTag(repository: string): Promise<string> {\n try {\n // 获取所有 tags 并按版本排序\n const { stdout } = await execa(\n 'git',\n ['ls-remote', '--tags', repository],\n {\n stdio: 'pipe',\n }\n );\n\n const tags = stdout\n .split('\\n')\n .filter((line) => line.includes('refs/tags/') && !line.includes('^{}'))\n .map((line) => {\n const [, ref] = line.split('\\t');\n return ref.replace('refs/tags/', '');\n })\n .filter((tag) => /^v?\\d+\\.\\d+\\.\\d+/.test(tag))\n .sort((a, b) => {\n // 简单的版本排序\n const va = a.replace(/^v/, '').split('.').map(Number);\n const vb = b.replace(/^v/, '').split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n if ((va[i] || 0) > (vb[i] || 0)) return 1;\n if ((va[i] || 0) < (vb[i] || 0)) return -1;\n }\n return 0;\n });\n\n return tags[tags.length - 1] || '';\n } catch (error) {\n logger.debug(`获取 ${repository} 最新 tag 失败: ${error}`);\n return '';\n }\n}\n\n/**\n * 检查模板是否需要更新\n */\nexport async function checkTemplateUpdate(\n projectPath: string,\n type: TemplateType\n): Promise<TemplateInfo | null> {\n const config = await readTemplateConfig(projectPath);\n\n if (!config || !config[type]) {\n return null;\n }\n\n const repository = config[type].repository;\n const currentCommit = config[type].commit;\n const currentTag = config[type].tag;\n\n // 获取最新版本\n const latestCommit = await getLatestCommit(repository);\n const latestTag = await getLatestTag(repository);\n\n if (!latestCommit) {\n return null;\n }\n\n // 判断是否需要更新\n const needsUpdate = currentCommit && currentCommit !== latestCommit;\n\n return {\n type,\n repository,\n currentCommit,\n currentTag,\n latestCommit,\n latestTag,\n needsUpdate: needsUpdate || false,\n };\n}\n\n/**\n * 更新模板配置中的版本信息\n */\nexport async function updateTemplateVersion(\n projectPath: string,\n type: TemplateType,\n commit: string,\n options?: {\n tag?: string;\n branch?: string;\n }\n): Promise<void> {\n const config = await readTemplateConfig(projectPath);\n\n if (!config) {\n return;\n }\n\n config[type].commit = commit;\n if (options?.tag) {\n config[type].tag = options.tag;\n }\n if (options?.branch) {\n config[type].branch = options.branch;\n }\n config[type].lastUpdate = new Date().toISOString();\n\n await saveTemplateConfig(projectPath, config);\n}\n\n/**\n * 获取默认模板配置\n */\nexport function getDefaultTemplates(): TemplateConfig {\n // 返回深拷贝以避免修改原对象\n return {\n frontend: { ...DEFAULT_TEMPLATES.frontend },\n backend: { ...DEFAULT_TEMPLATES.backend },\n };\n}\n","import path from 'path';\nimport { FileUtils } from './utils.js';\n\nexport interface CommonModule {\n id: string;\n name: string;\n description: string;\n type: 'local' | 'remote';\n specs: string[]; \n mcpServer?: string;\n backendFragments?: { source: string; target: string }[]; \n frontendFragments?: { source: string; target: string }[];\n dependencies?: string[];\n}\n\nexport class ModuleManager {\n private static readonly MODULES: CommonModule[] = [\n // ========== 云谷公共模块 (新增) ==========\n {\n id: 'yungu-sso',\n name: 'SSO 单点登录',\n description: 'CAS单点登录集成、Token验证、会话管理',\n type: 'local',\n specs: ['yungu-sso/spec.md'],\n backendFragments: [\n // Config\n {\n source: 'yungu/sso/config/CasConfig.java',\n target: 'config/yungu/sso/CasConfig.java',\n },\n {\n source: 'yungu/sso/config/LoginClientConfig.java',\n target: 'config/yungu/sso/LoginClientConfig.java',\n },\n // Filter\n {\n source: 'yungu/sso/filter/AuthFilter.java',\n target: 'config/yungu/sso/filter/AuthFilter.java',\n },\n // Interceptor\n {\n source: 'yungu/sso/intercepter/CasLoginInterceptor.java',\n target: 'common/yungu/sso/intercepter/CasLoginInterceptor.java',\n },\n {\n source: 'yungu/sso/intercepter/UserContextInterceptor.java',\n target: 'common/yungu/sso/intercepter/UserContextInterceptor.java',\n },\n // UserContext\n {\n source: 'yungu/sso/common/UserContext.java',\n target: 'common/yungu/sso/UserContext.java',\n },\n {\n source: 'yungu/sso/common/domain/UserBaseInfo.java',\n target: 'common/yungu/sso/domain/UserBaseInfo.java',\n },\n {\n source: 'yungu/sso/common/domain/UserAccount.java',\n target: 'common/yungu/sso/domain/UserAccount.java',\n },\n // Config classes\n {\n source: 'yungu/sso/config/InterceptorConfiguration.java',\n target: 'config/yungu/sso/InterceptorConfiguration.java',\n },\n ],\n dependencies: ['org.yungu:login-client'],\n },\n {\n id: 'yungu-user-context',\n name: '用户上下文 (UserContext)',\n description: 'RequestScope级别的用户信息获取,支持多身份和Mock',\n type: 'local',\n specs: ['yungu-user-context/spec.md'],\n backendFragments: [\n {\n source: 'yungu/UserContext.java',\n target: 'common/yungu/UserContext.java',\n },\n {\n source: 'yungu/domain/UserBaseInfo.java',\n target: 'common/yungu/domain/UserBaseInfo.java',\n },\n {\n source: 'yungu/domain/UserAccount.java',\n target: 'common/yungu/domain/UserAccount.java',\n },\n ],\n dependencies: ['org.yungu:login-client'],\n },\n {\n id: 'yungu-auth',\n name: '用户认证与鉴权',\n description: 'CAS单点登录集成、用户上下文拦截器',\n type: 'local',\n specs: ['yungu-auth/spec.md'],\n requires: ['yungu-user-context'],\n backendFragments: [\n {\n source: 'yungu/intercepter/UserContextInterceptor.java',\n target: 'common/yungu/intercepter/UserContextInterceptor.java',\n },\n {\n source: 'yungu/config/InterceptorConfiguration.java',\n target: 'config/yungu/InterceptorConfiguration.java',\n },\n ],\n dependencies: ['org.yungu:login-client', 'org.yungu:acl-api'],\n },\n {\n id: 'yungu-managers',\n name: '通用服务封装',\n description: '用户服务、学校服务等Dubbo服务调用封装',\n type: 'local',\n specs: ['yungu-managers/spec.md'],\n backendFragments: [\n {\n source: 'yungu/managers/UserServiceManager.java',\n target: 'common/yungu/managers/UserServiceManager.java',\n },\n {\n source: 'yungu/managers/SchoolManager.java',\n target: 'common/yungu/managers/SchoolManager.java',\n },\n ],\n dependencies: ['org.yungu:user-service-api'],\n },\n {\n id: 'yungu-utils',\n name: '工具类模块',\n description: '通用工具类 (CommonUtils等)',\n type: 'local',\n specs: ['yungu-utils/spec.md'],\n backendFragments: [\n {\n source: 'yungu/utils/CommonUtils.java',\n target: 'common/yungu/utils/CommonUtils.java',\n },\n ],\n },\n {\n id: 'yungu-logging',\n name: '日志与监控',\n description: '方法耗时日志记录 (LogAspect)',\n type: 'local',\n specs: ['yungu-logging/spec.md'],\n backendFragments: [\n {\n source: 'yungu/config/LogAspect.java',\n target: 'config/yungu/LogAspect.java',\n },\n ],\n },\n {\n id: 'yungu-i18n',\n name: '国际化支持',\n description: '中英文切换、多语言枚举',\n type: 'local',\n specs: ['yungu-i18n/spec.md'],\n requires: ['yungu-user-context'],\n backendFragments: [\n {\n source: 'yungu/enums/LanguageEnum.java',\n target: 'common/yungu/enums/LanguageEnum.java',\n },\n {\n source: 'yungu/constant/LanguageConstant.java',\n target: 'common/yungu/constant/LanguageConstant.java',\n },\n ],\n },\n // ========== 原有模块 ==========\n {\n id: 'acl',\n name: 'ACL (Access Control List)',\n description: '基于角色的访问控制模块(本地模板版)',\n type: 'local',\n specs: ['acl/spec.md'],\n backendFragments: [\n {\n source: 'acl/backend/AclResultCode.java',\n target: 'common/enums/AclResultCode.java',\n },\n {\n source: 'acl/backend/RequiredPermission.java',\n target: 'common/annotation/RequiredPermission.java',\n },\n ],\n },\n {\n id: 'permission-remote',\n name: '权限管理 (远程 MCP 版)',\n description: '从 api-metadata 实时获取最新权限接口定义并生成代码',\n type: 'remote',\n mcpServer: 'api-metadata',\n specs: ['permission-remote/spec.md'],\n },\n {\n id: 'audit-log',\n name: '审计日志 (Audit Log)',\n description: '记录用户操作日志,支持 AOP 自动拦截和异步存储',\n type: 'local',\n specs: ['audit-log/spec.md'],\n },\n ];\n\n /**\n * 获取所有可用模块\n */\n static getAvailableModules(): CommonModule[] {\n return [...this.MODULES];\n }\n\n /**\n * 根据 ID 获取模块\n */\n static getModuleById(id: string): CommonModule | undefined {\n return this.MODULES.find((m) => m.id === id);\n }\n\n /**\n * 注入模块到项目,返回新增文件列表\n */\n static async injectModule(\n projectPath: string,\n moduleId: string,\n templatesDir: string\n ): Promise<string[]> {\n const module = this.getModuleById(moduleId);\n if (!module) return [];\n\n const addedFiles: string[] = [];\n\n // 1. 注入 Specs\n for (const specRelPath of module.specs) {\n const sourcePath = path.join(templatesDir, 'modules', specRelPath);\n const targetPath = path.join(projectPath, 'docs/specs', path.basename(specRelPath));\n \n // 对于远程模块,如果模板不存在,生成一个基础占位符\n if (await FileUtils.exists(sourcePath)) {\n await FileUtils.copy(sourcePath, targetPath);\n addedFiles.push(path.relative(projectPath, targetPath));\n } else if (module.type === 'remote') {\n await this.generateRemoteSpecPlaceholder(targetPath, module);\n addedFiles.push(path.relative(projectPath, targetPath));\n }\n }\n\n // 2. 注入 Backend Fragments (放在 org.yungu.common 包下,表示外部公共依赖)\n if (module.type === 'local' && module.backendFragments) {\n const backendJavaDir = path.join(projectPath, 'backend/src/main/java');\n // 使用固定的 org.yungu.common 包路径,与团队现有项目保持一致\n const commonBasePath = path.join(backendJavaDir, 'org/yungu/common');\n \n for (const fragment of module.backendFragments) {\n const sourcePath = path.join(templatesDir, 'modules', fragment.source);\n const targetPath = path.join(commonBasePath, fragment.target);\n \n if (await FileUtils.exists(sourcePath)) {\n await FileUtils.ensureDir(path.dirname(targetPath));\n // 读取源文件并替换 package 声明\n let content = await FileUtils.read(sourcePath);\n const targetPackage = 'org.yungu.common.' + path.dirname(fragment.target).replace(/\\//g, '.');\n content = content.replace(/^package\\s+[^;]+;/m, `package ${targetPackage};`);\n await FileUtils.write(targetPath, content);\n addedFiles.push(path.relative(projectPath, targetPath));\n }\n }\n } else if (module.type === 'remote') {\n // 远程模块的代码生成逻辑将由 init 命令中的专用步骤处理\n }\n\n return addedFiles;\n }\n\n /**\n * 生成远程模块的 Spec 占位符\n */\n private static async generateRemoteSpecPlaceholder(targetPath: string, module: CommonModule): Promise<void> {\n const content = `# ${module.name} (Remote)\n\n## 功能概述\n该模块通过远程 MCP 服务 \\`${module.mcpServer}\\` 获取实时元数据。\n\n## 使用说明\n1. 确保已安装并配置 MCP 服务。\n2. 运行 \\`team-cli dev\\` 并选择此 Spec。\n3. Claude 将自动调用 MCP 获取最新的 API 信息并完成实现。\n`;\n await FileUtils.write(targetPath, content);\n }\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport os from 'os';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { FileUtils, StringUtils } from '../lib/utils.js';\nimport { Listr } from 'listr2';\nimport {\n initTemplateConfig,\n updateTemplateVersion,\n getLatestTag,\n getDefaultTemplates,\n} from '../lib/template-version.js';\nimport { ModuleManager } from '../lib/module-registry.js';\n\n/**\n * 交互式收集项目配置 (类似 Spring Initializr)\n */\nasync function collectProjectConfig(defaultProjectName?: string): Promise<ProjectConfig> {\n // 1. 项目名称\n let projectName = defaultProjectName;\n if (!projectName) {\n const nameAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'projectName',\n message: '请输入项目目录名称:',\n default: 'my-project',\n validate: (input: string) => {\n if (!/^[a-z0-9-]+$/.test(input)) {\n return '项目名称只能包含小写字母、数字和连字符';\n }\n return true;\n },\n },\n ]);\n projectName = nameAnswer.projectName;\n }\n\n // 2. 项目类型\n const typeAnswer = await inquirer.prompt([\n {\n type: 'list',\n name: 'projectType',\n message: '请选择项目类型:',\n choices: [\n { name: '单模块项目', value: 'single' },\n { name: '多模块项目 (Gradle)', value: 'multi' },\n ],\n default: 'single',\n },\n ]);\n\n // 3. 根项目名 (仅多模块需要)\n let rootProjectName = projectName;\n if (typeAnswer.projectType === 'multi') {\n const rootAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'rootProjectName',\n message: '请输入根项目名 (settings.gradle rootProject.name):',\n default: projectName,\n validate: (input: string) => {\n if (!/^[a-z0-9-]+$/.test(input)) {\n return '根项目名只能包含小写字母、数字和连字符';\n }\n return true;\n },\n },\n ]);\n rootProjectName = rootAnswer.rootProjectName;\n }\n\n // 4. Group ID\n const groupAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'groupId',\n message: '请输入 Group ID (包路径前缀):',\n default: 'org.yungu',\n validate: (input: string) => {\n if (!/^[a-z][a-z0-9]*(\\.[a-z][a-z0-9]*)*$/.test(input)) {\n return 'Group ID 格式不正确 (如: com.example 或 org.yungu)';\n }\n return true;\n },\n },\n ]);\n const groupId = groupAnswer.groupId;\n\n // 5. 模块配置\n const modules: ModuleConfig[] = [];\n let addMoreModules = true;\n let moduleIndex = 1;\n\n while (addMoreModules) {\n // 第一个模块时,如果是多模块,询问第一个模块名\n let defaultModuleName = `module-${moduleIndex}`;\n if (moduleIndex === 1) {\n if (typeAnswer.projectType === 'single') {\n defaultModuleName = 'app';\n } else {\n defaultModuleName = projectName;\n }\n }\n\n const moduleNameAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'moduleName',\n message: `请输入第 ${moduleIndex} 个子模块名称 (目录名):`,\n default: defaultModuleName,\n validate: (input: string) => {\n if (!/^[a-z][a-z0-9-]*$/.test(input)) {\n return '模块名只能包含小写字母、数字和连字符';\n }\n return true;\n },\n },\n ]);\n\n const moduleName = moduleNameAnswer.moduleName;\n\n // 模块类型 (仅多模块需要选择)\n let moduleType: ModuleConfig['type'] = 'service';\n if (typeAnswer.projectType === 'multi') {\n const typeSelectAnswer = await inquirer.prompt([\n {\n type: 'list',\n name: 'moduleType',\n message: `模块 \"${moduleName}\" 类型:`,\n choices: [\n { name: 'API 服务模块 (独立部署)', value: 'service' },\n { name: '公共模块 (被其他模块依赖)', value: 'common' },\n { name: 'API 接口模块 (仅接口定义)', value: 'api' },\n ],\n default: 'service',\n },\n ]);\n moduleType = typeSelectAnswer.moduleType;\n }\n\n // 生成包路径\n const modulePackage = `${groupId}.${moduleName}`;\n // 生成启动类名\n const applicationClass = `${toPascalCase(moduleName)}Application`;\n\n modules.push({\n name: moduleName,\n type: moduleType,\n packagePath: modulePackage,\n applicationClass,\n });\n\n // 是否继续添加模块\n if (typeAnswer.projectType === 'multi') {\n const moreAnswer = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'addMore',\n message: '是否还需要添加更多模块?',\n default: false,\n },\n ]);\n addMoreModules = moreAnswer.addMore;\n } else {\n addMoreModules = false;\n }\n\n moduleIndex++;\n }\n\n // 6. Java 版本\n const javaAnswer = await inquirer.prompt([\n {\n type: 'list',\n name: 'javaVersion',\n message: '请选择 Java 版本:',\n choices: [\n { name: 'Java 8 (1.8)', value: '1.8' },\n { name: 'Java 11 (LTS)', value: '11' },\n { name: 'Java 17 (LTS)', value: '17' },\n { name: 'Java 21 (LTS)', value: '21' },\n ],\n default: '17',\n },\n ]);\n\n // 7. 构建工具\n const buildAnswer = await inquirer.prompt([\n {\n type: 'list',\n name: 'buildTool',\n message: '请选择构建工具:',\n choices: [\n { name: 'Gradle', value: 'gradle' },\n { name: 'Maven', value: 'maven' },\n ],\n default: 'gradle',\n },\n ]);\n\n // 8. 是否需要前端\n const frontendAnswer = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'includeFrontend',\n message: '是否需要包含前端项目?',\n default: true,\n },\n ]);\n\n return {\n projectName,\n projectType: typeAnswer.projectType,\n rootProjectName,\n groupId,\n modules,\n javaVersion: javaAnswer.javaVersion,\n buildTool: buildAnswer.buildTool,\n includeFrontend: frontendAnswer.includeFrontend,\n };\n}\n\n/**\n * 字符串转 PascalCase\n */\nfunction toPascalCase(str: string): string {\n return str\n .split(/[-_]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n\n/**\n * 字符串转 camelCase\n */\nfunction toCamelCase(str: string): string {\n const pascal = toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n\n/**\n * 项目配置接口\n */\ninterface ProjectConfig {\n projectName: string; // 项目目录名\n projectType: 'single' | 'multi'; // 项目类型\n rootProjectName: string; // settings.gradle rootProject.name (多模块需要)\n groupId: string; // Group ID (包路径前缀)\n modules: ModuleConfig[]; // 模块配置列表\n javaVersion: string; // Java 版本\n buildTool: 'gradle' | 'maven'; // 构建工具\n includeFrontend: boolean; // 是否包含前端\n}\n\n/**\n * 模块配置接口\n */\ninterface ModuleConfig {\n name: string; // 模块名 (目录名)\n type: 'service' | 'api' | 'common'; // 模块类型\n packagePath: string; // 包路径 (groupId + name)\n applicationClass: string; // 启动类名\n}\n\n/**\n * Init 命令\n */\nexport const initCommand = new Command('init')\n .argument('[project-name]', '项目名称')\n .description('初始化新项目')\n .option('-d, --dir <directory>', '项目目录', '.')\n .option('--no-docker', '不生成 Docker 配置')\n .option('--no-git', '不初始化 Git')\n .option('--tag <tag>', '指定模板标签 (前后端通用)')\n .option('--backend-tag <tag>', '指定后端模板标签')\n .option('--frontend-tag <tag>', '指定前端模板标签')\n .option('--backend-branch <branch>', '指定后端模板分支')\n .option('--frontend-branch <branch>', '指定前端模板分支')\n .action(async (projectName, options) => {\n try {\n // 交互式收集项目配置\n const config = await collectProjectConfig(projectName);\n\n logger.header('AI-Native 团队研发脚手架 - 项目初始化');\n logger.newLine();\n logger.info(`项目类型: ${config.projectType === 'multi' ? '多模块项目' : '单模块项目'}`);\n logger.info(`Group ID: ${config.groupId}`);\n logger.info(`模块: ${config.modules.map(m => m.name).join(', ')}`);\n logger.info(`Java 版本: ${config.javaVersion}`);\n logger.newLine();\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n const projectPath = path.resolve(options.dir, config.projectName);\n\n // 交互式选择通用模块\n const availableModules = ModuleManager.getAvailableModules();\n const { selectedModules } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'selectedModules',\n message: '请选择要开启的内置通用模块:',\n choices: availableModules.map((m) => ({\n name: `${m.name} - ${m.description}`,\n value: m.id,\n })),\n },\n ]);\n\n // 检查目录是否存在\n if (await FileUtils.exists(projectPath)) {\n logger.error(`目录已存在: ${projectPath}`);\n logger.info('请选择其他项目名称或删除现有目录');\n process.exit(1);\n }\n\n // 1. 基础任务列表 (逻辑顺序重构,避免重复)\n const tasks = new Listr(\n [\n {\n title: '创建项目目录结构',\n task: async () => {\n await FileUtils.ensureDir(projectPath);\n await FileUtils.ensureDir(path.join(projectPath, 'docs/specs'));\n await FileUtils.ensureDir(path.join(projectPath, 'docs/prd-docs'));\n await FileUtils.ensureDir(path.join(projectPath, 'docs/api'));\n await FileUtils.ensureDir(path.join(projectPath, 'docs/sessions'));\n },\n },\n {\n title: '生成技术文档 (Tech Stack, Conventions, Memory)',\n task: async () => {\n await generateTechStack(projectPath, config);\n await generateConventions(projectPath, config);\n await generateAIMemory(projectPath, config.projectName);\n await generateSpecTemplate(projectPath);\n },\n },\n {\n title: '创建后端结构',\n task: async () => {\n await createBackendFromConfig(projectPath, config);\n },\n },\n ...(config.includeFrontend\n ? [\n {\n title: '克隆前端模板',\n task: async () => {\n const frontendTag = options.frontendTag || options.tag;\n const frontendBranch = options.frontendBranch;\n await cloneFrontendTemplate(projectPath, {\n tag: frontendTag,\n branch: frontendBranch,\n });\n },\n },\n ]\n : []),\n {\n title: '注入选定的通用模块',\n task: async (ctx: any) => {\n if (selectedModules.length === 0) return;\n const templatesDir = path.resolve(FileUtils.getDirName(import.meta.url), '../templates');\n ctx.addedFiles = [];\n for (const moduleId of selectedModules) {\n const files = await ModuleManager.injectModule(projectPath, moduleId, templatesDir);\n ctx.addedFiles.push(...files);\n }\n },\n },\n ...(options.docker\n ? [\n {\n title: '生成 Docker 部署配置',\n task: async () => {\n await generateDockerFiles(projectPath, config.projectName);\n },\n },\n ]\n : []),\n ],\n { concurrent: false, exitOnError: true }\n );\n\n const taskContext = await tasks.run();\n\n // 2. 远程模块处理 (在 Listr 之外运行,以确保 Claude 交互可见)\n const remoteModules = selectedModules\n .map((id: string) => ModuleManager.getModuleById(id))\n .filter((m: any) => m?.type === 'remote');\n\n if (remoteModules.length > 0) {\n logger.newLine();\n logger.header('处理远程模块');\n \n const { execa: e } = await import('execa');\n\n // 注册 MCP\n try {\n logger.info('正在注册远程 MCP 服务 api-metadata...');\n await e('claude', [\n 'mcp', 'add',\n '--transport', 'sse',\n '--header', 'Authorization: Bearer mcp_00557dabb71297b4f9ac5fe748395f2c',\n '--',\n 'api-metadata', 'https://api-metadata.yungu.org/sse'\n ]);\n logger.success('远程 MCP 服务注册成功');\n } catch (err) {\n logger.warn('远程 MCP 服务注册提示: 可能已存在或手动注册');\n }\n\n // 生成代码\n for (const module of remoteModules) {\n if (!module) continue;\n logger.newLine();\n logger.info(`正在为您生成 [${module.name}] 的远程调用代码...`);\n \n const prompt = `使用 api-metadata MCP 工具获取所有与 \"${module.id.replace('-remote', '')}\" 相关的 API 元数据。\n然后在项目路径 \\`${projectPath}\\` 的后端目录中,直接生成对应的 Java 调用代码(如 Feign Client 或 RestTemplate 封装)。\n请确保代码符合 \\`CONVENTIONS.md\\` 中的规范。\n生成完成后,检查并修复任何编译错误,最后简要列出生成的文件。`;\n\n try {\n // 使用 --output-format text 确保实时输出可见\n await e('claude', [\n '-p', prompt,\n '--add-dir', projectPath,\n '--dangerously-skip-permissions',\n '--output-format', 'text'\n ], {\n stdio: 'inherit',\n timeout: 600000,\n env: { ...process.env, FORCE_COLOR: '1' } // 保持颜色输出\n });\n logger.success(`[${module.name}] 代码生成完成`);\n } catch (err) {\n logger.error(`[${module.name}] 代码生成失败,请稍后手动重试`);\n }\n }\n }\n\n // 3. 初始化 Git\n if (!options.noGit) {\n logger.newLine();\n await initGit(projectPath, projectName);\n }\n\n logger.newLine();\n logger.success(`项目 ${projectName} 初始化成功!`);\n logger.newLine();\n\n // 4. 显示新增文件汇总\n const addedFiles: string[] = taskContext?.addedFiles || [];\n if (addedFiles.length > 0) {\n logger.newLine();\n logger.header('模块新增文件汇总');\n for (const file of addedFiles) {\n logger.step(file);\n }\n }\n\n logger.newLine();\n logger.info('下一步:');\n logger.step(`cd ${projectName}`);\n logger.step('team-cli add-feature <feature-name>');\n logger.step('team-cli breakdown docs/specs/xxx.md');\n logger.step('team-cli dev');\n logger.newLine();\n } catch (error: any) {\n logger.error(`初始化失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 生成技术栈文档\n */\nasync function generateTechStack(projectPath: string, config: ProjectConfig): Promise<void> {\n const backendStructure = config.modules.map(m => {\n const packagePath = `${config.groupId}.${m.name}`;\n return `├── ${m.name}/\n│ └── src/main/java/${packagePath.replace(/\\./g, '/')}/\n│ ├── controller/ # API 控制器\n│ ├── service/ # 业务逻辑\n│ ├── mapper/ # 数据访问\n│ ├── entity/ # 数据模型\n│ ├── dto/ # 数据传输对象\n│ └── config/ # 配置类`;\n }).join('\\n');\n\n const content = `# 技术栈\n\n## 项目配置\n\n| 配置项 | 值 |\n|-------|------|\n| 项目名称 | ${config.projectName} |\n| Group ID | ${config.groupId} |\n| 根项目名 | ${config.rootProjectName} |\n| 模块 | ${config.modules.map(m => m.name).join(', ')} |\n| Java 版本 | ${config.javaVersion} |\n| 构建工具 | ${config.buildTool === 'gradle' ? 'Gradle' : 'Maven'} |\n\n## 后端技术栈\n\n| 组件 | 技术选型 | 版本 | 说明 |\n|------|---------|------|------|\n| 语言 | Java | ${config.javaVersion} | LTS 版本 |\n| 框架 | Spring Boot | 3.2 | 现代化 Java 框架 |\n| 构建工具 | Gradle | 8.x | 快速、灵活的构建工具 |\n| ORM | MyBatis Plus | 3.5 | 增强 MyBatis,简化 CRUD |\n| 数据库 | MySQL | 8.0 | 关系型数据库 |\n| 缓存 | Redis | 7.x | 缓存和会话存储 |\n| 文档 | SpringDoc OpenAPI | 2.3 | API 文档自动生成 |\n\n${config.includeFrontend ? `## 前端技术栈\n\n| 组件 | 技术选型 | 版本 | 说明 |\n|------|---------|------|------|\n| 框架 | Next.js | 14 | React 全栈框架 |\n| 语言 | TypeScript | 5.x | 类型安全 |\n| 样式 | Tailwind CSS | 3.x | 原子化 CSS |\n| UI 库 | Shadcn/UI | latest | 基于 Radix UI 的组件库 |\n| 图标 | Lucide React | latest | 一致性图标库 |\n| 状态管理 | React Context + Hooks | - | 轻量级状态管理 |\n| 表单 | React Hook Form | 7.x | 高性能表单 |\n| 数据验证 | Zod | 3.x | TypeScript 优先的验证库 |` : ''}\n\n## 开发工具\n\n| 工具 | 用途 |\n|------|------|\n| ESLint | 代码检查 |\n| Prettier | 代码格式化 |\n| Husky | Git Hooks |\n| Commitlint | 提交信息规范 |\n| Docker | 容器化部署 |\n\n## 代码规范\n\n### 后端规范\n\n- 使用 DTO 模式进行数据传输\n- Controller 负责接收请求,Service 处理业务逻辑\n- 使用 @Validated 进行参数校验\n- 统一异常处理和响应格式\n- API 路径使用 kebab-case\n- 类名使用 PascalCase\n- 方法名使用 camelCase\n- 包路径: \\`${config.groupId}.<module-name>\\`\n\n### 前端规范\n\n- 组件使用 PascalCase\n- 文件名使用 kebab-case\n- 使用 TypeScript 类型定义\n- Props 接口定义在组件内部\n- 使用 Semantic HTML\n- 响应式设计优先\n\n### Git 规范\n\n- 分支命名: \\`feature/xxx\\`, \\`bugfix/xxx\\`, \\`hotfix/xxx\\`\n- 提交信息: \\`feat: xxx\\`, \\`fix: xxx\\`, \\`docs: xxx\\`\n- 提交前必须通过 lint 检查\n\n## 目录结构\n\n\\`\\`\\`\nbackend/\n${backendStructure}\n├── src/main/resources/\n│ ├── mapper/ # MyBatis XML\n│ └── application.yml # 配置文件\n└── src/test/ # 测试代码\n\n${config.includeFrontend ? `frontend/\n├── src/\n│ ├── app/ # Next.js App Router\n│ ├── components/ # React 组件\n│ ├── lib/ # 工具库\n│ └── types/ # TypeScript 类型\n└── public/ # 静态资源` : ''}\n\ndocs/\n├── prd-docs/ # PRD 需求文档\n├── specs/ # 功能规格文档\n├── api/ # API 文档\n└── sessions/ # 开发会话记录\n\\`\\`\\`\n`;\n\n await FileUtils.write(path.join(projectPath, 'TECH_STACK.md'), content);\n}\n\n/**\n * 生成开发规范文档\n */\nasync function generateConventions(projectPath: string, config: ProjectConfig): Promise<void> {\n const content = `# 开发规范\n\n## 包路径规范\n\n所有后端代码的包路径遵循: \\`${config.groupId}.<module-name>\\`\n\n示例:\n${config.modules.map(m => `- \\`${m.packagePath}\\``).join('\\n')}\n` + `\n\n## 后端开发规范\n\n### 1. 分层架构\n\n` + \"`\" + `` + `\nController → Service → Mapper → Database\n ↓ ↓\n DTO Entity\n` + \"`\" + `` + `\n\n**职责划分:**\n- **Controller**: 接收 HTTP 请求,参数校验,调用 Service\n- **Service**: 业务逻辑处理,事务管理\n- **Mapper**: 数据库操作,SQL 执行\n- **DTO**: 数据传输对象,用于 API 接口\n- **Entity**: 数据库实体映射\n\n### 2. 命名规范\n\n| 类型 | 规范 | 示例 |\n|------|------|------|\n| 类名 | PascalCase | \\`UserController\\` |\n| 方法名 | camelCase | \\`getUserById\\` |\n| 常量 | UPPER_SNAKE_CASE | \\`MAX_RETRY_COUNT\\` |\n| 包名 | 小写点分隔 | \\`com.example.demo.controller\\` |\n| API 路径 | kebab-case | \\`/api/users\\` |\n\n### 3. API 设计\n\n**RESTful 风格:**\n\n` + \"`\" + `` + `\nGET /api/users # 列表\nGET /api/users/{id} # 详情\nPOST /api/users # 创建\nPUT /api/users/{id} # 更新\nDELETE /api/users/{id} # 删除\n` + \"`\" + `` + `\n\n**统一响应格式:**\n\n` + \"```json\" + `\n{\n \"code\": 200,\n \"message\": \"success\",\n \"data\": {...}\n}\n` + \"```\" + `\n\n### 4. 异常处理\n\n使用 \\`@ControllerAdvice\\` 统一处理异常:\n\n` + \"```java\" + `\n@RestControllerAdvice\npublic class GlobalExceptionHandler {\n\n @ExceptionHandler(BusinessException.class)\n public Result<Void> handleBusinessException(BusinessException e) {\n return Result.error(e.getMessage());\n }\n}\n` + \"```\" + `\n\n### 5. 参数校验\n\n使用 \\`@Validated\\` 和 JSR-303 注解:\n\n` + \"```java\" + `\n@PostMapping(\"/users\")\npublic Result<User> createUser(@Validated @RequestBody UserDTO dto) {\n // ...\n}\n` + \"```\" + `\n\n### 6. 事务管理\n\n在 Service 层使用 \\`@Transactional\\`:\n\n` + \"```java\" + `\n@Service\npublic class UserService {\n\n @Transactional(rollbackFor = Exception.class)\n public void createUserWithRole(User user, Role role) {\n // ...\n }\n}\n` + \"```\" + `\n\n## 前端开发规范\n\n### 1. 组件设计\n\n**组件结构:**\n\n` + \"```typescript\" + `\n// 组件定义\ninterface Props {\n // props 类型定义\n}\n\nexport function ComponentName({ prop1, prop2 }: Props) {\n // 组件逻辑\n\n return (\n // JSX\n );\n}\n` + \"```\" + `\n\n**命名规范:**\n- 组件文件: kebab-case (\\`user-card.tsx\\`)\n- 组件名: PascalCase (\\`UserCard\\`)\n- Hook 文件: kebab-case, 以 \\`use-\\` 开头 (\\`use-user-data.ts\\`)\n\n### 2. TypeScript 使用\n\n**定义接口:**\n\n` + \"```typescript\" + `\ninterface User {\n id: string;\n name: string;\n email: string;\n}\n\ninterface CreateUserDto {\n name: string;\n email: string;\n}\n` + \"```\" + `\n\n**避免使用 \\`any\\`:**\n\n` + \"```typescript\" + `\n// ❌ 不好\nconst data: any = await fetchData();\n\n// ✅ 好\nconst data: User = await fetchData();\n` + \"```\" + `\n\n### 3. 状态管理\n\n**使用 React Context:**\n\n` + \"```typescript\" + `\nconst UserContext = createContext<UserContextType>({\n user: null,\n login: async () => {},\n logout: () => {},\n});\n` + \"```\" + `\n\n**优先使用本地状态:**\n\n` + \"```typescript\" + `\n// 简单状态使用 useState\nconst [count, setCount] = useState(0);\n\n// 复杂逻辑使用 useReducer\nconst [state, dispatch] = useReducer(reducer, initialState);\n` + \"```\" + `\n\n### 4. 样式规范\n\n**使用 Tailwind CSS:**\n\n\\`\\`\\`tsx\n<div className=\"flex items-center gap-4 p-4 bg-white rounded-lg\">\n {/* ... */}\n</div>\n\\`\\`\\`\n\n**响应式设计:**\n\n\\`\\`\\`tsx\n<div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {/* ... */}\n</div>\n\\`\\`\\`\n\n### 5. 表单处理\n\n**使用 React Hook Form:**\n\n\\`\\`\\`typescript\nconst { register, handleSubmit, formState: { errors } } = useForm<FormData>();\n\nconst onSubmit = (data: FormData) => {\n console.log(data);\n};\n\nreturn (\n <form onSubmit={handleSubmit(onSubmit)}>\n <input {...register('name', { required: true })} />\n {errors.name && <span>必填</span>}\n </form>\n);\n\\`\\`\\`\n\n### 6. 数据获取\n\n**使用 Server Components (Next.js 14):**\n\n\\`\\`\\`typescript\nasync function getUser(id: string) {\n const res = await fetch(\\`/api/users/\\${id}\\`);\n if (!res.ok) throw new Error('Failed to fetch');\n return res.json();\n}\n\nexport default async function UserPage({ params }) {\n const user = await getUser(params.id);\n return <div>{user.name}</div>;\n}\n\\`\\`\\`\n\n## Git 工作流\n\n### 分支策略\n\n\\`\\`\\`\nmain # 主分支,始终保持稳定\n ├── feature/xxx # 功能分支\n ├── bugfix/xxx # Bug 修复分支\n └── hotfix/xxx # 紧急修复分支\n\\`\\`\\`\n\n### 提交信息规范\n\n\\`\\`\\`\n<type>(<scope>): <subject>\n\n<body>\n\n<footer>\n\\`\\`\\`\n\n**类型 (type):**\n- \\`feat\\`: 新功能\n- \\`fix\\`: Bug 修复\n- \\`docs\\`: 文档更新\n- \\`style\\`: 代码格式调整\n- \\`refactor\\`: 代码重构\n- \\`test\\`: 测试相关\n- \\`chore\\`: 构建/工具相关\n\n**示例:**\n\n\\`\\`\\`\nfeat(auth): add user login feature\n\nimplement JWT based authentication with:\n- login endpoint\n- token refresh\n- logout handling\n\nCloses #123\n\\`\\`\\`\n\n## 测试规范\n\n### 后端测试\n\n\\`\\`\\`java\n@SpringBootTest\nclass UserServiceTest {\n\n @Autowired\n private UserService userService;\n\n @Test\n void shouldCreateUser() {\n // given\n User user = new User(\"John\");\n\n // when\n User saved = userService.save(user);\n\n // then\n assertNotNull(saved.getId());\n }\n}\n\\`\\`\\`\n\n### 前端测试\n\n\\`\\`\\`typescript\nimport { render, screen } from '@testing-library/react';\n\ntest('renders user name', () => {\n render(<UserProfile name=\"John\" />);\n expect(screen.getByText('John')).toBeInTheDocument();\n});\n\\`\\`\\`\n`;\n\n await FileUtils.write(path.join(projectPath, 'CONVENTIONS.md'), content);\n}\n\n/**\n * 生成 AI Memory\n */\nasync function generateAIMemory(projectPath: string, projectName: string): Promise<void> {\n const content = `# AI Memory - 项目状态记录\n\n## 项目信息\n- **项目名称**: ${projectName}\n- **创建时间**: ${new Date().toISOString().split('T')[0]}\n- **当前阶段**: 初始化\n- **最后更新**: ${new Date().toISOString().split('T')[0]}\n\n## 模板版本信息\n\n> 本部分由 team-cli 自动管理,记录使用的前后端模板版本\n\n| 类型 | 仓库 | Tag | Branch | Commit | 更新时间 |\n|------|------|-----|--------|--------|----------|\n| 前端 | - | - | - | - | - |\n| 后端 | - | - | - | - | - |\n\n## 功能清单 (Feature Inventory)\n\n| 功能 | Spec 文件 | 状态 | 进度 | 完成日期 | 备注 |\n|------|----------|------|------|---------|------|\n\n## API 列表 (API Inventory)\n\n> 本部分由 team-cli 自动扫描后端 Controller 生成\n\n## 数据模型概览\n\n| 表名 | 说明 | 字段数 | 关联表 | 状态 |\n|------|------|--------|--------|------|\n| user | 用户表 | - | - | - |\n\n## 已完成的 Milestones\n\n## 当前任务\n\n## 待处理任务\n\n## 技术债务\n\n| 日期 | 问题 | 计划修复 |\n|------|------|---------|\n\n## 关键决策记录\n\n| 日期 | 决策 | 原因 |\n|------|------|------|\n| ${new Date().toISOString().split('T')[0]} | 初始化项目 | 使用 Spring Boot 3 + Next.js 14 技术栈 |\n\n## 注意事项\n\n## Bugfix 记录\n\n| Bug ID | 日期 | 问题描述 | 状态 |\n|--------|------|---------|------|\n`;\n\n await FileUtils.write(path.join(projectPath, 'AI_MEMORY.md'), content);\n}\n\n/**\n * 生成 Spec 模板\n */\nasync function generateSpecTemplate(projectPath: string): Promise<void> {\n const content = `# [功能标题]\n\n## 功能概述\n**功能名称**: [功能中文名]\n**优先级**: P0/P1/P2\n**预估工时**: X 天\n**状态**: 待拆分\n**创建日期**: {{DATE}}\n\n## 依赖关系\n**前置依赖**:\n- [ ] dependency-1.md\n- [ ] dependency-2.md\n\n**被依赖于**:\n- (自动生成)\n\n## 背景与目标\n[简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n1. 功能点一\n2. 功能点二\n3. 功能点三\n\n## 技术设计\n\n### API 设计\n- \\`POST /api/xxx\\` - 创建 XXX\n- \\`GET /api/xxx/{id}\\` - 获取 XXX 详情\n- \\`PUT /api/xxx/{id}\\` - 更新 XXX\n- \\`DELETE /api/xxx/{id}\\` - 删除 XXX\n\n### 数据模型\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n\n> 注: 使用 \\`team-cli breakdown\\` 拆分此 spec 为 milestones 和 todos\n\n### Milestone 1: [里程碑名称]\n- [ ] Todo 1\n- [ ] Todo 2\n- [ ] Todo 3\n\n### Milestone 2: [里程碑名称]\n- [ ] Todo 1\n- [ ] Todo 2\n\n----\n*生成于: {{TIMESTAMP}} by team-cli*\n`;\n\n await FileUtils.write(path.join(projectPath, 'docs/specs/template.md'), content);\n}\n\n/**\n * 克隆后端模板\n */\nasync function cloneBackendTemplate(\n projectPath: string,\n versionOptions?: {\n tag?: string;\n branch?: string;\n }\n): Promise<void> {\n const templateRepo = process.env.TEMPLATE_REPO || 'git@gitlab.yungu-inc.org:yungu-app/java-scaffold-template.git';\n const backendPath = path.join(projectPath, 'backend');\n\n try {\n const { execa: e } = await import('execa');\n const tempDir = path.join(projectPath, '.template-temp');\n\n // 如果指定了 tag 或 branch,先验证\n if (versionOptions?.tag || versionOptions?.branch) {\n const { userConfigManager } = await import('../lib/user-config.js');\n const { GitLabAPI } = await import('../lib/gitlab-api.js');\n\n const config = await userConfigManager.getGitLabConfig();\n if (config) {\n const gitlabAPI = new GitLabAPI(config);\n const projectPathEncoded = GitLabAPI.parseProjectPath(templateRepo);\n\n if (versionOptions.tag) {\n const isValid = await gitlabAPI.validateTag(projectPathEncoded, versionOptions.tag);\n if (!isValid) {\n logger.error(`后端模板 tag \"${versionOptions.tag}\" 不存在`);\n process.exit(1);\n }\n logger.info(`使用后端模板 tag: ${versionOptions.tag}`);\n }\n\n if (versionOptions.branch) {\n const isValid = await gitlabAPI.validateBranch(projectPathEncoded, versionOptions.branch);\n if (!isValid) {\n logger.error(`后端模板分支 \"${versionOptions.branch}\" 不存在`);\n process.exit(1);\n }\n logger.info(`使用后端模板分支: ${versionOptions.branch}`);\n }\n } else {\n logger.warn('未配置 GitLab Token,跳过版本验证');\n }\n }\n\n // 确定要克隆的 ref\n \n logger.info(`正在克隆后端模板 (${versionOptions?.tag || versionOptions?.branch || 'latest'})...`);\n\n const cloneArgs = ['clone', '--depth=1'];\n if (versionOptions?.tag || versionOptions?.branch) {\n cloneArgs.push('--branch', versionOptions.tag || versionOptions.branch!);\n }\n cloneArgs.push(templateRepo, tempDir);\n\n await e('git', cloneArgs, {\n stdio: 'inherit',\n timeout: 60000,\n });\n\n // 获取 commit 和 tag\n const { stdout: commit } = await e('git', ['rev-parse', 'HEAD'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n const { stdout: tags } = await e('git', ['tag', '-l', '--sort=-v:refname'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n const latestTag = tags.split('\\n')[0] || undefined;\n\n // 复制内容(排除 .git)\n await fs.copy(tempDir, backendPath, {\n filter: (src) => !src.includes('.git'),\n });\n\n // 删除临时目录\n await fs.remove(tempDir);\n\n // 删除 .git 目录\n const gitDir = path.join(backendPath, '.git');\n if (await FileUtils.exists(gitDir)) {\n await FileUtils.remove(gitDir);\n }\n\n // 保存模板版本信息\n await initTemplateConfig(projectPath);\n await updateTemplateVersion(projectPath, 'backend', commit.trim(), {\n tag: versionOptions?.tag || latestTag,\n branch: versionOptions?.branch,\n });\n } catch (error) {\n logger.warn('克隆后端模板失败,创建基础结构');\n await FileUtils.ensureDir(path.join(backendPath, 'src/main/java/com/example'));\n await FileUtils.ensureDir(path.join(backendPath, 'src/main/resources'));\n await FileUtils.ensureDir(path.join(backendPath, 'src/test/java'));\n }\n}\n\n/**\n * 克隆前端模板\n */\nasync function cloneFrontendTemplate(\n projectPath: string,\n versionOptions: { tag?: string; branch?: string } = {}\n): Promise<void> {\n const frontendPath = path.join(projectPath, 'frontend');\n const templates = getDefaultTemplates();\n const repository = templates.frontend.repository;\n\n try {\n const { execa: e } = await import('execa');\n \n // 获取最新 tag (如果没有指定)\n let latestTag = '';\n if (!versionOptions.tag && !versionOptions.branch) {\n latestTag = await getLatestTag(repository);\n }\n\n const targetVersion = versionOptions.branch || versionOptions.tag || latestTag;\n \n logger.info(`正在克隆前端模板 (${targetVersion || 'HEAD'})...`);\n\n // 创建临时目录进行克隆\n const tempDir = path.join(os.tmpdir(), `team-cli-fe-${Date.now()}`);\n await FileUtils.ensureDir(tempDir);\n\n const cloneArgs = ['clone', '--depth', '1'];\n if (targetVersion) {\n cloneArgs.push('--branch', targetVersion);\n }\n cloneArgs.push(repository, tempDir);\n \n await e('git', cloneArgs);\n\n // 获取 commit 信息\n const { stdout: commit } = await e('git', ['rev-parse', 'HEAD'], { cwd: tempDir });\n\n // 复制内容(排除 .git)\n await fs.copy(tempDir, frontendPath, {\n filter: (src) => !src.includes('.git'),\n });\n\n // 删除临时目录\n await fs.remove(tempDir);\n\n // 记录模板版本信息\n await updateTemplateVersion(projectPath, 'frontend', commit.trim(), {\n tag: versionOptions.tag || latestTag,\n branch: versionOptions.branch,\n });\n\n logger.success('前端模板克隆完成');\n } catch (error) {\n logger.warn('克隆前端模板失败,将创建基础结构');\n await FileUtils.ensureDir(path.join(frontendPath, 'src/app'));\n await FileUtils.ensureDir(path.join(frontendPath, 'src/components'));\n }\n}\n\n/**\n * 根据配置创建后端多模块结构\n */\nasync function createBackendFromConfig(\n projectPath: string,\n config: ProjectConfig\n): Promise<void> {\n const backendPath = path.join(projectPath, 'backend');\n\n logger.info(`正在创建后端多模块结构...`);\n\n // 1. 创建根目录\n await FileUtils.ensureDir(backendPath);\n\n // 2. 创建 settings.gradle\n await createSettingsGradle(backendPath, config);\n\n // 3. 创建根 build.gradle\n await createRootBuildGradle(backendPath, config);\n\n // 4. 创建各模块\n for (const module of config.modules) {\n await createModuleFromConfig(backendPath, module, config);\n }\n\n // 5. 创建公共模块 (common)\n if (config.modules.length > 0) {\n await createCommonModule(backendPath, config);\n }\n\n logger.success('后端结构创建完成');\n}\n\n/**\n * 创建 settings.gradle\n */\nasync function createSettingsGradle(backendPath: string, config: ProjectConfig): Promise<void> {\n const lines: string[] = [];\n lines.push(`rootProject.name = '${config.rootProjectName}'`);\n lines.push('');\n\n // 添加所有模块\n const allModules = ['common', ...config.modules.map(m => m.name)].sort();\n for (const module of allModules) {\n lines.push(`include '${module}'`);\n }\n\n await FileUtils.write(path.join(backendPath, 'settings.gradle'), lines.join('\\n'));\n logger.info('settings.gradle 已创建');\n}\n\n/**\n * 创建根 build.gradle\n */\nasync function createRootBuildGradle(backendPath: string, config: ProjectConfig): Promise<void> {\n const content = `plugins {\n id 'java' version '8' apply false\n}\n\nallprojects {\n group = '${config.groupId}'\n version = '0.0.1-SNAPSHOT'\n\n repositories {\n maven { url 'https://maven.aliyun.com/repository/public/' }\n }\n}\n\nsubprojects {\n apply plugin: 'java'\n apply plugin: 'org.springframework.boot'\n apply plugin: 'io.spring.dependency-management'\n\n sourceCompatibility = '${config.javaVersion}'\n targetCompatibility = '${config.javaVersion}'\n\n dependencies {\n implementation 'org.springframework.boot:spring-boot-starter-web'\n implementation 'org.springframework.boot:spring-boot-starter-logging'\n compileOnly \"org.projectlombok:lombok\"\n annotationProcessor \"org.projectlombok:lombok\"\n testCompileOnly \"org.projectlombok:lombok\"\n testAnnotationProcessor \"org.projectlombok:lombok\"\n }\n}\n`;\n await FileUtils.write(path.join(backendPath, 'build.gradle'), content);\n logger.info('build.gradle (root) 已创建');\n}\n\n/**\n * 从配置创建单个模块\n */\nasync function createModuleFromConfig(\n backendPath: string,\n module: ModuleConfig,\n config: ProjectConfig\n): Promise<void> {\n const modulePath = path.join(backendPath, module.name);\n const packagePath = module.packagePath.split('.');\n\n logger.info(`创建模块: ${module.name} (${module.type})...`);\n\n // 创建目录结构\n const baseDirs = [\n 'src/main/java',\n 'src/main/resources',\n 'src/test/java',\n ];\n\n for (const dir of baseDirs) {\n await FileUtils.ensureDir(path.join(modulePath, dir));\n }\n\n // 根据类型创建子目录\n let subDirs: string[] = [];\n if (module.type === 'service') {\n subDirs = ['controller', 'service', 'mapper', 'entity', 'dto', 'config'];\n } else if (module.type === 'api') {\n subDirs = ['model', 'constant', 'enums', 'exception'];\n } else {\n subDirs = ['util', 'common', 'config', 'manager'];\n }\n\n let javaPath = path.join(modulePath, 'src', 'main', 'java');\n for (const subDir of subDirs) {\n await FileUtils.ensureDir(path.join(javaPath, ...packagePath, subDir));\n }\n\n // 创建 Application 启动类\n await createApplicationClass(\n path.join(javaPath, ...packagePath, 'config', `${module.applicationClass}.java`),\n module.packagePath,\n module.applicationClass\n );\n\n // 创建 build.gradle\n await createModuleBuildGradle(modulePath, module, config);\n\n logger.success(`模块 ${module.name} 创建完成`);\n}\n\n/**\n * 创建 Application 启动类\n */\nasync function createApplicationClass(\n filePath: string,\n packagePath: string,\n className: string\n): Promise<void> {\n const content = `package ${packagePath}.config;\n\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.annotation.ComponentScan;\n\n@SpringBootApplication\n@ComponentScan(\"${packagePath}\")\n@Slf4j\npublic class ${className} {\n\n public static void main(String[] args) {\n ApplicationContext context = SpringApplication.run(${className}.class, args);\n log.info(\"${className} 启动成功!\");\n }\n}\n`;\n await FileUtils.ensureDir(path.dirname(filePath));\n await FileUtils.write(filePath, content);\n}\n\n/**\n * 创建模块 build.gradle\n */\nasync function createModuleBuildGradle(\n modulePath: string,\n module: ModuleConfig,\n config: ProjectConfig\n): Promise<void> {\n let applyPlugins = `plugins {\n id 'java-library'\n id 'org.springframework.boot'\n id 'io.spring.dependency-management'\n}\n\ngroup = '${config.groupId}'\nversion = '0.0.1-SNAPSHOT'\n\njava {\n sourceCompatibility = '${config.javaVersion}'\n targetCompatibility = '${config.javaVersion}'\n}\n\nrepositories {\n maven { url 'https://maven.aliyun.com/repository/public/' }\n}\n`;\n\n let dependencies = '';\n if (module.type === 'service') {\n dependencies = `\ndependencies {\n implementation project(\":common\")\n implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter'\n implementation 'com.alibaba:druid-spring-boot-starter'\n implementation 'org.springframework.boot:spring-boot-starter-validation'\n compileOnly \"org.projectlombok:lombok\"\n annotationProcessor \"org.projectlombok:lombok\"\n testCompileOnly \"org.projectlombok:lombok\"\n testAnnotationProcessor \"org.projectlombok:lombok\"\n}\n`;\n } else if (module.type === 'api') {\n dependencies = `\ndependencies {\n compileOnly 'org.springframework.boot:spring-boot-starter'\n compileOnly \"org.projectlombok:lombok\"\n annotationProcessor \"org.projectlombok:lombok\"\n}\n`;\n } else {\n dependencies = `\ndependencies {\n implementation 'org.springframework.boot:spring-boot-starter'\n implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter'\n implementation 'org.apache.commons:commons-lang3:3.12.0'\n compileOnly \"org.projectlombok:lombok\"\n annotationProcessor \"org.projectlombok:lombok\"\n}\n`;\n }\n\n await FileUtils.write(path.join(modulePath, 'build.gradle'), applyPlugins + dependencies);\n}\n\n/**\n * 创建 common 公共模块\n */\nasync function createCommonModule(backendPath: string, config: ProjectConfig): Promise<void> {\n const modulePath = path.join(backendPath, 'common');\n const packagePath = config.groupId.split('.');\n const subDirs = ['util', 'common', 'config', 'manager', 'constant', 'enums', 'exception'];\n\n logger.info('创建公共模块: common...');\n\n // 创建目录\n for (const dir of ['src/main/java', 'src/main/resources', 'src/test/java']) {\n await FileUtils.ensureDir(path.join(modulePath, dir));\n }\n\n let javaPath = path.join(modulePath, 'src', 'main', 'java');\n for (const subDir of subDirs) {\n await FileUtils.ensureDir(path.join(javaPath, ...packagePath, subDir));\n }\n\n // 创建 build.gradle\n await createModuleBuildGradle(modulePath, {\n name: 'common',\n type: 'common',\n packagePath: `${config.groupId}.common`,\n applicationClass: '',\n }, config);\n\n logger.success('公共模块 common 创建完成');\n}\n\n/**\n * 生成 Docker 配置 (支持阿里云镜像仓库和 Gradle 构建)\n */\nasync function generateDockerFiles(projectPath: string, projectName: string): Promise<void> {\n const backendPath = path.join(projectPath, 'backend');\n \n if (!(await FileUtils.exists(backendPath))) {\n logger.warn('未找到 backend 目录,跳过 Docker 配置生成');\n return;\n }\n\n // 1. Dockerfile\n const dockerfile = `FROM openjdk:17-jdk-slim\nWORKDIR /app\nCOPY build/libs/*.jar app.jar\nEXPOSE 8080\nENTRYPOINT [\"java\", \"-Djava.security.egd=file:/dev/./urandom\", \"-jar\", \"app.jar\"]\n`;\n \n // 2. 部署脚本 (Aliyun Registry + Gradle)\n const deploySh = `#!/bin/bash\n# yg-team-cli 自动生成的部署脚本\n# 偏好:Aliyun 镜像仓库, Gradle 构建, 刷新依赖, 跳过测试\n\nPROJECT_NAME=\"${projectName}\"\nTIMESTAMP=$(date +%Y%m%d%H%M%S)\nREGISTRY=\"registry.cn-hangzhou.aliyuncs.com/yungu-app\"\nIMAGE_TAG=\"\\${PROJECT_NAME}:\\${TIMESTAMP}\"\n\necho \"🐘 开始 Gradle 构建 (跳过测试, 刷新依赖)...\"\n./gradlew clean build -x test --refresh-dependencies\n\nif [ $? -ne 0 ]; then\n echo \"❌ 构建失败,请检查代码\"\n exit 1\nfi\n\necho \"🐳 构建 Docker 镜像...\"\ndocker build -t \\${REGISTRY}/\\${IMAGE_TAG} .\ndocker tag \\${REGISTRY}/\\${IMAGE_TAG} \\${REGISTRY}/\\${PROJECT_NAME}:latest\n\necho \"🚀 推送镜像到阿里云...\"\ndocker push \\${REGISTRY}/\\${IMAGE_TAG}\ndocker push \\${REGISTRY}/\\${PROJECT_NAME}:latest\n\necho \"✅ 部署完成! 镜像地址: \\${REGISTRY}/\\${IMAGE_TAG}\"\n`;\n\n await fs.writeFile(path.join(backendPath, 'Dockerfile'), dockerfile);\n await fs.writeFile(path.join(backendPath, 'deploy.sh'), deploySh);\n await fs.chmod(path.join(backendPath, 'deploy.sh'), 0o755);\n}\n\n/**\n * 初始化 Git\n */\nasync function initGit(projectPath: string, projectName: string): Promise<void> {\n try {\n const { execa: e } = await import('execa');\n\n await e('git', ['init'], { cwd: projectPath, stdio: 'pipe' });\n await e('git', ['add', '.'], { cwd: projectPath, stdio: 'pipe' });\n await e(\n 'git',\n ['commit', '-m', `feat: initialize ${projectName} project with team-cli`],\n { cwd: projectPath, stdio: 'pipe' }\n );\n\n logger.success('Git 仓库初始化完成');\n } catch (error: any) {\n logger.warn(`Git 初始化失败: ${error.message}`);\n }\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { Listr } from 'listr2';\n\n/**\n * Breakdown 命令 - 将 spec 拆分为 milestones 和 todos\n */\nexport const breakdownCommand = new Command('breakdown')\n .argument('[spec-file]', 'Spec 文件路径')\n .description('将 spec 拆分为 milestones 和 todos')\n .action(async (specFile) => {\n try {\n logger.header('Spec 拆分');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info('请先运行 team-cli init 或切换到项目目录');\n process.exit(1);\n }\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 扫描 spec 文件\n const tasks = new Listr([\n {\n title: '扫描 spec 文件',\n task: async (ctx) => {\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n if (!exists) {\n throw new Error(`specs 目录不存在: ${specDir}`);\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n ctx.specs = files.filter((f) => !f.includes('template'));\n },\n },\n {\n title: '选择 spec 文件',\n task: async (ctx) => {\n if (!ctx.specs || ctx.specs.length === 0) {\n throw new Error('未找到 spec 文件');\n }\n\n // 如果没有指定文件,交互式选择\n if (!specFile) {\n const { selectedFile } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedFile',\n message: '请选择要拆分的 spec 文件:',\n choices: ctx.specs,\n },\n ]);\n ctx.selectedFile = path.join('docs/specs', selectedFile);\n return;\n }\n\n // 验证指定的文件\n const fullPath = specFile.startsWith('docs/specs/')\n ? specFile\n : path.join('docs/specs', specFile);\n\n const exists = await FileUtils.exists(fullPath);\n if (!exists) {\n throw new Error(`Spec 文件不存在: ${specFile}`);\n }\n\n ctx.selectedFile = fullPath;\n },\n },\n {\n title: '读取 spec 内容',\n task: async (ctx) => {\n ctx.specContent = await FileUtils.read(ctx.selectedFile);\n logger.success(`已选择: ${ctx.selectedFile}`);\n },\n },\n {\n title: '调用 Claude 拆分 spec',\n task: async (ctx) => {\n const prompt = buildBreakdownPrompt(ctx.specContent);\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 执行中...');\n logger.separator('─', 60);\n logger.newLine();\n\n // 调用 Claude 执行拆分\n const result = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md'],\n });\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n ctx.breakdownResult = result;\n },\n },\n {\n title: '更新 spec 文件',\n task: async (ctx) => {\n // 精确合并里程碑内容\n const mergedContent = mergeMilestones(ctx.specContent, ctx.breakdownResult);\n await FileUtils.write(ctx.selectedFile, mergedContent);\n },\n },\n ]);\n// ... (rest of the run sequence)\n try {\n const ctx = await tasks.run();\n\n logger.newLine();\n logger.header('Spec 拆分完成!');\n logger.success(`Milestones 已添加到: ${ctx.selectedFile}`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step('1. 检查拆分结果,根据需要调整');\n logger.step(\"2. 运行 'team-cli dev' 选择 milestone 进行开发\");\n logger.newLine();\n } catch (error: any) {\n if (error.message) {\n logger.error(error.message);\n }\n throw error;\n }\n } catch (error: any) {\n logger.error(`拆分失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 合并里程碑到原 spec 内容中\n */\nfunction mergeMilestones(original: string, milestones: string): string {\n const milestoneHeader = '## 里程碑 (Milestones)';\n const lines = original.split('\\n');\n const headerIndex = lines.findIndex(l => l.trim().startsWith(milestoneHeader));\n\n // 清理里程碑内容,确保它以 ## 里程碑 (Milestones) 开头\n let cleanedMilestones = milestones.trim();\n if (!cleanedMilestones.startsWith('## ')) {\n // 可能是 Claude 没带标题,或者带了其他前缀\n const firstHeaderIndex = cleanedMilestones.indexOf('## ');\n if (firstHeaderIndex !== -1) {\n cleanedMilestones = cleanedMilestones.substring(firstHeaderIndex);\n } else {\n // 完全没标题,我们给它加上\n cleanedMilestones = `${milestoneHeader}\\n\\n${cleanedMilestones}`;\n }\n }\n\n if (headerIndex !== -1) {\n // 1. 替换原有里程碑部分\n const beforePart = lines.slice(0, headerIndex).join('\\n');\n const afterPart = lines.slice(headerIndex + 1);\n \n // 找到下一个二级标题\n const nextHeaderIndex = afterPart.findIndex(l => l.trim().startsWith('## '));\n \n if (nextHeaderIndex !== -1) {\n const remaining = afterPart.slice(nextHeaderIndex).join('\\n');\n return `${beforePart.trim()}\\n\\n${cleanedMilestones}\\n\\n${remaining.trim()}`;\n } else {\n // 后面没有二级标题了,直接跟在前面部分后面\n return `${beforePart.trim()}\\n\\n${cleanedMilestones}`;\n }\n }\n\n // 2. 插入到“技术设计”之后\n const techDesignHeader = '## 技术设计';\n const techIndex = lines.findIndex(l => l.trim().startsWith(techDesignHeader));\n if (techIndex !== -1) {\n // 找到本节的结尾(下一个二级标题之前)\n const afterTech = lines.slice(techIndex + 1);\n const nextHeaderIndex = afterTech.findIndex(l => l.trim().startsWith('## '));\n \n if (nextHeaderIndex !== -1) {\n const splitPoint = techIndex + 1 + nextHeaderIndex;\n const before = lines.slice(0, splitPoint).join('\\n');\n const after = lines.slice(splitPoint).join('\\n');\n return `${before.trim()}\\n\\n${cleanedMilestones}\\n\\n${after.trim()}`;\n }\n }\n\n // 3. 兜底:追加到末尾\n return `${original.trim()}\\n\\n${cleanedMilestones}`;\n}\n\n/**\n * 构建拆分 prompt\n */\nfunction buildBreakdownPrompt(specContent: string): string {\n return `Role: Senior Technical Lead and Agile Coach\n\nTask: Break down the following feature spec into milestones with frontend, backend, and integration tasks.\n\nContext:\n- Read TECH_STACK.md for technology constraints\n- Read CONVENTIONS.md for coding standards\n- Each milestone should be completable in 1-3 days\n- Each todo should be a concrete, actionable task\n\nSpec Content:\n\\`\\`\\`\n${specContent}\n\\`\\`\\`\n\nOutput Requirements:\n1. Parse the existing spec content and identify technical requirements.\n2. Break it down into 2-5 milestones.\n3. Each milestone must have three sections:\n - **前端任务**: Frontend tasks marked with [F] prefix\n - **后端任务**: Backend tasks marked with [B] prefix, include API associations\n - **联调任务**: Integration tasks marked with [I] prefix, include dependencies\n4. Todo items should be:\n - Concrete, specific, and testable\n - Independent as much as possible\n\nTask Prefix Format:\n- Frontend: \\`- [ ] [F] 具体的前端任务描述\\`\n- Backend: \\`- [ ] [B] 具体的后端任务描述 (关联 API: \\`METHOD /api/path\\`)\\`\n- Integration: \\`- [ ] [I] 联调任务描述 (依赖: F-x, B-y)\\`\n\nIMPORTANT:\n- Output ONLY the \"## 里程碑 (Milestones)\" section.\n- Do NOT output the entire spec file.\n- Do NOT output any preamble or postamble text.\n- Follow this exact format:\n\n\\`\\`\\`markdown\n## 里程碑 (Milestones)\n\n### Milestone 1: [里程碑名称]\n**目标**: [简短描述这个里程碑的目标]\n**预估**: 2 天\n\n**前端任务**:\n- [ ] [F] 前端任务描述 1\n- [ ] [F] 前端任务描述 2\n\n**后端任务**:\n- [ ] [B] 后端任务描述 1 (关联 API: \\`POST /api/xxx\\`)\n- [ ] [B] 后端任务描述 2 (关联 API: \\`GET /api/yyy\\`)\n\n**联调任务**:\n- [ ] [I] 联调任务描述 1 (依赖: F-1, B-1)\n\n### Milestone 2: [里程碑名称]\n...\n\\`\\`\\`\n`;\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils, SpecUtils, EnhancedMilestoneInfo, TodoItem } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\n\ninterface SpecInfo {\n file: string;\n name: string;\n status: '未开始' | '进行中' | '已拆分' | '已完成';\n dependencies: string[];\n index: number;\n}\n\n/**\n * Dev 命令 - 开发模式\n */\nexport const devCommand = new Command('dev')\n .description('开发模式,执行具体任务')\n .action(async () => {\n try {\n logger.header('开发模式');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n logger.success('检测到项目上下文');\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 步骤 1: 扫描并选择 spec\n const selectedSpec = await selectSpec();\n\n // 步骤 2: 解析并选择 milestone\n const selectedMilestone = await selectMilestone(selectedSpec);\n\n // 步骤 3: 选择 todo(如果选择了具体 milestone)\n const selectedTodo = await selectTodo(selectedSpec, selectedMilestone);\n\n // 步骤 4: 调用 Claude 执行开发\n await executeDevelopment(selectedSpec, selectedMilestone, selectedTodo);\n } catch (error: any) {\n logger.error(`开发模式执行失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 步骤 1: 选择 spec 文件\n */\nasync function selectSpec(): Promise<string> {\n logger.step('步骤 1/3: 选择 spec 文件...');\n logger.newLine();\n\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n if (!exists) {\n throw new Error('docs/specs 目录不存在');\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n const specFiles = files.filter((f) => !f.includes('template'));\n\n if (specFiles.length === 0) {\n throw new Error('未找到 spec 文件');\n }\n\n // 解析 spec 信息(状态、依赖)\n const specs: SpecInfo[] = [];\n for (let i = 0; i < specFiles.length; i++) {\n const file = path.join(specDir, specFiles[i]);\n const spec = await FileUtils.read(file);\n\n const status = SpecUtils.parseSpecStatus(spec);\n const dependencies = parseDependencies(spec);\n\n specs.push({\n file,\n name: specFiles[i],\n status,\n dependencies,\n index: i,\n });\n }\n\n // 拓扑排序推荐开发顺序\n const sortedSpecs = topologicalSort(specs);\n\n // 显示选项\n logger.info('可用的 spec 文件:');\n logger.newLine();\n\n const choices = sortedSpecs.map((spec, idx) => {\n const statusIcon = getStatusIcon(spec.status);\n const recommendInfo = idx === 0 ? '[推荐从这开始] ' : '';\n const depInfo =\n spec.dependencies.length > 0 ? `[依赖: ${spec.dependencies.join(', ')}] ` : '';\n\n return {\n name: `${statusIcon} [${spec.status}] ${recommendInfo}${depInfo}${spec.name}`,\n value: spec.file,\n short: spec.name,\n };\n });\n\n logger.info(' ✓ = 已完成 ⟳ = 进行中 ◉ = 已拆分 ○ = 未开始');\n logger.info(' 根据依赖关系推荐的开发顺序已标注');\n logger.newLine();\n\n const { selectedFile } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedFile',\n message: '选择要开发的 spec:',\n choices,\n },\n ]);\n\n logger.success(`已选择: ${selectedFile}`);\n return selectedFile;\n}\n\n/**\n * 步骤 2: 解析并选择 milestone\n */\nasync function selectMilestone(specFile: string): Promise<string> {\n logger.newLine();\n logger.step('步骤 2/3: 解析 milestones...');\n logger.newLine();\n\n const specContent = await FileUtils.read(specFile);\n\n // 尝试增强解析\n const { enhanced, isEnhanced } = SpecUtils.parseMilestonesEnhancedWithFallback(specContent);\n\n if (enhanced.length === 0) {\n logger.info('该 spec 尚未拆分 milestones');\n\n const { breakdownNow } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'breakdownNow',\n message: '是否现在拆分?',\n default: true,\n },\n ]);\n\n if (breakdownNow) {\n // 调用 breakdown 命令\n logger.info('正在调用 breakdown...');\n // TODO: 调用 breakdown 命令\n throw new Error('breakdown 命令需要进一步实现');\n } else {\n logger.info('将直接实现整个 spec');\n return '整个 spec';\n }\n }\n\n // 显示 milestones\n const choices = enhanced.map((m, idx) => {\n const isDone = m.completedCount === m.totalCount && m.totalCount > 0;\n const statusIcon = isDone ? '✓' : m.completedCount > 0 ? '⟳' : '○';\n const progress = `[${m.completedCount}/${m.totalCount}]`;\n const label = isDone ? `✓ ${m.title}` : `${statusIcon} ${progress} ${m.title}`;\n\n // 如果是增强格式,显示更详细的信息\n let detailInfo = `(${m.totalCount} 个任务)`;\n if (isEnhanced) {\n const fCount = m.frontendTodos.filter(t => !t.isCompleted).length;\n const bCount = m.backendTodos.filter(t => !t.isCompleted).length;\n const iCount = m.integrationTodos.filter(t => !t.isCompleted).length;\n const details = [];\n if (fCount > 0) details.push(`前端:${fCount}`);\n if (bCount > 0) details.push(`后端:${bCount}`);\n if (iCount > 0) details.push(`联调:${iCount}`);\n if (details.length > 0) {\n detailInfo = `(${details.join(', ')} 未完成)`;\n }\n }\n\n return {\n name: `${idx + 1}. ${label} ${detailInfo}`,\n value: m.title,\n short: m.title,\n };\n });\n\n choices.push({\n name: `${enhanced.length + 1}. 整个 spec (全部 milestones)`,\n value: '整个 spec',\n short: '整个 spec',\n });\n\n const { milestone } = await inquirer.prompt([\n {\n type: 'list',\n name: 'milestone',\n message: '选择 milestone:',\n choices,\n },\n ]);\n\n return milestone;\n}\n\n/**\n * 步骤 3: 选择 todo 任务\n */\nasync function selectTodo(\n specFile: string,\n milestone: string\n): Promise<string> {\n if (milestone === '整个 spec') {\n return '全部功能';\n }\n\n logger.newLine();\n logger.step('步骤 3/3: 选择 todo 任务...');\n logger.newLine();\n\n const specContent = await FileUtils.read(specFile);\n\n // 尝试增强解析\n const { enhanced, isEnhanced } = SpecUtils.parseMilestonesEnhancedWithFallback(specContent);\n const targetMilestone = enhanced.find(m => m.title === milestone);\n\n // 如果增强解析失败或没有增强格式,回退到简单解析\n if (!targetMilestone || !isEnhanced) {\n return await selectTodoSimple(specFile, milestone);\n }\n\n // 使用增强格式显示\n return await selectTodoEnhanced(targetMilestone);\n}\n\n/**\n * 增强版 todo 选择\n */\nasync function selectTodoEnhanced(milestone: EnhancedMilestoneInfo): Promise<string> {\n const choices: any[] = [];\n\n // 前端任务\n if (milestone.frontendTodos.length > 0) {\n choices.push({ name: `━━ 前端任务 (${milestone.frontendTodos.length}) ━━`, disabled: true });\n milestone.frontendTodos.forEach((todo, idx) => {\n const icon = todo.isCompleted ? '[x]' : '[ ]';\n choices.push({\n name: ` [F] ${icon} ${todo.content}`,\n value: todo.content,\n short: `[F] ${todo.content}`,\n });\n });\n }\n\n // 后端任务\n if (milestone.backendTodos.length > 0) {\n choices.push({ name: `━━ 后端任务 (${milestone.backendTodos.length}) ━━`, disabled: true });\n milestone.backendTodos.forEach((todo, idx) => {\n const icon = todo.isCompleted ? '[x]' : '[ ]';\n const apiInfo = todo.apiAssociation ? ` (${todo.apiAssociation})` : '';\n choices.push({\n name: ` [B] ${icon} ${todo.content}${apiInfo}`,\n value: todo.content,\n short: `[B] ${todo.content}`,\n });\n });\n }\n\n // 联调任务\n if (milestone.integrationTodos.length > 0) {\n choices.push({ name: `━━ 联调任务 (${milestone.integrationTodos.length}) ━━`, disabled: true });\n milestone.integrationTodos.forEach((todo, idx) => {\n const icon = todo.isCompleted ? '[x]' : '[ ]';\n const depsInfo = todo.dependencies ? ` (依赖: ${todo.dependencies.join(', ')})` : '';\n choices.push({\n name: ` [I] ${icon} ${todo.content}${depsInfo}`,\n value: todo.content,\n short: `[I] ${todo.content}`,\n });\n });\n }\n\n // 通用任务\n if (milestone.generalTodos.length > 0) {\n choices.push({ name: `━━ 通用任务 (${milestone.generalTodos.length}) ━━`, disabled: true });\n milestone.generalTodos.forEach((todo, idx) => {\n const icon = todo.isCompleted ? '[x]' : '[ ]';\n choices.push({\n name: ` ${icon} ${todo.content}`,\n value: todo.content,\n short: todo.content,\n });\n });\n }\n\n choices.push({ name: '━━ 其他 ━━', disabled: true });\n choices.push({\n name: `全部任务 (整个 milestone)`,\n value: '全部任务',\n short: '全部任务',\n });\n\n const { todo } = await inquirer.prompt([\n {\n type: 'list',\n name: 'todo',\n message: '选择 todo 任务:',\n choices,\n },\n ]);\n\n return todo;\n}\n\n/**\n * 简单版 todo 选择(向后兼容)\n */\nasync function selectTodoSimple(\n specFile: string,\n milestone: string\n): Promise<string> {\n const specContent = await FileUtils.read(specFile);\n const milestones = SpecUtils.parseMilestones(specContent);\n const targetMilestone = milestones.find(m => m.title === milestone);\n const todos = targetMilestone ? targetMilestone.todos : [];\n\n if (todos.length === 0) {\n logger.warn('该 milestone 没有 todo 任务');\n const { implementAll } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'implementAll',\n message: '实现整个 milestone?',\n default: true,\n },\n ]);\n\n return implementAll ? '全部功能' : milestone;\n }\n\n const choices = todos.map((todo, idx) => ({\n name: `${idx + 1}. ${todo}`,\n value: todo,\n short: todo,\n }));\n\n choices.push({\n name: `${todos.length + 1}. 全部任务 (整个 milestone)`,\n value: '全部任务',\n short: '全部任务',\n });\n\n const { todo } = await inquirer.prompt([\n {\n type: 'list',\n name: 'todo',\n message: '选择 todo 任务:',\n choices,\n },\n ]);\n\n return todo;\n}\n\n/**\n * 步骤 4: 调用 Claude 执行开发\n */\nasync function executeDevelopment(\n specFile: string,\n milestone: string,\n todo: string\n): Promise<void> {\n logger.newLine();\n logger.step('构建 Prompt 并调用 Claude...');\n\n let taskDescription: string;\n if (milestone === '整个 spec') {\n taskDescription = '实现整个 spec 的所有功能';\n } else if (todo === '全部功能' || todo === '全部任务') {\n taskDescription = `实现 milestone '${milestone}' 的所有任务`;\n } else {\n taskDescription = `实现 milestone '${milestone}' 的任务: ${todo}`;\n }\n\n const prompt = buildDevPrompt(specFile, milestone, todo, taskDescription);\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('即将调用 Claude AI...');\n logger.separator('─', 60);\n logger.newLine();\n logger.info(` 任务描述: ${taskDescription}`);\n logger.info(` Spec 文件: ${specFile}`);\n logger.newLine();\n logger.info('📝 Claude 将在下方打开交互界面');\n logger.newLine();\n logger.info('⚠️ 重要提示:');\n logger.info(' 1. 在 Claude 中完成开发任务');\n logger.info(' 2. 按 \"a\" 接受所有编辑建议,或逐个选择');\n logger.info(' 3. 完成后使用 Ctrl+D 或输入 :exit 退出 Claude');\n logger.newLine();\n\n // 调用 Claude 执行开发 (交互式)\n await claudeAI.runTerminal(prompt);\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n // 生成会话日志 (交互式模式下记录任务元数据)\n await generateSessionLog(specFile, milestone, todo, taskDescription, '交互式会话已完成');\n\n // 询问是否更新 spec 文件状态\n await askAndUpdateSpecStatus(specFile, milestone, todo);\n\n logger.header('开发任务完成!');\n logger.success('会话日志已保存');\n logger.newLine();\n logger.info('下一步:');\n logger.step('1. 检查生成的代码');\n logger.step(\"2. 运行 'team-cli dev' 继续下一个任务\");\n logger.newLine();\n}\n\n/**\n * 解析依赖关系\n */\nfunction parseDependencies(spec: string): string[] {\n const deps: string[] = [];\n let inDepsSection = false;\n\n const lines = spec.split('\\n');\n for (const line of lines) {\n // 检测依赖关系部分\n if (line.includes('## 依赖关系') || line.includes('## 依赖')) {\n inDepsSection = true;\n continue;\n }\n\n // 遇到其他二级标题,退出\n if (inDepsSection && line.startsWith('## ')) {\n break;\n }\n\n // 匹配 - [xxx] dependency.md 格式\n const match = line.match(/^-\\s+\\[[ x ]\\]\\s*(.+\\.md)/);\n if (inDepsSection && match) {\n const dep = match[1];\n if (dep !== '无' && dep) {\n deps.push(dep);\n }\n }\n }\n\n return deps;\n}\nfunction topologicalSort(specs: SpecInfo[]): SpecInfo[] {\n const sorted: SpecInfo[] = [];\n const visited = new Set<number>();\n\n function visit(spec: SpecInfo) {\n if (visited.has(spec.index)) return;\n visited.add(spec.index);\n\n // 先访问依赖\n for (const depName of spec.dependencies) {\n const dep = specs.find((s) => s.name === depName);\n if (dep) {\n visit(dep);\n }\n }\n\n sorted.push(spec);\n }\n\n for (const spec of specs) {\n visit(spec);\n }\n\n return sorted;\n}\n\n/**\n * 获取状态图标\n */\nfunction getStatusIcon(status: string): string {\n switch (status) {\n case '已完成':\n return '✓';\n case '进行中':\n return '⟳';\n case '已拆分':\n return '◉';\n default:\n return '○';\n }\n}\n\n\n\n/**\n * 构建开发 prompt\n */\nfunction buildDevPrompt(\n specFile: string,\n milestone: string,\n todo: string,\n taskDescription: string\n): string {\n return `Role: Senior Fullstack Developer\n\nContext:\n- Read and follow TECH_STACK.md for technology choices\n- Read and follow CONVENTIONS.md for coding standards\n- Check AI_MEMORY.md for project context and history\n\nTask: ${taskDescription}\n\nSpec File: ${specFile}\nMilestone: ${milestone}\nTodo: ${todo}\n\nProcess:\n1. First, read and analyze the full spec file\n2. Focus on the selected milestone/todo\n3. Define API endpoints and data models if needed\n4. Write tests first (TDD approach)\n5. Implement the backend code in ./backend\n6. Implement the frontend integration in ./frontend\n7. Update AI_MEMORY.md with completed tasks\n8. Update the spec file to mark completed todos (if applicable)\n\nImportant:\n- Follow the tech stack exactly (Java 17, Spring Boot 3, MyBatis Plus, Next.js 14, TypeScript)\n- Use DTO pattern for all API requests/responses\n- Write clean, well-documented code\n- After completing the task, exit immediately without waiting for further input\n`;\n}\n\n/**\n * 生成会话日志\n */\nasync function generateSessionLog(\n specFile: string,\n milestone: string,\n todo: string,\n taskDescription: string,\n result: string\n): Promise<void> {\n const sessionDir = 'docs/sessions';\n await FileUtils.ensureDir(sessionDir);\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const specName = path.basename(specFile, '.md');\n const logFile = path.join(sessionDir, `${timestamp}_${specName}.md`);\n\n const content = `# 开发会话记录\n\n**时间**: ${new Date().toLocaleString('zh-CN')}\n**Spec**: ${specFile}\n**Milestone**: ${milestone}\n**Todo**: ${todo}\n\n## 任务描述\n\n${taskDescription}\n\n## 执行结果\n\n\\`\\`\\`\n${result}\n\\`\\`\\`\n\n## 生成的文件\n\n<!-- TODO: 列出生成的文件 -->\n\n## 下一步\n\n- [ ] 测试生成的代码\n- [ ] 更新 spec 文件中的 todo 状态\n- [ ] 继续下一个任务\n`;\n\n await FileUtils.write(logFile, content);\n}\n\n/**\n * 询问用户并更新 spec 文件中的 todo 状态\n */\nasync function askAndUpdateSpecStatus(\n specFile: string,\n milestone: string,\n todo: string\n): Promise<void> {\n try {\n const { shouldUpdate } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'shouldUpdate',\n message: '任务是否已完成?是否更新 spec 文件中的 todo 状态?',\n default: true,\n },\n ]);\n\n if (!shouldUpdate) {\n logger.info('跳过更新 spec 文件');\n return;\n }\n\n // 读取 spec 文件\n const content = await FileUtils.read(specFile);\n const lines = content.split('\\n');\n\n // 找到对应的 milestone 和 todo\n let inTargetMilestone = false;\n let targetTodoIndex = -1;\n let milestoneIndex = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // 找到目标 milestone\n if (milestone !== '整个 spec' && line.includes(milestone)) {\n inTargetMilestone = true;\n milestoneIndex = i;\n continue;\n }\n\n // 如果在目标 milestone 中\n if (inTargetMilestone) {\n // 检查是否是另一个 milestone\n if (line.match(/^###\\s+Milestone/)) {\n break;\n }\n\n // 查找目标 todo(支持增强格式)\n if (todo !== '全部功能' && todo !== '全部任务') {\n // 匹配 - [ ] [F/B/I] todo内容 或 - [ ] todo内容\n const todoMatch = line.match(/^-\\s+\\[ \\]\\s*(\\[[FBIN]\\]\\s*)?(.+)/);\n if (todoMatch) {\n const todoContent = todoMatch[2].trim();\n // 移除增强格式的后缀信息\n const cleanContent = todoContent\n .replace(/\\s*\\(关联 API:\\s*`[^`]+`\\)/, '')\n .replace(/\\s*\\(依赖:\\s*[^)]+\\)/, '')\n .trim();\n\n if (cleanContent === todo) {\n targetTodoIndex = i;\n break;\n }\n }\n }\n }\n }\n\n // 如果找到 todo,更新状态\n if (targetTodoIndex !== -1) {\n const line = lines[targetTodoIndex];\n lines[targetTodoIndex] = line.replace(/^-\\s+\\[ \\]/, '- [x]');\n logger.success(`已标记 todo 为完成: ${todo}`);\n } else if (todo === '全部功能' || todo === '全部任务') {\n // 如果是全部任务,标记整个 milestone 的所有 todos\n let updatedCount = 0;\n for (let i = milestoneIndex + 1; i < lines.length; i++) {\n const line = lines[i];\n // 遇到另一个 milestone,退出\n if (line.match(/^###\\s+Milestone/)) {\n break;\n }\n // 更新 todo 状态(支持增强格式)\n if (line.match(/^-\\s+\\[ \\]/)) {\n lines[i] = line.replace(/^-\\s+\\[ \\]/, '- [x]');\n updatedCount++;\n }\n }\n logger.success(`已标记 ${updatedCount} 个 todos 为完成`);\n } else {\n logger.warn('未找到对应的 todo 项');\n return;\n }\n\n // 重新通过进度推导最新状态并同步到文件头部\n const newContent = lines.join('\\n');\n const computedStatus = SpecUtils.parseSpecStatus(newContent);\n\n let finalLines = lines;\n // 自动更新文件头部的状态声明\n const statusLineIndex = finalLines.findIndex(l => l.match(/状态.*[::]/));\n if (statusLineIndex !== -1) {\n const oldLine = finalLines[statusLineIndex];\n const newLine = oldLine.replace(/([::]\\s*)(.+)/, `$1**${computedStatus}**`);\n if (oldLine !== newLine) {\n finalLines[statusLineIndex] = newLine;\n logger.info(`自动同步 Spec 头部状态为: ${computedStatus}`);\n }\n }\n\n // 写回文件\n await FileUtils.write(specFile, finalLines.join('\\n'));\n logger.success('Spec 文件已更新');\n } catch (error) {\n logger.warn(`更新 spec 文件失败: ${error}`);\n }\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils, StringUtils, SpecUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { Listr } from 'listr2';\n\n/**\n * Add-feature 命令 - 添加新功能\n */\nexport const addFeatureCommand = new Command('add-feature')\n .argument('<feature-name>', '功能名称')\n .description('添加新功能(支持 PRD 或简单描述模式)')\n .action(async (featureName) => {\n try {\n logger.header('添加新功能');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info('请先运行 team-cli init 或切换到项目目录');\n process.exit(1);\n }\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 转换为 kebab-case\n const featureSlug = StringUtils.toKebabCase(featureName);\n\n // 检查 PRD 是否已存在\n const prdFile = path.join('docs/prd-docs', `${featureSlug}.md`);\n const prdExists = await FileUtils.exists(prdFile);\n if (prdExists) {\n logger.error(`PRD 文件已存在: ${prdFile}`);\n logger.info('如需重新生成,请先删除:');\n logger.info(` rm ${prdFile}`);\n process.exit(1);\n }\n\n // 选择模式\n const { mode } = await inquirer.prompt([\n {\n type: 'list',\n name: 'mode',\n message: '选择需求输入模式:',\n choices: [\n { name: 'PRD 文档模式 (已有详细 PRD 文档)', value: 'prd' },\n { name: '简单描述模式 (一句话需求 + 模块依赖)', value: 'simple' },\n ],\n },\n ]);\n\n // 执行对应模式\n if (mode === 'prd') {\n await addFeatureFromPrd(featureName, featureSlug, prdFile);\n } else {\n await addFeatureSimple(featureName, featureSlug, prdFile);\n }\n } catch (error: any) {\n logger.error(`添加功能失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * PRD 文档模式\n */\nasync function addFeatureFromPrd(\n featureName: string,\n _featureSlug: string, // 保留参数以保持接口一致,但不使用\n prdOutputFile: string\n): Promise<void> {\n const { prdPath } = await inquirer.prompt([\n {\n type: 'input',\n name: 'prdPath',\n message: '请输入 PRD 文档路径:',\n validate: async (input: string) => {\n const exists = await FileUtils.exists(input);\n return exists || 'PRD 文档不存在';\n },\n },\n ]);\n\n const tasks = new Listr([\n {\n title: '读取 PRD 文档',\n task: async (ctx) => {\n ctx.prdContent = await FileUtils.read(prdPath);\n },\n },\n {\n title: '扫描已完成功能',\n task: async (ctx) => {\n const specDir = 'docs/specs';\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n ctx.completedSpecs = [];\n for (const file of specs) {\n const status = await SpecUtils.getSpecStatus(path.join(specDir, file));\n if (status === '已完成') {\n ctx.completedSpecs.push(file.replace('.md', ''));\n }\n }\n },\n },\n {\n title: '构建项目上下文',\n task: async (ctx) => {\n ctx.projectContext = await buildProjectContext();\n },\n },\n {\n title: '调用 Claude 生成 PRD',\n task: async (ctx) => {\n const prompt = buildPrdPrompt(\n featureName,\n ctx.prdContent,\n ctx.projectContext,\n ctx.completedSpecs\n );\n\n // 直接调用 Claude,不在 Listr 任务中输出分隔符,避免渲染冲突\n const result = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md', 'AI_MEMORY.md'],\n });\n\n ctx.generatedPrd = result;\n },\n },\n {\n title: '保存 PRD 文件',\n task: async (ctx) => {\n await FileUtils.write(prdOutputFile, ctx.generatedPrd);\n },\n },\n ]);\n\n await tasks.run();\n\n // 输出分隔符和成功信息\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n logger.success(`PRD 文件已生成: ${prdOutputFile}`);\n await showPrdPreview(prdOutputFile);\n await askToAdjust(prdOutputFile, 'prd');\n}\n\n/**\n * 简单描述模式\n */\nasync function addFeatureSimple(\n featureName: string,\n _featureSlug: string, // 保留参数以保持接口一致,但不使用\n prdOutputFile: string\n): Promise<void> {\n // 收集功能描述\n const { description } = await inquirer.prompt([\n {\n type: 'input',\n name: 'description',\n message: '功能描述 (一句话说明):',\n validate: (input: string) => input.trim().length > 0 || '描述不能为空',\n },\n ]);\n\n const tasks = new Listr([\n {\n title: '扫描已完成功能',\n task: async (ctx) => {\n const specDir = 'docs/specs';\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n ctx.completedSpecs = [];\n for (const file of specs) {\n const status = await SpecUtils.getSpecStatus(path.join(specDir, file));\n if (status === '已完成') {\n ctx.completedSpecs.push(file.replace('.md', ''));\n }\n }\n },\n },\n {\n title: '选择依赖功能',\n task: async (ctx) => {\n if (ctx.completedSpecs.length === 0) {\n ctx.selectedDeps = [];\n return;\n }\n\n const { dependencies } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'dependencies',\n message: '选择此功能依赖的已有功能 (可多选,直接回车跳过):',\n choices: ctx.completedSpecs,\n },\n ]);\n\n ctx.selectedDeps = dependencies;\n },\n },\n {\n title: '构建项目上下文',\n task: async (ctx) => {\n ctx.projectContext = await buildProjectContext();\n },\n },\n {\n title: '调用 Claude 生成 PRD',\n task: async (ctx) => {\n const prompt = buildSimplePrompt(\n featureName,\n description,\n ctx.projectContext,\n ctx.selectedDeps\n );\n\n // 直接调用 Claude,不在 Listr 任务中输出分隔符,避免渲染冲突\n const result = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md', 'AI_MEMORY.md'],\n });\n\n ctx.generatedPrd = result;\n },\n },\n {\n title: '保存 PRD 文件',\n task: async (ctx) => {\n await FileUtils.write(prdOutputFile, ctx.generatedPrd);\n },\n },\n ]);\n\n await tasks.run();\n\n // 输出分隔符和成功信息\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n logger.success(`PRD 文件已生成: ${prdOutputFile}`);\n await showPrdPreview(prdOutputFile);\n await askToAdjust(prdOutputFile, 'prd');\n}\n\n/**\n * 构建项目上下文\n */\nasync function buildProjectContext(): Promise<string> {\n const context: string[] = [];\n\n // 扫描后端目录\n if (await FileUtils.exists('backend/src/main/java')) {\n context.push('### 后端结构');\n const backendDirs = await FileUtils.findFiles('*/', 'backend/src/main/java');\n const limited = backendDirs.slice(0, 10);\n limited.forEach((dir) => {\n context.push(` - backend/src/main/java/${dir}`);\n });\n }\n\n // 扫描前端目录\n if (await FileUtils.exists('frontend/src')) {\n context.push('');\n context.push('### 前端结构');\n const frontendDirs = await FileUtils.findFiles('*/', 'frontend/src');\n const limited = frontendDirs.slice(0, 10);\n limited.forEach((dir) => {\n context.push(` - frontend/src/${dir}`);\n });\n }\n\n // 扫描已有 specs\n if (await FileUtils.exists('docs/specs')) {\n context.push('');\n context.push('### 已有功能');\n const files = await FileUtils.findFiles('*.md', 'docs/specs');\n const specs = files.filter((f) => !f.includes('template'));\n\n for (const file of specs) {\n const status = await SpecUtils.getSpecStatus(path.join('docs/specs', file));\n context.push(` - ${file.replace('.md', '')} [${status}]`);\n }\n }\n\n return context.join('\\n');\n}\n\n/**\n * 构建 PRD 模式 prompt\n */\nfunction buildPrdPrompt(\n featureName: string,\n prdContent: string,\n projectContext: string,\n completedSpecs: string[]\n): string {\n const deps = completedSpecs.length > 0 ? completedSpecs.join('、') : '(无)';\n\n return `Role: Senior Fullstack Developer\n\n你现在需要根据 PRD 文档生成一个功能规格(Spec)文档。\n\n## 项目技术栈\n后端: Java 17 + Spring Boot 3 + MyBatis Plus + MySQL 8.0\n前端: Next.js 14 (App Router) + TypeScript + Tailwind CSS\n\n## 项目当前状态\n${projectContext}\n\n## 功能名称\n${featureName}\n\n## PRD 文档内容\n${prdContent}\n\n## 依赖功能\n此功能可能依赖以下已完成的功能:${deps}\n\n## 任务\n请根据 PRD 文档,生成一个完整的功能规格文档 Spec。\n\n## Spec 文档格式要求\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: ${featureName}\n**优先级**: P0/P1/P2 (根据功能重要性判断)\n**预估工时**: X 天 (根据复杂度评估:简单1-2天,中等3-5天,复杂5-10天)\n**状态**: 待拆分\n**创建日期**: ${new Date().toISOString().split('T')[0]}\n\n## 依赖关系\n**前置依赖**:\n${completedSpecs.map((s) => `- [x] ${s}`).join('\\n') || '- (无)'}\n\n**被依赖于**:\n- (自动生成,表示哪些 spec 依赖本功能)\n\n## 背景与目标\n[根据 PRD 提取背景和目标]\n\n## 功能需求\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n[从 PRD 提取 3-8 个主要功能点]\n\n## 技术设计\n### API 设计\n列出主要的 API 端点,格式:\n- \\`METHOD /api/path\\` - 简短说明\n\n### 数据模型\n列出需要的数据表,格式:\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n> 注: 使用 \\`team-cli breakdown ${featureName}.md\\` 拆分此 spec 为 milestones 和 todos\n\n----\n*生成于: ${new Date().toISOString()} by Claude*\n\\`\\`\\`\n\n## 注意事项\n1. 只生成 Spec 文档,不要实现任何代码\n2. 优先级判断标准:\n - P0: 核心功能,阻塞其他功能\n - P1: 重要功能,影响用户体验\n - P2: 增强功能,锦上添花\n3. 工时评估标准:\n - 简单功能: 1-2 天\n - 中等功能: 3-5 天\n - 复杂功能: 5-10 天\n4. 功能点要具体可执行,避免过于抽象\n5. API 和数据模型要符合实际技术栈\n6. 从 PRD 中提取关键信息,保持简洁`;\n}\n\n/**\n * 构建简单描述模式 prompt\n */\nfunction buildSimplePrompt(\n featureName: string,\n description: string,\n projectContext: string,\n dependencies: string[]\n): string {\n const deps = dependencies.length > 0 ? dependencies.join('、') : '(无)';\n\n return `Role: Senior Fullstack Developer\n\n用户想要添加一个新功能,需要你生成功能规格文档(Spec)。\n\n## 功能名称\n${featureName}\n\n## 功能描述\n${description}\n\n## 依赖功能\n此功能依赖以下已完成的功能:${deps}\n\n## 项目技术栈\n后端: Java 17 + Spring Boot 3 + MyBatis Plus + MySQL 8.0\n前端: Next.js 14 (App Router) + TypeScript + Tailwind CSS\n\n## 项目当前状态\n${projectContext}\n\n## 任务\n请根据功能描述,生成一个完整的功能规格文档 Spec。\n\n## Spec 文档格式要求\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: ${featureName}\n**优先级**: P0/P1/P2 (根据功能重要性判断)\n**预估工时**: X 天 (根据复杂度评估:简单1-2天,中等3-5天,复杂5-10天)\n**状态**: 待拆分\n**创建日期**: ${new Date().toISOString().split('T')[0]}\n\n## 依赖关系\n**前置依赖**:\n${dependencies.map((d) => `- [x] ${d}`).join('\\n') || '- (无)'}\n\n**被依赖于**:\n- (自动生成,表示哪些 spec 依赖本功能)\n\n## 背景与目标\n[根据功能描述,简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n列出 3-8 个主要功能点,每个功能点用一句话描述。\n\n## 技术设计\n### API 设计\n列出主要的 API 端点,格式:\n- \\`METHOD /api/path\\` - 简短说明\n\n### 数据模型\n列出需要的数据表,格式:\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n> 注: 使用 \\`team-cli breakdown ${featureName}.md\\` 拆分此 spec 为 milestones 和 todos\n\n----\n*生成于: ${new Date().toISOString()} by Claude*\n\\`\\`\\`\n\n## 注意事项\n1. 只生成 Spec 文档,不要实现任何代码\n2. 优先级判断要合理,避免全部是 P0\n3. 工时评估要实际,不要过于乐观\n4. 功能点要具体可执行\n5. 根据功能描述推断合理的 API 和数据模型\n6. 参考已有功能的技术风格保持一致性`;\n}\n\n/**\n * 更新 AI_MEMORY\n */\nasync function updateAiMemory(featureName: string, featureSlug: string): Promise<void> {\n const aiMemoryFile = 'AI_MEMORY.md';\n const exists = await FileUtils.exists(aiMemoryFile);\n\n if (!exists) {\n logger.warn('AI_MEMORY.md 不存在,跳过更新');\n return;\n }\n\n let content = await FileUtils.read(aiMemoryFile);\n \n // 格式化功能名称:将 kebab-case 和 snake_case 转换为 Title Case\n const featureDisplay = featureName\n .replace(/[-_]/g, ' ')\n .split(' ')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n \n const newRow = `| ${featureDisplay} | ${featureSlug}.md | ○ 未开始 | 0/0 | - | |`;\n\n // 检查是否有功能清单部分\n if (!content.includes('## 功能清单')) {\n // 没有功能清单,直接追加到文件末尾\n content += `\\n## 功能清单 (Feature Inventory)\\n\\n| 功能 | Spec 文件 | 状态 | 进度 | 完成日期 | 备注 |\\n|------|----------|------|------|---------|------|\\n${newRow}\\n`;\n } else {\n // 已有功能清单,在表头分隔线后插入新行\n const lines = content.split('\\n');\n let featureInventorySection = false;\n let insertIndex = -1;\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n \n // 检测进入功能清单部分\n if (line.includes('## 功能清单')) {\n featureInventorySection = true;\n continue;\n }\n \n // 检测离开功能清单部分(遇到下一个 ## 标题)\n if (featureInventorySection && line.startsWith('## ') && !line.includes('功能清单')) {\n break;\n }\n \n // 在功能清单部分找到表头分隔线(|------|...)\n if (featureInventorySection && /^\\|[-]+\\|/.test(line.trim())) {\n insertIndex = i + 1;\n break;\n }\n }\n \n if (insertIndex !== -1) {\n lines.splice(insertIndex, 0, newRow);\n content = lines.join('\\n');\n } else {\n // 如果找不到合适的位置,直接在功能清单标题后添加完整表格\n const sectionIndex = lines.findIndex(line => line.includes('## 功能清单'));\n if (sectionIndex !== -1) {\n const tableLines = [\n '',\n '| 功能 | Spec 文件 | 状态 | 进度 | 完成日期 | 备注 |',\n '|------|----------|------|------|---------|------|',\n newRow,\n ''\n ];\n lines.splice(sectionIndex + 1, 0, ...tableLines);\n content = lines.join('\\n');\n } else {\n content += `\\n${newRow}\\n`;\n }\n }\n }\n\n await FileUtils.write(aiMemoryFile, content);\n}\n\n/**\n * 显示 PRD 预览\n */\nasync function showPrdPreview(prdFile: string): Promise<void> {\n logger.newLine();\n logger.header('生成的 PRD 预览:');\n logger.newLine();\n\n try {\n const content = await FileUtils.read(prdFile);\n\n if (!content || content.trim().length === 0) {\n logger.warn('PRD 文件内容为空');\n return;\n }\n\n const lines = content.split('\\n');\n if (lines.length === 0) {\n logger.warn('PRD 文件没有内容');\n return;\n }\n\n const preview = lines.slice(0, 40).join('\\n');\n\n console.log(preview);\n if (lines.length > 40) {\n console.log('...');\n console.log(`(共 ${lines.length} 行)`);\n }\n console.log('');\n } catch (error: any) {\n logger.error(`读取 PRD 预览失败: ${error.message}`);\n }\n}\n\n/**\n * 显示 Spec 预览\n */\nasync function showSpecPreview(specFile: string): Promise<void> {\n logger.newLine();\n logger.header('生成的 Spec 预览:');\n logger.newLine();\n\n try {\n const content = await FileUtils.read(specFile);\n\n if (!content || content.trim().length === 0) {\n logger.warn('Spec 文件内容为空');\n return;\n }\n\n const lines = content.split('\\n');\n if (lines.length === 0) {\n logger.warn('Spec 文件没有内容');\n return;\n }\n\n const preview = lines.slice(0, 40).join('\\n');\n\n console.log(preview);\n if (lines.length > 40) {\n console.log('...');\n console.log(`(共 ${lines.length} 行)`);\n }\n console.log('');\n } catch (error: any) {\n logger.error(`读取 Spec 预览失败: ${error.message}`);\n }\n}\n\n/**\n * 询问是否需要调整\n */\nasync function askToAdjust(file: string, type: 'prd' | 'spec' = 'spec'): Promise<void> {\n const typeLabel = type === 'prd' ? 'PRD' : 'Spec';\n const { needAdjust } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'needAdjust',\n message: `是否需要调整 ${typeLabel} 内容?`,\n default: false,\n },\n ]);\n\n if (needAdjust) {\n logger.info('正在打开编辑器...');\n const editor = process.env.EDITOR || 'vim';\n const { execaCommand } = await import('execa');\n await execaCommand(`${editor} ${file}`, { stdio: 'inherit' });\n }\n\n logger.newLine();\n logger.info('下一步:');\n if (type === 'prd') {\n logger.step(`1. 运行 'team-cli split-prd ${file}' 生成 Spec 规格文档`);\n logger.step(\"2. 运行 'team-cli breakdown <spec-file>' 拆分为 milestones\");\n } else {\n logger.step(`1. 运行 'team-cli breakdown ${file}' 拆分为 milestones`);\n logger.step(\"2. 运行 'team-cli dev' 选择 milestone 进行开发\");\n }\n logger.newLine();\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils, StringUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { Listr } from 'listr2';\n\n/**\n * Split-prd 命令 - 将 PRD 转换为 Spec\n * 支持两种模式:\n * 1. 单文件模式:team-cli split-prd docs/prd-docs/login.md -> 生成单个 spec\n * 2. 目录模式:team-cli split-prd docs/prd-docs -> 扫描目录下所有 PRD 生成多个 specs\n */\nexport const splitPrdCommand = new Command('split-prd')\n .argument('<prd-path>', 'PRD 文档路径 (支持单文件或目录)')\n .description('将 PRD 转换为 Spec 规格文档')\n .action(async (prdPath) => {\n try {\n logger.header('PRD → Spec 转换');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 检查路径是否存在\n const pathExists = await FileUtils.exists(prdPath);\n if (!pathExists) {\n throw new Error(`PRD 路径不存在: ${prdPath}`);\n }\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 判断是单文件还是目录\n const isSingleFile = prdPath.endsWith('.md') || prdPath.endsWith('.txt') || prdPath.endsWith('.markdown');\n \n if (isSingleFile) {\n await processSinglePrd(prdPath);\n } else {\n await processMultiplePrds(prdPath);\n }\n } catch (error: any) {\n logger.error(`PRD 转换失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 处理单个 PRD 文件 -> 生成单个 Spec\n */\nasync function processSinglePrd(prdFile: string): Promise<void> {\n // 从文件名提取功能名称\n const baseName = path.basename(prdFile, path.extname(prdFile));\n const featureSlug = StringUtils.toKebabCase(baseName);\n const specFile = path.join('docs/specs', `${featureSlug}.md`);\n\n // 检查 Spec 是否已存在\n const specExists = await FileUtils.exists(specFile);\n if (specExists) {\n logger.error(`Spec 文件已存在: ${specFile}`);\n logger.info('如需重新生成,请先删除:');\n logger.info(` rm ${specFile}`);\n process.exit(1);\n }\n\n const tasks = new Listr([\n {\n title: '读取 PRD 内容',\n task: async (ctx) => {\n ctx.prdContent = await FileUtils.read(prdFile);\n logger.success(`读取 PRD: ${prdFile}`);\n },\n },\n {\n title: '调用 Claude 生成 Spec',\n task: async (ctx) => {\n const prompt = buildSinglePrdToSpecPrompt(ctx.prdContent, featureSlug);\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 执行中...');\n logger.separator('─', 60);\n logger.newLine();\n\n ctx.specContent = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md', 'AI_MEMORY.md'],\n });\n },\n },\n {\n title: '保存 Spec 文件',\n task: async (ctx) => {\n await FileUtils.write(specFile, ctx.specContent);\n },\n },\n {\n title: '更新 AI_MEMORY',\n task: async () => {\n await updateAiMemory(baseName, featureSlug);\n },\n },\n ]);\n\n await tasks.run();\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n logger.header('PRD → Spec 转换完成!');\n logger.success(`Spec 文件已生成: ${specFile}`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step(`1. 运行 'team-cli breakdown ${specFile}' 拆分为 milestones`);\n logger.step(\"2. 运行 'team-cli dev' 选择 milestone 进行开发\");\n logger.newLine();\n}\n\n/**\n * 处理 PRD 目录 -> 生成多个 Specs(原有逻辑)\n */\nasync function processMultiplePrds(prdFolder: string): Promise<void> {\n // 执行 PRD 拆分任务\n const tasks = new Listr([\n {\n title: '扫描 PRD 文件',\n task: async (ctx) => {\n const supportedExtensions = ['md', 'txt', 'markdown'];\n ctx.prdFiles = [];\n\n for (const ext of supportedExtensions) {\n const files = await FileUtils.findFiles(`*.${ext}`, prdFolder);\n ctx.prdFiles.push(...files.map((f) => path.join(prdFolder, f)));\n }\n\n if (ctx.prdFiles.length === 0) {\n throw new Error(\n '未找到 PRD 文档 (支持 .md, .txt, .markdown)'\n );\n }\n\n ctx.prdFile = ctx.prdFiles[0];\n if (ctx.prdFiles.length > 1) {\n logger.info(`找到多个 PRD 文档,使用: ${ctx.prdFile}`);\n } else {\n logger.success(`找到 PRD 文档: ${ctx.prdFile}`);\n }\n },\n },\n {\n title: '扫描截图文件',\n task: async (ctx) => {\n const screenshotDir = path.join(prdFolder, 'screenshots');\n const dirExists = await FileUtils.exists(screenshotDir);\n\n if (!dirExists) {\n logger.info('未找到 screenshots 目录,跳过截图');\n ctx.screenshots = [];\n return;\n }\n\n const imageExtensions = ['png', 'jpg', 'jpeg', 'gif', 'webp'];\n ctx.screenshots = [];\n\n for (const ext of imageExtensions) {\n const files = await FileUtils.findFiles(`*.${ext}`, screenshotDir);\n ctx.screenshots.push(...files.map((f) => path.join(screenshotDir, f)));\n }\n\n logger.success(`找到 ${ctx.screenshots.length} 个截图文件`);\n },\n },\n {\n title: '扫描 demo 代码仓库',\n task: async (ctx) => {\n const entries = await FileUtils.findFiles('*/', prdFolder);\n ctx.demoRepos = [];\n\n for (const entry of entries) {\n const dirPath = path.join(prdFolder, entry);\n const gitDir = path.join(dirPath, '.git');\n const hasGit = await FileUtils.exists(gitDir);\n if (hasGit) {\n ctx.demoRepos.push(dirPath);\n }\n }\n\n if (ctx.demoRepos.length > 0) {\n logger.success(`找到 demo 仓库: ${ctx.demoRepos.join(', ')}`);\n } else {\n logger.info('未找到 demo 代码仓库,跳过');\n }\n },\n },\n {\n title: '读取 PRD 内容',\n task: async (ctx) => {\n ctx.prdContent = await FileUtils.read(ctx.prdFile);\n },\n },\n {\n title: '调用 Claude 拆分 PRD',\n task: async (ctx) => {\n const prompt = buildSplitPrdPrompt(\n ctx.prdContent,\n ctx.screenshots,\n ctx.demoRepos\n );\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 执行中...');\n logger.separator('─', 60);\n logger.newLine();\n\n return await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md'],\n });\n },\n },\n ]);\n\n await tasks.run();\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n logger.header('PRD 拆分完成!');\n logger.success('Spec 文件已生成到 docs/specs/ 目录');\n logger.newLine();\n\n logger.info('下一步:');\n logger.step(\"1. 检查生成的 spec 文件\");\n logger.step(\"2. 运行 'team-cli breakdown <spec-file>' 拆分 milestones\");\n logger.step(\"3. 运行 'team-cli dev' 开始开发\");\n logger.newLine();\n}\n\n/**\n * 更新 AI_MEMORY - 添加功能到功能清单\n */\nasync function updateAiMemory(featureName: string, featureSlug: string): Promise<void> {\n const aiMemoryFile = 'AI_MEMORY.md';\n const memoryExists = await FileUtils.exists(aiMemoryFile);\n if (!memoryExists) {\n logger.warn('AI_MEMORY.md 不存在,跳过更新');\n return;\n }\n\n let content = await FileUtils.read(aiMemoryFile);\n\n // 格式化功能名称:将 kebab-case 和 snake_case 转换为 Title Case\n const featureDisplay = featureName\n .replace(/[-_]/g, ' ')\n .split(' ')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n\n const newRow = `| ${featureDisplay} | ${featureSlug}.md | ○ 未开始 | 0/0 | - | |`;\n\n // 检查功能是否已存在\n if (content.includes(`| ${featureDisplay} |`) || content.includes(`${featureSlug}.md`)) {\n logger.info(`功能 ${featureDisplay} 已存在于 AI_MEMORY,跳过`);\n return;\n }\n\n // 查找功能清单表格并插入新行\n const lines = content.split('\\n');\n let insertIndex = -1;\n let featureInventorySection = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // 找到功能清单部分\n if (line.includes('功能清单') || line.includes('Feature Inventory')) {\n featureInventorySection = true;\n }\n\n // 在功能清单部分找到表头分隔线(|------|...)\n if (featureInventorySection && /^\\|[-]+\\|/.test(line.trim())) {\n insertIndex = i + 1;\n break;\n }\n }\n\n if (insertIndex > 0) {\n lines.splice(insertIndex, 0, newRow);\n content = lines.join('\\n');\n } else {\n content += `\\n${newRow}\\n`;\n }\n\n await FileUtils.write(aiMemoryFile, content);\n}\n\n/**\n * 构建单个 PRD 转 Spec 的 prompt\n */\nfunction buildSinglePrdToSpecPrompt(prdContent: string, featureSlug: string): string {\n return `Role: Senior Technical Architect\n\nTask: Convert the following PRD (Product Requirements Document) into a detailed technical Spec.\n\nContext:\n- Read TECH_STACK.md for technology constraints\n- Read CONVENTIONS.md for coding standards\n- Read AI_MEMORY.md for project status\n\nPRD Content:\n\\`\\`\\`\n${prdContent}\n\\`\\`\\`\n\nOutput Requirements:\nGenerate a complete Spec document with the following sections:\n\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: [功能中文名]\n**优先级**: P0/P1/P2 (根据功能重要性判断)\n**预估工时**: X 天 (根据复杂度评估:简单1-2天,中等3-5天,复杂5-10天)\n**状态**: 待拆分\n**创建日期**: ${new Date().toISOString().split('T')[0]}\n\n## 依赖关系\n**前置依赖**:\n- (列出依赖的其他功能)\n\n**被依赖于**:\n- (自动生成)\n\n## 背景与目标\n[根据 PRD 提取背景和目标]\n\n## 功能需求\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n[从 PRD 提取 3-8 个主要功能点]\n\n## 技术设计\n### API 设计\n列出主要的 API 端点,格式:\n- \\`METHOD /api/path\\` - 简短说明\n\n### 数据模型\n列出需要的数据表,格式:\n- \\`table_name\\` (表说明) - 字段说明\n\n### 前端组件\n列出需要的主要前端组件\n\n### 后端模块\n列出需要的后端模块结构\n\n## 验收标准\n- [ ] 验收标准 1\n- [ ] 验收标准 2\n- [ ] 验收标准 3\n\n## 里程碑 (Milestones)\n> 注: 使用 \\`team-cli breakdown ${featureSlug}.md\\` 拆分此 spec 为 milestones 和 todos\n\n----\n*生成于: ${new Date().toISOString()} by Claude*\n\\`\\`\\`\n\nIMPORTANT:\n1. Only output the Spec document content, no additional text\n2. Make sure to include comprehensive API and data model design\n3. Priority should be justified based on feature importance\n4. Work estimation should be realistic\n5. Extract key requirements from the PRD accurately\n`;\n}\n\n/**\n * 构建 PRD 拆分 prompt\n */\nfunction buildSplitPrdPrompt(\n prdContent: string,\n screenshots: string[],\n demoRepos: string[]\n): string {\n let prompt = `Role: Senior Product Manager and Technical Architect\n\nTask: Analyze the following PRD and split it into multiple independent feature specifications (specs).\n\nContext:\n- Read TECH_STACK.md for technology constraints\n- Read CONVENTIONS.md for coding standards\n- Each spec should be a standalone feature that can be developed independently\n\nPRD Content:\n\\`\\`\\`\n${prdContent}\n\\`\\`\\`\n`;\n\n // 添加截图信息\n if (screenshots.length > 0) {\n prompt += `\nScreenshots available (${screenshots.length} files):\n`;\n for (const screenshot of screenshots) {\n prompt += ` - ${screenshot}\\n`;\n }\n prompt += `You can use the Read tool to view these screenshots for visual reference.\n`;\n }\n\n // 添加 demo 仓库信息\n if (demoRepos.length > 0) {\n prompt += `\nDemo Code Repos available:\n`;\n for (const repo of demoRepos) {\n prompt += ` - ${repo}\\n`;\n }\n prompt += `You can explore these repos to understand existing implementation patterns.\n`;\n }\n\n prompt += `\nOutput Requirements:\n1. Split the PRD into multiple feature specs based on functionality\n2. Each spec should follow the template format (see docs/specs/template.md)\n3. Create each spec as a separate markdown file in docs/specs/\n4. Use kebab-case for filenames (e.g., user-authentication.md, data-export.md)\n5. Each spec must include:\n - Feature Overview (功能概述)\n - Background & Goals (背景与目标)\n - Functional Requirements (功能需求)\n - Technical Design (技术设计)\n - Acceptance Criteria (验收标准)\n\nSpec Format Template:\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: [功能中文名]\n**优先级**: P0/P1/P2\n**预估工时**: X 天\n**状态**: 待拆分\n**创建日期**: ${new Date().toISOString().split('T')[0]}\n\n## 依赖关系\n**前置依赖**:\n- (列出依赖的其他 spec)\n\n**被依赖于**:\n- (自动生成)\n\n## 背景与目标\n[简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n列出 3-8 个主要功能点\n\n## 技术设计\n\n### API 设计\n列出主要的 API 端点\n\n### 数据模型\n列出需要的数据表\n\n## 验收标准\n- [ ] 验收标准 1\n- [ ] 验收标准 2\n- [ ] 验收标准 3\n\n----\n*生成于: ${new Date().toISOString()} by Claude*\n\\`\\`\\`\n\nIMPORTANT:\n- After generating all spec files, exit immediately without waiting for further input\n- Do not ask any questions\n- Each spec should be implementable in 1-3 days\n- Dependencies between features should be clearly noted in the 依赖关系 section\n`;\n\n return prompt;\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils, StringUtils, DateUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { Listr } from 'listr2';\n\n/**\n * Bugfix 命令 - 创建 Bugfix 记录\n */\nexport const bugfixCommand = new Command('bugfix')\n .description('创建 Bugfix 记录')\n .action(async () => {\n try {\n logger.header('创建 Bugfix 记录');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 交互式收集 bug 信息\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'severity',\n message: 'Bug 严重程度:',\n choices: [\n { name: '高 - 阻塞功能或影响核心流程', value: '高' },\n { name: '中 - 影响功能但不阻塞', value: '中' },\n { name: '低 - 小问题或体验问题', value: '低' },\n ],\n default: '中',\n },\n {\n type: 'input',\n name: 'description',\n message: 'Bug 描述:',\n validate: (input: string) => input.trim().length > 0 || '描述不能为空',\n },\n {\n type: 'input',\n name: 'reproduction',\n message: '复现步骤:',\n default: '1. 步骤一\\n2. 步骤二\\n3. 步骤三',\n },\n {\n type: 'list',\n name: 'scope',\n message: '影响范围:',\n choices: ['全部用户', '部分用户', '个别用户', '未知'],\n default: '部分用户',\n },\n ]);\n\n // 生成 bug ID\n const bugId = generateBugId();\n const timestamp = DateUtils.format(new Date(), 'YYYY-MM-DD');\n\n // 查找可能关联的 spec\n const relatedSpec = await findRelatedSpec(answers.description);\n\n // 创建 bugfix 文档\n const bugfixDir = 'docs/bugfixes';\n await FileUtils.ensureDir(bugfixDir);\n\n const bugfixFile = path.join(bugfixDir, `${timestamp}_${bugId}.md`);\n\n const content = formatBugfixDocument({\n id: bugId,\n severity: answers.severity,\n description: answers.description,\n reproduction: answers.reproduction,\n scope: answers.scope,\n relatedSpec,\n timestamp,\n });\n\n await FileUtils.write(bugfixFile, content);\n\n logger.success(`Bugfix 记录已创建: ${bugfixFile}`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step('1. 分析 bug 根本原因');\n logger.step(\"2. 运行 'team-cli dev' 选择关联的 spec 进行修复\");\n logger.step('3. 修复后更新 bugfix 文档状态');\n logger.newLine();\n } catch (error: any) {\n logger.error(`创建 bugfix 失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * Hotfix 命令 - 紧急修复\n */\nexport const hotfixCommand = new Command('hotfix')\n .description('紧急修复流程')\n .action(async () => {\n try {\n logger.header('紧急修复流程');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n logger.warn('注意: hotfix 用于紧急问题修复');\n logger.warn('修复后需要创建规范 bugfix 记录');\n logger.newLine();\n\n // 交互式收集信息\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'description',\n message: '紧急问题描述:',\n validate: (input: string) => input.trim().length > 0 || '描述不能为空',\n },\n {\n type: 'list',\n name: 'scope',\n message: '影响范围:',\n choices: ['所有用户', '部分用户', '特定用户'],\n default: '所有用户',\n },\n {\n type: 'input',\n name: 'solution',\n message: '临时解决方案:',\n validate: (input: string) => input.trim().length > 0 || '方案不能为空',\n },\n ]);\n\n // 生成 hotfix ID\n const hotfixId = generateHotfixId();\n const branchName = `hotfix/${hotfixId}`;\n\n // 创建 hotfix 分支并提交\n const tasks = new Listr([\n {\n title: '创建 hotfix 分支',\n task: async () => {\n const { execa } = await import('execa');\n await execa('git', ['checkout', '-b', branchName], { stdio: 'inherit' });\n },\n },\n {\n title: '创建 hotfix 记录',\n task: async () => {\n const timestamp = DateUtils.format(new Date(), 'YYYY-MM-DD HH:mm:ss');\n const hotfixDir = 'docs/hotfixes';\n await FileUtils.ensureDir(hotfixDir);\n\n const hotfixFile = path.join(hotfixDir, `${timestamp}_${hotfixId}.md`);\n const content = formatHotfixDocument({\n id: hotfixId,\n description: answers.description,\n scope: answers.scope,\n solution: answers.solution,\n branch: branchName,\n timestamp,\n });\n\n await FileUtils.write(hotfixFile, content);\n },\n },\n {\n title: '创建初始 commit',\n task: async () => {\n const { execa } = await import('execa');\n await execa('git', ['add', 'docs/hotfixes'], { stdio: 'pipe' });\n await execa(\n 'git',\n [\n 'commit',\n '-m',\n `hotfix: ${answers.description}\\n\\nTemporary solution: ${answers.solution}`,\n ],\n { stdio: 'pipe' }\n );\n },\n },\n ]);\n\n await tasks.run();\n\n logger.newLine();\n logger.success(`Hotfix 分支已创建: ${branchName}`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step('1. 实施修复');\n logger.step(\"2. 运行 'team-cli lint' 检查代码\");\n logger.step('3. 提交并推送到远程');\n logger.step('4. 创建 PR 进行 code review');\n logger.step('5. 合并后创建规范 bugfix 记录');\n logger.newLine();\n } catch (error: any) {\n logger.error(`Hotfix 流程失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 生成 Bug ID\n */\nfunction generateBugId(): string {\n const date = new Date();\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n\n // 简单的序号生成(实际应该从已有文件中获取最大序号)\n return `BUG-${year}${month}${day}-001`;\n}\n\n/**\n * 生成 Hotfix ID\n */\nfunction generateHotfixId(): string {\n const date = new Date();\n const timestamp = date.getTime().toString().slice(-6);\n return `HF-${timestamp}`;\n}\n\n/**\n * 查找可能关联的 spec\n */\nasync function findRelatedSpec(description: string): Promise<string> {\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n\n if (!exists) {\n return '';\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n if (specs.length === 0) {\n return '';\n }\n\n // 简单的关键词匹配\n const keywords = extractKeywords(description);\n\n for (const file of specs) {\n const filePath = path.join(specDir, file);\n const content = await FileUtils.read(filePath);\n\n for (const keyword of keywords) {\n if (content.toLowerCase().includes(keyword.toLowerCase())) {\n return file.replace('.md', '');\n }\n }\n }\n\n return '';\n}\n\n/**\n * 提取关键词\n */\nfunction extractKeywords(text: string): string[] {\n // 简单的分词和过滤\n const stopWords = ['的', '是', '在', '有', '和', '或', '了', '不', '吗', '呢'];\n const words = text\n .toLowerCase()\n .replace(/[^\\w\\s\\u4e00-\\u9fa5]/g, '')\n .split(/\\s+/)\n .filter((w) => w.length > 1 && !stopWords.includes(w));\n\n return words.slice(0, 5);\n}\n\n/**\n * 格式化 bugfix 文档\n */\nfunction formatBugfixDocument(data: {\n id: string;\n severity: string;\n description: string;\n reproduction: string;\n scope: string;\n relatedSpec: string;\n timestamp: string;\n}): string {\n return `# Bugfix: ${data.description}\n\n## Bug 信息\n- **ID**: ${data.id}\n- **严重程度**: ${data.severity}\n- **状态**: 待修复\n- **创建时间**: ${data.timestamp}\n\n## 问题描述\n${data.description}\n\n## 复现步骤\n${data.reproduction}\n\n## 影响范围\n${data.scope}\n\n## 关联 Spec\n${data.relatedSpec ? `- ${data.relatedSpec}` : '- (无)'}\n\n## 修复方案\n- [ ] 分析根本原因\n- [ ] 设计修复方案\n- [ ] 实施修复\n- [ ] 编写测试\n- [ ] 验证修复\n\n## 验证清单\n- [ ] 本地测试通过\n- [ ] 单元测试覆盖\n- [ ] 回归测试通过\n- [ ] 更新相关文档\n\n---\n*创建于: ${data.timestamp} by team-cli*\n`;\n}\n\n/**\n * 格式化 hotfix 文档\n */\nfunction formatHotfixDocument(data: {\n id: string;\n description: string;\n scope: string;\n solution: string;\n branch: string;\n timestamp: string;\n}): string {\n return `# Hotfix: ${data.description}\n\n## Hotfix 信息\n- **ID**: ${data.id}\n- **创建时间**: ${data.timestamp}\n\n## 问题描述\n${data.description}\n\n## 影响范围\n${data.scope}\n\n## 临时解决方案\n${data.solution}\n\n## 修复分支\n\\`\\`\\`\ngit checkout ${data.branch}\n\\`\\`\\`\n\n## 后续步骤\n- [ ] 实施紧急修复\n- [ ] 推送到远程\n- [ ] 创建 PR 进行 code review\n- [ ] 紧急合并到主分支\n- [ ] 创建规范 bugfix 记录\n- [ ] 计划彻底修复方案\n\n---\n*创建于: ${data.timestamp} by team-cli*\n`;\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils, SpecUtils, EnhancedMilestoneInfo, TodoItem } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\n\n/**\n * 问题记录接口\n */\nexport interface IssueRecord {\n id: string;\n title: string;\n description: string;\n severity: 'high' | 'medium' | 'low';\n type: 'bug' | 'performance' | 'usability' | 'security' | 'other';\n status: 'pending' | 'in_progress' | 'resolved';\n createdAt: string;\n specFile: string;\n milestone: string;\n todo?: string;\n}\n\n/**\n * 验收检查结果\n */\nexport interface AcceptanceResult {\n specFile: string;\n milestone: string;\n checkTime: string;\n frontendTasks: { total: number; completed: number; items: CheckItem[] };\n backendTasks: { total: number; completed: number; items: CheckItem[] };\n apiVerification: { total: number; verified: number; items: CheckItem[] };\n integrationTasks: { total: number; completed: number; items: CheckItem[] };\n issues: IssueRecord[];\n}\n\n/**\n * 检查项\n */\nexport interface CheckItem {\n description: string;\n status: 'pass' | 'fail' | 'pending';\n details?: string;\n filePath?: string;\n}\n\n/**\n * Accept 命令 - 验收功能\n */\nexport const acceptCommand = new Command('accept')\n .argument('[spec-file]', 'Spec 文件路径')\n .description('验收功能 - 走查所有需求,验证联调是否完成')\n .action(async (specFile) => {\n try {\n logger.header('验收模式');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n logger.success('检测到项目上下文');\n\n // 步骤 1: 选择 spec 文件\n const selectedSpec = await selectSpec(specFile);\n\n // 步骤 2: 选择 milestone\n const selectedMilestone = await selectMilestone(selectedSpec);\n\n // 步骤 3: 执行验收检查\n const result = await runAcceptanceCheck(selectedSpec, selectedMilestone);\n\n // 步骤 4: 生成验收报告\n await generateAcceptanceReport(result);\n\n // 步骤 5: 处理发现的问题\n if (result.issues.length > 0) {\n await handleIssues(result);\n }\n\n // 步骤 6: 同步状态\n await syncSpecStatus(selectedSpec, result);\n\n logger.header('验收完成!');\n logger.newLine();\n } catch (error: any) {\n logger.error(`验收失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 步骤 1: 选择 spec 文件\n */\nasync function selectSpec(defaultSpec?: string): Promise<string> {\n logger.step('步骤 1/4: 选择 spec 文件...');\n logger.newLine();\n\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n if (!exists) {\n throw new Error('docs/specs 目录不存在');\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n const specFiles = files.filter((f) => !f.includes('template'));\n\n if (specFiles.length === 0) {\n throw new Error('未找到 spec 文件');\n }\n\n // 如果指定了文件,直接使用\n if (defaultSpec) {\n const fullPath = defaultSpec.startsWith('docs/specs/')\n ? defaultSpec\n : path.join(specDir, defaultSpec);\n\n const exists = await FileUtils.exists(fullPath);\n if (!exists) {\n throw new Error(`Spec 文件不存在: ${defaultSpec}`);\n }\n logger.success(`已选择: ${fullPath}`);\n return fullPath;\n }\n\n // 解析 spec 信息\n const specs: { file: string; name: string; status: string }[] = [];\n for (const file of specFiles) {\n const fullPath = path.join(specDir, file);\n const content = await FileUtils.read(fullPath);\n const status = SpecUtils.parseSpecStatus(content);\n specs.push({ file: fullPath, name: file, status });\n }\n\n // 只显示已拆分或进行中的 spec\n const activeSpecs = specs.filter(\n (s) => s.status === '已拆分' || s.status === '进行中' || s.status === '已完成'\n );\n\n if (activeSpecs.length === 0) {\n logger.warn('没有可验收的 spec 文件');\n const { continueAnyway } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'continueAnyway',\n message: '是否继续查看所有 spec?',\n default: true,\n },\n ]);\n\n if (!continueAnyway) {\n process.exit(0);\n }\n }\n\n const targetSpecs = activeSpecs.length > 0 ? activeSpecs : specs;\n\n const choices = targetSpecs.map((spec) => ({\n name: `[${spec.status}] ${spec.name}`,\n value: spec.file,\n short: spec.name,\n }));\n\n const { selectedFile } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedFile',\n message: '选择要验收的 spec:',\n choices,\n },\n ]);\n\n logger.success(`已选择: ${selectedFile}`);\n return selectedFile;\n}\n\n/**\n * 步骤 2: 选择 milestone\n */\nasync function selectMilestone(specFile: string): Promise<string> {\n logger.newLine();\n logger.step('步骤 2/4: 解析 milestones...');\n logger.newLine();\n\n const specContent = await FileUtils.read(specFile);\n const { enhanced } = SpecUtils.parseMilestonesEnhancedWithFallback(specContent);\n\n if (enhanced.length === 0) {\n throw new Error('该 spec 尚未拆分 milestones,无法进行验收');\n }\n\n // 显示未完成的 milestones\n const choices = enhanced.map((m, idx) => {\n const isDone = m.completedCount === m.totalCount;\n const statusIcon = isDone ? '✓' : m.completedCount > 0 ? '⟳' : '○';\n const progress = `[${m.completedCount}/${m.totalCount}]`;\n\n return {\n name: `${idx + 1}. ${statusIcon} ${progress} ${m.title}`,\n value: m.title,\n short: m.title,\n };\n });\n\n const { milestone } = await inquirer.prompt([\n {\n type: 'list',\n name: 'milestone',\n message: '选择要验收的 milestone:',\n choices,\n },\n ]);\n\n return milestone;\n}\n\n/**\n * 步骤 3: 执行验收检查\n */\nasync function runAcceptanceCheck(\n specFile: string,\n milestone: string\n): Promise<AcceptanceResult> {\n logger.newLine();\n logger.step('步骤 3/4: 执行验收检查...');\n logger.newLine();\n\n const specContent = await FileUtils.read(specFile);\n const { enhanced } = SpecUtils.parseMilestonesEnhancedWithFallback(specFile);\n const targetMilestone = enhanced.find((m) => m.title === milestone);\n\n if (!targetMilestone) {\n throw new Error(`未找到 milestone: ${milestone}`);\n }\n\n const result: AcceptanceResult = {\n specFile,\n milestone,\n checkTime: new Date().toLocaleString('zh-CN'),\n frontendTasks: { total: 0, completed: 0, items: [] },\n backendTasks: { total: 0, completed: 0, items: [] },\n apiVerification: { total: 0, verified: 0, items: [] },\n integrationTasks: { total: 0, completed: 0, items: [] },\n issues: [],\n };\n\n // 检查前端任务\n logger.info('检查前端任务...');\n for (const todo of targetMilestone.frontendTodos) {\n const checkResult = await checkFrontendTask(todo);\n result.frontendTasks.items.push(checkResult);\n if (checkResult.status === 'pass') {\n result.frontendTasks.completed++;\n }\n result.frontendTasks.total++;\n\n const icon = checkResult.status === 'pass' ? '✓' : checkResult.status === 'fail' ? '✗' : '○';\n logger.info(` ${icon} [F] ${todo.content}${checkResult.filePath ? ` - ${checkResult.filePath}` : ''}`);\n }\n\n // 检查后端任务\n logger.info('检查后端任务...');\n for (const todo of targetMilestone.backendTodos) {\n const checkResult = await checkBackendTask(todo);\n result.backendTasks.items.push(checkResult);\n if (checkResult.status === 'pass') {\n result.backendTasks.completed++;\n }\n result.backendTasks.total++;\n\n const icon = checkResult.status === 'pass' ? '✓' : checkResult.status === 'fail' ? '✗' : '○';\n logger.info(` ${icon} [B] ${todo.content}${checkResult.filePath ? ` - ${checkResult.filePath}` : ''}`);\n }\n\n // 验证 API 实现\n logger.info('验证 API 实现...');\n for (const todo of targetMilestone.backendTodos) {\n if (todo.apiAssociation) {\n const checkResult = await verifyApiImplementation(todo);\n result.apiVerification.items.push(checkResult);\n if (checkResult.status === 'pass') {\n result.apiVerification.verified++;\n }\n result.apiVerification.total++;\n\n const icon = checkResult.status === 'pass' ? '✓' : checkResult.status === 'fail' ? '✗' : '○';\n logger.info(` ${icon} ${todo.apiAssociation}${checkResult.filePath ? ` - ${checkResult.filePath}` : ''}`);\n }\n }\n\n // 检查联调任务\n logger.info('检查联调任务...');\n for (const todo of targetMilestone.integrationTodos) {\n const checkResult = await checkIntegrationTask(todo);\n result.integrationTasks.items.push(checkResult);\n if (checkResult.status === 'pass') {\n result.integrationTasks.completed++;\n }\n result.integrationTasks.total++;\n\n const icon = checkResult.status === 'pass' ? '✓' : checkResult.status === 'fail' ? '✗' : '○';\n logger.info(` ${icon} [I] ${todo.content}`);\n }\n\n return result;\n}\n\n/**\n * 检查前端任务\n */\nasync function checkFrontendTask(todo: TodoItem): Promise<CheckItem> {\n // 前端代码检查 - 检查常见前端文件路径\n const frontendPaths = [\n `frontend/src/pages/${todo.content}.tsx`,\n `frontend/src/components/${todo.content}.tsx`,\n `frontend/src/components/${todo.content.replace(/\\s+/g, '')}.tsx`,\n `frontend/src/views/${todo.content}.vue`,\n `frontend/src/components/${todo.content}.vue`,\n ];\n\n for (const fp of frontendPaths) {\n if (await FileUtils.exists(fp)) {\n return {\n description: `[F] ${todo.content}`,\n status: 'pass',\n details: '前端代码存在',\n filePath: fp,\n };\n }\n }\n\n // 检查增强格式中的路径信息\n const pathMatch = todo.content.match(/\\s*-\\s*(.+?\\.(tsx|vue|js|jsx))\\s*/);\n if (pathMatch) {\n const filePath = pathMatch[1];\n if (await FileUtils.exists(filePath)) {\n return {\n description: `[F] ${todo.content}`,\n status: 'pass',\n details: '前端代码存在',\n filePath,\n };\n }\n }\n\n return {\n description: `[F] ${todo.content}`,\n status: 'fail',\n details: '前端代码不存在或路径无法验证',\n };\n}\n\n/**\n * 检查后端任务\n */\nasync function checkBackendTask(todo: TodoItem): Promise<CheckItem> {\n // 后端代码检查 - 检查常见后端文件路径\n const backendPaths = [\n `backend/src/main/java/${todo.content.replace(/\\s+/g, '/')}.java`,\n `backend/src/${todo.content.toLowerCase().replace(/\\s+/g, '/')}.java`,\n ];\n\n for (const fp of backendPaths) {\n if (await FileUtils.exists(fp)) {\n return {\n description: `[B] ${todo.content}`,\n status: 'pass',\n details: '后端代码存在',\n filePath: fp,\n };\n }\n }\n\n // 检查增强格式中的路径信息\n const pathMatch = todo.content.match(/\\s*-\\s*(.+?\\.(java|kt|py|go))\\s*/);\n if (pathMatch) {\n const filePath = pathMatch[1];\n if (await FileUtils.exists(filePath)) {\n return {\n description: `[B] ${todo.content}`,\n status: 'pass',\n details: '后端代码存在',\n filePath,\n };\n }\n }\n\n return {\n description: `[B] ${todo.content}`,\n status: 'fail',\n details: '后端代码不存在或路径无法验证',\n };\n}\n\n/**\n * 验证 API 实现\n */\nasync function verifyApiImplementation(todo: TodoItem): Promise<CheckItem> {\n if (!todo.apiAssociation) {\n return {\n description: todo.apiAssociation || 'API 验证',\n status: 'pending',\n details: '无 API 关联信息',\n };\n }\n\n // 解析 API 路径和方法\n const apiMatch = todo.apiAssociation.match(/^(GET|POST|PUT|DELETE|PATCH)\\s+\\/(.+)$/);\n if (!apiMatch) {\n return {\n description: todo.apiAssociation,\n status: 'pending',\n details: '无法解析 API 格式',\n };\n }\n\n const method = apiMatch[1];\n const apiPath = apiMatch[2];\n\n // 检查 Controller 层实现\n const controllerPaths = [\n `backend/src/main/java/**/*Controller.java`,\n `backend/src/**/*Controller.java`,\n ];\n\n const controllerFiles = await FileUtils.findFiles('**/*Controller.java', 'backend/src');\n\n for (const cf of controllerFiles) {\n const content = await FileUtils.read(cf);\n // 检查是否包含 API 路径和方法\n if (content.includes(apiPath) || content.includes(`\"${apiPath}\"`)) {\n // 检查方法注解\n const methodAnnotations: Record<string, string[]> = {\n GET: ['@GetMapping', '@RequestMapping(method = RequestMethod.GET)'],\n POST: ['@PostMapping', '@RequestMapping(method = RequestMethod.POST)'],\n PUT: ['@PutMapping', '@RequestMapping(method = RequestMethod.PUT)'],\n DELETE: ['@DeleteMapping', '@RequestMapping(method = RequestMethod.DELETE)'],\n PATCH: ['@PatchMapping', '@RequestMapping(method = RequestMethod.PATCH)'],\n };\n\n for (const annotation of methodAnnotations[method] || []) {\n if (content.includes(annotation)) {\n return {\n description: todo.apiAssociation,\n status: 'pass',\n details: 'API Controller 实现存在',\n filePath: cf,\n };\n }\n }\n }\n }\n\n return {\n description: todo.apiAssociation,\n status: 'fail',\n details: 'API Controller 未实现',\n };\n}\n\n/**\n * 检查联调任务\n */\nasync function checkIntegrationTask(todo: TodoItem): Promise<CheckItem> {\n // 联调任务通常需要前后端联动验证\n // 这里我们检查是否有相关的测试文件或集成测试证据\n const integrationEvidence = [\n '**/*integration*.test.*',\n '**/*e2e*.test.*',\n '**/*IT.java',\n 'docs/integration-test-results.md',\n 'docs/session-logs/**',\n ];\n\n // 检查是否有相关的 session 日志或测试报告\n const sessionDir = 'docs/sessions';\n if (await FileUtils.exists(sessionDir)) {\n const sessionFiles = await FileUtils.findFiles('*.md', sessionDir);\n const hasRecentSession = sessionFiles.some((sf) =>\n sf.includes('integration') || sf.includes('联调')\n );\n if (hasRecentSession) {\n return {\n description: `[I] ${todo.content}`,\n status: 'pass',\n details: '联调证据存在(session 日志)',\n };\n }\n }\n\n // 默认为 pending,因为联调通常需要人工验证\n return {\n description: `[I] ${todo.content}`,\n status: 'pending',\n details: '建议人工验证联调结果',\n };\n}\n\n/**\n * 步骤 4: 生成验收报告\n */\nasync function generateAcceptanceReport(result: AcceptanceResult): Promise<void> {\n logger.newLine();\n logger.step('步骤 4/4: 生成验收报告...');\n logger.newLine();\n\n const reportDir = 'docs/acceptance-reports';\n await FileUtils.ensureDir(reportDir);\n\n const timestamp = new Date().toISOString().slice(0, 10);\n const specName = path.basename(result.specFile, '.md');\n const milestoneSafe = result.milestone.replace(/[^a-zA-Z0-9]/g, '-');\n const reportFile = path.join(reportDir, `${timestamp}_${specName}_${milestoneSafe}.md`);\n\n const report = generateMarkdownReport(result);\n\n await FileUtils.write(reportFile, report);\n\n logger.success(`验收报告已生成: ${reportFile}`);\n logger.newLine();\n\n // 控制台输出报告摘要\n console.log(generateConsoleReport(result));\n}\n\n/**\n * 生成 Markdown 格式的验收报告\n */\nfunction generateMarkdownReport(result: AcceptanceResult): string {\n const lines: string[] = [];\n\n lines.push('# 验收报告');\n lines.push('');\n lines.push(`**Spec 文件**: ${result.specFile}`);\n lines.push(`**Milestone**: ${result.milestone}`);\n lines.push(`**验收时间**: ${result.checkTime}`);\n lines.push('');\n\n // 检查结果汇总\n lines.push('## 检查结果汇总');\n lines.push('');\n lines.push('| 检查项 | 状态 |');\n lines.push('|--------|------|');\n lines.push(\n `| 前端任务 | ${result.frontendTasks.completed}/${result.frontendTasks.total} 完成 |`\n );\n lines.push(\n `| 后端任务 | ${result.backendTasks.completed}/${result.backendTasks.total} 完成 |`\n );\n lines.push(`| API 验证 | ${result.apiVerification.verified}/${result.apiVerification.total} 实现 |`);\n lines.push(\n `| 联调任务 | ${result.integrationTasks.completed}/${result.integrationTasks.total} 完成 |`\n );\n lines.push('');\n\n // 详细记录\n lines.push('## 详细记录');\n lines.push('');\n\n // 前端任务\n lines.push('### 前端任务');\n lines.push('');\n for (const item of result.frontendTasks.items) {\n const icon = item.status === 'pass' ? '✓' : item.status === 'fail' ? '✗' : '○';\n lines.push(`- ${icon} ${item.description} - ${item.details || ''} ${item.filePath ? `(\\`${item.filePath}\\`)` : ''}`);\n }\n lines.push('');\n\n // 后端任务\n lines.push('### 后端任务');\n lines.push('');\n for (const item of result.backendTasks.items) {\n const icon = item.status === 'pass' ? '✓' : item.status === 'fail' ? '✗' : '○';\n lines.push(`- ${icon} ${item.description} - ${item.details || ''} ${item.filePath ? `(\\`${item.filePath}\\`)` : ''}`);\n }\n lines.push('');\n\n // API 验证\n lines.push('### API 验证');\n lines.push('');\n for (const item of result.apiVerification.items) {\n const icon = item.status === 'pass' ? '✓' : item.status === 'fail' ? '✗' : '○';\n lines.push(`- ${icon} ${item.description} - ${item.details || ''} ${item.filePath ? `(\\`${item.filePath}\\`)` : ''}`);\n }\n lines.push('');\n\n // 联调任务\n lines.push('### 联调任务');\n lines.push('');\n for (const item of result.integrationTasks.items) {\n const icon = item.status === 'pass' ? '✓' : item.status === 'fail' ? '✗' : '⚠';\n lines.push(`- ${icon} ${item.description} - ${item.details || ''}`);\n }\n lines.push('');\n\n // 发现的问题\n if (result.issues.length > 0) {\n lines.push('## 发现的问题');\n lines.push('');\n lines.push('| 问题 | 类型 | 严重程度 | 状态 |');\n lines.push('|------|------|---------|------|');\n for (const issue of result.issues) {\n lines.push(`| ${issue.title} | ${issue.type} | ${issue.severity} | ${issue.status} |`);\n }\n lines.push('');\n lines.push('**操作**:');\n lines.push(`- 运行 \\`team-cli bugfix ${result.specFile}\\` 查看详情`);\n lines.push('- 或运行 `team-cli hotfix` 立即修复');\n lines.push('');\n }\n\n // 下一步建议\n lines.push('## 下一步建议');\n lines.push('');\n if (result.issues.length > 0) {\n lines.push('- [ ] 修复发现的问题');\n }\n lines.push('- [ ] 运行 `team-cli dev` 继续开发');\n lines.push(\"- [ ] 运行 `team-cli accept` 重新验收\");\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * 生成控制台报告摘要\n */\nfunction generateConsoleReport(result: AcceptanceResult): string {\n const lines: string[] = [];\n\n lines.push('┌──────────────────────────────────────────────┐');\n lines.push('│ 验 收 结 果 摘 要 │');\n lines.push('├──────────────────────────────────────────────┤');\n lines.push(`│ Spec: ${result.specFile.padEnd(40)}│`);\n lines.push(`│ Milestone: ${result.milestone.padEnd(37)}│`);\n lines.push('├──────────────────────────────────────────────┤');\n lines.push(\n `│ 前端任务: ${result.frontendTasks.completed}/${result.frontendTasks.total} 完成`.padEnd(47) + '│'\n );\n lines.push(\n `│ 后端任务: ${result.backendTasks.completed}/${result.backendTasks.total} 完成`.padEnd(47) + '│'\n );\n lines.push(\n `│ API 验证: ${result.apiVerification.verified}/${result.apiVerification.total} 实现`.padEnd(47) + '│'\n );\n lines.push(\n `│ 联调任务: ${result.integrationTasks.completed}/${result.integrationTasks.total} 完成`.padEnd(47) + '│'\n );\n lines.push('├──────────────────────────────────────────────┤');\n\n const totalIssues = result.issues.length;\n if (totalIssues > 0) {\n lines.push(`│ ⚠ 发现问题: ${totalIssues} 个`.padEnd(47) + '│');\n } else {\n lines.push(`│ ✓ 验收通过`.padEnd(47) + '│');\n }\n lines.push('└──────────────────────────────────────────────┘');\n\n return lines.join('\\n');\n}\n\n/**\n * 处理发现的问题\n */\nasync function handleIssues(result: AcceptanceResult): Promise<void> {\n logger.newLine();\n logger.warn(`发现 ${result.issues.length} 个问题需要处理`);\n\n // 自动创建 bugfix 记录\n const bugfixDir = 'docs/bugfixes';\n await FileUtils.ensureDir(bugfixDir);\n\n for (const issue of result.issues) {\n const bugfixFile = path.join(\n bugfixDir,\n `${new Date().toISOString().slice(0, 10)}_${issue.id}.md`\n );\n\n const bugfixContent = generateBugfixContent(result, issue);\n await FileUtils.write(bugfixFile, bugfixContent);\n\n logger.info(` 已创建 Bugfix 记录: ${bugfixFile}`);\n }\n\n logger.newLine();\n\n const { fixNow } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'fixNow',\n message: '是否立即修复发现的问题?',\n default: false,\n },\n ]);\n\n if (fixNow) {\n logger.info('请运行 `team-cli hotfix` 立即修复问题');\n } else {\n logger.info(`问题记录已保存到 ${bugfixDir} 目录`);\n logger.info(\"运行 `team-cli bugfix` 查看所有问题记录\");\n }\n}\n\n/**\n * 生成 Bugfix 内容\n */\nfunction generateBugfixContent(result: AcceptanceResult, issue: IssueRecord): string {\n const lines: string[] = [];\n\n lines.push('# Bugfix 记录');\n lines.push('');\n lines.push(`**ID**: ${issue.id}`);\n lines.push(`**创建时间**: ${issue.createdAt}`);\n lines.push(`**状态**: ${issue.status}`);\n lines.push('');\n lines.push('## 问题描述');\n lines.push('');\n lines.push(issue.description);\n lines.push('');\n lines.push('## 所属范围');\n lines.push('');\n lines.push(`- Spec: ${result.specFile}`);\n lines.push(`- Milestone: ${result.milestone}`);\n if (issue.todo) {\n lines.push(`- Todo: ${issue.todo}`);\n }\n lines.push('');\n lines.push('## 严重程度');\n lines.push('');\n lines.push(`- ${issue.severity.toUpperCase()}`);\n lines.push('');\n lines.push('## 问题类型');\n lines.push('');\n lines.push(`- ${issue.type}`);\n lines.push('');\n lines.push('## 解决方案');\n lines.push('');\n lines.push('<!-- TODO: 填写解决方案 -->');\n lines.push('');\n lines.push('## 验证步骤');\n lines.push('');\n lines.push('1. ');\n lines.push('2. ');\n lines.push('3. ');\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * 同步 Spec 状态\n */\nasync function syncSpecStatus(specFile: string, result: AcceptanceResult): Promise<void> {\n const content = await FileUtils.read(specFile);\n const lines = content.split('\\n');\n\n // 查找并更新里程碑状态\n let inTargetMilestone = false;\n let milestoneIndex = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (line.includes(result.milestone)) {\n inTargetMilestone = true;\n milestoneIndex = i;\n continue;\n }\n\n if (inTargetMilestone && line.match(/^###\\s+Milestone/)) {\n break;\n }\n }\n\n if (milestoneIndex !== -1) {\n // 统计已完成的 tasks\n let completedTasks = 0;\n let totalTasks = 0;\n\n for (let i = milestoneIndex + 1; i < lines.length; i++) {\n const line = lines[i];\n if (line.match(/^###\\s+Milestone/)) {\n break;\n }\n if (line.match(/^-\\s+\\[/)) {\n totalTasks++;\n if (line.match(/^-\\s+\\[x\\]/)) {\n completedTasks++;\n }\n }\n }\n\n // 更新进度标注\n const progressLine = `${result.milestone} [${completedTasks}/${totalTasks}]`;\n const linesBefore = lines.slice(0, milestoneIndex);\n const linesAfter = lines.slice(milestoneIndex + 1);\n\n // 检查是否已有进度标注\n if (!lines[milestoneIndex].includes(`[${completedTasks}/${totalTasks}]`)) {\n // 替换里程碑标题行\n const updatedMilestoneLine = lines[milestoneIndex].replace(\n /(\\s*\\[\\d+\\/\\d+\\])?$/,\n ` [${completedTasks}/${totalTasks}]`\n );\n lines[milestoneIndex] = updatedMilestoneLine;\n\n await FileUtils.write(specFile, lines.join('\\n'));\n logger.info(`已同步里程碑进度: [${completedTasks}/${totalTasks}]`);\n }\n }\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\n\n/**\n * 模块配置接口\n */\ninterface ModuleConfig {\n name: string; // 模块名 (目录名)\n type: 'service' | 'api' | 'common'; // 模块类型\n packagePath: string; // 包路径 (groupId + name)\n applicationClass: string; // 启动类名\n}\n\n/**\n * Add-Module 命令 - 为已有项目新增模块\n */\nexport const addModuleCommand = new Command('add-module')\n .description('为已有项目新增模块 (多模块 Gradle 项目)')\n .action(async () => {\n try {\n logger.header('新增模块');\n logger.newLine();\n\n // 1. 检查是否在项目根目录\n const projectPath = process.cwd();\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info('请切换到项目根目录后再执行此命令');\n process.exit(1);\n }\n\n // 2. 扫描现有模块\n const existingModules = await scanExistingModules(projectPath);\n\n if (existingModules.length > 0) {\n logger.success(`检测到现有模块: [${existingModules.join(', ')}]`);\n } else {\n logger.info('未检测到现有模块');\n }\n logger.newLine();\n\n // 3. 获取 Group ID (从 build.gradle 或 settings.gradle)\n const groupId = await detectGroupId(projectPath);\n logger.info(`检测到 Group ID: ${groupId}`);\n logger.newLine();\n\n // 4. 获取 rootProjectName\n const rootProjectName = await detectRootProjectName(projectPath);\n logger.info(`检测到根项目名: ${rootProjectName}`);\n logger.newLine();\n\n // 5. 收集新模块配置\n const newModules: ModuleConfig[] = [];\n let addMore = true;\n let moduleIndex = 1;\n\n while (addMore) {\n const moduleNameAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'moduleName',\n message: `请输入第 ${moduleIndex} 个新模块名称 (目录名):`,\n validate: (input: string) => {\n if (!/^[a-z][a-z0-9-]*$/.test(input)) {\n return '模块名只能以小写字母开头,包含小写字母、数字和连字符';\n }\n if (existingModules.includes(input)) {\n return '该模块已存在';\n }\n return true;\n },\n },\n ]);\n\n const moduleName = moduleNameAnswer.moduleName;\n\n // 模块类型\n const typeAnswer = await inquirer.prompt([\n {\n type: 'list',\n name: 'moduleType',\n message: `模块 \"${moduleName}\" 类型:`,\n choices: [\n { name: 'API 服务模块 (独立部署)', value: 'service' },\n { name: '公共模块 (被其他模块依赖)', value: 'common' },\n { name: 'API 接口模块 (仅接口定义)', value: 'api' },\n ],\n default: 'service',\n },\n ]);\n\n // 确认包路径\n const defaultPackage = `${groupId}.${moduleName}`;\n const packageAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'packagePath',\n message: '模块包路径:',\n default: defaultPackage,\n validate: (input: string) => {\n if (!/^[a-z][a-z0-9]*(\\.[a-z][a-z0-9]*)*$/.test(input)) {\n return '包路径格式不正确';\n }\n return true;\n },\n },\n ]);\n\n // 启动类名\n const pascalName = toPascalCase(moduleName);\n const classAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'applicationClass',\n message: '启动类名:',\n default: `${pascalName}Application`,\n },\n ]);\n\n newModules.push({\n name: moduleName,\n type: typeAnswer.moduleType,\n packagePath: packageAnswer.packagePath,\n applicationClass: classAnswer.applicationClass,\n });\n\n // 是否继续添加\n const moreAnswer = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'addMore',\n message: '是否还需要添加更多模块?',\n default: false,\n },\n ]);\n addMore = moreAnswer.addMore;\n moduleIndex++;\n }\n\n logger.newLine();\n logger.info(`将新增模块: ${newModules.map(m => m.name).join(', ')}`);\n logger.newLine();\n\n // 6. 创建模块结构\n for (const module of newModules) {\n await createModuleStructure(projectPath, module, groupId);\n }\n\n // 7. 更新 settings.gradle\n await updateSettingsGradle(projectPath, rootProjectName, newModules);\n\n logger.newLine();\n logger.success('模块创建完成!');\n logger.newLine();\n\n // 8. 显示下一步\n logger.info('下一步:');\n logger.step('1. 运行 `team-cli breakdown docs/specs/xxx.md` 拆分需求');\n logger.step('2. 运行 `team-cli dev` 开始开发');\n logger.newLine();\n\n } catch (error: any) {\n logger.error(`新增模块失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 扫描现有模块\n */\nasync function scanExistingModules(projectPath: string): Promise<string[]> {\n const modules: string[] = [];\n\n // 检查 settings.gradle\n const settingsGradle = path.join(projectPath, 'settings.gradle');\n if (await FileUtils.exists(settingsGradle)) {\n const content = await FileUtils.read(settingsGradle);\n const includeMatches = content.match(/include\\s+'([^']+)'/g);\n if (includeMatches) {\n for (const match of includeMatches) {\n const moduleName = match.replace(/include\\s+'/, '').replace(/'/, '');\n modules.push(moduleName);\n }\n }\n }\n\n // 检查 backend 目录下的子目录\n const backendPath = path.join(projectPath, 'backend');\n if (await FileUtils.exists(backendPath)) {\n const entries = await fs.readdir(backendPath, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'src') {\n if (!modules.includes(entry.name)) {\n modules.push(entry.name);\n }\n }\n }\n }\n\n return modules;\n}\n\n/**\n * 检测 Group ID\n */\nasync function detectGroupId(projectPath: string): Promise<string> {\n // 1. 尝试从 build.gradle 读取\n const buildGradle = path.join(projectPath, 'backend', 'build.gradle');\n if (await FileUtils.exists(buildGradle)) {\n const content = await FileUtils.read(buildGradle);\n const groupMatch = content.match(/group\\s*=\\s*['\"]([^'\"]+)['\"]/);\n if (groupMatch) {\n return groupMatch[1];\n }\n }\n\n // 2. 尝试从根 build.gradle 读取\n const rootBuildGradle = path.join(projectPath, 'build.gradle');\n if (await FileUtils.exists(rootBuildGradle)) {\n const content = await FileUtils.read(rootBuildGradle);\n const groupMatch = content.match(/group\\s*=\\s*['\"]([^'\"]+)['\"]/);\n if (groupMatch) {\n return groupMatch[1];\n }\n }\n\n // 3. 尝试从现有模块的 Java 文件读取\n const backendPath = path.join(projectPath, 'backend');\n if (await FileUtils.exists(backendPath)) {\n const entries = await fs.readdir(backendPath, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory() && !entry.name.startsWith('.')) {\n const srcPath = path.join(backendPath, entry.name, 'src', 'main', 'java');\n if (await FileUtils.exists(srcPath)) {\n const javaDirs = await fs.readdir(srcPath);\n if (javaDirs.length > 0) {\n return javaDirs[0];\n }\n }\n }\n }\n }\n\n // 默认值\n return 'org.yungu';\n}\n\n/**\n * 检测根项目名\n */\nasync function detectRootProjectName(projectPath: string): Promise<string> {\n const settingsGradle = path.join(projectPath, 'settings.gradle');\n if (await FileUtils.exists(settingsGradle)) {\n const content = await FileUtils.read(settingsGradle);\n const rootMatch = content.match(/rootProject\\.name\\s*=\\s*['\"]([^'\"]+)['\"]/);\n if (rootMatch) {\n return rootMatch[1];\n }\n }\n\n // 默认使用目录名\n return path.basename(projectPath);\n}\n\n/**\n * 创建模块目录结构\n */\nasync function createModuleStructure(\n projectPath: string,\n module: ModuleConfig,\n groupId: string\n): Promise<void> {\n const modulePath = path.join(projectPath, 'backend', module.name);\n\n logger.info(`正在创建模块: ${module.name}...`);\n\n // 根据模块类型创建不同结构\n const baseDirs = [\n 'src/main/java',\n 'src/main/resources',\n 'src/test/java',\n ];\n\n for (const dir of baseDirs) {\n await FileUtils.ensureDir(path.join(modulePath, dir));\n }\n\n // 创建 Java 包路径\n const packageDirs = module.packagePath.split('.');\n let javaPath = path.join(modulePath, 'src', 'main', 'java');\n\n // 根据模块类型创建不同的子目录\n if (module.type === 'service') {\n // 服务模块:controller, service, mapper, entity, dto, config\n for (const subDir of ['controller', 'service', 'mapper', 'entity', 'dto', 'config']) {\n await FileUtils.ensureDir(path.join(javaPath, ...packageDirs, subDir));\n }\n\n // 创建 Application 启动类\n await createApplicationClass(\n path.join(javaPath, ...packageDirs, 'config', `${module.applicationClass}.java`),\n module.packagePath,\n module.applicationClass\n );\n\n } else if (module.type === 'api') {\n // API 模块:model, constant, enums\n for (const subDir of ['model', 'constant', 'enums', 'exception']) {\n await FileUtils.ensureDir(path.join(javaPath, ...packageDirs, subDir));\n }\n\n } else {\n // 公共模块:util, common, config, manager\n for (const subDir of ['util', 'common', 'config', 'manager']) {\n await FileUtils.ensureDir(path.join(javaPath, ...packageDirs, subDir));\n }\n }\n\n // 创建 build.gradle\n await createModuleBuildGradle(\n path.join(modulePath, 'build.gradle'),\n module,\n groupId\n );\n\n // 创建 .gitignore\n const gitignore = `# Gradle\n.gradle/\nbuild/\n\n# IDE\n.idea/\n*.iml\n*.ipr\n*.iws\n.vscode/\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\nlogs/\n*.log\n\n# Application\napplication-local.yml\napplication-dev.yml\n`;\n await FileUtils.write(path.join(modulePath, '.gitignore'), gitignore);\n\n logger.success(`模块 ${module.name} 创建完成`);\n}\n\n/**\n * 创建 Application 启动类\n */\nasync function createApplicationClass(\n filePath: string,\n packagePath: string,\n className: string\n): Promise<void> {\n const content = `package ${packagePath}.config;\n\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.annotation.ComponentScan;\n\n@SpringBootApplication\n@ComponentScan(\"${packagePath}\")\n@Slf4j\npublic class ${className} {\n\n public static void main(String[] args) {\n ApplicationContext context = SpringApplication.run(${className}.class, args);\n log.info(\"${className} 启动成功!\");\n }\n}\n`;\n await FileUtils.write(filePath, content);\n}\n\n/**\n * 创建模块的 build.gradle\n */\nasync function createModuleBuildGradle(\n filePath: string,\n module: ModuleConfig,\n groupId: string\n): Promise<void> {\n let dependencies = '';\n\n if (module.type === 'service') {\n dependencies = `\ndependencies {\n implementation project(\":common\")\n implementation 'org.springframework.boot:spring-boot-starter-web'\n implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter'\n implementation 'com.alibaba:druid-spring-boot-starter'\n compileOnly \"org.projectlombok:lombok\"\n annotationProcessor \"org.projectlombok:lombok\"\n}\n`;\n } else if (module.type === 'api') {\n dependencies = `\ndependencies {\n compileOnly 'org.springframework.boot:spring-boot-starter'\n compileOnly \"org.projectlombok:lombok\"\n annotationProcessor \"org.projectlombok:lombok\"\n}\n`;\n } else {\n dependencies = `\ndependencies {\n implementation 'org.springframework.boot:spring-boot-starter'\n implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter'\n compileOnly \"org.projectlombok:lombok\"\n annotationProcessor \"org.projectlombok:lombok\"\n}\n`;\n }\n\n const content = `plugins {\n id 'java-library'\n id 'org.springframework.boot' version '3.2.0'\n id 'io.spring.dependency-management' version '1.1.4'\n}\n\ngroup = '${groupId}'\nversion = '0.0.1-SNAPSHOT'\n\njava {\n sourceCompatibility = '17'\n}\n\nrepositories {\n maven { url 'https://maven.aliyun.com/repository/public/' }\n}\n\n${dependencies}\n`;\n await FileUtils.write(filePath, content);\n}\n\n/**\n * 更新 settings.gradle\n */\nasync function updateSettingsGradle(\n projectPath: string,\n rootProjectName: string,\n newModules: ModuleConfig[]\n): Promise<void> {\n const settingsPath = path.join(projectPath, 'backend', 'settings.gradle');\n\n let content = '';\n if (await FileUtils.exists(settingsPath)) {\n content = await FileUtils.read(settingsPath);\n } else {\n content = `rootProject.name = '${rootProjectName}'\n`;\n }\n\n // 解析现有的 include 语句\n const existingModules = new Set<string>();\n const moduleMatches = content.matchAll(/include\\s+'([^']+)'/g);\n for (const match of moduleMatches) {\n existingModules.add(match[1]);\n }\n\n // 添加新模块\n for (const module of newModules) {\n if (!existingModules.has(module.name)) {\n existingModules.add(module.name);\n }\n }\n\n // 重新生成文件内容\n const lines: string[] = [];\n lines.push(`rootProject.name = '${rootProjectName}'`);\n lines.push('');\n\n // 添加所有模块\n const allModules = Array.from(existingModules).sort();\n for (const module of allModules) {\n lines.push(`include '${module}'`);\n }\n\n await FileUtils.write(settingsPath, lines.join('\\n'));\n logger.success('settings.gradle 已更新');\n}\n\n/**\n * 字符串转 PascalCase\n */\nfunction toPascalCase(str: string): string {\n return str\n .split(/[-_]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n","import { Command } from 'commander';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { execa } from 'execa';\n\n/**\n * Lint 命令 - 代码质量检查\n */\nexport const lintCommand = new Command('lint')\n .option('--fix', '自动修复问题')\n .option('--no-type-check', '跳过 TypeScript 类型检查')\n .description('代码质量检查 (前端 + 后端)')\n .action(async (options) => {\n try {\n logger.header('代码质量检查');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n interface LintResult {\n exists: boolean;\n passed: boolean;\n errors: string[];\n }\n\n const results: { frontend: LintResult; backend: LintResult } = {\n frontend: { exists: false, passed: false, errors: [] },\n backend: { exists: false, passed: false, errors: [] },\n };\n\n // 检查前端\n const frontendExists = await FileUtils.exists('frontend/package.json');\n if (frontendExists) {\n results.frontend.exists = true;\n try {\n logger.step('检查前端代码...');\n\n // ESLint 检查\n if (options.fix) {\n await execa('npm', ['run', 'lint', '--', '--fix'], {\n cwd: 'frontend',\n stdio: 'inherit',\n });\n } else {\n await execa('npm', ['run', 'lint'], {\n cwd: 'frontend',\n stdio: 'inherit',\n });\n }\n\n // TypeScript 类型检查\n if (options.typeCheck !== false) {\n try {\n logger.step('正在进行 TypeScript 类型检查...');\n await execa('npx', ['tsc', '--noEmit'], {\n cwd: 'frontend',\n stdio: 'pipe',\n });\n } catch (tscError: any) {\n logger.warn('TypeScript 类型检查发现问题,请检查代码类型安全。');\n if (process.env.DEBUG) {\n console.log(tscError.stdout);\n }\n // 仅作为警告,不阻塞整体通过逻辑(如果 eslint 已通过)\n results.frontend.errors.push('TypeScript 类型检查失败 (已跳过阻塞)');\n }\n }\n\n results.frontend.passed = true;\n logger.success('前端代码检查通过');\n } catch (error: any) {\n results.frontend.errors.push(error.message);\n logger.error(`前端代码检查失败: ${error.message}`);\n }\n } else {\n logger.info('未找到前端项目 (frontend/package.json)');\n }\n\n logger.newLine();\n\n // 检查后端\n const backendExists = await FileUtils.exists('backend/build.gradle') ||\n await FileUtils.exists('backend/pom.xml');\n if (backendExists) {\n results.backend.exists = true;\n\n // 检查构建工具\n const hasGradle = await FileUtils.exists('backend/build.gradle') ||\n await FileUtils.exists('backend/build.gradle.kts');\n const hasMaven = await FileUtils.exists('backend/pom.xml');\n\n try {\n logger.step('检查后端代码...');\n\n if (hasGradle) {\n // Gradle 构建\n if (options.fix) {\n await execa('./gradlew', ['spotlessApply'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n }\n await execa('./gradlew', ['checkstyleMain', 'compileJava'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n } else if (hasMaven) {\n // Maven 构建\n if (options.fix) {\n await execa('./mvnw', ['spotless:apply'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n }\n await execa('./mvnw', ['checkstyle:check', 'compile'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n }\n\n results.backend.passed = true;\n logger.success('后端代码检查通过');\n } catch (error: any) {\n results.backend.errors.push(error.message);\n logger.error('后端代码检查失败');\n }\n } else {\n logger.info('未找到后端项目 (build.gradle 或 pom.xml)');\n }\n\n logger.newLine();\n logger.separator('=', 50);\n logger.newLine();\n\n // 汇总结果\n let hasErrors = false;\n\n if (results.frontend.exists) {\n if (results.frontend.passed) {\n logger.success('前端: ✓ 通过');\n } else {\n logger.error('前端: ✗ 失败');\n hasErrors = true;\n }\n }\n\n if (results.backend.exists) {\n if (results.backend.passed) {\n logger.success('后端: ✓ 通过');\n } else {\n logger.error('后端: ✗ 失败');\n hasErrors = true;\n }\n }\n\n logger.newLine();\n\n if (hasErrors) {\n logger.error('代码检查失败');\n logger.info(\"运行 'team-cli lint --fix' 尝试自动修复\");\n process.exit(1);\n } else {\n logger.success('代码检查全部通过');\n }\n } catch (error: any) {\n logger.error(`代码检查失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils, GitUtils, SpecUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\n\n/**\n * Status 命令 - 查看项目状态\n */\nexport const statusCommand = new Command('status')\n .description('查看项目状态')\n .action(async () => {\n try {\n logger.header('项目状态');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 显示项目信息\n await displayProjectInfo();\n\n // 显示功能清单\n await displayFeatureInventory();\n\n // 显示 Git 状态\n await displayGitStatus();\n\n // 显示最近活动\n await displayRecentActivity();\n } catch (error: any) {\n logger.error(`获取状态失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 显示项目信息\n */\nasync function displayProjectInfo(): Promise<void> {\n logger.info('项目信息:');\n logger.newLine();\n\n // 读取项目名称\n if (await FileUtils.exists('AI_MEMORY.md')) {\n const content = await FileUtils.read('AI_MEMORY.md');\n const projectName = content.match(/项目名称.*[::]\\s*(.+)/);\n const currentPhase = content.match(/当前阶段.*[::]\\s*(.+)/);\n const lastUpdated = content.match(/最后更新.*[::]\\s*(.+)/);\n\n if (projectName) logger.step(`名称: ${projectName[1].trim()}`);\n if (currentPhase) logger.step(`阶段: ${currentPhase[1].trim()}`);\n if (lastUpdated) logger.step(`更新: ${lastUpdated[1].trim()}`);\n } else {\n logger.step('AI_MEMORY.md 不存在');\n }\n\n logger.newLine();\n}\n\n/**\n * 显示功能清单\n */\nasync function displayFeatureInventory(): Promise<void> {\n logger.info('功能清单:');\n logger.newLine();\n\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n\n if (!exists) {\n logger.info(' (无 spec 文件)');\n logger.newLine();\n return;\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n if (specs.length === 0) {\n logger.info(' (无 spec 文件)');\n logger.newLine();\n return;\n }\n\n // 解析每个 spec 的状态\n const inventory: Array<{\n name: string;\n status: string;\n progress: string;\n }> = [];\n\n for (const file of specs) {\n const filePath = path.join(specDir, file);\n const content = await FileUtils.read(filePath);\n const status = SpecUtils.parseSpecStatus(content);\n const statusWithIcon = SpecUtils.getStatusWithIcon(status);\n\n inventory.push({\n name: file.replace('.md', ''),\n status: statusWithIcon,\n progress: SpecUtils.getProgress(content),\n });\n }\n\n // 显示表格\n const tableData = inventory.map((item) => [\n item.name,\n item.status,\n item.progress,\n ]);\n\n logger.table(['功能', '状态', '进度'], tableData);\n logger.newLine();\n\n // 统计\n const completed = inventory.filter((i) => i.status.includes('已完成')).length;\n const inProgress = inventory.filter((i) => i.status.includes('进行中')).length;\n const pending = inventory.filter((i) => i.status.includes('未开始')).length;\n\n logger.info(`总计: ${inventory.length} | 已完成: ${completed} | 进行中: ${inProgress} | 未开始: ${pending}`);\n logger.newLine();\n}\n\n/**\n * 显示 Git 状态\n */\nasync function displayGitStatus(): Promise<void> {\n const isRepo = await GitUtils.isGitRepo();\n\n if (!isRepo) {\n logger.info('Git 状态: 非 Git 仓库');\n logger.newLine();\n return;\n }\n\n try {\n const branch = await GitUtils.getCurrentBranch();\n const commit = await GitUtils.getCurrentCommit();\n\n logger.info('Git 状态:');\n logger.step(`分支: ${branch}`);\n logger.step(`提交: ${commit}`);\n logger.newLine();\n } catch {\n logger.info('Git 状态: 无法获取');\n logger.newLine();\n }\n}\n\n/**\n * 显示最近活动\n */\nasync function displayRecentActivity(): Promise<void> {\n logger.info('最近活动:');\n logger.newLine();\n\n // 检查会话日志\n const sessionDir = 'docs/sessions';\n const exists = await FileUtils.exists(sessionDir);\n\n if (!exists) {\n logger.info(' (无会话记录)');\n logger.newLine();\n return;\n }\n\n const files = await FileUtils.findFiles('*.md', sessionDir);\n if (files.length === 0) {\n logger.info(' (无会话记录)');\n logger.newLine();\n return;\n }\n\n // 按时间排序,取最近 5 个\n const sorted = files.sort().reverse().slice(0, 5);\n\n for (const file of sorted) {\n const filePath = path.join(sessionDir, file);\n const stat = await FileUtils.read(filePath);\n const specMatch = stat.match(/\\*\\*Spec\\*\\*:\\s*(.+)/);\n const spec = specMatch ? specMatch[1].trim() : '未知';\n\n // 从文件名提取时间\n const match = file.match(/(\\d{4}-\\d{2}-\\d{2})/);\n const date = match ? match[1] : '未知';\n\n logger.step(`${date} - ${spec}`);\n }\n\n logger.newLine();\n\n if (files.length > 5) {\n logger.info(`(还有 ${files.length - 5} 个历史会话记录)`);\n logger.newLine();\n }\n}\n\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport inquirer from 'inquirer';\n\n/**\n * Detect-deps 命令 - 检测依赖关系\n */\nexport const detectDepsCommand = new Command('detect-deps')\n .argument('[spec-file]', 'Spec 文件路径')\n .description('检测依赖关系')\n .action(async (specFile) => {\n try {\n logger.header('检测依赖关系');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 如果没有指定 spec,扫描所有 specs\n if (!specFile) {\n logger.info('未指定 spec 文件,将扫描所有 specs...');\n logger.newLine();\n\n const specsDir = 'docs/specs';\n const exists = await FileUtils.exists(specsDir);\n\n if (!exists) {\n logger.error('未找到 spec 文件');\n process.exit(1);\n }\n\n const files = await FileUtils.findFiles('*.md', specsDir);\n const specs = files.filter((f) => f !== 'template.md');\n\n if (specs.length === 0) {\n logger.error('未找到 spec 文件');\n process.exit(1);\n }\n\n for (const spec of specs) {\n const specPath = path.join(specsDir, spec);\n logger.step(`处理: ${spec}`);\n await detectDependencies(specPath);\n logger.newLine();\n }\n } else {\n // 检查文件是否存在\n const exists = await FileUtils.exists(specFile);\n if (!exists) {\n logger.error(`Spec 文件不存在: ${specFile}`);\n process.exit(1);\n }\n\n await detectDependencies(specFile);\n }\n\n logger.header('依赖检测完成');\n } catch (error: any) {\n logger.error(`依赖检测失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 检测依赖关系\n */\nasync function detectDependencies(specFile: string): Promise<void> {\n logger.step('自动检测依赖关系...');\n\n const projectDir = '.';\n const allDeps = new Set<string>();\n\n // 1. 扫描后端依赖\n const backendDir = path.join(projectDir, 'backend');\n const backendExists = await FileUtils.exists(backendDir);\n\n if (backendExists) {\n // 扫描 API 调用\n const apiDeps = await scanBackendApiCalls(backendDir);\n apiDeps.forEach((d) => allDeps.add(d));\n\n // 扫描实体关联\n const entityDeps = await scanBackendEntityRelations(backendDir);\n entityDeps.forEach((d) => allDeps.add(d));\n\n // 扫描服务引用\n const serviceDeps = await scanBackendServiceRefs(backendDir);\n serviceDeps.forEach((d) => allDeps.add(d));\n }\n\n // 2. 扫描前端依赖\n const frontendDir = path.join(projectDir, 'frontend');\n const frontendExists = await FileUtils.exists(frontendDir);\n\n if (frontendExists) {\n const frontendDeps = await scanFrontendApiCalls(frontendDir);\n frontendDeps.forEach((d) => allDeps.add(d));\n }\n\n if (allDeps.size === 0) {\n logger.info('未检测到明确的依赖关系');\n return;\n }\n\n // 3. 匹配到对应的 spec 文件\n const detectedSpecs: string[] = [];\n for (const dep of allDeps) {\n const matchedSpec = await findSpecByKeyword(dep, 'docs/specs');\n if (matchedSpec && !detectedSpecs.includes(matchedSpec)) {\n detectedSpecs.push(matchedSpec);\n }\n }\n\n if (detectedSpecs.length === 0) {\n logger.info('检测到依赖,但未找到对应的 spec 文件');\n return;\n }\n\n // 4. 输出检测结果\n logger.success(`检测到 ${detectedSpecs.length} 个潜在依赖:`);\n for (const spec of detectedSpecs) {\n logger.step(`- ${spec}`);\n }\n logger.newLine();\n\n // 5. 询问是否自动更新\n const answers = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'autoUpdate',\n message: '是否自动更新依赖关系到 spec 文件?',\n default: true,\n },\n ]);\n\n if (answers.autoUpdate) {\n await updateSpecDependencies(specFile, detectedSpecs);\n logger.success('依赖关系已更新');\n }\n}\n\n/**\n * 扫描后端 API 调用\n */\nasync function scanBackendApiCalls(backendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(backendDir, 'src');\n\n try {\n // 查找 Java 文件中的 RestTemplate/WebClient/RestClient 调用\n const javaFiles = await FileUtils.findFiles('*.java', srcDir);\n\n for (const file of javaFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 API 路径\n const pathRegex = /\"(\\/api\\/[^\"]+)\"/g;\n let match;\n while ((match = pathRegex.exec(content)) !== null) {\n const fullPath = match[1];\n // 提取模块名 (如 /api/users -> users)\n const parts = fullPath.split('/').filter(Boolean);\n if (parts.length > 1) {\n deps.push(parts[1]); // 'api' 后面的部分\n }\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 扫描后端实体关联\n */\nasync function scanBackendEntityRelations(backendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(backendDir, 'src');\n\n try {\n const javaFiles = await FileUtils.findFiles('*.java', srcDir);\n\n for (const file of javaFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 @JoinColumn, @ManyToOne, @OneToMany\n if (\n content.includes('@JoinColumn') ||\n content.includes('@ManyToOne') ||\n content.includes('@OneToMany')\n ) {\n // 提取关联的实体类型\n const typeRegex = /type\\s*=\\s*(\\w+)/g;\n let match;\n while ((match = typeRegex.exec(content)) !== null) {\n deps.push(match[1].toLowerCase());\n }\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 扫描后端服务引用\n */\nasync function scanBackendServiceRefs(backendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(backendDir, 'src');\n\n try {\n const javaFiles = await FileUtils.findFiles('*.java', srcDir);\n\n for (const file of javaFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 Service 注入\n const serviceRegex = /private\\s+(\\w+)Service/g;\n let match;\n while ((match = serviceRegex.exec(content)) !== null) {\n const serviceName = match[1];\n // 提取模块名 (UserService -> user)\n const moduleName = serviceName.replace(/Service$/, '').toLowerCase();\n deps.push(moduleName);\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 扫描前端 API 调用\n */\nasync function scanFrontendApiCalls(frontendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(frontendDir, 'src');\n\n try {\n // 查找 TypeScript/JavaScript 文件\n const tsFiles = await FileUtils.findFiles('*.{ts,tsx,js,jsx}', srcDir);\n\n for (const file of tsFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 API 路径\n const pathRegex = /\"(\\/api\\/[^\"]+)\"/g;\n let match;\n while ((match = pathRegex.exec(content)) !== null) {\n const fullPath = match[1];\n const parts = fullPath.split('/').filter(Boolean);\n if (parts.length > 1) {\n deps.push(parts[1]);\n }\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 根据关键词查找 spec\n */\nasync function findSpecByKeyword(\n keyword: string,\n specsDir: string\n): Promise<string | null> {\n const exists = await FileUtils.exists(specsDir);\n if (!exists) {\n return null;\n }\n\n try {\n const files = await FileUtils.findFiles('*.md', specsDir);\n\n for (const file of files) {\n if (file === 'template.md') continue;\n\n const name = file.replace('.md', '');\n // 模糊匹配\n if (name.includes(keyword) || keyword.includes(name)) {\n return name;\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return null;\n}\n\n/**\n * 更新 spec 的依赖关系\n */\nasync function updateSpecDependencies(\n specFile: string,\n deps: string[]\n): Promise<void> {\n let content = await FileUtils.read(specFile);\n\n // 检查是否有依赖关系部分\n if (!content.includes('## 依赖关系')) {\n // 在背景与目标前插入依赖关系部分\n const targetSection = '## 背景与目标';\n const insertIndex = content.indexOf(targetSection);\n\n if (insertIndex !== -1) {\n const depsSection = `\\n## 依赖关系\\n\\n**前置依赖**:\\n${deps.map((d) => ` - [x] ${d}`).join('\\n')}\\n\\n**被依赖于**:\\n - (自动生成,表示哪些 spec 依赖本功能)\\n\\n`;\n content =\n content.slice(0, insertIndex) + depsSection + content.slice(insertIndex);\n }\n } else {\n // 更新现有依赖关系\n const lines = content.split('\\n');\n let inDeps = false;\n const result: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (line.startsWith('## 依赖关系')) {\n inDeps = true;\n result.push(line);\n result.push('');\n result.push('**前置依赖**:');\n for (const dep of deps) {\n result.push(` - [x] ${dep}`);\n }\n result.push('');\n result.push('**被依赖于**:');\n result.push(' - (自动生成,表示哪些 spec 依赖本功能)');\n continue;\n }\n\n if (inDeps) {\n // 跳过旧的前置依赖内容,直到遇到下一个章节\n if (line.startsWith('## ') && !line.startsWith('## 依赖关系')) {\n inDeps = false;\n result.push(line);\n }\n continue;\n }\n\n result.push(line);\n }\n\n content = result.join('\\n');\n }\n\n await FileUtils.write(specFile, content);\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils, DateUtils, SpecUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { readTemplateConfig } from '../lib/template-version.js';\n\n/**\n * Sync-memory 命令 - 同步 AI_MEMORY.md\n */\nexport const syncMemoryCommand = new Command('sync-memory')\n .description('同步 AI_MEMORY.md')\n .action(async () => {\n try {\n logger.header('同步 AI_MEMORY.md');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n const aiMemoryFile = 'AI_MEMORY.md';\n const exists = await FileUtils.exists(aiMemoryFile);\n\n if (!exists) {\n logger.info('AI_MEMORY.md 不存在,跳过同步');\n process.exit(0);\n }\n\n // 1. 同步功能清单\n await syncFeatureInventory(aiMemoryFile, '.');\n\n // 2. 同步 API 列表\n await syncApiInventory(aiMemoryFile, '.');\n\n // 3. 同步数据模型\n await syncDataModels(aiMemoryFile, '.');\n\n // 4. 同步模板版本信息\n await syncTemplateVersions(aiMemoryFile, '.');\n\n // 5. 更新最后同步时间\n await updateSyncTime(aiMemoryFile);\n\n logger.success('AI_MEMORY.md 已同步');\n } catch (error: any) {\n logger.error(`同步失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 同步功能清单\n */\nasync function syncFeatureInventory(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步功能清单...');\n\n const specsDir = path.join(projectDir, 'docs/specs');\n const exists = await FileUtils.exists(specsDir);\n\n if (!exists) {\n return;\n }\n\n // 读取所有 specs\n const files = await FileUtils.findFiles('*.md', specsDir);\n const specs = files.filter((f) => f !== 'template.md');\n\n // 构建功能清单表格\n const lines: string[] = [];\n lines.push('## 功能清单 (Feature Inventory)');\n lines.push('');\n lines.push('| 功能 | Spec 文件 | 状态 | 进度 | 完成日期 | 备注 |');\n lines.push('|------|----------|------|------|---------|------|');\n\n for (const specFile of specs) {\n const name = specFile.replace('.md', '');\n const displayName = name\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n const specPath = path.join(specsDir, specFile);\n const content = await FileUtils.read(specPath);\n\n // 获取状态\n const status = SpecUtils.parseSpecStatus(content);\n const statusWithIcon = SpecUtils.getStatusWithIcon(status);\n\n // 获取进度\n const progress = SpecUtils.getProgress(content);\n\n // 获取完成日期\n let completionDate = '-';\n if (status === '已完成') {\n const dateMatch = content.match(/完成日期.*[::]\\s*(.+)/);\n if (dateMatch) {\n completionDate = dateMatch[1].trim();\n }\n }\n\n lines.push(`| ${displayName} | ${name}.md | ${statusWithIcon} | ${progress} | ${completionDate} | |`);\n }\n\n const newContent = lines.join('\\n') + '\\n';\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## 功能清单', newContent);\n}\n\n/**\n * 同步 API 列表\n */\nasync function syncApiInventory(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步 API 列表...');\n\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (!exists) {\n return;\n }\n\n const lines: string[] = [];\n lines.push('## API 列表 (API Inventory)');\n lines.push('');\n lines.push('> 本部分由 team-cli 自动扫描后端 Controller 生成');\n lines.push('');\n\n // 查找所有 Controller\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n if (controllers.length === 0) {\n lines.push('暂无 API');\n } else {\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const controllerName = controllerFile.replace('.java', '');\n const module = controllerName.replace(/Controller$/, '').toLowerCase();\n\n lines.push(`### ${module} 模块`);\n lines.push('');\n lines.push('| 方法 | 路径 | 说明 | 状态 | 日期 |');\n lines.push('|------|------|------|------|------|');\n\n // 扫描 API\n const apis = await scanControllerApis(controllerPath);\n for (const api of apis) {\n lines.push(`| ${api.method} | ${api.path} | ${api.description} | ✅ | ${api.date} |`);\n }\n lines.push('');\n }\n }\n\n const newContent = lines.join('\\n');\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## API 列表', newContent);\n}\n\n/**\n * 扫描 Controller 中的 API\n */\nasync function scanControllerApis(\n controllerPath: string\n): Promise<Array<{ method: string; path: string; description: string; date: string }>> {\n const apis: Array<{ method: string; path: string; description: string; date: string }> = [];\n const content = await FileUtils.read(controllerPath);\n\n // 提取类级别的 @RequestMapping\n let classPath = '';\n const classRequestMappingMatch = content.match(/@RequestMapping\\(\"([^\"]+)\"\\)/);\n if (classRequestMappingMatch) {\n classPath = classRequestMappingMatch[1];\n }\n\n // 扫描方法级别的映射\n const methodRegex =\n /@(GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping)\\(\"([^\"]+)\"\\)\\s*\\n\\s*public\\s+(\\w+)\\s*\\(([^)]*)\\)/g;\n let match;\n\n while ((match = methodRegex.exec(content)) !== null) {\n const mappingType = match[1];\n const methodPath = match[2];\n const methodName = match[3];\n\n // 确定 HTTP 方法\n let httpMethod = '';\n switch (mappingType) {\n case 'GetMapping':\n httpMethod = 'GET';\n break;\n case 'PostMapping':\n httpMethod = 'POST';\n break;\n case 'PutMapping':\n httpMethod = 'PUT';\n break;\n case 'DeleteMapping':\n httpMethod = 'DELETE';\n break;\n case 'PatchMapping':\n httpMethod = 'PATCH';\n break;\n }\n\n // 组合完整路径\n let fullPath = methodPath;\n if (classPath && !methodPath.startsWith('/api')) {\n fullPath = `${classPath}${methodPath}`;\n }\n\n // 提取方法注释\n const description = extractMethodComment(content, methodName);\n\n apis.push({\n method: httpMethod,\n path: fullPath,\n description,\n date: DateUtils.format(new Date(), 'YYYY-MM-DD'),\n });\n }\n\n return apis;\n}\n\n/**\n * 提取方法注释\n */\nfunction extractMethodComment(content: string, methodName: string): string {\n // 查找方法定义前的注释\n const methodIndex = content.indexOf(`${methodName}(`);\n if (methodIndex === -1) {\n return '';\n }\n\n // 向前查找注释\n const beforeMethod = content.substring(Math.max(0, methodIndex - 500), methodIndex);\n const commentMatch = beforeMethod.match(/\\*\\s*([^\\n*]+)/g);\n\n if (commentMatch && commentMatch.length > 0) {\n return commentMatch[0].replace(/\\*\\s?/, '').trim();\n }\n\n return '';\n}\n\n/**\n * 同步数据模型\n */\nasync function syncDataModels(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步数据模型...');\n\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (!exists) {\n return;\n }\n\n const lines: string[] = [];\n lines.push('## 数据模型 (Data Models)');\n lines.push('');\n lines.push('> 本部分由 team-cli 自动扫描后端 Entity 生成');\n lines.push('');\n\n // 查找所有 Entity\n const srcDir = path.join(backendDir, 'src');\n const entities = await FileUtils.findFiles('*Entity.java', srcDir);\n\n if (entities.length === 0) {\n lines.push('暂无数据模型');\n } else {\n lines.push('| 模型 | 说明 | 字段 | 关联 |');\n lines.push('|------|------|------|------|');\n\n for (const entityFile of entities) {\n const entityPath = path.join(srcDir, entityFile);\n const entityName = entityFile.replace('.java', '').replace(/Entity$/, '');\n const displayName = entityName\n .split(/(?=[A-Z])/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n\n // 读取实体内容\n const content = await FileUtils.read(entityPath);\n\n // 提取注释\n const classCommentMatch = content.match(/\\/\\*\\*\\s*\\n([^*]|\\*[^/])*\\*\\//);\n const description = classCommentMatch\n ? classCommentMatch[0].replace(/\\/\\*\\*|\\*\\/|\\*/g, '').trim()\n : '';\n\n // 计算字段数\n const fieldCount = (content.match(/private\\s+\\w+/g) || []).length;\n\n // 检查关联\n const relations: string[] = [];\n if (content.includes('@ManyToOne')) relations.push('Many-to-One');\n if (content.includes('@OneToMany')) relations.push('One-to-Many');\n if (content.includes('@OneToOne')) relations.push('One-to-One');\n if (content.includes('@ManyToMany')) relations.push('Many-to-Many');\n\n lines.push(`| ${displayName} | ${description} | ${fieldCount} | ${relations.join(', ') || '-'} |`);\n }\n }\n\n const newContent = lines.join('\\n');\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## 数据模型', newContent);\n}\n\n/**\n * 更新同步时间\n */\nasync function updateSyncTime(aiMemoryFile: string): Promise<void> {\n const content = await FileUtils.read(aiMemoryFile);\n const timestamp = DateUtils.format(new Date(), 'YYYY-MM-DD HH:mm:ss');\n\n let updated = content;\n\n // 查找并更新最后同步时间\n if (content.includes('最后同步')) {\n updated = content.replace(\n /最后同步.*[::]\\s*.+/,\n `最后同步: ${timestamp}`\n );\n } else {\n // 在文件末尾添加\n updated = content.trimEnd() + `\\n\\n---\\n\\n*最后同步: ${timestamp} by team-cli*\\n`;\n }\n\n await FileUtils.write(aiMemoryFile, updated);\n}\n\n/**\n * 替换或插入章节\n */\nasync function replaceOrInsertSection(\n aiMemoryFile: string,\n sectionTitle: string,\n newContent: string\n): Promise<void> {\n const content = await FileUtils.read(aiMemoryFile);\n\n // 检查是否存在该章节\n if (content.includes(sectionTitle)) {\n // 替换现有章节\n const lines = content.split('\\n');\n const result: string[] = [];\n let inSection = false;\n let skip = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (line.startsWith(sectionTitle)) {\n inSection = true;\n result.push(newContent);\n skip = true;\n continue;\n }\n\n if (inSection) {\n if (line.startsWith('## ') && !line.startsWith(sectionTitle)) {\n inSection = false;\n skip = false;\n result.push(line);\n }\n continue;\n }\n\n if (!skip) {\n result.push(line);\n }\n }\n\n await FileUtils.write(aiMemoryFile, result.join('\\n'));\n } else {\n // 插入新章节\n await FileUtils.write(aiMemoryFile, content.trimEnd() + '\\n\\n' + newContent + '\\n');\n }\n}\n\n\n/**\n * 同步模板版本信息\n */\nasync function syncTemplateVersions(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步模板版本信息...');\n\n const config = await readTemplateConfig(projectDir);\n\n if (!config) {\n return;\n }\n\n const lines: string[] = [];\n lines.push('## 模板版本信息');\n lines.push('');\n lines.push('> 本部分由 team-cli 自动管理,记录使用的前后端模板版本');\n lines.push('');\n lines.push('| 类型 | 仓库 | Tag | Branch | Commit | 更新时间 |');\n lines.push('|------|------|-----|--------|--------|----------|');\n\n // 前端模板\n if (config.frontend) {\n const repoName = extractRepoName(config.frontend.repository);\n const commit = config.frontend.commit?.substring(0, 8) || '-';\n const tag = config.frontend.tag || '-';\n const branch = config.frontend.branch || '-';\n const updateDate = config.frontend.lastUpdate\n ? new Date(config.frontend.lastUpdate).toLocaleDateString('zh-CN')\n : '-';\n\n lines.push(`| 前端 | ${repoName} | ${tag} | ${branch} | ${commit} | ${updateDate} |`);\n }\n\n // 后端模板\n if (config.backend) {\n const repoName = extractRepoName(config.backend.repository);\n const commit = config.backend.commit?.substring(0, 8) || '-';\n const tag = config.backend.tag || '-';\n const branch = config.backend.branch || '-';\n const updateDate = config.backend.lastUpdate\n ? new Date(config.backend.lastUpdate).toLocaleDateString('zh-CN')\n : '-';\n\n lines.push(`| 后端 | ${repoName} | ${tag} | ${branch} | ${commit} | ${updateDate} |`);\n }\n\n const newContent = lines.join('\\n') + '\\n';\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## 模板版本信息', newContent);\n}\n\n/**\n * 从仓库 URL 中提取仓库名\n */\nfunction extractRepoName(repository: string): string {\n // 支持的格式:\n // - git@gitlab.com:group/project.git\n // - https://gitlab.com/group/project.git\n\n let path = repository;\n\n // 移除协议前缀\n path = path.replace(/^https?:\\/\\//, '');\n path = path.replace(/^git@/, '');\n\n // 移除域名部分\n const parts = path.split('/');\n if (parts.length > 1) {\n path = parts.slice(1).join('/');\n }\n\n // 移除 .git 后缀\n path = path.replace(/\\.git$/, '');\n\n return path;\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils, DateUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport inquirer from 'inquirer';\nimport { Listr } from 'listr2';\n\n/**\n * Check-api 命令 - API 检查\n */\nexport const checkApiCommand = new Command('check-api')\n .description('API 检查(冲突/变更/Registry)')\n .action(async () => {\n try {\n logger.header('API 检查');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 交互式选择\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'checkType',\n message: '选择检查类型:',\n choices: [\n { name: '检测 API 冲突', value: 'conflicts' },\n { name: '检测 API 变更', value: 'changes' },\n { name: '生成 API Registry', value: 'registry' },\n { name: '全部执行', value: 'all' },\n ],\n default: 'all',\n },\n ]);\n\n const tasks = new Listr([]);\n\n // 根据选择添加任务\n if (answers.checkType === 'conflicts' || answers.checkType === 'all') {\n tasks.add({\n title: '检测 API 冲突',\n task: async () => {\n await checkApiConflicts('.');\n },\n });\n }\n\n if (answers.checkType === 'changes' || answers.checkType === 'all') {\n tasks.add({\n title: '检测 API 变更',\n task: async () => {\n await detectApiChanges('.');\n },\n });\n }\n\n if (answers.checkType === 'registry' || answers.checkType === 'all') {\n tasks.add({\n title: '生成 API Registry',\n task: async () => {\n await generateApiRegistry('.');\n },\n });\n }\n\n await tasks.run();\n\n logger.newLine();\n logger.header('API 检查完成');\n } catch (error: any) {\n logger.error(`API 检查失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 检测 API 冲突\n */\nasync function checkApiConflicts(projectDir: string): Promise<void> {\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (!exists) {\n logger.info('未找到后端项目');\n return;\n }\n\n logger.step('扫描后端 API...');\n logger.newLine();\n\n const apiMap = new Map<string, string[]>();\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n // 收集所有 API\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const apis = await extractApisFromController(controllerPath);\n\n for (const api of apis) {\n const key = `${api.method}:${api.path}`;\n if (!apiMap.has(key)) {\n apiMap.set(key, []);\n }\n apiMap.get(key)!.push(controllerFile);\n }\n }\n\n // 检查冲突\n const conflicts: Array<{ key: string; controllers: string[] }> = [];\n for (const [key, controllers] of apiMap.entries()) {\n if (controllers.length > 1) {\n conflicts.push({ key, controllers });\n }\n }\n\n if (conflicts.length === 0) {\n logger.success('未发现 API 冲突');\n } else {\n logger.error(`发现 ${conflicts.length} 个 API 冲突:`);\n logger.newLine();\n\n for (const conflict of conflicts) {\n logger.error(`冲突: ${conflict.key}`);\n for (const controller of conflict.controllers) {\n logger.step(` - ${controller}`);\n }\n logger.newLine();\n }\n }\n}\n\n/**\n * 检测 API 变更\n */\nasync function detectApiChanges(projectDir: string): Promise<void> {\n const backendDir = path.join(projectDir, 'backend');\n const registryFile = path.join(projectDir, 'docs/api-registry.md');\n const registryExists = await FileUtils.exists(registryFile);\n\n if (!registryExists) {\n logger.info('API Registry 不存在,跳过变更检测');\n logger.info(\"运行 'team-cli check-api' 选择 '生成 API Registry'\");\n return;\n }\n\n logger.step('检测 API 变更...');\n logger.newLine();\n\n // 读取现有 Registry\n const registryContent = await FileUtils.read(registryFile);\n const existingApis = extractApisFromRegistry(registryContent);\n\n // 扫描当前 API\n const currentApis = new Map<string, { method: string; path: string; description: string }>();\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const apis = await extractApisFromController(controllerPath);\n\n for (const api of apis) {\n const key = `${api.method}:${api.path}`;\n currentApis.set(key, api);\n }\n }\n\n // 比较差异\n const added: Array<{ method: string; path: string }> = [];\n const removed: Array<{ method: string; path: string }> = [];\n const modified: Array<{ method: string; path: string; oldDesc: string; newDesc: string }> = [];\n\n for (const [key, api] of currentApis.entries()) {\n if (!existingApis.has(key)) {\n added.push({ method: api.method, path: api.path });\n } else {\n const existingApi = existingApis.get(key)!;\n if (existingApi.description !== api.description) {\n modified.push({\n method: api.method,\n path: api.path,\n oldDesc: existingApi.description,\n newDesc: api.description,\n });\n }\n }\n }\n\n for (const [key, api] of existingApis.entries()) {\n if (!currentApis.has(key)) {\n removed.push({ method: api.method, path: api.path });\n }\n }\n\n // 输出结果\n let hasChanges = false;\n\n if (added.length > 0) {\n hasChanges = true;\n logger.success(`新增 API (${added.length}):`);\n for (const api of added) {\n logger.step(` + ${api.method} ${api.path}`);\n }\n logger.newLine();\n }\n\n if (removed.length > 0) {\n hasChanges = true;\n logger.error(`删除 API (${removed.length}):`);\n for (const api of removed) {\n logger.step(` - ${api.method} ${api.path}`);\n }\n logger.newLine();\n }\n\n if (modified.length > 0) {\n hasChanges = true;\n logger.warn(`修改 API (${modified.length}):`);\n for (const api of modified) {\n logger.step(` ~ ${api.method} ${api.path}`);\n logger.step(` 旧: ${api.oldDesc}`);\n logger.step(` 新: ${api.newDesc}`);\n }\n logger.newLine();\n }\n\n if (!hasChanges) {\n logger.success('未检测到 API 变更');\n }\n}\n\n/**\n * 生成 API Registry\n */\nasync function generateApiRegistry(projectDir: string): Promise<void> {\n const registryFile = path.join(projectDir, 'docs/api-registry.md');\n\n logger.step('扫描并生成 API Registry...');\n\n // 创建 docs 目录\n await FileUtils.ensureDir(path.dirname(registryFile));\n\n // 写入文件头\n const header = `# API Registry\n\n> 本文件记录所有 API 的定义、版本和变更历史\n\n## API 规范\n\n### 基础信息\n- **Base URL**: \\`/api\\`\n- **认证方式**: JWT Bearer Token\n- **数据格式**: JSON\n- **字符编码**: UTF-8\n\n### 响应码规范\n| 状态码 | 说明 |\n|--------|------|\n| 200 | 成功 |\n| 201 | 创建成功 |\n| 400 | 请求参数错误 |\n| 401 | 未认证 |\n| 403 | 无权限 |\n| 404 | 资源不存在 |\n| 500 | 服务器错误 |\n\n---\n\n*最后更新: ${DateUtils.format(new Date(), 'YYYY-MM-DD HH:mm:ss')}*\n`;\n\n // 扫描 Controller 并生成 API 文档\n let content = header;\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (exists) {\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n // 按模块分组\n const moduleMap = new Map<string, Array<{ method: string; path: string; description: string }>>();\n\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const controllerName = controllerFile.replace('.java', '');\n const module = controllerName.replace(/Controller$/, '').toLowerCase();\n\n if (!moduleMap.has(module)) {\n moduleMap.set(module, []);\n }\n\n const apis = await extractApisFromController(controllerPath);\n moduleMap.get(module)!.push(...apis);\n }\n\n // 生成文档\n for (const [module, apis] of moduleMap.entries()) {\n content += `\\n## ${module.charAt(0).toUpperCase() + module.slice(1)} 模块\\n\\n`;\n\n for (const api of apis) {\n content += `### ${api.method} ${api.path}\\n\\n`;\n content += `**版本**: v1.0\\n\\n`;\n content += `**说明**: ${api.description || '-'}\\n\\n`;\n content += `---\\n\\n`;\n }\n }\n }\n\n await FileUtils.write(registryFile, content);\n\n logger.success(`API Registry 已生成: ${registryFile}`);\n}\n\n/**\n * 从 Controller 提取 API\n */\nasync function extractApisFromController(\n controllerPath: string\n): Promise<Array<{ method: string; path: string; description: string }>> {\n const apis: Array<{ method: string; path: string; description: string }> = [];\n const content = await FileUtils.read(controllerPath);\n\n // 提取类级别的 @RequestMapping\n let classPath = '';\n const classRequestMappingMatch = content.match(/@RequestMapping\\(\"([^\"]+)\"\\)/);\n if (classRequestMappingMatch) {\n classPath = classRequestMappingMatch[1];\n }\n\n // 扫描方法级别的映射\n const methodRegex =\n /@(GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping)\\(\"([^\"]+)\"\\)\\s*\\n\\s*public\\s+(\\w+)\\s*\\(([^)]*)\\)/g;\n let match;\n\n while ((match = methodRegex.exec(content)) !== null) {\n const mappingType = match[1];\n const methodPath = match[2];\n const methodName = match[3];\n\n // 确定 HTTP 方法\n let httpMethod = '';\n switch (mappingType) {\n case 'GetMapping':\n httpMethod = 'GET';\n break;\n case 'PostMapping':\n httpMethod = 'POST';\n break;\n case 'PutMapping':\n httpMethod = 'PUT';\n break;\n case 'DeleteMapping':\n httpMethod = 'DELETE';\n break;\n case 'PatchMapping':\n httpMethod = 'PATCH';\n break;\n }\n\n // 组合完整路径\n let fullPath = methodPath;\n if (classPath && !methodPath.startsWith('/api')) {\n fullPath = `${classPath}${methodPath}`;\n }\n\n // 提取方法注释\n const description = extractMethodComment(content, methodName);\n\n apis.push({\n method: httpMethod,\n path: fullPath,\n description,\n });\n }\n\n return apis;\n}\n\n/**\n * 从 Registry 提取 API\n */\nfunction extractApisFromRegistry(\n registryContent: string\n): Map<string, { method: string; path: string; description: string }> {\n const apis = new Map<string, { method: string; path: string; description: string }>();\n\n // 匹配 API 条目\n const apiRegex = /### (GET|POST|PUT|DELETE|PATCH) ([^\\n]+)\\n\\n\\*\\*版本\\*\\*:.+?\\n\\n\\*\\*说明\\*\\*:\\s*([^\\n-]+)/g;\n let match;\n\n while ((match = apiRegex.exec(registryContent)) !== null) {\n const method = match[1];\n const path = match[2].trim();\n const description = match[3].trim();\n const key = `${method}:${path}`;\n apis.set(key, { method, path, description });\n }\n\n return apis;\n}\n\n/**\n * 提取方法注释\n */\nfunction extractMethodComment(content: string, methodName: string): string {\n const methodIndex = content.indexOf(`${methodName}(`);\n if (methodIndex === -1) {\n return '';\n }\n\n const beforeMethod = content.substring(Math.max(0, methodIndex - 500), methodIndex);\n const commentMatch = beforeMethod.match(/\\*\\s*([^\\n*]+)/g);\n\n if (commentMatch && commentMatch.length > 0) {\n return commentMatch[0].replace(/\\*\\s?/, '').trim();\n }\n\n return '';\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport inquirer from 'inquirer';\n\n/**\n * Logs 命令 - 查看会话日志\n */\nexport const logsCommand = new Command('logs')\n .argument('[filter]', '过滤器 (today, --all, 或日期 YYYY-MM-DD)')\n .description('查看会话日志')\n .action(async (filter = 'today') => {\n try {\n logger.header('会话日志');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n const sessionsDir = 'docs/sessions';\n const dirExists = await FileUtils.exists(sessionsDir);\n\n if (!dirExists) {\n logger.info('暂无会话日志');\n logger.info(\"运行 'team-cli dev' 后会自动生成日志\");\n process.exit(0);\n }\n\n // 确定目标目录\n let targetDir = '';\n let displayTitle = '';\n\n switch (filter) {\n case '':\n case 'today': {\n const today = new Date().toISOString().split('T')[0];\n targetDir = path.join(sessionsDir, today);\n const todayExists = await FileUtils.exists(targetDir);\n if (!todayExists) {\n logger.info('今日暂无会话日志');\n process.exit(0);\n }\n displayTitle = '显示今日会话日志:';\n break;\n }\n case '--all':\n case '-a': {\n targetDir = sessionsDir;\n displayTitle = '显示所有会话日志:';\n break;\n }\n default: {\n // 假设是日期格式\n targetDir = path.join(sessionsDir, filter);\n const dateExists = await FileUtils.exists(targetDir);\n if (!dateExists) {\n logger.error(`未找到日期 '${filter}' 的日志`);\n logger.info('可用日期:');\n\n // 列出可用日期\n const entries = await FileUtils.findFiles('*/', sessionsDir);\n const dates = entries.slice(0, 10);\n for (const date of dates) {\n logger.info(` ${date.replace('/', '')}`);\n }\n process.exit(1);\n }\n displayTitle = `显示 ${filter} 的会话日志:`;\n break;\n }\n }\n\n logger.info(displayTitle);\n logger.newLine();\n\n // 收集日志文件\n const logs = await collectLogFiles(targetDir);\n\n if (logs.length === 0) {\n logger.info('无日志文件');\n process.exit(0);\n }\n\n // 显示日志列表\n for (let i = 0; i < logs.length; i++) {\n const relPath = path.relative(sessionsDir, logs[i]);\n logger.step(`${i + 1}) ${relPath}`);\n }\n\n logger.newLine();\n\n // 询问选择\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'selection',\n message: '输入编号查看详情 (或 Enter 退出):',\n default: '',\n },\n ]);\n\n const selection = answers.selection.trim();\n\n if (selection === '') {\n process.exit(0);\n }\n\n const selectionNum = parseInt(selection, 10);\n\n if (isNaN(selectionNum) || selectionNum < 1 || selectionNum > logs.length) {\n logger.error('无效的选择');\n process.exit(1);\n }\n\n // 显示选中的日志\n const selectedLog = logs[selectionNum - 1];\n logger.newLine();\n logger.header('日志详情');\n logger.newLine();\n\n const content = await FileUtils.read(selectedLog);\n console.log(content);\n } catch (error: any) {\n logger.error(`查看日志失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 收集日志文件\n */\nasync function collectLogFiles(targetDir: string): Promise<string[]> {\n const logs: string[] = [];\n\n try {\n // 查找所有 markdown 文件,排除 index.md\n const allFiles = await FileUtils.findFiles('*.md', targetDir);\n const filtered = allFiles.filter((f) => f !== 'index.md');\n\n for (const file of filtered) {\n const filePath = path.join(targetDir, file);\n // 确保是文件而不是目录\n const stat = await FileUtils.exists(filePath);\n if (stat) {\n logs.push(filePath);\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return logs;\n}\n","import path from 'path';\nimport os from 'os';\nimport crypto from 'crypto';\nimport { FileUtils } from './utils.js';\nimport { logger } from './logger.js';\n\n/**\n * 用户配置接口\n */\nexport interface UserConfig {\n gitlab: {\n accessToken: string;\n baseUrl: string;\n timeout?: number;\n };\n preferences?: {\n defaultBackendBranch?: string;\n defaultFrontendBranch?: string;\n };\n}\n\n/**\n * 用户配置管理类\n */\nexport class UserConfigManager {\n private configPath: string;\n\n constructor() {\n const configDir = path.join(os.homedir(), '.team-cli');\n this.configPath = path.join(configDir, 'config.json');\n }\n\n /**\n * 加载用户配置\n */\n async load(): Promise<UserConfig | null> {\n try {\n const exists = await FileUtils.exists(this.configPath);\n if (!exists) {\n return null;\n }\n\n const content = await FileUtils.read(this.configPath);\n const config = JSON.parse(content);\n\n // 解密 access token\n if (config.gitlab?.accessToken) {\n config.gitlab.accessToken = this.decrypt(config.gitlab.accessToken);\n }\n\n return config;\n } catch (error) {\n logger.debug(`加载用户配置失败: ${error}`);\n return null;\n }\n }\n\n /**\n * 保存用户配置\n */\n async save(config: UserConfig): Promise<void> {\n try {\n const configDir = path.dirname(this.configPath);\n await FileUtils.ensureDir(configDir);\n\n // 加密 access token(深拷贝以避免修改原对象)\n const configToSave = JSON.parse(JSON.stringify(config));\n if (configToSave.gitlab?.accessToken) {\n configToSave.gitlab.accessToken = this.encrypt(configToSave.gitlab.accessToken);\n }\n\n const content = JSON.stringify(configToSave, null, 2);\n await FileUtils.write(this.configPath, content);\n } catch (error) {\n throw new Error(`保存用户配置失败: ${error}`);\n }\n }\n\n /**\n * 更新 GitLab Token\n */\n async updateGitLabToken(token: string, baseUrl?: string): Promise<void> {\n const config = (await this.load()) || {\n gitlab: {\n accessToken: '',\n baseUrl: 'https://gitlab.com',\n timeout: 30000,\n },\n };\n\n config.gitlab.accessToken = token;\n if (baseUrl) {\n config.gitlab.baseUrl = baseUrl;\n }\n\n await this.save(config);\n }\n\n /**\n * 获取 GitLab Token\n */\n async getGitLabToken(): Promise<string | null> {\n const config = await this.load();\n return config?.gitlab?.accessToken || null;\n }\n\n /**\n * 获取 GitLab 配置\n */\n async getGitLabConfig(): Promise<{ accessToken: string; baseUrl: string; timeout?: number } | null> {\n const config = await this.load();\n return config?.gitlab || null;\n }\n\n /**\n * 检查是否已有配置\n */\n async hasConfig(): Promise<boolean> {\n const config = await this.load();\n return config !== null && config.gitlab?.accessToken !== undefined;\n }\n\n /**\n * 删除配置\n */\n async removeConfig(): Promise<void> {\n try {\n const exists = await FileUtils.exists(this.configPath);\n if (exists) {\n await FileUtils.remove(this.configPath);\n }\n } catch (error) {\n throw new Error(`删除配置失败: ${error}`);\n }\n }\n\n /**\n * 简单加密 (使用机器特定密钥)\n */\n private encrypt(text: string): string {\n const key = this.getMachineKey();\n const iv = crypto.randomBytes(16);\n const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);\n let encrypted = cipher.update(text, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n return iv.toString('hex') + ':' + encrypted;\n }\n\n /**\n * 简单解密\n */\n private decrypt(encryptedText: string): string {\n try {\n const key = this.getMachineKey();\n const parts = encryptedText.split(':');\n const iv = Buffer.from(parts[0], 'hex');\n const encrypted = parts[1];\n const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);\n let decrypted = decipher.update(encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n return decrypted;\n } catch {\n // 如果解密失败,可能是旧版本的明文存储\n return encryptedText;\n }\n }\n\n /**\n * 获取机器特定密钥\n */\n private getMachineKey(): Buffer {\n const hostname = os.hostname();\n const platform = os.platform();\n const arch = os.arch();\n const cpus = os.cpus();\n\n // 使用机器信息生成密钥\n const machineInfo = `${hostname}-${platform}-${arch}-${cpus[0]?.model || 'unknown'}`;\n return crypto.createHash('sha256').update(machineInfo).digest();\n }\n\n /**\n * 获取配置目录\n */\n getConfigDir(): string {\n return path.dirname(this.configPath);\n }\n\n /**\n * 获取配置文件路径\n */\n getConfigPath(): string {\n return this.configPath;\n }\n}\n\n// 导出单例\nexport const userConfigManager = new UserConfigManager();\n","/**\n * GitLab API 客户端\n */\n\n/**\n * GitLab Tag 信息\n */\nexport interface GitLabTag {\n name: string;\n commit: {\n id: string;\n short_id: string;\n created_at: string;\n };\n message: string;\n release: {\n tag_name: string;\n description: string;\n } | null;\n}\n\n/**\n * GitLab Branch 信息\n */\nexport interface GitLabBranch {\n name: string;\n commit: {\n id: string;\n short_id: string;\n title: string;\n created_at: string;\n author_name: string;\n author_email: string;\n };\n protected: boolean;\n default: boolean;\n}\n\n/**\n * GitLab Diff 结果\n */\nexport interface GitLabDiffResult {\n from: string;\n to: string;\n commits: Array<{\n id: string;\n short_id: string;\n title: string;\n author_name: string;\n created_at: string;\n message: string;\n }>;\n diffs: Array<{\n old_path: string;\n new_path: string;\n diff: string;\n new_file: boolean;\n renamed_file: boolean;\n deleted_file: boolean;\n }>;\n}\n\n/**\n * GitLab 项目信息\n */\nexport interface GitLabProject {\n id: number;\n name: string;\n path: string;\n path_with_namespace: string;\n http_url_to_repo: string;\n ssh_url_to_repo: string;\n default_branch: string;\n last_activity_at: string;\n}\n\n/**\n * GitLab API 配置\n */\nexport interface GitLabConfig {\n accessToken: string;\n baseUrl: string;\n timeout?: number;\n}\n\n/**\n * GitLab API 客户端类\n */\nexport class GitLabAPI {\n private config: GitLabConfig;\n private readonly defaultTimeout = 30000;\n\n constructor(config: GitLabConfig) {\n this.config = {\n ...config,\n timeout: config.timeout || this.defaultTimeout,\n };\n }\n\n /**\n * 验证 Token 是否有效\n */\n async authenticate(): Promise<boolean> {\n try {\n const response = await this.request('/user');\n return response.ok;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * 列出项目的所有 Tags\n */\n async listTags(projectPath: string): Promise<GitLabTag[]> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(`/projects/${encodedPath}/repository/tags?per_page=100`);\n\n if (!response.ok) {\n throw new Error(`GitLab API 请求失败: ${response.status}`);\n }\n\n const tags: GitLabTag[] = await response.json();\n return tags.sort((a, b) => {\n // 按版本号排序(降序)\n return this.compareVersionStrings(b.name, a.name);\n });\n } catch (error) {\n throw new Error(`获取 Tags 失败: ${error}`);\n }\n }\n\n /**\n * 列出项目的所有 Branches\n */\n async listBranches(projectPath: string): Promise<GitLabBranch[]> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(`/projects/${encodedPath}/repository/branches?per_page=100`);\n\n if (!response.ok) {\n throw new Error(`GitLab API 请求失败: ${response.status}`);\n }\n\n const branches: GitLabBranch[] = await response.json();\n\n // 将默认分支放在最前面\n return branches.sort((a, b) => {\n if (a.default) return -1;\n if (b.default) return 1;\n return a.name.localeCompare(b.name);\n });\n } catch (error) {\n throw new Error(`获取 Branches 失败: ${error}`);\n }\n }\n\n /**\n * 验证 Tag 是否存在\n */\n async validateTag(projectPath: string, tag: string): Promise<boolean> {\n try {\n const tags = await this.listTags(projectPath);\n return tags.some((t) => t.name === tag);\n } catch {\n return false;\n }\n }\n\n /**\n * 验证 Branch 是否存在\n */\n async validateBranch(projectPath: string, branch: string): Promise<boolean> {\n try {\n const branches = await this.listBranches(projectPath);\n return branches.some((b) => b.name === branch);\n } catch {\n return false;\n }\n }\n\n /**\n * 获取项目信息\n */\n async getProject(projectPath: string): Promise<GitLabProject | null> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(`/projects/${encodedPath}`);\n\n if (!response.ok) {\n return null;\n }\n\n return await response.json();\n } catch {\n return null;\n }\n }\n\n /**\n * 获取指定 Tag 的 commit 信息\n */\n async getTagCommit(projectPath: string, tag: string): Promise<string | null> {\n try {\n const tags = await this.listTags(projectPath);\n const targetTag = tags.find((t) => t.name === tag);\n return targetTag?.commit.id || null;\n } catch {\n return null;\n }\n }\n\n /**\n * 获取指定 Branch 的最新 commit 信息\n */\n async getBranchCommit(projectPath: string, branch: string): Promise<string | null> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(\n `/projects/${encodedPath}/repository/branches/${encodeURIComponent(branch)}`\n );\n\n if (!response.ok) {\n return null;\n }\n\n const branchInfo: GitLabBranch = await response.json();\n return branchInfo.commit.id;\n } catch {\n return null;\n }\n }\n\n /**\n * 对比两个版本之间的差异\n */\n async compareVersions(\n projectPath: string,\n from: string,\n to: string\n ): Promise<GitLabDiffResult | null> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(\n `/projects/${encodedPath}/repository/compare?from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}`\n );\n\n if (!response.ok) {\n return null;\n }\n\n return await response.json();\n } catch {\n return null;\n }\n }\n\n /**\n * 比较两个版本号(用于排序)\n * 返回值: -1 (v1 < v2), 0 (v1 == v2), 1 (v1 > v2)\n */\n private compareVersionStrings(v1: string, v2: string): number {\n // 移除 'v' 前缀\n const version1 = v1.replace(/^v/, '');\n const version2 = v2.replace(/^v/, '');\n\n const parts1 = version1.split('.').map((p) => parseInt(p, 10) || 0);\n const parts2 = version2.split('.').map((p) => parseInt(p, 10) || 0);\n\n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const p1 = parts1[i] || 0;\n const p2 = parts2[i] || 0;\n\n if (p1 > p2) return 1;\n if (p1 < p2) return -1;\n }\n\n return 0;\n }\n\n /**\n * 获取最新的版本(优先 Tag,否则 latest commit)\n */\n async getLatestVersion(projectPath: string): Promise<{ type: 'tag' | 'commit'; name: string; commit: string } | null> {\n try {\n const tags = await this.listTags(projectPath);\n const branches = await this.listBranches(projectPath);\n\n // 优先返回最新的 tag\n if (tags.length > 0) {\n const latestTag = tags[0];\n return {\n type: 'tag',\n name: latestTag.name,\n commit: latestTag.commit.id,\n };\n }\n\n // 如果没有 tag,返回默认分支的最新 commit\n const defaultBranch = branches.find((b) => b.default);\n if (defaultBranch) {\n return {\n type: 'commit',\n name: defaultBranch.name,\n commit: defaultBranch.commit.id,\n };\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * 解析项目路径\n * 从 Git URL 中提取项目路径\n */\n static parseProjectPath(repository: string): string {\n // 支持的格式:\n // - git@gitlab.com:group/project.git\n // - https://gitlab.com/group/project.git\n // - gitlab.com/group/project\n\n let path = repository;\n\n // 处理 SSH URL 格式 (git@domain:group/project.git)\n if (path.startsWith('git@')) {\n path = path.replace(/^git@/, '');\n const colonIndex = path.indexOf(':');\n if (colonIndex !== -1) {\n path = path.substring(colonIndex + 1);\n }\n } else {\n // 移除 HTTPS 协议前缀\n path = path.replace(/^https?:\\/\\//, '');\n // 移除域名\n const parts = path.split('/');\n if (parts.length > 1) {\n path = parts.slice(1).join('/');\n }\n }\n\n // 移除 .git 后缀\n path = path.replace(/\\.git$/, '');\n\n return path;\n }\n\n /**\n * 编码项目路径用于 API 请求\n */\n private encodeProjectPath(projectPath: string): string {\n // GitLab API 需要对项目路径进行 URL 编码\n // 并且需要将 / 替换为 %2F\n return encodeURIComponent(projectPath).replace(/%2F/g, '%2F');\n }\n\n /**\n * 发送 HTTP 请求\n */\n private async request(endpoint: string, options: RequestInit = {}): Promise<Response> {\n const url = `${this.config.baseUrl}/api/v4${endpoint}`;\n\n const headers: HeadersInit = {\n 'PRIVATE-TOKEN': this.config.accessToken,\n 'Content-Type': 'application/json',\n ...options.headers,\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const response = await fetch(url, {\n ...options,\n headers,\n signal: controller.signal,\n });\n\n return response;\n } catch (error: any) {\n if (error.name === 'AbortError') {\n throw new Error('请求超时');\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * 获取默认分支\n */\n async getDefaultBranch(projectPath: string): Promise<string | null> {\n try {\n const project = await this.getProject(projectPath);\n return project?.default_branch || null;\n } catch {\n return null;\n }\n }\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport {\n checkTemplateUpdate,\n updateTemplateVersion,\n readTemplateConfig,\n type TemplateType,\n} from '../lib/template-version.js';\nimport { logger } from '../lib/logger.js';\nimport { FileUtils } from '../lib/utils.js';\nimport { execa } from 'execa';\nimport inquirer from 'inquirer';\nimport { Listr } from 'listr2';\nimport fs from 'fs-extra';\n\n/**\n * Update 命令选项接口\n */\ninterface UpdateOptions {\n tag?: string;\n branch?: string;\n dryRun?: boolean;\n}\n\n/**\n * Update 命令 - 检查并更新模板版本\n */\nexport const updateCommand = new Command('update')\n .description('检查并更新模板版本')\n .option('-f, --frontend', '检查前端模板更新')\n .option('-b, --backend', '检查后端模板更新')\n .option('-a, --all', '检查所有模板 (默认)')\n .option('-t, --tag <tag>', '更新到指定标签')\n .option('-B, --branch <branch>', '更新到指定分支')\n .option('--dry-run', '预览更新,不实际执行')\n .action(async (options) => {\n try {\n logger.header('模板版本检查');\n logger.newLine();\n\n // 检查是否在项目目录中\n const hasConfig = await FileUtils.exists('TECH_STACK.md');\n if (!hasConfig) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先切换到项目目录\");\n process.exit(1);\n }\n\n const projectPath = '.';\n const checkAll = !options.frontend && !options.backend;\n const checkFrontend = options.frontend || checkAll;\n const checkBackend = options.backend || checkAll;\n\n // 如果指定了 tag 或 branch,则强制更新到指定版本\n const forceUpdate = options.tag || options.branch;\n\n const updates: Array<{ type: TemplateType; info: any; updateOptions?: UpdateOptions }> = [];\n const updateOptions: UpdateOptions = {\n tag: options.tag,\n branch: options.branch,\n dryRun: options.dryRun,\n };\n\n // 检查前端模板\n if (checkFrontend) {\n logger.step('检查前端模板...');\n const frontendInfo = await checkTemplateUpdate(projectPath, 'frontend');\n\n if (frontendInfo) {\n if (frontendInfo.needsUpdate || forceUpdate) {\n const version = updateOptions.tag || updateOptions.branch || frontendInfo.latestTag || frontendInfo.latestCommit?.substring(0, 8);\n logger.success(`前端模板${forceUpdate ? '将更新' : '有更新'} (${version})`);\n updates.push({ type: 'frontend', info: frontendInfo, updateOptions });\n } else {\n logger.info('前端模板已是最新版本');\n }\n } else {\n logger.info('前端模板未配置或无法检查');\n }\n logger.newLine();\n }\n\n // 检查后端模板\n if (checkBackend) {\n logger.step('检查后端模板...');\n const backendInfo = await checkTemplateUpdate(projectPath, 'backend');\n\n if (backendInfo) {\n if (backendInfo.needsUpdate || forceUpdate) {\n const version = updateOptions.tag || updateOptions.branch || backendInfo.latestTag || backendInfo.latestCommit?.substring(0, 8);\n logger.success(`后端模板${forceUpdate ? '将更新' : '有更新'} (${version})`);\n updates.push({ type: 'backend', info: backendInfo, updateOptions });\n } else {\n logger.info('后端模板已是最新版本');\n }\n } else {\n logger.info('后端模板未配置或无法检查');\n }\n logger.newLine();\n }\n\n // 显示总结\n if (updates.length === 0) {\n logger.success('所有模板已是最新版本!');\n return;\n }\n\n if (options.dryRun) {\n logger.header(`[Dry Run] 发现 ${updates.length} 个模板`);\n } else {\n logger.header(`发现 ${updates.length} 个模板更新`);\n }\n logger.newLine();\n\n for (const update of updates) {\n const version = update.updateOptions?.tag || update.updateOptions?.branch || update.info.latestTag || update.info.latestCommit?.substring(0, 8);\n logger.step(`${update.type === 'frontend' ? '前端' : '后端'}模板: ${version}`);\n }\n logger.newLine();\n\n // 如果是 dry-run 模式,直接显示信息并退出\n if (options.dryRun) {\n logger.info('Dry run 模式,不执行实际更新');\n return;\n }\n\n // 询问是否更新\n const answers = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'shouldUpdate',\n message: '是否更新模板?',\n default: false,\n },\n ]);\n\n if (answers.shouldUpdate) {\n await performUpdate(projectPath, updates);\n } else {\n logger.info('已取消更新');\n }\n } catch (error: any) {\n logger.error(`更新检查失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 执行模板更新\n */\nasync function performUpdate(\n projectPath: string,\n updates: Array<{ type: TemplateType; info: any; updateOptions?: UpdateOptions }>\n): Promise<void> {\n logger.newLine();\n logger.info('开始更新模板...');\n\n for (const update of updates) {\n const { type, info, updateOptions } = update;\n const targetDir = type === 'frontend' ? 'frontend' : 'backend';\n const targetPath = path.join(projectPath, targetDir);\n\n logger.newLine();\n logger.step(`更新 ${type === 'frontend' ? '前端' : '后端'}模板...`);\n\n // 如果指定了 tag 或 branch,先验证\n if (updateOptions?.tag || updateOptions?.branch) {\n const { userConfigManager } = await import('../lib/user-config.js');\n const { GitLabAPI } = await import('../lib/gitlab-api.js');\n\n const config = await userConfigManager.getGitLabConfig();\n if (config) {\n const gitlabAPI = new GitLabAPI(config);\n const projectPathEncoded = GitLabAPI.parseProjectPath(info.repository);\n\n if (updateOptions.tag) {\n const isValid = await gitlabAPI.validateTag(projectPathEncoded, updateOptions.tag);\n if (!isValid) {\n logger.error(`${type === 'frontend' ? '前端' : '后端'}模板 tag \"${updateOptions.tag}\" 不存在`);\n continue;\n }\n logger.info(`使用 ${type === 'frontend' ? '前端' : '后端'}模板 tag: ${updateOptions.tag}`);\n }\n\n if (updateOptions.branch) {\n const isValid = await gitlabAPI.validateBranch(projectPathEncoded, updateOptions.branch);\n if (!isValid) {\n logger.error(`${type === 'frontend' ? '前端' : '后端'}模板分支 \"${updateOptions.branch}\" 不存在`);\n continue;\n }\n logger.info(`使用 ${type === 'frontend' ? '前端' : '后端'}模板分支: ${updateOptions.branch}`);\n }\n } else {\n logger.warn('未配置 GitLab Token,跳过版本验证');\n }\n }\n\n // 确定要克隆的 ref\n const ref = updateOptions?.tag || updateOptions?.branch || 'HEAD';\n\n // 创建备份\n const backupDir = path.join(projectPath, `.backup-${Date.now()}`);\n await fs.copy(targetPath, path.join(backupDir, targetDir));\n logger.info(`已创建备份: ${backupDir}`);\n\n // Dry run 模式\n if (updateOptions?.dryRun) {\n logger.info('[Dry Run] 将会更新到以下版本:');\n logger.info(` Ref: ${ref}`);\n logger.info(` 仓库: ${info.repository}`);\n logger.info('备份已创建,跳过实际更新');\n continue;\n }\n\n try {\n // 克隆最新模板到临时目录\n const tempDir = path.join(projectPath, `.template-update-${Date.now()}`);\n\n await execa('git', ['clone', '--depth=1', '--branch', ref, info.repository, tempDir], {\n stdio: 'pipe',\n });\n\n // 获取最新 commit\n const { stdout: commit } = await execa('git', ['rev-parse', 'HEAD'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n\n // 获取最新 tag\n const { stdout: tags } = await execa('git', ['tag', '-l', '--sort=-v:refname'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n const latestTag = tags.split('\\n')[0] || undefined;\n\n // 删除旧内容(保留配置文件)\n const keepFiles = ['.env.local', 'package-lock.json', 'node_modules'];\n const currentFiles = await FileUtils.findFiles('*', targetPath);\n\n for (const file of currentFiles) {\n if (!keepFiles.includes(file)) {\n const filePath = path.join(targetPath, file);\n try {\n await fs.remove(filePath);\n } catch {\n // 忽略删除失败\n }\n }\n }\n\n // 复制新模板内容\n await fs.copy(tempDir, targetPath, {\n filter: (src) => !src.includes('.git'),\n });\n\n // 删除临时目录\n await fs.remove(tempDir);\n\n // 更新配置\n await updateTemplateVersion(projectPath, type, commit.trim(), {\n tag: updateOptions?.tag || latestTag,\n branch: updateOptions?.branch,\n });\n\n logger.success(`${type === 'frontend' ? '前端' : '后端'}模板更新完成!`);\n logger.info(`新版本: ${updateOptions?.tag || updateOptions?.branch || latestTag || commit.substring(0, 8)}`);\n logger.info(`备份位置: ${backupDir}`);\n } catch (error: any) {\n logger.error(`更新失败: ${error.message}`);\n logger.info('正在恢复备份...');\n\n // 恢复备份\n await fs.remove(targetPath);\n await fs.copy(path.join(backupDir, targetDir), targetPath);\n await fs.remove(backupDir);\n\n logger.info('已恢复到更新前的状态');\n }\n }\n\n logger.newLine();\n logger.header('模板更新完成!');\n logger.newLine();\n logger.info('下一步:');\n logger.step('1. 检查更新后的代码');\n logger.step('2. 运行 npm install 安装新依赖');\n logger.step('3. 测试应用是否正常运行');\n logger.step('4. 提交代码到 Git');\n logger.newLine();\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport { userConfigManager } from '../lib/user-config.js';\nimport { GitLabAPI } from '../lib/gitlab-api.js';\nimport { logger } from '../lib/logger.js';\n\n/**\n * 设置 GitLab Access Token\n */\nexport const setTokenCommand = new Command('set-token')\n .description('设置 GitLab Access Token')\n .option('-t, --token <token>', 'Access Token')\n .option('-u, --url <url>', 'GitLab Base URL', 'https://gitlab.com')\n .action(async (options) => {\n try {\n logger.header('GitLab Access Token 配置');\n logger.newLine();\n\n let { token, url } = options;\n\n // 如果没有提供 token,交互式输入\n if (!token) {\n const answers = await inquirer.prompt([\n {\n type: 'password',\n name: 'token',\n message: '请输入 GitLab Access Token:',\n mask: '*',\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return 'Token 不能为空';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'url',\n message: '请输入 GitLab Base URL:',\n default: 'https://gitlab.com',\n validate: (input: string) => {\n try {\n new URL(input);\n return true;\n } catch {\n return '请输入有效的 URL';\n }\n },\n },\n ]);\n token = answers.token;\n url = answers.url;\n }\n\n // 验证 URL 格式\n try {\n new URL(url);\n } catch {\n logger.error('无效的 GitLab URL');\n process.exit(1);\n }\n\n // 移除 URL 末尾的斜杠\n url = url.replace(/\\/+$/, '');\n\n logger.info('验证 Token...');\n const gitlabAPI = new GitLabAPI({ accessToken: token, baseUrl: url });\n const isValid = await gitlabAPI.authenticate();\n\n if (!isValid) {\n logger.error('Token 验证失败,请检查:');\n logger.info('1. Token 是否正确');\n logger.info('2. Token 是否有 api 权限');\n logger.info('3. GitLab URL 是否正确');\n process.exit(1);\n }\n\n logger.success('Token 验证成功!');\n\n // 保存配置\n await userConfigManager.updateGitLabToken(token, url);\n logger.success('配置已保存!');\n logger.newLine();\n logger.info(`GitLab URL: ${chalk.cyan(url)}`);\n logger.info(`配置文件: ${chalk.gray(userConfigManager.getConfigPath())}`);\n } catch (error: any) {\n logger.error(`配置失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 显示当前配置\n */\nexport const showConfigCommand = new Command('show')\n .description('显示当前配置')\n .action(async () => {\n try {\n logger.header('GitLab 配置');\n logger.newLine();\n\n const hasConfig = await userConfigManager.hasConfig();\n\n if (!hasConfig) {\n logger.warn('未配置 GitLab Access Token');\n logger.info(\"请使用 'team-cli config set-token' 进行配置\");\n } else {\n const config = await userConfigManager.load();\n\n if (config?.gitlab) {\n const token = config.gitlab.accessToken;\n const maskedToken = token ? `${token.substring(0, 8)}${'*'.repeat(Math.min(16, token.length - 8))}` : '';\n\n logger.info(`GitLab URL: ${chalk.cyan(config.gitlab.baseUrl)}`);\n logger.info(`Access Token: ${chalk.yellow(maskedToken)}`);\n logger.info(`Timeout: ${chalk.gray(config.gitlab.timeout || 30000)}ms`);\n\n if (config.preferences) {\n logger.newLine();\n logger.info('偏好设置:');\n if (config.preferences.defaultBackendBranch) {\n logger.info(` 默认后端分支: ${chalk.cyan(config.preferences.defaultBackendBranch)}`);\n }\n if (config.preferences.defaultFrontendBranch) {\n logger.info(` 默认前端分支: ${chalk.cyan(config.preferences.defaultFrontendBranch)}`);\n }\n }\n\n logger.newLine();\n logger.info('配置文件位置:');\n logger.info(` ${chalk.gray(userConfigManager.getConfigPath())}`);\n }\n }\n } catch (error: any) {\n logger.error(`读取配置失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 删除配置\n */\nexport const removeConfigCommand = new Command('remove')\n .alias('rm')\n .description('删除 GitLab 配置')\n .action(async () => {\n try {\n const hasConfig = await userConfigManager.hasConfig();\n\n if (!hasConfig) {\n logger.warn('未配置 GitLab Access Token');\n return;\n }\n\n const answers = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: '确定要删除 GitLab 配置吗?',\n default: false,\n },\n ]);\n\n if (!answers.confirm) {\n logger.info('已取消');\n return;\n }\n\n await userConfigManager.removeConfig();\n logger.success('配置已删除');\n } catch (error: any) {\n logger.error(`删除配置失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 验证 Token\n */\nexport const validateTokenCommand = new Command('validate')\n .alias('test')\n .description('验证当前 Token 是否有效')\n .action(async () => {\n try {\n logger.header('验证 GitLab Token');\n logger.newLine();\n\n const config = await userConfigManager.getGitLabConfig();\n\n if (!config) {\n logger.warn('未配置 GitLab Access Token');\n logger.info(\"请使用 'team-cli config set-token' 进行配置\");\n process.exit(1);\n }\n\n logger.info('正在验证...');\n\n const gitlabAPI = new GitLabAPI(config);\n const isValid = await gitlabAPI.authenticate();\n\n if (isValid) {\n logger.success('Token 有效!');\n logger.newLine();\n logger.info(`GitLab URL: ${chalk.cyan(config.baseUrl)}`);\n } else {\n logger.error('Token 验证失败');\n logger.info('请检查 Token 是否正确或已过期');\n process.exit(1);\n }\n } catch (error: any) {\n logger.error(`验证失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * Config 命令 - 管理 GitLab 配置\n */\nexport const configCommand = new Command('config')\n .description('管理 GitLab 配置')\n .addCommand(setTokenCommand)\n .addCommand(showConfigCommand)\n .addCommand(removeConfigCommand)\n .addCommand(validateTokenCommand);\n","import { Command } from 'commander';\nimport path from 'path';\nimport chalk from 'chalk';\nimport table from 'cli-table3';\nimport { readTemplateConfig, type TemplateType } from '../lib/template-version.js';\nimport { logger } from '../lib/logger.js';\nimport { FileUtils } from '../lib/utils.js';\nimport { userConfigManager } from '../lib/user-config.js';\nimport { GitLabAPI, GitLabDiffResult } from '../lib/gitlab-api.js';\n\n/**\n * Diff 命令 - 对比本地与远程模板差异\n */\nexport const diffCommand = new Command('diff')\n .description('对比本地与远程模板差异')\n .option('-f, --frontend', '对比前端模板')\n .option('-b, --backend', '对比后端模板')\n .option('-t, --tag <tag>', '指定远程标签')\n .option('-B, --branch <branch>', '指定远程分支')\n .option('-o, --output <format>', '输出格式 (table|json|diff)', 'table')\n .action(async (options) => {\n try {\n logger.header('模板版本对比');\n logger.newLine();\n\n // 检查是否在项目目录中\n const hasConfig = await FileUtils.exists('TECH_STACK.md');\n if (!hasConfig) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先切换到项目目录\");\n process.exit(1);\n }\n\n const projectPath = '.';\n const checkAll = !options.frontend && !options.backend;\n const checkFrontend = options.frontend || checkAll;\n const checkBackend = options.backend || checkAll;\n\n const config = await readTemplateConfig(projectPath);\n if (!config) {\n logger.error('未找到模板配置');\n process.exit(1);\n }\n\n const gitlabConfig = await userConfigManager.getGitLabConfig();\n if (!gitlabConfig) {\n logger.warn('未配置 GitLab Token');\n logger.info(\"请使用 'team-cli config set-token' 进行配置\");\n logger.info(\"将使用基本 git 命令进行对比\");\n }\n\n const results: Array<{\n type: TemplateType;\n local: any;\n remote: any;\n diff?: GitLabDiffResult;\n }> = [];\n\n // 对比前端模板\n if (checkFrontend && config.frontend) {\n const result = await compareTemplate(\n projectPath,\n 'frontend',\n config.frontend,\n options.tag,\n options.branch,\n gitlabConfig || undefined\n );\n if (result) {\n results.push(result);\n }\n }\n\n // 对比后端模板\n if (checkBackend && config.backend) {\n const result = await compareTemplate(\n projectPath,\n 'backend',\n config.backend,\n options.tag,\n options.branch,\n gitlabConfig || undefined\n );\n if (result) {\n results.push(result);\n }\n }\n\n if (results.length === 0) {\n logger.info('没有可对比的模板');\n return;\n }\n\n // 根据输出格式显示结果\n switch (options.output) {\n case 'json':\n outputJson(results);\n break;\n case 'diff':\n outputDiff(results);\n break;\n case 'table':\n default:\n outputTable(results);\n break;\n }\n } catch (error: any) {\n logger.error(`对比失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 对比模板版本\n */\nasync function compareTemplate(\n projectPath: string,\n type: TemplateType,\n localConfig: any,\n remoteTag?: string,\n remoteBranch?: string,\n gitlabConfig?: { accessToken: string; baseUrl: string; timeout?: number }\n): Promise<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult } | null> {\n try {\n logger.step(`对比${type === 'frontend' ? '前端' : '后端'}模板...`);\n\n const repository = localConfig.repository;\n const localCommit = localConfig.commit;\n const localTag = localConfig.tag;\n const localBranch = localConfig.branch;\n\n let remoteCommit: string | null = null;\n let remoteTagName: string | undefined;\n let remoteBranchName: string | undefined;\n\n // 如果有 GitLab 配置,使用 API 获取远程信息\n if (gitlabConfig) {\n const gitlabAPI = new GitLabAPI(gitlabConfig);\n const projectPathEncoded = GitLabAPI.parseProjectPath(repository);\n\n if (remoteTag) {\n // 获取指定 tag 的 commit\n remoteCommit = await gitlabAPI.getTagCommit(projectPathEncoded, remoteTag);\n remoteTagName = remoteTag;\n } else if (remoteBranch) {\n // 获取指定 branch 的 commit\n remoteCommit = await gitlabAPI.getBranchCommit(projectPathEncoded, remoteBranch);\n remoteBranchName = remoteBranch;\n } else {\n // 获取最新版本\n const latest = await gitlabAPI.getLatestVersion(projectPathEncoded);\n if (latest) {\n remoteCommit = latest.commit;\n if (latest.type === 'tag') {\n remoteTagName = latest.name;\n } else {\n remoteBranchName = latest.name;\n }\n }\n }\n\n // 获取 diff 信息\n if (remoteCommit && localCommit && remoteCommit !== localCommit) {\n const from = localTag || localBranch || localCommit;\n const to = remoteTagName || remoteBranchName || remoteCommit;\n const diff = await gitlabAPI.compareVersions(projectPathEncoded, from, to);\n\n return {\n type,\n local: {\n commit: localCommit,\n tag: localTag,\n branch: localBranch,\n },\n remote: {\n commit: remoteCommit,\n tag: remoteTagName,\n branch: remoteBranchName,\n },\n diff: diff || undefined,\n };\n }\n }\n\n // 如果没有 GitLab 配置,使用 git 命令获取基本信息\n if (!remoteCommit) {\n // 使用 git ls-remote 获取远程最新 commit\n const { execa } = await import('execa');\n const ref = remoteTag || remoteBranch || 'HEAD';\n const { stdout } = await execa('git', ['ls-remote', repository, ref], {\n stdio: 'pipe',\n });\n remoteCommit = stdout.split('\\t')[0];\n remoteTagName = remoteTag;\n remoteBranchName = remoteBranch;\n }\n\n const needsUpdate = localCommit !== remoteCommit;\n\n logger.info(\n `${type === 'frontend' ? '前端' : '后端'}模板: ${needsUpdate ? chalk.yellow('有更新') : chalk.green('已是最新')}`\n );\n\n return {\n type,\n local: {\n commit: localCommit,\n tag: localTag,\n branch: localBranch,\n },\n remote: {\n commit: remoteCommit || undefined,\n tag: remoteTagName,\n branch: remoteBranchName,\n },\n };\n } catch (error) {\n logger.error(`对比${type === 'frontend' ? '前端' : '后端'}模板失败: ${error}`);\n return null;\n }\n}\n\n/**\n * 输出表格格式\n */\nfunction outputTable(results: Array<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult }>): void {\n logger.newLine();\n\n for (const result of results) {\n const typeName = result.type === 'frontend' ? '前端' : '后端';\n console.log(chalk.bold(`${typeName}模板:`));\n console.log('');\n\n const t = new Table({\n head: [chalk.cyan('项目'), chalk.cyan('版本')],\n colWidths: [20, 50],\n });\n\n // 本地版本\n const localVersion = result.local.tag || result.local.branch || result.local.commit?.substring(0, 8) || '-';\n const localInfo = `Commit: ${result.local.commit?.substring(0, 8) || '-'}${result.local.tag ? `\\nTag: ${result.local.tag}` : ''}${result.local.branch ? `\\nBranch: ${result.local.branch}` : ''}`;\n t.push(['本地', localInfo]);\n\n // 远程版本\n const remoteVersion = result.remote.tag || result.remote.branch || result.remote.commit?.substring(0, 8) || '-';\n const remoteInfo = `Commit: ${result.remote.commit?.substring(0, 8) || '-'}${result.remote.tag ? `\\nTag: ${result.remote.tag}` : ''}${result.remote.branch ? `\\nBranch: ${result.remote.branch}` : ''}`;\n t.push(['远程', remoteInfo]);\n\n console.log(t.toString());\n\n // 显示 diff 信息\n if (result.diff && result.diff.commits.length > 0) {\n console.log('');\n console.log(chalk.bold('新增提交:'));\n\n const commitsTable = new Table({\n head: [chalk.cyan('Commit'), chalk.cyan('作者'), chalk.cyan('时间'), chalk.cyan('描述')],\n colWidths: [10, 15, 20, 50],\n wordWrap: true,\n });\n\n for (const commit of result.diff.commits.slice(0, 10)) {\n commitsTable.push([\n commit.short_id,\n commit.author_name,\n new Date(commit.created_at).toLocaleDateString('zh-CN'),\n commit.title,\n ]);\n }\n\n console.log(commitsTable.toString());\n\n if (result.diff.commits.length > 10) {\n console.log(chalk.gray(`... 还有 ${result.diff.commits.length - 10} 个提交`));\n }\n\n // 文件变更统计\n const files = result.diff.diffs;\n const added = files.filter((f) => f.new_file).length;\n const deleted = files.filter((f) => f.deleted_file).length;\n const modified = files.length - added - deleted;\n\n console.log('');\n console.log(chalk.bold('文件变更:'));\n console.log(` ${chalk.green('+')} 新增: ${added}`);\n console.log(` ${chalk.red('-')} 删除: ${deleted}`);\n console.log(` ${chalk.yellow('~')} 修改: ${modified}`);\n }\n\n console.log('');\n }\n}\n\n/**\n * 输出 JSON 格式\n */\nfunction outputJson(results: Array<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult }>): void {\n console.log(JSON.stringify(results, null, 2));\n}\n\n/**\n * 输出 diff 格式\n */\nfunction outputDiff(results: Array<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult }>): void {\n logger.newLine();\n\n for (const result of results) {\n const typeName = result.type === 'frontend' ? '前端' : '后端';\n console.log(chalk.bold(`${typeName}模板:`));\n console.log('');\n\n const from = result.local.tag || result.local.branch || result.local.commit?.substring(0, 8) || 'unknown';\n const to = result.remote.tag || result.remote.branch || result.remote.commit?.substring(0, 8) || 'unknown';\n\n console.log(`本地版本: ${chalk.cyan(from)}`);\n console.log(`远程版本: ${chalk.cyan(to)}`);\n\n if (result.diff && result.diff.commits.length > 0) {\n console.log('');\n console.log(chalk.bold('提交历史:'));\n\n for (const commit of result.diff.commits) {\n console.log('');\n console.log(chalk.yellow(`commit ${commit.id}`));\n console.log(`Author: ${commit.author_name} <${commit.author_email}>`);\n console.log(`Date: ${new Date(commit.created_at).toLocaleString('zh-CN')}`);\n console.log('');\n console.log(` ${commit.title}`);\n if (commit.message) {\n console.log(` ${commit.message.split('\\n').join('\\n ')}`);\n }\n }\n }\n\n console.log('');\n }\n}\n\n/**\n * 简单的 Table 类(如果 cli-table3 不可用)\n */\nclass Table {\n private options: any;\n private rows: any[][] = [];\n\n constructor(options: any) {\n this.options = options;\n }\n\n push(row: any[]): void {\n this.rows.push(row);\n }\n\n toString(): string {\n if (this.rows.length === 0) return '';\n\n let result = '';\n const colWidths = this.options.colWidths || [];\n\n // 表头\n if (this.options.head) {\n result += '| ';\n for (let i = 0; i < this.options.head.length; i++) {\n const width = colWidths[i] || 20;\n const cell = this.options.head[i] || '';\n result += cell.padEnd(width) + ' | ';\n }\n result += '\\n';\n\n // 分隔线\n result += '|';\n for (let i = 0; i < this.options.head.length; i++) {\n const width = colWidths[i] || 20;\n result += '-'.repeat(width + 2) + '|';\n }\n result += '\\n';\n }\n\n // 数据行\n for (const row of this.rows) {\n result += '| ';\n for (let i = 0; i < row.length; i++) {\n const width = colWidths[i] || 20;\n const cell = String(row[i] || '');\n const displayCell = this.options.wordWrap && cell.length > width ? cell.substring(0, width - 3) + '...' : cell;\n result += displayCell.padEnd(width) + ' | ';\n }\n result += '\\n';\n }\n\n return result;\n }\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { logger } from './lib/logger.js';\nimport { initCommand } from './commands/init.js';\nimport { breakdownCommand } from './commands/breakdown.js';\nimport { devCommand } from './commands/dev.js';\nimport { addFeatureCommand } from './commands/add-feature.js';\nimport { splitPrdCommand } from './commands/split-prd.js';\nimport { bugfixCommand } from './commands/bugfix.js';\nimport { hotfixCommand } from './commands/bugfix.js';\nimport { acceptCommand } from './commands/accept.js';\nimport { addModuleCommand } from './commands/add-module.js';\nimport { lintCommand } from './commands/lint.js';\nimport { statusCommand } from './commands/status.js';\nimport { detectDepsCommand } from './commands/detect-deps.js';\nimport { syncMemoryCommand } from './commands/sync-memory.js';\nimport { checkApiCommand } from './commands/check-api.js';\nimport { logsCommand } from './commands/logs.js';\nimport { updateCommand } from './commands/update.js';\nimport { configCommand } from './commands/config.js';\nimport { diffCommand } from './commands/diff.js';\n\n/**\n * team-cli - AI-Native 团队研发脚手架\n * Node.js 版本\n */\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst pkg = fs.readJsonSync(path.join(__dirname, '../package.json'));\n\nconst program = new Command();\n\n// 基本信息\nprogram\n .name('team-cli')\n .description('AI-Native 团队研发脚手架')\n .version(pkg.version);\n\n// 全局选项\nprogram.option('-v, --verbose', '详细输出模式').option('--debug', '调试模式');\n\n// 注册命令\nprogram.addCommand(initCommand);\nprogram.addCommand(splitPrdCommand);\nprogram.addCommand(breakdownCommand);\nprogram.addCommand(devCommand);\nprogram.addCommand(addFeatureCommand);\nprogram.addCommand(bugfixCommand);\nprogram.addCommand(hotfixCommand);\nprogram.addCommand(acceptCommand);\nprogram.addCommand(addModuleCommand);\nprogram.addCommand(lintCommand);\nprogram.addCommand(statusCommand);\nprogram.addCommand(detectDepsCommand);\nprogram.addCommand(syncMemoryCommand);\nprogram.addCommand(checkApiCommand);\nprogram.addCommand(logsCommand);\nprogram.addCommand(updateCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(diffCommand);\n\n// 默认显示帮助\nprogram.action(() => {\n showHelp();\n});\n\n/**\n * 显示帮助信息\n */\nfunction showHelp() {\n console.log('');\n logger.header('team-cli - AI-Native 团队研发脚手架');\n console.log('');\n console.log(chalk.bold('使用方法:'));\n console.log(' team-cli init [project-name] 初始化新项目');\n console.log(' team-cli split-prd <prd-folder> 将 PRD 拆分成多个 specs');\n console.log(' team-cli breakdown [spec-file] 将 spec 拆分为 milestones 和 todos');\n console.log(' team-cli dev 开发模式,执行具体任务');\n console.log(' team-cli accept [spec-file] 验收功能,走查所有需求');\n console.log(' team-cli add-module 为已有项目新增模块');\n console.log(' team-cli add-feature <name> 添加新功能');\n console.log(' team-cli bugfix 创建 Bugfix 记录');\n console.log(' team-cli hotfix 创建 Hotfix');\n console.log(' team-cli detect-deps [spec] 检测依赖关系');\n console.log(' team-cli sync-memory 同步 AI_MEMORY.md');\n console.log(' team-cli check-api API 检查(冲突/变更/Registry)');\n console.log(' team-cli status 查看项目状态');\n console.log(' team-cli lint 代码质量检查 (前端+后端)');\n console.log(' team-cli logs [date] 查看会话日志');\n console.log(' team-cli update 检查并更新模板版本');\n console.log(' team-cli config 管理 GitLab 配置');\n console.log(' team-cli diff 对比本地与远程模板差异');\n console.log(' team-cli --help 显示帮助信息');\n console.log('');\n console.log(chalk.bold('示例:'));\n console.log(' team-cli init my-project');\n console.log(' cd my-project');\n console.log(' team-cli add-feature payment-system');\n console.log(' team-cli breakdown docs/specs/xxx.md');\n console.log(' team-cli dev');\n console.log('');\n console.log(chalk.bold('开发流程:'));\n console.log(' 1. PRD → specs (split-prd)');\n console.log(' 2. spec → milestones + todos (breakdown)');\n console.log(' 3. 选择 milestone/todo → 实现 (dev)');\n console.log(' 4. 验收 (accept) → 验证联调是否完成');\n console.log('');\n console.log(chalk.bold('迭代流程:'));\n console.log(' team-cli add-feature <name> # 添加新功能');\n console.log(' team-cli detect-deps [spec] # 检测依赖关系');\n console.log(' team-cli sync-memory # 同步 AI_MEMORY');\n console.log(' team-cli check-api # API 检查');\n console.log(' team-cli bugfix # 创建 bugfix');\n console.log(' team-cli hotfix # 紧急修复');\n console.log(' team-cli status # 查看项目状态');\n console.log('');\n console.log(chalk.bold('模板管理:'));\n console.log(' team-cli config set-token # 设置 GitLab Access Token');\n console.log(' team-cli config show # 显示当前配置');\n console.log(' team-cli init --tag v1.0.0 # 使用指定 tag 初始化');\n console.log(' team-cli update --tag v1.1.0 # 更新到指定版本');\n console.log(' team-cli diff # 对比模板差异');\n console.log('');\n console.log(chalk.gray('更多信息: https://github.com/yungu/team-cli'));\n console.log('');\n}\n\n/**\n * 错误处理\n */\nprocess.on('uncaughtException', (error) => {\n logger.error('未捕获的异常');\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n});\n\nprocess.on('unhandledRejection', (reason) => {\n logger.error('未处理的 Promise 拒绝');\n if (process.env.DEBUG) {\n console.error(reason);\n }\n process.exit(1);\n});\n\n// 解析命令行参数\nprogram.parse(process.argv);\n","#!/usr/bin/env node\n// CLI 入口文件\nimport('./index.js').catch((error) => {\n console.error('Failed to start team-cli:', error);\n process.exit(1);\n});\n"],"mappings":"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","names":["path","execa","path","fs","execa","path","path","path","fs","os","Command","inquirer","path","Listr","Command","inquirer","path","todo","Command","inquirer","path","Listr","Command","path","Listr","Command","inquirer","path","Listr","execa","Command","inquirer","path","selectSpec","exists","selectMilestone","Command","inquirer","path","fs","createApplicationClass","createModuleBuildGradle","toPascalCase","Command","execa","Command","path","Command","path","inquirer","Command","path","Command","path","inquirer","Listr","controllers","extractMethodComment","Command","path","inquirer","path","os","path","Command","path","execa","inquirer","fs","userConfigManager","GitLabAPI","Command","inquirer","chalk","Command","chalk","execa","Command","chalk","fs","path","fileURLToPath","__dirname"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/lib/logger.ts","../src/lib/utils.ts","../src/lib/claude.ts","../src/lib/template-version.ts","../src/lib/module-registry.ts","../src/commands/init.ts","../src/commands/breakdown.ts","../src/commands/dev.ts","../src/commands/add-feature.ts","../src/commands/split-prd.ts","../src/commands/bugfix.ts","../src/lib/bdd-parser.ts","../src/commands/accept.ts","../src/commands/add-module.ts","../src/commands/lint.ts","../src/commands/status.ts","../src/commands/detect-deps.ts","../src/commands/sync-memory.ts","../src/commands/check-api.ts","../src/commands/logs.ts","../src/lib/user-config.ts","../src/lib/gitlab-api.ts","../src/commands/update.ts","../src/commands/config.ts","../src/commands/diff.ts","../src/index.ts","../src/cli.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import chalk from 'chalk';\nimport ora, { Ora } from 'ora';\n\n/**\n * 颜色输出类\n */\nexport class Logger {\n private spinner: Ora | null = null;\n\n /**\n * 打印标题(加粗)\n */\n header(text: string): void {\n console.log(chalk.bold(text));\n }\n\n /**\n * 打印成功信息(绿色)\n */\n success(text: string): void {\n console.log(chalk.green('✓'), text);\n }\n\n /**\n * 打印错误信息(红色)\n */\n error(text: string): void {\n console.error(chalk.red('✗'), text);\n }\n\n /**\n * 打印警告信息(黄色)\n */\n warn(text: string): void {\n console.warn(chalk.yellow('⚠'), text);\n }\n\n /**\n * 打印信息(蓝色)\n */\n info(text: string): void {\n console.info(chalk.blue('ℹ'), text);\n }\n\n /**\n * 打印步骤信息\n */\n step(text: string): void {\n console.log(chalk.cyan('→'), text);\n }\n\n /**\n * 打印空行\n */\n newLine(): void {\n console.log('');\n }\n\n /**\n * 打印分隔线\n */\n separator(char = '─', length = 50): void {\n console.log(chalk.gray(char.repeat(length)));\n }\n\n /**\n * 开始加载动画\n */\n startLoading(text: string): Ora {\n this.spinner = ora({\n text,\n color: 'cyan',\n }).start();\n return this.spinner;\n }\n\n /**\n * 更新加载文本\n */\n updateLoading(text: string): void {\n if (this.spinner) {\n this.spinner.text = text;\n }\n }\n\n /**\n * 停止加载并显示成功\n */\n succeedLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.succeed(text);\n this.spinner = null;\n }\n }\n\n /**\n * 停止加载并显示失败\n */\n failLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.fail(text);\n this.spinner = null;\n }\n }\n\n /**\n * 停止加载并显示警告\n */\n warnLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.warn(text);\n this.spinner = null;\n }\n }\n\n /**\n * 停止加载并显示信息\n */\n infoLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.info(text);\n this.spinner = null;\n }\n }\n\n /**\n * 打印表格\n */\n table(headers: string[], rows: string[][]): void {\n const columnWidths = headers.map((h, i) => {\n const maxWidth = Math.max(\n h.length,\n ...rows.map((row) => (row[i] || '').length)\n );\n return maxWidth + 2;\n });\n\n // 打印表头\n const headerRow = headers\n .map((h, i) => chalk.bold(h.padEnd(columnWidths[i])))\n .join('');\n console.log(headerRow);\n\n // 打印分隔线\n const separator = columnWidths.map((w) => '─'.repeat(w)).join('┼');\n console.log(chalk.gray(separator));\n\n // 打印数据行\n rows.forEach((row) => {\n const dataRow = row\n .map((cell, i) => (cell || '').padEnd(columnWidths[i]))\n .join('');\n console.log(dataRow);\n });\n }\n\n /**\n * 打印代码块\n */\n code(code: string, language = ''): void {\n if (language) {\n console.log(chalk.gray(`\\`\\`\\`${language}`));\n }\n console.log(chalk.gray(code));\n if (language) {\n console.log(chalk.gray('```'));\n }\n }\n\n /**\n * 打印列表\n */\n list(items: string[], indent = 2): void {\n items.forEach((item) => {\n console.log(' '.repeat(indent) + chalk.gray('•') + ' ' + item);\n });\n }\n\n /**\n * 打印带标签的文本\n */\n labeled(label: string, text: string, labelColor = 'blue'): void {\n const coloredLabel = chalk[labelColor as keyof typeof chalk](`[${label}]`);\n console.log(`${coloredLabel} ${text}`);\n }\n\n /**\n * 打印调试信息(灰色,仅在 DEBUG 模式下显示)\n */\n debug(text: string): void {\n if (process.env.DEBUG) {\n console.debug(chalk.gray(`[DEBUG] ${text}`));\n }\n }\n}\n\n// 导出单例\nexport const logger = new Logger();\n\n/**\n * 确认提示(用于重要操作)\n */\nexport async function confirm(message: string): Promise<boolean> {\n const inquirer = await import('inquirer');\n const { confirm } = await inquirer.default.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message,\n default: false,\n },\n ]);\n return confirm;\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { glob } from 'glob';\nimport type { Spec } from '../types/index.js';\n\n/**\n * 文件工具类\n */\nexport class FileUtils {\n /**\n * 确保目录存在\n */\n static async ensureDir(dir: string): Promise<void> {\n await fs.ensureDir(dir);\n }\n\n /**\n * 读取文件内容\n */\n static async read(file: string): Promise<string> {\n return await fs.readFile(file, 'utf-8');\n }\n\n /**\n * 同步读取文件内容\n */\n static readSync(file: string): string {\n return fs.readFileSync(file, 'utf-8');\n }\n\n /**\n * 写入文件内容(自动创建父目录)\n */\n static async write(file: string, content: string): Promise<void> {\n const dir = path.dirname(file);\n await fs.ensureDir(dir);\n await fs.writeFile(file, content, 'utf-8');\n }\n\n /**\n * 检查文件是否存在\n */\n static async exists(file: string): Promise<boolean> {\n return await fs.pathExists(file);\n }\n\n /**\n * 复制文件\n */\n static async copy(src: string, dest: string): Promise<void> {\n await fs.copy(src, dest);\n }\n\n /**\n * 删除文件或目录\n */\n static async remove(file: string): Promise<void> {\n await fs.remove(file);\n }\n\n /**\n * 移动文件\n */\n static async move(src: string, dest: string): Promise<void> {\n await fs.move(src, dest);\n }\n\n /**\n * 使用 glob 查找文件\n */\n static async findFiles(pattern: string, cwd?: string): Promise<string[]> {\n return await glob(pattern, {\n cwd,\n absolute: false,\n nodir: true,\n });\n }\n\n /**\n * 读取 JSON 文件\n */\n static async readJson<T = any>(file: string): Promise<T> {\n return await fs.readJson(file);\n }\n\n /**\n * 写入 JSON 文件\n */\n static async writeJson(file: string, data: any): Promise<void> {\n await fs.writeJson(file, data, { spaces: 2 });\n }\n\n /**\n * 获取路径的目录名 (ESM 兼容)\n */\n static getDirName(url: string): string {\n return path.dirname(new URL(url).pathname);\n }\n}\n\n/**\n * 字符串工具类\n */\nexport class StringUtils {\n /**\n * 转换为 kebab-case\n */\n static toKebabCase(str: string): string {\n return str\n .toLowerCase()\n .replace(/[\\s_]+/g, '-')\n .replace(/[^\\w\\-]/g, '')\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '');\n }\n\n /**\n * 转换为 PascalCase\n */\n static toPascalCase(str: string): string {\n return str\n .replace(/[-_\\s](\\w)/g, (_, c) => c.toUpperCase())\n .replace(/^\\w/, (c) => c.toUpperCase());\n }\n\n /**\n * 转换为 camelCase\n */\n static toCamelCase(str: string): string {\n const pascal = this.toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n }\n\n /**\n * 转换为 snake_case\n */\n static toSnakeCase(str: string): string {\n return str\n .replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)\n .replace(/^_/, '')\n .replace(/-+/g, '_')\n .replace(/[\\s]+/g, '_');\n }\n\n /**\n * 首字母大写\n */\n static capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n }\n\n /**\n * 截断字符串\n */\n static truncate(str: string, length: number, suffix = '...'): string {\n if (str.length <= length) return str;\n return str.slice(0, length - suffix.length) + suffix;\n }\n\n /**\n * 生成 slug\n */\n static slugify(str: string): string {\n return str\n .toLowerCase()\n .trim()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/[\\s_-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n }\n\n /**\n * 验证项目名称\n */\n static validateProjectName(name: string): boolean {\n return /^[a-z0-9-]+$/.test(name);\n }\n}\n\n/**\n * 数组工具类\n */\nexport class ArrayUtils {\n /**\n * 数组去重\n */\n static unique<T>(arr: T[]): T[] {\n return Array.from(new Set(arr));\n }\n\n /**\n * 数组分组\n */\n static groupBy<T>(arr: T[], keyFn: (item: T) => string): Record<string, T[]> {\n return arr.reduce((result, item) => {\n const key = keyFn(item);\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(item);\n return result;\n }, {} as Record<string, T[]>);\n }\n\n /**\n * 数组分块\n */\n static chunk<T>(arr: T[], size: number): T[][] {\n const chunks: T[][] = [];\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size));\n }\n return chunks;\n }\n\n /**\n * 数组乱序\n */\n static shuffle<T>(arr: T[]): T[] {\n const result = [...arr];\n for (let i = result.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [result[i], result[j]] = [result[j], result[i]];\n }\n return result;\n }\n}\n\n/**\n * 日期工具类\n */\nexport class DateUtils {\n /**\n * 格式化日期\n */\n static format(date: Date = new Date(), format = 'YYYY-MM-DD HH:mm:ss'): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n const seconds = String(date.getSeconds()).padStart(2, '0');\n\n return format\n .replace('YYYY', String(year))\n .replace('MM', month)\n .replace('DD', day)\n .replace('HH', hours)\n .replace('mm', minutes)\n .replace('ss', seconds);\n }\n\n /**\n * 获取相对时间\n */\n static relative(date: Date): string {\n const now = new Date();\n const diff = now.getTime() - date.getTime();\n const seconds = Math.floor(diff / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (days > 7) {\n return DateUtils.format(date, 'YYYY-MM-DD');\n } else if (days > 0) {\n return `${days} 天前`;\n } else if (hours > 0) {\n return `${hours} 小时前`;\n } else if (minutes > 0) {\n return `${minutes} 分钟前`;\n } else {\n return '刚刚';\n }\n }\n}\n\n/**\n * Milestone 信息接口\n */\nexport interface MilestoneInfo {\n title: string;\n todos: string[];\n completedCount: number;\n}\n\n/**\n * Todo 项接口(增强版 - 支持前后端分类)\n */\nexport interface TodoItem {\n raw: string; // 原始文本\n content: string; // 任务内容\n type: 'frontend' | 'backend' | 'integration' | 'general'; // 任务类型\n apiAssociation?: string; // API 关联 (后端任务)\n dependencies?: string[]; // 依赖关系 (联调任务)\n isCompleted: boolean; // 是否完成\n}\n\n/**\n * 增强版 Milestone 信息\n */\nexport interface EnhancedMilestoneInfo {\n title: string;\n todos: TodoItem[];\n frontendTodos: TodoItem[];\n backendTodos: TodoItem[];\n integrationTodos: TodoItem[];\n generalTodos: TodoItem[];\n completedCount: number;\n totalCount: number;\n}\n\n/**\n * Git 工具类\n */\nexport class GitUtils {\n /**\n * 检查是否在 Git 仓库中\n */\n static async isGitRepo(cwd: string = process.cwd()): Promise<boolean> {\n const gitDir = path.join(cwd, '.git');\n return await FileUtils.exists(gitDir);\n }\n\n /**\n * 获取当前分支名\n */\n static async getCurrentBranch(cwd: string = process.cwd()): Promise<string> {\n const { execa } = await import('execa');\n const { stdout } = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {\n cwd,\n });\n return stdout.trim();\n }\n\n /**\n * 获取当前 commit hash\n */\n static async getCurrentCommit(cwd: string = process.cwd()): Promise<string> {\n const { execa } = await import('execa');\n const { stdout } = await execa('git', ['rev-parse', 'HEAD'], { cwd });\n return stdout.trim().slice(0, 7);\n }\n}\n\n/**\n * Spec 解析工具类\n */\nexport class SpecUtils {\n /**\n * 解析 spec 文件\n */\n static async parseSpec(file: string): Promise<Partial<Spec>> {\n const content = await FileUtils.read(file);\n const spec: Partial<Spec> = {};\n\n // 解析标题\n const titleMatch = content.match(/^#\\s+(.+)$/m);\n if (titleMatch) {\n spec.title = titleMatch[1];\n }\n\n // 解析功能名称\n const nameMatch = content.match(/\\*\\*功能名称\\*\\*:\\s*(.+)$/m);\n if (nameMatch) {\n spec.name = nameMatch[1];\n }\n\n // 解析优先级\n const priorityMatch = content.match(/\\*\\*优先级\\*\\*:\\s*(P[0-2])/);\n if (priorityMatch) {\n spec.priority = priorityMatch[1] as 'P0' | 'P1' | 'P2';\n }\n\n // 解析状态\n const statusMatch = content.match(/\\*\\*状态\\*\\*:\\s*(.+)$/m);\n if (statusMatch) {\n spec.status = statusMatch[1] as Spec['status'];\n }\n\n // 解析依赖\n const depSection = content.match(/## 依赖关系\\s+([\\s\\S]+?)##/m);\n if (depSection) {\n const depMatches = depSection[1].matchAll(/- \\[([ x])\\]\\s*(.+)$/gm);\n spec.dependencies = Array.from(depMatches).map((m) => ({\n completed: m[1] === 'x',\n name: m[2],\n }));\n }\n\n return spec;\n }\n\n /**\n * 解析里程碑信息\n */\n static parseMilestones(content: string): MilestoneInfo[] {\n const milestones: MilestoneInfo[] = [];\n const lines = content.split('\\n');\n let currentMilestone: MilestoneInfo | null = null;\n let inMilestone = false;\n\n for (const line of lines) {\n if (line.match(/^###\\s+Milestone\\s+\\d+:/)) {\n if (currentMilestone) {\n milestones.push(currentMilestone);\n }\n const title = line.replace(/^###\\s+/, '').trim();\n currentMilestone = { title, todos: [], completedCount: 0 };\n inMilestone = true;\n continue;\n }\n\n if (inMilestone && currentMilestone) {\n if (line.match(/^###\\s+Milestone/)) {\n milestones.push(currentMilestone);\n currentMilestone = null;\n continue;\n }\n\n const todoMatch = line.match(/^-\\s+\\[([ xX])\\]\\s*(.+)/);\n if (todoMatch) {\n const isCompleted = todoMatch[1].toLowerCase() === 'x';\n if (isCompleted) {\n currentMilestone.completedCount++;\n }\n currentMilestone.todos.push(todoMatch[2].trim());\n }\n }\n }\n\n if (currentMilestone) {\n milestones.push(currentMilestone);\n }\n\n return milestones;\n }\n\n /**\n * 解析增强版里程碑信息(支持 [F]/[B]/[I] 前缀分类)\n */\n static parseMilestonesEnhanced(content: string): EnhancedMilestoneInfo[] {\n const milestones: EnhancedMilestoneInfo[] = [];\n const lines = content.split('\\n');\n let currentMilestone: EnhancedMilestoneInfo | null = null;\n let inMilestone = false;\n\n for (const line of lines) {\n if (line.match(/^###\\s+Milestone\\s+\\d+:/)) {\n if (currentMilestone) {\n currentMilestone.totalCount = currentMilestone.todos.length;\n milestones.push(currentMilestone);\n }\n const title = line.replace(/^###\\s+/, '').trim();\n currentMilestone = {\n title,\n todos: [],\n frontendTodos: [],\n backendTodos: [],\n integrationTodos: [],\n generalTodos: [],\n completedCount: 0,\n totalCount: 0,\n };\n inMilestone = true;\n continue;\n }\n\n if (inMilestone && currentMilestone) {\n if (line.match(/^###\\s+Milestone/)) {\n currentMilestone.totalCount = currentMilestone.todos.length;\n milestones.push(currentMilestone);\n currentMilestone = null;\n const title = line.replace(/^###\\s+/, '').trim();\n currentMilestone = {\n title,\n todos: [],\n frontendTodos: [],\n backendTodos: [],\n integrationTodos: [],\n generalTodos: [],\n completedCount: 0,\n totalCount: 0,\n };\n continue;\n }\n\n const todoMatch = line.match(/^-\\s+\\[([ xX])\\]\\s*(\\[[FBIN]\\])?\\s*(.+)/);\n if (todoMatch) {\n const isCompleted = todoMatch[1].toLowerCase() === 'x';\n const prefix = todoMatch[2]?.trim() || '';\n const rawContent = todoMatch[3].trim();\n\n let type: TodoItem['type'] = 'general';\n let apiAssociation: string | undefined;\n let dependencies: string[] | undefined;\n\n // 解析前缀确定任务类型\n if (prefix === '[F]') {\n type = 'frontend';\n } else if (prefix === '[B]') {\n type = 'backend';\n // 解析 API 关联\n const apiMatch = rawContent.match(/\\(关联 API:\\s*`([^`]+)`\\)/);\n if (apiMatch) {\n apiAssociation = apiMatch[1];\n }\n } else if (prefix === '[I]') {\n type = 'integration';\n // 解析依赖关系\n const depMatch = rawContent.match(/\\(依赖:\\s*([^)]+)\\)/);\n if (depMatch) {\n dependencies = depMatch[1]\n .split(',')\n .map((d) => d.trim())\n .filter((d) => d.length > 0);\n }\n }\n\n const todoItem: TodoItem = {\n raw: line.trim(),\n content: rawContent\n .replace(/\\s*\\(关联 API:\\s*`[^`]+`\\)/, '')\n .replace(/\\s*\\(依赖:\\s*[^)]+\\)/, '')\n .trim(),\n type,\n apiAssociation,\n dependencies,\n isCompleted,\n };\n\n currentMilestone.todos.push(todoItem);\n if (isCompleted) {\n currentMilestone.completedCount++;\n }\n\n // 按类型分类\n switch (type) {\n case 'frontend':\n currentMilestone.frontendTodos.push(todoItem);\n break;\n case 'backend':\n currentMilestone.backendTodos.push(todoItem);\n break;\n case 'integration':\n currentMilestone.integrationTodos.push(todoItem);\n break;\n default:\n currentMilestone.generalTodos.push(todoItem);\n }\n }\n }\n }\n\n if (currentMilestone) {\n currentMilestone.totalCount = currentMilestone.todos.length;\n milestones.push(currentMilestone);\n }\n\n return milestones;\n }\n\n /**\n * 解析增强版里程碑(向后兼容版 - 优先尝试增强解析,失败回退到简单解析)\n */\n static parseMilestonesEnhancedWithFallback(content: string): {\n enhanced: EnhancedMilestoneInfo[];\n isEnhanced: boolean;\n } {\n const enhanced = this.parseMilestonesEnhanced(content);\n // 检查是否包含增强格式的任务\n const hasEnhancedFormat = enhanced.some((m) =>\n m.todos.some(\n (t) => t.type !== 'general' || t.apiAssociation || t.dependencies\n )\n );\n return { enhanced, isEnhanced: hasEnhancedFormat };\n }\n\n /**\n * 解析 spec 状态(基于进度动态推导)\n */\n static parseSpecStatus(content: string): '未开始' | '进行中' | '已拆分' | '已完成' {\n const milestones = this.parseMilestones(content);\n \n if (milestones.length > 0) {\n const totalTodos = milestones.reduce((sum, m) => sum + m.todos.length, 0);\n const completedTodos = milestones.reduce((sum, m) => sum + m.completedCount, 0);\n\n if (totalTodos > 0) {\n if (completedTodos === totalTodos) return '已完成';\n if (completedTodos > 0) return '进行中';\n }\n return '已拆分';\n }\n\n const statusMatch = content.match(/状态.*[::]\\s*(.+)/);\n if (statusMatch) {\n const status = statusMatch[1].replace(/\\*\\*/g, '').trim();\n if (status.includes('已完成')) return '已完成';\n if (status.includes('进行中')) return '进行中';\n if (status.includes('已拆分')) return '已拆分';\n }\n return '未开始';\n }\n\n /**\n * 获取进度字符串\n */\n static getProgress(content: string): string {\n const milestones = this.parseMilestones(content);\n if (milestones.length === 0) return '-';\n \n const totalTodos = milestones.reduce((sum, m) => sum + m.todos.length, 0);\n const completedTodos = milestones.reduce((sum, m) => sum + m.completedCount, 0);\n \n if (totalTodos === 0) return '-';\n return `${completedTodos}/${totalTodos}`;\n }\n\n /**\n * 获取带图标的状态\n */\n static getStatusWithIcon(status: string): string {\n if (status.includes('已完成')) return '✓ 已完成';\n if (status.includes('进行中')) return '⟳ 进行中';\n if (status.includes('已拆分')) return '◉ 已拆分';\n return '○ 未开始';\n }\n\n /**\n * 获取 spec 状态 (原始版本兼容)\n */\n static async getSpecStatus(file: string): Promise<string> {\n try {\n const spec = await this.parseSpec(file);\n return spec.status || '未知';\n } catch {\n return '错误';\n }\n }\n}\n\n/**\n * 模板工具类\n */\nexport class TemplateUtils {\n /**\n * 渲染模板(简单变量替换)\n */\n static render(template: string, data: Record<string, any>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) => {\n return data[key] !== undefined ? String(data[key]) : '';\n });\n }\n\n /**\n * 渲染 Handlebars 模板\n */\n static async renderHandlebars(\n template: string,\n data: Record<string, any>\n ): Promise<string> {\n const Handlebars = await import('handlebars');\n const compiled = Handlebars.default.compile(template);\n return compiled(data);\n }\n}\n\n/**\n * 验证工具类\n */\nexport class ValidationUtils {\n /**\n * 验证项目名称\n */\n static validateProjectName(name: string): boolean {\n return /^[a-z0-9-]+$/.test(name);\n }\n\n /**\n * 验证邮箱\n */\n static validateEmail(email: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n }\n\n /**\n * 验证 URL\n */\n static validateUrl(url: string): boolean {\n try {\n new URL(url);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import { execa } from 'execa';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport os from 'os';\nimport { logger } from './logger.js';\nimport { FileUtils, StringUtils } from './utils.js';\n\n/**\n * Claude AI 集成类\n */\nexport class ClaudeAI {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n private verbose: boolean;\n\n constructor(verbose = false) {\n this.verbose = verbose;\n }\n\n async checkInstalled(): Promise<boolean> {\n try {\n // 使用 which 检查,更轻量且不会触发 CLI 的任何初始化逻辑\n const { exitCode } = await execa('which', ['claude'], { stdio: 'ignore', reject: false });\n return exitCode === 0;\n } catch {\n return false;\n }\n }\n\n /**\n * 获取 Claude 版本\n */\n async getVersion(): Promise<string> {\n try {\n const { stdout } = await execa('claude', ['--version'], { stdio: 'pipe' });\n return stdout.trim();\n } catch {\n throw new Error('无法获取 Claude 版本');\n }\n }\n\n /**\n * 发送 prompt 到 Claude\n */\n async prompt(promptText: string, options?: PromptOptions): Promise<string> {\n // 创建临时文件来存储 prompt(避免命令行参数过长)\n const tempDir = os.tmpdir();\n const tempFile = path.join(tempDir, `team-cli-prompt-${Date.now()}.txt`);\n\n try {\n // 构建最终的 prompt(包含上下文文件内容)\n let finalPrompt = promptText;\n const validContextFiles: string[] = [];\n\n // 验证并读取上下文文件\n if (options?.contextFiles && options.contextFiles.length > 0) {\n for (const file of options.contextFiles) {\n const exists = await FileUtils.exists(file);\n if (exists) {\n validContextFiles.push(file);\n } else {\n logger.warn(`上下文文件不存在,已跳过: ${file}`);\n }\n }\n\n // 将上下文文件内容添加到 prompt 开头\n if (validContextFiles.length > 0) {\n const contextParts: string[] = [];\n for (const file of validContextFiles) {\n try {\n const content = await FileUtils.read(file);\n const fileName = path.basename(file);\n contextParts.push(`## Context from ${fileName}\\n\\n${content}`);\n } catch (error) {\n logger.warn(`无法读取文件 ${file},已跳过`);\n }\n }\n\n if (contextParts.length > 0) {\n finalPrompt = `${contextParts.join('\\n\\n---\\n\\n')}\\n\\n---\\n\\n${promptText}`;\n }\n }\n }\n\n // 将 prompt 写入临时文件\n await fs.writeFile(tempFile, finalPrompt, 'utf-8');\n\n // 使用 -p 参数以 print 模式运行 Claude(非交互式,直接输出结果)\n // 通过 stdin 传递 prompt 内容,避免命令行参数过长\n // 添加 --dangerously-skip-permissions 跳过权限确认\n const result = await execa('claude', ['--dangerously-skip-permissions', '-p'], {\n input: finalPrompt, // 通过 stdin 传递 prompt\n timeout: options?.timeout || 300000, // 5 分钟超时\n maxBuffer: 1024 * 1024 * 10, // 10MB buffer\n });\n\n return result.stdout || '';\n } finally {\n // 清理临时文件\n try {\n await fs.remove(tempFile);\n } catch {\n // 忽略清理失败\n }\n }\n }\n\n /**\n * 使用 prompt 模板和参数发送请求\n */\n async promptWithTemplate(\n template: string,\n data: Record<string, any>,\n options?: PromptOptions\n ): Promise<string> {\n // 简单的模板替换\n let promptText = template;\n for (const [key, value] of Object.entries(data)) {\n const regex = new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g');\n promptText = promptText.replace(regex, String(value));\n }\n\n return await this.prompt(promptText, options);\n }\n\n /**\n * 启动交互式会话\n */\n async runTerminal(promptText: string): Promise<void> {\n logger.info('正在启动交互式 Claude 会话...');\n\n try {\n // 仅保留最核心的参数,避免多余参数干扰 CLI 启动\n await execa('claude', ['--dangerously-skip-permissions', promptText], {\n stdio: 'inherit',\n env: { ...process.env, FORCE_COLOR: '1' }\n });\n } catch (error: any) {\n if (error.signal !== 'SIGINT') {\n throw error;\n }\n }\n }\n\n /**\n * 发送对话(支持上下文)\n */\n async chat(messages: ChatMessage[], options?: PromptOptions): Promise<string> {\n // 构建完整的 prompt\n const fullPrompt = messages\n .map((msg) => {\n const role = msg.role === 'system' ? '系统指令' : `${msg.role === 'user' ? '用户' : '助手'}`;\n return `[${role}]: ${msg.content}`;\n })\n .join('\\n\\n');\n\n // 使用 -p 参数以 print 模式运行 Claude,通过 stdin 传递 prompt\n // 添加 --dangerously-skip-permissions 跳过权限确认\n const result = await execa('claude', ['--dangerously-skip-permissions', '-p'], {\n input: fullPrompt, // 通过 stdin 传递 prompt\n timeout: options?.timeout || 300000,\n maxBuffer: 1024 * 1024 * 10,\n });\n\n return result.stdout || '';\n }\n\n /**\n * 分析代码\n */\n async analyzeCode(code: string, language: string, question?: string): Promise<string> {\n const prompt = `请分析以下 ${language} 代码:${question ? `并回答:${question}` : ''}\n\n\\`\\`\\`${language}\n${code}\n\\`\\`\\`\n\n请提供:\n1. 代码功能概述\n2. 潜在问题\n3. 改进建议\n`;\n\n return await this.prompt(prompt);\n }\n\n /**\n * 生成代码\n */\n async generateCode(\n description: string,\n language: string,\n context?: string\n ): Promise<string> {\n let prompt = `请用 ${language} 编写代码实现以下功能:\\n\\n${description}\\n\\n`;\n\n if (context) {\n prompt += `参考上下文:\\n\\n${context}\\n\\n`;\n }\n\n prompt += `要求:\n1. 代码简洁易读\n2. 包含必要的注释\n3. 遵循最佳实践\n4. 只返回代码,不要额外解释\n`;\n\n return await this.prompt(prompt);\n }\n\n /**\n * 审查代码\n */\n async reviewCode(code: string, language: string): Promise<CodeReviewResult> {\n const prompt = `请审查以下 ${language} 代码,提供详细反馈:\n\n\\`\\`\\`${language}\n${code}\n\\`\\`\\`\n\n请按以下格式回复:\n## 发现的问题\n- [严重程度] 问题描述\n\n## 改进建议\n- 建议内容\n\n## 亮点\n- 做得好的地方\n\n请用 JSON 格式回复:\n{\n \"issues\": [{\"severity\": \"high|medium|low\", \"message\": \"问题描述\"}],\n \"suggestions\": [\"建议1\", \"建议2\"],\n \"highlights\": [\"亮点1\", \"亮点2\"]\n}\n`;\n\n const response = await this.prompt(prompt);\n try {\n // 尝试从响应中提取 JSON\n const jsonMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n return JSON.parse(jsonMatch[0]);\n }\n } catch {\n // 如果解析失败,返回默认结构\n }\n\n return {\n issues: [],\n suggestions: [response],\n highlights: [],\n };\n }\n\n /**\n * 生成 Spec 文档\n */\n async generateSpec(\n featureName: string,\n description: string,\n projectContext: string,\n dependencies?: string[]\n ): Promise<string> {\n let prompt = `Role: Senior Fullstack Developer\n\n你是一个资深的全栈工程师,现在需要为一个新功能生成规格文档(Spec)。\n\n## 功能名称\n${featureName}\n\n## 功能描述\n${description}\n`;\n\n if (dependencies && dependencies.length > 0) {\n prompt += `\n## 依赖功能\n此功能依赖以下已完成的功能:${dependencies.join('、')}\n`;\n }\n\n prompt += `\n## 项目技术栈\n后端: Java 17 + Spring Boot 3 + MyBatis Plus + MySQL 8.0\n前端: Next.js 14 (App Router) + TypeScript + Tailwind CSS\n\n## 项目当前状态\n${projectContext}\n\n## 任务\n请根据功能描述,生成一个完整的功能规格文档 Spec。\n\n## Spec 文档格式要求\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: [功能中文名]\n**优先级**: P0/P1/P2 (根据功能重要性判断)\n**预估工时**: X 天 (根据复杂度评估:简单1-2天,中等3-5天,复杂5-10天)\n**状态**: 待拆分\n**创建日期**: {{DATE}}\n\n## 依赖关系\n**前置依赖**:\n${dependencies ? dependencies.map((d) => `- [x] ${d}`).join('\\n') : '- (无)'}\n\n**被依赖于**:\n- (自动生成,表示哪些 spec 依赖本功能)\n\n## 背景与目标\n[根据功能描述,简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n列出 3-8 个主要功能点,每个功能点用一句话描述。\n\n## 技术设计\n### API 设计\n列出主要的 API 端点,格式:\n- \\`METHOD /api/path\\` - 简短说明\n\n### 数据模型\n列出需要的数据表,格式:\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n> 注: 使用 \\`team-cli breakdown ${StringUtils.toKebabCase(featureName)}.md\\` 拆分此 spec 为 milestones 和 todos\n\n----\n*生成于: {{TIMESTAMP}} by Claude*\n\\`\\`\\`\n\n## 注意事项\n1. 只生成 Spec 文档,不要实现任何代码\n2. 优先级判断标准:\n - P0: 核心功能,阻塞其他功能\n - P1: 重要功能,影响用户体验\n - P2: 增强功能,锦上添花\n3. 工时评估标准:\n - 简单功能: 1-2 天\n - 中等功能: 3-5 天\n - 复杂功能: 5-10 天\n4. 功能点要具体可执行,避免过于抽象\n5. API 和数据模型要符合实际技术栈\n`;\n\n return await this.prompt(prompt, { timeout: 180000 });\n }\n\n /**\n * 生成 Bugfix 报告\n */\n async generateBugfixReport(\n bugDescription: string,\n reproductionSteps: string[],\n projectContext: string\n ): Promise<string> {\n const prompt = `Role: Senior Fullstack Developer\n\n用户报告了一个 Bug,需要你生成 Bugfix 规格文档。\n\n## Bug 描述\n${bugDescription}\n\n## 复现步骤\n${reproductionSteps.map((step, i) => `${i + 1}. ${step}`).join('\\n')}\n\n## 项目当前状态\n${projectContext}\n\n## 任务\n请生成一个完整的 Bugfix 报告,包括:\n1. 问题分析\n2. 根本原因推测\n3. 修复建议\n4. 测试计划\n`;\n\n return await this.prompt(prompt, { timeout: 120000 });\n }\n}\n\n/**\n * Prompt 选项\n */\nexport interface PromptOptions {\n contextFiles?: string[];\n timeout?: number;\n model?: string;\n}\n\n/**\n * 聊天消息\n */\nexport interface ChatMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\n/**\n * 代码审查结果\n */\nexport interface CodeReviewResult {\n issues: Array<{\n severity: 'high' | 'medium' | 'low';\n message: string;\n }>;\n suggestions: string[];\n highlights: string[];\n}\n\n// 导出单例\nexport const claudeAI = new ClaudeAI();\n","import { execa } from 'execa';\nimport path from 'path';\nimport { FileUtils } from './utils.js';\nimport { logger } from './logger.js';\n\n/**\n * 模板类型\n */\nexport type TemplateType = 'frontend' | 'backend';\n\n/**\n * 模板信息接口\n */\nexport interface TemplateInfo {\n type: TemplateType;\n repository: string;\n currentCommit?: string;\n currentTag?: string;\n latestCommit?: string;\n latestTag?: string;\n needsUpdate: boolean;\n}\n\n/**\n * 模板版本信息接口\n */\nexport interface TemplateVersionInfo {\n commit: string;\n tag?: string;\n branch?: string;\n lastUpdate?: string;\n}\n\n/**\n * 模板配置接口\n */\nexport interface TemplateConfig {\n frontend: {\n repository: string;\n commit?: string;\n tag?: string;\n branch?: string;\n lastUpdate?: string;\n };\n backend: {\n repository: string;\n commit?: string;\n tag?: string;\n branch?: string;\n lastUpdate?: string;\n };\n}\n\n/**\n * 默认模板配置\n */\nconst DEFAULT_TEMPLATES: TemplateConfig = {\n frontend: {\n repository: 'git@gitlab.yungu-inc.org:static/fe-tpl-ai.git',\n },\n backend: {\n repository: 'git@gitlab.yungu-inc.org:yungu-app/java-scaffold-template.git',\n },\n};\n\n/**\n * 获取项目配置文件路径\n */\nfunction getConfigPath(projectPath: string): string {\n return path.join(projectPath, '.team-cli', 'template.json');\n}\n\n/**\n * 读取项目的模板配置\n */\nexport async function readTemplateConfig(projectPath: string): Promise<TemplateConfig | null> {\n const configPath = getConfigPath(projectPath);\n const exists = await FileUtils.exists(configPath);\n\n if (!exists) {\n return null;\n }\n\n try {\n const content = await FileUtils.read(configPath);\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\n/**\n * 保存项目的模板配置\n */\nexport async function saveTemplateConfig(projectPath: string, config: TemplateConfig): Promise<void> {\n const configDir = path.join(projectPath, '.team-cli');\n await FileUtils.ensureDir(configDir);\n\n const configPath = getConfigPath(projectPath);\n const content = JSON.stringify(config, null, 2);\n await FileUtils.write(configPath, content);\n}\n\n/**\n * 初始化模板配置\n */\nexport async function initTemplateConfig(projectPath: string): Promise<void> {\n const config = await readTemplateConfig(projectPath);\n\n if (config) {\n return; // 已存在配置\n }\n\n // 保存当前使用的模板信息\n await saveTemplateConfig(projectPath, DEFAULT_TEMPLATES);\n}\n\n/**\n * 获取远程仓库的最新 commit\n */\nexport async function getLatestCommit(repository: string): Promise<string> {\n try {\n // 使用 git ls-remote 获取最新 commit\n const { stdout } = await execa('git', ['ls-remote', repository, 'HEAD'], {\n stdio: 'pipe',\n });\n\n const commit = stdout.split('\\t')[0];\n return commit;\n } catch (error) {\n logger.debug(`获取 ${repository} 最新 commit 失败: ${error}`);\n return '';\n }\n}\n\n/**\n * 获取远程仓库的最新 tag\n */\nexport async function getLatestTag(repository: string): Promise<string> {\n try {\n // 获取所有 tags 并按版本排序\n const { stdout } = await execa(\n 'git',\n ['ls-remote', '--tags', repository],\n {\n stdio: 'pipe',\n }\n );\n\n const tags = stdout\n .split('\\n')\n .filter((line) => line.includes('refs/tags/') && !line.includes('^{}'))\n .map((line) => {\n const [, ref] = line.split('\\t');\n return ref.replace('refs/tags/', '');\n })\n .filter((tag) => /^v?\\d+\\.\\d+\\.\\d+/.test(tag))\n .sort((a, b) => {\n // 简单的版本排序\n const va = a.replace(/^v/, '').split('.').map(Number);\n const vb = b.replace(/^v/, '').split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n if ((va[i] || 0) > (vb[i] || 0)) return 1;\n if ((va[i] || 0) < (vb[i] || 0)) return -1;\n }\n return 0;\n });\n\n return tags[tags.length - 1] || '';\n } catch (error) {\n logger.debug(`获取 ${repository} 最新 tag 失败: ${error}`);\n return '';\n }\n}\n\n/**\n * 检查模板是否需要更新\n */\nexport async function checkTemplateUpdate(\n projectPath: string,\n type: TemplateType\n): Promise<TemplateInfo | null> {\n const config = await readTemplateConfig(projectPath);\n\n if (!config || !config[type]) {\n return null;\n }\n\n const repository = config[type].repository;\n const currentCommit = config[type].commit;\n const currentTag = config[type].tag;\n\n // 获取最新版本\n const latestCommit = await getLatestCommit(repository);\n const latestTag = await getLatestTag(repository);\n\n if (!latestCommit) {\n return null;\n }\n\n // 判断是否需要更新\n const needsUpdate = currentCommit && currentCommit !== latestCommit;\n\n return {\n type,\n repository,\n currentCommit,\n currentTag,\n latestCommit,\n latestTag,\n needsUpdate: needsUpdate || false,\n };\n}\n\n/**\n * 更新模板配置中的版本信息\n */\nexport async function updateTemplateVersion(\n projectPath: string,\n type: TemplateType,\n commit: string,\n options?: {\n tag?: string;\n branch?: string;\n }\n): Promise<void> {\n const config = await readTemplateConfig(projectPath);\n\n if (!config) {\n return;\n }\n\n config[type].commit = commit;\n if (options?.tag) {\n config[type].tag = options.tag;\n }\n if (options?.branch) {\n config[type].branch = options.branch;\n }\n config[type].lastUpdate = new Date().toISOString();\n\n await saveTemplateConfig(projectPath, config);\n}\n\n/**\n * 获取默认模板配置\n */\nexport function getDefaultTemplates(): TemplateConfig {\n // 返回深拷贝以避免修改原对象\n return {\n frontend: { ...DEFAULT_TEMPLATES.frontend },\n backend: { ...DEFAULT_TEMPLATES.backend },\n };\n}\n","import path from 'path';\nimport { FileUtils } from './utils.js';\n\nexport interface CommonModule {\n id: string;\n name: string;\n description: string;\n type: 'local' | 'remote';\n specs: string[]; \n mcpServer?: string;\n backendFragments?: { source: string; target: string }[]; \n frontendFragments?: { source: string; target: string }[];\n dependencies?: string[];\n}\n\nexport class ModuleManager {\n private static readonly MODULES: CommonModule[] = [\n // ========== 云谷公共模块 (新增) ==========\n {\n id: 'yungu-sso',\n name: 'SSO 单点登录',\n description: 'CAS单点登录集成、Token验证、会话管理',\n type: 'local',\n specs: ['yungu-sso/spec.md'],\n backendFragments: [\n // Config\n {\n source: 'yungu/sso/config/CasConfig.java',\n target: 'config/yungu/sso/CasConfig.java',\n },\n {\n source: 'yungu/sso/config/LoginClientConfig.java',\n target: 'config/yungu/sso/LoginClientConfig.java',\n },\n // Filter\n {\n source: 'yungu/sso/filter/AuthFilter.java',\n target: 'config/yungu/sso/filter/AuthFilter.java',\n },\n // Interceptor\n {\n source: 'yungu/sso/intercepter/CasLoginInterceptor.java',\n target: 'common/yungu/sso/intercepter/CasLoginInterceptor.java',\n },\n {\n source: 'yungu/sso/intercepter/UserContextInterceptor.java',\n target: 'common/yungu/sso/intercepter/UserContextInterceptor.java',\n },\n // UserContext\n {\n source: 'yungu/sso/common/UserContext.java',\n target: 'common/yungu/sso/UserContext.java',\n },\n {\n source: 'yungu/sso/common/domain/UserBaseInfo.java',\n target: 'common/yungu/sso/domain/UserBaseInfo.java',\n },\n {\n source: 'yungu/sso/common/domain/UserAccount.java',\n target: 'common/yungu/sso/domain/UserAccount.java',\n },\n // Config classes\n {\n source: 'yungu/sso/config/InterceptorConfiguration.java',\n target: 'config/yungu/sso/InterceptorConfiguration.java',\n },\n ],\n dependencies: ['org.yungu:login-client'],\n },\n {\n id: 'yungu-user-context',\n name: '用户上下文 (UserContext)',\n description: 'RequestScope级别的用户信息获取,支持多身份和Mock',\n type: 'local',\n specs: ['yungu-user-context/spec.md'],\n backendFragments: [\n {\n source: 'yungu/UserContext.java',\n target: 'common/yungu/UserContext.java',\n },\n {\n source: 'yungu/domain/UserBaseInfo.java',\n target: 'common/yungu/domain/UserBaseInfo.java',\n },\n {\n source: 'yungu/domain/UserAccount.java',\n target: 'common/yungu/domain/UserAccount.java',\n },\n ],\n dependencies: ['org.yungu:login-client'],\n },\n {\n id: 'yungu-auth',\n name: '用户认证与鉴权',\n description: 'CAS单点登录集成、用户上下文拦截器',\n type: 'local',\n specs: ['yungu-auth/spec.md'],\n requires: ['yungu-user-context'],\n backendFragments: [\n {\n source: 'yungu/intercepter/UserContextInterceptor.java',\n target: 'common/yungu/intercepter/UserContextInterceptor.java',\n },\n {\n source: 'yungu/config/InterceptorConfiguration.java',\n target: 'config/yungu/InterceptorConfiguration.java',\n },\n ],\n dependencies: ['org.yungu:login-client', 'org.yungu:acl-api'],\n },\n {\n id: 'yungu-managers',\n name: '通用服务封装',\n description: '用户服务、学校服务等Dubbo服务调用封装',\n type: 'local',\n specs: ['yungu-managers/spec.md'],\n backendFragments: [\n {\n source: 'yungu/managers/UserServiceManager.java',\n target: 'common/yungu/managers/UserServiceManager.java',\n },\n {\n source: 'yungu/managers/SchoolManager.java',\n target: 'common/yungu/managers/SchoolManager.java',\n },\n ],\n dependencies: ['org.yungu:user-service-api'],\n },\n {\n id: 'yungu-utils',\n name: '工具类模块',\n description: '通用工具类 (CommonUtils等)',\n type: 'local',\n specs: ['yungu-utils/spec.md'],\n backendFragments: [\n {\n source: 'yungu/utils/CommonUtils.java',\n target: 'common/yungu/utils/CommonUtils.java',\n },\n ],\n },\n {\n id: 'yungu-logging',\n name: '日志与监控',\n description: '方法耗时日志记录 (LogAspect)',\n type: 'local',\n specs: ['yungu-logging/spec.md'],\n backendFragments: [\n {\n source: 'yungu/config/LogAspect.java',\n target: 'config/yungu/LogAspect.java',\n },\n ],\n },\n {\n id: 'yungu-i18n',\n name: '国际化支持',\n description: '中英文切换、多语言枚举',\n type: 'local',\n specs: ['yungu-i18n/spec.md'],\n requires: ['yungu-user-context'],\n backendFragments: [\n {\n source: 'yungu/enums/LanguageEnum.java',\n target: 'common/yungu/enums/LanguageEnum.java',\n },\n {\n source: 'yungu/constant/LanguageConstant.java',\n target: 'common/yungu/constant/LanguageConstant.java',\n },\n ],\n },\n // ========== 原有模块 ==========\n {\n id: 'acl',\n name: 'ACL (Access Control List)',\n description: '基于角色的访问控制模块(本地模板版)',\n type: 'local',\n specs: ['acl/spec.md'],\n backendFragments: [\n {\n source: 'acl/backend/AclResultCode.java',\n target: 'common/enums/AclResultCode.java',\n },\n {\n source: 'acl/backend/RequiredPermission.java',\n target: 'common/annotation/RequiredPermission.java',\n },\n ],\n },\n {\n id: 'permission-remote',\n name: '权限管理 (远程 MCP 版)',\n description: '从 api-metadata 实时获取最新权限接口定义并生成代码',\n type: 'remote',\n mcpServer: 'api-metadata',\n specs: ['permission-remote/spec.md'],\n },\n {\n id: 'audit-log',\n name: '审计日志 (Audit Log)',\n description: '记录用户操作日志,支持 AOP 自动拦截和异步存储',\n type: 'local',\n specs: ['audit-log/spec.md'],\n },\n ];\n\n /**\n * 获取所有可用模块\n */\n static getAvailableModules(): CommonModule[] {\n return [...this.MODULES];\n }\n\n /**\n * 根据 ID 获取模块\n */\n static getModuleById(id: string): CommonModule | undefined {\n return this.MODULES.find((m) => m.id === id);\n }\n\n /**\n * 注入模块到项目,返回新增文件列表\n */\n static async injectModule(\n projectPath: string,\n moduleId: string,\n templatesDir: string\n ): Promise<string[]> {\n const module = this.getModuleById(moduleId);\n if (!module) return [];\n\n const addedFiles: string[] = [];\n\n // 1. 注入 Specs\n for (const specRelPath of module.specs) {\n const sourcePath = path.join(templatesDir, 'modules', specRelPath);\n const targetPath = path.join(projectPath, 'docs/specs', path.basename(specRelPath));\n\n // 对于远程模块,如果模板不存在,生成一个基础占位符\n if (await FileUtils.exists(sourcePath)) {\n await FileUtils.copy(sourcePath, targetPath);\n addedFiles.push(path.relative(projectPath, targetPath));\n } else if (module.type === 'remote') {\n await this.generateRemoteSpecPlaceholder(targetPath, module);\n addedFiles.push(path.relative(projectPath, targetPath));\n } else {\n // 本地模块也生成占位符 spec\n await this.generateLocalSpecPlaceholder(targetPath, module);\n addedFiles.push(path.relative(projectPath, targetPath));\n }\n }\n\n // 2. 注入 Backend Fragments\n if (module.backendFragments) {\n const backendJavaDir = path.join(projectPath, 'backend/src/main/java');\n\n // 优先使用模板目录中的文件\n const useTemplates = await FileUtils.exists(path.join(templatesDir, 'modules'));\n\n for (const fragment of module.backendFragments) {\n let sourcePath: string | null = null;\n let targetPath: string;\n let content: string;\n\n if (useTemplates) {\n // 使用模板文件\n sourcePath = path.join(templatesDir, 'modules', fragment.source);\n if (await FileUtils.exists(sourcePath)) {\n content = await FileUtils.read(sourcePath);\n }\n }\n\n // 如果模板不存在,生成占位符代码\n if (!content) {\n content = this.generatePlaceholderCode(module, fragment);\n }\n\n // 计算目标路径\n if (fragment.target.startsWith('common/')) {\n // 放到 common 模块\n const relativePath = fragment.target.replace(/^common\\//, 'org/yungu/common/');\n targetPath = path.join(backendJavaDir, relativePath);\n } else if (fragment.target.startsWith('config/')) {\n // 放到主模块的 config 目录\n const mainModule = this.findMainModule(projectPath);\n if (mainModule) {\n const relativePath = fragment.target.replace(/^config\\//, `${mainModule}/config/`);\n targetPath = path.join(backendJavaDir, relativePath);\n } else {\n targetPath = path.join(backendJavaDir, fragment.target);\n }\n } else {\n targetPath = path.join(backendJavaDir, fragment.target);\n }\n\n await FileUtils.ensureDir(path.dirname(targetPath));\n await FileUtils.write(targetPath, content);\n addedFiles.push(path.relative(projectPath, targetPath));\n }\n }\n\n // 3. 注入 Frontend Fragments\n if (module.frontendFragments) {\n const frontendSrcDir = path.join(projectPath, 'frontend/src');\n\n for (const fragment of module.frontendFragments) {\n const sourcePath = path.join(templatesDir, 'modules', fragment.source);\n const targetPath = path.join(frontendSrcDir, fragment.target);\n\n if (await FileUtils.exists(sourcePath)) {\n await FileUtils.copy(sourcePath, targetPath);\n addedFiles.push(path.relative(projectPath, targetPath));\n }\n }\n }\n\n return addedFiles;\n }\n\n /**\n * 查找主模块名 (第一个 service 类型的模块)\n */\n private static findMainModule(projectPath: string): string | null {\n const settingsPath = path.join(projectPath, 'backend/settings.gradle');\n const content = FileUtils.readSync(settingsPath);\n const matches = content.match(/include\\s+'([^']+)'/g);\n if (matches) {\n for (const match of matches) {\n const moduleName = match.replace(/include\\s+'/, '').replace(/'/, '');\n if (moduleName !== 'common') {\n return moduleName;\n }\n }\n }\n return null;\n }\n\n /**\n * 生成占位符代码\n */\n private static generatePlaceholderCode(module: CommonModule, fragment: { target: string }): string {\n const targetPackage = path.dirname(fragment.target).replace(/\\//g, '.');\n const className = path.basename(fragment.target, '.java');\n const moduleName = module.name;\n const moduleId = module.id;\n\n return `package ${targetPackage};\n\nimport lombok.extern.slf4j.Slf4j;\n\n/**\n * ${moduleName} - 占位符\n *\n * 此文件由 team-cli 自动生成。\n * 模块 ID: ${moduleId}\n *\n * 使用说明:\n * 1. 请根据项目实际需求完善此文件\n * 2. 或参考 docs/specs/${moduleId}/spec.md 获取详细需求\n */\n@Slf4j\npublic class ${className} {\n\n /**\n * TODO: 实现 ${moduleName} 功能\n */\n public void execute() {\n log.info(\"${className} - 执行中...\");\n // 在此实现具体逻辑\n }\n}\n`;\n }\n\n /**\n * 生成本地模块的 Spec 占位符\n */\n private static async generateLocalSpecPlaceholder(targetPath: string, module: CommonModule): Promise<void> {\n const content = `# ${module.name}\n\n## 功能概述\n${module.description}\n\n## 使用说明\n\n此模块为云谷通用模块的占位符配置。\n\n### 配置步骤\n\n1. **添加依赖**\n\n在 \\`backend/build.gradle\\` 中添加:\n\n\\`\\`\\`groovy\n${module.dependencies ? module.dependencies.map(d => `implementation '${d}'`).join('\\n') : ''}\n\\`\\`\\`\n\n2. **配置文件**\n\n根据需求配置 application.yml:\n\n\\`\\`\\`yaml\n# ${module.name} 配置\n\\`\\`\\`\n\n3. **导入配置类**\n\n在主 Application 类上添加注解:\n\n\\`\\`\\`java\n@SpringBootApplication\n@ComponentScan(\"${module.id}\")\npublic class Application {\n // ...\n}\n\\`\\`\\`\n\n4. **参考文档**\n\n查看 docs/specs/${module.id}/spec.md 获取详细实现说明。\n\n## 依赖关系\n\n${module.requires ? `需要先启用: ${module.requires.join(', ')}` : '无前置依赖'}\n`;\n await FileUtils.write(targetPath, content);\n }\n\n /**\n * 生成远程模块的 Spec 占位符\n */\n private static async generateRemoteSpecPlaceholder(targetPath: string, module: CommonModule): Promise<void> {\n const content = `# ${module.name} (Remote)\n\n## 功能概述\n该模块通过远程 MCP 服务 \\`${module.mcpServer}\\` 获取实时元数据。\n\n## 使用说明\n1. 确保已安装并配置 MCP 服务。\n2. 运行 \\`team-cli dev\\` 并选择此 Spec。\n3. Claude 将自动调用 MCP 获取最新的 API 信息并完成实现。\n`;\n await FileUtils.write(targetPath, content);\n }\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport os from 'os';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { FileUtils, StringUtils } from '../lib/utils.js';\nimport { Listr } from 'listr2';\nimport {\n initTemplateConfig,\n updateTemplateVersion,\n getLatestTag,\n getDefaultTemplates,\n} from '../lib/template-version.js';\nimport { ModuleManager } from '../lib/module-registry.js';\n\n/**\n * 交互式收集项目配置 (类似 Spring Initializr)\n */\nasync function collectProjectConfig(defaultProjectName?: string): Promise<ProjectConfig> {\n // 1. 项目名称\n let projectName = defaultProjectName;\n if (!projectName) {\n const nameAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'projectName',\n message: '请输入项目目录名称:',\n default: 'my-project',\n validate: (input: string) => {\n if (!/^[a-z0-9-]+$/.test(input)) {\n return '项目名称只能包含小写字母、数字和连字符';\n }\n return true;\n },\n },\n ]);\n projectName = nameAnswer.projectName;\n }\n\n // 2. 项目类型\n const typeAnswer = await inquirer.prompt([\n {\n type: 'list',\n name: 'projectType',\n message: '请选择项目类型:',\n choices: [\n { name: '单模块项目', value: 'single' },\n { name: '多模块项目 (Gradle)', value: 'multi' },\n ],\n default: 'single',\n },\n ]);\n\n // 3. 根项目名 (仅多模块需要)\n let rootProjectName = projectName;\n if (typeAnswer.projectType === 'multi') {\n const rootAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'rootProjectName',\n message: '请输入根项目名 (settings.gradle rootProject.name):',\n default: projectName,\n validate: (input: string) => {\n if (!/^[a-z0-9-]+$/.test(input)) {\n return '根项目名只能包含小写字母、数字和连字符';\n }\n return true;\n },\n },\n ]);\n rootProjectName = rootAnswer.rootProjectName;\n }\n\n // 4. Group ID\n const groupAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'groupId',\n message: '请输入 Group ID (包路径前缀):',\n default: 'org.yungu',\n validate: (input: string) => {\n if (!/^[a-z][a-z0-9]*(\\.[a-z][a-z0-9]*)*$/.test(input)) {\n return 'Group ID 格式不正确 (如: com.example 或 org.yungu)';\n }\n return true;\n },\n },\n ]);\n const groupId = groupAnswer.groupId;\n\n // 5. 模块配置\n const modules: ModuleConfig[] = [];\n let addMoreModules = true;\n let moduleIndex = 1;\n\n while (addMoreModules) {\n // 第一个模块时,如果是多模块,询问第一个模块名\n let defaultModuleName = `module-${moduleIndex}`;\n if (moduleIndex === 1) {\n if (typeAnswer.projectType === 'single') {\n defaultModuleName = 'app';\n } else {\n defaultModuleName = projectName;\n }\n }\n\n const moduleNameAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'moduleName',\n message: `请输入第 ${moduleIndex} 个子模块名称 (目录名):`,\n default: defaultModuleName,\n validate: (input: string) => {\n if (!/^[a-z][a-z0-9-]*$/.test(input)) {\n return '模块名只能包含小写字母、数字和连字符';\n }\n return true;\n },\n },\n ]);\n\n const moduleName = moduleNameAnswer.moduleName;\n\n // 模块类型 (仅多模块需要选择)\n let moduleType: ModuleConfig['type'] = 'service';\n if (typeAnswer.projectType === 'multi') {\n const typeSelectAnswer = await inquirer.prompt([\n {\n type: 'list',\n name: 'moduleType',\n message: `模块 \"${moduleName}\" 类型:`,\n choices: [\n { name: 'API 服务模块 (独立部署)', value: 'service' },\n { name: '公共模块 (被其他模块依赖)', value: 'common' },\n { name: 'API 接口模块 (仅接口定义)', value: 'api' },\n ],\n default: 'service',\n },\n ]);\n moduleType = typeSelectAnswer.moduleType;\n }\n\n // 生成包路径\n const modulePackage = `${groupId}.${moduleName}`;\n // 生成启动类名\n const applicationClass = `${toPascalCase(moduleName)}Application`;\n\n modules.push({\n name: moduleName,\n type: moduleType,\n packagePath: modulePackage,\n applicationClass,\n });\n\n // 是否继续添加模块\n if (typeAnswer.projectType === 'multi') {\n const moreAnswer = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'addMore',\n message: '是否还需要添加更多模块?',\n default: false,\n },\n ]);\n addMoreModules = moreAnswer.addMore;\n } else {\n addMoreModules = false;\n }\n\n moduleIndex++;\n }\n\n // 6. Java 版本\n const javaAnswer = await inquirer.prompt([\n {\n type: 'list',\n name: 'javaVersion',\n message: '请选择 Java 版本:',\n choices: [\n { name: 'Java 8 (1.8)', value: '1.8' },\n { name: 'Java 11 (LTS)', value: '11' },\n { name: 'Java 17 (LTS)', value: '17' },\n { name: 'Java 21 (LTS)', value: '21' },\n ],\n default: '17',\n },\n ]);\n\n // 7. 构建工具\n const buildAnswer = await inquirer.prompt([\n {\n type: 'list',\n name: 'buildTool',\n message: '请选择构建工具:',\n choices: [\n { name: 'Gradle', value: 'gradle' },\n { name: 'Maven', value: 'maven' },\n ],\n default: 'gradle',\n },\n ]);\n\n // 8. 是否需要前端\n const frontendAnswer = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'includeFrontend',\n message: '是否需要包含前端项目?',\n default: true,\n },\n ]);\n\n return {\n projectName,\n projectType: typeAnswer.projectType,\n rootProjectName,\n groupId,\n modules,\n javaVersion: javaAnswer.javaVersion,\n buildTool: buildAnswer.buildTool,\n includeFrontend: frontendAnswer.includeFrontend,\n };\n}\n\n/**\n * 字符串转 PascalCase\n */\nfunction toPascalCase(str: string): string {\n return str\n .split(/[-_]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n\n/**\n * 字符串转 camelCase\n */\nfunction toCamelCase(str: string): string {\n const pascal = toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n\n/**\n * 项目配置接口\n */\ninterface ProjectConfig {\n projectName: string; // 项目目录名\n projectType: 'single' | 'multi'; // 项目类型\n rootProjectName: string; // settings.gradle rootProject.name (多模块需要)\n groupId: string; // Group ID (包路径前缀)\n modules: ModuleConfig[]; // 模块配置列表\n javaVersion: string; // Java 版本\n buildTool: 'gradle' | 'maven'; // 构建工具\n includeFrontend: boolean; // 是否包含前端\n}\n\n/**\n * 模块配置接口\n */\ninterface ModuleConfig {\n name: string; // 模块名 (目录名)\n type: 'service' | 'api' | 'common'; // 模块类型\n packagePath: string; // 包路径 (groupId + name)\n applicationClass: string; // 启动类名\n}\n\n/**\n * Init 命令\n */\nexport const initCommand = new Command('init')\n .argument('[project-name]', '项目名称')\n .description('初始化新项目')\n .option('-d, --dir <directory>', '项目目录', '.')\n .option('--no-docker', '不生成 Docker 配置')\n .option('--no-git', '不初始化 Git')\n .option('--tag <tag>', '指定模板标签 (前后端通用)')\n .option('--backend-tag <tag>', '指定后端模板标签')\n .option('--frontend-tag <tag>', '指定前端模板标签')\n .option('--backend-branch <branch>', '指定后端模板分支')\n .option('--frontend-branch <branch>', '指定前端模板分支')\n .action(async (projectName, options) => {\n try {\n // 交互式收集项目配置\n const config = await collectProjectConfig(projectName);\n\n logger.header('AI-Native 团队研发脚手架 - 项目初始化');\n logger.newLine();\n logger.info(`项目类型: ${config.projectType === 'multi' ? '多模块项目' : '单模块项目'}`);\n logger.info(`Group ID: ${config.groupId}`);\n logger.info(`模块: ${config.modules.map(m => m.name).join(', ')}`);\n logger.info(`Java 版本: ${config.javaVersion}`);\n logger.newLine();\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n const projectPath = path.resolve(options.dir, config.projectName);\n\n // 交互式选择通用模块\n const availableModules = ModuleManager.getAvailableModules();\n const { selectedModules } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'selectedModules',\n message: '请选择要开启的内置通用模块:',\n choices: availableModules.map((m) => ({\n name: `${m.name} - ${m.description}`,\n value: m.id,\n })),\n },\n ]);\n\n // 检查目录是否存在\n if (await FileUtils.exists(projectPath)) {\n logger.error(`目录已存在: ${projectPath}`);\n logger.info('请选择其他项目名称或删除现有目录');\n process.exit(1);\n }\n\n // 1. 基础任务列表 (逻辑顺序重构,避免重复)\n const tasks = new Listr(\n [\n {\n title: '创建项目目录结构',\n task: async () => {\n await FileUtils.ensureDir(projectPath);\n await FileUtils.ensureDir(path.join(projectPath, 'docs/specs'));\n await FileUtils.ensureDir(path.join(projectPath, 'docs/prd-docs'));\n await FileUtils.ensureDir(path.join(projectPath, 'docs/api'));\n await FileUtils.ensureDir(path.join(projectPath, 'docs/sessions'));\n },\n },\n {\n title: '生成技术文档 (Tech Stack, Conventions, Memory)',\n task: async () => {\n await generateTechStack(projectPath, config);\n await generateConventions(projectPath, config);\n await generateAIMemory(projectPath, config.projectName);\n await generateSpecTemplate(projectPath);\n },\n },\n {\n title: '创建后端结构',\n task: async () => {\n await createBackendFromConfig(projectPath, config);\n },\n },\n ...(config.includeFrontend\n ? [\n {\n title: '克隆前端模板',\n task: async () => {\n const frontendTag = options.frontendTag || options.tag;\n const frontendBranch = options.frontendBranch;\n await cloneFrontendTemplate(projectPath, {\n tag: frontendTag,\n branch: frontendBranch,\n });\n },\n },\n ]\n : []),\n {\n title: '注入选定的通用模块',\n task: async (ctx: any) => {\n if (selectedModules.length === 0) return;\n const templatesDir = path.resolve(FileUtils.getDirName(import.meta.url), '../templates');\n ctx.addedFiles = [];\n for (const moduleId of selectedModules) {\n const files = await ModuleManager.injectModule(projectPath, moduleId, templatesDir);\n ctx.addedFiles.push(...files);\n }\n },\n },\n ...(options.docker\n ? [\n {\n title: '生成 Docker 部署配置',\n task: async () => {\n await generateDockerFiles(projectPath, config.projectName);\n },\n },\n ]\n : []),\n ],\n { concurrent: false, exitOnError: true }\n );\n\n const taskContext = await tasks.run();\n\n // 2. 远程模块处理 (在 Listr 之外运行,以确保 Claude 交互可见)\n const remoteModules = selectedModules\n .map((id: string) => ModuleManager.getModuleById(id))\n .filter((m: any) => m?.type === 'remote');\n\n if (remoteModules.length > 0) {\n logger.newLine();\n logger.header('处理远程模块');\n \n const { execa: e } = await import('execa');\n\n // 注册 MCP\n try {\n logger.info('正在注册远程 MCP 服务 api-metadata...');\n await e('claude', [\n 'mcp', 'add',\n '--transport', 'sse',\n '--header', 'Authorization: Bearer mcp_00557dabb71297b4f9ac5fe748395f2c',\n '--',\n 'api-metadata', 'https://api-metadata.yungu.org/sse'\n ]);\n logger.success('远程 MCP 服务注册成功');\n } catch (err) {\n logger.warn('远程 MCP 服务注册提示: 可能已存在或手动注册');\n }\n\n // 生成代码\n for (const module of remoteModules) {\n if (!module) continue;\n logger.newLine();\n logger.info(`正在为您生成 [${module.name}] 的远程调用代码...`);\n \n const prompt = `使用 api-metadata MCP 工具获取所有与 \"${module.id.replace('-remote', '')}\" 相关的 API 元数据。\n然后在项目路径 \\`${projectPath}\\` 的后端目录中,直接生成对应的 Java 调用代码(如 Feign Client 或 RestTemplate 封装)。\n请确保代码符合 \\`CONVENTIONS.md\\` 中的规范。\n生成完成后,检查并修复任何编译错误,最后简要列出生成的文件。`;\n\n try {\n // 使用 --output-format text 确保实时输出可见\n await e('claude', [\n '-p', prompt,\n '--add-dir', projectPath,\n '--dangerously-skip-permissions',\n '--output-format', 'text'\n ], {\n stdio: 'inherit',\n timeout: 600000,\n env: { ...process.env, FORCE_COLOR: '1' } // 保持颜色输出\n });\n logger.success(`[${module.name}] 代码生成完成`);\n } catch (err) {\n logger.error(`[${module.name}] 代码生成失败,请稍后手动重试`);\n }\n }\n }\n\n // 3. 初始化 Git\n if (!options.noGit) {\n logger.newLine();\n await initGit(projectPath, projectName);\n }\n\n logger.newLine();\n logger.success(`项目 ${projectName} 初始化成功!`);\n logger.newLine();\n\n // 4. 显示新增文件汇总\n const addedFiles: string[] = taskContext?.addedFiles || [];\n if (addedFiles.length > 0) {\n logger.newLine();\n logger.header('模块新增文件汇总');\n for (const file of addedFiles) {\n logger.step(file);\n }\n }\n\n logger.newLine();\n logger.info('下一步:');\n logger.step(`cd ${projectName}`);\n logger.step('team-cli add-feature <feature-name>');\n logger.step('team-cli breakdown docs/specs/xxx.md');\n logger.step('team-cli dev');\n logger.newLine();\n } catch (error: any) {\n logger.error(`初始化失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 生成技术栈文档\n */\nasync function generateTechStack(projectPath: string, config: ProjectConfig): Promise<void> {\n const backendStructure = config.modules.map(m => {\n const packagePath = `${config.groupId}.${m.name}`;\n return `├── ${m.name}/\n│ └── src/main/java/${packagePath.replace(/\\./g, '/')}/\n│ ├── controller/ # API 控制器\n│ ├── service/ # 业务逻辑\n│ ├── mapper/ # 数据访问\n│ ├── entity/ # 数据模型\n│ ├── dto/ # 数据传输对象\n│ └── config/ # 配置类`;\n }).join('\\n');\n\n const content = `# 技术栈\n\n## 项目配置\n\n| 配置项 | 值 |\n|-------|------|\n| 项目名称 | ${config.projectName} |\n| Group ID | ${config.groupId} |\n| 根项目名 | ${config.rootProjectName} |\n| 模块 | ${config.modules.map(m => m.name).join(', ')} |\n| Java 版本 | ${config.javaVersion} |\n| 构建工具 | ${config.buildTool === 'gradle' ? 'Gradle' : 'Maven'} |\n\n## 后端技术栈\n\n| 组件 | 技术选型 | 版本 | 说明 |\n|------|---------|------|------|\n| 语言 | Java | ${config.javaVersion} | LTS 版本 |\n| 框架 | Spring Boot | 3.2 | 现代化 Java 框架 |\n| 构建工具 | Gradle | 8.x | 快速、灵活的构建工具 |\n| ORM | MyBatis Plus | 3.5 | 增强 MyBatis,简化 CRUD |\n| 数据库 | MySQL | 8.0 | 关系型数据库 |\n| 缓存 | Redis | 7.x | 缓存和会话存储 |\n| 文档 | SpringDoc OpenAPI | 2.3 | API 文档自动生成 |\n\n${config.includeFrontend ? `## 前端技术栈\n\n| 组件 | 技术选型 | 版本 | 说明 |\n|------|---------|------|------|\n| 框架 | Next.js | 14 | React 全栈框架 |\n| 语言 | TypeScript | 5.x | 类型安全 |\n| 样式 | Tailwind CSS | 3.x | 原子化 CSS |\n| UI 库 | Shadcn/UI | latest | 基于 Radix UI 的组件库 |\n| 图标 | Lucide React | latest | 一致性图标库 |\n| 状态管理 | React Context + Hooks | - | 轻量级状态管理 |\n| 表单 | React Hook Form | 7.x | 高性能表单 |\n| 数据验证 | Zod | 3.x | TypeScript 优先的验证库 |` : ''}\n\n## 开发工具\n\n| 工具 | 用途 |\n|------|------|\n| ESLint | 代码检查 |\n| Prettier | 代码格式化 |\n| Husky | Git Hooks |\n| Commitlint | 提交信息规范 |\n| Docker | 容器化部署 |\n\n## 代码规范\n\n### 后端规范\n\n- 使用 DTO 模式进行数据传输\n- Controller 负责接收请求,Service 处理业务逻辑\n- 使用 @Validated 进行参数校验\n- 统一异常处理和响应格式\n- API 路径使用 kebab-case\n- 类名使用 PascalCase\n- 方法名使用 camelCase\n- 包路径: \\`${config.groupId}.<module-name>\\`\n\n### 前端规范\n\n- 组件使用 PascalCase\n- 文件名使用 kebab-case\n- 使用 TypeScript 类型定义\n- Props 接口定义在组件内部\n- 使用 Semantic HTML\n- 响应式设计优先\n\n### Git 规范\n\n- 分支命名: \\`feature/xxx\\`, \\`bugfix/xxx\\`, \\`hotfix/xxx\\`\n- 提交信息: \\`feat: xxx\\`, \\`fix: xxx\\`, \\`docs: xxx\\`\n- 提交前必须通过 lint 检查\n\n## 目录结构\n\n\\`\\`\\`\nbackend/\n${backendStructure}\n├── src/main/resources/\n│ ├── mapper/ # MyBatis XML\n│ └── application.yml # 配置文件\n└── src/test/ # 测试代码\n\n${config.includeFrontend ? `frontend/\n├── src/\n│ ├── app/ # Next.js App Router\n│ ├── components/ # React 组件\n│ ├── lib/ # 工具库\n│ └── types/ # TypeScript 类型\n└── public/ # 静态资源` : ''}\n\ndocs/\n├── prd-docs/ # PRD 需求文档\n├── specs/ # 功能规格文档\n├── api/ # API 文档\n└── sessions/ # 开发会话记录\n\\`\\`\\`\n`;\n\n await FileUtils.write(path.join(projectPath, 'TECH_STACK.md'), content);\n}\n\n/**\n * 生成开发规范文档\n */\nasync function generateConventions(projectPath: string, config: ProjectConfig): Promise<void> {\n const content = `# 开发规范\n\n## 包路径规范\n\n所有后端代码的包路径遵循: \\`${config.groupId}.<module-name>\\`\n\n示例:\n${config.modules.map(m => `- \\`${m.packagePath}\\``).join('\\n')}\n` + `\n\n## 后端开发规范\n\n### 1. 分层架构\n\n` + \"`\" + `` + `\nController → Service → Mapper → Database\n ↓ ↓\n DTO Entity\n` + \"`\" + `` + `\n\n**职责划分:**\n- **Controller**: 接收 HTTP 请求,参数校验,调用 Service\n- **Service**: 业务逻辑处理,事务管理\n- **Mapper**: 数据库操作,SQL 执行\n- **DTO**: 数据传输对象,用于 API 接口\n- **Entity**: 数据库实体映射\n\n### 2. 命名规范\n\n| 类型 | 规范 | 示例 |\n|------|------|------|\n| 类名 | PascalCase | \\`UserController\\` |\n| 方法名 | camelCase | \\`getUserById\\` |\n| 常量 | UPPER_SNAKE_CASE | \\`MAX_RETRY_COUNT\\` |\n| 包名 | 小写点分隔 | \\`com.example.demo.controller\\` |\n| API 路径 | kebab-case | \\`/api/users\\` |\n\n### 3. API 设计\n\n**RESTful 风格:**\n\n` + \"`\" + `` + `\nGET /api/users # 列表\nGET /api/users/{id} # 详情\nPOST /api/users # 创建\nPUT /api/users/{id} # 更新\nDELETE /api/users/{id} # 删除\n` + \"`\" + `` + `\n\n**统一响应格式:**\n\n` + \"```json\" + `\n{\n \"code\": 200,\n \"message\": \"success\",\n \"data\": {...}\n}\n` + \"```\" + `\n\n### 4. 异常处理\n\n使用 \\`@ControllerAdvice\\` 统一处理异常:\n\n` + \"```java\" + `\n@RestControllerAdvice\npublic class GlobalExceptionHandler {\n\n @ExceptionHandler(BusinessException.class)\n public Result<Void> handleBusinessException(BusinessException e) {\n return Result.error(e.getMessage());\n }\n}\n` + \"```\" + `\n\n### 5. 参数校验\n\n使用 \\`@Validated\\` 和 JSR-303 注解:\n\n` + \"```java\" + `\n@PostMapping(\"/users\")\npublic Result<User> createUser(@Validated @RequestBody UserDTO dto) {\n // ...\n}\n` + \"```\" + `\n\n### 6. 事务管理\n\n在 Service 层使用 \\`@Transactional\\`:\n\n` + \"```java\" + `\n@Service\npublic class UserService {\n\n @Transactional(rollbackFor = Exception.class)\n public void createUserWithRole(User user, Role role) {\n // ...\n }\n}\n` + \"```\" + `\n\n## 前端开发规范\n\n### 1. 组件设计\n\n**组件结构:**\n\n` + \"```typescript\" + `\n// 组件定义\ninterface Props {\n // props 类型定义\n}\n\nexport function ComponentName({ prop1, prop2 }: Props) {\n // 组件逻辑\n\n return (\n // JSX\n );\n}\n` + \"```\" + `\n\n**命名规范:**\n- 组件文件: kebab-case (\\`user-card.tsx\\`)\n- 组件名: PascalCase (\\`UserCard\\`)\n- Hook 文件: kebab-case, 以 \\`use-\\` 开头 (\\`use-user-data.ts\\`)\n\n### 2. TypeScript 使用\n\n**定义接口:**\n\n` + \"```typescript\" + `\ninterface User {\n id: string;\n name: string;\n email: string;\n}\n\ninterface CreateUserDto {\n name: string;\n email: string;\n}\n` + \"```\" + `\n\n**避免使用 \\`any\\`:**\n\n` + \"```typescript\" + `\n// ❌ 不好\nconst data: any = await fetchData();\n\n// ✅ 好\nconst data: User = await fetchData();\n` + \"```\" + `\n\n### 3. 状态管理\n\n**使用 React Context:**\n\n` + \"```typescript\" + `\nconst UserContext = createContext<UserContextType>({\n user: null,\n login: async () => {},\n logout: () => {},\n});\n` + \"```\" + `\n\n**优先使用本地状态:**\n\n` + \"```typescript\" + `\n// 简单状态使用 useState\nconst [count, setCount] = useState(0);\n\n// 复杂逻辑使用 useReducer\nconst [state, dispatch] = useReducer(reducer, initialState);\n` + \"```\" + `\n\n### 4. 样式规范\n\n**使用 Tailwind CSS:**\n\n\\`\\`\\`tsx\n<div className=\"flex items-center gap-4 p-4 bg-white rounded-lg\">\n {/* ... */}\n</div>\n\\`\\`\\`\n\n**响应式设计:**\n\n\\`\\`\\`tsx\n<div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {/* ... */}\n</div>\n\\`\\`\\`\n\n### 5. 表单处理\n\n**使用 React Hook Form:**\n\n\\`\\`\\`typescript\nconst { register, handleSubmit, formState: { errors } } = useForm<FormData>();\n\nconst onSubmit = (data: FormData) => {\n console.log(data);\n};\n\nreturn (\n <form onSubmit={handleSubmit(onSubmit)}>\n <input {...register('name', { required: true })} />\n {errors.name && <span>必填</span>}\n </form>\n);\n\\`\\`\\`\n\n### 6. 数据获取\n\n**使用 Server Components (Next.js 14):**\n\n\\`\\`\\`typescript\nasync function getUser(id: string) {\n const res = await fetch(\\`/api/users/\\${id}\\`);\n if (!res.ok) throw new Error('Failed to fetch');\n return res.json();\n}\n\nexport default async function UserPage({ params }) {\n const user = await getUser(params.id);\n return <div>{user.name}</div>;\n}\n\\`\\`\\`\n\n## Git 工作流\n\n### 分支策略\n\n\\`\\`\\`\nmain # 主分支,始终保持稳定\n ├── feature/xxx # 功能分支\n ├── bugfix/xxx # Bug 修复分支\n └── hotfix/xxx # 紧急修复分支\n\\`\\`\\`\n\n### 提交信息规范\n\n\\`\\`\\`\n<type>(<scope>): <subject>\n\n<body>\n\n<footer>\n\\`\\`\\`\n\n**类型 (type):**\n- \\`feat\\`: 新功能\n- \\`fix\\`: Bug 修复\n- \\`docs\\`: 文档更新\n- \\`style\\`: 代码格式调整\n- \\`refactor\\`: 代码重构\n- \\`test\\`: 测试相关\n- \\`chore\\`: 构建/工具相关\n\n**示例:**\n\n\\`\\`\\`\nfeat(auth): add user login feature\n\nimplement JWT based authentication with:\n- login endpoint\n- token refresh\n- logout handling\n\nCloses #123\n\\`\\`\\`\n\n## 测试规范\n\n### 后端测试\n\n\\`\\`\\`java\n@SpringBootTest\nclass UserServiceTest {\n\n @Autowired\n private UserService userService;\n\n @Test\n void shouldCreateUser() {\n // given\n User user = new User(\"John\");\n\n // when\n User saved = userService.save(user);\n\n // then\n assertNotNull(saved.getId());\n }\n}\n\\`\\`\\`\n\n### 前端测试\n\n\\`\\`\\`typescript\nimport { render, screen } from '@testing-library/react';\n\ntest('renders user name', () => {\n render(<UserProfile name=\"John\" />);\n expect(screen.getByText('John')).toBeInTheDocument();\n});\n\\`\\`\\`\n`;\n\n await FileUtils.write(path.join(projectPath, 'CONVENTIONS.md'), content);\n}\n\n/**\n * 生成 AI Memory\n */\nasync function generateAIMemory(projectPath: string, projectName: string): Promise<void> {\n const content = `# AI Memory - 项目状态记录\n\n## 项目信息\n- **项目名称**: ${projectName}\n- **创建时间**: ${new Date().toISOString().split('T')[0]}\n- **当前阶段**: 初始化\n- **最后更新**: ${new Date().toISOString().split('T')[0]}\n\n## 模板版本信息\n\n> 本部分由 team-cli 自动管理,记录使用的前后端模板版本\n\n| 类型 | 仓库 | Tag | Branch | Commit | 更新时间 |\n|------|------|-----|--------|--------|----------|\n| 前端 | - | - | - | - | - |\n| 后端 | - | - | - | - | - |\n\n## 功能清单 (Feature Inventory)\n\n| 功能 | Spec 文件 | 状态 | 进度 | 完成日期 | 备注 |\n|------|----------|------|------|---------|------|\n\n## API 列表 (API Inventory)\n\n> 本部分由 team-cli 自动扫描后端 Controller 生成\n\n## 数据模型概览\n\n| 表名 | 说明 | 字段数 | 关联表 | 状态 |\n|------|------|--------|--------|------|\n| user | 用户表 | - | - | - |\n\n## 已完成的 Milestones\n\n## 当前任务\n\n## 待处理任务\n\n## 技术债务\n\n| 日期 | 问题 | 计划修复 |\n|------|------|---------|\n\n## 关键决策记录\n\n| 日期 | 决策 | 原因 |\n|------|------|------|\n| ${new Date().toISOString().split('T')[0]} | 初始化项目 | 使用 Spring Boot 3 + Next.js 14 技术栈 |\n\n## 注意事项\n\n## Bugfix 记录\n\n| Bug ID | 日期 | 问题描述 | 状态 |\n|--------|------|---------|------|\n`;\n\n await FileUtils.write(path.join(projectPath, 'AI_MEMORY.md'), content);\n}\n\n/**\n * 生成 Spec 模板\n */\nasync function generateSpecTemplate(projectPath: string): Promise<void> {\n const content = `# [功能标题]\n\n## 功能概述\n**功能名称**: [功能中文名]\n**优先级**: P0/P1/P2\n**预估工时**: X 天\n**状态**: 待拆分\n**创建日期**: {{DATE}}\n\n## 依赖关系\n**前置依赖**:\n- [ ] dependency-1.md\n- [ ] dependency-2.md\n\n**被依赖于**:\n- (自动生成)\n\n## 背景与目标\n[简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n1. 功能点一\n2. 功能点二\n3. 功能点三\n\n## 技术设计\n\n### API 设计\n- \\`POST /api/xxx\\` - 创建 XXX\n- \\`GET /api/xxx/{id}\\` - 获取 XXX 详情\n- \\`PUT /api/xxx/{id}\\` - 更新 XXX\n- \\`DELETE /api/xxx/{id}\\` - 删除 XXX\n\n### 数据模型\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n\n> 注: 使用 \\`team-cli breakdown\\` 拆分此 spec 为 milestones 和 todos\n\n### Milestone 1: [里程碑名称]\n- [ ] Todo 1\n- [ ] Todo 2\n- [ ] Todo 3\n\n### Milestone 2: [里程碑名称]\n- [ ] Todo 1\n- [ ] Todo 2\n\n----\n*生成于: {{TIMESTAMP}} by team-cli*\n`;\n\n await FileUtils.write(path.join(projectPath, 'docs/specs/template.md'), content);\n}\n\n/**\n * 克隆后端模板\n */\nasync function cloneBackendTemplate(\n projectPath: string,\n versionOptions?: {\n tag?: string;\n branch?: string;\n }\n): Promise<void> {\n const templateRepo = process.env.TEMPLATE_REPO || 'git@gitlab.yungu-inc.org:yungu-app/java-scaffold-template.git';\n const backendPath = path.join(projectPath, 'backend');\n\n try {\n const { execa: e } = await import('execa');\n const tempDir = path.join(projectPath, '.template-temp');\n\n // 如果指定了 tag 或 branch,先验证\n if (versionOptions?.tag || versionOptions?.branch) {\n const { userConfigManager } = await import('../lib/user-config.js');\n const { GitLabAPI } = await import('../lib/gitlab-api.js');\n\n const config = await userConfigManager.getGitLabConfig();\n if (config) {\n const gitlabAPI = new GitLabAPI(config);\n const projectPathEncoded = GitLabAPI.parseProjectPath(templateRepo);\n\n if (versionOptions.tag) {\n const isValid = await gitlabAPI.validateTag(projectPathEncoded, versionOptions.tag);\n if (!isValid) {\n logger.error(`后端模板 tag \"${versionOptions.tag}\" 不存在`);\n process.exit(1);\n }\n logger.info(`使用后端模板 tag: ${versionOptions.tag}`);\n }\n\n if (versionOptions.branch) {\n const isValid = await gitlabAPI.validateBranch(projectPathEncoded, versionOptions.branch);\n if (!isValid) {\n logger.error(`后端模板分支 \"${versionOptions.branch}\" 不存在`);\n process.exit(1);\n }\n logger.info(`使用后端模板分支: ${versionOptions.branch}`);\n }\n } else {\n logger.warn('未配置 GitLab Token,跳过版本验证');\n }\n }\n\n // 确定要克隆的 ref\n \n logger.info(`正在克隆后端模板 (${versionOptions?.tag || versionOptions?.branch || 'latest'})...`);\n\n const cloneArgs = ['clone', '--depth=1'];\n if (versionOptions?.tag || versionOptions?.branch) {\n cloneArgs.push('--branch', versionOptions.tag || versionOptions.branch!);\n }\n cloneArgs.push(templateRepo, tempDir);\n\n await e('git', cloneArgs, {\n stdio: 'inherit',\n timeout: 60000,\n });\n\n // 获取 commit 和 tag\n const { stdout: commit } = await e('git', ['rev-parse', 'HEAD'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n const { stdout: tags } = await e('git', ['tag', '-l', '--sort=-v:refname'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n const latestTag = tags.split('\\n')[0] || undefined;\n\n // 复制内容(排除 .git)\n await fs.copy(tempDir, backendPath, {\n filter: (src) => !src.includes('.git'),\n });\n\n // 删除临时目录\n await fs.remove(tempDir);\n\n // 删除 .git 目录\n const gitDir = path.join(backendPath, '.git');\n if (await FileUtils.exists(gitDir)) {\n await FileUtils.remove(gitDir);\n }\n\n // 保存模板版本信息\n await initTemplateConfig(projectPath);\n await updateTemplateVersion(projectPath, 'backend', commit.trim(), {\n tag: versionOptions?.tag || latestTag,\n branch: versionOptions?.branch,\n });\n } catch (error) {\n logger.warn('克隆后端模板失败,创建基础结构');\n await FileUtils.ensureDir(path.join(backendPath, 'src/main/java/com/example'));\n await FileUtils.ensureDir(path.join(backendPath, 'src/main/resources'));\n await FileUtils.ensureDir(path.join(backendPath, 'src/test/java'));\n }\n}\n\n/**\n * 克隆前端模板\n */\nasync function cloneFrontendTemplate(\n projectPath: string,\n versionOptions: { tag?: string; branch?: string } = {}\n): Promise<void> {\n const frontendPath = path.join(projectPath, 'frontend');\n const templates = getDefaultTemplates();\n const repository = templates.frontend.repository;\n\n try {\n const { execa: e } = await import('execa');\n \n // 获取最新 tag (如果没有指定)\n let latestTag = '';\n if (!versionOptions.tag && !versionOptions.branch) {\n latestTag = await getLatestTag(repository);\n }\n\n const targetVersion = versionOptions.branch || versionOptions.tag || latestTag;\n \n logger.info(`正在克隆前端模板 (${targetVersion || 'HEAD'})...`);\n\n // 创建临时目录进行克隆\n const tempDir = path.join(os.tmpdir(), `team-cli-fe-${Date.now()}`);\n await FileUtils.ensureDir(tempDir);\n\n const cloneArgs = ['clone', '--depth', '1'];\n if (targetVersion) {\n cloneArgs.push('--branch', targetVersion);\n }\n cloneArgs.push(repository, tempDir);\n \n await e('git', cloneArgs);\n\n // 获取 commit 信息\n const { stdout: commit } = await e('git', ['rev-parse', 'HEAD'], { cwd: tempDir });\n\n // 复制内容(排除 .git)\n await fs.copy(tempDir, frontendPath, {\n filter: (src) => !src.includes('.git'),\n });\n\n // 删除临时目录\n await fs.remove(tempDir);\n\n // 记录模板版本信息\n await updateTemplateVersion(projectPath, 'frontend', commit.trim(), {\n tag: versionOptions.tag || latestTag,\n branch: versionOptions.branch,\n });\n\n logger.success('前端模板克隆完成');\n } catch (error) {\n logger.warn('克隆前端模板失败,将创建基础结构');\n await FileUtils.ensureDir(path.join(frontendPath, 'src/app'));\n await FileUtils.ensureDir(path.join(frontendPath, 'src/components'));\n }\n}\n\n/**\n * 根据配置创建后端多模块结构\n */\nasync function createBackendFromConfig(\n projectPath: string,\n config: ProjectConfig\n): Promise<void> {\n const backendPath = path.join(projectPath, 'backend');\n\n logger.info(`正在创建后端多模块结构...`);\n\n // 1. 创建根目录\n await FileUtils.ensureDir(backendPath);\n\n // 2. 创建 settings.gradle\n await createSettingsGradle(backendPath, config);\n\n // 3. 创建根 build.gradle\n await createRootBuildGradle(backendPath, config);\n\n // 4. 创建各模块\n for (const module of config.modules) {\n await createModuleFromConfig(backendPath, module, config);\n }\n\n // 5. 创建公共模块 (common)\n if (config.modules.length > 0) {\n await createCommonModule(backendPath, config);\n }\n\n logger.success('后端结构创建完成');\n}\n\n/**\n * 创建 settings.gradle\n */\nasync function createSettingsGradle(backendPath: string, config: ProjectConfig): Promise<void> {\n const lines: string[] = [];\n lines.push(`rootProject.name = '${config.rootProjectName}'`);\n lines.push('');\n\n // 添加所有模块\n const allModules = ['common', ...config.modules.map(m => m.name)].sort();\n for (const module of allModules) {\n lines.push(`include '${module}'`);\n }\n\n await FileUtils.write(path.join(backendPath, 'settings.gradle'), lines.join('\\n'));\n logger.info('settings.gradle 已创建');\n}\n\n/**\n * 创建根 build.gradle\n */\nasync function createRootBuildGradle(backendPath: string, config: ProjectConfig): Promise<void> {\n const content = `plugins {\n id 'java' version '8' apply false\n}\n\nallprojects {\n group = '${config.groupId}'\n version = '0.0.1-SNAPSHOT'\n\n repositories {\n maven { url 'https://maven.aliyun.com/repository/public/' }\n }\n}\n\nsubprojects {\n apply plugin: 'java'\n apply plugin: 'org.springframework.boot'\n apply plugin: 'io.spring.dependency-management'\n\n sourceCompatibility = '${config.javaVersion}'\n targetCompatibility = '${config.javaVersion}'\n\n dependencies {\n implementation 'org.springframework.boot:spring-boot-starter-web'\n implementation 'org.springframework.boot:spring-boot-starter-logging'\n compileOnly \"org.projectlombok:lombok\"\n annotationProcessor \"org.projectlombok:lombok\"\n testCompileOnly \"org.projectlombok:lombok\"\n testAnnotationProcessor \"org.projectlombok:lombok\"\n }\n}\n`;\n await FileUtils.write(path.join(backendPath, 'build.gradle'), content);\n logger.info('build.gradle (root) 已创建');\n}\n\n/**\n * 从配置创建单个模块\n */\nasync function createModuleFromConfig(\n backendPath: string,\n module: ModuleConfig,\n config: ProjectConfig\n): Promise<void> {\n const modulePath = path.join(backendPath, module.name);\n const packagePath = module.packagePath.split('.');\n\n logger.info(`创建模块: ${module.name} (${module.type})...`);\n\n // 创建目录结构\n const baseDirs = [\n 'src/main/java',\n 'src/main/resources',\n 'src/test/java',\n ];\n\n for (const dir of baseDirs) {\n await FileUtils.ensureDir(path.join(modulePath, dir));\n }\n\n // 根据类型创建子目录\n let subDirs: string[] = [];\n if (module.type === 'service') {\n subDirs = ['controller', 'service', 'mapper', 'entity', 'dto', 'config'];\n } else if (module.type === 'api') {\n subDirs = ['model', 'constant', 'enums', 'exception'];\n } else {\n subDirs = ['util', 'common', 'config', 'manager'];\n }\n\n let javaPath = path.join(modulePath, 'src', 'main', 'java');\n for (const subDir of subDirs) {\n await FileUtils.ensureDir(path.join(javaPath, ...packagePath, subDir));\n }\n\n // 创建 Application 启动类\n await createApplicationClass(\n path.join(javaPath, ...packagePath, 'config', `${module.applicationClass}.java`),\n module.packagePath,\n module.applicationClass\n );\n\n // 创建 build.gradle\n await createModuleBuildGradle(modulePath, module, config);\n\n logger.success(`模块 ${module.name} 创建完成`);\n}\n\n/**\n * 创建 Application 启动类\n */\nasync function createApplicationClass(\n filePath: string,\n packagePath: string,\n className: string\n): Promise<void> {\n const content = `package ${packagePath}.config;\n\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.annotation.ComponentScan;\n\n@SpringBootApplication\n@ComponentScan(\"${packagePath}\")\n@Slf4j\npublic class ${className} {\n\n public static void main(String[] args) {\n ApplicationContext context = SpringApplication.run(${className}.class, args);\n log.info(\"${className} 启动成功!\");\n }\n}\n`;\n await FileUtils.ensureDir(path.dirname(filePath));\n await FileUtils.write(filePath, content);\n}\n\n/**\n * 创建模块 build.gradle\n */\nasync function createModuleBuildGradle(\n modulePath: string,\n module: ModuleConfig,\n config: ProjectConfig\n): Promise<void> {\n let applyPlugins = `plugins {\n id 'java-library'\n id 'org.springframework.boot'\n id 'io.spring.dependency-management'\n}\n\ngroup = '${config.groupId}'\nversion = '0.0.1-SNAPSHOT'\n\njava {\n sourceCompatibility = '${config.javaVersion}'\n targetCompatibility = '${config.javaVersion}'\n}\n\nrepositories {\n maven { url 'https://maven.aliyun.com/repository/public/' }\n}\n`;\n\n let dependencies = '';\n if (module.type === 'service') {\n dependencies = `\ndependencies {\n implementation project(\":common\")\n implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter'\n implementation 'com.alibaba:druid-spring-boot-starter'\n implementation 'org.springframework.boot:spring-boot-starter-validation'\n compileOnly \"org.projectlombok:lombok\"\n annotationProcessor \"org.projectlombok:lombok\"\n testCompileOnly \"org.projectlombok:lombok\"\n testAnnotationProcessor \"org.projectlombok:lombok\"\n}\n`;\n } else if (module.type === 'api') {\n dependencies = `\ndependencies {\n compileOnly 'org.springframework.boot:spring-boot-starter'\n compileOnly \"org.projectlombok:lombok\"\n annotationProcessor \"org.projectlombok:lombok\"\n}\n`;\n } else {\n dependencies = `\ndependencies {\n implementation 'org.springframework.boot:spring-boot-starter'\n implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter'\n implementation 'org.apache.commons:commons-lang3:3.12.0'\n compileOnly \"org.projectlombok:lombok\"\n annotationProcessor \"org.projectlombok:lombok\"\n}\n`;\n }\n\n await FileUtils.write(path.join(modulePath, 'build.gradle'), applyPlugins + dependencies);\n}\n\n/**\n * 创建 common 公共模块\n */\nasync function createCommonModule(backendPath: string, config: ProjectConfig): Promise<void> {\n const modulePath = path.join(backendPath, 'common');\n const packagePath = config.groupId.split('.');\n const subDirs = ['util', 'common', 'config', 'manager', 'constant', 'enums', 'exception'];\n\n logger.info('创建公共模块: common...');\n\n // 创建目录\n for (const dir of ['src/main/java', 'src/main/resources', 'src/test/java']) {\n await FileUtils.ensureDir(path.join(modulePath, dir));\n }\n\n let javaPath = path.join(modulePath, 'src', 'main', 'java');\n for (const subDir of subDirs) {\n await FileUtils.ensureDir(path.join(javaPath, ...packagePath, subDir));\n }\n\n // 创建 build.gradle\n await createModuleBuildGradle(modulePath, {\n name: 'common',\n type: 'common',\n packagePath: `${config.groupId}.common`,\n applicationClass: '',\n }, config);\n\n logger.success('公共模块 common 创建完成');\n}\n\n/**\n * 生成 Docker 配置 (支持阿里云镜像仓库和 Gradle 构建)\n */\nasync function generateDockerFiles(projectPath: string, projectName: string): Promise<void> {\n const backendPath = path.join(projectPath, 'backend');\n \n if (!(await FileUtils.exists(backendPath))) {\n logger.warn('未找到 backend 目录,跳过 Docker 配置生成');\n return;\n }\n\n // 1. Dockerfile\n const dockerfile = `FROM openjdk:17-jdk-slim\nWORKDIR /app\nCOPY build/libs/*.jar app.jar\nEXPOSE 8080\nENTRYPOINT [\"java\", \"-Djava.security.egd=file:/dev/./urandom\", \"-jar\", \"app.jar\"]\n`;\n \n // 2. 部署脚本 (Aliyun Registry + Gradle)\n const deploySh = `#!/bin/bash\n# yg-team-cli 自动生成的部署脚本\n# 偏好:Aliyun 镜像仓库, Gradle 构建, 刷新依赖, 跳过测试\n\nPROJECT_NAME=\"${projectName}\"\nTIMESTAMP=$(date +%Y%m%d%H%M%S)\nREGISTRY=\"registry.cn-hangzhou.aliyuncs.com/yungu-app\"\nIMAGE_TAG=\"\\${PROJECT_NAME}:\\${TIMESTAMP}\"\n\necho \"🐘 开始 Gradle 构建 (跳过测试, 刷新依赖)...\"\n./gradlew clean build -x test --refresh-dependencies\n\nif [ $? -ne 0 ]; then\n echo \"❌ 构建失败,请检查代码\"\n exit 1\nfi\n\necho \"🐳 构建 Docker 镜像...\"\ndocker build -t \\${REGISTRY}/\\${IMAGE_TAG} .\ndocker tag \\${REGISTRY}/\\${IMAGE_TAG} \\${REGISTRY}/\\${PROJECT_NAME}:latest\n\necho \"🚀 推送镜像到阿里云...\"\ndocker push \\${REGISTRY}/\\${IMAGE_TAG}\ndocker push \\${REGISTRY}/\\${PROJECT_NAME}:latest\n\necho \"✅ 部署完成! 镜像地址: \\${REGISTRY}/\\${IMAGE_TAG}\"\n`;\n\n await fs.writeFile(path.join(backendPath, 'Dockerfile'), dockerfile);\n await fs.writeFile(path.join(backendPath, 'deploy.sh'), deploySh);\n await fs.chmod(path.join(backendPath, 'deploy.sh'), 0o755);\n}\n\n/**\n * 初始化 Git\n */\nasync function initGit(projectPath: string, projectName: string): Promise<void> {\n try {\n const { execa: e } = await import('execa');\n\n await e('git', ['init'], { cwd: projectPath, stdio: 'pipe' });\n await e('git', ['add', '.'], { cwd: projectPath, stdio: 'pipe' });\n await e(\n 'git',\n ['commit', '-m', `feat: initialize ${projectName} project with team-cli`],\n { cwd: projectPath, stdio: 'pipe' }\n );\n\n logger.success('Git 仓库初始化完成');\n } catch (error: any) {\n logger.warn(`Git 初始化失败: ${error.message}`);\n }\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { Listr } from 'listr2';\n\n/**\n * Breakdown 命令 - 将 spec 拆分为 milestones 和 todos\n */\nexport const breakdownCommand = new Command('breakdown')\n .argument('[spec-file]', 'Spec 文件路径')\n .description('将 spec 拆分为 milestones 和 todos')\n .action(async (specFile) => {\n try {\n logger.header('Spec 拆分');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info('请先运行 team-cli init 或切换到项目目录');\n process.exit(1);\n }\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 扫描 spec 文件\n const tasks = new Listr([\n {\n title: '扫描 spec 文件',\n task: async (ctx) => {\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n if (!exists) {\n throw new Error(`specs 目录不存在: ${specDir}`);\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n ctx.specs = files.filter((f) => !f.includes('template'));\n },\n },\n {\n title: '选择 spec 文件',\n task: async (ctx) => {\n if (!ctx.specs || ctx.specs.length === 0) {\n throw new Error('未找到 spec 文件');\n }\n\n // 如果没有指定文件,交互式选择\n if (!specFile) {\n const { selectedFile } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedFile',\n message: '请选择要拆分的 spec 文件:',\n choices: ctx.specs,\n },\n ]);\n ctx.selectedFile = path.join('docs/specs', selectedFile);\n return;\n }\n\n // 验证指定的文件\n const fullPath = specFile.startsWith('docs/specs/')\n ? specFile\n : path.join('docs/specs', specFile);\n\n const exists = await FileUtils.exists(fullPath);\n if (!exists) {\n throw new Error(`Spec 文件不存在: ${specFile}`);\n }\n\n ctx.selectedFile = fullPath;\n },\n },\n {\n title: '读取 spec 内容',\n task: async (ctx) => {\n ctx.specContent = await FileUtils.read(ctx.selectedFile);\n logger.success(`已选择: ${ctx.selectedFile}`);\n },\n },\n {\n title: '调用 Claude 拆分 spec',\n task: async (ctx) => {\n const prompt = buildBreakdownPrompt(ctx.specContent);\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 执行中...');\n logger.separator('─', 60);\n logger.newLine();\n\n // 调用 Claude 执行拆分\n const result = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md'],\n });\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n ctx.breakdownResult = result;\n },\n },\n {\n title: '更新 spec 文件',\n task: async (ctx) => {\n // 精确合并里程碑内容\n const mergedContent = mergeMilestones(ctx.specContent, ctx.breakdownResult);\n await FileUtils.write(ctx.selectedFile, mergedContent);\n },\n },\n ]);\n// ... (rest of the run sequence)\n try {\n const ctx = await tasks.run();\n\n logger.newLine();\n logger.header('Spec 拆分完成!');\n logger.success(`Milestones 已添加到: ${ctx.selectedFile}`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step('1. 检查拆分结果,根据需要调整');\n logger.step(\"2. 运行 'team-cli dev' 选择 milestone 进行开发\");\n logger.newLine();\n } catch (error: any) {\n if (error.message) {\n logger.error(error.message);\n }\n throw error;\n }\n } catch (error: any) {\n logger.error(`拆分失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 合并里程碑到原 spec 内容中\n */\nfunction mergeMilestones(original: string, milestones: string): string {\n const milestoneHeader = '## 里程碑 (Milestones)';\n const lines = original.split('\\n');\n const headerIndex = lines.findIndex(l => l.trim().startsWith(milestoneHeader));\n\n // 清理里程碑内容,确保它以 ## 里程碑 (Milestones) 开头\n let cleanedMilestones = milestones.trim();\n if (!cleanedMilestones.startsWith('## ')) {\n // 可能是 Claude 没带标题,或者带了其他前缀\n const firstHeaderIndex = cleanedMilestones.indexOf('## ');\n if (firstHeaderIndex !== -1) {\n cleanedMilestones = cleanedMilestones.substring(firstHeaderIndex);\n } else {\n // 完全没标题,我们给它加上\n cleanedMilestones = `${milestoneHeader}\\n\\n${cleanedMilestones}`;\n }\n }\n\n if (headerIndex !== -1) {\n // 1. 替换原有里程碑部分\n const beforePart = lines.slice(0, headerIndex).join('\\n');\n const afterPart = lines.slice(headerIndex + 1);\n \n // 找到下一个二级标题\n const nextHeaderIndex = afterPart.findIndex(l => l.trim().startsWith('## '));\n \n if (nextHeaderIndex !== -1) {\n const remaining = afterPart.slice(nextHeaderIndex).join('\\n');\n return `${beforePart.trim()}\\n\\n${cleanedMilestones}\\n\\n${remaining.trim()}`;\n } else {\n // 后面没有二级标题了,直接跟在前面部分后面\n return `${beforePart.trim()}\\n\\n${cleanedMilestones}`;\n }\n }\n\n // 2. 插入到“技术设计”之后\n const techDesignHeader = '## 技术设计';\n const techIndex = lines.findIndex(l => l.trim().startsWith(techDesignHeader));\n if (techIndex !== -1) {\n // 找到本节的结尾(下一个二级标题之前)\n const afterTech = lines.slice(techIndex + 1);\n const nextHeaderIndex = afterTech.findIndex(l => l.trim().startsWith('## '));\n \n if (nextHeaderIndex !== -1) {\n const splitPoint = techIndex + 1 + nextHeaderIndex;\n const before = lines.slice(0, splitPoint).join('\\n');\n const after = lines.slice(splitPoint).join('\\n');\n return `${before.trim()}\\n\\n${cleanedMilestones}\\n\\n${after.trim()}`;\n }\n }\n\n // 3. 兜底:追加到末尾\n return `${original.trim()}\\n\\n${cleanedMilestones}`;\n}\n\n/**\n * 构建拆分 prompt\n */\nfunction buildBreakdownPrompt(specContent: string): string {\n return `Role: Senior Technical Lead and Agile Coach\n\nTask: Break down the following feature spec into milestones with frontend, backend, and integration tasks.\n\nContext:\n- Read TECH_STACK.md for technology constraints\n- Read CONVENTIONS.md for coding standards\n- Each milestone should be completable in 1-3 days\n- Each todo should be a concrete, actionable task\n\nSpec Content:\n\\`\\`\\`\n${specContent}\n\\`\\`\\`\n\nOutput Requirements:\n1. Parse the existing spec content and identify technical requirements.\n2. Break it down into 2-5 milestones.\n3. Each milestone must have three sections:\n - **前端任务**: Frontend tasks marked with [F] prefix\n - **后端任务**: Backend tasks marked with [B] prefix, include API associations\n - **联调任务**: Integration tasks marked with [I] prefix, include dependencies\n4. Todo items should be:\n - Concrete, specific, and testable\n - Independent as much as possible\n\nTask Prefix Format:\n- Frontend: \\`- [ ] [F] 具体的前端任务描述\\`\n- Backend: \\`- [ ] [B] 具体的后端任务描述 (关联 API: \\`METHOD /api/path\\`)\\`\n- Integration: \\`- [ ] [I] 联调任务描述 (依赖: F-x, B-y)\\`\n\nIMPORTANT:\n- Output ONLY the \"## 里程碑 (Milestones)\" section.\n- Do NOT output the entire spec file.\n- Do NOT output any preamble or postamble text.\n- Follow this exact format:\n\n\\`\\`\\`markdown\n## 里程碑 (Milestones)\n\n### Milestone 1: [里程碑名称]\n**目标**: [简短描述这个里程碑的目标]\n**预估**: 2 天\n\n**前端任务**:\n- [ ] [F] 前端任务描述 1\n- [ ] [F] 前端任务描述 2\n\n**后端任务**:\n- [ ] [B] 后端任务描述 1 (关联 API: \\`POST /api/xxx\\`)\n- [ ] [B] 后端任务描述 2 (关联 API: \\`GET /api/yyy\\`)\n\n**联调任务**:\n- [ ] [I] 联调任务描述 1 (依赖: F-1, B-1)\n\n### Milestone 2: [里程碑名称]\n...\n\\`\\`\\`\n`;\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils, SpecUtils, EnhancedMilestoneInfo, TodoItem } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\n\ninterface SpecInfo {\n file: string;\n name: string;\n status: '未开始' | '进行中' | '已拆分' | '已完成';\n dependencies: string[];\n index: number;\n}\n\n/**\n * Dev 命令 - 开发模式\n */\nexport const devCommand = new Command('dev')\n .description('开发模式,执行具体任务')\n .action(async () => {\n try {\n logger.header('开发模式');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n logger.success('检测到项目上下文');\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 步骤 1: 扫描并选择 spec\n const selectedSpec = await selectSpec();\n\n // 步骤 2: 解析并选择 milestone\n const selectedMilestone = await selectMilestone(selectedSpec);\n\n // 步骤 3: 选择 todo(如果选择了具体 milestone)\n const selectedTodo = await selectTodo(selectedSpec, selectedMilestone);\n\n // 步骤 4: 调用 Claude 执行开发\n await executeDevelopment(selectedSpec, selectedMilestone, selectedTodo);\n } catch (error: any) {\n logger.error(`开发模式执行失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 步骤 1: 选择 spec 文件\n */\nasync function selectSpec(): Promise<string> {\n logger.step('步骤 1/3: 选择 spec 文件...');\n logger.newLine();\n\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n if (!exists) {\n throw new Error('docs/specs 目录不存在');\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n const specFiles = files.filter((f) => !f.includes('template'));\n\n if (specFiles.length === 0) {\n throw new Error('未找到 spec 文件');\n }\n\n // 解析 spec 信息(状态、依赖)\n const specs: SpecInfo[] = [];\n for (let i = 0; i < specFiles.length; i++) {\n const file = path.join(specDir, specFiles[i]);\n const spec = await FileUtils.read(file);\n\n const status = SpecUtils.parseSpecStatus(spec);\n const dependencies = parseDependencies(spec);\n\n specs.push({\n file,\n name: specFiles[i],\n status,\n dependencies,\n index: i,\n });\n }\n\n // 拓扑排序推荐开发顺序\n const sortedSpecs = topologicalSort(specs);\n\n // 显示选项\n logger.info('可用的 spec 文件:');\n logger.newLine();\n\n const choices = sortedSpecs.map((spec, idx) => {\n const statusIcon = getStatusIcon(spec.status);\n const recommendInfo = idx === 0 ? '[推荐从这开始] ' : '';\n const depInfo =\n spec.dependencies.length > 0 ? `[依赖: ${spec.dependencies.join(', ')}] ` : '';\n\n return {\n name: `${statusIcon} [${spec.status}] ${recommendInfo}${depInfo}${spec.name}`,\n value: spec.file,\n short: spec.name,\n };\n });\n\n logger.info(' ✓ = 已完成 ⟳ = 进行中 ◉ = 已拆分 ○ = 未开始');\n logger.info(' 根据依赖关系推荐的开发顺序已标注');\n logger.newLine();\n\n const { selectedFile } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedFile',\n message: '选择要开发的 spec:',\n choices,\n },\n ]);\n\n logger.success(`已选择: ${selectedFile}`);\n return selectedFile;\n}\n\n/**\n * 步骤 2: 解析并选择 milestone\n */\nasync function selectMilestone(specFile: string): Promise<string> {\n logger.newLine();\n logger.step('步骤 2/3: 解析 milestones...');\n logger.newLine();\n\n const specContent = await FileUtils.read(specFile);\n\n // 尝试增强解析\n const { enhanced, isEnhanced } = SpecUtils.parseMilestonesEnhancedWithFallback(specContent);\n\n if (enhanced.length === 0) {\n logger.info('该 spec 尚未拆分 milestones');\n\n const { breakdownNow } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'breakdownNow',\n message: '是否现在拆分?',\n default: true,\n },\n ]);\n\n if (breakdownNow) {\n // 调用 breakdown 命令\n logger.info('正在调用 breakdown...');\n // TODO: 调用 breakdown 命令\n throw new Error('breakdown 命令需要进一步实现');\n } else {\n logger.info('将直接实现整个 spec');\n return '整个 spec';\n }\n }\n\n // 显示 milestones\n const choices = enhanced.map((m, idx) => {\n const isDone = m.completedCount === m.totalCount && m.totalCount > 0;\n const statusIcon = isDone ? '✓' : m.completedCount > 0 ? '⟳' : '○';\n const progress = `[${m.completedCount}/${m.totalCount}]`;\n const label = isDone ? `✓ ${m.title}` : `${statusIcon} ${progress} ${m.title}`;\n\n // 如果是增强格式,显示更详细的信息\n let detailInfo = `(${m.totalCount} 个任务)`;\n if (isEnhanced) {\n const fCount = m.frontendTodos.filter(t => !t.isCompleted).length;\n const bCount = m.backendTodos.filter(t => !t.isCompleted).length;\n const iCount = m.integrationTodos.filter(t => !t.isCompleted).length;\n const details = [];\n if (fCount > 0) details.push(`前端:${fCount}`);\n if (bCount > 0) details.push(`后端:${bCount}`);\n if (iCount > 0) details.push(`联调:${iCount}`);\n if (details.length > 0) {\n detailInfo = `(${details.join(', ')} 未完成)`;\n }\n }\n\n return {\n name: `${idx + 1}. ${label} ${detailInfo}`,\n value: m.title,\n short: m.title,\n };\n });\n\n choices.push({\n name: `${enhanced.length + 1}. 整个 spec (全部 milestones)`,\n value: '整个 spec',\n short: '整个 spec',\n });\n\n const { milestone } = await inquirer.prompt([\n {\n type: 'list',\n name: 'milestone',\n message: '选择 milestone:',\n choices,\n },\n ]);\n\n return milestone;\n}\n\n/**\n * 步骤 3: 选择 todo 任务\n */\nasync function selectTodo(\n specFile: string,\n milestone: string\n): Promise<string> {\n if (milestone === '整个 spec') {\n return '全部功能';\n }\n\n logger.newLine();\n logger.step('步骤 3/3: 选择 todo 任务...');\n logger.newLine();\n\n const specContent = await FileUtils.read(specFile);\n\n // 尝试增强解析\n const { enhanced, isEnhanced } = SpecUtils.parseMilestonesEnhancedWithFallback(specContent);\n const targetMilestone = enhanced.find(m => m.title === milestone);\n\n // 如果增强解析失败或没有增强格式,回退到简单解析\n if (!targetMilestone || !isEnhanced) {\n return await selectTodoSimple(specFile, milestone);\n }\n\n // 使用增强格式显示\n return await selectTodoEnhanced(targetMilestone);\n}\n\n/**\n * 增强版 todo 选择\n */\nasync function selectTodoEnhanced(milestone: EnhancedMilestoneInfo): Promise<string> {\n const choices: any[] = [];\n\n // 前端任务\n if (milestone.frontendTodos.length > 0) {\n choices.push({ name: `━━ 前端任务 (${milestone.frontendTodos.length}) ━━`, disabled: true });\n milestone.frontendTodos.forEach((todo, idx) => {\n const icon = todo.isCompleted ? '[x]' : '[ ]';\n choices.push({\n name: ` [F] ${icon} ${todo.content}`,\n value: todo.content,\n short: `[F] ${todo.content}`,\n });\n });\n }\n\n // 后端任务\n if (milestone.backendTodos.length > 0) {\n choices.push({ name: `━━ 后端任务 (${milestone.backendTodos.length}) ━━`, disabled: true });\n milestone.backendTodos.forEach((todo, idx) => {\n const icon = todo.isCompleted ? '[x]' : '[ ]';\n const apiInfo = todo.apiAssociation ? ` (${todo.apiAssociation})` : '';\n choices.push({\n name: ` [B] ${icon} ${todo.content}${apiInfo}`,\n value: todo.content,\n short: `[B] ${todo.content}`,\n });\n });\n }\n\n // 联调任务\n if (milestone.integrationTodos.length > 0) {\n choices.push({ name: `━━ 联调任务 (${milestone.integrationTodos.length}) ━━`, disabled: true });\n milestone.integrationTodos.forEach((todo, idx) => {\n const icon = todo.isCompleted ? '[x]' : '[ ]';\n const depsInfo = todo.dependencies ? ` (依赖: ${todo.dependencies.join(', ')})` : '';\n choices.push({\n name: ` [I] ${icon} ${todo.content}${depsInfo}`,\n value: todo.content,\n short: `[I] ${todo.content}`,\n });\n });\n }\n\n // 通用任务\n if (milestone.generalTodos.length > 0) {\n choices.push({ name: `━━ 通用任务 (${milestone.generalTodos.length}) ━━`, disabled: true });\n milestone.generalTodos.forEach((todo, idx) => {\n const icon = todo.isCompleted ? '[x]' : '[ ]';\n choices.push({\n name: ` ${icon} ${todo.content}`,\n value: todo.content,\n short: todo.content,\n });\n });\n }\n\n choices.push({ name: '━━ 其他 ━━', disabled: true });\n choices.push({\n name: `全部任务 (整个 milestone)`,\n value: '全部任务',\n short: '全部任务',\n });\n\n const { todo } = await inquirer.prompt([\n {\n type: 'list',\n name: 'todo',\n message: '选择 todo 任务:',\n choices,\n },\n ]);\n\n return todo;\n}\n\n/**\n * 简单版 todo 选择(向后兼容)\n */\nasync function selectTodoSimple(\n specFile: string,\n milestone: string\n): Promise<string> {\n const specContent = await FileUtils.read(specFile);\n const milestones = SpecUtils.parseMilestones(specContent);\n const targetMilestone = milestones.find(m => m.title === milestone);\n const todos = targetMilestone ? targetMilestone.todos : [];\n\n if (todos.length === 0) {\n logger.warn('该 milestone 没有 todo 任务');\n const { implementAll } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'implementAll',\n message: '实现整个 milestone?',\n default: true,\n },\n ]);\n\n return implementAll ? '全部功能' : milestone;\n }\n\n const choices = todos.map((todo, idx) => ({\n name: `${idx + 1}. ${todo}`,\n value: todo,\n short: todo,\n }));\n\n choices.push({\n name: `${todos.length + 1}. 全部任务 (整个 milestone)`,\n value: '全部任务',\n short: '全部任务',\n });\n\n const { todo } = await inquirer.prompt([\n {\n type: 'list',\n name: 'todo',\n message: '选择 todo 任务:',\n choices,\n },\n ]);\n\n return todo;\n}\n\n/**\n * 步骤 4: 调用 Claude 执行开发\n */\nasync function executeDevelopment(\n specFile: string,\n milestone: string,\n todo: string\n): Promise<void> {\n logger.newLine();\n logger.step('构建 Prompt 并调用 Claude...');\n\n let taskDescription: string;\n if (milestone === '整个 spec') {\n taskDescription = '实现整个 spec 的所有功能';\n } else if (todo === '全部功能' || todo === '全部任务') {\n taskDescription = `实现 milestone '${milestone}' 的所有任务`;\n } else {\n taskDescription = `实现 milestone '${milestone}' 的任务: ${todo}`;\n }\n\n const prompt = buildDevPrompt(specFile, milestone, todo, taskDescription);\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('即将调用 Claude AI...');\n logger.separator('─', 60);\n logger.newLine();\n logger.info(` 任务描述: ${taskDescription}`);\n logger.info(` Spec 文件: ${specFile}`);\n logger.newLine();\n logger.info('📝 Claude 将在下方打开交互界面');\n logger.newLine();\n logger.info('⚠️ 重要提示:');\n logger.info(' 1. 在 Claude 中完成开发任务');\n logger.info(' 2. 按 \"a\" 接受所有编辑建议,或逐个选择');\n logger.info(' 3. 完成后使用 Ctrl+D 或输入 :exit 退出 Claude');\n logger.newLine();\n\n // 调用 Claude 执行开发 (交互式)\n await claudeAI.runTerminal(prompt);\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n // 生成会话日志 (交互式模式下记录任务元数据)\n await generateSessionLog(specFile, milestone, todo, taskDescription, '交互式会话已完成');\n\n // 询问是否更新 spec 文件状态\n await askAndUpdateSpecStatus(specFile, milestone, todo);\n\n logger.header('开发任务完成!');\n logger.success('会话日志已保存');\n logger.newLine();\n logger.info('下一步:');\n logger.step('1. 检查生成的代码');\n logger.step(\"2. 运行 'team-cli dev' 继续下一个任务\");\n logger.newLine();\n}\n\n/**\n * 解析依赖关系\n */\nfunction parseDependencies(spec: string): string[] {\n const deps: string[] = [];\n let inDepsSection = false;\n\n const lines = spec.split('\\n');\n for (const line of lines) {\n // 检测依赖关系部分\n if (line.includes('## 依赖关系') || line.includes('## 依赖')) {\n inDepsSection = true;\n continue;\n }\n\n // 遇到其他二级标题,退出\n if (inDepsSection && line.startsWith('## ')) {\n break;\n }\n\n // 匹配 - [xxx] dependency.md 格式\n const match = line.match(/^-\\s+\\[[ x ]\\]\\s*(.+\\.md)/);\n if (inDepsSection && match) {\n const dep = match[1];\n if (dep !== '无' && dep) {\n deps.push(dep);\n }\n }\n }\n\n return deps;\n}\nfunction topologicalSort(specs: SpecInfo[]): SpecInfo[] {\n const sorted: SpecInfo[] = [];\n const visited = new Set<number>();\n\n function visit(spec: SpecInfo) {\n if (visited.has(spec.index)) return;\n visited.add(spec.index);\n\n // 先访问依赖\n for (const depName of spec.dependencies) {\n const dep = specs.find((s) => s.name === depName);\n if (dep) {\n visit(dep);\n }\n }\n\n sorted.push(spec);\n }\n\n for (const spec of specs) {\n visit(spec);\n }\n\n return sorted;\n}\n\n/**\n * 获取状态图标\n */\nfunction getStatusIcon(status: string): string {\n switch (status) {\n case '已完成':\n return '✓';\n case '进行中':\n return '⟳';\n case '已拆分':\n return '◉';\n default:\n return '○';\n }\n}\n\n\n\n/**\n * 构建开发 prompt\n */\nfunction buildDevPrompt(\n specFile: string,\n milestone: string,\n todo: string,\n taskDescription: string\n): string {\n return `Role: Senior Fullstack Developer\n\nContext:\n- Read and follow TECH_STACK.md for technology choices\n- Read and follow CONVENTIONS.md for coding standards\n- Check AI_MEMORY.md for project context and history\n\nTask: ${taskDescription}\n\nSpec File: ${specFile}\nMilestone: ${milestone}\nTodo: ${todo}\n\nProcess:\n1. First, read and analyze the full spec file\n2. Focus on the selected milestone/todo\n3. Define API endpoints and data models if needed\n4. Write tests first (TDD approach)\n5. Implement the backend code in ./backend\n6. Implement the frontend integration in ./frontend\n7. Update AI_MEMORY.md with completed tasks\n8. Update the spec file to mark completed todos (if applicable)\n\nImportant:\n- Follow the tech stack exactly (Java 17, Spring Boot 3, MyBatis Plus, Next.js 14, TypeScript)\n- Use DTO pattern for all API requests/responses\n- Write clean, well-documented code\n- After completing the task, exit immediately without waiting for further input\n`;\n}\n\n/**\n * 生成会话日志\n */\nasync function generateSessionLog(\n specFile: string,\n milestone: string,\n todo: string,\n taskDescription: string,\n result: string\n): Promise<void> {\n const sessionDir = 'docs/sessions';\n await FileUtils.ensureDir(sessionDir);\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const specName = path.basename(specFile, '.md');\n const logFile = path.join(sessionDir, `${timestamp}_${specName}.md`);\n\n const content = `# 开发会话记录\n\n**时间**: ${new Date().toLocaleString('zh-CN')}\n**Spec**: ${specFile}\n**Milestone**: ${milestone}\n**Todo**: ${todo}\n\n## 任务描述\n\n${taskDescription}\n\n## 执行结果\n\n\\`\\`\\`\n${result}\n\\`\\`\\`\n\n## 生成的文件\n\n<!-- TODO: 列出生成的文件 -->\n\n## 下一步\n\n- [ ] 测试生成的代码\n- [ ] 更新 spec 文件中的 todo 状态\n- [ ] 继续下一个任务\n`;\n\n await FileUtils.write(logFile, content);\n}\n\n/**\n * 询问用户并更新 spec 文件中的 todo 状态\n */\nasync function askAndUpdateSpecStatus(\n specFile: string,\n milestone: string,\n todo: string\n): Promise<void> {\n try {\n const { shouldUpdate } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'shouldUpdate',\n message: '任务是否已完成?是否更新 spec 文件中的 todo 状态?',\n default: true,\n },\n ]);\n\n if (!shouldUpdate) {\n logger.info('跳过更新 spec 文件');\n return;\n }\n\n // 读取 spec 文件\n const content = await FileUtils.read(specFile);\n const lines = content.split('\\n');\n\n // 找到对应的 milestone 和 todo\n let inTargetMilestone = false;\n let targetTodoIndex = -1;\n let milestoneIndex = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // 找到目标 milestone\n if (milestone !== '整个 spec' && line.includes(milestone)) {\n inTargetMilestone = true;\n milestoneIndex = i;\n continue;\n }\n\n // 如果在目标 milestone 中\n if (inTargetMilestone) {\n // 检查是否是另一个 milestone\n if (line.match(/^###\\s+Milestone/)) {\n break;\n }\n\n // 查找目标 todo(支持增强格式)\n if (todo !== '全部功能' && todo !== '全部任务') {\n // 匹配 - [ ] [F/B/I] todo内容 或 - [ ] todo内容\n const todoMatch = line.match(/^-\\s+\\[ \\]\\s*(\\[[FBIN]\\]\\s*)?(.+)/);\n if (todoMatch) {\n const todoContent = todoMatch[2].trim();\n // 移除增强格式的后缀信息\n const cleanContent = todoContent\n .replace(/\\s*\\(关联 API:\\s*`[^`]+`\\)/, '')\n .replace(/\\s*\\(依赖:\\s*[^)]+\\)/, '')\n .trim();\n\n if (cleanContent === todo) {\n targetTodoIndex = i;\n break;\n }\n }\n }\n }\n }\n\n // 如果找到 todo,更新状态\n if (targetTodoIndex !== -1) {\n const line = lines[targetTodoIndex];\n lines[targetTodoIndex] = line.replace(/^-\\s+\\[ \\]/, '- [x]');\n logger.success(`已标记 todo 为完成: ${todo}`);\n } else if (todo === '全部功能' || todo === '全部任务') {\n // 如果是全部任务,标记整个 milestone 的所有 todos\n let updatedCount = 0;\n for (let i = milestoneIndex + 1; i < lines.length; i++) {\n const line = lines[i];\n // 遇到另一个 milestone,退出\n if (line.match(/^###\\s+Milestone/)) {\n break;\n }\n // 更新 todo 状态(支持增强格式)\n if (line.match(/^-\\s+\\[ \\]/)) {\n lines[i] = line.replace(/^-\\s+\\[ \\]/, '- [x]');\n updatedCount++;\n }\n }\n logger.success(`已标记 ${updatedCount} 个 todos 为完成`);\n } else {\n logger.warn('未找到对应的 todo 项');\n return;\n }\n\n // 重新通过进度推导最新状态并同步到文件头部\n const newContent = lines.join('\\n');\n const computedStatus = SpecUtils.parseSpecStatus(newContent);\n\n let finalLines = lines;\n // 自动更新文件头部的状态声明\n const statusLineIndex = finalLines.findIndex(l => l.match(/状态.*[::]/));\n if (statusLineIndex !== -1) {\n const oldLine = finalLines[statusLineIndex];\n const newLine = oldLine.replace(/([::]\\s*)(.+)/, `$1**${computedStatus}**`);\n if (oldLine !== newLine) {\n finalLines[statusLineIndex] = newLine;\n logger.info(`自动同步 Spec 头部状态为: ${computedStatus}`);\n }\n }\n\n // 写回文件\n await FileUtils.write(specFile, finalLines.join('\\n'));\n logger.success('Spec 文件已更新');\n } catch (error) {\n logger.warn(`更新 spec 文件失败: ${error}`);\n }\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils, StringUtils, SpecUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { Listr } from 'listr2';\n\n/**\n * Add-feature 命令 - 添加新功能\n */\nexport const addFeatureCommand = new Command('add-feature')\n .argument('<feature-name>', '功能名称')\n .description('添加新功能(支持 PRD 或简单描述模式)')\n .action(async (featureName) => {\n try {\n logger.header('添加新功能');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info('请先运行 team-cli init 或切换到项目目录');\n process.exit(1);\n }\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 转换为 kebab-case\n const featureSlug = StringUtils.toKebabCase(featureName);\n\n // 检查 PRD 是否已存在\n const prdFile = path.join('docs/prd-docs', `${featureSlug}.md`);\n const prdExists = await FileUtils.exists(prdFile);\n if (prdExists) {\n logger.error(`PRD 文件已存在: ${prdFile}`);\n logger.info('如需重新生成,请先删除:');\n logger.info(` rm ${prdFile}`);\n process.exit(1);\n }\n\n // 选择模式\n const { mode } = await inquirer.prompt([\n {\n type: 'list',\n name: 'mode',\n message: '选择需求输入模式:',\n choices: [\n { name: 'PRD 文档模式 (已有详细 PRD 文档)', value: 'prd' },\n { name: '简单描述模式 (一句话需求 + 模块依赖)', value: 'simple' },\n ],\n },\n ]);\n\n // 执行对应模式\n if (mode === 'prd') {\n await addFeatureFromPrd(featureName, featureSlug, prdFile);\n } else {\n await addFeatureSimple(featureName, featureSlug, prdFile);\n }\n } catch (error: any) {\n logger.error(`添加功能失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * PRD 文档模式\n */\nasync function addFeatureFromPrd(\n featureName: string,\n _featureSlug: string, // 保留参数以保持接口一致,但不使用\n prdOutputFile: string\n): Promise<void> {\n const { prdPath } = await inquirer.prompt([\n {\n type: 'input',\n name: 'prdPath',\n message: '请输入 PRD 文档路径:',\n validate: async (input: string) => {\n const exists = await FileUtils.exists(input);\n return exists || 'PRD 文档不存在';\n },\n },\n ]);\n\n const tasks = new Listr([\n {\n title: '读取 PRD 文档',\n task: async (ctx) => {\n ctx.prdContent = await FileUtils.read(prdPath);\n },\n },\n {\n title: '扫描已完成功能',\n task: async (ctx) => {\n const specDir = 'docs/specs';\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n ctx.completedSpecs = [];\n for (const file of specs) {\n const status = await SpecUtils.getSpecStatus(path.join(specDir, file));\n if (status === '已完成') {\n ctx.completedSpecs.push(file.replace('.md', ''));\n }\n }\n },\n },\n {\n title: '构建项目上下文',\n task: async (ctx) => {\n ctx.projectContext = await buildProjectContext();\n },\n },\n {\n title: '调用 Claude 生成 PRD',\n task: async (ctx) => {\n const prompt = buildPrdPrompt(\n featureName,\n ctx.prdContent,\n ctx.projectContext,\n ctx.completedSpecs\n );\n\n // 直接调用 Claude,不在 Listr 任务中输出分隔符,避免渲染冲突\n const result = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md', 'AI_MEMORY.md'],\n });\n\n ctx.generatedPrd = result;\n },\n },\n {\n title: '保存 PRD 文件',\n task: async (ctx) => {\n await FileUtils.write(prdOutputFile, ctx.generatedPrd);\n },\n },\n ]);\n\n await tasks.run();\n\n // 输出分隔符和成功信息\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n logger.success(`PRD 文件已生成: ${prdOutputFile}`);\n await showPrdPreview(prdOutputFile);\n await askToAdjust(prdOutputFile, 'prd');\n}\n\n/**\n * 简单描述模式\n */\nasync function addFeatureSimple(\n featureName: string,\n _featureSlug: string, // 保留参数以保持接口一致,但不使用\n prdOutputFile: string\n): Promise<void> {\n // 收集功能描述\n const { description } = await inquirer.prompt([\n {\n type: 'input',\n name: 'description',\n message: '功能描述 (一句话说明):',\n validate: (input: string) => input.trim().length > 0 || '描述不能为空',\n },\n ]);\n\n const tasks = new Listr([\n {\n title: '扫描已完成功能',\n task: async (ctx) => {\n const specDir = 'docs/specs';\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n ctx.completedSpecs = [];\n for (const file of specs) {\n const status = await SpecUtils.getSpecStatus(path.join(specDir, file));\n if (status === '已完成') {\n ctx.completedSpecs.push(file.replace('.md', ''));\n }\n }\n },\n },\n {\n title: '选择依赖功能',\n task: async (ctx) => {\n if (ctx.completedSpecs.length === 0) {\n ctx.selectedDeps = [];\n return;\n }\n\n const { dependencies } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'dependencies',\n message: '选择此功能依赖的已有功能 (可多选,直接回车跳过):',\n choices: ctx.completedSpecs,\n },\n ]);\n\n ctx.selectedDeps = dependencies;\n },\n },\n {\n title: '构建项目上下文',\n task: async (ctx) => {\n ctx.projectContext = await buildProjectContext();\n },\n },\n {\n title: '调用 Claude 生成 PRD',\n task: async (ctx) => {\n const prompt = buildSimplePrompt(\n featureName,\n description,\n ctx.projectContext,\n ctx.selectedDeps\n );\n\n // 直接调用 Claude,不在 Listr 任务中输出分隔符,避免渲染冲突\n const result = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md', 'AI_MEMORY.md'],\n });\n\n ctx.generatedPrd = result;\n },\n },\n {\n title: '保存 PRD 文件',\n task: async (ctx) => {\n await FileUtils.write(prdOutputFile, ctx.generatedPrd);\n },\n },\n ]);\n\n await tasks.run();\n\n // 输出分隔符和成功信息\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n logger.success(`PRD 文件已生成: ${prdOutputFile}`);\n await showPrdPreview(prdOutputFile);\n await askToAdjust(prdOutputFile, 'prd');\n}\n\n/**\n * 构建项目上下文\n */\nasync function buildProjectContext(): Promise<string> {\n const context: string[] = [];\n\n // 扫描后端目录\n if (await FileUtils.exists('backend/src/main/java')) {\n context.push('### 后端结构');\n const backendDirs = await FileUtils.findFiles('*/', 'backend/src/main/java');\n const limited = backendDirs.slice(0, 10);\n limited.forEach((dir) => {\n context.push(` - backend/src/main/java/${dir}`);\n });\n }\n\n // 扫描前端目录\n if (await FileUtils.exists('frontend/src')) {\n context.push('');\n context.push('### 前端结构');\n const frontendDirs = await FileUtils.findFiles('*/', 'frontend/src');\n const limited = frontendDirs.slice(0, 10);\n limited.forEach((dir) => {\n context.push(` - frontend/src/${dir}`);\n });\n }\n\n // 扫描已有 specs\n if (await FileUtils.exists('docs/specs')) {\n context.push('');\n context.push('### 已有功能');\n const files = await FileUtils.findFiles('*.md', 'docs/specs');\n const specs = files.filter((f) => !f.includes('template'));\n\n for (const file of specs) {\n const status = await SpecUtils.getSpecStatus(path.join('docs/specs', file));\n context.push(` - ${file.replace('.md', '')} [${status}]`);\n }\n }\n\n return context.join('\\n');\n}\n\n/**\n * 构建 PRD 模式 prompt\n */\nfunction buildPrdPrompt(\n featureName: string,\n prdContent: string,\n projectContext: string,\n completedSpecs: string[]\n): string {\n const deps = completedSpecs.length > 0 ? completedSpecs.join('、') : '(无)';\n\n return `Role: Senior Fullstack Developer\n\n你现在需要根据 PRD 文档生成一个功能规格(Spec)文档。\n\n## 项目技术栈\n后端: Java 17 + Spring Boot 3 + MyBatis Plus + MySQL 8.0\n前端: Next.js 14 (App Router) + TypeScript + Tailwind CSS\n\n## 项目当前状态\n${projectContext}\n\n## 功能名称\n${featureName}\n\n## PRD 文档内容\n${prdContent}\n\n## 依赖功能\n此功能可能依赖以下已完成的功能:${deps}\n\n## 任务\n请根据 PRD 文档,生成一个完整的功能规格文档 Spec。\n\n## Spec 文档格式要求\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: ${featureName}\n**优先级**: P0/P1/P2 (根据功能重要性判断)\n**预估工时**: X 天 (根据复杂度评估:简单1-2天,中等3-5天,复杂5-10天)\n**状态**: 待拆分\n**创建日期**: ${new Date().toISOString().split('T')[0]}\n\n## 依赖关系\n**前置依赖**:\n${completedSpecs.map((s) => `- [x] ${s}`).join('\\n') || '- (无)'}\n\n**被依赖于**:\n- (自动生成,表示哪些 spec 依赖本功能)\n\n## 背景与目标\n[根据 PRD 提取背景和目标]\n\n## 功能需求\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n[从 PRD 提取 3-8 个主要功能点]\n\n## 技术设计\n### API 设计\n列出主要的 API 端点,格式:\n- \\`METHOD /api/path\\` - 简短说明\n\n### 数据模型\n列出需要的数据表,格式:\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n> 注: 使用 \\`team-cli breakdown ${featureName}.md\\` 拆分此 spec 为 milestones 和 todos\n\n----\n*生成于: ${new Date().toISOString()} by Claude*\n\\`\\`\\`\n\n## 注意事项\n1. 只生成 Spec 文档,不要实现任何代码\n2. 优先级判断标准:\n - P0: 核心功能,阻塞其他功能\n - P1: 重要功能,影响用户体验\n - P2: 增强功能,锦上添花\n3. 工时评估标准:\n - 简单功能: 1-2 天\n - 中等功能: 3-5 天\n - 复杂功能: 5-10 天\n4. 功能点要具体可执行,避免过于抽象\n5. API 和数据模型要符合实际技术栈\n6. 从 PRD 中提取关键信息,保持简洁`;\n}\n\n/**\n * 构建简单描述模式 prompt\n */\nfunction buildSimplePrompt(\n featureName: string,\n description: string,\n projectContext: string,\n dependencies: string[]\n): string {\n const deps = dependencies.length > 0 ? dependencies.join('、') : '(无)';\n\n return `Role: Senior Fullstack Developer\n\n用户想要添加一个新功能,需要你生成功能规格文档(Spec)。\n\n## 功能名称\n${featureName}\n\n## 功能描述\n${description}\n\n## 依赖功能\n此功能依赖以下已完成的功能:${deps}\n\n## 项目技术栈\n后端: Java 17 + Spring Boot 3 + MyBatis Plus + MySQL 8.0\n前端: Next.js 14 (App Router) + TypeScript + Tailwind CSS\n\n## 项目当前状态\n${projectContext}\n\n## 任务\n请根据功能描述,生成一个完整的功能规格文档 Spec。\n\n## Spec 文档格式要求\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: ${featureName}\n**优先级**: P0/P1/P2 (根据功能重要性判断)\n**预估工时**: X 天 (根据复杂度评估:简单1-2天,中等3-5天,复杂5-10天)\n**状态**: 待拆分\n**创建日期**: ${new Date().toISOString().split('T')[0]}\n\n## 依赖关系\n**前置依赖**:\n${dependencies.map((d) => `- [x] ${d}`).join('\\n') || '- (无)'}\n\n**被依赖于**:\n- (自动生成,表示哪些 spec 依赖本功能)\n\n## 背景与目标\n[根据功能描述,简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n列出 3-8 个主要功能点,每个功能点用一句话描述。\n\n## 技术设计\n### API 设计\n列出主要的 API 端点,格式:\n- \\`METHOD /api/path\\` - 简短说明\n\n### 数据模型\n列出需要的数据表,格式:\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n> 注: 使用 \\`team-cli breakdown ${featureName}.md\\` 拆分此 spec 为 milestones 和 todos\n\n----\n*生成于: ${new Date().toISOString()} by Claude*\n\\`\\`\\`\n\n## 注意事项\n1. 只生成 Spec 文档,不要实现任何代码\n2. 优先级判断要合理,避免全部是 P0\n3. 工时评估要实际,不要过于乐观\n4. 功能点要具体可执行\n5. 根据功能描述推断合理的 API 和数据模型\n6. 参考已有功能的技术风格保持一致性`;\n}\n\n/**\n * 更新 AI_MEMORY\n */\nasync function updateAiMemory(featureName: string, featureSlug: string): Promise<void> {\n const aiMemoryFile = 'AI_MEMORY.md';\n const exists = await FileUtils.exists(aiMemoryFile);\n\n if (!exists) {\n logger.warn('AI_MEMORY.md 不存在,跳过更新');\n return;\n }\n\n let content = await FileUtils.read(aiMemoryFile);\n \n // 格式化功能名称:将 kebab-case 和 snake_case 转换为 Title Case\n const featureDisplay = featureName\n .replace(/[-_]/g, ' ')\n .split(' ')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n \n const newRow = `| ${featureDisplay} | ${featureSlug}.md | ○ 未开始 | 0/0 | - | |`;\n\n // 检查是否有功能清单部分\n if (!content.includes('## 功能清单')) {\n // 没有功能清单,直接追加到文件末尾\n content += `\\n## 功能清单 (Feature Inventory)\\n\\n| 功能 | Spec 文件 | 状态 | 进度 | 完成日期 | 备注 |\\n|------|----------|------|------|---------|------|\\n${newRow}\\n`;\n } else {\n // 已有功能清单,在表头分隔线后插入新行\n const lines = content.split('\\n');\n let featureInventorySection = false;\n let insertIndex = -1;\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n \n // 检测进入功能清单部分\n if (line.includes('## 功能清单')) {\n featureInventorySection = true;\n continue;\n }\n \n // 检测离开功能清单部分(遇到下一个 ## 标题)\n if (featureInventorySection && line.startsWith('## ') && !line.includes('功能清单')) {\n break;\n }\n \n // 在功能清单部分找到表头分隔线(|------|...)\n if (featureInventorySection && /^\\|[-]+\\|/.test(line.trim())) {\n insertIndex = i + 1;\n break;\n }\n }\n \n if (insertIndex !== -1) {\n lines.splice(insertIndex, 0, newRow);\n content = lines.join('\\n');\n } else {\n // 如果找不到合适的位置,直接在功能清单标题后添加完整表格\n const sectionIndex = lines.findIndex(line => line.includes('## 功能清单'));\n if (sectionIndex !== -1) {\n const tableLines = [\n '',\n '| 功能 | Spec 文件 | 状态 | 进度 | 完成日期 | 备注 |',\n '|------|----------|------|------|---------|------|',\n newRow,\n ''\n ];\n lines.splice(sectionIndex + 1, 0, ...tableLines);\n content = lines.join('\\n');\n } else {\n content += `\\n${newRow}\\n`;\n }\n }\n }\n\n await FileUtils.write(aiMemoryFile, content);\n}\n\n/**\n * 显示 PRD 预览\n */\nasync function showPrdPreview(prdFile: string): Promise<void> {\n logger.newLine();\n logger.header('生成的 PRD 预览:');\n logger.newLine();\n\n try {\n const content = await FileUtils.read(prdFile);\n\n if (!content || content.trim().length === 0) {\n logger.warn('PRD 文件内容为空');\n return;\n }\n\n const lines = content.split('\\n');\n if (lines.length === 0) {\n logger.warn('PRD 文件没有内容');\n return;\n }\n\n const preview = lines.slice(0, 40).join('\\n');\n\n console.log(preview);\n if (lines.length > 40) {\n console.log('...');\n console.log(`(共 ${lines.length} 行)`);\n }\n console.log('');\n } catch (error: any) {\n logger.error(`读取 PRD 预览失败: ${error.message}`);\n }\n}\n\n/**\n * 显示 Spec 预览\n */\nasync function showSpecPreview(specFile: string): Promise<void> {\n logger.newLine();\n logger.header('生成的 Spec 预览:');\n logger.newLine();\n\n try {\n const content = await FileUtils.read(specFile);\n\n if (!content || content.trim().length === 0) {\n logger.warn('Spec 文件内容为空');\n return;\n }\n\n const lines = content.split('\\n');\n if (lines.length === 0) {\n logger.warn('Spec 文件没有内容');\n return;\n }\n\n const preview = lines.slice(0, 40).join('\\n');\n\n console.log(preview);\n if (lines.length > 40) {\n console.log('...');\n console.log(`(共 ${lines.length} 行)`);\n }\n console.log('');\n } catch (error: any) {\n logger.error(`读取 Spec 预览失败: ${error.message}`);\n }\n}\n\n/**\n * 询问是否需要调整\n */\nasync function askToAdjust(file: string, type: 'prd' | 'spec' = 'spec'): Promise<void> {\n const typeLabel = type === 'prd' ? 'PRD' : 'Spec';\n const { needAdjust } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'needAdjust',\n message: `是否需要调整 ${typeLabel} 内容?`,\n default: false,\n },\n ]);\n\n if (needAdjust) {\n logger.info('正在打开编辑器...');\n const editor = process.env.EDITOR || 'vim';\n const { execaCommand } = await import('execa');\n await execaCommand(`${editor} ${file}`, { stdio: 'inherit' });\n }\n\n logger.newLine();\n logger.info('下一步:');\n if (type === 'prd') {\n logger.step(`1. 运行 'team-cli split-prd ${file}' 生成 Spec 规格文档`);\n logger.step(\"2. 运行 'team-cli breakdown <spec-file>' 拆分为 milestones\");\n } else {\n logger.step(`1. 运行 'team-cli breakdown ${file}' 拆分为 milestones`);\n logger.step(\"2. 运行 'team-cli dev' 选择 milestone 进行开发\");\n }\n logger.newLine();\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils, StringUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { Listr } from 'listr2';\n\n/**\n * Split-prd 命令 - 将 PRD 转换为 Spec\n * 支持两种模式:\n * 1. 单文件模式:team-cli split-prd docs/prd-docs/login.md -> 生成单个 spec\n * 2. 目录模式:team-cli split-prd docs/prd-docs -> 扫描目录下所有 PRD 生成多个 specs\n */\nexport const splitPrdCommand = new Command('split-prd')\n .argument('<prd-path>', 'PRD 文档路径 (支持单文件或目录)')\n .description('将 PRD 转换为 Spec 规格文档')\n .action(async (prdPath) => {\n try {\n logger.header('PRD → Spec 转换');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 检查路径是否存在\n const pathExists = await FileUtils.exists(prdPath);\n if (!pathExists) {\n throw new Error(`PRD 路径不存在: ${prdPath}`);\n }\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 判断是单文件还是目录\n const isSingleFile = prdPath.endsWith('.md') || prdPath.endsWith('.txt') || prdPath.endsWith('.markdown');\n \n if (isSingleFile) {\n await processSinglePrd(prdPath);\n } else {\n await processMultiplePrds(prdPath);\n }\n } catch (error: any) {\n logger.error(`PRD 转换失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 处理单个 PRD 文件 -> 生成单个 Spec\n */\nasync function processSinglePrd(prdFile: string): Promise<void> {\n // 从文件名提取功能名称\n const baseName = path.basename(prdFile, path.extname(prdFile));\n const featureSlug = StringUtils.toKebabCase(baseName);\n const specFile = path.join('docs/specs', `${featureSlug}.md`);\n\n // 检查 Spec 是否已存在\n const specExists = await FileUtils.exists(specFile);\n if (specExists) {\n logger.error(`Spec 文件已存在: ${specFile}`);\n logger.info('如需重新生成,请先删除:');\n logger.info(` rm ${specFile}`);\n process.exit(1);\n }\n\n const tasks = new Listr([\n {\n title: '读取 PRD 内容',\n task: async (ctx) => {\n ctx.prdContent = await FileUtils.read(prdFile);\n logger.success(`读取 PRD: ${prdFile}`);\n },\n },\n {\n title: '调用 Claude 生成 Spec',\n task: async (ctx) => {\n const prompt = buildSinglePrdToSpecPrompt(ctx.prdContent, featureSlug);\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 执行中...');\n logger.separator('─', 60);\n logger.newLine();\n\n ctx.specContent = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md', 'AI_MEMORY.md'],\n });\n },\n },\n {\n title: '保存 Spec 文件',\n task: async (ctx) => {\n await FileUtils.write(specFile, ctx.specContent);\n },\n },\n {\n title: '更新 AI_MEMORY',\n task: async () => {\n await updateAiMemory(baseName, featureSlug);\n },\n },\n ]);\n\n await tasks.run();\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n logger.header('PRD → Spec 转换完成!');\n logger.success(`Spec 文件已生成: ${specFile}`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step(`1. 运行 'team-cli breakdown ${specFile}' 拆分为 milestones`);\n logger.step(\"2. 运行 'team-cli dev' 选择 milestone 进行开发\");\n logger.newLine();\n}\n\n/**\n * 处理 PRD 目录 -> 生成多个 Specs(原有逻辑)\n */\nasync function processMultiplePrds(prdFolder: string): Promise<void> {\n // 执行 PRD 拆分任务\n const tasks = new Listr([\n {\n title: '扫描 PRD 文件',\n task: async (ctx) => {\n const supportedExtensions = ['md', 'txt', 'markdown'];\n ctx.prdFiles = [];\n\n for (const ext of supportedExtensions) {\n const files = await FileUtils.findFiles(`*.${ext}`, prdFolder);\n ctx.prdFiles.push(...files.map((f) => path.join(prdFolder, f)));\n }\n\n if (ctx.prdFiles.length === 0) {\n throw new Error(\n '未找到 PRD 文档 (支持 .md, .txt, .markdown)'\n );\n }\n\n ctx.prdFile = ctx.prdFiles[0];\n if (ctx.prdFiles.length > 1) {\n logger.info(`找到多个 PRD 文档,使用: ${ctx.prdFile}`);\n } else {\n logger.success(`找到 PRD 文档: ${ctx.prdFile}`);\n }\n },\n },\n {\n title: '扫描截图文件',\n task: async (ctx) => {\n const screenshotDir = path.join(prdFolder, 'screenshots');\n const dirExists = await FileUtils.exists(screenshotDir);\n\n if (!dirExists) {\n logger.info('未找到 screenshots 目录,跳过截图');\n ctx.screenshots = [];\n return;\n }\n\n const imageExtensions = ['png', 'jpg', 'jpeg', 'gif', 'webp'];\n ctx.screenshots = [];\n\n for (const ext of imageExtensions) {\n const files = await FileUtils.findFiles(`*.${ext}`, screenshotDir);\n ctx.screenshots.push(...files.map((f) => path.join(screenshotDir, f)));\n }\n\n logger.success(`找到 ${ctx.screenshots.length} 个截图文件`);\n },\n },\n {\n title: '扫描 demo 代码仓库',\n task: async (ctx) => {\n const entries = await FileUtils.findFiles('*/', prdFolder);\n ctx.demoRepos = [];\n\n for (const entry of entries) {\n const dirPath = path.join(prdFolder, entry);\n const gitDir = path.join(dirPath, '.git');\n const hasGit = await FileUtils.exists(gitDir);\n if (hasGit) {\n ctx.demoRepos.push(dirPath);\n }\n }\n\n if (ctx.demoRepos.length > 0) {\n logger.success(`找到 demo 仓库: ${ctx.demoRepos.join(', ')}`);\n } else {\n logger.info('未找到 demo 代码仓库,跳过');\n }\n },\n },\n {\n title: '读取 PRD 内容',\n task: async (ctx) => {\n ctx.prdContent = await FileUtils.read(ctx.prdFile);\n },\n },\n {\n title: '调用 Claude 拆分 PRD',\n task: async (ctx) => {\n const prompt = buildSplitPrdPrompt(\n ctx.prdContent,\n ctx.screenshots,\n ctx.demoRepos\n );\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 执行中...');\n logger.separator('─', 60);\n logger.newLine();\n\n return await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md'],\n });\n },\n },\n ]);\n\n await tasks.run();\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n logger.header('PRD 拆分完成!');\n logger.success('Spec 文件已生成到 docs/specs/ 目录');\n logger.newLine();\n\n logger.info('下一步:');\n logger.step(\"1. 检查生成的 spec 文件\");\n logger.step(\"2. 运行 'team-cli breakdown <spec-file>' 拆分 milestones\");\n logger.step(\"3. 运行 'team-cli dev' 开始开发\");\n logger.newLine();\n}\n\n/**\n * 更新 AI_MEMORY - 添加功能到功能清单\n */\nasync function updateAiMemory(featureName: string, featureSlug: string): Promise<void> {\n const aiMemoryFile = 'AI_MEMORY.md';\n const memoryExists = await FileUtils.exists(aiMemoryFile);\n if (!memoryExists) {\n logger.warn('AI_MEMORY.md 不存在,跳过更新');\n return;\n }\n\n let content = await FileUtils.read(aiMemoryFile);\n\n // 格式化功能名称:将 kebab-case 和 snake_case 转换为 Title Case\n const featureDisplay = featureName\n .replace(/[-_]/g, ' ')\n .split(' ')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n\n const newRow = `| ${featureDisplay} | ${featureSlug}.md | ○ 未开始 | 0/0 | - | |`;\n\n // 检查功能是否已存在\n if (content.includes(`| ${featureDisplay} |`) || content.includes(`${featureSlug}.md`)) {\n logger.info(`功能 ${featureDisplay} 已存在于 AI_MEMORY,跳过`);\n return;\n }\n\n // 查找功能清单表格并插入新行\n const lines = content.split('\\n');\n let insertIndex = -1;\n let featureInventorySection = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // 找到功能清单部分\n if (line.includes('功能清单') || line.includes('Feature Inventory')) {\n featureInventorySection = true;\n }\n\n // 在功能清单部分找到表头分隔线(|------|...)\n if (featureInventorySection && /^\\|[-]+\\|/.test(line.trim())) {\n insertIndex = i + 1;\n break;\n }\n }\n\n if (insertIndex > 0) {\n lines.splice(insertIndex, 0, newRow);\n content = lines.join('\\n');\n } else {\n content += `\\n${newRow}\\n`;\n }\n\n await FileUtils.write(aiMemoryFile, content);\n}\n\n/**\n * 构建单个 PRD 转 Spec 的 prompt\n */\nfunction buildSinglePrdToSpecPrompt(prdContent: string, featureSlug: string): string {\n return `Role: Senior Technical Architect\n\nTask: Convert the following PRD (Product Requirements Document) into a detailed technical Spec.\n\nContext:\n- Read TECH_STACK.md for technology constraints\n- Read CONVENTIONS.md for coding standards\n- Read AI_MEMORY.md for project status\n\nPRD Content:\n\\`\\`\\`\n${prdContent}\n\\`\\`\\`\n\nOutput Requirements:\nGenerate a complete Spec document with the following sections:\n\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: [功能中文名]\n**优先级**: P0/P1/P2 (根据功能重要性判断)\n**预估工时**: X 天 (根据复杂度评估:简单1-2天,中等3-5天,复杂5-10天)\n**状态**: 待拆分\n**创建日期**: ${new Date().toISOString().split('T')[0]}\n\n## 依赖关系\n**前置依赖**:\n- (列出依赖的其他功能)\n\n**被依赖于**:\n- (自动生成)\n\n## 背景与目标\n[根据 PRD 提取背景和目标]\n\n## 功能需求\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n[从 PRD 提取 3-8 个主要功能点]\n\n## 技术设计\n### API 设计\n列出主要的 API 端点,格式:\n- \\`METHOD /api/path\\` - 简短说明\n\n### 数据模型\n列出需要的数据表,格式:\n- \\`table_name\\` (表说明) - 字段说明\n\n### 前端组件\n列出需要的主要前端组件\n\n### 后端模块\n列出需要的后端模块结构\n\n## 验收标准\n\n### BDD 场景(行为驱动视角)\n\n请为每个主要功能点生成 2-4 个 BDD 场景,格式如下:\n\n\\`\\`\\`markdown\n#### 场景 1: [场景名称]\n**作为** [用户角色]\n**我希望** [完成的动作]\n**以便** [实现的价值]\n\n- [GIVEN] 前置条件描述\n- [WHEN] 用户动作或 API 调用\n- [THEN] 预期结果\n\n**状态流转**:\n- \\`未登录\\` → \\`登录中\\` → \\`已登录\\`\n\\`\\`\\`\n\n要求:\n1. 每个场景覆盖一个完整的用户流程\n2. Given/When/Then 结构清晰\n3. 状态流转标注明确\n4. 场景数量根据功能复杂度决定(简单功能 2-3 个,复杂功能 4-6 个)\n\n## 里程碑 (Milestones)\n> 注: 使用 \\`team-cli breakdown ${featureSlug}.md\\` 拆分此 spec 为 milestones 和 todos\n\n----\n*生成于: ${new Date().toISOString()} by Claude*\n\\`\\`\\`\n\nIMPORTANT:\n1. Only output the Spec document content, no additional text\n2. Make sure to include comprehensive API and data model design\n3. Priority should be justified based on feature importance\n4. Work estimation should be realistic\n5. Extract key requirements from the PRD accurately\n6. BDD scenarios should cover all user flows and edge cases\n`;\n}\n\n/**\n * 构建 PRD 拆分 prompt\n */\nfunction buildSplitPrdPrompt(\n prdContent: string,\n screenshots: string[],\n demoRepos: string[]\n): string {\n let prompt = `Role: Senior Product Manager and Technical Architect\n\nTask: Analyze the following PRD and split it into multiple independent feature specifications (specs).\n\nContext:\n- Read TECH_STACK.md for technology constraints\n- Read CONVENTIONS.md for coding standards\n- Each spec should be a standalone feature that can be developed independently\n\nPRD Content:\n\\`\\`\\`\n${prdContent}\n\\`\\`\\`\n`;\n\n // 添加截图信息\n if (screenshots.length > 0) {\n prompt += `\nScreenshots available (${screenshots.length} files):\n`;\n for (const screenshot of screenshots) {\n prompt += ` - ${screenshot}\\n`;\n }\n prompt += `You can use the Read tool to view these screenshots for visual reference.\n`;\n }\n\n // 添加 demo 仓库信息\n if (demoRepos.length > 0) {\n prompt += `\nDemo Code Repos available:\n`;\n for (const repo of demoRepos) {\n prompt += ` - ${repo}\\n`;\n }\n prompt += `You can explore these repos to understand existing implementation patterns.\n`;\n }\n\n prompt += `\nOutput Requirements:\n1. Split the PRD into multiple feature specs based on functionality\n2. Each spec should follow the template format (see docs/specs/template.md)\n3. Create each spec as a separate markdown file in docs/specs/\n4. Use kebab-case for filenames (e.g., user-authentication.md, data-export.md)\n5. Each spec must include:\n - Feature Overview (功能概述)\n - Background & Goals (背景与目标)\n - Functional Requirements (功能需求)\n - Technical Design (技术设计)\n - Acceptance Criteria (验收标准)\n\nSpec Format Template:\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: [功能中文名]\n**优先级**: P0/P1/P2\n**预估工时**: X 天\n**状态**: 待拆分\n**创建日期**: ${new Date().toISOString().split('T')[0]}\n\n## 依赖关系\n**前置依赖**:\n- (列出依赖的其他 spec)\n\n**被依赖于**:\n- (自动生成)\n\n## 背景与目标\n[简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n列出 3-8 个主要功能点\n\n## 技术设计\n\n### API 设计\n列出主要的 API 端点\n\n### 数据模型\n列出需要的数据表\n\n## 验收标准\n- [ ] 验收标准 1\n- [ ] 验收标准 2\n- [ ] 验收标准 3\n\n----\n*生成于: ${new Date().toISOString()} by Claude*\n\\`\\`\\`\n\nIMPORTANT:\n- After generating all spec files, exit immediately without waiting for further input\n- Do not ask any questions\n- Each spec should be implementable in 1-3 days\n- Dependencies between features should be clearly noted in the 依赖关系 section\n`;\n\n return prompt;\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils, StringUtils, DateUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { Listr } from 'listr2';\n\n/**\n * Bugfix 命令 - 创建 Bugfix 记录\n */\nexport const bugfixCommand = new Command('bugfix')\n .description('创建 Bugfix 记录')\n .action(async () => {\n try {\n logger.header('创建 Bugfix 记录');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 交互式收集 bug 信息\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'severity',\n message: 'Bug 严重程度:',\n choices: [\n { name: '高 - 阻塞功能或影响核心流程', value: '高' },\n { name: '中 - 影响功能但不阻塞', value: '中' },\n { name: '低 - 小问题或体验问题', value: '低' },\n ],\n default: '中',\n },\n {\n type: 'input',\n name: 'description',\n message: 'Bug 描述:',\n validate: (input: string) => input.trim().length > 0 || '描述不能为空',\n },\n {\n type: 'input',\n name: 'reproduction',\n message: '复现步骤:',\n default: '1. 步骤一\\n2. 步骤二\\n3. 步骤三',\n },\n {\n type: 'list',\n name: 'scope',\n message: '影响范围:',\n choices: ['全部用户', '部分用户', '个别用户', '未知'],\n default: '部分用户',\n },\n ]);\n\n // 生成 bug ID\n const bugId = generateBugId();\n const timestamp = DateUtils.format(new Date(), 'YYYY-MM-DD');\n\n // 查找可能关联的 spec\n const relatedSpec = await findRelatedSpec(answers.description);\n\n // 创建 bugfix 文档\n const bugfixDir = 'docs/bugfixes';\n await FileUtils.ensureDir(bugfixDir);\n\n const bugfixFile = path.join(bugfixDir, `${timestamp}_${bugId}.md`);\n\n const content = formatBugfixDocument({\n id: bugId,\n severity: answers.severity,\n description: answers.description,\n reproduction: answers.reproduction,\n scope: answers.scope,\n relatedSpec,\n timestamp,\n });\n\n await FileUtils.write(bugfixFile, content);\n\n logger.success(`Bugfix 记录已创建: ${bugfixFile}`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step('1. 分析 bug 根本原因');\n logger.step(\"2. 运行 'team-cli dev' 选择关联的 spec 进行修复\");\n logger.step('3. 修复后更新 bugfix 文档状态');\n logger.newLine();\n } catch (error: any) {\n logger.error(`创建 bugfix 失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * Hotfix 命令 - 紧急修复\n */\nexport const hotfixCommand = new Command('hotfix')\n .description('紧急修复流程')\n .action(async () => {\n try {\n logger.header('紧急修复流程');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n logger.warn('注意: hotfix 用于紧急问题修复');\n logger.warn('修复后需要创建规范 bugfix 记录');\n logger.newLine();\n\n // 交互式收集信息\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'description',\n message: '紧急问题描述:',\n validate: (input: string) => input.trim().length > 0 || '描述不能为空',\n },\n {\n type: 'list',\n name: 'scope',\n message: '影响范围:',\n choices: ['所有用户', '部分用户', '特定用户'],\n default: '所有用户',\n },\n {\n type: 'input',\n name: 'solution',\n message: '临时解决方案:',\n validate: (input: string) => input.trim().length > 0 || '方案不能为空',\n },\n ]);\n\n // 生成 hotfix ID\n const hotfixId = generateHotfixId();\n const branchName = `hotfix/${hotfixId}`;\n\n // 创建 hotfix 分支并提交\n const tasks = new Listr([\n {\n title: '创建 hotfix 分支',\n task: async () => {\n const { execa } = await import('execa');\n await execa('git', ['checkout', '-b', branchName], { stdio: 'inherit' });\n },\n },\n {\n title: '创建 hotfix 记录',\n task: async () => {\n const timestamp = DateUtils.format(new Date(), 'YYYY-MM-DD HH:mm:ss');\n const hotfixDir = 'docs/hotfixes';\n await FileUtils.ensureDir(hotfixDir);\n\n const hotfixFile = path.join(hotfixDir, `${timestamp}_${hotfixId}.md`);\n const content = formatHotfixDocument({\n id: hotfixId,\n description: answers.description,\n scope: answers.scope,\n solution: answers.solution,\n branch: branchName,\n timestamp,\n });\n\n await FileUtils.write(hotfixFile, content);\n },\n },\n {\n title: '创建初始 commit',\n task: async () => {\n const { execa } = await import('execa');\n await execa('git', ['add', 'docs/hotfixes'], { stdio: 'pipe' });\n await execa(\n 'git',\n [\n 'commit',\n '-m',\n `hotfix: ${answers.description}\\n\\nTemporary solution: ${answers.solution}`,\n ],\n { stdio: 'pipe' }\n );\n },\n },\n ]);\n\n await tasks.run();\n\n logger.newLine();\n logger.success(`Hotfix 分支已创建: ${branchName}`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step('1. 实施修复');\n logger.step(\"2. 运行 'team-cli lint' 检查代码\");\n logger.step('3. 提交并推送到远程');\n logger.step('4. 创建 PR 进行 code review');\n logger.step('5. 合并后创建规范 bugfix 记录');\n logger.newLine();\n } catch (error: any) {\n logger.error(`Hotfix 流程失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 生成 Bug ID\n */\nfunction generateBugId(): string {\n const date = new Date();\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n\n // 简单的序号生成(实际应该从已有文件中获取最大序号)\n return `BUG-${year}${month}${day}-001`;\n}\n\n/**\n * 生成 Hotfix ID\n */\nfunction generateHotfixId(): string {\n const date = new Date();\n const timestamp = date.getTime().toString().slice(-6);\n return `HF-${timestamp}`;\n}\n\n/**\n * 查找可能关联的 spec\n */\nasync function findRelatedSpec(description: string): Promise<string> {\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n\n if (!exists) {\n return '';\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n if (specs.length === 0) {\n return '';\n }\n\n // 简单的关键词匹配\n const keywords = extractKeywords(description);\n\n for (const file of specs) {\n const filePath = path.join(specDir, file);\n const content = await FileUtils.read(filePath);\n\n for (const keyword of keywords) {\n if (content.toLowerCase().includes(keyword.toLowerCase())) {\n return file.replace('.md', '');\n }\n }\n }\n\n return '';\n}\n\n/**\n * 提取关键词\n */\nfunction extractKeywords(text: string): string[] {\n // 简单的分词和过滤\n const stopWords = ['的', '是', '在', '有', '和', '或', '了', '不', '吗', '呢'];\n const words = text\n .toLowerCase()\n .replace(/[^\\w\\s\\u4e00-\\u9fa5]/g, '')\n .split(/\\s+/)\n .filter((w) => w.length > 1 && !stopWords.includes(w));\n\n return words.slice(0, 5);\n}\n\n/**\n * 格式化 bugfix 文档\n */\nfunction formatBugfixDocument(data: {\n id: string;\n severity: string;\n description: string;\n reproduction: string;\n scope: string;\n relatedSpec: string;\n timestamp: string;\n}): string {\n return `# Bugfix: ${data.description}\n\n## Bug 信息\n- **ID**: ${data.id}\n- **严重程度**: ${data.severity}\n- **状态**: 待修复\n- **创建时间**: ${data.timestamp}\n\n## 问题描述\n${data.description}\n\n## 复现步骤\n${data.reproduction}\n\n## 影响范围\n${data.scope}\n\n## 关联 Spec\n${data.relatedSpec ? `- ${data.relatedSpec}` : '- (无)'}\n\n## 修复方案\n- [ ] 分析根本原因\n- [ ] 设计修复方案\n- [ ] 实施修复\n- [ ] 编写测试\n- [ ] 验证修复\n\n## 验证清单\n- [ ] 本地测试通过\n- [ ] 单元测试覆盖\n- [ ] 回归测试通过\n- [ ] 更新相关文档\n\n---\n*创建于: ${data.timestamp} by team-cli*\n`;\n}\n\n/**\n * 格式化 hotfix 文档\n */\nfunction formatHotfixDocument(data: {\n id: string;\n description: string;\n scope: string;\n solution: string;\n branch: string;\n timestamp: string;\n}): string {\n return `# Hotfix: ${data.description}\n\n## Hotfix 信息\n- **ID**: ${data.id}\n- **创建时间**: ${data.timestamp}\n\n## 问题描述\n${data.description}\n\n## 影响范围\n${data.scope}\n\n## 临时解决方案\n${data.solution}\n\n## 修复分支\n\\`\\`\\`\ngit checkout ${data.branch}\n\\`\\`\\`\n\n## 后续步骤\n- [ ] 实施紧急修复\n- [ ] 推送到远程\n- [ ] 创建 PR 进行 code review\n- [ ] 紧急合并到主分支\n- [ ] 创建规范 bugfix 记录\n- [ ] 计划彻底修复方案\n\n---\n*创建于: ${data.timestamp} by team-cli*\n`;\n}\n","import { BDDScenario, BDDCondition, BDDAction, BDDResult, StateTransition } from '../types/bdd.js';\nimport { StringUtils } from './utils.js';\n\n/**\n * BDD 场景解析器\n */\nexport class BDDParser {\n private static readonly SCENARIO_PATTERN =\n /^####?\\s*场景\\s*(\\d+)[::]?\\s*(.+)$/;\n\n private static readonly GIVEN_PATTERN =\n /^\\*?\\s*-\\s*\\[GIVEN\\]\\s*(.+)$/;\n\n private static readonly WHEN_PATTERN =\n /^\\*?\\s*-\\s*\\[WHEN\\]\\s*(.+)$/;\n\n private static readonly THEN_PATTERN =\n /^\\*?\\s*-\\s*\\[THEN\\]\\s*(.+)$/;\n\n private static readonly STATE_PATTERN =\n /^\\*?\\s*-\\s*\\[STATE\\]\\s*(.+)$/;\n\n private static readonly ROLE_PATTERN =\n /^\\*\\*作为\\*\\*[::]?\\s*(.+)$/i;\n\n private static readonly WANT_PATTERN =\n /^\\*\\*我希望\\*\\*[::]?\\s*(.+)$/i;\n\n private static readonly SO_THAT_PATTERN =\n /^\\*\\*以便\\*\\*[::]?\\s*(.+)$/i;\n\n private static readonly TRANSITION_PATTERN =\n /`([^`]+)`\\s*→\\s*`([^`]+)`/;\n\n /**\n * 解析 BDD 场景\n */\n static parseScenarios(content: string): BDDScenario[] {\n const scenarios: BDDScenario[] = [];\n const lines = content.split('\\n');\n\n let currentScenario: Partial<BDDScenario> | null = null;\n let section: 'title' | 'given' | 'when' | 'then' | 'state' | null = null;\n let scenarioOrder = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n const lineNum = i + 1;\n\n // 匹配场景标题\n const scenarioMatch = line.match(this.SCENARIO_PATTERN);\n if (scenarioMatch) {\n if (currentScenario && currentScenario.title) {\n scenarios.push(this.finalizeScenario(currentScenario, scenarioOrder));\n }\n scenarioOrder++;\n currentScenario = {\n id: `scenario-${scenarioOrder}`,\n title: scenarioMatch[2].trim(),\n order: scenarioOrder,\n given: [],\n when: [],\n then: [],\n stateTransitions: [],\n relatedApis: [],\n relatedFeatures: [],\n };\n section = 'title';\n continue;\n }\n\n // 匹配 Gherkin 关键字\n if (line.match(/^\\*\\*作为\\*\\*[::]?/i)) {\n const match = line.match(this.ROLE_PATTERN);\n if (match && currentScenario) {\n currentScenario.asA = match[1].trim();\n }\n continue;\n }\n\n if (line.match(/^\\*\\*我希望\\*\\*[::]?/i)) {\n const match = line.match(this.WANT_PATTERN);\n if (match && currentScenario) {\n currentScenario.iWant = match[1].trim();\n }\n continue;\n }\n\n if (line.match(/^\\*\\*以便\\*\\*[::]?/i)) {\n const match = line.match(this.SO_THAT_PATTERN);\n if (match && currentScenario) {\n currentScenario.soThat = match[1].trim();\n }\n continue;\n }\n\n // 匹配验收步骤\n const givenMatch = line.match(this.GIVEN_PATTERN);\n const whenMatch = line.match(this.WHEN_PATTERN);\n const thenMatch = line.match(this.THEN_PATTERN);\n const stateMatch = line.match(this.STATE_PATTERN);\n\n if (givenMatch && currentScenario) {\n currentScenario.given.push({\n description: givenMatch[1].trim(),\n type: this.detectConditionType(givenMatch[1]),\n validation: this.extractValidation(givenMatch[1]),\n });\n section = 'given';\n continue;\n }\n\n if (whenMatch && currentScenario) {\n const action = this.parseAction(whenMatch[1].trim());\n currentScenario.when.push(action);\n if (action.api) {\n currentScenario.relatedApis.push(action.api);\n }\n section = 'when';\n continue;\n }\n\n if (thenMatch && currentScenario) {\n currentScenario.then.push({\n description: thenMatch[1].trim(),\n type: this.detectResultType(thenMatch[1]),\n expectedBehavior: this.extractExpectedBehavior(thenMatch[1]),\n });\n section = 'then';\n continue;\n }\n\n if (stateMatch && currentScenario) {\n const transition = this.parseStateTransition(stateMatch[1].trim());\n if (transition) {\n currentScenario.stateTransitions.push(transition);\n }\n section = 'state';\n continue;\n }\n\n // 多行描述处理\n if (line && !line.startsWith('#') && !line.startsWith('---') && currentScenario) {\n const trimmed = line.replace(/^[\\s-]*/, '');\n if (trimmed && section === 'given' && currentScenario.given.length > 0) {\n currentScenario.given[currentScenario.given.length - 1].description +=\n ' ' + trimmed;\n } else if (trimmed && section === 'when' && currentScenario.when.length > 0) {\n currentScenario.when[currentScenario.when.length - 1].description +=\n ' ' + trimmed;\n } else if (trimmed && section === 'then' && currentScenario.then.length > 0) {\n currentScenario.then[currentScenario.then.length - 1].description +=\n ' ' + trimmed;\n }\n }\n }\n\n // 处理最后一个场景\n if (currentScenario && currentScenario.title) {\n scenarios.push(this.finalizeScenario(currentScenario, scenarioOrder));\n }\n\n return scenarios;\n }\n\n /**\n * 从验收标准部分提取 BDD 场景\n */\n static parseFromAcceptanceSection(acceptanceSection: string): BDDScenario[] {\n // 提取 BDD 场景部分\n const bddSectionMatch = acceptanceSection.match(\n /(?:###\\s*BDD[^\\n]*|###\\s*场景|###\\s*行为驱动)[^]*(?=##|$)/i\n );\n\n if (bddSectionMatch) {\n return this.parseScenarios(bddSectionMatch[0]);\n }\n\n // 如果没有明确 BDD 章节,尝试从原有验收标准转换\n return this.convertFromLegacyCriteria(acceptanceSection);\n }\n\n /**\n * 从传统验收标准转换\n */\n private static convertFromLegacyCriteria(criteria: string): BDDScenario[] {\n const scenarios: BDDScenario[] = [];\n const lines = criteria.split('\\n');\n\n let scenarioId = 0;\n let currentScenario: Partial<BDDScenario> | null = null;\n\n for (const line of lines) {\n const criteriaMatch = line.match(/^-\\s*\\[\\s*\\]\\s*(.+)$/);\n\n if (criteriaMatch) {\n if (!currentScenario) {\n scenarioId++;\n currentScenario = {\n id: `scenario-${scenarioId}`,\n title: `场景 ${scenarioId}`,\n order: scenarioId,\n given: [],\n when: [],\n then: [],\n stateTransitions: [],\n };\n }\n\n const text = criteriaMatch[1];\n const normalized = text.toLowerCase();\n\n if (normalized.includes('已') || normalized.includes('有') || normalized.includes('存在')) {\n currentScenario.given.push({\n description: text,\n type: 'data',\n validation: '检查数据存在',\n });\n } else if (normalized.includes('当') || normalized.includes('提交') || normalized.includes('点击')) {\n currentScenario.when.push({\n description: text,\n trigger: 'user',\n });\n } else if (normalized.includes('应') || normalized.includes('返回') || normalized.includes('显示')) {\n currentScenario.then.push({\n description: text,\n type: 'response',\n expectedBehavior: text,\n });\n }\n } else if (line.trim() === '' && currentScenario) {\n scenarios.push(this.finalizeScenario(currentScenario, scenarioId));\n currentScenario = null;\n }\n }\n\n if (currentScenario && currentScenario.title) {\n scenarios.push(this.finalizeScenario(currentScenario, scenarioId));\n }\n\n return scenarios;\n }\n\n /**\n * 检测条件类型\n */\n private static detectConditionType(description: string): 'data' | 'state' | 'user' {\n const lower = description.toLowerCase();\n if (lower.includes('数据') || lower.includes('记录') || lower.includes('表')) return 'data';\n if (lower.includes('状态') || lower.includes('已') || lower.includes('未')) return 'state';\n return 'user';\n }\n\n /**\n * 检测结果类型\n */\n private static detectResultType(description: string): 'response' | 'state' | 'data' | 'ui' {\n const lower = description.toLowerCase();\n if (lower.includes('返回') || lower.includes('响应') || lower.includes('状态码')) return 'response';\n if (lower.includes('状态') || lower.includes('变成') || lower.includes('更新')) return 'state';\n if (lower.includes('显示') || lower.includes('页面') || lower.includes('界面')) return 'ui';\n return 'data';\n }\n\n /**\n * 提取验证方式\n */\n private static extractValidation(description: string): string {\n const match = description.match(/\\(([^)]+)\\)/);\n return match ? match[1] : '检查条件满足';\n }\n\n /**\n * 提取预期行为\n */\n private static extractExpectedBehavior(description: string): string {\n return description.replace(/^(应该|应|应当|应该会|会)/, '').trim();\n }\n\n /**\n * 解析动作\n */\n private static parseAction(description: string): BDDAction {\n const apiMatch = description.match(/(?:API|POST|GET|PUT|DELETE|PATCH)\\s*[::]?\\s*`([^`]+)`/i);\n const uiMatch = description.match(/(?:点击|输入|选择|提交|拖拽)[::]?\\s*(.+)/);\n\n return {\n description,\n api: apiMatch?.[1],\n uiAction: uiMatch?.[1],\n trigger: apiMatch ? 'api' : 'user',\n };\n }\n\n /**\n * 解析状态流转\n */\n private static parseStateTransition(description: string): StateTransition | null {\n const arrowMatch = description.match(/`([^`]+)`\\s*(?:→|->)\\s*`([^`]+)`/);\n\n if (arrowMatch) {\n return {\n from: arrowMatch[1],\n trigger: description.split(/→|->/)[1]?.trim() || '完成',\n to: arrowMatch[2],\n };\n }\n\n const fromMatch = description.match(/(?:从|起始于|开始于)\\s*`([^`]+)`/);\n const toMatch = description.match(/(?:到|变为|结束于)\\s*`([^`]+)`/);\n const triggerMatch = description.match(/通过|当|使用\\s*[::]?\\s*(.+?)(?:,|$)/);\n\n if (fromMatch && toMatch) {\n return {\n from: fromMatch[1],\n trigger: triggerMatch?.[1] || '完成',\n to: toMatch[1],\n };\n }\n\n return null;\n }\n\n /**\n * 完成场景构建\n */\n private static finalizeScenario(\n scenario: Partial<BDDScenario>,\n order: number\n ): BDDScenario {\n return {\n id: scenario.id || `scenario-${order}`,\n title: scenario.title || `场景 ${order}`,\n order: scenario.order || order,\n asA: scenario.asA || '用户',\n iWant: scenario.iWant || '',\n soThat: scenario.soThat || '',\n given: scenario.given || [],\n when: scenario.when || [],\n then: scenario.then || [],\n stateTransitions: scenario.stateTransitions || [],\n relatedApis: scenario.relatedApis || [],\n relatedFeatures: scenario.relatedFeatures || [],\n };\n }\n\n /**\n * 生成场景的 Markdown\n */\n static generateMarkdown(scenario: BDDScenario): string {\n const lines: string[] = [];\n\n lines.push(`#### 场景 ${scenario.order}: ${scenario.title}`);\n lines.push('');\n\n if (scenario.asA) {\n lines.push(`**作为** ${scenario.asA}`);\n }\n if (scenario.iWant) {\n lines.push(`**我希望** ${scenario.iWant}`);\n }\n if (scenario.soThat) {\n lines.push(`**以便** ${scenario.soThat}`);\n }\n lines.push('');\n\n for (const given of scenario.given) {\n lines.push(`- [GIVEN] ${given.description}`);\n }\n lines.push('');\n\n for (const when of scenario.when) {\n lines.push(`- [WHEN] ${when.description}`);\n }\n lines.push('');\n\n for (const then of scenario.then) {\n lines.push(`- [THEN] ${then.description}`);\n }\n lines.push('');\n\n if (scenario.stateTransitions.length > 0) {\n lines.push('**状态流转**:');\n for (const trans of scenario.stateTransitions) {\n lines.push(`- \\`${trans.from}\\` → \\`${trans.to}\\` (触发: ${trans.trigger})`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n }\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils, SpecUtils, EnhancedMilestoneInfo, TodoItem, StringUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { BDDParser } from '../lib/bdd-parser.js';\nimport { BDDScenario, BDDCheckResult } from '../types/bdd.js';\n\n/**\n * 问题记录接口\n */\nexport interface IssueRecord {\n id: string;\n title: string;\n description: string;\n severity: 'high' | 'medium' | 'low';\n type: 'bug' | 'performance' | 'usability' | 'security' | 'other';\n status: 'pending' | 'in_progress' | 'resolved';\n createdAt: string;\n specFile: string;\n milestone: string;\n todo?: string;\n}\n\n/**\n * 验收检查结果\n */\nexport interface AcceptanceResult {\n specFile: string;\n milestone: string;\n checkTime: string;\n frontendTasks: { total: number; completed: number; items: CheckItem[] };\n backendTasks: { total: number; completed: number; items: CheckItem[] };\n apiVerification: { total: number; verified: number; items: CheckItem[] };\n integrationTasks: { total: number; completed: number; items: CheckItem[] };\n issues: IssueRecord[];\n}\n\n/**\n * 检查项\n */\nexport interface CheckItem {\n description: string;\n status: 'pass' | 'fail' | 'pending';\n details?: string;\n filePath?: string;\n}\n\n/**\n * Accept 命令 - 验收功能\n */\nexport const acceptCommand = new Command('accept')\n .argument('[spec-file]', 'Spec 文件路径')\n .description('验收功能 - 走查所有需求,验证联调是否完成')\n .option('--mode <mode>', '验收模式: traditional (传统) 或 bdd (行为驱动)', 'traditional')\n .option('--scenario <id>', '指定验收的 BDD 场景 ID')\n .action(async (specFile, options) => {\n try {\n logger.header('验收模式');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n logger.success('检测到项目上下文');\n\n if (options.mode === 'bdd') {\n // BDD 验收模式\n await runBDDAcceptance(specFile, options.scenario);\n } else {\n // 传统验收模式\n await runTraditionalAcceptance(specFile);\n }\n\n logger.header('验收完成!');\n logger.newLine();\n } catch (error: any) {\n logger.error(`验收失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 传统验收模式入口\n */\nasync function runTraditionalAcceptance(defaultSpec?: string): Promise<void> {\n // 步骤 1: 选择 spec 文件\n const selectedSpec = await selectSpec(defaultSpec);\n\n // 步骤 2: 选择 milestone\n const selectedMilestone = await selectMilestone(selectedSpec);\n\n // 步骤 3: 执行验收检查\n const result = await runAcceptanceCheck(selectedSpec, selectedMilestone);\n\n // 步骤 4: 生成验收报告\n await generateAcceptanceReport(result);\n\n // 步骤 5: 处理发现的问题\n if (result.issues.length > 0) {\n await handleIssues(result);\n }\n\n // 步骤 6: 同步状态\n await syncSpecStatus(selectedSpec, result);\n}\n\n/**\n * BDD 验收模式入口\n */\nasync function runBDDAcceptance(defaultSpec?: string, scenarioId?: string): Promise<void> {\n // 步骤 1: 选择 spec 文件\n const selectedSpec = await selectSpec(defaultSpec);\n\n // 步骤 2: 解析 BDD 场景\n const specContent = await FileUtils.read(selectedSpec);\n const scenarios = BDDParser.parseFromAcceptanceSection(specContent);\n\n if (scenarios.length === 0) {\n logger.warn('未找到 BDD 场景,使用传统验收模式');\n logger.info('请先运行 \"team-cli split-prd\" 生成包含 BDD 场景的 spec');\n await runTraditionalAcceptance(selectedSpec);\n return;\n }\n\n // 步骤 3: 选择要验收的场景\n const targetScenarios = scenarioId\n ? scenarios.filter(s => s.id === scenarioId || s.title.toLowerCase().includes(scenarioId.toLowerCase()))\n : scenarios;\n\n if (targetScenarios.length === 0) {\n throw new Error(`未找到场景: ${scenarioId}`);\n }\n\n logger.newLine();\n logger.info(`找到 ${scenarios.length} 个 BDD 场景,将验收 ${targetScenarios.length} 个`);\n\n // 步骤 4: 逐个验收场景\n const results: BDDCheckResult[] = [];\n\n for (const scenario of targetScenarios) {\n logger.newLine();\n logger.info(`验收场景: ${scenario.title}`);\n\n const result = await checkBDDScenario(scenario, selectedSpec);\n results.push(result);\n\n // 输出场景验收摘要\n printScenarioResult(result);\n }\n\n // 步骤 5: 生成 BDD 验收报告\n await generateBDDReport(selectedSpec, results);\n\n // 步骤 6: 同步状态\n await syncBDDStatus(selectedSpec, results);\n}\n\n/**\n * 步骤 1: 选择 spec 文件\n */\nasync function selectSpec(defaultSpec?: string): Promise<string> {\n logger.step('步骤 1/4: 选择 spec 文件...');\n logger.newLine();\n\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n if (!exists) {\n throw new Error('docs/specs 目录不存在');\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n const specFiles = files.filter((f) => !f.includes('template'));\n\n if (specFiles.length === 0) {\n throw new Error('未找到 spec 文件');\n }\n\n // 如果指定了文件,直接使用\n if (defaultSpec) {\n const fullPath = defaultSpec.startsWith('docs/specs/')\n ? defaultSpec\n : path.join(specDir, defaultSpec);\n\n const exists = await FileUtils.exists(fullPath);\n if (!exists) {\n throw new Error(`Spec 文件不存在: ${defaultSpec}`);\n }\n logger.success(`已选择: ${fullPath}`);\n return fullPath;\n }\n\n // 解析 spec 信息\n const specs: { file: string; name: string; status: string }[] = [];\n for (const file of specFiles) {\n const fullPath = path.join(specDir, file);\n const content = await FileUtils.read(fullPath);\n const status = SpecUtils.parseSpecStatus(content);\n specs.push({ file: fullPath, name: file, status });\n }\n\n // 只显示已拆分或进行中的 spec\n const activeSpecs = specs.filter(\n (s) => s.status === '已拆分' || s.status === '进行中' || s.status === '已完成'\n );\n\n if (activeSpecs.length === 0) {\n logger.warn('没有可验收的 spec 文件');\n const { continueAnyway } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'continueAnyway',\n message: '是否继续查看所有 spec?',\n default: true,\n },\n ]);\n\n if (!continueAnyway) {\n process.exit(0);\n }\n }\n\n const targetSpecs = activeSpecs.length > 0 ? activeSpecs : specs;\n\n const choices = targetSpecs.map((spec) => ({\n name: `[${spec.status}] ${spec.name}`,\n value: spec.file,\n short: spec.name,\n }));\n\n const { selectedFile } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedFile',\n message: '选择要验收的 spec:',\n choices,\n },\n ]);\n\n logger.success(`已选择: ${selectedFile}`);\n return selectedFile;\n}\n\n/**\n * 步骤 2: 选择 milestone\n */\nasync function selectMilestone(specFile: string): Promise<string> {\n logger.newLine();\n logger.step('步骤 2/4: 解析 milestones...');\n logger.newLine();\n\n const specContent = await FileUtils.read(specFile);\n const { enhanced } = SpecUtils.parseMilestonesEnhancedWithFallback(specContent);\n\n if (enhanced.length === 0) {\n throw new Error('该 spec 尚未拆分 milestones,无法进行验收');\n }\n\n // 显示未完成的 milestones\n const choices = enhanced.map((m, idx) => {\n const isDone = m.completedCount === m.totalCount;\n const statusIcon = isDone ? '✓' : m.completedCount > 0 ? '⟳' : '○';\n const progress = `[${m.completedCount}/${m.totalCount}]`;\n\n return {\n name: `${idx + 1}. ${statusIcon} ${progress} ${m.title}`,\n value: m.title,\n short: m.title,\n };\n });\n\n const { milestone } = await inquirer.prompt([\n {\n type: 'list',\n name: 'milestone',\n message: '选择要验收的 milestone:',\n choices,\n },\n ]);\n\n return milestone;\n}\n\n/**\n * 步骤 3: 执行验收检查\n */\nasync function runAcceptanceCheck(\n specFile: string,\n milestone: string\n): Promise<AcceptanceResult> {\n logger.newLine();\n logger.step('步骤 3/4: 执行验收检查...');\n logger.newLine();\n\n const specContent = await FileUtils.read(specFile);\n const { enhanced } = SpecUtils.parseMilestonesEnhancedWithFallback(specFile);\n const targetMilestone = enhanced.find((m) => m.title === milestone);\n\n if (!targetMilestone) {\n throw new Error(`未找到 milestone: ${milestone}`);\n }\n\n const result: AcceptanceResult = {\n specFile,\n milestone,\n checkTime: new Date().toLocaleString('zh-CN'),\n frontendTasks: { total: 0, completed: 0, items: [] },\n backendTasks: { total: 0, completed: 0, items: [] },\n apiVerification: { total: 0, verified: 0, items: [] },\n integrationTasks: { total: 0, completed: 0, items: [] },\n issues: [],\n };\n\n // 检查前端任务\n logger.info('检查前端任务...');\n for (const todo of targetMilestone.frontendTodos) {\n const checkResult = await checkFrontendTask(todo);\n result.frontendTasks.items.push(checkResult);\n if (checkResult.status === 'pass') {\n result.frontendTasks.completed++;\n }\n result.frontendTasks.total++;\n\n const icon = checkResult.status === 'pass' ? '✓' : checkResult.status === 'fail' ? '✗' : '○';\n logger.info(` ${icon} [F] ${todo.content}${checkResult.filePath ? ` - ${checkResult.filePath}` : ''}`);\n }\n\n // 检查后端任务\n logger.info('检查后端任务...');\n for (const todo of targetMilestone.backendTodos) {\n const checkResult = await checkBackendTask(todo);\n result.backendTasks.items.push(checkResult);\n if (checkResult.status === 'pass') {\n result.backendTasks.completed++;\n }\n result.backendTasks.total++;\n\n const icon = checkResult.status === 'pass' ? '✓' : checkResult.status === 'fail' ? '✗' : '○';\n logger.info(` ${icon} [B] ${todo.content}${checkResult.filePath ? ` - ${checkResult.filePath}` : ''}`);\n }\n\n // 验证 API 实现\n logger.info('验证 API 实现...');\n for (const todo of targetMilestone.backendTodos) {\n if (todo.apiAssociation) {\n const checkResult = await verifyApiImplementation(todo);\n result.apiVerification.items.push(checkResult);\n if (checkResult.status === 'pass') {\n result.apiVerification.verified++;\n }\n result.apiVerification.total++;\n\n const icon = checkResult.status === 'pass' ? '✓' : checkResult.status === 'fail' ? '✗' : '○';\n logger.info(` ${icon} ${todo.apiAssociation}${checkResult.filePath ? ` - ${checkResult.filePath}` : ''}`);\n }\n }\n\n // 检查联调任务\n logger.info('检查联调任务...');\n for (const todo of targetMilestone.integrationTodos) {\n const checkResult = await checkIntegrationTask(todo);\n result.integrationTasks.items.push(checkResult);\n if (checkResult.status === 'pass') {\n result.integrationTasks.completed++;\n }\n result.integrationTasks.total++;\n\n const icon = checkResult.status === 'pass' ? '✓' : checkResult.status === 'fail' ? '✗' : '○';\n logger.info(` ${icon} [I] ${todo.content}`);\n }\n\n return result;\n}\n\n/**\n * 检查前端任务\n */\nasync function checkFrontendTask(todo: TodoItem): Promise<CheckItem> {\n // 前端代码检查 - 检查常见前端文件路径\n const frontendPaths = [\n `frontend/src/pages/${todo.content}.tsx`,\n `frontend/src/components/${todo.content}.tsx`,\n `frontend/src/components/${todo.content.replace(/\\s+/g, '')}.tsx`,\n `frontend/src/views/${todo.content}.vue`,\n `frontend/src/components/${todo.content}.vue`,\n ];\n\n for (const fp of frontendPaths) {\n if (await FileUtils.exists(fp)) {\n return {\n description: `[F] ${todo.content}`,\n status: 'pass',\n details: '前端代码存在',\n filePath: fp,\n };\n }\n }\n\n // 检查增强格式中的路径信息\n const pathMatch = todo.content.match(/\\s*-\\s*(.+?\\.(tsx|vue|js|jsx))\\s*/);\n if (pathMatch) {\n const filePath = pathMatch[1];\n if (await FileUtils.exists(filePath)) {\n return {\n description: `[F] ${todo.content}`,\n status: 'pass',\n details: '前端代码存在',\n filePath,\n };\n }\n }\n\n return {\n description: `[F] ${todo.content}`,\n status: 'fail',\n details: '前端代码不存在或路径无法验证',\n };\n}\n\n/**\n * 检查后端任务\n */\nasync function checkBackendTask(todo: TodoItem): Promise<CheckItem> {\n // 后端代码检查 - 检查常见后端文件路径\n const backendPaths = [\n `backend/src/main/java/${todo.content.replace(/\\s+/g, '/')}.java`,\n `backend/src/${todo.content.toLowerCase().replace(/\\s+/g, '/')}.java`,\n ];\n\n for (const fp of backendPaths) {\n if (await FileUtils.exists(fp)) {\n return {\n description: `[B] ${todo.content}`,\n status: 'pass',\n details: '后端代码存在',\n filePath: fp,\n };\n }\n }\n\n // 检查增强格式中的路径信息\n const pathMatch = todo.content.match(/\\s*-\\s*(.+?\\.(java|kt|py|go))\\s*/);\n if (pathMatch) {\n const filePath = pathMatch[1];\n if (await FileUtils.exists(filePath)) {\n return {\n description: `[B] ${todo.content}`,\n status: 'pass',\n details: '后端代码存在',\n filePath,\n };\n }\n }\n\n return {\n description: `[B] ${todo.content}`,\n status: 'fail',\n details: '后端代码不存在或路径无法验证',\n };\n}\n\n/**\n * 验证 API 实现\n */\nasync function verifyApiImplementation(todo: TodoItem): Promise<CheckItem> {\n if (!todo.apiAssociation) {\n return {\n description: todo.apiAssociation || 'API 验证',\n status: 'pending',\n details: '无 API 关联信息',\n };\n }\n\n // 解析 API 路径和方法\n const apiMatch = todo.apiAssociation.match(/^(GET|POST|PUT|DELETE|PATCH)\\s+\\/(.+)$/);\n if (!apiMatch) {\n return {\n description: todo.apiAssociation,\n status: 'pending',\n details: '无法解析 API 格式',\n };\n }\n\n const method = apiMatch[1];\n const apiPath = apiMatch[2];\n\n // 检查 Controller 层实现\n const controllerPaths = [\n `backend/src/main/java/**/*Controller.java`,\n `backend/src/**/*Controller.java`,\n ];\n\n const controllerFiles = await FileUtils.findFiles('**/*Controller.java', 'backend/src');\n\n for (const cf of controllerFiles) {\n const content = await FileUtils.read(cf);\n // 检查是否包含 API 路径和方法\n if (content.includes(apiPath) || content.includes(`\"${apiPath}\"`)) {\n // 检查方法注解\n const methodAnnotations: Record<string, string[]> = {\n GET: ['@GetMapping', '@RequestMapping(method = RequestMethod.GET)'],\n POST: ['@PostMapping', '@RequestMapping(method = RequestMethod.POST)'],\n PUT: ['@PutMapping', '@RequestMapping(method = RequestMethod.PUT)'],\n DELETE: ['@DeleteMapping', '@RequestMapping(method = RequestMethod.DELETE)'],\n PATCH: ['@PatchMapping', '@RequestMapping(method = RequestMethod.PATCH)'],\n };\n\n for (const annotation of methodAnnotations[method] || []) {\n if (content.includes(annotation)) {\n return {\n description: todo.apiAssociation,\n status: 'pass',\n details: 'API Controller 实现存在',\n filePath: cf,\n };\n }\n }\n }\n }\n\n return {\n description: todo.apiAssociation,\n status: 'fail',\n details: 'API Controller 未实现',\n };\n}\n\n/**\n * 检查联调任务\n */\nasync function checkIntegrationTask(todo: TodoItem): Promise<CheckItem> {\n // 联调任务通常需要前后端联动验证\n // 这里我们检查是否有相关的测试文件或集成测试证据\n const integrationEvidence = [\n '**/*integration*.test.*',\n '**/*e2e*.test.*',\n '**/*IT.java',\n 'docs/integration-test-results.md',\n 'docs/session-logs/**',\n ];\n\n // 检查是否有相关的 session 日志或测试报告\n const sessionDir = 'docs/sessions';\n if (await FileUtils.exists(sessionDir)) {\n const sessionFiles = await FileUtils.findFiles('*.md', sessionDir);\n const hasRecentSession = sessionFiles.some((sf) =>\n sf.includes('integration') || sf.includes('联调')\n );\n if (hasRecentSession) {\n return {\n description: `[I] ${todo.content}`,\n status: 'pass',\n details: '联调证据存在(session 日志)',\n };\n }\n }\n\n // 默认为 pending,因为联调通常需要人工验证\n return {\n description: `[I] ${todo.content}`,\n status: 'pending',\n details: '建议人工验证联调结果',\n };\n}\n\n/**\n * 步骤 4: 生成验收报告\n */\nasync function generateAcceptanceReport(result: AcceptanceResult): Promise<void> {\n logger.newLine();\n logger.step('步骤 4/4: 生成验收报告...');\n logger.newLine();\n\n const reportDir = 'docs/acceptance-reports';\n await FileUtils.ensureDir(reportDir);\n\n const timestamp = new Date().toISOString().slice(0, 10);\n const specName = path.basename(result.specFile, '.md');\n const milestoneSafe = result.milestone.replace(/[^a-zA-Z0-9]/g, '-');\n const reportFile = path.join(reportDir, `${timestamp}_${specName}_${milestoneSafe}.md`);\n\n const report = generateMarkdownReport(result);\n\n await FileUtils.write(reportFile, report);\n\n logger.success(`验收报告已生成: ${reportFile}`);\n logger.newLine();\n\n // 控制台输出报告摘要\n console.log(generateConsoleReport(result));\n}\n\n/**\n * 生成 Markdown 格式的验收报告\n */\nfunction generateMarkdownReport(result: AcceptanceResult): string {\n const lines: string[] = [];\n\n lines.push('# 验收报告');\n lines.push('');\n lines.push(`**Spec 文件**: ${result.specFile}`);\n lines.push(`**Milestone**: ${result.milestone}`);\n lines.push(`**验收时间**: ${result.checkTime}`);\n lines.push('');\n\n // 检查结果汇总\n lines.push('## 检查结果汇总');\n lines.push('');\n lines.push('| 检查项 | 状态 |');\n lines.push('|--------|------|');\n lines.push(\n `| 前端任务 | ${result.frontendTasks.completed}/${result.frontendTasks.total} 完成 |`\n );\n lines.push(\n `| 后端任务 | ${result.backendTasks.completed}/${result.backendTasks.total} 完成 |`\n );\n lines.push(`| API 验证 | ${result.apiVerification.verified}/${result.apiVerification.total} 实现 |`);\n lines.push(\n `| 联调任务 | ${result.integrationTasks.completed}/${result.integrationTasks.total} 完成 |`\n );\n lines.push('');\n\n // 详细记录\n lines.push('## 详细记录');\n lines.push('');\n\n // 前端任务\n lines.push('### 前端任务');\n lines.push('');\n for (const item of result.frontendTasks.items) {\n const icon = item.status === 'pass' ? '✓' : item.status === 'fail' ? '✗' : '○';\n lines.push(`- ${icon} ${item.description} - ${item.details || ''} ${item.filePath ? `(\\`${item.filePath}\\`)` : ''}`);\n }\n lines.push('');\n\n // 后端任务\n lines.push('### 后端任务');\n lines.push('');\n for (const item of result.backendTasks.items) {\n const icon = item.status === 'pass' ? '✓' : item.status === 'fail' ? '✗' : '○';\n lines.push(`- ${icon} ${item.description} - ${item.details || ''} ${item.filePath ? `(\\`${item.filePath}\\`)` : ''}`);\n }\n lines.push('');\n\n // API 验证\n lines.push('### API 验证');\n lines.push('');\n for (const item of result.apiVerification.items) {\n const icon = item.status === 'pass' ? '✓' : item.status === 'fail' ? '✗' : '○';\n lines.push(`- ${icon} ${item.description} - ${item.details || ''} ${item.filePath ? `(\\`${item.filePath}\\`)` : ''}`);\n }\n lines.push('');\n\n // 联调任务\n lines.push('### 联调任务');\n lines.push('');\n for (const item of result.integrationTasks.items) {\n const icon = item.status === 'pass' ? '✓' : item.status === 'fail' ? '✗' : '⚠';\n lines.push(`- ${icon} ${item.description} - ${item.details || ''}`);\n }\n lines.push('');\n\n // 发现的问题\n if (result.issues.length > 0) {\n lines.push('## 发现的问题');\n lines.push('');\n lines.push('| 问题 | 类型 | 严重程度 | 状态 |');\n lines.push('|------|------|---------|------|');\n for (const issue of result.issues) {\n lines.push(`| ${issue.title} | ${issue.type} | ${issue.severity} | ${issue.status} |`);\n }\n lines.push('');\n lines.push('**操作**:');\n lines.push(`- 运行 \\`team-cli bugfix ${result.specFile}\\` 查看详情`);\n lines.push('- 或运行 `team-cli hotfix` 立即修复');\n lines.push('');\n }\n\n // 下一步建议\n lines.push('## 下一步建议');\n lines.push('');\n if (result.issues.length > 0) {\n lines.push('- [ ] 修复发现的问题');\n }\n lines.push('- [ ] 运行 `team-cli dev` 继续开发');\n lines.push(\"- [ ] 运行 `team-cli accept` 重新验收\");\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * 生成控制台报告摘要\n */\nfunction generateConsoleReport(result: AcceptanceResult): string {\n const lines: string[] = [];\n\n lines.push('┌──────────────────────────────────────────────┐');\n lines.push('│ 验 收 结 果 摘 要 │');\n lines.push('├──────────────────────────────────────────────┤');\n lines.push(`│ Spec: ${result.specFile.padEnd(40)}│`);\n lines.push(`│ Milestone: ${result.milestone.padEnd(37)}│`);\n lines.push('├──────────────────────────────────────────────┤');\n lines.push(\n `│ 前端任务: ${result.frontendTasks.completed}/${result.frontendTasks.total} 完成`.padEnd(47) + '│'\n );\n lines.push(\n `│ 后端任务: ${result.backendTasks.completed}/${result.backendTasks.total} 完成`.padEnd(47) + '│'\n );\n lines.push(\n `│ API 验证: ${result.apiVerification.verified}/${result.apiVerification.total} 实现`.padEnd(47) + '│'\n );\n lines.push(\n `│ 联调任务: ${result.integrationTasks.completed}/${result.integrationTasks.total} 完成`.padEnd(47) + '│'\n );\n lines.push('├──────────────────────────────────────────────┤');\n\n const totalIssues = result.issues.length;\n if (totalIssues > 0) {\n lines.push(`│ ⚠ 发现问题: ${totalIssues} 个`.padEnd(47) + '│');\n } else {\n lines.push(`│ ✓ 验收通过`.padEnd(47) + '│');\n }\n lines.push('└──────────────────────────────────────────────┘');\n\n return lines.join('\\n');\n}\n\n/**\n * 处理发现的问题\n */\nasync function handleIssues(result: AcceptanceResult): Promise<void> {\n logger.newLine();\n logger.warn(`发现 ${result.issues.length} 个问题需要处理`);\n\n // 自动创建 bugfix 记录\n const bugfixDir = 'docs/bugfixes';\n await FileUtils.ensureDir(bugfixDir);\n\n for (const issue of result.issues) {\n const bugfixFile = path.join(\n bugfixDir,\n `${new Date().toISOString().slice(0, 10)}_${issue.id}.md`\n );\n\n const bugfixContent = generateBugfixContent(result, issue);\n await FileUtils.write(bugfixFile, bugfixContent);\n\n logger.info(` 已创建 Bugfix 记录: ${bugfixFile}`);\n }\n\n logger.newLine();\n\n const { fixNow } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'fixNow',\n message: '是否立即修复发现的问题?',\n default: false,\n },\n ]);\n\n if (fixNow) {\n logger.info('请运行 `team-cli hotfix` 立即修复问题');\n } else {\n logger.info(`问题记录已保存到 ${bugfixDir} 目录`);\n logger.info(\"运行 `team-cli bugfix` 查看所有问题记录\");\n }\n}\n\n/**\n * 生成 Bugfix 内容\n */\nfunction generateBugfixContent(result: AcceptanceResult, issue: IssueRecord): string {\n const lines: string[] = [];\n\n lines.push('# Bugfix 记录');\n lines.push('');\n lines.push(`**ID**: ${issue.id}`);\n lines.push(`**创建时间**: ${issue.createdAt}`);\n lines.push(`**状态**: ${issue.status}`);\n lines.push('');\n lines.push('## 问题描述');\n lines.push('');\n lines.push(issue.description);\n lines.push('');\n lines.push('## 所属范围');\n lines.push('');\n lines.push(`- Spec: ${result.specFile}`);\n lines.push(`- Milestone: ${result.milestone}`);\n if (issue.todo) {\n lines.push(`- Todo: ${issue.todo}`);\n }\n lines.push('');\n lines.push('## 严重程度');\n lines.push('');\n lines.push(`- ${issue.severity.toUpperCase()}`);\n lines.push('');\n lines.push('## 问题类型');\n lines.push('');\n lines.push(`- ${issue.type}`);\n lines.push('');\n lines.push('## 解决方案');\n lines.push('');\n lines.push('<!-- TODO: 填写解决方案 -->');\n lines.push('');\n lines.push('## 验证步骤');\n lines.push('');\n lines.push('1. ');\n lines.push('2. ');\n lines.push('3. ');\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * 同步 Spec 状态\n */\nasync function syncSpecStatus(specFile: string, result: AcceptanceResult): Promise<void> {\n const content = await FileUtils.read(specFile);\n const lines = content.split('\\n');\n\n // 查找并更新里程碑状态\n let inTargetMilestone = false;\n let milestoneIndex = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (line.includes(result.milestone)) {\n inTargetMilestone = true;\n milestoneIndex = i;\n continue;\n }\n\n if (inTargetMilestone && line.match(/^###\\s+Milestone/)) {\n break;\n }\n }\n\n if (milestoneIndex !== -1) {\n // 统计已完成的 tasks\n let completedTasks = 0;\n let totalTasks = 0;\n\n for (let i = milestoneIndex + 1; i < lines.length; i++) {\n const line = lines[i];\n if (line.match(/^###\\s+Milestone/)) {\n break;\n }\n if (line.match(/^-\\s+\\[/)) {\n totalTasks++;\n if (line.match(/^-\\s+\\[x\\]/)) {\n completedTasks++;\n }\n }\n }\n\n // 更新进度标注\n const progressLine = `${result.milestone} [${completedTasks}/${totalTasks}]`;\n const linesBefore = lines.slice(0, milestoneIndex);\n const linesAfter = lines.slice(milestoneIndex + 1);\n\n // 检查是否已有进度标注\n if (!lines[milestoneIndex].includes(`[${completedTasks}/${totalTasks}]`)) {\n // 替换里程碑标题行\n const updatedMilestoneLine = lines[milestoneIndex].replace(\n /(\\s*\\[\\d+\\/\\d+\\])?$/,\n ` [${completedTasks}/${totalTasks}]`\n );\n lines[milestoneIndex] = updatedMilestoneLine;\n\n await FileUtils.write(specFile, lines.join('\\n'));\n logger.info(`已同步里程碑进度: [${completedTasks}/${totalTasks}]`);\n }\n }\n}\n\n// ==================== BDD 验收功能 ====================\n\n/**\n * 验收单个 BDD 场景\n */\nasync function checkBDDScenario(\n scenario: BDDScenario,\n specFile: string\n): Promise<BDDCheckResult> {\n const result: BDDCheckResult = {\n scenarioId: scenario.id,\n scenarioTitle: scenario.title,\n overallStatus: 'pending',\n givenResults: [],\n whenResults: [],\n thenResults: [],\n stateTransitionResults: [],\n };\n\n // 验证 Given 条件\n for (const given of scenario.given) {\n const checkResult = await verifyGivenCondition(given, specFile);\n result.givenResults.push(checkResult);\n }\n\n // 验证 When 动作\n for (const when of scenario.when) {\n const checkResult = await verifyWhenAction(when, specFile);\n result.whenResults.push(checkResult);\n }\n\n // 验证 Then 结果\n for (const then of scenario.then) {\n const checkResult = await verifyThenResult(then, specFile);\n result.thenResults.push(checkResult);\n }\n\n // 验证状态流转\n for (const transition of scenario.stateTransitions) {\n const checkResult = await verifyStateTransition(transition, specFile);\n result.stateTransitionResults.push(checkResult);\n }\n\n // 计算总体状态\n const allResults = [\n ...result.givenResults,\n ...result.whenResults,\n ...result.thenResults,\n ...result.stateTransitionResults,\n ];\n\n if (allResults.every(r => r.status === 'pass')) {\n result.overallStatus = 'pass';\n } else if (allResults.some(r => r.status === 'fail')) {\n result.overallStatus = 'fail';\n } else {\n result.overallStatus = 'pending';\n }\n\n return result;\n}\n\n/**\n * 验证 Given 条件\n */\nasync function verifyGivenCondition(\n given: BDDCondition,\n specFile: string\n): Promise<{ condition: string; status: 'pass' | 'fail' | 'pending'; evidence?: string }> {\n switch (given.type) {\n case 'data':\n return verifyDataCondition(given);\n case 'state':\n return verifyStateCondition(given);\n case 'user':\n return verifyUserCondition(given);\n default:\n return { condition: given.description, status: 'pending' };\n }\n}\n\n/**\n * 验证数据条件\n */\nasync function verifyDataCondition(\n given: BDDCondition\n): Promise<{ condition: string; status: 'pass' | 'fail' | 'pending'; evidence?: string }> {\n const tableMatch = given.description.match(/`?([a-z_]+)`?表/);\n const fieldMatch = given.description.match(/`?([a-z_]+)`?字段/);\n\n if (tableMatch) {\n const tableName = tableMatch[1];\n const tableFiles = await FileUtils.findFiles(`**/${tableName}.sql`, 'database');\n const entityFiles = await FileUtils.findFiles(`**/${StringUtils.toPascalCase(tableName)}.java`, 'backend/src');\n\n if (tableFiles.length > 0 || entityFiles.length > 0) {\n return {\n condition: given.description,\n status: 'pass',\n evidence: tableFiles[0] || entityFiles[0],\n };\n }\n\n return {\n condition: given.description,\n status: 'fail',\n evidence: `表 ${tableName} 未找到`,\n };\n }\n\n return { condition: given.description, status: 'pending' };\n}\n\n/**\n * 验证状态条件\n */\nasync function verifyStateCondition(\n given: BDDCondition\n): Promise<{ condition: string; status: 'pass' | 'fail' | 'pending'; evidence?: string }> {\n const statusMatch = given.description.match(/`([^`]+)`状态/);\n const stateMatch = given.description.match(/`([^`]+)`/);\n\n const statusName = statusMatch?.[1] || stateMatch?.[1];\n\n if (statusName) {\n const enumFiles = [\n ...(await FileUtils.findFiles('**/*Status*.java', 'backend/src')),\n ...(await FileUtils.findFiles('**/*Status*.ts', 'frontend/src')),\n ];\n\n for (const ef of enumFiles) {\n const content = await FileUtils.read(ef);\n if (content.includes(statusName)) {\n return {\n condition: given.description,\n status: 'pass',\n evidence: ef,\n };\n }\n }\n\n return {\n condition: given.description,\n status: 'fail',\n evidence: `状态 ${statusName} 未找到`,\n };\n }\n\n return { condition: given.description, status: 'pending' };\n}\n\n/**\n * 验证用户条件\n */\nasync function verifyUserCondition(\n given: BDDCondition\n): Promise<{ condition: string; status: 'pass' | 'fail' | 'pending'; evidence?: string }> {\n // 验证用户相关条件,通常需要检查用户表\n const userMatch = given.description.match(/用户.*?`([^`]+)`/);\n if (userMatch) {\n return {\n condition: given.description,\n status: 'pending',\n evidence: '需要人工验证用户状态',\n };\n }\n\n return { condition: given.description, status: 'pending' };\n}\n\n/**\n * 验证 When 动作\n */\nasync function verifyWhenAction(\n when: BDDAction,\n specFile: string\n): Promise<{ action: string; status: 'pass' | 'fail' | 'pending'; apiCalled?: string; responseCode?: number }> {\n if (when.api) {\n const apiCheck = await verifyApiImplementationByPath(when.api);\n return {\n action: when.description,\n status: apiCheck.status,\n apiCalled: when.api,\n responseCode: apiCheck.responseCode,\n };\n }\n\n if (when.uiAction) {\n const uiCheck = await verifyUIComponent(when.uiAction);\n return {\n action: when.description,\n status: uiCheck.status,\n };\n }\n\n return { action: when.description, status: 'pending' };\n}\n\n/**\n * 通过 API 路径验证实现\n */\nasync function verifyApiImplementationByPath(\n apiPath: string\n): Promise<{ status: 'pass' | 'fail' | 'pending'; responseCode?: number }> {\n const apiMatch = apiPath.match(/(GET|POST|PUT|DELETE|PATCH)\\s+\\/?(.+)/i);\n if (!apiMatch) {\n return { status: 'pending' };\n }\n\n const method = apiMatch[1].toUpperCase();\n const path = '/' + apiMatch[2];\n\n const controllerFiles = await FileUtils.findFiles('**/*Controller.java', 'backend/src');\n\n for (const cf of controllerFiles) {\n const content = await FileUtils.read(cf);\n\n if (content.includes(`\"${path}\"`) || content.includes(`\"${path}/\"`)) {\n const annotationMap: Record<string, string[]> = {\n GET: ['@GetMapping', '@RequestMapping(method = RequestMethod.GET)'],\n POST: ['@PostMapping', '@RequestMapping(method = RequestMethod.POST)'],\n PUT: ['@PutMapping', '@RequestMapping(method = RequestMethod.PUT)'],\n DELETE: ['@DeleteMapping', '@RequestMapping(method = RequestMethod.DELETE)'],\n };\n\n for (const annotation of annotationMap[method] || []) {\n if (content.includes(annotation)) {\n return { status: 'pass', responseCode: 200 };\n }\n }\n }\n }\n\n return { status: 'fail' };\n}\n\n/**\n * 验证 UI 组件\n */\nasync function verifyUIComponent(\n uiAction: string\n): Promise<{ status: 'pass' | 'fail' | 'pending' }> {\n const componentFiles = await FileUtils.findFiles('**/*.tsx', 'frontend/src');\n const viewFiles = await FileUtils.findFiles('**/*.vue', 'frontend/src');\n\n const allFiles = [...componentFiles, ...viewFiles];\n\n for (const cf of allFiles) {\n const content = await FileUtils.read(cf);\n if (content.includes(uiAction) || content.toLowerCase().includes(uiAction.toLowerCase())) {\n return { status: 'pass' };\n }\n }\n\n return { status: 'pending' };\n}\n\n/**\n * 验证 Then 结果\n */\nasync function verifyThenResult(\n then: BDDResult,\n specFile: string\n): Promise<{ result: string; status: 'pass' | 'fail' | 'pending'; actualValue?: string; expectedValue?: string }> {\n switch (then.type) {\n case 'response':\n return verifyResponseResult(then);\n case 'state':\n return verifyStateResult(then);\n case 'data':\n return verifyDataResult(then);\n case 'ui':\n return verifyUIResult(then);\n default:\n return { result: then.description, status: 'pending' };\n }\n}\n\n/**\n * 验证响应结果\n */\nasync function verifyResponseResult(\n then: BDDResult\n): Promise<{ result: string; status: 'pass' | 'fail' | 'pending'; actualValue?: string; expectedValue?: string }> {\n const codeMatch = then.description.match(/状态码\\s*(\\d+)/);\n const tokenMatch = then.description.match(/token/i);\n\n if (tokenMatch) {\n const tokenFiles = await FileUtils.findFiles('**/*Token*.java', 'backend/src');\n if (tokenFiles.length > 0) {\n return { result: then.description, status: 'pass', expectedValue: 'JWT Token' };\n }\n return { result: then.description, status: 'pending' };\n }\n\n if (codeMatch) {\n return { result: then.description, status: 'pending', expectedValue: `HTTP ${codeMatch[1]}` };\n }\n\n return { result: then.description, status: 'pending' };\n}\n\n/**\n * 验证状态结果\n */\nasync function verifyStateResult(\n then: BDDResult\n): Promise<{ result: string; status: 'pass' | 'fail' | 'pending'; actualValue?: string; expectedValue?: string }> {\n const stateMatch = then.description.match(/`([^`]+)`/);\n if (stateMatch) {\n const stateName = stateMatch[1];\n const enumFiles = [\n ...(await FileUtils.findFiles('**/*Status*.java', 'backend/src')),\n ...(await FileUtils.findFiles('**/*Status*.ts', 'frontend/src')),\n ];\n\n for (const ef of enumFiles) {\n const content = await FileUtils.read(ef);\n if (content.includes(stateName)) {\n return { result: then.description, status: 'pass', expectedValue: stateName };\n }\n }\n\n return { result: then.description, status: 'fail', expectedValue: stateName };\n }\n\n return { result: then.description, status: 'pending' };\n}\n\n/**\n * 验证数据结果\n */\nasync function verifyDataResult(\n then: BDDResult\n): Promise<{ result: string; status: 'pass' | 'fail' | 'pending'; actualValue?: string; expectedValue?: string }> {\n return { result: then.description, status: 'pending' };\n}\n\n/**\n * 验证 UI 结果\n */\nasync function verifyUIResult(\n then: BDDResult\n): Promise<{ result: string; status: 'pass' | 'fail' | 'pending'; actualValue?: string; expectedValue?: string }> {\n return { result: then.description, status: 'pending' };\n}\n\n/**\n * 验证状态流转\n */\nasync function verifyStateTransition(\n transition: { from: string; trigger: string; to: string },\n specFile: string\n): Promise<{ transition: string; status: 'pass' | 'fail' | 'pending'; fromState?: string; toState?: string }> {\n const { from, trigger, to } = transition;\n\n const enumFiles = [\n ...(await FileUtils.findFiles('**/*Status*.java', 'backend/src')),\n ...(await FileUtils.findFiles('**/*Status*.ts', 'frontend/src')),\n ...(await FileUtils.findFiles('**/*State*.ts', 'frontend/src')),\n ];\n\n const fromExists = await checkStateExists(from, enumFiles);\n const toExists = await checkStateExists(to, enumFiles);\n\n if (!fromExists || !toExists) {\n return {\n transition: `\\`${from}\\` → \\`${to}\\``,\n status: 'fail',\n fromState: fromExists ? '✓' : '✗',\n toState: toExists ? '✓' : '✗',\n };\n }\n\n const serviceFiles = await FileUtils.findFiles('**/*Service*.java', 'backend/src');\n\n for (const sf of serviceFiles) {\n const content = await FileUtils.read(sf);\n const methodPatterns = [\n new RegExp(`${from}\\\\s*→\\\\s*${to}`, 'i'),\n new RegExp(`from\\\\s*${from}\\\\s*to\\\\s*${to}`, 'i'),\n ];\n\n for (const pattern of methodPatterns) {\n if (pattern.test(content)) {\n return {\n transition: `\\`${from}\\` → \\`${to}\\` (${trigger})`,\n status: 'pass',\n fromState: from,\n toState: to,\n };\n }\n }\n }\n\n return {\n transition: `\\`${from}\\` → \\`${to}\\` (${trigger})`,\n status: 'pending',\n fromState: from,\n toState: to,\n };\n}\n\n/**\n * 检查状态是否存在\n */\nasync function checkStateExists(state: string, files: string[]): Promise<boolean> {\n for (const file of files) {\n try {\n const content = await FileUtils.read(file);\n if (content.includes(state) || content.includes(`\"${state}\"`)) {\n return true;\n }\n } catch {\n continue;\n }\n }\n return false;\n}\n\n/**\n * 打印场景验收结果\n */\nfunction printScenarioResult(result: BDDCheckResult): void {\n const icon = result.overallStatus === 'pass' ? '✓' : result.overallStatus === 'fail' ? '✗' : '○';\n console.log('');\n console.log(` ${icon} 场景: ${result.scenarioTitle}`);\n\n const passGiven = result.givenResults.filter(r => r.status === 'pass').length;\n const passWhen = result.whenResults.filter(r => r.status === 'pass').length;\n const passThen = result.thenResults.filter(r => r.status === 'pass').length;\n const passTrans = result.stateTransitionResults.filter(r => r.status === 'pass').length;\n\n console.log(` Given: ${passGiven}/${result.givenResults.length}`);\n console.log(` When: ${passWhen}/${result.whenResults.length}`);\n console.log(` Then: ${passThen}/${result.thenResults.length}`);\n console.log(` State: ${passTrans}/${result.stateTransitionResults.length}`);\n}\n\n/**\n * 生成 BDD 验收报告\n */\nasync function generateBDDReport(specFile: string, results: BDDCheckResult[]): Promise<void> {\n const reportDir = 'docs/bdd-reports';\n await FileUtils.ensureDir(reportDir);\n\n const timestamp = new Date().toISOString().slice(0, 10);\n const specName = path.basename(specFile, '.md');\n const reportFile = path.join(reportDir, `${timestamp}_${specName}_bdd.md`);\n\n const lines: string[] = [];\n\n lines.push('# BDD 验收报告');\n lines.push('');\n lines.push(`**Spec 文件**: ${specFile}`);\n lines.push(`**验收时间**: ${new Date().toLocaleString('zh-CN')}`);\n lines.push(`**场景数量**: ${results.length}`);\n lines.push('');\n\n // 汇总\n lines.push('## 验收汇总');\n lines.push('');\n\n let totalPass = 0;\n let totalFail = 0;\n\n for (const r of results) {\n const statusIcon = r.overallStatus === 'pass' ? '✓' : r.overallStatus === 'fail' ? '✗' : '○';\n const givenIcon = r.givenResults.every(g => g.status === 'pass') ? '✓' :\n r.givenResults.some(g => g.status === 'fail') ? '✗' : '○';\n const whenIcon = r.whenResults.every(w => w.status === 'pass') ? '✓' :\n r.whenResults.some(w => w.status === 'fail') ? '✗' : '○';\n const thenIcon = r.thenResults.every(t => t.status === 'pass') ? '✓' :\n r.thenResults.some(t => t.status === 'fail') ? '✗' : '○';\n const transIcon = r.stateTransitionResults.every(t => t.status === 'pass') ? '✓' :\n r.stateTransitionResults.some(t => t.status === 'fail') ? '✗' : '○';\n\n lines.push(`- ${statusIcon} ${r.scenarioTitle} | Given:${givenIcon} When:${whenIcon} Then:${thenIcon} State:${transIcon}`);\n\n if (r.overallStatus === 'pass') totalPass++;\n if (r.overallStatus === 'fail') totalFail++;\n }\n\n lines.push('');\n lines.push(`**总计**: ${totalPass} 个通过, ${totalFail} 个失败, ${results.length - totalPass - totalFail} 个待验证`);\n lines.push('');\n\n // 详细结果\n lines.push('## 详细验收结果');\n lines.push('');\n\n for (const r of results) {\n lines.push(`### 场景: ${r.scenarioTitle}`);\n lines.push('');\n\n lines.push('#### GIVEN (前置条件)');\n for (const g of r.givenResults) {\n const icon = g.status === 'pass' ? '✓' : g.status === 'fail' ? '✗' : '○';\n lines.push(`- ${icon} ${g.condition}`);\n if (g.evidence) {\n lines.push(` - 证据: ${g.evidence}`);\n }\n }\n lines.push('');\n\n lines.push('#### WHEN (触发动作)');\n for (const w of r.whenResults) {\n const icon = w.status === 'pass' ? '✓' : w.status === 'fail' ? '✗' : '○';\n lines.push(`- ${icon} ${w.action}`);\n if (w.apiCalled) {\n lines.push(` - API: ${w.apiCalled}`);\n }\n }\n lines.push('');\n\n lines.push('#### THEN (预期结果)');\n for (const t of r.thenResults) {\n const icon = t.status === 'pass' ? '✓' : t.status === 'fail' ? '✗' : '○';\n lines.push(`- ${icon} ${t.result}`);\n }\n lines.push('');\n\n lines.push('#### 状态流转');\n for (const s of r.stateTransitionResults) {\n const icon = s.status === 'pass' ? '✓' : s.status === 'fail' ? '✗' : '○';\n lines.push(`- ${icon} ${s.transition}`);\n }\n lines.push('');\n lines.push('---');\n lines.push('');\n }\n\n await FileUtils.write(reportFile, lines.join('\\n'));\n\n logger.success(`BDD 验收报告已生成: ${reportFile}`);\n}\n\n/**\n * 同步 BDD 验收状态\n */\nasync function syncBDDStatus(specFile: string, results: BDDCheckResult[]): Promise<void> {\n const allPassed = results.every(r => r.overallStatus === 'pass');\n\n if (allPassed) {\n logger.success('所有 BDD 场景验收通过');\n } else {\n const failedCount = results.filter(r => r.overallStatus === 'fail').length;\n logger.warn(`${failedCount} 个场景验收未通过,需要修复`);\n }\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\n\n/**\n * 模块配置接口\n */\ninterface ModuleConfig {\n name: string; // 模块名 (目录名)\n type: 'service' | 'api' | 'common'; // 模块类型\n packagePath: string; // 包路径 (groupId + name)\n applicationClass: string; // 启动类名\n}\n\n/**\n * Add-Module 命令 - 为已有项目新增模块\n */\nexport const addModuleCommand = new Command('add-module')\n .description('为已有项目新增模块 (多模块 Gradle 项目)')\n .action(async () => {\n try {\n logger.header('新增模块');\n logger.newLine();\n\n // 1. 检查是否在项目根目录\n const projectPath = process.cwd();\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info('请切换到项目根目录后再执行此命令');\n process.exit(1);\n }\n\n // 2. 扫描现有模块\n const existingModules = await scanExistingModules(projectPath);\n\n if (existingModules.length > 0) {\n logger.success(`检测到现有模块: [${existingModules.join(', ')}]`);\n } else {\n logger.info('未检测到现有模块');\n }\n logger.newLine();\n\n // 3. 获取 Group ID (从 build.gradle 或 settings.gradle)\n const groupId = await detectGroupId(projectPath);\n logger.info(`检测到 Group ID: ${groupId}`);\n logger.newLine();\n\n // 4. 获取 rootProjectName\n const rootProjectName = await detectRootProjectName(projectPath);\n logger.info(`检测到根项目名: ${rootProjectName}`);\n logger.newLine();\n\n // 5. 收集新模块配置\n const newModules: ModuleConfig[] = [];\n let addMore = true;\n let moduleIndex = 1;\n\n while (addMore) {\n const moduleNameAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'moduleName',\n message: `请输入第 ${moduleIndex} 个新模块名称 (目录名):`,\n validate: (input: string) => {\n if (!/^[a-z][a-z0-9-]*$/.test(input)) {\n return '模块名只能以小写字母开头,包含小写字母、数字和连字符';\n }\n if (existingModules.includes(input)) {\n return '该模块已存在';\n }\n return true;\n },\n },\n ]);\n\n const moduleName = moduleNameAnswer.moduleName;\n\n // 模块类型\n const typeAnswer = await inquirer.prompt([\n {\n type: 'list',\n name: 'moduleType',\n message: `模块 \"${moduleName}\" 类型:`,\n choices: [\n { name: 'API 服务模块 (独立部署)', value: 'service' },\n { name: '公共模块 (被其他模块依赖)', value: 'common' },\n { name: 'API 接口模块 (仅接口定义)', value: 'api' },\n ],\n default: 'service',\n },\n ]);\n\n // 确认包路径\n const defaultPackage = `${groupId}.${moduleName}`;\n const packageAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'packagePath',\n message: '模块包路径:',\n default: defaultPackage,\n validate: (input: string) => {\n if (!/^[a-z][a-z0-9]*(\\.[a-z][a-z0-9]*)*$/.test(input)) {\n return '包路径格式不正确';\n }\n return true;\n },\n },\n ]);\n\n // 启动类名\n const pascalName = toPascalCase(moduleName);\n const classAnswer = await inquirer.prompt([\n {\n type: 'input',\n name: 'applicationClass',\n message: '启动类名:',\n default: `${pascalName}Application`,\n },\n ]);\n\n newModules.push({\n name: moduleName,\n type: typeAnswer.moduleType,\n packagePath: packageAnswer.packagePath,\n applicationClass: classAnswer.applicationClass,\n });\n\n // 是否继续添加\n const moreAnswer = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'addMore',\n message: '是否还需要添加更多模块?',\n default: false,\n },\n ]);\n addMore = moreAnswer.addMore;\n moduleIndex++;\n }\n\n logger.newLine();\n logger.info(`将新增模块: ${newModules.map(m => m.name).join(', ')}`);\n logger.newLine();\n\n // 6. 创建模块结构\n for (const module of newModules) {\n await createModuleStructure(projectPath, module, groupId);\n }\n\n // 7. 更新 settings.gradle\n await updateSettingsGradle(projectPath, rootProjectName, newModules);\n\n logger.newLine();\n logger.success('模块创建完成!');\n logger.newLine();\n\n // 8. 显示下一步\n logger.info('下一步:');\n logger.step('1. 运行 `team-cli breakdown docs/specs/xxx.md` 拆分需求');\n logger.step('2. 运行 `team-cli dev` 开始开发');\n logger.newLine();\n\n } catch (error: any) {\n logger.error(`新增模块失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 扫描现有模块\n */\nasync function scanExistingModules(projectPath: string): Promise<string[]> {\n const modules: string[] = [];\n\n // 检查 settings.gradle\n const settingsGradle = path.join(projectPath, 'settings.gradle');\n if (await FileUtils.exists(settingsGradle)) {\n const content = await FileUtils.read(settingsGradle);\n const includeMatches = content.match(/include\\s+'([^']+)'/g);\n if (includeMatches) {\n for (const match of includeMatches) {\n const moduleName = match.replace(/include\\s+'/, '').replace(/'/, '');\n modules.push(moduleName);\n }\n }\n }\n\n // 检查 backend 目录下的子目录\n const backendPath = path.join(projectPath, 'backend');\n if (await FileUtils.exists(backendPath)) {\n const entries = await fs.readdir(backendPath, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'src') {\n if (!modules.includes(entry.name)) {\n modules.push(entry.name);\n }\n }\n }\n }\n\n return modules;\n}\n\n/**\n * 检测 Group ID\n */\nasync function detectGroupId(projectPath: string): Promise<string> {\n // 1. 尝试从 build.gradle 读取\n const buildGradle = path.join(projectPath, 'backend', 'build.gradle');\n if (await FileUtils.exists(buildGradle)) {\n const content = await FileUtils.read(buildGradle);\n const groupMatch = content.match(/group\\s*=\\s*['\"]([^'\"]+)['\"]/);\n if (groupMatch) {\n return groupMatch[1];\n }\n }\n\n // 2. 尝试从根 build.gradle 读取\n const rootBuildGradle = path.join(projectPath, 'build.gradle');\n if (await FileUtils.exists(rootBuildGradle)) {\n const content = await FileUtils.read(rootBuildGradle);\n const groupMatch = content.match(/group\\s*=\\s*['\"]([^'\"]+)['\"]/);\n if (groupMatch) {\n return groupMatch[1];\n }\n }\n\n // 3. 尝试从现有模块的 Java 文件读取\n const backendPath = path.join(projectPath, 'backend');\n if (await FileUtils.exists(backendPath)) {\n const entries = await fs.readdir(backendPath, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory() && !entry.name.startsWith('.')) {\n const srcPath = path.join(backendPath, entry.name, 'src', 'main', 'java');\n if (await FileUtils.exists(srcPath)) {\n const javaDirs = await fs.readdir(srcPath);\n if (javaDirs.length > 0) {\n return javaDirs[0];\n }\n }\n }\n }\n }\n\n // 默认值\n return 'org.yungu';\n}\n\n/**\n * 检测根项目名\n */\nasync function detectRootProjectName(projectPath: string): Promise<string> {\n const settingsGradle = path.join(projectPath, 'settings.gradle');\n if (await FileUtils.exists(settingsGradle)) {\n const content = await FileUtils.read(settingsGradle);\n const rootMatch = content.match(/rootProject\\.name\\s*=\\s*['\"]([^'\"]+)['\"]/);\n if (rootMatch) {\n return rootMatch[1];\n }\n }\n\n // 默认使用目录名\n return path.basename(projectPath);\n}\n\n/**\n * 创建模块目录结构\n */\nasync function createModuleStructure(\n projectPath: string,\n module: ModuleConfig,\n groupId: string\n): Promise<void> {\n const modulePath = path.join(projectPath, 'backend', module.name);\n\n logger.info(`正在创建模块: ${module.name}...`);\n\n // 根据模块类型创建不同结构\n const baseDirs = [\n 'src/main/java',\n 'src/main/resources',\n 'src/test/java',\n ];\n\n for (const dir of baseDirs) {\n await FileUtils.ensureDir(path.join(modulePath, dir));\n }\n\n // 创建 Java 包路径\n const packageDirs = module.packagePath.split('.');\n let javaPath = path.join(modulePath, 'src', 'main', 'java');\n\n // 根据模块类型创建不同的子目录\n if (module.type === 'service') {\n // 服务模块:controller, service, mapper, entity, dto, config\n for (const subDir of ['controller', 'service', 'mapper', 'entity', 'dto', 'config']) {\n await FileUtils.ensureDir(path.join(javaPath, ...packageDirs, subDir));\n }\n\n // 创建 Application 启动类\n await createApplicationClass(\n path.join(javaPath, ...packageDirs, 'config', `${module.applicationClass}.java`),\n module.packagePath,\n module.applicationClass\n );\n\n } else if (module.type === 'api') {\n // API 模块:model, constant, enums\n for (const subDir of ['model', 'constant', 'enums', 'exception']) {\n await FileUtils.ensureDir(path.join(javaPath, ...packageDirs, subDir));\n }\n\n } else {\n // 公共模块:util, common, config, manager\n for (const subDir of ['util', 'common', 'config', 'manager']) {\n await FileUtils.ensureDir(path.join(javaPath, ...packageDirs, subDir));\n }\n }\n\n // 创建 build.gradle\n await createModuleBuildGradle(\n path.join(modulePath, 'build.gradle'),\n module,\n groupId\n );\n\n // 创建 .gitignore\n const gitignore = `# Gradle\n.gradle/\nbuild/\n\n# IDE\n.idea/\n*.iml\n*.ipr\n*.iws\n.vscode/\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\nlogs/\n*.log\n\n# Application\napplication-local.yml\napplication-dev.yml\n`;\n await FileUtils.write(path.join(modulePath, '.gitignore'), gitignore);\n\n logger.success(`模块 ${module.name} 创建完成`);\n}\n\n/**\n * 创建 Application 启动类\n */\nasync function createApplicationClass(\n filePath: string,\n packagePath: string,\n className: string\n): Promise<void> {\n const content = `package ${packagePath}.config;\n\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.annotation.ComponentScan;\n\n@SpringBootApplication\n@ComponentScan(\"${packagePath}\")\n@Slf4j\npublic class ${className} {\n\n public static void main(String[] args) {\n ApplicationContext context = SpringApplication.run(${className}.class, args);\n log.info(\"${className} 启动成功!\");\n }\n}\n`;\n await FileUtils.write(filePath, content);\n}\n\n/**\n * 创建模块的 build.gradle\n */\nasync function createModuleBuildGradle(\n filePath: string,\n module: ModuleConfig,\n groupId: string\n): Promise<void> {\n let dependencies = '';\n\n if (module.type === 'service') {\n dependencies = `\ndependencies {\n implementation project(\":common\")\n implementation 'org.springframework.boot:spring-boot-starter-web'\n implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter'\n implementation 'com.alibaba:druid-spring-boot-starter'\n compileOnly \"org.projectlombok:lombok\"\n annotationProcessor \"org.projectlombok:lombok\"\n}\n`;\n } else if (module.type === 'api') {\n dependencies = `\ndependencies {\n compileOnly 'org.springframework.boot:spring-boot-starter'\n compileOnly \"org.projectlombok:lombok\"\n annotationProcessor \"org.projectlombok:lombok\"\n}\n`;\n } else {\n dependencies = `\ndependencies {\n implementation 'org.springframework.boot:spring-boot-starter'\n implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter'\n compileOnly \"org.projectlombok:lombok\"\n annotationProcessor \"org.projectlombok:lombok\"\n}\n`;\n }\n\n const content = `plugins {\n id 'java-library'\n id 'org.springframework.boot' version '3.2.0'\n id 'io.spring.dependency-management' version '1.1.4'\n}\n\ngroup = '${groupId}'\nversion = '0.0.1-SNAPSHOT'\n\njava {\n sourceCompatibility = '17'\n}\n\nrepositories {\n maven { url 'https://maven.aliyun.com/repository/public/' }\n}\n\n${dependencies}\n`;\n await FileUtils.write(filePath, content);\n}\n\n/**\n * 更新 settings.gradle\n */\nasync function updateSettingsGradle(\n projectPath: string,\n rootProjectName: string,\n newModules: ModuleConfig[]\n): Promise<void> {\n const settingsPath = path.join(projectPath, 'backend', 'settings.gradle');\n\n let content = '';\n if (await FileUtils.exists(settingsPath)) {\n content = await FileUtils.read(settingsPath);\n } else {\n content = `rootProject.name = '${rootProjectName}'\n`;\n }\n\n // 解析现有的 include 语句\n const existingModules = new Set<string>();\n const moduleMatches = content.matchAll(/include\\s+'([^']+)'/g);\n for (const match of moduleMatches) {\n existingModules.add(match[1]);\n }\n\n // 添加新模块\n for (const module of newModules) {\n if (!existingModules.has(module.name)) {\n existingModules.add(module.name);\n }\n }\n\n // 重新生成文件内容\n const lines: string[] = [];\n lines.push(`rootProject.name = '${rootProjectName}'`);\n lines.push('');\n\n // 添加所有模块\n const allModules = Array.from(existingModules).sort();\n for (const module of allModules) {\n lines.push(`include '${module}'`);\n }\n\n await FileUtils.write(settingsPath, lines.join('\\n'));\n logger.success('settings.gradle 已更新');\n}\n\n/**\n * 字符串转 PascalCase\n */\nfunction toPascalCase(str: string): string {\n return str\n .split(/[-_]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n","import { Command } from 'commander';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { execa } from 'execa';\n\n/**\n * Lint 命令 - 代码质量检查\n */\nexport const lintCommand = new Command('lint')\n .option('--fix', '自动修复问题')\n .option('--no-type-check', '跳过 TypeScript 类型检查')\n .description('代码质量检查 (前端 + 后端)')\n .action(async (options) => {\n try {\n logger.header('代码质量检查');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n interface LintResult {\n exists: boolean;\n passed: boolean;\n errors: string[];\n }\n\n const results: { frontend: LintResult; backend: LintResult } = {\n frontend: { exists: false, passed: false, errors: [] },\n backend: { exists: false, passed: false, errors: [] },\n };\n\n // 检查前端\n const frontendExists = await FileUtils.exists('frontend/package.json');\n if (frontendExists) {\n results.frontend.exists = true;\n try {\n logger.step('检查前端代码...');\n\n // ESLint 检查\n if (options.fix) {\n await execa('npm', ['run', 'lint', '--', '--fix'], {\n cwd: 'frontend',\n stdio: 'inherit',\n });\n } else {\n await execa('npm', ['run', 'lint'], {\n cwd: 'frontend',\n stdio: 'inherit',\n });\n }\n\n // TypeScript 类型检查\n if (options.typeCheck !== false) {\n try {\n logger.step('正在进行 TypeScript 类型检查...');\n await execa('npx', ['tsc', '--noEmit'], {\n cwd: 'frontend',\n stdio: 'pipe',\n });\n } catch (tscError: any) {\n logger.warn('TypeScript 类型检查发现问题,请检查代码类型安全。');\n if (process.env.DEBUG) {\n console.log(tscError.stdout);\n }\n // 仅作为警告,不阻塞整体通过逻辑(如果 eslint 已通过)\n results.frontend.errors.push('TypeScript 类型检查失败 (已跳过阻塞)');\n }\n }\n\n results.frontend.passed = true;\n logger.success('前端代码检查通过');\n } catch (error: any) {\n results.frontend.errors.push(error.message);\n logger.error(`前端代码检查失败: ${error.message}`);\n }\n } else {\n logger.info('未找到前端项目 (frontend/package.json)');\n }\n\n logger.newLine();\n\n // 检查后端\n const backendExists = await FileUtils.exists('backend/build.gradle') ||\n await FileUtils.exists('backend/pom.xml');\n if (backendExists) {\n results.backend.exists = true;\n\n // 检查构建工具\n const hasGradle = await FileUtils.exists('backend/build.gradle') ||\n await FileUtils.exists('backend/build.gradle.kts');\n const hasMaven = await FileUtils.exists('backend/pom.xml');\n\n try {\n logger.step('检查后端代码...');\n\n if (hasGradle) {\n // Gradle 构建\n if (options.fix) {\n await execa('./gradlew', ['spotlessApply'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n }\n await execa('./gradlew', ['checkstyleMain', 'compileJava'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n } else if (hasMaven) {\n // Maven 构建\n if (options.fix) {\n await execa('./mvnw', ['spotless:apply'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n }\n await execa('./mvnw', ['checkstyle:check', 'compile'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n }\n\n results.backend.passed = true;\n logger.success('后端代码检查通过');\n } catch (error: any) {\n results.backend.errors.push(error.message);\n logger.error('后端代码检查失败');\n }\n } else {\n logger.info('未找到后端项目 (build.gradle 或 pom.xml)');\n }\n\n logger.newLine();\n logger.separator('=', 50);\n logger.newLine();\n\n // 汇总结果\n let hasErrors = false;\n\n if (results.frontend.exists) {\n if (results.frontend.passed) {\n logger.success('前端: ✓ 通过');\n } else {\n logger.error('前端: ✗ 失败');\n hasErrors = true;\n }\n }\n\n if (results.backend.exists) {\n if (results.backend.passed) {\n logger.success('后端: ✓ 通过');\n } else {\n logger.error('后端: ✗ 失败');\n hasErrors = true;\n }\n }\n\n logger.newLine();\n\n if (hasErrors) {\n logger.error('代码检查失败');\n logger.info(\"运行 'team-cli lint --fix' 尝试自动修复\");\n process.exit(1);\n } else {\n logger.success('代码检查全部通过');\n }\n } catch (error: any) {\n logger.error(`代码检查失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils, GitUtils, SpecUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\n\n/**\n * Status 命令 - 查看项目状态\n */\nexport const statusCommand = new Command('status')\n .description('查看项目状态')\n .action(async () => {\n try {\n logger.header('项目状态');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 显示项目信息\n await displayProjectInfo();\n\n // 显示功能清单\n await displayFeatureInventory();\n\n // 显示 Git 状态\n await displayGitStatus();\n\n // 显示最近活动\n await displayRecentActivity();\n } catch (error: any) {\n logger.error(`获取状态失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 显示项目信息\n */\nasync function displayProjectInfo(): Promise<void> {\n logger.info('项目信息:');\n logger.newLine();\n\n // 读取项目名称\n if (await FileUtils.exists('AI_MEMORY.md')) {\n const content = await FileUtils.read('AI_MEMORY.md');\n const projectName = content.match(/项目名称.*[::]\\s*(.+)/);\n const currentPhase = content.match(/当前阶段.*[::]\\s*(.+)/);\n const lastUpdated = content.match(/最后更新.*[::]\\s*(.+)/);\n\n if (projectName) logger.step(`名称: ${projectName[1].trim()}`);\n if (currentPhase) logger.step(`阶段: ${currentPhase[1].trim()}`);\n if (lastUpdated) logger.step(`更新: ${lastUpdated[1].trim()}`);\n } else {\n logger.step('AI_MEMORY.md 不存在');\n }\n\n logger.newLine();\n}\n\n/**\n * 显示功能清单\n */\nasync function displayFeatureInventory(): Promise<void> {\n logger.info('功能清单:');\n logger.newLine();\n\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n\n if (!exists) {\n logger.info(' (无 spec 文件)');\n logger.newLine();\n return;\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n if (specs.length === 0) {\n logger.info(' (无 spec 文件)');\n logger.newLine();\n return;\n }\n\n // 解析每个 spec 的状态\n const inventory: Array<{\n name: string;\n status: string;\n progress: string;\n }> = [];\n\n for (const file of specs) {\n const filePath = path.join(specDir, file);\n const content = await FileUtils.read(filePath);\n const status = SpecUtils.parseSpecStatus(content);\n const statusWithIcon = SpecUtils.getStatusWithIcon(status);\n\n inventory.push({\n name: file.replace('.md', ''),\n status: statusWithIcon,\n progress: SpecUtils.getProgress(content),\n });\n }\n\n // 显示表格\n const tableData = inventory.map((item) => [\n item.name,\n item.status,\n item.progress,\n ]);\n\n logger.table(['功能', '状态', '进度'], tableData);\n logger.newLine();\n\n // 统计\n const completed = inventory.filter((i) => i.status.includes('已完成')).length;\n const inProgress = inventory.filter((i) => i.status.includes('进行中')).length;\n const pending = inventory.filter((i) => i.status.includes('未开始')).length;\n\n logger.info(`总计: ${inventory.length} | 已完成: ${completed} | 进行中: ${inProgress} | 未开始: ${pending}`);\n logger.newLine();\n}\n\n/**\n * 显示 Git 状态\n */\nasync function displayGitStatus(): Promise<void> {\n const isRepo = await GitUtils.isGitRepo();\n\n if (!isRepo) {\n logger.info('Git 状态: 非 Git 仓库');\n logger.newLine();\n return;\n }\n\n try {\n const branch = await GitUtils.getCurrentBranch();\n const commit = await GitUtils.getCurrentCommit();\n\n logger.info('Git 状态:');\n logger.step(`分支: ${branch}`);\n logger.step(`提交: ${commit}`);\n logger.newLine();\n } catch {\n logger.info('Git 状态: 无法获取');\n logger.newLine();\n }\n}\n\n/**\n * 显示最近活动\n */\nasync function displayRecentActivity(): Promise<void> {\n logger.info('最近活动:');\n logger.newLine();\n\n // 检查会话日志\n const sessionDir = 'docs/sessions';\n const exists = await FileUtils.exists(sessionDir);\n\n if (!exists) {\n logger.info(' (无会话记录)');\n logger.newLine();\n return;\n }\n\n const files = await FileUtils.findFiles('*.md', sessionDir);\n if (files.length === 0) {\n logger.info(' (无会话记录)');\n logger.newLine();\n return;\n }\n\n // 按时间排序,取最近 5 个\n const sorted = files.sort().reverse().slice(0, 5);\n\n for (const file of sorted) {\n const filePath = path.join(sessionDir, file);\n const stat = await FileUtils.read(filePath);\n const specMatch = stat.match(/\\*\\*Spec\\*\\*:\\s*(.+)/);\n const spec = specMatch ? specMatch[1].trim() : '未知';\n\n // 从文件名提取时间\n const match = file.match(/(\\d{4}-\\d{2}-\\d{2})/);\n const date = match ? match[1] : '未知';\n\n logger.step(`${date} - ${spec}`);\n }\n\n logger.newLine();\n\n if (files.length > 5) {\n logger.info(`(还有 ${files.length - 5} 个历史会话记录)`);\n logger.newLine();\n }\n}\n\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport inquirer from 'inquirer';\n\n/**\n * Detect-deps 命令 - 检测依赖关系\n */\nexport const detectDepsCommand = new Command('detect-deps')\n .argument('[spec-file]', 'Spec 文件路径')\n .description('检测依赖关系')\n .action(async (specFile) => {\n try {\n logger.header('检测依赖关系');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 如果没有指定 spec,扫描所有 specs\n if (!specFile) {\n logger.info('未指定 spec 文件,将扫描所有 specs...');\n logger.newLine();\n\n const specsDir = 'docs/specs';\n const exists = await FileUtils.exists(specsDir);\n\n if (!exists) {\n logger.error('未找到 spec 文件');\n process.exit(1);\n }\n\n const files = await FileUtils.findFiles('*.md', specsDir);\n const specs = files.filter((f) => f !== 'template.md');\n\n if (specs.length === 0) {\n logger.error('未找到 spec 文件');\n process.exit(1);\n }\n\n for (const spec of specs) {\n const specPath = path.join(specsDir, spec);\n logger.step(`处理: ${spec}`);\n await detectDependencies(specPath);\n logger.newLine();\n }\n } else {\n // 检查文件是否存在\n const exists = await FileUtils.exists(specFile);\n if (!exists) {\n logger.error(`Spec 文件不存在: ${specFile}`);\n process.exit(1);\n }\n\n await detectDependencies(specFile);\n }\n\n logger.header('依赖检测完成');\n } catch (error: any) {\n logger.error(`依赖检测失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 检测依赖关系\n */\nasync function detectDependencies(specFile: string): Promise<void> {\n logger.step('自动检测依赖关系...');\n\n const projectDir = '.';\n const allDeps = new Set<string>();\n\n // 1. 扫描后端依赖\n const backendDir = path.join(projectDir, 'backend');\n const backendExists = await FileUtils.exists(backendDir);\n\n if (backendExists) {\n // 扫描 API 调用\n const apiDeps = await scanBackendApiCalls(backendDir);\n apiDeps.forEach((d) => allDeps.add(d));\n\n // 扫描实体关联\n const entityDeps = await scanBackendEntityRelations(backendDir);\n entityDeps.forEach((d) => allDeps.add(d));\n\n // 扫描服务引用\n const serviceDeps = await scanBackendServiceRefs(backendDir);\n serviceDeps.forEach((d) => allDeps.add(d));\n }\n\n // 2. 扫描前端依赖\n const frontendDir = path.join(projectDir, 'frontend');\n const frontendExists = await FileUtils.exists(frontendDir);\n\n if (frontendExists) {\n const frontendDeps = await scanFrontendApiCalls(frontendDir);\n frontendDeps.forEach((d) => allDeps.add(d));\n }\n\n if (allDeps.size === 0) {\n logger.info('未检测到明确的依赖关系');\n return;\n }\n\n // 3. 匹配到对应的 spec 文件\n const detectedSpecs: string[] = [];\n for (const dep of allDeps) {\n const matchedSpec = await findSpecByKeyword(dep, 'docs/specs');\n if (matchedSpec && !detectedSpecs.includes(matchedSpec)) {\n detectedSpecs.push(matchedSpec);\n }\n }\n\n if (detectedSpecs.length === 0) {\n logger.info('检测到依赖,但未找到对应的 spec 文件');\n return;\n }\n\n // 4. 输出检测结果\n logger.success(`检测到 ${detectedSpecs.length} 个潜在依赖:`);\n for (const spec of detectedSpecs) {\n logger.step(`- ${spec}`);\n }\n logger.newLine();\n\n // 5. 询问是否自动更新\n const answers = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'autoUpdate',\n message: '是否自动更新依赖关系到 spec 文件?',\n default: true,\n },\n ]);\n\n if (answers.autoUpdate) {\n await updateSpecDependencies(specFile, detectedSpecs);\n logger.success('依赖关系已更新');\n }\n}\n\n/**\n * 扫描后端 API 调用\n */\nasync function scanBackendApiCalls(backendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(backendDir, 'src');\n\n try {\n // 查找 Java 文件中的 RestTemplate/WebClient/RestClient 调用\n const javaFiles = await FileUtils.findFiles('*.java', srcDir);\n\n for (const file of javaFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 API 路径\n const pathRegex = /\"(\\/api\\/[^\"]+)\"/g;\n let match;\n while ((match = pathRegex.exec(content)) !== null) {\n const fullPath = match[1];\n // 提取模块名 (如 /api/users -> users)\n const parts = fullPath.split('/').filter(Boolean);\n if (parts.length > 1) {\n deps.push(parts[1]); // 'api' 后面的部分\n }\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 扫描后端实体关联\n */\nasync function scanBackendEntityRelations(backendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(backendDir, 'src');\n\n try {\n const javaFiles = await FileUtils.findFiles('*.java', srcDir);\n\n for (const file of javaFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 @JoinColumn, @ManyToOne, @OneToMany\n if (\n content.includes('@JoinColumn') ||\n content.includes('@ManyToOne') ||\n content.includes('@OneToMany')\n ) {\n // 提取关联的实体类型\n const typeRegex = /type\\s*=\\s*(\\w+)/g;\n let match;\n while ((match = typeRegex.exec(content)) !== null) {\n deps.push(match[1].toLowerCase());\n }\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 扫描后端服务引用\n */\nasync function scanBackendServiceRefs(backendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(backendDir, 'src');\n\n try {\n const javaFiles = await FileUtils.findFiles('*.java', srcDir);\n\n for (const file of javaFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 Service 注入\n const serviceRegex = /private\\s+(\\w+)Service/g;\n let match;\n while ((match = serviceRegex.exec(content)) !== null) {\n const serviceName = match[1];\n // 提取模块名 (UserService -> user)\n const moduleName = serviceName.replace(/Service$/, '').toLowerCase();\n deps.push(moduleName);\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 扫描前端 API 调用\n */\nasync function scanFrontendApiCalls(frontendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(frontendDir, 'src');\n\n try {\n // 查找 TypeScript/JavaScript 文件\n const tsFiles = await FileUtils.findFiles('*.{ts,tsx,js,jsx}', srcDir);\n\n for (const file of tsFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 API 路径\n const pathRegex = /\"(\\/api\\/[^\"]+)\"/g;\n let match;\n while ((match = pathRegex.exec(content)) !== null) {\n const fullPath = match[1];\n const parts = fullPath.split('/').filter(Boolean);\n if (parts.length > 1) {\n deps.push(parts[1]);\n }\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 根据关键词查找 spec\n */\nasync function findSpecByKeyword(\n keyword: string,\n specsDir: string\n): Promise<string | null> {\n const exists = await FileUtils.exists(specsDir);\n if (!exists) {\n return null;\n }\n\n try {\n const files = await FileUtils.findFiles('*.md', specsDir);\n\n for (const file of files) {\n if (file === 'template.md') continue;\n\n const name = file.replace('.md', '');\n // 模糊匹配\n if (name.includes(keyword) || keyword.includes(name)) {\n return name;\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return null;\n}\n\n/**\n * 更新 spec 的依赖关系\n */\nasync function updateSpecDependencies(\n specFile: string,\n deps: string[]\n): Promise<void> {\n let content = await FileUtils.read(specFile);\n\n // 检查是否有依赖关系部分\n if (!content.includes('## 依赖关系')) {\n // 在背景与目标前插入依赖关系部分\n const targetSection = '## 背景与目标';\n const insertIndex = content.indexOf(targetSection);\n\n if (insertIndex !== -1) {\n const depsSection = `\\n## 依赖关系\\n\\n**前置依赖**:\\n${deps.map((d) => ` - [x] ${d}`).join('\\n')}\\n\\n**被依赖于**:\\n - (自动生成,表示哪些 spec 依赖本功能)\\n\\n`;\n content =\n content.slice(0, insertIndex) + depsSection + content.slice(insertIndex);\n }\n } else {\n // 更新现有依赖关系\n const lines = content.split('\\n');\n let inDeps = false;\n const result: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (line.startsWith('## 依赖关系')) {\n inDeps = true;\n result.push(line);\n result.push('');\n result.push('**前置依赖**:');\n for (const dep of deps) {\n result.push(` - [x] ${dep}`);\n }\n result.push('');\n result.push('**被依赖于**:');\n result.push(' - (自动生成,表示哪些 spec 依赖本功能)');\n continue;\n }\n\n if (inDeps) {\n // 跳过旧的前置依赖内容,直到遇到下一个章节\n if (line.startsWith('## ') && !line.startsWith('## 依赖关系')) {\n inDeps = false;\n result.push(line);\n }\n continue;\n }\n\n result.push(line);\n }\n\n content = result.join('\\n');\n }\n\n await FileUtils.write(specFile, content);\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils, DateUtils, SpecUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { readTemplateConfig } from '../lib/template-version.js';\n\n/**\n * Sync-memory 命令 - 同步 AI_MEMORY.md\n */\nexport const syncMemoryCommand = new Command('sync-memory')\n .description('同步 AI_MEMORY.md')\n .action(async () => {\n try {\n logger.header('同步 AI_MEMORY.md');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n const aiMemoryFile = 'AI_MEMORY.md';\n const exists = await FileUtils.exists(aiMemoryFile);\n\n if (!exists) {\n logger.info('AI_MEMORY.md 不存在,跳过同步');\n process.exit(0);\n }\n\n // 1. 同步功能清单\n await syncFeatureInventory(aiMemoryFile, '.');\n\n // 2. 同步 API 列表\n await syncApiInventory(aiMemoryFile, '.');\n\n // 3. 同步数据模型\n await syncDataModels(aiMemoryFile, '.');\n\n // 4. 同步模板版本信息\n await syncTemplateVersions(aiMemoryFile, '.');\n\n // 5. 更新最后同步时间\n await updateSyncTime(aiMemoryFile);\n\n logger.success('AI_MEMORY.md 已同步');\n } catch (error: any) {\n logger.error(`同步失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 同步功能清单\n */\nasync function syncFeatureInventory(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步功能清单...');\n\n const specsDir = path.join(projectDir, 'docs/specs');\n const exists = await FileUtils.exists(specsDir);\n\n if (!exists) {\n return;\n }\n\n // 读取所有 specs\n const files = await FileUtils.findFiles('*.md', specsDir);\n const specs = files.filter((f) => f !== 'template.md');\n\n // 构建功能清单表格\n const lines: string[] = [];\n lines.push('## 功能清单 (Feature Inventory)');\n lines.push('');\n lines.push('| 功能 | Spec 文件 | 状态 | 进度 | 完成日期 | 备注 |');\n lines.push('|------|----------|------|------|---------|------|');\n\n for (const specFile of specs) {\n const name = specFile.replace('.md', '');\n const displayName = name\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n const specPath = path.join(specsDir, specFile);\n const content = await FileUtils.read(specPath);\n\n // 获取状态\n const status = SpecUtils.parseSpecStatus(content);\n const statusWithIcon = SpecUtils.getStatusWithIcon(status);\n\n // 获取进度\n const progress = SpecUtils.getProgress(content);\n\n // 获取完成日期\n let completionDate = '-';\n if (status === '已完成') {\n const dateMatch = content.match(/完成日期.*[::]\\s*(.+)/);\n if (dateMatch) {\n completionDate = dateMatch[1].trim();\n }\n }\n\n lines.push(`| ${displayName} | ${name}.md | ${statusWithIcon} | ${progress} | ${completionDate} | |`);\n }\n\n const newContent = lines.join('\\n') + '\\n';\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## 功能清单', newContent);\n}\n\n/**\n * 同步 API 列表\n */\nasync function syncApiInventory(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步 API 列表...');\n\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (!exists) {\n return;\n }\n\n const lines: string[] = [];\n lines.push('## API 列表 (API Inventory)');\n lines.push('');\n lines.push('> 本部分由 team-cli 自动扫描后端 Controller 生成');\n lines.push('');\n\n // 查找所有 Controller\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n if (controllers.length === 0) {\n lines.push('暂无 API');\n } else {\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const controllerName = controllerFile.replace('.java', '');\n const module = controllerName.replace(/Controller$/, '').toLowerCase();\n\n lines.push(`### ${module} 模块`);\n lines.push('');\n lines.push('| 方法 | 路径 | 说明 | 状态 | 日期 |');\n lines.push('|------|------|------|------|------|');\n\n // 扫描 API\n const apis = await scanControllerApis(controllerPath);\n for (const api of apis) {\n lines.push(`| ${api.method} | ${api.path} | ${api.description} | ✅ | ${api.date} |`);\n }\n lines.push('');\n }\n }\n\n const newContent = lines.join('\\n');\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## API 列表', newContent);\n}\n\n/**\n * 扫描 Controller 中的 API\n */\nasync function scanControllerApis(\n controllerPath: string\n): Promise<Array<{ method: string; path: string; description: string; date: string }>> {\n const apis: Array<{ method: string; path: string; description: string; date: string }> = [];\n const content = await FileUtils.read(controllerPath);\n\n // 提取类级别的 @RequestMapping\n let classPath = '';\n const classRequestMappingMatch = content.match(/@RequestMapping\\(\"([^\"]+)\"\\)/);\n if (classRequestMappingMatch) {\n classPath = classRequestMappingMatch[1];\n }\n\n // 扫描方法级别的映射\n const methodRegex =\n /@(GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping)\\(\"([^\"]+)\"\\)\\s*\\n\\s*public\\s+(\\w+)\\s*\\(([^)]*)\\)/g;\n let match;\n\n while ((match = methodRegex.exec(content)) !== null) {\n const mappingType = match[1];\n const methodPath = match[2];\n const methodName = match[3];\n\n // 确定 HTTP 方法\n let httpMethod = '';\n switch (mappingType) {\n case 'GetMapping':\n httpMethod = 'GET';\n break;\n case 'PostMapping':\n httpMethod = 'POST';\n break;\n case 'PutMapping':\n httpMethod = 'PUT';\n break;\n case 'DeleteMapping':\n httpMethod = 'DELETE';\n break;\n case 'PatchMapping':\n httpMethod = 'PATCH';\n break;\n }\n\n // 组合完整路径\n let fullPath = methodPath;\n if (classPath && !methodPath.startsWith('/api')) {\n fullPath = `${classPath}${methodPath}`;\n }\n\n // 提取方法注释\n const description = extractMethodComment(content, methodName);\n\n apis.push({\n method: httpMethod,\n path: fullPath,\n description,\n date: DateUtils.format(new Date(), 'YYYY-MM-DD'),\n });\n }\n\n return apis;\n}\n\n/**\n * 提取方法注释\n */\nfunction extractMethodComment(content: string, methodName: string): string {\n // 查找方法定义前的注释\n const methodIndex = content.indexOf(`${methodName}(`);\n if (methodIndex === -1) {\n return '';\n }\n\n // 向前查找注释\n const beforeMethod = content.substring(Math.max(0, methodIndex - 500), methodIndex);\n const commentMatch = beforeMethod.match(/\\*\\s*([^\\n*]+)/g);\n\n if (commentMatch && commentMatch.length > 0) {\n return commentMatch[0].replace(/\\*\\s?/, '').trim();\n }\n\n return '';\n}\n\n/**\n * 同步数据模型\n */\nasync function syncDataModels(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步数据模型...');\n\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (!exists) {\n return;\n }\n\n const lines: string[] = [];\n lines.push('## 数据模型 (Data Models)');\n lines.push('');\n lines.push('> 本部分由 team-cli 自动扫描后端 Entity 生成');\n lines.push('');\n\n // 查找所有 Entity\n const srcDir = path.join(backendDir, 'src');\n const entities = await FileUtils.findFiles('*Entity.java', srcDir);\n\n if (entities.length === 0) {\n lines.push('暂无数据模型');\n } else {\n lines.push('| 模型 | 说明 | 字段 | 关联 |');\n lines.push('|------|------|------|------|');\n\n for (const entityFile of entities) {\n const entityPath = path.join(srcDir, entityFile);\n const entityName = entityFile.replace('.java', '').replace(/Entity$/, '');\n const displayName = entityName\n .split(/(?=[A-Z])/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n\n // 读取实体内容\n const content = await FileUtils.read(entityPath);\n\n // 提取注释\n const classCommentMatch = content.match(/\\/\\*\\*\\s*\\n([^*]|\\*[^/])*\\*\\//);\n const description = classCommentMatch\n ? classCommentMatch[0].replace(/\\/\\*\\*|\\*\\/|\\*/g, '').trim()\n : '';\n\n // 计算字段数\n const fieldCount = (content.match(/private\\s+\\w+/g) || []).length;\n\n // 检查关联\n const relations: string[] = [];\n if (content.includes('@ManyToOne')) relations.push('Many-to-One');\n if (content.includes('@OneToMany')) relations.push('One-to-Many');\n if (content.includes('@OneToOne')) relations.push('One-to-One');\n if (content.includes('@ManyToMany')) relations.push('Many-to-Many');\n\n lines.push(`| ${displayName} | ${description} | ${fieldCount} | ${relations.join(', ') || '-'} |`);\n }\n }\n\n const newContent = lines.join('\\n');\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## 数据模型', newContent);\n}\n\n/**\n * 更新同步时间\n */\nasync function updateSyncTime(aiMemoryFile: string): Promise<void> {\n const content = await FileUtils.read(aiMemoryFile);\n const timestamp = DateUtils.format(new Date(), 'YYYY-MM-DD HH:mm:ss');\n\n let updated = content;\n\n // 查找并更新最后同步时间\n if (content.includes('最后同步')) {\n updated = content.replace(\n /最后同步.*[::]\\s*.+/,\n `最后同步: ${timestamp}`\n );\n } else {\n // 在文件末尾添加\n updated = content.trimEnd() + `\\n\\n---\\n\\n*最后同步: ${timestamp} by team-cli*\\n`;\n }\n\n await FileUtils.write(aiMemoryFile, updated);\n}\n\n/**\n * 替换或插入章节\n */\nasync function replaceOrInsertSection(\n aiMemoryFile: string,\n sectionTitle: string,\n newContent: string\n): Promise<void> {\n const content = await FileUtils.read(aiMemoryFile);\n\n // 检查是否存在该章节\n if (content.includes(sectionTitle)) {\n // 替换现有章节\n const lines = content.split('\\n');\n const result: string[] = [];\n let inSection = false;\n let skip = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (line.startsWith(sectionTitle)) {\n inSection = true;\n result.push(newContent);\n skip = true;\n continue;\n }\n\n if (inSection) {\n if (line.startsWith('## ') && !line.startsWith(sectionTitle)) {\n inSection = false;\n skip = false;\n result.push(line);\n }\n continue;\n }\n\n if (!skip) {\n result.push(line);\n }\n }\n\n await FileUtils.write(aiMemoryFile, result.join('\\n'));\n } else {\n // 插入新章节\n await FileUtils.write(aiMemoryFile, content.trimEnd() + '\\n\\n' + newContent + '\\n');\n }\n}\n\n\n/**\n * 同步模板版本信息\n */\nasync function syncTemplateVersions(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步模板版本信息...');\n\n const config = await readTemplateConfig(projectDir);\n\n if (!config) {\n return;\n }\n\n const lines: string[] = [];\n lines.push('## 模板版本信息');\n lines.push('');\n lines.push('> 本部分由 team-cli 自动管理,记录使用的前后端模板版本');\n lines.push('');\n lines.push('| 类型 | 仓库 | Tag | Branch | Commit | 更新时间 |');\n lines.push('|------|------|-----|--------|--------|----------|');\n\n // 前端模板\n if (config.frontend) {\n const repoName = extractRepoName(config.frontend.repository);\n const commit = config.frontend.commit?.substring(0, 8) || '-';\n const tag = config.frontend.tag || '-';\n const branch = config.frontend.branch || '-';\n const updateDate = config.frontend.lastUpdate\n ? new Date(config.frontend.lastUpdate).toLocaleDateString('zh-CN')\n : '-';\n\n lines.push(`| 前端 | ${repoName} | ${tag} | ${branch} | ${commit} | ${updateDate} |`);\n }\n\n // 后端模板\n if (config.backend) {\n const repoName = extractRepoName(config.backend.repository);\n const commit = config.backend.commit?.substring(0, 8) || '-';\n const tag = config.backend.tag || '-';\n const branch = config.backend.branch || '-';\n const updateDate = config.backend.lastUpdate\n ? new Date(config.backend.lastUpdate).toLocaleDateString('zh-CN')\n : '-';\n\n lines.push(`| 后端 | ${repoName} | ${tag} | ${branch} | ${commit} | ${updateDate} |`);\n }\n\n const newContent = lines.join('\\n') + '\\n';\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## 模板版本信息', newContent);\n}\n\n/**\n * 从仓库 URL 中提取仓库名\n */\nfunction extractRepoName(repository: string): string {\n // 支持的格式:\n // - git@gitlab.com:group/project.git\n // - https://gitlab.com/group/project.git\n\n let path = repository;\n\n // 移除协议前缀\n path = path.replace(/^https?:\\/\\//, '');\n path = path.replace(/^git@/, '');\n\n // 移除域名部分\n const parts = path.split('/');\n if (parts.length > 1) {\n path = parts.slice(1).join('/');\n }\n\n // 移除 .git 后缀\n path = path.replace(/\\.git$/, '');\n\n return path;\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils, DateUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport inquirer from 'inquirer';\nimport { Listr } from 'listr2';\n\n/**\n * Check-api 命令 - API 检查\n */\nexport const checkApiCommand = new Command('check-api')\n .description('API 检查(冲突/变更/Registry)')\n .action(async () => {\n try {\n logger.header('API 检查');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 交互式选择\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'checkType',\n message: '选择检查类型:',\n choices: [\n { name: '检测 API 冲突', value: 'conflicts' },\n { name: '检测 API 变更', value: 'changes' },\n { name: '生成 API Registry', value: 'registry' },\n { name: '全部执行', value: 'all' },\n ],\n default: 'all',\n },\n ]);\n\n const tasks = new Listr([]);\n\n // 根据选择添加任务\n if (answers.checkType === 'conflicts' || answers.checkType === 'all') {\n tasks.add({\n title: '检测 API 冲突',\n task: async () => {\n await checkApiConflicts('.');\n },\n });\n }\n\n if (answers.checkType === 'changes' || answers.checkType === 'all') {\n tasks.add({\n title: '检测 API 变更',\n task: async () => {\n await detectApiChanges('.');\n },\n });\n }\n\n if (answers.checkType === 'registry' || answers.checkType === 'all') {\n tasks.add({\n title: '生成 API Registry',\n task: async () => {\n await generateApiRegistry('.');\n },\n });\n }\n\n await tasks.run();\n\n logger.newLine();\n logger.header('API 检查完成');\n } catch (error: any) {\n logger.error(`API 检查失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 检测 API 冲突\n */\nasync function checkApiConflicts(projectDir: string): Promise<void> {\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (!exists) {\n logger.info('未找到后端项目');\n return;\n }\n\n logger.step('扫描后端 API...');\n logger.newLine();\n\n const apiMap = new Map<string, string[]>();\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n // 收集所有 API\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const apis = await extractApisFromController(controllerPath);\n\n for (const api of apis) {\n const key = `${api.method}:${api.path}`;\n if (!apiMap.has(key)) {\n apiMap.set(key, []);\n }\n apiMap.get(key)!.push(controllerFile);\n }\n }\n\n // 检查冲突\n const conflicts: Array<{ key: string; controllers: string[] }> = [];\n for (const [key, controllers] of apiMap.entries()) {\n if (controllers.length > 1) {\n conflicts.push({ key, controllers });\n }\n }\n\n if (conflicts.length === 0) {\n logger.success('未发现 API 冲突');\n } else {\n logger.error(`发现 ${conflicts.length} 个 API 冲突:`);\n logger.newLine();\n\n for (const conflict of conflicts) {\n logger.error(`冲突: ${conflict.key}`);\n for (const controller of conflict.controllers) {\n logger.step(` - ${controller}`);\n }\n logger.newLine();\n }\n }\n}\n\n/**\n * 检测 API 变更\n */\nasync function detectApiChanges(projectDir: string): Promise<void> {\n const backendDir = path.join(projectDir, 'backend');\n const registryFile = path.join(projectDir, 'docs/api-registry.md');\n const registryExists = await FileUtils.exists(registryFile);\n\n if (!registryExists) {\n logger.info('API Registry 不存在,跳过变更检测');\n logger.info(\"运行 'team-cli check-api' 选择 '生成 API Registry'\");\n return;\n }\n\n logger.step('检测 API 变更...');\n logger.newLine();\n\n // 读取现有 Registry\n const registryContent = await FileUtils.read(registryFile);\n const existingApis = extractApisFromRegistry(registryContent);\n\n // 扫描当前 API\n const currentApis = new Map<string, { method: string; path: string; description: string }>();\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const apis = await extractApisFromController(controllerPath);\n\n for (const api of apis) {\n const key = `${api.method}:${api.path}`;\n currentApis.set(key, api);\n }\n }\n\n // 比较差异\n const added: Array<{ method: string; path: string }> = [];\n const removed: Array<{ method: string; path: string }> = [];\n const modified: Array<{ method: string; path: string; oldDesc: string; newDesc: string }> = [];\n\n for (const [key, api] of currentApis.entries()) {\n if (!existingApis.has(key)) {\n added.push({ method: api.method, path: api.path });\n } else {\n const existingApi = existingApis.get(key)!;\n if (existingApi.description !== api.description) {\n modified.push({\n method: api.method,\n path: api.path,\n oldDesc: existingApi.description,\n newDesc: api.description,\n });\n }\n }\n }\n\n for (const [key, api] of existingApis.entries()) {\n if (!currentApis.has(key)) {\n removed.push({ method: api.method, path: api.path });\n }\n }\n\n // 输出结果\n let hasChanges = false;\n\n if (added.length > 0) {\n hasChanges = true;\n logger.success(`新增 API (${added.length}):`);\n for (const api of added) {\n logger.step(` + ${api.method} ${api.path}`);\n }\n logger.newLine();\n }\n\n if (removed.length > 0) {\n hasChanges = true;\n logger.error(`删除 API (${removed.length}):`);\n for (const api of removed) {\n logger.step(` - ${api.method} ${api.path}`);\n }\n logger.newLine();\n }\n\n if (modified.length > 0) {\n hasChanges = true;\n logger.warn(`修改 API (${modified.length}):`);\n for (const api of modified) {\n logger.step(` ~ ${api.method} ${api.path}`);\n logger.step(` 旧: ${api.oldDesc}`);\n logger.step(` 新: ${api.newDesc}`);\n }\n logger.newLine();\n }\n\n if (!hasChanges) {\n logger.success('未检测到 API 变更');\n }\n}\n\n/**\n * 生成 API Registry\n */\nasync function generateApiRegistry(projectDir: string): Promise<void> {\n const registryFile = path.join(projectDir, 'docs/api-registry.md');\n\n logger.step('扫描并生成 API Registry...');\n\n // 创建 docs 目录\n await FileUtils.ensureDir(path.dirname(registryFile));\n\n // 写入文件头\n const header = `# API Registry\n\n> 本文件记录所有 API 的定义、版本和变更历史\n\n## API 规范\n\n### 基础信息\n- **Base URL**: \\`/api\\`\n- **认证方式**: JWT Bearer Token\n- **数据格式**: JSON\n- **字符编码**: UTF-8\n\n### 响应码规范\n| 状态码 | 说明 |\n|--------|------|\n| 200 | 成功 |\n| 201 | 创建成功 |\n| 400 | 请求参数错误 |\n| 401 | 未认证 |\n| 403 | 无权限 |\n| 404 | 资源不存在 |\n| 500 | 服务器错误 |\n\n---\n\n*最后更新: ${DateUtils.format(new Date(), 'YYYY-MM-DD HH:mm:ss')}*\n`;\n\n // 扫描 Controller 并生成 API 文档\n let content = header;\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (exists) {\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n // 按模块分组\n const moduleMap = new Map<string, Array<{ method: string; path: string; description: string }>>();\n\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const controllerName = controllerFile.replace('.java', '');\n const module = controllerName.replace(/Controller$/, '').toLowerCase();\n\n if (!moduleMap.has(module)) {\n moduleMap.set(module, []);\n }\n\n const apis = await extractApisFromController(controllerPath);\n moduleMap.get(module)!.push(...apis);\n }\n\n // 生成文档\n for (const [module, apis] of moduleMap.entries()) {\n content += `\\n## ${module.charAt(0).toUpperCase() + module.slice(1)} 模块\\n\\n`;\n\n for (const api of apis) {\n content += `### ${api.method} ${api.path}\\n\\n`;\n content += `**版本**: v1.0\\n\\n`;\n content += `**说明**: ${api.description || '-'}\\n\\n`;\n content += `---\\n\\n`;\n }\n }\n }\n\n await FileUtils.write(registryFile, content);\n\n logger.success(`API Registry 已生成: ${registryFile}`);\n}\n\n/**\n * 从 Controller 提取 API\n */\nasync function extractApisFromController(\n controllerPath: string\n): Promise<Array<{ method: string; path: string; description: string }>> {\n const apis: Array<{ method: string; path: string; description: string }> = [];\n const content = await FileUtils.read(controllerPath);\n\n // 提取类级别的 @RequestMapping\n let classPath = '';\n const classRequestMappingMatch = content.match(/@RequestMapping\\(\"([^\"]+)\"\\)/);\n if (classRequestMappingMatch) {\n classPath = classRequestMappingMatch[1];\n }\n\n // 扫描方法级别的映射\n const methodRegex =\n /@(GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping)\\(\"([^\"]+)\"\\)\\s*\\n\\s*public\\s+(\\w+)\\s*\\(([^)]*)\\)/g;\n let match;\n\n while ((match = methodRegex.exec(content)) !== null) {\n const mappingType = match[1];\n const methodPath = match[2];\n const methodName = match[3];\n\n // 确定 HTTP 方法\n let httpMethod = '';\n switch (mappingType) {\n case 'GetMapping':\n httpMethod = 'GET';\n break;\n case 'PostMapping':\n httpMethod = 'POST';\n break;\n case 'PutMapping':\n httpMethod = 'PUT';\n break;\n case 'DeleteMapping':\n httpMethod = 'DELETE';\n break;\n case 'PatchMapping':\n httpMethod = 'PATCH';\n break;\n }\n\n // 组合完整路径\n let fullPath = methodPath;\n if (classPath && !methodPath.startsWith('/api')) {\n fullPath = `${classPath}${methodPath}`;\n }\n\n // 提取方法注释\n const description = extractMethodComment(content, methodName);\n\n apis.push({\n method: httpMethod,\n path: fullPath,\n description,\n });\n }\n\n return apis;\n}\n\n/**\n * 从 Registry 提取 API\n */\nfunction extractApisFromRegistry(\n registryContent: string\n): Map<string, { method: string; path: string; description: string }> {\n const apis = new Map<string, { method: string; path: string; description: string }>();\n\n // 匹配 API 条目\n const apiRegex = /### (GET|POST|PUT|DELETE|PATCH) ([^\\n]+)\\n\\n\\*\\*版本\\*\\*:.+?\\n\\n\\*\\*说明\\*\\*:\\s*([^\\n-]+)/g;\n let match;\n\n while ((match = apiRegex.exec(registryContent)) !== null) {\n const method = match[1];\n const path = match[2].trim();\n const description = match[3].trim();\n const key = `${method}:${path}`;\n apis.set(key, { method, path, description });\n }\n\n return apis;\n}\n\n/**\n * 提取方法注释\n */\nfunction extractMethodComment(content: string, methodName: string): string {\n const methodIndex = content.indexOf(`${methodName}(`);\n if (methodIndex === -1) {\n return '';\n }\n\n const beforeMethod = content.substring(Math.max(0, methodIndex - 500), methodIndex);\n const commentMatch = beforeMethod.match(/\\*\\s*([^\\n*]+)/g);\n\n if (commentMatch && commentMatch.length > 0) {\n return commentMatch[0].replace(/\\*\\s?/, '').trim();\n }\n\n return '';\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport inquirer from 'inquirer';\n\n/**\n * Logs 命令 - 查看会话日志\n */\nexport const logsCommand = new Command('logs')\n .argument('[filter]', '过滤器 (today, --all, 或日期 YYYY-MM-DD)')\n .description('查看会话日志')\n .action(async (filter = 'today') => {\n try {\n logger.header('会话日志');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n const sessionsDir = 'docs/sessions';\n const dirExists = await FileUtils.exists(sessionsDir);\n\n if (!dirExists) {\n logger.info('暂无会话日志');\n logger.info(\"运行 'team-cli dev' 后会自动生成日志\");\n process.exit(0);\n }\n\n // 确定目标目录\n let targetDir = '';\n let displayTitle = '';\n\n switch (filter) {\n case '':\n case 'today': {\n const today = new Date().toISOString().split('T')[0];\n targetDir = path.join(sessionsDir, today);\n const todayExists = await FileUtils.exists(targetDir);\n if (!todayExists) {\n logger.info('今日暂无会话日志');\n process.exit(0);\n }\n displayTitle = '显示今日会话日志:';\n break;\n }\n case '--all':\n case '-a': {\n targetDir = sessionsDir;\n displayTitle = '显示所有会话日志:';\n break;\n }\n default: {\n // 假设是日期格式\n targetDir = path.join(sessionsDir, filter);\n const dateExists = await FileUtils.exists(targetDir);\n if (!dateExists) {\n logger.error(`未找到日期 '${filter}' 的日志`);\n logger.info('可用日期:');\n\n // 列出可用日期\n const entries = await FileUtils.findFiles('*/', sessionsDir);\n const dates = entries.slice(0, 10);\n for (const date of dates) {\n logger.info(` ${date.replace('/', '')}`);\n }\n process.exit(1);\n }\n displayTitle = `显示 ${filter} 的会话日志:`;\n break;\n }\n }\n\n logger.info(displayTitle);\n logger.newLine();\n\n // 收集日志文件\n const logs = await collectLogFiles(targetDir);\n\n if (logs.length === 0) {\n logger.info('无日志文件');\n process.exit(0);\n }\n\n // 显示日志列表\n for (let i = 0; i < logs.length; i++) {\n const relPath = path.relative(sessionsDir, logs[i]);\n logger.step(`${i + 1}) ${relPath}`);\n }\n\n logger.newLine();\n\n // 询问选择\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'selection',\n message: '输入编号查看详情 (或 Enter 退出):',\n default: '',\n },\n ]);\n\n const selection = answers.selection.trim();\n\n if (selection === '') {\n process.exit(0);\n }\n\n const selectionNum = parseInt(selection, 10);\n\n if (isNaN(selectionNum) || selectionNum < 1 || selectionNum > logs.length) {\n logger.error('无效的选择');\n process.exit(1);\n }\n\n // 显示选中的日志\n const selectedLog = logs[selectionNum - 1];\n logger.newLine();\n logger.header('日志详情');\n logger.newLine();\n\n const content = await FileUtils.read(selectedLog);\n console.log(content);\n } catch (error: any) {\n logger.error(`查看日志失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 收集日志文件\n */\nasync function collectLogFiles(targetDir: string): Promise<string[]> {\n const logs: string[] = [];\n\n try {\n // 查找所有 markdown 文件,排除 index.md\n const allFiles = await FileUtils.findFiles('*.md', targetDir);\n const filtered = allFiles.filter((f) => f !== 'index.md');\n\n for (const file of filtered) {\n const filePath = path.join(targetDir, file);\n // 确保是文件而不是目录\n const stat = await FileUtils.exists(filePath);\n if (stat) {\n logs.push(filePath);\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return logs;\n}\n","import path from 'path';\nimport os from 'os';\nimport crypto from 'crypto';\nimport { FileUtils } from './utils.js';\nimport { logger } from './logger.js';\n\n/**\n * 用户配置接口\n */\nexport interface UserConfig {\n gitlab: {\n accessToken: string;\n baseUrl: string;\n timeout?: number;\n };\n preferences?: {\n defaultBackendBranch?: string;\n defaultFrontendBranch?: string;\n };\n}\n\n/**\n * 用户配置管理类\n */\nexport class UserConfigManager {\n private configPath: string;\n\n constructor() {\n const configDir = path.join(os.homedir(), '.team-cli');\n this.configPath = path.join(configDir, 'config.json');\n }\n\n /**\n * 加载用户配置\n */\n async load(): Promise<UserConfig | null> {\n try {\n const exists = await FileUtils.exists(this.configPath);\n if (!exists) {\n return null;\n }\n\n const content = await FileUtils.read(this.configPath);\n const config = JSON.parse(content);\n\n // 解密 access token\n if (config.gitlab?.accessToken) {\n config.gitlab.accessToken = this.decrypt(config.gitlab.accessToken);\n }\n\n return config;\n } catch (error) {\n logger.debug(`加载用户配置失败: ${error}`);\n return null;\n }\n }\n\n /**\n * 保存用户配置\n */\n async save(config: UserConfig): Promise<void> {\n try {\n const configDir = path.dirname(this.configPath);\n await FileUtils.ensureDir(configDir);\n\n // 加密 access token(深拷贝以避免修改原对象)\n const configToSave = JSON.parse(JSON.stringify(config));\n if (configToSave.gitlab?.accessToken) {\n configToSave.gitlab.accessToken = this.encrypt(configToSave.gitlab.accessToken);\n }\n\n const content = JSON.stringify(configToSave, null, 2);\n await FileUtils.write(this.configPath, content);\n } catch (error) {\n throw new Error(`保存用户配置失败: ${error}`);\n }\n }\n\n /**\n * 更新 GitLab Token\n */\n async updateGitLabToken(token: string, baseUrl?: string): Promise<void> {\n const config = (await this.load()) || {\n gitlab: {\n accessToken: '',\n baseUrl: 'https://gitlab.com',\n timeout: 30000,\n },\n };\n\n config.gitlab.accessToken = token;\n if (baseUrl) {\n config.gitlab.baseUrl = baseUrl;\n }\n\n await this.save(config);\n }\n\n /**\n * 获取 GitLab Token\n */\n async getGitLabToken(): Promise<string | null> {\n const config = await this.load();\n return config?.gitlab?.accessToken || null;\n }\n\n /**\n * 获取 GitLab 配置\n */\n async getGitLabConfig(): Promise<{ accessToken: string; baseUrl: string; timeout?: number } | null> {\n const config = await this.load();\n return config?.gitlab || null;\n }\n\n /**\n * 检查是否已有配置\n */\n async hasConfig(): Promise<boolean> {\n const config = await this.load();\n return config !== null && config.gitlab?.accessToken !== undefined;\n }\n\n /**\n * 删除配置\n */\n async removeConfig(): Promise<void> {\n try {\n const exists = await FileUtils.exists(this.configPath);\n if (exists) {\n await FileUtils.remove(this.configPath);\n }\n } catch (error) {\n throw new Error(`删除配置失败: ${error}`);\n }\n }\n\n /**\n * 简单加密 (使用机器特定密钥)\n */\n private encrypt(text: string): string {\n const key = this.getMachineKey();\n const iv = crypto.randomBytes(16);\n const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);\n let encrypted = cipher.update(text, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n return iv.toString('hex') + ':' + encrypted;\n }\n\n /**\n * 简单解密\n */\n private decrypt(encryptedText: string): string {\n try {\n const key = this.getMachineKey();\n const parts = encryptedText.split(':');\n const iv = Buffer.from(parts[0], 'hex');\n const encrypted = parts[1];\n const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);\n let decrypted = decipher.update(encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n return decrypted;\n } catch {\n // 如果解密失败,可能是旧版本的明文存储\n return encryptedText;\n }\n }\n\n /**\n * 获取机器特定密钥\n */\n private getMachineKey(): Buffer {\n const hostname = os.hostname();\n const platform = os.platform();\n const arch = os.arch();\n const cpus = os.cpus();\n\n // 使用机器信息生成密钥\n const machineInfo = `${hostname}-${platform}-${arch}-${cpus[0]?.model || 'unknown'}`;\n return crypto.createHash('sha256').update(machineInfo).digest();\n }\n\n /**\n * 获取配置目录\n */\n getConfigDir(): string {\n return path.dirname(this.configPath);\n }\n\n /**\n * 获取配置文件路径\n */\n getConfigPath(): string {\n return this.configPath;\n }\n}\n\n// 导出单例\nexport const userConfigManager = new UserConfigManager();\n","/**\n * GitLab API 客户端\n */\n\n/**\n * GitLab Tag 信息\n */\nexport interface GitLabTag {\n name: string;\n commit: {\n id: string;\n short_id: string;\n created_at: string;\n };\n message: string;\n release: {\n tag_name: string;\n description: string;\n } | null;\n}\n\n/**\n * GitLab Branch 信息\n */\nexport interface GitLabBranch {\n name: string;\n commit: {\n id: string;\n short_id: string;\n title: string;\n created_at: string;\n author_name: string;\n author_email: string;\n };\n protected: boolean;\n default: boolean;\n}\n\n/**\n * GitLab Diff 结果\n */\nexport interface GitLabDiffResult {\n from: string;\n to: string;\n commits: Array<{\n id: string;\n short_id: string;\n title: string;\n author_name: string;\n created_at: string;\n message: string;\n }>;\n diffs: Array<{\n old_path: string;\n new_path: string;\n diff: string;\n new_file: boolean;\n renamed_file: boolean;\n deleted_file: boolean;\n }>;\n}\n\n/**\n * GitLab 项目信息\n */\nexport interface GitLabProject {\n id: number;\n name: string;\n path: string;\n path_with_namespace: string;\n http_url_to_repo: string;\n ssh_url_to_repo: string;\n default_branch: string;\n last_activity_at: string;\n}\n\n/**\n * GitLab API 配置\n */\nexport interface GitLabConfig {\n accessToken: string;\n baseUrl: string;\n timeout?: number;\n}\n\n/**\n * GitLab API 客户端类\n */\nexport class GitLabAPI {\n private config: GitLabConfig;\n private readonly defaultTimeout = 30000;\n\n constructor(config: GitLabConfig) {\n this.config = {\n ...config,\n timeout: config.timeout || this.defaultTimeout,\n };\n }\n\n /**\n * 验证 Token 是否有效\n */\n async authenticate(): Promise<boolean> {\n try {\n const response = await this.request('/user');\n return response.ok;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * 列出项目的所有 Tags\n */\n async listTags(projectPath: string): Promise<GitLabTag[]> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(`/projects/${encodedPath}/repository/tags?per_page=100`);\n\n if (!response.ok) {\n throw new Error(`GitLab API 请求失败: ${response.status}`);\n }\n\n const tags: GitLabTag[] = await response.json();\n return tags.sort((a, b) => {\n // 按版本号排序(降序)\n return this.compareVersionStrings(b.name, a.name);\n });\n } catch (error) {\n throw new Error(`获取 Tags 失败: ${error}`);\n }\n }\n\n /**\n * 列出项目的所有 Branches\n */\n async listBranches(projectPath: string): Promise<GitLabBranch[]> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(`/projects/${encodedPath}/repository/branches?per_page=100`);\n\n if (!response.ok) {\n throw new Error(`GitLab API 请求失败: ${response.status}`);\n }\n\n const branches: GitLabBranch[] = await response.json();\n\n // 将默认分支放在最前面\n return branches.sort((a, b) => {\n if (a.default) return -1;\n if (b.default) return 1;\n return a.name.localeCompare(b.name);\n });\n } catch (error) {\n throw new Error(`获取 Branches 失败: ${error}`);\n }\n }\n\n /**\n * 验证 Tag 是否存在\n */\n async validateTag(projectPath: string, tag: string): Promise<boolean> {\n try {\n const tags = await this.listTags(projectPath);\n return tags.some((t) => t.name === tag);\n } catch {\n return false;\n }\n }\n\n /**\n * 验证 Branch 是否存在\n */\n async validateBranch(projectPath: string, branch: string): Promise<boolean> {\n try {\n const branches = await this.listBranches(projectPath);\n return branches.some((b) => b.name === branch);\n } catch {\n return false;\n }\n }\n\n /**\n * 获取项目信息\n */\n async getProject(projectPath: string): Promise<GitLabProject | null> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(`/projects/${encodedPath}`);\n\n if (!response.ok) {\n return null;\n }\n\n return await response.json();\n } catch {\n return null;\n }\n }\n\n /**\n * 获取指定 Tag 的 commit 信息\n */\n async getTagCommit(projectPath: string, tag: string): Promise<string | null> {\n try {\n const tags = await this.listTags(projectPath);\n const targetTag = tags.find((t) => t.name === tag);\n return targetTag?.commit.id || null;\n } catch {\n return null;\n }\n }\n\n /**\n * 获取指定 Branch 的最新 commit 信息\n */\n async getBranchCommit(projectPath: string, branch: string): Promise<string | null> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(\n `/projects/${encodedPath}/repository/branches/${encodeURIComponent(branch)}`\n );\n\n if (!response.ok) {\n return null;\n }\n\n const branchInfo: GitLabBranch = await response.json();\n return branchInfo.commit.id;\n } catch {\n return null;\n }\n }\n\n /**\n * 对比两个版本之间的差异\n */\n async compareVersions(\n projectPath: string,\n from: string,\n to: string\n ): Promise<GitLabDiffResult | null> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(\n `/projects/${encodedPath}/repository/compare?from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}`\n );\n\n if (!response.ok) {\n return null;\n }\n\n return await response.json();\n } catch {\n return null;\n }\n }\n\n /**\n * 比较两个版本号(用于排序)\n * 返回值: -1 (v1 < v2), 0 (v1 == v2), 1 (v1 > v2)\n */\n private compareVersionStrings(v1: string, v2: string): number {\n // 移除 'v' 前缀\n const version1 = v1.replace(/^v/, '');\n const version2 = v2.replace(/^v/, '');\n\n const parts1 = version1.split('.').map((p) => parseInt(p, 10) || 0);\n const parts2 = version2.split('.').map((p) => parseInt(p, 10) || 0);\n\n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const p1 = parts1[i] || 0;\n const p2 = parts2[i] || 0;\n\n if (p1 > p2) return 1;\n if (p1 < p2) return -1;\n }\n\n return 0;\n }\n\n /**\n * 获取最新的版本(优先 Tag,否则 latest commit)\n */\n async getLatestVersion(projectPath: string): Promise<{ type: 'tag' | 'commit'; name: string; commit: string } | null> {\n try {\n const tags = await this.listTags(projectPath);\n const branches = await this.listBranches(projectPath);\n\n // 优先返回最新的 tag\n if (tags.length > 0) {\n const latestTag = tags[0];\n return {\n type: 'tag',\n name: latestTag.name,\n commit: latestTag.commit.id,\n };\n }\n\n // 如果没有 tag,返回默认分支的最新 commit\n const defaultBranch = branches.find((b) => b.default);\n if (defaultBranch) {\n return {\n type: 'commit',\n name: defaultBranch.name,\n commit: defaultBranch.commit.id,\n };\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * 解析项目路径\n * 从 Git URL 中提取项目路径\n */\n static parseProjectPath(repository: string): string {\n // 支持的格式:\n // - git@gitlab.com:group/project.git\n // - https://gitlab.com/group/project.git\n // - gitlab.com/group/project\n\n let path = repository;\n\n // 处理 SSH URL 格式 (git@domain:group/project.git)\n if (path.startsWith('git@')) {\n path = path.replace(/^git@/, '');\n const colonIndex = path.indexOf(':');\n if (colonIndex !== -1) {\n path = path.substring(colonIndex + 1);\n }\n } else {\n // 移除 HTTPS 协议前缀\n path = path.replace(/^https?:\\/\\//, '');\n // 移除域名\n const parts = path.split('/');\n if (parts.length > 1) {\n path = parts.slice(1).join('/');\n }\n }\n\n // 移除 .git 后缀\n path = path.replace(/\\.git$/, '');\n\n return path;\n }\n\n /**\n * 编码项目路径用于 API 请求\n */\n private encodeProjectPath(projectPath: string): string {\n // GitLab API 需要对项目路径进行 URL 编码\n // 并且需要将 / 替换为 %2F\n return encodeURIComponent(projectPath).replace(/%2F/g, '%2F');\n }\n\n /**\n * 发送 HTTP 请求\n */\n private async request(endpoint: string, options: RequestInit = {}): Promise<Response> {\n const url = `${this.config.baseUrl}/api/v4${endpoint}`;\n\n const headers: HeadersInit = {\n 'PRIVATE-TOKEN': this.config.accessToken,\n 'Content-Type': 'application/json',\n ...options.headers,\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const response = await fetch(url, {\n ...options,\n headers,\n signal: controller.signal,\n });\n\n return response;\n } catch (error: any) {\n if (error.name === 'AbortError') {\n throw new Error('请求超时');\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * 获取默认分支\n */\n async getDefaultBranch(projectPath: string): Promise<string | null> {\n try {\n const project = await this.getProject(projectPath);\n return project?.default_branch || null;\n } catch {\n return null;\n }\n }\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport {\n checkTemplateUpdate,\n updateTemplateVersion,\n readTemplateConfig,\n type TemplateType,\n} from '../lib/template-version.js';\nimport { logger } from '../lib/logger.js';\nimport { FileUtils } from '../lib/utils.js';\nimport { execa } from 'execa';\nimport inquirer from 'inquirer';\nimport { Listr } from 'listr2';\nimport fs from 'fs-extra';\n\n/**\n * Update 命令选项接口\n */\ninterface UpdateOptions {\n tag?: string;\n branch?: string;\n dryRun?: boolean;\n}\n\n/**\n * Update 命令 - 检查并更新模板版本\n */\nexport const updateCommand = new Command('update')\n .description('检查并更新模板版本')\n .option('-f, --frontend', '检查前端模板更新')\n .option('-b, --backend', '检查后端模板更新')\n .option('-a, --all', '检查所有模板 (默认)')\n .option('-t, --tag <tag>', '更新到指定标签')\n .option('-B, --branch <branch>', '更新到指定分支')\n .option('--dry-run', '预览更新,不实际执行')\n .action(async (options) => {\n try {\n logger.header('模板版本检查');\n logger.newLine();\n\n // 检查是否在项目目录中\n const hasConfig = await FileUtils.exists('TECH_STACK.md');\n if (!hasConfig) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先切换到项目目录\");\n process.exit(1);\n }\n\n const projectPath = '.';\n const checkAll = !options.frontend && !options.backend;\n const checkFrontend = options.frontend || checkAll;\n const checkBackend = options.backend || checkAll;\n\n // 如果指定了 tag 或 branch,则强制更新到指定版本\n const forceUpdate = options.tag || options.branch;\n\n const updates: Array<{ type: TemplateType; info: any; updateOptions?: UpdateOptions }> = [];\n const updateOptions: UpdateOptions = {\n tag: options.tag,\n branch: options.branch,\n dryRun: options.dryRun,\n };\n\n // 检查前端模板\n if (checkFrontend) {\n logger.step('检查前端模板...');\n const frontendInfo = await checkTemplateUpdate(projectPath, 'frontend');\n\n if (frontendInfo) {\n if (frontendInfo.needsUpdate || forceUpdate) {\n const version = updateOptions.tag || updateOptions.branch || frontendInfo.latestTag || frontendInfo.latestCommit?.substring(0, 8);\n logger.success(`前端模板${forceUpdate ? '将更新' : '有更新'} (${version})`);\n updates.push({ type: 'frontend', info: frontendInfo, updateOptions });\n } else {\n logger.info('前端模板已是最新版本');\n }\n } else {\n logger.info('前端模板未配置或无法检查');\n }\n logger.newLine();\n }\n\n // 检查后端模板\n if (checkBackend) {\n logger.step('检查后端模板...');\n const backendInfo = await checkTemplateUpdate(projectPath, 'backend');\n\n if (backendInfo) {\n if (backendInfo.needsUpdate || forceUpdate) {\n const version = updateOptions.tag || updateOptions.branch || backendInfo.latestTag || backendInfo.latestCommit?.substring(0, 8);\n logger.success(`后端模板${forceUpdate ? '将更新' : '有更新'} (${version})`);\n updates.push({ type: 'backend', info: backendInfo, updateOptions });\n } else {\n logger.info('后端模板已是最新版本');\n }\n } else {\n logger.info('后端模板未配置或无法检查');\n }\n logger.newLine();\n }\n\n // 显示总结\n if (updates.length === 0) {\n logger.success('所有模板已是最新版本!');\n return;\n }\n\n if (options.dryRun) {\n logger.header(`[Dry Run] 发现 ${updates.length} 个模板`);\n } else {\n logger.header(`发现 ${updates.length} 个模板更新`);\n }\n logger.newLine();\n\n for (const update of updates) {\n const version = update.updateOptions?.tag || update.updateOptions?.branch || update.info.latestTag || update.info.latestCommit?.substring(0, 8);\n logger.step(`${update.type === 'frontend' ? '前端' : '后端'}模板: ${version}`);\n }\n logger.newLine();\n\n // 如果是 dry-run 模式,直接显示信息并退出\n if (options.dryRun) {\n logger.info('Dry run 模式,不执行实际更新');\n return;\n }\n\n // 询问是否更新\n const answers = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'shouldUpdate',\n message: '是否更新模板?',\n default: false,\n },\n ]);\n\n if (answers.shouldUpdate) {\n await performUpdate(projectPath, updates);\n } else {\n logger.info('已取消更新');\n }\n } catch (error: any) {\n logger.error(`更新检查失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 执行模板更新\n */\nasync function performUpdate(\n projectPath: string,\n updates: Array<{ type: TemplateType; info: any; updateOptions?: UpdateOptions }>\n): Promise<void> {\n logger.newLine();\n logger.info('开始更新模板...');\n\n for (const update of updates) {\n const { type, info, updateOptions } = update;\n const targetDir = type === 'frontend' ? 'frontend' : 'backend';\n const targetPath = path.join(projectPath, targetDir);\n\n logger.newLine();\n logger.step(`更新 ${type === 'frontend' ? '前端' : '后端'}模板...`);\n\n // 如果指定了 tag 或 branch,先验证\n if (updateOptions?.tag || updateOptions?.branch) {\n const { userConfigManager } = await import('../lib/user-config.js');\n const { GitLabAPI } = await import('../lib/gitlab-api.js');\n\n const config = await userConfigManager.getGitLabConfig();\n if (config) {\n const gitlabAPI = new GitLabAPI(config);\n const projectPathEncoded = GitLabAPI.parseProjectPath(info.repository);\n\n if (updateOptions.tag) {\n const isValid = await gitlabAPI.validateTag(projectPathEncoded, updateOptions.tag);\n if (!isValid) {\n logger.error(`${type === 'frontend' ? '前端' : '后端'}模板 tag \"${updateOptions.tag}\" 不存在`);\n continue;\n }\n logger.info(`使用 ${type === 'frontend' ? '前端' : '后端'}模板 tag: ${updateOptions.tag}`);\n }\n\n if (updateOptions.branch) {\n const isValid = await gitlabAPI.validateBranch(projectPathEncoded, updateOptions.branch);\n if (!isValid) {\n logger.error(`${type === 'frontend' ? '前端' : '后端'}模板分支 \"${updateOptions.branch}\" 不存在`);\n continue;\n }\n logger.info(`使用 ${type === 'frontend' ? '前端' : '后端'}模板分支: ${updateOptions.branch}`);\n }\n } else {\n logger.warn('未配置 GitLab Token,跳过版本验证');\n }\n }\n\n // 确定要克隆的 ref\n const ref = updateOptions?.tag || updateOptions?.branch || 'HEAD';\n\n // 创建备份\n const backupDir = path.join(projectPath, `.backup-${Date.now()}`);\n await fs.copy(targetPath, path.join(backupDir, targetDir));\n logger.info(`已创建备份: ${backupDir}`);\n\n // Dry run 模式\n if (updateOptions?.dryRun) {\n logger.info('[Dry Run] 将会更新到以下版本:');\n logger.info(` Ref: ${ref}`);\n logger.info(` 仓库: ${info.repository}`);\n logger.info('备份已创建,跳过实际更新');\n continue;\n }\n\n try {\n // 克隆最新模板到临时目录\n const tempDir = path.join(projectPath, `.template-update-${Date.now()}`);\n\n await execa('git', ['clone', '--depth=1', '--branch', ref, info.repository, tempDir], {\n stdio: 'pipe',\n });\n\n // 获取最新 commit\n const { stdout: commit } = await execa('git', ['rev-parse', 'HEAD'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n\n // 获取最新 tag\n const { stdout: tags } = await execa('git', ['tag', '-l', '--sort=-v:refname'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n const latestTag = tags.split('\\n')[0] || undefined;\n\n // 删除旧内容(保留配置文件)\n const keepFiles = ['.env.local', 'package-lock.json', 'node_modules'];\n const currentFiles = await FileUtils.findFiles('*', targetPath);\n\n for (const file of currentFiles) {\n if (!keepFiles.includes(file)) {\n const filePath = path.join(targetPath, file);\n try {\n await fs.remove(filePath);\n } catch {\n // 忽略删除失败\n }\n }\n }\n\n // 复制新模板内容\n await fs.copy(tempDir, targetPath, {\n filter: (src) => !src.includes('.git'),\n });\n\n // 删除临时目录\n await fs.remove(tempDir);\n\n // 更新配置\n await updateTemplateVersion(projectPath, type, commit.trim(), {\n tag: updateOptions?.tag || latestTag,\n branch: updateOptions?.branch,\n });\n\n logger.success(`${type === 'frontend' ? '前端' : '后端'}模板更新完成!`);\n logger.info(`新版本: ${updateOptions?.tag || updateOptions?.branch || latestTag || commit.substring(0, 8)}`);\n logger.info(`备份位置: ${backupDir}`);\n } catch (error: any) {\n logger.error(`更新失败: ${error.message}`);\n logger.info('正在恢复备份...');\n\n // 恢复备份\n await fs.remove(targetPath);\n await fs.copy(path.join(backupDir, targetDir), targetPath);\n await fs.remove(backupDir);\n\n logger.info('已恢复到更新前的状态');\n }\n }\n\n logger.newLine();\n logger.header('模板更新完成!');\n logger.newLine();\n logger.info('下一步:');\n logger.step('1. 检查更新后的代码');\n logger.step('2. 运行 npm install 安装新依赖');\n logger.step('3. 测试应用是否正常运行');\n logger.step('4. 提交代码到 Git');\n logger.newLine();\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport { userConfigManager } from '../lib/user-config.js';\nimport { GitLabAPI } from '../lib/gitlab-api.js';\nimport { logger } from '../lib/logger.js';\n\n/**\n * 设置 GitLab Access Token\n */\nexport const setTokenCommand = new Command('set-token')\n .description('设置 GitLab Access Token')\n .option('-t, --token <token>', 'Access Token')\n .option('-u, --url <url>', 'GitLab Base URL', 'https://gitlab.com')\n .action(async (options) => {\n try {\n logger.header('GitLab Access Token 配置');\n logger.newLine();\n\n let { token, url } = options;\n\n // 如果没有提供 token,交互式输入\n if (!token) {\n const answers = await inquirer.prompt([\n {\n type: 'password',\n name: 'token',\n message: '请输入 GitLab Access Token:',\n mask: '*',\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return 'Token 不能为空';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'url',\n message: '请输入 GitLab Base URL:',\n default: 'https://gitlab.com',\n validate: (input: string) => {\n try {\n new URL(input);\n return true;\n } catch {\n return '请输入有效的 URL';\n }\n },\n },\n ]);\n token = answers.token;\n url = answers.url;\n }\n\n // 验证 URL 格式\n try {\n new URL(url);\n } catch {\n logger.error('无效的 GitLab URL');\n process.exit(1);\n }\n\n // 移除 URL 末尾的斜杠\n url = url.replace(/\\/+$/, '');\n\n logger.info('验证 Token...');\n const gitlabAPI = new GitLabAPI({ accessToken: token, baseUrl: url });\n const isValid = await gitlabAPI.authenticate();\n\n if (!isValid) {\n logger.error('Token 验证失败,请检查:');\n logger.info('1. Token 是否正确');\n logger.info('2. Token 是否有 api 权限');\n logger.info('3. GitLab URL 是否正确');\n process.exit(1);\n }\n\n logger.success('Token 验证成功!');\n\n // 保存配置\n await userConfigManager.updateGitLabToken(token, url);\n logger.success('配置已保存!');\n logger.newLine();\n logger.info(`GitLab URL: ${chalk.cyan(url)}`);\n logger.info(`配置文件: ${chalk.gray(userConfigManager.getConfigPath())}`);\n } catch (error: any) {\n logger.error(`配置失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 显示当前配置\n */\nexport const showConfigCommand = new Command('show')\n .description('显示当前配置')\n .action(async () => {\n try {\n logger.header('GitLab 配置');\n logger.newLine();\n\n const hasConfig = await userConfigManager.hasConfig();\n\n if (!hasConfig) {\n logger.warn('未配置 GitLab Access Token');\n logger.info(\"请使用 'team-cli config set-token' 进行配置\");\n } else {\n const config = await userConfigManager.load();\n\n if (config?.gitlab) {\n const token = config.gitlab.accessToken;\n const maskedToken = token ? `${token.substring(0, 8)}${'*'.repeat(Math.min(16, token.length - 8))}` : '';\n\n logger.info(`GitLab URL: ${chalk.cyan(config.gitlab.baseUrl)}`);\n logger.info(`Access Token: ${chalk.yellow(maskedToken)}`);\n logger.info(`Timeout: ${chalk.gray(config.gitlab.timeout || 30000)}ms`);\n\n if (config.preferences) {\n logger.newLine();\n logger.info('偏好设置:');\n if (config.preferences.defaultBackendBranch) {\n logger.info(` 默认后端分支: ${chalk.cyan(config.preferences.defaultBackendBranch)}`);\n }\n if (config.preferences.defaultFrontendBranch) {\n logger.info(` 默认前端分支: ${chalk.cyan(config.preferences.defaultFrontendBranch)}`);\n }\n }\n\n logger.newLine();\n logger.info('配置文件位置:');\n logger.info(` ${chalk.gray(userConfigManager.getConfigPath())}`);\n }\n }\n } catch (error: any) {\n logger.error(`读取配置失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 删除配置\n */\nexport const removeConfigCommand = new Command('remove')\n .alias('rm')\n .description('删除 GitLab 配置')\n .action(async () => {\n try {\n const hasConfig = await userConfigManager.hasConfig();\n\n if (!hasConfig) {\n logger.warn('未配置 GitLab Access Token');\n return;\n }\n\n const answers = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: '确定要删除 GitLab 配置吗?',\n default: false,\n },\n ]);\n\n if (!answers.confirm) {\n logger.info('已取消');\n return;\n }\n\n await userConfigManager.removeConfig();\n logger.success('配置已删除');\n } catch (error: any) {\n logger.error(`删除配置失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 验证 Token\n */\nexport const validateTokenCommand = new Command('validate')\n .alias('test')\n .description('验证当前 Token 是否有效')\n .action(async () => {\n try {\n logger.header('验证 GitLab Token');\n logger.newLine();\n\n const config = await userConfigManager.getGitLabConfig();\n\n if (!config) {\n logger.warn('未配置 GitLab Access Token');\n logger.info(\"请使用 'team-cli config set-token' 进行配置\");\n process.exit(1);\n }\n\n logger.info('正在验证...');\n\n const gitlabAPI = new GitLabAPI(config);\n const isValid = await gitlabAPI.authenticate();\n\n if (isValid) {\n logger.success('Token 有效!');\n logger.newLine();\n logger.info(`GitLab URL: ${chalk.cyan(config.baseUrl)}`);\n } else {\n logger.error('Token 验证失败');\n logger.info('请检查 Token 是否正确或已过期');\n process.exit(1);\n }\n } catch (error: any) {\n logger.error(`验证失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * Config 命令 - 管理 GitLab 配置\n */\nexport const configCommand = new Command('config')\n .description('管理 GitLab 配置')\n .addCommand(setTokenCommand)\n .addCommand(showConfigCommand)\n .addCommand(removeConfigCommand)\n .addCommand(validateTokenCommand);\n","import { Command } from 'commander';\nimport path from 'path';\nimport chalk from 'chalk';\nimport table from 'cli-table3';\nimport { readTemplateConfig, type TemplateType } from '../lib/template-version.js';\nimport { logger } from '../lib/logger.js';\nimport { FileUtils } from '../lib/utils.js';\nimport { userConfigManager } from '../lib/user-config.js';\nimport { GitLabAPI, GitLabDiffResult } from '../lib/gitlab-api.js';\n\n/**\n * Diff 命令 - 对比本地与远程模板差异\n */\nexport const diffCommand = new Command('diff')\n .description('对比本地与远程模板差异')\n .option('-f, --frontend', '对比前端模板')\n .option('-b, --backend', '对比后端模板')\n .option('-t, --tag <tag>', '指定远程标签')\n .option('-B, --branch <branch>', '指定远程分支')\n .option('-o, --output <format>', '输出格式 (table|json|diff)', 'table')\n .action(async (options) => {\n try {\n logger.header('模板版本对比');\n logger.newLine();\n\n // 检查是否在项目目录中\n const hasConfig = await FileUtils.exists('TECH_STACK.md');\n if (!hasConfig) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先切换到项目目录\");\n process.exit(1);\n }\n\n const projectPath = '.';\n const checkAll = !options.frontend && !options.backend;\n const checkFrontend = options.frontend || checkAll;\n const checkBackend = options.backend || checkAll;\n\n const config = await readTemplateConfig(projectPath);\n if (!config) {\n logger.error('未找到模板配置');\n process.exit(1);\n }\n\n const gitlabConfig = await userConfigManager.getGitLabConfig();\n if (!gitlabConfig) {\n logger.warn('未配置 GitLab Token');\n logger.info(\"请使用 'team-cli config set-token' 进行配置\");\n logger.info(\"将使用基本 git 命令进行对比\");\n }\n\n const results: Array<{\n type: TemplateType;\n local: any;\n remote: any;\n diff?: GitLabDiffResult;\n }> = [];\n\n // 对比前端模板\n if (checkFrontend && config.frontend) {\n const result = await compareTemplate(\n projectPath,\n 'frontend',\n config.frontend,\n options.tag,\n options.branch,\n gitlabConfig || undefined\n );\n if (result) {\n results.push(result);\n }\n }\n\n // 对比后端模板\n if (checkBackend && config.backend) {\n const result = await compareTemplate(\n projectPath,\n 'backend',\n config.backend,\n options.tag,\n options.branch,\n gitlabConfig || undefined\n );\n if (result) {\n results.push(result);\n }\n }\n\n if (results.length === 0) {\n logger.info('没有可对比的模板');\n return;\n }\n\n // 根据输出格式显示结果\n switch (options.output) {\n case 'json':\n outputJson(results);\n break;\n case 'diff':\n outputDiff(results);\n break;\n case 'table':\n default:\n outputTable(results);\n break;\n }\n } catch (error: any) {\n logger.error(`对比失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 对比模板版本\n */\nasync function compareTemplate(\n projectPath: string,\n type: TemplateType,\n localConfig: any,\n remoteTag?: string,\n remoteBranch?: string,\n gitlabConfig?: { accessToken: string; baseUrl: string; timeout?: number }\n): Promise<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult } | null> {\n try {\n logger.step(`对比${type === 'frontend' ? '前端' : '后端'}模板...`);\n\n const repository = localConfig.repository;\n const localCommit = localConfig.commit;\n const localTag = localConfig.tag;\n const localBranch = localConfig.branch;\n\n let remoteCommit: string | null = null;\n let remoteTagName: string | undefined;\n let remoteBranchName: string | undefined;\n\n // 如果有 GitLab 配置,使用 API 获取远程信息\n if (gitlabConfig) {\n const gitlabAPI = new GitLabAPI(gitlabConfig);\n const projectPathEncoded = GitLabAPI.parseProjectPath(repository);\n\n if (remoteTag) {\n // 获取指定 tag 的 commit\n remoteCommit = await gitlabAPI.getTagCommit(projectPathEncoded, remoteTag);\n remoteTagName = remoteTag;\n } else if (remoteBranch) {\n // 获取指定 branch 的 commit\n remoteCommit = await gitlabAPI.getBranchCommit(projectPathEncoded, remoteBranch);\n remoteBranchName = remoteBranch;\n } else {\n // 获取最新版本\n const latest = await gitlabAPI.getLatestVersion(projectPathEncoded);\n if (latest) {\n remoteCommit = latest.commit;\n if (latest.type === 'tag') {\n remoteTagName = latest.name;\n } else {\n remoteBranchName = latest.name;\n }\n }\n }\n\n // 获取 diff 信息\n if (remoteCommit && localCommit && remoteCommit !== localCommit) {\n const from = localTag || localBranch || localCommit;\n const to = remoteTagName || remoteBranchName || remoteCommit;\n const diff = await gitlabAPI.compareVersions(projectPathEncoded, from, to);\n\n return {\n type,\n local: {\n commit: localCommit,\n tag: localTag,\n branch: localBranch,\n },\n remote: {\n commit: remoteCommit,\n tag: remoteTagName,\n branch: remoteBranchName,\n },\n diff: diff || undefined,\n };\n }\n }\n\n // 如果没有 GitLab 配置,使用 git 命令获取基本信息\n if (!remoteCommit) {\n // 使用 git ls-remote 获取远程最新 commit\n const { execa } = await import('execa');\n const ref = remoteTag || remoteBranch || 'HEAD';\n const { stdout } = await execa('git', ['ls-remote', repository, ref], {\n stdio: 'pipe',\n });\n remoteCommit = stdout.split('\\t')[0];\n remoteTagName = remoteTag;\n remoteBranchName = remoteBranch;\n }\n\n const needsUpdate = localCommit !== remoteCommit;\n\n logger.info(\n `${type === 'frontend' ? '前端' : '后端'}模板: ${needsUpdate ? chalk.yellow('有更新') : chalk.green('已是最新')}`\n );\n\n return {\n type,\n local: {\n commit: localCommit,\n tag: localTag,\n branch: localBranch,\n },\n remote: {\n commit: remoteCommit || undefined,\n tag: remoteTagName,\n branch: remoteBranchName,\n },\n };\n } catch (error) {\n logger.error(`对比${type === 'frontend' ? '前端' : '后端'}模板失败: ${error}`);\n return null;\n }\n}\n\n/**\n * 输出表格格式\n */\nfunction outputTable(results: Array<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult }>): void {\n logger.newLine();\n\n for (const result of results) {\n const typeName = result.type === 'frontend' ? '前端' : '后端';\n console.log(chalk.bold(`${typeName}模板:`));\n console.log('');\n\n const t = new Table({\n head: [chalk.cyan('项目'), chalk.cyan('版本')],\n colWidths: [20, 50],\n });\n\n // 本地版本\n const localVersion = result.local.tag || result.local.branch || result.local.commit?.substring(0, 8) || '-';\n const localInfo = `Commit: ${result.local.commit?.substring(0, 8) || '-'}${result.local.tag ? `\\nTag: ${result.local.tag}` : ''}${result.local.branch ? `\\nBranch: ${result.local.branch}` : ''}`;\n t.push(['本地', localInfo]);\n\n // 远程版本\n const remoteVersion = result.remote.tag || result.remote.branch || result.remote.commit?.substring(0, 8) || '-';\n const remoteInfo = `Commit: ${result.remote.commit?.substring(0, 8) || '-'}${result.remote.tag ? `\\nTag: ${result.remote.tag}` : ''}${result.remote.branch ? `\\nBranch: ${result.remote.branch}` : ''}`;\n t.push(['远程', remoteInfo]);\n\n console.log(t.toString());\n\n // 显示 diff 信息\n if (result.diff && result.diff.commits.length > 0) {\n console.log('');\n console.log(chalk.bold('新增提交:'));\n\n const commitsTable = new Table({\n head: [chalk.cyan('Commit'), chalk.cyan('作者'), chalk.cyan('时间'), chalk.cyan('描述')],\n colWidths: [10, 15, 20, 50],\n wordWrap: true,\n });\n\n for (const commit of result.diff.commits.slice(0, 10)) {\n commitsTable.push([\n commit.short_id,\n commit.author_name,\n new Date(commit.created_at).toLocaleDateString('zh-CN'),\n commit.title,\n ]);\n }\n\n console.log(commitsTable.toString());\n\n if (result.diff.commits.length > 10) {\n console.log(chalk.gray(`... 还有 ${result.diff.commits.length - 10} 个提交`));\n }\n\n // 文件变更统计\n const files = result.diff.diffs;\n const added = files.filter((f) => f.new_file).length;\n const deleted = files.filter((f) => f.deleted_file).length;\n const modified = files.length - added - deleted;\n\n console.log('');\n console.log(chalk.bold('文件变更:'));\n console.log(` ${chalk.green('+')} 新增: ${added}`);\n console.log(` ${chalk.red('-')} 删除: ${deleted}`);\n console.log(` ${chalk.yellow('~')} 修改: ${modified}`);\n }\n\n console.log('');\n }\n}\n\n/**\n * 输出 JSON 格式\n */\nfunction outputJson(results: Array<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult }>): void {\n console.log(JSON.stringify(results, null, 2));\n}\n\n/**\n * 输出 diff 格式\n */\nfunction outputDiff(results: Array<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult }>): void {\n logger.newLine();\n\n for (const result of results) {\n const typeName = result.type === 'frontend' ? '前端' : '后端';\n console.log(chalk.bold(`${typeName}模板:`));\n console.log('');\n\n const from = result.local.tag || result.local.branch || result.local.commit?.substring(0, 8) || 'unknown';\n const to = result.remote.tag || result.remote.branch || result.remote.commit?.substring(0, 8) || 'unknown';\n\n console.log(`本地版本: ${chalk.cyan(from)}`);\n console.log(`远程版本: ${chalk.cyan(to)}`);\n\n if (result.diff && result.diff.commits.length > 0) {\n console.log('');\n console.log(chalk.bold('提交历史:'));\n\n for (const commit of result.diff.commits) {\n console.log('');\n console.log(chalk.yellow(`commit ${commit.id}`));\n console.log(`Author: ${commit.author_name} <${commit.author_email}>`);\n console.log(`Date: ${new Date(commit.created_at).toLocaleString('zh-CN')}`);\n console.log('');\n console.log(` ${commit.title}`);\n if (commit.message) {\n console.log(` ${commit.message.split('\\n').join('\\n ')}`);\n }\n }\n }\n\n console.log('');\n }\n}\n\n/**\n * 简单的 Table 类(如果 cli-table3 不可用)\n */\nclass Table {\n private options: any;\n private rows: any[][] = [];\n\n constructor(options: any) {\n this.options = options;\n }\n\n push(row: any[]): void {\n this.rows.push(row);\n }\n\n toString(): string {\n if (this.rows.length === 0) return '';\n\n let result = '';\n const colWidths = this.options.colWidths || [];\n\n // 表头\n if (this.options.head) {\n result += '| ';\n for (let i = 0; i < this.options.head.length; i++) {\n const width = colWidths[i] || 20;\n const cell = this.options.head[i] || '';\n result += cell.padEnd(width) + ' | ';\n }\n result += '\\n';\n\n // 分隔线\n result += '|';\n for (let i = 0; i < this.options.head.length; i++) {\n const width = colWidths[i] || 20;\n result += '-'.repeat(width + 2) + '|';\n }\n result += '\\n';\n }\n\n // 数据行\n for (const row of this.rows) {\n result += '| ';\n for (let i = 0; i < row.length; i++) {\n const width = colWidths[i] || 20;\n const cell = String(row[i] || '');\n const displayCell = this.options.wordWrap && cell.length > width ? cell.substring(0, width - 3) + '...' : cell;\n result += displayCell.padEnd(width) + ' | ';\n }\n result += '\\n';\n }\n\n return result;\n }\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { logger } from './lib/logger.js';\nimport { initCommand } from './commands/init.js';\nimport { breakdownCommand } from './commands/breakdown.js';\nimport { devCommand } from './commands/dev.js';\nimport { addFeatureCommand } from './commands/add-feature.js';\nimport { splitPrdCommand } from './commands/split-prd.js';\nimport { bugfixCommand } from './commands/bugfix.js';\nimport { hotfixCommand } from './commands/bugfix.js';\nimport { acceptCommand } from './commands/accept.js';\nimport { addModuleCommand } from './commands/add-module.js';\nimport { lintCommand } from './commands/lint.js';\nimport { statusCommand } from './commands/status.js';\nimport { detectDepsCommand } from './commands/detect-deps.js';\nimport { syncMemoryCommand } from './commands/sync-memory.js';\nimport { checkApiCommand } from './commands/check-api.js';\nimport { logsCommand } from './commands/logs.js';\nimport { updateCommand } from './commands/update.js';\nimport { configCommand } from './commands/config.js';\nimport { diffCommand } from './commands/diff.js';\n\n/**\n * team-cli - AI-Native 团队研发脚手架\n * Node.js 版本\n */\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst pkg = fs.readJsonSync(path.join(__dirname, '../package.json'));\n\nconst program = new Command();\n\n// 基本信息\nprogram\n .name('team-cli')\n .description('AI-Native 团队研发脚手架')\n .version(pkg.version);\n\n// 全局选项\nprogram.option('-v, --verbose', '详细输出模式').option('--debug', '调试模式');\n\n// 注册命令\nprogram.addCommand(initCommand);\nprogram.addCommand(splitPrdCommand);\nprogram.addCommand(breakdownCommand);\nprogram.addCommand(devCommand);\nprogram.addCommand(addFeatureCommand);\nprogram.addCommand(bugfixCommand);\nprogram.addCommand(hotfixCommand);\nprogram.addCommand(acceptCommand);\nprogram.addCommand(addModuleCommand);\nprogram.addCommand(lintCommand);\nprogram.addCommand(statusCommand);\nprogram.addCommand(detectDepsCommand);\nprogram.addCommand(syncMemoryCommand);\nprogram.addCommand(checkApiCommand);\nprogram.addCommand(logsCommand);\nprogram.addCommand(updateCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(diffCommand);\n\n// 默认显示帮助\nprogram.action(() => {\n showHelp();\n});\n\n/**\n * 显示帮助信息\n */\nfunction showHelp() {\n console.log('');\n logger.header('team-cli - AI-Native 团队研发脚手架');\n console.log('');\n console.log(chalk.bold('使用方法:'));\n console.log(' team-cli init [project-name] 初始化新项目');\n console.log(' team-cli split-prd <prd-folder> 将 PRD 拆分成多个 specs');\n console.log(' team-cli breakdown [spec-file] 将 spec 拆分为 milestones 和 todos');\n console.log(' team-cli dev 开发模式,执行具体任务');\n console.log(' team-cli accept [spec-file] 验收功能,走查所有需求');\n console.log(' team-cli add-module 为已有项目新增模块');\n console.log(' team-cli add-feature <name> 添加新功能');\n console.log(' team-cli bugfix 创建 Bugfix 记录');\n console.log(' team-cli hotfix 创建 Hotfix');\n console.log(' team-cli detect-deps [spec] 检测依赖关系');\n console.log(' team-cli sync-memory 同步 AI_MEMORY.md');\n console.log(' team-cli check-api API 检查(冲突/变更/Registry)');\n console.log(' team-cli status 查看项目状态');\n console.log(' team-cli lint 代码质量检查 (前端+后端)');\n console.log(' team-cli logs [date] 查看会话日志');\n console.log(' team-cli update 检查并更新模板版本');\n console.log(' team-cli config 管理 GitLab 配置');\n console.log(' team-cli diff 对比本地与远程模板差异');\n console.log(' team-cli --help 显示帮助信息');\n console.log('');\n console.log(chalk.bold('示例:'));\n console.log(' team-cli init my-project');\n console.log(' cd my-project');\n console.log(' team-cli add-feature payment-system');\n console.log(' team-cli breakdown docs/specs/xxx.md');\n console.log(' team-cli dev');\n console.log('');\n console.log(chalk.bold('开发流程:'));\n console.log(' 1. PRD → specs (split-prd)');\n console.log(' 2. spec → milestones + todos (breakdown)');\n console.log(' 3. 选择 milestone/todo → 实现 (dev)');\n console.log(' 4. 验收 (accept) → 验证联调是否完成');\n console.log('');\n console.log(chalk.bold('迭代流程:'));\n console.log(' team-cli add-feature <name> # 添加新功能');\n console.log(' team-cli detect-deps [spec] # 检测依赖关系');\n console.log(' team-cli sync-memory # 同步 AI_MEMORY');\n console.log(' team-cli check-api # API 检查');\n console.log(' team-cli bugfix # 创建 bugfix');\n console.log(' team-cli hotfix # 紧急修复');\n console.log(' team-cli status # 查看项目状态');\n console.log('');\n console.log(chalk.bold('模板管理:'));\n console.log(' team-cli config set-token # 设置 GitLab Access Token');\n console.log(' team-cli config show # 显示当前配置');\n console.log(' team-cli init --tag v1.0.0 # 使用指定 tag 初始化');\n console.log(' team-cli update --tag v1.1.0 # 更新到指定版本');\n console.log(' team-cli diff # 对比模板差异');\n console.log('');\n console.log(chalk.gray('更多信息: https://github.com/yungu/team-cli'));\n console.log('');\n}\n\n/**\n * 错误处理\n */\nprocess.on('uncaughtException', (error) => {\n logger.error('未捕获的异常');\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n});\n\nprocess.on('unhandledRejection', (reason) => {\n logger.error('未处理的 Promise 拒绝');\n if (process.env.DEBUG) {\n console.error(reason);\n }\n process.exit(1);\n});\n\n// 解析命令行参数\nprogram.parse(process.argv);\n","#!/usr/bin/env node\n// CLI 入口文件\nimport('./index.js').catch((error) => {\n console.error('Failed to start team-cli:', error);\n process.exit(1);\n});\n"],"mappings":";;;;;;;;;;;;AACA,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAF9B;AAAA;AAAA;AAAA;AAAA;;;ACAA,OAAO,WAAW;AAClB,OAAO,SAAkB;AADzB,IAMa,QA+LA;AArMb;AAAA;AAAA;AAAA;AAMO,IAAM,SAAN,MAAa;AAAA,MACV,UAAsB;AAAA;AAAA;AAAA;AAAA,MAK9B,OAAO,MAAoB;AACzB,gBAAQ,IAAI,MAAM,KAAK,IAAI,CAAC;AAAA,MAC9B;AAAA;AAAA;AAAA;AAAA,MAKA,QAAQ,MAAoB;AAC1B,gBAAQ,IAAI,MAAM,MAAM,QAAG,GAAG,IAAI;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,MAAoB;AACxB,gBAAQ,MAAM,MAAM,IAAI,QAAG,GAAG,IAAI;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKA,KAAK,MAAoB;AACvB,gBAAQ,KAAK,MAAM,OAAO,QAAG,GAAG,IAAI;AAAA,MACtC;AAAA;AAAA;AAAA;AAAA,MAKA,KAAK,MAAoB;AACvB,gBAAQ,KAAK,MAAM,KAAK,QAAG,GAAG,IAAI;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKA,KAAK,MAAoB;AACvB,gBAAQ,IAAI,MAAM,KAAK,QAAG,GAAG,IAAI;AAAA,MACnC;AAAA;AAAA;AAAA;AAAA,MAKA,UAAgB;AACd,gBAAQ,IAAI,EAAE;AAAA,MAChB;AAAA;AAAA;AAAA;AAAA,MAKA,UAAU,OAAO,UAAK,SAAS,IAAU;AACvC,gBAAQ,IAAI,MAAM,KAAK,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,MAC7C;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,MAAmB;AAC9B,aAAK,UAAU,IAAI;AAAA,UACjB;AAAA,UACA,OAAO;AAAA,QACT,CAAC,EAAE,MAAM;AACT,eAAO,KAAK;AAAA,MACd;AAAA;AAAA;AAAA;AAAA,MAKA,cAAc,MAAoB;AAChC,YAAI,KAAK,SAAS;AAChB,eAAK,QAAQ,OAAO;AAAA,QACtB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,eAAe,MAAqB;AAClC,YAAI,KAAK,SAAS;AAChB,eAAK,QAAQ,QAAQ,IAAI;AACzB,eAAK,UAAU;AAAA,QACjB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,YAAY,MAAqB;AAC/B,YAAI,KAAK,SAAS;AAChB,eAAK,QAAQ,KAAK,IAAI;AACtB,eAAK,UAAU;AAAA,QACjB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,YAAY,MAAqB;AAC/B,YAAI,KAAK,SAAS;AAChB,eAAK,QAAQ,KAAK,IAAI;AACtB,eAAK,UAAU;AAAA,QACjB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,YAAY,MAAqB;AAC/B,YAAI,KAAK,SAAS;AAChB,eAAK,QAAQ,KAAK,IAAI;AACtB,eAAK,UAAU;AAAA,QACjB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,SAAmB,MAAwB;AAC/C,cAAM,eAAe,QAAQ,IAAI,CAAC,GAAG,MAAM;AACzC,gBAAM,WAAW,KAAK;AAAA,YACpB,EAAE;AAAA,YACF,GAAG,KAAK,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,IAAI,MAAM;AAAA,UAC5C;AACA,iBAAO,WAAW;AAAA,QACpB,CAAC;AAGD,cAAM,YAAY,QACf,IAAI,CAAC,GAAG,MAAM,MAAM,KAAK,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,EACnD,KAAK,EAAE;AACV,gBAAQ,IAAI,SAAS;AAGrB,cAAM,YAAY,aAAa,IAAI,CAAC,MAAM,SAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAG;AACjE,gBAAQ,IAAI,MAAM,KAAK,SAAS,CAAC;AAGjC,aAAK,QAAQ,CAAC,QAAQ;AACpB,gBAAM,UAAU,IACb,IAAI,CAAC,MAAM,OAAO,QAAQ,IAAI,OAAO,aAAa,CAAC,CAAC,CAAC,EACrD,KAAK,EAAE;AACV,kBAAQ,IAAI,OAAO;AAAA,QACrB,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA,MAKA,KAAK,MAAc,WAAW,IAAU;AACtC,YAAI,UAAU;AACZ,kBAAQ,IAAI,MAAM,KAAK,SAAS,QAAQ,EAAE,CAAC;AAAA,QAC7C;AACA,gBAAQ,IAAI,MAAM,KAAK,IAAI,CAAC;AAC5B,YAAI,UAAU;AACZ,kBAAQ,IAAI,MAAM,KAAK,KAAK,CAAC;AAAA,QAC/B;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,KAAK,OAAiB,SAAS,GAAS;AACtC,cAAM,QAAQ,CAAC,SAAS;AACtB,kBAAQ,IAAI,IAAI,OAAO,MAAM,IAAI,MAAM,KAAK,QAAG,IAAI,MAAM,IAAI;AAAA,QAC/D,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA,MAKA,QAAQ,OAAe,MAAc,aAAa,QAAc;AAC9D,cAAM,eAAe,MAAM,UAAgC,EAAE,IAAI,KAAK,GAAG;AACzE,gBAAQ,IAAI,GAAG,YAAY,IAAI,IAAI,EAAE;AAAA,MACvC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,MAAoB;AACxB,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,MAAM,KAAK,WAAW,IAAI,EAAE,CAAC;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAGO,IAAM,SAAS,IAAI,OAAO;AAAA;AAAA;;;ACrMjC,OAAO,QAAQ;AACf,OAAOA,WAAU;AACjB,SAAS,YAAY;AAFrB,IAQa,WA+FA,aAgIA,WAoFA,UAiCA;AA5Vb;AAAA;AAAA;AAAA;AAQO,IAAM,YAAN,MAAgB;AAAA;AAAA;AAAA;AAAA,MAIrB,aAAa,UAAU,KAA4B;AACjD,cAAM,GAAG,UAAU,GAAG;AAAA,MACxB;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,KAAK,MAA+B;AAC/C,eAAO,MAAM,GAAG,SAAS,MAAM,OAAO;AAAA,MACxC;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,SAAS,MAAsB;AACpC,eAAO,GAAG,aAAa,MAAM,OAAO;AAAA,MACtC;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,MAAM,MAAc,SAAgC;AAC/D,cAAM,MAAMA,MAAK,QAAQ,IAAI;AAC7B,cAAM,GAAG,UAAU,GAAG;AACtB,cAAM,GAAG,UAAU,MAAM,SAAS,OAAO;AAAA,MAC3C;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,OAAO,MAAgC;AAClD,eAAO,MAAM,GAAG,WAAW,IAAI;AAAA,MACjC;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,KAAK,KAAa,MAA6B;AAC1D,cAAM,GAAG,KAAK,KAAK,IAAI;AAAA,MACzB;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,OAAO,MAA6B;AAC/C,cAAM,GAAG,OAAO,IAAI;AAAA,MACtB;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,KAAK,KAAa,MAA6B;AAC1D,cAAM,GAAG,KAAK,KAAK,IAAI;AAAA,MACzB;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,UAAU,SAAiB,KAAiC;AACvE,eAAO,MAAM,KAAK,SAAS;AAAA,UACzB;AAAA,UACA,UAAU;AAAA,UACV,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,SAAkB,MAA0B;AACvD,eAAO,MAAM,GAAG,SAAS,IAAI;AAAA,MAC/B;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,UAAU,MAAc,MAA0B;AAC7D,cAAM,GAAG,UAAU,MAAM,MAAM,EAAE,QAAQ,EAAE,CAAC;AAAA,MAC9C;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,WAAW,KAAqB;AACrC,eAAOA,MAAK,QAAQ,IAAI,IAAI,GAAG,EAAE,QAAQ;AAAA,MAC3C;AAAA,IACF;AAKO,IAAM,cAAN,MAAkB;AAAA;AAAA;AAAA;AAAA,MAIvB,OAAO,YAAY,KAAqB;AACtC,eAAO,IACJ,YAAY,EACZ,QAAQ,WAAW,GAAG,EACtB,QAAQ,YAAY,EAAE,EACtB,QAAQ,OAAO,GAAG,EAClB,QAAQ,YAAY,EAAE;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,aAAa,KAAqB;AACvC,eAAO,IACJ,QAAQ,eAAe,CAAC,GAAG,MAAM,EAAE,YAAY,CAAC,EAChD,QAAQ,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC;AAAA,MAC1C;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,YAAY,KAAqB;AACtC,cAAM,SAAS,KAAK,aAAa,GAAG;AACpC,eAAO,OAAO,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC;AAAA,MACxD;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,YAAY,KAAqB;AACtC,eAAO,IACJ,QAAQ,UAAU,CAAC,WAAW,IAAI,OAAO,YAAY,CAAC,EAAE,EACxD,QAAQ,MAAM,EAAE,EAChB,QAAQ,OAAO,GAAG,EAClB,QAAQ,UAAU,GAAG;AAAA,MAC1B;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,WAAW,KAAqB;AACrC,eAAO,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAAA,MAClD;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,SAAS,KAAa,QAAgB,SAAS,OAAe;AACnE,YAAI,IAAI,UAAU,OAAQ,QAAO;AACjC,eAAO,IAAI,MAAM,GAAG,SAAS,OAAO,MAAM,IAAI;AAAA,MAChD;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,QAAQ,KAAqB;AAClC,eAAO,IACJ,YAAY,EACZ,KAAK,EACL,QAAQ,aAAa,EAAE,EACvB,QAAQ,YAAY,GAAG,EACvB,QAAQ,YAAY,EAAE;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,oBAAoB,MAAuB;AAChD,eAAO,eAAe,KAAK,IAAI;AAAA,MACjC;AAAA,IACF;AAsDO,IAAM,YAAN,MAAM,WAAU;AAAA;AAAA;AAAA;AAAA,MAIrB,OAAO,OAAO,OAAa,oBAAI,KAAK,GAAG,SAAS,uBAA+B;AAC7E,cAAM,OAAO,KAAK,YAAY;AAC9B,cAAM,QAAQ,OAAO,KAAK,SAAS,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG;AACzD,cAAM,MAAM,OAAO,KAAK,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG;AAClD,cAAM,QAAQ,OAAO,KAAK,SAAS,CAAC,EAAE,SAAS,GAAG,GAAG;AACrD,cAAM,UAAU,OAAO,KAAK,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG;AACzD,cAAM,UAAU,OAAO,KAAK,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG;AAEzD,eAAO,OACJ,QAAQ,QAAQ,OAAO,IAAI,CAAC,EAC5B,QAAQ,MAAM,KAAK,EACnB,QAAQ,MAAM,GAAG,EACjB,QAAQ,MAAM,KAAK,EACnB,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,OAAO;AAAA,MAC1B;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,SAAS,MAAoB;AAClC,cAAM,MAAM,oBAAI,KAAK;AACrB,cAAM,OAAO,IAAI,QAAQ,IAAI,KAAK,QAAQ;AAC1C,cAAM,UAAU,KAAK,MAAM,OAAO,GAAI;AACtC,cAAM,UAAU,KAAK,MAAM,UAAU,EAAE;AACvC,cAAM,QAAQ,KAAK,MAAM,UAAU,EAAE;AACrC,cAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;AAElC,YAAI,OAAO,GAAG;AACZ,iBAAO,WAAU,OAAO,MAAM,YAAY;AAAA,QAC5C,WAAW,OAAO,GAAG;AACnB,iBAAO,GAAG,IAAI;AAAA,QAChB,WAAW,QAAQ,GAAG;AACpB,iBAAO,GAAG,KAAK;AAAA,QACjB,WAAW,UAAU,GAAG;AACtB,iBAAO,GAAG,OAAO;AAAA,QACnB,OAAO;AACL,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAwCO,IAAM,WAAN,MAAe;AAAA;AAAA;AAAA;AAAA,MAIpB,aAAa,UAAU,MAAc,QAAQ,IAAI,GAAqB;AACpE,cAAM,SAASA,MAAK,KAAK,KAAK,MAAM;AACpC,eAAO,MAAM,UAAU,OAAO,MAAM;AAAA,MACtC;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,iBAAiB,MAAc,QAAQ,IAAI,GAAoB;AAC1E,cAAM,EAAE,OAAAC,OAAM,IAAI,MAAM,OAAO,OAAO;AACtC,cAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO,CAAC,aAAa,gBAAgB,MAAM,GAAG;AAAA,UAC3E;AAAA,QACF,CAAC;AACD,eAAO,OAAO,KAAK;AAAA,MACrB;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,iBAAiB,MAAc,QAAQ,IAAI,GAAoB;AAC1E,cAAM,EAAE,OAAAA,OAAM,IAAI,MAAM,OAAO,OAAO;AACtC,cAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO,CAAC,aAAa,MAAM,GAAG,EAAE,IAAI,CAAC;AACpE,eAAO,OAAO,KAAK,EAAE,MAAM,GAAG,CAAC;AAAA,MACjC;AAAA,IACF;AAKO,IAAM,YAAN,MAAgB;AAAA;AAAA;AAAA;AAAA,MAIrB,aAAa,UAAU,MAAsC;AAC3D,cAAM,UAAU,MAAM,UAAU,KAAK,IAAI;AACzC,cAAM,OAAsB,CAAC;AAG7B,cAAM,aAAa,QAAQ,MAAM,aAAa;AAC9C,YAAI,YAAY;AACd,eAAK,QAAQ,WAAW,CAAC;AAAA,QAC3B;AAGA,cAAM,YAAY,QAAQ,MAAM,wBAAwB;AACxD,YAAI,WAAW;AACb,eAAK,OAAO,UAAU,CAAC;AAAA,QACzB;AAGA,cAAM,gBAAgB,QAAQ,MAAM,yBAAyB;AAC7D,YAAI,eAAe;AACjB,eAAK,WAAW,cAAc,CAAC;AAAA,QACjC;AAGA,cAAM,cAAc,QAAQ,MAAM,sBAAsB;AACxD,YAAI,aAAa;AACf,eAAK,SAAS,YAAY,CAAC;AAAA,QAC7B;AAGA,cAAM,aAAa,QAAQ,MAAM,yBAAyB;AAC1D,YAAI,YAAY;AACd,gBAAM,aAAa,WAAW,CAAC,EAAE,SAAS,wBAAwB;AAClE,eAAK,eAAe,MAAM,KAAK,UAAU,EAAE,IAAI,CAAC,OAAO;AAAA,YACrD,WAAW,EAAE,CAAC,MAAM;AAAA,YACpB,MAAM,EAAE,CAAC;AAAA,UACX,EAAE;AAAA,QACJ;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,gBAAgB,SAAkC;AACvD,cAAM,aAA8B,CAAC;AACrC,cAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,YAAI,mBAAyC;AAC7C,YAAI,cAAc;AAElB,mBAAW,QAAQ,OAAO;AACxB,cAAI,KAAK,MAAM,yBAAyB,GAAG;AACzC,gBAAI,kBAAkB;AACpB,yBAAW,KAAK,gBAAgB;AAAA,YAClC;AACA,kBAAM,QAAQ,KAAK,QAAQ,WAAW,EAAE,EAAE,KAAK;AAC/C,+BAAmB,EAAE,OAAO,OAAO,CAAC,GAAG,gBAAgB,EAAE;AACzD,0BAAc;AACd;AAAA,UACF;AAEA,cAAI,eAAe,kBAAkB;AACnC,gBAAI,KAAK,MAAM,kBAAkB,GAAG;AAClC,yBAAW,KAAK,gBAAgB;AAChC,iCAAmB;AACnB;AAAA,YACF;AAEA,kBAAM,YAAY,KAAK,MAAM,yBAAyB;AACtD,gBAAI,WAAW;AACb,oBAAM,cAAc,UAAU,CAAC,EAAE,YAAY,MAAM;AACnD,kBAAI,aAAa;AACf,iCAAiB;AAAA,cACnB;AACA,+BAAiB,MAAM,KAAK,UAAU,CAAC,EAAE,KAAK,CAAC;AAAA,YACjD;AAAA,UACF;AAAA,QACF;AAEA,YAAI,kBAAkB;AACpB,qBAAW,KAAK,gBAAgB;AAAA,QAClC;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,wBAAwB,SAA0C;AACvE,cAAM,aAAsC,CAAC;AAC7C,cAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,YAAI,mBAAiD;AACrD,YAAI,cAAc;AAElB,mBAAW,QAAQ,OAAO;AACxB,cAAI,KAAK,MAAM,yBAAyB,GAAG;AACzC,gBAAI,kBAAkB;AACpB,+BAAiB,aAAa,iBAAiB,MAAM;AACrD,yBAAW,KAAK,gBAAgB;AAAA,YAClC;AACA,kBAAM,QAAQ,KAAK,QAAQ,WAAW,EAAE,EAAE,KAAK;AAC/C,+BAAmB;AAAA,cACjB;AAAA,cACA,OAAO,CAAC;AAAA,cACR,eAAe,CAAC;AAAA,cAChB,cAAc,CAAC;AAAA,cACf,kBAAkB,CAAC;AAAA,cACnB,cAAc,CAAC;AAAA,cACf,gBAAgB;AAAA,cAChB,YAAY;AAAA,YACd;AACA,0BAAc;AACd;AAAA,UACF;AAEA,cAAI,eAAe,kBAAkB;AACnC,gBAAI,KAAK,MAAM,kBAAkB,GAAG;AAClC,+BAAiB,aAAa,iBAAiB,MAAM;AACrD,yBAAW,KAAK,gBAAgB;AAChC,iCAAmB;AACnB,oBAAM,QAAQ,KAAK,QAAQ,WAAW,EAAE,EAAE,KAAK;AAC/C,iCAAmB;AAAA,gBACjB;AAAA,gBACA,OAAO,CAAC;AAAA,gBACR,eAAe,CAAC;AAAA,gBAChB,cAAc,CAAC;AAAA,gBACf,kBAAkB,CAAC;AAAA,gBACnB,cAAc,CAAC;AAAA,gBACf,gBAAgB;AAAA,gBAChB,YAAY;AAAA,cACd;AACA;AAAA,YACF;AAEA,kBAAM,YAAY,KAAK,MAAM,yCAAyC;AACtE,gBAAI,WAAW;AACb,oBAAM,cAAc,UAAU,CAAC,EAAE,YAAY,MAAM;AACnD,oBAAM,SAAS,UAAU,CAAC,GAAG,KAAK,KAAK;AACvC,oBAAM,aAAa,UAAU,CAAC,EAAE,KAAK;AAErC,kBAAI,OAAyB;AAC7B,kBAAI;AACJ,kBAAI;AAGJ,kBAAI,WAAW,OAAO;AACpB,uBAAO;AAAA,cACT,WAAW,WAAW,OAAO;AAC3B,uBAAO;AAEP,sBAAM,WAAW,WAAW,MAAM,yBAAyB;AAC3D,oBAAI,UAAU;AACZ,mCAAiB,SAAS,CAAC;AAAA,gBAC7B;AAAA,cACF,WAAW,WAAW,OAAO;AAC3B,uBAAO;AAEP,sBAAM,WAAW,WAAW,MAAM,mBAAmB;AACrD,oBAAI,UAAU;AACZ,iCAAe,SAAS,CAAC,EACtB,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAAA,gBAC/B;AAAA,cACF;AAEA,oBAAM,WAAqB;AAAA,gBACzB,KAAK,KAAK,KAAK;AAAA,gBACf,SAAS,WACN,QAAQ,4BAA4B,EAAE,EACtC,QAAQ,sBAAsB,EAAE,EAChC,KAAK;AAAA,gBACR;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAEA,+BAAiB,MAAM,KAAK,QAAQ;AACpC,kBAAI,aAAa;AACf,iCAAiB;AAAA,cACnB;AAGA,sBAAQ,MAAM;AAAA,gBACZ,KAAK;AACH,mCAAiB,cAAc,KAAK,QAAQ;AAC5C;AAAA,gBACF,KAAK;AACH,mCAAiB,aAAa,KAAK,QAAQ;AAC3C;AAAA,gBACF,KAAK;AACH,mCAAiB,iBAAiB,KAAK,QAAQ;AAC/C;AAAA,gBACF;AACE,mCAAiB,aAAa,KAAK,QAAQ;AAAA,cAC/C;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,YAAI,kBAAkB;AACpB,2BAAiB,aAAa,iBAAiB,MAAM;AACrD,qBAAW,KAAK,gBAAgB;AAAA,QAClC;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,oCAAoC,SAGzC;AACA,cAAM,WAAW,KAAK,wBAAwB,OAAO;AAErD,cAAM,oBAAoB,SAAS;AAAA,UAAK,CAAC,MACvC,EAAE,MAAM;AAAA,YACN,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,kBAAkB,EAAE;AAAA,UACvD;AAAA,QACF;AACA,eAAO,EAAE,UAAU,YAAY,kBAAkB;AAAA,MACnD;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,gBAAgB,SAAgD;AACrE,cAAM,aAAa,KAAK,gBAAgB,OAAO;AAE/C,YAAI,WAAW,SAAS,GAAG;AACzB,gBAAM,aAAa,WAAW,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxE,gBAAM,iBAAiB,WAAW,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,gBAAgB,CAAC;AAE9E,cAAI,aAAa,GAAG;AAClB,gBAAI,mBAAmB,WAAY,QAAO;AAC1C,gBAAI,iBAAiB,EAAG,QAAO;AAAA,UACjC;AACA,iBAAO;AAAA,QACT;AAEA,cAAM,cAAc,QAAQ,MAAM,iBAAiB;AACnD,YAAI,aAAa;AACf,gBAAM,SAAS,YAAY,CAAC,EAAE,QAAQ,SAAS,EAAE,EAAE,KAAK;AACxD,cAAI,OAAO,SAAS,oBAAK,EAAG,QAAO;AACnC,cAAI,OAAO,SAAS,oBAAK,EAAG,QAAO;AACnC,cAAI,OAAO,SAAS,oBAAK,EAAG,QAAO;AAAA,QACrC;AACA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,YAAY,SAAyB;AAC1C,cAAM,aAAa,KAAK,gBAAgB,OAAO;AAC/C,YAAI,WAAW,WAAW,EAAG,QAAO;AAEpC,cAAM,aAAa,WAAW,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxE,cAAM,iBAAiB,WAAW,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,gBAAgB,CAAC;AAE9E,YAAI,eAAe,EAAG,QAAO;AAC7B,eAAO,GAAG,cAAc,IAAI,UAAU;AAAA,MACxC;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,kBAAkB,QAAwB;AAC/C,YAAI,OAAO,SAAS,oBAAK,EAAG,QAAO;AACnC,YAAI,OAAO,SAAS,oBAAK,EAAG,QAAO;AACnC,YAAI,OAAO,SAAS,oBAAK,EAAG,QAAO;AACnC,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,cAAc,MAA+B;AACxD,YAAI;AACF,gBAAM,OAAO,MAAM,KAAK,UAAU,IAAI;AACtC,iBAAO,KAAK,UAAU;AAAA,QACxB,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACjoBA,SAAS,aAAa;AACtB,OAAOC,WAAU;AACjB,OAAOC,SAAQ;AACf,OAAO,QAAQ;AAHf,IAUa,UA2ZA;AArab;AAAA;AAAA;AAAA;AAIA;AACA;AAKO,IAAM,WAAN,MAAe;AAAA;AAAA,MAEZ;AAAA,MAER,YAAY,UAAU,OAAO;AAC3B,aAAK,UAAU;AAAA,MACjB;AAAA,MAEA,MAAM,iBAAmC;AACvC,YAAI;AAEF,gBAAM,EAAE,SAAS,IAAI,MAAM,MAAM,SAAS,CAAC,QAAQ,GAAG,EAAE,OAAO,UAAU,QAAQ,MAAM,CAAC;AACxF,iBAAO,aAAa;AAAA,QACtB,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,aAA8B;AAClC,YAAI;AACF,gBAAM,EAAE,OAAO,IAAI,MAAM,MAAM,UAAU,CAAC,WAAW,GAAG,EAAE,OAAO,OAAO,CAAC;AACzE,iBAAO,OAAO,KAAK;AAAA,QACrB,QAAQ;AACN,gBAAM,IAAI,MAAM,8CAAgB;AAAA,QAClC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,OAAO,YAAoB,SAA0C;AAEzE,cAAM,UAAU,GAAG,OAAO;AAC1B,cAAM,WAAWD,MAAK,KAAK,SAAS,mBAAmB,KAAK,IAAI,CAAC,MAAM;AAEvE,YAAI;AAEF,cAAI,cAAc;AAClB,gBAAM,oBAA8B,CAAC;AAGrC,cAAI,SAAS,gBAAgB,QAAQ,aAAa,SAAS,GAAG;AAC5D,uBAAW,QAAQ,QAAQ,cAAc;AACvC,oBAAM,SAAS,MAAM,UAAU,OAAO,IAAI;AAC1C,kBAAI,QAAQ;AACV,kCAAkB,KAAK,IAAI;AAAA,cAC7B,OAAO;AACL,uBAAO,KAAK,6EAAiB,IAAI,EAAE;AAAA,cACrC;AAAA,YACF;AAGA,gBAAI,kBAAkB,SAAS,GAAG;AAChC,oBAAM,eAAyB,CAAC;AAChC,yBAAW,QAAQ,mBAAmB;AACpC,oBAAI;AACF,wBAAM,UAAU,MAAM,UAAU,KAAK,IAAI;AACzC,wBAAM,WAAWA,MAAK,SAAS,IAAI;AACnC,+BAAa,KAAK,mBAAmB,QAAQ;AAAA;AAAA,EAAO,OAAO,EAAE;AAAA,gBAC/D,SAAS,OAAO;AACd,yBAAO,KAAK,wCAAU,IAAI,0BAAM;AAAA,gBAClC;AAAA,cACF;AAEA,kBAAI,aAAa,SAAS,GAAG;AAC3B,8BAAc,GAAG,aAAa,KAAK,aAAa,CAAC;AAAA;AAAA;AAAA;AAAA,EAAc,UAAU;AAAA,cAC3E;AAAA,YACF;AAAA,UACF;AAGA,gBAAMC,IAAG,UAAU,UAAU,aAAa,OAAO;AAKjD,gBAAM,SAAS,MAAM,MAAM,UAAU,CAAC,kCAAkC,IAAI,GAAG;AAAA,YAC7E,OAAO;AAAA;AAAA,YACP,SAAS,SAAS,WAAW;AAAA;AAAA,YAC7B,WAAW,OAAO,OAAO;AAAA;AAAA,UAC3B,CAAC;AAED,iBAAO,OAAO,UAAU;AAAA,QAC1B,UAAE;AAEA,cAAI;AACF,kBAAMA,IAAG,OAAO,QAAQ;AAAA,UAC1B,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,mBACJ,UACA,MACA,SACiB;AAEjB,YAAI,aAAa;AACjB,mBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,gBAAM,QAAQ,IAAI,OAAO,SAAS,GAAG,UAAU,GAAG;AAClD,uBAAa,WAAW,QAAQ,OAAO,OAAO,KAAK,CAAC;AAAA,QACtD;AAEA,eAAO,MAAM,KAAK,OAAO,YAAY,OAAO;AAAA,MAC9C;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,YAAY,YAAmC;AACnD,eAAO,KAAK,mEAAsB;AAElC,YAAI;AAEF,gBAAM,MAAM,UAAU,CAAC,kCAAkC,UAAU,GAAG;AAAA,YACpE,OAAO;AAAA,YACP,KAAK,EAAE,GAAG,QAAQ,KAAK,aAAa,IAAI;AAAA,UAC1C,CAAC;AAAA,QACH,SAAS,OAAY;AACnB,cAAI,MAAM,WAAW,UAAU;AAC7B,kBAAM;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,KAAK,UAAyB,SAA0C;AAE5E,cAAM,aAAa,SAChB,IAAI,CAAC,QAAQ;AACZ,gBAAM,OAAO,IAAI,SAAS,WAAW,6BAAS,GAAG,IAAI,SAAS,SAAS,iBAAO,cAAI;AAClF,iBAAO,IAAI,IAAI,MAAM,IAAI,OAAO;AAAA,QAClC,CAAC,EACA,KAAK,MAAM;AAId,cAAM,SAAS,MAAM,MAAM,UAAU,CAAC,kCAAkC,IAAI,GAAG;AAAA,UAC7E,OAAO;AAAA;AAAA,UACP,SAAS,SAAS,WAAW;AAAA,UAC7B,WAAW,OAAO,OAAO;AAAA,QAC3B,CAAC;AAED,eAAO,OAAO,UAAU;AAAA,MAC1B;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,YAAY,MAAc,UAAkB,UAAoC;AACpF,cAAM,SAAS,kCAAS,QAAQ,sBAAO,WAAW,2BAAO,QAAQ,KAAK,EAAE;AAAA;AAAA,QAEpE,QAAQ;AAAA,EACd,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASF,eAAO,MAAM,KAAK,OAAO,MAAM;AAAA,MACjC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,aACJ,aACA,UACA,SACiB;AACjB,YAAI,SAAS,gBAAM,QAAQ;AAAA;AAAA,EAAmB,WAAW;AAAA;AAAA;AAEzD,YAAI,SAAS;AACX,oBAAU;AAAA;AAAA,EAAa,OAAO;AAAA;AAAA;AAAA,QAChC;AAEA,kBAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAOV,eAAO,MAAM,KAAK,OAAO,MAAM;AAAA,MACjC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,WAAW,MAAc,UAA6C;AAC1E,cAAM,SAAS,kCAAS,QAAQ;AAAA;AAAA,QAE5B,QAAQ;AAAA,EACd,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBF,cAAM,WAAW,MAAM,KAAK,OAAO,MAAM;AACzC,YAAI;AAEF,gBAAM,YAAY,SAAS,MAAM,aAAa;AAC9C,cAAI,WAAW;AACb,mBAAO,KAAK,MAAM,UAAU,CAAC,CAAC;AAAA,UAChC;AAAA,QACF,QAAQ;AAAA,QAER;AAEA,eAAO;AAAA,UACL,QAAQ,CAAC;AAAA,UACT,aAAa,CAAC,QAAQ;AAAA,UACtB,YAAY,CAAC;AAAA,QACf;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,aACJ,aACA,aACA,gBACA,cACiB;AACjB,YAAI,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKf,WAAW;AAAA;AAAA;AAAA,EAGX,WAAW;AAAA;AAGT,YAAI,gBAAgB,aAAa,SAAS,GAAG;AAC3C,oBAAU;AAAA;AAAA,sFAEA,aAAa,KAAK,QAAG,CAAC;AAAA;AAAA,QAElC;AAEA,kBAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMZ,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBd,eAAe,aAAa,IAAI,CAAC,MAAM,SAAS,CAAC,EAAE,EAAE,KAAK,IAAI,IAAI,YAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8CA6B5C,YAAY,YAAY,WAAW,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoB/D,eAAO,MAAM,KAAK,OAAO,QAAQ,EAAE,SAAS,KAAO,CAAC;AAAA,MACtD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,qBACJ,gBACA,mBACA,gBACiB;AACjB,cAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKjB,cAAc;AAAA;AAAA;AAAA,EAGd,kBAAkB,IAAI,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,EAGlE,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUZ,eAAO,MAAM,KAAK,OAAO,QAAQ,EAAE,SAAS,KAAO,CAAC;AAAA,MACtD;AAAA,IACF;AAgCO,IAAM,WAAW,IAAI,SAAS;AAAA;AAAA;;;ACrarC,SAAS,SAAAC,cAAa;AACtB,OAAOC,WAAU;AAmEjB,SAAS,cAAc,aAA6B;AAClD,SAAOA,MAAK,KAAK,aAAa,aAAa,eAAe;AAC5D;AAKA,eAAsB,mBAAmB,aAAqD;AAC5F,QAAM,aAAa,cAAc,WAAW;AAC5C,QAAM,SAAS,MAAM,UAAU,OAAO,UAAU;AAEhD,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,UAAU,MAAM,UAAU,KAAK,UAAU;AAC/C,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,mBAAmB,aAAqB,QAAuC;AACnG,QAAM,YAAYA,MAAK,KAAK,aAAa,WAAW;AACpD,QAAM,UAAU,UAAU,SAAS;AAEnC,QAAM,aAAa,cAAc,WAAW;AAC5C,QAAM,UAAU,KAAK,UAAU,QAAQ,MAAM,CAAC;AAC9C,QAAM,UAAU,MAAM,YAAY,OAAO;AAC3C;AAmBA,eAAsB,gBAAgB,YAAqC;AACzE,MAAI;AAEF,UAAM,EAAE,OAAO,IAAI,MAAMD,OAAM,OAAO,CAAC,aAAa,YAAY,MAAM,GAAG;AAAA,MACvE,OAAO;AAAA,IACT,CAAC;AAED,UAAM,SAAS,OAAO,MAAM,GAAI,EAAE,CAAC;AACnC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO,MAAM,gBAAM,UAAU,sCAAkB,KAAK,EAAE;AACtD,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,aAAa,YAAqC;AACtE,MAAI;AAEF,UAAM,EAAE,OAAO,IAAI,MAAMA;AAAA,MACvB;AAAA,MACA,CAAC,aAAa,UAAU,UAAU;AAAA,MAClC;AAAA,QACE,OAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,OAAO,OACV,MAAM,IAAI,EACV,OAAO,CAAC,SAAS,KAAK,SAAS,YAAY,KAAK,CAAC,KAAK,SAAS,KAAK,CAAC,EACrE,IAAI,CAAC,SAAS;AACb,YAAM,CAAC,EAAE,GAAG,IAAI,KAAK,MAAM,GAAI;AAC/B,aAAO,IAAI,QAAQ,cAAc,EAAE;AAAA,IACrC,CAAC,EACA,OAAO,CAAC,QAAQ,mBAAmB,KAAK,GAAG,CAAC,EAC5C,KAAK,CAAC,GAAG,MAAM;AAEd,YAAM,KAAK,EAAE,QAAQ,MAAM,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AACpD,YAAM,KAAK,EAAE,QAAQ,MAAM,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AACpD,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAK,GAAG,CAAC,KAAK,MAAM,GAAG,CAAC,KAAK,GAAI,QAAO;AACxC,aAAK,GAAG,CAAC,KAAK,MAAM,GAAG,CAAC,KAAK,GAAI,QAAO;AAAA,MAC1C;AACA,aAAO;AAAA,IACT,CAAC;AAEH,WAAO,KAAK,KAAK,SAAS,CAAC,KAAK;AAAA,EAClC,SAAS,OAAO;AACd,WAAO,MAAM,gBAAM,UAAU,mCAAe,KAAK,EAAE;AACnD,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,oBACpB,aACA,MAC8B;AAC9B,QAAM,SAAS,MAAM,mBAAmB,WAAW;AAEnD,MAAI,CAAC,UAAU,CAAC,OAAO,IAAI,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,OAAO,IAAI,EAAE;AAChC,QAAM,gBAAgB,OAAO,IAAI,EAAE;AACnC,QAAM,aAAa,OAAO,IAAI,EAAE;AAGhC,QAAM,eAAe,MAAM,gBAAgB,UAAU;AACrD,QAAM,YAAY,MAAM,aAAa,UAAU;AAE/C,MAAI,CAAC,cAAc;AACjB,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,iBAAiB,kBAAkB;AAEvD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,eAAe;AAAA,EAC9B;AACF;AAKA,eAAsB,sBACpB,aACA,MACA,QACA,SAIe;AACf,QAAM,SAAS,MAAM,mBAAmB,WAAW;AAEnD,MAAI,CAAC,QAAQ;AACX;AAAA,EACF;AAEA,SAAO,IAAI,EAAE,SAAS;AACtB,MAAI,SAAS,KAAK;AAChB,WAAO,IAAI,EAAE,MAAM,QAAQ;AAAA,EAC7B;AACA,MAAI,SAAS,QAAQ;AACnB,WAAO,IAAI,EAAE,SAAS,QAAQ;AAAA,EAChC;AACA,SAAO,IAAI,EAAE,cAAa,oBAAI,KAAK,GAAE,YAAY;AAEjD,QAAM,mBAAmB,aAAa,MAAM;AAC9C;AAKO,SAAS,sBAAsC;AAEpD,SAAO;AAAA,IACL,UAAU,EAAE,GAAG,kBAAkB,SAAS;AAAA,IAC1C,SAAS,EAAE,GAAG,kBAAkB,QAAQ;AAAA,EAC1C;AACF;AA7PA,IAwDM;AAxDN;AAAA;AAAA;AAAA;AAEA;AACA;AAqDA,IAAM,oBAAoC;AAAA,MACxC,UAAU;AAAA,QACR,YAAY;AAAA,MACd;AAAA,MACA,SAAS;AAAA,QACP,YAAY;AAAA,MACd;AAAA,IACF;AAAA;AAAA;;;AC/DA,OAAOE,WAAU;AAAjB,IAea;AAfb;AAAA;AAAA;AAAA;AACA;AAcO,IAAM,gBAAN,MAAoB;AAAA,MACzB,OAAwB,UAA0B;AAAA;AAAA,QAEhD;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,MAAM;AAAA,UACN,OAAO,CAAC,mBAAmB;AAAA,UAC3B,kBAAkB;AAAA;AAAA,YAEhB;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA;AAAA,YAEA;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA;AAAA,YAEA;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA;AAAA,YAEA;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA;AAAA,YAEA;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,UACF;AAAA,UACA,cAAc,CAAC,wBAAwB;AAAA,QACzC;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,MAAM;AAAA,UACN,OAAO,CAAC,4BAA4B;AAAA,UACpC,kBAAkB;AAAA,YAChB;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,UACF;AAAA,UACA,cAAc,CAAC,wBAAwB;AAAA,QACzC;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,MAAM;AAAA,UACN,OAAO,CAAC,oBAAoB;AAAA,UAC5B,UAAU,CAAC,oBAAoB;AAAA,UAC/B,kBAAkB;AAAA,YAChB;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,UACF;AAAA,UACA,cAAc,CAAC,0BAA0B,mBAAmB;AAAA,QAC9D;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,MAAM;AAAA,UACN,OAAO,CAAC,wBAAwB;AAAA,UAChC,kBAAkB;AAAA,YAChB;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,UACF;AAAA,UACA,cAAc,CAAC,4BAA4B;AAAA,QAC7C;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,MAAM;AAAA,UACN,OAAO,CAAC,qBAAqB;AAAA,UAC7B,kBAAkB;AAAA,YAChB;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,MAAM;AAAA,UACN,OAAO,CAAC,uBAAuB;AAAA,UAC/B,kBAAkB;AAAA,YAChB;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,MAAM;AAAA,UACN,OAAO,CAAC,oBAAoB;AAAA,UAC5B,UAAU,CAAC,oBAAoB;AAAA,UAC/B,kBAAkB;AAAA,YAChB;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,UACF;AAAA,QACF;AAAA;AAAA,QAEA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,MAAM;AAAA,UACN,OAAO,CAAC,aAAa;AAAA,UACrB,kBAAkB;AAAA,YAChB;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,MAAM;AAAA,UACN,WAAW;AAAA,UACX,OAAO,CAAC,2BAA2B;AAAA,QACrC;AAAA,QACA;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,MAAM;AAAA,UACN,OAAO,CAAC,mBAAmB;AAAA,QAC7B;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,sBAAsC;AAC3C,eAAO,CAAC,GAAG,KAAK,OAAO;AAAA,MACzB;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,cAAc,IAAsC;AACzD,eAAO,KAAK,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,MAC7C;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,aACX,aACA,UACA,cACmB;AACnB,cAAM,SAAS,KAAK,cAAc,QAAQ;AAC1C,YAAI,CAAC,OAAQ,QAAO,CAAC;AAErB,cAAM,aAAuB,CAAC;AAG9B,mBAAW,eAAe,OAAO,OAAO;AACtC,gBAAM,aAAaA,MAAK,KAAK,cAAc,WAAW,WAAW;AACjE,gBAAM,aAAaA,MAAK,KAAK,aAAa,cAAcA,MAAK,SAAS,WAAW,CAAC;AAGlF,cAAI,MAAM,UAAU,OAAO,UAAU,GAAG;AACtC,kBAAM,UAAU,KAAK,YAAY,UAAU;AAC3C,uBAAW,KAAKA,MAAK,SAAS,aAAa,UAAU,CAAC;AAAA,UACxD,WAAW,OAAO,SAAS,UAAU;AACnC,kBAAM,KAAK,8BAA8B,YAAY,MAAM;AAC3D,uBAAW,KAAKA,MAAK,SAAS,aAAa,UAAU,CAAC;AAAA,UACxD,OAAO;AAEL,kBAAM,KAAK,6BAA6B,YAAY,MAAM;AAC1D,uBAAW,KAAKA,MAAK,SAAS,aAAa,UAAU,CAAC;AAAA,UACxD;AAAA,QACF;AAGA,YAAI,OAAO,kBAAkB;AAC3B,gBAAM,iBAAiBA,MAAK,KAAK,aAAa,uBAAuB;AAGrE,gBAAM,eAAe,MAAM,UAAU,OAAOA,MAAK,KAAK,cAAc,SAAS,CAAC;AAE9E,qBAAW,YAAY,OAAO,kBAAkB;AAC9C,gBAAI,aAA4B;AAChC,gBAAI;AACJ,gBAAI;AAEJ,gBAAI,cAAc;AAEhB,2BAAaA,MAAK,KAAK,cAAc,WAAW,SAAS,MAAM;AAC/D,kBAAI,MAAM,UAAU,OAAO,UAAU,GAAG;AACtC,0BAAU,MAAM,UAAU,KAAK,UAAU;AAAA,cAC3C;AAAA,YACF;AAGA,gBAAI,CAAC,SAAS;AACZ,wBAAU,KAAK,wBAAwB,QAAQ,QAAQ;AAAA,YACzD;AAGA,gBAAI,SAAS,OAAO,WAAW,SAAS,GAAG;AAEzC,oBAAM,eAAe,SAAS,OAAO,QAAQ,aAAa,mBAAmB;AAC7E,2BAAaA,MAAK,KAAK,gBAAgB,YAAY;AAAA,YACrD,WAAW,SAAS,OAAO,WAAW,SAAS,GAAG;AAEhD,oBAAM,aAAa,KAAK,eAAe,WAAW;AAClD,kBAAI,YAAY;AACd,sBAAM,eAAe,SAAS,OAAO,QAAQ,aAAa,GAAG,UAAU,UAAU;AACjF,6BAAaA,MAAK,KAAK,gBAAgB,YAAY;AAAA,cACrD,OAAO;AACL,6BAAaA,MAAK,KAAK,gBAAgB,SAAS,MAAM;AAAA,cACxD;AAAA,YACF,OAAO;AACL,2BAAaA,MAAK,KAAK,gBAAgB,SAAS,MAAM;AAAA,YACxD;AAEA,kBAAM,UAAU,UAAUA,MAAK,QAAQ,UAAU,CAAC;AAClD,kBAAM,UAAU,MAAM,YAAY,OAAO;AACzC,uBAAW,KAAKA,MAAK,SAAS,aAAa,UAAU,CAAC;AAAA,UACxD;AAAA,QACF;AAGA,YAAI,OAAO,mBAAmB;AAC5B,gBAAM,iBAAiBA,MAAK,KAAK,aAAa,cAAc;AAE5D,qBAAW,YAAY,OAAO,mBAAmB;AAC/C,kBAAM,aAAaA,MAAK,KAAK,cAAc,WAAW,SAAS,MAAM;AACrE,kBAAM,aAAaA,MAAK,KAAK,gBAAgB,SAAS,MAAM;AAE5D,gBAAI,MAAM,UAAU,OAAO,UAAU,GAAG;AACtC,oBAAM,UAAU,KAAK,YAAY,UAAU;AAC3C,yBAAW,KAAKA,MAAK,SAAS,aAAa,UAAU,CAAC;AAAA,YACxD;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,OAAe,eAAe,aAAoC;AAChE,cAAM,eAAeA,MAAK,KAAK,aAAa,yBAAyB;AACrE,cAAM,UAAU,UAAU,SAAS,YAAY;AAC/C,cAAM,UAAU,QAAQ,MAAM,sBAAsB;AACpD,YAAI,SAAS;AACX,qBAAW,SAAS,SAAS;AAC3B,kBAAM,aAAa,MAAM,QAAQ,eAAe,EAAE,EAAE,QAAQ,KAAK,EAAE;AACnE,gBAAI,eAAe,UAAU;AAC3B,qBAAO;AAAA,YACT;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,OAAe,wBAAwB,QAAsB,UAAsC;AACjG,cAAM,gBAAgBA,MAAK,QAAQ,SAAS,MAAM,EAAE,QAAQ,OAAO,GAAG;AACtE,cAAM,YAAYA,MAAK,SAAS,SAAS,QAAQ,OAAO;AACxD,cAAM,aAAa,OAAO;AAC1B,cAAM,WAAW,OAAO;AAExB,eAAO,WAAW,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA,KAK9B,UAAU;AAAA;AAAA;AAAA,sBAGH,QAAQ;AAAA;AAAA;AAAA;AAAA,sCAIG,QAAQ;AAAA;AAAA;AAAA,eAGhB,SAAS;AAAA;AAAA;AAAA,4BAGN,UAAU;AAAA;AAAA;AAAA,oBAGR,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,MAK3B;AAAA;AAAA;AAAA;AAAA,MAKA,aAAqB,6BAA6B,YAAoB,QAAqC;AACzG,cAAM,UAAU,KAAK,OAAO,IAAI;AAAA;AAAA;AAAA,EAGlC,OAAO,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAalB,OAAO,eAAe,OAAO,aAAa,IAAI,OAAK,mBAAmB,CAAC,GAAG,EAAE,KAAK,IAAI,IAAI,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQzF,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBASG,OAAO,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAQX,OAAO,EAAE;AAAA;AAAA;AAAA;AAAA,EAIvB,OAAO,WAAW,mCAAU,OAAO,SAAS,KAAK,IAAI,CAAC,KAAK,gCAAO;AAAA;AAEhE,cAAM,UAAU,MAAM,YAAY,OAAO;AAAA,MAC3C;AAAA;AAAA;AAAA;AAAA,MAKA,aAAqB,8BAA8B,YAAoB,QAAqC;AAC1G,cAAM,UAAU,KAAK,OAAO,IAAI;AAAA;AAAA;AAAA,gEAGjB,OAAO,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAO/B,cAAM,UAAU,MAAM,YAAY,OAAO;AAAA,MAC3C;AAAA,IACF;AAAA;AAAA;;;AC7bA,SAAS,eAAe;AACxB,OAAO,cAAc;AACrB,OAAOC,WAAU;AACjB,OAAOC,SAAQ;AACf,OAAOC,SAAQ;AAIf,SAAS,aAAa;AAYtB,eAAe,qBAAqB,oBAAqD;AAEvF,MAAI,cAAc;AAClB,MAAI,CAAC,aAAa;AAChB,UAAM,aAAa,MAAM,SAAS,OAAO;AAAA,MACvC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,UAAU,CAAC,UAAkB;AAC3B,cAAI,CAAC,eAAe,KAAK,KAAK,GAAG;AAC/B,mBAAO;AAAA,UACT;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AACD,kBAAc,WAAW;AAAA,EAC3B;AAGA,QAAM,aAAa,MAAM,SAAS,OAAO;AAAA,IACvC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,MAAM,kCAAS,OAAO,SAAS;AAAA,QACjC,EAAE,MAAM,2CAAkB,OAAO,QAAQ;AAAA,MAC3C;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAGD,MAAI,kBAAkB;AACtB,MAAI,WAAW,gBAAgB,SAAS;AACtC,UAAM,aAAa,MAAM,SAAS,OAAO;AAAA,MACvC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,UAAU,CAAC,UAAkB;AAC3B,cAAI,CAAC,eAAe,KAAK,KAAK,GAAG;AAC/B,mBAAO;AAAA,UACT;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AACD,sBAAkB,WAAW;AAAA,EAC/B;AAGA,QAAM,cAAc,MAAM,SAAS,OAAO;AAAA,IACxC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,MACT,UAAU,CAAC,UAAkB;AAC3B,YAAI,CAAC,sCAAsC,KAAK,KAAK,GAAG;AACtD,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF,CAAC;AACD,QAAM,UAAU,YAAY;AAG5B,QAAM,UAA0B,CAAC;AACjC,MAAI,iBAAiB;AACrB,MAAI,cAAc;AAElB,SAAO,gBAAgB;AAErB,QAAI,oBAAoB,UAAU,WAAW;AAC7C,QAAI,gBAAgB,GAAG;AACrB,UAAI,WAAW,gBAAgB,UAAU;AACvC,4BAAoB;AAAA,MACtB,OAAO;AACL,4BAAoB;AAAA,MACtB;AAAA,IACF;AAEA,UAAM,mBAAmB,MAAM,SAAS,OAAO;AAAA,MAC7C;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,4BAAQ,WAAW;AAAA,QAC5B,SAAS;AAAA,QACT,UAAU,CAAC,UAAkB;AAC3B,cAAI,CAAC,oBAAoB,KAAK,KAAK,GAAG;AACpC,mBAAO;AAAA,UACT;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAM,aAAa,iBAAiB;AAGpC,QAAI,aAAmC;AACvC,QAAI,WAAW,gBAAgB,SAAS;AACtC,YAAM,mBAAmB,MAAM,SAAS,OAAO;AAAA,QAC7C;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,iBAAO,UAAU;AAAA,UAC1B,SAAS;AAAA,YACP,EAAE,MAAM,2DAAmB,OAAO,UAAU;AAAA,YAC5C,EAAE,MAAM,yEAAkB,OAAO,SAAS;AAAA,YAC1C,EAAE,MAAM,iEAAoB,OAAO,MAAM;AAAA,UAC3C;AAAA,UACA,SAAS;AAAA,QACX;AAAA,MACF,CAAC;AACD,mBAAa,iBAAiB;AAAA,IAChC;AAGA,UAAM,gBAAgB,GAAG,OAAO,IAAI,UAAU;AAE9C,UAAM,mBAAmB,GAAG,aAAa,UAAU,CAAC;AAEpD,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,MAAM;AAAA,MACN,aAAa;AAAA,MACb;AAAA,IACF,CAAC;AAGD,QAAI,WAAW,gBAAgB,SAAS;AACtC,YAAM,aAAa,MAAM,SAAS,OAAO;AAAA,QACvC;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF,CAAC;AACD,uBAAiB,WAAW;AAAA,IAC9B,OAAO;AACL,uBAAiB;AAAA,IACnB;AAEA;AAAA,EACF;AAGA,QAAM,aAAa,MAAM,SAAS,OAAO;AAAA,IACvC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,MAAM,gBAAgB,OAAO,MAAM;AAAA,QACrC,EAAE,MAAM,iBAAiB,OAAO,KAAK;AAAA,QACrC,EAAE,MAAM,iBAAiB,OAAO,KAAK;AAAA,QACrC,EAAE,MAAM,iBAAiB,OAAO,KAAK;AAAA,MACvC;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAGD,QAAM,cAAc,MAAM,SAAS,OAAO;AAAA,IACxC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,MAAM,UAAU,OAAO,SAAS;AAAA,QAClC,EAAE,MAAM,SAAS,OAAO,QAAQ;AAAA,MAClC;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAGD,QAAM,iBAAiB,MAAM,SAAS,OAAO;AAAA,IAC3C;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,aAAa,WAAW;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,WAAW;AAAA,IACxB,WAAW,YAAY;AAAA,IACvB,iBAAiB,eAAe;AAAA,EAClC;AACF;AAKA,SAAS,aAAa,KAAqB;AACzC,SAAO,IACJ,MAAM,MAAM,EACZ,IAAI,UAAQ,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,EACtE,KAAK,EAAE;AACZ;AAkQA,eAAe,kBAAkB,aAAqB,QAAsC;AAC1F,QAAM,mBAAmB,OAAO,QAAQ,IAAI,OAAK;AAC/C,UAAM,cAAc,GAAG,OAAO,OAAO,IAAI,EAAE,IAAI;AAC/C,WAAO,sBAAO,EAAE,IAAI;AAAA,4CACA,YAAY,QAAQ,OAAO,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOrD,CAAC,EAAE,KAAK,IAAI;AAEZ,QAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+BAMP,OAAO,WAAW;AAAA,eACd,OAAO,OAAO;AAAA,+BAClB,OAAO,eAAe;AAAA,mBACxB,OAAO,QAAQ,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,wBACrC,OAAO,WAAW;AAAA,+BACrB,OAAO,cAAc,WAAW,WAAW,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAM7C,OAAO,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQhC,OAAO,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8FAWiB,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAuBnC,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBvB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhB,OAAO,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sEAMQ,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUnC,QAAM,UAAU,MAAMF,MAAK,KAAK,aAAa,eAAe,GAAG,OAAO;AACxE;AAKA,eAAe,oBAAoB,aAAqB,QAAsC;AAC5F,QAAM,UAAU;AAAA;AAAA;AAAA;AAAA,8EAIA,OAAO,OAAO;AAAA;AAAA;AAAA,EAG9B,OAAO,QAAQ,IAAI,OAAK,OAAO,EAAE,WAAW,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8S5D,QAAM,UAAU,MAAMA,MAAK,KAAK,aAAa,gBAAgB,GAAG,OAAO;AACzE;AAKA,eAAe,iBAAiB,aAAqB,aAAoC;AACvF,QAAM,UAAU;AAAA;AAAA;AAAA,kCAGJ,WAAW;AAAA,mCACX,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA;AAAA,mCAEtC,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAyChD,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUxC,QAAM,UAAU,MAAMA,MAAK,KAAK,aAAa,cAAc,GAAG,OAAO;AACvE;AAKA,eAAe,qBAAqB,aAAoC;AACtE,QAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8DhB,QAAM,UAAU,MAAMA,MAAK,KAAK,aAAa,wBAAwB,GAAG,OAAO;AACjF;AA4GA,eAAe,sBACb,aACA,iBAAoD,CAAC,GACtC;AACf,QAAM,eAAeA,MAAK,KAAK,aAAa,UAAU;AACtD,QAAM,YAAY,oBAAoB;AACtC,QAAM,aAAa,UAAU,SAAS;AAEtC,MAAI;AACF,UAAM,EAAE,OAAO,EAAE,IAAI,MAAM,OAAO,OAAO;AAGzC,QAAI,YAAY;AAChB,QAAI,CAAC,eAAe,OAAO,CAAC,eAAe,QAAQ;AACjD,kBAAY,MAAM,aAAa,UAAU;AAAA,IAC3C;AAEA,UAAM,gBAAgB,eAAe,UAAU,eAAe,OAAO;AAErE,WAAO,KAAK,qDAAa,iBAAiB,MAAM,MAAM;AAGtD,UAAM,UAAUA,MAAK,KAAKE,IAAG,OAAO,GAAG,eAAe,KAAK,IAAI,CAAC,EAAE;AAClE,UAAM,UAAU,UAAU,OAAO;AAEjC,UAAM,YAAY,CAAC,SAAS,WAAW,GAAG;AAC1C,QAAI,eAAe;AACjB,gBAAU,KAAK,YAAY,aAAa;AAAA,IAC1C;AACA,cAAU,KAAK,YAAY,OAAO;AAElC,UAAM,EAAE,OAAO,SAAS;AAGxB,UAAM,EAAE,QAAQ,OAAO,IAAI,MAAM,EAAE,OAAO,CAAC,aAAa,MAAM,GAAG,EAAE,KAAK,QAAQ,CAAC;AAGjF,UAAMD,IAAG,KAAK,SAAS,cAAc;AAAA,MACnC,QAAQ,CAAC,QAAQ,CAAC,IAAI,SAAS,MAAM;AAAA,IACvC,CAAC;AAGD,UAAMA,IAAG,OAAO,OAAO;AAGvB,UAAM,sBAAsB,aAAa,YAAY,OAAO,KAAK,GAAG;AAAA,MAClE,KAAK,eAAe,OAAO;AAAA,MAC3B,QAAQ,eAAe;AAAA,IACzB,CAAC;AAED,WAAO,QAAQ,kDAAU;AAAA,EAC3B,SAAS,OAAO;AACd,WAAO,KAAK,kGAAkB;AAC9B,UAAM,UAAU,UAAUD,MAAK,KAAK,cAAc,SAAS,CAAC;AAC5D,UAAM,UAAU,UAAUA,MAAK,KAAK,cAAc,gBAAgB,CAAC;AAAA,EACrE;AACF;AAKA,eAAe,wBACb,aACA,QACe;AACf,QAAM,cAAcA,MAAK,KAAK,aAAa,SAAS;AAEpD,SAAO,KAAK,uEAAgB;AAG5B,QAAM,UAAU,UAAU,WAAW;AAGrC,QAAM,qBAAqB,aAAa,MAAM;AAG9C,QAAM,sBAAsB,aAAa,MAAM;AAG/C,aAAW,UAAU,OAAO,SAAS;AACnC,UAAM,uBAAuB,aAAa,QAAQ,MAAM;AAAA,EAC1D;AAGA,MAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,UAAM,mBAAmB,aAAa,MAAM;AAAA,EAC9C;AAEA,SAAO,QAAQ,kDAAU;AAC3B;AAKA,eAAe,qBAAqB,aAAqB,QAAsC;AAC7F,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,uBAAuB,OAAO,eAAe,GAAG;AAC3D,QAAM,KAAK,EAAE;AAGb,QAAM,aAAa,CAAC,UAAU,GAAG,OAAO,QAAQ,IAAI,OAAK,EAAE,IAAI,CAAC,EAAE,KAAK;AACvE,aAAW,UAAU,YAAY;AAC/B,UAAM,KAAK,YAAY,MAAM,GAAG;AAAA,EAClC;AAEA,QAAM,UAAU,MAAMA,MAAK,KAAK,aAAa,iBAAiB,GAAG,MAAM,KAAK,IAAI,CAAC;AACjF,SAAO,KAAK,oCAAqB;AACnC;AAKA,eAAe,sBAAsB,aAAqB,QAAsC;AAC9F,QAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,eAKH,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6BAaA,OAAO,WAAW;AAAA,6BAClB,OAAO,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAY7C,QAAM,UAAU,MAAMA,MAAK,KAAK,aAAa,cAAc,GAAG,OAAO;AACrE,SAAO,KAAK,wCAAyB;AACvC;AAKA,eAAe,uBACb,aACA,QACA,QACe;AACf,QAAM,aAAaA,MAAK,KAAK,aAAa,OAAO,IAAI;AACrD,QAAM,cAAc,OAAO,YAAY,MAAM,GAAG;AAEhD,SAAO,KAAK,6BAAS,OAAO,IAAI,KAAK,OAAO,IAAI,MAAM;AAGtD,QAAM,WAAW;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,aAAW,OAAO,UAAU;AAC1B,UAAM,UAAU,UAAUA,MAAK,KAAK,YAAY,GAAG,CAAC;AAAA,EACtD;AAGA,MAAI,UAAoB,CAAC;AACzB,MAAI,OAAO,SAAS,WAAW;AAC7B,cAAU,CAAC,cAAc,WAAW,UAAU,UAAU,OAAO,QAAQ;AAAA,EACzE,WAAW,OAAO,SAAS,OAAO;AAChC,cAAU,CAAC,SAAS,YAAY,SAAS,WAAW;AAAA,EACtD,OAAO;AACL,cAAU,CAAC,QAAQ,UAAU,UAAU,SAAS;AAAA,EAClD;AAEA,MAAI,WAAWA,MAAK,KAAK,YAAY,OAAO,QAAQ,MAAM;AAC1D,aAAW,UAAU,SAAS;AAC5B,UAAM,UAAU,UAAUA,MAAK,KAAK,UAAU,GAAG,aAAa,MAAM,CAAC;AAAA,EACvE;AAGA,QAAM;AAAA,IACJA,MAAK,KAAK,UAAU,GAAG,aAAa,UAAU,GAAG,OAAO,gBAAgB,OAAO;AAAA,IAC/E,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAGA,QAAM,wBAAwB,YAAY,QAAQ,MAAM;AAExD,SAAO,QAAQ,gBAAM,OAAO,IAAI,2BAAO;AACzC;AAKA,eAAe,uBACb,UACA,aACA,WACe;AACf,QAAM,UAAU,WAAW,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAStB,WAAW;AAAA;AAAA,eAEd,SAAS;AAAA;AAAA;AAAA,6DAGqC,SAAS;AAAA,oBAClD,SAAS;AAAA;AAAA;AAAA;AAI3B,QAAM,UAAU,UAAUA,MAAK,QAAQ,QAAQ,CAAC;AAChD,QAAM,UAAU,MAAM,UAAU,OAAO;AACzC;AAKA,eAAe,wBACb,YACA,QACA,QACe;AACf,MAAI,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAMV,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA,6BAII,OAAO,WAAW;AAAA,6BAClB,OAAO,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQ7C,MAAI,eAAe;AACnB,MAAI,OAAO,SAAS,WAAW;AAC7B,mBAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYjB,WAAW,OAAO,SAAS,OAAO;AAChC,mBAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,OAAO;AACL,mBAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASjB;AAEA,QAAM,UAAU,MAAMA,MAAK,KAAK,YAAY,cAAc,GAAG,eAAe,YAAY;AAC1F;AAKA,eAAe,mBAAmB,aAAqB,QAAsC;AAC3F,QAAM,aAAaA,MAAK,KAAK,aAAa,QAAQ;AAClD,QAAM,cAAc,OAAO,QAAQ,MAAM,GAAG;AAC5C,QAAM,UAAU,CAAC,QAAQ,UAAU,UAAU,WAAW,YAAY,SAAS,WAAW;AAExF,SAAO,KAAK,iDAAmB;AAG/B,aAAW,OAAO,CAAC,iBAAiB,sBAAsB,eAAe,GAAG;AAC1E,UAAM,UAAU,UAAUA,MAAK,KAAK,YAAY,GAAG,CAAC;AAAA,EACtD;AAEA,MAAI,WAAWA,MAAK,KAAK,YAAY,OAAO,QAAQ,MAAM;AAC1D,aAAW,UAAU,SAAS;AAC5B,UAAM,UAAU,UAAUA,MAAK,KAAK,UAAU,GAAG,aAAa,MAAM,CAAC;AAAA,EACvE;AAGA,QAAM,wBAAwB,YAAY;AAAA,IACxC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,aAAa,GAAG,OAAO,OAAO;AAAA,IAC9B,kBAAkB;AAAA,EACpB,GAAG,MAAM;AAET,SAAO,QAAQ,0DAAkB;AACnC;AAKA,eAAe,oBAAoB,aAAqB,aAAoC;AAC1F,QAAM,cAAcA,MAAK,KAAK,aAAa,SAAS;AAEpD,MAAI,CAAE,MAAM,UAAU,OAAO,WAAW,GAAI;AAC1C,WAAO,KAAK,2FAA+B;AAC3C;AAAA,EACF;AAGA,QAAM,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAQnB,QAAM,WAAW;AAAA;AAAA;AAAA;AAAA,gBAIH,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBzB,QAAMC,IAAG,UAAUD,MAAK,KAAK,aAAa,YAAY,GAAG,UAAU;AACnE,QAAMC,IAAG,UAAUD,MAAK,KAAK,aAAa,WAAW,GAAG,QAAQ;AAChE,QAAMC,IAAG,MAAMD,MAAK,KAAK,aAAa,WAAW,GAAG,GAAK;AAC3D;AAKA,eAAe,QAAQ,aAAqB,aAAoC;AAC9E,MAAI;AACF,UAAM,EAAE,OAAO,EAAE,IAAI,MAAM,OAAO,OAAO;AAEzC,UAAM,EAAE,OAAO,CAAC,MAAM,GAAG,EAAE,KAAK,aAAa,OAAO,OAAO,CAAC;AAC5D,UAAM,EAAE,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE,KAAK,aAAa,OAAO,OAAO,CAAC;AAChE,UAAM;AAAA,MACJ;AAAA,MACA,CAAC,UAAU,MAAM,oBAAoB,WAAW,wBAAwB;AAAA,MACxE,EAAE,KAAK,aAAa,OAAO,OAAO;AAAA,IACpC;AAEA,WAAO,QAAQ,gDAAa;AAAA,EAC9B,SAAS,OAAY;AACnB,WAAO,KAAK,uCAAc,MAAM,OAAO,EAAE;AAAA,EAC3C;AACF;AA3hDA,IA+Qa;AA/Qb;AAAA;AAAA;AAAA;AAKA;AACA;AACA;AAEA;AAMA;AAgQO,IAAM,cAAc,IAAI,QAAQ,MAAM,EAC1C,SAAS,kBAAkB,0BAAM,EACjC,YAAY,sCAAQ,EACpB,OAAO,yBAAyB,4BAAQ,GAAG,EAC3C,OAAO,eAAe,wCAAe,EACrC,OAAO,YAAY,8BAAU,EAC7B,OAAO,eAAe,uEAAgB,EACtC,OAAO,uBAAuB,kDAAU,EACxC,OAAO,wBAAwB,kDAAU,EACzC,OAAO,6BAA6B,kDAAU,EAC9C,OAAO,8BAA8B,kDAAU,EAC/C,OAAO,OAAO,aAAa,YAAY;AACtC,UAAI;AAEF,cAAM,SAAS,MAAM,qBAAqB,WAAW;AAErD,eAAO,OAAO,uFAA2B;AACzC,eAAO,QAAQ;AACf,eAAO,KAAK,6BAAS,OAAO,gBAAgB,UAAU,mCAAU,gCAAO,EAAE;AACzE,eAAO,KAAK,aAAa,OAAO,OAAO,EAAE;AACzC,eAAO,KAAK,iBAAO,OAAO,QAAQ,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AAC/D,eAAO,KAAK,sBAAY,OAAO,WAAW,EAAE;AAC5C,eAAO,QAAQ;AAGf,cAAM,YAAY,MAAM,SAAS,eAAe;AAChD,YAAI,CAAC,WAAW;AACd,iBAAO,MAAM,qCAAiB;AAC9B,iBAAO,KAAK,yEAA0D;AACtE,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,cAAM,cAAcA,MAAK,QAAQ,QAAQ,KAAK,OAAO,WAAW;AAGhE,cAAM,mBAAmB,cAAc,oBAAoB;AAC3D,cAAM,EAAE,gBAAgB,IAAI,MAAM,SAAS,OAAO;AAAA,UAChD;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SAAS,iBAAiB,IAAI,CAAC,OAAO;AAAA,cACpC,MAAM,GAAG,EAAE,IAAI,MAAM,EAAE,WAAW;AAAA,cAClC,OAAO,EAAE;AAAA,YACX,EAAE;AAAA,UACJ;AAAA,QACF,CAAC;AAGD,YAAI,MAAM,UAAU,OAAO,WAAW,GAAG;AACvC,iBAAO,MAAM,mCAAU,WAAW,EAAE;AACpC,iBAAO,KAAK,kGAAkB;AAC9B,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,QAAQ,IAAI;AAAA,UAChB;AAAA,YACE;AAAA,cACE,OAAO;AAAA,cACP,MAAM,YAAY;AAChB,sBAAM,UAAU,UAAU,WAAW;AACrC,sBAAM,UAAU,UAAUA,MAAK,KAAK,aAAa,YAAY,CAAC;AAC9D,sBAAM,UAAU,UAAUA,MAAK,KAAK,aAAa,eAAe,CAAC;AACjE,sBAAM,UAAU,UAAUA,MAAK,KAAK,aAAa,UAAU,CAAC;AAC5D,sBAAM,UAAU,UAAUA,MAAK,KAAK,aAAa,eAAe,CAAC;AAAA,cACnE;AAAA,YACF;AAAA,YACA;AAAA,cACE,OAAO;AAAA,cACP,MAAM,YAAY;AAChB,sBAAM,kBAAkB,aAAa,MAAM;AAC3C,sBAAM,oBAAoB,aAAa,MAAM;AAC7C,sBAAM,iBAAiB,aAAa,OAAO,WAAW;AACtD,sBAAM,qBAAqB,WAAW;AAAA,cACxC;AAAA,YACF;AAAA,YACA;AAAA,cACE,OAAO;AAAA,cACP,MAAM,YAAY;AAChB,sBAAM,wBAAwB,aAAa,MAAM;AAAA,cACnD;AAAA,YACF;AAAA,YACA,GAAI,OAAO,kBACP;AAAA,cACE;AAAA,gBACE,OAAO;AAAA,gBACP,MAAM,YAAY;AAChB,wBAAM,cAAc,QAAQ,eAAe,QAAQ;AACnD,wBAAM,iBAAiB,QAAQ;AAC/B,wBAAM,sBAAsB,aAAa;AAAA,oBACvC,KAAK;AAAA,oBACL,QAAQ;AAAA,kBACV,CAAC;AAAA,gBACH;AAAA,cACF;AAAA,YACF,IACA,CAAC;AAAA,YACL;AAAA,cACE,OAAO;AAAA,cACP,MAAM,OAAO,QAAa;AACxB,oBAAI,gBAAgB,WAAW,EAAG;AAClC,sBAAM,eAAeA,MAAK,QAAQ,UAAU,WAAW,YAAY,GAAG,GAAG,cAAc;AACvF,oBAAI,aAAa,CAAC;AAClB,2BAAW,YAAY,iBAAiB;AACtC,wBAAM,QAAQ,MAAM,cAAc,aAAa,aAAa,UAAU,YAAY;AAClF,sBAAI,WAAW,KAAK,GAAG,KAAK;AAAA,gBAC9B;AAAA,cACF;AAAA,YACF;AAAA,YACA,GAAI,QAAQ,SACR;AAAA,cACE;AAAA,gBACE,OAAO;AAAA,gBACP,MAAM,YAAY;AAChB,wBAAM,oBAAoB,aAAa,OAAO,WAAW;AAAA,gBAC3D;AAAA,cACF;AAAA,YACF,IACA,CAAC;AAAA,UACP;AAAA,UACA,EAAE,YAAY,OAAO,aAAa,KAAK;AAAA,QACzC;AAEA,cAAM,cAAc,MAAM,MAAM,IAAI;AAGpC,cAAM,gBAAgB,gBACnB,IAAI,CAAC,OAAe,cAAc,cAAc,EAAE,CAAC,EACnD,OAAO,CAAC,MAAW,GAAG,SAAS,QAAQ;AAE1C,YAAI,cAAc,SAAS,GAAG;AAC5B,iBAAO,QAAQ;AACf,iBAAO,OAAO,sCAAQ;AAEtB,gBAAM,EAAE,OAAO,EAAE,IAAI,MAAM,OAAO,OAAO;AAGzC,cAAI;AACF,mBAAO,KAAK,uEAA+B;AAC3C,kBAAM,EAAE,UAAU;AAAA,cAChB;AAAA,cAAO;AAAA,cACP;AAAA,cAAe;AAAA,cACf;AAAA,cAAY;AAAA,cACZ;AAAA,cACA;AAAA,cAAgB;AAAA,YAClB,CAAC;AACD,mBAAO,QAAQ,uDAAe;AAAA,UAChC,SAAS,KAAK;AACZ,mBAAO,KAAK,qHAA2B;AAAA,UACzC;AAGA,qBAAW,UAAU,eAAe;AAClC,gBAAI,CAAC,OAAQ;AACb,mBAAO,QAAQ;AACf,mBAAO,KAAK,yCAAW,OAAO,IAAI,iDAAc;AAEhD,kBAAM,SAAS,6EAAgC,OAAO,GAAG,QAAQ,WAAW,EAAE,CAAC;AAAA,+CAC7E,WAAW;AAAA;AAAA;AAIb,gBAAI;AAEF,oBAAM,EAAE,UAAU;AAAA,gBAChB;AAAA,gBAAM;AAAA,gBACN;AAAA,gBAAa;AAAA,gBACb;AAAA,gBACA;AAAA,gBAAmB;AAAA,cACrB,GAAG;AAAA,gBACD,OAAO;AAAA,gBACP,SAAS;AAAA,gBACT,KAAK,EAAE,GAAG,QAAQ,KAAK,aAAa,IAAI;AAAA;AAAA,cAC1C,CAAC;AACD,qBAAO,QAAQ,IAAI,OAAO,IAAI,wCAAU;AAAA,YAC1C,SAAS,KAAK;AACZ,qBAAO,MAAM,IAAI,OAAO,IAAI,wFAAkB;AAAA,YAChD;AAAA,UACF;AAAA,QACF;AAGA,YAAI,CAAC,QAAQ,OAAO;AAClB,iBAAO,QAAQ;AACf,gBAAM,QAAQ,aAAa,WAAW;AAAA,QACxC;AAEA,eAAO,QAAQ;AACf,eAAO,QAAQ,gBAAM,WAAW,uCAAS;AACzC,eAAO,QAAQ;AAGf,cAAM,aAAuB,aAAa,cAAc,CAAC;AACzD,YAAI,WAAW,SAAS,GAAG;AACzB,iBAAO,QAAQ;AACf,iBAAO,OAAO,kDAAU;AACxB,qBAAW,QAAQ,YAAY;AAC7B,mBAAO,KAAK,IAAI;AAAA,UAClB;AAAA,QACF;AAEA,eAAO,QAAQ;AACf,eAAO,KAAK,qBAAM;AAClB,eAAO,KAAK,MAAM,WAAW,EAAE;AAC/B,eAAO,KAAK,qCAAqC;AACjD,eAAO,KAAK,sCAAsC;AAClD,eAAO,KAAK,cAAc;AAC1B,eAAO,QAAQ;AAAA,MACjB,SAAS,OAAY;AACnB,eAAO,MAAM,mCAAU,MAAM,OAAO,EAAE;AACtC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;ACveH,SAAS,WAAAG,gBAAe;AACxB,OAAOC,eAAc;AACrB,OAAOC,WAAU;AAIjB,SAAS,SAAAC,cAAa;AAoJtB,SAAS,gBAAgB,UAAkB,YAA4B;AACrE,QAAM,kBAAkB;AACxB,QAAM,QAAQ,SAAS,MAAM,IAAI;AACjC,QAAM,cAAc,MAAM,UAAU,OAAK,EAAE,KAAK,EAAE,WAAW,eAAe,CAAC;AAG7E,MAAI,oBAAoB,WAAW,KAAK;AACxC,MAAI,CAAC,kBAAkB,WAAW,KAAK,GAAG;AAExC,UAAM,mBAAmB,kBAAkB,QAAQ,KAAK;AACxD,QAAI,qBAAqB,IAAI;AAC3B,0BAAoB,kBAAkB,UAAU,gBAAgB;AAAA,IAClE,OAAO;AAEL,0BAAoB,GAAG,eAAe;AAAA;AAAA,EAAO,iBAAiB;AAAA,IAChE;AAAA,EACF;AAEA,MAAI,gBAAgB,IAAI;AAEtB,UAAM,aAAa,MAAM,MAAM,GAAG,WAAW,EAAE,KAAK,IAAI;AACxD,UAAM,YAAY,MAAM,MAAM,cAAc,CAAC;AAG7C,UAAM,kBAAkB,UAAU,UAAU,OAAK,EAAE,KAAK,EAAE,WAAW,KAAK,CAAC;AAE3E,QAAI,oBAAoB,IAAI;AAC1B,YAAM,YAAY,UAAU,MAAM,eAAe,EAAE,KAAK,IAAI;AAC5D,aAAO,GAAG,WAAW,KAAK,CAAC;AAAA;AAAA,EAAO,iBAAiB;AAAA;AAAA,EAAO,UAAU,KAAK,CAAC;AAAA,IAC5E,OAAO;AAEL,aAAO,GAAG,WAAW,KAAK,CAAC;AAAA;AAAA,EAAO,iBAAiB;AAAA,IACrD;AAAA,EACF;AAGA,QAAM,mBAAmB;AACzB,QAAM,YAAY,MAAM,UAAU,OAAK,EAAE,KAAK,EAAE,WAAW,gBAAgB,CAAC;AAC5E,MAAI,cAAc,IAAI;AAEpB,UAAM,YAAY,MAAM,MAAM,YAAY,CAAC;AAC3C,UAAM,kBAAkB,UAAU,UAAU,OAAK,EAAE,KAAK,EAAE,WAAW,KAAK,CAAC;AAE3E,QAAI,oBAAoB,IAAI;AAC1B,YAAM,aAAa,YAAY,IAAI;AACnC,YAAM,SAAS,MAAM,MAAM,GAAG,UAAU,EAAE,KAAK,IAAI;AACnD,YAAM,QAAQ,MAAM,MAAM,UAAU,EAAE,KAAK,IAAI;AAC/C,aAAO,GAAG,OAAO,KAAK,CAAC;AAAA;AAAA,EAAO,iBAAiB;AAAA;AAAA,EAAO,MAAM,KAAK,CAAC;AAAA,IACpE;AAAA,EACF;AAGA,SAAO,GAAG,SAAS,KAAK,CAAC;AAAA;AAAA,EAAO,iBAAiB;AACnD;AAKA,SAAS,qBAAqB,aAA6B;AACzD,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYP,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+Cb;AAhRA,IAWa;AAXb;AAAA;AAAA;AAAA;AAGA;AACA;AACA;AAMO,IAAM,mBAAmB,IAAIH,SAAQ,WAAW,EACpD,SAAS,eAAe,+BAAW,EACnC,YAAY,wDAA+B,EAC3C,OAAO,OAAO,aAAa;AAC1B,UAAI;AACF,eAAO,OAAO,mBAAS;AACvB,eAAO,QAAQ;AAGf,cAAM,eAAe,MAAM,UAAU,OAAO,eAAe;AAC3D,YAAI,CAAC,cAAc;AACjB,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,yFAA6B;AACzC,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,YAAY,MAAM,SAAS,eAAe;AAChD,YAAI,CAAC,WAAW;AACd,iBAAO,MAAM,qCAAiB;AAC9B,iBAAO,KAAK,yEAA0D;AACtE,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,QAAQ,IAAIG,OAAM;AAAA,UACtB;AAAA,YACE,OAAO;AAAA,YACP,MAAM,OAAO,QAAQ;AACnB,oBAAM,UAAU;AAChB,oBAAM,SAAS,MAAM,UAAU,OAAO,OAAO;AAC7C,kBAAI,CAAC,QAAQ;AACX,sBAAM,IAAI,MAAM,yCAAgB,OAAO,EAAE;AAAA,cAC3C;AAEA,oBAAM,QAAQ,MAAM,UAAU,UAAU,QAAQ,OAAO;AACvD,kBAAI,QAAQ,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,UAAU,CAAC;AAAA,YACzD;AAAA,UACF;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM,OAAO,QAAQ;AACnB,kBAAI,CAAC,IAAI,SAAS,IAAI,MAAM,WAAW,GAAG;AACxC,sBAAM,IAAI,MAAM,sCAAa;AAAA,cAC/B;AAGA,kBAAI,CAAC,UAAU;AACb,sBAAM,EAAE,aAAa,IAAI,MAAMF,UAAS,OAAO;AAAA,kBAC7C;AAAA,oBACE,MAAM;AAAA,oBACN,MAAM;AAAA,oBACN,SAAS;AAAA,oBACT,SAAS,IAAI;AAAA,kBACf;AAAA,gBACF,CAAC;AACD,oBAAI,eAAeC,MAAK,KAAK,cAAc,YAAY;AACvD;AAAA,cACF;AAGA,oBAAM,WAAW,SAAS,WAAW,aAAa,IAC9C,WACAA,MAAK,KAAK,cAAc,QAAQ;AAEpC,oBAAM,SAAS,MAAM,UAAU,OAAO,QAAQ;AAC9C,kBAAI,CAAC,QAAQ;AACX,sBAAM,IAAI,MAAM,wCAAe,QAAQ,EAAE;AAAA,cAC3C;AAEA,kBAAI,eAAe;AAAA,YACrB;AAAA,UACF;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM,OAAO,QAAQ;AACnB,kBAAI,cAAc,MAAM,UAAU,KAAK,IAAI,YAAY;AACvD,qBAAO,QAAQ,uBAAQ,IAAI,YAAY,EAAE;AAAA,YAC3C;AAAA,UACF;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM,OAAO,QAAQ;AACnB,oBAAM,SAAS,qBAAqB,IAAI,WAAW;AAEnD,qBAAO,QAAQ;AACf,qBAAO,UAAU,UAAK,EAAE;AACxB,qBAAO,KAAK,8BAAe;AAC3B,qBAAO,UAAU,UAAK,EAAE;AACxB,qBAAO,QAAQ;AAGf,oBAAM,SAAS,MAAM,SAAS,OAAO,QAAQ;AAAA,gBAC3C,cAAc,CAAC,iBAAiB,gBAAgB;AAAA,cAClD,CAAC;AAED,qBAAO,QAAQ;AACf,qBAAO,UAAU,UAAK,EAAE;AACxB,qBAAO,QAAQ;AAEf,kBAAI,kBAAkB;AAAA,YACxB;AAAA,UACF;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM,OAAO,QAAQ;AAEnB,oBAAM,gBAAgB,gBAAgB,IAAI,aAAa,IAAI,eAAe;AAC1E,oBAAM,UAAU,MAAM,IAAI,cAAc,aAAa;AAAA,YACvD;AAAA,UACF;AAAA,QACF,CAAC;AAED,YAAI;AACF,gBAAM,MAAM,MAAM,MAAM,IAAI;AAE5B,iBAAO,QAAQ;AACf,iBAAO,OAAO,gCAAY;AAC1B,iBAAO,QAAQ,wCAAoB,IAAI,YAAY,EAAE;AACrD,iBAAO,QAAQ;AAEf,iBAAO,KAAK,qBAAM;AAClB,iBAAO,KAAK,mFAAkB;AAC9B,iBAAO,KAAK,gFAAwC;AACpD,iBAAO,QAAQ;AAAA,QACjB,SAAS,OAAY;AACnB,cAAI,MAAM,SAAS;AACjB,mBAAO,MAAM,MAAM,OAAO;AAAA,UAC5B;AACA,gBAAM;AAAA,QACR;AAAA,MACF,SAAS,OAAY;AACnB,eAAO,MAAM,6BAAS,MAAM,OAAO,EAAE;AACrC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;ACrJH,SAAS,WAAAE,gBAAe;AACxB,OAAOC,eAAc;AACrB,OAAOC,WAAU;AAgEjB,eAAe,aAA8B;AAC3C,SAAO,KAAK,qDAAuB;AACnC,SAAO,QAAQ;AAEf,QAAM,UAAU;AAChB,QAAM,SAAS,MAAM,UAAU,OAAO,OAAO;AAC7C,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,2CAAkB;AAAA,EACpC;AAEA,QAAM,QAAQ,MAAM,UAAU,UAAU,QAAQ,OAAO;AACvD,QAAM,YAAY,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,UAAU,CAAC;AAE7D,MAAI,UAAU,WAAW,GAAG;AAC1B,UAAM,IAAI,MAAM,sCAAa;AAAA,EAC/B;AAGA,QAAM,QAAoB,CAAC;AAC3B,WAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,UAAM,OAAOA,MAAK,KAAK,SAAS,UAAU,CAAC,CAAC;AAC5C,UAAM,OAAO,MAAM,UAAU,KAAK,IAAI;AAEtC,UAAM,SAAS,UAAU,gBAAgB,IAAI;AAC7C,UAAM,eAAe,kBAAkB,IAAI;AAE3C,UAAM,KAAK;AAAA,MACT;AAAA,MACA,MAAM,UAAU,CAAC;AAAA,MACjB;AAAA,MACA;AAAA,MACA,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAGA,QAAM,cAAc,gBAAgB,KAAK;AAGzC,SAAO,KAAK,uCAAc;AAC1B,SAAO,QAAQ;AAEf,QAAM,UAAU,YAAY,IAAI,CAAC,MAAM,QAAQ;AAC7C,UAAM,aAAa,cAAc,KAAK,MAAM;AAC5C,UAAM,gBAAgB,QAAQ,IAAI,4CAAc;AAChD,UAAM,UACJ,KAAK,aAAa,SAAS,IAAI,kBAAQ,KAAK,aAAa,KAAK,IAAI,CAAC,OAAO;AAE5E,WAAO;AAAA,MACL,MAAM,GAAG,UAAU,KAAK,KAAK,MAAM,KAAK,aAAa,GAAG,OAAO,GAAG,KAAK,IAAI;AAAA,MAC3E,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,IACd;AAAA,EACF,CAAC;AAED,SAAO,KAAK,sHAAsC;AAClD,SAAO,KAAK,oGAAoB;AAChC,SAAO,QAAQ;AAEf,QAAM,EAAE,aAAa,IAAI,MAAMD,UAAS,OAAO;AAAA,IAC7C;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,QAAQ,uBAAQ,YAAY,EAAE;AACrC,SAAO;AACT;AAKA,eAAe,gBAAgB,UAAmC;AAChE,SAAO,QAAQ;AACf,SAAO,KAAK,8CAA0B;AACtC,SAAO,QAAQ;AAEf,QAAM,cAAc,MAAM,UAAU,KAAK,QAAQ;AAGjD,QAAM,EAAE,UAAU,WAAW,IAAI,UAAU,oCAAoC,WAAW;AAE1F,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,KAAK,iDAAwB;AAEpC,UAAM,EAAE,aAAa,IAAI,MAAMA,UAAS,OAAO;AAAA,MAC7C;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AAED,QAAI,cAAc;AAEhB,aAAO,KAAK,uCAAmB;AAE/B,YAAM,IAAI,MAAM,kEAAqB;AAAA,IACvC,OAAO;AACL,aAAO,KAAK,iDAAc;AAC1B,aAAO;AAAA,IACT;AAAA,EACF;AAGA,QAAM,UAAU,SAAS,IAAI,CAAC,GAAG,QAAQ;AACvC,UAAM,SAAS,EAAE,mBAAmB,EAAE,cAAc,EAAE,aAAa;AACnE,UAAM,aAAa,SAAS,WAAM,EAAE,iBAAiB,IAAI,WAAM;AAC/D,UAAM,WAAW,IAAI,EAAE,cAAc,IAAI,EAAE,UAAU;AACrD,UAAM,QAAQ,SAAS,UAAK,EAAE,KAAK,KAAK,GAAG,UAAU,IAAI,QAAQ,IAAI,EAAE,KAAK;AAG5E,QAAI,aAAa,IAAI,EAAE,UAAU;AACjC,QAAI,YAAY;AACd,YAAM,SAAS,EAAE,cAAc,OAAO,OAAK,CAAC,EAAE,WAAW,EAAE;AAC3D,YAAM,SAAS,EAAE,aAAa,OAAO,OAAK,CAAC,EAAE,WAAW,EAAE;AAC1D,YAAM,SAAS,EAAE,iBAAiB,OAAO,OAAK,CAAC,EAAE,WAAW,EAAE;AAC9D,YAAM,UAAU,CAAC;AACjB,UAAI,SAAS,EAAG,SAAQ,KAAK,gBAAM,MAAM,EAAE;AAC3C,UAAI,SAAS,EAAG,SAAQ,KAAK,gBAAM,MAAM,EAAE;AAC3C,UAAI,SAAS,EAAG,SAAQ,KAAK,gBAAM,MAAM,EAAE;AAC3C,UAAI,QAAQ,SAAS,GAAG;AACtB,qBAAa,IAAI,QAAQ,KAAK,IAAI,CAAC;AAAA,MACrC;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM,GAAG,MAAM,CAAC,KAAK,KAAK,IAAI,UAAU;AAAA,MACxC,OAAO,EAAE;AAAA,MACT,OAAO,EAAE;AAAA,IACX;AAAA,EACF,CAAC;AAED,UAAQ,KAAK;AAAA,IACX,MAAM,GAAG,SAAS,SAAS,CAAC;AAAA,IAC5B,OAAO;AAAA,IACP,OAAO;AAAA,EACT,CAAC;AAED,QAAM,EAAE,UAAU,IAAI,MAAMA,UAAS,OAAO;AAAA,IAC1C;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAKA,eAAe,WACb,UACA,WACiB;AACjB,MAAI,cAAc,qBAAW;AAC3B,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ;AACf,SAAO,KAAK,qDAAuB;AACnC,SAAO,QAAQ;AAEf,QAAM,cAAc,MAAM,UAAU,KAAK,QAAQ;AAGjD,QAAM,EAAE,UAAU,WAAW,IAAI,UAAU,oCAAoC,WAAW;AAC1F,QAAM,kBAAkB,SAAS,KAAK,OAAK,EAAE,UAAU,SAAS;AAGhE,MAAI,CAAC,mBAAmB,CAAC,YAAY;AACnC,WAAO,MAAM,iBAAiB,UAAU,SAAS;AAAA,EACnD;AAGA,SAAO,MAAM,mBAAmB,eAAe;AACjD;AAKA,eAAe,mBAAmB,WAAmD;AACnF,QAAM,UAAiB,CAAC;AAGxB,MAAI,UAAU,cAAc,SAAS,GAAG;AACtC,YAAQ,KAAK,EAAE,MAAM,0CAAY,UAAU,cAAc,MAAM,kBAAQ,UAAU,KAAK,CAAC;AACvF,cAAU,cAAc,QAAQ,CAACE,OAAM,QAAQ;AAC7C,YAAM,OAAOA,MAAK,cAAc,QAAQ;AACxC,cAAQ,KAAK;AAAA,QACX,MAAM,SAAS,IAAI,IAAIA,MAAK,OAAO;AAAA,QACnC,OAAOA,MAAK;AAAA,QACZ,OAAO,OAAOA,MAAK,OAAO;AAAA,MAC5B,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAGA,MAAI,UAAU,aAAa,SAAS,GAAG;AACrC,YAAQ,KAAK,EAAE,MAAM,0CAAY,UAAU,aAAa,MAAM,kBAAQ,UAAU,KAAK,CAAC;AACtF,cAAU,aAAa,QAAQ,CAACA,OAAM,QAAQ;AAC5C,YAAM,OAAOA,MAAK,cAAc,QAAQ;AACxC,YAAM,UAAUA,MAAK,iBAAiB,KAAKA,MAAK,cAAc,MAAM;AACpE,cAAQ,KAAK;AAAA,QACX,MAAM,SAAS,IAAI,IAAIA,MAAK,OAAO,GAAG,OAAO;AAAA,QAC7C,OAAOA,MAAK;AAAA,QACZ,OAAO,OAAOA,MAAK,OAAO;AAAA,MAC5B,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAGA,MAAI,UAAU,iBAAiB,SAAS,GAAG;AACzC,YAAQ,KAAK,EAAE,MAAM,0CAAY,UAAU,iBAAiB,MAAM,kBAAQ,UAAU,KAAK,CAAC;AAC1F,cAAU,iBAAiB,QAAQ,CAACA,OAAM,QAAQ;AAChD,YAAM,OAAOA,MAAK,cAAc,QAAQ;AACxC,YAAM,WAAWA,MAAK,eAAe,mBAASA,MAAK,aAAa,KAAK,IAAI,CAAC,MAAM;AAChF,cAAQ,KAAK;AAAA,QACX,MAAM,SAAS,IAAI,IAAIA,MAAK,OAAO,GAAG,QAAQ;AAAA,QAC9C,OAAOA,MAAK;AAAA,QACZ,OAAO,OAAOA,MAAK,OAAO;AAAA,MAC5B,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAGA,MAAI,UAAU,aAAa,SAAS,GAAG;AACrC,YAAQ,KAAK,EAAE,MAAM,0CAAY,UAAU,aAAa,MAAM,kBAAQ,UAAU,KAAK,CAAC;AACtF,cAAU,aAAa,QAAQ,CAACA,OAAM,QAAQ;AAC5C,YAAM,OAAOA,MAAK,cAAc,QAAQ;AACxC,cAAQ,KAAK;AAAA,QACX,MAAM,KAAK,IAAI,IAAIA,MAAK,OAAO;AAAA,QAC/B,OAAOA,MAAK;AAAA,QACZ,OAAOA,MAAK;AAAA,MACd,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,UAAQ,KAAK,EAAE,MAAM,0CAAY,UAAU,KAAK,CAAC;AACjD,UAAQ,KAAK;AAAA,IACX,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,EACT,CAAC;AAED,QAAM,EAAE,KAAK,IAAI,MAAMF,UAAS,OAAO;AAAA,IACrC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAKA,eAAe,iBACb,UACA,WACiB;AACjB,QAAM,cAAc,MAAM,UAAU,KAAK,QAAQ;AACjD,QAAM,aAAa,UAAU,gBAAgB,WAAW;AACxD,QAAM,kBAAkB,WAAW,KAAK,OAAK,EAAE,UAAU,SAAS;AAClE,QAAM,QAAQ,kBAAkB,gBAAgB,QAAQ,CAAC;AAEzD,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,KAAK,iDAAwB;AACpC,UAAM,EAAE,aAAa,IAAI,MAAMA,UAAS,OAAO;AAAA,MAC7C;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AAED,WAAO,eAAe,6BAAS;AAAA,EACjC;AAEA,QAAM,UAAU,MAAM,IAAI,CAACE,OAAM,SAAS;AAAA,IACxC,MAAM,GAAG,MAAM,CAAC,KAAKA,KAAI;AAAA,IACzB,OAAOA;AAAA,IACP,OAAOA;AAAA,EACT,EAAE;AAEF,UAAQ,KAAK;AAAA,IACX,MAAM,GAAG,MAAM,SAAS,CAAC;AAAA,IACzB,OAAO;AAAA,IACP,OAAO;AAAA,EACT,CAAC;AAED,QAAM,EAAE,KAAK,IAAI,MAAMF,UAAS,OAAO;AAAA,IACrC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAKA,eAAe,mBACb,UACA,WACA,MACe;AACf,SAAO,QAAQ;AACf,SAAO,KAAK,kDAAyB;AAErC,MAAI;AACJ,MAAI,cAAc,qBAAW;AAC3B,sBAAkB;AAAA,EACpB,WAAW,SAAS,8BAAU,SAAS,4BAAQ;AAC7C,sBAAkB,2BAAiB,SAAS;AAAA,EAC9C,OAAO;AACL,sBAAkB,2BAAiB,SAAS,yBAAU,IAAI;AAAA,EAC5D;AAEA,QAAM,SAAS,eAAe,UAAU,WAAW,MAAM,eAAe;AAExE,SAAO,QAAQ;AACf,SAAO,UAAU,UAAK,EAAE;AACxB,SAAO,KAAK,uCAAmB;AAC/B,SAAO,UAAU,UAAK,EAAE;AACxB,SAAO,QAAQ;AACf,SAAO,KAAK,+BAAW,eAAe,EAAE;AACxC,SAAO,KAAK,wBAAc,QAAQ,EAAE;AACpC,SAAO,QAAQ;AACf,SAAO,KAAK,+EAAsB;AAClC,SAAO,QAAQ;AACf,SAAO,KAAK,yCAAW;AACvB,SAAO,KAAK,gEAAwB;AACpC,SAAO,KAAK,uGAA4B;AACxC,SAAO,KAAK,0FAAwC;AACpD,SAAO,QAAQ;AAGf,QAAM,SAAS,YAAY,MAAM;AAEjC,SAAO,QAAQ;AACf,SAAO,UAAU,UAAK,EAAE;AACxB,SAAO,QAAQ;AAGf,QAAM,mBAAmB,UAAU,WAAW,MAAM,iBAAiB,kDAAU;AAG/E,QAAM,uBAAuB,UAAU,WAAW,IAAI;AAEtD,SAAO,OAAO,uCAAS;AACvB,SAAO,QAAQ,4CAAS;AACxB,SAAO,QAAQ;AACf,SAAO,KAAK,qBAAM;AAClB,SAAO,KAAK,+CAAY;AACxB,SAAO,KAAK,2EAA8B;AAC1C,SAAO,QAAQ;AACjB;AAKA,SAAS,kBAAkB,MAAwB;AACjD,QAAM,OAAiB,CAAC;AACxB,MAAI,gBAAgB;AAEpB,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,aAAW,QAAQ,OAAO;AAExB,QAAI,KAAK,SAAS,6BAAS,KAAK,KAAK,SAAS,iBAAO,GAAG;AACtD,sBAAgB;AAChB;AAAA,IACF;AAGA,QAAI,iBAAiB,KAAK,WAAW,KAAK,GAAG;AAC3C;AAAA,IACF;AAGA,UAAM,QAAQ,KAAK,MAAM,2BAA2B;AACpD,QAAI,iBAAiB,OAAO;AAC1B,YAAM,MAAM,MAAM,CAAC;AACnB,UAAI,QAAQ,YAAO,KAAK;AACtB,aAAK,KAAK,GAAG;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AACA,SAAS,gBAAgB,OAA+B;AACtD,QAAM,SAAqB,CAAC;AAC5B,QAAM,UAAU,oBAAI,IAAY;AAEhC,WAAS,MAAM,MAAgB;AAC7B,QAAI,QAAQ,IAAI,KAAK,KAAK,EAAG;AAC7B,YAAQ,IAAI,KAAK,KAAK;AAGtB,eAAW,WAAW,KAAK,cAAc;AACvC,YAAM,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO;AAChD,UAAI,KAAK;AACP,cAAM,GAAG;AAAA,MACX;AAAA,IACF;AAEA,WAAO,KAAK,IAAI;AAAA,EAClB;AAEA,aAAW,QAAQ,OAAO;AACxB,UAAM,IAAI;AAAA,EACZ;AAEA,SAAO;AACT;AAKA,SAAS,cAAc,QAAwB;AAC7C,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAOA,SAAS,eACP,UACA,WACA,MACA,iBACQ;AACR,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOD,eAAe;AAAA;AAAA,aAEV,QAAQ;AAAA,aACR,SAAS;AAAA,QACd,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBZ;AAKA,eAAe,mBACb,UACA,WACA,MACA,iBACA,QACe;AACf,QAAM,aAAa;AACnB,QAAM,UAAU,UAAU,UAAU;AAEpC,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,SAAS,GAAG;AAC/D,QAAM,WAAWC,MAAK,SAAS,UAAU,KAAK;AAC9C,QAAM,UAAUA,MAAK,KAAK,YAAY,GAAG,SAAS,IAAI,QAAQ,KAAK;AAEnE,QAAM,UAAU;AAAA;AAAA,qBAER,oBAAI,KAAK,GAAE,eAAe,OAAO,CAAC;AAAA,YAChC,QAAQ;AAAA,iBACH,SAAS;AAAA,YACd,IAAI;AAAA;AAAA;AAAA;AAAA,EAId,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA,EAKf,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcN,QAAM,UAAU,MAAM,SAAS,OAAO;AACxC;AAKA,eAAe,uBACb,UACA,WACA,MACe;AACf,MAAI;AACF,UAAM,EAAE,aAAa,IAAI,MAAMD,UAAS,OAAO;AAAA,MAC7C;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AAED,QAAI,CAAC,cAAc;AACjB,aAAO,KAAK,4CAAc;AAC1B;AAAA,IACF;AAGA,UAAM,UAAU,MAAM,UAAU,KAAK,QAAQ;AAC7C,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAGhC,QAAI,oBAAoB;AACxB,QAAI,kBAAkB;AACtB,QAAI,iBAAiB;AAErB,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,OAAO,MAAM,CAAC;AAGpB,UAAI,cAAc,uBAAa,KAAK,SAAS,SAAS,GAAG;AACvD,4BAAoB;AACpB,yBAAiB;AACjB;AAAA,MACF;AAGA,UAAI,mBAAmB;AAErB,YAAI,KAAK,MAAM,kBAAkB,GAAG;AAClC;AAAA,QACF;AAGA,YAAI,SAAS,8BAAU,SAAS,4BAAQ;AAEtC,gBAAM,YAAY,KAAK,MAAM,mCAAmC;AAChE,cAAI,WAAW;AACb,kBAAM,cAAc,UAAU,CAAC,EAAE,KAAK;AAEtC,kBAAM,eAAe,YAClB,QAAQ,4BAA4B,EAAE,EACtC,QAAQ,sBAAsB,EAAE,EAChC,KAAK;AAER,gBAAI,iBAAiB,MAAM;AACzB,gCAAkB;AAClB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,oBAAoB,IAAI;AAC1B,YAAM,OAAO,MAAM,eAAe;AAClC,YAAM,eAAe,IAAI,KAAK,QAAQ,cAAc,OAAO;AAC3D,aAAO,QAAQ,+CAAiB,IAAI,EAAE;AAAA,IACxC,WAAW,SAAS,8BAAU,SAAS,4BAAQ;AAE7C,UAAI,eAAe;AACnB,eAAS,IAAI,iBAAiB,GAAG,IAAI,MAAM,QAAQ,KAAK;AACtD,cAAM,OAAO,MAAM,CAAC;AAEpB,YAAI,KAAK,MAAM,kBAAkB,GAAG;AAClC;AAAA,QACF;AAEA,YAAI,KAAK,MAAM,YAAY,GAAG;AAC5B,gBAAM,CAAC,IAAI,KAAK,QAAQ,cAAc,OAAO;AAC7C;AAAA,QACF;AAAA,MACF;AACA,aAAO,QAAQ,sBAAO,YAAY,kCAAc;AAAA,IAClD,OAAO;AACL,aAAO,KAAK,kDAAe;AAC3B;AAAA,IACF;AAGA,UAAM,aAAa,MAAM,KAAK,IAAI;AAClC,UAAM,iBAAiB,UAAU,gBAAgB,UAAU;AAE3D,QAAI,aAAa;AAEjB,UAAM,kBAAkB,WAAW,UAAU,OAAK,EAAE,MAAM,UAAU,CAAC;AACrE,QAAI,oBAAoB,IAAI;AAC1B,YAAM,UAAU,WAAW,eAAe;AAC1C,YAAM,UAAU,QAAQ,QAAQ,iBAAiB,OAAO,cAAc,IAAI;AAC1E,UAAI,YAAY,SAAS;AACvB,mBAAW,eAAe,IAAI;AAC9B,eAAO,KAAK,iEAAoB,cAAc,EAAE;AAAA,MAClD;AAAA,IACF;AAGA,UAAM,UAAU,MAAM,UAAU,WAAW,KAAK,IAAI,CAAC;AACrD,WAAO,QAAQ,qCAAY;AAAA,EAC7B,SAAS,OAAO;AACd,WAAO,KAAK,+CAAiB,KAAK,EAAE;AAAA,EACtC;AACF;AAltBA,IAkBa;AAlBb;AAAA;AAAA;AAAA;AAGA;AACA;AACA;AAaO,IAAM,aAAa,IAAID,SAAQ,KAAK,EACxC,YAAY,oEAAa,EACzB,OAAO,YAAY;AAClB,UAAI;AACF,eAAO,OAAO,0BAAM;AACpB,eAAO,QAAQ;AAGf,cAAM,eAAe,MAAM,UAAU,OAAO,eAAe;AAC3D,YAAI,CAAC,cAAc;AACjB,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,0GAA8C;AAC1D,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,eAAO,QAAQ,kDAAU;AAGzB,cAAM,YAAY,MAAM,SAAS,eAAe;AAChD,YAAI,CAAC,WAAW;AACd,iBAAO,MAAM,qCAAiB;AAC9B,iBAAO,KAAK,yEAA0D;AACtE,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,eAAe,MAAM,WAAW;AAGtC,cAAM,oBAAoB,MAAM,gBAAgB,YAAY;AAG5D,cAAM,eAAe,MAAM,WAAW,cAAc,iBAAiB;AAGrE,cAAM,mBAAmB,cAAc,mBAAmB,YAAY;AAAA,MACxE,SAAS,OAAY;AACnB,eAAO,MAAM,qDAAa,MAAM,OAAO,EAAE;AACzC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;AC7DH,SAAS,WAAAI,gBAAe;AACxB,OAAOC,eAAc;AACrB,OAAOC,WAAU;AAIjB,SAAS,SAAAC,cAAa;AAyEtB,eAAe,kBACb,aACA,cACA,eACe;AACf,QAAM,EAAE,QAAQ,IAAI,MAAMF,UAAS,OAAO;AAAA,IACxC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU,OAAO,UAAkB;AACjC,cAAM,SAAS,MAAM,UAAU,OAAO,KAAK;AAC3C,eAAO,UAAU;AAAA,MACnB;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,QAAQ,IAAIE,OAAM;AAAA,IACtB;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,YAAI,aAAa,MAAM,UAAU,KAAK,OAAO;AAAA,MAC/C;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,cAAM,UAAU;AAChB,cAAM,QAAQ,MAAM,UAAU,UAAU,QAAQ,OAAO;AACvD,cAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,UAAU,CAAC;AAEzD,YAAI,iBAAiB,CAAC;AACtB,mBAAW,QAAQ,OAAO;AACxB,gBAAM,SAAS,MAAM,UAAU,cAAcD,MAAK,KAAK,SAAS,IAAI,CAAC;AACrE,cAAI,WAAW,sBAAO;AACpB,gBAAI,eAAe,KAAK,KAAK,QAAQ,OAAO,EAAE,CAAC;AAAA,UACjD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,YAAI,iBAAiB,MAAM,oBAAoB;AAAA,MACjD;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,cAAM,SAAS;AAAA,UACb;AAAA,UACA,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN;AAGA,cAAM,SAAS,MAAM,SAAS,OAAO,QAAQ;AAAA,UAC3C,cAAc,CAAC,iBAAiB,kBAAkB,cAAc;AAAA,QAClE,CAAC;AAED,YAAI,eAAe;AAAA,MACrB;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,cAAM,UAAU,MAAM,eAAe,IAAI,YAAY;AAAA,MACvD;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,MAAM,IAAI;AAGhB,SAAO,QAAQ;AACf,SAAO,UAAU,UAAK,EAAE;AACxB,SAAO,QAAQ;AAEf,SAAO,QAAQ,uCAAc,aAAa,EAAE;AAC5C,QAAM,eAAe,aAAa;AAClC,QAAM,YAAY,eAAe,KAAK;AACxC;AAKA,eAAe,iBACb,aACA,cACA,eACe;AAEf,QAAM,EAAE,YAAY,IAAI,MAAMD,UAAS,OAAO;AAAA,IAC5C;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU,CAAC,UAAkB,MAAM,KAAK,EAAE,SAAS,KAAK;AAAA,IAC1D;AAAA,EACF,CAAC;AAED,QAAM,QAAQ,IAAIE,OAAM;AAAA,IACtB;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,cAAM,UAAU;AAChB,cAAM,QAAQ,MAAM,UAAU,UAAU,QAAQ,OAAO;AACvD,cAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,UAAU,CAAC;AAEzD,YAAI,iBAAiB,CAAC;AACtB,mBAAW,QAAQ,OAAO;AACxB,gBAAM,SAAS,MAAM,UAAU,cAAcD,MAAK,KAAK,SAAS,IAAI,CAAC;AACrE,cAAI,WAAW,sBAAO;AACpB,gBAAI,eAAe,KAAK,KAAK,QAAQ,OAAO,EAAE,CAAC;AAAA,UACjD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,YAAI,IAAI,eAAe,WAAW,GAAG;AACnC,cAAI,eAAe,CAAC;AACpB;AAAA,QACF;AAEA,cAAM,EAAE,aAAa,IAAI,MAAMD,UAAS,OAAO;AAAA,UAC7C;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SAAS,IAAI;AAAA,UACf;AAAA,QACF,CAAC;AAED,YAAI,eAAe;AAAA,MACrB;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,YAAI,iBAAiB,MAAM,oBAAoB;AAAA,MACjD;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,cAAM,SAAS;AAAA,UACb;AAAA,UACA;AAAA,UACA,IAAI;AAAA,UACJ,IAAI;AAAA,QACN;AAGA,cAAM,SAAS,MAAM,SAAS,OAAO,QAAQ;AAAA,UAC3C,cAAc,CAAC,iBAAiB,kBAAkB,cAAc;AAAA,QAClE,CAAC;AAED,YAAI,eAAe;AAAA,MACrB;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,cAAM,UAAU,MAAM,eAAe,IAAI,YAAY;AAAA,MACvD;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,MAAM,IAAI;AAGhB,SAAO,QAAQ;AACf,SAAO,UAAU,UAAK,EAAE;AACxB,SAAO,QAAQ;AAEf,SAAO,QAAQ,uCAAc,aAAa,EAAE;AAC5C,QAAM,eAAe,aAAa;AAClC,QAAM,YAAY,eAAe,KAAK;AACxC;AAKA,eAAe,sBAAuC;AACpD,QAAM,UAAoB,CAAC;AAG3B,MAAI,MAAM,UAAU,OAAO,uBAAuB,GAAG;AACnD,YAAQ,KAAK,8BAAU;AACvB,UAAM,cAAc,MAAM,UAAU,UAAU,MAAM,uBAAuB;AAC3E,UAAM,UAAU,YAAY,MAAM,GAAG,EAAE;AACvC,YAAQ,QAAQ,CAAC,QAAQ;AACvB,cAAQ,KAAK,6BAA6B,GAAG,EAAE;AAAA,IACjD,CAAC;AAAA,EACH;AAGA,MAAI,MAAM,UAAU,OAAO,cAAc,GAAG;AAC1C,YAAQ,KAAK,EAAE;AACf,YAAQ,KAAK,8BAAU;AACvB,UAAM,eAAe,MAAM,UAAU,UAAU,MAAM,cAAc;AACnE,UAAM,UAAU,aAAa,MAAM,GAAG,EAAE;AACxC,YAAQ,QAAQ,CAAC,QAAQ;AACvB,cAAQ,KAAK,oBAAoB,GAAG,EAAE;AAAA,IACxC,CAAC;AAAA,EACH;AAGA,MAAI,MAAM,UAAU,OAAO,YAAY,GAAG;AACxC,YAAQ,KAAK,EAAE;AACf,YAAQ,KAAK,8BAAU;AACvB,UAAM,QAAQ,MAAM,UAAU,UAAU,QAAQ,YAAY;AAC5D,UAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,UAAU,CAAC;AAEzD,eAAW,QAAQ,OAAO;AACxB,YAAM,SAAS,MAAM,UAAU,cAAcC,MAAK,KAAK,cAAc,IAAI,CAAC;AAC1E,cAAQ,KAAK,OAAO,KAAK,QAAQ,OAAO,EAAE,CAAC,KAAK,MAAM,GAAG;AAAA,IAC3D;AAAA,EACF;AAEA,SAAO,QAAQ,KAAK,IAAI;AAC1B;AAKA,SAAS,eACP,aACA,YACA,gBACA,gBACQ;AACR,QAAM,OAAO,eAAe,SAAS,IAAI,eAAe,KAAK,QAAG,IAAI;AAEpE,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASP,cAAc;AAAA;AAAA;AAAA,EAGd,WAAW;AAAA;AAAA;AAAA,EAGX,UAAU;AAAA;AAAA;AAAA,kGAGM,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gCAUV,WAAW;AAAA;AAAA;AAAA;AAAA,iCAIX,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA,EAIhD,eAAe,IAAI,CAAC,MAAM,SAAS,CAAC,EAAE,EAAE,KAAK,IAAI,KAAK,YAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8CA6BhC,WAAW;AAAA;AAAA;AAAA,wBAGlC,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBhC;AAKA,SAAS,kBACP,aACA,aACA,gBACA,cACQ;AACR,QAAM,OAAO,aAAa,SAAS,IAAI,aAAa,KAAK,QAAG,IAAI;AAEhE,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKP,WAAW;AAAA;AAAA;AAAA,EAGX,WAAW;AAAA;AAAA;AAAA,sFAGG,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOlB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gCAUJ,WAAW;AAAA;AAAA;AAAA;AAAA,iCAIX,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA,EAIhD,aAAa,IAAI,CAAC,MAAM,SAAS,CAAC,EAAE,EAAE,KAAK,IAAI,KAAK,YAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8CA6B9B,WAAW;AAAA;AAAA;AAAA,wBAGlC,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUhC;AAoFA,eAAe,eAAe,SAAgC;AAC5D,SAAO,QAAQ;AACf,SAAO,OAAO,sCAAa;AAC3B,SAAO,QAAQ;AAEf,MAAI;AACF,UAAM,UAAU,MAAM,UAAU,KAAK,OAAO;AAE5C,QAAI,CAAC,WAAW,QAAQ,KAAK,EAAE,WAAW,GAAG;AAC3C,aAAO,KAAK,0CAAY;AACxB;AAAA,IACF;AAEA,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO,KAAK,0CAAY;AACxB;AAAA,IACF;AAEA,UAAM,UAAU,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI;AAE5C,YAAQ,IAAI,OAAO;AACnB,QAAI,MAAM,SAAS,IAAI;AACrB,cAAQ,IAAI,KAAK;AACjB,cAAQ,IAAI,WAAM,MAAM,MAAM,UAAK;AAAA,IACrC;AACA,YAAQ,IAAI,EAAE;AAAA,EAChB,SAAS,OAAY;AACnB,WAAO,MAAM,8CAAgB,MAAM,OAAO,EAAE;AAAA,EAC9C;AACF;AAwCA,eAAe,YAAY,MAAc,OAAuB,QAAuB;AACrF,QAAM,YAAY,SAAS,QAAQ,QAAQ;AAC3C,QAAM,EAAE,WAAW,IAAI,MAAMD,UAAS,OAAO;AAAA,IAC3C;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,wCAAU,SAAS;AAAA,MAC5B,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,MAAI,YAAY;AACd,WAAO,KAAK,+CAAY;AACxB,UAAM,SAAS,QAAQ,IAAI,UAAU;AACrC,UAAM,EAAE,aAAa,IAAI,MAAM,OAAO,OAAO;AAC7C,UAAM,aAAa,GAAG,MAAM,IAAI,IAAI,IAAI,EAAE,OAAO,UAAU,CAAC;AAAA,EAC9D;AAEA,SAAO,QAAQ;AACf,SAAO,KAAK,qBAAM;AAClB,MAAI,SAAS,OAAO;AAClB,WAAO,KAAK,uCAA6B,IAAI,8CAAgB;AAC7D,WAAO,KAAK,gFAAuD;AAAA,EACrE,OAAO;AACL,WAAO,KAAK,uCAA6B,IAAI,iCAAkB;AAC/D,WAAO,KAAK,gFAAwC;AAAA,EACtD;AACA,SAAO,QAAQ;AACjB;AAjqBA,IAWa;AAXb;AAAA;AAAA;AAAA;AAGA;AACA;AACA;AAMO,IAAM,oBAAoB,IAAID,SAAQ,aAAa,EACvD,SAAS,kBAAkB,0BAAM,EACjC,YAAY,uGAAuB,EACnC,OAAO,OAAO,gBAAgB;AAC7B,UAAI;AACF,eAAO,OAAO,gCAAO;AACrB,eAAO,QAAQ;AAGf,cAAM,eAAe,MAAM,UAAU,OAAO,eAAe;AAC3D,YAAI,CAAC,cAAc;AACjB,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,yFAA6B;AACzC,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,YAAY,MAAM,SAAS,eAAe;AAChD,YAAI,CAAC,WAAW;AACd,iBAAO,MAAM,qCAAiB;AAC9B,iBAAO,KAAK,yEAA0D;AACtE,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,cAAc,YAAY,YAAY,WAAW;AAGvD,cAAM,UAAUE,MAAK,KAAK,iBAAiB,GAAG,WAAW,KAAK;AAC9D,cAAM,YAAY,MAAM,UAAU,OAAO,OAAO;AAChD,YAAI,WAAW;AACb,iBAAO,MAAM,uCAAc,OAAO,EAAE;AACpC,iBAAO,KAAK,0EAAc;AAC1B,iBAAO,KAAK,QAAQ,OAAO,EAAE;AAC7B,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,EAAE,KAAK,IAAI,MAAMD,UAAS,OAAO;AAAA,UACrC;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SAAS;AAAA,cACP,EAAE,MAAM,4EAA0B,OAAO,MAAM;AAAA,cAC/C,EAAE,MAAM,oGAAyB,OAAO,SAAS;AAAA,YACnD;AAAA,UACF;AAAA,QACF,CAAC;AAGD,YAAI,SAAS,OAAO;AAClB,gBAAM,kBAAkB,aAAa,aAAa,OAAO;AAAA,QAC3D,OAAO;AACL,gBAAM,iBAAiB,aAAa,aAAa,OAAO;AAAA,QAC1D;AAAA,MACF,SAAS,OAAY;AACnB,eAAO,MAAM,yCAAW,MAAM,OAAO,EAAE;AACvC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;AC1EH,SAAS,WAAAG,gBAAe;AACxB,OAAOC,YAAU;AAIjB,SAAS,SAAAC,cAAa;AA0DtB,eAAe,iBAAiB,SAAgC;AAE9D,QAAM,WAAWD,OAAK,SAAS,SAASA,OAAK,QAAQ,OAAO,CAAC;AAC7D,QAAM,cAAc,YAAY,YAAY,QAAQ;AACpD,QAAM,WAAWA,OAAK,KAAK,cAAc,GAAG,WAAW,KAAK;AAG5D,QAAM,aAAa,MAAM,UAAU,OAAO,QAAQ;AAClD,MAAI,YAAY;AACd,WAAO,MAAM,wCAAe,QAAQ,EAAE;AACtC,WAAO,KAAK,0EAAc;AAC1B,WAAO,KAAK,QAAQ,QAAQ,EAAE;AAC9B,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,QAAQ,IAAIC,OAAM;AAAA,IACtB;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,YAAI,aAAa,MAAM,UAAU,KAAK,OAAO;AAC7C,eAAO,QAAQ,qBAAW,OAAO,EAAE;AAAA,MACrC;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,cAAM,SAAS,2BAA2B,IAAI,YAAY,WAAW;AAErE,eAAO,QAAQ;AACf,eAAO,UAAU,UAAK,EAAE;AACxB,eAAO,KAAK,8BAAe;AAC3B,eAAO,UAAU,UAAK,EAAE;AACxB,eAAO,QAAQ;AAEf,YAAI,cAAc,MAAM,SAAS,OAAO,QAAQ;AAAA,UAC9C,cAAc,CAAC,iBAAiB,kBAAkB,cAAc;AAAA,QAClE,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,cAAM,UAAU,MAAM,UAAU,IAAI,WAAW;AAAA,MACjD;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,YAAY;AAChB,cAAM,eAAe,UAAU,WAAW;AAAA,MAC5C;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,MAAM,IAAI;AAEhB,SAAO,QAAQ;AACf,SAAO,UAAU,UAAK,EAAE;AACxB,SAAO,QAAQ;AAEf,SAAO,OAAO,2CAAkB;AAChC,SAAO,QAAQ,wCAAe,QAAQ,EAAE;AACxC,SAAO,QAAQ;AAEf,SAAO,KAAK,qBAAM;AAClB,SAAO,KAAK,uCAA6B,QAAQ,iCAAkB;AACnE,SAAO,KAAK,gFAAwC;AACpD,SAAO,QAAQ;AACjB;AAKA,eAAe,oBAAoB,WAAkC;AAEnE,QAAM,QAAQ,IAAIA,OAAM;AAAA,IACtB;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,cAAM,sBAAsB,CAAC,MAAM,OAAO,UAAU;AACpD,YAAI,WAAW,CAAC;AAEhB,mBAAW,OAAO,qBAAqB;AACrC,gBAAM,QAAQ,MAAM,UAAU,UAAU,KAAK,GAAG,IAAI,SAAS;AAC7D,cAAI,SAAS,KAAK,GAAG,MAAM,IAAI,CAAC,MAAMD,OAAK,KAAK,WAAW,CAAC,CAAC,CAAC;AAAA,QAChE;AAEA,YAAI,IAAI,SAAS,WAAW,GAAG;AAC7B,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAEA,YAAI,UAAU,IAAI,SAAS,CAAC;AAC5B,YAAI,IAAI,SAAS,SAAS,GAAG;AAC3B,iBAAO,KAAK,gEAAmB,IAAI,OAAO,EAAE;AAAA,QAC9C,OAAO;AACL,iBAAO,QAAQ,kCAAc,IAAI,OAAO,EAAE;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,cAAM,gBAAgBA,OAAK,KAAK,WAAW,aAAa;AACxD,cAAM,YAAY,MAAM,UAAU,OAAO,aAAa;AAEtD,YAAI,CAAC,WAAW;AACd,iBAAO,KAAK,2EAAyB;AACrC,cAAI,cAAc,CAAC;AACnB;AAAA,QACF;AAEA,cAAM,kBAAkB,CAAC,OAAO,OAAO,QAAQ,OAAO,MAAM;AAC5D,YAAI,cAAc,CAAC;AAEnB,mBAAW,OAAO,iBAAiB;AACjC,gBAAM,QAAQ,MAAM,UAAU,UAAU,KAAK,GAAG,IAAI,aAAa;AACjE,cAAI,YAAY,KAAK,GAAG,MAAM,IAAI,CAAC,MAAMA,OAAK,KAAK,eAAe,CAAC,CAAC,CAAC;AAAA,QACvE;AAEA,eAAO,QAAQ,gBAAM,IAAI,YAAY,MAAM,iCAAQ;AAAA,MACrD;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,cAAM,UAAU,MAAM,UAAU,UAAU,MAAM,SAAS;AACzD,YAAI,YAAY,CAAC;AAEjB,mBAAW,SAAS,SAAS;AAC3B,gBAAM,UAAUA,OAAK,KAAK,WAAW,KAAK;AAC1C,gBAAM,SAASA,OAAK,KAAK,SAAS,MAAM;AACxC,gBAAM,SAAS,MAAM,UAAU,OAAO,MAAM;AAC5C,cAAI,QAAQ;AACV,gBAAI,UAAU,KAAK,OAAO;AAAA,UAC5B;AAAA,QACF;AAEA,YAAI,IAAI,UAAU,SAAS,GAAG;AAC5B,iBAAO,QAAQ,mCAAe,IAAI,UAAU,KAAK,IAAI,CAAC,EAAE;AAAA,QAC1D,OAAO;AACL,iBAAO,KAAK,oEAAkB;AAAA,QAChC;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,YAAI,aAAa,MAAM,UAAU,KAAK,IAAI,OAAO;AAAA,MACnD;AAAA,IACF;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,MAAM,OAAO,QAAQ;AACnB,cAAM,SAAS;AAAA,UACb,IAAI;AAAA,UACJ,IAAI;AAAA,UACJ,IAAI;AAAA,QACN;AAEA,eAAO,QAAQ;AACf,eAAO,UAAU,UAAK,EAAE;AACxB,eAAO,KAAK,8BAAe;AAC3B,eAAO,UAAU,UAAK,EAAE;AACxB,eAAO,QAAQ;AAEf,eAAO,MAAM,SAAS,OAAO,QAAQ;AAAA,UACnC,cAAc,CAAC,iBAAiB,gBAAgB;AAAA,QAClD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,MAAM,IAAI;AAEhB,SAAO,QAAQ;AACf,SAAO,UAAU,UAAK,EAAE;AACxB,SAAO,QAAQ;AAEf,SAAO,OAAO,+BAAW;AACzB,SAAO,QAAQ,oEAA4B;AAC3C,SAAO,QAAQ;AAEf,SAAO,KAAK,qBAAM;AAClB,SAAO,KAAK,qDAAkB;AAC9B,SAAO,KAAK,0EAAsD;AAClE,SAAO,KAAK,yDAA2B;AACvC,SAAO,QAAQ;AACjB;AAKA,eAAe,eAAe,aAAqB,aAAoC;AACrF,QAAM,eAAe;AACrB,QAAM,eAAe,MAAM,UAAU,OAAO,YAAY;AACxD,MAAI,CAAC,cAAc;AACjB,WAAO,KAAK,+DAAuB;AACnC;AAAA,EACF;AAEA,MAAI,UAAU,MAAM,UAAU,KAAK,YAAY;AAG/C,QAAM,iBAAiB,YACpB,QAAQ,SAAS,GAAG,EACpB,MAAM,GAAG,EACT,IAAI,UAAQ,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,EACtE,KAAK,GAAG;AAEX,QAAM,SAAS,KAAK,cAAc,MAAM,WAAW;AAGnD,MAAI,QAAQ,SAAS,KAAK,cAAc,IAAI,KAAK,QAAQ,SAAS,GAAG,WAAW,KAAK,GAAG;AACtF,WAAO,KAAK,gBAAM,cAAc,uDAAoB;AACpD;AAAA,EACF;AAGA,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,MAAI,cAAc;AAClB,MAAI,0BAA0B;AAE9B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AAGpB,QAAI,KAAK,SAAS,0BAAM,KAAK,KAAK,SAAS,mBAAmB,GAAG;AAC/D,gCAA0B;AAAA,IAC5B;AAGA,QAAI,2BAA2B,YAAY,KAAK,KAAK,KAAK,CAAC,GAAG;AAC5D,oBAAc,IAAI;AAClB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,cAAc,GAAG;AACnB,UAAM,OAAO,aAAa,GAAG,MAAM;AACnC,cAAU,MAAM,KAAK,IAAI;AAAA,EAC3B,OAAO;AACL,eAAW;AAAA,EAAK,MAAM;AAAA;AAAA,EACxB;AAEA,QAAM,UAAU,MAAM,cAAc,OAAO;AAC7C;AAKA,SAAS,2BAA2B,YAAoB,aAA6B;AACnF,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWP,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iCAcA,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8CAiEnB,WAAW;AAAA;AAAA;AAAA,wBAGlC,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWhC;AAKA,SAAS,oBACP,YACA,aACA,WACQ;AACR,MAAI,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWb,UAAU;AAAA;AAAA;AAKV,MAAI,YAAY,SAAS,GAAG;AAC1B,cAAU;AAAA,yBACW,YAAY,MAAM;AAAA;AAEvC,eAAW,cAAc,aAAa;AACpC,gBAAU,OAAO,UAAU;AAAA;AAAA,IAC7B;AACA,cAAU;AAAA;AAAA,EAEZ;AAGA,MAAI,UAAU,SAAS,GAAG;AACxB,cAAU;AAAA;AAAA;AAGV,eAAW,QAAQ,WAAW;AAC5B,gBAAU,OAAO,IAAI;AAAA;AAAA,IACvB;AACA,cAAU;AAAA;AAAA,EAEZ;AAEA,YAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iCAsBA,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAsC1C,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAU9B,SAAO;AACT;AA3hBA,IAaa;AAbb;AAAA;AAAA;AAAA;AAEA;AACA;AACA;AASO,IAAM,kBAAkB,IAAID,SAAQ,WAAW,EACnD,SAAS,cAAc,iFAAqB,EAC5C,YAAY,6DAAqB,EACjC,OAAO,OAAO,YAAY;AACzB,UAAI;AACF,eAAO,OAAO,8BAAe;AAC7B,eAAO,QAAQ;AAGf,cAAM,eAAe,MAAM,UAAU,OAAO,eAAe;AAC3D,YAAI,CAAC,cAAc;AACjB,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,0GAA8C;AAC1D,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,aAAa,MAAM,UAAU,OAAO,OAAO;AACjD,YAAI,CAAC,YAAY;AACf,gBAAM,IAAI,MAAM,uCAAc,OAAO,EAAE;AAAA,QACzC;AAGA,cAAM,YAAY,MAAM,SAAS,eAAe;AAChD,YAAI,CAAC,WAAW;AACd,iBAAO,MAAM,qCAAiB;AAC9B,iBAAO,KAAK,yEAA0D;AACtE,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,eAAe,QAAQ,SAAS,KAAK,KAAK,QAAQ,SAAS,MAAM,KAAK,QAAQ,SAAS,WAAW;AAExG,YAAI,cAAc;AAChB,gBAAM,iBAAiB,OAAO;AAAA,QAChC,OAAO;AACL,gBAAM,oBAAoB,OAAO;AAAA,QACnC;AAAA,MACF,SAAS,OAAY;AACnB,eAAO,MAAM,iCAAa,MAAM,OAAO,EAAE;AACzC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;AC1DH,SAAS,WAAAG,gBAAe;AACxB,OAAOC,eAAc;AACrB,OAAOC,YAAU;AAGjB,SAAS,SAAAC,cAAa;AAyNtB,SAAS,gBAAwB;AAC/B,QAAM,OAAO,oBAAI,KAAK;AACtB,QAAM,OAAO,KAAK,YAAY;AAC9B,QAAM,QAAQ,OAAO,KAAK,SAAS,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG;AACzD,QAAM,MAAM,OAAO,KAAK,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG;AAGlD,SAAO,OAAO,IAAI,GAAG,KAAK,GAAG,GAAG;AAClC;AAKA,SAAS,mBAA2B;AAClC,QAAM,OAAO,oBAAI,KAAK;AACtB,QAAM,YAAY,KAAK,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE;AACpD,SAAO,MAAM,SAAS;AACxB;AAKA,eAAe,gBAAgB,aAAsC;AACnE,QAAM,UAAU;AAChB,QAAM,SAAS,MAAM,UAAU,OAAO,OAAO;AAE7C,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,MAAM,UAAU,UAAU,QAAQ,OAAO;AACvD,QAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,UAAU,CAAC;AAEzD,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AAGA,QAAM,WAAW,gBAAgB,WAAW;AAE5C,aAAW,QAAQ,OAAO;AACxB,UAAM,WAAWD,OAAK,KAAK,SAAS,IAAI;AACxC,UAAM,UAAU,MAAM,UAAU,KAAK,QAAQ;AAE7C,eAAW,WAAW,UAAU;AAC9B,UAAI,QAAQ,YAAY,EAAE,SAAS,QAAQ,YAAY,CAAC,GAAG;AACzD,eAAO,KAAK,QAAQ,OAAO,EAAE;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,gBAAgB,MAAwB;AAE/C,QAAM,YAAY,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AACnE,QAAM,QAAQ,KACX,YAAY,EACZ,QAAQ,yBAAyB,EAAE,EACnC,MAAM,KAAK,EACX,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,UAAU,SAAS,CAAC,CAAC;AAEvD,SAAO,MAAM,MAAM,GAAG,CAAC;AACzB;AAKA,SAAS,qBAAqB,MAQnB;AACT,SAAO,aAAa,KAAK,WAAW;AAAA;AAAA;AAAA,YAG1B,KAAK,EAAE;AAAA,kCACL,KAAK,QAAQ;AAAA;AAAA,kCAEb,KAAK,SAAS;AAAA;AAAA;AAAA,EAG1B,KAAK,WAAW;AAAA;AAAA;AAAA,EAGhB,KAAK,YAAY;AAAA;AAAA;AAAA,EAGjB,KAAK,KAAK;AAAA;AAAA;AAAA,EAGV,KAAK,cAAc,KAAK,KAAK,WAAW,KAAK,YAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAgB9C,KAAK,SAAS;AAAA;AAEtB;AAKA,SAAS,qBAAqB,MAOnB;AACT,SAAO,aAAa,KAAK,WAAW;AAAA;AAAA;AAAA,YAG1B,KAAK,EAAE;AAAA,kCACL,KAAK,SAAS;AAAA;AAAA;AAAA,EAG1B,KAAK,WAAW;AAAA;AAAA;AAAA,EAGhB,KAAK,KAAK;AAAA;AAAA;AAAA,EAGV,KAAK,QAAQ;AAAA;AAAA;AAAA;AAAA,eAIA,KAAK,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAYlB,KAAK,SAAS;AAAA;AAEtB;AA/XA,IAUa,eA8FA;AAxGb;AAAA;AAAA;AAAA;AAGA;AACA;AAMO,IAAM,gBAAgB,IAAIF,SAAQ,QAAQ,EAC9C,YAAY,kCAAc,EAC1B,OAAO,YAAY;AAClB,UAAI;AACF,eAAO,OAAO,kCAAc;AAC5B,eAAO,QAAQ;AAGf,cAAM,eAAe,MAAM,UAAU,OAAO,eAAe;AAC3D,YAAI,CAAC,cAAc;AACjB,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,0GAA8C;AAC1D,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,UAAU,MAAMC,UAAS,OAAO;AAAA,UACpC;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SAAS;AAAA,cACP,EAAE,MAAM,+EAAmB,OAAO,SAAI;AAAA,cACtC,EAAE,MAAM,6DAAgB,OAAO,SAAI;AAAA,cACnC,EAAE,MAAM,6DAAgB,OAAO,SAAI;AAAA,YACrC;AAAA,YACA,SAAS;AAAA,UACX;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,UAAU,CAAC,UAAkB,MAAM,KAAK,EAAE,SAAS,KAAK;AAAA,UAC1D;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SAAS;AAAA,UACX;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SAAS,CAAC,4BAAQ,4BAAQ,4BAAQ,cAAI;AAAA,YACtC,SAAS;AAAA,UACX;AAAA,QACF,CAAC;AAGD,cAAM,QAAQ,cAAc;AAC5B,cAAM,YAAY,UAAU,OAAO,oBAAI,KAAK,GAAG,YAAY;AAG3D,cAAM,cAAc,MAAM,gBAAgB,QAAQ,WAAW;AAG7D,cAAM,YAAY;AAClB,cAAM,UAAU,UAAU,SAAS;AAEnC,cAAM,aAAaC,OAAK,KAAK,WAAW,GAAG,SAAS,IAAI,KAAK,KAAK;AAElE,cAAM,UAAU,qBAAqB;AAAA,UACnC,IAAI;AAAA,UACJ,UAAU,QAAQ;AAAA,UAClB,aAAa,QAAQ;AAAA,UACrB,cAAc,QAAQ;AAAA,UACtB,OAAO,QAAQ;AAAA,UACf;AAAA,UACA;AAAA,QACF,CAAC;AAED,cAAM,UAAU,MAAM,YAAY,OAAO;AAEzC,eAAO,QAAQ,0CAAiB,UAAU,EAAE;AAC5C,eAAO,QAAQ;AAEf,eAAO,KAAK,qBAAM;AAClB,eAAO,KAAK,8CAAgB;AAC5B,eAAO,KAAK,6FAAsC;AAClD,eAAO,KAAK,mEAAsB;AAClC,eAAO,QAAQ;AAAA,MACjB,SAAS,OAAY;AACnB,eAAO,MAAM,qCAAiB,MAAM,OAAO,EAAE;AAC7C,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAKI,IAAM,gBAAgB,IAAIF,SAAQ,QAAQ,EAC9C,YAAY,sCAAQ,EACpB,OAAO,YAAY;AAClB,UAAI;AACF,eAAO,OAAO,sCAAQ;AACtB,eAAO,QAAQ;AAGf,cAAM,eAAe,MAAM,UAAU,OAAO,eAAe;AAC3D,YAAI,CAAC,cAAc;AACjB,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,0GAA8C;AAC1D,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,eAAO,KAAK,uEAAqB;AACjC,eAAO,KAAK,4EAAqB;AACjC,eAAO,QAAQ;AAGf,cAAM,UAAU,MAAMC,UAAS,OAAO;AAAA,UACpC;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,UAAU,CAAC,UAAkB,MAAM,KAAK,EAAE,SAAS,KAAK;AAAA,UAC1D;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SAAS,CAAC,4BAAQ,4BAAQ,0BAAM;AAAA,YAChC,SAAS;AAAA,UACX;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,UAAU,CAAC,UAAkB,MAAM,KAAK,EAAE,SAAS,KAAK;AAAA,UAC1D;AAAA,QACF,CAAC;AAGD,cAAM,WAAW,iBAAiB;AAClC,cAAM,aAAa,UAAU,QAAQ;AAGrC,cAAM,QAAQ,IAAIE,OAAM;AAAA,UACtB;AAAA,YACE,OAAO;AAAA,YACP,MAAM,YAAY;AAChB,oBAAM,EAAE,OAAAC,OAAM,IAAI,MAAM,OAAO,OAAO;AACtC,oBAAMA,OAAM,OAAO,CAAC,YAAY,MAAM,UAAU,GAAG,EAAE,OAAO,UAAU,CAAC;AAAA,YACzE;AAAA,UACF;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM,YAAY;AAChB,oBAAM,YAAY,UAAU,OAAO,oBAAI,KAAK,GAAG,qBAAqB;AACpE,oBAAM,YAAY;AAClB,oBAAM,UAAU,UAAU,SAAS;AAEnC,oBAAM,aAAaF,OAAK,KAAK,WAAW,GAAG,SAAS,IAAI,QAAQ,KAAK;AACrE,oBAAM,UAAU,qBAAqB;AAAA,gBACnC,IAAI;AAAA,gBACJ,aAAa,QAAQ;AAAA,gBACrB,OAAO,QAAQ;AAAA,gBACf,UAAU,QAAQ;AAAA,gBAClB,QAAQ;AAAA,gBACR;AAAA,cACF,CAAC;AAED,oBAAM,UAAU,MAAM,YAAY,OAAO;AAAA,YAC3C;AAAA,UACF;AAAA,UACA;AAAA,YACE,OAAO;AAAA,YACP,MAAM,YAAY;AAChB,oBAAM,EAAE,OAAAE,OAAM,IAAI,MAAM,OAAO,OAAO;AACtC,oBAAMA,OAAM,OAAO,CAAC,OAAO,eAAe,GAAG,EAAE,OAAO,OAAO,CAAC;AAC9D,oBAAMA;AAAA,gBACJ;AAAA,gBACA;AAAA,kBACE;AAAA,kBACA;AAAA,kBACA,WAAW,QAAQ,WAAW;AAAA;AAAA,sBAA2B,QAAQ,QAAQ;AAAA,gBAC3E;AAAA,gBACA,EAAE,OAAO,OAAO;AAAA,cAClB;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAC;AAED,cAAM,MAAM,IAAI;AAEhB,eAAO,QAAQ;AACf,eAAO,QAAQ,0CAAiB,UAAU,EAAE;AAC5C,eAAO,QAAQ;AAEf,eAAO,KAAK,qBAAM;AAClB,eAAO,KAAK,6BAAS;AACrB,eAAO,KAAK,0DAA4B;AACxC,eAAO,KAAK,qDAAa;AACzB,eAAO,KAAK,6CAAyB;AACrC,eAAO,KAAK,mEAAsB;AAClC,eAAO,QAAQ;AAAA,MACjB,SAAS,OAAY;AACnB,eAAO,MAAM,oCAAgB,MAAM,OAAO,EAAE;AAC5C,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;ACzNH,IAMa;AANb;AAAA;AAAA;AAAA;AAMO,IAAM,YAAN,MAAgB;AAAA,MACrB,OAAwB,mBACtB;AAAA,MAEF,OAAwB,gBACtB;AAAA,MAEF,OAAwB,eACtB;AAAA,MAEF,OAAwB,eACtB;AAAA,MAEF,OAAwB,gBACtB;AAAA,MAEF,OAAwB,eACtB;AAAA,MAEF,OAAwB,eACtB;AAAA,MAEF,OAAwB,kBACtB;AAAA,MAEF,OAAwB,qBACtB;AAAA;AAAA;AAAA;AAAA,MAKF,OAAO,eAAe,SAAgC;AACpD,cAAM,YAA2B,CAAC;AAClC,cAAM,QAAQ,QAAQ,MAAM,IAAI;AAEhC,YAAI,kBAA+C;AACnD,YAAI,UAAgE;AACpE,YAAI,gBAAgB;AAEpB,iBAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,gBAAM,OAAO,MAAM,CAAC,EAAE,KAAK;AAC3B,gBAAM,UAAU,IAAI;AAGpB,gBAAM,gBAAgB,KAAK,MAAM,KAAK,gBAAgB;AACtD,cAAI,eAAe;AACjB,gBAAI,mBAAmB,gBAAgB,OAAO;AAC5C,wBAAU,KAAK,KAAK,iBAAiB,iBAAiB,aAAa,CAAC;AAAA,YACtE;AACA;AACA,8BAAkB;AAAA,cAChB,IAAI,YAAY,aAAa;AAAA,cAC7B,OAAO,cAAc,CAAC,EAAE,KAAK;AAAA,cAC7B,OAAO;AAAA,cACP,OAAO,CAAC;AAAA,cACR,MAAM,CAAC;AAAA,cACP,MAAM,CAAC;AAAA,cACP,kBAAkB,CAAC;AAAA,cACnB,aAAa,CAAC;AAAA,cACd,iBAAiB,CAAC;AAAA,YACpB;AACA,sBAAU;AACV;AAAA,UACF;AAGA,cAAI,KAAK,MAAM,mBAAmB,GAAG;AACnC,kBAAM,QAAQ,KAAK,MAAM,KAAK,YAAY;AAC1C,gBAAI,SAAS,iBAAiB;AAC5B,8BAAgB,MAAM,MAAM,CAAC,EAAE,KAAK;AAAA,YACtC;AACA;AAAA,UACF;AAEA,cAAI,KAAK,MAAM,oBAAoB,GAAG;AACpC,kBAAM,QAAQ,KAAK,MAAM,KAAK,YAAY;AAC1C,gBAAI,SAAS,iBAAiB;AAC5B,8BAAgB,QAAQ,MAAM,CAAC,EAAE,KAAK;AAAA,YACxC;AACA;AAAA,UACF;AAEA,cAAI,KAAK,MAAM,mBAAmB,GAAG;AACnC,kBAAM,QAAQ,KAAK,MAAM,KAAK,eAAe;AAC7C,gBAAI,SAAS,iBAAiB;AAC5B,8BAAgB,SAAS,MAAM,CAAC,EAAE,KAAK;AAAA,YACzC;AACA;AAAA,UACF;AAGA,gBAAM,aAAa,KAAK,MAAM,KAAK,aAAa;AAChD,gBAAM,YAAY,KAAK,MAAM,KAAK,YAAY;AAC9C,gBAAM,YAAY,KAAK,MAAM,KAAK,YAAY;AAC9C,gBAAM,aAAa,KAAK,MAAM,KAAK,aAAa;AAEhD,cAAI,cAAc,iBAAiB;AACjC,4BAAgB,MAAM,KAAK;AAAA,cACzB,aAAa,WAAW,CAAC,EAAE,KAAK;AAAA,cAChC,MAAM,KAAK,oBAAoB,WAAW,CAAC,CAAC;AAAA,cAC5C,YAAY,KAAK,kBAAkB,WAAW,CAAC,CAAC;AAAA,YAClD,CAAC;AACD,sBAAU;AACV;AAAA,UACF;AAEA,cAAI,aAAa,iBAAiB;AAChC,kBAAM,SAAS,KAAK,YAAY,UAAU,CAAC,EAAE,KAAK,CAAC;AACnD,4BAAgB,KAAK,KAAK,MAAM;AAChC,gBAAI,OAAO,KAAK;AACd,8BAAgB,YAAY,KAAK,OAAO,GAAG;AAAA,YAC7C;AACA,sBAAU;AACV;AAAA,UACF;AAEA,cAAI,aAAa,iBAAiB;AAChC,4BAAgB,KAAK,KAAK;AAAA,cACxB,aAAa,UAAU,CAAC,EAAE,KAAK;AAAA,cAC/B,MAAM,KAAK,iBAAiB,UAAU,CAAC,CAAC;AAAA,cACxC,kBAAkB,KAAK,wBAAwB,UAAU,CAAC,CAAC;AAAA,YAC7D,CAAC;AACD,sBAAU;AACV;AAAA,UACF;AAEA,cAAI,cAAc,iBAAiB;AACjC,kBAAM,aAAa,KAAK,qBAAqB,WAAW,CAAC,EAAE,KAAK,CAAC;AACjE,gBAAI,YAAY;AACd,8BAAgB,iBAAiB,KAAK,UAAU;AAAA,YAClD;AACA,sBAAU;AACV;AAAA,UACF;AAGA,cAAI,QAAQ,CAAC,KAAK,WAAW,GAAG,KAAK,CAAC,KAAK,WAAW,KAAK,KAAK,iBAAiB;AAC/E,kBAAM,UAAU,KAAK,QAAQ,WAAW,EAAE;AAC1C,gBAAI,WAAW,YAAY,WAAW,gBAAgB,MAAM,SAAS,GAAG;AACtE,8BAAgB,MAAM,gBAAgB,MAAM,SAAS,CAAC,EAAE,eACtD,MAAM;AAAA,YACV,WAAW,WAAW,YAAY,UAAU,gBAAgB,KAAK,SAAS,GAAG;AAC3E,8BAAgB,KAAK,gBAAgB,KAAK,SAAS,CAAC,EAAE,eACpD,MAAM;AAAA,YACV,WAAW,WAAW,YAAY,UAAU,gBAAgB,KAAK,SAAS,GAAG;AAC3E,8BAAgB,KAAK,gBAAgB,KAAK,SAAS,CAAC,EAAE,eACpD,MAAM;AAAA,YACV;AAAA,UACF;AAAA,QACF;AAGA,YAAI,mBAAmB,gBAAgB,OAAO;AAC5C,oBAAU,KAAK,KAAK,iBAAiB,iBAAiB,aAAa,CAAC;AAAA,QACtE;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,2BAA2B,mBAA0C;AAE1E,cAAM,kBAAkB,kBAAkB;AAAA,UACxC;AAAA,QACF;AAEA,YAAI,iBAAiB;AACnB,iBAAO,KAAK,eAAe,gBAAgB,CAAC,CAAC;AAAA,QAC/C;AAGA,eAAO,KAAK,0BAA0B,iBAAiB;AAAA,MACzD;AAAA;AAAA;AAAA;AAAA,MAKA,OAAe,0BAA0B,UAAiC;AACxE,cAAM,YAA2B,CAAC;AAClC,cAAM,QAAQ,SAAS,MAAM,IAAI;AAEjC,YAAI,aAAa;AACjB,YAAI,kBAA+C;AAEnD,mBAAW,QAAQ,OAAO;AACxB,gBAAM,gBAAgB,KAAK,MAAM,sBAAsB;AAEvD,cAAI,eAAe;AACjB,gBAAI,CAAC,iBAAiB;AACpB;AACA,gCAAkB;AAAA,gBAChB,IAAI,YAAY,UAAU;AAAA,gBAC1B,OAAO,gBAAM,UAAU;AAAA,gBACvB,OAAO;AAAA,gBACP,OAAO,CAAC;AAAA,gBACR,MAAM,CAAC;AAAA,gBACP,MAAM,CAAC;AAAA,gBACP,kBAAkB,CAAC;AAAA,cACrB;AAAA,YACF;AAEA,kBAAM,OAAO,cAAc,CAAC;AAC5B,kBAAM,aAAa,KAAK,YAAY;AAEpC,gBAAI,WAAW,SAAS,QAAG,KAAK,WAAW,SAAS,QAAG,KAAK,WAAW,SAAS,cAAI,GAAG;AACrF,8BAAgB,MAAM,KAAK;AAAA,gBACzB,aAAa;AAAA,gBACb,MAAM;AAAA,gBACN,YAAY;AAAA,cACd,CAAC;AAAA,YACH,WAAW,WAAW,SAAS,QAAG,KAAK,WAAW,SAAS,cAAI,KAAK,WAAW,SAAS,cAAI,GAAG;AAC7F,8BAAgB,KAAK,KAAK;AAAA,gBACxB,aAAa;AAAA,gBACb,SAAS;AAAA,cACX,CAAC;AAAA,YACH,WAAW,WAAW,SAAS,QAAG,KAAK,WAAW,SAAS,cAAI,KAAK,WAAW,SAAS,cAAI,GAAG;AAC7F,8BAAgB,KAAK,KAAK;AAAA,gBACxB,aAAa;AAAA,gBACb,MAAM;AAAA,gBACN,kBAAkB;AAAA,cACpB,CAAC;AAAA,YACH;AAAA,UACF,WAAW,KAAK,KAAK,MAAM,MAAM,iBAAiB;AAChD,sBAAU,KAAK,KAAK,iBAAiB,iBAAiB,UAAU,CAAC;AACjE,8BAAkB;AAAA,UACpB;AAAA,QACF;AAEA,YAAI,mBAAmB,gBAAgB,OAAO;AAC5C,oBAAU,KAAK,KAAK,iBAAiB,iBAAiB,UAAU,CAAC;AAAA,QACnE;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,OAAe,oBAAoB,aAAgD;AACjF,cAAM,QAAQ,YAAY,YAAY;AACtC,YAAI,MAAM,SAAS,cAAI,KAAK,MAAM,SAAS,cAAI,KAAK,MAAM,SAAS,QAAG,EAAG,QAAO;AAChF,YAAI,MAAM,SAAS,cAAI,KAAK,MAAM,SAAS,QAAG,KAAK,MAAM,SAAS,QAAG,EAAG,QAAO;AAC/E,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,OAAe,iBAAiB,aAA2D;AACzF,cAAM,QAAQ,YAAY,YAAY;AACtC,YAAI,MAAM,SAAS,cAAI,KAAK,MAAM,SAAS,cAAI,KAAK,MAAM,SAAS,oBAAK,EAAG,QAAO;AAClF,YAAI,MAAM,SAAS,cAAI,KAAK,MAAM,SAAS,cAAI,KAAK,MAAM,SAAS,cAAI,EAAG,QAAO;AACjF,YAAI,MAAM,SAAS,cAAI,KAAK,MAAM,SAAS,cAAI,KAAK,MAAM,SAAS,cAAI,EAAG,QAAO;AACjF,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,OAAe,kBAAkB,aAA6B;AAC5D,cAAM,QAAQ,YAAY,MAAM,aAAa;AAC7C,eAAO,QAAQ,MAAM,CAAC,IAAI;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA,MAKA,OAAe,wBAAwB,aAA6B;AAClE,eAAO,YAAY,QAAQ,oBAAoB,EAAE,EAAE,KAAK;AAAA,MAC1D;AAAA;AAAA;AAAA;AAAA,MAKA,OAAe,YAAY,aAAgC;AACzD,cAAM,WAAW,YAAY,MAAM,wDAAwD;AAC3F,cAAM,UAAU,YAAY,MAAM,gCAAgC;AAElE,eAAO;AAAA,UACL;AAAA,UACA,KAAK,WAAW,CAAC;AAAA,UACjB,UAAU,UAAU,CAAC;AAAA,UACrB,SAAS,WAAW,QAAQ;AAAA,QAC9B;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,OAAe,qBAAqB,aAA6C;AAC/E,cAAM,aAAa,YAAY,MAAM,kCAAkC;AAEvE,YAAI,YAAY;AACd,iBAAO;AAAA,YACL,MAAM,WAAW,CAAC;AAAA,YAClB,SAAS,YAAY,MAAM,MAAM,EAAE,CAAC,GAAG,KAAK,KAAK;AAAA,YACjD,IAAI,WAAW,CAAC;AAAA,UAClB;AAAA,QACF;AAEA,cAAM,YAAY,YAAY,MAAM,2BAA2B;AAC/D,cAAM,UAAU,YAAY,MAAM,0BAA0B;AAC5D,cAAM,eAAe,YAAY,MAAM,gCAAgC;AAEvE,YAAI,aAAa,SAAS;AACxB,iBAAO;AAAA,YACL,MAAM,UAAU,CAAC;AAAA,YACjB,SAAS,eAAe,CAAC,KAAK;AAAA,YAC9B,IAAI,QAAQ,CAAC;AAAA,UACf;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,OAAe,iBACb,UACA,OACa;AACb,eAAO;AAAA,UACL,IAAI,SAAS,MAAM,YAAY,KAAK;AAAA,UACpC,OAAO,SAAS,SAAS,gBAAM,KAAK;AAAA,UACpC,OAAO,SAAS,SAAS;AAAA,UACzB,KAAK,SAAS,OAAO;AAAA,UACrB,OAAO,SAAS,SAAS;AAAA,UACzB,QAAQ,SAAS,UAAU;AAAA,UAC3B,OAAO,SAAS,SAAS,CAAC;AAAA,UAC1B,MAAM,SAAS,QAAQ,CAAC;AAAA,UACxB,MAAM,SAAS,QAAQ,CAAC;AAAA,UACxB,kBAAkB,SAAS,oBAAoB,CAAC;AAAA,UAChD,aAAa,SAAS,eAAe,CAAC;AAAA,UACtC,iBAAiB,SAAS,mBAAmB,CAAC;AAAA,QAChD;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,iBAAiB,UAA+B;AACrD,cAAM,QAAkB,CAAC;AAEzB,cAAM,KAAK,qBAAW,SAAS,KAAK,KAAK,SAAS,KAAK,EAAE;AACzD,cAAM,KAAK,EAAE;AAEb,YAAI,SAAS,KAAK;AAChB,gBAAM,KAAK,oBAAU,SAAS,GAAG,EAAE;AAAA,QACrC;AACA,YAAI,SAAS,OAAO;AAClB,gBAAM,KAAK,0BAAW,SAAS,KAAK,EAAE;AAAA,QACxC;AACA,YAAI,SAAS,QAAQ;AACnB,gBAAM,KAAK,oBAAU,SAAS,MAAM,EAAE;AAAA,QACxC;AACA,cAAM,KAAK,EAAE;AAEb,mBAAW,SAAS,SAAS,OAAO;AAClC,gBAAM,KAAK,aAAa,MAAM,WAAW,EAAE;AAAA,QAC7C;AACA,cAAM,KAAK,EAAE;AAEb,mBAAW,QAAQ,SAAS,MAAM;AAChC,gBAAM,KAAK,YAAY,KAAK,WAAW,EAAE;AAAA,QAC3C;AACA,cAAM,KAAK,EAAE;AAEb,mBAAW,QAAQ,SAAS,MAAM;AAChC,gBAAM,KAAK,YAAY,KAAK,WAAW,EAAE;AAAA,QAC3C;AACA,cAAM,KAAK,EAAE;AAEb,YAAI,SAAS,iBAAiB,SAAS,GAAG;AACxC,gBAAM,KAAK,+BAAW;AACtB,qBAAW,SAAS,SAAS,kBAAkB;AAC7C,kBAAM,KAAK,OAAO,MAAM,IAAI,eAAU,MAAM,EAAE,qBAAW,MAAM,OAAO,GAAG;AAAA,UAC3E;AACA,gBAAM,KAAK,EAAE;AAAA,QACf;AAEA,eAAO,MAAM,KAAK,IAAI;AAAA,MACxB;AAAA,IACF;AAAA;AAAA;;;ACvYA,SAAS,WAAAC,gBAAe;AACxB,OAAOC,eAAc;AACrB,OAAOC,YAAU;AA2FjB,eAAe,yBAAyB,aAAqC;AAE3E,QAAM,eAAe,MAAMC,YAAW,WAAW;AAGjD,QAAM,oBAAoB,MAAMC,iBAAgB,YAAY;AAG5D,QAAM,SAAS,MAAM,mBAAmB,cAAc,iBAAiB;AAGvE,QAAM,yBAAyB,MAAM;AAGrC,MAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,UAAM,aAAa,MAAM;AAAA,EAC3B;AAGA,QAAM,eAAe,cAAc,MAAM;AAC3C;AAKA,eAAe,iBAAiB,aAAsB,YAAoC;AAExF,QAAM,eAAe,MAAMD,YAAW,WAAW;AAGjD,QAAM,cAAc,MAAM,UAAU,KAAK,YAAY;AACrD,QAAM,YAAY,UAAU,2BAA2B,WAAW;AAElE,MAAI,UAAU,WAAW,GAAG;AAC1B,WAAO,KAAK,2FAAqB;AACjC,WAAO,KAAK,oGAA6C;AACzD,UAAM,yBAAyB,YAAY;AAC3C;AAAA,EACF;AAGA,QAAM,kBAAkB,aACpB,UAAU,OAAO,OAAK,EAAE,OAAO,cAAc,EAAE,MAAM,YAAY,EAAE,SAAS,WAAW,YAAY,CAAC,CAAC,IACrG;AAEJ,MAAI,gBAAgB,WAAW,GAAG;AAChC,UAAM,IAAI,MAAM,mCAAU,UAAU,EAAE;AAAA,EACxC;AAEA,SAAO,QAAQ;AACf,SAAO,KAAK,gBAAM,UAAU,MAAM,oDAAiB,gBAAgB,MAAM,SAAI;AAG7E,QAAM,UAA4B,CAAC;AAEnC,aAAW,YAAY,iBAAiB;AACtC,WAAO,QAAQ;AACf,WAAO,KAAK,6BAAS,SAAS,KAAK,EAAE;AAErC,UAAM,SAAS,MAAM,iBAAiB,UAAU,YAAY;AAC5D,YAAQ,KAAK,MAAM;AAGnB,wBAAoB,MAAM;AAAA,EAC5B;AAGA,QAAM,kBAAkB,cAAc,OAAO;AAG7C,QAAM,cAAc,cAAc,OAAO;AAC3C;AAKA,eAAeA,YAAW,aAAuC;AAC/D,SAAO,KAAK,qDAAuB;AACnC,SAAO,QAAQ;AAEf,QAAM,UAAU;AAChB,QAAM,SAAS,MAAM,UAAU,OAAO,OAAO;AAC7C,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,2CAAkB;AAAA,EACpC;AAEA,QAAM,QAAQ,MAAM,UAAU,UAAU,QAAQ,OAAO;AACvD,QAAM,YAAY,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,UAAU,CAAC;AAE7D,MAAI,UAAU,WAAW,GAAG;AAC1B,UAAM,IAAI,MAAM,sCAAa;AAAA,EAC/B;AAGA,MAAI,aAAa;AACf,UAAM,WAAW,YAAY,WAAW,aAAa,IACjD,cACAD,OAAK,KAAK,SAAS,WAAW;AAElC,UAAMG,UAAS,MAAM,UAAU,OAAO,QAAQ;AAC9C,QAAI,CAACA,SAAQ;AACX,YAAM,IAAI,MAAM,wCAAe,WAAW,EAAE;AAAA,IAC9C;AACA,WAAO,QAAQ,uBAAQ,QAAQ,EAAE;AACjC,WAAO;AAAA,EACT;AAGA,QAAM,QAA0D,CAAC;AACjE,aAAW,QAAQ,WAAW;AAC5B,UAAM,WAAWH,OAAK,KAAK,SAAS,IAAI;AACxC,UAAM,UAAU,MAAM,UAAU,KAAK,QAAQ;AAC7C,UAAM,SAAS,UAAU,gBAAgB,OAAO;AAChD,UAAM,KAAK,EAAE,MAAM,UAAU,MAAM,MAAM,OAAO,CAAC;AAAA,EACnD;AAGA,QAAM,cAAc,MAAM;AAAA,IACxB,CAAC,MAAM,EAAE,WAAW,wBAAS,EAAE,WAAW,wBAAS,EAAE,WAAW;AAAA,EAClE;AAEA,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO,KAAK,wDAAgB;AAC5B,UAAM,EAAE,eAAe,IAAI,MAAMD,UAAS,OAAO;AAAA,MAC/C;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AAED,QAAI,CAAC,gBAAgB;AACnB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,cAAc,YAAY,SAAS,IAAI,cAAc;AAE3D,QAAM,UAAU,YAAY,IAAI,CAAC,UAAU;AAAA,IACzC,MAAM,IAAI,KAAK,MAAM,KAAK,KAAK,IAAI;AAAA,IACnC,OAAO,KAAK;AAAA,IACZ,OAAO,KAAK;AAAA,EACd,EAAE;AAEF,QAAM,EAAE,aAAa,IAAI,MAAMA,UAAS,OAAO;AAAA,IAC7C;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,QAAQ,uBAAQ,YAAY,EAAE;AACrC,SAAO;AACT;AAKA,eAAeG,iBAAgB,UAAmC;AAChE,SAAO,QAAQ;AACf,SAAO,KAAK,8CAA0B;AACtC,SAAO,QAAQ;AAEf,QAAM,cAAc,MAAM,UAAU,KAAK,QAAQ;AACjD,QAAM,EAAE,SAAS,IAAI,UAAU,oCAAoC,WAAW;AAE9E,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,IAAI,MAAM,2FAA+B;AAAA,EACjD;AAGA,QAAM,UAAU,SAAS,IAAI,CAAC,GAAG,QAAQ;AACvC,UAAM,SAAS,EAAE,mBAAmB,EAAE;AACtC,UAAM,aAAa,SAAS,WAAM,EAAE,iBAAiB,IAAI,WAAM;AAC/D,UAAM,WAAW,IAAI,EAAE,cAAc,IAAI,EAAE,UAAU;AAErD,WAAO;AAAA,MACL,MAAM,GAAG,MAAM,CAAC,KAAK,UAAU,IAAI,QAAQ,IAAI,EAAE,KAAK;AAAA,MACtD,OAAO,EAAE;AAAA,MACT,OAAO,EAAE;AAAA,IACX;AAAA,EACF,CAAC;AAED,QAAM,EAAE,UAAU,IAAI,MAAMH,UAAS,OAAO;AAAA,IAC1C;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAKA,eAAe,mBACb,UACA,WAC2B;AAC3B,SAAO,QAAQ;AACf,SAAO,KAAK,2DAAmB;AAC/B,SAAO,QAAQ;AAEf,QAAM,cAAc,MAAM,UAAU,KAAK,QAAQ;AACjD,QAAM,EAAE,SAAS,IAAI,UAAU,oCAAoC,QAAQ;AAC3E,QAAM,kBAAkB,SAAS,KAAK,CAAC,MAAM,EAAE,UAAU,SAAS;AAElE,MAAI,CAAC,iBAAiB;AACpB,UAAM,IAAI,MAAM,iCAAkB,SAAS,EAAE;AAAA,EAC/C;AAEA,QAAM,SAA2B;AAAA,IAC/B;AAAA,IACA;AAAA,IACA,YAAW,oBAAI,KAAK,GAAE,eAAe,OAAO;AAAA,IAC5C,eAAe,EAAE,OAAO,GAAG,WAAW,GAAG,OAAO,CAAC,EAAE;AAAA,IACnD,cAAc,EAAE,OAAO,GAAG,WAAW,GAAG,OAAO,CAAC,EAAE;AAAA,IAClD,iBAAiB,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC,EAAE;AAAA,IACpD,kBAAkB,EAAE,OAAO,GAAG,WAAW,GAAG,OAAO,CAAC,EAAE;AAAA,IACtD,QAAQ,CAAC;AAAA,EACX;AAGA,SAAO,KAAK,yCAAW;AACvB,aAAW,QAAQ,gBAAgB,eAAe;AAChD,UAAM,cAAc,MAAM,kBAAkB,IAAI;AAChD,WAAO,cAAc,MAAM,KAAK,WAAW;AAC3C,QAAI,YAAY,WAAW,QAAQ;AACjC,aAAO,cAAc;AAAA,IACvB;AACA,WAAO,cAAc;AAErB,UAAM,OAAO,YAAY,WAAW,SAAS,WAAM,YAAY,WAAW,SAAS,WAAM;AACzF,WAAO,KAAK,KAAK,IAAI,QAAQ,KAAK,OAAO,GAAG,YAAY,WAAW,MAAM,YAAY,QAAQ,KAAK,EAAE,EAAE;AAAA,EACxG;AAGA,SAAO,KAAK,yCAAW;AACvB,aAAW,QAAQ,gBAAgB,cAAc;AAC/C,UAAM,cAAc,MAAM,iBAAiB,IAAI;AAC/C,WAAO,aAAa,MAAM,KAAK,WAAW;AAC1C,QAAI,YAAY,WAAW,QAAQ;AACjC,aAAO,aAAa;AAAA,IACtB;AACA,WAAO,aAAa;AAEpB,UAAM,OAAO,YAAY,WAAW,SAAS,WAAM,YAAY,WAAW,SAAS,WAAM;AACzF,WAAO,KAAK,KAAK,IAAI,QAAQ,KAAK,OAAO,GAAG,YAAY,WAAW,MAAM,YAAY,QAAQ,KAAK,EAAE,EAAE;AAAA,EACxG;AAGA,SAAO,KAAK,kCAAc;AAC1B,aAAW,QAAQ,gBAAgB,cAAc;AAC/C,QAAI,KAAK,gBAAgB;AACvB,YAAM,cAAc,MAAM,wBAAwB,IAAI;AACtD,aAAO,gBAAgB,MAAM,KAAK,WAAW;AAC7C,UAAI,YAAY,WAAW,QAAQ;AACjC,eAAO,gBAAgB;AAAA,MACzB;AACA,aAAO,gBAAgB;AAEvB,YAAM,OAAO,YAAY,WAAW,SAAS,WAAM,YAAY,WAAW,SAAS,WAAM;AACzF,aAAO,KAAK,KAAK,IAAI,IAAI,KAAK,cAAc,GAAG,YAAY,WAAW,MAAM,YAAY,QAAQ,KAAK,EAAE,EAAE;AAAA,IAC3G;AAAA,EACF;AAGA,SAAO,KAAK,yCAAW;AACvB,aAAW,QAAQ,gBAAgB,kBAAkB;AACnD,UAAM,cAAc,MAAM,qBAAqB,IAAI;AACnD,WAAO,iBAAiB,MAAM,KAAK,WAAW;AAC9C,QAAI,YAAY,WAAW,QAAQ;AACjC,aAAO,iBAAiB;AAAA,IAC1B;AACA,WAAO,iBAAiB;AAExB,UAAM,OAAO,YAAY,WAAW,SAAS,WAAM,YAAY,WAAW,SAAS,WAAM;AACzF,WAAO,KAAK,KAAK,IAAI,QAAQ,KAAK,OAAO,EAAE;AAAA,EAC7C;AAEA,SAAO;AACT;AAKA,eAAe,kBAAkB,MAAoC;AAEnE,QAAM,gBAAgB;AAAA,IACpB,sBAAsB,KAAK,OAAO;AAAA,IAClC,2BAA2B,KAAK,OAAO;AAAA,IACvC,2BAA2B,KAAK,QAAQ,QAAQ,QAAQ,EAAE,CAAC;AAAA,IAC3D,sBAAsB,KAAK,OAAO;AAAA,IAClC,2BAA2B,KAAK,OAAO;AAAA,EACzC;AAEA,aAAW,MAAM,eAAe;AAC9B,QAAI,MAAM,UAAU,OAAO,EAAE,GAAG;AAC9B,aAAO;AAAA,QACL,aAAa,OAAO,KAAK,OAAO;AAAA,QAChC,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAGA,QAAM,YAAY,KAAK,QAAQ,MAAM,mCAAmC;AACxE,MAAI,WAAW;AACb,UAAM,WAAW,UAAU,CAAC;AAC5B,QAAI,MAAM,UAAU,OAAO,QAAQ,GAAG;AACpC,aAAO;AAAA,QACL,aAAa,OAAO,KAAK,OAAO;AAAA,QAChC,QAAQ;AAAA,QACR,SAAS;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,aAAa,OAAO,KAAK,OAAO;AAAA,IAChC,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AACF;AAKA,eAAe,iBAAiB,MAAoC;AAElE,QAAM,eAAe;AAAA,IACnB,yBAAyB,KAAK,QAAQ,QAAQ,QAAQ,GAAG,CAAC;AAAA,IAC1D,eAAe,KAAK,QAAQ,YAAY,EAAE,QAAQ,QAAQ,GAAG,CAAC;AAAA,EAChE;AAEA,aAAW,MAAM,cAAc;AAC7B,QAAI,MAAM,UAAU,OAAO,EAAE,GAAG;AAC9B,aAAO;AAAA,QACL,aAAa,OAAO,KAAK,OAAO;AAAA,QAChC,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAGA,QAAM,YAAY,KAAK,QAAQ,MAAM,kCAAkC;AACvE,MAAI,WAAW;AACb,UAAM,WAAW,UAAU,CAAC;AAC5B,QAAI,MAAM,UAAU,OAAO,QAAQ,GAAG;AACpC,aAAO;AAAA,QACL,aAAa,OAAO,KAAK,OAAO;AAAA,QAChC,QAAQ;AAAA,QACR,SAAS;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,aAAa,OAAO,KAAK,OAAO;AAAA,IAChC,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AACF;AAKA,eAAe,wBAAwB,MAAoC;AACzE,MAAI,CAAC,KAAK,gBAAgB;AACxB,WAAO;AAAA,MACL,aAAa,KAAK,kBAAkB;AAAA,MACpC,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,EACF;AAGA,QAAM,WAAW,KAAK,eAAe,MAAM,wCAAwC;AACnF,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,MACL,aAAa,KAAK;AAAA,MAClB,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,EACF;AAEA,QAAM,SAAS,SAAS,CAAC;AACzB,QAAM,UAAU,SAAS,CAAC;AAG1B,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA;AAAA,EACF;AAEA,QAAM,kBAAkB,MAAM,UAAU,UAAU,uBAAuB,aAAa;AAEtF,aAAW,MAAM,iBAAiB;AAChC,UAAM,UAAU,MAAM,UAAU,KAAK,EAAE;AAEvC,QAAI,QAAQ,SAAS,OAAO,KAAK,QAAQ,SAAS,IAAI,OAAO,GAAG,GAAG;AAEjE,YAAM,oBAA8C;AAAA,QAClD,KAAK,CAAC,eAAe,6CAA6C;AAAA,QAClE,MAAM,CAAC,gBAAgB,8CAA8C;AAAA,QACrE,KAAK,CAAC,eAAe,6CAA6C;AAAA,QAClE,QAAQ,CAAC,kBAAkB,gDAAgD;AAAA,QAC3E,OAAO,CAAC,iBAAiB,+CAA+C;AAAA,MAC1E;AAEA,iBAAW,cAAc,kBAAkB,MAAM,KAAK,CAAC,GAAG;AACxD,YAAI,QAAQ,SAAS,UAAU,GAAG;AAChC,iBAAO;AAAA,YACL,aAAa,KAAK;AAAA,YAClB,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,UAAU;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,aAAa,KAAK;AAAA,IAClB,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AACF;AAKA,eAAe,qBAAqB,MAAoC;AAGtE,QAAM,sBAAsB;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,aAAa;AACnB,MAAI,MAAM,UAAU,OAAO,UAAU,GAAG;AACtC,UAAM,eAAe,MAAM,UAAU,UAAU,QAAQ,UAAU;AACjE,UAAM,mBAAmB,aAAa;AAAA,MAAK,CAAC,OAC1C,GAAG,SAAS,aAAa,KAAK,GAAG,SAAS,cAAI;AAAA,IAChD;AACA,QAAI,kBAAkB;AACpB,aAAO;AAAA,QACL,aAAa,OAAO,KAAK,OAAO;AAAA,QAChC,QAAQ;AAAA,QACR,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL,aAAa,OAAO,KAAK,OAAO;AAAA,IAChC,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AACF;AAKA,eAAe,yBAAyB,QAAyC;AAC/E,SAAO,QAAQ;AACf,SAAO,KAAK,2DAAmB;AAC/B,SAAO,QAAQ;AAEf,QAAM,YAAY;AAClB,QAAM,UAAU,UAAU,SAAS;AAEnC,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AACtD,QAAM,WAAWC,OAAK,SAAS,OAAO,UAAU,KAAK;AACrD,QAAM,gBAAgB,OAAO,UAAU,QAAQ,iBAAiB,GAAG;AACnE,QAAM,aAAaA,OAAK,KAAK,WAAW,GAAG,SAAS,IAAI,QAAQ,IAAI,aAAa,KAAK;AAEtF,QAAM,SAAS,uBAAuB,MAAM;AAE5C,QAAM,UAAU,MAAM,YAAY,MAAM;AAExC,SAAO,QAAQ,+CAAY,UAAU,EAAE;AACvC,SAAO,QAAQ;AAGf,UAAQ,IAAI,sBAAsB,MAAM,CAAC;AAC3C;AAKA,SAAS,uBAAuB,QAAkC;AAChE,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,4BAAQ;AACnB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,0BAAgB,OAAO,QAAQ,EAAE;AAC5C,QAAM,KAAK,kBAAkB,OAAO,SAAS,EAAE;AAC/C,QAAM,KAAK,iCAAa,OAAO,SAAS,EAAE;AAC1C,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,yCAAW;AACtB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,uCAAc;AACzB,QAAM,KAAK,mBAAmB;AAC9B,QAAM;AAAA,IACJ,gCAAY,OAAO,cAAc,SAAS,IAAI,OAAO,cAAc,KAAK;AAAA,EAC1E;AACA,QAAM;AAAA,IACJ,gCAAY,OAAO,aAAa,SAAS,IAAI,OAAO,aAAa,KAAK;AAAA,EACxE;AACA,QAAM,KAAK,wBAAc,OAAO,gBAAgB,QAAQ,IAAI,OAAO,gBAAgB,KAAK,iBAAO;AAC/F,QAAM;AAAA,IACJ,gCAAY,OAAO,iBAAiB,SAAS,IAAI,OAAO,iBAAiB,KAAK;AAAA,EAChF;AACA,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,6BAAS;AACpB,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,8BAAU;AACrB,QAAM,KAAK,EAAE;AACb,aAAW,QAAQ,OAAO,cAAc,OAAO;AAC7C,UAAM,OAAO,KAAK,WAAW,SAAS,WAAM,KAAK,WAAW,SAAS,WAAM;AAC3E,UAAM,KAAK,KAAK,IAAI,IAAI,KAAK,WAAW,MAAM,KAAK,WAAW,EAAE,IAAI,KAAK,WAAW,MAAM,KAAK,QAAQ,QAAQ,EAAE,EAAE;AAAA,EACrH;AACA,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,8BAAU;AACrB,QAAM,KAAK,EAAE;AACb,aAAW,QAAQ,OAAO,aAAa,OAAO;AAC5C,UAAM,OAAO,KAAK,WAAW,SAAS,WAAM,KAAK,WAAW,SAAS,WAAM;AAC3E,UAAM,KAAK,KAAK,IAAI,IAAI,KAAK,WAAW,MAAM,KAAK,WAAW,EAAE,IAAI,KAAK,WAAW,MAAM,KAAK,QAAQ,QAAQ,EAAE,EAAE;AAAA,EACrH;AACA,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,sBAAY;AACvB,QAAM,KAAK,EAAE;AACb,aAAW,QAAQ,OAAO,gBAAgB,OAAO;AAC/C,UAAM,OAAO,KAAK,WAAW,SAAS,WAAM,KAAK,WAAW,SAAS,WAAM;AAC3E,UAAM,KAAK,KAAK,IAAI,IAAI,KAAK,WAAW,MAAM,KAAK,WAAW,EAAE,IAAI,KAAK,WAAW,MAAM,KAAK,QAAQ,QAAQ,EAAE,EAAE;AAAA,EACrH;AACA,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,8BAAU;AACrB,QAAM,KAAK,EAAE;AACb,aAAW,QAAQ,OAAO,iBAAiB,OAAO;AAChD,UAAM,OAAO,KAAK,WAAW,SAAS,WAAM,KAAK,WAAW,SAAS,WAAM;AAC3E,UAAM,KAAK,KAAK,IAAI,IAAI,KAAK,WAAW,MAAM,KAAK,WAAW,EAAE,EAAE;AAAA,EACpE;AACA,QAAM,KAAK,EAAE;AAGb,MAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,UAAM,KAAK,mCAAU;AACrB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,2EAAyB;AACpC,UAAM,KAAK,kCAAkC;AAC7C,eAAW,SAAS,OAAO,QAAQ;AACjC,YAAM,KAAK,KAAK,MAAM,KAAK,MAAM,MAAM,IAAI,MAAM,MAAM,QAAQ,MAAM,MAAM,MAAM,IAAI;AAAA,IACvF;AACA,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,mBAAS;AACpB,UAAM,KAAK,oCAA0B,OAAO,QAAQ,6BAAS;AAC7D,UAAM,KAAK,iEAA8B;AACzC,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,QAAM,KAAK,mCAAU;AACrB,QAAM,KAAK,EAAE;AACb,MAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,UAAM,KAAK,kDAAe;AAAA,EAC5B;AACA,QAAM,KAAK,4DAA8B;AACzC,QAAM,KAAK,+DAAiC;AAC5C,QAAM,KAAK,EAAE;AAEb,SAAO,MAAM,KAAK,IAAI;AACxB;AAKA,SAAS,sBAAsB,QAAkC;AAC/D,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,kSAAkD;AAC7D,QAAM,KAAK,qFAA6C;AACxD,QAAM,KAAK,kSAAkD;AAC7D,QAAM,KAAK,gBAAW,OAAO,SAAS,OAAO,EAAE,CAAC,QAAG;AACnD,QAAM,KAAK,qBAAgB,OAAO,UAAU,OAAO,EAAE,CAAC,QAAG;AACzD,QAAM,KAAK,kSAAkD;AAC7D,QAAM;AAAA,IACJ,oCAAW,OAAO,cAAc,SAAS,IAAI,OAAO,cAAc,KAAK,gBAAM,OAAO,EAAE,IAAI;AAAA,EAC5F;AACA,QAAM;AAAA,IACJ,oCAAW,OAAO,aAAa,SAAS,IAAI,OAAO,aAAa,KAAK,gBAAM,OAAO,EAAE,IAAI;AAAA,EAC1F;AACA,QAAM;AAAA,IACJ,4BAAa,OAAO,gBAAgB,QAAQ,IAAI,OAAO,gBAAgB,KAAK,gBAAM,OAAO,EAAE,IAAI;AAAA,EACjG;AACA,QAAM;AAAA,IACJ,oCAAW,OAAO,iBAAiB,SAAS,IAAI,OAAO,iBAAiB,KAAK,gBAAM,OAAO,EAAE,IAAI;AAAA,EAClG;AACA,QAAM,KAAK,kSAAkD;AAE7D,QAAM,cAAc,OAAO,OAAO;AAClC,MAAI,cAAc,GAAG;AACnB,UAAM,KAAK,2CAAa,WAAW,UAAK,OAAO,EAAE,IAAI,QAAG;AAAA,EAC1D,OAAO;AACL,UAAM,KAAK,yCAAW,OAAO,EAAE,IAAI,QAAG;AAAA,EACxC;AACA,QAAM,KAAK,kSAAkD;AAE7D,SAAO,MAAM,KAAK,IAAI;AACxB;AAKA,eAAe,aAAa,QAAyC;AACnE,SAAO,QAAQ;AACf,SAAO,KAAK,gBAAM,OAAO,OAAO,MAAM,6CAAU;AAGhD,QAAM,YAAY;AAClB,QAAM,UAAU,UAAU,SAAS;AAEnC,aAAW,SAAS,OAAO,QAAQ;AACjC,UAAM,aAAaA,OAAK;AAAA,MACtB;AAAA,MACA,IAAG,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,IAAI,MAAM,EAAE;AAAA,IACtD;AAEA,UAAM,gBAAgB,sBAAsB,QAAQ,KAAK;AACzD,UAAM,UAAU,MAAM,YAAY,aAAa;AAE/C,WAAO,KAAK,6CAAoB,UAAU,EAAE;AAAA,EAC9C;AAEA,SAAO,QAAQ;AAEf,QAAM,EAAE,OAAO,IAAI,MAAMD,UAAS,OAAO;AAAA,IACvC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,MAAI,QAAQ;AACV,WAAO,KAAK,2EAA8B;AAAA,EAC5C,OAAO;AACL,WAAO,KAAK,oDAAY,SAAS,eAAK;AACtC,WAAO,KAAK,iFAA+B;AAAA,EAC7C;AACF;AAKA,SAAS,sBAAsB,QAA0B,OAA4B;AACnF,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,uBAAa;AACxB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,WAAW,MAAM,EAAE,EAAE;AAChC,QAAM,KAAK,iCAAa,MAAM,SAAS,EAAE;AACzC,QAAM,KAAK,qBAAW,MAAM,MAAM,EAAE;AACpC,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,6BAAS;AACpB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,MAAM,WAAW;AAC5B,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,6BAAS;AACpB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,WAAW,OAAO,QAAQ,EAAE;AACvC,QAAM,KAAK,gBAAgB,OAAO,SAAS,EAAE;AAC7C,MAAI,MAAM,MAAM;AACd,UAAM,KAAK,WAAW,MAAM,IAAI,EAAE;AAAA,EACpC;AACA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,6BAAS;AACpB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,KAAK,MAAM,SAAS,YAAY,CAAC,EAAE;AAC9C,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,6BAAS;AACpB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,KAAK,MAAM,IAAI,EAAE;AAC5B,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,6BAAS;AACpB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,qDAAuB;AAClC,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,6BAAS;AACpB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AAEb,SAAO,MAAM,KAAK,IAAI;AACxB;AAKA,eAAe,eAAe,UAAkB,QAAyC;AACvF,QAAM,UAAU,MAAM,UAAU,KAAK,QAAQ;AAC7C,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAGhC,MAAI,oBAAoB;AACxB,MAAI,iBAAiB;AAErB,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AAEpB,QAAI,KAAK,SAAS,OAAO,SAAS,GAAG;AACnC,0BAAoB;AACpB,uBAAiB;AACjB;AAAA,IACF;AAEA,QAAI,qBAAqB,KAAK,MAAM,kBAAkB,GAAG;AACvD;AAAA,IACF;AAAA,EACF;AAEA,MAAI,mBAAmB,IAAI;AAEzB,QAAI,iBAAiB;AACrB,QAAI,aAAa;AAEjB,aAAS,IAAI,iBAAiB,GAAG,IAAI,MAAM,QAAQ,KAAK;AACtD,YAAM,OAAO,MAAM,CAAC;AACpB,UAAI,KAAK,MAAM,kBAAkB,GAAG;AAClC;AAAA,MACF;AACA,UAAI,KAAK,MAAM,SAAS,GAAG;AACzB;AACA,YAAI,KAAK,MAAM,YAAY,GAAG;AAC5B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,eAAe,GAAG,OAAO,SAAS,KAAK,cAAc,IAAI,UAAU;AACzE,UAAM,cAAc,MAAM,MAAM,GAAG,cAAc;AACjD,UAAM,aAAa,MAAM,MAAM,iBAAiB,CAAC;AAGjD,QAAI,CAAC,MAAM,cAAc,EAAE,SAAS,IAAI,cAAc,IAAI,UAAU,GAAG,GAAG;AAExE,YAAM,uBAAuB,MAAM,cAAc,EAAE;AAAA,QACjD;AAAA,QACA,KAAK,cAAc,IAAI,UAAU;AAAA,MACnC;AACA,YAAM,cAAc,IAAI;AAExB,YAAM,UAAU,MAAM,UAAU,MAAM,KAAK,IAAI,CAAC;AAChD,aAAO,KAAK,sDAAc,cAAc,IAAI,UAAU,GAAG;AAAA,IAC3D;AAAA,EACF;AACF;AAOA,eAAe,iBACb,UACA,UACyB;AACzB,QAAM,SAAyB;AAAA,IAC7B,YAAY,SAAS;AAAA,IACrB,eAAe,SAAS;AAAA,IACxB,eAAe;AAAA,IACf,cAAc,CAAC;AAAA,IACf,aAAa,CAAC;AAAA,IACd,aAAa,CAAC;AAAA,IACd,wBAAwB,CAAC;AAAA,EAC3B;AAGA,aAAW,SAAS,SAAS,OAAO;AAClC,UAAM,cAAc,MAAM,qBAAqB,OAAO,QAAQ;AAC9D,WAAO,aAAa,KAAK,WAAW;AAAA,EACtC;AAGA,aAAW,QAAQ,SAAS,MAAM;AAChC,UAAM,cAAc,MAAM,iBAAiB,MAAM,QAAQ;AACzD,WAAO,YAAY,KAAK,WAAW;AAAA,EACrC;AAGA,aAAW,QAAQ,SAAS,MAAM;AAChC,UAAM,cAAc,MAAM,iBAAiB,MAAM,QAAQ;AACzD,WAAO,YAAY,KAAK,WAAW;AAAA,EACrC;AAGA,aAAW,cAAc,SAAS,kBAAkB;AAClD,UAAM,cAAc,MAAM,sBAAsB,YAAY,QAAQ;AACpE,WAAO,uBAAuB,KAAK,WAAW;AAAA,EAChD;AAGA,QAAM,aAAa;AAAA,IACjB,GAAG,OAAO;AAAA,IACV,GAAG,OAAO;AAAA,IACV,GAAG,OAAO;AAAA,IACV,GAAG,OAAO;AAAA,EACZ;AAEA,MAAI,WAAW,MAAM,OAAK,EAAE,WAAW,MAAM,GAAG;AAC9C,WAAO,gBAAgB;AAAA,EACzB,WAAW,WAAW,KAAK,OAAK,EAAE,WAAW,MAAM,GAAG;AACpD,WAAO,gBAAgB;AAAA,EACzB,OAAO;AACL,WAAO,gBAAgB;AAAA,EACzB;AAEA,SAAO;AACT;AAKA,eAAe,qBACb,OACA,UACwF;AACxF,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AACH,aAAO,oBAAoB,KAAK;AAAA,IAClC,KAAK;AACH,aAAO,qBAAqB,KAAK;AAAA,IACnC,KAAK;AACH,aAAO,oBAAoB,KAAK;AAAA,IAClC;AACE,aAAO,EAAE,WAAW,MAAM,aAAa,QAAQ,UAAU;AAAA,EAC7D;AACF;AAKA,eAAe,oBACb,OACwF;AACxF,QAAM,aAAa,MAAM,YAAY,MAAM,gBAAgB;AAC3D,QAAM,aAAa,MAAM,YAAY,MAAM,iBAAiB;AAE5D,MAAI,YAAY;AACd,UAAM,YAAY,WAAW,CAAC;AAC9B,UAAM,aAAa,MAAM,UAAU,UAAU,MAAM,SAAS,QAAQ,UAAU;AAC9E,UAAM,cAAc,MAAM,UAAU,UAAU,MAAM,YAAY,aAAa,SAAS,CAAC,SAAS,aAAa;AAE7G,QAAI,WAAW,SAAS,KAAK,YAAY,SAAS,GAAG;AACnD,aAAO;AAAA,QACL,WAAW,MAAM;AAAA,QACjB,QAAQ;AAAA,QACR,UAAU,WAAW,CAAC,KAAK,YAAY,CAAC;AAAA,MAC1C;AAAA,IACF;AAEA,WAAO;AAAA,MACL,WAAW,MAAM;AAAA,MACjB,QAAQ;AAAA,MACR,UAAU,UAAK,SAAS;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO,EAAE,WAAW,MAAM,aAAa,QAAQ,UAAU;AAC3D;AAKA,eAAe,qBACb,OACwF;AACxF,QAAM,cAAc,MAAM,YAAY,MAAM,aAAa;AACzD,QAAM,aAAa,MAAM,YAAY,MAAM,WAAW;AAEtD,QAAM,aAAa,cAAc,CAAC,KAAK,aAAa,CAAC;AAErD,MAAI,YAAY;AACd,UAAM,YAAY;AAAA,MAChB,GAAI,MAAM,UAAU,UAAU,oBAAoB,aAAa;AAAA,MAC/D,GAAI,MAAM,UAAU,UAAU,kBAAkB,cAAc;AAAA,IAChE;AAEA,eAAW,MAAM,WAAW;AAC1B,YAAM,UAAU,MAAM,UAAU,KAAK,EAAE;AACvC,UAAI,QAAQ,SAAS,UAAU,GAAG;AAChC,eAAO;AAAA,UACL,WAAW,MAAM;AAAA,UACjB,QAAQ;AAAA,UACR,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,WAAW,MAAM;AAAA,MACjB,QAAQ;AAAA,MACR,UAAU,gBAAM,UAAU;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO,EAAE,WAAW,MAAM,aAAa,QAAQ,UAAU;AAC3D;AAKA,eAAe,oBACb,OACwF;AAExF,QAAM,YAAY,MAAM,YAAY,MAAM,gBAAgB;AAC1D,MAAI,WAAW;AACb,WAAO;AAAA,MACL,WAAW,MAAM;AAAA,MACjB,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,SAAO,EAAE,WAAW,MAAM,aAAa,QAAQ,UAAU;AAC3D;AAKA,eAAe,iBACb,MACA,UAC6G;AAC7G,MAAI,KAAK,KAAK;AACZ,UAAM,WAAW,MAAM,8BAA8B,KAAK,GAAG;AAC7D,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,QAAQ,SAAS;AAAA,MACjB,WAAW,KAAK;AAAA,MAChB,cAAc,SAAS;AAAA,IACzB;AAAA,EACF;AAEA,MAAI,KAAK,UAAU;AACjB,UAAM,UAAU,MAAM,kBAAkB,KAAK,QAAQ;AACrD,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,QAAQ,QAAQ;AAAA,IAClB;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,KAAK,aAAa,QAAQ,UAAU;AACvD;AAKA,eAAe,8BACb,SACyE;AACzE,QAAM,WAAW,QAAQ,MAAM,wCAAwC;AACvE,MAAI,CAAC,UAAU;AACb,WAAO,EAAE,QAAQ,UAAU;AAAA,EAC7B;AAEA,QAAM,SAAS,SAAS,CAAC,EAAE,YAAY;AACvC,QAAMC,SAAO,MAAM,SAAS,CAAC;AAE7B,QAAM,kBAAkB,MAAM,UAAU,UAAU,uBAAuB,aAAa;AAEtF,aAAW,MAAM,iBAAiB;AAChC,UAAM,UAAU,MAAM,UAAU,KAAK,EAAE;AAEvC,QAAI,QAAQ,SAAS,IAAIA,MAAI,GAAG,KAAK,QAAQ,SAAS,IAAIA,MAAI,IAAI,GAAG;AACnE,YAAM,gBAA0C;AAAA,QAC9C,KAAK,CAAC,eAAe,6CAA6C;AAAA,QAClE,MAAM,CAAC,gBAAgB,8CAA8C;AAAA,QACrE,KAAK,CAAC,eAAe,6CAA6C;AAAA,QAClE,QAAQ,CAAC,kBAAkB,gDAAgD;AAAA,MAC7E;AAEA,iBAAW,cAAc,cAAc,MAAM,KAAK,CAAC,GAAG;AACpD,YAAI,QAAQ,SAAS,UAAU,GAAG;AAChC,iBAAO,EAAE,QAAQ,QAAQ,cAAc,IAAI;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAKA,eAAe,kBACb,UACkD;AAClD,QAAM,iBAAiB,MAAM,UAAU,UAAU,YAAY,cAAc;AAC3E,QAAM,YAAY,MAAM,UAAU,UAAU,YAAY,cAAc;AAEtE,QAAM,WAAW,CAAC,GAAG,gBAAgB,GAAG,SAAS;AAEjD,aAAW,MAAM,UAAU;AACzB,UAAM,UAAU,MAAM,UAAU,KAAK,EAAE;AACvC,QAAI,QAAQ,SAAS,QAAQ,KAAK,QAAQ,YAAY,EAAE,SAAS,SAAS,YAAY,CAAC,GAAG;AACxF,aAAO,EAAE,QAAQ,OAAO;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,UAAU;AAC7B;AAKA,eAAe,iBACb,MACA,UACgH;AAChH,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AACH,aAAO,qBAAqB,IAAI;AAAA,IAClC,KAAK;AACH,aAAO,kBAAkB,IAAI;AAAA,IAC/B,KAAK;AACH,aAAO,iBAAiB,IAAI;AAAA,IAC9B,KAAK;AACH,aAAO,eAAe,IAAI;AAAA,IAC5B;AACE,aAAO,EAAE,QAAQ,KAAK,aAAa,QAAQ,UAAU;AAAA,EACzD;AACF;AAKA,eAAe,qBACb,MACgH;AAChH,QAAM,YAAY,KAAK,YAAY,MAAM,aAAa;AACtD,QAAM,aAAa,KAAK,YAAY,MAAM,QAAQ;AAElD,MAAI,YAAY;AACd,UAAM,aAAa,MAAM,UAAU,UAAU,mBAAmB,aAAa;AAC7E,QAAI,WAAW,SAAS,GAAG;AACzB,aAAO,EAAE,QAAQ,KAAK,aAAa,QAAQ,QAAQ,eAAe,YAAY;AAAA,IAChF;AACA,WAAO,EAAE,QAAQ,KAAK,aAAa,QAAQ,UAAU;AAAA,EACvD;AAEA,MAAI,WAAW;AACb,WAAO,EAAE,QAAQ,KAAK,aAAa,QAAQ,WAAW,eAAe,QAAQ,UAAU,CAAC,CAAC,GAAG;AAAA,EAC9F;AAEA,SAAO,EAAE,QAAQ,KAAK,aAAa,QAAQ,UAAU;AACvD;AAKA,eAAe,kBACb,MACgH;AAChH,QAAM,aAAa,KAAK,YAAY,MAAM,WAAW;AACrD,MAAI,YAAY;AACd,UAAM,YAAY,WAAW,CAAC;AAC9B,UAAM,YAAY;AAAA,MAChB,GAAI,MAAM,UAAU,UAAU,oBAAoB,aAAa;AAAA,MAC/D,GAAI,MAAM,UAAU,UAAU,kBAAkB,cAAc;AAAA,IAChE;AAEA,eAAW,MAAM,WAAW;AAC1B,YAAM,UAAU,MAAM,UAAU,KAAK,EAAE;AACvC,UAAI,QAAQ,SAAS,SAAS,GAAG;AAC/B,eAAO,EAAE,QAAQ,KAAK,aAAa,QAAQ,QAAQ,eAAe,UAAU;AAAA,MAC9E;AAAA,IACF;AAEA,WAAO,EAAE,QAAQ,KAAK,aAAa,QAAQ,QAAQ,eAAe,UAAU;AAAA,EAC9E;AAEA,SAAO,EAAE,QAAQ,KAAK,aAAa,QAAQ,UAAU;AACvD;AAKA,eAAe,iBACb,MACgH;AAChH,SAAO,EAAE,QAAQ,KAAK,aAAa,QAAQ,UAAU;AACvD;AAKA,eAAe,eACb,MACgH;AAChH,SAAO,EAAE,QAAQ,KAAK,aAAa,QAAQ,UAAU;AACvD;AAKA,eAAe,sBACb,YACA,UAC4G;AAC5G,QAAM,EAAE,MAAM,SAAS,GAAG,IAAI;AAE9B,QAAM,YAAY;AAAA,IAChB,GAAI,MAAM,UAAU,UAAU,oBAAoB,aAAa;AAAA,IAC/D,GAAI,MAAM,UAAU,UAAU,kBAAkB,cAAc;AAAA,IAC9D,GAAI,MAAM,UAAU,UAAU,iBAAiB,cAAc;AAAA,EAC/D;AAEA,QAAM,aAAa,MAAM,iBAAiB,MAAM,SAAS;AACzD,QAAM,WAAW,MAAM,iBAAiB,IAAI,SAAS;AAErD,MAAI,CAAC,cAAc,CAAC,UAAU;AAC5B,WAAO;AAAA,MACL,YAAY,KAAK,IAAI,eAAU,EAAE;AAAA,MACjC,QAAQ;AAAA,MACR,WAAW,aAAa,WAAM;AAAA,MAC9B,SAAS,WAAW,WAAM;AAAA,IAC5B;AAAA,EACF;AAEA,QAAM,eAAe,MAAM,UAAU,UAAU,qBAAqB,aAAa;AAEjF,aAAW,MAAM,cAAc;AAC7B,UAAM,UAAU,MAAM,UAAU,KAAK,EAAE;AACvC,UAAM,iBAAiB;AAAA,MACrB,IAAI,OAAO,GAAG,IAAI,iBAAY,EAAE,IAAI,GAAG;AAAA,MACvC,IAAI,OAAO,WAAW,IAAI,aAAa,EAAE,IAAI,GAAG;AAAA,IAClD;AAEA,eAAW,WAAW,gBAAgB;AACpC,UAAI,QAAQ,KAAK,OAAO,GAAG;AACzB,eAAO;AAAA,UACL,YAAY,KAAK,IAAI,eAAU,EAAE,OAAO,OAAO;AAAA,UAC/C,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,YAAY,KAAK,IAAI,eAAU,EAAE,OAAO,OAAO;AAAA,IAC/C,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AACF;AAKA,eAAe,iBAAiB,OAAe,OAAmC;AAChF,aAAW,QAAQ,OAAO;AACxB,QAAI;AACF,YAAM,UAAU,MAAM,UAAU,KAAK,IAAI;AACzC,UAAI,QAAQ,SAAS,KAAK,KAAK,QAAQ,SAAS,IAAI,KAAK,GAAG,GAAG;AAC7D,eAAO;AAAA,MACT;AAAA,IACF,QAAQ;AACN;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAKA,SAAS,oBAAoB,QAA8B;AACzD,QAAM,OAAO,OAAO,kBAAkB,SAAS,WAAM,OAAO,kBAAkB,SAAS,WAAM;AAC7F,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,KAAK,IAAI,kBAAQ,OAAO,aAAa,EAAE;AAEnD,QAAM,YAAY,OAAO,aAAa,OAAO,OAAK,EAAE,WAAW,MAAM,EAAE;AACvE,QAAM,WAAW,OAAO,YAAY,OAAO,OAAK,EAAE,WAAW,MAAM,EAAE;AACrE,QAAM,WAAW,OAAO,YAAY,OAAO,OAAK,EAAE,WAAW,MAAM,EAAE;AACrE,QAAM,YAAY,OAAO,uBAAuB,OAAO,OAAK,EAAE,WAAW,MAAM,EAAE;AAEjF,UAAQ,IAAI,cAAc,SAAS,IAAI,OAAO,aAAa,MAAM,EAAE;AACnE,UAAQ,IAAI,cAAc,QAAQ,IAAI,OAAO,YAAY,MAAM,EAAE;AACjE,UAAQ,IAAI,cAAc,QAAQ,IAAI,OAAO,YAAY,MAAM,EAAE;AACjE,UAAQ,IAAI,cAAc,SAAS,IAAI,OAAO,uBAAuB,MAAM,EAAE;AAC/E;AAKA,eAAe,kBAAkB,UAAkB,SAA0C;AAC3F,QAAM,YAAY;AAClB,QAAM,UAAU,UAAU,SAAS;AAEnC,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AACtD,QAAM,WAAWA,OAAK,SAAS,UAAU,KAAK;AAC9C,QAAM,aAAaA,OAAK,KAAK,WAAW,GAAG,SAAS,IAAI,QAAQ,SAAS;AAEzE,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,gCAAY;AACvB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,0BAAgB,QAAQ,EAAE;AACrC,QAAM,KAAK,kCAAa,oBAAI,KAAK,GAAE,eAAe,OAAO,CAAC,EAAE;AAC5D,QAAM,KAAK,iCAAa,QAAQ,MAAM,EAAE;AACxC,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,6BAAS;AACpB,QAAM,KAAK,EAAE;AAEb,MAAI,YAAY;AAChB,MAAI,YAAY;AAEhB,aAAW,KAAK,SAAS;AACvB,UAAM,aAAa,EAAE,kBAAkB,SAAS,WAAM,EAAE,kBAAkB,SAAS,WAAM;AACzF,UAAM,YAAY,EAAE,aAAa,MAAM,OAAK,EAAE,WAAW,MAAM,IAAI,WACjD,EAAE,aAAa,KAAK,OAAK,EAAE,WAAW,MAAM,IAAI,WAAM;AACxE,UAAM,WAAW,EAAE,YAAY,MAAM,OAAK,EAAE,WAAW,MAAM,IAAI,WAChD,EAAE,YAAY,KAAK,OAAK,EAAE,WAAW,MAAM,IAAI,WAAM;AACtE,UAAM,WAAW,EAAE,YAAY,MAAM,OAAK,EAAE,WAAW,MAAM,IAAI,WAChD,EAAE,YAAY,KAAK,OAAK,EAAE,WAAW,MAAM,IAAI,WAAM;AACtE,UAAM,YAAY,EAAE,uBAAuB,MAAM,OAAK,EAAE,WAAW,MAAM,IAAI,WAC3D,EAAE,uBAAuB,KAAK,OAAK,EAAE,WAAW,MAAM,IAAI,WAAM;AAElF,UAAM,KAAK,KAAK,UAAU,IAAI,EAAE,aAAa,YAAY,SAAS,SAAS,QAAQ,SAAS,QAAQ,UAAU,SAAS,EAAE;AAEzH,QAAI,EAAE,kBAAkB,OAAQ;AAChC,QAAI,EAAE,kBAAkB,OAAQ;AAAA,EAClC;AAEA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,qBAAW,SAAS,wBAAS,SAAS,wBAAS,QAAQ,SAAS,YAAY,SAAS,2BAAO;AACvG,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,yCAAW;AACtB,QAAM,KAAK,EAAE;AAEb,aAAW,KAAK,SAAS;AACvB,UAAM,KAAK,qBAAW,EAAE,aAAa,EAAE;AACvC,UAAM,KAAK,EAAE;AAEb,UAAM,KAAK,uCAAmB;AAC9B,eAAW,KAAK,EAAE,cAAc;AAC9B,YAAM,OAAO,EAAE,WAAW,SAAS,WAAM,EAAE,WAAW,SAAS,WAAM;AACrE,YAAM,KAAK,KAAK,IAAI,IAAI,EAAE,SAAS,EAAE;AACrC,UAAI,EAAE,UAAU;AACd,cAAM,KAAK,qBAAW,EAAE,QAAQ,EAAE;AAAA,MACpC;AAAA,IACF;AACA,UAAM,KAAK,EAAE;AAEb,UAAM,KAAK,sCAAkB;AAC7B,eAAW,KAAK,EAAE,aAAa;AAC7B,YAAM,OAAO,EAAE,WAAW,SAAS,WAAM,EAAE,WAAW,SAAS,WAAM;AACrE,YAAM,KAAK,KAAK,IAAI,IAAI,EAAE,MAAM,EAAE;AAClC,UAAI,EAAE,WAAW;AACf,cAAM,KAAK,YAAY,EAAE,SAAS,EAAE;AAAA,MACtC;AAAA,IACF;AACA,UAAM,KAAK,EAAE;AAEb,UAAM,KAAK,sCAAkB;AAC7B,eAAW,KAAK,EAAE,aAAa;AAC7B,YAAM,OAAO,EAAE,WAAW,SAAS,WAAM,EAAE,WAAW,SAAS,WAAM;AACrE,YAAM,KAAK,KAAK,IAAI,IAAI,EAAE,MAAM,EAAE;AAAA,IACpC;AACA,UAAM,KAAK,EAAE;AAEb,UAAM,KAAK,+BAAW;AACtB,eAAW,KAAK,EAAE,wBAAwB;AACxC,YAAM,OAAO,EAAE,WAAW,SAAS,WAAM,EAAE,WAAW,SAAS,WAAM;AACrE,YAAM,KAAK,KAAK,IAAI,IAAI,EAAE,UAAU,EAAE;AAAA,IACxC;AACA,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,UAAU,MAAM,YAAY,MAAM,KAAK,IAAI,CAAC;AAElD,SAAO,QAAQ,mDAAgB,UAAU,EAAE;AAC7C;AAKA,eAAe,cAAc,UAAkB,SAA0C;AACvF,QAAM,YAAY,QAAQ,MAAM,OAAK,EAAE,kBAAkB,MAAM;AAE/D,MAAI,WAAW;AACb,WAAO,QAAQ,uDAAe;AAAA,EAChC,OAAO;AACL,UAAM,cAAc,QAAQ,OAAO,OAAK,EAAE,kBAAkB,MAAM,EAAE;AACpE,WAAO,KAAK,GAAG,WAAW,iFAAgB;AAAA,EAC5C;AACF;AA55CA,IAmDa;AAnDb;AAAA;AAAA;AAAA;AAGA;AACA;AACA;AA8CO,IAAM,gBAAgB,IAAIF,SAAQ,QAAQ,EAC9C,SAAS,eAAe,+BAAW,EACnC,YAAY,uHAAwB,EACpC,OAAO,iBAAiB,8FAAuC,aAAa,EAC5E,OAAO,mBAAmB,oDAAiB,EAC3C,OAAO,OAAO,UAAU,YAAY;AACnC,UAAI;AACF,eAAO,OAAO,0BAAM;AACpB,eAAO,QAAQ;AAGf,cAAM,eAAe,MAAM,UAAU,OAAO,eAAe;AAC3D,YAAI,CAAC,cAAc;AACjB,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,0GAA8C;AAC1D,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,eAAO,QAAQ,kDAAU;AAEzB,YAAI,QAAQ,SAAS,OAAO;AAE1B,gBAAM,iBAAiB,UAAU,QAAQ,QAAQ;AAAA,QACnD,OAAO;AAEL,gBAAM,yBAAyB,QAAQ;AAAA,QACzC;AAEA,eAAO,OAAO,2BAAO;AACrB,eAAO,QAAQ;AAAA,MACjB,SAAS,OAAY;AACnB,eAAO,MAAM,6BAAS,MAAM,OAAO,EAAE;AACrC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;ACxFH,SAAS,WAAAM,gBAAe;AACxB,OAAOC,eAAc;AACrB,OAAOC,YAAU;AACjB,OAAOC,SAAQ;AA+Kf,eAAe,oBAAoB,aAAwC;AACzE,QAAM,UAAoB,CAAC;AAG3B,QAAM,iBAAiBD,OAAK,KAAK,aAAa,iBAAiB;AAC/D,MAAI,MAAM,UAAU,OAAO,cAAc,GAAG;AAC1C,UAAM,UAAU,MAAM,UAAU,KAAK,cAAc;AACnD,UAAM,iBAAiB,QAAQ,MAAM,sBAAsB;AAC3D,QAAI,gBAAgB;AAClB,iBAAW,SAAS,gBAAgB;AAClC,cAAM,aAAa,MAAM,QAAQ,eAAe,EAAE,EAAE,QAAQ,KAAK,EAAE;AACnE,gBAAQ,KAAK,UAAU;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAGA,QAAM,cAAcA,OAAK,KAAK,aAAa,SAAS;AACpD,MAAI,MAAM,UAAU,OAAO,WAAW,GAAG;AACvC,UAAM,UAAU,MAAMC,IAAG,QAAQ,aAAa,EAAE,eAAe,KAAK,CAAC;AACrE,eAAW,SAAS,SAAS;AAC3B,UAAI,MAAM,YAAY,KAAK,CAAC,MAAM,KAAK,WAAW,GAAG,KAAK,MAAM,SAAS,OAAO;AAC9E,YAAI,CAAC,QAAQ,SAAS,MAAM,IAAI,GAAG;AACjC,kBAAQ,KAAK,MAAM,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKA,eAAe,cAAc,aAAsC;AAEjE,QAAM,cAAcD,OAAK,KAAK,aAAa,WAAW,cAAc;AACpE,MAAI,MAAM,UAAU,OAAO,WAAW,GAAG;AACvC,UAAM,UAAU,MAAM,UAAU,KAAK,WAAW;AAChD,UAAM,aAAa,QAAQ,MAAM,8BAA8B;AAC/D,QAAI,YAAY;AACd,aAAO,WAAW,CAAC;AAAA,IACrB;AAAA,EACF;AAGA,QAAM,kBAAkBA,OAAK,KAAK,aAAa,cAAc;AAC7D,MAAI,MAAM,UAAU,OAAO,eAAe,GAAG;AAC3C,UAAM,UAAU,MAAM,UAAU,KAAK,eAAe;AACpD,UAAM,aAAa,QAAQ,MAAM,8BAA8B;AAC/D,QAAI,YAAY;AACd,aAAO,WAAW,CAAC;AAAA,IACrB;AAAA,EACF;AAGA,QAAM,cAAcA,OAAK,KAAK,aAAa,SAAS;AACpD,MAAI,MAAM,UAAU,OAAO,WAAW,GAAG;AACvC,UAAM,UAAU,MAAMC,IAAG,QAAQ,aAAa,EAAE,eAAe,KAAK,CAAC;AACrE,eAAW,SAAS,SAAS;AAC3B,UAAI,MAAM,YAAY,KAAK,CAAC,MAAM,KAAK,WAAW,GAAG,GAAG;AACtD,cAAM,UAAUD,OAAK,KAAK,aAAa,MAAM,MAAM,OAAO,QAAQ,MAAM;AACxE,YAAI,MAAM,UAAU,OAAO,OAAO,GAAG;AACnC,gBAAM,WAAW,MAAMC,IAAG,QAAQ,OAAO;AACzC,cAAI,SAAS,SAAS,GAAG;AACvB,mBAAO,SAAS,CAAC;AAAA,UACnB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AACT;AAKA,eAAe,sBAAsB,aAAsC;AACzE,QAAM,iBAAiBD,OAAK,KAAK,aAAa,iBAAiB;AAC/D,MAAI,MAAM,UAAU,OAAO,cAAc,GAAG;AAC1C,UAAM,UAAU,MAAM,UAAU,KAAK,cAAc;AACnD,UAAM,YAAY,QAAQ,MAAM,0CAA0C;AAC1E,QAAI,WAAW;AACb,aAAO,UAAU,CAAC;AAAA,IACpB;AAAA,EACF;AAGA,SAAOA,OAAK,SAAS,WAAW;AAClC;AAKA,eAAe,sBACb,aACA,QACA,SACe;AACf,QAAM,aAAaA,OAAK,KAAK,aAAa,WAAW,OAAO,IAAI;AAEhE,SAAO,KAAK,yCAAW,OAAO,IAAI,KAAK;AAGvC,QAAM,WAAW;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,aAAW,OAAO,UAAU;AAC1B,UAAM,UAAU,UAAUA,OAAK,KAAK,YAAY,GAAG,CAAC;AAAA,EACtD;AAGA,QAAM,cAAc,OAAO,YAAY,MAAM,GAAG;AAChD,MAAI,WAAWA,OAAK,KAAK,YAAY,OAAO,QAAQ,MAAM;AAG1D,MAAI,OAAO,SAAS,WAAW;AAE7B,eAAW,UAAU,CAAC,cAAc,WAAW,UAAU,UAAU,OAAO,QAAQ,GAAG;AACnF,YAAM,UAAU,UAAUA,OAAK,KAAK,UAAU,GAAG,aAAa,MAAM,CAAC;AAAA,IACvE;AAGA,UAAME;AAAA,MACJF,OAAK,KAAK,UAAU,GAAG,aAAa,UAAU,GAAG,OAAO,gBAAgB,OAAO;AAAA,MAC/E,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EAEF,WAAW,OAAO,SAAS,OAAO;AAEhC,eAAW,UAAU,CAAC,SAAS,YAAY,SAAS,WAAW,GAAG;AAChE,YAAM,UAAU,UAAUA,OAAK,KAAK,UAAU,GAAG,aAAa,MAAM,CAAC;AAAA,IACvE;AAAA,EAEF,OAAO;AAEL,eAAW,UAAU,CAAC,QAAQ,UAAU,UAAU,SAAS,GAAG;AAC5D,YAAM,UAAU,UAAUA,OAAK,KAAK,UAAU,GAAG,aAAa,MAAM,CAAC;AAAA,IACvE;AAAA,EACF;AAGA,QAAMG;AAAA,IACJH,OAAK,KAAK,YAAY,cAAc;AAAA,IACpC;AAAA,IACA;AAAA,EACF;AAGA,QAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBlB,QAAM,UAAU,MAAMA,OAAK,KAAK,YAAY,YAAY,GAAG,SAAS;AAEpE,SAAO,QAAQ,gBAAM,OAAO,IAAI,2BAAO;AACzC;AAKA,eAAeE,wBACb,UACA,aACA,WACe;AACf,QAAM,UAAU,WAAW,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAStB,WAAW;AAAA;AAAA,eAEd,SAAS;AAAA;AAAA;AAAA,6DAGqC,SAAS;AAAA,oBAClD,SAAS;AAAA;AAAA;AAAA;AAI3B,QAAM,UAAU,MAAM,UAAU,OAAO;AACzC;AAKA,eAAeC,yBACb,UACA,QACA,SACe;AACf,MAAI,eAAe;AAEnB,MAAI,OAAO,SAAS,WAAW;AAC7B,mBAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUjB,WAAW,OAAO,SAAS,OAAO;AAChC,mBAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,OAAO;AACL,mBAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjB;AAEA,QAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAMP,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWhB,YAAY;AAAA;AAEZ,QAAM,UAAU,MAAM,UAAU,OAAO;AACzC;AAKA,eAAe,qBACb,aACA,iBACA,YACe;AACf,QAAM,eAAeH,OAAK,KAAK,aAAa,WAAW,iBAAiB;AAExE,MAAI,UAAU;AACd,MAAI,MAAM,UAAU,OAAO,YAAY,GAAG;AACxC,cAAU,MAAM,UAAU,KAAK,YAAY;AAAA,EAC7C,OAAO;AACL,cAAU,uBAAuB,eAAe;AAAA;AAAA,EAElD;AAGA,QAAM,kBAAkB,oBAAI,IAAY;AACxC,QAAM,gBAAgB,QAAQ,SAAS,sBAAsB;AAC7D,aAAW,SAAS,eAAe;AACjC,oBAAgB,IAAI,MAAM,CAAC,CAAC;AAAA,EAC9B;AAGA,aAAW,UAAU,YAAY;AAC/B,QAAI,CAAC,gBAAgB,IAAI,OAAO,IAAI,GAAG;AACrC,sBAAgB,IAAI,OAAO,IAAI;AAAA,IACjC;AAAA,EACF;AAGA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,uBAAuB,eAAe,GAAG;AACpD,QAAM,KAAK,EAAE;AAGb,QAAM,aAAa,MAAM,KAAK,eAAe,EAAE,KAAK;AACpD,aAAW,UAAU,YAAY;AAC/B,UAAM,KAAK,YAAY,MAAM,GAAG;AAAA,EAClC;AAEA,QAAM,UAAU,MAAM,cAAc,MAAM,KAAK,IAAI,CAAC;AACpD,SAAO,QAAQ,oCAAqB;AACtC;AAKA,SAASI,cAAa,KAAqB;AACzC,SAAO,IACJ,MAAM,MAAM,EACZ,IAAI,UAAQ,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,EACtE,KAAK,EAAE;AACZ;AA7fA,IAoBa;AApBb;AAAA;AAAA;AAAA;AAIA;AACA;AAeO,IAAM,mBAAmB,IAAIN,SAAQ,YAAY,EACrD,YAAY,iGAA2B,EACvC,OAAO,YAAY;AAClB,UAAI;AACF,eAAO,OAAO,0BAAM;AACpB,eAAO,QAAQ;AAGf,cAAM,cAAc,QAAQ,IAAI;AAChC,cAAM,eAAe,MAAM,UAAU,OAAO,eAAe;AAC3D,YAAI,CAAC,cAAc;AACjB,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,kGAAkB;AAC9B,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,kBAAkB,MAAM,oBAAoB,WAAW;AAE7D,YAAI,gBAAgB,SAAS,GAAG;AAC9B,iBAAO,QAAQ,gDAAa,gBAAgB,KAAK,IAAI,CAAC,GAAG;AAAA,QAC3D,OAAO;AACL,iBAAO,KAAK,kDAAU;AAAA,QACxB;AACA,eAAO,QAAQ;AAGf,cAAM,UAAU,MAAM,cAAc,WAAW;AAC/C,eAAO,KAAK,gCAAiB,OAAO,EAAE;AACtC,eAAO,QAAQ;AAGf,cAAM,kBAAkB,MAAM,sBAAsB,WAAW;AAC/D,eAAO,KAAK,+CAAY,eAAe,EAAE;AACzC,eAAO,QAAQ;AAGf,cAAM,aAA6B,CAAC;AACpC,YAAI,UAAU;AACd,YAAI,cAAc;AAElB,eAAO,SAAS;AACd,gBAAM,mBAAmB,MAAMC,UAAS,OAAO;AAAA,YAC7C;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS,4BAAQ,WAAW;AAAA,cAC5B,UAAU,CAAC,UAAkB;AAC3B,oBAAI,CAAC,oBAAoB,KAAK,KAAK,GAAG;AACpC,yBAAO;AAAA,gBACT;AACA,oBAAI,gBAAgB,SAAS,KAAK,GAAG;AACnC,yBAAO;AAAA,gBACT;AACA,uBAAO;AAAA,cACT;AAAA,YACF;AAAA,UACF,CAAC;AAED,gBAAM,aAAa,iBAAiB;AAGpC,gBAAM,aAAa,MAAMA,UAAS,OAAO;AAAA,YACvC;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS,iBAAO,UAAU;AAAA,cAC1B,SAAS;AAAA,gBACP,EAAE,MAAM,2DAAmB,OAAO,UAAU;AAAA,gBAC5C,EAAE,MAAM,yEAAkB,OAAO,SAAS;AAAA,gBAC1C,EAAE,MAAM,iEAAoB,OAAO,MAAM;AAAA,cAC3C;AAAA,cACA,SAAS;AAAA,YACX;AAAA,UACF,CAAC;AAGD,gBAAM,iBAAiB,GAAG,OAAO,IAAI,UAAU;AAC/C,gBAAM,gBAAgB,MAAMA,UAAS,OAAO;AAAA,YAC1C;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,SAAS;AAAA,cACT,UAAU,CAAC,UAAkB;AAC3B,oBAAI,CAAC,sCAAsC,KAAK,KAAK,GAAG;AACtD,yBAAO;AAAA,gBACT;AACA,uBAAO;AAAA,cACT;AAAA,YACF;AAAA,UACF,CAAC;AAGD,gBAAM,aAAaK,cAAa,UAAU;AAC1C,gBAAM,cAAc,MAAML,UAAS,OAAO;AAAA,YACxC;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,SAAS,GAAG,UAAU;AAAA,YACxB;AAAA,UACF,CAAC;AAED,qBAAW,KAAK;AAAA,YACd,MAAM;AAAA,YACN,MAAM,WAAW;AAAA,YACjB,aAAa,cAAc;AAAA,YAC3B,kBAAkB,YAAY;AAAA,UAChC,CAAC;AAGD,gBAAM,aAAa,MAAMA,UAAS,OAAO;AAAA,YACvC;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,SAAS;AAAA,YACX;AAAA,UACF,CAAC;AACD,oBAAU,WAAW;AACrB;AAAA,QACF;AAEA,eAAO,QAAQ;AACf,eAAO,KAAK,mCAAU,WAAW,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AAC9D,eAAO,QAAQ;AAGf,mBAAW,UAAU,YAAY;AAC/B,gBAAM,sBAAsB,aAAa,QAAQ,OAAO;AAAA,QAC1D;AAGA,cAAM,qBAAqB,aAAa,iBAAiB,UAAU;AAEnE,eAAO,QAAQ;AACf,eAAO,QAAQ,uCAAS;AACxB,eAAO,QAAQ;AAGf,eAAO,KAAK,qBAAM;AAClB,eAAO,KAAK,iFAAmD;AAC/D,eAAO,KAAK,yDAA2B;AACvC,eAAO,QAAQ;AAAA,MAEjB,SAAS,OAAY;AACnB,eAAO,MAAM,yCAAW,MAAM,OAAO,EAAE;AACvC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;AC7KH,SAAS,WAAAM,gBAAe;AAGxB,SAAS,SAAAC,cAAa;AAHtB,IAQa;AARb;AAAA;AAAA;AAAA;AACA;AACA;AAMO,IAAM,cAAc,IAAID,SAAQ,MAAM,EAC1C,OAAO,SAAS,sCAAQ,EACxB,OAAO,mBAAmB,kDAAoB,EAC9C,YAAY,oEAAkB,EAC9B,OAAO,OAAO,YAAY;AACzB,UAAI;AACF,eAAO,OAAO,sCAAQ;AACtB,eAAO,QAAQ;AAGf,cAAM,eAAe,MAAM,UAAU,OAAO,eAAe;AAC3D,YAAI,CAAC,cAAc;AACjB,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,0GAA8C;AAC1D,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAQA,cAAM,UAAyD;AAAA,UAC7D,UAAU,EAAE,QAAQ,OAAO,QAAQ,OAAO,QAAQ,CAAC,EAAE;AAAA,UACrD,SAAS,EAAE,QAAQ,OAAO,QAAQ,OAAO,QAAQ,CAAC,EAAE;AAAA,QACtD;AAGA,cAAM,iBAAiB,MAAM,UAAU,OAAO,uBAAuB;AACrE,YAAI,gBAAgB;AAClB,kBAAQ,SAAS,SAAS;AAC1B,cAAI;AACF,mBAAO,KAAK,yCAAW;AAGvB,gBAAI,QAAQ,KAAK;AACf,oBAAMC,OAAM,OAAO,CAAC,OAAO,QAAQ,MAAM,OAAO,GAAG;AAAA,gBACjD,KAAK;AAAA,gBACL,OAAO;AAAA,cACT,CAAC;AAAA,YACH,OAAO;AACL,oBAAMA,OAAM,OAAO,CAAC,OAAO,MAAM,GAAG;AAAA,gBAClC,KAAK;AAAA,gBACL,OAAO;AAAA,cACT,CAAC;AAAA,YACH;AAGA,gBAAI,QAAQ,cAAc,OAAO;AAC/B,kBAAI;AACF,uBAAO,KAAK,iEAAyB;AACrC,sBAAMA,OAAM,OAAO,CAAC,OAAO,UAAU,GAAG;AAAA,kBACtC,KAAK;AAAA,kBACL,OAAO;AAAA,gBACT,CAAC;AAAA,cACH,SAAS,UAAe;AACtB,uBAAO,KAAK,+HAAgC;AAC5C,oBAAI,QAAQ,IAAI,OAAO;AACrB,0BAAQ,IAAI,SAAS,MAAM;AAAA,gBAC7B;AAEA,wBAAQ,SAAS,OAAO,KAAK,kFAA2B;AAAA,cAC1D;AAAA,YACF;AAEA,oBAAQ,SAAS,SAAS;AAC1B,mBAAO,QAAQ,kDAAU;AAAA,UAC3B,SAAS,OAAY;AACnB,oBAAQ,SAAS,OAAO,KAAK,MAAM,OAAO;AAC1C,mBAAO,MAAM,qDAAa,MAAM,OAAO,EAAE;AAAA,UAC3C;AAAA,QACF,OAAO;AACL,iBAAO,KAAK,oEAAiC;AAAA,QAC/C;AAEA,eAAO,QAAQ;AAGf,cAAM,gBAAgB,MAAM,UAAU,OAAO,sBAAsB,KAC5C,MAAM,UAAU,OAAO,iBAAiB;AAC/D,YAAI,eAAe;AACjB,kBAAQ,QAAQ,SAAS;AAGzB,gBAAM,YAAY,MAAM,UAAU,OAAO,sBAAsB,KAC7C,MAAM,UAAU,OAAO,0BAA0B;AACnE,gBAAM,WAAW,MAAM,UAAU,OAAO,iBAAiB;AAEzD,cAAI;AACF,mBAAO,KAAK,yCAAW;AAEvB,gBAAI,WAAW;AAEb,kBAAI,QAAQ,KAAK;AACf,sBAAMA,OAAM,aAAa,CAAC,eAAe,GAAG;AAAA,kBAC1C,KAAK;AAAA,kBACL,OAAO;AAAA,gBACT,CAAC;AAAA,cACH;AACA,oBAAMA,OAAM,aAAa,CAAC,kBAAkB,aAAa,GAAG;AAAA,gBAC1D,KAAK;AAAA,gBACL,OAAO;AAAA,cACT,CAAC;AAAA,YACH,WAAW,UAAU;AAEnB,kBAAI,QAAQ,KAAK;AACf,sBAAMA,OAAM,UAAU,CAAC,gBAAgB,GAAG;AAAA,kBACxC,KAAK;AAAA,kBACL,OAAO;AAAA,gBACT,CAAC;AAAA,cACH;AACA,oBAAMA,OAAM,UAAU,CAAC,oBAAoB,SAAS,GAAG;AAAA,gBACrD,KAAK;AAAA,gBACL,OAAO;AAAA,cACT,CAAC;AAAA,YACH;AAEA,oBAAQ,QAAQ,SAAS;AACzB,mBAAO,QAAQ,kDAAU;AAAA,UAC3B,SAAS,OAAY;AACnB,oBAAQ,QAAQ,OAAO,KAAK,MAAM,OAAO;AACzC,mBAAO,MAAM,kDAAU;AAAA,UACzB;AAAA,QACF,OAAO;AACL,iBAAO,KAAK,0EAAkC;AAAA,QAChD;AAEA,eAAO,QAAQ;AACf,eAAO,UAAU,KAAK,EAAE;AACxB,eAAO,QAAQ;AAGf,YAAI,YAAY;AAEhB,YAAI,QAAQ,SAAS,QAAQ;AAC3B,cAAI,QAAQ,SAAS,QAAQ;AAC3B,mBAAO,QAAQ,mCAAU;AAAA,UAC3B,OAAO;AACL,mBAAO,MAAM,mCAAU;AACvB,wBAAY;AAAA,UACd;AAAA,QACF;AAEA,YAAI,QAAQ,QAAQ,QAAQ;AAC1B,cAAI,QAAQ,QAAQ,QAAQ;AAC1B,mBAAO,QAAQ,mCAAU;AAAA,UAC3B,OAAO;AACL,mBAAO,MAAM,mCAAU;AACvB,wBAAY;AAAA,UACd;AAAA,QACF;AAEA,eAAO,QAAQ;AAEf,YAAI,WAAW;AACb,iBAAO,MAAM,sCAAQ;AACrB,iBAAO,KAAK,yEAAiC;AAC7C,kBAAQ,KAAK,CAAC;AAAA,QAChB,OAAO;AACL,iBAAO,QAAQ,kDAAU;AAAA,QAC3B;AAAA,MACF,SAAS,OAAY;AACnB,eAAO,MAAM,yCAAW,MAAM,OAAO,EAAE;AACvC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;ACjLH,SAAS,WAAAC,iBAAe;AACxB,OAAOC,YAAU;AA6CjB,eAAe,qBAAoC;AACjD,SAAO,KAAK,2BAAO;AACnB,SAAO,QAAQ;AAGf,MAAI,MAAM,UAAU,OAAO,cAAc,GAAG;AAC1C,UAAM,UAAU,MAAM,UAAU,KAAK,cAAc;AACnD,UAAM,cAAc,QAAQ,MAAM,mBAAmB;AACrD,UAAM,eAAe,QAAQ,MAAM,mBAAmB;AACtD,UAAM,cAAc,QAAQ,MAAM,mBAAmB;AAErD,QAAI,YAAa,QAAO,KAAK,iBAAO,YAAY,CAAC,EAAE,KAAK,CAAC,EAAE;AAC3D,QAAI,aAAc,QAAO,KAAK,iBAAO,aAAa,CAAC,EAAE,KAAK,CAAC,EAAE;AAC7D,QAAI,YAAa,QAAO,KAAK,iBAAO,YAAY,CAAC,EAAE,KAAK,CAAC,EAAE;AAAA,EAC7D,OAAO;AACL,WAAO,KAAK,iCAAkB;AAAA,EAChC;AAEA,SAAO,QAAQ;AACjB;AAKA,eAAe,0BAAyC;AACtD,SAAO,KAAK,2BAAO;AACnB,SAAO,QAAQ;AAEf,QAAM,UAAU;AAChB,QAAM,SAAS,MAAM,UAAU,OAAO,OAAO;AAE7C,MAAI,CAAC,QAAQ;AACX,WAAO,KAAK,8BAAe;AAC3B,WAAO,QAAQ;AACf;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM,UAAU,UAAU,QAAQ,OAAO;AACvD,QAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,UAAU,CAAC;AAEzD,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,KAAK,8BAAe;AAC3B,WAAO,QAAQ;AACf;AAAA,EACF;AAGA,QAAM,YAID,CAAC;AAEN,aAAW,QAAQ,OAAO;AACxB,UAAM,WAAWA,OAAK,KAAK,SAAS,IAAI;AACxC,UAAM,UAAU,MAAM,UAAU,KAAK,QAAQ;AAC7C,UAAM,SAAS,UAAU,gBAAgB,OAAO;AAChD,UAAM,iBAAiB,UAAU,kBAAkB,MAAM;AAEzD,cAAU,KAAK;AAAA,MACb,MAAM,KAAK,QAAQ,OAAO,EAAE;AAAA,MAC5B,QAAQ;AAAA,MACR,UAAU,UAAU,YAAY,OAAO;AAAA,IACzC,CAAC;AAAA,EACH;AAGA,QAAM,YAAY,UAAU,IAAI,CAAC,SAAS;AAAA,IACxC,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EACP,CAAC;AAED,SAAO,MAAM,CAAC,gBAAM,gBAAM,cAAI,GAAG,SAAS;AAC1C,SAAO,QAAQ;AAGf,QAAM,YAAY,UAAU,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS,oBAAK,CAAC,EAAE;AACpE,QAAM,aAAa,UAAU,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS,oBAAK,CAAC,EAAE;AACrE,QAAM,UAAU,UAAU,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS,oBAAK,CAAC,EAAE;AAElE,SAAO,KAAK,iBAAO,UAAU,MAAM,0BAAW,SAAS,0BAAW,UAAU,0BAAW,OAAO,EAAE;AAChG,SAAO,QAAQ;AACjB;AAKA,eAAe,mBAAkC;AAC/C,QAAM,SAAS,MAAM,SAAS,UAAU;AAExC,MAAI,CAAC,QAAQ;AACX,WAAO,KAAK,2CAAkB;AAC9B,WAAO,QAAQ;AACf;AAAA,EACF;AAEA,MAAI;AACF,UAAM,SAAS,MAAM,SAAS,iBAAiB;AAC/C,UAAM,SAAS,MAAM,SAAS,iBAAiB;AAE/C,WAAO,KAAK,mBAAS;AACrB,WAAO,KAAK,iBAAO,MAAM,EAAE;AAC3B,WAAO,KAAK,iBAAO,MAAM,EAAE;AAC3B,WAAO,QAAQ;AAAA,EACjB,QAAQ;AACN,WAAO,KAAK,4CAAc;AAC1B,WAAO,QAAQ;AAAA,EACjB;AACF;AAKA,eAAe,wBAAuC;AACpD,SAAO,KAAK,2BAAO;AACnB,SAAO,QAAQ;AAGf,QAAM,aAAa;AACnB,QAAM,SAAS,MAAM,UAAU,OAAO,UAAU;AAEhD,MAAI,CAAC,QAAQ;AACX,WAAO,KAAK,oCAAW;AACvB,WAAO,QAAQ;AACf;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM,UAAU,UAAU,QAAQ,UAAU;AAC1D,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,KAAK,oCAAW;AACvB,WAAO,QAAQ;AACf;AAAA,EACF;AAGA,QAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC;AAEhD,aAAW,QAAQ,QAAQ;AACzB,UAAM,WAAWA,OAAK,KAAK,YAAY,IAAI;AAC3C,UAAM,OAAO,MAAM,UAAU,KAAK,QAAQ;AAC1C,UAAM,YAAY,KAAK,MAAM,sBAAsB;AACnD,UAAM,OAAO,YAAY,UAAU,CAAC,EAAE,KAAK,IAAI;AAG/C,UAAM,QAAQ,KAAK,MAAM,qBAAqB;AAC9C,UAAM,OAAO,QAAQ,MAAM,CAAC,IAAI;AAEhC,WAAO,KAAK,GAAG,IAAI,MAAM,IAAI,EAAE;AAAA,EACjC;AAEA,SAAO,QAAQ;AAEf,MAAI,MAAM,SAAS,GAAG;AACpB,WAAO,KAAK,iBAAO,MAAM,SAAS,CAAC,8CAAW;AAC9C,WAAO,QAAQ;AAAA,EACjB;AACF;AA3MA,IAQa;AARb;AAAA;AAAA;AAAA;AAEA;AACA;AAKO,IAAM,gBAAgB,IAAID,UAAQ,QAAQ,EAC9C,YAAY,sCAAQ,EACpB,OAAO,YAAY;AAClB,UAAI;AACF,eAAO,OAAO,0BAAM;AACpB,eAAO,QAAQ;AAGf,cAAM,eAAe,MAAM,UAAU,OAAO,eAAe;AAC3D,YAAI,CAAC,cAAc;AACjB,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,0GAA8C;AAC1D,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,mBAAmB;AAGzB,cAAM,wBAAwB;AAG9B,cAAM,iBAAiB;AAGvB,cAAM,sBAAsB;AAAA,MAC9B,SAAS,OAAY;AACnB,eAAO,MAAM,yCAAW,MAAM,OAAO,EAAE;AACvC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;ACzCH,SAAS,WAAAE,iBAAe;AACxB,OAAOC,YAAU;AAGjB,OAAOC,eAAc;AAwErB,eAAe,mBAAmB,UAAiC;AACjE,SAAO,KAAK,qDAAa;AAEzB,QAAM,aAAa;AACnB,QAAM,UAAU,oBAAI,IAAY;AAGhC,QAAM,aAAaD,OAAK,KAAK,YAAY,SAAS;AAClD,QAAM,gBAAgB,MAAM,UAAU,OAAO,UAAU;AAEvD,MAAI,eAAe;AAEjB,UAAM,UAAU,MAAM,oBAAoB,UAAU;AACpD,YAAQ,QAAQ,CAAC,MAAM,QAAQ,IAAI,CAAC,CAAC;AAGrC,UAAM,aAAa,MAAM,2BAA2B,UAAU;AAC9D,eAAW,QAAQ,CAAC,MAAM,QAAQ,IAAI,CAAC,CAAC;AAGxC,UAAM,cAAc,MAAM,uBAAuB,UAAU;AAC3D,gBAAY,QAAQ,CAAC,MAAM,QAAQ,IAAI,CAAC,CAAC;AAAA,EAC3C;AAGA,QAAM,cAAcA,OAAK,KAAK,YAAY,UAAU;AACpD,QAAM,iBAAiB,MAAM,UAAU,OAAO,WAAW;AAEzD,MAAI,gBAAgB;AAClB,UAAM,eAAe,MAAM,qBAAqB,WAAW;AAC3D,iBAAa,QAAQ,CAAC,MAAM,QAAQ,IAAI,CAAC,CAAC;AAAA,EAC5C;AAEA,MAAI,QAAQ,SAAS,GAAG;AACtB,WAAO,KAAK,oEAAa;AACzB;AAAA,EACF;AAGA,QAAM,gBAA0B,CAAC;AACjC,aAAW,OAAO,SAAS;AACzB,UAAM,cAAc,MAAM,kBAAkB,KAAK,YAAY;AAC7D,QAAI,eAAe,CAAC,cAAc,SAAS,WAAW,GAAG;AACvD,oBAAc,KAAK,WAAW;AAAA,IAChC;AAAA,EACF;AAEA,MAAI,cAAc,WAAW,GAAG;AAC9B,WAAO,KAAK,kGAAuB;AACnC;AAAA,EACF;AAGA,SAAO,QAAQ,sBAAO,cAAc,MAAM,kCAAS;AACnD,aAAW,QAAQ,eAAe;AAChC,WAAO,KAAK,KAAK,IAAI,EAAE;AAAA,EACzB;AACA,SAAO,QAAQ;AAGf,QAAM,UAAU,MAAMC,UAAS,OAAO;AAAA,IACpC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,MAAI,QAAQ,YAAY;AACtB,UAAM,uBAAuB,UAAU,aAAa;AACpD,WAAO,QAAQ,4CAAS;AAAA,EAC1B;AACF;AAKA,eAAe,oBAAoB,YAAuC;AACxE,QAAM,OAAiB,CAAC;AACxB,QAAM,SAASD,OAAK,KAAK,YAAY,KAAK;AAE1C,MAAI;AAEF,UAAM,YAAY,MAAM,UAAU,UAAU,UAAU,MAAM;AAE5D,eAAW,QAAQ,WAAW;AAC5B,YAAM,WAAWA,OAAK,KAAK,QAAQ,IAAI;AACvC,YAAM,UAAU,MAAM,UAAU,KAAK,QAAQ;AAG7C,YAAM,YAAY;AAClB,UAAI;AACJ,cAAQ,QAAQ,UAAU,KAAK,OAAO,OAAO,MAAM;AACjD,cAAM,WAAW,MAAM,CAAC;AAExB,cAAM,QAAQ,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AAChD,YAAI,MAAM,SAAS,GAAG;AACpB,eAAK,KAAK,MAAM,CAAC,CAAC;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AAAA,EAEhB;AAEA,SAAO;AACT;AAKA,eAAe,2BAA2B,YAAuC;AAC/E,QAAM,OAAiB,CAAC;AACxB,QAAM,SAASA,OAAK,KAAK,YAAY,KAAK;AAE1C,MAAI;AACF,UAAM,YAAY,MAAM,UAAU,UAAU,UAAU,MAAM;AAE5D,eAAW,QAAQ,WAAW;AAC5B,YAAM,WAAWA,OAAK,KAAK,QAAQ,IAAI;AACvC,YAAM,UAAU,MAAM,UAAU,KAAK,QAAQ;AAG7C,UACE,QAAQ,SAAS,aAAa,KAC9B,QAAQ,SAAS,YAAY,KAC7B,QAAQ,SAAS,YAAY,GAC7B;AAEA,cAAM,YAAY;AAClB,YAAI;AACJ,gBAAQ,QAAQ,UAAU,KAAK,OAAO,OAAO,MAAM;AACjD,eAAK,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AAAA,EAEhB;AAEA,SAAO;AACT;AAKA,eAAe,uBAAuB,YAAuC;AAC3E,QAAM,OAAiB,CAAC;AACxB,QAAM,SAASA,OAAK,KAAK,YAAY,KAAK;AAE1C,MAAI;AACF,UAAM,YAAY,MAAM,UAAU,UAAU,UAAU,MAAM;AAE5D,eAAW,QAAQ,WAAW;AAC5B,YAAM,WAAWA,OAAK,KAAK,QAAQ,IAAI;AACvC,YAAM,UAAU,MAAM,UAAU,KAAK,QAAQ;AAG7C,YAAM,eAAe;AACrB,UAAI;AACJ,cAAQ,QAAQ,aAAa,KAAK,OAAO,OAAO,MAAM;AACpD,cAAM,cAAc,MAAM,CAAC;AAE3B,cAAM,aAAa,YAAY,QAAQ,YAAY,EAAE,EAAE,YAAY;AACnE,aAAK,KAAK,UAAU;AAAA,MACtB;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AAAA,EAEhB;AAEA,SAAO;AACT;AAKA,eAAe,qBAAqB,aAAwC;AAC1E,QAAM,OAAiB,CAAC;AACxB,QAAM,SAASA,OAAK,KAAK,aAAa,KAAK;AAE3C,MAAI;AAEF,UAAM,UAAU,MAAM,UAAU,UAAU,qBAAqB,MAAM;AAErE,eAAW,QAAQ,SAAS;AAC1B,YAAM,WAAWA,OAAK,KAAK,QAAQ,IAAI;AACvC,YAAM,UAAU,MAAM,UAAU,KAAK,QAAQ;AAG7C,YAAM,YAAY;AAClB,UAAI;AACJ,cAAQ,QAAQ,UAAU,KAAK,OAAO,OAAO,MAAM;AACjD,cAAM,WAAW,MAAM,CAAC;AACxB,cAAM,QAAQ,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AAChD,YAAI,MAAM,SAAS,GAAG;AACpB,eAAK,KAAK,MAAM,CAAC,CAAC;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AAAA,EAEhB;AAEA,SAAO;AACT;AAKA,eAAe,kBACb,SACA,UACwB;AACxB,QAAM,SAAS,MAAM,UAAU,OAAO,QAAQ;AAC9C,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,QAAQ,MAAM,UAAU,UAAU,QAAQ,QAAQ;AAExD,eAAW,QAAQ,OAAO;AACxB,UAAI,SAAS,cAAe;AAE5B,YAAM,OAAO,KAAK,QAAQ,OAAO,EAAE;AAEnC,UAAI,KAAK,SAAS,OAAO,KAAK,QAAQ,SAAS,IAAI,GAAG;AACpD,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AAAA,EAEhB;AAEA,SAAO;AACT;AAKA,eAAe,uBACb,UACA,MACe;AACf,MAAI,UAAU,MAAM,UAAU,KAAK,QAAQ;AAG3C,MAAI,CAAC,QAAQ,SAAS,6BAAS,GAAG;AAEhC,UAAM,gBAAgB;AACtB,UAAM,cAAc,QAAQ,QAAQ,aAAa;AAEjD,QAAI,gBAAgB,IAAI;AACtB,YAAM,cAAc;AAAA;AAAA;AAAA;AAAA,EAA2B,KAAK,IAAI,CAAC,MAAM,WAAW,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AACzF,gBACE,QAAQ,MAAM,GAAG,WAAW,IAAI,cAAc,QAAQ,MAAM,WAAW;AAAA,IAC3E;AAAA,EACF,OAAO;AAEL,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,QAAI,SAAS;AACb,UAAM,SAAmB,CAAC;AAE1B,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,OAAO,MAAM,CAAC;AAEpB,UAAI,KAAK,WAAW,6BAAS,GAAG;AAC9B,iBAAS;AACT,eAAO,KAAK,IAAI;AAChB,eAAO,KAAK,EAAE;AACd,eAAO,KAAK,+BAAW;AACvB,mBAAW,OAAO,MAAM;AACtB,iBAAO,KAAK,WAAW,GAAG,EAAE;AAAA,QAC9B;AACA,eAAO,KAAK,EAAE;AACd,eAAO,KAAK,+BAAW;AACvB,eAAO,KAAK,kGAA4B;AACxC;AAAA,MACF;AAEA,UAAI,QAAQ;AAEV,YAAI,KAAK,WAAW,KAAK,KAAK,CAAC,KAAK,WAAW,6BAAS,GAAG;AACzD,mBAAS;AACT,iBAAO,KAAK,IAAI;AAAA,QAClB;AACA;AAAA,MACF;AAEA,aAAO,KAAK,IAAI;AAAA,IAClB;AAEA,cAAU,OAAO,KAAK,IAAI;AAAA,EAC5B;AAEA,QAAM,UAAU,MAAM,UAAU,OAAO;AACzC;AAtXA,IASa;AATb;AAAA;AAAA;AAAA;AAEA;AACA;AAMO,IAAM,oBAAoB,IAAID,UAAQ,aAAa,EACvD,SAAS,eAAe,+BAAW,EACnC,YAAY,sCAAQ,EACpB,OAAO,OAAO,aAAa;AAC1B,UAAI;AACF,eAAO,OAAO,sCAAQ;AACtB,eAAO,QAAQ;AAGf,cAAM,eAAe,MAAM,UAAU,OAAO,eAAe;AAC3D,YAAI,CAAC,cAAc;AACjB,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,0GAA8C;AAC1D,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,YAAI,CAAC,UAAU;AACb,iBAAO,KAAK,mFAA4B;AACxC,iBAAO,QAAQ;AAEf,gBAAM,WAAW;AACjB,gBAAM,SAAS,MAAM,UAAU,OAAO,QAAQ;AAE9C,cAAI,CAAC,QAAQ;AACX,mBAAO,MAAM,sCAAa;AAC1B,oBAAQ,KAAK,CAAC;AAAA,UAChB;AAEA,gBAAM,QAAQ,MAAM,UAAU,UAAU,QAAQ,QAAQ;AACxD,gBAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,MAAM,aAAa;AAErD,cAAI,MAAM,WAAW,GAAG;AACtB,mBAAO,MAAM,sCAAa;AAC1B,oBAAQ,KAAK,CAAC;AAAA,UAChB;AAEA,qBAAW,QAAQ,OAAO;AACxB,kBAAM,WAAWC,OAAK,KAAK,UAAU,IAAI;AACzC,mBAAO,KAAK,iBAAO,IAAI,EAAE;AACzB,kBAAM,mBAAmB,QAAQ;AACjC,mBAAO,QAAQ;AAAA,UACjB;AAAA,QACF,OAAO;AAEL,gBAAM,SAAS,MAAM,UAAU,OAAO,QAAQ;AAC9C,cAAI,CAAC,QAAQ;AACX,mBAAO,MAAM,wCAAe,QAAQ,EAAE;AACtC,oBAAQ,KAAK,CAAC;AAAA,UAChB;AAEA,gBAAM,mBAAmB,QAAQ;AAAA,QACnC;AAEA,eAAO,OAAO,sCAAQ;AAAA,MACxB,SAAS,OAAY;AACnB,eAAO,MAAM,yCAAW,MAAM,OAAO,EAAE;AACvC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;ACvEH,SAAS,WAAAE,iBAAe;AACxB,OAAOC,YAAU;AA2DjB,eAAe,qBACb,cACA,YACe;AACf,SAAO,KAAK,yCAAW;AAEvB,QAAM,WAAWA,OAAK,KAAK,YAAY,YAAY;AACnD,QAAM,SAAS,MAAM,UAAU,OAAO,QAAQ;AAE9C,MAAI,CAAC,QAAQ;AACX;AAAA,EACF;AAGA,QAAM,QAAQ,MAAM,UAAU,UAAU,QAAQ,QAAQ;AACxD,QAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,MAAM,aAAa;AAGrD,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,iDAA6B;AACxC,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,8GAAwC;AACnD,QAAM,KAAK,oDAAoD;AAE/D,aAAW,YAAY,OAAO;AAC5B,UAAM,OAAO,SAAS,QAAQ,OAAO,EAAE;AACvC,UAAM,cAAc,KACjB,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EAC1D,KAAK,GAAG;AAEX,UAAM,WAAWA,OAAK,KAAK,UAAU,QAAQ;AAC7C,UAAM,UAAU,MAAM,UAAU,KAAK,QAAQ;AAG7C,UAAM,SAAS,UAAU,gBAAgB,OAAO;AAChD,UAAM,iBAAiB,UAAU,kBAAkB,MAAM;AAGzD,UAAM,WAAW,UAAU,YAAY,OAAO;AAG9C,QAAI,iBAAiB;AACrB,QAAI,WAAW,sBAAO;AACpB,YAAM,YAAY,QAAQ,MAAM,mBAAmB;AACnD,UAAI,WAAW;AACb,yBAAiB,UAAU,CAAC,EAAE,KAAK;AAAA,MACrC;AAAA,IACF;AAEA,UAAM,KAAK,KAAK,WAAW,MAAM,IAAI,SAAS,cAAc,MAAM,QAAQ,MAAM,cAAc,MAAM;AAAA,EACtG;AAEA,QAAM,aAAa,MAAM,KAAK,IAAI,IAAI;AAGtC,QAAM,uBAAuB,cAAc,+BAAW,UAAU;AAClE;AAKA,eAAe,iBACb,cACA,YACe;AACf,SAAO,KAAK,kCAAc;AAE1B,QAAM,aAAaA,OAAK,KAAK,YAAY,SAAS;AAClD,QAAM,SAAS,MAAM,UAAU,OAAO,UAAU;AAEhD,MAAI,CAAC,QAAQ;AACX;AAAA,EACF;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,qCAA2B;AACtC,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,kGAAsC;AACjD,QAAM,KAAK,EAAE;AAGb,QAAM,SAASA,OAAK,KAAK,YAAY,KAAK;AAC1C,QAAM,cAAc,MAAM,UAAU,UAAU,oBAAoB,MAAM;AAExE,MAAI,YAAY,WAAW,GAAG;AAC5B,UAAM,KAAK,kBAAQ;AAAA,EACrB,OAAO;AACL,eAAW,kBAAkB,aAAa;AACxC,YAAM,iBAAiBA,OAAK,KAAK,QAAQ,cAAc;AACvD,YAAM,iBAAiB,eAAe,QAAQ,SAAS,EAAE;AACzD,YAAM,SAAS,eAAe,QAAQ,eAAe,EAAE,EAAE,YAAY;AAErE,YAAM,KAAK,OAAO,MAAM,eAAK;AAC7B,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,8EAA4B;AACvC,YAAM,KAAK,sCAAsC;AAGjD,YAAM,OAAO,MAAM,mBAAmB,cAAc;AACpD,iBAAW,OAAO,MAAM;AACtB,cAAM,KAAK,KAAK,IAAI,MAAM,MAAM,IAAI,IAAI,MAAM,IAAI,WAAW,eAAU,IAAI,IAAI,IAAI;AAAA,MACrF;AACA,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,QAAM,aAAa,MAAM,KAAK,IAAI;AAGlC,QAAM,uBAAuB,cAAc,uBAAa,UAAU;AACpE;AAKA,eAAe,mBACb,gBACqF;AACrF,QAAM,OAAmF,CAAC;AAC1F,QAAM,UAAU,MAAM,UAAU,KAAK,cAAc;AAGnD,MAAI,YAAY;AAChB,QAAM,2BAA2B,QAAQ,MAAM,8BAA8B;AAC7E,MAAI,0BAA0B;AAC5B,gBAAY,yBAAyB,CAAC;AAAA,EACxC;AAGA,QAAM,cACJ;AACF,MAAI;AAEJ,UAAQ,QAAQ,YAAY,KAAK,OAAO,OAAO,MAAM;AACnD,UAAM,cAAc,MAAM,CAAC;AAC3B,UAAM,aAAa,MAAM,CAAC;AAC1B,UAAM,aAAa,MAAM,CAAC;AAG1B,QAAI,aAAa;AACjB,YAAQ,aAAa;AAAA,MACnB,KAAK;AACH,qBAAa;AACb;AAAA,MACF,KAAK;AACH,qBAAa;AACb;AAAA,MACF,KAAK;AACH,qBAAa;AACb;AAAA,MACF,KAAK;AACH,qBAAa;AACb;AAAA,MACF,KAAK;AACH,qBAAa;AACb;AAAA,IACJ;AAGA,QAAI,WAAW;AACf,QAAI,aAAa,CAAC,WAAW,WAAW,MAAM,GAAG;AAC/C,iBAAW,GAAG,SAAS,GAAG,UAAU;AAAA,IACtC;AAGA,UAAM,cAAc,qBAAqB,SAAS,UAAU;AAE5D,SAAK,KAAK;AAAA,MACR,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,MAAM,UAAU,OAAO,oBAAI,KAAK,GAAG,YAAY;AAAA,IACjD,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAKA,SAAS,qBAAqB,SAAiB,YAA4B;AAEzE,QAAM,cAAc,QAAQ,QAAQ,GAAG,UAAU,GAAG;AACpD,MAAI,gBAAgB,IAAI;AACtB,WAAO;AAAA,EACT;AAGA,QAAM,eAAe,QAAQ,UAAU,KAAK,IAAI,GAAG,cAAc,GAAG,GAAG,WAAW;AAClF,QAAM,eAAe,aAAa,MAAM,iBAAiB;AAEzD,MAAI,gBAAgB,aAAa,SAAS,GAAG;AAC3C,WAAO,aAAa,CAAC,EAAE,QAAQ,SAAS,EAAE,EAAE,KAAK;AAAA,EACnD;AAEA,SAAO;AACT;AAKA,eAAe,eACb,cACA,YACe;AACf,SAAO,KAAK,yCAAW;AAEvB,QAAM,aAAaA,OAAK,KAAK,YAAY,SAAS;AAClD,QAAM,SAAS,MAAM,UAAU,OAAO,UAAU;AAEhD,MAAI,CAAC,QAAQ;AACX;AAAA,EACF;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,2CAAuB;AAClC,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,8FAAkC;AAC7C,QAAM,KAAK,EAAE;AAGb,QAAM,SAASA,OAAK,KAAK,YAAY,KAAK;AAC1C,QAAM,WAAW,MAAM,UAAU,UAAU,gBAAgB,MAAM;AAEjE,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,KAAK,sCAAQ;AAAA,EACrB,OAAO;AACL,UAAM,KAAK,+DAAuB;AAClC,UAAM,KAAK,+BAA+B;AAE1C,eAAW,cAAc,UAAU;AACjC,YAAM,aAAaA,OAAK,KAAK,QAAQ,UAAU;AAC/C,YAAM,aAAa,WAAW,QAAQ,SAAS,EAAE,EAAE,QAAQ,WAAW,EAAE;AACxE,YAAM,cAAc,WACjB,MAAM,WAAW,EACjB,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,EACxE,KAAK,GAAG;AAGX,YAAM,UAAU,MAAM,UAAU,KAAK,UAAU;AAG/C,YAAM,oBAAoB,QAAQ,MAAM,+BAA+B;AACvE,YAAM,cAAc,oBAChB,kBAAkB,CAAC,EAAE,QAAQ,mBAAmB,EAAE,EAAE,KAAK,IACzD;AAGJ,YAAM,cAAc,QAAQ,MAAM,gBAAgB,KAAK,CAAC,GAAG;AAG3D,YAAM,YAAsB,CAAC;AAC7B,UAAI,QAAQ,SAAS,YAAY,EAAG,WAAU,KAAK,aAAa;AAChE,UAAI,QAAQ,SAAS,YAAY,EAAG,WAAU,KAAK,aAAa;AAChE,UAAI,QAAQ,SAAS,WAAW,EAAG,WAAU,KAAK,YAAY;AAC9D,UAAI,QAAQ,SAAS,aAAa,EAAG,WAAU,KAAK,cAAc;AAElE,YAAM,KAAK,KAAK,WAAW,MAAM,WAAW,MAAM,UAAU,MAAM,UAAU,KAAK,IAAI,KAAK,GAAG,IAAI;AAAA,IACnG;AAAA,EACF;AAEA,QAAM,aAAa,MAAM,KAAK,IAAI;AAGlC,QAAM,uBAAuB,cAAc,+BAAW,UAAU;AAClE;AAKA,eAAe,eAAe,cAAqC;AACjE,QAAM,UAAU,MAAM,UAAU,KAAK,YAAY;AACjD,QAAM,YAAY,UAAU,OAAO,oBAAI,KAAK,GAAG,qBAAqB;AAEpE,MAAI,UAAU;AAGd,MAAI,QAAQ,SAAS,0BAAM,GAAG;AAC5B,cAAU,QAAQ;AAAA,MAChB;AAAA,MACA,6BAAS,SAAS;AAAA,IACpB;AAAA,EACF,OAAO;AAEL,cAAU,QAAQ,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA,6BAAqB,SAAS;AAAA;AAAA,EAC9D;AAEA,QAAM,UAAU,MAAM,cAAc,OAAO;AAC7C;AAKA,eAAe,uBACb,cACA,cACA,YACe;AACf,QAAM,UAAU,MAAM,UAAU,KAAK,YAAY;AAGjD,MAAI,QAAQ,SAAS,YAAY,GAAG;AAElC,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,UAAM,SAAmB,CAAC;AAC1B,QAAI,YAAY;AAChB,QAAI,OAAO;AAEX,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,OAAO,MAAM,CAAC;AAEpB,UAAI,KAAK,WAAW,YAAY,GAAG;AACjC,oBAAY;AACZ,eAAO,KAAK,UAAU;AACtB,eAAO;AACP;AAAA,MACF;AAEA,UAAI,WAAW;AACb,YAAI,KAAK,WAAW,KAAK,KAAK,CAAC,KAAK,WAAW,YAAY,GAAG;AAC5D,sBAAY;AACZ,iBAAO;AACP,iBAAO,KAAK,IAAI;AAAA,QAClB;AACA;AAAA,MACF;AAEA,UAAI,CAAC,MAAM;AACT,eAAO,KAAK,IAAI;AAAA,MAClB;AAAA,IACF;AAEA,UAAM,UAAU,MAAM,cAAc,OAAO,KAAK,IAAI,CAAC;AAAA,EACvD,OAAO;AAEL,UAAM,UAAU,MAAM,cAAc,QAAQ,QAAQ,IAAI,SAAS,aAAa,IAAI;AAAA,EACpF;AACF;AAMA,eAAe,qBACb,cACA,YACe;AACf,SAAO,KAAK,qDAAa;AAEzB,QAAM,SAAS,MAAM,mBAAmB,UAAU;AAElD,MAAI,CAAC,QAAQ;AACX;AAAA,EACF;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,yCAAW;AACtB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,4IAAmC;AAC9C,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,oFAA4C;AACvD,QAAM,KAAK,oDAAoD;AAG/D,MAAI,OAAO,UAAU;AACnB,UAAM,WAAW,gBAAgB,OAAO,SAAS,UAAU;AAC3D,UAAM,SAAS,OAAO,SAAS,QAAQ,UAAU,GAAG,CAAC,KAAK;AAC1D,UAAM,MAAM,OAAO,SAAS,OAAO;AACnC,UAAM,SAAS,OAAO,SAAS,UAAU;AACzC,UAAM,aAAa,OAAO,SAAS,aAC/B,IAAI,KAAK,OAAO,SAAS,UAAU,EAAE,mBAAmB,OAAO,IAC/D;AAEJ,UAAM,KAAK,oBAAU,QAAQ,MAAM,GAAG,MAAM,MAAM,MAAM,MAAM,MAAM,UAAU,IAAI;AAAA,EACpF;AAGA,MAAI,OAAO,SAAS;AAClB,UAAM,WAAW,gBAAgB,OAAO,QAAQ,UAAU;AAC1D,UAAM,SAAS,OAAO,QAAQ,QAAQ,UAAU,GAAG,CAAC,KAAK;AACzD,UAAM,MAAM,OAAO,QAAQ,OAAO;AAClC,UAAM,SAAS,OAAO,QAAQ,UAAU;AACxC,UAAM,aAAa,OAAO,QAAQ,aAC9B,IAAI,KAAK,OAAO,QAAQ,UAAU,EAAE,mBAAmB,OAAO,IAC9D;AAEJ,UAAM,KAAK,oBAAU,QAAQ,MAAM,GAAG,MAAM,MAAM,MAAM,MAAM,MAAM,UAAU,IAAI;AAAA,EACpF;AAEA,QAAM,aAAa,MAAM,KAAK,IAAI,IAAI;AAGtC,QAAM,uBAAuB,cAAc,2CAAa,UAAU;AACpE;AAKA,SAAS,gBAAgB,YAA4B;AAKnD,MAAIA,SAAO;AAGX,EAAAA,SAAOA,OAAK,QAAQ,gBAAgB,EAAE;AACtC,EAAAA,SAAOA,OAAK,QAAQ,SAAS,EAAE;AAG/B,QAAM,QAAQA,OAAK,MAAM,GAAG;AAC5B,MAAI,MAAM,SAAS,GAAG;AACpB,IAAAA,SAAO,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG;AAAA,EAChC;AAGA,EAAAA,SAAOA,OAAK,QAAQ,UAAU,EAAE;AAEhC,SAAOA;AACT;AAjeA,IASa;AATb;AAAA;AAAA;AAAA;AAEA;AACA;AACA;AAKO,IAAM,oBAAoB,IAAID,UAAQ,aAAa,EACvD,YAAY,2BAAiB,EAC7B,OAAO,YAAY;AAClB,UAAI;AACF,eAAO,OAAO,2BAAiB;AAC/B,eAAO,QAAQ;AAGf,cAAM,eAAe,MAAM,UAAU,OAAO,eAAe;AAC3D,YAAI,CAAC,cAAc;AACjB,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,0GAA8C;AAC1D,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,cAAM,eAAe;AACrB,cAAM,SAAS,MAAM,UAAU,OAAO,YAAY;AAElD,YAAI,CAAC,QAAQ;AACX,iBAAO,KAAK,+DAAuB;AACnC,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,qBAAqB,cAAc,GAAG;AAG5C,cAAM,iBAAiB,cAAc,GAAG;AAGxC,cAAM,eAAe,cAAc,GAAG;AAGtC,cAAM,qBAAqB,cAAc,GAAG;AAG5C,cAAM,eAAe,YAAY;AAEjC,eAAO,QAAQ,iCAAkB;AAAA,MACnC,SAAS,OAAY;AACnB,eAAO,MAAM,6BAAS,MAAM,OAAO,EAAE;AACrC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;ACvDH,SAAS,WAAAE,iBAAe;AACxB,OAAOC,YAAU;AAGjB,OAAOC,eAAc;AACrB,SAAS,SAAAC,cAAa;AAkFtB,eAAe,kBAAkB,YAAmC;AAClE,QAAM,aAAaF,OAAK,KAAK,YAAY,SAAS;AAClD,QAAM,SAAS,MAAM,UAAU,OAAO,UAAU;AAEhD,MAAI,CAAC,QAAQ;AACX,WAAO,KAAK,4CAAS;AACrB;AAAA,EACF;AAEA,SAAO,KAAK,iCAAa;AACzB,SAAO,QAAQ;AAEf,QAAM,SAAS,oBAAI,IAAsB;AACzC,QAAM,SAASA,OAAK,KAAK,YAAY,KAAK;AAC1C,QAAM,cAAc,MAAM,UAAU,UAAU,oBAAoB,MAAM;AAGxE,aAAW,kBAAkB,aAAa;AACxC,UAAM,iBAAiBA,OAAK,KAAK,QAAQ,cAAc;AACvD,UAAM,OAAO,MAAM,0BAA0B,cAAc;AAE3D,eAAW,OAAO,MAAM;AACtB,YAAM,MAAM,GAAG,IAAI,MAAM,IAAI,IAAI,IAAI;AACrC,UAAI,CAAC,OAAO,IAAI,GAAG,GAAG;AACpB,eAAO,IAAI,KAAK,CAAC,CAAC;AAAA,MACpB;AACA,aAAO,IAAI,GAAG,EAAG,KAAK,cAAc;AAAA,IACtC;AAAA,EACF;AAGA,QAAM,YAA2D,CAAC;AAClE,aAAW,CAAC,KAAKG,YAAW,KAAK,OAAO,QAAQ,GAAG;AACjD,QAAIA,aAAY,SAAS,GAAG;AAC1B,gBAAU,KAAK,EAAE,KAAK,aAAAA,aAAY,CAAC;AAAA,IACrC;AAAA,EACF;AAEA,MAAI,UAAU,WAAW,GAAG;AAC1B,WAAO,QAAQ,qCAAY;AAAA,EAC7B,OAAO;AACL,WAAO,MAAM,gBAAM,UAAU,MAAM,2BAAY;AAC/C,WAAO,QAAQ;AAEf,eAAW,YAAY,WAAW;AAChC,aAAO,MAAM,iBAAO,SAAS,GAAG,EAAE;AAClC,iBAAW,cAAc,SAAS,aAAa;AAC7C,eAAO,KAAK,OAAO,UAAU,EAAE;AAAA,MACjC;AACA,aAAO,QAAQ;AAAA,IACjB;AAAA,EACF;AACF;AAKA,eAAe,iBAAiB,YAAmC;AACjE,QAAM,aAAaH,OAAK,KAAK,YAAY,SAAS;AAClD,QAAM,eAAeA,OAAK,KAAK,YAAY,sBAAsB;AACjE,QAAM,iBAAiB,MAAM,UAAU,OAAO,YAAY;AAE1D,MAAI,CAAC,gBAAgB;AACnB,WAAO,KAAK,2EAAyB;AACrC,WAAO,KAAK,4EAA8C;AAC1D;AAAA,EACF;AAEA,SAAO,KAAK,kCAAc;AAC1B,SAAO,QAAQ;AAGf,QAAM,kBAAkB,MAAM,UAAU,KAAK,YAAY;AACzD,QAAM,eAAe,wBAAwB,eAAe;AAG5D,QAAM,cAAc,oBAAI,IAAmE;AAC3F,QAAM,SAASA,OAAK,KAAK,YAAY,KAAK;AAC1C,QAAM,cAAc,MAAM,UAAU,UAAU,oBAAoB,MAAM;AAExE,aAAW,kBAAkB,aAAa;AACxC,UAAM,iBAAiBA,OAAK,KAAK,QAAQ,cAAc;AACvD,UAAM,OAAO,MAAM,0BAA0B,cAAc;AAE3D,eAAW,OAAO,MAAM;AACtB,YAAM,MAAM,GAAG,IAAI,MAAM,IAAI,IAAI,IAAI;AACrC,kBAAY,IAAI,KAAK,GAAG;AAAA,IAC1B;AAAA,EACF;AAGA,QAAM,QAAiD,CAAC;AACxD,QAAM,UAAmD,CAAC;AAC1D,QAAM,WAAsF,CAAC;AAE7F,aAAW,CAAC,KAAK,GAAG,KAAK,YAAY,QAAQ,GAAG;AAC9C,QAAI,CAAC,aAAa,IAAI,GAAG,GAAG;AAC1B,YAAM,KAAK,EAAE,QAAQ,IAAI,QAAQ,MAAM,IAAI,KAAK,CAAC;AAAA,IACnD,OAAO;AACL,YAAM,cAAc,aAAa,IAAI,GAAG;AACxC,UAAI,YAAY,gBAAgB,IAAI,aAAa;AAC/C,iBAAS,KAAK;AAAA,UACZ,QAAQ,IAAI;AAAA,UACZ,MAAM,IAAI;AAAA,UACV,SAAS,YAAY;AAAA,UACrB,SAAS,IAAI;AAAA,QACf,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,aAAW,CAAC,KAAK,GAAG,KAAK,aAAa,QAAQ,GAAG;AAC/C,QAAI,CAAC,YAAY,IAAI,GAAG,GAAG;AACzB,cAAQ,KAAK,EAAE,QAAQ,IAAI,QAAQ,MAAM,IAAI,KAAK,CAAC;AAAA,IACrD;AAAA,EACF;AAGA,MAAI,aAAa;AAEjB,MAAI,MAAM,SAAS,GAAG;AACpB,iBAAa;AACb,WAAO,QAAQ,qBAAW,MAAM,MAAM,IAAI;AAC1C,eAAW,OAAO,OAAO;AACvB,aAAO,KAAK,OAAO,IAAI,MAAM,IAAI,IAAI,IAAI,EAAE;AAAA,IAC7C;AACA,WAAO,QAAQ;AAAA,EACjB;AAEA,MAAI,QAAQ,SAAS,GAAG;AACtB,iBAAa;AACb,WAAO,MAAM,qBAAW,QAAQ,MAAM,IAAI;AAC1C,eAAW,OAAO,SAAS;AACzB,aAAO,KAAK,OAAO,IAAI,MAAM,IAAI,IAAI,IAAI,EAAE;AAAA,IAC7C;AACA,WAAO,QAAQ;AAAA,EACjB;AAEA,MAAI,SAAS,SAAS,GAAG;AACvB,iBAAa;AACb,WAAO,KAAK,qBAAW,SAAS,MAAM,IAAI;AAC1C,eAAW,OAAO,UAAU;AAC1B,aAAO,KAAK,OAAO,IAAI,MAAM,IAAI,IAAI,IAAI,EAAE;AAC3C,aAAO,KAAK,eAAU,IAAI,OAAO,EAAE;AACnC,aAAO,KAAK,eAAU,IAAI,OAAO,EAAE;AAAA,IACrC;AACA,WAAO,QAAQ;AAAA,EACjB;AAEA,MAAI,CAAC,YAAY;AACf,WAAO,QAAQ,2CAAa;AAAA,EAC9B;AACF;AAKA,eAAe,oBAAoB,YAAmC;AACpE,QAAM,eAAeA,OAAK,KAAK,YAAY,sBAAsB;AAEjE,SAAO,KAAK,gDAAuB;AAGnC,QAAM,UAAU,UAAUA,OAAK,QAAQ,YAAY,CAAC;AAGpD,QAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6BAyBR,UAAU,OAAO,oBAAI,KAAK,GAAG,qBAAqB,CAAC;AAAA;AAI1D,MAAI,UAAU;AACd,QAAM,aAAaA,OAAK,KAAK,YAAY,SAAS;AAClD,QAAM,SAAS,MAAM,UAAU,OAAO,UAAU;AAEhD,MAAI,QAAQ;AACV,UAAM,SAASA,OAAK,KAAK,YAAY,KAAK;AAC1C,UAAM,cAAc,MAAM,UAAU,UAAU,oBAAoB,MAAM;AAGxE,UAAM,YAAY,oBAAI,IAA0E;AAEhG,eAAW,kBAAkB,aAAa;AACxC,YAAM,iBAAiBA,OAAK,KAAK,QAAQ,cAAc;AACvD,YAAM,iBAAiB,eAAe,QAAQ,SAAS,EAAE;AACzD,YAAM,SAAS,eAAe,QAAQ,eAAe,EAAE,EAAE,YAAY;AAErE,UAAI,CAAC,UAAU,IAAI,MAAM,GAAG;AAC1B,kBAAU,IAAI,QAAQ,CAAC,CAAC;AAAA,MAC1B;AAEA,YAAM,OAAO,MAAM,0BAA0B,cAAc;AAC3D,gBAAU,IAAI,MAAM,EAAG,KAAK,GAAG,IAAI;AAAA,IACrC;AAGA,eAAW,CAAC,QAAQ,IAAI,KAAK,UAAU,QAAQ,GAAG;AAChD,iBAAW;AAAA,KAAQ,OAAO,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC,CAAC;AAAA;AAAA;AAEnE,iBAAW,OAAO,MAAM;AACtB,mBAAW,OAAO,IAAI,MAAM,IAAI,IAAI,IAAI;AAAA;AAAA;AACxC,mBAAW;AAAA;AAAA;AACX,mBAAW,qBAAW,IAAI,eAAe,GAAG;AAAA;AAAA;AAC5C,mBAAW;AAAA;AAAA;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,MAAM,cAAc,OAAO;AAE3C,SAAO,QAAQ,oCAAqB,YAAY,EAAE;AACpD;AAKA,eAAe,0BACb,gBACuE;AACvE,QAAM,OAAqE,CAAC;AAC5E,QAAM,UAAU,MAAM,UAAU,KAAK,cAAc;AAGnD,MAAI,YAAY;AAChB,QAAM,2BAA2B,QAAQ,MAAM,8BAA8B;AAC7E,MAAI,0BAA0B;AAC5B,gBAAY,yBAAyB,CAAC;AAAA,EACxC;AAGA,QAAM,cACJ;AACF,MAAI;AAEJ,UAAQ,QAAQ,YAAY,KAAK,OAAO,OAAO,MAAM;AACnD,UAAM,cAAc,MAAM,CAAC;AAC3B,UAAM,aAAa,MAAM,CAAC;AAC1B,UAAM,aAAa,MAAM,CAAC;AAG1B,QAAI,aAAa;AACjB,YAAQ,aAAa;AAAA,MACnB,KAAK;AACH,qBAAa;AACb;AAAA,MACF,KAAK;AACH,qBAAa;AACb;AAAA,MACF,KAAK;AACH,qBAAa;AACb;AAAA,MACF,KAAK;AACH,qBAAa;AACb;AAAA,MACF,KAAK;AACH,qBAAa;AACb;AAAA,IACJ;AAGA,QAAI,WAAW;AACf,QAAI,aAAa,CAAC,WAAW,WAAW,MAAM,GAAG;AAC/C,iBAAW,GAAG,SAAS,GAAG,UAAU;AAAA,IACtC;AAGA,UAAM,cAAcI,sBAAqB,SAAS,UAAU;AAE5D,SAAK,KAAK;AAAA,MACR,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAKA,SAAS,wBACP,iBACoE;AACpE,QAAM,OAAO,oBAAI,IAAmE;AAGpF,QAAM,WAAW;AACjB,MAAI;AAEJ,UAAQ,QAAQ,SAAS,KAAK,eAAe,OAAO,MAAM;AACxD,UAAM,SAAS,MAAM,CAAC;AACtB,UAAMJ,SAAO,MAAM,CAAC,EAAE,KAAK;AAC3B,UAAM,cAAc,MAAM,CAAC,EAAE,KAAK;AAClC,UAAM,MAAM,GAAG,MAAM,IAAIA,MAAI;AAC7B,SAAK,IAAI,KAAK,EAAE,QAAQ,MAAAA,QAAM,YAAY,CAAC;AAAA,EAC7C;AAEA,SAAO;AACT;AAKA,SAASI,sBAAqB,SAAiB,YAA4B;AACzE,QAAM,cAAc,QAAQ,QAAQ,GAAG,UAAU,GAAG;AACpD,MAAI,gBAAgB,IAAI;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,QAAQ,UAAU,KAAK,IAAI,GAAG,cAAc,GAAG,GAAG,WAAW;AAClF,QAAM,eAAe,aAAa,MAAM,iBAAiB;AAEzD,MAAI,gBAAgB,aAAa,SAAS,GAAG;AAC3C,WAAO,aAAa,CAAC,EAAE,QAAQ,SAAS,EAAE,EAAE,KAAK;AAAA,EACnD;AAEA,SAAO;AACT;AA7aA,IAUa;AAVb;AAAA;AAAA;AAAA;AAEA;AACA;AAOO,IAAM,kBAAkB,IAAIL,UAAQ,WAAW,EACnD,YAAY,gEAAwB,EACpC,OAAO,YAAY;AAClB,UAAI;AACF,eAAO,OAAO,kBAAQ;AACtB,eAAO,QAAQ;AAGf,cAAM,eAAe,MAAM,UAAU,OAAO,eAAe;AAC3D,YAAI,CAAC,cAAc;AACjB,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,0GAA8C;AAC1D,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,UAAU,MAAME,UAAS,OAAO;AAAA,UACpC;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SAAS;AAAA,cACP,EAAE,MAAM,iCAAa,OAAO,YAAY;AAAA,cACxC,EAAE,MAAM,iCAAa,OAAO,UAAU;AAAA,cACtC,EAAE,MAAM,6BAAmB,OAAO,WAAW;AAAA,cAC7C,EAAE,MAAM,4BAAQ,OAAO,MAAM;AAAA,YAC/B;AAAA,YACA,SAAS;AAAA,UACX;AAAA,QACF,CAAC;AAED,cAAM,QAAQ,IAAIC,OAAM,CAAC,CAAC;AAG1B,YAAI,QAAQ,cAAc,eAAe,QAAQ,cAAc,OAAO;AACpE,gBAAM,IAAI;AAAA,YACR,OAAO;AAAA,YACP,MAAM,YAAY;AAChB,oBAAM,kBAAkB,GAAG;AAAA,YAC7B;AAAA,UACF,CAAC;AAAA,QACH;AAEA,YAAI,QAAQ,cAAc,aAAa,QAAQ,cAAc,OAAO;AAClE,gBAAM,IAAI;AAAA,YACR,OAAO;AAAA,YACP,MAAM,YAAY;AAChB,oBAAM,iBAAiB,GAAG;AAAA,YAC5B;AAAA,UACF,CAAC;AAAA,QACH;AAEA,YAAI,QAAQ,cAAc,cAAc,QAAQ,cAAc,OAAO;AACnE,gBAAM,IAAI;AAAA,YACR,OAAO;AAAA,YACP,MAAM,YAAY;AAChB,oBAAM,oBAAoB,GAAG;AAAA,YAC/B;AAAA,UACF,CAAC;AAAA,QACH;AAEA,cAAM,MAAM,IAAI;AAEhB,eAAO,QAAQ;AACf,eAAO,OAAO,8BAAU;AAAA,MAC1B,SAAS,OAAY;AACnB,eAAO,MAAM,iCAAa,MAAM,OAAO,EAAE;AACzC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;AClFH,SAAS,WAAAG,iBAAe;AACxB,OAAOC,YAAU;AAGjB,OAAOC,gBAAc;AAwIrB,eAAe,gBAAgB,WAAsC;AACnE,QAAM,OAAiB,CAAC;AAExB,MAAI;AAEF,UAAM,WAAW,MAAM,UAAU,UAAU,QAAQ,SAAS;AAC5D,UAAM,WAAW,SAAS,OAAO,CAAC,MAAM,MAAM,UAAU;AAExD,eAAW,QAAQ,UAAU;AAC3B,YAAM,WAAWD,OAAK,KAAK,WAAW,IAAI;AAE1C,YAAM,OAAO,MAAM,UAAU,OAAO,QAAQ;AAC5C,UAAI,MAAM;AACR,aAAK,KAAK,QAAQ;AAAA,MACpB;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AAAA,EAEhB;AAEA,SAAO;AACT;AAjKA,IASa;AATb;AAAA;AAAA;AAAA;AAEA;AACA;AAMO,IAAM,cAAc,IAAID,UAAQ,MAAM,EAC1C,SAAS,YAAY,kEAAoC,EACzD,YAAY,sCAAQ,EACpB,OAAO,OAAO,SAAS,YAAY;AAClC,UAAI;AACF,eAAO,OAAO,0BAAM;AACpB,eAAO,QAAQ;AAGf,cAAM,eAAe,MAAM,UAAU,OAAO,eAAe;AAC3D,YAAI,CAAC,cAAc;AACjB,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,0GAA8C;AAC1D,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,cAAM,cAAc;AACpB,cAAM,YAAY,MAAM,UAAU,OAAO,WAAW;AAEpD,YAAI,CAAC,WAAW;AACd,iBAAO,KAAK,sCAAQ;AACpB,iBAAO,KAAK,8EAA4B;AACxC,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,YAAI,YAAY;AAChB,YAAI,eAAe;AAEnB,gBAAQ,QAAQ;AAAA,UACd,KAAK;AAAA,UACL,KAAK,SAAS;AACZ,kBAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AACnD,wBAAYC,OAAK,KAAK,aAAa,KAAK;AACxC,kBAAM,cAAc,MAAM,UAAU,OAAO,SAAS;AACpD,gBAAI,CAAC,aAAa;AAChB,qBAAO,KAAK,kDAAU;AACtB,sBAAQ,KAAK,CAAC;AAAA,YAChB;AACA,2BAAe;AACf;AAAA,UACF;AAAA,UACA,KAAK;AAAA,UACL,KAAK,MAAM;AACT,wBAAY;AACZ,2BAAe;AACf;AAAA,UACF;AAAA,UACA,SAAS;AAEP,wBAAYA,OAAK,KAAK,aAAa,MAAM;AACzC,kBAAM,aAAa,MAAM,UAAU,OAAO,SAAS;AACnD,gBAAI,CAAC,YAAY;AACf,qBAAO,MAAM,mCAAU,MAAM,sBAAO;AACpC,qBAAO,KAAK,2BAAO;AAGnB,oBAAM,UAAU,MAAM,UAAU,UAAU,MAAM,WAAW;AAC3D,oBAAM,QAAQ,QAAQ,MAAM,GAAG,EAAE;AACjC,yBAAW,QAAQ,OAAO;AACxB,uBAAO,KAAK,KAAK,KAAK,QAAQ,KAAK,EAAE,CAAC,EAAE;AAAA,cAC1C;AACA,sBAAQ,KAAK,CAAC;AAAA,YAChB;AACA,2BAAe,gBAAM,MAAM;AAC3B;AAAA,UACF;AAAA,QACF;AAEA,eAAO,KAAK,YAAY;AACxB,eAAO,QAAQ;AAGf,cAAM,OAAO,MAAM,gBAAgB,SAAS;AAE5C,YAAI,KAAK,WAAW,GAAG;AACrB,iBAAO,KAAK,gCAAO;AACnB,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,iBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,gBAAM,UAAUA,OAAK,SAAS,aAAa,KAAK,CAAC,CAAC;AAClD,iBAAO,KAAK,GAAG,IAAI,CAAC,KAAK,OAAO,EAAE;AAAA,QACpC;AAEA,eAAO,QAAQ;AAGf,cAAM,UAAU,MAAMC,WAAS,OAAO;AAAA,UACpC;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SAAS;AAAA,UACX;AAAA,QACF,CAAC;AAED,cAAM,YAAY,QAAQ,UAAU,KAAK;AAEzC,YAAI,cAAc,IAAI;AACpB,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,cAAM,eAAe,SAAS,WAAW,EAAE;AAE3C,YAAI,MAAM,YAAY,KAAK,eAAe,KAAK,eAAe,KAAK,QAAQ;AACzE,iBAAO,MAAM,gCAAO;AACpB,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,cAAc,KAAK,eAAe,CAAC;AACzC,eAAO,QAAQ;AACf,eAAO,OAAO,0BAAM;AACpB,eAAO,QAAQ;AAEf,cAAM,UAAU,MAAM,UAAU,KAAK,WAAW;AAChD,gBAAQ,IAAI,OAAO;AAAA,MACrB,SAAS,OAAY;AACnB,eAAO,MAAM,yCAAW,MAAM,OAAO,EAAE;AACvC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;ACvIH;AAAA;AAAA;AAAA;AAAA;AAAA,OAAOC,YAAU;AACjB,OAAOC,SAAQ;AACf,OAAO,YAAY;AAFnB,IAwBa,mBA6KA;AArMb;AAAA;AAAA;AAAA;AAGA;AACA;AAoBO,IAAM,oBAAN,MAAwB;AAAA,MACrB;AAAA,MAER,cAAc;AACZ,cAAM,YAAYD,OAAK,KAAKC,IAAG,QAAQ,GAAG,WAAW;AACrD,aAAK,aAAaD,OAAK,KAAK,WAAW,aAAa;AAAA,MACtD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,OAAmC;AACvC,YAAI;AACF,gBAAM,SAAS,MAAM,UAAU,OAAO,KAAK,UAAU;AACrD,cAAI,CAAC,QAAQ;AACX,mBAAO;AAAA,UACT;AAEA,gBAAM,UAAU,MAAM,UAAU,KAAK,KAAK,UAAU;AACpD,gBAAM,SAAS,KAAK,MAAM,OAAO;AAGjC,cAAI,OAAO,QAAQ,aAAa;AAC9B,mBAAO,OAAO,cAAc,KAAK,QAAQ,OAAO,OAAO,WAAW;AAAA,UACpE;AAEA,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,iBAAO,MAAM,qDAAa,KAAK,EAAE;AACjC,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,KAAK,QAAmC;AAC5C,YAAI;AACF,gBAAM,YAAYA,OAAK,QAAQ,KAAK,UAAU;AAC9C,gBAAM,UAAU,UAAU,SAAS;AAGnC,gBAAM,eAAe,KAAK,MAAM,KAAK,UAAU,MAAM,CAAC;AACtD,cAAI,aAAa,QAAQ,aAAa;AACpC,yBAAa,OAAO,cAAc,KAAK,QAAQ,aAAa,OAAO,WAAW;AAAA,UAChF;AAEA,gBAAM,UAAU,KAAK,UAAU,cAAc,MAAM,CAAC;AACpD,gBAAM,UAAU,MAAM,KAAK,YAAY,OAAO;AAAA,QAChD,SAAS,OAAO;AACd,gBAAM,IAAI,MAAM,qDAAa,KAAK,EAAE;AAAA,QACtC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,kBAAkB,OAAe,SAAiC;AACtE,cAAM,SAAU,MAAM,KAAK,KAAK,KAAM;AAAA,UACpC,QAAQ;AAAA,YACN,aAAa;AAAA,YACb,SAAS;AAAA,YACT,SAAS;AAAA,UACX;AAAA,QACF;AAEA,eAAO,OAAO,cAAc;AAC5B,YAAI,SAAS;AACX,iBAAO,OAAO,UAAU;AAAA,QAC1B;AAEA,cAAM,KAAK,KAAK,MAAM;AAAA,MACxB;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,iBAAyC;AAC7C,cAAM,SAAS,MAAM,KAAK,KAAK;AAC/B,eAAO,QAAQ,QAAQ,eAAe;AAAA,MACxC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,kBAA8F;AAClG,cAAM,SAAS,MAAM,KAAK,KAAK;AAC/B,eAAO,QAAQ,UAAU;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,YAA8B;AAClC,cAAM,SAAS,MAAM,KAAK,KAAK;AAC/B,eAAO,WAAW,QAAQ,OAAO,QAAQ,gBAAgB;AAAA,MAC3D;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,eAA8B;AAClC,YAAI;AACF,gBAAM,SAAS,MAAM,UAAU,OAAO,KAAK,UAAU;AACrD,cAAI,QAAQ;AACV,kBAAM,UAAU,OAAO,KAAK,UAAU;AAAA,UACxC;AAAA,QACF,SAAS,OAAO;AACd,gBAAM,IAAI,MAAM,yCAAW,KAAK,EAAE;AAAA,QACpC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKQ,QAAQ,MAAsB;AACpC,cAAM,MAAM,KAAK,cAAc;AAC/B,cAAM,KAAK,OAAO,YAAY,EAAE;AAChC,cAAM,SAAS,OAAO,eAAe,eAAe,KAAK,EAAE;AAC3D,YAAI,YAAY,OAAO,OAAO,MAAM,QAAQ,KAAK;AACjD,qBAAa,OAAO,MAAM,KAAK;AAC/B,eAAO,GAAG,SAAS,KAAK,IAAI,MAAM;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKQ,QAAQ,eAA+B;AAC7C,YAAI;AACF,gBAAM,MAAM,KAAK,cAAc;AAC/B,gBAAM,QAAQ,cAAc,MAAM,GAAG;AACrC,gBAAM,KAAK,OAAO,KAAK,MAAM,CAAC,GAAG,KAAK;AACtC,gBAAM,YAAY,MAAM,CAAC;AACzB,gBAAM,WAAW,OAAO,iBAAiB,eAAe,KAAK,EAAE;AAC/D,cAAI,YAAY,SAAS,OAAO,WAAW,OAAO,MAAM;AACxD,uBAAa,SAAS,MAAM,MAAM;AAClC,iBAAO;AAAA,QACT,QAAQ;AAEN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKQ,gBAAwB;AAC9B,cAAM,WAAWC,IAAG,SAAS;AAC7B,cAAM,WAAWA,IAAG,SAAS;AAC7B,cAAM,OAAOA,IAAG,KAAK;AACrB,cAAM,OAAOA,IAAG,KAAK;AAGrB,cAAM,cAAc,GAAG,QAAQ,IAAI,QAAQ,IAAI,IAAI,IAAI,KAAK,CAAC,GAAG,SAAS,SAAS;AAClF,eAAO,OAAO,WAAW,QAAQ,EAAE,OAAO,WAAW,EAAE,OAAO;AAAA,MAChE;AAAA;AAAA;AAAA;AAAA,MAKA,eAAuB;AACrB,eAAOD,OAAK,QAAQ,KAAK,UAAU;AAAA,MACrC;AAAA;AAAA;AAAA;AAAA,MAKA,gBAAwB;AACtB,eAAO,KAAK;AAAA,MACd;AAAA,IACF;AAGO,IAAM,oBAAoB,IAAI,kBAAkB;AAAA;AAAA;;;ACrMvD;AAAA;AAAA;AAAA;AAAA,IAwFa;AAxFb;AAAA;AAAA;AAAA;AAwFO,IAAM,YAAN,MAAgB;AAAA,MACb;AAAA,MACS,iBAAiB;AAAA,MAElC,YAAY,QAAsB;AAChC,aAAK,SAAS;AAAA,UACZ,GAAG;AAAA,UACH,SAAS,OAAO,WAAW,KAAK;AAAA,QAClC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,eAAiC;AACrC,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,QAAQ,OAAO;AAC3C,iBAAO,SAAS;AAAA,QAClB,SAAS,OAAO;AACd,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,SAAS,aAA2C;AACxD,YAAI;AACF,gBAAM,cAAc,KAAK,kBAAkB,WAAW;AACtD,gBAAM,WAAW,MAAM,KAAK,QAAQ,aAAa,WAAW,+BAA+B;AAE3F,cAAI,CAAC,SAAS,IAAI;AAChB,kBAAM,IAAI,MAAM,wCAAoB,SAAS,MAAM,EAAE;AAAA,UACvD;AAEA,gBAAM,OAAoB,MAAM,SAAS,KAAK;AAC9C,iBAAO,KAAK,KAAK,CAAC,GAAG,MAAM;AAEzB,mBAAO,KAAK,sBAAsB,EAAE,MAAM,EAAE,IAAI;AAAA,UAClD,CAAC;AAAA,QACH,SAAS,OAAO;AACd,gBAAM,IAAI,MAAM,mCAAe,KAAK,EAAE;AAAA,QACxC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,aAAa,aAA8C;AAC/D,YAAI;AACF,gBAAM,cAAc,KAAK,kBAAkB,WAAW;AACtD,gBAAM,WAAW,MAAM,KAAK,QAAQ,aAAa,WAAW,mCAAmC;AAE/F,cAAI,CAAC,SAAS,IAAI;AAChB,kBAAM,IAAI,MAAM,wCAAoB,SAAS,MAAM,EAAE;AAAA,UACvD;AAEA,gBAAM,WAA2B,MAAM,SAAS,KAAK;AAGrD,iBAAO,SAAS,KAAK,CAAC,GAAG,MAAM;AAC7B,gBAAI,EAAE,QAAS,QAAO;AACtB,gBAAI,EAAE,QAAS,QAAO;AACtB,mBAAO,EAAE,KAAK,cAAc,EAAE,IAAI;AAAA,UACpC,CAAC;AAAA,QACH,SAAS,OAAO;AACd,gBAAM,IAAI,MAAM,uCAAmB,KAAK,EAAE;AAAA,QAC5C;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,YAAY,aAAqB,KAA+B;AACpE,YAAI;AACF,gBAAM,OAAO,MAAM,KAAK,SAAS,WAAW;AAC5C,iBAAO,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,GAAG;AAAA,QACxC,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,eAAe,aAAqB,QAAkC;AAC1E,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,aAAa,WAAW;AACpD,iBAAO,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AAAA,QAC/C,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,WAAW,aAAoD;AACnE,YAAI;AACF,gBAAM,cAAc,KAAK,kBAAkB,WAAW;AACtD,gBAAM,WAAW,MAAM,KAAK,QAAQ,aAAa,WAAW,EAAE;AAE9D,cAAI,CAAC,SAAS,IAAI;AAChB,mBAAO;AAAA,UACT;AAEA,iBAAO,MAAM,SAAS,KAAK;AAAA,QAC7B,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,aAAa,aAAqB,KAAqC;AAC3E,YAAI;AACF,gBAAM,OAAO,MAAM,KAAK,SAAS,WAAW;AAC5C,gBAAM,YAAY,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,GAAG;AACjD,iBAAO,WAAW,OAAO,MAAM;AAAA,QACjC,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,gBAAgB,aAAqB,QAAwC;AACjF,YAAI;AACF,gBAAM,cAAc,KAAK,kBAAkB,WAAW;AACtD,gBAAM,WAAW,MAAM,KAAK;AAAA,YAC1B,aAAa,WAAW,wBAAwB,mBAAmB,MAAM,CAAC;AAAA,UAC5E;AAEA,cAAI,CAAC,SAAS,IAAI;AAChB,mBAAO;AAAA,UACT;AAEA,gBAAM,aAA2B,MAAM,SAAS,KAAK;AACrD,iBAAO,WAAW,OAAO;AAAA,QAC3B,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,gBACJ,aACA,MACA,IACkC;AAClC,YAAI;AACF,gBAAM,cAAc,KAAK,kBAAkB,WAAW;AACtD,gBAAM,WAAW,MAAM,KAAK;AAAA,YAC1B,aAAa,WAAW,4BAA4B,mBAAmB,IAAI,CAAC,OAAO,mBAAmB,EAAE,CAAC;AAAA,UAC3G;AAEA,cAAI,CAAC,SAAS,IAAI;AAChB,mBAAO;AAAA,UACT;AAEA,iBAAO,MAAM,SAAS,KAAK;AAAA,QAC7B,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA,MAMQ,sBAAsB,IAAY,IAAoB;AAE5D,cAAM,WAAW,GAAG,QAAQ,MAAM,EAAE;AACpC,cAAM,WAAW,GAAG,QAAQ,MAAM,EAAE;AAEpC,cAAM,SAAS,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,KAAK,CAAC;AAClE,cAAM,SAAS,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,KAAK,CAAC;AAElE,iBAAS,IAAI,GAAG,IAAI,KAAK,IAAI,OAAO,QAAQ,OAAO,MAAM,GAAG,KAAK;AAC/D,gBAAM,KAAK,OAAO,CAAC,KAAK;AACxB,gBAAM,KAAK,OAAO,CAAC,KAAK;AAExB,cAAI,KAAK,GAAI,QAAO;AACpB,cAAI,KAAK,GAAI,QAAO;AAAA,QACtB;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,iBAAiB,aAA+F;AACpH,YAAI;AACF,gBAAM,OAAO,MAAM,KAAK,SAAS,WAAW;AAC5C,gBAAM,WAAW,MAAM,KAAK,aAAa,WAAW;AAGpD,cAAI,KAAK,SAAS,GAAG;AACnB,kBAAM,YAAY,KAAK,CAAC;AACxB,mBAAO;AAAA,cACL,MAAM;AAAA,cACN,MAAM,UAAU;AAAA,cAChB,QAAQ,UAAU,OAAO;AAAA,YAC3B;AAAA,UACF;AAGA,gBAAM,gBAAgB,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO;AACpD,cAAI,eAAe;AACjB,mBAAO;AAAA,cACL,MAAM;AAAA,cACN,MAAM,cAAc;AAAA,cACpB,QAAQ,cAAc,OAAO;AAAA,YAC/B;AAAA,UACF;AAEA,iBAAO;AAAA,QACT,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,OAAO,iBAAiB,YAA4B;AAMlD,YAAIE,SAAO;AAGX,YAAIA,OAAK,WAAW,MAAM,GAAG;AAC3B,UAAAA,SAAOA,OAAK,QAAQ,SAAS,EAAE;AAC/B,gBAAM,aAAaA,OAAK,QAAQ,GAAG;AACnC,cAAI,eAAe,IAAI;AACrB,YAAAA,SAAOA,OAAK,UAAU,aAAa,CAAC;AAAA,UACtC;AAAA,QACF,OAAO;AAEL,UAAAA,SAAOA,OAAK,QAAQ,gBAAgB,EAAE;AAEtC,gBAAM,QAAQA,OAAK,MAAM,GAAG;AAC5B,cAAI,MAAM,SAAS,GAAG;AACpB,YAAAA,SAAO,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG;AAAA,UAChC;AAAA,QACF;AAGA,QAAAA,SAAOA,OAAK,QAAQ,UAAU,EAAE;AAEhC,eAAOA;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKQ,kBAAkB,aAA6B;AAGrD,eAAO,mBAAmB,WAAW,EAAE,QAAQ,QAAQ,KAAK;AAAA,MAC9D;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,QAAQ,UAAkB,UAAuB,CAAC,GAAsB;AACpF,cAAM,MAAM,GAAG,KAAK,OAAO,OAAO,UAAU,QAAQ;AAEpD,cAAM,UAAuB;AAAA,UAC3B,iBAAiB,KAAK,OAAO;AAAA,UAC7B,gBAAgB;AAAA,UAChB,GAAG,QAAQ;AAAA,QACb;AAEA,cAAM,aAAa,IAAI,gBAAgB;AACvC,cAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,OAAO,OAAO;AAE1E,YAAI;AACF,gBAAM,WAAW,MAAM,MAAM,KAAK;AAAA,YAChC,GAAG;AAAA,YACH;AAAA,YACA,QAAQ,WAAW;AAAA,UACrB,CAAC;AAED,iBAAO;AAAA,QACT,SAAS,OAAY;AACnB,cAAI,MAAM,SAAS,cAAc;AAC/B,kBAAM,IAAI,MAAM,0BAAM;AAAA,UACxB;AACA,gBAAM;AAAA,QACR,UAAE;AACA,uBAAa,SAAS;AAAA,QACxB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,iBAAiB,aAA6C;AAClE,YAAI;AACF,gBAAM,UAAU,MAAM,KAAK,WAAW,WAAW;AACjD,iBAAO,SAAS,kBAAkB;AAAA,QACpC,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACnZA,SAAS,WAAAC,iBAAe;AACxB,OAAOC,YAAU;AASjB,SAAS,SAAAC,cAAa;AACtB,OAAOC,gBAAc;AAErB,OAAOC,SAAQ;AA4If,eAAe,cACb,aACA,SACe;AACf,SAAO,QAAQ;AACf,SAAO,KAAK,yCAAW;AAEvB,aAAW,UAAU,SAAS;AAC5B,UAAM,EAAE,MAAM,MAAM,cAAc,IAAI;AACtC,UAAM,YAAY,SAAS,aAAa,aAAa;AACrD,UAAM,aAAaH,OAAK,KAAK,aAAa,SAAS;AAEnD,WAAO,QAAQ;AACf,WAAO,KAAK,gBAAM,SAAS,aAAa,iBAAO,cAAI,iBAAO;AAG1D,QAAI,eAAe,OAAO,eAAe,QAAQ;AAC/C,YAAM,EAAE,mBAAAI,mBAAkB,IAAI,MAAM;AACpC,YAAM,EAAE,WAAAC,WAAU,IAAI,MAAM;AAE5B,YAAM,SAAS,MAAMD,mBAAkB,gBAAgB;AACvD,UAAI,QAAQ;AACV,cAAM,YAAY,IAAIC,WAAU,MAAM;AACtC,cAAM,qBAAqBA,WAAU,iBAAiB,KAAK,UAAU;AAErE,YAAI,cAAc,KAAK;AACrB,gBAAM,UAAU,MAAM,UAAU,YAAY,oBAAoB,cAAc,GAAG;AACjF,cAAI,CAAC,SAAS;AACZ,mBAAO,MAAM,GAAG,SAAS,aAAa,iBAAO,cAAI,qBAAW,cAAc,GAAG,sBAAO;AACpF;AAAA,UACF;AACA,iBAAO,KAAK,gBAAM,SAAS,aAAa,iBAAO,cAAI,qBAAW,cAAc,GAAG,EAAE;AAAA,QACnF;AAEA,YAAI,cAAc,QAAQ;AACxB,gBAAM,UAAU,MAAM,UAAU,eAAe,oBAAoB,cAAc,MAAM;AACvF,cAAI,CAAC,SAAS;AACZ,mBAAO,MAAM,GAAG,SAAS,aAAa,iBAAO,cAAI,6BAAS,cAAc,MAAM,sBAAO;AACrF;AAAA,UACF;AACA,iBAAO,KAAK,gBAAM,SAAS,aAAa,iBAAO,cAAI,6BAAS,cAAc,MAAM,EAAE;AAAA,QACpF;AAAA,MACF,OAAO;AACL,eAAO,KAAK,2EAAyB;AAAA,MACvC;AAAA,IACF;AAGA,UAAM,MAAM,eAAe,OAAO,eAAe,UAAU;AAG3D,UAAM,YAAYL,OAAK,KAAK,aAAa,WAAW,KAAK,IAAI,CAAC,EAAE;AAChE,UAAMG,IAAG,KAAK,YAAYH,OAAK,KAAK,WAAW,SAAS,CAAC;AACzD,WAAO,KAAK,mCAAU,SAAS,EAAE;AAGjC,QAAI,eAAe,QAAQ;AACzB,aAAO,KAAK,mEAAsB;AAClC,aAAO,KAAK,UAAU,GAAG,EAAE;AAC3B,aAAO,KAAK,mBAAS,KAAK,UAAU,EAAE;AACtC,aAAO,KAAK,0EAAc;AAC1B;AAAA,IACF;AAEA,QAAI;AAEF,YAAM,UAAUA,OAAK,KAAK,aAAa,oBAAoB,KAAK,IAAI,CAAC,EAAE;AAEvE,YAAMC,OAAM,OAAO,CAAC,SAAS,aAAa,YAAY,KAAK,KAAK,YAAY,OAAO,GAAG;AAAA,QACpF,OAAO;AAAA,MACT,CAAC;AAGD,YAAM,EAAE,QAAQ,OAAO,IAAI,MAAMA,OAAM,OAAO,CAAC,aAAa,MAAM,GAAG;AAAA,QACnE,KAAK;AAAA,QACL,OAAO;AAAA,MACT,CAAC;AAGD,YAAM,EAAE,QAAQ,KAAK,IAAI,MAAMA,OAAM,OAAO,CAAC,OAAO,MAAM,mBAAmB,GAAG;AAAA,QAC9E,KAAK;AAAA,QACL,OAAO;AAAA,MACT,CAAC;AACD,YAAM,YAAY,KAAK,MAAM,IAAI,EAAE,CAAC,KAAK;AAGzC,YAAM,YAAY,CAAC,cAAc,qBAAqB,cAAc;AACpE,YAAM,eAAe,MAAM,UAAU,UAAU,KAAK,UAAU;AAE9D,iBAAW,QAAQ,cAAc;AAC/B,YAAI,CAAC,UAAU,SAAS,IAAI,GAAG;AAC7B,gBAAM,WAAWD,OAAK,KAAK,YAAY,IAAI;AAC3C,cAAI;AACF,kBAAMG,IAAG,OAAO,QAAQ;AAAA,UAC1B,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF;AAGA,YAAMA,IAAG,KAAK,SAAS,YAAY;AAAA,QACjC,QAAQ,CAAC,QAAQ,CAAC,IAAI,SAAS,MAAM;AAAA,MACvC,CAAC;AAGD,YAAMA,IAAG,OAAO,OAAO;AAGvB,YAAM,sBAAsB,aAAa,MAAM,OAAO,KAAK,GAAG;AAAA,QAC5D,KAAK,eAAe,OAAO;AAAA,QAC3B,QAAQ,eAAe;AAAA,MACzB,CAAC;AAED,aAAO,QAAQ,GAAG,SAAS,aAAa,iBAAO,cAAI,uCAAS;AAC5D,aAAO,KAAK,uBAAQ,eAAe,OAAO,eAAe,UAAU,aAAa,OAAO,UAAU,GAAG,CAAC,CAAC,EAAE;AACxG,aAAO,KAAK,6BAAS,SAAS,EAAE;AAAA,IAClC,SAAS,OAAY;AACnB,aAAO,MAAM,6BAAS,MAAM,OAAO,EAAE;AACrC,aAAO,KAAK,yCAAW;AAGvB,YAAMA,IAAG,OAAO,UAAU;AAC1B,YAAMA,IAAG,KAAKH,OAAK,KAAK,WAAW,SAAS,GAAG,UAAU;AACzD,YAAMG,IAAG,OAAO,SAAS;AAEzB,aAAO,KAAK,8DAAY;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO,QAAQ;AACf,SAAO,OAAO,uCAAS;AACvB,SAAO,QAAQ;AACf,SAAO,KAAK,qBAAM;AAClB,SAAO,KAAK,qDAAa;AACzB,SAAO,KAAK,4DAAyB;AACrC,SAAO,KAAK,iEAAe;AAC3B,SAAO,KAAK,uCAAc;AAC1B,SAAO,QAAQ;AACjB;AApSA,IA2Ba;AA3Bb;AAAA;AAAA;AAAA;AAEA;AAMA;AACA;AAkBO,IAAM,gBAAgB,IAAIJ,UAAQ,QAAQ,EAC9C,YAAY,wDAAW,EACvB,OAAO,kBAAkB,kDAAU,EACnC,OAAO,iBAAiB,kDAAU,EAClC,OAAO,aAAa,qDAAa,EACjC,OAAO,mBAAmB,4CAAS,EACnC,OAAO,yBAAyB,4CAAS,EACzC,OAAO,aAAa,8DAAY,EAChC,OAAO,OAAO,YAAY;AACzB,UAAI;AACF,eAAO,OAAO,sCAAQ;AACtB,eAAO,QAAQ;AAGf,cAAM,YAAY,MAAM,UAAU,OAAO,eAAe;AACxD,YAAI,CAAC,WAAW;AACd,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,wDAAW;AACvB,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,cAAM,cAAc;AACpB,cAAM,WAAW,CAAC,QAAQ,YAAY,CAAC,QAAQ;AAC/C,cAAM,gBAAgB,QAAQ,YAAY;AAC1C,cAAM,eAAe,QAAQ,WAAW;AAGxC,cAAM,cAAc,QAAQ,OAAO,QAAQ;AAE3C,cAAM,UAAmF,CAAC;AAC1F,cAAM,gBAA+B;AAAA,UACnC,KAAK,QAAQ;AAAA,UACb,QAAQ,QAAQ;AAAA,UAChB,QAAQ,QAAQ;AAAA,QAClB;AAGA,YAAI,eAAe;AACjB,iBAAO,KAAK,yCAAW;AACvB,gBAAM,eAAe,MAAM,oBAAoB,aAAa,UAAU;AAEtE,cAAI,cAAc;AAChB,gBAAI,aAAa,eAAe,aAAa;AAC3C,oBAAM,UAAU,cAAc,OAAO,cAAc,UAAU,aAAa,aAAa,aAAa,cAAc,UAAU,GAAG,CAAC;AAChI,qBAAO,QAAQ,2BAAO,cAAc,uBAAQ,oBAAK,KAAK,OAAO,GAAG;AAChE,sBAAQ,KAAK,EAAE,MAAM,YAAY,MAAM,cAAc,cAAc,CAAC;AAAA,YACtE,OAAO;AACL,qBAAO,KAAK,8DAAY;AAAA,YAC1B;AAAA,UACF,OAAO;AACL,mBAAO,KAAK,0EAAc;AAAA,UAC5B;AACA,iBAAO,QAAQ;AAAA,QACjB;AAGA,YAAI,cAAc;AAChB,iBAAO,KAAK,yCAAW;AACvB,gBAAM,cAAc,MAAM,oBAAoB,aAAa,SAAS;AAEpE,cAAI,aAAa;AACf,gBAAI,YAAY,eAAe,aAAa;AAC1C,oBAAM,UAAU,cAAc,OAAO,cAAc,UAAU,YAAY,aAAa,YAAY,cAAc,UAAU,GAAG,CAAC;AAC9H,qBAAO,QAAQ,2BAAO,cAAc,uBAAQ,oBAAK,KAAK,OAAO,GAAG;AAChE,sBAAQ,KAAK,EAAE,MAAM,WAAW,MAAM,aAAa,cAAc,CAAC;AAAA,YACpE,OAAO;AACL,qBAAO,KAAK,8DAAY;AAAA,YAC1B;AAAA,UACF,OAAO;AACL,mBAAO,KAAK,0EAAc;AAAA,UAC5B;AACA,iBAAO,QAAQ;AAAA,QACjB;AAGA,YAAI,QAAQ,WAAW,GAAG;AACxB,iBAAO,QAAQ,+DAAa;AAC5B;AAAA,QACF;AAEA,YAAI,QAAQ,QAAQ;AAClB,iBAAO,OAAO,0BAAgB,QAAQ,MAAM,qBAAM;AAAA,QACpD,OAAO;AACL,iBAAO,OAAO,gBAAM,QAAQ,MAAM,iCAAQ;AAAA,QAC5C;AACA,eAAO,QAAQ;AAEf,mBAAW,UAAU,SAAS;AAC5B,gBAAM,UAAU,OAAO,eAAe,OAAO,OAAO,eAAe,UAAU,OAAO,KAAK,aAAa,OAAO,KAAK,cAAc,UAAU,GAAG,CAAC;AAC9I,iBAAO,KAAK,GAAG,OAAO,SAAS,aAAa,iBAAO,cAAI,iBAAO,OAAO,EAAE;AAAA,QACzE;AACA,eAAO,QAAQ;AAGf,YAAI,QAAQ,QAAQ;AAClB,iBAAO,KAAK,sEAAoB;AAChC;AAAA,QACF;AAGA,cAAM,UAAU,MAAMG,WAAS,OAAO;AAAA,UACpC;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SAAS;AAAA,UACX;AAAA,QACF,CAAC;AAED,YAAI,QAAQ,cAAc;AACxB,gBAAM,cAAc,aAAa,OAAO;AAAA,QAC1C,OAAO;AACL,iBAAO,KAAK,gCAAO;AAAA,QACrB;AAAA,MACF,SAAS,OAAY;AACnB,eAAO,MAAM,yCAAW,MAAM,OAAO,EAAE;AACvC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAAA;AAAA;;;ACpJH,SAAS,WAAAI,iBAAe;AACxB,OAAOC,gBAAc;AACrB,OAAOC,YAAW;AAFlB,IAUa,iBAwFA,mBAmDA,qBAwCA,sBA0CA;AAvOb;AAAA;AAAA;AAAA;AAGA;AACA;AACA;AAKO,IAAM,kBAAkB,IAAIF,UAAQ,WAAW,EACnD,YAAY,kCAAwB,EACpC,OAAO,uBAAuB,cAAc,EAC5C,OAAO,mBAAmB,mBAAmB,oBAAoB,EACjE,OAAO,OAAO,YAAY;AACzB,UAAI;AACF,eAAO,OAAO,kCAAwB;AACtC,eAAO,QAAQ;AAEf,YAAI,EAAE,OAAO,IAAI,IAAI;AAGrB,YAAI,CAAC,OAAO;AACV,gBAAM,UAAU,MAAMC,WAAS,OAAO;AAAA,YACpC;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,MAAM;AAAA,cACN,UAAU,CAAC,UAAkB;AAC3B,oBAAI,CAAC,SAAS,MAAM,KAAK,EAAE,WAAW,GAAG;AACvC,yBAAO;AAAA,gBACT;AACA,uBAAO;AAAA,cACT;AAAA,YACF;AAAA,YACA;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,SAAS;AAAA,cACT,UAAU,CAAC,UAAkB;AAC3B,oBAAI;AACF,sBAAI,IAAI,KAAK;AACb,yBAAO;AAAA,gBACT,QAAQ;AACN,yBAAO;AAAA,gBACT;AAAA,cACF;AAAA,YACF;AAAA,UACF,CAAC;AACD,kBAAQ,QAAQ;AAChB,gBAAM,QAAQ;AAAA,QAChB;AAGA,YAAI;AACF,cAAI,IAAI,GAAG;AAAA,QACb,QAAQ;AACN,iBAAO,MAAM,+BAAgB;AAC7B,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAGA,cAAM,IAAI,QAAQ,QAAQ,EAAE;AAE5B,eAAO,KAAK,uBAAa;AACzB,cAAM,YAAY,IAAI,UAAU,EAAE,aAAa,OAAO,SAAS,IAAI,CAAC;AACpE,cAAM,UAAU,MAAM,UAAU,aAAa;AAE7C,YAAI,CAAC,SAAS;AACZ,iBAAO,MAAM,yDAAiB;AAC9B,iBAAO,KAAK,mCAAe;AAC3B,iBAAO,KAAK,8CAAqB;AACjC,iBAAO,KAAK,wCAAoB;AAChC,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,eAAO,QAAQ,iCAAa;AAG5B,cAAM,kBAAkB,kBAAkB,OAAO,GAAG;AACpD,eAAO,QAAQ,iCAAQ;AACvB,eAAO,QAAQ;AACf,eAAO,KAAK,eAAeC,OAAM,KAAK,GAAG,CAAC,EAAE;AAC5C,eAAO,KAAK,6BAASA,OAAM,KAAK,kBAAkB,cAAc,CAAC,CAAC,EAAE;AAAA,MACtE,SAAS,OAAY;AACnB,eAAO,MAAM,6BAAS,MAAM,OAAO,EAAE;AACrC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAKI,IAAM,oBAAoB,IAAIF,UAAQ,MAAM,EAChD,YAAY,sCAAQ,EACpB,OAAO,YAAY;AAClB,UAAI;AACF,eAAO,OAAO,qBAAW;AACzB,eAAO,QAAQ;AAEf,cAAM,YAAY,MAAM,kBAAkB,UAAU;AAEpD,YAAI,CAAC,WAAW;AACd,iBAAO,KAAK,wCAAyB;AACrC,iBAAO,KAAK,yEAAsC;AAAA,QACpD,OAAO;AACL,gBAAM,SAAS,MAAM,kBAAkB,KAAK;AAE5C,cAAI,QAAQ,QAAQ;AAClB,kBAAM,QAAQ,OAAO,OAAO;AAC5B,kBAAM,cAAc,QAAQ,GAAG,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,IAAI,OAAO,KAAK,IAAI,IAAI,MAAM,SAAS,CAAC,CAAC,CAAC,KAAK;AAEtG,mBAAO,KAAK,eAAeE,OAAM,KAAK,OAAO,OAAO,OAAO,CAAC,EAAE;AAC9D,mBAAO,KAAK,iBAAiBA,OAAM,OAAO,WAAW,CAAC,EAAE;AACxD,mBAAO,KAAK,YAAYA,OAAM,KAAK,OAAO,OAAO,WAAW,GAAK,CAAC,IAAI;AAEtE,gBAAI,OAAO,aAAa;AACtB,qBAAO,QAAQ;AACf,qBAAO,KAAK,2BAAO;AACnB,kBAAI,OAAO,YAAY,sBAAsB;AAC3C,uBAAO,KAAK,2CAAaA,OAAM,KAAK,OAAO,YAAY,oBAAoB,CAAC,EAAE;AAAA,cAChF;AACA,kBAAI,OAAO,YAAY,uBAAuB;AAC5C,uBAAO,KAAK,2CAAaA,OAAM,KAAK,OAAO,YAAY,qBAAqB,CAAC,EAAE;AAAA,cACjF;AAAA,YACF;AAEA,mBAAO,QAAQ;AACf,mBAAO,KAAK,uCAAS;AACrB,mBAAO,KAAK,KAAKA,OAAM,KAAK,kBAAkB,cAAc,CAAC,CAAC,EAAE;AAAA,UAClE;AAAA,QACF;AAAA,MACF,SAAS,OAAY;AACnB,eAAO,MAAM,yCAAW,MAAM,OAAO,EAAE;AACvC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAKI,IAAM,sBAAsB,IAAIF,UAAQ,QAAQ,EACpD,MAAM,IAAI,EACV,YAAY,kCAAc,EAC1B,OAAO,YAAY;AAClB,UAAI;AACF,cAAM,YAAY,MAAM,kBAAkB,UAAU;AAEpD,YAAI,CAAC,WAAW;AACd,iBAAO,KAAK,wCAAyB;AACrC;AAAA,QACF;AAEA,cAAM,UAAU,MAAMC,WAAS,OAAO;AAAA,UACpC;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SAAS;AAAA,UACX;AAAA,QACF,CAAC;AAED,YAAI,CAAC,QAAQ,SAAS;AACpB,iBAAO,KAAK,oBAAK;AACjB;AAAA,QACF;AAEA,cAAM,kBAAkB,aAAa;AACrC,eAAO,QAAQ,gCAAO;AAAA,MACxB,SAAS,OAAY;AACnB,eAAO,MAAM,yCAAW,MAAM,OAAO,EAAE;AACvC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAKI,IAAM,uBAAuB,IAAID,UAAQ,UAAU,EACvD,MAAM,MAAM,EACZ,YAAY,yDAAiB,EAC7B,OAAO,YAAY;AAClB,UAAI;AACF,eAAO,OAAO,2BAAiB;AAC/B,eAAO,QAAQ;AAEf,cAAM,SAAS,MAAM,kBAAkB,gBAAgB;AAEvD,YAAI,CAAC,QAAQ;AACX,iBAAO,KAAK,wCAAyB;AACrC,iBAAO,KAAK,yEAAsC;AAClD,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,eAAO,KAAK,6BAAS;AAErB,cAAM,YAAY,IAAI,UAAU,MAAM;AACtC,cAAM,UAAU,MAAM,UAAU,aAAa;AAE7C,YAAI,SAAS;AACX,iBAAO,QAAQ,qBAAW;AAC1B,iBAAO,QAAQ;AACf,iBAAO,KAAK,eAAeE,OAAM,KAAK,OAAO,OAAO,CAAC,EAAE;AAAA,QACzD,OAAO;AACL,iBAAO,MAAM,gCAAY;AACzB,iBAAO,KAAK,2EAAoB;AAChC,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAAA,MACF,SAAS,OAAY;AACnB,eAAO,MAAM,6BAAS,MAAM,OAAO,EAAE;AACrC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAKI,IAAM,gBAAgB,IAAIF,UAAQ,QAAQ,EAC9C,YAAY,kCAAc,EAC1B,WAAW,eAAe,EAC1B,WAAW,iBAAiB,EAC5B,WAAW,mBAAmB,EAC9B,WAAW,oBAAoB;AAAA;AAAA;;;AC5OlC,SAAS,WAAAG,iBAAe;AAExB,OAAOC,YAAW;AAoHlB,eAAe,gBACb,aACA,MACA,aACA,WACA,cACA,cAC0F;AAC1F,MAAI;AACF,WAAO,KAAK,eAAK,SAAS,aAAa,iBAAO,cAAI,iBAAO;AAEzD,UAAM,aAAa,YAAY;AAC/B,UAAM,cAAc,YAAY;AAChC,UAAM,WAAW,YAAY;AAC7B,UAAM,cAAc,YAAY;AAEhC,QAAI,eAA8B;AAClC,QAAI;AACJ,QAAI;AAGJ,QAAI,cAAc;AAChB,YAAM,YAAY,IAAI,UAAU,YAAY;AAC5C,YAAM,qBAAqB,UAAU,iBAAiB,UAAU;AAEhE,UAAI,WAAW;AAEb,uBAAe,MAAM,UAAU,aAAa,oBAAoB,SAAS;AACzE,wBAAgB;AAAA,MAClB,WAAW,cAAc;AAEvB,uBAAe,MAAM,UAAU,gBAAgB,oBAAoB,YAAY;AAC/E,2BAAmB;AAAA,MACrB,OAAO;AAEL,cAAM,SAAS,MAAM,UAAU,iBAAiB,kBAAkB;AAClE,YAAI,QAAQ;AACV,yBAAe,OAAO;AACtB,cAAI,OAAO,SAAS,OAAO;AACzB,4BAAgB,OAAO;AAAA,UACzB,OAAO;AACL,+BAAmB,OAAO;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAGA,UAAI,gBAAgB,eAAe,iBAAiB,aAAa;AAC/D,cAAM,OAAO,YAAY,eAAe;AACxC,cAAM,KAAK,iBAAiB,oBAAoB;AAChD,cAAM,OAAO,MAAM,UAAU,gBAAgB,oBAAoB,MAAM,EAAE;AAEzE,eAAO;AAAA,UACL;AAAA,UACA,OAAO;AAAA,YACL,QAAQ;AAAA,YACR,KAAK;AAAA,YACL,QAAQ;AAAA,UACV;AAAA,UACA,QAAQ;AAAA,YACN,QAAQ;AAAA,YACR,KAAK;AAAA,YACL,QAAQ;AAAA,UACV;AAAA,UACA,MAAM,QAAQ;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAGA,QAAI,CAAC,cAAc;AAEjB,YAAM,EAAE,OAAAC,OAAM,IAAI,MAAM,OAAO,OAAO;AACtC,YAAM,MAAM,aAAa,gBAAgB;AACzC,YAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO,CAAC,aAAa,YAAY,GAAG,GAAG;AAAA,QACpE,OAAO;AAAA,MACT,CAAC;AACD,qBAAe,OAAO,MAAM,GAAI,EAAE,CAAC;AACnC,sBAAgB;AAChB,yBAAmB;AAAA,IACrB;AAEA,UAAM,cAAc,gBAAgB;AAEpC,WAAO;AAAA,MACL,GAAG,SAAS,aAAa,iBAAO,cAAI,iBAAO,cAAcD,OAAM,OAAO,oBAAK,IAAIA,OAAM,MAAM,0BAAM,CAAC;AAAA,IACpG;AAEA,WAAO;AAAA,MACL;AAAA,MACA,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,KAAK;AAAA,QACL,QAAQ;AAAA,MACV;AAAA,MACA,QAAQ;AAAA,QACN,QAAQ,gBAAgB;AAAA,QACxB,KAAK;AAAA,QACL,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,WAAO,MAAM,eAAK,SAAS,aAAa,iBAAO,cAAI,6BAAS,KAAK,EAAE;AACnE,WAAO;AAAA,EACT;AACF;AAKA,SAAS,YAAY,SAAgG;AACnH,SAAO,QAAQ;AAEf,aAAW,UAAU,SAAS;AAC5B,UAAM,WAAW,OAAO,SAAS,aAAa,iBAAO;AACrD,YAAQ,IAAIA,OAAM,KAAK,GAAG,QAAQ,eAAK,CAAC;AACxC,YAAQ,IAAI,EAAE;AAEd,UAAM,IAAI,IAAI,MAAM;AAAA,MAClB,MAAM,CAACA,OAAM,KAAK,cAAI,GAAGA,OAAM,KAAK,cAAI,CAAC;AAAA,MACzC,WAAW,CAAC,IAAI,EAAE;AAAA,IACpB,CAAC;AAGD,UAAM,eAAe,OAAO,MAAM,OAAO,OAAO,MAAM,UAAU,OAAO,MAAM,QAAQ,UAAU,GAAG,CAAC,KAAK;AACxG,UAAM,YAAY,WAAW,OAAO,MAAM,QAAQ,UAAU,GAAG,CAAC,KAAK,GAAG,GAAG,OAAO,MAAM,MAAM;AAAA,OAAU,OAAO,MAAM,GAAG,KAAK,EAAE,GAAG,OAAO,MAAM,SAAS;AAAA,UAAa,OAAO,MAAM,MAAM,KAAK,EAAE;AAC/L,MAAE,KAAK,CAAC,gBAAM,SAAS,CAAC;AAGxB,UAAM,gBAAgB,OAAO,OAAO,OAAO,OAAO,OAAO,UAAU,OAAO,OAAO,QAAQ,UAAU,GAAG,CAAC,KAAK;AAC5G,UAAM,aAAa,WAAW,OAAO,OAAO,QAAQ,UAAU,GAAG,CAAC,KAAK,GAAG,GAAG,OAAO,OAAO,MAAM;AAAA,OAAU,OAAO,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,OAAO,SAAS;AAAA,UAAa,OAAO,OAAO,MAAM,KAAK,EAAE;AACrM,MAAE,KAAK,CAAC,gBAAM,UAAU,CAAC;AAEzB,YAAQ,IAAI,EAAE,SAAS,CAAC;AAGxB,QAAI,OAAO,QAAQ,OAAO,KAAK,QAAQ,SAAS,GAAG;AACjD,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAIA,OAAM,KAAK,2BAAO,CAAC;AAE/B,YAAM,eAAe,IAAI,MAAM;AAAA,QAC7B,MAAM,CAACA,OAAM,KAAK,QAAQ,GAAGA,OAAM,KAAK,cAAI,GAAGA,OAAM,KAAK,cAAI,GAAGA,OAAM,KAAK,cAAI,CAAC;AAAA,QACjF,WAAW,CAAC,IAAI,IAAI,IAAI,EAAE;AAAA,QAC1B,UAAU;AAAA,MACZ,CAAC;AAED,iBAAW,UAAU,OAAO,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG;AACrD,qBAAa,KAAK;AAAA,UAChB,OAAO;AAAA,UACP,OAAO;AAAA,UACP,IAAI,KAAK,OAAO,UAAU,EAAE,mBAAmB,OAAO;AAAA,UACtD,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAEA,cAAQ,IAAI,aAAa,SAAS,CAAC;AAEnC,UAAI,OAAO,KAAK,QAAQ,SAAS,IAAI;AACnC,gBAAQ,IAAIA,OAAM,KAAK,oBAAU,OAAO,KAAK,QAAQ,SAAS,EAAE,qBAAM,CAAC;AAAA,MACzE;AAGA,YAAM,QAAQ,OAAO,KAAK;AAC1B,YAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE;AAC9C,YAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE;AACpD,YAAM,WAAW,MAAM,SAAS,QAAQ;AAExC,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAIA,OAAM,KAAK,2BAAO,CAAC;AAC/B,cAAQ,IAAI,KAAKA,OAAM,MAAM,GAAG,CAAC,kBAAQ,KAAK,EAAE;AAChD,cAAQ,IAAI,KAAKA,OAAM,IAAI,GAAG,CAAC,kBAAQ,OAAO,EAAE;AAChD,cAAQ,IAAI,KAAKA,OAAM,OAAO,GAAG,CAAC,kBAAQ,QAAQ,EAAE;AAAA,IACtD;AAEA,YAAQ,IAAI,EAAE;AAAA,EAChB;AACF;AAKA,SAAS,WAAW,SAAgG;AAClH,UAAQ,IAAI,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAC9C;AAKA,SAAS,WAAW,SAAgG;AAClH,SAAO,QAAQ;AAEf,aAAW,UAAU,SAAS;AAC5B,UAAM,WAAW,OAAO,SAAS,aAAa,iBAAO;AACrD,YAAQ,IAAIA,OAAM,KAAK,GAAG,QAAQ,eAAK,CAAC;AACxC,YAAQ,IAAI,EAAE;AAEd,UAAM,OAAO,OAAO,MAAM,OAAO,OAAO,MAAM,UAAU,OAAO,MAAM,QAAQ,UAAU,GAAG,CAAC,KAAK;AAChG,UAAM,KAAK,OAAO,OAAO,OAAO,OAAO,OAAO,UAAU,OAAO,OAAO,QAAQ,UAAU,GAAG,CAAC,KAAK;AAEjG,YAAQ,IAAI,6BAASA,OAAM,KAAK,IAAI,CAAC,EAAE;AACvC,YAAQ,IAAI,6BAASA,OAAM,KAAK,EAAE,CAAC,EAAE;AAErC,QAAI,OAAO,QAAQ,OAAO,KAAK,QAAQ,SAAS,GAAG;AACjD,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAIA,OAAM,KAAK,2BAAO,CAAC;AAE/B,iBAAW,UAAU,OAAO,KAAK,SAAS;AACxC,gBAAQ,IAAI,EAAE;AACd,gBAAQ,IAAIA,OAAM,OAAO,UAAU,OAAO,EAAE,EAAE,CAAC;AAC/C,gBAAQ,IAAI,WAAW,OAAO,WAAW,KAAK,OAAO,YAAY,GAAG;AACpE,gBAAQ,IAAI,SAAS,IAAI,KAAK,OAAO,UAAU,EAAE,eAAe,OAAO,CAAC,EAAE;AAC1E,gBAAQ,IAAI,EAAE;AACd,gBAAQ,IAAI,OAAO,OAAO,KAAK,EAAE;AACjC,YAAI,OAAO,SAAS;AAClB,kBAAQ,IAAI,OAAO,OAAO,QAAQ,MAAM,IAAI,EAAE,KAAK,QAAQ,CAAC,EAAE;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAEA,YAAQ,IAAI,EAAE;AAAA,EAChB;AACF;AAnVA,IAaa,aA2UP;AAxVN;AAAA;AAAA;AAAA;AAIA;AACA;AACA;AACA;AACA;AAKO,IAAM,cAAc,IAAID,UAAQ,MAAM,EAC1C,YAAY,oEAAa,EACzB,OAAO,kBAAkB,sCAAQ,EACjC,OAAO,iBAAiB,sCAAQ,EAChC,OAAO,mBAAmB,sCAAQ,EAClC,OAAO,yBAAyB,sCAAQ,EACxC,OAAO,yBAAyB,8CAA0B,OAAO,EACjE,OAAO,OAAO,YAAY;AACzB,UAAI;AACF,eAAO,OAAO,sCAAQ;AACtB,eAAO,QAAQ;AAGf,cAAM,YAAY,MAAM,UAAU,OAAO,eAAe;AACxD,YAAI,CAAC,WAAW;AACd,iBAAO,MAAM,0FAAyB;AACtC,iBAAO,KAAK,wDAAW;AACvB,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,cAAM,cAAc;AACpB,cAAM,WAAW,CAAC,QAAQ,YAAY,CAAC,QAAQ;AAC/C,cAAM,gBAAgB,QAAQ,YAAY;AAC1C,cAAM,eAAe,QAAQ,WAAW;AAExC,cAAM,SAAS,MAAM,mBAAmB,WAAW;AACnD,YAAI,CAAC,QAAQ;AACX,iBAAO,MAAM,4CAAS;AACtB,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAEA,cAAM,eAAe,MAAM,kBAAkB,gBAAgB;AAC7D,YAAI,CAAC,cAAc;AACjB,iBAAO,KAAK,iCAAkB;AAC9B,iBAAO,KAAK,yEAAsC;AAClD,iBAAO,KAAK,yEAAkB;AAAA,QAChC;AAEA,cAAM,UAKD,CAAC;AAGN,YAAI,iBAAiB,OAAO,UAAU;AACpC,gBAAM,SAAS,MAAM;AAAA,YACnB;AAAA,YACA;AAAA,YACA,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,gBAAgB;AAAA,UAClB;AACA,cAAI,QAAQ;AACV,oBAAQ,KAAK,MAAM;AAAA,UACrB;AAAA,QACF;AAGA,YAAI,gBAAgB,OAAO,SAAS;AAClC,gBAAM,SAAS,MAAM;AAAA,YACnB;AAAA,YACA;AAAA,YACA,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,gBAAgB;AAAA,UAClB;AACA,cAAI,QAAQ;AACV,oBAAQ,KAAK,MAAM;AAAA,UACrB;AAAA,QACF;AAEA,YAAI,QAAQ,WAAW,GAAG;AACxB,iBAAO,KAAK,kDAAU;AACtB;AAAA,QACF;AAGA,gBAAQ,QAAQ,QAAQ;AAAA,UACtB,KAAK;AACH,uBAAW,OAAO;AAClB;AAAA,UACF,KAAK;AACH,uBAAW,OAAO;AAClB;AAAA,UACF,KAAK;AAAA,UACL;AACE,wBAAY,OAAO;AACnB;AAAA,QACJ;AAAA,MACF,SAAS,OAAY;AACnB,eAAO,MAAM,6BAAS,MAAM,OAAO,EAAE;AACrC,YAAI,QAAQ,IAAI,OAAO;AACrB,kBAAQ,MAAM,KAAK;AAAA,QACrB;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAuOH,IAAM,QAAN,MAAY;AAAA,MACF;AAAA,MACA,OAAgB,CAAC;AAAA,MAEzB,YAAY,SAAc;AACxB,aAAK,UAAU;AAAA,MACjB;AAAA,MAEA,KAAK,KAAkB;AACrB,aAAK,KAAK,KAAK,GAAG;AAAA,MACpB;AAAA,MAEA,WAAmB;AACjB,YAAI,KAAK,KAAK,WAAW,EAAG,QAAO;AAEnC,YAAI,SAAS;AACb,cAAM,YAAY,KAAK,QAAQ,aAAa,CAAC;AAG7C,YAAI,KAAK,QAAQ,MAAM;AACrB,oBAAU;AACV,mBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,QAAQ,KAAK;AACjD,kBAAM,QAAQ,UAAU,CAAC,KAAK;AAC9B,kBAAM,OAAO,KAAK,QAAQ,KAAK,CAAC,KAAK;AACrC,sBAAU,KAAK,OAAO,KAAK,IAAI;AAAA,UACjC;AACA,oBAAU;AAGV,oBAAU;AACV,mBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,QAAQ,KAAK;AACjD,kBAAM,QAAQ,UAAU,CAAC,KAAK;AAC9B,sBAAU,IAAI,OAAO,QAAQ,CAAC,IAAI;AAAA,UACpC;AACA,oBAAU;AAAA,QACZ;AAGA,mBAAW,OAAO,KAAK,MAAM;AAC3B,oBAAU;AACV,mBAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,kBAAM,QAAQ,UAAU,CAAC,KAAK;AAC9B,kBAAM,OAAO,OAAO,IAAI,CAAC,KAAK,EAAE;AAChC,kBAAM,cAAc,KAAK,QAAQ,YAAY,KAAK,SAAS,QAAQ,KAAK,UAAU,GAAG,QAAQ,CAAC,IAAI,QAAQ;AAC1G,sBAAU,YAAY,OAAO,KAAK,IAAI;AAAA,UACxC;AACA,oBAAU;AAAA,QACZ;AAEA,eAAO;AAAA,MACT;AAAA,IACF;AAAA;AAAA;;;AC3YA;AAEA,SAAS,WAAAG,iBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,SAAQ;AACf,OAAOC,YAAU;AACjB,SAAS,iBAAAC,sBAAqB;AAoE9B,SAAS,WAAW;AAClB,UAAQ,IAAI,EAAE;AACd,SAAO,OAAO,iEAA8B;AAC5C,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIH,OAAM,KAAK,2BAAO,CAAC;AAC/B,UAAQ,IAAI,2EAA6C;AACzD,UAAQ,IAAI,sFAAwD;AACpE,UAAQ,IAAI,6FAAoE;AAChF,UAAQ,IAAI,yGAAkD;AAC9D,UAAQ,IAAI,yGAAkD;AAC9D,UAAQ,IAAI,6FAAgD;AAC5D,UAAQ,IAAI,oEAA2C;AACvD,UAAQ,IAAI,uEAAmD;AAC/D,UAAQ,IAAI,0DAAgD;AAC5D,UAAQ,IAAI,2EAA6C;AACzD,UAAQ,IAAI,gEAAsD;AAClE,UAAQ,IAAI,qGAA6D;AACzE,UAAQ,IAAI,2EAA6C;AACzD,UAAQ,IAAI,uGAAqD;AACjE,UAAQ,IAAI,2EAA6C;AACzD,UAAQ,IAAI,6FAAgD;AAC5D,UAAQ,IAAI,uEAAmD;AAC/D,UAAQ,IAAI,yGAAkD;AAC9D,UAAQ,IAAI,2EAA6C;AACzD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIA,OAAM,KAAK,eAAK,CAAC;AAC7B,UAAQ,IAAI,4BAA4B;AACxC,UAAQ,IAAI,iBAAiB;AAC7B,UAAQ,IAAI,uCAAuC;AACnD,UAAQ,IAAI,wCAAwC;AACpD,UAAQ,IAAI,gBAAgB;AAC5B,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIA,OAAM,KAAK,2BAAO,CAAC;AAC/B,UAAQ,IAAI,mCAA8B;AAC1C,UAAQ,IAAI,iDAA4C;AACxD,UAAQ,IAAI,4DAAmC;AAC/C,UAAQ,IAAI,oFAA6B;AACzC,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIA,OAAM,KAAK,2BAAO,CAAC;AAC/B,UAAQ,IAAI,oEAA2C;AACvD,UAAQ,IAAI,0EAA4C;AACxD,UAAQ,IAAI,4DAAkD;AAC9D,UAAQ,IAAI,sDAA4C;AACxD,UAAQ,IAAI,yDAA+C;AAC3D,UAAQ,IAAI,8DAA0C;AACtD,UAAQ,IAAI,0EAA4C;AACxD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIA,OAAM,KAAK,2BAAO,CAAC;AAC/B,UAAQ,IAAI,sEAA4D;AACxE,UAAQ,IAAI,0EAA4C;AACxD,UAAQ,IAAI,qFAAkD;AAC9D,UAAQ,IAAI,gFAA6C;AACzD,UAAQ,IAAI,0EAA4C;AACxD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIA,OAAM,KAAK,6DAAyC,CAAC;AACjE,UAAQ,IAAI,EAAE;AAChB;AAlIA,IAgCMI,YACA,KAEA;AAnCN;AAAA;AAAA;AAAA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA,IAAMA,aAAYF,OAAK,QAAQC,eAAc,YAAY,GAAG,CAAC;AAC7D,IAAM,MAAMF,IAAG,aAAaC,OAAK,KAAKE,YAAW,iBAAiB,CAAC;AAEnE,IAAM,UAAU,IAAIL,UAAQ;AAG5B,YACG,KAAK,UAAU,EACf,YAAY,sDAAmB,EAC/B,QAAQ,IAAI,OAAO;AAGtB,YAAQ,OAAO,iBAAiB,sCAAQ,EAAE,OAAO,WAAW,0BAAM;AAGlE,YAAQ,WAAW,WAAW;AAC9B,YAAQ,WAAW,eAAe;AAClC,YAAQ,WAAW,gBAAgB;AACnC,YAAQ,WAAW,UAAU;AAC7B,YAAQ,WAAW,iBAAiB;AACpC,YAAQ,WAAW,aAAa;AAChC,YAAQ,WAAW,aAAa;AAChC,YAAQ,WAAW,aAAa;AAChC,YAAQ,WAAW,gBAAgB;AACnC,YAAQ,WAAW,WAAW;AAC9B,YAAQ,WAAW,aAAa;AAChC,YAAQ,WAAW,iBAAiB;AACpC,YAAQ,WAAW,iBAAiB;AACpC,YAAQ,WAAW,eAAe;AAClC,YAAQ,WAAW,WAAW;AAC9B,YAAQ,WAAW,aAAa;AAChC,YAAQ,WAAW,aAAa;AAChC,YAAQ,WAAW,WAAW;AAG9B,YAAQ,OAAO,MAAM;AACnB,eAAS;AAAA,IACX,CAAC;AAkED,YAAQ,GAAG,qBAAqB,CAAC,UAAU;AACzC,aAAO,MAAM,sCAAQ;AACrB,UAAI,QAAQ,IAAI,OAAO;AACrB,gBAAQ,MAAM,KAAK;AAAA,MACrB;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB,CAAC;AAED,YAAQ,GAAG,sBAAsB,CAAC,WAAW;AAC3C,aAAO,MAAM,+CAAiB;AAC9B,UAAI,QAAQ,IAAI,OAAO;AACrB,gBAAQ,MAAM,MAAM;AAAA,MACtB;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB,CAAC;AAGD,YAAQ,MAAM,QAAQ,IAAI;AAAA;AAAA;;;ACxJ1B;AAEA,4DAAqB,MAAM,CAAC,UAAU;AACpC,UAAQ,MAAM,6BAA6B,KAAK;AAChD,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["path","execa","path","fs","execa","path","path","path","fs","os","Command","inquirer","path","Listr","Command","inquirer","path","todo","Command","inquirer","path","Listr","Command","path","Listr","Command","inquirer","path","Listr","execa","Command","inquirer","path","selectSpec","selectMilestone","exists","Command","inquirer","path","fs","createApplicationClass","createModuleBuildGradle","toPascalCase","Command","execa","Command","path","Command","path","inquirer","Command","path","Command","path","inquirer","Listr","controllers","extractMethodComment","Command","path","inquirer","path","os","path","Command","path","execa","inquirer","fs","userConfigManager","GitLabAPI","Command","inquirer","chalk","Command","chalk","execa","Command","chalk","fs","path","fileURLToPath","__dirname"]}
|