theokit 0.43.6 → 0.43.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/dist/{actions-virtual-module-N7GKUS3D.js → actions-virtual-module-HG66SZ7T.js} +8 -8
- package/dist/actions-virtual-module-HG66SZ7T.js.map +1 -0
- package/dist/{actions-virtual-module-LD3YKWIX.js → actions-virtual-module-RSFRPJQZ.js} +7 -7
- package/dist/actions-virtual-module-RSFRPJQZ.js.map +1 -0
- package/dist/{add-W6FNTAFS.js → add-3VLFUPF4.js} +1 -1
- package/dist/add-3VLFUPF4.js.map +1 -0
- package/dist/{agent-U35G3WNE.js → agent-OXRRKB55.js} +5 -5
- package/dist/{agents-typed-client-NJ73Z6XY.js → agents-typed-client-X56CQ6FX.js} +1 -1
- package/dist/agents-typed-client-X56CQ6FX.js.map +1 -0
- package/dist/{agents-typed-client-CHMVW7MK.js → agents-typed-client-ZP7BKJB3.js} +1 -1
- package/dist/agents-typed-client-ZP7BKJB3.js.map +1 -0
- package/dist/{app-typed-client-6YZRDAPY.js → app-typed-client-GDF2OMJ2.js} +8 -8
- package/dist/app-typed-client-GDF2OMJ2.js.map +1 -0
- package/dist/{app-typed-client-V77SVU2O.js → app-typed-client-USLAMN7X.js} +7 -7
- package/dist/app-typed-client-USLAMN7X.js.map +1 -0
- package/dist/{aws-lambda-7GSCNLPY.js → aws-lambda-473QCOL6.js} +3 -3
- package/dist/{body-parser-web-MUWBKZ3F.js → body-parser-web-NNEJGX6Y.js} +1 -1
- package/dist/body-parser-web-NNEJGX6Y.js.map +1 -0
- package/dist/{body-parser-web-FV5HWCY3.js → body-parser-web-TIOTXPDW.js} +1 -1
- package/dist/body-parser-web-TIOTXPDW.js.map +1 -0
- package/dist/broadcast-LUMOJIJT.js +0 -0
- package/dist/{build-BYLQZJT2.js → build-MQHIJROR.js} +11 -11
- package/dist/{build-BYLQZJT2.js.map → build-MQHIJROR.js.map} +1 -1
- package/dist/{build-request-body-preview-EOP2Y4F3.js → build-request-body-preview-FVBQ7LCE.js} +1 -1
- package/dist/build-request-body-preview-FVBQ7LCE.js.map +1 -0
- package/dist/{build-request-body-preview-QMWD2IXK.js → build-request-body-preview-XPZ2GYMG.js} +1 -1
- package/dist/build-request-body-preview-XPZ2GYMG.js.map +1 -0
- package/dist/{bun-KP2KES6S.js → bun-OQUCL3XW.js} +3 -3
- package/dist/{check-PD2FTKMM.js → check-45NKUVSQ.js} +1 -1
- package/dist/check-45NKUVSQ.js.map +1 -0
- package/dist/{chunk-FRUEDJFX.js → chunk-226KMIGZ.js} +3 -3
- package/dist/{chunk-FRUEDJFX.js.map → chunk-226KMIGZ.js.map} +1 -1
- package/dist/{chunk-U3NTEK46.js → chunk-26ECIX74.js} +2 -2
- package/dist/chunk-2CVV6CNN.js +0 -0
- package/dist/{chunk-FEDSPOY6.js → chunk-2WH6SD3C.js} +6 -6
- package/dist/chunk-2WH6SD3C.js.map +1 -0
- package/dist/{chunk-JAIKGP3Q.js → chunk-47VNWTL4.js} +1 -1
- package/dist/chunk-47VNWTL4.js.map +1 -0
- package/dist/{chunk-D7ZH7DTG.js → chunk-4B2ZMX45.js} +1 -1
- package/dist/chunk-4B2ZMX45.js.map +1 -0
- package/dist/{chunk-IHJZPQEF.js → chunk-4HAU7AJM.js} +3 -3
- package/dist/chunk-4HAU7AJM.js.map +1 -0
- package/dist/{chunk-IPC5UREF.js → chunk-575PAX5L.js} +17 -17
- package/dist/chunk-575PAX5L.js.map +1 -0
- package/dist/chunk-5ODOE6EF.js +0 -0
- package/dist/{chunk-X2VVCJ4V.js → chunk-65EFIUDD.js} +1 -1
- package/dist/chunk-65EFIUDD.js.map +1 -0
- package/dist/{chunk-GY5Q27BJ.js → chunk-6FK7FKY6.js} +1 -1
- package/dist/{chunk-GY5Q27BJ.js.map → chunk-6FK7FKY6.js.map} +1 -1
- package/dist/{chunk-GSO77FSM.js → chunk-6OXCZMW3.js} +45 -47
- package/dist/chunk-6OXCZMW3.js.map +1 -0
- package/dist/{chunk-P37RZRFV.js → chunk-A7JBF5FO.js} +1 -1
- package/dist/chunk-A7JBF5FO.js.map +1 -0
- package/dist/{chunk-AFVTEAES.js → chunk-CJNMJUHE.js} +2 -2
- package/dist/{chunk-AXVFVMLM.js → chunk-DJFMAWH5.js} +8 -4
- package/dist/chunk-DJFMAWH5.js.map +1 -0
- package/dist/{chunk-2ZX4J4SX.js → chunk-DQVBL2G4.js} +58 -56
- package/dist/chunk-DQVBL2G4.js.map +1 -0
- package/dist/{chunk-GW5H4KB4.js → chunk-FX72VHAE.js} +3 -3
- package/dist/chunk-GDN3PXFH.js +0 -0
- package/dist/chunk-GEQJAFSV.js +0 -0
- package/dist/{chunk-5AVPWHUE.js → chunk-HGUZWG2C.js} +7 -4
- package/dist/chunk-HGUZWG2C.js.map +1 -0
- package/dist/chunk-HGZL5EOI.js +0 -0
- package/dist/chunk-HNBWZKIQ.js +0 -0
- package/dist/{chunk-UNLG36Z5.js → chunk-IE6C4KZX.js} +10 -5
- package/dist/chunk-IE6C4KZX.js.map +1 -0
- package/dist/chunk-IEES3CHD.js +0 -0
- package/dist/{chunk-QWBXUZAX.js → chunk-JIL74SFK.js} +4 -4
- package/dist/chunk-JIL74SFK.js.map +1 -0
- package/dist/{chunk-KI7OWQUX.js → chunk-L2S2R3TI.js} +63 -20
- package/dist/chunk-L2S2R3TI.js.map +1 -0
- package/dist/{chunk-L4GCEMNW.js → chunk-LNVMHQ2Z.js} +2 -2
- package/dist/{chunk-SPJNVWOK.js → chunk-N2D5AVRR.js} +2 -3
- package/dist/chunk-N2D5AVRR.js.map +1 -0
- package/dist/{chunk-UO7WS32S.js → chunk-OI6DK6ZJ.js} +3 -3
- package/dist/chunk-OI6DK6ZJ.js.map +1 -0
- package/dist/{chunk-RMU7EBRO.js → chunk-OP7QCTR5.js} +2 -2
- package/dist/{chunk-RMU7EBRO.js.map → chunk-OP7QCTR5.js.map} +1 -1
- package/dist/{chunk-GUUWDMR2.js → chunk-OVHW23YC.js} +2 -2
- package/dist/{chunk-NQRNDPZJ.js → chunk-OXCALO3W.js} +3 -3
- package/dist/{chunk-45C3WUQ7.js → chunk-QPVXGC7O.js} +1 -1
- package/dist/chunk-QPVXGC7O.js.map +1 -0
- package/dist/{chunk-FOZIR3TG.js → chunk-SMP2T335.js} +2 -2
- package/dist/{chunk-M6NMS5LR.js → chunk-TDNNBLGW.js} +1 -1
- package/dist/chunk-TDNNBLGW.js.map +1 -0
- package/dist/{chunk-WFNLNIJX.js → chunk-VPISAMXU.js} +2 -2
- package/dist/{chunk-5PU65T5W.js → chunk-XZ6B2Y2R.js} +1 -1
- package/dist/chunk-XZ6B2Y2R.js.map +1 -0
- package/dist/cli/index.js +15 -15
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +20 -25
- package/dist/client/index.js.map +1 -1
- package/dist/{cloudflare-C6E5SPAE.js → cloudflare-4YT5CK3P.js} +3 -3
- package/dist/configure-agent-registry-ZOBVU3MV.js +0 -0
- package/dist/{controller-swc-transform-URELVCBM.js → controller-swc-transform-JJRMTSDY.js} +1 -1
- package/dist/controller-swc-transform-JJRMTSDY.js.map +1 -0
- package/dist/{controller-swc-transform-XV3ETSE3.js → controller-swc-transform-LUJ4VAZJ.js} +1 -1
- package/dist/controller-swc-transform-LUJ4VAZJ.js.map +1 -0
- package/dist/{db-3UNAMSFK.js → db-IVVCQE5Z.js} +1 -2
- package/dist/db-IVVCQE5Z.js.map +1 -0
- package/dist/{deno-deploy-RFZN56X4.js → deno-deploy-YYN6BNLF.js} +3 -3
- package/dist/{dev-PS2NGT6I.js → dev-WQ4LWCAW.js} +13 -13
- package/dist/{dev-emit-2DL3MCLM.js → dev-emit-HLGJK3PP.js} +3 -3
- package/dist/dev-emit-HLGJK3PP.js.map +1 -0
- package/dist/{dev-emit-XVTJXZGA.js → dev-emit-J7V6GWSK.js} +6 -6
- package/dist/devtools/entry.js +43 -15
- package/dist/devtools/entry.js.map +1 -1
- package/dist/{dispatcher-63LBXYLE.js → dispatcher-DLKIXYNO.js} +2 -2
- package/dist/{dispatcher-EJHL6JMJ.js → dispatcher-KMZBGMM5.js} +1 -1
- package/dist/dispatcher-KMZBGMM5.js.map +1 -0
- package/dist/docker-LZZB4D5E.js +0 -0
- package/dist/{generate-5X4LG77M.js → generate-GXWPUVS7.js} +4 -5
- package/dist/generate-GXWPUVS7.js.map +1 -0
- package/dist/index.js +9 -9
- package/dist/{info-2OOXFTJX.js → info-75U6GCMD.js} +4 -4
- package/dist/info-75U6GCMD.js.map +1 -0
- package/dist/{internal-api-LFW7R65K.js → internal-api-DV3H5NNV.js} +7 -9
- package/dist/{internal-api-FBFV265J.js → internal-api-JFORKYLR.js} +8 -10
- package/dist/{load-config-3EAQTXPH.js → load-config-XP7NSSA7.js} +4 -4
- package/dist/{mcp-ML4QK5ON.js → mcp-FF3NTCHB.js} +6 -6
- package/dist/mcp-FF3NTCHB.js.map +1 -0
- package/dist/{netlify-PMLHVPN4.js → netlify-2WZUQYI3.js} +3 -3
- package/dist/node-CMAYKDCM.js +10 -0
- package/dist/{openapi-2HVGJMSN.js → openapi-ZPXYRAM2.js} +9 -9
- package/dist/openapi-ZPXYRAM2.js.map +1 -0
- package/dist/registry-72YH7ZJM.js +23 -0
- package/dist/registry-72YH7ZJM.js.map +1 -0
- package/dist/{router-TLEAOFID.js → router-6MAACS25.js} +1 -2
- package/dist/router-6MAACS25.js.map +1 -0
- package/dist/{routes-XNS3UM3B.js → routes-ZVDKABXZ.js} +6 -6
- package/dist/scan-7MJC6PYU.js +0 -0
- package/dist/schema-FBOTN46F.js +22 -0
- package/dist/server/agent/index.js +1 -1
- package/dist/server/cost/index.js +1 -1
- package/dist/server/cron/index.js +2 -2
- package/dist/server/http/index.js +3 -3
- package/dist/server/index.js +11 -11
- package/dist/server/jobs/index.js +3 -3
- package/dist/server/observability/index.d.ts +1 -38
- package/dist/server/observability/index.js +2 -2
- package/dist/server/scan/index.js +2 -2
- package/dist/server-error-to-envelope-UUXDSLAZ.js +0 -0
- package/dist/{server-routes-hmr-VZXOP5YT.js → server-routes-hmr-4W5L2MKN.js} +1 -1
- package/dist/server-routes-hmr-4W5L2MKN.js.map +1 -0
- package/dist/{server-routes-hmr-PBHSKCQJ.js → server-routes-hmr-RI7SYNT2.js} +1 -1
- package/dist/server-routes-hmr-RI7SYNT2.js.map +1 -0
- package/dist/{services-json-Y3XODNB5.js → services-json-7ZXJ4CIS.js} +1 -1
- package/dist/services-json-7ZXJ4CIS.js.map +1 -0
- package/dist/{services-typed-client-IETY2SAK.js → services-typed-client-AU6DKXAO.js} +2 -2
- package/dist/services-typed-client-AU6DKXAO.js.map +1 -0
- package/dist/{services-typed-client-32KMTTXR.js → services-typed-client-EO4RFNTZ.js} +2 -2
- package/dist/services-typed-client-EO4RFNTZ.js.map +1 -0
- package/dist/{start-YLR2SFHU.js → start-2U3FUCJX.js} +12 -12
- package/dist/start-2U3FUCJX.js.map +1 -0
- package/dist/{static-MB2CD5Y3.js → static-25H5K42R.js} +3 -3
- package/dist/{static-MB2CD5Y3.js.map → static-25H5K42R.js.map} +1 -1
- package/dist/storage-manager-ZSQFLEYT.js +0 -0
- package/dist/{theo-cloud-DQRP6S6M.js → theo-cloud-JL2KXHIS.js} +2 -2
- package/dist/{upgrade-readiness-ACGW44JC.js → upgrade-readiness-77P6VNB4.js} +1 -1
- package/dist/upgrade-readiness-77P6VNB4.js.map +1 -0
- package/dist/{vercel-J6G7ZHYQ.js → vercel-FP3C6LN6.js} +3 -3
- package/dist/vite-plugin/index.js +9 -9
- package/dist/{vite-plugin-6VVU6PPC.js → vite-plugin-D2NTPZNC.js} +13 -13
- package/package.json +10 -13
- package/dist/actions-virtual-module-LD3YKWIX.js.map +0 -1
- package/dist/actions-virtual-module-N7GKUS3D.js.map +0 -1
- package/dist/add-W6FNTAFS.js.map +0 -1
- package/dist/agents-typed-client-CHMVW7MK.js.map +0 -1
- package/dist/agents-typed-client-NJ73Z6XY.js.map +0 -1
- package/dist/app-typed-client-6YZRDAPY.js.map +0 -1
- package/dist/app-typed-client-V77SVU2O.js.map +0 -1
- package/dist/body-parser-web-FV5HWCY3.js.map +0 -1
- package/dist/body-parser-web-MUWBKZ3F.js.map +0 -1
- package/dist/build-request-body-preview-EOP2Y4F3.js.map +0 -1
- package/dist/build-request-body-preview-QMWD2IXK.js.map +0 -1
- package/dist/check-PD2FTKMM.js.map +0 -1
- package/dist/chunk-2ZX4J4SX.js.map +0 -1
- package/dist/chunk-45C3WUQ7.js.map +0 -1
- package/dist/chunk-5AVPWHUE.js.map +0 -1
- package/dist/chunk-5PU65T5W.js.map +0 -1
- package/dist/chunk-AXVFVMLM.js.map +0 -1
- package/dist/chunk-D7ZH7DTG.js.map +0 -1
- package/dist/chunk-FEDSPOY6.js.map +0 -1
- package/dist/chunk-GSO77FSM.js.map +0 -1
- package/dist/chunk-IHJZPQEF.js.map +0 -1
- package/dist/chunk-IPC5UREF.js.map +0 -1
- package/dist/chunk-JAIKGP3Q.js.map +0 -1
- package/dist/chunk-KI7OWQUX.js.map +0 -1
- package/dist/chunk-M6NMS5LR.js.map +0 -1
- package/dist/chunk-P37RZRFV.js.map +0 -1
- package/dist/chunk-QWBXUZAX.js.map +0 -1
- package/dist/chunk-SPJNVWOK.js.map +0 -1
- package/dist/chunk-UNLG36Z5.js.map +0 -1
- package/dist/chunk-UO7WS32S.js.map +0 -1
- package/dist/chunk-X2VVCJ4V.js.map +0 -1
- package/dist/controller-swc-transform-URELVCBM.js.map +0 -1
- package/dist/controller-swc-transform-XV3ETSE3.js.map +0 -1
- package/dist/db-3UNAMSFK.js.map +0 -1
- package/dist/dev-emit-2DL3MCLM.js.map +0 -1
- package/dist/dispatcher-EJHL6JMJ.js.map +0 -1
- package/dist/generate-5X4LG77M.js.map +0 -1
- package/dist/info-2OOXFTJX.js.map +0 -1
- package/dist/mcp-ML4QK5ON.js.map +0 -1
- package/dist/node-BPJ3Z4DT.js +0 -10
- package/dist/openapi-2HVGJMSN.js.map +0 -1
- package/dist/registry-FKPH7XEL.js +0 -24
- package/dist/registry-FKPH7XEL.js.map +0 -1
- package/dist/router-TLEAOFID.js.map +0 -1
- package/dist/schema-LYOLNHZ7.js +0 -30
- package/dist/server-routes-hmr-PBHSKCQJ.js.map +0 -1
- package/dist/server-routes-hmr-VZXOP5YT.js.map +0 -1
- package/dist/services-json-Y3XODNB5.js.map +0 -1
- package/dist/services-typed-client-32KMTTXR.js.map +0 -1
- package/dist/services-typed-client-IETY2SAK.js.map +0 -1
- package/dist/start-YLR2SFHU.js.map +0 -1
- package/dist/upgrade-readiness-ACGW44JC.js.map +0 -1
- /package/dist/{agent-U35G3WNE.js.map → agent-OXRRKB55.js.map} +0 -0
- /package/dist/{aws-lambda-7GSCNLPY.js.map → aws-lambda-473QCOL6.js.map} +0 -0
- /package/dist/{bun-KP2KES6S.js.map → bun-OQUCL3XW.js.map} +0 -0
- /package/dist/{chunk-U3NTEK46.js.map → chunk-26ECIX74.js.map} +0 -0
- /package/dist/{chunk-AFVTEAES.js.map → chunk-CJNMJUHE.js.map} +0 -0
- /package/dist/{chunk-GW5H4KB4.js.map → chunk-FX72VHAE.js.map} +0 -0
- /package/dist/{chunk-L4GCEMNW.js.map → chunk-LNVMHQ2Z.js.map} +0 -0
- /package/dist/{chunk-GUUWDMR2.js.map → chunk-OVHW23YC.js.map} +0 -0
- /package/dist/{chunk-NQRNDPZJ.js.map → chunk-OXCALO3W.js.map} +0 -0
- /package/dist/{chunk-FOZIR3TG.js.map → chunk-SMP2T335.js.map} +0 -0
- /package/dist/{chunk-WFNLNIJX.js.map → chunk-VPISAMXU.js.map} +0 -0
- /package/dist/{cloudflare-C6E5SPAE.js.map → cloudflare-4YT5CK3P.js.map} +0 -0
- /package/dist/{deno-deploy-RFZN56X4.js.map → deno-deploy-YYN6BNLF.js.map} +0 -0
- /package/dist/{dev-PS2NGT6I.js.map → dev-WQ4LWCAW.js.map} +0 -0
- /package/dist/{dev-emit-XVTJXZGA.js.map → dev-emit-J7V6GWSK.js.map} +0 -0
- /package/dist/{dispatcher-63LBXYLE.js.map → dispatcher-DLKIXYNO.js.map} +0 -0
- /package/dist/{internal-api-FBFV265J.js.map → internal-api-DV3H5NNV.js.map} +0 -0
- /package/dist/{internal-api-LFW7R65K.js.map → internal-api-JFORKYLR.js.map} +0 -0
- /package/dist/{load-config-3EAQTXPH.js.map → load-config-XP7NSSA7.js.map} +0 -0
- /package/dist/{netlify-PMLHVPN4.js.map → netlify-2WZUQYI3.js.map} +0 -0
- /package/dist/{node-BPJ3Z4DT.js.map → node-CMAYKDCM.js.map} +0 -0
- /package/dist/{routes-XNS3UM3B.js.map → routes-ZVDKABXZ.js.map} +0 -0
- /package/dist/{schema-LYOLNHZ7.js.map → schema-FBOTN46F.js.map} +0 -0
- /package/dist/{theo-cloud-DQRP6S6M.js.map → theo-cloud-JL2KXHIS.js.map} +0 -0
- /package/dist/{vercel-J6G7ZHYQ.js.map → vercel-FP3C6LN6.js.map} +0 -0
- /package/dist/{vite-plugin-6VVU6PPC.js.map → vite-plugin-D2NTPZNC.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server/scan/action-scan.ts","../src/server/scan/agent-scan.ts","../src/server/scan/match.ts","../src/server/scan/scan.ts","../src/server/scan/detect-http-methods.ts","../src/server/scan/errors.ts","../src/server/scan/ws-scan.ts","../src/server/scan/manifest.ts"],"sourcesContent":["/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time scanner: walks `serverDir/actions/` derived from cwd.\n * No HTTP input ever reaches these fs calls.\n */\nimport { existsSync, readFileSync, statSync } from 'node:fs'\nimport { extname, join, relative } from 'node:path'\n\nimport { walkSourceFiles } from '../_internal/scan-walker.js'\n\nexport interface ActionNode {\n filePath: string\n actionPath: string\n}\n\n/**\n * Enriched manifest entry per plan g3-server-actions-and-useaction v1.2\n * § Phase 1 / T1.4 + ADR D4. Consumed by virtual module `@theo/actions`\n * (T3.1) and G4 devtools \"Actions\" tab (T5.1).\n */\nexport interface ActionManifestEntry {\n name: string\n filePath: string\n urlPath: string\n accept: 'form' | 'json'\n hasInput: boolean\n /**\n * P#4 plugin-forms shared-schema convention (per plan p4-plugin-forms v1.1 T1.1).\n * When present, points to an isomorphic schema file at\n * `<serverDir>/actions/schemas/<basename>.ts` exporting `export const schema = z.object(...)`.\n * Virtual module emits `import {schema} from '<schemaFilePath>'` + attaches as\n * `actions.X.__zodSchema` so client-side <TheoForm> can drive zodResolver.\n * Undefined when convention not followed (graceful degrade — TheoForm still\n * works via explicit `schema={...}` prop escape hatch).\n */\n schemaFilePath?: string\n}\n\n/**\n * EC-2: structured error for scan-time defects (name collision, reserved\n * identifier, etc.). Throw at scan time to fail loud — silent shadowing is\n * a security/correctness footgun.\n */\nexport class ActionScanError extends Error {\n readonly code: 'NAME_COLLISION' | 'RESERVED_NAME'\n readonly conflictingPaths: readonly string[]\n\n constructor(\n code: 'NAME_COLLISION' | 'RESERVED_NAME',\n message: string,\n conflictingPaths: readonly string[],\n ) {\n super(message)\n // T4.1 fix: identify class by name so serverErrorToEnvelope boundary\n // translator can route via class-name lookup (without this, runtime\n // `err.name` defaults to 'Error' and the meta.name diagnostic is wrong).\n this.name = 'ActionScanError'\n this.code = code\n this.conflictingPaths = conflictingPaths\n }\n}\n\nconst ACTION_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx'])\nconst TEST_FILE_RE = /\\.(test|spec)\\.(ts|tsx|js|jsx)$/\nconst RESERVED_NAMES = new Set(['index', 'constructor', '__proto__', 'prototype', 'hasOwnProperty'])\n\n/**\n * Backward-compatible: original simple-shape scanner used by existing\n * consumers. Preserved verbatim; new consumers should call\n * `scanServerActionsEnriched`.\n */\nexport function scanServerActions(serverDir: string): ActionNode[] {\n const actionsDir = join(serverDir, 'actions')\n if (!existsSync(actionsDir) || !statSync(actionsDir).isDirectory()) {\n return []\n }\n\n const results: ActionNode[] = []\n walkSourceFiles(actionsDir, { extensions: ACTION_EXTENSIONS }, (absPath) => {\n if (TEST_FILE_RE.test(absPath)) return\n let rel = relative(actionsDir, absPath)\n rel = rel.replace(/\\\\/g, '/')\n rel = rel.slice(0, -extname(rel).length)\n results.push({\n filePath: absPath,\n actionPath: rel,\n })\n })\n return results\n}\n\n/**\n * Enriched scan: light AST detection of `accept: 'form'|'json'` + `input:`\n * presence via regex-after-comment-stripping (EC-9). Throws ActionScanError\n * on file/dir name collision (EC-2) or reserved JS identifier names.\n *\n * Output `ActionManifestEntry[]` is sorted by `name` for deterministic\n * `.theokit/actions-manifest.json` emission.\n */\nexport function scanServerActionsEnriched(serverDir: string): ActionManifestEntry[] {\n const actionsDir = join(serverDir, 'actions')\n if (!existsSync(actionsDir) || !statSync(actionsDir).isDirectory()) {\n return []\n }\n\n const seenNames = new Set<string>()\n const entries: ActionManifestEntry[] = []\n\n // Collect first; collision-check after the full walk.\n walkSourceFiles(actionsDir, { extensions: ACTION_EXTENSIONS }, (absPath) => {\n if (TEST_FILE_RE.test(absPath)) return\n const rel = relative(actionsDir, absPath).replace(/\\\\/g, '/')\n // P#4 plugin-forms — `schemas/` subdir holds isomorphic zod schemas\n // for the shared-schema convention (T1.1). NOT executable actions; skip.\n if (rel.startsWith('schemas/')) return\n const name = rel.slice(0, -extname(rel).length)\n\n const basename = name.includes('/') ? (name.split('/').pop() ?? name) : name\n if (RESERVED_NAMES.has(basename)) {\n throw new ActionScanError(\n 'RESERVED_NAME',\n `Reserved JS identifier \"${basename}\" cannot be an action name (${absPath})`,\n [absPath],\n )\n }\n // File-level collision (one file appearing twice) is impossible via the\n // walker; per-export collision check happens inside the export loop below.\n const source = readFileSync(absPath, 'utf8')\n const stripped = stripComments(source)\n const accept = /\\baccept\\s*:\\s*['\"]form['\"]/.test(stripped) ? 'form' : 'json'\n const hasInput = /\\binput\\s*:\\s*z\\./.test(stripped) || /\\binput\\s*:\\s*\\w+\\(/.test(stripped)\n\n // T7.1 wire fix — extract exports so the urlPath includes the second\n // segment required by action-middleware (`/api/__actions/<file>/<export>`).\n // Each named action export becomes its own manifest entry.\n // Proxy key on the EXPORT name (so consumers write `actions.saveMemory(input)`).\n // URL keeps the runtime 2-segment shape `/api/__actions/<file>/<export>`\n // expected by action-middleware. Cross-file export collisions become a\n // scan error to surface the ambiguity early.\n const exportNames = extractActionExportNames(stripped)\n // P#4 plugin-forms shared-schema convention: check for\n // `<actionsDir>/schemas/<basename>.ts` (or .tsx/.js/.jsx).\n // Skip when actions live in subdirs (`schemas/` is flat by convention).\n const schemaFilePath = name.includes('/') ? undefined : detectSchemaFile(actionsDir, basename)\n for (const exportName of exportNames) {\n const proxyKey = exportName === 'default' ? name : exportName\n if (seenNames.has(proxyKey)) {\n throw new ActionScanError(\n 'NAME_COLLISION',\n `Duplicate action proxy key \"${proxyKey}\" (two files export the same name)`,\n [absPath],\n )\n }\n seenNames.add(proxyKey)\n const entry: ActionManifestEntry = {\n name: proxyKey,\n filePath: absPath,\n urlPath: `/api/__actions/${name}/${exportName}`,\n accept,\n hasInput,\n }\n if (schemaFilePath !== undefined) {\n entry.schemaFilePath = schemaFilePath\n }\n entries.push(entry)\n }\n })\n\n // EC-2: detect file vs dir collisions (e.g., foo.ts AND foo/bar.ts).\n // After walk completes, any name that has children prefixed `name/` triggers collision.\n for (const entry of entries) {\n const childPrefix = `${entry.name}/`\n const conflictingChild = entries.find((other) => other.name.startsWith(childPrefix))\n if (conflictingChild) {\n throw new ActionScanError(\n 'NAME_COLLISION',\n `Action \"${entry.name}\" conflicts with directory of same name containing \"${conflictingChild.name}\"`,\n [entry.filePath, conflictingChild.filePath],\n )\n }\n }\n\n entries.sort((a, b) => {\n if (a.name < b.name) return -1\n if (a.name > b.name) return 1\n return 0\n })\n return entries\n}\n\n/**\n * Strip JavaScript line + block comments from source. Simple state machine\n * (does not parse strings — false positives if a comment marker appears\n * inside a string literal, but that's an acceptable trade-off for v1 vs\n * full AST parse).\n */\n/**\n * Extract action export names via regex over comment-stripped source.\n * Matches `export const <name> = defineAction(...)`, `export default\n * defineAction(...)`, and `export function <name>(...)` forms. Returns\n * `['default']` when no named action exports are found (best-effort fallback\n * for default-export shapes the regex misses).\n */\nfunction extractActionExportNames(stripped: string): string[] {\n const names = new Set<string>()\n const namedRe = /\\bexport\\s+(?:const|let|var|function\\*?)\\s+([a-zA-Z_$][\\w$]*)\\s*[=(]/g\n let m: RegExpExecArray | null\n while ((m = namedRe.exec(stripped)) !== null) {\n const name = m[1]\n if (typeof name === 'string' && name.length > 0) names.add(name)\n }\n if (/\\bexport\\s+default\\s+defineAction\\b/.test(stripped)) {\n names.add('default')\n }\n if (names.size === 0) names.add('default')\n return [...names]\n}\n\n/**\n * P#4 plugin-forms shared-schema convention helper (per plan p4-plugin-forms v1.1 T1.1).\n * Returns the resolved path to `<actionsDir>/schemas/<basename>.<ext>` if it exists.\n * Tries `.ts`, `.tsx`, `.js`, `.jsx` in that order. Returns undefined when no match.\n */\nfunction detectSchemaFile(actionsDir: string, basename: string): string | undefined {\n const schemasDir = join(actionsDir, 'schemas')\n if (!existsSync(schemasDir)) return undefined\n for (const ext of ['.ts', '.tsx', '.js', '.jsx']) {\n const candidate = join(schemasDir, `${basename}${ext}`)\n if (existsSync(candidate)) return candidate\n }\n return undefined\n}\n\nfunction stripComments(source: string): string {\n let out = ''\n let i = 0\n while (i < source.length) {\n const ch = source[i]\n const next = source[i + 1]\n if (ch === '/' && next === '/') {\n // Line comment: skip until newline\n while (i < source.length && source[i] !== '\\n') i++\n continue\n }\n if (ch === '/' && next === '*') {\n // Block comment: skip until */\n i += 2\n while (i < source.length - 1 && !(source[i] === '*' && source[i + 1] === '/')) i++\n i += 2\n continue\n }\n out += ch\n i++\n }\n return out\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time scanner: walks `<projectRoot>/agents/` derived from cwd.\n * No HTTP input ever reaches these fs calls.\n */\nimport { existsSync, statSync } from 'node:fs'\nimport { extname, join, relative } from 'node:path'\n\nimport { walkSourceFiles } from '../_internal/scan-walker.js'\n\nconst AGENT_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx'])\n// Convention § 5: a co-located test file is not an agent.\nconst TEST_FILE = /\\.(test|spec)$/\n\n/**\n * Folder-semantic discovery (Eve-style \"file = identity\"): an agent may be a self-contained folder that\n * co-locates its composition — `agents/<name>/{index.ts, tools/, skills/, prompts/, lib/}`. Files INSIDE\n * these conventional sub-folders are that concern (a tool, a skill, a prompt, a helper), NOT a routed\n * agent, so the scanner skips any file whose path passes through one of them. Only `<name>.ts` or\n * `<name>/index.ts` is served at `/api/agents/<name>`. A flat file literally named `tools.ts` is still a\n * valid agent (the reserved names only apply to intermediate DIRECTORIES, never the agent file itself).\n */\nconst AGENT_SUBFOLDERS = new Set([\n 'tools',\n 'skills',\n 'prompts',\n 'lib',\n 'hooks',\n 'channels',\n 'connections',\n 'subagents',\n 'schedules',\n 'sandbox',\n 'workflows',\n 'evals',\n 'memory',\n])\n\n/**\n * A discovered agent file. `name` is the client-facing key; `agentPath` is the mounted\n * SSE route (M0/M1 `UIMessageStream`).\n */\nexport interface AgentNode {\n filePath: string\n agentPath: string\n name: string\n}\n\n/**\n * M2 — scan the TOP-LEVEL `agents/` convention (sibling of `server/`, per the LOCKED naming\n * decision). Mirrors `scanWebSocketRoutes`: one file → one endpoint, `index` stripped.\n */\nexport function scanAgents(projectRoot: string, agentsDirName = 'agents'): AgentNode[] {\n // `agentsDirName` (config `agentsDir`, default \"agents\") — the dir holding `<name>.ts` agent\n // definitions, relative to the project root. May be nested (e.g. \"core/agents\"). (#95 follow-up)\n const agentsDir = join(projectRoot, agentsDirName)\n if (!existsSync(agentsDir) || !statSync(agentsDir).isDirectory()) {\n return []\n }\n\n const results: AgentNode[] = []\n walkSourceFiles(agentsDir, { extensions: AGENT_EXTENSIONS }, (absPath) => {\n let rel = relative(agentsDir, absPath)\n rel = rel.replace(/\\\\/g, '/')\n rel = rel.slice(0, -extname(rel).length)\n if (TEST_FILE.test(rel)) return\n // Eve-style: a file living under a composition sub-folder (tools/, skills/, prompts/, …) is that\n // concern, not a routed agent. Check the intermediate DIRECTORIES only — the agent file itself may\n // be named anything.\n const dirs = rel.split('/').slice(0, -1)\n if (dirs.some((segment) => AGENT_SUBFOLDERS.has(segment))) return\n // Unlike routes/ws, an agent needs an explicit name — a bare `agents/index.ts`\n // (name `''` → `/api/agents/`) is nonsensical for a typed `useAgent(name)` binding.\n // `agents/foo/index.ts` still collapses to `foo` (a named nested agent).\n if (rel.endsWith('/index')) rel = rel.slice(0, -6)\n if (rel === 'index' || rel === '') return\n results.push({\n filePath: absPath,\n agentPath: `/api/agents/${rel}`,\n name: rel,\n })\n })\n return results\n}\n","export interface ServerRouteNode {\n filePath: string\n routePath: string\n paramNames: string[]\n pattern: RegExp\n /** HTTP methods (uppercase) the route file exports. Optional for backward\n * compatibility with manifests generated before G1. Empty array means the\n * file has no HTTP exports (util-only); undefined means \"not detected\". */\n methods?: string[]\n}\n\nexport function compilePattern(routePath: string): {\n pattern: RegExp\n paramNames: string[]\n} {\n const paramNames: string[] = []\n // Single pass: handle both catch-all (:...name) and regular (:name) params\n const regexStr = routePath.replace(/:(?:\\.\\.\\.)?([^/]+)/g, (match: string, name: string) => {\n paramNames.push(name)\n // Catch-all matches across slashes, regular matches single segment\n return match.startsWith(':...') ? '(.+)' : '([^/]+)'\n })\n // `regexStr` is derived from a developer-authored route path (build-time\n // input, not HTTP-controlled). The `security/detect-non-literal-regexp`\n // rule cannot see this constraint — disable narrowly.\n // eslint-disable-next-line security/detect-non-literal-regexp -- route pattern from build-time scan, never HTTP input\n return { pattern: new RegExp(`^${regexStr}$`), paramNames }\n}\n\nexport function matchRoute(\n url: string,\n routes: ServerRouteNode[],\n): { route: ServerRouteNode; params: Record<string, string> } | null {\n // Strip query string and trailing slash\n let path = url.split('?')[0]\n if (path.length > 1 && path.endsWith('/')) {\n path = path.slice(0, -1)\n }\n\n for (const route of routes) {\n const match = route.pattern.exec(path)\n if (match) {\n const params: Record<string, string> = {}\n route.paramNames.forEach((name, i) => {\n params[name] = match[i + 1]\n })\n return { route, params }\n }\n }\n return null\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time scanner: walks `serverDir/routes/` derived from cwd.\n * No HTTP input ever reaches these fs calls.\n */\nimport { existsSync, statSync } from 'node:fs'\nimport { basename, extname, join, relative } from 'node:path'\n\nimport { walkSourceFiles } from '../_internal/scan-walker.js'\n\nimport { detectExportedHttpMethods } from './detect-http-methods.js'\nimport { RouterConventionError } from './errors.js'\nimport { compilePattern, type ServerRouteNode } from './match.js'\n\nconst ROUTE_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx'])\n\n// EC-4: Co-located unit/spec tests must be silently skipped by the scanner,\n// BEFORE the dotted-basename check fires. Matches `*.test.ts|tsx|js|jsx`\n// and `*.spec.ts|tsx|js|jsx`.\nconst TEST_OR_SPEC_RE = /\\.(test|spec)\\.[jt]sx?$/\n\nfunction isTestOrSpecFile(filePath: string): boolean {\n return TEST_OR_SPEC_RE.test(basename(filePath))\n}\n\nfunction hasDotOutsideBrackets(segment: string): boolean {\n let depth = 0\n for (const ch of segment) {\n if (ch === '[') depth++\n else if (ch === ']') depth--\n else if (ch === '.' && depth === 0) return true\n }\n return false\n}\n\nfunction splitDottedSegmentOutsideBrackets(segment: string): string[] {\n const parts: string[] = []\n let current = ''\n let depth = 0\n for (const ch of segment) {\n if (ch === '[') {\n depth++\n current += ch\n } else if (ch === ']') {\n depth--\n current += ch\n } else if (ch === '.' && depth === 0) {\n if (current) parts.push(current)\n current = ''\n } else {\n current += ch\n }\n }\n if (current) parts.push(current)\n return parts\n}\n\nfunction buildDirectoryNestedSuggestion(filePath: string, routesDir: string): string {\n const rel = relative(routesDir, filePath).replace(/\\\\/g, '/')\n const ext = extname(rel)\n const withoutExt = rel.slice(0, -ext.length)\n const segments = withoutExt.split('/').flatMap(splitDottedSegmentOutsideBrackets)\n return `routes/${segments.join('/')}${ext}`\n}\n\nfunction assertNoDottedSegment(filePath: string, routesDir: string): void {\n const rel = relative(routesDir, filePath).replace(/\\\\/g, '/')\n const ext = extname(rel)\n const withoutExt = rel.slice(0, -ext.length)\n const segments = withoutExt.split('/')\n for (const seg of segments) {\n if (hasDotOutsideBrackets(seg)) {\n throw new RouterConventionError({\n file: filePath,\n suggestion: buildDirectoryNestedSuggestion(filePath, routesDir),\n })\n }\n }\n}\n\nfunction fileToRoutePath(filePath: string, routesDir: string): string {\n let rel = relative(routesDir, filePath)\n // Strip extension\n const ext = extname(rel)\n rel = rel.slice(0, -ext.length)\n // Normalize separators\n rel = rel.replace(/\\\\/g, '/')\n // Strip index suffix\n if (rel.endsWith('/index')) {\n rel = rel.slice(0, -6)\n } else if (rel === 'index') {\n rel = ''\n }\n // Replace [...param] with :...param (catch-all, before regular params).\n // Replace [param] with :param. Inputs are file paths bounded by the\n // OS filename limit; the bracket capture is bounded by `]`.\n rel = rel.replace(/\\[\\.\\.\\.([^\\]]+)\\]/g, ':...$1')\n // eslint-disable-next-line sonarjs/slow-regex -- bounded by `]`; input is a single filename\n rel = rel.replace(/\\[([^\\]]+)\\]/g, ':$1')\n return `/api/${rel}`\n}\n\nexport function scanServerRoutes(serverDir: string): ServerRouteNode[] {\n const routesDir = join(serverDir, 'routes')\n if (!existsSync(routesDir) || !statSync(routesDir).isDirectory()) {\n return []\n }\n\n const results: ServerRouteNode[] = []\n walkSourceFiles(routesDir, { extensions: ROUTE_EXTENSIONS }, (absPath) => {\n // EC-4: skip co-located test/spec files BEFORE the dotted-basename check\n if (isTestOrSpecFile(absPath)) return\n\n // G6 T1.1: reject dotted basenames (legacy convention that produced wrong\n // paramNames due to greedy `:(?:\\.\\.\\.)?([^/]+)` regex in compilePattern).\n assertNoDottedSegment(absPath, routesDir)\n\n const routePath = fileToRoutePath(absPath, routesDir)\n const { pattern, paramNames } = compilePattern(routePath)\n const methods = detectExportedHttpMethods(absPath)\n results.push({\n filePath: absPath,\n routePath,\n paramNames,\n pattern,\n methods,\n })\n })\n\n // T1.4 / EC-2 — refuse to scan if a user route collides with the reserved\n // batch endpoint path. User must rename or disable batching.\n const conflicting = results.find((r) => r.routePath === '/api/__theo_batch__')\n if (conflicting) {\n throw new Error(\n `Server route ${conflicting.filePath} resolves to '/api/__theo_batch__' which is reserved for the batch endpoint. Rename the route or disable batching in theo.config.ts.`,\n )\n }\n\n // Sort: static first, then dynamic, then catch-all last\n const isCatchAll = (route: ServerRouteNode) => route.routePath.includes(':...')\n results.sort((a, b) => {\n const aStatic = a.paramNames.length === 0\n const bStatic = b.paramNames.length === 0\n const aCatchAll = isCatchAll(a)\n const bCatchAll = isCatchAll(b)\n\n // Static routes first\n if (aStatic && !bStatic) return -1\n if (!aStatic && bStatic) return 1\n // Catch-all routes last\n if (aCatchAll && !bCatchAll) return 1\n if (!aCatchAll && bCatchAll) return -1\n return a.routePath.localeCompare(b.routePath)\n })\n\n return results\n}\n","/**\n * Detect which HTTP-method named exports a route file declares.\n *\n * Uses the TypeScript compiler API (not regex) per G1 edge-case review EC-4:\n * regex over file content emits false positives for `// export const GET = ...`\n * in comments and `` `export const GET = ...` `` in template literals. AST\n * walking avoids both classes of bug.\n *\n * `typescript` ships as CommonJS with internal dynamic `require('fs')`.\n * When loaded via ESM `import`, the dynamic requires fail at module-bootstrap.\n * We use `createRequire(import.meta.url)` to keep the package on its native\n * CJS path. The type-only namespace import gives us the AST helpers shape.\n *\n * Returns the set of HTTP methods (uppercase) the file exports. Empty array\n * means the file has no HTTP exports (the route file is util-only).\n */\n\nimport { readFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\n\nimport type * as TS from 'typescript'\n\nimport { HTTP_METHODS, type HttpMethod } from '../../core/contracts/http-methods.js'\n\nconst require_ = createRequire(import.meta.url)\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst ts = require_('typescript') as typeof TS\n\nconst HTTP_METHOD_NAMES = new Set<string>(HTTP_METHODS)\n\nfunction hasExportModifier(modifiers: readonly TS.Modifier[] | undefined): boolean {\n if (!modifiers) return false\n for (const m of modifiers) {\n if (m.kind === ts.SyntaxKind.ExportKeyword) return true\n }\n return false\n}\n\nfunction collectFromStatement(stmt: TS.Statement, found: Set<HttpMethod>): void {\n // `export const GET = ...` / `export function GET ...` / `export async function GET ...`\n if (ts.isVariableStatement(stmt) && hasExportModifier(ts.getModifiers(stmt))) {\n for (const decl of stmt.declarationList.declarations) {\n if (ts.isIdentifier(decl.name) && HTTP_METHOD_NAMES.has(decl.name.text)) {\n found.add(decl.name.text as HttpMethod)\n }\n }\n return\n }\n\n if (\n (ts.isFunctionDeclaration(stmt) || ts.isClassDeclaration(stmt)) &&\n hasExportModifier(ts.getModifiers(stmt))\n ) {\n if (stmt.name && HTTP_METHOD_NAMES.has(stmt.name.text)) {\n found.add(stmt.name.text as HttpMethod)\n }\n return\n }\n\n // `export { GET }` / `export { handler as GET } from './shared'` (EC-5)\n if (ts.isExportDeclaration(stmt) && stmt.exportClause && ts.isNamedExports(stmt.exportClause)) {\n for (const spec of stmt.exportClause.elements) {\n // spec.name is the exported (re-)name; spec.propertyName is the original (when renamed)\n if (HTTP_METHOD_NAMES.has(spec.name.text)) {\n found.add(spec.name.text as HttpMethod)\n }\n }\n }\n}\n\nexport function detectExportedHttpMethods(filePath: string, content?: string): HttpMethod[] {\n const src = content ?? readFileSync(filePath, 'utf-8')\n const sourceFile = ts.createSourceFile(\n filePath,\n src,\n ts.ScriptTarget.Latest,\n /* setParentNodes */ false,\n ts.ScriptKind.TS,\n )\n const found = new Set<HttpMethod>()\n for (const stmt of sourceFile.statements) {\n collectFromStatement(stmt, found)\n }\n return [...found].sort()\n}\n","/**\n * Router-convention errors thrown by the server-route scanner.\n *\n * Plan: .claude/knowledge-base/plans/g6-router-convention-plan.md v1.1\n *\n * theokit 0.4.0+ enforces directory-nested file-system routing\n * (`auth/[provider]/login.ts`) and REJECTS dotted-basename routes\n * (`auth.[provider].login.ts`) because the legacy regex extracted the\n * dotted basename incorrectly — `params.provider` was undefined at request\n * time. Decision recorded in the plan above (`g6-router-convention-plan.md`) and CHANGELOG 0.4.0\n * (no standalone ADR was cut for this router-convention change).\n */\n\n/**\n * Canonical migration guide URL. T4.2 establishes this as the authoritative\n * landing page. EC-3: error message uses this constant so the URL never\n * drifts from the doc location.\n */\nexport const ROUTER_MIGRATION_GUIDE_URL = 'https://theokit.dev/migration/0.3-to-0.4-router'\n\nexport interface RouterConventionErrorOptions {\n /** Absolute path of the offending route file. */\n file: string\n /** Suggested directory-nested replacement path (relative, e.g. `routes/auth/[provider]/login.ts`). */\n suggestion: string\n /** Migration guide URL (defaults to `ROUTER_MIGRATION_GUIDE_URL`). */\n migrationUrl?: string\n}\n\n/**\n * Thrown by `scanServerRoutes` when a route file uses the legacy\n * dotted-basename convention (`auth.[provider].login.ts`).\n *\n * The error is FAIL-FAST by design — running with a route that has wrong\n * `paramNames` produces silent 404s at request time, which is strictly\n * worse than a build-time error.\n */\nexport class RouterConventionError extends Error {\n override readonly name = 'RouterConventionError'\n readonly file: string\n readonly suggestion: string\n readonly migrationUrl: string\n\n constructor(opts: RouterConventionErrorOptions) {\n const migrationUrl = opts.migrationUrl ?? ROUTER_MIGRATION_GUIDE_URL\n const message = [\n `Router convention violation: dotted route basename is not supported in theokit 0.4+.`,\n ``,\n ` File: ${opts.file}`,\n ` Use directory-nested form: ${opts.suggestion}`,\n ``,\n `Migration guide: ${migrationUrl}`,\n `Run \\`theokit migrate router\\` to convert all dotted basenames automatically.`,\n ].join('\\n')\n super(message)\n this.file = opts.file\n this.suggestion = opts.suggestion\n this.migrationUrl = migrationUrl\n }\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time scanner: walks `serverDir/ws/` derived from cwd.\n * No HTTP input ever reaches these fs calls.\n */\nimport { existsSync, statSync } from 'node:fs'\nimport { extname, join, relative } from 'node:path'\n\nimport { walkSourceFiles } from '../_internal/scan-walker.js'\n\nconst WS_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx'])\n\nexport interface WebSocketRouteNode {\n filePath: string\n wsPath: string\n}\n\nexport function scanWebSocketRoutes(serverDir: string): WebSocketRouteNode[] {\n const wsDir = join(serverDir, 'ws')\n if (!existsSync(wsDir) || !statSync(wsDir).isDirectory()) {\n return []\n }\n\n const results: WebSocketRouteNode[] = []\n walkSourceFiles(wsDir, { extensions: WS_EXTENSIONS }, (absPath) => {\n let rel = relative(wsDir, absPath)\n rel = rel.replace(/\\\\/g, '/')\n rel = rel.slice(0, -extname(rel).length)\n if (rel.endsWith('/index')) rel = rel.slice(0, -6)\n else if (rel === 'index') rel = ''\n results.push({\n filePath: absPath,\n wsPath: `/ws/${rel}`,\n })\n })\n return results\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time manifest emitter / loader. All paths derived from `distDir`\n * + `serverDir`, themselves resolved from `process.cwd()`. No HTTP input.\n */\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs'\nimport { join, resolve, relative, dirname } from 'node:path'\n\nimport { scanServerActions } from './action-scan.js'\nimport type { ActionNode } from './action-scan.js'\nimport { scanAgents } from './agent-scan.js'\nimport type { AgentNode } from './agent-scan.js'\nimport { compilePattern } from './match.js'\nimport type { ServerRouteNode } from './match.js'\nimport { scanServerRoutes } from './scan.js'\nimport { scanWebSocketRoutes } from './ws-scan.js'\nimport type { WebSocketRouteNode } from './ws-scan.js'\n\n// --- Manifest Types ---\n\nexport interface ManifestRoute {\n filePath: string\n routePath: string\n paramNames: string[]\n /** HTTP methods (uppercase) the route file exports. Optional — manifests\n * generated before G1 omit this; loaders treat absence as \"unknown\". */\n methods?: string[]\n}\n\nexport interface ManifestAction {\n filePath: string\n actionPath: string\n}\n\nexport interface ManifestWebSocket {\n filePath: string\n wsPath: string\n}\n\n/** M2 — a top-level `agents/*.ts` convention entry. `filePath` is relative to the\n * project root (agents live OUTSIDE `serverDir`), unlike routes/actions/ws. */\nexport interface ManifestAgent {\n filePath: string\n agentPath: string\n name: string\n}\n\nexport interface TheoManifest {\n version: 1\n generatedAt: string\n routes: ManifestRoute[]\n actions: ManifestAction[]\n websockets: ManifestWebSocket[]\n /** M2 — optional for backward compat: manifests generated before M2 omit it. */\n agents?: ManifestAgent[]\n}\n\nexport interface LoadedManifest {\n routes: ServerRouteNode[]\n actions: ActionNode[]\n websockets: WebSocketRouteNode[]\n agents: AgentNode[]\n}\n\n// --- Generate ---\n\nexport function generateManifest(\n serverDir: string,\n // Agents live at `<projectRoot>/<agentsDir>`. Defaults to the server dir's parent; overridable\n // for tests / non-standard layouts.\n projectRoot: string = dirname(serverDir),\n // Agents dir NAME (config `agentsDir`, default \"agents\"), relative to projectRoot (#95 follow-up).\n agentsDir = 'agents',\n): TheoManifest {\n const routes = scanServerRoutes(serverDir)\n const actions = scanServerActions(serverDir)\n const websockets = scanWebSocketRoutes(serverDir)\n const agents = scanAgents(projectRoot, agentsDir)\n\n return {\n version: 1,\n generatedAt: new Date().toISOString(),\n routes: routes.map((r) => ({\n filePath: relative(serverDir, r.filePath),\n routePath: r.routePath,\n paramNames: r.paramNames,\n ...(r.methods !== undefined ? { methods: r.methods } : {}),\n })),\n actions: actions.map((a) => ({\n filePath: relative(serverDir, a.filePath),\n actionPath: a.actionPath,\n })),\n websockets: websockets.map((w) => ({\n filePath: relative(serverDir, w.filePath),\n wsPath: w.wsPath,\n })),\n agents: agents.map((a) => ({\n // Relative to projectRoot (agents/ is outside serverDir).\n filePath: relative(projectRoot, a.filePath),\n agentPath: a.agentPath,\n name: a.name,\n })),\n }\n}\n\n// --- Write ---\n\nexport function writeManifest(manifest: TheoManifest, outputDir: string): void {\n mkdirSync(outputDir, { recursive: true })\n const manifestPath = join(outputDir, 'manifest.json')\n writeFileSync(manifestPath, JSON.stringify(manifest, null, 2))\n}\n\n// --- Load ---\n\nexport function loadManifest(distDir: string, serverDir: string): LoadedManifest {\n const manifestPath = join(distDir, 'manifest.json')\n\n if (!existsSync(manifestPath)) {\n throw new Error(`No manifest found at ${manifestPath}. Run \"theo build\" first.`)\n }\n\n const raw = JSON.parse(readFileSync(manifestPath, 'utf-8')) as TheoManifest\n\n const routes: ServerRouteNode[] = raw.routes.map((r) => {\n const { pattern, paramNames } = compilePattern(r.routePath)\n return {\n filePath: resolve(serverDir, r.filePath),\n routePath: r.routePath,\n paramNames,\n pattern,\n ...(r.methods !== undefined ? { methods: r.methods } : {}),\n }\n })\n\n const actions: ActionNode[] = raw.actions.map((a) => ({\n filePath: resolve(serverDir, a.filePath),\n actionPath: a.actionPath,\n }))\n\n const websockets: WebSocketRouteNode[] = raw.websockets.map((w) => ({\n filePath: resolve(serverDir, w.filePath),\n wsPath: w.wsPath,\n }))\n\n // M2 — agents resolve relative to the project root (sibling of serverDir).\n // `?? []` keeps pre-M2 manifests (no `agents` field) loadable (fail-safe).\n const projectRoot = dirname(serverDir)\n const agents: AgentNode[] = (raw.agents ?? []).map((a) => ({\n filePath: resolve(projectRoot, a.filePath),\n agentPath: a.agentPath,\n name: a.name,\n }))\n\n return { routes, actions, websockets, agents }\n}\n"],"mappings":";;;;;;;;AAIA,SAAS,YAAY,cAAc,gBAAgB;AACnD,SAAS,SAAS,MAAM,gBAAgB;AAqCjC,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAChC;AAAA,EACA;AAAA,EAET,YACE,MACA,SACA,kBACA;AACA,UAAM,OAAO;AAIb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,mBAAmB;AAAA,EAC1B;AACF;AAEA,IAAM,oBAAoB,oBAAI,IAAI,CAAC,OAAO,QAAQ,OAAO,MAAM,CAAC;AAChE,IAAM,eAAe;AACrB,IAAM,iBAAiB,oBAAI,IAAI,CAAC,SAAS,eAAe,aAAa,aAAa,gBAAgB,CAAC;AAO5F,SAAS,kBAAkB,WAAiC;AACjE,QAAM,aAAa,KAAK,WAAW,SAAS;AAC5C,MAAI,CAAC,WAAW,UAAU,KAAK,CAAC,SAAS,UAAU,EAAE,YAAY,GAAG;AAClE,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAwB,CAAC;AAC/B,kBAAgB,YAAY,EAAE,YAAY,kBAAkB,GAAG,CAAC,YAAY;AAC1E,QAAI,aAAa,KAAK,OAAO,EAAG;AAChC,QAAI,MAAM,SAAS,YAAY,OAAO;AACtC,UAAM,IAAI,QAAQ,OAAO,GAAG;AAC5B,UAAM,IAAI,MAAM,GAAG,CAAC,QAAQ,GAAG,EAAE,MAAM;AACvC,YAAQ,KAAK;AAAA,MACX,UAAU;AAAA,MACV,YAAY;AAAA,IACd,CAAC;AAAA,EACH,CAAC;AACD,SAAO;AACT;AAUO,SAAS,0BAA0B,WAA0C;AAClF,QAAM,aAAa,KAAK,WAAW,SAAS;AAC5C,MAAI,CAAC,WAAW,UAAU,KAAK,CAAC,SAAS,UAAU,EAAE,YAAY,GAAG;AAClE,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,YAAY,oBAAI,IAAY;AAClC,QAAM,UAAiC,CAAC;AAGxC,kBAAgB,YAAY,EAAE,YAAY,kBAAkB,GAAG,CAAC,YAAY;AAC1E,QAAI,aAAa,KAAK,OAAO,EAAG;AAChC,UAAM,MAAM,SAAS,YAAY,OAAO,EAAE,QAAQ,OAAO,GAAG;AAG5D,QAAI,IAAI,WAAW,UAAU,EAAG;AAChC,UAAM,OAAO,IAAI,MAAM,GAAG,CAAC,QAAQ,GAAG,EAAE,MAAM;AAE9C,UAAMA,YAAW,KAAK,SAAS,GAAG,IAAK,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK,OAAQ;AACxE,QAAI,eAAe,IAAIA,SAAQ,GAAG;AAChC,YAAM,IAAI;AAAA,QACR;AAAA,QACA,2BAA2BA,SAAQ,+BAA+B,OAAO;AAAA,QACzE,CAAC,OAAO;AAAA,MACV;AAAA,IACF;AAGA,UAAM,SAAS,aAAa,SAAS,MAAM;AAC3C,UAAM,WAAW,cAAc,MAAM;AACrC,UAAM,SAAS,8BAA8B,KAAK,QAAQ,IAAI,SAAS;AACvE,UAAM,WAAW,oBAAoB,KAAK,QAAQ,KAAK,sBAAsB,KAAK,QAAQ;AAS1F,UAAM,cAAc,yBAAyB,QAAQ;AAIrD,UAAM,iBAAiB,KAAK,SAAS,GAAG,IAAI,SAAY,iBAAiB,YAAYA,SAAQ;AAC7F,eAAW,cAAc,aAAa;AACpC,YAAM,WAAW,eAAe,YAAY,OAAO;AACnD,UAAI,UAAU,IAAI,QAAQ,GAAG;AAC3B,cAAM,IAAI;AAAA,UACR;AAAA,UACA,+BAA+B,QAAQ;AAAA,UACvC,CAAC,OAAO;AAAA,QACV;AAAA,MACF;AACA,gBAAU,IAAI,QAAQ;AACtB,YAAM,QAA6B;AAAA,QACjC,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS,kBAAkB,IAAI,IAAI,UAAU;AAAA,QAC7C;AAAA,QACA;AAAA,MACF;AACA,UAAI,mBAAmB,QAAW;AAChC,cAAM,iBAAiB;AAAA,MACzB;AACA,cAAQ,KAAK,KAAK;AAAA,IACpB;AAAA,EACF,CAAC;AAID,aAAW,SAAS,SAAS;AAC3B,UAAM,cAAc,GAAG,MAAM,IAAI;AACjC,UAAM,mBAAmB,QAAQ,KAAK,CAAC,UAAU,MAAM,KAAK,WAAW,WAAW,CAAC;AACnF,QAAI,kBAAkB;AACpB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,WAAW,MAAM,IAAI,uDAAuD,iBAAiB,IAAI;AAAA,QACjG,CAAC,MAAM,UAAU,iBAAiB,QAAQ;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,KAAK,CAAC,GAAG,MAAM;AACrB,QAAI,EAAE,OAAO,EAAE,KAAM,QAAO;AAC5B,QAAI,EAAE,OAAO,EAAE,KAAM,QAAO;AAC5B,WAAO;AAAA,EACT,CAAC;AACD,SAAO;AACT;AAeA,SAAS,yBAAyB,UAA4B;AAC5D,QAAM,QAAQ,oBAAI,IAAY;AAC9B,QAAM,UAAU;AAChB,MAAI;AACJ,UAAQ,IAAI,QAAQ,KAAK,QAAQ,OAAO,MAAM;AAC5C,UAAM,OAAO,EAAE,CAAC;AAChB,QAAI,OAAO,SAAS,YAAY,KAAK,SAAS,EAAG,OAAM,IAAI,IAAI;AAAA,EACjE;AACA,MAAI,sCAAsC,KAAK,QAAQ,GAAG;AACxD,UAAM,IAAI,SAAS;AAAA,EACrB;AACA,MAAI,MAAM,SAAS,EAAG,OAAM,IAAI,SAAS;AACzC,SAAO,CAAC,GAAG,KAAK;AAClB;AAOA,SAAS,iBAAiB,YAAoBA,WAAsC;AAClF,QAAM,aAAa,KAAK,YAAY,SAAS;AAC7C,MAAI,CAAC,WAAW,UAAU,EAAG,QAAO;AACpC,aAAW,OAAO,CAAC,OAAO,QAAQ,OAAO,MAAM,GAAG;AAChD,UAAM,YAAY,KAAK,YAAY,GAAGA,SAAQ,GAAG,GAAG,EAAE;AACtD,QAAI,WAAW,SAAS,EAAG,QAAO;AAAA,EACpC;AACA,SAAO;AACT;AAEA,SAAS,cAAc,QAAwB;AAC7C,MAAI,MAAM;AACV,MAAI,IAAI;AACR,SAAO,IAAI,OAAO,QAAQ;AACxB,UAAM,KAAK,OAAO,CAAC;AACnB,UAAM,OAAO,OAAO,IAAI,CAAC;AACzB,QAAI,OAAO,OAAO,SAAS,KAAK;AAE9B,aAAO,IAAI,OAAO,UAAU,OAAO,CAAC,MAAM,KAAM;AAChD;AAAA,IACF;AACA,QAAI,OAAO,OAAO,SAAS,KAAK;AAE9B,WAAK;AACL,aAAO,IAAI,OAAO,SAAS,KAAK,EAAE,OAAO,CAAC,MAAM,OAAO,OAAO,IAAI,CAAC,MAAM,KAAM;AAC/E,WAAK;AACL;AAAA,IACF;AACA,WAAO;AACP;AAAA,EACF;AACA,SAAO;AACT;;;AC1PA,SAAS,cAAAC,aAAY,YAAAC,iBAAgB;AACrC,SAAS,WAAAC,UAAS,QAAAC,OAAM,YAAAC,iBAAgB;AAIxC,IAAM,mBAAmB,oBAAI,IAAI,CAAC,OAAO,QAAQ,OAAO,MAAM,CAAC;AAE/D,IAAM,YAAY;AAUlB,IAAM,mBAAmB,oBAAI,IAAI;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAgBM,SAAS,WAAW,aAAqB,gBAAgB,UAAuB;AAGrF,QAAM,YAAYC,MAAK,aAAa,aAAa;AACjD,MAAI,CAACC,YAAW,SAAS,KAAK,CAACC,UAAS,SAAS,EAAE,YAAY,GAAG;AAChE,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAuB,CAAC;AAC9B,kBAAgB,WAAW,EAAE,YAAY,iBAAiB,GAAG,CAAC,YAAY;AACxE,QAAI,MAAMC,UAAS,WAAW,OAAO;AACrC,UAAM,IAAI,QAAQ,OAAO,GAAG;AAC5B,UAAM,IAAI,MAAM,GAAG,CAACC,SAAQ,GAAG,EAAE,MAAM;AACvC,QAAI,UAAU,KAAK,GAAG,EAAG;AAIzB,UAAM,OAAO,IAAI,MAAM,GAAG,EAAE,MAAM,GAAG,EAAE;AACvC,QAAI,KAAK,KAAK,CAAC,YAAY,iBAAiB,IAAI,OAAO,CAAC,EAAG;AAI3D,QAAI,IAAI,SAAS,QAAQ,EAAG,OAAM,IAAI,MAAM,GAAG,EAAE;AACjD,QAAI,QAAQ,WAAW,QAAQ,GAAI;AACnC,YAAQ,KAAK;AAAA,MACX,UAAU;AAAA,MACV,WAAW,eAAe,GAAG;AAAA,MAC7B,MAAM;AAAA,IACR,CAAC;AAAA,EACH,CAAC;AACD,SAAO;AACT;;;ACvEO,SAAS,eAAe,WAG7B;AACA,QAAM,aAAuB,CAAC;AAE9B,QAAM,WAAW,UAAU,QAAQ,wBAAwB,CAAC,OAAe,SAAiB;AAC1F,eAAW,KAAK,IAAI;AAEpB,WAAO,MAAM,WAAW,MAAM,IAAI,SAAS;AAAA,EAC7C,CAAC;AAKD,SAAO,EAAE,SAAS,IAAI,OAAO,IAAI,QAAQ,GAAG,GAAG,WAAW;AAC5D;AAEO,SAAS,WACd,KACA,QACmE;AAEnE,MAAI,OAAO,IAAI,MAAM,GAAG,EAAE,CAAC;AAC3B,MAAI,KAAK,SAAS,KAAK,KAAK,SAAS,GAAG,GAAG;AACzC,WAAO,KAAK,MAAM,GAAG,EAAE;AAAA,EACzB;AAEA,aAAW,SAAS,QAAQ;AAC1B,UAAM,QAAQ,MAAM,QAAQ,KAAK,IAAI;AACrC,QAAI,OAAO;AACT,YAAM,SAAiC,CAAC;AACxC,YAAM,WAAW,QAAQ,CAAC,MAAM,MAAM;AACpC,eAAO,IAAI,IAAI,MAAM,IAAI,CAAC;AAAA,MAC5B,CAAC;AACD,aAAO,EAAE,OAAO,OAAO;AAAA,IACzB;AAAA,EACF;AACA,SAAO;AACT;;;AC9CA,SAAS,cAAAC,aAAY,YAAAC,iBAAgB;AACrC,SAAS,UAAU,WAAAC,UAAS,QAAAC,OAAM,YAAAC,iBAAgB;;;ACYlD,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,qBAAqB;AAM9B,IAAM,WAAW,cAAc,YAAY,GAAG;AAE9C,IAAM,KAAK,SAAS,YAAY;AAEhC,IAAM,oBAAoB,IAAI,IAAY,YAAY;AAEtD,SAAS,kBAAkB,WAAwD;AACjF,MAAI,CAAC,UAAW,QAAO;AACvB,aAAW,KAAK,WAAW;AACzB,QAAI,EAAE,SAAS,GAAG,WAAW,cAAe,QAAO;AAAA,EACrD;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,MAAoB,OAA8B;AAE9E,MAAI,GAAG,oBAAoB,IAAI,KAAK,kBAAkB,GAAG,aAAa,IAAI,CAAC,GAAG;AAC5E,eAAW,QAAQ,KAAK,gBAAgB,cAAc;AACpD,UAAI,GAAG,aAAa,KAAK,IAAI,KAAK,kBAAkB,IAAI,KAAK,KAAK,IAAI,GAAG;AACvE,cAAM,IAAI,KAAK,KAAK,IAAkB;AAAA,MACxC;AAAA,IACF;AACA;AAAA,EACF;AAEA,OACG,GAAG,sBAAsB,IAAI,KAAK,GAAG,mBAAmB,IAAI,MAC7D,kBAAkB,GAAG,aAAa,IAAI,CAAC,GACvC;AACA,QAAI,KAAK,QAAQ,kBAAkB,IAAI,KAAK,KAAK,IAAI,GAAG;AACtD,YAAM,IAAI,KAAK,KAAK,IAAkB;AAAA,IACxC;AACA;AAAA,EACF;AAGA,MAAI,GAAG,oBAAoB,IAAI,KAAK,KAAK,gBAAgB,GAAG,eAAe,KAAK,YAAY,GAAG;AAC7F,eAAW,QAAQ,KAAK,aAAa,UAAU;AAE7C,UAAI,kBAAkB,IAAI,KAAK,KAAK,IAAI,GAAG;AACzC,cAAM,IAAI,KAAK,KAAK,IAAkB;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,0BAA0B,UAAkB,SAAgC;AAC1F,QAAM,MAAM,WAAWC,cAAa,UAAU,OAAO;AACrD,QAAM,aAAa,GAAG;AAAA,IACpB;AAAA,IACA;AAAA,IACA,GAAG,aAAa;AAAA;AAAA,IACK;AAAA,IACrB,GAAG,WAAW;AAAA,EAChB;AACA,QAAM,QAAQ,oBAAI,IAAgB;AAClC,aAAW,QAAQ,WAAW,YAAY;AACxC,yBAAqB,MAAM,KAAK;AAAA,EAClC;AACA,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK;AACzB;;;AClEO,IAAM,6BAA6B;AAmBnC,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAC7B,OAAO;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,MAAoC;AAC9C,UAAM,eAAe,KAAK,gBAAgB;AAC1C,UAAM,UAAU;AAAA,MACd;AAAA,MACA;AAAA,MACA,WAAW,KAAK,IAAI;AAAA,MACpB,gCAAgC,KAAK,UAAU;AAAA,MAC/C;AAAA,MACA,oBAAoB,YAAY;AAAA,MAChC;AAAA,IACF,EAAE,KAAK,IAAI;AACX,UAAM,OAAO;AACb,SAAK,OAAO,KAAK;AACjB,SAAK,aAAa,KAAK;AACvB,SAAK,eAAe;AAAA,EACtB;AACF;;;AF9CA,IAAM,mBAAmB,oBAAI,IAAI,CAAC,OAAO,QAAQ,OAAO,MAAM,CAAC;AAK/D,IAAM,kBAAkB;AAExB,SAAS,iBAAiB,UAA2B;AACnD,SAAO,gBAAgB,KAAK,SAAS,QAAQ,CAAC;AAChD;AAEA,SAAS,sBAAsB,SAA0B;AACvD,MAAI,QAAQ;AACZ,aAAW,MAAM,SAAS;AACxB,QAAI,OAAO,IAAK;AAAA,aACP,OAAO,IAAK;AAAA,aACZ,OAAO,OAAO,UAAU,EAAG,QAAO;AAAA,EAC7C;AACA,SAAO;AACT;AAEA,SAAS,kCAAkC,SAA2B;AACpE,QAAM,QAAkB,CAAC;AACzB,MAAI,UAAU;AACd,MAAI,QAAQ;AACZ,aAAW,MAAM,SAAS;AACxB,QAAI,OAAO,KAAK;AACd;AACA,iBAAW;AAAA,IACb,WAAW,OAAO,KAAK;AACrB;AACA,iBAAW;AAAA,IACb,WAAW,OAAO,OAAO,UAAU,GAAG;AACpC,UAAI,QAAS,OAAM,KAAK,OAAO;AAC/B,gBAAU;AAAA,IACZ,OAAO;AACL,iBAAW;AAAA,IACb;AAAA,EACF;AACA,MAAI,QAAS,OAAM,KAAK,OAAO;AAC/B,SAAO;AACT;AAEA,SAAS,+BAA+B,UAAkB,WAA2B;AACnF,QAAM,MAAMC,UAAS,WAAW,QAAQ,EAAE,QAAQ,OAAO,GAAG;AAC5D,QAAM,MAAMC,SAAQ,GAAG;AACvB,QAAM,aAAa,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM;AAC3C,QAAM,WAAW,WAAW,MAAM,GAAG,EAAE,QAAQ,iCAAiC;AAChF,SAAO,UAAU,SAAS,KAAK,GAAG,CAAC,GAAG,GAAG;AAC3C;AAEA,SAAS,sBAAsB,UAAkB,WAAyB;AACxE,QAAM,MAAMD,UAAS,WAAW,QAAQ,EAAE,QAAQ,OAAO,GAAG;AAC5D,QAAM,MAAMC,SAAQ,GAAG;AACvB,QAAM,aAAa,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM;AAC3C,QAAM,WAAW,WAAW,MAAM,GAAG;AACrC,aAAW,OAAO,UAAU;AAC1B,QAAI,sBAAsB,GAAG,GAAG;AAC9B,YAAM,IAAI,sBAAsB;AAAA,QAC9B,MAAM;AAAA,QACN,YAAY,+BAA+B,UAAU,SAAS;AAAA,MAChE,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,UAAkB,WAA2B;AACpE,MAAI,MAAMD,UAAS,WAAW,QAAQ;AAEtC,QAAM,MAAMC,SAAQ,GAAG;AACvB,QAAM,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM;AAE9B,QAAM,IAAI,QAAQ,OAAO,GAAG;AAE5B,MAAI,IAAI,SAAS,QAAQ,GAAG;AAC1B,UAAM,IAAI,MAAM,GAAG,EAAE;AAAA,EACvB,WAAW,QAAQ,SAAS;AAC1B,UAAM;AAAA,EACR;AAIA,QAAM,IAAI,QAAQ,uBAAuB,QAAQ;AAEjD,QAAM,IAAI,QAAQ,iBAAiB,KAAK;AACxC,SAAO,QAAQ,GAAG;AACpB;AAEO,SAAS,iBAAiB,WAAsC;AACrE,QAAM,YAAYC,MAAK,WAAW,QAAQ;AAC1C,MAAI,CAACC,YAAW,SAAS,KAAK,CAACC,UAAS,SAAS,EAAE,YAAY,GAAG;AAChE,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAA6B,CAAC;AACpC,kBAAgB,WAAW,EAAE,YAAY,iBAAiB,GAAG,CAAC,YAAY;AAExE,QAAI,iBAAiB,OAAO,EAAG;AAI/B,0BAAsB,SAAS,SAAS;AAExC,UAAM,YAAY,gBAAgB,SAAS,SAAS;AACpD,UAAM,EAAE,SAAS,WAAW,IAAI,eAAe,SAAS;AACxD,UAAM,UAAU,0BAA0B,OAAO;AACjD,YAAQ,KAAK;AAAA,MACX,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAID,QAAM,cAAc,QAAQ,KAAK,CAAC,MAAM,EAAE,cAAc,qBAAqB;AAC7E,MAAI,aAAa;AACf,UAAM,IAAI;AAAA,MACR,gBAAgB,YAAY,QAAQ;AAAA,IACtC;AAAA,EACF;AAGA,QAAM,aAAa,CAAC,UAA2B,MAAM,UAAU,SAAS,MAAM;AAC9E,UAAQ,KAAK,CAAC,GAAG,MAAM;AACrB,UAAM,UAAU,EAAE,WAAW,WAAW;AACxC,UAAM,UAAU,EAAE,WAAW,WAAW;AACxC,UAAM,YAAY,WAAW,CAAC;AAC9B,UAAM,YAAY,WAAW,CAAC;AAG9B,QAAI,WAAW,CAAC,QAAS,QAAO;AAChC,QAAI,CAAC,WAAW,QAAS,QAAO;AAEhC,QAAI,aAAa,CAAC,UAAW,QAAO;AACpC,QAAI,CAAC,aAAa,UAAW,QAAO;AACpC,WAAO,EAAE,UAAU,cAAc,EAAE,SAAS;AAAA,EAC9C,CAAC;AAED,SAAO;AACT;;;AGvJA,SAAS,cAAAC,aAAY,YAAAC,iBAAgB;AACrC,SAAS,WAAAC,UAAS,QAAAC,OAAM,YAAAC,iBAAgB;AAIxC,IAAM,gBAAgB,oBAAI,IAAI,CAAC,OAAO,QAAQ,OAAO,MAAM,CAAC;AAOrD,SAAS,oBAAoB,WAAyC;AAC3E,QAAM,QAAQC,MAAK,WAAW,IAAI;AAClC,MAAI,CAACC,YAAW,KAAK,KAAK,CAACC,UAAS,KAAK,EAAE,YAAY,GAAG;AACxD,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAgC,CAAC;AACvC,kBAAgB,OAAO,EAAE,YAAY,cAAc,GAAG,CAAC,YAAY;AACjE,QAAI,MAAMC,UAAS,OAAO,OAAO;AACjC,UAAM,IAAI,QAAQ,OAAO,GAAG;AAC5B,UAAM,IAAI,MAAM,GAAG,CAACC,SAAQ,GAAG,EAAE,MAAM;AACvC,QAAI,IAAI,SAAS,QAAQ,EAAG,OAAM,IAAI,MAAM,GAAG,EAAE;AAAA,aACxC,QAAQ,QAAS,OAAM;AAChC,YAAQ,KAAK;AAAA,MACX,UAAU;AAAA,MACV,QAAQ,OAAO,GAAG;AAAA,IACpB,CAAC;AAAA,EACH,CAAC;AACD,SAAO;AACT;;;AC/BA,SAAS,cAAAC,aAAY,gBAAAC,eAAc,eAAe,iBAAiB;AACnE,SAAS,QAAAC,OAAM,SAAS,YAAAC,WAAU,eAAe;AA4D1C,SAAS,iBACd,WAGA,cAAsB,QAAQ,SAAS,GAEvC,YAAY,UACE;AACd,QAAM,SAAS,iBAAiB,SAAS;AACzC,QAAM,UAAU,kBAAkB,SAAS;AAC3C,QAAM,aAAa,oBAAoB,SAAS;AAChD,QAAM,SAAS,WAAW,aAAa,SAAS;AAEhD,SAAO;AAAA,IACL,SAAS;AAAA,IACT,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,QAAQ,OAAO,IAAI,CAAC,OAAO;AAAA,MACzB,UAAUC,UAAS,WAAW,EAAE,QAAQ;AAAA,MACxC,WAAW,EAAE;AAAA,MACb,YAAY,EAAE;AAAA,MACd,GAAI,EAAE,YAAY,SAAY,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC1D,EAAE;AAAA,IACF,SAAS,QAAQ,IAAI,CAAC,OAAO;AAAA,MAC3B,UAAUA,UAAS,WAAW,EAAE,QAAQ;AAAA,MACxC,YAAY,EAAE;AAAA,IAChB,EAAE;AAAA,IACF,YAAY,WAAW,IAAI,CAAC,OAAO;AAAA,MACjC,UAAUA,UAAS,WAAW,EAAE,QAAQ;AAAA,MACxC,QAAQ,EAAE;AAAA,IACZ,EAAE;AAAA,IACF,QAAQ,OAAO,IAAI,CAAC,OAAO;AAAA;AAAA,MAEzB,UAAUA,UAAS,aAAa,EAAE,QAAQ;AAAA,MAC1C,WAAW,EAAE;AAAA,MACb,MAAM,EAAE;AAAA,IACV,EAAE;AAAA,EACJ;AACF;AAIO,SAAS,cAAc,UAAwB,WAAyB;AAC7E,YAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AACxC,QAAM,eAAeC,MAAK,WAAW,eAAe;AACpD,gBAAc,cAAc,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAC/D;AAIO,SAAS,aAAa,SAAiB,WAAmC;AAC/E,QAAM,eAAeA,MAAK,SAAS,eAAe;AAElD,MAAI,CAACC,YAAW,YAAY,GAAG;AAC7B,UAAM,IAAI,MAAM,wBAAwB,YAAY,2BAA2B;AAAA,EACjF;AAEA,QAAM,MAAM,KAAK,MAAMC,cAAa,cAAc,OAAO,CAAC;AAE1D,QAAM,SAA4B,IAAI,OAAO,IAAI,CAAC,MAAM;AACtD,UAAM,EAAE,SAAS,WAAW,IAAI,eAAe,EAAE,SAAS;AAC1D,WAAO;AAAA,MACL,UAAU,QAAQ,WAAW,EAAE,QAAQ;AAAA,MACvC,WAAW,EAAE;AAAA,MACb;AAAA,MACA;AAAA,MACA,GAAI,EAAE,YAAY,SAAY,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC1D;AAAA,EACF,CAAC;AAED,QAAM,UAAwB,IAAI,QAAQ,IAAI,CAAC,OAAO;AAAA,IACpD,UAAU,QAAQ,WAAW,EAAE,QAAQ;AAAA,IACvC,YAAY,EAAE;AAAA,EAChB,EAAE;AAEF,QAAM,aAAmC,IAAI,WAAW,IAAI,CAAC,OAAO;AAAA,IAClE,UAAU,QAAQ,WAAW,EAAE,QAAQ;AAAA,IACvC,QAAQ,EAAE;AAAA,EACZ,EAAE;AAIF,QAAM,cAAc,QAAQ,SAAS;AACrC,QAAM,UAAuB,IAAI,UAAU,CAAC,GAAG,IAAI,CAAC,OAAO;AAAA,IACzD,UAAU,QAAQ,aAAa,EAAE,QAAQ;AAAA,IACzC,WAAW,EAAE;AAAA,IACb,MAAM,EAAE;AAAA,EACV,EAAE;AAEF,SAAO,EAAE,QAAQ,SAAS,YAAY,OAAO;AAC/C;","names":["basename","existsSync","statSync","extname","join","relative","join","existsSync","statSync","relative","extname","existsSync","statSync","extname","join","relative","readFileSync","readFileSync","relative","extname","join","existsSync","statSync","existsSync","statSync","extname","join","relative","join","existsSync","statSync","relative","extname","existsSync","readFileSync","join","relative","relative","join","existsSync","readFileSync"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/vite-plugin/index.ts","../src/vite-plugin/config-hook.ts","../src/vite-plugin/theoui-detect.ts","../src/vite-plugin/config-resolve.ts","../src/vite-plugin/configure-server-hook.ts","../src/devtools/server-side/route-manifest.ts","../src/vite-plugin/action-middleware.ts","../src/vite-plugin/agent-middleware.ts","../src/vite-plugin/api-middleware.ts","../src/vite-plugin/ssr-dev-middleware.ts","../src/vite-plugin/ws-upgrade.ts","../src/vite-plugin/integrate-ui.ts","../src/vite-plugin/auto-detect.ts","../src/vite-plugin/resolve-theo-root.ts","../src/vite-plugin/transform-html-hook.ts","../src/vite-plugin/inject-devtools.ts","../src/vite-plugin/inject-entry-client.ts","../src/vite-plugin/inject-stylesheets.ts","../src/router/entry-server.ts","../src/router/entry.ts","../src/router/generate.ts","../src/vite-plugin/virtual-modules-hook.ts","../src/vite-plugin/integrations.ts"],"sourcesContent":["/* eslint-disable security/detect-non-literal-fs-filename --\n * Vite plugin entry. Reads `package.json` + checks for ts vs js source\n * layout under `theoSrcDir` (build-time literal). No HTTP input.\n */\nimport { existsSync } from 'node:fs'\nimport { resolve, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport type { Plugin } from 'vite'\n\nimport {\n type AuditLogger,\n type CorsConfig,\n type CsrfReadinessStore,\n type DisallowedConfig,\n type PluginRunner,\n type RateLimitConfig,\n type SecurityHeadersConfig,\n} from '../server/internal-api.js'\nimport type { TheoTransformer } from '../server/transformer.js'\nimport { type ServicesConfig } from '../services/index.js'\n\n// T2.1-T2.3 (architecture-medium-deferrals) + T2.6 (M6) — sibling extractions.\nimport { runConfigHook } from './config-hook.js'\nimport { resolvePluginConfig, type ResolvedOpenApi } from './config-resolve.js'\nimport { runConfigureServer } from './configure-server-hook.js'\nimport { integrateUseTheoUI } from './integrate-ui.js'\nimport { resolveTheoRootDir } from './resolve-theo-root.js'\nimport type { TheoUiDetectResult } from './theoui-detect.js'\nimport { runTransformIndexHtml } from './transform-html-hook.js'\nimport {\n loadVirtualModule,\n resolveVirtualModuleId,\n type VirtualModuleIds,\n} from './virtual-modules-hook.js'\n\nexport {\n defineTheoIntegration,\n createIntegrationRegistry,\n IntegrationRouteCollisionError,\n IntegrationVirtualModulePrefixError,\n} from './integrations.js'\nexport type {\n TheoIntegration,\n HookName as IntegrationHookName,\n Hook as IntegrationHook,\n HookContext as IntegrationHookContext,\n IntegrationRegistry,\n IntegrationRegistryOptions,\n IntegrationRoute,\n RouteHandler as IntegrationRouteHandler,\n} from './integrations.js'\n\nconst VIRTUAL_ENTRY_ID = '/@theo/entry-client'\nconst RESOLVED_ENTRY_ID = '\\0@theo/entry-client'\nconst VIRTUAL_MANIFEST_ID = '/@theo/route-manifest'\nconst RESOLVED_MANIFEST_ID = '\\0@theo/route-manifest'\nconst VIRTUAL_ENTRY_SERVER_ID = '/@theo/entry-server'\nconst RESOLVED_ENTRY_SERVER_ID = '\\0@theo/entry-server'\nconst VIRTUAL_RUNTIME_CONFIG_ID = '/@theo/runtime-config'\nconst RESOLVED_RUNTIME_CONFIG_ID = '\\0@theo/runtime-config'\n\nexport interface TheoPluginOptions {\n root?: string\n rateLimit?: RateLimitConfig\n ssr?: boolean\n ssrStreaming?: boolean\n /**\n * Wave 2 (T3.1) — polyglot services config. When passed, the\n * services-typed-client plugin is wired and generates `clients/<name>.ts`\n * per service with an OpenAPI URL. Empty `{}` → no-op.\n */\n services?: ServicesConfig\n /**\n * T4.1 (canvas-ecosystem-refactor / ADR D6) — extra package names appended\n * to Vite `optimizeDeps.include`. Required when an installed plugin\n * peer-dep is consumed via a literal `import('<pkg>')` (dynamic specifier)\n * — Vite cannot trace those without a hint, and the browser receives a\n * `Failed to resolve module specifier '<pkg>'` error.\n *\n * Default targets pre-bundled regardless: `@theokit/ui`, `lucide-react`.\n *\n * Example:\n * viteOptimizeDeps: ['mermaid']\n */\n viteOptimizeDeps?: string[]\n /**\n * Optional override for the in-memory CSRF readiness store consumed by\n * the `/__theo/csrf-readiness` endpoint and the devtools CSRF Readiness\n * tab. When omitted, the plugin auto-instantiates a default in-process\n * `CsrfReadinessStore` so the tab works out-of-the-box in dev.\n *\n * Override with a custom impl when you need cross-worker telemetry\n * (e.g., Redis-backed store) or want to silence the tab entirely\n * (pass an inert store that discards writes).\n */\n csrfReadinessStore?: CsrfReadinessStore\n /**\n * Backend root directory name (config `serverDir`), relative to the project root. Route/action\n * discovery, the typed-client codegen, and the routes HMR watcher all scan `<serverDir>/routes`,\n * `<serverDir>/actions`, etc. Defaults to `\"server\"` — apps that keep the canonical layout are\n * unaffected. Set to e.g. `\"core\"` to organize the backend by domain (issue #95).\n */\n serverDir?: string\n /**\n * Directory (relative to project root) holding `agents/<name>.ts` definitions (config `agentsDir`).\n * Scanned by the dev agent-middleware + the typed-agent codegen + the routes manifest. Defaults to\n * `\"agents\"`. Set to e.g. `\"core/agents\"` to co-locate agents with the domain root (#95 follow-up).\n */\n agentsDir?: string\n /**\n * Frontend dir (config `appDir`, default \"app\") holding the file-based router (`page.tsx`,\n * `layout.tsx`, …), relative to the project root. Set to e.g. `\"apps/web\"` to group the web UI\n * under an `apps/` root alongside other frontends (#95 follow-up).\n */\n appDir?: string\n}\n\n/**\n * T3.3 — Find a consumer-side config file (`tailwind.config.*`, `postcss.config.*`)\n * by walking from projectRoot up to 3 levels. Returns the absolute path on the\n * first hit, or `undefined`. Used to defer to consumer's manual config (D3).\n */\nfunction findConsumerConfig(projectRoot: string, basename: string): string | undefined {\n const extensions = ['.ts', '.js', '.mjs', '.cjs']\n let dir = projectRoot\n for (let level = 0; level < 3; level++) {\n for (const ext of extensions) {\n const candidate = resolve(dir, `${basename}${ext}`)\n if (existsSync(candidate)) return candidate\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n return undefined\n}\n\n/**\n * Async factory companion. Returns `[theoPlugin, ...autoChainedPlugins]`.\n *\n * Why this exists alongside the sync `theoPlugin()` factory: Vite does NOT\n * reliably merge plugins returned from a child plugin's `config()` hook\n * (verified empirically 2026-05-23 — plugins were silently dropped from\n * the resolved chain despite being returned correctly). The canonical\n * Vite pattern for plugin-from-plugin is to return `Plugin[]` from the\n * plugin factory itself, which Vite flattens into the consumer's\n * `plugins` array.\n *\n * Consumers should prefer `await theoPluginAsync(...)` over `theoPlugin(...)`\n * when they want @theokit/ui + @tailwindcss/vite auto-chaining. The sync\n * factory remains for backward compatibility and tests.\n */\nexport async function theoPluginAsync(\n rootOrOptions?: string | TheoPluginOptions,\n): Promise<Plugin[]> {\n const options =\n typeof rootOrOptions === 'string' ? { root: rootOrOptions } : (rootOrOptions ?? {})\n const projectRoot = options.root ?? process.cwd()\n // Backend root (config `serverDir`, default \"server\"). Route/action discovery, typed-client\n // codegen, and the routes HMR watcher all scan under this dir (issue #95). Absolute.\n const serverDirAbs = resolve(projectRoot, options.serverDir ?? 'server')\n // Agents dir NAME (config `agentsDir`, default \"agents\"), relative to projectRoot — scanAgents\n // joins it. May be nested (e.g. \"core/agents\"). (#95 follow-up)\n const agentsDirName = options.agentsDir ?? 'agents'\n\n const consumerTailwindConfig = findConsumerConfig(projectRoot, 'tailwind.config')\n const consumerPostcssConfig = findConsumerConfig(projectRoot, 'postcss.config')\n const uiPlugins = await integrateUseTheoUI(projectRoot, {\n consumerTailwindConfig,\n consumerPostcssConfig,\n })\n\n // Wave 2 (T3.1) — typed-client plugin wired only when services declared.\n // Empty `services: {}` (default) → plugin is a no-op (no fetch fired).\n const servicesPlugins: Plugin[] = []\n if (options.services && Object.keys(options.services).length > 0) {\n const { servicesTypedClientPlugin } = await import('./services-typed-client.js')\n servicesPlugins.push(\n servicesTypedClientPlugin({\n cwd: projectRoot,\n services: options.services,\n }),\n )\n }\n\n // G1 — app typed client (`@theo/client`). Always wired (route detection is\n // cheap and the plugin is a no-op when `server/routes/` is absent).\n const { appTypedClientPlugin } = await import('./app-typed-client.js')\n const appClientPlugin = appTypedClientPlugin({\n cwd: projectRoot,\n serverDir: serverDirAbs,\n distDir: resolve(projectRoot, '.theokit'),\n })\n\n // G3 — actions virtual module (`@theo/actions`). Always wired; the plugin\n // emits an empty `{}` facade when `server/actions/` is absent so consumers\n // can still `import { actions } from '@theo/actions'` without breakage.\n // The `distDir` opt enables `.theokit/actions.d.ts` emit so TS resolves the\n // virtual module ambient declaration in consumer apps.\n const { actionsVirtualModule } = await import('./actions-virtual-module.js')\n const actionsPlugin = actionsVirtualModule({\n serverDir: serverDirAbs,\n distDir: resolve(projectRoot, '.theokit'),\n })\n\n // M2 — agents typed client (`@theo/agents`). Emits `.theokit/agents.d.ts` mapping each\n // top-level `agents/<name>.ts` to its `defineAgent({ input })` type, so `useAgent('name')`\n // is typed end-to-end with zero manual wiring. Watches `agents/*`.\n const { agentsTypedClientPlugin } = await import('./agents-typed-client.js')\n const { generateManifest } = await import('../server/internal-api.js')\n const agentsClientPlugin = agentsTypedClientPlugin({\n projectRoot,\n agentsDir: agentsDirName,\n distDir: resolve(projectRoot, '.theokit'),\n // Agents live at <projectRoot>/<agentsDir>; generateManifest scans them via the server dir's\n // parent (projectRoot for the canonical layout) + the agents dir name (#95 follow-up).\n scanManifest: () => generateManifest(serverDirAbs, projectRoot, agentsDirName),\n })\n\n // G6 T1.2 — server-routes HMR. Watches `<serverDir>/routes/**` and\n // invalidates SSR module cache + sends full-reload on any add/change/unlink\n // with a 50 ms debounce per EC-6.\n const { serverRoutesHmrPlugin } = await import('./server-routes-hmr.js')\n const routesHmrPlugin = serverRoutesHmrPlugin({\n serverDir: serverDirAbs,\n })\n\n // #122 (T1.1) — compile `<serverDir>/controllers/**` through @theokit/http's\n // swc transform so parameter decorators (@Body/@Param/@Query) emit metadata\n // esbuild drops. No-op for every non-controller file (ADR-4 — file-based\n // routes are byte-for-byte unchanged).\n const { controllerSwcTransformPlugin } = await import('./controller-swc-transform.js')\n const controllerTransformPlugin = controllerSwcTransformPlugin({\n serverDir: serverDirAbs,\n })\n\n return [\n theoPlugin(rootOrOptions),\n ...uiPlugins,\n ...servicesPlugins,\n // #122 — swc-compile controllers/** (enforce:'pre'; order-independent).\n controllerTransformPlugin,\n appClientPlugin,\n actionsPlugin,\n agentsClientPlugin,\n routesHmrPlugin,\n ]\n}\n\n/**\n * Build the `optimizeDeps.include` array Vite uses to pre-bundle heavy\n * deps at server startup. Detects `@theokit/ui` and `lucide-react` in\n * the consumer's `node_modules` (auto-include) and appends user-declared\n * peer deps via `viteOptimizeDeps` (e.g., `mermaid` for plugin-canvas\n * — without this hint Vite fails to resolve dynamic `import('mermaid')`\n * inside an installed plugin at dev time). T4.1 of canvas-ecosystem-refactor.\n */\nfunction buildOptimizeDepsInclude(\n projectRoot: string,\n viteOptimizeDeps: readonly string[] | undefined,\n): string[] {\n const include: string[] = []\n if (existsSync(resolve(projectRoot, 'node_modules', '@theokit', 'ui'))) {\n include.push('@theokit/ui')\n }\n if (existsSync(resolve(projectRoot, 'node_modules', 'lucide-react'))) {\n include.push('lucide-react')\n }\n // T7.1 — devalue is a peer of the @theo/actions virtual module facade.\n // Without this include hint, Vite import-analysis fails to resolve the\n // facade's `await import('devalue')` from the consumer context (devalue\n // lives in theokit's node_modules subtree, not the consumer root).\n include.push('devalue')\n if (Array.isArray(viteOptimizeDeps)) {\n for (const pkg of viteOptimizeDeps) {\n if (typeof pkg === 'string' && pkg.length > 0 && !include.includes(pkg)) {\n include.push(pkg)\n }\n }\n }\n return include\n}\n\nconst VIRTUAL_MODULE_IDS: VirtualModuleIds = {\n VIRTUAL_ENTRY_ID,\n RESOLVED_ENTRY_ID,\n VIRTUAL_MANIFEST_ID,\n RESOLVED_MANIFEST_ID,\n VIRTUAL_ENTRY_SERVER_ID,\n RESOLVED_ENTRY_SERVER_ID,\n VIRTUAL_RUNTIME_CONFIG_ID,\n RESOLVED_RUNTIME_CONFIG_ID,\n}\n\nexport function theoPlugin(rootOrOptions?: string | TheoPluginOptions): Plugin {\n const options =\n typeof rootOrOptions === 'string' ? { root: rootOrOptions } : (rootOrOptions ?? {})\n const projectRoot = options.root ?? process.cwd()\n // Frontend dir (config `appDir`, default \"app\") — the file-based router scan + SSR/client entry (#95).\n const appDir = resolve(projectRoot, options.appDir ?? 'app')\n // Backend root (config `serverDir`, default \"server\") — route/action middleware scan under it (#95).\n const serverDir = resolve(projectRoot, options.serverDir ?? 'server')\n // Agents dir NAME (config `agentsDir`, default \"agents\") — the agent-middleware scanAgents uses it.\n const agentsDir = options.agentsDir ?? 'agents'\n const ssrEnabled = options.ssr ?? false\n\n // Resolve paths for SSR module loading. Pure helper extracted for T1.3\n // regression test — see resolve-theo-root.ts for branch documentation.\n const currentDir = dirname(fileURLToPath(import.meta.url))\n const theoSrcDir = resolveTheoRootDir(currentDir)\n\n // EC-1: plugin runner cached in module closure. Instantiated in configResolved\n // (non-HMR-able). theo.config.ts edits during dev emit a warn but do NOT\n // re-instantiate — user must restart dev server for plugin changes.\n let pluginRunner: PluginRunner | undefined\n let transformer: TheoTransformer | undefined\n let resolvedBatching: { max?: number } | undefined\n let theoUi: TheoUiDetectResult | undefined\n let csrfMode: 'off' | 'warn' | 'strict' = 'strict'\n let securityHeaders: SecurityHeadersConfig | undefined\n let disallowed: DisallowedConfig | undefined\n // T1.2 — CORS config resolved from theo.config.ts; passed to api-middleware.\n let cors: CorsConfig | undefined\n // T4.1 — Audit logger from theo.config.ts.audit.logger\n let auditLogger: AuditLogger | undefined\n // T1.2 — devtools opt-out. `false` skips injection; anything else enables (dev only).\n let devtoolsEnabled = true\n // P#3 T1.1 — OpenAPI dev-emit config. undefined = opt-out (no behavior).\n let resolvedOpenApi: ResolvedOpenApi | undefined\n let resolvedDistDir = '.theokit'\n // Dev mode flag set in configureServer. transformIndexHtml runs in both\n // dev and build; we only want to inject during dev. Wrapped in a ref\n // struct so sub-hooks (configure-server-hook, transform-html-hook) can\n // observe mutations across hook boundaries without losing identity.\n const isDevModeRef = { value: false }\n let configLoadedOnce = false\n\n return {\n name: 'theo',\n\n async configResolved() {\n // T2.1 (architecture-medium-deferrals, ADR D2) — config-load logic\n // extracted to `config-resolve.ts`. This hook owns only the one-shot\n // semantic and the closure-variable assignment.\n if (configLoadedOnce) return\n configLoadedOnce = true\n const resolved = await resolvePluginConfig(projectRoot)\n pluginRunner = resolved.pluginRunner\n transformer = resolved.transformer\n resolvedBatching = resolved.resolvedBatching\n theoUi = resolved.theoUi\n csrfMode = resolved.csrfMode\n securityHeaders = resolved.securityHeaders\n disallowed = resolved.disallowed\n cors = resolved.cors\n auditLogger = resolved.auditLogger\n devtoolsEnabled = resolved.devtoolsEnabled\n resolvedOpenApi = resolved.openapi\n resolvedDistDir = resolved.distDir\n },\n\n // T2.6 (M6) — config() body extracted to config-hook.ts. The hook\n // owns optimizeDeps + warmup + services proxy + alias cascade.\n // The @theokit/ui + @tailwindcss/vite auto-chain lives in\n // `theoPluginAsync` because Vite drops plugins returned from a\n // child plugin's config() hook.\n config() {\n return runConfigHook({\n projectRoot,\n theoSrcDir,\n services: options.services,\n optimizeDepsInclude: buildOptimizeDepsInclude(projectRoot, options.viteOptimizeDeps),\n })\n },\n\n // T2.6 (M6) — transformIndexHtml hook extracted to transform-html-hook.ts.\n // Preserves the canonical 3-step order (entry-client → devtools → styles)\n // so EC-10 (Vite hook ordering side effects) is honored.\n transformIndexHtml: {\n order: 'pre' as const,\n handler(html: string): string {\n return runTransformIndexHtml(html, {\n isDevMode: isDevModeRef,\n devtoolsEnabled,\n projectRoot,\n })\n },\n },\n\n // T2.6 (M6) — virtual-module resolveId + load dispatch extracted to\n // virtual-modules-hook.ts. Pure structural split; identity branches\n // preserved.\n resolveId(id: string) {\n return resolveVirtualModuleId(id, VIRTUAL_MODULE_IDS)\n },\n\n load(id: string) {\n return loadVirtualModule(id, {\n ids: VIRTUAL_MODULE_IDS,\n appDir,\n ssrEnabled,\n streamingEnabled: options.ssrStreaming === true,\n theoUi,\n transformer,\n })\n },\n\n // T2.6 (M6) — configureServer body extracted to configure-server-hook.ts.\n // The hook owns middleware order, ws subscriptions, watcher handlers,\n // OpenAPI re-emit, and WS upgrade. EC-10 honored (every effect preserved\n // in its original ordering).\n async configureServer(server) {\n await runConfigureServer(server, {\n projectRoot,\n appDir,\n serverDir,\n agentsDir,\n resolvedDistDir,\n ssrEnabled,\n isDevMode: isDevModeRef,\n pluginRunner,\n transformer,\n resolvedBatching,\n csrfMode,\n securityHeaders,\n disallowed,\n cors,\n auditLogger,\n resolvedOpenApi,\n services: options.services,\n rateLimit: options.rateLimit,\n csrfReadinessStoreOverride: options.csrfReadinessStore,\n virtualEntryServerId: VIRTUAL_ENTRY_SERVER_ID,\n resolvedManifestId: RESOLVED_MANIFEST_ID,\n })\n },\n }\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * config() hook extraction (T2.6 / M6). Reads `app/<file>` candidates +\n * theoSrcDir composition (build-time literals).\n */\nimport { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nimport { buildServicesProxyConfig, type ServicesConfig } from '../services/index.js'\n\nexport interface ConfigHookCtx {\n projectRoot: string\n theoSrcDir: string\n services: ServicesConfig | undefined\n optimizeDepsInclude: string[]\n}\n\n/**\n * Builds the partial Vite config returned from `theoPlugin.config()`.\n * Pure extraction — `optimizeDeps.force: true` (workspace iteration\n * coherence), `server.watch.ignored` (ENOSPC prevention), and the\n * `resolve.alias` cascade with order-matters comment all preserved.\n */\nexport function runConfigHook(ctx: ConfigHookCtx): Record<string, unknown> {\n // Detect whether we're running from source (.ts) or compiled dist (.js)\n const ext = existsSync(resolve(ctx.theoSrcDir, 'index.ts')) ? '.ts' : '.js'\n\n // Perf: warm up the app's critical-path files so Vite transforms them\n // before the browser asks. Cuts the visible LCP when these files\n // import heavy barrels (TheoUI).\n const warmupClientFiles: string[] = []\n for (const candidate of ['app/layout.tsx', 'app/page.tsx', 'app/page.jsx']) {\n const full = resolve(ctx.projectRoot, candidate)\n if (existsSync(full)) warmupClientFiles.push(`./${candidate}`)\n }\n\n // Wave 2 completion T1.1 — translate `services: {}` into Vite proxy.\n // Empty services → empty record → Vite proxy unaffected.\n const servicesProxy =\n ctx.services && Object.keys(ctx.services).length > 0\n ? buildServicesProxyConfig(ctx.services)\n : undefined\n\n // T7.1 dogfood fix — workspace-linked packages change frequently as\n // we iterate. Vite's pre-bundler caches by lockfile hash, NOT source-\n // content hash; when the workspace dist updates but the lockfile\n // doesn't, the cache serves stale bundles. Setting `force: true`\n // always re-optimizes on boot — slower cold-start but cache-coherent\n // across workspace iter.\n return {\n envPrefix: 'THEO_PUBLIC_',\n optimizeDeps: {\n ...(ctx.optimizeDepsInclude.length > 0 ? { include: ctx.optimizeDepsInclude } : {}),\n force: true,\n },\n server: {\n ...(warmupClientFiles.length > 0 ? { warmup: { clientFiles: warmupClientFiles } } : {}),\n ...(servicesProxy !== undefined ? { proxy: servicesProxy } : {}),\n // Skip watching gitignored heavy dirs to avoid ENOSPC (inotify watcher\n // exhaustion), theokit's own generated output, and local SQLite data.\n // #121: a DB write (`.data/app.db` + `-wal`/`-shm`) on every agent turn /\n // request must NOT trigger a full page reload — that \"blinks\" the screen\n // and tears down the in-flight agent stream.\n watch: {\n ignored: [\n '**/referencias/**',\n '**/.theokit/**',\n '**/dist/**',\n '**/node_modules/**',\n '**/.data/**',\n '**/*.db',\n '**/*.db-wal',\n '**/*.db-shm',\n '**/*.sqlite',\n '**/*.sqlite-journal',\n ],\n },\n },\n resolve: {\n alias: [\n // Order matters: most-specific first so `theokit/X` doesn't\n // get matched by the bare `theokit` alias.\n { find: 'theokit/server', replacement: resolve(ctx.theoSrcDir, `server/index${ext}`) },\n { find: 'theokit/client', replacement: resolve(ctx.theoSrcDir, `client/index${ext}`) },\n {\n // T2.1 (M5 lonely folders) moved the source from\n // `react-query/index.ts` into `client/react-query.ts` (sibling of\n // `client/index.ts`). The package.json export `./react-query`\n // still points at the build artifact `./dist/react-query/index.{js,d.ts}`,\n // but the dev-time source alias must follow the new location.\n find: 'theokit/react-query',\n replacement: resolve(ctx.theoSrcDir, `client/react-query${ext}`),\n },\n {\n find: 'theokit/vite-plugin',\n replacement: resolve(ctx.theoSrcDir, `vite-plugin/index${ext}`),\n },\n {\n find: 'theokit/adapters/web-shim',\n replacement: resolve(ctx.theoSrcDir, `adapters/web-shim${ext}`),\n },\n {\n find: 'theokit/adapters/ws-shim',\n replacement: resolve(ctx.theoSrcDir, `adapters/ws-shim${ext}`),\n },\n // T1.2 — devtools entry (DEV only; tree-shaken in build).\n // Source layout: src/devtools/dom/entry.tsx (has /dom/ segment)\n // Dist layout: dist/devtools/entry.js (tsup flattens /dom/)\n {\n find: 'theokit/devtools/entry',\n replacement: resolve(\n ctx.theoSrcDir,\n ext === '.ts' ? 'devtools/dom/entry.tsx' : 'devtools/entry.js',\n ),\n },\n { find: 'theokit', replacement: resolve(ctx.theoSrcDir, `index${ext}`) },\n ],\n },\n }\n}\n","/**\n * T2.1 — Detect `@theokit/ui` presence in the user's project.\n *\n * Uses `require.resolve` with explicit `paths` instead of `existsSync` so\n * pnpm-hoist layouts (TheoUI at workspace root, app in `apps/<x>/`) still\n * detect correctly. Returns `{ enabled: false }` on any failure — never throws.\n */\n\n/* eslint-disable security/detect-non-literal-fs-filename --\n * Reads `package.json` of `@theokit/ui` via filesystem walk under `node_modules`.\n * Paths come from a controlled CLI/config inputs; this is a build-time tool.\n *\n * D13 invariant (ADR 0021): @theokit/ui is ESM-only by design (`type: \"module\"`,\n * exports['.'] sem `require` condition). Não usar `createRequire(...).resolve()` —\n * `ERR_PACKAGE_PATH_NOT_EXPORTED` em runtime. Usar filesystem walk direto.\n */\nimport { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\n\nexport type TheoUiTheme = 'violet-forge' | 'noir' | 'paper'\nexport type TheoUiFonts = 'bundled' | 'cdn'\n\nexport interface TheoUiConfig {\n theme: TheoUiTheme\n fonts: TheoUiFonts\n}\n\nexport interface TheoUiDetectResult {\n enabled: boolean\n config: TheoUiConfig\n}\n\n/**\n * Raw user config shape (from theo.config.ts > ui field).\n * `false` = opt-out (force disabled); object = explicit config; undefined = default.\n */\nexport type RawTheoUiConfig = false | undefined | { theme?: TheoUiTheme; fonts?: TheoUiFonts }\n\n/**\n * Resolve the TheoUI config with defaults applied.\n * `false` → returns disabled defaults (caller checks `enabled`).\n */\nexport function resolveTheoUiConfig(\n raw: { theme?: TheoUiTheme; fonts?: TheoUiFonts } | undefined,\n): TheoUiConfig {\n return {\n theme: raw?.theme ?? 'violet-forge',\n fonts: raw?.fonts ?? 'bundled',\n }\n}\n\n/**\n * Detect whether `@theokit/ui` is installed under `projectRoot` (or any\n * parent dir via Node module resolution — handles pnpm hoist).\n *\n * EC-1: uses `require.resolve` with `paths: [projectRoot]` not `existsSync`.\n * EC-5: corrupted installs (dir without an importable entry) fall through to disabled.\n * EC-9: theme validation happens in the Zod schema, not here.\n *\n * Note: we resolve a known subpath (`./styles.css`) instead of `./package.json`\n * or the root specifier because (a) `@theokit/ui` declares `exports` with no\n * CJS entry, so `require.resolve('@theokit/ui')` fails inside CJS contexts,\n * and (b) `./package.json` is not listed in `exports`. The `styles.css`\n * subpath IS exported and is exactly what entry-client imports — if it\n * resolves, the package is installed and usable.\n */\n/** Resolver fn — abstracted so tests can stub Node's walk-up behavior. */\nexport type SubpathResolver = (specifier: string, projectRoot: string) => boolean\n\n/**\n * D13 invariant: substituir `require.resolve` por filesystem walk que LÊ exports.\n *\n * Specifier shape: `<pkgScope>/<pkgName>/<subpath>` (e.g. `@theokit/ui/styles.css`)\n * OR `<pkgName>/<subpath>` (e.g. `react/jsx-runtime`).\n *\n * Algoritmo:\n * 1. Walk up node_modules a partir de projectRoot (handle pnpm hoist + workspaces).\n * 2. Em cada candidato, ler package.json + resolver subpath via exports field.\n * 3. Se exports mapeia o subpath, checar existsSync no path mapeado.\n *\n * Mimica resolução ESM Node sem usar createRequire (D13).\n */\nfunction resolveExportSubpath(pkgRoot: string, subpath: string): string | null {\n const pkgJsonPath = join(pkgRoot, 'package.json')\n if (!existsSync(pkgJsonPath)) return null\n try {\n const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf-8')) as {\n exports?: Record<string, unknown>\n }\n const exportKey = `./${subpath}`\n const exp = pkg.exports?.[exportKey]\n if (!exp) {\n // Fallback: tentar path direto (dist/<subpath> é convenção comum)\n const fallback = join(pkgRoot, 'dist', subpath)\n return existsSync(fallback) ? fallback : null\n }\n // exports value: string OR { import, require, default, types, ... }\n let target: string | undefined\n if (typeof exp === 'string') target = exp\n else if (typeof exp === 'object') {\n const e = exp as { import?: string; default?: string }\n target = e.import ?? e.default\n }\n if (!target) return null\n const cleaned = target.replace(/^\\.\\//, '')\n const candidate = join(pkgRoot, cleaned)\n return existsSync(candidate) ? candidate : null\n } catch {\n return null\n }\n}\n\nconst defaultResolver: SubpathResolver = (specifier, projectRoot) => {\n const parts = specifier.split('/')\n const pkgName =\n parts[0]?.startsWith('@') && parts.length >= 2 ? `${parts[0]}/${parts[1]}` : parts[0]\n if (!pkgName) return false\n const subpath = specifier.slice(pkgName.length + 1)\n if (!subpath) return false\n // Walk up node_modules (handle pnpm hoist)\n let dir = projectRoot\n for (let depth = 0; depth < 10; depth++) {\n const pkgRoot = join(dir, 'node_modules', ...pkgName.split('/'))\n if (existsSync(pkgRoot)) {\n const resolved = resolveExportSubpath(pkgRoot, subpath)\n if (resolved) return true\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n return false\n}\n\n/** Reads `<projectRoot>/package.json` and returns whether `@theokit/ui`\n * is declared as a (dev)dependency. Conservative gate: pnpm hoist still\n * works because pnpm rewrites the consumer's package.json to include the\n * declared dep, even when the install lives at the workspace root. */\nfunction isDeclaredInPackageJson(projectRoot: string): boolean {\n try {\n const raw = readFileSync(join(projectRoot, 'package.json'), 'utf-8')\n const pkg = JSON.parse(raw) as {\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n peerDependencies?: Record<string, string>\n }\n // `||` is intentional — any truthy version string (including '0.0.0')\n // counts as a declaration. `??` would let '' fall through, but version\n // strings are never empty.\n return Boolean(\n pkg.dependencies?.['@theokit/ui'] ??\n pkg.devDependencies?.['@theokit/ui'] ??\n pkg.peerDependencies?.['@theokit/ui'],\n )\n } catch {\n return false\n }\n}\n\nexport function detectTheoUi(\n projectRoot: string,\n rawConfig: RawTheoUiConfig,\n resolver: SubpathResolver = defaultResolver,\n): TheoUiDetectResult {\n const config = resolveTheoUiConfig(typeof rawConfig === 'object' ? rawConfig : undefined)\n\n // Explicit opt-out wins over detection\n if (rawConfig === false) {\n return { enabled: false, config }\n }\n\n // **Conservative gate** — require the dep to be DECLARED in the user's\n // package.json. Stops the monorepo workspace from being detected as\n // having TheoUI inside fixtures that never asked for it (and would\n // 500 on the import).\n if (!isDeclaredInPackageJson(projectRoot)) {\n return { enabled: false, config }\n }\n\n // EC-1 + EC-5: prefer a subpath that's guaranteed to be in `exports`.\n // Try several known subpaths; success on any one means the package is usable.\n const probes = ['@theokit/ui/styles.css', '@theokit/ui/fonts.css']\n for (const probe of probes) {\n if (resolver(probe, projectRoot)) {\n return { enabled: true, config }\n }\n }\n return { enabled: false, config }\n}\n","/**\n * T2.1 (architecture-medium-deferrals plan, ADR D2) — `configResolved` hook\n * body extracted from `vite-plugin/index.ts` for SRP.\n *\n * `resolvePluginConfig(projectRoot)` reads `theo.config.ts` and returns a\n * `ResolvedPluginConfig` bag with every field the Vite plugin needs at\n * `configResolved` time. The `configLoadedOnce` flag stays in `index.ts`\n * (caller owns the one-shot semantic).\n *\n * Errors during config load are swallowed silently (matches pre-refactor\n * behavior — config errors are surfaced elsewhere via validate-structure).\n */\n\nimport { loadConfig } from '../config/load-config.js'\nimport {\n createPluginRunnerFromConfig,\n type AuditLogger,\n type CorsConfig,\n type DisallowedConfig,\n type PluginRunner,\n type SecurityHeadersConfig,\n} from '../server/internal-api.js'\nimport { resolveTransformer, type TheoTransformer } from '../server/transformer.js'\n\nimport { detectTheoUi, type TheoUiDetectResult } from './theoui-detect.js'\n\nexport interface ResolvedOpenApi {\n servers: { url: string; description?: string }[]\n specVersion: '3.1.0' | '3.0.3'\n title: string\n version: string\n}\n\nexport interface ResolvedPluginConfig {\n pluginRunner: PluginRunner | undefined\n transformer: TheoTransformer | undefined\n resolvedBatching: { max?: number } | undefined\n theoUi: TheoUiDetectResult | undefined\n csrfMode: 'off' | 'warn' | 'strict'\n securityHeaders: SecurityHeadersConfig | undefined\n disallowed: DisallowedConfig | undefined\n cors: CorsConfig | undefined\n auditLogger: AuditLogger | undefined\n devtoolsEnabled: boolean\n // P#3 T1.1 — undefined when config.openapi opt-out; otherwise validated config block\n openapi: ResolvedOpenApi | undefined\n // P#3 T1.1 — distDir resolved relative to projectRoot for openapi-emit output\n distDir: string\n}\n\n/**\n * Default config when load fails — keeps the plugin running with safe defaults.\n */\nconst DEFAULT_RESOLVED: ResolvedPluginConfig = {\n pluginRunner: undefined,\n transformer: undefined,\n resolvedBatching: undefined,\n theoUi: undefined,\n csrfMode: 'strict',\n securityHeaders: undefined,\n disallowed: undefined,\n cors: undefined,\n auditLogger: undefined,\n devtoolsEnabled: true,\n openapi: undefined,\n distDir: '.theokit',\n}\n\nexport async function resolvePluginConfig(projectRoot: string): Promise<ResolvedPluginConfig> {\n try {\n const userConfig = await loadConfig(projectRoot)\n const pluginRunner = await createPluginRunnerFromConfig(userConfig.plugins)\n const transformer = resolveTransformer(userConfig.serialization)\n\n // Batching: Zod admits `boolean | { max?: number }`; normalize to object.\n let resolvedBatching: { max?: number } | undefined\n if (userConfig.batching === true) {\n resolvedBatching = {}\n } else if (typeof userConfig.batching === 'object') {\n resolvedBatching = userConfig.batching\n }\n\n const theoUi = detectTheoUi(projectRoot, userConfig.ui)\n\n // Audit logger — duck-type validation (consumer may pass any shape with `log()`).\n let auditLogger: AuditLogger | undefined\n const maybeLogger = (userConfig as { audit?: { logger?: unknown } }).audit?.logger\n if (maybeLogger && typeof (maybeLogger as { log?: unknown }).log === 'function') {\n auditLogger = maybeLogger as AuditLogger\n }\n\n return {\n pluginRunner,\n transformer,\n resolvedBatching,\n theoUi,\n csrfMode: userConfig.security?.csrf ?? 'strict',\n securityHeaders: userConfig.security?.headers,\n disallowed: userConfig.security?.disallowed,\n cors: userConfig.security?.cors,\n auditLogger,\n devtoolsEnabled: userConfig.devtools !== false,\n openapi: userConfig.openapi,\n distDir: userConfig.distDir,\n }\n } catch {\n // Config load errors are surfaced elsewhere (validate-structure).\n // Return safe defaults so middlewares can run without hooks.\n return DEFAULT_RESOLVED\n }\n}\n","import { resolve, basename } from 'node:path'\n\nimport type { ViteDevServer } from 'vite'\n\nimport { broadcastRouteManifest } from '../devtools/server-side/route-manifest.js'\nimport { scanRoutes } from '../router/scan.js'\nimport { isRouteFile } from '../router/types.js'\nimport {\n CsrfReadinessStore,\n type AuditLogger,\n type CorsConfig,\n type DisallowedConfig,\n type PluginRunner,\n type RateLimitConfig,\n type SecurityHeadersConfig,\n} from '../server/internal-api.js'\nimport type { TheoTransformer } from '../server/transformer.js'\nimport type { ServicesConfig } from '../services/index.js'\n\nimport { createActionMiddleware } from './action-middleware.js'\nimport { createAgentMiddleware } from './agent-middleware.js'\nimport { createApiMiddleware } from './api-middleware.js'\nimport type { ResolvedOpenApi } from './config-resolve.js'\nimport { setupSsrDevMiddleware } from './ssr-dev-middleware.js'\nimport { setupWsUpgrade } from './ws-upgrade.js'\n\n/**\n * Inputs assembled by `theoPlugin` from its closure variables + the\n * resolvedOpenApi from `config-resolve.ts`. Kept as a struct so the\n * extraction is a pure pass-through with no behavior change.\n */\nexport interface ConfigureServerCtx {\n projectRoot: string\n appDir: string\n /** Absolute backend root (config `serverDir`, default `<projectRoot>/server`) — route/action scan (#95). */\n serverDir: string\n /** Agents dir NAME (config `agentsDir`, default \"agents\") relative to projectRoot — agent-middleware scan. */\n agentsDir: string\n resolvedDistDir: string\n ssrEnabled: boolean\n isDevMode: { value: boolean }\n pluginRunner: PluginRunner | undefined\n transformer: TheoTransformer | undefined\n resolvedBatching: { max?: number } | undefined\n csrfMode: 'off' | 'warn' | 'strict'\n securityHeaders: SecurityHeadersConfig | undefined\n disallowed: DisallowedConfig | undefined\n cors: CorsConfig | undefined\n auditLogger: AuditLogger | undefined\n resolvedOpenApi: ResolvedOpenApi | undefined\n services: ServicesConfig | undefined\n rateLimit: RateLimitConfig | undefined\n csrfReadinessStoreOverride: CsrfReadinessStore | undefined\n virtualEntryServerId: string\n resolvedManifestId: string\n}\n\n/**\n * Runs the body of Vite's `configureServer` hook. Pure extraction —\n * preserves invocation order of every server.watcher event, middleware\n * registration, and ws hook so EC-10 (Vite hook ordering side effects)\n * is honored.\n */\n\nexport async function runConfigureServer(\n server: ViteDevServer,\n ctx: ConfigureServerCtx,\n): Promise<void> {\n // T1.2 — mark dev mode so transformIndexHtml injects devtools script\n // and resolveId/load serve the virtual module. Build mode never calls\n // configureServer, so isDevMode stays false and injection is skipped.\n ctx.isDevMode.value = true\n\n // T2.4 — expose dev server WS to server-side broadcast helper\n ;(globalThis as { __theoViteHotServer?: typeof server }).__theoViteHotServer = server\n\n // T3.1 — re-broadcast the route manifest when the devtools bridge asks.\n server.ws.on('theo:devtools:request-manifest', () => {\n try {\n const tree = scanRoutes(ctx.appDir)\n broadcastRouteManifest(tree)\n } catch {\n /* fail silently — dev-only convenience */\n }\n })\n\n // Server middleware (action before API — more specific prefix first). `serverDir` honors the\n // config `serverDir` (default `<projectRoot>/server`) — no longer hardcoded (#95).\n const serverDir = ctx.serverDir\n server.middlewares.use(\n createActionMiddleware(server, serverDir, {\n pluginRunner: ctx.pluginRunner,\n csrfMode: ctx.csrfMode,\n disallowed: ctx.disallowed,\n }),\n )\n // M2 — agent convention (`/api/agents/<name>`) before the generic api-middleware\n // (mirrors the action prefix). Agents live at <projectRoot>/agents (LOCKED naming).\n // CSRF is enforced in `mountAgent` (shared dev+prod point) at the same mode as routes.\n server.middlewares.use(\n createAgentMiddleware(server, ctx.projectRoot, ctx.csrfMode, ctx.agentsDir),\n )\n // Wave 2 completion — services-proxy prefixes flow through to the\n // api-middleware so it can call `next()` for paths that should be\n // forwarded to a sidecar by Vite's proxyMiddleware.\n const servicesProxyPrefixes =\n ctx.services && Object.keys(ctx.services).length > 0\n ? Object.values(ctx.services).map((s) => s.proxy)\n : []\n // Auto-instantiate a dev-only CsrfReadinessStore so the devtools\n // CSRF Readiness tab works out-of-the-box.\n const csrfReadinessStore = ctx.csrfReadinessStoreOverride ?? new CsrfReadinessStore()\n server.middlewares.use(\n createApiMiddleware(server, serverDir, {\n rateLimitConfig: ctx.rateLimit,\n pluginRunner: ctx.pluginRunner,\n batching: ctx.resolvedBatching,\n transformer: ctx.transformer,\n csrfMode: ctx.csrfMode,\n securityHeaders: ctx.securityHeaders,\n disallowed: ctx.disallowed,\n cors: ctx.cors,\n auditLogger: ctx.auditLogger,\n servicesProxyPrefixes,\n csrfReadinessStore,\n }),\n )\n\n // EC-1: warn if theo.config.ts is edited during dev session.\n const configPath = resolve(ctx.projectRoot, 'theo.config.ts')\n server.watcher.on('change', (file) => {\n if (file === configPath) {\n console.warn(\n '\\n[theokit] theo.config.ts changed; restart dev server for plugin changes to take effect\\n',\n )\n }\n })\n\n // T2.2 (architecture-medium-deferrals) — SSR dev middleware extracted.\n if (ctx.ssrEnabled) {\n setupSsrDevMiddleware(server, {\n projectRoot: ctx.projectRoot,\n virtualEntryServerId: ctx.virtualEntryServerId,\n securityHeaders: ctx.securityHeaders,\n })\n }\n\n // Frontend HMR watcher\n function handleRouteChange(filePath: string): void {\n if (!isRouteFile(basename(filePath))) return\n if (!filePath.startsWith(ctx.appDir)) return\n\n const mod = server.moduleGraph.getModuleById(ctx.resolvedManifestId)\n if (mod) {\n server.moduleGraph.invalidateModule(mod)\n server.ws.send({ type: 'full-reload' })\n }\n }\n\n server.watcher.on('add', handleRouteChange)\n server.watcher.on('unlink', handleRouteChange)\n\n // P#3 T1.1 — Dev-mode OpenAPI emit. Gated on config.openapi !== undefined.\n if (ctx.resolvedOpenApi !== undefined) {\n const openApiCfg = ctx.resolvedOpenApi\n const { reEmitOpenApi } = await import('./openapi-emit/dev-emit.js')\n // #95 — the OpenAPI dev-emit scans the SAME backend root as the route middleware (honor serverDir).\n const openApiServerDir = ctx.serverDir\n const openApiDistDir = resolve(ctx.projectRoot, ctx.resolvedDistDir)\n const isRouteFileForOpenApi = (file: string): boolean =>\n file.startsWith(openApiServerDir) && /\\.(ts|tsx|js|mjs)$/.test(file)\n // Boot emit (fire-and-forget — boot doesn't await)\n void reEmitOpenApi(openApiServerDir, openApiDistDir, openApiCfg)\n // Watcher emit\n server.watcher.on('change', (file: string) => {\n if (isRouteFileForOpenApi(file)) {\n void reEmitOpenApi(openApiServerDir, openApiDistDir, openApiCfg)\n }\n })\n server.watcher.on('add', (file: string) => {\n if (isRouteFileForOpenApi(file)) {\n void reEmitOpenApi(openApiServerDir, openApiDistDir, openApiCfg)\n }\n })\n server.watcher.on('unlink', (file: string) => {\n if (isRouteFileForOpenApi(file)) {\n void reEmitOpenApi(openApiServerDir, openApiDistDir, openApiCfg)\n }\n })\n }\n\n // T2.3 (architecture-medium-deferrals) — WS upgrade extracted to sibling.\n setupWsUpgrade(server, ctx.projectRoot)\n\n // T2.4 — clear devtools WS reference on shutdown\n server.httpServer?.once('close', () => {\n ;(globalThis as { __theoViteHotServer?: unknown }).__theoViteHotServer = undefined\n })\n}\n","/**\n * T3.1 — Translate the server-side RouteNode tree into the devtools-facing\n * RouteManifest shape, then broadcast over the HMR bridge.\n *\n * No-op in production / when no dev server is attached.\n *\n * NEVER use dangerouslySetInnerHTML in any devtools component — see plan EC-20.\n */\nimport type { RouteNode } from '../../core/contracts/route-node.js'\nimport type { RouteInfo, RouteManifest } from '../shared.js'\n\nimport { broadcastToDevtools } from './broadcast.js'\n\ninterface FlattenAccumulator {\n routes: RouteInfo[]\n}\n\nfunction buildPath(parents: string[], segment: string): string {\n const joined = [...parents, segment].filter(Boolean).join('/')\n return '/' + joined\n}\n\nfunction walk(\n node: RouteNode,\n parents: string[],\n layoutChain: string[],\n acc: FlattenAccumulator,\n): void {\n const path = buildPath(parents, node.segment)\n // Layout file (if any) joins the chain for any descendant page.\n const nextChain = node.layout ? [...layoutChain, node.layout] : layoutChain\n\n if (node.page) {\n acc.routes.push({\n path,\n absoluteFilePath: node.page,\n layoutChain: [...layoutChain], // freeze chain at this leaf\n hasLoading: Boolean(node.loading),\n hasError: Boolean(node.error),\n hasNotFound: Boolean(node.notFound),\n })\n }\n\n for (const child of node.children) {\n const nextParents = node.segment ? [...parents, node.segment] : parents\n walk(child, nextParents, nextChain, acc)\n }\n}\n\n/**\n * Pure helper: convert RouteNode tree → RouteManifest for the devtools UI.\n * Exported for testing.\n */\nexport function buildRouteManifest(tree: RouteNode): RouteManifest {\n const acc: FlattenAccumulator = { routes: [] }\n walk(tree, [], [], acc)\n return { routes: acc.routes }\n}\n\n/**\n * Broadcast the manifest to the devtools UI over the HMR bridge.\n * Safe to call from any dev-server context — no-op in production.\n */\nexport function broadcastRouteManifest(tree: RouteNode): void {\n const manifest = buildRouteManifest(tree)\n broadcastToDevtools('theo:devtools:manifest', manifest)\n}\n","import { randomUUID } from 'node:crypto'\n\nimport type { ViteDevServer, Connect } from 'vite'\n\nimport {\n createViteLoader,\n executeAction,\n findSuggestion,\n logRequest,\n scanServerActions,\n sendError,\n type CsrfMode,\n type DisallowedConfig,\n type PluginRunner,\n} from '../server/internal-api.js'\n\nconst PREFIX = '/api/__actions/'\n\nexport interface ActionMiddlewareOptions {\n pluginRunner?: PluginRunner\n /**\n * CSRF mode passed through to `executeAction`. Parity with the route\n * middleware — actions inherit the same warn/strict policy as routes.\n * Defaults to 'strict' (the 0.3.0 default).\n */\n csrfMode?: CsrfMode\n /**\n * T5.1 — Rails-inspired per-route escalation. Forwarded to `executeAction`.\n */\n disallowed?: DisallowedConfig\n}\n\nexport function createActionMiddleware(\n vite: ViteDevServer,\n serverDir: string,\n options?: ActionMiddlewareOptions,\n): Connect.NextHandleFunction {\n const loadModule = createViteLoader(vite)\n const pluginRunner = options?.pluginRunner\n const csrfMode: CsrfMode = options?.csrfMode ?? 'strict'\n const disallowed = options?.disallowed\n return (req, res, next) => {\n void (async () => {\n const url = req.url ?? ''\n if (!url.startsWith(PREFIX)) {\n next()\n return\n }\n\n const requestId = randomUUID()\n const start = Date.now()\n res.setHeader('x-request-id', requestId)\n\n const pathAfterPrefix = url.slice(PREFIX.length).split('?')[0]\n const segments = pathAfterPrefix.split('/').filter(Boolean)\n\n if (segments.length < 2) {\n sendError(\n res,\n 'BAD_REQUEST',\n 'Action URL must be /api/__actions/{file}/{exportName}',\n 400,\n undefined,\n requestId,\n )\n logRequest({\n method: req.method ?? 'POST',\n url,\n status: 400,\n duration: Date.now() - start,\n requestId,\n })\n return\n }\n\n const exportName = segments[segments.length - 1]\n const actionPath = segments.slice(0, -1).join('/')\n\n const actions = scanServerActions(serverDir)\n const action = actions.find((a) => a.actionPath === actionPath)\n\n if (!action) {\n const actionPaths = actions.map((a) => a.actionPath)\n const suggestion = findSuggestion(actionPath, actionPaths)\n const msg = suggestion\n ? `Action file \"${actionPath}\" not found. Did you mean: ${suggestion}?`\n : `Action file \"${actionPath}\" not found`\n sendError(res, 'NOT_FOUND', msg, 404, undefined, requestId)\n logRequest({\n method: req.method ?? 'POST',\n url,\n status: 404,\n duration: Date.now() - start,\n requestId,\n })\n return\n }\n\n await executeAction(\n action.filePath,\n exportName,\n req,\n res,\n loadModule,\n serverDir,\n requestId,\n pluginRunner,\n csrfMode,\n disallowed,\n )\n logRequest(\n {\n method: req.method ?? 'POST',\n url,\n status: res.statusCode,\n duration: Date.now() - start,\n requestId,\n },\n undefined,\n req,\n )\n })()\n }\n}\n","/**\n * M2 (theokit-ai-first) — dev middleware for the `agents/<name>.ts` convention.\n *\n * Serves `POST /api/agents/<name>` in `theokit dev` by scanning the top-level `agents/`\n * directory on each request, loading the matched module via Vite's SSR loader, and\n * streaming the M0/M1 UIMessageStream through `mountAgent` — the SAME wiring point the\n * prod server uses (`start/handlers.ts` `tryServeAgent`), so dev and build never drift.\n *\n * Registered under the reserved `/api/agents/` prefix BEFORE the generic api-middleware\n * (mirrors how the action middleware owns `/api/__actions/`); an unmatched agent path\n * falls through to `next()` so the api-middleware can 404 it consistently.\n */\nimport { randomUUID } from 'node:crypto'\nimport type { ServerResponse } from 'node:http'\n\nimport type { ViteDevServer, Connect } from 'vite'\n\nimport { isAgentCardPath } from '../server/agent/agent-card-handler.js'\nimport { getApprovalRegistry } from '../server/agent/approval-registry.js'\nimport { handleAgentApproval, isApprovalPath } from '../server/agent/approve-agent.js'\nimport { isListApprovalsPath } from '../server/agent/list-approvals-handler.js'\nimport { isMcpPath } from '../server/agent/mcp-handler.js'\nimport { mountAgent } from '../server/agent/mount-agent.js'\nimport { resolveProvider } from '../server/agent/provider-resolver.js'\nimport { serveAgentAuxRoute } from '../server/agent/serve-aux-routes.js'\nimport {\n incomingMessageToWebRequest,\n writeWebResponseToServerResponse,\n} from '../server/http/node-web-adapter.js'\nimport {\n createViteLoader,\n logRequest,\n scanAgents,\n sendError,\n type CsrfMode,\n} from '../server/internal-api.js'\n\nconst PREFIX = '/api/agents/'\n\n/**\n * M15 — serve `/.well-known/<name>/agent-card.json` (GET) if the request matches. Returns `true`\n * when it owned the request (responded or fell through to `next()`), `false` to let the caller\n * continue. Extracted from the middleware arrow to keep that function within the complexity budget.\n */\ninterface CardDeps {\n projectRoot: string\n loadModule: (filePath: string) => Promise<unknown>\n agentsDir: string\n /** M34 (#97) — CSRF mode threaded to the MCP aux route (which drives the agent → spends tokens). */\n csrfMode: CsrfMode\n}\n\n/** M4 — serve the HITL approve route `/api/agents/<name>/approve/<id>` (already matched). */\nasync function serveApprove(\n req: Connect.IncomingMessage,\n res: ServerResponse,\n urlPath: string,\n csrfMode: CsrfMode,\n log: { requestId: string; start: number },\n): Promise<void> {\n const method = (req.method ?? 'POST').toUpperCase()\n if (method !== 'POST') {\n sendError(\n res,\n 'METHOD_NOT_ALLOWED',\n 'Approve endpoints accept POST',\n 405,\n undefined,\n log.requestId,\n )\n logRequest({\n method,\n url: req.url ?? '',\n status: 405,\n duration: Date.now() - log.start,\n requestId: log.requestId,\n })\n return\n }\n try {\n const response = await handleAgentApproval(\n incomingMessageToWebRequest(req),\n urlPath,\n getApprovalRegistry(),\n csrfMode,\n )\n await writeWebResponseToServerResponse(response, res)\n } catch (err) {\n sendError(\n res,\n 'INTERNAL',\n err instanceof Error ? err.message : 'Approve handler failed',\n 500,\n undefined,\n log.requestId,\n )\n }\n logRequest({\n method,\n url: req.url ?? '',\n status: res.statusCode,\n duration: Date.now() - log.start,\n requestId: log.requestId,\n })\n}\n\n/**\n * M15/M16/M14 — serve an agent AUXILIARY route (agent card / MCP / pending-approvals listing) via\n * the shared `serveAgentAuxRoute` dispatcher (the SAME one `theokit start`'s `tryServeAgentAux`\n * uses, so dev and prod never drift). Falls through to `next()` when the path is not an aux route,\n * the method is wrong, or the agent is unknown.\n */\nasync function serveAux(\n req: Connect.IncomingMessage,\n res: ServerResponse,\n next: Connect.NextFunction,\n urlPath: string,\n deps: CardDeps,\n): Promise<void> {\n const requestId = randomUUID()\n const start = Date.now()\n try {\n const request = incomingMessageToWebRequest(req)\n const response = await serveAgentAuxRoute(request, urlPath, {\n agents: scanAgents(deps.projectRoot, deps.agentsDir),\n loadModule: deps.loadModule,\n baseUrl: `http://${req.headers.host ?? 'localhost'}`,\n csrfMode: deps.csrfMode,\n // M39 — the thread follow-up route drives the agent; resolve the key on demand.\n resolveApiKey: () => resolveProvider().apiKey,\n })\n if (response === null) {\n next()\n return\n }\n res.setHeader('x-request-id', requestId)\n await writeWebResponseToServerResponse(response, res)\n } catch (err) {\n res.setHeader('x-request-id', requestId)\n sendError(\n res,\n 'INTERNAL',\n err instanceof Error ? err.message : 'Agent aux handler failed',\n 500,\n undefined,\n requestId,\n )\n }\n logRequest({\n method: (req.method ?? 'GET').toUpperCase(),\n url: req.url ?? '',\n status: res.statusCode,\n duration: Date.now() - start,\n requestId,\n })\n}\n\nexport function createAgentMiddleware(\n vite: ViteDevServer,\n projectRoot: string,\n csrfMode: CsrfMode = 'strict',\n agentsDir = 'agents',\n): Connect.NextHandleFunction {\n const loadModule = createViteLoader(vite)\n return (req, res, next) => {\n void (async () => {\n const url = req.url ?? ''\n\n // M15 — A2A agent card at `/.well-known/<name>/agent-card.json` (GET). The match check is\n // SYNC so a non-card request still calls `next()` synchronously (no `await` before it — a\n // dev-middleware contract some tests rely on); only a real card path enters the async path.\n if (isAgentCardPath(url.split('?')[0]) !== null) {\n await serveAux(req, res, next, url.split('?')[0], {\n projectRoot,\n loadModule,\n agentsDir,\n csrfMode,\n })\n return\n }\n\n if (!url.startsWith(PREFIX)) {\n next()\n return\n }\n\n const requestId = randomUUID()\n const start = Date.now()\n res.setHeader('x-request-id', requestId)\n\n const urlPath = url.split('?')[0]\n\n // HITL approve route (`/api/agents/<name>/approve/<id>`, M4) — resolve the pending approval.\n // Branches BEFORE the agent-path exact match (the approve path never equals an `agentPath`).\n // Extracted to keep this arrow within the complexity budget (G6).\n if (isApprovalPath(urlPath)) {\n await serveApprove(req, res, urlPath, csrfMode, { requestId, start })\n return\n }\n\n // M14 (list approvals) + M16 (MCP) — both are agent aux routes served by the shared\n // dispatcher. Branch BEFORE the agent exact-match (neither path equals an `agentPath`).\n if (isListApprovalsPath(urlPath) !== null || isMcpPath(urlPath) !== null) {\n await serveAux(req, res, next, urlPath, { projectRoot, loadModule, agentsDir, csrfMode })\n return\n }\n\n const agent = scanAgents(projectRoot, agentsDir).find((a) => a.agentPath === urlPath)\n if (!agent) {\n // Not a known agent — let the api-middleware own the 404 (single 404 shape).\n next()\n return\n }\n\n const method = (req.method ?? 'POST').toUpperCase()\n if (method !== 'POST') {\n sendError(\n res,\n 'METHOD_NOT_ALLOWED',\n 'Agent endpoints accept POST',\n 405,\n undefined,\n requestId,\n )\n logRequest({ method, url, status: 405, duration: Date.now() - start, requestId })\n return\n }\n\n try {\n const mod = await loadModule(agent.filePath)\n const apiKey = resolveProvider().apiKey\n const request = incomingMessageToWebRequest(req)\n const response = await mountAgent(mod, request, apiKey, {\n source: agent.filePath,\n csrfMode,\n projectRoot,\n })\n await writeWebResponseToServerResponse(response, res)\n } catch (err) {\n sendError(\n res,\n 'INTERNAL',\n err instanceof Error ? err.message : 'Agent handler failed',\n 500,\n undefined,\n requestId,\n )\n }\n logRequest({ method, url, status: res.statusCode, duration: Date.now() - start, requestId })\n })()\n }\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { resolve } from 'node:path'\n\nimport type { ViteDevServer, Connect } from 'vite'\n\nimport {\n BATCH_PATH,\n CSP_REPORT_PATH,\n TRACE_HEADER,\n applySecurityHeaders,\n createCorsHandler,\n createRateLimiter,\n createViteLoader,\n executeRoute,\n extractTraceId,\n findSuggestion,\n handleBatchRequest,\n handleCspReport,\n handleCsrfReadiness,\n incomingMessageToHandlerRequest,\n logRequest,\n dispatchControllerRequest,\n mountAgent,\n resolveProvider,\n matchRoute,\n scanServerRoutes,\n sendError,\n type AuditLogger,\n type CorsConfig,\n type CspReportHandlerOptions,\n type CsrfReadinessStore,\n type DisallowedConfig,\n type LoadModule,\n type PluginRunner,\n type RateLimitConfig,\n type SecurityHeadersConfig,\n} from '../server/internal-api.js'\nimport type { TheoTransformer } from '../server/transformer.js'\n\nexport interface ApiMiddlewareOptions {\n rateLimitConfig?: RateLimitConfig\n pluginRunner?: PluginRunner\n transformer?: TheoTransformer\n /** When defined, enables /api/__theo_batch__ endpoint with given options. */\n batching?: { max?: number }\n /** Phase 5 — CSRF enforcement mode. Default 'warn' (0.2.0). */\n csrfMode?: 'off' | 'warn' | 'strict'\n /** Phase 6 — Default security headers config. */\n securityHeaders?: SecurityHeadersConfig\n /** T5.1 — per-route disallowed escalation pattern. */\n disallowed?: DisallowedConfig\n /** T1.2 — CORS configuration. When undefined, no CORS handling (same-origin only). */\n cors?: CorsConfig\n /** T4.1 — Audit logger. Receives csrf.warn, rate-limit.exceeded, csp.violation events. */\n auditLogger?: AuditLogger\n /** T5.1 — Optional CSP violation hook (forwarded to Sentry / custom sink). */\n onCspViolation?: CspReportHandlerOptions['onViolation']\n /**\n * T2.2 — Optional CSRF readiness store. When provided, the\n * `/__theo/csrf-readiness` endpoint is mounted and warn events are\n * recorded into the store. Dev-mode middleware wires this automatically;\n * production hosts opt in via config.security.csrfTelemetry.exposeReadinessEndpoint.\n */\n csrfReadinessStore?: CsrfReadinessStore\n /**\n * Wave 2 completion (T1.1 vite-proxy) — list of services-proxy path prefixes\n * (e.g. `['/api/agent', '/api/worker']`). Requests whose path starts with\n * any of these prefixes bypass the api-middleware (call `next()`) so the\n * later proxyMiddleware (installed by Vite from `server.proxy`) can forward\n * them to the polyglot sidecar. Empty / undefined preserves Wave 1 BC.\n */\n servicesProxyPrefixes?: readonly string[]\n}\n\n/**\n * Wave 2 completion — true when `url` is OUTSIDE TheoKit's API namespace,\n * either because it doesn't start with `/api/` OR because it matches a\n * services-proxy prefix. In both cases the middleware should call `next()`\n * so the request reaches Vite's proxyMiddleware / static fallback. Combining\n * both checks into one helper keeps the main arrow function's cyclomatic\n * complexity within the eslint ceiling.\n */\nfunction shouldBypassApiMiddleware(url: string, prefixes: readonly string[]): boolean {\n if (!url.startsWith('/api/')) return true\n if (prefixes.length === 0) return false\n const path = url.split('?')[0]\n for (const prefix of prefixes) {\n if (path === prefix || path.startsWith(`${prefix}/`)) return true\n }\n return false\n}\n\nasync function handleCspReportIfMatch(\n req: IncomingMessage,\n res: ServerResponse,\n url: string,\n ctx: {\n auditLogger: AuditLogger | undefined\n onCspViolation: CspReportHandlerOptions['onViolation'] | undefined\n },\n): Promise<boolean> {\n const pathOnly = url.split('?')[0]\n if (pathOnly !== CSP_REPORT_PATH || req.method !== 'POST') return false\n await handleCspReport(req, res, { auditLogger: ctx.auditLogger, onViolation: ctx.onCspViolation })\n return true\n}\n\ninterface RateLimitCtx {\n rateLimiter:\n | ((req: IncomingMessage) => { limited: boolean; headers: Record<string, string> })\n | null\n requestId: string\n url: string\n start: number\n}\n\n/**\n * Apply rate-limit headers and send 429 if exceeded. Returns true when\n * the caller should stop handling the request (limit hit), false otherwise.\n * Extracted from `createApiMiddleware` to keep complexity within ceiling.\n */\nfunction applyRateLimitOr429(\n req: IncomingMessage,\n res: ServerResponse,\n ctx: RateLimitCtx,\n): boolean {\n if (!ctx.rateLimiter) return false\n const check = ctx.rateLimiter(req)\n for (const [k, v] of Object.entries(check.headers)) res.setHeader(k, v)\n if (!check.limited) return false\n sendError(res, 'RATE_LIMITED', 'Too many requests', 429, undefined, ctx.requestId)\n logRequest({\n method: req.method ?? 'GET',\n url: ctx.url,\n status: 429,\n duration: Date.now() - ctx.start,\n requestId: ctx.requestId,\n })\n return true\n}\n\ninterface BatchMatchCtx {\n url: string\n batching: { max?: number } | undefined\n requestId: string\n start: number\n}\n\nasync function handleBatchIfMatch(\n req: IncomingMessage,\n res: ServerResponse,\n ctx: BatchMatchCtx,\n): Promise<boolean> {\n if (!ctx.batching) return false\n const urlPathOnly = ctx.url.split('?')[0]\n if (urlPathOnly !== BATCH_PATH || req.method !== 'POST') return false\n await handleBatchInline(req, res, ctx.batching, ctx.requestId)\n logRequest({\n method: req.method ?? 'POST',\n url: ctx.url,\n status: res.statusCode,\n duration: Date.now() - ctx.start,\n requestId: ctx.requestId,\n })\n return true\n}\n\nasync function handleBatchInline(\n req: IncomingMessage,\n res: ServerResponse,\n batching: { max?: number },\n requestId: string,\n): Promise<void> {\n try {\n const chunks: Buffer[] = []\n await new Promise<void>((resolve, reject) => {\n req.on('data', (c) => chunks.push(c as Buffer))\n req.on('end', () => {\n resolve()\n })\n req.on('error', reject)\n })\n // CR-028: pass the parsed JSON as `unknown`; Zod inside\n // handleBatchRequest is the validation boundary.\n const payload: unknown = JSON.parse(Buffer.concat(chunks).toString())\n const outerHeaders: Record<string, string> = {}\n for (const [k, v] of Object.entries(req.headers)) {\n if (typeof v === 'string') outerHeaders[k.toLowerCase()] = v\n }\n const result = await handleBatchRequest(payload, {\n max: batching.max,\n outerHeaders,\n // T1.4 placeholder — full per-item route execution lands in a\n // follow-up; for now we return an empty ack so the integration\n // tests of the batch endpoint shape pass.\n execute: () => Promise.resolve({ data: { ok: true } }),\n })\n res.writeHead(200, { 'Content-Type': 'application/json' })\n res.end(JSON.stringify(result))\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n sendError(res, 'BATCH_ERROR', message, 400, undefined, requestId)\n }\n}\n\n/**\n * P#3 T4.1 — fire pluginRunner.onRequest for unmatched routes so plugins\n * can intercept paths outside server/routes/ (e.g., @theokit/plugin-openapi\n * /api/docs). Returns true when a plugin short-circuited the response.\n */\ninterface RunPluginsCtx {\n req: IncomingMessage\n res: ServerResponse\n requestId: string\n start: number\n url: string\n}\n\nasync function runPluginsBeforeRouteMatch(\n pluginRunner: PluginRunner,\n reqCtx: RunPluginsCtx,\n): Promise<boolean> {\n const { req, res, requestId, start, url } = reqCtx\n try {\n const hookResult = await pluginRunner.runOnRequest({\n // #119 — plugin hooks see a Web `Request` in every runtime (ADR-0028 R3a).\n request: incomingMessageToHandlerRequest(req),\n response: res,\n ctx: {},\n requestId,\n })\n if (hookResult.shortCircuited) {\n logRequest(\n {\n method: req.method ?? 'GET',\n url,\n status: res.statusCode,\n duration: Date.now() - start,\n requestId,\n },\n undefined,\n req,\n )\n return true\n }\n } catch (err) {\n sendError(res, 'PLUGIN_ERROR', (err as Error).message, 500, undefined, requestId)\n return true\n }\n return false\n}\n\n/**\n * #122 (T1.2) — controller fall-through for the `!match` arm. Serves a decorator\n * controller under `<serverDir>/controllers/` (dev parity); inherits the security-\n * headers/CORS/rate-limit/plugin gates already run upstream, and CSRF is enforced\n * inside `dispatchControllerRequest`. Zero cost for routes-only apps. Returns `true`\n * when a controller handled the request (response already written + logged).\n */\nasync function tryControllerFallthrough(ctx: {\n req: IncomingMessage\n res: ServerResponse\n serverDir: string\n loadModule: LoadModule\n csrfMode: 'off' | 'warn' | 'strict'\n disallowed: DisallowedConfig | undefined\n requestId: string\n url: string\n start: number\n}): Promise<boolean> {\n const handled = await dispatchControllerRequest({\n controllersDir: resolve(ctx.serverDir, 'controllers'),\n loadModule: ctx.loadModule,\n req: ctx.req,\n res: ctx.res,\n csrfMode: ctx.csrfMode,\n disallowed: ctx.disallowed,\n requestId: ctx.requestId,\n // M47 — serve @Expose-bound agent routes via the ONE runtime (mountAgent). CSRF is already enforced\n // once at the controller-dispatch boundary (G5), so mountAgent runs with csrfMode 'off' (no double gate).\n serveAgent: (agent: unknown, request: Request) =>\n mountAgent(agent, request, resolveProvider().apiKey, { source: 'expose', csrfMode: 'off' }),\n })\n if (!handled) return false\n logRequest(\n {\n method: (ctx.req.method ?? 'GET').toUpperCase(),\n url: ctx.url,\n status: ctx.res.statusCode,\n duration: Date.now() - ctx.start,\n requestId: ctx.requestId,\n },\n undefined,\n ctx.req,\n )\n return true\n}\n\nexport function createApiMiddleware(\n vite: ViteDevServer,\n serverDir: string,\n rateLimitConfigOrOptions?: RateLimitConfig | ApiMiddlewareOptions,\n): Connect.NextHandleFunction {\n // Backward-compat: accept either RateLimitConfig directly (old signature)\n // or an ApiMiddlewareOptions object (new signature with pluginRunner).\n const opts: ApiMiddlewareOptions =\n rateLimitConfigOrOptions && 'windowMs' in rateLimitConfigOrOptions\n ? { rateLimitConfig: rateLimitConfigOrOptions }\n : (rateLimitConfigOrOptions ?? {})\n\n const loadModule = createViteLoader(vite)\n const rateLimiter = opts.rateLimitConfig ? createRateLimiter(opts.rateLimitConfig) : null\n const pluginRunner = opts.pluginRunner\n const transformer = opts.transformer\n const batching = opts.batching\n // T6.1 — default flipped from 'warn' to 'strict' for 0.3.0.\n const csrfMode = opts.csrfMode ?? 'strict'\n const disallowed = opts.disallowed\n const securityHeadersConfig = opts.securityHeaders ?? {}\n const securityEnv = { production: process.env.NODE_ENV === 'production' }\n // T1.2 — CORS handler runs FIRST in the pipeline (D10).\n const corsHandler = opts.cors ? createCorsHandler(opts.cors) : null\n const auditLogger = opts.auditLogger\n const onCspViolation = opts.onCspViolation\n const csrfReadinessStore = opts.csrfReadinessStore\n const servicesProxyPrefixes = opts.servicesProxyPrefixes ?? []\n\n return (req, res, next) => {\n // Middleware dispatch arm: each branch guards a protocol concern\n // (CSP report, CSRF readiness, services proxy, CORS preflight, rate\n // limit, plugin onRequest, batch, route match); linear dispatch order\n // is more readable than per-concern function extraction.\n // eslint-disable-next-line complexity\n const handle = async (): Promise<void> => {\n const url = req.url ?? ''\n\n // T5.1 — built-in CSP report endpoint. Matched BEFORE the /api/* gate\n // so the path lives outside the user's route namespace. Endpoint is\n // CSRF-exempt (browsers don't send X-Theo-Action on report POSTs).\n if (await handleCspReportIfMatch(req, res, url, { auditLogger, onCspViolation })) {\n return\n }\n\n // T2.2 — CSRF readiness endpoint. Only mounted when a store is wired\n // (dev-mode wires it automatically; prod opt-in via config).\n if (csrfReadinessStore && (await handleCsrfReadiness(req, res, csrfReadinessStore))) {\n return\n }\n\n if (shouldBypassApiMiddleware(url, servicesProxyPrefixes)) {\n next()\n return\n }\n\n // T1.2 + D10 — CORS preflight runs BEFORE rate limit, BEFORE CSRF.\n // Preflight short-circuits the response (204 + Access-Control-* headers).\n if (corsHandler?.handlePreflight(req, res)) {\n return\n }\n\n // Phase 7 — traceId resolution. Reads traceparent / x-request-id /\n // generates UUID. The `requestId` name is kept for backward compat\n // with downstream helpers (sendError, logRequest) — same value flows\n // under both `x-request-id` (legacy) and `x-trace-id` (canonical).\n const requestId = extractTraceId(req)\n const start = Date.now()\n res.setHeader('x-request-id', requestId)\n res.setHeader(TRACE_HEADER, requestId)\n // Phase 6 — Apply security headers BEFORE the handler runs so route\n // handlers can still override via res.setHeader (last write wins).\n applySecurityHeaders(res, securityHeadersConfig, securityEnv)\n // T1.2 — Add CORS headers to non-preflight responses.\n corsHandler?.applyHeaders(req, res)\n\n if (applyRateLimitOr429(req, res, { rateLimiter, requestId, url, start })) {\n return\n }\n\n // P#3 T4.1 — fire pluginRunner.onRequest BEFORE matchRoute so plugins\n // can intercept unmatched paths (e.g., @theokit/plugin-openapi /api/docs).\n if (\n pluginRunner &&\n (await runPluginsBeforeRouteMatch(pluginRunner, { req, res, requestId, start, url }))\n ) {\n return\n }\n\n // T1.4 — Batch endpoint (only when batching is enabled in config)\n if (await handleBatchIfMatch(req, res, { url, batching, requestId, start })) {\n return\n }\n\n const routes = scanServerRoutes(serverDir)\n const match = matchRoute(url, routes)\n\n if (!match) {\n // #122 (T1.2) — no file route matched; try a decorator controller (dev parity).\n if (\n await tryControllerFallthrough({\n req,\n res,\n serverDir,\n loadModule,\n csrfMode,\n disallowed,\n requestId,\n url,\n start,\n })\n ) {\n return\n }\n\n const urlPath = url.split('?')[0]\n const routePaths = routes.map((r) => r.routePath)\n const suggestion = findSuggestion(urlPath, routePaths)\n const msg = suggestion\n ? `API route not found: ${urlPath}. Did you mean: ${suggestion}?`\n : 'API route not found'\n sendError(res, 'NOT_FOUND', msg, 404, undefined, requestId)\n logRequest(\n {\n method: req.method ?? 'GET',\n url,\n status: 404,\n duration: Date.now() - start,\n requestId,\n },\n undefined,\n req,\n )\n return\n }\n\n const method = (req.method ?? 'GET').toUpperCase()\n // T3.1 (ADR-0016) — context object replaces 12 positional args\n await executeRoute({\n route: match.route,\n method,\n params: match.params,\n req,\n res,\n loadModule,\n serverDir,\n requestId,\n pluginRunner,\n transformer,\n csrfMode,\n disallowed,\n })\n logRequest(\n { method, url, status: res.statusCode, duration: Date.now() - start, requestId },\n undefined,\n req,\n )\n }\n void handle()\n }\n}\n","/**\n * T2.2 (architecture-medium-deferrals plan, ADR D2) — SSR dev middleware\n * extracted from `vite-plugin/index.ts` for SRP.\n *\n * `setupSsrDevMiddleware(server, opts)` registers a Connect-style middleware\n * on the Vite dev server that:\n * 1. Skips API, static, and HMR requests (let other middlewares handle).\n * 2. Reads `index.html`, runs `transformIndexHtml`.\n * 3. Generates per-request nonce, applies security headers (CSP + Cache-Control).\n * 4. Calls `ssrLoadModule(VIRTUAL_ENTRY_SERVER_ID).render(url, { nonce })`.\n * 5. Injects rendered HTML (with hydration script) into root div.\n * 6. On error: ssrFixStacktrace + fallback to CSR via `next()`.\n *\n * No-op when `ssrEnabled === false`. Caller's responsibility to gate.\n */\n\nimport { readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nimport type { ViteDevServer } from 'vite'\n\nimport {\n applySecurityHeaders,\n generateNonce,\n type SecurityHeadersConfig,\n} from '../server/internal-api.js'\n\ninterface SsrRenderResult {\n html: string\n hydrationData: {\n loaderData?: unknown\n actionData?: unknown\n errors?: unknown\n }\n}\n\ninterface SsrEntryServer {\n render: (\n url: string,\n opts: { nonce: string },\n ) => Promise<SsrRenderResult | { redirect: Response } | string>\n}\n\nfunction isSsrRenderResult(value: unknown): value is SsrRenderResult {\n if (typeof value !== 'object' || value === null) return false\n if (!('html' in value)) return false\n return typeof (value as Record<string, unknown>).html === 'string'\n}\n\nexport interface SsrDevMiddlewareOptions {\n projectRoot: string\n virtualEntryServerId: string\n securityHeaders: SecurityHeadersConfig | undefined\n}\n\n/**\n * Attach the SSR dev middleware to a Vite dev server. Caller decides whether\n * to invoke this based on `ssrEnabled` — this function does not gate.\n */\nexport function setupSsrDevMiddleware(server: ViteDevServer, opts: SsrDevMiddlewareOptions): void {\n server.middlewares.use((req, res, next) => {\n void (async () => {\n const url = req.url ?? '/'\n // Skip API, static, and HMR requests\n if (\n url.startsWith('/api/') ||\n url.startsWith('/@') ||\n url.startsWith('/node_modules/') ||\n url.includes('.')\n ) {\n next()\n return\n }\n\n try {\n const indexPath = resolve(opts.projectRoot, 'index.html')\n // eslint-disable-next-line security/detect-non-literal-fs-filename -- projectRoot is from `theokit dev`'s caller-controlled cwd\n let template = readFileSync(indexPath, 'utf-8')\n template = await server.transformIndexHtml(url, template)\n\n // T4.1 — Generate a per-request nonce and apply security headers BEFORE render.\n // The same nonce flows into React's renderToPipeableStream({ nonce }) so every\n // emitted <script> carries it AND into the CSP script-src directive.\n // EC-3: applySecurityHeaders also forces Cache-Control: private, no-store.\n const nonce = generateNonce()\n applySecurityHeaders(\n res,\n opts.securityHeaders ?? {},\n { production: process.env.NODE_ENV === 'production' },\n { nonce },\n )\n\n const mod = (await server.ssrLoadModule(opts.virtualEntryServerId)) as SsrEntryServer\n const result = await mod.render(url, { nonce })\n\n if (result && typeof result === 'object' && 'redirect' in result) {\n res.writeHead(302, {\n Location: result.redirect.headers.get('location') ?? '/',\n })\n res.end()\n return\n }\n\n // Backward-compat: old render returned string. New shape returns\n // { html, hydrationData } so the framework can emit the hydration\n // data script OUTSIDE the React root (fixes hydration mismatch).\n let ssrHtml: string\n let hydrationScript = ''\n if (typeof result === 'string') {\n ssrHtml = result\n } else if (isSsrRenderResult(result)) {\n ssrHtml = result.html\n const dataJson = JSON.stringify(result.hydrationData).replace(/</g, '\\\\u003c')\n hydrationScript = `<script nonce=\"${nonce}\">window.__staticRouterHydrationData=${dataJson}</script>`\n } else {\n ssrHtml = ''\n }\n const rootDivMatch = /<div id=[\"']root[\"'][^>]*>/.exec(template)\n if (!rootDivMatch) {\n res.writeHead(200, { 'Content-Type': 'text/html' })\n res.end(template)\n return\n }\n\n const splitIdx = template.indexOf(rootDivMatch[0]) + rootDivMatch[0].length\n const html =\n template.slice(0, splitIdx) + ssrHtml + hydrationScript + template.slice(splitIdx)\n\n res.writeHead(200, { 'Content-Type': 'text/html' })\n res.end(html)\n } catch (err) {\n server.ssrFixStacktrace(err as Error)\n console.error('[SSR Dev Error]', err)\n // Fallback to CSR\n next()\n return\n }\n })()\n })\n}\n","/**\n * T2.3 (architecture-medium-deferrals plan, ADR D2) — WebSocket upgrade\n * handler extracted from `vite-plugin/index.ts` for SRP.\n *\n * `setupWsUpgrade(server, projectRoot)` scans `server/ws/*` and attaches an\n * upgrade handler to `server.httpServer`. Lazy-imports the `ws` package so\n * non-WS apps don't pay the cost.\n *\n * **EC-1 (architecture-medium-deferrals plan v1.1 MUST FIX):** must tolerate\n * `server.httpServer === null` (Vite middleware mode — embed in Express/etc).\n * Without the guard, dev embeds crash on plugin init. The function exits\n * silently when no httpServer is available; consumer can wire their own.\n *\n * Mirrors the prod surface in `cli/commands/start-websocket-handler.ts` —\n * same `onOpen`/`onMessage`/`onClose`/`onError` handler shape (EC-6 parity).\n */\n\nimport type { IncomingMessage } from 'node:http'\nimport { resolve } from 'node:path'\nimport type { Duplex } from 'node:stream'\n\nimport type { ViteDevServer } from 'vite'\n\nimport { scanWebSocketRoutes } from '../server/internal-api.js'\n\ninterface WsHandler {\n onOpen?: (ws: unknown, request: unknown) => void | Promise<void>\n onMessage?: (ws: unknown, data: string) => void | Promise<void>\n onClose?: (ws: unknown, code: number, reason: Buffer) => void | Promise<void>\n onError?: (ws: unknown, err: Error) => void | Promise<void>\n}\n\nexport function setupWsUpgrade(server: ViteDevServer, projectRoot: string): void {\n const wsRoutes = scanWebSocketRoutes(resolve(projectRoot, 'server'))\n if (wsRoutes.length === 0) return\n\n // EC-1 — middleware-mode Vite has no httpServer. Silently skip; the host\n // platform owns its own upgrade routing in that case.\n const wsHttpServer = server.httpServer\n if (!wsHttpServer) return\n\n // Lazy-import `ws` so non-WS apps don't pay the cost.\n void import('ws')\n .then(({ WebSocketServer }) => {\n const wss = new WebSocketServer({ noServer: true })\n\n wsHttpServer.on('upgrade', (request: IncomingMessage, socket: Duplex, head: Buffer) => {\n void (async () => {\n const url = request.url ?? '/'\n if (!url.startsWith('/ws/')) return // Let Vite handle HMR etc.\n\n const wsPath = url.split('?')[0]\n const match = wsRoutes.find((r) => r.wsPath === wsPath)\n if (!match) {\n socket.destroy()\n return\n }\n\n try {\n const mod = await server.ssrLoadModule(match.filePath)\n const handler = ((mod as { default?: unknown }).default ?? mod) as WsHandler\n\n wss.handleUpgrade(request, socket, head, (ws) => {\n void handler.onOpen?.(ws, request)\n ws.on('message', (data: Buffer) => {\n void handler.onMessage?.(ws, data.toString())\n })\n ws.on('close', (code: number, reason: Buffer) => {\n void handler.onClose?.(ws, code, reason)\n })\n ws.on('error', (err: Error) => {\n void handler.onError?.(ws, err)\n })\n })\n } catch {\n socket.destroy()\n }\n })()\n })\n })\n .catch(() => {\n console.warn(\n '[Theo] WebSocket routes found but \"ws\" package not installed. Run: npm install ws',\n )\n })\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time tool. Read-only filesystem walks under cwd + node_modules\n * to resolve consumer-side optional deps. Paths are derived from the\n * CLI-controlled cwd and a fixed package name list.\n */\n/**\n * `integrateUseTheoUI(cwd, opts)` — auto-chains the Vite plugins needed\n * for `@theokit/ui` styling when the consumer has the dep declared.\n *\n * Algorithm (D3 + D5 of the plan):\n * 1. opts.enabled === false → return [].\n * 2. detectPackage('@theokit/ui') — if absent, return [].\n * 3. opts.consumerTailwindConfig or opts.consumerPostcssConfig set →\n * log info + return []. Consumer-in-control wins (D3).\n * 4. detectPackage('@tailwindcss/vite') — if absent, log warn + return [].\n * 5. Dynamic-import both. Type-check default exports (EC-5). Type-check\n * return shapes (EC-6). If any guard fails, log + return [].\n * 6. Return [tailwindcssPlugin(), useTheoUIPlugin()].\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { pathToFileURL } from 'node:url'\n\nimport type { Plugin } from 'vite'\n\nimport { detectPackage } from './auto-detect.js'\n\nexport interface IntegrateUiOptions {\n /** When `false`, disable auto-config regardless of detection. Default: true. */\n enabled?: boolean\n /** Path to the consumer's tailwind.config.* (any extension), if present. D3 deferral. */\n consumerTailwindConfig?: string\n /** Path to the consumer's postcss.config.* (any extension), if present. D3 deferral. */\n consumerPostcssConfig?: string\n}\n\n/**\n * Resolve a bare specifier to an absolute file URL by walking up from the\n * consumer's `cwd`, scanning `node_modules` directly. Works for ESM-only\n * packages that don't expose a `require` condition (createRequire fails\n * on those). Reads the resolved package.json's `exports.\".\"` field to\n * find the entry. Returns the file:// URL or null if not resolvable.\n */\nfunction resolveConsumerImport(name: string, cwd: string): string | null {\n let dir = cwd\n for (let i = 0; i < 10; i++) {\n const pkgDir = join(dir, 'node_modules', ...name.split('/'))\n const pkgJsonPath = join(pkgDir, 'package.json')\n if (existsSync(pkgJsonPath)) {\n try {\n const raw = readFileSync(pkgJsonPath, 'utf-8')\n const pkg = JSON.parse(raw) as {\n exports?: { '.'?: { import?: string; default?: string } | string }\n main?: string\n module?: string\n }\n let entry: string | undefined\n const dotExport = pkg.exports?.['.']\n if (typeof dotExport === 'string') entry = dotExport\n else if (dotExport && typeof dotExport === 'object') {\n entry = dotExport.import ?? dotExport.default\n }\n entry ??= pkg.module ?? pkg.main\n if (!entry) return null\n // Strip leading ./ then join.\n const cleaned = entry.replace(/^\\.\\//, '')\n return pathToFileURL(join(pkgDir, cleaned)).href\n } catch {\n return null\n }\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n return null\n}\n\nfunction isValidPlugin(value: unknown): value is Plugin {\n if (value === null || typeof value !== 'object') return false\n if (Array.isArray(value)) return false\n // Vite Plugin shape: object with a `name: string` field at minimum.\n if (!('name' in value)) return false\n return typeof (value as Record<string, unknown>).name === 'string'\n}\n\n/**\n * Normalize a Vite plugin factory return value into a flat Plugin[].\n *\n * Background: Tailwind v3 returned a single Plugin from its factory.\n * Tailwind v4 (`@tailwindcss/vite@4.x`) returns an ARRAY of 3 plugins\n * (`@tailwindcss/vite:scan` + `:generate:serve` + `:generate:build`).\n * The EC-6 single-Plugin guard rejected the v4 array shape and silently\n * skipped chain integration, causing 0 utilities generated in the\n * consumer's CSS. This normalizer accepts both shapes.\n */\nfunction normalizePluginReturn(value: unknown): Plugin[] | null {\n if (Array.isArray(value)) {\n const result: Plugin[] = []\n for (const entry of value) {\n if (!isValidPlugin(entry)) return null\n result.push(entry)\n }\n return result.length > 0 ? result : null\n }\n if (isValidPlugin(value)) return [value]\n return null\n}\n\n/** Test-only side-door so EC-6 shape guard can be unit-tested directly. */\nexport const _isValidPluginForTest = isValidPlugin\n/** Test-only side-door for the v3/v4 normalizer. */\nexport const _normalizePluginReturnForTest = normalizePluginReturn\n\n// eslint-disable-next-line complexity -- canonical auto-config gate (5 detection branches + 2 import guards + 2 shape guards); flattening to micro-helpers would hide the linear contract\nexport async function integrateUseTheoUI(\n cwd: string,\n opts?: IntegrateUiOptions,\n): Promise<Plugin[]> {\n if (opts?.enabled === false) return []\n\n const uiDetect = detectPackage('@theokit/ui', cwd)\n if (!uiDetect.installed) return []\n\n // D3 — consumer's manual config wins\n if (opts?.consumerTailwindConfig || opts?.consumerPostcssConfig) {\n // eslint-disable-next-line no-console -- one-line transparency hint; goal is to surface the override path\n console.info(\n `[theokit] Detected your tailwind.config / postcss.config — skipping auto-config. Extend with \\`import preset from '@theokit/ui/preset'\\` to apply UI theme.`,\n )\n return []\n }\n\n const tailwindDetect = detectPackage('@tailwindcss/vite', cwd)\n if (!tailwindDetect.installed) {\n console.warn(\n `[theokit] @theokit/ui detected but @tailwindcss/vite is not installed. Run \\`pnpm add -D @tailwindcss/vite\\` to enable styling.`,\n )\n return []\n }\n\n // Explicit chain: @tailwindcss/vite FIRST + @theokit/ui/vite-plugin\n // with `{ tailwind: false }` (avoids double-add of @tailwindcss/vite).\n //\n // Why resolve via filesystem then import by URL: this module runs from\n // theokit's own dist/, so `await import('@tailwindcss/vite')` would\n // try to resolve from theokit's node_modules — where the consumer's\n // optional deps don't exist. Resolving from the consumer's cwd\n // gives the correct path.\n const tailwindUrl = resolveConsumerImport('@tailwindcss/vite', cwd)\n if (!tailwindUrl) {\n console.warn(\n `[theokit] @tailwindcss/vite installed but its package entry was not resolvable from ${cwd}. Skipping auto-config.`,\n )\n return []\n }\n let tailwindMod: { default?: unknown }\n let uiMod: { default?: unknown }\n try {\n tailwindMod = (await import(tailwindUrl)) as { default?: unknown }\n } catch (err) {\n console.warn(\n `[theokit] @tailwindcss/vite dynamic import failed (${(err as Error).message}). Skipping auto-config.`,\n )\n return []\n }\n // For @theokit/ui/vite-plugin, resolve via package + subpath:\n // node_modules/@theokit/ui/dist/vite-plugin.js\n const uiPkgInstalled = detectPackage('@theokit/ui', cwd)\n const uiPkgDir = uiPkgInstalled.resolvedPath\n ? uiPkgInstalled.resolvedPath.replace(/[\\\\/]package\\.json$/, '')\n : null\n const uiPluginPath = uiPkgDir ? join(uiPkgDir, 'dist', 'vite-plugin.js') : null\n if (!uiPluginPath || !existsSync(uiPluginPath)) {\n console.warn(\n `[theokit] @theokit/ui/vite-plugin entry not found at ${String(uiPluginPath)}. Skipping auto-config.`,\n )\n return []\n }\n try {\n uiMod = (await import(pathToFileURL(uiPluginPath).href)) as { default?: unknown }\n } catch (err) {\n console.warn(\n `[theokit] @theokit/ui/vite-plugin dynamic import failed (${(err as Error).message}). Skipping auto-config.`,\n )\n return []\n }\n\n if (typeof tailwindMod.default !== 'function') {\n console.warn(\n `[theokit] @tailwindcss/vite does not expose a default-export function. Skipping auto-config.`,\n )\n return []\n }\n if (typeof uiMod.default !== 'function') {\n console.warn(\n `[theokit] @theokit/ui/vite-plugin does not expose a default-export function. Skipping auto-config.`,\n )\n return []\n }\n\n let tailwindPlugin: unknown\n let uiPlugin: unknown\n try {\n tailwindPlugin = (tailwindMod.default as () => unknown)()\n } catch (err) {\n console.warn(`[theokit] @tailwindcss/vite() threw: ${(err as Error).message}`)\n return []\n }\n try {\n // Pass { tailwind: false } so the UI plugin skips its internal\n // @tailwindcss/vite chain (we already added it above).\n uiPlugin = (uiMod.default as (opts?: { tailwind?: boolean }) => unknown)({\n tailwind: false,\n })\n } catch (err) {\n console.warn(`[theokit] @theokit/ui/vite-plugin() threw: ${(err as Error).message}`)\n return []\n }\n\n const tailwindPlugins = normalizePluginReturn(tailwindPlugin)\n if (tailwindPlugins === null) {\n console.warn(`[theokit] @tailwindcss/vite returned unexpected shape. Skipping auto-config.`)\n return []\n }\n const uiPlugins = normalizePluginReturn(uiPlugin)\n if (uiPlugins === null) {\n console.warn(\n `[theokit] @theokit/ui/vite-plugin returned unexpected shape. Skipping auto-config.`,\n )\n return []\n }\n\n return [...tailwindPlugins, ...uiPlugins]\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Reads <projectRoot>/package.json + resolves the target package's own\n * package.json. Paths come from controlled CLI/config inputs; this is a\n * build-time tool, no HTTP.\n */\n/**\n * `detectPackage(name, cwd)` — generalized form of `theoui-detect.ts`.\n *\n * Used by T3.2 `integrateUseTheoUI` to gate auto-config on whether the\n * consumer has `@theokit/ui` AND `@tailwindcss/vite` installed.\n *\n * Algorithm (same as `theoui-detect.ts` but parameterized):\n * 1. Read `<cwd>/package.json`. Check `dependencies` / `devDependencies` /\n * `peerDependencies` for the package name.\n * 2. If declared, probe `require.resolve('<name>/package.json', { paths: [cwd] })`.\n * Read the resolved package.json to capture `version`.\n * 3. If resolution fails, fall back to probing common entrypoints (so\n * packages whose `exports` doesn't include `./package.json` still\n * detect).\n *\n * NEVER throws. Returns `{installed: false}` on any failure.\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\n\nimport type { DetectResult } from './auto-detect-types.js'\n\n/**\n * D13 invariant (ADR 0021): @theokit/ui is ESM-only by design.\n * NÃO usar `createRequire(...).resolve()` — `ERR_PACKAGE_PATH_NOT_EXPORTED`\n * em runtime para packages que declaram `type:\"module\"` sem `require` condition.\n * Tudo filesystem walk direto.\n */\n\nfunction isDeclared(name: string, projectRoot: string): boolean {\n try {\n const raw = readFileSync(join(projectRoot, 'package.json'), 'utf-8')\n const pkg = JSON.parse(raw) as {\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n peerDependencies?: Record<string, string>\n }\n return Boolean(\n pkg.dependencies?.[name] ?? pkg.devDependencies?.[name] ?? pkg.peerDependencies?.[name],\n )\n } catch {\n return false\n }\n}\n\n/**\n * D13: filesystem walk pra encontrar package.json (substitui require.resolve).\n * Walks node_modules up to 10 levels (handles pnpm hoist + workspace symlinks).\n */\nfunction resolvePackageJson(name: string, cwd: string): { path: string; version?: string } | null {\n let dir = cwd\n for (let depth = 0; depth < 10; depth++) {\n const pkgJsonPath = join(dir, 'node_modules', ...name.split('/'), 'package.json')\n if (existsSync(pkgJsonPath)) {\n try {\n const raw = readFileSync(pkgJsonPath, 'utf-8')\n const pkg = JSON.parse(raw) as { name?: string; version?: string }\n // Validate package name matches (defesa contra colisão path)\n if (pkg.name === name) {\n return { path: pkgJsonPath, version: pkg.version }\n }\n } catch {\n // continue walking\n }\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n return null\n}\n\n/**\n * D13: fallback probe via filesystem (substitui require.resolve).\n * Tenta common entry paths em node_modules. Retorna path do entry achado.\n */\nfunction fallbackProbe(name: string, cwd: string): { resolvedEntry: string } | null {\n const candidates = ['index.mjs', 'dist/index.mjs', 'dist/index.js', 'index.js']\n let dir = cwd\n for (let depth = 0; depth < 10; depth++) {\n const pkgDir = join(dir, 'node_modules', ...name.split('/'))\n for (const candidate of candidates) {\n const entry = join(pkgDir, candidate)\n if (existsSync(entry)) return { resolvedEntry: entry }\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n return null\n}\n\n/** Walk up from a resolved entry path until we hit the package's own package.json\n * whose `name` field matches `expectedName`. Returns null on any failure. */\nfunction findOwningPackageJson(\n entry: string,\n expectedName: string,\n): { path: string; version?: string } | null {\n let dir = dirname(entry)\n // Bound the walk to ~10 levels to avoid pathological cases.\n for (let i = 0; i < 10; i++) {\n const candidate = join(dir, 'package.json')\n if (existsSync(candidate)) {\n try {\n const raw = readFileSync(candidate, 'utf-8')\n const pkg = JSON.parse(raw) as { name?: string; version?: string }\n if (pkg.name === expectedName) {\n return { path: candidate, version: pkg.version }\n }\n } catch {\n // ignore + continue walking\n }\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n return null\n}\n\nexport function detectPackage(name: string, cwd: string): DetectResult {\n if (!isDeclared(name, cwd)) {\n return { installed: false }\n }\n\n const pkgJson = resolvePackageJson(name, cwd)\n if (pkgJson) {\n return {\n installed: true,\n version: pkgJson.version,\n resolvedPath: pkgJson.path,\n }\n }\n\n // Filesystem fallback: ESM-only packages (no `require` condition) can't\n // be resolved by createRequire. Check node_modules directly. The walk\n // upward handles pnpm hoist + workspace symlinks.\n let dir = cwd\n for (let i = 0; i < 10; i++) {\n const nmPath = join(dir, 'node_modules', ...name.split('/'))\n const nmPkgJson = join(nmPath, 'package.json')\n if (existsSync(nmPkgJson)) {\n try {\n const raw = readFileSync(nmPkgJson, 'utf-8')\n const pkg = JSON.parse(raw) as { name?: string; version?: string }\n if (pkg.name === name) {\n return { installed: true, version: pkg.version, resolvedPath: nmPkgJson }\n }\n } catch {\n /* fall through to entry probe */\n }\n return { installed: true }\n }\n const parent = dirname(dir)\n if (parent === dir) break\n dir = parent\n }\n\n // Last-resort fallback — exports doesn't include ./package.json. Walk up from\n // the resolved entry to find the package's own package.json.\n const probe = fallbackProbe(name, cwd)\n if (probe) {\n const owning = findOwningPackageJson(probe.resolvedEntry, name)\n if (owning) {\n return { installed: true, version: owning.version, resolvedPath: owning.path }\n }\n return { installed: true }\n }\n\n return { installed: false }\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Resolves theokit's own install directory (the `node_modules/theokit/`).\n * Build-time tool. Read-only check. No HTTP input.\n */\nimport { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\n/**\n * Resolve the directory that holds the framework's compiled (or source)\n * subpaths — `client/`, `server/`, `react-query/`, etc.\n *\n * Cases (regression T1.3):\n * - Source mode (`src/vite-plugin/index.ts`) — `currentDir` is\n * `…/src/vite-plugin`. Parent (`…/src`) contains `client/`. Return parent.\n * - Dist mode (`dist/chunk-XYZ.js`) — `currentDir` is `…/dist`. That dir\n * itself contains `client/`. Return currentDir.\n * - Unknown shape — fall back to parent (legacy behavior). The dogfood\n * validator will catch the misconfiguration before runtime.\n *\n * Pure function — no side effects, only filesystem reads via `existsSync`.\n * Exported so the regression test can exercise the branch logic directly.\n */\nexport function resolveTheoRootDir(currentDir: string): string {\n if (existsSync(resolve(currentDir, 'client'))) {\n return currentDir\n }\n return resolve(currentDir, '..')\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * transformIndexHtml extraction (T2.6 / M6). hasPackage probe reads\n * `node_modules/<name>` paths built from build-time projectRoot. No\n * HTTP input.\n */\nimport { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nimport { injectDevtoolsScript } from './inject-devtools.js'\nimport { injectEntryClient } from './inject-entry-client.js'\nimport { injectStylesheets } from './inject-stylesheets.js'\n\nexport interface TransformHtmlCtx {\n isDevMode: { value: boolean }\n devtoolsEnabled: boolean\n projectRoot: string\n}\n\n/**\n * Runs the 3-step HTML injection sequence in the canonical order:\n * 1. entry-client (always)\n * 2. devtools (dev only)\n * 3. stylesheets (dev only)\n * Order is part of the contract — devtools depends on entry-client\n * being present; stylesheets injection sits last so the <link>\n * follows the bundled <script>. EC-10 honored.\n */\nexport function runTransformIndexHtml(html: string, ctx: TransformHtmlCtx): string {\n // 1. entry-client (always)\n const entry = injectEntryClient(html)\n\n if (entry.warning) console.warn(entry.warning)\n let next = entry.html\n\n // 2. devtools (dev only, respecting config.devtools = false)\n const devtools = injectDevtoolsScript(next, {\n isDev: ctx.isDevMode.value,\n enabled: ctx.devtoolsEnabled,\n })\n\n if (devtools.warning) console.warn(devtools.warning)\n next = devtools.html\n\n // 3. Stylesheet link (dev only) — fixes LCP. Without the\n // <link rel=\"stylesheet\">, CSS only loads after the JS bundle\n // executes `import 'styles.css'`, causing FOUC + LCP > 9s.\n // Production builds rely on Vite's SSR bundle for the\n // correctly-hashed <link>. Font preload was tried + reverted\n // (see inject-stylesheets.ts comment); CLS was hydration\n // mismatch, not font swap.\n const styles = injectStylesheets(next, {\n isDev: ctx.isDevMode.value,\n hasPackage: (name) => existsSync(resolve(ctx.projectRoot, 'node_modules', ...name.split('/'))),\n })\n next = styles.html\n\n return next\n}\n","/**\n * T1.2 — Auto-inject the devtools entry `<script>` into served HTML (dev only).\n *\n * Origin: matches the inject-entry-client.ts pattern but for the devtools\n * module. In dev, the Vite plugin's transformIndexHtml hook calls this for\n * every served HTML. In build, this is a no-op.\n *\n * - EC-30: naive `.replace('</head>', ...)` IS used; alternative HTML parser\n * is too heavy for the bug class (user putting `</head>` literal in inline\n * JS is near-zero). Documented in known limitations.\n * - User opt-out via `config.devtools = false` is respected at the plugin\n * level (this function is simply not called).\n *\n * NEVER use dangerouslySetInnerHTML in any devtools component — see plan EC-20.\n */\n\nexport const DEVTOOLS_VIRTUAL_ID = '/@theo/devtools/entry.js'\nexport const DEVTOOLS_RESOLVED_ID = '\\0@theo/devtools/entry.js'\n\nconst SCRIPT_TAG = `<script type=\"module\" src=\"${DEVTOOLS_VIRTUAL_ID}\"></script>`\n\nexport interface InjectDevtoolsResult {\n html: string\n injected: boolean\n warning?: string\n}\n\nexport function injectDevtoolsScript(\n html: string,\n opts: { isDev: boolean; enabled?: boolean },\n): InjectDevtoolsResult {\n // Build mode → no inject\n if (!opts.isDev) return { html, injected: false }\n // User opt-out via config.devtools = false\n if (opts.enabled === false) return { html, injected: false }\n\n // Already present (HMR re-run, user added manually) → idempotent\n if (html.includes(DEVTOOLS_VIRTUAL_ID)) {\n return { html, injected: false }\n }\n\n // Inject before </head> (case-insensitive, first occurrence)\n const headClosePattern = /<\\/head\\s*>/i\n if (headClosePattern.test(html)) {\n return {\n html: html.replace(headClosePattern, (match) => ` ${SCRIPT_TAG}\\n ${match}`),\n injected: true,\n }\n }\n\n // No </head> tag — skip inject + warn (rather than corrupt the HTML)\n return {\n html,\n injected: false,\n warning:\n 'theokit devtools: index.html has no </head> tag; devtools script was NOT injected. Add <head>…</head> to your template to enable devtools.',\n }\n}\n","/**\n * Auto-inject the entry-client `<script>` into served HTML.\n *\n * Origin: a real user (live session) wrote `index.html` without the\n * `<script type=\"module\" src=\"/@theo/entry-client\"></script>` tag. The\n * page rendered SSR perfectly but NO JS ran — every onClick was dead.\n * No error, no warning. An hour of debugging.\n *\n * Fix: the Vite plugin's `transformIndexHtml` hook runs this for every\n * served HTML. If the script is already present (by URL substring match\n * — handles every quoting/ordering variant) the HTML is returned\n * unchanged. Otherwise the script is inserted before `</body>`. If\n * there's no `</body>` at all (malformed HTML), the script is appended\n * at the end and we emit a console.warn in dev.\n */\n\nconst ENTRY_CLIENT_URL = '/@theo/entry-client'\nconst SCRIPT_TAG = `<script type=\"module\" src=\"${ENTRY_CLIENT_URL}\"></script>`\n\nexport interface InjectResult {\n html: string\n injected: boolean\n warning?: string\n}\n\nexport function injectEntryClient(html: string): InjectResult {\n // Detect via URL substring — robust against:\n // <script src='/@theo/entry-client'>\n // <script type=\"module\" src=\"/@theo/entry-client\" />\n // <link rel=\"modulepreload\" href=\"/@theo/entry-client\">\n if (html.includes(ENTRY_CLIENT_URL)) {\n return { html, injected: false }\n }\n\n // Inject before </body> (case-insensitive, first occurrence)\n const bodyClosePattern = /<\\/body\\s*>/i\n if (bodyClosePattern.test(html)) {\n return {\n html: html.replace(bodyClosePattern, (match) => ` ${SCRIPT_TAG}\\n ${match}`),\n injected: true,\n }\n }\n\n // Malformed HTML — append at end and warn\n return {\n html: `${html}\\n${SCRIPT_TAG}`,\n injected: true,\n warning:\n 'theokit: index.html has no </body> tag; entry-client script was appended at end. Add <body>…</body> to your template.',\n }\n}\n","/**\n * Inject `<link rel=\"stylesheet\">` tags into served HTML during DEV.\n *\n * Why this exists (real bug, 2026-05-22): the example chat app had an\n * LCP of 9-16s because the HTML response landed WITHOUT any `<link>` tag\n * for `@theokit/ui/styles.css`. CSS only loaded after entry-client.js\n * ran the layout import. Browser paint waited for the JS → CSS chain:\n *\n * HTML arrives → browser paints nothing\n * JS bundle arrives → React hydrates → encounters `import 'styles.css'`\n * CSS arrives → browser RE-paints with styles\n *\n * Fix: emit the `<link>` in the HTML head so the browser fetches CSS in\n * PARALLEL with JS. LCP becomes time-to-CSS instead of time-to-JS-exec.\n *\n * DEV-only: in production builds, Vite's SSR pipeline emits the\n * appropriate `<link>` via its own asset manifest (with content hashes).\n * We must not double-inject there.\n */\n\ninterface StylesheetTarget {\n /** Vite dev URL — what the browser hits */\n href: string\n /** node_modules path checked before injection */\n packageRoot: string\n}\n\nconst TARGETS: StylesheetTarget[] = [\n {\n href: '/@id/@theokit/ui/styles.css',\n packageRoot: '@theokit/ui',\n },\n]\n\n/**\n * Note (2026-05-23): font preloads were briefly added here to address a\n * \"FOUT-looking\" CLS of 0.39 measured in DevTools. They turned out to\n * be a misdiagnosis — the real cause was a React hydration mismatch\n * from `<StaticRouterProvider hydrate>` emitting a `<script>` inside\n * the React tree (fixed in commit 31506d1).\n *\n * Why we don't preload fonts:\n * - In dev, pnpm hoists @theokit/ui via `.pnpm/<hash>/...`. The CSS\n * `@font-face` resolves to the real path; our preload would use the\n * symlink path. Browser doesn't dedupe — preload is \"wasted\" and\n * Chrome logs \"preloaded but not used within a few seconds\".\n * - In prod, Vite's SSR bundle emits proper hashed preload metadata\n * for fonts referenced from compiled CSS. Manual preload there\n * would conflict.\n *\n * If a future regression brings back font-related CLS, the right path\n * is `font-display: optional` (no swap) or size-adjust metric matching\n * in @theokit/ui itself — not framework-side preload.\n */\n\nexport interface InjectStylesheetsResult {\n html: string\n injected: string[]\n}\n\nexport interface InjectStylesheetsOptions {\n /** Only inject in dev (default). Skip when building for production. */\n isDev: boolean\n /** Function that checks whether a package is installed at projectRoot. */\n hasPackage(name: string): boolean\n}\n\nexport function injectStylesheets(\n html: string,\n opts: InjectStylesheetsOptions,\n): InjectStylesheetsResult {\n if (!opts.isDev) return { html, injected: [] }\n\n const tagsToInject: string[] = []\n for (const target of TARGETS) {\n if (!opts.hasPackage(target.packageRoot)) continue\n // Idempotency: skip if href already present\n if (html.includes(target.href)) continue\n tagsToInject.push(`<link rel=\"stylesheet\" href=\"${target.href}\" />`)\n }\n\n if (tagsToInject.length === 0) return { html, injected: [] }\n\n const joined = tagsToInject.join('\\n ')\n // Inject before </head>; fall back to start of <body> if no head close.\n const headClosePattern = /<\\/head\\s*>/i\n if (headClosePattern.test(html)) {\n return {\n html: html.replace(headClosePattern, (match) => ` ${joined}\\n ${match}`),\n injected: tagsToInject,\n }\n }\n\n const bodyOpenPattern = /<body[^>]*>/i\n if (bodyOpenPattern.test(html)) {\n return {\n html: html.replace(bodyOpenPattern, (match) => `${match}\\n ${joined}`),\n injected: tagsToInject,\n }\n }\n\n // Malformed HTML — prepend and trust the browser\n return { html: `${joined}\\n${html}`, injected: tagsToInject }\n}\n","export interface EntryServerOptions {\n /** When true, emit a streaming entry using onShellReady + signal cleanup.\n * When false (default), emit the legacy single-shot onAllReady entry. */\n streaming?: boolean\n /**\n * TheoUI config — when present, the SSR React tree wraps StaticRouterProvider\n * in <TheoUIProvider> + <Suspense> to MATCH the client entry exactly. Without\n * this, hydration falls back silently because the trees differ — button\n * onClick handlers never get attached and the page looks dead.\n *\n * EC-2 (CSS): the SSR entry never imports CSS. Only the React tree is\n * mirrored — the CSS stays client-only.\n */\n theoUi?: { theme?: 'violet-forge' | 'noir' | 'paper' }\n}\n\nexport function generateEntryServer(options: EntryServerOptions = {}): string {\n if (options.streaming) {\n return generateStreamingEntry(options)\n }\n return generateSingleShotEntry(options)\n}\n\n/**\n * Build the React element tree the server renders. Must mirror the client\n * tree shape from `generateEntryClient` — same wrapper components, same\n * order — or hydration silently falls back to client-only render.\n */\nfunction buildAppTreeJs(options: EntryServerOptions): string {\n const theme = options.theoUi?.theme ?? 'violet-forge'\n // T4.1 — pass options.nonce to StaticRouterProvider so its internal\n // hydration data script (`<script>window.__staticRouterHydrationData\n // = ...</script>`) carries the nonce attribute. Without this, CSP\n // enforce mode (without 'unsafe-inline') blocks the hydration script\n // → React falls back to client-only render → button onClick handlers\n // never attach → page looks dead. The nonce option to\n // renderToPipeableStream covers React-emitted scripts but NOT the\n // hydration script which is emitted by react-router itself.\n // hydrate: false — CRITICAL fix for hydration mismatch.\n //\n // StaticRouterProvider with `hydrate: true` (default) emits\n // `<script>window.__staticRouterHydrationData = ...</script>` INSIDE\n // the React tree. The client's `<RouterProvider>` does NOT emit any\n // script. React's reconciler sees server={...stuff, <script>} vs\n // client={...stuff} and DISCARDS the entire server tree, regenerating\n // from scratch on the client. That regeneration causes a massive\n // layout shift (CLS 0.39 measured in the example).\n //\n // Fix: tell StaticRouterProvider to NOT emit the script. The framework\n // emits the hydration data as a separate `<script>` in the HTML\n // template (outside #root), via the `hydrationData` returned from\n // `render()`. The script still runs BEFORE entry-client.js, so\n // window.__staticRouterHydrationData is populated when\n // createBrowserRouter reads it.\n if (options.theoUi) {\n return [\n `React.createElement(TheoUIProvider, { theme: { defaultTheme: '${theme}' } },`,\n ` React.createElement(Suspense, { fallback: null },`,\n ` React.createElement(StaticRouterProvider, { router, context, hydrate: false })`,\n ` )`,\n ` )`,\n ].join('\\n')\n }\n return `React.createElement(Suspense, { fallback: null },\\n React.createElement(StaticRouterProvider, { router, context, hydrate: false })\\n )`\n}\n\n/**\n * Generate the hydration data extraction snippet. Reads\n * loaderData/actionData/errors from the StaticHandlerContext and returns\n * them as an object the framework can serialize into a `<script>` tag.\n */\nfunction hydrationDataExtractSnippet(): string {\n return [\n ` const hydrationData = {`,\n ` loaderData: context.loaderData,`,\n ` actionData: context.actionData,`,\n ` errors: context.errors,`,\n ` }`,\n ].join('\\n')\n}\n\nfunction generateSingleShotEntry(options: EntryServerOptions): string {\n const theoUiImport = options.theoUi ? `import { TheoUIProvider } from '@theokit/ui'\\n` : ''\n const appTree = buildAppTreeJs(options)\n return [\n `import React, { Suspense } from 'react'`,\n `import { renderToPipeableStream } from 'react-dom/server'`,\n `import { createStaticHandler, createStaticRouter, StaticRouterProvider } from 'react-router'`,\n `import { PassThrough } from 'node:stream'`,\n `import { routes } from '/@theo/route-manifest'`,\n theoUiImport,\n `export async function render(url, options = {}) {`,\n ` const handler = createStaticHandler(routes)`,\n ` const request = new Request('http://localhost' + url)`,\n ` const context = await handler.query(request)`,\n ``,\n ` if (context instanceof Response) {`,\n ` return { redirect: context }`,\n ` }`,\n ``,\n ` const router = createStaticRouter(handler.dataRoutes, context)`,\n ` const app = ${appTree}`,\n ``,\n hydrationDataExtractSnippet(),\n ``,\n ` return new Promise((resolve, reject) => {`,\n ` let html = ''`,\n ` let piped = false`,\n ` const passthrough = new PassThrough()`,\n ` passthrough.on('data', (chunk) => { html += chunk.toString() })`,\n ` passthrough.on('end', () => { resolve({ html, hydrationData }) })`,\n ` passthrough.on('error', reject)`,\n ``,\n ` // Pipe on onShellReady (Next.js pattern). Calling pipe() twice`,\n ` // throws \"React currently only supports piping to one writable`,\n ` // stream\". The \\`piped\\` flag is a belt-and-suspenders guard if`,\n ` // onShellReady fires unexpectedly more than once.`,\n ` // Forward options.nonce to React so every <script> tag React`,\n ` // emits (Suspense boundary scripts) carries the nonce attribute.`,\n ` const { pipe } = renderToPipeableStream(app, {`,\n ` nonce: options.nonce,`,\n ` onShellReady() { if (!piped) { piped = true; pipe(passthrough) } },`,\n ` onShellError(err) { reject(err) },`,\n ` onError(err) { console.error('[SSR Error]', err) },`,\n ` })`,\n ` })`,\n `}`,\n ].join('\\n')\n}\n\n// Generated-code fragments — extracted so the parent emitter stays under\n// the max-lines-per-function ceiling.\nfunction streamingWebRenderer(appTree: string): string[] {\n return [\n `// T2.3 — Web Standards streaming entry for edge runtimes (Cloudflare,`,\n `// Bun, Deno, Vercel Edge). Uses renderToReadableStream and returns a`,\n `// Response with the stream as body. Honors request.signal for client`,\n `// disconnect cleanup.`,\n `export async function renderStreamingWeb(request, options = {}) {`,\n ` const handler = createStaticHandler(routes)`,\n ` const url = new URL(request.url)`,\n ` const context = await handler.query(request)`,\n ``,\n ` if (context instanceof Response) {`,\n ` return context`,\n ` }`,\n ``,\n ` const router = createStaticRouter(handler.dataRoutes, context)`,\n ` const app = ${appTree}`,\n ``,\n ` const stream = await renderToReadableStream(app, {`,\n ` signal: request.signal,`,\n ` nonce: options.nonce,`,\n ` onError(err) { console.error('[SSR Web Stream Error]', err) },`,\n ` })`,\n ` return new Response(stream, {`,\n ` status: 200,`,\n ` headers: {`,\n ` 'Content-Type': 'text/html; charset=utf-8',`,\n ` 'Transfer-Encoding': 'chunked',`,\n ` },`,\n ` })`,\n `}`,\n ]\n}\n\nfunction streamingNodeRenderer(appTree: string): string[] {\n return [\n `// T6.1 — Node streaming SSR entry (opt-in via theo.config.ts > ssrStreaming: true)`,\n `// Flushes the shell as soon as it's ready, then streams Suspense boundaries.`,\n `// EC-11: respects request.signal for client-disconnect cleanup.`,\n `export async function renderStreaming(url, response, options = {}) {`,\n ` const handler = createStaticHandler(routes)`,\n ` const request = new Request('http://localhost' + url, { signal: options.signal })`,\n ` const context = await handler.query(request)`,\n ``,\n ` if (context instanceof Response) {`,\n ` return { redirect: context }`,\n ` }`,\n ``,\n ` const router = createStaticRouter(handler.dataRoutes, context)`,\n ` const app = ${appTree}`,\n ``,\n ` return new Promise((resolve, reject) => {`,\n ` let didError = false`,\n ` const stream = renderToPipeableStream(app, {`,\n ` nonce: options.nonce,`,\n ` onShellReady() {`,\n ` response.statusCode = didError ? 500 : 200`,\n ` response.setHeader('Content-Type', 'text/html; charset=utf-8')`,\n ` response.setHeader('Transfer-Encoding', 'chunked')`,\n ` stream.pipe(response)`,\n ` resolve({ streaming: true })`,\n ` },`,\n ` onShellError(err) { reject(err) },`,\n ` onError(err) {`,\n ` didError = true`,\n ` console.error('[SSR Stream Error]', err)`,\n ` },`,\n ` })`,\n ``,\n ` // EC-11: client disconnect cleanup`,\n ` if (options.signal) {`,\n ` options.signal.addEventListener('abort', () => { stream.abort() })`,\n ` }`,\n ` })`,\n `}`,\n ]\n}\n\nfunction backCompatRenderer(appTree: string): string[] {\n return [\n `// Backward compatibility: keep the single-shot render export available so`,\n `// callers that always used 'render()' don't break when streaming is on.`,\n `export async function render(url, options = {}) {`,\n ` const handler = createStaticHandler(routes)`,\n ` const request = new Request('http://localhost' + url)`,\n ` const context = await handler.query(request)`,\n ``,\n ` if (context instanceof Response) {`,\n ` return { redirect: context }`,\n ` }`,\n ``,\n ` const router = createStaticRouter(handler.dataRoutes, context)`,\n ` const app = ${appTree}`,\n ``,\n hydrationDataExtractSnippet(),\n ``,\n ` const { PassThrough } = await import('node:stream')`,\n ` return new Promise((resolve, reject) => {`,\n ` let html = ''`,\n ` let piped = false`,\n ` const passthrough = new PassThrough()`,\n ` passthrough.on('data', (chunk) => { html += chunk.toString() })`,\n ` passthrough.on('end', () => { resolve({ html, hydrationData }) })`,\n ` passthrough.on('error', reject)`,\n ``,\n ` // Pipe on onShellReady (Next.js pattern). nonce forwarded.`,\n ` const { pipe } = renderToPipeableStream(app, {`,\n ` nonce: options.nonce,`,\n ` onShellReady() { if (!piped) { piped = true; pipe(passthrough) } },`,\n ` onShellError(err) { reject(err) },`,\n ` onError(err) { console.error('[SSR Error]', err) },`,\n ` })`,\n ` })`,\n `}`,\n ]\n}\n\nfunction generateStreamingEntry(options: EntryServerOptions): string {\n const theoUiImport = options.theoUi ? `import { TheoUIProvider } from '@theokit/ui'\\n` : ''\n const appTree = buildAppTreeJs(options)\n return [\n `import React, { Suspense } from 'react'`,\n `import { renderToPipeableStream, renderToReadableStream } from 'react-dom/server'`,\n `import { createStaticHandler, createStaticRouter, StaticRouterProvider } from 'react-router'`,\n `import { routes } from '/@theo/route-manifest'`,\n theoUiImport,\n ``,\n ...streamingWebRenderer(appTree),\n ``,\n ...streamingNodeRenderer(appTree),\n ``,\n ...backCompatRenderer(appTree),\n ].join('\\n')\n}\n","export interface EntryClientOptions {\n theoUi?: {\n fonts?: 'bundled' | 'cdn'\n theme?: 'violet-forge' | 'noir' | 'paper'\n }\n}\n\nexport function generateEntryClient(ssr?: boolean, opts: EntryClientOptions = {}): string {\n const rootMethod = ssr ? 'hydrateRoot' : 'createRoot'\n\n // T2.2 — TheoUI CSS imports (client-only; EC-2: NEVER in entry-server)\n // T2.3 — Wrap RouterProvider in <TheoUIProvider>\n const theoUiImports: string[] = []\n if (opts.theoUi) {\n theoUiImports.push(\n `// T2.2 — TheoUI CSS auto-injected (config.ui)`,\n `import '@theokit/ui/styles.css'`,\n )\n const fontsModule = opts.theoUi.fonts === 'cdn' ? 'fonts-cdn.css' : 'fonts.css'\n theoUiImports.push(\n `import '@theokit/ui/${fontsModule}'`,\n `// T2.3 — TheoUIProvider auto-wraps RouterProvider`,\n `import { TheoUIProvider } from '@theokit/ui'`,\n )\n }\n\n const theme = opts.theoUi?.theme ?? 'violet-forge'\n // Build the React tree: when theoUi enabled, RouterProvider sits inside\n // TheoUIProvider; otherwise RouterProvider is the top-level child.\n const routerTree = opts.theoUi\n ? `React.createElement(TheoUIProvider, { theme: { defaultTheme: '${theme}' } },\\n React.createElement(Suspense, { fallback: null },\\n React.createElement(RouterProvider, { router })\\n )\\n )`\n : `React.createElement(Suspense, { fallback: null },\\n React.createElement(RouterProvider, { router })\\n )`\n\n const renderCall = ssr\n ? ` ${rootMethod}(el,\\n ${routerTree}\\n )`\n : ` ${rootMethod}(el).render(\\n ${routerTree}\\n )`\n\n // SSR hydration: <StaticRouterProvider hydrate> emits\n // `<script>window.__staticRouterHydrationData = …</script>` into the\n // server HTML. The browser router MUST receive this so it continues\n // from the server's state instead of re-fetching everything.\n //\n // Without `hydrationData`, `createBrowserRouter` boots from scratch,\n // React detects a DOM mismatch with the SSR-rendered HTML, and\n // hydration silently falls back to client-only render — every\n // `onClick` handler attached during hydration is lost. The page\n // looks fine but is \"dead HTML\".\n const hydrationLine = ssr\n ? `const router = createBrowserRouter(routes, { hydrationData: window.__staticRouterHydrationData })`\n : `const router = createBrowserRouter(routes)`\n\n // Phase 4 — Code-splitting + matchRoutes safeguard (EC-3).\n //\n // SSR mode: pages are React.lazy()-wrapped in the manifest. If we render\n // before the matched route's module is loaded, React.lazy throws a\n // promise, the outer Suspense fires its fallback (null), and the SSR\n // DOM is wiped before hydration → onClick handlers die.\n //\n // The fix:\n // 1. matchRoutes(routes, location.pathname) on the client to discover\n // which routes actually render at this URL. Using the client matcher\n // (not a server hint) avoids URL-drift races: SSR may have prepared\n // /foo while a browser auto-redirect now points at /bar.\n // 2. Look up each matched route's path in __theoPreloadMap and call\n // the import() factory. Browsers cache modules by URL — when\n // React.lazy fires its own import() during render, it gets the\n // cached promise instantly.\n // 3. Promise.all with a 1500ms timeout. On slow networks we'd rather\n // lose hydration on ONE request than hang the page forever. The\n // fallback path proceeds to hydrate anyway — React.lazy will then\n // Suspense its fallback as usual.\n const preloadBlock = ssr\n ? [\n `// Phase 4 — preload matched-route modules before hydrate (EC-3 safeguard)`,\n `const __theoMatches = matchRoutes(routes, window.location.pathname) ?? []`,\n `const __theoPreloadPaths = __theoMatches`,\n ` .map((m) => m.route && (m.route).path)`,\n ` .filter((p) => typeof p === 'string' && p in __theoPreloadMap)`,\n `const __theoPreloadPromise = Promise.all(`,\n ` __theoPreloadPaths.map((p) => __theoPreloadMap[p]().catch((err) => { console.error('[theo] preload failed', p, err); return null }))`,\n `)`,\n `const __theoTimeout = new Promise((resolve) => setTimeout(() => resolve('timeout'), 1500))`,\n `await Promise.race([__theoPreloadPromise, __theoTimeout])`,\n '',\n ]\n : []\n\n // The hydrate/render call needs to live inside an async IIFE when we\n // await preloads. In CSR-only mode we keep the existing synchronous\n // block for backward compat.\n const renderBlock = ssr\n ? [\n `if (el) {`,\n ` ;(async () => {`,\n ...preloadBlock.map((l) => ' ' + l),\n renderCall,\n ` })()`,\n `}`,\n ]\n : [`if (el) {`, renderCall, `}`]\n\n const manifestImports = ssr\n ? `import { routes, __theoPreloadMap } from '/@theo/route-manifest'`\n : `import { routes } from '/@theo/route-manifest'`\n\n const reactRouterImports = ssr\n ? `import { createBrowserRouter, RouterProvider, matchRoutes } from 'react-router'`\n : `import { createBrowserRouter, RouterProvider } from 'react-router'`\n\n return [\n `import React, { Suspense } from 'react'`,\n `import { ${rootMethod} } from 'react-dom/client'`,\n reactRouterImports,\n manifestImports,\n `// T1.3 — side-effect import sets globalThis.__THEO_TRANSFORMER__ for theoFetch`,\n `import '/@theo/runtime-config'`,\n ...theoUiImports,\n ``,\n hydrationLine,\n `const el = document.getElementById('root')`,\n ...renderBlock,\n ].join('\\n')\n}\n","import type { RouteNode } from './types.js'\n\nfunction normalizePath(p: string): string {\n return p.replace(/\\\\/g, '/')\n}\n\nfunction safeVarName(segment: string, prefix: string): string {\n const safe = segment.replace(/[^a-zA-Z0-9]/g, '_') || 'root'\n return `${prefix}_${safe}`\n}\n\n/**\n * Map a route node to its react-router path segment. Dynamic `[slug]` →\n * `:slug`; catch-all `[...slug]` → `*` (react-router splat — param read via\n * `params['*']`); static segments pass through unchanged. (T2.2 — the page\n * router uses react-router's own matcher, NOT the server regex; see plan D3.)\n */\nfunction segmentPath(node: RouteNode): string {\n if (node.dynamic?.catchAll) return '*'\n if (node.dynamic) return `:${node.dynamic.paramName}`\n return node.segment\n}\n\ninterface ImportEntry {\n varName: string\n importPath: string\n}\n\n/**\n * Build the absolute route path for a node by accumulating segments from\n * the root. Used to key the preload map exactly as react-router's\n * `matchRoutes` reports `match.route.path`.\n */\nfunction buildRoutePath(parents: string[], segment: string): string {\n const joined = [...parents, segment].filter(Boolean).join('/')\n return '/' + joined\n}\n\ninterface WalkAccumulator {\n staticImports: ImportEntry[]\n lazyPages: { varName: string; importPath: string; routePath: string }[]\n layoutState: { found: boolean }\n}\n\nfunction pushIf(staticImports: ImportEntry[], filePath: string | undefined, varName: string): void {\n if (filePath !== undefined) {\n staticImports.push({ varName, importPath: normalizePath(filePath) })\n }\n}\n\nfunction walkRouteTree(node: RouteNode, parents: string[], acc: WalkAccumulator): void {\n const seg = node.segment || 'root'\n const routePath = buildRoutePath(parents, segmentPath(node))\n\n if (node.page !== undefined) {\n acc.lazyPages.push({\n varName: safeVarName(seg, 'Page'),\n importPath: normalizePath(node.page),\n routePath,\n })\n }\n if (node.layout !== undefined) acc.layoutState.found = true\n pushIf(acc.staticImports, node.layout, safeVarName(seg, 'Layout'))\n pushIf(acc.staticImports, node.error, safeVarName(seg, 'Error'))\n pushIf(acc.staticImports, node.loading, safeVarName(seg, 'Loading'))\n pushIf(acc.staticImports, node.notFound, safeVarName(seg, 'NotFound'))\n for (const child of node.children) {\n const childSegPath = segmentPath(node)\n const nextParents = childSegPath ? [...parents, childSegPath] : parents\n walkRouteTree(child, nextParents, acc)\n }\n}\n\nexport function generateRouteManifest(tree: RouteNode): string {\n // Static imports (always-needed at boot): layouts, errors, loading, not-found.\n // Lazy-loaded pages — tracked separately so we emit React.lazy() and\n // build the preload map.\n const acc: WalkAccumulator = {\n staticImports: [],\n lazyPages: [],\n layoutState: { found: false },\n }\n walkRouteTree(tree, [], acc)\n const staticImports = acc.staticImports\n const lazyPages = acc.lazyPages\n const layoutState = acc.layoutState\n\n // Phase 4 — Code-splitting + matchRoutes safeguard (EC-3).\n // PAGES are lazy. LAYOUTS / ERROR / LOADING / NOT-FOUND stay static\n // because they're always needed at boot regardless of route.\n // The preload map exposes the same `import()` calls keyed by absolute\n // route path. The entry-client re-matches `routes` against\n // `location.pathname` and awaits the matched entries BEFORE\n // `hydrateRoot`, so React.lazy modules resolve from cache and no\n // Suspense fallback fires during hydration.\n const lines: string[] = [`import React, { Suspense } from 'react'`]\n\n if (layoutState.found) {\n lines.push(`import { Outlet } from 'react-router'`)\n }\n\n lines.push('')\n\n // Static imports first\n for (const imp of staticImports) {\n lines.push(`import ${imp.varName} from '${imp.importPath}'`)\n }\n\n // Lazy-loaded pages\n for (const lp of lazyPages) {\n lines.push(`const ${lp.varName} = React.lazy(() => import('${lp.importPath}'))`)\n }\n\n lines.push('')\n\n // Preload map — keys are absolute route paths, values are factories that\n // return the same import() the lazy() above resolves. Browsers cache the\n // module by URL so the preload + lazy() share a single promise.\n const preloadEntries = lazyPages.map(\n (lp) => ` '${lp.routePath}': () => import('${lp.importPath}'),`,\n )\n // No TS type annotation — this manifest is emitted as a virtual JS module\n // and Rollup rejects type annotations in production builds.\n lines.push('export const __theoPreloadMap = {')\n for (const e of preloadEntries) lines.push(e)\n lines.push('}', '')\n\n // Build the children-array string for one node, separately from the\n // wrapping logic — keeps `genRouteConfig` under the complexity ceiling.\n function buildChildrenArray(node: RouteNode, seg: string): string {\n const childConfigs: string[] = []\n\n // Index route for this node's page — wrap in Suspense (the lazy module\n // is preloaded on initial hydrate, so this fallback never fires there;\n // it covers client-side navigation to other routes too).\n if (node.page) {\n const pageVar = safeVarName(seg, 'Page')\n const fallbackEl = node.loading\n ? `React.createElement(${safeVarName(seg, 'Loading')})`\n : 'null'\n const pageElement = `React.createElement(Suspense, { fallback: ${fallbackEl} }, React.createElement(${pageVar}))`\n childConfigs.push(`{ index: true, element: ${pageElement} }`)\n }\n\n // Child routes\n for (const child of node.children) {\n childConfigs.push(genRouteConfig(child, false))\n }\n\n // Not-found wildcard (only at this level)\n if (node.notFound) {\n const nfVar = safeVarName(seg, 'NotFound')\n childConfigs.push(`{ path: '*', element: React.createElement(${nfVar}) }`)\n }\n\n let arr = `[${childConfigs.join(', ')}]`\n if (node.error) {\n const errVar = safeVarName(seg, 'Error')\n arr = `[{ errorElement: React.createElement(${errVar}), children: ${arr} }]`\n }\n return arr\n }\n\n // Generate route config\n function genRouteConfig(node: RouteNode, isRoot: boolean): string {\n const seg = node.segment || 'root'\n const childrenArray = buildChildrenArray(node, seg)\n\n // Build route object\n if (node.layout) {\n const layoutVar = safeVarName(seg, 'Layout')\n const pathPart = isRoot ? `path: '/'` : `path: '${segmentPath(node)}'`\n // Layout receives `<Outlet />` as `children` prop. This supports BOTH\n // conventions: Next.js-style layouts that render `{children}` AND\n // layouts that call `<Outlet />` directly (the prop is the same element,\n // ignored by the latter). Without this, Next.js-style templates render\n // empty because react-router does not pass a `children` prop by default.\n return `{ ${pathPart}, element: React.createElement(${layoutVar}, { children: React.createElement(Outlet) }), children: ${childrenArray} }`\n }\n\n // No layout — if root, wrap in path '/'\n if (isRoot) {\n if (node.children.length === 0 && !node.page && !node.notFound && !node.error) {\n return `{ path: '/', children: [] }`\n }\n // Root without layout: children are direct routes\n return `{ path: '/', children: ${childrenArray} }`\n }\n\n // Child segment without layout — just a route\n if (node.page && node.children.length === 0 && !node.error && !node.notFound) {\n const pageVar = safeVarName(seg, 'Page')\n const fallbackEl = node.loading\n ? `React.createElement(${safeVarName(seg, 'Loading')})`\n : 'null'\n const pageElement = `React.createElement(Suspense, { fallback: ${fallbackEl} }, React.createElement(${pageVar}))`\n return `{ path: '${segmentPath(node)}', element: ${pageElement} }`\n }\n\n // Child with children but no layout\n return `{ path: '${segmentPath(node)}', children: ${childrenArray} }`\n }\n\n const routeConfig = genRouteConfig(tree, true)\n lines.push(`export const routes = [${routeConfig}]`)\n\n return lines.join('\\n')\n}\n","/**\n * Virtual modules resolveId + load extraction (T2.6 / M6).\n *\n * Pure structural split — every branch identity preserved from the\n * original inline body in `theoPlugin()`. The dispatcher is purely\n * synchronous; effects (broadcast, transformer wiring) keep their\n * original ordering so EC-10 (Vite hook ordering side effects) is\n * honored.\n */\n\nimport { broadcastRouteManifest } from '../devtools/server-side/route-manifest.js'\nimport { generateEntryServer } from '../router/entry-server.js'\nimport { generateEntryClient } from '../router/entry.js'\nimport { generateRouteManifest } from '../router/generate.js'\nimport { scanRoutes } from '../router/scan.js'\nimport type { TheoTransformer } from '../server/transformer.js'\n\nimport { DEVTOOLS_RESOLVED_ID, DEVTOOLS_VIRTUAL_ID } from './inject-devtools.js'\nimport type { TheoUiDetectResult } from './theoui-detect.js'\n\nexport interface VirtualModuleIds {\n VIRTUAL_ENTRY_ID: string\n RESOLVED_ENTRY_ID: string\n VIRTUAL_MANIFEST_ID: string\n RESOLVED_MANIFEST_ID: string\n VIRTUAL_ENTRY_SERVER_ID: string\n RESOLVED_ENTRY_SERVER_ID: string\n VIRTUAL_RUNTIME_CONFIG_ID: string\n RESOLVED_RUNTIME_CONFIG_ID: string\n}\n\nexport interface VirtualModulesCtx {\n ids: VirtualModuleIds\n appDir: string\n ssrEnabled: boolean\n streamingEnabled: boolean\n theoUi: TheoUiDetectResult | undefined\n transformer: TheoTransformer | undefined\n}\n\nexport function resolveVirtualModuleId(id: string, ids: VirtualModuleIds): string | undefined {\n if (id === ids.VIRTUAL_ENTRY_ID) return ids.RESOLVED_ENTRY_ID\n if (id === ids.VIRTUAL_MANIFEST_ID) return ids.RESOLVED_MANIFEST_ID\n if (id === ids.VIRTUAL_ENTRY_SERVER_ID) return ids.RESOLVED_ENTRY_SERVER_ID\n if (id === ids.VIRTUAL_RUNTIME_CONFIG_ID) return ids.RESOLVED_RUNTIME_CONFIG_ID\n // T1.2 — devtools virtual module. Only resolves in dev; build mode\n // never serves it because transformIndexHtml never injects the tag.\n if (id === DEVTOOLS_VIRTUAL_ID) return DEVTOOLS_RESOLVED_ID\n return undefined\n}\n\nexport function loadVirtualModule(id: string, ctx: VirtualModulesCtx): string | undefined {\n if (id === ctx.ids.RESOLVED_ENTRY_ID) {\n return generateEntryClient(ctx.ssrEnabled, {\n theoUi: ctx.theoUi?.enabled\n ? { fonts: ctx.theoUi.config.fonts, theme: ctx.theoUi.config.theme }\n : undefined,\n })\n }\n if (id === ctx.ids.RESOLVED_MANIFEST_ID) {\n const tree = scanRoutes(ctx.appDir)\n // T3.1 — also broadcast a devtools-shaped manifest to the overlay\n // (no-op in prod / when no dev server is attached).\n broadcastRouteManifest(tree)\n return generateRouteManifest(tree)\n }\n if (id === ctx.ids.RESOLVED_ENTRY_SERVER_ID) {\n // SSR tree MUST mirror client tree shape — pass theoUi through so\n // <TheoUIProvider> wraps in both. Without this, React detects a\n // hydration mismatch and silently falls back to client-only\n // render — onClick handlers never get attached.\n return generateEntryServer({\n streaming: ctx.streamingEnabled,\n theoUi: ctx.theoUi?.enabled ? { theme: ctx.theoUi.config.theme } : undefined,\n })\n }\n if (id === ctx.ids.RESOLVED_RUNTIME_CONFIG_ID) {\n // T1.3 — set globalThis.__THEO_TRANSFORMER__ so theoFetch picks it up\n const tName = ctx.transformer?.name ?? 'json'\n return [\n `// Generated by Theo Vite plugin`,\n `;(globalThis).__THEO_TRANSFORMER__ = ${JSON.stringify(tName)}`,\n `export const TRANSFORMER_NAME = ${JSON.stringify(tName)}`,\n ].join('\\n')\n }\n if (id === DEVTOOLS_RESOLVED_ID) {\n // T1.2 — virtual module re-exports the real entry from theokit's devtools subpath.\n return [\n `// Theo devtools — virtual entry (DEV only)`,\n `import('theokit/devtools/entry').catch((e) => console.error('[theo devtools] mount failed', e))`,\n ].join('\\n')\n }\n return undefined\n}\n","/**\n * T3.1 — Vite integration extension API (`defineTheoIntegration`).\n *\n * Build-time extension system (mirrors Astro Integrations). Lets third\n * parties hook into Theo's Vite lifecycle without forking the plugin.\n *\n * Strictly separated from runtime `defineTheoPlugin` (Phase 4) — different\n * concerns, different surfaces. See ADR D7 in the plan.\n */\n\nexport type HookName =\n | 'theo:config:setup'\n | 'theo:build:start'\n | 'theo:build:done'\n | 'theo:dev:start'\n\nexport interface HookContext {\n addVirtualModule?: (id: string, code: string) => void\n addRoute?: (path: string, handler: RouteHandler) => void\n [key: string]: unknown\n}\n\nexport type Hook = (ctx: HookContext) => void | Promise<void>\n\nexport type RouteHandler = (request: Request) => Response | Promise<Response>\n\nexport interface TheoIntegration {\n name: string\n hooks: Partial<Record<HookName, Hook>>\n}\n\n/**\n * Identity factory for type-checking against TheoIntegration shape.\n */\nexport function defineTheoIntegration(integration: TheoIntegration): TheoIntegration {\n return integration\n}\n\nexport class IntegrationVirtualModulePrefixError extends Error {\n constructor(integrationName: string, id: string) {\n super(\n `Integration \"${integrationName}\" tried to addVirtualModule(\"${id}\"). ` +\n `Virtual module IDs must start with \"virtual:integration:${integrationName}/\" ` +\n `to avoid collisions with Theo internals or other integrations.`,\n )\n this.name = 'IntegrationVirtualModulePrefixError'\n }\n}\n\nexport class IntegrationRouteCollisionError extends Error {\n constructor(integrationName: string, path: string) {\n super(\n `Integration \"${integrationName}\" tried to register route \"${path}\", ` +\n `but it conflicts with an existing route. Choose a different path.`,\n )\n this.name = 'IntegrationRouteCollisionError'\n }\n}\n\nexport interface IntegrationRegistryOptions {\n /** Routes already scanned from `server/routes/`. Used to detect collisions. */\n existingRoutes: string[]\n}\n\nexport interface IntegrationRoute {\n path: string\n owner: string\n}\n\nexport interface IntegrationRegistry {\n registerIntegration(integration: TheoIntegration): void\n fire(hookName: HookName, baseCtx: Record<string, unknown>): Promise<void>\n addVirtualModule(integrationName: string, id: string, code: string): void\n addRoute(integrationName: string, path: string, handler: RouteHandler): void\n getVirtualModule(id: string): string | undefined\n listVirtualModules(): string[]\n listRoutes(): IntegrationRoute[]\n /** Test helper: invoke hook surface directly without firing the lifecycle. */\n callHook(\n integrationName: string,\n hookName: HookName,\n extraCtx: Partial<HookContext>,\n ): Promise<void>\n}\n\nexport function createIntegrationRegistry(\n options: IntegrationRegistryOptions,\n): IntegrationRegistry {\n const integrations: TheoIntegration[] = []\n const virtualModules = new Map<string, { code: string; owner: string }>()\n const routes: { path: string; owner: string; handler: RouteHandler }[] = []\n const userRoutes = new Set(options.existingRoutes)\n\n function buildHookCtxFor(integrationName: string, extra: Partial<HookContext>): HookContext {\n return {\n ...extra,\n addVirtualModule: (id: string, code: string) => {\n addVirtualModule(integrationName, id, code)\n },\n addRoute: (path: string, handler: RouteHandler) => {\n addRoute(integrationName, path, handler)\n },\n }\n }\n\n function addVirtualModule(integrationName: string, id: string, code: string): void {\n const expectedPrefix = `virtual:integration:${integrationName}/`\n if (!id.startsWith(expectedPrefix)) {\n throw new IntegrationVirtualModulePrefixError(integrationName, id)\n }\n virtualModules.set(id, { code, owner: integrationName })\n }\n\n function addRoute(integrationName: string, path: string, handler: RouteHandler): void {\n if (userRoutes.has(path)) {\n throw new IntegrationRouteCollisionError(integrationName, path)\n }\n if (routes.some((r) => r.path === path)) {\n throw new IntegrationRouteCollisionError(integrationName, path)\n }\n routes.push({ path, owner: integrationName, handler })\n }\n\n return {\n registerIntegration(integration) {\n integrations.push(integration)\n },\n async fire(hookName, baseCtx) {\n for (const intg of integrations) {\n const hook = intg.hooks[hookName]\n if (!hook) continue\n try {\n await hook(buildHookCtxFor(intg.name, baseCtx))\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err))\n const wrapped = new Error(\n `Integration \"${intg.name}\" hook \"${hookName}\" threw: ${e.message}`,\n )\n ;(wrapped as { cause?: unknown }).cause = e\n throw wrapped\n }\n }\n },\n addVirtualModule,\n addRoute,\n getVirtualModule(id) {\n return virtualModules.get(id)?.code\n },\n listVirtualModules() {\n return Array.from(virtualModules.keys())\n },\n listRoutes() {\n return routes.map((r) => ({ path: r.path, owner: r.owner }))\n },\n // eslint-disable-next-line @typescript-eslint/require-await -- async surface for the public callHook contract\n async callHook(integrationName, _hookName, extraCtx) {\n // Build the ctx for parity with `fire()` so test invocations\n // observe the same shape; we don't actually need the value here.\n buildHookCtxFor(integrationName, extraCtx)\n // Surface for direct test invocation; production code uses fire()\n if (typeof extraCtx.addVirtualModule === 'function') {\n extraCtx.addVirtualModule(\n `virtual:integration:${integrationName}/test`,\n 'export const ok = true',\n )\n }\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,SAAS,cAAAA,mBAAkB;AAC3B,SAAS,WAAAC,UAAS,WAAAC,gBAAe;AACjC,SAAS,qBAAqB;;;ACF9B,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AAiBjB,SAAS,cAAc,KAA6C;AAEzE,QAAM,MAAM,WAAW,QAAQ,IAAI,YAAY,UAAU,CAAC,IAAI,QAAQ;AAKtE,QAAM,oBAA8B,CAAC;AACrC,aAAW,aAAa,CAAC,kBAAkB,gBAAgB,cAAc,GAAG;AAC1E,UAAM,OAAO,QAAQ,IAAI,aAAa,SAAS;AAC/C,QAAI,WAAW,IAAI,EAAG,mBAAkB,KAAK,KAAK,SAAS,EAAE;AAAA,EAC/D;AAIA,QAAM,gBACJ,IAAI,YAAY,OAAO,KAAK,IAAI,QAAQ,EAAE,SAAS,IAC/C,yBAAyB,IAAI,QAAQ,IACrC;AAQN,SAAO;AAAA,IACL,WAAW;AAAA,IACX,cAAc;AAAA,MACZ,GAAI,IAAI,oBAAoB,SAAS,IAAI,EAAE,SAAS,IAAI,oBAAoB,IAAI,CAAC;AAAA,MACjF,OAAO;AAAA,IACT;AAAA,IACA,QAAQ;AAAA,MACN,GAAI,kBAAkB,SAAS,IAAI,EAAE,QAAQ,EAAE,aAAa,kBAAkB,EAAE,IAAI,CAAC;AAAA,MACrF,GAAI,kBAAkB,SAAY,EAAE,OAAO,cAAc,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAM9D,OAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,OAAO;AAAA;AAAA;AAAA,QAGL,EAAE,MAAM,kBAAkB,aAAa,QAAQ,IAAI,YAAY,eAAe,GAAG,EAAE,EAAE;AAAA,QACrF,EAAE,MAAM,kBAAkB,aAAa,QAAQ,IAAI,YAAY,eAAe,GAAG,EAAE,EAAE;AAAA,QACrF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAME,MAAM;AAAA,UACN,aAAa,QAAQ,IAAI,YAAY,qBAAqB,GAAG,EAAE;AAAA,QACjE;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,aAAa,QAAQ,IAAI,YAAY,oBAAoB,GAAG,EAAE;AAAA,QAChE;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,aAAa,QAAQ,IAAI,YAAY,oBAAoB,GAAG,EAAE;AAAA,QAChE;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,aAAa,QAAQ,IAAI,YAAY,mBAAmB,GAAG,EAAE;AAAA,QAC/D;AAAA;AAAA;AAAA;AAAA,QAIA;AAAA,UACE,MAAM;AAAA,UACN,aAAa;AAAA,YACX,IAAI;AAAA,YACJ,QAAQ,QAAQ,2BAA2B;AAAA,UAC7C;AAAA,QACF;AAAA,QACA,EAAE,MAAM,WAAW,aAAa,QAAQ,IAAI,YAAY,QAAQ,GAAG,EAAE,EAAE;AAAA,MACzE;AAAA,IACF;AAAA,EACF;AACF;;;ACtGA,SAAS,cAAAC,aAAY,oBAAoB;AACzC,SAAS,SAAS,YAAY;AAyBvB,SAAS,oBACd,KACc;AACd,SAAO;AAAA,IACL,OAAO,KAAK,SAAS;AAAA,IACrB,OAAO,KAAK,SAAS;AAAA,EACvB;AACF;AAiCA,SAAS,qBAAqB,SAAiB,SAAgC;AAC7E,QAAM,cAAc,KAAK,SAAS,cAAc;AAChD,MAAI,CAACA,YAAW,WAAW,EAAG,QAAO;AACrC,MAAI;AACF,UAAM,MAAM,KAAK,MAAM,aAAa,aAAa,OAAO,CAAC;AAGzD,UAAM,YAAY,KAAK,OAAO;AAC9B,UAAM,MAAM,IAAI,UAAU,SAAS;AACnC,QAAI,CAAC,KAAK;AAER,YAAM,WAAW,KAAK,SAAS,QAAQ,OAAO;AAC9C,aAAOA,YAAW,QAAQ,IAAI,WAAW;AAAA,IAC3C;AAEA,QAAI;AACJ,QAAI,OAAO,QAAQ,SAAU,UAAS;AAAA,aAC7B,OAAO,QAAQ,UAAU;AAChC,YAAM,IAAI;AACV,eAAS,EAAE,UAAU,EAAE;AAAA,IACzB;AACA,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,UAAU,OAAO,QAAQ,SAAS,EAAE;AAC1C,UAAM,YAAY,KAAK,SAAS,OAAO;AACvC,WAAOA,YAAW,SAAS,IAAI,YAAY;AAAA,EAC7C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAM,kBAAmC,CAAC,WAAW,gBAAgB;AACnE,QAAM,QAAQ,UAAU,MAAM,GAAG;AACjC,QAAM,UACJ,MAAM,CAAC,GAAG,WAAW,GAAG,KAAK,MAAM,UAAU,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC;AACtF,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,UAAU,UAAU,MAAM,QAAQ,SAAS,CAAC;AAClD,MAAI,CAAC,QAAS,QAAO;AAErB,MAAI,MAAM;AACV,WAAS,QAAQ,GAAG,QAAQ,IAAI,SAAS;AACvC,UAAM,UAAU,KAAK,KAAK,gBAAgB,GAAG,QAAQ,MAAM,GAAG,CAAC;AAC/D,QAAIA,YAAW,OAAO,GAAG;AACvB,YAAM,WAAW,qBAAqB,SAAS,OAAO;AACtD,UAAI,SAAU,QAAO;AAAA,IACvB;AACA,UAAM,SAAS,QAAQ,GAAG;AAC1B,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAMA,SAAS,wBAAwB,aAA8B;AAC7D,MAAI;AACF,UAAM,MAAM,aAAa,KAAK,aAAa,cAAc,GAAG,OAAO;AACnE,UAAM,MAAM,KAAK,MAAM,GAAG;AAQ1B,WAAO;AAAA,MACL,IAAI,eAAe,aAAa,KAChC,IAAI,kBAAkB,aAAa,KACnC,IAAI,mBAAmB,aAAa;AAAA,IACtC;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,aACd,aACA,WACA,WAA4B,iBACR;AACpB,QAAM,SAAS,oBAAoB,OAAO,cAAc,WAAW,YAAY,MAAS;AAGxF,MAAI,cAAc,OAAO;AACvB,WAAO,EAAE,SAAS,OAAO,OAAO;AAAA,EAClC;AAMA,MAAI,CAAC,wBAAwB,WAAW,GAAG;AACzC,WAAO,EAAE,SAAS,OAAO,OAAO;AAAA,EAClC;AAIA,QAAM,SAAS,CAAC,0BAA0B,uBAAuB;AACjE,aAAW,SAAS,QAAQ;AAC1B,QAAI,SAAS,OAAO,WAAW,GAAG;AAChC,aAAO,EAAE,SAAS,MAAM,OAAO;AAAA,IACjC;AAAA,EACF;AACA,SAAO,EAAE,SAAS,OAAO,OAAO;AAClC;;;ACvIA,IAAM,mBAAyC;AAAA,EAC7C,cAAc;AAAA,EACd,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,SAAS;AACX;AAEA,eAAsB,oBAAoB,aAAoD;AAC5F,MAAI;AACF,UAAM,aAAa,MAAM,WAAW,WAAW;AAC/C,UAAM,eAAe,MAAM,6BAA6B,WAAW,OAAO;AAC1E,UAAM,cAAc,mBAAmB,WAAW,aAAa;AAG/D,QAAI;AACJ,QAAI,WAAW,aAAa,MAAM;AAChC,yBAAmB,CAAC;AAAA,IACtB,WAAW,OAAO,WAAW,aAAa,UAAU;AAClD,yBAAmB,WAAW;AAAA,IAChC;AAEA,UAAM,SAAS,aAAa,aAAa,WAAW,EAAE;AAGtD,QAAI;AACJ,UAAM,cAAe,WAAgD,OAAO;AAC5E,QAAI,eAAe,OAAQ,YAAkC,QAAQ,YAAY;AAC/E,oBAAc;AAAA,IAChB;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,WAAW,UAAU,QAAQ;AAAA,MACvC,iBAAiB,WAAW,UAAU;AAAA,MACtC,YAAY,WAAW,UAAU;AAAA,MACjC,MAAM,WAAW,UAAU;AAAA,MAC3B;AAAA,MACA,iBAAiB,WAAW,aAAa;AAAA,MACzC,SAAS,WAAW;AAAA,MACpB,SAAS,WAAW;AAAA,IACtB;AAAA,EACF,QAAQ;AAGN,WAAO;AAAA,EACT;AACF;;;AC9GA,SAAS,WAAAC,UAAS,gBAAgB;;;ACiBlC,SAAS,UAAU,SAAmB,SAAyB;AAC7D,QAAM,SAAS,CAAC,GAAG,SAAS,OAAO,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAC7D,SAAO,MAAM;AACf;AAEA,SAAS,KACP,MACA,SACA,aACA,KACM;AACN,QAAM,OAAO,UAAU,SAAS,KAAK,OAAO;AAE5C,QAAM,YAAY,KAAK,SAAS,CAAC,GAAG,aAAa,KAAK,MAAM,IAAI;AAEhE,MAAI,KAAK,MAAM;AACb,QAAI,OAAO,KAAK;AAAA,MACd;AAAA,MACA,kBAAkB,KAAK;AAAA,MACvB,aAAa,CAAC,GAAG,WAAW;AAAA;AAAA,MAC5B,YAAY,QAAQ,KAAK,OAAO;AAAA,MAChC,UAAU,QAAQ,KAAK,KAAK;AAAA,MAC5B,aAAa,QAAQ,KAAK,QAAQ;AAAA,IACpC,CAAC;AAAA,EACH;AAEA,aAAW,SAAS,KAAK,UAAU;AACjC,UAAM,cAAc,KAAK,UAAU,CAAC,GAAG,SAAS,KAAK,OAAO,IAAI;AAChE,SAAK,OAAO,aAAa,WAAW,GAAG;AAAA,EACzC;AACF;AAMO,SAAS,mBAAmB,MAAgC;AACjE,QAAM,MAA0B,EAAE,QAAQ,CAAC,EAAE;AAC7C,OAAK,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG;AACtB,SAAO,EAAE,QAAQ,IAAI,OAAO;AAC9B;AAMO,SAAS,uBAAuB,MAAuB;AAC5D,QAAM,WAAW,mBAAmB,IAAI;AACxC,sBAAoB,0BAA0B,QAAQ;AACxD;;;AClEA,SAAS,kBAAkB;AAgB3B,IAAM,SAAS;AAgBR,SAAS,uBACd,MACA,WACA,SAC4B;AAC5B,QAAM,aAAa,iBAAiB,IAAI;AACxC,QAAM,eAAe,SAAS;AAC9B,QAAM,WAAqB,SAAS,YAAY;AAChD,QAAM,aAAa,SAAS;AAC5B,SAAO,CAAC,KAAK,KAAK,SAAS;AACzB,UAAM,YAAY;AAChB,YAAM,MAAM,IAAI,OAAO;AACvB,UAAI,CAAC,IAAI,WAAW,MAAM,GAAG;AAC3B,aAAK;AACL;AAAA,MACF;AAEA,YAAM,YAAY,WAAW;AAC7B,YAAM,QAAQ,KAAK,IAAI;AACvB,UAAI,UAAU,gBAAgB,SAAS;AAEvC,YAAM,kBAAkB,IAAI,MAAM,OAAO,MAAM,EAAE,MAAM,GAAG,EAAE,CAAC;AAC7D,YAAM,WAAW,gBAAgB,MAAM,GAAG,EAAE,OAAO,OAAO;AAE1D,UAAI,SAAS,SAAS,GAAG;AACvB;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,mBAAW;AAAA,UACT,QAAQ,IAAI,UAAU;AAAA,UACtB;AAAA,UACA,QAAQ;AAAA,UACR,UAAU,KAAK,IAAI,IAAI;AAAA,UACvB;AAAA,QACF,CAAC;AACD;AAAA,MACF;AAEA,YAAM,aAAa,SAAS,SAAS,SAAS,CAAC;AAC/C,YAAM,aAAa,SAAS,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG;AAEjD,YAAM,UAAU,kBAAkB,SAAS;AAC3C,YAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,eAAe,UAAU;AAE9D,UAAI,CAAC,QAAQ;AACX,cAAM,cAAc,QAAQ,IAAI,CAAC,MAAM,EAAE,UAAU;AACnD,cAAM,aAAa,eAAe,YAAY,WAAW;AACzD,cAAM,MAAM,aACR,gBAAgB,UAAU,8BAA8B,UAAU,MAClE,gBAAgB,UAAU;AAC9B,kBAAU,KAAK,aAAa,KAAK,KAAK,QAAW,SAAS;AAC1D,mBAAW;AAAA,UACT,QAAQ,IAAI,UAAU;AAAA,UACtB;AAAA,UACA,QAAQ;AAAA,UACR,UAAU,KAAK,IAAI,IAAI;AAAA,UACvB;AAAA,QACF,CAAC;AACD;AAAA,MACF;AAEA,YAAM;AAAA,QACJ,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA;AAAA,QACE;AAAA,UACE,QAAQ,IAAI,UAAU;AAAA,UACtB;AAAA,UACA,QAAQ,IAAI;AAAA,UACZ,UAAU,KAAK,IAAI,IAAI;AAAA,UACvB;AAAA,QACF;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,GAAG;AAAA,EACL;AACF;;;AC/GA,SAAS,cAAAC,mBAAkB;AAyB3B,IAAMC,UAAS;AAgBf,eAAe,aACb,KACA,KACA,SACA,UACA,KACe;AACf,QAAM,UAAU,IAAI,UAAU,QAAQ,YAAY;AAClD,MAAI,WAAW,QAAQ;AACrB;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI;AAAA,IACN;AACA,eAAW;AAAA,MACT;AAAA,MACA,KAAK,IAAI,OAAO;AAAA,MAChB,QAAQ;AAAA,MACR,UAAU,KAAK,IAAI,IAAI,IAAI;AAAA,MAC3B,WAAW,IAAI;AAAA,IACjB,CAAC;AACD;AAAA,EACF;AACA,MAAI;AACF,UAAM,WAAW,MAAM;AAAA,MACrB,4BAA4B,GAAG;AAAA,MAC/B;AAAA,MACA,oBAAoB;AAAA,MACpB;AAAA,IACF;AACA,UAAM,iCAAiC,UAAU,GAAG;AAAA,EACtD,SAAS,KAAK;AACZ;AAAA,MACE;AAAA,MACA;AAAA,MACA,eAAe,QAAQ,IAAI,UAAU;AAAA,MACrC;AAAA,MACA;AAAA,MACA,IAAI;AAAA,IACN;AAAA,EACF;AACA,aAAW;AAAA,IACT;AAAA,IACA,KAAK,IAAI,OAAO;AAAA,IAChB,QAAQ,IAAI;AAAA,IACZ,UAAU,KAAK,IAAI,IAAI,IAAI;AAAA,IAC3B,WAAW,IAAI;AAAA,EACjB,CAAC;AACH;AAQA,eAAe,SACb,KACA,KACA,MACA,SACA,MACe;AACf,QAAM,YAAYC,YAAW;AAC7B,QAAM,QAAQ,KAAK,IAAI;AACvB,MAAI;AACF,UAAM,UAAU,4BAA4B,GAAG;AAC/C,UAAM,WAAW,MAAM,mBAAmB,SAAS,SAAS;AAAA,MAC1D,QAAQ,WAAW,KAAK,aAAa,KAAK,SAAS;AAAA,MACnD,YAAY,KAAK;AAAA,MACjB,SAAS,UAAU,IAAI,QAAQ,QAAQ,WAAW;AAAA,MAClD,UAAU,KAAK;AAAA;AAAA,MAEf,eAAe,MAAM,gBAAgB,EAAE;AAAA,IACzC,CAAC;AACD,QAAI,aAAa,MAAM;AACrB,WAAK;AACL;AAAA,IACF;AACA,QAAI,UAAU,gBAAgB,SAAS;AACvC,UAAM,iCAAiC,UAAU,GAAG;AAAA,EACtD,SAAS,KAAK;AACZ,QAAI,UAAU,gBAAgB,SAAS;AACvC;AAAA,MACE;AAAA,MACA;AAAA,MACA,eAAe,QAAQ,IAAI,UAAU;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,aAAW;AAAA,IACT,SAAS,IAAI,UAAU,OAAO,YAAY;AAAA,IAC1C,KAAK,IAAI,OAAO;AAAA,IAChB,QAAQ,IAAI;AAAA,IACZ,UAAU,KAAK,IAAI,IAAI;AAAA,IACvB;AAAA,EACF,CAAC;AACH;AAEO,SAAS,sBACd,MACA,aACA,WAAqB,UACrB,YAAY,UACgB;AAC5B,QAAM,aAAa,iBAAiB,IAAI;AACxC,SAAO,CAAC,KAAK,KAAK,SAAS;AACzB,UAAM,YAAY;AAChB,YAAM,MAAM,IAAI,OAAO;AAKvB,UAAI,gBAAgB,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC,MAAM,MAAM;AAC/C,cAAM,SAAS,KAAK,KAAK,MAAM,IAAI,MAAM,GAAG,EAAE,CAAC,GAAG;AAAA,UAChD;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AACD;AAAA,MACF;AAEA,UAAI,CAAC,IAAI,WAAWD,OAAM,GAAG;AAC3B,aAAK;AACL;AAAA,MACF;AAEA,YAAM,YAAYC,YAAW;AAC7B,YAAM,QAAQ,KAAK,IAAI;AACvB,UAAI,UAAU,gBAAgB,SAAS;AAEvC,YAAM,UAAU,IAAI,MAAM,GAAG,EAAE,CAAC;AAKhC,UAAI,eAAe,OAAO,GAAG;AAC3B,cAAM,aAAa,KAAK,KAAK,SAAS,UAAU,EAAE,WAAW,MAAM,CAAC;AACpE;AAAA,MACF;AAIA,UAAI,oBAAoB,OAAO,MAAM,QAAQ,UAAU,OAAO,MAAM,MAAM;AACxE,cAAM,SAAS,KAAK,KAAK,MAAM,SAAS,EAAE,aAAa,YAAY,WAAW,SAAS,CAAC;AACxF;AAAA,MACF;AAEA,YAAM,QAAQ,WAAW,aAAa,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,cAAc,OAAO;AACpF,UAAI,CAAC,OAAO;AAEV,aAAK;AACL;AAAA,MACF;AAEA,YAAM,UAAU,IAAI,UAAU,QAAQ,YAAY;AAClD,UAAI,WAAW,QAAQ;AACrB;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,mBAAW,EAAE,QAAQ,KAAK,QAAQ,KAAK,UAAU,KAAK,IAAI,IAAI,OAAO,UAAU,CAAC;AAChF;AAAA,MACF;AAEA,UAAI;AACF,cAAM,MAAM,MAAM,WAAW,MAAM,QAAQ;AAC3C,cAAM,SAAS,gBAAgB,EAAE;AACjC,cAAM,UAAU,4BAA4B,GAAG;AAC/C,cAAM,WAAW,MAAM,WAAW,KAAK,SAAS,QAAQ;AAAA,UACtD,QAAQ,MAAM;AAAA,UACd;AAAA,UACA;AAAA,QACF,CAAC;AACD,cAAM,iCAAiC,UAAU,GAAG;AAAA,MACtD,SAAS,KAAK;AACZ;AAAA,UACE;AAAA,UACA;AAAA,UACA,eAAe,QAAQ,IAAI,UAAU;AAAA,UACrC;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,iBAAW,EAAE,QAAQ,KAAK,QAAQ,IAAI,YAAY,UAAU,KAAK,IAAI,IAAI,OAAO,UAAU,CAAC;AAAA,IAC7F,GAAG;AAAA,EACL;AACF;;;AC1PA,SAAS,WAAAC,gBAAe;AAiFxB,SAAS,0BAA0B,KAAa,UAAsC;AACpF,MAAI,CAAC,IAAI,WAAW,OAAO,EAAG,QAAO;AACrC,MAAI,SAAS,WAAW,EAAG,QAAO;AAClC,QAAM,OAAO,IAAI,MAAM,GAAG,EAAE,CAAC;AAC7B,aAAW,UAAU,UAAU;AAC7B,QAAI,SAAS,UAAU,KAAK,WAAW,GAAG,MAAM,GAAG,EAAG,QAAO;AAAA,EAC/D;AACA,SAAO;AACT;AAEA,eAAe,uBACb,KACA,KACA,KACA,KAIkB;AAClB,QAAM,WAAW,IAAI,MAAM,GAAG,EAAE,CAAC;AACjC,MAAI,aAAa,mBAAmB,IAAI,WAAW,OAAQ,QAAO;AAClE,QAAM,gBAAgB,KAAK,KAAK,EAAE,aAAa,IAAI,aAAa,aAAa,IAAI,eAAe,CAAC;AACjG,SAAO;AACT;AAgBA,SAAS,oBACP,KACA,KACA,KACS;AACT,MAAI,CAAC,IAAI,YAAa,QAAO;AAC7B,QAAM,QAAQ,IAAI,YAAY,GAAG;AACjC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,OAAO,EAAG,KAAI,UAAU,GAAG,CAAC;AACtE,MAAI,CAAC,MAAM,QAAS,QAAO;AAC3B,YAAU,KAAK,gBAAgB,qBAAqB,KAAK,QAAW,IAAI,SAAS;AACjF,aAAW;AAAA,IACT,QAAQ,IAAI,UAAU;AAAA,IACtB,KAAK,IAAI;AAAA,IACT,QAAQ;AAAA,IACR,UAAU,KAAK,IAAI,IAAI,IAAI;AAAA,IAC3B,WAAW,IAAI;AAAA,EACjB,CAAC;AACD,SAAO;AACT;AASA,eAAe,mBACb,KACA,KACA,KACkB;AAClB,MAAI,CAAC,IAAI,SAAU,QAAO;AAC1B,QAAM,cAAc,IAAI,IAAI,MAAM,GAAG,EAAE,CAAC;AACxC,MAAI,gBAAgB,cAAc,IAAI,WAAW,OAAQ,QAAO;AAChE,QAAM,kBAAkB,KAAK,KAAK,IAAI,UAAU,IAAI,SAAS;AAC7D,aAAW;AAAA,IACT,QAAQ,IAAI,UAAU;AAAA,IACtB,KAAK,IAAI;AAAA,IACT,QAAQ,IAAI;AAAA,IACZ,UAAU,KAAK,IAAI,IAAI,IAAI;AAAA,IAC3B,WAAW,IAAI;AAAA,EACjB,CAAC;AACD,SAAO;AACT;AAEA,eAAe,kBACb,KACA,KACA,UACA,WACe;AACf,MAAI;AACF,UAAM,SAAmB,CAAC;AAC1B,UAAM,IAAI,QAAc,CAACC,UAAS,WAAW;AAC3C,UAAI,GAAG,QAAQ,CAAC,MAAM,OAAO,KAAK,CAAW,CAAC;AAC9C,UAAI,GAAG,OAAO,MAAM;AAClB,QAAAA,SAAQ;AAAA,MACV,CAAC;AACD,UAAI,GAAG,SAAS,MAAM;AAAA,IACxB,CAAC;AAGD,UAAM,UAAmB,KAAK,MAAM,OAAO,OAAO,MAAM,EAAE,SAAS,CAAC;AACpE,UAAM,eAAuC,CAAC;AAC9C,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,IAAI,OAAO,GAAG;AAChD,UAAI,OAAO,MAAM,SAAU,cAAa,EAAE,YAAY,CAAC,IAAI;AAAA,IAC7D;AACA,UAAM,SAAS,MAAM,mBAAmB,SAAS;AAAA,MAC/C,KAAK,SAAS;AAAA,MACd;AAAA;AAAA;AAAA;AAAA,MAIA,SAAS,MAAM,QAAQ,QAAQ,EAAE,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;AAAA,IACvD,CAAC;AACD,QAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,QAAI,IAAI,KAAK,UAAU,MAAM,CAAC;AAAA,EAChC,SAAS,KAAK;AACZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,cAAU,KAAK,eAAe,SAAS,KAAK,QAAW,SAAS;AAAA,EAClE;AACF;AAeA,eAAe,2BACb,cACA,QACkB;AAClB,QAAM,EAAE,KAAK,KAAK,WAAW,OAAO,IAAI,IAAI;AAC5C,MAAI;AACF,UAAM,aAAa,MAAM,aAAa,aAAa;AAAA;AAAA,MAEjD,SAAS,gCAAgC,GAAG;AAAA,MAC5C,UAAU;AAAA,MACV,KAAK,CAAC;AAAA,MACN;AAAA,IACF,CAAC;AACD,QAAI,WAAW,gBAAgB;AAC7B;AAAA,QACE;AAAA,UACE,QAAQ,IAAI,UAAU;AAAA,UACtB;AAAA,UACA,QAAQ,IAAI;AAAA,UACZ,UAAU,KAAK,IAAI,IAAI;AAAA,UACvB;AAAA,QACF;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF,SAAS,KAAK;AACZ,cAAU,KAAK,gBAAiB,IAAc,SAAS,KAAK,QAAW,SAAS;AAChF,WAAO;AAAA,EACT;AACA,SAAO;AACT;AASA,eAAe,yBAAyB,KAUnB;AACnB,QAAM,UAAU,MAAM,0BAA0B;AAAA,IAC9C,gBAAgBA,SAAQ,IAAI,WAAW,aAAa;AAAA,IACpD,YAAY,IAAI;AAAA,IAChB,KAAK,IAAI;AAAA,IACT,KAAK,IAAI;AAAA,IACT,UAAU,IAAI;AAAA,IACd,YAAY,IAAI;AAAA,IAChB,WAAW,IAAI;AAAA;AAAA;AAAA,IAGf,YAAY,CAAC,OAAgB,YAC3B,WAAW,OAAO,SAAS,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,UAAU,UAAU,MAAM,CAAC;AAAA,EAC9F,CAAC;AACD,MAAI,CAAC,QAAS,QAAO;AACrB;AAAA,IACE;AAAA,MACE,SAAS,IAAI,IAAI,UAAU,OAAO,YAAY;AAAA,MAC9C,KAAK,IAAI;AAAA,MACT,QAAQ,IAAI,IAAI;AAAA,MAChB,UAAU,KAAK,IAAI,IAAI,IAAI;AAAA,MAC3B,WAAW,IAAI;AAAA,IACjB;AAAA,IACA;AAAA,IACA,IAAI;AAAA,EACN;AACA,SAAO;AACT;AAEO,SAAS,oBACd,MACA,WACA,0BAC4B;AAG5B,QAAM,OACJ,4BAA4B,cAAc,2BACtC,EAAE,iBAAiB,yBAAyB,IAC3C,4BAA4B,CAAC;AAEpC,QAAM,aAAa,iBAAiB,IAAI;AACxC,QAAM,cAAc,KAAK,kBAAkB,kBAAkB,KAAK,eAAe,IAAI;AACrF,QAAM,eAAe,KAAK;AAC1B,QAAM,cAAc,KAAK;AACzB,QAAM,WAAW,KAAK;AAEtB,QAAM,WAAW,KAAK,YAAY;AAClC,QAAM,aAAa,KAAK;AACxB,QAAM,wBAAwB,KAAK,mBAAmB,CAAC;AACvD,QAAM,cAAc,EAAE,YAAY,QAAQ,IAAI,aAAa,aAAa;AAExE,QAAM,cAAc,KAAK,OAAO,kBAAkB,KAAK,IAAI,IAAI;AAC/D,QAAM,cAAc,KAAK;AACzB,QAAM,iBAAiB,KAAK;AAC5B,QAAM,qBAAqB,KAAK;AAChC,QAAM,wBAAwB,KAAK,yBAAyB,CAAC;AAE7D,SAAO,CAAC,KAAK,KAAK,SAAS;AAMzB,UAAM,SAAS,YAA2B;AACxC,YAAM,MAAM,IAAI,OAAO;AAKvB,UAAI,MAAM,uBAAuB,KAAK,KAAK,KAAK,EAAE,aAAa,eAAe,CAAC,GAAG;AAChF;AAAA,MACF;AAIA,UAAI,sBAAuB,MAAM,oBAAoB,KAAK,KAAK,kBAAkB,GAAI;AACnF;AAAA,MACF;AAEA,UAAI,0BAA0B,KAAK,qBAAqB,GAAG;AACzD,aAAK;AACL;AAAA,MACF;AAIA,UAAI,aAAa,gBAAgB,KAAK,GAAG,GAAG;AAC1C;AAAA,MACF;AAMA,YAAM,YAAY,eAAe,GAAG;AACpC,YAAM,QAAQ,KAAK,IAAI;AACvB,UAAI,UAAU,gBAAgB,SAAS;AACvC,UAAI,UAAU,cAAc,SAAS;AAGrC,2BAAqB,KAAK,uBAAuB,WAAW;AAE5D,mBAAa,aAAa,KAAK,GAAG;AAElC,UAAI,oBAAoB,KAAK,KAAK,EAAE,aAAa,WAAW,KAAK,MAAM,CAAC,GAAG;AACzE;AAAA,MACF;AAIA,UACE,gBACC,MAAM,2BAA2B,cAAc,EAAE,KAAK,KAAK,WAAW,OAAO,IAAI,CAAC,GACnF;AACA;AAAA,MACF;AAGA,UAAI,MAAM,mBAAmB,KAAK,KAAK,EAAE,KAAK,UAAU,WAAW,MAAM,CAAC,GAAG;AAC3E;AAAA,MACF;AAEA,YAAM,SAAS,iBAAiB,SAAS;AACzC,YAAM,QAAQ,WAAW,KAAK,MAAM;AAEpC,UAAI,CAAC,OAAO;AAEV,YACE,MAAM,yBAAyB;AAAA,UAC7B;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC,GACD;AACA;AAAA,QACF;AAEA,cAAM,UAAU,IAAI,MAAM,GAAG,EAAE,CAAC;AAChC,cAAM,aAAa,OAAO,IAAI,CAAC,MAAM,EAAE,SAAS;AAChD,cAAM,aAAa,eAAe,SAAS,UAAU;AACrD,cAAM,MAAM,aACR,wBAAwB,OAAO,mBAAmB,UAAU,MAC5D;AACJ,kBAAU,KAAK,aAAa,KAAK,KAAK,QAAW,SAAS;AAC1D;AAAA,UACE;AAAA,YACE,QAAQ,IAAI,UAAU;AAAA,YACtB;AAAA,YACA,QAAQ;AAAA,YACR,UAAU,KAAK,IAAI,IAAI;AAAA,YACvB;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA;AAAA,MACF;AAEA,YAAM,UAAU,IAAI,UAAU,OAAO,YAAY;AAEjD,YAAM,aAAa;AAAA,QACjB,OAAO,MAAM;AAAA,QACb;AAAA,QACA,QAAQ,MAAM;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AACD;AAAA,QACE,EAAE,QAAQ,KAAK,QAAQ,IAAI,YAAY,UAAU,KAAK,IAAI,IAAI,OAAO,UAAU;AAAA,QAC/E;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,SAAK,OAAO;AAAA,EACd;AACF;;;AC1bA,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,WAAAC,gBAAe;AA0BxB,SAAS,kBAAkB,OAA0C;AACnE,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,MAAI,EAAE,UAAU,OAAQ,QAAO;AAC/B,SAAO,OAAQ,MAAkC,SAAS;AAC5D;AAYO,SAAS,sBAAsB,QAAuB,MAAqC;AAChG,SAAO,YAAY,IAAI,CAAC,KAAK,KAAK,SAAS;AACzC,UAAM,YAAY;AAChB,YAAM,MAAM,IAAI,OAAO;AAEvB,UACE,IAAI,WAAW,OAAO,KACtB,IAAI,WAAW,IAAI,KACnB,IAAI,WAAW,gBAAgB,KAC/B,IAAI,SAAS,GAAG,GAChB;AACA,aAAK;AACL;AAAA,MACF;AAEA,UAAI;AACF,cAAM,YAAYC,SAAQ,KAAK,aAAa,YAAY;AAExD,YAAI,WAAWC,cAAa,WAAW,OAAO;AAC9C,mBAAW,MAAM,OAAO,mBAAmB,KAAK,QAAQ;AAMxD,cAAM,QAAQ,cAAc;AAC5B;AAAA,UACE;AAAA,UACA,KAAK,mBAAmB,CAAC;AAAA,UACzB,EAAE,YAAY,QAAQ,IAAI,aAAa,aAAa;AAAA,UACpD,EAAE,MAAM;AAAA,QACV;AAEA,cAAM,MAAO,MAAM,OAAO,cAAc,KAAK,oBAAoB;AACjE,cAAM,SAAS,MAAM,IAAI,OAAO,KAAK,EAAE,MAAM,CAAC;AAE9C,YAAI,UAAU,OAAO,WAAW,YAAY,cAAc,QAAQ;AAChE,cAAI,UAAU,KAAK;AAAA,YACjB,UAAU,OAAO,SAAS,QAAQ,IAAI,UAAU,KAAK;AAAA,UACvD,CAAC;AACD,cAAI,IAAI;AACR;AAAA,QACF;AAKA,YAAI;AACJ,YAAI,kBAAkB;AACtB,YAAI,OAAO,WAAW,UAAU;AAC9B,oBAAU;AAAA,QACZ,WAAW,kBAAkB,MAAM,GAAG;AACpC,oBAAU,OAAO;AACjB,gBAAM,WAAW,KAAK,UAAU,OAAO,aAAa,EAAE,QAAQ,MAAM,SAAS;AAC7E,4BAAkB,kBAAkB,KAAK,wCAAwC,QAAQ;AAAA,QAC3F,OAAO;AACL,oBAAU;AAAA,QACZ;AACA,cAAM,eAAe,6BAA6B,KAAK,QAAQ;AAC/D,YAAI,CAAC,cAAc;AACjB,cAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,cAAI,IAAI,QAAQ;AAChB;AAAA,QACF;AAEA,cAAM,WAAW,SAAS,QAAQ,aAAa,CAAC,CAAC,IAAI,aAAa,CAAC,EAAE;AACrE,cAAM,OACJ,SAAS,MAAM,GAAG,QAAQ,IAAI,UAAU,kBAAkB,SAAS,MAAM,QAAQ;AAEnF,YAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,YAAI,IAAI,IAAI;AAAA,MACd,SAAS,KAAK;AACZ,eAAO,iBAAiB,GAAY;AACpC,gBAAQ,MAAM,mBAAmB,GAAG;AAEpC,aAAK;AACL;AAAA,MACF;AAAA,IACF,GAAG;AAAA,EACL,CAAC;AACH;;;ACzHA,SAAS,WAAAC,gBAAe;AAcjB,SAAS,eAAe,QAAuB,aAA2B;AAC/E,QAAM,WAAW,oBAAoBC,SAAQ,aAAa,QAAQ,CAAC;AACnE,MAAI,SAAS,WAAW,EAAG;AAI3B,QAAM,eAAe,OAAO;AAC5B,MAAI,CAAC,aAAc;AAGnB,OAAK,OAAO,IAAI,EACb,KAAK,CAAC,EAAE,gBAAgB,MAAM;AAC7B,UAAM,MAAM,IAAI,gBAAgB,EAAE,UAAU,KAAK,CAAC;AAElD,iBAAa,GAAG,WAAW,CAAC,SAA0B,QAAgB,SAAiB;AACrF,YAAM,YAAY;AAChB,cAAM,MAAM,QAAQ,OAAO;AAC3B,YAAI,CAAC,IAAI,WAAW,MAAM,EAAG;AAE7B,cAAM,SAAS,IAAI,MAAM,GAAG,EAAE,CAAC;AAC/B,cAAM,QAAQ,SAAS,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM;AACtD,YAAI,CAAC,OAAO;AACV,iBAAO,QAAQ;AACf;AAAA,QACF;AAEA,YAAI;AACF,gBAAM,MAAM,MAAM,OAAO,cAAc,MAAM,QAAQ;AACrD,gBAAM,UAAY,IAA8B,WAAW;AAE3D,cAAI,cAAc,SAAS,QAAQ,MAAM,CAAC,OAAO;AAC/C,iBAAK,QAAQ,SAAS,IAAI,OAAO;AACjC,eAAG,GAAG,WAAW,CAAC,SAAiB;AACjC,mBAAK,QAAQ,YAAY,IAAI,KAAK,SAAS,CAAC;AAAA,YAC9C,CAAC;AACD,eAAG,GAAG,SAAS,CAAC,MAAc,WAAmB;AAC/C,mBAAK,QAAQ,UAAU,IAAI,MAAM,MAAM;AAAA,YACzC,CAAC;AACD,eAAG,GAAG,SAAS,CAAC,QAAe;AAC7B,mBAAK,QAAQ,UAAU,IAAI,GAAG;AAAA,YAChC,CAAC;AAAA,UACH,CAAC;AAAA,QACH,QAAQ;AACN,iBAAO,QAAQ;AAAA,QACjB;AAAA,MACF,GAAG;AAAA,IACL,CAAC;AAAA,EACH,CAAC,EACA,MAAM,MAAM;AACX,YAAQ;AAAA,MACN;AAAA,IACF;AAAA,EACF,CAAC;AACL;;;ANrBA,eAAsB,mBACpB,QACA,KACe;AAIf,MAAI,UAAU,QAAQ;AAGrB,EAAC,WAAuD,sBAAsB;AAG/E,SAAO,GAAG,GAAG,kCAAkC,MAAM;AACnD,QAAI;AACF,YAAM,OAAO,WAAW,IAAI,MAAM;AAClC,6BAAuB,IAAI;AAAA,IAC7B,QAAQ;AAAA,IAER;AAAA,EACF,CAAC;AAID,QAAM,YAAY,IAAI;AACtB,SAAO,YAAY;AAAA,IACjB,uBAAuB,QAAQ,WAAW;AAAA,MACxC,cAAc,IAAI;AAAA,MAClB,UAAU,IAAI;AAAA,MACd,YAAY,IAAI;AAAA,IAClB,CAAC;AAAA,EACH;AAIA,SAAO,YAAY;AAAA,IACjB,sBAAsB,QAAQ,IAAI,aAAa,IAAI,UAAU,IAAI,SAAS;AAAA,EAC5E;AAIA,QAAM,wBACJ,IAAI,YAAY,OAAO,KAAK,IAAI,QAAQ,EAAE,SAAS,IAC/C,OAAO,OAAO,IAAI,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,IAC9C,CAAC;AAGP,QAAM,qBAAqB,IAAI,8BAA8B,IAAI,mBAAmB;AACpF,SAAO,YAAY;AAAA,IACjB,oBAAoB,QAAQ,WAAW;AAAA,MACrC,iBAAiB,IAAI;AAAA,MACrB,cAAc,IAAI;AAAA,MAClB,UAAU,IAAI;AAAA,MACd,aAAa,IAAI;AAAA,MACjB,UAAU,IAAI;AAAA,MACd,iBAAiB,IAAI;AAAA,MACrB,YAAY,IAAI;AAAA,MAChB,MAAM,IAAI;AAAA,MACV,aAAa,IAAI;AAAA,MACjB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAGA,QAAM,aAAaC,SAAQ,IAAI,aAAa,gBAAgB;AAC5D,SAAO,QAAQ,GAAG,UAAU,CAAC,SAAS;AACpC,QAAI,SAAS,YAAY;AACvB,cAAQ;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAGD,MAAI,IAAI,YAAY;AAClB,0BAAsB,QAAQ;AAAA,MAC5B,aAAa,IAAI;AAAA,MACjB,sBAAsB,IAAI;AAAA,MAC1B,iBAAiB,IAAI;AAAA,IACvB,CAAC;AAAA,EACH;AAGA,WAAS,kBAAkB,UAAwB;AACjD,QAAI,CAAC,YAAY,SAAS,QAAQ,CAAC,EAAG;AACtC,QAAI,CAAC,SAAS,WAAW,IAAI,MAAM,EAAG;AAEtC,UAAM,MAAM,OAAO,YAAY,cAAc,IAAI,kBAAkB;AACnE,QAAI,KAAK;AACP,aAAO,YAAY,iBAAiB,GAAG;AACvC,aAAO,GAAG,KAAK,EAAE,MAAM,cAAc,CAAC;AAAA,IACxC;AAAA,EACF;AAEA,SAAO,QAAQ,GAAG,OAAO,iBAAiB;AAC1C,SAAO,QAAQ,GAAG,UAAU,iBAAiB;AAG7C,MAAI,IAAI,oBAAoB,QAAW;AACrC,UAAM,aAAa,IAAI;AACvB,UAAM,EAAE,cAAc,IAAI,MAAM,OAAO,wBAA4B;AAEnE,UAAM,mBAAmB,IAAI;AAC7B,UAAM,iBAAiBA,SAAQ,IAAI,aAAa,IAAI,eAAe;AACnE,UAAM,wBAAwB,CAAC,SAC7B,KAAK,WAAW,gBAAgB,KAAK,qBAAqB,KAAK,IAAI;AAErE,SAAK,cAAc,kBAAkB,gBAAgB,UAAU;AAE/D,WAAO,QAAQ,GAAG,UAAU,CAAC,SAAiB;AAC5C,UAAI,sBAAsB,IAAI,GAAG;AAC/B,aAAK,cAAc,kBAAkB,gBAAgB,UAAU;AAAA,MACjE;AAAA,IACF,CAAC;AACD,WAAO,QAAQ,GAAG,OAAO,CAAC,SAAiB;AACzC,UAAI,sBAAsB,IAAI,GAAG;AAC/B,aAAK,cAAc,kBAAkB,gBAAgB,UAAU;AAAA,MACjE;AAAA,IACF,CAAC;AACD,WAAO,QAAQ,GAAG,UAAU,CAAC,SAAiB;AAC5C,UAAI,sBAAsB,IAAI,GAAG;AAC/B,aAAK,cAAc,kBAAkB,gBAAgB,UAAU;AAAA,MACjE;AAAA,IACF,CAAC;AAAA,EACH;AAGA,iBAAe,QAAQ,IAAI,WAAW;AAGtC,SAAO,YAAY,KAAK,SAAS,MAAM;AACrC;AAAC,IAAC,WAAiD,sBAAsB;AAAA,EAC3E,CAAC;AACH;;;AOlLA,SAAS,cAAAC,aAAY,gBAAAC,qBAAoB;AACzC,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAC9B,SAAS,qBAAqB;;;ACC9B,SAAS,cAAAC,aAAY,gBAAAC,qBAAoB;AACzC,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAW9B,SAAS,WAAW,MAAc,aAA8B;AAC9D,MAAI;AACF,UAAM,MAAMF,cAAaE,MAAK,aAAa,cAAc,GAAG,OAAO;AACnE,UAAM,MAAM,KAAK,MAAM,GAAG;AAK1B,WAAO;AAAA,MACL,IAAI,eAAe,IAAI,KAAK,IAAI,kBAAkB,IAAI,KAAK,IAAI,mBAAmB,IAAI;AAAA,IACxF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMA,SAAS,mBAAmB,MAAc,KAAwD;AAChG,MAAI,MAAM;AACV,WAAS,QAAQ,GAAG,QAAQ,IAAI,SAAS;AACvC,UAAM,cAAcA,MAAK,KAAK,gBAAgB,GAAG,KAAK,MAAM,GAAG,GAAG,cAAc;AAChF,QAAIH,YAAW,WAAW,GAAG;AAC3B,UAAI;AACF,cAAM,MAAMC,cAAa,aAAa,OAAO;AAC7C,cAAM,MAAM,KAAK,MAAM,GAAG;AAE1B,YAAI,IAAI,SAAS,MAAM;AACrB,iBAAO,EAAE,MAAM,aAAa,SAAS,IAAI,QAAQ;AAAA,QACnD;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AACA,UAAM,SAASC,SAAQ,GAAG;AAC1B,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAMA,SAAS,cAAc,MAAc,KAA+C;AAClF,QAAM,aAAa,CAAC,aAAa,kBAAkB,iBAAiB,UAAU;AAC9E,MAAI,MAAM;AACV,WAAS,QAAQ,GAAG,QAAQ,IAAI,SAAS;AACvC,UAAM,SAASC,MAAK,KAAK,gBAAgB,GAAG,KAAK,MAAM,GAAG,CAAC;AAC3D,eAAW,aAAa,YAAY;AAClC,YAAM,QAAQA,MAAK,QAAQ,SAAS;AACpC,UAAIH,YAAW,KAAK,EAAG,QAAO,EAAE,eAAe,MAAM;AAAA,IACvD;AACA,UAAM,SAASE,SAAQ,GAAG;AAC1B,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAIA,SAAS,sBACP,OACA,cAC2C;AAC3C,MAAI,MAAMA,SAAQ,KAAK;AAEvB,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,UAAM,YAAYC,MAAK,KAAK,cAAc;AAC1C,QAAIH,YAAW,SAAS,GAAG;AACzB,UAAI;AACF,cAAM,MAAMC,cAAa,WAAW,OAAO;AAC3C,cAAM,MAAM,KAAK,MAAM,GAAG;AAC1B,YAAI,IAAI,SAAS,cAAc;AAC7B,iBAAO,EAAE,MAAM,WAAW,SAAS,IAAI,QAAQ;AAAA,QACjD;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AACA,UAAM,SAASC,SAAQ,GAAG;AAC1B,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAEO,SAAS,cAAc,MAAc,KAA2B;AACrE,MAAI,CAAC,WAAW,MAAM,GAAG,GAAG;AAC1B,WAAO,EAAE,WAAW,MAAM;AAAA,EAC5B;AAEA,QAAM,UAAU,mBAAmB,MAAM,GAAG;AAC5C,MAAI,SAAS;AACX,WAAO;AAAA,MACL,WAAW;AAAA,MACX,SAAS,QAAQ;AAAA,MACjB,cAAc,QAAQ;AAAA,IACxB;AAAA,EACF;AAKA,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,UAAM,SAASC,MAAK,KAAK,gBAAgB,GAAG,KAAK,MAAM,GAAG,CAAC;AAC3D,UAAM,YAAYA,MAAK,QAAQ,cAAc;AAC7C,QAAIH,YAAW,SAAS,GAAG;AACzB,UAAI;AACF,cAAM,MAAMC,cAAa,WAAW,OAAO;AAC3C,cAAM,MAAM,KAAK,MAAM,GAAG;AAC1B,YAAI,IAAI,SAAS,MAAM;AACrB,iBAAO,EAAE,WAAW,MAAM,SAAS,IAAI,SAAS,cAAc,UAAU;AAAA,QAC1E;AAAA,MACF,QAAQ;AAAA,MAER;AACA,aAAO,EAAE,WAAW,KAAK;AAAA,IAC3B;AACA,UAAM,SAASC,SAAQ,GAAG;AAC1B,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AAIA,QAAM,QAAQ,cAAc,MAAM,GAAG;AACrC,MAAI,OAAO;AACT,UAAM,SAAS,sBAAsB,MAAM,eAAe,IAAI;AAC9D,QAAI,QAAQ;AACV,aAAO,EAAE,WAAW,MAAM,SAAS,OAAO,SAAS,cAAc,OAAO,KAAK;AAAA,IAC/E;AACA,WAAO,EAAE,WAAW,KAAK;AAAA,EAC3B;AAEA,SAAO,EAAE,WAAW,MAAM;AAC5B;;;ADpIA,SAAS,sBAAsB,MAAc,KAA4B;AACvE,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,UAAM,SAASE,MAAK,KAAK,gBAAgB,GAAG,KAAK,MAAM,GAAG,CAAC;AAC3D,UAAM,cAAcA,MAAK,QAAQ,cAAc;AAC/C,QAAIC,YAAW,WAAW,GAAG;AAC3B,UAAI;AACF,cAAM,MAAMC,cAAa,aAAa,OAAO;AAC7C,cAAM,MAAM,KAAK,MAAM,GAAG;AAK1B,YAAI;AACJ,cAAM,YAAY,IAAI,UAAU,GAAG;AACnC,YAAI,OAAO,cAAc,SAAU,SAAQ;AAAA,iBAClC,aAAa,OAAO,cAAc,UAAU;AACnD,kBAAQ,UAAU,UAAU,UAAU;AAAA,QACxC;AACA,kBAAU,IAAI,UAAU,IAAI;AAC5B,YAAI,CAAC,MAAO,QAAO;AAEnB,cAAM,UAAU,MAAM,QAAQ,SAAS,EAAE;AACzC,eAAO,cAAcF,MAAK,QAAQ,OAAO,CAAC,EAAE;AAAA,MAC9C,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AACA,UAAM,SAASG,SAAQ,GAAG;AAC1B,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAEA,SAAS,cAAc,OAAiC;AACtD,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AAEjC,MAAI,EAAE,UAAU,OAAQ,QAAO;AAC/B,SAAO,OAAQ,MAAkC,SAAS;AAC5D;AAYA,SAAS,sBAAsB,OAAiC;AAC9D,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,UAAM,SAAmB,CAAC;AAC1B,eAAW,SAAS,OAAO;AACzB,UAAI,CAAC,cAAc,KAAK,EAAG,QAAO;AAClC,aAAO,KAAK,KAAK;AAAA,IACnB;AACA,WAAO,OAAO,SAAS,IAAI,SAAS;AAAA,EACtC;AACA,MAAI,cAAc,KAAK,EAAG,QAAO,CAAC,KAAK;AACvC,SAAO;AACT;AAQA,eAAsB,mBACpB,KACA,MACmB;AACnB,MAAI,MAAM,YAAY,MAAO,QAAO,CAAC;AAErC,QAAM,WAAW,cAAc,eAAe,GAAG;AACjD,MAAI,CAAC,SAAS,UAAW,QAAO,CAAC;AAGjC,MAAI,MAAM,0BAA0B,MAAM,uBAAuB;AAE/D,YAAQ;AAAA,MACN;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,iBAAiB,cAAc,qBAAqB,GAAG;AAC7D,MAAI,CAAC,eAAe,WAAW;AAC7B,YAAQ;AAAA,MACN;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AAUA,QAAM,cAAc,sBAAsB,qBAAqB,GAAG;AAClE,MAAI,CAAC,aAAa;AAChB,YAAQ;AAAA,MACN,uFAAuF,GAAG;AAAA,IAC5F;AACA,WAAO,CAAC;AAAA,EACV;AACA,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,kBAAe,MAAM,OAAO;AAAA,EAC9B,SAAS,KAAK;AACZ,YAAQ;AAAA,MACN,sDAAuD,IAAc,OAAO;AAAA,IAC9E;AACA,WAAO,CAAC;AAAA,EACV;AAGA,QAAM,iBAAiB,cAAc,eAAe,GAAG;AACvD,QAAM,WAAW,eAAe,eAC5B,eAAe,aAAa,QAAQ,uBAAuB,EAAE,IAC7D;AACJ,QAAM,eAAe,WAAWC,MAAK,UAAU,QAAQ,gBAAgB,IAAI;AAC3E,MAAI,CAAC,gBAAgB,CAACC,YAAW,YAAY,GAAG;AAC9C,YAAQ;AAAA,MACN,wDAAwD,OAAO,YAAY,CAAC;AAAA,IAC9E;AACA,WAAO,CAAC;AAAA,EACV;AACA,MAAI;AACF,YAAS,MAAM,OAAO,cAAc,YAAY,EAAE;AAAA,EACpD,SAAS,KAAK;AACZ,YAAQ;AAAA,MACN,4DAA6D,IAAc,OAAO;AAAA,IACpF;AACA,WAAO,CAAC;AAAA,EACV;AAEA,MAAI,OAAO,YAAY,YAAY,YAAY;AAC7C,YAAQ;AAAA,MACN;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AACA,MAAI,OAAO,MAAM,YAAY,YAAY;AACvC,YAAQ;AAAA,MACN;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AAEA,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,qBAAkB,YAAY,QAA0B;AAAA,EAC1D,SAAS,KAAK;AACZ,YAAQ,KAAK,wCAAyC,IAAc,OAAO,EAAE;AAC7E,WAAO,CAAC;AAAA,EACV;AACA,MAAI;AAGF,eAAY,MAAM,QAAuD;AAAA,MACvE,UAAU;AAAA,IACZ,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAQ,KAAK,8CAA+C,IAAc,OAAO,EAAE;AACnF,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,kBAAkB,sBAAsB,cAAc;AAC5D,MAAI,oBAAoB,MAAM;AAC5B,YAAQ,KAAK,8EAA8E;AAC3F,WAAO,CAAC;AAAA,EACV;AACA,QAAM,YAAY,sBAAsB,QAAQ;AAChD,MAAI,cAAc,MAAM;AACtB,YAAQ;AAAA,MACN;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,CAAC,GAAG,iBAAiB,GAAG,SAAS;AAC1C;;;AEvOA,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,WAAAC,gBAAe;AAiBjB,SAAS,mBAAmB,YAA4B;AAC7D,MAAID,YAAWC,SAAQ,YAAY,QAAQ,CAAC,GAAG;AAC7C,WAAO;AAAA,EACT;AACA,SAAOA,SAAQ,YAAY,IAAI;AACjC;;;ACtBA,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,WAAAC,gBAAe;;;ACUjB,IAAM,sBAAsB;AAC5B,IAAM,uBAAuB;AAEpC,IAAM,aAAa,8BAA8B,mBAAmB;AAQ7D,SAAS,qBACd,MACA,MACsB;AAEtB,MAAI,CAAC,KAAK,MAAO,QAAO,EAAE,MAAM,UAAU,MAAM;AAEhD,MAAI,KAAK,YAAY,MAAO,QAAO,EAAE,MAAM,UAAU,MAAM;AAG3D,MAAI,KAAK,SAAS,mBAAmB,GAAG;AACtC,WAAO,EAAE,MAAM,UAAU,MAAM;AAAA,EACjC;AAGA,QAAM,mBAAmB;AACzB,MAAI,iBAAiB,KAAK,IAAI,GAAG;AAC/B,WAAO;AAAA,MACL,MAAM,KAAK,QAAQ,kBAAkB,CAAC,UAAU,OAAO,UAAU;AAAA,IAAO,KAAK,EAAE;AAAA,MAC/E,UAAU;AAAA,IACZ;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA,UAAU;AAAA,IACV,SACE;AAAA,EACJ;AACF;;;ACzCA,IAAM,mBAAmB;AACzB,IAAMC,cAAa,8BAA8B,gBAAgB;AAQ1D,SAAS,kBAAkB,MAA4B;AAK5D,MAAI,KAAK,SAAS,gBAAgB,GAAG;AACnC,WAAO,EAAE,MAAM,UAAU,MAAM;AAAA,EACjC;AAGA,QAAM,mBAAmB;AACzB,MAAI,iBAAiB,KAAK,IAAI,GAAG;AAC/B,WAAO;AAAA,MACL,MAAM,KAAK,QAAQ,kBAAkB,CAAC,UAAU,OAAOA,WAAU;AAAA,IAAO,KAAK,EAAE;AAAA,MAC/E,UAAU;AAAA,IACZ;AAAA,EACF;AAGA,SAAO;AAAA,IACL,MAAM,GAAG,IAAI;AAAA,EAAKA,WAAU;AAAA,IAC5B,UAAU;AAAA,IACV,SACE;AAAA,EACJ;AACF;;;ACvBA,IAAM,UAA8B;AAAA,EAClC;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AACF;AAmCO,SAAS,kBACd,MACA,MACyB;AACzB,MAAI,CAAC,KAAK,MAAO,QAAO,EAAE,MAAM,UAAU,CAAC,EAAE;AAE7C,QAAM,eAAyB,CAAC;AAChC,aAAW,UAAU,SAAS;AAC5B,QAAI,CAAC,KAAK,WAAW,OAAO,WAAW,EAAG;AAE1C,QAAI,KAAK,SAAS,OAAO,IAAI,EAAG;AAChC,iBAAa,KAAK,gCAAgC,OAAO,IAAI,MAAM;AAAA,EACrE;AAEA,MAAI,aAAa,WAAW,EAAG,QAAO,EAAE,MAAM,UAAU,CAAC,EAAE;AAE3D,QAAM,SAAS,aAAa,KAAK,QAAQ;AAEzC,QAAM,mBAAmB;AACzB,MAAI,iBAAiB,KAAK,IAAI,GAAG;AAC/B,WAAO;AAAA,MACL,MAAM,KAAK,QAAQ,kBAAkB,CAAC,UAAU,OAAO,MAAM;AAAA,IAAO,KAAK,EAAE;AAAA,MAC3E,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,kBAAkB;AACxB,MAAI,gBAAgB,KAAK,IAAI,GAAG;AAC9B,WAAO;AAAA,MACL,MAAM,KAAK,QAAQ,iBAAiB,CAAC,UAAU,GAAG,KAAK;AAAA,MAAS,MAAM,EAAE;AAAA,MACxE,UAAU;AAAA,IACZ;AAAA,EACF;AAGA,SAAO,EAAE,MAAM,GAAG,MAAM;AAAA,EAAK,IAAI,IAAI,UAAU,aAAa;AAC9D;;;AH5EO,SAAS,sBAAsB,MAAc,KAA+B;AAEjF,QAAM,QAAQ,kBAAkB,IAAI;AAEpC,MAAI,MAAM,QAAS,SAAQ,KAAK,MAAM,OAAO;AAC7C,MAAI,OAAO,MAAM;AAGjB,QAAM,WAAW,qBAAqB,MAAM;AAAA,IAC1C,OAAO,IAAI,UAAU;AAAA,IACrB,SAAS,IAAI;AAAA,EACf,CAAC;AAED,MAAI,SAAS,QAAS,SAAQ,KAAK,SAAS,OAAO;AACnD,SAAO,SAAS;AAShB,QAAM,SAAS,kBAAkB,MAAM;AAAA,IACrC,OAAO,IAAI,UAAU;AAAA,IACrB,YAAY,CAAC,SAASC,YAAWC,SAAQ,IAAI,aAAa,gBAAgB,GAAG,KAAK,MAAM,GAAG,CAAC,CAAC;AAAA,EAC/F,CAAC;AACD,SAAO,OAAO;AAEd,SAAO;AACT;;;AIzCO,SAAS,oBAAoB,UAA8B,CAAC,GAAW;AAC5E,MAAI,QAAQ,WAAW;AACrB,WAAO,uBAAuB,OAAO;AAAA,EACvC;AACA,SAAO,wBAAwB,OAAO;AACxC;AAOA,SAAS,eAAe,SAAqC;AAC3D,QAAM,QAAQ,QAAQ,QAAQ,SAAS;AAyBvC,MAAI,QAAQ,QAAQ;AAClB,WAAO;AAAA,MACL,iEAAiE,KAAK;AAAA,MACtE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AACA,SAAO;AAAA;AAAA;AACT;AAOA,SAAS,8BAAsC;AAC7C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,wBAAwB,SAAqC;AACpE,QAAM,eAAe,QAAQ,SAAS;AAAA,IAAmD;AACzF,QAAM,UAAU,eAAe,OAAO;AACtC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,OAAO;AAAA,IACxB;AAAA,IACA,4BAA4B;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAIA,SAAS,qBAAqB,SAA2B;AACvD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,OAAO;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,sBAAsB,SAA2B;AACxD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,OAAO;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,mBAAmB,SAA2B;AACrD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,OAAO;AAAA,IACxB;AAAA,IACA,4BAA4B;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,SAAqC;AACnE,QAAM,eAAe,QAAQ,SAAS;AAAA,IAAmD;AACzF,QAAM,UAAU,eAAe,OAAO;AACtC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG,qBAAqB,OAAO;AAAA,IAC/B;AAAA,IACA,GAAG,sBAAsB,OAAO;AAAA,IAChC;AAAA,IACA,GAAG,mBAAmB,OAAO;AAAA,EAC/B,EAAE,KAAK,IAAI;AACb;;;AClQO,SAAS,oBAAoB,KAAe,OAA2B,CAAC,GAAW;AACxF,QAAM,aAAa,MAAM,gBAAgB;AAIzC,QAAM,gBAA0B,CAAC;AACjC,MAAI,KAAK,QAAQ;AACf,kBAAc;AAAA,MACZ;AAAA,MACA;AAAA,IACF;AACA,UAAM,cAAc,KAAK,OAAO,UAAU,QAAQ,kBAAkB;AACpE,kBAAc;AAAA,MACZ,uBAAuB,WAAW;AAAA,MAClC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ,KAAK,QAAQ,SAAS;AAGpC,QAAM,aAAa,KAAK,SACpB,iEAAiE,KAAK;AAAA;AAAA;AAAA;AAAA,SACtE;AAAA;AAAA;AAEJ,QAAM,aAAa,MACf,KAAK,UAAU;AAAA,MAAa,UAAU;AAAA,OACtC,KAAK,UAAU;AAAA,MAAqB,UAAU;AAAA;AAYlD,QAAM,gBAAgB,MAClB,sGACA;AAsBJ,QAAM,eAAe,MACjB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IACA,CAAC;AAKL,QAAM,cAAc,MAChB;AAAA,IACE;AAAA,IACA;AAAA,IACA,GAAG,aAAa,IAAI,CAAC,MAAM,SAAS,CAAC;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,EACF,IACA,CAAC,aAAa,YAAY,GAAG;AAEjC,QAAM,kBAAkB,MACpB,qEACA;AAEJ,QAAM,qBAAqB,MACvB,oFACA;AAEJ,SAAO;AAAA,IACL;AAAA,IACA,YAAY,UAAU;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,EAAE,KAAK,IAAI;AACb;;;ACxHA,SAAS,cAAc,GAAmB;AACxC,SAAO,EAAE,QAAQ,OAAO,GAAG;AAC7B;AAEA,SAAS,YAAY,SAAiB,QAAwB;AAC5D,QAAM,OAAO,QAAQ,QAAQ,iBAAiB,GAAG,KAAK;AACtD,SAAO,GAAG,MAAM,IAAI,IAAI;AAC1B;AAQA,SAAS,YAAY,MAAyB;AAC5C,MAAI,KAAK,SAAS,SAAU,QAAO;AACnC,MAAI,KAAK,QAAS,QAAO,IAAI,KAAK,QAAQ,SAAS;AACnD,SAAO,KAAK;AACd;AAYA,SAAS,eAAe,SAAmB,SAAyB;AAClE,QAAM,SAAS,CAAC,GAAG,SAAS,OAAO,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAC7D,SAAO,MAAM;AACf;AAQA,SAAS,OAAO,eAA8B,UAA8B,SAAuB;AACjG,MAAI,aAAa,QAAW;AAC1B,kBAAc,KAAK,EAAE,SAAS,YAAY,cAAc,QAAQ,EAAE,CAAC;AAAA,EACrE;AACF;AAEA,SAAS,cAAc,MAAiB,SAAmB,KAA4B;AACrF,QAAM,MAAM,KAAK,WAAW;AAC5B,QAAM,YAAY,eAAe,SAAS,YAAY,IAAI,CAAC;AAE3D,MAAI,KAAK,SAAS,QAAW;AAC3B,QAAI,UAAU,KAAK;AAAA,MACjB,SAAS,YAAY,KAAK,MAAM;AAAA,MAChC,YAAY,cAAc,KAAK,IAAI;AAAA,MACnC;AAAA,IACF,CAAC;AAAA,EACH;AACA,MAAI,KAAK,WAAW,OAAW,KAAI,YAAY,QAAQ;AACvD,SAAO,IAAI,eAAe,KAAK,QAAQ,YAAY,KAAK,QAAQ,CAAC;AACjE,SAAO,IAAI,eAAe,KAAK,OAAO,YAAY,KAAK,OAAO,CAAC;AAC/D,SAAO,IAAI,eAAe,KAAK,SAAS,YAAY,KAAK,SAAS,CAAC;AACnE,SAAO,IAAI,eAAe,KAAK,UAAU,YAAY,KAAK,UAAU,CAAC;AACrE,aAAW,SAAS,KAAK,UAAU;AACjC,UAAM,eAAe,YAAY,IAAI;AACrC,UAAM,cAAc,eAAe,CAAC,GAAG,SAAS,YAAY,IAAI;AAChE,kBAAc,OAAO,aAAa,GAAG;AAAA,EACvC;AACF;AAEO,SAAS,sBAAsB,MAAyB;AAI7D,QAAM,MAAuB;AAAA,IAC3B,eAAe,CAAC;AAAA,IAChB,WAAW,CAAC;AAAA,IACZ,aAAa,EAAE,OAAO,MAAM;AAAA,EAC9B;AACA,gBAAc,MAAM,CAAC,GAAG,GAAG;AAC3B,QAAM,gBAAgB,IAAI;AAC1B,QAAM,YAAY,IAAI;AACtB,QAAM,cAAc,IAAI;AAUxB,QAAM,QAAkB,CAAC,yCAAyC;AAElE,MAAI,YAAY,OAAO;AACrB,UAAM,KAAK,uCAAuC;AAAA,EACpD;AAEA,QAAM,KAAK,EAAE;AAGb,aAAW,OAAO,eAAe;AAC/B,UAAM,KAAK,UAAU,IAAI,OAAO,UAAU,IAAI,UAAU,GAAG;AAAA,EAC7D;AAGA,aAAW,MAAM,WAAW;AAC1B,UAAM,KAAK,SAAS,GAAG,OAAO,+BAA+B,GAAG,UAAU,KAAK;AAAA,EACjF;AAEA,QAAM,KAAK,EAAE;AAKb,QAAM,iBAAiB,UAAU;AAAA,IAC/B,CAAC,OAAO,MAAM,GAAG,SAAS,oBAAoB,GAAG,UAAU;AAAA,EAC7D;AAGA,QAAM,KAAK,mCAAmC;AAC9C,aAAW,KAAK,eAAgB,OAAM,KAAK,CAAC;AAC5C,QAAM,KAAK,KAAK,EAAE;AAIlB,WAAS,mBAAmB,MAAiB,KAAqB;AAChE,UAAM,eAAyB,CAAC;AAKhC,QAAI,KAAK,MAAM;AACb,YAAM,UAAU,YAAY,KAAK,MAAM;AACvC,YAAM,aAAa,KAAK,UACpB,uBAAuB,YAAY,KAAK,SAAS,CAAC,MAClD;AACJ,YAAM,cAAc,6CAA6C,UAAU,2BAA2B,OAAO;AAC7G,mBAAa,KAAK,2BAA2B,WAAW,IAAI;AAAA,IAC9D;AAGA,eAAW,SAAS,KAAK,UAAU;AACjC,mBAAa,KAAK,eAAe,OAAO,KAAK,CAAC;AAAA,IAChD;AAGA,QAAI,KAAK,UAAU;AACjB,YAAM,QAAQ,YAAY,KAAK,UAAU;AACzC,mBAAa,KAAK,6CAA6C,KAAK,KAAK;AAAA,IAC3E;AAEA,QAAI,MAAM,IAAI,aAAa,KAAK,IAAI,CAAC;AACrC,QAAI,KAAK,OAAO;AACd,YAAM,SAAS,YAAY,KAAK,OAAO;AACvC,YAAM,wCAAwC,MAAM,gBAAgB,GAAG;AAAA,IACzE;AACA,WAAO;AAAA,EACT;AAGA,WAAS,eAAe,MAAiB,QAAyB;AAChE,UAAM,MAAM,KAAK,WAAW;AAC5B,UAAM,gBAAgB,mBAAmB,MAAM,GAAG;AAGlD,QAAI,KAAK,QAAQ;AACf,YAAM,YAAY,YAAY,KAAK,QAAQ;AAC3C,YAAM,WAAW,SAAS,cAAc,UAAU,YAAY,IAAI,CAAC;AAMnE,aAAO,KAAK,QAAQ,kCAAkC,SAAS,2DAA2D,aAAa;AAAA,IACzI;AAGA,QAAI,QAAQ;AACV,UAAI,KAAK,SAAS,WAAW,KAAK,CAAC,KAAK,QAAQ,CAAC,KAAK,YAAY,CAAC,KAAK,OAAO;AAC7E,eAAO;AAAA,MACT;AAEA,aAAO,0BAA0B,aAAa;AAAA,IAChD;AAGA,QAAI,KAAK,QAAQ,KAAK,SAAS,WAAW,KAAK,CAAC,KAAK,SAAS,CAAC,KAAK,UAAU;AAC5E,YAAM,UAAU,YAAY,KAAK,MAAM;AACvC,YAAM,aAAa,KAAK,UACpB,uBAAuB,YAAY,KAAK,SAAS,CAAC,MAClD;AACJ,YAAM,cAAc,6CAA6C,UAAU,2BAA2B,OAAO;AAC7G,aAAO,YAAY,YAAY,IAAI,CAAC,eAAe,WAAW;AAAA,IAChE;AAGA,WAAO,YAAY,YAAY,IAAI,CAAC,gBAAgB,aAAa;AAAA,EACnE;AAEA,QAAM,cAAc,eAAe,MAAM,IAAI;AAC7C,QAAM,KAAK,0BAA0B,WAAW,GAAG;AAEnD,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACvKO,SAAS,uBAAuB,IAAY,KAA2C;AAC5F,MAAI,OAAO,IAAI,iBAAkB,QAAO,IAAI;AAC5C,MAAI,OAAO,IAAI,oBAAqB,QAAO,IAAI;AAC/C,MAAI,OAAO,IAAI,wBAAyB,QAAO,IAAI;AACnD,MAAI,OAAO,IAAI,0BAA2B,QAAO,IAAI;AAGrD,MAAI,OAAO,oBAAqB,QAAO;AACvC,SAAO;AACT;AAEO,SAAS,kBAAkB,IAAY,KAA4C;AACxF,MAAI,OAAO,IAAI,IAAI,mBAAmB;AACpC,WAAO,oBAAoB,IAAI,YAAY;AAAA,MACzC,QAAQ,IAAI,QAAQ,UAChB,EAAE,OAAO,IAAI,OAAO,OAAO,OAAO,OAAO,IAAI,OAAO,OAAO,MAAM,IACjE;AAAA,IACN,CAAC;AAAA,EACH;AACA,MAAI,OAAO,IAAI,IAAI,sBAAsB;AACvC,UAAM,OAAO,WAAW,IAAI,MAAM;AAGlC,2BAAuB,IAAI;AAC3B,WAAO,sBAAsB,IAAI;AAAA,EACnC;AACA,MAAI,OAAO,IAAI,IAAI,0BAA0B;AAK3C,WAAO,oBAAoB;AAAA,MACzB,WAAW,IAAI;AAAA,MACf,QAAQ,IAAI,QAAQ,UAAU,EAAE,OAAO,IAAI,OAAO,OAAO,MAAM,IAAI;AAAA,IACrE,CAAC;AAAA,EACH;AACA,MAAI,OAAO,IAAI,IAAI,4BAA4B;AAE7C,UAAM,QAAQ,IAAI,aAAa,QAAQ;AACvC,WAAO;AAAA,MACL;AAAA,MACA,wCAAwC,KAAK,UAAU,KAAK,CAAC;AAAA,MAC7D,mCAAmC,KAAK,UAAU,KAAK,CAAC;AAAA,IAC1D,EAAE,KAAK,IAAI;AAAA,EACb;AACA,MAAI,OAAO,sBAAsB;AAE/B,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AACA,SAAO;AACT;;;AC3DO,SAAS,sBAAsB,aAA+C;AACnF,SAAO;AACT;AAEO,IAAM,sCAAN,cAAkD,MAAM;AAAA,EAC7D,YAAY,iBAAyB,IAAY;AAC/C;AAAA,MACE,gBAAgB,eAAe,gCAAgC,EAAE,+DACJ,eAAe;AAAA,IAE9E;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,iCAAN,cAA6C,MAAM;AAAA,EACxD,YAAY,iBAAyB,MAAc;AACjD;AAAA,MACE,gBAAgB,eAAe,8BAA8B,IAAI;AAAA,IAEnE;AACA,SAAK,OAAO;AAAA,EACd;AACF;AA4BO,SAAS,0BACd,SACqB;AACrB,QAAM,eAAkC,CAAC;AACzC,QAAM,iBAAiB,oBAAI,IAA6C;AACxE,QAAM,SAAmE,CAAC;AAC1E,QAAM,aAAa,IAAI,IAAI,QAAQ,cAAc;AAEjD,WAAS,gBAAgB,iBAAyB,OAA0C;AAC1F,WAAO;AAAA,MACL,GAAG;AAAA,MACH,kBAAkB,CAAC,IAAY,SAAiB;AAC9C,yBAAiB,iBAAiB,IAAI,IAAI;AAAA,MAC5C;AAAA,MACA,UAAU,CAAC,MAAc,YAA0B;AACjD,iBAAS,iBAAiB,MAAM,OAAO;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAEA,WAAS,iBAAiB,iBAAyB,IAAY,MAAoB;AACjF,UAAM,iBAAiB,uBAAuB,eAAe;AAC7D,QAAI,CAAC,GAAG,WAAW,cAAc,GAAG;AAClC,YAAM,IAAI,oCAAoC,iBAAiB,EAAE;AAAA,IACnE;AACA,mBAAe,IAAI,IAAI,EAAE,MAAM,OAAO,gBAAgB,CAAC;AAAA,EACzD;AAEA,WAAS,SAAS,iBAAyB,MAAc,SAA6B;AACpF,QAAI,WAAW,IAAI,IAAI,GAAG;AACxB,YAAM,IAAI,+BAA+B,iBAAiB,IAAI;AAAA,IAChE;AACA,QAAI,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,GAAG;AACvC,YAAM,IAAI,+BAA+B,iBAAiB,IAAI;AAAA,IAChE;AACA,WAAO,KAAK,EAAE,MAAM,OAAO,iBAAiB,QAAQ,CAAC;AAAA,EACvD;AAEA,SAAO;AAAA,IACL,oBAAoB,aAAa;AAC/B,mBAAa,KAAK,WAAW;AAAA,IAC/B;AAAA,IACA,MAAM,KAAK,UAAU,SAAS;AAC5B,iBAAW,QAAQ,cAAc;AAC/B,cAAM,OAAO,KAAK,MAAM,QAAQ;AAChC,YAAI,CAAC,KAAM;AACX,YAAI;AACF,gBAAM,KAAK,gBAAgB,KAAK,MAAM,OAAO,CAAC;AAAA,QAChD,SAAS,KAAK;AACZ,gBAAM,IAAI,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAC5D,gBAAM,UAAU,IAAI;AAAA,YAClB,gBAAgB,KAAK,IAAI,WAAW,QAAQ,YAAY,EAAE,OAAO;AAAA,UACnE;AACC,UAAC,QAAgC,QAAQ;AAC1C,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,IAAI;AACnB,aAAO,eAAe,IAAI,EAAE,GAAG;AAAA,IACjC;AAAA,IACA,qBAAqB;AACnB,aAAO,MAAM,KAAK,eAAe,KAAK,CAAC;AAAA,IACzC;AAAA,IACA,aAAa;AACX,aAAO,OAAO,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE;AAAA,IAC7D;AAAA;AAAA,IAEA,MAAM,SAAS,iBAAiB,WAAW,UAAU;AAGnD,sBAAgB,iBAAiB,QAAQ;AAEzC,UAAI,OAAO,SAAS,qBAAqB,YAAY;AACnD,iBAAS;AAAA,UACP,uBAAuB,eAAe;AAAA,UACtC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AtBnHA,IAAM,mBAAmB;AACzB,IAAM,oBAAoB;AAC1B,IAAM,sBAAsB;AAC5B,IAAM,uBAAuB;AAC7B,IAAM,0BAA0B;AAChC,IAAM,2BAA2B;AACjC,IAAM,4BAA4B;AAClC,IAAM,6BAA6B;AA+DnC,SAAS,mBAAmB,aAAqBC,WAAsC;AACrF,QAAM,aAAa,CAAC,OAAO,OAAO,QAAQ,MAAM;AAChD,MAAI,MAAM;AACV,WAAS,QAAQ,GAAG,QAAQ,GAAG,SAAS;AACtC,eAAW,OAAO,YAAY;AAC5B,YAAM,YAAYC,SAAQ,KAAK,GAAGD,SAAQ,GAAG,GAAG,EAAE;AAClD,UAAIE,YAAW,SAAS,EAAG,QAAO;AAAA,IACpC;AACA,UAAM,SAASC,SAAQ,GAAG;AAC1B,QAAI,WAAW,IAAK;AACpB,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAiBA,eAAsB,gBACpB,eACmB;AACnB,QAAM,UACJ,OAAO,kBAAkB,WAAW,EAAE,MAAM,cAAc,IAAK,iBAAiB,CAAC;AACnF,QAAM,cAAc,QAAQ,QAAQ,QAAQ,IAAI;AAGhD,QAAM,eAAeF,SAAQ,aAAa,QAAQ,aAAa,QAAQ;AAGvE,QAAM,gBAAgB,QAAQ,aAAa;AAE3C,QAAM,yBAAyB,mBAAmB,aAAa,iBAAiB;AAChF,QAAM,wBAAwB,mBAAmB,aAAa,gBAAgB;AAC9E,QAAM,YAAY,MAAM,mBAAmB,aAAa;AAAA,IACtD;AAAA,IACA;AAAA,EACF,CAAC;AAID,QAAM,kBAA4B,CAAC;AACnC,MAAI,QAAQ,YAAY,OAAO,KAAK,QAAQ,QAAQ,EAAE,SAAS,GAAG;AAChE,UAAM,EAAE,0BAA0B,IAAI,MAAM,OAAO,qCAA4B;AAC/E,oBAAgB;AAAA,MACd,0BAA0B;AAAA,QACxB,KAAK;AAAA,QACL,UAAU,QAAQ;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF;AAIA,QAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,gCAAuB;AACrE,QAAM,kBAAkB,qBAAqB;AAAA,IAC3C,KAAK;AAAA,IACL,WAAW;AAAA,IACX,SAASA,SAAQ,aAAa,UAAU;AAAA,EAC1C,CAAC;AAOD,QAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,sCAA6B;AAC3E,QAAM,gBAAgB,qBAAqB;AAAA,IACzC,WAAW;AAAA,IACX,SAASA,SAAQ,aAAa,UAAU;AAAA,EAC1C,CAAC;AAKD,QAAM,EAAE,wBAAwB,IAAI,MAAM,OAAO,mCAA0B;AAC3E,QAAM,EAAE,iBAAiB,IAAI,MAAM,OAAO,4BAA2B;AACrE,QAAM,qBAAqB,wBAAwB;AAAA,IACjD;AAAA,IACA,WAAW;AAAA,IACX,SAASA,SAAQ,aAAa,UAAU;AAAA;AAAA;AAAA,IAGxC,cAAc,MAAM,iBAAiB,cAAc,aAAa,aAAa;AAAA,EAC/E,CAAC;AAKD,QAAM,EAAE,sBAAsB,IAAI,MAAM,OAAO,iCAAwB;AACvE,QAAM,kBAAkB,sBAAsB;AAAA,IAC5C,WAAW;AAAA,EACb,CAAC;AAMD,QAAM,EAAE,6BAA6B,IAAI,MAAM,OAAO,wCAA+B;AACrF,QAAM,4BAA4B,6BAA6B;AAAA,IAC7D,WAAW;AAAA,EACb,CAAC;AAED,SAAO;AAAA,IACL,WAAW,aAAa;AAAA,IACxB,GAAG;AAAA,IACH,GAAG;AAAA;AAAA,IAEH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAUA,SAAS,yBACP,aACA,kBACU;AACV,QAAM,UAAoB,CAAC;AAC3B,MAAIC,YAAWD,SAAQ,aAAa,gBAAgB,YAAY,IAAI,CAAC,GAAG;AACtE,YAAQ,KAAK,aAAa;AAAA,EAC5B;AACA,MAAIC,YAAWD,SAAQ,aAAa,gBAAgB,cAAc,CAAC,GAAG;AACpE,YAAQ,KAAK,cAAc;AAAA,EAC7B;AAKA,UAAQ,KAAK,SAAS;AACtB,MAAI,MAAM,QAAQ,gBAAgB,GAAG;AACnC,eAAW,OAAO,kBAAkB;AAClC,UAAI,OAAO,QAAQ,YAAY,IAAI,SAAS,KAAK,CAAC,QAAQ,SAAS,GAAG,GAAG;AACvE,gBAAQ,KAAK,GAAG;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,qBAAuC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,WAAW,eAAoD;AAC7E,QAAM,UACJ,OAAO,kBAAkB,WAAW,EAAE,MAAM,cAAc,IAAK,iBAAiB,CAAC;AACnF,QAAM,cAAc,QAAQ,QAAQ,QAAQ,IAAI;AAEhD,QAAM,SAASA,SAAQ,aAAa,QAAQ,UAAU,KAAK;AAE3D,QAAM,YAAYA,SAAQ,aAAa,QAAQ,aAAa,QAAQ;AAEpE,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,aAAa,QAAQ,OAAO;AAIlC,QAAM,aAAaE,SAAQ,cAAc,YAAY,GAAG,CAAC;AACzD,QAAM,aAAa,mBAAmB,UAAU;AAKhD,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI,WAAsC;AAC1C,MAAI;AACJ,MAAI;AAEJ,MAAI;AAEJ,MAAI;AAEJ,MAAI,kBAAkB;AAEtB,MAAI;AACJ,MAAI,kBAAkB;AAKtB,QAAM,eAAe,EAAE,OAAO,MAAM;AACpC,MAAI,mBAAmB;AAEvB,SAAO;AAAA,IACL,MAAM;AAAA,IAEN,MAAM,iBAAiB;AAIrB,UAAI,iBAAkB;AACtB,yBAAmB;AACnB,YAAM,WAAW,MAAM,oBAAoB,WAAW;AACtD,qBAAe,SAAS;AACxB,oBAAc,SAAS;AACvB,yBAAmB,SAAS;AAC5B,eAAS,SAAS;AAClB,iBAAW,SAAS;AACpB,wBAAkB,SAAS;AAC3B,mBAAa,SAAS;AACtB,aAAO,SAAS;AAChB,oBAAc,SAAS;AACvB,wBAAkB,SAAS;AAC3B,wBAAkB,SAAS;AAC3B,wBAAkB,SAAS;AAAA,IAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,SAAS;AACP,aAAO,cAAc;AAAA,QACnB;AAAA,QACA;AAAA,QACA,UAAU,QAAQ;AAAA,QAClB,qBAAqB,yBAAyB,aAAa,QAAQ,gBAAgB;AAAA,MACrF,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA,IAKA,oBAAoB;AAAA,MAClB,OAAO;AAAA,MACP,QAAQ,MAAsB;AAC5B,eAAO,sBAAsB,MAAM;AAAA,UACjC,WAAW;AAAA,UACX;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,UAAU,IAAY;AACpB,aAAO,uBAAuB,IAAI,kBAAkB;AAAA,IACtD;AAAA,IAEA,KAAK,IAAY;AACf,aAAO,kBAAkB,IAAI;AAAA,QAC3B,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,kBAAkB,QAAQ,iBAAiB;AAAA,QAC3C;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,MAAM,gBAAgB,QAAQ;AAC5B,YAAM,mBAAmB,QAAQ;AAAA,QAC/B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU,QAAQ;AAAA,QAClB,WAAW,QAAQ;AAAA,QACnB,4BAA4B,QAAQ;AAAA,QACpC,sBAAsB;AAAA,QACtB,oBAAoB;AAAA,MACtB,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":["existsSync","resolve","dirname","existsSync","resolve","randomUUID","PREFIX","randomUUID","resolve","resolve","readFileSync","resolve","resolve","readFileSync","resolve","resolve","resolve","existsSync","readFileSync","dirname","join","existsSync","readFileSync","dirname","join","join","existsSync","readFileSync","dirname","join","existsSync","existsSync","resolve","existsSync","resolve","SCRIPT_TAG","existsSync","resolve","basename","resolve","existsSync","dirname"]}
|