@bytespell/shella 0.1.10 → 0.1.13

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 (119) hide show
  1. package/dist/bin/cli.js +1166 -304
  2. package/dist/bin/cli.js.map +1 -1
  3. package/dist/index.js +1166 -304
  4. package/dist/index.js.map +1 -1
  5. package/dist/public/assets/{_baseUniq-xMBLm_vj.js → _baseUniq-EGFlDlSf.js} +1 -1
  6. package/{public/assets/arc-CCivY36l.js → dist/public/assets/arc-BmFavzWc.js} +1 -1
  7. package/{public/assets/architectureDiagram-VXUJARFQ-Cx1ftnZs.js → dist/public/assets/architectureDiagram-VXUJARFQ-CZnDNYtj.js} +1 -1
  8. package/{public/assets/blockDiagram-VD42YOAC-Dd5J4pAa.js → dist/public/assets/blockDiagram-VD42YOAC-CabGM_NX.js} +1 -1
  9. package/dist/public/assets/{c4Diagram-YG6GDRKO-C4yoJFk1.js → c4Diagram-YG6GDRKO-BTq0tfrY.js} +1 -1
  10. package/dist/public/assets/channel-CNSk0Rnk.js +1 -0
  11. package/dist/public/assets/{chunk-4BX2VUAB-CiImuKHD.js → chunk-4BX2VUAB-DP2HLRAj.js} +1 -1
  12. package/dist/public/assets/{chunk-55IACEB6-V6l1i-_P.js → chunk-55IACEB6-_ByWPNnF.js} +1 -1
  13. package/{public/assets/chunk-B4BG7PRW-DU8Wql9S.js → dist/public/assets/chunk-B4BG7PRW-BkPl9d2w.js} +1 -1
  14. package/{public/assets/chunk-DI55MBZ5-B_Jw-lhj.js → dist/public/assets/chunk-DI55MBZ5-Bx6nm2tL.js} +1 -1
  15. package/dist/public/assets/{chunk-FMBD7UC4-C1LlA37K.js → chunk-FMBD7UC4-DZpP7ydN.js} +1 -1
  16. package/dist/public/assets/{chunk-QN33PNHL-CcgyTGxJ.js → chunk-QN33PNHL-DSX4eX_h.js} +1 -1
  17. package/dist/public/assets/{chunk-QZHKN3VN-C2H0lOPM.js → chunk-QZHKN3VN-1uzZkVFg.js} +1 -1
  18. package/dist/public/assets/{chunk-TZMSLE5B-Cp4Dpzkh.js → chunk-TZMSLE5B-BwKElFeo.js} +1 -1
  19. package/dist/public/assets/classDiagram-2ON5EDUG-CNctsmkW.js +1 -0
  20. package/dist/public/assets/classDiagram-v2-WZHVMYZB-CNctsmkW.js +1 -0
  21. package/dist/public/assets/clone-CUs-4v14.js +1 -0
  22. package/dist/public/assets/{code-block-IT6T5CEO-DOOuyfxG.js → code-block-IT6T5CEO-BoXZl_RQ.js} +1 -1
  23. package/dist/public/assets/{cose-bilkent-S5V4N54A-DefjjRca.js → cose-bilkent-S5V4N54A-Dux9YKGp.js} +1 -1
  24. package/dist/public/assets/{dagre-6UL2VRFP-hHpxpOKX.js → dagre-6UL2VRFP-Bcdq9Aj5.js} +1 -1
  25. package/dist/public/assets/{diagram-PSM6KHXK-ZgZ2X0Q-.js → diagram-PSM6KHXK-CA-sK31I.js} +1 -1
  26. package/dist/public/assets/{diagram-QEK2KX5R-gCeAqKj1.js → diagram-QEK2KX5R-De47GBMW.js} +1 -1
  27. package/dist/public/assets/{diagram-S2PKOQOG-9IyVqMFa.js → diagram-S2PKOQOG-DJm2AaGk.js} +1 -1
  28. package/{public/assets/erDiagram-Q2GNP2WA-Dzm33cik.js → dist/public/assets/erDiagram-Q2GNP2WA-Lu5P0RSi.js} +1 -1
  29. package/{public/assets/flowDiagram-NV44I4VS-BamNhi0g.js → dist/public/assets/flowDiagram-NV44I4VS-DflY4Ld4.js} +1 -1
  30. package/dist/public/assets/{ganttDiagram-JELNMOA3-CrECl9wX.js → ganttDiagram-JELNMOA3-B8jvAfhh.js} +1 -1
  31. package/dist/public/assets/{gitGraphDiagram-NY62KEGX-C7_E64uK.js → gitGraphDiagram-NY62KEGX-B5ATDGVE.js} +1 -1
  32. package/dist/public/assets/{graph-CtTAhETf.js → graph-8Q4ZN1_7.js} +1 -1
  33. package/dist/public/assets/index-B-jh1L5n.css +1 -0
  34. package/dist/public/assets/index-BEOKXaJG.js +23 -0
  35. package/dist/public/assets/index-DRWhjxj6.js +1781 -0
  36. package/dist/public/assets/{infoDiagram-WHAUD3N6-CLOougXO.js → infoDiagram-WHAUD3N6-qrN7AH1w.js} +1 -1
  37. package/dist/public/assets/{journeyDiagram-XKPGCS4Q-g0dISD-I.js → journeyDiagram-XKPGCS4Q-CnL6w_Jf.js} +1 -1
  38. package/{public/assets/kanban-definition-3W4ZIXB7-DFIVrLyR.js → dist/public/assets/kanban-definition-3W4ZIXB7-tuy_lNx5.js} +1 -1
  39. package/dist/public/assets/{layout-DolajoeL.js → layout-BCBlc1xg.js} +1 -1
  40. package/dist/public/assets/{linear-B5Hf7uIN.js → linear-BzyanBSW.js} +1 -1
  41. package/dist/public/assets/{mermaid.core-DqP3HtOk.js → mermaid.core-CKdMcV_T.js} +5 -5
  42. package/dist/public/assets/{min-UFvm8GLY.js → min-CQR8eUcq.js} +1 -1
  43. package/dist/public/assets/{mindmap-definition-VGOIOE7T-CnSTRcIt.js → mindmap-definition-VGOIOE7T-fQec8JxD.js} +1 -1
  44. package/dist/public/assets/{pieDiagram-ADFJNKIX-CuMH9Po8.js → pieDiagram-ADFJNKIX-BrLsJv83.js} +1 -1
  45. package/{public/assets/quadrantDiagram-AYHSOK5B-6i0SX3Xo.js → dist/public/assets/quadrantDiagram-AYHSOK5B-BPHHSjXt.js} +1 -1
  46. package/dist/public/assets/{requirementDiagram-UZGBJVZJ-ChwO2HU-.js → requirementDiagram-UZGBJVZJ-Bb93lhEQ.js} +1 -1
  47. package/{public/assets/sankeyDiagram-TZEHDZUN-DG-8crEL.js → dist/public/assets/sankeyDiagram-TZEHDZUN-CDK30tx7.js} +1 -1
  48. package/dist/public/assets/{sequenceDiagram-WL72ISMW-BQH_OfEp.js → sequenceDiagram-WL72ISMW-B2WQiW_k.js} +1 -1
  49. package/{public/assets/stateDiagram-FKZM4ZOC-CBOkbVQn.js → dist/public/assets/stateDiagram-FKZM4ZOC-uM1w_xjr.js} +1 -1
  50. package/dist/public/assets/stateDiagram-v2-4FDKWEC3-BGfXuXW9.js +1 -0
  51. package/{public/assets/timeline-definition-IT6M3QCI-CkNd8y6W.js → dist/public/assets/timeline-definition-IT6M3QCI-07DImEJ7.js} +1 -1
  52. package/dist/public/assets/{treemap-KMMF4GRG-D6z_eudj.js → treemap-KMMF4GRG-N0jjjXe0.js} +1 -1
  53. package/{public/assets/xychartDiagram-PRI3JC2R-B5wk4XRt.js → dist/public/assets/xychartDiagram-PRI3JC2R-BV-5VcHE.js} +1 -1
  54. package/dist/public/index.html +15 -2
  55. package/package.json +6 -2
  56. package/public/assets/{_baseUniq-xMBLm_vj.js → _baseUniq-EGFlDlSf.js} +1 -1
  57. package/{dist/public/assets/arc-CCivY36l.js → public/assets/arc-BmFavzWc.js} +1 -1
  58. package/{dist/public/assets/architectureDiagram-VXUJARFQ-Cx1ftnZs.js → public/assets/architectureDiagram-VXUJARFQ-CZnDNYtj.js} +1 -1
  59. package/{dist/public/assets/blockDiagram-VD42YOAC-Dd5J4pAa.js → public/assets/blockDiagram-VD42YOAC-CabGM_NX.js} +1 -1
  60. package/public/assets/{c4Diagram-YG6GDRKO-C4yoJFk1.js → c4Diagram-YG6GDRKO-BTq0tfrY.js} +1 -1
  61. package/public/assets/channel-CNSk0Rnk.js +1 -0
  62. package/public/assets/{chunk-4BX2VUAB-CiImuKHD.js → chunk-4BX2VUAB-DP2HLRAj.js} +1 -1
  63. package/public/assets/{chunk-55IACEB6-V6l1i-_P.js → chunk-55IACEB6-_ByWPNnF.js} +1 -1
  64. package/{dist/public/assets/chunk-B4BG7PRW-DU8Wql9S.js → public/assets/chunk-B4BG7PRW-BkPl9d2w.js} +1 -1
  65. package/{dist/public/assets/chunk-DI55MBZ5-B_Jw-lhj.js → public/assets/chunk-DI55MBZ5-Bx6nm2tL.js} +1 -1
  66. package/public/assets/{chunk-FMBD7UC4-C1LlA37K.js → chunk-FMBD7UC4-DZpP7ydN.js} +1 -1
  67. package/public/assets/{chunk-QN33PNHL-CcgyTGxJ.js → chunk-QN33PNHL-DSX4eX_h.js} +1 -1
  68. package/public/assets/{chunk-QZHKN3VN-C2H0lOPM.js → chunk-QZHKN3VN-1uzZkVFg.js} +1 -1
  69. package/public/assets/{chunk-TZMSLE5B-Cp4Dpzkh.js → chunk-TZMSLE5B-BwKElFeo.js} +1 -1
  70. package/public/assets/classDiagram-2ON5EDUG-CNctsmkW.js +1 -0
  71. package/public/assets/classDiagram-v2-WZHVMYZB-CNctsmkW.js +1 -0
  72. package/public/assets/clone-CUs-4v14.js +1 -0
  73. package/public/assets/{code-block-IT6T5CEO-DOOuyfxG.js → code-block-IT6T5CEO-BoXZl_RQ.js} +1 -1
  74. package/public/assets/{cose-bilkent-S5V4N54A-DefjjRca.js → cose-bilkent-S5V4N54A-Dux9YKGp.js} +1 -1
  75. package/public/assets/{dagre-6UL2VRFP-hHpxpOKX.js → dagre-6UL2VRFP-Bcdq9Aj5.js} +1 -1
  76. package/public/assets/{diagram-PSM6KHXK-ZgZ2X0Q-.js → diagram-PSM6KHXK-CA-sK31I.js} +1 -1
  77. package/public/assets/{diagram-QEK2KX5R-gCeAqKj1.js → diagram-QEK2KX5R-De47GBMW.js} +1 -1
  78. package/public/assets/{diagram-S2PKOQOG-9IyVqMFa.js → diagram-S2PKOQOG-DJm2AaGk.js} +1 -1
  79. package/{dist/public/assets/erDiagram-Q2GNP2WA-Dzm33cik.js → public/assets/erDiagram-Q2GNP2WA-Lu5P0RSi.js} +1 -1
  80. package/{dist/public/assets/flowDiagram-NV44I4VS-BamNhi0g.js → public/assets/flowDiagram-NV44I4VS-DflY4Ld4.js} +1 -1
  81. package/public/assets/{ganttDiagram-JELNMOA3-CrECl9wX.js → ganttDiagram-JELNMOA3-B8jvAfhh.js} +1 -1
  82. package/public/assets/{gitGraphDiagram-NY62KEGX-C7_E64uK.js → gitGraphDiagram-NY62KEGX-B5ATDGVE.js} +1 -1
  83. package/public/assets/{graph-CtTAhETf.js → graph-8Q4ZN1_7.js} +1 -1
  84. package/public/assets/index-B-jh1L5n.css +1 -0
  85. package/public/assets/index-BEOKXaJG.js +23 -0
  86. package/public/assets/index-DRWhjxj6.js +1781 -0
  87. package/public/assets/{infoDiagram-WHAUD3N6-CLOougXO.js → infoDiagram-WHAUD3N6-qrN7AH1w.js} +1 -1
  88. package/public/assets/{journeyDiagram-XKPGCS4Q-g0dISD-I.js → journeyDiagram-XKPGCS4Q-CnL6w_Jf.js} +1 -1
  89. package/{dist/public/assets/kanban-definition-3W4ZIXB7-DFIVrLyR.js → public/assets/kanban-definition-3W4ZIXB7-tuy_lNx5.js} +1 -1
  90. package/public/assets/{layout-DolajoeL.js → layout-BCBlc1xg.js} +1 -1
  91. package/public/assets/{linear-B5Hf7uIN.js → linear-BzyanBSW.js} +1 -1
  92. package/public/assets/{mermaid.core-DqP3HtOk.js → mermaid.core-CKdMcV_T.js} +5 -5
  93. package/public/assets/{min-UFvm8GLY.js → min-CQR8eUcq.js} +1 -1
  94. package/public/assets/{mindmap-definition-VGOIOE7T-CnSTRcIt.js → mindmap-definition-VGOIOE7T-fQec8JxD.js} +1 -1
  95. package/public/assets/{pieDiagram-ADFJNKIX-CuMH9Po8.js → pieDiagram-ADFJNKIX-BrLsJv83.js} +1 -1
  96. package/{dist/public/assets/quadrantDiagram-AYHSOK5B-6i0SX3Xo.js → public/assets/quadrantDiagram-AYHSOK5B-BPHHSjXt.js} +1 -1
  97. package/public/assets/{requirementDiagram-UZGBJVZJ-ChwO2HU-.js → requirementDiagram-UZGBJVZJ-Bb93lhEQ.js} +1 -1
  98. package/{dist/public/assets/sankeyDiagram-TZEHDZUN-DG-8crEL.js → public/assets/sankeyDiagram-TZEHDZUN-CDK30tx7.js} +1 -1
  99. package/public/assets/{sequenceDiagram-WL72ISMW-BQH_OfEp.js → sequenceDiagram-WL72ISMW-B2WQiW_k.js} +1 -1
  100. package/{dist/public/assets/stateDiagram-FKZM4ZOC-CBOkbVQn.js → public/assets/stateDiagram-FKZM4ZOC-uM1w_xjr.js} +1 -1
  101. package/public/assets/stateDiagram-v2-4FDKWEC3-BGfXuXW9.js +1 -0
  102. package/{dist/public/assets/timeline-definition-IT6M3QCI-CkNd8y6W.js → public/assets/timeline-definition-IT6M3QCI-07DImEJ7.js} +1 -1
  103. package/public/assets/{treemap-KMMF4GRG-D6z_eudj.js → treemap-KMMF4GRG-N0jjjXe0.js} +1 -1
  104. package/{dist/public/assets/xychartDiagram-PRI3JC2R-B5wk4XRt.js → public/assets/xychartDiagram-PRI3JC2R-BV-5VcHE.js} +1 -1
  105. package/public/index.html +15 -2
  106. package/dist/public/assets/channel-CgkYY8Ci.js +0 -1
  107. package/dist/public/assets/classDiagram-2ON5EDUG-BuYVNwmc.js +0 -1
  108. package/dist/public/assets/classDiagram-v2-WZHVMYZB-BuYVNwmc.js +0 -1
  109. package/dist/public/assets/clone-mkrd6lC9.js +0 -1
  110. package/dist/public/assets/index-Czr2q0NP.css +0 -1
  111. package/dist/public/assets/index-kEIJA0pC.js +0 -1781
  112. package/dist/public/assets/stateDiagram-v2-4FDKWEC3-BqHz04Bh.js +0 -1
  113. package/public/assets/channel-CgkYY8Ci.js +0 -1
  114. package/public/assets/classDiagram-2ON5EDUG-BuYVNwmc.js +0 -1
  115. package/public/assets/classDiagram-v2-WZHVMYZB-BuYVNwmc.js +0 -1
  116. package/public/assets/clone-mkrd6lC9.js +0 -1
  117. package/public/assets/index-Czr2q0NP.css +0 -1
  118. package/public/assets/index-kEIJA0pC.js +0 -1781
  119. package/public/assets/stateDiagram-v2-4FDKWEC3-BqHz04Bh.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../bin/cli.ts","../../src/index.ts","../../src/db/index.ts","../../src/lib/paths.ts","../../src/db/schema.ts","../../src/amuxBridge.ts","../../src/trpc/trpc.ts","../../src/trpc/windows.ts","../../client/lib/layout.ts","../../src/trpc/layout.ts","../../src/trpc/agents.ts","../../src/trpc/files.ts","../../src/trpc/terminals.ts","../../src/trpc/router.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Shella CLI - Self-hosted AI coding agents\n *\n * Usage:\n * npx @bytespell/shella Start in current directory\n * npx @bytespell/shella --port 3070 Custom port\n */\n\nimport { program } from 'commander';\nimport { networkInterfaces } from 'os';\nimport { spawn } from 'child_process';\nimport * as p from '@clack/prompts';\nimport { createShellaServer } from '../src/index.js';\n\nconst VERSION = '0.1.0';\n\n// Brand color (indigo) for terminal output\nconst BRAND = '\\x1b[38;2;99;102;241m'; // rgb(99, 102, 241)\nconst RESET = '\\x1b[0m';\nconst DIM = '\\x1b[2m';\nconst brand = (text: string) => `${BRAND}${text}${RESET}`;\nconst dim = (text: string) => `${DIM}${text}${RESET}`;\n\nfunction getLanIp(): string {\n const interfaces = networkInterfaces();\n for (const [name, addrs] of Object.entries(interfaces)) {\n if (/^(lo|docker|veth|br-|virbr)/.test(name)) continue;\n for (const addr of addrs || []) {\n if (addr.family === 'IPv4' && !addr.internal) {\n return addr.address;\n }\n }\n }\n return 'localhost';\n}\n\ninterface StartOptions {\n port: string;\n open: boolean;\n verbose: boolean;\n}\n\nasync function startCommand(options: StartOptions) {\n const port = parseInt(options.port, 10);\n const verbose = options.verbose;\n\n const s = verbose ? null : p.spinner();\n const log = (msg: string) => verbose && console.log(msg);\n\n if (!verbose) {\n p.intro(`${brand('shella')} ${dim(`v${VERSION}`)}`);\n } else {\n log(`${brand('shella')} ${dim(`v${VERSION}`)}`);\n }\n\n if (s) s.start('Starting server...');\n else log('Starting server...');\n\n const shella = createShellaServer({\n port,\n verbose,\n onReady: (url) => {\n if (s) s.stop('Ready');\n\n const lanIp = getLanIp();\n const lanUrl = `http://${lanIp}:${port}`;\n\n if (verbose) {\n log(`\\n${brand(lanUrl)}`);\n log(dim('access from any device'));\n log(`\\n${dim('press ctrl+c to stop')}\\n`);\n } else {\n p.log.success(`${brand(lanUrl)}`);\n p.log.message(dim('access from any device'));\n p.outro(dim('press ctrl+c to stop'));\n }\n\n // Open browser if requested\n if (options.open) {\n const openCommand =\n process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';\n spawn(openCommand, [url], { stdio: 'ignore', detached: true }).unref();\n }\n },\n });\n\n try {\n await shella.start();\n } catch (err) {\n if (s) s.stop('Failed');\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n\n // Graceful shutdown\n const shutdown = async () => {\n console.log('');\n console.log(dim('stopping...'));\n await shella.stop();\n console.log(`${brand('shella')} ${dim('stopped')}`);\n process.exit(0);\n };\n\n process.on('SIGTERM', shutdown);\n process.on('SIGINT', shutdown);\n}\n\nprogram\n .name('shella')\n .description(`${brand('shella')} - Self-hosted AI coding agents. Access from your phone.`)\n .version(VERSION)\n .option('-p, --port <port>', 'Server port', '3067')\n .option('--no-open', \"Don't open browser automatically\")\n .option('-v, --verbose', 'Show detailed logs', false)\n .action(startCommand);\n\nprogram.parse();\n","/**\n * Shella Server - Full product combining Amux + UI\n *\n * Creates a server that:\n * 1. Initializes Shella's database (windows, panes, ui_state)\n * 2. Creates an amux bridge for session/agent operations\n * 3. Serves the bundled UI static files\n * 4. Mounts Shella's tRPC API at /trpc (which proxies to amux internally)\n * 5. Handles WebSocket connections for subscriptions\n */\n\nimport express from 'express';\nimport { createServer } from 'http';\nimport { WebSocketServer } from 'ws';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { createExpressMiddleware } from '@trpc/server/adapters/express';\nimport { applyWSSHandler } from '@trpc/server/adapters/ws';\nimport { agentManager } from '@bytespell/amux/agents/manager';\nimport { setVerbose, debug } from '@bytespell/amux/lib/logger';\n\n// Import to trigger amux database initialization\nimport '@bytespell/amux/db';\n\n// Import to trigger shella database initialization\nimport './db/index.js';\n\nimport { createAmuxBridge } from './amuxBridge.js';\nimport { shellaRouter, initializeRouters } from './trpc/router.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport interface ShellaServerOptions {\n port?: number;\n verbose?: boolean;\n onReady?: (url: string) => void;\n}\n\nexport interface ShellaServer {\n start: () => Promise<void>;\n stop: () => Promise<void>;\n}\n\nexport function createShellaServer(options: ShellaServerOptions = {}): ShellaServer {\n const port = options.port ?? 3067;\n\n // Configure verbose logging\n if (options.verbose) {\n setVerbose(true);\n }\n\n // Initialize amux bridge\n const amuxBridge = createAmuxBridge();\n\n // Initialize routers with the bridge\n initializeRouters(amuxBridge);\n\n // Create main express app\n const app = express();\n app.use(express.json());\n\n // Serve static UI files first\n const publicPath = path.join(__dirname, '..', 'public');\n app.use(express.static(publicPath));\n\n // tRPC HTTP endpoint\n app.use('/trpc', createExpressMiddleware({ router: shellaRouter }));\n\n // Health check\n app.get('/health', (_req, res) => res.json({ status: 'ok' }));\n\n // SPA fallback - serve index.html for all non-API routes\n // Express 5 requires named parameter for wildcards\n app.get('/{*splat}', (_req, res) => {\n res.sendFile(path.join(publicPath, 'index.html'));\n });\n\n // Create HTTP server\n const server = createServer(app);\n\n // WebSocket for subscriptions\n const wss = new WebSocketServer({ server, path: '/trpc' });\n applyWSSHandler({ wss, router: shellaRouter });\n\n return {\n start: () => {\n return new Promise((resolve, reject) => {\n server.once('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n reject(new Error(`Port ${port} is already in use. Kill the other process or use a different port.`));\n } else {\n reject(err);\n }\n });\n\n server.listen(port, () => {\n const url = `http://localhost:${port}`;\n debug('shella', `Running on ${url}`);\n options.onReady?.(url);\n resolve();\n });\n });\n },\n\n stop: async () => {\n debug('shella', 'Shutting down...');\n wss.close();\n await agentManager.stopAll();\n server.close();\n },\n };\n}\n\n// Re-export router type for UI\nexport { shellaRouter, type ShellaRouter } from './trpc/router.js';\n","import Database from 'better-sqlite3';\nimport { drizzle } from 'drizzle-orm/better-sqlite3';\nimport { getShellaDbPath, ensureDir, getDataDir } from '../lib/paths.js';\nimport * as schema from './schema.js';\n\nensureDir(getDataDir());\n\nconst sqlite = new Database(getShellaDbPath());\nsqlite.pragma('journal_mode = WAL');\nsqlite.pragma('foreign_keys = ON');\n\nexport const db = drizzle(sqlite, { schema });\n\n// Create tables if they don't exist\nsqlite.exec(`\n CREATE TABLE IF NOT EXISTS windows (\n id TEXT PRIMARY KEY,\n title TEXT NOT NULL,\n has_custom_title INTEGER NOT NULL DEFAULT 0,\n layout TEXT NOT NULL,\n active_pane_id TEXT NOT NULL,\n created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000),\n last_accessed_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)\n );\n\n CREATE TABLE IF NOT EXISTS panes (\n id TEXT PRIMARY KEY,\n window_id TEXT NOT NULL REFERENCES windows(id) ON DELETE CASCADE,\n content TEXT,\n created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)\n );\n\n CREATE TABLE IF NOT EXISTS ui_state (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n`);\n\n// Migration: Convert session_id column to content JSON column\n// This migrates from the old schema where panes had session_id to the new\n// schema where panes have a content JSON object with type discrimination\ntry {\n const tableInfo = sqlite.prepare('PRAGMA table_info(panes)').all() as Array<{\n name: string;\n notnull: number;\n }>;\n const hasSessionId = tableInfo.some((col) => col.name === 'session_id');\n const hasContent = tableInfo.some((col) => col.name === 'content');\n\n if (hasSessionId && !hasContent) {\n // Old schema with session_id, need to migrate to content\n sqlite.exec(`\n -- Disable foreign keys temporarily\n PRAGMA foreign_keys = OFF;\n\n -- Create new table with content column\n CREATE TABLE panes_new (\n id TEXT PRIMARY KEY,\n window_id TEXT NOT NULL REFERENCES windows(id) ON DELETE CASCADE,\n content TEXT,\n created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)\n );\n\n -- Copy data, converting session_id to content JSON\n INSERT INTO panes_new (id, window_id, content, created_at)\n SELECT\n id,\n window_id,\n CASE\n WHEN session_id IS NOT NULL THEN json_object('type', 'session', 'sessionId', session_id)\n ELSE NULL\n END,\n created_at\n FROM panes;\n\n -- Drop old table and rename new\n DROP TABLE panes;\n ALTER TABLE panes_new RENAME TO panes;\n\n -- Re-enable foreign keys\n PRAGMA foreign_keys = ON;\n `);\n console.log('[shella-db] Migrated panes from session_id to content column');\n }\n} catch {\n // Migration not needed or already done\n}\n\nexport { schema };\n","import path from 'path';\nimport os from 'os';\nimport fs from 'fs';\n\n/**\n * Get the data directory following XDG Base Directory spec\n * Shared with amux in the same directory.\n */\nexport function getDataDir(): string {\n const home = os.homedir();\n\n let dataDir: string;\n\n switch (process.platform) {\n case 'darwin':\n dataDir = path.join(home, 'Library', 'Application Support', 'shella');\n break;\n case 'win32':\n dataDir = path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), 'shella');\n break;\n default:\n // Linux and others - follow XDG spec\n dataDir = path.join(process.env.XDG_DATA_HOME || path.join(home, '.local', 'share'), 'shella');\n }\n\n return dataDir;\n}\n\n/**\n * Check if running in mock mode\n */\nexport function isMockMode(): boolean {\n return process.env.SHELLA_MOCK_MODE === 'true';\n}\n\n/**\n * Get the path to Shella's database file (UI state: windows, panes, layouts)\n * This is separate from amux's database (sessions, events, agent configs)\n */\nexport function getShellaDbPath(): string {\n const filename = isMockMode() ? 'shella-ui.mock.db' : 'shella-ui.db';\n return path.join(getDataDir(), filename);\n}\n\n/**\n * Ensure a directory exists, creating it if necessary\n */\nexport function ensureDir(dir: string): void {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n}\n","import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';\nimport { sql } from 'drizzle-orm';\nimport type { LayoutNode } from '../../client/lib/layout.js';\n\n/**\n * Windows - top-level UI containers with layout trees.\n * Each window contains one or more panes arranged in a layout.\n */\nexport const windows = sqliteTable('windows', {\n id: text('id').primaryKey(),\n title: text('title').notNull(),\n hasCustomTitle: integer('has_custom_title', { mode: 'boolean' }).notNull().default(false),\n /** JSON-serialized LayoutNode tree */\n layout: text('layout', { mode: 'json' }).$type<LayoutNode>().notNull(),\n activePaneId: text('active_pane_id').notNull(),\n createdAt: integer('created_at', { mode: 'timestamp_ms' })\n .notNull()\n .default(sql`(unixepoch() * 1000)`),\n lastAccessedAt: integer('last_accessed_at', { mode: 'timestamp_ms' })\n .notNull()\n .default(sql`(unixepoch() * 1000)`),\n});\n\n/**\n * Pane content types - tagged union for what a pane displays.\n * - session: References an amux session (agent or shell)\n * - browser: Embeds a URL in an iframe\n */\nexport type PaneContent =\n | { type: 'session'; sessionId: string }\n | { type: 'browser'; url: string };\n\n/**\n * Panes - individual content containers within a window.\n * Each pane has a content type that determines what it displays.\n */\nexport const panes = sqliteTable('panes', {\n id: text('id').primaryKey(),\n windowId: text('window_id')\n .notNull()\n .references(() => windows.id, { onDelete: 'cascade' }),\n /** Content configuration. Null when pane type not yet selected. */\n content: text('content', { mode: 'json' }).$type<PaneContent>(),\n createdAt: integer('created_at', { mode: 'timestamp_ms' })\n .notNull()\n .default(sql`(unixepoch() * 1000)`),\n});\n\n/**\n * UI state - key/value store for UI preferences.\n * Examples: active_window_id, theme, sidebar_collapsed\n */\nexport const uiState = sqliteTable('ui_state', {\n key: text('key').primaryKey(),\n value: text('value').notNull(),\n});\n\n// Type exports\nexport type Window = typeof windows.$inferSelect;\nexport type NewWindow = typeof windows.$inferInsert;\nexport type Pane = typeof panes.$inferSelect;\nexport type NewPane = typeof panes.$inferInsert;\nexport type UiState = typeof uiState.$inferSelect;\n","/**\n * Bridge between Shella and Amux.\n *\n * Since Shella embeds Amux (same process), this bridge directly calls\n * Amux's internal functions rather than going through tRPC.\n */\n\nimport { randomUUID } from 'crypto';\nimport { eq, inArray } from 'drizzle-orm';\nimport { db, schema } from '@bytespell/amux/db';\nimport { agentManager } from '@bytespell/amux/agents/manager';\nimport { clearEventsForSession } from '@bytespell/amux/agents/eventStore';\nimport { listFilesForAutocomplete, type FileEntry } from '@bytespell/amux/trpc/files';\nimport type { WindowUpdate } from '@bytespell/amux/types';\n\nconst { sessions, agentConfigs, appState } = schema;\n\n// Types that match Amux's internal types\nexport interface AmuxSession {\n id: string;\n directory: string;\n agentConfigId: string;\n acpSessionId: string | null;\n title: string | null;\n model: string | null;\n mode: string | null;\n createdAt: Date;\n}\n\nexport interface AmuxAgentConfig {\n id: string;\n name: string;\n command: string;\n args: string[] | null;\n env: Record<string, string> | null;\n createdAt: Date;\n}\n\nexport interface AmuxAgentSession {\n acpSessionId: string;\n replayEvents: any[];\n scrollback?: string;\n models?: Array<{ modelId: string; name: string }>;\n modes?: Array<{ id: string; name: string; description?: string }>;\n}\n\nexport interface AmuxBridge {\n // Session operations\n getSessions(ids: string[]): Promise<AmuxSession[]>;\n getSession(id: string): Promise<AmuxSession | null>;\n createSession(params: { id?: string; directory: string; agentConfigId?: string }): Promise<AmuxSession>;\n deleteSession(id: string): Promise<void>;\n\n // Agent config operations\n getAgentConfigs(): Promise<AmuxAgentConfig[]>;\n\n // Agent operations (start/stop/prompt/etc)\n startAgent(sessionId: string): Promise<AmuxAgentSession>;\n stopAgent(sessionId: string): Promise<void>;\n prompt(sessionId: string, message: string): Promise<void>;\n cancel(sessionId: string): Promise<void>;\n setMode(sessionId: string, modeId: string): Promise<void>;\n setModel(sessionId: string, modelId: string): Promise<void>;\n respondPermission(sessionId: string, requestId: string, optionId: string): void;\n\n // Subscriptions\n subscribeToSession(sessionId: string, callback: (update: WindowUpdate) => void): () => void;\n\n // File operations\n listFilesForAutocomplete(sessionId: string, partialPath: string, limit: number): Promise<FileEntry[]>;\n\n // Terminal operations (ShellBackend)\n terminalWrite(sessionId: string, data: string): void;\n terminalResize(sessionId: string, cols: number, rows: number): void;\n getTerminalScrollback(sessionId: string): string | undefined;\n isTerminalSession(sessionId: string): boolean;\n\n // Session updates\n updateSessionTitle(sessionId: string, title: string): void;\n}\n\n/**\n * Create an AmuxBridge from the embedded Amux instance.\n * This connects to Amux running in the same process.\n */\nexport function createAmuxBridge(): AmuxBridge {\n return {\n async getSessions(ids: string[]): Promise<AmuxSession[]> {\n if (ids.length === 0) return [];\n return db.select().from(sessions).where(inArray(sessions.id, ids)).all();\n },\n\n async getSession(id: string): Promise<AmuxSession | null> {\n return db.select().from(sessions).where(eq(sessions.id, id)).get() ?? null;\n },\n\n async createSession(params: { id?: string; directory: string; agentConfigId?: string }): Promise<AmuxSession> {\n // Get agent config\n let configId = params.agentConfigId;\n if (!configId) {\n const lastUsedRow = db.select().from(appState).where(eq(appState.key, 'last_used_agent_config_id')).get();\n if (lastUsedRow?.value) {\n const config = db.select().from(agentConfigs).where(eq(agentConfigs.id, lastUsedRow.value)).get();\n if (config) configId = config.id;\n }\n if (!configId) {\n const firstConfig = db.select().from(agentConfigs).get();\n if (!firstConfig) {\n throw new Error('No agent configs available');\n }\n configId = firstConfig.id;\n }\n } else {\n // Save as last used\n db.insert(appState)\n .values({ key: 'last_used_agent_config_id', value: configId })\n .onConflictDoUpdate({ target: appState.key, set: { value: configId } })\n .run();\n }\n\n // Use client-provided ID if available (for optimistic updates)\n const id = params.id ?? randomUUID();\n const now = new Date();\n\n // For PTY sessions (terminals), default title to directory name\n const config = db.select().from(agentConfigs).where(eq(agentConfigs.id, configId)).get();\n const initialTitle = config?.streamType === 'pty'\n ? params.directory.split('/').pop() || null\n : null;\n\n db.insert(sessions).values({\n id,\n directory: params.directory,\n agentConfigId: configId,\n acpSessionId: null,\n title: initialTitle,\n model: null,\n mode: null,\n createdAt: now,\n }).run();\n\n return db.select().from(sessions).where(eq(sessions.id, id)).get()!;\n },\n\n async deleteSession(id: string): Promise<void> {\n await agentManager.stopForSession(id);\n clearEventsForSession(id);\n db.delete(sessions).where(eq(sessions.id, id)).run();\n },\n\n async getAgentConfigs(): Promise<AmuxAgentConfig[]> {\n return db.select().from(agentConfigs).all();\n },\n\n async startAgent(sessionId: string): Promise<AmuxAgentSession> {\n return agentManager.startForSession(sessionId);\n },\n\n async stopAgent(sessionId: string): Promise<void> {\n await agentManager.stopForSession(sessionId);\n },\n\n async prompt(sessionId: string, message: string): Promise<void> {\n await agentManager.prompt(sessionId, message);\n },\n\n async cancel(sessionId: string): Promise<void> {\n await agentManager.cancel(sessionId);\n },\n\n async setMode(sessionId: string, modeId: string): Promise<void> {\n await agentManager.setMode(sessionId, modeId);\n },\n\n async setModel(sessionId: string, modelId: string): Promise<void> {\n await agentManager.setModel(sessionId, modelId);\n },\n\n respondPermission(sessionId: string, requestId: string, optionId: string): void {\n agentManager.respondPermission(sessionId, requestId, optionId);\n },\n\n subscribeToSession(sessionId: string, callback: (update: WindowUpdate) => void): () => void {\n const handler = (event: { sessionId: string; update: WindowUpdate }) => {\n if (event.sessionId === sessionId) {\n callback(event.update);\n }\n };\n agentManager.on('update', handler);\n return () => agentManager.off('update', handler);\n },\n\n async listFilesForAutocomplete(sessionId: string, partialPath: string, limit: number): Promise<FileEntry[]> {\n const session = db.select().from(sessions).where(eq(sessions.id, sessionId)).get();\n if (!session) throw new Error(`Session ${sessionId} not found`);\n return listFilesForAutocomplete(session.directory, partialPath, limit);\n },\n\n // Terminal operations\n terminalWrite(sessionId: string, data: string): void {\n agentManager.terminalWrite(sessionId, data);\n },\n\n terminalResize(sessionId: string, cols: number, rows: number): void {\n agentManager.terminalResize(sessionId, cols, rows);\n },\n\n getTerminalScrollback(sessionId: string): string | undefined {\n return agentManager.getTerminalScrollback(sessionId);\n },\n\n isTerminalSession(sessionId: string): boolean {\n return agentManager.isTerminalSession(sessionId);\n },\n\n updateSessionTitle(sessionId: string, title: string): void {\n db.update(sessions)\n .set({ title })\n .where(eq(sessions.id, sessionId))\n .run();\n },\n };\n}\n","import { initTRPC } from '@trpc/server';\n\nconst t = initTRPC.create();\n\nexport const router = t.router;\nexport const publicProcedure = t.procedure;\n","import { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { eq } from 'drizzle-orm';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { windows, panes, uiState } from '../db/schema.js';\nimport { createLeaf, type LayoutNode } from '../../client/lib/layout.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\n// AmuxBridge is injected at server startup\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nfunction generateTitle(existingCount: number, directory: string): string {\n // Use directory name as title, or generic \"Window N\"\n const dirName = directory.split('/').pop();\n if (dirName && dirName !== '~' && dirName !== '') {\n return dirName;\n }\n return `Window ${existingCount + 1}`;\n}\n\nexport const windowsRouter = router({\n /**\n * List all windows with their panes and sessions.\n */\n list: publicProcedure.query(async () => {\n const allWindows = db.select().from(windows).orderBy(windows.createdAt).all();\n const allPanes = db.select().from(panes).all();\n const activeRow = db.select().from(uiState).where(eq(uiState.key, 'active_window_id')).get();\n\n // Get all unique session IDs from session-type panes\n const sessionIds = [...new Set(\n allPanes\n .map(p => p.content?.type === 'session' ? p.content.sessionId : null)\n .filter((id): id is string => id !== null)\n )];\n\n // Fetch sessions from amux\n const sessionsData = await amux.getSessions(sessionIds);\n const sessionMap = new Map(sessionsData.map(s => [s.id, s]));\n\n // Get agent configs from amux\n const agentConfigs = await amux.getAgentConfigs();\n\n return {\n windows: allWindows.map(w => ({\n ...w,\n panes: allPanes\n .filter(p => p.windowId === w.id)\n .map(p => ({\n ...p,\n // Enrich session-type content with full session data\n session: p.content?.type === 'session'\n ? sessionMap.get(p.content.sessionId) ?? null\n : null,\n })),\n })),\n activeWindowId: activeRow?.value ?? allWindows[allWindows.length - 1]?.id ?? null,\n agentConfigs,\n };\n }),\n\n /**\n * Get a single window by ID.\n */\n get: publicProcedure\n .input(z.object({ id: z.string() }))\n .query(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.id)).get();\n if (!window) {\n throw new Error(`Window ${input.id} not found`);\n }\n const windowPanes = db.select().from(panes).where(eq(panes.windowId, input.id)).all();\n\n // Fetch sessions for session-type panes\n const sessionIds = windowPanes\n .map(p => p.content?.type === 'session' ? p.content.sessionId : null)\n .filter((id): id is string => id !== null);\n const sessionsData = await amux.getSessions(sessionIds);\n const sessionMap = new Map(sessionsData.map(s => [s.id, s]));\n\n return {\n ...window,\n panes: windowPanes.map(p => ({\n ...p,\n session: p.content?.type === 'session'\n ? sessionMap.get(p.content.sessionId) ?? null\n : null,\n })),\n };\n }),\n\n /**\n * Create a new window with a single pane.\n * If agentConfigId is not provided, pane is created with no content (shows picker).\n */\n create: publicProcedure\n .input(z.object({\n id: z.string().optional(),\n title: z.string().optional(),\n directory: z.string().optional(),\n agentConfigId: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n const directory = input.directory ?? process.cwd();\n\n // 1. Only create session if agentConfigId is provided\n let session = null;\n if (input.agentConfigId) {\n session = await amux.createSession({\n directory,\n agentConfigId: input.agentConfigId,\n });\n }\n\n // 2. Create window + pane in shella\n const windowId = input.id ?? randomUUID();\n const paneId = randomUUID();\n const existingCount = db.select().from(windows).all().length;\n const layout: LayoutNode = createLeaf(paneId);\n\n db.insert(windows).values({\n id: windowId,\n title: input.title || generateTitle(existingCount, directory),\n hasCustomTitle: !!input.title,\n layout,\n activePaneId: paneId,\n }).run();\n\n db.insert(panes).values({\n id: paneId,\n windowId,\n content: session ? { type: 'session', sessionId: session.id } : null,\n }).run();\n\n // 3. Set as active window\n db.insert(uiState)\n .values({ key: 'active_window_id', value: windowId })\n .onConflictDoUpdate({ target: uiState.key, set: { value: windowId } })\n .run();\n\n // Fetch the full window with panes for the response\n const newWindow = db.select().from(windows).where(eq(windows.id, windowId)).get()!;\n const newPanes = db.select().from(panes).where(eq(panes.windowId, windowId)).all();\n\n return {\n ...newWindow,\n panes: newPanes.map(p => ({\n ...p,\n session: session && p.content?.type === 'session' && p.content.sessionId === session.id\n ? session\n : null,\n })),\n };\n }),\n\n /**\n * Update a window (title, etc).\n */\n update: publicProcedure\n .input(z.object({\n id: z.string(),\n title: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n const updates: Record<string, unknown> = {};\n if (input.title !== undefined) {\n updates.title = input.title;\n updates.hasCustomTitle = true;\n }\n updates.lastAccessedAt = new Date();\n\n db.update(windows)\n .set(updates)\n .where(eq(windows.id, input.id))\n .run();\n\n return db.select().from(windows).where(eq(windows.id, input.id)).get()!;\n }),\n\n /**\n * Delete a window and all its panes/sessions.\n */\n delete: publicProcedure\n .input(z.object({ id: z.string() }))\n .mutation(async ({ input }) => {\n // Get all panes for this window\n const windowPanes = db.select().from(panes).where(eq(panes.windowId, input.id)).all();\n\n // Delete sessions in amux (only for session-type panes)\n for (const pane of windowPanes) {\n if (pane.content?.type === 'session') {\n await amux.deleteSession(pane.content.sessionId);\n }\n }\n\n // Delete window (cascades to panes)\n db.delete(windows).where(eq(windows.id, input.id)).run();\n\n // Update active window if needed\n const activeRow = db.select().from(uiState).where(eq(uiState.key, 'active_window_id')).get();\n if (activeRow?.value === input.id) {\n const remaining = db.select().from(windows).orderBy(windows.createdAt).all();\n const newActiveId = remaining[remaining.length - 1]?.id ?? null;\n if (newActiveId) {\n db.update(uiState)\n .set({ value: newActiveId })\n .where(eq(uiState.key, 'active_window_id'))\n .run();\n } else {\n db.delete(uiState).where(eq(uiState.key, 'active_window_id')).run();\n }\n }\n\n return { ok: true };\n }),\n\n /**\n * Set the active window.\n */\n setActive: publicProcedure\n .input(z.object({ id: z.string() }))\n .mutation(async ({ input }) => {\n db.insert(uiState)\n .values({ key: 'active_window_id', value: input.id })\n .onConflictDoUpdate({ target: uiState.key, set: { value: input.id } })\n .run();\n\n // Update last accessed\n db.update(windows)\n .set({ lastAccessedAt: new Date() })\n .where(eq(windows.id, input.id))\n .run();\n\n return { ok: true };\n }),\n});\n","/**\n * Layout types for tmux-like pane splitting.\n *\n * Layout is a binary tree where:\n * - Leaf nodes are panes (contain a paneId)\n * - Branch nodes split space horizontally or vertically\n */\n\nexport type SplitDirection = 'horizontal' | 'vertical';\n\nexport interface LayoutLeaf {\n type: 'leaf';\n paneId: string;\n}\n\nexport interface LayoutBranch {\n type: 'branch';\n direction: SplitDirection;\n /** Percentage of space for first child (0-100) */\n ratio: number;\n first: LayoutNode;\n second: LayoutNode;\n}\n\nexport type LayoutNode = LayoutLeaf | LayoutBranch;\n\n/**\n * Create a leaf node for a pane.\n */\nexport function createLeaf(paneId: string): LayoutLeaf {\n return { type: 'leaf', paneId };\n}\n\n/**\n * Create a branch node splitting two children.\n */\nexport function createBranch(\n direction: SplitDirection,\n first: LayoutNode,\n second: LayoutNode,\n ratio = 50\n): LayoutBranch {\n return { type: 'branch', direction, ratio, first, second };\n}\n\n/**\n * Find all pane IDs in a layout tree.\n */\nexport function getAllPaneIds(node: LayoutNode): string[] {\n if (node.type === 'leaf') {\n return [node.paneId];\n }\n return [...getAllPaneIds(node.first), ...getAllPaneIds(node.second)];\n}\n\n/**\n * Find a pane in the layout and return its path.\n * Returns null if not found.\n */\nexport function findPanePath(\n node: LayoutNode,\n paneId: string,\n path: ('first' | 'second')[] = []\n): ('first' | 'second')[] | null {\n if (node.type === 'leaf') {\n return node.paneId === paneId ? path : null;\n }\n const firstPath = findPanePath(node.first, paneId, [...path, 'first']);\n if (firstPath) return firstPath;\n return findPanePath(node.second, paneId, [...path, 'second']);\n}\n\n/**\n * Replace a pane in the layout with a new node.\n */\nexport function replacePaneWithNode(\n root: LayoutNode,\n paneId: string,\n newNode: LayoutNode\n): LayoutNode {\n if (root.type === 'leaf') {\n return root.paneId === paneId ? newNode : root;\n }\n return {\n ...root,\n first: replacePaneWithNode(root.first, paneId, newNode),\n second: replacePaneWithNode(root.second, paneId, newNode),\n };\n}\n\n/**\n * Split a pane, creating a new branch with the original and new pane.\n */\nexport function splitPane(\n root: LayoutNode,\n paneId: string,\n newPaneId: string,\n direction: SplitDirection\n): LayoutNode {\n const originalLeaf = createLeaf(paneId);\n const newLeaf = createLeaf(newPaneId);\n const branch = createBranch(direction, originalLeaf, newLeaf);\n return replacePaneWithNode(root, paneId, branch);\n}\n\n/**\n * Remove a pane from the layout.\n * Returns the modified layout, or null if removing the only pane.\n */\nexport function removePane(root: LayoutNode, paneId: string): LayoutNode | null {\n if (root.type === 'leaf') {\n return root.paneId === paneId ? null : root;\n }\n\n // Check if either child is the pane to remove\n if (root.first.type === 'leaf' && root.first.paneId === paneId) {\n return root.second;\n }\n if (root.second.type === 'leaf' && root.second.paneId === paneId) {\n return root.first;\n }\n\n // Recursively remove from children\n const newFirst = removePane(root.first, paneId);\n const newSecond = removePane(root.second, paneId);\n\n // If a child was removed entirely, return the other\n if (newFirst === null) return newSecond;\n if (newSecond === null) return newFirst;\n\n // If either child changed, return updated branch\n if (newFirst !== root.first || newSecond !== root.second) {\n return { ...root, first: newFirst, second: newSecond };\n }\n\n return root;\n}\n\n/**\n * Update the split ratio at a specific path.\n */\nexport function updateRatio(\n root: LayoutNode,\n path: ('first' | 'second')[],\n newRatio: number\n): LayoutNode {\n if (path.length === 0) {\n if (root.type === 'branch') {\n return { ...root, ratio: Math.max(10, Math.min(90, newRatio)) };\n }\n return root;\n }\n\n if (root.type === 'leaf') return root;\n\n const [next, ...rest] = path;\n if (next === 'first') {\n return { ...root, first: updateRatio(root.first, rest, newRatio) };\n } else {\n return { ...root, second: updateRatio(root.second, rest, newRatio) };\n }\n}\n\n/**\n * Get the sibling pane ID when navigating in a direction.\n * Returns null if there's no sibling in that direction.\n */\nexport function getAdjacentPane(\n root: LayoutNode,\n currentPaneId: string,\n direction: 'left' | 'right' | 'up' | 'down'\n): string | null {\n const path = findPanePath(root, currentPaneId);\n if (!path) return null;\n\n // Navigate up the tree to find a branch going the right direction\n let node = root;\n const pathNodes: { node: LayoutBranch; childSide: 'first' | 'second' }[] = [];\n\n for (const step of path) {\n if (node.type === 'branch') {\n pathNodes.push({ node, childSide: step });\n node = step === 'first' ? node.first : node.second;\n }\n }\n\n // Find the closest branch that allows movement in the desired direction\n for (let i = pathNodes.length - 1; i >= 0; i--) {\n const { node: branch, childSide } = pathNodes[i];\n const isHorizontal = branch.direction === 'horizontal';\n const isVertical = branch.direction === 'vertical';\n\n // Check if this branch allows movement in the desired direction\n const canMove =\n (direction === 'left' && isHorizontal && childSide === 'second') ||\n (direction === 'right' && isHorizontal && childSide === 'first') ||\n (direction === 'up' && isVertical && childSide === 'second') ||\n (direction === 'down' && isVertical && childSide === 'first');\n\n if (canMove) {\n // Get the other child and find the closest pane in it\n const otherChild = childSide === 'first' ? branch.second : branch.first;\n return getFirstPaneInDirection(otherChild, direction);\n }\n }\n\n return null;\n}\n\n/**\n * Get the first pane when entering a subtree from a direction.\n */\nfunction getFirstPaneInDirection(\n node: LayoutNode,\n fromDirection: 'left' | 'right' | 'up' | 'down'\n): string {\n if (node.type === 'leaf') {\n return node.paneId;\n }\n\n // When entering from left, prefer the leftmost pane (first in horizontal split)\n // When entering from right, prefer the rightmost pane (second in horizontal split)\n // Similar for up/down with vertical splits\n const isHorizontal = node.direction === 'horizontal';\n\n if (fromDirection === 'left' || fromDirection === 'up') {\n // Coming from left/up, go to the first (left/top) child\n const targetChild = isHorizontal\n ? (fromDirection === 'left' ? node.first : node.first)\n : (fromDirection === 'up' ? node.first : node.first);\n return getFirstPaneInDirection(targetChild, fromDirection);\n } else {\n // Coming from right/down, go to the second (right/bottom) child\n const targetChild = isHorizontal\n ? (fromDirection === 'right' ? node.second : node.second)\n : (fromDirection === 'down' ? node.second : node.second);\n return getFirstPaneInDirection(targetChild, fromDirection);\n }\n}\n","import { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { eq } from 'drizzle-orm';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { windows, panes } from '../db/schema.js';\nimport {\n splitPane,\n removePane,\n getAllPaneIds,\n getAdjacentPane,\n updateRatio,\n type LayoutNode,\n type SplitDirection,\n} from '../../client/lib/layout.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nexport const layoutRouter = router({\n /**\n * Split a pane horizontally or vertically.\n * If source pane has a session, clones it. Otherwise creates empty pane.\n */\n split: publicProcedure\n .input(z.object({\n windowId: z.string(),\n paneId: z.string(),\n direction: z.enum(['horizontal', 'vertical']),\n // Client can provide IDs for optimistic updates\n newPaneId: z.string().optional(),\n newSessionId: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n // 1. Get source pane\n const sourcePane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!sourcePane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n // 2. Get window for layout update\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n // 3. New pane always starts empty (shows PaneTypePicker)\n const newContent = null;\n\n // 4. Create new pane\n const newPaneId = input.newPaneId ?? randomUUID();\n db.insert(panes).values({\n id: newPaneId,\n windowId: input.windowId,\n content: newContent,\n }).run();\n\n // 5. Update window layout\n const currentLayout = window.layout as LayoutNode;\n const newLayout = splitPane(currentLayout, input.paneId, newPaneId, input.direction as SplitDirection);\n\n db.update(windows)\n .set({\n layout: newLayout,\n activePaneId: newPaneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n const now = new Date();\n return {\n newPaneId,\n newSessionId: null,\n layout: newLayout,\n newPane: {\n id: newPaneId,\n windowId: input.windowId,\n content: newContent,\n createdAt: now.toISOString(),\n session: null,\n },\n };\n }),\n\n /**\n * Close a pane. If it's the last pane, close the window.\n */\n closePane: publicProcedure\n .input(z.object({\n windowId: z.string(),\n paneId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n const pane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n const currentLayout = window.layout as LayoutNode;\n const allPaneIds = getAllPaneIds(currentLayout);\n\n // Check if this is the last pane\n if (allPaneIds.length === 1) {\n // Delete session in amux if this is a session-type pane\n if (pane.content?.type === 'session') {\n await amux.deleteSession(pane.content.sessionId);\n }\n // Delete window (cascades to pane)\n db.delete(windows).where(eq(windows.id, input.windowId)).run();\n return { windowClosed: true, layout: null, activePaneId: null };\n }\n\n // Delete session in amux if this is a session-type pane\n if (pane.content?.type === 'session') {\n await amux.deleteSession(pane.content.sessionId);\n }\n // Delete pane\n db.delete(panes).where(eq(panes.id, input.paneId)).run();\n\n // Update layout\n const newLayout = removePane(currentLayout, input.paneId);\n if (!newLayout) {\n throw new Error('Failed to remove pane from layout');\n }\n\n // Determine new active pane\n const newActivePaneId = window.activePaneId === input.paneId\n ? getAllPaneIds(newLayout)[0]\n : window.activePaneId;\n\n db.update(windows)\n .set({\n layout: newLayout,\n activePaneId: newActivePaneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return {\n windowClosed: false,\n layout: newLayout,\n activePaneId: newActivePaneId,\n };\n }),\n\n /**\n * Set the active pane within a window.\n */\n setActivePane: publicProcedure\n .input(z.object({\n windowId: z.string(),\n paneId: z.string(),\n }))\n .mutation(async ({ input }) => {\n db.update(windows)\n .set({\n activePaneId: input.paneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return { ok: true };\n }),\n\n /**\n * Navigate to an adjacent pane.\n */\n navigate: publicProcedure\n .input(z.object({\n windowId: z.string(),\n currentPaneId: z.string(),\n direction: z.enum(['left', 'right', 'up', 'down']),\n }))\n .mutation(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n const currentLayout = window.layout as LayoutNode;\n const adjacentPaneId = getAdjacentPane(currentLayout, input.currentPaneId, input.direction);\n\n if (adjacentPaneId) {\n db.update(windows)\n .set({\n activePaneId: adjacentPaneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return { newActivePaneId: adjacentPaneId };\n }\n\n return { newActivePaneId: null };\n }),\n\n /**\n * Update the split ratio at a specific position.\n */\n setRatio: publicProcedure\n .input(z.object({\n windowId: z.string(),\n path: z.array(z.enum(['first', 'second'])),\n ratio: z.number().min(10).max(90),\n }))\n .mutation(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n const currentLayout = window.layout as LayoutNode;\n const newLayout = updateRatio(currentLayout, input.path, input.ratio);\n\n db.update(windows)\n .set({ layout: newLayout })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return { layout: newLayout };\n }),\n\n /**\n * Set the session for an empty pane (used when user picks agent/shell type).\n * Creates a session in amux and updates the pane.\n */\n setSession: publicProcedure\n .input(z.object({\n paneId: z.string(),\n agentConfigId: z.string(),\n directory: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n const pane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n if (pane.content) {\n throw new Error(`Pane ${input.paneId} already has content`);\n }\n\n // Create session in amux\n const session = await amux.createSession({\n directory: input.directory ?? process.cwd(),\n agentConfigId: input.agentConfigId,\n });\n\n // Update pane with session content\n db.update(panes)\n .set({ content: { type: 'session', sessionId: session.id } })\n .where(eq(panes.id, input.paneId))\n .run();\n\n // Start the agent\n await amux.startAgent(session.id);\n\n return {\n sessionId: session.id,\n content: { type: 'session' as const, sessionId: session.id },\n session: {\n id: session.id,\n directory: session.directory,\n agentConfigId: session.agentConfigId,\n model: session.model,\n mode: session.mode,\n createdAt: session.createdAt.toISOString(),\n acpSessionId: session.acpSessionId,\n },\n };\n }),\n\n /**\n * Set browser content for an empty pane.\n */\n setBrowserContent: publicProcedure\n .input(z.object({\n paneId: z.string(),\n url: z.string().url(),\n }))\n .mutation(async ({ input }) => {\n const pane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n if (pane.content) {\n throw new Error(`Pane ${input.paneId} already has content`);\n }\n\n const content = { type: 'browser' as const, url: input.url };\n\n db.update(panes)\n .set({ content })\n .where(eq(panes.id, input.paneId))\n .run();\n\n return { content };\n }),\n\n /**\n * Update the URL of an existing browser pane.\n */\n updateBrowserUrl: publicProcedure\n .input(z.object({\n paneId: z.string(),\n url: z.string().url(),\n }))\n .mutation(async ({ input }) => {\n const pane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n if (pane.content?.type !== 'browser') {\n throw new Error(`Pane ${input.paneId} is not a browser pane`);\n }\n\n const content = { type: 'browser' as const, url: input.url };\n\n db.update(panes)\n .set({ content })\n .where(eq(panes.id, input.paneId))\n .run();\n\n return { content };\n }),\n});\n","import { z } from 'zod';\nimport { eq } from 'drizzle-orm';\nimport { observable } from '@trpc/server/observable';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { panes } from '../db/schema.js';\nimport type { WindowUpdate } from '@bytespell/amux/types';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nconst paneInput = z.object({\n paneId: z.string(),\n});\n\n// Helper to get sessionId from paneId (for session-type panes only)\nfunction getSessionIdForPane(paneId: string): string {\n const pane = db.select().from(panes).where(eq(panes.id, paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${paneId} not found`);\n }\n if (pane.content?.type !== 'session') {\n throw new Error(`Pane ${paneId} is not a session pane`);\n }\n return pane.content.sessionId;\n}\n\nexport const agentsRouter = router({\n /**\n * Start agent for a pane.\n */\n start: publicProcedure\n .input(paneInput)\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n return amux.startAgent(sessionId);\n }),\n\n /**\n * Stop agent for a pane.\n */\n stop: publicProcedure\n .input(paneInput)\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.stopAgent(sessionId);\n return { ok: true };\n }),\n\n /**\n * Send a prompt to a pane's agent.\n */\n prompt: publicProcedure\n .input(z.object({\n paneId: z.string(),\n message: z.string(),\n }))\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.prompt(sessionId, input.message);\n return { ok: true };\n }),\n\n /**\n * Cancel the current prompt.\n */\n cancel: publicProcedure\n .input(paneInput)\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.cancel(sessionId);\n return { ok: true };\n }),\n\n /**\n * Set agent mode.\n */\n setMode: publicProcedure\n .input(z.object({\n paneId: z.string(),\n modeId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.setMode(sessionId, input.modeId);\n return { ok: true };\n }),\n\n /**\n * Set agent model.\n */\n setModel: publicProcedure\n .input(z.object({\n paneId: z.string(),\n modelId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n await amux.setModel(sessionId, input.modelId);\n return { ok: true };\n }),\n\n /**\n * Respond to a permission request.\n */\n respondPermission: publicProcedure\n .input(z.object({\n paneId: z.string(),\n requestId: z.string(),\n optionId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n amux.respondPermission(sessionId, input.requestId, input.optionId);\n return { ok: true };\n }),\n\n /**\n * Subscribe to updates for a pane's agent session.\n */\n subscribe: publicProcedure\n .input(paneInput)\n .subscription(({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n return observable<WindowUpdate>((emit) => {\n return amux.subscribeToSession(sessionId, (update) => {\n emit.next(update);\n });\n });\n }),\n});\n","import { z } from 'zod';\nimport { eq } from 'drizzle-orm';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { panes } from '../db/schema.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\n// Helper to get sessionId from paneId (for session-type panes only)\nfunction getSessionIdForPane(paneId: string): string {\n const pane = db.select().from(panes).where(eq(panes.id, paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${paneId} not found`);\n }\n if (pane.content?.type !== 'session') {\n throw new Error(`Pane ${paneId} is not a session pane`);\n }\n return pane.content.sessionId;\n}\n\nexport const filesRouter = router({\n /**\n * List files/directories matching a partial path for autocomplete.\n * Returns files in the session's working directory.\n */\n listForAutocomplete: publicProcedure\n .input(z.object({\n paneId: z.string(),\n partialPath: z.string(),\n limit: z.number().default(20),\n }))\n .query(async ({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n return amux.listFilesForAutocomplete(sessionId, input.partialPath, input.limit);\n }),\n});\n","import { z } from 'zod';\nimport { eq } from 'drizzle-orm';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { panes } from '../db/schema.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nconst paneInput = z.object({\n paneId: z.string(),\n});\n\n// Helper to get sessionId from paneId (for session-type panes only)\nfunction getSessionIdForPane(paneId: string): string {\n const pane = db.select().from(panes).where(eq(panes.id, paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${paneId} not found`);\n }\n if (pane.content?.type !== 'session') {\n throw new Error(`Pane ${paneId} is not a session pane`);\n }\n return pane.content.sessionId;\n}\n\n/**\n * Terminal-specific tRPC router.\n *\n * These endpoints are for interactive terminal panes (ShellBackend).\n * Regular agent panes use the agents router instead.\n */\nexport const terminalsRouter = router({\n /**\n * Write raw input to terminal (keystrokes from client).\n */\n write: publicProcedure\n .input(\n z.object({\n paneId: z.string(),\n data: z.string(),\n })\n )\n .mutation(({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n amux.terminalWrite(sessionId, input.data);\n return { ok: true };\n }),\n\n /**\n * Resize terminal dimensions.\n */\n resize: publicProcedure\n .input(\n z.object({\n paneId: z.string(),\n cols: z.number().int().positive(),\n rows: z.number().int().positive(),\n })\n )\n .mutation(({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n amux.terminalResize(sessionId, input.cols, input.rows);\n return { ok: true };\n }),\n\n /**\n * Check if a pane is a terminal session.\n */\n isTerminal: publicProcedure.input(paneInput).query(({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n return { isTerminal: amux.isTerminalSession(sessionId) };\n }),\n\n /**\n * Set terminal title (from OSC escape sequence).\n */\n setTitle: publicProcedure\n .input(z.object({\n paneId: z.string(),\n title: z.string(),\n }))\n .mutation(({ input }) => {\n const sessionId = getSessionIdForPane(input.paneId);\n amux.updateSessionTitle(sessionId, input.title);\n return { ok: true };\n }),\n});\n","import { router } from './trpc.js';\nimport { windowsRouter, setAmuxBridge as setWindowsAmux } from './windows.js';\nimport { layoutRouter, setAmuxBridge as setLayoutAmux } from './layout.js';\nimport { agentsRouter, setAmuxBridge as setAgentsAmux } from './agents.js';\nimport { filesRouter, setAmuxBridge as setFilesAmux } from './files.js';\nimport { terminalsRouter, setAmuxBridge as setTerminalsAmux } from './terminals.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\n/**\n * Initialize all routers with the amux bridge.\n * Must be called before any routes are used.\n */\nexport function initializeRouters(amux: AmuxBridge) {\n setWindowsAmux(amux);\n setLayoutAmux(amux);\n setAgentsAmux(amux);\n setFilesAmux(amux);\n setTerminalsAmux(amux);\n}\n\n/**\n * Shella's tRPC router.\n *\n * Provides UI-layer endpoints:\n * - windows: Window CRUD (with panes)\n * - layout: Split, close, navigate panes\n * - agents: Proxy to amux for agent operations\n * - terminals: Terminal-specific operations (ShellBackend)\n */\nexport const shellaRouter = router({\n windows: windowsRouter,\n layout: layoutRouter,\n agents: agentsRouter,\n files: filesRouter,\n terminals: terminalsRouter,\n});\n\nexport type ShellaRouter = typeof shellaRouter;\n"],"mappings":"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","names":["path","agentManager","db","config","randomUUID","eq","path","eq","p","agentConfigs","randomUUID","z","randomUUID","eq","amux","setAmuxBridge","z","eq","randomUUID","z","eq","amux","setAmuxBridge","z","eq","z","eq","amux","setAmuxBridge","getSessionIdForPane","eq","z","z","eq","amux","setAmuxBridge","paneInput","z","getSessionIdForPane","eq","amux","setAmuxBridge","path","agentManager","text","log"]}
