@better-fullstack/template-generator 1.0.0-canary.1d67537e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/core/template-reader.d.mts +11 -0
  2. package/dist/core/template-reader.d.mts.map +1 -0
  3. package/dist/core/template-reader.mjs +4 -0
  4. package/dist/fs-writer.d.mts +8 -0
  5. package/dist/fs-writer.d.mts.map +1 -0
  6. package/dist/fs-writer.mjs +51 -0
  7. package/dist/fs-writer.mjs.map +1 -0
  8. package/dist/index.d.mts +442 -0
  9. package/dist/index.d.mts.map +1 -0
  10. package/dist/index.mjs +46568 -0
  11. package/dist/index.mjs.map +1 -0
  12. package/dist/is-binary-path-BN88l03c.mjs +282 -0
  13. package/dist/is-binary-path-BN88l03c.mjs.map +1 -0
  14. package/dist/template-reader-DOXCnctl.mjs +2564 -0
  15. package/dist/template-reader-DOXCnctl.mjs.map +1 -0
  16. package/dist/types-4RpstO2l.d.mts +37 -0
  17. package/dist/types-4RpstO2l.d.mts.map +1 -0
  18. package/package.json +68 -0
  19. package/templates-binary/addons/pwa/apps/web/next/public/favicon/apple-touch-icon.png +0 -0
  20. package/templates-binary/addons/pwa/apps/web/next/public/favicon/favicon-96x96.png +0 -0
  21. package/templates-binary/addons/pwa/apps/web/next/public/favicon/web-app-manifest-192x192.png +0 -0
  22. package/templates-binary/addons/pwa/apps/web/next/public/favicon/web-app-manifest-512x512.png +0 -0
  23. package/templates-binary/addons/pwa/apps/web/vite/public/logo.png +0 -0
  24. package/templates-binary/frontend/native/base/assets/images/android-icon-background.png +0 -0
  25. package/templates-binary/frontend/native/base/assets/images/android-icon-foreground.png +0 -0
  26. package/templates-binary/frontend/native/base/assets/images/android-icon-monochrome.png +0 -0
  27. package/templates-binary/frontend/native/base/assets/images/favicon.png +0 -0
  28. package/templates-binary/frontend/native/base/assets/images/icon.png +0 -0
  29. package/templates-binary/frontend/native/base/assets/images/partial-react-logo.png +0 -0
  30. package/templates-binary/frontend/native/base/assets/images/react-logo.png +0 -0
  31. package/templates-binary/frontend/native/base/assets/images/react-logo@2x.png +0 -0
  32. package/templates-binary/frontend/native/base/assets/images/react-logo@3x.png +0 -0
  33. package/templates-binary/frontend/native/base/assets/images/splash-icon.png +0 -0
  34. package/templates-binary/frontend/nuxt/public/favicon.ico +0 -0
  35. package/templates-binary/frontend/react/next/src/app/favicon.ico +0 -0
  36. package/templates-binary/frontend/react/react-router/public/favicon.ico +0 -0
  37. package/templates-binary/frontend/svelte/static/favicon.png +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["files: string[]","dirs: string[]","root: VirtualDirectory","dirNode: VirtualDirectory","fileNode: VirtualFile","packagesInfo: PackageInfo[]","catalog: Record<string, string>","workspaces: string[]","exports: Record<string, string>","devDeps: Parameters<typeof addPackageDependency>[0][\"devDependencies\"]","REACT_WEB_FRAMEWORKS: Frontend[]","NATIVE_FRAMEWORKS: Frontend[]","REACT_WEB_FRAMEWORKS","NATIVE_FRAMEWORKS","deps: AvailableDependencies[]","deps: AvailableDependencies[]","pluginsToAdd: string[]","importsToAdd: { named: string; module: string }[]","deps: AvailableDependencies[]","devDeps: AvailableDependencies[]","deps: AvailableDependencies[]","deps: AvailableDependencies[]","deps: AvailableDependencies[]","deps: AvailableDependencies[]","devDeps: AvailableDependencies[]","deps: AvailableDependencies[]","deps: AvailableDependencies[]","vars: EnvVariable[]","databaseUrl: string | null","deps: AvailableDependencies[]","SVELTE_FRONTENDS","VUE_FRONTENDS","FILEPOND_PLUGINS: AvailableDependencies[]","UPPY_CORE_PACKAGES: AvailableDependencies[]","baseDeps: AvailableDependencies[]","REACT_WEB_FRAMEWORKS: Frontend[]","NATIVE_FRAMEWORKS: Frontend[]","SOLID_FRAMEWORKS: Frontend[]","QWIK_FRAMEWORKS: Frontend[]","REACT_WEB_FRAMEWORKS","NATIVE_FRAMEWORKS","deps: AvailableDependencies[]","deps: AvailableDependencies[]","parts: string[]","frontendMap: Record<string, string>","instructions: string[]","structure: string[]","frontendTypes: Record<string, string>","frontendFeatures: Record<string, string>","backendFeatures: Record<string, string>","addonFeatures: Record<string, string>","dbDescriptions: Record<string, string>","lines: string[]","features: string[]","REACT_WEB_FRAMEWORKS: Frontend[]","NATIVE_FRAMEWORKS: Frontend[]","REACT_WEB_FRAMEWORKS","NATIVE_FRAMEWORKS","deps: AvailableDependencies[]","REACT_WEB_FRAMEWORKS: Frontend[]","NATIVE_FRAMEWORKS: Frontend[]","deps: AvailableDependencies[]","devDeps: AvailableDependencies[]","deps: AvailableDependencies[]","deps: AvailableDependencies[]","commonDeps: AvailableDependencies[]","commonDevDeps: AvailableDependencies[]","envDevDeps: Record<string, string>","authDeps: Record<string, string>","apiPackageDeps: Record<string, string>","serverDeps: Record<string, string>","webPackageDeps: Record<string, string>","nativeDeps: Record<string, string>","processedContent: string","processedContent: string","templateMap: Record<string, string>","EMBEDDED_TEMPLATES: Map<string, string>"],"sources":["../src/core/virtual-fs.ts","../src/core/template-processor.ts","../src/post-process/catalogs.ts","../src/post-process/package-configs.ts","../src/utils/add-deps.ts","../src/processors/addons-deps.ts","../src/processors/alchemy-plugins.ts","../src/processors/animation-deps.ts","../src/processors/api-deps.ts","../src/processors/auth-deps.ts","../src/processors/auth-plugins.ts","../src/processors/backend-deps.ts","../src/processors/caching-deps.ts","../src/processors/cms-deps.ts","../src/processors/css-ui-deps.ts","../src/processors/db-deps.ts","../src/processors/deploy-deps.ts","../src/processors/effect-deps.ts","../src/processors/email-deps.ts","../src/processors/env-deps.ts","../src/processors/env-vars.ts","../src/processors/examples-deps.ts","../src/processors/file-upload-deps.ts","../src/processors/forms-deps.ts","../src/processors/infra-deps.ts","../src/processors/job-queue-deps.ts","../src/processors/logging-deps.ts","../src/processors/observability-deps.ts","../src/processors/payments-deps.ts","../src/processors/pwa-plugins.ts","../src/processors/readme-generator.ts","../src/processors/realtime-deps.ts","../src/processors/runtime-deps.ts","../src/processors/state-management-deps.ts","../src/processors/testing-deps.ts","../src/processors/turbo-generator.ts","../src/processors/validation-deps.ts","../src/processors/workspace-deps.ts","../src/processors/index.ts","../src/template-handlers/utils.ts","../src/template-handlers/base.ts","../src/template-handlers/rust-base.ts","../src/template-handlers/frontend.ts","../src/template-handlers/backend.ts","../src/template-handlers/database.ts","../src/template-handlers/api.ts","../src/template-handlers/packages.ts","../src/template-handlers/auth.ts","../src/template-handlers/payments.ts","../src/template-handlers/email.ts","../src/template-handlers/addons.ts","../src/template-handlers/examples.ts","../src/template-handlers/extras.ts","../src/template-handlers/deploy.ts","../src/template-handlers/logging.ts","../src/template-handlers/observability.ts","../src/template-handlers/job-queue.ts","../src/template-handlers/cms.ts","../src/generator.ts","../src/templates.generated.ts"],"sourcesContent":["import type { Dirent } from \"node:fs\";\n\nimport { memfs } from \"memfs\";\nimport { dirname, extname, normalize, join } from \"pathe\";\n\nimport type { VirtualDirectory, VirtualFile } from \"../types\";\n\nexport class VirtualFileSystem {\n private _fs: ReturnType<typeof memfs>[\"fs\"];\n private _vol: ReturnType<typeof memfs>[\"vol\"];\n private _sourcePathMap: Map<string, string> = new Map();\n\n constructor() {\n const { fs, vol } = memfs();\n this._fs = fs;\n this._vol = vol;\n }\n\n writeFile(filePath: string, content: string, sourcePath?: string): void {\n const path = this.normalizePath(filePath);\n const dir = dirname(path);\n if (dir && dir !== \"/\" && dir !== \".\") {\n this._fs.mkdirSync(dir, { recursive: true });\n }\n this._fs.writeFileSync(path, content, { encoding: \"utf-8\" });\n if (sourcePath) {\n this._sourcePathMap.set(path, sourcePath);\n }\n }\n\n readFile(filePath: string): string | undefined {\n try {\n return this._fs.readFileSync(this.normalizePath(filePath), \"utf-8\") as string;\n } catch {\n return undefined;\n }\n }\n\n exists(path: string): boolean {\n try {\n this._fs.statSync(this.normalizePath(path));\n return true;\n } catch {\n return false;\n }\n }\n\n fileExists(filePath: string): boolean {\n try {\n return this._fs.statSync(this.normalizePath(filePath)).isFile();\n } catch {\n return false;\n }\n }\n\n directoryExists(dirPath: string): boolean {\n try {\n return this._fs.statSync(this.normalizePath(dirPath)).isDirectory();\n } catch {\n return false;\n }\n }\n\n mkdir(dirPath: string): void {\n this._fs.mkdirSync(this.normalizePath(dirPath), { recursive: true });\n }\n\n deleteFile(filePath: string): boolean {\n try {\n this._fs.unlinkSync(this.normalizePath(filePath));\n return true;\n } catch {\n return false;\n }\n }\n\n listDir(dirPath: string): string[] {\n try {\n return (this._fs.readdirSync(this.normalizePath(dirPath) || \"/\") as string[]).sort();\n } catch {\n return [];\n }\n }\n\n readJson<T = unknown>(filePath: string): T | undefined {\n const content = this.readFile(filePath);\n if (!content) return undefined;\n try {\n return JSON.parse(content) as T;\n } catch {\n return undefined;\n }\n }\n\n writeJson(filePath: string, data: unknown, spaces = 2): void {\n this.writeFile(filePath, JSON.stringify(data, null, spaces));\n }\n\n getAllFiles(): string[] {\n const files: string[] = [];\n this.walkDir(\"/\", files, true);\n return files.sort();\n }\n\n getAllDirectories(): string[] {\n const dirs: string[] = [];\n this.walkDir(\"/\", dirs, false);\n return dirs.filter((d) => d !== \"/\").sort();\n }\n\n getFileCount(): number {\n return this.getAllFiles().length;\n }\n\n getDirectoryCount(): number {\n return this.getAllDirectories().length;\n }\n\n toTree(rootName = \"project\"): VirtualDirectory {\n const root: VirtualDirectory = { type: \"directory\", path: \"\", name: rootName, children: [] };\n this.buildTree(\"/\", root);\n this.sortChildren(root);\n return root;\n }\n\n clear(): void {\n const { fs, vol } = memfs();\n this._fs = fs;\n this._vol = vol;\n this._sourcePathMap.clear();\n }\n\n getVolume() {\n return this._vol;\n }\n getFs() {\n return this._fs;\n }\n\n private walkDir(dir: string, results: string[], filesOnly: boolean): void {\n try {\n for (const entry of this._fs.readdirSync(dir, { withFileTypes: true }) as Dirent[]) {\n const fullPath = join(dir, entry.name);\n const relativePath = fullPath.replace(/^\\//, \"\");\n if (entry.isDirectory()) {\n if (!filesOnly) results.push(relativePath);\n this.walkDir(fullPath, results, filesOnly);\n } else if (entry.isFile() && filesOnly) {\n results.push(relativePath);\n }\n }\n } catch {}\n }\n\n private buildTree(dir: string, parent: VirtualDirectory): void {\n try {\n for (const entry of this._fs.readdirSync(dir, { withFileTypes: true }) as Dirent[]) {\n const fullPath = join(dir, entry.name);\n const relativePath = fullPath.replace(/^\\//, \"\");\n if (entry.isDirectory()) {\n const dirNode: VirtualDirectory = {\n type: \"directory\",\n path: relativePath,\n name: entry.name,\n children: [],\n };\n parent.children.push(dirNode);\n this.buildTree(fullPath, dirNode);\n } else if (entry.isFile()) {\n const content = this._fs.readFileSync(fullPath, \"utf-8\") as string;\n const sourcePath = this._sourcePathMap.get(fullPath);\n const fileNode: VirtualFile = {\n type: \"file\",\n path: relativePath,\n name: entry.name,\n content,\n extension: extname(entry.name).slice(1),\n };\n if (sourcePath) {\n fileNode.sourcePath = sourcePath;\n }\n parent.children.push(fileNode);\n }\n }\n } catch {}\n }\n\n private sortChildren(node: VirtualDirectory): void {\n node.children.sort((a, b) => {\n if (a.type === \"directory\" && b.type === \"file\") return -1;\n if (a.type === \"file\" && b.type === \"directory\") return 1;\n return a.name.localeCompare(b.name);\n });\n for (const child of node.children) {\n if (child.type === \"directory\") this.sortChildren(child);\n }\n }\n\n private normalizePath(p: string): string {\n return \"/\" + normalize(p).replace(/^\\/+/, \"\");\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport Handlebars from \"handlebars\";\nimport isBinaryPath from \"is-binary-path\";\n\nHandlebars.registerHelper(\"eq\", (a, b) => a === b);\nHandlebars.registerHelper(\"ne\", (a, b) => a !== b);\nHandlebars.registerHelper(\"not\", (a) => !a);\nHandlebars.registerHelper(\"and\", (...args) => args.slice(0, -1).every(Boolean));\nHandlebars.registerHelper(\"or\", (...args) => args.slice(0, -1).some(Boolean));\nHandlebars.registerHelper(\"includes\", (arr, val) => Array.isArray(arr) && arr.includes(val));\n\nexport function processTemplateString(content: string, context: ProjectConfig): string {\n return Handlebars.compile(content)(context);\n}\n\nexport function isBinaryFile(filePath: string): boolean {\n return isBinaryPath(filePath);\n}\n\nexport function transformFilename(filename: string): string {\n let result = filename.endsWith(\".hbs\") ? filename.slice(0, -4) : filename;\n\n const basename = result.split(\"/\").pop() || result;\n if (basename === \"_gitignore\") result = result.replace(/_gitignore$/, \".gitignore\");\n else if (basename === \"_npmrc\") result = result.replace(/_npmrc$/, \".npmrc\");\n\n return result;\n}\n\nexport function processFileContent(\n filePath: string,\n content: string,\n context: ProjectConfig,\n): string {\n if (isBinaryFile(filePath)) return \"[Binary file]\";\n\n const originalPath = filePath.endsWith(\".hbs\") ? filePath : filePath + \".hbs\";\n if (filePath !== originalPath || filePath.includes(\".hbs\")) {\n try {\n return processTemplateString(content, context);\n } catch (error) {\n console.warn(`Template processing failed for ${filePath}:`, error);\n return content;\n }\n }\n\n return content;\n}\n\nexport { Handlebars };\n","/**\n * Catalogs post-processor\n * Deduplicates dependencies across packages using pnpm/bun catalogs\n */\n\nimport type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport yaml from \"yaml\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\ntype PackageJson = {\n name?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n workspaces?: string[] | { packages?: string[]; catalog?: Record<string, string> };\n packageManager?: string;\n [key: string]: unknown;\n};\n\ntype CatalogEntry = {\n versions: Set<string>;\n packages: string[];\n};\n\ntype PackageInfo = {\n path: string;\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n};\n\nconst PACKAGE_PATHS = [\n \".\",\n \"apps/server\",\n \"apps/web\",\n \"apps/native\",\n \"apps/fumadocs\",\n \"apps/docs\",\n \"packages/api\",\n \"packages/db\",\n \"packages/auth\",\n \"packages/backend\",\n \"packages/config\",\n \"packages/env\",\n \"packages/infra\",\n];\n\n/**\n * Process dependency catalogs for pnpm/bun\n */\nexport function processCatalogs(vfs: VirtualFileSystem, config: ProjectConfig): void {\n if (config.packageManager === \"npm\") return;\n\n const packagesInfo: PackageInfo[] = [];\n\n for (const pkgPath of PACKAGE_PATHS) {\n const jsonPath = pkgPath === \".\" ? \"package.json\" : `${pkgPath}/package.json`;\n const pkgJson = vfs.readJson<PackageJson>(jsonPath);\n\n if (pkgJson) {\n packagesInfo.push({\n path: pkgPath,\n dependencies: (pkgJson.dependencies || {}) as Record<string, string>,\n devDependencies: (pkgJson.devDependencies || {}) as Record<string, string>,\n });\n }\n }\n\n const catalog = findDuplicateDependencies(packagesInfo, config.projectName);\n\n if (Object.keys(catalog).length === 0) return;\n\n if (config.packageManager === \"bun\") {\n setupBunCatalogs(vfs, catalog);\n } else if (config.packageManager === \"pnpm\") {\n setupPnpmCatalogs(vfs, catalog);\n }\n\n updatePackageJsonsWithCatalogs(vfs, packagesInfo, catalog);\n}\n\nfunction findDuplicateDependencies(\n packagesInfo: PackageInfo[],\n projectName: string,\n): Record<string, string> {\n const depCount = new Map<string, CatalogEntry>();\n const projectScope = `@${projectName}/`;\n\n for (const pkg of packagesInfo) {\n const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };\n\n for (const [depName, version] of Object.entries(allDeps)) {\n if (depName.startsWith(projectScope)) continue;\n if (version.startsWith(\"workspace:\")) continue;\n\n const existing = depCount.get(depName);\n if (existing) {\n existing.versions.add(version);\n existing.packages.push(pkg.path);\n } else {\n depCount.set(depName, {\n versions: new Set([version]),\n packages: [pkg.path],\n });\n }\n }\n }\n\n const catalog: Record<string, string> = {};\n for (const [depName, info] of depCount.entries()) {\n if (info.packages.length > 1 && info.versions.size === 1) {\n const version = Array.from(info.versions)[0];\n if (version) {\n catalog[depName] = version;\n }\n }\n }\n\n return catalog;\n}\n\nfunction setupBunCatalogs(vfs: VirtualFileSystem, catalog: Record<string, string>): void {\n const pkgJson = vfs.readJson<PackageJson>(\"package.json\");\n if (!pkgJson) return;\n\n if (!pkgJson.workspaces) {\n pkgJson.workspaces = {};\n }\n\n if (Array.isArray(pkgJson.workspaces)) {\n pkgJson.workspaces = {\n packages: pkgJson.workspaces,\n catalog,\n };\n } else if (typeof pkgJson.workspaces === \"object\") {\n if (!pkgJson.workspaces.catalog) {\n pkgJson.workspaces.catalog = {};\n }\n pkgJson.workspaces.catalog = {\n ...pkgJson.workspaces.catalog,\n ...catalog,\n };\n }\n\n vfs.writeJson(\"package.json\", pkgJson);\n}\n\nfunction setupPnpmCatalogs(vfs: VirtualFileSystem, catalog: Record<string, string>): void {\n let content = vfs.readFile(\"pnpm-workspace.yaml\");\n\n // Create pnpm-workspace.yaml if it doesn't exist\n if (!content) {\n content = `packages:\n - \"apps/*\"\n - \"packages/*\"\n`;\n vfs.writeFile(\"pnpm-workspace.yaml\", content);\n }\n\n const workspaceYaml = yaml.parse(content);\n\n if (!workspaceYaml.catalog) {\n workspaceYaml.catalog = {};\n }\n\n workspaceYaml.catalog = {\n ...workspaceYaml.catalog,\n ...catalog,\n };\n\n vfs.writeFile(\"pnpm-workspace.yaml\", yaml.stringify(workspaceYaml));\n}\n\nfunction updatePackageJsonsWithCatalogs(\n vfs: VirtualFileSystem,\n packagesInfo: PackageInfo[],\n catalog: Record<string, string>,\n): void {\n for (const pkg of packagesInfo) {\n const jsonPath = pkg.path === \".\" ? \"package.json\" : `${pkg.path}/package.json`;\n const pkgJson = vfs.readJson<PackageJson>(jsonPath);\n if (!pkgJson) continue;\n\n let updated = false;\n\n if (pkgJson.dependencies) {\n for (const depName of Object.keys(pkgJson.dependencies)) {\n if (catalog[depName]) {\n (pkgJson.dependencies as Record<string, string>)[depName] = \"catalog:\";\n updated = true;\n }\n }\n }\n\n if (pkgJson.devDependencies) {\n for (const depName of Object.keys(pkgJson.devDependencies)) {\n if (catalog[depName]) {\n (pkgJson.devDependencies as Record<string, string>)[depName] = \"catalog:\";\n updated = true;\n }\n }\n }\n\n if (updated) {\n vfs.writeJson(jsonPath, pkgJson);\n }\n }\n}\n","/**\n * Package.json configuration post-processor\n * Updates package names, scripts, and workspaces after template generation\n */\n\nimport type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\ntype PackageJson = {\n name?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n workspaces?: string[] | { packages?: string[]; catalog?: Record<string, string> };\n packageManager?: string;\n [key: string]: unknown;\n};\n\ntype PackageManagerConfig = {\n dev: string;\n build: string;\n checkTypes: string;\n filter: (workspace: string, script: string) => string;\n};\n\n/**\n * Update all package.json files with proper names, scripts, and workspaces\n */\nexport function processPackageConfigs(vfs: VirtualFileSystem, config: ProjectConfig): void {\n updateRootPackageJson(vfs, config);\n updateConfigPackageJson(vfs, config);\n updateEnvPackageJson(vfs, config);\n updateInfraPackageJson(vfs, config);\n\n if (config.backend === \"convex\") {\n updateConvexPackageJson(vfs, config);\n } else if (config.backend !== \"none\") {\n updateDbPackageJson(vfs, config);\n updateAuthPackageJson(vfs, config);\n updateApiPackageJson(vfs, config);\n }\n}\n\nfunction updateRootPackageJson(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const pkgJson = vfs.readJson<PackageJson>(\"package.json\");\n if (!pkgJson) return;\n\n pkgJson.name = config.projectName;\n pkgJson.scripts = pkgJson.scripts || {};\n\n // Ensure workspaces is an array\n let workspaces: string[] = [];\n if (Array.isArray(pkgJson.workspaces)) {\n workspaces = pkgJson.workspaces;\n } else if (\n pkgJson.workspaces &&\n typeof pkgJson.workspaces === \"object\" &&\n pkgJson.workspaces.packages\n ) {\n workspaces = pkgJson.workspaces.packages;\n }\n pkgJson.workspaces = workspaces;\n\n const scripts = pkgJson.scripts;\n const { projectName, packageManager, backend, database, orm, dbSetup, serverDeploy, addons } =\n config;\n\n const backendPackageName = backend === \"convex\" ? `@${projectName}/backend` : \"server\";\n const dbPackageName = `@${projectName}/db`;\n const hasTurborepo = addons.includes(\"turborepo\");\n\n const needsDbScripts =\n backend !== \"convex\" && database !== \"none\" && orm !== \"none\" && orm !== \"mongoose\";\n const isD1Alchemy = dbSetup === \"d1\" && serverDeploy === \"cloudflare\";\n\n const pmConfig = getPackageManagerConfig(packageManager, hasTurborepo);\n\n scripts.dev = pmConfig.dev;\n scripts.build = pmConfig.build;\n scripts[\"check-types\"] = pmConfig.checkTypes;\n scripts[\"dev:native\"] = pmConfig.filter(\"native\", \"dev\");\n scripts[\"dev:web\"] = pmConfig.filter(\"web\", \"dev\");\n\n if (backend !== \"self\" && backend !== \"none\") {\n scripts[\"dev:server\"] = pmConfig.filter(backendPackageName, \"dev\");\n }\n\n if (backend === \"convex\") {\n scripts[\"dev:setup\"] = pmConfig.filter(backendPackageName, \"dev:setup\");\n }\n\n if (needsDbScripts) {\n scripts[\"db:push\"] = pmConfig.filter(dbPackageName, \"db:push\");\n\n if (!isD1Alchemy) {\n scripts[\"db:studio\"] = pmConfig.filter(dbPackageName, \"db:studio\");\n }\n\n if (orm === \"prisma\") {\n scripts[\"db:generate\"] = pmConfig.filter(dbPackageName, \"db:generate\");\n scripts[\"db:migrate\"] = pmConfig.filter(dbPackageName, \"db:migrate\");\n } else if (orm === \"drizzle\") {\n scripts[\"db:generate\"] = pmConfig.filter(dbPackageName, \"db:generate\");\n if (!isD1Alchemy) {\n scripts[\"db:migrate\"] = pmConfig.filter(dbPackageName, \"db:migrate\");\n }\n }\n }\n\n if (database === \"sqlite\" && dbSetup !== \"d1\") {\n scripts[\"db:local\"] = pmConfig.filter(dbPackageName, \"db:local\");\n }\n\n if (dbSetup === \"docker\") {\n scripts[\"db:start\"] = pmConfig.filter(dbPackageName, \"db:start\");\n scripts[\"db:watch\"] = pmConfig.filter(dbPackageName, \"db:watch\");\n scripts[\"db:stop\"] = pmConfig.filter(dbPackageName, \"db:stop\");\n scripts[\"db:down\"] = pmConfig.filter(dbPackageName, \"db:down\");\n }\n\n // Note: packageManager version is set by CLI at runtime since it requires running the actual CLI\n // For preview purposes, we just show the configured package manager\n pkgJson.packageManager = `${packageManager}@latest`;\n\n if (backend === \"convex\") {\n if (!workspaces.includes(\"packages/*\")) {\n workspaces.push(\"packages/*\");\n }\n const needsAppsDir = config.frontend.length > 0 || addons.includes(\"starlight\");\n if (needsAppsDir && !workspaces.includes(\"apps/*\")) {\n workspaces.push(\"apps/*\");\n }\n } else {\n if (!workspaces.includes(\"apps/*\")) {\n workspaces.push(\"apps/*\");\n }\n if (!workspaces.includes(\"packages/*\")) {\n workspaces.push(\"packages/*\");\n }\n }\n\n vfs.writeJson(\"package.json\", pkgJson);\n}\n\nfunction getPackageManagerConfig(\n packageManager: ProjectConfig[\"packageManager\"],\n hasTurborepo: boolean,\n): PackageManagerConfig {\n if (hasTurborepo) {\n return {\n dev: \"turbo dev\",\n build: \"turbo build\",\n checkTypes: \"turbo check-types\",\n filter: (workspace, script) => `turbo -F ${workspace} ${script}`,\n };\n }\n\n switch (packageManager) {\n case \"pnpm\":\n return {\n dev: \"pnpm -r dev\",\n build: \"pnpm -r build\",\n checkTypes: \"pnpm -r check-types\",\n filter: (workspace, script) => `pnpm --filter ${workspace} ${script}`,\n };\n case \"npm\":\n return {\n dev: \"npm run dev --workspaces\",\n build: \"npm run build --workspaces\",\n checkTypes: \"npm run check-types --workspaces\",\n filter: (workspace, script) => `npm run ${script} --workspace ${workspace}`,\n };\n case \"bun\":\n return {\n dev: \"bun run --filter '*' dev\",\n build: \"bun run --filter '*' build\",\n checkTypes: \"bun run --filter '*' check-types\",\n filter: (workspace, script) => `bun run --filter ${workspace} ${script}`,\n };\n }\n}\n\nfunction updateDbPackageJson(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const pkgJson = vfs.readJson<PackageJson>(\"packages/db/package.json\");\n if (!pkgJson) return;\n\n pkgJson.name = `@${config.projectName}/db`;\n pkgJson.scripts = pkgJson.scripts || {};\n\n const scripts = pkgJson.scripts;\n const { database, orm, dbSetup, serverDeploy } = config;\n const isD1Alchemy = dbSetup === \"d1\" && serverDeploy === \"cloudflare\";\n\n if (database !== \"none\") {\n if (database === \"sqlite\" && dbSetup !== \"d1\") {\n scripts[\"db:local\"] = \"turso dev --db-file local.db\";\n }\n\n if (orm === \"prisma\") {\n scripts[\"db:push\"] = \"prisma db push\";\n scripts[\"db:generate\"] = \"prisma generate\";\n scripts[\"db:migrate\"] = \"prisma migrate dev\";\n if (!isD1Alchemy) {\n scripts[\"db:studio\"] = \"prisma studio\";\n }\n } else if (orm === \"drizzle\") {\n scripts[\"db:push\"] = \"drizzle-kit push\";\n scripts[\"db:generate\"] = \"drizzle-kit generate\";\n if (!isD1Alchemy) {\n scripts[\"db:studio\"] = \"drizzle-kit studio\";\n scripts[\"db:migrate\"] = \"drizzle-kit migrate\";\n }\n }\n }\n\n if (dbSetup === \"docker\") {\n scripts[\"db:start\"] = \"docker compose up -d\";\n scripts[\"db:watch\"] = \"docker compose up\";\n scripts[\"db:stop\"] = \"docker compose stop\";\n scripts[\"db:down\"] = \"docker compose down\";\n }\n\n vfs.writeJson(\"packages/db/package.json\", pkgJson);\n}\n\nfunction updateAuthPackageJson(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const pkgJson = vfs.readJson<PackageJson>(\"packages/auth/package.json\");\n if (!pkgJson) return;\n\n pkgJson.name = `@${config.projectName}/auth`;\n vfs.writeJson(\"packages/auth/package.json\", pkgJson);\n}\n\nfunction updateApiPackageJson(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const pkgJson = vfs.readJson<PackageJson>(\"packages/api/package.json\");\n if (!pkgJson) return;\n\n pkgJson.name = `@${config.projectName}/api`;\n vfs.writeJson(\"packages/api/package.json\", pkgJson);\n}\n\nfunction updateConfigPackageJson(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const pkgJson = vfs.readJson<PackageJson>(\"packages/config/package.json\");\n if (!pkgJson) return;\n\n pkgJson.name = `@${config.projectName}/config`;\n vfs.writeJson(\"packages/config/package.json\", pkgJson);\n}\n\nfunction updateEnvPackageJson(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const pkgJson = vfs.readJson<PackageJson>(\"packages/env/package.json\");\n if (!pkgJson) return;\n\n pkgJson.name = `@${config.projectName}/env`;\n\n // Set exports based on which env files exist\n const hasWebFrontend = config.frontend.some((f) =>\n [\n \"tanstack-router\",\n \"react-router\",\n \"tanstack-start\",\n \"next\",\n \"nuxt\",\n \"svelte\",\n \"solid\",\n ].includes(f),\n );\n const hasNative = config.frontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n const needsServerEnv = config.backend !== \"none\" && config.backend !== \"convex\";\n\n const exports: Record<string, string> = {};\n\n if (needsServerEnv) {\n exports[\"./server\"] = \"./src/server.ts\";\n }\n if (hasWebFrontend) {\n exports[\"./web\"] = \"./src/web.ts\";\n }\n if (hasNative) {\n exports[\"./native\"] = \"./src/native.ts\";\n }\n\n pkgJson.exports = exports;\n\n vfs.writeJson(\"packages/env/package.json\", pkgJson);\n}\n\nfunction updateInfraPackageJson(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const pkgJson = vfs.readJson<PackageJson>(\"packages/infra/package.json\");\n if (!pkgJson) return;\n\n pkgJson.name = `@${config.projectName}/infra`;\n vfs.writeJson(\"packages/infra/package.json\", pkgJson);\n}\n\nfunction updateConvexPackageJson(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const pkgJson = vfs.readJson<PackageJson>(\"packages/backend/package.json\");\n if (!pkgJson) return;\n\n pkgJson.name = `@${config.projectName}/backend`;\n pkgJson.scripts = pkgJson.scripts || {};\n vfs.writeJson(\"packages/backend/package.json\", pkgJson);\n}\n","/**\n * Add dependencies to a package.json in the virtual filesystem\n */\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\ntype PackageJson = {\n name?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n [key: string]: unknown;\n};\n\nexport const dependencyVersionMap = {\n typescript: \"^5\",\n\n \"better-auth\": \"^1.4.9\",\n \"@better-auth/expo\": \"^1.4.9\",\n\n \"@clerk/nextjs\": \"^6.31.5\",\n \"@clerk/clerk-react\": \"^5.45.0\",\n \"@clerk/tanstack-react-start\": \"^0.26.3\",\n \"@clerk/clerk-expo\": \"^2.14.25\",\n\n // Auth.js (NextAuth v5)\n \"next-auth\": \"^5.0.0-beta.28\",\n \"@auth/core\": \"^0.39.1\",\n \"@auth/drizzle-adapter\": \"^1.8.1\",\n \"@auth/prisma-adapter\": \"^2.9.1\",\n\n \"drizzle-orm\": \"^0.45.1\",\n \"drizzle-kit\": \"^0.31.8\",\n \"@planetscale/database\": \"^1.19.0\",\n\n \"@libsql/client\": \"0.15.15\",\n libsql: \"0.5.22\",\n\n \"@neondatabase/serverless\": \"^1.0.2\",\n pg: \"^8.16.3\",\n \"@types/pg\": \"^8.15.6\",\n \"@types/ws\": \"^8.18.1\",\n ws: \"^8.18.3\",\n\n mysql2: \"^3.14.0\",\n\n \"@prisma/client\": \"^7.1.0\",\n prisma: \"^7.1.0\",\n \"@prisma/adapter-d1\": \"^7.1.0\",\n \"@prisma/adapter-neon\": \"^7.1.0\",\n \"@prisma/adapter-mariadb\": \"^7.1.0\",\n \"@prisma/adapter-libsql\": \"^7.1.0\",\n \"@prisma/adapter-better-sqlite3\": \"^7.1.0\",\n \"@prisma/adapter-pg\": \"^7.1.0\",\n \"@prisma/adapter-planetscale\": \"^7.1.0\",\n\n mongoose: \"^8.14.0\",\n\n // TypeORM\n typeorm: \"^0.3.23\",\n \"better-sqlite3\": \"^11.9.1\",\n \"@types/better-sqlite3\": \"^7.6.13\",\n\n // Kysely\n kysely: \"^0.28.3\",\n\n // MikroORM\n \"@mikro-orm/core\": \"^6.5.3\",\n \"@mikro-orm/sqlite\": \"^6.5.3\",\n \"@mikro-orm/postgresql\": \"^6.5.3\",\n \"@mikro-orm/mysql\": \"^6.5.3\",\n \"@mikro-orm/better-sqlite\": \"^6.5.3\",\n\n // Sequelize\n sequelize: \"^6.37.5\",\n \"sequelize-typescript\": \"^2.1.6\",\n sqlite3: \"^5.1.7\",\n\n \"vite-plugin-pwa\": \"^1.0.1\",\n \"@vite-pwa/assets-generator\": \"^1.0.0\",\n\n \"@tauri-apps/cli\": \"^2.4.0\",\n\n \"@biomejs/biome\": \"^2.2.0\",\n\n oxlint: \"^1.34.0\",\n oxfmt: \"^0.19.0\",\n\n husky: \"^9.1.7\",\n lefthook: \"^2.0.13\",\n \"lint-staged\": \"^16.1.2\",\n\n tsx: \"^4.19.2\",\n \"@types/node\": \"^22.13.14\",\n\n \"@types/bun\": \"^1.3.4\",\n\n \"@elysiajs/node\": \"^1.3.1\",\n\n \"@elysiajs/cors\": \"^1.4.1\",\n \"@elysiajs/trpc\": \"^1.1.0\",\n elysia: \"^1.4.21\",\n\n \"@hono/node-server\": \"^1.14.4\",\n \"@hono/trpc-server\": \"^0.4.0\",\n hono: \"^4.8.2\",\n\n cors: \"^2.8.5\",\n express: \"^5.1.0\",\n \"@types/express\": \"^5.0.1\",\n \"@types/cors\": \"^2.8.17\",\n\n fastify: \"^5.3.3\",\n \"@fastify/cors\": \"^11.0.1\",\n\n \"@nestjs/core\": \"^11.0.20\",\n \"@nestjs/common\": \"^11.0.20\",\n \"@nestjs/platform-express\": \"^11.0.20\",\n \"reflect-metadata\": \"^0.2.2\",\n rxjs: \"^7.8.1\",\n\n // Encore.ts\n \"encore.dev\": \"^1.50.0\",\n\n // AdonisJS\n \"@adonisjs/core\": \"^6.19.0\",\n \"@adonisjs/cors\": \"^2.2.1\",\n \"@adonisjs/tsconfig\": \"^1.4.0\",\n\n // Nitro\n nitropack: \"^2.11.12\",\n h3: \"^1.15.3\",\n\n // feTS\n fets: \"^0.8.5\",\n\n turbo: \"^2.6.3\",\n\n ai: \"^6.0.3\",\n \"@ai-sdk/google\": \"^3.0.1\",\n \"@ai-sdk/vue\": \"^3.0.3\",\n \"@ai-sdk/svelte\": \"^4.0.3\",\n \"@ai-sdk/react\": \"^3.0.3\",\n \"@ai-sdk/devtools\": \"^0.0.2\",\n streamdown: \"^1.6.10\",\n shiki: \"^3.20.0\",\n\n // Mastra AI Framework\n mastra: \"^0.24.9\",\n \"@mastra/core\": \"^0.24.9\",\n\n // VoltAgent AI Framework\n \"@voltagent/core\": \"^2.0.10\",\n \"@voltagent/server-hono\": \"^2.0.3\",\n \"@voltagent/libsql\": \"^2.0.3\",\n \"@voltagent/logger\": \"^2.0.2\",\n\n // LangGraph.js AI Framework\n \"@langchain/langgraph\": \"^1.0.15\",\n \"@langchain/core\": \"^1.1.12\",\n \"@langchain/google-genai\": \"^2.1.8\",\n\n // OpenAI Agents SDK\n \"@openai/agents\": \"^0.0.17\",\n\n // Google ADK (Agent Development Kit)\n \"@google/adk\": \"^0.2.0\",\n\n // ModelFusion AI Library\n modelfusion: \"^0.137.0\",\n\n \"@orpc/server\": \"^1.12.2\",\n \"@orpc/client\": \"^1.12.2\",\n \"@orpc/openapi\": \"^1.12.2\",\n \"@orpc/zod\": \"^1.12.2\",\n \"@orpc/tanstack-query\": \"^1.12.2\",\n\n // ts-rest\n \"@ts-rest/core\": \"^3.55.0\",\n \"@ts-rest/react-query\": \"^3.55.0\",\n \"@ts-rest/serverless\": \"^3.55.0\",\n \"@ts-rest/next\": \"^3.55.0\",\n\n // Garph (GraphQL)\n garph: \"^0.6.8\",\n \"graphql-yoga\": \"^5.10.11\",\n graphql: \"^16.11.0\",\n \"@garph/gqty\": \"^1.3.5\",\n gqty: \"^3.5.0\",\n\n \"@trpc/tanstack-react-query\": \"^11.7.2\",\n \"@trpc/server\": \"^11.7.2\",\n \"@trpc/client\": \"^11.7.2\",\n\n next: \"^16.1.1\",\n\n convex: \"^1.31.2\",\n \"@convex-dev/react-query\": \"^0.1.0\",\n \"@convex-dev/agent\": \"^0.3.2\",\n \"convex-svelte\": \"^0.0.12\",\n \"convex-nuxt\": \"0.1.5\",\n \"convex-vue\": \"^0.1.5\",\n \"@convex-dev/better-auth\": \"^0.10.9\",\n\n \"@tanstack/svelte-query\": \"^5.85.3\",\n \"@tanstack/svelte-query-devtools\": \"^5.85.3\",\n\n \"@tanstack/vue-query-devtools\": \"^5.90.2\",\n \"@tanstack/vue-query\": \"^5.90.2\",\n\n \"@tanstack/react-query-devtools\": \"^5.91.1\",\n \"@tanstack/react-query\": \"^5.90.12\",\n \"@tanstack/react-router-ssr-query\": \"^1.142.7\",\n\n \"@tanstack/solid-query\": \"^5.87.4\",\n \"@tanstack/solid-query-devtools\": \"^5.87.4\",\n \"@tanstack/solid-router-devtools\": \"^1.131.44\",\n\n wrangler: \"^4.54.0\",\n \"@cloudflare/vite-plugin\": \"^1.17.1\",\n \"@opennextjs/cloudflare\": \"^1.14.6\",\n \"nitro-cloudflare-dev\": \"^0.2.2\",\n \"@sveltejs/adapter-cloudflare\": \"^7.2.4\",\n \"@cloudflare/workers-types\": \"^4.20251213.0\",\n\n alchemy: \"^0.82.1\",\n\n dotenv: \"^17.2.2\",\n tsdown: \"^0.16.5\",\n zod: \"^4.1.13\",\n \"@t3-oss/env-core\": \"^0.13.1\",\n \"@t3-oss/env-nextjs\": \"^0.13.1\",\n \"@t3-oss/env-nuxt\": \"^0.13.1\",\n srvx: \"0.8.15\",\n\n \"@polar-sh/better-auth\": \"^1.1.3\",\n \"@polar-sh/sdk\": \"^0.34.16\",\n\n // Email\n resend: \"^4.5.1\",\n \"@react-email/components\": \"^0.0.36\",\n \"react-email\": \"^3.0.6\",\n nodemailer: \"^6.10.1\",\n \"@types/nodemailer\": \"^6.4.17\",\n postmark: \"^4.0.5\",\n \"@sendgrid/mail\": \"^8.1.4\",\n \"@aws-sdk/client-ses\": \"^3.970.0\",\n \"mailgun.js\": \"^10.2.3\",\n \"form-data\": \"^4.0.1\",\n \"@plunk/node\": \"^3.0.2\",\n\n // Effect ecosystem\n effect: \"^3.16.1\",\n \"@effect/schema\": \"^0.75.8\",\n \"@effect/platform\": \"^0.78.1\",\n \"@effect/platform-node\": \"^0.74.1\",\n \"@effect/platform-bun\": \"^0.58.1\",\n \"@effect/platform-browser\": \"^0.57.1\",\n \"@effect/sql\": \"^0.35.1\",\n \"@effect/sql-sqlite-node\": \"^0.29.1\",\n \"@effect/sql-sqlite-bun\": \"^0.29.1\",\n \"@effect/sql-pg\": \"^0.29.1\",\n \"@effect/sql-mysql2\": \"^0.29.1\",\n \"@effect/sql-libsql\": \"^0.29.1\",\n \"@effect/sql-drizzle\": \"^0.26.1\",\n \"@effect/cli\": \"^0.56.1\",\n \"@effect/vitest\": \"^0.17.1\",\n \"@effect/opentelemetry\": \"^0.43.1\",\n \"@effect/rpc\": \"^0.51.1\",\n \"@effect/rpc-http\": \"^0.51.1\",\n \"@effect/cluster\": \"^0.26.1\",\n \"@effect/workflow\": \"^0.26.1\",\n \"@effect/ai\": \"^0.5.1\",\n \"@effect/ai-openai\": \"^0.5.1\",\n \"@effect/ai-anthropic\": \"^0.5.1\",\n\n // CSS preprocessors\n sass: \"^1.86.0\",\n less: \"^4.3.0\",\n\n // UI libraries\n \"@radix-ui/react-dialog\": \"^1.1.14\",\n \"@radix-ui/react-dropdown-menu\": \"^2.1.15\",\n \"@radix-ui/react-slot\": \"^1.2.3\",\n \"@radix-ui/react-label\": \"^2.1.4\",\n \"@radix-ui/react-checkbox\": \"^1.3.2\",\n \"@radix-ui/react-select\": \"^2.2.5\",\n \"@radix-ui/react-toast\": \"^1.2.14\",\n \"@radix-ui/react-popover\": \"^1.1.14\",\n \"@radix-ui/react-switch\": \"^1.1.7\",\n \"@radix-ui/react-tabs\": \"^1.1.7\",\n\n \"@headlessui/react\": \"^2.3.1\",\n \"@headlessui/vue\": \"^1.8.1\",\n\n \"@park-ui/panda-preset\": \"^0.47.0\",\n \"@park-ui/ark\": \"^0.47.0\",\n\n \"@chakra-ui/react\": \"^3.21.3\",\n \"@emotion/react\": \"^11.14.0\",\n\n \"@heroui/react\": \"^2.8.3\",\n \"framer-motion\": \"^12.17.0\",\n\n // Mantine\n \"@mantine/core\": \"^8.3.12\",\n \"@mantine/hooks\": \"^8.3.12\",\n\n // Base UI\n \"@base-ui-components/react\": \"^1.0.0-rc.0\",\n\n // Ark UI (headless components for React/Vue/Solid/Svelte)\n \"@ark-ui/react\": \"^5.30.0\",\n \"@ark-ui/vue\": \"^5.26.2\",\n \"@ark-ui/solid\": \"^5.30.0\",\n \"@ark-ui/svelte\": \"^5.15.0\",\n\n // React Aria (Adobe's accessible components for React)\n \"react-aria-components\": \"^1.14.0\",\n\n daisyui: \"^4.12.28\",\n\n // Qwik\n \"@builder.io/qwik\": \"^1.14.1\",\n \"@builder.io/qwik-city\": \"^1.14.1\",\n \"@builder.io/qwik-react\": \"^0.7.0\",\n\n // Angular\n \"@angular/core\": \"^19.2.0\",\n \"@angular/common\": \"^19.2.0\",\n \"@angular/compiler\": \"^19.2.0\",\n \"@angular/platform-browser\": \"^19.2.0\",\n \"@angular/platform-browser-dynamic\": \"^19.2.0\",\n \"@angular/router\": \"^19.2.0\",\n \"@angular/forms\": \"^19.2.0\",\n \"@angular/animations\": \"^19.2.0\",\n \"@angular-devkit/build-angular\": \"^19.2.0\",\n \"@angular/cli\": \"^19.2.0\",\n \"@angular/compiler-cli\": \"^19.2.0\",\n\n // State management\n zustand: \"^5.0.5\",\n jotai: \"^2.12.5\",\n nanostores: \"^0.11.3\",\n \"@nanostores/react\": \"^0.8.4\",\n \"@reduxjs/toolkit\": \"^2.8.2\",\n \"react-redux\": \"^9.2.0\",\n mobx: \"^6.13.5\",\n \"mobx-react-lite\": \"^4.1.0\",\n xstate: \"^5.19.4\",\n \"@xstate/react\": \"^5.0.4\",\n valtio: \"^2.1.2\",\n \"@tanstack/store\": \"^0.8.0\",\n \"@tanstack/react-store\": \"^0.8.0\",\n \"@legendapp/state\": \"^3.0.0\",\n \"@legendapp/state-react\": \"^4.0.0\",\n\n // Validation libraries\n valibot: \"^1.1.0\",\n arktype: \"^2.1.29\",\n \"@sinclair/typebox\": \"^0.34.31\",\n typia: \"^9.7.1\",\n runtypes: \"^7.0.4\",\n\n // Form libraries\n formik: \"^2.4.6\",\n yup: \"^1.6.1\",\n \"final-form\": \"^4.20.10\",\n \"react-final-form\": \"^6.5.9\",\n \"@conform-to/react\": \"^1.8.2\",\n \"@conform-to/zod\": \"^1.8.2\",\n \"@modular-forms/solid\": \"^0.25.1\",\n \"@modular-forms/qwik\": \"^0.29.1\",\n\n // Real-time/WebSocket\n \"socket.io\": \"^4.8.1\",\n \"socket.io-client\": \"^4.8.1\",\n partykit: \"^0.0.111\",\n partysocket: \"^1.0.2\",\n ably: \"^2.6.3\",\n pusher: \"^5.2.0\",\n \"pusher-js\": \"^8.4.0-rc2\",\n \"@liveblocks/client\": \"^3.11.0\",\n \"@liveblocks/react\": \"^3.13.2\",\n \"@liveblocks/node\": \"^3.11.0\",\n yjs: \"^13.6.27\",\n \"y-websocket\": \"^2.1.0\",\n \"y-protocols\": \"^1.0.6\",\n \"@y-sweet/sdk\": \"^0.6.3\",\n \"@y-sweet/react\": \"^0.6.3\",\n\n // Job Queues / Background Workers\n bullmq: \"^5.34.8\",\n ioredis: \"^5.4.2\",\n \"@trigger.dev/sdk\": \"^4.1.1\",\n inngest: \"^3.33.0\",\n \"@temporalio/client\": \"^1.11.7\",\n \"@temporalio/worker\": \"^1.11.7\",\n \"@temporalio/workflow\": \"^1.11.7\",\n \"@temporalio/activity\": \"^1.11.7\",\n\n // Testing - Jest\n jest: \"^29.7.0\",\n \"@types/jest\": \"^29.5.14\",\n \"ts-jest\": \"^29.2.5\",\n \"@jest/globals\": \"^29.7.0\",\n \"jest-environment-jsdom\": \"^29.7.0\",\n\n // Testing - Cypress\n cypress: \"^14.3.3\",\n\n // Testing - Vitest\n vitest: \"^3.1.1\",\n \"@vitest/ui\": \"^3.1.1\",\n \"@vitest/coverage-v8\": \"^3.1.1\",\n jsdom: \"^26.0.0\",\n \"happy-dom\": \"^18.0.1\",\n\n // Testing - Playwright\n \"@playwright/test\": \"^1.52.0\",\n playwright: \"^1.52.0\",\n\n // Testing Library\n \"@testing-library/dom\": \"^10.4.0\",\n \"@testing-library/react\": \"^16.2.0\",\n \"@testing-library/vue\": \"^8.1.0\",\n \"@testing-library/svelte\": \"^5.2.7\",\n \"@testing-library/jest-dom\": \"^6.6.3\",\n \"@testing-library/user-event\": \"^14.6.1\",\n\n // MSW (Mock Service Worker)\n msw: \"^2.7.0\",\n\n // Storybook\n storybook: \"^9.0.15\",\n \"@storybook/react-vite\": \"^9.0.15\",\n \"@storybook/vue3-vite\": \"^9.0.15\",\n \"@storybook/svelte-vite\": \"^9.0.15\",\n \"@storybook/nextjs\": \"^9.0.15\",\n \"@storybook/addon-essentials\": \"^9.0.15\",\n \"@storybook/addon-interactions\": \"^9.0.15\",\n \"@storybook/test\": \"^9.0.15\",\n\n // Animation\n motion: \"^12.17.0\",\n gsap: \"^3.12.7\",\n \"@react-spring/web\": \"^9.7.5\",\n \"@react-spring/native\": \"^9.7.5\",\n \"@formkit/auto-animate\": \"^0.8.2\",\n \"lottie-react\": \"^2.4.1\",\n \"lottie-react-native\": \"^7.1.0\",\n\n // Payments - Stripe\n stripe: \"^17.5.0\",\n \"@stripe/stripe-js\": \"^5.5.0\",\n \"@stripe/react-stripe-js\": \"^3.1.1\",\n\n // Payments - Lemon Squeezy\n \"@lemonsqueezy/lemonsqueezy.js\": \"^4.0.0\",\n\n // Payments - Paddle\n \"@paddle/paddle-node-sdk\": \"^1.8.0\",\n \"@paddle/paddle-js\": \"^1.3.0\",\n\n // Payments - Dodo Payments\n dodopayments: \"^0.23.0\",\n \"dodopayments-checkout\": \"^0.2.1\",\n\n // File Upload - UploadThing\n uploadthing: \"^7.8.0\",\n \"@uploadthing/react\": \"^7.3.0\",\n \"@uploadthing/svelte\": \"^7.3.0\",\n \"@uploadthing/vue\": \"^7.3.0\",\n \"@uploadthing/solid\": \"^7.3.0\",\n \"@uploadthing/nuxt\": \"^7.3.0\",\n \"@uploadthing/expo\": \"^7.3.0\",\n\n // File Upload - FilePond\n filepond: \"^4.32.10\",\n \"react-filepond\": \"^7.1.2\",\n \"svelte-filepond\": \"^1.0.2\",\n \"vue-filepond\": \"^7.0.4\",\n \"filepond-plugin-image-preview\": \"^4.6.12\",\n \"filepond-plugin-file-validate-type\": \"^1.2.9\",\n \"filepond-plugin-file-validate-size\": \"^2.2.8\",\n\n // File Upload - Uppy\n \"@uppy/core\": \"^4.4.0\",\n \"@uppy/dashboard\": \"^4.3.2\",\n \"@uppy/drag-drop\": \"^4.1.1\",\n \"@uppy/progress-bar\": \"^4.2.0\",\n \"@uppy/xhr-upload\": \"^4.3.0\",\n \"@uppy/tus\": \"^4.2.0\",\n \"@uppy/react\": \"^4.1.0\",\n \"@uppy/svelte\": \"^4.1.0\",\n \"@uppy/vue\": \"^4.1.0\",\n \"@uppy/angular\": \"^0.8.0\",\n\n // RedwoodJS\n \"@redwoodjs/core\": \"^8.8.0\",\n \"@redwoodjs/web\": \"^8.6.1\",\n \"@redwoodjs/api\": \"^8.6.1\",\n \"@redwoodjs/router\": \"^8.6.1\",\n \"@redwoodjs/forms\": \"^8.6.1\",\n \"@redwoodjs/graphql-server\": \"^8.6.1\",\n \"@redwoodjs/vite\": \"^8.6.1\",\n \"@redwoodjs/project-config\": \"^8.6.1\",\n\n // Fresh (Deno-native framework - uses JSR/deno.json, not npm)\n // These are reference versions for Fresh ecosystem\n preact: \"^10.25.4\",\n \"preact-render-to-string\": \"^6.5.12\",\n\n // Logging\n pino: \"^9.6.0\",\n \"pino-pretty\": \"^13.0.0\",\n \"pino-http\": \"^10.4.0\",\n winston: \"^3.19.0\",\n\n // OpenTelemetry\n \"@opentelemetry/api\": \"^1.9.0\",\n \"@opentelemetry/sdk-node\": \"^0.57.2\",\n \"@opentelemetry/auto-instrumentations-node\": \"^0.56.1\",\n \"@opentelemetry/exporter-trace-otlp-http\": \"^0.57.2\",\n \"@opentelemetry/exporter-metrics-otlp-http\": \"^0.57.2\",\n \"@opentelemetry/resources\": \"^1.30.1\",\n \"@opentelemetry/semantic-conventions\": \"^1.30.0\",\n\n // Headless CMS - Payload\n payload: \"^3.14.1\",\n \"@payloadcms/next\": \"^3.14.1\",\n \"@payloadcms/richtext-lexical\": \"^3.14.1\",\n \"@payloadcms/db-postgres\": \"^3.14.1\",\n \"@payloadcms/db-mongodb\": \"^3.14.1\",\n \"@payloadcms/db-sqlite\": \"^3.14.1\",\n \"@payloadcms/plugin-seo\": \"^3.14.1\",\n \"@payloadcms/storage-s3\": \"^3.14.1\",\n\n // Headless CMS - Sanity\n sanity: \"^3.82.0\",\n \"next-sanity\": \"^9.11.2\",\n \"@sanity/image-url\": \"^1.1.0\",\n \"@sanity/vision\": \"^3.82.0\",\n\n // Headless CMS - Strapi\n \"@strapi/client\": \"^1.2.1\",\n qs: \"^6.14.0\",\n\n // Caching - Upstash Redis\n \"@upstash/redis\": \"^1.34.3\",\n} as const;\n\nexport type AvailableDependencies = keyof typeof dependencyVersionMap;\n\nexport type AddDepsOptions = {\n vfs: VirtualFileSystem;\n packagePath: string;\n dependencies?: AvailableDependencies[];\n devDependencies?: AvailableDependencies[];\n customDependencies?: Record<string, string>;\n customDevDependencies?: Record<string, string>;\n};\n\n/**\n * Add dependencies to a package.json file in the VFS\n */\nexport function addPackageDependency(options: AddDepsOptions): void {\n const {\n vfs,\n packagePath,\n dependencies = [],\n devDependencies = [],\n customDependencies = {},\n customDevDependencies = {},\n } = options;\n\n const pkgJson = vfs.readJson<PackageJson>(packagePath);\n if (!pkgJson) return;\n\n // Initialize if not present\n pkgJson.dependencies = pkgJson.dependencies || {};\n pkgJson.devDependencies = pkgJson.devDependencies || {};\n\n // Add regular dependencies\n for (const dep of dependencies) {\n if (!pkgJson.dependencies[dep]) {\n const version = dependencyVersionMap[dep as AvailableDependencies];\n if (!version) {\n throw new Error(\n `Missing version for dependency: ${dep}. Add it to dependencyVersionMap in add-deps.ts`,\n );\n }\n pkgJson.dependencies[dep] = version;\n }\n }\n\n // Add dev dependencies\n for (const dep of devDependencies) {\n if (!pkgJson.devDependencies[dep]) {\n const version = dependencyVersionMap[dep as AvailableDependencies];\n if (!version) {\n throw new Error(\n `Missing version for devDependency: ${dep}. Add it to dependencyVersionMap in add-deps.ts`,\n );\n }\n pkgJson.devDependencies[dep] = version;\n }\n }\n\n // Add custom dependencies (with specific versions)\n for (const [dep, version] of Object.entries(customDependencies)) {\n pkgJson.dependencies[dep] = version;\n }\n\n // Add custom dev dependencies (with specific versions)\n for (const [dep, version] of Object.entries(customDevDependencies)) {\n pkgJson.devDependencies[dep] = version;\n }\n\n vfs.writeJson(packagePath, pkgJson);\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency } from \"../utils/add-deps\";\n\ntype PackageJson = {\n name?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n \"lint-staged\"?: Record<string, string | string[]>;\n [key: string]: unknown;\n};\n\nexport function processAddonsDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n if (!config.addons || config.addons.length === 0) return;\n\n const hasViteReactFrontend =\n config.frontend.includes(\"react-router\") || config.frontend.includes(\"tanstack-router\");\n const hasSolidFrontend = config.frontend.includes(\"solid\");\n const hasPwaCompatibleFrontend = hasViteReactFrontend || hasSolidFrontend;\n\n if (config.addons.includes(\"turborepo\")) {\n addPackageDependency({ vfs, packagePath: \"package.json\", devDependencies: [\"turbo\"] });\n }\n\n if (config.addons.includes(\"pwa\") && hasPwaCompatibleFrontend) {\n const webPkgPath = \"apps/web/package.json\";\n if (vfs.exists(webPkgPath)) {\n addPackageDependency({\n vfs,\n packagePath: webPkgPath,\n dependencies: [\"vite-plugin-pwa\"],\n devDependencies: [\"@vite-pwa/assets-generator\"],\n });\n const webPkg = vfs.readJson<PackageJson>(webPkgPath);\n if (webPkg) {\n webPkg.scripts = { ...webPkg.scripts, \"generate-pwa-assets\": \"pwa-assets-generator\" };\n vfs.writeJson(webPkgPath, webPkg);\n }\n }\n }\n\n if (config.addons.includes(\"tauri\")) {\n const webPkgPath = \"apps/web/package.json\";\n if (vfs.exists(webPkgPath)) {\n addPackageDependency({ vfs, packagePath: webPkgPath, devDependencies: [\"@tauri-apps/cli\"] });\n const webPkg = vfs.readJson<PackageJson>(webPkgPath);\n if (webPkg) {\n webPkg.scripts = {\n ...webPkg.scripts,\n tauri: \"tauri\",\n \"desktop:dev\": \"tauri dev\",\n \"desktop:build\": \"tauri build\",\n };\n vfs.writeJson(webPkgPath, webPkg);\n }\n }\n }\n\n // MSW (Mock Service Worker) - API mocking for testing and development\n if (config.addons.includes(\"msw\")) {\n const webPkgPath = \"apps/web/package.json\";\n const serverPkgPath = \"apps/server/package.json\";\n\n // Add MSW to web package (for browser-based mocking)\n if (vfs.exists(webPkgPath)) {\n addPackageDependency({ vfs, packagePath: webPkgPath, devDependencies: [\"msw\"] });\n }\n\n // Add MSW to server package (for Node.js-based mocking in tests)\n if (vfs.exists(serverPkgPath)) {\n addPackageDependency({ vfs, packagePath: serverPkgPath, devDependencies: [\"msw\"] });\n }\n }\n\n // Storybook - Component development and testing\n if (config.addons.includes(\"storybook\")) {\n const webPkgPath = \"apps/web/package.json\";\n if (vfs.exists(webPkgPath)) {\n // Determine framework-specific Storybook package\n const hasReactVite =\n config.frontend.includes(\"tanstack-router\") || config.frontend.includes(\"react-router\");\n const hasNext = config.frontend.includes(\"next\");\n const hasVue = config.frontend.includes(\"nuxt\");\n const hasSvelte = config.frontend.includes(\"svelte\");\n const hasSolid = config.frontend.includes(\"solid\");\n\n // Base Storybook dependencies\n const devDeps: Parameters<typeof addPackageDependency>[0][\"devDependencies\"] = [\n \"storybook\",\n \"@storybook/addon-essentials\",\n \"@storybook/addon-interactions\",\n \"@storybook/test\",\n ];\n\n // Add framework-specific renderer\n if (hasNext) {\n devDeps.push(\"@storybook/nextjs\");\n } else if (hasReactVite || hasSolid) {\n // Solid can use React Storybook with adapter, but for now use React-Vite\n devDeps.push(\"@storybook/react-vite\");\n } else if (hasVue) {\n devDeps.push(\"@storybook/vue3-vite\");\n } else if (hasSvelte) {\n devDeps.push(\"@storybook/svelte-vite\");\n }\n\n addPackageDependency({ vfs, packagePath: webPkgPath, devDependencies: devDeps });\n\n // Add Storybook scripts\n const webPkg = vfs.readJson<PackageJson>(webPkgPath);\n if (webPkg) {\n webPkg.scripts = {\n ...webPkg.scripts,\n storybook: \"storybook dev -p 6006\",\n \"build-storybook\": \"storybook build\",\n };\n vfs.writeJson(webPkgPath, webPkg);\n }\n }\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport { IndentationText, Node, Project, QuoteKind } from \"ts-morph\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nexport function processAlchemyPlugins(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { webDeploy, frontend } = config;\n\n if (webDeploy !== \"cloudflare\") return;\n\n const isNext = frontend.includes(\"next\");\n const isNuxt = frontend.includes(\"nuxt\");\n const isSvelte = frontend.includes(\"svelte\");\n const isTanstackStart = frontend.includes(\"tanstack-start\");\n\n if (isNext) {\n processNextAlchemy(vfs);\n } else if (isNuxt) {\n processNuxtAlchemy(vfs);\n } else if (isSvelte) {\n processSvelteAlchemy(vfs);\n } else if (isTanstackStart) {\n processTanStackStartAlchemy(vfs);\n }\n}\n\nfunction processNextAlchemy(vfs: VirtualFileSystem) {\n const webAppDir = \"apps/web\";\n const openNextConfigPath = `${webAppDir}/open-next.config.ts`;\n\n if (!vfs.exists(openNextConfigPath)) {\n const openNextConfigContent = `import { defineCloudflareConfig } from \"@opennextjs/cloudflare\";\n\nexport default defineCloudflareConfig({});\n`;\n vfs.writeFile(openNextConfigPath, openNextConfigContent);\n }\n\n const gitignorePath = `${webAppDir}/.gitignore`;\n if (vfs.exists(gitignorePath)) {\n let gitignoreContent = vfs.readFile(gitignorePath);\n if (gitignoreContent && !gitignoreContent.includes(\"wrangler.jsonc\")) {\n gitignoreContent += \"\\nwrangler.jsonc\\n\";\n vfs.writeFile(gitignorePath, gitignoreContent);\n }\n } else {\n vfs.writeFile(gitignorePath, \"wrangler.jsonc\\n\");\n }\n}\n\nfunction processNuxtAlchemy(vfs: VirtualFileSystem) {\n const nuxtConfigPath = \"apps/web/nuxt.config.ts\";\n if (!vfs.exists(nuxtConfigPath)) return;\n\n const content = vfs.readFile(nuxtConfigPath);\n const project = new Project({\n useInMemoryFileSystem: true,\n manipulationSettings: {\n indentationText: IndentationText.TwoSpaces,\n quoteKind: QuoteKind.Double,\n },\n });\n\n const sourceFile = project.createSourceFile(\"nuxt.config.ts\", content);\n const exportAssignment = sourceFile.getExportAssignment((d) => !d.isExportEquals());\n\n if (!exportAssignment) return;\n\n const defineConfigCall = exportAssignment.getExpression();\n if (\n !Node.isCallExpression(defineConfigCall) ||\n defineConfigCall.getExpression().getText() !== \"defineNuxtConfig\"\n ) {\n return;\n }\n\n let configObject = defineConfigCall.getArguments()[0];\n if (!configObject) {\n configObject = defineConfigCall.addArgument(\"{}\");\n }\n\n if (Node.isObjectLiteralExpression(configObject)) {\n if (!configObject.getProperty(\"nitro\")) {\n configObject.addPropertyAssignment({\n name: \"nitro\",\n initializer: `{\n preset: \"cloudflare_module\",\n cloudflare: {\n deployConfig: true,\n nodeCompat: true\n }\n }`,\n });\n }\n\n const modulesProperty = configObject.getProperty(\"modules\");\n if (modulesProperty && Node.isPropertyAssignment(modulesProperty)) {\n const initializer = modulesProperty.getInitializer();\n if (Node.isArrayLiteralExpression(initializer)) {\n const hasModule = initializer\n .getElements()\n .some(\n (el) =>\n el.getText() === '\"nitro-cloudflare-dev\"' ||\n el.getText() === \"'nitro-cloudflare-dev'\",\n );\n if (!hasModule) {\n initializer.addElement('\"nitro-cloudflare-dev\"');\n }\n }\n } else if (!modulesProperty) {\n configObject.addPropertyAssignment({\n name: \"modules\",\n initializer: '[\"nitro-cloudflare-dev\"]',\n });\n }\n }\n\n vfs.writeFile(nuxtConfigPath, sourceFile.getFullText());\n}\n\nfunction processSvelteAlchemy(vfs: VirtualFileSystem) {\n const svelteConfigPath = \"apps/web/svelte.config.js\";\n if (!vfs.exists(svelteConfigPath)) return;\n\n const content = vfs.readFile(svelteConfigPath);\n const project = new Project({\n useInMemoryFileSystem: true,\n manipulationSettings: {\n indentationText: IndentationText.TwoSpaces,\n quoteKind: QuoteKind.Single,\n },\n });\n\n const sourceFile = project.createSourceFile(\"svelte.config.js\", content);\n\n const importDeclarations = sourceFile.getImportDeclarations();\n const adapterImport = importDeclarations.find((imp) =>\n imp.getModuleSpecifierValue().includes(\"@sveltejs/adapter\"),\n );\n\n if (adapterImport) {\n adapterImport.setModuleSpecifier(\"alchemy/cloudflare/sveltekit\");\n adapterImport.removeDefaultImport();\n adapterImport.setDefaultImport(\"alchemy\");\n } else {\n sourceFile.insertImportDeclaration(0, {\n moduleSpecifier: \"alchemy/cloudflare/sveltekit\",\n defaultImport: \"alchemy\",\n });\n }\n\n const configVariable = sourceFile.getVariableDeclaration(\"config\");\n if (configVariable) {\n const initializer = configVariable.getInitializer();\n if (Node.isObjectLiteralExpression(initializer)) {\n const kitProperty = initializer.getProperty(\"kit\");\n if (kitProperty && Node.isPropertyAssignment(kitProperty)) {\n const kitInitializer = kitProperty.getInitializer();\n if (Node.isObjectLiteralExpression(kitInitializer)) {\n const adapterProperty = kitInitializer.getProperty(\"adapter\");\n if (adapterProperty && Node.isPropertyAssignment(adapterProperty)) {\n const adapterInitializer = adapterProperty.getInitializer();\n if (Node.isCallExpression(adapterInitializer)) {\n const expression = adapterInitializer.getExpression();\n if (Node.isIdentifier(expression) && expression.getText() === \"adapter\") {\n expression.replaceWithText(\"alchemy\");\n }\n }\n }\n }\n }\n }\n }\n\n vfs.writeFile(svelteConfigPath, sourceFile.getFullText());\n}\n\nfunction processTanStackStartAlchemy(vfs: VirtualFileSystem) {\n const viteConfigPath = \"apps/web/vite.config.ts\";\n if (!vfs.exists(viteConfigPath)) return;\n\n const content = vfs.readFile(viteConfigPath);\n const project = new Project({\n useInMemoryFileSystem: true,\n manipulationSettings: {\n indentationText: IndentationText.TwoSpaces,\n quoteKind: QuoteKind.Double,\n },\n });\n\n const sourceFile = project.createSourceFile(\"vite.config.ts\", content);\n\n const alchemyImport = sourceFile.getImportDeclaration(\n (decl) => decl.getModuleSpecifierValue() === \"alchemy/cloudflare/tanstack-start\",\n );\n\n if (!alchemyImport) {\n sourceFile.addImportDeclaration({\n moduleSpecifier: \"alchemy/cloudflare/tanstack-start\",\n defaultImport: \"alchemy\",\n });\n }\n\n const exportAssignment = sourceFile.getExportAssignment((d) => !d.isExportEquals());\n if (!exportAssignment) return;\n\n const defineConfigCall = exportAssignment.getExpression();\n if (\n !Node.isCallExpression(defineConfigCall) ||\n defineConfigCall.getExpression().getText() !== \"defineConfig\"\n ) {\n return;\n }\n\n let configObject = defineConfigCall.getArguments()[0];\n if (!configObject) {\n configObject = defineConfigCall.addArgument(\"{}\");\n }\n\n if (Node.isObjectLiteralExpression(configObject)) {\n const pluginsProperty = configObject.getProperty(\"plugins\");\n if (pluginsProperty && Node.isPropertyAssignment(pluginsProperty)) {\n const initializer = pluginsProperty.getInitializer();\n if (Node.isArrayLiteralExpression(initializer)) {\n const hasAlchemy = initializer\n .getElements()\n .some((el) => el.getText().includes(\"alchemy(\"));\n if (!hasAlchemy) {\n initializer.addElement(\"alchemy()\");\n }\n }\n } else {\n configObject.addPropertyAssignment({\n name: \"plugins\",\n initializer: \"[alchemy()]\",\n });\n }\n }\n\n vfs.writeFile(viteConfigPath, sourceFile.getFullText());\n}\n","import type { Frontend, ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\n// React-based web frameworks that support animation libraries\nconst REACT_WEB_FRAMEWORKS: Frontend[] = [\n \"tanstack-router\",\n \"react-router\",\n \"tanstack-start\",\n \"next\",\n];\n\n// Native frameworks (always React-based)\nconst NATIVE_FRAMEWORKS: Frontend[] = [\"native-bare\", \"native-uniwind\", \"native-unistyles\"];\n\nexport function processAnimationDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { animation, frontend } = config;\n\n // Skip if not selected or set to \"none\"\n if (!animation || animation === \"none\") return;\n\n // Determine which packages need animation deps\n const hasReactWeb = frontend.some((f) => REACT_WEB_FRAMEWORKS.includes(f));\n const hasNative = frontend.some((f) => NATIVE_FRAMEWORKS.includes(f));\n\n // Add to web package if it's a React-based web frontend\n const webPath = \"apps/web/package.json\";\n if (hasReactWeb && vfs.exists(webPath)) {\n const deps = getAnimationDeps(animation, false);\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: deps,\n });\n }\n }\n\n // Add to native package if it exists\n const nativePath = \"apps/native/package.json\";\n if (hasNative && vfs.exists(nativePath)) {\n const deps = getAnimationDeps(animation, true);\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: nativePath,\n dependencies: deps,\n });\n }\n }\n}\n\nfunction getAnimationDeps(\n animation: ProjectConfig[\"animation\"],\n isNative: boolean,\n): AvailableDependencies[] {\n const deps: AvailableDependencies[] = [];\n\n switch (animation) {\n case \"framer-motion\":\n deps.push(\"motion\");\n break;\n case \"gsap\":\n deps.push(\"gsap\");\n break;\n case \"react-spring\":\n // Use platform-specific package\n deps.push(isNative ? \"@react-spring/native\" : \"@react-spring/web\");\n break;\n case \"auto-animate\":\n // Same package works for both web and native\n deps.push(\"@formkit/auto-animate\");\n break;\n case \"lottie\":\n // Use platform-specific Lottie package\n deps.push(isNative ? \"lottie-react-native\" : \"lottie-react\");\n break;\n }\n\n return deps;\n}\n","import type { ProjectConfig, Frontend, API, Backend } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\ntype FrontendType = {\n hasReactWeb: boolean;\n hasNuxtWeb: boolean;\n hasSvelteWeb: boolean;\n hasSolidWeb: boolean;\n hasNative: boolean;\n};\n\nfunction getFrontendType(frontend: Frontend[]): FrontendType {\n return {\n hasReactWeb: frontend.some((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n ),\n hasNuxtWeb: frontend.includes(\"nuxt\"),\n hasSvelteWeb: frontend.includes(\"svelte\"),\n hasSolidWeb: frontend.includes(\"solid\"),\n hasNative: frontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n ),\n };\n}\n\nexport function processApiDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { api, backend, frontend, auth } = config;\n const frontendType = getFrontendType(frontend);\n\n if (backend === \"convex\") {\n addConvexDeps(vfs, frontend, frontendType);\n return;\n }\n\n if (api === \"none\") return;\n\n addApiPackageDeps(vfs, api, backend, frontend, auth);\n addServerDeps(vfs, api, backend);\n addSelfBackendWebDeps(vfs, api, backend, frontendType);\n addWebClientDeps(vfs, api, backend, frontendType);\n if (frontendType.hasNative) addNativeDeps(vfs, api, backend);\n addQueryDeps(vfs, frontend, backend);\n}\n\nfunction addApiPackageDeps(\n vfs: VirtualFileSystem,\n api: API,\n backend: Backend,\n frontend: Frontend[],\n auth: ProjectConfig[\"auth\"],\n): void {\n const pkgPath = \"packages/api/package.json\";\n if (!vfs.exists(pkgPath)) return;\n\n if (api === \"trpc\") {\n addPackageDependency({\n vfs,\n packagePath: pkgPath,\n dependencies: [\"@trpc/server\", \"@trpc/client\", \"zod\"],\n });\n } else if (api === \"orpc\") {\n addPackageDependency({\n vfs,\n packagePath: pkgPath,\n dependencies: [\"@orpc/server\", \"@orpc/client\", \"@orpc/openapi\", \"@orpc/zod\", \"zod\"],\n });\n } else if (api === \"ts-rest\") {\n addPackageDependency({\n vfs,\n packagePath: pkgPath,\n dependencies: [\"@ts-rest/core\", \"zod\"],\n });\n } else if (api === \"garph\") {\n addPackageDependency({\n vfs,\n packagePath: pkgPath,\n dependencies: [\"garph\", \"graphql-yoga\", \"graphql\"],\n });\n }\n\n // Add next dep for api package when backend is self and frontend includes next\n if (backend === \"self\" && frontend.includes(\"next\")) {\n addPackageDependency({ vfs, packagePath: pkgPath, dependencies: [\"next\"] });\n }\n\n // Add better-auth for express/fastify backends\n if (auth === \"better-auth\" && (backend === \"express\" || backend === \"fastify\")) {\n addPackageDependency({ vfs, packagePath: pkgPath, dependencies: [\"better-auth\"] });\n }\n\n // Add @types/express for express backend\n if (backend === \"express\") {\n addPackageDependency({ vfs, packagePath: pkgPath, devDependencies: [\"@types/express\"] });\n }\n}\n\nfunction addServerDeps(vfs: VirtualFileSystem, api: API, backend: Backend): void {\n const serverPath = \"apps/server/package.json\";\n if (!vfs.exists(serverPath)) return;\n\n if (backend === \"convex\") return;\n\n if (api === \"trpc\") {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"@trpc/server\", \"@hono/trpc-server\"],\n });\n } else if (api === \"orpc\") {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"@orpc/server\", \"@orpc/openapi\"],\n });\n } else if (api === \"ts-rest\") {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"@ts-rest/core\", \"@ts-rest/serverless\"],\n });\n } else if (api === \"garph\") {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"garph\", \"graphql-yoga\", \"graphql\"],\n });\n }\n}\n\nfunction addSelfBackendWebDeps(\n vfs: VirtualFileSystem,\n api: API,\n backend: Backend,\n frontendType: FrontendType,\n): void {\n if (backend !== \"self\") return;\n\n const webPath = \"apps/web/package.json\";\n if (!vfs.exists(webPath) || !frontendType.hasReactWeb) return;\n\n // When backend is \"self\", add server deps to web too\n if (api === \"trpc\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@trpc/server\", \"@trpc/client\"],\n });\n } else if (api === \"orpc\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@orpc/server\", \"@orpc/client\", \"@orpc/openapi\", \"@orpc/zod\"],\n });\n } else if (api === \"ts-rest\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@ts-rest/core\", \"@ts-rest/serverless\", \"@ts-rest/next\"],\n });\n } else if (api === \"garph\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"garph\", \"graphql-yoga\", \"graphql\"],\n });\n }\n}\n\nfunction addWebClientDeps(\n vfs: VirtualFileSystem,\n api: API,\n backend: Backend,\n frontendType: FrontendType,\n): void {\n const webPath = \"apps/web/package.json\";\n if (!vfs.exists(webPath) || backend === \"convex\") return;\n\n if (api === \"trpc\" && frontendType.hasReactWeb) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@trpc/tanstack-react-query\", \"@trpc/client\", \"@trpc/server\"],\n });\n } else if (api === \"ts-rest\" && frontendType.hasReactWeb) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@ts-rest/core\", \"@ts-rest/react-query\"],\n });\n } else if (api === \"orpc\" && frontendType.hasReactWeb) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@orpc/tanstack-query\", \"@orpc/client\", \"@orpc/server\"],\n });\n } else if (api === \"orpc\" && frontendType.hasNuxtWeb) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@tanstack/vue-query\", \"@orpc/tanstack-query\", \"@orpc/client\", \"@orpc/server\"],\n devDependencies: [\"@tanstack/vue-query-devtools\"],\n });\n } else if (api === \"orpc\" && frontendType.hasSvelteWeb) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\n \"@orpc/tanstack-query\",\n \"@orpc/client\",\n \"@orpc/server\",\n \"@tanstack/svelte-query\",\n ],\n devDependencies: [\"@tanstack/svelte-query-devtools\"],\n });\n } else if (api === \"orpc\" && frontendType.hasSolidWeb) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\n \"@orpc/tanstack-query\",\n \"@orpc/client\",\n \"@orpc/server\",\n \"@tanstack/solid-query\",\n ],\n devDependencies: [\"@tanstack/solid-query-devtools\", \"@tanstack/solid-router-devtools\"],\n });\n } else if (api === \"garph\" && frontendType.hasReactWeb) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@garph/gqty\", \"gqty\"],\n });\n }\n}\n\nfunction addNativeDeps(vfs: VirtualFileSystem, api: API, backend: Backend): void {\n const nativePath = \"apps/native/package.json\";\n if (!vfs.exists(nativePath)) return;\n\n if (backend === \"convex\") return;\n\n if (api === \"trpc\") {\n addPackageDependency({\n vfs,\n packagePath: nativePath,\n dependencies: [\"@trpc/tanstack-react-query\", \"@trpc/client\", \"@trpc/server\"],\n });\n } else if (api === \"orpc\") {\n addPackageDependency({\n vfs,\n packagePath: nativePath,\n dependencies: [\"@orpc/tanstack-query\", \"@orpc/client\"],\n });\n } else if (api === \"ts-rest\") {\n addPackageDependency({\n vfs,\n packagePath: nativePath,\n dependencies: [\"@ts-rest/core\", \"@ts-rest/react-query\"],\n });\n } else if (api === \"garph\") {\n addPackageDependency({\n vfs,\n packagePath: nativePath,\n dependencies: [\"@garph/gqty\", \"gqty\"],\n });\n }\n}\n\nfunction addQueryDeps(vfs: VirtualFileSystem, frontend: Frontend[], backend: Backend): void {\n const webPath = \"apps/web/package.json\";\n const nativePath = \"apps/native/package.json\";\n const frontendType = getFrontendType(frontend);\n\n if (frontendType.hasReactWeb && vfs.exists(webPath) && backend !== \"convex\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@tanstack/react-query\"],\n devDependencies: [\"@tanstack/react-query-devtools\"],\n });\n }\n\n if (frontendType.hasSolidWeb && vfs.exists(webPath) && backend !== \"convex\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@tanstack/solid-query\"],\n devDependencies: [\"@tanstack/solid-query-devtools\", \"@tanstack/solid-router-devtools\"],\n });\n }\n\n if (frontendType.hasNative && vfs.exists(nativePath) && backend !== \"convex\") {\n addPackageDependency({\n vfs,\n packagePath: nativePath,\n dependencies: [\"@tanstack/react-query\"],\n });\n }\n}\n\nfunction addConvexDeps(\n vfs: VirtualFileSystem,\n frontend: Frontend[],\n frontendType: FrontendType,\n): void {\n const webPath = \"apps/web/package.json\";\n const nativePath = \"apps/native/package.json\";\n const webExists = vfs.exists(webPath);\n const nativeExists = vfs.exists(nativePath);\n\n if (webExists) {\n const deps: AvailableDependencies[] = [\"convex\"];\n if (frontend.includes(\"tanstack-start\")) {\n deps.push(\"@convex-dev/react-query\", \"@tanstack/react-router-ssr-query\");\n }\n if (frontend.includes(\"svelte\")) {\n deps.push(\"convex-svelte\");\n }\n if (frontend.includes(\"nuxt\")) {\n deps.push(\"convex-nuxt\", \"convex-vue\");\n }\n addPackageDependency({ vfs, packagePath: webPath, dependencies: deps });\n }\n\n if (nativeExists && frontendType.hasNative) {\n addPackageDependency({ vfs, packagePath: nativePath, dependencies: [\"convex\"] });\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency } from \"../utils/add-deps\";\n\nexport function processAuthDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { auth, backend } = config;\n if (!auth || auth === \"none\") return;\n\n if (backend === \"convex\") {\n processConvexAuthDeps(vfs, config);\n } else {\n processStandardAuthDeps(vfs, config);\n }\n}\n\nfunction processConvexAuthDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { auth, frontend } = config;\n const webPath = \"apps/web/package.json\";\n const nativePath = \"apps/native/package.json\";\n const backendPath = \"packages/backend/package.json\";\n\n const webExists = vfs.exists(webPath);\n const nativeExists = vfs.exists(nativePath);\n const backendExists = vfs.exists(backendPath);\n\n const hasNative = frontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n const hasNextJs = frontend.includes(\"next\");\n const hasTanStackStart = frontend.includes(\"tanstack-start\");\n const hasViteReact = frontend.some((f) => [\"tanstack-router\", \"react-router\"].includes(f));\n\n if (auth === \"clerk\") {\n if (webExists) {\n if (hasNextJs) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@clerk/nextjs\"],\n });\n } else if (hasTanStackStart) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@clerk/tanstack-react-start\", \"srvx\"],\n });\n } else if (hasViteReact) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@clerk/clerk-react\"],\n });\n }\n }\n if (nativeExists && hasNative) {\n addPackageDependency({\n vfs,\n packagePath: nativePath,\n dependencies: [\"@clerk/clerk-expo\"],\n });\n }\n } else if (auth === \"better-auth\") {\n if (backendExists) {\n addPackageDependency({\n vfs,\n packagePath: backendPath,\n dependencies: [\"better-auth\", \"@convex-dev/better-auth\"],\n customDependencies: { \"better-auth\": \"1.4.9\" },\n });\n if (hasNative) {\n addPackageDependency({\n vfs,\n packagePath: backendPath,\n dependencies: [\"@better-auth/expo\"],\n customDependencies: { \"@better-auth/expo\": \"1.4.9\" },\n });\n }\n }\n\n if (webExists) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"better-auth\", \"@convex-dev/better-auth\"],\n customDependencies: { \"better-auth\": \"1.4.9\" },\n });\n }\n\n if (nativeExists && hasNative) {\n addPackageDependency({\n vfs,\n packagePath: nativePath,\n dependencies: [\"better-auth\", \"@better-auth/expo\", \"@convex-dev/better-auth\"],\n customDependencies: {\n \"better-auth\": \"1.4.9\",\n \"@better-auth/expo\": \"1.4.9\",\n },\n });\n }\n }\n}\n\nfunction processStandardAuthDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { auth, frontend } = config;\n const authPath = \"packages/auth/package.json\";\n const webPath = \"apps/web/package.json\";\n const nativePath = \"apps/native/package.json\";\n\n const authExists = vfs.exists(authPath);\n const webExists = vfs.exists(webPath);\n const nativeExists = vfs.exists(nativePath);\n\n const hasNative = frontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n const hasWebFrontend = frontend.some((f) =>\n [\n \"react-router\",\n \"tanstack-router\",\n \"tanstack-start\",\n \"next\",\n \"nuxt\",\n \"svelte\",\n \"solid\",\n ].includes(f),\n );\n\n if (auth === \"better-auth\") {\n if (authExists) {\n addPackageDependency({\n vfs,\n packagePath: authPath,\n dependencies: [\"better-auth\"],\n });\n if (hasNative) {\n addPackageDependency({\n vfs,\n packagePath: authPath,\n dependencies: [\"@better-auth/expo\"],\n });\n }\n }\n\n if (hasWebFrontend && webExists) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"better-auth\"],\n });\n }\n\n if (hasNative && nativeExists) {\n addPackageDependency({\n vfs,\n packagePath: nativePath,\n dependencies: [\"better-auth\", \"@better-auth/expo\"],\n });\n }\n } else if (auth === \"nextauth\") {\n const { orm } = config;\n const hasNextJs = frontend.includes(\"next\");\n\n // NextAuth only works with Next.js (self backend)\n if (hasNextJs && webExists) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"next-auth\", \"@auth/core\"],\n });\n\n // Add ORM-specific adapter\n if (orm === \"drizzle\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@auth/drizzle-adapter\"],\n });\n } else if (orm === \"prisma\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@auth/prisma-adapter\"],\n });\n }\n }\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport { Project, SyntaxKind } from \"ts-morph\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nexport function processAuthPlugins(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const authIndexPath = \"packages/auth/src/index.ts\";\n if (!vfs.exists(authIndexPath)) return;\n\n const content = vfs.readFile(authIndexPath);\n const project = new Project({\n useInMemoryFileSystem: true,\n });\n\n const sourceFile = project.createSourceFile(\"index.ts\", content);\n\n const pluginsToAdd: string[] = [];\n const importsToAdd: { named: string; module: string }[] = [];\n\n // TanStack Start Cookies\n if (config.backend === \"self\" && config.frontend.includes(\"tanstack-start\")) {\n pluginsToAdd.push(\"tanstackStartCookies()\");\n importsToAdd.push({\n named: \"tanstackStartCookies\",\n module: \"better-auth/tanstack-start\",\n });\n }\n\n // Next.js Cookies\n if (config.backend === \"self\" && config.frontend.includes(\"next\")) {\n pluginsToAdd.push(\"nextCookies()\");\n importsToAdd.push({\n named: \"nextCookies\",\n module: \"better-auth/next-js\",\n });\n }\n\n // Expo Plugin\n const hasNative = config.frontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n if (hasNative) {\n pluginsToAdd.push(\"expo()\");\n importsToAdd.push({\n named: \"expo\",\n module: \"@better-auth/expo\",\n });\n }\n\n if (pluginsToAdd.length === 0) return;\n\n // Add imports\n importsToAdd.forEach(({ named, module }) => {\n const existingImport = sourceFile.getImportDeclaration((decl) =>\n decl.getModuleSpecifierValue().includes(module),\n );\n\n if (existingImport) {\n const namedImports = existingImport.getNamedImports();\n if (!namedImports.some((ni) => ni.getName() === named)) {\n existingImport.addNamedImport(named);\n }\n } else {\n sourceFile.addImportDeclaration({\n moduleSpecifier: module,\n namedImports: [named],\n });\n }\n });\n\n // Add plugins to betterAuth config\n const betterAuthCall = sourceFile\n .getVariableDeclaration(\"auth\")\n ?.getInitializerIfKind(SyntaxKind.CallExpression);\n\n if (betterAuthCall) {\n const configObject = betterAuthCall\n .getArguments()[0]\n ?.asKind(SyntaxKind.ObjectLiteralExpression);\n\n if (configObject) {\n const pluginsProp = configObject.getProperty(\"plugins\");\n\n if (pluginsProp?.isKind(SyntaxKind.PropertyAssignment)) {\n const arrayLiteral = pluginsProp.getInitializerIfKind(SyntaxKind.ArrayLiteralExpression);\n if (arrayLiteral) {\n pluginsToAdd.forEach((plugin) => {\n arrayLiteral.addElement(plugin);\n });\n }\n } else {\n // Create plugins array if it doesn't exist\n configObject.addPropertyAssignment({\n name: \"plugins\",\n initializer: `[${pluginsToAdd.join(\", \")}]`,\n });\n }\n }\n }\n\n vfs.writeFile(authIndexPath, sourceFile.getFullText());\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\nexport function processBackendDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { backend, runtime, api, auth } = config;\n\n if (backend === \"convex\") {\n const convexPath = \"packages/backend/package.json\";\n if (vfs.exists(convexPath)) {\n addPackageDependency({ vfs, packagePath: convexPath, dependencies: [\"convex\"] });\n }\n return;\n }\n\n const serverPath = \"apps/server/package.json\";\n if (!vfs.exists(serverPath) || backend === \"self\" || backend === \"none\") return;\n\n const deps: AvailableDependencies[] = [];\n const devDeps: AvailableDependencies[] = [];\n\n if (backend === \"hono\") {\n deps.push(\"hono\");\n if (runtime === \"node\") deps.push(\"@hono/node-server\");\n } else if (backend === \"elysia\") {\n deps.push(\"elysia\", \"@elysiajs/cors\");\n if (runtime === \"node\") deps.push(\"@elysiajs/node\");\n } else if (backend === \"express\") {\n deps.push(\"express\", \"cors\");\n devDeps.push(\"@types/express\", \"@types/cors\");\n } else if (backend === \"fastify\") {\n deps.push(\"fastify\", \"@fastify/cors\");\n } else if (backend === \"nestjs\") {\n deps.push(\n \"@nestjs/core\",\n \"@nestjs/common\",\n \"@nestjs/platform-express\",\n \"reflect-metadata\",\n \"rxjs\",\n \"express\",\n );\n devDeps.push(\"@types/express\");\n } else if (backend === \"encore\") {\n deps.push(\"encore.dev\");\n } else if (backend === \"adonisjs\") {\n deps.push(\"@adonisjs/core\", \"@adonisjs/cors\", \"reflect-metadata\");\n devDeps.push(\"@adonisjs/tsconfig\", \"@types/node\");\n } else if (backend === \"nitro\") {\n deps.push(\"nitropack\", \"h3\");\n } else if (backend === \"fets\") {\n deps.push(\"fets\");\n }\n\n if (api === \"trpc\") {\n deps.push(\"@trpc/server\");\n if (backend === \"hono\") deps.push(\"@hono/trpc-server\");\n else if (backend === \"elysia\") deps.push(\"@elysiajs/trpc\");\n } else if (api === \"orpc\") {\n deps.push(\"@orpc/server\", \"@orpc/openapi\", \"@orpc/zod\");\n }\n\n if (auth === \"better-auth\") deps.push(\"better-auth\");\n\n if (runtime === \"node\") devDeps.push(\"tsx\", \"@types/node\");\n else if (runtime === \"bun\") devDeps.push(\"@types/bun\");\n\n if (deps.length > 0 || devDeps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: deps,\n devDependencies: devDeps,\n });\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\nexport function processCachingDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { caching, backend } = config;\n\n // Skip if not selected or set to \"none\"\n if (!caching || caching === \"none\") return;\n\n // Skip if no backend to support caching (convex has its own caching)\n if (backend === \"none\" || backend === \"convex\") return;\n\n // Add server-side caching dependencies\n const serverPath = \"apps/server/package.json\";\n if (vfs.exists(serverPath)) {\n const deps = getCachingDeps(caching);\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: deps,\n });\n }\n }\n\n // For fullstack frameworks (self), add to web package\n if (backend === \"self\") {\n const webPath = \"apps/web/package.json\";\n if (vfs.exists(webPath)) {\n const deps = getCachingDeps(caching);\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: deps,\n });\n }\n }\n }\n}\n\nfunction getCachingDeps(caching: ProjectConfig[\"caching\"]): AvailableDependencies[] {\n const deps: AvailableDependencies[] = [];\n\n switch (caching) {\n case \"upstash-redis\":\n deps.push(\"@upstash/redis\");\n break;\n }\n\n return deps;\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\nexport function processCMSDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { cms, frontend, database } = config;\n\n // Skip if not selected or set to \"none\"\n if (!cms || cms === \"none\") return;\n\n // Both Payload and Sanity require Next.js for optimal integration\n const hasNext = frontend.includes(\"next\");\n\n if (cms === \"payload\") {\n // Payload is a Next.js-only CMS in v3\n if (!hasNext) return;\n\n const webPath = \"apps/web/package.json\";\n if (vfs.exists(webPath)) {\n const deps = getPayloadDeps(database);\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: deps,\n });\n }\n }\n }\n\n if (cms === \"sanity\") {\n // Sanity works best with Next.js due to next-sanity integration\n if (!hasNext) return;\n\n const webPath = \"apps/web/package.json\";\n if (vfs.exists(webPath)) {\n const deps = getSanityDeps();\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: deps,\n });\n }\n }\n }\n\n if (cms === \"strapi\") {\n // Strapi client works with any frontend but we provide Next.js templates\n if (!hasNext) return;\n\n const webPath = \"apps/web/package.json\";\n if (vfs.exists(webPath)) {\n const deps = getStrapiDeps();\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: deps,\n });\n }\n }\n }\n}\n\nfunction getPayloadDeps(database: ProjectConfig[\"database\"]): AvailableDependencies[] {\n const deps: AvailableDependencies[] = [\n \"payload\",\n \"@payloadcms/next\",\n \"@payloadcms/richtext-lexical\",\n ];\n\n // Add appropriate database adapter based on selected database\n switch (database) {\n case \"postgres\":\n deps.push(\"@payloadcms/db-postgres\");\n break;\n case \"mongodb\":\n deps.push(\"@payloadcms/db-mongodb\");\n break;\n case \"sqlite\":\n deps.push(\"@payloadcms/db-sqlite\");\n break;\n default:\n // Default to SQLite for simplicity\n deps.push(\"@payloadcms/db-sqlite\");\n break;\n }\n\n return deps;\n}\n\nfunction getSanityDeps(): AvailableDependencies[] {\n return [\"sanity\", \"next-sanity\", \"@sanity/image-url\", \"@sanity/vision\"];\n}\n\nfunction getStrapiDeps(): AvailableDependencies[] {\n return [\"@strapi/client\", \"qs\"];\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\n/**\n * Process CSS framework dependencies based on config.cssFramework\n */\nexport function processCSSFrameworkDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { cssFramework, frontend } = config;\n\n const hasWeb = frontend.some((f) =>\n [\n \"tanstack-router\",\n \"react-router\",\n \"tanstack-start\",\n \"next\",\n \"nuxt\",\n \"svelte\",\n \"solid\",\n \"astro\",\n \"qwik\",\n ].includes(f),\n );\n\n if (!hasWeb) return;\n\n const webPath = \"apps/web/package.json\";\n if (!vfs.exists(webPath)) return;\n\n // Add CSS preprocessor dependencies\n if (cssFramework === \"scss\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n devDependencies: [\"sass\"],\n });\n } else if (cssFramework === \"less\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n devDependencies: [\"less\"],\n });\n }\n // tailwind, postcss-only, and none don't need extra dependencies\n // tailwind is already included in the base templates\n}\n\n/**\n * Process UI library dependencies based on config.uiLibrary\n */\nexport function processUILibraryDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { uiLibrary, frontend, cssFramework } = config;\n\n const hasReactWeb = frontend.some((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n const hasNuxt = frontend.includes(\"nuxt\");\n const hasSolid = frontend.includes(\"solid\");\n const hasSvelte = frontend.includes(\"svelte\");\n\n if (uiLibrary === \"none\" || uiLibrary === \"shadcn-ui\") {\n // shadcn-ui is handled by the shadcn CLI, not as a package dependency\n return;\n }\n\n const webPath = \"apps/web/package.json\";\n if (!vfs.exists(webPath)) return;\n\n const deps: AvailableDependencies[] = [];\n\n switch (uiLibrary) {\n case \"daisyui\":\n // daisyui is a Tailwind plugin, added via tailwind.config\n addPackageDependency({\n vfs,\n packagePath: webPath,\n devDependencies: [\"daisyui\"],\n });\n break;\n\n case \"radix-ui\":\n if (hasReactWeb) {\n deps.push(\n \"@radix-ui/react-dialog\",\n \"@radix-ui/react-dropdown-menu\",\n \"@radix-ui/react-slot\",\n \"@radix-ui/react-label\",\n \"@radix-ui/react-checkbox\",\n \"@radix-ui/react-select\",\n \"@radix-ui/react-toast\",\n \"@radix-ui/react-popover\",\n \"@radix-ui/react-switch\",\n \"@radix-ui/react-tabs\",\n );\n }\n break;\n\n case \"headless-ui\":\n if (hasReactWeb) {\n deps.push(\"@headlessui/react\");\n } else if (hasNuxt) {\n deps.push(\"@headlessui/vue\");\n }\n break;\n\n case \"park-ui\":\n // Park UI uses Panda CSS preset and Ark UI components\n deps.push(\"@park-ui/panda-preset\", \"@park-ui/ark\");\n break;\n\n case \"chakra-ui\":\n if (hasReactWeb) {\n deps.push(\"@chakra-ui/react\", \"@emotion/react\");\n }\n break;\n\n case \"nextui\":\n if (hasReactWeb) {\n deps.push(\"@heroui/react\", \"framer-motion\");\n }\n break;\n\n case \"mantine\":\n if (hasReactWeb) {\n deps.push(\"@mantine/core\", \"@mantine/hooks\");\n }\n break;\n\n case \"base-ui\":\n if (hasReactWeb) {\n deps.push(\"@base-ui-components/react\");\n }\n break;\n\n case \"ark-ui\":\n if (hasReactWeb) {\n deps.push(\"@ark-ui/react\");\n } else if (hasNuxt) {\n deps.push(\"@ark-ui/vue\");\n } else if (hasSolid) {\n deps.push(\"@ark-ui/solid\");\n } else if (hasSvelte) {\n deps.push(\"@ark-ui/svelte\");\n }\n break;\n\n case \"react-aria\":\n if (hasReactWeb) {\n deps.push(\"react-aria-components\");\n }\n break;\n }\n\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: deps,\n });\n }\n}\n\n/**\n * Combined processor for both CSS framework and UI library dependencies\n */\nexport function processCSSAndUILibraryDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n processCSSFrameworkDeps(vfs, config);\n processUILibraryDeps(vfs, config);\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\nexport function processDatabaseDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { database, orm, backend } = config;\n\n if (backend === \"convex\" || database === \"none\") return;\n\n const dbPkgPath = \"packages/db/package.json\";\n const webPkgPath = \"apps/web/package.json\";\n\n if (!vfs.exists(dbPkgPath)) return;\n const webExists = vfs.exists(webPkgPath);\n\n if (orm === \"prisma\") {\n processPrismaDeps(vfs, config, dbPkgPath, webPkgPath, webExists);\n } else if (orm === \"drizzle\") {\n processDrizzleDeps(vfs, config, dbPkgPath, webPkgPath, webExists);\n } else if (orm === \"mongoose\") {\n addPackageDependency({ vfs, packagePath: dbPkgPath, dependencies: [\"mongoose\"] });\n } else if (orm === \"typeorm\") {\n processTypeORMDeps(vfs, config, dbPkgPath);\n } else if (orm === \"kysely\") {\n processKyselyDeps(vfs, config, dbPkgPath);\n } else if (orm === \"mikroorm\") {\n processMikroORMDeps(vfs, config, dbPkgPath);\n } else if (orm === \"sequelize\") {\n processSequelizeDeps(vfs, config, dbPkgPath);\n }\n}\n\nfunction processPrismaDeps(\n vfs: VirtualFileSystem,\n config: ProjectConfig,\n dbPkgPath: string,\n webPkgPath: string,\n webExists: boolean,\n): void {\n const { database, dbSetup } = config;\n\n if (database === \"mongodb\") {\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n customDependencies: { \"@prisma/client\": \"6.19.0\" },\n customDevDependencies: { prisma: \"6.19.0\" },\n });\n if (webExists) {\n addPackageDependency({\n vfs,\n packagePath: webPkgPath,\n customDependencies: { \"@prisma/client\": \"6.19.0\" },\n });\n }\n return;\n }\n\n const deps: AvailableDependencies[] = [\"@prisma/client\"];\n const devDeps: AvailableDependencies[] = [\"prisma\"];\n\n if (database === \"mysql\" && dbSetup === \"planetscale\") {\n deps.push(\"@prisma/adapter-planetscale\", \"@planetscale/database\");\n } else if (database === \"mysql\") {\n deps.push(\"@prisma/adapter-mariadb\");\n } else if (database === \"sqlite\") {\n deps.push(dbSetup === \"d1\" ? \"@prisma/adapter-d1\" : \"@prisma/adapter-libsql\");\n } else if (database === \"postgres\") {\n if (dbSetup === \"neon\") {\n deps.push(\"@prisma/adapter-neon\", \"@neondatabase/serverless\", \"ws\");\n devDeps.push(\"@types/ws\");\n } else if (dbSetup === \"prisma-postgres\") {\n deps.push(\"@prisma/adapter-pg\");\n } else {\n deps.push(\"@prisma/adapter-pg\", \"pg\");\n devDeps.push(\"@types/pg\");\n }\n }\n\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: deps,\n devDependencies: devDeps,\n });\n\n if (webExists) {\n addPackageDependency({ vfs, packagePath: webPkgPath, dependencies: [\"@prisma/client\"] });\n }\n}\n\nfunction processDrizzleDeps(\n vfs: VirtualFileSystem,\n config: ProjectConfig,\n dbPkgPath: string,\n webPkgPath: string,\n webExists: boolean,\n): void {\n const { database, dbSetup } = config;\n\n if (database === \"sqlite\") {\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: [\"drizzle-orm\", \"@libsql/client\", \"libsql\"],\n devDependencies: [\"drizzle-kit\"],\n });\n if (webExists) {\n addPackageDependency({\n vfs,\n packagePath: webPkgPath,\n dependencies: [\"@libsql/client\", \"libsql\"],\n });\n }\n } else if (database === \"postgres\") {\n const deps: AvailableDependencies[] = [\"drizzle-orm\"];\n const devDeps: AvailableDependencies[] = [\"drizzle-kit\"];\n\n if (dbSetup === \"neon\") {\n deps.push(\"@neondatabase/serverless\", \"ws\");\n devDeps.push(\"@types/ws\");\n } else {\n deps.push(\"pg\");\n devDeps.push(\"@types/pg\");\n }\n\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: deps,\n devDependencies: devDeps,\n });\n } else if (database === \"mysql\") {\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies:\n dbSetup === \"planetscale\"\n ? [\"drizzle-orm\", \"@planetscale/database\"]\n : [\"drizzle-orm\", \"mysql2\"],\n devDependencies: [\"drizzle-kit\"],\n });\n }\n}\n\nfunction processTypeORMDeps(\n vfs: VirtualFileSystem,\n config: ProjectConfig,\n dbPkgPath: string,\n): void {\n const { database } = config;\n\n const deps: AvailableDependencies[] = [\"typeorm\", \"reflect-metadata\"];\n\n if (database === \"sqlite\") {\n deps.push(\"better-sqlite3\");\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: deps,\n devDependencies: [\"@types/better-sqlite3\"],\n });\n } else if (database === \"postgres\") {\n deps.push(\"pg\");\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: deps,\n devDependencies: [\"@types/pg\"],\n });\n } else if (database === \"mysql\") {\n deps.push(\"mysql2\");\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: deps,\n });\n }\n}\n\nfunction processKyselyDeps(vfs: VirtualFileSystem, config: ProjectConfig, dbPkgPath: string): void {\n const { database } = config;\n\n const deps: AvailableDependencies[] = [\"kysely\"];\n\n if (database === \"sqlite\") {\n deps.push(\"better-sqlite3\");\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: deps,\n devDependencies: [\"@types/better-sqlite3\"],\n });\n } else if (database === \"postgres\") {\n deps.push(\"pg\");\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: deps,\n devDependencies: [\"@types/pg\"],\n });\n } else if (database === \"mysql\") {\n deps.push(\"mysql2\");\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: deps,\n });\n }\n}\n\nfunction processMikroORMDeps(\n vfs: VirtualFileSystem,\n config: ProjectConfig,\n dbPkgPath: string,\n): void {\n const { database } = config;\n\n const deps: AvailableDependencies[] = [\"@mikro-orm/core\"];\n\n if (database === \"sqlite\") {\n deps.push(\"@mikro-orm/better-sqlite\");\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: deps,\n });\n } else if (database === \"postgres\") {\n deps.push(\"@mikro-orm/postgresql\");\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: deps,\n });\n } else if (database === \"mysql\") {\n deps.push(\"@mikro-orm/mysql\");\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: deps,\n });\n }\n}\n\nfunction processSequelizeDeps(\n vfs: VirtualFileSystem,\n config: ProjectConfig,\n dbPkgPath: string,\n): void {\n const { database } = config;\n\n const deps: AvailableDependencies[] = [\"sequelize\", \"sequelize-typescript\"];\n\n if (database === \"sqlite\") {\n deps.push(\"sqlite3\");\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: deps,\n });\n } else if (database === \"postgres\") {\n deps.push(\"pg\");\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: deps,\n devDependencies: [\"@types/pg\"],\n });\n } else if (database === \"mysql\") {\n deps.push(\"mysql2\");\n addPackageDependency({\n vfs,\n packagePath: dbPkgPath,\n dependencies: deps,\n });\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency } from \"../utils/add-deps\";\n\nexport function processDeployDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { webDeploy, serverDeploy, frontend, backend } = config;\n\n const isCloudflareWeb = webDeploy === \"cloudflare\";\n const isCloudflareServer = serverDeploy === \"cloudflare\";\n const isBackendSelf = backend === \"self\";\n\n if (!isCloudflareWeb && !isCloudflareServer) return;\n\n if (isCloudflareWeb || isCloudflareServer) {\n addPackageDependency({\n vfs,\n packagePath: \"package.json\",\n devDependencies: [\"@cloudflare/workers-types\"],\n });\n }\n\n if (isCloudflareServer && !isBackendSelf) {\n const serverPkgPath = \"apps/server/package.json\";\n if (vfs.exists(serverPkgPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPkgPath,\n devDependencies: [\"alchemy\", \"wrangler\", \"@types/node\", \"@cloudflare/workers-types\"],\n });\n }\n }\n\n if (isCloudflareWeb) {\n const webPkgPath = \"apps/web/package.json\";\n if (!vfs.exists(webPkgPath)) return;\n\n if (frontend.includes(\"next\")) {\n addPackageDependency({\n vfs,\n packagePath: webPkgPath,\n dependencies: [\"@opennextjs/cloudflare\"],\n devDependencies: [\"alchemy\", \"wrangler\", \"@cloudflare/workers-types\"],\n });\n } else if (frontend.includes(\"nuxt\")) {\n addPackageDependency({\n vfs,\n packagePath: webPkgPath,\n devDependencies: [\"alchemy\", \"nitro-cloudflare-dev\", \"wrangler\"],\n });\n } else if (frontend.includes(\"svelte\")) {\n addPackageDependency({\n vfs,\n packagePath: webPkgPath,\n devDependencies: [\"alchemy\", \"@sveltejs/adapter-cloudflare\"],\n });\n } else if (frontend.includes(\"tanstack-start\")) {\n addPackageDependency({\n vfs,\n packagePath: webPkgPath,\n devDependencies: [\"alchemy\", \"@cloudflare/vite-plugin\", \"wrangler\"],\n });\n } else if (\n frontend.includes(\"tanstack-router\") ||\n frontend.includes(\"react-router\") ||\n frontend.includes(\"solid\")\n ) {\n addPackageDependency({ vfs, packagePath: webPkgPath, devDependencies: [\"alchemy\"] });\n }\n }\n}\n","import type { ProjectConfig, Database, Runtime, ORM } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\nexport function processEffectDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { effect, runtime, database, orm, testing, backend, frontend } = config;\n\n if (effect === \"none\") return;\n\n const hasWeb = frontend.some((f) => f !== \"none\");\n const hasNative = frontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n const hasServer = backend !== \"none\" && backend !== \"convex\" && backend !== \"self\";\n\n // Add core effect to all relevant packages\n addEffectCoreDeps(vfs, effect, hasWeb, hasNative, hasServer);\n\n // For effect-full, add platform and schema packages\n if (effect === \"effect-full\") {\n addEffectPlatformDeps(vfs, runtime, hasWeb, hasNative, hasServer);\n addEffectSqlDeps(vfs, database, orm, runtime);\n addEffectTestingDeps(vfs, testing);\n }\n}\n\nfunction addEffectCoreDeps(\n vfs: VirtualFileSystem,\n effect: ProjectConfig[\"effect\"],\n hasWeb: boolean,\n hasNative: boolean,\n hasServer: boolean,\n): void {\n const deps: AvailableDependencies[] = [\"effect\"];\n\n // For effect-full, also add schema\n if (effect === \"effect-full\") {\n deps.push(\"@effect/schema\");\n }\n\n // Add to server package\n const serverPath = \"apps/server/package.json\";\n if (hasServer && vfs.exists(serverPath)) {\n addPackageDependency({ vfs, packagePath: serverPath, dependencies: deps });\n }\n\n // Add to web package\n const webPath = \"apps/web/package.json\";\n if (hasWeb && vfs.exists(webPath)) {\n addPackageDependency({ vfs, packagePath: webPath, dependencies: deps });\n }\n\n // Add to native package\n const nativePath = \"apps/native/package.json\";\n if (hasNative && vfs.exists(nativePath)) {\n addPackageDependency({ vfs, packagePath: nativePath, dependencies: deps });\n }\n\n // Add to packages/api if it exists\n const apiPath = \"packages/api/package.json\";\n if (vfs.exists(apiPath)) {\n addPackageDependency({ vfs, packagePath: apiPath, dependencies: deps });\n }\n}\n\nfunction addEffectPlatformDeps(\n vfs: VirtualFileSystem,\n runtime: Runtime,\n hasWeb: boolean,\n hasNative: boolean,\n hasServer: boolean,\n): void {\n const serverPath = \"apps/server/package.json\";\n const webPath = \"apps/web/package.json\";\n const nativePath = \"apps/native/package.json\";\n\n // Add platform packages based on runtime\n if (hasServer && vfs.exists(serverPath)) {\n const deps: AvailableDependencies[] = [\"@effect/platform\"];\n if (runtime === \"bun\") {\n deps.push(\"@effect/platform-bun\");\n } else if (runtime === \"node\") {\n deps.push(\"@effect/platform-node\");\n }\n // For workers runtime, just use @effect/platform\n addPackageDependency({ vfs, packagePath: serverPath, dependencies: deps });\n }\n\n // For web, add browser platform\n if (hasWeb && vfs.exists(webPath)) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@effect/platform\", \"@effect/platform-browser\"],\n });\n }\n\n // For native, add the platform package\n if (hasNative && vfs.exists(nativePath)) {\n addPackageDependency({\n vfs,\n packagePath: nativePath,\n dependencies: [\"@effect/platform\"],\n });\n }\n}\n\nfunction addEffectSqlDeps(\n vfs: VirtualFileSystem,\n database: Database,\n orm: ORM,\n runtime: Runtime,\n): void {\n if (database === \"none\") return;\n\n const serverPath = \"apps/server/package.json\";\n if (!vfs.exists(serverPath)) return;\n\n const deps: AvailableDependencies[] = [\"@effect/sql\"];\n\n // Add database-specific SQL adapter\n if (database === \"sqlite\") {\n if (runtime === \"bun\") {\n deps.push(\"@effect/sql-sqlite-bun\");\n } else {\n deps.push(\"@effect/sql-sqlite-node\");\n }\n } else if (database === \"postgres\") {\n deps.push(\"@effect/sql-pg\");\n } else if (database === \"mysql\") {\n deps.push(\"@effect/sql-mysql2\");\n }\n\n // If using Drizzle ORM, also add the drizzle adapter\n if (orm === \"drizzle\") {\n deps.push(\"@effect/sql-drizzle\");\n }\n\n addPackageDependency({ vfs, packagePath: serverPath, dependencies: deps });\n}\n\nfunction addEffectTestingDeps(vfs: VirtualFileSystem, testing: ProjectConfig[\"testing\"]): void {\n if (testing === \"none\" || testing === \"playwright\") return;\n\n // Add @effect/vitest to packages that use vitest\n const packagesToCheck = [\n \"apps/server/package.json\",\n \"apps/web/package.json\",\n \"packages/api/package.json\",\n ];\n\n for (const pkgPath of packagesToCheck) {\n if (vfs.exists(pkgPath)) {\n addPackageDependency({\n vfs,\n packagePath: pkgPath,\n devDependencies: [\"@effect/vitest\"],\n });\n }\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency } from \"../utils/add-deps\";\n\nexport function processEmailDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { email, frontend, backend } = config;\n if (!email || email === \"none\") return;\n if (backend === \"none\" || backend === \"convex\") return;\n\n const serverPath = \"apps/server/package.json\";\n\n // Add Resend SDK for resend option\n if (email === \"resend\" && vfs.exists(serverPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"resend\"],\n });\n }\n\n // Add Nodemailer for nodemailer option\n if (email === \"nodemailer\" && vfs.exists(serverPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"nodemailer\"],\n devDependencies: [\"@types/nodemailer\"],\n });\n }\n\n // Add Postmark for postmark option\n if (email === \"postmark\" && vfs.exists(serverPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"postmark\"],\n });\n }\n\n // Add SendGrid for sendgrid option\n if (email === \"sendgrid\" && vfs.exists(serverPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"@sendgrid/mail\"],\n });\n }\n\n // Add AWS SES for aws-ses option\n if (email === \"aws-ses\" && vfs.exists(serverPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"@aws-sdk/client-ses\"],\n });\n }\n\n // Add Mailgun for mailgun option\n if (email === \"mailgun\" && vfs.exists(serverPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"mailgun.js\", \"form-data\"],\n });\n }\n\n // Add Plunk for plunk option\n if (email === \"plunk\" && vfs.exists(serverPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"@plunk/node\"],\n });\n }\n\n // Add React Email components for resend and react-email options (not nodemailer)\n const hasReactWeb = frontend.some((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n\n if (hasReactWeb && vfs.exists(serverPath) && (email === \"resend\" || email === \"react-email\")) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"@react-email/components\", \"react-email\"],\n });\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\nexport function processEnvDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const envPath = \"packages/env/package.json\";\n if (!vfs.exists(envPath)) return;\n\n const { frontend, backend, runtime } = config;\n const deps: AvailableDependencies[] = [\"zod\"];\n\n if (frontend.includes(\"next\")) {\n deps.push(\"@t3-oss/env-nextjs\");\n } else if (frontend.includes(\"nuxt\")) {\n deps.push(\"@t3-oss/env-nuxt\");\n } else {\n deps.push(\"@t3-oss/env-core\");\n }\n\n const needsServerEnv = backend !== \"convex\" && backend !== \"none\" && runtime !== \"workers\";\n if (needsServerEnv && !deps.includes(\"@t3-oss/env-core\")) {\n deps.push(\"@t3-oss/env-core\");\n }\n\n addPackageDependency({ vfs, packagePath: envPath, dependencies: deps });\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nexport interface EnvVariable {\n key: string;\n value: string | null | undefined;\n condition: boolean;\n comment?: string;\n}\n\nfunction generateRandomString(length: number, charset: string) {\n let result = \"\";\n if (\n typeof globalThis.crypto !== \"undefined\" &&\n typeof globalThis.crypto.getRandomValues === \"function\"\n ) {\n const values = new Uint8Array(length);\n globalThis.crypto.getRandomValues(values);\n for (let i = 0; i < length; i++) {\n const value = values[i];\n if (value !== undefined) {\n result += charset[value % charset.length];\n }\n }\n return result;\n } else {\n // Fallback for environments without crypto\n for (let i = 0; i < length; i++) {\n result += charset[Math.floor(Math.random() * charset.length)];\n }\n return result;\n }\n}\n\nfunction generateAuthSecret() {\n return generateRandomString(32, \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\");\n}\n\nfunction getClientServerVar(frontend: string[], backend: ProjectConfig[\"backend\"]) {\n const hasNextJs = frontend.includes(\"next\");\n const hasNuxt = frontend.includes(\"nuxt\");\n const hasSvelte = frontend.includes(\"svelte\");\n const hasTanstackStart = frontend.includes(\"tanstack-start\");\n\n // For fullstack self, no base URL is needed (same-origin)\n if (backend === \"self\") {\n return { key: \"\", value: \"\", write: false } as const;\n }\n\n let key = \"VITE_SERVER_URL\";\n if (hasNextJs) key = \"NEXT_PUBLIC_SERVER_URL\";\n else if (hasNuxt) key = \"NUXT_PUBLIC_SERVER_URL\";\n else if (hasSvelte) key = \"PUBLIC_SERVER_URL\";\n else if (hasTanstackStart) key = \"VITE_SERVER_URL\";\n\n return { key, value: \"http://localhost:3000\", write: true } as const;\n}\n\nfunction getConvexVar(frontend: string[]) {\n const hasNextJs = frontend.includes(\"next\");\n const hasNuxt = frontend.includes(\"nuxt\");\n const hasSvelte = frontend.includes(\"svelte\");\n const hasTanstackStart = frontend.includes(\"tanstack-start\");\n if (hasNextJs) return \"NEXT_PUBLIC_CONVEX_URL\";\n if (hasNuxt) return \"NUXT_PUBLIC_CONVEX_URL\";\n if (hasSvelte) return \"PUBLIC_CONVEX_URL\";\n if (hasTanstackStart) return \"VITE_CONVEX_URL\";\n return \"VITE_CONVEX_URL\";\n}\n\nfunction addEnvVariablesToContent(currentContent: string, variables: EnvVariable[]): string {\n let envContent = currentContent || \"\";\n let contentToAdd = \"\";\n\n for (const { key, value, condition, comment } of variables) {\n if (condition) {\n const regex = new RegExp(`^${key}=.*$`, \"m\");\n const valueToWrite = value ?? \"\";\n\n if (regex.test(envContent)) {\n const existingMatch = envContent.match(regex);\n if (existingMatch && existingMatch[0] !== `${key}=${valueToWrite}`) {\n envContent = envContent.replace(regex, `${key}=${valueToWrite}`);\n }\n } else {\n if (comment) {\n contentToAdd += `# ${comment}\\n`;\n }\n contentToAdd += `${key}=${valueToWrite}\\n`;\n }\n }\n }\n\n if (contentToAdd) {\n if (envContent.length > 0 && !envContent.endsWith(\"\\n\")) {\n envContent += \"\\n\";\n }\n envContent += contentToAdd;\n }\n\n return envContent.trimEnd();\n}\n\nfunction writeEnvFile(vfs: VirtualFileSystem, envPath: string, variables: EnvVariable[]): void {\n let currentContent = \"\";\n if (vfs.exists(envPath)) {\n currentContent = vfs.readFile(envPath) || \"\";\n }\n const newContent = addEnvVariablesToContent(currentContent, variables);\n vfs.writeFile(envPath, newContent);\n}\n\nfunction buildClientVars(\n frontend: string[],\n backend: ProjectConfig[\"backend\"],\n auth: ProjectConfig[\"auth\"],\n payments: ProjectConfig[\"payments\"],\n): EnvVariable[] {\n const hasNextJs = frontend.includes(\"next\");\n const hasReactRouter = frontend.includes(\"react-router\");\n const hasTanStackRouter = frontend.includes(\"tanstack-router\");\n const hasTanStackStart = frontend.includes(\"tanstack-start\");\n const hasNuxt = frontend.includes(\"nuxt\");\n const hasSvelte = frontend.includes(\"svelte\");\n\n const baseVar = getClientServerVar(frontend, backend);\n const envVarName = backend === \"convex\" ? getConvexVar(frontend) : baseVar.key;\n const serverUrl = backend === \"convex\" ? \"https://<YOUR_CONVEX_URL>\" : baseVar.value;\n\n const vars: EnvVariable[] = [\n {\n key: envVarName,\n value: serverUrl,\n condition: backend === \"convex\" ? true : baseVar.write,\n },\n ];\n\n if (backend === \"convex\" && auth === \"clerk\") {\n if (hasNextJs) {\n vars.push(\n {\n key: \"NEXT_PUBLIC_CLERK_FRONTEND_API_URL\",\n value: \"\",\n condition: true,\n },\n {\n key: \"NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY\",\n value: \"\",\n condition: true,\n },\n {\n key: \"CLERK_SECRET_KEY\",\n value: \"\",\n condition: true,\n },\n );\n } else if (hasReactRouter || hasTanStackRouter || hasTanStackStart) {\n vars.push({\n key: \"VITE_CLERK_PUBLISHABLE_KEY\",\n value: \"\",\n condition: true,\n });\n if (hasTanStackStart) {\n vars.push({\n key: \"CLERK_SECRET_KEY\",\n value: \"\",\n condition: true,\n });\n }\n }\n }\n\n if (backend === \"convex\" && auth === \"better-auth\") {\n if (hasNextJs) {\n vars.push({\n key: \"NEXT_PUBLIC_CONVEX_SITE_URL\",\n value: \"https://<YOUR_CONVEX_URL>\",\n condition: true,\n });\n } else if (hasReactRouter || hasTanStackRouter || hasTanStackStart) {\n vars.push({\n key: \"VITE_CONVEX_SITE_URL\",\n value: \"https://<YOUR_CONVEX_URL>\",\n condition: true,\n });\n }\n }\n\n // Stripe publishable key for client-side\n if (payments === \"stripe\") {\n let stripeKeyName = \"VITE_STRIPE_PUBLISHABLE_KEY\";\n if (hasNextJs) stripeKeyName = \"NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY\";\n else if (hasNuxt) stripeKeyName = \"NUXT_PUBLIC_STRIPE_PUBLISHABLE_KEY\";\n else if (hasSvelte) stripeKeyName = \"PUBLIC_STRIPE_PUBLISHABLE_KEY\";\n\n vars.push({\n key: stripeKeyName,\n value: \"\",\n condition: true,\n comment: \"Stripe publishable key - get it at https://dashboard.stripe.com/apikeys\",\n });\n }\n\n // Paddle client token for client-side\n if (payments === \"paddle\") {\n let paddleTokenName = \"VITE_PADDLE_CLIENT_TOKEN\";\n if (hasNextJs) paddleTokenName = \"NEXT_PUBLIC_PADDLE_CLIENT_TOKEN\";\n else if (hasNuxt) paddleTokenName = \"NUXT_PUBLIC_PADDLE_CLIENT_TOKEN\";\n else if (hasSvelte) paddleTokenName = \"PUBLIC_PADDLE_CLIENT_TOKEN\";\n\n vars.push(\n {\n key: paddleTokenName,\n value: \"\",\n condition: true,\n comment: \"Paddle client-side token - get it at Paddle > Developer Tools > Authentication\",\n },\n {\n key: hasNextJs\n ? \"NEXT_PUBLIC_PADDLE_ENVIRONMENT\"\n : hasNuxt\n ? \"NUXT_PUBLIC_PADDLE_ENVIRONMENT\"\n : hasSvelte\n ? \"PUBLIC_PADDLE_ENVIRONMENT\"\n : \"VITE_PADDLE_ENVIRONMENT\",\n value: \"sandbox\",\n condition: true,\n comment: \"Paddle environment - use 'sandbox' for testing, 'production' for live\",\n },\n );\n }\n\n // Dodo Payments environment for client-side\n if (payments === \"dodo\") {\n vars.push({\n key: hasNextJs\n ? \"NEXT_PUBLIC_DODO_ENVIRONMENT\"\n : hasNuxt\n ? \"NUXT_PUBLIC_DODO_ENVIRONMENT\"\n : hasSvelte\n ? \"PUBLIC_DODO_ENVIRONMENT\"\n : \"VITE_DODO_ENVIRONMENT\",\n value: \"test_mode\",\n condition: true,\n comment:\n \"Dodo Payments environment - use 'test_mode' for testing, 'live_mode' for production\",\n });\n }\n\n return vars;\n}\n\nfunction buildNativeVars(\n frontend: string[],\n backend: ProjectConfig[\"backend\"],\n auth: ProjectConfig[\"auth\"],\n): EnvVariable[] {\n let envVarName = \"EXPO_PUBLIC_SERVER_URL\";\n let serverUrl = \"http://localhost:3000\";\n\n if (backend === \"self\") {\n // Both TanStack Start and Next.js use port 3001 for fullstack\n serverUrl = \"http://localhost:3001\";\n }\n\n if (backend === \"convex\") {\n envVarName = \"EXPO_PUBLIC_CONVEX_URL\";\n serverUrl = \"https://<YOUR_CONVEX_URL>\";\n }\n\n const vars: EnvVariable[] = [\n {\n key: envVarName,\n value: serverUrl,\n condition: true,\n },\n ];\n\n if (backend === \"convex\" && auth === \"clerk\") {\n vars.push({\n key: \"EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY\",\n value: \"\",\n condition: true,\n });\n }\n\n if (backend === \"convex\" && auth === \"better-auth\") {\n vars.push({\n key: \"EXPO_PUBLIC_CONVEX_SITE_URL\",\n value: \"https://<YOUR_CONVEX_URL>\",\n condition: true,\n });\n }\n\n return vars;\n}\n\nfunction buildConvexBackendVars(\n frontend: string[],\n auth: ProjectConfig[\"auth\"],\n examples: ProjectConfig[\"examples\"],\n): EnvVariable[] {\n const hasNextJs = frontend.includes(\"next\");\n const hasNative =\n frontend.includes(\"native-bare\") ||\n frontend.includes(\"native-uniwind\") ||\n frontend.includes(\"native-unistyles\");\n const hasWeb =\n frontend.includes(\"react-router\") ||\n frontend.includes(\"tanstack-router\") ||\n frontend.includes(\"tanstack-start\") ||\n hasNextJs ||\n frontend.includes(\"nuxt\") ||\n frontend.includes(\"solid\") ||\n frontend.includes(\"svelte\");\n\n const vars: EnvVariable[] = [];\n\n if (examples?.includes(\"ai\")) {\n vars.push({\n key: \"GOOGLE_GENERATIVE_AI_API_KEY\",\n value: \"\",\n condition: true,\n comment: \"Google AI API key for AI agent\",\n });\n }\n\n if (auth === \"better-auth\") {\n if (hasNative) {\n vars.push({\n key: \"EXPO_PUBLIC_CONVEX_SITE_URL\",\n value: \"\",\n condition: true,\n comment: \"Same as CONVEX_URL but ends in .site\",\n });\n }\n\n if (hasWeb) {\n vars.push(\n {\n key: hasNextJs ? \"NEXT_PUBLIC_CONVEX_SITE_URL\" : \"VITE_CONVEX_SITE_URL\",\n value: \"\",\n condition: true,\n comment: \"Same as CONVEX_URL but ends in .site\",\n },\n {\n key: \"SITE_URL\",\n value: \"http://localhost:3001\",\n condition: true,\n comment: \"Web app URL for authentication\",\n },\n );\n }\n }\n\n return vars;\n}\n\nfunction buildConvexCommentBlocks(\n frontend: string[],\n auth: ProjectConfig[\"auth\"],\n examples: ProjectConfig[\"examples\"],\n): string {\n const hasWeb =\n frontend.includes(\"react-router\") ||\n frontend.includes(\"tanstack-router\") ||\n frontend.includes(\"tanstack-start\") ||\n frontend.includes(\"next\") ||\n frontend.includes(\"nuxt\") ||\n frontend.includes(\"solid\") ||\n frontend.includes(\"svelte\");\n\n let commentBlocks = \"\";\n\n if (examples?.includes(\"ai\")) {\n commentBlocks += `# Set Google AI API key for AI agent\n# npx convex env set GOOGLE_GENERATIVE_AI_API_KEY=your_google_api_key\n\n`;\n }\n\n if (auth === \"better-auth\") {\n commentBlocks += `# Set Convex environment variables\n# npx convex env set BETTER_AUTH_SECRET=$(openssl rand -base64 32)\n${hasWeb ? \"# npx convex env set SITE_URL http://localhost:3001\\n\" : \"\"}`;\n }\n\n return commentBlocks;\n}\n\nfunction buildServerVars(\n backend: ProjectConfig[\"backend\"],\n frontend: string[],\n auth: ProjectConfig[\"auth\"],\n database: ProjectConfig[\"database\"],\n dbSetup: ProjectConfig[\"dbSetup\"],\n runtime: ProjectConfig[\"runtime\"],\n webDeploy: ProjectConfig[\"webDeploy\"],\n serverDeploy: ProjectConfig[\"serverDeploy\"],\n payments: ProjectConfig[\"payments\"],\n email: ProjectConfig[\"email\"],\n examples: ProjectConfig[\"examples\"],\n fileUpload: ProjectConfig[\"fileUpload\"],\n logging: ProjectConfig[\"logging\"],\n observability: ProjectConfig[\"observability\"],\n jobQueue: ProjectConfig[\"jobQueue\"],\n caching: ProjectConfig[\"caching\"],\n): EnvVariable[] {\n const hasReactRouter = frontend.includes(\"react-router\");\n const hasSvelte = frontend.includes(\"svelte\");\n\n let corsOrigin = \"http://localhost:3001\";\n if (backend === \"self\") {\n corsOrigin = \"http://localhost:3001\";\n } else if (hasReactRouter || hasSvelte) {\n corsOrigin = \"http://localhost:5173\";\n }\n\n let databaseUrl: string | null = null;\n if (database !== \"none\" && dbSetup === \"none\") {\n switch (database) {\n case \"postgres\":\n databaseUrl = \"postgresql://postgres:password@localhost:5432/postgres\";\n break;\n case \"mysql\":\n databaseUrl = \"mysql://root:password@localhost:3306/mydb\";\n break;\n case \"mongodb\":\n databaseUrl = \"mongodb://localhost:27017/mydatabase\";\n break;\n case \"sqlite\":\n if (runtime === \"workers\" || webDeploy === \"cloudflare\" || serverDeploy === \"cloudflare\") {\n databaseUrl = \"http://127.0.0.1:8080\";\n } else {\n databaseUrl = \"file:../../local.db\";\n }\n break;\n }\n }\n\n return [\n {\n key: \"BETTER_AUTH_SECRET\",\n value: generateAuthSecret(),\n condition: auth === \"better-auth\",\n },\n {\n key: \"BETTER_AUTH_URL\",\n value: backend === \"self\" ? \"http://localhost:3001\" : \"http://localhost:3000\",\n condition: auth === \"better-auth\",\n },\n {\n key: \"AUTH_SECRET\",\n value: generateAuthSecret(),\n condition: auth === \"nextauth\",\n comment: \"NextAuth.js secret - generate with: openssl rand -base64 32\",\n },\n {\n key: \"AUTH_TRUST_HOST\",\n value: \"true\",\n condition: auth === \"nextauth\",\n comment: \"Trust the host header for NextAuth\",\n },\n {\n key: \"AUTH_GITHUB_ID\",\n value: \"\",\n condition: auth === \"nextauth\",\n comment: \"GitHub OAuth App Client ID (optional)\",\n },\n {\n key: \"AUTH_GITHUB_SECRET\",\n value: \"\",\n condition: auth === \"nextauth\",\n comment: \"GitHub OAuth App Client Secret (optional)\",\n },\n {\n key: \"AUTH_GOOGLE_ID\",\n value: \"\",\n condition: auth === \"nextauth\",\n comment: \"Google OAuth Client ID (optional)\",\n },\n {\n key: \"AUTH_GOOGLE_SECRET\",\n value: \"\",\n condition: auth === \"nextauth\",\n comment: \"Google OAuth Client Secret (optional)\",\n },\n {\n key: \"POLAR_ACCESS_TOKEN\",\n value: \"\",\n condition: payments === \"polar\",\n },\n {\n key: \"POLAR_SUCCESS_URL\",\n value: `${corsOrigin}/success?checkout_id={CHECKOUT_ID}`,\n condition: payments === \"polar\",\n },\n {\n key: \"STRIPE_SECRET_KEY\",\n value: \"\",\n condition: payments === \"stripe\",\n comment: \"Stripe secret key - get it at https://dashboard.stripe.com/apikeys\",\n },\n {\n key: \"STRIPE_WEBHOOK_SECRET\",\n value: \"\",\n condition: payments === \"stripe\",\n comment: \"Stripe webhook signing secret - get it when creating a webhook endpoint\",\n },\n {\n key: \"LEMONSQUEEZY_API_KEY\",\n value: \"\",\n condition: payments === \"lemon-squeezy\",\n comment: \"Lemon Squeezy API key - get it at Settings > API in your dashboard\",\n },\n {\n key: \"LEMONSQUEEZY_STORE_ID\",\n value: \"\",\n condition: payments === \"lemon-squeezy\",\n comment: \"Lemon Squeezy Store ID - found in your store settings\",\n },\n {\n key: \"LEMONSQUEEZY_WEBHOOK_SECRET\",\n value: \"\",\n condition: payments === \"lemon-squeezy\",\n comment: \"Lemon Squeezy webhook signing secret - get it when creating a webhook\",\n },\n {\n key: \"PADDLE_API_KEY\",\n value: \"\",\n condition: payments === \"paddle\",\n comment: \"Paddle API key - get it at Paddle > Developer Tools > Authentication\",\n },\n {\n key: \"PADDLE_WEBHOOK_SECRET\",\n value: \"\",\n condition: payments === \"paddle\",\n comment: \"Paddle webhook secret key - get it when creating a notification destination\",\n },\n {\n key: \"PADDLE_ENVIRONMENT\",\n value: \"sandbox\",\n condition: payments === \"paddle\",\n comment: \"Paddle environment - use 'sandbox' for testing, 'production' for live\",\n },\n {\n key: \"DODO_PAYMENTS_API_KEY\",\n value: \"\",\n condition: payments === \"dodo\",\n comment: \"Dodo Payments API key - get it at https://dashboard.dodopayments.com\",\n },\n {\n key: \"DODO_PAYMENTS_WEBHOOK_SECRET\",\n value: \"\",\n condition: payments === \"dodo\",\n comment: \"Dodo Payments webhook secret - get it when creating a webhook endpoint\",\n },\n {\n key: \"DODO_PAYMENTS_ENVIRONMENT\",\n value: \"test_mode\",\n condition: payments === \"dodo\",\n comment:\n \"Dodo Payments environment - use 'test_mode' for testing, 'live_mode' for production\",\n },\n {\n key: \"RESEND_API_KEY\",\n value: \"\",\n condition: email === \"resend\",\n comment: \"Resend API key - get it at https://resend.com\",\n },\n {\n key: \"RESEND_FROM_EMAIL\",\n value: \"onboarding@resend.dev\",\n condition: email === \"resend\",\n comment: \"Email address to send from (must be verified in Resend)\",\n },\n {\n key: \"SMTP_HOST\",\n value: \"smtp.ethereal.email\",\n condition: email === \"nodemailer\",\n comment: \"SMTP server host - use smtp.ethereal.email for testing\",\n },\n {\n key: \"SMTP_PORT\",\n value: \"587\",\n condition: email === \"nodemailer\",\n comment: \"SMTP server port (587 for TLS, 465 for SSL)\",\n },\n {\n key: \"SMTP_SECURE\",\n value: \"false\",\n condition: email === \"nodemailer\",\n comment: \"Use SSL/TLS (true for port 465, false for 587)\",\n },\n {\n key: \"SMTP_USER\",\n value: \"\",\n condition: email === \"nodemailer\",\n comment: \"SMTP username/email\",\n },\n {\n key: \"SMTP_PASS\",\n value: \"\",\n condition: email === \"nodemailer\",\n comment: \"SMTP password or app-specific password\",\n },\n {\n key: \"SMTP_FROM_EMAIL\",\n value: \"noreply@example.com\",\n condition: email === \"nodemailer\",\n comment: \"Default from email address\",\n },\n {\n key: \"POSTMARK_SERVER_TOKEN\",\n value: \"\",\n condition: email === \"postmark\",\n comment: \"Postmark Server API Token - get it at https://postmarkapp.com\",\n },\n {\n key: \"POSTMARK_FROM_EMAIL\",\n value: \"noreply@example.com\",\n condition: email === \"postmark\",\n comment: \"Email address to send from (must have verified sender signature in Postmark)\",\n },\n {\n key: \"SENDGRID_API_KEY\",\n value: \"\",\n condition: email === \"sendgrid\",\n comment:\n \"SendGrid API key - get it at https://sendgrid.com/docs/ui/account-and-settings/api-keys/\",\n },\n {\n key: \"SENDGRID_FROM_EMAIL\",\n value: \"noreply@example.com\",\n condition: email === \"sendgrid\",\n comment: \"Email address to send from (must be verified in SendGrid)\",\n },\n {\n key: \"AWS_REGION\",\n value: \"us-east-1\",\n condition: email === \"aws-ses\",\n comment: \"AWS region for SES (e.g., us-east-1, eu-west-1)\",\n },\n {\n key: \"AWS_ACCESS_KEY_ID\",\n value: \"\",\n condition: email === \"aws-ses\",\n comment: \"AWS access key ID - get it at https://console.aws.amazon.com/iam\",\n },\n {\n key: \"AWS_SECRET_ACCESS_KEY\",\n value: \"\",\n condition: email === \"aws-ses\",\n comment: \"AWS secret access key\",\n },\n {\n key: \"AWS_SES_FROM_EMAIL\",\n value: \"noreply@example.com\",\n condition: email === \"aws-ses\",\n comment: \"Email address to send from (must be verified in AWS SES)\",\n },\n {\n key: \"MAILGUN_API_KEY\",\n value: \"\",\n condition: email === \"mailgun\",\n comment: \"Mailgun API key - get it at https://app.mailgun.com/app/account/security/api_keys\",\n },\n {\n key: \"MAILGUN_DOMAIN\",\n value: \"\",\n condition: email === \"mailgun\",\n comment: \"Mailgun sending domain (e.g., mg.yourdomain.com)\",\n },\n {\n key: \"MAILGUN_FROM_EMAIL\",\n value: \"noreply@example.com\",\n condition: email === \"mailgun\",\n comment: \"Email address to send from (must be authorized in Mailgun)\",\n },\n {\n key: \"PLUNK_API_KEY\",\n value: \"\",\n condition: email === \"plunk\",\n comment: \"Plunk secret API key - get it at https://app.useplunk.com\",\n },\n {\n key: \"PLUNK_FROM_EMAIL\",\n value: \"noreply@example.com\",\n condition: email === \"plunk\",\n comment: \"Email address to send from\",\n },\n {\n key: \"UPLOADTHING_TOKEN\",\n value: \"\",\n condition: fileUpload === \"uploadthing\",\n comment: \"UploadThing token - get it at https://uploadthing.com/dashboard\",\n },\n {\n key: \"CORS_ORIGIN\",\n value: corsOrigin,\n condition: true,\n },\n {\n key: \"GOOGLE_GENERATIVE_AI_API_KEY\",\n value: \"\",\n condition: examples?.includes(\"ai\") || false,\n },\n {\n key: \"DATABASE_URL\",\n value: databaseUrl,\n condition: database !== \"none\" && dbSetup === \"none\",\n },\n {\n key: \"LOG_LEVEL\",\n value: \"info\",\n condition: logging === \"pino\",\n comment: \"Pino log level - trace, debug, info, warn, error, or fatal\",\n },\n {\n key: \"OTEL_SERVICE_NAME\",\n value: \"\",\n condition: observability === \"opentelemetry\",\n comment: \"OpenTelemetry service name (defaults to project name if not set)\",\n },\n {\n key: \"OTEL_EXPORTER_OTLP_ENDPOINT\",\n value: \"http://localhost:4318\",\n condition: observability === \"opentelemetry\",\n comment: \"OTLP exporter endpoint (Jaeger, OTEL Collector, Tempo, etc.)\",\n },\n {\n key: \"REDIS_HOST\",\n value: \"localhost\",\n condition: jobQueue === \"bullmq\",\n comment: \"Redis host for BullMQ job queue\",\n },\n {\n key: \"REDIS_PORT\",\n value: \"6379\",\n condition: jobQueue === \"bullmq\",\n comment: \"Redis port for BullMQ job queue\",\n },\n {\n key: \"REDIS_PASSWORD\",\n value: \"\",\n condition: jobQueue === \"bullmq\",\n comment: \"Redis password (optional, leave empty for local development)\",\n },\n {\n key: \"TRIGGER_SECRET_KEY\",\n value: \"\",\n condition: jobQueue === \"trigger-dev\",\n comment: \"Trigger.dev secret key (from dashboard.trigger.dev)\",\n },\n {\n key: \"TRIGGER_PROJECT_ID\",\n value: \"\",\n condition: jobQueue === \"trigger-dev\",\n comment: \"Trigger.dev project ID (e.g., proj_xxxxxxxxxxxx)\",\n },\n {\n key: \"INNGEST_EVENT_KEY\",\n value: \"\",\n condition: jobQueue === \"inngest\",\n comment: \"Inngest Event Key (from app.inngest.com)\",\n },\n {\n key: \"INNGEST_SIGNING_KEY\",\n value: \"\",\n condition: jobQueue === \"inngest\",\n comment: \"Inngest Signing Key for webhook verification\",\n },\n {\n key: \"TEMPORAL_ADDRESS\",\n value: \"localhost:7233\",\n condition: jobQueue === \"temporal\",\n comment: \"Temporal server address (default: localhost:7233)\",\n },\n {\n key: \"TEMPORAL_NAMESPACE\",\n value: \"default\",\n condition: jobQueue === \"temporal\",\n comment: \"Temporal namespace (default: 'default')\",\n },\n {\n key: \"TEMPORAL_TASK_QUEUE\",\n value: \"\",\n condition: jobQueue === \"temporal\",\n comment: \"Temporal task queue name (defaults to project name if not set)\",\n },\n {\n key: \"UPSTASH_REDIS_REST_URL\",\n value: \"\",\n condition: caching === \"upstash-redis\",\n comment: \"Upstash Redis REST URL - get it at https://console.upstash.com\",\n },\n {\n key: \"UPSTASH_REDIS_REST_TOKEN\",\n value: \"\",\n condition: caching === \"upstash-redis\",\n comment: \"Upstash Redis REST token - get it at https://console.upstash.com\",\n },\n ];\n}\n\nfunction buildCMSVars(cms: ProjectConfig[\"cms\"]): EnvVariable[] {\n const vars: EnvVariable[] = [];\n\n if (cms === \"payload\") {\n vars.push({\n key: \"PAYLOAD_SECRET\",\n value: generateRandomString(\n 32,\n \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\",\n ),\n condition: true,\n comment: \"Payload CMS secret - used for encryption\",\n });\n }\n\n if (cms === \"sanity\") {\n vars.push(\n {\n key: \"NEXT_PUBLIC_SANITY_PROJECT_ID\",\n value: \"your-project-id\",\n condition: true,\n comment: \"Sanity project ID - get from sanity.io/manage\",\n },\n {\n key: \"NEXT_PUBLIC_SANITY_DATASET\",\n value: \"production\",\n condition: true,\n comment: \"Sanity dataset name\",\n },\n {\n key: \"NEXT_PUBLIC_SANITY_API_VERSION\",\n value: new Date().toISOString().split(\"T\")[0],\n condition: true,\n comment: \"Sanity API version (YYYY-MM-DD format)\",\n },\n {\n key: \"SANITY_API_READ_TOKEN\",\n value: \"\",\n condition: true,\n comment: \"Sanity API read token for server-side operations (optional)\",\n },\n );\n }\n\n return vars;\n}\n\nexport function processEnvVariables(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const {\n backend,\n frontend,\n database,\n auth,\n email,\n examples,\n dbSetup,\n webDeploy,\n serverDeploy,\n runtime,\n payments,\n fileUpload,\n logging,\n observability,\n } = config;\n\n const hasReactRouter = frontend.includes(\"react-router\");\n const hasTanStackRouter = frontend.includes(\"tanstack-router\");\n const hasTanStackStart = frontend.includes(\"tanstack-start\");\n const hasNextJs = frontend.includes(\"next\");\n const hasNuxt = frontend.includes(\"nuxt\");\n const hasSvelte = frontend.includes(\"svelte\");\n const hasSolid = frontend.includes(\"solid\");\n const hasWebFrontend =\n hasReactRouter ||\n hasTanStackRouter ||\n hasTanStackStart ||\n hasNextJs ||\n hasNuxt ||\n hasSolid ||\n hasSvelte;\n\n // --- Client App .env ---\n if (hasWebFrontend) {\n const clientDir = \"apps/web\";\n if (vfs.directoryExists(clientDir)) {\n const envPath = `${clientDir}/.env`;\n const clientVars = buildClientVars(frontend, backend, auth, payments);\n writeEnvFile(vfs, envPath, clientVars);\n }\n }\n\n // --- Native App .env ---\n if (\n frontend.includes(\"native-bare\") ||\n frontend.includes(\"native-uniwind\") ||\n frontend.includes(\"native-unistyles\")\n ) {\n const nativeDir = \"apps/native\";\n if (vfs.directoryExists(nativeDir)) {\n const envPath = `${nativeDir}/.env`;\n const nativeVars = buildNativeVars(frontend, backend, auth);\n writeEnvFile(vfs, envPath, nativeVars);\n }\n }\n\n // --- Convex Backend .env.local ---\n if (backend === \"convex\") {\n const convexBackendDir = \"packages/backend\";\n if (vfs.directoryExists(convexBackendDir)) {\n const envLocalPath = `${convexBackendDir}/.env.local`;\n\n // Write comment blocks first\n const commentBlocks = buildConvexCommentBlocks(frontend, auth, examples);\n if (commentBlocks) {\n let currentContent = \"\";\n if (vfs.exists(envLocalPath)) {\n currentContent = vfs.readFile(envLocalPath) || \"\";\n }\n vfs.writeFile(envLocalPath, commentBlocks + currentContent);\n }\n\n // Then add variables\n const convexBackendVars = buildConvexBackendVars(frontend, auth, examples);\n if (convexBackendVars.length > 0) {\n let existingContent = \"\";\n if (vfs.exists(envLocalPath)) {\n existingContent = vfs.readFile(envLocalPath) || \"\";\n }\n const contentWithVars = addEnvVariablesToContent(existingContent, convexBackendVars);\n vfs.writeFile(envLocalPath, contentWithVars);\n }\n }\n return;\n }\n\n // --- Server App .env ---\n const serverVars = buildServerVars(\n backend,\n frontend,\n auth,\n database,\n dbSetup,\n runtime,\n webDeploy,\n serverDeploy,\n payments,\n email,\n examples,\n fileUpload,\n logging,\n observability,\n config.jobQueue,\n config.caching,\n );\n\n if (backend === \"self\") {\n const webDir = \"apps/web\";\n if (vfs.directoryExists(webDir)) {\n const envPath = `${webDir}/.env`;\n writeEnvFile(vfs, envPath, serverVars);\n }\n } else if (vfs.directoryExists(\"apps/server\")) {\n const envPath = \"apps/server/.env\";\n writeEnvFile(vfs, envPath, serverVars);\n }\n\n // --- CMS .env (Payload and Sanity require Next.js and add vars to web/.env) ---\n if ((config.cms === \"payload\" || config.cms === \"sanity\") && hasNextJs) {\n const webDir = \"apps/web\";\n if (vfs.directoryExists(webDir)) {\n const envPath = `${webDir}/.env`;\n const cmsVars = buildCMSVars(config.cms);\n writeEnvFile(vfs, envPath, cmsVars);\n }\n }\n\n // --- Alchemy Infra .env ---\n const isUnifiedAlchemy = webDeploy === \"cloudflare\" && serverDeploy === \"cloudflare\";\n const isIndividualAlchemy = webDeploy === \"cloudflare\" || serverDeploy === \"cloudflare\";\n\n if (isUnifiedAlchemy || isIndividualAlchemy) {\n const infraDir = \"packages/infra\";\n if (vfs.directoryExists(infraDir)) {\n const envPath = `${infraDir}/.env`;\n const infraAlchemyVars: EnvVariable[] = [\n {\n key: \"ALCHEMY_PASSWORD\",\n value: \"please-change-this\",\n condition: true,\n },\n ];\n writeEnvFile(vfs, envPath, infraAlchemyVars);\n }\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\nexport function processExamplesDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n if (!config.examples || config.examples.length === 0 || config.examples[0] === \"none\") return;\n\n if (\n config.examples.includes(\"todo\") &&\n config.backend !== \"convex\" &&\n config.backend !== \"none\"\n ) {\n setupTodoDependencies(vfs, config);\n }\n\n if (config.examples.includes(\"ai\")) {\n setupAIDependencies(vfs, config);\n }\n}\n\nfunction setupTodoDependencies(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { orm, database, backend } = config;\n const apiPkgPath = \"packages/api/package.json\";\n if (!vfs.exists(apiPkgPath) || backend === \"none\") return;\n\n if (orm === \"drizzle\") {\n const deps: AvailableDependencies[] = [\"drizzle-orm\"];\n if (database === \"postgres\") deps.push(\"@types/pg\");\n addPackageDependency({ vfs, packagePath: apiPkgPath, dependencies: deps });\n } else if (orm === \"prisma\") {\n addPackageDependency({ vfs, packagePath: apiPkgPath, dependencies: [\"@prisma/client\"] });\n } else if (orm === \"mongoose\") {\n addPackageDependency({ vfs, packagePath: apiPkgPath, dependencies: [\"mongoose\"] });\n } else if (orm === \"typeorm\") {\n addPackageDependency({ vfs, packagePath: apiPkgPath, dependencies: [\"typeorm\"] });\n } else if (orm === \"kysely\") {\n addPackageDependency({ vfs, packagePath: apiPkgPath, dependencies: [\"kysely\"] });\n } else if (orm === \"mikroorm\") {\n addPackageDependency({ vfs, packagePath: apiPkgPath, dependencies: [\"@mikro-orm/core\"] });\n } else if (orm === \"sequelize\") {\n addPackageDependency({ vfs, packagePath: apiPkgPath, dependencies: [\"sequelize\"] });\n }\n}\n\nfunction setupAIDependencies(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { frontend, backend, ai } = config;\n\n const webPkgPath = \"apps/web/package.json\";\n const nativePkgPath = \"apps/native/package.json\";\n const serverPkgPath = \"apps/server/package.json\";\n const convexBackendPkgPath = \"packages/backend/package.json\";\n\n const webExists = vfs.exists(webPkgPath);\n const nativeExists = vfs.exists(nativePkgPath);\n const serverExists = vfs.exists(serverPkgPath);\n const convexBackendExists = vfs.exists(convexBackendPkgPath);\n\n const hasReactWeb = frontend.some((f) =>\n [\"react-router\", \"tanstack-router\", \"next\", \"tanstack-start\"].includes(f),\n );\n const hasNuxt = frontend.includes(\"nuxt\");\n const hasSvelte = frontend.includes(\"svelte\");\n const hasReactNative = frontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n\n // Check which AI SDK is selected\n const useMastra = ai === \"mastra\";\n const useVoltAgent = ai === \"voltagent\";\n const useLangGraph = ai === \"langgraph\";\n const useOpenAIAgents = ai === \"openai-agents\";\n const useGoogleADK = ai === \"google-adk\";\n const useModelFusion = ai === \"modelfusion\";\n\n if (backend === \"convex\" && convexBackendExists) {\n addPackageDependency({\n vfs,\n packagePath: convexBackendPkgPath,\n dependencies: [\"@convex-dev/agent\"],\n customDependencies: { ai: \"^5.0.117\", \"@ai-sdk/google\": \"^2.0.52\" },\n });\n } else if (backend === \"self\" && webExists) {\n if (useMastra) {\n addPackageDependency({\n vfs,\n packagePath: webPkgPath,\n dependencies: [\"mastra\", \"@mastra/core\"],\n });\n } else if (useVoltAgent) {\n addPackageDependency({\n vfs,\n packagePath: webPkgPath,\n dependencies: [\"@voltagent/core\", \"@voltagent/server-hono\", \"@voltagent/libsql\"],\n customDependencies: { ai: \"^6.0.0\", \"@ai-sdk/google\": \"^3.0.1\", zod: \"^3.25.76\" },\n });\n } else if (useLangGraph) {\n addPackageDependency({\n vfs,\n packagePath: webPkgPath,\n dependencies: [\"@langchain/langgraph\", \"@langchain/core\", \"@langchain/google-genai\"],\n });\n } else if (useOpenAIAgents) {\n addPackageDependency({\n vfs,\n packagePath: webPkgPath,\n dependencies: [\"@openai/agents\"],\n customDependencies: { zod: \"^3.25.67\" },\n });\n } else if (useGoogleADK) {\n addPackageDependency({\n vfs,\n packagePath: webPkgPath,\n dependencies: [\"@google/adk\"],\n customDependencies: { zod: \"^3.25.67\" },\n });\n } else if (useModelFusion) {\n addPackageDependency({\n vfs,\n packagePath: webPkgPath,\n dependencies: [\"modelfusion\"],\n });\n } else {\n addPackageDependency({\n vfs,\n packagePath: webPkgPath,\n dependencies: [\"ai\", \"@ai-sdk/google\", \"@ai-sdk/devtools\"],\n });\n }\n } else if (serverExists && backend !== \"none\") {\n if (useMastra) {\n addPackageDependency({\n vfs,\n packagePath: serverPkgPath,\n dependencies: [\"mastra\", \"@mastra/core\"],\n });\n } else if (useVoltAgent) {\n addPackageDependency({\n vfs,\n packagePath: serverPkgPath,\n dependencies: [\"@voltagent/core\", \"@voltagent/server-hono\", \"@voltagent/libsql\"],\n customDependencies: { ai: \"^6.0.0\", \"@ai-sdk/google\": \"^3.0.1\", zod: \"^3.25.76\" },\n });\n } else if (useLangGraph) {\n addPackageDependency({\n vfs,\n packagePath: serverPkgPath,\n dependencies: [\"@langchain/langgraph\", \"@langchain/core\", \"@langchain/google-genai\"],\n });\n } else if (useOpenAIAgents) {\n addPackageDependency({\n vfs,\n packagePath: serverPkgPath,\n dependencies: [\"@openai/agents\"],\n customDependencies: { zod: \"^3.25.67\" },\n });\n } else if (useGoogleADK) {\n addPackageDependency({\n vfs,\n packagePath: serverPkgPath,\n dependencies: [\"@google/adk\"],\n customDependencies: { zod: \"^3.25.67\" },\n });\n } else if (useModelFusion) {\n addPackageDependency({\n vfs,\n packagePath: serverPkgPath,\n dependencies: [\"modelfusion\"],\n });\n } else {\n addPackageDependency({\n vfs,\n packagePath: serverPkgPath,\n dependencies: [\"ai\", \"@ai-sdk/google\", \"@ai-sdk/devtools\"],\n });\n }\n }\n\n if (webExists) {\n const deps: AvailableDependencies[] = [];\n if (backend === \"convex\") {\n if (hasReactWeb) deps.push(\"@convex-dev/agent\", \"streamdown\");\n } else if (useMastra) {\n // Mastra uses @ai-sdk/react for frontend integration\n if (hasReactWeb) deps.push(\"@ai-sdk/react\", \"streamdown\");\n } else if (useVoltAgent) {\n // VoltAgent uses @ai-sdk/react for frontend integration (built on Vercel AI SDK)\n if (hasReactWeb) deps.push(\"@ai-sdk/react\", \"streamdown\");\n } else if (useLangGraph) {\n // LangGraph uses native streaming - no special frontend SDK needed\n // Just add streamdown for markdown rendering\n if (hasReactWeb) deps.push(\"streamdown\");\n } else if (useOpenAIAgents) {\n // OpenAI Agents SDK uses native streaming - no special frontend SDK needed\n // Just add streamdown for markdown rendering\n if (hasReactWeb) deps.push(\"streamdown\");\n } else if (useGoogleADK) {\n // Google ADK uses native streaming - no special frontend SDK needed\n // Just add streamdown for markdown rendering\n if (hasReactWeb) deps.push(\"streamdown\");\n } else if (useModelFusion) {\n // ModelFusion uses native streaming - no special frontend SDK needed\n // Just add streamdown for markdown rendering\n if (hasReactWeb) deps.push(\"streamdown\");\n } else {\n deps.push(\"ai\");\n if (hasNuxt) deps.push(\"@ai-sdk/vue\");\n else if (hasSvelte) deps.push(\"@ai-sdk/svelte\");\n else if (hasReactWeb) deps.push(\"@ai-sdk/react\", \"streamdown\");\n }\n if (deps.length > 0) {\n addPackageDependency({ vfs, packagePath: webPkgPath, dependencies: deps });\n }\n }\n\n if (nativeExists && hasReactNative) {\n if (backend === \"convex\") {\n addPackageDependency({\n vfs,\n packagePath: nativePkgPath,\n dependencies: [\"@convex-dev/agent\"],\n });\n } else {\n addPackageDependency({\n vfs,\n packagePath: nativePkgPath,\n dependencies: [\"ai\", \"@ai-sdk/react\"],\n });\n }\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\nconst REACT_WEB_FRONTENDS = [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"];\nconst NATIVE_FRONTENDS = [\"native-bare\", \"native-uniwind\", \"native-unistyles\"];\nconst SVELTE_FRONTENDS = [\"svelte\"];\nconst VUE_FRONTENDS = [\"nuxt\"];\nconst SOLID_FRONTENDS = [\"solid\"];\nconst ASTRO_FRONTENDS = [\"astro\"];\nconst ANGULAR_FRONTENDS = [\"angular\"];\n\n// Fullstack frameworks that have their own backend\nconst FULLSTACK_WITH_SELF_BACKEND = [\"next\", \"tanstack-start\", \"astro\", \"nuxt\", \"svelte\", \"solid\"];\n\n// Common FilePond plugins for all frameworks\nconst FILEPOND_PLUGINS: AvailableDependencies[] = [\n \"filepond\",\n \"filepond-plugin-image-preview\",\n \"filepond-plugin-file-validate-type\",\n \"filepond-plugin-file-validate-size\",\n];\n\n// Common Uppy packages for all frameworks\nconst UPPY_CORE_PACKAGES: AvailableDependencies[] = [\n \"@uppy/core\",\n \"@uppy/dashboard\",\n \"@uppy/drag-drop\",\n \"@uppy/progress-bar\",\n \"@uppy/xhr-upload\",\n \"@uppy/tus\",\n];\n\nexport function processFileUploadDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { fileUpload } = config;\n\n // Skip if not selected or set to \"none\"\n if (!fileUpload || fileUpload === \"none\") return;\n\n if (fileUpload === \"uploadthing\") {\n processUploadthingDeps(vfs, config);\n } else if (fileUpload === \"filepond\") {\n processFilepondDeps(vfs, config);\n } else if (fileUpload === \"uppy\") {\n processUppyDeps(vfs, config);\n }\n}\n\nfunction processUploadthingDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { frontend, backend, astroIntegration } = config;\n\n // Server-side SDK\n // Add to apps/server if it exists (separate backend)\n const serverPath = \"apps/server/package.json\";\n if (vfs.exists(serverPath) && backend !== \"none\" && backend !== \"convex\") {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"uploadthing\"],\n });\n }\n\n // Check for fullstack frameworks with self-backend\n const hasFullstackSelf =\n backend === \"self\" && frontend.some((f) => FULLSTACK_WITH_SELF_BACKEND.includes(f));\n\n // Client-side SDK\n const webPath = \"apps/web/package.json\";\n if (vfs.exists(webPath)) {\n const hasReactWeb = frontend.some((f) => REACT_WEB_FRONTENDS.includes(f));\n const hasSvelte = frontend.some((f) => SVELTE_FRONTENDS.includes(f));\n const hasVue = frontend.some((f) => VUE_FRONTENDS.includes(f));\n const hasSolid = frontend.some((f) => SOLID_FRONTENDS.includes(f));\n const hasAstro = frontend.some((f) => ASTRO_FRONTENDS.includes(f));\n\n // For fullstack frameworks, add both client and server SDK to web package\n const baseDeps: AvailableDependencies[] = [];\n if (hasFullstackSelf) {\n baseDeps.push(\"uploadthing\");\n }\n\n if (hasReactWeb) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...baseDeps, \"@uploadthing/react\"],\n });\n } else if (hasSvelte) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...baseDeps, \"@uploadthing/svelte\"],\n });\n } else if (hasVue) {\n // Nuxt uses the special nuxt module\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...baseDeps, \"@uploadthing/nuxt\"],\n });\n } else if (hasSolid) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...baseDeps, \"@uploadthing/solid\"],\n });\n } else if (hasAstro) {\n // Astro with React integration\n if (astroIntegration === \"react\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...baseDeps, \"@uploadthing/react\"],\n });\n } else if (astroIntegration === \"vue\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...baseDeps, \"@uploadthing/vue\"],\n });\n } else if (astroIntegration === \"svelte\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...baseDeps, \"@uploadthing/svelte\"],\n });\n } else if (astroIntegration === \"solid\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...baseDeps, \"@uploadthing/solid\"],\n });\n } else if (baseDeps.length > 0) {\n // Astro without UI integration but with self backend\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: baseDeps,\n });\n }\n }\n }\n\n // Native apps\n const hasNative = frontend.some((f) => NATIVE_FRONTENDS.includes(f));\n if (hasNative) {\n const nativePath = \"apps/native/package.json\";\n if (vfs.exists(nativePath)) {\n addPackageDependency({\n vfs,\n packagePath: nativePath,\n dependencies: [\"@uploadthing/expo\"],\n });\n }\n }\n}\n\nfunction processFilepondDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { frontend, astroIntegration } = config;\n\n const webPath = \"apps/web/package.json\";\n if (!vfs.exists(webPath)) return;\n\n const hasReactWeb = frontend.some((f) => REACT_WEB_FRONTENDS.includes(f));\n const hasSvelte = frontend.some((f) => SVELTE_FRONTENDS.includes(f));\n const hasVue = frontend.some((f) => VUE_FRONTENDS.includes(f));\n const hasAstro = frontend.some((f) => ASTRO_FRONTENDS.includes(f));\n\n // FilePond is a client-side only library (no server SDK needed)\n // Add framework-specific adapter + common plugins\n if (hasReactWeb) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...FILEPOND_PLUGINS, \"react-filepond\"],\n });\n } else if (hasSvelte) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...FILEPOND_PLUGINS, \"svelte-filepond\"],\n });\n } else if (hasVue) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...FILEPOND_PLUGINS, \"vue-filepond\"],\n });\n } else if (hasAstro) {\n // Astro with framework integration\n if (astroIntegration === \"react\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...FILEPOND_PLUGINS, \"react-filepond\"],\n });\n } else if (astroIntegration === \"vue\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...FILEPOND_PLUGINS, \"vue-filepond\"],\n });\n } else if (astroIntegration === \"svelte\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...FILEPOND_PLUGINS, \"svelte-filepond\"],\n });\n } else {\n // Astro without UI integration - add vanilla FilePond\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: FILEPOND_PLUGINS,\n });\n }\n } else {\n // For other frontends (Solid, Qwik, Angular, etc.), add vanilla FilePond\n // These can use FilePond directly via its vanilla JS API\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: FILEPOND_PLUGINS,\n });\n }\n}\n\nfunction processUppyDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { frontend, astroIntegration } = config;\n\n const webPath = \"apps/web/package.json\";\n if (!vfs.exists(webPath)) return;\n\n const hasReactWeb = frontend.some((f) => REACT_WEB_FRONTENDS.includes(f));\n const hasSvelte = frontend.some((f) => SVELTE_FRONTENDS.includes(f));\n const hasVue = frontend.some((f) => VUE_FRONTENDS.includes(f));\n const hasAngular = frontend.some((f) => ANGULAR_FRONTENDS.includes(f));\n const hasAstro = frontend.some((f) => ASTRO_FRONTENDS.includes(f));\n\n // Uppy is a client-side only library (no server SDK needed)\n // Add framework-specific adapter + core packages\n if (hasReactWeb) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...UPPY_CORE_PACKAGES, \"@uppy/react\"],\n });\n } else if (hasSvelte) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...UPPY_CORE_PACKAGES, \"@uppy/svelte\"],\n });\n } else if (hasVue) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...UPPY_CORE_PACKAGES, \"@uppy/vue\"],\n });\n } else if (hasAngular) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...UPPY_CORE_PACKAGES, \"@uppy/angular\"],\n });\n } else if (hasAstro) {\n // Astro with framework integration\n if (astroIntegration === \"react\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...UPPY_CORE_PACKAGES, \"@uppy/react\"],\n });\n } else if (astroIntegration === \"vue\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...UPPY_CORE_PACKAGES, \"@uppy/vue\"],\n });\n } else if (astroIntegration === \"svelte\") {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [...UPPY_CORE_PACKAGES, \"@uppy/svelte\"],\n });\n } else {\n // Astro without UI integration - add vanilla Uppy\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: UPPY_CORE_PACKAGES,\n });\n }\n } else {\n // For other frontends (Solid, Qwik, etc.), add vanilla Uppy\n // These can use Uppy directly via its vanilla JS API\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: UPPY_CORE_PACKAGES,\n });\n }\n}\n","import type { Frontend, ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\n// React-based web frameworks that support form libraries\nconst REACT_WEB_FRAMEWORKS: Frontend[] = [\n \"tanstack-router\",\n \"react-router\",\n \"tanstack-start\",\n \"next\",\n];\n\n// Native frameworks (always React-based)\nconst NATIVE_FRAMEWORKS: Frontend[] = [\"native-bare\", \"native-uniwind\", \"native-unistyles\"];\n\n// SolidJS frameworks\nconst SOLID_FRAMEWORKS: Frontend[] = [\"solid\"];\n\n// Qwik frameworks\nconst QWIK_FRAMEWORKS: Frontend[] = [\"qwik\"];\n\nexport function processFormsDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { forms, frontend } = config;\n\n // Skip if not selected or set to \"none\"\n if (!forms || forms === \"none\") return;\n\n // Determine which packages need form library deps\n const hasReactWeb = frontend.some((f) => REACT_WEB_FRAMEWORKS.includes(f));\n const hasNative = frontend.some((f) => NATIVE_FRAMEWORKS.includes(f));\n const hasSolid = frontend.some((f) => SOLID_FRAMEWORKS.includes(f));\n const hasQwik = frontend.some((f) => QWIK_FRAMEWORKS.includes(f));\n\n // Add to web package if it's a React-based web frontend\n const webPath = \"apps/web/package.json\";\n if (hasReactWeb && vfs.exists(webPath)) {\n const deps = getFormsDeps(forms, \"react\");\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: deps,\n });\n }\n }\n\n // Add to native package if it exists\n const nativePath = \"apps/native/package.json\";\n if (hasNative && vfs.exists(nativePath)) {\n const deps = getFormsDeps(forms, \"react\");\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: nativePath,\n dependencies: deps,\n });\n }\n }\n\n // Add to Solid web package if it exists\n if (hasSolid && vfs.exists(webPath)) {\n const deps = getFormsDeps(forms, \"solid\");\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: deps,\n });\n }\n }\n\n // Add to Qwik web package if it exists\n if (hasQwik && vfs.exists(webPath)) {\n const deps = getFormsDeps(forms, \"qwik\");\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: deps,\n });\n }\n }\n}\n\nfunction getFormsDeps(\n forms: ProjectConfig[\"forms\"],\n target: \"react\" | \"solid\" | \"qwik\",\n): AvailableDependencies[] {\n const deps: AvailableDependencies[] = [];\n\n switch (forms) {\n case \"formik\":\n if (target === \"react\") {\n deps.push(\"formik\", \"yup\");\n }\n break;\n case \"final-form\":\n if (target === \"react\") {\n deps.push(\"final-form\", \"react-final-form\");\n }\n break;\n case \"conform\":\n if (target === \"react\") {\n deps.push(\"@conform-to/react\", \"@conform-to/zod\");\n }\n break;\n case \"modular-forms\":\n if (target === \"solid\") {\n deps.push(\"@modular-forms/solid\");\n } else if (target === \"qwik\") {\n deps.push(\"@modular-forms/qwik\");\n }\n break;\n // react-hook-form and tanstack-form are handled elsewhere or already included\n // No additional deps needed for those cases\n }\n\n return deps;\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency } from \"../utils/add-deps\";\n\nexport function processInfraDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const infraPath = \"packages/infra/package.json\";\n if (!vfs.exists(infraPath)) return;\n\n const { serverDeploy, webDeploy } = config;\n if (serverDeploy === \"cloudflare\" || webDeploy === \"cloudflare\") {\n addPackageDependency({ vfs, packagePath: infraPath, devDependencies: [\"alchemy\"] });\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\nexport function processJobQueueDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { jobQueue, backend } = config;\n\n // Skip if not selected or set to \"none\"\n if (!jobQueue || jobQueue === \"none\") return;\n\n // Skip if no backend to support job queues (convex has its own background jobs)\n if (backend === \"none\" || backend === \"convex\") return;\n\n // Add server-side job queue dependencies\n const serverPath = \"apps/server/package.json\";\n if (vfs.exists(serverPath)) {\n const deps = getJobQueueDeps(jobQueue);\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: deps,\n });\n }\n }\n}\n\nfunction getJobQueueDeps(jobQueue: ProjectConfig[\"jobQueue\"]): AvailableDependencies[] {\n const deps: AvailableDependencies[] = [];\n\n switch (jobQueue) {\n case \"bullmq\":\n deps.push(\"bullmq\");\n deps.push(\"ioredis\");\n break;\n case \"trigger-dev\":\n deps.push(\"@trigger.dev/sdk\");\n break;\n case \"inngest\":\n deps.push(\"inngest\");\n break;\n case \"temporal\":\n deps.push(\"@temporalio/client\");\n deps.push(\"@temporalio/worker\");\n deps.push(\"@temporalio/workflow\");\n deps.push(\"@temporalio/activity\");\n break;\n }\n\n return deps;\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency } from \"../utils/add-deps\";\n\nexport function processLoggingDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { logging, backend } = config;\n if (!logging || logging === \"none\") return;\n if (backend === \"none\" || backend === \"convex\") return;\n\n const serverPath = \"apps/server/package.json\";\n\n // Add Pino for pino option\n if (logging === \"pino\" && vfs.exists(serverPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"pino\", \"pino-http\"],\n devDependencies: [\"pino-pretty\"],\n });\n }\n\n // Add Winston for winston option\n if (logging === \"winston\" && vfs.exists(serverPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"winston\"],\n });\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency } from \"../utils/add-deps\";\n\nexport function processObservabilityDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { observability, backend } = config;\n if (!observability || observability === \"none\") return;\n if (backend === \"none\" || backend === \"convex\") return;\n\n const serverPath = \"apps/server/package.json\";\n\n // Add OpenTelemetry packages\n if (observability === \"opentelemetry\" && vfs.exists(serverPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\n \"@opentelemetry/api\",\n \"@opentelemetry/sdk-node\",\n \"@opentelemetry/auto-instrumentations-node\",\n \"@opentelemetry/exporter-trace-otlp-http\",\n \"@opentelemetry/exporter-metrics-otlp-http\",\n \"@opentelemetry/resources\",\n \"@opentelemetry/semantic-conventions\",\n ],\n });\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency } from \"../utils/add-deps\";\n\nexport function processPaymentsDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { payments, frontend } = config;\n if (!payments || payments === \"none\") return;\n\n const authPath = \"packages/auth/package.json\";\n const webPath = \"apps/web/package.json\";\n\n if (payments === \"polar\") {\n if (vfs.exists(authPath)) {\n addPackageDependency({\n vfs,\n packagePath: authPath,\n dependencies: [\"@polar-sh/better-auth\", \"@polar-sh/sdk\"],\n });\n }\n\n if (vfs.exists(webPath)) {\n const hasWebFrontend = frontend.some((f) =>\n [\n \"react-router\",\n \"tanstack-router\",\n \"tanstack-start\",\n \"next\",\n \"nuxt\",\n \"svelte\",\n \"solid\",\n ].includes(f),\n );\n if (hasWebFrontend) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@polar-sh/better-auth\"],\n });\n }\n }\n }\n\n if (payments === \"stripe\") {\n const serverPath = \"apps/server/package.json\";\n\n // Add server-side Stripe SDK\n if (vfs.exists(serverPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"stripe\"],\n });\n }\n\n // Also add to auth package if it exists (for webhook handling)\n if (vfs.exists(authPath)) {\n addPackageDependency({\n vfs,\n packagePath: authPath,\n dependencies: [\"stripe\"],\n });\n }\n\n // Add client-side Stripe.js for web frontends\n if (vfs.exists(webPath)) {\n const hasReactWeb = frontend.some((f) =>\n [\"react-router\", \"tanstack-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n const hasOtherWeb = frontend.some((f) => [\"nuxt\", \"svelte\", \"solid\"].includes(f));\n\n if (hasReactWeb) {\n // React apps get the React bindings\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@stripe/stripe-js\", \"@stripe/react-stripe-js\"],\n });\n } else if (hasOtherWeb) {\n // Non-React web apps get just the base Stripe.js\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@stripe/stripe-js\"],\n });\n }\n }\n }\n\n if (payments === \"lemon-squeezy\") {\n const serverPath = \"apps/server/package.json\";\n\n // Add server-side Lemon Squeezy SDK (server-side only for security)\n if (vfs.exists(serverPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"@lemonsqueezy/lemonsqueezy.js\"],\n });\n }\n\n // Also add to auth package if it exists (for webhook handling)\n if (vfs.exists(authPath)) {\n addPackageDependency({\n vfs,\n packagePath: authPath,\n dependencies: [\"@lemonsqueezy/lemonsqueezy.js\"],\n });\n }\n }\n\n if (payments === \"paddle\") {\n const serverPath = \"apps/server/package.json\";\n\n // Add server-side Paddle SDK\n if (vfs.exists(serverPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"@paddle/paddle-node-sdk\"],\n });\n }\n\n // Also add to auth package if it exists (for webhook handling)\n if (vfs.exists(authPath)) {\n addPackageDependency({\n vfs,\n packagePath: authPath,\n dependencies: [\"@paddle/paddle-node-sdk\"],\n });\n }\n\n // Add client-side Paddle.js for web frontends\n if (vfs.exists(webPath)) {\n const hasWebFrontend = frontend.some((f) =>\n [\n \"react-router\",\n \"tanstack-router\",\n \"tanstack-start\",\n \"next\",\n \"nuxt\",\n \"svelte\",\n \"solid\",\n ].includes(f),\n );\n\n if (hasWebFrontend) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"@paddle/paddle-js\"],\n });\n }\n }\n }\n\n if (payments === \"dodo\") {\n const serverPath = \"apps/server/package.json\";\n\n // Add server-side Dodo Payments SDK\n if (vfs.exists(serverPath)) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"dodopayments\"],\n });\n }\n\n // Also add to auth package if it exists (for webhook handling)\n if (vfs.exists(authPath)) {\n addPackageDependency({\n vfs,\n packagePath: authPath,\n dependencies: [\"dodopayments\"],\n });\n }\n\n // Add client-side Dodo Payments checkout for web frontends\n if (vfs.exists(webPath)) {\n const hasWebFrontend = frontend.some((f) =>\n [\n \"react-router\",\n \"tanstack-router\",\n \"tanstack-start\",\n \"next\",\n \"nuxt\",\n \"svelte\",\n \"solid\",\n ].includes(f),\n );\n\n if (hasWebFrontend) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: [\"dodopayments-checkout\"],\n });\n }\n }\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport { IndentationText, Node, Project, QuoteKind } from \"ts-morph\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nexport function processPwaPlugins(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { addons, projectName } = config;\n\n if (!addons.includes(\"pwa\")) return;\n\n const viteConfigPath = \"apps/web/vite.config.ts\";\n if (!vfs.exists(viteConfigPath)) return;\n\n const content = vfs.readFile(viteConfigPath);\n const project = new Project({\n useInMemoryFileSystem: true,\n manipulationSettings: {\n indentationText: IndentationText.TwoSpaces,\n quoteKind: QuoteKind.Double,\n },\n });\n\n const sourceFile = project.createSourceFile(\"vite.config.ts\", content);\n\n const hasImport = sourceFile\n .getImportDeclarations()\n .some((imp) => imp.getModuleSpecifierValue() === \"vite-plugin-pwa\");\n\n if (!hasImport) {\n sourceFile.addImportDeclaration({\n namedImports: [\"VitePWA\"],\n moduleSpecifier: \"vite-plugin-pwa\",\n });\n }\n\n const exportAssignment = sourceFile.getExportAssignment((d) => !d.isExportEquals());\n if (!exportAssignment) return;\n\n const defineConfigCall = exportAssignment.getExpression();\n if (\n !Node.isCallExpression(defineConfigCall) ||\n defineConfigCall.getExpression().getText() !== \"defineConfig\"\n ) {\n return;\n }\n\n let configObject = defineConfigCall.getArguments()[0];\n if (!configObject) {\n configObject = defineConfigCall.addArgument(\"{}\");\n }\n\n if (Node.isObjectLiteralExpression(configObject)) {\n const pluginsProperty = configObject.getProperty(\"plugins\");\n\n const pwaConfig = `VitePWA({\n registerType: \"autoUpdate\",\n manifest: {\n name: \"${projectName}\",\n short_name: \"${projectName}\",\n description: \"${projectName} - PWA Application\",\n theme_color: \"#0c0c0c\",\n },\n pwaAssets: { disabled: false, config: true },\n devOptions: { enabled: true },\n})`;\n\n if (pluginsProperty && Node.isPropertyAssignment(pluginsProperty)) {\n const initializer = pluginsProperty.getInitializer();\n if (Node.isArrayLiteralExpression(initializer)) {\n const hasPwa = initializer.getElements().some((el) => el.getText().startsWith(\"VitePWA(\"));\n if (!hasPwa) {\n initializer.addElement(pwaConfig);\n }\n }\n } else {\n configObject.addPropertyAssignment({\n name: \"plugins\",\n initializer: `[${pwaConfig}]`,\n });\n }\n }\n\n vfs.writeFile(viteConfigPath, sourceFile.getFullText());\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nexport function processReadme(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const content =\n config.ecosystem === \"rust\" ? generateRustReadmeContent(config) : generateReadmeContent(config);\n vfs.writeFile(\"README.md\", content);\n}\n\nfunction generateReadmeContent(options: ProjectConfig): string {\n const {\n projectName,\n packageManager,\n database,\n auth,\n addons = [],\n orm = \"drizzle\",\n runtime = \"bun\",\n frontend = [\"tanstack-router\"],\n backend = \"hono\",\n api = \"trpc\",\n webDeploy,\n serverDeploy,\n dbSetup,\n } = options;\n\n const isConvex = backend === \"convex\";\n const hasReactRouter = frontend.includes(\"react-router\");\n const hasNative = frontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n const hasSvelte = frontend.includes(\"svelte\");\n const packageManagerRunCmd = `${packageManager} run`;\n const webPort = hasReactRouter || hasSvelte ? \"5173\" : \"3001\";\n\n const stackDescription = generateStackDescription(frontend, backend, api, isConvex);\n\n return `# ${projectName}\n\nThis project was created with [Better Fullstack](https://github.com/Marve10s/Better-Fullstack), a modern TypeScript stack${\n stackDescription ? ` that combines ${stackDescription}` : \"\"\n }.\n\n## Features\n\n${generateFeaturesList(database, auth, addons, orm, runtime, frontend, backend, api)}\n\n## Getting Started\n\nFirst, install the dependencies:\n\n\\`\\`\\`bash\n${packageManager} install\n\\`\\`\\`\n${\n isConvex\n ? `\n## Convex Setup\n\nThis project uses Convex as a backend. You'll need to set up Convex before running the app:\n\n\\`\\`\\`bash\n${packageManagerRunCmd} dev:setup\n\\`\\`\\`\n\nFollow the prompts to create a new Convex project and connect it to your application.\n\nCopy environment variables from \\`packages/backend/.env.local\\` to \\`apps/*/.env\\`.\n${\n auth === \"clerk\"\n ? `\n### Clerk Authentication Setup\n\n- Follow the guide: [Convex + Clerk](https://docs.convex.dev/auth/clerk)\n- Set \\`CLERK_JWT_ISSUER_DOMAIN\\` in Convex Dashboard\n- Set \\`CLERK_PUBLISHABLE_KEY\\` in \\`apps/*/.env\\``\n : \"\"\n}`\n : generateDatabaseSetup(database, packageManagerRunCmd, orm, dbSetup, backend)\n}\n\nThen, run the development server:\n\n\\`\\`\\`bash\n${packageManagerRunCmd} dev\n\\`\\`\\`\n\n${generateRunningInstructions(frontend, backend, webPort, hasNative, isConvex)}\n${\n addons.includes(\"pwa\") && hasReactRouter\n ? \"\\n## PWA Support with React Router v7\\n\\nThere is a known compatibility issue between VitePWA and React Router v7.\\nSee: https://github.com/vite-pwa/vite-plugin-pwa/issues/809\\n\"\n : \"\"\n}\n${generateDeploymentCommands(packageManagerRunCmd, webDeploy, serverDeploy)}\n${generateGitHooksSection(packageManagerRunCmd, addons)}\n\n## Project Structure\n\n\\`\\`\\`\n${generateProjectStructure(projectName, frontend, backend, addons, isConvex, api, auth)}\n\\`\\`\\`\n\n## Available Scripts\n\n${generateScriptsList(packageManagerRunCmd, database, orm, hasNative, addons, backend, dbSetup)}\n`;\n}\n\nfunction generateStackDescription(\n frontend: ProjectConfig[\"frontend\"],\n backend: ProjectConfig[\"backend\"],\n api: ProjectConfig[\"api\"],\n isConvex: boolean,\n): string {\n const parts: string[] = [];\n\n const frontendMap: Record<string, string> = {\n \"tanstack-router\": \"React, TanStack Router\",\n \"react-router\": \"React, React Router\",\n next: \"Next.js\",\n \"tanstack-start\": \"React, TanStack Start\",\n svelte: \"SvelteKit\",\n nuxt: \"Nuxt\",\n solid: \"SolidJS\",\n };\n\n for (const fe of frontend) {\n if (frontendMap[fe]) {\n parts.push(frontendMap[fe]);\n break;\n }\n }\n\n if (backend !== \"none\") {\n parts.push((backend[0]?.toUpperCase() ?? \"\") + backend.slice(1));\n }\n\n if (!isConvex && api !== \"none\") {\n parts.push(api.toUpperCase());\n }\n\n return parts.length > 0 ? `${parts.join(\", \")}, and more` : \"\";\n}\n\nfunction generateRunningInstructions(\n frontend: ProjectConfig[\"frontend\"],\n backend: ProjectConfig[\"backend\"],\n webPort: string,\n hasNative: boolean,\n isConvex: boolean,\n): string {\n const instructions: string[] = [];\n const hasFrontend = frontend.length > 0 && !frontend.includes(\"none\");\n const isBackendSelf = backend === \"self\";\n\n if (hasFrontend) {\n const desc = isBackendSelf ? \"fullstack application\" : \"web application\";\n instructions.push(\n `Open [http://localhost:${webPort}](http://localhost:${webPort}) in your browser to see the ${desc}.`,\n );\n }\n\n if (hasNative) {\n instructions.push(\"Use the Expo Go app to run the mobile application.\");\n }\n\n if (isConvex) {\n instructions.push(\"Your app will connect to the Convex cloud backend automatically.\");\n } else if (backend !== \"none\" && !isBackendSelf) {\n instructions.push(\"The API is running at [http://localhost:3000](http://localhost:3000).\");\n }\n\n return instructions.join(\"\\n\");\n}\n\nfunction generateProjectStructure(\n projectName: string,\n frontend: ProjectConfig[\"frontend\"],\n backend: ProjectConfig[\"backend\"],\n addons: ProjectConfig[\"addons\"],\n isConvex: boolean,\n api: ProjectConfig[\"api\"],\n auth: ProjectConfig[\"auth\"],\n): string {\n const structure: string[] = [`${projectName}/`, \"├── apps/\"];\n const hasFrontend = frontend.length > 0 && !frontend.includes(\"none\");\n const isBackendSelf = backend === \"self\";\n const hasNative = frontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n\n if (hasFrontend) {\n const frontendTypes: Record<string, string> = {\n \"tanstack-router\": \"React + TanStack Router\",\n \"react-router\": \"React + React Router\",\n next: \"Next.js\",\n \"tanstack-start\": \"React + TanStack Start\",\n svelte: \"SvelteKit\",\n nuxt: \"Nuxt\",\n solid: \"SolidJS\",\n };\n const frontendType = frontend.find((f) => frontendTypes[f])\n ? frontendTypes[frontend.find((f) => frontendTypes[f]) || \"\"]\n : \"\";\n\n const prefix = isBackendSelf ? \"└──\" : \"├──\";\n const desc = isBackendSelf ? \"Fullstack application\" : \"Frontend application\";\n structure.push(`│ ${prefix} web/ # ${desc} (${frontendType})`);\n }\n\n if (hasNative) {\n structure.push(\"│ ├── native/ # Mobile application (React Native, Expo)\");\n }\n\n if (addons.includes(\"starlight\")) {\n structure.push(\"│ ├── docs/ # Documentation site (Astro Starlight)\");\n }\n\n if (!isBackendSelf && backend !== \"none\" && !isConvex) {\n const backendName = (backend[0]?.toUpperCase() ?? \"\") + backend.slice(1);\n const apiName = api !== \"none\" ? api.toUpperCase() : \"\";\n const desc = apiName ? `${backendName}, ${apiName}` : backendName;\n structure.push(`│ └── server/ # Backend API (${desc})`);\n }\n\n if (isConvex || backend !== \"none\") {\n structure.push(\"├── packages/\");\n\n if (isConvex) {\n structure.push(\"│ ├── backend/ # Convex backend functions and schema\");\n if (auth === \"clerk\") {\n structure.push(\n \"│ │ ├── convex/ # Convex functions and schema\",\n \"│ │ └── .env.local # Convex environment variables\",\n );\n }\n }\n\n if (!isConvex) {\n structure.push(\"│ ├── api/ # API layer / business logic\");\n if (auth !== \"none\") {\n structure.push(\"│ ├── auth/ # Authentication configuration & logic\");\n }\n if (api !== \"none\" || auth !== \"none\") {\n structure.push(\"│ └── db/ # Database schema & queries\");\n }\n }\n }\n\n return structure.join(\"\\n\");\n}\n\nfunction generateFeaturesList(\n database: ProjectConfig[\"database\"],\n auth: ProjectConfig[\"auth\"],\n addons: ProjectConfig[\"addons\"],\n orm: ProjectConfig[\"orm\"],\n runtime: ProjectConfig[\"runtime\"],\n frontend: ProjectConfig[\"frontend\"],\n backend: ProjectConfig[\"backend\"],\n api: ProjectConfig[\"api\"],\n): string {\n const isConvex = backend === \"convex\";\n const hasNative = frontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n const hasFrontend = frontend.length > 0 && !frontend.includes(\"none\");\n\n const features = [\"- **TypeScript** - For type safety and improved developer experience\"];\n\n const frontendFeatures: Record<string, string> = {\n \"tanstack-router\": \"- **TanStack Router** - File-based routing with full type safety\",\n \"react-router\": \"- **React Router** - Declarative routing for React\",\n next: \"- **Next.js** - Full-stack React framework\",\n \"tanstack-start\": \"- **TanStack Start** - SSR framework with TanStack Router\",\n svelte: \"- **SvelteKit** - Web framework for building Svelte apps\",\n nuxt: \"- **Nuxt** - The Intuitive Vue Framework\",\n solid: \"- **SolidJS** - Simple and performant reactivity\",\n };\n\n for (const fe of frontend) {\n if (frontendFeatures[fe]) {\n features.push(frontendFeatures[fe]);\n break;\n }\n }\n\n if (hasNative) {\n features.push(\n \"- **React Native** - Build mobile apps using React\",\n \"- **Expo** - Tools for React Native development\",\n );\n }\n\n if (hasFrontend) {\n features.push(\n \"- **TailwindCSS** - Utility-first CSS for rapid UI development\",\n \"- **shadcn/ui** - Reusable UI components\",\n );\n }\n\n const backendFeatures: Record<string, string> = {\n convex: \"- **Convex** - Reactive backend-as-a-service platform\",\n hono: \"- **Hono** - Lightweight, performant server framework\",\n express: \"- **Express** - Fast, unopinionated web framework\",\n fastify: \"- **Fastify** - Fast, low-overhead web framework\",\n elysia: \"- **Elysia** - Type-safe, high-performance framework\",\n };\n\n if (backendFeatures[backend]) {\n features.push(backendFeatures[backend]);\n }\n\n if (!isConvex && api === \"trpc\") {\n features.push(\"- **tRPC** - End-to-end type-safe APIs\");\n } else if (!isConvex && api === \"orpc\") {\n features.push(\"- **oRPC** - End-to-end type-safe APIs with OpenAPI integration\");\n }\n\n if (!isConvex && backend !== \"none\" && runtime !== \"none\") {\n const runtimeName = runtime === \"bun\" ? \"Bun\" : runtime === \"node\" ? \"Node.js\" : runtime;\n features.push(`- **${runtimeName}** - Runtime environment`);\n }\n\n if (database !== \"none\" && !isConvex) {\n const ormNames: Record<string, string> = {\n drizzle: \"Drizzle\",\n prisma: \"Prisma\",\n mongoose: \"Mongoose\",\n };\n const dbNames: Record<string, string> = {\n sqlite: \"SQLite/Turso\",\n postgres: \"PostgreSQL\",\n mysql: \"MySQL\",\n mongodb: \"MongoDB\",\n };\n features.push(\n `- **${ormNames[orm] || \"ORM\"}** - TypeScript-first ORM`,\n `- **${dbNames[database] || \"Database\"}** - Database engine`,\n );\n }\n\n if (auth !== \"none\") {\n const authLabel = auth === \"clerk\" ? \"Clerk\" : \"Better-Auth\";\n features.push(`- **Authentication** - ${authLabel}`);\n }\n\n const addonFeatures: Record<string, string> = {\n pwa: \"- **PWA** - Progressive Web App support\",\n tauri: \"- **Tauri** - Build native desktop applications\",\n biome: \"- **Biome** - Linting and formatting\",\n oxlint: \"- **Oxlint** - Oxlint + Oxfmt (linting & formatting)\",\n husky: \"- **Husky** - Git hooks for code quality\",\n starlight: \"- **Starlight** - Documentation site with Astro\",\n turborepo: \"- **Turborepo** - Optimized monorepo build system\",\n };\n\n for (const addon of addons) {\n if (addonFeatures[addon]) {\n features.push(addonFeatures[addon]);\n }\n }\n\n return features.join(\"\\n\");\n}\n\nfunction generateDatabaseSetup(\n database: ProjectConfig[\"database\"],\n packageManagerRunCmd: string,\n orm: ProjectConfig[\"orm\"],\n dbSetup: ProjectConfig[\"dbSetup\"],\n backend: ProjectConfig[\"backend\"],\n): string {\n if (database === \"none\") return \"\";\n\n const isBackendSelf = backend === \"self\";\n const envPath = isBackendSelf ? \"apps/web/.env\" : \"apps/server/.env\";\n const ormDesc =\n orm === \"drizzle\" ? \" with Drizzle ORM\" : orm === \"prisma\" ? \" with Prisma\" : ` with ${orm}`;\n\n let setup = \"## Database Setup\\n\\n\";\n\n const dbDescriptions: Record<string, string> = {\n sqlite: `This project uses SQLite${ormDesc}.\n\n1. Start the local SQLite database (optional):\n${\n dbSetup === \"d1\"\n ? \"D1 local development and migrations are handled automatically by Alchemy during dev and deploy.\"\n : `\\`\\`\\`bash\n${packageManagerRunCmd} db:local\n\\`\\`\\``\n}\n\n2. Update your \\`.env\\` file in the \\`${isBackendSelf ? \"apps/web\" : \"apps/server\"}\\` directory with the appropriate connection details if needed.`,\n\n postgres: `This project uses PostgreSQL${ormDesc}.\n\n1. Make sure you have a PostgreSQL database set up.\n2. Update your \\`${envPath}\\` file with your PostgreSQL connection details.`,\n\n mysql: `This project uses MySQL${ormDesc}.\n\n1. Make sure you have a MySQL database set up.\n2. Update your \\`${envPath}\\` file with your MySQL connection details.`,\n\n mongodb: `This project uses MongoDB ${ormDesc.replace(\" with \", \"with \")}.\n\n1. Make sure you have MongoDB set up.\n2. Update your \\`${envPath}\\` file with your MongoDB connection URI.`,\n };\n\n setup += dbDescriptions[database] || \"\";\n\n setup += `\n\n3. Apply the schema to your database:\n\\`\\`\\`bash\n${packageManagerRunCmd} db:push\n\\`\\`\\`\n`;\n\n return setup;\n}\n\nfunction generateScriptsList(\n packageManagerRunCmd: string,\n database: ProjectConfig[\"database\"],\n orm: ProjectConfig[\"orm\"],\n hasNative: boolean,\n addons: ProjectConfig[\"addons\"],\n backend: ProjectConfig[\"backend\"],\n dbSetup: ProjectConfig[\"dbSetup\"],\n): string {\n const isConvex = backend === \"convex\";\n const isBackendSelf = backend === \"self\";\n\n let scripts = `- \\`${packageManagerRunCmd} dev\\`: Start all applications in development mode\n- \\`${packageManagerRunCmd} build\\`: Build all applications`;\n\n if (!isBackendSelf) {\n scripts += `\\n- \\`${packageManagerRunCmd} dev:web\\`: Start only the web application`;\n }\n\n if (isConvex) {\n scripts += `\\n- \\`${packageManagerRunCmd} dev:setup\\`: Setup and configure your Convex project`;\n } else if (backend !== \"none\" && !isBackendSelf) {\n scripts += `\\n- \\`${packageManagerRunCmd} dev:server\\`: Start only the server`;\n }\n\n scripts += `\\n- \\`${packageManagerRunCmd} check-types\\`: Check TypeScript types across all apps`;\n\n if (hasNative) {\n scripts += `\\n- \\`${packageManagerRunCmd} dev:native\\`: Start the React Native/Expo development server`;\n }\n\n if (database !== \"none\" && !isConvex) {\n scripts += `\\n- \\`${packageManagerRunCmd} db:push\\`: Push schema changes to database\n- \\`${packageManagerRunCmd} db:studio\\`: Open database studio UI`;\n\n if (database === \"sqlite\" && dbSetup !== \"d1\") {\n scripts += `\\n- \\`${packageManagerRunCmd} db:local\\`: Start the local SQLite database`;\n }\n }\n\n if (addons.includes(\"biome\")) {\n scripts += `\\n- \\`${packageManagerRunCmd} check\\`: Run Biome formatting and linting`;\n }\n\n if (addons.includes(\"oxlint\")) {\n scripts += `\\n- \\`${packageManagerRunCmd} check\\`: Run Oxlint and Oxfmt`;\n }\n\n if (addons.includes(\"pwa\")) {\n scripts += `\\n- \\`cd apps/web && ${packageManagerRunCmd} generate-pwa-assets\\`: Generate PWA assets`;\n }\n\n if (addons.includes(\"tauri\")) {\n scripts += `\\n- \\`cd apps/web && ${packageManagerRunCmd} desktop:dev\\`: Start Tauri desktop app in development\n- \\`cd apps/web && ${packageManagerRunCmd} desktop:build\\`: Build Tauri desktop app`;\n }\n\n if (addons.includes(\"starlight\")) {\n scripts += `\\n- \\`cd apps/docs && ${packageManagerRunCmd} dev\\`: Start documentation site\n- \\`cd apps/docs && ${packageManagerRunCmd} build\\`: Build documentation site`;\n }\n\n return scripts;\n}\n\nfunction generateDeploymentCommands(\n packageManagerRunCmd: string,\n webDeploy: ProjectConfig[\"webDeploy\"],\n serverDeploy: ProjectConfig[\"serverDeploy\"],\n): string {\n if (webDeploy !== \"cloudflare\" && serverDeploy !== \"cloudflare\") {\n return \"\";\n }\n\n const lines: string[] = [\"## Deployment (Cloudflare via Alchemy)\"];\n\n if (webDeploy === \"cloudflare\" && serverDeploy !== \"cloudflare\") {\n lines.push(\n `- Dev: cd apps/web && ${packageManagerRunCmd} alchemy dev`,\n `- Deploy: cd apps/web && ${packageManagerRunCmd} deploy`,\n `- Destroy: cd apps/web && ${packageManagerRunCmd} destroy`,\n );\n }\n\n if (serverDeploy === \"cloudflare\" && webDeploy !== \"cloudflare\") {\n lines.push(\n `- Dev: cd apps/server && ${packageManagerRunCmd} dev`,\n `- Deploy: cd apps/server && ${packageManagerRunCmd} deploy`,\n `- Destroy: cd apps/server && ${packageManagerRunCmd} destroy`,\n );\n }\n\n if (webDeploy === \"cloudflare\" && serverDeploy === \"cloudflare\") {\n lines.push(\n `- Dev: ${packageManagerRunCmd} dev`,\n `- Deploy: ${packageManagerRunCmd} deploy`,\n `- Destroy: ${packageManagerRunCmd} destroy`,\n );\n }\n\n lines.push(\n \"\",\n \"For more details, see the guide on [Deploying to Cloudflare with Alchemy](https://www.better-t-stack.dev/docs/guides/cloudflare-alchemy).\",\n );\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction generateGitHooksSection(\n packageManagerRunCmd: string,\n addons: ProjectConfig[\"addons\"],\n): string {\n const hasHusky = addons.includes(\"husky\");\n const hasLinting = addons.includes(\"biome\") || addons.includes(\"oxlint\");\n\n if (!hasHusky && !hasLinting) {\n return \"\";\n }\n\n const lines: string[] = [\"## Git Hooks and Formatting\", \"\"];\n\n if (hasHusky) {\n lines.push(`- Initialize hooks: \\`${packageManagerRunCmd} prepare\\``);\n }\n\n if (hasLinting) {\n lines.push(`- Format and lint fix: \\`${packageManagerRunCmd} check\\``);\n }\n\n return `${lines.join(\"\\n\")}\\n\\n`;\n}\n\nfunction generateRustReadmeContent(config: ProjectConfig): string {\n const { projectName, rustWebFramework, rustFrontend, rustOrm, rustApi, rustCli, rustLibraries } =\n config;\n\n const features: string[] = [\"- **Rust** - Memory-safe, high-performance systems programming\"];\n\n // Web framework\n if (rustWebFramework === \"axum\") {\n features.push(\"- **Axum** - Ergonomic and modular web framework by Tokio team\");\n } else if (rustWebFramework === \"actix-web\") {\n features.push(\"- **Actix-web** - Powerful, pragmatic, and extremely fast web framework\");\n }\n\n // Frontend\n if (rustFrontend === \"leptos\") {\n features.push(\"- **Leptos** - Fine-grained reactive framework with SSR support\");\n features.push(\"- **WebAssembly** - High-performance frontend compiled from Rust\");\n } else if (rustFrontend === \"dioxus\") {\n features.push(\"- **Dioxus** - React-like GUI library for web, desktop, and mobile\");\n features.push(\"- **WebAssembly** - High-performance frontend compiled from Rust\");\n }\n\n // ORM\n if (rustOrm === \"sea-orm\") {\n features.push(\"- **SeaORM** - Async & dynamic ORM with ActiveRecord pattern\");\n } else if (rustOrm === \"sqlx\") {\n features.push(\"- **SQLx** - Async SQL toolkit with compile-time checked queries\");\n }\n\n // API\n if (rustApi === \"tonic\") {\n features.push(\"- **Tonic** - Production-ready gRPC implementation\");\n } else if (rustApi === \"async-graphql\") {\n features.push(\"- **async-graphql** - High-performance GraphQL server\");\n }\n\n // CLI\n if (rustCli === \"clap\") {\n features.push(\"- **Clap** - CLI argument parser with derive macros\");\n } else if (rustCli === \"ratatui\") {\n features.push(\"- **Ratatui** - Terminal user interface library\");\n }\n\n // Libraries\n const libs = Array.isArray(rustLibraries) ? rustLibraries : [];\n if (libs.includes(\"validator\")) {\n features.push(\"- **Validator** - Derive-based validation\");\n }\n if (libs.includes(\"jsonwebtoken\")) {\n features.push(\"- **jsonwebtoken** - JWT encoding/decoding\");\n }\n if (libs.includes(\"argon2\")) {\n features.push(\"- **Argon2** - Secure password hashing\");\n }\n if (libs.includes(\"tokio-test\")) {\n features.push(\"- **Tokio Test** - Async testing utilities\");\n }\n\n // Project structure\n const structure: string[] = [`${projectName}/`, \"├── Cargo.toml # Workspace manifest\"];\n\n if (rustFrontend === \"leptos\") {\n structure.push(\n \"├── crates/\",\n \"│ ├── server/ # Backend API server\",\n \"│ │ ├── Cargo.toml\",\n \"│ │ └── src/main.rs\",\n \"│ └── client/ # Leptos WASM frontend\",\n \"│ ├── Cargo.toml\",\n \"│ ├── Trunk.toml # Trunk build config\",\n \"│ ├── index.html\",\n \"│ ├── src/lib.rs\",\n \"│ └── style/main.css\",\n );\n } else if (rustFrontend === \"dioxus\") {\n structure.push(\n \"├── crates/\",\n \"│ ├── server/ # Backend API server\",\n \"│ │ ├── Cargo.toml\",\n \"│ │ └── src/main.rs\",\n \"│ └── dioxus-client/ # Dioxus WASM frontend\",\n \"│ ├── Cargo.toml\",\n \"│ ├── Dioxus.toml # Dioxus CLI config\",\n \"│ ├── src/main.rs\",\n \"│ └── assets/main.css\",\n );\n } else {\n structure.push(\n \"├── crates/\",\n \"│ └── server/ # Backend API server\",\n \"│ ├── Cargo.toml\",\n \"│ └── src/main.rs\",\n );\n }\n\n structure.push(\n \"├── rust-toolchain.toml # Rust version config\",\n \"├── .env.example # Environment variables\",\n \"└── .gitignore\",\n );\n\n // Scripts\n let scripts = `- \\`cargo build\\`: Build all crates\n- \\`cargo run --bin server\\`: Run the server\n- \\`cargo test\\`: Run all tests\n- \\`cargo clippy\\`: Run linter\n- \\`cargo fmt\\`: Format code`;\n\n if (rustFrontend === \"leptos\") {\n scripts += `\n- \\`cd crates/client && trunk serve\\`: Start Leptos dev server\n- \\`cd crates/client && trunk build --release\\`: Build Leptos for production`;\n } else if (rustFrontend === \"dioxus\") {\n scripts += `\n- \\`cd crates/dioxus-client && dx serve\\`: Start Dioxus dev server\n- \\`cd crates/dioxus-client && dx build --release\\`: Build Dioxus for production`;\n }\n\n return `# ${projectName}\n\nThis project was created with [Better Fullstack](https://github.com/Marve10s/Better-Fullstack), a high-performance Rust stack.\n\n## Features\n\n${features.join(\"\\n\")}\n\n## Prerequisites\n\n- [Rust](https://rustup.rs/) (stable toolchain)\n${rustFrontend === \"leptos\" ? \"- [Trunk](https://trunkrs.dev/) (`cargo install trunk`)\\n- [wasm32-unknown-unknown target](https://rustwasm.github.io/docs/book/) (`rustup target add wasm32-unknown-unknown`)\" : \"\"}${rustFrontend === \"dioxus\" ? \"- [Dioxus CLI](https://dioxuslabs.com/learn/0.6/getting_started) (`cargo install dioxus-cli`)\\n- [wasm32-unknown-unknown target](https://rustwasm.github.io/docs/book/) (`rustup target add wasm32-unknown-unknown`)\" : \"\"}\n\n## Getting Started\n\nFirst, copy the environment file:\n\n\\`\\`\\`bash\ncp .env.example .env\n\\`\\`\\`\n\nThen, build and run the server:\n\n\\`\\`\\`bash\ncargo run --bin server\n\\`\\`\\`\n\n${rustWebFramework !== \"none\" ? \"The API server will be running at [http://localhost:3000](http://localhost:3000).\" : \"\"}\n\n${\n rustFrontend === \"leptos\"\n ? `### Running the Frontend\n\nIn a separate terminal, start the Leptos frontend:\n\n\\`\\`\\`bash\ncd crates/client\ntrunk serve\n\\`\\`\\`\n\nThe frontend will be available at [http://localhost:8080](http://localhost:8080).\n`\n : \"\"\n}${\n rustFrontend === \"dioxus\"\n ? `### Running the Frontend\n\nIn a separate terminal, start the Dioxus frontend:\n\n\\`\\`\\`bash\ncd crates/dioxus-client\ndx serve\n\\`\\`\\`\n\nThe frontend will be available at [http://localhost:8080](http://localhost:8080).\n`\n : \"\"\n }\n## Project Structure\n\n\\`\\`\\`\n${structure.join(\"\\n\")}\n\\`\\`\\`\n\n## Available Commands\n\n${scripts}\n`;\n}\n","import type { Frontend, ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\n// React-based web frameworks that can use Socket.IO client\nconst REACT_WEB_FRAMEWORKS: Frontend[] = [\n \"tanstack-router\",\n \"react-router\",\n \"tanstack-start\",\n \"next\",\n];\n\n// Native frameworks (always React-based)\nconst NATIVE_FRAMEWORKS: Frontend[] = [\"native-bare\", \"native-uniwind\", \"native-unistyles\"];\n\nexport function processRealtimeDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { realtime, frontend, backend } = config;\n\n // Skip if not selected or set to \"none\"\n if (!realtime || realtime === \"none\") return;\n\n // Skip if no backend to support real-time (convex has its own real-time)\n if (backend === \"none\" || backend === \"convex\") return;\n\n // Determine which packages need real-time deps\n const hasReactWeb = frontend.some((f) => REACT_WEB_FRAMEWORKS.includes(f));\n const hasNative = frontend.some((f) => NATIVE_FRAMEWORKS.includes(f));\n\n // Add server-side real-time dependencies\n const serverPath = \"apps/server/package.json\";\n if (vfs.exists(serverPath)) {\n const deps = getRealtimeServerDeps(realtime);\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: deps,\n });\n }\n }\n\n // Add to web package if it's a React-based web frontend\n const webPath = \"apps/web/package.json\";\n if (hasReactWeb && vfs.exists(webPath)) {\n const deps = getRealtimeClientDeps(realtime);\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: deps,\n });\n }\n }\n\n // Add to native package if it exists\n const nativePath = \"apps/native/package.json\";\n if (hasNative && vfs.exists(nativePath)) {\n const deps = getRealtimeClientDeps(realtime);\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: nativePath,\n dependencies: deps,\n });\n }\n }\n}\n\nfunction getRealtimeServerDeps(realtime: ProjectConfig[\"realtime\"]): AvailableDependencies[] {\n const deps: AvailableDependencies[] = [];\n\n switch (realtime) {\n case \"socket-io\":\n deps.push(\"socket.io\");\n break;\n case \"partykit\":\n deps.push(\"partykit\");\n break;\n case \"ably\":\n deps.push(\"ably\");\n break;\n case \"pusher\":\n deps.push(\"pusher\");\n break;\n case \"liveblocks\":\n deps.push(\"@liveblocks/node\");\n break;\n case \"yjs\":\n deps.push(\"yjs\");\n deps.push(\"y-websocket\");\n deps.push(\"y-protocols\");\n deps.push(\"@y-sweet/sdk\");\n break;\n }\n\n return deps;\n}\n\nfunction getRealtimeClientDeps(realtime: ProjectConfig[\"realtime\"]): AvailableDependencies[] {\n const deps: AvailableDependencies[] = [];\n\n switch (realtime) {\n case \"socket-io\":\n deps.push(\"socket.io-client\");\n break;\n case \"partykit\":\n deps.push(\"partysocket\");\n break;\n case \"ably\":\n // Ably uses the same package for client and server\n deps.push(\"ably\");\n break;\n case \"pusher\":\n deps.push(\"pusher-js\");\n break;\n case \"liveblocks\":\n deps.push(\"@liveblocks/client\");\n deps.push(\"@liveblocks/react\");\n break;\n case \"yjs\":\n deps.push(\"yjs\");\n deps.push(\"y-websocket\");\n deps.push(\"@y-sweet/react\");\n break;\n }\n\n return deps;\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency } from \"../utils/add-deps\";\n\ntype PackageJson = {\n scripts?: Record<string, string>;\n [key: string]: unknown;\n};\n\nexport function processRuntimeDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { runtime, backend } = config;\n\n if (\n backend === \"convex\" ||\n backend === \"self\" ||\n backend === \"encore\" ||\n backend === \"adonisjs\" ||\n backend === \"nitro\" ||\n runtime === \"none\"\n )\n return;\n\n const serverPath = \"apps/server/package.json\";\n if (!vfs.exists(serverPath)) return;\n\n const pkgJson = vfs.readJson<PackageJson>(serverPath);\n if (!pkgJson) return;\n\n pkgJson.scripts = pkgJson.scripts || {};\n\n if (runtime === \"bun\") {\n pkgJson.scripts.dev = \"bun run --hot src/index.ts\";\n pkgJson.scripts.start = \"bun run dist/index.js\";\n\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n devDependencies: [\"@types/bun\"],\n });\n } else if (runtime === \"node\") {\n pkgJson.scripts.dev = \"tsx watch src/index.ts\";\n pkgJson.scripts.start = \"node dist/index.js\";\n\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n devDependencies: [\"tsx\", \"@types/node\"],\n });\n\n if (backend === \"hono\") {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"@hono/node-server\"],\n });\n } else if (backend === \"elysia\") {\n addPackageDependency({\n vfs,\n packagePath: serverPath,\n dependencies: [\"@elysiajs/node\"],\n });\n }\n }\n\n vfs.writeJson(serverPath, pkgJson);\n}\n","import type { Frontend, ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\n// React-based web frameworks that support state management libraries\nconst REACT_WEB_FRAMEWORKS: Frontend[] = [\n \"tanstack-router\",\n \"react-router\",\n \"tanstack-start\",\n \"next\",\n];\n\n// Native frameworks (always React-based)\nconst NATIVE_FRAMEWORKS: Frontend[] = [\"native-bare\", \"native-uniwind\", \"native-unistyles\"];\n\nexport function processStateManagementDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { stateManagement, frontend } = config;\n\n // Skip if not selected or set to \"none\"\n if (!stateManagement || stateManagement === \"none\") return;\n\n // Determine which packages need state management deps\n const hasReactWeb = frontend.some((f) => REACT_WEB_FRAMEWORKS.includes(f));\n const hasNative = frontend.some((f) => NATIVE_FRAMEWORKS.includes(f));\n\n // Add to web package if it's a React-based web frontend\n const webPath = \"apps/web/package.json\";\n if (hasReactWeb && vfs.exists(webPath)) {\n const deps = getStateManagementDeps(stateManagement, \"web\");\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: webPath,\n dependencies: deps,\n });\n }\n }\n\n // Add to native package if it exists\n const nativePath = \"apps/native/package.json\";\n if (hasNative && vfs.exists(nativePath)) {\n const deps = getStateManagementDeps(stateManagement, \"native\");\n if (deps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: nativePath,\n dependencies: deps,\n });\n }\n }\n}\n\nfunction getStateManagementDeps(\n stateManagement: ProjectConfig[\"stateManagement\"],\n _target: \"web\" | \"native\",\n): AvailableDependencies[] {\n const deps: AvailableDependencies[] = [];\n\n switch (stateManagement) {\n case \"zustand\":\n deps.push(\"zustand\");\n break;\n case \"jotai\":\n deps.push(\"jotai\");\n break;\n case \"nanostores\":\n deps.push(\"nanostores\", \"@nanostores/react\");\n break;\n case \"redux-toolkit\":\n deps.push(\"@reduxjs/toolkit\", \"react-redux\");\n break;\n case \"mobx\":\n deps.push(\"mobx\", \"mobx-react-lite\");\n break;\n case \"xstate\":\n deps.push(\"xstate\", \"@xstate/react\");\n break;\n case \"valtio\":\n deps.push(\"valtio\");\n break;\n case \"tanstack-store\":\n deps.push(\"@tanstack/store\", \"@tanstack/react-store\");\n break;\n case \"legend-state\":\n deps.push(\"@legendapp/state\", \"@legendapp/state-react\");\n break;\n }\n\n return deps;\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\n// React-based frontends that can use @testing-library/react\nconst REACT_FRONTENDS = [\n \"tanstack-router\",\n \"react-router\",\n \"tanstack-start\",\n \"next\",\n \"native-bare\",\n \"native-uniwind\",\n \"native-unistyles\",\n \"redwood\",\n \"astro\", // Only when astroIntegration is \"react\"\n] as const;\n\n// Vue-based frontends that can use @testing-library/vue\nconst VUE_FRONTENDS = [\"nuxt\"] as const;\n\n// Svelte frontends that can use @testing-library/svelte\nconst SVELTE_FRONTENDS = [\"svelte\"] as const;\n\n/**\n * Process testing framework dependencies.\n *\n * Adds the appropriate testing framework dependencies based on the selected option:\n * - vitest: Fast unit test framework (default) with Testing Library support\n * - jest: Classic testing framework with Testing Library support\n * - playwright: E2E testing\n * - vitest-playwright: Both unit and E2E testing\n * - cypress: E2E testing with time travel debugging\n *\n * Testing Library is automatically included for compatible frontends (React, Vue, Svelte)\n * when using unit test frameworks (vitest, jest, vitest-playwright).\n */\nexport function processTestingDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { testing, frontend, astroIntegration } = config;\n\n // Skip if not selected or \"none\"\n if (!testing || testing === \"none\") return;\n\n const packages = {\n server: vfs.exists(\"apps/server/package.json\"),\n web: vfs.exists(\"apps/web/package.json\"),\n api: vfs.exists(\"packages/api/package.json\"),\n };\n\n // Get base testing framework dependencies\n const { devDeps: baseDeps } = getTestingDeps(testing);\n\n // Get Testing Library dependencies based on frontend\n const testingLibraryDeps = getTestingLibraryDeps(testing, frontend, astroIntegration);\n\n // Server package gets base testing deps only (no UI testing)\n if (packages.server && baseDeps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: \"apps/server/package.json\",\n devDependencies: baseDeps,\n });\n }\n\n // Web package gets both base testing deps and Testing Library deps\n if (packages.web) {\n const webDeps = [...baseDeps, ...testingLibraryDeps];\n if (webDeps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: \"apps/web/package.json\",\n devDependencies: webDeps,\n });\n }\n }\n\n // API package gets base testing deps only (no UI testing)\n if (packages.api && baseDeps.length > 0) {\n addPackageDependency({\n vfs,\n packagePath: \"packages/api/package.json\",\n devDependencies: baseDeps,\n });\n }\n}\n\n/**\n * Get base testing framework dependencies\n */\nfunction getTestingDeps(testing: ProjectConfig[\"testing\"]): {\n devDeps: AvailableDependencies[];\n} {\n const devDeps: AvailableDependencies[] = [];\n\n switch (testing) {\n case \"vitest\":\n devDeps.push(\"vitest\", \"@vitest/ui\", \"@vitest/coverage-v8\", \"jsdom\");\n break;\n case \"jest\":\n devDeps.push(\"jest\", \"@types/jest\", \"ts-jest\", \"@jest/globals\", \"jest-environment-jsdom\");\n break;\n case \"playwright\":\n devDeps.push(\"@playwright/test\", \"playwright\");\n break;\n case \"vitest-playwright\":\n devDeps.push(\n \"vitest\",\n \"@vitest/ui\",\n \"@vitest/coverage-v8\",\n \"jsdom\",\n \"@playwright/test\",\n \"playwright\",\n );\n break;\n case \"cypress\":\n devDeps.push(\"cypress\");\n break;\n }\n\n return { devDeps };\n}\n\n/**\n * Get Testing Library dependencies based on frontend framework\n * Testing Library is added for unit test frameworks (vitest, jest, vitest-playwright)\n * but not for pure E2E frameworks (playwright-only, cypress)\n */\nfunction getTestingLibraryDeps(\n testing: ProjectConfig[\"testing\"],\n frontend: ProjectConfig[\"frontend\"],\n astroIntegration?: ProjectConfig[\"astroIntegration\"],\n): AvailableDependencies[] {\n // Only add Testing Library for unit test frameworks\n if (!testing || ![\"vitest\", \"jest\", \"vitest-playwright\"].includes(testing)) {\n return [];\n }\n\n const deps: AvailableDependencies[] = [];\n\n // Core Testing Library packages (always included for compatible frontends)\n const addCoreDeps = () => {\n deps.push(\"@testing-library/dom\", \"@testing-library/user-event\");\n\n // Add jest-dom matchers for both Jest and Vitest (works with both)\n if (testing === \"jest\") {\n deps.push(\"@testing-library/jest-dom\");\n } else if (testing === \"vitest\" || testing === \"vitest-playwright\") {\n deps.push(\"@testing-library/jest-dom\");\n }\n };\n\n // Check frontend type and add appropriate framework-specific library\n if (isReactFrontend(frontend, astroIntegration)) {\n addCoreDeps();\n deps.push(\"@testing-library/react\");\n } else if (isVueFrontend(frontend)) {\n addCoreDeps();\n deps.push(\"@testing-library/vue\");\n } else if (isSvelteFrontend(frontend, astroIntegration)) {\n addCoreDeps();\n deps.push(\"@testing-library/svelte\");\n }\n\n return deps;\n}\n\n/**\n * Check if any frontend in the array is React-based\n */\nfunction isReactFrontend(\n frontend: ProjectConfig[\"frontend\"],\n astroIntegration?: ProjectConfig[\"astroIntegration\"],\n): boolean {\n if (!frontend || frontend.length === 0) return false;\n\n // Check each frontend in the array\n return frontend.some((f) => {\n // Astro with React integration\n if (f === \"astro\" && astroIntegration === \"react\") {\n return true;\n }\n\n // Skip Astro with non-React integration\n if (f === \"astro\") {\n return false;\n }\n\n return (REACT_FRONTENDS as readonly string[]).includes(f);\n });\n}\n\n/**\n * Check if any frontend in the array is Vue-based\n */\nfunction isVueFrontend(frontend: ProjectConfig[\"frontend\"]): boolean {\n if (!frontend || frontend.length === 0) return false;\n return frontend.some((f) => (VUE_FRONTENDS as readonly string[]).includes(f));\n}\n\n/**\n * Check if any frontend in the array is Svelte-based\n */\nfunction isSvelteFrontend(\n frontend: ProjectConfig[\"frontend\"],\n astroIntegration?: ProjectConfig[\"astroIntegration\"],\n): boolean {\n if (!frontend || frontend.length === 0) return false;\n\n return frontend.some((f) => {\n // Astro with Svelte integration\n if (f === \"astro\" && astroIntegration === \"svelte\") {\n return true;\n }\n\n return (SVELTE_FRONTENDS as readonly string[]).includes(f);\n });\n}\n","/**\n * Turbo.json Generator - Programmatically generates turbo.json configuration\n * Replaces the previous Handlebars template with type-safe TypeScript generation\n */\n\nimport type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\ninterface TurboTask {\n dependsOn?: string[];\n inputs?: string[];\n outputs?: string[];\n cache?: boolean;\n persistent?: boolean;\n}\n\ninterface TurboConfig {\n $schema: string;\n ui: string;\n tasks: Record<string, TurboTask>;\n}\n\nexport function processTurboConfig(vfs: VirtualFileSystem, config: ProjectConfig): void {\n if (!config.addons.includes(\"turborepo\")) return;\n\n const turboConfig = generateTurboConfig(config);\n vfs.writeFile(\"turbo.json\", JSON.stringify(turboConfig, null, \"\\t\"));\n}\n\nfunction generateTurboConfig(config: ProjectConfig): TurboConfig {\n const { backend, database, orm, dbSetup, webDeploy, serverDeploy, frontend } = config;\n\n const isConvex = backend === \"convex\";\n const hasDatabase = database !== \"none\" && orm !== \"none\";\n const isDocker = dbSetup === \"docker\";\n const isSqliteLocal = database === \"sqlite\" && dbSetup !== \"d1\";\n const hasCloudflare = webDeploy === \"cloudflare\" || serverDeploy === \"cloudflare\";\n\n const tasks: Record<string, TurboTask> = {\n ...getBaseTasks(frontend),\n ...(isConvex ? getConvexTasks() : {}),\n ...(!isConvex && hasDatabase ? getDatabaseTasks() : {}),\n ...(isDocker ? getDockerTasks() : {}),\n ...(isSqliteLocal ? getSqliteLocalTask() : {}),\n ...(hasCloudflare ? getDeployTasks() : {}),\n };\n\n return {\n $schema: \"https://turbo.build/schema.json\",\n ui: \"tui\",\n tasks,\n };\n}\n\nfunction getBaseTasks(frontend: string[]): Record<string, TurboTask> {\n // Build outputs per framework:\n // - Vite-based (tanstack-router, react-router, tanstack-start, solid, svelte): dist/**\n // - Next.js: .next/**\n // - Nuxt: .nuxt/**, .output/**\n const buildOutputs = [\"dist/**\"];\n\n if (frontend.includes(\"next\")) {\n buildOutputs.push(\".next/**\");\n }\n\n if (frontend.includes(\"nuxt\")) {\n buildOutputs.push(\".nuxt/**\", \".output/**\");\n }\n\n // SvelteKit outputs to .svelte-kit/** in addition to build/\n if (frontend.includes(\"svelte\")) {\n buildOutputs.push(\".svelte-kit/**\", \"build/**\");\n }\n\n return {\n build: {\n dependsOn: [\"^build\"],\n inputs: [\"$TURBO_DEFAULT$\", \".env*\"],\n outputs: buildOutputs,\n },\n lint: {\n dependsOn: [\"^lint\"],\n },\n \"check-types\": {\n dependsOn: [\"^check-types\"],\n },\n dev: {\n cache: false,\n persistent: true,\n },\n };\n}\n\nfunction getConvexTasks(): Record<string, TurboTask> {\n return {\n \"dev:setup\": {\n cache: false,\n persistent: true,\n },\n };\n}\n\nfunction getDatabaseTasks(): Record<string, TurboTask> {\n return {\n \"db:push\": {\n cache: false,\n },\n \"db:studio\": {\n cache: false,\n persistent: true,\n },\n \"db:migrate\": {\n cache: false,\n },\n \"db:generate\": {\n cache: false,\n },\n };\n}\n\nfunction getDockerTasks(): Record<string, TurboTask> {\n return {\n \"db:start\": {\n cache: false,\n persistent: true,\n },\n \"db:stop\": {\n cache: false,\n },\n \"db:watch\": {\n cache: false,\n persistent: true,\n },\n \"db:down\": {\n cache: false,\n },\n };\n}\n\nfunction getSqliteLocalTask(): Record<string, TurboTask> {\n return {\n \"db:local\": {\n cache: false,\n },\n };\n}\n\nfunction getDeployTasks(): Record<string, TurboTask> {\n return {\n deploy: {\n cache: false,\n },\n destroy: {\n cache: false,\n },\n };\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\n/**\n * Process validation library dependencies.\n *\n * When Valibot is selected, it adds Valibot to the appropriate packages.\n * Zod is still included by default (via workspace-deps) for internal usage,\n * but Valibot can be used as the primary validation library in user code.\n */\nexport function processValidationDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const { validation } = config;\n\n // Skip if not selected, \"none\", or \"zod\" (zod is added by workspace-deps already)\n if (!validation || validation === \"none\" || validation === \"zod\") return;\n\n const packages = {\n api: vfs.exists(\"packages/api/package.json\"),\n server: vfs.exists(\"apps/server/package.json\"),\n web: vfs.exists(\"apps/web/package.json\"),\n native: vfs.exists(\"apps/native/package.json\"),\n };\n\n const deps = getValidationDeps(validation);\n if (deps.length === 0) return;\n\n // Add validation library to API package (for schema definitions)\n if (packages.api) {\n addPackageDependency({\n vfs,\n packagePath: \"packages/api/package.json\",\n dependencies: deps,\n });\n }\n\n // Add to server package (for server-side validation)\n if (packages.server) {\n addPackageDependency({\n vfs,\n packagePath: \"apps/server/package.json\",\n dependencies: deps,\n });\n }\n\n // Add to web package (for client-side validation)\n if (packages.web) {\n addPackageDependency({\n vfs,\n packagePath: \"apps/web/package.json\",\n dependencies: deps,\n });\n }\n\n // Add to native package (for mobile validation)\n if (packages.native) {\n addPackageDependency({\n vfs,\n packagePath: \"apps/native/package.json\",\n dependencies: deps,\n });\n }\n}\n\nfunction getValidationDeps(validation: ProjectConfig[\"validation\"]): AvailableDependencies[] {\n const deps: AvailableDependencies[] = [];\n\n switch (validation) {\n case \"valibot\":\n deps.push(\"valibot\");\n break;\n case \"arktype\":\n deps.push(\"arktype\");\n break;\n case \"typebox\":\n deps.push(\"@sinclair/typebox\");\n break;\n case \"typia\":\n deps.push(\"typia\");\n break;\n case \"runtypes\":\n deps.push(\"runtypes\");\n break;\n case \"effect-schema\":\n deps.push(\"@effect/schema\");\n deps.push(\"effect\");\n break;\n }\n\n return deps;\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { addPackageDependency, type AvailableDependencies } from \"../utils/add-deps\";\n\nexport function processWorkspaceDeps(vfs: VirtualFileSystem, config: ProjectConfig): void {\n const {\n projectName,\n packageManager,\n runtime,\n backend,\n database,\n auth,\n api,\n serverDeploy,\n webDeploy,\n } = config;\n\n const workspaceVersion = packageManager === \"npm\" ? \"*\" : \"workspace:*\";\n const packages = {\n config: vfs.exists(\"packages/config/package.json\"),\n env: vfs.exists(\"packages/env/package.json\"),\n infra: vfs.exists(\"packages/infra/package.json\"),\n db: vfs.exists(\"packages/db/package.json\"),\n auth: vfs.exists(\"packages/auth/package.json\"),\n api: vfs.exists(\"packages/api/package.json\"),\n backend: vfs.exists(\"packages/backend/package.json\"),\n server: vfs.exists(\"apps/server/package.json\"),\n web: vfs.exists(\"apps/web/package.json\"),\n native: vfs.exists(\"apps/native/package.json\"),\n };\n\n const configDep = packages.config ? { [`@${projectName}/config`]: workspaceVersion } : {};\n const envDep = packages.env ? { [`@${projectName}/env`]: workspaceVersion } : {};\n const isCloudflare = serverDeploy === \"cloudflare\" || webDeploy === \"cloudflare\";\n const runtimeDevDeps = getRuntimeDevDeps(runtime, backend);\n const commonDeps: AvailableDependencies[] = [\"dotenv\", \"zod\"];\n const commonDevDeps: AvailableDependencies[] = [\"typescript\", ...runtimeDevDeps];\n\n addPackageDependency({\n vfs,\n packagePath: \"package.json\",\n dependencies: commonDeps,\n devDependencies: commonDevDeps,\n customDependencies: envDep,\n customDevDependencies: configDep,\n });\n\n if (packages.env) {\n const envDevDeps: Record<string, string> = { ...configDep };\n if (isCloudflare && packages.infra) {\n envDevDeps[`@${projectName}/infra`] = workspaceVersion;\n }\n addPackageDependency({\n vfs,\n packagePath: \"packages/env/package.json\",\n dependencies: commonDeps,\n devDependencies: commonDevDeps,\n customDevDependencies: envDevDeps,\n });\n }\n\n if (packages.infra) {\n addPackageDependency({\n vfs,\n packagePath: \"packages/infra/package.json\",\n dependencies: commonDeps,\n devDependencies: [\"typescript\"],\n customDevDependencies: configDep,\n });\n }\n\n if (packages.db) {\n addPackageDependency({\n vfs,\n packagePath: \"packages/db/package.json\",\n dependencies: commonDeps,\n devDependencies: [\"typescript\"],\n customDependencies: envDep,\n customDevDependencies: configDep,\n });\n }\n\n if (packages.auth) {\n const authDeps: Record<string, string> = { ...envDep };\n if (database !== \"none\" && packages.db) {\n authDeps[`@${projectName}/db`] = workspaceVersion;\n }\n addPackageDependency({\n vfs,\n packagePath: \"packages/auth/package.json\",\n dependencies: commonDeps,\n devDependencies: [\"typescript\"],\n customDependencies: authDeps,\n customDevDependencies: configDep,\n });\n }\n\n if (packages.api) {\n const apiPackageDeps: Record<string, string> = { ...envDep };\n if (auth !== \"none\" && packages.auth) {\n apiPackageDeps[`@${projectName}/auth`] = workspaceVersion;\n }\n if (database !== \"none\" && packages.db) {\n apiPackageDeps[`@${projectName}/db`] = workspaceVersion;\n }\n addPackageDependency({\n vfs,\n packagePath: \"packages/api/package.json\",\n dependencies: commonDeps,\n devDependencies: [\"typescript\"],\n customDependencies: apiPackageDeps,\n customDevDependencies: configDep,\n });\n }\n\n if (packages.backend) {\n addPackageDependency({\n vfs,\n packagePath: \"packages/backend/package.json\",\n dependencies: commonDeps,\n devDependencies: [\"typescript\"],\n customDevDependencies: configDep,\n });\n }\n\n if (packages.server) {\n const serverDeps: Record<string, string> = { ...envDep };\n if (api !== \"none\" && packages.api) serverDeps[`@${projectName}/api`] = workspaceVersion;\n if (auth !== \"none\" && packages.auth) serverDeps[`@${projectName}/auth`] = workspaceVersion;\n if (database !== \"none\" && packages.db) serverDeps[`@${projectName}/db`] = workspaceVersion;\n addPackageDependency({\n vfs,\n packagePath: \"apps/server/package.json\",\n dependencies: commonDeps,\n devDependencies: [\"typescript\", \"tsdown\"],\n customDependencies: serverDeps,\n customDevDependencies: configDep,\n });\n }\n\n if (packages.web) {\n const webPackageDeps: Record<string, string> = { ...envDep };\n if (api !== \"none\" && packages.api) webPackageDeps[`@${projectName}/api`] = workspaceVersion;\n if (auth !== \"none\" && packages.auth) webPackageDeps[`@${projectName}/auth`] = workspaceVersion;\n if (backend === \"convex\" && packages.backend)\n webPackageDeps[`@${projectName}/backend`] = workspaceVersion;\n addPackageDependency({\n vfs,\n packagePath: \"apps/web/package.json\",\n dependencies: commonDeps,\n devDependencies: [\"typescript\"],\n customDependencies: webPackageDeps,\n customDevDependencies: configDep,\n });\n }\n\n if (packages.native) {\n const nativeDeps: Record<string, string> = { ...envDep };\n if (api !== \"none\" && packages.api) nativeDeps[`@${projectName}/api`] = workspaceVersion;\n if (backend === \"convex\" && packages.backend)\n nativeDeps[`@${projectName}/backend`] = workspaceVersion;\n addPackageDependency({\n vfs,\n packagePath: \"apps/native/package.json\",\n dependencies: commonDeps,\n devDependencies: [\"typescript\"],\n customDependencies: nativeDeps,\n customDevDependencies: configDep,\n });\n }\n}\n\nfunction getRuntimeDevDeps(\n runtime: ProjectConfig[\"runtime\"],\n backend: ProjectConfig[\"backend\"],\n): AvailableDependencies[] {\n if (runtime === \"none\" && backend === \"self\") return [\"@types/node\"];\n if (runtime === \"node\" || runtime === \"workers\") return [\"@types/node\"];\n if (runtime === \"bun\") return [\"@types/bun\"];\n return [];\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { processAddonsDeps } from \"./addons-deps\";\nimport { processAlchemyPlugins } from \"./alchemy-plugins\";\nimport { processAnimationDeps } from \"./animation-deps\";\nimport { processApiDeps } from \"./api-deps\";\nimport { processAuthDeps } from \"./auth-deps\";\nimport { processAuthPlugins } from \"./auth-plugins\";\nimport { processBackendDeps } from \"./backend-deps\";\nimport { processCachingDeps } from \"./caching-deps\";\nimport { processCMSDeps } from \"./cms-deps\";\nimport { processCSSAndUILibraryDeps } from \"./css-ui-deps\";\nimport { processDatabaseDeps } from \"./db-deps\";\nimport { processDeployDeps } from \"./deploy-deps\";\nimport { processEffectDeps } from \"./effect-deps\";\nimport { processEmailDeps } from \"./email-deps\";\nimport { processEnvDeps } from \"./env-deps\";\nimport { processEnvVariables } from \"./env-vars\";\nimport { processExamplesDeps } from \"./examples-deps\";\nimport { processFileUploadDeps } from \"./file-upload-deps\";\nimport { processFormsDeps } from \"./forms-deps\";\nimport { processInfraDeps } from \"./infra-deps\";\nimport { processJobQueueDeps } from \"./job-queue-deps\";\nimport { processLoggingDeps } from \"./logging-deps\";\nimport { processObservabilityDeps } from \"./observability-deps\";\nimport { processPaymentsDeps } from \"./payments-deps\";\nimport { processPwaPlugins } from \"./pwa-plugins\";\nimport { processReadme } from \"./readme-generator\";\nimport { processRealtimeDeps } from \"./realtime-deps\";\nimport { processRuntimeDeps } from \"./runtime-deps\";\nimport { processStateManagementDeps } from \"./state-management-deps\";\nimport { processTestingDeps } from \"./testing-deps\";\nimport { processTurboConfig } from \"./turbo-generator\";\nimport { processValidationDeps } from \"./validation-deps\";\nimport { processWorkspaceDeps } from \"./workspace-deps\";\n\nexport function processDependencies(vfs: VirtualFileSystem, config: ProjectConfig): void {\n processWorkspaceDeps(vfs, config);\n processEnvDeps(vfs, config);\n processInfraDeps(vfs, config);\n processDatabaseDeps(vfs, config);\n processBackendDeps(vfs, config);\n processRuntimeDeps(vfs, config);\n processApiDeps(vfs, config);\n processAuthDeps(vfs, config);\n processPaymentsDeps(vfs, config);\n processEmailDeps(vfs, config);\n processFileUploadDeps(vfs, config);\n processDeployDeps(vfs, config);\n processAddonsDeps(vfs, config);\n processExamplesDeps(vfs, config);\n processEffectDeps(vfs, config);\n processStateManagementDeps(vfs, config);\n processFormsDeps(vfs, config);\n processValidationDeps(vfs, config);\n processRealtimeDeps(vfs, config);\n processJobQueueDeps(vfs, config);\n processAnimationDeps(vfs, config);\n processTestingDeps(vfs, config);\n processLoggingDeps(vfs, config);\n processObservabilityDeps(vfs, config);\n processCSSAndUILibraryDeps(vfs, config);\n processCMSDeps(vfs, config);\n processCachingDeps(vfs, config);\n processTurboConfig(vfs, config);\n}\n\nexport {\n processAddonsDeps,\n processAnimationDeps,\n processApiDeps,\n processAuthDeps,\n processBackendDeps,\n processCachingDeps,\n processCMSDeps,\n processCSSAndUILibraryDeps,\n processDatabaseDeps,\n processDeployDeps,\n processEffectDeps,\n processEmailDeps,\n processEnvDeps,\n processFileUploadDeps,\n processExamplesDeps,\n processFormsDeps,\n processInfraDeps,\n processJobQueueDeps,\n processLoggingDeps,\n processObservabilityDeps,\n processPaymentsDeps,\n processReadme,\n processRealtimeDeps,\n processRuntimeDeps,\n processStateManagementDeps,\n processTestingDeps,\n processValidationDeps,\n processTurboConfig,\n processWorkspaceDeps,\n processAuthPlugins,\n processAlchemyPlugins,\n processPwaPlugins,\n processEnvVariables,\n};\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { processTemplateString, transformFilename, isBinaryFile } from \"../core/template-processor\";\n\nexport type TemplateData = Map<string, string>;\n\nexport function hasTemplatesWithPrefix(templates: TemplateData, prefix: string): boolean {\n const normalizedPrefix = prefix.endsWith(\"/\") ? prefix : `${prefix}/`;\n for (const path of templates.keys()) {\n if (path.startsWith(normalizedPrefix)) return true;\n }\n return false;\n}\n\nexport function processSingleTemplate(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n templatePath: string,\n destPath: string,\n config: ProjectConfig,\n): void {\n const templateKey = templatePath.endsWith(\".hbs\") ? templatePath : `${templatePath}.hbs`;\n const content = templates.get(templateKey);\n\n if (!content) return;\n\n let processedContent: string;\n if (isBinaryFile(templateKey)) {\n processedContent = \"[Binary file]\";\n } else if (templateKey.endsWith(\".hbs\")) {\n processedContent = processTemplateString(content, config);\n } else {\n processedContent = content;\n }\n\n // Pass original template path for binary files\n const sourcePath = isBinaryFile(templateKey) ? templateKey : undefined;\n vfs.writeFile(destPath, processedContent, sourcePath);\n}\n\nexport function processTemplatesFromPrefix(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n prefix: string,\n destPrefix: string,\n config: ProjectConfig,\n): void {\n const normalizedPrefix = prefix.endsWith(\"/\") ? prefix : `${prefix}/`;\n\n for (const [templatePath, content] of templates) {\n if (!templatePath.startsWith(normalizedPrefix)) continue;\n\n const relativePath = templatePath.slice(normalizedPrefix.length);\n const outputPath = transformFilename(relativePath);\n const destPath = destPrefix ? `${destPrefix}/${outputPath}` : outputPath;\n\n let processedContent: string;\n if (isBinaryFile(templatePath)) {\n processedContent = \"[Binary file]\";\n } else if (templatePath.endsWith(\".hbs\")) {\n processedContent = processTemplateString(content, config);\n } else {\n processedContent = content;\n }\n\n // Pass original template path for binary files\n const sourcePath = isBinaryFile(templatePath) ? templatePath : undefined;\n vfs.writeFile(destPath, processedContent, sourcePath);\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processBaseTemplate(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n processTemplatesFromPrefix(vfs, templates, \"base\", \"\", config);\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\nimport type { TemplateData } from \"./utils\";\n\nimport { isBinaryFile, processTemplateString, transformFilename } from \"../core/template-processor\";\n\nexport async function processRustBaseTemplate(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n // Only process Rust templates if ecosystem is \"rust\"\n if (config.ecosystem !== \"rust\") return;\n\n const prefix = \"rust-base/\";\n const hasLeptos = config.rustFrontend === \"leptos\";\n const hasDioxus = config.rustFrontend === \"dioxus\";\n const hasTonic = config.rustApi === \"tonic\";\n const hasAsyncGraphql = config.rustApi === \"async-graphql\";\n const hasClap = config.rustCli === \"clap\";\n const hasRatatui = config.rustCli === \"ratatui\";\n\n for (const [templatePath, content] of templates) {\n if (!templatePath.startsWith(prefix)) continue;\n\n // Skip client crate templates if Leptos is not selected\n if (!hasLeptos && templatePath.includes(\"crates/client/\")) continue;\n\n // Skip dioxus-client crate templates if Dioxus is not selected\n if (!hasDioxus && templatePath.includes(\"crates/dioxus-client/\")) continue;\n\n // Skip proto crate templates if Tonic is not selected\n if (!hasTonic && templatePath.includes(\"crates/proto/\")) continue;\n\n // Skip grpc.rs if Tonic is not selected\n if (!hasTonic && templatePath.includes(\"crates/server/src/grpc.rs\")) continue;\n\n // Skip graphql.rs if async-graphql is not selected\n if (!hasAsyncGraphql && templatePath.includes(\"crates/server/src/graphql.rs\")) continue;\n\n // Skip cli crate templates if Clap is not selected\n if (!hasClap && templatePath.includes(\"crates/cli/\")) continue;\n\n // Skip tui crate templates if Ratatui is not selected\n if (!hasRatatui && templatePath.includes(\"crates/tui/\")) continue;\n\n const relativePath = templatePath.slice(prefix.length);\n const outputPath = transformFilename(relativePath);\n\n let processedContent: string;\n if (isBinaryFile(templatePath)) {\n processedContent = \"[Binary file]\";\n } else if (templatePath.endsWith(\".hbs\")) {\n processedContent = processTemplateString(content, config);\n } else {\n processedContent = content;\n }\n\n // Pass original template path for binary files\n const sourcePath = isBinaryFile(templatePath) ? templatePath : undefined;\n vfs.writeFile(outputPath, processedContent, sourcePath);\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processFrontendTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n const hasReactWeb = config.frontend.some((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n const hasNuxtWeb = config.frontend.includes(\"nuxt\");\n const hasSvelteWeb = config.frontend.includes(\"svelte\");\n const hasSolidWeb = config.frontend.includes(\"solid\");\n const hasAstroWeb = config.frontend.includes(\"astro\");\n const hasQwikWeb = config.frontend.includes(\"qwik\");\n const hasAngularWeb = config.frontend.includes(\"angular\");\n const hasRedwoodWeb = config.frontend.includes(\"redwood\");\n const hasFreshWeb = config.frontend.includes(\"fresh\");\n const hasNativeBare = config.frontend.includes(\"native-bare\");\n const hasNativeUniwind = config.frontend.includes(\"native-uniwind\");\n const hasUnistyles = config.frontend.includes(\"native-unistyles\");\n const isConvex = config.backend === \"convex\";\n\n if (\n hasReactWeb ||\n hasNuxtWeb ||\n hasSvelteWeb ||\n hasSolidWeb ||\n hasAstroWeb ||\n hasQwikWeb ||\n hasAngularWeb ||\n hasRedwoodWeb ||\n hasFreshWeb\n ) {\n if (hasReactWeb) {\n processTemplatesFromPrefix(vfs, templates, \"frontend/react/web-base\", \"apps/web\", config);\n\n const reactFramework = config.frontend.find((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n if (reactFramework) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `frontend/react/${reactFramework}`,\n \"apps/web\",\n config,\n );\n }\n } else if (hasNuxtWeb) {\n processTemplatesFromPrefix(vfs, templates, \"frontend/nuxt\", \"apps/web\", config);\n } else if (hasSvelteWeb) {\n processTemplatesFromPrefix(vfs, templates, \"frontend/svelte\", \"apps/web\", config);\n } else if (hasSolidWeb) {\n processTemplatesFromPrefix(vfs, templates, \"frontend/solid\", \"apps/web\", config);\n } else if (hasAstroWeb) {\n // Process base Astro templates\n processTemplatesFromPrefix(vfs, templates, \"frontend/astro\", \"apps/web\", config);\n\n // Process integration-specific templates (React, Vue, Svelte, Solid)\n if (config.astroIntegration && config.astroIntegration !== \"none\") {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `frontend/astro/integrations/${config.astroIntegration}`,\n \"apps/web\",\n config,\n );\n }\n } else if (hasQwikWeb) {\n processTemplatesFromPrefix(vfs, templates, \"frontend/qwik\", \"apps/web\", config);\n } else if (hasAngularWeb) {\n processTemplatesFromPrefix(vfs, templates, \"frontend/angular\", \"apps/web\", config);\n } else if (hasRedwoodWeb) {\n // RedwoodJS has its own monorepo structure at the root level\n processTemplatesFromPrefix(vfs, templates, \"frontend/redwood\", \".\", config);\n } else if (hasFreshWeb) {\n // Fresh (Deno) outputs to apps/web like other frameworks\n processTemplatesFromPrefix(vfs, templates, \"frontend/fresh\", \"apps/web\", config);\n }\n }\n\n if (hasNativeBare || hasNativeUniwind || hasUnistyles) {\n processTemplatesFromPrefix(vfs, templates, \"frontend/native/base\", \"apps/native\", config);\n\n if (hasNativeBare) {\n processTemplatesFromPrefix(vfs, templates, \"frontend/native/bare\", \"apps/native\", config);\n } else if (hasNativeUniwind) {\n processTemplatesFromPrefix(vfs, templates, \"frontend/native/uniwind\", \"apps/native\", config);\n } else if (hasUnistyles) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n \"frontend/native/unistyles\",\n \"apps/native\",\n config,\n );\n }\n\n if (!isConvex && (config.api === \"trpc\" || config.api === \"orpc\" || config.api === \"ts-rest\")) {\n processTemplatesFromPrefix(vfs, templates, `api/${config.api}/native`, \"apps/native\", config);\n }\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processBackendTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n if (config.backend === \"none\") return;\n\n if (config.backend === \"convex\") {\n processTemplatesFromPrefix(\n vfs,\n templates,\n \"backend/convex/packages/backend\",\n \"packages/backend\",\n config,\n );\n return;\n }\n\n if (config.backend === \"self\") return;\n\n if (config.backend === \"encore\") {\n processTemplatesFromPrefix(vfs, templates, \"backend/server/encore\", \"apps/server\", config);\n return;\n }\n\n if (config.backend === \"adonisjs\") {\n processTemplatesFromPrefix(vfs, templates, \"backend/server/adonisjs\", \"apps/server\", config);\n return;\n }\n\n if (config.backend === \"nitro\") {\n processTemplatesFromPrefix(vfs, templates, \"backend/server/nitro\", \"apps/server\", config);\n return;\n }\n\n if (config.backend === \"fets\") {\n processTemplatesFromPrefix(vfs, templates, \"backend/server/base\", \"apps/server\", config);\n processTemplatesFromPrefix(vfs, templates, \"backend/server/fets\", \"apps/server\", config);\n return;\n }\n\n processTemplatesFromPrefix(vfs, templates, \"backend/server/base\", \"apps/server\", config);\n processTemplatesFromPrefix(\n vfs,\n templates,\n `backend/server/${config.backend}`,\n \"apps/server\",\n config,\n );\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processDbTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n if (config.database === \"none\" || config.orm === \"none\") return;\n if (config.backend === \"convex\") return;\n\n processTemplatesFromPrefix(vfs, templates, \"db/base\", \"packages/db\", config);\n processTemplatesFromPrefix(vfs, templates, `db/${config.orm}/base`, \"packages/db\", config);\n processTemplatesFromPrefix(\n vfs,\n templates,\n `db/${config.orm}/${config.database}`,\n \"packages/db\",\n config,\n );\n\n if (config.dbSetup === \"docker\") {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `db-setup/docker-compose/${config.database}`,\n \"packages/db\",\n config,\n );\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processApiTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n if (config.api === \"none\") return;\n if (config.backend === \"convex\") return;\n\n processTemplatesFromPrefix(vfs, templates, `api/${config.api}/server`, \"packages/api\", config);\n\n const hasReactWeb = config.frontend.some((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n const hasNuxtWeb = config.frontend.includes(\"nuxt\");\n const hasSvelteWeb = config.frontend.includes(\"svelte\");\n const hasSolidWeb = config.frontend.includes(\"solid\");\n const hasAstroWeb = config.frontend.includes(\"astro\");\n\n if (hasReactWeb) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `api/${config.api}/web/react/base`,\n \"apps/web\",\n config,\n );\n\n const reactFramework = config.frontend.find((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n if (\n config.backend === \"self\" &&\n (reactFramework === \"next\" || reactFramework === \"tanstack-start\")\n ) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `api/${config.api}/fullstack/${reactFramework}`,\n \"apps/web\",\n config,\n );\n }\n } else if (hasAstroWeb) {\n // Astro with React integration can use tRPC or oRPC\n if (config.astroIntegration === \"react\") {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `api/${config.api}/web/react/base`,\n \"apps/web\",\n config,\n );\n } else if (config.api === \"orpc\" || config.api === \"garph\") {\n // Non-React Astro integrations use oRPC or Garph\n processTemplatesFromPrefix(vfs, templates, `api/${config.api}/web/astro`, \"apps/web\", config);\n }\n\n // Astro fullstack mode\n if (config.backend === \"self\") {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `api/${config.api}/fullstack/astro`,\n \"apps/web\",\n config,\n );\n }\n } else if (hasNuxtWeb && config.api === \"orpc\") {\n processTemplatesFromPrefix(vfs, templates, `api/${config.api}/web/nuxt`, \"apps/web\", config);\n } else if (hasSvelteWeb && config.api === \"orpc\") {\n processTemplatesFromPrefix(vfs, templates, `api/${config.api}/web/svelte`, \"apps/web\", config);\n } else if (hasSolidWeb && config.api === \"orpc\") {\n processTemplatesFromPrefix(vfs, templates, `api/${config.api}/web/solid`, \"apps/web\", config);\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processConfigPackage(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n processTemplatesFromPrefix(vfs, templates, \"packages/config\", \"packages/config\", config);\n}\n\nexport async function processEnvPackage(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n const hasWebFrontend = config.frontend.some((f) =>\n [\n \"tanstack-router\",\n \"react-router\",\n \"tanstack-start\",\n \"next\",\n \"nuxt\",\n \"svelte\",\n \"solid\",\n ].includes(f),\n );\n const hasNative = config.frontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n\n if (!hasWebFrontend && !hasNative && config.backend === \"none\") return;\n\n processTemplatesFromPrefix(vfs, templates, \"packages/env\", \"packages/env\", config);\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { processTemplatesFromPrefix, type TemplateData } from \"./utils\";\n\nexport async function processAuthTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n if (!config.auth || config.auth === \"none\") return;\n\n const hasReactWeb = config.frontend.some((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n const hasNuxtWeb = config.frontend.includes(\"nuxt\");\n const hasSvelteWeb = config.frontend.includes(\"svelte\");\n const hasSolidWeb = config.frontend.includes(\"solid\");\n const hasNativeBare = config.frontend.includes(\"native-bare\");\n const hasUniwind = config.frontend.includes(\"native-uniwind\");\n const hasUnistyles = config.frontend.includes(\"native-unistyles\");\n const hasNative = hasNativeBare || hasUniwind || hasUnistyles;\n\n const authProvider = config.auth;\n\n if (config.backend === \"convex\" && authProvider === \"clerk\") {\n processTemplatesFromPrefix(\n vfs,\n templates,\n \"auth/clerk/convex/backend\",\n \"packages/backend\",\n config,\n );\n\n if (hasReactWeb) {\n const reactFramework = config.frontend.find((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n if (reactFramework) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `auth/clerk/convex/web/react/${reactFramework}`,\n \"apps/web\",\n config,\n );\n }\n }\n\n if (hasNative) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n \"auth/clerk/convex/native/base\",\n \"apps/native\",\n config,\n );\n\n let nativeFramework = \"\";\n if (hasNativeBare) nativeFramework = \"bare\";\n else if (hasUniwind) nativeFramework = \"uniwind\";\n else if (hasUnistyles) nativeFramework = \"unistyles\";\n\n if (nativeFramework) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `auth/clerk/convex/native/${nativeFramework}`,\n \"apps/native\",\n config,\n );\n }\n }\n return;\n }\n\n if (config.backend === \"convex\" && authProvider === \"better-auth\") {\n processTemplatesFromPrefix(\n vfs,\n templates,\n \"auth/better-auth/convex/backend\",\n \"packages/backend\",\n config,\n );\n\n if (hasReactWeb) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n \"auth/better-auth/convex/web/react/base\",\n \"apps/web\",\n config,\n );\n\n const reactFramework = config.frontend.find((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n if (reactFramework) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `auth/better-auth/convex/web/react/${reactFramework}`,\n \"apps/web\",\n config,\n );\n }\n }\n\n if (hasNative) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n \"auth/better-auth/convex/native/base\",\n \"apps/native\",\n config,\n );\n\n let nativeFramework = \"\";\n if (hasNativeBare) nativeFramework = \"bare\";\n else if (hasUniwind) nativeFramework = \"uniwind\";\n else if (hasUnistyles) nativeFramework = \"unistyles\";\n\n if (nativeFramework) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `auth/better-auth/convex/native/${nativeFramework}`,\n \"apps/native\",\n config,\n );\n }\n }\n return;\n }\n\n // NextAuth is specifically for Next.js fullstack (self backend)\n if (\n authProvider === \"nextauth\" &&\n config.backend === \"self\" &&\n config.frontend.includes(\"next\")\n ) {\n // Process fullstack templates (auth config and API route)\n processTemplatesFromPrefix(vfs, templates, \"auth/nextauth/fullstack/next\", \"apps/web\", config);\n\n // Process web templates (components and client utilities)\n processTemplatesFromPrefix(vfs, templates, \"auth/nextauth/web/react/next\", \"apps/web\", config);\n\n // Process database schema templates if ORM is configured\n if (config.orm !== \"none\" && config.database !== \"none\") {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `auth/nextauth/server/db/${config.orm}/${config.database}`,\n \"packages/db\",\n config,\n );\n }\n return;\n }\n\n if (config.backend !== \"convex\" && config.backend !== \"none\") {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `auth/${authProvider}/server/base`,\n \"packages/auth\",\n config,\n );\n\n if (config.orm !== \"none\" && config.database !== \"none\") {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `auth/${authProvider}/server/db/${config.orm}/${config.database}`,\n \"packages/db\",\n config,\n );\n }\n }\n\n if (hasReactWeb) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `auth/${authProvider}/web/react/base`,\n \"apps/web\",\n config,\n );\n\n const reactFramework = config.frontend.find((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n if (reactFramework) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `auth/${authProvider}/web/react/${reactFramework}`,\n \"apps/web\",\n config,\n );\n\n if (\n config.backend === \"self\" &&\n (reactFramework === \"next\" || reactFramework === \"tanstack-start\")\n ) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `auth/${authProvider}/fullstack/${reactFramework}`,\n \"apps/web\",\n config,\n );\n }\n }\n } else if (hasNuxtWeb) {\n processTemplatesFromPrefix(vfs, templates, `auth/${authProvider}/web/nuxt`, \"apps/web\", config);\n } else if (hasSvelteWeb) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `auth/${authProvider}/web/svelte`,\n \"apps/web\",\n config,\n );\n } else if (hasSolidWeb) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `auth/${authProvider}/web/solid`,\n \"apps/web\",\n config,\n );\n }\n\n if (hasNative) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `auth/${authProvider}/native/base`,\n \"apps/native\",\n config,\n );\n\n let nativeFramework = \"\";\n if (hasNativeBare) nativeFramework = \"bare\";\n else if (hasUniwind) nativeFramework = \"uniwind\";\n else if (hasUnistyles) nativeFramework = \"unistyles\";\n\n if (nativeFramework) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `auth/${authProvider}/native/${nativeFramework}`,\n \"apps/native\",\n config,\n );\n }\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processPaymentsTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n if (!config.payments || config.payments === \"none\") return;\n if (config.backend === \"convex\") return;\n\n const hasReactWeb = config.frontend.some((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n const hasNuxtWeb = config.frontend.includes(\"nuxt\");\n const hasSvelteWeb = config.frontend.includes(\"svelte\");\n const hasSolidWeb = config.frontend.includes(\"solid\");\n\n if (config.backend !== \"none\") {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `payments/${config.payments}/server/base`,\n \"packages/auth\",\n config,\n );\n }\n\n if (hasReactWeb) {\n const reactFramework = config.frontend.find((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n if (reactFramework) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `payments/${config.payments}/web/react/${reactFramework}`,\n \"apps/web\",\n config,\n );\n }\n } else if (hasNuxtWeb) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `payments/${config.payments}/web/nuxt`,\n \"apps/web\",\n config,\n );\n } else if (hasSvelteWeb) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `payments/${config.payments}/web/svelte`,\n \"apps/web\",\n config,\n );\n } else if (hasSolidWeb) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `payments/${config.payments}/web/solid`,\n \"apps/web\",\n config,\n );\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processEmailTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n if (!config.email || config.email === \"none\") return;\n if (config.backend === \"convex\") return;\n if (config.backend === \"none\") return;\n\n // Process server-side email templates (Resend client, email sending utilities)\n processTemplatesFromPrefix(\n vfs,\n templates,\n `email/${config.email}/server/base`,\n \"apps/server\",\n config,\n );\n\n // Process React Email components for React-based frontends\n const hasReactWeb = config.frontend.some((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n\n if (hasReactWeb && (config.email === \"resend\" || config.email === \"react-email\")) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `email/${config.email}/components`,\n \"apps/server\",\n config,\n );\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processAddonTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n if (!config.addons || config.addons.length === 0) return;\n\n for (const addon of config.addons) {\n if (addon === \"none\") continue;\n\n // turborepo is handled programmatically by turbo-generator.ts\n if (addon === \"turborepo\") continue;\n\n if (addon === \"pwa\") {\n if (config.frontend.includes(\"next\")) {\n processTemplatesFromPrefix(vfs, templates, \"addons/pwa/apps/web/next\", \"apps/web\", config);\n } else if (\n config.frontend.some((f) => [\"tanstack-router\", \"react-router\", \"solid\"].includes(f))\n ) {\n processTemplatesFromPrefix(vfs, templates, \"addons/pwa/apps/web/vite\", \"apps/web\", config);\n }\n continue;\n }\n\n // MSW templates - only add to existing packages\n if (addon === \"msw\") {\n if (vfs.exists(\"apps/web/package.json\")) {\n processTemplatesFromPrefix(vfs, templates, \"addons/msw/apps/web\", \"apps/web\", config);\n }\n if (vfs.exists(\"apps/server/package.json\")) {\n processTemplatesFromPrefix(vfs, templates, \"addons/msw/apps/server\", \"apps/server\", config);\n }\n continue;\n }\n\n // Storybook templates - only add to existing web packages\n if (addon === \"storybook\") {\n if (vfs.exists(\"apps/web/package.json\")) {\n processTemplatesFromPrefix(vfs, templates, \"addons/storybook/apps/web\", \"apps/web\", config);\n }\n continue;\n }\n\n processTemplatesFromPrefix(vfs, templates, `addons/${addon}`, \"\", config);\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processExampleTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n if (!config.examples || config.examples.length === 0 || config.examples[0] === \"none\") return;\n\n const hasReactWeb = config.frontend.some((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n );\n const hasNuxtWeb = config.frontend.includes(\"nuxt\");\n const hasSvelteWeb = config.frontend.includes(\"svelte\");\n const hasSolidWeb = config.frontend.includes(\"solid\");\n const hasNativeBare = config.frontend.includes(\"native-bare\");\n const hasUniwind = config.frontend.includes(\"native-uniwind\");\n const hasUnistyles = config.frontend.includes(\"native-unistyles\");\n const hasNative = hasNativeBare || hasUniwind || hasUnistyles;\n\n for (const example of config.examples) {\n if (example === \"none\") continue;\n\n if (config.backend === \"convex\") {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `examples/${example}/convex/packages/backend`,\n \"packages/backend\",\n config,\n );\n } else if (config.backend !== \"none\" && config.api !== \"none\") {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `examples/${example}/server/${config.orm}/base`,\n \"packages/api\",\n config,\n );\n\n if (config.orm !== \"none\" && config.database !== \"none\") {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `examples/${example}/server/${config.orm}/${config.database}`,\n \"packages/db\",\n config,\n );\n }\n }\n\n if (hasReactWeb) {\n const reactFramework = config.frontend.find((f) =>\n [\"next\", \"react-router\", \"tanstack-router\", \"tanstack-start\"].includes(f),\n );\n if (reactFramework) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `examples/${example}/web/react/${reactFramework}`,\n \"apps/web\",\n config,\n );\n\n if (\n config.backend === \"self\" &&\n (reactFramework === \"next\" || reactFramework === \"tanstack-start\")\n ) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `examples/${example}/fullstack/${reactFramework}`,\n \"apps/web\",\n config,\n );\n }\n }\n } else if (hasNuxtWeb) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `examples/${example}/web/nuxt`,\n \"apps/web\",\n config,\n );\n } else if (hasSvelteWeb) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `examples/${example}/web/svelte`,\n \"apps/web\",\n config,\n );\n } else if (hasSolidWeb) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `examples/${example}/web/solid`,\n \"apps/web\",\n config,\n );\n }\n\n if (hasNative) {\n let nativeFramework = \"\";\n if (hasNativeBare) nativeFramework = \"bare\";\n else if (hasUniwind) nativeFramework = \"uniwind\";\n else if (hasUnistyles) nativeFramework = \"unistyles\";\n\n if (nativeFramework) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `examples/${example}/native/${nativeFramework}`,\n \"apps/native\",\n config,\n );\n }\n }\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport {\n type TemplateData,\n hasTemplatesWithPrefix,\n processTemplatesFromPrefix,\n processSingleTemplate,\n} from \"./utils\";\n\nexport async function processExtrasTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n const hasNative = config.frontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n const hasNuxt = config.frontend.includes(\"nuxt\");\n\n if (config.packageManager === \"pnpm\") {\n if (hasTemplatesWithPrefix(templates, \"extras\")) {\n processTemplatesFromPrefix(vfs, templates, \"extras/pnpm-workspace.yaml\", \"\", config);\n }\n }\n\n if (config.packageManager === \"bun\") {\n processTemplatesFromPrefix(vfs, templates, \"extras/bunfig.toml\", \"\", config);\n }\n\n if (config.packageManager === \"pnpm\" && (hasNative || hasNuxt)) {\n processTemplatesFromPrefix(vfs, templates, \"extras/_npmrc\", \"\", config);\n }\n\n if (config.serverDeploy === \"cloudflare\") {\n processSingleTemplate(vfs, templates, \"extras/env.d.ts\", \"packages/env/env.d.ts\", config);\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processDeployTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n const isBackendSelf = config.backend === \"self\";\n\n if (config.webDeploy === \"cloudflare\" || config.serverDeploy === \"cloudflare\") {\n processTemplatesFromPrefix(vfs, templates, \"packages/infra\", \"packages/infra\", config);\n }\n\n if (config.webDeploy !== \"none\" && config.webDeploy !== \"cloudflare\") {\n const templateMap: Record<string, string> = {\n \"tanstack-router\": \"react/tanstack-router\",\n \"tanstack-start\": \"react/tanstack-start\",\n \"react-router\": \"react/react-router\",\n solid: \"solid\",\n next: \"react/next\",\n nuxt: \"nuxt\",\n svelte: \"svelte\",\n };\n\n for (const f of config.frontend) {\n if (templateMap[f]) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `deploy/${config.webDeploy}/web/${templateMap[f]}`,\n \"apps/web\",\n config,\n );\n }\n }\n }\n\n if (config.serverDeploy !== \"none\" && config.serverDeploy !== \"cloudflare\" && !isBackendSelf) {\n processTemplatesFromPrefix(\n vfs,\n templates,\n `deploy/${config.serverDeploy}/server`,\n \"apps/server\",\n config,\n );\n }\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processLoggingTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n if (!config.logging || config.logging === \"none\") return;\n if (config.backend === \"convex\") return;\n if (config.backend === \"none\") return;\n\n // Process server-side logging templates (Pino logger setup)\n processTemplatesFromPrefix(\n vfs,\n templates,\n `logging/${config.logging}/server/base`,\n \"apps/server\",\n config,\n );\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processObservabilityTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n if (!config.observability || config.observability === \"none\") return;\n if (config.backend === \"convex\") return;\n if (config.backend === \"none\") return;\n\n // Process server-side observability templates (OpenTelemetry tracing setup)\n processTemplatesFromPrefix(\n vfs,\n templates,\n `observability/${config.observability}/server/base`,\n \"apps/server\",\n config,\n );\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processJobQueueTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n if (!config.jobQueue || config.jobQueue === \"none\") return;\n if (config.backend === \"convex\") return;\n if (config.backend === \"none\") return;\n\n // Process server-side job queue templates\n processTemplatesFromPrefix(\n vfs,\n templates,\n `job-queue/${config.jobQueue}/server/base`,\n \"apps/server\",\n config,\n );\n}\n","import type { ProjectConfig } from \"@better-fullstack/types\";\n\nimport type { VirtualFileSystem } from \"../core/virtual-fs\";\n\nimport { type TemplateData, processTemplatesFromPrefix } from \"./utils\";\n\nexport async function processCMSTemplates(\n vfs: VirtualFileSystem,\n templates: TemplateData,\n config: ProjectConfig,\n): Promise<void> {\n if (!config.cms || config.cms === \"none\") return;\n\n // Both Payload and Sanity require Next.js for optimal integration\n const hasNext = config.frontend.includes(\"next\");\n\n if (config.cms === \"payload\" && hasNext) {\n // Process Payload CMS templates for Next.js\n processTemplatesFromPrefix(vfs, templates, \"cms/payload/web/next\", \"apps/web\", config);\n }\n\n if (config.cms === \"sanity\" && hasNext) {\n // Process Sanity CMS templates for Next.js\n processTemplatesFromPrefix(vfs, templates, \"cms/sanity/web/next\", \"apps/web\", config);\n }\n\n if (config.cms === \"strapi\" && hasNext) {\n // Process Strapi CMS templates for Next.js\n processTemplatesFromPrefix(vfs, templates, \"cms/strapi/web/next\", \"apps/web\", config);\n }\n}\n","import type { GeneratorOptions, GeneratorResult, VirtualFileTree } from \"./types\";\n\nimport { VirtualFileSystem } from \"./core/virtual-fs\";\nimport { processCatalogs, processPackageConfigs } from \"./post-process\";\nimport {\n processDependencies,\n processReadme,\n processAuthPlugins,\n processAlchemyPlugins,\n processPwaPlugins,\n processEnvVariables,\n} from \"./processors\";\nimport {\n type TemplateData,\n processBaseTemplate,\n processRustBaseTemplate,\n processFrontendTemplates,\n processBackendTemplates,\n processDbTemplates,\n processApiTemplates,\n processConfigPackage,\n processEnvPackage,\n processAuthTemplates,\n processPaymentsTemplates,\n processEmailTemplates,\n processAddonTemplates,\n processExampleTemplates,\n processExtrasTemplates,\n processDeployTemplates,\n processLoggingTemplates,\n processObservabilityTemplates,\n processJobQueueTemplates,\n processCMSTemplates,\n} from \"./template-handlers\";\n\nexport type { TemplateData };\n\nexport async function generateVirtualProject(options: GeneratorOptions): Promise<GeneratorResult> {\n try {\n const { config, templates } = options;\n\n if (!templates || templates.size === 0) {\n return {\n success: false,\n error: \"No templates provided. Templates must be passed via the templates option.\",\n };\n }\n\n const vfs = new VirtualFileSystem();\n\n // Process base templates based on ecosystem\n if (config.ecosystem === \"rust\") {\n // Rust ecosystem - use Cargo.toml and Rust project structure\n await processRustBaseTemplate(vfs, templates, config);\n } else {\n // TypeScript ecosystem - use package.json and TypeScript project structure\n await processBaseTemplate(vfs, templates, config);\n await processFrontendTemplates(vfs, templates, config);\n await processBackendTemplates(vfs, templates, config);\n await processDbTemplates(vfs, templates, config);\n await processApiTemplates(vfs, templates, config);\n await processConfigPackage(vfs, templates, config);\n await processEnvPackage(vfs, templates, config);\n await processAuthTemplates(vfs, templates, config);\n await processPaymentsTemplates(vfs, templates, config);\n await processEmailTemplates(vfs, templates, config);\n await processAddonTemplates(vfs, templates, config);\n await processExampleTemplates(vfs, templates, config);\n await processExtrasTemplates(vfs, templates, config);\n await processDeployTemplates(vfs, templates, config);\n await processLoggingTemplates(vfs, templates, config);\n await processObservabilityTemplates(vfs, templates, config);\n await processJobQueueTemplates(vfs, templates, config);\n await processCMSTemplates(vfs, templates, config);\n\n processPackageConfigs(vfs, config);\n processDependencies(vfs, config);\n processEnvVariables(vfs, config);\n processAuthPlugins(vfs, config);\n processAlchemyPlugins(vfs, config);\n processPwaPlugins(vfs, config);\n processCatalogs(vfs, config);\n }\n\n processReadme(vfs, config);\n\n const tree: VirtualFileTree = {\n root: vfs.toTree(config.projectName),\n fileCount: vfs.getFileCount(),\n directoryCount: vfs.getDirectoryCount(),\n config,\n };\n\n return { success: true, tree };\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n}\n","// Auto-generated - DO NOT EDIT\n// Run 'bun run generate-templates' to regenerate\n\nexport const EMBEDDED_TEMPLATES: Map<string, string> = new Map([\n [\"rust-base/.env.example\", `# Application\nRUST_LOG=debug\nAPP_ENV=development\n\n# Server\nHOST=127.0.0.1\nPORT=3000\n\n# gRPC (if using tonic)\n# GRPC_PORT=50051\n\n# Database (if using)\n# DATABASE_URL=postgres://user:password@localhost:5432/dbname\n# DATABASE_URL=sqlite:./data.db\n\n# JWT Secret (if using jsonwebtoken)\n# JWT_SECRET=your-secret-key-here\n`],\n [\"rust-base/Cargo.toml.hbs\", `[workspace]\nresolver = \"2\"\nmembers = [\n \"crates/server\",\n{{#if (eq rustApi \"tonic\")}}\n \"crates/proto\",\n{{/if}}\n{{#if (eq rustFrontend \"leptos\")}}\n \"crates/client\",\n{{/if}}\n{{#if (eq rustFrontend \"dioxus\")}}\n \"crates/dioxus-client\",\n{{/if}}\n{{#if (eq rustCli \"clap\")}}\n \"crates/cli\",\n{{/if}}\n{{#if (eq rustCli \"ratatui\")}}\n \"crates/tui\",\n{{/if}}\n]\n\n[workspace.package]\nversion = \"0.1.0\"\nedition = \"2021\"\nauthors = [\"Your Name <your.email@example.com>\"]\nlicense = \"MIT\"\nrepository = \"\"\n\n[workspace.dependencies]\n# Async runtime\ntokio = { version = \"1.43\", features = [\"full\"] }\n\n# Serialization\nserde = { version = \"1.0\", features = [\"derive\"] }\nserde_json = \"1.0\"\n\n# Error handling\nthiserror = \"2.0\"\nanyhow = \"1.0\"\n\n# Logging\ntracing = \"0.1\"\ntracing-subscriber = { version = \"0.3\", features = [\"env-filter\"] }\n\n# Environment variables\ndotenvy = \"0.15\"\n\n{{#if (eq rustWebFramework \"axum\")}}\n# Web framework (Axum)\naxum = \"0.8\"\ntower = \"0.5\"\ntower-http = { version = \"0.6\", features = [\"cors\", \"trace\"] }\n{{/if}}\n{{#if (eq rustWebFramework \"actix-web\")}}\n# Web framework (Actix-web)\nactix-web = \"4\"\nactix-rt = \"2\"\nactix-cors = \"0.7\"\n{{/if}}\n\n{{#if (eq rustOrm \"sqlx\")}}\n# Database (SQLx)\nsqlx = { version = \"0.8\", features = [\"runtime-tokio\", \"postgres\", \"sqlite\", \"mysql\", \"migrate\"] }\n{{/if}}\n{{#if (eq rustOrm \"sea-orm\")}}\n# Database (SeaORM)\nsea-orm = { version = \"1.1\", features = [\"runtime-tokio-rustls\", \"sqlx-postgres\", \"sqlx-sqlite\", \"sqlx-mysql\"] }\nsea-orm-migration = \"1.1\"\n{{/if}}\n\n{{#if (eq rustApi \"tonic\")}}\n# gRPC (Tonic)\ntonic = \"0.12\"\ntonic-build = \"0.12\"\nprost = \"0.13\"\n{{/if}}\n{{#if (eq rustApi \"async-graphql\")}}\n# GraphQL (async-graphql)\nasync-graphql = \"7\"\n{{#if (eq rustWebFramework \"axum\")}}\nasync-graphql-axum = \"7\"\n{{/if}}\n{{#if (eq rustWebFramework \"actix-web\")}}\nasync-graphql-actix-web = \"7\"\n{{/if}}\n{{/if}}\n\n{{#if (eq rustFrontend \"leptos\")}}\n# Frontend (Leptos)\nleptos = { version = \"0.7\", features = [\"csr\"] }\nleptos_router = { version = \"0.7\", features = [\"csr\"] }\nleptos_meta = { version = \"0.7\", features = [\"csr\"] }\nconsole_error_panic_hook = \"0.1\"\nconsole_log = \"1\"\nlog = \"0.4\"\nwasm-bindgen = \"0.2\"\nwasm-bindgen-futures = \"0.4\"\nweb-sys = { version = \"0.3\", features = [\"Window\", \"Document\", \"Element\", \"HtmlElement\", \"console\"] }\n{{/if}}\n{{#if (eq rustFrontend \"dioxus\")}}\n# Frontend (Dioxus)\ndioxus = { version = \"0.6\", features = [\"router\"] }\ndioxus-router = \"0.6\"\ndioxus-logger = \"0.6\"\nconsole_error_panic_hook = \"0.1\"\nwasm-bindgen = \"0.2\"\n{{/if}}\n\n{{#if (eq rustCli \"clap\")}}\n# CLI (Clap)\nclap = { version = \"4\", features = [\"derive\"] }\n{{/if}}\n{{#if (eq rustCli \"ratatui\")}}\n# TUI (Ratatui)\nratatui = \"0.29\"\ncrossterm = \"0.28\"\ntracing-appender = \"0.2\"\n{{/if}}\n\n{{#if (includes rustLibraries \"validator\")}}\n# Validation\nvalidator = { version = \"0.19\", features = [\"derive\"] }\n{{/if}}\n{{#if (includes rustLibraries \"jsonwebtoken\")}}\n# JWT\njsonwebtoken = \"9\"\n{{/if}}\n{{#if (includes rustLibraries \"argon2\")}}\n# Password hashing\nargon2 = \"0.5\"\n{{/if}}\n{{#if (includes rustLibraries \"tokio-test\")}}\n# Testing\ntokio-test = \"0.4\"\n{{/if}}\n{{#if (includes rustLibraries \"mockall\")}}\n# Mocking\nmockall = \"0.13\"\n{{/if}}\n\n[profile.dev]\nopt-level = 0\n\n[profile.release]\nopt-level = 3\nlto = true\ncodegen-units = 1\n`],\n [\"rust-base/rust-toolchain.toml.hbs\", `[toolchain]\nchannel = \"stable\"\ncomponents = [\"rustfmt\", \"clippy\"]\n{{#if (or (eq rustFrontend \"leptos\") (eq rustFrontend \"dioxus\"))}}\ntargets = [\"wasm32-unknown-unknown\"]\n{{/if}}\n`],\n [\"rust-base/_gitignore\", `# Generated by Cargo\n/target/\nCargo.lock\n\n# IDE\n.idea/\n.vscode/\n*.swp\n*.swo\n*~\n\n# OS\n.DS_Store\nThumbs.db\n\n# Environment\n.env\n.env.local\n.env.*.local\n\n# Build artifacts\n*.pdb\n\n# Debug\ndebug/\n\n# Documentation (generated)\n/target/doc/\n`],\n [\"base/package.json.hbs\", `{\n \"name\": \"better-t-stack\",\n \"private\": true,\n \"type\": \"module\",\n \"workspaces\": [\n \"apps/*\",\n \"packages/*\"\n ],\n \"scripts\": {}\n}\n`],\n [\"base/tsconfig.json.hbs\", `{\n \"extends\": \"@{{projectName}}/config/tsconfig.base.json\",\n}\n`],\n [\"base/_gitignore\", `# Dependencies\nnode_modules\n.pnp\n.pnp.js\n\n# Build outputs\ndist\nbuild\n*.tsbuildinfo\n\n# Environment variables\n.env\n.env*.local\n\n# IDEs and editors\n.vscode/*\n!.vscode/settings.json\n!.vscode/tasks.json\n!.vscode/launch.json\n!.vscode/extensions.json\n.idea\n*.swp\n*.swo\n*~\n.DS_Store\n\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n.pnpm-debug.log*\n\n# Turbo\n.turbo\n\n# Better-T-Stack\n.alchemy\n\n# Testing\ncoverage\n.nyc_output\n\n# Misc\n*.tgz\n.cache\ntmp\ntemp`],\n [\"extras/env.d.ts.hbs\", `import { type server } from \"@{{projectName}}/infra/alchemy.run\";\n\n// This file infers types for the cloudflare:workers environment from your Alchemy Worker.\n// @see https://alchemy.run/concepts/bindings/#type-safe-bindings\n\nexport type CloudflareEnv = typeof server.Env;\n\ndeclare global {\n type Env = CloudflareEnv;\n}\n\ndeclare module \"cloudflare:workers\" {\n namespace Cloudflare {\n export interface Env extends CloudflareEnv {}\n }\n}\n`],\n [\"extras/bunfig.toml.hbs\", `[install]\n{{#if (or (includes frontend \"nuxt\"))}}\nlinker = \"hoisted\" # having issues with Nuxt when linker is isolated\n{{else}}\nlinker = \"isolated\"\n{{/if}}`],\n [\"extras/pnpm-workspace.yaml\", `packages:\n - \"apps/*\"\n - \"packages/*\"\n`],\n [\"extras/_npmrc.hbs\", `node-linker=isolated\n{{#if (includes frontend \"nuxt\")}}\nshamefully-hoist=true\nstrict-peer-dependencies=false\n{{/if}}`],\n [\"frontend/qwik/package.json.hbs\", `{\n \"name\": \"web\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"build\": \"qwik build\",\n \"build.client\": \"vite build\",\n \"build.preview\": \"vite build --ssr src/entry.preview.tsx\",\n \"build.types\": \"tsc --incremental --noEmit\",\n \"dev\": \"vite --mode ssr\",\n \"dev.debug\": \"node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force\",\n \"preview\": \"qwik build preview && vite preview --open\",\n \"start\": \"vite --open --mode ssr\",\n \"qwik\": \"qwik\"\n },\n \"dependencies\": {\n \"@builder.io/qwik\": \"^1.14.1\",\n \"@builder.io/qwik-city\": \"^1.14.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.13.14\",\n \"typescript\": \"^5.7.3\",\n \"vite\": \"^6.3.5\",\n \"vite-tsconfig-paths\": \"^5.1.4\"\n }\n}\n`],\n [\"frontend/qwik/tsconfig.json.hbs\", `{\n \"compilerOptions\": {\n \"allowJs\": true,\n \"target\": \"ES2021\",\n \"module\": \"ES2020\",\n \"lib\": [\"ES2021\", \"DOM\", \"DOM.Iterable\"],\n \"jsx\": \"react-jsx\",\n \"jsxImportSource\": \"@builder.io/qwik\",\n \"strict\": true,\n \"forceConsistentCasingInFileNames\": true,\n \"resolveJsonModule\": true,\n \"moduleResolution\": \"Bundler\",\n \"esModuleInterop\": true,\n \"skipLibCheck\": true,\n \"incremental\": true,\n \"isolatedModules\": true,\n \"outDir\": \"tmp\",\n \"noEmit\": true,\n \"types\": [\"node\", \"vite/client\"],\n \"baseUrl\": \".\",\n \"paths\": {\n \"@/*\": [\"./src/*\"]\n }\n },\n \"include\": [\"src/**/*.ts\", \"src/**/*.tsx\"]\n}\n`],\n [\"frontend/qwik/vite.config.ts.hbs\", `import { qwikVite } from \"@builder.io/qwik/optimizer\";\nimport { qwikCity } from \"@builder.io/qwik-city/vite\";\nimport { defineConfig } from \"vite\";\nimport tsconfigPaths from \"vite-tsconfig-paths\";\n\nexport default defineConfig(() => {\n return {\n plugins: [qwikCity(), qwikVite(), tsconfigPaths()],\n server: {\n port: 3001,\n },\n preview: {\n headers: {\n \"Cache-Control\": \"public, max-age=600\",\n },\n },\n };\n});\n`],\n [\"frontend/qwik/_gitignore\", `# Dependencies\nnode_modules\n\n# Build outputs\ndist\nserver\ntmp\n\n# Logs\n*.log\n\n# Editor directories and files\n.idea\n.vscode\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n\n# Local env files\n.env\n.env.local\n.env.*.local\n\n# Qwik specific\n.vercel\n.netlify\n`],\n [\"frontend/svelte/svelte.config.js.hbs\", `import adapter from '@sveltejs/adapter-auto';\nimport { vitePreprocess } from '@sveltejs/vite-plugin-svelte';\n\n/** @type {import('@sveltejs/kit').Config} */\nconst config = {\n\t// Consult https://svelte.dev/docs/kit/integrations\n\t// for more information about preprocessors\n\tpreprocess: vitePreprocess(),\n\n\tkit: {\n\t\t// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.\n\t\t// If your environment is not supported, or you settled on a specific environment, switch out the adapter.\n\t\t// See https://svelte.dev/docs/kit/adapters for more information about adapters.\n\t\tadapter: adapter()\n\t}\n};\n\nexport default config;\n`],\n [\"frontend/svelte/package.json.hbs\", `{\n\t\"name\": \"web\",\n\t\"private\": true,\n\t\"version\": \"0.0.1\",\n\t\"type\": \"module\",\n\t\"scripts\": {\n\t\t\"dev\": \"vite dev\",\n\t\t\"build\": \"vite build\",\n\t\t\"preview\": \"vite preview\",\n\t\t\"prepare\": \"svelte-kit sync || echo ''\",\n\t\t\"check\": \"svelte-kit sync && svelte-check --tsconfig ./tsconfig.json\",\n\t\t\"check:watch\": \"svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@sveltejs/adapter-auto\": \"^6.1.0\",\n\t\t\"@sveltejs/kit\": \"^2.31.1\",\n\t\t\"@sveltejs/vite-plugin-svelte\": \"^6.1.2\",\n\t\t\"@tailwindcss/vite\": \"^4.1.12\",\n\t\t\"svelte\": \"^5.38.1\",\n\t\t\"svelte-check\": \"^4.3.1\",\n\t\t\"tailwindcss\": \"^4.1.12\",\n\t\t\"vite\": \"^7.1.2\"\n\t},\n\t\"dependencies\": {\n\t\t\"@tanstack/svelte-form\": \"^1.19.2\"\n\t}\n}\n`],\n [\"frontend/svelte/_npmrc\", `engine-strict=true\n`],\n [\"frontend/svelte/tsconfig.json.hbs\", `{\n\t\"extends\": \"./.svelte-kit/tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"allowJs\": true,\n\t\t\"checkJs\": true,\n\t\t\"esModuleInterop\": true,\n\t\t\"forceConsistentCasingInFileNames\": true,\n\t\t\"resolveJsonModule\": true,\n\t\t\"skipLibCheck\": true,\n\t\t\"sourceMap\": true,\n\t\t\"strict\": true,\n\t\t\"moduleResolution\": \"bundler\"\n\t}\n\t// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias\n\t// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files\n\t//\n\t// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes\n\t// from the referenced tsconfig.json - TypeScript does not merge them in\n}\n`],\n [\"frontend/svelte/vite.config.ts.hbs\", `import tailwindcss from \"@tailwindcss/vite\";\nimport { sveltekit } from \"@sveltejs/kit/vite\";\nimport { defineConfig } from \"vite\";\n\nexport default defineConfig({\n plugins: [tailwindcss(), sveltekit()],\n});\n`],\n [\"frontend/svelte/_gitignore\", `node_modules\n\n# Output\n.output\n.vercel\n.netlify\n.wrangler\n.alchemy\n/.svelte-kit\n/build\n\n# OS\n.DS_Store\nThumbs.db\n\n# Env\n.env\n.env.*\n!.env.example\n!.env.test\n\n# Vite\nvite.config.js.timestamp-*\nvite.config.ts.timestamp-*\n`],\n [\"frontend/angular/package.json.hbs\", `{\n \"name\": \"web\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"ng\": \"ng\",\n \"dev\": \"ng serve --port 3001\",\n \"start\": \"ng serve --port 3001\",\n \"build\": \"ng build\",\n \"watch\": \"ng build --watch --configuration development\"\n },\n \"dependencies\": {\n \"@angular/animations\": \"^19.2.0\",\n \"@angular/common\": \"^19.2.0\",\n \"@angular/compiler\": \"^19.2.0\",\n \"@angular/core\": \"^19.2.0\",\n \"@angular/forms\": \"^19.2.0\",\n \"@angular/platform-browser\": \"^19.2.0\",\n \"@angular/platform-browser-dynamic\": \"^19.2.0\",\n \"@angular/router\": \"^19.2.0\",\n \"rxjs\": \"^7.8.1\",\n \"tslib\": \"^2.8.1\",\n \"zone.js\": \"^0.15.0\"\n },\n \"devDependencies\": {\n \"@angular-devkit/build-angular\": \"^19.2.0\",\n \"@angular/cli\": \"^19.2.0\",\n \"@angular/compiler-cli\": \"^19.2.0\",\n \"typescript\": \"~5.7.0\"\n }\n}\n`],\n [\"frontend/angular/tsconfig.app.json\", `{\n \"extends\": \"./tsconfig.json\",\n \"compilerOptions\": {\n \"outDir\": \"./out-tsc/app\",\n \"types\": []\n },\n \"files\": [\"src/main.ts\"],\n \"include\": [\"src/**/*.d.ts\"]\n}\n`],\n [\"frontend/angular/angular.json.hbs\", `{\n \"$schema\": \"./node_modules/@angular/cli/lib/config/schema.json\",\n \"version\": 1,\n \"newProjectRoot\": \"projects\",\n \"projects\": {\n \"web\": {\n \"projectType\": \"application\",\n \"schematics\": {\n \"@schematics/angular:component\": {\n \"style\": \"{{#if (eq cssFramework \"scss\")}}scss{{else if (eq cssFramework \"less\")}}less{{else}}css{{/if}}\",\n \"standalone\": true\n }\n },\n \"root\": \"\",\n \"sourceRoot\": \"src\",\n \"prefix\": \"app\",\n \"architect\": {\n \"build\": {\n \"builder\": \"@angular-devkit/build-angular:application\",\n \"options\": {\n \"outputPath\": \"dist/web\",\n \"index\": \"src/index.html\",\n \"browser\": \"src/main.ts\",\n \"polyfills\": [\"zone.js\"],\n \"tsConfig\": \"tsconfig.app.json\",\n {{#if (eq cssFramework \"tailwind\")}}\n \"styles\": [\"src/styles.css\"],\n {{else if (eq cssFramework \"scss\")}}\n \"styles\": [\"src/styles.scss\"],\n {{else if (eq cssFramework \"less\")}}\n \"styles\": [\"src/styles.less\"],\n {{else}}\n \"styles\": [\"src/styles.css\"],\n {{/if}}\n \"scripts\": [],\n \"assets\": [\n {\n \"glob\": \"**/*\",\n \"input\": \"public\"\n }\n ]\n },\n \"configurations\": {\n \"production\": {\n \"budgets\": [\n {\n \"type\": \"initial\",\n \"maximumWarning\": \"500kB\",\n \"maximumError\": \"1MB\"\n },\n {\n \"type\": \"anyComponentStyle\",\n \"maximumWarning\": \"4kB\",\n \"maximumError\": \"8kB\"\n }\n ],\n \"outputHashing\": \"all\"\n },\n \"development\": {\n \"optimization\": false,\n \"extractLicenses\": false,\n \"sourceMap\": true\n }\n },\n \"defaultConfiguration\": \"production\"\n },\n \"serve\": {\n \"builder\": \"@angular-devkit/build-angular:dev-server\",\n \"configurations\": {\n \"production\": {\n \"buildTarget\": \"web:build:production\"\n },\n \"development\": {\n \"buildTarget\": \"web:build:development\"\n }\n },\n \"defaultConfiguration\": \"development\"\n }\n }\n }\n }\n}\n`],\n [\"frontend/angular/tsconfig.json.hbs\", `{\n \"compileOnSave\": false,\n \"compilerOptions\": {\n \"outDir\": \"./dist/out-tsc\",\n \"strict\": true,\n \"noImplicitOverride\": true,\n \"noPropertyAccessFromIndexSignature\": true,\n \"noImplicitReturns\": true,\n \"noFallthroughCasesInSwitch\": true,\n \"skipLibCheck\": true,\n \"isolatedModules\": true,\n \"esModuleInterop\": true,\n \"sourceMap\": true,\n \"declaration\": false,\n \"experimentalDecorators\": true,\n \"moduleResolution\": \"bundler\",\n \"importHelpers\": true,\n \"target\": \"ES2022\",\n \"module\": \"ES2022\",\n \"lib\": [\"ES2022\", \"dom\"],\n \"paths\": {\n \"@/*\": [\"./src/*\"]\n }\n },\n \"angularCompilerOptions\": {\n \"enableI18nLegacyMessageIdFormat\": false,\n \"strictInjectionParameters\": true,\n \"strictInputAccessModifiers\": true,\n \"strictTemplates\": true\n }\n}\n`],\n [\"frontend/angular/_gitignore\", `# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# Compiled output\n/dist\n/tmp\n/out-tsc\n/bazel-out\n\n# Node\n/node_modules\nnpm-debug.log\nyarn-error.log\n\n# IDEs and editors\n.idea/\n.project\n.classpath\n.c9/\n*.launch\n.settings/\n*.sublime-workspace\n\n# Visual Studio Code\n.vscode/*\n!.vscode/settings.json\n!.vscode/tasks.json\n!.vscode/launch.json\n!.vscode/extensions.json\n.history/*\n\n# Miscellaneous\n/.angular/cache\n.sass-cache/\n/connect.lock\n/coverage\n/libpeerconnection.log\ntestem.log\n/typings\n\n# System files\n.DS_Store\nThumbs.db\n\n# Environment\n.env\n.env.local\n`],\n [\"frontend/redwood/graphql.config.js\", `const { getPaths } = require(\"@redwoodjs/project-config\");\n\nconst redwoodPaths = getPaths();\n\nmodule.exports = {\n schema: redwoodPaths.generated.schema,\n documents: \"./web/src/**/!(*.d).{ts,tsx,js,jsx}\",\n};\n`],\n [\"frontend/redwood/package.json.hbs\", `{\n \"name\": \"{{projectName}}\",\n \"private\": true,\n \"workspaces\": {\n \"packages\": [\n \"api\",\n \"web\"\n ]\n },\n \"devDependencies\": {\n \"@redwoodjs/core\": \"^8.8.0\"\n },\n \"eslintConfig\": {\n \"extends\": \"@redwoodjs/eslint-config\",\n \"root\": true\n },\n \"engines\": {\n \"node\": \">=20.x\"\n },\n \"packageManager\": \"{{packageManager}}@latest\"\n}\n`],\n [\"frontend/redwood/redwood.toml.hbs\", `# Redwood Configuration\n# https://redwoodjs.com/docs/app-configuration-redwood-toml\n\n[web]\n title = \"{{projectName}}\"\n port = 8910\n apiUrl = \"/.redwood/functions\"\n includeEnvironmentVariables = []\n\n[api]\n port = 8911\n\n[browser]\n open = true\n\n[notifications]\n versionUpdates = [\"latest\"]\n`],\n [\"frontend/redwood/_gitignore\", `# RedwoodJS\n.redwood/\n.netlify/\n.vercel/\ndist/\nnode_modules/\n*.log\n\n# Prisma\napi/db/dev.db\napi/db/dev.db-journal\napi/db/migrations/\n\n# Environment\n.env\n.env.local\n.env.*.local\n\n# IDE\n.idea/\n.vscode/\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Build\nweb/dist/\napi/dist/\n`],\n [\"frontend/fresh/dev.ts\", `#!/usr/bin/env -S deno run -A --watch=static/,routes/\n\nimport dev from \"$fresh/dev.ts\";\n\nimport config from \"./fresh.config.ts\";\n\nawait dev(import.meta.url, \"./main.ts\", config);\n`],\n [\"frontend/fresh/utils.ts\", `import { createDefine } from \"$fresh/server.ts\";\n\nexport interface State {\n // Add your state properties here\n title?: string;\n}\n\nexport const define = createDefine<State>();\n`],\n [\"frontend/fresh/main.ts\", `/// <reference lib=\"deno.ns\" />\n\nimport { App, staticFiles } from \"$fresh/server.ts\";\n\nexport const app = new App({ root: import.meta.url }).use(staticFiles());\n\n// To add custom routes, import { define } from \"./utils.ts\"\n// app.get(\"/api/example\", define.handlers(() => new Response(\"Hello!\")));\n\nif (import.meta.main) {\n await app.listen();\n}\n`],\n [\"frontend/fresh/tailwind.config.ts.hbs\", `{{#if (eq cssFramework \"tailwind\")}}\nimport type { Config } from \"tailwindcss\";\n\nexport default {\n content: [\n \"{routes,islands,components}/**/*.{ts,tsx}\",\n \"src/**/*.{ts,tsx}\",\n ],\n theme: {\n extend: {},\n },\n plugins: [{{#if (eq uiLibrary \"daisyui\")}}\n require(\"daisyui\"),\n {{/if}}],\n{{#if (eq uiLibrary \"daisyui\")}}\n daisyui: {\n themes: [\"dark\", \"light\"],\n },\n{{/if}}\n} satisfies Config;\n{{/if}}\n`],\n [\"frontend/fresh/fresh.config.ts.hbs\", `import { defineConfig } from \"$fresh/server.ts\";\n{{#if (eq cssFramework \"tailwind\")}}\nimport tailwind from \"$fresh/plugins/tailwind.ts\";\n\nexport default defineConfig({\n plugins: [tailwind()],\n});\n{{else}}\nexport default defineConfig({});\n{{/if}}\n`],\n [\"frontend/fresh/deno.json.hbs\", `{\n \"lock\": false,\n \"tasks\": {\n \"check\": \"deno fmt --check && deno lint && deno check **/*.ts && deno check **/*.tsx\",\n \"cli\": \"echo \\\\\"import '\\\\\\\\$fresh/src/dev/cli.ts'\\\\\" | deno run --unstable -A -\",\n \"manifest\": \"deno task cli manifest $(pwd)\",\n \"dev\": \"deno run -A --watch=static/,routes/ dev.ts\",\n \"build\": \"deno run -A dev.ts build\",\n \"preview\": \"deno run -A main.ts\",\n \"update\": \"deno run -A -r jsr:@fresh/update .\"\n },\n \"lint\": {\n \"rules\": {\n \"tags\": [\n \"fresh\",\n \"recommended\"\n ]\n }\n },\n \"exclude\": [\n \"**/_fresh/*\"\n ],\n \"imports\": {\n \"$fresh/\": \"jsr:@fresh/core@^2.0.0-alpha/\",\n \"preact\": \"npm:preact@^10.25.4\",\n \"preact/\": \"npm:preact@^10.25.4/\",\n \"@preact/signals\": \"npm:@preact/signals@^2.0.0\",\n \"@preact/signals-core\": \"npm:@preact/signals-core@^2.0.0\"{{#if (eq cssFramework \"tailwind\")}},\n \"tailwindcss\": \"npm:tailwindcss@^3.4.17\",\n \"tailwindcss/plugin\": \"npm:tailwindcss@^3.4.17/plugin.js\"{{/if}}\n },\n \"compilerOptions\": {\n \"lib\": [\n \"dom\",\n \"dom.asynciterable\",\n \"deno.ns\"\n ],\n \"jsx\": \"react-jsx\",\n \"jsxImportSource\": \"preact\"\n },\n \"nodeModulesDir\": \"auto\"\n}\n`],\n [\"frontend/fresh/_gitignore\", `# Fresh build output\n_fresh/\n\n# Deno\n.deno/\n\n# Editor directories\n.idea/\n.vscode/\n\n# OS generated files\n.DS_Store\nThumbs.db\n\n# Environment files\n.env\n.env.local\n.env.*.local\n\n# Logs\nlogs\n*.log\n`],\n [\"frontend/solid/package.json.hbs\", `{\n \"name\": \"web\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"dev\": \"vite dev\",\n \"build\": \"vite build\",\n \"serve\": \"vite preview\",\n \"test\": \"vitest run\"\n },\n \"dependencies\": {\n \"@tailwindcss/vite\": \"^4.1.13\",\n \"@tanstack/router-plugin\": \"^1.131.44\",\n \"@tanstack/solid-form\": \"^1.20.0\",\n \"@tanstack/solid-router\": \"^1.131.44\",\n \"lucide-solid\": \"^0.544.0\",\n \"solid-js\": \"^1.9.9\",\n \"tailwindcss\": \"^4.1.13\"\n },\n \"devDependencies\": {\n \"vite\": \"^7.1.5\",\n \"vite-plugin-solid\": \"^2.11.8\"\n }\n}\n`],\n [\"frontend/solid/index.html\", `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <link rel=\"icon\" href=\"/favicon.ico\" />\n <meta name=\"theme-color\" content=\"#000000\" />\n </head>\n <body>\n <div id=\"app\"></div>\n <script type=\"module\" src=\"/src/main.tsx\"></script>\n </body>\n</html>\n`],\n [\"frontend/solid/tsconfig.json.hbs\", `{\n \"include\": [\"**/*.ts\", \"**/*.tsx\"],\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"jsx\": \"preserve\",\n \"jsxImportSource\": \"solid-js\",\n \"module\": \"ESNext\",\n \"lib\": [\"ES2022\", \"DOM\", \"DOM.Iterable\"],\n \"types\": [\"vite/client\"],\n\n \"moduleResolution\": \"bundler\",\n \"allowImportingTsExtensions\": true,\n \"verbatimModuleSyntax\": true,\n \"noEmit\": true,\n\n \"skipLibCheck\": true,\n \"strict\": true,\n \"noUnusedLocals\": true,\n \"noUnusedParameters\": true,\n \"noFallthroughCasesInSwitch\": true,\n \"noUncheckedSideEffectImports\": true,\n\n \"rootDirs\": [\".\"],\n \"baseUrl\": \".\",\n \"paths\": {\n \"@/*\": [\"./src/*\"]\n }\n }\n}\n`],\n [\"frontend/solid/vite.config.ts.hbs\", `import { defineConfig } from \"vite\";\nimport { tanstackRouter } from \"@tanstack/router-plugin/vite\";\nimport solidPlugin from \"vite-plugin-solid\";\nimport tailwindcss from \"@tailwindcss/vite\";\nimport path from \"node:path\";\n\nexport default defineConfig({\n plugins: [\n tanstackRouter({ target: \"solid\", autoCodeSplitting: true }),\n solidPlugin(),\n tailwindcss(),\n ],\n resolve: {\n alias: {\n \"@\": path.resolve(__dirname, \"./src\"),\n },\n },\n server: {\n port: 3001,\n },\n});`],\n [\"frontend/solid/_gitignore\", `node_modules\n.DS_Store\ndist\ndist-ssr\n*.local\n.env\n.env.*\n\n.wrangler\n.alchemy\n.dev.vars*`],\n [\"frontend/nuxt/package.json.hbs\", `{\n \"name\": \"web\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"build\": \"nuxt build\",\n \"dev\": \"nuxt dev\",\n \"generate\": \"nuxt generate\",\n \"preview\": \"nuxt preview\",\n \"postinstall\": \"nuxt prepare\"\n },\n \"dependencies\": {\n \"@nuxt/ui\": \"4.2.1\",\n \"@nuxt/content\": \"^3.7.1\",\n \"@nuxtjs/mdc\": \"^0.17.4\",\n \"nuxt\": \"^4.1.2\",\n \"vue\": \"^3.5.21\",\n \"vue-router\": \"^4.5.1\"\n },\n \"devDependencies\": {\n \"tailwindcss\": \"^4.1.13\",\n \"@iconify-json/lucide\": \"^1.2.57\"\n }\n}\n`],\n [\"frontend/nuxt/nuxt.config.ts.hbs\", `import \"@{{projectName}}/env/web\";\n\n// https://nuxt.com/docs/api/configuration/nuxt-config\nexport default defineNuxtConfig({\n compatibilityDate: 'latest',\n devtools: { enabled: true },\n modules: [\n '@nuxt/ui'\n {{#if (eq backend \"convex\")}},\n 'convex-nuxt'\n {{/if}}\n ],\n css: ['~/assets/css/main.css'],\n devServer: {\n port: 3001\n },\n ssr: true,\n {{#if (eq backend \"convex\")}}\n convex: {\n url: process.env.NUXT_PUBLIC_CONVEX_URL,\n },\n {{else}}\n runtimeConfig: {\n public: {\n serverUrl: process.env.NUXT_PUBLIC_SERVER_URL,\n }\n },\n {{/if}}\n})\n`],\n [\"frontend/nuxt/tsconfig.json.hbs\", `{\n // https://nuxt.com/docs/guide/concepts/typescript\n \"files\": [],\n \"references\": [\n {\n \"path\": \"./.nuxt/tsconfig.app.json\"\n },\n {\n \"path\": \"./.nuxt/tsconfig.server.json\"\n },\n {\n \"path\": \"./.nuxt/tsconfig.shared.json\"\n },\n {\n \"path\": \"./.nuxt/tsconfig.node.json\"\n }\n ]\n}\n`],\n [\"frontend/nuxt/_gitignore\", `# Nuxt dev/build outputs\n.output\n.data\n.nuxt\n.nitro\n.cache\ndist\n.wrangler\n.alchemy\n\n# Node dependencies\nnode_modules\n\n# Logs\nlogs\n*.log\n\n# Misc\n.DS_Store\n.fleet\n.idea\n\n# Local env files\n.env\n.env.*\n!.env.example\n\n`],\n [\"packages/infra/alchemy.run.ts.hbs\", `import alchemy from \"alchemy\";\n{{#if (eq webDeploy \"cloudflare\")}}\n{{#if (includes frontend \"next\")}}\nimport { Nextjs } from \"alchemy/cloudflare\";\n{{else if (includes frontend \"nuxt\")}}\nimport { Nuxt } from \"alchemy/cloudflare\";\n{{else if (includes frontend \"svelte\")}}\nimport { SvelteKit } from \"alchemy/cloudflare\";\n{{else if (includes frontend \"tanstack-start\")}}\nimport { TanStackStart } from \"alchemy/cloudflare\";\n{{else if (includes frontend \"tanstack-router\")}}\nimport { Vite } from \"alchemy/cloudflare\";\n{{else if (includes frontend \"react-router\")}}\nimport { ReactRouter } from \"alchemy/cloudflare\";\n{{else if (includes frontend \"solid\")}}\nimport { Vite } from \"alchemy/cloudflare\";\n{{/if}}\n{{/if}}\n{{#if (eq serverDeploy \"cloudflare\")}}\nimport { Worker } from \"alchemy/cloudflare\";\n{{/if}}\n{{#if (and (or (eq serverDeploy \"cloudflare\") (and (eq webDeploy \"cloudflare\") (eq backend \"self\"))) (eq dbSetup \"d1\"))}}\nimport { D1Database } from \"alchemy/cloudflare\";\n{{/if}}\nimport { config } from \"dotenv\";\n\n{{#if (and (eq webDeploy \"cloudflare\") (eq serverDeploy \"cloudflare\"))}}\nconfig({ path: \"./.env\" });\nconfig({ path: \"../../apps/web/.env\" });\nconfig({ path: \"../../apps/server/.env\" });\n{{else if (eq webDeploy \"cloudflare\")}}\nconfig({ path: \"./.env\" });\nconfig({ path: \"../../apps/web/.env\" });\n{{else if (eq serverDeploy \"cloudflare\")}}\nconfig({ path: \"./.env\" });\nconfig({ path: \"../../apps/server/.env\" });\n{{/if}}\n\nconst app = await alchemy(\"{{projectName}}\");\n\n{{#if (and (or (eq serverDeploy \"cloudflare\") (and (eq webDeploy \"cloudflare\") (eq backend \"self\"))) (eq dbSetup \"d1\"))}}\nconst db = await D1Database(\"database\", {\n\t{{#if (eq orm \"prisma\")}}\n\tmigrationsDir: \"../../packages/db/prisma/migrations\",\n\t{{else if (eq orm \"drizzle\")}}\n\tmigrationsDir: \"../../packages/db/src/migrations\",\n\t{{/if}}\n});\n{{/if}}\n\n{{#if (eq webDeploy \"cloudflare\")}}\n{{#if (includes frontend \"next\")}}\nexport const web = await Nextjs(\"web\", {\n cwd: \"../../apps/web\",\n bindings: {\n {{#if (eq backend \"convex\")}}\n NEXT_PUBLIC_CONVEX_URL: alchemy.env.NEXT_PUBLIC_CONVEX_URL!,\n {{#if (eq auth \"better-auth\")}}\n NEXT_PUBLIC_CONVEX_SITE_URL: alchemy.env.NEXT_PUBLIC_CONVEX_SITE_URL!,\n {{/if}}\n {{else if (ne backend \"self\")}}\n NEXT_PUBLIC_SERVER_URL: alchemy.env.NEXT_PUBLIC_SERVER_URL!,\n {{/if}}\n {{#if (eq dbSetup \"d1\")}}\n DB: db,\n {{else if (ne database \"none\")}}\n DATABASE_URL: alchemy.secret.env.DATABASE_URL!,\n {{/if}}\n {{#if (ne backend \"convex\")}}\n CORS_ORIGIN: alchemy.env.CORS_ORIGIN!,\n {{#if (eq auth \"better-auth\")}}\n BETTER_AUTH_SECRET: alchemy.secret.env.BETTER_AUTH_SECRET!,\n BETTER_AUTH_URL: alchemy.env.BETTER_AUTH_URL!,\n {{/if}}\n {{/if}}\n {{#if (eq auth \"clerk\")}}\n CLERK_SECRET_KEY: alchemy.secret.env.CLERK_SECRET_KEY!,\n {{/if}}\n {{#if (and (includes examples \"ai\") (ne backend \"convex\"))}}\n GOOGLE_GENERATIVE_AI_API_KEY: alchemy.secret.env.GOOGLE_GENERATIVE_AI_API_KEY!,\n {{/if}}\n {{#if (eq payments \"polar\")}}\n POLAR_ACCESS_TOKEN: alchemy.secret.env.POLAR_ACCESS_TOKEN!,\n POLAR_SUCCESS_URL: alchemy.env.POLAR_SUCCESS_URL!,\n {{/if}}\n {{#if (eq dbSetup \"turso\")}}\n DATABASE_AUTH_TOKEN: alchemy.secret.env.DATABASE_AUTH_TOKEN!,\n {{/if}}\n {{#if (eq database \"mysql\")}}\n {{#if (eq orm \"drizzle\")}}\n DATABASE_HOST: alchemy.env.DATABASE_HOST!,\n DATABASE_USERNAME: alchemy.env.DATABASE_USERNAME!,\n DATABASE_PASSWORD: alchemy.secret.env.DATABASE_PASSWORD!,\n {{/if}}\n {{/if}}\n }\n});\n{{else if (includes frontend \"nuxt\")}}\nexport const web = await Nuxt(\"web\", {\n cwd: \"../../apps/web\",\n bindings: {\n {{#if (eq backend \"convex\")}}\n NUXT_PUBLIC_CONVEX_URL: alchemy.env.NUXT_PUBLIC_CONVEX_URL!,\n {{#if (eq auth \"better-auth\")}}\n NUXT_PUBLIC_CONVEX_SITE_URL: alchemy.env.NUXT_PUBLIC_CONVEX_SITE_URL!,\n {{/if}}\n {{else if (ne backend \"self\")}}\n NUXT_PUBLIC_SERVER_URL: alchemy.env.NUXT_PUBLIC_SERVER_URL!,\n {{/if}}\n }\n});\n{{else if (includes frontend \"svelte\")}}\nexport const web = await SvelteKit(\"web\", {\n cwd: \"../../apps/web\",\n bindings: {\n {{#if (eq backend \"convex\")}}\n PUBLIC_CONVEX_URL: alchemy.env.PUBLIC_CONVEX_URL!,\n {{#if (eq auth \"better-auth\")}}\n PUBLIC_CONVEX_SITE_URL: alchemy.env.PUBLIC_CONVEX_SITE_URL!,\n {{/if}}\n {{else if (ne backend \"self\")}}\n PUBLIC_SERVER_URL: alchemy.env.PUBLIC_SERVER_URL!,\n {{/if}}\n }\n});\n{{else if (includes frontend \"tanstack-start\")}}\nexport const web = await TanStackStart(\"web\", {\n cwd: \"../../apps/web\",\n bindings: {\n {{#if (eq backend \"convex\")}}\n VITE_CONVEX_URL: alchemy.env.VITE_CONVEX_URL!,\n {{#if (eq auth \"better-auth\")}}\n VITE_CONVEX_SITE_URL: alchemy.env.VITE_CONVEX_SITE_URL!,\n {{/if}}\n {{else if (ne backend \"self\")}}\n VITE_SERVER_URL: alchemy.env.VITE_SERVER_URL!,\n {{/if}}\n {{#if (eq dbSetup \"d1\")}}\n DB: db,\n {{else if (ne database \"none\")}}\n DATABASE_URL: alchemy.secret.env.DATABASE_URL!,\n {{/if}}\n {{#if (ne backend \"convex\")}}\n CORS_ORIGIN: alchemy.env.CORS_ORIGIN!,\n {{#if (eq auth \"better-auth\")}}\n BETTER_AUTH_SECRET: alchemy.secret.env.BETTER_AUTH_SECRET!,\n BETTER_AUTH_URL: alchemy.env.BETTER_AUTH_URL!,\n {{/if}}\n {{/if}}\n {{#if (eq auth \"clerk\")}}\n CLERK_SECRET_KEY: alchemy.secret.env.CLERK_SECRET_KEY!,\n {{/if}}\n {{#if (and (includes examples \"ai\") (ne backend \"convex\"))}}\n GOOGLE_GENERATIVE_AI_API_KEY: alchemy.secret.env.GOOGLE_GENERATIVE_AI_API_KEY!,\n {{/if}}\n {{#if (eq payments \"polar\")}}\n POLAR_ACCESS_TOKEN: alchemy.secret.env.POLAR_ACCESS_TOKEN!,\n POLAR_SUCCESS_URL: alchemy.env.POLAR_SUCCESS_URL!,\n {{/if}}\n {{#if (eq dbSetup \"turso\")}}\n DATABASE_AUTH_TOKEN: alchemy.secret.env.DATABASE_AUTH_TOKEN!,\n {{/if}}\n {{#if (eq database \"mysql\")}}\n {{#if (eq orm \"drizzle\")}}\n DATABASE_HOST: alchemy.env.DATABASE_HOST!,\n DATABASE_USERNAME: alchemy.env.DATABASE_USERNAME!,\n DATABASE_PASSWORD: alchemy.secret.env.DATABASE_PASSWORD!,\n {{/if}}\n {{/if}}\n }\n});\n{{else if (includes frontend \"tanstack-router\")}}\nexport const web = await Vite(\"web\", {\n cwd: \"../../apps/web\",\n assets: \"dist\",\n bindings: {\n {{#if (eq backend \"convex\")}}\n VITE_CONVEX_URL: alchemy.env.VITE_CONVEX_URL!,\n {{#if (eq auth \"better-auth\")}}\n VITE_CONVEX_SITE_URL: alchemy.env.VITE_CONVEX_SITE_URL!,\n {{/if}}\n {{else if (ne backend \"self\")}}\n VITE_SERVER_URL: alchemy.env.VITE_SERVER_URL!,\n {{/if}}\n }\n});\n{{else if (includes frontend \"react-router\")}}\nexport const web = await ReactRouter(\"web\", {\n cwd: \"../../apps/web\",\n bindings: {\n {{#if (eq backend \"convex\")}}\n VITE_CONVEX_URL: alchemy.env.VITE_CONVEX_URL!,\n {{#if (eq auth \"better-auth\")}}\n VITE_CONVEX_SITE_URL: alchemy.env.VITE_CONVEX_SITE_URL!,\n {{/if}}\n {{else if (ne backend \"self\")}}\n VITE_SERVER_URL: alchemy.env.VITE_SERVER_URL!,\n {{/if}}\n }\n});\n{{else if (includes frontend \"solid\")}}\nexport const web = await Vite(\"web\", {\n cwd: \"../../apps/web\",\n assets: \"dist\",\n bindings: {\n {{#if (eq backend \"convex\")}}\n VITE_CONVEX_URL: alchemy.env.VITE_CONVEX_URL!,\n {{#if (eq auth \"better-auth\")}}\n VITE_CONVEX_SITE_URL: alchemy.env.VITE_CONVEX_SITE_URL!,\n {{/if}}\n {{else if (ne backend \"self\")}}\n VITE_SERVER_URL: alchemy.env.VITE_SERVER_URL!,\n {{/if}}\n }\n});\n{{/if}}\n{{/if}}\n\n{{#if (eq serverDeploy \"cloudflare\")}}\nexport const server = await Worker(\"server\", {\n cwd: \"../../apps/server\",\n entrypoint: \"src/index.ts\",\n compatibility: \"node\",\n bindings: {\n {{#if (eq dbSetup \"d1\")}}\n DB: db,\n {{else if (ne database \"none\")}}\n DATABASE_URL: alchemy.secret.env.DATABASE_URL!,\n {{/if}}\n CORS_ORIGIN: alchemy.env.CORS_ORIGIN!,\n {{#if (eq auth \"better-auth\")}}\n BETTER_AUTH_SECRET: alchemy.secret.env.BETTER_AUTH_SECRET!,\n BETTER_AUTH_URL: alchemy.env.BETTER_AUTH_URL!,\n {{/if}}\n {{#if (eq auth \"clerk\")}}\n CLERK_SECRET_KEY: alchemy.secret.env.CLERK_SECRET_KEY!,\n {{/if}}\n {{#if (includes examples \"ai\")}}\n GOOGLE_GENERATIVE_AI_API_KEY: alchemy.secret.env.GOOGLE_GENERATIVE_AI_API_KEY!,\n {{/if}}\n {{#if (eq payments \"polar\")}}\n POLAR_ACCESS_TOKEN: alchemy.secret.env.POLAR_ACCESS_TOKEN!,\n POLAR_SUCCESS_URL: alchemy.env.POLAR_SUCCESS_URL!,\n {{/if}}\n {{#if (eq dbSetup \"turso\")}}\n DATABASE_AUTH_TOKEN: alchemy.secret.env.DATABASE_AUTH_TOKEN!,\n {{/if}}\n {{#if (eq database \"mysql\")}}\n {{#if (eq orm \"drizzle\")}}\n DATABASE_HOST: alchemy.env.DATABASE_HOST!,\n DATABASE_USERNAME: alchemy.env.DATABASE_USERNAME!,\n DATABASE_PASSWORD: alchemy.secret.env.DATABASE_PASSWORD!,\n {{/if}}\n {{/if}}\n },\n dev: {\n\t\tport: 3000,\n\t},\n});\n{{/if}}\n\n{{#if (and (eq webDeploy \"cloudflare\") (eq serverDeploy \"cloudflare\"))}}\nconsole.log(\\`Web -> \\${web.url}\\`);\nconsole.log(\\`Server -> \\${server.url}\\`);\n{{else if (eq webDeploy \"cloudflare\")}}\nconsole.log(\\`Web -> \\${web.url}\\`);\n{{else if (eq serverDeploy \"cloudflare\")}}\nconsole.log(\\`Server -> \\${server.url}\\`);\n{{/if}}\n\nawait app.finalize();\n`],\n [\"packages/infra/package.json.hbs\", `{\n \"name\": \"@{{projectName}}/infra\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"dev\": \"alchemy dev\",\n \"deploy\": \"alchemy deploy\",\n \"destroy\": \"alchemy destroy\"\n }\n}\n`],\n [\"packages/env/package.json.hbs\", `{\n\t\"name\": \"@{{projectName}}/env\",\n\t\"version\": \"0.0.0\",\n\t\"private\": true,\n\t\"type\": \"module\",\n\t\"exports\": {}\n}`],\n [\"packages/env/tsconfig.json.hbs\", `{\n \"extends\": \"@{{projectName}}/config/tsconfig.base.json\",\n}\n`],\n [\"frontend/astro/astro.config.mjs.hbs\", `import { defineConfig } from 'astro/config';\nimport tailwindcss from '@tailwindcss/vite';\n{{#if (eq astroIntegration \"react\")}}\nimport react from '@astrojs/react';\n{{/if}}\n{{#if (eq astroIntegration \"vue\")}}\nimport vue from '@astrojs/vue';\n{{/if}}\n{{#if (eq astroIntegration \"svelte\")}}\nimport svelte from '@astrojs/svelte';\n{{/if}}\n{{#if (eq astroIntegration \"solid\")}}\nimport solidJs from '@astrojs/solid-js';\n{{/if}}\n{{#if (eq backend \"self\")}}\nimport node from '@astrojs/node';\n{{/if}}\n{{#if (eq runtime \"workers\")}}\nimport cloudflare from '@astrojs/cloudflare';\n{{/if}}\n\nexport default defineConfig({\n\tintegrations: [\n{{#if (eq astroIntegration \"react\")}}\n\t\treact(),\n{{/if}}\n{{#if (eq astroIntegration \"vue\")}}\n\t\tvue(),\n{{/if}}\n{{#if (eq astroIntegration \"svelte\")}}\n\t\tsvelte(),\n{{/if}}\n{{#if (eq astroIntegration \"solid\")}}\n\t\tsolidJs(),\n{{/if}}\n\t],\n\tvite: {\n\t\tplugins: [tailwindcss()],\n\t},\n{{#if (or (eq backend \"self\") (eq runtime \"workers\"))}}\n\toutput: 'server',\n{{#if (eq backend \"self\")}}\n\tadapter: node({ mode: 'standalone' }),\n{{else if (eq runtime \"workers\")}}\n\tadapter: cloudflare(),\n{{/if}}\n{{/if}}\n});\n`],\n [\"frontend/astro/package.json.hbs\", `{\n\t\"name\": \"web\",\n\t\"private\": true,\n\t\"version\": \"0.0.1\",\n\t\"type\": \"module\",\n\t\"scripts\": {\n\t\t\"dev\": \"astro dev\",\n\t\t\"build\": \"astro build\",\n\t\t\"preview\": \"astro preview\",\n\t\t\"astro\": \"astro\"\n\t},\n\t\"dependencies\": {\n\t\t\"astro\": \"^5.7.10\"\n{{#if (eq astroIntegration \"react\")}}\n\t\t,\"@astrojs/react\": \"^4.2.1\"\n\t\t,\"react\": \"^19.1.0\"\n\t\t,\"react-dom\": \"^19.1.0\"\n{{/if}}\n{{#if (eq astroIntegration \"vue\")}}\n\t\t,\"@astrojs/vue\": \"^5.0.6\"\n\t\t,\"vue\": \"^3.5.17\"\n{{/if}}\n{{#if (eq astroIntegration \"svelte\")}}\n\t\t,\"@astrojs/svelte\": \"^7.0.8\"\n\t\t,\"svelte\": \"^5.33.0\"\n{{/if}}\n{{#if (eq astroIntegration \"solid\")}}\n\t\t,\"@astrojs/solid-js\": \"^5.0.6\"\n\t\t,\"solid-js\": \"^1.9.5\"\n{{/if}}\n{{#if (eq backend \"self\")}}\n\t\t,\"@astrojs/node\": \"^9.1.3\"\n{{/if}}\n{{#if (eq runtime \"workers\")}}\n\t\t,\"@astrojs/cloudflare\": \"^12.3.1\"\n{{/if}}\n\t},\n\t\"devDependencies\": {\n\t\t\"@tailwindcss/vite\": \"^4.1.12\",\n\t\t\"tailwindcss\": \"^4.1.12\"\n{{#if (eq astroIntegration \"react\")}}\n\t\t,\"@types/react\": \"^19.1.6\"\n\t\t,\"@types/react-dom\": \"^19.1.5\"\n{{/if}}\n\t}\n}\n`],\n [\"frontend/astro/_npmrc\", `shamefully-hoist=true\n`],\n [\"frontend/astro/tsconfig.json.hbs\", `{\n\t\"extends\": \"astro/tsconfigs/strict\",\n\t\"compilerOptions\": {\n\t\t\"baseUrl\": \".\",\n\t\t\"paths\": {\n\t\t\t\"@/*\": [\"./src/*\"]\n\t\t}\n{{#if (eq astroIntegration \"react\")}}\n\t\t,\"jsx\": \"react-jsx\",\n\t\t\"jsxImportSource\": \"react\"\n{{/if}}\n{{#if (eq astroIntegration \"solid\")}}\n\t\t,\"jsx\": \"preserve\",\n\t\t\"jsxImportSource\": \"solid-js\"\n{{/if}}\n\t},\n\t\"include\": [\"src/**/*\", \"env.d.ts\"]\n}\n`],\n [\"frontend/astro/_gitignore\", `# build output\ndist/\n.output/\n\n# generated types\n.astro/\n\n# dependencies\nnode_modules/\n\n# logs\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\n\n# environment variables\n.env\n.env.production\n.env.local\n\n# macOS-specific files\n.DS_Store\n`],\n [\"packages/config/package.json.hbs\", `{\n \"name\": \"@{{projectName}}/config\",\n \"version\": \"0.0.0\",\n \"private\": true\n}\n`],\n [\"packages/config/tsconfig.base.json.hbs\", `{\n \"$schema\": \"https://json.schemastore.org/tsconfig\",\n \"compilerOptions\": {\n \"target\": \"ESNext\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"lib\": [\"ESNext\"],\n \"verbatimModuleSyntax\": true,\n \"strict\": true,\n \"skipLibCheck\": true,\n \"resolveJsonModule\": true,\n \"allowSyntheticDefaultImports\": true,\n \"esModuleInterop\": true,\n \"forceConsistentCasingInFileNames\": true,\n \"isolatedModules\": true,\n \"noUncheckedIndexedAccess\": true,\n \"noUnusedLocals\": true,\n \"noUnusedParameters\": true,\n \"noFallthroughCasesInSwitch\": true,\n \"types\": [\n {{#if (eq runtime \"node\")}}\n \"node\"\n {{else if (eq runtime \"bun\")}}\n \"bun\"\n {{else if (eq runtime \"workers\")}}\n \"node\"\n {{else}}\n \"node\"\n {{/if}}{{#if (or (eq serverDeploy \"cloudflare\") (eq webDeploy \"cloudflare\"))}},\n \"@cloudflare/workers-types\"{{/if}}\n ]\n }\n}`],\n [\"db/base/package.json.hbs\", `{\n \"name\": \"@{{projectName}}/db\",\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"default\": \"./src/index.ts\"\n },\n \"./*\": {\n \"default\": \"./src/*.ts\"\n }\n },\n \"scripts\": {},\n \"devDependencies\": {}\n}`],\n [\"db/base/tsconfig.json.hbs\", `{\n \"extends\": \"@{{projectName}}/config/tsconfig.base.json\",\n \"compilerOptions\": {\n \"declaration\": true,\n \"declarationMap\": true,\n \"sourceMap\": true,\n \"outDir\": \"dist\",\n \"composite\": true\n }\n}`],\n [\"db/base/_gitignore\", `# dependencies (bun install)\nnode_modules\n\n# output\nout\ndist\n*.tgz\n/prisma/generated\n\n# code coverage\ncoverage\n*.lcov\n\n# logs\nlogs\n_.log\nreport.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json\n\n# dotenv environment variable files\n.env\n.env.development.local\n.env.test.local\n.env.production.local\n.env.local\n\n# caches\n.eslintcache\n.cache\n*.tsbuildinfo\n\n# IntelliJ based IDEs\n.idea\n\n# Finder (MacOS) folder config\n.DS_Store\n`],\n [\"addons/biome/biome.json.hbs\", `{\n \"$schema\": \"./node_modules/@biomejs/biome/configuration_schema.json\",\n\t\"vcs\": {\n\t\t\"enabled\": false,\n\t\t\"clientKind\": \"git\",\n\t\t\"useIgnoreFile\": false\n\t},\n\t\"files\": {\n\t\t\"ignoreUnknown\": false,\n\t\t\"includes\": [\n\t\t\t\"**\",\n\t\t\t\"!**/.next\",\n\t\t\t\"!**/dist\",\n\t\t\t\"!**/.turbo\",\n\t\t\t\"!**/dev-dist\",\n\t\t\t\"!**/.zed\",\n\t\t\t\"!**/.vscode\",\n\t\t\t\"!**/routeTree.gen.ts\",\n\t\t\t\"!**/src-tauri\",\n\t\t\t\"!**/.nuxt\",\n\t\t\t\"!bts.jsonc\",\n\t\t\t\"!**/.expo\",\n\t\t\t\"!**/.wrangler\",\n\t\t\t\"!**/.alchemy\",\n\t\t\t\"!**/.svelte-kit\",\n\t\t\t\"!**/wrangler.jsonc\",\n\t\t\t\"!**/.source\",\n\t\t\t\"!**/convex/_generated\"\n\t\t]\n\t},\n\t\"formatter\": {\n\t\t\"enabled\": true,\n\t\t\"indentStyle\": \"tab\"\n\t},\n\t\"assist\": { \"actions\": { \"source\": { \"organizeImports\": \"on\" } } },\n\t\"linter\": {\n\t\t\"enabled\": true,\n\t\t\"rules\": {\n\t\t\t\"recommended\": true,\n\t\t\t\"correctness\": {\n\t\t\t\t\"useExhaustiveDependencies\": \"info\"\n\t\t\t},\n\t\t\t\"nursery\": {\n\t\t\t\t\"useSortedClasses\": {\n\t\t\t\t\t\"level\": \"warn\",\n\t\t\t\t\t\"fix\": \"safe\",\n\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\"functions\": [\"clsx\", \"cva\", \"cn\"]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"style\": {\n\t\t\t\t\"noParameterAssign\": \"error\",\n\t\t\t\t\"useAsConstAssertion\": \"error\",\n\t\t\t\t\"useDefaultParameterLast\": \"error\",\n\t\t\t\t\"useEnumInitializers\": \"error\",\n\t\t\t\t\"useSelfClosingElements\": \"error\",\n\t\t\t\t\"useSingleVarDeclarator\": \"error\",\n\t\t\t\t\"noUnusedTemplateLiteral\": \"error\",\n\t\t\t\t\"useNumberNamespace\": \"error\",\n\t\t\t\t\"noInferrableTypes\": \"error\",\n\t\t\t\t\"noUselessElse\": \"error\"\n\t\t\t}\n\t\t}\n\t},\n\t\"javascript\": {\n\t\t\"formatter\": {\n\t\t\t\"quoteStyle\": \"double\"\n\t\t}\n\t},\n\t\"css\": {\n\t\t\"parser\": {\n\t\t\t\"tailwindDirectives\": true\n\t\t}\n\t}\n\t{{#if (or (includes frontend \"svelte\") (includes frontend \"nuxt\"))}}\n\t,\n\t\"overrides\": [\n\t\t{\n\t\t\t\"includes\": [\"**/*.svelte\", \"**/*.vue\"],\n\t\t\t\"linter\": {\n\t\t\t\t\"rules\": {\n\t\t\t\t\t\"style\": {\n\t\t\t\t\t\t\"useConst\": \"off\",\n\t\t\t\t\t\t\"useImportType\": \"off\"\n\t\t\t\t\t},\n\t\t\t\t\t\"correctness\": {\n\t\t\t\t\t\t\"noUnusedVariables\": \"off\",\n\t\t\t\t\t\t\"noUnusedImports\": \"off\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t]\n\t{{/if}}\n}\n`],\n [\"addons/lefthook/lefthook.yml.hbs\", `# Lefthook configuration\n# https://github.com/evilmartians/lefthook\n\npre-commit:\n parallel: true\n jobs:\n{{#if (includes addons \"biome\")}}\n - name: biome\n glob: \"*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}\"\n run: {{packageManager}} biome check --write --no-errors-on-unmatched --files-ignore-unknown=true {staged_files}\n stage_fixed: true\n{{else if (includes addons \"oxlint\")}}\n - name: oxlint\n run: {{packageManager}} oxlint --fix {staged_files}\n stage_fixed: true\n - name: oxfmt\n run: {{packageManager}} oxfmt --write {staged_files}\n stage_fixed: true\n{{else}}\n # Add your pre-commit commands here\n # Example:\n # - name: lint\n # run: {{packageManagerRunCmd}} lint\n{{/if}}\n`],\n [\"rust-base/crates/client/Trunk.toml.hbs\", `[build]\ntarget = \"index.html\"\ndist = \"dist\"\n\n[watch]\nwatch = [\"src\", \"style\", \"index.html\"]\nignore = [\"dist\"]\n\n[serve]\naddress = \"127.0.0.1\"\nport = 8080\nopen = false\n\n[clean]\ndist = \"dist\"\n`],\n [\"rust-base/crates/client/Cargo.toml.hbs\", `[package]\nname = \"{{projectName}}-client\"\nversion.workspace = true\nedition.workspace = true\nauthors.workspace = true\nlicense.workspace = true\n\n[lib]\ncrate-type = [\"cdylib\", \"rlib\"]\n\n[dependencies]\n# Leptos framework\nleptos.workspace = true\nleptos_router.workspace = true\nleptos_meta.workspace = true\n\n# Logging\nlog.workspace = true\nconsole_log.workspace = true\n\n# WASM utilities\nwasm-bindgen.workspace = true\nwasm-bindgen-futures.workspace = true\nweb-sys.workspace = true\nconsole_error_panic_hook.workspace = true\n\n# Serialization\nserde.workspace = true\nserde_json.workspace = true\n\n[features]\ndefault = []\nhydrate = [\"leptos/hydrate\", \"leptos_router/hydrate\", \"leptos_meta/hydrate\"]\nssr = [\"leptos/ssr\", \"leptos_router/ssr\", \"leptos_meta/ssr\"]\n`],\n [\"rust-base/crates/client/index.html.hbs\", `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <meta name=\"description\" content=\"{{projectName}} - A Rust WASM application built with Leptos\" />\n <title>{{projectName}}</title>\n <link data-trunk rel=\"css\" href=\"style/main.css\" />\n <link data-trunk rel=\"rust\" href=\"Cargo.toml\" data-wasm-opt=\"z\" />\n </head>\n <body></body>\n</html>\n`],\n [\"rust-base/crates/cli/Cargo.toml.hbs\", `[package]\nname = \"{{projectName}}-cli\"\nversion.workspace = true\nedition.workspace = true\nauthors.workspace = true\nlicense.workspace = true\ndescription = \"Command-line interface for {{projectName}}\"\n\n[dependencies]\n# CLI argument parsing\nclap.workspace = true\n\n# Async runtime\ntokio.workspace = true\n\n# Serialization\nserde.workspace = true\nserde_json.workspace = true\n\n# Error handling\nanyhow.workspace = true\n\n# Logging\ntracing.workspace = true\ntracing-subscriber.workspace = true\n\n# Environment\ndotenvy.workspace = true\n\n[[bin]]\nname = \"cli\"\npath = \"src/main.rs\"\n`],\n [\"rust-base/crates/dioxus-client/Dioxus.toml.hbs\", `[application]\nname = \"{{projectName}}\"\ndefault_platform = \"web\"\n\n[web.app]\ntitle = \"{{projectName}}\"\n\n[web.watcher]\nreload_html = true\nwatch_path = [\"src\", \"assets\"]\n\n[web.resource]\ndev_serve_crate = true\nstyle = [\"assets/main.css\"]\n\n[web.https]\nenabled = false\n`],\n [\"rust-base/crates/dioxus-client/Cargo.toml.hbs\", `[package]\nname = \"{{projectName}}-client\"\nversion.workspace = true\nedition.workspace = true\nauthors.workspace = true\nlicense.workspace = true\n\n[[bin]]\nname = \"{{projectName}}-client\"\npath = \"src/main.rs\"\n\n[dependencies]\n# Dioxus framework\ndioxus.workspace = true\ndioxus-router.workspace = true\n\n# Logging\ntracing.workspace = true\ndioxus-logger.workspace = true\n\n# WASM utilities\nwasm-bindgen.workspace = true\nconsole_error_panic_hook.workspace = true\n\n# Serialization\nserde.workspace = true\nserde_json.workspace = true\n\n[features]\ndefault = [\"web\"]\nweb = [\"dioxus/web\"]\ndesktop = [\"dioxus/desktop\"]\n`],\n [\"rust-base/crates/proto/build.rs.hbs\", `fn main() -> Result<(), Box<dyn std::error::Error>> {\n // Compile the protobuf definitions\n tonic_build::configure()\n .build_server(true)\n .build_client(true)\n .out_dir(\"src/generated\")\n .compile_protos(&[\"proto/greeter.proto\"], &[\"proto\"])?;\n\n // Tell Cargo to rerun this build script if the proto files change\n println!(\"cargo:rerun-if-changed=proto/greeter.proto\");\n\n Ok(())\n}\n`],\n [\"rust-base/crates/proto/Cargo.toml.hbs\", `[package]\nname = \"{{projectName}}-proto\"\nversion.workspace = true\nedition.workspace = true\nauthors.workspace = true\nlicense.workspace = true\n\n[dependencies]\ntonic.workspace = true\nprost.workspace = true\n\n[build-dependencies]\ntonic-build.workspace = true\n`],\n [\"rust-base/crates/server/Cargo.toml.hbs\", `[package]\nname = \"{{projectName}}-server\"\nversion.workspace = true\nedition.workspace = true\nauthors.workspace = true\nlicense.workspace = true\n\n[dependencies]\n# Async runtime\ntokio.workspace = true\n\n# Serialization\nserde.workspace = true\nserde_json.workspace = true\n\n# Error handling\nthiserror.workspace = true\nanyhow.workspace = true\n\n# Logging\ntracing.workspace = true\ntracing-subscriber.workspace = true\n\n# Environment\ndotenvy.workspace = true\n\n{{#if (eq rustWebFramework \"axum\")}}\n# Web framework\naxum.workspace = true\ntower.workspace = true\ntower-http.workspace = true\n{{/if}}\n{{#if (eq rustWebFramework \"actix-web\")}}\n# Web framework\nactix-web.workspace = true\nactix-rt.workspace = true\nactix-cors.workspace = true\n{{/if}}\n\n{{#if (eq rustOrm \"sqlx\")}}\n# Database\nsqlx.workspace = true\n{{/if}}\n{{#if (eq rustOrm \"sea-orm\")}}\n# Database\nsea-orm.workspace = true\n{{/if}}\n\n{{#if (eq rustApi \"tonic\")}}\n# gRPC\ntonic.workspace = true\nprost.workspace = true\n{{projectName}}-proto = { path = \"../proto\" }\ntokio-stream = \"0.1\"\n{{/if}}\n{{#if (eq rustApi \"async-graphql\")}}\n# GraphQL\nasync-graphql.workspace = true\n{{#if (eq rustWebFramework \"axum\")}}\nasync-graphql-axum.workspace = true\n{{/if}}\n{{#if (eq rustWebFramework \"actix-web\")}}\nasync-graphql-actix-web.workspace = true\n{{/if}}\n{{/if}}\n\n{{#if (includes rustLibraries \"validator\")}}\nvalidator.workspace = true\n{{/if}}\n{{#if (includes rustLibraries \"jsonwebtoken\")}}\njsonwebtoken.workspace = true\n{{/if}}\n{{#if (includes rustLibraries \"argon2\")}}\nargon2.workspace = true\n{{/if}}\n{{#if (eq rustCli \"clap\")}}\n\n# CLI\nclap.workspace = true\n{{/if}}\n\n[[bin]]\nname = \"server\"\npath = \"src/main.rs\"\n\n{{#if (or (includes rustLibraries \"tokio-test\") (includes rustLibraries \"mockall\"))}}\n[dev-dependencies]\n{{#if (includes rustLibraries \"tokio-test\")}}\ntokio-test.workspace = true\n{{/if}}\n{{#if (includes rustLibraries \"mockall\")}}\nmockall.workspace = true\n{{/if}}\n{{/if}}\n`],\n [\"rust-base/crates/tui/Cargo.toml.hbs\", `[package]\nname = \"{{projectName}}-tui\"\nversion.workspace = true\nedition.workspace = true\nauthors.workspace = true\nlicense.workspace = true\ndescription = \"Terminal user interface for {{projectName}}\"\n\n[dependencies]\n# TUI framework\nratatui.workspace = true\ncrossterm.workspace = true\n\n# Async runtime\ntokio.workspace = true\n\n# Serialization\nserde.workspace = true\nserde_json.workspace = true\n\n# Error handling\nanyhow.workspace = true\n\n# Logging\ntracing.workspace = true\ntracing-subscriber.workspace = true\ntracing-appender.workspace = true\n\n# Environment\ndotenvy.workspace = true\n\n[[bin]]\nname = \"tui\"\npath = \"src/main.rs\"\n`],\n [\"frontend/qwik/public/manifest.json\", `{\n \"short_name\": \"Better T Stack\",\n \"name\": \"Better T Stack - Qwik\",\n \"icons\": [\n {\n \"src\": \"/favicon.svg\",\n \"sizes\": \"any\",\n \"type\": \"image/svg+xml\"\n }\n ],\n \"start_url\": \"/\",\n \"background_color\": \"#0a0a0a\",\n \"display\": \"standalone\",\n \"scope\": \"/\",\n \"theme_color\": \"#AC7EF4\"\n}\n`],\n [\"frontend/qwik/public/robots.txt\", `User-agent: *\nAllow: /\n`],\n [\"frontend/qwik/public/favicon.svg\", `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 200 200\">\n <rect width=\"200\" height=\"200\" rx=\"20\" fill=\"#AC7EF4\"/>\n <text x=\"100\" y=\"140\" font-family=\"Arial Black, sans-serif\" font-size=\"120\" text-anchor=\"middle\" fill=\"white\">Q</text>\n</svg>\n`],\n [\"frontend/qwik/src/entry.preview.tsx\", `import { createQwikCity } from \"@builder.io/qwik-city/middleware/node\";\nimport qwikCityPlan from \"@qwik-city-plan\";\n\nimport render from \"./entry.ssr\";\n\nconst { router, notFound } = createQwikCity({ render, qwikCityPlan });\n\nexport { notFound, router };\n`],\n [\"frontend/qwik/src/root.tsx.hbs\", `import { component$ } from \"@builder.io/qwik\";\nimport {\n QwikCityProvider,\n RouterOutlet,\n ServiceWorkerRegister,\n} from \"@builder.io/qwik-city\";\nimport { RouterHead } from \"./components/router-head/router-head\";\n\nimport \"./global.css\";\n\nexport default component$(() => {\n return (\n <QwikCityProvider>\n <head>\n <meta charset=\"utf-8\" />\n <link rel=\"manifest\" href=\"/manifest.json\" />\n <RouterHead />\n <ServiceWorkerRegister />\n </head>\n <body lang=\"en\">\n <RouterOutlet />\n </body>\n </QwikCityProvider>\n );\n});\n`],\n [\"frontend/qwik/src/entry.ssr.tsx\", `import { renderToStream, type RenderToStreamOptions } from \"@builder.io/qwik/server\";\nimport { manifest } from \"@qwik-client-manifest\";\n\nimport Root from \"./root\";\n\nexport default function (opts: RenderToStreamOptions) {\n return renderToStream(<Root />, {\n manifest,\n ...opts,\n containerAttributes: {\n lang: \"en-us\",\n ...opts.containerAttributes,\n },\n serverData: {\n ...opts.serverData,\n },\n });\n}\n`],\n [\"frontend/qwik/src/global.css.hbs\", `{{#if (eq cssFramework \"tailwind\")}}\n@import \"tailwindcss\";\n{{else}}\n:root {\n --bg-color: #ffffff;\n --text-color: #1a1a1a;\n --border-color: #e5e7eb;\n --muted-color: #6b7280;\n}\n\n@media (prefers-color-scheme: dark) {\n :root {\n --bg-color: #0a0a0a;\n --text-color: #fafafa;\n --border-color: #27272a;\n --muted-color: #a1a1aa;\n }\n}\n\n* {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n background-color: var(--bg-color);\n color: var(--text-color);\n line-height: 1.5;\n}\n\na {\n color: inherit;\n text-decoration: none;\n}\n\na:hover {\n text-decoration: underline;\n}\n{{/if}}\n`],\n [\"frontend/svelte/src/app.d.ts\", `// See https://svelte.dev/docs/kit/types#app.d.ts\n// for information about these interfaces\ndeclare global {\n namespace App {\n // interface Error {}\n // interface Locals {}\n // interface PageData {}\n // interface PageState {}\n // interface Platform {}\n }\n}\n\nexport {};\n`],\n [\"frontend/svelte/src/app.html\", `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <link rel=\"icon\" href=\"%sveltekit.assets%/favicon.png\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n %sveltekit.head%\n </head>\n <body data-sveltekit-preload-data=\"hover\">\n <div style=\"display: contents\">%sveltekit.body%</div>\n </body>\n</html>\n`],\n [\"frontend/svelte/src/app.css\", `@import \"tailwindcss\";\n\nbody {\n @apply bg-neutral-950 text-neutral-100;\n}\n`],\n [\"frontend/react/web-base/components.json.hbs\", `{{#if (eq uiLibrary \"shadcn-ui\")}}\n{\n \"$schema\": \"https://ui.shadcn.com/schema.json\",\n \"style\": \"base-lyra\",\n \"rsc\": false,\n \"tsx\": true,\n \"tailwind\": {\n \"config\": \"\",\n \"css\": \"src/index.css\",\n \"baseColor\": \"neutral\",\n \"cssVariables\": true,\n \"prefix\": \"\"\n },\n \"iconLibrary\": \"lucide\",\n \"aliases\": {\n \"components\": \"@/components\",\n \"utils\": \"@/lib/utils\",\n \"ui\": \"@/components/ui\",\n \"lib\": \"@/lib\",\n \"hooks\": \"@/hooks\"\n },\n \"menuColor\": \"default\",\n \"menuAccent\": \"subtle\",\n \"registries\": {}\n}\n{{/if}}\n`],\n [\"frontend/react/web-base/_gitignore\", `# Dependencies\n/node_modules\n/.pnp\n.pnp.*\n.yarn/*\n!.yarn/patches\n!.yarn/plugins\n!.yarn/releases\n!.yarn/versions\n\n# Testing\n/coverage\n\n# Build outputs\n/.next/\n/out/\n/build/\n/dist/\n.vinxi\n.output\n.react-router/\n.tanstack/\n.nitro/\n\n# Deployment\n.vercel\n.netlify\n.wrangler\n.alchemy\n\n# Environment & local files\n.env*\n!.env.example\n.DS_Store\n*.pem\n*.local\n\n# Logs\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n.pnpm-debug.log*\n*.log*\n\n# TypeScript\n*.tsbuildinfo\nnext-env.d.ts\n\n# IDE\n.vscode/*\n!.vscode/extensions.json\n.idea\n\n# Other\ndev-dist\n\n.wrangler\n.dev.vars*\n\n.open-next\n`],\n [\"frontend/svelte/static/favicon.png\", `[Binary file]`],\n [\"frontend/react/tanstack-start/package.json.hbs\", `{\n \"name\": \"web\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"build\": \"vite build\",\n \"serve\": \"vite preview\",\n \"dev\": \"vite dev\"\n },\n \"dependencies\": {\n{{#if (eq uiLibrary \"shadcn-ui\")}}\n \"@base-ui/react\": \"^1.0.0\",\n \"shadcn\": \"^3.6.2\",\n \"@tanstack/react-form\": \"^1.23.5\",\n \"class-variance-authority\": \"^0.7.1\",\n \"clsx\": \"^2.1.1\",\n \"lucide-react\": \"^0.525.0\",\n \"next-themes\": \"^0.4.6\",\n \"sonner\": \"^2.0.3\",\n \"tailwind-merge\": \"^3.3.1\",\n{{/if}}\n{{#if (eq cssFramework \"tailwind\")}}\n \"@tailwindcss/vite\": \"^4.1.8\",\n \"tailwindcss\": \"^4.1.3\",\n \"tw-animate-css\": \"^1.2.5\",\n{{/if}}\n \"@tanstack/react-query\": \"^5.80.6\",\n \"@tanstack/react-router\": \"^1.141.1\",\n \"@tanstack/react-router-with-query\": \"^1.130.17\",\n \"@tanstack/react-start\": \"^1.141.1\",\n \"@tanstack/router-plugin\": \"^1.141.1\",\n \"react\": \"19.2.3\",\n \"react-dom\": \"19.2.3\",\n \"vite-tsconfig-paths\": \"^5.1.4\"\n },\n \"devDependencies\": {\n \"@tanstack/react-router-devtools\": \"^1.141.1\",\n \"@testing-library/dom\": \"^10.4.0\",\n \"@testing-library/react\": \"^16.2.0\",\n \"@types/react\": \"19.2.7\",\n \"@types/react-dom\": \"19.2.3\",\n \"@vitejs/plugin-react\": \"^5.0.4\",\n \"jsdom\": \"^26.0.0\",\n \"vite\": \"^7.0.2\",\n \"web-vitals\": \"^5.0.3\"\n }\n}\n`],\n [\"frontend/react/tanstack-start/tsconfig.json.hbs\", `{\n \"include\": [\"**/*.ts\", \"**/*.tsx\"],\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"jsx\": \"react-jsx\",\n \"module\": \"ESNext\",\n \"lib\": [\"ES2022\", \"DOM\", \"DOM.Iterable\"],\n \"types\": [\"vite/client\"],\n\n /* Bundler mode */\n \"moduleResolution\": \"bundler\",\n \"allowImportingTsExtensions\": true,\n \"verbatimModuleSyntax\": true,\n \"noEmit\": true,\n\n /* Linting */\n \"skipLibCheck\": true,\n \"strict\": true,\n \"noUnusedLocals\": true,\n \"noUnusedParameters\": true,\n \"noFallthroughCasesInSwitch\": true,\n \"noUncheckedSideEffectImports\": true,\n \"baseUrl\": \".\",\n \"paths\": {\n \"@/*\": [\"./src/*\"]\n }\n }\n}\n`],\n [\"frontend/react/tanstack-start/vite.config.ts.hbs\", `import { defineConfig } from \"vite\";\nimport tsconfigPaths from \"vite-tsconfig-paths\";\nimport { tanstackStart } from \"@tanstack/react-start/plugin/vite\";\nimport tailwindcss from \"@tailwindcss/vite\";\nimport viteReact from \"@vitejs/plugin-react\";\n\nexport default defineConfig({\n plugins: [\n tsconfigPaths(),\n tailwindcss(),\n tanstackStart(),\n viteReact(),\n ],\n server: {\n port: 3001,\n },\n{{#if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\n ssr: {\n noExternal: [\"@convex-dev/better-auth\"],\n },\n{{/if}}\n});\n`],\n [\"frontend/react/tanstack-router/package.json.hbs\", `{\n\t\"name\": \"web\",\n\t\"version\": \"0.0.0\",\n\t\"private\": true,\n\t\"type\": \"module\",\n\t\"scripts\": {\n\t\t\"dev\": \"vite dev\",\n\t\t\"build\": \"vite build\",\n\t\t\"serve\": \"vite preview\",\n\t\t\"start\": \"vite\",\n\t\t\"check-types\": \"tsc --noEmit\"\n\t},\n\t\"dependencies\": {\n{{#if (eq uiLibrary \"shadcn-ui\")}}\n \"@hookform/resolvers\": \"^5.1.1\",\n \"@base-ui/react\": \"^1.0.0\",\n \"shadcn\": \"^3.6.2\",\n \"@tanstack/react-form\": \"^1.12.3\",\n\t\t\"class-variance-authority\": \"^0.7.1\",\n\t\t\"clsx\": \"^2.1.1\",\n\t\t\"lucide-react\": \"^0.473.0\",\n \"next-themes\": \"^0.4.6\",\n \"sonner\": \"^2.0.5\",\n\t\t\"tailwind-merge\": \"^3.3.1\",\n{{/if}}\n{{#if (eq cssFramework \"tailwind\")}}\n\t\t\"@tailwindcss/vite\": \"^4.0.15\",\n\t\t\"tw-animate-css\": \"^1.2.5\",\n{{/if}}\n\t\t\"@tanstack/react-router\": \"^1.141.1\",\n\t\t\"react\": \"19.2.3\",\n\t\t\"react-dom\": \"19.2.3\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@tanstack/react-router-devtools\": \"^1.141.1\",\n\t\t\"@tanstack/router-plugin\": \"^1.141.1\",\n\t\t\"@types/node\": \"^22.13.14\",\n\t\t\"@types/react\": \"19.2.7\",\n\t\t\"@types/react-dom\": \"19.2.3\",\n\t\t\"@vitejs/plugin-react\": \"^4.3.4\",\n{{#if (eq cssFramework \"tailwind\")}}\n\t\t\"postcss\": \"^8.5.3\",\n\t\t\"tailwindcss\": \"^4.0.15\",\n{{/if}}\n\t\t\"vite\": \"^6.2.2\"\n\t}\n}\n`],\n [\"frontend/react/tanstack-router/index.html.hbs\", `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>{{projectName}}</title>\n </head>\n\n <body>\n <div id=\"app\"></div>\n <script type=\"module\" src=\"/src/main.tsx\"></script>\n </body>\n</html>\n`],\n [\"frontend/react/tanstack-router/tsconfig.json.hbs\", `{\n \"compilerOptions\": {\n \"strict\": true,\n \"esModuleInterop\": true,\n \"jsx\": \"react-jsx\",\n \"target\": \"ESNext\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"Bundler\",\n \"verbatimModuleSyntax\": true,\n \"skipLibCheck\": true,\n \"types\": [\"vite/client\"],\n \"rootDirs\": [\".\"],\n \"baseUrl\": \".\",\n \"paths\": {\n \"@/*\": [\"./src/*\"]\n }\n }\n}\n`],\n [\"frontend/react/tanstack-router/vite.config.ts.hbs\", `import tailwindcss from \"@tailwindcss/vite\";\nimport { tanstackRouter } from \"@tanstack/router-plugin/vite\";\nimport react from \"@vitejs/plugin-react\";\nimport path from \"node:path\";\nimport { defineConfig } from \"vite\";\n\nexport default defineConfig({\n plugins: [\n tailwindcss(),\n tanstackRouter({}),\n react(),\n ],\n resolve: {\n alias: {\n \"@\": path.resolve(__dirname, \"./src\"),\n },\n },\n server: {\n port: 3001,\n },\n});`],\n [\"frontend/angular/public/favicon.svg\", `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 256 256\">\n <rect width=\"256\" height=\"256\" fill=\"#0f0f0f\" rx=\"32\"/>\n <text x=\"128\" y=\"170\" text-anchor=\"middle\" font-family=\"monospace\" font-size=\"140\" font-weight=\"bold\" fill=\"#fafafa\">T</text>\n</svg>\n`],\n [\"frontend/react/next/package.json.hbs\", `{\n \"name\": \"web\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"scripts\": {\n \"dev\": \"next dev --port 3001\",\n \"build\": \"next build\",\n \"start\": \"next start\"\n },\n \"dependencies\": {\n{{#if (eq uiLibrary \"shadcn-ui\")}}\n \"@base-ui/react\": \"^1.0.0\",\n \"shadcn\": \"^3.6.2\",\n \"@tanstack/react-form\": \"^1.27.3\",\n \"class-variance-authority\": \"^0.7.1\",\n \"clsx\": \"^2.1.1\",\n \"lucide-react\": \"^0.546.0\",\n \"next-themes\": \"^0.4.6\",\n \"sonner\": \"^2.0.5\",\n \"tailwind-merge\": \"^3.3.1\",\n{{/if}}\n{{#if (eq cssFramework \"tailwind\")}}\n \"tw-animate-css\": \"^1.3.4\",\n{{/if}}\n \"next\": \"^16.1.1\",\n \"react\": \"^19.2.3\",\n \"react-dom\": \"^19.2.3\",\n \"babel-plugin-react-compiler\": \"^1.0.0\"\n },\n \"devDependencies\": {\n{{#if (eq cssFramework \"tailwind\")}}\n \"@tailwindcss/postcss\": \"^4.1.10\",\n \"tailwindcss\": \"^4.1.10\",\n{{/if}}\n \"@types/node\": \"^20\",\n \"@types/react\": \"^19.2.7\",\n \"@types/react-dom\": \"^19.2.3\",\n \"typescript\": \"^5\"\n }\n}\n`],\n [\"frontend/react/next/next-env.d.ts.hbs\", `/// <reference types=\"next\" />\n/// <reference types=\"next/image-types/global\" />\n\n// NOTE: This file should not be edited\n// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.\n`],\n [\"frontend/react/next/next.config.ts.hbs\", `import \"@{{projectName}}/env/web\";\n{{#if (eq webDeploy \"cloudflare\")}}\nimport { initOpenNextCloudflareForDev } from \"@opennextjs/cloudflare\";\n{{/if}}\nimport type { NextConfig } from \"next\";\n\nconst nextConfig: NextConfig = {\n\ttypedRoutes: true,\n\treactCompiler: true,\n\t{{#if (includes examples \"ai\")}}\n\ttranspilePackages: [\"shiki\"],\n\t{{/if}}\n\t{{#if (eq dbSetup \"turso\")}}\n\tserverExternalPackages: [\"libsql\", \"@libsql/client\"],\n\t{{/if}}\n};\n\nexport default nextConfig;\n\n{{#if (eq webDeploy \"cloudflare\")}}\ninitOpenNextCloudflareForDev();\n{{/if}}\n`],\n [\"frontend/react/next/postcss.config.mjs.hbs\", `const config = {\n plugins: [\"@tailwindcss/postcss\"],\n};\n\nexport default config;\n`],\n [\"frontend/react/next/tsconfig.json.hbs\", `{\n \"compilerOptions\": {\n \"target\": \"ES2017\",\n \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n \"allowJs\": true,\n \"skipLibCheck\": true,\n \"strict\": true,\n \"noEmit\": true,\n \"esModuleInterop\": true,\n \"module\": \"esnext\",\n \"moduleResolution\": \"bundler\",\n \"resolveJsonModule\": true,\n \"isolatedModules\": true,\n \"verbatimModuleSyntax\": true,\n \"jsx\": \"preserve\",\n \"incremental\": true,\n \"plugins\": [\n {\n \"name\": \"next\"\n }\n ],\n \"paths\": {\n \"@/*\": [\"./src/*\"]\n }{{#if (or (eq serverDeploy \"cloudflare\") (eq webDeploy \"cloudflare\"))}},\n \"types\": [\n \"@cloudflare/workers-types\"\n ]{{/if}}\n },\n \"include\": [\n {{#if (eq serverDeploy \"cloudflare\")}}\n \"../server/env.d.ts\",\n {{/if}}\n \"./next-env.d.ts\",\n \"./**/*.ts\",\n \"./**/*.tsx\",\n \"./.next/types/**/*.ts\"\n ],\n \"exclude\": [\n \"./node_modules\"\n ]\n}\n`],\n [\"frontend/angular/src/styles.css.hbs\", `{{#if (eq cssFramework \"tailwind\")}}\n@import \"tailwindcss\";\n{{/if}}\n\n:root {\n --background: #ffffff;\n --foreground: #0a0a0a;\n --muted-color: #6b7280;\n --border-color: #e5e7eb;\n}\n\n@media (prefers-color-scheme: dark) {\n :root {\n --background: #0a0a0a;\n --foreground: #ededed;\n --muted-color: #9ca3af;\n --border-color: #374151;\n }\n}\n\n* {\n box-sizing: border-box;\n padding: 0;\n margin: 0;\n}\n\nhtml,\nbody {\n max-width: 100vw;\n overflow-x: hidden;\n}\n\nbody {\n color: var(--foreground);\n background: var(--background);\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen,\n Ubuntu, Cantarell, \"Open Sans\", \"Helvetica Neue\", sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\na {\n color: inherit;\n text-decoration: none;\n}\n`],\n [\"frontend/angular/src/main.ts\", `import { bootstrapApplication } from \"@angular/platform-browser\";\n\nimport { AppComponent } from \"./app/app.component\";\nimport { appConfig } from \"./app/app.config\";\n\nbootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err));\n`],\n [\"frontend/angular/src/index.html\", `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <title>Better T Stack - Angular</title>\n <base href=\"/\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <link rel=\"icon\" type=\"image/svg+xml\" href=\"favicon.svg\" />\n </head>\n <body>\n <app-root></app-root>\n </body>\n</html>\n`],\n [\"frontend/react/react-router/react-router.config.ts\", `import type { Config } from \"@react-router/dev/config\";\n\nexport default {\n ssr: false,\n appDirectory: \"src\",\n} satisfies Config;\n`],\n [\"frontend/react/react-router/package.json.hbs\", `{\n \"name\": \"web\",\n \"private\": true,\n \"type\": \"module\",\n \"scripts\": {\n \"build\": \"react-router build\",\n \"dev\": \"react-router dev\",\n \"start\": \"react-router-serve ./build/server/index.js\",\n \"typecheck\": \"react-router typegen && tsc\"\n },\n \"dependencies\": {\n{{#if (eq uiLibrary \"shadcn-ui\")}}\n \"@base-ui/react\": \"^1.0.0\",\n \"shadcn\": \"^3.6.2\",\n \"@tanstack/react-form\": \"^1.27.3\",\n \"class-variance-authority\": \"^0.7.1\",\n \"clsx\": \"^2.1.1\",\n \"lucide-react\": \"^0.511.0\",\n \"next-themes\": \"^0.4.6\",\n \"sonner\": \"^2.0.3\",\n \"tailwind-merge\": \"^3.3.0\",\n{{/if}}\n{{#if (eq cssFramework \"tailwind\")}}\n \"tw-animate-css\": \"^1.3.2\",\n{{/if}}\n \"@react-router/fs-routes\": \"^7.10.1\",\n \"@react-router/node\": \"^7.10.1\",\n \"@react-router/serve\": \"^7.10.1\",\n \"isbot\": \"^5.1.28\",\n \"react\": \"19.2.3\",\n \"react-dom\": \"19.2.3\",\n \"react-router\": \"^7.10.1\"\n },\n \"devDependencies\": {\n \"@react-router/dev\": \"^7.10.1\",\n{{#if (eq cssFramework \"tailwind\")}}\n \"@tailwindcss/vite\": \"^4.1.18\",\n \"tailwindcss\": \"^4.1.18\",\n{{/if}}\n \"@types/node\": \"^20\",\n \"@types/react\": \"~19.2.7\",\n \"@types/react-dom\": \"^19.2.3\",\n \"react-router-devtools\": \"^1.1.0\",\n \"typescript\": \"^5.8.3\",\n \"vite\": \"^7.2.7\",\n \"vite-tsconfig-paths\": \"^5.1.4\"\n }\n}\n`],\n [\"frontend/react/react-router/tsconfig.json.hbs\", `{\n \"include\": [\n \"**/*\",\n \"**/.server/**/*\",\n \"**/.client/**/*\",\n \".react-router/types/**/*\"\n ],\n \"compilerOptions\": {\n \"lib\": [\"DOM\", \"DOM.Iterable\", \"ES2022\"],\n \"types\": [\"node\", \"vite/client\"],\n \"target\": \"ES2022\",\n \"module\": \"ES2022\",\n \"moduleResolution\": \"bundler\",\n \"jsx\": \"react-jsx\",\n \"rootDirs\": [\".\", \"./.react-router/types\"],\n \"baseUrl\": \".\",\n \"paths\": {\n \"@/*\": [\"./src/*\"]\n },\n \"esModuleInterop\": true,\n \"verbatimModuleSyntax\": true,\n \"noEmit\": true,\n \"resolveJsonModule\": true,\n \"skipLibCheck\": true,\n \"strict\": true\n }\n}\n`],\n [\"frontend/react/react-router/vite.config.ts.hbs\", `import { reactRouter } from \"@react-router/dev/vite\";\nimport tailwindcss from \"@tailwindcss/vite\";\nimport { defineConfig } from \"vite\";\nimport tsconfigPaths from \"vite-tsconfig-paths\";\n\nexport default defineConfig({\n plugins: [\n tailwindcss(),\n reactRouter(),\n tsconfigPaths(),\n ],\n});`],\n [\"frontend/redwood/web/package.json.hbs\", `{\n \"name\": \"web\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@redwoodjs/forms\": \"^8.6.1\",\n \"@redwoodjs/router\": \"^8.6.1\",\n \"@redwoodjs/web\": \"^8.6.1\",\n \"react\": \"^19.1.0\",\n \"react-dom\": \"^19.1.0\"\n },\n \"devDependencies\": {\n \"@redwoodjs/vite\": \"^8.6.1\",\n \"@types/react\": \"^19.1.6\",\n \"@types/react-dom\": \"^19.1.5\",\n \"typescript\": \"^5.7.3\"\n }\n}\n`],\n [\"frontend/redwood/web/tsconfig.json\", `{\n \"compilerOptions\": {\n \"noEmit\": true,\n \"allowJs\": true,\n \"esModuleInterop\": true,\n \"target\": \"esnext\",\n \"module\": \"esnext\",\n \"moduleResolution\": \"bundler\",\n \"baseUrl\": \"./\",\n \"strict\": true,\n \"skipLibCheck\": true,\n \"jsx\": \"preserve\",\n \"rootDirs\": [\n \"./src\",\n \"../.redwood/types/mirror/web/src\",\n \"../api/src\",\n \"../.redwood/types/mirror/api/src\"\n ],\n \"paths\": {\n \"src/*\": [\"./src/*\", \"../.redwood/types/mirror/web/src/*\"],\n \"$api/*\": [\"../api/src/*\", \"../.redwood/types/mirror/api/src/*\"],\n \"types/*\": [\"./types/*\", \"../.redwood/types/mirror/web/types/*\"],\n \"@redwoodjs/testing\": [\"../node_modules/@redwoodjs/testing/web\"]\n },\n \"typeRoots\": [\"../node_modules/@types\", \"./node_modules/@types\"],\n \"types\": [\"node\"],\n \"lib\": [\"esnext\", \"dom\"]\n },\n \"include\": [\n \"src\",\n \"../.redwood/types/includes/all-*\",\n \"../.redwood/types/includes/web-*\",\n \"./types\"\n ]\n}\n`],\n [\"frontend/redwood/scripts/seed.ts\", `import type { Prisma } from \"@prisma/client\";\n\nimport { db } from \"api/src/lib/db\";\n\nexport default async () => {\n try {\n // If using dbAuth, you can seed users here.\n // If you're using a different auth provider, you can seed users there.\n\n // Example seeding posts\n const posts: Prisma.PostCreateInput[] = [\n {\n title: \"Welcome to RedwoodJS\",\n body: \"RedwoodJS is a full-stack web framework that brings together the best parts of React, GraphQL, Prisma, and serverless.\",\n },\n {\n title: \"Getting Started\",\n body: \"Run \\`yarn rw dev\\` to start the development server. Your app will be available at http://localhost:8910.\",\n },\n ];\n\n for (const post of posts) {\n await db.post.create({ data: post });\n }\n\n console.log(\"Database has been seeded. 🌱\");\n } catch (error) {\n console.warn(\"Please define your seed data.\");\n console.error(error);\n }\n};\n`],\n [\"frontend/redwood/api/package.json.hbs\", `{\n \"name\": \"api\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@redwoodjs/api\": \"^8.6.1\",\n \"@redwoodjs/graphql-server\": \"^8.6.1\"\n }\n}\n`],\n [\"frontend/redwood/api/tsconfig.json\", `{\n \"compilerOptions\": {\n \"noEmit\": true,\n \"allowJs\": true,\n \"esModuleInterop\": true,\n \"target\": \"esnext\",\n \"module\": \"esnext\",\n \"moduleResolution\": \"bundler\",\n \"baseUrl\": \"./\",\n \"strict\": true,\n \"skipLibCheck\": true,\n \"rootDirs\": [\"./src\", \"../.redwood/types/mirror/api/src\"],\n \"paths\": {\n \"src/*\": [\"./src/*\", \"../.redwood/types/mirror/api/src/*\"],\n \"$api/*\": [\"./src/*\", \"../.redwood/types/mirror/api/src/*\"],\n \"types/*\": [\"./types/*\", \"../.redwood/types/mirror/api/types/*\"],\n \"@redwoodjs/testing\": [\"../node_modules/@redwoodjs/testing/api\"]\n },\n \"typeRoots\": [\"../node_modules/@types\", \"./node_modules/@types\"],\n \"types\": [\"node\"]\n },\n \"include\": [\n \"src\",\n \"../.redwood/types/includes/all-*\",\n \"../.redwood/types/includes/api-*\",\n \"./types\"\n ]\n}\n`],\n [\"frontend/fresh/static/styles.css.hbs\", `{{#if (eq cssFramework \"tailwind\")}}\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n{{else}}\n/* Base styles */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n background: linear-gradient(to bottom right, #0f172a, #581c87, #0f172a);\n min-height: 100vh;\n color: #e2e8f0;\n}\n\nheader {\n background: rgba(0, 0, 0, 0.2);\n backdrop-filter: blur(12px);\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n\nnav {\n max-width: 1200px;\n margin: 0 auto;\n padding: 1rem;\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\na {\n color: inherit;\n text-decoration: none;\n}\n\nmain {\n max-width: 1200px;\n margin: 0 auto;\n padding: 4rem 1rem;\n}\n\nh1 {\n font-size: 3rem;\n font-weight: bold;\n margin-bottom: 1.5rem;\n}\n\nbutton {\n cursor: pointer;\n border: none;\n padding: 0.5rem 1rem;\n border-radius: 0.5rem;\n font-weight: 600;\n background: #06b6d4;\n color: white;\n}\n\nbutton:hover {\n background: #0891b2;\n}\n{{/if}}\n`],\n [\"frontend/fresh/static/favicon.svg\", `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\">\n <defs>\n <linearGradient id=\"freshGradient\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" style=\"stop-color:#06b6d4\"/>\n <stop offset=\"100%\" style=\"stop-color:#8b5cf6\"/>\n </linearGradient>\n </defs>\n <circle cx=\"50\" cy=\"50\" r=\"45\" fill=\"url(#freshGradient)\"/>\n <text x=\"50\" y=\"62\" font-family=\"Arial, sans-serif\" font-size=\"40\" font-weight=\"bold\" fill=\"white\" text-anchor=\"middle\">F</text>\n</svg>\n`],\n [\"frontend/solid/public/robots.txt\", `# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n`],\n [\"frontend/solid/src/styles.css\", `@import \"tailwindcss\";\n\nbody {\n @apply bg-neutral-950 text-neutral-100;\n}\n`],\n [\"frontend/solid/src/main.tsx.hbs\", `import { RouterProvider, createRouter } from \"@tanstack/solid-router\";\nimport { render } from \"solid-js/web\";\nimport { routeTree } from \"./routeTree.gen\";\nimport \"./styles.css\";\n{{#if (eq api \"orpc\")}}\nimport { QueryClientProvider } from \"@tanstack/solid-query\";\nimport { orpc, queryClient } from \"./utils/orpc\";\n{{/if}}\n\nconst router = createRouter({\n routeTree,\n defaultPreload: \"intent\",\n scrollRestoration: true,\n defaultPreloadStaleTime: 0,\n {{#if (eq api \"orpc\")}}\n context: { orpc, queryClient },\n {{/if}}\n});\n\ndeclare module \"@tanstack/solid-router\" {\n interface Register {\n router: typeof router;\n }\n}\n\nfunction App() {\n return (\n {{#if (eq api \"orpc\")}}\n <QueryClientProvider client={queryClient}>\n {{/if}}\n <RouterProvider router={router} />\n {{#if (eq api \"orpc\")}}\n </QueryClientProvider>\n {{/if}}\n );\n}\n\nconst rootElement = document.getElementById(\"app\");\nif (rootElement) {\n render(() => <App />, rootElement);\n}\n`],\n [\"frontend/nuxt/server/tsconfig.json\", `{\n \"extends\": \"../.nuxt/tsconfig.server.json\"\n}\n`],\n [\"frontend/nuxt/public/favicon.ico\", `[Binary file]`],\n [\"frontend/nuxt/public/robots.txt\", `User-Agent: *\nDisallow:\n`],\n [\"frontend/nuxt/app/app.vue.hbs\", `<script setup lang=\"ts\">\n{{#if (eq api \"orpc\")}}\nimport { VueQueryDevtools } from '@tanstack/vue-query-devtools'\n{{/if}}\n</script>\n\n<template>\n <NuxtLoadingIndicator />\n <UApp>\n <NuxtLayout>\n <NuxtPage />\n </NuxtLayout>\n </UApp>\n {{#if (eq api \"orpc\")}}\n <VueQueryDevtools />\n {{/if}}\n</template>\n`],\n [\"frontend/nuxt/app/app.config.ts.hbs\", `export default defineAppConfig({\n // https://ui.nuxt.com/getting-started/theme#design-system\n ui: {\n colors: {\n primary: 'emerald',\n neutral: 'neutral',\n },\n button: {\n defaultVariants: {\n // Set default button color to neutral\n // color: 'neutral'\n }\n }\n }\n})\n`],\n [\"packages/env/src/web.ts.hbs\", `{{#if (includes frontend \"next\")}}\nimport { createEnv } from \"@t3-oss/env-nextjs\";\n{{else if (includes frontend \"nuxt\")}}\nimport { createEnv } from \"@t3-oss/env-nuxt\";\n{{else}}\nimport { createEnv } from \"@t3-oss/env-core\";\n{{/if}}\nimport { z } from \"zod\";\n\n{{#if (includes frontend \"nuxt\")}}\n/**\n * Nuxt env validation - validates at build time when imported in nuxt.config.ts\n * For runtime access in components/plugins, use useRuntimeConfig() instead:\n * const config = useRuntimeConfig()\n * config.public.serverUrl (NUXT_PUBLIC_SERVER_URL maps to serverUrl)\n */\n{{/if}}\nexport const env = createEnv({\n{{#if (eq backend \"convex\")}}\n{{#if (includes frontend \"next\")}}\n\tclient: {\n\t\tNEXT_PUBLIC_CONVEX_URL: z.url(),\n{{#if (eq auth \"better-auth\")}}\n\t\tNEXT_PUBLIC_CONVEX_SITE_URL: z.url(),\n{{/if}}\n{{#if (eq auth \"clerk\")}}\n\t\tNEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().min(1),\n{{/if}}\n\t},\n\truntimeEnv: {\n\t\tNEXT_PUBLIC_CONVEX_URL: process.env.NEXT_PUBLIC_CONVEX_URL,\n{{#if (eq auth \"better-auth\")}}\n\t\tNEXT_PUBLIC_CONVEX_SITE_URL: process.env.NEXT_PUBLIC_CONVEX_SITE_URL,\n{{/if}}\n{{#if (eq auth \"clerk\")}}\n\t\tNEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,\n{{/if}}\n\t},\n{{else if (includes frontend \"nuxt\")}}\n\tclient: {\n\t\tNUXT_PUBLIC_CONVEX_URL: z.url(),\n\t},\n{{else if (includes frontend \"svelte\")}}\n\tclientPrefix: \"PUBLIC_\",\n\tclient: {\n\t\tPUBLIC_CONVEX_URL: z.url(),\n\t},\n\truntimeEnv: (import.meta as any).env,\n{{else}}\n\tclientPrefix: \"VITE_\",\n\tclient: {\n\t\tVITE_CONVEX_URL: z.url(),\n{{#if (eq auth \"better-auth\")}}\n\t\tVITE_CONVEX_SITE_URL: z.url(),\n{{/if}}\n{{#if (eq auth \"clerk\")}}\n\t\tVITE_CLERK_PUBLISHABLE_KEY: z.string().min(1),\n{{/if}}\n\t},\n\truntimeEnv: (import.meta as any).env,\n{{/if}}\n{{else if (eq backend \"self\")}}\n{{#if (includes frontend \"next\")}}\n\tclient: {},\n\truntimeEnv: {},\n{{else}}\n\tclientPrefix: \"VITE_\",\n\tclient: {},\n\truntimeEnv: (import.meta as any).env,\n{{/if}}\n{{else if (ne backend \"none\")}}\n{{#if (includes frontend \"next\")}}\n\tclient: {\n\t\tNEXT_PUBLIC_SERVER_URL: z.url(),\n\t},\n\truntimeEnv: {\n\t\tNEXT_PUBLIC_SERVER_URL: process.env.NEXT_PUBLIC_SERVER_URL,\n\t},\n{{else if (includes frontend \"nuxt\")}}\n\tclient: {\n\t\tNUXT_PUBLIC_SERVER_URL: z.url(),\n\t},\n{{else if (includes frontend \"svelte\")}}\n\tclientPrefix: \"PUBLIC_\",\n\tclient: {\n\t\tPUBLIC_SERVER_URL: z.url(),\n\t},\n\truntimeEnv: (import.meta as any).env,\n{{else}}\n\tclientPrefix: \"VITE_\",\n\tclient: {\n\t\tVITE_SERVER_URL: z.url(),\n\t},\n\truntimeEnv: (import.meta as any).env,\n{{/if}}\n{{/if}}\n\temptyStringAsUndefined: true,\n});`],\n [\"packages/env/src/server.ts.hbs\", `{{#if (eq serverDeploy \"cloudflare\")}}\n/// <reference path=\"../env.d.ts\" />\n// For Cloudflare Workers, env is accessed via cloudflare:workers module\n// Types are defined in env.d.ts based on your alchemy.run.ts bindings\nexport { env } from \"cloudflare:workers\";\n{{else}}\nimport \"dotenv/config\";\nimport { createEnv } from \"@t3-oss/env-core\";\nimport { z } from \"zod\";\n\nexport const env = createEnv({\n\tserver: {\n{{#if (ne database \"none\")}}\n{{#if (eq dbSetup \"planetscale\")}}\n\t\tDATABASE_HOST: z.string().min(1),\n\t\tDATABASE_USERNAME: z.string().min(1),\n\t\tDATABASE_PASSWORD: z.string().min(1),\n{{else}}\n\t\tDATABASE_URL: z.string().min(1),\n{{#if (eq dbSetup \"turso\")}}\n\t\tDATABASE_AUTH_TOKEN: z.string().min(1),\n{{/if}}\n{{/if}}\n{{/if}}\n{{#if (eq auth \"better-auth\")}}\n\t\tBETTER_AUTH_SECRET: z.string().min(32),\n\t\tBETTER_AUTH_URL: z.url(),\n{{/if}}\n{{#if (eq payments \"polar\")}}\n\t\tPOLAR_ACCESS_TOKEN: z.string().min(1),\n\t\tPOLAR_SUCCESS_URL: z.url(),\n{{/if}}\n\t\tCORS_ORIGIN: z.url(),\n\t\tNODE_ENV: z.enum([\"development\", \"production\", \"test\"]).default(\"development\"),\n\t},\n\truntimeEnv: process.env,\n\temptyStringAsUndefined: true,\n});\n{{/if}}`],\n [\"packages/env/src/native.ts.hbs\", `import { createEnv } from \"@t3-oss/env-core\";\nimport { z } from \"zod\";\n\nexport const env = createEnv({\n\tclientPrefix: \"EXPO_PUBLIC_\",\n\tclient: {\n{{#if (eq backend \"convex\")}}\n\t\tEXPO_PUBLIC_CONVEX_URL: z.url(),\n{{#if (eq auth \"better-auth\")}}\n\t\tEXPO_PUBLIC_CONVEX_SITE_URL: z.url(),\n{{/if}}\n{{#if (eq auth \"clerk\")}}\n\t\tEXPO_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().min(1),\n{{/if}}\n{{else}}\n\t\tEXPO_PUBLIC_SERVER_URL: z.url(),\n{{/if}}\n\t},\n\truntimeEnv: process.env,\n\temptyStringAsUndefined: true,\n});`],\n [\"frontend/astro/public/favicon.svg\", `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\">\n <rect width=\"32\" height=\"32\" rx=\"8\" fill=\"#7C3AED\"/>\n <path d=\"M16 6L8 26h4l2-5h4l2 5h4L16 6zm0 8l2 5h-4l2-5z\" fill=\"white\"/>\n</svg>\n`],\n [\"frontend/astro/src/env.d.ts\", `/// <reference path=\"../.astro/types.d.ts\" />\n`],\n [\"frontend/native/unistyles/index.js.hbs\", `import 'expo-router/entry';\nimport './unistyles';\n`],\n [\"frontend/native/unistyles/metro.config.js.hbs\", `const { getDefaultConfig } = require(\"expo/metro-config\");\n\nconst config = getDefaultConfig(__dirname);\n\nmodule.exports = config;\n`],\n [\"frontend/native/unistyles/breakpoints.ts.hbs\", `export const breakpoints = {\n xs: 0,\n sm: 576,\n md: 768,\n lg: 992,\n xl: 1200,\n superLarge: 2000,\n tvLike: 4000,\n} as const;\n`],\n [\"frontend/native/unistyles/package.json.hbs\", `{\n \"name\": \"native\",\n \"version\": \"1.0.0\",\n \"private\": true,\n \"main\": \"index.js\",\n \"scripts\": {\n \"dev\": \"expo start --clear\",\n \"android\": \"expo run:android\",\n \"ios\": \"expo run:ios\",\n \"web\": \"expo start --web\"\n },\n \"dependencies\": {\n \"@expo/vector-icons\": \"^15.0.2\",\n \"@react-navigation/bottom-tabs\": \"^7.3.10\",\n \"@react-navigation/drawer\": \"^7.3.9\",\n \"@react-navigation/native\": \"^7.1.6\",\n {{#if (includes examples \"ai\")}}\n \"@stardazed/streams-text-encoding\": \"^1.0.2\",\n \"@ungap/structured-clone\": \"^1.3.0\",\n {{/if}}\n \"@tanstack/react-form\": \"^1.0.5\",\n \"expo\": \"^54.0.0\",\n \"expo-constants\": \"~18.0.8\",\n \"expo-crypto\": \"~15.0.6\",\n \"expo-linking\": \"~8.0.7\",\n \"expo-router\": \"~6.0.0\",\n \"expo-secure-store\": \"~15.0.6\",\n \"expo-splash-screen\": \"~31.0.8\",\n\t\t\"expo-status-bar\": \"^3.0.7\",\n \"expo-system-ui\": \"~6.0.7\",\n\t\t\"expo-dev-client\": \"~6.0.11\",\n \"expo-web-browser\": \"~15.0.6\",\n \"react\": \"19.1.0\",\n \"react-dom\": \"19.1.0\",\n \"react-native\": \"0.81.4\",\n\t\t\"react-native-edge-to-edge\": \"^1.7.0\",\n \"react-native-gesture-handler\": \"~2.28.0\",\n\t\t\"react-native-nitro-modules\": \"^0.29.4\",\n \"react-native-reanimated\": \"~4.1.0\",\n \"react-native-safe-area-context\": \"~5.6.0\",\n \"react-native-screens\": \"~4.16.0\",\n\t\t\"react-native-unistyles\": \"^3.0.12\",\n \"react-native-web\": \"^0.21.0\",\n \"react-native-worklets\": \"^0.5.1\"\n },\n \"devDependencies\": {\n \"ajv\": \"^8.17.1\",\n \"@babel/core\": \"^7.28.0\",\n \"@types/react\": \"~19.1.10\"\n }\n}\n`],\n [\"frontend/native/unistyles/theme.ts.hbs\", `const sharedColors = {\n success: \"#22C55E\",\n destructive: \"#EF4444\",\n warning: \"#F59E0B\",\n info: \"#3B82F6\",\n} as const;\n\nexport const lightTheme = {\n colors: {\n ...sharedColors,\n typography: \"hsl(0 0% 0%)\",\n background: \"hsl(0 0% 100%)\",\n foreground: \"hsl(0 0% 0%)\",\n card: \"hsl(0 0% 98%)\",\n cardForeground: \"hsl(0 0% 0%)\",\n primary: \"hsl(0 0% 10%)\",\n primaryForeground: \"hsl(0 0% 100%)\",\n secondary: \"hsl(0 0% 95%)\",\n secondaryForeground: \"hsl(0 0% 0%)\",\n muted: \"hsl(0 0% 96%)\",\n mutedForeground: \"hsl(0 0% 45%)\",\n accent: \"hsl(0 0% 96%)\",\n accentForeground: \"hsl(0 0% 0%)\",\n border: \"hsl(0 0% 90%)\",\n input: \"hsl(0 0% 90%)\",\n ring: \"hsl(0 0% 20%)\",\n },\n spacing: {\n xs: 4,\n sm: 8,\n md: 16,\n lg: 24,\n xl: 32,\n xxl: 48,\n },\n borderRadius: {\n sm: 6,\n md: 8,\n lg: 12,\n xl: 16,\n },\n fontSize: {\n xs: 12,\n sm: 14,\n base: 16,\n lg: 18,\n xl: 20,\n \"2xl\": 24,\n \"3xl\": 30,\n \"4xl\": 36,\n },\n} as const;\n\nexport const darkTheme = {\n colors: {\n ...sharedColors,\n typography: \"hsl(0 0% 100%)\",\n background: \"hsl(0 0% 0%)\",\n foreground: \"hsl(0 0% 100%)\",\n card: \"hsl(0 0% 2%)\",\n cardForeground: \"hsl(0 0% 100%)\",\n primary: \"hsl(0 0% 90%)\",\n primaryForeground: \"hsl(0 0% 0%)\",\n secondary: \"hsl(0 0% 10%)\",\n secondaryForeground: \"hsl(0 0% 100%)\",\n muted: \"hsl(0 0% 8%)\",\n mutedForeground: \"hsl(0 0% 65%)\",\n accent: \"hsl(0 0% 8%)\",\n accentForeground: \"hsl(0 0% 100%)\",\n border: \"hsl(0 0% 15%)\",\n input: \"hsl(0 0% 15%)\",\n ring: \"hsl(0 0% 80%)\",\n },\n spacing: {\n xs: 4,\n sm: 8,\n md: 16,\n lg: 24,\n xl: 32,\n xxl: 48,\n },\n borderRadius: {\n sm: 6,\n md: 8,\n lg: 12,\n xl: 16,\n },\n fontSize: {\n xs: 12,\n sm: 14,\n base: 16,\n lg: 18,\n xl: 20,\n \"2xl\": 24,\n \"3xl\": 30,\n \"4xl\": 36,\n },\n} as const;\n`],\n [\"frontend/native/unistyles/app.json.hbs\", `{\n \"expo\": {\n \"name\": \"{{projectName}}\",\n \"slug\": \"{{projectName}}\",\n \"version\": \"1.0.0\",\n \"orientation\": \"portrait\",\n \"icon\": \"./assets/images/icon.png\",\n \"scheme\": \"mybettertapp\",\n \"userInterfaceStyle\": \"automatic\",\n \"newArchEnabled\": true,\n \"ios\": {\n \"supportsTablet\": true\n },\n \"android\": {\n \"adaptiveIcon\": {\n \"backgroundColor\": \"#E6F4FE\",\n \"foregroundImage\": \"./assets/images/android-icon-foreground.png\",\n \"backgroundImage\": \"./assets/images/android-icon-background.png\",\n \"monochromeImage\": \"./assets/images/android-icon-monochrome.png\"\n },\n \"edgeToEdgeEnabled\": true,\n \"predictiveBackGestureEnabled\": false,\n \"package\": \"com.anonymous.mybettertapp\"\n },\n \"web\": {\n \"output\": \"static\",\n \"favicon\": \"./assets/images/favicon.png\"\n },\n \"plugins\": [\n \"expo-router\",\n [\n \"expo-splash-screen\",\n {\n \"image\": \"./assets/images/splash-icon.png\",\n \"imageWidth\": 200,\n \"resizeMode\": \"contain\",\n \"backgroundColor\": \"#ffffff\",\n \"dark\": {\n \"backgroundColor\": \"#000000\"\n }\n }\n ]\n ],\n \"experiments\": {\n \"typedRoutes\": true,\n \"reactCompiler\": true\n }\n }\n}\n`],\n [\"frontend/native/unistyles/babel.config.js.hbs\", `module.exports = (api) => {\n\tapi.cache(true);\n\tconst plugins = [];\n\n\tplugins.push([\n\t\t\"react-native-unistyles/plugin\",\n\t\t{\n\t\t\troot: \"src\",\n\t\t\tautoProcessRoot: \"app\",\n\t\t\tautoProcessImports: [\"@/components\"],\n\t\t},\n\t]);\n\n\tplugins.push(\"react-native-worklets/plugin\");\n\n\treturn {\n\t\tpresets: [\"babel-preset-expo\"],\n\n\t\tplugins,\n\t};\n};\n`],\n [\"frontend/native/unistyles/tsconfig.json.hbs\", `{\n \"extends\": \"expo/tsconfig.base\",\n \"compilerOptions\": {\n \"strict\": true,\n \"jsx\": \"react-jsx\",\n \"baseUrl\": \".\",\n \"paths\": {\n \"@/*\": [\"*\"]\n }\n },\n \"include\": [\"**/*.ts\", \"**/*.tsx\", \".expo/types/**/*.ts\", \"expo-env.d.ts\"]\n}\n`],\n [\"frontend/native/unistyles/unistyles.ts.hbs\", `import { StyleSheet } from \"react-native-unistyles\";\n\nimport { breakpoints } from \"./breakpoints\";\nimport { darkTheme, lightTheme } from \"./theme\";\n\ntype AppBreakpoints = typeof breakpoints;\n\ntype AppThemes = {\n light: typeof lightTheme;\n dark: typeof darkTheme;\n};\n\ndeclare module \"react-native-unistyles\" {\n export interface UnistylesBreakpoints extends AppBreakpoints {}\n export interface UnistylesThemes extends AppThemes {}\n}\n\nStyleSheet.configure({\n breakpoints,\n themes: {\n light: lightTheme,\n dark: darkTheme,\n },\n settings: {\n adaptiveThemes: true,\n },\n});\n`],\n [\"frontend/native/unistyles/_gitignore\", `node_modules/\n.expo/\ndist/\nnpm-debug.*\n*.jks\n*.p8\n*.p12\n*.key\n*.mobileprovision\n*.orig.*\nweb-build/\n# expo router\nexpo-env.d.ts\n\n.env\n\nios\nandroid\n\n# macOS\n.DS_Store\n\n# Temporary files created by Metro to check the health of the file watcher\n.metro-health-check*`],\n [\"frontend/native/bare/metro.config.js.hbs\", `// Learn more https://docs.expo.io/guides/customizing-metro\nconst { getDefaultConfig } = require(\"expo/metro-config\");\n\nconst config = getDefaultConfig(__dirname);\n\nconfig.resolver.unstable_enablePackageExports = true;\n\nmodule.exports = config;\n\n`],\n [\"frontend/native/bare/package.json.hbs\", `{\n \"name\": \"native\",\n \"version\": \"1.0.0\",\n \"main\": \"expo-router/entry\",\n \"scripts\": {\n \"dev\": \"expo start --clear\",\n \"android\": \"expo run:android\",\n \"ios\": \"expo run:ios\",\n \"prebuild\": \"expo prebuild\",\n \"web\": \"expo start --web\"\n },\n \"dependencies\": {\n \"@expo/vector-icons\": \"^15.0.2\",\n \"@react-navigation/bottom-tabs\": \"^7.2.0\",\n \"@react-navigation/drawer\": \"^7.1.1\",\n \"@react-navigation/native\": \"^7.0.14\",\n \"@tanstack/react-form\": \"^1.0.5\",\n \"@tanstack/react-query\": \"^5.85.5\",\n {{#if (includes examples \"ai\")}}\n \"@stardazed/streams-text-encoding\": \"^1.0.2\",\n \"@ungap/structured-clone\": \"^1.3.0\",\n {{/if}}\n\t\t\"expo\": \"^54.0.1\",\n \"expo-constants\": \"~18.0.8\",\n \"expo-crypto\": \"~15.0.6\",\n \"expo-linking\": \"~8.0.7\",\n \"expo-navigation-bar\": \"~5.0.8\",\n \"expo-network\": \"~8.0.7\",\n \"expo-router\": \"~6.0.0\",\n \"expo-secure-store\": \"~15.0.6\",\n \"expo-splash-screen\": \"~31.0.8\",\n \"expo-status-bar\": \"~3.0.7\",\n \"expo-system-ui\": \"~6.0.7\",\n \"expo-web-browser\": \"~15.0.6\",\n \"react\": \"19.1.0\",\n \"react-dom\": \"19.1.0\",\n \"react-native\": \"0.81.4\",\n \"react-native-gesture-handler\": \"~2.28.0\",\n \"react-native-reanimated\": \"~4.1.0\",\n \"react-native-safe-area-context\": \"~5.6.0\",\n \"react-native-screens\": \"~4.16.0\",\n \"react-native-web\": \"^0.21.0\",\n \"react-native-worklets\": \"^0.5.1\"\n },\n \"devDependencies\": {\n \"@babel/core\": \"^7.26.10\",\n \"@types/react\": \"~19.1.10\"\n },\n \"private\": true\n}\n\n`],\n [\"frontend/native/bare/app.json.hbs\", `{\n\t\"expo\": {\n\t\t\"name\": \"{{projectName}}\",\n\t\t\"slug\": \"{{projectName}}\",\n\t\t\"version\": \"1.0.0\",\n\t\t\"orientation\": \"portrait\",\n\t\t\"icon\": \"./assets/images/icon.png\",\n\t\t\"scheme\": \"mybettertapp\",\n\t\t\"userInterfaceStyle\": \"automatic\",\n\t\t\"newArchEnabled\": true,\n\t\t\"ios\": {\n\t\t\t\"supportsTablet\": true\n\t\t},\n\t\t\"android\": {\n\t\t\t\"adaptiveIcon\": {\n\t\t\t\t\"backgroundColor\": \"#E6F4FE\",\n\t\t\t\t\"foregroundImage\": \"./assets/images/android-icon-foreground.png\",\n\t\t\t\t\"backgroundImage\": \"./assets/images/android-icon-background.png\",\n\t\t\t\t\"monochromeImage\": \"./assets/images/android-icon-monochrome.png\"\n\t\t\t},\n\t\t\t\"edgeToEdgeEnabled\": true,\n\t\t\t\"predictiveBackGestureEnabled\": false,\n\t\t\t\"package\": \"com.anonymous.mybettertapp\"\n\t\t},\n\t\t\"web\": {\n\t\t\t\"output\": \"static\",\n\t\t\t\"favicon\": \"./assets/images/favicon.png\"\n\t\t},\n\t\t\"plugins\": [\n\t\t\t\"expo-router\",\n\t\t\t[\n\t\t\t\t\"expo-splash-screen\",\n\t\t\t\t{\n\t\t\t\t\t\"image\": \"./assets/images/splash-icon.png\",\n\t\t\t\t\t\"imageWidth\": 200,\n\t\t\t\t\t\"resizeMode\": \"contain\",\n\t\t\t\t\t\"backgroundColor\": \"#ffffff\",\n\t\t\t\t\t\"dark\": {\n\t\t\t\t\t\t\"backgroundColor\": \"#000000\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t],\n\t\t\"experiments\": {\n\t\t\t\"typedRoutes\": true,\n\t\t\t\"reactCompiler\": true\n\t\t}\n\t}\n}\n\n`],\n [\"frontend/native/bare/tsconfig.json.hbs\", `{\n\t\"extends\": \"expo/tsconfig.base\",\n\t\"compilerOptions\": {\n\t\t\"strict\": true,\n\t\t\"paths\": {\n\t\t\t\"@/*\": [\"./*\"]\n\t\t}\n\t},\n\t\"include\": [\"**/*.ts\", \"**/*.tsx\", \".expo/types/**/*.ts\", \"expo-env.d.ts\"]\n}\n\n`],\n [\"frontend/native/bare/_gitignore\", `node_modules/\n.expo/\ndist/\nnpm-debug.*\n*.jks\n*.p8\n*.p12\n*.key\n*.mobileprovision\n*.orig.*\nweb-build/\n\n# macOS\n.DS_Store\n\n# Temporary files created by Metro to check the health of the file watcher\n.metro-health-check*\n\n`],\n [\"frontend/native/uniwind/metro.config.js.hbs\", `const { getDefaultConfig } = require(\"expo/metro-config\");\nconst { withUniwindConfig } = require(\"uniwind/metro\");\n\n/** @type {import('expo/metro-config').MetroConfig} */\nconst config = getDefaultConfig(__dirname);\n\nconst uniwindConfig = withUniwindConfig(config, {\n cssEntryFile: \"./global.css\",\n dtsFile: \"./uniwind-types.d.ts\",\n});\n\nmodule.exports = uniwindConfig;\n\n`],\n [\"frontend/native/uniwind/global.css\", `@import \"tailwindcss\";\n@import \"uniwind\";\n@import \"heroui-native/styles\";\n\n@source './node_modules/heroui-native/lib';\n`],\n [\"frontend/native/uniwind/package.json.hbs\", `{\n \"name\": \"native\",\n \"version\": \"1.0.0\",\n \"private\": true,\n \"main\": \"expo-router/entry\",\n \"scripts\": {\n \"start\": \"expo start\",\n \"dev\": \"expo start --clear\",\n \"android\": \"expo run:android\",\n \"ios\": \"expo run:ios\",\n \"prebuild\": \"expo prebuild\",\n \"web\": \"expo start --web\"\n },\n \"dependencies\": {\n \"@expo/metro-runtime\": \"~6.1.2\",\n \"@expo/vector-icons\": \"^15.0.3\",\n \"@gorhom/bottom-sheet\": \"^5\",\n \"@react-navigation/drawer\": \"^7.3.9\",\n \"@react-navigation/elements\": \"^2.8.1\",\n {{#if (includes examples \"ai\")}}\n \"@stardazed/streams-text-encoding\": \"^1.0.2\",\n \"@ungap/structured-clone\": \"^1.3.0\",\n {{/if}}\n \"expo\": \"^54.0.23\",\n \"expo-constants\": \"~18.0.10\",\n \"expo-font\": \"~14.0.9\",\n \"expo-haptics\": \"^15.0.7\",\n \"expo-linking\": \"~8.0.8\",\n \"expo-network\": \"~8.0.7\",\n \"expo-router\": \"~6.0.14\",\n \"expo-secure-store\": \"~15.0.7\",\n \"expo-status-bar\": \"~3.0.8\",\n \"heroui-native\": \"^1.0.0-beta.9\",\n \"react\": \"19.1.0\",\n \"react-dom\": \"19.1.0\",\n \"react-native\": \"0.81.5\",\n \"react-native-gesture-handler\": \"^2.28.0\",\n \"react-native-keyboard-controller\": \"1.18.5\",\n \"react-native-reanimated\": \"~4.1.1\",\n \"react-native-safe-area-context\": \"~5.6.0\",\n \"react-native-screens\": \"~4.16.0\",\n \"react-native-svg\": \"15.12.1\",\n \"react-native-web\": \"^0.21.0\",\n \"react-native-worklets\": \"0.5.1\",\n \"tailwind-merge\": \"^3.4.0\",\n \"tailwind-variants\": \"^3.2.2\",\n \"tailwindcss\": \"^4.1.18\",\n \"uniwind\": \"^1.2.2\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^24.10.0\",\n \"@types/react\": \"~19.1.0\"\n }\n}`],\n [\"frontend/native/uniwind/app.json.hbs\", `{\n \"expo\": {\n \"scheme\": \"{{projectName}}\",\n \"userInterfaceStyle\": \"automatic\",\n \"orientation\": \"default\",\n \"web\": {\n \"bundler\": \"metro\"\n },\n \"name\": \"{{projectName}}\",\n \"slug\": \"{{projectName}}\",\n \"plugins\": [\n \"expo-font\"\n ],\n \"experiments\": {\n \"typedRoutes\": true,\n \"reactCompiler\": true\n }\n }\n}\n`],\n [\"frontend/native/uniwind/tsconfig.json.hbs\", `{\n \"extends\": \"expo/tsconfig.base\",\n \"compilerOptions\": {\n \"strict\": true,\n \"baseUrl\": \".\",\n \"paths\": {\n \"@/*\": [\"./*\"]\n }\n },\n \"include\": [\n \"**/*.ts\",\n \"**/*.tsx\"\n ]\n}`],\n [\"frontend/native/uniwind/_gitignore\", `node_modules/\n.expo/\ndist/\nnpm-debug.*\n*.jks\n*.p8\n*.p12\n*.key\n*.mobileprovision\n*.orig.*\nweb-build/\n\n# macOS\n.DS_Store\n\n# Temporary files created by Metro to check the health of the file watcher\n.metro-health-check*\n\n# UniWind generated types\nuniwind-types.d.ts\n\n`],\n [\"db/prisma/mongodb/prisma.config.ts.hbs\", `import path from \"node:path\";\nimport type { PrismaConfig } from \"prisma\";\nimport dotenv from \"dotenv\";\n\ndotenv.config({\n {{#if (eq backend \"self\")}}\n path: \"../../apps/web/.env\",\n {{else}}\n path: \"../../apps/server/.env\",\n {{/if}}\n});\n\nexport default {\n schema: path.join(\"prisma\", \"schema\"),\n migrations: {\n path: path.join(\"prisma\", \"migrations\"),\n }\n} satisfies PrismaConfig;\n`],\n [\"db/drizzle/postgres/drizzle.config.ts.hbs\", `import { defineConfig } from \"drizzle-kit\";\nimport dotenv from \"dotenv\";\n\ndotenv.config({\n {{#if (eq backend \"self\")}}\n path: \"../../apps/web/.env\",\n {{else}}\n path: \"../../apps/server/.env\",\n {{/if}}\n});\n\nexport default defineConfig({\n schema: \"./src/schema\",\n out: \"./src/migrations\",\n dialect: \"postgresql\",\n dbCredentials: {\n url: process.env.DATABASE_URL || \"\",\n },\n});\n`],\n [\"db/drizzle/mysql/drizzle.config.ts.hbs\", `import { defineConfig } from \"drizzle-kit\";\nimport dotenv from \"dotenv\";\n\ndotenv.config({\n {{#if (eq backend \"self\")}}\n path: \"../../apps/web/.env\",\n {{else}}\n path: \"../../apps/server/.env\",\n {{/if}}\n});\n\nexport default defineConfig({\n schema: \"./src/schema\",\n out: \"./src/migrations\",\n dialect: \"mysql\",\n dbCredentials: {\n url: process.env.DATABASE_URL || \"\",\n },\n});\n`],\n [\"db/prisma/mysql/prisma.config.ts.hbs\", `import path from \"node:path\";\nimport { defineConfig, env } from \"prisma/config\";\nimport dotenv from \"dotenv\";\n\ndotenv.config({\n {{#if (eq backend \"self\")}}\n path: \"../../apps/web/.env\",\n {{else}}\n path: \"../../apps/server/.env\",\n {{/if}}\n});\n\nexport default defineConfig({\n schema: path.join(\"prisma\", \"schema\"),\n migrations: {\n path: path.join(\"prisma\", \"migrations\"),\n },\n datasource: {\n url: env(\"DATABASE_URL\"),\n },\n});`],\n [\"db/prisma/sqlite/prisma.config.ts.hbs\", `import path from \"node:path\";\nimport { defineConfig, env } from \"prisma/config\";\nimport dotenv from \"dotenv\";\n\ndotenv.config({\n {{#if (eq backend \"self\")}}\n path: \"../../apps/web/.env\",\n {{else}}\n path: \"../../apps/server/.env\",\n {{/if}}\n});\n\nexport default defineConfig({\n schema: path.join(\"prisma\", \"schema\"),\n migrations: {\n path: path.join(\"prisma\", \"migrations\"),\n },\n datasource: {\n {{#if (eq dbSetup \"turso\")}}\n url: \"file:./dev.db\",\n {{else}}\n url: env(\"DATABASE_URL\"),\n {{/if}}\n },\n});`],\n [\"db/prisma/postgres/prisma.config.ts.hbs\", `import path from \"node:path\";\nimport { defineConfig, env } from 'prisma/config'\nimport dotenv from 'dotenv'\n\ndotenv.config({\n {{#if (eq backend \"self\")}}\n path: \"../../apps/web/.env\",\n {{else}}\n path: \"../../apps/server/.env\",\n {{/if}}\n})\n\nexport default defineConfig({\n schema: path.join(\"prisma\", \"schema\"),\n migrations: {\n path: path.join(\"prisma\", \"migrations\"),\n },\n datasource: {\n url: env('DATABASE_URL'),\n },\n})\n`],\n [\"db/drizzle/sqlite/drizzle.config.ts.hbs\", `import { defineConfig } from \"drizzle-kit\";\nimport dotenv from \"dotenv\";\n\ndotenv.config({\n {{#if (eq backend \"self\")}}\n path: \"../../apps/web/.env\",\n {{else}}\n path: \"../../apps/server/.env\",\n {{/if}}\n});\n\nexport default defineConfig({\n schema: \"./src/schema\",\n out: \"./src/migrations\",\n {{#if (eq dbSetup \"d1\")}}\n // DOCS: https://orm.drizzle.team/docs/guides/d1-http-with-drizzle-kit\n dialect: \"sqlite\",\n driver: \"d1-http\",\n {{else}}\n dialect: \"turso\",\n dbCredentials: {\n url: process.env.DATABASE_URL || \"\",\n {{#if (eq dbSetup \"turso\")}}\n authToken: process.env.DATABASE_AUTH_TOKEN,\n {{/if}}\n },\n {{/if}}\n});\n`],\n [\"api/garph/server/package.json.hbs\", `{\n \"name\": \"@{{projectName}}/api\",\n \"exports\": {\n \".\": {\n \"default\": \"./src/index.ts\"\n },\n \"./*\": {\n \"default\": \"./src/*.ts\"\n }\n },\n \"type\": \"module\",\n \"scripts\": {},\n \"devDependencies\": {}\n}\n`],\n [\"api/garph/server/tsconfig.json.hbs\", `{\n \"extends\": \"../../tsconfig.json\",\n \"compilerOptions\": {\n \"outDir\": \"./dist\",\n \"rootDir\": \"./src\"\n },\n \"include\": [\"src/**/*\"]\n}\n`],\n [\"api/garph/server/_gitignore\", `dist\nnode_modules\n`],\n [\"api/ts-rest/server/package.json.hbs\", `{\n \"name\": \"@{{projectName}}/api\",\n \"exports\": {\n \".\": {\n \"default\": \"./src/index.ts\"\n },\n \"./*\": {\n \"default\": \"./src/*.ts\"\n }\n },\n \"type\": \"module\",\n \"scripts\": {},\n \"devDependencies\": {}\n}\n`],\n [\"api/ts-rest/server/tsconfig.json.hbs\", `{\n \"extends\": \"../../tooling/typescript/base.json\",\n \"compilerOptions\": {\n \"outDir\": \"./dist\",\n \"rootDir\": \"./src\"\n },\n \"include\": [\"src/**/*.ts\"]\n}\n`],\n [\"api/ts-rest/server/_gitignore\", `dist\n`],\n [\"backend/server/encore/package.json.hbs\", `{\n\t\"name\": \"server\",\n\t\"main\": \"src/index.ts\",\n\t\"type\": \"module\",\n\t\"scripts\": {\n\t\t\"dev\": \"encore run\",\n\t\t\"build\": \"encore build\",\n\t\t\"check-types\": \"tsc -b\",\n\t\t\"test\": \"encore test\"\n\t},\n\t\"dependencies\": {},\n\t\"devDependencies\": {}\n}\n`],\n [\"backend/server/encore/encore.app.hbs\", `{\n\t\"id\": \"{{projectName}}-server\"\n}\n`],\n [\"backend/server/encore/encore.service.ts.hbs\", `import { Service } from \"encore.dev/service\";\n\nexport default new Service(\"api\");\n`],\n [\"backend/server/encore/tsconfig.json.hbs\", `{\n\t\"compilerOptions\": {\n\t\t\"target\": \"ESNext\",\n\t\t\"module\": \"ESNext\",\n\t\t\"moduleResolution\": \"bundler\",\n\t\t\"strict\": true,\n\t\t\"esModuleInterop\": true,\n\t\t\"skipLibCheck\": true,\n\t\t\"forceConsistentCasingInFileNames\": true,\n\t\t\"resolveJsonModule\": true,\n\t\t\"declaration\": true,\n\t\t\"declarationMap\": true,\n\t\t\"noEmit\": true,\n\t\t\"paths\": {\n\t\t\t\"~encore/*\": [\"./encore.gen/*\"]\n\t\t}\n\t},\n\t\"include\": [\"**/*.ts\"],\n\t\"exclude\": [\"node_modules\"]\n}\n`],\n [\"backend/server/encore/_gitignore\", `# Encore.ts generated files\nencore.gen/\n.encore/\n\n# Dependencies\nnode_modules/\n\n# Build outputs\ndist/\n\n# Environment files\n.env\n.env.local\n.env.*.local\n\n# IDE\n.vscode/\n.idea/\n*.swp\n*.swo\n`],\n [\"rust-base/crates/dioxus-client/src/main.rs.hbs\", `#![allow(non_snake_case)]\n\nuse dioxus::prelude::*;\nuse dioxus_router::prelude::*;\nuse tracing::info;\n\n/// Application routes\n#[derive(Clone, Routable, Debug, PartialEq)]\nenum Route {\n #[route(\"/\")]\n Home {},\n #[route(\"/about\")]\n About {},\n}\n\nfn main() {\n // Set up better panic messages in console\n console_error_panic_hook::set_once();\n\n // Initialize logging\n dioxus_logger::init(tracing::Level::INFO).expect(\"Failed to init logger\");\n\n info!(\"Starting Dioxus client application\");\n\n launch(App);\n}\n\n/// Main application component\nfn App() -> Element {\n rsx! {\n Router::<Route> {}\n }\n}\n\n/// Home page component\n#[component]\nfn Home() -> Element {\n let mut count = use_signal(|| 0);\n\n rsx! {\n div { class: \"container\",\n div { class: \"home\",\n h1 { \"Welcome to {{projectName}}\" }\n p { \"A full-stack Rust application powered by Dioxus\" }\n\n div { class: \"counter\",\n button {\n class: \"btn\",\n onclick: move |_| count -= 1,\n \"-\"\n }\n span { class: \"count\", \"{count}\" }\n button {\n class: \"btn\",\n onclick: move |_| count += 1,\n \"+\"\n }\n }\n\n nav {\n Link { to: Route::About {}, \"About\" }\n }\n }\n }\n }\n}\n\n/// About page component\n#[component]\nfn About() -> Element {\n rsx! {\n div { class: \"container\",\n div { class: \"about\",\n h1 { \"About\" }\n p { \"This application was generated with Better-Fullstack using the Dioxus framework.\" }\n\n h2 { \"Technology Stack\" }\n ul {\n li { \"Dioxus - React-like reactive framework\" }\n li { \"Rust + WebAssembly - High-performance frontend\" }\n{{#if (eq rustWebFramework \"axum\")}}\n li { \"Axum - Ergonomic web framework by Tokio team\" }\n{{/if}}\n{{#if (eq rustWebFramework \"actix-web\")}}\n li { \"Actix-web - Powerful, pragmatic web framework\" }\n{{/if}}\n }\n\n nav {\n Link { to: Route::Home {}, \"Back to Home\" }\n }\n }\n }\n }\n}\n`],\n [\"rust-base/crates/dioxus-client/assets/main.css\", `/* Dioxus Application Styles */\n\n:root {\n --bg-color: #1a1a2e;\n --text-color: #eaeaea;\n --primary-color: #00b4d8;\n --secondary-color: #16213e;\n --accent-color: #0f3460;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family:\n -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell, \"Open Sans\",\n \"Helvetica Neue\", sans-serif;\n background-color: var(--bg-color);\n color: var(--text-color);\n min-height: 100vh;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.container {\n max-width: 800px;\n margin: 0 auto;\n padding: 2rem;\n text-align: center;\n}\n\nh1 {\n font-size: 2.5rem;\n margin-bottom: 1rem;\n color: var(--primary-color);\n}\n\nh2 {\n font-size: 1.5rem;\n margin: 1.5rem 0 1rem;\n color: var(--text-color);\n}\n\np {\n font-size: 1.1rem;\n line-height: 1.6;\n margin-bottom: 1rem;\n opacity: 0.9;\n}\n\n.home,\n.about {\n background: var(--secondary-color);\n border-radius: 12px;\n padding: 2rem;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n}\n\n.counter {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 1rem;\n margin: 2rem 0;\n}\n\n.count {\n font-size: 2rem;\n font-weight: bold;\n min-width: 4rem;\n padding: 0.5rem 1rem;\n background: var(--accent-color);\n border-radius: 8px;\n}\n\n.btn {\n font-size: 1.5rem;\n padding: 0.5rem 1.5rem;\n background: var(--primary-color);\n color: white;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition:\n transform 0.1s,\n background 0.2s;\n}\n\n.btn:hover {\n background: #48cae4;\n}\n\n.btn:active {\n transform: scale(0.95);\n}\n\nnav {\n margin-top: 2rem;\n}\n\nnav a {\n color: var(--primary-color);\n text-decoration: none;\n font-weight: 500;\n padding: 0.5rem 1rem;\n border: 2px solid var(--primary-color);\n border-radius: 6px;\n transition: all 0.2s;\n}\n\nnav a:hover {\n background: var(--primary-color);\n color: white;\n}\n\nul {\n list-style: none;\n text-align: left;\n max-width: 400px;\n margin: 0 auto;\n}\n\nul li {\n padding: 0.5rem 0;\n padding-left: 1.5rem;\n position: relative;\n}\n\nul li::before {\n content: \"\\\\2713\";\n position: absolute;\n left: 0;\n color: var(--primary-color);\n}\n`],\n [\"rust-base/crates/cli/src/main.rs.hbs\", `use anyhow::Result;\nuse clap::{Parser, Subcommand};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n/// {{projectName}} CLI - Command-line interface\n#[derive(Parser, Debug)]\n#[command(name = \"{{projectName}}\")]\n#[command(author, version, about, long_about = None)]\nstruct Cli {\n /// Turn on verbose output\n #[arg(short, long, global = true)]\n verbose: bool,\n\n /// Config file path\n #[arg(short, long, global = true)]\n config: Option<String>,\n\n #[command(subcommand)]\n command: Commands,\n}\n\n#[derive(Subcommand, Debug)]\nenum Commands {\n /// Start the application\n Start {\n /// Port to listen on\n #[arg(short, long, default_value = \"3000\")]\n port: u16,\n\n /// Host to bind to\n #[arg(short = 'H', long, default_value = \"127.0.0.1\")]\n host: String,\n },\n\n /// Check configuration and health\n Check {\n /// Check database connection\n #[arg(long)]\n database: bool,\n\n /// Check all services\n #[arg(long)]\n all: bool,\n },\n\n /// Run database migrations\n Migrate {\n /// Run pending migrations\n #[arg(long)]\n up: bool,\n\n /// Rollback last migration\n #[arg(long)]\n down: bool,\n\n /// Migration status\n #[arg(long)]\n status: bool,\n },\n\n /// Generate project components\n Generate {\n /// Component type to generate\n #[arg(value_enum)]\n component: GenerateComponent,\n\n /// Name for the generated component\n name: String,\n },\n}\n\n#[derive(clap::ValueEnum, Clone, Debug)]\nenum GenerateComponent {\n /// Generate a new model\n Model,\n /// Generate a new handler/controller\n Handler,\n /// Generate a new service\n Service,\n /// Generate a new migration\n Migration,\n}\n\n#[tokio::main]\nasync fn main() -> Result<()> {\n // Load environment variables\n dotenvy::dotenv().ok();\n\n let cli = Cli::parse();\n\n // Initialize tracing with verbosity level\n let filter = if cli.verbose { \"debug\" } else { \"info\" };\n tracing_subscriber::registry()\n .with(tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| filter.into()))\n .with(tracing_subscriber::fmt::layer())\n .init();\n\n if let Some(config_path) = &cli.config {\n tracing::info!(\"Using config file: {}\", config_path);\n }\n\n match cli.command {\n Commands::Start { port, host } => {\n tracing::info!(\"Starting server on {}:{}\", host, port);\n // TODO: Implement server start logic\n // This is where you would start your Axum/Actix server\n println!(\"Server would start on {}:{}\", host, port);\n }\n\n Commands::Check { database, all } => {\n tracing::info!(\"Running health checks...\");\n\n if database || all {\n tracing::info!(\"Checking database connection...\");\n // TODO: Implement database check\n println!(\"Database check: Not implemented\");\n }\n\n if all {\n tracing::info!(\"Checking all services...\");\n // TODO: Implement other service checks\n println!(\"All checks complete\");\n }\n\n if !database && !all {\n println!(\"No checks specified. Use --database or --all\");\n }\n }\n\n Commands::Migrate { up, down, status } => {\n if status {\n tracing::info!(\"Checking migration status...\");\n // TODO: Implement migration status check\n println!(\"Migration status: Not implemented\");\n } else if up {\n tracing::info!(\"Running pending migrations...\");\n // TODO: Implement migration up\n println!(\"Migrations run: Not implemented\");\n } else if down {\n tracing::info!(\"Rolling back last migration...\");\n // TODO: Implement migration down\n println!(\"Migration rollback: Not implemented\");\n } else {\n println!(\"No migration action specified. Use --up, --down, or --status\");\n }\n }\n\n Commands::Generate { component, name } => {\n tracing::info!(\"Generating {:?}: {}\", component, name);\n match component {\n GenerateComponent::Model => {\n println!(\"Would generate model: {}\", name);\n // TODO: Implement model generation\n }\n GenerateComponent::Handler => {\n println!(\"Would generate handler: {}\", name);\n // TODO: Implement handler generation\n }\n GenerateComponent::Service => {\n println!(\"Would generate service: {}\", name);\n // TODO: Implement service generation\n }\n GenerateComponent::Migration => {\n println!(\"Would generate migration: {}\", name);\n // TODO: Implement migration generation\n }\n }\n }\n }\n\n Ok(())\n}\n`],\n [\"rust-base/crates/client/src/lib.rs.hbs\", `use leptos::prelude::*;\nuse leptos_meta::*;\nuse leptos_router::components::*;\nuse leptos_router::path;\n\n/// Main application component\n#[component]\npub fn App() -> impl IntoView {\n // Provides context for managing document head metadata\n provide_meta_context();\n\n view! {\n <Stylesheet id=\"leptos\" href=\"/pkg/{{projectName}}_client.css\"/>\n <Title text=\"{{projectName}} - Built with Leptos\"/>\n <Meta name=\"description\" content=\"A Rust WASM application built with Leptos\"/>\n\n <Router>\n <main class=\"container\">\n <Routes fallback=|| \"Page not found.\".into_view()>\n <Route path=path!(\"/\") view=HomePage/>\n <Route path=path!(\"/about\") view=AboutPage/>\n </Routes>\n </main>\n </Router>\n }\n}\n\n/// Home page component\n#[component]\nfn HomePage() -> impl IntoView {\n let (count, set_count) = signal(0);\n\n view! {\n <div class=\"home\">\n <h1>\"Welcome to {{projectName}}\"</h1>\n <p>\"A full-stack Rust application powered by Leptos\"</p>\n\n <div class=\"counter\">\n <button\n class=\"btn\"\n on:click=move |_| set_count.update(|n| *n -= 1)\n >\n \"-\"\n </button>\n <span class=\"count\">{count}</span>\n <button\n class=\"btn\"\n on:click=move |_| set_count.update(|n| *n += 1)\n >\n \"+\"\n </button>\n </div>\n\n <nav>\n <a href=\"/about\">\"About\"</a>\n </nav>\n </div>\n }\n}\n\n/// About page component\n#[component]\nfn AboutPage() -> impl IntoView {\n view! {\n <div class=\"about\">\n <h1>\"About\"</h1>\n <p>\"This application was generated with Better-Fullstack using the Leptos framework.\"</p>\n\n <h2>\"Technology Stack\"</h2>\n <ul>\n <li>\"Leptos - Fine-grained reactive framework\"</li>\n <li>\"Rust + WebAssembly - High-performance frontend\"</li>\n{{#if (eq rustWebFramework \"axum\")}}\n <li>\"Axum - Ergonomic web framework by Tokio team\"</li>\n{{/if}}\n{{#if (eq rustWebFramework \"actix-web\")}}\n <li>\"Actix-web - Powerful, pragmatic web framework\"</li>\n{{/if}}\n </ul>\n\n <nav>\n <a href=\"/\">\"Back to Home\"</a>\n </nav>\n </div>\n }\n}\n\n/// Initialize the Leptos client-side app\n#[wasm_bindgen::prelude::wasm_bindgen(start)]\npub fn main() {\n // Set up better panic messages in console\n console_error_panic_hook::set_once();\n\n // Initialize logging\n _ = console_log::init_with_level(log::Level::Debug);\n\n log::info!(\"Starting Leptos client application\");\n\n leptos::mount::mount_to_body(App);\n}\n`],\n [\"rust-base/crates/client/style/main.css\", `/* Leptos Application Styles */\n\n:root {\n --bg-color: #1a1a2e;\n --text-color: #eaeaea;\n --primary-color: #e94560;\n --secondary-color: #16213e;\n --accent-color: #0f3460;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family:\n -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell, \"Open Sans\",\n \"Helvetica Neue\", sans-serif;\n background-color: var(--bg-color);\n color: var(--text-color);\n min-height: 100vh;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.container {\n max-width: 800px;\n margin: 0 auto;\n padding: 2rem;\n text-align: center;\n}\n\nh1 {\n font-size: 2.5rem;\n margin-bottom: 1rem;\n color: var(--primary-color);\n}\n\nh2 {\n font-size: 1.5rem;\n margin: 1.5rem 0 1rem;\n color: var(--text-color);\n}\n\np {\n font-size: 1.1rem;\n line-height: 1.6;\n margin-bottom: 1rem;\n opacity: 0.9;\n}\n\n.home,\n.about {\n background: var(--secondary-color);\n border-radius: 12px;\n padding: 2rem;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n}\n\n.counter {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 1rem;\n margin: 2rem 0;\n}\n\n.count {\n font-size: 2rem;\n font-weight: bold;\n min-width: 4rem;\n padding: 0.5rem 1rem;\n background: var(--accent-color);\n border-radius: 8px;\n}\n\n.btn {\n font-size: 1.5rem;\n padding: 0.5rem 1.5rem;\n background: var(--primary-color);\n color: white;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition:\n transform 0.1s,\n background 0.2s;\n}\n\n.btn:hover {\n background: #ff6b6b;\n}\n\n.btn:active {\n transform: scale(0.95);\n}\n\nnav {\n margin-top: 2rem;\n}\n\nnav a {\n color: var(--primary-color);\n text-decoration: none;\n font-weight: 500;\n padding: 0.5rem 1rem;\n border: 2px solid var(--primary-color);\n border-radius: 6px;\n transition: all 0.2s;\n}\n\nnav a:hover {\n background: var(--primary-color);\n color: white;\n}\n\nul {\n list-style: none;\n text-align: left;\n max-width: 400px;\n margin: 0 auto;\n}\n\nul li {\n padding: 0.5rem 0;\n padding-left: 1.5rem;\n position: relative;\n}\n\nul li::before {\n content: \"\\\\2713\";\n position: absolute;\n left: 0;\n color: var(--primary-color);\n}\n`],\n [\"addons/ruler/.ruler/ruler.toml.hbs\", `# Ruler Configuration File\n# See https://okigu.com/ruler for documentation.\n\n# Default agents to run when --agents is not specified\ndefault_agents = []\n\n# --- Global MCP Server Configuration ---\n[mcp]\n# Enable/disable MCP propagation globally (default: true)\nenabled = true\n# Global merge strategy: 'merge' or 'overwrite' (default: 'merge')\nmerge_strategy = \"merge\"\n\n# --- MCP Server Definitions ---\n[mcp_servers.context7]\ncommand = \"npx\"\nargs = [\"-y\", \"@upstash/context7-mcp\"]\n\n{{#if (or (eq runtime \"workers\") (eq webDeploy \"wrangler\"))}}\n[mcp_servers.cloudflare]\ncommand = \"npx\"\nargs = [\"mcp-remote\", \"https://docs.mcp.cloudflare.com/sse\"]\n{{/if}}\n\n{{#if (eq backend \"convex\")}}\n[mcp_servers.convex]\ncommand = \"npx\"\nargs = [\"-y\", \"convex@latest\", \"mcp\", \"start\"]\n{{/if}}\n\n{{#if (or (includes frontend \"tanstack-router\") (includes frontend \"react-router\") (includes frontend \"tanstack-start\") (includes frontend \"next\"))}}\n[mcp_servers.shadcn]\ncommand = \"npx\"\nargs = [\"shadcn@latest\", \"mcp\"]\n{{/if}}\n\n{{#if (eq dbSetup \"planetscale\")}}\n[mcp_servers.planetscale]\ncommand = \"pscale\"\nargs = [\"mcp\", \"server\"]\n{{/if}}\n\n{{#if (eq dbSetup \"prisma-postgres\")}}\n[mcp_servers.prisma]\ncommand = \"npx\"\nargs = [\"-y\", \"prisma\", \"mcp\"]\n{{/if}}\n\n{{#if (eq dbSetup \"neon\")}}\n[mcp_servers.neon]\ncommand = \"npx\"\nargs = [\"-y\", \"mcp-remote@latest\", \"https://mcp.neon.tech/mcp\"]\n{{/if}}\n\n{{#if (eq dbSetup \"mongodb-atlas\")}}\n[mcp_servers.mongodb]\ncommand = \"npx\"\nargs = [\"-y\", \"mongodb-mcp-server\", \"--connectionString\", \"mongodb://localhost:27017/myDatabase\", \"--readOnly\"]\n{{/if}}\n\n{{#if (eq auth \"better-auth\")}}\n[mcp_servers.better-auth]\nurl = \"https://mcp.chonkie.ai/better-auth/better-auth-builder/mcp\"\n{{/if}}\n\n{{#if (includes frontend \"nuxt\")}}\n[mcp_servers.nuxt-ui]\nurl = \"https://ui.nuxt.com/mcp\"\n{{/if}}\n\n{{#if (includes frontend \"next\")}}\n[mcp_servers.next-devtools]\ncommand = \"npx\"\nargs = [\"-y\", \"next-devtools-mcp@latest\"]\n{{/if}}\n\n# --- Global .gitignore Configuration ---\n[gitignore]\n# Enable/disable automatic .gitignore updates (default: true)\nenabled = true`],\n [\"addons/ruler/.ruler/bts.md.hbs\", `# Better-T-Stack Project Rules\n\nThis is a {{projectName}} project created with Better-T-Stack CLI.\n\n## Project Structure\n\nThis is a monorepo with the following structure:\n\n{{#if (or (includes frontend \"tanstack-router\") (includes frontend \"react-router\") (includes frontend \"tanstack-start\")\n(includes frontend \"next\") (includes frontend \"nuxt\") (includes frontend \"svelte\") (includes frontend \"solid\"))}}\n- **\\`apps/web/\\`** - {{#if (eq backend \"self\")}}Fullstack application{{else}}Frontend application{{/if}}{{#if (includes frontend \"tanstack-router\")}} (React with TanStack Router){{else if (includes frontend \"react-router\")}} (React with React Router){{else if (includes frontend \"tanstack-start\")}} (TanStack Start){{else if (includes frontend \"next\")}} (Next.js){{else if (includes frontend \"nuxt\")}} (Nuxt.js){{else if (includes frontend \"svelte\")}} (SvelteKit){{else if (includes frontend \"solid\")}} (SolidStart){{/if}}\n{{/if}}\n\n{{#if (ne backend \"convex\")}}\n{{#if (and (ne backend \"none\") (ne backend \"self\"))}}\n- **\\`apps/server/\\`** - Backend server{{#if (eq backend \"hono\")}} (Hono){{else if (eq backend \"express\")}} (Express){{else if (eq backend \"fastify\")}} (Fastify){{else if (eq backend \"elysia\")}} (Elysia){{/if}}\n{{/if}}\n{{else}}\n- **\\`packages/backend/\\`** - Convex backend functions\n{{/if}}\n\n{{#if (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\"))}}\n- **\\`apps/native/\\`** - React Native mobile app{{#if (includes frontend \"native-uniwind\")}} (with NativeWind){{else if (includes frontend \"native-unistyles\")}} (with Unistyles){{else if (includes frontend \"native-bare\")}} (bare styling){{/if}}\n{{/if}}\n\n{{#if (ne backend \"convex\")}}\n{{#if (ne api \"none\")}}\n- **\\`packages/api/\\`** - Shared API logic and types\n{{/if}}\n{{#if (and (ne auth \"none\") (ne backend \"convex\"))}}\n- **\\`packages/auth/\\`** - Authentication logic and utilities\n{{/if}}\n{{#if (and (ne database \"none\") (ne orm \"none\"))}}\n- **\\`packages/db/\\`** - Database schema and utilities\n{{/if}}\n- **\\`packages/env/\\`** - Shared environment variables and validation\n- **\\`packages/config/\\`** - Shared TypeScript configuration\n{{#if (or (eq webDeploy \"cloudflare\") (eq serverDeploy \"cloudflare\"))}}\n- **\\`packages/infra/\\`** - Infrastructure as code (Alchemy for Cloudflare)\n{{/if}}\n{{/if}}\n\n## Available Scripts\n\n- \\`{{packageManager}} run dev\\` - Start all apps in development mode\n{{#if (and (or (includes frontend \"tanstack-router\") (includes frontend \"react-router\") (includes frontend \"tanstack-start\")\n(includes frontend \"next\") (includes frontend \"nuxt\") (includes frontend \"svelte\") (includes frontend \"solid\")) (ne backend \"self\"))}}\n- \\`{{packageManager}} run dev:web\\` - Start only the web app\n{{/if}}\n{{#if (and (ne backend \"none\") (ne backend \"convex\") (ne backend \"self\"))}}\n- \\`{{packageManager}} run dev:server\\` - Start only the server\n{{/if}}\n{{#if (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\"))}}\n- \\`{{packageManager}} run dev:native\\` - Start only the native app\n{{/if}}\n- \\`{{packageManager}} run build\\` - Build all apps\n- \\`{{packageManager}} run lint\\` - Lint all packages\n- \\`{{packageManager}} run typecheck\\` - Type check all packages\n\n{{#if (and (ne database \"none\") (ne orm \"none\") (ne backend \"convex\"))}}\n## Database Commands\n\nAll database operations should be run from the {{#if (eq backend \"self\")}}web{{else}}server{{/if}} workspace:\n\n- \\`{{packageManager}} run db:push\\` - Push schema changes to database\n- \\`{{packageManager}} run db:studio\\` - Open database studio\n- \\`{{packageManager}} run db:generate\\` - Generate {{#if (eq orm \"drizzle\")}}Drizzle{{else if (eq orm \"prisma\")}}Prisma{{else}}{{orm}}{{/if}} files\n- \\`{{packageManager}} run db:migrate\\` - Run database migrations\n\n{{#if (eq orm \"drizzle\")}}\nDatabase schema files are located in {{#if (eq backend \"self\")}}\\`apps/web/src/db/schema/\\`{{else}}\\`packages/db/src/schema/\\`{{/if}}\n{{else if (eq orm \"prisma\")}}\nDatabase schema is located in {{#if (eq backend \"self\")}}\\`apps/web/prisma/schema.prisma\\`{{else}}\\`packages/db/prisma/schema.prisma\\`{{/if}}\n{{else if (eq orm \"mongoose\")}}\nDatabase models are located in {{#if (eq backend \"self\")}}\\`apps/web/src/db/models/\\`{{else}}\\`packages/db/src/models/\\`{{/if}}\n{{/if}}\n{{/if}}\n\n{{#if (ne api \"none\")}}\n## API Structure\n\n{{#if (eq api \"trpc\")}}\n- tRPC routers are in \\`packages/api/src/routers/\\`\n- Client-side tRPC utils are in \\`apps/web/src/utils/trpc.ts\\`\n{{else if (eq api \"orpc\")}}\n- oRPC contracts and routers are in \\`packages/api/src/\\`\n- Client-side oRPC client is in \\`apps/web/src/utils/orpc.ts\\`\n{{/if}}\n{{/if}}\n\n{{#if (eq auth \"better-auth\")}}\n## Authentication\n\nAuthentication is powered by Better Auth:\n- Auth configuration is in \\`packages/auth/src/\\`\n{{#if (or (includes frontend \"tanstack-router\") (includes frontend \"react-router\") (includes frontend \"tanstack-start\")\n(includes frontend \"next\") (includes frontend \"nuxt\") (includes frontend \"svelte\") (includes frontend \"solid\"))}}\n- Web app auth client is in \\`apps/web/src/lib/auth-client.ts\\`\n{{/if}}\n{{#if (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\"))}}\n- Native app auth client is in \\`apps/native/src/lib/auth-client.ts\\`\n{{/if}}\n{{/if}}\n\n## Project Configuration\n\nThis project includes a \\`bts.jsonc\\` configuration file that stores your Better-T-Stack settings:\n\n- Contains your selected stack configuration (database, ORM, backend, frontend, etc.)\n- Used by the CLI to understand your project structure\n- Safe to delete if not needed\n\n## Key Points\n\n- This is a {{#if (includes addons \"turborepo\")}}Turborepo {{/if}}monorepo using {{packageManager}} workspaces\n- Each app has its own \\`package.json\\` and dependencies\n- Run commands from the root to execute across all workspaces\n- Run workspace-specific commands with \\`{{packageManager}} run command-name\\`\n{{#if (includes addons \"turborepo\")}}\n- Turborepo handles build caching and parallel execution\n{{/if}}\n{{#if (or (includes addons \"husky\") (includes addons \"lefthook\"))}}\n- Git hooks are configured with {{#if (includes addons \"husky\")}}Husky{{else}}Lefthook{{/if}} for pre-commit checks\n{{/if}}\n`],\n [\"addons/husky/.husky/pre-commit\", `lint-staged\n`],\n [\"rust-base/crates/proto/src/lib.rs.hbs\", `//! Protocol buffer definitions for {{projectName}}.\n//!\n//! This crate contains the generated code from protobuf definitions.\n//! The generated code is committed to version control to avoid requiring\n//! protoc at build time.\n\n/// Generated gRPC service definitions\npub mod greeter {\n include!(\"generated/greeter.rs\");\n}\n\npub use greeter::greeter_server::{Greeter, GreeterServer};\npub use greeter::greeter_client::GreeterClient;\npub use greeter::{HelloRequest, HelloReply};\n`],\n [\"api/orpc/server/package.json.hbs\", `{\n \"name\": \"@{{projectName}}/api\",\n \"exports\": {\n \".\": {\n \"default\": \"./src/index.ts\"\n },\n \"./*\": {\n \"default\": \"./src/*.ts\"\n }\n },\n \"type\": \"module\",\n \"scripts\": {},\n \"devDependencies\": {},\n \"dependencies\": {}\n}`],\n [\"api/orpc/server/tsconfig.json.hbs\", `{\n \"extends\": \"@{{projectName}}/config/tsconfig.base.json\",\n \"compilerOptions\": {\n \"declaration\": true,\n \"declarationMap\": true,\n \"sourceMap\": true,\n \"outDir\": \"dist\",\n \"composite\": true\n }\n}`],\n [\"api/orpc/server/_gitignore\", `# dependencies (bun install)\nnode_modules\n\n# output\nout\ndist\n*.tgz\n\n# code coverage\ncoverage\n*.lcov\n\n# logs\nlogs\n_.log\nreport.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json\n\n# dotenv environment variable files\n.env\n.env.development.local\n.env.test.local\n.env.production.local\n.env.local\n\n# caches\n.eslintcache\n.cache\n*.tsbuildinfo\n\n# IntelliJ based IDEs\n.idea\n\n# Finder (MacOS) folder config\n.DS_Store\n`],\n [\"rust-base/crates/proto/proto/greeter.proto.hbs\", `syntax = \"proto3\";\n\npackage greeter;\n\n// The greeting service definition.\nservice Greeter {\n // Sends a greeting\n rpc SayHello (HelloRequest) returns (HelloReply) {}\n\n // Sends a streaming greeting\n rpc SayHelloStream (HelloRequest) returns (stream HelloReply) {}\n}\n\n// The request message containing the user's name.\nmessage HelloRequest {\n string name = 1;\n}\n\n// The response message containing the greeting.\nmessage HelloReply {\n string message = 1;\n}\n`],\n [\"rust-base/crates/server/src/main.rs.hbs\", `{{#if (eq rustWebFramework \"axum\")}}\nuse axum::{routing::get, Json, Router};\nuse serde::Serialize;\nuse tower_http::cors::CorsLayer;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n{{#if (eq rustOrm \"sea-orm\")}}\nuse sea_orm::{Database, DatabaseConnection};\nuse std::sync::Arc;\n{{/if}}\n{{#if (eq rustOrm \"sqlx\")}}\nuse sqlx::postgres::PgPoolOptions;\nuse sqlx::PgPool;\n{{/if}}\n{{#if (eq rustApi \"tonic\")}}\n\nmod grpc;\n{{/if}}\n{{#if (eq rustApi \"async-graphql\")}}\nuse async_graphql::http::GraphiQLSource;\nuse async_graphql_axum::GraphQL;\nuse axum::{\n response::{Html, IntoResponse},\n routing::post,\n};\n\nmod graphql;\n{{/if}}\n\n#[derive(Serialize)]\nstruct HealthResponse {\n status: &'static str,\n message: &'static str,\n{{#if (or (eq rustOrm \"sea-orm\") (eq rustOrm \"sqlx\"))}}\n database: &'static str,\n{{/if}}\n}\n\n{{#if (eq rustOrm \"sea-orm\")}}\n#[derive(Clone)]\npub struct AppState {\n pub db: Arc<DatabaseConnection>,\n}\n\nasync fn health(\n axum::extract::State(state): axum::extract::State<AppState>,\n) -> Json<HealthResponse> {\n let db_status = if state.db.ping().await.is_ok() {\n \"connected\"\n } else {\n \"disconnected\"\n };\n Json(HealthResponse {\n status: \"ok\",\n message: \"Server is running\",\n database: db_status,\n })\n}\n{{else if (eq rustOrm \"sqlx\")}}\n#[derive(Clone)]\npub struct AppState {\n pub db: PgPool,\n}\n\nasync fn health(\n axum::extract::State(state): axum::extract::State<AppState>,\n) -> Json<HealthResponse> {\n let db_status = if state.db.acquire().await.is_ok() {\n \"connected\"\n } else {\n \"disconnected\"\n };\n Json(HealthResponse {\n status: \"ok\",\n message: \"Server is running\",\n database: db_status,\n })\n}\n{{else}}\nasync fn health() -> Json<HealthResponse> {\n Json(HealthResponse {\n status: \"ok\",\n message: \"Server is running\",\n })\n}\n{{/if}}\n\n{{#if (eq rustApi \"async-graphql\")}}\n/// GraphiQL IDE handler\nasync fn graphiql() -> impl IntoResponse {\n Html(\n GraphiQLSource::build()\n .endpoint(\"/graphql\")\n .finish(),\n )\n}\n{{/if}}\n\n#[tokio::main]\nasync fn main() -> anyhow::Result<()> {\n // Load environment variables\n dotenvy::dotenv().ok();\n\n // Initialize tracing\n tracing_subscriber::registry()\n .with(tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| \"debug\".into()))\n .with(tracing_subscriber::fmt::layer())\n .init();\n\n{{#if (eq rustOrm \"sea-orm\")}}\n // Initialize database connection\n let database_url = std::env::var(\"DATABASE_URL\")\n .expect(\"DATABASE_URL must be set\");\n\n tracing::info!(\"Connecting to database...\");\n let db = Database::connect(&database_url).await?;\n tracing::info!(\"Database connected successfully\");\n\n let state = AppState { db: Arc::new(db) };\n\n{{#if (eq rustApi \"async-graphql\")}}\n // Build GraphQL schema with database connection\n let schema = graphql::build_schema(state.db.clone());\n\n // Build router with GraphQL and state\n let app = Router::new()\n .route(\"/health\", get(health))\n .route(\"/graphql\", post(GraphQL::new(schema)))\n .route(\"/graphiql\", get(graphiql))\n .layer(CorsLayer::permissive())\n .with_state(state);\n\n tracing::info!(\"GraphQL endpoint: /graphql\");\n tracing::info!(\"GraphiQL IDE: /graphiql\");\n{{else}}\n // Build router with state\n let app = Router::new()\n .route(\"/health\", get(health))\n .layer(CorsLayer::permissive())\n .with_state(state);\n{{/if}}\n{{else if (eq rustOrm \"sqlx\")}}\n // Initialize database connection pool\n let database_url = std::env::var(\"DATABASE_URL\")\n .expect(\"DATABASE_URL must be set\");\n\n tracing::info!(\"Connecting to database...\");\n let pool = PgPoolOptions::new()\n .max_connections(5)\n .connect(&database_url)\n .await?;\n tracing::info!(\"Database connected successfully\");\n\n let state = AppState { db: pool.clone() };\n\n{{#if (eq rustApi \"async-graphql\")}}\n // Build GraphQL schema with database pool\n let schema = graphql::build_schema(pool);\n\n // Build router with GraphQL and state\n let app = Router::new()\n .route(\"/health\", get(health))\n .route(\"/graphql\", post(GraphQL::new(schema)))\n .route(\"/graphiql\", get(graphiql))\n .layer(CorsLayer::permissive())\n .with_state(state);\n\n tracing::info!(\"GraphQL endpoint: /graphql\");\n tracing::info!(\"GraphiQL IDE: /graphiql\");\n{{else}}\n // Build router with state\n let app = Router::new()\n .route(\"/health\", get(health))\n .layer(CorsLayer::permissive())\n .with_state(state);\n{{/if}}\n{{else}}\n{{#if (eq rustApi \"async-graphql\")}}\n // Build GraphQL schema\n let schema = graphql::build_schema();\n\n // Build router with GraphQL\n let app = Router::new()\n .route(\"/health\", get(health))\n .route(\"/graphql\", post(GraphQL::new(schema)))\n .route(\"/graphiql\", get(graphiql))\n .layer(CorsLayer::permissive());\n\n tracing::info!(\"GraphQL endpoint: /graphql\");\n tracing::info!(\"GraphiQL IDE: /graphiql\");\n{{else}}\n // Build router\n let app = Router::new()\n .route(\"/health\", get(health))\n .layer(CorsLayer::permissive());\n{{/if}}\n{{/if}}\n\n // Get host and port from environment\n let host = std::env::var(\"HOST\").unwrap_or_else(|_| \"127.0.0.1\".to_string());\n let port = std::env::var(\"PORT\").unwrap_or_else(|_| \"3000\".to_string());\n let addr = format!(\"{}:{}\", host, port);\n\n tracing::info!(\"Starting HTTP server at http://{}\", addr);\n\n{{#if (eq rustApi \"tonic\")}}\n // Start gRPC server on a separate port\n let grpc_port = std::env::var(\"GRPC_PORT\").unwrap_or_else(|_| \"50051\".to_string());\n let grpc_addr = format!(\"{}:{}\", host, grpc_port).parse()?;\n\n tracing::info!(\"Starting gRPC server at {}\", grpc_addr);\n\n let grpc_server = tonic::transport::Server::builder()\n .add_service(grpc::create_grpc_server())\n .serve(grpc_addr);\n\n // Start HTTP server\n let listener = tokio::net::TcpListener::bind(&addr).await?;\n let http_server = axum::serve(listener, app);\n\n // Run both servers concurrently\n tokio::select! {\n result = http_server => {\n if let Err(e) = result {\n tracing::error!(\"HTTP server error: {}\", e);\n }\n }\n result = grpc_server => {\n if let Err(e) = result {\n tracing::error!(\"gRPC server error: {}\", e);\n }\n }\n }\n{{else}}\n // Start server\n let listener = tokio::net::TcpListener::bind(&addr).await?;\n axum::serve(listener, app).await?;\n{{/if}}\n\n Ok(())\n}\n{{else if (eq rustWebFramework \"actix-web\")}}\nuse actix_cors::Cors;\nuse actix_web::{get, web, App, HttpResponse, HttpServer, Responder};\nuse serde::Serialize;\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n{{#if (eq rustOrm \"sea-orm\")}}\nuse sea_orm::{Database, DatabaseConnection};\nuse std::sync::Arc;\n{{/if}}\n{{#if (eq rustOrm \"sqlx\")}}\nuse sqlx::postgres::PgPoolOptions;\nuse sqlx::PgPool;\n{{/if}}\n{{#if (eq rustApi \"tonic\")}}\n\nmod grpc;\n{{/if}}\n{{#if (eq rustApi \"async-graphql\")}}\nuse async_graphql::http::GraphiQLSource;\nuse async_graphql_actix_web::{GraphQLRequest, GraphQLResponse};\n\nmod graphql;\n{{/if}}\n\n#[derive(Serialize)]\nstruct HealthResponse {\n status: &'static str,\n message: &'static str,\n{{#if (or (eq rustOrm \"sea-orm\") (eq rustOrm \"sqlx\"))}}\n database: &'static str,\n{{/if}}\n}\n\n{{#if (eq rustOrm \"sea-orm\")}}\npub struct AppState {\n pub db: Arc<DatabaseConnection>,\n}\n\n#[get(\"/health\")]\nasync fn health(data: web::Data<AppState>) -> impl Responder {\n let db_status = if data.db.ping().await.is_ok() {\n \"connected\"\n } else {\n \"disconnected\"\n };\n HttpResponse::Ok().json(HealthResponse {\n status: \"ok\",\n message: \"Server is running\",\n database: db_status,\n })\n}\n{{else if (eq rustOrm \"sqlx\")}}\npub struct AppState {\n pub db: PgPool,\n}\n\n#[get(\"/health\")]\nasync fn health(data: web::Data<AppState>) -> impl Responder {\n let db_status = if data.db.acquire().await.is_ok() {\n \"connected\"\n } else {\n \"disconnected\"\n };\n HttpResponse::Ok().json(HealthResponse {\n status: \"ok\",\n message: \"Server is running\",\n database: db_status,\n })\n}\n{{else}}\n#[get(\"/health\")]\nasync fn health() -> impl Responder {\n HttpResponse::Ok().json(HealthResponse {\n status: \"ok\",\n message: \"Server is running\",\n })\n}\n{{/if}}\n\n{{#if (eq rustApi \"async-graphql\")}}\n/// GraphQL endpoint handler\nasync fn graphql_handler(\n schema: web::Data<graphql::GraphQLSchema>,\n req: GraphQLRequest,\n) -> GraphQLResponse {\n schema.execute(req.into_inner()).await.into()\n}\n\n/// GraphiQL IDE handler\n#[get(\"/graphiql\")]\nasync fn graphiql() -> impl Responder {\n HttpResponse::Ok()\n .content_type(\"text/html; charset=utf-8\")\n .body(\n GraphiQLSource::build()\n .endpoint(\"/graphql\")\n .finish(),\n )\n}\n{{/if}}\n\n#[actix_web::main]\nasync fn main() -> anyhow::Result<()> {\n // Load environment variables\n dotenvy::dotenv().ok();\n\n // Initialize tracing\n tracing_subscriber::registry()\n .with(tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| \"debug\".into()))\n .with(tracing_subscriber::fmt::layer())\n .init();\n\n{{#if (eq rustOrm \"sea-orm\")}}\n // Initialize database connection\n let database_url = std::env::var(\"DATABASE_URL\")\n .expect(\"DATABASE_URL must be set\");\n\n tracing::info!(\"Connecting to database...\");\n let db = Database::connect(&database_url).await?;\n tracing::info!(\"Database connected successfully\");\n\n let db_arc = Arc::new(db);\n let state = web::Data::new(AppState { db: db_arc.clone() });\n{{#if (eq rustApi \"async-graphql\")}}\n\n // Build GraphQL schema with database\n let schema = web::Data::new(graphql::build_schema(db_arc));\n tracing::info!(\"GraphQL endpoint: /graphql\");\n tracing::info!(\"GraphiQL IDE: /graphiql\");\n{{/if}}\n{{/if}}\n{{#if (eq rustOrm \"sqlx\")}}\n // Initialize database connection pool\n let database_url = std::env::var(\"DATABASE_URL\")\n .expect(\"DATABASE_URL must be set\");\n\n tracing::info!(\"Connecting to database...\");\n let pool = PgPoolOptions::new()\n .max_connections(5)\n .connect(&database_url)\n .await?;\n tracing::info!(\"Database connected successfully\");\n\n let state = web::Data::new(AppState { db: pool.clone() });\n{{#if (eq rustApi \"async-graphql\")}}\n\n // Build GraphQL schema with database pool\n let schema = web::Data::new(graphql::build_schema(pool));\n tracing::info!(\"GraphQL endpoint: /graphql\");\n tracing::info!(\"GraphiQL IDE: /graphiql\");\n{{/if}}\n{{/if}}\n{{#if (and (not (eq rustOrm \"sea-orm\")) (not (eq rustOrm \"sqlx\")) (eq rustApi \"async-graphql\"))}}\n // Build GraphQL schema\n let schema = web::Data::new(graphql::build_schema());\n tracing::info!(\"GraphQL endpoint: /graphql\");\n tracing::info!(\"GraphiQL IDE: /graphiql\");\n{{/if}}\n\n // Get host and port from environment\n let host = std::env::var(\"HOST\").unwrap_or_else(|_| \"127.0.0.1\".to_string());\n let port: u16 = std::env::var(\"PORT\")\n .unwrap_or_else(|_| \"3000\".to_string())\n .parse()?;\n\n tracing::info!(\"Starting HTTP server at http://{}:{}\", host, port);\n\n{{#if (eq rustApi \"tonic\")}}\n // Start gRPC server on a separate port\n let grpc_port = std::env::var(\"GRPC_PORT\").unwrap_or_else(|_| \"50051\".to_string());\n let grpc_host = host.clone();\n let grpc_addr = format!(\"{}:{}\", grpc_host, grpc_port).parse()?;\n\n tracing::info!(\"Starting gRPC server at {}\", grpc_addr);\n\n // Spawn gRPC server in a separate task\n let grpc_handle = tokio::spawn(async move {\n tonic::transport::Server::builder()\n .add_service(grpc::create_grpc_server())\n .serve(grpc_addr)\n .await\n });\n\n // Start HTTP server\n{{#if (or (eq rustOrm \"sea-orm\") (eq rustOrm \"sqlx\"))}}\n let http_server = HttpServer::new(move || {\n let cors = Cors::permissive();\n App::new()\n .wrap(cors)\n .app_data(state.clone())\n .service(health)\n })\n{{else}}\n let http_server = HttpServer::new(|| {\n let cors = Cors::permissive();\n App::new()\n .wrap(cors)\n .service(health)\n })\n{{/if}}\n .bind((host, port))?\n .run();\n\n // Run both servers concurrently\n tokio::select! {\n result = http_server => {\n if let Err(e) = result {\n tracing::error!(\"HTTP server error: {}\", e);\n }\n }\n result = grpc_handle => {\n match result {\n Ok(Ok(())) => {}\n Ok(Err(e)) => tracing::error!(\"gRPC server error: {}\", e),\n Err(e) => tracing::error!(\"gRPC task error: {}\", e),\n }\n }\n }\n{{else if (eq rustApi \"async-graphql\")}}\n // Start server with GraphQL\n{{#if (or (eq rustOrm \"sea-orm\") (eq rustOrm \"sqlx\"))}}\n HttpServer::new(move || {\n let cors = Cors::permissive();\n App::new()\n .wrap(cors)\n .app_data(state.clone())\n .app_data(schema.clone())\n .service(health)\n .service(graphiql)\n .route(\"/graphql\", web::post().to(graphql_handler))\n })\n{{else}}\n HttpServer::new(move || {\n let cors = Cors::permissive();\n App::new()\n .wrap(cors)\n .app_data(schema.clone())\n .service(health)\n .service(graphiql)\n .route(\"/graphql\", web::post().to(graphql_handler))\n })\n{{/if}}\n .bind((host, port))?\n .run()\n .await?;\n{{else}}\n // Start server\n{{#if (or (eq rustOrm \"sea-orm\") (eq rustOrm \"sqlx\"))}}\n HttpServer::new(move || {\n let cors = Cors::permissive();\n App::new()\n .wrap(cors)\n .app_data(state.clone())\n .service(health)\n })\n{{else}}\n HttpServer::new(|| {\n let cors = Cors::permissive();\n App::new()\n .wrap(cors)\n .service(health)\n })\n{{/if}}\n .bind((host, port))?\n .run()\n .await?;\n{{/if}}\n\n Ok(())\n}\n{{else}}\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n{{#if (eq rustApi \"tonic\")}}\n\nmod grpc;\n{{/if}}\n\n#[tokio::main]\nasync fn main() -> anyhow::Result<()> {\n // Load environment variables\n dotenvy::dotenv().ok();\n\n // Initialize tracing\n tracing_subscriber::registry()\n .with(tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| \"debug\".into()))\n .with(tracing_subscriber::fmt::layer())\n .init();\n\n{{#if (eq rustApi \"tonic\")}}\n // Get host and port from environment\n let host = std::env::var(\"HOST\").unwrap_or_else(|_| \"127.0.0.1\".to_string());\n let grpc_port = std::env::var(\"GRPC_PORT\").unwrap_or_else(|_| \"50051\".to_string());\n let grpc_addr = format!(\"{}:{}\", host, grpc_port).parse()?;\n\n tracing::info!(\"Starting gRPC server at {}\", grpc_addr);\n\n tonic::transport::Server::builder()\n .add_service(grpc::create_grpc_server())\n .serve(grpc_addr)\n .await?;\n{{else}}\n tracing::info!(\"Hello from {{projectName}}!\");\n tracing::info!(\"Add a web framework (axum or actix-web) to start building your API.\");\n{{/if}}\n\n Ok(())\n}\n{{/if}}\n`],\n [\"rust-base/crates/server/src/graphql.rs.hbs\", `use async_graphql::{Context, EmptySubscription, Object, Schema};\n{{#if (eq rustOrm \"sea-orm\")}}\nuse sea_orm::DatabaseConnection;\nuse std::sync::Arc;\n{{/if}}\n{{#if (eq rustOrm \"sqlx\")}}\nuse sqlx::PgPool;\n{{/if}}\n\n/// GraphQL Query root\npub struct QueryRoot;\n\n#[Object]\nimpl QueryRoot {\n /// Returns a greeting message\n async fn hello(&self, name: Option<String>) -> String {\n format!(\"Hello, {}!\", name.unwrap_or_else(|| \"World\".to_string()))\n }\n\n /// Returns the server status\n async fn status(&self) -> &'static str {\n \"Server is running\"\n }\n\n{{#if (eq rustOrm \"sea-orm\")}}\n /// Example query using database connection\n async fn db_status(&self, ctx: &Context<'_>) -> async_graphql::Result<String> {\n let db = ctx.data::<Arc<DatabaseConnection>>()?;\n match db.ping().await {\n Ok(_) => Ok(\"Database connected\".to_string()),\n Err(e) => Ok(format!(\"Database error: {}\", e)),\n }\n }\n{{/if}}\n{{#if (eq rustOrm \"sqlx\")}}\n /// Example query using database pool\n async fn db_status(&self, ctx: &Context<'_>) -> async_graphql::Result<String> {\n let pool = ctx.data::<PgPool>()?;\n match pool.acquire().await {\n Ok(_) => Ok(\"Database connected\".to_string()),\n Err(e) => Ok(format!(\"Database error: {}\", e)),\n }\n }\n{{/if}}\n}\n\n/// GraphQL Mutation root\npub struct MutationRoot;\n\n#[Object]\nimpl MutationRoot {\n /// Example mutation that echoes back a message\n async fn echo(&self, message: String) -> String {\n message\n }\n}\n\n/// The GraphQL schema type\npub type GraphQLSchema = Schema<QueryRoot, MutationRoot, EmptySubscription>;\n\n/// Build the GraphQL schema with optional data sources\n{{#if (eq rustOrm \"sea-orm\")}}\npub fn build_schema(db: Arc<DatabaseConnection>) -> GraphQLSchema {\n Schema::build(QueryRoot, MutationRoot, EmptySubscription)\n .data(db)\n .finish()\n}\n{{else if (eq rustOrm \"sqlx\")}}\npub fn build_schema(pool: PgPool) -> GraphQLSchema {\n Schema::build(QueryRoot, MutationRoot, EmptySubscription)\n .data(pool)\n .finish()\n}\n{{else}}\npub fn build_schema() -> GraphQLSchema {\n Schema::build(QueryRoot, MutationRoot, EmptySubscription)\n .finish()\n}\n{{/if}}\n`],\n [\"rust-base/crates/server/src/grpc.rs.hbs\", `//! gRPC service implementations for {{projectName}}.\n\nuse {{projectName}}_proto::{Greeter, GreeterServer, HelloReply, HelloRequest};\nuse tokio_stream::wrappers::ReceiverStream;\nuse tonic::{Request, Response, Status};\n\n/// Implementation of the Greeter gRPC service.\n#[derive(Debug, Default)]\npub struct GreeterService;\n\n#[tonic::async_trait]\nimpl Greeter for GreeterService {\n /// Handle a unary greeting request.\n async fn say_hello(\n &self,\n request: Request<HelloRequest>,\n ) -> Result<Response<HelloReply>, Status> {\n let name = request.into_inner().name;\n tracing::info!(\"Received gRPC request: SayHello from '{}'\", name);\n\n let reply = HelloReply {\n message: format!(\"Hello, {}!\", name),\n };\n\n Ok(Response::new(reply))\n }\n\n type SayHelloStreamStream = ReceiverStream<Result<HelloReply, Status>>;\n\n /// Handle a streaming greeting request.\n async fn say_hello_stream(\n &self,\n request: Request<HelloRequest>,\n ) -> Result<Response<Self::SayHelloStreamStream>, Status> {\n let name = request.into_inner().name;\n tracing::info!(\"Received gRPC streaming request: SayHelloStream from '{}'\", name);\n\n let (tx, rx) = tokio::sync::mpsc::channel(4);\n\n tokio::spawn(async move {\n for i in 1..=5 {\n let reply = HelloReply {\n message: format!(\"Hello #{} to {}!\", i, name),\n };\n if tx.send(Ok(reply)).await.is_err() {\n break;\n }\n tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;\n }\n });\n\n Ok(Response::new(ReceiverStream::new(rx)))\n }\n}\n\n/// Create and configure the gRPC server.\npub fn create_grpc_server() -> GreeterServer<GreeterService> {\n GreeterServer::new(GreeterService::default())\n}\n`],\n [\"rust-base/crates/tui/src/main.rs.hbs\", `use std::io;\nuse std::time::Duration;\n\nuse anyhow::Result;\nuse crossterm::{\n event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind},\n execute,\n terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},\n};\nuse ratatui::{\n prelude::*,\n widgets::{Block, Borders, List, ListItem, ListState, Paragraph, Tabs},\n};\nuse tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};\n\n/// Application state\nstruct App {\n /// Current tab index\n tab_index: usize,\n /// Menu items for the sidebar\n menu_items: Vec<&'static str>,\n /// Current menu selection state\n menu_state: ListState,\n /// Counter value for demo\n counter: i32,\n /// Status messages\n status: String,\n /// Whether the app should quit\n should_quit: bool,\n}\n\nimpl Default for App {\n fn default() -> Self {\n let mut menu_state = ListState::default();\n menu_state.select(Some(0));\n\n Self {\n tab_index: 0,\n menu_items: vec![\"Dashboard\", \"Settings\", \"Logs\", \"Help\"],\n menu_state,\n counter: 0,\n status: String::from(\"Ready\"),\n should_quit: false,\n }\n }\n}\n\nimpl App {\n /// Handle key events\n fn handle_key(&mut self, key: KeyCode) {\n match key {\n KeyCode::Char('q') | KeyCode::Esc => {\n self.should_quit = true;\n }\n KeyCode::Tab => {\n self.tab_index = (self.tab_index + 1) % 3;\n }\n KeyCode::BackTab => {\n self.tab_index = if self.tab_index == 0 { 2 } else { self.tab_index - 1 };\n }\n KeyCode::Up | KeyCode::Char('k') => {\n self.menu_previous();\n }\n KeyCode::Down | KeyCode::Char('j') => {\n self.menu_next();\n }\n KeyCode::Enter => {\n if let Some(selected) = self.menu_state.selected() {\n self.status = format!(\"Selected: {}\", self.menu_items[selected]);\n }\n }\n KeyCode::Char('+') | KeyCode::Char('=') => {\n self.counter += 1;\n self.status = format!(\"Counter incremented to {}\", self.counter);\n }\n KeyCode::Char('-') => {\n self.counter -= 1;\n self.status = format!(\"Counter decremented to {}\", self.counter);\n }\n _ => {}\n }\n }\n\n /// Select previous menu item\n fn menu_previous(&mut self) {\n let i = match self.menu_state.selected() {\n Some(i) => {\n if i == 0 {\n self.menu_items.len() - 1\n } else {\n i - 1\n }\n }\n None => 0,\n };\n self.menu_state.select(Some(i));\n }\n\n /// Select next menu item\n fn menu_next(&mut self) {\n let i = match self.menu_state.selected() {\n Some(i) => {\n if i >= self.menu_items.len() - 1 {\n 0\n } else {\n i + 1\n }\n }\n None => 0,\n };\n self.menu_state.select(Some(i));\n }\n}\n\nfn main() -> Result<()> {\n // Load environment variables\n dotenvy::dotenv().ok();\n\n // Initialize tracing to a file (can't use terminal while TUI is running)\n let file_appender = tracing_appender::rolling::daily(\"logs\", \"tui.log\");\n let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);\n tracing_subscriber::registry()\n .with(tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| \"info\".into()))\n .with(tracing_subscriber::fmt::layer().with_writer(non_blocking))\n .init();\n\n tracing::info!(\"Starting {{projectName}} TUI\");\n\n // Setup terminal\n enable_raw_mode()?;\n let mut stdout = io::stdout();\n execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;\n let backend = CrosstermBackend::new(stdout);\n let mut terminal = Terminal::new(backend)?;\n\n // Create app state\n let mut app = App::default();\n\n // Main loop\n let result = run_app(&mut terminal, &mut app);\n\n // Restore terminal\n disable_raw_mode()?;\n execute!(\n terminal.backend_mut(),\n LeaveAlternateScreen,\n DisableMouseCapture\n )?;\n terminal.show_cursor()?;\n\n if let Err(err) = result {\n tracing::error!(\"Application error: {:?}\", err);\n eprintln!(\"Error: {:?}\", err);\n }\n\n tracing::info!(\"{{projectName}} TUI exited\");\n Ok(())\n}\n\n/// Run the application main loop\nfn run_app<B: Backend>(terminal: &mut Terminal<B>, app: &mut App) -> Result<()> {\n loop {\n terminal.draw(|f| ui(f, app))?;\n\n // Poll for events with a timeout\n if event::poll(Duration::from_millis(100))? {\n if let Event::Key(key) = event::read()? {\n if key.kind == KeyEventKind::Press {\n app.handle_key(key.code);\n }\n }\n }\n\n if app.should_quit {\n return Ok(());\n }\n }\n}\n\n/// Render the UI\nfn ui(f: &mut Frame, app: &mut App) {\n let chunks = Layout::default()\n .direction(Direction::Vertical)\n .constraints([\n Constraint::Length(3), // Tabs\n Constraint::Min(0), // Main content\n Constraint::Length(3), // Status bar\n ])\n .split(f.area());\n\n // Render tabs\n let tabs = Tabs::new(vec![\"Main\", \"Stats\", \"Config\"])\n .block(Block::default().borders(Borders::ALL).title(\" {{projectName}} TUI \"))\n .select(app.tab_index)\n .style(Style::default().fg(Color::White))\n .highlight_style(Style::default().fg(Color::Yellow).bold());\n f.render_widget(tabs, chunks[0]);\n\n // Render main content area\n let main_chunks = Layout::default()\n .direction(Direction::Horizontal)\n .constraints([Constraint::Percentage(30), Constraint::Percentage(70)])\n .split(chunks[1]);\n\n // Render sidebar menu\n let menu_items: Vec<ListItem> = app\n .menu_items\n .iter()\n .map(|i| ListItem::new(*i).style(Style::default().fg(Color::White)))\n .collect();\n let menu = List::new(menu_items)\n .block(Block::default().borders(Borders::ALL).title(\" Menu \"))\n .highlight_style(Style::default().bg(Color::Blue).fg(Color::White).bold())\n .highlight_symbol(\"▶ \");\n f.render_stateful_widget(menu, main_chunks[0], &mut app.menu_state);\n\n // Render content based on selected tab\n let content = match app.tab_index {\n 0 => {\n let text = vec![\n Line::from(\"Welcome to {{projectName}} TUI!\"),\n Line::from(\"\"),\n Line::from(format!(\"Counter: {}\", app.counter)),\n Line::from(\"\"),\n Line::from(\"Keybindings:\"),\n Line::from(\" Tab / Shift+Tab - Switch tabs\"),\n Line::from(\" j/k or ↑/↓ - Navigate menu\"),\n Line::from(\" Enter - Select item\"),\n Line::from(\" +/- - Increment/Decrement counter\"),\n Line::from(\" q or Esc - Quit\"),\n ];\n Paragraph::new(text)\n .block(Block::default().borders(Borders::ALL).title(\" Dashboard \"))\n .style(Style::default().fg(Color::White))\n }\n 1 => {\n let text = vec![\n Line::from(\"Statistics\"),\n Line::from(\"\"),\n Line::from(format!(\"Current counter value: {}\", app.counter)),\n Line::from(format!(\"Menu items: {}\", app.menu_items.len())),\n Line::from(format!(\n \"Selected menu item: {}\",\n app.menu_state\n .selected()\n .map(|i| app.menu_items[i])\n .unwrap_or(\"None\")\n )),\n ];\n Paragraph::new(text)\n .block(Block::default().borders(Borders::ALL).title(\" Stats \"))\n .style(Style::default().fg(Color::Cyan))\n }\n _ => {\n let text = vec![\n Line::from(\"Configuration\"),\n Line::from(\"\"),\n Line::from(\"This is where you would configure the application.\"),\n Line::from(\"\"),\n Line::from(\"Environment variables:\"),\n Line::from(format!(\" RUST_LOG: {}\", std::env::var(\"RUST_LOG\").unwrap_or_else(|_| \"not set\".to_string()))),\n ];\n Paragraph::new(text)\n .block(Block::default().borders(Borders::ALL).title(\" Config \"))\n .style(Style::default().fg(Color::Green))\n }\n };\n f.render_widget(content, main_chunks[1]);\n\n // Render status bar\n let status = Paragraph::new(app.status.as_str())\n .block(Block::default().borders(Borders::ALL).title(\" Status \"))\n .style(Style::default().fg(Color::Gray));\n f.render_widget(status, chunks[2]);\n}\n`],\n [\"db-setup/docker-compose/mongodb/docker-compose.yml.hbs\", `name: {{projectName}}\n\nservices:\n mongodb:\n image: mongo\n container_name: {{projectName}}-mongodb\n environment:\n MONGO_INITDB_ROOT_USERNAME: root\n MONGO_INITDB_ROOT_PASSWORD: password\n MONGO_INITDB_DATABASE: {{projectName}}\n ports:\n - \"27017:27017\"\n volumes:\n - {{projectName}}_mongodb_data:/data/db\n healthcheck:\n test: [\"CMD\", \"mongosh\", \"--eval\", \"db.adminCommand('ping')\"]\n interval: 10s\n timeout: 5s\n retries: 5\n restart: unless-stopped\n\nvolumes:\n {{projectName}}_mongodb_data:`],\n [\"db-setup/docker-compose/mysql/docker-compose.yml.hbs\", `name: {{projectName}}\n\nservices:\n mysql:\n image: mysql\n container_name: {{projectName}}-mysql\n environment:\n MYSQL_ROOT_PASSWORD: password\n MYSQL_DATABASE: {{projectName}}\n MYSQL_USER: user\n MYSQL_PASSWORD: password\n ports:\n - \"3306:3306\"\n volumes:\n - {{projectName}}_mysql_data:/var/lib/mysql\n healthcheck:\n test: [\"CMD\", \"mysqladmin\", \"ping\", \"-h\", \"localhost\"]\n interval: 10s\n timeout: 5s\n retries: 5\n restart: unless-stopped\n\nvolumes:\n {{projectName}}_mysql_data:`],\n [\"db-setup/docker-compose/postgres/docker-compose.yml.hbs\", `name: {{projectName}}\n\nservices:\n postgres:\n image: postgres\n container_name: {{projectName}}-postgres\n environment:\n POSTGRES_DB: {{projectName}}\n POSTGRES_USER: postgres\n POSTGRES_PASSWORD: password\n ports:\n - \"5432:5432\"\n volumes:\n - {{projectName}}_postgres_data:/var/lib/postgresql\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n interval: 10s\n timeout: 5s\n retries: 5\n restart: unless-stopped\n\nvolumes:\n {{projectName}}_postgres_data:`],\n [\"api/trpc/server/package.json.hbs\", `{\n \"name\": \"@{{projectName}}/api\",\n \"exports\": {\n \".\": {\n \"default\": \"./src/index.ts\"\n },\n \"./*\": {\n \"default\": \"./src/*.ts\"\n }\n },\n \"type\": \"module\",\n \"scripts\": {},\n \"devDependencies\": {}\n}`],\n [\"api/trpc/server/tsconfig.json.hbs\", `{\n \"extends\": \"@{{projectName}}/config/tsconfig.base.json\",\n \"compilerOptions\": {\n \"declaration\": true,\n \"declarationMap\": true,\n \"sourceMap\": true,\n \"outDir\": \"dist\",\n \"composite\": true\n }\n}`],\n [\"api/trpc/server/_gitignore\", `# dependencies (bun install)\nnode_modules\n\n# output\nout\ndist\n*.tgz\n\n# code coverage\ncoverage\n*.lcov\n\n# logs\nlogs\n_.log\nreport.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json\n\n# dotenv environment variable files\n.env\n.env.development.local\n.env.test.local\n.env.production.local\n.env.local\n\n# caches\n.eslintcache\n.cache\n*.tsbuildinfo\n\n# IntelliJ based IDEs\n.idea\n\n# Finder (MacOS) folder config\n.DS_Store\n`],\n [\"backend/server/adonisjs/package.json.hbs\", `{\n\t\"name\": \"server\",\n\t\"main\": \"bin/server.js\",\n\t\"type\": \"module\",\n\t\"scripts\": {\n\t\t\"dev\": \"node ace serve --watch\",\n\t\t\"build\": \"node ace build\",\n\t\t\"start\": \"node bin/server.js\",\n\t\t\"check-types\": \"tsc -b\",\n\t\t\"test\": \"node ace test\"\n\t},\n\t\"dependencies\": {},\n\t\"devDependencies\": {}\n}\n`],\n [\"backend/server/adonisjs/adonisrc.ts.hbs\", `import { defineConfig } from \"@adonisjs/core/app\";\n\nexport default defineConfig({\n\tcommands: [],\n\tproviders: [\n\t\t() => import(\"@adonisjs/core/providers/app_provider\"),\n\t\t() => import(\"@adonisjs/core/providers/hash_provider\"),\n\t\t{\n\t\t\tfile: () => import(\"@adonisjs/core/providers/repl_provider\"),\n\t\t\tenvironment: [\"repl\", \"test\"],\n\t\t},\n\t],\n\tpreloads: [() => import(\"#start/routes\")],\n\tdirectories: {\n\t\tconfig: \"config\",\n\t\tstart: \"start\",\n\t\ttmp: \"tmp\",\n\t},\n\tmetaFiles: [\n\t\t{\n\t\t\tpattern: \"public/**\",\n\t\t\treloadServer: false,\n\t\t},\n\t],\n});\n`],\n [\"backend/server/adonisjs/tsconfig.json.hbs\", `{\n\t\"extends\": \"@adonisjs/tsconfig/tsconfig.app.json\",\n\t\"compilerOptions\": {\n\t\t\"outDir\": \"./build\",\n\t\t\"rootDir\": \".\",\n\t\t\"paths\": {\n\t\t\t\"#controllers/*\": [\"./app/controllers/*.js\"],\n\t\t\t\"#middleware/*\": [\"./app/middleware/*.js\"],\n\t\t\t\"#start/*\": [\"./start/*.js\"],\n\t\t\t\"#config/*\": [\"./config/*.js\"]\n\t\t}\n\t},\n\t\"include\": [\"**/*.ts\"],\n\t\"exclude\": [\"node_modules\", \"build\"]\n}\n`],\n [\"backend/server/adonisjs/_gitignore\", `build\ntmp\nnode_modules\n.env\n`],\n [\"backend/server/base/tsdown.config.ts.hbs\", `import { defineConfig } from 'tsdown';\n\nexport default defineConfig({\n entry: './src/index.ts',\n format: 'esm',\n outDir: './dist',\n clean: true,\n noExternal: [/@{{projectName}}\\\\/.*/]\n});\n`],\n [\"backend/server/base/package.json.hbs\", `{\n\t\"name\": \"server\",\n\t\"main\": \"src/index.ts\",\n\t\"type\": \"module\",\n\t\"scripts\": {\n\t\t\"build\": \"tsdown\",\n\t\t\"check-types\": \"tsc -b\",\n\t\t\"compile\": \"bun build --compile --minify --sourcemap --bytecode ./src/index.ts --outfile server\"\n\t},\n\t\"dependencies\": {},\n\t{{#if (eq dbSetup 'supabase')}}\n\t\"trustedDependencies\": [\n \"supabase\"\n ],\n {{/if}}\n\t\"devDependencies\": {}\n}\n`],\n [\"backend/server/base/tsconfig.json.hbs\", `{\n \"extends\": \"@{{projectName}}/config/tsconfig.base.json\",\n \"compilerOptions\": {\n \"composite\": true,\n\t\t\"outDir\": \"dist\",\n\t\t\"baseUrl\": \".\",\n \"paths\": {\n \"@/*\": [\"./src/*\"]\n },\n \"jsx\": \"react-jsx\"{{#if (eq backend \"hono\")}},\n \"jsxImportSource\": \"hono/jsx\"{{/if}}\n }\n}\n`],\n [\"backend/server/base/_gitignore\", `# prod\ndist/\n/build\n/out/\n\n# dev\n.yarn/\n!.yarn/patches\n!.yarn/plugins\n!.yarn/releases\n!.yarn/versions\n.vscode/*\n!.vscode/launch.json\n!.vscode/*.code-snippets\n.idea/workspace.xml\n.idea/usage.statistics.xml\n.idea/shelf\n.wrangler\n.alchemy\n/.next/\n.vercel\nprisma/generated/\n\n\n# deps\nnode_modules/\n/node_modules\n/.pnp\n.pnp.*\n\n# env\n.env*\n.env.production\n!.env.example\n.dev.vars\n\n# logs\nlogs/\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\n# misc\n.DS_Store\n*.pem\n\n# local db\n*.db*\n\n# typescript\n*.tsbuildinfo\nnext-env.d.ts\n`],\n [\"backend/server/nitro/package.json.hbs\", `{\n\t\"name\": \"server\",\n\t\"type\": \"module\",\n\t\"scripts\": {\n\t\t\"dev\": \"nitro dev\",\n\t\t\"build\": \"nitro build\",\n\t\t\"start\": \"node .output/server/index.mjs\",\n\t\t\"check-types\": \"tsc --noEmit\"\n\t},\n\t\"dependencies\": {},\n\t\"devDependencies\": {}\n}\n`],\n [\"backend/server/nitro/nitro.config.ts.hbs\", `import { defineNitroConfig } from \"nitropack/config\";\n\nexport default defineNitroConfig({\n\t// Server configuration\n\tcompatibilityDate: \"2025-01-01\",\n{{#if (eq runtime \"node\")}}\n\tpreset: \"node-server\",\n{{/if}}\n{{#if (eq runtime \"bun\")}}\n\tpreset: \"bun\",\n{{/if}}\n{{#if (eq runtime \"workers\")}}\n\tpreset: \"cloudflare-module\",\n{{/if}}\n\t// Enable source maps for debugging\n\tsourcemap: true,\n\t// Route rules\n\trouteRules: {\n\t\t\"/**\": {\n\t\t\tcors: true,\n\t\t\theaders: {\n\t\t\t\t\"Access-Control-Allow-Origin\": \"*\",\n\t\t\t\t\"Access-Control-Allow-Methods\": \"GET, POST, PUT, DELETE, OPTIONS\",\n{{#if (eq auth \"better-auth\")}}\n\t\t\t\t\"Access-Control-Allow-Headers\": \"Content-Type, Authorization\",\n\t\t\t\t\"Access-Control-Allow-Credentials\": \"true\",\n{{else}}\n\t\t\t\t\"Access-Control-Allow-Headers\": \"Content-Type\",\n{{/if}}\n\t\t\t},\n\t\t},\n\t},\n});\n`],\n [\"backend/server/nitro/tsconfig.json.hbs\", `{\n\t\"compilerOptions\": {\n\t\t\"target\": \"ESNext\",\n\t\t\"module\": \"ESNext\",\n\t\t\"moduleResolution\": \"bundler\",\n\t\t\"strict\": true,\n\t\t\"skipLibCheck\": true,\n\t\t\"esModuleInterop\": true,\n\t\t\"resolveJsonModule\": true,\n\t\t\"isolatedModules\": true,\n\t\t\"noEmit\": true,\n\t\t\"types\": [\"nitropack\"]\n\t},\n\t\"include\": [\"**/*.ts\", \"nitro.config.ts\"],\n\t\"exclude\": [\"node_modules\", \".output\", \".nitro\"]\n}\n`],\n [\"backend/server/nitro/_gitignore\", `# Nitro output\n.output\n.nitro\n\n# Dependencies\nnode_modules\n\n# Environment\n.env\n.env.local\n.env.*.local\n\n# IDE\n.idea\n.vscode\n\n# OS\n.DS_Store\nThumbs.db\n`],\n [\"job-queue/trigger-dev/server/base/trigger.config.ts.hbs\", `import { defineConfig } from \"@trigger.dev/sdk/v3\";\n\n/**\n * Trigger.dev configuration\n * @see https://trigger.dev/docs/config/config-file\n */\nexport default defineConfig({\n // Your project ref from the Trigger.dev dashboard\n // Get this from: https://cloud.trigger.dev/\n project: process.env.TRIGGER_PROJECT_ID || \"<your-project-ref>\",\n\n // Directories containing your task definitions\n dirs: [\"./src/trigger\"],\n\n // Retry configuration for all tasks (can be overridden per task)\n retries: {\n // Enable retries during development\n enabledInDev: true,\n // Default retry settings\n default: {\n maxAttempts: 3,\n minTimeoutInMs: 1000,\n maxTimeoutInMs: 10000,\n factor: 2,\n randomize: true,\n },\n },\n\n // Maximum duration for tasks in seconds (can be overridden per task)\n maxDuration: 300, // 5 minutes\n\n // Runtime configuration\n runtime: \"node\",\n\n // Log level for debugging\n logLevel: \"info\",\n\n // Build configuration\n build: {\n // Automatically detect external packages\n autoDetectExternal: true,\n // Keep function names for better debugging\n keepNames: true,\n },\n\n // Global lifecycle hooks (optional)\n // onStart: async ({ payload, ctx }) => {\n // console.log(\"Task started:\", ctx.task.id);\n // },\n // onSuccess: async ({ payload, output, ctx }) => {\n // console.log(\"Task completed:\", ctx.task.id);\n // },\n // onFailure: async ({ payload, error, ctx }) => {\n // console.error(\"Task failed:\", ctx.task.id, error);\n // },\n});\n`],\n [\"auth/better-auth/server/base/package.json.hbs\", `{\n \"name\": \"@{{projectName}}/auth\",\n \"exports\": {\n \".\": {\n \"default\": \"./src/index.ts\"\n },\n \"./*\": {\n \"default\": \"./src/*.ts\"\n }\n },\n \"type\": \"module\",\n \"scripts\": {},\n \"devDependencies\": {}\n}`],\n [\"auth/better-auth/server/base/tsconfig.json.hbs\", `{\n \"extends\": \"@{{projectName}}/config/tsconfig.base.json\",\n \"compilerOptions\": {\n \"declaration\": true,\n \"declarationMap\": true,\n \"sourceMap\": true,\n \"outDir\": \"dist\",\n \"composite\": true\n }\n}`],\n [\"auth/better-auth/server/base/_gitignore\", `# dependencies (bun install)\nnode_modules\n\n# output\nout\ndist\n*.tgz\n\n# code coverage\ncoverage\n*.lcov\n\n# logs\nlogs\n_.log\nreport.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json\n\n# dotenv environment variable files\n.env\n.env.development.local\n.env.test.local\n.env.production.local\n.env.local\n\n# caches\n.eslintcache\n.cache\n*.tsbuildinfo\n\n# IntelliJ based IDEs\n.idea\n\n# Finder (MacOS) folder config\n.DS_Store\n`],\n [\"frontend/svelte/src/routes/+page.svelte.hbs\", `{{#if (eq backend \"convex\")}}\n<script lang=\"ts\">\nimport { useQuery } from 'convex-svelte';\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\n\nconst healthCheck = useQuery(api.healthCheck.get, {});\n\nconst TITLE_TEXT = \\`\n ██████╗ ███████╗████████╗████████╗███████╗██████╗\n ██╔══██╗██╔════╝╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗\n ██████╔╝█████╗ ██║ ██║ █████╗ ██████╔╝\n ██╔══██╗██╔══╝ ██║ ██║ ██╔══╝ ██╔══██╗\n ██████╔╝███████╗ ██║ ██║ ███████╗██║ ██║\n ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝\n\n ████████╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗\n ╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝\n ██║ ███████╗ ██║ ███████║██║ █████╔╝\n ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗\n ██║ ███████║ ██║ ██║ ██║╚██████╗██║ ██╗\n ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝\n \\`;\n</script>\n\n<div class=\"container mx-auto max-w-3xl px-4 py-2\">\n\t<pre class=\"overflow-x-auto font-mono text-sm\">{TITLE_TEXT}</pre>\n\t<div class=\"grid gap-6\">\n\t\t<section class=\"rounded-lg border p-4\">\n\t\t\t<h2 class=\"mb-2 font-medium\">API Status</h2>\n\t\t\t<div class=\"flex items-center gap-2\">\n\t\t\t\t<div\n\t\t\t\t\tclass={\\`h-2 w-2 rounded-full \\${healthCheck.data ? \"bg-green-500\" : \"bg-red-500\"}\\`}\n\t\t\t\t></div>\n\t\t\t\t<span class=\"text-muted-foreground text-sm\">\n\t\t\t\t\t{healthCheck.isLoading\n\t\t\t\t\t\t? \"Checking...\"\n\t\t\t\t\t\t: healthCheck.data\n\t\t\t\t\t\t\t? \"Connected\"\n\t\t\t\t\t\t\t: \"Disconnected\"}\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n</div>\n{{else}}\n<script lang=\"ts\">\n{{#if (eq api \"orpc\")}}\nimport { orpc } from \"$lib/orpc\";\nimport { createQuery } from \"@tanstack/svelte-query\";\nconst healthCheck = createQuery(orpc.healthCheck.queryOptions());\n{{/if}}\n\nconst TITLE_TEXT = \\`\n ██████╗ ███████╗████████╗████████╗███████╗██████╗\n ██╔══██╗██╔════╝╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗\n ██████╔╝█████╗ ██║ ██║ █████╗ ██████╔╝\n ██╔══██╗██╔══╝ ██║ ██║ ██╔══╝ ██╔══██╗\n ██████╔╝███████╗ ██║ ██║ ███████╗██║ ██║\n ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝\n\n ████████╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗\n ╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝\n ██║ ███████╗ ██║ ███████║██║ █████╔╝\n ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗\n ██║ ███████║ ██║ ██║ ██║╚██████╗██║ ██╗\n ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝\n \\`;\n</script>\n\n<div class=\"container mx-auto max-w-3xl px-4 py-2\">\n\t<pre class=\"overflow-x-auto font-mono text-sm\">{TITLE_TEXT}</pre>\n\t<div class=\"grid gap-6\">\n\t {{#if (eq api \"orpc\")}}\n\t\t<section class=\"rounded-lg border p-4\">\n\t\t\t<h2 class=\"mb-2 font-medium\">API Status</h2>\n\t\t\t<div class=\"flex items-center gap-2\">\n\t\t\t\t<div\n\t\t\t\t\tclass={\\`h-2 w-2 rounded-full \\${$healthCheck.data ? \"bg-green-500\" : \"bg-red-500\"}\\`}\n\t\t\t\t></div>\n\t\t\t\t<span class=\"text-muted-foreground text-sm\">\n\t\t\t\t\t{$healthCheck.isLoading\n\t\t\t\t\t\t? \"Checking...\"\n\t\t\t\t\t\t: $healthCheck.data\n\t\t\t\t\t\t\t? \"Connected\"\n\t\t\t\t\t\t\t: \"Disconnected\"}\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t</section>\n\t {{/if}}\n\t</div>\n</div>\n{{/if}}\n`],\n [\"frontend/svelte/src/routes/+layout.svelte.hbs\", `{{#if (eq backend \"convex\")}}\n<script lang=\"ts\">\n\timport '../app.css';\n import Header from '../components/Header.svelte';\n import { PUBLIC_CONVEX_URL } from '$env/static/public';\n\timport { setupConvex } from 'convex-svelte';\n\n\tconst { children } = $props();\n\tsetupConvex(PUBLIC_CONVEX_URL);\n</script>\n\n<div class=\"grid h-svh grid-rows-[auto_1fr]\">\n\t<Header />\n\t<main class=\"overflow-y-auto\">\n\t\t{@render children()}\n\t</main>\n</div>\n{{else}}\n {{#if (eq api \"orpc\")}}\n<script lang=\"ts\">\n import { QueryClientProvider } from '@tanstack/svelte-query';\n import { SvelteQueryDevtools } from '@tanstack/svelte-query-devtools'\n\timport '../app.css';\n import { queryClient } from '$lib/orpc';\n import Header from '../components/Header.svelte';\n\n\tconst { children } = $props();\n</script>\n\n<QueryClientProvider client={queryClient}>\n <div class=\"grid h-svh grid-rows-[auto_1fr]\">\n\t\t<Header />\n\t\t<main class=\"overflow-y-auto\">\n\t\t\t{@render children()}\n\t\t</main>\n </div>\n <SvelteQueryDevtools />\n</QueryClientProvider>\n {{else}}\n<script lang=\"ts\">\n\timport '../app.css';\n import Header from '../components/Header.svelte';\n\n\tconst { children } = $props();\n</script>\n\n<div class=\"grid h-svh grid-rows-[auto_1fr]\">\n\t<Header />\n\t<main class=\"overflow-y-auto\">\n\t\t{@render children()}\n\t</main>\n</div>\n {{/if}}\n{{/if}}\n`],\n [\"frontend/svelte/src/components/Header.svelte.hbs\", `<script lang=\"ts\">\n\n {{#if (eq auth \"better-auth\")}}\n\timport UserMenu from './UserMenu.svelte';\n {{/if}}\n const links = [\n { to: \"/\", label: \"Home\" },\n {{#if (eq auth \"better-auth\")}}\n { to: \"/dashboard\", label: \"Dashboard\" },\n {{/if}}\n {{#if (includes examples \"todo\")}}\n { to: \"/todos\", label: \"Todos\" },\n {{/if}}\n {{#if (includes examples \"ai\")}}\n { to: \"/ai\", label: \"AI Chat\" },\n {{/if}}\n ];\n\n</script>\n\n<div>\n\t<div class=\"flex flex-row items-center justify-between px-4 py-2 md:px-6\">\n\t\t<nav class=\"flex gap-4 text-lg\">\n\t\t\t{#each links as link (link.to)}\n\t\t\t\t<a\n\t\t\t\t\thref={link.to}\n\t\t\t\t\tclass=\"hover:text-neutral-400 transition-colors\"\n\t\t\t\t>\n\t\t\t\t\t{link.label}\n\t\t\t\t</a>\n\t\t\t{/each}\n\t\t</nav>\n\t\t<div class=\"flex items-center gap-2\">\n\t\t {{#if (eq auth \"better-auth\")}}\n <UserMenu />\n {{/if}}\n\t\t</div>\n\t</div>\n\t<hr class=\"border-neutral-800\" />\n</div>\n`],\n [\"frontend/svelte/src/lib/index.ts\", `// place files you want to import through the \\`$lib\\` alias in this folder.\nexport {};\n`],\n [\"frontend/react/web-base/src/index.css.hbs\", `{{#if (eq cssFramework \"tailwind\")}}\n@import 'tailwindcss';\n@import 'tw-animate-css';\n{{#if (eq uiLibrary \"shadcn-ui\")}}\n@import 'shadcn/tailwind.css';\n{{/if}}\n{{#if (includes examples \"ai\")}}\n@source \"../node_modules/streamdown/dist/*.js\";\n{{/if}}\n\n@custom-variant dark (&:is(.dark *));\n\n{{#if (eq uiLibrary \"shadcn-ui\")}}\n:root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.145 0 0);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.145 0 0);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.145 0 0);\n --primary: oklch(0.205 0 0);\n --primary-foreground: oklch(0.985 0 0);\n --secondary: oklch(0.97 0 0);\n --secondary-foreground: oklch(0.205 0 0);\n --muted: oklch(0.97 0 0);\n --muted-foreground: oklch(0.556 0 0);\n --accent: oklch(0.97 0 0);\n --accent-foreground: oklch(0.205 0 0);\n --destructive: oklch(0.58 0.22 27);\n --border: oklch(0.922 0 0);\n --input: oklch(0.922 0 0);\n --ring: oklch(0.708 0 0);\n --chart-1: oklch(0.809 0.105 251.813);\n --chart-2: oklch(0.623 0.214 259.815);\n --chart-3: oklch(0.546 0.245 262.881);\n --chart-4: oklch(0.488 0.243 264.376);\n --chart-5: oklch(0.424 0.199 265.638);\n --radius: 0.625rem;\n --sidebar: oklch(0.985 0 0);\n --sidebar-foreground: oklch(0.145 0 0);\n --sidebar-primary: oklch(0.205 0 0);\n --sidebar-primary-foreground: oklch(0.985 0 0);\n --sidebar-accent: oklch(0.97 0 0);\n --sidebar-accent-foreground: oklch(0.205 0 0);\n --sidebar-border: oklch(0.922 0 0);\n --sidebar-ring: oklch(0.708 0 0);\n}\n\n.dark {\n --background: oklch(0.145 0 0);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.205 0 0);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.205 0 0);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.87 0 0);\n --primary-foreground: oklch(0.205 0 0);\n --secondary: oklch(0.269 0 0);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.269 0 0);\n --muted-foreground: oklch(0.708 0 0);\n --accent: oklch(0.371 0 0);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --border: oklch(1 0 0 / 10%);\n --input: oklch(1 0 0 / 15%);\n --ring: oklch(0.556 0 0);\n --chart-1: oklch(0.809 0.105 251.813);\n --chart-2: oklch(0.623 0.214 259.815);\n --chart-3: oklch(0.546 0.245 262.881);\n --chart-4: oklch(0.488 0.243 264.376);\n --chart-5: oklch(0.424 0.199 265.638);\n --sidebar: oklch(0.205 0 0);\n --sidebar-foreground: oklch(0.985 0 0);\n --sidebar-primary: oklch(0.488 0.243 264.376);\n --sidebar-primary-foreground: oklch(0.985 0 0);\n --sidebar-accent: oklch(0.269 0 0);\n --sidebar-accent-foreground: oklch(0.985 0 0);\n --sidebar-border: oklch(1 0 0 / 10%);\n --sidebar-ring: oklch(0.556 0 0);\n}\n\n@theme inline {\n --font-sans: 'Inter Variable', sans-serif;\n --color-sidebar-ring: var(--sidebar-ring);\n --color-sidebar-border: var(--sidebar-border);\n --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);\n --color-sidebar-accent: var(--sidebar-accent);\n --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);\n --color-sidebar-primary: var(--sidebar-primary);\n --color-sidebar-foreground: var(--sidebar-foreground);\n --color-sidebar: var(--sidebar);\n --color-chart-5: var(--chart-5);\n --color-chart-4: var(--chart-4);\n --color-chart-3: var(--chart-3);\n --color-chart-2: var(--chart-2);\n --color-chart-1: var(--chart-1);\n --color-ring: var(--ring);\n --color-input: var(--input);\n --color-border: var(--border);\n --color-destructive: var(--destructive);\n --color-accent-foreground: var(--accent-foreground);\n --color-accent: var(--accent);\n --color-muted-foreground: var(--muted-foreground);\n --color-muted: var(--muted);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-secondary: var(--secondary);\n --color-primary-foreground: var(--primary-foreground);\n --color-primary: var(--primary);\n --color-popover-foreground: var(--popover-foreground);\n --color-popover: var(--popover);\n --color-card-foreground: var(--card-foreground);\n --color-card: var(--card);\n --color-foreground: var(--foreground);\n --color-background: var(--background);\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n --radius-2xl: calc(var(--radius) + 8px);\n --radius-3xl: calc(var(--radius) + 12px);\n --radius-4xl: calc(var(--radius) + 16px);\n}\n\n@layer base {\n * {\n @apply border-border outline-ring/50;\n }\n body {\n @apply font-sans bg-background text-foreground;\n }\n html {\n @apply font-sans;\n }\n}\n{{else}}\n/* Basic Tailwind setup without shadcn-ui theme */\n@layer base {\n body {\n font-family: 'Inter Variable', system-ui, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n}\n{{/if}}\n{{else}}\n/* Non-Tailwind CSS framework styles */\n:root {\n --color-background: #ffffff;\n --color-foreground: #1a1a1a;\n --color-primary: #3b82f6;\n --color-secondary: #64748b;\n}\n\n.dark {\n --color-background: #1a1a1a;\n --color-foreground: #fafafa;\n --color-primary: #60a5fa;\n --color-secondary: #94a3b8;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: 'Inter Variable', system-ui, sans-serif;\n background-color: var(--color-background);\n color: var(--color-foreground);\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n{{/if}}\n`],\n [\"frontend/react/tanstack-start/public/robots.txt\", `# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n`],\n [\"frontend/qwik/src/components/header.tsx.hbs\", `import { component$ } from \"@builder.io/qwik\";\nimport { Link } from \"@builder.io/qwik-city\";\n\nexport default component$(() => {\n const links = [\n { href: \"/\", label: \"Home\" },\n {{#if (eq auth \"better-auth\")}}\n { href: \"/dashboard\", label: \"Dashboard\" },\n {{/if}}\n {{#if (includes examples \"todo\")}}\n { href: \"/todos\", label: \"Todos\" },\n {{/if}}\n {{#if (includes examples \"ai\")}}\n { href: \"/ai\", label: \"AI Chat\" },\n {{/if}}\n ];\n\n return (\n <header>\n {{#if (eq cssFramework \"tailwind\")}}\n <div class=\"flex flex-row items-center justify-between px-4 py-2\">\n <nav class=\"flex gap-4 text-lg\">\n {links.map((link) => (\n <Link key={link.href} href={link.href} class=\"hover:underline\">\n {link.label}\n </Link>\n ))}\n </nav>\n <div class=\"flex items-center gap-2\">\n {{#if (eq auth \"better-auth\")}}\n {/* User menu component would go here */}\n {{/if}}\n </div>\n </div>\n <hr class=\"border-gray-200 dark:border-gray-800\" />\n {{else}}\n <div style=\\\\{{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\", padding: \"0.5rem 1rem\" }}>\n <nav style=\\\\{{ display: \"flex\", gap: \"1rem\", fontSize: \"1.125rem\" }}>\n {links.map((link) => (\n <Link key={link.href} href={link.href}>\n {link.label}\n </Link>\n ))}\n </nav>\n <div style=\\\\{{ display: \"flex\", alignItems: \"center\", gap: \"0.5rem\" }}>\n {{#if (eq auth \"better-auth\")}}\n {/* User menu component would go here */}\n {{/if}}\n </div>\n </div>\n <hr style=\\\\{{ borderColor: \"var(--border-color)\" }} />\n {{/if}}\n </header>\n );\n});\n`],\n [\"frontend/qwik/src/routes/index.tsx.hbs\", `import { component$ } from \"@builder.io/qwik\";\nimport type { DocumentHead } from \"@builder.io/qwik-city\";\n\nconst TITLE_TEXT = \\`\n ██████╗ ███████╗████████╗████████╗███████╗██████╗\n ██╔══██╗██╔════╝╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗\n ██████╔╝█████╗ ██║ ██║ █████╗ ██████╔╝\n ██╔══██╗██╔══╝ ██║ ██║ ██╔══╝ ██╔══██╗\n ██████╔╝███████╗ ██║ ██║ ███████╗██║ ██║\n ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝\n\n ████████╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗\n ╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝\n ██║ ███████╗ ██║ ███████║██║ █████╔╝\n ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗\n ██║ ███████║ ██║ ██║ ██║╚██████╗██║ ██╗\n ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝\n\\`;\n\nexport default component$(() => {\n return (\n {{#if (eq cssFramework \"tailwind\")}}\n <div class=\"container mx-auto max-w-3xl px-4 py-2\">\n <pre class=\"overflow-x-auto font-mono text-sm whitespace-pre\">{TITLE_TEXT}</pre>\n <div class=\"grid gap-6 mt-6\">\n <section class=\"rounded-lg border border-gray-200 dark:border-gray-800 p-4\">\n <h2 class=\"mb-2 font-medium\">Welcome to Qwik</h2>\n <p class=\"text-sm text-gray-600 dark:text-gray-400\">\n Qwik is a resumable framework that delivers instant apps at scale.\n It achieves this by serializing the application state and resuming\n execution on the client without re-running the entire application.\n </p>\n </section>\n <section class=\"rounded-lg border border-gray-200 dark:border-gray-800 p-4\">\n <h2 class=\"mb-2 font-medium\">Key Features</h2>\n <ul class=\"list-disc list-inside text-sm text-gray-600 dark:text-gray-400 space-y-1\">\n <li>Resumability - No hydration overhead</li>\n <li>Lazy loading by default</li>\n <li>Familiar JSX syntax</li>\n <li>Built-in optimizations</li>\n </ul>\n </section>\n </div>\n </div>\n {{else}}\n <div style=\\\\{{ maxWidth: \"48rem\", margin: \"0 auto\", padding: \"0.5rem 1rem\" }}>\n <pre style=\\\\{{ overflow: \"auto\", fontFamily: \"monospace\", fontSize: \"0.875rem\", whiteSpace: \"pre\" }}>{TITLE_TEXT}</pre>\n <div style=\\\\{{ display: \"grid\", gap: \"1.5rem\", marginTop: \"1.5rem\" }}>\n <section style=\\\\{{ borderRadius: \"0.5rem\", border: \"1px solid var(--border-color)\", padding: \"1rem\" }}>\n <h2 style=\\\\{{ marginBottom: \"0.5rem\", fontWeight: 500 }}>Welcome to Qwik</h2>\n <p style=\\\\{{ fontSize: \"0.875rem\", color: \"var(--muted-color)\" }}>\n Qwik is a resumable framework that delivers instant apps at scale.\n It achieves this by serializing the application state and resuming\n execution on the client without re-running the entire application.\n </p>\n </section>\n <section style=\\\\{{ borderRadius: \"0.5rem\", border: \"1px solid var(--border-color)\", padding: \"1rem\" }}>\n <h2 style=\\\\{{ marginBottom: \"0.5rem\", fontWeight: 500 }}>Key Features</h2>\n <ul style=\\\\{{ fontSize: \"0.875rem\", color: \"var(--muted-color)\", listStyleType: \"disc\", paddingLeft: \"1.5rem\" }}>\n <li>Resumability - No hydration overhead</li>\n <li>Lazy loading by default</li>\n <li>Familiar JSX syntax</li>\n <li>Built-in optimizations</li>\n </ul>\n </section>\n </div>\n </div>\n {{/if}}\n );\n});\n\nexport const head: DocumentHead = {\n title: \"Better T Stack - Qwik\",\n meta: [\n {\n name: \"description\",\n content: \"Better T Stack with Qwik - Resumable framework with instant load times\",\n },\n ],\n};\n`],\n [\"frontend/qwik/src/routes/layout.tsx.hbs\", `import { component$, Slot } from \"@builder.io/qwik\";\nimport type { RequestHandler } from \"@builder.io/qwik-city\";\nimport Header from \"@/components/header\";\n\nexport const onGet: RequestHandler = async ({ cacheControl }) => {\n cacheControl({\n staleWhileRevalidate: 60 * 60 * 24 * 7,\n maxAge: 5,\n });\n};\n\nexport default component$(() => {\n return (\n {{#if (eq cssFramework \"tailwind\")}}\n <div class=\"grid grid-rows-[auto_1fr] min-h-screen\">\n <Header />\n <main>\n <Slot />\n </main>\n </div>\n {{else}}\n <div style=\\\\{{ display: \"grid\", gridTemplateRows: \"auto 1fr\", minHeight: \"100vh\" }}>\n <Header />\n <main>\n <Slot />\n </main>\n </div>\n {{/if}}\n );\n});\n`],\n [\"frontend/react/tanstack-start/src/router.tsx.hbs\", `{{#if (eq backend \"convex\")}}\nimport { createRouter as createTanStackRouter } from \"@tanstack/react-router\";\nimport { QueryClient } from \"@tanstack/react-query\";\nimport { setupRouterSsrQueryIntegration } from \"@tanstack/react-router-ssr-query\";\nimport { ConvexQueryClient } from \"@convex-dev/react-query\";\nimport { routeTree } from \"./routeTree.gen\";\nimport Loader from \"./components/loader\";\nimport \"./index.css\";\nimport { env } from \"@{{projectName}}/env/web\";\n{{else}}\nimport { createRouter as createTanStackRouter } from \"@tanstack/react-router\";\nimport Loader from \"./components/loader\";\nimport \"./index.css\";\nimport { routeTree } from \"./routeTree.gen\";\n{{#if (eq api \"trpc\")}}\nimport { QueryCache, QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { createTRPCClient, httpBatchLink } from \"@trpc/client\";\nimport { createTRPCOptionsProxy } from \"@trpc/tanstack-react-query\";\nimport { toast } from \"sonner\";\nimport type { AppRouter } from \"@{{projectName}}/api/routers/index\";\nimport { TRPCProvider } from \"./utils/trpc\";\n{{#unless (eq backend \"self\")}}\nimport { env } from \"@{{projectName}}/env/web\";\n{{/unless}}\n{{else if (eq api \"orpc\")}}\nimport { QueryClientProvider } from \"@tanstack/react-query\";\nimport { orpc, queryClient } from \"./utils/orpc\";\n{{/if}}\n{{/if}}\n\n{{#if (eq backend \"convex\")}}\nexport function getRouter() {\n\tconst convexUrl = env.VITE_CONVEX_URL;\n\tif (!convexUrl) {\n\t\tthrow new Error(\"VITE_CONVEX_URL is not set\");\n\t}\n\n\tconst convexQueryClient = new ConvexQueryClient(convexUrl);\n\n\tconst queryClient: QueryClient = new QueryClient({\n\t\tdefaultOptions: {\n\t\t\tqueries: {\n\t\t\t\tqueryKeyHashFn: convexQueryClient.hashFn(),\n\t\t\t\tqueryFn: convexQueryClient.queryFn(),\n\t\t\t},\n\t\t},\n\t});\n\tconvexQueryClient.connect(queryClient);\n\n\tconst router = createTanStackRouter({\n\t\trouteTree,\n\t\tdefaultPreload: \"intent\",\n\t\tdefaultPendingComponent: () => <Loader />,\n\t\tdefaultNotFoundComponent: () => <div>Not Found</div>,\n\t\tcontext: { queryClient, convexQueryClient },\n\t});\n\n\tsetupRouterSsrQueryIntegration({\n\t\trouter,\n\t\tqueryClient,\n\t});\n\n\treturn router;\n}\n{{else}}\n{{#if (eq api \"trpc\")}}\nexport const queryClient = new QueryClient({\n\tqueryCache: new QueryCache({\n\t\tonError: (error, query) => {\n\t\t\ttoast.error(error.message, {\n\t\t\t\taction: {\n\t\t\t\t\tlabel: \"retry\",\n\t\t\t\t\tonClick: query.invalidate,\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t}),\n\tdefaultOptions: { queries: { staleTime: 60 * 1000 } },\n});\n\nconst trpcClient = createTRPCClient<AppRouter>({\n\tlinks: [\n\t\thttpBatchLink({\n\t\t\turl: {{#if (eq backend \"self\")}}\"/api/trpc\"{{else}}\\`\\${env.VITE_SERVER_URL}/trpc\\`{{/if}},\n{{#if (eq auth \"better-auth\")}}\n\t\t\tfetch(url, options) {\n\t\t\t\treturn fetch(url, {\n\t\t\t\t\t...options,\n\t\t\t\t\tcredentials: \"include\",\n\t\t\t\t});\n\t\t\t},\n{{/if}}\n\t\t}),\n\t],\n});\n\nconst trpc = createTRPCOptionsProxy({\n\tclient: trpcClient,\n\tqueryClient: queryClient,\n});\n{{else if (eq api \"orpc\")}}\n{{/if}}\n\nexport const getRouter = () => {\n\tconst router = createTanStackRouter({\n\t\trouteTree,\n\t\tscrollRestoration: true,\n\t\tdefaultPreloadStaleTime: 0,\n{{#if (eq api \"trpc\")}}\n\t\tcontext: { trpc, queryClient },\n{{else if (eq api \"orpc\")}}\n\t\tcontext: { orpc, queryClient },\n{{else}}\n\t\tcontext: {},\n{{/if}}\n\t\tdefaultPendingComponent: () => <Loader />,\n\t\tdefaultNotFoundComponent: () => <div>Not Found</div>,\n{{#if (eq api \"trpc\")}}\n\t\tWrap: ({ children }) => (\n\t\t\t<QueryClientProvider client={queryClient}>\n\t\t\t\t<TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>\n\t\t\t\t\t{children}\n\t\t\t\t</TRPCProvider>\n\t\t\t</QueryClientProvider>\n\t\t),\n{{else if (eq api \"orpc\")}}\n\t\tWrap: ({ children }) => (\n\t\t\t<QueryClientProvider client={queryClient}>\n\t\t\t\t{children}\n\t\t\t</QueryClientProvider>\n\t\t),\n{{else}}\n\t\tWrap: ({ children }) => <>{children}</>,\n{{/if}}\n\t});\n\treturn router;\n};\n{{/if}}\n\ndeclare module \"@tanstack/react-router\" {\n\tinterface Register {\n\t\trouter: ReturnType<typeof getRouter>;\n\t}\n}\n`],\n [\"frontend/react/tanstack-router/src/main.tsx.hbs\", `import { RouterProvider, createRouter } from \"@tanstack/react-router\";\nimport ReactDOM from \"react-dom/client\";\nimport Loader from \"./components/loader\";\nimport { routeTree } from \"./routeTree.gen\";\n\n{{#if (eq api \"orpc\")}}\n import { QueryClientProvider } from \"@tanstack/react-query\";\n import { orpc, queryClient } from \"./utils/orpc\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\n import { QueryClientProvider } from \"@tanstack/react-query\";\n import { queryClient, trpc } from \"./utils/trpc\";\n{{/if}}\n{{#if (eq backend \"convex\")}}\n import { ConvexReactClient } from \"convex/react\";\n import { env } from \"@{{projectName}}/env/web\";\n {{#if (eq auth \"clerk\")}}\n import { ClerkProvider, useAuth } from \"@clerk/clerk-react\";\n import { ConvexProviderWithClerk } from \"convex/react-clerk\";\n {{else if (eq auth \"better-auth\")}}\n import { ConvexBetterAuthProvider } from \"@convex-dev/better-auth/react\";\n import { authClient } from \"@/lib/auth-client\";\n {{else}}\n import { ConvexProvider } from \"convex/react\";\n {{/if}}\n const convex = new ConvexReactClient(env.VITE_CONVEX_URL);\n{{/if}}\n\nconst router = createRouter({\n routeTree,\n defaultPreload: \"intent\",\n defaultPendingComponent: () => <Loader />,\n {{#if (eq api \"orpc\")}}\n context: { orpc, queryClient },\n Wrap: function WrapComponent({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n {children}\n </QueryClientProvider>\n );\n },\n {{else if (eq api \"trpc\")}}\n context: { trpc, queryClient },\n Wrap: function WrapComponent({ children }: { children: React.ReactNode }) {\n return (\n <QueryClientProvider client={queryClient}>\n {children}\n </QueryClientProvider>\n );\n },\n {{else if (eq backend \"convex\")}}\n context: {},\n Wrap: function WrapComponent({ children }: { children: React.ReactNode }) {\n {{#if (eq auth \"clerk\")}}\n return (\n <ClerkProvider\n publishableKey={env.VITE_CLERK_PUBLISHABLE_KEY}\n >\n <ConvexProviderWithClerk client={convex} useAuth={useAuth}>\n {children}\n </ConvexProviderWithClerk>\n </ClerkProvider>\n );\n {{else if (eq auth \"better-auth\")}}\n return <ConvexBetterAuthProvider client={convex} authClient={authClient}>{children}</ConvexBetterAuthProvider>;\n {{else}}\n return <ConvexProvider client={convex}>{children}</ConvexProvider>;\n {{/if}}\n },\n {{else}}\n context: {},\n {{/if}}\n});\n\ndeclare module \"@tanstack/react-router\" {\n interface Register {\n router: typeof router;\n }\n}\n\nconst rootElement = document.getElementById(\"app\");\n\nif (!rootElement) {\n throw new Error(\"Root element not found\");\n}\n\nif (!rootElement.innerHTML) {\n const root = ReactDOM.createRoot(rootElement);\n root.render(<RouterProvider router={router} />);\n}\n`],\n [\"frontend/angular/src/app/app.routes.ts\", `import { Routes } from \"@angular/router\";\n\nimport { HomeComponent } from \"./pages/home/home.component\";\n\nexport const routes: Routes = [{ path: \"\", component: HomeComponent }];\n`],\n [\"frontend/angular/src/app/app.config.ts\", `import { ApplicationConfig, provideZoneChangeDetection } from \"@angular/core\";\nimport { provideRouter } from \"@angular/router\";\n\nimport { routes } from \"./app.routes\";\n\nexport const appConfig: ApplicationConfig = {\n providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes)],\n};\n`],\n [\"frontend/angular/src/app/app.component.ts.hbs\", `import { Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport { HeaderComponent } from './components/header.component';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [RouterOutlet, HeaderComponent],\n template: \\`\n {{#if (eq cssFramework \"tailwind\")}}\n <div class=\"grid grid-rows-[auto_1fr] min-h-screen\">\n <app-header />\n <main>\n <router-outlet />\n </main>\n </div>\n {{else}}\n <div [style.display]=\"'grid'\" [style.gridTemplateRows]=\"'auto 1fr'\" [style.minHeight]=\"'100vh'\">\n <app-header />\n <main>\n <router-outlet />\n </main>\n </div>\n {{/if}}\n \\`,\n})\nexport class AppComponent {\n title = 'Better T Stack';\n}\n`],\n [\"frontend/react/react-router/public/favicon.ico\", `[Binary file]`],\n [\"frontend/react/react-router/src/routes.ts\", `import { type RouteConfig } from \"@react-router/dev/routes\";\nimport { flatRoutes } from \"@react-router/fs-routes\";\n\nexport default flatRoutes() satisfies RouteConfig;\n`],\n [\"frontend/react/react-router/src/root.tsx.hbs\", `import {\n isRouteErrorResponse,\n Links,\n Meta,\n Outlet,\n Scripts,\n ScrollRestoration,\n} from \"react-router\";\nimport type { Route } from \"./+types/root\";\nimport \"./index.css\";\nimport Header from \"./components/header\";\nimport { ThemeProvider } from \"./components/theme-provider\";\nimport { Toaster } from \"./components/ui/sonner\";\n\n{{#if (eq backend \"convex\")}}\nimport { ConvexReactClient } from \"convex/react\";\nimport { env } from \"@{{projectName}}/env/web\";\n{{#if (eq auth \"clerk\")}}\nimport { ClerkProvider, useAuth } from \"@clerk/clerk-react\";\nimport { ConvexProviderWithClerk } from \"convex/react-clerk\";\n{{else}}\nimport { ConvexProvider } from \"convex/react\";\n{{/if}}\n{{else}}\n {{#unless (eq api \"none\")}}\nimport { QueryClientProvider } from \"@tanstack/react-query\";\nimport { ReactQueryDevtools } from \"@tanstack/react-query-devtools\";\n {{#if (eq api \"orpc\")}}\nimport { queryClient } from \"./utils/orpc\";\n {{/if}}\n {{#if (eq api \"trpc\")}}\nimport { queryClient } from \"./utils/trpc\";\n {{/if}}\n {{/unless}}\n{{/if}}\n\nexport const links: Route.LinksFunction = () => [\n { rel: \"preconnect\", href: \"https://fonts.googleapis.com\" },\n { rel: \"preconnect\", href: \"https://fonts.gstatic.com\", crossOrigin: \"anonymous\" },\n {\n rel: \"stylesheet\",\n href:\n \"https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap\",\n },\n];\n\nexport function Layout({ children }: { children: React.ReactNode }) {\n return (\n <html lang=\"en\">\n <head>\n <meta charSet=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <Meta />\n <Links />\n </head>\n <body>\n {children}\n <ScrollRestoration />\n <Scripts />\n </body>\n </html>\n );\n}\n\n{{#if (eq backend \"convex\")}}\nexport default function App() {\n const convex = new ConvexReactClient(env.VITE_CONVEX_URL);\n {{#if (eq auth \"clerk\")}}\n return (\n <ClerkProvider publishableKey={env.VITE_CLERK_PUBLISHABLE_KEY}>\n <ConvexProviderWithClerk client={convex} useAuth={useAuth}>\n <ThemeProvider\n attribute=\"class\"\n defaultTheme=\"dark\"\n disableTransitionOnChange\n storageKey=\"vite-ui-theme\"\n >\n <div className=\"grid grid-rows-[auto_1fr] h-svh\">\n <Header />\n <Outlet />\n </div>\n <Toaster richColors />\n </ThemeProvider>\n </ConvexProviderWithClerk>\n </ClerkProvider>\n );\n {{else}}\n return (\n <ConvexProvider client={convex}>\n <ThemeProvider\n attribute=\"class\"\n defaultTheme=\"dark\"\n disableTransitionOnChange\n storageKey=\"vite-ui-theme\"\n >\n <div className=\"grid grid-rows-[auto_1fr] h-svh\">\n <Header />\n <Outlet />\n </div>\n <Toaster richColors />\n </ThemeProvider>\n </ConvexProvider>\n );\n {{/if}}\n}\n{{else if (eq api \"orpc\")}}\nexport default function App() {\n return (\n <QueryClientProvider client={queryClient}>\n <ThemeProvider\n attribute=\"class\"\n defaultTheme=\"dark\"\n disableTransitionOnChange\n storageKey=\"vite-ui-theme\"\n >\n <div className=\"grid grid-rows-[auto_1fr] h-svh\">\n <Header />\n <Outlet />\n </div>\n <Toaster richColors />\n </ThemeProvider>\n <ReactQueryDevtools position=\"bottom\" buttonPosition=\"bottom-right\" />\n </QueryClientProvider>\n );\n}\n{{else if (eq api \"trpc\")}}\nexport default function App() {\n return (\n <QueryClientProvider client={queryClient}>\n <ThemeProvider\n attribute=\"class\"\n defaultTheme=\"dark\"\n disableTransitionOnChange\n storageKey=\"vite-ui-theme\"\n >\n <div className=\"grid grid-rows-[auto_1fr] h-svh\">\n <Header />\n <Outlet />\n </div>\n <Toaster richColors />\n </ThemeProvider>\n <ReactQueryDevtools position=\"bottom\" buttonPosition=\"bottom-right\" />\n </QueryClientProvider>\n );\n}\n{{else}}\nexport default function App() {\n return (\n <ThemeProvider\n attribute=\"class\"\n defaultTheme=\"dark\"\n disableTransitionOnChange\n storageKey=\"vite-ui-theme\"\n >\n <div className=\"grid grid-rows-[auto_1fr] h-svh\">\n <Header />\n <Outlet />\n </div>\n <Toaster richColors />\n </ThemeProvider>\n );\n}\n{{/if}}\n\nexport function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {\n let message = \"Oops!\";\n let details = \"An unexpected error occurred.\";\n let stack: string | undefined;\n if (isRouteErrorResponse(error)) {\n message = error.status === 404 ? \"404\" : \"Error\";\n details =\n error.status === 404\n ? \"The requested page could not be found.\"\n : error.statusText || details;\n } else if (import.meta.env.DEV && error && error instanceof Error) {\n details = error.message;\n stack = error.stack;\n }\n return (\n <main className=\"pt-16 p-4 container mx-auto\">\n <h1>{message}</h1>\n <p>{details}</p>\n {stack && (\n <pre className=\"w-full p-4 overflow-x-auto\">\n <code>{stack}</code>\n </pre>\n )}\n </main>\n );\n}\n`],\n [\"frontend/redwood/web/public/robots.txt\", `User-agent: *\nDisallow:\n`],\n [\"frontend/redwood/web/public/favicon.svg\", `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\">\n <rect width=\"100\" height=\"100\" rx=\"10\" fill=\"#bf4722\"/>\n <path d=\"M25 75V25h15l10 25 10-25h15v50h-12V45l-8 20h-10l-8-20v30H25z\" fill=\"white\"/>\n</svg>\n`],\n [\"frontend/redwood/api/db/schema.prisma\", `// Don't forget to tell Prisma about your database:\n// https://www.prisma.io/docs/reference/database-reference/connection-urls\n\ndatasource db {\n provider = \"sqlite\"\n url = env(\"DATABASE_URL\")\n}\n\ngenerator client {\n provider = \"prisma-client-js\"\n binaryTargets = \"native\"\n}\n\n// Define your own datamodels here and run \\`yarn rw prisma migrate dev\\`\n// to create migrations for them and apply to your dev DB.\n\nmodel Post {\n id Int @id @default(autoincrement())\n title String\n body String\n createdAt DateTime @default(now())\n}\n`],\n [\"frontend/fresh/src/routes/_layout.tsx.hbs\", `import type { PageProps } from \"$fresh/server.ts\";\nimport Header from \"../components/Header.tsx\";\n\nexport default function Layout({ Component, state }: PageProps) {\n return (\n <html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>{state.title ?? \"{{projectName}}\"}</title>\n <link rel=\"stylesheet\" href=\"/styles.css\" />\n </head>\n <body{{#if (eq cssFramework \"tailwind\")}} class=\"bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900 min-h-screen\"{{/if}}>\n <Header />\n <Component />\n </body>\n </html>\n );\n}\n`],\n [\"frontend/fresh/src/routes/index.tsx.hbs\", `import { define } from \"../../utils.ts\";\nimport Counter from \"../islands/Counter.tsx\";\n\nexport const handler = define.handlers({\n GET(ctx) {\n ctx.state.title = \"Home | {{projectName}}\";\n return ctx.render();\n },\n});\n\nexport default define.page(function Home() {\n return (\n <main{{#if (eq cssFramework \"tailwind\")}} class=\"container mx-auto px-4 py-16\"{{/if}}>\n <div{{#if (eq cssFramework \"tailwind\")}} class=\"flex flex-col items-center justify-center text-center\"{{/if}}>\n <h1{{#if (eq cssFramework \"tailwind\")}} class=\"text-5xl font-bold text-white mb-6\"{{/if}}>\n Welcome to <span{{#if (eq cssFramework \"tailwind\")}} class=\"text-transparent bg-clip-text bg-gradient-to-r from-cyan-400 to-purple-500\"{{/if}}>Fresh</span>\n </h1>\n <p{{#if (eq cssFramework \"tailwind\")}} class=\"text-xl text-gray-300 mb-8 max-w-2xl\"{{/if}}>\n A Deno-native full-stack web framework with islands architecture for optimal performance.\n </p>\n\n <div{{#if (eq cssFramework \"tailwind\")}} class=\"bg-white/10 backdrop-blur-lg rounded-2xl p-8 border border-white/20\"{{/if}}>\n <h2{{#if (eq cssFramework \"tailwind\")}} class=\"text-2xl font-semibold text-white mb-4\"{{/if}}>Interactive Island</h2>\n <Counter start={0} />\n </div>\n\n <div{{#if (eq cssFramework \"tailwind\")}} class=\"mt-12 grid grid-cols-1 md:grid-cols-3 gap-6\"{{/if}}>\n <FeatureCard\n title=\"Islands Architecture\"\n description=\"Ship zero JavaScript by default, hydrate only interactive components.\"\n />\n <FeatureCard\n title=\"Deno Native\"\n description=\"Built for Deno with first-class TypeScript support and modern APIs.\"\n />\n <FeatureCard\n title=\"Fast by Default\"\n description=\"No build step for development, instant page loads with streaming.\"\n />\n </div>\n </div>\n </main>\n );\n});\n\nfunction FeatureCard({ title, description }: { title: string; description: string }) {\n return (\n <div{{#if (eq cssFramework \"tailwind\")}} class=\"bg-white/5 backdrop-blur rounded-xl p-6 border border-white/10 hover:border-cyan-500/50 transition-colors\"{{/if}}>\n <h3{{#if (eq cssFramework \"tailwind\")}} class=\"text-lg font-semibold text-white mb-2\"{{/if}}>{title}</h3>\n <p{{#if (eq cssFramework \"tailwind\")}} class=\"text-gray-400\"{{/if}}>{description}</p>\n </div>\n );\n}\n`],\n [\"frontend/fresh/src/islands/Counter.tsx.hbs\", `import { useSignal } from \"@preact/signals\";\n\ninterface CounterProps {\n start: number;\n}\n\nexport default function Counter({ start }: CounterProps) {\n const count = useSignal(start);\n\n return (\n <div{{#if (eq cssFramework \"tailwind\")}} class=\"flex items-center gap-4\"{{/if}}>\n <button\n onClick={() => count.value--}\n {{#if (eq cssFramework \"tailwind\")}}class=\"px-4 py-2 bg-cyan-500 hover:bg-cyan-600 text-white rounded-lg font-semibold transition-colors\"{{/if}}\n >\n -\n </button>\n <span{{#if (eq cssFramework \"tailwind\")}} class=\"text-3xl font-bold text-white min-w-[60px] text-center\"{{/if}}>\n {count}\n </span>\n <button\n onClick={() => count.value++}\n {{#if (eq cssFramework \"tailwind\")}}class=\"px-4 py-2 bg-cyan-500 hover:bg-cyan-600 text-white rounded-lg font-semibold transition-colors\"{{/if}}\n >\n +\n </button>\n </div>\n );\n}\n`],\n [\"frontend/fresh/src/components/Header.tsx.hbs\", `export default function Header() {\n return (\n <header{{#if (eq cssFramework \"tailwind\")}} class=\"bg-black/20 backdrop-blur-md border-b border-white/10\"{{/if}}>\n <nav{{#if (eq cssFramework \"tailwind\")}} class=\"container mx-auto px-4 py-4 flex items-center justify-between\"{{/if}}>\n <a href=\"/\"{{#if (eq cssFramework \"tailwind\")}} class=\"text-xl font-bold text-white hover:text-cyan-400 transition-colors\"{{/if}}>\n {{projectName}}\n </a>\n <div{{#if (eq cssFramework \"tailwind\")}} class=\"flex items-center gap-6\"{{/if}}>\n <a\n href=\"https://fresh.deno.dev/docs\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n {{#if (eq cssFramework \"tailwind\")}}class=\"text-gray-300 hover:text-white transition-colors\"{{/if}}\n >\n Docs\n </a>\n <a\n href=\"https://github.com/denoland/fresh\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n {{#if (eq cssFramework \"tailwind\")}}class=\"text-gray-300 hover:text-white transition-colors\"{{/if}}\n >\n GitHub\n </a>\n </div>\n </nav>\n </header>\n );\n}\n`],\n [\"frontend/redwood/web/src/index.css.hbs\", `{{#if (eq cssFramework \"tailwind\")}}\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n{{else}}\n* {\n box-sizing: border-box;\n}\n\nbody {\n margin: 0;\n padding: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\", \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n background-color: #0f172a;\n color: #f8fafc;\n min-height: 100vh;\n}\n\na {\n color: #38bdf8;\n text-decoration: none;\n}\n\na:hover {\n text-decoration: underline;\n}\n{{/if}}\n`],\n [\"frontend/redwood/web/src/App.tsx\", `import { FatalErrorBoundary, RedwoodProvider } from \"@redwoodjs/web\";\nimport { RedwoodApolloProvider } from \"@redwoodjs/web/apollo\";\nimport FatalErrorPage from \"src/pages/FatalErrorPage/FatalErrorPage\";\nimport Routes from \"src/Routes\";\n\nimport \"./index.css\";\n\nconst App = () => (\n <FatalErrorBoundary page={FatalErrorPage}>\n <RedwoodProvider titleTemplate=\"%PageTitle | %AppTitle\">\n <RedwoodApolloProvider>\n <Routes />\n </RedwoodApolloProvider>\n </RedwoodProvider>\n </FatalErrorBoundary>\n);\n\nexport default App;\n`],\n [\"frontend/redwood/web/src/index.html\", `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />\n </head>\n <body>\n <div id=\"redwood-app\">\n <!-- content -->\n </div>\n </body>\n</html>\n`],\n [\"frontend/redwood/web/src/entry.client.tsx\", `import { hydrateRoot, createRoot } from \"react-dom/client\";\n\nimport App from \"./App\";\n\n/**\n * When \\`#redwood-app\\` isn't empty then it's very likely that you're using\n * prerendering. So React attaches event listeners to the existing markup\n * rather than replacing it.\n * https://reactjs.org/docs/react-dom-client.html#hydrateroot\n */\nconst redwoodAppElement = document.getElementById(\"redwood-app\");\n\nif (redwoodAppElement!.children?.length > 0) {\n hydrateRoot(redwoodAppElement!, <App />);\n} else {\n const root = createRoot(redwoodAppElement!);\n root.render(<App />);\n}\n`],\n [\"frontend/redwood/web/src/Routes.tsx\", `// In this file, all Page components from 'src/pages\\` are auto-imported. Nested\n// directories are supported, and should be uppercase. Each subdirectory will be\n// prepended onto the component name.\n//\n// Examples:\n//\n// 'src/pages/HomePage/HomePage.js' -> HomePage\n// 'src/pages/Admin/BooksPage/BooksPage.js' -> AdminBooksPage\n\nimport { Router, Route } from \"@redwoodjs/router\";\n\nconst Routes = () => {\n return (\n <Router>\n <Route path=\"/\" page={HomePage} name=\"home\" />\n <Route notfound page={NotFoundPage} />\n </Router>\n );\n};\n\nexport default Routes;\n`],\n [\"frontend/solid/src/components/loader.tsx\", `import { Loader2 } from \"lucide-solid\";\n\nexport default function Loader() {\n return (\n <div class=\"flex h-full items-center justify-center pt-8\">\n <Loader2 class=\"animate-spin\" />\n </div>\n );\n}\n`],\n [\"frontend/solid/src/components/header.tsx.hbs\", `import { Link } from \"@tanstack/solid-router\";\n{{#if (eq auth \"better-auth\")}}\nimport UserMenu from \"./user-menu\";\n{{/if}}\nimport { For } from \"solid-js\";\n\nexport default function Header() {\n const links = [\n { to: \"/\", label: \"Home\" },\n {{#if (eq auth \"better-auth\")}}\n { to: \"/dashboard\", label: \"Dashboard\" },\n {{/if}}\n {{#if (includes examples \"todo\")}}\n { to: \"/todos\", label: \"Todos\" },\n {{/if}}\n {{#if (includes examples \"ai\")}}\n { to: \"/ai\", label: \"AI Chat\" },\n {{/if}}\n ];\n\n return (\n <div>\n <div class=\"flex flex-row items-center justify-between px-2 py-1\">\n <nav class=\"flex gap-4 text-lg\">\n <For each={links}>\n {(link) => <Link to={link.to}>{link.label}</Link>}\n </For>\n </nav>\n <div class=\"flex items-center gap-2\">\n {{#if (eq auth \"better-auth\")}}\n <UserMenu />\n {{/if}}\n </div>\n </div>\n <hr />\n </div>\n );\n}\n`],\n [\"frontend/solid/src/routes/__root.tsx.hbs\", `import Header from \"@/components/header\";\nimport { Outlet, createRootRouteWithContext } from \"@tanstack/solid-router\";\nimport { TanStackRouterDevtools } from \"@tanstack/solid-router-devtools\";\n{{#if (eq api \"orpc\")}}\nimport { SolidQueryDevtools } from \"@tanstack/solid-query-devtools\";\nimport type { QueryClient } from \"@tanstack/solid-query\";\nimport type { orpc } from \"../utils/orpc\";\n\nexport interface RouterContext {\n orpc: typeof orpc;\n queryClient: QueryClient;\n}\n{{else}}\nexport interface RouterContext {}\n{{/if}}\n\nexport const Route = createRootRouteWithContext<RouterContext>()({\n component: RootComponent,\n});\n\nfunction RootComponent() {\n return (\n <>\n <div class=\"grid grid-rows-[auto_1fr] h-svh\">\n <Header />\n <Outlet />\n </div>\n {{#if (eq api \"orpc\")}}\n <SolidQueryDevtools />\n {{/if}}\n <TanStackRouterDevtools />\n </>\n );\n}\n`],\n [\"frontend/solid/src/routes/index.tsx.hbs\", `import { createFileRoute } from \"@tanstack/solid-router\";\n{{#if (eq api \"orpc\")}}\nimport { useQuery } from \"@tanstack/solid-query\";\nimport { orpc } from \"../utils/orpc\";\nimport { Match, Switch } from \"solid-js\";\n{{else}}\n{{/if}}\n\nexport const Route = createFileRoute(\"/\")({\n component: App,\n});\n\nconst TITLE_TEXT = \\`\n ██████╗ ███████╗████████╗████████╗███████╗██████╗\n ██╔══██╗██╔════╝╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗\n ██████╔╝█████╗ ██║ ██║ █████╗ ██████╔╝\n ██╔══██╗██╔══╝ ██║ ██║ ██╔══╝ ██╔══██╗\n ██████╔╝███████╗ ██║ ██║ ███████╗██║ ██║\n ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝\n\n ████████╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗\n ╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝\n ██║ ███████╗ ██║ ███████║██║ █████╔╝\n ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗\n ██║ ███████║ ██║ ██║ ██║╚██████╗██║ ██╗\n ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝\n \\`;\n\nfunction App() {\n {{#if (eq api \"orpc\")}}\n const healthCheck = useQuery(() => orpc.healthCheck.queryOptions());\n {{/if}}\n\n return (\n <div class=\"container mx-auto max-w-3xl px-4 py-2\">\n <pre class=\"overflow-x-auto font-mono text-sm\">{TITLE_TEXT}</pre>\n <div class=\"grid gap-6\">\n {{#if (eq api \"orpc\")}}\n <section class=\"rounded-lg border p-4\">\n <h2 class=\"mb-2 font-medium\">API Status</h2>\n <Switch>\n <Match when={healthCheck.isPending}>\n <div class=\"flex items-center gap-2\">\n <div class=\"h-2 w-2 rounded-full bg-gray-500 animate-pulse\" />{\" \"}\n <span class=\"text-sm text-muted-foreground\">Checking...</span>\n </div>\n </Match>\n <Match when={healthCheck.isError}>\n <div class=\"flex items-center gap-2\">\n <div class=\"h-2 w-2 rounded-full bg-red-500\" />\n <span class=\"text-sm text-muted-foreground\">Disconnected</span>\n </div>\n </Match>\n <Match when={healthCheck.isSuccess}>\n <div class=\"flex items-center gap-2\">\n <div\n class={\\`h-2 w-2 rounded-full \\${healthCheck.data ? \"bg-green-500\" : \"bg-red-500\"}\\`}\n />\n <span class=\"text-sm text-muted-foreground\">\n {healthCheck.data\n ? \"Connected\"\n : \"Disconnected\"}\n </span>\n </div>\n </Match>\n </Switch>\n </section>\n {{/if}}\n </div>\n </div>\n );\n}\n`],\n [\"examples/ai/native/bare/polyfills.js\", `import structuredClone from \"@ungap/structured-clone\";\nimport { Platform } from \"react-native\";\n\nif (Platform.OS !== \"web\") {\n const setupPolyfills = async () => {\n const { polyfillGlobal } = await import(\"react-native/Libraries/Utilities/PolyfillFunctions\");\n\n const { TextEncoderStream, TextDecoderStream } =\n await import(\"@stardazed/streams-text-encoding\");\n\n if (!(\"structuredClone\" in global)) {\n polyfillGlobal(\"structuredClone\", () => structuredClone);\n }\n\n polyfillGlobal(\"TextEncoderStream\", () => TextEncoderStream);\n polyfillGlobal(\"TextDecoderStream\", () => TextDecoderStream);\n };\n\n setupPolyfills();\n}\n\nexport {};\n`],\n [\"examples/ai/native/uniwind/polyfills.js\", `import structuredClone from \"@ungap/structured-clone\";\nimport { Platform } from \"react-native\";\n\nif (Platform.OS !== \"web\") {\n const setupPolyfills = async () => {\n const { polyfillGlobal } = await import(\"react-native/Libraries/Utilities/PolyfillFunctions\");\n\n const { TextEncoderStream, TextDecoderStream } =\n await import(\"@stardazed/streams-text-encoding\");\n\n if (!(\"structuredClone\" in global)) {\n polyfillGlobal(\"structuredClone\", () => structuredClone);\n }\n\n polyfillGlobal(\"TextEncoderStream\", () => TextEncoderStream);\n polyfillGlobal(\"TextDecoderStream\", () => TextDecoderStream);\n };\n\n setupPolyfills();\n}\n\nexport {};\n`],\n [\"frontend/nuxt/app/components/Header.vue.hbs\", `<script setup lang=\"ts\">\nimport type { NavigationMenuItem } from '@nuxt/ui'\n{{#if (eq auth \"better-auth\")}}\nimport UserMenu from './UserMenu.vue'\n{{/if}}\n\nconst route = useRoute()\n\nconst items = computed<NavigationMenuItem[]>(() => [\n { label: \"Home\", to: \"/\", active: route.path === \"/\" },\n {{#if (or (eq auth \"better-auth\") (eq auth \"clerk\"))}}\n { label: \"Dashboard\", to: \"/dashboard\", active: route.path.startsWith(\"/dashboard\") },\n {{/if}}\n {{#if (includes examples \"todo\")}}\n { label: \"Todos\", to: \"/todos\", active: route.path.startsWith(\"/todos\") },\n {{/if}}\n {{#if (includes examples \"ai\")}}\n { label: \"AI Chat\", to: \"/ai\", active: route.path.startsWith(\"/ai\") },\n {{/if}}\n])\n</script>\n\n<template>\n <UHeader>\n <template #left>\n <UNavigationMenu :items=\"items\" />\n </template>\n\n <template #right>\n <UColorModeButton />\n {{#if (eq auth \"better-auth\")}}\n <UserMenu />\n {{/if}}\n </template>\n\n <template #body>\n <UNavigationMenu :items=\"items\" orientation=\"vertical\" class=\"-mx-2.5\" />\n </template>\n </UHeader>\n</template>\n`],\n [\"frontend/nuxt/app/pages/index.vue.hbs\", `<script setup lang=\"ts\">\n{{#if (eq backend \"convex\")}}\nimport { api } from \"@{{ projectName }}/backend/convex/_generated/api\";\nimport { useConvexQuery } from \"convex-vue\";\n{{else}}\n {{#unless (eq api \"none\")}}\nconst { $orpc } = useNuxtApp()\nimport { useQuery } from '@tanstack/vue-query'\n {{/unless}}\n{{/if}}\n\nconst TITLE_TEXT = \\`\n ██████╗ ███████╗████████╗████████╗███████╗██████╗\n ██╔══██╗██╔════╝╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗\n ██████╔╝█████╗ ██║ ██║ █████╗ ██████╔╝\n ██╔══██╗██╔══╝ ██║ ██║ ██╔══╝ ██╔══██╗\n ██████╔╝███████╗ ██║ ██║ ███████╗██║ ██║\n ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝\n\n ████████╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗\n ╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝\n ██║ ███████╗ ██║ ███████║██║ █████╔╝\n ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗\n ██║ ███████║ ██║ ██║ ██║╚██████╗██║ ██╗\n ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝\n \\`;\n\n{{#if (eq backend \"convex\")}}\nconst healthCheck = useConvexQuery(api.healthCheck.get, {});\n{{else}}\n {{#unless (eq api \"none\")}}\nconst healthCheck = useQuery($orpc.healthCheck.queryOptions())\n {{/unless}}\n{{/if}}\n</script>\n\n<template>\n <UContainer class=\"py-8\">\n <pre class=\"overflow-x-auto font-mono text-sm whitespace-pre-wrap\">\\\\{{ TITLE_TEXT }}</pre>\n\n <div class=\"grid gap-6 mt-6\">\n <UCard>\n <template #header>\n <div class=\"font-medium\">API Status</div>\n </template>\n\n {{#if (eq backend \"convex\")}}\n <div class=\"flex items-center gap-2\">\n <UIcon\n :name=\"healthCheck === undefined ? 'i-lucide-loader-2' : healthCheck.data.value === 'OK' ? 'i-lucide-check-circle' : 'i-lucide-x-circle'\"\n :class=\"[\n healthCheck === undefined ? 'animate-spin text-muted' : '',\n healthCheck?.data.value === 'OK' ? 'text-success' : 'text-error'\n ]\"\n />\n <span class=\"text-sm\">\n \\\\{{\n healthCheck === undefined\n ? \"Checking...\"\n : healthCheck.data.value === \"OK\"\n ? \"Connected\"\n : \"Error\"\n }}\n </span>\n </div>\n {{else}}\n {{#unless (eq api \"none\")}}\n <div class=\"flex items-center gap-2\">\n <UIcon\n :name=\"healthCheck.isLoading.value ? 'i-lucide-loader-2' : healthCheck.isSuccess.value ? 'i-lucide-check-circle' : 'i-lucide-x-circle'\"\n :class=\"[\n healthCheck.isLoading.value ? 'animate-spin text-muted' : '',\n healthCheck.isSuccess.value ? 'text-success' : '',\n healthCheck.isError.value ? 'text-error' : ''\n ]\"\n />\n <span class=\"text-sm\">\n <template v-if=\"healthCheck.isLoading.value\">\n Checking...\n </template>\n <template v-else-if=\"healthCheck.isSuccess.value\">\n Connected (\\\\{{ healthCheck.data.value }})\n </template>\n <template v-else-if=\"healthCheck.isError.value\">\n Error: \\\\{{ healthCheck.error.value?.message || 'Failed to connect' }}\n </template>\n <template v-else>\n Idle\n </template>\n </span>\n </div>\n {{/unless}}\n {{/if}}\n </UCard>\n </div>\n </UContainer>\n</template>\n`],\n [\"examples/ai/native/unistyles/polyfills.js\", `import structuredClone from \"@ungap/structured-clone\";\nimport { Platform } from \"react-native\";\n\nif (Platform.OS !== \"web\") {\n const setupPolyfills = async () => {\n const { polyfillGlobal } = await import(\"react-native/Libraries/Utilities/PolyfillFunctions\");\n\n const { TextEncoderStream, TextDecoderStream } =\n await import(\"@stardazed/streams-text-encoding\");\n\n if (!(\"structuredClone\" in global)) {\n polyfillGlobal(\"structuredClone\", () => structuredClone);\n }\n\n polyfillGlobal(\"TextEncoderStream\", () => TextEncoderStream);\n polyfillGlobal(\"TextDecoderStream\", () => TextDecoderStream);\n };\n\n setupPolyfills();\n}\n\nexport {};\n`],\n [\"frontend/nuxt/app/layouts/default.vue.hbs\", `<script setup></script>\n\n<template>\n <div class=\"grid grid-rows-[auto_1fr] h-svh\">\n <Header />\n <UMain>\n <slot />\n </UMain>\n </div>\n</template>\n`],\n [\"frontend/astro/src/pages/index.astro.hbs\", `---\nimport Layout from '@/layouts/Layout.astro';\n{{#if (ne astroIntegration \"none\")}}\n{{#if (eq astroIntegration \"react\")}}\nimport Counter from '@/components/Counter';\n{{/if}}\n{{#if (eq astroIntegration \"vue\")}}\nimport Counter from '@/components/Counter.vue';\n{{/if}}\n{{#if (eq astroIntegration \"svelte\")}}\nimport Counter from '@/components/Counter.svelte';\n{{/if}}\n{{#if (eq astroIntegration \"solid\")}}\nimport Counter from '@/components/Counter';\n{{/if}}\n{{/if}}\n---\n\n<Layout title=\"{{projectName}}\">\n\t<div class=\"flex flex-col items-center justify-center gap-8 py-12\">\n\t\t<div class=\"text-center\">\n\t\t\t<h1 class=\"mb-4 text-4xl font-bold tracking-tight sm:text-5xl\">\n\t\t\t\tWelcome to <span class=\"text-primary\">{{projectName}}</span>\n\t\t\t</h1>\n\t\t\t<p class=\"text-lg text-muted-foreground\">\n\t\t\t\tBuilt with Astro and Better-T-Stack\n\t\t\t</p>\n\t\t</div>\n\n{{#if (ne astroIntegration \"none\")}}\n\t\t<div class=\"mt-8 rounded-lg border border-border bg-card p-6 shadow-sm\">\n\t\t\t<h2 class=\"mb-4 text-xl font-semibold\">Interactive Counter</h2>\n\t\t\t<p class=\"mb-4 text-sm text-muted-foreground\">\n\t\t\t\tThis is an island component using {{astroIntegration}} with client-side hydration.\n\t\t\t</p>\n\t\t\t<Counter client:load />\n\t\t</div>\n{{else}}\n\t\t<div class=\"mt-8 rounded-lg border border-border bg-card p-6 shadow-sm\">\n\t\t\t<h2 class=\"mb-4 text-xl font-semibold\">Static Site</h2>\n\t\t\t<p class=\"text-sm text-muted-foreground\">\n\t\t\t\tThis is a static Astro site without client-side JavaScript framework.\n\t\t\t</p>\n\t\t</div>\n{{/if}}\n\n\t\t<div class=\"mt-8 grid gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n\t\t\t<a\n\t\t\t\thref=\"https://docs.astro.build/\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\tclass=\"rounded-lg border border-border bg-card p-4 transition-colors hover:border-primary\"\n\t\t\t>\n\t\t\t\t<h3 class=\"font-semibold\">Astro Docs</h3>\n\t\t\t\t<p class=\"text-sm text-muted-foreground\">Learn about Astro's features and API.</p>\n\t\t\t</a>\n\t\t\t<a\n\t\t\t\thref=\"https://better-t-stack.dev\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\tclass=\"rounded-lg border border-border bg-card p-4 transition-colors hover:border-primary\"\n\t\t\t>\n\t\t\t\t<h3 class=\"font-semibold\">Better-T-Stack</h3>\n\t\t\t\t<p class=\"text-sm text-muted-foreground\">Full-stack TypeScript development.</p>\n\t\t\t</a>\n\t\t\t<a\n\t\t\t\thref=\"https://astro.build/integrations/\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\tclass=\"rounded-lg border border-border bg-card p-4 transition-colors hover:border-primary\"\n\t\t\t>\n\t\t\t\t<h3 class=\"font-semibold\">Integrations</h3>\n\t\t\t\t<p class=\"text-sm text-muted-foreground\">Extend Astro with plugins and frameworks.</p>\n\t\t\t</a>\n\t\t</div>\n\t</div>\n</Layout>\n`],\n [\"frontend/astro/src/components/Header.astro.hbs\", `---\n{{#if (eq astroIntegration \"react\")}}\nimport ModeToggle from '@/components/ModeToggle';\n{{/if}}\n---\n\n<header class=\"sticky top-0 z-50 w-full border-b border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60\">\n\t<div class=\"container mx-auto flex h-14 items-center justify-between px-4\">\n\t\t<a href=\"/\" class=\"flex items-center space-x-2\">\n\t\t\t<span class=\"text-xl font-bold\">{{projectName}}</span>\n\t\t</a>\n\t\t<nav class=\"flex items-center gap-4\">\n\t\t\t<a\n\t\t\t\thref=\"https://github.com\"\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\tclass=\"text-sm font-medium text-muted-foreground transition-colors hover:text-foreground\"\n\t\t\t>\n\t\t\t\tGitHub\n\t\t\t</a>\n{{#if (eq astroIntegration \"react\")}}\n\t\t\t<ModeToggle client:load />\n{{else}}\n\t\t\t<button\n\t\t\t\tid=\"theme-toggle\"\n\t\t\t\tclass=\"rounded-md p-2 hover:bg-accent\"\n\t\t\t\taria-label=\"Toggle theme\"\n\t\t\t>\n\t\t\t\t<svg class=\"dark:hidden h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n\t\t\t\t\t<path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z\" />\n\t\t\t\t</svg>\n\t\t\t\t<svg class=\"hidden dark:block h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n\t\t\t\t\t<path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z\" />\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t\t<script>\n\t\t\t\tconst toggle = document.getElementById('theme-toggle');\n\t\t\t\ttoggle?.addEventListener('click', () => {\n\t\t\t\t\tdocument.documentElement.classList.toggle('dark');\n\t\t\t\t});\n\t\t\t</script>\n{{/if}}\n\t\t</nav>\n\t</div>\n</header>\n`],\n [\"frontend/astro/src/styles/global.css.hbs\", `@import \"tailwindcss\";\n\n@theme {\n\t--color-background: oklch(100% 0 0);\n\t--color-foreground: oklch(14.08% 0.004 285.82);\n\t--color-card: oklch(100% 0 0);\n\t--color-card-foreground: oklch(14.08% 0.004 285.82);\n\t--color-primary: oklch(20.47% 0.006 285.88);\n\t--color-primary-foreground: oklch(98.51% 0.001 106.42);\n\t--color-secondary: oklch(96.76% 0.001 286.38);\n\t--color-secondary-foreground: oklch(20.47% 0.006 285.88);\n\t--color-muted: oklch(96.76% 0.001 286.38);\n\t--color-muted-foreground: oklch(55.19% 0.014 285.94);\n\t--color-accent: oklch(96.76% 0.001 286.38);\n\t--color-accent-foreground: oklch(20.47% 0.006 285.88);\n\t--color-border: oklch(91.97% 0.004 286.32);\n\t--color-input: oklch(91.97% 0.004 286.32);\n\t--color-ring: oklch(14.08% 0.004 285.82);\n\n\t--radius-sm: 0.25rem;\n\t--radius-md: 0.375rem;\n\t--radius-lg: 0.5rem;\n}\n\n.dark {\n\t--color-background: oklch(14.08% 0.004 285.82);\n\t--color-foreground: oklch(98.51% 0.001 106.42);\n\t--color-card: oklch(14.08% 0.004 285.82);\n\t--color-card-foreground: oklch(98.51% 0.001 106.42);\n\t--color-primary: oklch(98.51% 0.001 106.42);\n\t--color-primary-foreground: oklch(20.47% 0.006 285.88);\n\t--color-secondary: oklch(26.96% 0.005 286.03);\n\t--color-secondary-foreground: oklch(98.51% 0.001 106.42);\n\t--color-muted: oklch(26.96% 0.005 286.03);\n\t--color-muted-foreground: oklch(70.67% 0.01 286.07);\n\t--color-accent: oklch(26.96% 0.005 286.03);\n\t--color-accent-foreground: oklch(98.51% 0.001 106.42);\n\t--color-border: oklch(26.96% 0.005 286.03);\n\t--color-input: oklch(26.96% 0.005 286.03);\n\t--color-ring: oklch(83.53% 0.005 286.29);\n}\n`],\n [\"frontend/astro/src/layouts/Layout.astro.hbs\", `---\nimport '@/styles/global.css';\nimport Header from '@/components/Header.astro';\n\ninterface Props {\n\ttitle: string;\n}\n\nconst { title } = Astro.props;\n---\n\n<!doctype html>\n<html lang=\"en\" class=\"dark\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta name=\"description\" content=\"Astro website built with Better-T-Stack\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n\t\t<link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />\n\t\t<meta name=\"generator\" content={Astro.generator} />\n\t\t<title>{title}</title>\n\t</head>\n\t<body class=\"min-h-screen bg-background text-foreground antialiased\">\n\t\t<Header />\n\t\t<main class=\"container mx-auto px-4 py-8\">\n\t\t\t<slot />\n\t\t</main>\n\t</body>\n</html>\n`],\n [\"frontend/native/unistyles/app/+not-found.tsx.hbs\", `import { Link, Stack } from \"expo-router\";\nimport { Text, View } from \"react-native\";\nimport { StyleSheet } from \"react-native-unistyles\";\nimport { Container } from \"@/components/container\";\n\nexport default function NotFoundScreen() {\n return (\n <>\n <Stack.Screen options=\\\\{{ title: \"Oops!\" }} />\n <Container>\n <View style={styles.container}>\n <View style={styles.content}>\n <Text style={styles.emoji}>🤔</Text>\n <Text style={styles.title}>Page Not Found</Text>\n <Text style={styles.description}>\n Sorry, the page you're looking for doesn't exist.\n </Text>\n <Link href=\"/\" style={styles.button}>\n <Text style={styles.buttonText}>Go to Home</Text>\n </Link>\n </View>\n </View>\n </Container>\n </>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n container: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n padding: theme.spacing.lg,\n },\n content: {\n alignItems: \"center\",\n },\n emoji: {\n fontSize: 64,\n marginBottom: theme.spacing.md,\n },\n title: {\n fontSize: theme.fontSize[\"2xl\"],\n fontWeight: \"bold\",\n color: theme.colors.foreground,\n marginBottom: theme.spacing.sm,\n textAlign: \"center\",\n },\n description: {\n color: theme.colors.mutedForeground,\n textAlign: \"center\",\n marginBottom: theme.spacing.xl,\n maxWidth: 280,\n },\n button: {\n backgroundColor: \\`\\${theme.colors.primary}1A\\`, // 10% opacity\n paddingHorizontal: theme.spacing.lg,\n paddingVertical: theme.spacing.sm + 4,\n borderRadius: theme.borderRadius.lg,\n },\n buttonText: {\n color: theme.colors.primary,\n fontWeight: \"500\",\n },\n}));\n`],\n [\"frontend/native/unistyles/app/modal.tsx.hbs\", `import { Container } from \"@/components/container\";\nimport { Text, View } from \"react-native\";\nimport { StyleSheet } from \"react-native-unistyles\";\n\nexport default function Modal() {\n return (\n <Container>\n <View style={styles.container}>\n <View style={styles.header}>\n <Text style={styles.title}>Modal</Text>\n </View>\n </View>\n </Container>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n container: {\n flex: 1,\n padding: theme.spacing.lg,\n },\n header: {\n flexDirection: \"row\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n marginBottom: theme.spacing.xl,\n },\n title: {\n fontSize: theme.fontSize[\"2xl\"],\n fontWeight: \"bold\",\n color: theme.colors.foreground,\n },\n}));\n`],\n [\"frontend/native/unistyles/app/_layout.tsx.hbs\", `{{#if (includes examples \"ai\")}}\nimport \"@/polyfills\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { queryClient } from \"@/utils/trpc\";\n{{/if}}\n{{#if (eq api \"orpc\")}}\nimport { queryClient } from \"@/utils/orpc\";\n{{/if}}\n{{#if (eq backend \"convex\")}}\n{{#if (eq auth \"better-auth\")}}\nimport { ConvexReactClient } from \"convex/react\";\nimport { ConvexBetterAuthProvider } from \"@convex-dev/better-auth/react\";\nimport { authClient } from \"@/lib/auth-client\";\nimport { env } from \"@{{projectName}}/env/native\";\n{{else}}\nimport { ConvexProvider, ConvexReactClient } from \"convex/react\";\nimport { env } from \"@{{projectName}}/env/native\";\n{{/if}}\n{{#if (eq auth \"clerk\")}}\nimport { ClerkProvider, useAuth } from \"@clerk/clerk-expo\";\nimport { ConvexProviderWithClerk } from \"convex/react-clerk\";\nimport { tokenCache } from \"@clerk/clerk-expo/token-cache\";\n{{/if}}\n{{else}}\n {{#unless (eq api \"none\")}}\nimport { QueryClientProvider } from \"@tanstack/react-query\";\n {{/unless}}\n{{/if}}\nimport { Stack } from \"expo-router\";\nimport { GestureHandlerRootView } from \"react-native-gesture-handler\";\nimport { useUnistyles } from \"react-native-unistyles\";\nimport { StatusBar } from \"expo-status-bar\";\n\nexport const unstable_settings = {\n initialRouteName: \"(drawer)\",\n};\n\n{{#if (eq backend \"convex\")}}\nconst convex = new ConvexReactClient(env.EXPO_PUBLIC_CONVEX_URL, {\n unsavedChangesWarning: false,\n});\n{{/if}}\n\nexport default function RootLayout() {\n const { theme } = useUnistyles();\n\n return (\n {{#if (eq backend \"convex\")}}\n {{#if (eq auth \"clerk\")}}\n <ClerkProvider\n tokenCache={tokenCache}\n publishableKey={env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY}\n >\n <ConvexProviderWithClerk client={convex} useAuth={useAuth}>\n <GestureHandlerRootView style=\\\\{{ flex: 1 }}>\n <Stack\n screenOptions=\\\\{{\n headerStyle: {\n backgroundColor: theme.colors.background,\n },\n headerTitleStyle: {\n color: theme.colors.foreground,\n },\n headerTintColor: theme.colors.foreground,\n }}\n >\n <Stack.Screen name=\"(drawer)\" options=\\\\{{ headerShown: false }} />\n <Stack.Screen name=\"(auth)\" options=\\\\{{ headerShown: false }} />\n <Stack.Screen\n name=\"modal\"\n options=\\\\{{ title: \"Modal\", presentation: \"modal\" }}\n />\n </Stack>\n </GestureHandlerRootView>\n </ConvexProviderWithClerk>\n </ClerkProvider>\n {{else if (eq auth \"better-auth\")}}\n <ConvexBetterAuthProvider client={convex} authClient={authClient}>\n <GestureHandlerRootView style=\\\\{{ flex: 1 }}>\n <Stack\n screenOptions=\\\\{{\n headerStyle: {\n backgroundColor: theme.colors.background,\n },\n headerTitleStyle: {\n color: theme.colors.foreground,\n },\n headerTintColor: theme.colors.foreground,\n }}\n >\n <Stack.Screen name=\"(drawer)\" options=\\\\{{ headerShown: false }} />\n <Stack.Screen\n name=\"modal\"\n options=\\\\{{ title: \"Modal\", presentation: \"modal\" }}\n />\n </Stack>\n </GestureHandlerRootView>\n </ConvexBetterAuthProvider>\n {{else}}\n <ConvexProvider client={convex}>\n <GestureHandlerRootView style=\\\\{{ flex: 1 }}>\n <Stack\n screenOptions=\\\\{{\n headerStyle: {\n backgroundColor: theme.colors.background,\n },\n headerTitleStyle: {\n color: theme.colors.foreground,\n },\n headerTintColor: theme.colors.foreground,\n }}\n >\n <Stack.Screen name=\"(drawer)\" options=\\\\{{ headerShown: false }} />\n <Stack.Screen\n name=\"modal\"\n options=\\\\{{ title: \"Modal\", presentation: \"modal\" }}\n />\n </Stack>\n </GestureHandlerRootView>\n </ConvexProvider>\n {{/if}}\n {{else}}\n {{#unless (eq api \"none\")}}\n <QueryClientProvider client={queryClient}>\n <GestureHandlerRootView style=\\\\{{ flex: 1 }}>\n <Stack\n screenOptions=\\\\{{\n headerStyle: {\n backgroundColor: theme.colors.background,\n },\n headerTitleStyle: {\n color: theme.colors.foreground,\n },\n headerTintColor: theme.colors.foreground,\n }}\n >\n <Stack.Screen name=\"(drawer)\" options=\\\\{{ headerShown: false }} />\n <Stack.Screen\n name=\"modal\"\n options=\\\\{{ title: \"Modal\", presentation: \"modal\" }}\n />\n </Stack>\n </GestureHandlerRootView>\n </QueryClientProvider>\n {{else}}\n <GestureHandlerRootView style=\\\\{{ flex: 1 }}>\n <Stack\n screenOptions=\\\\{{\n headerStyle: {\n backgroundColor: theme.colors.background,\n },\n headerTitleStyle: {\n color: theme.colors.foreground,\n },\n headerTintColor: theme.colors.foreground,\n }}\n >\n <Stack.Screen name=\"(drawer)\" options=\\\\{{ headerShown: false }} />\n <Stack.Screen\n name=\"modal\"\n options=\\\\{{ title: \"Modal\", presentation: \"modal\" }}\n />\n </Stack>\n </GestureHandlerRootView>\n {{/unless}}\n {{/if}}\n );\n}\n`],\n [\"frontend/native/unistyles/components/tabbar-icon.tsx.hbs\", `import FontAwesome from \"@expo/vector-icons/FontAwesome\";\n\nexport const TabBarIcon = (props: {\n name: React.ComponentProps<typeof FontAwesome>[\"name\"];\n color: string;\n}) => {\n return <FontAwesome size={24} style=\\\\{{ marginBottom: -3 }} {...props} />;\n};\n`],\n [\"frontend/native/unistyles/components/container.tsx.hbs\", `import React from \"react\";\nimport { SafeAreaView } from \"react-native-safe-area-context\";\nimport { StyleSheet } from \"react-native-unistyles\";\n\nexport const Container = ({ children }: { children: React.ReactNode }) => {\n return <SafeAreaView style={styles.container}>{children}</SafeAreaView>;\n};\n\nconst styles = StyleSheet.create((theme, rt) => ({\n container: {\n flex: 1,\n backgroundColor: theme.colors.background,\n paddingBottom: rt.insets.bottom,\n },\n}));\n`],\n [\"frontend/native/unistyles/components/header-button.tsx.hbs\", `import FontAwesome from \"@expo/vector-icons/FontAwesome\";\nimport { forwardRef } from \"react\";\nimport { Pressable } from \"react-native\";\nimport { StyleSheet } from \"react-native-unistyles\";\n\nexport const HeaderButton = forwardRef<\n typeof Pressable,\n { onPress?: () => void }\n>(({ onPress }, ref) => {\n return (\n <Pressable onPress={onPress} style={styles.button}>\n {({ pressed }) => (\n <FontAwesome\n name=\"info-circle\"\n size={20}\n color={styles.icon.color}\n style=\\\\{{\n opacity: pressed ? 0.7 : 1,\n }}\n />\n )}\n </Pressable>\n );\n});\n\nconst styles = StyleSheet.create((theme) => ({\n button: {\n padding: theme.spacing.sm,\n marginRight: theme.spacing.sm,\n borderRadius: theme.borderRadius.lg,\n backgroundColor: \\`\\${theme.colors.secondary}80\\`, // 50% opacity\n },\n icon: {\n color: theme.colors.secondaryForeground,\n },\n}));\n`],\n [\"db/kysely/sqlite/src/index.ts.hbs\", `import { env } from \"@{{projectName}}/env/server\";\nimport { Kysely, SqliteDialect } from \"kysely\";\nimport Database from \"better-sqlite3\";\nimport type { Database as DB } from \"./schema\";\n\nconst dialect = new SqliteDialect({\n\tdatabase: new Database(env.DATABASE_URL.replace(\"file:\", \"\")),\n});\n\nexport const db = new Kysely<DB>({\n\tdialect,\n});\n`],\n [\"frontend/native/bare/components/tabbar-icon.tsx.hbs\", `import FontAwesome from \"@expo/vector-icons/FontAwesome\";\n\nexport const TabBarIcon = (props: {\n name: React.ComponentProps<typeof FontAwesome>[\"name\"];\n color: string;\n}) => {\n return <FontAwesome size={24} style=\\\\{{ marginBottom: -3 }} {...props} />;\n};\n\n`],\n [\"frontend/native/bare/components/container.tsx.hbs\", `import React from \"react\";\nimport { SafeAreaView } from \"react-native-safe-area-context\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\nimport { StyleSheet } from \"react-native\";\n\nexport function Container({ children }: { children: React.ReactNode }) {\n const { colorScheme } = useColorScheme();\n const backgroundColor = colorScheme === \"dark\" \n ? NAV_THEME.dark.background \n : NAV_THEME.light.background;\n\n return (\n <SafeAreaView style={[styles.container, { backgroundColor }]}>\n {children}\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n },\n});\n\n`],\n [\"frontend/native/bare/components/header-button.tsx.hbs\", `import FontAwesome from \"@expo/vector-icons/FontAwesome\";\nimport { forwardRef } from \"react\";\nimport { Pressable, StyleSheet, View } from \"react-native\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\n\nexport const HeaderButton = forwardRef<\n View,\n { onPress?: () => void }\n>(({ onPress }, ref) => {\n const { colorScheme } = useColorScheme();\n const theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\n\n return (\n <Pressable\n ref={ref}\n onPress={onPress}\n style={({ pressed }) => [\n styles.button,\n {\n backgroundColor: pressed \n ? theme.background \n : theme.card,\n },\n ]}\n >\n {({ pressed }) => (\n <FontAwesome\n name=\"info-circle\"\n size={20}\n color={theme.text}\n style=\\\\{{\n opacity: pressed ? 0.7 : 1,\n }}\n />\n )}\n </Pressable>\n );\n});\n\nconst styles = StyleSheet.create({\n button: {\n padding: 8,\n marginRight: 8,\n },\n});\n\n`],\n [\"frontend/native/bare/lib/constants.ts.hbs\", `export const NAV_THEME = {\n light: {\n background: \"hsl(0 0% 100%)\",\n border: \"hsl(220 13% 91%)\",\n card: \"hsl(0 0% 100%)\",\n notification: \"hsl(0 84.2% 60.2%)\",\n primary: \"hsl(221.2 83.2% 53.3%)\",\n text: \"hsl(222.2 84% 4.9%)\",\n },\n dark: {\n background: \"hsl(222.2 84% 4.9%)\",\n border: \"hsl(217.2 32.6% 17.5%)\",\n card: \"hsl(222.2 84% 4.9%)\",\n notification: \"hsl(0 72% 51%)\",\n primary: \"hsl(217.2 91.2% 59.8%)\",\n text: \"hsl(210 40% 98%)\",\n },\n};\n\n`],\n [\"frontend/native/bare/lib/use-color-scheme.ts.hbs\", `import { useColorScheme as useRNColorScheme } from \"react-native\";\n\nexport function useColorScheme() {\n const systemColorScheme = useRNColorScheme();\n const colorScheme = systemColorScheme ?? \"light\";\n \n return {\n colorScheme: colorScheme as \"light\" | \"dark\",\n isDarkColorScheme: colorScheme === \"dark\",\n setColorScheme: () => {\n // Color scheme is managed by the system in bare mode\n console.warn(\"setColorScheme is not available in bare mode. Color scheme is managed by the system.\");\n },\n toggleColorScheme: () => {\n // Color scheme is managed by the system in bare mode\n console.warn(\"toggleColorScheme is not available in bare mode. Color scheme is managed by the system.\");\n },\n };\n}\n\n`],\n [\"frontend/native/bare/lib/android-navigation-bar.tsx.hbs\", `import * as NavigationBar from \"expo-navigation-bar\";\nimport { Platform } from \"react-native\";\nimport { NAV_THEME } from \"@/lib/constants\";\n\nexport async function setAndroidNavigationBar(theme: \"light\" | \"dark\") {\n if (Platform.OS !== \"android\") return;\n await NavigationBar.setButtonStyleAsync(theme === \"dark\" ? \"light\" : \"dark\");\n await NavigationBar.setBackgroundColorAsync(\n theme === \"dark\" ? NAV_THEME.dark.background : NAV_THEME.light.background,\n );\n}\n\n`],\n [\"db/kysely/postgres/src/index.ts.hbs\", `import { env } from \"@{{projectName}}/env/server\";\nimport { Kysely, PostgresDialect } from \"kysely\";\nimport { Pool } from \"pg\";\nimport type { Database as DB } from \"./schema\";\n\nconst dialect = new PostgresDialect({\n\tpool: new Pool({\n\t\tconnectionString: env.DATABASE_URL,\n{{#if (eq dbSetup \"neon\")}}\n\t\tssl: {\n\t\t\trejectUnauthorized: false,\n\t\t},\n{{/if}}\n\t}),\n});\n\nexport const db = new Kysely<DB>({\n\tdialect,\n});\n`],\n [\"frontend/native/uniwind/components/container.tsx.hbs\", `import { cn } from \"heroui-native\";\nimport { type PropsWithChildren } from \"react\";\nimport { ScrollView, View, type ViewProps } from \"react-native\";\nimport Animated, { type AnimatedProps } from \"react-native-reanimated\";\nimport { useSafeAreaInsets } from \"react-native-safe-area-context\";\n\nconst AnimatedView = Animated.createAnimatedComponent(View);\n\ntype Props = AnimatedProps<ViewProps> & {\n\tclassName?: string;\n};\n\nexport function Container({\n\tchildren,\n\tclassName,\n\t...props\n}: PropsWithChildren<Props>) {\n\tconst insets = useSafeAreaInsets();\n\n\treturn (\n\t\t<AnimatedView\n\t\t\tclassName={cn(\"flex-1 bg-background\", className)}\n\t\t\tstyle=\\\\{{\n\t\t\t\tpaddingBottom: insets.bottom,\n\t\t\t}}\n\t\t\t{...props}\n\t\t>\n\t\t\t<ScrollView contentContainerStyle=\\\\{{ flexGrow: 1 }}>\n\t\t\t\t{children}\n\t\t\t</ScrollView>\n\t\t</AnimatedView>\n\t);\n}\n`],\n [\"frontend/native/uniwind/components/theme-toggle.tsx.hbs\", `import { Ionicons } from '@expo/vector-icons';\nimport * as Haptics from 'expo-haptics';\nimport { Platform, Pressable } from 'react-native';\nimport Animated, { FadeOut, ZoomIn } from 'react-native-reanimated';\nimport { withUniwind } from 'uniwind';\nimport { useAppTheme } from '@/contexts/app-theme-context';\n\nconst StyledIonicons = withUniwind(Ionicons);\n\nexport function ThemeToggle() {\n\tconst { toggleTheme, isLight } = useAppTheme();\n\n\treturn (\n\t\t<Pressable\n\t\t\tonPress={() => {\n\t\t\t\tif (Platform.OS === 'ios') {\n\t\t\t\t\tHaptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);\n\t\t\t\t}\n\t\t\t\ttoggleTheme();\n\t\t\t}}\n\t\t\tclassName=\"px-2.5\"\n\t\t>\n\t\t\t{isLight ? (\n\t\t\t\t<Animated.View key=\"moon\" entering={ZoomIn} exiting={FadeOut}>\n\t\t\t\t\t<StyledIonicons name=\"moon\" size={20} className=\"text-foreground\" />\n\t\t\t\t</Animated.View>\n\t\t\t) : (\n\t\t\t\t<Animated.View key=\"sun\" entering={ZoomIn} exiting={FadeOut}>\n\t\t\t\t\t<StyledIonicons name=\"sunny\" size={20} className=\"text-foreground\" />\n\t\t\t\t</Animated.View>\n\t\t\t)}\n\t\t</Pressable>\n\t);\n}\n\n`],\n [\"frontend/native/bare/app/+not-found.tsx.hbs\", `import { Container } from \"@/components/container\";\nimport { Link, Stack } from \"expo-router\";\nimport { Text, View, StyleSheet } from \"react-native\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\n\nexport default function NotFoundScreen() {\n const { colorScheme } = useColorScheme();\n const theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\n\n return (\n <>\n <Stack.Screen options=\\\\{{ title: \"Oops!\" }} />\n <Container>\n <View style={styles.container}>\n <View style={styles.content}>\n <Text style={styles.emoji}>🤔</Text>\n <Text style={[styles.title, { color: theme.text }]}>\n Page Not Found\n </Text>\n <Text style={[styles.subtitle, { color: theme.text, opacity: 0.7 }]}>\n Sorry, the page you're looking for doesn't exist.\n </Text>\n <Link href=\"/\" asChild>\n <Text style={[styles.link, { color: theme.primary, backgroundColor: \\`\\${theme.primary}1a\\` }]}>\n Go to Home\n </Text>\n </Link>\n </View>\n </View>\n </Container>\n </>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n padding: 16,\n },\n content: {\n alignItems: \"center\",\n },\n emoji: {\n fontSize: 48,\n marginBottom: 16,\n },\n title: {\n fontSize: 20,\n fontWeight: \"bold\",\n marginBottom: 8,\n textAlign: \"center\",\n },\n subtitle: {\n fontSize: 14,\n textAlign: \"center\",\n marginBottom: 24,\n },\n link: {\n padding: 12,\n },\n});\n\n`],\n [\"frontend/native/bare/app/modal.tsx.hbs\", `import { Container } from \"@/components/container\";\nimport { Text, View, StyleSheet } from \"react-native\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\n\nexport default function Modal() {\n const { colorScheme } = useColorScheme();\n const theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\n\n return (\n <Container>\n <View style={styles.container}>\n <View style={styles.header}>\n <Text style={[styles.title, { color: theme.text }]}>Modal</Text>\n </View>\n </View>\n </Container>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n padding: 16,\n },\n header: {\n marginBottom: 16,\n },\n title: {\n fontSize: 20,\n fontWeight: \"bold\",\n },\n});\n\n`],\n [\"frontend/native/bare/app/_layout.tsx.hbs\", `{{#if (includes examples \"ai\")}}\nimport \"@/polyfills\";\n{{/if}}\n\n{{#if (eq backend \"convex\")}}\n {{#if (eq auth \"better-auth\")}}\n import { ConvexReactClient } from \"convex/react\";\n import { ConvexBetterAuthProvider } from \"@convex-dev/better-auth/react\";\n import { authClient } from \"@/lib/auth-client\";\n import { env } from \"@{{projectName}}/env/native\";\n {{else}}\n import { ConvexProvider, ConvexReactClient } from \"convex/react\";\n import { env } from \"@{{projectName}}/env/native\";\n {{/if}}\n {{#if (eq auth \"clerk\")}}\n import { ClerkProvider, useAuth } from \"@clerk/clerk-expo\";\n import { ConvexProviderWithClerk } from \"convex/react-clerk\";\n import { tokenCache } from \"@clerk/clerk-expo/token-cache\";\n {{/if}}\n{{else}}\n {{#unless (eq api \"none\")}}\n import { QueryClientProvider } from \"@tanstack/react-query\";\n {{/unless}}\n{{/if}}\n\nimport { Stack } from \"expo-router\";\nimport {\n DarkTheme,\n DefaultTheme,\n type Theme,\n ThemeProvider,\n} from \"@react-navigation/native\";\nimport { StatusBar } from \"expo-status-bar\";\nimport { GestureHandlerRootView } from \"react-native-gesture-handler\";\n{{#if (eq api \"trpc\")}}\nimport { queryClient } from \"@/utils/trpc\";\n{{/if}}\n{{#if (eq api \"orpc\")}}\nimport { queryClient } from \"@/utils/orpc\";\n{{/if}}\nimport { NAV_THEME } from \"@/lib/constants\";\nimport React, { useRef } from \"react\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { Platform, StyleSheet } from \"react-native\";\nimport { setAndroidNavigationBar } from \"@/lib/android-navigation-bar\";\n\nconst LIGHT_THEME: Theme = {\n ...DefaultTheme,\n colors: NAV_THEME.light,\n};\nconst DARK_THEME: Theme = {\n ...DarkTheme,\n colors: NAV_THEME.dark,\n};\n\nexport const unstable_settings = {\n initialRouteName: \"(drawer)\",\n};\n\n{{#if (eq backend \"convex\")}}\nconst convex = new ConvexReactClient(env.EXPO_PUBLIC_CONVEX_URL, {\n unsavedChangesWarning: false,\n});\n{{/if}}\n\nconst useIsomorphicLayoutEffect =\n Platform.OS === \"web\" && typeof window === \"undefined\"\n ? React.useEffect\n : React.useLayoutEffect;\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n },\n});\n\nexport default function RootLayout() {\n const hasMounted = useRef(false);\n const { colorScheme, isDarkColorScheme } = useColorScheme();\n const [isColorSchemeLoaded, setIsColorSchemeLoaded] = React.useState(false);\n\n useIsomorphicLayoutEffect(() => {\n if (hasMounted.current) {\n return;\n }\n setAndroidNavigationBar(colorScheme);\n setIsColorSchemeLoaded(true);\n hasMounted.current = true;\n }, []);\n\n if (!isColorSchemeLoaded) {\n return null;\n }\n\n return (\n <>\n {{#if (eq backend \"convex\")}}\n {{#if (eq auth \"clerk\")}}\n <ClerkProvider tokenCache={tokenCache} publishableKey={env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY}>\n <ConvexProviderWithClerk client={convex} useAuth={useAuth}>\n <ThemeProvider value={isDarkColorScheme ? DARK_THEME : LIGHT_THEME}>\n <StatusBar style={isDarkColorScheme ? \"light\" : \"dark\"} />\n <GestureHandlerRootView style={styles.container}>\n <Stack>\n <Stack.Screen name=\"(drawer)\" options=\\\\{{ headerShown: false }} />\n <Stack.Screen name=\"(auth)\" options=\\\\{{ headerShown: false }} />\n <Stack.Screen name=\"modal\" options=\\\\{{ title: \"Modal\", presentation: \"modal\" }} />\n </Stack>\n </GestureHandlerRootView>\n </ThemeProvider>\n </ConvexProviderWithClerk>\n </ClerkProvider>\n {{else if (eq auth \"better-auth\")}}\n <ConvexBetterAuthProvider client={convex} authClient={authClient}>\n <ThemeProvider value={isDarkColorScheme ? DARK_THEME : LIGHT_THEME}>\n <StatusBar style={isDarkColorScheme ? \"light\" : \"dark\"} />\n <GestureHandlerRootView style={styles.container}>\n <Stack>\n <Stack.Screen name=\"(drawer)\" options=\\\\{{ headerShown: false }} />\n <Stack.Screen name=\"modal\" options=\\\\{{ title: \"Modal\", presentation: \"modal\" }} />\n </Stack>\n </GestureHandlerRootView>\n </ThemeProvider>\n </ConvexBetterAuthProvider>\n {{else}}\n <ConvexProvider client={convex}>\n <ThemeProvider value={isDarkColorScheme ? DARK_THEME : LIGHT_THEME}>\n <StatusBar style={isDarkColorScheme ? \"light\" : \"dark\"} />\n <GestureHandlerRootView style={styles.container}>\n <Stack>\n <Stack.Screen name=\"(drawer)\" options=\\\\{{ headerShown: false }} />\n <Stack.Screen name=\"modal\" options=\\\\{{ title: \"Modal\", presentation: \"modal\" }} />\n </Stack>\n </GestureHandlerRootView>\n </ThemeProvider>\n </ConvexProvider>\n {{/if}}\n {{else}}\n {{#unless (eq api \"none\")}}\n <QueryClientProvider client={queryClient}>\n <ThemeProvider value={isDarkColorScheme ? DARK_THEME : LIGHT_THEME}>\n <StatusBar style={isDarkColorScheme ? \"light\" : \"dark\"} />\n <GestureHandlerRootView style={styles.container}>\n <Stack>\n <Stack.Screen name=\"(drawer)\" options=\\\\{{ headerShown: false }} />\n <Stack.Screen name=\"modal\" options=\\\\{{ title: \"Modal\", presentation: \"modal\" }} />\n </Stack>\n </GestureHandlerRootView>\n </ThemeProvider>\n </QueryClientProvider>\n {{else}}\n <ThemeProvider value={isDarkColorScheme ? DARK_THEME : LIGHT_THEME}>\n <StatusBar style={isDarkColorScheme ? \"light\" : \"dark\"} />\n <GestureHandlerRootView style={styles.container}>\n <Stack>\n <Stack.Screen name=\"(drawer)\" options=\\\\{{ headerShown: false }} />\n <Stack.Screen name=\"modal\" options=\\\\{{ title: \"Modal\", presentation: \"modal\" }} />\n </Stack>\n </GestureHandlerRootView>\n </ThemeProvider>\n {{/unless}}\n {{/if}}\n </>\n );\n}`],\n [\"db/kysely/mysql/src/index.ts.hbs\", `import { env } from \"@{{projectName}}/env/server\";\nimport { Kysely, MysqlDialect } from \"kysely\";\nimport { createPool } from \"mysql2\";\nimport type { Database as DB } from \"./schema\";\n\n{{#if (eq dbSetup \"planetscale\")}}\nconst dialect = new MysqlDialect({\n\tpool: createPool({\n\t\thost: env.DATABASE_HOST,\n\t\tuser: env.DATABASE_USERNAME,\n\t\tpassword: env.DATABASE_PASSWORD,\n\t\tdatabase: env.DATABASE_NAME,\n\t\tssl: {\n\t\t\trejectUnauthorized: true,\n\t\t},\n\t}),\n});\n{{else}}\nconst dialect = new MysqlDialect({\n\tpool: createPool(env.DATABASE_URL),\n});\n{{/if}}\n\nexport const db = new Kysely<DB>({\n\tdialect,\n});\n`],\n [\"frontend/native/uniwind/contexts/app-theme-context.tsx.hbs\", `import React, { createContext, useCallback, useContext, useMemo } from 'react';\nimport { Uniwind, useUniwind } from 'uniwind';\n\ntype ThemeName = 'light' | 'dark';\n\ntype AppThemeContextType = {\n currentTheme: string;\n isLight: boolean;\n isDark: boolean;\n setTheme: (theme: ThemeName) => void;\n toggleTheme: () => void;\n}\n\nconst AppThemeContext = createContext<AppThemeContextType | undefined>(\n undefined\n);\n\nexport const AppThemeProvider = ({ children }: { children: React.ReactNode }) => {\n const { theme } = useUniwind();\n\n const isLight = useMemo(() => {\n return theme === 'light';\n }, [theme]);\n\n const isDark = useMemo(() => {\n return theme === 'dark';\n }, [theme]);\n\n const setTheme = useCallback((newTheme: ThemeName) => {\n Uniwind.setTheme(newTheme);\n }, []);\n\n const toggleTheme = useCallback(() => {\n Uniwind.setTheme(theme === 'light' ? 'dark' : 'light');\n }, [theme]);\n\n const value = useMemo(\n () => ({\n currentTheme: theme,\n isLight,\n isDark,\n setTheme,\n toggleTheme,\n }),\n [theme, isLight, isDark, setTheme, toggleTheme]\n );\n\n return (\n <AppThemeContext.Provider value={value}>\n {children}\n </AppThemeContext.Provider>\n );\n};\n\nexport function useAppTheme() {\n const context = useContext(AppThemeContext);\n if (!context) {\n throw new Error('useAppTheme must be used within AppThemeProvider');\n }\n return context;\n}\n\n`],\n [\"db/prisma/mongodb/src/index.ts.hbs\", `import { PrismaClient } from \"../prisma/generated/client\";\n\nconst prisma = new PrismaClient();\n\nexport default prisma;\n`],\n [\"frontend/native/uniwind/app/+not-found.tsx.hbs\", `import { Link, Stack } from \"expo-router\";\nimport { Button, Surface } from \"heroui-native\";\nimport { Text, View } from \"react-native\";\n\nimport { Container } from \"@/components/container\";\n\nexport default function NotFoundScreen() {\n\treturn (\n\t\t<>\n\t\t\t<Stack.Screen options=\\\\{{ title: \"Not Found\" }} />\n\t\t\t<Container>\n\t\t\t\t<View className=\"flex-1 justify-center items-center p-4\">\n\t\t\t\t\t<Surface variant=\"secondary\" className=\"items-center p-6 max-w-sm rounded-lg\">\n\t\t\t\t\t\t<Text className=\"text-4xl mb-3\">🤔</Text>\n\t\t\t\t\t\t<Text className=\"text-foreground font-medium text-lg mb-1\">Page Not Found</Text>\n\t\t\t\t\t\t<Text className=\"text-muted text-sm text-center mb-4\">\n\t\t\t\t\t\t\tThe page you're looking for doesn't exist.\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t<Link href=\"/\" asChild>\n\t\t\t\t\t\t\t<Button size=\"sm\">Go Home</Button>\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t</Surface>\n\t\t\t\t</View>\n\t\t\t</Container>\n\t\t</>\n\t);\n}\n`],\n [\"frontend/native/uniwind/app/modal.tsx.hbs\", `import { Ionicons } from \"@expo/vector-icons\";\nimport { router } from \"expo-router\";\nimport { Button, Surface, useThemeColor } from \"heroui-native\";\nimport { Text, View } from \"react-native\";\n\nimport { Container } from \"@/components/container\";\n\nfunction Modal() {\n\tconst accentForegroundColor = useThemeColor(\"accent-foreground\");\n\n\tfunction handleClose() {\n\t\trouter.back();\n\t}\n\n\treturn (\n\t\t<Container>\n\t\t\t<View className=\"flex-1 justify-center items-center p-4\">\n\t\t\t\t<Surface variant=\"secondary\" className=\"p-5 w-full max-w-sm rounded-lg\">\n\t\t\t\t\t<View className=\"items-center\">\n\t\t\t\t\t\t<View className=\"w-12 h-12 bg-accent rounded-lg items-center justify-center mb-3\">\n\t\t\t\t\t\t\t<Ionicons name=\"checkmark\" size={24} color={accentForegroundColor} />\n\t\t\t\t\t\t</View>\n\t\t\t\t\t\t<Text className=\"text-foreground font-medium text-lg mb-1\">Modal Screen</Text>\n\t\t\t\t\t\t<Text className=\"text-muted text-sm text-center mb-4\">\n\t\t\t\t\t\t\tThis is an example modal screen for dialogs and confirmations.\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t</View>\n\t\t\t\t\t<Button onPress={handleClose} className=\"w-full\" size=\"sm\">\n\t\t\t\t\t\t<Button.Label>Close</Button.Label>\n\t\t\t\t\t</Button>\n\t\t\t\t</Surface>\n\t\t\t</View>\n\t\t</Container>\n\t);\n}\n\nexport default Modal;\n`],\n [\"frontend/native/uniwind/app/_layout.tsx.hbs\", `{{#if (includes examples \"ai\")}}\nimport \"@/polyfills\";\n{{/if}}\n\nimport \"@/global.css\";\n\n{{#if (eq backend \"convex\")}}\n {{#if (eq auth \"better-auth\")}}\n import { ConvexReactClient } from \"convex/react\";\n import { ConvexBetterAuthProvider } from \"@convex-dev/better-auth/react\";\n import { authClient } from \"@/lib/auth-client\";\n import { env } from \"@{{projectName}}/env/native\";\n {{else}}\n import { ConvexProvider, ConvexReactClient } from \"convex/react\";\n import { env } from \"@{{projectName}}/env/native\";\n {{/if}}\n\n {{#if (eq auth \"clerk\")}}\n import { ClerkProvider, useAuth } from \"@clerk/clerk-expo\";\n import { ConvexProviderWithClerk } from \"convex/react-clerk\";\n import { tokenCache } from \"@clerk/clerk-expo/token-cache\";\n {{/if}}\n{{else}}\n {{#unless (eq api \"none\")}}\n import { QueryClientProvider } from \"@tanstack/react-query\";\n {{/unless}}\n{{/if}}\n\nimport { Stack } from \"expo-router\";\nimport { HeroUINativeProvider } from \"heroui-native\";\nimport { GestureHandlerRootView } from \"react-native-gesture-handler\";\nimport { KeyboardProvider } from \"react-native-keyboard-controller\";\nimport { AppThemeProvider } from \"@/contexts/app-theme-context\";\n\n{{#if (eq api \"trpc\")}}\n import { queryClient } from \"@/utils/trpc\";\n{{/if}}\n{{#if (eq api \"orpc\")}}\n import { queryClient } from \"@/utils/orpc\";\n{{/if}}\n\nexport const unstable_settings = {\n initialRouteName: \"(drawer)\",\n};\n\n{{#if (eq backend \"convex\")}}\n const convex = new ConvexReactClient(env.EXPO_PUBLIC_CONVEX_URL, {\n unsavedChangesWarning: false,\n });\n{{/if}}\n\nfunction StackLayout() {\n return (\n <Stack screenOptions=\\\\{{}}>\n <Stack.Screen name=\"(drawer)\" options=\\\\{{ headerShown: false }} />\n {{#if (eq auth \"clerk\")}}\n <Stack.Screen name=\"(auth)\" options=\\\\{{ headerShown: false }} />\n {{/if}}\n <Stack.Screen name=\"modal\" options=\\\\{{ title: \"Modal\", presentation: \"modal\" }} />\n </Stack>\n );\n}\n\nexport default function Layout() {\n return (\n {{#if (eq backend \"convex\")}}\n {{#if (eq auth \"clerk\")}}\n <ClerkProvider tokenCache={tokenCache} publishableKey={env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY}>\n <ConvexProviderWithClerk client={convex} useAuth={useAuth}>\n <GestureHandlerRootView style=\\\\{{ flex: 1 }}>\n <KeyboardProvider>\n <AppThemeProvider>\n <HeroUINativeProvider>\n <StackLayout />\n </HeroUINativeProvider>\n </AppThemeProvider>\n </KeyboardProvider>\n </GestureHandlerRootView>\n </ConvexProviderWithClerk>\n </ClerkProvider>\n {{else if (eq auth \"better-auth\")}}\n <ConvexBetterAuthProvider client={convex} authClient={authClient}>\n <GestureHandlerRootView style=\\\\{{ flex: 1 }}>\n <KeyboardProvider>\n <AppThemeProvider>\n <HeroUINativeProvider>\n <StackLayout />\n </HeroUINativeProvider>\n </AppThemeProvider>\n </KeyboardProvider>\n </GestureHandlerRootView>\n </ConvexBetterAuthProvider>\n {{else}}\n <ConvexProvider client={convex}>\n <GestureHandlerRootView style=\\\\{{ flex: 1 }}>\n <KeyboardProvider>\n <AppThemeProvider>\n <HeroUINativeProvider>\n <StackLayout />\n </HeroUINativeProvider>\n </AppThemeProvider>\n </KeyboardProvider>\n </GestureHandlerRootView>\n </ConvexProvider>\n {{/if}}\n {{else}}\n {{#unless (eq api \"none\")}}\n <QueryClientProvider client={queryClient}>\n <GestureHandlerRootView style=\\\\{{ flex: 1 }}>\n <KeyboardProvider>\n <AppThemeProvider>\n <HeroUINativeProvider>\n <StackLayout />\n </HeroUINativeProvider>\n </AppThemeProvider>\n </KeyboardProvider>\n </GestureHandlerRootView>\n </QueryClientProvider>\n {{else}}\n <GestureHandlerRootView style=\\\\{{ flex: 1 }}>\n <KeyboardProvider>\n <AppThemeProvider>\n <HeroUINativeProvider>\n <StackLayout />\n </HeroUINativeProvider>\n </AppThemeProvider>\n </KeyboardProvider>\n </GestureHandlerRootView>\n {{/unless}}\n {{/if}}\n );\n}`],\n [\"db/drizzle/postgres/src/index.ts.hbs\", `{{#if (or (eq runtime \"bun\") (eq runtime \"node\") (eq runtime \"none\"))}}\nimport { env } from \"@{{projectName}}/env/server\";\nimport * as schema from \"./schema\";\n\n{{#if (eq dbSetup \"neon\")}}\nimport { neon, neonConfig } from '@neondatabase/serverless';\nimport { drizzle } from 'drizzle-orm/neon-http';\nimport ws from \"ws\";\n\nneonConfig.webSocketConstructor = ws;\n\n// To work in edge environments (Cloudflare Workers, Vercel Edge, etc.), enable querying over fetch\n// neonConfig.poolQueryViaFetch = true\n\nconst sql = neon(env.DATABASE_URL);\nexport const db = drizzle(sql, { schema });\n{{else}}\nimport { drizzle } from \"drizzle-orm/node-postgres\";\n\nexport const db = drizzle(env.DATABASE_URL, { schema });\n{{/if}}\n{{/if}}\n\n{{#if (eq runtime \"workers\")}}\nimport * as schema from \"./schema\";\n\n{{#if (eq dbSetup \"neon\")}}\nimport { neon, neonConfig } from '@neondatabase/serverless';\nimport { drizzle } from 'drizzle-orm/neon-http';\nimport { env } from \"@{{projectName}}/env/server\";\nimport ws from \"ws\";\n\nneonConfig.webSocketConstructor = ws;\nneonConfig.poolQueryViaFetch = true;\n\nconst sql = neon(env.DATABASE_URL || \"\");\nexport const db = drizzle(sql, { schema });\n{{else}}\nimport { drizzle } from \"drizzle-orm/node-postgres\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nexport const db = drizzle(env.DATABASE_URL || \"\", { schema });\n{{/if}}\n{{/if}}`],\n [\"db/drizzle/mysql/src/index.ts.hbs\", `{{#if (or (eq runtime \"bun\") (eq runtime \"node\") (eq runtime \"none\"))}}\nimport { env } from \"@{{projectName}}/env/server\";\nimport * as schema from \"./schema\";\n\n{{#if (eq dbSetup \"planetscale\")}}\nimport { drizzle } from \"drizzle-orm/planetscale-serverless\";\n\nexport const db = drizzle({\n\tconnection: {\n\t\thost: env.DATABASE_HOST,\n\t\tusername: env.DATABASE_USERNAME,\n\t\tpassword: env.DATABASE_PASSWORD,\n\t},\n\tschema,\n});\n{{else}}\nimport { drizzle } from \"drizzle-orm/mysql2\";\n\nexport const db = drizzle({\n\tconnection: {\n\t\turi: env.DATABASE_URL,\n\t},\n\tschema,\n});\n{{/if}}\n{{/if}}\n\n{{#if (eq runtime \"workers\")}}\nimport * as schema from \"./schema\";\n\n{{#if (eq dbSetup \"planetscale\")}}\nimport { drizzle } from \"drizzle-orm/planetscale-serverless\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nexport const db = drizzle({\n\tconnection: {\n\t\thost: env.DATABASE_HOST,\n\t\tusername: env.DATABASE_USERNAME,\n\t\tpassword: env.DATABASE_PASSWORD,\n\t},\n\tschema,\n});\n{{else}}\nimport { drizzle } from \"drizzle-orm/mysql2\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nexport const db = drizzle({\n\tconnection: {\n\t\turi: env.DATABASE_URL,\n\t},\n\tschema,\n});\n{{/if}}\n{{/if}}\n`],\n [\"db/prisma/postgres/src/index.ts.hbs\", `{{#if (eq runtime \"workers\")}}\nimport { PrismaClient } from \"../prisma/generated/client\";\nimport { env } from \"@{{projectName}}/env/server\";\n{{#if (eq dbSetup \"neon\")}}\nimport { PrismaNeon } from \"@prisma/adapter-neon\";\nimport { neonConfig } from \"@neondatabase/serverless\";\n\nneonConfig.poolQueryViaFetch = true;\n\nconst prisma = new PrismaClient({\n\tadapter: new PrismaNeon({\n\t\tconnectionString: env.DATABASE_URL,\n\t}),\n});\n\n{{else if (eq dbSetup \"prisma-postgres\")}}\nimport { PrismaPg } from \"@prisma/adapter-pg\";\n\nconst adapter = new PrismaPg({\n\tconnectionString: env.DATABASE_URL,\n});\n\nconst prisma = new PrismaClient({ adapter });\n\n{{else}}\nimport { PrismaPg } from \"@prisma/adapter-pg\";\n\nconst adapter = new PrismaPg({ connectionString: env.DATABASE_URL });\nconst prisma = new PrismaClient({ adapter });\n\n{{/if}}\n\nexport default prisma;\n{{else}}\nimport { PrismaClient } from \"../prisma/generated/client\";\nimport { env } from \"@{{projectName}}/env/server\";\n{{#if (eq dbSetup \"neon\")}}\nimport { PrismaNeon } from \"@prisma/adapter-neon\";\nimport { neonConfig } from \"@neondatabase/serverless\";\nimport ws from \"ws\";\n\nneonConfig.webSocketConstructor = ws;\nneonConfig.poolQueryViaFetch = true;\n\nconst adapter = new PrismaNeon({\n\tconnectionString: env.DATABASE_URL,\n});\n\nconst prisma = new PrismaClient({ adapter });\n\n{{else if (eq dbSetup \"prisma-postgres\")}}\nimport { PrismaPg } from \"@prisma/adapter-pg\";\n\nconst adapter = new PrismaPg({\n\tconnectionString: env.DATABASE_URL,\n});\n\nconst prisma = new PrismaClient({ adapter });\n\n{{else}}\nimport { PrismaPg } from \"@prisma/adapter-pg\";\n\nconst adapter = new PrismaPg({ connectionString: env.DATABASE_URL });\nconst prisma = new PrismaClient({ adapter });\n\n{{/if}}\n\nexport default prisma;\n{{/if}}`],\n [\"db/prisma/mysql/src/index.ts.hbs\", `{{#if (eq runtime \"workers\")}}\nimport { PrismaClient } from \"../prisma/generated/client\";\nimport { env } from \"@{{projectName}}/env/server\";\n\n{{#if (eq dbSetup \"planetscale\")}}\nimport { PrismaPlanetScale } from \"@prisma/adapter-planetscale\";\n\nconst adapter = new PrismaPlanetScale({ url: env.DATABASE_URL });\nconst prisma = new PrismaClient({ adapter });\n{{else}}\nimport { PrismaMariaDb } from \"@prisma/adapter-mariadb\";\n\nconst databaseUrl: string = env.DATABASE_URL;\nconst url: URL = new URL(databaseUrl);\nconst connectionConfig = {\n\thost: url.hostname,\n\tport: parseInt(url.port || \"3306\"),\n\tuser: url.username,\n\tpassword: url.password,\n\tdatabase: url.pathname.slice(1),\n};\n\nconst adapter = new PrismaMariaDb(connectionConfig);\nconst prisma = new PrismaClient({ adapter });\n{{/if}}\n\nexport default prisma;\n{{else}}\nimport { PrismaClient } from \"../prisma/generated/client\";\nimport { env } from \"@{{projectName}}/env/server\";\n\n{{#if (eq dbSetup \"planetscale\")}}\nimport { PrismaPlanetScale } from \"@prisma/adapter-planetscale\";\n\nconst adapter = new PrismaPlanetScale({ url: env.DATABASE_URL });\nconst prisma = new PrismaClient({ adapter });\n{{else}}\nimport { PrismaMariaDb } from \"@prisma/adapter-mariadb\";\n\nconst databaseUrl: string = env.DATABASE_URL;\nconst url: URL = new URL(databaseUrl);\nconst connectionConfig = {\n\thost: url.hostname,\n\tport: parseInt(url.port || \"3306\"),\n\tuser: url.username,\n\tpassword: url.password,\n\tdatabase: url.pathname.slice(1),\n};\n\nconst adapter = new PrismaMariaDb(connectionConfig);\nconst prisma = new PrismaClient({ adapter });\n{{/if}}\n\nexport default prisma;\n{{/if}}`],\n [\"db/mongoose/mongodb/src/index.ts.hbs\", `import mongoose from \"mongoose\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nawait mongoose.connect(env.DATABASE_URL).catch((error) => {\n\tconsole.log(\"Error connecting to database:\", error);\n});\n\nconst client = mongoose.connection.getClient().db(\"myDB\");\n\nexport { client };\n`],\n [\"db/prisma/sqlite/src/index.ts.hbs\", `import { PrismaClient } from \"../prisma/generated/client\";\n\n{{#if (eq dbSetup \"d1\")}}\nimport { PrismaD1 } from \"@prisma/adapter-d1\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nconst adapter = new PrismaD1(env.DB);\nconst prisma = new PrismaClient({ adapter });\n\nexport default prisma;\n{{else}}\nimport { PrismaLibSql } from \"@prisma/adapter-libsql\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nconst adapter = new PrismaLibSql({\n\turl: env.DATABASE_URL,\n{{#if (eq dbSetup \"turso\")}}\n\tauthToken: env.DATABASE_AUTH_TOKEN || \"\",\n{{/if}}\n});\n\nconst prisma = new PrismaClient({ adapter });\n\nexport default prisma;\n{{/if}}`],\n [\"db/typeorm/sqlite/src/index.ts.hbs\", `import \"reflect-metadata\";\nimport { DataSource } from \"typeorm\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nexport const AppDataSource = new DataSource({\n\ttype: \"better-sqlite3\",\n\tdatabase: env.DATABASE_URL.replace(\"file:\", \"\"),\n\tsynchronize: true,\n\tlogging: false,\n\tentities: [\"src/entities/**/*.ts\"],\n\tmigrations: [\"src/migrations/**/*.ts\"],\n\tsubscribers: [\"src/subscribers/**/*.ts\"],\n});\n\nexport const initializeDatabase = async () => {\n\tif (!AppDataSource.isInitialized) {\n\t\tawait AppDataSource.initialize();\n\t}\n\treturn AppDataSource;\n};\n\nexport const db = AppDataSource;\n`],\n [\"db/drizzle/sqlite/src/index.ts.hbs\", `{{#if (or (eq runtime \"bun\") (eq runtime \"node\") (eq runtime \"none\"))}}\nimport { env } from \"@{{projectName}}/env/server\";\nimport * as schema from \"./schema\";\nimport { drizzle } from \"drizzle-orm/libsql\";\nimport { createClient } from \"@libsql/client\";\n\nconst client = createClient({\n\turl: env.DATABASE_URL,\n{{#if (eq dbSetup \"turso\")}}\n\tauthToken: env.DATABASE_AUTH_TOKEN,\n{{/if}}\n});\n\nexport const db = drizzle({ client, schema });\n{{/if}}\n\n{{#if (eq runtime \"workers\")}}\nimport * as schema from \"./schema\";\n\n{{#if (eq dbSetup \"d1\")}}\nimport { drizzle } from \"drizzle-orm/d1\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nexport const db = drizzle(env.DB, { schema });\n{{else}}\nimport { drizzle } from \"drizzle-orm/libsql\";\nimport { env } from \"@{{projectName}}/env/server\";\nimport { createClient } from \"@libsql/client\";\n\nconst client = createClient({\n\turl: env.DATABASE_URL || \"\",\n{{#if (eq dbSetup \"turso\")}}\n\tauthToken: env.DATABASE_AUTH_TOKEN,\n{{/if}}\n});\n\nexport const db = drizzle({ client, schema });\n{{/if}}\n{{/if}}\n`],\n [\"db/typeorm/postgres/src/index.ts.hbs\", `import \"reflect-metadata\";\nimport { DataSource } from \"typeorm\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nexport const AppDataSource = new DataSource({\n\ttype: \"postgres\",\n\turl: env.DATABASE_URL,\n\tsynchronize: true,\n\tlogging: false,\n\tentities: [\"src/entities/**/*.ts\"],\n\tmigrations: [\"src/migrations/**/*.ts\"],\n\tsubscribers: [\"src/subscribers/**/*.ts\"],\n{{#if (eq dbSetup \"neon\")}}\n\tssl: {\n\t\trejectUnauthorized: false,\n\t},\n{{/if}}\n});\n\nexport const initializeDatabase = async () => {\n\tif (!AppDataSource.isInitialized) {\n\t\tawait AppDataSource.initialize();\n\t}\n\treturn AppDataSource;\n};\n\nexport const db = AppDataSource;\n`],\n [\"db/typeorm/mysql/src/index.ts.hbs\", `import \"reflect-metadata\";\nimport { DataSource } from \"typeorm\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nexport const AppDataSource = new DataSource({\n\ttype: \"mysql\",\n\turl: env.DATABASE_URL,\n\tsynchronize: true,\n\tlogging: false,\n\tentities: [\"src/entities/**/*.ts\"],\n\tmigrations: [\"src/migrations/**/*.ts\"],\n\tsubscribers: [\"src/subscribers/**/*.ts\"],\n{{#if (eq dbSetup \"planetscale\")}}\n\tssl: {\n\t\trejectUnauthorized: false,\n\t},\n{{/if}}\n});\n\nexport const initializeDatabase = async () => {\n\tif (!AppDataSource.isInitialized) {\n\t\tawait AppDataSource.initialize();\n\t}\n\treturn AppDataSource;\n};\n\nexport const db = AppDataSource;\n`],\n [\"api/ts-rest/native/utils/ts-rest.ts.hbs\", `import { QueryClient } from \"@tanstack/react-query\";\nimport { initClient, tsRestFetchApi } from \"@ts-rest/core\";\nimport { initTsrReactQuery } from \"@ts-rest/react-query\";\nimport { contract } from \"@{{projectName}}/api/index\";\nimport { env } from \"@{{projectName}}/env/native\";\n\nexport const queryClient = new QueryClient({\n\tdefaultOptions: {\n\t\tqueries: {\n\t\t\tretry: 2,\n\t\t\tstaleTime: 1000 * 60,\n\t\t},\n\t},\n});\n\nconst client = initClient(contract, {\n\tbaseUrl: \\`\\${env.EXPO_PUBLIC_SERVER_URL}/rest\\`,\n\tbaseHeaders: {},\n{{#if (eq auth \"better-auth\")}}\n\tcredentials: \"include\",\n{{/if}}\n\tapi: tsRestFetchApi,\n});\n\nexport const tsr = initTsrReactQuery(contract, client);\n`],\n [\"api/garph/native/utils/garph.ts.hbs\", `import { QueryClient } from \"@tanstack/react-query\";\nimport { createClient, type InferClient } from \"@garph/gqty\";\nimport {\n createGeneratedSchema,\n createScalarsEnumsHash,\n} from \"@garph/gqty/dist/utils\";\nimport {\n g,\n queryType,\n mutationType,\n{{#if (includes examples \"todo\")}}\n todoType,\n{{/if}}\n} from \"@{{projectName}}/api/index\";\nimport { API_URL } from \"@/lib/api\";\n\n// Create QueryClient for React Query integration\nexport const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n retry: 2,\n staleTime: 1000 * 60,\n },\n },\n});\n\n// Generate schema and scalars for GQty client\nconst generatedSchema = createGeneratedSchema(g);\nconst scalarsEnumsHash = createScalarsEnumsHash(g);\n\n// Create type-safe GraphQL client\nexport const client = createClient<{\n query: InferClient<typeof queryType>;\n mutation: InferClient<typeof mutationType>;\n}>({\n generatedSchema,\n scalarsEnumsHash,\n url: \\`\\${API_URL}/graphql\\`,\n{{#if (eq auth \"better-auth\")}}\n credentials: \"include\",\n{{/if}}\n});\n\n// Export typed query and mutation functions\nexport const { query, mutation, resolved } = client;\n\n// Helper for React Query integration\nexport async function graphqlFetcher<T>(\n fn: () => T | Promise<T>\n): Promise<T> {\n return resolved(fn);\n}\n`],\n [\"db/sequelize/sqlite/src/index.ts.hbs\", `import { Sequelize } from \"sequelize-typescript\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nconst dbPath = env.DATABASE_URL.replace(\"file:\", \"\");\n\nexport const sequelize = new Sequelize({\n\tdialect: \"sqlite\",\n\tstorage: dbPath,\n\tlogging: false,\n\tmodels: [__dirname + \"/models/**/*.ts\"],\n});\n\nexport const initializeDatabase = async () => {\n\tawait sequelize.authenticate();\n\tawait sequelize.sync();\n\treturn sequelize;\n};\n\nexport const db = sequelize;\n`],\n [\"api/ts-rest/server/src/context.ts.hbs\", `{{#if (eq backend \"hono\")}}\nimport type { Context as HonoContext } from \"hono\";\n{{#if (eq auth \"better-auth\")}}\nimport type { Session, User } from \"better-auth\";\n{{/if}}\n\nexport type Context = {\n honoContext: HonoContext;\n{{#if (eq auth \"better-auth\")}}\n session: { user: User; session: Session } | null;\n{{/if}}\n};\n\nexport function createContext(c: HonoContext{{#if (eq auth \"better-auth\")}}, session: { user: User; session: Session } | null{{/if}}): Context {\n return {\n honoContext: c,\n{{#if (eq auth \"better-auth\")}}\n session,\n{{/if}}\n };\n}\n{{else if (eq backend \"elysia\")}}\n{{#if (eq auth \"better-auth\")}}\nimport type { Session, User } from \"better-auth\";\n{{/if}}\n\nexport type Context = {\n{{#if (eq auth \"better-auth\")}}\n session: { user: User; session: Session } | null;\n{{/if}}\n};\n\nexport function createContext({{#if (eq auth \"better-auth\")}}session: { user: User; session: Session } | null{{/if}}): Context {\n return {\n{{#if (eq auth \"better-auth\")}}\n session,\n{{/if}}\n };\n}\n{{else if (eq backend \"express\")}}\nimport type { Request } from \"express\";\n{{#if (eq auth \"better-auth\")}}\nimport type { Session, User } from \"better-auth\";\n{{/if}}\n\nexport type Context = {\n req: Request;\n{{#if (eq auth \"better-auth\")}}\n session: { user: User; session: Session } | null;\n{{/if}}\n};\n\nexport function createContext(req: Request{{#if (eq auth \"better-auth\")}}, session: { user: User; session: Session } | null{{/if}}): Context {\n return {\n req,\n{{#if (eq auth \"better-auth\")}}\n session,\n{{/if}}\n };\n}\n{{else if (eq backend \"fastify\")}}\nimport type { FastifyRequest } from \"fastify\";\n{{#if (eq auth \"better-auth\")}}\nimport type { Session, User } from \"better-auth\";\n{{/if}}\n\nexport type Context = {\n req: FastifyRequest;\n{{#if (eq auth \"better-auth\")}}\n session: { user: User; session: Session } | null;\n{{/if}}\n};\n\nexport function createContext(req: FastifyRequest{{#if (eq auth \"better-auth\")}}, session: { user: User; session: Session } | null{{/if}}): Context {\n return {\n req,\n{{#if (eq auth \"better-auth\")}}\n session,\n{{/if}}\n };\n}\n{{else if (eq backend \"self\")}}\n{{#if (includes frontend \"next\")}}\nimport type { NextRequest } from \"next/server\";\n{{#if (eq auth \"better-auth\")}}\nimport type { Session, User } from \"better-auth\";\n{{/if}}\n\nexport type Context = {\n req: NextRequest;\n{{#if (eq auth \"better-auth\")}}\n session: { user: User; session: Session } | null;\n{{/if}}\n};\n\nexport function createContext(req: NextRequest{{#if (eq auth \"better-auth\")}}, session: { user: User; session: Session } | null{{/if}}): Context {\n return {\n req,\n{{#if (eq auth \"better-auth\")}}\n session,\n{{/if}}\n };\n}\n{{else if (includes frontend \"tanstack-start\")}}\n{{#if (eq auth \"better-auth\")}}\nimport type { Session, User } from \"better-auth\";\n{{/if}}\n\nexport type Context = {\n request: Request;\n{{#if (eq auth \"better-auth\")}}\n session: { user: User; session: Session } | null;\n{{/if}}\n};\n\nexport function createContext(request: Request{{#if (eq auth \"better-auth\")}}, session: { user: User; session: Session } | null{{/if}}): Context {\n return {\n request,\n{{#if (eq auth \"better-auth\")}}\n session,\n{{/if}}\n };\n}\n{{else if (includes frontend \"astro\")}}\nimport type { APIContext } from \"astro\";\n{{#if (eq auth \"better-auth\")}}\nimport type { Session, User } from \"better-auth\";\n{{/if}}\n\nexport type Context = {\n astroContext: APIContext;\n{{#if (eq auth \"better-auth\")}}\n session: { user: User; session: Session } | null;\n{{/if}}\n};\n\nexport function createContext(astroContext: APIContext{{#if (eq auth \"better-auth\")}}, session: { user: User; session: Session } | null{{/if}}): Context {\n return {\n astroContext,\n{{#if (eq auth \"better-auth\")}}\n session,\n{{/if}}\n };\n}\n{{/if}}\n{{/if}}\n`],\n [\"api/ts-rest/server/src/index.ts.hbs\", `import { initContract } from \"@ts-rest/core\";\nimport { z } from \"zod\";\n\nconst c = initContract();\n\nexport const contract = c.router({\n healthCheck: {\n method: \"GET\",\n path: \"/health\",\n responses: {\n 200: z.literal(\"OK\"),\n },\n },\n{{#if (eq auth \"better-auth\")}}\n privateData: {\n method: \"GET\",\n path: \"/private\",\n responses: {\n 200: z.object({\n message: z.string(),\n user: z.object({\n id: z.string(),\n email: z.string(),\n name: z.string().nullable(),\n }),\n }),\n 401: z.object({\n message: z.string(),\n }),\n },\n },\n{{/if}}\n{{#if (includes examples \"todo\")}}\n todos: {\n getAll: {\n method: \"GET\",\n path: \"/todos\",\n responses: {\n 200: z.array(\n z.object({\n id: z.number(),\n content: z.string(),\n completed: z.boolean(),\n createdAt: z.string(),\n })\n ),\n },\n },\n create: {\n method: \"POST\",\n path: \"/todos\",\n body: z.object({\n content: z.string().min(1),\n }),\n responses: {\n 201: z.object({\n id: z.number(),\n content: z.string(),\n completed: z.boolean(),\n createdAt: z.string(),\n }),\n },\n },\n toggle: {\n method: \"PATCH\",\n path: \"/todos/:id/toggle\",\n pathParams: z.object({\n id: z.coerce.number(),\n }),\n body: z.object({}),\n responses: {\n 200: z.object({\n id: z.number(),\n content: z.string(),\n completed: z.boolean(),\n createdAt: z.string(),\n }),\n 404: z.object({\n message: z.string(),\n }),\n },\n },\n delete: {\n method: \"DELETE\",\n path: \"/todos/:id\",\n pathParams: z.object({\n id: z.coerce.number(),\n }),\n body: z.object({}),\n responses: {\n 200: z.object({\n success: z.boolean(),\n }),\n 404: z.object({\n message: z.string(),\n }),\n },\n },\n },\n{{/if}}\n});\n\nexport type AppContract = typeof contract;\n`],\n [\"api/garph/server/src/context.ts.hbs\", `{{#if (eq backend \"hono\")}}\nimport type { Context as HonoContext } from \"hono\";\n{{#if (eq auth \"better-auth\")}}\nimport type { Session, User } from \"better-auth\";\n{{/if}}\n\nexport type Context = {\n honoContext: HonoContext;\n{{#if (eq auth \"better-auth\")}}\n session: { user: User; session: Session } | null;\n{{/if}}\n};\n\nexport function createContext(c: HonoContext{{#if (eq auth \"better-auth\")}}, session: { user: User; session: Session } | null{{/if}}): Context {\n return {\n honoContext: c,\n{{#if (eq auth \"better-auth\")}}\n session,\n{{/if}}\n };\n}\n{{else if (eq backend \"elysia\")}}\n{{#if (eq auth \"better-auth\")}}\nimport type { Session, User } from \"better-auth\";\n{{/if}}\n\nexport type Context = {\n{{#if (eq auth \"better-auth\")}}\n session: { user: User; session: Session } | null;\n{{/if}}\n};\n\nexport function createContext({{#if (eq auth \"better-auth\")}}session: { user: User; session: Session } | null{{/if}}): Context {\n return {\n{{#if (eq auth \"better-auth\")}}\n session,\n{{/if}}\n };\n}\n{{else if (eq backend \"express\")}}\nimport type { Request } from \"express\";\n{{#if (eq auth \"better-auth\")}}\nimport type { Session, User } from \"better-auth\";\n{{/if}}\n\nexport type Context = {\n req: Request;\n{{#if (eq auth \"better-auth\")}}\n session: { user: User; session: Session } | null;\n{{/if}}\n};\n\nexport function createContext(req: Request{{#if (eq auth \"better-auth\")}}, session: { user: User; session: Session } | null{{/if}}): Context {\n return {\n req,\n{{#if (eq auth \"better-auth\")}}\n session,\n{{/if}}\n };\n}\n{{else if (eq backend \"fastify\")}}\nimport type { FastifyRequest } from \"fastify\";\n{{#if (eq auth \"better-auth\")}}\nimport type { Session, User } from \"better-auth\";\n{{/if}}\n\nexport type Context = {\n req: FastifyRequest;\n{{#if (eq auth \"better-auth\")}}\n session: { user: User; session: Session } | null;\n{{/if}}\n};\n\nexport function createContext(req: FastifyRequest{{#if (eq auth \"better-auth\")}}, session: { user: User; session: Session } | null{{/if}}): Context {\n return {\n req,\n{{#if (eq auth \"better-auth\")}}\n session,\n{{/if}}\n };\n}\n{{else if (eq backend \"self\")}}\n{{#if (includes frontend \"next\")}}\nimport type { NextRequest } from \"next/server\";\n{{#if (eq auth \"better-auth\")}}\nimport type { Session, User } from \"better-auth\";\n{{/if}}\n\nexport type Context = {\n req: NextRequest;\n{{#if (eq auth \"better-auth\")}}\n session: { user: User; session: Session } | null;\n{{/if}}\n};\n\nexport function createContext(req: NextRequest{{#if (eq auth \"better-auth\")}}, session: { user: User; session: Session } | null{{/if}}): Context {\n return {\n req,\n{{#if (eq auth \"better-auth\")}}\n session,\n{{/if}}\n };\n}\n{{else if (includes frontend \"tanstack-start\")}}\n{{#if (eq auth \"better-auth\")}}\nimport type { Session, User } from \"better-auth\";\n{{/if}}\n\nexport type Context = {\n request: Request;\n{{#if (eq auth \"better-auth\")}}\n session: { user: User; session: Session } | null;\n{{/if}}\n};\n\nexport function createContext(request: Request{{#if (eq auth \"better-auth\")}}, session: { user: User; session: Session } | null{{/if}}): Context {\n return {\n request,\n{{#if (eq auth \"better-auth\")}}\n session,\n{{/if}}\n };\n}\n{{else if (includes frontend \"astro\")}}\nimport type { APIContext } from \"astro\";\n{{#if (eq auth \"better-auth\")}}\nimport type { Session, User } from \"better-auth\";\n{{/if}}\n\nexport type Context = {\n astroContext: APIContext;\n{{#if (eq auth \"better-auth\")}}\n session: { user: User; session: Session } | null;\n{{/if}}\n};\n\nexport function createContext(astroContext: APIContext{{#if (eq auth \"better-auth\")}}, session: { user: User; session: Session } | null{{/if}}): Context {\n return {\n astroContext,\n{{#if (eq auth \"better-auth\")}}\n session,\n{{/if}}\n };\n}\n{{/if}}\n{{/if}}\n`],\n [\"api/garph/server/src/index.ts.hbs\", `import { g, buildSchema, InferResolvers } from \"garph\";\n\n// Define GraphQL types using Garph's type-safe builder\n{{#if (includes examples \"todo\")}}\nexport const todoType = g.type(\"Todo\", {\n id: g.int(),\n content: g.string(),\n completed: g.boolean(),\n createdAt: g.string(),\n});\n{{/if}}\n\n{{#if (eq auth \"better-auth\")}}\nexport const userType = g.type(\"User\", {\n id: g.string(),\n email: g.string(),\n name: g.string().nullable(),\n});\n\nexport const privateDataType = g.type(\"PrivateData\", {\n message: g.string(),\n user: g.ref(userType),\n});\n{{/if}}\n\nexport const queryType = g.type(\"Query\", {\n health: g.string().description(\"Health check endpoint\"),\n{{#if (eq auth \"better-auth\")}}\n privateData: g.ref(privateDataType).nullable().description(\"Get private data (requires authentication)\"),\n{{/if}}\n{{#if (includes examples \"todo\")}}\n todos: g.ref(todoType).list().description(\"Get all todos\"),\n todo: g\n .ref(todoType)\n .nullable()\n .args({ id: g.int() })\n .description(\"Get a single todo by ID\"),\n{{/if}}\n});\n\nexport const mutationType = g.type(\"Mutation\", {\n{{#if (includes examples \"todo\")}}\n createTodo: g\n .ref(todoType)\n .args({ content: g.string() })\n .description(\"Create a new todo\"),\n toggleTodo: g\n .ref(todoType)\n .nullable()\n .args({ id: g.int() })\n .description(\"Toggle a todo's completed status\"),\n deleteTodo: g\n .boolean()\n .args({ id: g.int() })\n .description(\"Delete a todo\"),\n{{/if}}\n _empty: g.string().nullable().description(\"Placeholder mutation\"),\n});\n\n// Export types for resolver type inference\nexport type QueryType = typeof queryType;\nexport type MutationType = typeof mutationType;\n{{#if (includes examples \"todo\")}}\nexport type TodoType = typeof todoType;\n{{/if}}\n\n// Re-export Garph utilities for use in resolvers\nexport { g, buildSchema, type InferResolvers };\n`],\n [\"db/sequelize/postgres/src/index.ts.hbs\", `import { Sequelize } from \"sequelize-typescript\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nexport const sequelize = new Sequelize(env.DATABASE_URL, {\n\tdialect: \"postgres\",\n\tlogging: false,\n\tmodels: [__dirname + \"/models/**/*.ts\"],\n{{#if (eq dbSetup \"neon\")}}\n\tdialectOptions: {\n\t\tssl: {\n\t\t\trequire: true,\n\t\t\trejectUnauthorized: false,\n\t\t},\n\t},\n{{/if}}\n});\n\nexport const initializeDatabase = async () => {\n\tawait sequelize.authenticate();\n\tawait sequelize.sync();\n\treturn sequelize;\n};\n\nexport const db = sequelize;\n`],\n [\"db/sequelize/mysql/src/index.ts.hbs\", `import { Sequelize } from \"sequelize-typescript\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nexport const sequelize = new Sequelize(env.DATABASE_URL, {\n\tdialect: \"mysql\",\n\tlogging: false,\n\tmodels: [__dirname + \"/models/**/*.ts\"],\n{{#if (eq dbSetup \"planetscale\")}}\n\tdialectOptions: {\n\t\tssl: {\n\t\t\trejectUnauthorized: false,\n\t\t},\n\t},\n{{/if}}\n});\n\nexport const initializeDatabase = async () => {\n\tawait sequelize.authenticate();\n\tawait sequelize.sync();\n\treturn sequelize;\n};\n\nexport const db = sequelize;\n`],\n [\"db/mikroorm/mysql/src/index.ts.hbs\", `import { MikroORM, type Options } from \"@mikro-orm/core\";\nimport { MySqlDriver } from \"@mikro-orm/mysql\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nconst config: Options<MySqlDriver> = {\n\tdriver: MySqlDriver,\n\tclientUrl: env.DATABASE_URL,\n\tentities: [\"./src/entities\"],\n\tentitiesTs: [\"./src/entities\"],\n\tdebug: process.env.NODE_ENV !== \"production\",\n{{#if (eq dbSetup \"planetscale\")}}\n\tdriverOptions: {\n\t\tconnection: {\n\t\t\tssl: {\n\t\t\t\trejectUnauthorized: false,\n\t\t\t},\n\t\t},\n\t},\n{{/if}}\n};\n\nlet orm: MikroORM<MySqlDriver> | null = null;\n\nexport const initializeDatabase = async () => {\n\tif (!orm) {\n\t\torm = await MikroORM.init(config);\n\t}\n\treturn orm;\n};\n\nexport const getEntityManager = async () => {\n\tconst db = await initializeDatabase();\n\treturn db.em.fork();\n};\n\nexport const db = {\n\tgetORM: initializeDatabase,\n\tgetEM: getEntityManager,\n};\n`],\n [\"db/mikroorm/postgres/src/index.ts.hbs\", `import { MikroORM, type Options } from \"@mikro-orm/core\";\nimport { PostgreSqlDriver } from \"@mikro-orm/postgresql\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nconst config: Options<PostgreSqlDriver> = {\n\tdriver: PostgreSqlDriver,\n\tclientUrl: env.DATABASE_URL,\n\tentities: [\"./src/entities\"],\n\tentitiesTs: [\"./src/entities\"],\n\tdebug: process.env.NODE_ENV !== \"production\",\n{{#if (eq dbSetup \"neon\")}}\n\tdriverOptions: {\n\t\tconnection: {\n\t\t\tssl: {\n\t\t\t\trejectUnauthorized: false,\n\t\t\t},\n\t\t},\n\t},\n{{/if}}\n};\n\nlet orm: MikroORM<PostgreSqlDriver> | null = null;\n\nexport const initializeDatabase = async () => {\n\tif (!orm) {\n\t\torm = await MikroORM.init(config);\n\t}\n\treturn orm;\n};\n\nexport const getEntityManager = async () => {\n\tconst db = await initializeDatabase();\n\treturn db.em.fork();\n};\n\nexport const db = {\n\tgetORM: initializeDatabase,\n\tgetEM: getEntityManager,\n};\n`],\n [\"backend/server/express/src/index.ts.hbs\", `import { env } from \"@{{projectName}}/env/server\";\n{{#if (eq api \"trpc\")}}\nimport { createExpressMiddleware } from \"@trpc/server/adapters/express\";\nimport { createContext } from \"@{{projectName}}/api/context\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\n{{/if}}\n{{#if (eq api \"orpc\")}}\nimport { OpenAPIHandler } from \"@orpc/openapi/node\";\nimport { OpenAPIReferencePlugin } from \"@orpc/openapi/plugins\";\nimport { ZodToJsonSchemaConverter } from \"@orpc/zod/zod4\";\nimport { RPCHandler } from \"@orpc/server/node\";\nimport { onError } from \"@orpc/server\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\n{{#if (eq auth \"better-auth\")}}\nimport { createContext } from \"@{{projectName}}/api/context\";\n{{/if}}\n{{/if}}\nimport cors from \"cors\";\nimport express from \"express\";\n{{#if (includes examples \"ai\")}}\nimport { streamText, type UIMessage, convertToModelMessages, wrapLanguageModel } from \"ai\";\nimport { google } from \"@ai-sdk/google\";\nimport { devToolsMiddleware } from \"@ai-sdk/devtools\";\n{{/if}}\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\nimport { toNodeHandler } from \"better-auth/node\";\n{{/if}}\n\nconst app = express();\n\napp.use(\n\tcors({\n\t\torigin: env.CORS_ORIGIN,\n\t\tmethods: [\"GET\", \"POST\", \"OPTIONS\"],\n{{#if (eq auth \"better-auth\")}}\n\t\tallowedHeaders: [\"Content-Type\", \"Authorization\"],\n\t\tcredentials: true,\n{{/if}}\n\t})\n);\n\n{{#if (eq auth \"better-auth\")}}\napp.all(\"/api/auth{/*path}\", toNodeHandler(auth));\n{{/if}}\n\n{{#if (eq api \"trpc\")}}\napp.use(\n\t\"/trpc\",\n\tcreateExpressMiddleware({\n\t\trouter: appRouter,\n\t\tcreateContext,\n\t})\n);\n{{/if}}\n\n{{#if (eq api \"orpc\")}}\nconst rpcHandler = new RPCHandler(appRouter, {\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\nconst apiHandler = new OpenAPIHandler(appRouter, {\n\tplugins: [\n\t\tnew OpenAPIReferencePlugin({\n\t\t\tschemaConverters: [new ZodToJsonSchemaConverter()],\n\t\t}),\n\t],\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\n\napp.use(async (req, res, next) => {\n\tconst rpcResult = await rpcHandler.handle(req, res, {\n\t\tprefix: \"/rpc\",\n{{#if (eq auth \"better-auth\")}}\n\t\tcontext: await createContext({ req }),\n{{else}}\n\t\tcontext: {},\n{{/if}}\n\t});\n\tif (rpcResult.matched) return;\n\n\tconst apiResult = await apiHandler.handle(req, res, {\n\t\tprefix: \"/api-reference\",\n{{#if (eq auth \"better-auth\")}}\n\t\tcontext: await createContext({ req }),\n{{else}}\n\t\tcontext: {},\n{{/if}}\n\t});\n\tif (apiResult.matched) return;\n\n\tnext();\n});\n{{/if}}\n\napp.use(express.json());\n\n{{#if (includes examples \"ai\")}}\napp.post(\"/ai\", async (req, res) => {\n\tconst { messages = [] } = (req.body || {}) as { messages: UIMessage[] };\n\tconst model = wrapLanguageModel({\n\t\tmodel: google(\"gemini-2.5-flash\"),\n\t\tmiddleware: devToolsMiddleware(),\n\t});\n\tconst result = streamText({\n\t\tmodel,\n\t\tmessages: await convertToModelMessages(messages),\n\t});\n\tresult.pipeUIMessageStreamToResponse(res);\n});\n{{/if}}\n\napp.get(\"/\", (_req, res) => {\n\tres.status(200).send(\"OK\");\n});\n\napp.listen(3000, () => {\n\tconsole.log(\"Server is running on http://localhost:3000\");\n});\n`],\n [\"db/mikroorm/sqlite/src/index.ts.hbs\", `import { MikroORM, type Options } from \"@mikro-orm/core\";\nimport { BetterSqliteDriver } from \"@mikro-orm/better-sqlite\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nconst config: Options<BetterSqliteDriver> = {\n\tdriver: BetterSqliteDriver,\n\tdbName: env.DATABASE_URL.replace(\"file:\", \"\"),\n\tentities: [\"./src/entities\"],\n\tentitiesTs: [\"./src/entities\"],\n\tdebug: process.env.NODE_ENV !== \"production\",\n};\n\nlet orm: MikroORM<BetterSqliteDriver> | null = null;\n\nexport const initializeDatabase = async () => {\n\tif (!orm) {\n\t\torm = await MikroORM.init(config);\n\t}\n\treturn orm;\n};\n\nexport const getEntityManager = async () => {\n\tconst db = await initializeDatabase();\n\treturn db.em.fork();\n};\n\nexport const db = {\n\tgetORM: initializeDatabase,\n\tgetEM: getEntityManager,\n};\n`],\n [\"backend/server/nestjs/src/app.module.ts.hbs\", `import { Module } from \"@nestjs/common\";\nimport { AppController } from \"./app.controller\";\nimport { AppService } from \"./app.service\";\n{{#if (eq api \"trpc\")}}\nimport { TrpcModule } from \"./trpc/trpc.module\";\n{{/if}}\n{{#if (eq api \"orpc\")}}\nimport { OrpcModule } from \"./orpc/orpc.module\";\n{{/if}}\n{{#if (includes examples \"ai\")}}\nimport { AiModule } from \"./ai/ai.module\";\n{{/if}}\n\n@Module({\n\timports: [\n{{#if (eq api \"trpc\")}}\n\t\tTrpcModule,\n{{/if}}\n{{#if (eq api \"orpc\")}}\n\t\tOrpcModule,\n{{/if}}\n{{#if (includes examples \"ai\")}}\n\t\tAiModule,\n{{/if}}\n\t],\n\tcontrollers: [AppController],\n\tproviders: [AppService],\n})\nexport class AppModule {}\n`],\n [\"backend/server/nestjs/src/app.controller.ts.hbs\", `import { Controller, Get } from \"@nestjs/common\";\nimport { AppService } from \"./app.service\";\n\n@Controller()\nexport class AppController {\n\tconstructor(private readonly appService: AppService) {}\n\n\t@Get()\n\tgetHello(): string {\n\t\treturn this.appService.getHello();\n\t}\n}\n`],\n [\"backend/server/nestjs/src/index.ts.hbs\", `import \"reflect-metadata\";\nimport { env } from \"@{{projectName}}/env/server\";\nimport { NestFactory } from \"@nestjs/core\";\nimport { AppModule } from \"./app.module\";\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\nasync function bootstrap() {\n\tconst app = await NestFactory.create(AppModule);\n\n\tapp.enableCors({\n\t\torigin: env.CORS_ORIGIN,\n\t\tmethods: [\"GET\", \"POST\", \"OPTIONS\"],\n{{#if (eq auth \"better-auth\")}}\n\t\tallowedHeaders: [\"Content-Type\", \"Authorization\"],\n\t\tcredentials: true,\n{{/if}}\n\t});\n\n{{#if (eq auth \"better-auth\")}}\n\tconst expressApp = app.getHttpAdapter().getInstance();\n\texpressApp.all(\"/api/auth/*path\", async (req: any, res: any) => {\n\t\treturn auth.handler(req);\n\t});\n{{/if}}\n\n\tawait app.listen(3000);\n\tconsole.log(\"Server is running on http://localhost:3000\");\n}\n\nbootstrap();\n`],\n [\"backend/server/nestjs/src/app.service.ts.hbs\", `import { Injectable } from \"@nestjs/common\";\n\n@Injectable()\nexport class AppService {\n\tgetHello(): string {\n\t\treturn \"OK\";\n\t}\n}\n`],\n [\"backend/server/encore/src/index.ts.hbs\", `import { api } from \"encore.dev/api\";\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n{{#if (and (includes examples \"ai\") (or (eq runtime \"bun\") (eq runtime \"node\")))}}\nimport { streamText, convertToModelMessages, wrapLanguageModel } from \"ai\";\nimport { google } from \"@ai-sdk/google\";\nimport { devToolsMiddleware } from \"@ai-sdk/devtools\";\n{{/if}}\n\ninterface Response {\n\tmessage: string;\n}\n\ninterface HealthResponse {\n\tstatus: string;\n\ttimestamp: string;\n}\n\n// Health check endpoint\nexport const health = api(\n\t{ expose: true, method: \"GET\", path: \"/health\" },\n\tasync (): Promise<HealthResponse> => {\n\t\treturn {\n\t\t\tstatus: \"ok\",\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\t}\n);\n\n// Hello world endpoint\nexport const hello = api(\n\t{ expose: true, method: \"GET\", path: \"/hello/:name\" },\n\tasync ({ name }: { name: string }): Promise<Response> => {\n\t\treturn { message: \\`Hello \\${name}!\\` };\n\t}\n);\n\n// Root endpoint\nexport const root = api(\n\t{ expose: true, method: \"GET\", path: \"/\" },\n\tasync (): Promise<Response> => {\n\t\treturn { message: \"OK\" };\n\t}\n);\n{{#if (and (includes examples \"ai\") (or (eq runtime \"bun\") (eq runtime \"node\")))}}\n\ninterface AIRequest {\n\tmessages: Array<{ role: string; content: string }>;\n}\n\n// AI chat endpoint (Encore.ts uses native streaming)\nexport const chat = api(\n\t{ expose: true, method: \"POST\", path: \"/ai\" },\n\tasync (req: AIRequest): Promise<Response> => {\n\t\tconst model = wrapLanguageModel({\n\t\t\tmodel: google(\"gemini-2.5-flash\"),\n\t\t\tmiddleware: devToolsMiddleware(),\n\t\t});\n\n\t\tconst result = await streamText({\n\t\t\tmodel,\n\t\t\tmessages: await convertToModelMessages(req.messages),\n\t\t});\n\n\t\t// For simple response - streaming would need Encore's streaming API\n\t\tconst text = await result.text;\n\t\treturn { message: text };\n\t}\n);\n{{/if}}\n`],\n [\"cms/sanity/web/next/sanity.cli.ts.hbs\", `import { defineCliConfig } from \"sanity/cli\";\n\nconst projectId = process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!;\nconst dataset = process.env.NEXT_PUBLIC_SANITY_DATASET!;\n\nexport default defineCliConfig({\n api: {\n projectId,\n dataset,\n },\n});\n`],\n [\"cms/sanity/web/next/sanity.config.ts.hbs\", `\"use client\";\n\nimport { defineConfig } from \"sanity\";\nimport { structureTool } from \"sanity/structure\";\nimport { visionTool } from \"@sanity/vision\";\n\nimport { schemaTypes } from \"./src/sanity/schemas\";\n\nconst projectId = process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!;\nconst dataset = process.env.NEXT_PUBLIC_SANITY_DATASET!;\n\nexport default defineConfig({\n name: \"{{projectName}}\",\n title: \"{{projectName}}\",\n\n projectId,\n dataset,\n\n basePath: \"/studio\",\n\n plugins: [structureTool(), visionTool()],\n\n schema: {\n types: schemaTypes,\n },\n});\n`],\n [\"backend/convex/packages/backend/package.json.hbs\", `{\n \"name\": \"@{{projectName}}/backend\",\n \"version\": \"1.0.0\",\n \"scripts\": {\n \"dev\": \"convex dev\",\n \"dev:setup\": \"convex dev --configure --until-success\"\n },\n \"author\": \"\",\n \"license\": \"ISC\",\n \"description\": \"\",\n \"devDependencies\": {\n \"@types/node\": \"^24.3.0\"\n },\n \"dependencies\": {}\n}\n`],\n [\"backend/convex/packages/backend/_gitignore\", `\n.env.local\n`],\n [\"api/orpc/native/utils/orpc.ts.hbs\", `import { createORPCClient } from \"@orpc/client\";\nimport { RPCLink } from \"@orpc/client/fetch\";\nimport { createTanstackQueryUtils } from \"@orpc/tanstack-query\";\nimport { QueryCache, QueryClient } from \"@tanstack/react-query\";\nimport type { AppRouterClient } from \"@{{projectName}}/api/routers/index\";\nimport { env } from \"@{{projectName}}/env/native\";\n{{#if (eq auth \"better-auth\")}}\nimport { authClient } from \"@/lib/auth-client\";\n{{/if}}\n\nexport const queryClient = new QueryClient({\n\tqueryCache: new QueryCache({\n\t\tonError: (error) => {\n\t\t\tconsole.log(error)\n\t\t},\n\t}),\n});\n\nexport const link = new RPCLink({\n{{#if (eq backend \"self\")}}\n\turl: \\`\\${env.EXPO_PUBLIC_SERVER_URL}/api/rpc\\`,\n{{else}}\n\turl: \\`\\${env.EXPO_PUBLIC_SERVER_URL}/rpc\\`,\n{{/if}}\n{{#if (eq auth \"better-auth\")}}\n\theaders() {\n\t\tconst headers = new Map<string, string>();\n\t\tconst cookies = authClient.getCookie();\n\t\tif (cookies) {\n\t\t\theaders.set(\"Cookie\", cookies);\n\t\t}\n\t\treturn Object.fromEntries(headers);\n\t},\n{{/if}}\n});\n\nexport const client: AppRouterClient = createORPCClient(link);\n\nexport const orpc = createTanstackQueryUtils(client);\n`],\n [\"rust-base/crates/proto/src/generated/greeter.rs.hbs\", `// This file is @generated by prost-build.\n/// The request message containing the user's name.\n#[derive(Clone, PartialEq, ::prost::Message)]\npub struct HelloRequest {\n #[prost(string, tag = \"1\")]\n pub name: ::prost::alloc::string::String,\n}\n/// The response message containing the greeting.\n#[derive(Clone, PartialEq, ::prost::Message)]\npub struct HelloReply {\n #[prost(string, tag = \"1\")]\n pub message: ::prost::alloc::string::String,\n}\n/// Generated client implementations.\npub mod greeter_client {\n #![allow(\n unused_variables,\n dead_code,\n missing_docs,\n clippy::wildcard_imports,\n clippy::let_unit_value,\n )]\n use tonic::codegen::*;\n use tonic::codegen::http::Uri;\n /// The greeting service definition.\n #[derive(Debug, Clone)]\n pub struct GreeterClient<T> {\n inner: tonic::client::Grpc<T>,\n }\n impl GreeterClient<tonic::transport::Channel> {\n /// Attempt to create a new client by connecting to a given endpoint.\n pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error>\n where\n D: TryInto<tonic::transport::Endpoint>,\n D::Error: Into<StdError>,\n {\n let conn = tonic::transport::Endpoint::new(dst)?.connect().await?;\n Ok(Self::new(conn))\n }\n }\n impl<T> GreeterClient<T>\n where\n T: tonic::client::GrpcService<tonic::body::BoxBody>,\n T::Error: Into<StdError>,\n T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static,\n <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send,\n {\n pub fn new(inner: T) -> Self {\n let inner = tonic::client::Grpc::new(inner);\n Self { inner }\n }\n pub fn with_origin(inner: T, origin: Uri) -> Self {\n let inner = tonic::client::Grpc::with_origin(inner, origin);\n Self { inner }\n }\n pub fn with_interceptor<F>(\n inner: T,\n interceptor: F,\n ) -> GreeterClient<InterceptedService<T, F>>\n where\n F: tonic::service::Interceptor,\n T::ResponseBody: Default,\n T: tonic::codegen::Service<\n http::Request<tonic::body::BoxBody>,\n Response = http::Response<\n <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody,\n >,\n >,\n <T as tonic::codegen::Service<\n http::Request<tonic::body::BoxBody>,\n >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync,\n {\n GreeterClient::new(InterceptedService::new(inner, interceptor))\n }\n /// Compress requests with the given encoding.\n ///\n /// This requires the server to support it otherwise it might respond with an\n /// error.\n #[must_use]\n pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {\n self.inner = self.inner.send_compressed(encoding);\n self\n }\n /// Enable decompressing responses.\n #[must_use]\n pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {\n self.inner = self.inner.accept_compressed(encoding);\n self\n }\n /// Limits the maximum size of a decoded message.\n ///\n /// Default: \\`4MB\\`\n #[must_use]\n pub fn max_decoding_message_size(mut self, limit: usize) -> Self {\n self.inner = self.inner.max_decoding_message_size(limit);\n self\n }\n /// Limits the maximum size of an encoded message.\n ///\n /// Default: \\`usize::MAX\\`\n #[must_use]\n pub fn max_encoding_message_size(mut self, limit: usize) -> Self {\n self.inner = self.inner.max_encoding_message_size(limit);\n self\n }\n /// Sends a greeting\n pub async fn say_hello(\n &mut self,\n request: impl tonic::IntoRequest<super::HelloRequest>,\n ) -> std::result::Result<tonic::Response<super::HelloReply>, tonic::Status> {\n self.inner\n .ready()\n .await\n .map_err(|e| {\n tonic::Status::unknown(\n format!(\"Service was not ready: {}\", e.into()),\n )\n })?;\n let codec = tonic::codec::ProstCodec::default();\n let path = http::uri::PathAndQuery::from_static(\"/greeter.Greeter/SayHello\");\n let mut req = request.into_request();\n req.extensions_mut().insert(GrpcMethod::new(\"greeter.Greeter\", \"SayHello\"));\n self.inner.unary(req, path, codec).await\n }\n /// Sends a streaming greeting\n pub async fn say_hello_stream(\n &mut self,\n request: impl tonic::IntoRequest<super::HelloRequest>,\n ) -> std::result::Result<\n tonic::Response<tonic::codec::Streaming<super::HelloReply>>,\n tonic::Status,\n > {\n self.inner\n .ready()\n .await\n .map_err(|e| {\n tonic::Status::unknown(\n format!(\"Service was not ready: {}\", e.into()),\n )\n })?;\n let codec = tonic::codec::ProstCodec::default();\n let path = http::uri::PathAndQuery::from_static(\n \"/greeter.Greeter/SayHelloStream\",\n );\n let mut req = request.into_request();\n req.extensions_mut()\n .insert(GrpcMethod::new(\"greeter.Greeter\", \"SayHelloStream\"));\n self.inner.server_streaming(req, path, codec).await\n }\n }\n}\n/// Generated server implementations.\npub mod greeter_server {\n #![allow(\n unused_variables,\n dead_code,\n missing_docs,\n clippy::wildcard_imports,\n clippy::let_unit_value,\n )]\n use tonic::codegen::*;\n /// Generated trait containing gRPC methods that should be implemented for use with GreeterServer.\n #[async_trait]\n pub trait Greeter: std::marker::Send + std::marker::Sync + 'static {\n /// Sends a greeting\n async fn say_hello(\n &self,\n request: tonic::Request<super::HelloRequest>,\n ) -> std::result::Result<tonic::Response<super::HelloReply>, tonic::Status>;\n /// Server streaming response type for the SayHelloStream method.\n type SayHelloStreamStream: tonic::codegen::tokio_stream::Stream<\n Item = std::result::Result<super::HelloReply, tonic::Status>,\n >\n + std::marker::Send\n + 'static;\n /// Sends a streaming greeting\n async fn say_hello_stream(\n &self,\n request: tonic::Request<super::HelloRequest>,\n ) -> std::result::Result<tonic::Response<Self::SayHelloStreamStream>, tonic::Status>;\n }\n /// The greeting service definition.\n #[derive(Debug)]\n pub struct GreeterServer<T: Greeter> {\n inner: Arc<T>,\n accept_compression_encodings: EnabledCompressionEncodings,\n send_compression_encodings: EnabledCompressionEncodings,\n max_decoding_message_size: Option<usize>,\n max_encoding_message_size: Option<usize>,\n }\n impl<T: Greeter> GreeterServer<T> {\n pub fn new(inner: T) -> Self {\n Self::from_arc(Arc::new(inner))\n }\n pub fn from_arc(inner: Arc<T>) -> Self {\n Self {\n inner,\n accept_compression_encodings: Default::default(),\n send_compression_encodings: Default::default(),\n max_decoding_message_size: None,\n max_encoding_message_size: None,\n }\n }\n pub fn with_interceptor<F>(\n inner: T,\n interceptor: F,\n ) -> InterceptedService<Self, F>\n where\n F: tonic::service::Interceptor,\n {\n InterceptedService::new(Self::new(inner), interceptor)\n }\n /// Enable decompressing requests with the given encoding.\n #[must_use]\n pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self {\n self.accept_compression_encodings.enable(encoding);\n self\n }\n /// Compress responses with the given encoding, if the client supports it.\n #[must_use]\n pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self {\n self.send_compression_encodings.enable(encoding);\n self\n }\n /// Limits the maximum size of a decoded message.\n ///\n /// Default: \\`4MB\\`\n #[must_use]\n pub fn max_decoding_message_size(mut self, limit: usize) -> Self {\n self.max_decoding_message_size = Some(limit);\n self\n }\n /// Limits the maximum size of an encoded message.\n ///\n /// Default: \\`usize::MAX\\`\n #[must_use]\n pub fn max_encoding_message_size(mut self, limit: usize) -> Self {\n self.max_encoding_message_size = Some(limit);\n self\n }\n }\n impl<T, B> tonic::codegen::Service<http::Request<B>> for GreeterServer<T>\n where\n T: Greeter,\n B: Body + std::marker::Send + 'static,\n B::Error: Into<StdError> + std::marker::Send + 'static,\n {\n type Response = http::Response<tonic::body::BoxBody>;\n type Error = std::convert::Infallible;\n type Future = BoxFuture<Self::Response, Self::Error>;\n fn poll_ready(\n &mut self,\n _cx: &mut Context<'_>,\n ) -> Poll<std::result::Result<(), Self::Error>> {\n Poll::Ready(Ok(()))\n }\n fn call(&mut self, req: http::Request<B>) -> Self::Future {\n match req.uri().path() {\n \"/greeter.Greeter/SayHello\" => {\n #[allow(non_camel_case_types)]\n struct SayHelloSvc<T: Greeter>(pub Arc<T>);\n impl<T: Greeter> tonic::server::UnaryService<super::HelloRequest>\n for SayHelloSvc<T> {\n type Response = super::HelloReply;\n type Future = BoxFuture<\n tonic::Response<Self::Response>,\n tonic::Status,\n >;\n fn call(\n &mut self,\n request: tonic::Request<super::HelloRequest>,\n ) -> Self::Future {\n let inner = Arc::clone(&self.0);\n let fut = async move {\n <T as Greeter>::say_hello(&inner, request).await\n };\n Box::pin(fut)\n }\n }\n let accept_compression_encodings = self.accept_compression_encodings;\n let send_compression_encodings = self.send_compression_encodings;\n let max_decoding_message_size = self.max_decoding_message_size;\n let max_encoding_message_size = self.max_encoding_message_size;\n let inner = self.inner.clone();\n let fut = async move {\n let method = SayHelloSvc(inner);\n let codec = tonic::codec::ProstCodec::default();\n let mut grpc = tonic::server::Grpc::new(codec)\n .apply_compression_config(\n accept_compression_encodings,\n send_compression_encodings,\n )\n .apply_max_message_size_config(\n max_decoding_message_size,\n max_encoding_message_size,\n );\n let res = grpc.unary(method, req).await;\n Ok(res)\n };\n Box::pin(fut)\n }\n \"/greeter.Greeter/SayHelloStream\" => {\n #[allow(non_camel_case_types)]\n struct SayHelloStreamSvc<T: Greeter>(pub Arc<T>);\n impl<\n T: Greeter,\n > tonic::server::ServerStreamingService<super::HelloRequest>\n for SayHelloStreamSvc<T> {\n type Response = super::HelloReply;\n type ResponseStream = T::SayHelloStreamStream;\n type Future = BoxFuture<\n tonic::Response<Self::ResponseStream>,\n tonic::Status,\n >;\n fn call(\n &mut self,\n request: tonic::Request<super::HelloRequest>,\n ) -> Self::Future {\n let inner = Arc::clone(&self.0);\n let fut = async move {\n <T as Greeter>::say_hello_stream(&inner, request).await\n };\n Box::pin(fut)\n }\n }\n let accept_compression_encodings = self.accept_compression_encodings;\n let send_compression_encodings = self.send_compression_encodings;\n let max_decoding_message_size = self.max_decoding_message_size;\n let max_encoding_message_size = self.max_encoding_message_size;\n let inner = self.inner.clone();\n let fut = async move {\n let method = SayHelloStreamSvc(inner);\n let codec = tonic::codec::ProstCodec::default();\n let mut grpc = tonic::server::Grpc::new(codec)\n .apply_compression_config(\n accept_compression_encodings,\n send_compression_encodings,\n )\n .apply_max_message_size_config(\n max_decoding_message_size,\n max_encoding_message_size,\n );\n let res = grpc.server_streaming(method, req).await;\n Ok(res)\n };\n Box::pin(fut)\n }\n _ => {\n Box::pin(async move {\n let mut response = http::Response::new(empty_body());\n let headers = response.headers_mut();\n headers\n .insert(\n tonic::Status::GRPC_STATUS,\n (tonic::Code::Unimplemented as i32).into(),\n );\n headers\n .insert(\n http::header::CONTENT_TYPE,\n tonic::metadata::GRPC_CONTENT_TYPE,\n );\n Ok(response)\n })\n }\n }\n }\n }\n impl<T: Greeter> Clone for GreeterServer<T> {\n fn clone(&self) -> Self {\n let inner = self.inner.clone();\n Self {\n inner,\n accept_compression_encodings: self.accept_compression_encodings,\n send_compression_encodings: self.send_compression_encodings,\n max_decoding_message_size: self.max_decoding_message_size,\n max_encoding_message_size: self.max_encoding_message_size,\n }\n }\n }\n /// Generated gRPC service name\n pub const SERVICE_NAME: &str = \"greeter.Greeter\";\n impl<T: Greeter> tonic::server::NamedService for GreeterServer<T> {\n const NAME: &'static str = SERVICE_NAME;\n }\n}\n`],\n [\"api/orpc/server/src/context.ts.hbs\", `{{#if (and (eq backend 'self') (includes frontend \"next\"))}}\nimport type { NextRequest } from \"next/server\";\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\nexport async function createContext(req: NextRequest) {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: req.headers,\n });\n return {\n session,\n };\n{{else}}\n return {}\n{{/if}}\n}\n\n{{else if (and (eq backend 'self') (includes frontend \"tanstack-start\"))}}\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\nexport async function createContext({ req }: { req: Request }) {\n{{#if (eq auth \"better-auth\")}}\n\tconst session = await auth.api.getSession({\n\t\theaders: req.headers,\n\t});\n\treturn {\n\t\tsession,\n\t};\n{{else}}\n\treturn {};\n{{/if}}\n}\n\n{{else if (eq backend 'hono')}}\nimport type { Context as HonoContext } from \"hono\";\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\nexport type CreateContextOptions = {\n context: HonoContext;\n};\n\nexport async function createContext({ context }: CreateContextOptions) {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: context.req.raw.headers,\n });\n return {\n session,\n };\n{{else}}\n // No auth configured\n return {\n session: null,\n };\n{{/if}}\n}\n\n{{else if (eq backend 'elysia')}}\nimport type { Context as ElysiaContext } from \"elysia\";\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\nexport type CreateContextOptions = {\n context: ElysiaContext;\n};\n\nexport async function createContext({ context }: CreateContextOptions) {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: context.request.headers,\n });\n return {\n session,\n };\n{{else}}\n // No auth configured\n return {\n session: null,\n };\n{{/if}}\n}\n\n{{else if (eq backend 'express')}}\nimport type { Request } from \"express\";\n{{#if (eq auth \"better-auth\")}}\nimport { fromNodeHeaders } from \"better-auth/node\";\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\ninterface CreateContextOptions {\n\treq: Request;\n}\n\nexport async function createContext(opts: CreateContextOptions) {\n{{#if (eq auth \"better-auth\")}}\n\tconst session = await auth.api.getSession({\n\t\theaders: fromNodeHeaders(opts.req.headers),\n\t});\n\treturn {\n\t\tsession,\n\t};\n{{else}}\n // No auth configured\n\treturn {\n\t\tsession: null,\n\t};\n{{/if}}\n}\n\n{{else if (eq backend 'fastify')}}\nimport type { IncomingHttpHeaders } from \"node:http\";\n{{#if (eq auth \"better-auth\")}}\nimport { fromNodeHeaders } from \"better-auth/node\";\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\nexport async function createContext(req: IncomingHttpHeaders) {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: fromNodeHeaders(req),\n });\n return {\n session,\n };\n{{else}}\n // No auth configured\n return {\n session: null,\n };\n{{/if}}\n}\n\n{{else}}\nexport async function createContext() {\n return {\n session: null,\n };\n}\n{{/if}}\n\nexport type Context = Awaited<ReturnType<typeof createContext>>;\n`],\n [\"api/orpc/server/src/index.ts.hbs\", `import { ORPCError, os } from \"@orpc/server\";\nimport type { Context } from \"./context\";\n\nexport const o = os.$context<Context>();\n\nexport const publicProcedure = o;\n\n{{#if (eq auth \"better-auth\")}}\nconst requireAuth = o.middleware(async ({ context, next }) => {\n if (!context.session?.user) {\n throw new ORPCError(\"UNAUTHORIZED\");\n }\n return next({\n context: {\n session: context.session,\n },\n });\n});\n\nexport const protectedProcedure = publicProcedure.use(requireAuth);\n{{/if}}\n`],\n [\"api/trpc/native/utils/trpc.ts.hbs\", `{{#if (eq auth \"better-auth\")}}\nimport { authClient } from \"@/lib/auth-client\";\n{{/if}}\nimport { QueryClient } from \"@tanstack/react-query\";\nimport { createTRPCClient, httpBatchLink } from \"@trpc/client\";\nimport { createTRPCOptionsProxy } from \"@trpc/tanstack-react-query\";\nimport type { AppRouter } from \"@{{projectName}}/api/routers/index\";\nimport { env } from \"@{{projectName}}/env/native\";\n\nexport const queryClient = new QueryClient();\n\nconst trpcClient = createTRPCClient<AppRouter>({\n\tlinks: [\n\t\thttpBatchLink({\n{{#if (eq backend \"self\")}}\n\t\t\turl: \\`\\${env.EXPO_PUBLIC_SERVER_URL}/api/trpc\\`,\n{{else}}\n\t\t\turl: \\`\\${env.EXPO_PUBLIC_SERVER_URL}/trpc\\`,\n{{/if}}\n{{#if (eq auth \"better-auth\")}}\n\t\t\theaders() {\n\t\t\t\tconst headers = new Map<string, string>();\n\t\t\t\tconst cookies = authClient.getCookie();\n\t\t\t\tif (cookies) {\n\t\t\t\t\theaders.set(\"Cookie\", cookies);\n\t\t\t\t}\n\t\t\t\treturn Object.fromEntries(headers);\n\t\t\t},\n{{/if}}\n\t\t}),\n\t],\n});\n\nexport const trpc = createTRPCOptionsProxy<AppRouter>({\n\tclient: trpcClient,\n\tqueryClient,\n});\n`],\n [\"api/trpc/server/src/context.ts.hbs\", `{{#if (and (eq backend 'self') (includes frontend \"next\"))}}\nimport type { NextRequest } from \"next/server\";\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\nexport async function createContext(req: NextRequest) {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: req.headers,\n });\n return {\n session,\n };\n{{else}}\n // No auth configured\n return {\n session: null,\n };\n{{/if}}\n}\n\n{{else if (and (eq backend 'self') (includes frontend \"tanstack-start\"))}}\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\nexport async function createContext({ req }: { req: Request }) {\n{{#if (eq auth \"better-auth\")}}\n\tconst session = await auth.api.getSession({\n\t\theaders: req.headers,\n\t});\n\treturn {\n\t\tsession,\n\t};\n{{else}}\n\t// No auth configured\n\treturn {\n\t\tsession: null,\n\t};\n{{/if}}\n}\n\n{{else if (eq backend 'hono')}}\nimport type { Context as HonoContext } from \"hono\";\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\nexport type CreateContextOptions = {\n context: HonoContext;\n};\n\nexport async function createContext({ context }: CreateContextOptions) {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: context.req.raw.headers,\n });\n return {\n session,\n };\n{{else}}\n // No auth configured\n return {\n session: null,\n };\n{{/if}}\n}\n\n{{else if (eq backend 'elysia')}}\nimport type { Context as ElysiaContext } from \"elysia\";\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\nexport type CreateContextOptions = {\n context: ElysiaContext;\n};\n\nexport async function createContext({ context }: CreateContextOptions) {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: context.request.headers,\n });\n return {\n session,\n };\n{{else}}\n // No auth configured\n return {\n session: null,\n };\n{{/if}}\n}\n\n{{else if (eq backend 'express')}}\nimport type { CreateExpressContextOptions } from \"@trpc/server/adapters/express\";\n{{#if (eq auth \"better-auth\")}}\nimport { fromNodeHeaders } from \"better-auth/node\";\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\nexport async function createContext(opts: CreateExpressContextOptions) {\n{{#if (eq auth \"better-auth\")}}\n\tconst session = await auth.api.getSession({\n\t\theaders: fromNodeHeaders(opts.req.headers),\n\t});\n\treturn {\n\t\tsession,\n\t};\n{{else}}\n // No auth configured\n\treturn {\n\t\tsession: null,\n\t};\n{{/if}}\n}\n\n{{else if (eq backend 'fastify')}}\nimport type { CreateFastifyContextOptions } from \"@trpc/server/adapters/fastify\";\n{{#if (eq auth \"better-auth\")}}\nimport { fromNodeHeaders } from \"better-auth/node\";\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\nexport async function createContext({ req, res }: CreateFastifyContextOptions) {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: fromNodeHeaders(req.headers),\n });\n return { session };\n{{else}}\n // No auth configured\n\treturn {\n\t\tsession: null,\n\t};\n{{/if}}\n}\n\n{{else}}\nexport async function createContext() {\n return {\n session: null,\n };\n}\n{{/if}}\n\nexport type Context = Awaited<ReturnType<typeof createContext>>;\n`],\n [\"api/trpc/server/src/index.ts.hbs\", `import { initTRPC, TRPCError } from \"@trpc/server\";\nimport type { Context } from \"./context\";\n\nexport const t = initTRPC.context<Context>().create();\n\nexport const router = t.router;\n\nexport const publicProcedure = t.procedure;\n\n{{#if (eq auth \"better-auth\")}}\nexport const protectedProcedure = t.procedure.use(({ ctx, next }) => {\n if (!ctx.session) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Authentication required\",\n cause: \"No session\",\n });\n }\n return next({\n ctx: {\n ...ctx,\n session: ctx.session,\n },\n });\n});\n{{/if}}\n`],\n [\"backend/server/elysia/src/index.ts.hbs\", `import { env } from \"@{{projectName}}/env/server\";\n{{#if (eq runtime \"node\")}}\nimport { node } from \"@elysiajs/node\";\n{{/if}}\nimport { Elysia } from \"elysia\";\nimport { cors } from \"@elysiajs/cors\";\n{{#if (includes examples \"ai\")}}\nimport { google } from \"@ai-sdk/google\";\nimport { convertToModelMessages, streamText, wrapLanguageModel } from \"ai\";\nimport { devToolsMiddleware } from \"@ai-sdk/devtools\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { createContext } from \"@{{projectName}}/api/context\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\nimport { fetchRequestHandler } from \"@trpc/server/adapters/fetch\";\n{{/if}}\n{{#if (eq api \"orpc\")}}\nimport { OpenAPIHandler } from \"@orpc/openapi/fetch\";\nimport { OpenAPIReferencePlugin } from \"@orpc/openapi/plugins\";\nimport { ZodToJsonSchemaConverter } from \"@orpc/zod/zod4\";\nimport { RPCHandler } from \"@orpc/server/fetch\";\nimport { onError } from \"@orpc/server\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\nimport { createContext } from \"@{{projectName}}/api/context\";\n{{/if}}\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\n{{#if (eq api \"orpc\")}}\nconst rpcHandler = new RPCHandler(appRouter, {\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\nconst apiHandler = new OpenAPIHandler(appRouter, {\n\tplugins: [\n\t\tnew OpenAPIReferencePlugin({\n\t\t\tschemaConverters: [new ZodToJsonSchemaConverter()],\n\t\t}),\n\t],\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\n{{/if}}\n\n{{#if (eq runtime \"node\")}}\nconst app = new Elysia({ adapter: node() })\n{{else}}\nconst app = new Elysia()\n{{/if}}\n\t.use(\n\t\tcors({\n\t\t\torigin: env.CORS_ORIGIN,\n\t\t\tmethods: [\"GET\", \"POST\", \"OPTIONS\"],\n{{#if (eq auth \"better-auth\")}}\n\t\t\tallowedHeaders: [\"Content-Type\", \"Authorization\"],\n\t\t\tcredentials: true,\n{{/if}}\n\t\t}),\n\t)\n{{#if (eq auth \"better-auth\")}}\n\t.all(\"/api/auth/*\", async (context) => {\n\t\tconst { request, status } = context;\n\t\tif ([\"POST\", \"GET\"].includes(request.method)) {\n\t\t\treturn auth.handler(request);\n\t\t}\n\t\treturn status(405)\n\t})\n{{/if}}\n{{#if (eq api \"orpc\")}}\n\t.all('/rpc*', async (context) => {\n\t\tconst { response } = await rpcHandler.handle(context.request, {\n\t\t\tprefix: '/rpc',\n\t\t\tcontext: await createContext({ context })\n\t\t})\n\t\treturn response ?? new Response('Not Found', { status: 404 })\n\t})\n\t.all('/api*', async (context) => {\n\t\tconst { response } = await apiHandler.handle(context.request, {\n\t\t\tprefix: '/api-reference',\n\t\t\tcontext: await createContext({ context })\n\t\t})\n\t\treturn response ?? new Response('Not Found', { status: 404 })\n\t})\n{{/if}}\n{{#if (eq api \"trpc\")}}\n\t.all(\"/trpc/*\", async (context) => {\n\t\tconst res = await fetchRequestHandler({\n\t\t\tendpoint: \"/trpc\",\n\t\t\trouter: appRouter,\n\t\t\treq: context.request,\n\t\t\tcreateContext: () => createContext({ context }),\n\t\t});\n\t\treturn res;\n\t})\n{{/if}}\n{{#if (includes examples \"ai\")}}\n\t.post(\"/ai\", async (context) => {\n\t\tconst body = await context.request.json();\n\t\tconst uiMessages = body.messages || [];\n\t\tconst model = wrapLanguageModel({\n\t\t\tmodel: google(\"gemini-2.5-flash\"),\n\t\t\tmiddleware: devToolsMiddleware(),\n\t\t});\n\t\tconst result = streamText({\n\t\t\tmodel,\n\t\t\tmessages: await convertToModelMessages(uiMessages)\n\t\t});\n\n\t\treturn result.toUIMessageStreamResponse();\n\t})\n{{/if}}\n\t.get(\"/\", () => \"OK\")\n\t.listen(3000, () => {\n\t\tconsole.log(\"Server is running on http://localhost:3000\");\n\t});\n`],\n [\"backend/server/adonisjs/start/routes.ts.hbs\", `import { env } from \"@{{projectName}}/env/server\";\n{{#if (eq api \"trpc\")}}\nimport { createExpressMiddleware } from \"@trpc/server/adapters/express\";\nimport { createContext } from \"@{{projectName}}/api/context\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\n{{/if}}\n{{#if (eq api \"orpc\")}}\nimport { OpenAPIHandler } from \"@orpc/openapi/node\";\nimport { OpenAPIReferencePlugin } from \"@orpc/openapi/plugins\";\nimport { ZodToJsonSchemaConverter } from \"@orpc/zod/zod4\";\nimport { RPCHandler } from \"@orpc/server/node\";\nimport { onError } from \"@orpc/server\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\n{{#if (eq auth \"better-auth\")}}\nimport { createContext } from \"@{{projectName}}/api/context\";\n{{/if}}\n{{/if}}\n{{#if (includes examples \"ai\")}}\nimport { streamText, type UIMessage, convertToModelMessages, wrapLanguageModel } from \"ai\";\nimport { google } from \"@ai-sdk/google\";\nimport { devToolsMiddleware } from \"@ai-sdk/devtools\";\n{{/if}}\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\nimport { toNodeHandler } from \"better-auth/node\";\n{{/if}}\nimport router from \"@adonisjs/core/services/router\";\n\n// CORS headers helper\nconst setCorsHeaders = (response: any) => {\n\tconst origin = env.CORS_ORIGIN;\n\tresponse.header(\"Access-Control-Allow-Origin\", origin);\n\tresponse.header(\"Access-Control-Allow-Methods\", \"GET, POST, PUT, DELETE, OPTIONS\");\n{{#if (eq auth \"better-auth\")}}\n\tresponse.header(\"Access-Control-Allow-Headers\", \"Content-Type, Authorization\");\n\tresponse.header(\"Access-Control-Allow-Credentials\", \"true\");\n{{else}}\n\tresponse.header(\"Access-Control-Allow-Headers\", \"Content-Type\");\n{{/if}}\n};\n\n// CORS preflight handler\nrouter.options(\"*\", ({ response }) => {\n\tsetCorsHeaders(response);\n\treturn response.status(204);\n});\n\n// Health check endpoint\nrouter.get(\"/\", ({ response }) => {\n\tsetCorsHeaders(response);\n\treturn response.send(\"OK\");\n});\n\n{{#if (eq auth \"better-auth\")}}\n// Better Auth handler\nconst authHandler = toNodeHandler(auth);\nrouter.any(\"/api/auth/*\", async ({ request, response }) => {\n\tsetCorsHeaders(response);\n\treturn new Promise<void>((resolve) => {\n\t\tauthHandler(request.request as any, response.response as any, () => {\n\t\t\tresolve();\n\t\t});\n\t});\n});\n{{/if}}\n\n{{#if (eq api \"trpc\")}}\n// tRPC middleware adapter for AdonisJS\nconst trpcMiddleware = createExpressMiddleware({\n\trouter: appRouter,\n\tcreateContext,\n});\n\nrouter.any(\"/trpc/*\", async ({ request, response }) => {\n\tsetCorsHeaders(response);\n\treturn new Promise<void>((resolve) => {\n\t\ttrpcMiddleware(request.request as any, response.response as any, () => {\n\t\t\tresolve();\n\t\t});\n\t});\n});\n{{/if}}\n\n{{#if (eq api \"orpc\")}}\nconst rpcHandler = new RPCHandler(appRouter, {\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\nconst apiHandler = new OpenAPIHandler(appRouter, {\n\tplugins: [\n\t\tnew OpenAPIReferencePlugin({\n\t\t\tschemaConverters: [new ZodToJsonSchemaConverter()],\n\t\t}),\n\t],\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\n\nrouter.any(\"/rpc/*\", async ({ request, response }) => {\n\tsetCorsHeaders(response);\n\tconst result = await rpcHandler.handle(request.request as any, response.response as any, {\n\t\tprefix: \"/rpc\",\n{{#if (eq auth \"better-auth\")}}\n\t\tcontext: await createContext({ req: request.request as any }),\n{{else}}\n\t\tcontext: {},\n{{/if}}\n\t});\n\tif (!result.matched) {\n\t\treturn response.status(404).send(\"Not Found\");\n\t}\n});\n\nrouter.any(\"/api-reference/*\", async ({ request, response }) => {\n\tsetCorsHeaders(response);\n\tconst result = await apiHandler.handle(request.request as any, response.response as any, {\n\t\tprefix: \"/api-reference\",\n{{#if (eq auth \"better-auth\")}}\n\t\tcontext: await createContext({ req: request.request as any }),\n{{else}}\n\t\tcontext: {},\n{{/if}}\n\t});\n\tif (!result.matched) {\n\t\treturn response.status(404).send(\"Not Found\");\n\t}\n});\n{{/if}}\n\n{{#if (includes examples \"ai\")}}\nrouter.post(\"/ai\", async ({ request, response }) => {\n\tsetCorsHeaders(response);\n\tconst body = request.body() as { messages?: UIMessage[] };\n\tconst messages = body.messages || [];\n\tconst model = wrapLanguageModel({\n\t\tmodel: google(\"gemini-2.5-flash\"),\n\t\tmiddleware: devToolsMiddleware(),\n\t});\n\tconst result = streamText({\n\t\tmodel,\n\t\tmessages: await convertToModelMessages(messages),\n\t});\n\tresult.pipeUIMessageStreamToResponse(response.response as any);\n});\n{{/if}}\n`],\n [\"backend/server/adonisjs/bin/server.ts.hbs\", `import \"reflect-metadata\";\nimport { Ignitor, prettyPrintError } from \"@adonisjs/core\";\n\nconst APP_ROOT = new URL(\"../\", import.meta.url);\n\nconst ignitor = new Ignitor(APP_ROOT);\n\nignitor\n\t.tap((app) => {\n\t\tapp.booting(async () => {\n\t\t\tawait import(\"#start/routes\");\n\t\t});\n\t})\n\t.httpServer()\n\t.start()\n\t.catch((error) => {\n\t\tprocess.exitCode = 1;\n\t\tprettyPrintError(error);\n\t});\n`],\n [\"backend/server/adonisjs/config/app.ts.hbs\", `import { defineConfig } from \"@adonisjs/core/http\";\n\nexport default defineConfig({\n\tgenerateRequestId: true,\n\tuseAsyncLocalStorage: true,\n\tqs: {\n\t\tparse: {},\n\t},\n});\n`],\n [\"backend/server/nitro/routes/ai.post.ts.hbs\", `{{#if (includes examples \"ai\")}}\nimport { streamText, type UIMessage, convertToModelMessages, wrapLanguageModel } from \"ai\";\n{{#if (or (eq runtime \"bun\") (eq runtime \"node\"))}}\nimport { google } from \"@ai-sdk/google\";\n{{else}}\nimport { createGoogleGenerativeAI } from \"@ai-sdk/google\";\nimport { env } from \"@{{projectName}}/env/server\";\n{{/if}}\nimport { devToolsMiddleware } from \"@ai-sdk/devtools\";\n\nexport default defineEventHandler(async (event) => {\n\tconst body = await readBody<{ messages?: UIMessage[] }>(event);\n\tconst messages = body.messages || [];\n\n{{#if (eq runtime \"workers\")}}\n\tconst google = createGoogleGenerativeAI({\n\t\tapiKey: env.GOOGLE_GENERATIVE_AI_API_KEY,\n\t});\n{{/if}}\n\tconst model = wrapLanguageModel({\n\t\tmodel: google(\"gemini-2.5-flash\"),\n\t\tmiddleware: devToolsMiddleware(),\n\t});\n\n\tconst result = streamText({\n\t\tmodel,\n\t\tmessages: await convertToModelMessages(messages),\n\t});\n\n\treturn result.toUIMessageStreamResponse();\n});\n{{else}}\n// AI placeholder - AI example not included\nexport default defineEventHandler(() => {\n\treturn { error: \"AI not configured\" };\n});\n{{/if}}\n`],\n [\"backend/server/nitro/routes/index.ts.hbs\", `// Health check endpoint\nexport default defineEventHandler(() => {\n\treturn \"OK\";\n});\n`],\n [\"backend/server/fastify/src/index.ts.hbs\", `import { env } from \"@{{projectName}}/env/server\";\nimport Fastify from \"fastify\";\nimport fastifyCors from \"@fastify/cors\";\n\n{{#if (eq api \"trpc\")}}\nimport { fastifyTRPCPlugin, type FastifyTRPCPluginOptions } from \"@trpc/server/adapters/fastify\";\nimport { createContext } from \"@{{projectName}}/api/context\";\nimport { appRouter, type AppRouter } from \"@{{projectName}}/api/routers/index\";\n{{/if}}\n\n{{#if (eq api \"orpc\")}}\nimport { OpenAPIHandler } from \"@orpc/openapi/node\";\nimport { OpenAPIReferencePlugin } from \"@orpc/openapi/plugins\";\nimport { ZodToJsonSchemaConverter } from \"@orpc/zod/zod4\";\nimport { RPCHandler } from \"@orpc/server/node\";\nimport { CORSPlugin } from \"@orpc/server/plugins\";\nimport { onError } from \"@orpc/server\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\nimport { createServer } from \"node:http\";\n{{#if (eq auth \"better-auth\")}}\nimport { createContext } from \"@{{projectName}}/api/context\";\n{{/if}}\n{{/if}}\n\n{{#if (includes examples \"ai\")}}\nimport { streamText, type UIMessage, convertToModelMessages, wrapLanguageModel } from \"ai\";\nimport { google } from \"@ai-sdk/google\";\nimport { devToolsMiddleware } from \"@ai-sdk/devtools\";\n{{/if}}\n\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\n\nconst baseCorsConfig = {\n\torigin: env.CORS_ORIGIN,\n\tmethods: [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"OPTIONS\"],\n\tallowedHeaders: [\n\t\t\"Content-Type\",\n\t\t\"Authorization\",\n\t\t\"X-Requested-With\"\n\t],\n\tcredentials: true,\n\tmaxAge: 86400,\n};\n\n{{#if (eq api \"orpc\")}}\nconst rpcHandler = new RPCHandler(appRouter, {\n\tplugins: [\n\t\tnew CORSPlugin({\n\t\t\torigin: env.CORS_ORIGIN,\n\t\t\tcredentials: true,\n\t\t\tallowHeaders: [\"Content-Type\", \"Authorization\"],\n\t\t}),\n\t],\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\n\nconst apiHandler = new OpenAPIHandler(appRouter, {\n\tplugins: [\n\t\tnew OpenAPIReferencePlugin({\n\t\t\tschemaConverters: [new ZodToJsonSchemaConverter()],\n\t\t}),\n\t],\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\n\nconst fastify = Fastify({\n\tlogger: true,\n\tserverFactory: (fastifyHandler) => {\n\t\tconst server = createServer(async (req, res) => {\n\t\t\tconst { matched } = await rpcHandler.handle(req, res, {\n\t\t\t\tcontext: await createContext(req.headers),\n\t\t\t\tprefix: \"/rpc\",\n\t\t\t});\n\n\t\t\tif (matched) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst apiResult = await apiHandler.handle(req, res, {\n\t\t\t\tcontext: await createContext(req.headers),\n\t\t\t\tprefix: \"/api-reference\",\n\t\t\t});\n\n\t\t\tif (apiResult.matched) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfastifyHandler(req, res);\n\t\t});\n\n\t\treturn server;\n\t},\n});\n{{else}}\nconst fastify = Fastify({\n\tlogger: true,\n});\n{{/if}}\n\nfastify.register(fastifyCors, baseCorsConfig);\n\n{{#if (eq auth \"better-auth\")}}\nfastify.route({\n\tmethod: [\"GET\", \"POST\"],\n\turl: \"/api/auth/*\",\n\tasync handler(request, reply) {\n\t\ttry {\n\t\t\tconst url = new URL(request.url, \\`http://\\${request.headers.host}\\`);\n\t\t\tconst headers = new Headers();\n\t\t\tObject.entries(request.headers).forEach(([key, value]) => {\n\t\t\t\tif (value) headers.append(key, value.toString());\n\t\t\t});\n\t\t\tconst req = new Request(url.toString(), {\n\t\t\t\tmethod: request.method,\n\t\t\t\theaders,\n\t\t\t\tbody: request.body ? JSON.stringify(request.body) : undefined,\n\t\t\t});\n\t\t\tconst response = await auth.handler(req);\n\t\t\treply.status(response.status);\n\t\t\tresponse.headers.forEach((value, key) => reply.header(key, value));\n\t\t\treply.send(response.body ? await response.text() : null);\n\t\t} catch (error) {\n\t\t\tfastify.log.error({ err: error }, \"Authentication Error:\");\n\t\t\treply.status(500).send({\n\t\t\t\terror: \"Internal authentication error\",\n\t\t\t\tcode: \"AUTH_FAILURE\"\n\t\t\t});\n\t\t}\n\t}\n});\n{{/if}}\n\n{{#if (eq api \"trpc\")}}\nfastify.register(fastifyTRPCPlugin, {\n\tprefix: \"/trpc\",\n\ttrpcOptions: {\n\t\trouter: appRouter,\n\t\tcreateContext,\n\t\tonError({ path, error }) {\n\t\t\tconsole.error(\\`Error in tRPC handler on path '\\${path}':\\`, error);\n\t\t},\n\t} satisfies FastifyTRPCPluginOptions<AppRouter>[\"trpcOptions\"],\n});\n{{/if}}\n\n{{#if (includes examples \"ai\")}}\ninterface AiRequestBody {\n\tid?: string;\n\tmessages: UIMessage[];\n}\n\nfastify.post('/ai', async function (request) {\n\tconst { messages } = request.body as AiRequestBody;\n\tconst model = wrapLanguageModel({\n\t\tmodel: google('gemini-2.5-flash'),\n\t\tmiddleware: devToolsMiddleware(),\n\t});\n\tconst result = streamText({\n\t\tmodel,\n\t\tmessages: await convertToModelMessages(messages),\n\t});\n\n\treturn result.toUIMessageStreamResponse();\n});\n{{/if}}\n\nfastify.get('/', async () => {\n\treturn 'OK';\n});\n\nfastify.listen({ port: 3000 }, (err) => {\n\tif (err) {\n\t\tfastify.log.error(err);\n\t\tprocess.exit(1);\n\t}\n\tconsole.log(\"Server running on port 3000\");\n});\n`],\n [\"backend/server/hono/src/index.ts.hbs\", `import { env } from \"@{{projectName}}/env/server\";\n{{#if (eq api \"orpc\")}}\nimport { OpenAPIHandler } from \"@orpc/openapi/fetch\";\nimport { OpenAPIReferencePlugin } from \"@orpc/openapi/plugins\";\nimport { ZodToJsonSchemaConverter } from \"@orpc/zod/zod4\";\nimport { RPCHandler } from \"@orpc/server/fetch\";\nimport { onError } from \"@orpc/server\";\nimport { createContext } from \"@{{projectName}}/api/context\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { trpcServer } from \"@hono/trpc-server\";\nimport { createContext } from \"@{{projectName}}/api/context\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\n{{/if}}\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\nimport { Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport { logger } from \"hono/logger\";\n{{#if (and (includes examples \"ai\") (or (eq runtime \"bun\") (eq runtime \"node\")))}}\nimport { streamText, convertToModelMessages, wrapLanguageModel } from \"ai\";\nimport { google } from \"@ai-sdk/google\";\nimport { devToolsMiddleware } from \"@ai-sdk/devtools\";\n{{/if}}\n{{#if (and (includes examples \"ai\") (eq runtime \"workers\"))}}\nimport { streamText, convertToModelMessages, wrapLanguageModel } from \"ai\";\nimport { createGoogleGenerativeAI } from \"@ai-sdk/google\";\nimport { devToolsMiddleware } from \"@ai-sdk/devtools\";\n{{/if}}\n\nconst app = new Hono();\n\napp.use(logger());\napp.use(\n\t\"/*\",\n\tcors({\n\t\torigin: env.CORS_ORIGIN,\n\t\tallowMethods: [\"GET\", \"POST\", \"OPTIONS\"],\n{{#if (eq auth \"better-auth\")}}\n\t\tallowHeaders: [\"Content-Type\", \"Authorization\"],\n\t\tcredentials: true,\n{{/if}}\n\t})\n);\n\n{{#if (eq auth \"better-auth\")}}\napp.on([\"POST\", \"GET\"], \"/api/auth/*\", (c) => auth.handler(c.req.raw));\n{{/if}}\n\n{{#if (eq api \"orpc\")}}\nexport const apiHandler = new OpenAPIHandler(appRouter, {\n\tplugins: [\n\t\tnew OpenAPIReferencePlugin({\n\t\t\tschemaConverters: [new ZodToJsonSchemaConverter()],\n\t\t}),\n\t],\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\n\nexport const rpcHandler = new RPCHandler(appRouter, {\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\n\napp.use(\"/*\", async (c, next) => {\n\tconst context = await createContext({ context: c });\n\n\tconst rpcResult = await rpcHandler.handle(c.req.raw, {\n\t\tprefix: \"/rpc\",\n\t\tcontext: context,\n\t});\n\n\tif (rpcResult.matched) {\n\t\treturn c.newResponse(rpcResult.response.body, rpcResult.response);\n\t}\n\n\tconst apiResult = await apiHandler.handle(c.req.raw, {\n\t\tprefix: \"/api-reference\",\n\t\tcontext: context,\n\t});\n\n\tif (apiResult.matched) {\n\t\treturn c.newResponse(apiResult.response.body, apiResult.response);\n\t}\n\n\tawait next();\n});\n{{/if}}\n\n{{#if (eq api \"trpc\")}}\napp.use(\n\t\"/trpc/*\",\n\ttrpcServer({\n\t\trouter: appRouter,\n\t\tcreateContext: (_opts, context) => {\n\t\t\treturn createContext({ context });\n\t\t},\n\t})\n);\n{{/if}}\n\n{{#if (and (includes examples \"ai\") (or (eq runtime \"bun\") (eq runtime \"node\")))}}\napp.post(\"/ai\", async (c) => {\n\tconst body = await c.req.json();\n\tconst uiMessages = body.messages || [];\n\tconst model = wrapLanguageModel({\n\t\tmodel: google(\"gemini-2.5-flash\"),\n\t\tmiddleware: devToolsMiddleware(),\n\t});\n\tconst result = streamText({\n\t\tmodel,\n\t\tmessages: await convertToModelMessages(uiMessages),\n\t});\n\n\treturn result.toUIMessageStreamResponse();\n});\n{{/if}}\n\n{{#if (and (includes examples \"ai\") (eq runtime \"workers\"))}}\napp.post(\"/ai\", async (c) => {\n\tconst body = await c.req.json();\n\tconst uiMessages = body.messages || [];\n\tconst google = createGoogleGenerativeAI({\n\t\tapiKey: env.GOOGLE_GENERATIVE_AI_API_KEY,\n\t});\n\tconst model = wrapLanguageModel({\n\t\tmodel: google(\"gemini-2.5-flash\"),\n\t\tmiddleware: devToolsMiddleware(),\n\t});\n\tconst result = streamText({\n\t\tmodel,\n\t\tmessages: await convertToModelMessages(uiMessages),\n\t});\n\n\treturn result.toUIMessageStreamResponse();\n});\n{{/if}}\n\napp.get(\"/\", (c) => {\n\treturn c.text(\"OK\");\n});\n\n{{#if (eq runtime \"node\")}}\nimport { serve } from \"@hono/node-server\";\n\nserve(\n\t{\n\t\tfetch: app.fetch,\n\t\tport: 3000,\n\t},\n\t(info) => {\n\t\tconsole.log(\\`Server is running on http://localhost:\\${info.port}\\`);\n\t}\n);\n{{else}}\n{{#if (eq runtime \"bun\")}}\nexport default app;\n{{/if}}\n{{#if (eq runtime \"workers\")}}\nexport default app;\n{{/if}}\n{{/if}}\n`],\n [\"backend/server/fets/src/index.ts.hbs\", `import { env } from \"@{{projectName}}/env/server\";\n{{#if (eq api \"orpc\")}}\nimport { OpenAPIHandler } from \"@orpc/openapi/fetch\";\nimport { OpenAPIReferencePlugin } from \"@orpc/openapi/plugins\";\nimport { ZodToJsonSchemaConverter } from \"@orpc/zod/zod4\";\nimport { RPCHandler } from \"@orpc/server/fetch\";\nimport { onError } from \"@orpc/server\";\nimport { createContext } from \"@{{projectName}}/api/context\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { fetchRequestHandler } from \"@trpc/server/adapters/fetch\";\nimport { createContext } from \"@{{projectName}}/api/context\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\n{{/if}}\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\nimport { createRouter, Response } from \"fets\";\n{{#if (and (includes examples \"ai\") (or (eq runtime \"bun\") (eq runtime \"node\")))}}\nimport { streamText, convertToModelMessages, wrapLanguageModel } from \"ai\";\nimport { google } from \"@ai-sdk/google\";\nimport { devToolsMiddleware } from \"@ai-sdk/devtools\";\n{{/if}}\n{{#if (and (includes examples \"ai\") (eq runtime \"workers\"))}}\nimport { streamText, convertToModelMessages, wrapLanguageModel } from \"ai\";\nimport { createGoogleGenerativeAI } from \"@ai-sdk/google\";\nimport { devToolsMiddleware } from \"@ai-sdk/devtools\";\n{{/if}}\n\nconst router = createRouter({\n\topenAPI: {\n\t\tinfo: {\n\t\t\ttitle: \"{{projectName}} API\",\n\t\t\tversion: \"1.0.0\",\n\t\t},\n\t},\n\tswaggerUI: {\n\t\tendpoint: \"/docs\",\n\t},\n})\n\t.route({\n\t\tmethod: \"GET\",\n\t\tpath: \"/\",\n\t\tschemas: {\n\t\t\tresponses: {\n\t\t\t\t200: {\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tstatus: { type: \"string\" },\n\t\t\t\t\t},\n\t\t\t\t\trequired: [\"status\"],\n\t\t\t\t\tadditionalProperties: false,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\thandler: () => Response.json({ status: \"OK\" }),\n\t})\n{{#if (eq auth \"better-auth\")}}\n\t.route({\n\t\tmethod: \"GET\",\n\t\tpath: \"/api/auth/*\",\n\t\thandler: (request) => auth.handler(request),\n\t})\n\t.route({\n\t\tmethod: \"POST\",\n\t\tpath: \"/api/auth/*\",\n\t\thandler: (request) => auth.handler(request),\n\t})\n{{/if}}\n{{#if (eq api \"trpc\")}}\n\t.route({\n\t\tmethod: \"GET\",\n\t\tpath: \"/trpc/*\",\n\t\thandler: (request) =>\n\t\t\tfetchRequestHandler({\n\t\t\t\tendpoint: \"/trpc\",\n\t\t\t\treq: request,\n\t\t\t\trouter: appRouter,\n\t\t\t\tcreateContext: () => createContext({ context: request }),\n\t\t\t}),\n\t})\n\t.route({\n\t\tmethod: \"POST\",\n\t\tpath: \"/trpc/*\",\n\t\thandler: (request) =>\n\t\t\tfetchRequestHandler({\n\t\t\t\tendpoint: \"/trpc\",\n\t\t\t\treq: request,\n\t\t\t\trouter: appRouter,\n\t\t\t\tcreateContext: () => createContext({ context: request }),\n\t\t\t}),\n\t})\n{{/if}}\n{{#if (eq api \"orpc\")}}\n\t.route({\n\t\tmethod: \"GET\",\n\t\tpath: \"/rpc/*\",\n\t\thandler: async (request) => {\n\t\t\tconst context = await createContext({ context: request });\n\t\t\tconst rpcHandler = new RPCHandler(appRouter, {\n\t\t\t\tinterceptors: [\n\t\t\t\t\tonError((error) => {\n\t\t\t\t\t\tconsole.error(error);\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t});\n\t\t\tconst result = await rpcHandler.handle(request, {\n\t\t\t\tprefix: \"/rpc\",\n\t\t\t\tcontext,\n\t\t\t});\n\t\t\tif (result.matched) {\n\t\t\t\treturn result.response;\n\t\t\t}\n\t\t\treturn Response.json({ error: \"Not found\" }, { status: 404 });\n\t\t},\n\t})\n\t.route({\n\t\tmethod: \"POST\",\n\t\tpath: \"/rpc/*\",\n\t\thandler: async (request) => {\n\t\t\tconst context = await createContext({ context: request });\n\t\t\tconst rpcHandler = new RPCHandler(appRouter, {\n\t\t\t\tinterceptors: [\n\t\t\t\t\tonError((error) => {\n\t\t\t\t\t\tconsole.error(error);\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t});\n\t\t\tconst result = await rpcHandler.handle(request, {\n\t\t\t\tprefix: \"/rpc\",\n\t\t\t\tcontext,\n\t\t\t});\n\t\t\tif (result.matched) {\n\t\t\t\treturn result.response;\n\t\t\t}\n\t\t\treturn Response.json({ error: \"Not found\" }, { status: 404 });\n\t\t},\n\t})\n\t.route({\n\t\tmethod: \"GET\",\n\t\tpath: \"/api-reference/*\",\n\t\thandler: async (request) => {\n\t\t\tconst context = await createContext({ context: request });\n\t\t\tconst apiHandler = new OpenAPIHandler(appRouter, {\n\t\t\t\tplugins: [\n\t\t\t\t\tnew OpenAPIReferencePlugin({\n\t\t\t\t\t\tschemaConverters: [new ZodToJsonSchemaConverter()],\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t\tinterceptors: [\n\t\t\t\t\tonError((error) => {\n\t\t\t\t\t\tconsole.error(error);\n\t\t\t\t\t}),\n\t\t\t\t],\n\t\t\t});\n\t\t\tconst result = await apiHandler.handle(request, {\n\t\t\t\tprefix: \"/api-reference\",\n\t\t\t\tcontext,\n\t\t\t});\n\t\t\tif (result.matched) {\n\t\t\t\treturn result.response;\n\t\t\t}\n\t\t\treturn Response.json({ error: \"Not found\" }, { status: 404 });\n\t\t},\n\t})\n{{/if}}\n{{#if (and (includes examples \"ai\") (or (eq runtime \"bun\") (eq runtime \"node\")))}}\n\t.route({\n\t\tmethod: \"POST\",\n\t\tpath: \"/ai\",\n\t\thandler: async (request) => {\n\t\t\tconst body = await request.json();\n\t\t\tconst uiMessages = body.messages || [];\n\t\t\tconst model = wrapLanguageModel({\n\t\t\t\tmodel: google(\"gemini-2.5-flash\"),\n\t\t\t\tmiddleware: devToolsMiddleware(),\n\t\t\t});\n\t\t\tconst result = streamText({\n\t\t\t\tmodel,\n\t\t\t\tmessages: await convertToModelMessages(uiMessages),\n\t\t\t});\n\t\t\treturn result.toUIMessageStreamResponse();\n\t\t},\n\t})\n{{/if}}\n{{#if (and (includes examples \"ai\") (eq runtime \"workers\"))}}\n\t.route({\n\t\tmethod: \"POST\",\n\t\tpath: \"/ai\",\n\t\thandler: async (request) => {\n\t\t\tconst body = await request.json();\n\t\t\tconst uiMessages = body.messages || [];\n\t\t\tconst google = createGoogleGenerativeAI({\n\t\t\t\tapiKey: env.GOOGLE_GENERATIVE_AI_API_KEY,\n\t\t\t});\n\t\t\tconst model = wrapLanguageModel({\n\t\t\t\tmodel: google(\"gemini-2.5-flash\"),\n\t\t\t\tmiddleware: devToolsMiddleware(),\n\t\t\t});\n\t\t\tconst result = streamText({\n\t\t\t\tmodel,\n\t\t\t\tmessages: await convertToModelMessages(uiMessages),\n\t\t\t});\n\t\t\treturn result.toUIMessageStreamResponse();\n\t\t},\n\t})\n{{/if}};\n\n{{#if (eq runtime \"node\")}}\nimport { createServer } from \"node:http\";\n\n// Add CORS middleware wrapper\nconst corsOrigin = env.CORS_ORIGIN;\n\nconst corsMiddleware = (handler: typeof router) => {\n\treturn async (request: Request): Promise<globalThis.Response> => {\n\t\t// Handle preflight OPTIONS request\n\t\tif (request.method === \"OPTIONS\") {\n\t\t\treturn new globalThis.Response(null, {\n\t\t\t\tstatus: 204,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Access-Control-Allow-Origin\": corsOrigin,\n\t\t\t\t\t\"Access-Control-Allow-Methods\": \"GET, POST, PUT, DELETE, OPTIONS\",\n{{#if (eq auth \"better-auth\")}}\n\t\t\t\t\t\"Access-Control-Allow-Headers\": \"Content-Type, Authorization\",\n\t\t\t\t\t\"Access-Control-Allow-Credentials\": \"true\",\n{{else}}\n\t\t\t\t\t\"Access-Control-Allow-Headers\": \"Content-Type\",\n{{/if}}\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tconst response = await handler.fetch(request);\n\t\tconst newHeaders = new Headers(response.headers);\n\t\tnewHeaders.set(\"Access-Control-Allow-Origin\", corsOrigin);\n\t\tnewHeaders.set(\"Access-Control-Allow-Methods\", \"GET, POST, PUT, DELETE, OPTIONS\");\n{{#if (eq auth \"better-auth\")}}\n\t\tnewHeaders.set(\"Access-Control-Allow-Headers\", \"Content-Type, Authorization\");\n\t\tnewHeaders.set(\"Access-Control-Allow-Credentials\", \"true\");\n{{else}}\n\t\tnewHeaders.set(\"Access-Control-Allow-Headers\", \"Content-Type\");\n{{/if}}\n\n\t\treturn new globalThis.Response(response.body, {\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\theaders: newHeaders,\n\t\t});\n\t};\n};\n\nconst handler = corsMiddleware(router);\n\ncreateServer((req, res) => {\n\tconst url = new URL(req.url || \"/\", \\`http://\\${req.headers.host}\\`);\n\tconst headers: Record<string, string> = {};\n\tfor (const [key, value] of Object.entries(req.headers)) {\n\t\tif (value) headers[key] = Array.isArray(value) ? value.join(\", \") : value;\n\t}\n\n\tconst body: Buffer[] = [];\n\treq.on(\"data\", (chunk) => body.push(chunk));\n\treq.on(\"end\", async () => {\n\t\tconst request = new Request(url.href, {\n\t\t\tmethod: req.method,\n\t\t\theaders,\n\t\t\tbody: req.method !== \"GET\" && req.method !== \"HEAD\" ? Buffer.concat(body) : undefined,\n\t\t});\n\n\t\tconst response = await handler(request);\n\t\tres.statusCode = response.status;\n\t\tresponse.headers.forEach((value, key) => {\n\t\t\tres.setHeader(key, value);\n\t\t});\n\t\tconst responseBody = await response.arrayBuffer();\n\t\tres.end(Buffer.from(responseBody));\n\t});\n}).listen(3000, () => {\n\tconsole.log(\"Server is running on http://localhost:3000\");\n\tconsole.log(\"Swagger UI is available at http://localhost:3000/docs\");\n});\n{{else}}\n{{#if (eq runtime \"bun\")}}\nconst corsOrigin = env.CORS_ORIGIN;\n\nconst corsMiddleware = (handler: typeof router) => {\n\treturn async (request: Request): Promise<globalThis.Response> => {\n\t\tif (request.method === \"OPTIONS\") {\n\t\t\treturn new globalThis.Response(null, {\n\t\t\t\tstatus: 204,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Access-Control-Allow-Origin\": corsOrigin,\n\t\t\t\t\t\"Access-Control-Allow-Methods\": \"GET, POST, PUT, DELETE, OPTIONS\",\n{{#if (eq auth \"better-auth\")}}\n\t\t\t\t\t\"Access-Control-Allow-Headers\": \"Content-Type, Authorization\",\n\t\t\t\t\t\"Access-Control-Allow-Credentials\": \"true\",\n{{else}}\n\t\t\t\t\t\"Access-Control-Allow-Headers\": \"Content-Type\",\n{{/if}}\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tconst response = await handler.fetch(request);\n\t\tconst newHeaders = new Headers(response.headers);\n\t\tnewHeaders.set(\"Access-Control-Allow-Origin\", corsOrigin);\n\t\tnewHeaders.set(\"Access-Control-Allow-Methods\", \"GET, POST, PUT, DELETE, OPTIONS\");\n{{#if (eq auth \"better-auth\")}}\n\t\tnewHeaders.set(\"Access-Control-Allow-Headers\", \"Content-Type, Authorization\");\n\t\tnewHeaders.set(\"Access-Control-Allow-Credentials\", \"true\");\n{{else}}\n\t\tnewHeaders.set(\"Access-Control-Allow-Headers\", \"Content-Type\");\n{{/if}}\n\n\t\treturn new globalThis.Response(response.body, {\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\theaders: newHeaders,\n\t\t});\n\t};\n};\n\nconst server = Bun.serve({\n\tport: 3000,\n\tfetch: corsMiddleware(router),\n});\n\nconsole.log(\\`Server is running on http://localhost:\\${server.port}\\`);\nconsole.log(\\`Swagger UI is available at http://localhost:\\${server.port}/docs\\`);\n{{/if}}\n{{#if (eq runtime \"workers\")}}\nexport default router;\n{{/if}}\n{{/if}}\n`],\n [\"auth/better-auth/convex/backend/convex/auth.ts.hbs\", `import { createClient, type GenericCtx } from \"@convex-dev/better-auth\";\n{{#if (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\"))}}\nimport { convex } from \"@convex-dev/better-auth/plugins\";\nimport { expo } from \"@better-auth/expo\";\n{{else if (or (includes frontend \"tanstack-router\") (includes frontend \"react-router\") (includes frontend \"nuxt\") (includes frontend \"svelte\") (includes frontend \"solid\"))}}\nimport { convex, crossDomain } from \"@convex-dev/better-auth/plugins\";\n{{else}}\nimport { convex } from \"@convex-dev/better-auth/plugins\";\n{{/if}}\nimport { components } from \"./_generated/api\";\nimport type { DataModel } from \"./_generated/dataModel\";\nimport { query } from \"./_generated/server\";\nimport { betterAuth } from \"better-auth\";\nimport authConfig from \"./auth.config\";\n\n{{#if (or (includes frontend \"tanstack-start\") (includes frontend \"next\"))}}\nconst siteUrl = process.env.SITE_URL!;\n{{else if (or (includes frontend \"tanstack-router\") (includes frontend \"react-router\") (includes frontend \"nuxt\") (includes frontend \"svelte\") (includes frontend \"solid\"))}}\nconst siteUrl = process.env.SITE_URL!;\n{{/if}}\n{{#if (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\"))}}\nconst nativeAppUrl = process.env.NATIVE_APP_URL || \"mybettertapp://\";\n{{/if}}\n\nexport const authComponent = createClient<DataModel>(components.betterAuth);\n\nfunction createAuth(ctx: GenericCtx<DataModel>) {\n return betterAuth({\n {{#if (and (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\")) (or (includes frontend \"tanstack-start\") (includes frontend \"next\")))}}\n baseURL: siteUrl,\n trustedOrigins: [siteUrl, nativeAppUrl],\n {{else if (and (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\")) (or (includes frontend \"tanstack-router\") (includes frontend \"react-router\") (includes frontend \"nuxt\") (includes frontend \"svelte\") (includes frontend \"solid\")))}}\n trustedOrigins: [siteUrl, nativeAppUrl],\n {{else if (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\"))}}\n trustedOrigins: [nativeAppUrl],\n {{else if (or (includes frontend \"tanstack-start\") (includes frontend \"next\"))}}\n baseURL: siteUrl,\n trustedOrigins: [siteUrl],\n {{else if (or (includes frontend \"tanstack-router\") (includes frontend \"react-router\") (includes frontend \"nuxt\") (includes frontend \"svelte\") (includes frontend \"solid\"))}}\n trustedOrigins: [siteUrl],\n {{/if}}\n database: authComponent.adapter(ctx),\n emailAndPassword: {\n enabled: true,\n requireEmailVerification: false,\n },\n plugins: [\n {{#if (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\"))}}\n expo(),\n {{else if (or (includes frontend \"tanstack-router\") (includes frontend \"react-router\") (includes frontend \"nuxt\") (includes frontend \"svelte\") (includes frontend \"solid\"))}}\n crossDomain({ siteUrl }),\n {{/if}}\n convex({\n authConfig,\n jwksRotateOnTokenGenerationError: true,\n }),\n ],\n });\n}\n\nexport { createAuth };\n\nexport const getCurrentUser = query({\n args: {},\n handler: async (ctx) => {\n return await authComponent.safeGetAuthUser(ctx);\n },\n});\n`],\n [\"auth/better-auth/convex/backend/convex/http.ts.hbs\", `import { httpRouter } from \"convex/server\";\nimport { authComponent, createAuth } from \"./auth\";\n\nconst http = httpRouter();\n\n{{#if (or (includes frontend \"tanstack-router\") (includes frontend \"react-router\") (includes frontend \"nuxt\") (includes frontend \"svelte\") (includes frontend \"solid\"))}}\nauthComponent.registerRoutes(http, createAuth, { cors: true });\n{{else}}\nauthComponent.registerRoutes(http, createAuth);\n{{/if}}\n\nexport default http;\n`],\n [\"auth/better-auth/convex/backend/convex/auth.config.ts.hbs\", `import { getAuthConfigProvider } from \"@convex-dev/better-auth/auth-config\";\nimport type { AuthConfig } from \"convex/server\";\n\nexport default {\n providers: [getAuthConfigProvider()],\n} satisfies AuthConfig;\n`],\n [\"auth/better-auth/convex/backend/convex/privateData.ts.hbs\", `import { query } from \"./_generated/server\";\nimport { authComponent } from \"./auth\";\n\nexport const get = query({\n args: {},\n handler: async (ctx) => {\n const authUser = await authComponent.safeGetAuthUser(ctx);\n if (!authUser) {\n return {\n message: \"Not authenticated\",\n };\n }\n return {\n message: \"This is private\",\n };\n },\n});\n`],\n [\"auth/clerk/convex/backend/convex/auth.config.ts.hbs\", `export default {\n\tproviders: [\n\t\t{\n\t\t\t// Replace with your own Clerk Issuer URL from your \"convex\" JWT template\n\t\t\t// or with \\`process.env.CLERK_JWT_ISSUER_DOMAIN\\`\n\t\t\t// and configure CLERK_JWT_ISSUER_DOMAIN on the Convex Dashboard\n\t\t\t// See https://docs.convex.dev/auth/clerk#configuring-dev-and-prod-instances\n\t\t\tdomain: process.env.CLERK_JWT_ISSUER_DOMAIN,\n\t\t\tapplicationID: \"convex\",\n\t\t},\n\t],\n};\n`],\n [\"auth/clerk/convex/backend/convex/privateData.ts.hbs\", `import { query } from \"./_generated/server\";\n\nexport const get = query({\n\targs: {},\n\thandler: async (ctx) => {\n\t\tconst identity = await ctx.auth.getUserIdentity();\n\t\tif (identity === null) {\n\t\t\treturn {\n\t\t\t\tmessage: \"Not authenticated\",\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tmessage: \"This is private\",\n\t\t};\n\t},\n});\n`],\n [\"auth/better-auth/server/base/src/index.ts.hbs\", `{{#if (eq orm \"prisma\")}}\nimport { betterAuth } from \"better-auth\";\nimport { prismaAdapter } from \"better-auth/adapters/prisma\";\nimport { env } from \"@{{projectName}}/env/server\";\n{{#if (eq payments \"polar\")}}\nimport { polar, checkout, portal } from \"@polar-sh/better-auth\";\nimport { polarClient } from \"./lib/payments\";\n{{/if}}\nimport prisma from \"@{{projectName}}/db\";\n\nexport const auth = betterAuth({\n\tdatabase: prismaAdapter(prisma, {\n{{#if (eq database \"postgres\")}}provider: \"postgresql\",{{/if}}\n{{#if (eq database \"sqlite\")}}provider: \"sqlite\",{{/if}}\n{{#if (eq database \"mysql\")}}provider: \"mysql\",{{/if}}\n{{#if (eq database \"mongodb\")}}provider: \"mongodb\",{{/if}}\n\t}),\n\n\ttrustedOrigins: [\n\t\tenv.CORS_ORIGIN,\n{{#if (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\"))}}\n\t\t\"mybettertapp://\", \"exp://\"\n{{/if}}\n\t],\n\temailAndPassword: {\n\t\tenabled: true,\n\t},\n{{#if (ne backend \"self\")}}\n\tadvanced: {\n\t\tdefaultCookieAttributes: {\n\t\t\tsameSite: \"none\",\n\t\t\tsecure: true,\n\t\t\thttpOnly: true,\n\t\t},\n\t},\n{{/if}}\n\tplugins: [\n{{#if (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\"))}}\n expo(),\n{{/if}}\n{{#if (and (eq backend \"self\") (includes frontend \"tanstack-start\"))}}\n tanstackStartCookies(),\n{{/if}}\n{{#if (and (eq backend \"self\") (includes frontend \"next\"))}}\n nextCookies(),\n{{/if}}\n{{#if (eq payments \"polar\")}}\n\t\tpolar({\n\t\t\tclient: polarClient,\n\t\t\tcreateCustomerOnSignUp: true,\n\t\t\tenableCustomerPortal: true,\n\t\t\tuse: [\n\t\t\t\tcheckout({\n\t\t\t\t\tproducts: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tproductId: \"your-product-id\",\n\t\t\t\t\t\t\tslug: \"pro\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tsuccessUrl: env.POLAR_SUCCESS_URL,\n\t\t\t\t\tauthenticatedUsersOnly: true,\n\t\t\t\t}),\n\t\t\t\tportal(),\n\t\t\t],\n\t\t}),\n{{/if}}\n\t],\n});\n{{/if}}\n\n{{#if (eq orm \"drizzle\")}}\n{{#if (or (eq runtime \"bun\") (eq runtime \"node\") (eq runtime \"none\"))}}\nimport { betterAuth } from \"better-auth\";\nimport { drizzleAdapter } from \"better-auth/adapters/drizzle\";\nimport { env } from \"@{{projectName}}/env/server\";\n{{#if (eq payments \"polar\")}}\nimport { polar, checkout, portal } from \"@polar-sh/better-auth\";\nimport { polarClient } from \"./lib/payments\";\n{{/if}}\nimport { db } from \"@{{projectName}}/db\";\nimport * as schema from \"@{{projectName}}/db/schema/auth\";\n{{#if (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\"))}}\nimport { expo } from \"@better-auth/expo\";\n{{/if}}\n{{#if (and (eq backend \"self\") (includes frontend \"tanstack-start\"))}}\nimport { tanstackStartCookies } from \"better-auth/tanstack-start\";\n{{/if}}\n{{#if (and (eq backend \"self\") (includes frontend \"next\"))}}\nimport { nextCookies } from \"better-auth/next-js\";\n{{/if}}\n\nexport const auth = betterAuth({\n\tdatabase: drizzleAdapter(db, {\n{{#if (eq database \"postgres\")}}provider: \"pg\",{{/if}}\n{{#if (eq database \"sqlite\")}}provider: \"sqlite\",{{/if}}\n{{#if (eq database \"mysql\")}}provider: \"mysql\",{{/if}}\n\t\tschema: schema,\n\t}),\n\ttrustedOrigins: [\n\t\tenv.CORS_ORIGIN,\n{{#if (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\"))}}\n\t\t\"mybettertapp://\", \"exp://\"\n{{/if}}\n\t],\n\temailAndPassword: {\n\t\tenabled: true,\n\t},\n{{#if (ne backend \"self\")}}\n\tadvanced: {\n\t\tdefaultCookieAttributes: {\n\t\t\tsameSite: \"none\",\n\t\t\tsecure: true,\n\t\t\thttpOnly: true,\n\t\t},\n\t},\n{{/if}}\n\tplugins: [\n{{#if (eq payments \"polar\")}}\n\t\tpolar({\n\t\t\tclient: polarClient,\n\t\t\tcreateCustomerOnSignUp: true,\n\t\t\tenableCustomerPortal: true,\n\t\t\tuse: [\n\t\t\t\tcheckout({\n\t\t\t\t\tproducts: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tproductId: \"your-product-id\",\n\t\t\t\t\t\t\tslug: \"pro\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tsuccessUrl: env.POLAR_SUCCESS_URL,\n\t\t\t\t\tauthenticatedUsersOnly: true,\n\t\t\t\t}),\n\t\t\t\tportal(),\n\t\t\t],\n\t\t}),\n{{/if}}\n\t],\n});\n{{/if}}\n\n{{#if (eq runtime \"workers\")}}\nimport { betterAuth } from \"better-auth\";\nimport { drizzleAdapter } from \"better-auth/adapters/drizzle\";\nimport { env } from \"@{{projectName}}/env/server\";\n{{#if (eq payments \"polar\")}}\nimport { polar, checkout, portal } from \"@polar-sh/better-auth\";\nimport { polarClient } from \"./lib/payments\";\n{{/if}}\nimport { db } from \"@{{projectName}}/db\";\nimport * as schema from \"@{{projectName}}/db/schema/auth\";\n\n\nexport const auth = betterAuth({\n\tdatabase: drizzleAdapter(db, {\n{{#if (eq database \"postgres\")}}provider: \"pg\",{{/if}}\n{{#if (eq database \"sqlite\")}}provider: \"sqlite\",{{/if}}\n{{#if (eq database \"mysql\")}}provider: \"mysql\",{{/if}}\n\t\tschema: schema,\n\t}),\n\ttrustedOrigins: [\n\t\tenv.CORS_ORIGIN,\n{{#if (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\"))}}\n\t\t\"mybettertapp://\", \"exp://\"\n{{/if}}\n\t],\n\temailAndPassword: {\n\t\tenabled: true,\n\t},\n\t// uncomment cookieCache setting when ready to deploy to Cloudflare using *.workers.dev domains\n\t// session: {\n\t// cookieCache: {\n\t// enabled: true,\n\t// maxAge: 60,\n\t// },\n\t// },\n\tsecret: env.BETTER_AUTH_SECRET,\n\tbaseURL: env.BETTER_AUTH_URL,\n\tadvanced: {\n\t\tdefaultCookieAttributes: {\n\t\t\tsameSite: \"none\",\n\t\t\tsecure: true,\n\t\t\thttpOnly: true,\n\t\t},\n\t\t// uncomment crossSubDomainCookies setting when ready to deploy and replace <your-workers-subdomain> with your actual workers subdomain\n\t\t// https://developers.cloudflare.com/workers/wrangler/configuration/#workersdev\n\t\t// crossSubDomainCookies: {\n\t\t// enabled: true,\n\t\t// domain: \"<your-workers-subdomain>\",\n\t\t// },\n\t},\n{{#if (eq payments \"polar\")}}\n\tplugins: [\n\t\tpolar({\n\t\t\tclient: polarClient,\n\t\t\tcreateCustomerOnSignUp: true,\n\t\t\tenableCustomerPortal: true,\n\t\t\tuse: [\n\t\t\t\tcheckout({\n\t\t\t\t\tproducts: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tproductId: \"your-product-id\",\n\t\t\t\t\t\t\tslug: \"pro\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tsuccessUrl: env.POLAR_SUCCESS_URL,\n\t\t\t\t\tauthenticatedUsersOnly: true,\n\t\t\t\t}),\n\t\t\t\tportal(),\n\t\t\t],\n\t\t}),\n\t],\n{{/if}}\n});\n{{/if}}\n{{/if}}\n\n{{#if (eq orm \"mongoose\")}}\nimport { betterAuth } from \"better-auth\";\nimport { mongodbAdapter } from \"better-auth/adapters/mongodb\";\nimport { env } from \"@{{projectName}}/env/server\";\n{{#if (eq payments \"polar\")}}\nimport { polar, checkout, portal } from \"@polar-sh/better-auth\";\nimport { polarClient } from \"./lib/payments\";\n{{/if}}\nimport { client } from \"@{{projectName}}/db\";\n\nexport const auth = betterAuth({\n\tdatabase: mongodbAdapter(client),\n\ttrustedOrigins: [\n\t\tenv.CORS_ORIGIN,\n{{#if (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\"))}}\n\t\t\"mybettertapp://\", \"exp://\"\n{{/if}}\n\t],\n\temailAndPassword: {\n\t\tenabled: true,\n\t},\n{{#if (ne backend \"self\")}}\n\tadvanced: {\n\t\tdefaultCookieAttributes: {\n\t\t\tsameSite: \"none\",\n\t\t\tsecure: true,\n\t\t\thttpOnly: true,\n\t\t},\n\t},\n{{/if}}\n{{#if (eq payments \"polar\")}}\n\tplugins: [\n\t\tpolar({\n\t\t\tclient: polarClient,\n\t\t\tcreateCustomerOnSignUp: true,\n\t\t\tenableCustomerPortal: true,\n\t\t\tuse: [\n\t\t\t\tcheckout({\n\t\t\t\t\tproducts: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tproductId: \"your-product-id\",\n\t\t\t\t\t\t\tslug: \"pro\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tsuccessUrl: env.POLAR_SUCCESS_URL,\n\t\t\t\t\tauthenticatedUsersOnly: true,\n\t\t\t\t}),\n\t\t\t\tportal(),\n\t\t\t],\n\t\t}),\n\t],\n{{/if}}\n});\n{{/if}}\n\n{{#if (eq orm \"none\")}}\nimport { betterAuth } from \"better-auth\";\nimport { env } from \"@{{projectName}}/env/server\";\n{{#if (eq payments \"polar\")}}\nimport { polar, checkout, portal } from \"@polar-sh/better-auth\";\nimport { polarClient } from \"./lib/payments\";\n{{/if}}\n\n\nexport const auth = betterAuth({\n\tdatabase: \"\", // Invalid configuration\n\ttrustedOrigins: [\n\t\tenv.CORS_ORIGIN,\n{{#if (or (includes frontend \"native-bare\") (includes frontend \"native-uniwind\") (includes frontend \"native-unistyles\"))}}\n\t\t\"mybettertapp://\", \"exp://\"\n{{/if}}\n\t],\n\temailAndPassword: {\n\t\tenabled: true,\n\t},\n{{#if (ne backend \"self\")}}\n\tadvanced: {\n\t\tdefaultCookieAttributes: {\n\t\t\tsameSite: \"none\",\n\t\t\tsecure: true,\n\t\t\thttpOnly: true,\n\t\t},\n\t},\n{{/if}}\n{{#if (eq payments \"polar\")}}\n\tplugins: [\n\t\tpolar({\n\t\t\tclient: polarClient,\n\t\t\tcreateCustomerOnSignUp: true,\n\t\t\tenableCustomerPortal: true,\n\t\t\tuse: [\n\t\t\t\tcheckout({\n\t\t\t\t\tproducts: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tproductId: \"your-product-id\",\n\t\t\t\t\t\t\tslug: \"pro\",\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tsuccessUrl: env.POLAR_SUCCESS_URL,\n\t\t\t\t\tauthenticatedUsersOnly: true,\n\t\t\t\t}),\n\t\t\t\tportal(),\n\t\t\t],\n\t\t}),\n\t],\n{{/if}}\n});\n{{/if}}`],\n [\"email/react-email/components/src/emails/welcome.tsx.hbs\", `import {\n Body,\n Button,\n Container,\n Head,\n Heading,\n Html,\n Link,\n Preview,\n Section,\n Text,\n} from \"@react-email/components\";\n\ninterface WelcomeEmailProps {\n username?: string;\n loginUrl?: string;\n}\n\nexport function WelcomeEmail({\n username = \"there\",\n loginUrl = \"{{#if (includes frontend 'next')}}http://localhost:3000{{else}}http://localhost:5173{{/if}}\",\n}: WelcomeEmailProps) {\n return (\n <Html>\n <Head />\n <Preview>Welcome to {{projectName}}!</Preview>\n <Body style={main}>\n <Container style={container}>\n <Heading style={h1}>Welcome to {{projectName}}!</Heading>\n <Text style={text}>Hi {username},</Text>\n <Text style={text}>\n Thanks for signing up! We're excited to have you on board.\n </Text>\n <Section style={buttonContainer}>\n <Button style={button} href={loginUrl}>\n Get Started\n </Button>\n </Section>\n <Text style={footer}>\n If you didn't create an account, you can safely ignore this email.\n </Text>\n </Container>\n </Body>\n </Html>\n );\n}\n\nexport default WelcomeEmail;\n\nconst main = {\n backgroundColor: \"#f6f9fc\",\n fontFamily:\n '-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Ubuntu,sans-serif',\n};\n\nconst container = {\n backgroundColor: \"#ffffff\",\n margin: \"0 auto\",\n padding: \"20px 0 48px\",\n marginBottom: \"64px\",\n borderRadius: \"5px\",\n maxWidth: \"600px\",\n};\n\nconst h1 = {\n color: \"#333\",\n fontSize: \"24px\",\n fontWeight: \"bold\",\n margin: \"40px 0\",\n padding: \"0\",\n textAlign: \"center\" as const,\n};\n\nconst text = {\n color: \"#333\",\n fontSize: \"16px\",\n lineHeight: \"26px\",\n padding: \"0 48px\",\n};\n\nconst buttonContainer = {\n padding: \"27px 0 27px\",\n textAlign: \"center\" as const,\n};\n\nconst button = {\n backgroundColor: \"#000\",\n borderRadius: \"5px\",\n color: \"#fff\",\n fontSize: \"16px\",\n fontWeight: \"bold\",\n textDecoration: \"none\",\n textAlign: \"center\" as const,\n display: \"inline-block\",\n padding: \"12px 30px\",\n};\n\nconst footer = {\n color: \"#898989\",\n fontSize: \"12px\",\n lineHeight: \"22px\",\n padding: \"0 48px\",\n marginTop: \"20px\",\n};\n`],\n [\"email/react-email/components/src/emails/index.ts.hbs\", `export { WelcomeEmail } from \"./welcome\";\n`],\n [\"auth/nextauth/fullstack/next/src/middleware.ts.hbs\", `export { auth as middleware } from \"@/lib/auth\";\n\nexport const config = {\n matcher: [\n // Skip Next.js internals and all static files\n \"/((?!_next|[^?]*\\\\\\\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)\",\n // Always run for API routes\n \"/(api|trpc)(.*)\",\n ],\n};\n`],\n [\"email/resend/components/src/emails/welcome.tsx.hbs\", `import {\n Body,\n Button,\n Container,\n Head,\n Heading,\n Html,\n Link,\n Preview,\n Section,\n Text,\n} from \"@react-email/components\";\n\ninterface WelcomeEmailProps {\n username?: string;\n loginUrl?: string;\n}\n\nexport function WelcomeEmail({\n username = \"there\",\n loginUrl = \"{{#if (includes frontend 'next')}}http://localhost:3000{{else}}http://localhost:5173{{/if}}\",\n}: WelcomeEmailProps) {\n return (\n <Html>\n <Head />\n <Preview>Welcome to {{projectName}}!</Preview>\n <Body style={main}>\n <Container style={container}>\n <Heading style={h1}>Welcome to {{projectName}}!</Heading>\n <Text style={text}>Hi {username},</Text>\n <Text style={text}>\n Thanks for signing up! We're excited to have you on board.\n </Text>\n <Section style={buttonContainer}>\n <Button style={button} href={loginUrl}>\n Get Started\n </Button>\n </Section>\n <Text style={footer}>\n If you didn't create an account, you can safely ignore this email.\n </Text>\n </Container>\n </Body>\n </Html>\n );\n}\n\nexport default WelcomeEmail;\n\nconst main = {\n backgroundColor: \"#f6f9fc\",\n fontFamily:\n '-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Ubuntu,sans-serif',\n};\n\nconst container = {\n backgroundColor: \"#ffffff\",\n margin: \"0 auto\",\n padding: \"20px 0 48px\",\n marginBottom: \"64px\",\n borderRadius: \"5px\",\n maxWidth: \"600px\",\n};\n\nconst h1 = {\n color: \"#333\",\n fontSize: \"24px\",\n fontWeight: \"bold\",\n margin: \"40px 0\",\n padding: \"0\",\n textAlign: \"center\" as const,\n};\n\nconst text = {\n color: \"#333\",\n fontSize: \"16px\",\n lineHeight: \"26px\",\n padding: \"0 48px\",\n};\n\nconst buttonContainer = {\n padding: \"27px 0 27px\",\n textAlign: \"center\" as const,\n};\n\nconst button = {\n backgroundColor: \"#000\",\n borderRadius: \"5px\",\n color: \"#fff\",\n fontSize: \"16px\",\n fontWeight: \"bold\",\n textDecoration: \"none\",\n textAlign: \"center\" as const,\n display: \"inline-block\",\n padding: \"12px 30px\",\n};\n\nconst footer = {\n color: \"#898989\",\n fontSize: \"12px\",\n lineHeight: \"22px\",\n padding: \"0 48px\",\n marginTop: \"20px\",\n};\n`],\n [\"email/resend/components/src/emails/index.ts.hbs\", `export { WelcomeEmail } from \"./welcome\";\n`],\n [\"auth/better-auth/native/base/lib/auth-client.ts.hbs\", `import { expoClient } from \"@better-auth/expo/client\";\nimport { createAuthClient } from \"better-auth/react\";\nimport * as SecureStore from \"expo-secure-store\";\nimport Constants from \"expo-constants\";\nimport { env } from \"@{{projectName}}/env/native\";\n\nexport const authClient = createAuthClient({\n\tbaseURL: env.EXPO_PUBLIC_SERVER_URL,\n\tplugins: [\n\t\texpoClient({\n\t\t\tscheme: Constants.expoConfig?.scheme as string,\n\t\t\tstoragePrefix: Constants.expoConfig?.scheme as string,\n\t\t\tstorage: SecureStore,\n\t\t}),\n\t],\n});\n`],\n [\"auth/better-auth/native/uniwind/components/sign-up.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\n{{#if (eq api \"trpc\")}}\nimport { queryClient } from \"@/utils/trpc\";\n{{/if}}\n{{#if (eq api \"orpc\")}}\nimport { queryClient } from \"@/utils/orpc\";\n{{/if}}\nimport { useState } from \"react\";\nimport { Text, View } from \"react-native\";\nimport { Button, ErrorView, Spinner, Surface, TextField } from \"heroui-native\";\n\nfunction signUpHandler({\nname,\nemail,\npassword,\nsetError,\nsetIsLoading,\nsetName,\nsetEmail,\nsetPassword,\n}: {\n name: string;\n email: string;\n password: string;\n setError: (error: string | null) => void;\n setIsLoading: (loading: boolean) => void;\n setName: (name: string) => void;\n setEmail: (email: string) => void;\n setPassword: (password: string) => void;\n}) {\nsetIsLoading(true);\nsetError(null);\n\nauthClient.signUp.email(\n{\nname,\nemail,\npassword,\n},\n{\nonError(error) {\nsetError(error.error?.message || \"Failed to sign up\");\nsetIsLoading(false);\n},\nonSuccess() {\nsetName(\"\");\nsetEmail(\"\");\nsetPassword(\"\");\n{{#if (eq api \"orpc\")}}\nqueryClient.refetchQueries();\n{{/if}}\n{{#if (eq api \"trpc\")}}\nqueryClient.refetchQueries();\n{{/if}}\n},\nonFinished() {\nsetIsLoading(false);\n},\n}\n);\n}\n\nexport function SignUp() {\nconst [name, setName] = useState(\"\");\nconst [email, setEmail] = useState(\"\");\nconst [password, setPassword] = useState(\"\");\nconst [isLoading, setIsLoading] = useState(false);\nconst [error, setError] = useState<string | null>(null);\n\n function handlePress() {\n signUpHandler({\n name,\n email,\n password,\n setError,\n setIsLoading,\n setName,\n setEmail,\n setPassword,\n });\n }\n\n return (\n <Surface variant=\"secondary\" className=\"p-4 rounded-lg\">\n <Text className=\"text-foreground font-medium mb-4\">Create Account</Text>\n\n <ErrorView isInvalid={!!error} className=\"mb-3\">\n {error}\n </ErrorView>\n\n <View className=\"gap-3\">\n <TextField>\n <TextField.Label>Name</TextField.Label>\n <TextField.Input value={name} onChangeText={setName} placeholder=\"John Doe\" />\n </TextField>\n\n <TextField>\n <TextField.Label>Email</TextField.Label>\n <TextField.Input\n value={email}\n onChangeText={setEmail}\n placeholder=\"email@example.com\"\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n />\n </TextField>\n\n <TextField>\n <TextField.Label>Password</TextField.Label>\n <TextField.Input\n value={password}\n onChangeText={setPassword}\n placeholder=\"••••••••\"\n secureTextEntry\n />\n </TextField>\n\n <Button onPress={handlePress} isDisabled={isLoading} className=\"mt-1\">\n {isLoading ? (\n <Spinner size=\"sm\" color=\"default\" />\n ) : (\n <Button.Label>Create Account</Button.Label>\n )}\n </Button>\n </View>\n </Surface>\n );\n }`],\n [\"auth/better-auth/native/uniwind/components/sign-in.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\n{{#if (eq api \"trpc\")}}\nimport { queryClient } from \"@/utils/trpc\";\n{{/if}}\n{{#if (eq api \"orpc\")}}\nimport { queryClient } from \"@/utils/orpc\";\n{{/if}}\nimport { useState } from \"react\";\nimport { Text, View } from \"react-native\";\nimport { Button, ErrorView, Spinner, Surface, TextField } from \"heroui-native\";\n\nfunction SignIn() {\nconst [email, setEmail] = useState(\"\");\nconst [password, setPassword] = useState(\"\");\nconst [isLoading, setIsLoading] = useState(false);\nconst [error, setError] = useState<string | null>(null);\n\n async function handleLogin() {\n setIsLoading(true);\n setError(null);\n\n await authClient.signIn.email(\n {\n email,\n password,\n },\n {\n onError(error) {\n setError(error.error?.message || \"Failed to sign in\");\n setIsLoading(false);\n },\n onSuccess() {\n setEmail(\"\");\n setPassword(\"\");\n {{#if (eq api \"orpc\")}}\n queryClient.refetchQueries();\n {{/if}}\n {{#if (eq api \"trpc\")}}\n queryClient.refetchQueries();\n {{/if}}\n },\n onFinished() {\n setIsLoading(false);\n },\n }\n );\n }\n\n return (\n <Surface variant=\"secondary\" className=\"p-4 rounded-lg\">\n <Text className=\"text-foreground font-medium mb-4\">Sign In</Text>\n\n <ErrorView isInvalid={!!error} className=\"mb-3\">\n {error}\n </ErrorView>\n\n <View className=\"gap-3\">\n <TextField>\n <TextField.Label>Email</TextField.Label>\n <TextField.Input\n value={email}\n onChangeText={setEmail}\n placeholder=\"email@example.com\"\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n />\n </TextField>\n\n <TextField>\n <TextField.Label>Password</TextField.Label>\n <TextField.Input\n value={password}\n onChangeText={setPassword}\n placeholder=\"••••••••\"\n secureTextEntry\n />\n </TextField>\n\n <Button onPress={handleLogin} isDisabled={isLoading} className=\"mt-1\">\n {isLoading ? <Spinner size=\"sm\" color=\"default\" /> : <Button.Label>Sign In</Button.Label>}\n </Button>\n </View>\n </Surface>\n );\n }\n\n export { SignIn };`],\n [\"auth/better-auth/native/bare/components/sign-up.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\n{{#if (eq api \"trpc\")}}\nimport { queryClient } from \"@/utils/trpc\";\n{{/if}}\n{{#if (eq api \"orpc\")}}\nimport { queryClient } from \"@/utils/orpc\";\n{{/if}}\nimport { useState } from \"react\";\nimport {\n ActivityIndicator,\n Text,\n TextInput,\n TouchableOpacity,\n View,\n StyleSheet,\n} from \"react-native\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\n\nfunction SignUp() {\n const { colorScheme } = useColorScheme();\n const theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\n const [name, setName] = useState(\"\");\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n async function handleSignUp() {\n setIsLoading(true);\n setError(null);\n\n await authClient.signUp.email(\n {\n name,\n email,\n password,\n },\n {\n onError(error) {\n setError(error.error?.message || \"Failed to sign up\");\n setIsLoading(false);\n },\n onSuccess() {\n setName(\"\");\n setEmail(\"\");\n setPassword(\"\");\n {{#if (eq api \"orpc\")}}\n queryClient.refetchQueries();\n {{/if}}\n {{#if (eq api \"trpc\")}}\n queryClient.refetchQueries();\n {{/if}}\n },\n onFinished() {\n setIsLoading(false);\n },\n }\n );\n }\n\n return (\n <View style={[styles.card, { backgroundColor: theme.card, borderColor: theme.border }]}>\n <Text style={[styles.title, { color: theme.text }]}>Create Account</Text>\n\n {error ? (\n <View style={[styles.errorContainer, { backgroundColor: theme.notification + \"20\" }]}>\n <Text style={[styles.errorText, { color: theme.notification }]}>{error}</Text>\n </View>\n ) : null}\n\n <TextInput\n style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}\n placeholder=\"Name\"\n placeholderTextColor={theme.text}\n value={name}\n onChangeText={setName}\n />\n\n <TextInput\n style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}\n placeholder=\"Email\"\n placeholderTextColor={theme.text}\n value={email}\n onChangeText={setEmail}\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n />\n\n <TextInput\n style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}\n placeholder=\"Password\"\n placeholderTextColor={theme.text}\n value={password}\n onChangeText={setPassword}\n secureTextEntry\n />\n\n <TouchableOpacity\n onPress={handleSignUp}\n disabled={isLoading}\n style={[styles.button, { backgroundColor: theme.primary, opacity: isLoading ? 0.5 : 1 }]}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color=\"#ffffff\" />\n ) : (\n <Text style={styles.buttonText}>Sign Up</Text>\n )}\n </TouchableOpacity>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n card: {\n marginTop: 16,\n padding: 16,\n borderWidth: 1,\n },\n title: {\n fontSize: 18,\n fontWeight: \"bold\",\n marginBottom: 12,\n },\n errorContainer: {\n marginBottom: 12,\n padding: 8,\n },\n errorText: {\n fontSize: 14,\n },\n input: {\n borderWidth: 1,\n padding: 12,\n fontSize: 16,\n marginBottom: 12,\n },\n button: {\n padding: 12,\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n buttonText: {\n color: \"#ffffff\",\n fontSize: 16,\n },\n});\n\nexport { SignUp };\n\n`],\n [\"auth/better-auth/native/bare/components/sign-in.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\n{{#if (eq api \"trpc\")}}\nimport { queryClient } from \"@/utils/trpc\";\n{{/if}}\n{{#if (eq api \"orpc\")}}\nimport { queryClient } from \"@/utils/orpc\";\n{{/if}}\nimport { useState } from \"react\";\nimport {\nActivityIndicator,\nText,\nTextInput,\nTouchableOpacity,\nView,\nStyleSheet,\n} from \"react-native\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\n\nfunction SignIn() {\nconst { colorScheme } = useColorScheme();\nconst theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\nconst [form, setForm] = useState({ email: \"\", password: \"\" });\nconst [isLoading, setIsLoading] = useState(false);\nconst [error, setError] = useState<string | null>(null);\n\n function handleFormChange(field: \"email\" | \"password\", value: string) {\n setForm(prev => ({ ...prev, [field]: value }));\n }\n\n async function handleLogin() {\n setIsLoading(true);\n setError(null);\n\n await authClient.signIn.email(\n {\n email: form.email,\n password: form.password,\n },\n {\n onError(error) {\n setError(error.error?.message || \"Failed to sign in\");\n setIsLoading(false);\n },\n onSuccess() {\n setForm({ email: \"\", password: \"\" });\n {{#if (eq api \"orpc\")}}\n queryClient.refetchQueries();\n {{/if}}\n {{#if (eq api \"trpc\")}}\n queryClient.refetchQueries();\n {{/if}}\n },\n onFinished() {\n setIsLoading(false);\n },\n }\n );\n }\n\n return (\n <View style={[styles.card, { backgroundColor: theme.card, borderColor: theme.border }]}>\n <Text style={[styles.title, { color: theme.text }]}>Sign In</Text>\n\n {error ? (\n <View style={[styles.errorContainer, { backgroundColor: theme.notification + \"20\" }]}>\n <Text style={[styles.errorText, { color: theme.notification }]}>{error}</Text>\n </View>\n ) : null}\n\n <TextInput style={[ styles.input, { color: theme.text, borderColor: theme.border, backgroundColor:\n theme.background }, ]} placeholder=\"Email\" placeholderTextColor={theme.text} value={form.email}\n onChangeText={value=> handleFormChange(\"email\", value)}\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n />\n\n <TextInput style={[ styles.input, { color: theme.text, borderColor: theme.border, backgroundColor:\n theme.background }, ]} placeholder=\"Password\" placeholderTextColor={theme.text} value={form.password}\n onChangeText={value=> handleFormChange(\"password\", value)}\n secureTextEntry\n />\n\n <TouchableOpacity onPress={handleLogin} disabled={isLoading} style={[ styles.button, { backgroundColor:\n theme.primary, opacity: isLoading ? 0.5 : 1 }, ]}>\n {isLoading ? (\n <ActivityIndicator size=\"small\" color=\"#ffffff\" />\n ) : (\n <Text style={styles.buttonText}>Sign In</Text>\n )}\n </TouchableOpacity>\n </View>\n );\n }\n\n const styles = StyleSheet.create({\n card: {\n marginTop: 16,\n padding: 16,\n borderWidth: 1,\n },\n title: {\n fontSize: 18,\n fontWeight: \"bold\",\n marginBottom: 12,\n },\n errorContainer: {\n marginBottom: 12,\n padding: 8,\n },\n errorText: {\n fontSize: 14,\n },\n input: {\n borderWidth: 1,\n padding: 12,\n fontSize: 16,\n marginBottom: 12,\n },\n button: {\n padding: 12,\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n buttonText: {\n color: \"#ffffff\",\n fontSize: 16,\n },\n });\n\n export { SignIn };`],\n [\"frontend/react/web-base/src/components/loader.tsx.hbs\", `import { Loader2 } from \"lucide-react\";\n\nexport default function Loader() {\n return (\n <div className=\"flex h-full items-center justify-center pt-8\">\n <Loader2 className=\"animate-spin\" />\n </div>\n );\n}\n`],\n [\"frontend/react/web-base/src/components/header.tsx.hbs\", `{{#if (includes frontend \"next\")}}\n\"use client\";\nimport Link from \"next/link\";\n{{else if (includes frontend \"react-router\")}}\nimport { NavLink } from \"react-router\";\n{{else if (or (includes frontend \"tanstack-router\") (includes frontend \"tanstack-start\"))}}\nimport { Link } from \"@tanstack/react-router\";\n{{/if}}\n{{#unless (includes frontend \"tanstack-start\")}}\nimport { ModeToggle } from \"./mode-toggle\";\n{{/unless}}\n{{#if (and (eq auth \"better-auth\") (ne backend \"convex\"))}}\nimport UserMenu from \"./user-menu\";\n{{/if}}\n\nexport default function Header() {\n const links = [\n { to: \"/\", label: \"Home\" },\n {{#if (or (eq auth \"better-auth\") (eq auth \"clerk\"))}}\n { to: \"/dashboard\", label: \"Dashboard\" },\n {{/if}}\n {{#if (includes examples \"todo\")}}\n { to: \"/todos\", label: \"Todos\" },\n {{/if}}\n {{#if (includes examples \"ai\")}}\n { to: \"/ai\", label: \"AI Chat\" },\n {{/if}}\n ] as const;\n\n return (\n <div>\n <div className=\"flex flex-row items-center justify-between px-2 py-1\">\n <nav className=\"flex gap-4 text-lg\">\n {links.map(({ to, label }) => {\n {{#if (includes frontend \"next\")}}\n return (\n <Link key={to} href={to}>\n {label}\n </Link>\n );\n {{else if (includes frontend \"react-router\")}}\n return (\n <NavLink\n key={to}\n to={to}\n className={({ isActive }) => isActive ? \"font-bold\" : \"\"}\n end\n >\n {label}\n </NavLink>\n );\n {{else if (or (includes frontend \"tanstack-router\") (includes frontend \"tanstack-start\"))}}\n return (\n <Link\n key={to}\n to={to}\n >\n {label}\n </Link>\n );\n {{else}}\n return null;\n {{/if}}\n })}\n </nav>\n <div className=\"flex items-center gap-2\">\n {{#unless (includes frontend \"tanstack-start\")}}\n <ModeToggle />\n {{/unless}}\n {{#if (and (eq auth \"better-auth\") (ne backend \"convex\"))}}\n <UserMenu />\n {{/if}}\n </div>\n </div>\n <hr />\n </div>\n );\n}\n`],\n [\"frontend/react/web-base/src/lib/utils.ts.hbs\", `import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n`],\n [\"frontend/qwik/src/components/router-head/router-head.tsx\", `import { component$ } from \"@builder.io/qwik\";\nimport { useDocumentHead, useLocation } from \"@builder.io/qwik-city\";\n\nexport const RouterHead = component$(() => {\n const head = useDocumentHead();\n const loc = useLocation();\n\n return (\n <>\n <title>{head.title}</title>\n\n <link rel=\"canonical\" href={loc.url.href} />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />\n\n {head.meta.map((m) => (\n <meta key={m.key} {...m} />\n ))}\n\n {head.links.map((l) => (\n <link key={l.key} {...l} />\n ))}\n\n {head.styles.map((s) => (\n <style\n key={s.key}\n {...s.props}\n {...(s.props?.dangerouslySetInnerHTML ? {} : { dangerouslySetInnerHTML: s.style })}\n />\n ))}\n\n {head.scripts.map((s) => (\n <script\n key={s.key}\n {...s.props}\n {...(s.props?.dangerouslySetInnerHTML ? {} : { dangerouslySetInnerHTML: s.script })}\n />\n ))}\n </>\n );\n});\n`],\n [\"frontend/react/tanstack-start/src/routes/__root.tsx.hbs\", `import { Toaster } from \"@/components/ui/sonner\";\n{{#unless (eq backend \"convex\")}} {{#unless (eq api \"none\")}}\nimport { ReactQueryDevtools } from \"@tanstack/react-query-devtools\";\n{{/unless}} {{/unless}}\nimport {\n HeadContent,\n Outlet,\n Scripts,\n createRootRouteWithContext,\n{{#if (and (eq backend \"convex\") (or (eq auth \"clerk\") (eq auth \"better-auth\")))}}\n useRouteContext,\n{{/if}}\n} from \"@tanstack/react-router\";\nimport { TanStackRouterDevtools } from \"@tanstack/react-router-devtools\";\nimport Header from \"../components/header\";\nimport appCss from \"../index.css?url\";\n{{#if (eq backend \"convex\")}}\nimport type { QueryClient } from \"@tanstack/react-query\";\nimport type { ConvexQueryClient } from \"@convex-dev/react-query\";\n{{else}}\n{{#if (or (eq api \"trpc\") (eq api \"orpc\"))}}\nimport type { QueryClient } from \"@tanstack/react-query\";\n{{/if}}\n{{/if}}\n\n{{#if (and (eq backend \"convex\") (eq auth \"clerk\"))}}\nimport { ClerkProvider, useAuth } from \"@clerk/tanstack-react-start\";\nimport { auth } from \"@clerk/tanstack-react-start/server\";\nimport { createServerFn } from \"@tanstack/react-start\";\nimport { ConvexProviderWithClerk } from \"convex/react-clerk\";\n\nconst fetchClerkAuth = createServerFn({ method: \"GET\" }).handler(async () => {\n const clerkAuth = await auth();\n const token = await clerkAuth.getToken({ template: \"convex\" });\n return { userId: clerkAuth.userId, token };\n});\n{{else if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\nimport { createServerFn } from \"@tanstack/react-start\";\nimport { ConvexBetterAuthProvider } from \"@convex-dev/better-auth/react\";\nimport { authClient } from \"@/lib/auth-client\";\nimport { getToken } from \"@/lib/auth-server\";\n\nconst getAuth = createServerFn({ method: \"GET\" }).handler(async () => {\n return await getToken();\n});\n{{else if (eq backend \"convex\")}}\nimport { ConvexProvider } from \"convex/react\";\n{{/if}}\n\n{{#if (eq backend \"convex\")}}\nexport interface RouterAppContext {\n queryClient: QueryClient;\n convexQueryClient: ConvexQueryClient;\n}\n{{else}}\n {{#if (eq api \"trpc\")}}\nimport type { TRPCOptionsProxy } from \"@trpc/tanstack-react-query\";\nimport type { AppRouter } from \"@{{projectName}}/api/routers/index\";\nexport interface RouterAppContext {\n trpc: TRPCOptionsProxy<AppRouter>;\n queryClient: QueryClient;\n}\n {{else if (eq api \"orpc\")}}\nimport type { orpc } from \"@/utils/orpc\";\nexport interface RouterAppContext {\n orpc: typeof orpc;\n queryClient: QueryClient;\n}\n {{else}}\nexport interface RouterAppContext {\n}\n {{/if}}\n{{/if}}\n\nexport const Route = createRootRouteWithContext<RouterAppContext>()({\n head: () => ({\n meta: [\n {\n charSet: \"utf-8\",\n },\n {\n name: \"viewport\",\n content: \"width=device-width, initial-scale=1\",\n },\n {\n title: \"My App\",\n },\n ],\n links: [\n {\n rel: \"stylesheet\",\n href: appCss,\n },\n ],\n }),\n\n component: RootDocument,\n {{#if (and (eq backend \"convex\") (eq auth \"clerk\"))}}\n beforeLoad: async (ctx) => {\n const { userId, token } = await fetchClerkAuth();\n if (token) {\n ctx.context.convexQueryClient.serverHttpClient?.setAuth(token);\n }\n return { userId, token };\n },\n {{else if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\n beforeLoad: async (ctx) => {\n const token = await getAuth();\n if (token) {\n ctx.context.convexQueryClient.serverHttpClient?.setAuth(token);\n }\n return {\n isAuthenticated: !!token,\n token,\n };\n },\n {{/if}}\n});\n\nfunction RootDocument() {\n {{#if (and (eq backend \"convex\") (eq auth \"clerk\"))}}\n const context = useRouteContext({ from: Route.id });\n return (\n <ClerkProvider>\n <ConvexProviderWithClerk client={context.convexQueryClient.convexClient} useAuth={useAuth}>\n <html lang=\"en\" className=\"dark\">\n <head>\n <HeadContent />\n </head>\n <body>\n <div className=\"grid h-svh grid-rows-[auto_1fr]\">\n <Header />\n <Outlet />\n </div>\n <Toaster richColors />\n <TanStackRouterDevtools position=\"bottom-left\" />\n <Scripts />\n </body>\n </html>\n </ConvexProviderWithClerk>\n </ClerkProvider>\n );\n {{else if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\n const context = useRouteContext({ from: Route.id });\n return (\n <ConvexBetterAuthProvider\n client={context.convexQueryClient.convexClient}\n authClient={authClient}\n initialToken={context.token}\n >\n <html lang=\"en\" className=\"dark\">\n <head>\n <HeadContent />\n </head>\n <body>\n <div className=\"grid h-svh grid-rows-[auto_1fr]\">\n <Header />\n <Outlet />\n </div>\n <Toaster richColors />\n <TanStackRouterDevtools position=\"bottom-left\" />\n <Scripts />\n </body>\n </html>\n </ConvexBetterAuthProvider>\n );\n {{else if (eq backend \"convex\")}}\n const { convexQueryClient } = Route.useRouteContext();\n return (\n <ConvexProvider client={convexQueryClient.convexClient}>\n <html lang=\"en\" className=\"dark\">\n <head>\n <HeadContent />\n </head>\n <body>\n <div className=\"grid h-svh grid-rows-[auto_1fr]\">\n <Header />\n <Outlet />\n </div>\n <Toaster richColors />\n <TanStackRouterDevtools position=\"bottom-left\" />\n <Scripts />\n </body>\n </html>\n </ConvexProvider>\n );\n {{else}}\n return (\n <html lang=\"en\" className=\"dark\">\n <head>\n <HeadContent />\n </head>\n <body>\n <div className=\"grid h-svh grid-rows-[auto_1fr]\">\n <Header />\n <Outlet />\n </div>\n <Toaster richColors />\n <TanStackRouterDevtools position=\"bottom-left\" />\n {{#unless (eq api \"none\")}}\n <ReactQueryDevtools position=\"bottom\" buttonPosition=\"bottom-right\" />\n {{/unless}}\n <Scripts />\n </body>\n </html>\n );\n {{/if}}\n}\n`],\n [\"frontend/react/tanstack-start/src/routes/index.tsx.hbs\", `import { createFileRoute } from \"@tanstack/react-router\";\n{{#if (eq backend \"convex\")}}\nimport { convexQuery } from \"@convex-dev/react-query\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\n{{else if (or (eq api \"trpc\") (eq api \"orpc\"))}}\nimport { useQuery } from \"@tanstack/react-query\";\n {{#if (eq api \"trpc\")}}\nimport { useTRPC } from \"@/utils/trpc\";\n {{/if}}\n {{#if (eq api \"orpc\")}}\nimport { orpc } from \"@/utils/orpc\";\n {{/if}}\n{{/if}}\n\nexport const Route = createFileRoute(\"/\")({\n component: HomeComponent,\n});\n\nconst TITLE_TEXT = \\`\n ██████╗ ███████╗████████╗████████╗███████╗██████╗\n ██╔══██╗██╔════╝╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗\n ██████╔╝█████╗ ██║ ██║ █████╗ ██████╔╝\n ██╔══██╗██╔══╝ ██║ ██║ ██╔══╝ ██╔══██╗\n ██████╔╝███████╗ ██║ ██║ ███████╗██║ ██║\n ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝\n\n ████████╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗\n ╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝\n ██║ ███████╗ ██║ ███████║██║ █████╔╝\n ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗\n ██║ ███████║ ██║ ██║ ██║╚██████╗██║ ██╗\n ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝\n \\`;\n\nfunction HomeComponent() {\n {{#if (eq backend \"convex\")}}\n const healthCheck = useQuery(convexQuery(api.healthCheck.get, {}));\n {{else if (eq api \"trpc\")}}\n const trpc = useTRPC();\n const healthCheck = useQuery(trpc.healthCheck.queryOptions());\n {{else if (eq api \"orpc\")}}\n const healthCheck = useQuery(orpc.healthCheck.queryOptions());\n {{/if}}\n\n return (\n <div className=\"container mx-auto max-w-3xl px-4 py-2\">\n <pre className=\"overflow-x-auto font-mono text-sm\">{TITLE_TEXT}</pre>\n <div className=\"grid gap-6\">\n <section className=\"rounded-lg border p-4\">\n <h2 className=\"mb-2 font-medium\">API Status</h2>\n {{#if (eq backend \"convex\")}}\n <div className=\"flex items-center gap-2\">\n <div\n className={\\`h-2 w-2 rounded-full \\${healthCheck.data === \"OK\" ? \"bg-green-500\" : healthCheck.isLoading ? \"bg-orange-400\" : \"bg-red-500\"}\\`}\n />\n <span className=\"text-muted-foreground text-sm\">\n {healthCheck.isLoading\n ? \"Checking...\"\n : healthCheck.data === \"OK\"\n ? \"Connected\"\n : \"Error\"}\n </span>\n </div>\n {{else}}\n {{#unless (eq api \"none\")}}\n <div className=\"flex items-center gap-2\">\n <div\n className={\\`h-2 w-2 rounded-full \\${healthCheck.data ? \"bg-green-500\" : \"bg-red-500\"}\\`}\n />\n <span className=\"text-muted-foreground text-sm\">\n {healthCheck.isLoading\n ? \"Checking...\"\n : healthCheck.data\n ? \"Connected\"\n : \"Disconnected\"}\n </span>\n </div>\n {{/unless}}\n {{/if}}\n </section>\n </div>\n </div>\n );\n}\n`],\n [\"frontend/react/tanstack-router/src/routes/__root.tsx.hbs\", `import Header from \"@/components/header\";\nimport { ThemeProvider } from \"@/components/theme-provider\";\nimport { Toaster } from \"@/components/ui/sonner\";\n{{#if (eq api \"orpc\")}}\nimport { link, orpc } from \"@/utils/orpc\";\nimport type { QueryClient } from \"@tanstack/react-query\";\nimport { ReactQueryDevtools } from \"@tanstack/react-query-devtools\";\nimport { useState } from \"react\";\nimport { createTanstackQueryUtils } from \"@orpc/tanstack-query\";\nimport type { AppRouterClient } from \"@{{projectName}}/api/routers/index\";\nimport { createORPCClient } from \"@orpc/client\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport type { trpc } from \"@/utils/trpc\";\nimport type { QueryClient } from \"@tanstack/react-query\";\nimport { ReactQueryDevtools } from \"@tanstack/react-query-devtools\";\n{{/if}}\nimport {\n HeadContent,\n Outlet,\n createRootRouteWithContext,\n} from \"@tanstack/react-router\";\nimport { TanStackRouterDevtools } from \"@tanstack/react-router-devtools\";\nimport \"../index.css\";\n\n{{#if (eq api \"orpc\")}}\nexport interface RouterAppContext {\n orpc: typeof orpc;\n queryClient: QueryClient;\n}\n{{else if (eq api \"trpc\")}}\nexport interface RouterAppContext {\n trpc: typeof trpc;\n queryClient: QueryClient;\n}\n{{else}}\nexport interface RouterAppContext {}\n{{/if}}\n\nexport const Route = createRootRouteWithContext<RouterAppContext>()({\n component: RootComponent,\n head: () => ({\n meta: [\n {\n title: \"{{projectName}}\",\n },\n {\n name: \"description\",\n content: \"{{projectName}} is a web application\",\n },\n ],\n links: [\n {\n rel: \"icon\",\n href: \"/favicon.ico\",\n },\n ],\n }),\n});\n\nfunction RootComponent() {\n {{#if (eq api \"orpc\")}}\n const [client] = useState<AppRouterClient>(() => createORPCClient(link));\n const [orpcUtils] = useState(() => createTanstackQueryUtils(client));\n {{/if}}\n\n return (\n <>\n <HeadContent />\n {{#if (eq api \"orpc\")}}\n <ThemeProvider\n attribute=\"class\"\n defaultTheme=\"dark\"\n disableTransitionOnChange\n storageKey=\"vite-ui-theme\"\n >\n <div className=\"grid grid-rows-[auto_1fr] h-svh\">\n <Header />\n <Outlet />\n </div>\n <Toaster richColors />\n </ThemeProvider>\n {{else}}\n <ThemeProvider\n attribute=\"class\"\n defaultTheme=\"dark\"\n disableTransitionOnChange\n storageKey=\"vite-ui-theme\"\n >\n <div className=\"grid grid-rows-[auto_1fr] h-svh\">\n <Header />\n <Outlet />\n </div>\n <Toaster richColors />\n </ThemeProvider>\n {{/if}}\n <TanStackRouterDevtools position=\"bottom-left\" />\n {{#if (or (eq api \"orpc\") (eq api \"trpc\"))}}\n <ReactQueryDevtools position=\"bottom\" buttonPosition=\"bottom-right\" />\n {{/if}}\n </>\n );\n}\n`],\n [\"frontend/react/tanstack-router/src/routes/index.tsx.hbs\", `import { createFileRoute } from \"@tanstack/react-router\";\n{{#if (eq api \"orpc\")}}\nimport { orpc } from \"@/utils/orpc\";\nimport { useQuery } from \"@tanstack/react-query\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { trpc } from \"@/utils/trpc\";\nimport { useQuery } from \"@tanstack/react-query\";\n{{/if}}\n{{#if (eq backend \"convex\")}}\nimport { useQuery } from \"convex/react\";\nimport { api } from \"@{{ projectName }}/backend/convex/_generated/api\";\n{{/if}}\n\nexport const Route = createFileRoute(\"/\")({\n component: HomeComponent,\n});\n\nconst TITLE_TEXT = \\`\n ██████╗ ███████╗████████╗████████╗███████╗██████╗\n ██╔══██╗██╔════╝╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗\n ██████╔╝█████╗ ██║ ██║ █████╗ ██████╔╝\n ██╔══██╗██╔══╝ ██║ ██║ ██╔══╝ ██╔══██╗\n ██████╔╝███████╗ ██║ ██║ ███████╗██║ ██║\n ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝\n\n ████████╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗\n ╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝\n ██║ ███████╗ ██║ ███████║██║ █████╔╝\n ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗\n ██║ ███████║ ██║ ██║ ██║╚██████╗██║ ██╗\n ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝\n \\`;\n\nfunction HomeComponent() {\n {{#if (eq api \"orpc\")}}\n const healthCheck = useQuery(orpc.healthCheck.queryOptions());\n {{/if}}\n {{#if (eq api \"trpc\")}}\n const healthCheck = useQuery(trpc.healthCheck.queryOptions());\n {{/if}}\n {{#if (eq backend \"convex\")}}\n const healthCheck = useQuery(api.healthCheck.get);\n {{/if}}\n\n return (\n <div className=\"container mx-auto max-w-3xl px-4 py-2\">\n <pre className=\"overflow-x-auto font-mono text-sm\">{TITLE_TEXT}</pre>\n <div className=\"grid gap-6\">\n <section className=\"rounded-lg border p-4\">\n <h2 className=\"mb-2 font-medium\">API Status</h2>\n {{#if (eq backend \"convex\")}}\n <div className=\"flex items-center gap-2\">\n <div\n className={\\`h-2 w-2 rounded-full \\${healthCheck === \"OK\" ? \"bg-green-500\" : healthCheck === undefined ? \"bg-orange-400\" : \"bg-red-500\"}\\`}\n />\n <span className=\"text-sm text-muted-foreground\">\n {healthCheck === undefined\n ? \"Checking...\"\n : healthCheck === \"OK\"\n ? \"Connected\"\n : \"Error\"}\n </span>\n </div>\n {{else}}\n {{#unless (eq api \"none\")}}\n <div className=\"flex items-center gap-2\">\n <div\n className={\\`h-2 w-2 rounded-full \\${healthCheck.data ? \"bg-green-500\" : \"bg-red-500\"}\\`}\n />\n <span className=\"text-sm text-muted-foreground\">\n {healthCheck.isLoading\n ? \"Checking...\"\n : healthCheck.data\n ? \"Connected\"\n : \"Disconnected\"}\n </span>\n </div>\n {{/unless}}\n {{/if}}\n </section>\n </div>\n </div>\n );\n}\n`],\n [\"frontend/react/tanstack-router/src/components/theme-provider.tsx.hbs\", `import * as React from \"react\";\nimport { ThemeProvider as NextThemesProvider } from \"next-themes\";\n\nexport function ThemeProvider({\n children,\n ...props\n}: React.ComponentProps<typeof NextThemesProvider>) {\n return <NextThemesProvider {...props}>{children}</NextThemesProvider>;\n}\n\nexport { useTheme } from \"next-themes\";\n`],\n [\"frontend/react/tanstack-router/src/components/mode-toggle.tsx.hbs\", `import { Moon, Sun } from \"lucide-react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { useTheme } from \"@/components/theme-provider\";\n\nexport function ModeToggle() {\n const { setTheme } = useTheme();\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button variant=\"outline\" size=\"icon\" />}>\n <Sun className=\"h-[1.2rem] w-[1.2rem] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90\" />\n <Moon className=\"absolute h-[1.2rem] w-[1.2rem] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0\" />\n <span className=\"sr-only\">Toggle theme</span>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => setTheme(\"light\")}>Light</DropdownMenuItem>\n <DropdownMenuItem onClick={() => setTheme(\"dark\")}>Dark</DropdownMenuItem>\n <DropdownMenuItem onClick={() => setTheme(\"system\")}>System</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n`],\n [\"auth/better-auth/native/unistyles/components/sign-up.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\n{{#if (eq api \"trpc\")}}\nimport { queryClient } from \"@/utils/trpc\";\n{{/if}}\n{{#if (eq api \"orpc\")}}\nimport { queryClient } from \"@/utils/orpc\";\n{{/if}}\nimport { useState } from \"react\";\nimport {\n ActivityIndicator,\n Text,\n TextInput,\n TouchableOpacity,\n View,\n} from \"react-native\";\nimport { StyleSheet } from \"react-native-unistyles\";\n\nexport function SignUp() {\n const [name, setName] = useState(\"\");\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const handleSignUp = async () => {\n setIsLoading(true);\n setError(null);\n\n await authClient.signUp.email(\n {\n name,\n email,\n password,\n },\n {\n onError: (error) => {\n setError(error.error?.message || \"Failed to sign up\");\n setIsLoading(false);\n },\n onSuccess: () => {\n setName(\"\");\n setEmail(\"\");\n setPassword(\"\");\n {{#if (eq api \"orpc\")}}\n queryClient.refetchQueries();\n {{/if}}\n {{#if (eq api \"trpc\")}}\n queryClient.refetchQueries();\n {{/if}}\n },\n onFinished: () => {\n setIsLoading(false);\n },\n },\n );\n };\n\n return (\n <View style={styles.container}>\n <Text style={styles.title}>Create Account</Text>\n\n {error && (\n <View style={styles.errorContainer}>\n <Text style={styles.errorText}>{error}</Text>\n </View>\n )}\n\n <TextInput\n style={styles.input}\n placeholder=\"Name\"\n value={name}\n onChangeText={setName}\n />\n\n <TextInput\n style={styles.input}\n placeholder=\"Email\"\n value={email}\n onChangeText={setEmail}\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n />\n\n <TextInput\n style={styles.inputLast}\n placeholder=\"Password\"\n value={password}\n onChangeText={setPassword}\n secureTextEntry\n />\n\n <TouchableOpacity\n onPress={handleSignUp}\n disabled={isLoading}\n style={styles.button}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color=\"#fff\" />\n ) : (\n <Text style={styles.buttonText}>Sign Up</Text>\n )}\n </TouchableOpacity>\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n container: {\n marginTop: 24,\n padding: 16,\n borderRadius: 8,\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n title: {\n fontSize: 18,\n fontWeight: \"600\",\n color: theme.colors.typography,\n marginBottom: 16,\n },\n errorContainer: {\n marginBottom: 16,\n padding: 12,\n borderRadius: 6,\n },\n errorText: {\n color: theme.colors.destructive,\n fontSize: 14,\n },\n input: {\n marginBottom: 12,\n padding: 16,\n borderRadius: 6,\n color: theme.colors.typography,\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n inputLast: {\n marginBottom: 16,\n padding: 16,\n borderRadius: 6,\n color: theme.colors.typography,\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n button: {\n backgroundColor: theme.colors.primary,\n padding: 16,\n borderRadius: 6,\n flexDirection: \"row\",\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n buttonText: {\n fontWeight: \"500\",\n },\n}));\n`],\n [\"auth/better-auth/native/unistyles/components/sign-in.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\n{{#if (eq api \"trpc\")}}\nimport { queryClient } from \"@/utils/trpc\";\n{{/if}}\n{{#if (eq api \"orpc\")}}\nimport { queryClient } from \"@/utils/orpc\";\n{{/if}}\nimport { useState } from \"react\";\nimport {\n ActivityIndicator,\n Text,\n TextInput,\n TouchableOpacity,\n View,\n} from \"react-native\";\nimport { StyleSheet } from \"react-native-unistyles\";\n\nexport function SignIn() {\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const handleLogin = async () => {\n setIsLoading(true);\n setError(null);\n\n await authClient.signIn.email(\n {\n email,\n password,\n },\n {\n onError: (error) => {\n setError(error.error?.message || \"Failed to sign in\");\n setIsLoading(false);\n },\n onSuccess: () => {\n setEmail(\"\");\n setPassword(\"\");\n {{#if (eq api \"orpc\")}}\n queryClient.refetchQueries();\n {{/if}}\n {{#if (eq api \"trpc\")}}\n queryClient.refetchQueries();\n {{/if}}\n },\n onFinished: () => {\n setIsLoading(false);\n },\n },\n );\n };\n\n return (\n <View style={styles.container}>\n <Text style={styles.title}>Sign In</Text>\n\n {error && (\n <View style={styles.errorContainer}>\n <Text style={styles.errorText}>{error}</Text>\n </View>\n )}\n\n <TextInput\n style={styles.input}\n placeholder=\"Email\"\n value={email}\n onChangeText={setEmail}\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n />\n\n <TextInput\n style={styles.input}\n placeholder=\"Password\"\n value={password}\n onChangeText={setPassword}\n secureTextEntry\n />\n\n <TouchableOpacity\n onPress={handleLogin}\n disabled={isLoading}\n style={styles.button}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color=\"#fff\" />\n ) : (\n <Text style={styles.buttonText}>Sign In</Text>\n )}\n </TouchableOpacity>\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n container: {\n marginTop: 24,\n padding: 16,\n borderRadius: 8,\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n title: {\n fontSize: 18,\n fontWeight: \"600\",\n color: theme.colors.typography,\n marginBottom: 16,\n },\n errorContainer: {\n marginBottom: 16,\n padding: 12,\n borderRadius: 6,\n },\n errorText: {\n color: theme.colors.destructive,\n fontSize: 14,\n },\n input: {\n marginBottom: 12,\n padding: 16,\n borderRadius: 6,\n color: theme.colors.typography,\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n button: {\n backgroundColor: theme.colors.primary,\n padding: 16,\n borderRadius: 6,\n flexDirection: \"row\",\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n buttonText: {\n fontWeight: \"500\",\n },\n}));\n`],\n [\"frontend/react/next/src/app/favicon.ico\", `[Binary file]`],\n [\"frontend/react/next/src/app/page.tsx.hbs\", `\"use client\"\n{{#if (eq backend \"convex\")}}\nimport { useQuery } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\n{{else if (or (eq api \"orpc\") (eq api \"trpc\"))}}\nimport { useQuery } from \"@tanstack/react-query\";\n {{#if (eq api \"orpc\")}}\nimport { orpc } from \"@/utils/orpc\";\n {{/if}}\n {{#if (eq api \"trpc\")}}\nimport { trpc } from \"@/utils/trpc\";\n {{/if}}\n{{/if}}\n\nconst TITLE_TEXT = \\`\n ██████╗ ███████╗████████╗████████╗███████╗██████╗\n ██╔══██╗██╔════╝╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗\n ██████╔╝█████╗ ██║ ██║ █████╗ ██████╔╝\n ██╔══██╗██╔══╝ ██║ ██║ ██╔══╝ ██╔══██╗\n ██████╔╝███████╗ ██║ ██║ ███████╗██║ ██║\n ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝\n\n ████████╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗\n ╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝\n ██║ ███████╗ ██║ ███████║██║ █████╔╝\n ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗\n ██║ ███████║ ██║ ██║ ██║╚██████╗██║ ██╗\n ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝\n \\`;\n\nexport default function Home() {\n {{#if (eq backend \"convex\")}}\n const healthCheck = useQuery(api.healthCheck.get);\n {{else if (eq api \"orpc\")}}\n const healthCheck = useQuery(orpc.healthCheck.queryOptions());\n {{else if (eq api \"trpc\")}}\n const healthCheck = useQuery(trpc.healthCheck.queryOptions());\n {{/if}}\n\n return (\n <div className=\"container mx-auto max-w-3xl px-4 py-2\">\n <pre className=\"overflow-x-auto font-mono text-sm\">{TITLE_TEXT}</pre>\n <div className=\"grid gap-6\">\n <section className=\"rounded-lg border p-4\">\n <h2 className=\"mb-2 font-medium\">API Status</h2>\n {{#if (eq backend \"convex\")}}\n <div className=\"flex items-center gap-2\">\n <div\n className={\\`h-2 w-2 rounded-full \\${healthCheck === \"OK\" ? \"bg-green-500\" : healthCheck === undefined ? \"bg-orange-400\" : \"bg-red-500\"}\\`}\n />\n <span className=\"text-sm text-muted-foreground\">\n {healthCheck === undefined\n ? \"Checking...\"\n : healthCheck === \"OK\"\n ? \"Connected\"\n : \"Error\"}\n </span>\n </div>\n {{else}}\n {{#unless (eq api \"none\")}}\n <div className=\"flex items-center gap-2\">\n <div\n className={\\`h-2 w-2 rounded-full \\${healthCheck.data ? \"bg-green-500\" : \"bg-red-500\"}\\`}\n />\n <span className=\"text-sm text-muted-foreground\">\n {healthCheck.isLoading\n ? \"Checking...\"\n : healthCheck.data\n ? \"Connected\"\n : \"Disconnected\"}\n </span>\n </div>\n {{/unless}}\n {{/if}}\n </section>\n </div>\n </div>\n );\n}\n`],\n [\"frontend/react/next/src/app/layout.tsx.hbs\", `import type { Metadata } from \"next\";\nimport { Geist, Geist_Mono } from \"next/font/google\";\nimport \"../index.css\";\n{{#if (eq auth \"clerk\")}}{{#if (eq backend \"convex\")}}import { ClerkProvider } from \"@clerk/nextjs\";\n{{/if}}{{/if}}{{#if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\nimport { getToken } from \"@/lib/auth-server\";\n{{/if}}\nimport Providers from \"@/components/providers\";\nimport Header from \"@/components/header\";\n\nconst geistSans = Geist({\n variable: \"--font-geist-sans\",\n subsets: [\"latin\"],\n});\n\nconst geistMono = Geist_Mono({\n variable: \"--font-geist-mono\",\n subsets: [\"latin\"],\n});\n\nexport const metadata: Metadata = {\n title: \"{{projectName}}\",\n description: \"{{projectName}}\",\n};\n\n{{#if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\nexport default async function RootLayout({\n children,\n}: Readonly<{\n children: React.ReactNode;\n}>) {\n const token = await getToken();\n return (\n <html lang=\"en\" suppressHydrationWarning>\n <body\n className={\\`\\${geistSans.variable} \\${geistMono.variable} antialiased\\`}\n >\n <Providers initialToken={token}>\n <div className=\"grid grid-rows-[auto_1fr] h-svh\">\n <Header />\n {children}\n </div>\n </Providers>\n </body>\n </html>\n );\n}\n{{else}}\nexport default function RootLayout({\n children,\n}: Readonly<{\n children: React.ReactNode;\n}>) {\n \treturn (\n\t\t<html lang=\"en\" suppressHydrationWarning>\n\t\t\t<body\n\t\t\t\tclassName={\\`\\${geistSans.variable} \\${geistMono.variable} antialiased\\`}\n\t\t\t>\n\t\t\t\t{{#if (and (eq auth \"clerk\") (eq backend \"convex\"))}}<ClerkProvider>\n\t\t\t\t\t<Providers>\n\t\t\t\t\t\t<div className=\"grid grid-rows-[auto_1fr] h-svh\">\n\t\t\t\t\t\t\t<Header />\n\t\t\t\t\t\t\t{children}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</Providers>\n\t\t\t\t</ClerkProvider>{{else}}<Providers>\n\t\t\t\t\t<div className=\"grid grid-rows-[auto_1fr] h-svh\">\n\t\t\t\t\t\t<Header />\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</div>\n\t\t\t\t</Providers>{{/if}}\n\t\t\t</body>\n\t\t</html>\n\t);\n}\n{{/if}}\n`],\n [\"frontend/angular/src/app/components/header.component.ts.hbs\", `import { Component } from '@angular/core';\n\n@Component({\n selector: 'app-header',\n standalone: true,\n template: \\`\n {{#if (eq cssFramework \"tailwind\")}}\n <header class=\"flex items-center justify-between border-b border-gray-200 dark:border-gray-800 px-4 py-3\">\n <div class=\"flex items-center gap-2\">\n <span class=\"font-semibold\">Better T Stack</span>\n </div>\n <nav class=\"flex items-center gap-4\">\n <a href=\"https://github.com/better-t-stack/create-better-t-stack\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 transition-colors\">\n GitHub\n </a>\n <a href=\"https://better-t-stack.dev\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 transition-colors\">\n Docs\n </a>\n </nav>\n </header>\n {{else}}\n <header [style.display]=\"'flex'\"\n [style.alignItems]=\"'center'\"\n [style.justifyContent]=\"'space-between'\"\n [style.borderBottom]=\"'1px solid var(--border-color)'\"\n [style.padding]=\"'0.75rem 1rem'\">\n <div [style.display]=\"'flex'\" [style.alignItems]=\"'center'\" [style.gap]=\"'0.5rem'\">\n <span [style.fontWeight]=\"600\">Better T Stack</span>\n </div>\n <nav [style.display]=\"'flex'\" [style.alignItems]=\"'center'\" [style.gap]=\"'1rem'\">\n <a href=\"https://github.com/better-t-stack/create-better-t-stack\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n [style.fontSize]=\"'0.875rem'\"\n [style.color]=\"'var(--muted-color)'\">\n GitHub\n </a>\n <a href=\"https://better-t-stack.dev\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n [style.fontSize]=\"'0.875rem'\"\n [style.color]=\"'var(--muted-color)'\">\n Docs\n </a>\n </nav>\n </header>\n {{/if}}\n \\`,\n})\nexport class HeaderComponent {}\n`],\n [\"frontend/react/next/src/components/theme-provider.tsx.hbs\", `\"use client\"\n\nimport * as React from \"react\"\nimport { ThemeProvider as NextThemesProvider } from \"next-themes\"\n\nexport function ThemeProvider({\n children,\n ...props\n}: React.ComponentProps<typeof NextThemesProvider>) {\n return <NextThemesProvider {...props}>{children}</NextThemesProvider>\n}\n`],\n [\"frontend/react/next/src/components/mode-toggle.tsx.hbs\", `\"use client\"\n\nimport * as React from \"react\"\nimport { Moon, Sun } from \"lucide-react\"\nimport { useTheme } from \"next-themes\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function ModeToggle() {\n const { setTheme } = useTheme()\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button variant=\"outline\" size=\"icon\" />}>\n <Sun className=\"h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0\" />\n <Moon className=\"absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100\" />\n <span className=\"sr-only\">Toggle theme</span>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => setTheme(\"light\")}>\n Light\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => setTheme(\"dark\")}>\n Dark\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => setTheme(\"system\")}>\n System\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n`],\n [\"frontend/react/next/src/components/providers.tsx.hbs\", `\"use client\";\n\n{{#if (eq backend \"convex\")}}\n{{#if (eq auth \"clerk\")}}\nimport { useAuth } from \"@clerk/nextjs\";\nimport { ConvexReactClient } from \"convex/react\";\nimport { ConvexProviderWithClerk } from \"convex/react-clerk\";\nimport { env } from \"@{{projectName}}/env/web\";\n{{else if (eq auth \"better-auth\")}}\nimport { ConvexReactClient } from \"convex/react\";\nimport { ConvexBetterAuthProvider } from \"@convex-dev/better-auth/react\";\nimport { authClient } from \"@/lib/auth-client\";\nimport { env } from \"@{{projectName}}/env/web\";\n{{else}}\nimport { ConvexProvider, ConvexReactClient } from \"convex/react\";\nimport { env } from \"@{{projectName}}/env/web\";\n{{/if}}\n{{else}}\n{{#unless (eq api \"none\")}}\nimport { QueryClientProvider } from \"@tanstack/react-query\";\nimport { ReactQueryDevtools } from \"@tanstack/react-query-devtools\";\n{{#if (eq api \"orpc\")}}\nimport { queryClient } from \"@/utils/orpc\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { queryClient } from \"@/utils/trpc\";\n{{/if}}\n{{/unless}}\n{{/if}}\nimport { ThemeProvider } from \"./theme-provider\";\nimport { Toaster } from \"./ui/sonner\";\n\n{{#if (eq backend \"convex\")}}\nconst convex = new ConvexReactClient(env.NEXT_PUBLIC_CONVEX_URL);\n{{/if}}\n\nexport default function Providers({\n children,\n{{#if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\n initialToken,\n{{/if}}\n}: {\n children: React.ReactNode;\n{{#if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\n initialToken?: string | null;\n{{/if}}\n}) {\n return (\n <ThemeProvider\n attribute=\"class\"\n defaultTheme=\"system\"\n enableSystem\n disableTransitionOnChange\n >\n {{#if (eq backend \"convex\")}}\n {{#if (eq auth \"clerk\")}}\n <ConvexProviderWithClerk client={convex} useAuth={useAuth}>\n {children}\n </ConvexProviderWithClerk>\n {{else if (eq auth \"better-auth\")}}\n <ConvexBetterAuthProvider\n client={convex}\n authClient={authClient}\n initialToken={initialToken}\n >\n {children}\n </ConvexBetterAuthProvider>\n {{else}}\n <ConvexProvider client={convex}>{children}</ConvexProvider>\n {{/if}}\n {{else}}\n {{#unless (eq api \"none\")}}\n <QueryClientProvider client={queryClient}>\n {{#if (eq api \"orpc\")}}\n {children}\n {{/if}}\n {{#if (eq api \"trpc\")}}\n {children}\n {{/if}}\n <ReactQueryDevtools />\n </QueryClientProvider>\n {{else}}\n {children}\n {{/unless}}\n {{/if}}\n <Toaster richColors />\n </ThemeProvider>\n );\n}\n`],\n [\"frontend/react/react-router/src/routes/_index.tsx.hbs\", `import type { Route } from \"./+types/_index\";\n{{#if (eq backend \"convex\")}}\nimport { useQuery } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\n{{else if (or (eq api \"orpc\") (eq api \"trpc\"))}}\nimport { useQuery } from \"@tanstack/react-query\";\n {{#if (eq api \"orpc\")}}\n import { orpc } from \"@/utils/orpc\";\n {{/if}}\n {{#if (eq api \"trpc\")}}\n import { trpc } from \"@/utils/trpc\";\n {{/if}}\n{{/if}}\n\nconst TITLE_TEXT = \\`\n ██████╗ ███████╗████████╗████████╗███████╗██████╗\n ██╔══██╗██╔════╝╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗\n ██████╔╝█████╗ ██║ ██║ █████╗ ██████╔╝\n ██╔══██╗██╔══╝ ██║ ██║ ██╔══╝ ██╔══██╗\n ██████╔╝███████╗ ██║ ██║ ███████╗██║ ██║\n ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝\n\n ████████╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗\n ╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝\n ██║ ███████╗ ██║ ███████║██║ █████╔╝\n ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗\n ██║ ███████║ ██║ ██║ ██║╚██████╗██║ ██╗\n ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝\n \\`;\n\nexport function meta({}: Route.MetaArgs) {\n return [{ title: \"{{projectName}}\" }, { name: \"description\", content: \"{{projectName}} is a web application\" }];\n}\n\nexport default function Home() {\n {{#if (eq backend \"convex\")}}\n const healthCheck = useQuery(api.healthCheck.get);\n {{else if (eq api \"orpc\")}}\n const healthCheck = useQuery(orpc.healthCheck.queryOptions());\n {{else if (eq api \"trpc\")}}\n const healthCheck = useQuery(trpc.healthCheck.queryOptions());\n {{/if}}\n\n return (\n <div className=\"container mx-auto max-w-3xl px-4 py-2\">\n <pre className=\"overflow-x-auto font-mono text-sm\">{TITLE_TEXT}</pre>\n <div className=\"grid gap-6\">\n <section className=\"rounded-lg border p-4\">\n <h2 className=\"mb-2 font-medium\">API Status</h2>\n {{#if (eq backend \"convex\")}}\n <div className=\"flex items-center gap-2\">\n <div\n className={\\`h-2 w-2 rounded-full \\${healthCheck === \"OK\" ? \"bg-green-500\" : healthCheck === undefined ? \"bg-orange-400\" : \"bg-red-500\"}\\`}\n />\n <span className=\"text-sm text-muted-foreground\">\n {healthCheck === undefined\n ? \"Checking...\"\n : healthCheck === \"OK\"\n ? \"Connected\"\n : \"Error\"}\n </span>\n </div>\n {{else}}\n {{#unless (eq api \"none\")}}\n <div className=\"flex items-center gap-2\">\n <div\n className={\\`h-2 w-2 rounded-full \\${\n healthCheck.data ? \"bg-green-500\" : \"bg-red-500\"\n }\\`}\n />\n <span className=\"text-sm text-muted-foreground\">\n {healthCheck.isLoading\n ? \"Checking...\"\n : healthCheck.data\n ? \"Connected\"\n : \"Disconnected\"}\n </span>\n </div>\n {{/unless}}\n {{/if}}\n </section>\n </div>\n </div>\n );\n}\n`],\n [\"frontend/react/react-router/src/components/theme-provider.tsx.hbs\", `import * as React from \"react\";\nimport { ThemeProvider as NextThemesProvider } from \"next-themes\";\n\nexport function ThemeProvider({\n children,\n ...props\n}: React.ComponentProps<typeof NextThemesProvider>) {\n return <NextThemesProvider {...props}>{children}</NextThemesProvider>;\n}\n\nexport { useTheme } from \"next-themes\";\n`],\n [\"frontend/react/react-router/src/components/mode-toggle.tsx.hbs\", `import { Moon, Sun } from \"lucide-react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { useTheme } from \"@/components/theme-provider\";\n\nexport function ModeToggle() {\n const { setTheme } = useTheme();\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button variant=\"outline\" size=\"icon\" />}>\n <Sun className=\"h-[1.2rem] w-[1.2rem] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90\" />\n <Moon className=\"absolute h-[1.2rem] w-[1.2rem] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0\" />\n <span className=\"sr-only\">Toggle theme</span>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => setTheme(\"light\")}>Light</DropdownMenuItem>\n <DropdownMenuItem onClick={() => setTheme(\"dark\")}>Dark</DropdownMenuItem>\n <DropdownMenuItem onClick={() => setTheme(\"system\")}>System</DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n`],\n [\"frontend/redwood/api/src/functions/graphql.ts\", `import { createGraphQLHandler } from \"@redwoodjs/graphql-server\";\nimport directives from \"src/directives/**/*.{js,ts}\";\nimport sdls from \"src/graphql/**/*.sdl.{js,ts}\";\nimport { db } from \"src/lib/db\";\nimport { logger } from \"src/lib/logger\";\nimport services from \"src/services/**/*.{js,ts}\";\n\nexport const handler = createGraphQLHandler({\n loggerConfig: { logger, options: {} },\n directives,\n sdls,\n services,\n onException: () => {\n // Disconnect from your database with an unhandled exception.\n db.$disconnect();\n },\n});\n`],\n [\"frontend/redwood/api/src/lib/auth.ts\", `/**\n * Once you have your authentication type defined (e.g. Cookie, OAuth, etc.),\n * you can add auth to your API functions by importing this file\n * and calling \\`isAuthenticated()\\` and \\`hasRole()\\` in your handler functions.\n *\n * @see https://redwoodjs.com/docs/authentication\n */\nimport type { Decoded } from \"@redwoodjs/api\";\n\n/**\n * Represents the user attributes returned by the decoding the\n * Authentication provider's JWT token together with any additional\n * attributes that you wish to add to the user's context.\n */\nexport interface CurrentUser {\n id: string;\n email?: string;\n roles?: string[];\n}\n\n/**\n * The session object sent in as the first argument to getCurrentUser() will\n * have a single key \\`id\\` containing the unique ID of the logged in user\n * (whatever field you set as \\`authFields.id\\` in your auth function config).\n */\nexport const getCurrentUser = async (\n decoded: Decoded,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n { _token, _type }: { _token: string; _type: string },\n): Promise<CurrentUser | null> => {\n if (!decoded) {\n return null;\n }\n\n // Add your custom user lookup logic here\n return {\n id: decoded.sub || decoded.id || \"user\",\n email: decoded.email,\n roles: decoded.roles || [],\n };\n};\n\n/**\n * The user is authenticated if there is a currentUser in the context\n */\nexport const isAuthenticated = (): boolean => {\n return !!context.currentUser;\n};\n\n/**\n * When checking role membership, roles can be a single value, a list, or none.\n * You can use Prisma enum types if you have defined them.\n */\nexport const hasRole = (roles: string | string[]): boolean => {\n if (!isAuthenticated()) {\n return false;\n }\n\n const currentUserRoles = context.currentUser?.roles;\n\n if (typeof roles === \"string\") {\n if (typeof currentUserRoles === \"string\") {\n return currentUserRoles === roles;\n } else if (Array.isArray(currentUserRoles)) {\n return currentUserRoles?.some((allowedRole) => roles === allowedRole);\n }\n }\n\n if (Array.isArray(roles)) {\n if (Array.isArray(currentUserRoles)) {\n return currentUserRoles?.some((allowedRole) => roles.includes(allowedRole));\n } else if (typeof currentUserRoles === \"string\") {\n return roles.some((allowedRole) => currentUserRoles === allowedRole);\n }\n }\n\n return false;\n};\n\n/**\n * Use requireAuth in your services to check that a user is logged in\n *\n * @example\n *\n * export const createPost = ({ input }: { input: CreatePostInput }) => {\n * requireAuth({ roles: ['admin'] })\n *\n * return db.post.create({ data: input })\n * }\n *\n */\nexport const requireAuth = ({ roles }: { roles?: string | string[] } = {}) => {\n if (!isAuthenticated()) {\n throw new Error(\"You must be logged in to access this\");\n }\n\n if (roles && !hasRole(roles)) {\n throw new Error(\"You do not have permission to access this\");\n }\n};\n`],\n [\"frontend/redwood/api/src/lib/db.ts\", `// See https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/constructor\n// for options.\n\nimport { PrismaClient } from \"@prisma/client\";\nimport { emitLogLevels, handlePrismaLogging } from \"@redwoodjs/api/logger\";\n\nimport { logger } from \"./logger\";\n\n/*\n * Instance of the Prisma Client\n */\nexport const db = new PrismaClient({\n log: emitLogLevels([\"info\", \"warn\", \"error\"]),\n});\n\nhandlePrismaLogging({\n db,\n logger,\n logLevels: [\"info\", \"warn\", \"error\"],\n});\n`],\n [\"frontend/redwood/api/src/lib/logger.ts\", `import { createLogger } from \"@redwoodjs/api/logger\";\n\n/**\n * Creates a logger with RedwoodLoggerOptions\n *\n * These extend and adhere to options defined in https://github.com/pinojs/pino/blob/master/docs/api.md\n *\n * @param RedwoodLoggerOptions\n *\n * @returns Logger\n */\nexport const logger = createLogger({});\n`],\n [\"frontend/redwood/api/src/graphql/posts.sdl.ts\", `export const schema = gql\\`\n type Post {\n id: Int!\n title: String!\n body: String!\n createdAt: DateTime!\n }\n\n type Query {\n posts: [Post!]! @skipAuth\n post(id: Int!): Post @skipAuth\n }\n\n input CreatePostInput {\n title: String!\n body: String!\n }\n\n input UpdatePostInput {\n title: String\n body: String\n }\n\n type Mutation {\n createPost(input: CreatePostInput!): Post! @requireAuth\n updatePost(id: Int!, input: UpdatePostInput!): Post! @requireAuth\n deletePost(id: Int!): Post! @requireAuth\n }\n\\`;\n`],\n [\"frontend/nuxt/app/assets/css/main.css\", `@import \"tailwindcss\";\n@import \"@nuxt/ui\";\n`],\n [\"frontend/astro/integrations/vue/components/Counter.vue.hbs\", `<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nconst count = ref(0);\n</script>\n\n<template>\n\t<div class=\"flex items-center gap-4\">\n\t\t<button\n\t\t\t@click=\"count--\"\n\t\t\tclass=\"rounded-md bg-secondary px-4 py-2 text-secondary-foreground transition-colors hover:bg-secondary/80\"\n\t\t>\n\t\t\t-\n\t\t</button>\n\t\t<span class=\"min-w-[3rem] text-center text-2xl font-bold\">{{ count }}</span>\n\t\t<button\n\t\t\t@click=\"count++\"\n\t\t\tclass=\"rounded-md bg-primary px-4 py-2 text-primary-foreground transition-colors hover:bg-primary/80\"\n\t\t>\n\t\t\t+\n\t\t</button>\n\t</div>\n</template>\n`],\n [\"frontend/native/unistyles/app/(drawer)/_layout.tsx.hbs\", `import { Ionicons, MaterialIcons } from \"@expo/vector-icons\";\nimport { Link } from \"expo-router\";\nimport { Drawer } from \"expo-router/drawer\";\nimport { useUnistyles } from \"react-native-unistyles\";\n\nimport { HeaderButton } from \"../../components/header-button\";\n\nconst DrawerLayout = () => {\n const { theme } = useUnistyles();\n\n return (\n <Drawer\n screenOptions=\\\\{{\n headerStyle: {\n backgroundColor: theme.colors.background,\n },\n headerTitleStyle: {\n color: theme.colors.foreground,\n },\n headerTintColor: theme.colors.foreground,\n drawerStyle: {\n backgroundColor: theme.colors.background,\n },\n drawerLabelStyle: {\n color: theme.colors.foreground,\n },\n drawerInactiveTintColor: theme.colors.mutedForeground,\n }}\n >\n <Drawer.Screen\n name=\"index\"\n options=\\\\{{\n headerTitle: \"Home\",\n drawerLabel: \"Home\",\n drawerIcon: ({ size, color }) => (\n <Ionicons name=\"home-outline\" size={size} color={color} />\n ),\n }}\n />\n <Drawer.Screen\n name=\"(tabs)\"\n options=\\\\{{\n headerTitle: \"Tabs\",\n drawerLabel: \"Tabs\",\n drawerIcon: ({ size, color }) => (\n <MaterialIcons name=\"border-bottom\" size={size} color={color} />\n ),\n headerRight: () => (\n <Link href=\"/modal\" asChild>\n <HeaderButton />\n </Link>\n ),\n }}\n />\n {{#if (includes examples \"todo\")}}\n <Drawer.Screen\n name=\"todos\"\n options=\\\\{{\n headerTitle: \"Todos\",\n drawerLabel: \"Todos\",\n drawerIcon: ({ size, color }) => (\n <Ionicons name=\"checkbox-outline\" size={size} color={color} />\n ),\n }}\n />\n {{/if}}\n {{#if (includes examples \"ai\")}}\n <Drawer.Screen\n name=\"ai\"\n options=\\\\{{\n headerTitle: \"AI\",\n drawerLabel: \"AI\",\n drawerIcon: ({ size, color }) => (\n <Ionicons\n name=\"chatbubble-ellipses-outline\"\n size={size}\n color={color}\n />\n ),\n }}\n />\n {{/if}}\n </Drawer>\n );\n};\n\nexport default DrawerLayout;\n`],\n [\"frontend/native/unistyles/app/(drawer)/index.tsx.hbs\", `import { ScrollView, Text, View, TouchableOpacity } from \"react-native\";\nimport { StyleSheet } from \"react-native-unistyles\";\nimport { Container } from \"@/components/container\";\n\n{{#if (eq api \"orpc\")}}\nimport { useQuery } from \"@tanstack/react-query\";\nimport { orpc } from \"@/utils/orpc\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { useQuery } from \"@tanstack/react-query\";\nimport { trpc } from \"@/utils/trpc\";\n{{/if}}\n{{#if (and (eq backend \"convex\") (eq auth \"clerk\"))}}\nimport { Link } from \"expo-router\";\nimport { Authenticated, AuthLoading, Unauthenticated, useQuery } from \"convex/react\";\nimport { api } from \"@{{ projectName }}/backend/convex/_generated/api\";\nimport { useUser } from \"@clerk/clerk-expo\";\nimport { SignOutButton } from \"@/components/sign-out-button\";\n{{else if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\nimport { useConvexAuth, useQuery } from \"convex/react\";\nimport { api } from \"@{{ projectName }}/backend/convex/_generated/api\";\nimport { authClient } from \"@/lib/auth-client\";\nimport { SignIn } from \"@/components/sign-in\";\nimport { SignUp } from \"@/components/sign-up\";\n{{else if (eq backend \"convex\")}}\nimport { useQuery } from \"convex/react\";\nimport { api } from \"@{{ projectName }}/backend/convex/_generated/api\";\n{{/if}}\n\nexport default function Home() {\n {{#if (eq api \"orpc\")}}\n const healthCheck = useQuery(orpc.healthCheck.queryOptions());\n {{/if}}\n {{#if (eq api \"trpc\")}}\n const healthCheck = useQuery(trpc.healthCheck.queryOptions());\n {{/if}}\n {{#if (and (eq backend \"convex\") (eq auth \"clerk\"))}}\n const { user } = useUser();\n const healthCheck = useQuery(api.healthCheck.get);\n const privateData = useQuery(api.privateData.get);\n {{else if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\n const healthCheck = useQuery(api.healthCheck.get);\n const { isAuthenticated } = useConvexAuth();\n const user = useQuery(api.auth.getCurrentUser, isAuthenticated ? {} : \"skip\");\n {{else if (eq backend \"convex\")}}\n const healthCheck = useQuery(api.healthCheck.get);\n {{/if}}\n\n return (\n <Container>\n <ScrollView\n contentContainerStyle={styles.container}\n showsVerticalScrollIndicator={false}\n >\n <Text style={styles.heroTitle}>\n BETTER T STACK\n </Text>\n\n {{#unless (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\n <View style={styles.statusCard}>\n <View style={styles.statusHeader}>\n <Text style={styles.statusTitle}>System Status</Text>\n <View style={styles.statusBadge}>\n <Text style={styles.statusBadgeText}>LIVE</Text>\n </View>\n </View>\n {{#if (eq backend \"convex\")}}\n {{#unless (eq auth \"better-auth\")}}\n <View style={styles.statusRow}>\n <View\n style={[\n styles.statusDot,\n healthCheck === \"OK\"\n ? styles.statusDotSuccess\n : styles.statusDotWarning,\n ]}\n />\n <View style={styles.statusContent}>\n <Text style={styles.statusLabel}>Convex</Text>\n <Text style={styles.statusDescription}>\n {healthCheck === undefined\n ? \"Checking connection...\"\n : healthCheck === \"OK\"\n ? \"Connected to API\"\n : \"API Disconnected\"}\n </Text>\n </View>\n </View>\n {{/unless}}\n {{else}}\n {{#unless (eq api \"none\")}}\n <View style={styles.statusRow}>\n <View\n style={[\n styles.statusDot,\n healthCheck.data\n ? styles.statusDotSuccess\n : styles.statusDotWarning,\n ]}\n />\n <View style={styles.statusContent}>\n <Text style={styles.statusLabel}>\n {{#if (eq api \"orpc\")}}ORPC{{/if}}\n {{#if (eq api \"trpc\")}}TRPC{{/if}}\n </Text>\n <Text style={styles.statusDescription}>\n {healthCheck.isLoading\n ? \"Checking connection...\"\n : healthCheck.data\n ? \"Connected to API\"\n : \"API Disconnected\"}\n </Text>\n </View>\n </View>\n {{/unless}}\n {{/if}}\n </View>\n {{/unless}}\n\n {{#if (and (eq backend \"convex\") (eq auth \"clerk\"))}}\n <Authenticated>\n <Text>\n Hello {user?.emailAddresses[0].emailAddress}\n </Text>\n <Text>\n Private Data: {privateData?.message}\n </Text>\n <SignOutButton />\n </Authenticated>\n <Unauthenticated>\n <Link href=\"/(auth)/sign-in\">\n <Text>Sign in</Text>\n </Link>\n <Link href=\"/(auth)/sign-up\">\n <Text>Sign up</Text>\n </Link>\n </Unauthenticated>\n <AuthLoading>\n <Text>Loading...</Text>\n </AuthLoading>\n {{/if}}\n\n {{#if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\n {user ? (\n <View style={styles.userCard}>\n <View style={styles.userHeader}>\n <Text style={styles.userWelcome}>\n Welcome,{\" \"}\n <Text style={styles.userName}>{user.name}</Text>\n </Text>\n </View>\n <Text style={styles.userEmail}>{user.email}</Text>\n <TouchableOpacity\n style={styles.signOutButton}\n onPress={() => {\n authClient.signOut();\n }}\n >\n <Text style={styles.signOutText}>Sign Out</Text>\n </TouchableOpacity>\n </View>\n ) : null}\n <View style={styles.apiStatusCard}>\n <Text style={styles.apiStatusTitle}>API Status</Text>\n <View style={styles.apiStatusRow}>\n <View\n style={[\n styles.statusDot,\n healthCheck === \"OK\"\n ? styles.statusDotSuccess\n : styles.statusDotWarning,\n ]}\n />\n <Text style={styles.apiStatusText}>\n {healthCheck === undefined\n ? \"Checking...\"\n : healthCheck === \"OK\"\n ? \"Connected to API\"\n : \"API Disconnected\"}\n </Text>\n </View>\n </View>\n {!user && (\n <>\n <SignIn />\n <SignUp />\n </>\n )}\n {{/if}}\n </ScrollView>\n </Container>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n container: {\n paddingHorizontal: theme.spacing.md,\n },\n heroSection: {\n paddingVertical: theme.spacing.xl,\n },\n heroTitle: {\n fontSize: theme.fontSize[\"4xl\"],\n fontWeight: \"bold\",\n color: theme.colors.foreground,\n marginBottom: theme.spacing.sm,\n },\n heroSubtitle: {\n fontSize: theme.fontSize.lg,\n color: theme.colors.mutedForeground,\n lineHeight: 28,\n },\n statusCard: {\n backgroundColor: theme.colors.card,\n borderWidth: 1,\n borderColor: theme.colors.border,\n borderRadius: theme.borderRadius.xl,\n padding: theme.spacing.lg,\n marginBottom: theme.spacing.lg,\n shadowColor: \"#000\",\n shadowOffset: { width: 0, height: 1 },\n shadowOpacity: 0.05,\n shadowRadius: 3,\n elevation: 2,\n },\n statusHeader: {\n flexDirection: \"row\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n marginBottom: theme.spacing.md,\n },\n statusTitle: {\n fontSize: theme.fontSize.lg,\n fontWeight: \"600\",\n color: theme.colors.cardForeground,\n },\n statusBadge: {\n backgroundColor: theme.colors.secondary,\n paddingHorizontal: theme.spacing.sm + 4,\n paddingVertical: theme.spacing.xs,\n borderRadius: 9999,\n },\n statusBadgeText: {\n fontSize: theme.fontSize.xs,\n fontWeight: \"500\",\n color: theme.colors.secondaryForeground,\n },\n statusRow: {\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: theme.spacing.sm + 4,\n },\n statusDot: {\n height: 12,\n width: 12,\n borderRadius: 6,\n },\n statusDotSuccess: {\n backgroundColor: theme.colors.success,\n },\n statusDotWarning: {\n backgroundColor: \"#F59E0B\",\n },\n statusContent: {\n flex: 1,\n },\n statusLabel: {\n fontSize: theme.fontSize.sm,\n fontWeight: \"500\",\n color: theme.colors.cardForeground,\n },\n statusDescription: {\n fontSize: theme.fontSize.xs,\n color: theme.colors.mutedForeground,\n },\n userCard: {\n backgroundColor: theme.colors.card,\n borderWidth: 1,\n borderColor: theme.colors.border,\n borderRadius: theme.borderRadius.lg,\n padding: theme.spacing.md,\n marginBottom: theme.spacing.md,\n },\n userHeader: {\n flexDirection: \"row\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: theme.spacing.xs,\n },\n userWelcome: {\n fontSize: theme.fontSize.base,\n color: theme.colors.foreground,\n },\n userName: {\n fontWeight: \"500\",\n },\n userEmail: {\n fontSize: theme.fontSize.sm,\n color: theme.colors.mutedForeground,\n marginBottom: theme.spacing.md,\n },\n signOutButton: {\n backgroundColor: theme.colors.destructive,\n paddingVertical: theme.spacing.sm,\n paddingHorizontal: theme.spacing.md,\n borderRadius: theme.borderRadius.md,\n alignSelf: \"flex-start\",\n },\n signOutText: {\n color: theme.colors.destructiveForeground,\n fontWeight: \"500\",\n },\n apiStatusCard: {\n marginBottom: theme.spacing.md,\n borderRadius: theme.borderRadius.lg,\n borderWidth: 1,\n borderColor: theme.colors.border,\n padding: theme.spacing.md,\n },\n apiStatusTitle: {\n marginBottom: theme.spacing.sm,\n fontWeight: \"500\",\n color: theme.colors.foreground,\n },\n apiStatusRow: {\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: theme.spacing.xs,\n },\n apiStatusText: {\n color: theme.colors.mutedForeground,\n },\n}));`],\n [\"frontend/astro/integrations/svelte/components/Counter.svelte.hbs\", `<script lang=\"ts\">\n\tlet count = $state(0);\n</script>\n\n<div class=\"flex items-center gap-4\">\n\t<button\n\t\tonclick={() => count--}\n\t\tclass=\"rounded-md bg-secondary px-4 py-2 text-secondary-foreground transition-colors hover:bg-secondary/80\"\n\t>\n\t\t-\n\t</button>\n\t<span class=\"min-w-[3rem] text-center text-2xl font-bold\">{count}</span>\n\t<button\n\t\tonclick={() => count++}\n\t\tclass=\"rounded-md bg-primary px-4 py-2 text-primary-foreground transition-colors hover:bg-primary/80\"\n\t>\n\t\t+\n\t</button>\n</div>\n`],\n [\"frontend/astro/integrations/solid/components/Counter.tsx.hbs\", `import { createSignal } from 'solid-js';\n\nexport default function Counter() {\n\tconst [count, setCount] = createSignal(0);\n\n\treturn (\n\t\t<div class=\"flex items-center gap-4\">\n\t\t\t<button\n\t\t\t\tonClick={() => setCount(count() - 1)}\n\t\t\t\tclass=\"rounded-md bg-secondary px-4 py-2 text-secondary-foreground transition-colors hover:bg-secondary/80\"\n\t\t\t>\n\t\t\t\t-\n\t\t\t</button>\n\t\t\t<span class=\"min-w-[3rem] text-center text-2xl font-bold\">{count()}</span>\n\t\t\t<button\n\t\t\t\tonClick={() => setCount(count() + 1)}\n\t\t\t\tclass=\"rounded-md bg-primary px-4 py-2 text-primary-foreground transition-colors hover:bg-primary/80\"\n\t\t\t>\n\t\t\t\t+\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n`],\n [\"frontend/astro/integrations/react/components/ModeToggle.tsx.hbs\", `import { useEffect, useState } from 'react';\n\nexport default function ModeToggle() {\n\tconst [isDark, setIsDark] = useState(true);\n\n\tuseEffect(() => {\n\t\tsetIsDark(document.documentElement.classList.contains('dark'));\n\t}, []);\n\n\tconst toggleTheme = () => {\n\t\tdocument.documentElement.classList.toggle('dark');\n\t\tsetIsDark(!isDark);\n\t};\n\n\treturn (\n\t\t<button\n\t\t\tonClick={toggleTheme}\n\t\t\tclassName=\"rounded-md p-2 hover:bg-accent\"\n\t\t\taria-label=\"Toggle theme\"\n\t\t>\n\t\t\t{isDark ? (\n\t\t\t\t<svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n\t\t\t\t\t<path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z\" />\n\t\t\t\t</svg>\n\t\t\t) : (\n\t\t\t\t<svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n\t\t\t\t\t<path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z\" />\n\t\t\t\t</svg>\n\t\t\t)}\n\t\t</button>\n\t);\n}\n`],\n [\"frontend/astro/integrations/react/components/Counter.tsx.hbs\", `import { useState } from 'react';\n\nexport default function Counter() {\n\tconst [count, setCount] = useState(0);\n\n\treturn (\n\t\t<div className=\"flex items-center gap-4\">\n\t\t\t<button\n\t\t\t\tonClick={() => setCount(count - 1)}\n\t\t\t\tclassName=\"rounded-md bg-secondary px-4 py-2 text-secondary-foreground transition-colors hover:bg-secondary/80\"\n\t\t\t>\n\t\t\t\t-\n\t\t\t</button>\n\t\t\t<span className=\"min-w-[3rem] text-center text-2xl font-bold\">{count}</span>\n\t\t\t<button\n\t\t\t\tonClick={() => setCount(count + 1)}\n\t\t\t\tclassName=\"rounded-md bg-primary px-4 py-2 text-primary-foreground transition-colors hover:bg-primary/80\"\n\t\t\t>\n\t\t\t\t+\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n`],\n [\"frontend/native/bare/app/(drawer)/_layout.tsx.hbs\", `import { Ionicons, MaterialIcons } from \"@expo/vector-icons\";\nimport { Link } from \"expo-router\";\nimport { Drawer } from \"expo-router/drawer\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\n\nimport { HeaderButton } from \"@/components/header-button\";\n\nconst DrawerLayout = () => {\n const { colorScheme } = useColorScheme();\n const theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\n\n return (\n <Drawer\n screenOptions=\\\\{{\n headerStyle: {\n backgroundColor: theme.background,\n },\n headerTitleStyle: {\n color: theme.text,\n },\n headerTintColor: theme.text,\n drawerStyle: {\n backgroundColor: theme.background,\n },\n drawerLabelStyle: {\n color: theme.text,\n },\n drawerInactiveTintColor: theme.text,\n }}\n >\n <Drawer.Screen\n name=\"index\"\n options=\\\\{{\n headerTitle: \"Home\",\n drawerLabel: \"Home\",\n drawerIcon: ({ size, color }) => (\n <Ionicons name=\"home-outline\" size={size} color={color} />\n ),\n }}\n />\n <Drawer.Screen\n name=\"(tabs)\"\n options=\\\\{{\n headerTitle: \"Tabs\",\n drawerLabel: \"Tabs\",\n drawerIcon: ({ size, color }) => (\n <MaterialIcons name=\"border-bottom\" size={size} color={color} />\n ),\n headerRight: () => (\n <Link href=\"/modal\" asChild>\n <HeaderButton />\n </Link>\n ),\n }}\n />\n {{#if (includes examples \"todo\")}}\n <Drawer.Screen\n name=\"todos\"\n options=\\\\{{\n headerTitle: \"Todos\",\n drawerLabel: \"Todos\",\n drawerIcon: ({ size, color }) => (\n <Ionicons name=\"checkbox-outline\" size={size} color={color} />\n ),\n }}\n />\n {{/if}}\n {{#if (includes examples \"ai\")}}\n <Drawer.Screen\n name=\"ai\"\n options=\\\\{{\n headerTitle: \"AI\",\n drawerLabel: \"AI\",\n drawerIcon: ({ size, color }) => (\n <Ionicons\n name=\"chatbubble-ellipses-outline\"\n size={size}\n color={color}\n />\n ),\n }}\n />\n {{/if}}\n </Drawer>\n );\n};\n\nexport default DrawerLayout;\n\n`],\n [\"frontend/native/bare/app/(drawer)/index.tsx.hbs\", `import { View, Text, ScrollView, TouchableOpacity, StyleSheet } from \"react-native\";\nimport { Container } from \"@/components/container\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\n{{#if (eq api \"orpc\")}}\nimport { useQuery } from \"@tanstack/react-query\";\nimport { orpc } from \"@/utils/orpc\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { useQuery } from \"@tanstack/react-query\";\nimport { trpc } from \"@/utils/trpc\";\n{{/if}}\n{{#if (and (eq backend \"convex\") (eq auth \"clerk\"))}}\nimport { Link } from \"expo-router\";\nimport { Authenticated, AuthLoading, Unauthenticated, useQuery } from \"convex/react\";\nimport { api } from \"@{{ projectName }}/backend/convex/_generated/api\";\nimport { useUser } from \"@clerk/clerk-expo\";\nimport { SignOutButton } from \"@/components/sign-out-button\";\n{{else if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\nimport { useConvexAuth, useQuery } from \"convex/react\";\nimport { api } from \"@{{ projectName }}/backend/convex/_generated/api\";\nimport { authClient } from \"@/lib/auth-client\";\nimport { SignIn } from \"@/components/sign-in\";\nimport { SignUp } from \"@/components/sign-up\";\n{{else if (eq backend \"convex\")}}\nimport { useQuery } from \"convex/react\";\nimport { api } from \"@{{ projectName }}/backend/convex/_generated/api\";\n{{/if}}\n\nexport default function Home() {\nconst { colorScheme } = useColorScheme();\nconst theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\n{{#if (eq api \"orpc\")}}\nconst healthCheck = useQuery(orpc.healthCheck.queryOptions());\n{{/if}}\n{{#if (eq api \"trpc\")}}\nconst healthCheck = useQuery(trpc.healthCheck.queryOptions());\n{{/if}}\n{{#if (and (eq backend \"convex\") (eq auth \"clerk\"))}}\nconst { user } = useUser();\nconst healthCheck = useQuery(api.healthCheck.get);\nconst privateData = useQuery(api.privateData.get);\n{{else if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\nconst healthCheck = useQuery(api.healthCheck.get);\nconst { isAuthenticated } = useConvexAuth();\nconst user = useQuery(api.auth.getCurrentUser, isAuthenticated ? {} : \"skip\");\n{{else if (eq backend \"convex\")}}\nconst healthCheck = useQuery(api.healthCheck.get);\n{{/if}}\n\nreturn (\n<Container>\n <ScrollView style={styles.scrollView}>\n <View style={styles.content}>\n <Text style={[styles.title, { color: theme.text }]}>\n BETTER T STACK\n </Text>\n\n {{#unless (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\n <View style={[styles.card, { backgroundColor: theme.card, borderColor: theme.border }]}>\n {{#if (eq backend \"convex\")}}\n <View style={styles.statusRow}>\n <View style={[styles.statusIndicator, { backgroundColor: healthCheck ? \"#10b981\" : \"#f59e0b\" }]} />\n <View style={styles.statusContent}>\n <Text style={[styles.statusTitle, { color: theme.text }]}>\n Convex\n </Text>\n <Text style={[styles.statusText, { color: theme.text, opacity: 0.7 }]}>\n {healthCheck === undefined\n ? \"Checking...\"\n : healthCheck === \"OK\"\n ? \"Connected to API\"\n : \"API Disconnected\"}\n </Text>\n </View>\n </View>\n {{else}}\n {{#unless (eq api \"none\")}}\n <View style={styles.statusRow}>\n <View style={[styles.statusIndicator, { backgroundColor: healthCheck.data ? \"#10b981\" : \"#f59e0b\" }]} />\n <View style={styles.statusContent}>\n <Text style={[styles.statusTitle, { color: theme.text }]}>\n {{#if (eq api \"orpc\")}}ORPC{{else}}TRPC{{/if}}\n </Text>\n <Text style={[styles.statusText, { color: theme.text, opacity: 0.7 }]}>\n {healthCheck.isLoading\n ? \"Checking connection...\"\n : healthCheck.data\n ? \"All systems operational\"\n : \"Service unavailable\"}\n </Text>\n </View>\n </View>\n {{/unless}}\n {{/if}}\n </View>\n {{/unless}}\n\n {{#if (and (eq backend \"convex\") (eq auth \"clerk\"))}}\n <Authenticated>\n <Text style=\\\\{{ color: theme.text }}>Hello {user?.emailAddresses[0].emailAddress}</Text>\n <Text style=\\\\{{ color: theme.text }}>Private Data: {privateData?.message}</Text>\n <SignOutButton />\n </Authenticated>\n <Unauthenticated>\n <Link href=\"/(auth)/sign-in\">\n <Text style=\\\\{{ color: theme.primary }}>Sign in</Text>\n </Link>\n <Link href=\"/(auth)/sign-up\">\n <Text style=\\\\{{ color: theme.primary }}>Sign up</Text>\n </Link>\n </Unauthenticated>\n <AuthLoading>\n <Text style=\\\\{{ color: theme.text }}>Loading...</Text>\n </AuthLoading>\n {{/if}}\n\n {{#if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\n {user ? (\n <View style={[styles.userCard, { backgroundColor: theme.card, borderColor: theme.border }]}>\n <View style={styles.userHeader}>\n <Text style={[styles.userText, { color: theme.text }]}>\n Welcome, <Text style={styles.userName}>{user.name}</Text>\n </Text>\n </View>\n <Text style={[styles.userEmail, { color: theme.text, opacity: 0.7 }]}>\n {user.email}\n </Text>\n <TouchableOpacity style={[styles.signOutButton, { backgroundColor: theme.notification }]} onPress={()=> {\n authClient.signOut();\n }}\n >\n <Text style={styles.signOutText}>Sign Out</Text>\n </TouchableOpacity>\n </View>\n ) : null}\n <View style={[styles.statusCard, { backgroundColor: theme.card, borderColor: theme.border }]}>\n <Text style={[styles.statusCardTitle, { color: theme.text }]}>\n API Status\n </Text>\n <View style={styles.statusRow}>\n <View style={[styles.statusIndicator, { backgroundColor: healthCheck ? \"#10b981\" : \"#ef4444\" }]} />\n <Text style={[styles.statusText, { color: theme.text, opacity: 0.7 }]}>\n {healthCheck === undefined\n ? \"Checking...\"\n : healthCheck === \"OK\"\n ? \"Connected to API\"\n : \"API Disconnected\"}\n </Text>\n </View>\n </View>\n {!user && (\n <>\n <SignIn />\n <SignUp />\n </>\n )}\n {{/if}}\n </View>\n </ScrollView>\n</Container>\n);\n}\n\nconst styles = StyleSheet.create({\nscrollView: {\nflex: 1,\n},\ncontent: {\npadding: 16,\n},\ntitle: {\nfontSize: 24,\nfontWeight: \"bold\",\nmarginBottom: 16,\n},\ncard: {\npadding: 16,\nmarginBottom: 16,\nborderWidth: 1,\n},\nstatusRow: {\nflexDirection: \"row\",\nalignItems: \"center\",\ngap: 8,\n},\nstatusIndicator: {\nheight: 8,\nwidth: 8,\n},\nstatusContent: {\nflex: 1,\n},\nstatusTitle: {\nfontSize: 14,\nfontWeight: \"bold\",\n},\nstatusText: {\nfontSize: 12,\n},\nuserCard: {\nmarginBottom: 16,\npadding: 16,\nborderWidth: 1,\n},\nuserHeader: {\nmarginBottom: 8,\n},\nuserText: {\nfontSize: 16,\n},\nuserName: {\nfontWeight: \"bold\",\n},\nuserEmail: {\nfontSize: 14,\nmarginBottom: 12,\n},\nsignOutButton: {\npadding: 12,\n},\nsignOutText: {\ncolor: \"#ffffff\",\n},\nstatusCard: {\nmarginBottom: 16,\npadding: 16,\nborderWidth: 1,\n},\nstatusCardTitle: {\nmarginBottom: 8,\nfontWeight: \"bold\",\n},\n});`],\n [\"frontend/native/base/assets/images/partial-react-logo.png\", `[Binary file]`],\n [\"frontend/native/base/assets/images/react-logo.png\", `[Binary file]`],\n [\"frontend/native/base/assets/images/react-logo@2x.png\", `[Binary file]`],\n [\"frontend/native/base/assets/images/android-icon-monochrome.png\", `[Binary file]`],\n [\"frontend/native/base/assets/images/splash-icon.png\", `[Binary file]`],\n [\"frontend/native/base/assets/images/react-logo@3x.png\", `[Binary file]`],\n [\"frontend/native/base/assets/images/icon.png\", `[Binary file]`],\n [\"frontend/native/base/assets/images/android-icon-foreground.png\", `[Binary file]`],\n [\"frontend/native/base/assets/images/favicon.png\", `[Binary file]`],\n [\"frontend/native/base/assets/images/android-icon-background.png\", `[Binary file]`],\n [\"db/prisma/mongodb/prisma/schema/schema.prisma.hbs\", `generator client {\n provider = \"prisma-client\"\n output = \"../generated\"\n moduleFormat = \"esm\"\n {{#if (eq runtime \"bun\")}}\n runtime = \"bun\"\n {{/if}}\n {{#if (eq runtime \"node\")}}\n runtime = \"nodejs\"\n {{/if}}\n {{#if (or (eq runtime \"workers\") (and (eq backend \"self\") (eq webDeploy \"cloudflare\")))}}\n runtime = \"workerd\"\n {{/if}}\n}\n\ndatasource db {\n provider = \"mongodb\"\n url = env(\"DATABASE_URL\")\n}\n`],\n [\"frontend/native/uniwind/app/(drawer)/_layout.tsx.hbs\", `import React, { useCallback } from \"react\";\nimport { Ionicons, MaterialIcons } from \"@expo/vector-icons\";\nimport { Link } from \"expo-router\";\nimport { Drawer } from \"expo-router/drawer\";\nimport { useThemeColor } from \"heroui-native\";\nimport { Pressable, Text } from \"react-native\";\nimport { ThemeToggle } from \"@/components/theme-toggle\";\n\nfunction DrawerLayout() {\n const themeColorForeground = useThemeColor(\"foreground\");\n const themeColorBackground = useThemeColor(\"background\");\n\n const renderThemeToggle = useCallback(() => <ThemeToggle />, []);\n\n return (\n <Drawer\n screenOptions=\\\\{{\n headerTintColor: themeColorForeground,\n headerStyle: { backgroundColor: themeColorBackground },\n headerTitleStyle: {\n fontWeight: \"600\",\n color: themeColorForeground,\n },\n headerRight: renderThemeToggle,\n drawerStyle: { backgroundColor: themeColorBackground },\n }}\n >\n <Drawer.Screen\n name=\"index\"\n options=\\\\{{\n headerTitle: \"Home\",\n drawerLabel: ({ color, focused }) => (\n <Text style=\\\\{{ color: focused ? color : themeColorForeground }}>Home</Text>\n ),\n drawerIcon: ({ size, color, focused }) => (\n <Ionicons name=\"home-outline\" size={size} color={focused ? color : themeColorForeground} />\n ),\n }}\n />\n <Drawer.Screen\n name=\"(tabs)\"\n options=\\\\{{\n headerTitle: \"Tabs\",\n drawerLabel: ({ color, focused }) => (\n <Text style=\\\\{{ color: focused ? color : themeColorForeground }}>Tabs</Text>\n ),\n drawerIcon: ({ size, color, focused }) => (\n <MaterialIcons name=\"border-bottom\" size={size} color={focused ? color : themeColorForeground} />\n ),\n headerRight: () => (\n <Link href=\"/modal\" asChild>\n <Pressable className=\"mr-4\">\n <Ionicons name=\"add-outline\" size={24} color={themeColorForeground} />\n </Pressable>\n </Link>\n ),\n }}\n />\n {{#if (includes examples \"todo\")}}\n <Drawer.Screen\n name=\"todos\"\n options=\\\\{{\n headerTitle: \"Todos\",\n drawerLabel: ({ color, focused }) => (\n <Text style=\\\\{{ color: focused ? color : themeColorForeground }}>Todos</Text>\n ),\n drawerIcon: ({ size, color, focused }) => (\n <Ionicons name=\"checkbox-outline\" size={size} color={focused ? color : themeColorForeground} />\n ),\n }}\n />\n {{/if}}\n {{#if (includes examples \"ai\")}}\n <Drawer.Screen\n name=\"ai\"\n options=\\\\{{\n headerTitle: \"AI\",\n drawerLabel: ({ color, focused }) => (\n <Text style=\\\\{{ color: focused ? color : themeColorForeground }}>AI</Text>\n ),\n drawerIcon: ({ size, color, focused }) => (\n <Ionicons name=\"chatbubble-ellipses-outline\" size={size} color={focused ? color : themeColorForeground} />\n ),\n }}\n />\n {{/if}}\n </Drawer>\n );\n}\n\nexport default DrawerLayout;`],\n [\"frontend/native/uniwind/app/(drawer)/index.tsx.hbs\", `import { Text, View } from \"react-native\";\nimport { Container } from \"@/components/container\";\n{{#if (eq api \"orpc\")}}\nimport { useQuery } from \"@tanstack/react-query\";\nimport { orpc } from \"@/utils/orpc\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { useQuery } from \"@tanstack/react-query\";\nimport { trpc } from \"@/utils/trpc\";\n{{/if}}\n{{#if (and (eq backend \"convex\") (eq auth \"clerk\"))}}\nimport { Link } from \"expo-router\";\nimport { Authenticated, AuthLoading, Unauthenticated, useQuery } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport { useUser } from \"@clerk/clerk-expo\";\nimport { SignOutButton } from \"@/components/sign-out-button\";\n{{else if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\nimport { useConvexAuth, useQuery } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport { authClient } from \"@/lib/auth-client\";\nimport { SignIn } from \"@/components/sign-in\";\nimport { SignUp } from \"@/components/sign-up\";\n{{else if (eq backend \"convex\")}}\nimport { useQuery } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\n{{/if}}\n{{#unless (or (eq backend \"none\") (and (eq backend \"convex\") (eq auth \"better-auth\")))}}\nimport { Ionicons } from \"@expo/vector-icons\";\n{{/unless}}\nimport { Button, Chip, Divider, Spinner, Surface, useThemeColor } from \"heroui-native\";\n\nexport default function Home() {\n{{#if (eq api \"orpc\")}}\nconst healthCheck = useQuery(orpc.healthCheck.queryOptions());\n{{/if}}\n{{#if (eq api \"trpc\")}}\nconst healthCheck = useQuery(trpc.healthCheck.queryOptions());\n{{/if}}\n{{#if (and (eq backend \"convex\") (eq auth \"clerk\"))}}\nconst { user } = useUser();\nconst healthCheck = useQuery(api.healthCheck.get);\nconst privateData = useQuery(api.privateData.get);\n{{else if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\nconst healthCheck = useQuery(api.healthCheck.get);\nconst { isAuthenticated } = useConvexAuth();\nconst user = useQuery(api.auth.getCurrentUser, isAuthenticated ? {} : \"skip\");\n{{else if (eq backend \"convex\")}}\nconst healthCheck = useQuery(api.healthCheck.get);\n{{/if}}\n{{#unless (eq backend \"none\")}}\nconst successColor = useThemeColor(\"success\");\nconst dangerColor = useThemeColor(\"danger\");\n\n{{#if (eq backend \"convex\")}}\nconst isConnected = healthCheck === \"OK\";\nconst isLoading = healthCheck === undefined;\n{{else}}\n{{#unless (eq api \"none\")}}\nconst isConnected = healthCheck?.data === \"OK\";\nconst isLoading = healthCheck?.isLoading;\n{{/unless}}\n{{/if}}\n{{/unless}}\n\nreturn (\n<Container className=\"p-4\">\n <View className=\"py-6 mb-4\">\n <Text className=\"text-3xl font-semibold text-foreground tracking-tight\">\n Better T Stack\n </Text>\n <Text className=\"text-muted text-sm mt-1\">Full-stack TypeScript starter</Text>\n </View>\n\n {{#unless (or (eq backend \"none\") (and (eq backend \"convex\") (eq auth \"better-auth\")))}}\n <Surface variant=\"secondary\" className=\"p-4 rounded-lg\">\n <View className=\"flex-row items-center justify-between mb-3\">\n <Text className=\"text-foreground font-medium\">System Status</Text>\n <Chip variant=\"secondary\" color={isConnected ? \"success\" : \"danger\" } size=\"sm\">\n <Chip.Label>\n {isConnected ? \"LIVE\" : \"OFFLINE\"}\n </Chip.Label>\n </Chip>\n </View>\n\n <Divider className=\"mb-3\" />\n\n <Surface variant=\"tertiary\" className=\"p-3 rounded-md\">\n <View className=\"flex-row items-center\">\n <View className={\\`w-2 h-2 rounded-full mr-3 \\${ isConnected ? \"bg-success\" : \"bg-muted\" }\\`} />\n <View className=\"flex-1\">\n <Text className=\"text-foreground text-sm font-medium\">\n {{#if (eq backend \"convex\")}}\n Convex Backend\n {{else}}\n {{#unless (eq api \"none\")}}\n {{#if (eq api \"orpc\")}}ORPC{{else}}TRPC{{/if}} Backend\n {{/unless}}\n {{/if}}\n </Text>\n <Text className=\"text-muted text-xs mt-0.5\">\n {isLoading\n ? \"Checking connection...\"\n : isConnected\n ? \"Connected to API\"\n : \"API Disconnected\"}\n </Text>\n </View>\n {isLoading && <Spinner size=\"sm\" />}\n {!isLoading && isConnected && (\n <Ionicons name=\"checkmark-circle\" size={18} color={successColor} />\n )}\n {!isLoading && !isConnected && (\n <Ionicons name=\"close-circle\" size={18} color={dangerColor} />\n )}\n </View>\n </Surface>\n </Surface>\n {{/unless}}\n\n {{#if (and (eq backend \"convex\") (eq auth \"clerk\"))}}\n <Authenticated>\n <Surface variant=\"secondary\" className=\"mt-4 p-4 rounded-lg\">\n <View className=\"flex-row items-center justify-between\">\n <View className=\"flex-1\">\n <Text className=\"text-foreground font-medium\">{user?.emailAddresses[0].emailAddress}</Text>\n <Text className=\"text-muted text-xs mt-0.5\">Private: {privateData?.message}</Text>\n </View>\n <SignOutButton />\n </View>\n </Surface>\n </Authenticated>\n <Unauthenticated>\n <View className=\"mt-4 gap-3\">\n <Link href=\"/(auth)/sign-in\" asChild>\n <Button variant=\"secondary\"><Button.Label>Sign In</Button.Label></Button>\n </Link>\n <Link href=\"/(auth)/sign-up\" asChild>\n <Button variant=\"ghost\"><Button.Label>Sign Up</Button.Label></Button>\n </Link>\n </View>\n </Unauthenticated>\n <AuthLoading>\n <View className=\"mt-4 items-center\">\n <Spinner size=\"sm\" />\n </View>\n </AuthLoading>\n {{/if}}\n\n {{#if (and (eq backend \"convex\") (eq auth \"better-auth\"))}}\n {user ? (\n <Surface variant=\"secondary\" className=\"mb-4 p-4 rounded-lg\">\n <View className=\"flex-row items-center justify-between\">\n <View className=\"flex-1\">\n <Text className=\"text-foreground font-medium\">{user.name}</Text>\n <Text className=\"text-muted text-xs mt-0.5\">{user.email}</Text>\n </View>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onPress={() => {\n authClient.signOut();\n }}\n >\n Sign Out\n </Button>\n </View>\n </Surface>\n ) : null}\n <Surface variant=\"secondary\" className=\"p-4 rounded-lg\">\n <Text className=\"text-foreground font-medium mb-2\">API Status</Text>\n <View className=\"flex-row items-center gap-2\">\n <View className={\\`w-2 h-2 rounded-full \\${healthCheck===\"OK\" ? \"bg-success\" : \"bg-danger\" }\\`} />\n <Text className=\"text-muted text-xs\">\n {healthCheck === undefined\n ? \"Checking...\"\n : healthCheck === \"OK\"\n ? \"Connected to API\"\n : \"API Disconnected\"}\n </Text>\n </View>\n </Surface>\n {!user && (\n <View className=\"mt-4 gap-4\">\n <SignIn />\n <SignUp />\n </View>\n )}\n {{/if}}\n</Container>\n);\n}`],\n [\"db/drizzle/base/src/schema/index.ts.hbs\", `{{#if (eq auth \"better-auth\")}}\nexport * from \"./auth\";\n{{/if}}\n{{#if (includes examples \"todo\")}}\nexport * from \"./todo\";\n{{/if}}\nexport {};`],\n [\"db/prisma/mysql/prisma/schema/schema.prisma.hbs\", `generator client {\n provider = \"prisma-client\"\n output = \"../generated\"\n moduleFormat = \"esm\"\n {{#if (eq runtime \"bun\")}}\n runtime = \"bun\"\n {{/if}}\n {{#if (eq runtime \"node\")}}\n runtime = \"nodejs\"\n {{/if}}\n {{#if (or (eq runtime \"workers\") (and (eq backend \"self\") (eq webDeploy \"cloudflare\")))}}\n runtime = \"workerd\"\n {{/if}}\n}\n\ndatasource db {\n provider = \"mysql\"\n {{#if (eq dbSetup \"planetscale\")}}\n relationMode = \"prisma\"\n {{/if}}\n}`],\n [\"db/prisma/postgres/prisma/schema/schema.prisma.hbs\", `generator client {\n provider = \"prisma-client\"\n output = \"../generated\"\n moduleFormat = \"esm\"\n {{#if (eq runtime \"bun\")}}\n runtime = \"bun\"\n {{/if}}\n {{#if (eq runtime \"node\")}}\n runtime = \"nodejs\"\n {{/if}}\n {{#if (or (eq runtime \"workers\") (and (eq backend \"self\") (eq webDeploy \"cloudflare\")))}}\n runtime = \"workerd\"\n {{/if}}\n}\n\ndatasource db {\n provider = \"postgresql\"\n {{#if (eq dbSetup \"planetscale\")}}\n relationMode = \"prisma\"\n {{/if}}\n}\n`],\n [\"db/kysely/base/src/schema/index.ts.hbs\", `import type { Generated, ColumnType } from \"kysely\";\n\n{{#if (eq auth \"better-auth\")}}\n// Auth tables\nexport interface UserTable {\n\tid: string;\n\tname: string;\n\temail: string;\n\temailVerified: number;\n\timage: string | null;\n\tcreatedAt: ColumnType<Date, string | undefined, never>;\n\tupdatedAt: ColumnType<Date, string | undefined, never>;\n}\n\nexport interface SessionTable {\n\tid: string;\n\texpiresAt: ColumnType<Date, string, string>;\n\ttoken: string;\n\tcreatedAt: ColumnType<Date, string | undefined, never>;\n\tupdatedAt: ColumnType<Date, string | undefined, never>;\n\tipAddress: string | null;\n\tuserAgent: string | null;\n\tuserId: string;\n}\n\nexport interface AccountTable {\n\tid: string;\n\taccountId: string;\n\tproviderId: string;\n\tuserId: string;\n\taccessToken: string | null;\n\trefreshToken: string | null;\n\tidToken: string | null;\n\taccessTokenExpiresAt: ColumnType<Date, string | null, string | null>;\n\trefreshTokenExpiresAt: ColumnType<Date, string | null, string | null>;\n\tscope: string | null;\n\tpassword: string | null;\n\tcreatedAt: ColumnType<Date, string | undefined, never>;\n\tupdatedAt: ColumnType<Date, string | undefined, never>;\n}\n\nexport interface VerificationTable {\n\tid: string;\n\tidentifier: string;\n\tvalue: string;\n\texpiresAt: ColumnType<Date, string, string>;\n\tcreatedAt: ColumnType<Date, string | undefined, never>;\n\tupdatedAt: ColumnType<Date, string | undefined, never>;\n}\n{{/if}}\n\n{{#if (includes examples \"todo\")}}\n// Todo table\nexport interface TodoTable {\n\tid: Generated<number>;\n\ttext: string;\n\tcompleted: number;\n\tcreatedAt: ColumnType<Date, string | undefined, never>;\n}\n{{/if}}\n\n// Database interface - lists all tables\nexport interface Database {\n{{#if (eq auth \"better-auth\")}}\n\tuser: UserTable;\n\tsession: SessionTable;\n\taccount: AccountTable;\n\tverification: VerificationTable;\n{{/if}}\n{{#if (includes examples \"todo\")}}\n\ttodo: TodoTable;\n{{/if}}\n}\n`],\n [\"db/typeorm/base/src/entities/index.ts.hbs\", `{{#if (eq auth \"better-auth\")}}\nexport * from \"./user\";\nexport * from \"./session\";\nexport * from \"./account\";\nexport * from \"./verification\";\n{{/if}}\n{{#if (includes examples \"todo\")}}\nexport * from \"./todo\";\n{{/if}}\nexport {};\n`],\n [\"db/prisma/sqlite/prisma/schema/schema.prisma.hbs\", `generator client {\n provider = \"prisma-client\"\n output = \"../generated\"\n moduleFormat = \"esm\"\n {{#if (eq runtime \"bun\")}}\n runtime = \"bun\"\n {{/if}}\n {{#if (eq runtime \"node\")}}\n runtime = \"nodejs\"\n {{/if}}\n {{#if (or (eq runtime \"workers\") (and (eq backend \"self\") (eq webDeploy \"cloudflare\")))}}\n runtime = \"workerd\"\n {{/if}}\n}\n\ndatasource db {\n provider = \"sqlite\"\n}\n`],\n [\"api/ts-rest/server/src/routers/index.ts.hbs\", `import { contract } from \"../index\";\nimport type { Context } from \"../context\";\n{{#if (includes examples \"todo\")}}\nimport { todoHandlers } from \"./todo\";\n{{/if}}\n\nexport function createRouter(ctx: Context) {\n return {\n healthCheck: async () => {\n return {\n status: 200 as const,\n body: \"OK\" as const,\n };\n },\n{{#if (eq auth \"better-auth\")}}\n privateData: async () => {\n if (!ctx.session) {\n return {\n status: 401 as const,\n body: {\n message: \"Authentication required\",\n },\n };\n }\n return {\n status: 200 as const,\n body: {\n message: \"This is private\",\n user: ctx.session.user,\n },\n };\n },\n{{/if}}\n{{#if (includes examples \"todo\")}}\n todos: todoHandlers(ctx),\n{{/if}}\n };\n}\n\nexport type AppRouter = ReturnType<typeof createRouter>;\n`],\n [\"api/ts-rest/server/src/routers/todo.ts.hbs\", `{{#if (includes examples \"todo\")}}\nimport type { Context } from \"../context\";\nimport { db } from \"@{{projectName}}/db\";\nimport { todos } from \"@{{projectName}}/db/schema\";\nimport { eq } from \"drizzle-orm\";\n\nexport function todoHandlers(ctx: Context) {\n return {\n getAll: async () => {\n const allTodos = await db.select().from(todos).orderBy(todos.createdAt);\n return {\n status: 200 as const,\n body: allTodos.map((t) => ({\n ...t,\n createdAt: t.createdAt.toISOString(),\n })),\n };\n },\n create: async ({ body }: { body: { content: string } }) => {\n const [newTodo] = await db\n .insert(todos)\n .values({ content: body.content })\n .returning();\n return {\n status: 201 as const,\n body: {\n ...newTodo,\n createdAt: newTodo.createdAt.toISOString(),\n },\n };\n },\n toggle: async ({ params }: { params: { id: number } }) => {\n const [existing] = await db\n .select()\n .from(todos)\n .where(eq(todos.id, params.id));\n if (!existing) {\n return {\n status: 404 as const,\n body: { message: \"Todo not found\" },\n };\n }\n const [updated] = await db\n .update(todos)\n .set({ completed: !existing.completed })\n .where(eq(todos.id, params.id))\n .returning();\n return {\n status: 200 as const,\n body: {\n ...updated,\n createdAt: updated.createdAt.toISOString(),\n },\n };\n },\n delete: async ({ params }: { params: { id: number } }) => {\n const [existing] = await db\n .select()\n .from(todos)\n .where(eq(todos.id, params.id));\n if (!existing) {\n return {\n status: 404 as const,\n body: { message: \"Todo not found\" },\n };\n }\n await db.delete(todos).where(eq(todos.id, params.id));\n return {\n status: 200 as const,\n body: { success: true },\n };\n },\n };\n}\n{{/if}}\n`],\n [\"api/garph/server/src/routers/index.ts.hbs\", `import { g, buildSchema, type InferResolvers, queryType, mutationType } from \"../index\";\nimport type { Context } from \"../context\";\n{{#if (includes examples \"todo\")}}\nimport { todoResolvers } from \"./todo\";\n{{/if}}\n\nexport function createResolvers(ctx: Context): InferResolvers<{ Query: typeof queryType; Mutation: typeof mutationType }, { context: Context }> {\n{{#if (includes examples \"todo\")}}\n const todos = todoResolvers(ctx);\n{{/if}}\n\n return {\n Query: {\n health: () => \"OK\",\n{{#if (eq auth \"better-auth\")}}\n privateData: () => {\n if (!ctx.session) {\n return null;\n }\n return {\n message: \"This is private data\",\n user: ctx.session.user,\n };\n },\n{{/if}}\n{{#if (includes examples \"todo\")}}\n todos: todos.getAll,\n todo: todos.getOne,\n{{/if}}\n },\n Mutation: {\n{{#if (includes examples \"todo\")}}\n createTodo: todos.create,\n toggleTodo: todos.toggle,\n deleteTodo: todos.delete,\n{{/if}}\n _empty: () => null,\n },\n };\n}\n\nexport function createSchema(ctx: Context) {\n const resolvers = createResolvers(ctx);\n return buildSchema({ g, resolvers });\n}\n`],\n [\"api/garph/server/src/routers/todo.ts.hbs\", `{{#if (includes examples \"todo\")}}\nimport type { Context } from \"../context\";\nimport { db } from \"@{{projectName}}/db\";\nimport { todos } from \"@{{projectName}}/db/schema\";\nimport { eq } from \"drizzle-orm\";\n\nexport function todoResolvers(ctx: Context) {\n return {\n getAll: async () => {\n const allTodos = await db.select().from(todos).orderBy(todos.createdAt);\n return allTodos.map((t) => ({\n ...t,\n createdAt: t.createdAt.toISOString(),\n }));\n },\n getOne: async (_: unknown, args: { id: number }) => {\n const [todo] = await db.select().from(todos).where(eq(todos.id, args.id));\n if (!todo) return null;\n return {\n ...todo,\n createdAt: todo.createdAt.toISOString(),\n };\n },\n create: async (_: unknown, args: { content: string }) => {\n const [newTodo] = await db\n .insert(todos)\n .values({ content: args.content })\n .returning();\n return {\n ...newTodo,\n createdAt: newTodo.createdAt.toISOString(),\n };\n },\n toggle: async (_: unknown, args: { id: number }) => {\n const [existing] = await db\n .select()\n .from(todos)\n .where(eq(todos.id, args.id));\n if (!existing) return null;\n const [updated] = await db\n .update(todos)\n .set({ completed: !existing.completed })\n .where(eq(todos.id, args.id))\n .returning();\n return {\n ...updated,\n createdAt: updated.createdAt.toISOString(),\n };\n },\n delete: async (_: unknown, args: { id: number }) => {\n const [existing] = await db\n .select()\n .from(todos)\n .where(eq(todos.id, args.id));\n if (!existing) return false;\n await db.delete(todos).where(eq(todos.id, args.id));\n return true;\n },\n };\n}\n{{/if}}\n`],\n [\"db/sequelize/base/src/models/index.ts.hbs\", `{{#if (eq auth \"better-auth\")}}\nexport * from \"./user\";\nexport * from \"./session\";\nexport * from \"./account\";\nexport * from \"./verification\";\n{{/if}}\n{{#if (includes examples \"todo\")}}\nexport * from \"./todo\";\n{{/if}}\nexport {};\n`],\n [\"db/mikroorm/base/src/entities/index.ts.hbs\", `{{#if (eq auth \"better-auth\")}}\nexport * from \"./user\";\nexport * from \"./session\";\nexport * from \"./account\";\nexport * from \"./verification\";\n{{/if}}\n{{#if (includes examples \"todo\")}}\nexport * from \"./todo\";\n{{/if}}\nexport {};\n`],\n [\"backend/server/nestjs/src/trpc/trpc.module.ts.hbs\", `import { Module, type MiddlewareConsumer, type NestModule } from \"@nestjs/common\";\nimport { TrpcMiddleware } from \"./trpc.middleware\";\n\n@Module({})\nexport class TrpcModule implements NestModule {\n\tconfigure(consumer: MiddlewareConsumer) {\n\t\tconsumer.apply(TrpcMiddleware).forRoutes(\"trpc/*path\");\n\t}\n}\n`],\n [\"backend/server/nestjs/src/trpc/trpc.middleware.ts.hbs\", `import { Injectable, type NestMiddleware } from \"@nestjs/common\";\nimport { createExpressMiddleware } from \"@trpc/server/adapters/express\";\nimport { createContext } from \"@{{projectName}}/api/context\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\nimport type { Request, Response, NextFunction } from \"express\";\n\n@Injectable()\nexport class TrpcMiddleware implements NestMiddleware {\n\tprivate trpcMiddleware = createExpressMiddleware({\n\t\trouter: appRouter,\n\t\tcreateContext,\n\t});\n\n\tuse(req: Request, res: Response, next: NextFunction) {\n\t\tthis.trpcMiddleware(req, res, next);\n\t}\n}\n`],\n [\"backend/server/nestjs/src/ai/ai.service.ts.hbs\", `import { Injectable } from \"@nestjs/common\";\nimport { streamText, type UIMessage, convertToModelMessages, wrapLanguageModel } from \"ai\";\nimport { google } from \"@ai-sdk/google\";\nimport { devToolsMiddleware } from \"@ai-sdk/devtools\";\nimport type { Request, Response } from \"express\";\n\n@Injectable()\nexport class AiService {\n\tasync streamChat(req: Request, res: Response) {\n\t\tconst { messages = [] } = (req.body || {}) as { messages: UIMessage[] };\n\t\tconst model = wrapLanguageModel({\n\t\t\tmodel: google(\"gemini-2.5-flash\"),\n\t\t\tmiddleware: devToolsMiddleware(),\n\t\t});\n\t\tconst result = streamText({\n\t\t\tmodel,\n\t\t\tmessages: await convertToModelMessages(messages),\n\t\t});\n\t\tresult.pipeUIMessageStreamToResponse(res);\n\t}\n}\n`],\n [\"backend/server/nestjs/src/ai/ai.controller.ts.hbs\", `import { Controller, Post, Req, Res } from \"@nestjs/common\";\nimport { AiService } from \"./ai.service\";\nimport type { Request, Response } from \"express\";\n\n@Controller(\"ai\")\nexport class AiController {\n\tconstructor(private readonly aiService: AiService) {}\n\n\t@Post()\n\tasync chat(@Req() req: Request, @Res() res: Response) {\n\t\treturn this.aiService.streamChat(req, res);\n\t}\n}\n`],\n [\"backend/server/nestjs/src/ai/ai.module.ts.hbs\", `import { Module } from \"@nestjs/common\";\nimport { AiController } from \"./ai.controller\";\nimport { AiService } from \"./ai.service\";\n\n@Module({\n\tcontrollers: [AiController],\n\tproviders: [AiService],\n})\nexport class AiModule {}\n`],\n [\"backend/server/nestjs/src/orpc/orpc.module.ts.hbs\", `import { Module, type MiddlewareConsumer, type NestModule } from \"@nestjs/common\";\nimport { OrpcMiddleware } from \"./orpc.middleware\";\n\n@Module({})\nexport class OrpcModule implements NestModule {\n\tconfigure(consumer: MiddlewareConsumer) {\n\t\tconsumer.apply(OrpcMiddleware).forRoutes(\"rpc/*path\", \"api-reference/*path\");\n\t}\n}\n`],\n [\"backend/server/nestjs/src/orpc/orpc.middleware.ts.hbs\", `import { Injectable, type NestMiddleware } from \"@nestjs/common\";\nimport { OpenAPIHandler } from \"@orpc/openapi/node\";\nimport { OpenAPIReferencePlugin } from \"@orpc/openapi/plugins\";\nimport { ZodToJsonSchemaConverter } from \"@orpc/zod/zod4\";\nimport { RPCHandler } from \"@orpc/server/node\";\nimport { onError } from \"@orpc/server\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\n{{#if (eq auth \"better-auth\")}}\nimport { createContext } from \"@{{projectName}}/api/context\";\n{{/if}}\nimport type { Request, Response, NextFunction } from \"express\";\n\n@Injectable()\nexport class OrpcMiddleware implements NestMiddleware {\n\tprivate rpcHandler = new RPCHandler(appRouter, {\n\t\tinterceptors: [\n\t\t\tonError((error) => {\n\t\t\t\tconsole.error(error);\n\t\t\t}),\n\t\t],\n\t});\n\n\tprivate apiHandler = new OpenAPIHandler(appRouter, {\n\t\tplugins: [\n\t\t\tnew OpenAPIReferencePlugin({\n\t\t\t\tschemaConverters: [new ZodToJsonSchemaConverter()],\n\t\t\t}),\n\t\t],\n\t\tinterceptors: [\n\t\t\tonError((error) => {\n\t\t\t\tconsole.error(error);\n\t\t\t}),\n\t\t],\n\t});\n\n\tasync use(req: Request, res: Response, next: NextFunction) {\n\t\tconst rpcResult = await this.rpcHandler.handle(req, res, {\n\t\t\tprefix: \"/rpc\",\n{{#if (eq auth \"better-auth\")}}\n\t\t\tcontext: await createContext({ req }),\n{{else}}\n\t\t\tcontext: {},\n{{/if}}\n\t\t});\n\t\tif (rpcResult.matched) return;\n\n\t\tconst apiResult = await this.apiHandler.handle(req, res, {\n\t\t\tprefix: \"/api-reference\",\n{{#if (eq auth \"better-auth\")}}\n\t\t\tcontext: await createContext({ req }),\n{{else}}\n\t\t\tcontext: {},\n{{/if}}\n\t\t});\n\t\tif (apiResult.matched) return;\n\n\t\tnext();\n\t}\n}\n`],\n [\"addons/storybook/apps/web/.storybook/main.ts.hbs\", `import type { StorybookConfig } from \"{{#if (eq frontend \"next\")}}@storybook/nextjs{{else if (or (eq frontend \"tanstack-router\") (eq frontend \"react-router\") (eq frontend \"solid\"))}}@storybook/react-vite{{else if (eq frontend \"nuxt\")}}@storybook/vue3-vite{{else if (eq frontend \"svelte\")}}@storybook/svelte-vite{{else}}@storybook/react-vite{{/if}}\";\n\nconst config: StorybookConfig = {\n stories: [\"../src/**/*.mdx\", \"../src/**/*.stories.@(js|jsx|mjs|ts|tsx)\"],\n addons: [\n \"@storybook/addon-essentials\",\n \"@storybook/addon-interactions\",\n ],\n framework: {\n name: \"{{#if (eq frontend \"next\")}}@storybook/nextjs{{else if (or (eq frontend \"tanstack-router\") (eq frontend \"react-router\") (eq frontend \"solid\"))}}@storybook/react-vite{{else if (eq frontend \"nuxt\")}}@storybook/vue3-vite{{else if (eq frontend \"svelte\")}}@storybook/svelte-vite{{else}}@storybook/react-vite{{/if}}\",\n options: {},\n },\n};\n\nexport default config;\n`],\n [\"addons/storybook/apps/web/.storybook/preview.ts.hbs\", `{{#if (eq frontend \"next\")}}\nimport type { Preview } from \"@storybook/nextjs\";\n{{else if (or (eq frontend \"tanstack-router\") (eq frontend \"react-router\") (eq frontend \"solid\"))}}\nimport type { Preview } from \"@storybook/react-vite\";\n{{else if (eq frontend \"nuxt\")}}\nimport type { Preview } from \"@storybook/vue3-vite\";\n{{else if (eq frontend \"svelte\")}}\nimport type { Preview } from \"@storybook/svelte-vite\";\n{{else}}\nimport type { Preview } from \"@storybook/react-vite\";\n{{/if}}\n{{#if (eq cssFramework \"tailwind\")}}\nimport \"../src/index.css\";\n{{/if}}\n\nconst preview: Preview = {\n parameters: {\n controls: {\n matchers: {\n color: /(background|color)$/i,\n date: /Date$/i,\n },\n },\n },\n};\n\nexport default preview;\n`],\n [\"observability/opentelemetry/server/base/src/lib/tracing.ts.hbs\", `import { NodeSDK } from \"@opentelemetry/sdk-node\";\nimport { getNodeAutoInstrumentations } from \"@opentelemetry/auto-instrumentations-node\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport { OTLPMetricExporter } from \"@opentelemetry/exporter-metrics-otlp-http\";\nimport { Resource } from \"@opentelemetry/resources\";\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n ATTR_DEPLOYMENT_ENVIRONMENT_NAME,\n} from \"@opentelemetry/semantic-conventions\";\nimport { PeriodicExportingMetricReader } from \"@opentelemetry/sdk-metrics\";\n\n// Service configuration from environment variables\nconst serviceName = process.env.OTEL_SERVICE_NAME || \"{{projectName}}-server\";\nconst serviceVersion = process.env.OTEL_SERVICE_VERSION || \"1.0.0\";\nconst environment = process.env.NODE_ENV || \"development\";\n\n// OTLP endpoint configuration\n// Default to localhost:4318 for local development with Jaeger or OTEL Collector\nconst otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT || \"http://localhost:4318\";\n\n// Create resource with service information\nconst resource = new Resource({\n [ATTR_SERVICE_NAME]: serviceName,\n [ATTR_SERVICE_VERSION]: serviceVersion,\n [ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: environment,\n});\n\n// Configure trace exporter\nconst traceExporter = new OTLPTraceExporter({\n url: \\`\\${otlpEndpoint}/v1/traces\\`,\n});\n\n// Configure metric exporter\nconst metricExporter = new OTLPMetricExporter({\n url: \\`\\${otlpEndpoint}/v1/metrics\\`,\n});\n\n// Initialize OpenTelemetry SDK\nconst sdk = new NodeSDK({\n resource,\n traceExporter,\n metricReader: new PeriodicExportingMetricReader({\n exporter: metricExporter,\n // Export metrics every 30 seconds\n exportIntervalMillis: 30000,\n }),\n instrumentations: [\n getNodeAutoInstrumentations({\n // Disable fs instrumentation to reduce noise\n \"@opentelemetry/instrumentation-fs\": {\n enabled: false,\n },\n // Configure HTTP instrumentation\n \"@opentelemetry/instrumentation-http\": {\n enabled: true,\n },\n }),\n ],\n});\n\n/**\n * Start the OpenTelemetry SDK\n * Call this at the very beginning of your application, before any other imports\n *\n * @example\n * // At the top of your main entry file (e.g., index.ts)\n * import { startTracing } from './lib/tracing';\n * startTracing();\n *\n * // Then import and start your application\n * import { app } from './app';\n */\nexport function startTracing(): void {\n sdk.start();\n console.log(\\`[OpenTelemetry] Tracing started for service: \\${serviceName}\\`);\n console.log(\\`[OpenTelemetry] Exporting to: \\${otlpEndpoint}\\`);\n}\n\n/**\n * Gracefully shutdown the SDK\n * Call this before your application exits to ensure all spans are flushed\n *\n * @example\n * process.on('SIGTERM', async () => {\n * await shutdownTracing();\n * process.exit(0);\n * });\n */\nexport async function shutdownTracing(): Promise<void> {\n try {\n await sdk.shutdown();\n console.log(\"[OpenTelemetry] Tracing shutdown complete\");\n } catch (error) {\n console.error(\"[OpenTelemetry] Error shutting down tracing:\", error);\n }\n}\n\n/**\n * Get the OpenTelemetry API for manual instrumentation\n * Use this when you need to create custom spans or add attributes\n *\n * @example\n * import { trace } from '@opentelemetry/api';\n *\n * const tracer = trace.getTracer('my-component');\n * const span = tracer.startSpan('my-operation');\n * try {\n * // ... do work\n * span.setAttribute('result', 'success');\n * } catch (error) {\n * span.recordException(error);\n * span.setStatus({ code: SpanStatusCode.ERROR });\n * } finally {\n * span.end();\n * }\n */\nexport { trace, context, SpanStatusCode } from \"@opentelemetry/api\";\n\n/**\n * Environment Variables:\n *\n * OTEL_SERVICE_NAME - Service name for tracing (default: {{projectName}}-server)\n * OTEL_SERVICE_VERSION - Service version (default: 1.0.0)\n * OTEL_EXPORTER_OTLP_ENDPOINT - OTLP collector endpoint (default: http://localhost:4318)\n *\n * Common OTLP backends:\n * - Jaeger: http://localhost:4318 (with OTLP enabled)\n * - OTEL Collector: http://localhost:4318\n * - Grafana Tempo: Your Tempo endpoint\n * - Honeycomb: https://api.honeycomb.io (requires API key header)\n * - Datadog: https://trace.agent.datadoghq.com\n *\n * For production, configure OTEL_EXPORTER_OTLP_HEADERS for authentication:\n * OTEL_EXPORTER_OTLP_HEADERS=\"x-honeycomb-team=your-api-key\"\n */\n`],\n [\"backend/convex/packages/backend/convex/convex.config.ts.hbs\", `import { defineApp } from \"convex/server\";\n{{#if (eq auth \"better-auth\")}}\nimport betterAuth from \"@convex-dev/better-auth/convex.config\";\n{{/if}}\n{{#if (includes examples \"ai\")}}\nimport agent from \"@convex-dev/agent/convex.config\";\n{{/if}}\n\nconst app = defineApp();\n{{#if (eq auth \"better-auth\")}}\napp.use(betterAuth);\n{{/if}}\n{{#if (includes examples \"ai\")}}\napp.use(agent);\n{{/if}}\n\nexport default app;\n`],\n [\"backend/convex/packages/backend/convex/schema.ts.hbs\", `import { defineSchema, defineTable } from \"convex/server\";\nimport { v } from \"convex/values\";\n\nexport default defineSchema({\n{{#if (includes examples \"todo\")}}\n todos: defineTable({\n text: v.string(),\n completed: v.boolean(),\n }),\n{{/if}}\n});\n`],\n [\"backend/convex/packages/backend/convex/healthCheck.ts.hbs\", `import { query } from \"./_generated/server\";\n\nexport const get = query({\n handler: async () => {\n return \"OK\";\n },\n});\n`],\n [\"backend/convex/packages/backend/convex/tsconfig.json.hbs\", `{\n /* This TypeScript project config describes the environment that\n * Convex functions run in and is used to typecheck them.\n * You can modify it, but some settings are required to use Convex.\n */\n \"compilerOptions\": {\n /* These settings are not required by Convex and can be modified. */\n \"allowJs\": true,\n \"strict\": true,\n \"moduleResolution\": \"Bundler\",\n \"jsx\": \"react-jsx\",\n \"skipLibCheck\": true,\n \"allowSyntheticDefaultImports\": true,\n\n /* These compiler options are required by Convex */\n \"target\": \"ESNext\",\n \"lib\": [\"ES2021\", \"dom\"],\n \"forceConsistentCasingInFileNames\": true,\n \"module\": \"ESNext\",\n \"isolatedModules\": true,\n \"noEmit\": true\n },\n \"include\": [\"./**/*\"],\n \"exclude\": [\"./_generated\"]\n}\n`],\n [\"backend/convex/packages/backend/convex/README.md\", `# Welcome to your Convex functions directory!\n\nWrite your Convex functions here.\nSee https://docs.convex.dev/functions for more.\n\nA query function that takes two arguments looks like:\n\n\\`\\`\\`ts\n// convex/myFunctions.ts\nimport { query } from \"./_generated/server\";\nimport { v } from \"convex/values\";\n\nexport const myQueryFunction = query({\n // Validators for arguments.\n args: {\n first: v.number(),\n second: v.string(),\n },\n\n // Function implementation.\n handler: async (ctx, args) => {\n // Read the database as many times as you need here.\n // See https://docs.convex.dev/database/reading-data.\n const documents = await ctx.db.query(\"tablename\").collect();\n\n // Arguments passed from the client are properties of the args object.\n console.log(args.first, args.second);\n\n // Write arbitrary JavaScript here: filter, aggregate, build derived data,\n // remove non-public properties, or create new objects.\n return documents;\n },\n});\n\\`\\`\\`\n\nUsing this query function in a React component looks like:\n\n\\`\\`\\`ts\nconst data = useQuery(api.myFunctions.myQueryFunction, {\n first: 10,\n second: \"hello\",\n});\n\\`\\`\\`\n\nA mutation function looks like:\n\n\\`\\`\\`ts\n// convex/myFunctions.ts\nimport { mutation } from \"./_generated/server\";\nimport { v } from \"convex/values\";\n\nexport const myMutationFunction = mutation({\n // Validators for arguments.\n args: {\n first: v.string(),\n second: v.string(),\n },\n\n // Function implementation.\n handler: async (ctx, args) => {\n // Insert or modify documents in the database here.\n // Mutations can also read from the database like queries.\n // See https://docs.convex.dev/database/writing-data.\n const message = { body: args.first, author: args.second };\n const id = await ctx.db.insert(\"messages\", message);\n\n // Optionally, return a value from your mutation.\n return await ctx.db.get(\"messages\", id);\n },\n});\n\\`\\`\\`\n\nUsing this mutation function in a React component looks like:\n\n\\`\\`\\`ts\nconst mutation = useMutation(api.myFunctions.myMutationFunction);\nfunction handleButtonPress() {\n // fire and forget, the most common way to use mutations\n mutation({ first: \"Hello!\", second: \"me\" });\n // OR\n // use the result once the mutation has completed\n mutation({ first: \"Hello!\", second: \"me\" }).then((result) =>\n console.log(result),\n );\n}\n\\`\\`\\`\n\nUse the Convex CLI to push your functions to a deployment. See everything\nthe Convex CLI can do by running \\`npx convex -h\\` in your project root\ndirectory. To learn more, launch the docs with \\`npx convex docs\\`.\n`],\n [\"addons/pwa/apps/web/vite/pwa-assets.config.ts.hbs\", `import {\n defineConfig,\n minimal2023Preset as preset,\n} from \"@vite-pwa/assets-generator/config\";\n\nexport default defineConfig({\n headLinkOptions: {\n preset: \"2023\",\n },\n preset,\n images: [\"public/logo.png\"],\n});\n`],\n [\"api/orpc/server/src/routers/index.ts.hbs\", `{{#if (eq api \"orpc\")}}\nimport { {{#if (eq auth \"better-auth\")}}protectedProcedure, {{/if}}publicProcedure } from \"../index\";\nimport type { RouterClient } from \"@orpc/server\";\n{{#if (includes examples \"todo\")}}\nimport { todoRouter } from \"./todo\";\n{{/if}}\n\nexport const appRouter = {\n healthCheck: publicProcedure.handler(() => {\n return \"OK\";\n }),\n {{#if (eq auth \"better-auth\")}}\n privateData: protectedProcedure.handler(({ context }) => {\n return {\n message: \"This is private\",\n user: context.session?.user,\n };\n }),\n {{/if}}\n {{#if (includes examples \"todo\")}}\n todo: todoRouter,\n {{/if}}\n};\nexport type AppRouter = typeof appRouter;\nexport type AppRouterClient = RouterClient<typeof appRouter>;\n{{else if (eq api \"trpc\")}}\nimport {\n {{#if (eq auth \"better-auth\")}}protectedProcedure, {{/if}}publicProcedure,\n router,\n} from \"../index\";\n{{#if (includes examples \"todo\")}}\nimport { todoRouter } from \"./todo\";\n{{/if}}\n\nexport const appRouter = router({\n healthCheck: publicProcedure.query(() => {\n return \"OK\";\n }),\n {{#if (eq auth \"better-auth\")}}\n privateData: protectedProcedure.query(({ ctx }) => {\n return {\n message: \"This is private\",\n user: ctx.session.user,\n };\n }),\n {{/if}}\n {{#if (includes examples \"todo\")}}\n todo: todoRouter,\n {{/if}}\n});\nexport type AppRouter = typeof appRouter;\n{{else}}\nexport const appRouter = {};\nexport type AppRouter = typeof appRouter;\n{{/if}}\n`],\n [\"cms/payload/web/next/src/payload.config.ts.hbs\", `import { buildConfig } from \"payload\";\nimport { lexicalEditor } from \"@payloadcms/richtext-lexical\";\n{{#if (eq database \"postgres\")}}\nimport { postgresAdapter } from \"@payloadcms/db-postgres\";\n{{else if (eq database \"mongodb\")}}\nimport { mongooseAdapter } from \"@payloadcms/db-mongodb\";\n{{else}}\nimport { sqliteAdapter } from \"@payloadcms/db-sqlite\";\n{{/if}}\n\nimport { Users } from \"./payload/collections/Users\";\nimport { Media } from \"./payload/collections/Media\";\nimport { Pages } from \"./payload/collections/Pages\";\n\nexport default buildConfig({\n // Rich text editor\n editor: lexicalEditor(),\n\n // Collections\n collections: [Users, Media, Pages],\n\n // Secret for encryption (should be a complex and secure string)\n secret: process.env.PAYLOAD_SECRET || \"\",\n\n // Database adapter\n{{#if (eq database \"postgres\")}}\n db: postgresAdapter({\n pool: {\n connectionString: process.env.DATABASE_URL || \"\",\n },\n }),\n{{else if (eq database \"mongodb\")}}\n db: mongooseAdapter({\n url: process.env.DATABASE_URL || \"\",\n }),\n{{else}}\n db: sqliteAdapter({\n client: {\n url: process.env.DATABASE_URL || \"file:./payload.db\",\n },\n }),\n{{/if}}\n\n // Admin panel configuration\n admin: {\n // Customize admin panel\n meta: {\n titleSuffix: \"- {{projectName}}\",\n },\n },\n\n // TypeScript configuration\n typescript: {\n outputFile: \"./src/payload-types.ts\",\n },\n});\n`],\n [\"payments/lemon-squeezy/web/nuxt/app/pages/success.vue.hbs\", `<script setup lang=\"ts\">\nconst route = useRoute();\nconst checkoutId = computed(() => route.query.checkout_id as string | undefined);\n</script>\n\n<template>\n\t<div class=\"container mx-auto px-4 py-8\">\n\t\t<h1 class=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t<p class=\"text-gray-600 mb-4\">\n\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t</p>\n\t\t<p v-if=\"checkoutId\" class=\"text-sm text-gray-500\">\n\t\t\tCheckout ID: {{ checkoutId }}\n\t\t</p>\n\t</div>\n</template>\n`],\n [\"payments/stripe/web/solid/src/routes/success.tsx.hbs\", `import { createFileRoute } from \"@tanstack/solid-router\";\nimport { Show } from \"solid-js\";\n\nexport const Route = createFileRoute(\"/success\")({\n\tcomponent: SuccessPage,\n\tvalidateSearch: (search) => ({\n\t\tsession_id: search.session_id as string,\n\t}),\n});\n\nfunction SuccessPage() {\n\tconst searchParams = Route.useSearch();\n\tconst session_id = searchParams().session_id;\n\n\treturn (\n\t\t<div class=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 class=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p class=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t<Show when={session_id}>\n\t\t\t\t<p class=\"text-sm text-gray-500\">Session ID: {session_id}</p>\n\t\t\t</Show>\n\t\t</div>\n\t);\n}\n`],\n [\"payments/paddle/web/solid/src/routes/success.tsx.hbs\", `import { useSearchParams } from \"@solidjs/router\";\n\nexport default function SuccessPage() {\n\tconst [searchParams] = useSearchParams();\n\tconst transactionId = () => searchParams.transaction_id;\n\n\treturn (\n\t\t<div class=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 class=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p class=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t{transactionId() && (\n\t\t\t\t<p class=\"text-sm text-gray-500\">Transaction ID: {transactionId()}</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n`],\n [\"api/trpc/server/src/routers/index.ts.hbs\", `{{#if (eq api \"orpc\")}}\nimport { {{#if (eq auth \"better-auth\")}}protectedProcedure, {{/if}}publicProcedure } from \"../index\";\nimport type { RouterClient } from \"@orpc/server\";\n{{#if (includes examples \"todo\")}}\nimport { todoRouter } from \"./todo\";\n{{/if}}\n\nexport const appRouter = {\n healthCheck: publicProcedure.handler(() => {\n return \"OK\";\n }),\n {{#if (eq auth \"better-auth\")}}\n privateData: protectedProcedure.handler(({ context }) => {\n return {\n message: \"This is private\",\n user: context.session?.user,\n };\n }),\n {{/if}}\n {{#if (includes examples \"todo\")}}\n todo: todoRouter,\n {{/if}}\n};\nexport type AppRouter = typeof appRouter;\nexport type AppRouterClient = RouterClient<typeof appRouter>;\n{{else if (eq api \"trpc\")}}\nimport {\n {{#if (eq auth \"better-auth\")}}protectedProcedure, {{/if}}publicProcedure,\n router,\n} from \"../index\";\n{{#if (includes examples \"todo\")}}\nimport { todoRouter } from \"./todo\";\n{{/if}}\n\nexport const appRouter = router({\n healthCheck: publicProcedure.query(() => {\n return \"OK\";\n }),\n {{#if (eq auth \"better-auth\")}}\n privateData: protectedProcedure.query(({ ctx }) => {\n return {\n message: \"This is private\",\n user: ctx.session.user,\n };\n }),\n {{/if}}\n {{#if (includes examples \"todo\")}}\n todo: todoRouter,\n {{/if}}\n});\nexport type AppRouter = typeof appRouter;\n{{else}}\nexport const appRouter = {};\nexport type AppRouter = typeof appRouter;\n{{/if}}\n`],\n [\"payments/stripe/server/base/src/lib/stripe.ts.hbs\", `import Stripe from \"stripe\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nexport const stripe = new Stripe(env.STRIPE_SECRET_KEY, {\n\tapiVersion: \"2024-12-18\",\n});\n\nexport async function createCheckoutSession(params: {\n\tpriceId: string;\n\tsuccessUrl: string;\n\tcancelUrl: string;\n\tcustomerId?: string;\n\tmetadata?: Record<string, string>;\n}) {\n\tconst session = await stripe.checkout.sessions.create({\n\t\tmode: \"payment\",\n\t\tpayment_method_types: [\"card\"],\n\t\tline_items: [\n\t\t\t{\n\t\t\t\tprice: params.priceId,\n\t\t\t\tquantity: 1,\n\t\t\t},\n\t\t],\n\t\tsuccess_url: params.successUrl,\n\t\tcancel_url: params.cancelUrl,\n\t\tcustomer: params.customerId,\n\t\tmetadata: params.metadata,\n\t});\n\n\treturn session;\n}\n\nexport async function createSubscriptionCheckout(params: {\n\tpriceId: string;\n\tsuccessUrl: string;\n\tcancelUrl: string;\n\tcustomerId?: string;\n\tmetadata?: Record<string, string>;\n}) {\n\tconst session = await stripe.checkout.sessions.create({\n\t\tmode: \"subscription\",\n\t\tpayment_method_types: [\"card\"],\n\t\tline_items: [\n\t\t\t{\n\t\t\t\tprice: params.priceId,\n\t\t\t\tquantity: 1,\n\t\t\t},\n\t\t],\n\t\tsuccess_url: params.successUrl,\n\t\tcancel_url: params.cancelUrl,\n\t\tcustomer: params.customerId,\n\t\tmetadata: params.metadata,\n\t});\n\n\treturn session;\n}\n\nexport async function constructWebhookEvent(\n\tpayload: string | Buffer,\n\tsignature: string,\n) {\n\treturn stripe.webhooks.constructEvent(\n\t\tpayload,\n\t\tsignature,\n\t\tenv.STRIPE_WEBHOOK_SECRET,\n\t);\n}\n`],\n [\"payments/lemon-squeezy/server/base/src/lib/lemonsqueezy.ts.hbs\", `import {\n\tlemonSqueezySetup,\n\tcreateCheckout,\n\tgetCheckout,\n\tlistProducts,\n\tgetProduct,\n\tlistVariants,\n\tgetVariant,\n\tlistSubscriptions,\n\tgetSubscription,\n\tcancelSubscription,\n\ttype Checkout,\n\ttype Product,\n\ttype Variant,\n\ttype Subscription,\n} from \"@lemonsqueezy/lemonsqueezy.js\";\nimport { env } from \"@{{projectName}}/env/server\";\n\n// Initialize Lemon Squeezy with your API key\nlemonSqueezySetup({\n\tapiKey: env.LEMONSQUEEZY_API_KEY,\n\tonError: (error) => console.error(\"Lemon Squeezy Error:\", error),\n});\n\nexport async function createCheckoutSession(params: {\n\tvariantId: number;\n\tcustomData?: Record<string, string | number | boolean>;\n\tcheckoutOptions?: {\n\t\tembed?: boolean;\n\t\tmedia?: boolean;\n\t\tlogo?: boolean;\n\t\tdesc?: boolean;\n\t\tdiscount?: boolean;\n\t\tdark?: boolean;\n\t\tsubscriptionPreview?: boolean;\n\t\tbuttonColor?: string;\n\t};\n\tproductOptions?: {\n\t\tname?: string;\n\t\tdescription?: string;\n\t\tredirectUrl?: string;\n\t\treceiptButtonText?: string;\n\t\treceiptLinkUrl?: string;\n\t\treceiptThankYouNote?: string;\n\t\tenabledVariants?: number[];\n\t};\n\tcheckoutData?: {\n\t\temail?: string;\n\t\tname?: string;\n\t\tbillingAddress?: {\n\t\t\tcountry: string;\n\t\t\tzip?: string;\n\t\t};\n\t\ttaxNumber?: string;\n\t\tdiscountCode?: string;\n\t};\n\texpiresAt?: string;\n\tpreview?: boolean;\n\ttestMode?: boolean;\n}) {\n\tconst { data, error } = await createCheckout(env.LEMONSQUEEZY_STORE_ID, params.variantId, {\n\t\tcustomData: params.customData,\n\t\tcheckoutOptions: params.checkoutOptions,\n\t\tproductOptions: params.productOptions,\n\t\tcheckoutData: params.checkoutData,\n\t\texpiresAt: params.expiresAt,\n\t\tpreview: params.preview,\n\t\ttestMode: params.testMode,\n\t});\n\n\tif (error) {\n\t\tthrow new Error(\\`Failed to create checkout: \\${error.message}\\`);\n\t}\n\n\treturn data;\n}\n\nexport async function getCheckoutById(checkoutId: string): Promise<Checkout | null> {\n\tconst { data, error } = await getCheckout(checkoutId);\n\n\tif (error) {\n\t\tthrow new Error(\\`Failed to get checkout: \\${error.message}\\`);\n\t}\n\n\treturn data;\n}\n\nexport async function getProducts(): Promise<Product[]> {\n\tconst { data, error } = await listProducts({\n\t\tfilter: { storeId: env.LEMONSQUEEZY_STORE_ID },\n\t});\n\n\tif (error) {\n\t\tthrow new Error(\\`Failed to list products: \\${error.message}\\`);\n\t}\n\n\treturn data?.data ?? [];\n}\n\nexport async function getProductById(productId: string): Promise<Product | null> {\n\tconst { data, error } = await getProduct(productId);\n\n\tif (error) {\n\t\tthrow new Error(\\`Failed to get product: \\${error.message}\\`);\n\t}\n\n\treturn data;\n}\n\nexport async function getVariants(productId?: string): Promise<Variant[]> {\n\tconst { data, error } = await listVariants({\n\t\tfilter: productId ? { productId } : undefined,\n\t});\n\n\tif (error) {\n\t\tthrow new Error(\\`Failed to list variants: \\${error.message}\\`);\n\t}\n\n\treturn data?.data ?? [];\n}\n\nexport async function getVariantById(variantId: string): Promise<Variant | null> {\n\tconst { data, error } = await getVariant(variantId);\n\n\tif (error) {\n\t\tthrow new Error(\\`Failed to get variant: \\${error.message}\\`);\n\t}\n\n\treturn data;\n}\n\nexport async function getUserSubscriptions(customerId?: string): Promise<Subscription[]> {\n\tconst { data, error } = await listSubscriptions({\n\t\tfilter: customerId ? { customerId } : undefined,\n\t});\n\n\tif (error) {\n\t\tthrow new Error(\\`Failed to list subscriptions: \\${error.message}\\`);\n\t}\n\n\treturn data?.data ?? [];\n}\n\nexport async function getSubscriptionById(subscriptionId: string): Promise<Subscription | null> {\n\tconst { data, error } = await getSubscription(subscriptionId);\n\n\tif (error) {\n\t\tthrow new Error(\\`Failed to get subscription: \\${error.message}\\`);\n\t}\n\n\treturn data;\n}\n\nexport async function cancelUserSubscription(subscriptionId: string): Promise<Subscription | null> {\n\tconst { data, error } = await cancelSubscription(subscriptionId);\n\n\tif (error) {\n\t\tthrow new Error(\\`Failed to cancel subscription: \\${error.message}\\`);\n\t}\n\n\treturn data;\n}\n\nexport function verifyWebhookSignature(\n\tpayload: string,\n\tsignature: string,\n): boolean {\n\t// Lemon Squeezy uses HMAC-SHA256 for webhook signatures\n\tconst crypto = require(\"crypto\");\n\tconst hmac = crypto.createHmac(\"sha256\", env.LEMONSQUEEZY_WEBHOOK_SECRET);\n\tconst digest = hmac.update(payload).digest(\"hex\");\n\treturn crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest));\n}\n\nexport type WebhookEvent =\n\t| \"order_created\"\n\t| \"order_refunded\"\n\t| \"subscription_created\"\n\t| \"subscription_updated\"\n\t| \"subscription_cancelled\"\n\t| \"subscription_resumed\"\n\t| \"subscription_expired\"\n\t| \"subscription_paused\"\n\t| \"subscription_unpaused\"\n\t| \"subscription_payment_success\"\n\t| \"subscription_payment_failed\"\n\t| \"subscription_payment_recovered\"\n\t| \"license_key_created\"\n\t| \"license_key_updated\";\n\nexport interface WebhookPayload {\n\tmeta: {\n\t\tevent_name: WebhookEvent;\n\t\tcustom_data?: Record<string, string | number | boolean>;\n\t\twebhook_id: string;\n\t};\n\tdata: {\n\t\ttype: string;\n\t\tid: string;\n\t\tattributes: Record<string, unknown>;\n\t\trelationships?: Record<string, unknown>;\n\t};\n}\n`],\n [\"payments/stripe/web/nuxt/app/pages/success.vue.hbs\", `<script setup lang=\"ts\">\nconst route = useRoute()\nconst session_id = route.query.session_id as string\n</script>\n\n<template>\n <div class=\"container mx-auto px-4 py-8\">\n <h1 class=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n <p class=\"text-gray-600 mb-4\">\n Thank you for your purchase. Your payment has been processed successfully.\n </p>\n <p v-if=\"session_id\" class=\"text-sm text-gray-500\">\n Session ID: \\\\{{ session_id }}\n </p>\n </div>\n</template>\n`],\n [\"payments/paddle/web/nuxt/app/pages/success.vue.hbs\", `<script setup lang=\"ts\">\nconst route = useRoute();\nconst transactionId = route.query.transaction_id as string | undefined;\n</script>\n\n<template>\n\t<div class=\"container mx-auto px-4 py-8\">\n\t\t<h1 class=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t<p class=\"text-gray-600 mb-4\">\n\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t</p>\n\t\t<p v-if=\"transactionId\" class=\"text-sm text-gray-500\">\n\t\t\tTransaction ID: {{ transactionId }}\n\t\t</p>\n\t</div>\n</template>\n`],\n [\"backend/server/nitro/routes/api-reference/[...path].ts.hbs\", `{{#if (eq api \"orpc\")}}\nimport { OpenAPIHandler } from \"@orpc/openapi/node\";\nimport { OpenAPIReferencePlugin } from \"@orpc/openapi/plugins\";\nimport { ZodToJsonSchemaConverter } from \"@orpc/zod/zod4\";\nimport { onError } from \"@orpc/server\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\n{{#if (eq auth \"better-auth\")}}\nimport { createContext } from \"@{{projectName}}/api/context\";\n{{/if}}\n\nconst apiHandler = new OpenAPIHandler(appRouter, {\n\tplugins: [\n\t\tnew OpenAPIReferencePlugin({\n\t\t\tschemaConverters: [new ZodToJsonSchemaConverter()],\n\t\t}),\n\t],\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\n\nexport default defineEventHandler(async (event) => {\n\tconst { req, res } = event.node;\n\tconst result = await apiHandler.handle(req, res, {\n\t\tprefix: \"/api-reference\",\n{{#if (eq auth \"better-auth\")}}\n\t\tcontext: await createContext({ req }),\n{{else}}\n\t\tcontext: {},\n{{/if}}\n\t});\n\tif (!result.matched) {\n\t\tsetResponseStatus(event, 404);\n\t\treturn \"Not Found\";\n\t}\n});\n{{else}}\n// OpenAPI reference placeholder - oRPC not configured\nexport default defineEventHandler(() => {\n\treturn { error: \"OpenAPI reference not configured\" };\n});\n{{/if}}\n`],\n [\"backend/server/nitro/routes/trpc/[...path].ts.hbs\", `{{#if (eq api \"trpc\")}}\nimport { fetchRequestHandler } from \"@trpc/server/adapters/fetch\";\nimport { createContext } from \"@{{projectName}}/api/context\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\n\nexport default defineEventHandler(async (event) => {\n\tconst response = await fetchRequestHandler({\n\t\tendpoint: \"/trpc\",\n\t\treq: event.node.req as unknown as Request,\n\t\trouter: appRouter,\n\t\tcreateContext: ({ req }) => createContext({ req }),\n\t});\n\treturn response;\n});\n{{else}}\n// tRPC placeholder - not configured\nexport default defineEventHandler(() => {\n\treturn { error: \"tRPC not configured\" };\n});\n{{/if}}\n`],\n [\"backend/server/nitro/routes/rpc/[...path].ts.hbs\", `{{#if (eq api \"orpc\")}}\nimport { RPCHandler } from \"@orpc/server/node\";\nimport { onError } from \"@orpc/server\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\n{{#if (eq auth \"better-auth\")}}\nimport { createContext } from \"@{{projectName}}/api/context\";\n{{/if}}\n\nconst rpcHandler = new RPCHandler(appRouter, {\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\n\nexport default defineEventHandler(async (event) => {\n\tconst { req, res } = event.node;\n\tconst result = await rpcHandler.handle(req, res, {\n\t\tprefix: \"/rpc\",\n{{#if (eq auth \"better-auth\")}}\n\t\tcontext: await createContext({ req }),\n{{else}}\n\t\tcontext: {},\n{{/if}}\n\t});\n\tif (!result.matched) {\n\t\tsetResponseStatus(event, 404);\n\t\treturn \"Not Found\";\n\t}\n});\n{{else}}\n// oRPC placeholder - not configured\nexport default defineEventHandler(() => {\n\treturn { error: \"oRPC not configured\" };\n});\n{{/if}}\n`],\n [\"payments/polar/web/nuxt/app/pages/success.vue.hbs\", `<script setup lang=\"ts\">\nconst route = useRoute()\nconst checkout_id = route.query.checkout_id as string\n</script>\n\n<template>\n <div class=\"container mx-auto px-4 py-8\">\n <h1 class=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n <p v-if=\"checkout_id\">Checkout ID: \\\\{{ checkout_id }}</p>\n </div>\n</template>\n`],\n [\"payments/paddle/server/base/src/lib/paddle.ts.hbs\", `import {\n\tPaddle,\n\tEnvironment,\n\ttype Product,\n\ttype Price,\n\ttype Subscription,\n\ttype Customer,\n\ttype Transaction,\n\ttype EventEntity,\n} from \"@paddle/paddle-node-sdk\";\nimport { env } from \"@{{projectName}}/env/server\";\n\n// Initialize Paddle with your API key\nconst paddle = new Paddle(env.PADDLE_API_KEY, {\n\tenvironment: env.PADDLE_ENVIRONMENT === \"production\" ? Environment.production : Environment.sandbox,\n});\n\nexport { paddle };\n\n// Products\nexport async function listProducts(): Promise<Product[]> {\n\tconst products: Product[] = [];\n\tconst productCollection = paddle.products.list();\n\n\tfor await (const product of productCollection) {\n\t\tproducts.push(product);\n\t}\n\n\treturn products;\n}\n\nexport async function getProduct(productId: string): Promise<Product> {\n\treturn paddle.products.get(productId);\n}\n\n// Prices\nexport async function listPrices(productId?: string): Promise<Price[]> {\n\tconst prices: Price[] = [];\n\tconst priceCollection = paddle.prices.list(productId ? { productId: [productId] } : undefined);\n\n\tfor await (const price of priceCollection) {\n\t\tprices.push(price);\n\t}\n\n\treturn prices;\n}\n\nexport async function getPrice(priceId: string): Promise<Price> {\n\treturn paddle.prices.get(priceId);\n}\n\n// Customers\nexport async function listCustomers(email?: string): Promise<Customer[]> {\n\tconst customers: Customer[] = [];\n\tconst customerCollection = paddle.customers.list(email ? { email: [email] } : undefined);\n\n\tfor await (const customer of customerCollection) {\n\t\tcustomers.push(customer);\n\t}\n\n\treturn customers;\n}\n\nexport async function getCustomer(customerId: string): Promise<Customer> {\n\treturn paddle.customers.get(customerId);\n}\n\nexport async function createCustomer(params: {\n\temail: string;\n\tname?: string;\n\tlocale?: string;\n}): Promise<Customer> {\n\treturn paddle.customers.create(params);\n}\n\n// Subscriptions\nexport async function listSubscriptions(customerId?: string): Promise<Subscription[]> {\n\tconst subscriptions: Subscription[] = [];\n\tconst subscriptionCollection = paddle.subscriptions.list(\n\t\tcustomerId ? { customerId: [customerId] } : undefined\n\t);\n\n\tfor await (const subscription of subscriptionCollection) {\n\t\tsubscriptions.push(subscription);\n\t}\n\n\treturn subscriptions;\n}\n\nexport async function getSubscription(subscriptionId: string): Promise<Subscription> {\n\treturn paddle.subscriptions.get(subscriptionId);\n}\n\nexport async function cancelSubscription(\n\tsubscriptionId: string,\n\teffectiveFrom?: \"immediately\" | \"next_billing_period\"\n): Promise<Subscription> {\n\treturn paddle.subscriptions.cancel(subscriptionId, {\n\t\teffectiveFrom: effectiveFrom ?? \"next_billing_period\",\n\t});\n}\n\nexport async function pauseSubscription(subscriptionId: string): Promise<Subscription> {\n\treturn paddle.subscriptions.pause(subscriptionId, {});\n}\n\nexport async function resumeSubscription(subscriptionId: string): Promise<Subscription> {\n\treturn paddle.subscriptions.resume(subscriptionId, {\n\t\teffectiveFrom: \"immediately\",\n\t});\n}\n\n// Transactions\nexport async function listTransactions(customerId?: string): Promise<Transaction[]> {\n\tconst transactions: Transaction[] = [];\n\tconst transactionCollection = paddle.transactions.list(\n\t\tcustomerId ? { customerId: [customerId] } : undefined\n\t);\n\n\tfor await (const transaction of transactionCollection) {\n\t\ttransactions.push(transaction);\n\t}\n\n\treturn transactions;\n}\n\nexport async function getTransaction(transactionId: string): Promise<Transaction> {\n\treturn paddle.transactions.get(transactionId);\n}\n\n// Webhook verification\nexport function verifyWebhookSignature(\n\trequestBody: string,\n\tsignature: string\n): EventEntity | null {\n\ttry {\n\t\t// Paddle SDK handles webhook verification internally\n\t\tconst event = paddle.webhooks.unmarshal(requestBody, env.PADDLE_WEBHOOK_SECRET, signature);\n\t\treturn event;\n\t} catch (error) {\n\t\tconsole.error(\"Webhook verification failed:\", error);\n\t\treturn null;\n\t}\n}\n\n// Webhook event types\nexport type WebhookEventType =\n\t| \"transaction.billed\"\n\t| \"transaction.canceled\"\n\t| \"transaction.completed\"\n\t| \"transaction.created\"\n\t| \"transaction.paid\"\n\t| \"transaction.past_due\"\n\t| \"transaction.payment_failed\"\n\t| \"transaction.ready\"\n\t| \"transaction.updated\"\n\t| \"subscription.activated\"\n\t| \"subscription.canceled\"\n\t| \"subscription.created\"\n\t| \"subscription.imported\"\n\t| \"subscription.past_due\"\n\t| \"subscription.paused\"\n\t| \"subscription.resumed\"\n\t| \"subscription.trialing\"\n\t| \"subscription.updated\"\n\t| \"customer.created\"\n\t| \"customer.imported\"\n\t| \"customer.updated\"\n\t| \"product.created\"\n\t| \"product.imported\"\n\t| \"product.updated\"\n\t| \"price.created\"\n\t| \"price.imported\"\n\t| \"price.updated\";\n`],\n [\"payments/polar/web/solid/src/routes/success.tsx.hbs\", `import { createFileRoute } from \"@tanstack/solid-router\";\nimport { Show } from \"solid-js\";\n\nexport const Route = createFileRoute(\"/success\")({\n\tcomponent: SuccessPage,\n\tvalidateSearch: (search) => ({\n\t\tcheckout_id: search.checkout_id as string,\n\t}),\n});\n\nfunction SuccessPage() {\n\tconst searchParams = Route.useSearch();\n\tconst checkout_id = searchParams().checkout_id;\n\n\treturn (\n\t\t<div class=\"container mx-auto px-4 py-8\">\n\t\t\t<h1>Payment Successful!</h1>\n\t\t\t<Show when={checkout_id}>\n\t\t\t\t<p>Checkout ID: {checkout_id}</p>\n\t\t\t</Show>\n\t\t</div>\n\t);\n}\n`],\n [\"payments/polar/server/base/src/lib/payments.ts.hbs\", `import { Polar } from \"@polar-sh/sdk\";\nimport { env } from \"@{{projectName}}/env/server\";\n\nexport const polarClient = new Polar({\n\taccessToken: env.POLAR_ACCESS_TOKEN,\n\tserver: \"sandbox\",\n});\n`],\n [\"job-queue/trigger-dev/server/base/src/lib/trigger.ts.hbs\", `import { tasks, configure } from \"@trigger.dev/sdk/v3\";\nimport type {\n sendEmailTask,\n sendNotificationTask,\n processDataTask,\n} from \"../trigger/tasks\";\n\n/**\n * Configure Trigger.dev SDK\n * This is called automatically when importing this module\n * @see https://trigger.dev/docs\n */\nconfigure({\n secretKey: process.env.TRIGGER_SECRET_KEY,\n});\n\n/**\n * Type-safe task triggering utilities\n * Use these functions to trigger background tasks from your backend\n */\n\n// Type definitions for task payloads\nexport interface EmailPayload {\n to: string;\n subject: string;\n body: string;\n templateId?: string;\n}\n\nexport interface NotificationPayload {\n userId: string;\n type: \"push\" | \"in-app\" | \"sms\";\n title: string;\n message: string;\n data?: Record<string, unknown>;\n}\n\nexport interface DataProcessingPayload {\n dataId: string;\n operation: \"transform\" | \"aggregate\" | \"export\";\n}\n\n/**\n * Trigger an email task\n * @example\n * const handle = await triggerEmail({\n * to: \"user@example.com\",\n * subject: \"Welcome!\",\n * body: \"Thanks for signing up.\"\n * });\n */\nexport async function triggerEmail(\n payload: EmailPayload,\n options?: { delay?: string | number }\n) {\n return tasks.trigger<typeof sendEmailTask>(\"send-email\", payload, options);\n}\n\n/**\n * Trigger a notification task\n * @example\n * const handle = await triggerNotification({\n * userId: \"user_123\",\n * type: \"push\",\n * title: \"New message\",\n * message: \"You have a new message!\"\n * });\n */\nexport async function triggerNotification(\n payload: NotificationPayload,\n options?: { delay?: string | number }\n) {\n return tasks.trigger<typeof sendNotificationTask>(\n \"send-notification\",\n payload,\n options\n );\n}\n\n/**\n * Trigger a data processing task\n * @example\n * const handle = await triggerDataProcessing({\n * dataId: \"data_456\",\n * operation: \"transform\"\n * });\n */\nexport async function triggerDataProcessing(\n payload: DataProcessingPayload,\n options?: { delay?: string | number }\n) {\n return tasks.trigger<typeof processDataTask>(\n \"process-data\",\n payload,\n options\n );\n}\n\n/**\n * Trigger multiple emails in batch\n * @example\n * const handles = await triggerEmailBatch([\n * { to: \"user1@example.com\", subject: \"Hello\", body: \"Hi!\" },\n * { to: \"user2@example.com\", subject: \"Hello\", body: \"Hi!\" }\n * ]);\n */\nexport async function triggerEmailBatch(payloads: EmailPayload[]) {\n return tasks.batchTrigger<typeof sendEmailTask>(\n \"send-email\",\n payloads.map((payload) => ({ payload }))\n );\n}\n\n/**\n * Get the status of a task run\n * @example\n * const run = await getTaskRun(\"run_123\");\n * console.log(run.status); // \"COMPLETED\" | \"FAILED\" | \"RUNNING\" etc.\n */\nexport { tasks };\n`],\n [\"job-queue/trigger-dev/server/base/src/trigger/tasks.ts.hbs\", `import { task, logger, schedules, AbortTaskRunError } from \"@trigger.dev/sdk/v3\";\n\n/**\n * Example email sending task\n * Trigger from your backend with: await sendEmailTask.trigger({ to, subject, body })\n * @see https://trigger.dev/docs\n */\nexport const sendEmailTask = task({\n id: \"send-email\",\n // Retry configuration\n retry: {\n maxAttempts: 3,\n minTimeoutInMs: 1000,\n maxTimeoutInMs: 10000,\n factor: 2,\n },\n run: async (payload: {\n to: string;\n subject: string;\n body: string;\n templateId?: string;\n }) => {\n const { to, subject, body, templateId } = payload;\n\n logger.info(\"Processing email task\", { to, subject });\n\n // TODO: Implement your email sending logic here\n // Example with a hypothetical email service:\n // await emailService.send({ to, subject, body, templateId });\n\n // Simulate email sending\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n logger.info(\"Email sent successfully\", { to });\n\n return {\n sent: true,\n to,\n timestamp: new Date().toISOString(),\n };\n },\n});\n\n/**\n * Example notification task\n * Supports different notification types: push, in-app, sms\n */\nexport const sendNotificationTask = task({\n id: \"send-notification\",\n retry: {\n maxAttempts: 3,\n minTimeoutInMs: 500,\n maxTimeoutInMs: 5000,\n factor: 2,\n },\n run: async (payload: {\n userId: string;\n type: \"push\" | \"in-app\" | \"sms\";\n title: string;\n message: string;\n data?: Record<string, unknown>;\n }) => {\n const { userId, type, title, message, data } = payload;\n\n logger.info(\"Processing notification\", { userId, type, title });\n\n // TODO: Implement your notification logic here\n // switch (type) {\n // case \"push\":\n // await pushService.send(userId, { title, message, data });\n // break;\n // case \"in-app\":\n // await inAppNotificationService.create(userId, { title, message, data });\n // break;\n // case \"sms\":\n // await smsService.send(userId, message);\n // break;\n // }\n\n // Simulate notification processing\n await new Promise((resolve) => setTimeout(resolve, 500));\n\n logger.info(\"Notification sent\", { userId, type });\n\n return {\n sent: true,\n type,\n userId,\n timestamp: new Date().toISOString(),\n };\n },\n});\n\n/**\n * Example data processing task with error handling\n * Demonstrates AbortTaskRunError for permanent failures\n */\nexport const processDataTask = task({\n id: \"process-data\",\n // Machine resources (uncomment for larger workloads)\n // machine: { preset: \"medium-1x\" }, // 1 vCPU, 2 GB RAM\n maxDuration: 300, // 5 minutes timeout\n retry: {\n maxAttempts: 2,\n },\n run: async (payload: {\n dataId: string;\n operation: \"transform\" | \"aggregate\" | \"export\";\n }) => {\n const { dataId, operation } = payload;\n\n logger.info(\"Processing data\", { dataId, operation });\n\n // Example of handling permanent errors\n if (!dataId) {\n // This is a known permanent error, don't retry\n throw new AbortTaskRunError(\"Data ID is required\");\n }\n\n // TODO: Implement your data processing logic here\n // const data = await database.getData(dataId);\n // switch (operation) {\n // case \"transform\":\n // return await transformData(data);\n // case \"aggregate\":\n // return await aggregateData(data);\n // case \"export\":\n // return await exportData(data);\n // }\n\n // Simulate data processing\n await new Promise((resolve) => setTimeout(resolve, 2000));\n\n logger.info(\"Data processing complete\", { dataId, operation });\n\n return {\n processed: true,\n dataId,\n operation,\n timestamp: new Date().toISOString(),\n };\n },\n});\n\n/**\n * Example scheduled task (cron job)\n * Runs every hour - customize the cron pattern as needed\n * @see https://trigger.dev/docs/tasks/scheduled\n */\nexport const hourlyCleanupTask = schedules.task({\n id: \"hourly-cleanup\",\n // Every hour at minute 0\n cron: \"0 * * * *\",\n run: async (payload) => {\n logger.info(\"Running scheduled cleanup\", {\n scheduledTime: payload.timestamp,\n timezone: payload.timezone,\n });\n\n // TODO: Implement your cleanup logic here\n // await database.deleteExpiredSessions();\n // await cache.clearStale();\n\n // Simulate cleanup\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n logger.info(\"Scheduled cleanup complete\", {\n nextRun: payload.upcoming[0],\n });\n\n return {\n cleaned: true,\n timestamp: new Date().toISOString(),\n };\n },\n});\n\n/**\n * Example daily report task with timezone\n * Runs at 9 AM in the specified timezone\n */\nexport const dailyReportTask = schedules.task({\n id: \"daily-report\",\n cron: {\n // 9 AM every day\n pattern: \"0 9 * * *\",\n // Change to your preferred timezone\n // See: https://cloud.trigger.dev/timezones\n timezone: \"UTC\",\n },\n run: async (payload) => {\n logger.info(\"Generating daily report\", {\n scheduledTime: payload.timestamp,\n timezone: payload.timezone,\n });\n\n // TODO: Implement your report generation logic here\n // const report = await generateReport();\n // await sendReportEmail(report);\n\n // Simulate report generation\n await new Promise((resolve) => setTimeout(resolve, 3000));\n\n logger.info(\"Daily report sent\", {\n nextRun: payload.upcoming[0],\n });\n\n return {\n reportGenerated: true,\n timestamp: new Date().toISOString(),\n };\n },\n});\n`],\n [\"auth/clerk/convex/native/base/components/sign-out-button.tsx.hbs\", `import { useClerk } from \"@clerk/clerk-expo\";\nimport { useRouter } from \"expo-router\";\nimport { Text, TouchableOpacity } from \"react-native\";\n\nexport const SignOutButton = () => {\n // Use \\`useClerk()\\` to access the \\`signOut()\\` function\n const { signOut } = useClerk();\n const router = useRouter();\n\n const handleSignOut = async () => {\n try {\n await signOut();\n // Redirect to your desired page\n router.replace(\"/\");\n } catch (err) {\n // See https://clerk.com/docs/custom-flows/error-handling\n // for more info on error handling\n console.error(JSON.stringify(err, null, 2));\n }\n };\n\n return (\n <TouchableOpacity onPress={handleSignOut}>\n <Text>Sign out</Text>\n </TouchableOpacity>\n );\n};\n`],\n [\"auth/better-auth/web/nuxt/app/pages/login.vue.hbs\", `<script setup lang=\"ts\">\nconst { $authClient } = useNuxtApp();\nimport SignInForm from \"~/components/SignInForm.vue\";\nimport SignUpForm from \"~/components/SignUpForm.vue\";\n\nconst session = $authClient.useSession();\nconst showSignIn = ref(true);\n\nwatchEffect(() => {\n if (!session?.value.isPending && session?.value.data) {\n navigateTo(\"/dashboard\", { replace: true });\n }\n});\n</script>\n\n<template>\n <UContainer class=\"py-8\">\n <div v-if=\"session.isPending\" class=\"flex flex-col items-center justify-center gap-4 py-12\">\n <UIcon name=\"i-lucide-loader-2\" class=\"animate-spin text-4xl text-primary\" />\n <span class=\"text-muted\">Loading...</span>\n </div>\n <div v-else-if=\"!session.data\">\n <SignInForm v-if=\"showSignIn\" @switch-to-sign-up=\"showSignIn = false\" />\n <SignUpForm v-else @switch-to-sign-in=\"showSignIn = true\" />\n </div>\n </UContainer>\n</template>\n`],\n [\"auth/better-auth/web/nuxt/app/pages/dashboard.vue.hbs\", `<script setup lang=\"ts\">\n{{#if (eq api \"orpc\")}}\nimport { useQuery } from '@tanstack/vue-query'\n{{/if}}\n\nconst { $authClient, $orpc } = useNuxtApp()\n\ndefinePageMeta({\n middleware: ['auth']\n})\n\nconst session = $authClient.useSession()\n\n{{#if (eq payments \"polar\")}}\nconst customerState = ref<any>(null)\n{{/if}}\n\n{{#if (eq api \"orpc\")}}\nconst privateData = useQuery({\n ...$orpc.privateData.queryOptions(),\n enabled: computed(() => !!session.value?.data?.user)\n})\n{{/if}}\n\n{{#if (eq payments \"polar\")}}\nonMounted(async () => {\n if (session.value?.data) {\n const { data } = await $authClient.customer.state()\n customerState.value = data\n }\n})\n\nconst hasProSubscription = computed(() => \n customerState.value?.activeSubscriptions?.length! > 0\n)\n{{/if}}\n</script>\n\n<template>\n <UContainer class=\"py-8\">\n <UPageHeader\n title=\"Dashboard\"\n :description=\"session?.data?.user ? \\`Welcome back, \\${session.data.user.name}!\\` : 'Loading...'\"\n />\n\n <div class=\"mt-6 space-y-4\">\n {{#if (eq api \"orpc\")}}\n <UCard>\n <template #header>\n <div class=\"font-medium\">Private Data</div>\n </template>\n\n <USkeleton v-if=\"privateData.status.value === 'pending'\" class=\"h-6 w-48\" />\n\n <UAlert\n v-else-if=\"privateData.status.value === 'error'\"\n color=\"error\"\n icon=\"i-lucide-alert-circle\"\n title=\"Error loading data\"\n :description=\"privateData.error.value?.message || 'Failed to load private data'\"\n />\n\n <div v-else-if=\"privateData.data.value\" class=\"flex items-center gap-2\">\n <UIcon name=\"i-lucide-check-circle\" class=\"text-success\" />\n <span>\\\\{{ privateData.data.value.message }}</span>\n </div>\n </UCard>\n {{/if}}\n\n {{#if (eq payments \"polar\")}}\n <UCard>\n <template #header>\n <div class=\"font-medium\">Subscription</div>\n </template>\n\n <div class=\"flex items-center justify-between\">\n <div class=\"flex items-center gap-2\">\n <UIcon :name=\"hasProSubscription ? 'i-lucide-crown' : 'i-lucide-user'\" :class=\"hasProSubscription ? 'text-warning' : 'text-muted'\" />\n <span>Plan: \\\\{{ hasProSubscription ? \"Pro\" : \"Free\" }}</span>\n </div>\n <UButton \n v-if=\"hasProSubscription\"\n variant=\"outline\"\n @click=\"() => { $authClient.customer.portal() }\"\n >\n Manage Subscription\n </UButton>\n <UButton \n v-else\n @click=\"() => { $authClient.checkout({ slug: 'pro' }) }\"\n >\n Upgrade to Pro\n </UButton>\n </div>\n </UCard>\n {{/if}}\n </div>\n </UContainer>\n</template>\n`],\n [\"job-queue/bullmq/server/base/src/lib/queue.ts.hbs\", `import { Queue, Worker, type Job, type ConnectionOptions } from \"bullmq\";\nimport IORedis from \"ioredis\";\n\n// Redis connection configuration\n// For production, use environment variables to configure the connection\nconst redisConnection: ConnectionOptions = {\n host: process.env.REDIS_HOST || \"localhost\",\n port: Number(process.env.REDIS_PORT) || 6379,\n password: process.env.REDIS_PASSWORD || undefined,\n maxRetriesPerRequest: null, // Required for BullMQ\n};\n\n// Create a shared Redis connection for all queues\nconst connection = new IORedis(redisConnection);\n\n// Export connection for reuse\nexport { connection };\n\n/**\n * Example queue for background job processing\n * @see https://docs.bullmq.io/\n */\nexport const emailQueue = new Queue(\"email\", { connection });\nexport const notificationQueue = new Queue(\"notification\", { connection });\n\n// Define job data types\nexport interface EmailJobData {\n to: string;\n subject: string;\n body: string;\n templateId?: string;\n}\n\nexport interface NotificationJobData {\n userId: string;\n type: \"push\" | \"in-app\" | \"sms\";\n title: string;\n message: string;\n data?: Record<string, unknown>;\n}\n\n/**\n * Add an email job to the queue\n */\nexport async function queueEmail(data: EmailJobData, options?: { delay?: number; priority?: number }) {\n return emailQueue.add(\"send-email\", data, {\n delay: options?.delay,\n priority: options?.priority,\n attempts: 3,\n backoff: {\n type: \"exponential\",\n delay: 1000,\n },\n });\n}\n\n/**\n * Add a notification job to the queue\n */\nexport async function queueNotification(data: NotificationJobData, options?: { delay?: number }) {\n return notificationQueue.add(\"send-notification\", data, {\n delay: options?.delay,\n attempts: 3,\n backoff: {\n type: \"exponential\",\n delay: 1000,\n },\n });\n}\n\n/**\n * Schedule a recurring job (cron-style)\n * @example scheduleRecurringJob(emailQueue, \"daily-report\", { type: \"report\" }, \"0 9 * * *\")\n */\nexport async function scheduleRecurringJob<T>(\n queue: Queue,\n name: string,\n data: T,\n pattern: string, // Cron pattern\n) {\n return queue.upsertJobScheduler(\n name,\n { pattern },\n { name, data: data as object },\n );\n}\n\n/**\n * Get queue statistics\n */\nexport async function getQueueStats(queue: Queue) {\n const [waiting, active, completed, failed, delayed] = await Promise.all([\n queue.getWaitingCount(),\n queue.getActiveCount(),\n queue.getCompletedCount(),\n queue.getFailedCount(),\n queue.getDelayedCount(),\n ]);\n\n return { waiting, active, completed, failed, delayed };\n}\n\n/**\n * Gracefully close all queues and connections\n * Call this during application shutdown\n */\nexport async function closeQueues() {\n await emailQueue.close();\n await notificationQueue.close();\n await connection.quit();\n}\n`],\n [\"job-queue/bullmq/server/base/src/lib/workers.ts.hbs\", `import { Worker, type Job } from \"bullmq\";\nimport { connection, type EmailJobData, type NotificationJobData } from \"./queue\";\n\n/**\n * Email worker - processes email sending jobs\n * @see https://docs.bullmq.io/guide/workers\n */\nexport const emailWorker = new Worker<EmailJobData>(\n \"email\",\n async (job: Job<EmailJobData>) => {\n const { to, subject, body, templateId } = job.data;\n\n console.log(\\`Processing email job \\${job.id}: sending to \\${to}\\`);\n\n // TODO: Implement your email sending logic here\n // Example with a hypothetical email service:\n // await emailService.send({ to, subject, body, templateId });\n\n // Simulate email sending\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n console.log(\\`Email job \\${job.id} completed: sent to \\${to}\\`);\n\n return { sent: true, to, timestamp: new Date().toISOString() };\n },\n {\n connection,\n concurrency: 5, // Process up to 5 jobs in parallel\n limiter: {\n max: 100, // Max 100 jobs\n duration: 60000, // Per minute (rate limiting)\n },\n },\n);\n\n/**\n * Notification worker - processes notification jobs\n */\nexport const notificationWorker = new Worker<NotificationJobData>(\n \"notification\",\n async (job: Job<NotificationJobData>) => {\n const { userId, type, title, message, data } = job.data;\n\n console.log(\\`Processing notification job \\${job.id}: \\${type} to user \\${userId}\\`);\n\n // TODO: Implement your notification logic here\n // Example:\n // switch (type) {\n // case \"push\":\n // await pushService.send(userId, { title, message, data });\n // break;\n // case \"in-app\":\n // await inAppNotificationService.create(userId, { title, message, data });\n // break;\n // case \"sms\":\n // await smsService.send(userId, message);\n // break;\n // }\n\n // Simulate notification processing\n await new Promise((resolve) => setTimeout(resolve, 500));\n\n console.log(\\`Notification job \\${job.id} completed\\`);\n\n return { sent: true, type, userId, timestamp: new Date().toISOString() };\n },\n {\n connection,\n concurrency: 10,\n },\n);\n\n// Event handlers for monitoring\nemailWorker.on(\"completed\", (job) => {\n console.log(\\`Email job \\${job.id} has completed\\`);\n});\n\nemailWorker.on(\"failed\", (job, err) => {\n console.error(\\`Email job \\${job?.id} has failed with error: \\${err.message}\\`);\n});\n\nnotificationWorker.on(\"completed\", (job) => {\n console.log(\\`Notification job \\${job.id} has completed\\`);\n});\n\nnotificationWorker.on(\"failed\", (job, err) => {\n console.error(\\`Notification job \\${job?.id} has failed with error: \\${err.message}\\`);\n});\n\n/**\n * Gracefully close all workers\n * Call this during application shutdown\n */\nexport async function closeWorkers() {\n await emailWorker.close();\n await notificationWorker.close();\n}\n\n/**\n * Start all workers\n * Workers start automatically when created, but this function can be used\n * to ensure they're running or to restart after being paused\n */\nexport function startWorkers() {\n // Workers are already running by default\n // This function is here for explicit control if needed\n console.log(\"BullMQ workers started\");\n console.log(\"- Email worker: processing 'email' queue\");\n console.log(\"- Notification worker: processing 'notification' queue\");\n}\n`],\n [\"auth/better-auth/web/nuxt/app/components/SignInForm.vue.hbs\", `<script setup lang=\"ts\">\nimport * as z from 'zod'\nimport type { FormSubmitEvent, AuthFormField } from '@nuxt/ui'\n\nconst { $authClient } = useNuxtApp()\n\nconst emit = defineEmits(['switchToSignUp'])\n\nconst toast = useToast()\nconst loading = ref(false)\n\nconst fields: AuthFormField[] = [\n {\n name: 'email',\n type: 'email',\n label: 'Email',\n placeholder: 'Enter your email',\n required: true\n },\n {\n name: 'password',\n type: 'password',\n label: 'Password',\n placeholder: 'Enter your password',\n required: true\n }\n]\n\nconst schema = z.object({\n email: z.email('Invalid email address'),\n password: z.string().min(8, 'Password must be at least 8 characters'),\n})\n\ntype Schema = z.output<typeof schema>\n\nasync function onSubmit(event: FormSubmitEvent<Schema>) {\n loading.value = true\n try {\n await $authClient.signIn.email(\n {\n email: event.data.email,\n password: event.data.password,\n },\n {\n onSuccess: () => {\n toast.add({ title: 'Sign in successful' })\n navigateTo('/dashboard', { replace: true })\n },\n onError: (error) => {\n toast.add({ title: 'Sign in failed', description: error.error.message })\n },\n },\n )\n } catch (error: any) {\n toast.add({ title: 'An unexpected error occurred', description: error.message || 'Please try again.' })\n } finally {\n loading.value = false\n }\n}\n</script>\n\n<template>\n <div class=\"flex flex-col items-center justify-center gap-4 p-4\">\n <UPageCard class=\"w-full max-w-md\">\n <UAuthForm\n :schema=\"schema\"\n :fields=\"fields\"\n title=\"Welcome Back\"\n icon=\"i-lucide-log-in\"\n :submit=\"{ label: 'Sign In', loading }\"\n @submit=\"onSubmit\"\n >\n <template #description>\n Need an account?\n <ULink class=\"text-primary font-medium\" @click=\"$emit('switchToSignUp')\">\n Sign Up\n </ULink>\n </template>\n </UAuthForm>\n </UPageCard>\n </div>\n</template>\n`],\n [\"auth/better-auth/web/nuxt/app/components/UserMenu.vue.hbs\", `<script setup lang=\"ts\">\n\nconst {$authClient} = useNuxtApp()\nconst session = $authClient.useSession()\nconst toast = useToast()\n\nconst handleSignOut = async () => {\n try {\n await $authClient.signOut({\n fetchOptions: {\n onSuccess: async () => {\n toast.add({ title: 'Signed out successfully' })\n await navigateTo('/', { replace: true, external: true })\n },\n onError: (error) => {\n toast.add({ title: 'Sign out failed', description: error?.error?.message || 'Unknown error'})\n }\n },\n })\n } catch (error: any) {\n toast.add({ title: 'An unexpected error occurred during sign out', description: error.message || 'Please try again.'})\n }\n}\n</script>\n\n<template>\n <div>\n <USkeleton v-if=\"session.isPending\" class=\"h-9 w-24\" />\n\n <UButton v-else-if=\"!session.data\" variant=\"outline\" to=\"/login\">\n Sign In\n </UButton>\n\n <UButton\n v-else\n variant=\"solid\"\n icon=\"i-lucide-log-out\"\n label=\"Sign out\"\n @click=\"handleSignOut()\"\n />\n </div>\n</template>\n`],\n [\"auth/better-auth/web/nuxt/app/components/SignUpForm.vue.hbs\", `<script setup lang=\"ts\">\nimport * as z from 'zod'\nimport type { FormSubmitEvent, AuthFormField } from '@nuxt/ui'\n\nconst { $authClient } = useNuxtApp()\n\nconst emit = defineEmits(['switchToSignIn'])\n\nconst toast = useToast()\nconst loading = ref(false)\n\nconst fields: AuthFormField[] = [\n {\n name: 'name',\n type: 'text',\n label: 'Name',\n placeholder: 'Enter your name',\n required: true\n },\n {\n name: 'email',\n type: 'email',\n label: 'Email',\n placeholder: 'Enter your email',\n required: true\n },\n {\n name: 'password',\n type: 'password',\n label: 'Password',\n placeholder: 'Enter your password',\n required: true\n }\n]\n\nconst schema = z.object({\n name: z.string().min(2, 'Name must be at least 2 characters'),\n email: z.email('Invalid email address'),\n password: z.string().min(8, 'Password must be at least 8 characters'),\n})\n\ntype Schema = z.output<typeof schema>\n\nasync function onSubmit(event: FormSubmitEvent<Schema>) {\n loading.value = true\n try {\n await $authClient.signUp.email(\n {\n name: event.data.name,\n email: event.data.email,\n password: event.data.password,\n },\n {\n onSuccess: () => {\n toast.add({ title: 'Sign up successful' })\n navigateTo('/dashboard', { replace: true })\n },\n onError: (error) => {\n toast.add({ title: 'Sign up failed', description: error.error.message })\n },\n },\n )\n } catch (error: any) {\n toast.add({ title: 'An unexpected error occurred', description: error.message || 'Please try again.' })\n } finally {\n loading.value = false\n }\n}\n</script>\n\n<template>\n <div class=\"flex flex-col items-center justify-center gap-4 p-4\">\n <UPageCard class=\"w-full max-w-md\">\n <UAuthForm\n :schema=\"schema\"\n :fields=\"fields\"\n title=\"Create Account\"\n icon=\"i-lucide-user-plus\"\n :submit=\"{ label: 'Sign Up', loading }\"\n @submit=\"onSubmit\"\n >\n <template #description>\n Already have an account?\n <ULink class=\"text-primary font-medium\" @click=\"$emit('switchToSignIn')\">\n Sign In\n </ULink>\n </template>\n </UAuthForm>\n </UPageCard>\n </div>\n</template>\n`],\n [\"auth/better-auth/convex/native/unistyles/components/sign-up.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useState } from \"react\";\nimport {\n ActivityIndicator,\n Text,\n TextInput,\n TouchableOpacity,\n View,\n} from \"react-native\";\nimport { StyleSheet } from \"react-native-unistyles\";\n\nexport function SignUp() {\n const [name, setName] = useState(\"\");\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const handleSignUp = async () => {\n setIsLoading(true);\n setError(null);\n\n await authClient.signUp.email(\n {\n name,\n email,\n password,\n },\n {\n onError: (error) => {\n setError(error.error?.message || \"Failed to sign up\");\n setIsLoading(false);\n },\n onSuccess: () => {\n setName(\"\");\n setEmail(\"\");\n setPassword(\"\");\n },\n onFinished: () => {\n setIsLoading(false);\n },\n },\n );\n };\n\n return (\n <View style={styles.container}>\n <Text style={styles.title}>Create Account</Text>\n\n {error && (\n <View style={styles.errorContainer}>\n <Text style={styles.errorText}>{error}</Text>\n </View>\n )}\n\n <TextInput\n style={styles.input}\n placeholder=\"Name\"\n value={name}\n onChangeText={setName}\n />\n\n <TextInput\n style={styles.input}\n placeholder=\"Email\"\n value={email}\n onChangeText={setEmail}\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n />\n\n <TextInput\n style={styles.inputLast}\n placeholder=\"Password\"\n value={password}\n onChangeText={setPassword}\n secureTextEntry\n />\n\n <TouchableOpacity\n onPress={handleSignUp}\n disabled={isLoading}\n style={styles.button}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color=\"#fff\" />\n ) : (\n <Text style={styles.buttonText}>Sign Up</Text>\n )}\n </TouchableOpacity>\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n container: {\n marginTop: 24,\n padding: 16,\n borderRadius: 8,\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n title: {\n fontSize: 18,\n fontWeight: \"600\",\n color: theme.colors.typography,\n marginBottom: 16,\n },\n errorContainer: {\n marginBottom: 16,\n padding: 12,\n borderRadius: 6,\n },\n errorText: {\n color: theme.colors.destructive,\n fontSize: 14,\n },\n input: {\n marginBottom: 12,\n padding: 16,\n borderRadius: 6,\n color: theme.colors.typography,\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n inputLast: {\n marginBottom: 16,\n padding: 16,\n borderRadius: 6,\n color: theme.colors.typography,\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n button: {\n backgroundColor: theme.colors.primary,\n padding: 16,\n borderRadius: 6,\n flexDirection: \"row\",\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n buttonText: {\n fontWeight: \"500\",\n },\n}));\n`],\n [\"auth/better-auth/convex/native/unistyles/components/sign-in.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useState } from \"react\";\nimport {\n ActivityIndicator,\n Text,\n TextInput,\n TouchableOpacity,\n View,\n} from \"react-native\";\nimport { StyleSheet } from \"react-native-unistyles\";\n\nexport function SignIn() {\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const handleLogin = async () => {\n setIsLoading(true);\n setError(null);\n\n await authClient.signIn.email(\n {\n email,\n password,\n },\n {\n onError: (error) => {\n setError(error.error?.message || \"Failed to sign in\");\n setIsLoading(false);\n },\n onSuccess: () => {\n setEmail(\"\");\n setPassword(\"\");\n },\n onFinished: () => {\n setIsLoading(false);\n },\n },\n );\n };\n\n return (\n <View style={styles.container}>\n <Text style={styles.title}>Sign In</Text>\n\n {error && (\n <View style={styles.errorContainer}>\n <Text style={styles.errorText}>{error}</Text>\n </View>\n )}\n\n <TextInput\n style={styles.input}\n placeholder=\"Email\"\n value={email}\n onChangeText={setEmail}\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n />\n\n <TextInput\n style={styles.input}\n placeholder=\"Password\"\n value={password}\n onChangeText={setPassword}\n secureTextEntry\n />\n\n <TouchableOpacity\n onPress={handleLogin}\n disabled={isLoading}\n style={styles.button}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color=\"#fff\" />\n ) : (\n <Text style={styles.buttonText}>Sign In</Text>\n )}\n </TouchableOpacity>\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n container: {\n marginTop: 24,\n padding: 16,\n borderRadius: 8,\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n title: {\n fontSize: 18,\n fontWeight: \"600\",\n color: theme.colors.typography,\n marginBottom: 16,\n },\n errorContainer: {\n marginBottom: 16,\n padding: 12,\n borderRadius: 6,\n },\n errorText: {\n color: theme.colors.destructive,\n fontSize: 14,\n },\n input: {\n marginBottom: 12,\n padding: 16,\n borderRadius: 6,\n color: theme.colors.typography,\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n button: {\n backgroundColor: theme.colors.primary,\n padding: 16,\n borderRadius: 6,\n flexDirection: \"row\",\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n buttonText: {\n fontWeight: \"500\",\n },\n}));\n`],\n [\"auth/better-auth/web/nuxt/app/plugins/auth-client.ts.hbs\", `import { createAuthClient } from \"better-auth/vue\";\n{{#if (eq payments \"polar\")}}\nimport { polarClient } from \"@polar-sh/better-auth\";\n{{/if}}\n\nexport default defineNuxtPlugin(() => {\n const config = useRuntimeConfig();\n\n const authClient = createAuthClient({\n baseURL: config.public.serverUrl,\n {{#if (eq payments \"polar\")}}\n plugins: [polarClient()],\n {{/if}}\n });\n\n return {\n provide: {\n authClient: authClient,\n },\n };\n});\n`],\n [\"auth/better-auth/web/nuxt/app/middleware/auth.ts.hbs\", `export default defineNuxtRouteMiddleware(async (to, from) => {\n if (import.meta.server) return;\n\n const { $authClient } = useNuxtApp();\n const session = $authClient.useSession();\n\n if (session.value.isPending) {\n return;\n }\n\n if (!session.value.data) {\n return navigateTo(\"/login\");\n }\n});\n`],\n [\"auth/better-auth/convex/native/base/lib/auth-client.ts.hbs\", `import { createAuthClient } from \"better-auth/react\";\nimport { convexClient } from \"@convex-dev/better-auth/client/plugins\";\nimport { expoClient } from \"@better-auth/expo/client\";\nimport Constants from \"expo-constants\";\nimport * as SecureStore from \"expo-secure-store\";\nimport { env } from \"@{{projectName}}/env/native\";\n\nexport const authClient = createAuthClient({\n\tbaseURL: env.EXPO_PUBLIC_CONVEX_SITE_URL,\n\tplugins: [\n\t\texpoClient({\n\t\t\tscheme: Constants.expoConfig?.scheme as string,\n\t\t\tstoragePrefix: Constants.expoConfig?.scheme as string,\n\t\t\tstorage: SecureStore,\n\t\t}),\n\t\tconvexClient(),\n\t],\n});\n`],\n [\"job-queue/inngest/server/base/src/inngest/client.ts.hbs\", `import { Inngest } from \"inngest\";\n\n/**\n * Inngest client configuration\n * @see https://www.inngest.com/docs\n */\nexport const inngest = new Inngest({\n id: \"{{projectName}}\",\n // Event key is optional for local development\n // Required in production - get it at https://app.inngest.com\n eventKey: process.env.INNGEST_EVENT_KEY,\n});\n`],\n [\"job-queue/inngest/server/base/src/inngest/functions.ts.hbs\", `import { inngest } from \"./client\";\n\n/**\n * Example email sending function\n * Triggered by: inngest.send({ name: \"app/email.send\", data: { to, subject, body } })\n * @see https://www.inngest.com/docs/functions\n */\nexport const sendEmail = inngest.createFunction(\n {\n id: \"send-email\",\n // Retry configuration\n retries: 3,\n },\n { event: \"app/email.send\" },\n async ({ event, step }) => {\n const { to, subject, body, templateId } = event.data;\n\n // Use steps for reliable execution with automatic retries\n const result = await step.run(\"send-email\", async () => {\n // TODO: Implement your email sending logic here\n // Example with a hypothetical email service:\n // await emailService.send({ to, subject, body, templateId });\n\n // Simulate email sending\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n return {\n sent: true,\n to,\n timestamp: new Date().toISOString(),\n };\n });\n\n return result;\n }\n);\n\n/**\n * Example notification function\n * Supports different notification types: push, in-app, sms\n */\nexport const sendNotification = inngest.createFunction(\n {\n id: \"send-notification\",\n retries: 3,\n },\n { event: \"app/notification.send\" },\n async ({ event, step }) => {\n const { userId, type, title, message, data } = event.data;\n\n const result = await step.run(\"send-notification\", async () => {\n // TODO: Implement your notification logic here\n // switch (type) {\n // case \"push\":\n // await pushService.send(userId, { title, message, data });\n // break;\n // case \"in-app\":\n // await inAppNotificationService.create(userId, { title, message, data });\n // break;\n // case \"sms\":\n // await smsService.send(userId, message);\n // break;\n // }\n\n // Simulate notification processing\n await new Promise((resolve) => setTimeout(resolve, 500));\n\n return {\n sent: true,\n type,\n userId,\n timestamp: new Date().toISOString(),\n };\n });\n\n return result;\n }\n);\n\n/**\n * Example data processing function with multiple steps\n * Demonstrates step-based workflows for complex operations\n */\nexport const processData = inngest.createFunction(\n {\n id: \"process-data\",\n retries: 2,\n // Cancel if another run for the same dataId starts\n cancelOn: [\n {\n event: \"app/data.cancel\",\n match: \"data.dataId\",\n },\n ],\n },\n { event: \"app/data.process\" },\n async ({ event, step }) => {\n const { dataId, operation } = event.data;\n\n // Step 1: Validate input\n await step.run(\"validate\", async () => {\n if (!dataId) {\n throw new Error(\"Data ID is required\");\n }\n });\n\n // Step 2: Process data based on operation\n const result = await step.run(\"process\", async () => {\n // TODO: Implement your data processing logic here\n // const data = await database.getData(dataId);\n // switch (operation) {\n // case \"transform\":\n // return await transformData(data);\n // case \"aggregate\":\n // return await aggregateData(data);\n // case \"export\":\n // return await exportData(data);\n // }\n\n // Simulate data processing\n await new Promise((resolve) => setTimeout(resolve, 2000));\n\n return {\n processed: true,\n dataId,\n operation,\n };\n });\n\n // Step 3: Send completion notification\n await step.sendEvent(\"send-completion-notification\", {\n name: \"app/notification.send\",\n data: {\n userId: \"system\",\n type: \"in-app\" as const,\n title: \"Processing Complete\",\n message: \\`Data \\${dataId} has been \\${operation}ed successfully\\`,\n },\n });\n\n return {\n ...result,\n timestamp: new Date().toISOString(),\n };\n }\n);\n\n/**\n * Example scheduled function (cron job)\n * Runs every hour - customize the cron pattern as needed\n * @see https://www.inngest.com/docs/guides/scheduled-functions\n */\nexport const hourlyCleanup = inngest.createFunction(\n { id: \"hourly-cleanup\" },\n { cron: \"0 * * * *\" }, // Every hour at minute 0\n async ({ step }) => {\n const result = await step.run(\"cleanup\", async () => {\n // TODO: Implement your cleanup logic here\n // await database.deleteExpiredSessions();\n // await cache.clearStale();\n\n // Simulate cleanup\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n return {\n cleaned: true,\n timestamp: new Date().toISOString(),\n };\n });\n\n return result;\n }\n);\n\n/**\n * Example daily report function with timezone\n * Runs at 9 AM UTC - change timezone as needed\n */\nexport const dailyReport = inngest.createFunction(\n { id: \"daily-report\" },\n { cron: \"TZ=UTC 0 9 * * *\" }, // 9 AM UTC every day\n async ({ step }) => {\n // Step 1: Generate report data\n const reportData = await step.run(\"generate-report\", async () => {\n // TODO: Implement your report generation logic here\n // const stats = await analytics.getDailyStats();\n // return generateReportData(stats);\n\n // Simulate report generation\n await new Promise((resolve) => setTimeout(resolve, 2000));\n\n return {\n generatedAt: new Date().toISOString(),\n metrics: {\n users: 100,\n events: 500,\n },\n };\n });\n\n // Step 2: Send report via email\n await step.sendEvent(\"send-report-email\", {\n name: \"app/email.send\",\n data: {\n to: \"admin@example.com\",\n subject: \"Daily Report\",\n body: \\`Daily metrics: \\${JSON.stringify(reportData.metrics)}\\`,\n },\n });\n\n return {\n reportGenerated: true,\n timestamp: new Date().toISOString(),\n };\n }\n);\n\n/**\n * Example delayed function\n * Demonstrates using step.sleep for delayed execution\n */\nexport const welcomeSequence = inngest.createFunction(\n { id: \"welcome-sequence\" },\n { event: \"app/user.signup\" },\n async ({ event, step }) => {\n const { userId, email, name } = event.data;\n\n // Send immediate welcome email\n await step.sendEvent(\"send-welcome\", {\n name: \"app/email.send\",\n data: {\n to: email,\n subject: \"Welcome to {{projectName}}!\",\n body: \\`Hi \\${name}, welcome aboard!\\`,\n },\n });\n\n // Wait 1 day before sending tips email\n await step.sleep(\"wait-1-day\", \"1d\");\n\n await step.sendEvent(\"send-tips\", {\n name: \"app/email.send\",\n data: {\n to: email,\n subject: \"Getting Started Tips\",\n body: \\`Hi \\${name}, here are some tips to get the most out of {{projectName}}...\\`,\n },\n });\n\n // Wait 3 more days before sending feature highlight\n await step.sleep(\"wait-3-days\", \"3d\");\n\n await step.sendEvent(\"send-features\", {\n name: \"app/email.send\",\n data: {\n to: email,\n subject: \"Discover More Features\",\n body: \\`Hi \\${name}, have you tried these features yet?\\`,\n },\n });\n\n return {\n completed: true,\n userId,\n timestamp: new Date().toISOString(),\n };\n }\n);\n\n// Export all functions for the serve handler\nexport const functions = [\n sendEmail,\n sendNotification,\n processData,\n hourlyCleanup,\n dailyReport,\n welcomeSequence,\n];\n`],\n [\"job-queue/inngest/server/base/src/lib/inngest.ts.hbs\", `/**\n * Inngest utility functions for triggering events from your backend\n * @see https://www.inngest.com/docs\n */\nimport { inngest } from \"../inngest/client\";\n\n// Type definitions for event payloads\nexport interface EmailPayload {\n to: string;\n subject: string;\n body: string;\n templateId?: string;\n}\n\nexport interface NotificationPayload {\n userId: string;\n type: \"push\" | \"in-app\" | \"sms\";\n title: string;\n message: string;\n data?: Record<string, unknown>;\n}\n\nexport interface DataProcessingPayload {\n dataId: string;\n operation: \"transform\" | \"aggregate\" | \"export\";\n}\n\nexport interface UserSignupPayload {\n userId: string;\n email: string;\n name: string;\n}\n\n/**\n * Trigger an email event\n * @example\n * await triggerEmail({\n * to: \"user@example.com\",\n * subject: \"Welcome!\",\n * body: \"Thanks for signing up.\"\n * });\n */\nexport async function triggerEmail(payload: EmailPayload) {\n return inngest.send({\n name: \"app/email.send\",\n data: payload,\n });\n}\n\n/**\n * Trigger a notification event\n * @example\n * await triggerNotification({\n * userId: \"user_123\",\n * type: \"push\",\n * title: \"New message\",\n * message: \"You have a new message!\"\n * });\n */\nexport async function triggerNotification(payload: NotificationPayload) {\n return inngest.send({\n name: \"app/notification.send\",\n data: payload,\n });\n}\n\n/**\n * Trigger a data processing event\n * @example\n * await triggerDataProcessing({\n * dataId: \"data_456\",\n * operation: \"transform\"\n * });\n */\nexport async function triggerDataProcessing(payload: DataProcessingPayload) {\n return inngest.send({\n name: \"app/data.process\",\n data: payload,\n });\n}\n\n/**\n * Cancel a running data processing job\n * @example\n * await cancelDataProcessing(\"data_456\");\n */\nexport async function cancelDataProcessing(dataId: string) {\n return inngest.send({\n name: \"app/data.cancel\",\n data: { dataId },\n });\n}\n\n/**\n * Trigger user signup welcome sequence\n * @example\n * await triggerWelcomeSequence({\n * userId: \"user_123\",\n * email: \"user@example.com\",\n * name: \"John\"\n * });\n */\nexport async function triggerWelcomeSequence(payload: UserSignupPayload) {\n return inngest.send({\n name: \"app/user.signup\",\n data: payload,\n });\n}\n\n/**\n * Trigger multiple events in a batch\n * @example\n * await triggerEmailBatch([\n * { to: \"user1@example.com\", subject: \"Hello\", body: \"Hi!\" },\n * { to: \"user2@example.com\", subject: \"Hello\", body: \"Hi!\" }\n * ]);\n */\nexport async function triggerEmailBatch(payloads: EmailPayload[]) {\n return inngest.send(\n payloads.map((data) => ({\n name: \"app/email.send\" as const,\n data,\n }))\n );\n}\n\n// Re-export the inngest client for advanced usage\nexport { inngest };\n`],\n [\"auth/better-auth/convex/native/uniwind/components/sign-up.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useState } from \"react\";\nimport { Text, View } from \"react-native\";\nimport { Button, ErrorView, Spinner, Surface, TextField } from \"heroui-native\";\n\nexport function SignUp() {\n const [name, setName] = useState(\"\");\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const handleSignUp = async () => {\n setIsLoading(true);\n setError(null);\n\n await authClient.signUp.email(\n {\n name,\n email,\n password,\n },\n {\n onError: (error) => {\n setError(error.error?.message || \"Failed to sign up\");\n setIsLoading(false);\n },\n onSuccess: () => {\n setName(\"\");\n setEmail(\"\");\n setPassword(\"\");\n },\n onFinished: () => {\n setIsLoading(false);\n },\n },\n );\n };\n\n return (\n <Surface variant=\"secondary\" className=\"p-4 rounded-lg\">\n <Text className=\"text-foreground font-medium mb-4\">Create Account</Text>\n\n <ErrorView isInvalid={!!error} className=\"mb-3\">\n {error}\n </ErrorView>\n\n <View className=\"gap-3\">\n <TextField>\n <TextField.Label>Name</TextField.Label>\n <TextField.Input value={name} onChangeText={setName} placeholder=\"John Doe\" />\n </TextField>\n\n <TextField>\n <TextField.Label>Email</TextField.Label>\n <TextField.Input\n value={email}\n onChangeText={setEmail}\n placeholder=\"email@example.com\"\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n />\n </TextField>\n\n <TextField>\n <TextField.Label>Password</TextField.Label>\n <TextField.Input\n value={password}\n onChangeText={setPassword}\n placeholder=\"••••••••\"\n secureTextEntry\n />\n </TextField>\n\n <Button onPress={handleSignUp} isDisabled={isLoading} className=\"mt-1\">\n {isLoading ? (\n <Spinner size=\"sm\" color=\"default\" />\n ) : (\n <Button.Label>Create Account</Button.Label>\n )}\n </Button>\n </View>\n </Surface>\n );\n}\n`],\n [\"auth/better-auth/convex/native/uniwind/components/sign-in.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useState } from \"react\";\nimport { Text, View } from \"react-native\";\nimport { Button, ErrorView, Spinner, Surface, TextField } from \"heroui-native\";\n\nexport function SignIn() {\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const handleLogin = async () => {\n setIsLoading(true);\n setError(null);\n\n await authClient.signIn.email(\n {\n email,\n password,\n },\n {\n onError: (error) => {\n setError(error.error?.message || \"Failed to sign in\");\n setIsLoading(false);\n },\n onSuccess: () => {\n setEmail(\"\");\n setPassword(\"\");\n },\n onFinished: () => {\n setIsLoading(false);\n },\n },\n );\n };\n\n return (\n <Surface variant=\"secondary\" className=\"p-4 rounded-lg\">\n <Text className=\"text-foreground font-medium mb-4\">Sign In</Text>\n\n <ErrorView isInvalid={!!error} className=\"mb-3\">\n {error}\n </ErrorView>\n\n <View className=\"gap-3\">\n <TextField>\n <TextField.Label>Email</TextField.Label>\n <TextField.Input\n value={email}\n onChangeText={setEmail}\n placeholder=\"email@example.com\"\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n />\n </TextField>\n\n <TextField>\n <TextField.Label>Password</TextField.Label>\n <TextField.Input\n value={password}\n onChangeText={setPassword}\n placeholder=\"••••••••\"\n secureTextEntry\n />\n </TextField>\n\n <Button onPress={handleLogin} isDisabled={isLoading} className=\"mt-1\">\n {isLoading ? <Spinner size=\"sm\" color=\"default\" /> : <Button.Label>Sign In</Button.Label>}\n </Button>\n </View>\n </Surface>\n );\n}\n`],\n [\"auth/better-auth/convex/native/bare/components/sign-up.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useState } from \"react\";\nimport {\n ActivityIndicator,\n Text,\n TextInput,\n TouchableOpacity,\n View,\n StyleSheet,\n} from \"react-native\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\n\nfunction SignUp() {\n const { colorScheme } = useColorScheme();\n const theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\n const [name, setName] = useState(\"\");\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n async function handleSignUp() {\n setIsLoading(true);\n setError(null);\n\n await authClient.signUp.email(\n {\n name,\n email,\n password,\n },\n {\n onError(error) {\n setError(error.error?.message || \"Failed to sign up\");\n setIsLoading(false);\n },\n onSuccess() {\n setName(\"\");\n setEmail(\"\");\n setPassword(\"\");\n },\n onFinished() {\n setIsLoading(false);\n },\n }\n );\n }\n\n return (\n <View style={[styles.card, { backgroundColor: theme.card, borderColor: theme.border }]}>\n <Text style={[styles.title, { color: theme.text }]}>Create Account</Text>\n\n {error ? (\n <View style={[styles.errorContainer, { backgroundColor: theme.notification + \"20\" }]}>\n <Text style={[styles.errorText, { color: theme.notification }]}>{error}</Text>\n </View>\n ) : null}\n\n <TextInput\n style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}\n placeholder=\"Name\"\n placeholderTextColor={theme.text}\n value={name}\n onChangeText={setName}\n />\n\n <TextInput\n style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}\n placeholder=\"Email\"\n placeholderTextColor={theme.text}\n value={email}\n onChangeText={setEmail}\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n />\n\n <TextInput\n style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}\n placeholder=\"Password\"\n placeholderTextColor={theme.text}\n value={password}\n onChangeText={setPassword}\n secureTextEntry\n />\n\n <TouchableOpacity\n onPress={handleSignUp}\n disabled={isLoading}\n style={[styles.button, { backgroundColor: theme.primary, opacity: isLoading ? 0.5 : 1 }]}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color=\"#ffffff\" />\n ) : (\n <Text style={styles.buttonText}>Sign Up</Text>\n )}\n </TouchableOpacity>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n card: {\n marginTop: 16,\n padding: 16,\n borderWidth: 1,\n },\n title: {\n fontSize: 18,\n fontWeight: \"bold\",\n marginBottom: 12,\n },\n errorContainer: {\n marginBottom: 12,\n padding: 8,\n },\n errorText: {\n fontSize: 14,\n },\n input: {\n borderWidth: 1,\n padding: 12,\n fontSize: 16,\n marginBottom: 12,\n },\n button: {\n padding: 12,\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n buttonText: {\n color: \"#ffffff\",\n fontSize: 16,\n },\n});\n\nexport { SignUp };\n\n`],\n [\"auth/better-auth/convex/native/bare/components/sign-in.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useState } from \"react\";\nimport {\n ActivityIndicator,\n Text,\n TextInput,\n TouchableOpacity,\n View,\n StyleSheet,\n} from \"react-native\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\n\nfunction SignIn() {\n const { colorScheme } = useColorScheme();\n const theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\n const [email, setEmail] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n async function handleLogin() {\n setIsLoading(true);\n setError(null);\n\n await authClient.signIn.email(\n {\n email,\n password,\n },\n {\n onError(error) {\n setError(error.error?.message || \"Failed to sign in\");\n setIsLoading(false);\n },\n onSuccess() {\n setEmail(\"\");\n setPassword(\"\");\n },\n onFinished() {\n setIsLoading(false);\n },\n }\n );\n }\n\n return (\n <View style={[styles.card, { backgroundColor: theme.card, borderColor: theme.border }]}>\n <Text style={[styles.title, { color: theme.text }]}>Sign In</Text>\n\n {error ? (\n <View style={[styles.errorContainer, { backgroundColor: theme.notification + \"20\" }]}>\n <Text style={[styles.errorText, { color: theme.notification }]}>{error}</Text>\n </View>\n ) : null}\n\n <TextInput\n style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}\n placeholder=\"Email\"\n placeholderTextColor={theme.text}\n value={email}\n onChangeText={setEmail}\n keyboardType=\"email-address\"\n autoCapitalize=\"none\"\n />\n\n <TextInput\n style={[styles.input, { color: theme.text, borderColor: theme.border, backgroundColor: theme.background }]}\n placeholder=\"Password\"\n placeholderTextColor={theme.text}\n value={password}\n onChangeText={setPassword}\n secureTextEntry\n />\n\n <TouchableOpacity\n onPress={handleLogin}\n disabled={isLoading}\n style={[styles.button, { backgroundColor: theme.primary, opacity: isLoading ? 0.5 : 1 }]}\n >\n {isLoading ? (\n <ActivityIndicator size=\"small\" color=\"#ffffff\" />\n ) : (\n <Text style={styles.buttonText}>Sign In</Text>\n )}\n </TouchableOpacity>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n card: {\n marginTop: 16,\n padding: 16,\n borderWidth: 1,\n },\n title: {\n fontSize: 18,\n fontWeight: \"bold\",\n marginBottom: 12,\n },\n errorContainer: {\n marginBottom: 12,\n padding: 8,\n },\n errorText: {\n fontSize: 14,\n },\n input: {\n borderWidth: 1,\n padding: 12,\n fontSize: 16,\n marginBottom: 12,\n },\n button: {\n padding: 12,\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n buttonText: {\n color: \"#ffffff\",\n fontSize: 16,\n },\n});\n\nexport { SignIn };\n\n`],\n [\"caching/upstash-redis/server/base/src/lib/cache.ts.hbs\", `import { Redis } from \"@upstash/redis\";\n\n/**\n * Upstash Redis client for serverless caching\n * @see https://upstash.com/docs/redis/overall/getstarted\n */\nexport const redis = new Redis({\n url: process.env.UPSTASH_REDIS_REST_URL!,\n token: process.env.UPSTASH_REDIS_REST_TOKEN!,\n});\n\n/**\n * Cache utilities for common caching patterns\n */\n\n/**\n * Get a cached value by key\n */\nexport async function cacheGet<T>(key: string): Promise<T | null> {\n return redis.get<T>(key);\n}\n\n/**\n * Set a cached value with optional TTL (in seconds)\n */\nexport async function cacheSet<T>(\n key: string,\n value: T,\n options?: { ex?: number; px?: number; nx?: boolean; xx?: boolean }\n): Promise<\"OK\" | null> {\n if (options?.ex) {\n return redis.set(key, value, { ex: options.ex });\n }\n if (options?.px) {\n return redis.set(key, value, { px: options.px });\n }\n if (options?.nx) {\n return redis.set(key, value, { nx: true });\n }\n if (options?.xx) {\n return redis.set(key, value, { xx: true });\n }\n return redis.set(key, value);\n}\n\n/**\n * Delete a cached value\n */\nexport async function cacheDelete(key: string): Promise<number> {\n return redis.del(key);\n}\n\n/**\n * Delete multiple cached values\n */\nexport async function cacheDeleteMany(keys: string[]): Promise<number> {\n if (keys.length === 0) return 0;\n return redis.del(...keys);\n}\n\n/**\n * Check if a key exists in cache\n */\nexport async function cacheExists(key: string): Promise<boolean> {\n const result = await redis.exists(key);\n return result === 1;\n}\n\n/**\n * Set expiration time on a key (in seconds)\n */\nexport async function cacheExpire(key: string, seconds: number): Promise<boolean> {\n const result = await redis.expire(key, seconds);\n return result === 1;\n}\n\n/**\n * Get remaining TTL of a key (in seconds)\n * Returns -1 if key has no expiration, -2 if key doesn't exist\n */\nexport async function cacheTTL(key: string): Promise<number> {\n return redis.ttl(key);\n}\n\n/**\n * Increment a numeric value\n */\nexport async function cacheIncr(key: string): Promise<number> {\n return redis.incr(key);\n}\n\n/**\n * Increment a numeric value by amount\n */\nexport async function cacheIncrBy(key: string, amount: number): Promise<number> {\n return redis.incrby(key, amount);\n}\n\n/**\n * Decrement a numeric value\n */\nexport async function cacheDecr(key: string): Promise<number> {\n return redis.decr(key);\n}\n\n/**\n * Get or set pattern - retrieves from cache or executes function and caches result\n */\nexport async function cacheGetOrSet<T>(\n key: string,\n fn: () => Promise<T>,\n ttlSeconds?: number\n): Promise<T> {\n const cached = await cacheGet<T>(key);\n if (cached !== null) {\n return cached;\n }\n\n const value = await fn();\n await cacheSet(key, value, ttlSeconds ? { ex: ttlSeconds } : undefined);\n return value;\n}\n\n/**\n * Hash operations - useful for storing objects\n */\nexport const cacheHash = {\n async get<T>(key: string, field: string): Promise<T | null> {\n return redis.hget<T>(key, field);\n },\n\n async getAll<T extends Record<string, unknown>>(key: string): Promise<T | null> {\n return redis.hgetall<T>(key);\n },\n\n async set(key: string, field: string, value: unknown): Promise<number> {\n return redis.hset(key, { [field]: value });\n },\n\n async setMultiple(key: string, values: Record<string, unknown>): Promise<number> {\n return redis.hset(key, values);\n },\n\n async delete(key: string, ...fields: string[]): Promise<number> {\n return redis.hdel(key, ...fields);\n },\n\n async exists(key: string, field: string): Promise<boolean> {\n const result = await redis.hexists(key, field);\n return result === 1;\n },\n};\n\n/**\n * List operations - useful for queues, recent items, etc.\n */\nexport const cacheList = {\n async push(key: string, ...values: unknown[]): Promise<number> {\n return redis.rpush(key, ...values);\n },\n\n async unshift(key: string, ...values: unknown[]): Promise<number> {\n return redis.lpush(key, ...values);\n },\n\n async pop<T>(key: string): Promise<T | null> {\n return redis.rpop<T>(key);\n },\n\n async shift<T>(key: string): Promise<T | null> {\n return redis.lpop<T>(key);\n },\n\n async range<T>(key: string, start: number, stop: number): Promise<T[]> {\n return redis.lrange<T>(key, start, stop);\n },\n\n async length(key: string): Promise<number> {\n return redis.llen(key);\n },\n\n async trim(key: string, start: number, stop: number): Promise<\"OK\"> {\n return redis.ltrim(key, start, stop);\n },\n};\n\n/**\n * Set operations - useful for unique collections, tags, etc.\n */\nexport const cacheSet_ = {\n async add(key: string, ...members: unknown[]): Promise<number> {\n return redis.sadd(key, ...members);\n },\n\n async remove(key: string, ...members: unknown[]): Promise<number> {\n return redis.srem(key, ...members);\n },\n\n async members<T>(key: string): Promise<T[]> {\n return redis.smembers<T>(key);\n },\n\n async isMember(key: string, member: unknown): Promise<boolean> {\n const result = await redis.sismember(key, member);\n return result === 1;\n },\n\n async size(key: string): Promise<number> {\n return redis.scard(key);\n },\n};\n\n/**\n * JSON operations - for complex data structures\n * Note: Requires Upstash Redis with JSON module enabled\n */\nexport const cacheJson = {\n async get<T>(key: string, path = \"$\"): Promise<T | null> {\n const result = await redis.json.get<T>(key, path);\n return result;\n },\n\n async set(key: string, path: string, value: unknown): Promise<\"OK\" | null> {\n return redis.json.set(key, path, value);\n },\n\n async delete(key: string, path = \"$\"): Promise<number> {\n return redis.json.del(key, path);\n },\n};\n`],\n [\"auth/nextauth/fullstack/next/src/lib/auth.ts.hbs\", `import NextAuth from \"next-auth\";\nimport Credentials from \"next-auth/providers/credentials\";\nimport GitHub from \"next-auth/providers/github\";\nimport Google from \"next-auth/providers/google\";\n{{#if (eq orm \"drizzle\")}}\nimport { DrizzleAdapter } from \"@auth/drizzle-adapter\";\nimport { db } from \"@{{projectName}}/db\";\nimport * as schema from \"@{{projectName}}/db/schema/auth\";\n{{/if}}\n{{#if (eq orm \"prisma\")}}\nimport { PrismaAdapter } from \"@auth/prisma-adapter\";\nimport prisma from \"@{{projectName}}/db\";\n{{/if}}\n\nexport const { handlers, auth, signIn, signOut } = NextAuth({\n{{#if (eq orm \"drizzle\")}}\n adapter: DrizzleAdapter(db, {\n usersTable: schema.users,\n accountsTable: schema.accounts,\n sessionsTable: schema.sessions,\n verificationTokensTable: schema.verificationTokens,\n }),\n{{/if}}\n{{#if (eq orm \"prisma\")}}\n adapter: PrismaAdapter(prisma),\n{{/if}}\n session: {\n strategy: \"{{#if (or (eq orm \"drizzle\") (eq orm \"prisma\"))}}database{{else}}jwt{{/if}}\",\n },\n providers: [\n // OAuth providers - configure in your .env file\n GitHub({\n clientId: process.env.AUTH_GITHUB_ID,\n clientSecret: process.env.AUTH_GITHUB_SECRET,\n }),\n Google({\n clientId: process.env.AUTH_GOOGLE_ID,\n clientSecret: process.env.AUTH_GOOGLE_SECRET,\n }),\n // Email/Password authentication\n Credentials({\n name: \"credentials\",\n credentials: {\n email: { label: \"Email\", type: \"email\" },\n password: { label: \"Password\", type: \"password\" },\n },\n async authorize(credentials) {\n // Add your own authentication logic here\n // This is a placeholder - implement proper password validation\n if (!credentials?.email || !credentials?.password) {\n return null;\n }\n\n // Example: Replace with your actual user lookup and password verification\n // const user = await db.query.users.findFirst({\n // where: eq(users.email, credentials.email),\n // });\n // if (user && await verifyPassword(credentials.password, user.password)) {\n // return { id: user.id, email: user.email, name: user.name };\n // }\n\n return null;\n },\n }),\n ],\n pages: {\n signIn: \"/login\",\n },\n callbacks: {\n async session({ session, user, token }) {\n if (session.user) {\n session.user.id = user?.id ?? token?.sub ?? \"\";\n }\n return session;\n },\n async jwt({ token, user }) {\n if (user) {\n token.sub = user.id;\n }\n return token;\n },\n },\n trustHost: true,\n});\n`],\n [\"email/postmark/server/base/src/lib/email.ts.hbs\", `import * as postmark from \"postmark\";\n\n// Initialize Postmark client with Server API Token\nconst client = new postmark.ServerClient(process.env.POSTMARK_SERVER_TOKEN || \"\");\n\nexport interface SendEmailOptions {\n to: string | string[];\n subject: string;\n html?: string;\n text?: string;\n from?: string;\n replyTo?: string;\n tag?: string;\n attachments?: Array<{\n name: string;\n content: string; // Base64 encoded content\n contentType: string;\n contentId?: string;\n }>;\n}\n\n/**\n * Send an email using Postmark\n * @see https://postmarkapp.com/developer/user-guide/send-email-with-api\n */\nexport async function sendEmail(options: SendEmailOptions) {\n const { to, subject, html, text, from, replyTo, tag, attachments } = options;\n\n const fromAddress = from || process.env.POSTMARK_FROM_EMAIL || \"noreply@example.com\";\n const toAddresses = Array.isArray(to) ? to.join(\", \") : to;\n\n try {\n const response = await client.sendEmail({\n From: fromAddress,\n To: toAddresses,\n Subject: subject,\n HtmlBody: html,\n TextBody: text,\n ReplyTo: replyTo,\n Tag: tag,\n Attachments: attachments?.map((a) => ({\n Name: a.name,\n Content: a.content,\n ContentType: a.contentType,\n ContentID: a.contentId,\n })),\n });\n\n console.log(\"Email sent:\", response.MessageID);\n return { success: true, messageId: response.MessageID };\n } catch (error) {\n console.error(\"Email sending error:\", error);\n throw error;\n }\n}\n\n/**\n * Send an email using a Postmark template\n * @see https://postmarkapp.com/developer/user-guide/send-email-with-templates\n */\nexport async function sendTemplateEmail(options: {\n to: string | string[];\n templateId: number;\n templateModel: Record<string, unknown>;\n from?: string;\n tag?: string;\n}) {\n const { to, templateId, templateModel, from, tag } = options;\n\n const fromAddress = from || process.env.POSTMARK_FROM_EMAIL || \"noreply@example.com\";\n const toAddresses = Array.isArray(to) ? to.join(\", \") : to;\n\n try {\n const response = await client.sendEmailWithTemplate({\n From: fromAddress,\n To: toAddresses,\n TemplateId: templateId,\n TemplateModel: templateModel,\n Tag: tag,\n });\n\n console.log(\"Template email sent:\", response.MessageID);\n return { success: true, messageId: response.MessageID };\n } catch (error) {\n console.error(\"Template email sending error:\", error);\n throw error;\n }\n}\n\n/**\n * Send batch emails (up to 500 per batch)\n * @see https://postmarkapp.com/developer/user-guide/send-email-with-api#batch-emails\n */\nexport async function sendBatchEmails(\n emails: Array<{\n to: string;\n subject: string;\n html?: string;\n text?: string;\n from?: string;\n tag?: string;\n }>\n) {\n const fromAddress = process.env.POSTMARK_FROM_EMAIL || \"noreply@example.com\";\n\n const messages = emails.map((email) => ({\n From: email.from || fromAddress,\n To: email.to,\n Subject: email.subject,\n HtmlBody: email.html,\n TextBody: email.text,\n Tag: email.tag,\n }));\n\n try {\n const responses = await client.sendEmailBatch(messages);\n console.log(\\`Batch of \\${responses.length} emails sent\\`);\n return {\n success: true,\n results: responses.map((r) => ({\n messageId: r.MessageID,\n errorCode: r.ErrorCode,\n message: r.Message,\n })),\n };\n } catch (error) {\n console.error(\"Batch email sending error:\", error);\n throw error;\n }\n}\n\n/**\n * Get the Postmark client instance for advanced usage\n */\nexport function getPostmarkClient() {\n return client;\n}\n\nexport { client };\n`],\n [\"email/aws-ses/server/base/src/lib/email.ts.hbs\", `import { SESClient, SendEmailCommand, SendRawEmailCommand } from \"@aws-sdk/client-ses\";\n\n// Initialize AWS SES client\nconst sesClient = new SESClient({\n region: process.env.AWS_REGION || \"us-east-1\",\n credentials: {\n accessKeyId: process.env.AWS_ACCESS_KEY_ID || \"\",\n secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || \"\",\n },\n});\n\nexport interface SendEmailOptions {\n to: string | string[];\n subject: string;\n html?: string;\n text?: string;\n from?: string;\n replyTo?: string | string[];\n cc?: string | string[];\n bcc?: string | string[];\n}\n\n/**\n * Send an email using AWS SES\n * @see https://docs.aws.amazon.com/ses/latest/APIReference/API_SendEmail.html\n */\nexport async function sendEmail(options: SendEmailOptions) {\n const { to, subject, html, text, from, replyTo, cc, bcc } = options;\n\n const fromAddress = from || process.env.AWS_SES_FROM_EMAIL || \"noreply@example.com\";\n const toAddresses = Array.isArray(to) ? to : [to];\n const replyToAddresses = replyTo ? (Array.isArray(replyTo) ? replyTo : [replyTo]) : undefined;\n const ccAddresses = cc ? (Array.isArray(cc) ? cc : [cc]) : undefined;\n const bccAddresses = bcc ? (Array.isArray(bcc) ? bcc : [bcc]) : undefined;\n\n const command = new SendEmailCommand({\n Source: fromAddress,\n Destination: {\n ToAddresses: toAddresses,\n CcAddresses: ccAddresses,\n BccAddresses: bccAddresses,\n },\n Message: {\n Subject: {\n Data: subject,\n Charset: \"UTF-8\",\n },\n Body: {\n ...(html && {\n Html: {\n Data: html,\n Charset: \"UTF-8\",\n },\n }),\n ...(text && {\n Text: {\n Data: text,\n Charset: \"UTF-8\",\n },\n }),\n },\n },\n ReplyToAddresses: replyToAddresses,\n });\n\n try {\n const response = await sesClient.send(command);\n console.log(\"Email sent:\", response.MessageId);\n return { success: true, messageId: response.MessageId };\n } catch (error) {\n console.error(\"Email sending error:\", error);\n throw error;\n }\n}\n\nexport interface SendRawEmailOptions {\n to: string | string[];\n subject: string;\n html?: string;\n text?: string;\n from?: string;\n replyTo?: string;\n attachments?: Array<{\n filename: string;\n content: string | Buffer;\n contentType: string;\n }>;\n}\n\n/**\n * Send a raw email with attachments using AWS SES\n * @see https://docs.aws.amazon.com/ses/latest/APIReference/API_SendRawEmail.html\n */\nexport async function sendRawEmail(options: SendRawEmailOptions) {\n const { to, subject, html, text, from, replyTo, attachments } = options;\n\n const fromAddress = from || process.env.AWS_SES_FROM_EMAIL || \"noreply@example.com\";\n const toAddresses = Array.isArray(to) ? to : [to];\n\n // Build MIME message\n const boundary = \\`----=_Part_\\${Date.now().toString(36)}\\`;\n const mixedBoundary = \\`----=_Mixed_\\${Date.now().toString(36)}\\`;\n\n let rawMessage = \"\";\n rawMessage += \\`From: \\${fromAddress}\\\\r\\\\n\\`;\n rawMessage += \\`To: \\${toAddresses.join(\", \")}\\\\r\\\\n\\`;\n rawMessage += \\`Subject: \\${subject}\\\\r\\\\n\\`;\n if (replyTo) {\n rawMessage += \\`Reply-To: \\${replyTo}\\\\r\\\\n\\`;\n }\n rawMessage += \"MIME-Version: 1.0\\\\r\\\\n\";\n\n if (attachments && attachments.length > 0) {\n rawMessage += \\`Content-Type: multipart/mixed; boundary=\"\\${mixedBoundary}\"\\\\r\\\\n\\\\r\\\\n\\`;\n rawMessage += \\`--\\${mixedBoundary}\\\\r\\\\n\\`;\n rawMessage += \\`Content-Type: multipart/alternative; boundary=\"\\${boundary}\"\\\\r\\\\n\\\\r\\\\n\\`;\n } else {\n rawMessage += \\`Content-Type: multipart/alternative; boundary=\"\\${boundary}\"\\\\r\\\\n\\\\r\\\\n\\`;\n }\n\n // Text part\n if (text) {\n rawMessage += \\`--\\${boundary}\\\\r\\\\n\\`;\n rawMessage += \"Content-Type: text/plain; charset=UTF-8\\\\r\\\\n\";\n rawMessage += \"Content-Transfer-Encoding: 7bit\\\\r\\\\n\\\\r\\\\n\";\n rawMessage += \\`\\${text}\\\\r\\\\n\\`;\n }\n\n // HTML part\n if (html) {\n rawMessage += \\`--\\${boundary}\\\\r\\\\n\\`;\n rawMessage += \"Content-Type: text/html; charset=UTF-8\\\\r\\\\n\";\n rawMessage += \"Content-Transfer-Encoding: 7bit\\\\r\\\\n\\\\r\\\\n\";\n rawMessage += \\`\\${html}\\\\r\\\\n\\`;\n }\n\n rawMessage += \\`--\\${boundary}--\\\\r\\\\n\\`;\n\n // Attachments\n if (attachments && attachments.length > 0) {\n for (const attachment of attachments) {\n rawMessage += \\`--\\${mixedBoundary}\\\\r\\\\n\\`;\n rawMessage += \\`Content-Type: \\${attachment.contentType}; name=\"\\${attachment.filename}\"\\\\r\\\\n\\`;\n rawMessage += \"Content-Transfer-Encoding: base64\\\\r\\\\n\";\n rawMessage += \\`Content-Disposition: attachment; filename=\"\\${attachment.filename}\"\\\\r\\\\n\\\\r\\\\n\\`;\n\n const content =\n typeof attachment.content === \"string\"\n ? attachment.content\n : attachment.content.toString(\"base64\");\n\n rawMessage += \\`\\${content}\\\\r\\\\n\\`;\n }\n rawMessage += \\`--\\${mixedBoundary}--\\\\r\\\\n\\`;\n }\n\n const command = new SendRawEmailCommand({\n RawMessage: {\n Data: Buffer.from(rawMessage),\n },\n });\n\n try {\n const response = await sesClient.send(command);\n console.log(\"Raw email sent:\", response.MessageId);\n return { success: true, messageId: response.MessageId };\n } catch (error) {\n console.error(\"Raw email sending error:\", error);\n throw error;\n }\n}\n\n/**\n * Send multiple emails (note: SES has rate limits, consider using bulk sending for large volumes)\n */\nexport async function sendBatchEmails(\n emails: Array<{\n to: string | string[];\n subject: string;\n html?: string;\n text?: string;\n from?: string;\n }>\n) {\n const results = await Promise.allSettled(\n emails.map((email) => sendEmail(email))\n );\n\n const successful = results.filter((r) => r.status === \"fulfilled\").length;\n const failed = results.filter((r) => r.status === \"rejected\").length;\n\n console.log(\\`Batch emails: \\${successful} sent, \\${failed} failed\\`);\n\n return {\n success: failed === 0,\n total: emails.length,\n successful,\n failed,\n results: results.map((r, i) => ({\n email: emails[i]?.to,\n status: r.status,\n ...(r.status === \"fulfilled\" ? { messageId: r.value.messageId } : { error: r.reason }),\n })),\n };\n}\n\n/**\n * Get the SES client for advanced usage\n */\nexport function getSESClient() {\n return sesClient;\n}\n\nexport { sesClient, SESClient, SendEmailCommand, SendRawEmailCommand };\n`],\n [\"email/plunk/server/base/src/lib/email.ts.hbs\", `import Plunk from \"@plunk/node\";\n\n// Initialize Plunk client with secret API key\nconst plunk = new Plunk(process.env.PLUNK_API_KEY || \"\");\n\nexport interface SendEmailOptions {\n to: string;\n subject: string;\n body: string;\n from?: string;\n name?: string;\n reply?: string;\n headers?: Record<string, string>;\n subscribed?: boolean;\n}\n\n/**\n * Send an email using Plunk\n * @see https://docs.useplunk.com/api-reference/emails/send\n */\nexport async function sendEmail(options: SendEmailOptions) {\n const { to, subject, body, name, reply, headers, subscribed } = options;\n\n try {\n const success = await plunk.emails.send({\n to,\n subject,\n body,\n name,\n reply,\n headers,\n subscribed,\n });\n\n if (success) {\n console.log(\"Email sent successfully to:\", to);\n return { success: true };\n }\n\n return { success: false, error: \"Failed to send email\" };\n } catch (error) {\n console.error(\"Email sending error:\", error);\n throw error;\n }\n}\n\nexport interface TrackEventOptions {\n event: string;\n email: string;\n data?: Record<string, string | number | boolean>;\n}\n\n/**\n * Track an event for a contact in Plunk\n * Events can trigger automated email sequences (automations)\n * @see https://docs.useplunk.com/api-reference/events/track\n */\nexport async function trackEvent(options: TrackEventOptions) {\n const { event, email, data } = options;\n\n try {\n const success = await plunk.events.track({\n event,\n email,\n data,\n });\n\n if (success) {\n console.log(\\`Event \"\\${event}\" tracked for:\\`, email);\n return { success: true };\n }\n\n return { success: false, error: \"Failed to track event\" };\n } catch (error) {\n console.error(\"Event tracking error:\", error);\n throw error;\n }\n}\n\n/**\n * Get the Plunk client instance for advanced usage\n * Useful for accessing contacts API or other advanced features\n */\nexport function getPlunkClient() {\n return plunk;\n}\n\nexport { plunk };\n`],\n [\"email/resend/server/base/src/lib/email.ts.hbs\", `import { Resend } from \"resend\";\n\n// Initialize Resend client\nconst resend = new Resend(process.env.RESEND_API_KEY);\n\nexport interface SendEmailOptions {\n to: string | string[];\n subject: string;\n html?: string;\n text?: string;\n react?: React.ReactElement;\n from?: string;\n replyTo?: string;\n}\n\n/**\n * Send an email using Resend\n * @see https://resend.com/docs/send-with-nodejs\n */\nexport async function sendEmail(options: SendEmailOptions) {\n const { to, subject, html, text, react, from, replyTo } = options;\n\n const fromAddress = from || process.env.RESEND_FROM_EMAIL || \"onboarding@resend.dev\";\n\n try {\n const { data, error } = await resend.emails.send({\n from: fromAddress,\n to: Array.isArray(to) ? to : [to],\n subject,\n html,\n text,\n react,\n replyTo,\n });\n\n if (error) {\n console.error(\"Failed to send email:\", error);\n throw new Error(\\`Failed to send email: \\${error.message}\\`);\n }\n\n return { success: true, data };\n } catch (error) {\n console.error(\"Email sending error:\", error);\n throw error;\n }\n}\n\n/**\n * Get the Resend client instance for advanced usage\n */\nexport function getResendClient() {\n return resend;\n}\n\nexport { resend };\n`],\n [\"auth/better-auth/web/svelte/src/lib/auth-client.ts.hbs\", `import { PUBLIC_SERVER_URL } from \"$env/static/public\";\nimport { createAuthClient } from \"better-auth/svelte\";\n{{#if (eq payments \"polar\")}}\nimport { polarClient } from \"@polar-sh/better-auth\";\n{{/if}}\n\nexport const authClient = createAuthClient({\n\tbaseURL: PUBLIC_SERVER_URL,\n{{#if (eq payments \"polar\")}}\n\tplugins: [polarClient()]\n{{/if}}\n});\n`],\n [\"auth/better-auth/native/uniwind/app/(drawer)/index.tsx.hbs\", `import { Text, View, Pressable } from \"react-native\";\nimport { Container } from \"@/components/container\";\nimport { authClient } from \"@/lib/auth-client\";\nimport { Ionicons } from \"@expo/vector-icons\";\nimport { Card, Chip, useThemeColor } from \"heroui-native\";\nimport { SignIn } from \"@/components/sign-in\";\nimport { SignUp } from \"@/components/sign-up\";\n{{#if (eq api \"orpc\")}}\nimport { useQuery } from \"@tanstack/react-query\";\nimport { queryClient, orpc } from \"@/utils/orpc\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { useQuery } from \"@tanstack/react-query\";\nimport { queryClient, trpc } from \"@/utils/trpc\";\n{{/if}}\n\nexport default function Home() {\n{{#if (eq api \"orpc\")}}\nconst healthCheck = useQuery(orpc.healthCheck.queryOptions());\nconst privateData = useQuery(orpc.privateData.queryOptions());\nconst isConnected = healthCheck?.data === \"OK\";\nconst isLoading = healthCheck?.isLoading;\n{{/if}}\n{{#if (eq api \"trpc\")}}\nconst healthCheck = useQuery(trpc.healthCheck.queryOptions());\nconst privateData = useQuery(trpc.privateData.queryOptions());\nconst isConnected = healthCheck?.data === \"OK\";\nconst isLoading = healthCheck?.isLoading;\n{{/if}}\nconst { data: session } = authClient.useSession();\n\nconst mutedColor = useThemeColor(\"muted\");\nconst successColor = useThemeColor(\"success\");\nconst dangerColor = useThemeColor(\"danger\");\nconst foregroundColor = useThemeColor(\"foreground\");\n\nreturn (\n<Container className=\"p-6\">\n <View className=\"py-4 mb-6\">\n <Text className=\"text-4xl font-bold text-foreground mb-2\">\n BETTER T STACK\n </Text>\n </View>\n\n {session?.user ? (\n <Card variant=\"secondary\" className=\"mb-6 p-4\">\n <Text className=\"text-foreground text-base mb-2\">\n Welcome, <Text className=\"font-medium\">{session.user.name}</Text>\n </Text>\n <Text className=\"text-muted text-sm mb-4\">\n {session.user.email}\n </Text>\n <Pressable className=\"bg-danger py-3 px-4 rounded-lg self-start active:opacity-70\" onPress={()=> {\n authClient.signOut();\n {{#if (eq api \"orpc\")}}\n queryClient.invalidateQueries();\n {{/if}}\n {{#if (eq api \"trpc\")}}\n queryClient.invalidateQueries();\n {{/if}}\n }}\n >\n <Text className=\"text-foreground font-medium\">Sign Out</Text>\n </Pressable>\n </Card>\n ) : null}\n\n {{#unless (eq api \"none\")}}\n <Card variant=\"secondary\" className=\"p-6\">\n <View className=\"flex-row items-center justify-between mb-4\">\n <Card.Title>System Status</Card.Title>\n <Chip variant=\"secondary\" color={isConnected ? \"success\" : \"danger\" } size=\"sm\">\n <Chip.Label>{isConnected ? \"LIVE\" : \"OFFLINE\"}</Chip.Label>\n </Chip>\n </View>\n\n <Card className=\"p-4\">\n <View className=\"flex-row items-center\">\n <View className={\\`w-3 h-3 rounded-full mr-3 \\${isConnected ? \"bg-success\" : \"bg-muted\" }\\`} />\n <View className=\"flex-1\">\n <Text className=\"text-foreground font-medium mb-1\">\n {{#if (eq api \"orpc\")}}ORPC{{else}}TRPC{{/if}} Backend\n </Text>\n <Card.Description>\n {isLoading\n ? \"Checking connection...\"\n : isConnected\n ? \"Connected to API\"\n : \"API Disconnected\"}\n </Card.Description>\n </View>\n {isLoading && (\n <Ionicons name=\"hourglass-outline\" size={20} color={mutedColor} />\n )}\n {!isLoading && isConnected && (\n <Ionicons name=\"checkmark-circle\" size={20} color={successColor} />\n )}\n {!isLoading && !isConnected && (\n <Ionicons name=\"close-circle\" size={20} color={dangerColor} />\n )}\n </View>\n </Card>\n </Card>\n\n <Card variant=\"secondary\" className=\"mt-6 p-4\">\n <Card.Title className=\"mb-3\">Private Data</Card.Title>\n {privateData && (\n <Card.Description>\n {privateData.data?.message}\n </Card.Description>\n )}\n </Card>\n {{/unless}}\n\n {!session?.user && (\n <>\n <SignIn />\n <SignUp />\n </>\n )}\n</Container>\n);\n}`],\n [\"auth/better-auth/web/svelte/src/components/SignInForm.svelte.hbs\", `<script lang=\"ts\">\n\timport { createForm } from '@tanstack/svelte-form';\n\timport { z } from 'zod';\n\timport { authClient } from '$lib/auth-client';\n\timport { goto } from '$app/navigation';\n\n\tlet { switchToSignUp } = $props<{ switchToSignUp: () => void }>();\n\n\tconst validationSchema = z.object({\n\t\temail: z.email('Invalid email address'),\n\t\tpassword: z.string().min(1, 'Password is required'),\n\t});\n\n\tconst form = createForm(() => ({\n\t\tdefaultValues: { email: '', password: '' },\n\t\tonSubmit: async ({ value }) => {\n\t\t\t\tawait authClient.signIn.email(\n\t\t\t\t\t{ email: value.email, password: value.password },\n\t\t\t\t\t{\n\t\t\t\t\t\tonSuccess: () => goto('/dashboard'),\n\t\t\t\t\t\tonError: (error) => {\n\t\t\t\t\t\t\tconsole.log(error.error.message || 'Sign in failed. Please try again.');\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t},\n\t\tvalidators: {\n\t\t\tonSubmit: validationSchema,\n\t\t},\n\t}));\n</script>\n\n<div class=\"mx-auto mt-10 w-full max-w-md p-6\">\n\t<h1 class=\"mb-6 text-center font-bold text-3xl\">Welcome Back</h1>\n\n\t<form\n\t\tclass=\"space-y-4\"\n\t\tonsubmit={(e) => {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tform.handleSubmit();\n\t\t}}\n\t>\n\t\t<form.Field name=\"email\">\n\t\t\t{#snippet children(field)}\n\t\t\t\t<div class=\"space-y-1\">\n\t\t\t\t\t<label for={field.name}>Email</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid={field.name}\n\t\t\t\t\t\tname={field.name}\n\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\tclass=\"w-full border\"\n\t\t\t\t\t\tonblur={field.handleBlur}\n\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\toninput={(e: Event) => {\n\t\t\t\t\t\t\tconst target = e.target as HTMLInputElement;\n\t\t\t\t\t\t\tfield.handleChange(target.value);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t\t{#if field.state.meta.isTouched}\n\t\t\t\t\t\t{#each field.state.meta.errors as error}\n\t\t\t\t\t\t\t<p class=\"text-sm text-red-500\" role=\"alert\">{error}</p>\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t{/if}\n\t\t\t\t</div>\n\t\t\t{/snippet}\n\t\t</form.Field>\n\n\t\t<form.Field name=\"password\">\n\t\t\t{#snippet children(field)}\n\t\t\t\t<div class=\"space-y-1\">\n\t\t\t\t\t<label for={field.name}>Password</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid={field.name}\n\t\t\t\t\t\tname={field.name}\n\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\tclass=\"w-full border\"\n\t\t\t\t\t\tonblur={field.handleBlur}\n\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\toninput={(e: Event) => {\n\t\t\t\t\t\t\tconst target = e.target as HTMLInputElement;\n\t\t\t\t\t\t\tfield.handleChange(target.value);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t\t{#if field.state.meta.isTouched}\n\t\t\t\t\t\t{#each field.state.meta.errors as error}\n\t\t\t\t\t\t\t<p class=\"text-sm text-red-500\" role=\"alert\">{error}</p>\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t{/if}\n\t\t\t\t</div>\n\t\t\t{/snippet}\n\t\t</form.Field>\n\n\t\t<form.Subscribe selector={(state) => ({ canSubmit: state.canSubmit, isSubmitting: state.isSubmitting })}>\n\t\t\t{#snippet children(state)}\n\t\t\t\t<button type=\"submit\" class=\"w-full\" disabled={!state.canSubmit || state.isSubmitting}>\n\t\t\t\t\t{state.isSubmitting ? 'Submitting...' : 'Sign In'}\n\t\t\t\t</button>\n\t\t\t{/snippet}\n\t\t</form.Subscribe>\n\t</form>\n\n\t<div class=\"mt-4 text-center\">\n\t\t<button type=\"button\" class=\"text-indigo-600 hover:text-indigo-800\" onclick={switchToSignUp}>\n\t\t\tNeed an account? Sign Up\n\t\t</button>\n\t</div>\n</div>\n`],\n [\"auth/better-auth/web/svelte/src/components/UserMenu.svelte.hbs\", `<script lang=\"ts\">\n\timport { authClient } from '$lib/auth-client';\n\timport { goto } from '$app/navigation';\n\n\tconst sessionQuery = authClient.useSession();\n\n\tasync function handleSignOut() {\n\t\tawait authClient.signOut({\n\t\tfetchOptions: {\n\t\t\tonSuccess: () => {\n\t\t\t\tgoto('/');\n\t\t\t},\n\t\t\tonError: (error) => {\n\t\t\t\tconsole.error('Sign out failed:', error);\n\t\t\t}\n\t\t}\n\t\t});\n\t}\n\n\tfunction goToLogin() {\n\t\tgoto('/login');\n\t}\n\n</script>\n\n<div class=\"relative\">\n\t{#if $sessionQuery.isPending}\n\t\t<div class=\"h-8 w-24 animate-pulse rounded bg-neutral-700\"></div>\n\t{:else if $sessionQuery.data?.user}\n\t\t{@const user = $sessionQuery.data.user}\n\t\t<div class=\"flex items-center gap-3\">\n\t\t\t<span class=\"text-sm text-neutral-300 hidden sm:inline\" title={user.email}>\n\t\t\t\t{user.name || user.email?.split('@')[0] || 'User'}\n\t\t\t</span>\n\t\t\t<button\n\t\t\t\tonclick={handleSignOut}\n\t\t\t\tclass=\"rounded px-3 py-1 text-sm bg-red-600 hover:bg-red-700 text-white transition-colors\"\n\t\t\t>\n\t\t\t\tSign Out\n\t\t\t</button>\n\t\t</div>\n\t{:else}\n\t\t<div class=\"flex items-center gap-2\">\n\t\t\t<button\n\t\t\t\tonclick={goToLogin}\n\t\t\t\tclass=\"rounded px-3 py-1 text-sm bg-indigo-600 hover:bg-indigo-700 text-white transition-colors\"\n\t\t\t>\n\t\t\t\tSign In\n\t\t\t</button>\n\t\t</div>\n\t{/if}\n</div>\n`],\n [\"auth/better-auth/web/svelte/src/components/SignUpForm.svelte.hbs\", `<script lang=\"ts\">\n\timport { createForm } from '@tanstack/svelte-form';\n\timport { z } from 'zod';\n\timport { authClient } from '$lib/auth-client';\n\timport { goto } from '$app/navigation';\n\n\tlet { switchToSignIn } = $props<{ switchToSignIn: () => void }>();\n\n\tconst validationSchema = z.object({\n\t\tname: z.string().min(2, 'Name must be at least 2 characters'),\n\t\temail: z.email('Invalid email address'),\n\t\tpassword: z.string().min(8, 'Password must be at least 8 characters'),\n\t});\n\n\n\tconst form = createForm(() => ({\n\t\tdefaultValues: { name: '', email: '', password: '' },\n\t\tonSubmit: async ({ value }) => {\n\t\t\t\tawait authClient.signUp.email(\n\t\t\t\t\t{\n\t\t\t\t\t\temail: value.email,\n\t\t\t\t\t\tpassword: value.password,\n\t\t\t\t\t\tname: value.name,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\t\tgoto('/dashboard');\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonError: (error) => {\n\t\t\t\t\t\t\tconsole.log(error.error.message || 'Sign up failed. Please try again.');\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t},\n\t\tvalidators: {\n\t\t\tonSubmit: validationSchema,\n\t\t},\n\t}));\n</script>\n\n<div class=\"mx-auto mt-10 w-full max-w-md p-6\">\n\t<h1 class=\"mb-6 text-center font-bold text-3xl\">Create Account</h1>\n\n\t<form\n\t\tid=\"form\"\n\t\tclass=\"space-y-4\"\n\t\tonsubmit={(e) => {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tform.handleSubmit();\n\t\t}}\n\t>\n\t\t<form.Field name=\"name\">\n\t\t\t{#snippet children(field)}\n\t\t\t\t<div class=\"space-y-1\">\n\t\t\t\t\t<label for={field.name}>Name</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid={field.name}\n\t\t\t\t\t\tname={field.name}\n\t\t\t\t\t\tclass=\"w-full border\"\n\t\t\t\t\t\tonblur={field.handleBlur}\n\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\toninput={(e: Event) => {\n\t\t\t\t\t\t\tconst target = e.target as HTMLInputElement;\n\t\t\t\t\t\t\tfield.handleChange(target.value);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t\t{#if field.state.meta.isTouched}\n\t\t\t\t\t\t{#each field.state.meta.errors as error}\n\t\t\t\t\t\t\t<p class=\"text-sm text-red-500\" role=\"alert\">{error}</p>\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t{/if}\n\t\t\t\t</div>\n\t\t\t{/snippet}\n\t\t</form.Field>\n\n\t\t<form.Field name=\"email\">\n\t\t\t{#snippet children(field)}\n\t\t\t\t<div class=\"space-y-1\">\n\t\t\t\t\t<label for={field.name}>Email</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid={field.name}\n\t\t\t\t\t\tname={field.name}\n\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\tclass=\"w-full border\"\n\t\t\t\t\t\tonblur={field.handleBlur}\n\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\toninput={(e: Event) => {\n\t\t\t\t\t\t\tconst target = e.target as HTMLInputElement;\n\t\t\t\t\t\t\tfield.handleChange(target.value);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t\t{#if field.state.meta.isTouched}\n\t\t\t\t\t\t{#each field.state.meta.errors as error}\n\t\t\t\t\t\t\t<p class=\"text-sm text-red-500\" role=\"alert\">{error}</p>\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t{/if}\n\t\t\t\t</div>\n\t\t\t{/snippet}\n\t\t</form.Field>\n\n\t\t<form.Field name=\"password\">\n\t\t\t{#snippet children(field)}\n\t\t\t\t<div class=\"space-y-1\">\n\t\t\t\t\t<label for={field.name}>Password</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid={field.name}\n\t\t\t\t\t\tname={field.name}\n\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\tclass=\"w-full border\"\n\t\t\t\t\t\tonblur={field.handleBlur}\n\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\toninput={(e: Event) => {\n\t\t\t\t\t\t\tconst target = e.target as HTMLInputElement;\n\t\t\t\t\t\t\tfield.handleChange(target.value);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t\t{#if field.state.meta.isTouched}\n\t\t\t\t\t\t{#each field.state.meta.errors as error}\n\t\t\t\t\t\t\t<p class=\"text-sm text-red-500\" role=\"alert\">{error}</p>\n\t\t\t\t\t\t{/each}\n\t\t\t\t\t{/if}\n\t\t\t\t</div>\n\t\t\t{/snippet}\n\t\t</form.Field>\n\n\t\t<form.Subscribe selector={(state) => ({ canSubmit: state.canSubmit, isSubmitting: state.isSubmitting })}>\n\t\t\t{#snippet children(state)}\n\t\t\t\t<button type=\"submit\" class=\"w-full\" disabled={!state.canSubmit || state.isSubmitting}>\n\t\t\t\t\t{state.isSubmitting ? 'Submitting...' : 'Sign Up'}\n\t\t\t\t</button>\n\t\t\t{/snippet}\n\t\t</form.Subscribe>\n\t</form>\n\n\t<div class=\"mt-4 text-center\">\n\t\t<button type=\"button\" class=\"text-indigo-600 hover:text-indigo-800\" onclick={switchToSignIn}>\n\t\t\tAlready have an account? Sign In\n\t\t</button>\n\t</div>\n</div>\n`],\n [\"email/sendgrid/server/base/src/lib/email.ts.hbs\", `import sgMail from \"@sendgrid/mail\";\n\n// Initialize SendGrid with API key\nsgMail.setApiKey(process.env.SENDGRID_API_KEY || \"\");\n\nexport interface SendEmailOptions {\n to: string | string[];\n subject: string;\n html?: string;\n text?: string;\n from?: string;\n replyTo?: string;\n attachments?: Array<{\n filename: string;\n content: string; // Base64 encoded content\n type: string;\n disposition?: \"attachment\" | \"inline\";\n contentId?: string;\n }>;\n categories?: string[];\n sendAt?: number; // Unix timestamp for scheduled sending\n}\n\n/**\n * Send an email using SendGrid\n * @see https://docs.sendgrid.com/api-reference/mail-send/mail-send\n */\nexport async function sendEmail(options: SendEmailOptions) {\n const { to, subject, html, text, from, replyTo, attachments, categories, sendAt } = options;\n\n const fromAddress = from || process.env.SENDGRID_FROM_EMAIL || \"noreply@example.com\";\n const toAddresses = Array.isArray(to) ? to : [to];\n\n try {\n const msg: sgMail.MailDataRequired = {\n to: toAddresses,\n from: fromAddress,\n subject,\n html: html || undefined,\n text: text || undefined,\n replyTo: replyTo || undefined,\n attachments: attachments?.map((a) => ({\n filename: a.filename,\n content: a.content,\n type: a.type,\n disposition: a.disposition || \"attachment\",\n contentId: a.contentId,\n })),\n categories,\n sendAt,\n };\n\n const response = await sgMail.send(msg);\n console.log(\"Email sent:\", response[0].statusCode);\n return { success: true, statusCode: response[0].statusCode };\n } catch (error) {\n console.error(\"Email sending error:\", error);\n throw error;\n }\n}\n\n/**\n * Send multiple emails in a batch (up to 1000 per batch)\n * @see https://docs.sendgrid.com/api-reference/mail-send/mail-send\n */\nexport async function sendBatchEmails(\n emails: Array<{\n to: string | string[];\n subject: string;\n html?: string;\n text?: string;\n from?: string;\n categories?: string[];\n }>\n) {\n const fromAddress = process.env.SENDGRID_FROM_EMAIL || \"noreply@example.com\";\n\n const messages: sgMail.MailDataRequired[] = emails.map((email) => ({\n to: Array.isArray(email.to) ? email.to : [email.to],\n from: email.from || fromAddress,\n subject: email.subject,\n html: email.html || undefined,\n text: email.text || undefined,\n categories: email.categories,\n }));\n\n try {\n const responses = await sgMail.send(messages);\n console.log(\\`Batch of \\${emails.length} emails sent\\`);\n return {\n success: true,\n results: responses.map((r) => ({\n statusCode: r[0].statusCode,\n })),\n };\n } catch (error) {\n console.error(\"Batch email sending error:\", error);\n throw error;\n }\n}\n\n/**\n * Send personalized emails to multiple recipients using dynamic templates\n * @see https://docs.sendgrid.com/api-reference/mail-send/mail-send#dynamic-templates\n */\nexport async function sendTemplateEmail(options: {\n to: string | string[];\n templateId: string;\n dynamicTemplateData: Record<string, unknown>;\n from?: string;\n categories?: string[];\n}) {\n const { to, templateId, dynamicTemplateData, from, categories } = options;\n\n const fromAddress = from || process.env.SENDGRID_FROM_EMAIL || \"noreply@example.com\";\n const toAddresses = Array.isArray(to) ? to : [to];\n\n try {\n const msg: sgMail.MailDataRequired = {\n to: toAddresses,\n from: fromAddress,\n templateId,\n dynamicTemplateData,\n categories,\n };\n\n const response = await sgMail.send(msg);\n console.log(\"Template email sent:\", response[0].statusCode);\n return { success: true, statusCode: response[0].statusCode };\n } catch (error) {\n console.error(\"Template email sending error:\", error);\n throw error;\n }\n}\n\n/**\n * Get the SendGrid mail client for advanced usage\n */\nexport function getSendGridClient() {\n return sgMail;\n}\n\nexport { sgMail };\n`],\n [\"auth/better-auth/native/bare/app/(drawer)/index.tsx.hbs\", `import { View, Text, ScrollView, TouchableOpacity, StyleSheet } from \"react-native\";\nimport { Container } from \"@/components/container\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\nimport { authClient } from \"@/lib/auth-client\";\nimport { SignIn } from \"@/components/sign-in\";\nimport { SignUp } from \"@/components/sign-up\";\n{{#if (eq api \"orpc\")}}\nimport { useQuery } from \"@tanstack/react-query\";\nimport { queryClient, orpc } from \"@/utils/orpc\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { useQuery } from \"@tanstack/react-query\";\nimport { queryClient, trpc } from \"@/utils/trpc\";\n{{/if}}\n\nexport default function Home() {\nconst { colorScheme } = useColorScheme();\nconst theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\n{{#if (eq api \"orpc\")}}\nconst healthCheck = useQuery(orpc.healthCheck.queryOptions());\nconst privateData = useQuery(orpc.privateData.queryOptions());\nconst isConnected = healthCheck?.data === \"OK\";\nconst isLoading = healthCheck?.isLoading;\n{{/if}}\n{{#if (eq api \"trpc\")}}\nconst healthCheck = useQuery(trpc.healthCheck.queryOptions());\nconst privateData = useQuery(trpc.privateData.queryOptions());\nconst isConnected = healthCheck?.data === \"OK\";\nconst isLoading = healthCheck?.isLoading;\n{{/if}}\nconst { data: session } = authClient.useSession();\n\nreturn (\n<Container>\n <ScrollView style={styles.scrollView}>\n <View style={styles.content}>\n <Text style={[styles.title, { color: theme.text }]}>\n BETTER T STACK\n </Text>\n\n {session?.user ? (\n <View style={[styles.userCard, { backgroundColor: theme.card, borderColor: theme.border }]}>\n <View style={styles.userHeader}>\n <Text style={[styles.userText, { color: theme.text }]}>\n Welcome, <Text style={styles.userName}>{session.user.name}</Text>\n </Text>\n </View>\n <Text style={[styles.userEmail, { color: theme.text, opacity: 0.7 }]}>\n {session.user.email}\n </Text>\n <TouchableOpacity style={[styles.signOutButton, { backgroundColor: theme.notification }]} onPress={()=> {\n authClient.signOut();\n {{#if (eq api \"orpc\")}}\n queryClient.invalidateQueries();\n {{/if}}\n {{#if (eq api \"trpc\")}}\n queryClient.invalidateQueries();\n {{/if}}\n }}\n >\n <Text style={styles.signOutText}>Sign Out</Text>\n </TouchableOpacity>\n </View>\n ) : null}\n\n {{#unless (eq api \"none\")}}\n <View style={[styles.statusCard, { backgroundColor: theme.card, borderColor: theme.border }]}>\n <Text style={[styles.cardTitle, { color: theme.text }]}>\n System Status\n </Text>\n <View style={styles.statusRow}>\n <View style={[styles.statusIndicator, { backgroundColor: isConnected ? \"#10b981\" : \"#ef4444\" }]} />\n <View style={styles.statusContent}>\n <Text style={[styles.statusTitle, { color: theme.text }]}>\n {{#if (eq api \"orpc\")}}ORPC{{else}}TRPC{{/if}} Backend\n </Text>\n <Text style={[styles.statusText, { color: theme.text, opacity: 0.7 }]}>\n {isLoading\n ? \"Checking connection...\"\n : isConnected\n ? \"Connected to API\"\n : \"API Disconnected\"}\n </Text>\n </View>\n </View>\n </View>\n\n <View style={[styles.privateDataCard, { backgroundColor: theme.card, borderColor: theme.border }]}>\n <Text style={[styles.cardTitle, { color: theme.text }]}>\n Private Data\n </Text>\n {privateData && (\n <Text style={[styles.privateDataText, { color: theme.text, opacity: 0.7 }]}>\n {privateData.data?.message}\n </Text>\n )}\n </View>\n {{/unless}}\n\n {!session?.user && (\n <>\n <SignIn />\n <SignUp />\n </>\n )}\n </View>\n </ScrollView>\n</Container>\n);\n}\n\nconst styles = StyleSheet.create({\nscrollView: {\nflex: 1,\n},\ncontent: {\npadding: 16,\n},\ntitle: {\nfontSize: 24,\nfontWeight: \"bold\",\nmarginBottom: 16,\n},\nuserCard: {\nmarginBottom: 16,\npadding: 16,\nborderWidth: 1,\n},\nuserHeader: {\nmarginBottom: 8,\n},\nuserText: {\nfontSize: 16,\n},\nuserName: {\nfontWeight: \"bold\",\n},\nuserEmail: {\nfontSize: 14,\nmarginBottom: 12,\n},\nsignOutButton: {\npadding: 12,\n},\nsignOutText: {\ncolor: \"#ffffff\",\n},\nstatusCard: {\nmarginBottom: 16,\npadding: 16,\nborderWidth: 1,\n},\ncardTitle: {\nfontSize: 16,\nfontWeight: \"bold\",\nmarginBottom: 12,\n},\nstatusRow: {\nflexDirection: \"row\",\nalignItems: \"center\",\ngap: 8,\n},\nstatusIndicator: {\nheight: 8,\nwidth: 8,\n},\nstatusContent: {\nflex: 1,\n},\nstatusTitle: {\nfontSize: 14,\nfontWeight: \"bold\",\n},\nstatusText: {\nfontSize: 12,\n},\nprivateDataCard: {\nmarginBottom: 16,\npadding: 16,\nborderWidth: 1,\n},\nprivateDataText: {\nfontSize: 14,\n},\n});`],\n [\"auth/better-auth/web/solid/src/routes/login.tsx.hbs\", `import SignInForm from \"@/components/sign-in-form\";\nimport SignUpForm from \"@/components/sign-up-form\";\nimport { createFileRoute } from \"@tanstack/solid-router\";\nimport { createSignal, Match, Switch } from \"solid-js\";\n\nexport const Route = createFileRoute(\"/login\")({\n component: RouteComponent,\n});\n\nfunction RouteComponent() {\n const [showSignIn, setShowSignIn] = createSignal(false);\n\n return (\n <Switch>\n <Match when={showSignIn()}>\n <SignInForm onSwitchToSignUp={() => setShowSignIn(false)} />\n </Match>\n <Match when={!showSignIn()}>\n <SignUpForm onSwitchToSignIn={() => setShowSignIn(true)} />\n </Match>\n </Switch>\n );\n}\n`],\n [\"auth/better-auth/web/solid/src/routes/dashboard.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\n{{#if (eq api \"orpc\")}}\nimport { orpc } from \"@/utils/orpc\";\nimport { useQuery } from \"@tanstack/solid-query\";\n{{/if}}\nimport { createFileRoute, redirect } from \"@tanstack/solid-router\";\n\nexport const Route = createFileRoute(\"/dashboard\")({\n\tcomponent: RouteComponent,\n\tbeforeLoad: async () => {\n\t\tconst session = await authClient.getSession();\n\t\tif (!session.data) {\n\t\t\tredirect({\n\t\t\t\tto: \"/login\",\n\t\t\t\tthrow: true,\n\t\t\t});\n\t\t}\n\t\t{{#if (eq payments \"polar\")}}\n\t\tconst { data: customerState } = await authClient.customer.state();\n\t\treturn { session, customerState };\n\t\t{{else}}\n\t\treturn { session };\n\t\t{{/if}}\n\t},\n});\n\nfunction RouteComponent() {\n\tconst context = Route.useRouteContext();\n\n\tconst session = context().session;\n\t{{#if (eq payments \"polar\")}}\n\tconst customerState = context().customerState;\n\t{{/if}}\n\n\t{{#if (eq api \"orpc\")}}\n\tconst privateData = useQuery(() => orpc.privateData.queryOptions());\n\t{{/if}}\n\n\t{{#if (eq payments \"polar\")}}\n\tconst hasProSubscription = () =>\n\t\tcustomerState?.activeSubscriptions?.length! > 0;\n\t{{/if}}\n\n\treturn (\n\t\t<div>\n\t\t\t<h1>Dashboard</h1>\n\t\t\t<p>Welcome {session.data?.user.name}</p>\n\t\t\t{{#if (eq api \"orpc\")}}\n\t\t\t<p>API: {privateData.data?.message}</p>\n\t\t\t{{/if}}\n\t\t\t{{#if (eq payments \"polar\")}}\n\t\t\t<p>Plan: {hasProSubscription() ? \"Pro\" : \"Free\"}</p>\n\t\t\t{hasProSubscription() ? (\n\t\t\t\t<button onClick={async () => await authClient.customer.portal()}>\n\t\t\t\t\tManage Subscription\n\t\t\t\t</button>\n\t\t\t) : (\n\t\t\t\t<button\n\t\t\t\t\tonClick={async () => await authClient.checkout({ slug: \"pro\" })}\n\t\t\t\t>\n\t\t\t\t\tUpgrade to Pro\n\t\t\t\t</button>\n\t\t\t)}\n\t\t\t{{/if}}\n\t\t</div>\n\t);\n}\n`],\n [\"auth/better-auth/web/solid/src/components/user-menu.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useNavigate, Link } from \"@tanstack/solid-router\";\nimport { createSignal, Show } from \"solid-js\";\n\nexport default function UserMenu() {\n const navigate = useNavigate();\n const session = authClient.useSession();\n const [isMenuOpen, setIsMenuOpen] = createSignal(false);\n\n return (\n <div class=\"relative inline-block text-left\">\n <Show when={session().isPending}>\n <div class=\"h-9 w-24 animate-pulse rounded\" />\n </Show>\n\n <Show when={!session().isPending && !session().data}>\n <Link to=\"/login\" class=\"inline-block border rounded px-4 text-sm\">\n Sign In\n </Link>\n </Show>\n\n <Show when={!session().isPending && session().data}>\n <button\n type=\"button\"\n class=\"inline-block border rounded px-4 text-sm\"\n onClick={() => setIsMenuOpen(!isMenuOpen())}\n >\n {session().data?.user.name}\n </button>\n\n <Show when={isMenuOpen()}>\n <div class=\"absolute right-0 mt-2 w-56 rounded p-1 shadow-sm\">\n <div class=\"px-4 text-sm\">{session().data?.user.email}</div>\n <button\n type=\"button\"\n class=\"mt-1 w-full border rounded px-4 text-center text-sm\"\n onClick={() => {\n setIsMenuOpen(false);\n authClient.signOut({\n fetchOptions: {\n onSuccess: () => {\n navigate({ to: \"/\" });\n },\n },\n });\n }}\n >\n Sign Out\n </button>\n </div>\n </Show>\n </Show>\n </div>\n );\n}\n`],\n [\"auth/better-auth/web/solid/src/components/sign-in-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { createForm } from \"@tanstack/solid-form\";\nimport { useNavigate } from \"@tanstack/solid-router\";\nimport z from \"zod\";\nimport { For } from \"solid-js\";\n\nexport default function SignInForm({ onSwitchToSignUp }: { onSwitchToSignUp: () => void }) {\n const navigate = useNavigate({\n from: \"/\",\n });\n\n const form = createForm(() => ({\n defaultValues: {\n email: \"\",\n password: \"\",\n },\n onSubmit: async ({ value }) => {\n await authClient.signIn.email(\n {\n email: value.email,\n password: value.password,\n },\n {\n onSuccess: () => {\n navigate({\n to: \"/dashboard\",\n });\n console.log(\"Sign in successful\");\n },\n onError: (error) => {\n console.error(error.error.message);\n },\n },\n );\n },\n validators: {\n onSubmit: z.object({\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n }));\n\n return (\n <div class=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 class=\"mb-6 text-center text-3xl font-bold\">Welcome Back</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n class=\"space-y-4\"\n >\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div class=\"space-y-2\">\n <label for={field().name}>Email</label>\n <input\n id={field().name}\n name={field().name}\n type=\"email\"\n value={field().state.value}\n onBlur={field().handleBlur}\n onInput={(e) => field().handleChange(e.currentTarget.value)}\n class=\"w-full rounded border p-2\"\n />\n <For each={field().state.meta.errors}>\n {(error) => <p class=\"text-sm text-red-600\">{error?.message}</p>}\n </For>\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div class=\"space-y-2\">\n <label for={field().name}>Password</label>\n <input\n id={field().name}\n name={field().name}\n type=\"password\"\n value={field().state.value}\n onBlur={field().handleBlur}\n onInput={(e) => field().handleChange(e.currentTarget.value)}\n class=\"w-full rounded border p-2\"\n />\n <For each={field().state.meta.errors}>\n {(error) => <p class=\"text-sm text-red-600\">{error?.message}</p>}\n </For>\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <button\n type=\"submit\"\n class=\"w-full rounded bg-indigo-600 p-2 text-white hover:bg-indigo-700 disabled:opacity-50\"\n disabled={!state().canSubmit || state().isSubmitting}\n >\n {state().isSubmitting ? \"Submitting...\" : \"Sign In\"}\n </button>\n )}\n </form.Subscribe>\n </form>\n\n <div class=\"mt-4 text-center\">\n <button\n type=\"button\"\n onClick={onSwitchToSignUp}\n class=\"text-sm text-indigo-600 hover:text-indigo-800 hover:underline\"\n >\n Need an account? Sign Up\n </button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/better-auth/web/solid/src/components/sign-up-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { createForm } from \"@tanstack/solid-form\";\nimport { useNavigate } from \"@tanstack/solid-router\";\nimport z from \"zod\";\nimport { For } from \"solid-js\";\n\nexport default function SignUpForm({ onSwitchToSignIn }: { onSwitchToSignIn: () => void }) {\n const navigate = useNavigate({\n from: \"/\",\n });\n\n const form = createForm(() => ({\n defaultValues: {\n email: \"\",\n password: \"\",\n name: \"\",\n },\n onSubmit: async ({ value }) => {\n await authClient.signUp.email(\n {\n email: value.email,\n password: value.password,\n name: value.name,\n },\n {\n onSuccess: () => {\n navigate({\n to: \"/dashboard\",\n });\n console.log(\"Sign up successful\");\n },\n onError: (error) => {\n console.error(error.error.message);\n },\n },\n );\n },\n validators: {\n onSubmit: z.object({\n name: z.string().min(2, \"Name must be at least 2 characters\"),\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n }));\n\n return (\n <div class=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 class=\"mb-6 text-center text-3xl font-bold\">Create Account</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n class=\"space-y-4\"\n >\n <div>\n <form.Field name=\"name\">\n {(field) => (\n <div class=\"space-y-2\">\n <label for={field().name}>Name</label>\n <input\n id={field().name}\n name={field().name}\n value={field().state.value}\n onBlur={field().handleBlur}\n onInput={(e) => field().handleChange(e.currentTarget.value)}\n class=\"w-full rounded border p-2\"\n />\n <For each={field().state.meta.errors}>\n {(error) => <p class=\"text-sm text-red-600\">{error?.message}</p>}\n </For>\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div class=\"space-y-2\">\n <label for={field().name}>Email</label>\n <input\n id={field().name}\n name={field().name}\n type=\"email\"\n value={field().state.value}\n onBlur={field().handleBlur}\n onInput={(e) => field().handleChange(e.currentTarget.value)}\n class=\"w-full rounded border p-2\"\n />\n <For each={field().state.meta.errors}>\n {(error) => <p class=\"text-sm text-red-600\">{error?.message}</p>}\n </For>\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div class=\"space-y-2\">\n <label for={field().name}>Password</label>\n <input\n id={field().name}\n name={field().name}\n type=\"password\"\n value={field().state.value}\n onBlur={field().handleBlur}\n onInput={(e) => field().handleChange(e.currentTarget.value)}\n class=\"w-full rounded border p-2\"\n />\n <For each={field().state.meta.errors}>\n {(error) => <p class=\"text-sm text-red-600\">{error?.message}</p>}\n </For>\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <button\n type=\"submit\"\n class=\"w-full rounded bg-indigo-600 p-2 text-white hover:bg-indigo-700 disabled:opacity-50\"\n disabled={!state().canSubmit || state().isSubmitting}\n >\n {state().isSubmitting ? \"Submitting...\" : \"Sign Up\"}\n </button>\n )}\n </form.Subscribe>\n </form>\n\n <div class=\"mt-4 text-center\">\n <button\n type=\"button\"\n onClick={onSwitchToSignIn}\n class=\"text-sm text-indigo-600 hover:text-indigo-800 hover:underline\"\n >\n Already have an account? Sign In\n </button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/better-auth/web/solid/src/lib/auth-client.ts.hbs\", `import { createAuthClient } from \"better-auth/solid\";\n{{#if (eq payments \"polar\")}}\nimport { polarClient } from \"@polar-sh/better-auth\";\n{{/if}}\nimport { env } from \"@{{projectName}}/env/web\";\n\nexport const authClient = createAuthClient({\n\tbaseURL: env.VITE_SERVER_URL,\n{{#if (eq payments \"polar\")}}\n\tplugins: [polarClient()]\n{{/if}}\n});\n`],\n [\"email/nodemailer/server/base/src/lib/email.ts.hbs\", `import nodemailer from \"nodemailer\";\n\n// Create reusable transporter object using SMTP transport\n// For development, you can use services like Mailtrap, Ethereal, or a local SMTP server\n// For production, configure with your SMTP provider (Gmail, SendGrid, AWS SES, etc.)\nconst transporter = nodemailer.createTransport({\n host: process.env.SMTP_HOST || \"smtp.ethereal.email\",\n port: Number(process.env.SMTP_PORT) || 587,\n secure: process.env.SMTP_SECURE === \"true\", // true for 465, false for other ports\n auth: {\n user: process.env.SMTP_USER,\n pass: process.env.SMTP_PASS,\n },\n});\n\nexport interface SendEmailOptions {\n to: string | string[];\n subject: string;\n html?: string;\n text?: string;\n from?: string;\n replyTo?: string;\n attachments?: Array<{\n filename: string;\n content?: string | Buffer;\n path?: string;\n contentType?: string;\n }>;\n}\n\n/**\n * Send an email using Nodemailer\n * @see https://nodemailer.com/\n */\nexport async function sendEmail(options: SendEmailOptions) {\n const { to, subject, html, text, from, replyTo, attachments } = options;\n\n const fromAddress = from || process.env.SMTP_FROM_EMAIL || \"noreply@example.com\";\n\n try {\n const info = await transporter.sendMail({\n from: fromAddress,\n to: Array.isArray(to) ? to.join(\", \") : to,\n subject,\n html,\n text,\n replyTo,\n attachments,\n });\n\n console.log(\"Email sent:\", info.messageId);\n return { success: true, messageId: info.messageId };\n } catch (error) {\n console.error(\"Email sending error:\", error);\n throw error;\n }\n}\n\n/**\n * Verify SMTP connection configuration\n * Call this on startup to ensure email sending will work\n */\nexport async function verifyEmailConnection(): Promise<boolean> {\n try {\n await transporter.verify();\n console.log(\"SMTP connection verified successfully\");\n return true;\n } catch (error) {\n console.error(\"SMTP connection verification failed:\", error);\n return false;\n }\n}\n\n/**\n * Get the nodemailer transporter instance for advanced usage\n */\nexport function getTransporter() {\n return transporter;\n}\n\nexport { transporter };\n`],\n [\"frontend/react/web-base/src/components/ui/skeleton.tsx.hbs\", `import { cn } from \"@/lib/utils\";\n\nfunction Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n data-slot=\"skeleton\"\n className={cn(\"bg-muted rounded-none animate-pulse\", className)}\n {...props}\n />\n );\n}\n\nexport { Skeleton };\n`],\n [\"frontend/react/web-base/src/components/ui/dropdown-menu.tsx.hbs\", `import * as React from 'react'\nimport { Menu as MenuPrimitive } from '@base-ui/react/menu'\n\nimport { CheckIcon, ChevronRightIcon } from 'lucide-react'\nimport { cn } from '@/lib/utils'\n\nfunction DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {\n return <MenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {\n return <MenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n}\n\nfunction DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {\n return <MenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />\n}\n\nfunction DropdownMenuContent({\n align = 'start',\n alignOffset = 0,\n side = 'bottom',\n sideOffset = 4,\n className,\n ...props\n}: MenuPrimitive.Popup.Props &\n Pick<\n MenuPrimitive.Positioner.Props,\n 'align' | 'alignOffset' | 'side' | 'sideOffset'\n >) {\n return (\n <MenuPrimitive.Portal>\n <MenuPrimitive.Positioner\n className=\"isolate z-50 outline-none\"\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n >\n <MenuPrimitive.Popup\n data-slot=\"dropdown-menu-content\"\n className={cn(\n 'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground min-w-32 rounded-none shadow-md ring-1 duration-100 z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto outline-none data-closed:overflow-hidden',\n className,\n )}\n {...props}\n />\n </MenuPrimitive.Positioner>\n </MenuPrimitive.Portal>\n )\n}\n\nfunction DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {\n return <MenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: MenuPrimitive.GroupLabel.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.GroupLabel\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n 'text-muted-foreground px-2 py-2 text-xs data-[inset]:pl-8',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = 'default',\n ...props\n}: MenuPrimitive.Item.Props & {\n inset?: boolean\n variant?: 'default' | 'destructive'\n}) {\n return (\n <MenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2 rounded-none px-2 py-2 text-xs [&_svg:not([class*='size-'])]:size-4 group/dropdown-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {\n return <MenuPrimitive.SubmenuRoot data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: MenuPrimitive.SubmenuTrigger.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.SubmenuTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2 rounded-none px-2 py-2 text-xs [&_svg:not([class*='size-'])]:size-4 flex cursor-default items-center outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto\" />\n </MenuPrimitive.SubmenuTrigger>\n )\n}\n\nfunction DropdownMenuSubContent({\n align = 'start',\n alignOffset = -3,\n side = 'right',\n sideOffset = 0,\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuContent>) {\n return (\n <DropdownMenuContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n 'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground min-w-[96px] rounded-none shadow-lg ring-1 duration-100 w-auto',\n className,\n )}\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: MenuPrimitive.CheckboxItem.Props) {\n return (\n <MenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2 rounded-none py-2 pr-8 pl-2 text-xs [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span\n className=\"pointer-events-none absolute right-2 flex items-center justify-center pointer-events-none\"\n data-slot=\"dropdown-menu-checkbox-item-indicator\"\n >\n <MenuPrimitive.CheckboxItemIndicator>\n <CheckIcon />\n </MenuPrimitive.CheckboxItemIndicator>\n </span>\n {children}\n </MenuPrimitive.CheckboxItem>\n )\n}\n\nfunction DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {\n return (\n <MenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: MenuPrimitive.RadioItem.Props) {\n return (\n <MenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2 rounded-none py-2 pr-8 pl-2 text-xs [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n className,\n )}\n {...props}\n >\n <span\n className=\"pointer-events-none absolute right-2 flex items-center justify-center pointer-events-none\"\n data-slot=\"dropdown-menu-radio-item-indicator\"\n >\n <MenuPrimitive.RadioItemIndicator>\n <CheckIcon />\n </MenuPrimitive.RadioItemIndicator>\n </span>\n {children}\n </MenuPrimitive.RadioItem>\n )\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: MenuPrimitive.Separator.Props) {\n return (\n <MenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn('bg-border -mx-1 h-px', className)}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n 'text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground ml-auto text-xs tracking-widest',\n className,\n )}\n {...props}\n />\n )\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n}\n`],\n [\"frontend/react/web-base/src/components/ui/label.tsx.hbs\", `'use client'\n\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nfunction Label({ className, ...props }: React.ComponentProps<'label'>) {\n return (\n <label\n data-slot=\"label\"\n className={cn(\n 'gap-2 text-xs leading-none group-data-[disabled=true]:opacity-50 peer-disabled:opacity-50 flex items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed',\n className,\n )}\n {...props}\n />\n )\n}\n\nexport { Label }\n`],\n [\"frontend/react/web-base/src/components/ui/button.tsx.hbs\", `import { Button as ButtonPrimitive } from '@base-ui/react/button'\nimport { cva } from 'class-variance-authority'\nimport type {VariantProps} from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils'\n\nconst buttonVariants = cva(\n \"focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-none border border-transparent bg-clip-padding text-xs font-medium focus-visible:ring-1 aria-invalid:ring-1 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none\",\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground [a]:hover:bg-primary/80',\n outline:\n 'border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground',\n ghost:\n 'hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground',\n destructive:\n 'bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default:\n 'h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2',\n xs: \"h-6 gap-1 rounded-none px-2 text-xs has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-7 gap-1 rounded-none px-2.5 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5\",\n lg: 'h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3',\n icon: 'size-8',\n 'icon-xs': \"size-6 rounded-none [&_svg:not([class*='size-'])]:size-3\",\n 'icon-sm': 'size-7 rounded-none',\n 'icon-lg': 'size-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n)\n\nfunction Button({\n className,\n variant = 'default',\n size = 'default',\n ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n`],\n [\"frontend/react/web-base/src/components/ui/checkbox.tsx.hbs\", `import { Checkbox as CheckboxPrimitive } from '@base-ui/react/checkbox'\n\nimport { CheckIcon } from 'lucide-react'\nimport { cn } from '@/lib/utils'\n\nfunction Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n 'border-input dark:bg-input/30 data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 flex size-4 items-center justify-center rounded-none border transition-colors group-has-disabled/field:opacity-50 focus-visible:ring-1 aria-invalid:ring-1 peer relative shrink-0 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"[&>svg]:size-3.5 grid place-content-center text-current transition-none\"\n >\n <CheckIcon />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n )\n}\n\nexport { Checkbox }\n`],\n [\"frontend/react/web-base/src/components/ui/input.tsx.hbs\", `import * as React from 'react'\nimport { Input as InputPrimitive } from '@base-ui/react/input'\n\nimport { cn } from '@/lib/utils'\n\nfunction Input({ className, type, ...props }: React.ComponentProps<'input'>) {\n return (\n <InputPrimitive\n type={type}\n data-slot=\"input\"\n className={cn(\n 'dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 rounded-none border bg-transparent px-2.5 py-1 text-xs transition-colors file:h-6 file:text-xs file:font-medium focus-visible:ring-1 aria-invalid:ring-1 md:text-xs file:text-foreground placeholder:text-muted-foreground w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n />\n )\n}\n\nexport { Input }\n`],\n [\"frontend/react/web-base/src/components/ui/sonner.tsx.hbs\", `import { useTheme } from 'next-themes'\nimport { Toaster as Sonner } from 'sonner'\nimport {\n CircleCheckIcon,\n InfoIcon,\n Loader2Icon,\n OctagonXIcon,\n TriangleAlertIcon,\n} from 'lucide-react'\nimport type {ToasterProps} from 'sonner';\n\nconst Toaster = ({ ...props }: ToasterProps) => {\n const { theme = 'system' } = useTheme()\n\n return (\n <Sonner\n theme={theme as ToasterProps['theme']}\n className=\"toaster group\"\n icons=\\\\{{\n success: <CircleCheckIcon className=\"size-4\" />,\n info: <InfoIcon className=\"size-4\" />,\n warning: <TriangleAlertIcon className=\"size-4\" />,\n error: <OctagonXIcon className=\"size-4\" />,\n loading: <Loader2Icon className=\"size-4 animate-spin\" />,\n }}\n style={\n {\n '--normal-bg': 'var(--popover)',\n '--normal-text': 'var(--popover-foreground)',\n '--normal-border': 'var(--border)',\n '--border-radius': 'var(--radius)',\n } as React.CSSProperties\n }\n toastOptions=\\\\{{\n classNames: {\n toast: 'cn-toast',\n },\n }}\n {...props}\n />\n )\n}\n\nexport { Toaster }\n`],\n [\"frontend/react/web-base/src/components/ui/card.tsx.hbs\", `import * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nfunction Card({\n className,\n size = 'default',\n ...props\n}: React.ComponentProps<'div'> & { size?: 'default' | 'sm' }) {\n return (\n <div\n data-slot=\"card\"\n data-size={size}\n className={cn(\n 'ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-none py-4 text-xs/relaxed ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-2 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none group/card flex flex-col',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n 'gap-1 rounded-none px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\n 'text-sm font-medium group-data-[size=sm]/card:text-sm',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn('text-muted-foreground text-xs/relaxed', className)}\n {...props}\n />\n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\n 'col-start-2 row-span-2 row-start-1 self-start justify-self-end',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn('px-4 group-data-[size=sm]/card:px-3', className)}\n {...props}\n />\n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\n 'rounded-none border-t p-4 group-data-[size=sm]/card:p-3 flex items-center',\n className,\n )}\n {...props}\n />\n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n`],\n [\"job-queue/temporal/server/base/src/temporal/client.ts.hbs\", `import { Client, Connection } from \"@temporalio/client\";\n\n/**\n * Temporal client configuration\n * @see https://docs.temporal.io/develop/typescript/core-application\n */\n\nlet client: Client | null = null;\n\n/**\n * Get or create a Temporal client connection\n * Reuses existing connection if available\n */\nexport async function getTemporalClient(): Promise<Client> {\n if (client) {\n return client;\n }\n\n const connection = await Connection.connect({\n // Connect to Temporal server (default: localhost:7233)\n // Use TEMPORAL_ADDRESS env var for custom server address\n address: process.env.TEMPORAL_ADDRESS || \"localhost:7233\",\n });\n\n client = new Client({\n connection,\n // Namespace to use (default: \"default\")\n namespace: process.env.TEMPORAL_NAMESPACE || \"default\",\n });\n\n return client;\n}\n\n/**\n * Close the Temporal client connection\n * Call this during graceful shutdown\n */\nexport async function closeTemporalClient(): Promise<void> {\n if (client) {\n await client.connection.close();\n client = null;\n }\n}\n`],\n [\"job-queue/temporal/server/base/src/temporal/activities.ts.hbs\", `/**\n * Temporal Activities\n *\n * Activities are the building blocks of workflows - they perform the actual work.\n * Activities can make network calls, interact with databases, or perform any side effects.\n * They automatically retry on failure based on configuration.\n *\n * @see https://docs.temporal.io/develop/typescript/core-application#develop-activities\n */\n\n// Activity context provides utilities like heartbeating for long-running activities\n// import { Context } from \"@temporalio/activity\";\n\n/**\n * Send an email activity\n * @param to - Recipient email address\n * @param subject - Email subject\n * @param body - Email body content\n */\nexport async function sendEmail(\n to: string,\n subject: string,\n body: string\n): Promise<{ sent: boolean; timestamp: string }> {\n // TODO: Implement your email sending logic here\n // Example with a hypothetical email service:\n // await emailService.send({ to, subject, body });\n\n // Simulate email sending\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n console.log(\\`[Activity] Sending email to \\${to}: \\${subject}\\`);\n\n return {\n sent: true,\n timestamp: new Date().toISOString(),\n };\n}\n\n/**\n * Send a notification activity\n * @param userId - User ID to send notification to\n * @param type - Notification type: \"push\" | \"in-app\" | \"sms\"\n * @param message - Notification message\n */\nexport async function sendNotification(\n userId: string,\n type: \"push\" | \"in-app\" | \"sms\",\n message: string\n): Promise<{ sent: boolean; type: string; timestamp: string }> {\n // TODO: Implement your notification logic here\n // switch (type) {\n // case \"push\":\n // await pushService.send(userId, message);\n // break;\n // case \"in-app\":\n // await inAppNotificationService.create(userId, message);\n // break;\n // case \"sms\":\n // await smsService.send(userId, message);\n // break;\n // }\n\n // Simulate notification sending\n await new Promise((resolve) => setTimeout(resolve, 500));\n\n console.log(\\`[Activity] Sending \\${type} notification to user \\${userId}: \\${message}\\`);\n\n return {\n sent: true,\n type,\n timestamp: new Date().toISOString(),\n };\n}\n\n/**\n * Process data activity\n * @param dataId - ID of the data to process\n * @param operation - Operation to perform: \"transform\" | \"aggregate\" | \"export\"\n */\nexport async function processData(\n dataId: string,\n operation: \"transform\" | \"aggregate\" | \"export\"\n): Promise<{ processed: boolean; dataId: string; operation: string }> {\n // TODO: Implement your data processing logic here\n // const data = await database.getData(dataId);\n // switch (operation) {\n // case \"transform\":\n // return await transformData(data);\n // case \"aggregate\":\n // return await aggregateData(data);\n // case \"export\":\n // return await exportData(data);\n // }\n\n // For long-running activities, use heartbeating to report progress\n // const ctx = Context.current();\n // ctx.heartbeat(\"Processing started\");\n\n // Simulate data processing\n await new Promise((resolve) => setTimeout(resolve, 2000));\n\n console.log(\\`[Activity] Processing data \\${dataId} with operation \\${operation}\\`);\n\n return {\n processed: true,\n dataId,\n operation,\n };\n}\n\n/**\n * Cleanup activity for scheduled jobs\n * Removes expired sessions, clears stale cache, etc.\n */\nexport async function performCleanup(): Promise<{ cleaned: boolean; timestamp: string }> {\n // TODO: Implement your cleanup logic here\n // await database.deleteExpiredSessions();\n // await cache.clearStale();\n\n // Simulate cleanup\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n console.log(\"[Activity] Performing scheduled cleanup\");\n\n return {\n cleaned: true,\n timestamp: new Date().toISOString(),\n };\n}\n\n/**\n * Generate daily report activity\n */\nexport async function generateReport(): Promise<{\n generatedAt: string;\n metrics: { users: number; events: number };\n}> {\n // TODO: Implement your report generation logic here\n // const stats = await analytics.getDailyStats();\n // return generateReportData(stats);\n\n // Simulate report generation\n await new Promise((resolve) => setTimeout(resolve, 2000));\n\n console.log(\"[Activity] Generating daily report\");\n\n return {\n generatedAt: new Date().toISOString(),\n metrics: {\n users: 100,\n events: 500,\n },\n };\n}\n\n/**\n * Fetch user data activity\n * @param userId - User ID to fetch data for\n */\nexport async function fetchUserData(\n userId: string\n): Promise<{ userId: string; email: string; name: string }> {\n // TODO: Implement your user data fetching logic\n // return await database.getUser(userId);\n\n // Simulate database fetch\n await new Promise((resolve) => setTimeout(resolve, 300));\n\n return {\n userId,\n email: \\`user-\\${userId}@example.com\\`,\n name: \\`User \\${userId}\\`,\n };\n}\n`],\n [\"job-queue/temporal/server/base/src/temporal/worker.ts.hbs\", `import { Worker, NativeConnection } from \"@temporalio/worker\";\n\nimport * as activities from \"./activities\";\n\n/**\n * Temporal Worker Configuration\n *\n * Workers execute workflows and activities. You can run multiple workers\n * for scalability - they will automatically coordinate via the Temporal server.\n *\n * @see https://docs.temporal.io/develop/typescript/core-application#run-a-dev-worker\n */\n\nconst TASK_QUEUE = process.env.TEMPORAL_TASK_QUEUE || \"{{projectName}}-task-queue\";\n\n/**\n * Create and run a Temporal worker\n */\nexport async function runWorker(): Promise<void> {\n // Connect to the Temporal server\n const connection = await NativeConnection.connect({\n address: process.env.TEMPORAL_ADDRESS || \"localhost:7233\",\n });\n\n try {\n // Create a worker that connects to the server and executes workflows/activities\n const worker = await Worker.create({\n connection,\n namespace: process.env.TEMPORAL_NAMESPACE || \"default\",\n taskQueue: TASK_QUEUE,\n // Point to compiled workflow file for bundling\n workflowsPath: require.resolve(\"./workflows\"),\n // Register activities directly\n activities,\n // Optional: Configure worker behavior\n maxConcurrentActivityTaskExecutions: 100,\n maxConcurrentWorkflowTaskExecutions: 100,\n });\n\n // Start accepting tasks\n console.log(\\`[Temporal Worker] Starting worker on task queue: \\${TASK_QUEUE}\\`);\n await worker.run();\n } finally {\n // Ensure we close the connection when shutting down\n await connection.close();\n }\n}\n\n/**\n * Run the worker when this file is executed directly\n * Usage: npx ts-node src/temporal/worker.ts\n */\nif (require.main === module) {\n runWorker().catch((err) => {\n console.error(\"[Temporal Worker] Failed to start:\", err);\n process.exit(1);\n });\n}\n`],\n [\"job-queue/temporal/server/base/src/temporal/workflows.ts.hbs\", `/**\n * Temporal Workflows\n *\n * Workflows are the core abstraction in Temporal. They orchestrate activities\n * and other workflows, and are durable - they survive process restarts.\n *\n * IMPORTANT: Workflow code must be deterministic!\n * - No direct I/O, network calls, or random number generation\n * - Use activities for any non-deterministic operations\n * - Use workflow.sleep instead of setTimeout\n *\n * @see https://docs.temporal.io/develop/typescript/core-application#develop-workflows\n */\n\nimport { proxyActivities, sleep, defineSignal, setHandler, condition } from \"@temporalio/workflow\";\n\n// Import activity types for type-safe proxy\nimport type * as activities from \"./activities\";\n\n// Create activity proxies with retry policies\nconst { sendEmail, sendNotification, processData, performCleanup, generateReport, fetchUserData } =\n proxyActivities<typeof activities>({\n // Default activity options\n startToCloseTimeout: \"1 minute\",\n retry: {\n initialInterval: \"1 second\",\n maximumInterval: \"1 minute\",\n backoffCoefficient: 2,\n maximumAttempts: 3,\n },\n });\n\n// Define signals for workflow interaction\nexport const cancelSignal = defineSignal(\"cancel\");\n\n/**\n * Email sending workflow\n * Simple workflow that sends a single email\n */\nexport async function sendEmailWorkflow(\n to: string,\n subject: string,\n body: string\n): Promise<{ sent: boolean; timestamp: string }> {\n return await sendEmail(to, subject, body);\n}\n\n/**\n * Notification workflow\n * Sends a notification to a user\n */\nexport async function sendNotificationWorkflow(\n userId: string,\n type: \"push\" | \"in-app\" | \"sms\",\n message: string\n): Promise<{ sent: boolean; type: string; timestamp: string }> {\n return await sendNotification(userId, type, message);\n}\n\n/**\n * Data processing workflow with cancellation support\n * Demonstrates multi-step workflow with signal handling\n */\nexport async function processDataWorkflow(\n dataId: string,\n operation: \"transform\" | \"aggregate\" | \"export\"\n): Promise<{ processed: boolean; dataId: string; operation: string; timestamp: string }> {\n let cancelled = false;\n\n // Set up cancellation signal handler\n setHandler(cancelSignal, () => {\n cancelled = true;\n });\n\n // Step 1: Validate input\n if (!dataId) {\n throw new Error(\"Data ID is required\");\n }\n\n // Check for cancellation\n if (cancelled) {\n return {\n processed: false,\n dataId,\n operation,\n timestamp: new Date().toISOString(),\n };\n }\n\n // Step 2: Process data\n const result = await processData(dataId, operation);\n\n // Step 3: Send completion notification\n await sendNotification(\"system\", \"in-app\", \\`Data \\${dataId} has been \\${operation}ed successfully\\`);\n\n return {\n ...result,\n timestamp: new Date().toISOString(),\n };\n}\n\n/**\n * Scheduled cleanup workflow\n * Can be started with a cron schedule\n *\n * Start with: client.schedule.create({\n * scheduleId: \"hourly-cleanup\",\n * spec: { cronExpressions: [\"0 * * * *\"] },\n * action: { type: \"startWorkflow\", workflowType: \"cleanupWorkflow\", ... }\n * })\n */\nexport async function cleanupWorkflow(): Promise<{ cleaned: boolean; timestamp: string }> {\n return await performCleanup();\n}\n\n/**\n * Daily report workflow\n * Generates a report and sends it via email\n *\n * Start with cron schedule: \"0 9 * * *\" (9 AM daily)\n */\nexport async function dailyReportWorkflow(): Promise<{\n reportGenerated: boolean;\n timestamp: string;\n}> {\n // Step 1: Generate report\n const reportData = await generateReport();\n\n // Step 2: Send report via email\n await sendEmail(\n \"admin@example.com\",\n \"Daily Report\",\n \\`Daily metrics: \\${JSON.stringify(reportData.metrics)}\\`\n );\n\n return {\n reportGenerated: true,\n timestamp: new Date().toISOString(),\n };\n}\n\n/**\n * Welcome sequence workflow\n * Demonstrates long-running workflow with delays\n *\n * This workflow sends a series of emails over several days:\n * - Immediate: Welcome email\n * - After 1 day: Tips email\n * - After 3 more days: Feature highlight email\n */\nexport async function welcomeSequenceWorkflow(\n userId: string\n): Promise<{ completed: boolean; userId: string; timestamp: string }> {\n // Fetch user data\n const user = await fetchUserData(userId);\n\n // Send immediate welcome email\n await sendEmail(user.email, \"Welcome to {{projectName}}!\", \\`Hi \\${user.name}, welcome aboard!\\`);\n\n // Wait 1 day before sending tips email\n await sleep(\"1 day\");\n\n await sendEmail(\n user.email,\n \"Getting Started Tips\",\n \\`Hi \\${user.name}, here are some tips to get the most out of {{projectName}}...\\`\n );\n\n // Wait 3 more days before sending feature highlight\n await sleep(\"3 days\");\n\n await sendEmail(\n user.email,\n \"Discover More Features\",\n \\`Hi \\${user.name}, have you tried these features yet?\\`\n );\n\n return {\n completed: true,\n userId,\n timestamp: new Date().toISOString(),\n };\n}\n\n/**\n * Order processing workflow\n * Example of a saga pattern with compensation\n */\nexport async function orderProcessingWorkflow(orderId: string): Promise<{\n success: boolean;\n orderId: string;\n steps: string[];\n}> {\n const completedSteps: string[] = [];\n\n try {\n // Step 1: Validate order\n completedSteps.push(\"validated\");\n\n // Step 2: Reserve inventory (simulated with notification)\n await sendNotification(\"system\", \"in-app\", \\`Reserving inventory for order \\${orderId}\\`);\n completedSteps.push(\"inventory_reserved\");\n\n // Step 3: Process payment (simulated)\n await sendNotification(\"system\", \"in-app\", \\`Processing payment for order \\${orderId}\\`);\n completedSteps.push(\"payment_processed\");\n\n // Step 4: Ship order (simulated)\n await sendNotification(\"system\", \"in-app\", \\`Shipping order \\${orderId}\\`);\n completedSteps.push(\"shipped\");\n\n // Step 5: Send confirmation email\n await sendEmail(\"customer@example.com\", \"Order Confirmed\", \\`Your order \\${orderId} has shipped!\\`);\n completedSteps.push(\"notification_sent\");\n\n return {\n success: true,\n orderId,\n steps: completedSteps,\n };\n } catch (error) {\n // Compensation logic would go here\n // For example: release inventory, refund payment, etc.\n return {\n success: false,\n orderId,\n steps: completedSteps,\n };\n }\n}\n\n/**\n * Batch processing workflow with child workflows\n * Demonstrates parent-child workflow pattern\n */\nexport async function batchEmailWorkflow(\n recipients: Array<{ email: string; subject: string; body: string }>\n): Promise<{ sent: number; failed: number }> {\n let sent = 0;\n let failed = 0;\n\n for (const recipient of recipients) {\n try {\n await sendEmail(recipient.email, recipient.subject, recipient.body);\n sent++;\n } catch {\n failed++;\n }\n }\n\n return { sent, failed };\n}\n`],\n [\"payments/lemon-squeezy/web/solid/src/routes/success.tsx.hbs\", `import { useSearchParams } from \"@solidjs/router\";\n\nexport default function SuccessPage() {\n\tconst [searchParams] = useSearchParams();\n\n\treturn (\n\t\t<div class=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 class=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p class=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t{searchParams.checkout_id && (\n\t\t\t\t<p class=\"text-sm text-gray-500\">Checkout ID: {searchParams.checkout_id}</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n`],\n [\"auth/better-auth/native/unistyles/app/(drawer)/index.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { ScrollView, Text, TouchableOpacity, View } from \"react-native\";\nimport { StyleSheet } from \"react-native-unistyles\";\n\nimport { Container } from \"@/components/container\";\nimport { SignIn } from \"@/components/sign-in\";\nimport { SignUp } from \"@/components/sign-up\";\n{{#if (eq api \"orpc\")}}\nimport { useQuery } from \"@tanstack/react-query\";\nimport { queryClient, orpc } from \"@/utils/orpc\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { useQuery } from \"@tanstack/react-query\";\nimport { queryClient, trpc } from \"@/utils/trpc\";\n{{/if}}\n\nexport default function Home() {\n {{#if (eq api \"orpc\")}}\n const healthCheck = useQuery(orpc.healthCheck.queryOptions());\n const privateData = useQuery(orpc.privateData.queryOptions());\n {{/if}}\n {{#if (eq api \"trpc\")}}\n const healthCheck = useQuery(trpc.healthCheck.queryOptions());\n const privateData = useQuery(trpc.privateData.queryOptions());\n {{/if}}\n const { data: session } = authClient.useSession();\n\n return (\n <Container>\n <ScrollView>\n <View style={styles.pageContainer}>\n <Text style={styles.headerTitle}>BETTER T STACK</Text>\n {session?.user ? (\n <View style={styles.sessionInfoCard}>\n <View style={styles.sessionUserRow}>\n <Text style={styles.welcomeText}>\n Welcome,{\" \"}\n <Text style={styles.userNameText}>{session.user.name}</Text>\n </Text>\n </View>\n <Text style={styles.emailText}>{session.user.email}</Text>\n\n <TouchableOpacity\n style={styles.signOutButton}\n onPress={() => {\n authClient.signOut();\n {{#if (eq api \"orpc\")}}\n queryClient.invalidateQueries();\n {{/if}}\n {{#if (eq api \"trpc\")}}\n queryClient.invalidateQueries();\n {{/if}}\n }}\n >\n <Text style={styles.signOutButtonText}>Sign Out</Text>\n </TouchableOpacity>\n </View>\n ) : null}\n {{#unless (eq api \"none\")}}\n <View style={styles.apiStatusCard}>\n <Text style={styles.cardTitle}>API Status</Text>\n <View style={styles.apiStatusRow}>\n <View\n style={[\n styles.statusIndicatorDot,\n healthCheck.data\n ? styles.statusIndicatorGreen\n : styles.statusIndicatorRed,\n ]}\n />\n <Text style={styles.mutedText}>\n {healthCheck.isLoading\n ? \"Checking...\"\n : healthCheck.data\n ? \"Connected to API\"\n : \"API Disconnected\"}\n </Text>\n </View>\n </View>\n <View style={styles.privateDataCard}>\n <Text style={styles.cardTitle}>Private Data</Text>\n {privateData && (\n <View>\n <Text style={styles.mutedText}>\n {privateData.data?.message}\n </Text>\n </View>\n )}\n </View>\n {{/unless}}\n {!session?.user && (\n <>\n <SignIn />\n <SignUp />\n </>\n )}\n </View>\n </ScrollView>\n </Container>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n pageContainer: {\n paddingHorizontal: 8,\n },\n headerTitle: {\n color: theme?.colors?.typography,\n fontSize: 30,\n fontWeight: \"bold\",\n marginBottom: 16,\n },\n sessionInfoCard: {\n marginBottom: 24,\n padding: 16,\n borderRadius: 8,\n borderWidth: 1,\n borderColor: theme?.colors?.border,\n },\n sessionUserRow: {\n flexDirection: \"row\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: 8,\n },\n welcomeText: {\n color: theme?.colors?.typography,\n fontSize: 16,\n },\n userNameText: {\n fontWeight: \"500\",\n color: theme?.colors?.typography,\n },\n emailText: {\n color: theme?.colors?.typography,\n fontSize: 14,\n marginBottom: 16,\n },\n signOutButton: {\n backgroundColor: theme?.colors?.destructive,\n paddingVertical: 8,\n paddingHorizontal: 16,\n borderRadius: 6,\n alignSelf: \"flex-start\",\n },\n signOutButtonText: {\n fontWeight: \"500\",\n },\n apiStatusCard: {\n marginBottom: 24,\n borderRadius: 8,\n borderWidth: 1,\n borderColor: theme?.colors?.border,\n padding: 16,\n },\n cardTitle: {\n marginBottom: 12,\n fontWeight: \"500\",\n color: theme?.colors?.typography,\n },\n apiStatusRow: {\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: 8,\n },\n statusIndicatorDot: {\n height: 12,\n width: 12,\n borderRadius: 9999,\n },\n statusIndicatorGreen: {\n backgroundColor: theme.colors.success,\n },\n statusIndicatorRed: {\n backgroundColor: theme.colors.destructive,\n },\n mutedText: {\n color: theme?.colors?.typography,\n },\n privateDataCard: {\n marginBottom: 24,\n borderRadius: 8,\n borderWidth: 1,\n borderColor: theme?.colors?.border,\n padding: 16,\n },\n}));\n`],\n [\"email/mailgun/server/base/src/lib/email.ts.hbs\", `import Mailgun from \"mailgun.js\";\nimport FormData from \"form-data\";\n\n// Initialize Mailgun client\nconst mailgun = new Mailgun(FormData);\nconst mg = mailgun.client({\n username: \"api\",\n key: process.env.MAILGUN_API_KEY || \"\",\n});\n\nconst DOMAIN = process.env.MAILGUN_DOMAIN || \"\";\n\nexport interface SendEmailOptions {\n to: string | string[];\n subject: string;\n html?: string;\n text?: string;\n from?: string;\n replyTo?: string;\n cc?: string | string[];\n bcc?: string | string[];\n attachments?: Array<{\n filename: string;\n data: Buffer | string;\n contentType?: string;\n }>;\n tags?: string[];\n trackingClicks?: boolean;\n trackingOpens?: boolean;\n}\n\n/**\n * Send an email using Mailgun\n * @see https://documentation.mailgun.com/en/latest/api-sending-messages.html\n */\nexport async function sendEmail(options: SendEmailOptions) {\n const {\n to,\n subject,\n html,\n text,\n from,\n replyTo,\n cc,\n bcc,\n attachments,\n tags,\n trackingClicks,\n trackingOpens,\n } = options;\n\n const fromAddress = from || process.env.MAILGUN_FROM_EMAIL || \"noreply@example.com\";\n const toAddresses = Array.isArray(to) ? to.join(\",\") : to;\n\n try {\n const messageData: Record<string, unknown> = {\n from: fromAddress,\n to: toAddresses,\n subject,\n };\n\n if (html) messageData.html = html;\n if (text) messageData.text = text;\n if (replyTo) messageData[\"h:Reply-To\"] = replyTo;\n if (cc) messageData.cc = Array.isArray(cc) ? cc.join(\",\") : cc;\n if (bcc) messageData.bcc = Array.isArray(bcc) ? bcc.join(\",\") : bcc;\n if (tags) messageData[\"o:tag\"] = tags;\n if (trackingClicks !== undefined) messageData[\"o:tracking-clicks\"] = trackingClicks ? \"yes\" : \"no\";\n if (trackingOpens !== undefined) messageData[\"o:tracking-opens\"] = trackingOpens ? \"yes\" : \"no\";\n\n if (attachments && attachments.length > 0) {\n messageData.attachment = attachments.map((att) => ({\n filename: att.filename,\n data: att.data,\n contentType: att.contentType,\n }));\n }\n\n const response = await mg.messages.create(DOMAIN, messageData);\n console.log(\"Email sent:\", response.id);\n return { success: true, messageId: response.id };\n } catch (error) {\n console.error(\"Email sending error:\", error);\n throw error;\n }\n}\n\n/**\n * Send multiple emails in a batch using Mailgun's recipient variables\n * @see https://documentation.mailgun.com/en/latest/user_manual.html#batch-sending\n */\nexport async function sendBatchEmails(\n emails: Array<{\n to: string;\n subject: string;\n html?: string;\n text?: string;\n variables?: Record<string, string>;\n }>,\n commonOptions?: {\n from?: string;\n tags?: string[];\n }\n) {\n const fromAddress =\n commonOptions?.from || process.env.MAILGUN_FROM_EMAIL || \"noreply@example.com\";\n\n // Mailgun batch sending uses recipient variables\n const recipients = emails.map((e) => e.to);\n const recipientVariables: Record<string, Record<string, string>> = {};\n\n for (const email of emails) {\n if (email.variables) {\n recipientVariables[email.to] = email.variables;\n }\n }\n\n try {\n // For batch emails, we use the first email as template\n const firstEmail = emails[0];\n if (!firstEmail) throw new Error(\"No emails provided\");\n\n const messageData: Record<string, unknown> = {\n from: fromAddress,\n to: recipients,\n subject: firstEmail.subject,\n \"recipient-variables\": JSON.stringify(recipientVariables),\n };\n\n if (firstEmail.html) messageData.html = firstEmail.html;\n if (firstEmail.text) messageData.text = firstEmail.text;\n if (commonOptions?.tags) messageData[\"o:tag\"] = commonOptions.tags;\n\n const response = await mg.messages.create(DOMAIN, messageData);\n console.log(\\`Batch of \\${emails.length} emails queued:\\`, response.id);\n return { success: true, messageId: response.id };\n } catch (error) {\n console.error(\"Batch email sending error:\", error);\n throw error;\n }\n}\n\n/**\n * Send an email using a Mailgun template\n * @see https://documentation.mailgun.com/en/latest/api-sending-messages.html#sending-via-api\n */\nexport async function sendTemplateEmail(options: {\n to: string | string[];\n template: string;\n variables: Record<string, string>;\n subject?: string;\n from?: string;\n tags?: string[];\n}) {\n const { to, template, variables, subject, from, tags } = options;\n\n const fromAddress = from || process.env.MAILGUN_FROM_EMAIL || \"noreply@example.com\";\n const toAddresses = Array.isArray(to) ? to.join(\",\") : to;\n\n try {\n const messageData: Record<string, unknown> = {\n from: fromAddress,\n to: toAddresses,\n template,\n \"h:X-Mailgun-Variables\": JSON.stringify(variables),\n };\n\n if (subject) messageData.subject = subject;\n if (tags) messageData[\"o:tag\"] = tags;\n\n const response = await mg.messages.create(DOMAIN, messageData);\n console.log(\"Template email sent:\", response.id);\n return { success: true, messageId: response.id };\n } catch (error) {\n console.error(\"Template email sending error:\", error);\n throw error;\n }\n}\n\n/**\n * Validate an email address using Mailgun's email validation API\n * Note: This requires the email validation feature to be enabled on your account\n * @see https://documentation.mailgun.com/en/latest/api-email-validation.html\n */\nexport async function validateEmail(email: string) {\n try {\n const result = await mg.validate.get(email);\n return {\n valid: result.is_valid,\n didYouMean: result.did_you_mean,\n isDisposable: result.is_disposable_address,\n isRoleAddress: result.is_role_address,\n };\n } catch (error) {\n console.error(\"Email validation error:\", error);\n throw error;\n }\n}\n\n/**\n * Get the Mailgun client for advanced usage\n */\nexport function getMailgunClient() {\n return mg;\n}\n\nexport { mg as mailgun };\n`],\n [\"frontend/angular/src/app/pages/home/home.component.ts.hbs\", `import { Component } from '@angular/core';\n\n@Component({\n selector: 'app-home',\n standalone: true,\n template: \\`\n {{#if (eq cssFramework \"tailwind\")}}\n <div class=\"container mx-auto max-w-3xl px-4 py-2\">\n <pre class=\"overflow-x-auto font-mono text-sm whitespace-pre\">{{ titleText }}</pre>\n <div class=\"grid gap-6 mt-6\">\n <section class=\"rounded-lg border border-gray-200 dark:border-gray-800 p-4\">\n <h2 class=\"mb-2 font-medium\">Welcome to Angular</h2>\n <p class=\"text-sm text-gray-600 dark:text-gray-400\">\n Angular is a platform and framework for building single-page client applications\n using HTML and TypeScript. It implements core and optional functionality as a\n set of TypeScript libraries that you import into your applications.\n </p>\n </section>\n <section class=\"rounded-lg border border-gray-200 dark:border-gray-800 p-4\">\n <h2 class=\"mb-2 font-medium\">Key Features</h2>\n <ul class=\"list-disc list-inside text-sm text-gray-600 dark:text-gray-400 space-y-1\">\n <li>Standalone components - No NgModule required</li>\n <li>Signals - Fine-grained reactivity</li>\n <li>Built-in routing and forms</li>\n <li>Dependency injection</li>\n </ul>\n </section>\n </div>\n </div>\n {{else}}\n <div [style.maxWidth]=\"'48rem'\" [style.margin]=\"'0 auto'\" [style.padding]=\"'0.5rem 1rem'\">\n <pre [style.overflow]=\"'auto'\" [style.fontFamily]=\"'monospace'\" [style.fontSize]=\"'0.875rem'\" [style.whiteSpace]=\"'pre'\">{{ titleText }}</pre>\n <div [style.display]=\"'grid'\" [style.gap]=\"'1.5rem'\" [style.marginTop]=\"'1.5rem'\">\n <section [style.borderRadius]=\"'0.5rem'\" [style.border]=\"'1px solid var(--border-color)'\" [style.padding]=\"'1rem'\">\n <h2 [style.marginBottom]=\"'0.5rem'\" [style.fontWeight]=\"500\">Welcome to Angular</h2>\n <p [style.fontSize]=\"'0.875rem'\" [style.color]=\"'var(--muted-color)'\">\n Angular is a platform and framework for building single-page client applications\n using HTML and TypeScript. It implements core and optional functionality as a\n set of TypeScript libraries that you import into your applications.\n </p>\n </section>\n <section [style.borderRadius]=\"'0.5rem'\" [style.border]=\"'1px solid var(--border-color)'\" [style.padding]=\"'1rem'\">\n <h2 [style.marginBottom]=\"'0.5rem'\" [style.fontWeight]=\"500\">Key Features</h2>\n <ul [style.fontSize]=\"'0.875rem'\" [style.color]=\"'var(--muted-color)'\" [style.listStyleType]=\"'disc'\" [style.paddingLeft]=\"'1.5rem'\">\n <li>Standalone components - No NgModule required</li>\n <li>Signals - Fine-grained reactivity</li>\n <li>Built-in routing and forms</li>\n <li>Dependency injection</li>\n </ul>\n </section>\n </div>\n </div>\n {{/if}}\n \\`,\n})\nexport class HomeComponent {\n titleText = \\`\n \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557 \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557\n \\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u2588\\\\u2588\\\\u2557\\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u255D\\\\u255A\\\\u2550\\\\u2550\\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u255D\\\\u255A\\\\u2550\\\\u2550\\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u255D\\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u255D\\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u2588\\\\u2588\\\\u2557\n \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2554\\\\u255D\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557 \\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557 \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2554\\\\u255D\n \\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u2588\\\\u2588\\\\u2557\\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u255D \\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u255D \\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u2588\\\\u2588\\\\u2557\n \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2554\\\\u255D\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557 \\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557\\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2557\n \\\\u255A\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u255D \\\\u255A\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u255D \\\\u255A\\\\u2550\\\\u255D \\\\u255A\\\\u2550\\\\u255D \\\\u255A\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u255D\\\\u255A\\\\u2550\\\\u255D \\\\u255A\\\\u2550\\\\u255D\n\n \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557 \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557 \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557 \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557\\\\u2588\\\\u2588\\\\u2557 \\\\u2588\\\\u2588\\\\u2557\n \\\\u255A\\\\u2550\\\\u2550\\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u255D \\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u255D\\\\u255A\\\\u2550\\\\u2550\\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u255D\\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u2588\\\\u2588\\\\u2557\\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u255D\\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2554\\\\u255D\n \\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557 \\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2551\\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2554\\\\u255D\n \\\\u2588\\\\u2588\\\\u2551 \\\\u255A\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2550\\\\u2588\\\\u2588\\\\u2551\\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2554\\\\u2550\\\\u2588\\\\u2588\\\\u2557\n \\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2551\\\\u255A\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2588\\\\u2557\\\\u2588\\\\u2588\\\\u2551 \\\\u2588\\\\u2588\\\\u2557\n \\\\u255A\\\\u2550\\\\u255D \\\\u255A\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u255D \\\\u255A\\\\u2550\\\\u255D \\\\u255A\\\\u2550\\\\u255D \\\\u255A\\\\u2550\\\\u255D \\\\u255A\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u2550\\\\u255D\\\\u255A\\\\u2550\\\\u255D \\\\u255A\\\\u2550\\\\u255D\n\\`;\n}\n`],\n [\"frontend/redwood/web/src/pages/FatalErrorPage/FatalErrorPage.tsx\", `// This page will be rendered when an error makes it all the way to the top of the\n// application without being handled by a Javascript catch statement.\n// https://redwoodjs.com/docs/app-configuration-redwood-toml#handleuncaughtexception\n\nexport default () => (\n <main>\n <style\n dangerouslySetInnerHTML={{\n __html: \\`\n html, body {\n margin: 0;\n }\n html * {\n box-sizing: border-box;\n }\n main {\n display: flex;\n align-items: center;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif;\n text-align: center;\n background-color: #0f172a;\n color: #f8fafc;\n height: 100vh;\n }\n section {\n background-color: #1e293b;\n border-radius: 0.25rem;\n width: 32rem;\n padding: 1rem;\n margin: 0 auto;\n box-shadow: 0 1px 3px rgba(0,0,0,0.5);\n }\n h1 {\n font-size: 2rem;\n margin: 0;\n font-weight: 500;\n line-height: 1;\n color: #ef4444;\n }\n p {\n color: #94a3b8;\n }\n \\`,\n }}\n />\n <section>\n <h1>\n <span>Something went wrong</span>\n </h1>\n <p>\n Sorry, something went wrong. Please try refreshing the page or contact support if the\n problem persists.\n </p>\n </section>\n </main>\n);\n`],\n [\"frontend/redwood/api/src/directives/requireAuth/requireAuth.ts\", `import type { ValidatorDirectiveFunc } from \"@redwoodjs/graphql-server\";\n\nimport { createValidatorDirective } from \"@redwoodjs/graphql-server\";\nimport gql from \"graphql-tag\";\nimport { requireAuth as applicationRequireAuth } from \"src/lib/auth\";\n\nexport const schema = gql\\`\n \"\"\"\n Use to check whether or not a user is authenticated and is associated\n with an optional set of roles.\n \"\"\"\n directive @requireAuth(roles: [String]) on FIELD_DEFINITION\n\\`;\n\ntype RequireAuthValidate = ValidatorDirectiveFunc<{ roles?: string[] }>;\n\nconst validate: RequireAuthValidate = ({ directiveArgs }) => {\n const { roles } = directiveArgs;\n applicationRequireAuth({ roles });\n};\n\nconst requireAuth = createValidatorDirective(schema, validate);\n\nexport default requireAuth;\n`],\n [\"frontend/redwood/api/src/directives/skipAuth/skipAuth.ts\", `import { createValidatorDirective } from \"@redwoodjs/graphql-server\";\nimport gql from \"graphql-tag\";\n\nexport const schema = gql\\`\n \"\"\"\n Use to skip authentication checks and allow public access.\n \"\"\"\n directive @skipAuth on FIELD_DEFINITION\n\\`;\n\nconst skipAuth = createValidatorDirective(schema, () => {\n return;\n});\n\nexport default skipAuth;\n`],\n [\"frontend/redwood/web/src/pages/NotFoundPage/NotFoundPage.tsx\", `export default () => (\n <main>\n <style\n dangerouslySetInnerHTML={{\n __html: \\`\n html, body {\n margin: 0;\n }\n html * {\n box-sizing: border-box;\n }\n main {\n display: flex;\n align-items: center;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif;\n text-align: center;\n background-color: #0f172a;\n color: #f8fafc;\n height: 100vh;\n }\n section {\n background-color: #1e293b;\n border-radius: 0.25rem;\n width: 32rem;\n padding: 1rem;\n margin: 0 auto;\n box-shadow: 0 1px 3px rgba(0,0,0,0.5);\n }\n h1 {\n font-size: 2rem;\n margin: 0;\n font-weight: 500;\n line-height: 1;\n color: #38bdf8;\n }\n \\`,\n }}\n />\n <section>\n <h1>\n <span>404 Page Not Found</span>\n </h1>\n </section>\n </main>\n);\n`],\n [\"frontend/redwood/web/src/pages/HomePage/HomePage.tsx.hbs\", `import { Link, routes } from '@redwoodjs/router'\nimport { Metadata } from '@redwoodjs/web'\n\nconst HomePage = () => {\n return (\n <>\n <Metadata title=\"Home\" description=\"Home page\" />\n\n <main{{#if (eq cssFramework \"tailwind\")}} className=\"min-h-screen bg-slate-900 text-slate-100 flex flex-col items-center justify-center p-8\"{{/if}}>\n <div{{#if (eq cssFramework \"tailwind\")}} className=\"max-w-4xl mx-auto text-center\"{{/if}}>\n <h1{{#if (eq cssFramework \"tailwind\")}} className=\"text-5xl font-bold text-cyan-400 mb-6\"{{/if}}>\n Welcome to RedwoodJS\n </h1>\n <p{{#if (eq cssFramework \"tailwind\")}} className=\"text-xl text-slate-300 mb-8\"{{/if}}>\n Built with the Better T Stack\n </p>\n\n <div{{#if (eq cssFramework \"tailwind\")}} className=\"grid grid-cols-1 md:grid-cols-3 gap-6 mt-12\"{{/if}}>\n <div{{#if (eq cssFramework \"tailwind\")}} className=\"bg-slate-800 p-6 rounded-lg border border-slate-700\"{{/if}}>\n <h3{{#if (eq cssFramework \"tailwind\")}} className=\"text-lg font-semibold text-cyan-400 mb-2\"{{/if}}>\n React Frontend\n </h3>\n <p{{#if (eq cssFramework \"tailwind\")}} className=\"text-slate-400 text-sm\"{{/if}}>\n Modern React with file-based routing and Cells for data fetching.\n </p>\n </div>\n\n <div{{#if (eq cssFramework \"tailwind\")}} className=\"bg-slate-800 p-6 rounded-lg border border-slate-700\"{{/if}}>\n <h3{{#if (eq cssFramework \"tailwind\")}} className=\"text-lg font-semibold text-cyan-400 mb-2\"{{/if}}>\n GraphQL API\n </h3>\n <p{{#if (eq cssFramework \"tailwind\")}} className=\"text-slate-400 text-sm\"{{/if}}>\n Type-safe GraphQL with auto-generated types and SDL-first schema.\n </p>\n </div>\n\n <div{{#if (eq cssFramework \"tailwind\")}} className=\"bg-slate-800 p-6 rounded-lg border border-slate-700\"{{/if}}>\n <h3{{#if (eq cssFramework \"tailwind\")}} className=\"text-lg font-semibold text-cyan-400 mb-2\"{{/if}}>\n Prisma ORM\n </h3>\n <p{{#if (eq cssFramework \"tailwind\")}} className=\"text-slate-400 text-sm\"{{/if}}>\n Database access made easy with Prisma and automatic migrations.\n </p>\n </div>\n </div>\n\n <div{{#if (eq cssFramework \"tailwind\")}} className=\"mt-12\"{{/if}}>\n <a\n href=\"https://redwoodjs.com/docs\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n {{#if (eq cssFramework \"tailwind\")}}className=\"inline-block bg-cyan-500 text-slate-900 px-6 py-3 rounded-lg font-semibold hover:bg-cyan-400 transition-colors\"{{/if}}\n >\n Read the Docs\n </a>\n </div>\n </div>\n </main>\n </>\n )\n}\n\nexport default HomePage\n`],\n [\"frontend/redwood/api/src/services/posts/posts.ts\", `import type { QueryResolvers, MutationResolvers } from \"types/graphql\";\n\nimport { db } from \"src/lib/db\";\n\nexport const posts: QueryResolvers[\"posts\"] = () => {\n return db.post.findMany();\n};\n\nexport const post: QueryResolvers[\"post\"] = ({ id }) => {\n return db.post.findUnique({\n where: { id },\n });\n};\n\nexport const createPost: MutationResolvers[\"createPost\"] = ({ input }) => {\n return db.post.create({\n data: input,\n });\n};\n\nexport const updatePost: MutationResolvers[\"updatePost\"] = ({ id, input }) => {\n return db.post.update({\n data: input,\n where: { id },\n });\n};\n\nexport const deletePost: MutationResolvers[\"deletePost\"] = ({ id }) => {\n return db.post.delete({\n where: { id },\n });\n};\n`],\n [\"examples/todo/convex/packages/backend/convex/todos.ts.hbs\", `import { query, mutation } from \"./_generated/server\";\nimport { v } from \"convex/values\";\n\nexport const getAll = query({\n handler: async (ctx) => {\n return await ctx.db.query(\"todos\").collect();\n },\n});\n\nexport const create = mutation({\n args: {\n text: v.string(),\n },\n handler: async (ctx, args) => {\n const newTodoId = await ctx.db.insert(\"todos\", {\n text: args.text,\n completed: false,\n });\n return await ctx.db.get(\"todos\", newTodoId);\n },\n});\n\nexport const toggle = mutation({\n args: {\n id: v.id(\"todos\"),\n completed: v.boolean(),\n },\n handler: async (ctx, args) => {\n await ctx.db.patch(\"todos\", args.id, { completed: args.completed });\n return { success: true };\n },\n});\n\nexport const deleteTodo = mutation({\n args: {\n id: v.id(\"todos\"),\n },\n handler: async (ctx, args) => {\n await ctx.db.delete(\"todos\", args.id);\n return { success: true };\n },\n});`],\n [\"examples/todo/web/nuxt/app/pages/todos.vue.hbs\", `<script setup lang=\"ts\">\nimport { ref } from 'vue'\n{{#if (eq backend \"convex\")}}\nimport { api } from \"@{{ projectName }}/backend/convex/_generated/api\";\nimport type { Id } from \"@{{ projectName }}/backend/convex/_generated/dataModel\";\nimport { useConvexMutation, useConvexQuery } from \"convex-vue\";\n\nconst { data, error, isPending } = useConvexQuery(api.todos.getAll, {});\n\nconst newTodoText = ref(\"\");\nconst { mutate: createTodo, isPending: isCreatePending } = useConvexMutation(api.todos.create);\n\nconst { mutate: toggleTodo } = useConvexMutation(api.todos.toggle);\nconst { mutate: deleteTodo, error: deleteError } = useConvexMutation(\n api.todos.deleteTodo,\n);\n\nfunction handleAddTodo() {\n const text = newTodoText.value.trim();\n if (!text) return;\n\n createTodo({ text });\n newTodoText.value = \"\";\n}\n\nfunction handleToggleTodo(id: Id<\"todos\">, completed: boolean) {\n toggleTodo({ id, completed: !completed });\n}\n\nfunction handleDeleteTodo(id: Id<\"todos\">) {\n deleteTodo({ id });\n}\n{{else}}\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/vue-query'\n\nconst { $orpc } = useNuxtApp()\n\nconst newTodoText = ref('')\nconst queryClient = useQueryClient()\n\nconst todos = useQuery($orpc.todo.getAll.queryOptions())\n\nconst createMutation = useMutation($orpc.todo.create.mutationOptions({\n onSuccess: () => {\n queryClient.invalidateQueries()\n newTodoText.value = ''\n }\n}))\n\nconst toggleMutation = useMutation($orpc.todo.toggle.mutationOptions({\n onSuccess: () => queryClient.invalidateQueries()\n}))\n\nconst deleteMutation = useMutation($orpc.todo.delete.mutationOptions({\n onSuccess: () => queryClient.invalidateQueries()\n}))\n\nfunction handleAddTodo() {\n if (newTodoText.value.trim()) {\n createMutation.mutate({ text: newTodoText.value })\n }\n}\n\nfunction handleToggleTodo(id: number, completed: boolean) {\n toggleMutation.mutate({ id, completed: !completed })\n}\n\nfunction handleDeleteTodo(id: number) {\n deleteMutation.mutate({ id })\n}\n{{/if}}\n</script>\n\n<template>\n <UContainer class=\"py-8 max-w-md\">\n <UCard>\n <template #header>\n <div>\n <div class=\"text-xl font-bold\">Todo List</div>\n <div class=\"text-muted text-sm\">Manage your tasks efficiently</div>\n </div>\n </template>\n\n <form @submit.prevent=\"handleAddTodo\" class=\"mb-6 flex items-center gap-2\">\n <UInput\n v-model=\"newTodoText\"\n placeholder=\"Add a new task...\"\n autocomplete=\"off\"\n class=\"flex-1\"\n {{#if (eq backend \"convex\")}}\n :disabled=\"isCreatePending\"\n {{/if}}\n />\n <UButton\n type=\"submit\"\n {{#if (eq backend \"convex\")}}\n :loading=\"isCreatePending\"\n :disabled=\"!newTodoText.trim()\"\n {{else}}\n :loading=\"createMutation.isPending.value\"\n {{/if}}\n >\n Add\n </UButton>\n </form>\n\n {{#if (eq backend \"convex\")}}\n <!-- Loading State -->\n <div v-if=\"isPending\" class=\"space-y-2\">\n <USkeleton v-for=\"i in 3\" :key=\"i\" class=\"h-12 w-full\" />\n </div>\n\n <!-- Error State -->\n <UAlert\n v-else-if=\"error || deleteError\"\n color=\"error\"\n icon=\"i-lucide-alert-circle\"\n title=\"Error\"\n :description=\"error?.message || deleteError?.message\"\n />\n\n <!-- Empty State -->\n <UEmpty\n v-else-if=\"data?.length === 0\"\n icon=\"i-lucide-clipboard-list\"\n title=\"No todos yet\"\n description=\"Add your first task above!\"\n />\n\n <!-- Todo List -->\n <ul v-else-if=\"data\" class=\"space-y-2\">\n <li\n v-for=\"todo in data\"\n :key=\"todo._id\"\n class=\"flex items-center justify-between rounded-md border p-3\"\n >\n <div class=\"flex items-center gap-3\">\n <UCheckbox\n :model-value=\"todo.completed\"\n @update:model-value=\"() => handleToggleTodo(todo._id, todo.completed)\"\n :id=\"\\`todo-\\${todo._id}\\`\"\n />\n <label\n :for=\"\\`todo-\\${todo._id}\\`\"\n :class=\"{ 'line-through text-muted': todo.completed }\"\n class=\"cursor-pointer\"\n >\n \\\\{{ todo.text }}\n </label>\n </div>\n <UButton\n color=\"error\"\n variant=\"ghost\"\n size=\"sm\"\n square\n @click=\"handleDeleteTodo(todo._id)\"\n aria-label=\"Delete todo\"\n icon=\"i-lucide-trash-2\"\n />\n </li>\n </ul>\n {{else}}\n <!-- Loading State -->\n <div v-if=\"todos.status.value === 'pending'\" class=\"space-y-2\">\n <USkeleton v-for=\"i in 3\" :key=\"i\" class=\"h-12 w-full\" />\n </div>\n\n <!-- Error State -->\n <UAlert\n v-else-if=\"todos.status.value === 'error'\"\n color=\"error\"\n icon=\"i-lucide-alert-circle\"\n title=\"Failed to load todos\"\n :description=\"todos.error.value?.message\"\n />\n\n <!-- Empty State -->\n <UEmpty\n v-else-if=\"todos.data.value?.length === 0\"\n icon=\"i-lucide-clipboard-list\"\n title=\"No todos yet\"\n description=\"Add your first task above!\"\n />\n\n <!-- Todo List -->\n <ul v-else class=\"space-y-2\">\n <li\n v-for=\"todo in todos.data.value\"\n :key=\"todo.id\"\n class=\"flex items-center justify-between rounded-md border p-3\"\n >\n <div class=\"flex items-center gap-3\">\n <UCheckbox\n :model-value=\"todo.completed\"\n @update:model-value=\"() => handleToggleTodo(todo.id, todo.completed)\"\n :id=\"\\`todo-\\${todo.id}\\`\"\n />\n <label\n :for=\"\\`todo-\\${todo.id}\\`\"\n :class=\"{ 'line-through text-muted': todo.completed }\"\n class=\"cursor-pointer\"\n >\n \\\\{{ todo.text }}\n </label>\n </div>\n <UButton\n color=\"error\"\n variant=\"ghost\"\n size=\"sm\"\n square\n @click=\"handleDeleteTodo(todo.id)\"\n aria-label=\"Delete todo\"\n icon=\"i-lucide-trash-2\"\n />\n </li>\n </ul>\n {{/if}}\n </UCard>\n </UContainer>\n</template>\n`],\n [\"examples/todo/native/bare/app/(drawer)/todos.tsx.hbs\", `import { useState } from \"react\";\nimport {\n View,\n Text,\n TextInput,\n ScrollView,\n ActivityIndicator,\n Alert,\n TouchableOpacity,\n StyleSheet,\n} from \"react-native\";\nimport { Ionicons } from \"@expo/vector-icons\";\n{{#if (eq backend \"convex\")}}\nimport { useMutation, useQuery } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport type { Id } from \"@{{projectName}}/backend/convex/_generated/dataModel\";\n{{else}}\nimport { useMutation, useQuery } from \"@tanstack/react-query\";\n{{/if}}\nimport { Container } from \"@/components/container\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\n{{#unless (eq backend \"convex\")}}\n {{#if (eq api \"orpc\")}}\nimport { orpc } from \"@/utils/orpc\";\n {{/if}}\n {{#if (eq api \"trpc\")}}\nimport { trpc } from \"@/utils/trpc\";\n {{/if}}\n{{/unless}}\n\nexport default function TodosScreen() {\n const { colorScheme } = useColorScheme();\n const theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\n const [newTodoText, setNewTodoText] = useState(\"\");\n\n {{#if (eq backend \"convex\")}}\n const todos = useQuery(api.todos.getAll);\n const createTodoMutation = useMutation(api.todos.create);\n const toggleTodoMutation = useMutation(api.todos.toggle);\n const deleteTodoMutation = useMutation(api.todos.deleteTodo);\n\n async function handleAddTodo() {\n const text = newTodoText.trim();\n if (!text) return;\n await createTodoMutation({ text });\n setNewTodoText(\"\");\n }\n\n function handleToggleTodo(id: Id<\"todos\">, currentCompleted: boolean) {\n toggleTodoMutation({ id, completed: !currentCompleted });\n }\n\n function handleDeleteTodo(id: Id<\"todos\">) {\n Alert.alert(\"Delete Todo\", \"Are you sure you want to delete this todo?\", [\n { text: \"Cancel\", style: \"cancel\" },\n {\n text: \"Delete\",\n style: \"destructive\",\n onPress: () => deleteTodoMutation({ id }),\n },\n ]);\n }\n\n const isLoading = !todos;\n const completedCount = todos?.filter((t) => t.completed).length || 0;\n const totalCount = todos?.length || 0;\n {{else}}\n {{#if (eq api \"orpc\")}}\n const todos = useQuery(orpc.todo.getAll.queryOptions());\n const createMutation = useMutation(\n orpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n })\n );\n const toggleMutation = useMutation(\n orpc.todo.toggle.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n },\n })\n );\n const deleteMutation = useMutation(\n orpc.todo.delete.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n },\n })\n );\n {{/if}}\n {{#if (eq api \"trpc\")}}\n const todos = useQuery(trpc.todo.getAll.queryOptions());\n const createMutation = useMutation(\n trpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n })\n );\n const toggleMutation = useMutation(\n trpc.todo.toggle.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n },\n })\n );\n const deleteMutation = useMutation(\n trpc.todo.delete.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n },\n })\n );\n {{/if}}\n\n function handleAddTodo() {\n if (newTodoText.trim()) {\n createMutation.mutate({ text: newTodoText });\n }\n }\n\n function handleToggleTodo(id: number, completed: boolean) {\n toggleMutation.mutate({ id, completed: !completed });\n }\n\n function handleDeleteTodo(id: number) {\n Alert.alert(\"Delete Todo\", \"Are you sure you want to delete this todo?\", [\n { text: \"Cancel\", style: \"cancel\" },\n {\n text: \"Delete\",\n style: \"destructive\",\n onPress: () => deleteMutation.mutate({ id }),\n },\n ]);\n }\n\n const isLoading = todos?.isLoading;\n const completedCount = todos?.data?.filter((t) => t.completed).length || 0;\n const totalCount = todos?.data?.length || 0;\n {{/if}}\n\n return (\n <Container>\n <ScrollView\n style={styles.scrollView}\n contentContainerStyle={styles.contentContainer}\n >\n <View style={styles.header}>\n <View style={styles.headerRow}>\n <Text style={[styles.title, { color: theme.text }]}>\n Todo List\n </Text>\n {totalCount > 0 && (\n <View style={[styles.badge, { backgroundColor: theme.primary }]}>\n <Text style={styles.badgeText}>\n {completedCount}/{totalCount}\n </Text>\n </View>\n )}\n </View>\n </View>\n <View\n style={[\n styles.inputCard,\n { backgroundColor: theme.card, borderColor: theme.border },\n ]}\n >\n <View style={styles.inputRow}>\n <View style={styles.inputContainer}>\n <TextInput\n value={newTodoText}\n onChangeText={setNewTodoText}\n placeholder=\"Add a new task...\"\n placeholderTextColor={theme.text}\n {{#unless (eq backend \"convex\")}}\n editable={!createMutation.isPending}\n {{/unless}}\n onSubmitEditing={handleAddTodo}\n returnKeyType=\"done\"\n style={[\n styles.input,\n {\n color: theme.text,\n borderColor: theme.border,\n backgroundColor: theme.background,\n },\n ]}\n />\n </View>\n <TouchableOpacity\n onPress={handleAddTodo}\n {{#if (eq backend \"convex\")}}\n disabled={!newTodoText.trim()}\n style={[\n styles.addButton,\n {\n backgroundColor: !newTodoText.trim()\n ? theme.border\n : theme.primary,\n opacity: !newTodoText.trim() ? 0.5 : 1,\n },\n ]}\n >\n <Ionicons\n name=\"add\"\n size={24}\n color={newTodoText.trim() ? \"#ffffff\" : theme.text}\n />\n {{else}}\n disabled={createMutation.isPending || !newTodoText.trim()}\n style={[\n styles.addButton,\n {\n backgroundColor:\n createMutation.isPending || !newTodoText.trim()\n ? theme.border\n : theme.primary,\n opacity:\n createMutation.isPending || !newTodoText.trim() ? 0.5 : 1,\n },\n ]}\n >\n {createMutation.isPending ? (\n <ActivityIndicator size=\"small\" color=\"#ffffff\" />\n ) : (\n <Ionicons name=\"add\" size={24} color=\"#ffffff\" />\n )}\n {{/if}}\n </TouchableOpacity>\n </View>\n </View>\n\n {{#if (eq backend \"convex\")}}\n {isLoading && (\n <View style={styles.centerContainer}>\n <ActivityIndicator size=\"large\" color={theme.primary} />\n <Text\n style={[styles.loadingText, { color: theme.text, opacity: 0.7 }]}\n >\n Loading todos...\n </Text>\n </View>\n )}\n\n {todos && todos.length === 0 && !isLoading && (\n <View\n style={[\n styles.emptyCard,\n { backgroundColor: theme.card, borderColor: theme.border },\n ]}\n >\n <Ionicons\n name=\"checkbox-outline\"\n size={64}\n color={theme.text}\n style=\\\\{{ opacity: 0.5, marginBottom: 16 }}\n />\n <Text style={[styles.emptyTitle, { color: theme.text }]}>\n No todos yet\n </Text>\n <Text\n style={[styles.emptyText, { color: theme.text, opacity: 0.7 }]}\n >\n Add your first task to get started!\n </Text>\n </View>\n )}\n\n {todos && todos.length > 0 && (\n <View style={styles.todosList}>\n {todos.map((todo) => (\n <View\n key={todo._id}\n style={[\n styles.todoCard,\n { backgroundColor: theme.card, borderColor: theme.border },\n ]}\n >\n <View style={styles.todoRow}>\n <TouchableOpacity\n onPress={() => handleToggleTodo(todo._id, todo.completed)}\n style={[styles.checkbox, { borderColor: theme.border }]}\n >\n {todo.completed && (\n <Ionicons\n name=\"checkmark\"\n size={16}\n color={theme.primary}\n />\n )}\n </TouchableOpacity>\n <View style={styles.todoTextContainer}>\n <Text\n style={[\n styles.todoText,\n { color: theme.text },\n todo.completed && {\n textDecorationLine: \"line-through\",\n opacity: 0.5,\n },\n ]}\n >\n {todo.text}\n </Text>\n </View>\n <TouchableOpacity\n onPress={() => handleDeleteTodo(todo._id)}\n style={styles.deleteButton}\n >\n <Ionicons\n name=\"trash-outline\"\n size={24}\n color={theme.notification}\n />\n </TouchableOpacity>\n </View>\n </View>\n ))}\n </View>\n )}\n {{else}}\n {isLoading && (\n <View style={styles.centerContainer}>\n <ActivityIndicator size=\"large\" color={theme.primary} />\n <Text\n style={[styles.loadingText, { color: theme.text, opacity: 0.7 }]}\n >\n Loading todos...\n </Text>\n </View>\n )}\n\n {todos?.data && todos.data.length === 0 && !isLoading && (\n <View\n style={[\n styles.emptyCard,\n { backgroundColor: theme.card, borderColor: theme.border },\n ]}\n >\n <Ionicons\n name=\"checkbox-outline\"\n size={64}\n color={theme.text}\n style=\\\\{{ opacity: 0.5, marginBottom: 16 }}\n />\n <Text style={[styles.emptyTitle, { color: theme.text }]}>\n No todos yet\n </Text>\n <Text\n style={[styles.emptyText, { color: theme.text, opacity: 0.7 }]}\n >\n Add your first task to get started!\n </Text>\n </View>\n )}\n\n {todos?.data && todos.data.length > 0 && (\n <View style={styles.todosList}>\n {todos.data.map((todo) => (\n <View\n key={todo.id}\n style={[\n styles.todoCard,\n { backgroundColor: theme.card, borderColor: theme.border },\n ]}\n >\n <View style={styles.todoRow}>\n <TouchableOpacity\n onPress={() => handleToggleTodo(todo.id, todo.completed)}\n style={[styles.checkbox, { borderColor: theme.border }]}\n >\n {todo.completed && (\n <Ionicons\n name=\"checkmark\"\n size={16}\n color={theme.primary}\n />\n )}\n </TouchableOpacity>\n <View style={styles.todoTextContainer}>\n <Text\n style={[\n styles.todoText,\n { color: theme.text },\n todo.completed && {\n textDecorationLine: \"line-through\",\n opacity: 0.5,\n },\n ]}\n >\n {todo.text}\n </Text>\n </View>\n <TouchableOpacity\n onPress={() => handleDeleteTodo(todo.id)}\n style={styles.deleteButton}\n >\n <Ionicons\n name=\"trash-outline\"\n size={24}\n color={theme.notification}\n />\n </TouchableOpacity>\n </View>\n </View>\n ))}\n </View>\n )}\n {{/if}}\n </ScrollView>\n </Container>\n );\n}\n\nconst styles = StyleSheet.create({\n scrollView: {\n flex: 1,\n },\n contentContainer: {\n padding: 16,\n },\n header: {\n marginBottom: 16,\n },\n headerRow: {\n flexDirection: \"row\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n },\n title: {\n fontSize: 24,\n fontWeight: \"bold\",\n },\n badge: {\n paddingHorizontal: 8,\n paddingVertical: 4,\n },\n badgeText: {\n color: \"#ffffff\",\n fontSize: 12,\n },\n inputCard: {\n borderWidth: 1,\n padding: 12,\n marginBottom: 16,\n },\n inputRow: {\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: 8,\n },\n inputContainer: {\n flex: 1,\n },\n input: {\n borderWidth: 1,\n padding: 12,\n fontSize: 16,\n },\n addButton: {\n padding: 12,\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n centerContainer: {\n alignItems: \"center\",\n justifyContent: \"center\",\n paddingVertical: 32,\n },\n loadingText: {\n marginTop: 16,\n fontSize: 14,\n },\n emptyCard: {\n borderWidth: 1,\n padding: 32,\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n emptyTitle: {\n fontSize: 16,\n fontWeight: \"bold\",\n marginBottom: 8,\n },\n emptyText: {\n fontSize: 14,\n textAlign: \"center\",\n },\n todosList: {\n gap: 8,\n },\n todoCard: {\n borderWidth: 1,\n padding: 12,\n },\n todoRow: {\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: 12,\n },\n checkbox: {\n width: 20,\n height: 20,\n borderWidth: 2,\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n todoTextContainer: {\n flex: 1,\n },\n todoText: {\n fontSize: 16,\n },\n deleteButton: {\n padding: 8,\n },\n});`],\n [\"examples/todo/web/solid/src/routes/todos.tsx.hbs\", `import { createFileRoute } from \"@tanstack/solid-router\";\nimport { Loader2, Trash2 } from \"lucide-solid\";\nimport { createSignal, For, Show } from \"solid-js\";\nimport { orpc } from \"@/utils/orpc\";\nimport { useQuery, useMutation } from \"@tanstack/solid-query\";\n\nexport const Route = createFileRoute(\"/todos\")({\n component: TodosRoute,\n});\n\nfunction TodosRoute() {\n const [newTodoText, setNewTodoText] = createSignal(\"\");\n\n const todos = useQuery(() => orpc.todo.getAll.queryOptions());\n\n const createMutation = useMutation(() =>\n orpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n }),\n );\n\n const toggleMutation = useMutation(() =>\n orpc.todo.toggle.mutationOptions({\n onSuccess: () => { todos.refetch() },\n }),\n );\n\n const deleteMutation = useMutation(() =>\n orpc.todo.delete.mutationOptions({\n onSuccess: () => { todos.refetch() },\n }),\n );\n\n const handleAddTodo = (e: Event) => {\n e.preventDefault();\n if (newTodoText().trim()) {\n createMutation.mutate({ text: newTodoText() });\n }\n };\n\n const handleToggleTodo = (id: number, completed: boolean) => {\n toggleMutation.mutate({ id, completed: !completed });\n };\n\n const handleDeleteTodo = (id: number) => {\n deleteMutation.mutate({ id });\n };\n\n return (\n <div class=\"mx-auto w-full max-w-md py-10\">\n <div class=\"rounded-lg border p-6 shadow-sm\">\n <div class=\"mb-4\">\n <h2 class=\"text-xl font-semibold\">Todo List</h2>\n <p class=\"text-sm\">Manage your tasks efficiently</p>\n </div>\n <div>\n <form\n onSubmit={handleAddTodo}\n class=\"mb-6 flex items-center space-x-2\"\n >\n <input\n type=\"text\"\n value={newTodoText()}\n onInput={(e) => setNewTodoText(e.currentTarget.value)}\n placeholder=\"Add a new task...\"\n disabled={createMutation.isPending}\n class=\"w-full rounded-md border p-2 text-sm\"\n />\n <button\n type=\"submit\"\n disabled={createMutation.isPending || !newTodoText().trim()}\n class=\"rounded-md bg-blue-600 px-4 py-2 text-sm text-white disabled:opacity-50\"\n >\n <Show when={createMutation.isPending} fallback=\"Add\">\n <Loader2 class=\"h-4 w-4 animate-spin\" />\n </Show>\n </button>\n </form>\n\n <Show when={todos.isLoading}>\n <div class=\"flex justify-center py-4\">\n <Loader2 class=\"h-6 w-6 animate-spin\" />\n </div>\n </Show>\n\n <Show when={!todos.isLoading && todos.data?.length === 0}>\n <p class=\"py-4 text-center\">No todos yet. Add one above!</p>\n </Show>\n\n <Show when={!todos.isLoading}>\n <ul class=\"space-y-2\">\n <For each={todos.data}>\n {(todo) => (\n <li class=\"flex items-center justify-between rounded-md border p-2\">\n <div class=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n checked={todo.completed}\n onChange={() =>\n handleToggleTodo(todo.id, todo.completed)\n }\n id={\\`todo-\\${todo.id}\\`}\n class=\"h-4 w-4\"\n />\n <label\n for={\\`todo-\\${todo.id}\\`}\n class={todo.completed ? \"line-through\" : \"\"}\n >\n {todo.text}\n </label>\n </div>\n <button\n type=\"button\"\n onClick={() => handleDeleteTodo(todo.id)}\n aria-label=\"Delete todo\"\n class=\"ml-2 rounded-md p-1\"\n >\n <Trash2 class=\"h-4 w-4\" />\n </button>\n </li>\n )}\n </For>\n </ul>\n </Show>\n </div>\n </div>\n </div>\n );\n}\n`],\n [\"examples/todo/native/uniwind/app/(drawer)/todos.tsx.hbs\", `import { useState } from \"react\";\nimport { View, Text, ScrollView, Alert } from \"react-native\";\nimport { Ionicons } from \"@expo/vector-icons\";\n{{#if (eq backend \"convex\")}}\nimport { useMutation, useQuery } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport type { Id } from \"@{{projectName}}/backend/convex/_generated/dataModel\";\n{{else}}\nimport { useMutation, useQuery } from \"@tanstack/react-query\";\n{{/if}}\nimport { Container } from \"@/components/container\";\n{{#unless (eq backend \"convex\")}}\n {{#if (eq api \"orpc\")}}\n import { orpc } from \"@/utils/orpc\";\n {{/if}}\n {{#if (eq api \"trpc\")}}\n import { trpc } from \"@/utils/trpc\";\n {{/if}}\n{{/unless}}\nimport { Button, Checkbox, Chip, Spinner, Surface, TextField, useThemeColor } from \"heroui-native\";\n\nexport default function TodosScreen() {\n const [newTodoText, setNewTodoText] = useState(\"\");\n {{#if (eq backend \"convex\")}}\n const todos = useQuery(api.todos.getAll);\n const createTodoMutation = useMutation(api.todos.create);\n const toggleTodoMutation = useMutation(api.todos.toggle);\n const deleteTodoMutation = useMutation(api.todos.deleteTodo);\n {{else}}\n {{#if (eq api \"orpc\")}}\n const todos = useQuery(orpc.todo.getAll.queryOptions());\n const createMutation = useMutation(orpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n }));\n const toggleMutation = useMutation(orpc.todo.toggle.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n },\n }));\n const deleteMutation = useMutation(orpc.todo.delete.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n },\n }));\n {{/if}}\n {{#if (eq api \"trpc\")}}\n const todos = useQuery(trpc.todo.getAll.queryOptions());\n const createMutation = useMutation(trpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n }));\n const toggleMutation = useMutation(trpc.todo.toggle.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n },\n }));\n const deleteMutation = useMutation(trpc.todo.delete.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n },\n }));\n {{/if}}\n {{/if}}\n\n const mutedColor = useThemeColor(\"muted\");\n const dangerColor = useThemeColor(\"danger\");\n const foregroundColor = useThemeColor(\"foreground\");\n\n {{#if (eq backend \"convex\")}}\n const handleAddTodo = async () => {\n const text = newTodoText.trim();\n if (!text) return;\n await createTodoMutation({ text });\n setNewTodoText(\"\");\n };\n\n const handleToggleTodo = (id: Id<\"todos\">, currentCompleted: boolean) => {\n toggleTodoMutation({ id, completed: !currentCompleted });\n };\n\n const handleDeleteTodo = (id: Id<\"todos\">) => {\n Alert.alert(\"Delete Todo\", \"Are you sure you want to delete this todo?\", [\n { text: \"Cancel\", style: \"cancel\" },\n {\n text: \"Delete\",\n style: \"destructive\",\n onPress: () => deleteTodoMutation({ id }),\n },\n ]);\n };\n\n const isLoading = !todos;\n const completedCount = todos?.filter((t) => t.completed).length || 0;\n const totalCount = todos?.length || 0;\n {{else}}\n const handleAddTodo = () => {\n if (newTodoText.trim()) {\n createMutation.mutate({ text: newTodoText });\n }\n };\n\n const handleToggleTodo = (id: number, completed: boolean) => {\n toggleMutation.mutate({ id, completed: !completed });\n };\n\n const handleDeleteTodo = (id: number) => {\n Alert.alert(\"Delete Todo\", \"Are you sure you want to delete this todo?\", [\n { text: \"Cancel\", style: \"cancel\" },\n {\n text: \"Delete\",\n style: \"destructive\",\n onPress: () => deleteMutation.mutate({ id }),\n },\n ]);\n };\n\n const isLoading = todos?.isLoading;\n const completedCount = todos?.data?.filter((t) => t.completed).length || 0;\n const totalCount = todos?.data?.length || 0;\n {{/if}}\n\n return (\n <Container>\n <ScrollView className=\"flex-1\" contentContainerClassName=\"p-4\">\n <View className=\"py-4 mb-4\">\n <View className=\"flex-row items-center justify-between\">\n <Text className=\"text-2xl font-semibold text-foreground tracking-tight\">Tasks</Text>\n {totalCount > 0 && (\n <Chip variant=\"secondary\" color=\"accent\" size=\"sm\">\n <Chip.Label>\n {completedCount}/{totalCount}\n </Chip.Label>\n </Chip>\n )}\n </View>\n </View>\n\n <Surface variant=\"secondary\" className=\"mb-4 p-3 rounded-lg\">\n <View className=\"flex-row items-center gap-2\">\n <View className=\"flex-1\">\n <TextField>\n <TextField.Input\n value={newTodoText}\n onChangeText={setNewTodoText}\n placeholder=\"Add a new task...\"\n {{#unless (eq backend \"convex\")}}\n editable={!createMutation.isPending}\n {{/unless}}\n onSubmitEditing={handleAddTodo}\n returnKeyType=\"done\"\n />\n </TextField>\n </View>\n <Button\n isIconOnly\n {{#if (eq backend \"convex\")}}\n variant={!newTodoText.trim() ? \"secondary\" : \"primary\"}\n isDisabled={!newTodoText.trim()}\n {{else}}\n variant={createMutation.isPending || !newTodoText.trim() ? \"secondary\" : \"primary\"}\n isDisabled={createMutation.isPending || !newTodoText.trim()}\n {{/if}}\n onPress={handleAddTodo}\n size=\"sm\"\n >\n {{#if (eq backend \"convex\")}}\n <Ionicons\n name=\"add\"\n size={20}\n color={newTodoText.trim() ? foregroundColor : mutedColor}\n />\n {{else}}\n {createMutation.isPending ? (\n <Spinner size=\"sm\" color=\"default\" />\n ) : (\n <Ionicons\n name=\"add\"\n size={20}\n color={(createMutation.isPending || !newTodoText.trim()) ? mutedColor : foregroundColor}\n />\n )}\n {{/if}}\n </Button>\n </View>\n </Surface>\n\n {{#if (eq backend \"convex\")}}\n {isLoading && (\n <View className=\"items-center justify-center py-12\">\n <Spinner size=\"lg\" />\n <Text className=\"text-muted text-sm mt-3\">Loading tasks...</Text>\n </View>\n )}\n\n {todos && todos.length === 0 && !isLoading && (\n <Surface variant=\"secondary\" className=\"items-center justify-center py-10 rounded-lg\">\n <Ionicons name=\"checkbox-outline\" size={40} color={mutedColor} />\n <Text className=\"text-foreground font-medium mt-3\">No tasks yet</Text>\n <Text className=\"text-muted text-xs mt-1\">Add your first task to get started</Text>\n </Surface>\n )}\n\n {todos && todos.length > 0 && (\n <View className=\"gap-2\">\n {todos.map((todo) => (\n <Surface key={todo._id} variant=\"secondary\" className=\"p-3 rounded-lg\">\n <View className=\"flex-row items-center gap-3\">\n <Checkbox\n isSelected={todo.completed}\n onSelectedChange={() => handleToggleTodo(todo._id, todo.completed)}\n />\n <View className=\"flex-1\">\n <Text className={\\`text-sm \\${todo.completed ? \"text-muted line-through\" : \"text-foreground\"}\\`}>\n {todo.text}\n </Text>\n </View>\n <Button\n isIconOnly\n variant=\"ghost\"\n onPress={() => handleDeleteTodo(todo._id)}\n size=\"sm\"\n >\n <Ionicons name=\"trash-outline\" size={16} color={dangerColor} />\n </Button>\n </View>\n </Surface>\n ))}\n </View>\n )}\n {{else}}\n {isLoading && (\n <View className=\"items-center justify-center py-12\">\n <Spinner size=\"lg\" />\n <Text className=\"text-muted text-sm mt-3\">Loading tasks...</Text>\n </View>\n )}\n\n {todos?.data && todos.data.length === 0 && !isLoading && (\n <Surface variant=\"secondary\" className=\"items-center justify-center py-10 rounded-lg\">\n <Ionicons name=\"checkbox-outline\" size={40} color={mutedColor} />\n <Text className=\"text-foreground font-medium mt-3\">No tasks yet</Text>\n <Text className=\"text-muted text-xs mt-1\">Add your first task to get started</Text>\n </Surface>\n )}\n\n {todos?.data && todos.data.length > 0 && (\n <View className=\"gap-2\">\n {todos.data.map((todo) => (\n <Surface key={todo.id} variant=\"secondary\" className=\"p-3 rounded-lg\">\n <View className=\"flex-row items-center gap-3\">\n <Checkbox\n isSelected={todo.completed}\n onSelectedChange={() => handleToggleTodo(todo.id, todo.completed)}\n />\n <View className=\"flex-1\">\n <Text className={\\`text-sm \\${todo.completed ? \"text-muted line-through\" : \"text-foreground\"}\\`}>\n {todo.text}\n </Text>\n </View>\n <Button\n isIconOnly\n variant=\"ghost\"\n onPress={() => handleDeleteTodo(todo.id)}\n size=\"sm\"\n >\n <Ionicons name=\"trash-outline\" size={16} color={dangerColor} />\n </Button>\n </View>\n </Surface>\n ))}\n </View>\n )}\n {{/if}}\n </ScrollView>\n </Container>\n );\n}`],\n [\"examples/ai/native/uniwind/app/(drawer)/ai.tsx.hbs\", `{{#if (eq backend \"convex\")}}\nimport { Ionicons } from \"@expo/vector-icons\";\nimport {\n useUIMessages,\n useSmoothText,\n type UIMessage,\n} from \"@convex-dev/agent/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport { useMutation } from \"convex/react\";\nimport { Button, Divider, Spinner, Surface, TextField, useThemeColor } from \"heroui-native\";\nimport { useRef, useEffect, useState } from \"react\";\nimport {\n View,\n Text,\n ScrollView,\n KeyboardAvoidingView,\n Platform,\n} from \"react-native\";\n\nimport { Container } from \"@/components/container\";\n\nfunction MessageContent({\n text,\n isStreaming,\n}: {\n text: string;\n isStreaming: boolean;\n}) {\n const [visibleText] = useSmoothText(text, {\n startStreaming: isStreaming,\n });\n return <Text className=\"text-foreground text-sm leading-relaxed\">{visibleText}</Text>;\n}\n\nexport default function AIScreen() {\n const [input, setInput] = useState(\"\");\n const [threadId, setThreadId] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const scrollViewRef = useRef<ScrollView>(null);\n const mutedColor = useThemeColor(\"muted\");\n const foregroundColor = useThemeColor(\"foreground\");\n\n const createThread = useMutation(api.chat.createNewThread);\n const sendMessage = useMutation(api.chat.sendMessage);\n\n const { results: messages } = useUIMessages(\n api.chat.listMessages,\n threadId ? { threadId } : \"skip\",\n { initialNumItems: 50, stream: true },\n );\n\n const hasStreamingMessage = messages?.some(\n (m: UIMessage) => m.status === \"streaming\",\n );\n\n useEffect(() => {\n scrollViewRef.current?.scrollToEnd({ animated: true });\n }, [messages]);\n\n const onSubmit = async () => {\n const value = input.trim();\n if (!value || isLoading) return;\n\n setIsLoading(true);\n setInput(\"\");\n\n try {\n let currentThreadId = threadId;\n if (!currentThreadId) {\n currentThreadId = await createThread();\n setThreadId(currentThreadId);\n }\n\n await sendMessage({ threadId: currentThreadId, prompt: value });\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n };\n\n return (\n <Container>\n <KeyboardAvoidingView\n className=\"flex-1\"\n behavior={Platform.OS === \"ios\" ? \"padding\" : \"height\"}\n >\n <View className=\"flex-1 px-4 py-4\">\n <View className=\"py-4 mb-4\">\n <Text className=\"text-2xl font-semibold text-foreground tracking-tight\">AI Chat</Text>\n <Text className=\"text-muted text-sm mt-1\">Chat with our AI assistant</Text>\n </View>\n\n <ScrollView\n ref={scrollViewRef}\n className=\"flex-1 mb-4\"\n showsVerticalScrollIndicator={false}\n >\n {!messages || messages.length === 0 ? (\n <View className=\"flex-1 justify-center items-center py-10\">\n <Ionicons name=\"chatbubble-ellipses-outline\" size={32} color={mutedColor} />\n <Text className=\"text-muted text-sm mt-3\">Ask me anything to get started</Text>\n </View>\n ) : (\n <View className=\"gap-2\">\n {messages.map((message: UIMessage) => (\n <Surface\n key={message.key}\n variant={message.role === \"user\" ? \"tertiary\" : \"secondary\"}\n className={\\`p-3 rounded-lg \\${message.role === \"user\" ? \"ml-10\" : \"mr-10\"}\\`}\n >\n <Text className=\"text-xs font-medium mb-1 text-muted\">\n {message.role === \"user\" ? \"You\" : \"AI\"}\n </Text>\n <MessageContent\n text={message.text ?? \"\"}\n isStreaming={message.status === \"streaming\"}\n />\n </Surface>\n ))}\n {isLoading && !hasStreamingMessage && (\n <Surface variant=\"secondary\" className=\"p-3 mr-10 rounded-lg\">\n <Text className=\"text-xs font-medium mb-1 text-muted\">AI</Text>\n <View className=\"flex-row items-center gap-2\">\n <Spinner size=\"sm\" />\n <Text className=\"text-muted text-sm\">Thinking...</Text>\n </View>\n </Surface>\n )}\n </View>\n )}\n </ScrollView>\n\n <Divider className=\"mb-3\" />\n\n <View className=\"flex-row items-center gap-2\">\n <View className=\"flex-1\">\n <TextField>\n <TextField.Input\n value={input}\n onChangeText={setInput}\n placeholder=\"Type a message...\"\n onSubmitEditing={onSubmit}\n editable={!isLoading}\n autoFocus\n />\n </TextField>\n </View>\n <Button\n isIconOnly\n variant={input.trim() && !isLoading ? \"primary\" : \"secondary\"}\n onPress={onSubmit}\n isDisabled={!input.trim() || isLoading}\n size=\"sm\"\n >\n <Ionicons\n name=\"arrow-up\"\n size={18}\n color={input.trim() && !isLoading ? foregroundColor : mutedColor}\n />\n </Button>\n </View>\n </View>\n </KeyboardAvoidingView>\n </Container>\n );\n}\n{{else}}\nimport { useRef, useEffect, useState } from \"react\";\nimport {\n View,\n Text,\n ScrollView,\n KeyboardAvoidingView,\n Platform,\n} from \"react-native\";\nimport { useChat } from \"@ai-sdk/react\";\nimport { DefaultChatTransport } from \"ai\";\nimport { fetch as expoFetch } from \"expo/fetch\";\nimport { Ionicons } from \"@expo/vector-icons\";\nimport { Container } from \"@/components/container\";\nimport { Button, Divider, ErrorView, Spinner, Surface, TextField, useThemeColor } from \"heroui-native\";\nimport { env } from \"@{{projectName}}/env/native\";\n\nconst generateAPIUrl = (relativePath: string) => {\n const serverUrl = env.EXPO_PUBLIC_SERVER_URL;\n if (!serverUrl) {\n throw new Error(\n \"EXPO_PUBLIC_SERVER_URL environment variable is not defined\"\n );\n }\n const path = relativePath.startsWith(\"/\") ? relativePath : \\`/\\${relativePath}\\`;\n return serverUrl.concat(path);\n};\n\nexport default function AIScreen() {\n const [input, setInput] = useState(\"\");\n const { messages, error, sendMessage } = useChat({\n transport: new DefaultChatTransport({\n fetch: expoFetch as unknown as typeof globalThis.fetch,\n api: generateAPIUrl(\"/ai\"),\n }),\n onError: (error) => console.error(error, \"AI Chat Error\"),\n });\n const scrollViewRef = useRef<ScrollView>(null);\n const foregroundColor = useThemeColor(\"foreground\");\n const mutedColor = useThemeColor(\"muted\");\n\n useEffect(() => {\n scrollViewRef.current?.scrollToEnd({ animated: true });\n }, [messages]);\n\n const onSubmit = () => {\n const value = input.trim();\n if (value) {\n sendMessage({ text: value });\n setInput(\"\");\n }\n };\n\n if (error) {\n return (\n <Container>\n <View className=\"flex-1 justify-center items-center px-4\">\n <Surface variant=\"secondary\" className=\"p-4 rounded-lg\">\n <ErrorView isInvalid>\n <Text className=\"text-danger text-center font-medium mb-1\">\n {error.message}\n </Text>\n <Text className=\"text-muted text-center text-xs\">\n Please check your connection and try again.\n </Text>\n </ErrorView>\n </Surface>\n </View>\n </Container>\n );\n }\n\n return (\n <Container>\n <KeyboardAvoidingView\n className=\"flex-1\"\n behavior={Platform.OS === \"ios\" ? \"padding\" : \"height\"}\n >\n <View className=\"flex-1 px-4 py-4\">\n <View className=\"py-4 mb-4\">\n <Text className=\"text-2xl font-semibold text-foreground tracking-tight\">AI Chat</Text>\n <Text className=\"text-muted text-sm mt-1\">Chat with our AI assistant</Text>\n </View>\n\n <ScrollView\n ref={scrollViewRef}\n className=\"flex-1 mb-4\"\n showsVerticalScrollIndicator={false}\n >\n {messages.length === 0 ? (\n <View className=\"flex-1 justify-center items-center py-10\">\n <Ionicons name=\"chatbubble-ellipses-outline\" size={32} color={mutedColor} />\n <Text className=\"text-muted text-sm mt-3\">Ask me anything to get started</Text>\n </View>\n ) : (\n <View className=\"gap-2\">\n {messages.map((message) => (\n <Surface\n key={message.id}\n variant={message.role === \"user\" ? \"tertiary\" : \"secondary\"}\n className={\\`p-3 rounded-lg \\${message.role === \"user\" ? \"ml-10\" : \"mr-10\"}\\`}\n >\n <Text className=\"text-xs font-medium mb-1 text-muted\">\n {message.role === \"user\" ? \"You\" : \"AI\"}\n </Text>\n <View className=\"gap-1\">\n {message.parts.map((part, i) =>\n part.type === \"text\" ? (\n <Text\n key={\\`\\${message.id}-\\${i}\\`}\n className=\"text-foreground text-sm leading-relaxed\"\n >\n {part.text}\n </Text>\n ) : (\n <Text\n key={\\`\\${message.id}-\\${i}\\`}\n className=\"text-foreground text-sm leading-relaxed\"\n >\n {JSON.stringify(part)}\n </Text>\n )\n )}\n </View>\n </Surface>\n ))}\n </View>\n )}\n </ScrollView>\n\n <Divider className=\"mb-3\" />\n\n <View className=\"flex-row items-center gap-2\">\n <View className=\"flex-1\">\n <TextField>\n <TextField.Input\n value={input}\n onChangeText={setInput}\n placeholder=\"Type a message...\"\n onSubmitEditing={onSubmit}\n autoFocus\n />\n </TextField>\n </View>\n <Button\n isIconOnly\n variant={input.trim() ? \"primary\" : \"secondary\"}\n onPress={onSubmit}\n isDisabled={!input.trim()}\n size=\"sm\"\n >\n <Ionicons\n name=\"arrow-up\"\n size={18}\n color={input.trim() ? foregroundColor : mutedColor}\n />\n </Button>\n </View>\n </View>\n </KeyboardAvoidingView>\n </Container>\n );\n}\n{{/if}}\n`],\n [\"examples/ai/convex/packages/backend/convex/chat.ts.hbs\", `import {\n createThread,\n listUIMessages,\n saveMessage,\n syncStreams,\n vStreamArgs,\n} from \"@convex-dev/agent\";\nimport { paginationOptsValidator } from \"convex/server\";\nimport { v } from \"convex/values\";\n\nimport { components, internal } from \"./_generated/api\";\nimport { internalAction, mutation, query } from \"./_generated/server\";\nimport { chatAgent } from \"./agent\";\n\nexport const createNewThread = mutation({\n args: {},\n handler: async (ctx) => {\n const threadId = await createThread(ctx, components.agent, {});\n return threadId;\n },\n});\n\nexport const listMessages = query({\n args: {\n threadId: v.string(),\n paginationOpts: paginationOptsValidator,\n streamArgs: vStreamArgs,\n },\n handler: async (ctx, args) => {\n const paginated = await listUIMessages(ctx, components.agent, args);\n const streams = await syncStreams(ctx, components.agent, args);\n return { ...paginated, streams };\n },\n});\n\nexport const sendMessage = mutation({\n args: {\n threadId: v.string(),\n prompt: v.string(),\n },\n handler: async (ctx, { threadId, prompt }) => {\n const { messageId } = await saveMessage(ctx, components.agent, {\n threadId,\n prompt,\n });\n await ctx.scheduler.runAfter(0, internal.chat.generateResponseAsync, {\n threadId,\n promptMessageId: messageId,\n });\n return messageId;\n },\n});\n\nexport const generateResponseAsync = internalAction({\n args: {\n threadId: v.string(),\n promptMessageId: v.string(),\n },\n handler: async (ctx, { threadId, promptMessageId }) => {\n await chatAgent.streamText(\n ctx,\n { threadId },\n { promptMessageId },\n { saveStreamDeltas: true },\n );\n },\n});\n`],\n [\"examples/ai/convex/packages/backend/convex/agent.ts.hbs\", `import { Agent } from \"@convex-dev/agent\";\nimport { google } from \"@ai-sdk/google\";\nimport { components } from \"./_generated/api\";\n\nexport const chatAgent = new Agent(components.agent, {\n name: \"Chat Agent\",\n languageModel: google(\"gemini-2.5-flash\"),\n instructions: \"You are a helpful AI assistant. Be concise and friendly in your responses.\",\n});\n`],\n [\"examples/ai/native/bare/app/(drawer)/ai.tsx.hbs\", `{{#if (eq backend \"convex\")}}\nimport { Ionicons } from \"@expo/vector-icons\";\nimport {\n useUIMessages,\n useSmoothText,\n type UIMessage,\n} from \"@convex-dev/agent/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport { useMutation } from \"convex/react\";\nimport { useRef, useEffect, useState } from \"react\";\nimport {\n View,\n Text,\n TextInput,\n TouchableOpacity,\n ScrollView,\n KeyboardAvoidingView,\n Platform,\n StyleSheet,\n ActivityIndicator,\n} from \"react-native\";\n\nimport { Container } from \"@/components/container\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\n\nfunction MessageContent({\n text,\n isStreaming,\n textColor,\n}: {\n text: string;\n isStreaming: boolean;\n textColor: string;\n}) {\n const [visibleText] = useSmoothText(text, {\n startStreaming: isStreaming,\n });\n return <Text style={[styles.messageText, { color: textColor }]}>{visibleText}</Text>;\n}\n\nexport default function AIScreen() {\n const { colorScheme } = useColorScheme();\n const theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\n const [input, setInput] = useState(\"\");\n const [threadId, setThreadId] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const scrollViewRef = useRef<ScrollView>(null);\n\n const createThread = useMutation(api.chat.createNewThread);\n const sendMessage = useMutation(api.chat.sendMessage);\n\n const { results: messages } = useUIMessages(\n api.chat.listMessages,\n threadId ? { threadId } : \"skip\",\n { initialNumItems: 50, stream: true },\n );\n\n const hasStreamingMessage = messages?.some(\n (m: UIMessage) => m.status === \"streaming\",\n );\n\n useEffect(() => {\n scrollViewRef.current?.scrollToEnd({ animated: true });\n }, [messages]);\n\n async function onSubmit() {\n const value = input.trim();\n if (!value || isLoading) return;\n\n setIsLoading(true);\n setInput(\"\");\n\n try {\n let currentThreadId = threadId;\n if (!currentThreadId) {\n currentThreadId = await createThread();\n setThreadId(currentThreadId);\n }\n\n await sendMessage({ threadId: currentThreadId, prompt: value });\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n }\n\n return (\n <Container>\n <KeyboardAvoidingView\n style={styles.container}\n behavior={Platform.OS === \"ios\" ? \"padding\" : \"height\"}\n >\n <View style={styles.content}>\n <View style={styles.header}>\n <Text style={[styles.headerTitle, { color: theme.text }]}>\n AI Chat\n </Text>\n <Text style={[styles.headerSubtitle, { color: theme.text, opacity: 0.7 }]}>\n Chat with our AI assistant\n </Text>\n </View>\n <ScrollView\n ref={scrollViewRef}\n style={styles.scrollView}\n showsVerticalScrollIndicator={false}\n >\n {!messages || messages.length === 0 ? (\n <View style={styles.emptyContainer}>\n <Text style={[styles.emptyText, { color: theme.text, opacity: 0.7 }]}>\n Ask me anything to get started!\n </Text>\n </View>\n ) : (\n <View style={styles.messagesList}>\n {messages.map((message: UIMessage) => (\n <View\n key={message.key}\n style={[\n styles.messageCard,\n {\n backgroundColor: message.role === \"user\"\n ? theme.primary + \"20\"\n : theme.card,\n borderColor: theme.border,\n alignSelf: message.role === \"user\" ? \"flex-end\" : \"flex-start\",\n marginLeft: message.role === \"user\" ? 32 : 0,\n marginRight: message.role === \"user\" ? 0 : 32,\n },\n ]}\n >\n <Text style={[styles.messageRole, { color: theme.text }]}>\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </Text>\n <MessageContent\n text={message.text ?? \"\"}\n isStreaming={message.status === \"streaming\"}\n textColor={theme.text}\n />\n </View>\n ))}\n {isLoading && !hasStreamingMessage && (\n <View\n style={[\n styles.messageCard,\n {\n backgroundColor: theme.card,\n borderColor: theme.border,\n alignSelf: \"flex-start\",\n marginRight: 32,\n },\n ]}\n >\n <Text style={[styles.messageRole, { color: theme.text }]}>\n AI Assistant\n </Text>\n <View style={styles.loadingContainer}>\n <ActivityIndicator size=\"small\" color={theme.primary} />\n <Text style={[styles.loadingText, { color: theme.text, opacity: 0.7 }]}>\n Thinking...\n </Text>\n </View>\n </View>\n )}\n </View>\n )}\n </ScrollView>\n <View style={[styles.inputContainer, { borderTopColor: theme.border }]}>\n <View style={styles.inputRow}>\n <TextInput\n value={input}\n onChangeText={setInput}\n placeholder=\"Type your message...\"\n placeholderTextColor={theme.text}\n style={[\n styles.input,\n {\n color: theme.text,\n borderColor: theme.border,\n backgroundColor: theme.background,\n },\n ]}\n onSubmitEditing={(e) => {\n e.preventDefault();\n onSubmit();\n }}\n editable={!isLoading}\n autoFocus={true}\n multiline\n />\n <TouchableOpacity\n onPress={onSubmit}\n disabled={!input.trim() || isLoading}\n style={[\n styles.sendButton,\n {\n backgroundColor: input.trim() && !isLoading ? theme.primary : theme.border,\n opacity: input.trim() && !isLoading ? 1 : 0.5,\n },\n ]}\n >\n <Ionicons\n name=\"send\"\n size={20}\n color=\"#ffffff\"\n />\n </TouchableOpacity>\n </View>\n </View>\n </View>\n </KeyboardAvoidingView>\n </Container>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n },\n content: {\n flex: 1,\n padding: 16,\n },\n header: {\n marginBottom: 16,\n },\n headerTitle: {\n fontSize: 20,\n fontWeight: \"bold\",\n marginBottom: 4,\n },\n headerSubtitle: {\n fontSize: 14,\n },\n scrollView: {\n flex: 1,\n marginBottom: 16,\n },\n emptyContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n emptyText: {\n fontSize: 16,\n textAlign: \"center\",\n },\n messagesList: {\n gap: 8,\n paddingBottom: 16,\n },\n messageCard: {\n borderWidth: 1,\n padding: 12,\n maxWidth: \"80%\",\n },\n messageRole: {\n fontSize: 12,\n fontWeight: \"bold\",\n marginBottom: 4,\n },\n messageText: {\n fontSize: 14,\n lineHeight: 20,\n },\n loadingContainer: {\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: 8,\n },\n loadingText: {\n fontSize: 14,\n },\n inputContainer: {\n borderTopWidth: 1,\n paddingTop: 12,\n },\n inputRow: {\n flexDirection: \"row\",\n alignItems: \"flex-end\",\n gap: 8,\n },\n input: {\n flex: 1,\n borderWidth: 1,\n padding: 8,\n fontSize: 14,\n minHeight: 36,\n maxHeight: 100,\n },\n sendButton: {\n padding: 8,\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n});\n{{else}}\nimport { useRef, useEffect, useState } from \"react\";\nimport {\n View,\n Text,\n TextInput,\n TouchableOpacity,\n ScrollView,\n KeyboardAvoidingView,\n Platform,\n StyleSheet,\n} from \"react-native\";\nimport { useChat } from \"@ai-sdk/react\";\nimport { DefaultChatTransport } from \"ai\";\nimport { fetch as expoFetch } from \"expo/fetch\";\nimport { Ionicons } from \"@expo/vector-icons\";\nimport { Container } from \"@/components/container\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\nimport { env } from \"@{{projectName}}/env/native\";\n\nconst generateAPIUrl = (relativePath: string) => {\n const serverUrl = env.EXPO_PUBLIC_SERVER_URL;\n if (!serverUrl) {\n throw new Error(\n \"EXPO_PUBLIC_SERVER_URL environment variable is not defined\"\n );\n }\n const path = relativePath.startsWith(\"/\") ? relativePath : \\`/\\${relativePath}\\`;\n return serverUrl.concat(path);\n};\n\nexport default function AIScreen() {\n const { colorScheme } = useColorScheme();\n const theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\n const [input, setInput] = useState(\"\");\n const { messages, error, sendMessage } = useChat({\n transport: new DefaultChatTransport({\n fetch: expoFetch as unknown as typeof globalThis.fetch,\n api: generateAPIUrl(\"/ai\"),\n }),\n onError: (error) => console.error(error, \"AI Chat Error\"),\n });\n const scrollViewRef = useRef<ScrollView>(null);\n\n useEffect(() => {\n scrollViewRef.current?.scrollToEnd({ animated: true });\n }, [messages]);\n\n function onSubmit() {\n const value = input.trim();\n if (value) {\n sendMessage({ text: value });\n setInput(\"\");\n }\n }\n\n if (error) {\n return (\n <Container>\n <View style={styles.errorContainer}>\n <View style={[styles.errorCard, { backgroundColor: theme.notification + \"20\", borderColor: theme.notification }]}>\n <Text style={[styles.errorTitle, { color: theme.notification }]}>\n Error: {error.message}\n </Text>\n <Text style={[styles.errorText, { color: theme.text, opacity: 0.7 }]}>\n Please check your connection and try again.\n </Text>\n </View>\n </View>\n </Container>\n );\n }\n\n return (\n <Container>\n <KeyboardAvoidingView\n style={styles.container}\n behavior={Platform.OS === \"ios\" ? \"padding\" : \"height\"}\n >\n <View style={styles.content}>\n <View style={styles.header}>\n <Text style={[styles.headerTitle, { color: theme.text }]}>\n AI Chat\n </Text>\n <Text style={[styles.headerSubtitle, { color: theme.text, opacity: 0.7 }]}>\n Chat with our AI assistant\n </Text>\n </View>\n <ScrollView\n ref={scrollViewRef}\n style={styles.scrollView}\n showsVerticalScrollIndicator={false}\n >\n {messages.length === 0 ? (\n <View style={styles.emptyContainer}>\n <Text style={[styles.emptyText, { color: theme.text, opacity: 0.7 }]}>\n Ask me anything to get started!\n </Text>\n </View>\n ) : (\n <View style={styles.messagesList}>\n {messages.map((message) => (\n <View\n key={message.id}\n style={[\n styles.messageCard,\n {\n backgroundColor: message.role === \"user\"\n ? theme.primary + \"20\"\n : theme.card,\n borderColor: theme.border,\n alignSelf: message.role === \"user\" ? \"flex-end\" : \"flex-start\",\n marginLeft: message.role === \"user\" ? 32 : 0,\n marginRight: message.role === \"user\" ? 0 : 32,\n },\n ]}\n >\n <Text style={[styles.messageRole, { color: theme.text }]}>\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </Text>\n <View style={styles.messageParts}>\n {message.parts.map((part, i) =>\n part.type === \"text\" ? (\n <Text\n key={\\`\\${message.id}-\\${i}\\`}\n style={[styles.messageText, { color: theme.text }]}\n >\n {part.text}\n </Text>\n ) : (\n <Text\n key={\\`\\${message.id}-\\${i}\\`}\n style={[styles.messageText, { color: theme.text }]}\n >\n {JSON.stringify(part)}\n </Text>\n )\n )}\n </View>\n </View>\n ))}\n </View>\n )}\n </ScrollView>\n <View style={[styles.inputContainer, { borderTopColor: theme.border }]}>\n <View style={styles.inputRow}>\n <TextInput\n value={input}\n onChangeText={setInput}\n placeholder=\"Type your message...\"\n placeholderTextColor={theme.text}\n style={[\n styles.input,\n {\n color: theme.text,\n borderColor: theme.border,\n backgroundColor: theme.background,\n },\n ]}\n onSubmitEditing={(e) => {\n e.preventDefault();\n onSubmit();\n }}\n autoFocus={true}\n multiline\n />\n <TouchableOpacity\n onPress={onSubmit}\n disabled={!input.trim()}\n style={[\n styles.sendButton,\n {\n backgroundColor: input.trim() ? theme.primary : theme.border,\n opacity: input.trim() ? 1 : 0.5,\n },\n ]}\n >\n <Ionicons\n name=\"send\"\n size={20}\n color=\"#ffffff\"\n />\n </TouchableOpacity>\n </View>\n </View>\n </View>\n </KeyboardAvoidingView>\n </Container>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n },\n content: {\n flex: 1,\n padding: 16,\n },\n header: {\n marginBottom: 16,\n },\n headerTitle: {\n fontSize: 20,\n fontWeight: \"bold\",\n marginBottom: 4,\n },\n headerSubtitle: {\n fontSize: 14,\n },\n scrollView: {\n flex: 1,\n marginBottom: 16,\n },\n emptyContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n emptyText: {\n fontSize: 16,\n textAlign: \"center\",\n },\n messagesList: {\n gap: 8,\n paddingBottom: 16,\n },\n messageCard: {\n borderWidth: 1,\n padding: 12,\n maxWidth: \"80%\",\n },\n messageRole: {\n fontSize: 12,\n fontWeight: \"bold\",\n marginBottom: 4,\n },\n messageParts: {\n gap: 4,\n },\n messageText: {\n fontSize: 14,\n lineHeight: 20,\n },\n inputContainer: {\n borderTopWidth: 1,\n paddingTop: 12,\n },\n inputRow: {\n flexDirection: \"row\",\n alignItems: \"flex-end\",\n gap: 8,\n },\n input: {\n flex: 1,\n borderWidth: 1,\n padding: 8,\n fontSize: 14,\n minHeight: 36,\n maxHeight: 100,\n },\n sendButton: {\n padding: 8,\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n errorContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n padding: 16,\n },\n errorCard: {\n borderWidth: 1,\n padding: 16,\n },\n errorTitle: {\n fontSize: 16,\n fontWeight: \"bold\",\n marginBottom: 8,\n textAlign: \"center\",\n },\n errorText: {\n fontSize: 14,\n textAlign: \"center\",\n },\n});\n{{/if}}\n`],\n [\"examples/todo/native/unistyles/app/(drawer)/todos.tsx.hbs\", `import { useState } from \"react\";\nimport {\n View,\n Text,\n TextInput,\n TouchableOpacity,\n ScrollView,\n ActivityIndicator,\n Alert,\n} from \"react-native\";\nimport { Ionicons } from \"@expo/vector-icons\";\nimport { StyleSheet, useUnistyles } from \"react-native-unistyles\";\n\n{{#if (eq backend \"convex\")}}\nimport { useMutation, useQuery } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport type { Id } from \"@{{projectName}}/backend/convex/_generated/dataModel\";\n{{else}}\nimport { useMutation, useQuery } from \"@tanstack/react-query\";\n{{/if}}\n\nimport { Container } from \"@/components/container\";\n{{#unless (eq backend \"convex\")}}\n{{#if (eq api \"orpc\")}}\nimport { orpc } from \"@/utils/orpc\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { trpc } from \"@/utils/trpc\";\n{{/if}}\n{{/unless}}\n\nexport default function TodosScreen() {\n const [newTodoText, setNewTodoText] = useState(\"\");\n const { theme } = useUnistyles();\n\n {{#if (eq backend \"convex\")}}\n const todos = useQuery(api.todos.getAll);\n const createTodoMutation = useMutation(api.todos.create);\n const toggleTodoMutation = useMutation(api.todos.toggle);\n const deleteTodoMutation = useMutation(api.todos.deleteTodo);\n\n const handleAddTodo = async () => {\n const text = newTodoText.trim();\n if (!text) return;\n await createTodoMutation({ text });\n setNewTodoText(\"\");\n };\n\n const handleToggleTodo = (id: Id<\"todos\">, currentCompleted: boolean) => {\n toggleTodoMutation({ id, completed: !currentCompleted });\n };\n\n const handleDeleteTodo = (id: Id<\"todos\">) => {\n Alert.alert(\"Delete Todo\", \"Are you sure you want to delete this todo?\", [\n { text: \"Cancel\", style: \"cancel\" },\n {\n text: \"Delete\",\n style: \"destructive\",\n onPress: () => deleteTodoMutation({ id }),\n },\n ]);\n };\n {{else}}\n {{#if (eq api \"orpc\")}}\n const todos = useQuery(orpc.todo.getAll.queryOptions());\n const createMutation = useMutation(\n orpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n })\n );\n const toggleMutation = useMutation(\n orpc.todo.toggle.mutationOptions({\n onSuccess: () => { todos.refetch() },\n })\n );\n const deleteMutation = useMutation(\n orpc.todo.delete.mutationOptions({\n onSuccess: () => { todos.refetch() },\n })\n );\n {{/if}}\n {{#if (eq api \"trpc\")}}\n const todos = useQuery(trpc.todo.getAll.queryOptions());\n const createMutation = useMutation(\n trpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n })\n );\n const toggleMutation = useMutation(\n trpc.todo.toggle.mutationOptions({\n onSuccess: () => { todos.refetch() },\n })\n );\n const deleteMutation = useMutation(\n trpc.todo.delete.mutationOptions({\n onSuccess: () => { todos.refetch() },\n })\n );\n {{/if}}\n\n const handleAddTodo = () => {\n if (newTodoText.trim()) {\n createMutation.mutate({ text: newTodoText });\n }\n };\n\n const handleToggleTodo = (id: number, completed: boolean) => {\n toggleMutation.mutate({ id, completed: !completed });\n };\n\n const handleDeleteTodo = (id: number) => {\n Alert.alert(\"Delete Todo\", \"Are you sure you want to delete this todo?\", [\n { text: \"Cancel\", style: \"cancel\" },\n {\n text: \"Delete\",\n style: \"destructive\",\n onPress: () => deleteMutation.mutate({ id }),\n },\n ]);\n };\n {{/if}}\n\n const isLoading = {{#if (eq backend \"convex\")}}!todos{{else}}todos.isLoading{{/if}};\n const isCreating = {{#if (eq backend \"convex\")}}false{{else}}createMutation.isPending{{/if}};\n const primaryButtonTextColor = theme.colors.background;\n\n return (\n <Container>\n <ScrollView style={styles.scrollView}>\n <View style={styles.headerContainer}>\n <Text style={styles.headerTitle}>Todo List</Text>\n <Text style={styles.headerSubtitle}>\n Manage your tasks efficiently\n </Text>\n\n <View style={styles.inputContainer}>\n <TextInput\n value={newTodoText}\n onChangeText={setNewTodoText}\n placeholder=\"Add a new task...\"\n placeholderTextColor={theme.colors.border}\n editable={!isCreating}\n style={styles.textInput}\n onSubmitEditing={handleAddTodo}\n returnKeyType=\"done\"\n />\n <TouchableOpacity\n onPress={handleAddTodo}\n disabled={isCreating || !newTodoText.trim()}\n style={[\n styles.addButton,\n (isCreating || !newTodoText.trim()) && styles.addButtonDisabled,\n ]}\n >\n {isCreating ? (\n <ActivityIndicator size=\"small\" color={primaryButtonTextColor} />\n ) : (\n <Ionicons\n name=\"add\"\n size={24}\n color={primaryButtonTextColor}\n />\n )}\n </TouchableOpacity>\n </View>\n </View>\n\n {isLoading && (\n <View style={styles.loadingContainer}>\n <ActivityIndicator size=\"large\" color={theme.colors.primary} />\n <Text style={styles.loadingText}>Loading todos...</Text>\n </View>\n )}\n\n {{#if (eq backend \"convex\")}}\n {todos && todos.length === 0 && !isLoading && (\n <Text style={styles.emptyText}>No todos yet. Add one!</Text>\n )}\n {todos?.map((todo) => (\n <View key={todo._id} style={styles.todoItem}>\n <TouchableOpacity\n onPress={() => handleToggleTodo(todo._id, todo.completed)}\n style={styles.todoContent}\n >\n <Ionicons\n name={todo.completed ? \"checkbox\" : \"square-outline\"}\n size={24}\n color={todo.completed ? theme.colors.primary : theme.colors.typography}\n style={styles.checkbox}\n />\n <Text\n style={[\n styles.todoText,\n todo.completed && styles.todoTextCompleted,\n ]}\n >\n {todo.text}\n </Text>\n </TouchableOpacity>\n <TouchableOpacity onPress={() => handleDeleteTodo(todo._id)}>\n <Ionicons name=\"trash-outline\" size={24} color={theme.colors.destructive} />\n </TouchableOpacity>\n </View>\n ))}\n {{else}}\n {todos.data && todos.data.length === 0 && !isLoading && (\n <Text style={styles.emptyText}>No todos yet. Add one!</Text>\n )}\n {todos.data?.map((todo: { id: number; text: string; completed: boolean }) => (\n <View key={todo.id} style={styles.todoItem}>\n <TouchableOpacity\n onPress={() => handleToggleTodo(todo.id, todo.completed)}\n style={styles.todoContent}\n >\n <Ionicons\n name={todo.completed ? \"checkbox\" : \"square-outline\"}\n size={24}\n color={todo.completed ? theme.colors.primary : theme.colors.typography}\n style={styles.checkbox}\n />\n <Text\n style={[\n styles.todoText,\n todo.completed && styles.todoTextCompleted,\n ]}\n >\n {todo.text}\n </Text>\n </TouchableOpacity>\n <TouchableOpacity onPress={() => handleDeleteTodo(todo.id)}>\n <Ionicons name=\"trash-outline\" size={24} color={theme.colors.destructive} />\n </TouchableOpacity>\n </View>\n ))}\n {{/if}}\n </ScrollView>\n </Container>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n scrollView: {\n flex: 1,\n },\n headerContainer: {\n paddingHorizontal: theme.spacing.md,\n paddingVertical: theme.spacing.lg,\n borderBottomWidth: 1,\n borderBottomColor: theme.colors.border,\n backgroundColor: theme.colors.background,\n },\n headerTitle: {\n fontSize: 28,\n fontWeight: \"bold\",\n color: theme.colors.typography,\n marginBottom: theme.spacing.sm,\n },\n headerSubtitle: {\n fontSize: 16,\n color: theme.colors.typography,\n marginBottom: theme.spacing.md,\n },\n inputContainer: {\n flexDirection: \"row\",\n alignItems: \"center\",\n marginBottom: theme.spacing.md,\n },\n textInput: {\n flex: 1,\n borderWidth: 1,\n borderColor: theme.colors.border,\n borderRadius: 8,\n paddingHorizontal: theme.spacing.md,\n paddingVertical: theme.spacing.sm,\n color: theme.colors.typography,\n backgroundColor: theme.colors.background,\n marginRight: theme.spacing.sm,\n fontSize: 16,\n },\n addButton: {\n backgroundColor: theme.colors.primary,\n padding: theme.spacing.sm,\n borderRadius: 8,\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n addButtonDisabled: {\n backgroundColor: theme.colors.border,\n },\n loadingContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n padding: theme.spacing.lg,\n },\n loadingText: {\n marginTop: theme.spacing.sm,\n fontSize: 16,\n color: theme.colors.typography,\n },\n emptyText: {\n textAlign: \"center\",\n marginTop: theme.spacing.xl,\n fontSize: 16,\n color: theme.colors.typography,\n },\n todoItem: {\n flexDirection: \"row\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n paddingVertical: theme.spacing.md,\n paddingHorizontal: theme.spacing.md,\n borderBottomWidth: 1,\n borderBottomColor: theme.colors.border,\n backgroundColor: theme.colors.background,\n },\n todoContent: {\n flexDirection: \"row\",\n alignItems: \"center\",\n flex: 1,\n },\n checkbox: {\n marginRight: theme.spacing.md,\n },\n todoText: {\n fontSize: 16,\n color: theme.colors.typography,\n flex: 1,\n },\n todoTextCompleted: {\n textDecorationLine: \"line-through\",\n color: theme.colors.border,\n },\n}));\n`],\n [\"examples/ai/native/unistyles/app/(drawer)/ai.tsx.hbs\", `{{#if (eq backend \"convex\")}}\nimport { Ionicons } from \"@expo/vector-icons\";\nimport {\n useUIMessages,\n useSmoothText,\n type UIMessage,\n} from \"@convex-dev/agent/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport { useMutation } from \"convex/react\";\nimport React, { useRef, useEffect, useState } from \"react\";\nimport {\n View,\n Text,\n TextInput,\n TouchableOpacity,\n ScrollView,\n KeyboardAvoidingView,\n Platform,\n ActivityIndicator,\n} from \"react-native\";\nimport { StyleSheet, useUnistyles } from \"react-native-unistyles\";\n\nimport { Container } from \"@/components/container\";\n\nfunction MessageContent({\n text,\n isStreaming,\n style,\n}: {\n text: string;\n isStreaming: boolean;\n style: object;\n}) {\n const [visibleText] = useSmoothText(text, {\n startStreaming: isStreaming,\n });\n return <Text style={style}>{visibleText}</Text>;\n}\n\nexport default function AIScreen() {\n const { theme } = useUnistyles();\n const [input, setInput] = useState(\"\");\n const [threadId, setThreadId] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const scrollViewRef = useRef<ScrollView>(null);\n\n const createThread = useMutation(api.chat.createNewThread);\n const sendMessage = useMutation(api.chat.sendMessage);\n\n const { results: messages } = useUIMessages(\n api.chat.listMessages,\n threadId ? { threadId } : \"skip\",\n { initialNumItems: 50, stream: true },\n );\n\n const hasStreamingMessage = messages?.some(\n (m: UIMessage) => m.status === \"streaming\",\n );\n\n useEffect(() => {\n scrollViewRef.current?.scrollToEnd({ animated: true });\n }, [messages]);\n\n const onSubmit = async () => {\n const value = input.trim();\n if (!value || isLoading) return;\n\n setIsLoading(true);\n setInput(\"\");\n\n try {\n let currentThreadId = threadId;\n if (!currentThreadId) {\n currentThreadId = await createThread();\n setThreadId(currentThreadId);\n }\n\n await sendMessage({ threadId: currentThreadId, prompt: value });\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n };\n\n return (\n <Container>\n <KeyboardAvoidingView\n style={styles.container}\n behavior={Platform.OS === \"ios\" ? \"padding\" : \"height\"}\n >\n <View style={styles.content}>\n <View style={styles.header}>\n <Text style={styles.headerTitle}>AI Chat</Text>\n <Text style={styles.headerSubtitle}>\n Chat with our AI assistant\n </Text>\n </View>\n\n <ScrollView\n ref={scrollViewRef}\n style={styles.messagesContainer}\n showsVerticalScrollIndicator={false}\n >\n {!messages || messages.length === 0 ? (\n <View style={styles.emptyContainer}>\n <Text style={styles.emptyText}>\n Ask me anything to get started!\n </Text>\n </View>\n ) : (\n <View style={styles.messagesWrapper}>\n {messages.map((message: UIMessage) => (\n <View\n key={message.key}\n style={[\n styles.messageContainer,\n message.role === \"user\"\n ? styles.userMessage\n : styles.assistantMessage,\n ]}\n >\n <Text style={styles.messageRole}>\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </Text>\n <MessageContent\n text={message.text ?? \"\"}\n isStreaming={message.status === \"streaming\"}\n style={styles.messageContent}\n />\n </View>\n ))}\n {isLoading && !hasStreamingMessage && (\n <View style={[styles.messageContainer, styles.assistantMessage]}>\n <Text style={styles.messageRole}>AI Assistant</Text>\n <View style={styles.loadingContainer}>\n <ActivityIndicator size=\"small\" color={theme.colors.primary} />\n <Text style={styles.loadingText}>Thinking...</Text>\n </View>\n </View>\n )}\n </View>\n )}\n </ScrollView>\n\n <View style={styles.inputSection}>\n <View style={styles.inputContainer}>\n <TextInput\n value={input}\n onChangeText={setInput}\n placeholder=\"Type your message...\"\n placeholderTextColor={theme.colors.border}\n style={styles.textInput}\n onSubmitEditing={(e) => {\n e.preventDefault();\n onSubmit();\n }}\n editable={!isLoading}\n autoFocus={true}\n />\n <TouchableOpacity\n onPress={onSubmit}\n disabled={!input.trim() || isLoading}\n style={[\n styles.sendButton,\n (!input.trim() || isLoading) && styles.sendButtonDisabled,\n ]}\n >\n <Ionicons\n name=\"send\"\n size={20}\n color={\n input.trim() && !isLoading\n ? theme.colors.background\n : theme.colors.border\n }\n />\n </TouchableOpacity>\n </View>\n </View>\n </View>\n </KeyboardAvoidingView>\n </Container>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n container: {\n flex: 1,\n },\n content: {\n flex: 1,\n paddingHorizontal: theme.spacing.md,\n paddingVertical: theme.spacing.lg,\n },\n header: {\n marginBottom: theme.spacing.lg,\n },\n headerTitle: {\n fontSize: 28,\n fontWeight: \"bold\",\n color: theme.colors.typography,\n marginBottom: theme.spacing.sm,\n },\n headerSubtitle: {\n fontSize: 16,\n color: theme.colors.typography,\n },\n messagesContainer: {\n flex: 1,\n marginBottom: theme.spacing.md,\n },\n emptyContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n emptyText: {\n textAlign: \"center\",\n color: theme.colors.typography,\n fontSize: 18,\n },\n messagesWrapper: {\n gap: theme.spacing.md,\n },\n messageContainer: {\n padding: theme.spacing.md,\n borderRadius: 8,\n },\n userMessage: {\n backgroundColor: theme.colors.primary + \"20\",\n marginLeft: theme.spacing.xl,\n alignSelf: \"flex-end\",\n },\n assistantMessage: {\n backgroundColor: theme.colors.background,\n marginRight: theme.spacing.xl,\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n messageRole: {\n fontSize: 14,\n fontWeight: \"600\",\n marginBottom: theme.spacing.sm,\n color: theme.colors.typography,\n },\n messageContent: {\n color: theme.colors.typography,\n lineHeight: 20,\n },\n loadingContainer: {\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: theme.spacing.sm,\n },\n loadingText: {\n color: theme.colors.typography,\n opacity: 0.7,\n },\n inputSection: {\n borderTopWidth: 1,\n borderTopColor: theme.colors.border,\n paddingTop: theme.spacing.md,\n },\n inputContainer: {\n flexDirection: \"row\",\n alignItems: \"flex-end\",\n gap: theme.spacing.sm,\n },\n textInput: {\n flex: 1,\n borderWidth: 1,\n borderColor: theme.colors.border,\n borderRadius: 8,\n paddingHorizontal: theme.spacing.md,\n paddingVertical: theme.spacing.sm,\n color: theme.colors.typography,\n backgroundColor: theme.colors.background,\n fontSize: 16,\n minHeight: 40,\n maxHeight: 120,\n },\n sendButton: {\n backgroundColor: theme.colors.primary,\n padding: theme.spacing.sm,\n borderRadius: 8,\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n sendButtonDisabled: {\n backgroundColor: theme.colors.border,\n },\n}));\n{{else}}\nimport React, { useRef, useEffect, useState } from \"react\";\nimport {\n View,\n Text,\n TextInput,\n TouchableOpacity,\n ScrollView,\n KeyboardAvoidingView,\n Platform,\n} from \"react-native\";\nimport { useChat } from \"@ai-sdk/react\";\nimport { DefaultChatTransport } from \"ai\";\nimport { fetch as expoFetch } from \"expo/fetch\";\nimport { Ionicons } from \"@expo/vector-icons\";\nimport { StyleSheet, useUnistyles } from \"react-native-unistyles\";\nimport { Container } from \"@/components/container\";\nimport { env } from \"@{{projectName}}/env/native\";\n\nconst generateAPIUrl = (relativePath: string) => {\n const serverUrl = env.EXPO_PUBLIC_SERVER_URL;\n if (!serverUrl) {\n throw new Error(\n \"EXPO_PUBLIC_SERVER_URL environment variable is not defined\"\n );\n }\n const path = relativePath.startsWith(\"/\") ? relativePath : \\`/\\${relativePath}\\`;\n return serverUrl.concat(path);\n};\n\nexport default function AIScreen() {\n const { theme } = useUnistyles();\n const [input, setInput] = useState(\"\");\n const { messages, error, sendMessage } = useChat({\n transport: new DefaultChatTransport({\n fetch: expoFetch as unknown as typeof globalThis.fetch,\n api: generateAPIUrl(\"/ai\"),\n }),\n onError: (error) => console.error(error, \"AI Chat Error\"),\n });\n\n const scrollViewRef = useRef<ScrollView>(null);\n\n useEffect(() => {\n scrollViewRef.current?.scrollToEnd({ animated: true });\n }, [messages]);\n\n const onSubmit = () => {\n const value = input.trim();\n if (value) {\n sendMessage({ text: value });\n setInput(\"\");\n }\n };\n\n if (error) {\n return (\n <Container>\n <View style={styles.errorContainer}>\n <Text style={styles.errorText}>Error: {error.message}</Text>\n <Text style={styles.errorSubtext}>\n Please check your connection and try again.\n </Text>\n </View>\n </Container>\n );\n }\n\n return (\n <Container>\n <KeyboardAvoidingView\n style={styles.container}\n behavior={Platform.OS === \"ios\" ? \"padding\" : \"height\"}\n >\n <View style={styles.content}>\n <View style={styles.header}>\n <Text style={styles.headerTitle}>AI Chat</Text>\n <Text style={styles.headerSubtitle}>\n Chat with our AI assistant\n </Text>\n </View>\n\n <ScrollView\n ref={scrollViewRef}\n style={styles.messagesContainer}\n showsVerticalScrollIndicator={false}\n >\n {messages.length === 0 ? (\n <View style={styles.emptyContainer}>\n <Text style={styles.emptyText}>\n Ask me anything to get started!\n </Text>\n </View>\n ) : (\n <View style={styles.messagesWrapper}>\n {messages.map((message) => (\n <View\n key={message.id}\n style={[\n styles.messageContainer,\n message.role === \"user\"\n ? styles.userMessage\n : styles.assistantMessage,\n ]}\n >\n <Text style={styles.messageRole}>\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </Text>\n <View style={styles.messageContentWrapper}>\n {message.parts.map((part, i) => {\n if (part.type === \"text\") {\n return (\n <Text\n key={\\`\\${message.id}-\\${i}\\`}\n style={styles.messageContent}\n >\n {part.text}\n </Text>\n );\n }\n return (\n <Text\n key={\\`\\${message.id}-\\${i}\\`}\n style={styles.messageContent}\n >\n {JSON.stringify(part)}\n </Text>\n );\n })}\n </View>\n </View>\n ))}\n </View>\n )}\n </ScrollView>\n\n <View style={styles.inputSection}>\n <View style={styles.inputContainer}>\n <TextInput\n value={input}\n onChangeText={setInput}\n placeholder=\"Type your message...\"\n placeholderTextColor={theme.colors.border}\n style={styles.textInput}\n onSubmitEditing={(e) => {\n e.preventDefault();\n onSubmit();\n }}\n autoFocus={true}\n />\n <TouchableOpacity\n onPress={onSubmit}\n disabled={!input.trim()}\n style={[\n styles.sendButton,\n !input.trim() && styles.sendButtonDisabled,\n ]}\n >\n <Ionicons\n name=\"send\"\n size={20}\n color={\n input.trim()\n ? theme.colors.background\n : theme.colors.border\n }\n />\n </TouchableOpacity>\n </View>\n </View>\n </View>\n </KeyboardAvoidingView>\n </Container>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n container: {\n flex: 1,\n },\n content: {\n flex: 1,\n paddingHorizontal: theme.spacing.md,\n paddingVertical: theme.spacing.lg,\n },\n errorContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n paddingHorizontal: theme.spacing.md,\n },\n errorText: {\n color: theme.colors.destructive,\n textAlign: \"center\",\n fontSize: 18,\n marginBottom: theme.spacing.md,\n },\n errorSubtext: {\n color: theme.colors.typography,\n textAlign: \"center\",\n fontSize: 16,\n },\n header: {\n marginBottom: theme.spacing.lg,\n },\n headerTitle: {\n fontSize: 28,\n fontWeight: \"bold\",\n color: theme.colors.typography,\n marginBottom: theme.spacing.sm,\n },\n headerSubtitle: {\n fontSize: 16,\n color: theme.colors.typography,\n },\n messagesContainer: {\n flex: 1,\n marginBottom: theme.spacing.md,\n },\n emptyContainer: {\n flex: 1,\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n emptyText: {\n textAlign: \"center\",\n color: theme.colors.typography,\n fontSize: 18,\n },\n messagesWrapper: {\n gap: theme.spacing.md,\n },\n messageContainer: {\n padding: theme.spacing.md,\n borderRadius: 8,\n },\n userMessage: {\n backgroundColor: theme.colors.primary + \"20\",\n marginLeft: theme.spacing.xl,\n alignSelf: \"flex-end\",\n },\n assistantMessage: {\n backgroundColor: theme.colors.background,\n marginRight: theme.spacing.xl,\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n messageRole: {\n fontSize: 14,\n fontWeight: \"600\",\n marginBottom: theme.spacing.sm,\n color: theme.colors.typography,\n },\n messageContentWrapper: {\n gap: theme.spacing.xs,\n },\n messageContent: {\n color: theme.colors.typography,\n lineHeight: 20,\n },\n inputSection: {\n borderTopWidth: 1,\n borderTopColor: theme.colors.border,\n paddingTop: theme.spacing.md,\n },\n inputContainer: {\n flexDirection: \"row\",\n alignItems: \"flex-end\",\n gap: theme.spacing.sm,\n },\n textInput: {\n flex: 1,\n borderWidth: 1,\n borderColor: theme.colors.border,\n borderRadius: 8,\n paddingHorizontal: theme.spacing.md,\n paddingVertical: theme.spacing.sm,\n color: theme.colors.typography,\n backgroundColor: theme.colors.background,\n fontSize: 16,\n minHeight: 40,\n maxHeight: 120,\n },\n sendButton: {\n backgroundColor: theme.colors.primary,\n padding: theme.spacing.sm,\n borderRadius: 8,\n justifyContent: \"center\",\n alignItems: \"center\",\n },\n sendButtonDisabled: {\n backgroundColor: theme.colors.border,\n },\n}));\n{{/if}}\n`],\n [\"examples/ai/web/nuxt/app/pages/ai.vue.hbs\", `<script setup lang=\"ts\">\nimport { Chat } from '@ai-sdk/vue'\nimport type { UIMessage } from 'ai'\nimport { getTextFromMessage } from '@nuxt/ui/utils/ai'\nimport { DefaultChatTransport } from 'ai'\nimport { ref } from 'vue'\n\nconst config = useRuntimeConfig()\nconst messages: UIMessage[] = []\nconst input = ref('')\n\nconst chat = new Chat({\n messages,\n transport: new DefaultChatTransport({\n api: \\`\\${config.public.serverUrl}/ai\\`,\n }),\n onError(error) {\n console.error('Chat error:', error)\n }\n})\n\nasync function handleSubmit(e: Event) {\n e.preventDefault()\n const userInput = input.value\n input.value = ''\n\n if (!userInput.trim()) return\n\n chat.sendMessage({ text: userInput })\n}\n</script>\n\n<template>\n <UContainer class=\"h-full flex flex-col overflow-hidden py-4\">\n <div class=\"flex-1 min-h-0 overflow-y-auto\">\n <UChatMessages :messages=\"chat.messages\" :status=\"chat.status\">\n <template #content=\"{ message }\">\n <div class=\"whitespace-pre-wrap\">\\\\{{ getTextFromMessage(message) }}</div>\n </template>\n </UChatMessages>\n </div>\n\n <div class=\"shrink-0 pt-4 border-t border-gray-200 dark:border-gray-800\">\n <UChatPrompt\n v-model=\"input\"\n :error=\"chat.error\"\n @submit=\"handleSubmit\"\n placeholder=\"Type your message...\"\n >\n <UChatPromptSubmit :status=\"chat.status\" @stop=\"() => chat.stop()\" @reload=\"() => chat.regenerate()\" />\n </UChatPrompt>\n </div>\n </UContainer>\n</template>`],\n [\"frontend/native/unistyles/app/(drawer)/(tabs)/_layout.tsx.hbs\", `import { Tabs } from \"expo-router\";\nimport { useUnistyles } from \"react-native-unistyles\";\n\nimport { TabBarIcon } from \"@/components/tabbar-icon\";\n\nexport default function TabLayout() {\n const { theme } = useUnistyles();\n\n return (\n <Tabs\n screenOptions=\\\\{{\n headerShown: false,\n tabBarActiveTintColor: theme.colors.primary,\n tabBarInactiveTintColor: theme.colors.mutedForeground,\n tabBarStyle: {\n backgroundColor: theme.colors.background,\n borderTopColor: theme.colors.border,\n },\n }}\n >\n <Tabs.Screen\n name=\"index\"\n options=\\\\{{\n title: \"Home\",\n tabBarIcon: ({ color }) => <TabBarIcon name=\"home\" color={color} />,\n }}\n />\n <Tabs.Screen\n name=\"two\"\n options=\\\\{{\n title: \"Explore\",\n tabBarIcon: ({ color }) => (\n <TabBarIcon name=\"compass\" color={color} />\n ),\n }}\n />\n </Tabs>\n );\n}\n`],\n [\"frontend/native/unistyles/app/(drawer)/(tabs)/two.tsx.hbs\", `import { Container } from \"@/components/container\";\nimport { ScrollView, Text, View } from \"react-native\";\nimport { StyleSheet } from \"react-native-unistyles\";\n\nexport default function TabTwo() {\n return (\n <Container>\n <ScrollView contentContainerStyle={styles.container}>\n <View style={styles.headerSection}>\n <Text style={styles.title}>Tab Two</Text>\n <Text style={styles.subtitle}>\n Discover more features and content\n </Text>\n </View>\n </ScrollView>\n </Container>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n container: {\n padding: theme.spacing.lg,\n },\n headerSection: {\n paddingVertical: theme.spacing.xl,\n },\n title: {\n fontSize: theme.fontSize[\"3xl\"],\n fontWeight: \"bold\",\n color: theme.colors.foreground,\n marginBottom: theme.spacing.sm,\n },\n subtitle: {\n fontSize: theme.fontSize.lg,\n color: theme.colors.mutedForeground,\n },\n}));\n`],\n [\"frontend/native/unistyles/app/(drawer)/(tabs)/index.tsx.hbs\", `import { Container } from \"@/components/container\";\nimport { ScrollView, Text, View } from \"react-native\";\nimport { StyleSheet } from \"react-native-unistyles\";\n\nexport default function Home() {\n return (\n <Container>\n <ScrollView contentContainerStyle={styles.container}>\n <View style={styles.headerSection}>\n <Text style={styles.title}>Tab One</Text>\n <Text style={styles.subtitle}>\n Explore the first section of your app\n </Text>\n </View>\n </ScrollView>\n </Container>\n );\n}\n\nconst styles = StyleSheet.create((theme) => ({\n container: {\n padding: theme.spacing.lg,\n },\n headerSection: {\n paddingVertical: theme.spacing.xl,\n },\n title: {\n fontSize: theme.fontSize[\"3xl\"],\n fontWeight: \"bold\",\n color: theme.colors.foreground,\n marginBottom: theme.spacing.sm,\n },\n subtitle: {\n fontSize: theme.fontSize.lg,\n color: theme.colors.mutedForeground,\n },\n}));\n`],\n [\"frontend/native/bare/app/(drawer)/(tabs)/_layout.tsx.hbs\", `import { TabBarIcon } from \"@/components/tabbar-icon\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { Tabs } from \"expo-router\";\nimport { NAV_THEME } from \"@/lib/constants\";\n\nexport default function TabLayout() {\n const { isDarkColorScheme } = useColorScheme();\n const theme = isDarkColorScheme ? NAV_THEME.dark : NAV_THEME.light;\n\n return (\n <Tabs\n screenOptions=\\\\{{\n headerShown: false,\n tabBarActiveTintColor: theme.primary,\n tabBarInactiveTintColor: theme.text,\n tabBarStyle: {\n backgroundColor: theme.background,\n borderTopColor: theme.border,\n },\n }}\n >\n <Tabs.Screen\n name=\"index\"\n options=\\\\{{\n title: \"Home\",\n tabBarIcon: ({ color }) => <TabBarIcon name=\"home\" color={color} />,\n }}\n />\n <Tabs.Screen\n name=\"two\"\n options=\\\\{{\n title: \"Explore\",\n tabBarIcon: ({ color }) => (\n <TabBarIcon name=\"compass\" color={color} />\n ),\n }}\n />\n </Tabs>\n );\n}\n\n`],\n [\"frontend/native/bare/app/(drawer)/(tabs)/two.tsx.hbs\", `import { Container } from \"@/components/container\";\nimport { ScrollView, Text, View, StyleSheet } from \"react-native\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\n\nexport default function TabTwo() {\n const { colorScheme } = useColorScheme();\n const theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\n\n return (\n <Container>\n <ScrollView style={styles.scrollView}>\n <View style={styles.content}>\n <Text style={[styles.title, { color: theme.text }]}>\n Tab Two\n </Text>\n <Text style={[styles.subtitle, { color: theme.text, opacity: 0.7 }]}>\n Discover more features and content\n </Text>\n </View>\n </ScrollView>\n </Container>\n );\n}\n\nconst styles = StyleSheet.create({\n scrollView: {\n flex: 1,\n padding: 16,\n },\n content: {\n paddingVertical: 16,\n },\n title: {\n fontSize: 24,\n fontWeight: \"bold\",\n marginBottom: 8,\n },\n subtitle: {\n fontSize: 16,\n },\n});\n\n`],\n [\"frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs\", `import { Container } from \"@/components/container\";\nimport { ScrollView, Text, View, StyleSheet } from \"react-native\";\nimport { useColorScheme } from \"@/lib/use-color-scheme\";\nimport { NAV_THEME } from \"@/lib/constants\";\n\nexport default function TabOne() {\n const { colorScheme } = useColorScheme();\n const theme = colorScheme === \"dark\" ? NAV_THEME.dark : NAV_THEME.light;\n\n return (\n <Container>\n <ScrollView style={styles.scrollView}>\n <View style={styles.content}>\n <Text style={[styles.title, { color: theme.text }]}>\n Tab One\n </Text>\n <Text style={[styles.subtitle, { color: theme.text, opacity: 0.7 }]}>\n Explore the first section of your app\n </Text>\n </View>\n </ScrollView>\n </Container>\n );\n}\n\nconst styles = StyleSheet.create({\n scrollView: {\n flex: 1,\n padding: 16,\n },\n content: {\n paddingVertical: 16,\n },\n title: {\n fontSize: 24,\n fontWeight: \"bold\",\n marginBottom: 8,\n },\n subtitle: {\n fontSize: 16,\n },\n});\n\n`],\n [\"frontend/native/uniwind/app/(drawer)/(tabs)/_layout.tsx.hbs\", `import { Tabs } from \"expo-router\";\nimport { Ionicons } from \"@expo/vector-icons\";\nimport { useThemeColor } from \"heroui-native\";\n\nexport default function TabLayout() {\n\tconst themeColorForeground = useThemeColor(\"foreground\");\n\tconst themeColorBackground = useThemeColor(\"background\");\n\n\treturn (\n\t\t<Tabs\n\t\t\tscreenOptions=\\\\{{\n\t\t\t\theaderShown: false,\n\t\t\t\theaderStyle: {\n\t\t\t\t\tbackgroundColor: themeColorBackground,\n\t\t\t\t},\n\t\t\t\theaderTintColor: themeColorForeground,\n\t\t\t\theaderTitleStyle: {\n\t\t\t\t\tcolor: themeColorForeground,\n\t\t\t\t\tfontWeight: \"600\",\n\t\t\t\t},\n\t\t\t\ttabBarStyle: {\n\t\t\t\t\tbackgroundColor: themeColorBackground,\n\t\t\t\t},\n\t\t\t}}\n\t\t>\n\t\t\t<Tabs.Screen\n\t\t\t\tname=\"index\"\n\t\t\t\toptions=\\\\{{\n\t\t\t\t\ttitle: \"Home\",\n\t\t\t\t\ttabBarIcon: ({ color, size }: { color: string; size: number }) => (\n\t\t\t\t\t\t<Ionicons name=\"home\" size={size} color={color} />\n\t\t\t\t\t),\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<Tabs.Screen\n\t\t\t\tname=\"two\"\n\t\t\t\toptions=\\\\{{\n\t\t\t\t\ttitle: \"Explore\",\n\t\t\t\t\ttabBarIcon: ({ color, size }: { color: string; size: number }) => (\n\t\t\t\t\t\t<Ionicons name=\"compass\" size={size} color={color} />\n\t\t\t\t\t),\n\t\t\t\t}}\n\t\t\t/>\n\t\t</Tabs>\n\t);\n}\n`],\n [\"frontend/native/uniwind/app/(drawer)/(tabs)/two.tsx.hbs\", `import { Container } from \"@/components/container\";\nimport { Text, View } from \"react-native\";\nimport { Card } from \"heroui-native\";\n\nexport default function TabTwo() {\n\treturn (\n\t\t<Container className=\"p-6\">\n\t\t\t<View className=\"flex-1 justify-center items-center\">\n\t\t\t\t<Card variant=\"secondary\" className=\"p-8 items-center\">\n\t\t\t\t\t<Card.Title className=\"text-3xl mb-2\">TabTwo</Card.Title>\n\t\t\t\t</Card>\n\t\t\t</View>\n\t\t</Container>\n\t);\n}\n`],\n [\"frontend/native/uniwind/app/(drawer)/(tabs)/index.tsx.hbs\", `import { Container } from \"@/components/container\";\nimport { Text, View } from \"react-native\";\nimport { Card } from \"heroui-native\";\n\nexport default function Home() {\n\treturn (\n\t\t<Container className=\"p-6\">\n\t\t\t<View className=\"flex-1 justify-center items-center\">\n\t\t\t\t<Card variant=\"secondary\" className=\"p-8 items-center\">\n\t\t\t\t\t<Card.Title className=\"text-3xl mb-2\">Tab One</Card.Title>\n\t\t\t\t</Card>\n\t\t\t</View>\n\t\t</Container>\n\t);\n}\n`],\n [\"logging/pino/server/base/src/lib/logger.ts.hbs\", `import pino from \"pino\";\nimport type { Logger, LoggerOptions } from \"pino\";\n\n// Log levels: trace, debug, info, warn, error, fatal\nconst logLevel = (process.env.LOG_LEVEL || \"info\") as pino.LevelWithSilent;\nconst isDevelopment = process.env.NODE_ENV !== \"production\";\n\n// Create logger options\nconst loggerOptions: LoggerOptions = {\n level: logLevel,\n // Add timestamp formatting\n timestamp: pino.stdTimeFunctions.isoTime,\n // Base context for all logs\n base: {\n env: process.env.NODE_ENV || \"development\",\n },\n};\n\n// Use pino-pretty in development for readable logs\n// In production, use raw JSON for better performance and log aggregation\nlet logger: Logger;\n\nif (isDevelopment && process.env.PINO_PRETTY !== \"false\") {\n logger = pino({\n ...loggerOptions,\n transport: {\n target: \"pino-pretty\",\n options: {\n colorize: true,\n translateTime: \"SYS:standard\",\n ignore: \"pid,hostname\",\n singleLine: false,\n },\n },\n });\n} else {\n logger = pino(loggerOptions);\n}\n\n/**\n * Create a child logger with additional context\n * Useful for adding request IDs, user IDs, or other contextual information\n *\n * @example\n * const requestLogger = createChildLogger({ requestId: 'abc123', userId: 'user456' });\n * requestLogger.info('Processing request');\n */\nexport function createChildLogger(bindings: Record<string, unknown>): Logger {\n return logger.child(bindings);\n}\n\n/**\n * Log levels explained:\n * - trace: Most detailed logging, typically disabled in production\n * - debug: Detailed information useful during development\n * - info: General information about application flow\n * - warn: Warning messages for potentially problematic situations\n * - error: Error messages for failures that don't stop the application\n * - fatal: Critical errors that may cause the application to terminate\n *\n * @example\n * logger.info('Server started');\n * logger.info({ port: 3000 }, 'Server started on port');\n * logger.error({ err: error }, 'Failed to process request');\n * logger.debug({ userId, action }, 'User action logged');\n */\nexport { logger };\n\nexport default logger;\n`],\n [\"logging/winston/server/base/src/lib/logger.ts.hbs\", `import winston from \"winston\";\n\n// Log levels: error, warn, info, http, verbose, debug, silly\nconst logLevel = process.env.LOG_LEVEL || \"info\";\nconst isDevelopment = process.env.NODE_ENV !== \"production\";\n\n// Custom format for development with colors\nconst devFormat = winston.format.combine(\n winston.format.colorize(),\n winston.format.timestamp({ format: \"YYYY-MM-DD HH:mm:ss\" }),\n winston.format.printf(({ timestamp, level, message, ...meta }) => {\n const metaStr = Object.keys(meta).length ? \\` \\${JSON.stringify(meta)}\\` : \"\";\n return \\`\\${timestamp} [\\${level}]: \\${message}\\${metaStr}\\`;\n }),\n);\n\n// JSON format for production\nconst prodFormat = winston.format.combine(\n winston.format.timestamp(),\n winston.format.errors({ stack: true }),\n winston.format.json(),\n);\n\n// Create logger instance\nconst logger = winston.createLogger({\n level: logLevel,\n format: isDevelopment ? devFormat : prodFormat,\n defaultMeta: { env: process.env.NODE_ENV || \"development\" },\n transports: [\n new winston.transports.Console({\n stderrLevels: [\"error\"],\n }),\n ],\n});\n\n/**\n * Create a child logger with additional context\n * Useful for adding request IDs, user IDs, or other contextual information\n *\n * @example\n * const requestLogger = createChildLogger({ requestId: 'abc123', userId: 'user456' });\n * requestLogger.info('Processing request');\n */\nexport function createChildLogger(bindings: Record<string, unknown>): winston.Logger {\n return logger.child(bindings);\n}\n\n/**\n * Log levels explained (npm log levels):\n * - error (0): Error messages for failures that don't stop the application\n * - warn (1): Warning messages for potentially problematic situations\n * - info (2): General information about application flow\n * - http (3): HTTP request logging\n * - verbose (4): More detailed than info\n * - debug (5): Detailed information useful during development\n * - silly (6): Most detailed logging\n *\n * @example\n * logger.info('Server started');\n * logger.info('Server started on port', { port: 3000 });\n * logger.error('Failed to process request', { err: error });\n * logger.debug('User action logged', { userId, action });\n */\nexport { logger };\n\nexport default logger;\n`],\n [\"api/ts-rest/fullstack/next/src/utils/ts-rest.ts.hbs\", `import { QueryClient } from \"@tanstack/react-query\";\nimport { initClient, tsRestFetchApi } from \"@ts-rest/core\";\nimport { initTsrReactQuery } from \"@ts-rest/react-query\";\nimport { contract } from \"@{{projectName}}/api/index\";\n\nexport const queryClient = new QueryClient({\n\tdefaultOptions: {\n\t\tqueries: {\n\t\t\tretry: 2,\n\t\t\tstaleTime: 1000 * 60,\n\t\t},\n\t},\n});\n\nconst client = initClient(contract, {\n\tbaseUrl: \"/api/rest\",\n\tbaseHeaders: {},\n{{#if (eq auth \"better-auth\")}}\n\tcredentials: \"include\",\n{{/if}}\n\tapi: tsRestFetchApi,\n});\n\nexport const tsr = initTsrReactQuery(contract, client);\n`],\n [\"api/ts-rest/fullstack/astro/src/utils/ts-rest.ts.hbs\", `import { QueryClient } from \"@tanstack/react-query\";\nimport { initClient, tsRestFetchApi } from \"@ts-rest/core\";\nimport { initTsrReactQuery } from \"@ts-rest/react-query\";\nimport { contract } from \"@{{projectName}}/api/index\";\n\nexport const queryClient = new QueryClient({\n\tdefaultOptions: {\n\t\tqueries: {\n\t\t\tretry: 2,\n\t\t\tstaleTime: 1000 * 60,\n\t\t},\n\t},\n});\n\nconst client = initClient(contract, {\n\tbaseUrl: \"/api/rest\",\n\tbaseHeaders: {},\n{{#if (eq auth \"better-auth\")}}\n\tcredentials: \"include\",\n{{/if}}\n\tapi: tsRestFetchApi,\n});\n\nexport const tsr = initTsrReactQuery(contract, client);\n`],\n [\"api/ts-rest/fullstack/tanstack-start/src/utils/ts-rest.ts.hbs\", `import { QueryClient } from \"@tanstack/react-query\";\nimport { initClient, tsRestFetchApi } from \"@ts-rest/core\";\nimport { initTsrReactQuery } from \"@ts-rest/react-query\";\nimport { contract } from \"@{{projectName}}/api/index\";\n\nexport const queryClient = new QueryClient({\n\tdefaultOptions: {\n\t\tqueries: {\n\t\t\tretry: 2,\n\t\t\tstaleTime: 1000 * 60,\n\t\t},\n\t},\n});\n\nconst client = initClient(contract, {\n\tbaseUrl: \"/api/rest\",\n\tbaseHeaders: {},\n{{#if (eq auth \"better-auth\")}}\n\tcredentials: \"include\",\n{{/if}}\n\tapi: tsRestFetchApi,\n});\n\nexport const tsr = initTsrReactQuery(contract, client);\n`],\n [\"api/garph/web/astro/src/utils/garph.ts.hbs\", `import { createClient, type InferClient } from \"@garph/gqty\";\nimport {\n createGeneratedSchema,\n createScalarsEnumsHash,\n} from \"@garph/gqty/dist/utils\";\nimport {\n g,\n queryType,\n mutationType,\n{{#if (includes examples \"todo\")}}\n todoType,\n{{/if}}\n} from \"@{{projectName}}/api/index\";\nimport { env } from \"@{{projectName}}/env/web\";\n\n// Generate schema and scalars for GQty client\nconst generatedSchema = createGeneratedSchema(g);\nconst scalarsEnumsHash = createScalarsEnumsHash(g);\n\n// Create type-safe GraphQL client\nexport const client = createClient<{\n query: InferClient<typeof queryType>;\n mutation: InferClient<typeof mutationType>;\n}>({\n generatedSchema,\n scalarsEnumsHash,\n url: \\`\\${env.VITE_SERVER_URL}/graphql\\`,\n{{#if (eq auth \"better-auth\")}}\n credentials: \"include\",\n{{/if}}\n});\n\n// Export typed query and mutation functions\nexport const { query, mutation, resolved } = client;\n\n// Helper for fetching data\nexport async function graphqlFetcher<T>(\n fn: () => T | Promise<T>\n): Promise<T> {\n return resolved(fn);\n}\n`],\n [\"api/garph/fullstack/tanstack-start/src/utils/garph.ts.hbs\", `import { QueryClient } from \"@tanstack/react-query\";\nimport { createClient, type InferClient } from \"@garph/gqty\";\nimport {\n createGeneratedSchema,\n createScalarsEnumsHash,\n} from \"@garph/gqty/dist/utils\";\nimport {\n g,\n queryType,\n mutationType,\n{{#if (includes examples \"todo\")}}\n todoType,\n{{/if}}\n} from \"@{{projectName}}/api/index\";\n\n// Create QueryClient for React Query integration\nexport const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n retry: 2,\n staleTime: 1000 * 60,\n },\n },\n});\n\n// Generate schema and scalars for GQty client\nconst generatedSchema = createGeneratedSchema(g);\nconst scalarsEnumsHash = createScalarsEnumsHash(g);\n\n// Create type-safe GraphQL client\nexport const client = createClient<{\n query: InferClient<typeof queryType>;\n mutation: InferClient<typeof mutationType>;\n}>({\n generatedSchema,\n scalarsEnumsHash,\n url: \"/api/graphql\",\n{{#if (eq auth \"better-auth\")}}\n credentials: \"include\",\n{{/if}}\n});\n\n// Export typed query and mutation functions\nexport const { query, mutation, resolved } = client;\n\n// Helper for React Query integration\nexport async function graphqlFetcher<T>(\n fn: () => T | Promise<T>\n): Promise<T> {\n return resolved(fn);\n}\n`],\n [\"api/garph/fullstack/next/src/utils/garph.ts.hbs\", `import { QueryClient } from \"@tanstack/react-query\";\nimport { createClient, type InferClient } from \"@garph/gqty\";\nimport {\n createGeneratedSchema,\n createScalarsEnumsHash,\n} from \"@garph/gqty/dist/utils\";\nimport {\n g,\n queryType,\n mutationType,\n{{#if (includes examples \"todo\")}}\n todoType,\n{{/if}}\n} from \"@{{projectName}}/api/index\";\n\n// Create QueryClient for React Query integration\nexport const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n retry: 2,\n staleTime: 1000 * 60,\n },\n },\n});\n\n// Generate schema and scalars for GQty client\nconst generatedSchema = createGeneratedSchema(g);\nconst scalarsEnumsHash = createScalarsEnumsHash(g);\n\n// Create type-safe GraphQL client\nexport const client = createClient<{\n query: InferClient<typeof queryType>;\n mutation: InferClient<typeof mutationType>;\n}>({\n generatedSchema,\n scalarsEnumsHash,\n url: \"/api/graphql\",\n{{#if (eq auth \"better-auth\")}}\n credentials: \"include\",\n{{/if}}\n});\n\n// Export typed query and mutation functions\nexport const { query, mutation, resolved } = client;\n\n// Helper for React Query integration\nexport async function graphqlFetcher<T>(\n fn: () => T | Promise<T>\n): Promise<T> {\n return resolved(fn);\n}\n`],\n [\"api/garph/fullstack/astro/src/utils/garph.ts.hbs\", `import { QueryClient } from \"@tanstack/react-query\";\nimport { createClient, type InferClient } from \"@garph/gqty\";\nimport {\n createGeneratedSchema,\n createScalarsEnumsHash,\n} from \"@garph/gqty/dist/utils\";\nimport {\n g,\n queryType,\n mutationType,\n{{#if (includes examples \"todo\")}}\n todoType,\n{{/if}}\n} from \"@{{projectName}}/api/index\";\n\n// Create QueryClient for React Query integration\nexport const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n retry: 2,\n staleTime: 1000 * 60,\n },\n },\n});\n\n// Generate schema and scalars for GQty client\nconst generatedSchema = createGeneratedSchema(g);\nconst scalarsEnumsHash = createScalarsEnumsHash(g);\n\n// Create type-safe GraphQL client\nexport const client = createClient<{\n query: InferClient<typeof queryType>;\n mutation: InferClient<typeof mutationType>;\n}>({\n generatedSchema,\n scalarsEnumsHash,\n url: \"/api/graphql\",\n{{#if (eq auth \"better-auth\")}}\n credentials: \"include\",\n{{/if}}\n});\n\n// Export typed query and mutation functions\nexport const { query, mutation, resolved } = client;\n\n// Helper for React Query integration\nexport async function graphqlFetcher<T>(\n fn: () => T | Promise<T>\n): Promise<T> {\n return resolved(fn);\n}\n`],\n [\"addons/storybook/apps/web/src/stories/Button.stories.ts.hbs\", `{{#if (or (eq frontend \"tanstack-router\") (eq frontend \"react-router\") (eq frontend \"next\") (eq frontend \"solid\"))}}\nimport type { Meta, StoryObj } from \"{{#if (eq frontend \"next\")}}@storybook/nextjs{{else}}@storybook/react-vite{{/if}}\";\n\n// Example Button component for demonstration\n// Replace this with your actual component imports\nconst Button = ({\n primary = false,\n size = \"medium\",\n label,\n onClick,\n}: {\n primary?: boolean;\n size?: \"small\" | \"medium\" | \"large\";\n label: string;\n onClick?: () => void;\n}) => {\n const baseStyles = \"font-semibold rounded-lg transition-colors\";\n const sizeStyles = {\n small: \"px-3 py-1.5 text-sm\",\n medium: \"px-4 py-2 text-base\",\n large: \"px-6 py-3 text-lg\",\n };\n const variantStyles = primary\n ? \"bg-blue-600 text-white hover:bg-blue-700\"\n : \"bg-gray-200 text-gray-900 hover:bg-gray-300\";\n\n return (\n <button\n type=\"button\"\n className={\\`\\${baseStyles} \\${sizeStyles[size]} \\${variantStyles}\\`}\n onClick={onClick}\n >\n {label}\n </button>\n );\n};\n\nconst meta: Meta<typeof Button> = {\n title: \"Example/Button\",\n component: Button,\n parameters: {\n layout: \"centered\",\n },\n tags: [\"autodocs\"],\n argTypes: {\n size: {\n control: { type: \"select\" },\n options: [\"small\", \"medium\", \"large\"],\n },\n onClick: { action: \"clicked\" },\n },\n};\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Primary: Story = {\n args: {\n primary: true,\n label: \"Primary Button\",\n },\n};\n\nexport const Secondary: Story = {\n args: {\n label: \"Secondary Button\",\n },\n};\n\nexport const Large: Story = {\n args: {\n size: \"large\",\n label: \"Large Button\",\n },\n};\n\nexport const Small: Story = {\n args: {\n size: \"small\",\n label: \"Small Button\",\n },\n};\n{{else if (eq frontend \"nuxt\")}}\nimport type { Meta, StoryObj } from \"@storybook/vue3-vite\";\nimport { fn } from \"@storybook/test\";\n\n// Example Button component for demonstration\nconst Button = {\n name: \"Button\",\n props: {\n primary: { type: Boolean, default: false },\n size: { type: String, default: \"medium\" },\n label: { type: String, required: true },\n },\n emits: [\"click\"],\n template: \\`\n <button\n type=\"button\"\n :class=\"[\n 'font-semibold rounded-lg transition-colors',\n size === 'small' ? 'px-3 py-1.5 text-sm' : size === 'large' ? 'px-6 py-3 text-lg' : 'px-4 py-2 text-base',\n primary ? 'bg-blue-600 text-white hover:bg-blue-700' : 'bg-gray-200 text-gray-900 hover:bg-gray-300'\n ]\"\n @click=\"$emit('click')\"\n >\n \\\\{{ label }}\n </button>\n \\`,\n};\n\nconst meta: Meta<typeof Button> = {\n title: \"Example/Button\",\n component: Button,\n parameters: {\n layout: \"centered\",\n },\n tags: [\"autodocs\"],\n argTypes: {\n size: {\n control: { type: \"select\" },\n options: [\"small\", \"medium\", \"large\"],\n },\n },\n args: {\n onClick: fn(),\n },\n};\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Primary: Story = {\n args: {\n primary: true,\n label: \"Primary Button\",\n },\n};\n\nexport const Secondary: Story = {\n args: {\n label: \"Secondary Button\",\n },\n};\n{{else if (eq frontend \"svelte\")}}\nimport type { Meta, StoryObj } from \"@storybook/svelte-vite\";\nimport { fn } from \"@storybook/test\";\n\n// Example Button component for demonstration\n// In real usage, import your actual Svelte component\nconst Button = {\n render: (args: { primary?: boolean; size?: string; label: string }) => ({\n Component: {\n // Simplified Svelte-like component representation\n $$: { on_mount: [], on_destroy: [], after_update: [], context: new Map() },\n },\n props: args,\n }),\n};\n\nconst meta: Meta<typeof Button> = {\n title: \"Example/Button\",\n component: Button as any,\n parameters: {\n layout: \"centered\",\n },\n tags: [\"autodocs\"],\n argTypes: {\n size: {\n control: { type: \"select\" },\n options: [\"small\", \"medium\", \"large\"],\n },\n },\n args: {\n onClick: fn(),\n },\n};\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Primary: Story = {\n args: {\n primary: true,\n label: \"Primary Button\",\n },\n};\n\nexport const Secondary: Story = {\n args: {\n label: \"Secondary Button\",\n },\n};\n{{else}}\n// Generic Storybook example\nimport type { Meta, StoryObj } from \"@storybook/react-vite\";\n\nconst Button = ({ label }: { label: string }) => (\n <button type=\"button\">{label}</button>\n);\n\nconst meta: Meta<typeof Button> = {\n title: \"Example/Button\",\n component: Button,\n};\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Default: Story = {\n args: {\n label: \"Click me\",\n },\n};\n{{/if}}\n`],\n [\"cms/strapi/web/next/src/strapi/env.ts.hbs\", `// Strapi environment configuration\nexport const strapiUrl = process.env.NEXT_PUBLIC_STRAPI_URL || \"http://localhost:1337\";\nexport const strapiApiUrl = \\`\\${strapiUrl}/api\\`;\n\n// API token for server-side authenticated requests\nexport const strapiApiToken = process.env.STRAPI_API_TOKEN;\n`],\n [\"cms/strapi/web/next/src/strapi/index.ts.hbs\", `// Strapi client and utilities\nexport { strapiClient, strapiServerClient, strapiFetch, strapiFetchSingle } from \"./lib/client\";\nexport { buildCollectionQuery, stringifyQuery, populateConfigs, filterBuilders } from \"./lib/queries\";\nexport { getStrapiMediaUrl, getStrapiMediaFormat, getStrapiMediaDimensions, getStrapiSrcSet } from \"./lib/media\";\nexport { strapiUrl, strapiApiUrl, strapiApiToken } from \"./env\";\n\n// Types\nexport type {\n StrapiPagination,\n StrapiCollectionResponse,\n StrapiSingleResponse,\n StrapiBaseDocument,\n StrapiMedia,\n StrapiMediaFormat,\n StrapiSEO,\n Article,\n Author,\n Category,\n Page,\n Homepage,\n} from \"./lib/types\";\n`],\n [\"addons/msw/apps/web/src/mocks/node.ts.hbs\", `/**\n * MSW Node.js server setup\n *\n * This file sets up the MSW request interception for Node.js environments.\n * Use this in your test setup files (e.g., vitest.setup.ts or jest.setup.ts).\n *\n * @see https://mswjs.io/docs/integrations/node\n */\nimport { setupServer } from \"msw/node\";\nimport { handlers } from \"./handlers\";\n\nexport const server = setupServer(...handlers);\n`],\n [\"addons/msw/apps/web/src/mocks/handlers.ts.hbs\", `/**\n * MSW (Mock Service Worker) request handlers\n *\n * Define your mock API handlers here. These handlers intercept network requests\n * and return mocked responses, useful for testing and development.\n *\n * @see https://mswjs.io/docs/basics/mocking-responses\n */\nimport { http, HttpResponse } from \"msw\";\n\nexport const handlers = [\n // Example: Mock a GET request to /api/user\n http.get(\"/api/user\", () => {\n return HttpResponse.json({\n id: \"1\",\n name: \"John Doe\",\n email: \"john@example.com\",\n });\n }),\n\n // Example: Mock a POST request to /api/login\n http.post(\"/api/login\", async ({ request }) => {\n const body = (await request.json()) as { email: string; password: string };\n\n if (body.email === \"test@example.com\" && body.password === \"password\") {\n return HttpResponse.json({\n success: true,\n token: \"mock-jwt-token\",\n });\n }\n\n return HttpResponse.json(\n { success: false, message: \"Invalid credentials\" },\n { status: 401 }\n );\n }),\n\n // Add more handlers as needed for your API endpoints\n];\n`],\n [\"addons/msw/apps/web/src/mocks/browser.ts.hbs\", `/**\n * MSW browser worker setup\n *\n * This file sets up the MSW service worker for browser environments.\n * Import and start this in your app's entry point for development mocking.\n *\n * @see https://mswjs.io/docs/integrations/browser\n */\nimport { setupWorker } from \"msw/browser\";\nimport { handlers } from \"./handlers\";\n\nexport const worker = setupWorker(...handlers);\n`],\n [\"addons/pwa/apps/web/vite/public/logo.png\", `[Binary file]`],\n [\"addons/msw/apps/server/src/mocks/handlers.ts.hbs\", `/**\n * MSW (Mock Service Worker) request handlers for server-side testing\n *\n * Define your mock API handlers here. These handlers intercept outgoing\n * HTTP requests during tests, useful for mocking external API calls.\n *\n * @see https://mswjs.io/docs/basics/mocking-responses\n */\nimport { http, HttpResponse } from \"msw\";\n\nexport const handlers = [\n // Example: Mock an external API call\n http.get(\"https://api.example.com/data\", () => {\n return HttpResponse.json({\n items: [\n { id: \"1\", name: \"Item 1\" },\n { id: \"2\", name: \"Item 2\" },\n ],\n });\n }),\n\n // Add more handlers as needed for external API mocking\n];\n`],\n [\"addons/msw/apps/server/src/mocks/server.ts.hbs\", `/**\n * MSW Node.js server setup for server-side testing\n *\n * This file sets up the MSW request interception for Node.js environments.\n * Use this in your test setup files (e.g., vitest.setup.ts or jest.setup.ts).\n *\n * @see https://mswjs.io/docs/integrations/node\n */\nimport { setupServer } from \"msw/node\";\nimport { handlers } from \"./handlers\";\n\nexport const server = setupServer(...handlers);\n`],\n [\"cms/sanity/web/next/src/sanity/env.ts.hbs\", `export const projectId = process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!;\nexport const dataset = process.env.NEXT_PUBLIC_SANITY_DATASET!;\nexport const apiVersion =\n process.env.NEXT_PUBLIC_SANITY_API_VERSION || \"2024-07-11\";\n\n// Used for server-side fetching\nexport const token = process.env.SANITY_API_READ_TOKEN;\n`],\n [\"api/orpc/web/astro/src/utils/orpc.ts.hbs\", `import { createORPCClient } from '@orpc/client';\nimport { RPCLink } from '@orpc/client/fetch';\nimport type { appRouter } from '@{{projectName}}/api/routers/index';\n\nconst link = new RPCLink({\n{{#if (eq backend \"self\")}}\n\turl: '/api/rpc',\n{{else}}\n\turl: import.meta.env.PUBLIC_SERVER_URL\n\t\t? \\`\\${import.meta.env.PUBLIC_SERVER_URL}/rpc\\`\n\t\t: 'http://localhost:3001/rpc',\n{{/if}}\n\theaders: () => ({}),\n});\n\nexport const client = createORPCClient<typeof appRouter>(link);\n`],\n [\"api/orpc/web/svelte/src/lib/orpc.ts.hbs\", `import { PUBLIC_SERVER_URL } from \"$env/static/public\";\nimport { createORPCClient } from \"@orpc/client\";\nimport { RPCLink } from \"@orpc/client/fetch\";\nimport { createTanstackQueryUtils } from \"@orpc/tanstack-query\";\nimport { QueryCache, QueryClient } from \"@tanstack/svelte-query\";\nimport type { AppRouterClient } from \"@{{projectName}}/api/routers/index\";\n\nexport const queryClient = new QueryClient({\n\tqueryCache: new QueryCache({\n\t\tonError: (error) => {\n\t\t\tconsole.error(\\`Error: \\${error.message}\\`);\n\t\t},\n\t}),\n});\n\nexport const link = new RPCLink({\n\turl: \\`\\${PUBLIC_SERVER_URL}/rpc\\`,\n\t{{#if (eq auth \"better-auth\")}}\n\tfetch(url, options) {\n\t\treturn fetch(url, {\n\t\t\t...options,\n\t\t\tcredentials: \"include\",\n\t\t});\n\t},\n\t{{/if}}\n});\n\nexport const client: AppRouterClient = createORPCClient(link);\n\nexport const orpc = createTanstackQueryUtils(client);\n`],\n [\"payments/lemon-squeezy/web/react/tanstack-start/src/routes/success.tsx.hbs\", `import { createFileRoute } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/success\")({\n\tcomponent: SuccessPage,\n});\n\nfunction SuccessPage() {\n\tconst { checkout_id } = Route.useSearch();\n\n\treturn (\n\t\t<div className=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 className=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p className=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t{checkout_id && (\n\t\t\t\t<p className=\"text-sm text-gray-500\">Checkout ID: {checkout_id}</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n`],\n [\"payments/lemon-squeezy/web/react/tanstack-router/src/routes/success.tsx.hbs\", `import { createFileRoute } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/success\")({\n\tcomponent: SuccessPage,\n});\n\nfunction SuccessPage() {\n\tconst { checkout_id } = Route.useSearch();\n\n\treturn (\n\t\t<div className=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 className=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p className=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t{checkout_id && (\n\t\t\t\t<p className=\"text-sm text-gray-500\">Checkout ID: {checkout_id}</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n`],\n [\"api/orpc/web/nuxt/app/plugins/orpc.ts.hbs\", `import { defineNuxtPlugin } from '#app'\nimport type { AppRouterClient } from \"@{{projectName}}/api/routers/index\";\nimport { createORPCClient } from '@orpc/client'\nimport { RPCLink } from '@orpc/client/fetch'\nimport { createTanstackQueryUtils } from \"@orpc/tanstack-query\";\n\nexport default defineNuxtPlugin(() => {\n const config = useRuntimeConfig();\n const rpcUrl = \\`\\${config.public.serverUrl}/rpc\\`;\n\n const rpcLink = new RPCLink({\n url: rpcUrl,\n {{#if (eq auth \"better-auth\")}}\n fetch(url, options) {\n return fetch(url, {\n ...options,\n credentials: \"include\",\n });\n },\n {{/if}}\n })\n\n\n const client: AppRouterClient = createORPCClient(rpcLink)\n const orpcUtils = createTanstackQueryUtils(client)\n\n return {\n provide: {\n orpc: orpcUtils\n }\n }\n})\n`],\n [\"api/orpc/web/nuxt/app/plugins/vue-query.ts.hbs\", `import type {\n DehydratedState,\n VueQueryPluginOptions,\n} from '@tanstack/vue-query'\nimport {\n dehydrate,\n hydrate,\n QueryCache,\n QueryClient,\n VueQueryPlugin,\n} from '@tanstack/vue-query'\n\nexport default defineNuxtPlugin((nuxt) => {\n const vueQueryState = useState<DehydratedState | null>('vue-query')\n\n const toast = useToast()\n\n const queryClient = new QueryClient({\n queryCache: new QueryCache({\n onError: (error) => {\n console.log(error)\n toast.add({\n title: 'Error',\n description: error?.message || 'An unexpected error occurred.',\n })\n },\n }),\n })\n const options: VueQueryPluginOptions = { queryClient }\n\n nuxt.vueApp.use(VueQueryPlugin, options)\n\n if (import.meta.server) {\n nuxt.hooks.hook('app:rendered', () => {\n vueQueryState.value = dehydrate(queryClient)\n })\n }\n\n if (import.meta.client) {\n nuxt.hooks.hook('app:created', () => {\n hydrate(queryClient, vueQueryState.value)\n })\n }\n})\n`],\n [\"api/orpc/web/solid/src/utils/orpc.ts.hbs\", `import { createORPCClient } from \"@orpc/client\";\nimport { RPCLink } from \"@orpc/client/fetch\";\nimport { createTanstackQueryUtils } from \"@orpc/tanstack-query\";\nimport { QueryCache, QueryClient } from \"@tanstack/solid-query\";\nimport type { AppRouterClient } from \"@{{projectName}}/api/routers/index\";\nimport { env } from \"@{{projectName}}/env/web\";\n\nexport const queryClient = new QueryClient({\n\tqueryCache: new QueryCache({\n\t\tonError: (error) => {\n\t\t\tconsole.error(\\`Error: \\${error.message}\\`);\n\t\t},\n\t}),\n});\n\nexport const link = new RPCLink({\n\turl: \\`\\${env.VITE_SERVER_URL}/rpc\\`,\n{{#if (eq auth \"better-auth\")}}\n\tfetch(url, options) {\n\t\treturn fetch(url, {\n\t\t\t...options,\n\t\t\tcredentials: \"include\",\n\t\t});\n\t},\n{{/if}}\n});\n\nexport const client: AppRouterClient = createORPCClient(link);\n\nexport const orpc = createTanstackQueryUtils(client);\n`],\n [\"payments/lemon-squeezy/web/react/react-router/src/routes/success.tsx.hbs\", `import { useSearchParams } from \"react-router\";\n\nexport default function SuccessPage() {\n\tconst [searchParams] = useSearchParams();\n\tconst checkoutId = searchParams.get(\"checkout_id\");\n\n\treturn (\n\t\t<div className=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 className=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p className=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t{checkoutId && (\n\t\t\t\t<p className=\"text-sm text-gray-500\">Checkout ID: {checkoutId}</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n`],\n [\"payments/paddle/web/svelte/src/routes/success/+page.svelte.hbs\", `<script lang=\"ts\">\n\timport { page } from \"$app/stores\";\n\n\t$: transactionId = $page.url.searchParams.get(\"transaction_id\");\n</script>\n\n<div class=\"container mx-auto px-4 py-8\">\n\t<h1 class=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t<p class=\"text-gray-600 mb-4\">\n\t\tThank you for your purchase. Your payment has been processed successfully.\n\t</p>\n\t{#if transactionId}\n\t\t<p class=\"text-sm text-gray-500\">Transaction ID: {transactionId}</p>\n\t{/if}\n</div>\n`],\n [\"payments/lemon-squeezy/web/svelte/src/routes/success/+page.svelte.hbs\", `<script lang=\"ts\">\n\timport { page } from \"$app/stores\";\n\n\t$: checkoutId = $page.url.searchParams.get(\"checkout_id\");\n</script>\n\n<div class=\"container mx-auto px-4 py-8\">\n\t<h1 class=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t<p class=\"text-gray-600 mb-4\">\n\t\tThank you for your purchase. Your payment has been processed successfully.\n\t</p>\n\t{#if checkoutId}\n\t\t<p class=\"text-sm text-gray-500\">Checkout ID: {checkoutId}</p>\n\t{/if}\n</div>\n`],\n [\"payments/paddle/web/react/react-router/src/routes/success.tsx.hbs\", `import { useSearchParams } from \"react-router\";\n\nexport default function SuccessPage() {\n\tconst [searchParams] = useSearchParams();\n\tconst transactionId = searchParams.get(\"transaction_id\");\n\n\treturn (\n\t\t<div className=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 className=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p className=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t{transactionId && (\n\t\t\t\t<p className=\"text-sm text-gray-500\">Transaction ID: {transactionId}</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n`],\n [\"payments/stripe/web/svelte/src/routes/success/+page.svelte.hbs\", `<script lang=\"ts\">\n\timport { page } from '$app/state';\n\n\tconst session_id = $derived(page.url.searchParams.get('session_id'));\n</script>\n\n<div class=\"container mx-auto px-4 py-8\">\n\t<h1 class=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t<p class=\"text-gray-600 mb-4\">\n\t\tThank you for your purchase. Your payment has been processed successfully.\n\t</p>\n\t{#if session_id}\n\t\t<p class=\"text-sm text-gray-500\">Session ID: {session_id}</p>\n\t{/if}\n</div>\n`],\n [\"payments/paddle/web/react/tanstack-router/src/routes/success.tsx.hbs\", `import { createFileRoute } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/success\")({\n\tcomponent: SuccessPage,\n});\n\nfunction SuccessPage() {\n\tconst { transaction_id } = Route.useSearch<{ transaction_id?: string }>();\n\n\treturn (\n\t\t<div className=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 className=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p className=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t{transaction_id && (\n\t\t\t\t<p className=\"text-sm text-gray-500\">Transaction ID: {transaction_id}</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n`],\n [\"payments/paddle/web/react/tanstack-start/src/routes/success.tsx.hbs\", `import { createFileRoute } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/success\")({\n\tcomponent: SuccessPage,\n});\n\nfunction SuccessPage() {\n\tconst { transaction_id } = Route.useSearch<{ transaction_id?: string }>();\n\n\treturn (\n\t\t<div className=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 className=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p className=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t{transaction_id && (\n\t\t\t\t<p className=\"text-sm text-gray-500\">Transaction ID: {transaction_id}</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n`],\n [\"payments/stripe/web/react/react-router/src/routes/success.tsx.hbs\", `import { useSearchParams } from \"react-router\";\n\nexport default function SuccessPage() {\n\tconst [searchParams] = useSearchParams();\n\tconst session_id = searchParams.get(\"session_id\");\n\n\treturn (\n\t\t<div className=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 className=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p className=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t{session_id && (\n\t\t\t\t<p className=\"text-sm text-gray-500\">Session ID: {session_id}</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n`],\n [\"payments/stripe/web/react/tanstack-router/src/routes/success.tsx.hbs\", `import { createFileRoute, useSearch } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/success\")({\n\tcomponent: SuccessPage,\n\tvalidateSearch: (search) => ({\n\t\tsession_id: search.session_id as string,\n\t}),\n});\n\nfunction SuccessPage() {\n\tconst { session_id } = useSearch({ from: \"/success\" });\n\n\treturn (\n\t\t<div className=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 className=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p className=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t{session_id && (\n\t\t\t\t<p className=\"text-sm text-gray-500\">Session ID: {session_id}</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n`],\n [\"payments/stripe/web/react/tanstack-start/src/routes/success.tsx.hbs\", `import { createFileRoute, useSearch } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/success\")({\n\tcomponent: SuccessPage,\n\tvalidateSearch: (search) => ({\n\t\tsession_id: search.session_id as string,\n\t}),\n});\n\nfunction SuccessPage() {\n\tconst { session_id } = useSearch({ from: \"/success\" });\n\n\treturn (\n\t\t<div className=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 className=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p className=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t{session_id && (\n\t\t\t\t<p className=\"text-sm text-gray-500\">Session ID: {session_id}</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n`],\n [\"backend/server/nitro/routes/api/auth/[...path].ts.hbs\", `{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@{{projectName}}/auth\";\nimport { toNodeHandler } from \"better-auth/node\";\n\nconst authHandler = toNodeHandler(auth);\n\nexport default defineEventHandler(async (event) => {\n\tconst { req, res } = event.node;\n\tawait authHandler(req, res);\n});\n{{else}}\n// Auth placeholder - Better Auth not configured\nexport default defineEventHandler(() => {\n\treturn { error: \"Auth not configured\" };\n});\n{{/if}}\n`],\n [\"payments/polar/web/react/tanstack-router/src/routes/success.tsx.hbs\", `import { createFileRoute, useSearch } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/success\")({\n\tcomponent: SuccessPage,\n\tvalidateSearch: (search) => ({\n\t\tcheckout_id: search.checkout_id as string,\n\t}),\n});\n\nfunction SuccessPage() {\n\tconst { checkout_id } = useSearch({ from: \"/success\" });\n\n\treturn (\n\t\t<div className=\"container mx-auto px-4 py-8\">\n\t\t\t<h1>Payment Successful!</h1>\n\t\t\t{checkout_id && <p>Checkout ID: {checkout_id}</p>}\n\t\t</div>\n\t);\n}\n`],\n [\"payments/polar/web/react/react-router/src/routes/success.tsx.hbs\", `import { useSearchParams } from \"react-router\";\n\nexport default function SuccessPage() {\n const [searchParams] = useSearchParams();\n const checkout_id = searchParams.get(\"checkout_id\");\n\n return (\n <div className=\"container mx-auto px-4 py-8\">\n <h1>Payment Successful!</h1>\n {checkout_id && <p>Checkout ID: {checkout_id}</p>}\n </div>\n );\n}\n`],\n [\"payments/polar/web/react/tanstack-start/src/routes/success.tsx.hbs\", `import { createFileRoute, useSearch } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/success\")({\n\tcomponent: SuccessPage,\n\tvalidateSearch: (search) => ({\n\t\tcheckout_id: search.checkout_id as string,\n\t}),\n});\n\nfunction SuccessPage() {\n\tconst { checkout_id } = useSearch({ from: \"/success\" });\n\n\treturn (\n\t\t<div className=\"container mx-auto px-4 py-8\">\n\t\t\t<h1>Payment Successful!</h1>\n\t\t\t{checkout_id && <p>Checkout ID: {checkout_id}</p>}\n\t\t</div>\n\t);\n}\n`],\n [\"payments/polar/web/react/tanstack-start/src/functions/get-payment.ts.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { authMiddleware } from \"@/middleware/auth\";\nimport { createServerFn } from \"@tanstack/react-start\";\nimport { getRequestHeaders } from \"@tanstack/react-start/server\";\n\nexport const getPayment = createServerFn({ method: \"GET\" })\n .middleware([authMiddleware])\n .handler(async () => {\n const { data: customerState } = await authClient.customer.state({\n fetchOptions: {\n headers: getRequestHeaders()\n }\n });\n return customerState;\n });\n`],\n [\"payments/polar/web/svelte/src/routes/success/+page.svelte.hbs\", `<script lang=\"ts\">\n\timport { page } from '$app/state';\n\t\n\tconst checkout_id = $derived(page.url.searchParams.get('checkout_id'));\n</script>\n\n<div class=\"container mx-auto px-4 py-8\">\n\t<h1>Payment Successful!</h1>\n\t{#if checkout_id}\n\t\t<p>Checkout ID: {checkout_id}</p>\n\t{/if}\n</div>\n`],\n [\"auth/clerk/convex/native/base/app/(auth)/sign-up.tsx.hbs\", `import * as React from \"react\";\nimport { Text, TextInput, TouchableOpacity, View } from \"react-native\";\nimport { useSignUp } from \"@clerk/clerk-expo\";\nimport { Link, useRouter } from \"expo-router\";\n\nexport default function SignUpScreen() {\n const { isLoaded, signUp, setActive } = useSignUp();\n const router = useRouter();\n\n const [emailAddress, setEmailAddress] = React.useState(\"\");\n const [password, setPassword] = React.useState(\"\");\n const [pendingVerification, setPendingVerification] = React.useState(false);\n const [code, setCode] = React.useState(\"\");\n\n // Handle submission of sign-up form\n const onSignUpPress = async () => {\n if (!isLoaded) return;\n\n console.log(emailAddress, password);\n\n // Start sign-up process using email and password provided\n try {\n await signUp.create({\n emailAddress,\n password,\n });\n\n // Send user an email with verification code\n await signUp.prepareEmailAddressVerification({ strategy: \"email_code\" });\n\n // Set 'pendingVerification' to true to display second form\n // and capture OTP code\n setPendingVerification(true);\n } catch (err) {\n // See https://clerk.com/docs/custom-flows/error-handling\n // for more info on error handling\n console.error(JSON.stringify(err, null, 2));\n }\n };\n\n // Handle submission of verification form\n const onVerifyPress = async () => {\n if (!isLoaded) return;\n\n try {\n // Use the code the user provided to attempt verification\n const signUpAttempt = await signUp.attemptEmailAddressVerification({\n code,\n });\n\n // If verification was completed, set the session to active\n // and redirect the user\n if (signUpAttempt.status === \"complete\") {\n await setActive({ session: signUpAttempt.createdSessionId });\n router.replace(\"/\");\n } else {\n // If the status is not complete, check why. User may need to\n // complete further steps.\n console.error(JSON.stringify(signUpAttempt, null, 2));\n }\n } catch (err) {\n // See https://clerk.com/docs/custom-flows/error-handling\n // for more info on error handling\n console.error(JSON.stringify(err, null, 2));\n }\n };\n\n if (pendingVerification) {\n return (\n <>\n <Text>Verify your email</Text>\n <TextInput\n value={code}\n placeholder=\"Enter your verification code\"\n onChangeText={(code) => setCode(code)}\n />\n <TouchableOpacity onPress={onVerifyPress}>\n <Text>Verify</Text>\n </TouchableOpacity>\n </>\n );\n }\n\n return (\n <View>\n <Text>Sign up</Text>\n <TextInput\n autoCapitalize=\"none\"\n value={emailAddress}\n placeholder=\"Enter email\"\n onChangeText={(email) => setEmailAddress(email)}\n />\n <TextInput\n value={password}\n placeholder=\"Enter password\"\n secureTextEntry={true}\n onChangeText={(password) => setPassword(password)}\n />\n <TouchableOpacity onPress={onSignUpPress}>\n <Text>Continue</Text>\n </TouchableOpacity>\n <View style=\\\\{{ display: \"flex\", flexDirection: \"row\", gap: 3 }}>\n <Text>Already have an account?</Text>\n <Link href=\"/sign-in\">\n <Text>Sign in</Text>\n </Link>\n </View>\n </View>\n );\n}\n`],\n [\"auth/clerk/convex/native/base/app/(auth)/sign-in.tsx.hbs\", `import { useSignIn } from \"@clerk/clerk-expo\";\nimport { Link, useRouter } from \"expo-router\";\nimport { Text, TextInput, TouchableOpacity, View } from \"react-native\";\nimport React from \"react\";\n\nexport default function Page() {\n const { signIn, setActive, isLoaded } = useSignIn();\n const router = useRouter();\n\n const [emailAddress, setEmailAddress] = React.useState(\"\");\n const [password, setPassword] = React.useState(\"\");\n\n // Handle the submission of the sign-in form\n const onSignInPress = async () => {\n if (!isLoaded) return;\n\n // Start the sign-in process using the email and password provided\n try {\n const signInAttempt = await signIn.create({\n identifier: emailAddress,\n password,\n });\n\n // If sign-in process is complete, set the created session as active\n // and redirect the user\n if (signInAttempt.status === \"complete\") {\n await setActive({ session: signInAttempt.createdSessionId });\n router.replace(\"/\");\n } else {\n // If the status isn't complete, check why. User might need to\n // complete further steps.\n console.error(JSON.stringify(signInAttempt, null, 2));\n }\n } catch (err) {\n // See https://clerk.com/docs/custom-flows/error-handling\n // for more info on error handling\n console.error(JSON.stringify(err, null, 2));\n }\n };\n\n return (\n <View>\n <Text>Sign in</Text>\n <TextInput\n autoCapitalize=\"none\"\n value={emailAddress}\n placeholder=\"Enter email\"\n onChangeText={(emailAddress) => setEmailAddress(emailAddress)}\n />\n <TextInput\n value={password}\n placeholder=\"Enter password\"\n secureTextEntry={true}\n onChangeText={(password) => setPassword(password)}\n />\n <TouchableOpacity onPress={onSignInPress}>\n <Text>Continue</Text>\n </TouchableOpacity>\n <View style=\\\\{{ display: \"flex\", flexDirection: \"row\", gap: 3 }}>\n <Text>Don't have an account?</Text>\n <Link href=\"/sign-up\">\n <Text>Sign up</Text>\n </Link>\n </View>\n </View>\n );\n}\n`],\n [\"auth/clerk/convex/native/base/app/(auth)/_layout.tsx.hbs\", `import { Redirect, Stack } from \"expo-router\";\nimport { useAuth } from \"@clerk/clerk-expo\";\n\nexport default function AuthRoutesLayout() {\n const { isSignedIn } = useAuth();\n\n if (isSignedIn) {\n return <Redirect href={\"/\"} />;\n }\n\n return <Stack />;\n}\n`],\n [\"auth/clerk/convex/web/react/tanstack-start/src/start.ts.hbs\", `import { clerkMiddleware } from '@clerk/tanstack-react-start/server'\nimport { createStart } from '@tanstack/react-start'\n\nexport const startInstance = createStart(() => {\n\treturn {\n\t\trequestMiddleware: [clerkMiddleware()],\n\t}\n})`],\n [\"auth/clerk/convex/web/react/next/src/middleware.ts.hbs\", `import { clerkMiddleware } from \"@clerk/nextjs/server\";\n\nexport default clerkMiddleware();\n\nexport const config = {\n\tmatcher: [\n\t\t// Skip Next.js internals and all static files, unless found in search params\n\t\t\"/((?!_next|[^?]*\\\\\\\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)\",\n\t\t// Always run for API routes\n\t\t\"/(api|trpc)(.*)\",\n\t],\n};\n`],\n [\"auth/better-auth/web/react/tanstack-router/src/routes/login.tsx.hbs\", `import SignInForm from \"@/components/sign-in-form\";\nimport SignUpForm from \"@/components/sign-up-form\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { useState } from \"react\";\n\nexport const Route = createFileRoute(\"/login\")({\n component: RouteComponent,\n});\n\nfunction RouteComponent() {\n const [showSignIn, setShowSignIn] = useState(false);\n\n return showSignIn ? (\n <SignInForm onSwitchToSignUp={() => setShowSignIn(false)} />\n ) : (\n <SignUpForm onSwitchToSignIn={() => setShowSignIn(true)} />\n );\n}\n`],\n [\"auth/better-auth/web/react/tanstack-router/src/routes/dashboard.tsx.hbs\", `{{#if (eq payments \"polar\")}}\nimport { Button } from \"@/components/ui/button\";\n{{/if}}\nimport { authClient } from \"@/lib/auth-client\";\n{{#if (eq api \"orpc\")}}\nimport { orpc } from \"@/utils/orpc\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { trpc } from \"@/utils/trpc\";\n{{/if}}\n{{#if ( or (eq api \"orpc\") (eq api \"trpc\"))}}\nimport { useQuery } from \"@tanstack/react-query\";\n{{/if}}\nimport { createFileRoute, redirect } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/dashboard\")({\n\tcomponent: RouteComponent,\n\tbeforeLoad: async () => {\n\t\tconst session = await authClient.getSession();\n\t\tif (!session.data) {\n\t\t\tredirect({\n\t\t\t\tto: \"/login\",\n\t\t\t\tthrow: true\n\t\t\t});\n\t\t}\n\t\t{{#if (eq payments \"polar\")}}\n\t\tconst {data: customerState} = await authClient.customer.state()\n\t\treturn { session, customerState };\n\t\t{{else}}\n\t\treturn { session };\n\t\t{{/if}}\n\t}\n});\n\nfunction RouteComponent() {\n\tconst { session{{#if (eq payments \"polar\")}}, customerState{{/if}} } = Route.useRouteContext();\n\n\t{{#if (eq api \"orpc\")}}\n\tconst privateData = useQuery(orpc.privateData.queryOptions());\n\t{{/if}}\n\t{{#if (eq api \"trpc\")}}\n\tconst privateData = useQuery(trpc.privateData.queryOptions());\n\t{{/if}}\n\n\t{{#if (eq payments \"polar\")}}\n\tconst hasProSubscription = customerState?.activeSubscriptions?.length! > 0\n console.log(\"Active subscriptions:\", customerState?.activeSubscriptions)\n\t{{/if}}\n\n\treturn (\n\t\t<div>\n\t\t\t<h1>Dashboard</h1>\n\t\t\t<p>Welcome {session.data?.user.name}</p>\n\t\t\t{{#if ( or (eq api \"orpc\") (eq api \"trpc\"))}}\n\t\t\t<p>API: {privateData.data?.message}</p>\n\t\t\t{{/if}}\n\t\t\t{{#if (eq payments \"polar\")}}\n\t\t\t<p>Plan: {hasProSubscription ? \"Pro\" : \"Free\"}</p>\n\t\t\t{hasProSubscription ? (\n\t\t\t\t<Button onClick={async () => await authClient.customer.portal()}>\n\t\t\t\t\tManage Subscription\n\t\t\t\t</Button>\n\t\t\t) : (\n\t\t\t\t<Button onClick={async () => await authClient.checkout({ slug: \"pro\" })}>\n\t\t\t\t\tUpgrade to Pro\n\t\t\t\t</Button>\n\t\t\t)}\n\t\t\t{{/if}}\n\t\t</div>\n\t);\n}\n`],\n [\"auth/better-auth/web/react/tanstack-router/src/components/user-menu.tsx.hbs\", `import { Link, useNavigate } from \"@tanstack/react-router\";\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { authClient } from \"@/lib/auth-client\";\n\nimport { Button } from \"./ui/button\";\nimport { Skeleton } from \"./ui/skeleton\";\n\nexport default function UserMenu() {\n const navigate = useNavigate();\n const { data: session, isPending } = authClient.useSession();\n\n if (isPending) {\n return <Skeleton className=\"h-9 w-24\" />;\n }\n\n if (!session) {\n return (\n <Link to=\"/login\">\n <Button variant=\"outline\">Sign In</Button>\n </Link>\n );\n }\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button variant=\"outline\" />}>\n {session.user.name}\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"bg-card\">\n <DropdownMenuGroup>\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>{session.user.email}</DropdownMenuItem>\n <DropdownMenuItem\n variant=\"destructive\"\n onClick={() => {\n authClient.signOut({\n fetchOptions: {\n onSuccess: () => {\n navigate({\n to: \"/\",\n });\n },\n },\n });\n }}\n >\n Sign Out\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n`],\n [\"auth/better-auth/web/react/tanstack-router/src/components/sign-in-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { useNavigate } from \"@tanstack/react-router\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport Loader from \"./loader\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\n\nexport default function SignInForm({ onSwitchToSignUp }: { onSwitchToSignUp: () => void }) {\n const navigate = useNavigate({\n from: \"/\",\n });\n const { isPending } = authClient.useSession();\n\n const form = useForm({\n defaultValues: {\n email: \"\",\n password: \"\",\n },\n onSubmit: async ({ value }) => {\n await authClient.signIn.email(\n {\n email: value.email,\n password: value.password,\n },\n {\n onSuccess: () => {\n navigate({\n to: \"/dashboard\",\n });\n toast.success(\"Sign in successful\");\n },\n onError: (error) => {\n toast.error(error.error.message || error.error.statusText);\n },\n },\n );\n },\n validators: {\n onSubmit: z.object({\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n });\n\n if (isPending) {\n return <Loader />;\n }\n\n return (\n <div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 className=\"mb-6 text-center text-3xl font-bold\">Welcome Back</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n className=\"space-y-4\"\n >\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Email</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"email\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={!state.canSubmit || state.isSubmitting}\n >\n {state.isSubmitting ? \"Submitting...\" : \"Sign In\"}\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n <div className=\"mt-4 text-center\">\n <Button\n variant=\"link\"\n onClick={onSwitchToSignUp}\n className=\"text-indigo-600 hover:text-indigo-800\"\n >\n Need an account? Sign Up\n </Button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/better-auth/web/react/tanstack-router/src/components/sign-up-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { useNavigate } from \"@tanstack/react-router\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport Loader from \"./loader\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\n\nexport default function SignUpForm({ onSwitchToSignIn }: { onSwitchToSignIn: () => void }) {\n const navigate = useNavigate({\n from: \"/\",\n });\n const { isPending } = authClient.useSession();\n\n const form = useForm({\n defaultValues: {\n email: \"\",\n password: \"\",\n name: \"\",\n },\n onSubmit: async ({ value }) => {\n await authClient.signUp.email(\n {\n email: value.email,\n password: value.password,\n name: value.name,\n },\n {\n onSuccess: () => {\n navigate({\n to: \"/dashboard\",\n });\n toast.success(\"Sign up successful\");\n },\n onError: (error) => {\n toast.error(error.error.message || error.error.statusText);\n },\n },\n );\n },\n validators: {\n onSubmit: z.object({\n name: z.string().min(2, \"Name must be at least 2 characters\"),\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n });\n\n if (isPending) {\n return <Loader />;\n }\n\n return (\n <div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 className=\"mb-6 text-center text-3xl font-bold\">Create Account</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n className=\"space-y-4\"\n >\n <div>\n <form.Field name=\"name\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Name</Label>\n <Input\n id={field.name}\n name={field.name}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Email</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"email\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={!state.canSubmit || state.isSubmitting}\n >\n {state.isSubmitting ? \"Submitting...\" : \"Sign Up\"}\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n <div className=\"mt-4 text-center\">\n <Button\n variant=\"link\"\n onClick={onSwitchToSignIn}\n className=\"text-indigo-600 hover:text-indigo-800\"\n >\n Already have an account? Sign In\n </Button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/better-auth/web/react/tanstack-start/src/routes/login.tsx.hbs\", `import SignInForm from \"@/components/sign-in-form\";\nimport SignUpForm from \"@/components/sign-up-form\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { useState } from \"react\";\n\nexport const Route = createFileRoute(\"/login\")({\n component: RouteComponent,\n});\n\nfunction RouteComponent() {\n const [showSignIn, setShowSignIn] = useState(false);\n\n return showSignIn ? (\n <SignInForm onSwitchToSignUp={() => setShowSignIn(false)} />\n ) : (\n <SignUpForm onSwitchToSignIn={() => setShowSignIn(true)} />\n );\n}\n`],\n [\"auth/better-auth/web/react/tanstack-start/src/routes/dashboard.tsx.hbs\", `import { getUser } from \"@/functions/get-user\";\n{{#if (eq payments \"polar\") }}\nimport { Button } from \"@/components/ui/button\";\nimport { authClient } from \"@/lib/auth-client\";\nimport { getPayment } from \"@/functions/get-payment\";\n{{/if}}\n{{#if (eq api \"trpc\") }}\nimport { useTRPC } from \"@/utils/trpc\";\nimport { useQuery } from \"@tanstack/react-query\";\n{{/if}}\n{{#if (eq api \"orpc\") }}\nimport { orpc } from \"@/utils/orpc\";\nimport { useQuery } from \"@tanstack/react-query\";\n{{/if}}\nimport { createFileRoute, redirect } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/dashboard\")({\n component: RouteComponent,\n beforeLoad: async () => {\n const session = await getUser();\n {{#if (eq payments \"polar\") }}\n const customerState = await getPayment();\n return { session, customerState };\n {{else}}\n return { session };\n {{/if}}\n },\n loader: async ({ context }) => {\n if (!context.session) {\n throw redirect({\n to: \"/login\",\n });\n }\n },\n});\n\nfunction RouteComponent() {\n const { session{{#if (eq payments \"polar\") }}, customerState{{/if}} } = Route.useRouteContext();\n\n {{#if (eq api \"trpc\") }}\n const trpc = useTRPC();\n const privateData = useQuery(trpc.privateData.queryOptions());\n {{/if}}\n {{#if (eq api \"orpc\") }}\n const privateData = useQuery(orpc.privateData.queryOptions());\n {{/if}}\n\n {{#if (eq payments \"polar\") }}\n const hasProSubscription = (customerState?.activeSubscriptions?.length ?? 0) > 0;\n // For debugging: console.log(\"Active subscriptions:\", customerState?.activeSubscriptions);\n {{/if}}\n\n return (\n <div>\n <h1>Dashboard</h1>\n <p>Welcome {session?.user.name}</p>\n {{#if (eq api \"trpc\") }}\n <p>API: {privateData.data?.message}</p>\n {{else if (eq api \"orpc\") }}\n <p>API: {privateData.data?.message}</p>\n {{/if}}\n {{#if (eq payments \"polar\") }}\n <p>Plan: {hasProSubscription ? \"Pro\" : \"Free\"}</p>\n {hasProSubscription ? (\n <Button\n onClick={async function handlePortal() {\n await authClient.customer.portal();\n }}\n >\n Manage Subscription\n </Button>\n ) : (\n <Button\n onClick={async function handleUpgrade() {\n await authClient.checkout({ slug: \"pro\" });\n }}\n >\n Upgrade to Pro\n </Button>\n )}\n {{/if}}\n </div>\n );\n}`],\n [\"auth/better-auth/web/react/tanstack-start/src/components/user-menu.tsx.hbs\", `import { Link, useNavigate } from \"@tanstack/react-router\";\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { authClient } from \"@/lib/auth-client\";\n\nimport { Button } from \"./ui/button\";\nimport { Skeleton } from \"./ui/skeleton\";\n\nexport default function UserMenu() {\n const navigate = useNavigate();\n const { data: session, isPending } = authClient.useSession();\n\n if (isPending) {\n return <Skeleton className=\"h-9 w-24\" />;\n }\n\n if (!session) {\n return (\n <Link to=\"/login\">\n <Button variant=\"outline\">Sign In</Button>\n </Link>\n );\n }\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button variant=\"outline\" />}>\n {session.user.name}\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"bg-card\">\n <DropdownMenuGroup>\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>{session.user.email}</DropdownMenuItem>\n <DropdownMenuItem\n variant=\"destructive\"\n onClick={() => {\n authClient.signOut({\n fetchOptions: {\n onSuccess: () => {\n navigate({\n to: \"/\",\n });\n },\n },\n });\n }}\n >\n Sign Out\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n`],\n [\"auth/better-auth/web/react/tanstack-start/src/components/sign-in-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { useNavigate } from \"@tanstack/react-router\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport Loader from \"./loader\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\n\nexport default function SignInForm({ onSwitchToSignUp }: { onSwitchToSignUp: () => void }) {\n const navigate = useNavigate({\n from: \"/\",\n });\n const { isPending } = authClient.useSession();\n\n const form = useForm({\n defaultValues: {\n email: \"\",\n password: \"\",\n },\n onSubmit: async ({ value }) => {\n await authClient.signIn.email(\n {\n email: value.email,\n password: value.password,\n },\n {\n onSuccess: () => {\n navigate({\n to: \"/dashboard\",\n });\n toast.success(\"Sign in successful\");\n },\n onError: (error) => {\n toast.error(error.error.message || error.error.statusText);\n },\n },\n );\n },\n validators: {\n onSubmit: z.object({\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n });\n\n if (isPending) {\n return <Loader />;\n }\n\n return (\n <div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 className=\"mb-6 text-center text-3xl font-bold\">Welcome Back</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n className=\"space-y-4\"\n >\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Email</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"email\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={!state.canSubmit || state.isSubmitting}\n >\n {state.isSubmitting ? \"Submitting...\" : \"Sign In\"}\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n <div className=\"mt-4 text-center\">\n <Button\n variant=\"link\"\n onClick={onSwitchToSignUp}\n className=\"text-indigo-600 hover:text-indigo-800\"\n >\n Need an account? Sign Up\n </Button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/better-auth/web/react/tanstack-start/src/components/sign-up-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { useNavigate } from \"@tanstack/react-router\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport Loader from \"./loader\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\n\nexport default function SignUpForm({ onSwitchToSignIn }: { onSwitchToSignIn: () => void }) {\n const navigate = useNavigate({\n from: \"/\",\n });\n const { isPending } = authClient.useSession();\n\n const form = useForm({\n defaultValues: {\n email: \"\",\n password: \"\",\n name: \"\",\n },\n onSubmit: async ({ value }) => {\n await authClient.signUp.email(\n {\n email: value.email,\n password: value.password,\n name: value.name,\n },\n {\n onSuccess: () => {\n navigate({\n to: \"/dashboard\",\n });\n toast.success(\"Sign up successful\");\n },\n onError: (error) => {\n toast.error(error.error.message || error.error.statusText);\n },\n },\n );\n },\n validators: {\n onSubmit: z.object({\n name: z.string().min(2, \"Name must be at least 2 characters\"),\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n });\n\n if (isPending) {\n return <Loader />;\n }\n\n return (\n <div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 className=\"mb-6 text-center text-3xl font-bold\">Create Account</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n className=\"space-y-4\"\n >\n <div>\n <form.Field name=\"name\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Name</Label>\n <Input\n id={field.name}\n name={field.name}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Email</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"email\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={!state.canSubmit || state.isSubmitting}\n >\n {state.isSubmitting ? \"Submitting...\" : \"Sign Up\"}\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n <div className=\"mt-4 text-center\">\n <Button\n variant=\"link\"\n onClick={onSwitchToSignIn}\n className=\"text-indigo-600 hover:text-indigo-800\"\n >\n Already have an account? Sign In\n </Button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/better-auth/web/react/tanstack-start/src/functions/get-user.ts.hbs\", `import { authMiddleware } from \"@/middleware/auth\";\nimport { createServerFn } from \"@tanstack/react-start\";\n\nexport const getUser = createServerFn({ method: \"GET\" }).middleware([authMiddleware]).handler(async ({ context }) => {\n return context.session\n})`],\n [\"auth/better-auth/web/react/react-router/src/components/user-menu.tsx.hbs\", `import { Link, useNavigate } from \"react-router\";\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { authClient } from \"@/lib/auth-client\";\n\nimport { Button } from \"./ui/button\";\nimport { Skeleton } from \"./ui/skeleton\";\n\nexport default function UserMenu() {\n const navigate = useNavigate();\n const { data: session, isPending } = authClient.useSession();\n\n if (isPending) {\n return <Skeleton className=\"h-9 w-24\" />;\n }\n\n if (!session) {\n return (\n <Link to=\"/login\">\n <Button variant=\"outline\">Sign In</Button>\n </Link>\n );\n }\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button variant=\"outline\" />}>\n {session.user.name}\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"bg-card\">\n <DropdownMenuGroup>\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>{session.user.email}</DropdownMenuItem>\n <DropdownMenuItem\n variant=\"destructive\"\n onClick={() => {\n authClient.signOut({\n fetchOptions: {\n onSuccess: () => {\n navigate(\"/\");\n },\n },\n });\n }}\n >\n Sign Out\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n`],\n [\"auth/better-auth/web/react/react-router/src/components/sign-in-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { useNavigate } from \"react-router\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport Loader from \"./loader\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\n\nexport default function SignInForm({\n onSwitchToSignUp,\n}: {\n onSwitchToSignUp: () => void;\n}) {\n const navigate = useNavigate();\n const { isPending } = authClient.useSession();\n\n const form = useForm({\n defaultValues: {\n email: \"\",\n password: \"\",\n },\n onSubmit: async ({ value }) => {\n await authClient.signIn.email(\n {\n email: value.email,\n password: value.password,\n },\n {\n onSuccess: () => {\n navigate(\"/dashboard\");\n toast.success(\"Sign in successful\");\n },\n onError: (error) => {\n toast.error(error.error.message || error.error.statusText);\n },\n }\n );\n },\n validators: {\n onSubmit: z.object({\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n });\n\n if (isPending) {\n return <Loader />;\n }\n\n return (\n <div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 className=\"mb-6 text-center text-3xl font-bold\">Welcome Back</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n className=\"space-y-4\"\n >\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Email</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"email\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={!state.canSubmit || state.isSubmitting}\n >\n {state.isSubmitting ? \"Submitting...\" : \"Sign In\"}\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n <div className=\"mt-4 text-center\">\n <Button\n variant=\"link\"\n onClick={onSwitchToSignUp}\n className=\"text-indigo-600 hover:text-indigo-800\"\n >\n Need an account? Sign Up\n </Button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/better-auth/web/react/react-router/src/components/sign-up-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { useNavigate } from \"react-router\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport Loader from \"./loader\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\n\nexport default function SignUpForm({\n onSwitchToSignIn,\n}: {\n onSwitchToSignIn: () => void;\n}) {\n const navigate = useNavigate();\n const { isPending } = authClient.useSession();\n\n const form = useForm({\n defaultValues: {\n email: \"\",\n password: \"\",\n name: \"\",\n },\n onSubmit: async ({ value }) => {\n await authClient.signUp.email(\n {\n email: value.email,\n password: value.password,\n name: value.name,\n },\n {\n onSuccess: () => {\n navigate(\"/dashboard\");\n toast.success(\"Sign up successful\");\n },\n onError: (error) => {\n toast.error(error.error.message || error.error.statusText);\n },\n }\n );\n },\n validators: {\n onSubmit: z.object({\n name: z.string().min(2, \"Name must be at least 2 characters\"),\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n });\n\n if (isPending) {\n return <Loader />;\n }\n\n return (\n <div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 className=\"mb-6 text-center text-3xl font-bold\">Create Account</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n className=\"space-y-4\"\n >\n <div>\n <form.Field name=\"name\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Name</Label>\n <Input\n id={field.name}\n name={field.name}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Email</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"email\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={!state.canSubmit || state.isSubmitting}\n >\n {state.isSubmitting ? \"Submitting...\" : \"Sign Up\"}\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n <div className=\"mt-4 text-center\">\n <Button\n variant=\"link\"\n onClick={onSwitchToSignIn}\n className=\"text-indigo-600 hover:text-indigo-800\"\n >\n Already have an account? Sign In\n </Button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/better-auth/web/react/next/src/components/user-menu.tsx.hbs\", `import Link from \"next/link\";\nimport { useRouter } from \"next/navigation\";\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { authClient } from \"@/lib/auth-client\";\n\nimport { Button } from \"./ui/button\";\nimport { Skeleton } from \"./ui/skeleton\";\n\nexport default function UserMenu() {\n const router = useRouter();\n const { data: session, isPending } = authClient.useSession();\n\n if (isPending) {\n return <Skeleton className=\"h-9 w-24\" />;\n }\n\n if (!session) {\n return (\n <Link href=\"/login\">\n <Button variant=\"outline\">Sign In</Button>\n </Link>\n );\n }\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button variant=\"outline\" />}>\n {session.user.name}\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"bg-card\">\n <DropdownMenuGroup>\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>{session.user.email}</DropdownMenuItem>\n <DropdownMenuItem\n variant=\"destructive\"\n onClick={() => {\n authClient.signOut({\n fetchOptions: {\n onSuccess: () => {\n router.push(\"/\");\n },\n },\n });\n }}\n >\n Sign Out\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n`],\n [\"auth/better-auth/web/react/next/src/components/sign-in-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport Loader from \"./loader\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\nimport { useRouter } from \"next/navigation\";\n\nexport default function SignInForm({\n onSwitchToSignUp,\n}: {\n onSwitchToSignUp: () => void;\n}) {\n const router = useRouter()\n const { isPending } = authClient.useSession();\n\n const form = useForm({\n defaultValues: {\n email: \"\",\n password: \"\",\n },\n onSubmit: async ({ value }) => {\n await authClient.signIn.email(\n {\n email: value.email,\n password: value.password,\n },\n {\n onSuccess: () => {\n router.push(\"/dashboard\")\n toast.success(\"Sign in successful\");\n },\n onError: (error) => {\n toast.error(error.error.message || error.error.statusText);\n },\n },\n );\n },\n validators: {\n onSubmit: z.object({\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n });\n\n if (isPending) {\n return <Loader />;\n }\n\n return (\n <div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 className=\"mb-6 text-center text-3xl font-bold\">Welcome Back</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n className=\"space-y-4\"\n >\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Email</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"email\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={!state.canSubmit || state.isSubmitting}\n >\n {state.isSubmitting ? \"Submitting...\" : \"Sign In\"}\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n <div className=\"mt-4 text-center\">\n <Button\n variant=\"link\"\n onClick={onSwitchToSignUp}\n className=\"text-indigo-600 hover:text-indigo-800\"\n >\n Need an account? Sign Up\n </Button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/better-auth/web/react/next/src/components/sign-up-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport Loader from \"./loader\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\nimport { useRouter } from \"next/navigation\";\n\nexport default function SignUpForm({\n onSwitchToSignIn,\n}: {\n onSwitchToSignIn: () => void;\n}) {\n const router = useRouter();\n const { isPending } = authClient.useSession();\n\n const form = useForm({\n defaultValues: {\n email: \"\",\n password: \"\",\n name: \"\",\n },\n onSubmit: async ({ value }) => {\n await authClient.signUp.email(\n {\n email: value.email,\n password: value.password,\n name: value.name,\n },\n {\n onSuccess: () => {\n router.push(\"/dashboard\");\n toast.success(\"Sign up successful\");\n },\n onError: (error) => {\n toast.error(error.error.message || error.error.statusText);\n },\n },\n );\n },\n validators: {\n onSubmit: z.object({\n name: z.string().min(2, \"Name must be at least 2 characters\"),\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n });\n\n if (isPending) {\n return <Loader />;\n }\n\n return (\n <div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 className=\"mb-6 text-center text-3xl font-bold\">Create Account</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n className=\"space-y-4\"\n >\n <div>\n <form.Field name=\"name\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Name</Label>\n <Input\n id={field.name}\n name={field.name}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Email</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"email\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={!state.canSubmit || state.isSubmitting}\n >\n {state.isSubmitting ? \"Submitting...\" : \"Sign Up\"}\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n <div className=\"mt-4 text-center\">\n <Button\n variant=\"link\"\n onClick={onSwitchToSignIn}\n className=\"text-indigo-600 hover:text-indigo-800\"\n >\n Already have an account? Sign In\n </Button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/better-auth/web/react/tanstack-start/src/middleware/auth.ts.hbs\", `{{#if (eq backend \"self\")}}\nimport { auth } from \"@{{projectName}}/auth\";\nimport { createMiddleware } from \"@tanstack/react-start\";\n\n\nexport const authMiddleware = createMiddleware().server(async ({ next, request }) => {\n const session = await auth.api.getSession({\n headers: request.headers,\n })\n return next({\n context: { session }\n })\n})\n{{else}}\nimport { authClient } from \"@/lib/auth-client\";\nimport { createMiddleware } from \"@tanstack/react-start\";\n\nexport const authMiddleware = createMiddleware().server(\n\tasync ({ next, request }) => {\n\t\tconst session = await authClient.getSession({\n\t\t\tfetchOptions: {\n\t\t\t\theaders: request.headers,\n\t\t\t\tthrow: true\n\t\t\t}\n\t\t})\n\t\treturn next({\n\t\t\tcontext: { session },\n\t\t});\n\t},\n);\n{{/if}}\n`],\n [\"auth/better-auth/web/react/react-router/src/routes/login.tsx.hbs\", `import SignInForm from \"@/components/sign-in-form\";\nimport SignUpForm from \"@/components/sign-up-form\";\nimport { useState } from \"react\";\n\nexport default function Login() {\n const [showSignIn, setShowSignIn] = useState(false);\n\n return showSignIn ? (\n <SignInForm onSwitchToSignUp={() => setShowSignIn(false)} />\n ) : (\n <SignUpForm onSwitchToSignIn={() => setShowSignIn(true)} />\n );\n}\n`],\n [\"auth/better-auth/web/react/react-router/src/routes/dashboard.tsx.hbs\", `{{#if (eq payments \"polar\")}}\nimport { Button } from \"@/components/ui/button\";\n{{/if}}\nimport { authClient } from \"@/lib/auth-client\";\n{{#if (eq api \"orpc\")}}\nimport { orpc } from \"@/utils/orpc\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { trpc } from \"@/utils/trpc\";\n{{/if}}\n{{#if ( or (eq api \"orpc\") (eq api \"trpc\"))}}\nimport { useQuery } from \"@tanstack/react-query\";\n{{/if}}\nimport { useEffect, useState } from \"react\";\nimport { useNavigate } from \"react-router\";\n\nexport default function Dashboard() {\n const { data: session, isPending } = authClient.useSession();\n const navigate = useNavigate();\n {{#if (eq payments \"polar\")}}\n const [customerState, setCustomerState] = useState<any>(null);\n {{/if}}\n\n {{#if (eq api \"orpc\")}}\n const privateData = useQuery(orpc.privateData.queryOptions());\n {{/if}}\n {{#if (eq api \"trpc\")}}\n const privateData = useQuery(trpc.privateData.queryOptions());\n {{/if}}\n\n useEffect(() => {\n if (!session && !isPending) {\n navigate(\"/login\");\n }\n }, [session, isPending, navigate]);\n\n {{#if (eq payments \"polar\")}}\n useEffect(() => {\n async function fetchCustomerState() {\n if (session) {\n const { data } = await authClient.customer.state();\n setCustomerState(data);\n }\n }\n\n fetchCustomerState();\n }, [session]);\n {{/if}}\n\n if (isPending) {\n return <div>Loading...</div>;\n }\n\n {{#if (eq payments \"polar\")}}\n const hasProSubscription = customerState?.activeSubscriptions?.length! > 0;\n console.log(\"Active subscriptions:\", customerState?.activeSubscriptions);\n {{/if}}\n\n return (\n <div>\n <h1>Dashboard</h1>\n <p>Welcome {session?.user.name}</p>\n {{#if ( or (eq api \"orpc\") (eq api \"trpc\"))}}\n <p>API: {privateData.data?.message}</p>\n {{/if}}\n {{#if (eq payments \"polar\")}}\n <p>Plan: {hasProSubscription ? \"Pro\" : \"Free\"}</p>\n {hasProSubscription ? (\n <Button onClick={async () => await authClient.customer.portal()}>\n Manage Subscription\n </Button>\n ) : (\n <Button onClick={async () => await authClient.checkout({ slug: \"pro\" })}>\n Upgrade to Pro\n </Button>\n )}\n {{/if}}\n </div>\n );\n}\n`],\n [\"auth/better-auth/web/react/base/src/lib/auth-client.ts.hbs\", `import { createAuthClient } from \"better-auth/react\";\n{{#if (eq payments \"polar\")}}\nimport { polarClient } from \"@polar-sh/better-auth\";\n{{/if}}\n{{#unless (eq backend \"self\")}}\nimport { env } from \"@{{projectName}}/env/web\";\n{{/unless}}\n\nexport const authClient = createAuthClient({\n{{#unless (eq backend \"self\")}}\n\tbaseURL: env.{{#if (includes frontend \"next\")}}NEXT_PUBLIC_SERVER_URL{{else}}VITE_SERVER_URL{{/if}},\n{{/unless}}\n{{#if (eq payments \"polar\")}}\n\tplugins: [polarClient()]\n{{/if}}\n});\n`],\n [\"auth/better-auth/web/svelte/src/routes/dashboard/+page.svelte.hbs\", `<script lang=\"ts\">\n\timport { goto } from '$app/navigation';\n\timport { authClient } from '$lib/auth-client';\n\t{{#if (eq api \"orpc\")}}\n\timport { orpc } from '$lib/orpc';\n\timport { createQuery } from '@tanstack/svelte-query';\n\t{{/if}}\n\t{{#if (eq payments \"polar\")}}\n\tlet customerState = $state<{ activeSubscriptions?: unknown[] } | null>(null);\n\t{{/if}}\n\n\tconst sessionQuery = authClient.useSession();\n\n\t{{#if (eq api \"orpc\")}}\n\tconst privateDataQuery = createQuery(orpc.privateData.queryOptions());\n\t{{/if}}\n\n\t$effect(() => {\n\t\tif (!$sessionQuery.isPending && !$sessionQuery.data) {\n\t\t\tgoto('/login');\n\t\t}\n\t});\n\n\t{{#if (eq payments \"polar\")}}\n\t$effect(() => {\n\t\tif ($sessionQuery.data) {\n\t\t\tauthClient.customer.state().then(({ data }) => {\n\t\t\t\tcustomerState = data;\n\t\t\t});\n\t\t}\n\t});\n\t{{/if}}\n</script>\n\n{#if $sessionQuery.isPending}\n\t<div>Loading...</div>\n{:else if !$sessionQuery.data}\n\t<div>Redirecting to login...</div>\n{:else}\n\t<div>\n\t\t<h1>Dashboard</h1>\n\t\t<p>Welcome {$sessionQuery.data.user.name}</p>\n\t\t{{#if (eq api \"orpc\")}}\n\t\t<p>API: {$privateDataQuery.data?.message}</p>\n\t\t{{/if}}\n\t\t{{#if (eq payments \"polar\")}}\n\t\t<p>Plan: {customerState?.activeSubscriptions?.length > 0 ? \"Pro\" : \"Free\"}</p>\n\t\t{#if customerState?.activeSubscriptions?.length > 0}\n\t\t\t<button onclick={async () => await authClient.customer.portal()}>\n\t\t\t\tManage Subscription\n\t\t\t</button>\n\t\t{:else}\n\t\t\t<button onclick={async () => await authClient.checkout({ slug: \"pro\" })}>\n\t\t\t\tUpgrade to Pro\n\t\t\t</button>\n\t\t{/if}\n\t\t{{/if}}\n\t</div>\n{/if}\n`],\n [\"auth/better-auth/web/svelte/src/routes/login/+page.svelte.hbs\", `<script lang=\"ts\">\n\timport SignInForm from '../../components/SignInForm.svelte';\n\timport SignUpForm from '../../components/SignUpForm.svelte';\n\n\tlet showSignIn = $state(true);\n</script>\n\n{#if showSignIn}\n\t<SignInForm switchToSignUp={() => showSignIn = false} />\n{:else}\n\t<SignUpForm switchToSignIn={() => showSignIn = true} />\n{/if}\n`],\n [\"auth/nextauth/web/react/next/src/lib/auth-client.ts.hbs\", `\"use client\";\n\nimport { signIn, signOut, useSession } from \"next-auth/react\";\n\nexport { signIn, signOut, useSession };\n\nexport function useAuthClient() {\n const { data: session, status } = useSession();\n\n return {\n session,\n user: session?.user ?? null,\n isAuthenticated: status === \"authenticated\",\n isLoading: status === \"loading\",\n signIn,\n signOut,\n };\n}\n`],\n [\"auth/nextauth/web/react/next/src/components/user-menu.tsx.hbs\", `\"use client\";\n\nimport { useAuthClient } from \"@/lib/auth-client\";\nimport { Button } from \"./ui/button\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"./ui/dropdown-menu\";\n\nexport default function UserMenu() {\n const { user, signOut } = useAuthClient();\n\n if (!user) {\n return null;\n }\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" className=\"flex items-center gap-2\">\n {user.image ? (\n <img\n src={user.image}\n alt={user.name || \"User\"}\n className=\"h-6 w-6 rounded-full\"\n />\n ) : (\n <div className=\"h-6 w-6 rounded-full bg-primary text-primary-foreground flex items-center justify-center text-sm font-medium\">\n {user.name?.charAt(0) || user.email?.charAt(0) || \"U\"}\n </div>\n )}\n <span className=\"hidden sm:inline\">{user.name || user.email}</span>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-56\">\n <DropdownMenuLabel>\n <div className=\"flex flex-col space-y-1\">\n <p className=\"text-sm font-medium\">{user.name}</p>\n <p className=\"text-xs text-muted-foreground\">{user.email}</p>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem asChild>\n <a href=\"/dashboard\">Dashboard</a>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onClick={() => signOut({ callbackUrl: \"/\" })}\n className=\"text-red-600 focus:text-red-600\"\n >\n Sign Out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n`],\n [\"auth/nextauth/web/react/next/src/components/sign-in-form.tsx.hbs\", `\"use client\";\n\nimport { useForm } from \"@tanstack/react-form\";\nimport { signIn } from \"next-auth/react\";\nimport { useRouter } from \"next/navigation\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport Loader from \"./loader\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\nimport { useAuthClient } from \"@/lib/auth-client\";\n\nexport default function SignInForm({\n onSwitchToSignUp,\n}: {\n onSwitchToSignUp: () => void;\n}) {\n const router = useRouter();\n const { isLoading } = useAuthClient();\n\n const form = useForm({\n defaultValues: {\n email: \"\",\n password: \"\",\n },\n onSubmit: async ({ value }) => {\n const result = await signIn(\"credentials\", {\n email: value.email,\n password: value.password,\n redirect: false,\n });\n\n if (result?.error) {\n toast.error(\"Invalid credentials\");\n } else {\n router.push(\"/dashboard\");\n toast.success(\"Sign in successful\");\n }\n },\n validators: {\n onSubmit: z.object({\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n });\n\n if (isLoading) {\n return <Loader />;\n }\n\n return (\n <div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 className=\"mb-6 text-center text-3xl font-bold\">Welcome Back</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n className=\"space-y-4\"\n >\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Email</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"email\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={!state.canSubmit || state.isSubmitting}\n >\n {state.isSubmitting ? \"Signing in...\" : \"Sign In\"}\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n <div className=\"mt-4 space-y-2\">\n <div className=\"relative\">\n <div className=\"absolute inset-0 flex items-center\">\n <span className=\"w-full border-t\" />\n </div>\n <div className=\"relative flex justify-center text-xs uppercase\">\n <span className=\"bg-background px-2 text-muted-foreground\">\n Or continue with\n </span>\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-2\">\n <Button\n variant=\"outline\"\n onClick={() => signIn(\"github\", { callbackUrl: \"/dashboard\" })}\n >\n GitHub\n </Button>\n <Button\n variant=\"outline\"\n onClick={() => signIn(\"google\", { callbackUrl: \"/dashboard\" })}\n >\n Google\n </Button>\n </div>\n </div>\n\n <div className=\"mt-4 text-center\">\n <Button\n variant=\"link\"\n onClick={onSwitchToSignUp}\n className=\"text-indigo-600 hover:text-indigo-800\"\n >\n Need an account? Sign Up\n </Button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/nextauth/web/react/next/src/components/providers.tsx.hbs\", `\"use client\";\n\nimport { SessionProvider } from \"next-auth/react\";\nimport type { ReactNode } from \"react\";\n\nexport function AuthProvider({ children }: { children: ReactNode }) {\n return <SessionProvider>{children}</SessionProvider>;\n}\n`],\n [\"auth/nextauth/web/react/next/src/components/sign-up-form.tsx.hbs\", `\"use client\";\n\nimport { useForm } from \"@tanstack/react-form\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport Loader from \"./loader\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\nimport { useAuthClient } from \"@/lib/auth-client\";\n\nexport default function SignUpForm({\n onSwitchToSignIn,\n}: {\n onSwitchToSignIn: () => void;\n}) {\n const { isLoading } = useAuthClient();\n\n const form = useForm({\n defaultValues: {\n name: \"\",\n email: \"\",\n password: \"\",\n confirmPassword: \"\",\n },\n onSubmit: async ({ value }) => {\n // Implement your sign-up logic here\n // This could call an API route to create a user in your database\n try {\n const response = await fetch(\"/api/auth/register\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n name: value.name,\n email: value.email,\n password: value.password,\n }),\n });\n\n if (!response.ok) {\n const error = await response.json();\n toast.error(error.message || \"Registration failed\");\n return;\n }\n\n toast.success(\"Account created! Please sign in.\");\n onSwitchToSignIn();\n } catch {\n toast.error(\"Registration failed\");\n }\n },\n validators: {\n onSubmit: z\n .object({\n name: z.string().min(2, \"Name must be at least 2 characters\"),\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n confirmPassword: z.string(),\n })\n .refine((data) => data.password === data.confirmPassword, {\n message: \"Passwords don't match\",\n path: [\"confirmPassword\"],\n }),\n },\n });\n\n if (isLoading) {\n return <Loader />;\n }\n\n return (\n <div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 className=\"mb-6 text-center text-3xl font-bold\">Create Account</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n className=\"space-y-4\"\n >\n <div>\n <form.Field name=\"name\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Name</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"text\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Email</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"email\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"confirmPassword\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Confirm Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={!state.canSubmit || state.isSubmitting}\n >\n {state.isSubmitting ? \"Creating account...\" : \"Sign Up\"}\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n <div className=\"mt-4 text-center\">\n <Button\n variant=\"link\"\n onClick={onSwitchToSignIn}\n className=\"text-indigo-600 hover:text-indigo-800\"\n >\n Already have an account? Sign In\n </Button>\n </div>\n </div>\n );\n}\n`],\n [\"examples/todo/server/drizzle/postgres/src/schema/todo.ts\", `import { pgTable, text, boolean, serial } from \"drizzle-orm/pg-core\";\n\nexport const todo = pgTable(\"todo\", {\n id: serial(\"id\").primaryKey(),\n text: text(\"text\").notNull(),\n completed: boolean(\"completed\").default(false).notNull(),\n});\n`],\n [\"examples/todo/server/drizzle/sqlite/src/schema/todo.ts\", `import { integer, sqliteTable, text } from \"drizzle-orm/sqlite-core\";\n\nexport const todo = sqliteTable(\"todo\", {\n id: integer(\"id\").primaryKey({ autoIncrement: true }),\n text: text(\"text\").notNull(),\n completed: integer(\"completed\", { mode: \"boolean\" }).default(false).notNull(),\n});\n`],\n [\"examples/todo/web/react/tanstack-router/src/routes/todos.tsx.hbs\", `import { Button } from \"@/components/ui/button\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\";\nimport { Checkbox } from \"@/components/ui/checkbox\";\nimport { Input } from \"@/components/ui/input\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { Loader2, Trash2 } from \"lucide-react\";\nimport { useState } from \"react\";\n\n{{#if (eq backend \"convex\")}}\nimport { useMutation, useQuery } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport type { Id } from \"@{{projectName}}/backend/convex/_generated/dataModel\";\n{{else}}\n {{#if (eq api \"orpc\")}}\n import { orpc } from \"@/utils/orpc\";\n {{/if}}\n {{#if (eq api \"trpc\")}}\n import { trpc } from \"@/utils/trpc\";\n {{/if}}\nimport { useMutation, useQuery } from \"@tanstack/react-query\";\n{{/if}}\n\nexport const Route = createFileRoute(\"/todos\")({\n component: TodosRoute,\n});\n\nfunction TodosRoute() {\n const [newTodoText, setNewTodoText] = useState(\"\");\n\n {{#if (eq backend \"convex\")}}\n const todos = useQuery(api.todos.getAll);\n const createTodo = useMutation(api.todos.create);\n const toggleTodo = useMutation(api.todos.toggle);\n const deleteTodo = useMutation(api.todos.deleteTodo);\n\n const handleAddTodo = async (e: React.FormEvent) => {\n e.preventDefault();\n const text = newTodoText.trim();\n if (!text) return;\n await createTodo({ text });\n setNewTodoText(\"\");\n };\n\n const handleToggleTodo = (id: Id<\"todos\">, currentCompleted: boolean) => {\n toggleTodo({ id, completed: !currentCompleted });\n };\n\n const handleDeleteTodo = (id: Id<\"todos\">) => {\n deleteTodo({ id });\n };\n {{else}}\n {{#if (eq api \"orpc\")}}\n const todos = useQuery(orpc.todo.getAll.queryOptions());\n const createMutation = useMutation(\n orpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n }),\n );\n const toggleMutation = useMutation(\n orpc.todo.toggle.mutationOptions({\n onSuccess: () => { todos.refetch() },\n }),\n );\n const deleteMutation = useMutation(\n orpc.todo.delete.mutationOptions({\n onSuccess: () => { todos.refetch() },\n }),\n );\n {{/if}}\n {{#if (eq api \"trpc\")}}\n const todos = useQuery(trpc.todo.getAll.queryOptions());\n const createMutation = useMutation(\n trpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n }),\n );\n const toggleMutation = useMutation(\n trpc.todo.toggle.mutationOptions({\n onSuccess: () => { todos.refetch() },\n }),\n );\n const deleteMutation = useMutation(\n trpc.todo.delete.mutationOptions({\n onSuccess: () => { todos.refetch() },\n }),\n );\n {{/if}}\n\n const handleAddTodo = (e: React.FormEvent) => {\n e.preventDefault();\n if (newTodoText.trim()) {\n createMutation.mutate({ text: newTodoText });\n }\n };\n\n const handleToggleTodo = (id: number, completed: boolean) => {\n toggleMutation.mutate({ id, completed: !completed });\n };\n\n const handleDeleteTodo = (id: number) => {\n deleteMutation.mutate({ id });\n };\n {{/if}}\n\n return (\n <div className=\"mx-auto w-full max-w-md py-10\">\n <Card>\n <CardHeader>\n <CardTitle>Todo List</CardTitle>\n <CardDescription>Manage your tasks efficiently</CardDescription>\n </CardHeader>\n <CardContent>\n <form\n onSubmit={handleAddTodo}\n className=\"mb-6 flex items-center space-x-2\"\n >\n <Input\n value={newTodoText}\n onChange={(e) => setNewTodoText(e.target.value)}\n placeholder=\"Add a new task...\"\n {{#if (eq backend \"convex\")}}\n {{else}}\n disabled={createMutation.isPending}\n {{/if}}\n />\n <Button\n type=\"submit\"\n {{#if (eq backend \"convex\")}}\n disabled={!newTodoText.trim()}\n {{else}}\n disabled={createMutation.isPending || !newTodoText.trim()}\n {{/if}}\n >\n {{#if (eq backend \"convex\")}}\n Add\n {{else}}\n {createMutation.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n \"Add\"\n )}\n {{/if}}\n </Button>\n </form>\n\n {{#if (eq backend \"convex\")}}\n {todos === undefined ? (\n <div className=\"flex justify-center py-4\">\n <Loader2 className=\"h-6 w-6 animate-spin\" />\n </div>\n ) : todos.length === 0 ? (\n <p className=\"py-4 text-center\">No todos yet. Add one above!</p>\n ) : (\n <ul className=\"space-y-2\">\n {todos.map((todo) => (\n <li\n key={todo._id}\n className=\"flex items-center justify-between rounded-md border p-2\"\n >\n <div className=\"flex items-center space-x-2\">\n <Checkbox\n checked={todo.completed}\n onCheckedChange={() =>\n handleToggleTodo(todo._id, todo.completed)\n }\n id={\\`todo-\\${todo._id}\\`}\n />\n <label\n htmlFor={\\`todo-\\${todo._id}\\`}\n className={\\`\\${todo.completed ? \"line-through text-muted-foreground\" : \"\"}\\`}\n >\n {todo.text}\n </label>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleDeleteTodo(todo._id)}\n aria-label=\"Delete todo\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </li>\n ))}\n </ul>\n )}\n {{else}}\n {todos.isLoading ? (\n <div className=\"flex justify-center py-4\">\n <Loader2 className=\"h-6 w-6 animate-spin\" />\n </div>\n ) : todos.data?.length === 0 ? (\n <p className=\"py-4 text-center\">\n No todos yet. Add one above!\n </p>\n ) : (\n <ul className=\"space-y-2\">\n {todos.data?.map((todo) => (\n <li\n key={todo.id}\n className=\"flex items-center justify-between rounded-md border p-2\"\n >\n <div className=\"flex items-center space-x-2\">\n <Checkbox\n checked={todo.completed}\n onCheckedChange={() =>\n handleToggleTodo(todo.id, todo.completed)\n }\n id={\\`todo-\\${todo.id}\\`}\n />\n <label\n htmlFor={\\`todo-\\${todo.id}\\`}\n className={\\`\\${todo.completed ? \"line-through\" : \"\"}\\`}\n >\n {todo.text}\n </label>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleDeleteTodo(todo.id)}\n aria-label=\"Delete todo\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </li>\n ))}\n </ul>\n )}\n {{/if}}\n </CardContent>\n </Card>\n </div>\n );\n}\n`],\n [\"examples/todo/server/prisma/mongodb/prisma/schema/todo.prisma.hbs\", `model Todo {\n id String @id @default(auto()) @map(\"_id\") @db.ObjectId\n text String\n completed Boolean @default(false)\n\n @@map(\"todo\")\n}\n`],\n [\"examples/todo/web/svelte/src/routes/todos/+page.svelte.hbs\", `{{#if (eq backend \"convex\")}}\n<script lang=\"ts\">\n\timport { useQuery, useConvexClient } from 'convex-svelte';\n\timport { api } from '@{{projectName}}/backend/convex/_generated/api';\n\timport type { Id } from '@{{projectName}}/backend/convex/_generated/dataModel';\n\n\tlet newTodoText = $state('');\n\tlet isAdding = $state(false);\n\tlet addError = $state<Error | null>(null);\n\tlet togglingId = $state<Id<'todos'> | null>(null);\n\tlet toggleError = $state<Error | null>(null);\n\tlet deletingId = $state<Id<'todos'> | null>(null);\n\tlet deleteError = $state<Error | null>(null);\n\n\tconst client = useConvexClient();\n\n\tconst todosQuery = useQuery(api.todos.getAll, {});\n\n\tasync function handleAddTodo(event: SubmitEvent) {\n\t\tevent.preventDefault();\n\t\tconst text = newTodoText.trim();\n\t\tif (!text || isAdding) return;\n\n\t\tisAdding = true;\n\t\taddError = null;\n\t\ttry {\n\t\t\tawait client.mutation(api.todos.create, { text });\n\t\t\tnewTodoText = '';\n\t\t} catch (err) {\n\t\t\tconsole.error('Failed to add todo:', err);\n\t\t\taddError = err instanceof Error ? err : new Error(String(err));\n\t\t} finally {\n\t\t\tisAdding = false;\n\t\t}\n\t}\n\n\tasync function handleToggleTodo(id: Id<'todos'>, completed: boolean) {\n\t\tif (togglingId === id || deletingId === id) return;\n\n\t\ttogglingId = id;\n\t\ttoggleError = null;\n\t\ttry {\n\t\t\tawait client.mutation(api.todos.toggle, { id, completed: !completed });\n\t\t} catch (err) {\n\t\t\tconsole.error('Failed to toggle todo:', err);\n\t\t\ttoggleError = err instanceof Error ? err : new Error(String(err));\n\t\t} finally {\n\t\t\tif (togglingId === id) {\n\t\t\t\ttogglingId = null;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync function handleDeleteTodo(id: Id<'todos'>) {\n\t\tif (togglingId === id || deletingId === id) return;\n\n\t\tdeletingId = id;\n\t\tdeleteError = null;\n\t\ttry {\n\t\t\tawait client.mutation(api.todos.deleteTodo, { id });\n\t\t} catch (err) {\n\t\t\tconsole.error('Failed to delete todo:', err);\n\t\t\tdeleteError = err instanceof Error ? err : new Error(String(err));\n\t\t} finally {\n\t\t\tif (deletingId === id) {\n\t\t\t\tdeletingId = null;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst canAdd = $derived(!isAdding && newTodoText.trim().length > 0);\n\tconst isLoadingTodos = $derived(todosQuery.isLoading);\n\tconst todos = $derived(todosQuery.data ?? []);\n\tconst hasTodos = $derived(todos.length > 0);\n\n</script>\n\n<div class=\"p-4\">\n\t<h1 class=\"text-xl mb-4\">Todos (Convex)</h1>\n\n\t<form onsubmit={handleAddTodo} class=\"flex gap-2 mb-4\">\n\t\t<input\n\t\t\ttype=\"text\"\n\t\t\tbind:value={newTodoText}\n\t\t\tplaceholder=\"New task...\"\n\t\t\tdisabled={isAdding}\n\t\t\tclass=\"p-1 flex-grow\"\n\t\t/>\n\t\t<button\n\t\t\ttype=\"submit\"\n\t\t\tdisabled={!canAdd}\n\t\t\tclass=\"bg-blue-500 text-white px-3 py-1 rounded disabled:opacity-50\"\n\t\t>\n\t\t\t{#if isAdding}Adding...{:else}Add{/if}\n\t\t</button>\n\t</form>\n\n\t{#if isLoadingTodos}\n\t\t<p>Loading...</p>\n\t{:else if !hasTodos}\n\t\t<p>No todos yet.</p>\n\t{:else}\n\t\t<ul class=\"space-y-1\">\n\t\t\t{#each todos as todo (todo._id)}\n\t\t\t\t{@const isTogglingThis = togglingId === todo._id}\n\t\t\t\t{@const isDeletingThis = deletingId === todo._id}\n\t\t\t\t{@const isDisabled = isTogglingThis || isDeletingThis}\n\t\t\t\t<li\n\t\t\t\t\tclass=\"flex items-center justify-between p-2\"\n\t\t\t\t\tclass:opacity-50={isDisabled}\n\t\t\t\t>\n\t\t\t\t\t<div class=\"flex items-center gap-2\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\tid={\\`todo-\\${todo._id}\\`}\n\t\t\t\t\t\t\tchecked={todo.completed}\n\t\t\t\t\t\t\tonchange={() => handleToggleTodo(todo._id, todo.completed)}\n\t\t\t\t\t\t\tdisabled={isDisabled}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<label\n\t\t\t\t\t\t\tfor={\\`todo-\\${todo._id}\\`}\n\t\t\t\t\t\t\tclass:line-through={todo.completed}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{todo.text}\n\t\t\t\t\t\t</label>\n\t\t\t\t\t</div>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonclick={() => handleDeleteTodo(todo._id)}\n\t\t\t\t\t\tdisabled={isDisabled}\n\t\t\t\t\t\taria-label=\"Delete todo\"\n\t\t\t\t\t\tclass=\"text-red-500 px-1 disabled:opacity-50\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{#if isDeletingThis}Deleting...{:else}X{/if}\n\t\t\t\t\t</button>\n\t\t\t\t</li>\n\t\t\t{/each}\n\t\t</ul>\n\t{/if}\n\n\t{#if todosQuery.error}\n\t\t<p class=\"mt-4 text-red-500\">\n\t\t\tError loading: {todosQuery.error?.message ?? 'Unknown error'}\n\t\t</p>\n\t{/if}\n\t{#if addError}\n\t\t<p class=\"mt-4 text-red-500\">\n\t\t\tError adding: {addError.message ?? 'Unknown error'}\n\t\t</p>\n\t{/if}\n\t{#if toggleError}\n\t\t<p class=\"mt-4 text-red-500\">\n\t\t\tError updating: {toggleError.message ?? 'Unknown error'}\n\t\t</p>\n\t{/if}\n\t{#if deleteError}\n\t\t<p class=\"mt-4 text-red-500\">\n\t\t\tError deleting: {deleteError.message ?? 'Unknown error'}\n\t\t</p>\n\t{/if}\n</div>\n{{else}}\n<script lang=\"ts\">\n\t{{#if (eq api \"orpc\")}}\n\timport { orpc } from '$lib/orpc';\n\t{{/if}}\n\timport { createQuery, createMutation } from '@tanstack/svelte-query';\n\n\tlet newTodoText = $state('');\n\n\t{{#if (eq api \"orpc\")}}\n\tconst todosQuery = createQuery(orpc.todo.getAll.queryOptions());\n\n\tconst addMutation = createMutation(\n\t\torpc.todo.create.mutationOptions({\n\t\t\tonSuccess: () => {\n\t\t\t\t$todosQuery.refetch();\n\t\t\t\tnewTodoText = '';\n\t\t\t},\n\t\t\tonError: (error) => {\n\t\t\t\tconsole.error('Failed to create todo:', error?.message ?? error);\n\t\t\t},\n\t\t})\n\t);\n\n\tconst toggleMutation = createMutation(\n\t\torpc.todo.toggle.mutationOptions({\n\t\t\tonSuccess: () => {\n\t\t\t\t$todosQuery.refetch();\n\t\t\t},\n\t\t\tonError: (error) => {\n\t\t\t\tconsole.error('Failed to toggle todo:', error?.message ?? error);\n\t\t\t},\n\t\t})\n\t);\n\n\tconst deleteMutation = createMutation(\n\t\torpc.todo.delete.mutationOptions({\n\t\t\tonSuccess: () => {\n\t\t\t\t$todosQuery.refetch();\n\t\t\t},\n\t\t\tonError: (error) => {\n\t\t\t\tconsole.error('Failed to delete todo:', error?.message ?? error);\n\t\t\t},\n\t\t})\n\t);\n\t{{/if}}\n\n\tfunction handleAddTodo(event: SubmitEvent) {\n\t\tevent.preventDefault();\n\t\tconst text = newTodoText.trim();\n\t\tif (text) {\n\t\t\t$addMutation.mutate({ text });\n\t\t}\n\t}\n\n\tfunction handleToggleTodo(id: number, completed: boolean) {\n\t\t$toggleMutation.mutate({ id, completed: !completed });\n\t}\n\n\tfunction handleDeleteTodo(id: number) {\n\t\t$deleteMutation.mutate({ id });\n\t}\n\n\tconst isAdding = $derived($addMutation.isPending);\n\tconst canAdd = $derived(!isAdding && newTodoText.trim().length > 0);\n\tconst isLoadingTodos = $derived($todosQuery.isLoading);\n\tconst todos = $derived($todosQuery.data ?? []);\n\tconst hasTodos = $derived(todos.length > 0);\n\n</script>\n\n<div class=\"p-4\">\n\t<h1 class=\"text-xl mb-4\">Todos{{#if (eq api \"orpc\")}} (oRPC){{/if}}</h1>\n\n\t<form onsubmit={handleAddTodo} class=\"flex gap-2 mb-4\">\n\t\t<input\n\t\t\ttype=\"text\"\n\t\t\tbind:value={newTodoText}\n\t\t\tplaceholder=\"New task...\"\n\t\t\tdisabled={isAdding}\n\t\t\tclass=\" p-1 flex-grow\"\n\t\t/>\n\t\t<button\n\t\t\ttype=\"submit\"\n\t\t\tdisabled={!canAdd}\n\t\t\tclass=\"bg-blue-500 text-white px-3 py-1 rounded disabled:opacity-50\"\n\t\t>\n\t\t\t{#if isAdding}Adding...{:else}Add{/if}\n\t\t</button>\n\t</form>\n\n\t{#if isLoadingTodos}\n\t\t<p>Loading...</p>\n\t{:else if !hasTodos}\n\t\t<p>No todos yet.</p>\n\t{:else}\n\t\t<ul class=\"space-y-1\">\n\t\t\t{#each todos as todo (todo.id)}\n\t\t\t\t{@const isToggling = $toggleMutation.isPending && $toggleMutation.variables?.id === todo.id}\n\t\t\t\t{@const isDeleting = $deleteMutation.isPending && $deleteMutation.variables?.id === todo.id}\n\t\t\t\t{@const isDisabled = isToggling || isDeleting}\n\t\t\t\t<li\n\t\t\t\t\tclass=\"flex items-center justify-between p-2 \"\n\t\t\t\t\tclass:opacity-50={isDisabled}\n\t\t\t\t>\n\t\t\t\t\t<div class=\"flex items-center gap-2\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\tid={\\`todo-\\${todo.id}\\`}\n\t\t\t\t\t\t\tchecked={todo.completed}\n\t\t\t\t\t\t\tonchange={() => handleToggleTodo(todo.id, todo.completed)}\n\t\t\t\t\t\t\tdisabled={isDisabled}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<label\n\t\t\t\t\t\t\tfor={\\`todo-\\${todo.id}\\`}\n\t\t\t\t\t\t\tclass:line-through={todo.completed}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{todo.text}\n\t\t\t\t\t\t</label>\n\t\t\t\t\t</div>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonclick={() => handleDeleteTodo(todo.id)}\n\t\t\t\t\t\tdisabled={isDisabled}\n\t\t\t\t\t\taria-label=\"Delete todo\"\n\t\t\t\t\t\tclass=\"text-red-500 px-1 disabled:opacity-50\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{#if isDeleting}Deleting...{:else}X{/if}\n\t\t\t\t\t</button>\n\t\t\t\t</li>\n\t\t\t{/each}\n\t\t</ul>\n\t{/if}\n\n\t{#if $todosQuery.isError}\n\t\t<p class=\"mt-4 text-red-500\">\n\t\t\tError loading: {$todosQuery.error?.message ?? 'Unknown error'}\n\t\t</p>\n\t{/if}\n\t{#if $addMutation.isError}\n\t\t<p class=\"mt-4 text-red-500\">\n\t\t\tError adding: {$addMutation.error?.message ?? 'Unknown error'}\n\t\t</p>\n\t{/if}\n\t{#if $toggleMutation.isError}\n\t\t<p class=\"mt-4 text-red-500\">\n\t\t\tError updating: {$toggleMutation.error?.message ?? 'Unknown error'}\n\t\t</p>\n\t{/if}\n\t{#if $deleteMutation.isError}\n\t\t<p class=\"mt-4 text-red-500\">\n\t\t\tError deleting: {$deleteMutation.error?.message ?? 'Unknown error'}\n\t\t</p>\n\t{/if}\n</div>\n{{/if}}\n`],\n [\"examples/todo/server/drizzle/base/src/routers/todo.ts.hbs\", `{{#if (eq api \"orpc\")}}\nimport { eq } from \"drizzle-orm\";\nimport z from \"zod\";\nimport { db } from \"@{{projectName}}/db\";\nimport { todo } from \"@{{projectName}}/db/schema/todo\";\nimport { publicProcedure } from \"../index\";\n\nexport const todoRouter = {\n getAll: publicProcedure.handler(async () => {\n return await db.select().from(todo);\n }),\n\n create: publicProcedure\n .input(z.object({ text: z.string().min(1) }))\n .handler(async ({ input }) => {\n return await db\n .insert(todo)\n .values({\n text: input.text,\n });\n }),\n\n toggle: publicProcedure\n .input(z.object({ id: z.number(), completed: z.boolean() }))\n .handler(async ({ input }) => {\n return await db\n .update(todo)\n .set({ completed: input.completed })\n .where(eq(todo.id, input.id));\n }),\n\n delete: publicProcedure\n .input(z.object({ id: z.number() }))\n .handler(async ({ input }) => {\n return await db.delete(todo).where(eq(todo.id, input.id));\n }),\n};\n{{/if}}\n\n{{#if (eq api \"trpc\")}}\nimport z from \"zod\";\nimport { router, publicProcedure } from \"../index\";\nimport { todo } from \"@{{projectName}}/db/schema/todo\";\nimport { eq } from \"drizzle-orm\";\nimport { db } from \"@{{projectName}}/db\";\n\nexport const todoRouter = router({\n getAll: publicProcedure.query(async () => {\n return await db.select().from(todo);\n }),\n\n create: publicProcedure\n .input(z.object({ text: z.string().min(1) }))\n .mutation(async ({ input }) => {\n return await db.insert(todo).values({\n text: input.text,\n });\n }),\n\n toggle: publicProcedure\n .input(z.object({ id: z.number(), completed: z.boolean() }))\n .mutation(async ({ input }) => {\n return await db\n .update(todo)\n .set({ completed: input.completed })\n .where(eq(todo.id, input.id));\n }),\n\n delete: publicProcedure\n .input(z.object({ id: z.number() }))\n .mutation(async ({ input }) => {\n return await db.delete(todo).where(eq(todo.id, input.id));\n }),\n});\n{{/if}}\n`],\n [\"examples/todo/server/prisma/base/src/routers/todo.ts.hbs\", `{{#if (eq api \"orpc\")}}\nimport z from \"zod\";\nimport prisma from \"@{{projectName}}/db\";\nimport { publicProcedure } from \"../index\";\n\nexport const todoRouter = {\n getAll: publicProcedure.handler(async () => {\n return await prisma.todo.findMany({\n orderBy: {\n id: \"asc\",\n },\n });\n }),\n\n create: publicProcedure\n .input(z.object({ text: z.string().min(1) }))\n .handler(async ({ input }) => {\n return await prisma.todo.create({\n data: {\n text: input.text,\n },\n });\n }),\n\n toggle: publicProcedure\n {{#if (eq database \"mongodb\")}}\n .input(z.object({ id: z.string(), completed: z.boolean() }))\n {{else}}\n .input(z.object({ id: z.number(), completed: z.boolean() }))\n {{/if}}\n .handler(async ({ input }) => {\n return await prisma.todo.update({\n where: { id: input.id },\n data: { completed: input.completed },\n });\n }),\n\n delete: publicProcedure\n {{#if (eq database \"mongodb\")}}\n .input(z.object({ id: z.string() }))\n {{else}}\n .input(z.object({ id: z.number() }))\n {{/if}}\n .handler(async ({ input }) => {\n return await prisma.todo.delete({\n where: { id: input.id },\n });\n }),\n};\n{{/if}}\n\n{{#if (eq api \"trpc\")}}\nimport { TRPCError } from \"@trpc/server\";\nimport z from \"zod\";\nimport prisma from \"@{{projectName}}/db\";\nimport { publicProcedure, router } from \"../index\";\n\nexport const todoRouter = router({\n getAll: publicProcedure.query(async () => {\n return await prisma.todo.findMany({\n orderBy: {\n id: \"asc\"\n }\n });\n }),\n\n create: publicProcedure\n .input(z.object({ text: z.string().min(1) }))\n .mutation(async ({ input }) => {\n return await prisma.todo.create({\n data: {\n text: input.text,\n },\n });\n }),\n\n toggle: publicProcedure\n {{#if (eq database \"mongodb\")}}\n .input(z.object({ id: z.string(), completed: z.boolean() }))\n {{else}}\n .input(z.object({ id: z.number(), completed: z.boolean() }))\n {{/if}}\n .mutation(async ({ input }) => {\n try {\n return await prisma.todo.update({\n where: { id: input.id },\n data: { completed: input.completed },\n });\n } catch (error) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Todo not found\",\n });\n }\n }),\n\n delete: publicProcedure\n {{#if (eq database \"mongodb\")}}\n .input(z.object({ id: z.string() }))\n {{else}}\n .input(z.object({ id: z.number() }))\n {{/if}}\n .mutation(async ({ input }) => {\n try {\n return await prisma.todo.delete({\n where: { id: input.id },\n });\n } catch (error) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Todo not found\",\n });\n }\n }),\n});\n{{/if}}\n`],\n [\"examples/todo/server/prisma/mysql/prisma/schema/todo.prisma.hbs\", `model Todo {\n id Int @id @default(autoincrement())\n text String\n completed Boolean @default(false)\n\n @@map(\"todo\")\n}\n`],\n [\"examples/todo/web/react/tanstack-start/src/routes/todos.tsx.hbs\", `import { Button } from \"@/components/ui/button\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\";\nimport { Checkbox } from \"@/components/ui/checkbox\";\nimport { Input } from \"@/components/ui/input\";\nimport { createFileRoute } from \"@tanstack/react-router\";\n{{#if (eq backend \"convex\")}}\nimport { Trash2 } from \"lucide-react\";\n{{else}}\nimport { Loader2, Trash2 } from \"lucide-react\";\n{{/if}}\nimport { useState } from \"react\";\n\n{{#if (eq backend \"convex\")}}\nimport { useSuspenseQuery } from \"@tanstack/react-query\";\nimport { convexQuery } from \"@convex-dev/react-query\";\nimport { useMutation } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport type { Id } from \"@{{projectName}}/backend/convex/_generated/dataModel\";\n{{else}}\n{{#if (eq api \"trpc\")}}\nimport { useTRPC } from \"@/utils/trpc\";\n{{/if}}\n{{#if (eq api \"orpc\")}}\nimport { orpc } from \"@/utils/orpc\";\n{{/if}}\nimport { useMutation, useQuery } from \"@tanstack/react-query\";\n{{/if}}\n\nexport const Route = createFileRoute(\"/todos\")({\n component: TodosRoute,\n});\n\nfunction TodosRoute() {\n const [newTodoText, setNewTodoText] = useState(\"\");\n\n {{#if (eq backend \"convex\")}}\n const todosQuery = useSuspenseQuery(convexQuery(api.todos.getAll, {}));\n const todos = todosQuery.data;\n\n const createTodo = useMutation(api.todos.create);\n const toggleTodo = useMutation(api.todos.toggle);\n const removeTodo = useMutation(api.todos.deleteTodo);\n\n const handleAddTodo = async (e: React.FormEvent) => {\n e.preventDefault();\n const text = newTodoText.trim();\n if (text) {\n setNewTodoText(\"\");\n try {\n await createTodo({ text });\n } catch (error) {\n console.error(\"Failed to add todo:\", error);\n setNewTodoText(text);\n }\n }\n };\n\n const handleToggleTodo = async (id: Id<\"todos\">, completed: boolean) => {\n try {\n await toggleTodo({ id, completed: !completed });\n } catch (error) {\n console.error(\"Failed to toggle todo:\", error);\n }\n };\n\n const handleDeleteTodo = async (id: Id<\"todos\">) => {\n try {\n await removeTodo({ id });\n } catch (error) {\n console.error(\"Failed to delete todo:\", error);\n }\n };\n {{else}}\n {{#if (eq api \"trpc\")}}\n const trpc = useTRPC();\n {{/if}}\n {{#if (eq api \"orpc\")}}\n {{/if}}\n\n {{#if (eq api \"trpc\")}}\n const todos = useQuery(trpc.todo.getAll.queryOptions());\n const createMutation = useMutation(\n trpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n }),\n );\n const toggleMutation = useMutation(\n trpc.todo.toggle.mutationOptions({\n onSuccess: () => { todos.refetch() },\n }),\n );\n const deleteMutation = useMutation(\n trpc.todo.delete.mutationOptions({\n onSuccess: () => { todos.refetch() },\n }),\n );\n {{/if}}\n {{#if (eq api \"orpc\")}}\n const todos = useQuery(orpc.todo.getAll.queryOptions());\n const createMutation = useMutation(\n orpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n }),\n );\n const toggleMutation = useMutation(\n orpc.todo.toggle.mutationOptions({\n onSuccess: () => { todos.refetch() },\n }),\n );\n const deleteMutation = useMutation(\n orpc.todo.delete.mutationOptions({\n onSuccess: () => { todos.refetch() },\n }),\n );\n {{/if}}\n\n const handleAddTodo = (e: React.FormEvent) => {\n e.preventDefault();\n if (newTodoText.trim()) {\n createMutation.mutate({ text: newTodoText });\n }\n };\n\n const handleToggleTodo = (id: number, completed: boolean) => {\n toggleMutation.mutate({ id, completed: !completed });\n };\n\n const handleDeleteTodo = (id: number) => {\n deleteMutation.mutate({ id });\n };\n {{/if}}\n\n return (\n <div className=\"mx-auto w-full max-w-md py-10\">\n <Card>\n <CardHeader>\n <CardTitle>Todo List{{#if (eq backend \"convex\")}} (Convex){{/if}}</CardTitle>\n <CardDescription>Manage your tasks efficiently</CardDescription>\n </CardHeader>\n <CardContent>\n <form\n onSubmit={handleAddTodo}\n className=\"mb-6 flex items-center space-x-2\"\n >\n <Input\n value={newTodoText}\n onChange={(e) => setNewTodoText(e.target.value)}\n placeholder=\"Add a new task...\"\n {{#unless (eq backend \"convex\")}}\n disabled={createMutation.isPending}\n {{/unless}}\n />\n <Button\n type=\"submit\"\n {{#unless (eq backend \"convex\")}}\n disabled={createMutation.isPending || !newTodoText.trim()}\n {{else}}\n disabled={!newTodoText.trim()}\n {{/unless}}\n >\n {{#unless (eq backend \"convex\")}}\n {createMutation.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n \"Add\"\n )}\n {{else}}\n Add\n {{/unless}}\n </Button>\n </form>\n\n {{#if (eq backend \"convex\")}}\n {todos?.length === 0 ? (\n <p className=\"py-4 text-center\">No todos yet. Add one above!</p>\n ) : (\n <ul className=\"space-y-2\">\n {todos?.map((todo) => (\n <li\n key={todo._id}\n className=\"flex items-center justify-between rounded-md border p-2\"\n >\n <div className=\"flex items-center space-x-2\">\n <Checkbox\n checked={todo.completed}\n onCheckedChange={() =>\n handleToggleTodo(todo._id, todo.completed)\n }\n id={\\`todo-\\${todo._id}\\`}\n />\n <label\n htmlFor={\\`todo-\\${todo._id}\\`}\n className={\\`\\${\n todo.completed\n ? \"text-muted-foreground line-through\"\n : \"\"\n }\\`}\n >\n {todo.text}\n </label>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleDeleteTodo(todo._id)}\n aria-label=\"Delete todo\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </li>\n ))}\n </ul>\n )}\n {{else}}\n {todos.isLoading ? (\n <div className=\"flex justify-center py-4\">\n <Loader2 className=\"h-6 w-6 animate-spin\" />\n </div>\n ) : todos.data?.length === 0 ? (\n <p className=\"py-4 text-center\">No todos yet. Add one above!</p>\n ) : (\n <ul className=\"space-y-2\">\n {todos.data?.map((todo) => (\n <li\n key={todo.id}\n className=\"flex items-center justify-between rounded-md border p-2\"\n >\n <div className=\"flex items-center space-x-2\">\n <Checkbox\n checked={todo.completed}\n onCheckedChange={() =>\n handleToggleTodo(todo.id, todo.completed)\n }\n id={\\`todo-\\${todo.id}\\`}\n />\n <label\n htmlFor={\\`todo-\\${todo.id}\\`}\n className={\\`\\${todo.completed ? \"line-through\" : \"\"}\\`}\n >\n {todo.text}\n </label>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleDeleteTodo(todo.id)}\n aria-label=\"Delete todo\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </li>\n ))}\n </ul>\n )}\n {{/if}}\n </CardContent>\n </Card>\n </div>\n );\n}\n`],\n [\"examples/todo/server/drizzle/mysql/src/schema/todo.ts\", `import { mysqlTable, varchar, int, boolean } from \"drizzle-orm/mysql-core\";\n\nexport const todo = mysqlTable(\"todo\", {\n id: int(\"id\").primaryKey().autoincrement(),\n text: varchar(\"text\", { length: 255 }).notNull(),\n completed: boolean(\"completed\").default(false).notNull(),\n});\n`],\n [\"examples/todo/server/prisma/postgres/prisma/schema/todo.prisma.hbs\", `model Todo {\n id Int @id @default(autoincrement())\n text String\n completed Boolean @default(false)\n\n @@map(\"todo\")\n}\n`],\n [\"examples/todo/web/react/react-router/src/routes/todos.tsx.hbs\", `import { Button } from \"@/components/ui/button\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\";\nimport { Checkbox } from \"@/components/ui/checkbox\";\nimport { Input } from \"@/components/ui/input\";\nimport { Loader2, Trash2 } from \"lucide-react\";\nimport { useState } from \"react\";\n\n{{#if (eq backend \"convex\")}}\nimport { useMutation, useQuery } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport type { Id } from \"@{{projectName}}/backend/convex/_generated/dataModel\";\n{{else}}\n {{#if (eq api \"orpc\")}}\n import { orpc } from \"@/utils/orpc\";\n {{/if}}\n {{#if (eq api \"trpc\")}}\n import { trpc } from \"@/utils/trpc\";\n {{/if}}\nimport { useMutation, useQuery } from \"@tanstack/react-query\";\n{{/if}}\n\nexport default function Todos() {\n const [newTodoText, setNewTodoText] = useState(\"\");\n\n {{#if (eq backend \"convex\")}}\n const todos = useQuery(api.todos.getAll);\n const createTodo = useMutation(api.todos.create);\n const toggleTodo = useMutation(api.todos.toggle);\n const deleteTodo = useMutation(api.todos.deleteTodo);\n\n const handleAddTodo = async (e: React.FormEvent) => {\n e.preventDefault();\n const text = newTodoText.trim();\n if (!text) return;\n await createTodo({ text });\n setNewTodoText(\"\");\n };\n\n const handleToggleTodo = (id: Id<\"todos\">, currentCompleted: boolean) => {\n toggleTodo({ id, completed: !currentCompleted });\n };\n\n const handleDeleteTodo = (id: Id<\"todos\">) => {\n deleteTodo({ id });\n };\n {{else}}\n {{#if (eq api \"orpc\")}}\n const todos = useQuery(orpc.todo.getAll.queryOptions());\n const createMutation = useMutation(\n orpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n })\n );\n const toggleMutation = useMutation(\n orpc.todo.toggle.mutationOptions({\n onSuccess: () => { todos.refetch() },\n })\n );\n const deleteMutation = useMutation(\n orpc.todo.delete.mutationOptions({\n onSuccess: () => { todos.refetch() },\n })\n );\n {{/if}}\n {{#if (eq api \"trpc\")}}\n const todos = useQuery(trpc.todo.getAll.queryOptions());\n const createMutation = useMutation(\n trpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n })\n );\n const toggleMutation = useMutation(\n trpc.todo.toggle.mutationOptions({\n onSuccess: () => { todos.refetch() },\n })\n );\n const deleteMutation = useMutation(\n trpc.todo.delete.mutationOptions({\n onSuccess: () => { todos.refetch() },\n })\n );\n {{/if}}\n\n const handleAddTodo = (e: React.FormEvent) => {\n e.preventDefault();\n if (newTodoText.trim()) {\n createMutation.mutate({ text: newTodoText });\n }\n };\n\n const handleToggleTodo = (id: number, completed: boolean) => {\n toggleMutation.mutate({ id, completed: !completed });\n };\n\n const handleDeleteTodo = (id: number) => {\n deleteMutation.mutate({ id });\n };\n {{/if}}\n\n return (\n <div className=\"w-full mx-auto max-w-md py-10\">\n <Card>\n <CardHeader>\n <CardTitle>Todo List</CardTitle>\n <CardDescription>Manage your tasks efficiently</CardDescription>\n </CardHeader>\n <CardContent>\n <form\n onSubmit={handleAddTodo}\n className=\"mb-6 flex items-center space-x-2\"\n >\n <Input\n value={newTodoText}\n onChange={(e) => setNewTodoText(e.target.value)}\n placeholder=\"Add a new task...\"\n {{#if (eq backend \"convex\")}}\n {{else}}\n disabled={createMutation.isPending}\n {{/if}}\n />\n <Button\n type=\"submit\"\n {{#if (eq backend \"convex\")}}\n disabled={!newTodoText.trim()}\n {{else}}\n disabled={createMutation.isPending || !newTodoText.trim()}\n {{/if}}\n >\n {{#if (eq backend \"convex\")}}\n Add\n {{else}}\n {createMutation.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n \"Add\"\n )}\n {{/if}}\n </Button>\n </form>\n\n {{#if (eq backend \"convex\")}}\n {todos === undefined ? (\n <div className=\"flex justify-center py-4\">\n <Loader2 className=\"h-6 w-6 animate-spin\" />\n </div>\n ) : todos.length === 0 ? (\n <p className=\"py-4 text-center\">No todos yet. Add one above!</p>\n ) : (\n <ul className=\"space-y-2\">\n {todos.map((todo) => (\n <li\n key={todo._id}\n className=\"flex items-center justify-between rounded-md border p-2\"\n >\n <div className=\"flex items-center space-x-2\">\n <Checkbox\n checked={todo.completed}\n onCheckedChange={() =>\n handleToggleTodo(todo._id, todo.completed)\n }\n id={\\`todo-\\${todo._id}\\`}\n />\n <label\n htmlFor={\\`todo-\\${todo._id}\\`}\n className={\\`\\${todo.completed ? \"line-through text-muted-foreground\" : \"\"}\\`}\n >\n {todo.text}\n </label>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleDeleteTodo(todo._id)}\n aria-label=\"Delete todo\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </li>\n ))}\n </ul>\n )}\n {{else}}\n {todos.isLoading ? (\n <div className=\"flex justify-center py-4\">\n <Loader2 className=\"h-6 w-6 animate-spin\" />\n </div>\n ) : todos.data?.length === 0 ? (\n <p className=\"py-4 text-center\">\n No todos yet. Add one above!\n </p>\n ) : (\n <ul className=\"space-y-2\">\n {todos.data?.map((todo) => (\n <li\n key={todo.id}\n className=\"flex items-center justify-between rounded-md border p-2\"\n >\n <div className=\"flex items-center space-x-2\">\n <Checkbox\n checked={todo.completed}\n onCheckedChange={() =>\n handleToggleTodo(todo.id, todo.completed)\n }\n id={\\`todo-\\${todo.id}\\`}\n />\n <label\n htmlFor={\\`todo-\\${todo.id}\\`}\n className={\\`\\${todo.completed ? \"line-through\" : \"\"}\\`}\n >\n {todo.text}\n </label>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleDeleteTodo(todo.id)}\n aria-label=\"Delete todo\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </li>\n ))}\n </ul>\n )}\n {{/if}}\n </CardContent>\n </Card>\n </div>\n );\n}\n`],\n [\"examples/todo/server/prisma/sqlite/prisma/schema/todo.prisma.hbs\", `model Todo {\n id Int @id @default(autoincrement())\n text String\n completed Boolean @default(false)\n\n @@map(\"todo\")\n}\n`],\n [\"examples/todo/server/mongoose/mongodb/src/models/todo.model.ts.hbs\", `import mongoose from 'mongoose';\n\nconst { Schema, model } = mongoose;\n\nconst todoSchema = new Schema({\n id: {\n type: mongoose.Schema.Types.ObjectId,\n auto: true,\n },\n text: {\n type: String,\n required: true,\n },\n completed: {\n type: Boolean,\n default: false,\n },\n}, {\n collection: 'todo'\n});\n\nconst Todo = model('Todo', todoSchema);\n\nexport { Todo };\n`],\n [\"examples/ai/web/svelte/src/routes/ai/+page.svelte.hbs\", `<script lang=\"ts\">\n\timport { PUBLIC_SERVER_URL } from \"$env/static/public\";\n\timport { Chat } from \"@ai-sdk/svelte\";\n\timport { DefaultChatTransport } from \"ai\";\n\n\tlet input = $state(\"\");\n\tconst chat = new Chat({\n\t\ttransport: new DefaultChatTransport({\n\t\t\tapi: \\`\\${PUBLIC_SERVER_URL}/ai\\`,\n\t\t}),\n\t});\n\n\tlet messagesEndElement: HTMLDivElement | null = $state(null);\n\n\t$effect(() => {\n\t\tif (chat.messages.length > 0) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tmessagesEndElement?.scrollIntoView({ behavior: \"smooth\" });\n\t\t\t}, 0);\n\t\t}\n\t});\n\n\tfunction handleSubmit(e: Event) {\n\t\te.preventDefault();\n\t\tconst text = input.trim();\n\t\tif (!text) return;\n\t\tchat.sendMessage({ text });\n\t\tinput = \"\";\n\t}\n</script>\n\n<div\n\tclass=\"mx-auto grid h-full w-full max-w-2xl grid-rows-[1fr_auto] overflow-hidden p-4\"\n>\n\t<div class=\"mb-4 space-y-4 overflow-y-auto pb-4\">\n\t\t{#if chat.messages.length === 0}\n\t\t\t<div class=\"mt-8 text-center text-neutral-500\">\n\t\t\t\tAsk me anything to get started!\n\t\t\t</div>\n\t\t{/if}\n\n\t\t{#each chat.messages as message (message.id)}\n\t\t\t<div\n\t\t\t\tclass=\"p-3 rounded-lg w-fit max-w-[85%] text-sm md:text-base\"\n\t\t\t\tclass:ml-auto={message.role === \"user\"}\n\t\t\t\tclass:bg-primary={message.role === \"user\"}\n\t\t\t\tclass:bg-secondary={message.role === \"assistant\"}\n\t\t\t>\n\t\t\t\t<p\n\t\t\t\t\tclass=\"mb-1 text-sm font-semibold\"\n\t\t\t\t\tclass:text-indigo-600={message.role === \"user\"}\n\t\t\t\t\tclass:text-neutral-400={message.role === \"assistant\"}\n\t\t\t\t>\n\t\t\t\t\t{message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n\t\t\t\t</p>\n\t\t\t\t<div class=\"whitespace-pre-wrap break-words\">\n\t\t\t\t\t{#each message.parts as part, partIndex (partIndex)}\n\t\t\t\t\t\t{#if part.type === \"text\"}\n\t\t\t\t\t\t\t{part.text}\n\t\t\t\t\t\t{/if}\n\t\t\t\t\t{/each}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t{/each}\n\t\t<div bind:this={messagesEndElement}></div>\n\t</div>\n\n\t<form\n\t\tonsubmit={handleSubmit}\n\t\tclass=\"w-full flex items-center space-x-2 pt-2 border-t\"\n\t>\n\t\t<input\n\t\t\tname=\"prompt\"\n\t\t\tbind:value={input}\n\t\t\tplaceholder=\"Type your message...\"\n\t\t\tclass=\"flex-1 rounded border border-neutral-600 bg-neutral-800 px-3 py-2 text-neutral-100 placeholder-neutral-500 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 disabled:opacity-50\"\n\t\t\tautocomplete=\"off\"\n\t\t\tonkeydown={(e) => {\n\t\t\t\tif (e.key === \"Enter\" && !e.shiftKey) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\thandleSubmit(e);\n\t\t\t\t}\n\t\t\t}}\n\t\t/>\n\t\t<button\n\t\t\ttype=\"submit\"\n\t\t\tdisabled={!input.trim()}\n\t\t\tclass=\"inline-flex h-10 w-10 items-center justify-center rounded bg-indigo-600 text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 focus:ring-offset-neutral-900 disabled:cursor-not-allowed disabled:opacity-50\"\n\t\t\taria-label=\"Send message\"\n\t\t>\n\t\t\t<svg\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\twidth=\"18\"\n\t\t\t\theight=\"18\"\n\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\tfill=\"none\"\n\t\t\t\tstroke=\"currentColor\"\n\t\t\t\tstroke-width=\"2\"\n\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t>\n\t\t\t\t<path d=\"m22 2-7 20-4-9-9-4Z\" />\n\t\t\t\t<path d=\"M22 2 11 13\" />\n\t\t\t</svg>\n\t\t</button>\n\t</form>\n</div>\n`],\n [\"examples/todo/server/mongoose/base/src/routers/todo.ts.hbs\", `{{#if (eq api \"orpc\")}}\nimport z from \"zod\";\nimport { publicProcedure } from \"../index\";\nimport { Todo } from \"@{{projectName}}/db/models/todo.model\";\n\nexport const todoRouter = {\n getAll: publicProcedure.handler(async () => {\n return await Todo.find().lean();\n }),\n\n create: publicProcedure\n .input(z.object({ text: z.string().min(1) }))\n .handler(async ({ input }) => {\n const newTodo = await Todo.create({ text: input.text });\n return newTodo.toObject();\n }),\n\n toggle: publicProcedure\n .input(z.object({ id: z.string(), completed: z.boolean() }))\n .handler(async ({ input }) => {\n await Todo.updateOne({ id: input.id }, { completed: input.completed });\n return { success: true };\n }),\n\n delete: publicProcedure\n .input(z.object({ id: z.string() }))\n .handler(async ({ input }) => {\n await Todo.deleteOne({ id: input.id });\n return { success: true };\n }),\n};\n\n{{/if}}\n\n{{#if (eq api \"trpc\")}}\nimport z from \"zod\";\nimport { router, publicProcedure } from \"../index\";\nimport { Todo } from \"@{{projectName}}/db/models/todo.model\";\n\nexport const todoRouter = router({\n getAll: publicProcedure.query(async () => {\n return await Todo.find().lean();\n }),\n\n create: publicProcedure\n .input(z.object({ text: z.string().min(1) }))\n .mutation(async ({ input }) => {\n const newTodo = await Todo.create({ text: input.text });\n return newTodo.toObject();\n }),\n\n toggle: publicProcedure\n .input(z.object({ id: z.string(), completed: z.boolean() }))\n .mutation(async ({ input }) => {\n await Todo.updateOne({ id: input.id }, { completed: input.completed });\n return { success: true };\n }),\n\n delete: publicProcedure\n .input(z.object({ id: z.string() }))\n .mutation(async ({ input }) => {\n await Todo.deleteOne({ id: input.id });\n return { success: true };\n }),\n});\n{{/if}}\n`],\n [\"examples/ai/web/react/tanstack-start/src/routes/ai.tsx.hbs\", `{{#if (eq backend \"convex\")}}\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport {\n useUIMessages,\n useSmoothText,\n type UIMessage,\n} from \"@convex-dev/agent/react\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { useMutation } from \"convex/react\";\nimport { Send, Loader2 } from \"lucide-react\";\nimport { useRef, useEffect, useState } from \"react\";\nimport { Streamdown } from \"streamdown\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n\nexport const Route = createFileRoute(\"/ai\")({\n component: RouteComponent,\n});\n\nfunction MessageContent({\n text,\n isStreaming,\n}: {\n text: string;\n isStreaming: boolean;\n}) {\n const [visibleText] = useSmoothText(text, {\n startStreaming: isStreaming,\n });\n return <Streamdown>{visibleText}</Streamdown>;\n}\n\nfunction RouteComponent() {\n const [input, setInput] = useState(\"\");\n const [threadId, setThreadId] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n const createThread = useMutation(api.chat.createNewThread);\n const sendMessage = useMutation(api.chat.sendMessage);\n\n const { results: messages } = useUIMessages(\n api.chat.listMessages,\n threadId ? { threadId } : \"skip\",\n { initialNumItems: 50, stream: true },\n );\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n const hasStreamingMessage = messages?.some(\n (m: UIMessage) => m.status === \"streaming\",\n );\n\n const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text || isLoading) return;\n\n setIsLoading(true);\n setInput(\"\");\n\n try {\n let currentThreadId = threadId;\n if (!currentThreadId) {\n currentThreadId = await createThread();\n setThreadId(currentThreadId);\n }\n\n await sendMessage({ threadId: currentThreadId, prompt: text });\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {!messages || messages.length === 0 ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n messages.map((message: UIMessage) => (\n <div\n key={message.key}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n <MessageContent\n text={message.text ?? \"\"}\n isStreaming={message.status === \"streaming\"}\n />\n </div>\n ))\n )}\n {isLoading && !hasStreamingMessage && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Thinking...</span>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n disabled={isLoading}\n />\n <Button type=\"submit\" size=\"icon\" disabled={isLoading || !input.trim()}>\n {isLoading ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send size={18} />\n )}\n </Button>\n </form>\n </div>\n );\n}\n{{else if (eq ai \"modelfusion\")}}\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { Send, Loader2 } from \"lucide-react\";\nimport { useRef, useEffect, useState, useCallback } from \"react\";\nimport { Streamdown } from \"streamdown\";\n{{#unless (eq backend \"self\")}}\nimport { env } from \"@{{projectName}}/env/web\";\n{{/unless}}\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n\ntype Message = {\n id: string;\n role: \"user\" | \"assistant\";\n content: string;\n};\n\nexport const Route = createFileRoute(\"/ai\")({\n component: RouteComponent,\n});\n\nfunction RouteComponent() {\n const [input, setInput] = useState(\"\");\n const [messages, setMessages] = useState<Message[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [streamingContent, setStreamingContent] = useState(\"\");\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages, streamingContent]);\n\n const sendMessage = useCallback(async (text: string) => {\n const userMessage: Message = {\n id: Date.now().toString(),\n role: \"user\",\n content: text,\n };\n\n setMessages((prev) => [...prev, userMessage]);\n setIsLoading(true);\n setStreamingContent(\"\");\n\n try {\n const response = await fetch({{#if (eq backend \"self\")}}\"/api/ai\"{{else}}\\`\\${env.VITE_SERVER_URL}/ai\\`{{/if}}, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n messages: [...messages, userMessage].map((m) => ({\n role: m.role,\n content: m.content,\n })),\n }),\n });\n\n if (!response.ok) throw new Error(\"Failed to send message\");\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n\n if (reader) {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const data = line.slice(6);\n if (data === \"[DONE]\") continue;\n try {\n const parsed = JSON.parse(data);\n if (parsed.content) {\n fullContent += parsed.content;\n setStreamingContent(fullContent);\n }\n } catch {\n // Ignore parsing errors for incomplete chunks\n }\n }\n }\n }\n }\n\n const assistantMessage: Message = {\n id: (Date.now() + 1).toString(),\n role: \"assistant\",\n content: fullContent,\n };\n setMessages((prev) => [...prev, assistantMessage]);\n setStreamingContent(\"\");\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n }, [messages]);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text || isLoading) return;\n setInput(\"\");\n sendMessage(text);\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {messages.length === 0 && !streamingContent ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n <>\n {messages.map((message) => (\n <div\n key={message.id}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n <Streamdown>{message.content}</Streamdown>\n </div>\n ))}\n {streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <Streamdown isAnimating>{streamingContent}</Streamdown>\n </div>\n )}\n </>\n )}\n {isLoading && !streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Thinking...</span>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n disabled={isLoading}\n />\n <Button type=\"submit\" size=\"icon\" disabled={isLoading || !input.trim()}>\n {isLoading ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send size={18} />\n )}\n </Button>\n </form>\n </div>\n );\n}\n{{else if (eq ai \"langgraph\")}}\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { Send, Loader2 } from \"lucide-react\";\nimport { useRef, useEffect, useState, useCallback } from \"react\";\nimport { Streamdown } from \"streamdown\";\n{{#unless (eq backend \"self\")}}\nimport { env } from \"@{{projectName}}/env/web\";\n{{/unless}}\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n\ntype Message = {\n id: string;\n role: \"user\" | \"assistant\";\n content: string;\n};\n\nexport const Route = createFileRoute(\"/ai\")({\n component: RouteComponent,\n});\n\nfunction RouteComponent() {\n const [input, setInput] = useState(\"\");\n const [messages, setMessages] = useState<Message[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [streamingContent, setStreamingContent] = useState(\"\");\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages, streamingContent]);\n\n const sendMessage = useCallback(async (text: string) => {\n const userMessage: Message = {\n id: Date.now().toString(),\n role: \"user\",\n content: text,\n };\n\n setMessages((prev) => [...prev, userMessage]);\n setIsLoading(true);\n setStreamingContent(\"\");\n\n try {\n const response = await fetch({{#if (eq backend \"self\")}}\"/api/ai\"{{else}}\\`\\${env.VITE_SERVER_URL}/ai\\`{{/if}}, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n messages: [...messages, userMessage].map((m) => ({\n role: m.role,\n content: m.content,\n })),\n }),\n });\n\n if (!response.ok) throw new Error(\"Failed to send message\");\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n\n if (reader) {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const data = line.slice(6);\n if (data === \"[DONE]\") continue;\n try {\n const parsed = JSON.parse(data);\n if (parsed.content) {\n fullContent += parsed.content;\n setStreamingContent(fullContent);\n }\n } catch {\n // Ignore parsing errors for incomplete chunks\n }\n }\n }\n }\n }\n\n const assistantMessage: Message = {\n id: (Date.now() + 1).toString(),\n role: \"assistant\",\n content: fullContent,\n };\n setMessages((prev) => [...prev, assistantMessage]);\n setStreamingContent(\"\");\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n }, [messages]);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text || isLoading) return;\n setInput(\"\");\n sendMessage(text);\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {messages.length === 0 && !streamingContent ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n <>\n {messages.map((message) => (\n <div\n key={message.id}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n <Streamdown>{message.content}</Streamdown>\n </div>\n ))}\n {streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <Streamdown isAnimating>{streamingContent}</Streamdown>\n </div>\n )}\n </>\n )}\n {isLoading && !streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Thinking...</span>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n disabled={isLoading}\n />\n <Button type=\"submit\" size=\"icon\" disabled={isLoading || !input.trim()}>\n {isLoading ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send size={18} />\n )}\n </Button>\n </form>\n </div>\n );\n}\n{{else}}\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { useChat } from \"@ai-sdk/react\";\nimport { DefaultChatTransport } from \"ai\";\nimport { Send } from \"lucide-react\";\nimport { useRef, useEffect, useState } from \"react\";\nimport { Streamdown } from \"streamdown\";\n{{#unless (eq backend \"self\")}}\nimport { env } from \"@{{projectName}}/env/web\";\n{{/unless}}\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n\nexport const Route = createFileRoute(\"/ai\")({\n component: RouteComponent,\n});\n\nfunction RouteComponent() {\n const [input, setInput] = useState(\"\");\n const { messages, sendMessage, status } = useChat({\n transport: new DefaultChatTransport({\n api: {{#if (eq backend \"self\")}}\"/api/ai\"{{else}}\\`\\${env.VITE_SERVER_URL}/ai\\`{{/if}},\n }),\n });\n\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text) return;\n sendMessage({ text });\n setInput(\"\");\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {messages.length === 0 ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n messages.map((message) => (\n <div\n key={message.id}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n {message.parts?.map((part, index) => {\n if (part.type === \"text\") {\n return (\n <Streamdown\n key={index}\n isAnimating={status === \"streaming\" && message.role === \"assistant\"}\n >\n {part.text}\n </Streamdown>\n );\n }\n return null;\n })}\n </div>\n ))\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n />\n <Button type=\"submit\" size=\"icon\">\n <Send size={18} />\n </Button>\n </form>\n </div>\n );\n}\n{{/if}}\n`],\n [\"examples/ai/web/react/react-router/src/routes/ai.tsx.hbs\", `{{#if (eq backend \"convex\")}}\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport {\n useUIMessages,\n useSmoothText,\n type UIMessage,\n} from \"@convex-dev/agent/react\";\nimport { useMutation } from \"convex/react\";\nimport { Send, Loader2 } from \"lucide-react\";\nimport React, { useRef, useEffect, useState } from \"react\";\nimport { Streamdown } from \"streamdown\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n\nfunction MessageContent({\n text,\n isStreaming,\n}: {\n text: string;\n isStreaming: boolean;\n}) {\n const [visibleText] = useSmoothText(text, {\n startStreaming: isStreaming,\n });\n return <Streamdown>{visibleText}</Streamdown>;\n}\n\nconst AI: React.FC = () => {\n const [input, setInput] = useState(\"\");\n const [threadId, setThreadId] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n const createThread = useMutation(api.chat.createNewThread);\n const sendMessage = useMutation(api.chat.sendMessage);\n\n const { results: messages } = useUIMessages(\n api.chat.listMessages,\n threadId ? { threadId } : \"skip\",\n { initialNumItems: 50, stream: true },\n );\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n const hasStreamingMessage = messages?.some(\n (m: UIMessage) => m.status === \"streaming\",\n );\n\n const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text || isLoading) return;\n\n setIsLoading(true);\n setInput(\"\");\n\n try {\n let currentThreadId = threadId;\n if (!currentThreadId) {\n currentThreadId = await createThread();\n setThreadId(currentThreadId);\n }\n\n await sendMessage({ threadId: currentThreadId, prompt: text });\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {!messages || messages.length === 0 ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n messages.map((message: UIMessage) => (\n <div\n key={message.key}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n <MessageContent\n text={message.text ?? \"\"}\n isStreaming={message.status === \"streaming\"}\n />\n </div>\n ))\n )}\n {isLoading && !hasStreamingMessage && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Thinking...</span>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n disabled={isLoading}\n />\n <Button type=\"submit\" size=\"icon\" disabled={isLoading || !input.trim()}>\n {isLoading ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send size={18} />\n )}\n </Button>\n </form>\n </div>\n );\n};\n\nexport default AI;\n{{else if (eq ai \"modelfusion\")}}\nimport React, { useRef, useEffect, useState, useCallback } from \"react\";\nimport { Send, Loader2 } from \"lucide-react\";\nimport { Streamdown } from \"streamdown\";\nimport { env } from \"@{{projectName}}/env/web\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n\ntype Message = {\n id: string;\n role: \"user\" | \"assistant\";\n content: string;\n};\n\nconst AI: React.FC = () => {\n const [input, setInput] = useState(\"\");\n const [messages, setMessages] = useState<Message[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [streamingContent, setStreamingContent] = useState(\"\");\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages, streamingContent]);\n\n const sendMessage = useCallback(async (text: string) => {\n const userMessage: Message = {\n id: Date.now().toString(),\n role: \"user\",\n content: text,\n };\n\n setMessages((prev) => [...prev, userMessage]);\n setIsLoading(true);\n setStreamingContent(\"\");\n\n try {\n const response = await fetch(\\`\\${env.VITE_SERVER_URL}/ai\\`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n messages: [...messages, userMessage].map((m) => ({\n role: m.role,\n content: m.content,\n })),\n }),\n });\n\n if (!response.ok) throw new Error(\"Failed to send message\");\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n\n if (reader) {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const data = line.slice(6);\n if (data === \"[DONE]\") continue;\n try {\n const parsed = JSON.parse(data);\n if (parsed.content) {\n fullContent += parsed.content;\n setStreamingContent(fullContent);\n }\n } catch {\n // Ignore parsing errors for incomplete chunks\n }\n }\n }\n }\n }\n\n const assistantMessage: Message = {\n id: (Date.now() + 1).toString(),\n role: \"assistant\",\n content: fullContent,\n };\n setMessages((prev) => [...prev, assistantMessage]);\n setStreamingContent(\"\");\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n }, [messages]);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text || isLoading) return;\n setInput(\"\");\n sendMessage(text);\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {messages.length === 0 && !streamingContent ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n <>\n {messages.map((message) => (\n <div\n key={message.id}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n <Streamdown>{message.content}</Streamdown>\n </div>\n ))}\n {streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <Streamdown isAnimating>{streamingContent}</Streamdown>\n </div>\n )}\n </>\n )}\n {isLoading && !streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Thinking...</span>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n disabled={isLoading}\n />\n <Button type=\"submit\" size=\"icon\" disabled={isLoading || !input.trim()}>\n {isLoading ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send size={18} />\n )}\n </Button>\n </form>\n </div>\n );\n};\n\nexport default AI;\n{{else if (eq ai \"langgraph\")}}\nimport React, { useRef, useEffect, useState, useCallback } from \"react\";\nimport { Send, Loader2 } from \"lucide-react\";\nimport { Streamdown } from \"streamdown\";\nimport { env } from \"@{{projectName}}/env/web\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n\ntype Message = {\n id: string;\n role: \"user\" | \"assistant\";\n content: string;\n};\n\nconst AI: React.FC = () => {\n const [input, setInput] = useState(\"\");\n const [messages, setMessages] = useState<Message[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [streamingContent, setStreamingContent] = useState(\"\");\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages, streamingContent]);\n\n const sendMessage = useCallback(async (text: string) => {\n const userMessage: Message = {\n id: Date.now().toString(),\n role: \"user\",\n content: text,\n };\n\n setMessages((prev) => [...prev, userMessage]);\n setIsLoading(true);\n setStreamingContent(\"\");\n\n try {\n const response = await fetch(\\`\\${env.VITE_SERVER_URL}/ai\\`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n messages: [...messages, userMessage].map((m) => ({\n role: m.role,\n content: m.content,\n })),\n }),\n });\n\n if (!response.ok) throw new Error(\"Failed to send message\");\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n\n if (reader) {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const data = line.slice(6);\n if (data === \"[DONE]\") continue;\n try {\n const parsed = JSON.parse(data);\n if (parsed.content) {\n fullContent += parsed.content;\n setStreamingContent(fullContent);\n }\n } catch {\n // Ignore parsing errors for incomplete chunks\n }\n }\n }\n }\n }\n\n const assistantMessage: Message = {\n id: (Date.now() + 1).toString(),\n role: \"assistant\",\n content: fullContent,\n };\n setMessages((prev) => [...prev, assistantMessage]);\n setStreamingContent(\"\");\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n }, [messages]);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text || isLoading) return;\n setInput(\"\");\n sendMessage(text);\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {messages.length === 0 && !streamingContent ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n <>\n {messages.map((message) => (\n <div\n key={message.id}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n <Streamdown>{message.content}</Streamdown>\n </div>\n ))}\n {streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <Streamdown isAnimating>{streamingContent}</Streamdown>\n </div>\n )}\n </>\n )}\n {isLoading && !streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Thinking...</span>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n disabled={isLoading}\n />\n <Button type=\"submit\" size=\"icon\" disabled={isLoading || !input.trim()}>\n {isLoading ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send size={18} />\n )}\n </Button>\n </form>\n </div>\n );\n};\n\nexport default AI;\n{{else}}\nimport React, { useRef, useEffect, useState } from \"react\";\nimport { useChat } from \"@ai-sdk/react\";\nimport { DefaultChatTransport } from \"ai\";\nimport { Send } from \"lucide-react\";\nimport { Streamdown } from \"streamdown\";\nimport { env } from \"@{{projectName}}/env/web\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n\nconst AI: React.FC = () => {\n const [input, setInput] = useState(\"\");\n const { messages, sendMessage, status } = useChat({\n transport: new DefaultChatTransport({\n api: \\`\\${env.VITE_SERVER_URL}/ai\\`,\n }),\n });\n\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text) return;\n sendMessage({ text });\n setInput(\"\");\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {messages.length === 0 ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n messages.map((message) => (\n <div\n key={message.id}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n {message.parts?.map((part, index) => {\n if (part.type === \"text\") {\n return (\n <Streamdown\n key={index}\n isAnimating={status === \"streaming\" && message.role === \"assistant\"}\n >\n {part.text}\n </Streamdown>\n );\n }\n return null;\n })}\n </div>\n ))\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n />\n <Button type=\"submit\" size=\"icon\">\n <Send size={18} />\n </Button>\n </form>\n </div>\n );\n};\n\nexport default AI;\n{{/if}}\n`],\n [\"examples/ai/web/react/tanstack-router/src/routes/ai.tsx.hbs\", `{{#if (eq backend \"convex\")}}\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport {\n useUIMessages,\n useSmoothText,\n type UIMessage,\n} from \"@convex-dev/agent/react\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { useMutation } from \"convex/react\";\nimport { Send, Loader2 } from \"lucide-react\";\nimport { useRef, useEffect, useState } from \"react\";\nimport { Streamdown } from \"streamdown\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n\nexport const Route = createFileRoute(\"/ai\")({\n component: RouteComponent,\n});\n\nfunction MessageContent({\n text,\n isStreaming,\n}: {\n text: string;\n isStreaming: boolean;\n}) {\n const [visibleText] = useSmoothText(text, {\n startStreaming: isStreaming,\n });\n return <Streamdown>{visibleText}</Streamdown>;\n}\n\nfunction RouteComponent() {\n const [input, setInput] = useState(\"\");\n const [threadId, setThreadId] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n const createThread = useMutation(api.chat.createNewThread);\n const sendMessage = useMutation(api.chat.sendMessage);\n\n const { results: messages } = useUIMessages(\n api.chat.listMessages,\n threadId ? { threadId } : \"skip\",\n { initialNumItems: 50, stream: true },\n );\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n const hasStreamingMessage = messages?.some(\n (m: UIMessage) => m.status === \"streaming\",\n );\n\n const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text || isLoading) return;\n\n setIsLoading(true);\n setInput(\"\");\n\n try {\n let currentThreadId = threadId;\n if (!currentThreadId) {\n currentThreadId = await createThread();\n setThreadId(currentThreadId);\n }\n\n await sendMessage({ threadId: currentThreadId, prompt: text });\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {!messages || messages.length === 0 ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n messages.map((message: UIMessage) => (\n <div\n key={message.key}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n <MessageContent\n text={message.text ?? \"\"}\n isStreaming={message.status === \"streaming\"}\n />\n </div>\n ))\n )}\n {isLoading && !hasStreamingMessage && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Thinking...</span>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n disabled={isLoading}\n />\n <Button type=\"submit\" size=\"icon\" disabled={isLoading || !input.trim()}>\n {isLoading ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send size={18} />\n )}\n </Button>\n </form>\n </div>\n );\n}\n{{else if (eq ai \"modelfusion\")}}\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { Send, Loader2 } from \"lucide-react\";\nimport { useRef, useEffect, useState, useCallback } from \"react\";\nimport { Streamdown } from \"streamdown\";\n{{#unless (eq backend \"self\")}}\nimport { env } from \"@{{projectName}}/env/web\";\n{{/unless}}\n\ntype Message = {\n id: string;\n role: \"user\" | \"assistant\";\n content: string;\n};\n\nexport const Route = createFileRoute(\"/ai\")({\n component: RouteComponent,\n});\n\nfunction RouteComponent() {\n const [input, setInput] = useState(\"\");\n const [messages, setMessages] = useState<Message[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [streamingContent, setStreamingContent] = useState(\"\");\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages, streamingContent]);\n\n const sendMessage = useCallback(async (text: string) => {\n const userMessage: Message = {\n id: Date.now().toString(),\n role: \"user\",\n content: text,\n };\n\n setMessages((prev) => [...prev, userMessage]);\n setIsLoading(true);\n setStreamingContent(\"\");\n\n try {\n const response = await fetch({{#if (eq backend \"self\")}}\"/api/ai\"{{else}}\\`\\${env.VITE_SERVER_URL}/ai\\`{{/if}}, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n messages: [...messages, userMessage].map((m) => ({\n role: m.role,\n content: m.content,\n })),\n }),\n });\n\n if (!response.ok) throw new Error(\"Failed to send message\");\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n\n if (reader) {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const data = line.slice(6);\n if (data === \"[DONE]\") continue;\n try {\n const parsed = JSON.parse(data);\n if (parsed.content) {\n fullContent += parsed.content;\n setStreamingContent(fullContent);\n }\n } catch {\n // Ignore parsing errors for incomplete chunks\n }\n }\n }\n }\n }\n\n const assistantMessage: Message = {\n id: (Date.now() + 1).toString(),\n role: \"assistant\",\n content: fullContent,\n };\n setMessages((prev) => [...prev, assistantMessage]);\n setStreamingContent(\"\");\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n }, [messages]);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text || isLoading) return;\n setInput(\"\");\n sendMessage(text);\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {messages.length === 0 && !streamingContent ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n <>\n {messages.map((message) => (\n <div\n key={message.id}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n <Streamdown>{message.content}</Streamdown>\n </div>\n ))}\n {streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <Streamdown isAnimating>{streamingContent}</Streamdown>\n </div>\n )}\n </>\n )}\n {isLoading && !streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Thinking...</span>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n disabled={isLoading}\n />\n <Button type=\"submit\" size=\"icon\" disabled={isLoading || !input.trim()}>\n {isLoading ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send size={18} />\n )}\n </Button>\n </form>\n </div>\n );\n}\n{{else if (eq ai \"langgraph\")}}\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { Send, Loader2 } from \"lucide-react\";\nimport { useRef, useEffect, useState, useCallback } from \"react\";\nimport { Streamdown } from \"streamdown\";\n{{#unless (eq backend \"self\")}}\nimport { env } from \"@{{projectName}}/env/web\";\n{{/unless}}\n\ntype Message = {\n id: string;\n role: \"user\" | \"assistant\";\n content: string;\n};\n\nexport const Route = createFileRoute(\"/ai\")({\n component: RouteComponent,\n});\n\nfunction RouteComponent() {\n const [input, setInput] = useState(\"\");\n const [messages, setMessages] = useState<Message[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [streamingContent, setStreamingContent] = useState(\"\");\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages, streamingContent]);\n\n const sendMessage = useCallback(async (text: string) => {\n const userMessage: Message = {\n id: Date.now().toString(),\n role: \"user\",\n content: text,\n };\n\n setMessages((prev) => [...prev, userMessage]);\n setIsLoading(true);\n setStreamingContent(\"\");\n\n try {\n const response = await fetch({{#if (eq backend \"self\")}}\"/api/ai\"{{else}}\\`\\${env.VITE_SERVER_URL}/ai\\`{{/if}}, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n messages: [...messages, userMessage].map((m) => ({\n role: m.role,\n content: m.content,\n })),\n }),\n });\n\n if (!response.ok) throw new Error(\"Failed to send message\");\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n\n if (reader) {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const data = line.slice(6);\n if (data === \"[DONE]\") continue;\n try {\n const parsed = JSON.parse(data);\n if (parsed.content) {\n fullContent += parsed.content;\n setStreamingContent(fullContent);\n }\n } catch {\n // Ignore parsing errors for incomplete chunks\n }\n }\n }\n }\n }\n\n const assistantMessage: Message = {\n id: (Date.now() + 1).toString(),\n role: \"assistant\",\n content: fullContent,\n };\n setMessages((prev) => [...prev, assistantMessage]);\n setStreamingContent(\"\");\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n }, [messages]);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text || isLoading) return;\n setInput(\"\");\n sendMessage(text);\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {messages.length === 0 && !streamingContent ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n <>\n {messages.map((message) => (\n <div\n key={message.id}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n <Streamdown>{message.content}</Streamdown>\n </div>\n ))}\n {streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <Streamdown isAnimating>{streamingContent}</Streamdown>\n </div>\n )}\n </>\n )}\n {isLoading && !streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Thinking...</span>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n disabled={isLoading}\n />\n <Button type=\"submit\" size=\"icon\" disabled={isLoading || !input.trim()}>\n {isLoading ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send size={18} />\n )}\n </Button>\n </form>\n </div>\n );\n}\n{{else}}\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { useChat } from \"@ai-sdk/react\";\nimport { DefaultChatTransport } from \"ai\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { Send } from \"lucide-react\";\nimport { useRef, useEffect, useState } from \"react\";\nimport { Streamdown } from \"streamdown\";\n{{#unless (eq backend \"self\")}}\nimport { env } from \"@{{projectName}}/env/web\";\n{{/unless}}\n\nexport const Route = createFileRoute(\"/ai\")({\n component: RouteComponent,\n});\n\nfunction RouteComponent() {\n const [input, setInput] = useState(\"\");\n const { messages, sendMessage, status } = useChat({\n transport: new DefaultChatTransport({\n api: {{#if (eq backend \"self\")}}\"/api/ai\"{{else}}\\`\\${env.VITE_SERVER_URL}/ai\\`{{/if}},\n }),\n });\n\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text) return;\n sendMessage({ text });\n setInput(\"\");\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {messages.length === 0 ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n messages.map((message) => (\n <div\n key={message.id}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n {message.parts?.map((part, index) => {\n if (part.type === \"text\") {\n return (\n <Streamdown\n key={index}\n isAnimating={status === \"streaming\" && message.role === \"assistant\"}\n >\n {part.text}\n </Streamdown>\n );\n }\n return null;\n })}\n </div>\n ))\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n />\n <Button type=\"submit\" size=\"icon\">\n <Send size={18} />\n </Button>\n </form>\n </div>\n );\n}\n{{/if}}\n`],\n [\"api/garph/web/react/base/src/utils/garph.ts.hbs\", `import { QueryClient } from \"@tanstack/react-query\";\nimport { createClient, type InferClient } from \"@garph/gqty\";\nimport {\n createGeneratedSchema,\n createScalarsEnumsHash,\n} from \"@garph/gqty/dist/utils\";\nimport {\n g,\n queryType,\n mutationType,\n{{#if (includes examples \"todo\")}}\n todoType,\n{{/if}}\n} from \"@{{projectName}}/api/index\";\nimport { env } from \"@{{projectName}}/env/web\";\n\n// Create QueryClient for React Query integration\nexport const queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n retry: 2,\n staleTime: 1000 * 60,\n },\n },\n});\n\n// Generate schema and scalars for GQty client\nconst generatedSchema = createGeneratedSchema(g);\nconst scalarsEnumsHash = createScalarsEnumsHash(g);\n\n// Create type-safe GraphQL client\nexport const client = createClient<{\n query: InferClient<typeof queryType>;\n mutation: InferClient<typeof mutationType>;\n}>({\n generatedSchema,\n scalarsEnumsHash,\n url: \\`\\${env.VITE_SERVER_URL}/graphql\\`,\n{{#if (eq auth \"better-auth\")}}\n credentials: \"include\",\n{{/if}}\n});\n\n// Export typed query and mutation functions\nexport const { query, mutation, resolved } = client;\n\n// Helper for React Query integration\nexport async function graphqlFetcher<T>(\n fn: () => T | Promise<T>\n): Promise<T> {\n return resolved(fn);\n}\n`],\n [\"api/ts-rest/web/react/base/src/utils/ts-rest.ts.hbs\", `import { QueryClient } from \"@tanstack/react-query\";\nimport { initClient, tsRestFetchApi } from \"@ts-rest/core\";\nimport { initTsrReactQuery } from \"@ts-rest/react-query\";\nimport { contract } from \"@{{projectName}}/api/index\";\nimport { env } from \"@{{projectName}}/env/web\";\n\nexport const queryClient = new QueryClient({\n\tdefaultOptions: {\n\t\tqueries: {\n\t\t\tretry: 2,\n\t\t\tstaleTime: 1000 * 60,\n\t\t},\n\t},\n});\n\nconst client = initClient(contract, {\n\tbaseUrl: \\`\\${env.VITE_SERVER_URL}/rest\\`,\n\tbaseHeaders: {},\n{{#if (eq auth \"better-auth\")}}\n\tcredentials: \"include\",\n{{/if}}\n\tapi: tsRestFetchApi,\n});\n\nexport const tsr = initTsrReactQuery(contract, client);\n`],\n [\"api/garph/fullstack/tanstack-start/src/routes/api/graphql.ts.hbs\", `import { createAPIFileRoute } from \"@tanstack/react-start/api\";\nimport { createYoga } from \"graphql-yoga\";\nimport { createSchema } from \"@{{projectName}}/api/routers\";\nimport { createContext } from \"@{{projectName}}/api/context\";\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@/lib/auth\";\n{{/if}}\n\nconst yoga = createYoga({\n graphqlEndpoint: \"/api/graphql\",\n fetchAPI: { Response },\n context: async ({ request }) => {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: request.headers,\n });\n return createContext(request, session);\n{{else}}\n return createContext(request);\n{{/if}}\n },\n schema: async ({ request }) => {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: request.headers,\n });\n const ctx = createContext(request, session);\n{{else}}\n const ctx = createContext(request);\n{{/if}}\n return createSchema(ctx);\n },\n});\n\nexport const APIRoute = createAPIFileRoute(\"/api/graphql\")({\n GET: async ({ request }) => yoga.handleRequest(request, {}),\n POST: async ({ request }) => yoga.handleRequest(request, {}),\n});\n`],\n [\"api/garph/fullstack/astro/src/pages/api/graphql.ts.hbs\", `import type { APIRoute } from \"astro\";\nimport { createYoga } from \"graphql-yoga\";\nimport { createSchema } from \"@{{projectName}}/api/routers\";\nimport { createContext } from \"@{{projectName}}/api/context\";\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@/lib/auth\";\n{{/if}}\n\nconst yoga = createYoga({\n graphqlEndpoint: \"/api/graphql\",\n fetchAPI: { Response },\n context: async ({ request }) => {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: request.headers,\n });\n // Create a minimal API context for Astro\n const astroContext = { request } as any;\n return createContext(astroContext, session);\n{{else}}\n // Create a minimal API context for Astro\n const astroContext = { request } as any;\n return createContext(astroContext);\n{{/if}}\n },\n schema: async ({ request }) => {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: request.headers,\n });\n const astroContext = { request } as any;\n const ctx = createContext(astroContext, session);\n{{else}}\n const astroContext = { request } as any;\n const ctx = createContext(astroContext);\n{{/if}}\n return createSchema(ctx);\n },\n});\n\nexport const GET: APIRoute = async ({ request }) => {\n return yoga.handleRequest(request, {});\n};\n\nexport const POST: APIRoute = async ({ request }) => {\n return yoga.handleRequest(request, {});\n};\n`],\n [\"cms/strapi/web/next/src/strapi/lib/client.ts.hbs\", `import { strapi } from \"@strapi/client\";\nimport { strapiApiUrl, strapiApiToken } from \"../env\";\n\n// Public client for client-side requests (no auth)\nexport const strapiClient = strapi({\n baseURL: strapiApiUrl,\n});\n\n// Authenticated client for server-side requests\nexport const strapiServerClient = strapi({\n baseURL: strapiApiUrl,\n auth: strapiApiToken,\n});\n\n// Type-safe fetch helper with revalidation support\nexport async function strapiFetch<T>({\n collection,\n documentId,\n params = {},\n revalidate = 60,\n tags = [],\n useAuth = false,\n}: {\n collection: string;\n documentId?: string;\n params?: Record<string, unknown>;\n revalidate?: number | false;\n tags?: string[];\n useAuth?: boolean;\n}): Promise<T> {\n const client = useAuth ? strapiServerClient : strapiClient;\n const collectionManager = client.collection(collection);\n\n // Build fetch options for Next.js caching\n const fetchOptions = {\n next: {\n revalidate: tags.length ? false : revalidate,\n tags,\n },\n };\n\n if (documentId) {\n // Fetch single document\n const response = await collectionManager.findOne(documentId, {\n ...params,\n ...fetchOptions,\n });\n return response as T;\n }\n\n // Fetch collection\n const response = await collectionManager.find({\n ...params,\n ...fetchOptions,\n });\n return response as T;\n}\n\n// Helper for single-type content\nexport async function strapiFetchSingle<T>({\n resource,\n params = {},\n revalidate = 60,\n tags = [],\n useAuth = false,\n}: {\n resource: string;\n params?: Record<string, unknown>;\n revalidate?: number | false;\n tags?: string[];\n useAuth?: boolean;\n}): Promise<T> {\n const client = useAuth ? strapiServerClient : strapiClient;\n const singleManager = client.single(resource);\n\n const fetchOptions = {\n next: {\n revalidate: tags.length ? false : revalidate,\n tags,\n },\n };\n\n const response = await singleManager.find({\n ...params,\n ...fetchOptions,\n });\n return response as T;\n}\n`],\n [\"cms/strapi/web/next/src/strapi/lib/media.ts.hbs\", `import { strapiUrl } from \"../env\";\nimport type { StrapiMedia } from \"./types\";\n\n// Get full URL for Strapi media\nexport function getStrapiMediaUrl(media: StrapiMedia | null | undefined): string | null {\n if (!media?.url) return null;\n\n // If URL is already absolute, return as-is\n if (media.url.startsWith(\"http://\") || media.url.startsWith(\"https://\")) {\n return media.url;\n }\n\n // Prepend Strapi URL for relative paths\n return \\`\\${strapiUrl}\\${media.url}\\`;\n}\n\n// Get responsive image URL based on format\nexport function getStrapiMediaFormat(\n media: StrapiMedia | null | undefined,\n format: \"thumbnail\" | \"small\" | \"medium\" | \"large\" = \"medium\"\n): string | null {\n if (!media) return null;\n\n // Try to get the requested format, fallback to original\n const formatData = media.formats?.[format];\n if (formatData?.url) {\n if (formatData.url.startsWith(\"http://\") || formatData.url.startsWith(\"https://\")) {\n return formatData.url;\n }\n return \\`\\${strapiUrl}\\${formatData.url}\\`;\n }\n\n // Fallback to original\n return getStrapiMediaUrl(media);\n}\n\n// Get image dimensions\nexport function getStrapiMediaDimensions(\n media: StrapiMedia | null | undefined,\n format?: \"thumbnail\" | \"small\" | \"medium\" | \"large\"\n): { width: number; height: number } | null {\n if (!media) return null;\n\n if (format && media.formats?.[format]) {\n const formatData = media.formats[format];\n return {\n width: formatData.width,\n height: formatData.height,\n };\n }\n\n if (media.width && media.height) {\n return {\n width: media.width,\n height: media.height,\n };\n }\n\n return null;\n}\n\n// Generate srcset for responsive images\nexport function getStrapiSrcSet(media: StrapiMedia | null | undefined): string | null {\n if (!media?.formats) return null;\n\n const srcsetParts: string[] = [];\n const formats = [\"thumbnail\", \"small\", \"medium\", \"large\"] as const;\n\n for (const format of formats) {\n const formatData = media.formats[format];\n if (formatData?.url && formatData.width) {\n const url =\n formatData.url.startsWith(\"http://\") || formatData.url.startsWith(\"https://\")\n ? formatData.url\n : \\`\\${strapiUrl}\\${formatData.url}\\`;\n srcsetParts.push(\\`\\${url} \\${formatData.width}w\\`);\n }\n }\n\n // Add original as largest\n if (media.url && media.width) {\n const url =\n media.url.startsWith(\"http://\") || media.url.startsWith(\"https://\")\n ? media.url\n : \\`\\${strapiUrl}\\${media.url}\\`;\n srcsetParts.push(\\`\\${url} \\${media.width}w\\`);\n }\n\n return srcsetParts.length > 0 ? srcsetParts.join(\", \") : null;\n}\n`],\n [\"cms/strapi/web/next/src/strapi/lib/queries.ts.hbs\", `import qs from \"qs\";\n\n// Query parameter builders for common Strapi operations\n\n// Build query string for collection fetching with pagination\nexport function buildCollectionQuery({\n page = 1,\n pageSize = 25,\n sort,\n filters,\n populate,\n fields,\n locale,\n publicationState = \"live\",\n}: {\n page?: number;\n pageSize?: number;\n sort?: string | string[];\n filters?: Record<string, unknown>;\n populate?: string | string[] | Record<string, unknown>;\n fields?: string[];\n locale?: string;\n publicationState?: \"live\" | \"preview\";\n}): Record<string, unknown> {\n return {\n pagination: { page, pageSize },\n ...(sort && { sort }),\n ...(filters && { filters }),\n ...(populate && { populate }),\n ...(fields && { fields }),\n ...(locale && { locale }),\n publicationState,\n };\n}\n\n// Stringify query params for URL\nexport function stringifyQuery(params: Record<string, unknown>): string {\n return qs.stringify(params, {\n encodeValuesOnly: true,\n arrayFormat: \"brackets\",\n });\n}\n\n// Common populate configurations\nexport const populateConfigs = {\n // Populate all first-level relations\n all: \"*\",\n // Deep populate for nested content\n deep: {\n populate: \"*\",\n },\n // Common blog post populate\n blogPost: {\n author: {\n fields: [\"name\", \"email\"],\n populate: {\n avatar: {\n fields: [\"url\", \"alternativeText\"],\n },\n },\n },\n featuredImage: {\n fields: [\"url\", \"alternativeText\", \"width\", \"height\"],\n },\n categories: {\n fields: [\"name\", \"slug\"],\n },\n seo: {\n populate: \"*\",\n },\n },\n // Common page populate\n page: {\n seo: {\n populate: \"*\",\n },\n blocks: {\n populate: \"*\",\n },\n },\n} as const;\n\n// Common filter builders\nexport const filterBuilders = {\n // Filter by slug\n bySlug: (slug: string) => ({\n slug: { $eq: slug },\n }),\n // Filter by published status\n published: () => ({\n publishedAt: { $notNull: true },\n }),\n // Filter by category\n byCategory: (categorySlug: string) => ({\n categories: {\n slug: { $eq: categorySlug },\n },\n }),\n // Search by title\n searchTitle: (query: string) => ({\n title: { $containsi: query },\n }),\n // Date range filter\n dateRange: (start: string, end: string) => ({\n publishedAt: {\n $gte: start,\n $lte: end,\n },\n }),\n} as const;\n`],\n [\"cms/strapi/web/next/src/strapi/lib/types.ts.hbs\", `// Common Strapi response types\n\n// Pagination metadata from Strapi\nexport interface StrapiPagination {\n page: number;\n pageSize: number;\n pageCount: number;\n total: number;\n}\n\n// Standard Strapi collection response\nexport interface StrapiCollectionResponse<T> {\n data: T[];\n meta: {\n pagination: StrapiPagination;\n };\n}\n\n// Standard Strapi single response\nexport interface StrapiSingleResponse<T> {\n data: T;\n meta: Record<string, unknown>;\n}\n\n// Base Strapi document attributes\nexport interface StrapiBaseDocument {\n documentId: string;\n createdAt: string;\n updatedAt: string;\n publishedAt: string | null;\n locale?: string;\n}\n\n// Media/file type\nexport interface StrapiMedia {\n id: number;\n documentId: string;\n name: string;\n alternativeText: string | null;\n caption: string | null;\n width: number | null;\n height: number | null;\n formats: {\n thumbnail?: StrapiMediaFormat;\n small?: StrapiMediaFormat;\n medium?: StrapiMediaFormat;\n large?: StrapiMediaFormat;\n } | null;\n hash: string;\n ext: string;\n mime: string;\n size: number;\n url: string;\n previewUrl: string | null;\n provider: string;\n}\n\nexport interface StrapiMediaFormat {\n name: string;\n hash: string;\n ext: string;\n mime: string;\n width: number;\n height: number;\n size: number;\n url: string;\n}\n\n// SEO component type (common in Strapi projects)\nexport interface StrapiSEO {\n metaTitle?: string;\n metaDescription?: string;\n metaImage?: StrapiMedia;\n keywords?: string;\n canonicalURL?: string;\n metaRobots?: string;\n structuredData?: Record<string, unknown>;\n}\n\n// Example content types - customize these for your project\n\nexport interface Article extends StrapiBaseDocument {\n title: string;\n slug: string;\n content: string;\n excerpt?: string;\n featuredImage?: StrapiMedia;\n author?: Author;\n categories?: Category[];\n seo?: StrapiSEO;\n}\n\nexport interface Author extends StrapiBaseDocument {\n name: string;\n email?: string;\n bio?: string;\n avatar?: StrapiMedia;\n}\n\nexport interface Category extends StrapiBaseDocument {\n name: string;\n slug: string;\n description?: string;\n}\n\nexport interface Page extends StrapiBaseDocument {\n title: string;\n slug: string;\n content?: string;\n seo?: StrapiSEO;\n}\n\n// Homepage single type example\nexport interface Homepage extends StrapiBaseDocument {\n title: string;\n description?: string;\n heroImage?: StrapiMedia;\n seo?: StrapiSEO;\n}\n`],\n [\"addons/pwa/apps/web/next/public/favicon/apple-touch-icon.png\", `[Binary file]`],\n [\"addons/pwa/apps/web/next/public/favicon/web-app-manifest-192x192.png\", `[Binary file]`],\n [\"addons/pwa/apps/web/next/public/favicon/favicon-96x96.png\", `[Binary file]`],\n [\"addons/pwa/apps/web/next/public/favicon/web-app-manifest-512x512.png\", `[Binary file]`],\n [\"addons/pwa/apps/web/next/public/favicon/site.webmanifest.hbs\", `{\n\t\"name\": \"{{projectName}}\",\n\t\"short_name\": \"{{projectName}}\",\n\t\"icons\": [\n\t\t{\n\t\t\t\"src\": \"/web-app-manifest-192x192.png\",\n\t\t\t\"sizes\": \"192x192\",\n\t\t\t\"type\": \"image/png\",\n\t\t\t\"purpose\": \"maskable\"\n\t\t},\n\t\t{\n\t\t\t\"src\": \"/web-app-manifest-512x512.png\",\n\t\t\t\"sizes\": \"512x512\",\n\t\t\t\"type\": \"image/png\",\n\t\t\t\"purpose\": \"maskable\"\n\t\t}\n\t],\n\t\"theme_color\": \"#ffffff\",\n\t\"background_color\": \"#ffffff\",\n\t\"display\": \"standalone\"\n}\n`],\n [\"addons/pwa/apps/web/next/public/favicon/favicon.svg\", `<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"92\" height=\"92\"><svg width=\"92\" height=\"92\" viewBox=\"0 0 92 92\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"8\" y=\"8\" width=\"76\" height=\"76\" rx=\"12\" fill=\"#F5EEFF\" stroke=\"#B79AFF\" stroke-width=\"3\"></rect>\n <text x=\"46\" y=\"56\" text-anchor=\"middle\" font-family=\"monospace\" font-size=\"40\" fill=\"#8F5BFF\">$<tspan dx=\"0\" dy=\"0\">_</tspan></text>\n</svg><style>@media (prefers-color-scheme: light) { :root { filter: none; } }\n@media (prefers-color-scheme: dark) { :root { filter: none; } }\n</style></svg>`],\n [\"cms/sanity/web/next/src/sanity/schemas/post.ts.hbs\", `import { defineField, defineType } from \"sanity\";\n\nexport const post = defineType({\n name: \"post\",\n title: \"Post\",\n type: \"document\",\n fields: [\n defineField({\n name: \"title\",\n title: \"Title\",\n type: \"string\",\n validation: (rule) => rule.required(),\n }),\n defineField({\n name: \"slug\",\n title: \"Slug\",\n type: \"slug\",\n options: {\n source: \"title\",\n maxLength: 96,\n },\n validation: (rule) => rule.required(),\n }),\n defineField({\n name: \"author\",\n title: \"Author\",\n type: \"reference\",\n to: { type: \"author\" },\n }),\n defineField({\n name: \"mainImage\",\n title: \"Main image\",\n type: \"image\",\n options: {\n hotspot: true,\n },\n }),\n defineField({\n name: \"publishedAt\",\n title: \"Published at\",\n type: \"datetime\",\n }),\n defineField({\n name: \"excerpt\",\n title: \"Excerpt\",\n type: \"text\",\n rows: 3,\n }),\n defineField({\n name: \"body\",\n title: \"Body\",\n type: \"blockContent\",\n }),\n ],\n preview: {\n select: {\n title: \"title\",\n author: \"author.name\",\n media: \"mainImage\",\n },\n prepare(selection) {\n const { author } = selection;\n return { ...selection, subtitle: author && \\`by \\${author}\\` };\n },\n },\n});\n`],\n [\"cms/sanity/web/next/src/sanity/schemas/author.ts.hbs\", `import { defineField, defineType } from \"sanity\";\n\nexport const author = defineType({\n name: \"author\",\n title: \"Author\",\n type: \"document\",\n fields: [\n defineField({\n name: \"name\",\n title: \"Name\",\n type: \"string\",\n validation: (rule) => rule.required(),\n }),\n defineField({\n name: \"slug\",\n title: \"Slug\",\n type: \"slug\",\n options: {\n source: \"name\",\n maxLength: 96,\n },\n validation: (rule) => rule.required(),\n }),\n defineField({\n name: \"image\",\n title: \"Image\",\n type: \"image\",\n options: {\n hotspot: true,\n },\n }),\n defineField({\n name: \"bio\",\n title: \"Bio\",\n type: \"array\",\n of: [\n {\n title: \"Block\",\n type: \"block\",\n styles: [{ title: \"Normal\", value: \"normal\" }],\n lists: [],\n },\n ],\n }),\n ],\n preview: {\n select: {\n title: \"name\",\n media: \"image\",\n },\n },\n});\n`],\n [\"cms/sanity/web/next/src/sanity/schemas/page.ts.hbs\", `import { defineField, defineType } from \"sanity\";\n\nexport const page = defineType({\n name: \"page\",\n title: \"Page\",\n type: \"document\",\n fields: [\n defineField({\n name: \"title\",\n title: \"Title\",\n type: \"string\",\n validation: (rule) => rule.required(),\n }),\n defineField({\n name: \"slug\",\n title: \"Slug\",\n type: \"slug\",\n options: {\n source: \"title\",\n maxLength: 96,\n },\n validation: (rule) => rule.required(),\n }),\n defineField({\n name: \"content\",\n title: \"Content\",\n type: \"blockContent\",\n }),\n defineField({\n name: \"seo\",\n title: \"SEO\",\n type: \"object\",\n fields: [\n defineField({\n name: \"metaTitle\",\n title: \"Meta Title\",\n type: \"string\",\n }),\n defineField({\n name: \"metaDescription\",\n title: \"Meta Description\",\n type: \"text\",\n rows: 3,\n }),\n ],\n }),\n ],\n preview: {\n select: {\n title: \"title\",\n subtitle: \"slug.current\",\n },\n },\n});\n`],\n [\"cms/sanity/web/next/src/sanity/schemas/index.ts.hbs\", `import { author } from \"./author\";\nimport { blockContent } from \"./blockContent\";\nimport { page } from \"./page\";\nimport { post } from \"./post\";\n\nexport const schemaTypes = [author, blockContent, page, post];\n`],\n [\"cms/sanity/web/next/src/sanity/schemas/blockContent.ts.hbs\", `import { defineType, defineArrayMember } from \"sanity\";\n\nexport const blockContent = defineType({\n title: \"Block Content\",\n name: \"blockContent\",\n type: \"array\",\n of: [\n defineArrayMember({\n title: \"Block\",\n type: \"block\",\n styles: [\n { title: \"Normal\", value: \"normal\" },\n { title: \"H1\", value: \"h1\" },\n { title: \"H2\", value: \"h2\" },\n { title: \"H3\", value: \"h3\" },\n { title: \"H4\", value: \"h4\" },\n { title: \"Quote\", value: \"blockquote\" },\n ],\n lists: [\n { title: \"Bullet\", value: \"bullet\" },\n { title: \"Numbered\", value: \"number\" },\n ],\n marks: {\n decorators: [\n { title: \"Strong\", value: \"strong\" },\n { title: \"Emphasis\", value: \"em\" },\n { title: \"Code\", value: \"code\" },\n { title: \"Underline\", value: \"underline\" },\n { title: \"Strike\", value: \"strike-through\" },\n ],\n annotations: [\n {\n title: \"URL\",\n name: \"link\",\n type: \"object\",\n fields: [\n {\n title: \"URL\",\n name: \"href\",\n type: \"url\",\n },\n ],\n },\n ],\n },\n }),\n defineArrayMember({\n type: \"image\",\n options: { hotspot: true },\n }),\n ],\n});\n`],\n [\"cms/sanity/web/next/src/sanity/lib/client.ts.hbs\", `import { createClient, type QueryParams } from \"next-sanity\";\n\nimport { apiVersion, dataset, projectId, token } from \"../env\";\n\nexport const client = createClient({\n projectId,\n dataset,\n apiVersion,\n useCdn: true, // Set to false for ISR/SSG or tag-based revalidation\n});\n\n// Server-side client with token for authenticated requests\nexport const serverClient = token\n ? client.withConfig({\n token,\n useCdn: false,\n })\n : client;\n\n// Helper function for fetching data with revalidation options\nexport async function sanityFetch<T>({\n query,\n params = {},\n revalidate = 60,\n tags = [],\n}: {\n query: string;\n params?: QueryParams;\n revalidate?: number | false;\n tags?: string[];\n}): Promise<T> {\n return client.fetch<T>(query, params, {\n next: {\n revalidate: tags.length ? false : revalidate,\n tags,\n },\n });\n}\n`],\n [\"cms/sanity/web/next/src/sanity/lib/image.ts.hbs\", `import createImageUrlBuilder from \"@sanity/image-url\";\nimport type { SanityImageSource } from \"@sanity/image-url/lib/types/types\";\n\nimport { dataset, projectId } from \"../env\";\n\nconst imageBuilder = createImageUrlBuilder({\n projectId,\n dataset,\n});\n\nexport function urlFor(source: SanityImageSource) {\n return imageBuilder.image(source);\n}\n`],\n [\"cms/sanity/web/next/src/sanity/lib/queries.ts.hbs\", `import { defineQuery } from \"next-sanity\";\n\n// Get all posts\nexport const POSTS_QUERY = defineQuery(\\`\n *[_type == \"post\" && defined(slug.current)] | order(publishedAt desc) {\n _id,\n title,\n slug,\n excerpt,\n publishedAt,\n mainImage,\n \"author\": author->{ name, image }\n }\n\\`);\n\n// Get a single post by slug\nexport const POST_QUERY = defineQuery(\\`\n *[_type == \"post\" && slug.current == $slug][0] {\n _id,\n title,\n slug,\n excerpt,\n body,\n publishedAt,\n mainImage,\n \"author\": author->{ name, image, bio }\n }\n\\`);\n\n// Get all pages\nexport const PAGES_QUERY = defineQuery(\\`\n *[_type == \"page\" && defined(slug.current)] | order(title asc) {\n _id,\n title,\n slug\n }\n\\`);\n\n// Get a single page by slug\nexport const PAGE_QUERY = defineQuery(\\`\n *[_type == \"page\" && slug.current == $slug][0] {\n _id,\n title,\n slug,\n content\n }\n\\`);\n\n// Get all authors\nexport const AUTHORS_QUERY = defineQuery(\\`\n *[_type == \"author\"] | order(name asc) {\n _id,\n name,\n slug,\n image,\n bio\n }\n\\`);\n`],\n [\"addons/pwa/apps/web/next/src/app/manifest.ts.hbs\", `import type { MetadataRoute } from \"next\";\n\nexport default function manifest(): MetadataRoute.Manifest {\n\treturn {\n\t\tname: \"{{projectName}}\",\n\t\tshort_name: \"{{projectName}}\",\n\t\tdescription:\n\t\t\t\"my pwa app\",\n\t\tstart_url: \"/new\",\n\t\tdisplay: \"standalone\",\n\t\tbackground_color: \"#ffffff\",\n\t\ttheme_color: \"#000000\",\n\t\ticons: [\n\t\t\t{\n\t\t\t\tsrc: \"/favicon/web-app-manifest-192x192.png\",\n\t\t\t\tsizes: \"192x192\",\n\t\t\t\ttype: \"image/png\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tsrc: \"/favicon/web-app-manifest-512x512.png\",\n\t\t\t\tsizes: \"512x512\",\n\t\t\t\ttype: \"image/png\",\n\t\t\t},\n\t\t],\n\t};\n}\n`],\n [\"payments/lemon-squeezy/web/react/next/src/app/success/page.tsx.hbs\", `export default async function SuccessPage({\n\tsearchParams,\n}: {\n\tsearchParams: Promise<{ checkout_id?: string }>\n}) {\n\tconst params = await searchParams;\n\tconst checkoutId = params.checkout_id;\n\n\treturn (\n\t\t<div className=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 className=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p className=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t{checkoutId && (\n\t\t\t\t<p className=\"text-sm text-gray-500\">Checkout ID: {checkoutId}</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n`],\n [\"cms/payload/web/next/src/payload/collections/Media.ts.hbs\", `import type { CollectionConfig } from \"payload\";\n\nexport const Media: CollectionConfig = {\n slug: \"media\",\n upload: {\n staticDir: \"media\",\n mimeTypes: [\"image/*\", \"video/*\", \"audio/*\", \"application/pdf\"],\n },\n admin: {\n useAsTitle: \"alt\",\n },\n fields: [\n {\n name: \"alt\",\n type: \"text\",\n required: true,\n },\n {\n name: \"caption\",\n type: \"textarea\",\n },\n ],\n};\n`],\n [\"cms/payload/web/next/src/payload/collections/Pages.ts.hbs\", `import type { CollectionConfig } from \"payload\";\n\nexport const Pages: CollectionConfig = {\n slug: \"pages\",\n admin: {\n useAsTitle: \"title\",\n defaultColumns: [\"title\", \"slug\", \"status\", \"updatedAt\"],\n },\n versions: {\n drafts: true,\n },\n fields: [\n {\n name: \"title\",\n type: \"text\",\n required: true,\n },\n {\n name: \"slug\",\n type: \"text\",\n required: true,\n unique: true,\n admin: {\n position: \"sidebar\",\n },\n },\n {\n name: \"status\",\n type: \"select\",\n options: [\n { label: \"Draft\", value: \"draft\" },\n { label: \"Published\", value: \"published\" },\n ],\n defaultValue: \"draft\",\n admin: {\n position: \"sidebar\",\n },\n },\n {\n name: \"content\",\n type: \"richText\",\n },\n {\n name: \"featuredImage\",\n type: \"upload\",\n relationTo: \"media\",\n },\n {\n name: \"meta\",\n type: \"group\",\n fields: [\n {\n name: \"title\",\n type: \"text\",\n label: \"Meta Title\",\n },\n {\n name: \"description\",\n type: \"textarea\",\n label: \"Meta Description\",\n },\n ],\n },\n ],\n};\n`],\n [\"cms/payload/web/next/src/payload/collections/Users.ts.hbs\", `import type { CollectionConfig } from \"payload\";\n\nexport const Users: CollectionConfig = {\n slug: \"users\",\n auth: true,\n admin: {\n useAsTitle: \"email\",\n },\n fields: [\n {\n name: \"name\",\n type: \"text\",\n },\n {\n name: \"role\",\n type: \"select\",\n options: [\n { label: \"Admin\", value: \"admin\" },\n { label: \"Editor\", value: \"editor\" },\n { label: \"User\", value: \"user\" },\n ],\n defaultValue: \"user\",\n required: true,\n },\n ],\n};\n`],\n [\"api/orpc/web/react/base/src/utils/orpc.ts.hbs\", `import { createORPCClient } from \"@orpc/client\";\nimport { RPCLink } from \"@orpc/client/fetch\";\nimport { createTanstackQueryUtils } from \"@orpc/tanstack-query\";\nimport { QueryCache, QueryClient } from \"@tanstack/react-query\";\nimport { toast } from \"sonner\";\n{{#if (and (includes frontend \"tanstack-start\") (eq backend \"self\"))}}\nimport { createRouterClient } from \"@orpc/server\";\nimport type { RouterClient } from \"@orpc/server\";\nimport { createIsomorphicFn } from \"@tanstack/react-start\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\nimport { createContext } from \"@{{projectName}}/api/context\";\n{{else if (includes frontend \"tanstack-start\")}}\nimport type { RouterClient } from \"@orpc/server\";\nimport type { AppRouter } from \"@{{projectName}}/api/routers/index\";\nimport { env } from \"@{{projectName}}/env/web\";\n{{else}}\nimport type { AppRouterClient } from \"@{{projectName}}/api/routers/index\";\n{{#unless (eq backend \"self\")}}\nimport { env } from \"@{{projectName}}/env/web\";\n{{/unless}}\n{{/if}}\n\nexport const queryClient = new QueryClient({\n\tqueryCache: new QueryCache({\n\t\tonError: (error, query) => {\n\t\t\ttoast.error(\\`Error: \\${error.message}\\`, {\n\t\t\t\taction: {\n\t\t\t\t\tlabel: \"retry\",\n\t\t\t\t\tonClick: query.invalidate,\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t}),\n});\n\n{{#if (and (includes frontend \"tanstack-start\") (eq backend \"self\"))}}\nconst getORPCClient = createIsomorphicFn()\n\t.server(() =>\n\t\tcreateRouterClient(appRouter, {\n\t\t\tcontext: async ({ req }) => {\n\t\t\t\treturn createContext({ req });\n\t\t\t},\n\t\t}),\n\t)\n\t.client((): RouterClient<typeof appRouter> => {\n\t\t\tconst link = new RPCLink({\n\t\t\turl: \\`\\${window.location.origin}/api/rpc\\`,\n{{#if (eq auth \"better-auth\")}}\n\t\t\tfetch(url, options) {\n\t\t\t\treturn fetch(url, {\n\t\t\t\t\t...options,\n\t\t\t\t\tcredentials: \"include\",\n\t\t\t\t});\n\t\t\t},\n{{/if}}\n\t\t});\n\n\t\treturn createORPCClient(link);\n\t});\n\nexport const client: RouterClient<typeof appRouter> = getORPCClient();\n{{else if (includes frontend \"tanstack-start\")}}\nconst link = new RPCLink({\n\turl: \\`\\${env.VITE_SERVER_URL}/rpc\\`,\n{{#if (eq auth \"better-auth\")}}\n\tfetch(url, options) {\n\t\treturn fetch(url, {\n\t\t\t...options,\n\t\t\tcredentials: \"include\",\n\t\t});\n\t},\n{{/if}}\n});\n\nconst getORPCClient = () => {\n\treturn createORPCClient(link) as RouterClient<AppRouter>;\n};\n\nexport const client: RouterClient<AppRouter> = getORPCClient();\n{{else}}\nexport const link = new RPCLink({\n{{#if (and (eq backend \"self\") (includes frontend \"next\"))}}\n\turl: \\`\\${typeof window !== \"undefined\" ? window.location.origin : \"http://localhost:3001\"}/api/rpc\\`,\n{{else if (includes frontend \"next\")}}\n\turl: \\`\\${env.NEXT_PUBLIC_SERVER_URL}/rpc\\`,\n{{else}}\n\turl: \\`\\${env.VITE_SERVER_URL}/rpc\\`,\n{{/if}}\n{{#if (eq auth \"better-auth\")}}\n\tfetch(url, options) {\n\t\treturn fetch(url, {\n\t\t\t...options,\n\t\t\tcredentials: \"include\",\n\t\t});\n\t},\n{{#if (includes frontend \"next\")}}\n\theaders: async () => {\n\t\tif (typeof window !== \"undefined\") {\n\t\t\treturn {}\n\t\t}\n\n\t\tconst { headers } = await import(\"next/headers\")\n\t\treturn Object.fromEntries(await headers())\n\t},\n{{/if}}\n{{/if}}\n});\n\nexport const client: AppRouterClient = createORPCClient(link)\n{{/if}}\n\nexport const orpc = createTanstackQueryUtils(client)\n\n`],\n [\"api/trpc/web/react/base/src/utils/trpc.ts.hbs\", `{{#if (includes frontend 'next')}}\nimport { QueryCache, QueryClient } from '@tanstack/react-query';\nimport { createTRPCClient, httpBatchLink } from '@trpc/client';\nimport { createTRPCOptionsProxy } from '@trpc/tanstack-react-query';\nimport type { AppRouter } from \"@{{projectName}}/api/routers/index\";\nimport { toast } from 'sonner';\n{{#unless (eq backend \"self\")}}\nimport { env } from \"@{{projectName}}/env/web\";\n{{/unless}}\n\nexport const queryClient = new QueryClient({\n\tqueryCache: new QueryCache({\n\t\tonError: (error, query) => {\n\t\t\ttoast.error(error.message, {\n\t\t\t\taction: {\n\t\t\t\t\tlabel: \"retry\",\n\t\t\t\t\tonClick: query.invalidate,\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t}),\n});\n\nconst trpcClient = createTRPCClient<AppRouter>({\n\tlinks: [\n\t\thttpBatchLink({\n{{#if (eq backend \"self\")}}\n\t\t\turl: \"/api/trpc\",\n{{else}}\n\t\t\turl: \\`\\${env.NEXT_PUBLIC_SERVER_URL}/trpc\\`,\n{{/if}}\n{{#if (eq auth \"better-auth\")}}\n\t\t\tfetch(url, options) {\n\t\t\t\treturn fetch(url, {\n\t\t\t\t\t...options,\n\t\t\t\t\tcredentials: \"include\",\n\t\t\t\t});\n\t\t\t},\n{{/if}}\n\t\t}),\n\t],\n})\n\nexport const trpc = createTRPCOptionsProxy<AppRouter>({\n\tclient: trpcClient,\n\tqueryClient,\n});\n\n{{else if (includes frontend 'tanstack-start')}}\nimport { createTRPCContext } from \"@trpc/tanstack-react-query\";\nimport type { AppRouter } from \"@{{projectName}}/api/routers/index\";\n\nexport const { TRPCProvider, useTRPC, useTRPCClient } =\n\tcreateTRPCContext<AppRouter>();\n\n{{else}}\nimport type { AppRouter } from \"@{{projectName}}/api/routers/index\";\nimport { QueryCache, QueryClient } from \"@tanstack/react-query\";\nimport { createTRPCClient, httpBatchLink } from \"@trpc/client\";\nimport { createTRPCOptionsProxy } from \"@trpc/tanstack-react-query\";\nimport { toast } from \"sonner\";\nimport { env } from \"@{{projectName}}/env/web\";\n\nexport const queryClient = new QueryClient({\n\tqueryCache: new QueryCache({\n\t\tonError: (error, query) => {\n\t\t\ttoast.error(error.message, {\n\t\t\t\taction: {\n\t\t\t\t\tlabel: \"retry\",\n\t\t\t\t\tonClick: query.invalidate,\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t}),\n});\n\nexport const trpcClient = createTRPCClient<AppRouter>({\n\tlinks: [\n\t\thttpBatchLink({\n\t\t\turl: \\`\\${env.VITE_SERVER_URL}/trpc\\`,\n{{#if (eq auth \"better-auth\")}}\n\t\t\tfetch(url, options) {\n\t\t\t\treturn fetch(url, {\n\t\t\t\t\t...options,\n\t\t\t\t\tcredentials: \"include\",\n\t\t\t\t});\n\t\t\t},\n{{/if}}\n\t\t}),\n\t],\n});\n\nexport const trpc = createTRPCOptionsProxy<AppRouter>({\n\tclient: trpcClient,\n\tqueryClient,\n});\n{{/if}}\n`],\n [\"payments/paddle/web/react/next/src/app/success/page.tsx.hbs\", `export default async function SuccessPage({\n\tsearchParams,\n}: {\n\tsearchParams: Promise<{ transaction_id?: string }>\n}) {\n\tconst params = await searchParams;\n\tconst transactionId = params.transaction_id;\n\n\treturn (\n\t\t<div className=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 className=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p className=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t{transactionId && (\n\t\t\t\t<p className=\"text-sm text-gray-500\">Transaction ID: {transactionId}</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n`],\n [\"payments/stripe/web/react/next/src/app/success/page.tsx.hbs\", `export default async function SuccessPage({\n\tsearchParams,\n}: {\n\tsearchParams: Promise<{ session_id: string }>\n}) {\n\tconst params = await searchParams;\n\tconst session_id = params.session_id;\n\n\treturn (\n\t\t<div className=\"container mx-auto px-4 py-8\">\n\t\t\t<h1 className=\"text-2xl font-bold mb-4\">Payment Successful!</h1>\n\t\t\t<p className=\"text-gray-600 mb-4\">\n\t\t\t\tThank you for your purchase. Your payment has been processed successfully.\n\t\t\t</p>\n\t\t\t{session_id && (\n\t\t\t\t<p className=\"text-sm text-gray-500\">Session ID: {session_id}</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n`],\n [\"payments/polar/web/react/next/src/app/success/page.tsx.hbs\", `export default async function SuccessPage({\n searchParams,\n}: {\n searchParams: Promise<{ checkout_id: string }>\n}) {\n const params = await searchParams;\n const checkout_id = params.checkout_id;\n\n return (\n <div className=\"px-4 py-8\">\n <h1>Payment Successful!</h1>\n {checkout_id && <p>Checkout ID: {checkout_id}</p>}\n </div>\n );\n}\n`],\n [\"auth/better-auth/convex/web/react/tanstack-start/src/routes/dashboard.tsx.hbs\", `import SignInForm from \"@/components/sign-in-form\";\nimport SignUpForm from \"@/components/sign-up-form\";\nimport UserMenu from \"@/components/user-menu\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport {\n Authenticated,\n AuthLoading,\n Unauthenticated,\n useQuery,\n} from \"convex/react\";\nimport { useState } from \"react\";\n\nexport const Route = createFileRoute(\"/dashboard\")({\n component: RouteComponent,\n});\n\nfunction RouteComponent() {\n const [showSignIn, setShowSignIn] = useState(false);\n const privateData = useQuery(api.privateData.get);\n\n return (\n <>\n <Authenticated>\n <div>\n <h1>Dashboard</h1>\n <p>privateData: {privateData?.message}</p>\n <UserMenu />\n </div>\n </Authenticated>\n <Unauthenticated>\n {showSignIn ? (\n <SignInForm onSwitchToSignUp={() => setShowSignIn(false)} />\n ) : (\n <SignUpForm onSwitchToSignIn={() => setShowSignIn(true)} />\n )}\n </Unauthenticated>\n <AuthLoading>\n <div>Loading...</div>\n </AuthLoading>\n </>\n );\n}\n`],\n [\"auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-server.ts.hbs\", `import { convexBetterAuthReactStart } from \"@convex-dev/better-auth/react-start\";\nimport { env } from \"@{{projectName}}/env/web\";\n\nexport const {\n\thandler,\n\tgetToken,\n\tfetchAuthQuery,\n\tfetchAuthMutation,\n\tfetchAuthAction,\n} = convexBetterAuthReactStart({\n\tconvexUrl: env.VITE_CONVEX_URL,\n\tconvexSiteUrl: env.VITE_CONVEX_SITE_URL,\n});\n`],\n [\"auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-client.ts.hbs\", `import { createAuthClient } from \"better-auth/react\";\nimport { convexClient } from \"@convex-dev/better-auth/client/plugins\";\n\nexport const authClient = createAuthClient({\n plugins: [convexClient()],\n});`],\n [\"auth/better-auth/convex/web/react/tanstack-start/src/components/user-menu.tsx.hbs\", `import {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { authClient } from \"@/lib/auth-client\";\nimport { useQuery } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\n\nimport { Button } from \"./ui/button\";\n\nexport default function UserMenu() {\n const user = useQuery(api.auth.getCurrentUser)\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button variant=\"outline\" />}>\n {user?.name}\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"bg-card\">\n <DropdownMenuGroup>\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>{user?.email}</DropdownMenuItem>\n <DropdownMenuItem\n variant=\"destructive\"\n onClick={() => {\n authClient.signOut({\n fetchOptions: {\n onSuccess: () => {\n location.reload();\n },\n },\n });\n }}\n >\n Sign Out\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n`],\n [\"auth/better-auth/convex/web/react/tanstack-start/src/components/sign-in-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { useNavigate } from \"@tanstack/react-router\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\n\nexport default function SignInForm({\n onSwitchToSignUp,\n}: {\n onSwitchToSignUp: () => void;\n}) {\n const navigate = useNavigate({\n from: \"/\",\n });\n\n const form = useForm({\n defaultValues: {\n email: \"\",\n password: \"\",\n },\n onSubmit: async ({ value }) => {\n await authClient.signIn.email(\n {\n email: value.email,\n password: value.password,\n },\n {\n onSuccess: () => {\n navigate({\n to: \"/dashboard\",\n });\n toast.success(\"Sign in successful\");\n },\n onError: (error) => {\n toast.error(error.error.message || error.error.statusText);\n },\n },\n );\n },\n validators: {\n onSubmit: z.object({\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n });\n\n return (\n <div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 className=\"mb-6 text-center text-3xl font-bold\">Welcome Back</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n className=\"space-y-4\"\n >\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Email</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"email\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={!state.canSubmit || state.isSubmitting}\n >\n {state.isSubmitting ? \"Submitting...\" : \"Sign In\"}\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n <div className=\"mt-4 text-center\">\n <Button\n variant=\"link\"\n onClick={onSwitchToSignUp}\n className=\"text-indigo-600 hover:text-indigo-800\"\n >\n Need an account? Sign Up\n </Button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/better-auth/convex/web/react/tanstack-start/src/components/sign-up-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { useNavigate } from \"@tanstack/react-router\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\n\nexport default function SignUpForm({\n onSwitchToSignIn,\n}: {\n onSwitchToSignIn: () => void;\n}) {\n const navigate = useNavigate({\n from: \"/\",\n });\n\n const form = useForm({\n defaultValues: {\n email: \"\",\n password: \"\",\n name: \"\",\n },\n onSubmit: async ({ value }) => {\n await authClient.signUp.email(\n {\n email: value.email,\n password: value.password,\n name: value.name,\n },\n {\n onSuccess: () => {\n navigate({\n to: \"/dashboard\",\n });\n toast.success(\"Sign up successful\");\n },\n onError: (error) => {\n toast.error(error.error.message || error.error.statusText);\n },\n },\n );\n },\n validators: {\n onSubmit: z.object({\n name: z.string().min(2, \"Name must be at least 2 characters\"),\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n });\n\n return (\n <div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 className=\"mb-6 text-center text-3xl font-bold\">Create Account</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n className=\"space-y-4\"\n >\n <div>\n <form.Field name=\"name\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Name</Label>\n <Input\n id={field.name}\n name={field.name}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Email</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"email\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={!state.canSubmit || state.isSubmitting}\n >\n {state.isSubmitting ? \"Submitting...\" : \"Sign Up\"}\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n <div className=\"mt-4 text-center\">\n <Button\n variant=\"link\"\n onClick={onSwitchToSignIn}\n className=\"text-indigo-600 hover:text-indigo-800\"\n >\n Already have an account? Sign In\n </Button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs\", `import { convexBetterAuthNextJs } from \"@convex-dev/better-auth/nextjs\";\nimport { env } from \"@{{projectName}}/env/web\";\n\nexport const {\n\thandler,\n\tpreloadAuthQuery,\n\tisAuthenticated,\n\tgetToken,\n\tfetchAuthQuery,\n\tfetchAuthMutation,\n\tfetchAuthAction,\n} = convexBetterAuthNextJs({\n\tconvexUrl: env.NEXT_PUBLIC_CONVEX_URL,\n\tconvexSiteUrl: env.NEXT_PUBLIC_CONVEX_SITE_URL,\n});\n`],\n [\"auth/better-auth/convex/web/react/next/src/lib/auth-client.ts.hbs\", `import { createAuthClient } from \"better-auth/react\";\nimport { convexClient } from \"@convex-dev/better-auth/client/plugins\";\n\nexport const authClient = createAuthClient({\n plugins: [convexClient()],\n});\n`],\n [\"auth/better-auth/convex/web/react/next/src/components/user-menu.tsx.hbs\", `import {\n\tDropdownMenu,\n\tDropdownMenuContent,\n\tDropdownMenuGroup,\n\tDropdownMenuItem,\n\tDropdownMenuLabel,\n\tDropdownMenuSeparator,\n\tDropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { authClient } from \"@/lib/auth-client\";\nimport { Button } from \"./ui/button\";\nimport { useRouter } from \"next/navigation\";\nimport { useQuery } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\n\nexport default function UserMenu() {\n\tconst router = useRouter();\n\tconst user = useQuery(api.auth.getCurrentUser)\n\n\treturn (\n\t\t<DropdownMenu>\n\t\t\t<DropdownMenuTrigger render={<Button variant=\"outline\" />}>\n\t\t\t\t{user?.name}\n\t\t\t</DropdownMenuTrigger>\n\t\t\t<DropdownMenuContent className=\"bg-card\">\n\t\t\t\t<DropdownMenuGroup>\n\t\t\t\t\t<DropdownMenuLabel>My Account</DropdownMenuLabel>\n\t\t\t\t\t<DropdownMenuSeparator />\n\t\t\t\t\t<DropdownMenuItem>{user?.email}</DropdownMenuItem>\n\t\t\t\t\t<DropdownMenuItem\n\t\t\t\t\t\tvariant=\"destructive\"\n\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\tauthClient.signOut({\n\t\t\t\t\t\t\t\tfetchOptions: {\n\t\t\t\t\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\t\t\t\t\trouter.push(\"/dashboard\");\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\tSign Out\n\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t</DropdownMenuGroup>\n\t\t\t</DropdownMenuContent>\n\t\t</DropdownMenu>\n\t);\n}\n`],\n [\"auth/better-auth/convex/web/react/next/src/components/sign-in-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\nimport { useRouter } from \"next/navigation\";\n\nexport default function SignInForm({\n\tonSwitchToSignUp,\n}: {\n\tonSwitchToSignUp: () => void;\n}) {\n\tconst router = useRouter();\n\n\tconst form = useForm({\n\t\tdefaultValues: {\n\t\t\temail: \"\",\n\t\t\tpassword: \"\",\n\t\t},\n\t\tonSubmit: async ({ value }) => {\n\t\t\tawait authClient.signIn.email(\n\t\t\t\t{\n\t\t\t\t\temail: value.email,\n\t\t\t\t\tpassword: value.password,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\trouter.push(\"/dashboard\");\n\t\t\t\t\t\ttoast.success(\"Sign in successful\");\n\t\t\t\t\t},\n\t\t\t\t\tonError: (error) => {\n\t\t\t\t\t\ttoast.error(error.error.message || error.error.statusText);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tvalidators: {\n\t\t\tonSubmit: z.object({\n\t\t\t\temail: z.email(\"Invalid email address\"),\n\t\t\t\tpassword: z.string().min(8, \"Password must be at least 8 characters\"),\n\t\t\t}),\n\t\t},\n\t});\n\n\treturn (\n\t\t<div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n\t\t\t<h1 className=\"mb-6 text-center text-3xl font-bold\">Welcome Back</h1>\n\n\t\t\t<form\n\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t\tform.handleSubmit();\n\t\t\t\t}}\n\t\t\t\tclassName=\"space-y-4\"\n\t\t\t>\n\t\t\t\t<div>\n\t\t\t\t\t<form.Field name=\"email\">\n\t\t\t\t\t\t{(field) => (\n\t\t\t\t\t\t\t<div className=\"space-y-2\">\n\t\t\t\t\t\t\t\t<Label htmlFor={field.name}>Email</Label>\n\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\tid={field.name}\n\t\t\t\t\t\t\t\t\tname={field.name}\n\t\t\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\t\t\t\tonBlur={field.handleBlur}\n\t\t\t\t\t\t\t\t\tonChange={(e) => field.handleChange(e.target.value)}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{field.state.meta.errors.map((error) => (\n\t\t\t\t\t\t\t\t\t<p key={error?.message} className=\"text-red-500\">\n\t\t\t\t\t\t\t\t\t\t{error?.message}\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</form.Field>\n\t\t\t\t</div>\n\n\t\t\t\t<div>\n\t\t\t\t\t<form.Field name=\"password\">\n\t\t\t\t\t\t{(field) => (\n\t\t\t\t\t\t\t<div className=\"space-y-2\">\n\t\t\t\t\t\t\t\t<Label htmlFor={field.name}>Password</Label>\n\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\tid={field.name}\n\t\t\t\t\t\t\t\t\tname={field.name}\n\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\t\t\t\tonBlur={field.handleBlur}\n\t\t\t\t\t\t\t\t\tonChange={(e) => field.handleChange(e.target.value)}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{field.state.meta.errors.map((error) => (\n\t\t\t\t\t\t\t\t\t<p key={error?.message} className=\"text-red-500\">\n\t\t\t\t\t\t\t\t\t\t{error?.message}\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</form.Field>\n\t\t\t\t</div>\n\n\t\t\t\t<form.Subscribe>\n\t\t\t\t\t{(state) => (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tclassName=\"w-full\"\n\t\t\t\t\t\t\tdisabled={!state.canSubmit || state.isSubmitting}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{state.isSubmitting ? \"Submitting...\" : \"Sign In\"}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t</form.Subscribe>\n\t\t\t</form>\n\n\t\t\t<div className=\"mt-4 text-center\">\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"link\"\n\t\t\t\t\tonClick={onSwitchToSignUp}\n\t\t\t\t\tclassName=\"text-indigo-600 hover:text-indigo-800\"\n\t\t\t\t>\n\t\t\t\t\tNeed an account? Sign Up\n\t\t\t\t</Button>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n`],\n [\"auth/better-auth/convex/web/react/next/src/components/sign-up-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\nimport { useRouter } from \"next/navigation\";\n\nexport default function SignUpForm({\n\tonSwitchToSignIn,\n}: {\n\tonSwitchToSignIn: () => void;\n}) {\n\tconst router = useRouter();\n\n\tconst form = useForm({\n\t\tdefaultValues: {\n\t\t\temail: \"\",\n\t\t\tpassword: \"\",\n\t\t\tname: \"\",\n\t\t},\n\t\tonSubmit: async ({ value }) => {\n\t\t\tawait authClient.signUp.email(\n\t\t\t\t{\n\t\t\t\t\temail: value.email,\n\t\t\t\t\tpassword: value.password,\n\t\t\t\t\tname: value.name,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tonSuccess: () => {\n\t\t\t\t\t\trouter.push(\"/dashboard\");\n\t\t\t\t\t\ttoast.success(\"Sign up successful\");\n\t\t\t\t\t},\n\t\t\t\t\tonError: (error) => {\n\t\t\t\t\t\ttoast.error(error.error.message || error.error.statusText);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tvalidators: {\n\t\t\tonSubmit: z.object({\n\t\t\t\tname: z.string().min(2, \"Name must be at least 2 characters\"),\n\t\t\t\temail: z.email(\"Invalid email address\"),\n\t\t\t\tpassword: z.string().min(8, \"Password must be at least 8 characters\"),\n\t\t\t}),\n\t\t},\n\t});\n\n\treturn (\n\t\t<div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n\t\t\t<h1 className=\"mb-6 text-center text-3xl font-bold\">Create Account</h1>\n\n\t\t\t<form\n\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t\tform.handleSubmit();\n\t\t\t\t}}\n\t\t\t\tclassName=\"space-y-4\"\n\t\t\t>\n\t\t\t\t<div>\n\t\t\t\t\t<form.Field name=\"name\">\n\t\t\t\t\t\t{(field) => (\n\t\t\t\t\t\t\t<div className=\"space-y-2\">\n\t\t\t\t\t\t\t\t<Label htmlFor={field.name}>Name</Label>\n\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\tid={field.name}\n\t\t\t\t\t\t\t\t\tname={field.name}\n\t\t\t\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\t\t\t\tonBlur={field.handleBlur}\n\t\t\t\t\t\t\t\t\tonChange={(e) => field.handleChange(e.target.value)}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{field.state.meta.errors.map((error) => (\n\t\t\t\t\t\t\t\t\t<p key={error?.message} className=\"text-red-500\">\n\t\t\t\t\t\t\t\t\t\t{error?.message}\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</form.Field>\n\t\t\t\t</div>\n\n\t\t\t\t<div>\n\t\t\t\t\t<form.Field name=\"email\">\n\t\t\t\t\t\t{(field) => (\n\t\t\t\t\t\t\t<div className=\"space-y-2\">\n\t\t\t\t\t\t\t\t<Label htmlFor={field.name}>Email</Label>\n\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\tid={field.name}\n\t\t\t\t\t\t\t\t\tname={field.name}\n\t\t\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\t\t\t\tonBlur={field.handleBlur}\n\t\t\t\t\t\t\t\t\tonChange={(e) => field.handleChange(e.target.value)}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{field.state.meta.errors.map((error) => (\n\t\t\t\t\t\t\t\t\t<p key={error?.message} className=\"text-red-500\">\n\t\t\t\t\t\t\t\t\t\t{error?.message}\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</form.Field>\n\t\t\t\t</div>\n\n\t\t\t\t<div>\n\t\t\t\t\t<form.Field name=\"password\">\n\t\t\t\t\t\t{(field) => (\n\t\t\t\t\t\t\t<div className=\"space-y-2\">\n\t\t\t\t\t\t\t\t<Label htmlFor={field.name}>Password</Label>\n\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\tid={field.name}\n\t\t\t\t\t\t\t\t\tname={field.name}\n\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\t\t\t\tonBlur={field.handleBlur}\n\t\t\t\t\t\t\t\t\tonChange={(e) => field.handleChange(e.target.value)}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{field.state.meta.errors.map((error) => (\n\t\t\t\t\t\t\t\t\t<p key={error?.message} className=\"text-red-500\">\n\t\t\t\t\t\t\t\t\t\t{error?.message}\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</form.Field>\n\t\t\t\t</div>\n\n\t\t\t\t<form.Subscribe>\n\t\t\t\t\t{(state) => (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tclassName=\"w-full\"\n\t\t\t\t\t\t\tdisabled={!state.canSubmit || state.isSubmitting}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{state.isSubmitting ? \"Submitting...\" : \"Sign Up\"}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t</form.Subscribe>\n\t\t\t</form>\n\n\t\t\t<div className=\"mt-4 text-center\">\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"link\"\n\t\t\t\t\tonClick={onSwitchToSignIn}\n\t\t\t\t\tclassName=\"text-indigo-600 hover:text-indigo-800\"\n\t\t\t\t>\n\t\t\t\t\tAlready have an account? Sign In\n\t\t\t\t</Button>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n`],\n [\"auth/clerk/convex/web/react/tanstack-start/src/routes/dashboard.tsx.hbs\", `import { SignInButton, UserButton, useUser } from \"@clerk/tanstack-react-start\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport {\n\tAuthenticated,\n\tAuthLoading,\n\tUnauthenticated,\n\tuseQuery,\n} from \"convex/react\";\n\nexport const Route = createFileRoute(\"/dashboard\")({\n\tcomponent: RouteComponent,\n});\n\nfunction RouteComponent() {\n\tconst privateData = useQuery(api.privateData.get);\n\tconst user = useUser();\n\n\treturn (\n\t\t<>\n\t\t\t<Authenticated>\n\t\t\t\t<div>\n\t\t\t\t\t<h1>Dashboard</h1>\n\t\t\t\t\t<p>Welcome {user.user?.fullName}</p>\n\t\t\t\t\t<p>privateData: {privateData?.message}</p>\n\t\t\t\t\t<UserButton />\n\t\t\t\t</div>\n\t\t\t</Authenticated>\n\t\t\t<Unauthenticated>\n\t\t\t\t<SignInButton />\n\t\t\t</Unauthenticated>\n\t\t\t<AuthLoading>\n\t\t\t\t<div>Loading...</div>\n\t\t\t</AuthLoading>\n\t\t</>\n\t);\n}\n`],\n [\"auth/better-auth/convex/web/react/tanstack-router/src/routes/dashboard.tsx.hbs\", `import SignInForm from \"@/components/sign-in-form\";\nimport SignUpForm from \"@/components/sign-up-form\";\nimport UserMenu from \"@/components/user-menu\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport {\n Authenticated,\n AuthLoading,\n Unauthenticated,\n useQuery,\n} from \"convex/react\";\nimport { useState } from \"react\";\n\nexport const Route = createFileRoute(\"/dashboard\")({\n component: RouteComponent,\n});\n\nfunction RouteComponent() {\n const [showSignIn, setShowSignIn] = useState(false);\n const privateData = useQuery(api.privateData.get);\n\n return (\n <>\n <Authenticated>\n <div>\n <h1>Dashboard</h1>\n <p>privateData: {privateData?.message}</p>\n <UserMenu />\n </div>\n </Authenticated>\n <Unauthenticated>\n {showSignIn ? (\n <SignInForm onSwitchToSignUp={() => setShowSignIn(false)} />\n ) : (\n <SignUpForm onSwitchToSignIn={() => setShowSignIn(true)} />\n )}\n </Unauthenticated>\n <AuthLoading>\n <div>Loading...</div>\n </AuthLoading>\n </>\n );\n}\n`],\n [\"auth/clerk/convex/web/react/react-router/src/routes/dashboard.tsx.hbs\", `import { SignInButton, UserButton, useUser } from \"@clerk/clerk-react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport {\n\tAuthenticated,\n\tAuthLoading,\n\tUnauthenticated,\n\tuseQuery,\n} from \"convex/react\";\n\nexport default function Dashboard() {\n\tconst privateData = useQuery(api.privateData.get);\n\tconst user = useUser();\n\n\treturn (\n\t\t<>\n\t\t\t<Authenticated>\n\t\t\t\t<div>\n\t\t\t\t\t<h1>Dashboard</h1>\n\t\t\t\t\t<p>Welcome {user.user?.fullName}</p>\n\t\t\t\t\t<p>privateData: {privateData?.message}</p>\n\t\t\t\t\t<UserButton />\n\t\t\t\t</div>\n\t\t\t</Authenticated>\n\t\t\t<Unauthenticated>\n\t\t\t\t<SignInButton />\n\t\t\t</Unauthenticated>\n\t\t\t<AuthLoading>\n\t\t\t\t<div>Loading...</div>\n\t\t\t</AuthLoading>\n\t\t</>\n\t);\n}\n`],\n [\"auth/better-auth/convex/web/react/tanstack-router/src/components/user-menu.tsx.hbs\", `import { useNavigate } from \"@tanstack/react-router\";\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { authClient } from \"@/lib/auth-client\";\nimport { useQuery } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\n\nimport { Button } from \"./ui/button\";\n\nexport default function UserMenu() {\n const navigate = useNavigate();\n const user = useQuery(api.auth.getCurrentUser)\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger render={<Button variant=\"outline\" />}>\n {user?.name}\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"bg-card\">\n <DropdownMenuGroup>\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem>{user?.email}</DropdownMenuItem>\n <DropdownMenuItem\n variant=\"destructive\"\n onClick={() => {\n authClient.signOut({\n fetchOptions: {\n onSuccess: () => {\n navigate({\n to: \"/dashboard\",\n });\n },\n },\n });\n }}\n >\n Sign Out\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n`],\n [\"auth/better-auth/convex/web/react/tanstack-router/src/components/sign-in-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { useNavigate } from \"@tanstack/react-router\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\n\nexport default function SignInForm({\n onSwitchToSignUp,\n}: {\n onSwitchToSignUp: () => void;\n}) {\n const navigate = useNavigate({\n from: \"/\",\n });\n\n const form = useForm({\n defaultValues: {\n email: \"\",\n password: \"\",\n },\n onSubmit: async ({ value }) => {\n await authClient.signIn.email(\n {\n email: value.email,\n password: value.password,\n },\n {\n onSuccess: () => {\n navigate({\n to: \"/dashboard\",\n });\n toast.success(\"Sign in successful\");\n },\n onError: (error) => {\n toast.error(error.error.message || error.error.statusText);\n },\n },\n );\n },\n validators: {\n onSubmit: z.object({\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n });\n\n return (\n <div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 className=\"mb-6 text-center text-3xl font-bold\">Welcome Back</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n className=\"space-y-4\"\n >\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Email</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"email\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={!state.canSubmit || state.isSubmitting}\n >\n {state.isSubmitting ? \"Submitting...\" : \"Sign In\"}\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n <div className=\"mt-4 text-center\">\n <Button\n variant=\"link\"\n onClick={onSwitchToSignUp}\n className=\"text-indigo-600 hover:text-indigo-800\"\n >\n Need an account? Sign Up\n </Button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/better-auth/convex/web/react/tanstack-router/src/components/sign-up-form.tsx.hbs\", `import { authClient } from \"@/lib/auth-client\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { useNavigate } from \"@tanstack/react-router\";\nimport { toast } from \"sonner\";\nimport z from \"zod\";\nimport { Button } from \"./ui/button\";\nimport { Input } from \"./ui/input\";\nimport { Label } from \"./ui/label\";\n\nexport default function SignUpForm({\n onSwitchToSignIn,\n}: {\n onSwitchToSignIn: () => void;\n}) {\n const navigate = useNavigate({\n from: \"/\",\n });\n\n const form = useForm({\n defaultValues: {\n email: \"\",\n password: \"\",\n name: \"\",\n },\n onSubmit: async ({ value }) => {\n await authClient.signUp.email(\n {\n email: value.email,\n password: value.password,\n name: value.name,\n },\n {\n onSuccess: () => {\n navigate({\n to: \"/dashboard\",\n });\n toast.success(\"Sign up successful\");\n },\n onError: (error) => {\n toast.error(error.error.message || error.error.statusText);\n },\n },\n );\n },\n validators: {\n onSubmit: z.object({\n name: z.string().min(2, \"Name must be at least 2 characters\"),\n email: z.email(\"Invalid email address\"),\n password: z.string().min(8, \"Password must be at least 8 characters\"),\n }),\n },\n });\n\n return (\n <div className=\"mx-auto w-full mt-10 max-w-md p-6\">\n <h1 className=\"mb-6 text-center text-3xl font-bold\">Create Account</h1>\n\n <form\n onSubmit={(e) => {\n e.preventDefault();\n e.stopPropagation();\n form.handleSubmit();\n }}\n className=\"space-y-4\"\n >\n <div>\n <form.Field name=\"name\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Name</Label>\n <Input\n id={field.name}\n name={field.name}\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"email\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Email</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"email\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <div>\n <form.Field name=\"password\">\n {(field) => (\n <div className=\"space-y-2\">\n <Label htmlFor={field.name}>Password</Label>\n <Input\n id={field.name}\n name={field.name}\n type=\"password\"\n value={field.state.value}\n onBlur={field.handleBlur}\n onChange={(e) => field.handleChange(e.target.value)}\n />\n {field.state.meta.errors.map((error) => (\n <p key={error?.message} className=\"text-red-500\">\n {error?.message}\n </p>\n ))}\n </div>\n )}\n </form.Field>\n </div>\n\n <form.Subscribe>\n {(state) => (\n <Button\n type=\"submit\"\n className=\"w-full\"\n disabled={!state.canSubmit || state.isSubmitting}\n >\n {state.isSubmitting ? \"Submitting...\" : \"Sign Up\"}\n </Button>\n )}\n </form.Subscribe>\n </form>\n\n <div className=\"mt-4 text-center\">\n <Button\n variant=\"link\"\n onClick={onSwitchToSignIn}\n className=\"text-indigo-600 hover:text-indigo-800\"\n >\n Already have an account? Sign In\n </Button>\n </div>\n </div>\n );\n}\n`],\n [\"auth/better-auth/convex/web/react/tanstack-router/src/lib/auth-client.ts.hbs\", `import { createAuthClient } from \"better-auth/react\";\nimport {\n\tconvexClient,\n\tcrossDomainClient,\n} from \"@convex-dev/better-auth/client/plugins\";\nimport { env } from \"@{{projectName}}/env/web\";\n\nexport const authClient = createAuthClient({\n\tbaseURL: env.VITE_CONVEX_SITE_URL,\n\tplugins: [convexClient(), crossDomainClient()],\n});`],\n [\"auth/clerk/convex/web/react/tanstack-router/src/routes/dashboard.tsx.hbs\", `import { SignInButton, UserButton, useUser } from \"@clerk/clerk-react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport {\n\tAuthenticated,\n\tAuthLoading,\n\tUnauthenticated,\n\tuseQuery,\n} from \"convex/react\";\n\nexport const Route = createFileRoute(\"/dashboard\")({\n\tcomponent: RouteComponent,\n});\n\nfunction RouteComponent() {\n\tconst privateData = useQuery(api.privateData.get);\n\tconst user = useUser()\n\n\treturn (\n\t\t<>\n\t\t\t<Authenticated>\n\t\t\t\t<div>\n\t\t\t\t\t<h1>Dashboard</h1>\n\t\t\t\t\t<p>Welcome {user.user?.fullName}</p>\n\t\t\t\t\t<p>privateData: {privateData?.message}</p>\n\t\t\t\t\t<UserButton />\n\t\t\t\t</div>\n\t\t\t</Authenticated>\n\t\t\t<Unauthenticated>\n\t\t\t\t<SignInButton />\n\t\t\t</Unauthenticated>\n\t\t\t<AuthLoading>\n\t\t\t\t<div>Loading...</div>\n\t\t\t</AuthLoading>\n\t\t</>\n\t);\n}\n`],\n [\"auth/better-auth/web/react/next/src/app/dashboard/dashboard.tsx.hbs\", `\"use client\";\n{{#if (eq payments \"polar\")}}\nimport { Button } from \"@/components/ui/button\";\n{{/if}}\nimport { authClient } from \"@/lib/auth-client\";\n{{#if (eq api \"orpc\")}}\nimport { useQuery } from \"@tanstack/react-query\";\nimport { orpc } from \"@/utils/orpc\";\n{{/if}}\n{{#if (eq api \"trpc\")}}\nimport { useQuery } from \"@tanstack/react-query\";\nimport { trpc } from \"@/utils/trpc\";\n{{/if}}\n\nexport default function Dashboard({\n\t{{#if (eq payments \"polar\")}}\n\tcustomerState,\n\t{{/if}}\n\tsession\n}: {\n\t{{#if (eq payments \"polar\")}}\n\tcustomerState: ReturnType<typeof authClient.customer.state>;\n\t{{/if}}\n\tsession: typeof authClient.$Infer.Session;\n}) {\n\t{{#if (eq api \"orpc\")}}\n\tconst privateData = useQuery(orpc.privateData.queryOptions());\n\t{{/if}}\n\t{{#if (eq api \"trpc\")}}\n\tconst privateData = useQuery(trpc.privateData.queryOptions());\n\t{{/if}}\n\n\t{{#if (eq payments \"polar\")}}\n\tconst hasProSubscription = customerState?.activeSubscriptions?.length! > 0;\n\tconsole.log(\"Active subscriptions:\", customerState?.activeSubscriptions);\n\t{{/if}}\n\n\treturn (\n\t\t<>\n\t\t\t{{#if (eq api \"orpc\")}}\n\t\t\t<p>API: {privateData.data?.message}</p>\n\t\t\t{{/if}}\n\t\t\t{{#if (eq api \"trpc\")}}\n\t\t\t<p>API: {privateData.data?.message}</p>\n\t\t\t{{/if}}\n\t\t\t{{#if (eq payments \"polar\")}}\n\t\t\t<p>Plan: {hasProSubscription ? \"Pro\" : \"Free\"}</p>\n\t\t\t{hasProSubscription ? (\n\t\t\t\t<Button onClick={async () => await authClient.customer.portal()}>\n\t\t\t\t\tManage Subscription\n\t\t\t\t</Button>\n\t\t\t) : (\n\t\t\t\t<Button onClick={async () => await authClient.checkout({ slug: \"pro\" })}>\n\t\t\t\t\tUpgrade to Pro\n\t\t\t\t</Button>\n\t\t\t)}\n\t\t\t{{/if}}\n\t\t</>\n\t);\n}\n`],\n [\"auth/better-auth/web/react/next/src/app/dashboard/page.tsx.hbs\", `import { redirect } from \"next/navigation\";\nimport Dashboard from \"./dashboard\";\nimport { headers } from \"next/headers\";\n{{#if (eq backend \"self\")}}\nimport { auth } from \"@{{projectName}}/auth\";\n{{/if}}\nimport { authClient } from \"@/lib/auth-client\";\n\nexport default async function DashboardPage() {\n\t{{#if (eq backend \"self\")}}\n\tconst session = await auth.api.getSession({\n\t\theaders: await headers(),\n\t});\n\t{{else}}\n\tconst session = await authClient.getSession({\n\t\tfetchOptions: {\n\t\t\theaders: await headers(),\n\t\t\tthrow: true\n\t\t}\n\t});\n\t{{/if}}\n\n\tif (!session?.user) {\n\t\tredirect(\"/login\");\n\t}\n\n\t{{#if (eq payments \"polar\")}}\n\tconst { data: customerState } = await authClient.customer.state({\n\t\tfetchOptions: {\n\t\t\theaders: await headers(),\n\t\t},\n\t});\n\t{{/if}}\n\n\treturn (\n\t\t<div>\n\t\t\t<h1>Dashboard</h1>\n\t\t\t<p>Welcome {session.user.name}</p>\n\t\t\t<Dashboard session={session} {{#if (eq payments \"polar\")}}customerState={customerState}{{/if}} />\n\t\t</div>\n\t);\n}\n`],\n [\"auth/better-auth/web/react/next/src/app/login/page.tsx.hbs\", `\"use client\"\n\nimport SignInForm from \"@/components/sign-in-form\";\nimport SignUpForm from \"@/components/sign-up-form\";\nimport { useState } from \"react\";\n\n\nexport default function LoginPage() {\n const [showSignIn, setShowSignIn] = useState(false);\n\n return showSignIn ? (\n <SignInForm onSwitchToSignUp={() => setShowSignIn(false)} />\n ) : (\n <SignUpForm onSwitchToSignIn={() => setShowSignIn(true)} />\n );\n}\n`],\n [\"auth/nextauth/server/db/prisma/sqlite/prisma/schema/auth.prisma.hbs\", `model User {\n id String @id @default(cuid())\n name String?\n email String? @unique\n emailVerified DateTime?\n image String?\n accounts Account[]\n sessions Session[]\n}\n\nmodel Account {\n userId String\n type String\n provider String\n providerAccountId String\n refresh_token String?\n access_token String?\n expires_at Int?\n token_type String?\n scope String?\n id_token String?\n session_state String?\n\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@id([provider, providerAccountId])\n}\n\nmodel Session {\n sessionToken String @unique\n userId String\n expires DateTime\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel VerificationToken {\n identifier String\n token String @unique\n expires DateTime\n\n @@id([identifier, token])\n}\n`],\n [\"auth/nextauth/server/db/prisma/postgres/prisma/schema/auth.prisma.hbs\", `model User {\n id String @id @default(cuid())\n name String?\n email String? @unique\n emailVerified DateTime?\n image String?\n accounts Account[]\n sessions Session[]\n}\n\nmodel Account {\n userId String\n type String\n provider String\n providerAccountId String\n refresh_token String?\n access_token String?\n expires_at Int?\n token_type String?\n scope String?\n id_token String?\n session_state String?\n\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@id([provider, providerAccountId])\n}\n\nmodel Session {\n sessionToken String @unique\n userId String\n expires DateTime\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel VerificationToken {\n identifier String\n token String @unique\n expires DateTime\n\n @@id([identifier, token])\n}\n`],\n [\"auth/nextauth/server/db/drizzle/postgres/src/schema/auth.ts.hbs\", `import { pgTable, text, timestamp, primaryKey, integer } from \"drizzle-orm/pg-core\";\n\nexport const users = pgTable(\"user\", {\n id: text(\"id\")\n .primaryKey()\n .$defaultFn(() => crypto.randomUUID()),\n name: text(\"name\"),\n email: text(\"email\").unique(),\n emailVerified: timestamp(\"emailVerified\", { mode: \"date\" }),\n image: text(\"image\"),\n});\n\nexport const accounts = pgTable(\n \"account\",\n {\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n type: text(\"type\").notNull(),\n provider: text(\"provider\").notNull(),\n providerAccountId: text(\"providerAccountId\").notNull(),\n refresh_token: text(\"refresh_token\"),\n access_token: text(\"access_token\"),\n expires_at: integer(\"expires_at\"),\n token_type: text(\"token_type\"),\n scope: text(\"scope\"),\n id_token: text(\"id_token\"),\n session_state: text(\"session_state\"),\n },\n (account) => ({\n compoundKey: primaryKey({\n columns: [account.provider, account.providerAccountId],\n }),\n })\n);\n\nexport const sessions = pgTable(\"session\", {\n sessionToken: text(\"sessionToken\").primaryKey(),\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n expires: timestamp(\"expires\", { mode: \"date\" }).notNull(),\n});\n\nexport const verificationTokens = pgTable(\n \"verificationToken\",\n {\n identifier: text(\"identifier\").notNull(),\n token: text(\"token\").notNull(),\n expires: timestamp(\"expires\", { mode: \"date\" }).notNull(),\n },\n (verificationToken) => ({\n compositePk: primaryKey({\n columns: [verificationToken.identifier, verificationToken.token],\n }),\n })\n);\n`],\n [\"auth/nextauth/server/db/drizzle/sqlite/src/schema/auth.ts.hbs\", `import { sqliteTable, text, integer, primaryKey } from \"drizzle-orm/sqlite-core\";\n\nexport const users = sqliteTable(\"user\", {\n id: text(\"id\")\n .primaryKey()\n .$defaultFn(() => crypto.randomUUID()),\n name: text(\"name\"),\n email: text(\"email\").unique(),\n emailVerified: integer(\"emailVerified\", { mode: \"timestamp\" }),\n image: text(\"image\"),\n});\n\nexport const accounts = sqliteTable(\n \"account\",\n {\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n type: text(\"type\").notNull(),\n provider: text(\"provider\").notNull(),\n providerAccountId: text(\"providerAccountId\").notNull(),\n refresh_token: text(\"refresh_token\"),\n access_token: text(\"access_token\"),\n expires_at: integer(\"expires_at\"),\n token_type: text(\"token_type\"),\n scope: text(\"scope\"),\n id_token: text(\"id_token\"),\n session_state: text(\"session_state\"),\n },\n (account) => ({\n compoundKey: primaryKey({\n columns: [account.provider, account.providerAccountId],\n }),\n })\n);\n\nexport const sessions = sqliteTable(\"session\", {\n sessionToken: text(\"sessionToken\").primaryKey(),\n userId: text(\"userId\")\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n expires: integer(\"expires\", { mode: \"timestamp\" }).notNull(),\n});\n\nexport const verificationTokens = sqliteTable(\n \"verificationToken\",\n {\n identifier: text(\"identifier\").notNull(),\n token: text(\"token\").notNull(),\n expires: integer(\"expires\", { mode: \"timestamp\" }).notNull(),\n },\n (verificationToken) => ({\n compositePk: primaryKey({\n columns: [verificationToken.identifier, verificationToken.token],\n }),\n })\n);\n`],\n [\"auth/nextauth/server/db/drizzle/mysql/src/schema/auth.ts.hbs\", `import { mysqlTable, varchar, text, timestamp, int, primaryKey } from \"drizzle-orm/mysql-core\";\n\nexport const users = mysqlTable(\"user\", {\n id: varchar(\"id\", { length: 255 })\n .primaryKey()\n .$defaultFn(() => crypto.randomUUID()),\n name: varchar(\"name\", { length: 255 }),\n email: varchar(\"email\", { length: 255 }).unique(),\n emailVerified: timestamp(\"emailVerified\", { mode: \"date\", fsp: 3 }),\n image: varchar(\"image\", { length: 255 }),\n});\n\nexport const accounts = mysqlTable(\n \"account\",\n {\n userId: varchar(\"userId\", { length: 255 })\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n type: varchar(\"type\", { length: 255 }).notNull(),\n provider: varchar(\"provider\", { length: 255 }).notNull(),\n providerAccountId: varchar(\"providerAccountId\", { length: 255 }).notNull(),\n refresh_token: text(\"refresh_token\"),\n access_token: text(\"access_token\"),\n expires_at: int(\"expires_at\"),\n token_type: varchar(\"token_type\", { length: 255 }),\n scope: varchar(\"scope\", { length: 255 }),\n id_token: text(\"id_token\"),\n session_state: varchar(\"session_state\", { length: 255 }),\n },\n (account) => ({\n compoundKey: primaryKey({\n columns: [account.provider, account.providerAccountId],\n }),\n })\n);\n\nexport const sessions = mysqlTable(\"session\", {\n sessionToken: varchar(\"sessionToken\", { length: 255 }).primaryKey(),\n userId: varchar(\"userId\", { length: 255 })\n .notNull()\n .references(() => users.id, { onDelete: \"cascade\" }),\n expires: timestamp(\"expires\", { mode: \"date\" }).notNull(),\n});\n\nexport const verificationTokens = mysqlTable(\n \"verificationToken\",\n {\n identifier: varchar(\"identifier\", { length: 255 }).notNull(),\n token: varchar(\"token\", { length: 255 }).notNull(),\n expires: timestamp(\"expires\", { mode: \"date\" }).notNull(),\n },\n (verificationToken) => ({\n compositePk: primaryKey({\n columns: [verificationToken.identifier, verificationToken.token],\n }),\n })\n);\n`],\n [\"auth/better-auth/fullstack/tanstack-start/src/routes/api/auth/$.ts.hbs\", `import { auth } from '@{{projectName}}/auth'\nimport { createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/api/auth/$')({\n server: {\n handlers: {\n GET: ({ request }) => {\n return auth.handler(request)\n },\n POST: ({ request }) => {\n return auth.handler(request)\n },\n },\n },\n})\n`],\n [\"auth/better-auth/server/db/mongoose/mongodb/src/models/auth.model.ts.hbs\", `import mongoose from 'mongoose';\n\nconst { Schema, model } = mongoose;\n\nconst userSchema = new Schema(\n {\n _id: { type: String },\n name: { type: String, required: true },\n email: { type: String, required: true, unique: true },\n emailVerified: { type: Boolean, required: true },\n image: { type: String },\n createdAt: { type: Date, required: true },\n updatedAt: { type: Date, required: true },\n },\n { collection: 'user' }\n);\n\nconst sessionSchema = new Schema(\n {\n _id: { type: String },\n expiresAt: { type: Date, required: true },\n token: { type: String, required: true, unique: true },\n createdAt: { type: Date, required: true },\n updatedAt: { type: Date, required: true },\n ipAddress: { type: String },\n userAgent: { type: String },\n userId: { type: String, ref: 'User', required: true },\n },\n { collection: 'session' }\n);\n\nconst accountSchema = new Schema(\n {\n _id: { type: String },\n accountId: { type: String, required: true },\n providerId: { type: String, required: true },\n userId: { type: String, ref: 'User', required: true },\n accessToken: { type: String },\n refreshToken: { type: String },\n idToken: { type: String },\n accessTokenExpiresAt: { type: Date },\n refreshTokenExpiresAt: { type: Date },\n scope: { type: String },\n password: { type: String },\n createdAt: { type: Date, required: true },\n updatedAt: { type: Date, required: true },\n },\n { collection: 'account' }\n);\n\nconst verificationSchema = new Schema(\n {\n _id: { type: String },\n identifier: { type: String, required: true },\n value: { type: String, required: true },\n expiresAt: { type: Date, required: true },\n createdAt: { type: Date },\n updatedAt: { type: Date },\n },\n { collection: 'verification' }\n);\n\nconst User = model('User', userSchema);\nconst Session = model('Session', sessionSchema);\nconst Account = model('Account', accountSchema);\nconst Verification = model('Verification', verificationSchema);\n\nexport { User, Session, Account, Verification };\n`],\n [\"auth/better-auth/server/db/drizzle/postgres/src/schema/auth.ts.hbs\", `import { relations } from \"drizzle-orm\";\nimport { pgTable, text, timestamp, boolean, index } from \"drizzle-orm/pg-core\";\n\nexport const user = pgTable(\"user\", {\n id: text(\"id\").primaryKey(),\n name: text(\"name\").notNull(),\n email: text(\"email\").notNull().unique(),\n emailVerified: boolean(\"email_verified\").default(false).notNull(),\n image: text(\"image\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\")\n .defaultNow()\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n});\n\nexport const session = pgTable(\n \"session\",\n {\n id: text(\"id\").primaryKey(),\n expiresAt: timestamp(\"expires_at\").notNull(),\n token: text(\"token\").notNull().unique(),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\")\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n ipAddress: text(\"ip_address\"),\n userAgent: text(\"user_agent\"),\n userId: text(\"user_id\")\n .notNull()\n .references(() => user.id, { onDelete: \"cascade\" }),\n },\n (table) => [index(\"session_userId_idx\").on(table.userId)],\n);\n\nexport const account = pgTable(\n \"account\",\n {\n id: text(\"id\").primaryKey(),\n accountId: text(\"account_id\").notNull(),\n providerId: text(\"provider_id\").notNull(),\n userId: text(\"user_id\")\n .notNull()\n .references(() => user.id, { onDelete: \"cascade\" }),\n accessToken: text(\"access_token\"),\n refreshToken: text(\"refresh_token\"),\n idToken: text(\"id_token\"),\n accessTokenExpiresAt: timestamp(\"access_token_expires_at\"),\n refreshTokenExpiresAt: timestamp(\"refresh_token_expires_at\"),\n scope: text(\"scope\"),\n password: text(\"password\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\")\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n },\n (table) => [index(\"account_userId_idx\").on(table.userId)],\n);\n\nexport const verification = pgTable(\n \"verification\",\n {\n id: text(\"id\").primaryKey(),\n identifier: text(\"identifier\").notNull(),\n value: text(\"value\").notNull(),\n expiresAt: timestamp(\"expires_at\").notNull(),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\")\n .defaultNow()\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n },\n (table) => [index(\"verification_identifier_idx\").on(table.identifier)],\n);\n\nexport const userRelations = relations(user, ({ many }) => ({\n sessions: many(session),\n accounts: many(account),\n}));\n\nexport const sessionRelations = relations(session, ({ one }) => ({\n user: one(user, {\n fields: [session.userId],\n references: [user.id],\n }),\n}));\n\nexport const accountRelations = relations(account, ({ one }) => ({\n user: one(user, {\n fields: [account.userId],\n references: [user.id],\n }),\n}));\n`],\n [\"auth/nextauth/server/db/prisma/mysql/prisma/schema/auth.prisma.hbs\", `model User {\n id String @id @default(cuid())\n name String?\n email String? @unique\n emailVerified DateTime?\n image String?\n accounts Account[]\n sessions Session[]\n}\n\nmodel Account {\n userId String\n type String\n provider String\n providerAccountId String\n refresh_token String? @db.Text\n access_token String? @db.Text\n expires_at Int?\n token_type String?\n scope String?\n id_token String? @db.Text\n session_state String?\n\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@id([provider, providerAccountId])\n}\n\nmodel Session {\n sessionToken String @unique\n userId String\n expires DateTime\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel VerificationToken {\n identifier String\n token String @unique\n expires DateTime\n\n @@id([identifier, token])\n}\n`],\n [\"auth/better-auth/server/db/prisma/mongodb/prisma/schema/auth.prisma.hbs\", `model User {\n id String @id @map(\"_id\")\n name String\n email String\n emailVerified Boolean @default(false)\n image String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n sessions Session[]\n accounts Account[]\n\n @@unique([email])\n @@map(\"user\")\n}\n\nmodel Session {\n id String @id @map(\"_id\")\n expiresAt DateTime\n token String\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n ipAddress String?\n userAgent String?\n userId String\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([token])\n @@index([userId])\n @@map(\"session\")\n}\n\nmodel Account {\n id String @id @map(\"_id\")\n accountId String\n providerId String\n userId String\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n accessToken String?\n refreshToken String?\n idToken String?\n accessTokenExpiresAt DateTime?\n refreshTokenExpiresAt DateTime?\n scope String?\n password String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([userId])\n @@map(\"account\")\n}\n\nmodel Verification {\n id String @id @map(\"_id\")\n identifier String\n value String\n expiresAt DateTime\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([identifier])\n @@map(\"verification\")\n}\n`],\n [\"auth/better-auth/server/db/prisma/mysql/prisma/schema/auth.prisma.hbs\", `model User {\n id String @id\n name String @db.Text\n email String\n emailVerified Boolean @default(false)\n image String? @db.Text\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n sessions Session[]\n accounts Account[]\n\n @@unique([email])\n @@map(\"user\")\n}\n\nmodel Session {\n id String @id\n expiresAt DateTime\n token String\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n ipAddress String? @db.Text\n userAgent String? @db.Text\n userId String\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([token])\n @@index([userId(length: 191)])\n @@map(\"session\")\n}\n\nmodel Account {\n id String @id\n accountId String @db.Text\n providerId String @db.Text\n userId String\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n accessToken String? @db.Text\n refreshToken String? @db.Text\n idToken String? @db.Text\n accessTokenExpiresAt DateTime?\n refreshTokenExpiresAt DateTime?\n scope String? @db.Text\n password String? @db.Text\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([userId(length: 191)])\n @@map(\"account\")\n}\n\nmodel Verification {\n id String @id\n identifier String @db.Text\n value String @db.Text\n expiresAt DateTime\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([identifier(length: 191)])\n @@map(\"verification\")\n}\n`],\n [\"auth/better-auth/server/db/prisma/sqlite/prisma/schema/auth.prisma.hbs\", `model User {\n id String @id\n name String\n email String\n emailVerified Boolean @default(false)\n image String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n sessions Session[]\n accounts Account[]\n\n @@unique([email])\n @@map(\"user\")\n}\n\nmodel Session {\n id String @id\n expiresAt DateTime\n token String\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n ipAddress String?\n userAgent String?\n userId String\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([token])\n @@index([userId])\n @@map(\"session\")\n}\n\nmodel Account {\n id String @id\n accountId String\n providerId String\n userId String\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n accessToken String?\n refreshToken String?\n idToken String?\n accessTokenExpiresAt DateTime?\n refreshTokenExpiresAt DateTime?\n scope String?\n password String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([userId])\n @@map(\"account\")\n}\n\nmodel Verification {\n id String @id\n identifier String\n value String\n expiresAt DateTime\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([identifier])\n @@map(\"verification\")\n}\n`],\n [\"auth/better-auth/server/db/drizzle/sqlite/src/schema/auth.ts.hbs\", `import { relations, sql } from \"drizzle-orm\";\nimport { sqliteTable, text, integer, index } from \"drizzle-orm/sqlite-core\";\n\nexport const user = sqliteTable(\"user\", {\n id: text(\"id\").primaryKey(),\n name: text(\"name\").notNull(),\n email: text(\"email\").notNull().unique(),\n emailVerified: integer(\"email_verified\", { mode: \"boolean\" })\n .default(false)\n .notNull(),\n image: text(\"image\"),\n createdAt: integer(\"created_at\", { mode: \"timestamp_ms\" })\n .default(sql\\`(cast(unixepoch('subsecond') * 1000 as integer))\\`)\n .notNull(),\n updatedAt: integer(\"updated_at\", { mode: \"timestamp_ms\" })\n .default(sql\\`(cast(unixepoch('subsecond') * 1000 as integer))\\`)\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n});\n\nexport const session = sqliteTable(\n \"session\",\n {\n id: text(\"id\").primaryKey(),\n expiresAt: integer(\"expires_at\", { mode: \"timestamp_ms\" }).notNull(),\n token: text(\"token\").notNull().unique(),\n createdAt: integer(\"created_at\", { mode: \"timestamp_ms\" })\n .default(sql\\`(cast(unixepoch('subsecond') * 1000 as integer))\\`)\n .notNull(),\n updatedAt: integer(\"updated_at\", { mode: \"timestamp_ms\" })\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n ipAddress: text(\"ip_address\"),\n userAgent: text(\"user_agent\"),\n userId: text(\"user_id\")\n .notNull()\n .references(() => user.id, { onDelete: \"cascade\" }),\n },\n (table) => [index(\"session_userId_idx\").on(table.userId)],\n);\n\nexport const account = sqliteTable(\n \"account\",\n {\n id: text(\"id\").primaryKey(),\n accountId: text(\"account_id\").notNull(),\n providerId: text(\"provider_id\").notNull(),\n userId: text(\"user_id\")\n .notNull()\n .references(() => user.id, { onDelete: \"cascade\" }),\n accessToken: text(\"access_token\"),\n refreshToken: text(\"refresh_token\"),\n idToken: text(\"id_token\"),\n accessTokenExpiresAt: integer(\"access_token_expires_at\", {\n mode: \"timestamp_ms\",\n }),\n refreshTokenExpiresAt: integer(\"refresh_token_expires_at\", {\n mode: \"timestamp_ms\",\n }),\n scope: text(\"scope\"),\n password: text(\"password\"),\n createdAt: integer(\"created_at\", { mode: \"timestamp_ms\" })\n .default(sql\\`(cast(unixepoch('subsecond') * 1000 as integer))\\`)\n .notNull(),\n updatedAt: integer(\"updated_at\", { mode: \"timestamp_ms\" })\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n },\n (table) => [index(\"account_userId_idx\").on(table.userId)],\n);\n\nexport const verification = sqliteTable(\n \"verification\",\n {\n id: text(\"id\").primaryKey(),\n identifier: text(\"identifier\").notNull(),\n value: text(\"value\").notNull(),\n expiresAt: integer(\"expires_at\", { mode: \"timestamp_ms\" }).notNull(),\n createdAt: integer(\"created_at\", { mode: \"timestamp_ms\" })\n .default(sql\\`(cast(unixepoch('subsecond') * 1000 as integer))\\`)\n .notNull(),\n updatedAt: integer(\"updated_at\", { mode: \"timestamp_ms\" })\n .default(sql\\`(cast(unixepoch('subsecond') * 1000 as integer))\\`)\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n },\n (table) => [index(\"verification_identifier_idx\").on(table.identifier)],\n);\n\nexport const userRelations = relations(user, ({ many }) => ({\n sessions: many(session),\n accounts: many(account),\n}));\n\nexport const sessionRelations = relations(session, ({ one }) => ({\n user: one(user, {\n fields: [session.userId],\n references: [user.id],\n }),\n}));\n\nexport const accountRelations = relations(account, ({ one }) => ({\n user: one(user, {\n fields: [account.userId],\n references: [user.id],\n }),\n}));\n`],\n [\"auth/better-auth/server/db/prisma/postgres/prisma/schema/auth.prisma.hbs\", `model User {\n id String @id\n name String\n email String\n emailVerified Boolean @default(false)\n image String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n sessions Session[]\n accounts Account[]\n\n @@unique([email])\n @@map(\"user\")\n}\n\nmodel Session {\n id String @id\n expiresAt DateTime\n token String\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n ipAddress String?\n userAgent String?\n userId String\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([token])\n @@index([userId])\n @@map(\"session\")\n}\n\nmodel Account {\n id String @id\n accountId String\n providerId String\n userId String\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n accessToken String?\n refreshToken String?\n idToken String?\n accessTokenExpiresAt DateTime?\n refreshTokenExpiresAt DateTime?\n scope String?\n password String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([userId])\n @@map(\"account\")\n}\n\nmodel Verification {\n id String @id\n identifier String\n value String\n expiresAt DateTime\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([identifier])\n @@map(\"verification\")\n}\n`],\n [\"auth/nextauth/web/react/next/src/app/login/page.tsx.hbs\", `\"use client\";\n\nimport { useState } from \"react\";\nimport SignInForm from \"@/components/sign-in-form\";\nimport SignUpForm from \"@/components/sign-up-form\";\n\nexport default function LoginPage() {\n const [isSignIn, setIsSignIn] = useState(true);\n\n return (\n <div className=\"min-h-screen flex items-center justify-center\">\n {isSignIn ? (\n <SignInForm onSwitchToSignUp={() => setIsSignIn(false)} />\n ) : (\n <SignUpForm onSwitchToSignIn={() => setIsSignIn(true)} />\n )}\n </div>\n );\n}\n`],\n [\"auth/nextauth/web/react/next/src/app/dashboard/dashboard.tsx.hbs\", `\"use client\";\n\nimport type { User } from \"next-auth\";\nimport UserMenu from \"@/components/user-menu\";\nimport { AuthProvider } from \"@/components/providers\";\n\nexport default function Dashboard({ user }: { user: User }) {\n return (\n <AuthProvider>\n <div className=\"min-h-screen bg-background\">\n <header className=\"border-b\">\n <div className=\"container mx-auto px-4 py-4 flex justify-between items-center\">\n <h1 className=\"text-xl font-bold\">Dashboard</h1>\n <UserMenu />\n </div>\n </header>\n <main className=\"container mx-auto px-4 py-8\">\n <div className=\"max-w-2xl mx-auto\">\n <h2 className=\"text-2xl font-bold mb-4\">\n Welcome, {user.name || user.email}!\n </h2>\n <p className=\"text-muted-foreground mb-6\">\n You are now signed in with Auth.js (NextAuth).\n </p>\n <div className=\"bg-card border rounded-lg p-6\">\n <h3 className=\"font-semibold mb-2\">Your Profile</h3>\n <dl className=\"space-y-2\">\n {user.name && (\n <div>\n <dt className=\"text-sm text-muted-foreground\">Name</dt>\n <dd className=\"font-medium\">{user.name}</dd>\n </div>\n )}\n <div>\n <dt className=\"text-sm text-muted-foreground\">Email</dt>\n <dd className=\"font-medium\">{user.email}</dd>\n </div>\n <div>\n <dt className=\"text-sm text-muted-foreground\">User ID</dt>\n <dd className=\"font-mono text-sm\">{user.id}</dd>\n </div>\n </dl>\n </div>\n </div>\n </main>\n </div>\n </AuthProvider>\n );\n}\n`],\n [\"auth/nextauth/web/react/next/src/app/dashboard/page.tsx.hbs\", `import { auth } from \"@/lib/auth\";\nimport { redirect } from \"next/navigation\";\nimport Dashboard from \"./dashboard\";\n\nexport default async function DashboardPage() {\n const session = await auth();\n\n if (!session?.user) {\n redirect(\"/login\");\n }\n\n return <Dashboard user={session.user} />;\n}\n`],\n [\"auth/better-auth/server/db/drizzle/mysql/src/schema/auth.ts.hbs\", `import { relations } from \"drizzle-orm\";\nimport {\n mysqlTable,\n varchar,\n text,\n timestamp,\n boolean,\n index,\n} from \"drizzle-orm/mysql-core\";\n\nexport const user = mysqlTable(\"user\", {\n id: varchar(\"id\", { length: 36 }).primaryKey(),\n name: varchar(\"name\", { length: 255 }).notNull(),\n email: varchar(\"email\", { length: 255 }).notNull().unique(),\n emailVerified: boolean(\"email_verified\").default(false).notNull(),\n image: text(\"image\"),\n createdAt: timestamp(\"created_at\", { fsp: 3 }).defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\", { fsp: 3 })\n .defaultNow()\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n});\n\nexport const session = mysqlTable(\n \"session\",\n {\n id: varchar(\"id\", { length: 36 }).primaryKey(),\n expiresAt: timestamp(\"expires_at\", { fsp: 3 }).notNull(),\n token: varchar(\"token\", { length: 255 }).notNull().unique(),\n createdAt: timestamp(\"created_at\", { fsp: 3 }).defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\", { fsp: 3 })\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n ipAddress: text(\"ip_address\"),\n userAgent: text(\"user_agent\"),\n userId: varchar(\"user_id\", { length: 36 })\n .notNull()\n .references(() => user.id, { onDelete: \"cascade\" }),\n },\n (table) => [index(\"session_userId_idx\").on(table.userId)],\n);\n\nexport const account = mysqlTable(\n \"account\",\n {\n id: varchar(\"id\", { length: 36 }).primaryKey(),\n accountId: text(\"account_id\").notNull(),\n providerId: text(\"provider_id\").notNull(),\n userId: varchar(\"user_id\", { length: 36 })\n .notNull()\n .references(() => user.id, { onDelete: \"cascade\" }),\n accessToken: text(\"access_token\"),\n refreshToken: text(\"refresh_token\"),\n idToken: text(\"id_token\"),\n accessTokenExpiresAt: timestamp(\"access_token_expires_at\", { fsp: 3 }),\n refreshTokenExpiresAt: timestamp(\"refresh_token_expires_at\", { fsp: 3 }),\n scope: text(\"scope\"),\n password: text(\"password\"),\n createdAt: timestamp(\"created_at\", { fsp: 3 }).defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\", { fsp: 3 })\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n },\n (table) => [index(\"account_userId_idx\").on(table.userId)],\n);\n\nexport const verification = mysqlTable(\n \"verification\",\n {\n id: varchar(\"id\", { length: 36 }).primaryKey(),\n identifier: varchar(\"identifier\", { length: 255 }).notNull(),\n value: text(\"value\").notNull(),\n expiresAt: timestamp(\"expires_at\", { fsp: 3 }).notNull(),\n createdAt: timestamp(\"created_at\", { fsp: 3 }).defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\", { fsp: 3 })\n .defaultNow()\n .$onUpdate(() => /* @__PURE__ */ new Date())\n .notNull(),\n },\n (table) => [index(\"verification_identifier_idx\").on(table.identifier)],\n);\n\nexport const userRelations = relations(user, ({ many }) => ({\n sessions: many(session),\n accounts: many(account),\n}));\n\nexport const sessionRelations = relations(session, ({ one }) => ({\n user: one(user, {\n fields: [session.userId],\n references: [user.id],\n }),\n}));\n\nexport const accountRelations = relations(account, ({ one }) => ({\n user: one(user, {\n fields: [account.userId],\n references: [user.id],\n }),\n}));\n`],\n [\"examples/todo/web/react/next/src/app/todos/page.tsx.hbs\", `\"use client\"\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\";\nimport { Checkbox } from \"@/components/ui/checkbox\";\nimport { Input } from \"@/components/ui/input\";\nimport { Loader2, Trash2 } from \"lucide-react\";\nimport { useState } from \"react\";\n\n{{#if (eq backend \"convex\")}}\nimport { useMutation, useQuery } from \"convex/react\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport type { Id } from \"@{{projectName}}/backend/convex/_generated/dataModel\";\n{{else}}\nimport { useMutation, useQuery } from \"@tanstack/react-query\";\n {{#if (eq api \"orpc\")}}\nimport { orpc } from \"@/utils/orpc\";\n {{/if}}\n {{#if (eq api \"trpc\")}}\nimport { trpc } from \"@/utils/trpc\";\n {{/if}}\n{{/if}}\n\n\nexport default function TodosPage() {\n const [newTodoText, setNewTodoText] = useState(\"\");\n\n {{#if (eq backend \"convex\")}}\n const todos = useQuery(api.todos.getAll);\n const createTodoMutation = useMutation(api.todos.create);\n const toggleTodoMutation = useMutation(api.todos.toggle);\n const deleteTodoMutation = useMutation(api.todos.deleteTodo);\n\n const handleAddTodo = async (e: React.FormEvent) => {\n e.preventDefault();\n const text = newTodoText.trim();\n if (!text) return;\n await createTodoMutation({ text });\n setNewTodoText(\"\");\n };\n\n const handleToggleTodo = (id: Id<\"todos\">, currentCompleted: boolean) => {\n toggleTodoMutation({ id, completed: !currentCompleted });\n };\n\n const handleDeleteTodo = (id: Id<\"todos\">) => {\n deleteTodoMutation({ id });\n };\n {{else}}\n {{#if (eq api \"orpc\")}}\n const todos = useQuery(orpc.todo.getAll.queryOptions());\n const createMutation = useMutation(\n orpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n }),\n );\n const toggleMutation = useMutation(\n orpc.todo.toggle.mutationOptions({\n onSuccess: () => { todos.refetch() },\n }),\n );\n const deleteMutation = useMutation(\n orpc.todo.delete.mutationOptions({\n onSuccess: () => { todos.refetch() },\n }),\n );\n {{/if}}\n {{#if (eq api \"trpc\")}}\n const todos = useQuery(trpc.todo.getAll.queryOptions());\n const createMutation = useMutation(\n trpc.todo.create.mutationOptions({\n onSuccess: () => {\n todos.refetch();\n setNewTodoText(\"\");\n },\n }),\n );\n const toggleMutation = useMutation(\n trpc.todo.toggle.mutationOptions({\n onSuccess: () => { todos.refetch() },\n }),\n );\n const deleteMutation = useMutation(\n trpc.todo.delete.mutationOptions({\n onSuccess: () => { todos.refetch() },\n }),\n );\n {{/if}}\n\n const handleAddTodo = (e: React.FormEvent) => {\n e.preventDefault();\n if (newTodoText.trim()) {\n createMutation.mutate({ text: newTodoText });\n }\n };\n\n const handleToggleTodo = (id: number, completed: boolean) => {\n toggleMutation.mutate({ id, completed: !completed });\n };\n\n const handleDeleteTodo = (id: number) => {\n deleteMutation.mutate({ id });\n };\n {{/if}}\n\n return (\n <div className=\"mx-auto w-full max-w-md py-10\">\n <Card>\n <CardHeader>\n <CardTitle>Todo List</CardTitle>\n <CardDescription>Manage your tasks efficiently</CardDescription>\n </CardHeader>\n <CardContent>\n <form\n onSubmit={handleAddTodo}\n className=\"mb-6 flex items-center space-x-2\"\n >\n <Input\n value={newTodoText}\n onChange={(e) => setNewTodoText(e.target.value)}\n placeholder=\"Add a new task...\"\n {{#if (eq backend \"convex\")}}\n {{else}}\n disabled={createMutation.isPending}\n {{/if}}\n />\n <Button\n type=\"submit\"\n {{#if (eq backend \"convex\")}}\n disabled={!newTodoText.trim()}\n {{else}}\n disabled={createMutation.isPending || !newTodoText.trim()}\n {{/if}}\n >\n {{#if (eq backend \"convex\")}}\n Add\n {{else}}\n {createMutation.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n \"Add\"\n )}\n {{/if}}\n </Button>\n </form>\n\n {{#if (eq backend \"convex\")}}\n {todos === undefined ? (\n <div className=\"flex justify-center py-4\">\n <Loader2 className=\"h-6 w-6 animate-spin\" />\n </div>\n ) : todos.length === 0 ? (\n <p className=\"py-4 text-center\">No todos yet. Add one above!</p>\n ) : (\n <ul className=\"space-y-2\">\n {todos.map((todo) => (\n <li\n key={todo._id}\n className=\"flex items-center justify-between rounded-md border p-2\"\n >\n <div className=\"flex items-center space-x-2\">\n <Checkbox\n checked={todo.completed}\n onCheckedChange={() =>\n handleToggleTodo(todo._id, todo.completed)\n }\n id={\\`todo-\\${todo._id}\\`}\n />\n <label\n htmlFor={\\`todo-\\${todo._id}\\`}\n className={\\`\\${todo.completed ? \"line-through text-muted-foreground\" : \"\"}\\`}\n >\n {todo.text}\n </label>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleDeleteTodo(todo._id)}\n aria-label=\"Delete todo\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </li>\n ))}\n </ul>\n )}\n {{else}}\n {todos.isLoading ? (\n <div className=\"flex justify-center py-4\">\n <Loader2 className=\"h-6 w-6 animate-spin\" />\n </div>\n ) : todos.data?.length === 0 ? (\n <p className=\"py-4 text-center\">\n No todos yet. Add one above!\n </p>\n ) : (\n <ul className=\"space-y-2\">\n {todos.data?.map((todo) => (\n <li\n key={todo.id}\n className=\"flex items-center justify-between rounded-md border p-2\"\n >\n <div className=\"flex items-center space-x-2\">\n <Checkbox\n checked={todo.completed}\n onCheckedChange={() =>\n handleToggleTodo(todo.id, todo.completed)\n }\n id={\\`todo-\\${todo.id}\\`}\n />\n <label\n htmlFor={\\`todo-\\${todo.id}\\`}\n className={\\`\\${todo.completed ? \"line-through text-muted-foreground\" : \"\"}\\`}\n >\n {todo.text}\n </label>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleDeleteTodo(todo.id)}\n aria-label=\"Delete todo\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </li>\n ))}\n </ul>\n )}\n {{/if}}\n </CardContent>\n </Card>\n </div>\n );\n}\n`],\n [\"examples/ai/web/react/next/src/app/ai/page.tsx.hbs\", `{{#if (eq backend \"convex\")}}\n\"use client\";\n\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport {\n useUIMessages,\n useSmoothText,\n type UIMessage,\n} from \"@convex-dev/agent/react\";\nimport { useMutation } from \"convex/react\";\nimport { Send, Loader2 } from \"lucide-react\";\n{{#if (eq webDeploy \"cloudflare\")}}\nimport dynamic from \"next/dynamic\";\n\nconst Streamdown = dynamic(\n () => import(\"streamdown\").then((mod) => ({ default: mod.Streamdown })),\n {\n loading: () => (\n <div className=\"flex h-full items-center justify-center\">\n <div className=\"text-muted-foreground\">Loading response...</div>\n </div>\n ),\n ssr: false,\n }\n);\n{{else}}\nimport { Streamdown } from \"streamdown\";\n{{/if}}\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n\nfunction MessageContent({\n text,\n isStreaming,\n}: {\n text: string;\n isStreaming: boolean;\n}) {\n const [visibleText] = useSmoothText(text, {\n startStreaming: isStreaming,\n });\n return <Streamdown>{visibleText}</Streamdown>;\n}\n\nexport default function AIPage() {\n const [input, setInput] = useState(\"\");\n const [threadId, setThreadId] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n const createThread = useMutation(api.chat.createNewThread);\n const sendMessage = useMutation(api.chat.sendMessage);\n\n const { results: messages } = useUIMessages(\n api.chat.listMessages,\n threadId ? { threadId } : \"skip\",\n { initialNumItems: 50, stream: true },\n );\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n const hasStreamingMessage = messages?.some(\n (m: UIMessage) => m.status === \"streaming\",\n );\n\n const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text || isLoading) return;\n\n setIsLoading(true);\n setInput(\"\");\n\n try {\n let currentThreadId = threadId;\n if (!currentThreadId) {\n currentThreadId = await createThread();\n setThreadId(currentThreadId);\n }\n\n await sendMessage({ threadId: currentThreadId, prompt: text });\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {!messages || messages.length === 0 ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n messages.map((message: UIMessage) => (\n <div\n key={message.key}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n <MessageContent\n text={message.text ?? \"\"}\n isStreaming={message.status === \"streaming\"}\n />\n </div>\n ))\n )}\n {isLoading && !hasStreamingMessage && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Thinking...</span>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n disabled={isLoading}\n />\n <Button type=\"submit\" size=\"icon\" disabled={isLoading || !input.trim()}>\n {isLoading ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send size={18} />\n )}\n </Button>\n </form>\n </div>\n );\n}\n{{else if (eq ai \"modelfusion\")}}\n\"use client\";\n\nimport { Send, Loader2 } from \"lucide-react\";\n{{#if (eq webDeploy \"cloudflare\")}}\nimport dynamic from \"next/dynamic\";\n\nconst Streamdown = dynamic(\n () => import(\"streamdown\").then((mod) => ({ default: mod.Streamdown })),\n {\n loading: () => (\n <div className=\"flex h-full items-center justify-center\">\n <div className=\"text-muted-foreground\">Loading response...</div>\n </div>\n ),\n ssr: false,\n }\n);\n{{else}}\nimport { Streamdown } from \"streamdown\";\n{{/if}}\nimport { useEffect, useRef, useState, useCallback } from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n{{#unless (eq backend \"self\")}}\nimport { env } from \"@{{projectName}}/env/web\";\n{{/unless}}\n\ntype Message = {\n id: string;\n role: \"user\" | \"assistant\";\n content: string;\n};\n\nexport default function AIPage() {\n const [input, setInput] = useState(\"\");\n const [messages, setMessages] = useState<Message[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [streamingContent, setStreamingContent] = useState(\"\");\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages, streamingContent]);\n\n const sendMessage = useCallback(async (text: string) => {\n const userMessage: Message = {\n id: Date.now().toString(),\n role: \"user\",\n content: text,\n };\n\n setMessages((prev) => [...prev, userMessage]);\n setIsLoading(true);\n setStreamingContent(\"\");\n\n try {\n const response = await fetch({{#if (eq backend \"self\")}}\"/api/ai\"{{else}}\\`\\${env.NEXT_PUBLIC_SERVER_URL}/ai\\`{{/if}}, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n messages: [...messages, userMessage].map((m) => ({\n role: m.role,\n content: m.content,\n })),\n }),\n });\n\n if (!response.ok) throw new Error(\"Failed to send message\");\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n\n if (reader) {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const data = line.slice(6);\n if (data === \"[DONE]\") continue;\n try {\n const parsed = JSON.parse(data);\n if (parsed.content) {\n fullContent += parsed.content;\n setStreamingContent(fullContent);\n }\n } catch {\n // Ignore parsing errors for incomplete chunks\n }\n }\n }\n }\n }\n\n const assistantMessage: Message = {\n id: (Date.now() + 1).toString(),\n role: \"assistant\",\n content: fullContent,\n };\n setMessages((prev) => [...prev, assistantMessage]);\n setStreamingContent(\"\");\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n }, [messages]);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text || isLoading) return;\n setInput(\"\");\n sendMessage(text);\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {messages.length === 0 && !streamingContent ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n <>\n {messages.map((message) => (\n <div\n key={message.id}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n <Streamdown>{message.content}</Streamdown>\n </div>\n ))}\n {streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <Streamdown isAnimating>{streamingContent}</Streamdown>\n </div>\n )}\n </>\n )}\n {isLoading && !streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Thinking...</span>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n disabled={isLoading}\n />\n <Button type=\"submit\" size=\"icon\" disabled={isLoading || !input.trim()}>\n {isLoading ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send size={18} />\n )}\n </Button>\n </form>\n </div>\n );\n}\n{{else if (eq ai \"langgraph\")}}\n\"use client\";\n\nimport { Send, Loader2 } from \"lucide-react\";\n{{#if (eq webDeploy \"cloudflare\")}}\nimport dynamic from \"next/dynamic\";\n\nconst Streamdown = dynamic(\n () => import(\"streamdown\").then((mod) => ({ default: mod.Streamdown })),\n {\n loading: () => (\n <div className=\"flex h-full items-center justify-center\">\n <div className=\"text-muted-foreground\">Loading response...</div>\n </div>\n ),\n ssr: false,\n }\n);\n{{else}}\nimport { Streamdown } from \"streamdown\";\n{{/if}}\nimport { useEffect, useRef, useState, useCallback } from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n{{#unless (eq backend \"self\")}}\nimport { env } from \"@{{projectName}}/env/web\";\n{{/unless}}\n\ntype Message = {\n id: string;\n role: \"user\" | \"assistant\";\n content: string;\n};\n\nexport default function AIPage() {\n const [input, setInput] = useState(\"\");\n const [messages, setMessages] = useState<Message[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [streamingContent, setStreamingContent] = useState(\"\");\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages, streamingContent]);\n\n const sendMessage = useCallback(async (text: string) => {\n const userMessage: Message = {\n id: Date.now().toString(),\n role: \"user\",\n content: text,\n };\n\n setMessages((prev) => [...prev, userMessage]);\n setIsLoading(true);\n setStreamingContent(\"\");\n\n try {\n const response = await fetch({{#if (eq backend \"self\")}}\"/api/ai\"{{else}}\\`\\${env.NEXT_PUBLIC_SERVER_URL}/ai\\`{{/if}}, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n messages: [...messages, userMessage].map((m) => ({\n role: m.role,\n content: m.content,\n })),\n }),\n });\n\n if (!response.ok) throw new Error(\"Failed to send message\");\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder();\n let fullContent = \"\";\n\n if (reader) {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const data = line.slice(6);\n if (data === \"[DONE]\") continue;\n try {\n const parsed = JSON.parse(data);\n if (parsed.content) {\n fullContent += parsed.content;\n setStreamingContent(fullContent);\n }\n } catch {\n // Ignore parsing errors for incomplete chunks\n }\n }\n }\n }\n }\n\n const assistantMessage: Message = {\n id: (Date.now() + 1).toString(),\n role: \"assistant\",\n content: fullContent,\n };\n setMessages((prev) => [...prev, assistantMessage]);\n setStreamingContent(\"\");\n } catch (error) {\n console.error(\"Failed to send message:\", error);\n } finally {\n setIsLoading(false);\n }\n }, [messages]);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text || isLoading) return;\n setInput(\"\");\n sendMessage(text);\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {messages.length === 0 && !streamingContent ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n <>\n {messages.map((message) => (\n <div\n key={message.id}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n <Streamdown>{message.content}</Streamdown>\n </div>\n ))}\n {streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <Streamdown isAnimating>{streamingContent}</Streamdown>\n </div>\n )}\n </>\n )}\n {isLoading && !streamingContent && (\n <div className=\"p-3 rounded-lg bg-secondary/20 mr-8\">\n <p className=\"text-sm font-semibold mb-1\">AI Assistant</p>\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Thinking...</span>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n disabled={isLoading}\n />\n <Button type=\"submit\" size=\"icon\" disabled={isLoading || !input.trim()}>\n {isLoading ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Send size={18} />\n )}\n </Button>\n </form>\n </div>\n );\n}\n{{else}}\n\"use client\";\n\nimport { useChat } from \"@ai-sdk/react\";\nimport { DefaultChatTransport } from \"ai\";\nimport { Send } from \"lucide-react\";\n{{#if (eq webDeploy \"cloudflare\")}}\nimport dynamic from \"next/dynamic\";\n\nconst Streamdown = dynamic(\n () => import(\"streamdown\").then((mod) => ({ default: mod.Streamdown })),\n {\n loading: () => (\n <div className=\"flex h-full items-center justify-center\">\n <div className=\"text-muted-foreground\">Loading response...</div>\n </div>\n ),\n ssr: false,\n }\n);\n{{else}}\nimport { Streamdown } from \"streamdown\";\n{{/if}}\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { env } from \"@{{projectName}}/env/web\";\n\nexport default function AIPage() {\n const [input, setInput] = useState(\"\");\n const { messages, sendMessage, status } = useChat({\n transport: new DefaultChatTransport({\n api: {{#if (eq backend \"self\")}}\"/api/ai\"{{else}}\\`\\${env.NEXT_PUBLIC_SERVER_URL}/ai\\`{{/if}},\n }),\n });\n\n const messagesEndRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }, [messages]);\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n const text = input.trim();\n if (!text) return;\n sendMessage({ text });\n setInput(\"\");\n };\n\n return (\n <div className=\"grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4\">\n <div className=\"overflow-y-auto space-y-4 pb-4\">\n {messages.length === 0 ? (\n <div className=\"text-center text-muted-foreground mt-8\">\n Ask me anything to get started!\n </div>\n ) : (\n messages.map((message) => (\n <div\n key={message.id}\n className={\\`p-3 rounded-lg \\${\n message.role === \"user\"\n ? \"bg-primary/10 ml-8\"\n : \"bg-secondary/20 mr-8\"\n }\\`}\n >\n <p className=\"text-sm font-semibold mb-1\">\n {message.role === \"user\" ? \"You\" : \"AI Assistant\"}\n </p>\n {message.parts?.map((part, index) => {\n if (part.type === \"text\") {\n return (\n <Streamdown\n key={index}\n isAnimating={status === \"streaming\" && message.role === \"assistant\"}\n >\n {part.text}\n </Streamdown>\n );\n }\n return null;\n })}\n </div>\n ))\n )}\n <div ref={messagesEndRef} />\n </div>\n\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center space-x-2 pt-2 border-t\"\n >\n <Input\n name=\"prompt\"\n value={input}\n onChange={(e) => setInput(e.target.value)}\n placeholder=\"Type your message...\"\n className=\"flex-1\"\n autoComplete=\"off\"\n autoFocus\n />\n <Button type=\"submit\" size=\"icon\">\n <Send size={18} />\n </Button>\n </form>\n </div>\n );\n}\n{{/if}}\n`],\n [\"examples/ai/fullstack/next/src/app/api/ai/route.ts.hbs\", `{{#if (eq ai \"modelfusion\")}}\nimport { streamText, openai } from \"modelfusion\";\n\nexport const maxDuration = 30;\n\nconst model = openai.ChatTextGenerator({\n\tmodel: \"gpt-4o-mini\",\n\ttemperature: 0.7,\n\tmaxGenerationTokens: 1000,\n});\n\nexport async function POST(req: Request) {\n\tconst { messages } = await req.json();\n\n\tconst chatMessages = messages.map((msg: { role: string; content: string }) => {\n\t\tif (msg.role === \"user\") {\n\t\t\treturn openai.ChatMessage.user(msg.content);\n\t\t}\n\t\treturn openai.ChatMessage.assistant(msg.content);\n\t});\n\n\tconst textStream = await streamText({\n\t\tmodel,\n\t\tprompt: chatMessages,\n\t});\n\n\tconst encoder = new TextEncoder();\n\tconst readable = new ReadableStream({\n\t\tasync start(controller) {\n\t\t\ttry {\n\t\t\t\tfor await (const delta of textStream) {\n\t\t\t\t\tif (delta) {\n\t\t\t\t\t\tcontroller.enqueue(encoder.encode(\\`data: \\${JSON.stringify({ content: delta })}\\\\n\\\\n\\`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontroller.enqueue(encoder.encode(\"data: [DONE]\\\\n\\\\n\"));\n\t\t\t\tcontroller.close();\n\t\t\t} catch (error) {\n\t\t\t\tcontroller.error(error);\n\t\t\t}\n\t\t},\n\t});\n\n\treturn new Response(readable, {\n\t\theaders: {\n\t\t\t\"Content-Type\": \"text/event-stream\",\n\t\t\t\"Cache-Control\": \"no-cache\",\n\t\t\tConnection: \"keep-alive\",\n\t\t},\n\t});\n}\n{{else if (eq ai \"langgraph\")}}\nimport { ChatGoogleGenerativeAI } from \"@langchain/google-genai\";\nimport { HumanMessage, AIMessage, type BaseMessage } from \"@langchain/core/messages\";\nimport { createReactAgent } from \"@langchain/langgraph/prebuilt\";\n\nexport const maxDuration = 30;\n\nconst model = new ChatGoogleGenerativeAI({\n\tmodel: \"gemini-2.0-flash\",\n\ttemperature: 0,\n});\n\nconst agent = createReactAgent({\n\tllm: model,\n\ttools: [],\n});\n\nexport async function POST(req: Request) {\n\tconst { messages } = await req.json();\n\n\tconst langchainMessages: BaseMessage[] = messages.map((msg: { role: string; content: string }) => {\n\t\tif (msg.role === \"user\") {\n\t\t\treturn new HumanMessage(msg.content);\n\t\t}\n\t\treturn new AIMessage(msg.content);\n\t});\n\n\tconst stream = await agent.stream(\n\t\t{ messages: langchainMessages },\n\t\t{ streamMode: \"messages\" }\n\t);\n\n\tconst encoder = new TextEncoder();\n\tconst readable = new ReadableStream({\n\t\tasync start(controller) {\n\t\t\ttry {\n\t\t\t\tfor await (const [message] of stream) {\n\t\t\t\t\tif (message.content) {\n\t\t\t\t\t\tconst content = typeof message.content === \"string\"\n\t\t\t\t\t\t\t? message.content\n\t\t\t\t\t\t\t: JSON.stringify(message.content);\n\t\t\t\t\t\tcontroller.enqueue(encoder.encode(\\`data: \\${JSON.stringify({ content })}\\\\n\\\\n\\`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontroller.enqueue(encoder.encode(\"data: [DONE]\\\\n\\\\n\"));\n\t\t\t\tcontroller.close();\n\t\t\t} catch (error) {\n\t\t\t\tcontroller.error(error);\n\t\t\t}\n\t\t},\n\t});\n\n\treturn new Response(readable, {\n\t\theaders: {\n\t\t\t\"Content-Type\": \"text/event-stream\",\n\t\t\t\"Cache-Control\": \"no-cache\",\n\t\t\tConnection: \"keep-alive\",\n\t\t},\n\t});\n}\n{{else if (eq ai \"google-adk\")}}\nimport { LlmAgent, Runner } from \"@google/adk\";\n\nexport const maxDuration = 30;\n\nconst agent = new LlmAgent({\n\tname: \"chat_agent\",\n\tmodel: \"gemini-2.5-flash\",\n\tdescription: \"A helpful AI assistant that can answer questions and help with tasks.\",\n\tinstruction: \"You are a helpful AI assistant. Respond to user queries in a clear and concise manner.\",\n\ttools: [],\n});\n\nexport async function POST(req: Request) {\n\tconst { messages } = await req.json();\n\n\tconst lastMessage = messages[messages.length - 1];\n\tconst userMessage = lastMessage?.content || \"\";\n\n\tconst runner = new Runner({ agent, appName: \"chat-app\" });\n\tconst result = await runner.runAsync({ userMessage });\n\n\tlet responseText = \"\";\n\tfor await (const event of result) {\n\t\tif (event.content?.parts) {\n\t\t\tfor (const part of event.content.parts) {\n\t\t\t\tif (part.text) {\n\t\t\t\t\tresponseText += part.text;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst encoder = new TextEncoder();\n\tconst readable = new ReadableStream({\n\t\tstart(controller) {\n\t\t\tcontroller.enqueue(encoder.encode(\\`data: \\${JSON.stringify({ content: responseText })}\\\\n\\\\n\\`));\n\t\t\tcontroller.enqueue(encoder.encode(\"data: [DONE]\\\\n\\\\n\"));\n\t\t\tcontroller.close();\n\t\t},\n\t});\n\n\treturn new Response(readable, {\n\t\theaders: {\n\t\t\t\"Content-Type\": \"text/event-stream\",\n\t\t\t\"Cache-Control\": \"no-cache\",\n\t\t\tConnection: \"keep-alive\",\n\t\t},\n\t});\n}\n{{else}}\nimport { google } from \"@ai-sdk/google\";\nimport { streamText, type UIMessage, convertToModelMessages, wrapLanguageModel } from \"ai\";\nimport { devToolsMiddleware } from \"@ai-sdk/devtools\";\n\nexport const maxDuration = 30;\n\nexport async function POST(req: Request) {\n\tconst { messages }: { messages: UIMessage[] } = await req.json();\n\n\tconst model = wrapLanguageModel({\n\t\tmodel: google(\"gemini-2.5-flash\"),\n\t\tmiddleware: devToolsMiddleware(),\n\t});\n\tconst result = streamText({\n\t\tmodel,\n\t\tmessages: await convertToModelMessages(messages),\n\t});\n\n\treturn result.toUIMessageStreamResponse();\n}\n{{/if}}\n`],\n [\"examples/ai/fullstack/tanstack-start/src/routes/api/ai/$.ts.hbs\", `{{#if (eq ai \"modelfusion\")}}\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { streamText, openai } from \"modelfusion\";\n\nconst model = openai.ChatTextGenerator({\n\tmodel: \"gpt-4o-mini\",\n\ttemperature: 0.7,\n\tmaxGenerationTokens: 1000,\n});\n\nexport const Route = createFileRoute(\"/api/ai/$\")({\n\tserver: {\n\t\thandlers: {\n\t\t\tPOST: async ({ request }) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst { messages } = await request.json();\n\n\t\t\t\t\tconst chatMessages = messages.map((msg: { role: string; content: string }) => {\n\t\t\t\t\t\tif (msg.role === \"user\") {\n\t\t\t\t\t\t\treturn openai.ChatMessage.user(msg.content);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn openai.ChatMessage.assistant(msg.content);\n\t\t\t\t\t});\n\n\t\t\t\t\tconst textStream = await streamText({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tprompt: chatMessages,\n\t\t\t\t\t});\n\n\t\t\t\t\tconst encoder = new TextEncoder();\n\t\t\t\t\tconst readable = new ReadableStream({\n\t\t\t\t\t\tasync start(controller) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tfor await (const delta of textStream) {\n\t\t\t\t\t\t\t\t\tif (delta) {\n\t\t\t\t\t\t\t\t\t\tcontroller.enqueue(encoder.encode(\\`data: \\${JSON.stringify({ content: delta })}\\\\n\\\\n\\`));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcontroller.enqueue(encoder.encode(\"data: [DONE]\\\\n\\\\n\"));\n\t\t\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tcontroller.error(error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\treturn new Response(readable, {\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"Content-Type\": \"text/event-stream\",\n\t\t\t\t\t\t\t\"Cache-Control\": \"no-cache\",\n\t\t\t\t\t\t\tConnection: \"keep-alive\",\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"AI API error:\", error);\n\t\t\t\t\treturn new Response(\n\t\t\t\t\t\tJSON.stringify({ error: \"Failed to process AI request\" }),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstatus: 500,\n\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t},\n});\n{{else if (eq ai \"langgraph\")}}\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { ChatGoogleGenerativeAI } from \"@langchain/google-genai\";\nimport { HumanMessage, AIMessage, type BaseMessage } from \"@langchain/core/messages\";\nimport { createReactAgent } from \"@langchain/langgraph/prebuilt\";\n\nconst model = new ChatGoogleGenerativeAI({\n\tmodel: \"gemini-2.0-flash\",\n\ttemperature: 0,\n});\n\nconst agent = createReactAgent({\n\tllm: model,\n\ttools: [],\n});\n\nexport const Route = createFileRoute(\"/api/ai/$\")({\n\tserver: {\n\t\thandlers: {\n\t\t\tPOST: async ({ request }) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst { messages } = await request.json();\n\n\t\t\t\t\tconst langchainMessages: BaseMessage[] = messages.map((msg: { role: string; content: string }) => {\n\t\t\t\t\t\tif (msg.role === \"user\") {\n\t\t\t\t\t\t\treturn new HumanMessage(msg.content);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn new AIMessage(msg.content);\n\t\t\t\t\t});\n\n\t\t\t\t\tconst stream = await agent.stream(\n\t\t\t\t\t\t{ messages: langchainMessages },\n\t\t\t\t\t\t{ streamMode: \"messages\" }\n\t\t\t\t\t);\n\n\t\t\t\t\tconst encoder = new TextEncoder();\n\t\t\t\t\tconst readable = new ReadableStream({\n\t\t\t\t\t\tasync start(controller) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tfor await (const [message] of stream) {\n\t\t\t\t\t\t\t\t\tif (message.content) {\n\t\t\t\t\t\t\t\t\t\tconst content = typeof message.content === \"string\"\n\t\t\t\t\t\t\t\t\t\t\t? message.content\n\t\t\t\t\t\t\t\t\t\t\t: JSON.stringify(message.content);\n\t\t\t\t\t\t\t\t\t\tcontroller.enqueue(encoder.encode(\\`data: \\${JSON.stringify({ content })}\\\\n\\\\n\\`));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcontroller.enqueue(encoder.encode(\"data: [DONE]\\\\n\\\\n\"));\n\t\t\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\tcontroller.error(error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\treturn new Response(readable, {\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"Content-Type\": \"text/event-stream\",\n\t\t\t\t\t\t\t\"Cache-Control\": \"no-cache\",\n\t\t\t\t\t\t\tConnection: \"keep-alive\",\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"AI API error:\", error);\n\t\t\t\t\treturn new Response(\n\t\t\t\t\t\tJSON.stringify({ error: \"Failed to process AI request\" }),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstatus: 500,\n\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t},\n});\n{{else if (eq ai \"google-adk\")}}\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { LlmAgent, Runner } from \"@google/adk\";\n\nconst agent = new LlmAgent({\n\tname: \"chat_agent\",\n\tmodel: \"gemini-2.5-flash\",\n\tdescription: \"A helpful AI assistant that can answer questions and help with tasks.\",\n\tinstruction: \"You are a helpful AI assistant. Respond to user queries in a clear and concise manner.\",\n\ttools: [],\n});\n\nexport const Route = createFileRoute(\"/api/ai/$\")({\n\tserver: {\n\t\thandlers: {\n\t\t\tPOST: async ({ request }) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst { messages } = await request.json();\n\n\t\t\t\t\tconst lastMessage = messages[messages.length - 1];\n\t\t\t\t\tconst userMessage = lastMessage?.content || \"\";\n\n\t\t\t\t\tconst runner = new Runner({ agent, appName: \"chat-app\" });\n\t\t\t\t\tconst result = await runner.runAsync({ userMessage });\n\n\t\t\t\t\tlet responseText = \"\";\n\t\t\t\t\tfor await (const event of result) {\n\t\t\t\t\t\tif (event.content?.parts) {\n\t\t\t\t\t\t\tfor (const part of event.content.parts) {\n\t\t\t\t\t\t\t\tif (part.text) {\n\t\t\t\t\t\t\t\t\tresponseText += part.text;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst encoder = new TextEncoder();\n\t\t\t\t\tconst readable = new ReadableStream({\n\t\t\t\t\t\tstart(controller) {\n\t\t\t\t\t\t\tcontroller.enqueue(encoder.encode(\\`data: \\${JSON.stringify({ content: responseText })}\\\\n\\\\n\\`));\n\t\t\t\t\t\t\tcontroller.enqueue(encoder.encode(\"data: [DONE]\\\\n\\\\n\"));\n\t\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\treturn new Response(readable, {\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"Content-Type\": \"text/event-stream\",\n\t\t\t\t\t\t\t\"Cache-Control\": \"no-cache\",\n\t\t\t\t\t\t\tConnection: \"keep-alive\",\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"AI API error:\", error);\n\t\t\t\t\treturn new Response(\n\t\t\t\t\t\tJSON.stringify({ error: \"Failed to process AI request\" }),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstatus: 500,\n\t\t\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t},\n});\n{{else}}\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { google } from \"@ai-sdk/google\";\nimport { streamText, type UIMessage, convertToModelMessages, wrapLanguageModel } from \"ai\";\nimport { devToolsMiddleware } from \"@ai-sdk/devtools\";\n\nexport const Route = createFileRoute(\"/api/ai/$\")({\n server: {\n handlers: {\n POST: async ({ request }) => {\n try {\n const { messages }: { messages: UIMessage[] } = await request.json();\n\n const model = wrapLanguageModel({\n model: google(\"gemini-2.5-flash\"),\n middleware: devToolsMiddleware(),\n });\n const result = streamText({\n model,\n messages: await convertToModelMessages(messages),\n });\n\n return result.toUIMessageStreamResponse();\n } catch (error) {\n console.error(\"AI API error:\", error);\n return new Response(\n JSON.stringify({ error: \"Failed to process AI request\" }),\n {\n status: 500,\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n }\n },\n },\n },\n});\n{{/if}}\n`],\n [\"api/ts-rest/fullstack/tanstack-start/src/routes/api/rest/$.ts.hbs\", `import { createAPIFileRoute } from \"@tanstack/react-start/api\";\nimport { tsr } from \"@ts-rest/serverless\";\nimport { contract } from \"@{{projectName}}/api/index\";\nimport { createRouter } from \"@{{projectName}}/api/routers\";\nimport { createContext } from \"@{{projectName}}/api/context\";\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@/lib/auth\";\n{{/if}}\n\nconst handler = tsr.router(contract, async (args) => {\n{{#if (eq auth \"better-auth\")}}\n const request = args.request;\n const session = await auth.api.getSession({\n headers: request.headers,\n });\n const ctx = createContext(request, session);\n{{else}}\n const ctx = createContext(args.request);\n{{/if}}\n const router = createRouter(ctx);\n\n // Handle nested routes\n const path = args.appRoute.path;\n if (path.startsWith(\"/todos\")) {\n const method = args.appRoute.method;\n if (method === \"GET\" && path === \"/todos\") {\n return router.todos.getAll();\n }\n if (method === \"POST\" && path === \"/todos\") {\n return router.todos.create(args as any);\n }\n if (method === \"PATCH\" && path.includes(\"/toggle\")) {\n return router.todos.toggle(args as any);\n }\n if (method === \"DELETE\") {\n return router.todos.delete(args as any);\n }\n }\n\n if (path === \"/health\") {\n return router.healthCheck();\n }\n{{#if (eq auth \"better-auth\")}}\n if (path === \"/private\") {\n return router.privateData();\n }\n{{/if}}\n\n return { status: 404 as const, body: { message: \"Not found\" } };\n});\n\nexport const APIRoute = createAPIFileRoute(\"/api/rest/$\")({\n GET: ({ request }) => handler.fetch(request),\n POST: ({ request }) => handler.fetch(request),\n PATCH: ({ request }) => handler.fetch(request),\n DELETE: ({ request }) => handler.fetch(request),\n});\n`],\n [\"api/ts-rest/fullstack/astro/src/pages/api/rest/[...rest].ts.hbs\", `import type { APIRoute } from \"astro\";\nimport { tsr } from \"@ts-rest/serverless\";\nimport { contract } from \"@{{projectName}}/api/index\";\nimport { createRouter } from \"@{{projectName}}/api/routers\";\nimport { createContext } from \"@{{projectName}}/api/context\";\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@/lib/auth\";\n{{/if}}\n\nconst handler = tsr.router(contract, async (args) => {\n{{#if (eq auth \"better-auth\")}}\n const request = args.request;\n const session = await auth.api.getSession({\n headers: request.headers,\n });\n const ctx = createContext(args.astroContext, session);\n{{else}}\n const ctx = createContext(args.astroContext);\n{{/if}}\n const router = createRouter(ctx);\n\n // Handle nested routes\n const path = args.appRoute.path;\n if (path.startsWith(\"/todos\")) {\n const method = args.appRoute.method;\n if (method === \"GET\" && path === \"/todos\") {\n return router.todos.getAll();\n }\n if (method === \"POST\" && path === \"/todos\") {\n return router.todos.create(args as any);\n }\n if (method === \"PATCH\" && path.includes(\"/toggle\")) {\n return router.todos.toggle(args as any);\n }\n if (method === \"DELETE\") {\n return router.todos.delete(args as any);\n }\n }\n\n if (path === \"/health\") {\n return router.healthCheck();\n }\n{{#if (eq auth \"better-auth\")}}\n if (path === \"/private\") {\n return router.privateData();\n }\n{{/if}}\n\n return { status: 404 as const, body: { message: \"Not found\" } };\n});\n\nexport const ALL: APIRoute = async (context) => {\n return handler.fetch(context.request, { astroContext: context });\n};\n`],\n [\"api/garph/fullstack/next/src/app/api/graphql/route.ts.hbs\", `import { createYoga } from \"graphql-yoga\";\nimport { createSchema } from \"@{{projectName}}/api/routers\";\nimport { createContext } from \"@{{projectName}}/api/context\";\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@/lib/auth\";\nimport { headers } from \"next/headers\";\n{{/if}}\nimport type { NextRequest } from \"next/server\";\n\nconst yoga = createYoga({\n graphqlEndpoint: \"/api/graphql\",\n fetchAPI: { Response },\n context: async ({ request }) => {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: await headers(),\n });\n return createContext(request as NextRequest, session);\n{{else}}\n return createContext(request as NextRequest);\n{{/if}}\n },\n schema: async ({ request }) => {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: await headers(),\n });\n const ctx = createContext(request as NextRequest, session);\n{{else}}\n const ctx = createContext(request as NextRequest);\n{{/if}}\n return createSchema(ctx);\n },\n});\n\nexport async function GET(request: NextRequest) {\n return yoga.handleRequest(request, {});\n}\n\nexport async function POST(request: NextRequest) {\n return yoga.handleRequest(request, {});\n}\n`],\n [\"cms/sanity/web/next/src/app/studio/[[...tool]]/page.tsx.hbs\", `import { NextStudio } from \"next-sanity/studio\";\n\nimport config from \"../../../../sanity.config\";\n\nexport const dynamic = \"force-static\";\n\nexport { metadata, viewport } from \"next-sanity/studio\";\n\nexport default function StudioPage() {\n return <NextStudio config={config} />;\n}\n`],\n [\"api/orpc/fullstack/tanstack-start/src/routes/api/rpc/$.ts.hbs\", `import { createContext } from \"@{{projectName}}/api/context\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\nimport { OpenAPIHandler } from \"@orpc/openapi/fetch\";\nimport { OpenAPIReferencePlugin } from \"@orpc/openapi/plugins\";\nimport { ZodToJsonSchemaConverter } from \"@orpc/zod/zod4\";\nimport { RPCHandler } from \"@orpc/server/fetch\";\nimport { onError } from \"@orpc/server\";\nimport { createFileRoute } from \"@tanstack/react-router\";\n\nconst rpcHandler = new RPCHandler(appRouter, {\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\n\nconst apiHandler = new OpenAPIHandler(appRouter, {\n\tplugins: [\n\t\tnew OpenAPIReferencePlugin({\n\t\t\tschemaConverters: [new ZodToJsonSchemaConverter()],\n\t\t}),\n\t],\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\n\nasync function handle({ request }: { request: Request }) {\n\tconst rpcResult = await rpcHandler.handle(request, {\n\t\tprefix: \"/api/rpc\",\n\t\tcontext: await createContext({ req: request }),\n\t});\n\tif (rpcResult.response) return rpcResult.response;\n\n\tconst apiResult = await apiHandler.handle(request, {\n\t\tprefix: \"/api/rpc/api-reference\",\n\t\tcontext: await createContext({ req: request }),\n\t});\n\tif (apiResult.response) return apiResult.response;\n\n\treturn new Response(\"Not found\", { status: 404 });\n}\n\nexport const Route = createFileRoute('/api/rpc/$')({\n server: {\n handlers: {\n HEAD: handle,\n GET: handle,\n POST: handle,\n PUT: handle,\n PATCH: handle,\n DELETE: handle,\n },\n },\n})`],\n [\"api/orpc/fullstack/astro/src/pages/api/rpc/[...rest].ts.hbs\", `import type { APIRoute } from 'astro';\nimport { createContext } from '@{{projectName}}/api/context';\nimport { appRouter } from '@{{projectName}}/api/routers/index';\nimport { OpenAPIHandler } from '@orpc/openapi/fetch';\nimport { OpenAPIReferencePlugin } from '@orpc/openapi/plugins';\nimport { ZodToJsonSchemaConverter } from '@orpc/zod/zod4';\nimport { RPCHandler } from '@orpc/server/fetch';\nimport { onError } from '@orpc/server';\n\nconst rpcHandler = new RPCHandler(appRouter, {\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\n\nconst apiHandler = new OpenAPIHandler(appRouter, {\n\tplugins: [\n\t\tnew OpenAPIReferencePlugin({\n\t\t\tschemaConverters: [new ZodToJsonSchemaConverter()],\n\t\t}),\n\t],\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\n\nconst handler: APIRoute = async ({ request }) => {\n\tconst rpcResult = await rpcHandler.handle(request, {\n\t\tprefix: '/api/rpc',\n\t\tcontext: await createContext(request),\n\t});\n\tif (rpcResult.response) return rpcResult.response;\n\n\tconst apiResult = await apiHandler.handle(request, {\n\t\tprefix: '/api/rpc/api-reference',\n\t\tcontext: await createContext(request),\n\t});\n\tif (apiResult.response) return apiResult.response;\n\n\treturn new Response('Not found', { status: 404 });\n};\n\nexport const GET = handler;\nexport const POST = handler;\nexport const PUT = handler;\nexport const PATCH = handler;\nexport const DELETE = handler;\n`],\n [\"api/trpc/fullstack/tanstack-start/src/routes/api/trpc/$.ts.hbs\", `import { fetchRequestHandler } from '@trpc/server/adapters/fetch'\nimport { appRouter } from '@{{projectName}}/api/routers/index'\nimport { createContext } from '@{{projectName}}/api/context'\nimport { createFileRoute } from '@tanstack/react-router'\n\nfunction handler({ request }: { request: Request }) {\n return fetchRequestHandler({\n req: request,\n router: appRouter,\n createContext,\n endpoint: '/api/trpc',\n })\n}\n\nexport const Route = createFileRoute('/api/trpc/$')({\n server: {\n handlers: {\n GET: handler,\n POST: handler,\n },\n },\n})\n`],\n [\"api/trpc/fullstack/astro/src/pages/api/trpc/[...trpc].ts.hbs\", `import type { APIRoute } from 'astro';\nimport { fetchRequestHandler } from '@trpc/server/adapters/fetch';\nimport { appRouter } from '@{{projectName}}/api/routers/index';\nimport { createContext } from '@{{projectName}}/api/context';\n\nconst handler: APIRoute = async ({ request }) => {\n\treturn fetchRequestHandler({\n\t\tendpoint: '/api/trpc',\n\t\treq: request,\n\t\trouter: appRouter,\n\t\tcreateContext: () => createContext(request),\n\t});\n};\n\nexport const GET = handler;\nexport const POST = handler;\n`],\n [\"auth/better-auth/convex/web/react/next/src/app/dashboard/page.tsx.hbs\", `\"use client\"\n\nimport SignInForm from \"@/components/sign-in-form\";\nimport SignUpForm from \"@/components/sign-up-form\";\nimport UserMenu from \"@/components/user-menu\";\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport {\n Authenticated,\n AuthLoading,\n Unauthenticated,\n useQuery,\n} from \"convex/react\";\nimport { useState } from \"react\";\n\nexport default function DashboardPage() {\n const [showSignIn, setShowSignIn] = useState(false);\n const privateData = useQuery(api.privateData.get);\n\n return (\n <>\n <Authenticated>\n <div>\n <h1>Dashboard</h1>\n <p>privateData: {privateData?.message}</p>\n <UserMenu />\n </div>\n </Authenticated>\n <Unauthenticated>\n {showSignIn ? (\n <SignInForm onSwitchToSignUp={() => setShowSignIn(false)} />\n ) : (\n <SignUpForm onSwitchToSignIn={() => setShowSignIn(true)} />\n )}\n </Unauthenticated>\n <AuthLoading>\n <div>Loading...</div>\n </AuthLoading>\n </>\n );\n}\n`],\n [\"auth/clerk/convex/web/react/next/src/app/dashboard/page.tsx.hbs\", `\"use client\";\n\nimport { api } from \"@{{projectName}}/backend/convex/_generated/api\";\nimport { SignInButton, UserButton, useUser } from \"@clerk/nextjs\";\nimport { Authenticated, AuthLoading, Unauthenticated, useQuery } from \"convex/react\";\n\nexport default function Dashboard() {\n const user = useUser();\n const privateData = useQuery(api.privateData.get);\n\n return (\n <>\n <Authenticated>\n <div>\n <h1>Dashboard</h1>\n <p>Welcome {user.user?.fullName}</p>\n <p>privateData: {privateData?.message}</p>\n <UserButton />\n </div>\n </Authenticated>\n <Unauthenticated>\n <SignInButton />\n </Unauthenticated>\n <AuthLoading>\n <div>Loading...</div>\n </AuthLoading>\n </>\n );\n}\n`],\n [\"auth/nextauth/fullstack/next/src/app/api/auth/[...nextauth]/route.ts.hbs\", `import { handlers } from \"@/lib/auth\";\n\nexport const { GET, POST } = handlers;\n`],\n [\"auth/better-auth/fullstack/next/src/app/api/auth/[...all]/route.ts.hbs\", `import { auth } from \"@{{projectName}}/auth\";\nimport { toNextJsHandler } from \"better-auth/next-js\";\n\nexport const { GET, POST } = toNextJsHandler(auth.handler);\n`],\n [\"api/ts-rest/fullstack/next/src/app/api/rest/[[...rest]]/route.ts.hbs\", `import { createNextHandler } from \"@ts-rest/serverless/next\";\nimport { contract } from \"@{{projectName}}/api/index\";\nimport { createRouter } from \"@{{projectName}}/api/routers\";\nimport { createContext } from \"@{{projectName}}/api/context\";\n{{#if (eq auth \"better-auth\")}}\nimport { auth } from \"@/lib/auth\";\nimport { headers } from \"next/headers\";\n{{/if}}\n\nconst handler = createNextHandler(\n contract,\n async (args, { request }) => {\n{{#if (eq auth \"better-auth\")}}\n const session = await auth.api.getSession({\n headers: await headers(),\n });\n const ctx = createContext(request, session);\n{{else}}\n const ctx = createContext(request);\n{{/if}}\n const router = createRouter(ctx);\n \n // Handle nested routes\n const path = args.appRoute.path;\n if (path.startsWith(\"/todos\")) {\n const method = args.appRoute.method;\n if (method === \"GET\" && path === \"/todos\") {\n return router.todos.getAll();\n }\n if (method === \"POST\" && path === \"/todos\") {\n return router.todos.create(args as any);\n }\n if (method === \"PATCH\" && path.includes(\"/toggle\")) {\n return router.todos.toggle(args as any);\n }\n if (method === \"DELETE\") {\n return router.todos.delete(args as any);\n }\n }\n \n if (path === \"/health\") {\n return router.healthCheck();\n }\n{{#if (eq auth \"better-auth\")}}\n if (path === \"/private\") {\n return router.privateData();\n }\n{{/if}}\n \n return { status: 404 as const, body: { message: \"Not found\" } };\n },\n {\n basePath: \"/api/rest\",\n jsonQuery: true,\n }\n);\n\nexport { handler as GET, handler as POST, handler as PATCH, handler as DELETE };\n`],\n [\"api/orpc/fullstack/next/src/app/api/rpc/[[...rest]]/route.ts.hbs\", `import { createContext } from \"@{{projectName}}/api/context\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\nimport { OpenAPIHandler } from \"@orpc/openapi/fetch\";\nimport { OpenAPIReferencePlugin } from \"@orpc/openapi/plugins\";\nimport { ZodToJsonSchemaConverter } from \"@orpc/zod/zod4\";\nimport { RPCHandler } from \"@orpc/server/fetch\";\nimport { onError } from \"@orpc/server\";\nimport { NextRequest } from \"next/server\";\n\nconst rpcHandler = new RPCHandler(appRouter, {\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\nconst apiHandler = new OpenAPIHandler(appRouter, {\n\tplugins: [\n\t\tnew OpenAPIReferencePlugin({\n\t\t\tschemaConverters: [new ZodToJsonSchemaConverter()],\n\t\t}),\n\t],\n\tinterceptors: [\n\t\tonError((error) => {\n\t\t\tconsole.error(error);\n\t\t}),\n\t],\n});\n\nasync function handleRequest(req: NextRequest) {\n\tconst rpcResult = await rpcHandler.handle(req, {\n\t\tprefix: \"/api/rpc\",\n\t\tcontext: await createContext(req),\n\t});\n\tif (rpcResult.response) return rpcResult.response;\n\n\tconst apiResult = await apiHandler.handle(req, {\n\t\tprefix: \"/api/rpc/api-reference\",\n\t\tcontext: await createContext(req),\n\t});\n\tif (apiResult.response) return apiResult.response;\n\n\treturn new Response(\"Not found\", { status: 404 });\n}\n\nexport const GET = handleRequest;\nexport const POST = handleRequest;\nexport const PUT = handleRequest;\nexport const PATCH = handleRequest;\nexport const DELETE = handleRequest;`],\n [\"api/trpc/fullstack/next/src/app/api/trpc/[trpc]/route.ts.hbs\", `import { fetchRequestHandler } from \"@trpc/server/adapters/fetch\";\nimport { appRouter } from \"@{{projectName}}/api/routers/index\";\nimport { createContext } from \"@{{projectName}}/api/context\";\nimport { NextRequest } from \"next/server\";\n\nfunction handler(req: NextRequest) {\n\treturn fetchRequestHandler({\n\t\tendpoint: \"/api/trpc\",\n\t\treq,\n\t\trouter: appRouter,\n\t\tcreateContext: () => createContext(req),\n\t});\n}\nexport { handler as GET, handler as POST };\n`],\n [\"auth/better-auth/convex/web/react/tanstack-start/src/routes/api/auth/$.ts.hbs\", `import { createFileRoute } from \"@tanstack/react-router\";\nimport { handler } from \"@/lib/auth-server\";\n\nexport const Route = createFileRoute(\"/api/auth/$\")({\n server: {\n handlers: {\n GET: ({ request }) => handler(request),\n POST: ({ request }) => handler(request),\n },\n },\n});\n`],\n [\"auth/better-auth/convex/web/react/next/src/app/api/auth/[...all]/route.ts.hbs\", `import { handler } from \"@/lib/auth-server\";\n\nexport const { GET, POST } = handler;\n`]\n]);\n\nexport const TEMPLATE_COUNT = 703;\n"],"mappings":"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B,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SACE;GACH;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SACE;GACH;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU;GACrB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,eAAe;GAC1B,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW;GACZ;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,UAAU,SAAS,KAAK,IAAI;GACxC;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa,UAAU,YAAY;GAC/C;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,YAAY;GACvB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,kBAAkB;GAC7B,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,kBAAkB;GAC7B,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,aAAa;GACxB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,YAAY;GACvB,SAAS;GACV;EACD;GACE,KAAK;GACL,OAAO;GACP,WAAW,YAAY;GACvB,SAAS;GACV;EACF;;AAGH,SAAS,aAAa,KAA0C;CAC9D,MAAMD,OAAsB,EAAE;AAE9B,KAAI,QAAQ,UACV,MAAK,KAAK;EACR,KAAK;EACL,OAAO,qBACL,IACA,iEACD;EACD,WAAW;EACX,SAAS;EACV,CAAC;AAGJ,KAAI,QAAQ,SACV,MAAK,KACH;EACE,KAAK;EACL,OAAO;EACP,WAAW;EACX,SAAS;EACV,EACD;EACE,KAAK;EACL,OAAO;EACP,WAAW;EACX,SAAS;EACV,EACD;EACE,KAAK;EACL,wBAAO,IAAI,MAAM,EAAC,aAAa,CAAC,MAAM,IAAI,CAAC;EAC3C,WAAW;EACX,SAAS;EACV,EACD;EACE,KAAK;EACL,OAAO;EACP,WAAW;EACX,SAAS;EACV,CACF;AAGH,QAAO;;AAGT,SAAgB,oBAAoB,KAAwB,QAA6B;CACvF,MAAM,EACJ,SACA,UACA,UACA,MACA,OACA,UACA,SACA,WACA,cACA,SACA,UACA,YACA,SACA,kBACE;CAEJ,MAAM,iBAAiB,SAAS,SAAS,eAAe;CACxD,MAAM,oBAAoB,SAAS,SAAS,kBAAkB;CAC9D,MAAM,mBAAmB,SAAS,SAAS,iBAAiB;CAC5D,MAAM,YAAY,SAAS,SAAS,OAAO;CAC3C,MAAM,UAAU,SAAS,SAAS,OAAO;CACzC,MAAM,YAAY,SAAS,SAAS,SAAS;CAC7C,MAAM,WAAW,SAAS,SAAS,QAAQ;AAW3C,KATE,kBACA,qBACA,oBACA,aACA,WACA,YACA,WAGkB;EAClB,MAAM,YAAY;AAClB,MAAI,IAAI,gBAAgB,UAAU,CAGhC,cAAa,KAFG,GAAG,UAAU,QACV,gBAAgB,UAAU,SAAS,MAAM,SAAS,CAC/B;;AAK1C,KACE,SAAS,SAAS,cAAc,IAChC,SAAS,SAAS,iBAAiB,IACnC,SAAS,SAAS,mBAAmB,EACrC;EACA,MAAM,YAAY;AAClB,MAAI,IAAI,gBAAgB,UAAU,CAGhC,cAAa,KAFG,GAAG,UAAU,QACV,gBAAgB,UAAU,SAAS,KAAK,CACrB;;AAK1C,KAAI,YAAY,UAAU;EACxB,MAAM,mBAAmB;AACzB,MAAI,IAAI,gBAAgB,iBAAiB,EAAE;GACzC,MAAM,eAAe,GAAG,iBAAiB;GAGzC,MAAM,gBAAgB,yBAAyB,UAAU,MAAM,SAAS;AACxE,OAAI,eAAe;IACjB,IAAI,iBAAiB;AACrB,QAAI,IAAI,OAAO,aAAa,CAC1B,kBAAiB,IAAI,SAAS,aAAa,IAAI;AAEjD,QAAI,UAAU,cAAc,gBAAgB,eAAe;;GAI7D,MAAM,oBAAoB,uBAAuB,UAAU,MAAM,SAAS;AAC1E,OAAI,kBAAkB,SAAS,GAAG;IAChC,IAAI,kBAAkB;AACtB,QAAI,IAAI,OAAO,aAAa,CAC1B,mBAAkB,IAAI,SAAS,aAAa,IAAI;IAElD,MAAM,kBAAkB,yBAAyB,iBAAiB,kBAAkB;AACpF,QAAI,UAAU,cAAc,gBAAgB;;;AAGhD;;CAIF,MAAM,aAAa,gBACjB,SACA,UACA,MACA,UACA,SACA,SACA,WACA,cACA,UACA,OACA,UACA,YACA,SACA,eACA,OAAO,UACP,OAAO,QACR;AAED,KAAI,YAAY,QAAQ;EACtB,MAAM,SAAS;AACf,MAAI,IAAI,gBAAgB,OAAO,CAE7B,cAAa,KADG,GAAG,OAAO,QACC,WAAW;YAE/B,IAAI,gBAAgB,cAAc,CAE3C,cAAa,KADG,oBACW,WAAW;AAIxC,MAAK,OAAO,QAAQ,aAAa,OAAO,QAAQ,aAAa,WAAW;EACtE,MAAM,SAAS;AACf,MAAI,IAAI,gBAAgB,OAAO,CAG7B,cAAa,KAFG,GAAG,OAAO,QACV,aAAa,OAAO,IAAI,CACL;;AAQvC,KAHyB,cAAc,gBAAgB,iBAAiB,gBAC5C,cAAc,gBAAgB,iBAAiB,cAE9B;EAC3C,MAAM,WAAW;AACjB,MAAI,IAAI,gBAAgB,SAAS,CAS/B,cAAa,KARG,GAAG,SAAS,QACY,CACtC;GACE,KAAK;GACL,OAAO;GACP,WAAW;GACZ,CACF,CAC2C;;;;;;AC/9BlD,SAAgB,oBAAoB,KAAwB,QAA6B;AACvF,KAAI,CAAC,OAAO,YAAY,OAAO,SAAS,WAAW,KAAK,OAAO,SAAS,OAAO,OAAQ;AAEvF,KACE,OAAO,SAAS,SAAS,OAAO,IAChC,OAAO,YAAY,YACnB,OAAO,YAAY,OAEnB,uBAAsB,KAAK,OAAO;AAGpC,KAAI,OAAO,SAAS,SAAS,KAAK,CAChC,qBAAoB,KAAK,OAAO;;AAIpC,SAAS,sBAAsB,KAAwB,QAA6B;CAClF,MAAM,EAAE,KAAK,UAAU,YAAY;CACnC,MAAM,aAAa;AACnB,KAAI,CAAC,IAAI,OAAO,WAAW,IAAI,YAAY,OAAQ;AAEnD,KAAI,QAAQ,WAAW;EACrB,MAAME,OAAgC,CAAC,cAAc;AACrD,MAAI,aAAa,WAAY,MAAK,KAAK,YAAY;AACnD,uBAAqB;GAAE;GAAK,aAAa;GAAY,cAAc;GAAM,CAAC;YACjE,QAAQ,SACjB,sBAAqB;EAAE;EAAK,aAAa;EAAY,cAAc,CAAC,iBAAiB;EAAE,CAAC;UAC/E,QAAQ,WACjB,sBAAqB;EAAE;EAAK,aAAa;EAAY,cAAc,CAAC,WAAW;EAAE,CAAC;UACzE,QAAQ,UACjB,sBAAqB;EAAE;EAAK,aAAa;EAAY,cAAc,CAAC,UAAU;EAAE,CAAC;UACxE,QAAQ,SACjB,sBAAqB;EAAE;EAAK,aAAa;EAAY,cAAc,CAAC,SAAS;EAAE,CAAC;UACvE,QAAQ,WACjB,sBAAqB;EAAE;EAAK,aAAa;EAAY,cAAc,CAAC,kBAAkB;EAAE,CAAC;UAChF,QAAQ,YACjB,sBAAqB;EAAE;EAAK,aAAa;EAAY,cAAc,CAAC,YAAY;EAAE,CAAC;;AAIvF,SAAS,oBAAoB,KAAwB,QAA6B;CAChF,MAAM,EAAE,UAAU,SAAS,OAAO;CAElC,MAAM,aAAa;CACnB,MAAM,gBAAgB;CACtB,MAAM,gBAAgB;CACtB,MAAM,uBAAuB;CAE7B,MAAM,YAAY,IAAI,OAAO,WAAW;CACxC,MAAM,eAAe,IAAI,OAAO,cAAc;CAC9C,MAAM,eAAe,IAAI,OAAO,cAAc;CAC9C,MAAM,sBAAsB,IAAI,OAAO,qBAAqB;CAE5D,MAAM,cAAc,SAAS,MAAM,MACjC;EAAC;EAAgB;EAAmB;EAAQ;EAAiB,CAAC,SAAS,EAAE,CAC1E;CACD,MAAM,UAAU,SAAS,SAAS,OAAO;CACzC,MAAM,YAAY,SAAS,SAAS,SAAS;CAC7C,MAAM,iBAAiB,SAAS,MAAM,MACpC;EAAC;EAAe;EAAkB;EAAmB,CAAC,SAAS,EAAE,CAClE;CAGD,MAAM,YAAY,OAAO;CACzB,MAAM,eAAe,OAAO;CAC5B,MAAM,eAAe,OAAO;CAC5B,MAAM,kBAAkB,OAAO;CAC/B,MAAM,eAAe,OAAO;CAC5B,MAAM,iBAAiB,OAAO;AAE9B,KAAI,YAAY,YAAY,oBAC1B,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,oBAAoB;EACnC,oBAAoB;GAAE,IAAI;GAAY,kBAAkB;GAAW;EACpE,CAAC;UACO,YAAY,UAAU,UAC/B,KAAI,UACF,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,UAAU,eAAe;EACzC,CAAC;UACO,aACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;GAAC;GAAmB;GAA0B;GAAoB;EAChF,oBAAoB;GAAE,IAAI;GAAU,kBAAkB;GAAU,KAAK;GAAY;EAClF,CAAC;UACO,aACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;GAAC;GAAwB;GAAmB;GAA0B;EACrF,CAAC;UACO,gBACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,iBAAiB;EAChC,oBAAoB,EAAE,KAAK,YAAY;EACxC,CAAC;UACO,aACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,cAAc;EAC7B,oBAAoB,EAAE,KAAK,YAAY;EACxC,CAAC;UACO,eACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,cAAc;EAC9B,CAAC;KAEF,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;GAAC;GAAM;GAAkB;GAAmB;EAC3D,CAAC;UAEK,gBAAgB,YAAY,OACrC,KAAI,UACF,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,UAAU,eAAe;EACzC,CAAC;UACO,aACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;GAAC;GAAmB;GAA0B;GAAoB;EAChF,oBAAoB;GAAE,IAAI;GAAU,kBAAkB;GAAU,KAAK;GAAY;EAClF,CAAC;UACO,aACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;GAAC;GAAwB;GAAmB;GAA0B;EACrF,CAAC;UACO,gBACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,iBAAiB;EAChC,oBAAoB,EAAE,KAAK,YAAY;EACxC,CAAC;UACO,aACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,cAAc;EAC7B,oBAAoB,EAAE,KAAK,YAAY;EACxC,CAAC;UACO,eACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,cAAc;EAC9B,CAAC;KAEF,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;GAAC;GAAM;GAAkB;GAAmB;EAC3D,CAAC;AAIN,KAAI,WAAW;EACb,MAAMA,OAAgC,EAAE;AACxC,MAAI,YAAY,UACd;OAAI,YAAa,MAAK,KAAK,qBAAqB,aAAa;aACpD,WAET;OAAI,YAAa,MAAK,KAAK,iBAAiB,aAAa;aAChD,cAET;OAAI,YAAa,MAAK,KAAK,iBAAiB,aAAa;aAChD,cAGT;OAAI,YAAa,MAAK,KAAK,aAAa;aAC/B,iBAGT;OAAI,YAAa,MAAK,KAAK,aAAa;aAC/B,cAGT;OAAI,YAAa,MAAK,KAAK,aAAa;aAC/B,gBAGT;OAAI,YAAa,MAAK,KAAK,aAAa;SACnC;AACL,QAAK,KAAK,KAAK;AACf,OAAI,QAAS,MAAK,KAAK,cAAc;YAC5B,UAAW,MAAK,KAAK,iBAAiB;YACtC,YAAa,MAAK,KAAK,iBAAiB,aAAa;;AAEhE,MAAI,KAAK,SAAS,EAChB,sBAAqB;GAAE;GAAK,aAAa;GAAY,cAAc;GAAM,CAAC;;AAI9E,KAAI,gBAAgB,eAClB,KAAI,YAAY,SACd,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,oBAAoB;EACpC,CAAC;KAEF,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,MAAM,gBAAgB;EACtC,CAAC;;;;;AC9NR,MAAM,sBAAsB;CAAC;CAAmB;CAAgB;CAAkB;CAAO;AACzF,MAAM,mBAAmB;CAAC;CAAe;CAAkB;CAAmB;AAC9E,MAAMC,qBAAmB,CAAC,SAAS;AACnC,MAAMC,kBAAgB,CAAC,OAAO;AAC9B,MAAM,kBAAkB,CAAC,QAAQ;AACjC,MAAM,kBAAkB,CAAC,QAAQ;AACjC,MAAM,oBAAoB,CAAC,UAAU;AAGrC,MAAM,8BAA8B;CAAC;CAAQ;CAAkB;CAAS;CAAQ;CAAU;CAAQ;AAGlG,MAAMC,mBAA4C;CAChD;CACA;CACA;CACA;CACD;AAGD,MAAMC,qBAA8C;CAClD;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,sBAAsB,KAAwB,QAA6B;CACzF,MAAM,EAAE,eAAe;AAGvB,KAAI,CAAC,cAAc,eAAe,OAAQ;AAE1C,KAAI,eAAe,cACjB,wBAAuB,KAAK,OAAO;UAC1B,eAAe,WACxB,qBAAoB,KAAK,OAAO;UACvB,eAAe,OACxB,iBAAgB,KAAK,OAAO;;AAIhC,SAAS,uBAAuB,KAAwB,QAA6B;CACnF,MAAM,EAAE,UAAU,SAAS,qBAAqB;CAIhD,MAAM,aAAa;AACnB,KAAI,IAAI,OAAO,WAAW,IAAI,YAAY,UAAU,YAAY,SAC9D,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,cAAc;EAC9B,CAAC;CAIJ,MAAM,mBACJ,YAAY,UAAU,SAAS,MAAM,MAAM,4BAA4B,SAAS,EAAE,CAAC;CAGrF,MAAM,UAAU;AAChB,KAAI,IAAI,OAAO,QAAQ,EAAE;EACvB,MAAM,cAAc,SAAS,MAAM,MAAM,oBAAoB,SAAS,EAAE,CAAC;EACzE,MAAM,YAAY,SAAS,MAAM,MAAMH,mBAAiB,SAAS,EAAE,CAAC;EACpE,MAAM,SAAS,SAAS,MAAM,MAAMC,gBAAc,SAAS,EAAE,CAAC;EAC9D,MAAM,WAAW,SAAS,MAAM,MAAM,gBAAgB,SAAS,EAAE,CAAC;EAClE,MAAM,WAAW,SAAS,MAAM,MAAM,gBAAgB,SAAS,EAAE,CAAC;EAGlE,MAAMG,WAAoC,EAAE;AAC5C,MAAI,iBACF,UAAS,KAAK,cAAc;AAG9B,MAAI,YACF,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,GAAG,UAAU,qBAAqB;GAClD,CAAC;WACO,UACT,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,GAAG,UAAU,sBAAsB;GACnD,CAAC;WACO,OAET,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,GAAG,UAAU,oBAAoB;GACjD,CAAC;WACO,SACT,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,GAAG,UAAU,qBAAqB;GAClD,CAAC;WACO,UAET;OAAI,qBAAqB,QACvB,sBAAqB;IACnB;IACA,aAAa;IACb,cAAc,CAAC,GAAG,UAAU,qBAAqB;IAClD,CAAC;YACO,qBAAqB,MAC9B,sBAAqB;IACnB;IACA,aAAa;IACb,cAAc,CAAC,GAAG,UAAU,mBAAmB;IAChD,CAAC;YACO,qBAAqB,SAC9B,sBAAqB;IACnB;IACA,aAAa;IACb,cAAc,CAAC,GAAG,UAAU,sBAAsB;IACnD,CAAC;YACO,qBAAqB,QAC9B,sBAAqB;IACnB;IACA,aAAa;IACb,cAAc,CAAC,GAAG,UAAU,qBAAqB;IAClD,CAAC;YACO,SAAS,SAAS,EAE3B,sBAAqB;IACnB;IACA,aAAa;IACb,cAAc;IACf,CAAC;;;AAOR,KADkB,SAAS,MAAM,MAAM,iBAAiB,SAAS,EAAE,CAAC,EACrD;EACb,MAAM,aAAa;AACnB,MAAI,IAAI,OAAO,WAAW,CACxB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,oBAAoB;GACpC,CAAC;;;AAKR,SAAS,oBAAoB,KAAwB,QAA6B;CAChF,MAAM,EAAE,UAAU,qBAAqB;CAEvC,MAAM,UAAU;AAChB,KAAI,CAAC,IAAI,OAAO,QAAQ,CAAE;CAE1B,MAAM,cAAc,SAAS,MAAM,MAAM,oBAAoB,SAAS,EAAE,CAAC;CACzE,MAAM,YAAY,SAAS,MAAM,MAAMJ,mBAAiB,SAAS,EAAE,CAAC;CACpE,MAAM,SAAS,SAAS,MAAM,MAAMC,gBAAc,SAAS,EAAE,CAAC;CAC9D,MAAM,WAAW,SAAS,MAAM,MAAM,gBAAgB,SAAS,EAAE,CAAC;AAIlE,KAAI,YACF,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,GAAG,kBAAkB,iBAAiB;EACtD,CAAC;UACO,UACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,GAAG,kBAAkB,kBAAkB;EACvD,CAAC;UACO,OACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,GAAG,kBAAkB,eAAe;EACpD,CAAC;UACO,SAET,KAAI,qBAAqB,QACvB,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,GAAG,kBAAkB,iBAAiB;EACtD,CAAC;UACO,qBAAqB,MAC9B,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,GAAG,kBAAkB,eAAe;EACpD,CAAC;UACO,qBAAqB,SAC9B,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,GAAG,kBAAkB,kBAAkB;EACvD,CAAC;KAGF,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;EACf,CAAC;KAKJ,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;EACf,CAAC;;AAIN,SAAS,gBAAgB,KAAwB,QAA6B;CAC5E,MAAM,EAAE,UAAU,qBAAqB;CAEvC,MAAM,UAAU;AAChB,KAAI,CAAC,IAAI,OAAO,QAAQ,CAAE;CAE1B,MAAM,cAAc,SAAS,MAAM,MAAM,oBAAoB,SAAS,EAAE,CAAC;CACzE,MAAM,YAAY,SAAS,MAAM,MAAMD,mBAAiB,SAAS,EAAE,CAAC;CACpE,MAAM,SAAS,SAAS,MAAM,MAAMC,gBAAc,SAAS,EAAE,CAAC;CAC9D,MAAM,aAAa,SAAS,MAAM,MAAM,kBAAkB,SAAS,EAAE,CAAC;CACtE,MAAM,WAAW,SAAS,MAAM,MAAM,gBAAgB,SAAS,EAAE,CAAC;AAIlE,KAAI,YACF,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,GAAG,oBAAoB,cAAc;EACrD,CAAC;UACO,UACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,GAAG,oBAAoB,eAAe;EACtD,CAAC;UACO,OACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,GAAG,oBAAoB,YAAY;EACnD,CAAC;UACO,WACT,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,GAAG,oBAAoB,gBAAgB;EACvD,CAAC;UACO,SAET,KAAI,qBAAqB,QACvB,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,GAAG,oBAAoB,cAAc;EACrD,CAAC;UACO,qBAAqB,MAC9B,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,GAAG,oBAAoB,YAAY;EACnD,CAAC;UACO,qBAAqB,SAC9B,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,GAAG,oBAAoB,eAAe;EACtD,CAAC;KAGF,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;EACf,CAAC;KAKJ,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;EACf,CAAC;;;;;ACvSN,MAAMI,yBAAmC;CACvC;CACA;CACA;CACA;CACD;AAGD,MAAMC,sBAAgC;CAAC;CAAe;CAAkB;CAAmB;AAG3F,MAAMC,mBAA+B,CAAC,QAAQ;AAG9C,MAAMC,kBAA8B,CAAC,OAAO;AAE5C,SAAgB,iBAAiB,KAAwB,QAA6B;CACpF,MAAM,EAAE,OAAO,aAAa;AAG5B,KAAI,CAAC,SAAS,UAAU,OAAQ;CAGhC,MAAM,cAAc,SAAS,MAAM,MAAMC,uBAAqB,SAAS,EAAE,CAAC;CAC1E,MAAM,YAAY,SAAS,MAAM,MAAMC,oBAAkB,SAAS,EAAE,CAAC;CACrE,MAAM,WAAW,SAAS,MAAM,MAAM,iBAAiB,SAAS,EAAE,CAAC;CACnE,MAAM,UAAU,SAAS,MAAM,MAAM,gBAAgB,SAAS,EAAE,CAAC;CAGjE,MAAM,UAAU;AAChB,KAAI,eAAe,IAAI,OAAO,QAAQ,EAAE;EACtC,MAAM,OAAO,aAAa,OAAO,QAAQ;AACzC,MAAI,KAAK,SAAS,EAChB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACf,CAAC;;CAKN,MAAM,aAAa;AACnB,KAAI,aAAa,IAAI,OAAO,WAAW,EAAE;EACvC,MAAM,OAAO,aAAa,OAAO,QAAQ;AACzC,MAAI,KAAK,SAAS,EAChB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACf,CAAC;;AAKN,KAAI,YAAY,IAAI,OAAO,QAAQ,EAAE;EACnC,MAAM,OAAO,aAAa,OAAO,QAAQ;AACzC,MAAI,KAAK,SAAS,EAChB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACf,CAAC;;AAKN,KAAI,WAAW,IAAI,OAAO,QAAQ,EAAE;EAClC,MAAM,OAAO,aAAa,OAAO,OAAO;AACxC,MAAI,KAAK,SAAS,EAChB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACf,CAAC;;;AAKR,SAAS,aACP,OACA,QACyB;CACzB,MAAMC,OAAgC,EAAE;AAExC,SAAQ,OAAR;EACE,KAAK;AACH,OAAI,WAAW,QACb,MAAK,KAAK,UAAU,MAAM;AAE5B;EACF,KAAK;AACH,OAAI,WAAW,QACb,MAAK,KAAK,cAAc,mBAAmB;AAE7C;EACF,KAAK;AACH,OAAI,WAAW,QACb,MAAK,KAAK,qBAAqB,kBAAkB;AAEnD;EACF,KAAK;AACH,OAAI,WAAW,QACb,MAAK,KAAK,uBAAuB;YACxB,WAAW,OACpB,MAAK,KAAK,sBAAsB;AAElC;;AAKJ,QAAO;;;;;ACjHT,SAAgB,iBAAiB,KAAwB,QAA6B;CACpF,MAAM,YAAY;AAClB,KAAI,CAAC,IAAI,OAAO,UAAU,CAAE;CAE5B,MAAM,EAAE,cAAc,cAAc;AACpC,KAAI,iBAAiB,gBAAgB,cAAc,aACjD,sBAAqB;EAAE;EAAK,aAAa;EAAW,iBAAiB,CAAC,UAAU;EAAE,CAAC;;;;;ACNvF,SAAgB,oBAAoB,KAAwB,QAA6B;CACvF,MAAM,EAAE,UAAU,YAAY;AAG9B,KAAI,CAAC,YAAY,aAAa,OAAQ;AAGtC,KAAI,YAAY,UAAU,YAAY,SAAU;CAGhD,MAAM,aAAa;AACnB,KAAI,IAAI,OAAO,WAAW,EAAE;EAC1B,MAAM,OAAO,gBAAgB,SAAS;AACtC,MAAI,KAAK,SAAS,EAChB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACf,CAAC;;;AAKR,SAAS,gBAAgB,UAA8D;CACrF,MAAMC,OAAgC,EAAE;AAExC,SAAQ,UAAR;EACE,KAAK;AACH,QAAK,KAAK,SAAS;AACnB,QAAK,KAAK,UAAU;AACpB;EACF,KAAK;AACH,QAAK,KAAK,mBAAmB;AAC7B;EACF,KAAK;AACH,QAAK,KAAK,UAAU;AACpB;EACF,KAAK;AACH,QAAK,KAAK,qBAAqB;AAC/B,QAAK,KAAK,qBAAqB;AAC/B,QAAK,KAAK,uBAAuB;AACjC,QAAK,KAAK,uBAAuB;AACjC;;AAGJ,QAAO;;;;;AC7CT,SAAgB,mBAAmB,KAAwB,QAA6B;CACtF,MAAM,EAAE,SAAS,YAAY;AAC7B,KAAI,CAAC,WAAW,YAAY,OAAQ;AACpC,KAAI,YAAY,UAAU,YAAY,SAAU;CAEhD,MAAM,aAAa;AAGnB,KAAI,YAAY,UAAU,IAAI,OAAO,WAAW,CAC9C,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,QAAQ,YAAY;EACnC,iBAAiB,CAAC,cAAc;EACjC,CAAC;AAIJ,KAAI,YAAY,aAAa,IAAI,OAAO,WAAW,CACjD,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc,CAAC,UAAU;EAC1B,CAAC;;;;;ACvBN,SAAgB,yBAAyB,KAAwB,QAA6B;CAC5F,MAAM,EAAE,eAAe,YAAY;AACnC,KAAI,CAAC,iBAAiB,kBAAkB,OAAQ;AAChD,KAAI,YAAY,UAAU,YAAY,SAAU;CAEhD,MAAM,aAAa;AAGnB,KAAI,kBAAkB,mBAAmB,IAAI,OAAO,WAAW,CAC7D,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;GACZ;GACA;GACA;GACA;GACA;GACA;GACA;GACD;EACF,CAAC;;;;;ACrBN,SAAgB,oBAAoB,KAAwB,QAA6B;CACvF,MAAM,EAAE,UAAU,aAAa;AAC/B,KAAI,CAAC,YAAY,aAAa,OAAQ;CAEtC,MAAM,WAAW;CACjB,MAAM,UAAU;AAEhB,KAAI,aAAa,SAAS;AACxB,MAAI,IAAI,OAAO,SAAS,CACtB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,yBAAyB,gBAAgB;GACzD,CAAC;AAGJ,MAAI,IAAI,OAAO,QAAQ,EAYrB;OAXuB,SAAS,MAAM,MACpC;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACD,CAAC,SAAS,EAAE,CACd,CAEC,sBAAqB;IACnB;IACA,aAAa;IACb,cAAc,CAAC,wBAAwB;IACxC,CAAC;;;AAKR,KAAI,aAAa,UAAU;EACzB,MAAM,aAAa;AAGnB,MAAI,IAAI,OAAO,WAAW,CACxB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,SAAS;GACzB,CAAC;AAIJ,MAAI,IAAI,OAAO,SAAS,CACtB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,SAAS;GACzB,CAAC;AAIJ,MAAI,IAAI,OAAO,QAAQ,EAAE;GACvB,MAAM,cAAc,SAAS,MAAM,MACjC;IAAC;IAAgB;IAAmB;IAAkB;IAAO,CAAC,SAAS,EAAE,CAC1E;GACD,MAAM,cAAc,SAAS,MAAM,MAAM;IAAC;IAAQ;IAAU;IAAQ,CAAC,SAAS,EAAE,CAAC;AAEjF,OAAI,YAEF,sBAAqB;IACnB;IACA,aAAa;IACb,cAAc,CAAC,qBAAqB,0BAA0B;IAC/D,CAAC;YACO,YAET,sBAAqB;IACnB;IACA,aAAa;IACb,cAAc,CAAC,oBAAoB;IACpC,CAAC;;;AAKR,KAAI,aAAa,iBAAiB;EAChC,MAAM,aAAa;AAGnB,MAAI,IAAI,OAAO,WAAW,CACxB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,gCAAgC;GAChD,CAAC;AAIJ,MAAI,IAAI,OAAO,SAAS,CACtB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,gCAAgC;GAChD,CAAC;;AAIN,KAAI,aAAa,UAAU;EACzB,MAAM,aAAa;AAGnB,MAAI,IAAI,OAAO,WAAW,CACxB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,0BAA0B;GAC1C,CAAC;AAIJ,MAAI,IAAI,OAAO,SAAS,CACtB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,0BAA0B;GAC1C,CAAC;AAIJ,MAAI,IAAI,OAAO,QAAQ,EAarB;OAZuB,SAAS,MAAM,MACpC;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACD,CAAC,SAAS,EAAE,CACd,CAGC,sBAAqB;IACnB;IACA,aAAa;IACb,cAAc,CAAC,oBAAoB;IACpC,CAAC;;;AAKR,KAAI,aAAa,QAAQ;EACvB,MAAM,aAAa;AAGnB,MAAI,IAAI,OAAO,WAAW,CACxB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,eAAe;GAC/B,CAAC;AAIJ,MAAI,IAAI,OAAO,SAAS,CACtB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,eAAe;GAC/B,CAAC;AAIJ,MAAI,IAAI,OAAO,QAAQ,EAarB;OAZuB,SAAS,MAAM,MACpC;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACD,CAAC,SAAS,EAAE,CACd,CAGC,sBAAqB;IACnB;IACA,aAAa;IACb,cAAc,CAAC,wBAAwB;IACxC,CAAC;;;;;;;AC/LV,SAAgB,kBAAkB,KAAwB,QAA6B;CACrF,MAAM,EAAE,QAAQ,gBAAgB;AAEhC,KAAI,CAAC,OAAO,SAAS,MAAM,CAAE;CAE7B,MAAM,iBAAiB;AACvB,KAAI,CAAC,IAAI,OAAO,eAAe,CAAE;CAEjC,MAAM,UAAU,IAAI,SAAS,eAAe;CAS5C,MAAM,aARU,IAAI,QAAQ;EAC1B,uBAAuB;EACvB,sBAAsB;GACpB,iBAAiB,gBAAgB;GACjC,WAAW,UAAU;GACtB;EACF,CAAC,CAEyB,iBAAiB,kBAAkB,QAAQ;AAMtE,KAAI,CAJc,WACf,uBAAuB,CACvB,MAAM,QAAQ,IAAI,yBAAyB,KAAK,kBAAkB,CAGnE,YAAW,qBAAqB;EAC9B,cAAc,CAAC,UAAU;EACzB,iBAAiB;EAClB,CAAC;CAGJ,MAAM,mBAAmB,WAAW,qBAAqB,MAAM,CAAC,EAAE,gBAAgB,CAAC;AACnF,KAAI,CAAC,iBAAkB;CAEvB,MAAM,mBAAmB,iBAAiB,eAAe;AACzD,KACE,CAAC,KAAK,iBAAiB,iBAAiB,IACxC,iBAAiB,eAAe,CAAC,SAAS,KAAK,eAE/C;CAGF,IAAI,eAAe,iBAAiB,cAAc,CAAC;AACnD,KAAI,CAAC,aACH,gBAAe,iBAAiB,YAAY,KAAK;AAGnD,KAAI,KAAK,0BAA0B,aAAa,EAAE;EAChD,MAAM,kBAAkB,aAAa,YAAY,UAAU;EAE3D,MAAM,YAAY;;;aAGT,YAAY;mBACN,YAAY;oBACX,YAAY;;;;;;AAO5B,MAAI,mBAAmB,KAAK,qBAAqB,gBAAgB,EAAE;GACjE,MAAM,cAAc,gBAAgB,gBAAgB;AACpD,OAAI,KAAK,yBAAyB,YAAY,EAE5C;QAAI,CADW,YAAY,aAAa,CAAC,MAAM,OAAO,GAAG,SAAS,CAAC,WAAW,WAAW,CAAC,CAExF,aAAY,WAAW,UAAU;;QAIrC,cAAa,sBAAsB;GACjC,MAAM;GACN,aAAa,IAAI,UAAU;GAC5B,CAAC;;AAIN,KAAI,UAAU,gBAAgB,WAAW,aAAa,CAAC;;;;;AC/EzD,SAAgB,cAAc,KAAwB,QAA6B;CACjF,MAAM,UACJ,OAAO,cAAc,SAAS,0BAA0B,OAAO,GAAG,sBAAsB,OAAO;AACjG,KAAI,UAAU,aAAa,QAAQ;;AAGrC,SAAS,sBAAsB,SAAgC;CAC7D,MAAM,EACJ,aACA,gBACA,UACA,MACA,SAAS,EAAE,EACX,MAAM,WACN,UAAU,OACV,WAAW,CAAC,kBAAkB,EAC9B,UAAU,QACV,MAAM,QACN,WACA,cACA,YACE;CAEJ,MAAM,WAAW,YAAY;CAC7B,MAAM,iBAAiB,SAAS,SAAS,eAAe;CACxD,MAAM,YAAY,SAAS,MAAM,MAC/B;EAAC;EAAe;EAAkB;EAAmB,CAAC,SAAS,EAAE,CAClE;CACD,MAAM,YAAY,SAAS,SAAS,SAAS;CAC7C,MAAM,uBAAuB,GAAG,eAAe;CAC/C,MAAM,UAAU,kBAAkB,YAAY,SAAS;CAEvD,MAAM,mBAAmB,yBAAyB,UAAU,SAAS,KAAK,SAAS;AAEnF,QAAO,KAAK,YAAY;;2HAGtB,mBAAmB,kBAAkB,qBAAqB,GAC3D;;;;EAID,qBAAqB,UAAU,MAAM,QAAQ,KAAK,SAAS,UAAU,SAAS,IAAI,CAAC;;;;;;;EAOnF,eAAe;;EAGf,WACI;;;;;;EAMJ,qBAAqB;;;;;;EAOrB,SAAS,UACL;;;;;sDAMA,OAEA,sBAAsB,UAAU,sBAAsB,KAAK,SAAS,QAAQ,CACjF;;;;;EAKC,qBAAqB;;;EAGrB,4BAA4B,UAAU,SAAS,SAAS,WAAW,SAAS,CAAC;EAE7E,OAAO,SAAS,MAAM,IAAI,iBACtB,sLACA,GACL;EACC,2BAA2B,sBAAsB,WAAW,aAAa,CAAC;EAC1E,wBAAwB,sBAAsB,OAAO,CAAC;;;;;EAKtD,yBAAyB,aAAa,UAAU,SAAS,QAAQ,UAAU,KAAK,KAAK,CAAC;;;;;EAKtF,oBAAoB,sBAAsB,UAAU,KAAK,WAAW,QAAQ,SAAS,QAAQ,CAAC;;;AAIhG,SAAS,yBACP,UACA,SACA,KACA,UACQ;CACR,MAAMC,QAAkB,EAAE;CAE1B,MAAMC,cAAsC;EAC1C,mBAAmB;EACnB,gBAAgB;EAChB,MAAM;EACN,kBAAkB;EAClB,QAAQ;EACR,MAAM;EACN,OAAO;EACR;AAED,MAAK,MAAM,MAAM,SACf,KAAI,YAAY,KAAK;AACnB,QAAM,KAAK,YAAY,IAAI;AAC3B;;AAIJ,KAAI,YAAY,OACd,OAAM,MAAM,QAAQ,IAAI,aAAa,IAAI,MAAM,QAAQ,MAAM,EAAE,CAAC;AAGlE,KAAI,CAAC,YAAY,QAAQ,OACvB,OAAM,KAAK,IAAI,aAAa,CAAC;AAG/B,QAAO,MAAM,SAAS,IAAI,GAAG,MAAM,KAAK,KAAK,CAAC,cAAc;;AAG9D,SAAS,4BACP,UACA,SACA,SACA,WACA,UACQ;CACR,MAAMC,eAAyB,EAAE;CACjC,MAAM,cAAc,SAAS,SAAS,KAAK,CAAC,SAAS,SAAS,OAAO;CACrE,MAAM,gBAAgB,YAAY;AAElC,KAAI,aAAa;EACf,MAAM,OAAO,gBAAgB,0BAA0B;AACvD,eAAa,KACX,0BAA0B,QAAQ,qBAAqB,QAAQ,+BAA+B,KAAK,GACpG;;AAGH,KAAI,UACF,cAAa,KAAK,qDAAqD;AAGzE,KAAI,SACF,cAAa,KAAK,mEAAmE;UAC5E,YAAY,UAAU,CAAC,cAChC,cAAa,KAAK,wEAAwE;AAG5F,QAAO,aAAa,KAAK,KAAK;;AAGhC,SAAS,yBACP,aACA,UACA,SACA,QACA,UACA,KACA,MACQ;CACR,MAAMC,YAAsB,CAAC,GAAG,YAAY,IAAI,YAAY;CAC5D,MAAM,cAAc,SAAS,SAAS,KAAK,CAAC,SAAS,SAAS,OAAO;CACrE,MAAM,gBAAgB,YAAY;CAClC,MAAM,YAAY,SAAS,MAAM,MAC/B;EAAC;EAAe;EAAkB;EAAmB,CAAC,SAAS,EAAE,CAClE;AAED,KAAI,aAAa;EACf,MAAMC,gBAAwC;GAC5C,mBAAmB;GACnB,gBAAgB;GAChB,MAAM;GACN,kBAAkB;GAClB,QAAQ;GACR,MAAM;GACN,OAAO;GACR;EACD,MAAM,eAAe,SAAS,MAAM,MAAM,cAAc,GAAG,GACvD,cAAc,SAAS,MAAM,MAAM,cAAc,GAAG,IAAI,MACxD;EAEJ,MAAM,SAAS,gBAAgB,QAAQ;EACvC,MAAM,OAAO,gBAAgB,0BAA0B;AACvD,YAAU,KAAK,OAAO,OAAO,kBAAkB,KAAK,IAAI,aAAa,GAAG;;AAG1E,KAAI,UACF,WAAU,KAAK,iEAAiE;AAGlF,KAAI,OAAO,SAAS,YAAY,CAC9B,WAAU,KAAK,8DAA8D;AAG/E,KAAI,CAAC,iBAAiB,YAAY,UAAU,CAAC,UAAU;EACrD,MAAM,eAAe,QAAQ,IAAI,aAAa,IAAI,MAAM,QAAQ,MAAM,EAAE;EACxE,MAAM,UAAU,QAAQ,SAAS,IAAI,aAAa,GAAG;EACrD,MAAM,OAAO,UAAU,GAAG,YAAY,IAAI,YAAY;AACtD,YAAU,KAAK,uCAAuC,KAAK,GAAG;;AAGhE,KAAI,YAAY,YAAY,QAAQ;AAClC,YAAU,KAAK,gBAAgB;AAE/B,MAAI,UAAU;AACZ,aAAU,KAAK,6DAA6D;AAC5E,OAAI,SAAS,QACX,WAAU,KACR,wDACA,wDACD;;AAIL,MAAI,CAAC,UAAU;AACb,aAAU,KAAK,oDAAoD;AACnE,OAAI,SAAS,OACX,WAAU,KAAK,8DAA8D;AAE/E,OAAI,QAAQ,UAAU,SAAS,OAC7B,WAAU,KAAK,mDAAmD;;;AAKxE,QAAO,UAAU,KAAK,KAAK;;AAG7B,SAAS,qBACP,UACA,MACA,QACA,KACA,SACA,UACA,SACA,KACQ;CACR,MAAM,WAAW,YAAY;CAC7B,MAAM,YAAY,SAAS,MAAM,MAC/B;EAAC;EAAe;EAAkB;EAAmB,CAAC,SAAS,EAAE,CAClE;CACD,MAAM,cAAc,SAAS,SAAS,KAAK,CAAC,SAAS,SAAS,OAAO;CAErE,MAAM,WAAW,CAAC,uEAAuE;CAEzF,MAAMC,mBAA2C;EAC/C,mBAAmB;EACnB,gBAAgB;EAChB,MAAM;EACN,kBAAkB;EAClB,QAAQ;EACR,MAAM;EACN,OAAO;EACR;AAED,MAAK,MAAM,MAAM,SACf,KAAI,iBAAiB,KAAK;AACxB,WAAS,KAAK,iBAAiB,IAAI;AACnC;;AAIJ,KAAI,UACF,UAAS,KACP,sDACA,kDACD;AAGH,KAAI,YACF,UAAS,KACP,kEACA,2CACD;CAGH,MAAMC,kBAA0C;EAC9C,QAAQ;EACR,MAAM;EACN,SAAS;EACT,SAAS;EACT,QAAQ;EACT;AAED,KAAI,gBAAgB,SAClB,UAAS,KAAK,gBAAgB,SAAS;AAGzC,KAAI,CAAC,YAAY,QAAQ,OACvB,UAAS,KAAK,yCAAyC;UAC9C,CAAC,YAAY,QAAQ,OAC9B,UAAS,KAAK,kEAAkE;AAGlF,KAAI,CAAC,YAAY,YAAY,UAAU,YAAY,QAAQ;EACzD,MAAM,cAAc,YAAY,QAAQ,QAAQ,YAAY,SAAS,YAAY;AACjF,WAAS,KAAK,OAAO,YAAY,0BAA0B;;AAG7D,KAAI,aAAa,UAAU,CAAC,SAY1B,UAAS,KACP,OAZuC;EACvC,SAAS;EACT,QAAQ;EACR,UAAU;EACX,CAQiB,QAAQ,MAAM,4BAC9B,OARsC;EACtC,QAAQ;EACR,UAAU;EACV,OAAO;EACP,SAAS;EACV,CAGgB,aAAa,WAAW,sBACxC;AAGH,KAAI,SAAS,QAAQ;EACnB,MAAM,YAAY,SAAS,UAAU,UAAU;AAC/C,WAAS,KAAK,0BAA0B,YAAY;;CAGtD,MAAMC,gBAAwC;EAC5C,KAAK;EACL,OAAO;EACP,OAAO;EACP,QAAQ;EACR,OAAO;EACP,WAAW;EACX,WAAW;EACZ;AAED,MAAK,MAAM,SAAS,OAClB,KAAI,cAAc,OAChB,UAAS,KAAK,cAAc,OAAO;AAIvC,QAAO,SAAS,KAAK,KAAK;;AAG5B,SAAS,sBACP,UACA,sBACA,KACA,SACA,SACQ;AACR,KAAI,aAAa,OAAQ,QAAO;CAEhC,MAAM,gBAAgB,YAAY;CAClC,MAAM,UAAU,gBAAgB,kBAAkB;CAClD,MAAM,UACJ,QAAQ,YAAY,sBAAsB,QAAQ,WAAW,iBAAiB,SAAS;CAEzF,IAAI,QAAQ;CAEZ,MAAMC,iBAAyC;EAC7C,QAAQ,2BAA2B,QAAQ;;;EAI7C,YAAY,OACR,oGACA;EACJ,qBAAqB;QAEtB;;wCAEuC,gBAAgB,aAAa,cAAc;EAE/E,UAAU,+BAA+B,QAAQ;;;mBAGlC,QAAQ;EAEvB,OAAO,0BAA0B,QAAQ;;;mBAG1B,QAAQ;EAEvB,SAAS,6BAA6B,QAAQ,QAAQ,UAAU,QAAQ,CAAC;;;mBAG1D,QAAQ;EACxB;AAED,UAAS,eAAe,aAAa;AAErC,UAAS;;;;EAIT,qBAAqB;;;AAIrB,QAAO;;AAGT,SAAS,oBACP,sBACA,UACA,KACA,WACA,QACA,SACA,SACQ;CACR,MAAM,WAAW,YAAY;CAC7B,MAAM,gBAAgB,YAAY;CAElC,IAAI,UAAU,OAAO,qBAAqB;MACtC,qBAAqB;AAEzB,KAAI,CAAC,cACH,YAAW,SAAS,qBAAqB;AAG3C,KAAI,SACF,YAAW,SAAS,qBAAqB;UAChC,YAAY,UAAU,CAAC,cAChC,YAAW,SAAS,qBAAqB;AAG3C,YAAW,SAAS,qBAAqB;AAEzC,KAAI,UACF,YAAW,SAAS,qBAAqB;AAG3C,KAAI,aAAa,UAAU,CAAC,UAAU;AACpC,aAAW,SAAS,qBAAqB;MACvC,qBAAqB;AAEvB,MAAI,aAAa,YAAY,YAAY,KACvC,YAAW,SAAS,qBAAqB;;AAI7C,KAAI,OAAO,SAAS,QAAQ,CAC1B,YAAW,SAAS,qBAAqB;AAG3C,KAAI,OAAO,SAAS,SAAS,CAC3B,YAAW,SAAS,qBAAqB;AAG3C,KAAI,OAAO,SAAS,MAAM,CACxB,YAAW,wBAAwB,qBAAqB;AAG1D,KAAI,OAAO,SAAS,QAAQ,CAC1B,YAAW,wBAAwB,qBAAqB;qBACvC,qBAAqB;AAGxC,KAAI,OAAO,SAAS,YAAY,CAC9B,YAAW,yBAAyB,qBAAqB;sBACvC,qBAAqB;AAGzC,QAAO;;AAGT,SAAS,2BACP,sBACA,WACA,cACQ;AACR,KAAI,cAAc,gBAAgB,iBAAiB,aACjD,QAAO;CAGT,MAAMC,QAAkB,CAAC,yCAAyC;AAElE,KAAI,cAAc,gBAAgB,iBAAiB,aACjD,OAAM,KACJ,yBAAyB,qBAAqB,eAC9C,4BAA4B,qBAAqB,UACjD,6BAA6B,qBAAqB,UACnD;AAGH,KAAI,iBAAiB,gBAAgB,cAAc,aACjD,OAAM,KACJ,4BAA4B,qBAAqB,OACjD,+BAA+B,qBAAqB,UACpD,gCAAgC,qBAAqB,UACtD;AAGH,KAAI,cAAc,gBAAgB,iBAAiB,aACjD,OAAM,KACJ,UAAU,qBAAqB,OAC/B,aAAa,qBAAqB,UAClC,cAAc,qBAAqB,UACpC;AAGH,OAAM,KACJ,IACA,4IACD;AAED,QAAO,GAAG,MAAM,KAAK,KAAK,CAAC;;AAG7B,SAAS,wBACP,sBACA,QACQ;CACR,MAAM,WAAW,OAAO,SAAS,QAAQ;CACzC,MAAM,aAAa,OAAO,SAAS,QAAQ,IAAI,OAAO,SAAS,SAAS;AAExE,KAAI,CAAC,YAAY,CAAC,WAChB,QAAO;CAGT,MAAMA,QAAkB,CAAC,+BAA+B,GAAG;AAE3D,KAAI,SACF,OAAM,KAAK,yBAAyB,qBAAqB,YAAY;AAGvE,KAAI,WACF,OAAM,KAAK,4BAA4B,qBAAqB,UAAU;AAGxE,QAAO,GAAG,MAAM,KAAK,KAAK,CAAC;;AAG7B,SAAS,0BAA0B,QAA+B;CAChE,MAAM,EAAE,aAAa,kBAAkB,cAAc,SAAS,SAAS,SAAS,kBAC9E;CAEF,MAAMC,WAAqB,CAAC,iEAAiE;AAG7F,KAAI,qBAAqB,OACvB,UAAS,KAAK,iEAAiE;UACtE,qBAAqB,YAC9B,UAAS,KAAK,0EAA0E;AAI1F,KAAI,iBAAiB,UAAU;AAC7B,WAAS,KAAK,kEAAkE;AAChF,WAAS,KAAK,mEAAmE;YACxE,iBAAiB,UAAU;AACpC,WAAS,KAAK,qEAAqE;AACnF,WAAS,KAAK,mEAAmE;;AAInF,KAAI,YAAY,UACd,UAAS,KAAK,+DAA+D;UACpE,YAAY,OACrB,UAAS,KAAK,mEAAmE;AAInF,KAAI,YAAY,QACd,UAAS,KAAK,qDAAqD;UAC1D,YAAY,gBACrB,UAAS,KAAK,wDAAwD;AAIxE,KAAI,YAAY,OACd,UAAS,KAAK,sDAAsD;UAC3D,YAAY,UACrB,UAAS,KAAK,kDAAkD;CAIlE,MAAM,OAAO,MAAM,QAAQ,cAAc,GAAG,gBAAgB,EAAE;AAC9D,KAAI,KAAK,SAAS,YAAY,CAC5B,UAAS,KAAK,4CAA4C;AAE5D,KAAI,KAAK,SAAS,eAAe,CAC/B,UAAS,KAAK,6CAA6C;AAE7D,KAAI,KAAK,SAAS,SAAS,CACzB,UAAS,KAAK,yCAAyC;AAEzD,KAAI,KAAK,SAAS,aAAa,CAC7B,UAAS,KAAK,6CAA6C;CAI7D,MAAMP,YAAsB,CAAC,GAAG,YAAY,IAAI,iDAAiD;AAEjG,KAAI,iBAAiB,SACnB,WAAU,KACR,eACA,kDACA,0BACA,2BACA,oDACA,0BACA,kDACA,0BACA,0BACA,6BACD;UACQ,iBAAiB,SAC1B,WAAU,KACR,eACA,kDACA,0BACA,2BACA,oDACA,0BACA,iDACA,2BACA,8BACD;KAED,WAAU,KACR,eACA,kDACA,0BACA,0BACD;AAGH,WAAU,KACR,mDACA,qDACA,iBACD;CAGD,IAAI,UAAU;;;;;AAMd,KAAI,iBAAiB,SACnB,YAAW;;;UAGF,iBAAiB,SAC1B,YAAW;;;AAKb,QAAO,KAAK,YAAY;;;;;;EAMxB,SAAS,KAAK,KAAK,CAAC;;;;;EAKpB,iBAAiB,WAAW,mLAAmL,KAAK,iBAAiB,WAAW,yNAAyN,GAAG;;;;;;;;;;;;;;;;EAgB5c,qBAAqB,SAAS,sFAAsF,GAAG;;EAGvH,iBAAiB,WACb;;;;;;;;;;IAWA,KAEF,iBAAiB,WACb;;;;;;;;;;IAWA,GACL;;;;EAID,UAAU,KAAK,KAAK,CAAC;;;;;EAKrB,QAAQ;;;;;;AC/tBV,MAAMQ,yBAAmC;CACvC;CACA;CACA;CACA;CACD;AAGD,MAAMC,sBAAgC;CAAC;CAAe;CAAkB;CAAmB;AAE3F,SAAgB,oBAAoB,KAAwB,QAA6B;CACvF,MAAM,EAAE,UAAU,UAAU,YAAY;AAGxC,KAAI,CAAC,YAAY,aAAa,OAAQ;AAGtC,KAAI,YAAY,UAAU,YAAY,SAAU;CAGhD,MAAM,cAAc,SAAS,MAAM,MAAMC,uBAAqB,SAAS,EAAE,CAAC;CAC1E,MAAM,YAAY,SAAS,MAAM,MAAMC,oBAAkB,SAAS,EAAE,CAAC;CAGrE,MAAM,aAAa;AACnB,KAAI,IAAI,OAAO,WAAW,EAAE;EAC1B,MAAM,OAAO,sBAAsB,SAAS;AAC5C,MAAI,KAAK,SAAS,EAChB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACf,CAAC;;CAKN,MAAM,UAAU;AAChB,KAAI,eAAe,IAAI,OAAO,QAAQ,EAAE;EACtC,MAAM,OAAO,sBAAsB,SAAS;AAC5C,MAAI,KAAK,SAAS,EAChB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACf,CAAC;;CAKN,MAAM,aAAa;AACnB,KAAI,aAAa,IAAI,OAAO,WAAW,EAAE;EACvC,MAAM,OAAO,sBAAsB,SAAS;AAC5C,MAAI,KAAK,SAAS,EAChB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACf,CAAC;;;AAKR,SAAS,sBAAsB,UAA8D;CAC3F,MAAMC,OAAgC,EAAE;AAExC,SAAQ,UAAR;EACE,KAAK;AACH,QAAK,KAAK,YAAY;AACtB;EACF,KAAK;AACH,QAAK,KAAK,WAAW;AACrB;EACF,KAAK;AACH,QAAK,KAAK,OAAO;AACjB;EACF,KAAK;AACH,QAAK,KAAK,SAAS;AACnB;EACF,KAAK;AACH,QAAK,KAAK,mBAAmB;AAC7B;EACF,KAAK;AACH,QAAK,KAAK,MAAM;AAChB,QAAK,KAAK,cAAc;AACxB,QAAK,KAAK,cAAc;AACxB,QAAK,KAAK,eAAe;AACzB;;AAGJ,QAAO;;AAGT,SAAS,sBAAsB,UAA8D;CAC3F,MAAMA,OAAgC,EAAE;AAExC,SAAQ,UAAR;EACE,KAAK;AACH,QAAK,KAAK,mBAAmB;AAC7B;EACF,KAAK;AACH,QAAK,KAAK,cAAc;AACxB;EACF,KAAK;AAEH,QAAK,KAAK,OAAO;AACjB;EACF,KAAK;AACH,QAAK,KAAK,YAAY;AACtB;EACF,KAAK;AACH,QAAK,KAAK,qBAAqB;AAC/B,QAAK,KAAK,oBAAoB;AAC9B;EACF,KAAK;AACH,QAAK,KAAK,MAAM;AAChB,QAAK,KAAK,cAAc;AACxB,QAAK,KAAK,iBAAiB;AAC3B;;AAGJ,QAAO;;;;;ACrHT,SAAgB,mBAAmB,KAAwB,QAA6B;CACtF,MAAM,EAAE,SAAS,YAAY;AAE7B,KACE,YAAY,YACZ,YAAY,UACZ,YAAY,YACZ,YAAY,cACZ,YAAY,WACZ,YAAY,OAEZ;CAEF,MAAM,aAAa;AACnB,KAAI,CAAC,IAAI,OAAO,WAAW,CAAE;CAE7B,MAAM,UAAU,IAAI,SAAsB,WAAW;AACrD,KAAI,CAAC,QAAS;AAEd,SAAQ,UAAU,QAAQ,WAAW,EAAE;AAEvC,KAAI,YAAY,OAAO;AACrB,UAAQ,QAAQ,MAAM;AACtB,UAAQ,QAAQ,QAAQ;AAExB,uBAAqB;GACnB;GACA,aAAa;GACb,iBAAiB,CAAC,aAAa;GAChC,CAAC;YACO,YAAY,QAAQ;AAC7B,UAAQ,QAAQ,MAAM;AACtB,UAAQ,QAAQ,QAAQ;AAExB,uBAAqB;GACnB;GACA,aAAa;GACb,iBAAiB,CAAC,OAAO,cAAc;GACxC,CAAC;AAEF,MAAI,YAAY,OACd,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,oBAAoB;GACpC,CAAC;WACO,YAAY,SACrB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc,CAAC,iBAAiB;GACjC,CAAC;;AAIN,KAAI,UAAU,YAAY,QAAQ;;;;;AC3DpC,MAAMC,uBAAmC;CACvC;CACA;CACA;CACA;CACD;AAGD,MAAMC,oBAAgC;CAAC;CAAe;CAAkB;CAAmB;AAE3F,SAAgB,2BAA2B,KAAwB,QAA6B;CAC9F,MAAM,EAAE,iBAAiB,aAAa;AAGtC,KAAI,CAAC,mBAAmB,oBAAoB,OAAQ;CAGpD,MAAM,cAAc,SAAS,MAAM,MAAM,qBAAqB,SAAS,EAAE,CAAC;CAC1E,MAAM,YAAY,SAAS,MAAM,MAAM,kBAAkB,SAAS,EAAE,CAAC;CAGrE,MAAM,UAAU;AAChB,KAAI,eAAe,IAAI,OAAO,QAAQ,EAAE;EACtC,MAAM,OAAO,uBAAuB,iBAAiB,MAAM;AAC3D,MAAI,KAAK,SAAS,EAChB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACf,CAAC;;CAKN,MAAM,aAAa;AACnB,KAAI,aAAa,IAAI,OAAO,WAAW,EAAE;EACvC,MAAM,OAAO,uBAAuB,iBAAiB,SAAS;AAC9D,MAAI,KAAK,SAAS,EAChB,sBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACf,CAAC;;;AAKR,SAAS,uBACP,iBACA,SACyB;CACzB,MAAMC,OAAgC,EAAE;AAExC,SAAQ,iBAAR;EACE,KAAK;AACH,QAAK,KAAK,UAAU;AACpB;EACF,KAAK;AACH,QAAK,KAAK,QAAQ;AAClB;EACF,KAAK;AACH,QAAK,KAAK,cAAc,oBAAoB;AAC5C;EACF,KAAK;AACH,QAAK,KAAK,oBAAoB,cAAc;AAC5C;EACF,KAAK;AACH,QAAK,KAAK,QAAQ,kBAAkB;AACpC;EACF,KAAK;AACH,QAAK,KAAK,UAAU,gBAAgB;AACpC;EACF,KAAK;AACH,QAAK,KAAK,SAAS;AACnB;EACF,KAAK;AACH,QAAK,KAAK,mBAAmB,wBAAwB;AACrD;EACF,KAAK;AACH,QAAK,KAAK,oBAAoB,yBAAyB;AACvD;;AAGJ,QAAO;;;;;ACnFT,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAGD,MAAM,gBAAgB,CAAC,OAAO;AAG9B,MAAM,mBAAmB,CAAC,SAAS;;;;;;;;;;;;;;AAenC,SAAgB,mBAAmB,KAAwB,QAA6B;CACtF,MAAM,EAAE,SAAS,UAAU,qBAAqB;AAGhD,KAAI,CAAC,WAAW,YAAY,OAAQ;CAEpC,MAAM,WAAW;EACf,QAAQ,IAAI,OAAO,2BAA2B;EAC9C,KAAK,IAAI,OAAO,wBAAwB;EACxC,KAAK,IAAI,OAAO,4BAA4B;EAC7C;CAGD,MAAM,EAAE,SAAS,aAAa,eAAe,QAAQ;CAGrD,MAAM,qBAAqB,sBAAsB,SAAS,UAAU,iBAAiB;AAGrF,KAAI,SAAS,UAAU,SAAS,SAAS,EACvC,sBAAqB;EACnB;EACA,aAAa;EACb,iBAAiB;EAClB,CAAC;AAIJ,KAAI,SAAS,KAAK;EAChB,MAAM,UAAU,CAAC,GAAG,UAAU,GAAG,mBAAmB;AACpD,MAAI,QAAQ,SAAS,EACnB,sBAAqB;GACnB;GACA,aAAa;GACb,iBAAiB;GAClB,CAAC;;AAKN,KAAI,SAAS,OAAO,SAAS,SAAS,EACpC,sBAAqB;EACnB;EACA,aAAa;EACb,iBAAiB;EAClB,CAAC;;;;;AAON,SAAS,eAAe,SAEtB;CACA,MAAMC,UAAmC,EAAE;AAE3C,SAAQ,SAAR;EACE,KAAK;AACH,WAAQ,KAAK,UAAU,cAAc,uBAAuB,QAAQ;AACpE;EACF,KAAK;AACH,WAAQ,KAAK,QAAQ,eAAe,WAAW,iBAAiB,yBAAyB;AACzF;EACF,KAAK;AACH,WAAQ,KAAK,oBAAoB,aAAa;AAC9C;EACF,KAAK;AACH,WAAQ,KACN,UACA,cACA,uBACA,SACA,oBACA,aACD;AACD;EACF,KAAK;AACH,WAAQ,KAAK,UAAU;AACvB;;AAGJ,QAAO,EAAE,SAAS;;;;;;;AAQpB,SAAS,sBACP,SACA,UACA,kBACyB;AAEzB,KAAI,CAAC,WAAW,CAAC;EAAC;EAAU;EAAQ;EAAoB,CAAC,SAAS,QAAQ,CACxE,QAAO,EAAE;CAGX,MAAMC,OAAgC,EAAE;CAGxC,MAAM,oBAAoB;AACxB,OAAK,KAAK,wBAAwB,8BAA8B;AAGhE,MAAI,YAAY,OACd,MAAK,KAAK,4BAA4B;WAC7B,YAAY,YAAY,YAAY,oBAC7C,MAAK,KAAK,4BAA4B;;AAK1C,KAAI,gBAAgB,UAAU,iBAAiB,EAAE;AAC/C,eAAa;AACb,OAAK,KAAK,yBAAyB;YAC1B,cAAc,SAAS,EAAE;AAClC,eAAa;AACb,OAAK,KAAK,uBAAuB;YACxB,iBAAiB,UAAU,iBAAiB,EAAE;AACvD,eAAa;AACb,OAAK,KAAK,0BAA0B;;AAGtC,QAAO;;;;;AAMT,SAAS,gBACP,UACA,kBACS;AACT,KAAI,CAAC,YAAY,SAAS,WAAW,EAAG,QAAO;AAG/C,QAAO,SAAS,MAAM,MAAM;AAE1B,MAAI,MAAM,WAAW,qBAAqB,QACxC,QAAO;AAIT,MAAI,MAAM,QACR,QAAO;AAGT,SAAQ,gBAAsC,SAAS,EAAE;GACzD;;;;;AAMJ,SAAS,cAAc,UAA8C;AACnE,KAAI,CAAC,YAAY,SAAS,WAAW,EAAG,QAAO;AAC/C,QAAO,SAAS,MAAM,MAAO,cAAoC,SAAS,EAAE,CAAC;;;;;AAM/E,SAAS,iBACP,UACA,kBACS;AACT,KAAI,CAAC,YAAY,SAAS,WAAW,EAAG,QAAO;AAE/C,QAAO,SAAS,MAAM,MAAM;AAE1B,MAAI,MAAM,WAAW,qBAAqB,SACxC,QAAO;AAGT,SAAQ,iBAAuC,SAAS,EAAE;GAC1D;;;;;ACjMJ,SAAgB,mBAAmB,KAAwB,QAA6B;AACtF,KAAI,CAAC,OAAO,OAAO,SAAS,YAAY,CAAE;CAE1C,MAAM,cAAc,oBAAoB,OAAO;AAC/C,KAAI,UAAU,cAAc,KAAK,UAAU,aAAa,MAAM,IAAK,CAAC;;AAGtE,SAAS,oBAAoB,QAAoC;CAC/D,MAAM,EAAE,SAAS,UAAU,KAAK,SAAS,WAAW,cAAc,aAAa;CAE/E,MAAM,WAAW,YAAY;CAC7B,MAAM,cAAc,aAAa,UAAU,QAAQ;CACnD,MAAM,WAAW,YAAY;CAC7B,MAAM,gBAAgB,aAAa,YAAY,YAAY;CAC3D,MAAM,gBAAgB,cAAc,gBAAgB,iBAAiB;AAWrE,QAAO;EACL,SAAS;EACT,IAAI;EACJ,OAZuC;GACvC,GAAG,aAAa,SAAS;GACzB,GAAI,WAAW,gBAAgB,GAAG,EAAE;GACpC,GAAI,CAAC,YAAY,cAAc,kBAAkB,GAAG,EAAE;GACtD,GAAI,WAAW,gBAAgB,GAAG,EAAE;GACpC,GAAI,gBAAgB,oBAAoB,GAAG,EAAE;GAC7C,GAAI,gBAAgB,gBAAgB,GAAG,EAAE;GAC1C;EAMA;;AAGH,SAAS,aAAa,UAA+C;CAKnE,MAAM,eAAe,CAAC,UAAU;AAEhC,KAAI,SAAS,SAAS,OAAO,CAC3B,cAAa,KAAK,WAAW;AAG/B,KAAI,SAAS,SAAS,OAAO,CAC3B,cAAa,KAAK,YAAY,aAAa;AAI7C,KAAI,SAAS,SAAS,SAAS,CAC7B,cAAa,KAAK,kBAAkB,WAAW;AAGjD,QAAO;EACL,OAAO;GACL,WAAW,CAAC,SAAS;GACrB,QAAQ,CAAC,mBAAmB,QAAQ;GACpC,SAAS;GACV;EACD,MAAM,EACJ,WAAW,CAAC,QAAQ,EACrB;EACD,eAAe,EACb,WAAW,CAAC,eAAe,EAC5B;EACD,KAAK;GACH,OAAO;GACP,YAAY;GACb;EACF;;AAGH,SAAS,iBAA4C;AACnD,QAAO,EACL,aAAa;EACX,OAAO;EACP,YAAY;EACb,EACF;;AAGH,SAAS,mBAA8C;AACrD,QAAO;EACL,WAAW,EACT,OAAO,OACR;EACD,aAAa;GACX,OAAO;GACP,YAAY;GACb;EACD,cAAc,EACZ,OAAO,OACR;EACD,eAAe,EACb,OAAO,OACR;EACF;;AAGH,SAAS,iBAA4C;AACnD,QAAO;EACL,YAAY;GACV,OAAO;GACP,YAAY;GACb;EACD,WAAW,EACT,OAAO,OACR;EACD,YAAY;GACV,OAAO;GACP,YAAY;GACb;EACD,WAAW,EACT,OAAO,OACR;EACF;;AAGH,SAAS,qBAAgD;AACvD,QAAO,EACL,YAAY,EACV,OAAO,OACR,EACF;;AAGH,SAAS,iBAA4C;AACnD,QAAO;EACL,QAAQ,EACN,OAAO,OACR;EACD,SAAS,EACP,OAAO,OACR;EACF;;;;;;;;;;;;AC/IH,SAAgB,sBAAsB,KAAwB,QAA6B;CACzF,MAAM,EAAE,eAAe;AAGvB,KAAI,CAAC,cAAc,eAAe,UAAU,eAAe,MAAO;CAElE,MAAM,WAAW;EACf,KAAK,IAAI,OAAO,4BAA4B;EAC5C,QAAQ,IAAI,OAAO,2BAA2B;EAC9C,KAAK,IAAI,OAAO,wBAAwB;EACxC,QAAQ,IAAI,OAAO,2BAA2B;EAC/C;CAED,MAAM,OAAO,kBAAkB,WAAW;AAC1C,KAAI,KAAK,WAAW,EAAG;AAGvB,KAAI,SAAS,IACX,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;EACf,CAAC;AAIJ,KAAI,SAAS,OACX,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;EACf,CAAC;AAIJ,KAAI,SAAS,IACX,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;EACf,CAAC;AAIJ,KAAI,SAAS,OACX,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;EACf,CAAC;;AAIN,SAAS,kBAAkB,YAAkE;CAC3F,MAAMC,OAAgC,EAAE;AAExC,SAAQ,YAAR;EACE,KAAK;AACH,QAAK,KAAK,UAAU;AACpB;EACF,KAAK;AACH,QAAK,KAAK,UAAU;AACpB;EACF,KAAK;AACH,QAAK,KAAK,oBAAoB;AAC9B;EACF,KAAK;AACH,QAAK,KAAK,QAAQ;AAClB;EACF,KAAK;AACH,QAAK,KAAK,WAAW;AACrB;EACF,KAAK;AACH,QAAK,KAAK,iBAAiB;AAC3B,QAAK,KAAK,SAAS;AACnB;;AAGJ,QAAO;;;;;ACrFT,SAAgB,qBAAqB,KAAwB,QAA6B;CACxF,MAAM,EACJ,aACA,gBACA,SACA,SACA,UACA,MACA,KACA,cACA,cACE;CAEJ,MAAM,mBAAmB,mBAAmB,QAAQ,MAAM;CAC1D,MAAM,WAAW;EACf,QAAQ,IAAI,OAAO,+BAA+B;EAClD,KAAK,IAAI,OAAO,4BAA4B;EAC5C,OAAO,IAAI,OAAO,8BAA8B;EAChD,IAAI,IAAI,OAAO,2BAA2B;EAC1C,MAAM,IAAI,OAAO,6BAA6B;EAC9C,KAAK,IAAI,OAAO,4BAA4B;EAC5C,SAAS,IAAI,OAAO,gCAAgC;EACpD,QAAQ,IAAI,OAAO,2BAA2B;EAC9C,KAAK,IAAI,OAAO,wBAAwB;EACxC,QAAQ,IAAI,OAAO,2BAA2B;EAC/C;CAED,MAAM,YAAY,SAAS,SAAS,GAAG,IAAI,YAAY,WAAW,kBAAkB,GAAG,EAAE;CACzF,MAAM,SAAS,SAAS,MAAM,GAAG,IAAI,YAAY,QAAQ,kBAAkB,GAAG,EAAE;CAChF,MAAM,eAAe,iBAAiB,gBAAgB,cAAc;CACpE,MAAM,iBAAiB,kBAAkB,SAAS,QAAQ;CAC1D,MAAMC,aAAsC,CAAC,UAAU,MAAM;CAC7D,MAAMC,gBAAyC,CAAC,cAAc,GAAG,eAAe;AAEhF,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;EACd,iBAAiB;EACjB,oBAAoB;EACpB,uBAAuB;EACxB,CAAC;AAEF,KAAI,SAAS,KAAK;EAChB,MAAMC,aAAqC,EAAE,GAAG,WAAW;AAC3D,MAAI,gBAAgB,SAAS,MAC3B,YAAW,IAAI,YAAY,WAAW;AAExC,uBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACd,iBAAiB;GACjB,uBAAuB;GACxB,CAAC;;AAGJ,KAAI,SAAS,MACX,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;EACd,iBAAiB,CAAC,aAAa;EAC/B,uBAAuB;EACxB,CAAC;AAGJ,KAAI,SAAS,GACX,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;EACd,iBAAiB,CAAC,aAAa;EAC/B,oBAAoB;EACpB,uBAAuB;EACxB,CAAC;AAGJ,KAAI,SAAS,MAAM;EACjB,MAAMC,WAAmC,EAAE,GAAG,QAAQ;AACtD,MAAI,aAAa,UAAU,SAAS,GAClC,UAAS,IAAI,YAAY,QAAQ;AAEnC,uBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACd,iBAAiB,CAAC,aAAa;GAC/B,oBAAoB;GACpB,uBAAuB;GACxB,CAAC;;AAGJ,KAAI,SAAS,KAAK;EAChB,MAAMC,iBAAyC,EAAE,GAAG,QAAQ;AAC5D,MAAI,SAAS,UAAU,SAAS,KAC9B,gBAAe,IAAI,YAAY,UAAU;AAE3C,MAAI,aAAa,UAAU,SAAS,GAClC,gBAAe,IAAI,YAAY,QAAQ;AAEzC,uBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACd,iBAAiB,CAAC,aAAa;GAC/B,oBAAoB;GACpB,uBAAuB;GACxB,CAAC;;AAGJ,KAAI,SAAS,QACX,sBAAqB;EACnB;EACA,aAAa;EACb,cAAc;EACd,iBAAiB,CAAC,aAAa;EAC/B,uBAAuB;EACxB,CAAC;AAGJ,KAAI,SAAS,QAAQ;EACnB,MAAMC,aAAqC,EAAE,GAAG,QAAQ;AACxD,MAAI,QAAQ,UAAU,SAAS,IAAK,YAAW,IAAI,YAAY,SAAS;AACxE,MAAI,SAAS,UAAU,SAAS,KAAM,YAAW,IAAI,YAAY,UAAU;AAC3E,MAAI,aAAa,UAAU,SAAS,GAAI,YAAW,IAAI,YAAY,QAAQ;AAC3E,uBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACd,iBAAiB,CAAC,cAAc,SAAS;GACzC,oBAAoB;GACpB,uBAAuB;GACxB,CAAC;;AAGJ,KAAI,SAAS,KAAK;EAChB,MAAMC,iBAAyC,EAAE,GAAG,QAAQ;AAC5D,MAAI,QAAQ,UAAU,SAAS,IAAK,gBAAe,IAAI,YAAY,SAAS;AAC5E,MAAI,SAAS,UAAU,SAAS,KAAM,gBAAe,IAAI,YAAY,UAAU;AAC/E,MAAI,YAAY,YAAY,SAAS,QACnC,gBAAe,IAAI,YAAY,aAAa;AAC9C,uBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACd,iBAAiB,CAAC,aAAa;GAC/B,oBAAoB;GACpB,uBAAuB;GACxB,CAAC;;AAGJ,KAAI,SAAS,QAAQ;EACnB,MAAMC,aAAqC,EAAE,GAAG,QAAQ;AACxD,MAAI,QAAQ,UAAU,SAAS,IAAK,YAAW,IAAI,YAAY,SAAS;AACxE,MAAI,YAAY,YAAY,SAAS,QACnC,YAAW,IAAI,YAAY,aAAa;AAC1C,uBAAqB;GACnB;GACA,aAAa;GACb,cAAc;GACd,iBAAiB,CAAC,aAAa;GAC/B,oBAAoB;GACpB,uBAAuB;GACxB,CAAC;;;AAIN,SAAS,kBACP,SACA,SACyB;AACzB,KAAI,YAAY,UAAU,YAAY,OAAQ,QAAO,CAAC,cAAc;AACpE,KAAI,YAAY,UAAU,YAAY,UAAW,QAAO,CAAC,cAAc;AACvE,KAAI,YAAY,MAAO,QAAO,CAAC,aAAa;AAC5C,QAAO,EAAE;;;;;AC/IX,SAAgB,oBAAoB,KAAwB,QAA6B;AACvF,sBAAqB,KAAK,OAAO;AACjC,gBAAe,KAAK,OAAO;AAC3B,kBAAiB,KAAK,OAAO;AAC7B,qBAAoB,KAAK,OAAO;AAChC,oBAAmB,KAAK,OAAO;AAC/B,oBAAmB,KAAK,OAAO;AAC/B,gBAAe,KAAK,OAAO;AAC3B,iBAAgB,KAAK,OAAO;AAC5B,qBAAoB,KAAK,OAAO;AAChC,kBAAiB,KAAK,OAAO;AAC7B,uBAAsB,KAAK,OAAO;AAClC,mBAAkB,KAAK,OAAO;AAC9B,mBAAkB,KAAK,OAAO;AAC9B,qBAAoB,KAAK,OAAO;AAChC,mBAAkB,KAAK,OAAO;AAC9B,4BAA2B,KAAK,OAAO;AACvC,kBAAiB,KAAK,OAAO;AAC7B,uBAAsB,KAAK,OAAO;AAClC,qBAAoB,KAAK,OAAO;AAChC,qBAAoB,KAAK,OAAO;AAChC,sBAAqB,KAAK,OAAO;AACjC,oBAAmB,KAAK,OAAO;AAC/B,oBAAmB,KAAK,OAAO;AAC/B,0BAAyB,KAAK,OAAO;AACrC,4BAA2B,KAAK,OAAO;AACvC,gBAAe,KAAK,OAAO;AAC3B,oBAAmB,KAAK,OAAO;AAC/B,oBAAmB,KAAK,OAAO;;;;;AC1DjC,SAAgB,uBAAuB,WAAyB,QAAyB;CACvF,MAAM,mBAAmB,OAAO,SAAS,IAAI,GAAG,SAAS,GAAG,OAAO;AACnE,MAAK,MAAM,QAAQ,UAAU,MAAM,CACjC,KAAI,KAAK,WAAW,iBAAiB,CAAE,QAAO;AAEhD,QAAO;;AAGT,SAAgB,sBACd,KACA,WACA,cACA,UACA,QACM;CACN,MAAM,cAAc,aAAa,SAAS,OAAO,GAAG,eAAe,GAAG,aAAa;CACnF,MAAM,UAAU,UAAU,IAAI,YAAY;AAE1C,KAAI,CAAC,QAAS;CAEd,IAAIC;AACJ,KAAI,aAAa,YAAY,CAC3B,oBAAmB;UACV,YAAY,SAAS,OAAO,CACrC,oBAAmB,sBAAsB,SAAS,OAAO;KAEzD,oBAAmB;CAIrB,MAAM,aAAa,aAAa,YAAY,GAAG,cAAc;AAC7D,KAAI,UAAU,UAAU,kBAAkB,WAAW;;AAGvD,SAAgB,2BACd,KACA,WACA,QACA,YACA,QACM;CACN,MAAM,mBAAmB,OAAO,SAAS,IAAI,GAAG,SAAS,GAAG,OAAO;AAEnE,MAAK,MAAM,CAAC,cAAc,YAAY,WAAW;AAC/C,MAAI,CAAC,aAAa,WAAW,iBAAiB,CAAE;EAGhD,MAAM,aAAa,kBADE,aAAa,MAAM,iBAAiB,OAAO,CACd;EAClD,MAAM,WAAW,aAAa,GAAG,WAAW,GAAG,eAAe;EAE9D,IAAIA;AACJ,MAAI,aAAa,aAAa,CAC5B,oBAAmB;WACV,aAAa,SAAS,OAAO,CACtC,oBAAmB,sBAAsB,SAAS,OAAO;MAEzD,oBAAmB;EAIrB,MAAM,aAAa,aAAa,aAAa,GAAG,eAAe;AAC/D,MAAI,UAAU,UAAU,kBAAkB,WAAW;;;;;;AC/DzD,eAAsB,oBACpB,KACA,WACA,QACe;AACf,4BAA2B,KAAK,WAAW,QAAQ,IAAI,OAAO;;;;;ACJhE,eAAsB,wBACpB,KACA,WACA,QACe;AAEf,KAAI,OAAO,cAAc,OAAQ;CAEjC,MAAM,SAAS;CACf,MAAM,YAAY,OAAO,iBAAiB;CAC1C,MAAM,YAAY,OAAO,iBAAiB;CAC1C,MAAM,WAAW,OAAO,YAAY;CACpC,MAAM,kBAAkB,OAAO,YAAY;CAC3C,MAAM,UAAU,OAAO,YAAY;CACnC,MAAM,aAAa,OAAO,YAAY;AAEtC,MAAK,MAAM,CAAC,cAAc,YAAY,WAAW;AAC/C,MAAI,CAAC,aAAa,WAAW,OAAO,CAAE;AAGtC,MAAI,CAAC,aAAa,aAAa,SAAS,iBAAiB,CAAE;AAG3D,MAAI,CAAC,aAAa,aAAa,SAAS,wBAAwB,CAAE;AAGlE,MAAI,CAAC,YAAY,aAAa,SAAS,gBAAgB,CAAE;AAGzD,MAAI,CAAC,YAAY,aAAa,SAAS,4BAA4B,CAAE;AAGrE,MAAI,CAAC,mBAAmB,aAAa,SAAS,+BAA+B,CAAE;AAG/E,MAAI,CAAC,WAAW,aAAa,SAAS,cAAc,CAAE;AAGtD,MAAI,CAAC,cAAc,aAAa,SAAS,cAAc,CAAE;EAGzD,MAAM,aAAa,kBADE,aAAa,MAAM,GAAc,CACJ;EAElD,IAAIC;AACJ,MAAI,aAAa,aAAa,CAC5B,oBAAmB;WACV,aAAa,SAAS,OAAO,CACtC,oBAAmB,sBAAsB,SAAS,OAAO;MAEzD,oBAAmB;EAIrB,MAAM,aAAa,aAAa,aAAa,GAAG,eAAe;AAC/D,MAAI,UAAU,YAAY,kBAAkB,WAAW;;;;;;ACvD3D,eAAsB,yBACpB,KACA,WACA,QACe;CACf,MAAM,cAAc,OAAO,SAAS,MAAM,MACxC;EAAC;EAAmB;EAAgB;EAAkB;EAAO,CAAC,SAAS,EAAE,CAC1E;CACD,MAAM,aAAa,OAAO,SAAS,SAAS,OAAO;CACnD,MAAM,eAAe,OAAO,SAAS,SAAS,SAAS;CACvD,MAAM,cAAc,OAAO,SAAS,SAAS,QAAQ;CACrD,MAAM,cAAc,OAAO,SAAS,SAAS,QAAQ;CACrD,MAAM,aAAa,OAAO,SAAS,SAAS,OAAO;CACnD,MAAM,gBAAgB,OAAO,SAAS,SAAS,UAAU;CACzD,MAAM,gBAAgB,OAAO,SAAS,SAAS,UAAU;CACzD,MAAM,cAAc,OAAO,SAAS,SAAS,QAAQ;CACrD,MAAM,gBAAgB,OAAO,SAAS,SAAS,cAAc;CAC7D,MAAM,mBAAmB,OAAO,SAAS,SAAS,iBAAiB;CACnE,MAAM,eAAe,OAAO,SAAS,SAAS,mBAAmB;CACjE,MAAM,WAAW,OAAO,YAAY;AAEpC,KACE,eACA,cACA,gBACA,eACA,eACA,cACA,iBACA,iBACA,aAEA;MAAI,aAAa;AACf,8BAA2B,KAAK,WAAW,2BAA2B,YAAY,OAAO;GAEzF,MAAM,iBAAiB,OAAO,SAAS,MAAM,MAC3C;IAAC;IAAmB;IAAgB;IAAkB;IAAO,CAAC,SAAS,EAAE,CAC1E;AACD,OAAI,eACF,4BACE,KACA,WACA,kBAAkB,kBAClB,YACA,OACD;aAEM,WACT,4BAA2B,KAAK,WAAW,iBAAiB,YAAY,OAAO;WACtE,aACT,4BAA2B,KAAK,WAAW,mBAAmB,YAAY,OAAO;WACxE,YACT,4BAA2B,KAAK,WAAW,kBAAkB,YAAY,OAAO;WACvE,aAAa;AAEtB,8BAA2B,KAAK,WAAW,kBAAkB,YAAY,OAAO;AAGhF,OAAI,OAAO,oBAAoB,OAAO,qBAAqB,OACzD,4BACE,KACA,WACA,+BAA+B,OAAO,oBACtC,YACA,OACD;aAEM,WACT,4BAA2B,KAAK,WAAW,iBAAiB,YAAY,OAAO;WACtE,cACT,4BAA2B,KAAK,WAAW,oBAAoB,YAAY,OAAO;WACzE,cAET,4BAA2B,KAAK,WAAW,oBAAoB,KAAK,OAAO;WAClE,YAET,4BAA2B,KAAK,WAAW,kBAAkB,YAAY,OAAO;;AAIpF,KAAI,iBAAiB,oBAAoB,cAAc;AACrD,6BAA2B,KAAK,WAAW,wBAAwB,eAAe,OAAO;AAEzF,MAAI,cACF,4BAA2B,KAAK,WAAW,wBAAwB,eAAe,OAAO;WAChF,iBACT,4BAA2B,KAAK,WAAW,2BAA2B,eAAe,OAAO;WACnF,aACT,4BACE,KACA,WACA,6BACA,eACA,OACD;AAGH,MAAI,CAAC,aAAa,OAAO,QAAQ,UAAU,OAAO,QAAQ,UAAU,OAAO,QAAQ,WACjF,4BAA2B,KAAK,WAAW,OAAO,OAAO,IAAI,UAAU,eAAe,OAAO;;;;;;AClGnG,eAAsB,wBACpB,KACA,WACA,QACe;AACf,KAAI,OAAO,YAAY,OAAQ;AAE/B,KAAI,OAAO,YAAY,UAAU;AAC/B,6BACE,KACA,WACA,mCACA,oBACA,OACD;AACD;;AAGF,KAAI,OAAO,YAAY,OAAQ;AAE/B,KAAI,OAAO,YAAY,UAAU;AAC/B,6BAA2B,KAAK,WAAW,yBAAyB,eAAe,OAAO;AAC1F;;AAGF,KAAI,OAAO,YAAY,YAAY;AACjC,6BAA2B,KAAK,WAAW,2BAA2B,eAAe,OAAO;AAC5F;;AAGF,KAAI,OAAO,YAAY,SAAS;AAC9B,6BAA2B,KAAK,WAAW,wBAAwB,eAAe,OAAO;AACzF;;AAGF,KAAI,OAAO,YAAY,QAAQ;AAC7B,6BAA2B,KAAK,WAAW,uBAAuB,eAAe,OAAO;AACxF,6BAA2B,KAAK,WAAW,uBAAuB,eAAe,OAAO;AACxF;;AAGF,4BAA2B,KAAK,WAAW,uBAAuB,eAAe,OAAO;AACxF,4BACE,KACA,WACA,kBAAkB,OAAO,WACzB,eACA,OACD;;;;;AChDH,eAAsB,mBACpB,KACA,WACA,QACe;AACf,KAAI,OAAO,aAAa,UAAU,OAAO,QAAQ,OAAQ;AACzD,KAAI,OAAO,YAAY,SAAU;AAEjC,4BAA2B,KAAK,WAAW,WAAW,eAAe,OAAO;AAC5E,4BAA2B,KAAK,WAAW,MAAM,OAAO,IAAI,QAAQ,eAAe,OAAO;AAC1F,4BACE,KACA,WACA,MAAM,OAAO,IAAI,GAAG,OAAO,YAC3B,eACA,OACD;AAED,KAAI,OAAO,YAAY,SACrB,4BACE,KACA,WACA,2BAA2B,OAAO,YAClC,eACA,OACD;;;;;ACzBL,eAAsB,oBACpB,KACA,WACA,QACe;AACf,KAAI,OAAO,QAAQ,OAAQ;AAC3B,KAAI,OAAO,YAAY,SAAU;AAEjC,4BAA2B,KAAK,WAAW,OAAO,OAAO,IAAI,UAAU,gBAAgB,OAAO;CAE9F,MAAM,cAAc,OAAO,SAAS,MAAM,MACxC;EAAC;EAAmB;EAAgB;EAAkB;EAAO,CAAC,SAAS,EAAE,CAC1E;CACD,MAAM,aAAa,OAAO,SAAS,SAAS,OAAO;CACnD,MAAM,eAAe,OAAO,SAAS,SAAS,SAAS;CACvD,MAAM,cAAc,OAAO,SAAS,SAAS,QAAQ;CACrD,MAAM,cAAc,OAAO,SAAS,SAAS,QAAQ;AAErD,KAAI,aAAa;AACf,6BACE,KACA,WACA,OAAO,OAAO,IAAI,kBAClB,YACA,OACD;EAED,MAAM,iBAAiB,OAAO,SAAS,MAAM,MAC3C;GAAC;GAAmB;GAAgB;GAAkB;GAAO,CAAC,SAAS,EAAE,CAC1E;AACD,MACE,OAAO,YAAY,WAClB,mBAAmB,UAAU,mBAAmB,kBAEjD,4BACE,KACA,WACA,OAAO,OAAO,IAAI,aAAa,kBAC/B,YACA,OACD;YAEM,aAAa;AAEtB,MAAI,OAAO,qBAAqB,QAC9B,4BACE,KACA,WACA,OAAO,OAAO,IAAI,kBAClB,YACA,OACD;WACQ,OAAO,QAAQ,UAAU,OAAO,QAAQ,QAEjD,4BAA2B,KAAK,WAAW,OAAO,OAAO,IAAI,aAAa,YAAY,OAAO;AAI/F,MAAI,OAAO,YAAY,OACrB,4BACE,KACA,WACA,OAAO,OAAO,IAAI,mBAClB,YACA,OACD;YAEM,cAAc,OAAO,QAAQ,OACtC,4BAA2B,KAAK,WAAW,OAAO,OAAO,IAAI,YAAY,YAAY,OAAO;UACnF,gBAAgB,OAAO,QAAQ,OACxC,4BAA2B,KAAK,WAAW,OAAO,OAAO,IAAI,cAAc,YAAY,OAAO;UACrF,eAAe,OAAO,QAAQ,OACvC,4BAA2B,KAAK,WAAW,OAAO,OAAO,IAAI,aAAa,YAAY,OAAO;;;;;ACxEjG,eAAsB,qBACpB,KACA,WACA,QACe;AACf,4BAA2B,KAAK,WAAW,mBAAmB,mBAAmB,OAAO;;AAG1F,eAAsB,kBACpB,KACA,WACA,QACe;CACf,MAAM,iBAAiB,OAAO,SAAS,MAAM,MAC3C;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,SAAS,EAAE,CACd;CACD,MAAM,YAAY,OAAO,SAAS,MAAM,MACtC;EAAC;EAAe;EAAkB;EAAmB,CAAC,SAAS,EAAE,CAClE;AAED,KAAI,CAAC,kBAAkB,CAAC,aAAa,OAAO,YAAY,OAAQ;AAEhE,4BAA2B,KAAK,WAAW,gBAAgB,gBAAgB,OAAO;;;;;AC9BpF,eAAsB,qBACpB,KACA,WACA,QACe;AACf,KAAI,CAAC,OAAO,QAAQ,OAAO,SAAS,OAAQ;CAE5C,MAAM,cAAc,OAAO,SAAS,MAAM,MACxC;EAAC;EAAmB;EAAgB;EAAkB;EAAO,CAAC,SAAS,EAAE,CAC1E;CACD,MAAM,aAAa,OAAO,SAAS,SAAS,OAAO;CACnD,MAAM,eAAe,OAAO,SAAS,SAAS,SAAS;CACvD,MAAM,cAAc,OAAO,SAAS,SAAS,QAAQ;CACrD,MAAM,gBAAgB,OAAO,SAAS,SAAS,cAAc;CAC7D,MAAM,aAAa,OAAO,SAAS,SAAS,iBAAiB;CAC7D,MAAM,eAAe,OAAO,SAAS,SAAS,mBAAmB;CACjE,MAAM,YAAY,iBAAiB,cAAc;CAEjD,MAAM,eAAe,OAAO;AAE5B,KAAI,OAAO,YAAY,YAAY,iBAAiB,SAAS;AAC3D,6BACE,KACA,WACA,6BACA,oBACA,OACD;AAED,MAAI,aAAa;GACf,MAAM,iBAAiB,OAAO,SAAS,MAAM,MAC3C;IAAC;IAAmB;IAAgB;IAAkB;IAAO,CAAC,SAAS,EAAE,CAC1E;AACD,OAAI,eACF,4BACE,KACA,WACA,+BAA+B,kBAC/B,YACA,OACD;;AAIL,MAAI,WAAW;AACb,8BACE,KACA,WACA,iCACA,eACA,OACD;GAED,IAAI,kBAAkB;AACtB,OAAI,cAAe,mBAAkB;YAC5B,WAAY,mBAAkB;YAC9B,aAAc,mBAAkB;AAEzC,OAAI,gBACF,4BACE,KACA,WACA,4BAA4B,mBAC5B,eACA,OACD;;AAGL;;AAGF,KAAI,OAAO,YAAY,YAAY,iBAAiB,eAAe;AACjE,6BACE,KACA,WACA,mCACA,oBACA,OACD;AAED,MAAI,aAAa;AACf,8BACE,KACA,WACA,0CACA,YACA,OACD;GAED,MAAM,iBAAiB,OAAO,SAAS,MAAM,MAC3C;IAAC;IAAmB;IAAgB;IAAkB;IAAO,CAAC,SAAS,EAAE,CAC1E;AACD,OAAI,eACF,4BACE,KACA,WACA,qCAAqC,kBACrC,YACA,OACD;;AAIL,MAAI,WAAW;AACb,8BACE,KACA,WACA,uCACA,eACA,OACD;GAED,IAAI,kBAAkB;AACtB,OAAI,cAAe,mBAAkB;YAC5B,WAAY,mBAAkB;YAC9B,aAAc,mBAAkB;AAEzC,OAAI,gBACF,4BACE,KACA,WACA,kCAAkC,mBAClC,eACA,OACD;;AAGL;;AAIF,KACE,iBAAiB,cACjB,OAAO,YAAY,UACnB,OAAO,SAAS,SAAS,OAAO,EAChC;AAEA,6BAA2B,KAAK,WAAW,gCAAgC,YAAY,OAAO;AAG9F,6BAA2B,KAAK,WAAW,gCAAgC,YAAY,OAAO;AAG9F,MAAI,OAAO,QAAQ,UAAU,OAAO,aAAa,OAC/C,4BACE,KACA,WACA,2BAA2B,OAAO,IAAI,GAAG,OAAO,YAChD,eACA,OACD;AAEH;;AAGF,KAAI,OAAO,YAAY,YAAY,OAAO,YAAY,QAAQ;AAC5D,6BACE,KACA,WACA,QAAQ,aAAa,eACrB,iBACA,OACD;AAED,MAAI,OAAO,QAAQ,UAAU,OAAO,aAAa,OAC/C,4BACE,KACA,WACA,QAAQ,aAAa,aAAa,OAAO,IAAI,GAAG,OAAO,YACvD,eACA,OACD;;AAIL,KAAI,aAAa;AACf,6BACE,KACA,WACA,QAAQ,aAAa,kBACrB,YACA,OACD;EAED,MAAM,iBAAiB,OAAO,SAAS,MAAM,MAC3C;GAAC;GAAmB;GAAgB;GAAkB;GAAO,CAAC,SAAS,EAAE,CAC1E;AACD,MAAI,gBAAgB;AAClB,8BACE,KACA,WACA,QAAQ,aAAa,aAAa,kBAClC,YACA,OACD;AAED,OACE,OAAO,YAAY,WAClB,mBAAmB,UAAU,mBAAmB,kBAEjD,4BACE,KACA,WACA,QAAQ,aAAa,aAAa,kBAClC,YACA,OACD;;YAGI,WACT,4BAA2B,KAAK,WAAW,QAAQ,aAAa,YAAY,YAAY,OAAO;UACtF,aACT,4BACE,KACA,WACA,QAAQ,aAAa,cACrB,YACA,OACD;UACQ,YACT,4BACE,KACA,WACA,QAAQ,aAAa,aACrB,YACA,OACD;AAGH,KAAI,WAAW;AACb,6BACE,KACA,WACA,QAAQ,aAAa,eACrB,eACA,OACD;EAED,IAAI,kBAAkB;AACtB,MAAI,cAAe,mBAAkB;WAC5B,WAAY,mBAAkB;WAC9B,aAAc,mBAAkB;AAEzC,MAAI,gBACF,4BACE,KACA,WACA,QAAQ,aAAa,UAAU,mBAC/B,eACA,OACD;;;;;;AC1PP,eAAsB,yBACpB,KACA,WACA,QACe;AACf,KAAI,CAAC,OAAO,YAAY,OAAO,aAAa,OAAQ;AACpD,KAAI,OAAO,YAAY,SAAU;CAEjC,MAAM,cAAc,OAAO,SAAS,MAAM,MACxC;EAAC;EAAmB;EAAgB;EAAkB;EAAO,CAAC,SAAS,EAAE,CAC1E;CACD,MAAM,aAAa,OAAO,SAAS,SAAS,OAAO;CACnD,MAAM,eAAe,OAAO,SAAS,SAAS,SAAS;CACvD,MAAM,cAAc,OAAO,SAAS,SAAS,QAAQ;AAErD,KAAI,OAAO,YAAY,OACrB,4BACE,KACA,WACA,YAAY,OAAO,SAAS,eAC5B,iBACA,OACD;AAGH,KAAI,aAAa;EACf,MAAM,iBAAiB,OAAO,SAAS,MAAM,MAC3C;GAAC;GAAmB;GAAgB;GAAkB;GAAO,CAAC,SAAS,EAAE,CAC1E;AACD,MAAI,eACF,4BACE,KACA,WACA,YAAY,OAAO,SAAS,aAAa,kBACzC,YACA,OACD;YAEM,WACT,4BACE,KACA,WACA,YAAY,OAAO,SAAS,YAC5B,YACA,OACD;UACQ,aACT,4BACE,KACA,WACA,YAAY,OAAO,SAAS,cAC5B,YACA,OACD;UACQ,YACT,4BACE,KACA,WACA,YAAY,OAAO,SAAS,aAC5B,YACA,OACD;;;;;AC7DL,eAAsB,sBACpB,KACA,WACA,QACe;AACf,KAAI,CAAC,OAAO,SAAS,OAAO,UAAU,OAAQ;AAC9C,KAAI,OAAO,YAAY,SAAU;AACjC,KAAI,OAAO,YAAY,OAAQ;AAG/B,4BACE,KACA,WACA,SAAS,OAAO,MAAM,eACtB,eACA,OACD;AAOD,KAJoB,OAAO,SAAS,MAAM,MACxC;EAAC;EAAmB;EAAgB;EAAkB;EAAO,CAAC,SAAS,EAAE,CAC1E,KAEmB,OAAO,UAAU,YAAY,OAAO,UAAU,eAChE,4BACE,KACA,WACA,SAAS,OAAO,MAAM,cACtB,eACA,OACD;;;;;AC9BL,eAAsB,sBACpB,KACA,WACA,QACe;AACf,KAAI,CAAC,OAAO,UAAU,OAAO,OAAO,WAAW,EAAG;AAElD,MAAK,MAAM,SAAS,OAAO,QAAQ;AACjC,MAAI,UAAU,OAAQ;AAGtB,MAAI,UAAU,YAAa;AAE3B,MAAI,UAAU,OAAO;AACnB,OAAI,OAAO,SAAS,SAAS,OAAO,CAClC,4BAA2B,KAAK,WAAW,4BAA4B,YAAY,OAAO;YAE1F,OAAO,SAAS,MAAM,MAAM;IAAC;IAAmB;IAAgB;IAAQ,CAAC,SAAS,EAAE,CAAC,CAErF,4BAA2B,KAAK,WAAW,4BAA4B,YAAY,OAAO;AAE5F;;AAIF,MAAI,UAAU,OAAO;AACnB,OAAI,IAAI,OAAO,wBAAwB,CACrC,4BAA2B,KAAK,WAAW,uBAAuB,YAAY,OAAO;AAEvF,OAAI,IAAI,OAAO,2BAA2B,CACxC,4BAA2B,KAAK,WAAW,0BAA0B,eAAe,OAAO;AAE7F;;AAIF,MAAI,UAAU,aAAa;AACzB,OAAI,IAAI,OAAO,wBAAwB,CACrC,4BAA2B,KAAK,WAAW,6BAA6B,YAAY,OAAO;AAE7F;;AAGF,6BAA2B,KAAK,WAAW,UAAU,SAAS,IAAI,OAAO;;;;;;AC3C7E,eAAsB,wBACpB,KACA,WACA,QACe;AACf,KAAI,CAAC,OAAO,YAAY,OAAO,SAAS,WAAW,KAAK,OAAO,SAAS,OAAO,OAAQ;CAEvF,MAAM,cAAc,OAAO,SAAS,MAAM,MACxC;EAAC;EAAmB;EAAgB;EAAkB;EAAO,CAAC,SAAS,EAAE,CAC1E;CACD,MAAM,aAAa,OAAO,SAAS,SAAS,OAAO;CACnD,MAAM,eAAe,OAAO,SAAS,SAAS,SAAS;CACvD,MAAM,cAAc,OAAO,SAAS,SAAS,QAAQ;CACrD,MAAM,gBAAgB,OAAO,SAAS,SAAS,cAAc;CAC7D,MAAM,aAAa,OAAO,SAAS,SAAS,iBAAiB;CAC7D,MAAM,eAAe,OAAO,SAAS,SAAS,mBAAmB;CACjE,MAAM,YAAY,iBAAiB,cAAc;AAEjD,MAAK,MAAM,WAAW,OAAO,UAAU;AACrC,MAAI,YAAY,OAAQ;AAExB,MAAI,OAAO,YAAY,SACrB,4BACE,KACA,WACA,YAAY,QAAQ,2BACpB,oBACA,OACD;WACQ,OAAO,YAAY,UAAU,OAAO,QAAQ,QAAQ;AAC7D,8BACE,KACA,WACA,YAAY,QAAQ,UAAU,OAAO,IAAI,QACzC,gBACA,OACD;AAED,OAAI,OAAO,QAAQ,UAAU,OAAO,aAAa,OAC/C,4BACE,KACA,WACA,YAAY,QAAQ,UAAU,OAAO,IAAI,GAAG,OAAO,YACnD,eACA,OACD;;AAIL,MAAI,aAAa;GACf,MAAM,iBAAiB,OAAO,SAAS,MAAM,MAC3C;IAAC;IAAQ;IAAgB;IAAmB;IAAiB,CAAC,SAAS,EAAE,CAC1E;AACD,OAAI,gBAAgB;AAClB,+BACE,KACA,WACA,YAAY,QAAQ,aAAa,kBACjC,YACA,OACD;AAED,QACE,OAAO,YAAY,WAClB,mBAAmB,UAAU,mBAAmB,kBAEjD,4BACE,KACA,WACA,YAAY,QAAQ,aAAa,kBACjC,YACA,OACD;;aAGI,WACT,4BACE,KACA,WACA,YAAY,QAAQ,YACpB,YACA,OACD;WACQ,aACT,4BACE,KACA,WACA,YAAY,QAAQ,cACpB,YACA,OACD;WACQ,YACT,4BACE,KACA,WACA,YAAY,QAAQ,aACpB,YACA,OACD;AAGH,MAAI,WAAW;GACb,IAAI,kBAAkB;AACtB,OAAI,cAAe,mBAAkB;YAC5B,WAAY,mBAAkB;YAC9B,aAAc,mBAAkB;AAEzC,OAAI,gBACF,4BACE,KACA,WACA,YAAY,QAAQ,UAAU,mBAC9B,eACA,OACD;;;;;;;AC7GT,eAAsB,uBACpB,KACA,WACA,QACe;CACf,MAAM,YAAY,OAAO,SAAS,MAAM,MACtC;EAAC;EAAe;EAAkB;EAAmB,CAAC,SAAS,EAAE,CAClE;CACD,MAAM,UAAU,OAAO,SAAS,SAAS,OAAO;AAEhD,KAAI,OAAO,mBAAmB,QAC5B;MAAI,uBAAuB,WAAW,SAAS,CAC7C,4BAA2B,KAAK,WAAW,8BAA8B,IAAI,OAAO;;AAIxF,KAAI,OAAO,mBAAmB,MAC5B,4BAA2B,KAAK,WAAW,sBAAsB,IAAI,OAAO;AAG9E,KAAI,OAAO,mBAAmB,WAAW,aAAa,SACpD,4BAA2B,KAAK,WAAW,iBAAiB,IAAI,OAAO;AAGzE,KAAI,OAAO,iBAAiB,aAC1B,uBAAsB,KAAK,WAAW,mBAAmB,yBAAyB,OAAO;;;;;AC9B7F,eAAsB,uBACpB,KACA,WACA,QACe;CACf,MAAM,gBAAgB,OAAO,YAAY;AAEzC,KAAI,OAAO,cAAc,gBAAgB,OAAO,iBAAiB,aAC/D,4BAA2B,KAAK,WAAW,kBAAkB,kBAAkB,OAAO;AAGxF,KAAI,OAAO,cAAc,UAAU,OAAO,cAAc,cAAc;EACpE,MAAMC,cAAsC;GAC1C,mBAAmB;GACnB,kBAAkB;GAClB,gBAAgB;GAChB,OAAO;GACP,MAAM;GACN,MAAM;GACN,QAAQ;GACT;AAED,OAAK,MAAM,KAAK,OAAO,SACrB,KAAI,YAAY,GACd,4BACE,KACA,WACA,UAAU,OAAO,UAAU,OAAO,YAAY,MAC9C,YACA,OACD;;AAKP,KAAI,OAAO,iBAAiB,UAAU,OAAO,iBAAiB,gBAAgB,CAAC,cAC7E,4BACE,KACA,WACA,UAAU,OAAO,aAAa,UAC9B,eACA,OACD;;;;;AC1CL,eAAsB,wBACpB,KACA,WACA,QACe;AACf,KAAI,CAAC,OAAO,WAAW,OAAO,YAAY,OAAQ;AAClD,KAAI,OAAO,YAAY,SAAU;AACjC,KAAI,OAAO,YAAY,OAAQ;AAG/B,4BACE,KACA,WACA,WAAW,OAAO,QAAQ,eAC1B,eACA,OACD;;;;;AChBH,eAAsB,8BACpB,KACA,WACA,QACe;AACf,KAAI,CAAC,OAAO,iBAAiB,OAAO,kBAAkB,OAAQ;AAC9D,KAAI,OAAO,YAAY,SAAU;AACjC,KAAI,OAAO,YAAY,OAAQ;AAG/B,4BACE,KACA,WACA,iBAAiB,OAAO,cAAc,eACtC,eACA,OACD;;;;;AChBH,eAAsB,yBACpB,KACA,WACA,QACe;AACf,KAAI,CAAC,OAAO,YAAY,OAAO,aAAa,OAAQ;AACpD,KAAI,OAAO,YAAY,SAAU;AACjC,KAAI,OAAO,YAAY,OAAQ;AAG/B,4BACE,KACA,WACA,aAAa,OAAO,SAAS,eAC7B,eACA,OACD;;;;;AChBH,eAAsB,oBACpB,KACA,WACA,QACe;AACf,KAAI,CAAC,OAAO,OAAO,OAAO,QAAQ,OAAQ;CAG1C,MAAM,UAAU,OAAO,SAAS,SAAS,OAAO;AAEhD,KAAI,OAAO,QAAQ,aAAa,QAE9B,4BAA2B,KAAK,WAAW,wBAAwB,YAAY,OAAO;AAGxF,KAAI,OAAO,QAAQ,YAAY,QAE7B,4BAA2B,KAAK,WAAW,uBAAuB,YAAY,OAAO;AAGvF,KAAI,OAAO,QAAQ,YAAY,QAE7B,4BAA2B,KAAK,WAAW,uBAAuB,YAAY,OAAO;;;;;ACSzF,eAAsB,uBAAuB,SAAqD;AAChG,KAAI;EACF,MAAM,EAAE,QAAQ,cAAc;AAE9B,MAAI,CAAC,aAAa,UAAU,SAAS,EACnC,QAAO;GACL,SAAS;GACT,OAAO;GACR;EAGH,MAAM,MAAM,IAAI,mBAAmB;AAGnC,MAAI,OAAO,cAAc,OAEvB,OAAM,wBAAwB,KAAK,WAAW,OAAO;OAChD;AAEL,SAAM,oBAAoB,KAAK,WAAW,OAAO;AACjD,SAAM,yBAAyB,KAAK,WAAW,OAAO;AACtD,SAAM,wBAAwB,KAAK,WAAW,OAAO;AACrD,SAAM,mBAAmB,KAAK,WAAW,OAAO;AAChD,SAAM,oBAAoB,KAAK,WAAW,OAAO;AACjD,SAAM,qBAAqB,KAAK,WAAW,OAAO;AAClD,SAAM,kBAAkB,KAAK,WAAW,OAAO;AAC/C,SAAM,qBAAqB,KAAK,WAAW,OAAO;AAClD,SAAM,yBAAyB,KAAK,WAAW,OAAO;AACtD,SAAM,sBAAsB,KAAK,WAAW,OAAO;AACnD,SAAM,sBAAsB,KAAK,WAAW,OAAO;AACnD,SAAM,wBAAwB,KAAK,WAAW,OAAO;AACrD,SAAM,uBAAuB,KAAK,WAAW,OAAO;AACpD,SAAM,uBAAuB,KAAK,WAAW,OAAO;AACpD,SAAM,wBAAwB,KAAK,WAAW,OAAO;AACrD,SAAM,8BAA8B,KAAK,WAAW,OAAO;AAC3D,SAAM,yBAAyB,KAAK,WAAW,OAAO;AACtD,SAAM,oBAAoB,KAAK,WAAW,OAAO;AAEjD,yBAAsB,KAAK,OAAO;AAClC,uBAAoB,KAAK,OAAO;AAChC,uBAAoB,KAAK,OAAO;AAChC,sBAAmB,KAAK,OAAO;AAC/B,yBAAsB,KAAK,OAAO;AAClC,qBAAkB,KAAK,OAAO;AAC9B,mBAAgB,KAAK,OAAO;;AAG9B,gBAAc,KAAK,OAAO;AAS1B,SAAO;GAAE,SAAS;GAAM,MAPM;IAC5B,MAAM,IAAI,OAAO,OAAO,YAAY;IACpC,WAAW,IAAI,cAAc;IAC7B,gBAAgB,IAAI,mBAAmB;IACvC;IACD;GAE6B;UACvB,OAAO;AACd,SAAO;GAAE,SAAS;GAAO,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAAE;;;;;;AC5F5F,MAAaC,qBAA0C,IAAI,IAAI;CAC7D,CAAC,0BAA0B;;;;;;;;;;;;;;;;;EAiB3B;CACA,CAAC,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmJ7B;CACA,CAAC,qCAAqC;;;;;;EAMtC;CACA,CAAC,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BzB;CACA,CAAC,yBAAyB;;;;;;;;;;EAU1B;CACA,CAAC,0BAA0B;;;EAG3B;CACA,CAAC,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAiDhB;CACJ,CAAC,uBAAuB;;;;;;;;;;;;;;;;EAgBxB;CACA,CAAC,0BAA0B;;;;;SAKpB;CACP,CAAC,8BAA8B;;;EAG/B;CACA,CAAC,qBAAqB;;;;SAIf;CACP,CAAC,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BnC;CACA,CAAC,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BpC;CACA,CAAC,oCAAoC;;;;;;;;;;;;;;;;;;EAkBrC;CACA,CAAC,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4B7B;CACA,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;EAkBzC;CACA,CAAC,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BrC;CACA,CAAC,0BAA0B;EAC3B;CACA,CAAC,qCAAqC;;;;;;;;;;;;;;;;;;;EAmBtC;CACA,CAAC,sCAAsC;;;;;;;EAOvC;CACA,CAAC,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;EAwB/B;CACA,CAAC,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BtC;CACA,CAAC,sCAAsC;;;;;;;;;EASvC;CACA,CAAC,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkFtC;CACA,CAAC,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BvC;CACA,CAAC,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8ChC;CACA,CAAC,sCAAsC;;;;;;;;EAQvC;CACA,CAAC,qCAAqC;;;;;;;;;;;;;;;;;;;;;EAqBtC;CACA,CAAC,qCAAqC;;;;;;;;;;;;;;;;;EAiBtC;CACA,CAAC,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BhC;CACA,CAAC,yBAAyB;;;;;;;EAO1B;CACA,CAAC,2BAA2B;;;;;;;;EAQ5B;CACA,CAAC,0BAA0B;;;;;;;;;;;;EAY3B;CACA,CAAC,yCAAyC;;;;;;;;;;;;;;;;;;;;;EAqB1C;CACA,CAAC,sCAAsC;;;;;;;;;;EAUvC;CACA,CAAC,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0CjC;CACA,CAAC,6BAA6B;;;;;;;;;;;;;;;;;;;;;;EAsB9B;CACA,CAAC,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;EAwBpC;CACA,CAAC,6BAA6B;;;;;;;;;;;;;EAa9B;CACA,CAAC,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BrC;CACA,CAAC,qCAAqC;;;;;;;;;;;;;;;;;;;;KAoBnC;CACH,CAAC,6BAA6B;;;;;;;;;;YAUpB;CACV,CAAC,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;EAwBnC;CACA,CAAC,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BrC;CACA,CAAC,mCAAmC;;;;;;;;;;;;;;;;;;EAkBpC;CACA,CAAC,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2B7B;CACA,CAAC,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+QtC;CACA,CAAC,mCAAmC;;;;;;;;;;EAUpC;CACA,CAAC,iCAAiC;;;;;;GAMjC;CACD,CAAC,kCAAkC;;;EAGnC;CACA,CAAC,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgDxC;CACA,CAAC,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8CpC;CACA,CAAC,yBAAyB;EAC1B;CACA,CAAC,oCAAoC;;;;;;;;;;;;;;;;;;EAkBrC;CACA,CAAC,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;EAuB9B;CACA,CAAC,oCAAoC;;;;;EAKrC;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgC1C;CACD,CAAC,4BAA4B;;;;;;;;;;;;;GAa5B;CACD,CAAC,6BAA6B;;;;;;;;;GAS7B;CACD,CAAC,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmCvB;CACA,CAAC,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgGhC;CACA,CAAC,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;EAwBrC;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;EAe3C;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkC3C;CACA,CAAC,0CAA0C;;;;;;;;;;;;EAY3C;CACA,CAAC,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgCxC;CACA,CAAC,kDAAkD;;;;;;;;;;;;;;;;;EAiBnD;CACA,CAAC,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgClD;CACA,CAAC,uCAAuC;;;;;;;;;;;;;EAaxC;CACA,CAAC,yCAAyC;;;;;;;;;;;;;EAa1C;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8F3C;CACA,CAAC,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCxC;CACA,CAAC,sCAAsC;;;;;;;;;;;;;;;;EAgBvC;CACA,CAAC,mCAAmC;;EAEpC;CACA,CAAC,oCAAoC;;;;EAIrC;CACA,CAAC,uCAAuC;;;;;;;;EAQxC;CACA,CAAC,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;EAyBnC;CACA,CAAC,mCAAmC;;;;;;;;;;;;;;;;;;EAkBpC;CACA,CAAC,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCrC;CACA,CAAC,gCAAgC;;;;;;;;;;;;;EAajC;CACA,CAAC,gCAAgC;;;;;;;;;;;;EAYjC;CACA,CAAC,+BAA+B;;;;;EAKhC;CACA,CAAC,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BhD;CACA,CAAC,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4DvC;CACA,CAAC,sCAAsC,gBAAgB;CACvD,CAAC,kDAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+CnD;CACA,CAAC,mDAAmD;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BpD;CACA,CAAC,oDAAoD;;;;;;;;;;;;;;;;;;;;;;EAsBrD;CACA,CAAC,mDAAmD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+CpD;CACA,CAAC,iDAAiD;;;;;;;;;;;;;EAalD;CACA,CAAC,oDAAoD;;;;;;;;;;;;;;;;;;EAkBrD;CACA,CAAC,qDAAqD;;;;;;;;;;;;;;;;;;;;KAoBnD;CACH,CAAC,uCAAuC;;;;EAIxC;CACA,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwCzC;CACA,CAAC,yCAAyC;;;;;EAK1C;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;EAsB3C;CACA,CAAC,8CAA8C;;;;;EAK/C;CACA,CAAC,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyC1C;CACA,CAAC,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6CxC;CACA,CAAC,gCAAgC;;;;;;EAMjC;CACA,CAAC,mCAAmC;;;;;;;;;;;;;EAapC;CACA,CAAC,sDAAsD;;;;;;EAMvD;CACA,CAAC,gDAAgD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgDjD;CACA,CAAC,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BlD;CACA,CAAC,kDAAkD;;;;;;;;;;;KAWhD;CACH,CAAC,yCAAyC;;;;;;;;;;;;;;;;;;EAkB1C;CACA,CAAC,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmCvC;CACA,CAAC,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BrC;CACA,CAAC,yCAAyC;;;;;;;;;EAS1C;CACA,CAAC,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BvC;CACA,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkEzC;CACA,CAAC,qCAAqC;;;;;;;;;;EAUtC;CACA,CAAC,oCAAoC;;;EAGrC;CACA,CAAC,iCAAiC;;;;;EAKlC;CACA,CAAC,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCpC;CACA,CAAC,sCAAsC;;;EAGvC;CACA,CAAC,oCAAoC,gBAAgB;CACrD,CAAC,mCAAmC;;EAEpC;CACA,CAAC,iCAAiC;;;;;;;;;;;;;;;;;EAiBlC;CACA,CAAC,uCAAuC;;;;;;;;;;;;;;;EAexC;CACA,CAAC,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiG7B;CACH,CAAC,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAsC5B;CACP,CAAC,kCAAkC;;;;;;;;;;;;;;;;;;;;KAoBhC;CACH,CAAC,qCAAqC;;;;EAItC;CACA,CAAC,+BAA+B;EAChC;CACA,CAAC,0CAA0C;;EAE3C;CACA,CAAC,iDAAiD;;;;;EAKlD;CACA,CAAC,gDAAgD;;;;;;;;;EASjD;CACA,CAAC,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmD/C;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkG3C;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiD3C;CACA,CAAC,iDAAiD;;;;;;;;;;;;;;;;;;;;;EAqBlD;CACA,CAAC,+CAA+C;;;;;;;;;;;;EAYhD;CACA,CAAC,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2B/C;CACA,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;sBAuBrB;CACpB,CAAC,4CAA4C;;;;;;;;;EAS7C;CACA,CAAC,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmD1C;CACA,CAAC,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkDtC;CACA,CAAC,0CAA0C;;;;;;;;;;;EAW3C;CACA,CAAC,mCAAmC;;;;;;;;;;;;;;;;;;EAkBpC;CACA,CAAC,+CAA+C;;;;;;;;;;;;;EAahD;CACA,CAAC,sCAAsC;;;;;EAKvC;CACA,CAAC,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqD5C;CACD,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;;EAmBzC;CACA,CAAC,6CAA6C;;;;;;;;;;;;;GAa7C;CACD,CAAC,sCAAsC;;;;;;;;;;;;;;;;;;;;;EAqBvC;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;EAkB3C;CACA,CAAC,6CAA6C;;;;;;;;;;;;;;;;;;;EAmB9C;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;EAmB3C;CACA,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;;;KAoBtC;CACH,CAAC,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;KAwBvC;CACH,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;;EAqB5C;CACA,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4B5C;CACA,CAAC,qCAAqC;;;;;;;;;;;;;;EActC;CACA,CAAC,sCAAsC;;;;;;;;EAQvC;CACA,CAAC,+BAA+B;;EAEhC;CACA,CAAC,uCAAuC;;;;;;;;;;;;;;EAcxC;CACA,CAAC,wCAAwC;;;;;;;;EAQzC;CACA,CAAC,iCAAiC;EAClC;CACA,CAAC,0CAA0C;;;;;;;;;;;;;EAa3C;CACA,CAAC,wCAAwC;;;EAGzC;CACA,CAAC,+CAA+C;;;EAGhD;CACA,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;EAoB5C;CACA,CAAC,oCAAoC;;;;;;;;;;;;;;;;;;;;EAoBrC;CACA,CAAC,kDAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+FnD;CACA,CAAC,kDAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0InD;CACA,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4KzC;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoG3C;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0I3C;CACA,CAAC,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA+EzB;CACd,CAAC,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4HnC;CACA,CAAC,kCAAkC;EACnC;CACA,CAAC,yCAAyC;;;;;;;;;;;;;;EAc1C;CACA,CAAC,oCAAoC;;;;;;;;;;;;;;GAcpC;CACD,CAAC,qCAAqC;;;;;;;;;GASrC;CACD,CAAC,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkC/B;CACA,CAAC,kDAAkD;;;;;;;;;;;;;;;;;;;;;;EAsBnD;CACA,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoiB5C;CACA,CAAC,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+E/C;CACA,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2D5C;CACA,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmRzC;CACA,CAAC,0DAA0D;;;;;;;;;;;;;;;;;;;;;;iCAsB5B;CAC/B,CAAC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;+BAuB5B;CAC7B,CAAC,2DAA2D;;;;;;;;;;;;;;;;;;;;;;kCAsB5B;CAChC,CAAC,oCAAoC;;;;;;;;;;;;;GAapC;CACD,CAAC,qCAAqC;;;;;;;;;GASrC;CACD,CAAC,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkC/B;CACA,CAAC,4CAA4C;;;;;;;;;;;;;;EAc7C;CACA,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;EAyB5C;CACA,CAAC,6CAA6C;;;;;;;;;;;;;;;EAe9C;CACA,CAAC,sCAAsC;;;;EAIvC;CACA,CAAC,4CAA4C;;;;;;;;;EAS7C;CACA,CAAC,wCAAwC;;;;;;;;;;;;;;;;;EAiBzC;CACA,CAAC,yCAAyC;;;;;;;;;;;;;EAa1C;CACA,CAAC,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuDnC;CACA,CAAC,yCAAyC;;;;;;;;;;;;EAY1C;CACA,CAAC,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiC7C;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;EAgB3C;CACA,CAAC,mCAAmC;;;;;;;;;;;;;;;;;;;EAmBpC;CACA,CAAC,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwD5D;CACA,CAAC,iDAAiD;;;;;;;;;;;;;GAajD;CACD,CAAC,kDAAkD;;;;;;;;;GASlD;CACD,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkC5C;CACA,CAAC,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4FhD;CACA,CAAC,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsDlD;CACA,CAAC,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwCrD;CACA,CAAC,oCAAoC;;EAErC;CACA,CAAC,6CAA6C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+K9C;CACA,CAAC,mDAAmD;;;EAGpD;CACA,CAAC,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuDhD;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgF3C;CACA,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8B5C;CACA,CAAC,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgJrD;CACA,CAAC,mDAAmD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0FpD;CACA,CAAC,0CAA0C;;;;;EAK3C;CACA,CAAC,0CAA0C;;;;;;;;EAQ3C;CACA,CAAC,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BlD;CACA,CAAC,kDAAkD,gBAAgB;CACnE,CAAC,6CAA6C;;;;EAI9C;CACA,CAAC,gDAAgD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8LjD;CACA,CAAC,0CAA0C;;EAE3C;CACA,CAAC,2CAA2C;;;;EAI5C;CACA,CAAC,yCAAyC;;;;;;;;;;;;;;;;;;;;;;EAsB1C;CACA,CAAC,6CAA6C;;;;;;;;;;;;;;;;;;;EAmB9C;CACA,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqD5C;CACA,CAAC,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6B/C;CACA,CAAC,gDAAgD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BjD;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6B3C;CACA,CAAC,oCAAoC;;;;;;;;;;;;;;;;;;EAkBrC;CACA,CAAC,uCAAuC;;;;;;;;;;;;;EAaxC;CACA,CAAC,6CAA6C;;;;;;;;;;;;;;;;;;EAkB9C;CACA,CAAC,uCAAuC;;;;;;;;;;;;;;;;;;;;;EAqBxC;CACA,CAAC,4CAA4C;;;;;;;;;EAS7C;CACA,CAAC,gDAAgD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsCjD;CACA,CAAC,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkC7C;CACA,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwE5C;CACA,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;;;;;EAsBzC;CACA,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;;;EAsB5C;CACA,CAAC,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwChD;CACA,CAAC,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiG1C;CACA,CAAC,6CAA6C;;;;;;;;;;;;;;;;;;;;;;EAsB9C;CACA,CAAC,6CAA6C;;;;;;;;;;EAU9C;CACA,CAAC,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6E7C;CACA,CAAC,kDAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6CnD;CACA,CAAC,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyC7C;CACA,CAAC,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BhD;CACA,CAAC,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiErD;CACA,CAAC,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiChD;CACA,CAAC,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyKlD;CACA,CAAC,4DAA4D;;;;;;;;EAQ7D;CACA,CAAC,0DAA0D;;;;;;;;;;;;;;;EAe3D;CACA,CAAC,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoC/D;CACA,CAAC,qCAAqC;;;;;;;;;;;;EAYtC;CACA,CAAC,uDAAuD;;;;;;;;;EASxD;CACA,CAAC,qDAAqD;;;;;;;;;;;;;;;;;;;;;;;;;EAyBtD;CACA,CAAC,yDAAyD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+C1D;CACA,CAAC,6CAA6C;;;;;;;;;;;;;;;;;;;EAmB9C;CACA,CAAC,oDAAoD;;;;;;;;;;;;;;;;;;;;EAoBrD;CACA,CAAC,2DAA2D;;;;;;;;;;;;EAY5D;CACA,CAAC,uCAAuC;;;;;;;;;;;;;;;;;;;EAmBxC;CACA,CAAC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCzD;CACA,CAAC,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmC5D;CACA,CAAC,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiEhD;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkC3C;CACA,CAAC,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoK5C;CACD,CAAC,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BrC;CACA,CAAC,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8D/D;CACA,CAAC,sCAAsC;;;;;EAKvC;CACA,CAAC,kDAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BnD;CACA,CAAC,6CAA6C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqC9C;CACA,CAAC,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmI/C;CACD,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SA2ClC;CACP,CAAC,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsDtC;CACA,CAAC,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAoEjC;CACP,CAAC,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAsD9B;CACP,CAAC,wCAAwC;;;;;;;;;;EAUzC;CACA,CAAC,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;SAwB/B;CACP,CAAC,sCAAsC;;;;;;;;;;;;;;;;;;;;;;EAsBvC;CACA,CAAC,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuCvC;CACA,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BzC;CACA,CAAC,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BtC;CACA,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;EAyB5C;CACA,CAAC,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoDxC;CACA,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;;EAmBzC;CACA,CAAC,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkJ1C;CACA,CAAC,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuGxC;CACA,CAAC,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkJxC;CACA,CAAC,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoEtC;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;EAwB3C;CACA,CAAC,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;EAuBxC;CACA,CAAC,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuCvC;CACA,CAAC,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuC1C;CACA,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8H5C;CACA,CAAC,uCAAuC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BxC;CACA,CAAC,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BhD;CACA,CAAC,mDAAmD;;;;;;;;;;;;EAYpD;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgC3C;CACA,CAAC,gDAAgD;;;;;;;;EAQjD;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuE3C;CACA,CAAC,yCAAyC;;;;;;;;;;;EAW1C;CACA,CAAC,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;EA0B7C;CACA,CAAC,oDAAoD;;;;;;;;;;;;;;;EAerD;CACA,CAAC,8CAA8C;;EAE/C;CACA,CAAC,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuCtC;CACA,CAAC,uDAAuD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiYxD;CACA,CAAC,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoJvC;CACA,CAAC,oCAAoC;;;;;;;;;;;;;;;;;;;;;EAqBrC;CACA,CAAC,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqCtC;CACA,CAAC,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoJvC;CACA,CAAC,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BrC;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0H3C;CACA,CAAC,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuJhD;CACA,CAAC,6CAA6C;;;;;;;;;;;;;;;;;;;EAmB9C;CACA,CAAC,6CAA6C;;;;;;;;;EAS9C;CACA,CAAC,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqC/C;CACA,CAAC,4CAA4C;;;;EAI7C;CACA,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2L5C;CACA,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2KzC;CACA,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgVzC;CACA,CAAC,sDAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoEvD;CACA,CAAC,sDAAsD;;;;;;;;;;;;EAYvD;CACA,CAAC,6DAA6D;;;;;;EAM9D;CACA,CAAC,6DAA6D;;;;;;;;;;;;;;;;;EAiB9D;CACA,CAAC,uDAAuD;;;;;;;;;;;;EAYxD;CACA,CAAC,uDAAuD;;;;;;;;;;;;;;;;EAgBxD;CACA,CAAC,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAoU3C;CACP,CAAC,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwG5D;CACA,CAAC,wDAAwD;EACzD;CACA,CAAC,sDAAsD;;;;;;;;;;EAUvD;CACA,CAAC,sDAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwGvD;CACA,CAAC,mDAAmD;EACpD;CACA,CAAC,uDAAuD;;;;;;;;;;;;;;;;EAgBxD;CACA,CAAC,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+H5D;CACH,CAAC,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAsF3C;CACpB,CAAC,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsJ5D;CACA,CAAC,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAkItC;CACtB,CAAC,yDAAyD;;;;;;;;;EAS1D;CACA,CAAC,yDAAyD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8E1D;CACA,CAAC,gDAAgD;;;;;;EAMjD;CACA,CAAC,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyC7D;CACA,CAAC,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgN5D;CACA,CAAC,0DAA0D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqF3D;CACA,CAAC,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuG7D;CACA,CAAC,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqF5D;CACA,CAAC,wEAAwE;;;;;;;;;;;EAWzE;CACA,CAAC,qEAAqE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BtE;CACA,CAAC,gEAAgE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6JjE;CACA,CAAC,gEAAgE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2IjE;CACA,CAAC,2CAA2C,gBAAgB;CAC5D,CAAC,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+E7C;CACA,CAAC,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4E/C;CACA,CAAC,+DAA+D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwDhE;CACA,CAAC,6DAA6D;;;;;;;;;;;EAW9D;CACA,CAAC,0DAA0D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqC3D;CACA,CAAC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyFzD;CACA,CAAC,yDAAyD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqF1D;CACA,CAAC,qEAAqE;;;;;;;;;;;EAWtE;CACA,CAAC,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BnE;CACA,CAAC,iDAAiD;;;;;;;;;;;;;;;;;EAiBlD;CACA,CAAC,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoGzC;CACA,CAAC,sCAAsC;;;;;;;;;;;;;;;;;;;;EAoBvC;CACA,CAAC,0CAA0C;;;;;;;;;;;;EAY3C;CACA,CAAC,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BlD;CACA,CAAC,yCAAyC;;EAE1C;CACA,CAAC,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;EAuB/D;CACA,CAAC,0DAA0D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuF3D;CACA,CAAC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA4UrD;CACJ,CAAC,oEAAoE;;;;;;;;;;;;;;;;;;;EAmBrE;CACA,CAAC,gEAAgE;;;;;;;;;;;;;;;;;;;;;;;EAuBjE;CACA,CAAC,mEAAmE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgCpE;CACA,CAAC,gEAAgE;;;;;;;;;;;;;;;;;;;;;;;EAuBjE;CACA,CAAC,qDAAqD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0FtD;CACA,CAAC,mDAAmD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAyOjD;CACH,CAAC,6DAA6D,gBAAgB;CAC9E,CAAC,qDAAqD,gBAAgB;CACtE,CAAC,wDAAwD,gBAAgB;CACzE,CAAC,kEAAkE,gBAAgB;CACnF,CAAC,sDAAsD,gBAAgB;CACvE,CAAC,wDAAwD,gBAAgB;CACzE,CAAC,+CAA+C,gBAAgB;CAChE,CAAC,kEAAkE,gBAAgB;CACnF,CAAC,kDAAkD,gBAAgB;CACnE,CAAC,kEAAkE,gBAAgB;CACnF,CAAC,qDAAqD;;;;;;;;;;;;;;;;;;;EAmBtD;CACA,CAAC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BA0F7B;CAC5B,CAAC,sDAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8LtD;CACD,CAAC,2CAA2C;;;;;;YAMlC;CACV,CAAC,mDAAmD;;;;;;;;;;;;;;;;;;;;GAoBnD;CACD,CAAC,sDAAsD;;;;;;;;;;;;;;;;;;;;;EAqBvD;CACA,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyE3C;CACA,CAAC,6CAA6C;;;;;;;;;;EAU9C;CACA,CAAC,oDAAoD;;;;;;;;;;;;;;;;;;EAkBrD;CACA,CAAC,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwChD;CACA,CAAC,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2E/C;CACA,CAAC,6CAA6C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6C9C;CACA,CAAC,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6D7C;CACA,CAAC,6CAA6C;;;;;;;;;;EAU9C;CACA,CAAC,8CAA8C;;;;;;;;;;EAU/C;CACA,CAAC,qDAAqD;;;;;;;;;EAStD;CACA,CAAC,yDAAyD;;;;;;;;;;;;;;;;;EAiB1D;CACA,CAAC,kDAAkD;;;;;;;;;;;;;;;;;;;;;EAqBnD;CACA,CAAC,qDAAqD;;;;;;;;;;;;;EAatD;CACA,CAAC,iDAAiD;;;;;;;;;EASlD;CACA,CAAC,qDAAqD;;;;;;;;;EAStD;CACA,CAAC,yDAAyD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2D1D;CACA,CAAC,oDAAoD;;;;;;;;;;;;;;;EAerD;CACA,CAAC,uDAAuD;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BxD;CACA,CAAC,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwInE;CACA,CAAC,+DAA+D;;;;;;;;;;;;;;;;;EAiBhE;CACA,CAAC,wDAAwD;;;;;;;;;;;EAWzD;CACA,CAAC,6DAA6D;;;;;;;EAO9D;CACA,CAAC,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;EAyB7D;CACA,CAAC,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0FrD;CACA,CAAC,qDAAqD;;;;;;;;;;;;EAYtD;CACA,CAAC,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuD7C;CACA,CAAC,kDAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwDnD;CACA,CAAC,6DAA6D;;;;;;;;;;;;;;;;EAgB9D;CACA,CAAC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BzD;CACA,CAAC,wDAAwD;;;;;;;;;;;;;;;;;;EAkBzD;CACA,CAAC,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuD7C;CACA,CAAC,qDAAqD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmEtD;CACA,CAAC,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2MnE;CACA,CAAC,sDAAsD;;;;;;;;;;;;;;;;EAgBvD;CACA,CAAC,sDAAsD;;;;;;;;;;;;;;;;EAgBvD;CACA,CAAC,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4C/D;CACA,CAAC,qDAAqD;;;;;;;;;;;;;;;;;;;;EAoBtD;CACA,CAAC,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqCrD;CACA,CAAC,qDAAqD;;;;;;;;;;;EAWtD;CACA,CAAC,qDAAqD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8KtD;CACA,CAAC,uDAAuD;;;;;;;;;;;;;;;;;;;;;;;EAuBxD;CACA,CAAC,sDAAsD;;;;;;;EAOvD;CACA,CAAC,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwH7D;CACA,CAAC,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqN/D;CACA,CAAC,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BrE;CACA,CAAC,qDAAqD;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BtD;CACA,CAAC,yDAAyD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmG1D;CACA,CAAC,qDAAqD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+GtD;CACA,CAAC,uDAAuD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8GxD;CACA,CAAC,+DAA+D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkFhE;CACA,CAAC,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0C9D;CACA,CAAC,+DAA+D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2FhE;CACA,CAAC,uEAAuE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiJxE;CACA,CAAC,uEAAuE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+HxE;CACA,CAAC,4DAA4D;;;;;;;;;;;;;;;;;;;;;EAqB7D;CACA,CAAC,wDAAwD;;;;;;;;;;;;;;EAczD;CACA,CAAC,8DAA8D;;;;;;;;;;;;;;;;;;EAkB/D;CACA,CAAC,2DAA2D;;;;;;;;;;;;EAY5D;CACA,CAAC,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsR/D;CACA,CAAC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgIzD;CACA,CAAC,qEAAqE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqFtE;CACA,CAAC,qEAAqE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyEtE;CACA,CAAC,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0InE;CACA,CAAC,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+HnE;CACA,CAAC,0DAA0D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsO3D;CACA,CAAC,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoFrD;CACA,CAAC,mDAAmD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2IpD;CACA,CAAC,kDAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsNnD;CACA,CAAC,gDAAgD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwFjD;CACA,CAAC,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuDlD;CACA,CAAC,0DAA0D;;;;;;;;;;;;EAY3D;CACA,CAAC,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0H9D;CACD,CAAC,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6GrE;CACA,CAAC,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoDnE;CACA,CAAC,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8IrE;CACA,CAAC,mDAAmD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+IpD;CACA,CAAC,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAyLzD;CACH,CAAC,uDAAuD;;;;;;;;;;;;;;;;;;;;;;;EAuBxD;CACA,CAAC,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmE5D;CACA,CAAC,+DAA+D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuDhE;CACA,CAAC,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4HnE;CACA,CAAC,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoJnE;CACA,CAAC,yDAAyD;;;;;;;;;;;;EAY1D;CACA,CAAC,qDAAqD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiFtD;CACA,CAAC,8DAA8D;;;;;;;;;;;;;EAa/D;CACA,CAAC,mEAAmE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsQpE;CACA,CAAC,2DAA2D;;;;;;;;;;;;;;;;;;;;EAoB5D;CACA,CAAC,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyD7D;CACA,CAAC,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;;;;EA0B/D;CACA,CAAC,2DAA2D;;;;;;;;;;;;;;;;;;;;EAoB5D;CACA,CAAC,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4C7D;CACA,CAAC,0DAA0D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuG3D;CACA,CAAC,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2C9D;CACA,CAAC,iEAAiE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+KlE;CACA,CAAC,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0D9D;CACA,CAAC,gEAAgE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4PjE;CACA,CAAC,+DAA+D;;;;;;;;;;;;;;;;;EAiBhE;CACA,CAAC,gEAAgE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2LjE;CACA,CAAC,kDAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+MnD;CACA,CAAC,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwE9D;CACA,CAAC,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwDrE;CACA,CAAC,kEAAkE;;;;;;;;;;;;;;;;;;;;;;;;EAwBnE;CACA,CAAC,4DAA4D;;;;;;;;;;;;;;;EAe7D;CACA,CAAC,gEAAgE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6CjE;CACA,CAAC,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+D7D;CACA,CAAC,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgCrD;CACA,CAAC,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAyC3D;CACH,CAAC,kDAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4NnD;CACA,CAAC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAwgBtD;CACH,CAAC,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoIrD;CACA,CAAC,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyR3D;CACD,CAAC,sDAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2UvD;CACA,CAAC,0DAA0D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmE3D;CACA,CAAC,2DAA2D;;;;;;;;;EAS5D;CACA,CAAC,mDAAmD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0kBpD;CACA,CAAC,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoV9D;CACA,CAAC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4kBzD;CACA,CAAC,6CAA6C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAqDnC;CACX,CAAC,iEAAiE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuClE;CACA,CAAC,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqC9D;CACA,CAAC,+DAA+D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqChE;CACA,CAAC,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyC7D;CACA,CAAC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2CzD;CACA,CAAC,0DAA0D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2C3D;CACA,CAAC,+DAA+D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8ChE;CACA,CAAC,2DAA2D;;;;;;;;;;;;;;;EAe5D;CACA,CAAC,6DAA6D;;;;;;;;;;;;;;;EAe9D;CACA,CAAC,kDAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqEnD;CACA,CAAC,qDAAqD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkEtD;CACA,CAAC,uDAAuD;;;;;;;;;;;;;;;;;;;;;;;;EAwBxD;CACA,CAAC,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;EAwBzD;CACA,CAAC,iEAAiE;;;;;;;;;;;;;;;;;;;;;;;;EAwBlE;CACA,CAAC,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyC/C;CACA,CAAC,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmD9D;CACA,CAAC,mDAAmD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmDpD;CACA,CAAC,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmDrD;CACA,CAAC,+DAA+D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsNhE;CACA,CAAC,6CAA6C;;;;;;EAM9C;CACA,CAAC,+CAA+C;;;;;;;;;;;;;;;;;;;;;EAqBhD;CACA,CAAC,6CAA6C;;;;;;;;;;;;EAY9C;CACA,CAAC,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuClD;CACA,CAAC,gDAAgD;;;;;;;;;;;;EAYjD;CACA,CAAC,4CAA4C,gBAAgB;CAC7D,CAAC,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;EAuBrD;CACA,CAAC,kDAAkD;;;;;;;;;;;;EAYnD;CACA,CAAC,6CAA6C;;;;;;;EAO9C;CACA,CAAC,4CAA4C;;;;;;;;;;;;;;;;EAgB7C;CACA,CAAC,2CAA2C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8B5C;CACA,CAAC,8EAA8E;;;;;;;;;;;;;;;;;;;;;EAqB/E;CACA,CAAC,+EAA+E;;;;;;;;;;;;;;;;;;;;;EAqBhF;CACA,CAAC,6CAA6C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgC9C;CACA,CAAC,kDAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4CnD;CACA,CAAC,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8B7C;CACA,CAAC,4EAA4E;;;;;;;;;;;;;;;;;;EAkB7E;CACA,CAAC,kEAAkE;;;;;;;;;;;;;;;EAenE;CACA,CAAC,yEAAyE;;;;;;;;;;;;;;;EAe1E;CACA,CAAC,qEAAqE;;;;;;;;;;;;;;;;;;EAkBtE;CACA,CAAC,kEAAkE;;;;;;;;;;;;;;;EAenE;CACA,CAAC,wEAAwE;;;;;;;;;;;;;;;;;;;;;EAqBzE;CACA,CAAC,uEAAuE;;;;;;;;;;;;;;;;;;;;;EAqBxE;CACA,CAAC,qEAAqE;;;;;;;;;;;;;;;;;;EAkBtE;CACA,CAAC,wEAAwE;;;;;;;;;;;;;;;;;;;;;;;;EAwBzE;CACA,CAAC,uEAAuE;;;;;;;;;;;;;;;;;;;;;;;;EAwBxE;CACA,CAAC,yDAAyD;;;;;;;;;;;;;;;;EAgB1D;CACA,CAAC,uEAAuE;;;;;;;;;;;;;;;;;;;EAmBxE;CACA,CAAC,oEAAoE;;;;;;;;;;;;;EAarE;CACA,CAAC,sEAAsE;;;;;;;;;;;;;;;;;;;EAmBvE;CACA,CAAC,4EAA4E;;;;;;;;;;;;;;;EAe7E;CACA,CAAC,iEAAiE;;;;;;;;;;;;EAYlE;CACA,CAAC,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8G7D;CACA,CAAC,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmE7D;CACA,CAAC,4DAA4D;;;;;;;;;;;;EAY7D;CACA,CAAC,+DAA+D;;;;;;;IAO9D;CACF,CAAC,0DAA0D;;;;;;;;;;;;EAY3D;CACA,CAAC,uEAAuE;;;;;;;;;;;;;;;;;;EAkBxE;CACA,CAAC,2EAA2E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuE5E;CACA,CAAC,+EAA+E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+DhF;CACA,CAAC,kFAAkF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuInF;CACA,CAAC,kFAAkF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgKnF;CACA,CAAC,sEAAsE;;;;;;;;;;;;;;;;;;EAkBvE;CACA,CAAC,0EAA0E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmF1E;CACD,CAAC,8EAA8E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+D/E;CACA,CAAC,iFAAiF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuIlF;CACA,CAAC,iFAAiF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgKlF;CACA,CAAC,2EAA2E;;;;;IAK1E;CACF,CAAC,4EAA4E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6D7E;CACA,CAAC,+EAA+E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuIhF;CACA,CAAC,+EAA+E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgKhF;CACA,CAAC,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8DrE;CACA,CAAC,uEAAuE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuIxE;CACA,CAAC,uEAAuE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgKxE;CACA,CAAC,wEAAwE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BzE;CACA,CAAC,oEAAoE;;;;;;;;;;;;;EAarE;CACA,CAAC,wEAAwE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgFzE;CACA,CAAC,8DAA8D;;;;;;;;;;;;;;;;EAgB/D;CACA,CAAC,qEAAqE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2DtE;CACA,CAAC,iEAAiE;;;;;;;;;;;;EAYlE;CACA,CAAC,2DAA2D;;;;;;;;;;;;;;;;;;EAkB5D;CACA,CAAC,iEAAiE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4DlE;CACA,CAAC,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmKrE;CACA,CAAC,iEAAiE;;;;;;;;EAQlE;CACA,CAAC,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuMrE;CACA,CAAC,4DAA4D;;;;;;;EAO7D;CACA,CAAC,0DAA0D;;;;;;;EAO3D;CACA,CAAC,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuPrE;CACA,CAAC,qEAAqE;;;;;;;EAOtE;CACA,CAAC,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6T/D;CACA,CAAC,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2E9D;CACA,CAAC,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoH7D;CACA,CAAC,mEAAmE;;;;;;;EAOpE;CACA,CAAC,mEAAmE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgRpE;CACA,CAAC,yDAAyD;;;;;;;EAO1D;CACA,CAAC,sEAAsE;;;;;;;EAOvE;CACA,CAAC,iEAAiE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkPlE;CACA,CAAC,oEAAoE;;;;;;;EAOrE;CACA,CAAC,sEAAsE;;;;;;;;;;;;;;;;;;;;;;;;EAwBvE;CACA,CAAC,yDAAyD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2G1D;CACA,CAAC,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkE/D;CACA,CAAC,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAylB/D;CACA,CAAC,4DAA4D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAukB7D;CACA,CAAC,+DAA+D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqP5D;CACA,CAAC,sDAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2oBvD;CACA,CAAC,0DAA0D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuL3D;CACA,CAAC,mEAAmE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuPpE;CACA,CAAC,qEAAqE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyDtE;CACA,CAAC,mEAAmE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsDpE;CACA,CAAC,6DAA6D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0C9D;CACA,CAAC,+DAA+D;;;;;;;;;;;EAWhE;CACA,CAAC,iEAAiE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAyDhE;CACF,CAAC,+DAA+D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmDhE;CACA,CAAC,kEAAkE;;;;;;;;;;;;;;;;;;;;;;EAsBnE;CACA,CAAC,gEAAgE;;;;;;;;;;;;;;;;EAgBjE;CACA,CAAC,yEAAyE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwC1E;CACA,CAAC,mEAAmE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BpE;CACA,CAAC,4EAA4E;;;EAG7E;CACA,CAAC,0EAA0E;;;;EAI3E;CACA,CAAC,wEAAwE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0DzE;CACA,CAAC,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sCAiDjC;CACpC,CAAC,gEAAgE;;;;;;;;;;;;;;EAcjE;CACA,CAAC,iFAAiF;;;;;;;;;;;EAWlF;CACA,CAAC,iFAAiF;;;EAGlF;CACD,CAAC;AAEF,MAAa,iBAAiB"}