1
+ {"version":3,"sources":["../../bin/cli.ts","../../src/index.ts","../../src/db/index.ts","../../src/lib/paths.ts","../../src/db/schema.ts","../../src/lib/configDiscovery.ts","../../src/lib/driverWatcher.ts","../../src/lib/driverCompiler.ts","../../src/amuxBridge.ts","../../src/lib/files.ts","../../src/trpc/trpc.ts","../../src/trpc/windows.ts","../../client/lib/layout.ts","../../src/trpc/layout.ts","../../src/trpc/agents.ts","../../src/lib/panes.ts","../../src/trpc/files.ts","../../src/trpc/terminals.ts","../../src/trpc/renderers.ts","../../src/lib/rendererWatcher.ts","../../src/lib/rendererCompiler.ts","../../src/trpc/router.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Shella CLI - Self-hosted AI coding agents\n *\n * Usage:\n * npx @bytespell/shella Start in current directory\n * npx @bytespell/shella --port 3070 Custom port\n */\n\nimport { program } from 'commander';\nimport { networkInterfaces } from 'os';\nimport { spawn } from 'child_process';\nimport * as p from '@clack/prompts';\nimport { createShellaServer } from '../src/index.js';\n\nconst VERSION = '0.1.0';\n\n// Brand color (indigo) for terminal output\nconst BRAND = '\\x1b[38;2;99;102;241m'; // rgb(99, 102, 241)\nconst RESET = '\\x1b[0m';\nconst DIM = '\\x1b[2m';\nconst brand = (text: string) => `${BRAND}${text}${RESET}`;\nconst dim = (text: string) => `${DIM}${text}${RESET}`;\n\nfunction getLanIp(): string {\n const interfaces = networkInterfaces();\n for (const [name, addrs] of Object.entries(interfaces)) {\n if (/^(lo|docker|veth|br-|virbr)/.test(name)) continue;\n for (const addr of addrs || []) {\n if (addr.family === 'IPv4' && !addr.internal) {\n return addr.address;\n }\n }\n }\n return 'localhost';\n}\n\ninterface StartOptions {\n port: string;\n open: boolean;\n verbose: boolean;\n}\n\nasync function startCommand(options: StartOptions) {\n const port = parseInt(options.port, 10);\n const verbose = options.verbose;\n\n const s = verbose ? null : p.spinner();\n const log = (msg: string) => verbose && console.log(msg);\n\n if (!verbose) {\n p.intro(`${brand('shella')} ${dim(`v${VERSION}`)}`);\n } else {\n log(`${brand('shella')} ${dim(`v${VERSION}`)}`);\n }\n\n if (s) s.start('Starting server...');\n else log('Starting server...');\n\n const shella = createShellaServer({\n port,\n verbose,\n onReady: (url) => {\n if (s) s.stop('Ready');\n\n const lanIp = getLanIp();\n const lanUrl = `http://${lanIp}:${port}`;\n\n if (verbose) {\n log(`\\n${brand(lanUrl)}`);\n log(dim('access from any device'));\n log(`\\n${dim('press ctrl+c to stop')}\\n`);\n } else {\n p.log.success(`${brand(lanUrl)}`);\n p.log.message(dim('access from any device'));\n p.outro(dim('press ctrl+c to stop'));\n }\n\n // Open browser if requested\n if (options.open) {\n const openCommand =\n process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';\n spawn(openCommand, [url], { stdio: 'ignore', detached: true }).unref();\n }\n },\n });\n\n try {\n await shella.start();\n } catch (err) {\n if (s) s.stop('Failed');\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n\n // Graceful shutdown\n const shutdown = async () => {\n console.log('');\n console.log(dim('stopping...'));\n await shella.stop();\n console.log(`${brand('shella')} ${dim('stopped')}`);\n process.exit(0);\n };\n\n process.on('SIGTERM', shutdown);\n process.on('SIGINT', shutdown);\n}\n\nprogram\n .name('shella')\n .description(`${brand('shella')} - Self-hosted AI coding agents. Access from your phone.`)\n .version(VERSION)\n .option('-p, --port <port>', 'Server port', '3067')\n .option('--no-open', \"Don't open browser automatically\")\n .option('-v, --verbose', 'Show detailed logs', false)\n .action(startCommand);\n\nprogram.parse();\n","/**\n * Shella Server - Full product combining Amux + UI\n *\n * Creates a server that:\n * 1. Initializes Shella's database (windows, panes, ui_state)\n * 2. Creates an amux bridge for session/agent operations\n * 3. Serves the bundled UI static files\n * 4. Mounts Shella's tRPC API at /trpc (which proxies to amux internally)\n * 5. Handles WebSocket connections for subscriptions\n */\n\nimport express from 'express';\nimport { createServer } from 'http';\nimport { WebSocketServer } from 'ws';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { createExpressMiddleware } from '@trpc/server/adapters/express';\nimport { applyWSSHandler } from '@trpc/server/adapters/ws';\nimport { muxManager } from '@bytespell/amux/streams/manager';\nimport { setVerbose, debug } from '@bytespell/amux/lib/logger';\n\n// Import to trigger shella database initialization\nimport './db/index.js';\n\n// Discover and register stream configs\nimport { discoverAndRegisterConfigs, builtInDiscoverers } from './lib/configDiscovery.js';\ndiscoverAndRegisterConfigs(builtInDiscoverers);\n\n// Driver watcher for server-side plugins\nimport { DriverEventEmitter, watchDrivers, scanDrivers } from './lib/driverWatcher.js';\n\nimport { createAmuxBridge } from './amuxBridge.js';\nimport { shellaRouter, initializeRouters } from './trpc/router.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport interface ShellaServerOptions {\n port?: number;\n verbose?: boolean;\n onReady?: (url: string) => void;\n}\n\nexport interface ShellaServer {\n start: () => Promise<void>;\n stop: () => Promise<void>;\n}\n\nexport function createShellaServer(options: ShellaServerOptions = {}): ShellaServer {\n const port = options.port ?? 3067;\n\n // Configure verbose logging\n if (options.verbose) {\n setVerbose(true);\n }\n\n // Initialize driver watcher for server-side plugins\n const driverEmitter = new DriverEventEmitter();\n let stopDriverWatcher: (() => void) | null = null;\n\n driverEmitter.on('driver:added', ({ id, name }) => {\n debug('shella', `Driver registered: ${id} (${name})`);\n });\n driverEmitter.on('driver:updated', ({ id, name }) => {\n debug('shella', `Driver updated: ${id} (${name})`);\n });\n driverEmitter.on('driver:removed', ({ id }) => {\n debug('shella', `Driver removed: ${id}`);\n });\n driverEmitter.on('driver:error', ({ pluginDir, error }) => {\n console.error(`Driver error in ${pluginDir}:`, error.message);\n });\n\n // Initialize amux bridge\n const amuxBridge = createAmuxBridge();\n\n // Initialize routers with the bridge\n initializeRouters(amuxBridge);\n\n // Create main express app\n const app = express();\n app.use(express.json());\n\n // Serve static UI files first\n const publicPath = path.join(__dirname, '..', 'public');\n app.use(express.static(publicPath));\n\n // tRPC HTTP endpoint\n app.use('/trpc', createExpressMiddleware({ router: shellaRouter }));\n\n // Health check\n app.get('/health', (_req, res) => res.json({ status: 'ok' }));\n\n // SPA fallback - serve index.html for all non-API routes\n // Express 5 requires named parameter for wildcards\n app.get('/{*splat}', (_req, res) => {\n res.sendFile(path.join(publicPath, 'index.html'));\n });\n\n // Create HTTP server\n const server = createServer(app);\n\n // WebSocket for subscriptions\n const wss = new WebSocketServer({ server, path: '/trpc' });\n applyWSSHandler({ wss, router: shellaRouter });\n\n return {\n start: async () => {\n // Scan and load existing server-side drivers before starting\n await scanDrivers();\n\n // Start watching for driver changes\n stopDriverWatcher = watchDrivers(driverEmitter);\n\n return new Promise((resolve, reject) => {\n server.once('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n reject(new Error(`Port ${port} is already in use. Kill the other process or use a different port.`));\n } else {\n reject(err);\n }\n });\n\n server.listen(port, () => {\n const url = `http://localhost:${port}`;\n debug('shella', `Running on ${url}`);\n options.onReady?.(url);\n resolve();\n });\n });\n },\n\n stop: async () => {\n debug('shella', 'Shutting down...');\n stopDriverWatcher?.();\n wss.close();\n await muxManager.stopAll();\n server.close();\n },\n };\n}\n\n// Re-export router type for UI\nexport { shellaRouter, type ShellaRouter } from './trpc/router.js';\n","import Database from 'better-sqlite3';\nimport { drizzle } from 'drizzle-orm/better-sqlite3';\nimport { getShellaDbPath, ensureDir, getDataDir } from '../lib/paths.js';\nimport * as schema from './schema.js';\n\nensureDir(getDataDir());\n\nconst sqlite = new Database(getShellaDbPath());\nsqlite.pragma('journal_mode = WAL');\nsqlite.pragma('foreign_keys = ON');\n\nexport const db = drizzle(sqlite, { schema });\n\n// Create tables if they don't exist\nsqlite.exec(`\n -- Stream tables (from amux)\n CREATE TABLE IF NOT EXISTS stream_configs (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n driver_type TEXT NOT NULL DEFAULT 'acp',\n command TEXT NOT NULL,\n args TEXT DEFAULT '[]',\n env TEXT DEFAULT '{}',\n created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)\n );\n\n CREATE TABLE IF NOT EXISTS streams (\n id TEXT PRIMARY KEY,\n directory TEXT NOT NULL,\n stream_config_id TEXT NOT NULL REFERENCES stream_configs(id),\n stream_type TEXT NOT NULL,\n driver_state TEXT,\n title TEXT,\n model TEXT,\n mode TEXT,\n created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)\n );\n\n -- UI tables\n CREATE TABLE IF NOT EXISTS windows (\n id TEXT PRIMARY KEY,\n title TEXT NOT NULL,\n has_custom_title INTEGER NOT NULL DEFAULT 0,\n layout TEXT NOT NULL,\n active_pane_id TEXT NOT NULL,\n created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000),\n last_accessed_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)\n );\n\n CREATE TABLE IF NOT EXISTS panes (\n id TEXT PRIMARY KEY,\n window_id TEXT NOT NULL REFERENCES windows(id) ON DELETE CASCADE,\n content TEXT,\n event_stream TEXT,\n renderer_id TEXT,\n created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000)\n );\n\n CREATE TABLE IF NOT EXISTS ui_state (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n`);\n\n// Migration: add driver_type column to stream_configs\ntry {\n const configInfo = sqlite.prepare(`PRAGMA table_info(stream_configs)`).all() as { name: string }[];\n const hasDriverType = configInfo.some(col => col.name === 'driver_type');\n\n if (!hasDriverType) {\n console.log('[db] Adding driver_type column to stream_configs...');\n sqlite.exec(`ALTER TABLE stream_configs ADD COLUMN driver_type TEXT NOT NULL DEFAULT 'acp'`);\n\n // Update existing configs: infer driver type from command\n // __shell__ -> pty, __mock__ -> mock, everything else -> acp\n sqlite.exec(`UPDATE stream_configs SET driver_type = 'pty' WHERE command = '__shell__'`);\n sqlite.exec(`UPDATE stream_configs SET driver_type = 'mock' WHERE command = '__mock__'`);\n console.log('[db] driver_type migration complete');\n }\n} catch (e) {\n // Migration not needed or already done\n}\n\n// Migration: rename process column to event_stream and update data format\ntry {\n // Check if old 'process' column exists\n const tableInfo = sqlite.prepare(`PRAGMA table_info(panes)`).all() as { name: string }[];\n const hasProcessColumn = tableInfo.some(col => col.name === 'process');\n const hasEventStreamColumn = tableInfo.some(col => col.name === 'event_stream');\n\n if (hasProcessColumn && !hasEventStreamColumn) {\n console.log('[db] Migrating panes.process to panes.event_stream...');\n\n // Add the new column\n sqlite.exec(`ALTER TABLE panes ADD COLUMN event_stream TEXT`);\n\n // Migrate data: { type: 'session', sessionId: X } → { type: 'acp', streamId: X }\n // Note: We default to 'acp' type since we don't know the actual type at migration time\n // The type will be corrected when the stream is started\n const panesWithProcess = sqlite.prepare(`SELECT id, process FROM panes WHERE process IS NOT NULL`).all() as { id: string; process: string }[];\n\n for (const pane of panesWithProcess) {\n try {\n const process = JSON.parse(pane.process);\n if (process.type === 'session' && process.sessionId) {\n // Convert to new format - use 'acp' as default type\n const eventStream = JSON.stringify({ type: 'acp', streamId: process.sessionId });\n sqlite.prepare(`UPDATE panes SET event_stream = ? WHERE id = ?`).run(eventStream, pane.id);\n }\n } catch (e) {\n // Skip invalid JSON\n }\n }\n\n console.log('[db] Migration complete, migrated', panesWithProcess.length, 'panes');\n }\n} catch (e) {\n // Migration not needed or already done\n}\n\nexport { schema };\n","import path from 'path';\nimport os from 'os';\nimport fs from 'fs';\n\n/**\n * Get the data directory following XDG Base Directory spec\n * Shared with amux in the same directory.\n */\nexport function getDataDir(): string {\n const home = os.homedir();\n\n let dataDir: string;\n\n switch (process.platform) {\n case 'darwin':\n dataDir = path.join(home, 'Library', 'Application Support', 'shella');\n break;\n case 'win32':\n dataDir = path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), 'shella');\n break;\n default:\n // Linux and others - follow XDG spec\n dataDir = path.join(process.env.XDG_DATA_HOME || path.join(home, '.local', 'share'), 'shella');\n }\n\n return dataDir;\n}\n\n/**\n * Check if running in mock mode\n */\nexport function isMockMode(): boolean {\n return process.env.SHELLA_MOCK_MODE === 'true';\n}\n\n/**\n * Get the path to Shella's database file (UI state: windows, panes, layouts)\n * This is separate from amux's database (sessions, events, agent configs)\n */\nexport function getShellaDbPath(): string {\n const filename = isMockMode() ? 'shella-ui.mock.db' : 'shella-ui.db';\n return path.join(getDataDir(), filename);\n}\n\n/**\n * Ensure a directory exists, creating it if necessary\n */\nexport function ensureDir(dir: string): void {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n}\n","import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';\nimport { sql } from 'drizzle-orm';\nimport type { LayoutNode } from '../../client/lib/layout.js';\n\n// ===== Stream Tables (from amux) =====\n\n/**\n * Stream configurations - defines how to spawn a stream process.\n * Examples: Claude agent, terminal shell, mock agent for testing\n */\nexport const streamConfigs = sqliteTable('stream_configs', {\n id: text('id').primaryKey(),\n name: text('name').notNull(),\n /** Driver type for routing (e.g., 'acp', 'pty', or custom plugin types) */\n driverType: text('driver_type').notNull().default('acp'),\n command: text('command').notNull(),\n args: text('args', { mode: 'json' }).$type<string[]>().default([]),\n env: text('env', { mode: 'json' }).$type<Record<string, string>>().default({}),\n createdAt: integer('created_at', { mode: 'timestamp_ms' })\n .notNull()\n .default(sql`(unixepoch() * 1000)`),\n});\n\n/**\n * Streams - each stream is an independent process instance.\n * A stream is linked to a pane via pane.eventStream.streamId.\n */\nexport const streams = sqliteTable('streams', {\n id: text('id').primaryKey(),\n directory: text('directory').notNull(),\n streamConfigId: text('stream_config_id').notNull().references(() => streamConfigs.id),\n /** Stream type determined by the driver at creation time. Built-in: 'acp', 'pty' */\n streamType: text('stream_type').notNull(),\n /** Generic driver state (e.g., ACP's session ID for resumption) */\n driverState: text('driver_state', { mode: 'json' }).$type<unknown>(),\n /** Title from stream (via session_info_update for ACP) */\n title: text('title'),\n model: text('model'),\n mode: text('mode'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' })\n .notNull()\n .default(sql`(unixepoch() * 1000)`),\n});\n\n// ===== UI Tables =====\n\n/**\n * Windows - top-level UI containers with layout trees.\n * Each window contains one or more panes arranged in a layout.\n */\nexport const windows = sqliteTable('windows', {\n id: text('id').primaryKey(),\n title: text('title').notNull(),\n hasCustomTitle: integer('has_custom_title', { mode: 'boolean' }).notNull().default(false),\n /** JSON-serialized LayoutNode tree */\n layout: text('layout', { mode: 'json' }).$type<LayoutNode>().notNull(),\n activePaneId: text('active_pane_id').notNull(),\n createdAt: integer('created_at', { mode: 'timestamp_ms' })\n .notNull()\n .default(sql`(unixepoch() * 1000)`),\n lastAccessedAt: integer('last_accessed_at', { mode: 'timestamp_ms' })\n .notNull()\n .default(sql`(unixepoch() * 1000)`),\n});\n\n/**\n * Pane content - static data displayed in a pane.\n * Type is a string to allow plugin content types.\n * Built-in types: 'browser'\n */\nexport type PaneContent = { type: string; [key: string]: unknown };\n\n/**\n * Pane event stream - live connection to an amux stream.\n * Type is a string to allow plugin stream types.\n * Built-in types: 'acp', 'pty'\n */\nexport type PaneEventStream = { type: string; streamId: string };\n\n/**\n * Panes - individual containers within a window.\n * A pane can have content (static), eventStream (live), both, or neither.\n */\nexport const panes = sqliteTable('panes', {\n id: text('id').primaryKey(),\n windowId: text('window_id')\n .notNull()\n .references(() => windows.id, { onDelete: 'cascade' }),\n /** Static content (browser URL, etc.). Null when no content. */\n content: text('content', { mode: 'json' }).$type<PaneContent>(),\n /** Live event stream (amux stream). Null when no stream. */\n eventStream: text('event_stream', { mode: 'json' }).$type<PaneEventStream>(),\n /** Renderer ID (e.g., 'builtin:terminal', 'project:custom-viewer'). Null = use default. */\n rendererId: text('renderer_id'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' })\n .notNull()\n .default(sql`(unixepoch() * 1000)`),\n});\n\n/**\n * UI state - key/value store for UI preferences.\n * Examples: active_window_id, theme, sidebar_collapsed\n */\nexport const uiState = sqliteTable('ui_state', {\n key: text('key').primaryKey(),\n value: text('value').notNull(),\n});\n\n// Type exports - Streams\nexport type StreamConfig = typeof streamConfigs.$inferSelect;\nexport type NewStreamConfig = typeof streamConfigs.$inferInsert;\nexport type Stream = typeof streams.$inferSelect;\nexport type NewStream = typeof streams.$inferInsert;\n\n// Type exports - UI\nexport type Window = typeof windows.$inferSelect;\nexport type NewWindow = typeof windows.$inferInsert;\nexport type Pane = typeof panes.$inferSelect;\nexport type NewPane = typeof panes.$inferInsert;\nexport type UiState = typeof uiState.$inferSelect;\n","import { execSync } from 'child_process';\nimport { randomUUID } from 'crypto';\nimport type { StreamConfig } from '../db/schema.js';\nimport { db } from '../db/index.js';\nimport { streamConfigs } from '../db/schema.js';\n\n/**\n * Interface for discovering stream configurations.\n * Each discoverer checks if a specific stream type is available\n * and returns its configuration if so.\n */\nexport interface StreamConfigDiscoverer {\n /** Human-readable name for logging */\n name: string;\n\n /** Check if available and return config, or null if not available */\n discover(): StreamConfig | null;\n}\n\n/**\n * Check if a command exists on the system\n */\nfunction commandExists(cmd: string): boolean {\n try {\n execSync(`which ${cmd}`, { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Claude discoverer - only available if claude CLI is installed\n */\nexport const claudeDiscoverer: StreamConfigDiscoverer = {\n name: 'claude',\n discover(): StreamConfig | null {\n if (!commandExists('claude')) {\n return null;\n }\n return {\n id: randomUUID(),\n name: 'claude',\n driverType: 'acp',\n command: 'npx',\n args: ['@zed-industries/claude-code-acp'],\n env: {},\n createdAt: new Date(),\n };\n },\n};\n\n/**\n * Codex discoverer - only available if codex CLI is installed\n */\nexport const codexDiscoverer: StreamConfigDiscoverer = {\n name: 'codex',\n discover(): StreamConfig | null {\n if (!commandExists('codex')) {\n return null;\n }\n return {\n id: randomUUID(),\n name: 'codex',\n driverType: 'acp',\n command: 'npx',\n args: ['@zed-industries/codex-acp'],\n env: {},\n createdAt: new Date(),\n };\n },\n};\n\n/**\n * Gemini discoverer - only available if gemini CLI is installed\n */\nexport const geminiDiscoverer: StreamConfigDiscoverer = {\n name: 'gemini',\n discover(): StreamConfig | null {\n if (!commandExists('gemini')) {\n return null;\n }\n return {\n id: randomUUID(),\n name: 'gemini',\n driverType: 'acp',\n command: 'gemini',\n args: ['--experimental-acp'],\n env: {},\n createdAt: new Date(),\n };\n },\n};\n\n/**\n * OpenCode discoverer - only available if opencode is installed\n */\nexport const openCodeDiscoverer: StreamConfigDiscoverer = {\n name: 'opencode',\n discover(): StreamConfig | null {\n if (!commandExists('opencode')) {\n return null;\n }\n return {\n id: randomUUID(),\n name: 'opencode',\n driverType: 'acp',\n command: 'opencode',\n args: ['acp'],\n env: {},\n createdAt: new Date(),\n };\n },\n};\n\n/**\n * Shell discoverer - always available (interactive terminal)\n */\nexport const shellDiscoverer: StreamConfigDiscoverer = {\n name: 'Shell',\n discover(): StreamConfig | null {\n return {\n id: 'shell',\n name: 'shell',\n driverType: 'pty',\n command: '', // PTY driver ignores command, spawns user's $SHELL\n args: [],\n env: {},\n createdAt: new Date(),\n };\n },\n};\n\n/**\n * Built-in discoverers for standard stream configs\n */\nexport const builtInDiscoverers: StreamConfigDiscoverer[] = [\n claudeDiscoverer,\n codexDiscoverer,\n geminiDiscoverer,\n openCodeDiscoverer,\n shellDiscoverer,\n];\n\n/**\n * Discover and register stream configs from the given discoverers.\n * Configs are only inserted if they don't already exist (by command + args).\n */\nexport function discoverAndRegisterConfigs(discoverers: StreamConfigDiscoverer[]): void {\n // Get existing configs from DB\n const existing = db.select().from(streamConfigs).all();\n\n let added = 0;\n for (const discoverer of discoverers) {\n const config = discoverer.discover();\n if (!config) {\n continue;\n }\n\n // Check if this config already exists (by command + args)\n const alreadyExists = existing.some(\n (e) => e.command === config.command &&\n JSON.stringify(e.args) === JSON.stringify(config.args)\n );\n\n if (!alreadyExists) {\n db.insert(streamConfigs).values({\n id: config.id,\n name: config.name,\n driverType: config.driverType,\n command: config.command,\n args: config.args,\n env: config.env,\n createdAt: config.createdAt,\n }).run();\n console.log(`[config] Discovered: ${config.name}`);\n added++;\n }\n }\n\n if (added > 0) {\n console.log(`[config] ${added} new stream config(s) registered`);\n }\n}\n","import chokidar from 'chokidar';\nimport * as path from 'path';\nimport * as os from 'os';\nimport * as fs from 'fs/promises';\nimport { EventEmitter } from 'events';\nimport { compileDriver, type CompiledDriver } from './driverCompiler.js';\nimport { muxManager } from '@bytespell/amux/streams/manager';\nimport type { StreamDriver } from '@bytespell/amux/types';\nimport { db } from '../db/index.js';\nimport { streamConfigs } from '../db/schema.js';\nimport { eq } from 'drizzle-orm';\n\n/**\n * Events emitted by the driver watcher\n */\nexport interface DriverWatcherEvents {\n 'driver:added': { id: string; name: string };\n 'driver:updated': { id: string; name: string };\n 'driver:removed': { id: string };\n 'driver:error': { pluginDir: string; error: Error };\n}\n\n/**\n * Type-safe event emitter for driver events\n */\nexport class DriverEventEmitter extends EventEmitter {\n emit<K extends keyof DriverWatcherEvents>(event: K, data: DriverWatcherEvents[K]): boolean {\n return super.emit(event, data);\n }\n\n on<K extends keyof DriverWatcherEvents>(event: K, listener: (data: DriverWatcherEvents[K]) => void): this {\n return super.on(event, listener);\n }\n\n off<K extends keyof DriverWatcherEvents>(event: K, listener: (data: DriverWatcherEvents[K]) => void): this {\n return super.off(event, listener);\n }\n}\n\n// Track loaded drivers by pluginDir for hot reload\n// Key: pluginDir, Value: { id from meta.json, version for cache busting }\nconst loadedDrivers = new Map<string, { id: string; version: number }>();\n\n/**\n * Load a driver module with cache busting for hot reload.\n *\n * Uses dynamic import with a version query param to force Node to reload the module.\n */\nasync function loadDriver(compiled: CompiledDriver): Promise<StreamDriver> {\n const entry = loadedDrivers.get(compiled.pluginDir);\n const version = (entry?.version ?? 0) + 1;\n\n // Cache-bust by appending version query param\n const url = `file://${compiled.filePath}?v=${version}`;\n const module = await import(/* @vite-ignore */ url);\n\n const driver = module.default;\n if (!driver || typeof driver.start !== 'function') {\n throw new Error(`Plugin driver must export default with start() method`);\n }\n\n // Inject type from meta.json id - single source of truth\n driver.type = compiled.id;\n\n loadedDrivers.set(compiled.pluginDir, { id: compiled.id, version });\n return driver as StreamDriver;\n}\n\n/**\n * Ensure a stream config exists for a plugin driver.\n * Plugin drivers don't spawn external processes - they run in-process.\n */\nfunction ensureStreamConfig(compiled: CompiledDriver): void {\n const existing = db.select().from(streamConfigs).where(eq(streamConfigs.id, compiled.id)).get();\n\n if (!existing) {\n db.insert(streamConfigs)\n .values({\n id: compiled.id,\n name: compiled.name,\n driverType: compiled.id, // Driver type matches plugin id\n command: '', // Plugin drivers don't spawn processes\n args: [],\n env: {},\n createdAt: new Date(),\n })\n .run();\n } else if (existing.name !== compiled.name) {\n // Update name if changed\n db.update(streamConfigs)\n .set({ name: compiled.name })\n .where(eq(streamConfigs.id, compiled.id))\n .run();\n }\n}\n\n/**\n * Remove stream config for a plugin driver.\n */\nfunction removeStreamConfig(id: string): void {\n db.delete(streamConfigs).where(eq(streamConfigs.id, id)).run();\n}\n\n/**\n * Watch user plugin directory for server-side driver changes.\n *\n * Watches: ~/.shella/renderers/{plugin-name}/server.ts\n *\n * When server.ts changes:\n * 1. Recompile to .shella/server.mjs\n * 2. Unregister old driver (stops active streams)\n * 3. Load new driver with cache-busted import\n * 4. Register new driver with MuxManager\n */\nexport function watchDrivers(emitter: DriverEventEmitter): () => void {\n const userPath = path.join(os.homedir(), '.shella', 'renderers');\n\n // Debounce recompilation per plugin\n const pendingCompiles = new Map<string, NodeJS.Timeout>();\n\n const watcher = chokidar.watch(userPath, {\n ignoreInitial: false,\n persistent: true,\n awaitWriteFinish: {\n stabilityThreshold: 150,\n pollInterval: 50,\n },\n depth: 3, // Watch inside plugin folders\n });\n\n /**\n * Extract the plugin directory from a file path\n */\n const getPluginDir = (filePath: string): string | null => {\n const relative = path.relative(userPath, filePath);\n const parts = relative.split(path.sep);\n if (parts.length >= 1 && parts[0]) {\n return path.join(userPath, parts[0]);\n }\n return null;\n };\n\n /**\n * Check if a file is server-related (server.ts or files it might import)\n */\n const isServerFile = (filePath: string): boolean => {\n const relative = path.relative(userPath, filePath);\n const parts = relative.split(path.sep);\n // Only trigger on server.ts directly or files in a server/ subdirectory\n return (\n parts.length >= 2 &&\n (parts[1] === 'server.ts' || parts[1]?.startsWith('server/') || filePath.includes('/server/'))\n );\n };\n\n /**\n * Schedule a debounced compile for a plugin directory\n */\n const scheduleCompile = (pluginDir: string) => {\n if (pendingCompiles.has(pluginDir)) {\n clearTimeout(pendingCompiles.get(pluginDir));\n }\n pendingCompiles.set(\n pluginDir,\n setTimeout(async () => {\n pendingCompiles.delete(pluginDir);\n await handleDriverChange(pluginDir);\n }, 150)\n );\n };\n\n /**\n * Handle a driver being added or updated\n */\n const handleDriverChange = async (pluginDir: string) => {\n try {\n const compiled = await compileDriver(pluginDir);\n if (!compiled) return; // No server.ts\n\n const existing = loadedDrivers.get(pluginDir);\n\n // Unregister old driver before loading new one\n if (existing) {\n muxManager.unregisterDriver(existing.id);\n }\n\n const driver = await loadDriver(compiled);\n muxManager.registerDriver(driver);\n ensureStreamConfig(compiled);\n\n if (!existing) {\n console.log(`[drivers] Added: ${compiled.id} (${compiled.name})`);\n emitter.emit('driver:added', { id: compiled.id, name: compiled.name });\n } else {\n console.log(`[drivers] Updated: ${compiled.id} (${compiled.name})`);\n emitter.emit('driver:updated', { id: compiled.id, name: compiled.name });\n }\n } catch (err) {\n console.error(`[drivers] Error compiling ${pluginDir}:`, err);\n emitter.emit('driver:error', {\n pluginDir,\n error: err instanceof Error ? err : new Error(String(err)),\n });\n }\n };\n\n watcher.on('add', (filePath) => {\n if (isServerFile(filePath)) {\n const pluginDir = getPluginDir(filePath);\n if (pluginDir) scheduleCompile(pluginDir);\n }\n });\n\n watcher.on('change', (filePath) => {\n if (isServerFile(filePath)) {\n const pluginDir = getPluginDir(filePath);\n if (pluginDir) scheduleCompile(pluginDir);\n }\n });\n\n watcher.on('unlink', (filePath) => {\n if (filePath.endsWith('server.ts')) {\n const pluginDir = getPluginDir(filePath);\n if (pluginDir) {\n const entry = loadedDrivers.get(pluginDir);\n if (entry) {\n muxManager.unregisterDriver(entry.id);\n removeStreamConfig(entry.id);\n loadedDrivers.delete(pluginDir);\n console.log(`[drivers] Removed: ${entry.id}`);\n emitter.emit('driver:removed', { id: entry.id });\n }\n }\n }\n });\n\n watcher.on('error', (err) => {\n console.error('[drivers] Watcher error:', err);\n });\n\n // Return cleanup function\n return () => {\n for (const timeout of pendingCompiles.values()) {\n clearTimeout(timeout);\n }\n pendingCompiles.clear();\n watcher.close();\n };\n}\n\n/**\n * Scan and load all existing drivers at startup.\n *\n * Used to hydrate MuxManager before the server starts accepting requests.\n */\nexport async function scanDrivers(): Promise<void> {\n const userPath = path.join(os.homedir(), '.shella', 'renderers');\n\n try {\n const entries = await fs.readdir(userPath, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const pluginDir = path.join(userPath, entry.name);\n try {\n const compiled = await compileDriver(pluginDir);\n if (compiled) {\n const driver = await loadDriver(compiled);\n muxManager.registerDriver(driver);\n ensureStreamConfig(compiled);\n console.log(`[drivers] Loaded: ${compiled.id} (${compiled.name})`);\n }\n } catch (err) {\n console.error(`[drivers] Error loading ${pluginDir}:`, err);\n }\n }\n } catch {\n // Directory doesn't exist - that's fine\n }\n}\n","import { build } from 'esbuild';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * Compiled driver metadata\n */\nexport interface CompiledDriver {\n /** Plugin id from meta.json (unique identifier, used as driver type) */\n id: string;\n /** Display name from meta.json */\n name: string;\n /** Absolute path to compiled .mjs file */\n filePath: string;\n /** Original plugin directory (for watcher tracking) */\n pluginDir: string;\n}\n\n/**\n * Compile a server-side driver from a plugin directory.\n *\n * Looks for server.ts in the plugin directory. If found, compiles it with esbuild\n * and outputs to .shella/server.mjs in the plugin directory.\n *\n * SDK imports are resolved via esbuild alias to shella's bundled SDK.\n *\n * @param pluginDir - Path to the plugin directory\n * @returns CompiledDriver if server.ts exists, null otherwise\n */\nexport async function compileDriver(pluginDir: string): Promise<CompiledDriver | null> {\n const serverPath = path.join(pluginDir, 'server.ts');\n\n // Check if server.ts exists\n try {\n await fs.access(serverPath);\n } catch {\n return null; // No server code in this plugin\n }\n\n // Read and validate meta.json\n const metaPath = path.join(pluginDir, 'meta.json');\n let meta: { id?: string; name?: string };\n\n try {\n const metaContent = await fs.readFile(metaPath, 'utf-8');\n meta = JSON.parse(metaContent);\n } catch (err) {\n throw new Error(\n `Failed to read meta.json for ${pluginDir}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n\n if (!meta.id || typeof meta.id !== 'string') {\n throw new Error(`Plugin in ${pluginDir}: meta.json requires \"id\" field`);\n }\n\n if (!meta.name || typeof meta.name !== 'string') {\n throw new Error(`Plugin in ${pluginDir}: meta.json requires \"name\" field`);\n }\n\n // Output to .shella/server.mjs in the plugin directory\n const outDir = path.join(pluginDir, '.shella');\n const outFile = path.join(outDir, 'server.mjs');\n\n // Ensure output directory exists\n await fs.mkdir(outDir, { recursive: true });\n\n // Check for package.json for npm dependencies\n const pkgPath = path.join(pluginDir, 'package.json');\n let hasPackageJson = false;\n try {\n await fs.access(pkgPath);\n hasPackageJson = true;\n } catch {\n // No package.json is fine\n }\n\n // Resolve SDK imports to shella's bundled versions using absolute paths.\n // This way plugins can import SDK without installing it themselves.\n // packages/shella/src/lib/driverCompiler.ts -> packages/shella -> packages/sdk/dist\n const shellaRoot = path.resolve(__dirname, '../..');\n const sdkPath = path.resolve(shellaRoot, '../sdk/dist');\n\n await build({\n entryPoints: [serverPath],\n bundle: true,\n write: true,\n format: 'esm',\n platform: 'node',\n target: 'node20',\n outfile: outFile,\n alias: {\n '@bytespell/shella-sdk': path.join(sdkPath, 'index.js'),\n '@bytespell/shella-sdk/server': path.join(sdkPath, 'server.js'),\n },\n // If plugin has package.json, look for node_modules\n nodePaths: hasPackageJson ? [path.join(pluginDir, 'node_modules')] : [],\n minify: false,\n });\n\n return {\n id: meta.id,\n name: meta.name,\n filePath: outFile,\n pluginDir,\n };\n}\n\n/**\n * Check if a plugin directory has server-side code\n */\nexport async function hasServerCode(dirPath: string): Promise<boolean> {\n try {\n await fs.access(path.join(dirPath, 'server.ts'));\n return true;\n } catch {\n return false;\n }\n}\n","/**\n * Bridge between Shella and Amux.\n *\n * Shella uses Amux as a library. This bridge:\n * - Manages stream/config CRUD using Shella's DB\n * - Calls muxManager.startStream() to start streams\n * - Subscribes to stream events and persists them\n * - Handles title updates and driver state persistence\n */\n\nimport { randomUUID } from 'crypto';\nimport path from 'path';\nimport fs from 'fs';\nimport { eq, inArray } from 'drizzle-orm';\nimport { db } from './db/index.js';\nimport { streams, streamConfigs, uiState } from './db/schema.js';\nimport { getDataDir } from './lib/paths.js';\nimport { listFilesForAutocomplete, type FileEntry } from './lib/files.js';\nimport { muxManager } from '@bytespell/amux/streams/manager';\nimport type { StreamPayload, StreamEvent, StreamHandle } from '@bytespell/amux/types';\nimport { isAcpEvent } from '@bytespell/amux/types';\n\n/** Get the storage directory for a stream */\nfunction getStreamStorageDir(streamId: string): string {\n return path.join(getDataDir(), 'streams', streamId);\n}\n\n// Types that match Shella's internal types\nexport interface AmuxStream {\n id: string;\n directory: string;\n streamConfigId: string;\n streamType: 'acp' | 'pty';\n driverState: unknown;\n title: string | null;\n model: string | null;\n mode: string | null;\n createdAt: Date;\n}\n\nexport interface AmuxStreamConfig {\n id: string;\n name: string;\n driverType: string;\n command: string;\n args: string[] | null;\n env: Record<string, string> | null;\n createdAt: Date;\n}\n\nexport interface AmuxStreamSession {\n acpSessionId?: string;\n replayEvents: StreamPayload[];\n scrollback?: string;\n models?: Array<{ modelId: string; name: string }>;\n modes?: Array<{ id: string; name: string; description?: string }>;\n}\n\nexport interface AmuxBridge {\n // Stream operations\n getStreams(ids: string[]): Promise<AmuxStream[]>;\n getStream(id: string): Promise<AmuxStream | null>;\n createStream(params: { id?: string; directory: string; streamConfigId?: string }): Promise<AmuxStream>;\n deleteStream(id: string): Promise<void>;\n\n // Stream config operations\n getStreamConfigs(): Promise<AmuxStreamConfig[]>;\n\n // Stream runtime operations (start/stop/input/etc)\n startStream(streamId: string): Promise<AmuxStreamSession>;\n stopStream(streamId: string): Promise<void>;\n input(streamId: string, message: string): Promise<void>;\n cancel(streamId: string): Promise<void>;\n setMode(streamId: string, modeId: string): Promise<void>;\n setModel(streamId: string, modelId: string): Promise<void>;\n respondPermission(streamId: string, requestId: string, optionId: string): void;\n\n // Subscriptions\n subscribeToStream(streamId: string, callback: (update: StreamPayload) => void): () => void;\n\n // File operations\n listFilesForAutocomplete(streamId: string, partialPath: string, limit: number): Promise<FileEntry[]>;\n\n // Terminal operations (PtyDriver)\n terminalWrite(streamId: string, data: string): void;\n terminalResize(streamId: string, cols: number, rows: number): void;\n getTerminalScrollback(streamId: string): string | undefined;\n isTerminalStream(streamId: string): boolean;\n\n // Stream updates\n updateStreamTitle(streamId: string, title: string): void;\n}\n\n// Generate a title from the first user message\nfunction generateTitleFromMessage(message: string): string {\n const cleaned = message\n .replace(/@[\\w./~-]+/g, '')\n .replace(/\\s+/g, ' ')\n .trim();\n\n const firstLine = cleaned.split('\\n')[0] || cleaned;\n\n if (firstLine.length <= 50) return firstLine;\n\n const truncated = firstLine.slice(0, 50);\n const lastSpace = truncated.lastIndexOf(' ');\n return lastSpace > 20 ? truncated.slice(0, lastSpace) + '...' : truncated + '...';\n}\n\n/**\n * Create an AmuxBridge from the Amux library.\n * This connects Shella to Amux's MuxManager.\n */\nexport function createAmuxBridge(): AmuxBridge {\n const bridge: AmuxBridge = {\n async getStreams(ids: string[]): Promise<AmuxStream[]> {\n if (ids.length === 0) return [];\n return db.select().from(streams).where(inArray(streams.id, ids)).all();\n },\n\n async getStream(id: string): Promise<AmuxStream | null> {\n return db.select().from(streams).where(eq(streams.id, id)).get() ?? null;\n },\n\n async createStream(params: { id?: string; directory: string; streamConfigId?: string }): Promise<AmuxStream> {\n // Get stream config\n let configId = params.streamConfigId;\n if (!configId) {\n const lastUsedRow = db.select().from(uiState).where(eq(uiState.key, 'last_used_stream_config_id')).get();\n if (lastUsedRow?.value) {\n const config = db.select().from(streamConfigs).where(eq(streamConfigs.id, lastUsedRow.value)).get();\n if (config) configId = config.id;\n }\n if (!configId) {\n const firstConfig = db.select().from(streamConfigs).get();\n if (!firstConfig) {\n throw new Error('No stream configs available');\n }\n configId = firstConfig.id;\n }\n } else {\n // Save as last used\n db.insert(uiState)\n .values({ key: 'last_used_stream_config_id', value: configId })\n .onConflictDoUpdate({ target: uiState.key, set: { value: configId } })\n .run();\n }\n\n // Use client-provided ID if available (for optimistic updates)\n const id = params.id ?? randomUUID();\n const now = new Date();\n\n // Get stream type from config's driverType\n const config = db.select().from(streamConfigs).where(eq(streamConfigs.id, configId)).get();\n const streamType = config?.driverType === 'pty' ? 'pty' : 'acp';\n\n // For PTY streams (terminals), default title to directory name\n const initialTitle = streamType === 'pty'\n ? params.directory.split('/').pop() || null\n : null;\n\n db.insert(streams).values({\n id,\n directory: params.directory,\n streamConfigId: configId,\n streamType,\n driverState: null,\n title: initialTitle,\n model: null,\n mode: null,\n createdAt: now,\n }).run();\n\n return db.select().from(streams).where(eq(streams.id, id)).get()!;\n },\n\n async deleteStream(id: string): Promise<void> {\n await muxManager.stopForStream(id);\n // Clean up storage directory\n const storageDir = getStreamStorageDir(id);\n try {\n if (fs.existsSync(storageDir)) {\n fs.rmSync(storageDir, { recursive: true });\n }\n } catch {\n // Ignore cleanup errors\n }\n db.delete(streams).where(eq(streams.id, id)).run();\n },\n\n async getStreamConfigs(): Promise<AmuxStreamConfig[]> {\n return db.select().from(streamConfigs).all();\n },\n\n async startStream(streamId: string): Promise<AmuxStreamSession> {\n const dbStream = db.select().from(streams).where(eq(streams.id, streamId)).get();\n if (!dbStream) throw new Error(`Stream ${streamId} not found`);\n\n const dbConfig = db.select().from(streamConfigs).where(eq(streamConfigs.id, dbStream.streamConfigId)).get();\n if (!dbConfig) throw new Error(`Stream config ${dbStream.streamConfigId} not found`);\n\n const storageDir = getStreamStorageDir(streamId);\n\n // Create emit callback that handles title updates (driver handles event storage)\n const emit = (event: StreamEvent) => {\n // Handle title updates from session_info_update (ACP events)\n if (isAcpEvent(event) && event.sessionUpdate === 'session_info_update') {\n const title = (event as { title?: string }).title;\n if (title !== undefined) {\n db.update(streams)\n .set({ title })\n .where(eq(streams.id, streamId))\n .run();\n }\n }\n };\n\n const handle: StreamHandle = await muxManager.startStream({\n streamId,\n driverType: dbConfig.driverType,\n config: {\n id: dbConfig.id,\n name: dbConfig.name,\n command: dbConfig.command,\n args: dbConfig.args ?? [],\n env: (dbConfig.env as Record<string, string>) ?? {},\n },\n cwd: dbStream.directory,\n restoredState: dbStream.driverState,\n emit,\n storageDir,\n });\n\n // Persist driver state after start (for resumption)\n const driverState = muxManager.getDriverState(streamId);\n if (driverState !== undefined) {\n db.update(streams)\n .set({ driverState })\n .where(eq(streams.id, streamId))\n .run();\n }\n\n // Get replay data from driver (events for ACP, scrollback for PTY)\n const replayData = muxManager.getReplayData(streamId);\n const replayEvents = Array.isArray(replayData) ? replayData : [];\n const scrollback = typeof replayData === 'string' ? replayData : muxManager.getTerminalScrollback(streamId);\n\n return {\n acpSessionId: handle.stream.acpSessionId,\n replayEvents,\n scrollback,\n models: handle.stream.models,\n modes: handle.stream.modes,\n };\n },\n\n async stopStream(streamId: string): Promise<void> {\n // Persist driver state before stopping\n const driverState = muxManager.getDriverState(streamId);\n if (driverState !== undefined) {\n db.update(streams)\n .set({ driverState })\n .where(eq(streams.id, streamId))\n .run();\n }\n await muxManager.stopForStream(streamId);\n },\n\n async input(streamId: string, message: string): Promise<void> {\n const stream = db.select().from(streams).where(eq(streams.id, streamId)).get();\n if (!stream) throw new Error(`Stream ${streamId} not found`);\n\n // Auto-generate title from first message if stream has no title\n if (!stream.title) {\n const title = generateTitleFromMessage(message);\n if (title) {\n db.update(streams)\n .set({ title })\n .where(eq(streams.id, streamId))\n .run();\n }\n }\n\n // Driver handles storage internally (ACP stores to history.json, PTY uses scrollback)\n await muxManager.input(streamId, message);\n },\n\n async cancel(streamId: string): Promise<void> {\n await muxManager.cancel(streamId);\n },\n\n async setMode(streamId: string, modeId: string): Promise<void> {\n await muxManager.setMode(streamId, modeId);\n },\n\n async setModel(streamId: string, modelId: string): Promise<void> {\n await muxManager.setModel(streamId, modelId);\n },\n\n respondPermission(streamId: string, requestId: string, optionId: string): void {\n muxManager.respondPermission(streamId, requestId, optionId);\n },\n\n subscribeToStream(streamId: string, callback: (event: StreamPayload) => void): () => void {\n const handler = (event: StreamEvent) => {\n if (event.streamId === streamId) {\n callback(event);\n }\n };\n muxManager.on('update', handler);\n return () => muxManager.off('update', handler);\n },\n\n async listFilesForAutocomplete(streamId: string, partialPath: string, limit: number): Promise<FileEntry[]> {\n const stream = db.select().from(streams).where(eq(streams.id, streamId)).get();\n if (!stream) throw new Error(`Stream ${streamId} not found`);\n return listFilesForAutocomplete(stream.directory, partialPath, limit);\n },\n\n // Terminal operations\n terminalWrite(streamId: string, data: string): void {\n muxManager.terminalWrite(streamId, data);\n },\n\n terminalResize(streamId: string, cols: number, rows: number): void {\n muxManager.terminalResize(streamId, cols, rows);\n },\n\n getTerminalScrollback(streamId: string): string | undefined {\n return muxManager.getTerminalScrollback(streamId);\n },\n\n isTerminalStream(streamId: string): boolean {\n return muxManager.isTerminalStream(streamId);\n },\n\n updateStreamTitle(streamId: string, title: string): void {\n db.update(streams)\n .set({ title })\n .where(eq(streams.id, streamId))\n .run();\n },\n };\n\n return bridge;\n}\n","import * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { glob } from 'glob';\n\nexport interface FileEntry {\n name: string; // File/directory name\n path: string; // Full relative path for insertion\n isDirectory: boolean;\n}\n\n/**\n * List files/directories matching a partial path for autocomplete.\n * Uses glob for fuzzy full-text search across the entire project.\n */\nexport async function listFilesForAutocomplete(\n workingDir: string,\n partialPath: string,\n limit: number\n): Promise<FileEntry[]> {\n // Normalize partial path (strip leading ./)\n const normalized = partialPath.startsWith('./')\n ? partialPath.slice(2)\n : partialPath;\n\n // If query contains a slash, user is navigating into a directory - use prefix match\n if (normalized.includes('/')) {\n return listFilesPrefix(workingDir, normalized, limit);\n }\n\n // Otherwise, do a fuzzy search across the entire project\n return listFilesFuzzy(workingDir, normalized, limit);\n}\n\n/**\n * Prefix-based listing for directory navigation (e.g., \"src/comp\")\n */\nasync function listFilesPrefix(\n workingDir: string,\n partialPath: string,\n limit: number\n): Promise<FileEntry[]> {\n const lastSlash = partialPath.lastIndexOf('/');\n const dirPart = lastSlash >= 0 ? partialPath.slice(0, lastSlash) : '';\n const prefix = lastSlash >= 0 ? partialPath.slice(lastSlash + 1) : partialPath;\n\n const targetDir = path.resolve(workingDir, dirPart);\n\n // Security: ensure we're within working directory\n const normalizedWorkingDir = path.resolve(workingDir);\n const normalizedTargetDir = path.resolve(targetDir);\n if (!normalizedTargetDir.startsWith(normalizedWorkingDir)) {\n return [];\n }\n\n try {\n const entries = await fs.readdir(targetDir, { withFileTypes: true });\n\n const matching = entries\n .filter(e => !e.name.startsWith('.'))\n .filter(e => prefix === '' || e.name.toLowerCase().startsWith(prefix.toLowerCase()))\n .slice(0, limit * 2)\n .map(e => ({\n name: e.name,\n path: dirPart ? `${dirPart}/${e.name}` : e.name,\n isDirectory: e.isDirectory(),\n }));\n\n matching.sort((a, b) => {\n if (a.isDirectory !== b.isDirectory) {\n return a.isDirectory ? -1 : 1;\n }\n return a.name.localeCompare(b.name);\n });\n\n return matching.slice(0, limit);\n } catch {\n return [];\n }\n}\n\n/**\n * Fuzzy search across entire project using glob\n */\nasync function listFilesFuzzy(\n workingDir: string,\n query: string,\n limit: number\n): Promise<FileEntry[]> {\n if (!query.trim()) return [];\n\n try {\n // Use glob to find files matching *query* pattern anywhere in the project\n // Use brace expansion to match both root-level files and nested files\n const pattern = `{*${query}*,**/*${query}*}`;\n const matches = await glob(pattern, {\n cwd: workingDir,\n nodir: false,\n dot: false, // Skip hidden files\n ignore: ['**/node_modules/**', '**/.git/**'],\n maxDepth: 10,\n });\n\n // Get file stats to determine if directory\n const results: FileEntry[] = [];\n for (const match of matches.slice(0, limit * 2)) {\n try {\n const fullPath = path.join(workingDir, match);\n const stat = await fs.stat(fullPath);\n results.push({\n name: path.basename(match),\n path: match,\n isDirectory: stat.isDirectory(),\n });\n } catch {\n // Skip files we can't stat\n }\n }\n\n // Sort: directories first, shorter paths first, then alphabetically\n results.sort((a, b) => {\n if (a.isDirectory !== b.isDirectory) {\n return a.isDirectory ? -1 : 1;\n }\n // Prefer shorter paths (closer to root)\n const aDepth = a.path.split('/').length;\n const bDepth = b.path.split('/').length;\n if (aDepth !== bDepth) {\n return aDepth - bDepth;\n }\n return a.path.localeCompare(b.path);\n });\n\n return results.slice(0, limit);\n } catch {\n return [];\n }\n}\n","import { initTRPC } from '@trpc/server';\n\nconst t = initTRPC.create();\n\nexport const router = t.router;\nexport const publicProcedure = t.procedure;\n","import { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { eq } from 'drizzle-orm';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { windows, panes, uiState } from '../db/schema.js';\nimport { createLeaf, type LayoutNode } from '../../client/lib/layout.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\n// AmuxBridge is injected at server startup\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nfunction generateTitle(existingCount: number, directory: string): string {\n // Use directory name as title, or generic \"Window N\"\n const dirName = directory.split('/').pop();\n if (dirName && dirName !== '~' && dirName !== '') {\n return dirName;\n }\n return `Window ${existingCount + 1}`;\n}\n\nexport const windowsRouter = router({\n /**\n * List all windows with their panes and streams.\n */\n list: publicProcedure.query(async () => {\n const allWindows = db.select().from(windows).orderBy(windows.createdAt).all();\n const allPanes = db.select().from(panes).all();\n const activeRow = db.select().from(uiState).where(eq(uiState.key, 'active_window_id')).get();\n\n // Get all unique stream IDs from panes with event streams\n const streamIds = [...new Set(\n allPanes\n .map(p => p.eventStream?.streamId ?? null)\n .filter((id): id is string => id !== null)\n )];\n\n // Fetch streams from amux\n const streamsData = await amux.getStreams(streamIds);\n const streamMap = new Map(streamsData.map(s => [s.id, s]));\n\n // Get stream configs from amux\n const streamConfigs = await amux.getStreamConfigs();\n\n return {\n windows: allWindows.map(w => ({\n ...w,\n panes: allPanes\n .filter(p => p.windowId === w.id)\n .map(p => ({\n ...p,\n // Enrich eventStream with full stream data\n stream: p.eventStream\n ? streamMap.get(p.eventStream.streamId) ?? null\n : null,\n })),\n })),\n activeWindowId: activeRow?.value ?? allWindows[allWindows.length - 1]?.id ?? null,\n streamConfigs,\n // Legacy alias\n agentConfigs: streamConfigs,\n };\n }),\n\n /**\n * Get a single window by ID.\n */\n get: publicProcedure\n .input(z.object({ id: z.string() }))\n .query(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.id)).get();\n if (!window) {\n throw new Error(`Window ${input.id} not found`);\n }\n const windowPanes = db.select().from(panes).where(eq(panes.windowId, input.id)).all();\n\n // Fetch streams for panes with event streams\n const streamIds = windowPanes\n .map(p => p.eventStream?.streamId ?? null)\n .filter((id): id is string => id !== null);\n const streamsData = await amux.getStreams(streamIds);\n const streamMap = new Map(streamsData.map(s => [s.id, s]));\n\n return {\n ...window,\n panes: windowPanes.map(p => ({\n ...p,\n stream: p.eventStream\n ? streamMap.get(p.eventStream.streamId) ?? null\n : null,\n })),\n };\n }),\n\n /**\n * Create a new window with a single pane.\n * If streamConfigId is not provided, pane is created with no content (shows picker).\n */\n create: publicProcedure\n .input(z.object({\n id: z.string().optional(),\n title: z.string().optional(),\n directory: z.string().optional(),\n streamConfigId: z.string().optional(),\n // Legacy alias\n agentConfigId: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n const directory = input.directory ?? process.cwd();\n const configId = input.streamConfigId ?? input.agentConfigId;\n\n // 1. Only create stream if streamConfigId is provided\n let stream = null;\n if (configId) {\n stream = await amux.createStream({\n directory,\n streamConfigId: configId,\n });\n }\n\n // 2. Create window + pane in shella\n const windowId = input.id ?? randomUUID();\n const paneId = randomUUID();\n const existingCount = db.select().from(windows).all().length;\n const layout: LayoutNode = createLeaf(paneId);\n\n db.insert(windows).values({\n id: windowId,\n title: input.title || generateTitle(existingCount, directory),\n hasCustomTitle: !!input.title,\n layout,\n activePaneId: paneId,\n }).run();\n\n db.insert(panes).values({\n id: paneId,\n windowId,\n content: null,\n eventStream: stream ? { type: stream.streamType, streamId: stream.id } : null,\n }).run();\n\n // 3. Set as active window\n db.insert(uiState)\n .values({ key: 'active_window_id', value: windowId })\n .onConflictDoUpdate({ target: uiState.key, set: { value: windowId } })\n .run();\n\n // Fetch the full window with panes for the response\n const newWindow = db.select().from(windows).where(eq(windows.id, windowId)).get()!;\n const newPanes = db.select().from(panes).where(eq(panes.windowId, windowId)).all();\n\n return {\n ...newWindow,\n panes: newPanes.map(p => ({\n ...p,\n stream: stream && p.eventStream?.streamId === stream.id\n ? stream\n : null,\n })),\n };\n }),\n\n /**\n * Update a window (title, etc).\n */\n update: publicProcedure\n .input(z.object({\n id: z.string(),\n title: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n const updates: Record<string, unknown> = {};\n if (input.title !== undefined) {\n updates.title = input.title;\n updates.hasCustomTitle = true;\n }\n updates.lastAccessedAt = new Date();\n\n db.update(windows)\n .set(updates)\n .where(eq(windows.id, input.id))\n .run();\n\n return db.select().from(windows).where(eq(windows.id, input.id)).get()!;\n }),\n\n /**\n * Delete a window and all its panes/streams.\n */\n delete: publicProcedure\n .input(z.object({ id: z.string() }))\n .mutation(async ({ input }) => {\n // Get all panes for this window\n const windowPanes = db.select().from(panes).where(eq(panes.windowId, input.id)).all();\n\n // Delete streams in amux (only for panes with event streams)\n for (const pane of windowPanes) {\n if (pane.eventStream) {\n await amux.deleteStream(pane.eventStream.streamId);\n }\n }\n\n // Delete window (cascades to panes)\n db.delete(windows).where(eq(windows.id, input.id)).run();\n\n // Update active window if needed\n const activeRow = db.select().from(uiState).where(eq(uiState.key, 'active_window_id')).get();\n if (activeRow?.value === input.id) {\n const remaining = db.select().from(windows).orderBy(windows.createdAt).all();\n const newActiveId = remaining[remaining.length - 1]?.id ?? null;\n if (newActiveId) {\n db.update(uiState)\n .set({ value: newActiveId })\n .where(eq(uiState.key, 'active_window_id'))\n .run();\n } else {\n db.delete(uiState).where(eq(uiState.key, 'active_window_id')).run();\n }\n }\n\n return { ok: true };\n }),\n\n /**\n * Set the active window.\n */\n setActive: publicProcedure\n .input(z.object({ id: z.string() }))\n .mutation(async ({ input }) => {\n db.insert(uiState)\n .values({ key: 'active_window_id', value: input.id })\n .onConflictDoUpdate({ target: uiState.key, set: { value: input.id } })\n .run();\n\n // Update last accessed\n db.update(windows)\n .set({ lastAccessedAt: new Date() })\n .where(eq(windows.id, input.id))\n .run();\n\n return { ok: true };\n }),\n});\n","/**\n * Layout types for tmux-like pane splitting.\n *\n * Layout is a binary tree where:\n * - Leaf nodes are panes (contain a paneId)\n * - Branch nodes split space horizontally or vertically\n */\n\nexport type SplitDirection = 'horizontal' | 'vertical';\n\nexport interface LayoutLeaf {\n type: 'leaf';\n paneId: string;\n}\n\nexport interface LayoutBranch {\n type: 'branch';\n direction: SplitDirection;\n /** Percentage of space for first child (0-100) */\n ratio: number;\n first: LayoutNode;\n second: LayoutNode;\n}\n\nexport type LayoutNode = LayoutLeaf | LayoutBranch;\n\n/**\n * Create a leaf node for a pane.\n */\nexport function createLeaf(paneId: string): LayoutLeaf {\n return { type: 'leaf', paneId };\n}\n\n/**\n * Create a branch node splitting two children.\n */\nexport function createBranch(\n direction: SplitDirection,\n first: LayoutNode,\n second: LayoutNode,\n ratio = 50\n): LayoutBranch {\n return { type: 'branch', direction, ratio, first, second };\n}\n\n/**\n * Find all pane IDs in a layout tree.\n */\nexport function getAllPaneIds(node: LayoutNode): string[] {\n if (node.type === 'leaf') {\n return [node.paneId];\n }\n return [...getAllPaneIds(node.first), ...getAllPaneIds(node.second)];\n}\n\n/**\n * Find a pane in the layout and return its path.\n * Returns null if not found.\n */\nexport function findPanePath(\n node: LayoutNode,\n paneId: string,\n path: ('first' | 'second')[] = []\n): ('first' | 'second')[] | null {\n if (node.type === 'leaf') {\n return node.paneId === paneId ? path : null;\n }\n const firstPath = findPanePath(node.first, paneId, [...path, 'first']);\n if (firstPath) return firstPath;\n return findPanePath(node.second, paneId, [...path, 'second']);\n}\n\n/**\n * Replace a pane in the layout with a new node.\n */\nexport function replacePaneWithNode(\n root: LayoutNode,\n paneId: string,\n newNode: LayoutNode\n): LayoutNode {\n if (root.type === 'leaf') {\n return root.paneId === paneId ? newNode : root;\n }\n return {\n ...root,\n first: replacePaneWithNode(root.first, paneId, newNode),\n second: replacePaneWithNode(root.second, paneId, newNode),\n };\n}\n\n/**\n * Split a pane, creating a new branch with the original and new pane.\n */\nexport function splitPane(\n root: LayoutNode,\n paneId: string,\n newPaneId: string,\n direction: SplitDirection\n): LayoutNode {\n const originalLeaf = createLeaf(paneId);\n const newLeaf = createLeaf(newPaneId);\n const branch = createBranch(direction, originalLeaf, newLeaf);\n return replacePaneWithNode(root, paneId, branch);\n}\n\n/**\n * Remove a pane from the layout.\n * Returns the modified layout, or null if removing the only pane.\n */\nexport function removePane(root: LayoutNode, paneId: string): LayoutNode | null {\n if (root.type === 'leaf') {\n return root.paneId === paneId ? null : root;\n }\n\n // Check if either child is the pane to remove\n if (root.first.type === 'leaf' && root.first.paneId === paneId) {\n return root.second;\n }\n if (root.second.type === 'leaf' && root.second.paneId === paneId) {\n return root.first;\n }\n\n // Recursively remove from children\n const newFirst = removePane(root.first, paneId);\n const newSecond = removePane(root.second, paneId);\n\n // If a child was removed entirely, return the other\n if (newFirst === null) return newSecond;\n if (newSecond === null) return newFirst;\n\n // If either child changed, return updated branch\n if (newFirst !== root.first || newSecond !== root.second) {\n return { ...root, first: newFirst, second: newSecond };\n }\n\n return root;\n}\n\n/**\n * Update the split ratio at a specific path.\n */\nexport function updateRatio(\n root: LayoutNode,\n path: ('first' | 'second')[],\n newRatio: number\n): LayoutNode {\n if (path.length === 0) {\n if (root.type === 'branch') {\n return { ...root, ratio: Math.max(10, Math.min(90, newRatio)) };\n }\n return root;\n }\n\n if (root.type === 'leaf') return root;\n\n const [next, ...rest] = path;\n if (next === 'first') {\n return { ...root, first: updateRatio(root.first, rest, newRatio) };\n } else {\n return { ...root, second: updateRatio(root.second, rest, newRatio) };\n }\n}\n\n/**\n * Get the sibling pane ID when navigating in a direction.\n * Returns null if there's no sibling in that direction.\n */\nexport function getAdjacentPane(\n root: LayoutNode,\n currentPaneId: string,\n direction: 'left' | 'right' | 'up' | 'down'\n): string | null {\n const path = findPanePath(root, currentPaneId);\n if (!path) return null;\n\n // Navigate up the tree to find a branch going the right direction\n let node = root;\n const pathNodes: { node: LayoutBranch; childSide: 'first' | 'second' }[] = [];\n\n for (const step of path) {\n if (node.type === 'branch') {\n pathNodes.push({ node, childSide: step });\n node = step === 'first' ? node.first : node.second;\n }\n }\n\n // Find the closest branch that allows movement in the desired direction\n for (let i = pathNodes.length - 1; i >= 0; i--) {\n const { node: branch, childSide } = pathNodes[i];\n const isHorizontal = branch.direction === 'horizontal';\n const isVertical = branch.direction === 'vertical';\n\n // Check if this branch allows movement in the desired direction\n const canMove =\n (direction === 'left' && isHorizontal && childSide === 'second') ||\n (direction === 'right' && isHorizontal && childSide === 'first') ||\n (direction === 'up' && isVertical && childSide === 'second') ||\n (direction === 'down' && isVertical && childSide === 'first');\n\n if (canMove) {\n // Get the other child and find the closest pane in it\n const otherChild = childSide === 'first' ? branch.second : branch.first;\n return getFirstPaneInDirection(otherChild, direction);\n }\n }\n\n return null;\n}\n\n/**\n * Get the first pane when entering a subtree from a direction.\n */\nfunction getFirstPaneInDirection(\n node: LayoutNode,\n fromDirection: 'left' | 'right' | 'up' | 'down'\n): string {\n if (node.type === 'leaf') {\n return node.paneId;\n }\n\n // When entering from left, prefer the leftmost pane (first in horizontal split)\n // When entering from right, prefer the rightmost pane (second in horizontal split)\n // Similar for up/down with vertical splits\n const isHorizontal = node.direction === 'horizontal';\n\n if (fromDirection === 'left' || fromDirection === 'up') {\n // Coming from left/up, go to the first (left/top) child\n const targetChild = isHorizontal\n ? (fromDirection === 'left' ? node.first : node.first)\n : (fromDirection === 'up' ? node.first : node.first);\n return getFirstPaneInDirection(targetChild, fromDirection);\n } else {\n // Coming from right/down, go to the second (right/bottom) child\n const targetChild = isHorizontal\n ? (fromDirection === 'right' ? node.second : node.second)\n : (fromDirection === 'down' ? node.second : node.second);\n return getFirstPaneInDirection(targetChild, fromDirection);\n }\n}\n","import { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { eq } from 'drizzle-orm';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { windows, panes } from '../db/schema.js';\nimport {\n splitPane,\n removePane,\n getAllPaneIds,\n getAdjacentPane,\n updateRatio,\n type LayoutNode,\n type SplitDirection,\n} from '../../client/lib/layout.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nexport const layoutRouter = router({\n /**\n * Split a pane horizontally or vertically.\n * If source pane has a session, clones it. Otherwise creates empty pane.\n */\n split: publicProcedure\n .input(z.object({\n windowId: z.string(),\n paneId: z.string(),\n direction: z.enum(['horizontal', 'vertical']),\n // Client can provide IDs for optimistic updates\n newPaneId: z.string().optional(),\n newSessionId: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n // 1. Get source pane\n const sourcePane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!sourcePane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n // 2. Get window for layout update\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n // 3. New pane always starts empty (shows PaneTypePicker)\n // 4. Create new pane\n const newPaneId = input.newPaneId ?? randomUUID();\n db.insert(panes).values({\n id: newPaneId,\n windowId: input.windowId,\n content: null,\n eventStream: null,\n }).run();\n\n // 5. Update window layout\n const currentLayout = window.layout as LayoutNode;\n const newLayout = splitPane(currentLayout, input.paneId, newPaneId, input.direction as SplitDirection);\n\n db.update(windows)\n .set({\n layout: newLayout,\n activePaneId: newPaneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n const now = new Date();\n return {\n newPaneId,\n newStreamId: null,\n layout: newLayout,\n newPane: {\n id: newPaneId,\n windowId: input.windowId,\n content: null,\n eventStream: null,\n createdAt: now.toISOString(),\n stream: null,\n },\n // Legacy aliases\n newSessionId: null,\n };\n }),\n\n /**\n * Close a pane. If it's the last pane, close the window.\n */\n closePane: publicProcedure\n .input(z.object({\n windowId: z.string(),\n paneId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n const pane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n const currentLayout = window.layout as LayoutNode;\n const allPaneIds = getAllPaneIds(currentLayout);\n\n // Check if this is the last pane\n if (allPaneIds.length === 1) {\n // Delete stream in amux if pane has one\n if (pane.eventStream) {\n await amux.deleteStream(pane.eventStream.streamId);\n }\n // Delete window (cascades to pane)\n db.delete(windows).where(eq(windows.id, input.windowId)).run();\n return { windowClosed: true, layout: null, activePaneId: null };\n }\n\n // Delete stream in amux if pane has one\n if (pane.eventStream) {\n await amux.deleteStream(pane.eventStream.streamId);\n }\n // Delete pane\n db.delete(panes).where(eq(panes.id, input.paneId)).run();\n\n // Update layout\n const newLayout = removePane(currentLayout, input.paneId);\n if (!newLayout) {\n throw new Error('Failed to remove pane from layout');\n }\n\n // Determine new active pane\n const newActivePaneId = window.activePaneId === input.paneId\n ? getAllPaneIds(newLayout)[0]\n : window.activePaneId;\n\n db.update(windows)\n .set({\n layout: newLayout,\n activePaneId: newActivePaneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return {\n windowClosed: false,\n layout: newLayout,\n activePaneId: newActivePaneId,\n };\n }),\n\n /**\n * Set the active pane within a window.\n */\n setActivePane: publicProcedure\n .input(z.object({\n windowId: z.string(),\n paneId: z.string(),\n }))\n .mutation(async ({ input }) => {\n db.update(windows)\n .set({\n activePaneId: input.paneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return { ok: true };\n }),\n\n /**\n * Navigate to an adjacent pane.\n */\n navigate: publicProcedure\n .input(z.object({\n windowId: z.string(),\n currentPaneId: z.string(),\n direction: z.enum(['left', 'right', 'up', 'down']),\n }))\n .mutation(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n const currentLayout = window.layout as LayoutNode;\n const adjacentPaneId = getAdjacentPane(currentLayout, input.currentPaneId, input.direction);\n\n if (adjacentPaneId) {\n db.update(windows)\n .set({\n activePaneId: adjacentPaneId,\n lastAccessedAt: new Date(),\n })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return { newActivePaneId: adjacentPaneId };\n }\n\n return { newActivePaneId: null };\n }),\n\n /**\n * Update the split ratio at a specific position.\n */\n setRatio: publicProcedure\n .input(z.object({\n windowId: z.string(),\n path: z.array(z.enum(['first', 'second'])),\n ratio: z.number().min(10).max(90),\n }))\n .mutation(async ({ input }) => {\n const window = db.select().from(windows).where(eq(windows.id, input.windowId)).get();\n if (!window) {\n throw new Error(`Window ${input.windowId} not found`);\n }\n\n const currentLayout = window.layout as LayoutNode;\n const newLayout = updateRatio(currentLayout, input.path, input.ratio);\n\n db.update(windows)\n .set({ layout: newLayout })\n .where(eq(windows.id, input.windowId))\n .run();\n\n return { layout: newLayout };\n }),\n\n /**\n * Set static content for a pane (browser URL, etc.).\n * Upsert behavior - works for both initial set and updates.\n */\n setPaneContent: publicProcedure\n .input(z.object({\n paneId: z.string(),\n content: z.record(z.unknown()).nullable(),\n rendererId: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n const pane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n db.update(panes)\n .set({\n content: input.content,\n rendererId: input.rendererId ?? null,\n })\n .where(eq(panes.id, input.paneId))\n .run();\n\n return { content: input.content, rendererId: input.rendererId };\n }),\n\n /**\n * Set an event stream for a pane (agent or shell).\n * Creates stream in amux and starts the backend.\n */\n setPaneEventStream: publicProcedure\n .input(z.object({\n paneId: z.string(),\n streamConfigId: z.string(),\n directory: z.string().optional(),\n rendererId: z.string().optional(),\n // Legacy alias\n agentConfigId: z.string().optional(),\n }))\n .mutation(async ({ input }) => {\n const pane = db.select().from(panes).where(eq(panes.id, input.paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${input.paneId} not found`);\n }\n\n if (pane.eventStream) {\n throw new Error(`Pane ${input.paneId} already has an event stream`);\n }\n\n const configId = input.streamConfigId ?? input.agentConfigId!;\n\n // Create stream in amux\n const stream = await amux.createStream({\n directory: input.directory ?? process.cwd(),\n streamConfigId: configId,\n });\n\n // Update pane with event stream and rendererId\n const eventStream = { type: stream.streamType, streamId: stream.id };\n db.update(panes)\n .set({\n eventStream,\n rendererId: input.rendererId ?? null,\n })\n .where(eq(panes.id, input.paneId))\n .run();\n\n // Start the stream\n await amux.startStream(stream.id);\n\n return {\n streamId: stream.id,\n eventStream,\n stream: {\n id: stream.id,\n directory: stream.directory,\n streamConfigId: stream.streamConfigId,\n streamType: stream.streamType,\n model: stream.model,\n mode: stream.mode,\n createdAt: stream.createdAt.toISOString(),\n },\n // Legacy aliases\n sessionId: stream.id,\n process: eventStream,\n session: {\n id: stream.id,\n directory: stream.directory,\n agentConfigId: stream.streamConfigId,\n model: stream.model,\n mode: stream.mode,\n createdAt: stream.createdAt.toISOString(),\n },\n };\n }),\n});\n","import { z } from 'zod';\nimport { observable } from '@trpc/server/observable';\nimport { router, publicProcedure } from './trpc.js';\nimport { getStreamIdForPane } from '../lib/panes.js';\nimport type { StreamPayload } from '@bytespell/amux/types';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nconst paneInput = z.object({\n paneId: z.string(),\n});\n\nexport const streamsRouter = router({\n /**\n * Start stream for a pane.\n */\n start: publicProcedure\n .input(paneInput)\n .mutation(async ({ input }) => {\n const streamId = getStreamIdForPane(input.paneId);\n return amux.startStream(streamId);\n }),\n\n /**\n * Stop stream for a pane.\n */\n stop: publicProcedure\n .input(paneInput)\n .mutation(async ({ input }) => {\n const streamId = getStreamIdForPane(input.paneId);\n await amux.stopStream(streamId);\n return { ok: true };\n }),\n\n /**\n * Send input to a pane's stream.\n */\n input: publicProcedure\n .input(z.object({\n paneId: z.string(),\n message: z.string(),\n }))\n .mutation(async ({ input }) => {\n const streamId = getStreamIdForPane(input.paneId);\n await amux.input(streamId, input.message);\n return { ok: true };\n }),\n\n /**\n * Cancel the current prompt.\n */\n cancel: publicProcedure\n .input(paneInput)\n .mutation(async ({ input }) => {\n const streamId = getStreamIdForPane(input.paneId);\n await amux.cancel(streamId);\n return { ok: true };\n }),\n\n /**\n * Set stream mode.\n */\n setMode: publicProcedure\n .input(z.object({\n paneId: z.string(),\n modeId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const streamId = getStreamIdForPane(input.paneId);\n await amux.setMode(streamId, input.modeId);\n return { ok: true };\n }),\n\n /**\n * Set stream model.\n */\n setModel: publicProcedure\n .input(z.object({\n paneId: z.string(),\n modelId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const streamId = getStreamIdForPane(input.paneId);\n await amux.setModel(streamId, input.modelId);\n return { ok: true };\n }),\n\n /**\n * Respond to a permission request.\n */\n respondPermission: publicProcedure\n .input(z.object({\n paneId: z.string(),\n requestId: z.string(),\n optionId: z.string(),\n }))\n .mutation(async ({ input }) => {\n const streamId = getStreamIdForPane(input.paneId);\n amux.respondPermission(streamId, input.requestId, input.optionId);\n return { ok: true };\n }),\n\n /**\n * Subscribe to updates for a pane's stream.\n */\n subscribe: publicProcedure\n .input(paneInput)\n .subscription(({ input }) => {\n const streamId = getStreamIdForPane(input.paneId);\n return observable<StreamPayload>((emit) => {\n return amux.subscribeToStream(streamId, (update) => {\n emit.next(update);\n });\n });\n }),\n});\n","import { eq } from 'drizzle-orm';\nimport { db } from '../db/index.js';\nimport { panes } from '../db/schema.js';\n\n/**\n * Get the streamId for a pane that has an event stream.\n * Throws if the pane doesn't exist or doesn't have an event stream.\n */\nexport function getStreamIdForPane(paneId: string): string {\n const pane = db.select().from(panes).where(eq(panes.id, paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${paneId} not found`);\n }\n if (!pane.eventStream) {\n throw new Error(`Pane ${paneId} does not have an event stream`);\n }\n return pane.eventStream.streamId;\n}\n","import { z } from 'zod';\nimport { router, publicProcedure } from './trpc.js';\nimport { getStreamIdForPane } from '../lib/panes.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nexport const filesRouter = router({\n /**\n * List files/directories matching a partial path for autocomplete.\n * Returns files in the session's working directory.\n */\n listForAutocomplete: publicProcedure\n .input(z.object({\n paneId: z.string(),\n partialPath: z.string(),\n limit: z.number().default(20),\n }))\n .query(async ({ input }) => {\n const streamId = getStreamIdForPane(input.paneId);\n return amux.listFilesForAutocomplete(streamId, input.partialPath, input.limit);\n }),\n});\n","import { z } from 'zod';\nimport { eq } from 'drizzle-orm';\nimport { router, publicProcedure } from './trpc.js';\nimport { db } from '../db/index.js';\nimport { panes } from '../db/schema.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\nlet amux: AmuxBridge;\n\nexport function setAmuxBridge(bridge: AmuxBridge) {\n amux = bridge;\n}\n\nconst paneInput = z.object({\n paneId: z.string(),\n});\n\n// Helper to get streamId from paneId (for panes with an event stream)\nfunction getStreamIdForPane(paneId: string): string {\n const pane = db.select().from(panes).where(eq(panes.id, paneId)).get();\n if (!pane) {\n throw new Error(`Pane ${paneId} not found`);\n }\n if (!pane.eventStream) {\n throw new Error(`Pane ${paneId} does not have an event stream`);\n }\n return pane.eventStream.streamId;\n}\n\n/**\n * Terminal-specific tRPC router.\n *\n * These endpoints are for interactive terminal panes (ShellBackend).\n * Regular ACP panes use the streams router instead.\n */\nexport const terminalsRouter = router({\n /**\n * Write raw input to terminal (keystrokes from client).\n */\n write: publicProcedure\n .input(\n z.object({\n paneId: z.string(),\n data: z.string(),\n })\n )\n .mutation(({ input }) => {\n const streamId = getStreamIdForPane(input.paneId);\n amux.terminalWrite(streamId, input.data);\n return { ok: true };\n }),\n\n /**\n * Resize terminal dimensions.\n */\n resize: publicProcedure\n .input(\n z.object({\n paneId: z.string(),\n cols: z.number().int().positive(),\n rows: z.number().int().positive(),\n })\n )\n .mutation(({ input }) => {\n const streamId = getStreamIdForPane(input.paneId);\n amux.terminalResize(streamId, input.cols, input.rows);\n return { ok: true };\n }),\n\n /**\n * Check if a pane is a terminal stream.\n */\n isTerminal: publicProcedure.input(paneInput).query(({ input }) => {\n const streamId = getStreamIdForPane(input.paneId);\n return { isTerminal: amux.isTerminalStream(streamId) };\n }),\n\n /**\n * Set terminal title (from OSC escape sequence).\n */\n setTitle: publicProcedure\n .input(z.object({\n paneId: z.string(),\n title: z.string(),\n }))\n .mutation(({ input }) => {\n const streamId = getStreamIdForPane(input.paneId);\n amux.updateStreamTitle(streamId, input.title);\n return { ok: true };\n }),\n});\n","import { z } from 'zod';\nimport { observable } from '@trpc/server/observable';\nimport { router, publicProcedure } from './trpc.js';\nimport {\n RendererEventEmitter,\n scanRenderers,\n watchRenderers,\n} from '../lib/rendererWatcher.js';\nimport type { CompiledRenderer } from '../lib/rendererCompiler.js';\n\n// Global event emitter for renderer events\nconst rendererEmitter = new RendererEventEmitter();\n\n// Cleanup function for watcher\nlet stopWatcher: (() => void) | null = null;\n\n/**\n * Initialize the renderer watcher.\n * Should be called once when the server starts.\n */\nexport function initRendererWatcher(): void {\n // Stop existing watcher if running\n if (stopWatcher) {\n stopWatcher();\n }\n stopWatcher = watchRenderers(rendererEmitter);\n}\n\n/**\n * Stop the renderer watcher\n */\nexport function stopRendererWatcher(): void {\n if (stopWatcher) {\n stopWatcher();\n stopWatcher = null;\n }\n}\n\nexport const renderersRouter = router({\n /**\n * List all currently available user renderers\n * Used for initial hydration when client connects.\n */\n list: publicProcedure.query(async (): Promise<CompiledRenderer[]> => {\n return scanRenderers();\n }),\n\n /**\n * Subscribe to renderer additions\n */\n onAdded: publicProcedure.subscription(() => {\n return observable<CompiledRenderer>((emit) => {\n const handler = (data: CompiledRenderer) => emit.next(data);\n rendererEmitter.on('renderer:added', handler);\n return () => rendererEmitter.off('renderer:added', handler);\n });\n }),\n\n /**\n * Subscribe to renderer updates (code changes)\n */\n onUpdated: publicProcedure.subscription(() => {\n return observable<{ id: string; code: string }>((emit) => {\n const handler = (data: { id: string; code: string }) => emit.next(data);\n rendererEmitter.on('renderer:updated', handler);\n return () => rendererEmitter.off('renderer:updated', handler);\n });\n }),\n\n /**\n * Subscribe to renderer removals\n */\n onRemoved: publicProcedure.subscription(() => {\n return observable<{ id: string }>((emit) => {\n const handler = (data: { id: string }) => emit.next(data);\n rendererEmitter.on('renderer:removed', handler);\n return () => rendererEmitter.off('renderer:removed', handler);\n });\n }),\n});\n\nexport type RenderersRouter = typeof renderersRouter;\n","import chokidar from 'chokidar';\nimport * as path from 'path';\nimport * as os from 'os';\nimport * as fs from 'fs/promises';\nimport { EventEmitter } from 'events';\nimport { compileRenderer, isValidPlugin, type CompiledRenderer } from './rendererCompiler.js';\n\n/**\n * Events emitted by the renderer watcher\n */\nexport interface RendererWatcherEvents {\n 'renderer:added': CompiledRenderer;\n 'renderer:updated': { id: string; code: string };\n 'renderer:removed': { id: string };\n 'renderer:error': { filePath: string; error: Error };\n}\n\n/**\n * Type-safe event emitter for renderer events\n */\nexport class RendererEventEmitter extends EventEmitter {\n emit<K extends keyof RendererWatcherEvents>(event: K, data: RendererWatcherEvents[K]): boolean {\n return super.emit(event, data);\n }\n\n on<K extends keyof RendererWatcherEvents>(\n event: K,\n listener: (data: RendererWatcherEvents[K]) => void\n ): this {\n return super.on(event, listener);\n }\n\n off<K extends keyof RendererWatcherEvents>(\n event: K,\n listener: (data: RendererWatcherEvents[K]) => void\n ): this {\n return super.off(event, listener);\n }\n}\n\n/**\n * Watch user renderer directory for changes\n *\n * Watches: ~/.shella/renderers/{plugin-name}/\n *\n * Each plugin is a directory containing:\n * - meta.json (metadata)\n * - index.tsx (entry point)\n * - Optional additional files for relative imports\n *\n * Emits events for added, updated, and removed renderers.\n */\nexport function watchRenderers(emitter: RendererEventEmitter): () => void {\n const userPath = path.join(os.homedir(), '.shella', 'renderers');\n\n // Ensure directory exists\n ensureDir(userPath);\n\n // Track known plugin directories\n const knownPlugins = new Map<string, boolean>();\n\n // Debounce recompilation per plugin\n const pendingCompiles = new Map<string, NodeJS.Timeout>();\n\n const watcher = chokidar.watch(userPath, {\n ignoreInitial: false,\n persistent: true,\n awaitWriteFinish: {\n stabilityThreshold: 100,\n pollInterval: 50,\n },\n depth: 3, // Watch inside plugin folders for nested components\n });\n\n /**\n * Extract the plugin directory from a file path\n * e.g., ~/.shella/renderers/my-plugin/components/Foo.tsx -> ~/.shella/renderers/my-plugin\n */\n const getPluginDir = (filePath: string): string | null => {\n const relative = path.relative(userPath, filePath);\n const parts = relative.split(path.sep);\n if (parts.length >= 1 && parts[0]) {\n return path.join(userPath, parts[0]);\n }\n return null;\n };\n\n /**\n * Schedule a debounced compile for a plugin directory\n */\n const scheduleCompile = (pluginDir: string) => {\n if (pendingCompiles.has(pluginDir)) {\n clearTimeout(pendingCompiles.get(pluginDir));\n }\n pendingCompiles.set(\n pluginDir,\n setTimeout(async () => {\n pendingCompiles.delete(pluginDir);\n await handlePluginChange(pluginDir);\n }, 100)\n );\n };\n\n /**\n * Handle a plugin being added or updated\n */\n const handlePluginChange = async (pluginDir: string) => {\n if (!(await isValidPlugin(pluginDir))) return;\n\n try {\n const compiled = await compileRenderer(pluginDir);\n if (!knownPlugins.has(pluginDir)) {\n knownPlugins.set(pluginDir, true);\n console.log(`[renderers] Added: ${compiled.id}`);\n emitter.emit('renderer:added', compiled);\n } else {\n console.log(`[renderers] Updated: ${compiled.id}`);\n emitter.emit('renderer:updated', { id: compiled.id, code: compiled.code });\n }\n } catch (err) {\n console.error(`[renderers] Error compiling ${pluginDir}:`, err);\n emitter.emit('renderer:error', {\n filePath: pluginDir,\n error: err instanceof Error ? err : new Error(String(err)),\n });\n }\n };\n\n watcher.on('add', (filePath) => {\n const pluginDir = getPluginDir(filePath);\n if (pluginDir) scheduleCompile(pluginDir);\n });\n\n watcher.on('change', (filePath) => {\n const pluginDir = getPluginDir(filePath);\n if (pluginDir) scheduleCompile(pluginDir);\n });\n\n watcher.on('unlinkDir', (dirPath) => {\n if (knownPlugins.has(dirPath)) {\n const id = `user:${path.basename(dirPath)}`;\n knownPlugins.delete(dirPath);\n console.log(`[renderers] Removed: ${id}`);\n emitter.emit('renderer:removed', { id });\n }\n });\n\n watcher.on('error', (err) => {\n console.error('[renderers] Watcher error:', err);\n });\n\n // Return cleanup function\n return () => {\n // Clear any pending compiles\n for (const timeout of pendingCompiles.values()) {\n clearTimeout(timeout);\n }\n pendingCompiles.clear();\n watcher.close();\n };\n}\n\nasync function ensureDir(dirPath: string): Promise<void> {\n try {\n await fs.mkdir(dirPath, { recursive: true });\n } catch {\n // Ignore errors - directory may already exist\n }\n}\n\n/**\n * Scan and compile all existing user renderers\n *\n * Used for initial hydration when client connects.\n */\nexport async function scanRenderers(): Promise<CompiledRenderer[]> {\n const userPath = path.join(os.homedir(), '.shella', 'renderers');\n const renderers: CompiledRenderer[] = [];\n\n try {\n const entries = await fs.readdir(userPath, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const pluginDir = path.join(userPath, entry.name);\n if (await isValidPlugin(pluginDir)) {\n try {\n const compiled = await compileRenderer(pluginDir);\n renderers.push(compiled);\n } catch (err) {\n console.error(`[renderers] Error compiling ${pluginDir}:`, err);\n }\n }\n }\n } catch {\n // Directory doesn't exist, skip\n }\n\n return renderers;\n}\n","import { build } from 'esbuild';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\n\n/**\n * Renderer metadata from meta.json files\n */\nexport interface RendererMeta {\n name: string;\n description?: string;\n target: RendererTarget;\n}\n\nexport type RendererTarget = { kind: 'stream'; streamType: string };\n\n/**\n * Compiled renderer with metadata\n */\nexport interface CompiledRenderer {\n id: string;\n name: string;\n description?: string;\n target: RendererTarget;\n code: string;\n}\n\n/**\n * Compile a renderer plugin directory\n *\n * Reads meta from meta.json, bundles index.tsx with esbuild.\n * Supports relative imports within the plugin folder.\n * Supports npm dependencies via package.json.\n * ID is derived from directory name with 'user:' prefix.\n *\n * @param pluginDir - Path to the plugin directory\n */\nexport async function compileRenderer(pluginDir: string): Promise<CompiledRenderer> {\n const metaPath = path.join(pluginDir, 'meta.json');\n const entryPath = path.join(pluginDir, 'index.tsx');\n const pkgPath = path.join(pluginDir, 'package.json');\n let meta: RendererMeta;\n\n try {\n const metaContent = await fs.readFile(metaPath, 'utf-8');\n meta = JSON.parse(metaContent) as RendererMeta;\n } catch (err) {\n throw new Error(\n `Failed to read meta file for ${pluginDir}. ` +\n `Expected ${metaPath} with { name, target } properties. ` +\n `Error: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n\n // Validate required meta fields\n if (!meta.name || typeof meta.name !== 'string') {\n throw new Error(`Meta file ${metaPath} must have a 'name' string property`);\n }\n if (!meta.target || !meta.target.kind) {\n throw new Error(`Meta file ${metaPath} must have a 'target' object with 'kind' property`);\n }\n\n // Check for package.json and validate dependencies\n let hasPackageJson = false;\n try {\n const pkgContent = await fs.readFile(pkgPath, 'utf-8');\n const pkg = JSON.parse(pkgContent) as {\n dependencies?: Record<string, string>;\n };\n hasPackageJson = true;\n\n // Validate: react must not be in dependencies (should be peerDependencies)\n const deps = pkg.dependencies || {};\n if (deps['react'] || deps['react-dom']) {\n throw new Error(\n `Plugin \"${meta.name}\": react and react-dom must be in peerDependencies, not dependencies. ` +\n `This ensures plugins share the same React instance as the host app.`\n );\n }\n } catch (err) {\n // No package.json is fine - plugin just uses built-in imports\n if (err instanceof Error && err.message.includes('peerDependencies')) {\n throw err; // Re-throw validation errors\n }\n }\n\n // Bundle with esbuild\n // External packages are resolved via browser import map\n const result = await build({\n entryPoints: [entryPath],\n bundle: true,\n write: false,\n format: 'esm',\n jsx: 'automatic',\n target: 'es2020',\n external: ['react', 'react-dom', 'react/jsx-runtime', '@bytespell/shella-sdk', '@bytespell/shella-sdk/components/ui'],\n // If plugin has package.json, look for node_modules\n nodePaths: hasPackageJson ? [path.join(pluginDir, 'node_modules')] : [],\n minify: false,\n });\n\n const code = result.outputFiles[0].text;\n\n // Derive id from directory name with user: prefix\n const id = `user:${path.basename(pluginDir)}`;\n\n return {\n id,\n name: meta.name,\n description: meta.description,\n target: meta.target,\n code,\n };\n}\n\n/**\n * Check if a directory is a valid plugin (has meta.json and index.tsx)\n */\nexport async function isValidPlugin(dirPath: string): Promise<boolean> {\n try {\n await fs.access(path.join(dirPath, 'meta.json'));\n await fs.access(path.join(dirPath, 'index.tsx'));\n return true;\n } catch {\n return false;\n }\n}\n","import { router } from './trpc.js';\nimport { windowsRouter, setAmuxBridge as setWindowsAmux } from './windows.js';\nimport { layoutRouter, setAmuxBridge as setLayoutAmux } from './layout.js';\nimport { streamsRouter, setAmuxBridge as setStreamsAmux } from './agents.js';\nimport { filesRouter, setAmuxBridge as setFilesAmux } from './files.js';\nimport { terminalsRouter, setAmuxBridge as setTerminalsAmux } from './terminals.js';\nimport { renderersRouter, initRendererWatcher } from './renderers.js';\nimport type { AmuxBridge } from '../amuxBridge.js';\n\n/**\n * Initialize all routers with the amux bridge.\n * Must be called before any routes are used.\n */\nexport function initializeRouters(amux: AmuxBridge) {\n setWindowsAmux(amux);\n setLayoutAmux(amux);\n setStreamsAmux(amux);\n setFilesAmux(amux);\n setTerminalsAmux(amux);\n\n // Initialize renderer watcher for user renderers (~/.shella/renderers/)\n initRendererWatcher();\n}\n\n/**\n * Shella's tRPC router.\n *\n * Provides UI-layer endpoints:\n * - windows: Window CRUD (with panes)\n * - layout: Split, close, navigate panes\n * - streams: Proxy to amux for stream operations\n * - terminals: Terminal-specific operations (ShellBackend)\n */\nexport const shellaRouter = router({\n windows: windowsRouter,\n layout: layoutRouter,\n streams: streamsRouter,\n files: filesRouter,\n terminals: terminalsRouter,\n renderers: renderersRouter,\n // Legacy alias\n agents: streamsRouter,\n});\n\nexport type ShellaRouter = typeof shellaRouter;\n"],"mappings":";;;;;;;;AASA,SAAS,eAAe;AACxB,SAAS,yBAAyB;AAClC,SAAS,aAAa;AACtB,YAAY,OAAO;;;ACDnB,OAAO,aAAa;AACpB,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB;AAChC,OAAOA,WAAU;AACjB,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,+BAA+B;AACxC,SAAS,uBAAuB;AAChC,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,YAAY,aAAa;;;ACnBlC,OAAO,cAAc;AACrB,SAAS,eAAe;;;ACDxB,OAAO,UAAU;AACjB,OAAO,QAAQ;AACf,OAAO,QAAQ;AAMR,SAAS,aAAqB;AACnC,QAAM,OAAO,GAAG,QAAQ;AAExB,MAAI;AAEJ,UAAQ,QAAQ,UAAU;AAAA,IACxB,KAAK;AACH,gBAAU,KAAK,KAAK,MAAM,WAAW,uBAAuB,QAAQ;AACpE;AAAA,IACF,KAAK;AACH,gBAAU,KAAK,KAAK,QAAQ,IAAI,WAAW,KAAK,KAAK,MAAM,WAAW,SAAS,GAAG,QAAQ;AAC1F;AAAA,IACF;AAEE,gBAAU,KAAK,KAAK,QAAQ,IAAI,iBAAiB,KAAK,KAAK,MAAM,UAAU,OAAO,GAAG,QAAQ;AAAA,EACjG;AAEA,SAAO;AACT;AAKO,SAAS,aAAsB;AACpC,SAAO,QAAQ,IAAI,qBAAqB;AAC1C;AAMO,SAAS,kBAA0B;AACxC,QAAM,WAAW,WAAW,IAAI,sBAAsB;AACtD,SAAO,KAAK,KAAK,WAAW,GAAG,QAAQ;AACzC;AAKO,SAAS,UAAU,KAAmB;AAC3C,MAAI,CAAC,GAAG,WAAW,GAAG,GAAG;AACvB,OAAG,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,EACvC;AACF;;;ACnDA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,aAAa,MAAM,eAAe;AAC3C,SAAS,WAAW;AASb,IAAM,gBAAgB,YAAY,kBAAkB;AAAA,EACzD,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,MAAM,KAAK,MAAM,EAAE,QAAQ;AAAA;AAAA,EAE3B,YAAY,KAAK,aAAa,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EACvD,SAAS,KAAK,SAAS,EAAE,QAAQ;AAAA,EACjC,MAAM,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAC,EAAE,MAAgB,EAAE,QAAQ,CAAC,CAAC;AAAA,EACjE,KAAK,KAAK,OAAO,EAAE,MAAM,OAAO,CAAC,EAAE,MAA8B,EAAE,QAAQ,CAAC,CAAC;AAAA,EAC7E,WAAW,QAAQ,cAAc,EAAE,MAAM,eAAe,CAAC,EACtD,QAAQ,EACR,QAAQ,yBAAyB;AACtC,CAAC;AAMM,IAAM,UAAU,YAAY,WAAW;AAAA,EAC5C,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,WAAW,KAAK,WAAW,EAAE,QAAQ;AAAA,EACrC,gBAAgB,KAAK,kBAAkB,EAAE,QAAQ,EAAE,WAAW,MAAM,cAAc,EAAE;AAAA;AAAA,EAEpF,YAAY,KAAK,aAAa,EAAE,QAAQ;AAAA;AAAA,EAExC,aAAa,KAAK,gBAAgB,EAAE,MAAM,OAAO,CAAC,EAAE,MAAe;AAAA;AAAA,EAEnE,OAAO,KAAK,OAAO;AAAA,EACnB,OAAO,KAAK,OAAO;AAAA,EACnB,MAAM,KAAK,MAAM;AAAA,EACjB,WAAW,QAAQ,cAAc,EAAE,MAAM,eAAe,CAAC,EACtD,QAAQ,EACR,QAAQ,yBAAyB;AACtC,CAAC;AAQM,IAAM,UAAU,YAAY,WAAW;AAAA,EAC5C,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,OAAO,KAAK,OAAO,EAAE,QAAQ;AAAA,EAC7B,gBAAgB,QAAQ,oBAAoB,EAAE,MAAM,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA;AAAA,EAExF,QAAQ,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC,EAAE,MAAkB,EAAE,QAAQ;AAAA,EACrE,cAAc,KAAK,gBAAgB,EAAE,QAAQ;AAAA,EAC7C,WAAW,QAAQ,cAAc,EAAE,MAAM,eAAe,CAAC,EACtD,QAAQ,EACR,QAAQ,yBAAyB;AAAA,EACpC,gBAAgB,QAAQ,oBAAoB,EAAE,MAAM,eAAe,CAAC,EACjE,QAAQ,EACR,QAAQ,yBAAyB;AACtC,CAAC;AAoBM,IAAM,QAAQ,YAAY,SAAS;AAAA,EACxC,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,EAC1B,UAAU,KAAK,WAAW,EACvB,QAAQ,EACR,WAAW,MAAM,QAAQ,IAAI,EAAE,UAAU,UAAU,CAAC;AAAA;AAAA,EAEvD,SAAS,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC,EAAE,MAAmB;AAAA;AAAA,EAE9D,aAAa,KAAK,gBAAgB,EAAE,MAAM,OAAO,CAAC,EAAE,MAAuB;AAAA;AAAA,EAE3E,YAAY,KAAK,aAAa;AAAA,EAC9B,WAAW,QAAQ,cAAc,EAAE,MAAM,eAAe,CAAC,EACtD,QAAQ,EACR,QAAQ,yBAAyB;AACtC,CAAC;AAMM,IAAM,UAAU,YAAY,YAAY;AAAA,EAC7C,KAAK,KAAK,KAAK,EAAE,WAAW;AAAA,EAC5B,OAAO,KAAK,OAAO,EAAE,QAAQ;AAC/B,CAAC;;;AFrGD,UAAU,WAAW,CAAC;AAEtB,IAAM,SAAS,IAAI,SAAS,gBAAgB,CAAC;AAC7C,OAAO,OAAO,oBAAoB;AAClC,OAAO,OAAO,mBAAmB;AAE1B,IAAM,KAAK,QAAQ,QAAQ,EAAE,uBAAO,CAAC;AAG5C,OAAO,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAgDX;AAGD,IAAI;AACF,QAAM,aAAa,OAAO,QAAQ,mCAAmC,EAAE,IAAI;AAC3E,QAAM,gBAAgB,WAAW,KAAK,SAAO,IAAI,SAAS,aAAa;AAEvE,MAAI,CAAC,eAAe;AAClB,YAAQ,IAAI,qDAAqD;AACjE,WAAO,KAAK,+EAA+E;AAI3F,WAAO,KAAK,2EAA2E;AACvF,WAAO,KAAK,2EAA2E;AACvF,YAAQ,IAAI,qCAAqC;AAAA,EACnD;AACF,SAAS,GAAG;AAEZ;AAGA,IAAI;AAEF,QAAM,YAAY,OAAO,QAAQ,0BAA0B,EAAE,IAAI;AACjE,QAAM,mBAAmB,UAAU,KAAK,SAAO,IAAI,SAAS,SAAS;AACrE,QAAM,uBAAuB,UAAU,KAAK,SAAO,IAAI,SAAS,cAAc;AAE9E,MAAI,oBAAoB,CAAC,sBAAsB;AAC7C,YAAQ,IAAI,uDAAuD;AAGnE,WAAO,KAAK,gDAAgD;AAK5D,UAAM,mBAAmB,OAAO,QAAQ,yDAAyD,EAAE,IAAI;AAEvG,eAAW,QAAQ,kBAAkB;AACnC,UAAI;AACF,cAAMC,WAAU,KAAK,MAAM,KAAK,OAAO;AACvC,YAAIA,SAAQ,SAAS,aAAaA,SAAQ,WAAW;AAEnD,gBAAM,cAAc,KAAK,UAAU,EAAE,MAAM,OAAO,UAAUA,SAAQ,UAAU,CAAC;AAC/E,iBAAO,QAAQ,gDAAgD,EAAE,IAAI,aAAa,KAAK,EAAE;AAAA,QAC3F;AAAA,MACF,SAAS,GAAG;AAAA,MAEZ;AAAA,IACF;AAEA,YAAQ,IAAI,qCAAqC,iBAAiB,QAAQ,OAAO;AAAA,EACnF;AACF,SAAS,GAAG;AAEZ;;;AGtHA,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAqB3B,SAAS,cAAc,KAAsB;AAC3C,MAAI;AACF,aAAS,SAAS,GAAG,IAAI,EAAE,OAAO,SAAS,CAAC;AAC5C,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,IAAM,mBAA2C;AAAA,EACtD,MAAM;AAAA,EACN,WAAgC;AAC9B,QAAI,CAAC,cAAc,QAAQ,GAAG;AAC5B,aAAO;AAAA,IACT;AACA,WAAO;AAAA,MACL,IAAI,WAAW;AAAA,MACf,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,MAAM,CAAC,iCAAiC;AAAA,MACxC,KAAK,CAAC;AAAA,MACN,WAAW,oBAAI,KAAK;AAAA,IACtB;AAAA,EACF;AACF;AAKO,IAAM,kBAA0C;AAAA,EACrD,MAAM;AAAA,EACN,WAAgC;AAC9B,QAAI,CAAC,cAAc,OAAO,GAAG;AAC3B,aAAO;AAAA,IACT;AACA,WAAO;AAAA,MACL,IAAI,WAAW;AAAA,MACf,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,MAAM,CAAC,2BAA2B;AAAA,MAClC,KAAK,CAAC;AAAA,MACN,WAAW,oBAAI,KAAK;AAAA,IACtB;AAAA,EACF;AACF;AAKO,IAAM,mBAA2C;AAAA,EACtD,MAAM;AAAA,EACN,WAAgC;AAC9B,QAAI,CAAC,cAAc,QAAQ,GAAG;AAC5B,aAAO;AAAA,IACT;AACA,WAAO;AAAA,MACL,IAAI,WAAW;AAAA,MACf,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,MAAM,CAAC,oBAAoB;AAAA,MAC3B,KAAK,CAAC;AAAA,MACN,WAAW,oBAAI,KAAK;AAAA,IACtB;AAAA,EACF;AACF;AAKO,IAAM,qBAA6C;AAAA,EACxD,MAAM;AAAA,EACN,WAAgC;AAC9B,QAAI,CAAC,cAAc,UAAU,GAAG;AAC9B,aAAO;AAAA,IACT;AACA,WAAO;AAAA,MACL,IAAI,WAAW;AAAA,MACf,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,MAAM,CAAC,KAAK;AAAA,MACZ,KAAK,CAAC;AAAA,MACN,WAAW,oBAAI,KAAK;AAAA,IACtB;AAAA,EACF;AACF;AAKO,IAAM,kBAA0C;AAAA,EACrD,MAAM;AAAA,EACN,WAAgC;AAC9B,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS;AAAA;AAAA,MACT,MAAM,CAAC;AAAA,MACP,KAAK,CAAC;AAAA,MACN,WAAW,oBAAI,KAAK;AAAA,IACtB;AAAA,EACF;AACF;AAKO,IAAM,qBAA+C;AAAA,EAC1D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMO,SAAS,2BAA2B,aAA6C;AAEtF,QAAM,WAAW,GAAG,OAAO,EAAE,KAAK,aAAa,EAAE,IAAI;AAErD,MAAI,QAAQ;AACZ,aAAW,cAAc,aAAa;AACpC,UAAM,SAAS,WAAW,SAAS;AACnC,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAGA,UAAM,gBAAgB,SAAS;AAAA,MAC7B,CAAC,MAAM,EAAE,YAAY,OAAO,WACrB,KAAK,UAAU,EAAE,IAAI,MAAM,KAAK,UAAU,OAAO,IAAI;AAAA,IAC9D;AAEA,QAAI,CAAC,eAAe;AAClB,SAAG,OAAO,aAAa,EAAE,OAAO;AAAA,QAC9B,IAAI,OAAO;AAAA,QACX,MAAM,OAAO;AAAA,QACb,YAAY,OAAO;AAAA,QACnB,SAAS,OAAO;AAAA,QAChB,MAAM,OAAO;AAAA,QACb,KAAK,OAAO;AAAA,QACZ,WAAW,OAAO;AAAA,MACpB,CAAC,EAAE,IAAI;AACP,cAAQ,IAAI,wBAAwB,OAAO,IAAI,EAAE;AACjD;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,GAAG;AACb,YAAQ,IAAI,YAAY,KAAK,kCAAkC;AAAA,EACjE;AACF;;;ACvLA,OAAO,cAAc;AACrB,YAAYC,WAAU;AACtB,YAAYC,SAAQ;AACpB,YAAYC,SAAQ;AACpB,SAAS,oBAAoB;;;ACJ7B,SAAS,aAAa;AACtB,YAAYC,SAAQ;AACpB,YAAYC,WAAU;AACtB,SAAS,qBAAqB;AAE9B,IAAM,YAAiB,cAAQ,cAAc,YAAY,GAAG,CAAC;AA2B7D,eAAsB,cAAc,WAAmD;AACrF,QAAM,aAAkB,WAAK,WAAW,WAAW;AAGnD,MAAI;AACF,UAAS,WAAO,UAAU;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AAGA,QAAM,WAAgB,WAAK,WAAW,WAAW;AACjD,MAAI;AAEJ,MAAI;AACF,UAAM,cAAc,MAAS,aAAS,UAAU,OAAO;AACvD,WAAO,KAAK,MAAM,WAAW;AAAA,EAC/B,SAAS,KAAK;AACZ,UAAM,IAAI;AAAA,MACR,gCAAgC,SAAS,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAChG;AAAA,EACF;AAEA,MAAI,CAAC,KAAK,MAAM,OAAO,KAAK,OAAO,UAAU;AAC3C,UAAM,IAAI,MAAM,aAAa,SAAS,iCAAiC;AAAA,EACzE;AAEA,MAAI,CAAC,KAAK,QAAQ,OAAO,KAAK,SAAS,UAAU;AAC/C,UAAM,IAAI,MAAM,aAAa,SAAS,mCAAmC;AAAA,EAC3E;AAGA,QAAM,SAAc,WAAK,WAAW,SAAS;AAC7C,QAAM,UAAe,WAAK,QAAQ,YAAY;AAG9C,QAAS,UAAM,QAAQ,EAAE,WAAW,KAAK,CAAC;AAG1C,QAAM,UAAe,WAAK,WAAW,cAAc;AACnD,MAAI,iBAAiB;AACrB,MAAI;AACF,UAAS,WAAO,OAAO;AACvB,qBAAiB;AAAA,EACnB,QAAQ;AAAA,EAER;AAKA,QAAM,aAAkB,cAAQ,WAAW,OAAO;AAClD,QAAM,UAAe,cAAQ,YAAY,aAAa;AAEtD,QAAM,MAAM;AAAA,IACV,aAAa,CAAC,UAAU;AAAA,IACxB,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,MACL,yBAA8B,WAAK,SAAS,UAAU;AAAA,MACtD,gCAAqC,WAAK,SAAS,WAAW;AAAA,IAChE;AAAA;AAAA,IAEA,WAAW,iBAAiB,CAAM,WAAK,WAAW,cAAc,CAAC,IAAI,CAAC;AAAA,IACtE,QAAQ;AAAA,EACV,CAAC;AAED,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,MAAM,KAAK;AAAA,IACX,UAAU;AAAA,IACV;AAAA,EACF;AACF;;;ADvGA,SAAS,kBAAkB;AAI3B,SAAS,UAAU;AAeZ,IAAM,qBAAN,cAAiC,aAAa;AAAA,EACnD,KAA0C,OAAU,MAAuC;AACzF,WAAO,MAAM,KAAK,OAAO,IAAI;AAAA,EAC/B;AAAA,EAEA,GAAwC,OAAU,UAAwD;AACxG,WAAO,MAAM,GAAG,OAAO,QAAQ;AAAA,EACjC;AAAA,EAEA,IAAyC,OAAU,UAAwD;AACzG,WAAO,MAAM,IAAI,OAAO,QAAQ;AAAA,EAClC;AACF;AAIA,IAAM,gBAAgB,oBAAI,IAA6C;AAOvE,eAAe,WAAW,UAAiD;AACzE,QAAM,QAAQ,cAAc,IAAI,SAAS,SAAS;AAClD,QAAM,WAAW,OAAO,WAAW,KAAK;AAGxC,QAAM,MAAM,UAAU,SAAS,QAAQ,MAAM,OAAO;AACpD,QAAM,SAAS,MAAM;AAAA;AAAA,IAA0B;AAAA;AAE/C,QAAM,SAAS,OAAO;AACtB,MAAI,CAAC,UAAU,OAAO,OAAO,UAAU,YAAY;AACjD,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AAGA,SAAO,OAAO,SAAS;AAEvB,gBAAc,IAAI,SAAS,WAAW,EAAE,IAAI,SAAS,IAAI,QAAQ,CAAC;AAClE,SAAO;AACT;AAMA,SAAS,mBAAmB,UAAgC;AAC1D,QAAM,WAAW,GAAG,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,GAAG,cAAc,IAAI,SAAS,EAAE,CAAC,EAAE,IAAI;AAE9F,MAAI,CAAC,UAAU;AACb,OAAG,OAAO,aAAa,EACpB,OAAO;AAAA,MACN,IAAI,SAAS;AAAA,MACb,MAAM,SAAS;AAAA,MACf,YAAY,SAAS;AAAA;AAAA,MACrB,SAAS;AAAA;AAAA,MACT,MAAM,CAAC;AAAA,MACP,KAAK,CAAC;AAAA,MACN,WAAW,oBAAI,KAAK;AAAA,IACtB,CAAC,EACA,IAAI;AAAA,EACT,WAAW,SAAS,SAAS,SAAS,MAAM;AAE1C,OAAG,OAAO,aAAa,EACpB,IAAI,EAAE,MAAM,SAAS,KAAK,CAAC,EAC3B,MAAM,GAAG,cAAc,IAAI,SAAS,EAAE,CAAC,EACvC,IAAI;AAAA,EACT;AACF;AAKA,SAAS,mBAAmB,IAAkB;AAC5C,KAAG,OAAO,aAAa,EAAE,MAAM,GAAG,cAAc,IAAI,EAAE,CAAC,EAAE,IAAI;AAC/D;AAaO,SAAS,aAAa,SAAyC;AACpE,QAAM,WAAgB,WAAQ,YAAQ,GAAG,WAAW,WAAW;AAG/D,QAAM,kBAAkB,oBAAI,IAA4B;AAExD,QAAM,UAAU,SAAS,MAAM,UAAU;AAAA,IACvC,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,kBAAkB;AAAA,MAChB,oBAAoB;AAAA,MACpB,cAAc;AAAA,IAChB;AAAA,IACA,OAAO;AAAA;AAAA,EACT,CAAC;AAKD,QAAM,eAAe,CAAC,aAAoC;AACxD,UAAMC,YAAgB,eAAS,UAAU,QAAQ;AACjD,UAAM,QAAQA,UAAS,MAAW,SAAG;AACrC,QAAI,MAAM,UAAU,KAAK,MAAM,CAAC,GAAG;AACjC,aAAY,WAAK,UAAU,MAAM,CAAC,CAAC;AAAA,IACrC;AACA,WAAO;AAAA,EACT;AAKA,QAAM,eAAe,CAAC,aAA8B;AAClD,UAAMA,YAAgB,eAAS,UAAU,QAAQ;AACjD,UAAM,QAAQA,UAAS,MAAW,SAAG;AAErC,WACE,MAAM,UAAU,MACf,MAAM,CAAC,MAAM,eAAe,MAAM,CAAC,GAAG,WAAW,SAAS,KAAK,SAAS,SAAS,UAAU;AAAA,EAEhG;AAKA,QAAM,kBAAkB,CAAC,cAAsB;AAC7C,QAAI,gBAAgB,IAAI,SAAS,GAAG;AAClC,mBAAa,gBAAgB,IAAI,SAAS,CAAC;AAAA,IAC7C;AACA,oBAAgB;AAAA,MACd;AAAA,MACA,WAAW,YAAY;AACrB,wBAAgB,OAAO,SAAS;AAChC,cAAM,mBAAmB,SAAS;AAAA,MACpC,GAAG,GAAG;AAAA,IACR;AAAA,EACF;AAKA,QAAM,qBAAqB,OAAO,cAAsB;AACtD,QAAI;AACF,YAAM,WAAW,MAAM,cAAc,SAAS;AAC9C,UAAI,CAAC,SAAU;AAEf,YAAM,WAAW,cAAc,IAAI,SAAS;AAG5C,UAAI,UAAU;AACZ,mBAAW,iBAAiB,SAAS,EAAE;AAAA,MACzC;AAEA,YAAM,SAAS,MAAM,WAAW,QAAQ;AACxC,iBAAW,eAAe,MAAM;AAChC,yBAAmB,QAAQ;AAE3B,UAAI,CAAC,UAAU;AACb,gBAAQ,IAAI,oBAAoB,SAAS,EAAE,KAAK,SAAS,IAAI,GAAG;AAChE,gBAAQ,KAAK,gBAAgB,EAAE,IAAI,SAAS,IAAI,MAAM,SAAS,KAAK,CAAC;AAAA,MACvE,OAAO;AACL,gBAAQ,IAAI,sBAAsB,SAAS,EAAE,KAAK,SAAS,IAAI,GAAG;AAClE,gBAAQ,KAAK,kBAAkB,EAAE,IAAI,SAAS,IAAI,MAAM,SAAS,KAAK,CAAC;AAAA,MACzE;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAM,6BAA6B,SAAS,KAAK,GAAG;AAC5D,cAAQ,KAAK,gBAAgB;AAAA,QAC3B;AAAA,QACA,OAAO,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAAA,MAC3D,CAAC;AAAA,IACH;AAAA,EACF;AAEA,UAAQ,GAAG,OAAO,CAAC,aAAa;AAC9B,QAAI,aAAa,QAAQ,GAAG;AAC1B,YAAM,YAAY,aAAa,QAAQ;AACvC,UAAI,UAAW,iBAAgB,SAAS;AAAA,IAC1C;AAAA,EACF,CAAC;AAED,UAAQ,GAAG,UAAU,CAAC,aAAa;AACjC,QAAI,aAAa,QAAQ,GAAG;AAC1B,YAAM,YAAY,aAAa,QAAQ;AACvC,UAAI,UAAW,iBAAgB,SAAS;AAAA,IAC1C;AAAA,EACF,CAAC;AAED,UAAQ,GAAG,UAAU,CAAC,aAAa;AACjC,QAAI,SAAS,SAAS,WAAW,GAAG;AAClC,YAAM,YAAY,aAAa,QAAQ;AACvC,UAAI,WAAW;AACb,cAAM,QAAQ,cAAc,IAAI,SAAS;AACzC,YAAI,OAAO;AACT,qBAAW,iBAAiB,MAAM,EAAE;AACpC,6BAAmB,MAAM,EAAE;AAC3B,wBAAc,OAAO,SAAS;AAC9B,kBAAQ,IAAI,sBAAsB,MAAM,EAAE,EAAE;AAC5C,kBAAQ,KAAK,kBAAkB,EAAE,IAAI,MAAM,GAAG,CAAC;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,UAAQ,GAAG,SAAS,CAAC,QAAQ;AAC3B,YAAQ,MAAM,4BAA4B,GAAG;AAAA,EAC/C,CAAC;AAGD,SAAO,MAAM;AACX,eAAW,WAAW,gBAAgB,OAAO,GAAG;AAC9C,mBAAa,OAAO;AAAA,IACtB;AACA,oBAAgB,MAAM;AACtB,YAAQ,MAAM;AAAA,EAChB;AACF;AAOA,eAAsB,cAA6B;AACjD,QAAM,WAAgB,WAAQ,YAAQ,GAAG,WAAW,WAAW;AAE/D,MAAI;AACF,UAAM,UAAU,MAAS,YAAQ,UAAU,EAAE,eAAe,KAAK,CAAC;AAElE,eAAW,SAAS,SAAS;AAC3B,UAAI,CAAC,MAAM,YAAY,EAAG;AAE1B,YAAM,YAAiB,WAAK,UAAU,MAAM,IAAI;AAChD,UAAI;AACF,cAAM,WAAW,MAAM,cAAc,SAAS;AAC9C,YAAI,UAAU;AACZ,gBAAM,SAAS,MAAM,WAAW,QAAQ;AACxC,qBAAW,eAAe,MAAM;AAChC,6BAAmB,QAAQ;AAC3B,kBAAQ,IAAI,qBAAqB,SAAS,EAAE,KAAK,SAAS,IAAI,GAAG;AAAA,QACnE;AAAA,MACF,SAAS,KAAK;AACZ,gBAAQ,MAAM,2BAA2B,SAAS,KAAK,GAAG;AAAA,MAC5D;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;;;AE9QA,SAAS,cAAAC,mBAAkB;AAC3B,OAAOC,WAAU;AACjB,OAAOC,SAAQ;AACf,SAAS,MAAAC,KAAI,eAAe;;;ACb5B,YAAYC,SAAQ;AACpB,YAAYC,WAAU;AACtB,SAAS,YAAY;AAYrB,eAAsB,yBACpB,YACA,aACA,OACsB;AAEtB,QAAM,aAAa,YAAY,WAAW,IAAI,IAC1C,YAAY,MAAM,CAAC,IACnB;AAGJ,MAAI,WAAW,SAAS,GAAG,GAAG;AAC5B,WAAO,gBAAgB,YAAY,YAAY,KAAK;AAAA,EACtD;AAGA,SAAO,eAAe,YAAY,YAAY,KAAK;AACrD;AAKA,eAAe,gBACb,YACA,aACA,OACsB;AACtB,QAAM,YAAY,YAAY,YAAY,GAAG;AAC7C,QAAM,UAAU,aAAa,IAAI,YAAY,MAAM,GAAG,SAAS,IAAI;AACnE,QAAM,SAAS,aAAa,IAAI,YAAY,MAAM,YAAY,CAAC,IAAI;AAEnE,QAAM,YAAiB,cAAQ,YAAY,OAAO;AAGlD,QAAM,uBAA4B,cAAQ,UAAU;AACpD,QAAM,sBAA2B,cAAQ,SAAS;AAClD,MAAI,CAAC,oBAAoB,WAAW,oBAAoB,GAAG;AACzD,WAAO,CAAC;AAAA,EACV;AAEA,MAAI;AACF,UAAM,UAAU,MAAS,YAAQ,WAAW,EAAE,eAAe,KAAK,CAAC;AAEnE,UAAM,WAAW,QACd,OAAO,OAAK,CAAC,EAAE,KAAK,WAAW,GAAG,CAAC,EACnC,OAAO,OAAK,WAAW,MAAM,EAAE,KAAK,YAAY,EAAE,WAAW,OAAO,YAAY,CAAC,CAAC,EAClF,MAAM,GAAG,QAAQ,CAAC,EAClB,IAAI,QAAM;AAAA,MACT,MAAM,EAAE;AAAA,MACR,MAAM,UAAU,GAAG,OAAO,IAAI,EAAE,IAAI,KAAK,EAAE;AAAA,MAC3C,aAAa,EAAE,YAAY;AAAA,IAC7B,EAAE;AAEJ,aAAS,KAAK,CAAC,GAAG,MAAM;AACtB,UAAI,EAAE,gBAAgB,EAAE,aAAa;AACnC,eAAO,EAAE,cAAc,KAAK;AAAA,MAC9B;AACA,aAAO,EAAE,KAAK,cAAc,EAAE,IAAI;AAAA,IACpC,CAAC;AAED,WAAO,SAAS,MAAM,GAAG,KAAK;AAAA,EAChC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAKA,eAAe,eACb,YACA,OACA,OACsB;AACtB,MAAI,CAAC,MAAM,KAAK,EAAG,QAAO,CAAC;AAE3B,MAAI;AAGF,UAAM,UAAU,KAAK,KAAK,SAAS,KAAK;AACxC,UAAM,UAAU,MAAM,KAAK,SAAS;AAAA,MAClC,KAAK;AAAA,MACL,OAAO;AAAA,MACP,KAAK;AAAA;AAAA,MACL,QAAQ,CAAC,sBAAsB,YAAY;AAAA,MAC3C,UAAU;AAAA,IACZ,CAAC;AAGD,UAAM,UAAuB,CAAC;AAC9B,eAAW,SAAS,QAAQ,MAAM,GAAG,QAAQ,CAAC,GAAG;AAC/C,UAAI;AACF,cAAM,WAAgB,WAAK,YAAY,KAAK;AAC5C,cAAMC,QAAO,MAAS,SAAK,QAAQ;AACnC,gBAAQ,KAAK;AAAA,UACX,MAAW,eAAS,KAAK;AAAA,UACzB,MAAM;AAAA,UACN,aAAaA,MAAK,YAAY;AAAA,QAChC,CAAC;AAAA,MACH,QAAQ;AAAA,MAER;AAAA,IACF;AAGA,YAAQ,KAAK,CAAC,GAAG,MAAM;AACrB,UAAI,EAAE,gBAAgB,EAAE,aAAa;AACnC,eAAO,EAAE,cAAc,KAAK;AAAA,MAC9B;AAEA,YAAM,SAAS,EAAE,KAAK,MAAM,GAAG,EAAE;AACjC,YAAM,SAAS,EAAE,KAAK,MAAM,GAAG,EAAE;AACjC,UAAI,WAAW,QAAQ;AACrB,eAAO,SAAS;AAAA,MAClB;AACA,aAAO,EAAE,KAAK,cAAc,EAAE,IAAI;AAAA,IACpC,CAAC;AAED,WAAO,QAAQ,MAAM,GAAG,KAAK;AAAA,EAC/B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;;;ADtHA,SAAS,cAAAC,mBAAkB;AAE3B,SAAS,kBAAkB;AAG3B,SAAS,oBAAoB,UAA0B;AACrD,SAAOC,MAAK,KAAK,WAAW,GAAG,WAAW,QAAQ;AACpD;AAqEA,SAAS,yBAAyB,SAAyB;AACzD,QAAM,UAAU,QACb,QAAQ,eAAe,EAAE,EACzB,QAAQ,QAAQ,GAAG,EACnB,KAAK;AAER,QAAM,YAAY,QAAQ,MAAM,IAAI,EAAE,CAAC,KAAK;AAE5C,MAAI,UAAU,UAAU,GAAI,QAAO;AAEnC,QAAM,YAAY,UAAU,MAAM,GAAG,EAAE;AACvC,QAAM,YAAY,UAAU,YAAY,GAAG;AAC3C,SAAO,YAAY,KAAK,UAAU,MAAM,GAAG,SAAS,IAAI,QAAQ,YAAY;AAC9E;AAMO,SAAS,mBAA+B;AAC7C,QAAM,SAAqB;AAAA,IACzB,MAAM,WAAW,KAAsC;AACrD,UAAI,IAAI,WAAW,EAAG,QAAO,CAAC;AAC9B,aAAO,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,QAAQ,IAAI,GAAG,CAAC,EAAE,IAAI;AAAA,IACvE;AAAA,IAEA,MAAM,UAAU,IAAwC;AACtD,aAAO,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAMC,IAAG,QAAQ,IAAI,EAAE,CAAC,EAAE,IAAI,KAAK;AAAA,IACtE;AAAA,IAEA,MAAM,aAAa,QAA0F;AAE3G,UAAI,WAAW,OAAO;AACtB,UAAI,CAAC,UAAU;AACb,cAAM,cAAc,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAMA,IAAG,QAAQ,KAAK,4BAA4B,CAAC,EAAE,IAAI;AACvG,YAAI,aAAa,OAAO;AACtB,gBAAMC,UAAS,GAAG,OAAO,EAAE,KAAK,aAAa,EAAE,MAAMD,IAAG,cAAc,IAAI,YAAY,KAAK,CAAC,EAAE,IAAI;AAClG,cAAIC,QAAQ,YAAWA,QAAO;AAAA,QAChC;AACA,YAAI,CAAC,UAAU;AACb,gBAAM,cAAc,GAAG,OAAO,EAAE,KAAK,aAAa,EAAE,IAAI;AACxD,cAAI,CAAC,aAAa;AAChB,kBAAM,IAAI,MAAM,6BAA6B;AAAA,UAC/C;AACA,qBAAW,YAAY;AAAA,QACzB;AAAA,MACF,OAAO;AAEL,WAAG,OAAO,OAAO,EACd,OAAO,EAAE,KAAK,8BAA8B,OAAO,SAAS,CAAC,EAC7D,mBAAmB,EAAE,QAAQ,QAAQ,KAAK,KAAK,EAAE,OAAO,SAAS,EAAE,CAAC,EACpE,IAAI;AAAA,MACT;AAGA,YAAM,KAAK,OAAO,MAAMC,YAAW;AACnC,YAAM,MAAM,oBAAI,KAAK;AAGrB,YAAM,SAAS,GAAG,OAAO,EAAE,KAAK,aAAa,EAAE,MAAMF,IAAG,cAAc,IAAI,QAAQ,CAAC,EAAE,IAAI;AACzF,YAAM,aAAa,QAAQ,eAAe,QAAQ,QAAQ;AAG1D,YAAM,eAAe,eAAe,QAChC,OAAO,UAAU,MAAM,GAAG,EAAE,IAAI,KAAK,OACrC;AAEJ,SAAG,OAAO,OAAO,EAAE,OAAO;AAAA,QACxB;AAAA,QACA,WAAW,OAAO;AAAA,QAClB,gBAAgB;AAAA,QAChB;AAAA,QACA,aAAa;AAAA,QACb,OAAO;AAAA,QACP,OAAO;AAAA,QACP,MAAM;AAAA,QACN,WAAW;AAAA,MACb,CAAC,EAAE,IAAI;AAEP,aAAO,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAMA,IAAG,QAAQ,IAAI,EAAE,CAAC,EAAE,IAAI;AAAA,IACjE;AAAA,IAEA,MAAM,aAAa,IAA2B;AAC5C,YAAMF,YAAW,cAAc,EAAE;AAEjC,YAAM,aAAa,oBAAoB,EAAE;AACzC,UAAI;AACF,YAAIK,IAAG,WAAW,UAAU,GAAG;AAC7B,UAAAA,IAAG,OAAO,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,QAC3C;AAAA,MACF,QAAQ;AAAA,MAER;AACA,SAAG,OAAO,OAAO,EAAE,MAAMH,IAAG,QAAQ,IAAI,EAAE,CAAC,EAAE,IAAI;AAAA,IACnD;AAAA,IAEA,MAAM,mBAAgD;AACpD,aAAO,GAAG,OAAO,EAAE,KAAK,aAAa,EAAE,IAAI;AAAA,IAC7C;AAAA,IAEA,MAAM,YAAY,UAA8C;AAC9D,YAAM,WAAW,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAMA,IAAG,QAAQ,IAAI,QAAQ,CAAC,EAAE,IAAI;AAC/E,UAAI,CAAC,SAAU,OAAM,IAAI,MAAM,UAAU,QAAQ,YAAY;AAE7D,YAAM,WAAW,GAAG,OAAO,EAAE,KAAK,aAAa,EAAE,MAAMA,IAAG,cAAc,IAAI,SAAS,cAAc,CAAC,EAAE,IAAI;AAC1G,UAAI,CAAC,SAAU,OAAM,IAAI,MAAM,iBAAiB,SAAS,cAAc,YAAY;AAEnF,YAAM,aAAa,oBAAoB,QAAQ;AAG/C,YAAM,OAAO,CAAC,UAAuB;AAEnC,YAAI,WAAW,KAAK,KAAK,MAAM,kBAAkB,uBAAuB;AACtE,gBAAM,QAAS,MAA6B;AAC5C,cAAI,UAAU,QAAW;AACvB,eAAG,OAAO,OAAO,EACd,IAAI,EAAE,MAAM,CAAC,EACb,MAAMA,IAAG,QAAQ,IAAI,QAAQ,CAAC,EAC9B,IAAI;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAEA,YAAM,SAAuB,MAAMF,YAAW,YAAY;AAAA,QACxD;AAAA,QACA,YAAY,SAAS;AAAA,QACrB,QAAQ;AAAA,UACN,IAAI,SAAS;AAAA,UACb,MAAM,SAAS;AAAA,UACf,SAAS,SAAS;AAAA,UAClB,MAAM,SAAS,QAAQ,CAAC;AAAA,UACxB,KAAM,SAAS,OAAkC,CAAC;AAAA,QACpD;AAAA,QACA,KAAK,SAAS;AAAA,QACd,eAAe,SAAS;AAAA,QACxB;AAAA,QACA;AAAA,MACF,CAAC;AAGD,YAAM,cAAcA,YAAW,eAAe,QAAQ;AACtD,UAAI,gBAAgB,QAAW;AAC7B,WAAG,OAAO,OAAO,EACd,IAAI,EAAE,YAAY,CAAC,EACnB,MAAME,IAAG,QAAQ,IAAI,QAAQ,CAAC,EAC9B,IAAI;AAAA,MACT;AAGA,YAAM,aAAaF,YAAW,cAAc,QAAQ;AACpD,YAAM,eAAe,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC;AAC/D,YAAM,aAAa,OAAO,eAAe,WAAW,aAAaA,YAAW,sBAAsB,QAAQ;AAE1G,aAAO;AAAA,QACL,cAAc,OAAO,OAAO;AAAA,QAC5B;AAAA,QACA;AAAA,QACA,QAAQ,OAAO,OAAO;AAAA,QACtB,OAAO,OAAO,OAAO;AAAA,MACvB;AAAA,IACF;AAAA,IAEA,MAAM,WAAW,UAAiC;AAEhD,YAAM,cAAcA,YAAW,eAAe,QAAQ;AACtD,UAAI,gBAAgB,QAAW;AAC7B,WAAG,OAAO,OAAO,EACd,IAAI,EAAE,YAAY,CAAC,EACnB,MAAME,IAAG,QAAQ,IAAI,QAAQ,CAAC,EAC9B,IAAI;AAAA,MACT;AACA,YAAMF,YAAW,cAAc,QAAQ;AAAA,IACzC;AAAA,IAEA,MAAM,MAAM,UAAkB,SAAgC;AAC5D,YAAM,SAAS,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAME,IAAG,QAAQ,IAAI,QAAQ,CAAC,EAAE,IAAI;AAC7E,UAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,UAAU,QAAQ,YAAY;AAG3D,UAAI,CAAC,OAAO,OAAO;AACjB,cAAM,QAAQ,yBAAyB,OAAO;AAC9C,YAAI,OAAO;AACT,aAAG,OAAO,OAAO,EACd,IAAI,EAAE,MAAM,CAAC,EACb,MAAMA,IAAG,QAAQ,IAAI,QAAQ,CAAC,EAC9B,IAAI;AAAA,QACT;AAAA,MACF;AAGA,YAAMF,YAAW,MAAM,UAAU,OAAO;AAAA,IAC1C;AAAA,IAEA,MAAM,OAAO,UAAiC;AAC5C,YAAMA,YAAW,OAAO,QAAQ;AAAA,IAClC;AAAA,IAEA,MAAM,QAAQ,UAAkB,QAA+B;AAC7D,YAAMA,YAAW,QAAQ,UAAU,MAAM;AAAA,IAC3C;AAAA,IAEA,MAAM,SAAS,UAAkB,SAAgC;AAC/D,YAAMA,YAAW,SAAS,UAAU,OAAO;AAAA,IAC7C;AAAA,IAEA,kBAAkB,UAAkB,WAAmB,UAAwB;AAC7E,MAAAA,YAAW,kBAAkB,UAAU,WAAW,QAAQ;AAAA,IAC5D;AAAA,IAEA,kBAAkB,UAAkB,UAAsD;AACxF,YAAM,UAAU,CAAC,UAAuB;AACtC,YAAI,MAAM,aAAa,UAAU;AAC/B,mBAAS,KAAK;AAAA,QAChB;AAAA,MACF;AACA,MAAAA,YAAW,GAAG,UAAU,OAAO;AAC/B,aAAO,MAAMA,YAAW,IAAI,UAAU,OAAO;AAAA,IAC/C;AAAA,IAEA,MAAM,yBAAyB,UAAkB,aAAqB,OAAqC;AACzG,YAAM,SAAS,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAME,IAAG,QAAQ,IAAI,QAAQ,CAAC,EAAE,IAAI;AAC7E,UAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,UAAU,QAAQ,YAAY;AAC3D,aAAO,yBAAyB,OAAO,WAAW,aAAa,KAAK;AAAA,IACtE;AAAA;AAAA,IAGA,cAAc,UAAkB,MAAoB;AAClD,MAAAF,YAAW,cAAc,UAAU,IAAI;AAAA,IACzC;AAAA,IAEA,eAAe,UAAkB,MAAc,MAAoB;AACjE,MAAAA,YAAW,eAAe,UAAU,MAAM,IAAI;AAAA,IAChD;AAAA,IAEA,sBAAsB,UAAsC;AAC1D,aAAOA,YAAW,sBAAsB,QAAQ;AAAA,IAClD;AAAA,IAEA,iBAAiB,UAA2B;AAC1C,aAAOA,YAAW,iBAAiB,QAAQ;AAAA,IAC7C;AAAA,IAEA,kBAAkB,UAAkB,OAAqB;AACvD,SAAG,OAAO,OAAO,EACd,IAAI,EAAE,MAAM,CAAC,EACb,MAAME,IAAG,QAAQ,IAAI,QAAQ,CAAC,EAC9B,IAAI;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;;;AEzVA,SAAS,gBAAgB;AAEzB,IAAM,IAAI,SAAS,OAAO;AAEnB,IAAM,SAAS,EAAE;AACjB,IAAM,kBAAkB,EAAE;;;ACLjC,SAAS,SAAS;AAClB,SAAS,cAAAI,mBAAkB;AAC3B,SAAS,MAAAC,WAAU;;;AC2BZ,SAAS,WAAW,QAA4B;AACrD,SAAO,EAAE,MAAM,QAAQ,OAAO;AAChC;AAKO,SAAS,aACd,WACA,OACA,QACA,QAAQ,IACM;AACd,SAAO,EAAE,MAAM,UAAU,WAAW,OAAO,OAAO,OAAO;AAC3D;AAKO,SAAS,cAAc,MAA4B;AACxD,MAAI,KAAK,SAAS,QAAQ;AACxB,WAAO,CAAC,KAAK,MAAM;AAAA,EACrB;AACA,SAAO,CAAC,GAAG,cAAc,KAAK,KAAK,GAAG,GAAG,cAAc,KAAK,MAAM,CAAC;AACrE;AAMO,SAAS,aACd,MACA,QACAC,QAA+B,CAAC,GACD;AAC/B,MAAI,KAAK,SAAS,QAAQ;AACxB,WAAO,KAAK,WAAW,SAASA,QAAO;AAAA,EACzC;AACA,QAAM,YAAY,aAAa,KAAK,OAAO,QAAQ,CAAC,GAAGA,OAAM,OAAO,CAAC;AACrE,MAAI,UAAW,QAAO;AACtB,SAAO,aAAa,KAAK,QAAQ,QAAQ,CAAC,GAAGA,OAAM,QAAQ,CAAC;AAC9D;AAKO,SAAS,oBACd,MACA,QACA,SACY;AACZ,MAAI,KAAK,SAAS,QAAQ;AACxB,WAAO,KAAK,WAAW,SAAS,UAAU;AAAA,EAC5C;AACA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO,oBAAoB,KAAK,OAAO,QAAQ,OAAO;AAAA,IACtD,QAAQ,oBAAoB,KAAK,QAAQ,QAAQ,OAAO;AAAA,EAC1D;AACF;AAKO,SAAS,UACd,MACA,QACA,WACA,WACY;AACZ,QAAM,eAAe,WAAW,MAAM;AACtC,QAAM,UAAU,WAAW,SAAS;AACpC,QAAM,SAAS,aAAa,WAAW,cAAc,OAAO;AAC5D,SAAO,oBAAoB,MAAM,QAAQ,MAAM;AACjD;AAMO,SAAS,WAAW,MAAkB,QAAmC;AAC9E,MAAI,KAAK,SAAS,QAAQ;AACxB,WAAO,KAAK,WAAW,SAAS,OAAO;AAAA,EACzC;AAGA,MAAI,KAAK,MAAM,SAAS,UAAU,KAAK,MAAM,WAAW,QAAQ;AAC9D,WAAO,KAAK;AAAA,EACd;AACA,MAAI,KAAK,OAAO,SAAS,UAAU,KAAK,OAAO,WAAW,QAAQ;AAChE,WAAO,KAAK;AAAA,EACd;AAGA,QAAM,WAAW,WAAW,KAAK,OAAO,MAAM;AAC9C,QAAM,YAAY,WAAW,KAAK,QAAQ,MAAM;AAGhD,MAAI,aAAa,KAAM,QAAO;AAC9B,MAAI,cAAc,KAAM,QAAO;AAG/B,MAAI,aAAa,KAAK,SAAS,cAAc,KAAK,QAAQ;AACxD,WAAO,EAAE,GAAG,MAAM,OAAO,UAAU,QAAQ,UAAU;AAAA,EACvD;AAEA,SAAO;AACT;AAKO,SAAS,YACd,MACAA,OACA,UACY;AACZ,MAAIA,MAAK,WAAW,GAAG;AACrB,QAAI,KAAK,SAAS,UAAU;AAC1B,aAAO,EAAE,GAAG,MAAM,OAAO,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,QAAQ,CAAC,EAAE;AAAA,IAChE;AACA,WAAO;AAAA,EACT;AAEA,MAAI,KAAK,SAAS,OAAQ,QAAO;AAEjC,QAAM,CAAC,MAAM,GAAG,IAAI,IAAIA;AACxB,MAAI,SAAS,SAAS;AACpB,WAAO,EAAE,GAAG,MAAM,OAAO,YAAY,KAAK,OAAO,MAAM,QAAQ,EAAE;AAAA,EACnE,OAAO;AACL,WAAO,EAAE,GAAG,MAAM,QAAQ,YAAY,KAAK,QAAQ,MAAM,QAAQ,EAAE;AAAA,EACrE;AACF;AAMO,SAAS,gBACd,MACA,eACA,WACe;AACf,QAAMA,QAAO,aAAa,MAAM,aAAa;AAC7C,MAAI,CAACA,MAAM,QAAO;AAGlB,MAAI,OAAO;AACX,QAAM,YAAqE,CAAC;AAE5E,aAAW,QAAQA,OAAM;AACvB,QAAI,KAAK,SAAS,UAAU;AAC1B,gBAAU,KAAK,EAAE,MAAM,WAAW,KAAK,CAAC;AACxC,aAAO,SAAS,UAAU,KAAK,QAAQ,KAAK;AAAA,IAC9C;AAAA,EACF;AAGA,WAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,UAAM,EAAE,MAAM,QAAQ,UAAU,IAAI,UAAU,CAAC;AAC/C,UAAM,eAAe,OAAO,cAAc;AAC1C,UAAM,aAAa,OAAO,cAAc;AAGxC,UAAM,UACH,cAAc,UAAU,gBAAgB,cAAc,YACtD,cAAc,WAAW,gBAAgB,cAAc,WACvD,cAAc,QAAQ,cAAc,cAAc,YAClD,cAAc,UAAU,cAAc,cAAc;AAEvD,QAAI,SAAS;AAEX,YAAM,aAAa,cAAc,UAAU,OAAO,SAAS,OAAO;AAClE,aAAO,wBAAwB,YAAY,SAAS;AAAA,IACtD;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,wBACP,MACA,eACQ;AACR,MAAI,KAAK,SAAS,QAAQ;AACxB,WAAO,KAAK;AAAA,EACd;AAKA,QAAM,eAAe,KAAK,cAAc;AAExC,MAAI,kBAAkB,UAAU,kBAAkB,MAAM;AAEtD,UAAM,cAAc,eACf,kBAAkB,SAAS,KAAK,QAAQ,KAAK,QAC7C,kBAAkB,OAAO,KAAK,QAAQ,KAAK;AAChD,WAAO,wBAAwB,aAAa,aAAa;AAAA,EAC3D,OAAO;AAEL,UAAM,cAAc,eACf,kBAAkB,UAAU,KAAK,SAAS,KAAK,SAC/C,kBAAkB,SAAS,KAAK,SAAS,KAAK;AACnD,WAAO,wBAAwB,aAAa,aAAa;AAAA,EAC3D;AACF;;;ADpOA,IAAI;AAEG,SAAS,cAAc,QAAoB;AAChD,SAAO;AACT;AAEA,SAAS,cAAc,eAAuB,WAA2B;AAEvE,QAAM,UAAU,UAAU,MAAM,GAAG,EAAE,IAAI;AACzC,MAAI,WAAW,YAAY,OAAO,YAAY,IAAI;AAChD,WAAO;AAAA,EACT;AACA,SAAO,UAAU,gBAAgB,CAAC;AACpC;AAEO,IAAM,gBAAgB,OAAO;AAAA;AAAA;AAAA;AAAA,EAIlC,MAAM,gBAAgB,MAAM,YAAY;AACtC,UAAM,aAAa,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,QAAQ,QAAQ,SAAS,EAAE,IAAI;AAC5E,UAAM,WAAW,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,IAAI;AAC7C,UAAM,YAAY,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAMC,IAAG,QAAQ,KAAK,kBAAkB,CAAC,EAAE,IAAI;AAG3F,UAAM,YAAY,CAAC,GAAG,IAAI;AAAA,MACxB,SACG,IAAI,CAAAC,OAAKA,GAAE,aAAa,YAAY,IAAI,EACxC,OAAO,CAAC,OAAqB,OAAO,IAAI;AAAA,IAC7C,CAAC;AAGD,UAAM,cAAc,MAAM,KAAK,WAAW,SAAS;AACnD,UAAM,YAAY,IAAI,IAAI,YAAY,IAAI,OAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAGzD,UAAMC,iBAAgB,MAAM,KAAK,iBAAiB;AAElD,WAAO;AAAA,MACL,SAAS,WAAW,IAAI,QAAM;AAAA,QAC5B,GAAG;AAAA,QACH,OAAO,SACJ,OAAO,CAAAD,OAAKA,GAAE,aAAa,EAAE,EAAE,EAC/B,IAAI,CAAAA,QAAM;AAAA,UACT,GAAGA;AAAA;AAAA,UAEH,QAAQA,GAAE,cACN,UAAU,IAAIA,GAAE,YAAY,QAAQ,KAAK,OACzC;AAAA,QACN,EAAE;AAAA,MACN,EAAE;AAAA,MACF,gBAAgB,WAAW,SAAS,WAAW,WAAW,SAAS,CAAC,GAAG,MAAM;AAAA,MAC7E,eAAAC;AAAA;AAAA,MAEA,cAAcA;AAAA,IAChB;AAAA,EACF,CAAC;AAAA;AAAA;AAAA;AAAA,EAKD,KAAK,gBACF,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,EAClC,MAAM,OAAO,EAAE,MAAM,MAAM;AAC1B,UAAM,SAAS,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAMF,IAAG,QAAQ,IAAI,MAAM,EAAE,CAAC,EAAE,IAAI;AAC7E,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,UAAU,MAAM,EAAE,YAAY;AAAA,IAChD;AACA,UAAM,cAAc,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,MAAMA,IAAG,MAAM,UAAU,MAAM,EAAE,CAAC,EAAE,IAAI;AAGpF,UAAM,YAAY,YACf,IAAI,CAAAC,OAAKA,GAAE,aAAa,YAAY,IAAI,EACxC,OAAO,CAAC,OAAqB,OAAO,IAAI;AAC3C,UAAM,cAAc,MAAM,KAAK,WAAW,SAAS;AACnD,UAAM,YAAY,IAAI,IAAI,YAAY,IAAI,OAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAEzD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,YAAY,IAAI,CAAAA,QAAM;AAAA,QAC3B,GAAGA;AAAA,QACH,QAAQA,GAAE,cACN,UAAU,IAAIA,GAAE,YAAY,QAAQ,KAAK,OACzC;AAAA,MACN,EAAE;AAAA,IACJ;AAAA,EACF,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMH,QAAQ,gBACL,MAAM,EAAE,OAAO;AAAA,IACd,IAAI,EAAE,OAAO,EAAE,SAAS;AAAA,IACxB,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC3B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,IAC/B,gBAAgB,EAAE,OAAO,EAAE,SAAS;AAAA;AAAA,IAEpC,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,EACrC,CAAC,CAAC,EACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,UAAM,YAAY,MAAM,aAAa,QAAQ,IAAI;AACjD,UAAM,WAAW,MAAM,kBAAkB,MAAM;AAG/C,QAAI,SAAS;AACb,QAAI,UAAU;AACZ,eAAS,MAAM,KAAK,aAAa;AAAA,QAC/B;AAAA,QACA,gBAAgB;AAAA,MAClB,CAAC;AAAA,IACH;AAGA,UAAM,WAAW,MAAM,MAAME,YAAW;AACxC,UAAM,SAASA,YAAW;AAC1B,UAAM,gBAAgB,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,IAAI,EAAE;AACtD,UAAM,SAAqB,WAAW,MAAM;AAE5C,OAAG,OAAO,OAAO,EAAE,OAAO;AAAA,MACxB,IAAI;AAAA,MACJ,OAAO,MAAM,SAAS,cAAc,eAAe,SAAS;AAAA,MAC5D,gBAAgB,CAAC,CAAC,MAAM;AAAA,MACxB;AAAA,MACA,cAAc;AAAA,IAChB,CAAC,EAAE,IAAI;AAEP,OAAG,OAAO,KAAK,EAAE,OAAO;AAAA,MACtB,IAAI;AAAA,MACJ;AAAA,MACA,SAAS;AAAA,MACT,aAAa,SAAS,EAAE,MAAM,OAAO,YAAY,UAAU,OAAO,GAAG,IAAI;AAAA,IAC3E,CAAC,EAAE,IAAI;AAGP,OAAG,OAAO,OAAO,EACd,OAAO,EAAE,KAAK,oBAAoB,OAAO,SAAS,CAAC,EACnD,mBAAmB,EAAE,QAAQ,QAAQ,KAAK,KAAK,EAAE,OAAO,SAAS,EAAE,CAAC,EACpE,IAAI;AAGP,UAAM,YAAY,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAMH,IAAG,QAAQ,IAAI,QAAQ,CAAC,EAAE,IAAI;AAChF,UAAM,WAAW,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,MAAMA,IAAG,MAAM,UAAU,QAAQ,CAAC,EAAE,IAAI;AAEjF,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,SAAS,IAAI,CAAAC,QAAM;AAAA,QACxB,GAAGA;AAAA,QACH,QAAQ,UAAUA,GAAE,aAAa,aAAa,OAAO,KACjD,SACA;AAAA,MACN,EAAE;AAAA,IACJ;AAAA,EACF,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,QAAQ,gBACL,MAAM,EAAE,OAAO;AAAA,IACd,IAAI,EAAE,OAAO;AAAA,IACb,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,CAAC,CAAC,EACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,UAAM,UAAmC,CAAC;AAC1C,QAAI,MAAM,UAAU,QAAW;AAC7B,cAAQ,QAAQ,MAAM;AACtB,cAAQ,iBAAiB;AAAA,IAC3B;AACA,YAAQ,iBAAiB,oBAAI,KAAK;AAElC,OAAG,OAAO,OAAO,EACd,IAAI,OAAO,EACX,MAAMD,IAAG,QAAQ,IAAI,MAAM,EAAE,CAAC,EAC9B,IAAI;AAEP,WAAO,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAMA,IAAG,QAAQ,IAAI,MAAM,EAAE,CAAC,EAAE,IAAI;AAAA,EACvE,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,QAAQ,gBACL,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,EAClC,SAAS,OAAO,EAAE,MAAM,MAAM;AAE7B,UAAM,cAAc,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,MAAMA,IAAG,MAAM,UAAU,MAAM,EAAE,CAAC,EAAE,IAAI;AAGpF,eAAW,QAAQ,aAAa;AAC9B,UAAI,KAAK,aAAa;AACpB,cAAM,KAAK,aAAa,KAAK,YAAY,QAAQ;AAAA,MACnD;AAAA,IACF;AAGA,OAAG,OAAO,OAAO,EAAE,MAAMA,IAAG,QAAQ,IAAI,MAAM,EAAE,CAAC,EAAE,IAAI;AAGvD,UAAM,YAAY,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAMA,IAAG,QAAQ,KAAK,kBAAkB,CAAC,EAAE,IAAI;AAC3F,QAAI,WAAW,UAAU,MAAM,IAAI;AACjC,YAAM,YAAY,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,QAAQ,QAAQ,SAAS,EAAE,IAAI;AAC3E,YAAM,cAAc,UAAU,UAAU,SAAS,CAAC,GAAG,MAAM;AAC3D,UAAI,aAAa;AACf,WAAG,OAAO,OAAO,EACd,IAAI,EAAE,OAAO,YAAY,CAAC,EAC1B,MAAMA,IAAG,QAAQ,KAAK,kBAAkB,CAAC,EACzC,IAAI;AAAA,MACT,OAAO;AACL,WAAG,OAAO,OAAO,EAAE,MAAMA,IAAG,QAAQ,KAAK,kBAAkB,CAAC,EAAE,IAAI;AAAA,MACpE;AAAA,IACF;AAEA,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,WAAW,gBACR,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,EAClC,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,OAAG,OAAO,OAAO,EACd,OAAO,EAAE,KAAK,oBAAoB,OAAO,MAAM,GAAG,CAAC,EACnD,mBAAmB,EAAE,QAAQ,QAAQ,KAAK,KAAK,EAAE,OAAO,MAAM,GAAG,EAAE,CAAC,EACpE,IAAI;AAGP,OAAG,OAAO,OAAO,EACd,IAAI,EAAE,gBAAgB,oBAAI,KAAK,EAAE,CAAC,EAClC,MAAMA,IAAG,QAAQ,IAAI,MAAM,EAAE,CAAC,EAC9B,IAAI;AAEP,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,CAAC;AACL,CAAC;;;AEtPD,SAAS,KAAAI,UAAS;AAClB,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,MAAAC,WAAU;AAenB,IAAIC;AAEG,SAASC,eAAc,QAAoB;AAChD,EAAAD,QAAO;AACT;AAEO,IAAM,eAAe,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKjC,OAAO,gBACJ,MAAME,GAAE,OAAO;AAAA,IACd,UAAUA,GAAE,OAAO;AAAA,IACnB,QAAQA,GAAE,OAAO;AAAA,IACjB,WAAWA,GAAE,KAAK,CAAC,cAAc,UAAU,CAAC;AAAA;AAAA,IAE5C,WAAWA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC/B,cAAcA,GAAE,OAAO,EAAE,SAAS;AAAA,EACpC,CAAC,CAAC,EACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAE7B,UAAM,aAAa,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,MAAMC,IAAG,MAAM,IAAI,MAAM,MAAM,CAAC,EAAE,IAAI;AACjF,QAAI,CAAC,YAAY;AACf,YAAM,IAAI,MAAM,QAAQ,MAAM,MAAM,YAAY;AAAA,IAClD;AAGA,UAAM,SAAS,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAMA,IAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,EAAE,IAAI;AACnF,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,UAAU,MAAM,QAAQ,YAAY;AAAA,IACtD;AAIA,UAAM,YAAY,MAAM,aAAaC,YAAW;AAChD,OAAG,OAAO,KAAK,EAAE,OAAO;AAAA,MACtB,IAAI;AAAA,MACJ,UAAU,MAAM;AAAA,MAChB,SAAS;AAAA,MACT,aAAa;AAAA,IACf,CAAC,EAAE,IAAI;AAGP,UAAM,gBAAgB,OAAO;AAC7B,UAAM,YAAY,UAAU,eAAe,MAAM,QAAQ,WAAW,MAAM,SAA2B;AAErG,OAAG,OAAO,OAAO,EACd,IAAI;AAAA,MACH,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,gBAAgB,oBAAI,KAAK;AAAA,IAC3B,CAAC,EACA,MAAMD,IAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,EACpC,IAAI;AAEP,UAAM,MAAM,oBAAI,KAAK;AACrB,WAAO;AAAA,MACL;AAAA,MACA,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,IAAI;AAAA,QACJ,UAAU,MAAM;AAAA,QAChB,SAAS;AAAA,QACT,aAAa;AAAA,QACb,WAAW,IAAI,YAAY;AAAA,QAC3B,QAAQ;AAAA,MACV;AAAA;AAAA,MAEA,cAAc;AAAA,IAChB;AAAA,EACF,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,WAAW,gBACR,MAAMD,GAAE,OAAO;AAAA,IACd,UAAUA,GAAE,OAAO;AAAA,IACnB,QAAQA,GAAE,OAAO;AAAA,EACnB,CAAC,CAAC,EACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,UAAM,SAAS,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAMC,IAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,EAAE,IAAI;AACnF,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,UAAU,MAAM,QAAQ,YAAY;AAAA,IACtD;AAEA,UAAM,OAAO,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,MAAMA,IAAG,MAAM,IAAI,MAAM,MAAM,CAAC,EAAE,IAAI;AAC3E,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,QAAQ,MAAM,MAAM,YAAY;AAAA,IAClD;AAEA,UAAM,gBAAgB,OAAO;AAC7B,UAAM,aAAa,cAAc,aAAa;AAG9C,QAAI,WAAW,WAAW,GAAG;AAE3B,UAAI,KAAK,aAAa;AACpB,cAAMH,MAAK,aAAa,KAAK,YAAY,QAAQ;AAAA,MACnD;AAEA,SAAG,OAAO,OAAO,EAAE,MAAMG,IAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,EAAE,IAAI;AAC7D,aAAO,EAAE,cAAc,MAAM,QAAQ,MAAM,cAAc,KAAK;AAAA,IAChE;AAGA,QAAI,KAAK,aAAa;AACpB,YAAMH,MAAK,aAAa,KAAK,YAAY,QAAQ;AAAA,IACnD;AAEA,OAAG,OAAO,KAAK,EAAE,MAAMG,IAAG,MAAM,IAAI,MAAM,MAAM,CAAC,EAAE,IAAI;AAGvD,UAAM,YAAY,WAAW,eAAe,MAAM,MAAM;AACxD,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AAGA,UAAM,kBAAkB,OAAO,iBAAiB,MAAM,SAClD,cAAc,SAAS,EAAE,CAAC,IAC1B,OAAO;AAEX,OAAG,OAAO,OAAO,EACd,IAAI;AAAA,MACH,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,gBAAgB,oBAAI,KAAK;AAAA,IAC3B,CAAC,EACA,MAAMA,IAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,EACpC,IAAI;AAEP,WAAO;AAAA,MACL,cAAc;AAAA,MACd,QAAQ;AAAA,MACR,cAAc;AAAA,IAChB;AAAA,EACF,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,eAAe,gBACZ,MAAMD,GAAE,OAAO;AAAA,IACd,UAAUA,GAAE,OAAO;AAAA,IACnB,QAAQA,GAAE,OAAO;AAAA,EACnB,CAAC,CAAC,EACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,OAAG,OAAO,OAAO,EACd,IAAI;AAAA,MACH,cAAc,MAAM;AAAA,MACpB,gBAAgB,oBAAI,KAAK;AAAA,IAC3B,CAAC,EACA,MAAMC,IAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,EACpC,IAAI;AAEP,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,UAAU,gBACP,MAAMD,GAAE,OAAO;AAAA,IACd,UAAUA,GAAE,OAAO;AAAA,IACnB,eAAeA,GAAE,OAAO;AAAA,IACxB,WAAWA,GAAE,KAAK,CAAC,QAAQ,SAAS,MAAM,MAAM,CAAC;AAAA,EACnD,CAAC,CAAC,EACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,UAAM,SAAS,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAMC,IAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,EAAE,IAAI;AACnF,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,UAAU,MAAM,QAAQ,YAAY;AAAA,IACtD;AAEA,UAAM,gBAAgB,OAAO;AAC7B,UAAM,iBAAiB,gBAAgB,eAAe,MAAM,eAAe,MAAM,SAAS;AAE1F,QAAI,gBAAgB;AAClB,SAAG,OAAO,OAAO,EACd,IAAI;AAAA,QACH,cAAc;AAAA,QACd,gBAAgB,oBAAI,KAAK;AAAA,MAC3B,CAAC,EACA,MAAMA,IAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,EACpC,IAAI;AAEP,aAAO,EAAE,iBAAiB,eAAe;AAAA,IAC3C;AAEA,WAAO,EAAE,iBAAiB,KAAK;AAAA,EACjC,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,UAAU,gBACP,MAAMD,GAAE,OAAO;AAAA,IACd,UAAUA,GAAE,OAAO;AAAA,IACnB,MAAMA,GAAE,MAAMA,GAAE,KAAK,CAAC,SAAS,QAAQ,CAAC,CAAC;AAAA,IACzC,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE;AAAA,EAClC,CAAC,CAAC,EACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,UAAM,SAAS,GAAG,OAAO,EAAE,KAAK,OAAO,EAAE,MAAMC,IAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,EAAE,IAAI;AACnF,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,UAAU,MAAM,QAAQ,YAAY;AAAA,IACtD;AAEA,UAAM,gBAAgB,OAAO;AAC7B,UAAM,YAAY,YAAY,eAAe,MAAM,MAAM,MAAM,KAAK;AAEpE,OAAG,OAAO,OAAO,EACd,IAAI,EAAE,QAAQ,UAAU,CAAC,EACzB,MAAMA,IAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,EACpC,IAAI;AAEP,WAAO,EAAE,QAAQ,UAAU;AAAA,EAC7B,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMH,gBAAgB,gBACb,MAAMD,GAAE,OAAO;AAAA,IACd,QAAQA,GAAE,OAAO;AAAA,IACjB,SAASA,GAAE,OAAOA,GAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,IACxC,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA,EAClC,CAAC,CAAC,EACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,UAAM,OAAO,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,MAAMC,IAAG,MAAM,IAAI,MAAM,MAAM,CAAC,EAAE,IAAI;AAC3E,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,QAAQ,MAAM,MAAM,YAAY;AAAA,IAClD;AAEA,OAAG,OAAO,KAAK,EACZ,IAAI;AAAA,MACH,SAAS,MAAM;AAAA,MACf,YAAY,MAAM,cAAc;AAAA,IAClC,CAAC,EACA,MAAMA,IAAG,MAAM,IAAI,MAAM,MAAM,CAAC,EAChC,IAAI;AAEP,WAAO,EAAE,SAAS,MAAM,SAAS,YAAY,MAAM,WAAW;AAAA,EAChE,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMH,oBAAoB,gBACjB,MAAMD,GAAE,OAAO;AAAA,IACd,QAAQA,GAAE,OAAO;AAAA,IACjB,gBAAgBA,GAAE,OAAO;AAAA,IACzB,WAAWA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC/B,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA;AAAA,IAEhC,eAAeA,GAAE,OAAO,EAAE,SAAS;AAAA,EACrC,CAAC,CAAC,EACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,UAAM,OAAO,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,MAAMC,IAAG,MAAM,IAAI,MAAM,MAAM,CAAC,EAAE,IAAI;AAC3E,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,QAAQ,MAAM,MAAM,YAAY;AAAA,IAClD;AAEA,QAAI,KAAK,aAAa;AACpB,YAAM,IAAI,MAAM,QAAQ,MAAM,MAAM,8BAA8B;AAAA,IACpE;AAEA,UAAM,WAAW,MAAM,kBAAkB,MAAM;AAG/C,UAAM,SAAS,MAAMH,MAAK,aAAa;AAAA,MACrC,WAAW,MAAM,aAAa,QAAQ,IAAI;AAAA,MAC1C,gBAAgB;AAAA,IAClB,CAAC;AAGD,UAAM,cAAc,EAAE,MAAM,OAAO,YAAY,UAAU,OAAO,GAAG;AACnE,OAAG,OAAO,KAAK,EACZ,IAAI;AAAA,MACH;AAAA,MACA,YAAY,MAAM,cAAc;AAAA,IAClC,CAAC,EACA,MAAMG,IAAG,MAAM,IAAI,MAAM,MAAM,CAAC,EAChC,IAAI;AAGP,UAAMH,MAAK,YAAY,OAAO,EAAE;AAEhC,WAAO;AAAA,MACL,UAAU,OAAO;AAAA,MACjB;AAAA,MACA,QAAQ;AAAA,QACN,IAAI,OAAO;AAAA,QACX,WAAW,OAAO;AAAA,QAClB,gBAAgB,OAAO;AAAA,QACvB,YAAY,OAAO;AAAA,QACnB,OAAO,OAAO;AAAA,QACd,MAAM,OAAO;AAAA,QACb,WAAW,OAAO,UAAU,YAAY;AAAA,MAC1C;AAAA;AAAA,MAEA,WAAW,OAAO;AAAA,MAClB,SAAS;AAAA,MACT,SAAS;AAAA,QACP,IAAI,OAAO;AAAA,QACX,WAAW,OAAO;AAAA,QAClB,eAAe,OAAO;AAAA,QACtB,OAAO,OAAO;AAAA,QACd,MAAM,OAAO;AAAA,QACb,WAAW,OAAO,UAAU,YAAY;AAAA,MAC1C;AAAA,IACF;AAAA,EACF,CAAC;AACL,CAAC;;;AC7UD,SAAS,KAAAK,UAAS;AAClB,SAAS,kBAAkB;;;ACD3B,SAAS,MAAAC,WAAU;AAQZ,SAAS,mBAAmB,QAAwB;AACzD,QAAM,OAAO,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,MAAMC,IAAG,MAAM,IAAI,MAAM,CAAC,EAAE,IAAI;AACrE,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,QAAQ,MAAM,YAAY;AAAA,EAC5C;AACA,MAAI,CAAC,KAAK,aAAa;AACrB,UAAM,IAAI,MAAM,QAAQ,MAAM,gCAAgC;AAAA,EAChE;AACA,SAAO,KAAK,YAAY;AAC1B;;;ADVA,IAAIC;AAEG,SAASC,eAAc,QAAoB;AAChD,EAAAD,QAAO;AACT;AAEA,IAAM,YAAYE,GAAE,OAAO;AAAA,EACzB,QAAQA,GAAE,OAAO;AACnB,CAAC;AAEM,IAAM,gBAAgB,OAAO;AAAA;AAAA;AAAA;AAAA,EAIlC,OAAO,gBACJ,MAAM,SAAS,EACf,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,UAAM,WAAW,mBAAmB,MAAM,MAAM;AAChD,WAAOF,MAAK,YAAY,QAAQ;AAAA,EAClC,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,MAAM,gBACH,MAAM,SAAS,EACf,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,UAAM,WAAW,mBAAmB,MAAM,MAAM;AAChD,UAAMA,MAAK,WAAW,QAAQ;AAC9B,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,OAAO,gBACJ,MAAME,GAAE,OAAO;AAAA,IACd,QAAQA,GAAE,OAAO;AAAA,IACjB,SAASA,GAAE,OAAO;AAAA,EACpB,CAAC,CAAC,EACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,UAAM,WAAW,mBAAmB,MAAM,MAAM;AAChD,UAAMF,MAAK,MAAM,UAAU,MAAM,OAAO;AACxC,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,QAAQ,gBACL,MAAM,SAAS,EACf,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,UAAM,WAAW,mBAAmB,MAAM,MAAM;AAChD,UAAMA,MAAK,OAAO,QAAQ;AAC1B,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,SAAS,gBACN,MAAME,GAAE,OAAO;AAAA,IACd,QAAQA,GAAE,OAAO;AAAA,IACjB,QAAQA,GAAE,OAAO;AAAA,EACnB,CAAC,CAAC,EACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,UAAM,WAAW,mBAAmB,MAAM,MAAM;AAChD,UAAMF,MAAK,QAAQ,UAAU,MAAM,MAAM;AACzC,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,UAAU,gBACP,MAAME,GAAE,OAAO;AAAA,IACd,QAAQA,GAAE,OAAO;AAAA,IACjB,SAASA,GAAE,OAAO;AAAA,EACpB,CAAC,CAAC,EACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,UAAM,WAAW,mBAAmB,MAAM,MAAM;AAChD,UAAMF,MAAK,SAAS,UAAU,MAAM,OAAO;AAC3C,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,mBAAmB,gBAChB,MAAME,GAAE,OAAO;AAAA,IACd,QAAQA,GAAE,OAAO;AAAA,IACjB,WAAWA,GAAE,OAAO;AAAA,IACpB,UAAUA,GAAE,OAAO;AAAA,EACrB,CAAC,CAAC,EACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAC7B,UAAM,WAAW,mBAAmB,MAAM,MAAM;AAChD,IAAAF,MAAK,kBAAkB,UAAU,MAAM,WAAW,MAAM,QAAQ;AAChE,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,WAAW,gBACR,MAAM,SAAS,EACf,aAAa,CAAC,EAAE,MAAM,MAAM;AAC3B,UAAM,WAAW,mBAAmB,MAAM,MAAM;AAChD,WAAO,WAA0B,CAAC,SAAS;AACzC,aAAOA,MAAK,kBAAkB,UAAU,CAAC,WAAW;AAClD,aAAK,KAAK,MAAM;AAAA,MAClB,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACL,CAAC;;;AExHD,SAAS,KAAAG,UAAS;AAKlB,IAAIC;AAEG,SAASC,eAAc,QAAoB;AAChD,EAAAD,QAAO;AACT;AAEO,IAAM,cAAc,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKhC,qBAAqB,gBAClB,MAAME,GAAE,OAAO;AAAA,IACd,QAAQA,GAAE,OAAO;AAAA,IACjB,aAAaA,GAAE,OAAO;AAAA,IACtB,OAAOA,GAAE,OAAO,EAAE,QAAQ,EAAE;AAAA,EAC9B,CAAC,CAAC,EACD,MAAM,OAAO,EAAE,MAAM,MAAM;AAC1B,UAAM,WAAW,mBAAmB,MAAM,MAAM;AAChD,WAAOF,MAAK,yBAAyB,UAAU,MAAM,aAAa,MAAM,KAAK;AAAA,EAC/E,CAAC;AACL,CAAC;;;AC1BD,SAAS,KAAAG,UAAS;AAClB,SAAS,MAAAC,WAAU;AAMnB,IAAIC;AAEG,SAASC,eAAc,QAAoB;AAChD,EAAAD,QAAO;AACT;AAEA,IAAME,aAAYC,GAAE,OAAO;AAAA,EACzB,QAAQA,GAAE,OAAO;AACnB,CAAC;AAGD,SAASC,oBAAmB,QAAwB;AAClD,QAAM,OAAO,GAAG,OAAO,EAAE,KAAK,KAAK,EAAE,MAAMC,IAAG,MAAM,IAAI,MAAM,CAAC,EAAE,IAAI;AACrE,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,QAAQ,MAAM,YAAY;AAAA,EAC5C;AACA,MAAI,CAAC,KAAK,aAAa;AACrB,UAAM,IAAI,MAAM,QAAQ,MAAM,gCAAgC;AAAA,EAChE;AACA,SAAO,KAAK,YAAY;AAC1B;AAQO,IAAM,kBAAkB,OAAO;AAAA;AAAA;AAAA;AAAA,EAIpC,OAAO,gBACJ;AAAA,IACCF,GAAE,OAAO;AAAA,MACP,QAAQA,GAAE,OAAO;AAAA,MACjB,MAAMA,GAAE,OAAO;AAAA,IACjB,CAAC;AAAA,EACH,EACC,SAAS,CAAC,EAAE,MAAM,MAAM;AACvB,UAAM,WAAWC,oBAAmB,MAAM,MAAM;AAChD,IAAAJ,MAAK,cAAc,UAAU,MAAM,IAAI;AACvC,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,QAAQ,gBACL;AAAA,IACCG,GAAE,OAAO;AAAA,MACP,QAAQA,GAAE,OAAO;AAAA,MACjB,MAAMA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,MAChC,MAAMA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,IAClC,CAAC;AAAA,EACH,EACC,SAAS,CAAC,EAAE,MAAM,MAAM;AACvB,UAAM,WAAWC,oBAAmB,MAAM,MAAM;AAChD,IAAAJ,MAAK,eAAe,UAAU,MAAM,MAAM,MAAM,IAAI;AACpD,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,YAAY,gBAAgB,MAAME,UAAS,EAAE,MAAM,CAAC,EAAE,MAAM,MAAM;AAChE,UAAM,WAAWE,oBAAmB,MAAM,MAAM;AAChD,WAAO,EAAE,YAAYJ,MAAK,iBAAiB,QAAQ,EAAE;AAAA,EACvD,CAAC;AAAA;AAAA;AAAA;AAAA,EAKD,UAAU,gBACP,MAAMG,GAAE,OAAO;AAAA,IACd,QAAQA,GAAE,OAAO;AAAA,IACjB,OAAOA,GAAE,OAAO;AAAA,EAClB,CAAC,CAAC,EACD,SAAS,CAAC,EAAE,MAAM,MAAM;AACvB,UAAM,WAAWC,oBAAmB,MAAM,MAAM;AAChD,IAAAJ,MAAK,kBAAkB,UAAU,MAAM,KAAK;AAC5C,WAAO,EAAE,IAAI,KAAK;AAAA,EACpB,CAAC;AACL,CAAC;;;ACzFD,SAAS,cAAAM,mBAAkB;;;ACD3B,OAAOC,eAAc;AACrB,YAAYC,WAAU;AACtB,YAAYC,SAAQ;AACpB,YAAYC,SAAQ;AACpB,SAAS,gBAAAC,qBAAoB;;;ACJ7B,SAAS,SAAAC,cAAa;AACtB,YAAYC,SAAQ;AACpB,YAAYC,WAAU;AAkCtB,eAAsB,gBAAgB,WAA8C;AAClF,QAAM,WAAgB,WAAK,WAAW,WAAW;AACjD,QAAM,YAAiB,WAAK,WAAW,WAAW;AAClD,QAAM,UAAe,WAAK,WAAW,cAAc;AACnD,MAAI;AAEJ,MAAI;AACF,UAAM,cAAc,MAAS,aAAS,UAAU,OAAO;AACvD,WAAO,KAAK,MAAM,WAAW;AAAA,EAC/B,SAAS,KAAK;AACZ,UAAM,IAAI;AAAA,MACR,gCAAgC,SAAS,cAC3B,QAAQ,6CACV,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAC9D;AAAA,EACF;AAGA,MAAI,CAAC,KAAK,QAAQ,OAAO,KAAK,SAAS,UAAU;AAC/C,UAAM,IAAI,MAAM,aAAa,QAAQ,qCAAqC;AAAA,EAC5E;AACA,MAAI,CAAC,KAAK,UAAU,CAAC,KAAK,OAAO,MAAM;AACrC,UAAM,IAAI,MAAM,aAAa,QAAQ,mDAAmD;AAAA,EAC1F;AAGA,MAAI,iBAAiB;AACrB,MAAI;AACF,UAAM,aAAa,MAAS,aAAS,SAAS,OAAO;AACrD,UAAM,MAAM,KAAK,MAAM,UAAU;AAGjC,qBAAiB;AAGjB,UAAM,OAAO,IAAI,gBAAgB,CAAC;AAClC,QAAI,KAAK,OAAO,KAAK,KAAK,WAAW,GAAG;AACtC,YAAM,IAAI;AAAA,QACR,WAAW,KAAK,IAAI;AAAA,MAEtB;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AAEZ,QAAI,eAAe,SAAS,IAAI,QAAQ,SAAS,kBAAkB,GAAG;AACpE,YAAM;AAAA,IACR;AAAA,EACF;AAIA,QAAM,SAAS,MAAMF,OAAM;AAAA,IACzB,aAAa,CAAC,SAAS;AAAA,IACvB,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,UAAU,CAAC,SAAS,aAAa,qBAAqB,yBAAyB,qCAAqC;AAAA;AAAA,IAEpH,WAAW,iBAAiB,CAAM,WAAK,WAAW,cAAc,CAAC,IAAI,CAAC;AAAA,IACtE,QAAQ;AAAA,EACV,CAAC;AAED,QAAM,OAAO,OAAO,YAAY,CAAC,EAAE;AAGnC,QAAM,KAAK,QAAa,eAAS,SAAS,CAAC;AAE3C,SAAO;AAAA,IACL;AAAA,IACA,MAAM,KAAK;AAAA,IACX,aAAa,KAAK;AAAA,IAClB,QAAQ,KAAK;AAAA,IACb;AAAA,EACF;AACF;AAKA,eAAsB,cAAc,SAAmC;AACrE,MAAI;AACF,UAAS,WAAY,WAAK,SAAS,WAAW,CAAC;AAC/C,UAAS,WAAY,WAAK,SAAS,WAAW,CAAC;AAC/C,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ADzGO,IAAM,uBAAN,cAAmCG,cAAa;AAAA,EACrD,KAA4C,OAAU,MAAyC;AAC7F,WAAO,MAAM,KAAK,OAAO,IAAI;AAAA,EAC/B;AAAA,EAEA,GACE,OACA,UACM;AACN,WAAO,MAAM,GAAG,OAAO,QAAQ;AAAA,EACjC;AAAA,EAEA,IACE,OACA,UACM;AACN,WAAO,MAAM,IAAI,OAAO,QAAQ;AAAA,EAClC;AACF;AAcO,SAAS,eAAe,SAA2C;AACxE,QAAM,WAAgB,WAAQ,YAAQ,GAAG,WAAW,WAAW;AAG/D,EAAAC,WAAU,QAAQ;AAGlB,QAAM,eAAe,oBAAI,IAAqB;AAG9C,QAAM,kBAAkB,oBAAI,IAA4B;AAExD,QAAM,UAAUC,UAAS,MAAM,UAAU;AAAA,IACvC,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,kBAAkB;AAAA,MAChB,oBAAoB;AAAA,MACpB,cAAc;AAAA,IAChB;AAAA,IACA,OAAO;AAAA;AAAA,EACT,CAAC;AAMD,QAAM,eAAe,CAAC,aAAoC;AACxD,UAAMC,YAAgB,eAAS,UAAU,QAAQ;AACjD,UAAM,QAAQA,UAAS,MAAW,SAAG;AACrC,QAAI,MAAM,UAAU,KAAK,MAAM,CAAC,GAAG;AACjC,aAAY,WAAK,UAAU,MAAM,CAAC,CAAC;AAAA,IACrC;AACA,WAAO;AAAA,EACT;AAKA,QAAM,kBAAkB,CAAC,cAAsB;AAC7C,QAAI,gBAAgB,IAAI,SAAS,GAAG;AAClC,mBAAa,gBAAgB,IAAI,SAAS,CAAC;AAAA,IAC7C;AACA,oBAAgB;AAAA,MACd;AAAA,MACA,WAAW,YAAY;AACrB,wBAAgB,OAAO,SAAS;AAChC,cAAM,mBAAmB,SAAS;AAAA,MACpC,GAAG,GAAG;AAAA,IACR;AAAA,EACF;AAKA,QAAM,qBAAqB,OAAO,cAAsB;AACtD,QAAI,CAAE,MAAM,cAAc,SAAS,EAAI;AAEvC,QAAI;AACF,YAAM,WAAW,MAAM,gBAAgB,SAAS;AAChD,UAAI,CAAC,aAAa,IAAI,SAAS,GAAG;AAChC,qBAAa,IAAI,WAAW,IAAI;AAChC,gBAAQ,IAAI,sBAAsB,SAAS,EAAE,EAAE;AAC/C,gBAAQ,KAAK,kBAAkB,QAAQ;AAAA,MACzC,OAAO;AACL,gBAAQ,IAAI,wBAAwB,SAAS,EAAE,EAAE;AACjD,gBAAQ,KAAK,oBAAoB,EAAE,IAAI,SAAS,IAAI,MAAM,SAAS,KAAK,CAAC;AAAA,MAC3E;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAM,+BAA+B,SAAS,KAAK,GAAG;AAC9D,cAAQ,KAAK,kBAAkB;AAAA,QAC7B,UAAU;AAAA,QACV,OAAO,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAAA,MAC3D,CAAC;AAAA,IACH;AAAA,EACF;AAEA,UAAQ,GAAG,OAAO,CAAC,aAAa;AAC9B,UAAM,YAAY,aAAa,QAAQ;AACvC,QAAI,UAAW,iBAAgB,SAAS;AAAA,EAC1C,CAAC;AAED,UAAQ,GAAG,UAAU,CAAC,aAAa;AACjC,UAAM,YAAY,aAAa,QAAQ;AACvC,QAAI,UAAW,iBAAgB,SAAS;AAAA,EAC1C,CAAC;AAED,UAAQ,GAAG,aAAa,CAAC,YAAY;AACnC,QAAI,aAAa,IAAI,OAAO,GAAG;AAC7B,YAAM,KAAK,QAAa,eAAS,OAAO,CAAC;AACzC,mBAAa,OAAO,OAAO;AAC3B,cAAQ,IAAI,wBAAwB,EAAE,EAAE;AACxC,cAAQ,KAAK,oBAAoB,EAAE,GAAG,CAAC;AAAA,IACzC;AAAA,EACF,CAAC;AAED,UAAQ,GAAG,SAAS,CAAC,QAAQ;AAC3B,YAAQ,MAAM,8BAA8B,GAAG;AAAA,EACjD,CAAC;AAGD,SAAO,MAAM;AAEX,eAAW,WAAW,gBAAgB,OAAO,GAAG;AAC9C,mBAAa,OAAO;AAAA,IACtB;AACA,oBAAgB,MAAM;AACtB,YAAQ,MAAM;AAAA,EAChB;AACF;AAEA,eAAeF,WAAU,SAAgC;AACvD,MAAI;AACF,UAAS,UAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AAAA,EAC7C,QAAQ;AAAA,EAER;AACF;AAOA,eAAsB,gBAA6C;AACjE,QAAM,WAAgB,WAAQ,YAAQ,GAAG,WAAW,WAAW;AAC/D,QAAM,YAAgC,CAAC;AAEvC,MAAI;AACF,UAAM,UAAU,MAAS,YAAQ,UAAU,EAAE,eAAe,KAAK,CAAC;AAElE,eAAW,SAAS,SAAS;AAC3B,UAAI,CAAC,MAAM,YAAY,EAAG;AAE1B,YAAM,YAAiB,WAAK,UAAU,MAAM,IAAI;AAChD,UAAI,MAAM,cAAc,SAAS,GAAG;AAClC,YAAI;AACF,gBAAM,WAAW,MAAM,gBAAgB,SAAS;AAChD,oBAAU,KAAK,QAAQ;AAAA,QACzB,SAAS,KAAK;AACZ,kBAAQ,MAAM,+BAA+B,SAAS,KAAK,GAAG;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,SAAO;AACT;;;AD7LA,IAAM,kBAAkB,IAAI,qBAAqB;AAGjD,IAAI,cAAmC;AAMhC,SAAS,sBAA4B;AAE1C,MAAI,aAAa;AACf,gBAAY;AAAA,EACd;AACA,gBAAc,eAAe,eAAe;AAC9C;AAYO,IAAM,kBAAkB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpC,MAAM,gBAAgB,MAAM,YAAyC;AACnE,WAAO,cAAc;AAAA,EACvB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKD,SAAS,gBAAgB,aAAa,MAAM;AAC1C,WAAOG,YAA6B,CAAC,SAAS;AAC5C,YAAM,UAAU,CAAC,SAA2B,KAAK,KAAK,IAAI;AAC1D,sBAAgB,GAAG,kBAAkB,OAAO;AAC5C,aAAO,MAAM,gBAAgB,IAAI,kBAAkB,OAAO;AAAA,IAC5D,CAAC;AAAA,EACH,CAAC;AAAA;AAAA;AAAA;AAAA,EAKD,WAAW,gBAAgB,aAAa,MAAM;AAC5C,WAAOA,YAAyC,CAAC,SAAS;AACxD,YAAM,UAAU,CAAC,SAAuC,KAAK,KAAK,IAAI;AACtE,sBAAgB,GAAG,oBAAoB,OAAO;AAC9C,aAAO,MAAM,gBAAgB,IAAI,oBAAoB,OAAO;AAAA,IAC9D,CAAC;AAAA,EACH,CAAC;AAAA;AAAA;AAAA;AAAA,EAKD,WAAW,gBAAgB,aAAa,MAAM;AAC5C,WAAOA,YAA2B,CAAC,SAAS;AAC1C,YAAM,UAAU,CAAC,SAAyB,KAAK,KAAK,IAAI;AACxD,sBAAgB,GAAG,oBAAoB,OAAO;AAC9C,aAAO,MAAM,gBAAgB,IAAI,oBAAoB,OAAO;AAAA,IAC9D,CAAC;AAAA,EACH,CAAC;AACH,CAAC;;;AGlEM,SAAS,kBAAkBC,OAAkB;AAClD,gBAAeA,KAAI;AACnB,EAAAC,eAAcD,KAAI;AAClB,EAAAC,eAAeD,KAAI;AACnB,EAAAC,eAAaD,KAAI;AACjB,EAAAC,eAAiBD,KAAI;AAGrB,sBAAoB;AACtB;AAWO,IAAM,eAAe,OAAO;AAAA,EACjC,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AAAA,EACP,WAAW;AAAA,EACX,WAAW;AAAA;AAAA,EAEX,QAAQ;AACV,CAAC;;;ApBhBD,2BAA2B,kBAAkB;AAQ7C,IAAME,aAAYC,MAAK,QAAQC,eAAc,YAAY,GAAG,CAAC;AAatD,SAAS,mBAAmB,UAA+B,CAAC,GAAiB;AAClF,QAAM,OAAO,QAAQ,QAAQ;AAG7B,MAAI,QAAQ,SAAS;AACnB,eAAW,IAAI;AAAA,EACjB;AAGA,QAAM,gBAAgB,IAAI,mBAAmB;AAC7C,MAAI,oBAAyC;AAE7C,gBAAc,GAAG,gBAAgB,CAAC,EAAE,IAAI,KAAK,MAAM;AACjD,UAAM,UAAU,sBAAsB,EAAE,KAAK,IAAI,GAAG;AAAA,EACtD,CAAC;AACD,gBAAc,GAAG,kBAAkB,CAAC,EAAE,IAAI,KAAK,MAAM;AACnD,UAAM,UAAU,mBAAmB,EAAE,KAAK,IAAI,GAAG;AAAA,EACnD,CAAC;AACD,gBAAc,GAAG,kBAAkB,CAAC,EAAE,GAAG,MAAM;AAC7C,UAAM,UAAU,mBAAmB,EAAE,EAAE;AAAA,EACzC,CAAC;AACD,gBAAc,GAAG,gBAAgB,CAAC,EAAE,WAAW,MAAM,MAAM;AACzD,YAAQ,MAAM,mBAAmB,SAAS,KAAK,MAAM,OAAO;AAAA,EAC9D,CAAC;AAGD,QAAM,aAAa,iBAAiB;AAGpC,oBAAkB,UAAU;AAG5B,QAAM,MAAM,QAAQ;AACpB,MAAI,IAAI,QAAQ,KAAK,CAAC;AAGtB,QAAM,aAAaD,MAAK,KAAKD,YAAW,MAAM,QAAQ;AACtD,MAAI,IAAI,QAAQ,OAAO,UAAU,CAAC;AAGlC,MAAI,IAAI,SAAS,wBAAwB,EAAE,QAAQ,aAAa,CAAC,CAAC;AAGlE,MAAI,IAAI,WAAW,CAAC,MAAM,QAAQ,IAAI,KAAK,EAAE,QAAQ,KAAK,CAAC,CAAC;AAI5D,MAAI,IAAI,aAAa,CAAC,MAAM,QAAQ;AAClC,QAAI,SAASC,MAAK,KAAK,YAAY,YAAY,CAAC;AAAA,EAClD,CAAC;AAGD,QAAM,SAAS,aAAa,GAAG;AAG/B,QAAM,MAAM,IAAI,gBAAgB,EAAE,QAAQ,MAAM,QAAQ,CAAC;AACzD,kBAAgB,EAAE,KAAK,QAAQ,aAAa,CAAC;AAE7C,SAAO;AAAA,IACL,OAAO,YAAY;AAEjB,YAAM,YAAY;AAGlB,0BAAoB,aAAa,aAAa;AAE9C,aAAO,IAAI,QAAQ,CAACE,UAAS,WAAW;AACtC,eAAO,KAAK,SAAS,CAAC,QAA+B;AACnD,cAAI,IAAI,SAAS,cAAc;AAC7B,mBAAO,IAAI,MAAM,QAAQ,IAAI,qEAAqE,CAAC;AAAA,UACrG,OAAO;AACL,mBAAO,GAAG;AAAA,UACZ;AAAA,QACF,CAAC;AAED,eAAO,OAAO,MAAM,MAAM;AACxB,gBAAM,MAAM,oBAAoB,IAAI;AACpC,gBAAM,UAAU,cAAc,GAAG,EAAE;AACnC,kBAAQ,UAAU,GAAG;AACrB,UAAAA,SAAQ;AAAA,QACV,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAAA,IAEA,MAAM,YAAY;AAChB,YAAM,UAAU,kBAAkB;AAClC,0BAAoB;AACpB,UAAI,MAAM;AACV,YAAMC,YAAW,QAAQ;AACzB,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AACF;;;AD5HA,IAAM,UAAU;AAGhB,IAAM,QAAQ;AACd,IAAM,QAAQ;AACd,IAAM,MAAM;AACZ,IAAM,QAAQ,CAACC,UAAiB,GAAG,KAAK,GAAGA,KAAI,GAAG,KAAK;AACvD,IAAM,MAAM,CAACA,UAAiB,GAAG,GAAG,GAAGA,KAAI,GAAG,KAAK;AAEnD,SAAS,WAAmB;AAC1B,QAAM,aAAa,kBAAkB;AACrC,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACtD,QAAI,8BAA8B,KAAK,IAAI,EAAG;AAC9C,eAAW,QAAQ,SAAS,CAAC,GAAG;AAC9B,UAAI,KAAK,WAAW,UAAU,CAAC,KAAK,UAAU;AAC5C,eAAO,KAAK;AAAA,MACd;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAQA,eAAe,aAAa,SAAuB;AACjD,QAAM,OAAO,SAAS,QAAQ,MAAM,EAAE;AACtC,QAAM,UAAU,QAAQ;AAExB,QAAM,IAAI,UAAU,OAAS,UAAQ;AACrC,QAAMC,OAAM,CAAC,QAAgB,WAAW,QAAQ,IAAI,GAAG;AAEvD,MAAI,CAAC,SAAS;AACZ,IAAE,QAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,IAAI,IAAI,OAAO,EAAE,CAAC,EAAE;AAAA,EACpD,OAAO;AACL,IAAAA,KAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,IAAI,IAAI,OAAO,EAAE,CAAC,EAAE;AAAA,EAChD;AAEA,MAAI,EAAG,GAAE,MAAM,oBAAoB;AAAA,MAC9B,CAAAA,KAAI,oBAAoB;AAE7B,QAAM,SAAS,mBAAmB;AAAA,IAChC;AAAA,IACA;AAAA,IACA,SAAS,CAAC,QAAQ;AAChB,UAAI,EAAG,GAAE,KAAK,OAAO;AAErB,YAAM,QAAQ,SAAS;AACvB,YAAM,SAAS,UAAU,KAAK,IAAI,IAAI;AAEtC,UAAI,SAAS;AACX,QAAAA,KAAI;AAAA,EAAK,MAAM,MAAM,CAAC,EAAE;AACxB,QAAAA,KAAI,IAAI,wBAAwB,CAAC;AACjC,QAAAA,KAAI;AAAA,EAAK,IAAI,sBAAsB,CAAC;AAAA,CAAI;AAAA,MAC1C,OAAO;AACL,QAAE,MAAI,QAAQ,GAAG,MAAM,MAAM,CAAC,EAAE;AAChC,QAAE,MAAI,QAAQ,IAAI,wBAAwB,CAAC;AAC3C,QAAE,QAAM,IAAI,sBAAsB,CAAC;AAAA,MACrC;AAGA,UAAI,QAAQ,MAAM;AAChB,cAAM,cACJ,QAAQ,aAAa,WAAW,SAAS,QAAQ,aAAa,UAAU,UAAU;AACpF,cAAM,aAAa,CAAC,GAAG,GAAG,EAAE,OAAO,UAAU,UAAU,KAAK,CAAC,EAAE,MAAM;AAAA,MACvE;AAAA,IACF;AAAA,EACF,CAAC;AAED,MAAI;AACF,UAAM,OAAO,MAAM;AAAA,EACrB,SAAS,KAAK;AACZ,QAAI,EAAG,GAAE,KAAK,QAAQ;AACtB,IAAE,MAAI,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAC5D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,WAAW,YAAY;AAC3B,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,IAAI,aAAa,CAAC;AAC9B,UAAM,OAAO,KAAK;AAClB,YAAQ,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,IAAI,SAAS,CAAC,EAAE;AAClD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,GAAG,WAAW,QAAQ;AAC9B,UAAQ,GAAG,UAAU,QAAQ;AAC/B;AAEA,QACG,KAAK,QAAQ,EACb,YAAY,GAAG,MAAM,QAAQ,CAAC,0DAA0D,EACxF,QAAQ,OAAO,EACf,OAAO,qBAAqB,eAAe,MAAM,EACjD,OAAO,aAAa,kCAAkC,EACtD,OAAO,iBAAiB,sBAAsB,KAAK,EACnD,OAAO,YAAY;AAEtB,QAAQ,MAAM;","names":["path","fileURLToPath","muxManager","process","path","os","fs","fs","path","relative","randomUUID","path","fs","eq","fs","path","stat","muxManager","path","eq","config","randomUUID","fs","randomUUID","eq","path","eq","p","streamConfigs","randomUUID","z","randomUUID","eq","amux","setAmuxBridge","z","eq","randomUUID","z","eq","eq","amux","setAmuxBridge","z","z","amux","setAmuxBridge","z","z","eq","amux","setAmuxBridge","paneInput","z","getStreamIdForPane","eq","observable","chokidar","path","os","fs","EventEmitter","build","fs","path","EventEmitter","ensureDir","chokidar","relative","observable","amux","setAmuxBridge","__dirname","path","fileURLToPath","resolve","muxManager","text","log"]}