alepha 0.13.0 → 0.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (461) hide show
  1. package/README.md +1 -1
  2. package/dist/api-files/index.d.ts +28 -91
  3. package/dist/api-files/index.js +10 -755
  4. package/dist/api-files/index.js.map +1 -1
  5. package/dist/api-jobs/index.d.ts +67 -67
  6. package/dist/api-jobs/index.js +13 -13
  7. package/dist/api-jobs/index.js.map +1 -1
  8. package/dist/api-notifications/index.d.ts +129 -146
  9. package/dist/api-notifications/index.js +17 -39
  10. package/dist/api-notifications/index.js.map +1 -1
  11. package/dist/api-parameters/index.d.ts +21 -22
  12. package/dist/api-parameters/index.js +22 -22
  13. package/dist/api-parameters/index.js.map +1 -1
  14. package/dist/api-users/index.d.ts +224 -2001
  15. package/dist/api-users/index.js +914 -4787
  16. package/dist/api-users/index.js.map +1 -1
  17. package/dist/api-verifications/index.d.ts +96 -96
  18. package/dist/batch/index.d.ts +13 -13
  19. package/dist/batch/index.js +8 -8
  20. package/dist/batch/index.js.map +1 -1
  21. package/dist/bucket/index.d.ts +14 -14
  22. package/dist/bucket/index.js +12 -12
  23. package/dist/bucket/index.js.map +1 -1
  24. package/dist/cache/index.d.ts +11 -11
  25. package/dist/cache/index.js +9 -9
  26. package/dist/cache/index.js.map +1 -1
  27. package/dist/cli/{dist-Sz2EXvQX.cjs → dist-Dl9Vl7Ur.js} +17 -13
  28. package/dist/cli/{dist-BBPjuQ56.js.map → dist-Dl9Vl7Ur.js.map} +1 -1
  29. package/dist/cli/index.d.ts +31 -37
  30. package/dist/cli/index.js +152 -83
  31. package/dist/cli/index.js.map +1 -1
  32. package/dist/command/index.d.ts +19 -19
  33. package/dist/command/index.js +25 -25
  34. package/dist/command/index.js.map +1 -1
  35. package/dist/core/index.browser.js +218 -218
  36. package/dist/core/index.browser.js.map +1 -1
  37. package/dist/core/index.d.ts +232 -232
  38. package/dist/core/index.js +218 -218
  39. package/dist/core/index.js.map +1 -1
  40. package/dist/core/{index.cjs → index.native.js} +304 -455
  41. package/dist/core/index.native.js.map +1 -0
  42. package/dist/datetime/index.d.ts +9 -9
  43. package/dist/datetime/index.js +7 -7
  44. package/dist/datetime/index.js.map +1 -1
  45. package/dist/email/index.d.ts +16 -16
  46. package/dist/email/index.js +80 -82
  47. package/dist/email/index.js.map +1 -1
  48. package/dist/file/index.js +1 -1
  49. package/dist/file/index.js.map +1 -1
  50. package/dist/lock/index.d.ts +9 -9
  51. package/dist/lock/index.js +8 -8
  52. package/dist/lock/index.js.map +1 -1
  53. package/dist/lock-redis/index.js +3 -66
  54. package/dist/lock-redis/index.js.map +1 -1
  55. package/dist/logger/index.d.ts +5 -5
  56. package/dist/logger/index.js +8 -8
  57. package/dist/logger/index.js.map +1 -1
  58. package/dist/orm/index.browser.js +114 -114
  59. package/dist/orm/index.browser.js.map +1 -1
  60. package/dist/orm/index.d.ts +219 -219
  61. package/dist/orm/index.js +46 -46
  62. package/dist/orm/index.js.map +1 -1
  63. package/dist/queue/index.d.ts +25 -25
  64. package/dist/queue/index.js +20 -20
  65. package/dist/queue/index.js.map +1 -1
  66. package/dist/queue-redis/index.d.ts +2 -2
  67. package/dist/redis/index.d.ts +10 -10
  68. package/dist/retry/index.d.ts +20 -20
  69. package/dist/retry/index.js +9 -9
  70. package/dist/retry/index.js.map +1 -1
  71. package/dist/scheduler/index.d.ts +12 -12
  72. package/dist/scheduler/index.js +9 -9
  73. package/dist/scheduler/index.js.map +1 -1
  74. package/dist/security/index.d.ts +53 -53
  75. package/dist/security/index.js +32 -32
  76. package/dist/security/index.js.map +1 -1
  77. package/dist/server/index.browser.js +1 -1
  78. package/dist/server/index.browser.js.map +1 -1
  79. package/dist/server/index.d.ts +101 -101
  80. package/dist/server/index.js +17 -17
  81. package/dist/server/index.js.map +1 -1
  82. package/dist/server-auth/index.browser.js +4 -982
  83. package/dist/server-auth/index.browser.js.map +1 -1
  84. package/dist/server-auth/index.d.ts +204 -785
  85. package/dist/server-auth/index.js +47 -1239
  86. package/dist/server-auth/index.js.map +1 -1
  87. package/dist/server-cache/index.d.ts +10 -10
  88. package/dist/server-cache/index.js +2 -2
  89. package/dist/server-cache/index.js.map +1 -1
  90. package/dist/server-compress/index.d.ts +4 -4
  91. package/dist/server-compress/index.js +1 -1
  92. package/dist/server-compress/index.js.map +1 -1
  93. package/dist/server-cookies/index.browser.js +8 -8
  94. package/dist/server-cookies/index.browser.js.map +1 -1
  95. package/dist/server-cookies/index.d.ts +17 -17
  96. package/dist/server-cookies/index.js +10 -10
  97. package/dist/server-cookies/index.js.map +1 -1
  98. package/dist/server-cors/index.d.ts +17 -17
  99. package/dist/server-cors/index.js +9 -9
  100. package/dist/server-cors/index.js.map +1 -1
  101. package/dist/server-health/index.d.ts +2 -2
  102. package/dist/server-helmet/index.d.ts +1 -1
  103. package/dist/server-links/index.browser.js +12 -12
  104. package/dist/server-links/index.browser.js.map +1 -1
  105. package/dist/server-links/index.d.ts +59 -251
  106. package/dist/server-links/index.js +23 -502
  107. package/dist/server-links/index.js.map +1 -1
  108. package/dist/server-metrics/index.d.ts +4 -4
  109. package/dist/server-metrics/index.js +170 -174
  110. package/dist/server-metrics/index.js.map +1 -1
  111. package/dist/server-multipart/index.d.ts +2 -2
  112. package/dist/server-proxy/index.d.ts +12 -12
  113. package/dist/server-proxy/index.js +10 -10
  114. package/dist/server-proxy/index.js.map +1 -1
  115. package/dist/server-rate-limit/index.d.ts +22 -22
  116. package/dist/server-rate-limit/index.js +12 -12
  117. package/dist/server-rate-limit/index.js.map +1 -1
  118. package/dist/server-security/index.d.ts +24 -24
  119. package/dist/server-security/index.js +15 -15
  120. package/dist/server-security/index.js.map +1 -1
  121. package/dist/server-static/index.d.ts +14 -14
  122. package/dist/server-static/index.js +8 -8
  123. package/dist/server-static/index.js.map +1 -1
  124. package/dist/server-swagger/index.d.ts +25 -184
  125. package/dist/server-swagger/index.js +21 -724
  126. package/dist/server-swagger/index.js.map +1 -1
  127. package/dist/sms/index.d.ts +14 -14
  128. package/dist/sms/index.js +9 -9
  129. package/dist/sms/index.js.map +1 -1
  130. package/dist/thread/index.d.ts +11 -11
  131. package/dist/thread/index.js +17 -17
  132. package/dist/thread/index.js.map +1 -1
  133. package/dist/topic/index.d.ts +26 -26
  134. package/dist/topic/index.js +16 -16
  135. package/dist/topic/index.js.map +1 -1
  136. package/dist/topic-redis/index.d.ts +1 -1
  137. package/dist/vite/index.d.ts +3 -3
  138. package/dist/vite/index.js +12 -13
  139. package/dist/vite/index.js.map +1 -1
  140. package/dist/websocket/index.browser.js +11 -11
  141. package/dist/websocket/index.browser.js.map +1 -1
  142. package/dist/websocket/index.d.ts +51 -51
  143. package/dist/websocket/index.js +13 -13
  144. package/dist/websocket/index.js.map +1 -1
  145. package/package.json +62 -52
  146. package/src/api-files/services/FileService.ts +5 -7
  147. package/src/api-jobs/index.ts +1 -1
  148. package/src/api-jobs/{descriptors → primitives}/$job.ts +8 -8
  149. package/src/api-jobs/providers/JobProvider.ts +9 -9
  150. package/src/api-jobs/services/JobService.ts +5 -5
  151. package/src/api-notifications/index.ts +5 -15
  152. package/src/api-notifications/{descriptors → primitives}/$notification.ts +10 -10
  153. package/src/api-notifications/services/NotificationSenderService.ts +3 -3
  154. package/src/api-parameters/index.ts +1 -1
  155. package/src/api-parameters/{descriptors → primitives}/$config.ts +7 -12
  156. package/src/api-users/index.ts +1 -1
  157. package/src/api-users/{descriptors → primitives}/$userRealm.ts +8 -8
  158. package/src/api-users/providers/UserRealmProvider.ts +1 -1
  159. package/src/batch/index.ts +3 -3
  160. package/src/batch/{descriptors → primitives}/$batch.ts +13 -16
  161. package/src/bucket/index.ts +8 -8
  162. package/src/bucket/{descriptors → primitives}/$bucket.ts +8 -8
  163. package/src/bucket/providers/LocalFileStorageProvider.ts +3 -3
  164. package/src/cache/index.ts +4 -4
  165. package/src/cache/{descriptors → primitives}/$cache.ts +15 -15
  166. package/src/cli/apps/AlephaPackageBuilderCli.ts +30 -3
  167. package/src/cli/assets/appRouterTs.ts +9 -0
  168. package/src/cli/assets/indexHtml.ts +2 -1
  169. package/src/cli/assets/mainBrowserTs.ts +10 -0
  170. package/src/cli/commands/CoreCommands.ts +6 -5
  171. package/src/cli/commands/DrizzleCommands.ts +69 -61
  172. package/src/cli/commands/VerifyCommands.ts +2 -2
  173. package/src/cli/commands/ViteCommands.ts +6 -1
  174. package/src/cli/services/ProjectUtils.ts +78 -41
  175. package/src/command/index.ts +5 -5
  176. package/src/command/{descriptors → primitives}/$command.ts +9 -12
  177. package/src/command/providers/CliProvider.ts +10 -10
  178. package/src/core/Alepha.ts +30 -33
  179. package/src/core/constants/KIND.ts +1 -1
  180. package/src/core/constants/OPTIONS.ts +1 -1
  181. package/src/core/helpers/{descriptor.ts → primitive.ts} +18 -18
  182. package/src/core/helpers/ref.ts +1 -1
  183. package/src/core/index.shared.ts +8 -8
  184. package/src/core/{descriptors → primitives}/$context.ts +5 -5
  185. package/src/core/{descriptors → primitives}/$hook.ts +4 -4
  186. package/src/core/{descriptors → primitives}/$inject.ts +2 -2
  187. package/src/core/{descriptors → primitives}/$module.ts +9 -9
  188. package/src/core/{descriptors → primitives}/$use.ts +2 -2
  189. package/src/core/providers/CodecManager.ts +1 -1
  190. package/src/core/providers/JsonSchemaCodec.ts +1 -1
  191. package/src/core/providers/StateManager.ts +2 -2
  192. package/src/datetime/index.ts +3 -3
  193. package/src/datetime/{descriptors → primitives}/$interval.ts +6 -6
  194. package/src/email/index.ts +4 -4
  195. package/src/email/{descriptors → primitives}/$email.ts +8 -8
  196. package/src/file/index.ts +1 -1
  197. package/src/lock/index.ts +3 -3
  198. package/src/lock/{descriptors → primitives}/$lock.ts +10 -10
  199. package/src/logger/index.ts +8 -8
  200. package/src/logger/{descriptors → primitives}/$logger.ts +2 -2
  201. package/src/logger/services/Logger.ts +1 -1
  202. package/src/orm/constants/PG_SYMBOLS.ts +2 -2
  203. package/src/orm/index.browser.ts +2 -2
  204. package/src/orm/index.ts +8 -8
  205. package/src/orm/{descriptors → primitives}/$entity.ts +11 -11
  206. package/src/orm/{descriptors → primitives}/$repository.ts +2 -2
  207. package/src/orm/{descriptors → primitives}/$sequence.ts +8 -8
  208. package/src/orm/{descriptors → primitives}/$transaction.ts +4 -4
  209. package/src/orm/providers/DrizzleKitProvider.ts +1 -1
  210. package/src/orm/providers/PostgresTypeProvider.ts +3 -3
  211. package/src/orm/providers/RepositoryProvider.ts +4 -4
  212. package/src/orm/providers/drivers/DatabaseProvider.ts +7 -7
  213. package/src/orm/services/ModelBuilder.ts +9 -9
  214. package/src/orm/services/PgRelationManager.ts +2 -2
  215. package/src/orm/services/PostgresModelBuilder.ts +5 -5
  216. package/src/orm/services/Repository.ts +7 -7
  217. package/src/orm/services/SqliteModelBuilder.ts +5 -5
  218. package/src/queue/index.ts +7 -7
  219. package/src/queue/{descriptors → primitives}/$consumer.ts +15 -15
  220. package/src/queue/{descriptors → primitives}/$queue.ts +12 -12
  221. package/src/queue/providers/WorkerProvider.ts +7 -7
  222. package/src/retry/index.ts +3 -3
  223. package/src/retry/{descriptors → primitives}/$retry.ts +19 -17
  224. package/src/scheduler/index.ts +3 -3
  225. package/src/scheduler/{descriptors → primitives}/$scheduler.ts +9 -9
  226. package/src/scheduler/providers/CronProvider.ts +1 -1
  227. package/src/security/index.ts +9 -9
  228. package/src/security/{descriptors → primitives}/$permission.ts +7 -7
  229. package/src/security/{descriptors → primitives}/$realm.ts +6 -12
  230. package/src/security/{descriptors → primitives}/$role.ts +12 -12
  231. package/src/security/{descriptors → primitives}/$serviceAccount.ts +8 -8
  232. package/src/server/index.browser.ts +1 -1
  233. package/src/server/index.ts +14 -14
  234. package/src/server/{descriptors → primitives}/$action.ts +13 -13
  235. package/src/server/{descriptors → primitives}/$route.ts +9 -9
  236. package/src/server/providers/NodeHttpServerProvider.ts +2 -2
  237. package/src/server/services/HttpClient.ts +1 -1
  238. package/src/server-auth/index.browser.ts +1 -1
  239. package/src/server-auth/index.ts +6 -6
  240. package/src/server-auth/{descriptors → primitives}/$auth.ts +10 -10
  241. package/src/server-auth/{descriptors → primitives}/$authCredentials.ts +4 -4
  242. package/src/server-auth/{descriptors → primitives}/$authGithub.ts +4 -4
  243. package/src/server-auth/{descriptors → primitives}/$authGoogle.ts +4 -4
  244. package/src/server-auth/providers/ServerAuthProvider.ts +4 -4
  245. package/src/server-cache/providers/ServerCacheProvider.ts +7 -7
  246. package/src/server-compress/providers/ServerCompressProvider.ts +3 -3
  247. package/src/server-cookies/index.browser.ts +2 -2
  248. package/src/server-cookies/index.ts +5 -5
  249. package/src/server-cookies/{descriptors → primitives}/$cookie.browser.ts +12 -12
  250. package/src/server-cookies/{descriptors → primitives}/$cookie.ts +13 -13
  251. package/src/server-cookies/providers/ServerCookiesProvider.ts +4 -4
  252. package/src/server-cookies/services/CookieParser.ts +1 -1
  253. package/src/server-cors/index.ts +3 -3
  254. package/src/server-cors/{descriptors → primitives}/$cors.ts +11 -13
  255. package/src/server-cors/providers/ServerCorsProvider.ts +5 -5
  256. package/src/server-links/index.browser.ts +5 -5
  257. package/src/server-links/index.ts +9 -9
  258. package/src/server-links/{descriptors → primitives}/$remote.ts +11 -11
  259. package/src/server-links/providers/LinkProvider.ts +7 -7
  260. package/src/server-links/providers/{RemoteDescriptorProvider.ts → RemotePrimitiveProvider.ts} +6 -6
  261. package/src/server-links/providers/ServerLinksProvider.ts +3 -3
  262. package/src/server-proxy/index.ts +3 -3
  263. package/src/server-proxy/{descriptors → primitives}/$proxy.ts +8 -8
  264. package/src/server-proxy/providers/ServerProxyProvider.ts +4 -4
  265. package/src/server-rate-limit/index.ts +6 -6
  266. package/src/server-rate-limit/{descriptors → primitives}/$rateLimit.ts +13 -13
  267. package/src/server-rate-limit/providers/ServerRateLimitProvider.ts +5 -5
  268. package/src/server-security/index.ts +3 -3
  269. package/src/server-security/{descriptors → primitives}/$basicAuth.ts +13 -13
  270. package/src/server-security/providers/ServerBasicAuthProvider.ts +5 -5
  271. package/src/server-security/providers/ServerSecurityProvider.ts +4 -4
  272. package/src/server-static/index.ts +3 -3
  273. package/src/server-static/{descriptors → primitives}/$serve.ts +8 -10
  274. package/src/server-static/providers/ServerStaticProvider.ts +6 -6
  275. package/src/server-swagger/index.ts +5 -5
  276. package/src/server-swagger/{descriptors → primitives}/$swagger.ts +9 -9
  277. package/src/server-swagger/providers/ServerSwaggerProvider.ts +11 -10
  278. package/src/sms/index.ts +4 -4
  279. package/src/sms/{descriptors → primitives}/$sms.ts +8 -8
  280. package/src/thread/index.ts +3 -3
  281. package/src/thread/{descriptors → primitives}/$thread.ts +13 -13
  282. package/src/thread/providers/ThreadProvider.ts +7 -9
  283. package/src/topic/index.ts +5 -5
  284. package/src/topic/{descriptors → primitives}/$subscriber.ts +14 -14
  285. package/src/topic/{descriptors → primitives}/$topic.ts +10 -10
  286. package/src/topic/providers/TopicProvider.ts +4 -4
  287. package/src/vite/helpers/boot.ts +3 -3
  288. package/src/vite/tasks/copyAssets.ts +1 -1
  289. package/src/vite/tasks/generateSitemap.ts +3 -3
  290. package/src/vite/tasks/prerenderPages.ts +2 -2
  291. package/src/vite/tasks/runAlepha.ts +2 -2
  292. package/src/websocket/index.browser.ts +3 -3
  293. package/src/websocket/index.shared.ts +2 -2
  294. package/src/websocket/index.ts +4 -4
  295. package/src/websocket/interfaces/WebSocketInterfaces.ts +3 -3
  296. package/src/websocket/{descriptors → primitives}/$channel.ts +10 -10
  297. package/src/websocket/{descriptors → primitives}/$websocket.ts +8 -8
  298. package/src/websocket/providers/NodeWebSocketServerProvider.ts +7 -7
  299. package/src/websocket/providers/WebSocketServerProvider.ts +3 -3
  300. package/src/websocket/services/WebSocketClient.ts +5 -5
  301. package/dist/api-files/index.cjs +0 -1293
  302. package/dist/api-files/index.cjs.map +0 -1
  303. package/dist/api-files/index.d.cts +0 -829
  304. package/dist/api-jobs/index.cjs +0 -274
  305. package/dist/api-jobs/index.cjs.map +0 -1
  306. package/dist/api-jobs/index.d.cts +0 -654
  307. package/dist/api-notifications/index.cjs +0 -380
  308. package/dist/api-notifications/index.cjs.map +0 -1
  309. package/dist/api-notifications/index.d.cts +0 -289
  310. package/dist/api-parameters/index.cjs +0 -66
  311. package/dist/api-parameters/index.cjs.map +0 -1
  312. package/dist/api-parameters/index.d.cts +0 -84
  313. package/dist/api-users/index.cjs +0 -6009
  314. package/dist/api-users/index.cjs.map +0 -1
  315. package/dist/api-users/index.d.cts +0 -4740
  316. package/dist/api-verifications/index.cjs +0 -407
  317. package/dist/api-verifications/index.cjs.map +0 -1
  318. package/dist/api-verifications/index.d.cts +0 -207
  319. package/dist/batch/index.cjs +0 -408
  320. package/dist/batch/index.cjs.map +0 -1
  321. package/dist/batch/index.d.cts +0 -330
  322. package/dist/bin/index.cjs +0 -17
  323. package/dist/bin/index.cjs.map +0 -1
  324. package/dist/bin/index.d.cts +0 -1
  325. package/dist/bucket/index.cjs +0 -303
  326. package/dist/bucket/index.cjs.map +0 -1
  327. package/dist/bucket/index.d.cts +0 -355
  328. package/dist/cache/index.cjs +0 -241
  329. package/dist/cache/index.cjs.map +0 -1
  330. package/dist/cache/index.d.cts +0 -202
  331. package/dist/cache-redis/index.cjs +0 -84
  332. package/dist/cache-redis/index.cjs.map +0 -1
  333. package/dist/cache-redis/index.d.cts +0 -40
  334. package/dist/cli/chunk-DSlc6foC.cjs +0 -43
  335. package/dist/cli/dist-BBPjuQ56.js +0 -2778
  336. package/dist/cli/dist-Sz2EXvQX.cjs.map +0 -1
  337. package/dist/cli/index.cjs +0 -1241
  338. package/dist/cli/index.cjs.map +0 -1
  339. package/dist/cli/index.d.cts +0 -422
  340. package/dist/command/index.cjs +0 -693
  341. package/dist/command/index.cjs.map +0 -1
  342. package/dist/command/index.d.cts +0 -340
  343. package/dist/core/index.cjs.map +0 -1
  344. package/dist/core/index.d.cts +0 -1927
  345. package/dist/datetime/index.cjs +0 -318
  346. package/dist/datetime/index.cjs.map +0 -1
  347. package/dist/datetime/index.d.cts +0 -145
  348. package/dist/email/index.cjs +0 -10874
  349. package/dist/email/index.cjs.map +0 -1
  350. package/dist/email/index.d.cts +0 -186
  351. package/dist/fake/index.cjs +0 -34641
  352. package/dist/fake/index.cjs.map +0 -1
  353. package/dist/fake/index.d.cts +0 -74
  354. package/dist/file/index.cjs +0 -1212
  355. package/dist/file/index.cjs.map +0 -1
  356. package/dist/file/index.d.cts +0 -698
  357. package/dist/lock/index.cjs +0 -226
  358. package/dist/lock/index.cjs.map +0 -1
  359. package/dist/lock/index.d.cts +0 -361
  360. package/dist/lock-redis/index.cjs +0 -113
  361. package/dist/lock-redis/index.cjs.map +0 -1
  362. package/dist/lock-redis/index.d.cts +0 -24
  363. package/dist/logger/index.cjs +0 -521
  364. package/dist/logger/index.cjs.map +0 -1
  365. package/dist/logger/index.d.cts +0 -281
  366. package/dist/orm/index.cjs +0 -2986
  367. package/dist/orm/index.cjs.map +0 -1
  368. package/dist/orm/index.d.cts +0 -2213
  369. package/dist/queue/index.cjs +0 -1044
  370. package/dist/queue/index.cjs.map +0 -1
  371. package/dist/queue/index.d.cts +0 -1265
  372. package/dist/queue-redis/index.cjs +0 -873
  373. package/dist/queue-redis/index.cjs.map +0 -1
  374. package/dist/queue-redis/index.d.cts +0 -82
  375. package/dist/redis/index.cjs +0 -153
  376. package/dist/redis/index.cjs.map +0 -1
  377. package/dist/redis/index.d.cts +0 -82
  378. package/dist/retry/index.cjs +0 -146
  379. package/dist/retry/index.cjs.map +0 -1
  380. package/dist/retry/index.d.cts +0 -172
  381. package/dist/router/index.cjs +0 -111
  382. package/dist/router/index.cjs.map +0 -1
  383. package/dist/router/index.d.cts +0 -46
  384. package/dist/scheduler/index.cjs +0 -576
  385. package/dist/scheduler/index.cjs.map +0 -1
  386. package/dist/scheduler/index.d.cts +0 -145
  387. package/dist/security/index.cjs +0 -2402
  388. package/dist/security/index.cjs.map +0 -1
  389. package/dist/security/index.d.cts +0 -598
  390. package/dist/server/index.cjs +0 -1680
  391. package/dist/server/index.cjs.map +0 -1
  392. package/dist/server/index.d.cts +0 -810
  393. package/dist/server-auth/index.cjs +0 -3146
  394. package/dist/server-auth/index.cjs.map +0 -1
  395. package/dist/server-auth/index.d.cts +0 -1164
  396. package/dist/server-cache/index.cjs +0 -252
  397. package/dist/server-cache/index.cjs.map +0 -1
  398. package/dist/server-cache/index.d.cts +0 -164
  399. package/dist/server-compress/index.cjs +0 -141
  400. package/dist/server-compress/index.cjs.map +0 -1
  401. package/dist/server-compress/index.d.cts +0 -38
  402. package/dist/server-cookies/index.cjs +0 -234
  403. package/dist/server-cookies/index.cjs.map +0 -1
  404. package/dist/server-cookies/index.d.cts +0 -144
  405. package/dist/server-cors/index.cjs +0 -201
  406. package/dist/server-cors/index.cjs.map +0 -1
  407. package/dist/server-cors/index.d.cts +0 -140
  408. package/dist/server-health/index.cjs +0 -62
  409. package/dist/server-health/index.cjs.map +0 -1
  410. package/dist/server-health/index.d.cts +0 -58
  411. package/dist/server-helmet/index.cjs +0 -131
  412. package/dist/server-helmet/index.cjs.map +0 -1
  413. package/dist/server-helmet/index.d.cts +0 -97
  414. package/dist/server-links/index.cjs +0 -992
  415. package/dist/server-links/index.cjs.map +0 -1
  416. package/dist/server-links/index.d.cts +0 -513
  417. package/dist/server-metrics/index.cjs +0 -4535
  418. package/dist/server-metrics/index.cjs.map +0 -1
  419. package/dist/server-metrics/index.d.cts +0 -35
  420. package/dist/server-multipart/index.cjs +0 -237
  421. package/dist/server-multipart/index.cjs.map +0 -1
  422. package/dist/server-multipart/index.d.cts +0 -50
  423. package/dist/server-proxy/index.cjs +0 -186
  424. package/dist/server-proxy/index.cjs.map +0 -1
  425. package/dist/server-proxy/index.d.cts +0 -234
  426. package/dist/server-rate-limit/index.cjs +0 -241
  427. package/dist/server-rate-limit/index.cjs.map +0 -1
  428. package/dist/server-rate-limit/index.d.cts +0 -183
  429. package/dist/server-security/index.cjs +0 -316
  430. package/dist/server-security/index.cjs.map +0 -1
  431. package/dist/server-security/index.d.cts +0 -173
  432. package/dist/server-static/index.cjs +0 -170
  433. package/dist/server-static/index.cjs.map +0 -1
  434. package/dist/server-static/index.d.cts +0 -121
  435. package/dist/server-swagger/index.cjs +0 -1021
  436. package/dist/server-swagger/index.cjs.map +0 -1
  437. package/dist/server-swagger/index.d.cts +0 -382
  438. package/dist/sms/index.cjs +0 -221
  439. package/dist/sms/index.cjs.map +0 -1
  440. package/dist/sms/index.d.cts +0 -130
  441. package/dist/thread/index.cjs +0 -350
  442. package/dist/thread/index.cjs.map +0 -1
  443. package/dist/thread/index.d.cts +0 -260
  444. package/dist/topic/index.cjs +0 -282
  445. package/dist/topic/index.cjs.map +0 -1
  446. package/dist/topic/index.d.cts +0 -523
  447. package/dist/topic-redis/index.cjs +0 -71
  448. package/dist/topic-redis/index.cjs.map +0 -1
  449. package/dist/topic-redis/index.d.cts +0 -42
  450. package/dist/vite/index.cjs +0 -1077
  451. package/dist/vite/index.cjs.map +0 -1
  452. package/dist/vite/index.d.cts +0 -542
  453. package/dist/websocket/index.cjs +0 -1117
  454. package/dist/websocket/index.cjs.map +0 -1
  455. package/dist/websocket/index.d.cts +0 -861
  456. package/src/api-notifications/providers/MemorySmsProvider.ts +0 -20
  457. package/src/api-notifications/providers/SmsProvider.ts +0 -8
  458. /package/src/core/{descriptors → primitives}/$atom.ts +0 -0
  459. /package/src/core/{descriptors → primitives}/$env.ts +0 -0
  460. /package/src/server-auth/{descriptors → primitives}/$authApple.ts +0 -0
  461. /package/src/server-links/{descriptors → primitives}/$client.ts +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","names":["properties: Record<string, any>","AlephaError","json: Record<string, unknown>","errorNameByStatus: Record<number, string>","os: UserAgentInfo[\"os\"]","browser: UserAgentInfo[\"browser\"]","device: UserAgentInfo[\"device\"]","Alepha","Alepha","RouterProvider","Alepha","NodeWebStream","NodeStream","t","query: Record<string, any>","Alepha","DateTimeProvider","request: ServerRequestData","Readable","headers: Record<string, string>","t","Alepha","request: RequestInit","headers: Record<string, string>","fetchResponse: FetchResponse","options","envSchema","t","Descriptor","serverActionRequest: Partial<ServerRequest>","response: any","KIND","Descriptor","KIND","envSchema","t","Alepha","DateTimeProvider","envSchema","t","Alepha","DateTimeProvider","t","Alepha","stream: ReadableStream | undefined","WebStream","result: Record<string, string>","chunks: Uint8Array[]","Alepha","data: Record<string, string>","Alepha","t","alepha"],"sources":["../../src/server/helpers/isMultipart.ts","../../src/server/helpers/ServerReply.ts","../../src/server/errors/HttpError.ts","../../src/server/errors/ValidationError.ts","../../src/server/services/UserAgentParser.ts","../../src/server/services/ServerRequestParser.ts","../../src/server/providers/ServerTimingProvider.ts","../../src/server/providers/ServerRouterProvider.ts","../../src/server/providers/ServerProvider.ts","../../src/server/schemas/errorSchema.ts","../../src/server/services/HttpClient.ts","../../src/server/descriptors/$action.ts","../../src/server/descriptors/$route.ts","../../src/server/providers/BunHttpServerProvider.ts","../../src/server/providers/NodeHttpServerProvider.ts","../../src/server/providers/ServerBodyParserProvider.ts","../../src/server/providers/ServerLoggerProvider.ts","../../src/server/providers/ServerNotReadyProvider.ts","../../src/server/constants/routeMethods.ts","../../src/server/errors/BadRequestError.ts","../../src/server/errors/ConflictError.ts","../../src/server/errors/ForbiddenError.ts","../../src/server/errors/NotFoundError.ts","../../src/server/errors/UnauthorizedError.ts","../../src/server/schemas/okSchema.ts","../../src/server/index.ts"],"sourcesContent":["import type { RequestConfigSchema } from \"../interfaces/ServerRequest.ts\";\n\n/**\n * Checks if the route has multipart/form-data request body.\n */\nexport const isMultipart = (options: {\n schema?: RequestConfigSchema;\n requestBodyType?: string;\n}): boolean => {\n if (options.requestBodyType === \"multipart/form-data\") {\n return true;\n }\n\n if (options.schema?.body && \"properties\" in options.schema.body) {\n const properties: Record<string, any> = options.schema.body.properties;\n for (const key in properties) {\n if (properties[key].format === \"binary\") {\n return true;\n }\n }\n }\n\n return false;\n};\n","/**\n * Helper for building server replies.\n */\nexport class ServerReply {\n // TODO: make it private\n public headers: Record<string, string> & {\n \"set-cookie\"?: string[];\n } = {};\n\n public status?: number; // default 200, or 204 (no content)\n\n public body?: any;\n\n /**\n * Redirect to a given URL with optional status code (default 302).\n */\n public redirect(url: string, status: number = 302): void {\n this.status = status;\n this.headers.location = url;\n }\n\n // TODO: check if status / header is already set and throw an error if so (for allow to override with force flag)\n\n /**\n * Set the response status code.\n */\n public setStatus(status: number): this {\n this.status = status;\n return this;\n }\n\n /**\n * Set a response header.\n */\n public setHeader(name: string, value: string): this {\n this.headers[name.toLowerCase()] = value;\n return this;\n }\n\n /**\n * Set the response body.\n */\n public setBody(body: any): this {\n this.body = body;\n return this;\n }\n}\n","import { AlephaError } from \"alepha\";\nimport type { ErrorSchema } from \"../schemas/errorSchema.ts\";\n\nexport const isHttpError = (\n error: unknown,\n status?: number,\n): error is HttpErrorLike => {\n const isError =\n !!error &&\n typeof error === \"object\" &&\n \"message\" in error &&\n typeof error.message === \"string\" &&\n \"status\" in error &&\n typeof error.status === \"number\";\n\n if (!isError) {\n return false;\n }\n\n if (status) {\n return (error as HttpErrorLike).status === status;\n }\n\n return true;\n};\n\nexport class HttpError extends AlephaError {\n public name = \"HttpError\";\n\n static is = isHttpError;\n\n static toJSON(error: HttpError): ErrorSchema {\n const json: Record<string, unknown> = {\n error: error.error,\n status: error.status,\n message: error.message,\n };\n\n if (error.details) json.details = error.details;\n if (error.requestId) json.requestId = error.requestId;\n if (error.reason) json.cause = error.reason;\n\n return json as ErrorSchema;\n }\n\n public readonly error: string;\n public readonly status: number;\n\n public readonly requestId?: string;\n public readonly details?: string;\n public readonly reason?: {\n name: string;\n message: string;\n };\n\n constructor(options: Partial<ErrorSchema>, cause?: unknown) {\n super(options.message, {\n cause,\n });\n\n this.status = options.status ?? 500;\n this.details = options.details;\n this.requestId = options.requestId;\n\n if (typeof options.cause === \"object\") {\n this.reason = {\n name: (options.cause as { name: string }).name,\n message: (options.cause as { message: string }).message,\n };\n } else if (cause instanceof Error) {\n this.reason = {\n name: cause.name,\n message: cause.message,\n };\n }\n\n if (this.constructor.name === \"HttpError\") {\n this.error =\n options.error ?? errorNameByStatus[this.status] ?? \"HttpError\";\n } else {\n this.error = this.constructor.name;\n }\n }\n}\n\nexport const errorNameByStatus: Record<number, string> = {\n 400: \"BadRequestError\",\n 401: \"UnauthorizedError\",\n 403: \"ForbiddenError\",\n 404: \"NotFoundError\",\n 405: \"MethodNotAllowedError\",\n 409: \"ConflictError\",\n 410: \"GoneError\",\n 413: \"PayloadTooLargeError\",\n 415: \"UnsupportedMediaTypeError\",\n 429: \"TooManyRequestsError\",\n 500: \"InternalServerError\",\n 501: \"NotImplementedError\",\n 502: \"BadGatewayError\",\n 503: \"ServiceUnavailableError\",\n 504: \"GatewayTimeoutError\",\n};\n\nexport interface HttpErrorLike extends Error {\n status: number;\n}\n","import { HttpError } from \"./HttpError.ts\";\n\nexport class ValidationError extends HttpError {\n constructor(message = \"Validation has failed\", cause?: unknown) {\n super(\n {\n message,\n status: 400,\n },\n cause,\n );\n }\n}\n","export interface UserAgentInfo {\n os:\n | \"Windows\"\n | \"Android\"\n | \"Ubuntu\"\n | \"MacOS\"\n | \"iOS\"\n | \"Linux\"\n | \"FreeBSD\"\n | \"OpenBSD\"\n | \"ChromeOS\"\n | \"BlackBerry\"\n | \"Symbian\"\n | \"Windows Phone\";\n browser:\n | \"Chrome\"\n | \"Firefox\"\n | \"Safari\"\n | \"Edge\"\n | \"Opera\"\n | \"Internet Explorer\"\n | \"Brave\"\n | \"Vivaldi\"\n | \"Samsung Browser\"\n | \"UC Browser\"\n | \"Yandex\";\n device: \"MOBILE\" | \"DESKTOP\" | \"TABLET\";\n}\n\n/**\n * Simple User-Agent parser to detect OS, browser, and device type.\n * This parser is not exhaustive and may not cover all edge cases.\n *\n * Use result for non\n */\nexport class UserAgentParser {\n public parse(userAgent: string = \"\"): UserAgentInfo {\n const ua = userAgent.toLowerCase();\n\n // Default values\n let os: UserAgentInfo[\"os\"] = \"Windows\";\n let browser: UserAgentInfo[\"browser\"] = \"Chrome\";\n let device: UserAgentInfo[\"device\"] = \"DESKTOP\";\n\n // Detect OS - Order matters for specificity\n if (ua.includes(\"windows phone\")) {\n os = \"Windows Phone\";\n } else if (ua.includes(\"windows\")) {\n os = \"Windows\";\n } else if (ua.includes(\"android\")) {\n os = \"Android\";\n } else if (\n ua.includes(\"iphone\") ||\n ua.includes(\"ipad\") ||\n ua.includes(\"ipod\") ||\n (ua.includes(\"ios\") && !ua.includes(\"android\"))\n ) {\n os = \"iOS\";\n } else if (\n ua.includes(\"mac os\") ||\n ua.includes(\"macos\") ||\n ua.includes(\"macintosh\")\n ) {\n os = \"MacOS\";\n } else if (ua.includes(\"cros\") || ua.includes(\"chromeos\")) {\n os = \"ChromeOS\";\n } else if (ua.includes(\"ubuntu\")) {\n os = \"Ubuntu\";\n } else if (ua.includes(\"freebsd\")) {\n os = \"FreeBSD\";\n } else if (ua.includes(\"openbsd\")) {\n os = \"OpenBSD\";\n } else if (ua.includes(\"blackberry\") || ua.includes(\"bb10\")) {\n os = \"BlackBerry\";\n } else if (ua.includes(\"symbian\") || ua.includes(\"symbos\")) {\n os = \"Symbian\";\n } else if (ua.includes(\"linux\") || ua.includes(\"x11\")) {\n os = \"Linux\";\n }\n\n // Detect Browser/browser - Order matters, check most specific first\n if (ua.includes(\"yabrowser\") || ua.includes(\"yandex\")) {\n browser = \"Yandex\";\n } else if (ua.includes(\"brave\")) {\n browser = \"Brave\";\n } else if (ua.includes(\"vivaldi\")) {\n browser = \"Vivaldi\";\n } else if (ua.includes(\"samsungbrowser\") || ua.includes(\"samsung\")) {\n browser = \"Samsung Browser\";\n } else if (ua.includes(\"ucbrowser\") || ua.includes(\"uc browser\")) {\n browser = \"UC Browser\";\n } else if (\n ua.includes(\"opera\") ||\n ua.includes(\"opr/\") ||\n ua.includes(\"opios\")\n ) {\n browser = \"Opera\";\n } else if (\n ua.includes(\"edg/\") ||\n ua.includes(\"edge\") ||\n ua.includes(\"edgios\")\n ) {\n browser = \"Edge\";\n } else if (ua.includes(\"firefox\") && !ua.includes(\"seamonkey\")) {\n browser = \"Firefox\";\n } else if (ua.includes(\"trident\") || ua.includes(\"msie\")) {\n browser = \"Internet Explorer\";\n } else if (\n ua.includes(\"safari\") &&\n !ua.includes(\"chrome\") &&\n !ua.includes(\"chromium\")\n ) {\n browser = \"Safari\";\n } else if (\n ua.includes(\"chrome\") ||\n ua.includes(\"chromium\") ||\n ua.includes(\"crios\")\n ) {\n browser = \"Chrome\";\n }\n\n // Detect Device Type\n const mobileKeywords = [\n \"mobile\",\n \"android\",\n \"iphone\",\n \"ipod\",\n \"blackberry\",\n \"windows phone\",\n \"opera mini\",\n \"iemobile\",\n \"mobile safari\",\n \"nokia\",\n \"symbian\",\n ];\n\n const tabletKeywords = [\n \"ipad\",\n \"tablet\",\n \"kindle\",\n \"silk\",\n \"gt-p\",\n \"sm-t\",\n \"nexus 7\",\n \"nexus 10\",\n ];\n\n const isTablet = tabletKeywords.some((keyword) => ua.includes(keyword));\n const isMobile = mobileKeywords.some((keyword) => ua.includes(keyword));\n\n if (isTablet) {\n device = \"TABLET\";\n } else if (isMobile) {\n device = \"MOBILE\";\n } else {\n device = \"DESKTOP\";\n }\n\n return { os, browser, device };\n }\n}\n","import { $inject, Alepha } from \"alepha\";\nimport { ServerReply } from \"../helpers/ServerReply.ts\";\nimport type {\n ServerRequest,\n ServerRequestData,\n} from \"../interfaces/ServerRequest.ts\";\nimport { UserAgentParser } from \"./UserAgentParser.ts\";\n\nexport class ServerRequestParser {\n protected readonly alepha = $inject(Alepha);\n protected readonly userAgentParser = $inject(UserAgentParser);\n\n public createServerRequest(rawRequest: ServerRequestData): ServerRequest {\n const self = this;\n return {\n method: rawRequest.method,\n url: rawRequest.url,\n raw: rawRequest.raw,\n headers: rawRequest.headers,\n query: rawRequest.query,\n params: rawRequest.params,\n // body will be filled by body parser middleware\n body: null,\n metadata: {},\n requestId: this.getRequestId(rawRequest) || crypto.randomUUID(),\n reply: this.alepha.inject(ServerReply, { lifetime: \"transient\" }),\n get ip() {\n return self.getRequestIp(rawRequest);\n },\n get userAgent() {\n return self.getRequestUserAgent(rawRequest);\n },\n } as ServerRequest;\n }\n\n public getRequestId(request: ServerRequestData): string | undefined {\n return request.headers[\"x-request-id\"];\n }\n\n public getRequestUserAgent(request: ServerRequestData) {\n return this.userAgentParser.parse(request.headers[\"user-agent\"]);\n }\n\n public getRequestIp(request: ServerRequestData): string | undefined {\n // check for the 'x-forwarded-for' header first, which is commonly used\n // in proxy setups to forward the original client's IP address.\n\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For\n\n const forwardedFor = request.headers[\"x-forwarded-for\"];\n if (forwardedFor) {\n // The 'x-forwarded-for' header can contain multiple IPs, so we take the first one.\n return Array.isArray(forwardedFor)\n ? forwardedFor[0]\n : forwardedFor.split(\",\")[0].trim();\n }\n\n const xRealIP = request.headers[\"x-real-ip\"];\n if (xRealIP) {\n return Array.isArray(xRealIP) ? xRealIP[0] : xRealIP;\n }\n }\n}\n","import { $hook, $inject, Alepha } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type { ServerRequest } from \"../interfaces/ServerRequest.ts\";\n\ntype TimingMap = Record<string, [number, number]>;\n\nexport class ServerTimingProvider {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n\n public options = {\n prefix: this.alepha.env.APP_NAME\n ? `${this.alepha.env.APP_NAME.toLowerCase()}-`\n : \"\",\n disabled: this.alepha.isProduction(),\n };\n\n public readonly onRequest = $hook({\n priority: \"first\",\n on: \"server:onRequest\",\n handler: async ({ request }) => {\n if (this.options.disabled) {\n return;\n }\n\n request.metadata.timing = {};\n request.metadata.timing[this.handlerName] = [Date.now()];\n },\n });\n\n public readonly onResponse = $hook({\n priority: \"last\",\n on: \"server:onResponse\",\n handler: async ({ request }) => {\n if (this.options.disabled) {\n return;\n }\n\n if (request.metadata.timing) {\n this.setDuration(this.handlerName, request.metadata.timing);\n\n let timingHeader = \"\";\n\n for (const [name, [start, duration]] of Object.entries(\n request.metadata.timing as TimingMap,\n )) {\n if (typeof start !== \"number\" || typeof duration !== \"number\") {\n this.log.warn(\n `Invalid timing for '${name}': [${start}, ${duration}]`,\n );\n continue;\n }\n\n const formattedName =\n this.options.prefix + name.replace(/[^a-zA-Z0-9-]/g, \"-\");\n timingHeader += `${formattedName};dur=${duration}, `;\n }\n\n if (request.reply.headers[\"Server-Timing\"]) {\n request.reply.headers[\"Server-Timing\"] += `, ${timingHeader}`;\n } else {\n request.reply.headers[\"Server-Timing\"] = timingHeader;\n }\n }\n },\n });\n\n protected get handlerName() {\n return `request`;\n }\n\n public beginTiming(name: string): void {\n if (this.options.disabled) {\n return;\n }\n\n const request = this.alepha.context.get<ServerRequest>(\"request\");\n if (!request) {\n return;\n }\n\n request.metadata ??= {};\n request.metadata.timing ??= {};\n request.metadata.timing[name] = [Date.now()];\n }\n\n public endTiming(name: string): void {\n if (this.options.disabled) {\n return;\n }\n\n const request = this.alepha.context.get<ServerRequest>(\"request\");\n if (!request) {\n return;\n }\n\n if (!request.metadata?.timing || !(name in request.metadata.timing)) {\n this.log.warn(`No timing found for '${name}'.`);\n return;\n }\n\n const start = request.metadata.timing[name]?.[0];\n if (typeof start !== \"number\") {\n this.log.warn(`Invalid timing start for '${name}': ${start}`);\n return;\n }\n\n this.setDuration(name, request.metadata.timing);\n }\n\n protected setDuration(name: string, timing: TimingMap): void {\n timing[name] = [timing[name][0], Date.now() - timing[name][0]];\n }\n}\n","import { Readable as NodeStream } from \"node:stream\";\nimport { ReadableStream as NodeWebStream } from \"node:stream/web\";\nimport { $inject, Alepha, isFileLike, isTypeFile, isUUID, t } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { RouterProvider } from \"alepha/router\";\nimport type { RouteMethod } from \"../constants/routeMethods.ts\";\nimport { errorNameByStatus, HttpError } from \"../errors/HttpError.ts\";\nimport { ValidationError } from \"../errors/ValidationError.ts\";\nimport type { ServerReply } from \"../helpers/ServerReply.ts\";\nimport type {\n RequestConfigSchema,\n ResponseKind,\n ServerRequest,\n ServerRequestConfig,\n ServerRoute,\n ServerRouteMatcher,\n} from \"../interfaces/ServerRequest.ts\";\nimport { ServerRequestParser } from \"../services/ServerRequestParser.ts\";\nimport { ServerTimingProvider } from \"./ServerTimingProvider.ts\";\n\n/**\n * Main router for all routes on the server side.\n *\n * - $route => generic route\n * - $action => action route (for API calls)\n * - $page => React route (for SSR)\n */\nexport class ServerRouterProvider extends RouterProvider<ServerRouteMatcher> {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly routes: ServerRoute[] = [];\n protected readonly serverTimingProvider = $inject(ServerTimingProvider);\n protected readonly serverRequestParser = $inject(ServerRequestParser);\n\n /**\n * Get all registered routes, optionally filtered by a pattern.\n *\n * Pattern accept simple wildcard '*' at the end.\n * Example: '/api/*' will match all routes starting with '/api/' but '/api/' will match only that exact route.\n */\n public getRoutes(pattern?: string): ServerRoute[] {\n if (pattern) {\n if (pattern.endsWith(\"*\")) {\n const basePattern = pattern.slice(0, -1);\n return this.routes.filter((route) =>\n route.path.startsWith(basePattern),\n );\n } else {\n return this.routes.filter((route) => route.path === pattern);\n }\n }\n return this.routes;\n }\n\n public createRoute<TConfig extends RequestConfigSchema = RequestConfigSchema>(\n route: ServerRoute<TConfig>,\n ): void {\n route.method ??= \"GET\";\n route.method = route.method.toUpperCase() as RouteMethod;\n\n this.routes.push(route);\n\n const path = `/${route.method}/${route.path}`.replace(/\\/+/g, \"/\");\n const responseKind = this.getResponseType(route.schema);\n\n this.log.trace(`Create route ${path}`);\n\n this.push({\n path,\n handler: (rawRequest) => {\n const request =\n this.serverRequestParser.createServerRequest(rawRequest);\n\n return this.alepha.context.run(\n () => this.processRequest(request, route, responseKind),\n {\n context: this.getContextId(rawRequest.headers),\n },\n );\n },\n });\n }\n\n protected getContextId(headers: Record<string, string>): string {\n const contextId = headers[\"x-request-id\"] || headers[\"x-correlation-id\"];\n // TODO: check if it's not overkill, just checking length might be enough?\n // some cloud providers generate non-UUID request ids\n if (isUUID(contextId)) {\n return contextId;\n }\n\n return crypto.randomUUID();\n }\n\n protected async processRequest(\n request: ServerRequest,\n route: ServerRoute,\n responseKind: ResponseKind,\n ) {\n await this.runRouteHandler(route, request, responseKind).catch((error) => {\n return this.errorHandler(route, request, error as Error);\n });\n\n await this.alepha.events.emit(\n \"server:onSend\",\n {\n request,\n route,\n },\n {\n catch: true, // avoid unhandled rejection\n },\n );\n\n // create response\n const response = {\n status: request.reply.status ?? (request.reply.body ? 200 : 204),\n headers: request.reply.headers,\n body: request.reply.body as any,\n };\n\n await this.alepha.events.emit(\n \"server:onResponse\",\n {\n request,\n route,\n response,\n },\n {\n catch: true, // avoid unhandled rejection\n },\n );\n\n return response;\n }\n\n protected async runRouteHandler(\n route: ServerRoute,\n request: ServerRequest,\n responseKind: ResponseKind,\n ) {\n // there are some built-in hooks that are called before the request is handled\n // - ServerBodyParserProvider (parse body)\n // - ServerSecurityProvider (build user from headers)\n // - ServerLoggerProvider (log request)\n\n await this.alepha.events.emit(\n \"server:onRequest\", // this hook will fill request.user and request.cookies\n {\n request,\n route,\n },\n {\n log: false,\n },\n );\n\n if (\n request.reply.body ||\n (request.reply.status && request.reply.status >= 200)\n ) {\n // if the body is already set, we can skip the handler\n // this is useful for middlewares that set the body\n return;\n }\n\n // request is ready to be used -> inject to context\n this.alepha.context.set<ServerRequest>(\"request\", request as ServerRequest);\n\n // validate request\n this.serverTimingProvider.beginTiming(\"validateRequest\");\n try {\n this.validateRequest(route, request);\n } finally {\n this.serverTimingProvider.endTiming(\"validateRequest\");\n }\n\n // call the handler only if the body is not set yet\n this.serverTimingProvider.beginTiming(\"runHandler\");\n try {\n const result = await route.handler(request);\n if (result) {\n request.reply.body = result;\n }\n } finally {\n this.serverTimingProvider.endTiming(\"runHandler\");\n }\n\n // serialize response\n this.serverTimingProvider.beginTiming(\"serializeResponse\");\n try {\n this.serializeResponse(route, request.reply, responseKind);\n } finally {\n this.serverTimingProvider.endTiming(\"serializeResponse\");\n }\n }\n\n public serializeResponse(\n route: ServerRoute,\n reply: ServerReply,\n responseKind: ResponseKind,\n ): void {\n if (responseKind === \"json\" && route.schema?.response) {\n reply.headers[\"content-type\"] = \"application/json\";\n reply.body = this.alepha.codec.encode(route.schema.response, reply.body, {\n as: \"string\",\n });\n return;\n }\n\n if (responseKind === \"file\") {\n if (!isFileLike(reply.body)) {\n throw new HttpError({\n status: 500,\n message: \"Invalid response body - not a file\",\n });\n }\n reply.headers[\"content-type\"] = reply.body.type;\n reply.headers[\"content-disposition\"] =\n `attachment; filename=\"${reply.body.name.replaceAll('\"', \"\")}\"`;\n reply.body = reply.body.stream();\n return;\n }\n\n if (responseKind === \"text\") {\n reply.body = String(reply.body);\n if (reply.body.startsWith(\"<!DOCTYPE html>\")) {\n reply.headers[\"content-type\"] ??= \"text/html; charset=UTF-8\";\n } else {\n reply.headers[\"content-type\"] ??= \"text/plain\";\n }\n return;\n }\n\n if (reply.body == null || responseKind === \"void\") {\n delete reply.headers[\"content-type\"];\n reply.body = undefined;\n return;\n }\n\n if (Buffer.isBuffer(reply.body)) {\n reply.headers[\"content-type\"] ??= \"application/octet-stream\";\n return;\n }\n\n if (\n reply.body instanceof NodeWebStream ||\n reply.body instanceof NodeStream\n ) {\n // set content-type to application/octet-stream if not set\n reply.headers[\"content-type\"] ??= \"application/octet-stream\";\n return;\n }\n\n reply.headers[\"content-type\"] ??= \"text/plain\";\n reply.body = String(reply.body);\n return;\n }\n\n protected getResponseType(schema?: RequestConfigSchema): ResponseKind {\n if (schema?.response) {\n if (\n t.schema.isObject(schema.response) ||\n t.schema.isRecord(schema.response) ||\n t.schema.isArray(schema.response)\n ) {\n return \"json\";\n }\n\n if (\n t.schema.isString(schema.response) ||\n t.schema.isInteger(schema.response) ||\n t.schema.isNumber(schema.response) ||\n t.schema.isBoolean(schema.response)\n ) {\n return \"text\";\n }\n\n if (isTypeFile(schema.response)) {\n return \"file\";\n }\n\n if (t.schema.isVoid(schema.response)) {\n return \"void\";\n }\n }\n\n return \"any\";\n }\n\n protected async errorHandler(\n route: ServerRoute,\n request: ServerRequest,\n error: Error,\n ) {\n // reset body, which is probably invalid,\n // it can be filled by server:onError hook or by the default handler below\n request.reply.body = null;\n\n await this.alepha.events.emit(\n \"server:onError\",\n {\n request,\n route,\n error,\n },\n {\n log: false,\n },\n );\n\n if (!request.reply.body && !request.reply.status) {\n if (error instanceof HttpError) {\n request.reply.status = error.status;\n request.reply.headers[\"content-type\"] = \"application/json\";\n request.reply.body = JSON.stringify({\n ...HttpError.toJSON(error),\n requestId: request.requestId,\n });\n } else {\n if (\n \"status\" in error &&\n typeof error.status === \"number\" &&\n !!errorNameByStatus[error.status]\n ) {\n request.reply.status = error.status;\n request.reply.headers[\"content-type\"] = \"application/json\";\n request.reply.body = JSON.stringify({\n status: error.status,\n error: errorNameByStatus[error.status],\n message: (error as Error).message,\n requestId: request.requestId,\n });\n return;\n }\n\n request.reply.status = 500;\n request.reply.headers[\"content-type\"] = \"application/json\";\n request.reply.body = JSON.stringify({\n status: 500,\n error: \"InternalServerError\",\n message: (error as Error).message,\n requestId: request.requestId,\n });\n }\n }\n }\n\n public validateRequest(\n route: { schema?: RequestConfigSchema },\n request: ServerRequestConfig,\n ) {\n if (route.schema?.params) {\n try {\n request.params = this.alepha.codec.validate(\n route.schema.params,\n request.params,\n ) as any;\n } catch (error) {\n throw new ValidationError(\"Invalid request params\", error);\n }\n }\n\n if (route.schema?.query) {\n try {\n // we parse one by one to use the TypeBox coercion (e.g., number from string)\n const query: Record<string, any> = {};\n for (const key in route.schema.query.properties) {\n if (request.query[key] != null) {\n query[key] = this.alepha.codec.decode(\n route.schema.query.properties[key],\n request.query[key],\n );\n }\n }\n request.query = query;\n } catch (error) {\n throw new ValidationError(\"Invalid request query\", error);\n }\n }\n\n if (route.schema?.headers) {\n try {\n request.headers = this.alepha.codec.validate(\n route.schema.headers,\n request.headers,\n ) as any;\n } catch (error) {\n throw new ValidationError(\"Invalid request header\", error);\n }\n }\n\n if (route.schema?.body) {\n try {\n request.body = this.alepha.codec.decode(\n route.schema.body,\n request.body,\n );\n } catch (error) {\n throw new ValidationError(\"Invalid request body\", error);\n }\n }\n }\n}\n","import { Readable } from \"node:stream\";\nimport { $hook, $inject, Alepha } from \"alepha\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport type { Route } from \"alepha/router\";\nimport type { RouteMethod } from \"../constants/routeMethods.ts\";\nimport type {\n NodeRequestEvent,\n ServerRequestData,\n WebRequestEvent,\n} from \"../interfaces/ServerRequest.ts\";\nimport { ServerRouterProvider } from \"./ServerRouterProvider.ts\";\n\n/**\n * Base server provider to handle incoming requests and route them.\n *\n * This is the default implementation for serverless environments.\n *\n * ServerProvider supports both Node.js HTTP requests and Web (Fetch API) requests.\n */\nexport class ServerProvider {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n protected readonly router = $inject(ServerRouterProvider);\n\n protected readonly internalServerErrorMessage = \"Internal Server Error\";\n\n public get hostname(): string {\n return \"\"; // no hostname in serverless mode\n }\n\n /**\n * When a Node.js HTTP request is received from outside. (Vercel, AWS Lambda, etc.)\n */\n protected readonly onNodeRequest = $hook({\n on: \"node:request\",\n handler: (ev) => this.handleNodeRequest(ev),\n });\n\n /**\n * When a Web (Fetch API) request is received from outside. (Netlify, Cloudflare Workers, etc.)\n */\n protected readonly onWebRequest = $hook({\n on: \"web:request\",\n handler: (ev) => {\n return this.handleWebRequest(ev);\n },\n });\n\n /**\n * Handle Node.js HTTP request event.\n *\n * Technically, we just convert Node.js request to Web Standard Request.\n */\n public async handleNodeRequest(\n nodeRequestEvent: NodeRequestEvent,\n ): Promise<void> {\n const { req, res } = nodeRequestEvent;\n const { route, params } = this.router.match(`/${req.method}${req.url}`);\n\n if (this.isViteNotFound(req.url, route, params)) {\n return;\n }\n\n if (!route) {\n // if no route is found, return basic 404\n // note: you should not use this in production, use a custom 404 page instead by adding a route /*\n res.writeHead(404, { \"content-type\": \"text/plain\" });\n res.end(\"Not Found\");\n return;\n }\n\n const headers = (req.headers ?? {}) as Record<string, string>;\n const proto = headers[\"x-forwarded-proto\"] === \"https\" ? \"https\" : \"http\";\n const url = new URL(`${proto}://${headers.host}${req.url}`);\n const query = Object.fromEntries(url.searchParams.entries());\n const method = (req.method?.toUpperCase() ?? \"GET\") as RouteMethod;\n\n const request: ServerRequestData = {\n method,\n url,\n headers,\n params: params ?? {},\n query,\n raw: { node: nodeRequestEvent },\n };\n\n const response = await route.handler(request).catch(() => {\n return {\n status: 500,\n headers: { \"content-type\": \"text/plain\" },\n body: this.internalServerErrorMessage,\n };\n });\n\n // empty body - just send status & headers\n if (!response.body) {\n res.writeHead(response.status, response.headers).end();\n return;\n }\n\n // if response.body is string or buffer\n if (typeof response.body === \"string\" || Buffer.isBuffer(response.body)) {\n res.writeHead(response.status, response.headers).end(response.body);\n return;\n }\n\n // if response.body is node stream\n if (response.body instanceof Readable) {\n res.writeHead(response.status, response.headers);\n response.body.pipe(res);\n return;\n }\n\n // if response.body is web stream\n if (response.body instanceof ReadableStream) {\n res.writeHead(response.status, response.headers);\n try {\n for await (const chunk of response.body) {\n res.write(chunk);\n }\n } catch (error) {\n this.log.error(\"Error piping proxy response stream\", error);\n } finally {\n res.end();\n }\n return;\n }\n\n // not supported response body type\n\n this.log.error(\"Unknown response body type:\", typeof response.body);\n res.writeHead(500, { \"content-type\": \"text/plain\" });\n res.end(this.internalServerErrorMessage);\n }\n\n /**\n * Handle Web (Fetch API) request event.\n */\n public async handleWebRequest(ev: WebRequestEvent): Promise<void> {\n const req = ev.req;\n const url = new URL(req.url);\n const { route, params } = this.router.match(\n `/${req.method}${url.pathname}`,\n );\n\n if (this.isViteNotFound(req.url, route, params)) {\n return;\n }\n\n if (!route) {\n // if no route is found, return basic 404\n // note: you should not use this in production, use a custom 404 page instead by adding a route /*\n ev.res = new Response(\"Not Found\", {\n status: 404,\n headers: { \"content-type\": \"text/plain\" },\n });\n return;\n }\n\n const headers: Record<string, string> = {};\n\n req.headers.forEach((value, key) => {\n headers[key] = value;\n });\n\n const query = Object.fromEntries(url.searchParams.entries());\n const method = (req.method.toUpperCase() ?? \"GET\") as RouteMethod;\n const request: ServerRequestData = {\n method,\n url,\n headers,\n params: params || {},\n query,\n raw: { web: ev },\n };\n\n const response = await route.handler(request).catch(() => {\n return {\n status: 500,\n headers: { \"content-type\": \"text/plain\" },\n body: this.internalServerErrorMessage,\n };\n });\n\n // empty body - just send status & headers\n if (!response.body) {\n ev.res = new Response(null, {\n status: response.status,\n headers: response.headers,\n });\n return;\n }\n\n // if response.body is string or buffer\n if (typeof response.body === \"string\") {\n ev.res = new Response(response.body, {\n status: response.status,\n headers: response.headers,\n });\n return;\n }\n\n if (Buffer.isBuffer(response.body)) {\n ev.res = new Response(response.body.buffer as ArrayBuffer, {\n status: response.status,\n headers: response.headers,\n });\n return;\n }\n\n // if response.body is node stream\n if (response.body instanceof Readable) {\n ev.res = new Response(Readable.toWeb(response.body) as ReadableStream, {\n status: response.status,\n headers: response.headers,\n });\n return;\n }\n\n // if response.body is web stream\n if (response.body instanceof ReadableStream) {\n ev.res = new Response(response.body, {\n status: response.status,\n headers: response.headers,\n });\n return;\n }\n\n // not supported response body type\n this.log.error(`Unknown response body type: ${typeof response.body}`);\n ev.res = new Response(this.internalServerErrorMessage, {\n status: 500,\n headers: { \"content-type\": \"text/plain\" },\n });\n }\n\n /**\n * Helper for Vite development mode to let Vite handle (or not) 404.\n */\n protected isViteNotFound(\n url?: string,\n route?: Route,\n params?: Record<string, string>,\n ): boolean {\n if (this.alepha.isViteDev()) {\n if (!route) {\n return true;\n }\n\n url = url?.split(\"?\")[0];\n\n if (!!params?.[\"*\"] && `/${params?.[\"*\"]}` === url) {\n return true;\n }\n }\n\n return false;\n }\n}\n","import { type Static, t } from \"alepha\";\n\nexport const errorSchema = t.object(\n {\n error: t.text({ description: \"HTTP error name\" }),\n status: t.integer({\n description: \"HTTP status code\",\n }),\n message: t.text({\n description: \"Short text which describe the error\",\n size: \"rich\",\n }),\n details: t.optional(\n t.text({\n description: \"Detailed description of the error\",\n size: \"rich\",\n }),\n ),\n requestId: t.optional(t.text()),\n cause: t.optional(\n t.object({\n name: t.text(),\n message: t.text({\n description: \"Cause Error message\",\n size: \"rich\",\n }),\n }),\n ),\n },\n {\n title: \"HttpError\",\n description: \"Generic response after a failed operation\",\n },\n);\n\nexport type ErrorSchema = Static<typeof errorSchema>;\n","import {\n $inject,\n Alepha,\n type FileLike,\n isFileLike,\n type Static,\n type TObject,\n type TSchema,\n} from \"alepha\";\nimport { $cache } from \"alepha/cache\";\nimport type { DurationLike } from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport type { ClientRequestOptions } from \"../descriptors/$action.ts\";\nimport { HttpError } from \"../errors/HttpError.ts\";\nimport { isMultipart } from \"../helpers/isMultipart.ts\";\nimport type {\n ServerRequestConfigEntry,\n TRequestBody,\n TResponseBody,\n} from \"../interfaces/ServerRequest.ts\";\nimport { errorSchema } from \"../schemas/errorSchema.ts\";\n\nexport class HttpClient {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n\n public readonly cache = $cache<HttpClientCache>();\n\n protected readonly pendingRequests: HttpClientPendingRequests = {};\n\n public async fetchAction(args: FetchActionArgs): Promise<FetchResponse> {\n const route = args.action; // our link to fetch\n const options = args.options ?? {}; // fetch standard options, cache, etc.\n const config = args.config ?? {}; // params, query, body, etc.\n const host = args.host ?? \"\"; // remote host, e.g. \"https://api.example.com\" or empty (for browser)\n\n const request: RequestInit = {\n ...options.request,\n };\n\n const method = route.method;\n const headers: Record<string, string> = {};\n const url = this.url(host, route, config);\n\n await this.alepha.events.emit(\"client:onRequest\", {\n route,\n config,\n options,\n headers,\n request,\n });\n\n request.method ??= method;\n\n await this.body(request, headers, route, config);\n\n request.headers = {\n ...config.headers,\n ...Object.fromEntries(new Headers(request.headers).entries()),\n ...headers,\n };\n\n return await this.fetch(url, {\n ...request,\n schema: route.schema,\n ...options,\n });\n }\n\n public async fetch<T extends TSchema>(\n url: string,\n request: RequestInitWithOptions<T> = {}, // standard options\n ): Promise<FetchResponse<Static<T>>> {\n const options = {\n cache: request.localCache,\n schema: request.schema?.response,\n key: request.key,\n };\n\n request.method ??= \"GET\";\n\n this.log.trace(\"Request\", {\n url,\n method: request.method,\n body: request.body,\n headers: request.headers,\n options,\n });\n\n // Only add automatic ETag if user didn't explicitly provide headers\n const cached = await this.cache.get(url);\n if (cached && request.method === \"GET\") {\n if (cached.etag) {\n request.headers = new Headers(request.headers);\n if (!request.headers.has(\"if-none-match\")) {\n request.headers.set(\"if-none-match\", cached.etag);\n }\n } else {\n return {\n data: cached.data as Static<T>,\n status: 200,\n statusText: \"OK\",\n headers: new Headers(),\n };\n }\n }\n\n await this.alepha.events.emit(\"client:beforeFetch\", {\n url,\n options,\n request,\n });\n\n // make a key for the request\n // this will be used to check if the request is already pending\n const key =\n options.key ??\n JSON.stringify({\n url,\n method: request.method,\n body: request.body,\n });\n\n const existing = this.pendingRequests[key];\n if (existing) {\n this.log.info(\"Request already pending\", key);\n return existing;\n }\n\n this.pendingRequests[key] = fetch(url, request)\n .then(async (response) => {\n this.log.debug(\"Response\", {\n url,\n status: response.status,\n });\n\n const fetchResponse: FetchResponse = {\n data: await this.responseData(response, options),\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n raw: response,\n };\n\n if (request.method === \"GET\") {\n if (options.cache) {\n await this.cache.set(\n url,\n { data: fetchResponse.data },\n typeof options.cache === \"boolean\" ? undefined : options.cache,\n );\n } else if (!this.alepha.isBrowser()) {\n // only cache etag on server, browser can handle etag itself\n const etag = response.headers.get(\"etag\") ?? undefined;\n if (etag) {\n await this.cache.set(url, { data: fetchResponse.data, etag });\n }\n }\n }\n\n return fetchResponse;\n })\n .finally(() => {\n delete this.pendingRequests[key];\n });\n\n return this.pendingRequests[key];\n }\n\n protected url(\n host: string,\n action: HttpAction,\n args: ServerRequestConfigEntry,\n ) {\n let url = host;\n\n if (action.prefix) {\n url += action.prefix;\n }\n\n url += action.path;\n url = this.pathVariables(url, action, args);\n url = this.queryParams(url, action, args);\n\n return url;\n }\n\n protected async body(\n init: RequestInit,\n headers: Record<string, string>,\n action: HttpAction,\n args: ServerRequestConfigEntry = {},\n ) {\n const hasHeader =\n typeof init.headers === \"object\" &&\n \"content-type\" in init.headers &&\n init.headers[\"content-type\"] === \"multipart/form-data\";\n\n if (hasHeader || isMultipart(action)) {\n if (typeof init.headers === \"object\" && \"content-type\" in init.headers) {\n delete init.headers[\"content-type\"]; // fetch() will fill this for us\n }\n\n const formData = new FormData();\n\n for (const [key, value] of Object.entries(args.body ?? {})) {\n if (typeof value === \"string\") {\n formData.append(key, value);\n continue;\n }\n if (value instanceof Blob) {\n formData.append(key, value);\n continue;\n }\n if (isFileLike(value)) {\n // FileLike must be transformed to WebFile\n formData.append(\n key,\n new File([await value.arrayBuffer()], value.name, {\n type: value.type,\n }),\n );\n }\n }\n\n init.body = formData;\n\n return;\n }\n\n if (!init.body && action.schema?.body) {\n headers[\"content-type\"] = \"application/json\";\n init.body = this.alepha.codec.encode(action.schema?.body, args.body, {\n as: \"string\",\n });\n }\n }\n\n protected async responseData(\n response: Response,\n options: FetchOptions,\n ): Promise<any> {\n if (response.status === 304) {\n let cacheKey = response.url;\n if (typeof window !== \"undefined\") {\n cacheKey = cacheKey.replace(window.location.origin, \"\");\n }\n\n const cached = await this.cache.get(cacheKey);\n if (cached) {\n return cached.data;\n }\n\n // if no cached data (etag-only routes), return empty string\n return \"\";\n }\n\n if (response.status === 204) {\n return;\n }\n\n if (this.isMaybeFile(response)) {\n return this.createFileLike(response);\n }\n\n if (response.headers.get(\"Content-Type\")?.startsWith(\"text/\")) {\n return await response.text();\n }\n\n if (response.headers.get(\"Content-Type\") === \"application/json\") {\n const json = await response.json();\n\n if (response.status >= 400) {\n const jsonError = this.alepha.codec.decode(errorSchema, json);\n const error = new HttpError(jsonError);\n\n await this.alepha.events.emit(\"client:onError\", {\n error,\n });\n\n throw error;\n }\n\n if (options.schema) {\n return this.alepha.codec.decode(options.schema, json);\n }\n\n return json;\n }\n\n if (response.status >= 400) {\n const error = new HttpError({\n status: response.status,\n message: `An error occurred while fetching the resource. (${response.statusText})`,\n });\n\n await this.alepha.events.emit(\"client:onError\", {\n error,\n });\n\n throw error;\n }\n\n return response;\n }\n\n protected isMaybeFile(response: Response): boolean {\n const contentType = response.headers.get(\"Content-Type\");\n if (!contentType) {\n return false;\n }\n\n if (response.headers.get(\"Content-Disposition\")?.includes(\"attachment\")) {\n return true; // If Content-Disposition indicates an attachment, treat it as a file\n }\n\n return (\n contentType.startsWith(\"application/octet-stream\") ||\n contentType.startsWith(\"application/pdf\") ||\n contentType.startsWith(\"application/zip\") ||\n contentType.startsWith(\"image/\") ||\n contentType.startsWith(\"video/\") ||\n contentType.startsWith(\"audio/\")\n );\n }\n\n protected createFileLike(response: Response, defaultFileName = \"\"): FileLike {\n const match = (response.headers.get(\"Content-Disposition\") ?? \"\").match(\n /filename=\"(.+)\"/,\n );\n return {\n name: match?.[1] ? match[1] : defaultFileName,\n type: response.headers.get(\"Content-Type\") ?? \"application/octet-stream\",\n size: Number(response.headers.get(\"Content-Length\") ?? 0),\n lastModified: Date.now(),\n stream: () => {\n throw new Error(\"Not implemented\");\n },\n arrayBuffer: async () => {\n return await response.arrayBuffer();\n },\n text: async () => {\n return await response.text();\n },\n };\n }\n\n public pathVariables(\n url: string,\n action: { schema?: { params?: TObject } },\n args: ServerRequestConfigEntry = {},\n ): string {\n if (typeof args.params === \"object\") {\n const params = action.schema?.params\n ? (this.alepha.codec.decode(\n action.schema.params,\n args.params,\n ) as Record<string, any>)\n : args.params;\n\n for (const key of Object.keys(params)) {\n url = url.replace(`:${key}`, params[key]);\n url = url.replace(`{${key}}`, params[key]);\n }\n }\n\n return url;\n }\n\n public queryParams(\n url: string,\n action: { schema?: { query?: TObject } },\n args: ServerRequestConfigEntry = {},\n ): string {\n if (typeof args.query === \"object\") {\n const query = action.schema?.query\n ? this.alepha.codec.decode(action.schema.query, args.query ?? {})\n : args.query;\n\n for (const key of Object.keys(query)) {\n if (query[key] === undefined) {\n delete query[key];\n }\n if (typeof query[key] === \"object\") {\n query[key] = JSON.stringify(query[key]);\n }\n }\n\n return `${url}?${new URLSearchParams(\n query as Record<string, string>,\n ).toString()}`;\n }\n return url;\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface FetchOptions<T extends TSchema = TSchema> {\n /**\n * Key to identify the request in the pending requests.\n */\n key?: string;\n\n /**\n * The schema to validate the response against.\n */\n schema?: {\n response?: T;\n };\n\n /**\n * Built-in cache options.\n */\n localCache?: boolean | number | DurationLike;\n}\n\nexport type RequestInitWithOptions<T extends TSchema = TSchema> = RequestInit &\n FetchOptions<T>;\n\nexport interface FetchResponse<T = any> {\n data: T;\n status: number;\n statusText: string;\n headers: Headers;\n raw?: Response;\n}\n\nexport type HttpClientPendingRequests = Record<\n string,\n Promise<any> | undefined\n>;\n\ninterface HttpClientCache {\n data: any;\n etag?: string;\n}\n\nexport interface FetchActionArgs {\n action: HttpAction;\n host?: string;\n config?: ServerRequestConfigEntry;\n options?: ClientRequestOptions;\n}\n\nexport interface HttpAction {\n method?: string;\n prefix?: string;\n path: string;\n requestBodyType?: string;\n schema?: {\n params?: TObject;\n query?: TObject;\n body?: TRequestBody;\n response?: TResponseBody;\n };\n}\n","import {\n $env,\n $inject,\n type Async,\n createDescriptor,\n Descriptor,\n isTypeFile,\n KIND,\n type Static,\n type TObject,\n type TSchema,\n t,\n} from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type { RouteMethod } from \"../constants/routeMethods.ts\";\nimport { isMultipart } from \"../helpers/isMultipart.ts\";\nimport { ServerReply } from \"../helpers/ServerReply.ts\";\nimport type {\n RequestConfigSchema,\n ServerRequest,\n ServerResponseBody,\n ServerRoute,\n} from \"../interfaces/ServerRequest.ts\";\nimport { ServerProvider } from \"../providers/ServerProvider.ts\";\nimport { ServerRouterProvider } from \"../providers/ServerRouterProvider.ts\";\nimport {\n type FetchOptions,\n type FetchResponse,\n HttpClient,\n} from \"../services/HttpClient.ts\";\n\n/**\n * Creates a server action descriptor for defining type-safe HTTP endpoints.\n *\n * Server actions are the core building blocks for REST APIs in Alepha, providing declarative\n * HTTP endpoints with full type safety, automatic validation, and OpenAPI documentation.\n *\n * **Key Features**\n * - Full TypeScript inference for request/response types\n * - Automatic schema validation using TypeBox\n * - Convention-based URL generation with customizable paths\n * - Direct invocation (`run()`) or HTTP requests (`fetch()`)\n * - Built-in authentication and authorization support\n * - Automatic content-type handling (JSON, form-data, plain text)\n *\n * **URL Generation**\n * Actions are prefixed with `/api` by default (configurable via `SERVER_API_PREFIX`).\n * HTTP method defaults to GET, or POST if body schema is provided.\n *\n * **Common Use Cases**\n * - CRUD operations with type safety\n * - File upload and download endpoints\n * - Microservice communication\n *\n * @example\n * ```ts\n * class UserController {\n * getUsers = $action({\n * path: \"/users\",\n * schema: {\n * query: t.object({\n * page: t.optional(t.number({ default: 1 })),\n * limit: t.optional(t.number({ default: 10 }))\n * }),\n * response: t.object({\n * users: t.array(t.object({\n * id: t.text(),\n * name: t.text(),\n * email: t.text()\n * })),\n * total: t.number()\n * })\n * },\n * handler: async ({ query }) => {\n * const users = await this.userService.findUsers(query);\n * return { users: users.items, total: users.total };\n * }\n * });\n *\n * createUser = $action({\n * method: \"POST\",\n * path: \"/users\",\n * schema: {\n * body: t.object({\n * name: t.text(),\n * email: t.text({ format: \"email\" })\n * }),\n * response: t.object({ id: t.text(), name: t.text() })\n * },\n * handler: async ({ body }) => {\n * return await this.userService.create(body);\n * }\n * });\n * }\n * ```\n */\nexport const $action = <TConfig extends RequestConfigSchema>(\n options: ActionDescriptorOptions<TConfig>,\n): ActionDescriptorFn<TConfig> => {\n const instance = createDescriptor(ActionDescriptor<TConfig>, options);\n const fn = (\n config?: ClientRequestEntry<TConfig>,\n options?: ClientRequestOptions,\n ) => {\n return instance.run(config, options);\n };\n Object.defineProperty(fn, \"name\", {\n get(): string {\n return instance.options.name || instance.config.propertyKey;\n },\n });\n return Object.setPrototypeOf(fn, instance) as ActionDescriptorFn<TConfig>;\n};\n\n// ----------------------------------------------------------------------------------------------------------\n\nexport interface ActionDescriptorOptions<TConfig extends RequestConfigSchema>\n extends Omit<ServerRoute, \"handler\" | \"path\" | \"schema\" | \"mapParams\"> {\n /**\n * Name of the action.\n *\n * - It will be used to generate the route path if `path` is not provided.\n * - It will be used to generate the permission name if `security` is enabled.\n */\n name?: string;\n\n /**\n * Group actions together.\n *\n * - If not provided, the service name containing the route will be used.\n * - It will be used as Tag for documentation purposes.\n * - It will be used for permission name generation if `security` is enabled.\n *\n * @example\n * ```ts\n * // group = \"MyController\"\n * class MyController {\n * \thello = $action({ handler: () => \"Hello World\" });\n * }\n *\n * // group = \"users\"\n * class MyOtherController {\n * group = \"users\";\n * a1 = $action({ handler: () => \"Action 1\", group: this.group });\n * a2 = $action({ handler: () => \"Action 2\", group: this.group });\n * }\n * ```\n */\n group?: string;\n\n /**\n * Pathname of the route. If not provided, property key is used.\n */\n path?: string;\n\n /**\n * The route method.\n *\n * - If not provided, it will be set to \"GET\" by default.\n * - If not provider and a body is provided, it will be set to \"POST\".\n *\n * Wildcard methods are not supported for now. (e.g. \"ALL\", \"ANY\", etc.)\n */\n method?: RouteMethod;\n\n /**\n * The config schema of the route.\n * - body: The request body schema.\n * - params: Path variables schema.\n * - query: The request query-params schema.\n * - response: The response schema.\n */\n schema?: TConfig;\n\n /**\n * A short description of the action. Used for documentation purposes.\n */\n description?: string;\n\n /**\n * Disable the route. Useful with env variables do disable one specific route.\n * Route won't be available in the API but can still be called locally!\n */\n disabled?: boolean;\n\n /**\n * Main route handler. This is where the route logic is implemented.\n */\n handler: ServerActionHandler<TConfig>;\n}\n\n// ----------------------------------------------------------------------------------------------------------\n\nconst envSchema = t.object({\n SERVER_API_PREFIX: t.text({\n description: \"Prefix for all API routes (e.g. $action).\",\n default: \"/api\",\n }),\n});\n\nexport class ActionDescriptor<\n TConfig extends RequestConfigSchema,\n> extends Descriptor<ActionDescriptorOptions<TConfig>> {\n protected readonly log = $logger();\n protected readonly env = $env(envSchema);\n protected readonly httpClient = $inject(HttpClient);\n protected readonly serverProvider = $inject(ServerProvider);\n protected readonly serverRouterProvider = $inject(ServerRouterProvider);\n\n protected onInit() {\n if (this.options.disabled) {\n this.log.debug(\n `Action '${this.name}' is disabled. It won't be available in the API.`,\n );\n return;\n }\n this.serverRouterProvider.createRoute(this.route);\n }\n\n public get prefix() {\n return this.env.SERVER_API_PREFIX;\n }\n\n public get route(): ServerRoute {\n return {\n ...(this.options as any), // TODO: fix schema.header mapping\n method: this.method,\n path: `${this.prefix}${this.path}`,\n } as ServerRoute;\n }\n\n /**\n * Returns the name of the action.\n */\n public get name(): string {\n return this.options.name || this.config.propertyKey;\n }\n\n /**\n * Returns the group of the action. (e.g. \"orders\", \"admin\", etc.)\n */\n public get group(): string {\n return this.options.group || this.config.service.name;\n }\n\n /**\n * Returns the HTTP method of the action.\n */\n public get method(): RouteMethod {\n return this.options.method || (this.options.schema?.body ? \"POST\" : \"GET\");\n }\n\n /**\n * Returns the path of the action.\n *\n * Path is prefixed by `/api` by default.\n */\n public get path(): string {\n if (this.options.path) {\n return this.options.path;\n }\n\n let path = `/${this.name}`;\n\n if (this.options.schema?.params) {\n for (const [key] of Object.entries(\n this.options.schema.params.properties,\n )) {\n path += `/:${key}`;\n }\n }\n\n return path;\n }\n\n public get schema(): TConfig | undefined {\n return this.options.schema;\n }\n\n public getBodyContentType(): string | undefined {\n if (this.options.schema?.body) {\n // TODO: move to `alepha.server.multipart` module ?\n if (isMultipart(this.options)) {\n return \"multipart/form-data\";\n }\n\n if (t.schema.isString(this.options.schema.body)) {\n // if body is a string, we assume it's plain text\n return \"text/plain\";\n }\n\n if (\n t.schema.isObject(this.options.schema.body) ||\n t.schema.isArray(this.options.schema.body) ||\n t.schema.isRecord(this.options.schema.body)\n )\n // if body is an object or array, we assume it's JSON\n return \"application/json\";\n }\n }\n\n /**\n * Call the action handler directly.\n * There is no HTTP layer involved.\n */\n public async run(\n config?: ClientRequestEntry<TConfig>,\n options: ClientRequestOptions = {}, // most of the options are ignored here\n ): Promise<ClientRequestResponse<TConfig>> {\n const handler = this.options.handler;\n const {\n body,\n params = {},\n query = {},\n headers = {},\n } = (config ?? {}) as ClientRequestEntryContainer<RequestConfigSchema>;\n const reply = new ServerReply();\n const method = this.method;\n\n // we use localhost as the base URL for the action\n const url = new URL(`http://localhost${this.path ?? \"\"}`);\n\n const serverActionRequest: Partial<ServerRequest> = {\n method,\n url,\n body,\n params,\n query,\n headers,\n reply,\n metadata: {},\n };\n\n await this.alepha.events.emit(\"action:onRequest\", {\n action: this,\n request: serverActionRequest as ServerRequest,\n options,\n });\n\n if (serverActionRequest.reply?.body) {\n return serverActionRequest.reply.body as ClientRequestResponse<TConfig>;\n }\n\n if (serverActionRequest.query && this.options.schema?.query) {\n serverActionRequest.query = this.alepha.codec.encode(\n this.options.schema.query,\n serverActionRequest.query,\n );\n }\n\n if (serverActionRequest.headers && this.options.schema?.headers) {\n serverActionRequest.headers = this.alepha.codec.encode(\n this.options.schema.headers,\n serverActionRequest.headers,\n ) as Record<string, any>;\n }\n\n if (serverActionRequest.body && this.options.schema?.body) {\n serverActionRequest.body = this.alepha.codec.encode(\n this.options.schema.body,\n serverActionRequest.body,\n ) as unknown;\n }\n\n if (serverActionRequest.params && this.options.schema?.params) {\n serverActionRequest.params = this.alepha.codec.encode(\n this.options.schema.params,\n serverActionRequest.params,\n ) as Record<string, any>;\n }\n\n this.serverRouterProvider.validateRequest(\n this.options,\n serverActionRequest as ServerRequest,\n );\n\n let response: any = await handler(\n serverActionRequest as ServerActionRequest<TConfig>,\n );\n\n // we validate response just to remove undeclared properties from response\n if (\n this.options.schema?.response &&\n // skip validation if response is expected as file\n !isTypeFile(this.options.schema.response)\n ) {\n response = this.alepha.codec.validate(\n this.options.schema.response,\n response,\n );\n }\n\n await this.alepha.events.emit(\"action:onResponse\", {\n action: this,\n request: serverActionRequest as ServerRequest,\n options,\n response,\n });\n\n return response;\n }\n\n /**\n * Works like `run`, but always fetches (http request) the route.\n */\n public fetch(\n config?: ClientRequestEntry<TConfig>,\n options?: ClientRequestOptions,\n ): Promise<FetchResponse<ClientRequestResponse<TConfig>>> {\n return this.httpClient.fetchAction({\n host: this.serverProvider.hostname, // that's the trick, we just use the server hostname\n action: this,\n config,\n options,\n });\n }\n}\n\nexport interface ActionDescriptorFn<TConfig extends RequestConfigSchema>\n extends ActionDescriptor<TConfig> {\n (\n config?: ClientRequestEntry<TConfig>,\n options?: ClientRequestOptions,\n ): Promise<ClientRequestResponse<TConfig>>;\n}\n\n$action[KIND] = ActionDescriptor;\n\n// ----------------------------------------------------------------------------------------------------------\n\nexport type ClientRequestEntry<\n TConfig extends RequestConfigSchema,\n T = ClientRequestEntryContainer<TConfig>,\n> = {\n [K in keyof T as T[K] extends undefined ? never : K]: T[K];\n};\n\nexport type ClientRequestEntryContainer<TConfig extends RequestConfigSchema> = {\n body: TConfig[\"body\"] extends TObject ? Static<TConfig[\"body\"]> : undefined;\n\n params: TConfig[\"params\"] extends TObject\n ? Static<TConfig[\"params\"]>\n : undefined;\n\n headers?: TConfig[\"headers\"] extends TObject\n ? Static<TConfig[\"headers\"]>\n : undefined;\n\n query?: TConfig[\"query\"] extends TObject\n ? Partial<Static<TConfig[\"query\"]>>\n : undefined;\n};\n\nexport interface ClientRequestOptions extends FetchOptions {\n /**\n * Standard request fetch options.\n */\n request?: RequestInit;\n}\n\nexport type ClientRequestResponse<TConfig extends RequestConfigSchema> =\n TConfig[\"response\"] extends TSchema ? Static<TConfig[\"response\"]> : any;\n\n/**\n * Specific handler for server actions.\n */\nexport type ServerActionHandler<\n TConfig extends RequestConfigSchema = RequestConfigSchema,\n> = (\n request: ServerActionRequest<TConfig>,\n) => Async<ServerResponseBody<TConfig>>;\n\n/**\n * Server Action Request Interface\n *\n * Can be extended with module augmentation to add custom properties (like `user` in Server Security).\n *\n * This is NOT Server Request, but a specific type for actions.\n */\nexport interface ServerActionRequest<TConfig extends RequestConfigSchema>\n extends ServerRequest<TConfig> {}\n","import { $inject, createDescriptor, Descriptor, KIND } from \"alepha\";\nimport type {\n RequestConfigSchema,\n ServerRoute,\n} from \"../interfaces/ServerRequest.ts\";\nimport { ServerRouterProvider } from \"../providers/ServerRouterProvider.ts\";\n\n/**\n * Create a basic endpoint.\n *\n * It's a low level descriptor. You probably want to use `$action` instead.\n *\n * @see {@link $action}\n * @see {@link $page}\n */\nexport const $route = <TConfig extends RequestConfigSchema>(\n options: RouteDescriptorOptions<TConfig>,\n): RouteDescriptor<TConfig> => {\n return createDescriptor(RouteDescriptor<TConfig>, options);\n};\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport interface RouteDescriptorOptions<\n TConfig extends RequestConfigSchema = RequestConfigSchema,\n> extends ServerRoute<TConfig> {}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport class RouteDescriptor<\n TConfig extends RequestConfigSchema,\n> extends Descriptor<RouteDescriptorOptions<TConfig>> {\n protected readonly serverRouterProvider = $inject(ServerRouterProvider);\n\n protected onInit() {\n this.serverRouterProvider.createRoute(this.options);\n }\n}\n\n$route[KIND] = RouteDescriptor;\n","import { $env, $hook, $inject, Alepha, type Static, t } from \"alepha\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport { ServerProvider } from \"./ServerProvider.ts\";\nimport { ServerRouterProvider } from \"./ServerRouterProvider.ts\";\n\nconst envSchema = t.object({\n SERVER_PORT: t.integer({\n default: 3000,\n min: 0,\n max: 65535,\n description: \"Set 0 to listen on a random port.\",\n }),\n SERVER_HOST: t.text({\n default: \"localhost\",\n description: \"Set 0.0.0.0 to listen on all interfaces.\",\n }),\n});\n\ndeclare module \"alepha\" {\n interface Env extends Partial<Static<typeof envSchema>> {}\n}\n\n// Type declaration for Bun global (only when running in Bun runtime)\ndeclare const Bun: any;\n\nexport class BunHttpServerProvider extends ServerProvider {\n protected readonly alepha = $inject(Alepha);\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n protected readonly log = $logger();\n protected readonly env = $env(envSchema);\n protected readonly router = $inject(ServerRouterProvider);\n\n protected bunServer?: ReturnType<typeof Bun.serve>;\n\n public get hostname(): string {\n if (this.bunServer) {\n return `http://${this.bunServer.hostname}:${this.bunServer.port}`;\n }\n return `http://${this.env.SERVER_HOST}:${this.env.SERVER_PORT}`;\n }\n\n public readonly start = $hook({\n on: \"start\",\n handler: async () => {\n await this.listen();\n },\n });\n\n protected readonly stop = $hook({\n on: \"stop\",\n handler: async () => {\n if (this.alepha.isProduction()) {\n await this.close();\n return;\n }\n\n // do not await in development & test\n this.close().catch(() => {});\n },\n });\n\n protected async listen() {\n let port = this.env.SERVER_PORT;\n\n // for testing, use a random port if port is 3000 (default)\n if (this.alepha.isTest() && port === 3000) {\n port = 0;\n }\n\n try {\n this.bunServer = Bun.serve({\n port,\n hostname: this.env.SERVER_HOST,\n fetch: async (request: Request) => {\n this.log.trace(`Incoming Bun request -> ${request.url}`);\n\n // Create WebRequestEvent for handleWebRequest\n const webRequestEvent = {\n req: request,\n res: undefined as Response | undefined,\n };\n\n try {\n await this.handleWebRequest(webRequestEvent);\n\n if (!webRequestEvent.res) {\n // No response set, return 500\n return new Response(\"Internal Server Error\", {\n status: 500,\n headers: { \"content-type\": \"text/plain\" },\n });\n }\n\n return webRequestEvent.res;\n } catch (err) {\n this.log.error(\"Error handling request\", err);\n return new Response(\"Internal Server Error\", {\n status: 500,\n headers: { \"content-type\": \"text/plain\" },\n });\n }\n },\n error: (error: Error) => {\n this.log.error(\"Bun server error\", error);\n return new Response(\"Internal Server Error\", {\n status: 500,\n headers: { \"content-type\": \"text/plain\" },\n });\n },\n });\n\n this.log.info(`Server listening on ${this.hostname}`);\n } catch (err) {\n this.log.error(\"Failed to start Bun server\", err);\n throw err;\n }\n }\n\n protected async close() {\n if (!this.bunServer) {\n return;\n }\n\n try {\n // Bun's server.stop() returns a promise that resolves when all connections are closed\n const stopPromise = this.bunServer.stop();\n\n // Race between stop completion and timeout\n await Promise.race([this.dateTimeProvider.wait(10000), stopPromise]);\n\n this.bunServer = undefined;\n this.log.info(\"Server closed\");\n } catch (err) {\n this.log.error(\"Error closing Bun server\", err);\n throw err;\n }\n }\n}\n","import {\n createServer,\n type IncomingMessage,\n type Server,\n type ServerResponse,\n} from \"node:http\";\nimport { $env, $hook, $inject, Alepha, type Static, t } from \"alepha\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { $logger } from \"alepha/logger\";\nimport { ServerProvider } from \"./ServerProvider.ts\";\nimport { ServerRouterProvider } from \"./ServerRouterProvider.ts\";\n\nconst envSchema = t.object({\n SERVER_PORT: t.integer({\n default: 3000,\n min: 0,\n max: 65535,\n description: \"Set 0 to listen on a random port.\",\n }),\n SERVER_HOST: t.text({\n default: \"localhost\",\n description: \"Set 0.0.0.0 to listen on all interfaces.\",\n }),\n});\n\ndeclare module \"alepha\" {\n interface Env extends Partial<Static<typeof envSchema>> {}\n}\n\nexport class NodeHttpServerProvider extends ServerProvider {\n protected readonly alepha = $inject(Alepha);\n protected readonly dateTimeProvider = $inject(DateTimeProvider);\n protected readonly log = $logger();\n protected readonly env = $env(envSchema);\n protected readonly router = $inject(ServerRouterProvider);\n\n public get hostname(): string {\n if (this.server.listening) {\n const address = this.server.address();\n if (typeof address === \"object\" && address !== null) {\n return `http://${this.env.SERVER_HOST}:${address.port}`;\n }\n }\n return `http://${this.env.SERVER_HOST}:${this.env.SERVER_PORT}`;\n }\n\n public readonly server = this.createHttpServer((req, res) => {\n this.log.trace(`Incoming Node.js message -> ${req.url}`);\n this.handleNodeRequest({ req, res }).catch((err) => {\n this.log.error(\"Error handling request\", err);\n res.statusCode = 500;\n res.end(\"Internal Server Error\");\n });\n });\n\n public readonly start = $hook({\n on: \"start\",\n handler: async () => {\n await this.listen();\n this.alepha.state.set(\"alepha.node.server\", this.server);\n },\n });\n\n protected createHttpServer(\n func: (req: IncomingMessage, res: ServerResponse) => void,\n ): Server {\n return createServer(\n {\n // nov 25 - keep connections alive for better performance, cuz we http/1.1 by default\n keepAlive: true,\n },\n func,\n );\n }\n\n protected readonly stop = $hook({\n on: \"stop\",\n handler: async () => {\n if (this.alepha.isProduction()) {\n await this.close();\n return;\n }\n\n // do not await in development & test\n this.close().catch(() => {});\n },\n });\n\n protected async listen() {\n let port = this.env.SERVER_PORT;\n\n // for testing, use a random port if port is 3000 (default)\n if (this.alepha.isTest() && port === 3000) {\n port = 0;\n }\n\n await new Promise<void>((resolve, reject) => {\n this.server?.listen(port, this.env.SERVER_HOST, () => {\n this.log.info(`Server listening on ${this.hostname}`);\n resolve();\n });\n\n this.server?.on(\"error\", (err) => {\n reject(err);\n });\n });\n }\n\n protected async close() {\n const promise = new Promise<void>((resolve, reject) => {\n this.server?.close((err) => {\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n });\n });\n\n await Promise.race([this.dateTimeProvider.wait(2000), promise]);\n\n this.log.info(\"Server closed\");\n }\n}\n","import { ReadableStream as WebStream } from \"node:stream/web\";\nimport { createBrotliDecompress, createGunzip, createInflate } from \"node:zlib\";\nimport { $env, $hook, $inject, Alepha, t } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport { HttpError } from \"../errors/HttpError.ts\";\n\nconst envSchema = t.object({\n SERVER_BODY_PARSER_INFLATE: t.boolean({\n default: true,\n description: \"Enable decompression of request body.\",\n }),\n SERVER_BODY_PARSER_LIMIT: t.integer({\n default: 100_000, // 100KB\n min: 0,\n description: \"Maximum size of request body in bytes.\",\n }),\n});\n\nexport class ServerBodyParserProvider {\n protected readonly env = $env(envSchema);\n protected readonly alepha = $inject(Alepha);\n protected readonly log = $logger();\n\n public readonly onRequest = $hook({\n on: \"server:onRequest\",\n handler: async ({ route, request }) => {\n if (request.body) {\n return; // already parsed\n }\n\n let stream: ReadableStream | undefined;\n\n if (request.raw.web?.req.body) {\n stream = request.raw.web.req.body;\n } else if (request.raw.node?.req) {\n // convert Node.js IncomingMessage to Web ReadableStream\n // TODO: check performance impact, it's better to directly read from Node stream!\n stream = WebStream.from(request.raw.node.req) as ReadableStream;\n }\n\n if (!stream) {\n return;\n }\n\n if (route.schema?.body) {\n try {\n const body = await this.parse(stream, request.headers);\n if (body) {\n request.body = body;\n }\n } catch (error) {\n if (error instanceof HttpError) {\n throw error;\n }\n\n throw new HttpError(\n {\n status: 400,\n message: \"Failed to parse request body\",\n },\n error,\n );\n }\n }\n },\n });\n\n public async parse(\n stream: ReadableStream,\n headers: Record<string, string>,\n ): Promise<object | string | undefined> {\n const contentType = headers[\"content-type\"];\n const contentEncoding = headers[\"content-encoding\"];\n\n if (!contentType) return undefined;\n\n if (contentType.startsWith(\"application/json\")) {\n return this.parseJson(stream, contentEncoding);\n }\n\n if (contentType.startsWith(\"text/plain\")) {\n return this.parseText(stream, contentEncoding);\n }\n\n if (contentType.startsWith(\"application/x-www-form-urlencoded\")) {\n return this.parseUrlEncoded(stream, contentEncoding);\n }\n\n return undefined;\n }\n\n public async parseText(\n stream: ReadableStream,\n contentEncoding?: string,\n ): Promise<string> {\n const buffer = await this.streamToBuffer(stream);\n const bufferInflated = await this.maybeDecompress(buffer, contentEncoding);\n return bufferInflated.toString(\"utf-8\");\n }\n\n public async parseUrlEncoded(\n stream: ReadableStream,\n contentEncoding?: string,\n ): Promise<object> {\n const text = await this.parseText(stream, contentEncoding);\n const params = new URLSearchParams(text);\n const result: Record<string, string> = {};\n for (const [key, value] of params.entries()) {\n result[key] = value;\n }\n\n return result;\n }\n\n public async parseJson(\n stream: ReadableStream,\n contentEncoding?: string,\n ): Promise<object> {\n const text = await this.parseText(stream, contentEncoding);\n return JSON.parse(text);\n }\n\n protected async maybeDecompress(\n buffer: Buffer,\n encoding: string | undefined,\n ): Promise<Buffer> {\n if (!this.env.SERVER_BODY_PARSER_INFLATE && encoding) {\n throw new HttpError({\n status: 415,\n message: `Content-Encoding ${encoding} not allowed`,\n });\n }\n\n switch (encoding) {\n case \"gzip\":\n return new Promise((res, rej) =>\n createGunzip()\n .end(buffer, () => {})\n .on(\"data\", res)\n .on(\"error\", rej),\n );\n case \"deflate\":\n return new Promise((res, rej) =>\n createInflate()\n .end(buffer, () => {})\n .on(\"data\", res)\n .on(\"error\", rej),\n );\n case \"br\":\n return new Promise((res, rej) =>\n createBrotliDecompress()\n .end(buffer, () => {})\n .on(\"data\", res)\n .on(\"error\", rej),\n );\n case undefined:\n case \"identity\":\n return buffer;\n default:\n throw new Error(`Unsupported Content-Encoding: ${encoding}`);\n }\n }\n\n /**\n * Convert Web ReadableStream to Buffer, with a size limit.\n *\n * TODO: move to alepha/file FileUtils\n */\n protected async streamToBuffer(stream: ReadableStream): Promise<Buffer> {\n const chunks: Uint8Array[] = [];\n let totalLength = 0;\n\n const reader = stream.getReader();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n if (value) {\n totalLength += value.length;\n\n if (totalLength > this.env.SERVER_BODY_PARSER_LIMIT) {\n this.log.error(\n `Body size limit exceeded: ${totalLength} > ${this.env.SERVER_BODY_PARSER_LIMIT}`,\n );\n\n await reader.cancel(); // Cancel the stream\n\n throw new HttpError({\n status: 413,\n message: `Request body size limit exceeded`,\n });\n }\n\n chunks.push(value);\n }\n }\n\n // Combine all chunks into a single Buffer\n const combinedLength = chunks.reduce(\n (sum, chunk) => sum + chunk.length,\n 0,\n );\n const combined = new Uint8Array(combinedLength);\n let offset = 0;\n\n for (const chunk of chunks) {\n combined.set(chunk, offset);\n offset += chunk.length;\n }\n\n return Buffer.from(combined);\n } catch (error) {\n // Make sure to release the reader lock\n reader.releaseLock();\n throw error;\n }\n }\n}\n","import { $hook, $inject, Alepha } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\n\nexport class ServerLoggerProvider {\n protected readonly log = $logger();\n protected readonly alepha = $inject(Alepha);\n\n public readonly onRequest = $hook({\n on: \"server:onRequest\",\n priority: \"first\",\n handler: ({ route, request }) => {\n if (!route.silent) {\n request.metadata.now = Date.now();\n\n const data: Record<string, string> = {\n method: request.method,\n path: request.url.pathname,\n };\n\n if (this.alepha.isProduction()) {\n data.agent = request.headers[\"user-agent\"];\n const ip = request.ip;\n if (ip) {\n data.ip = ip;\n }\n }\n\n this.log.info(\"Incoming request\", data);\n }\n },\n });\n\n public readonly onError = $hook({\n on: \"server:onError\",\n priority: \"last\",\n handler: ({ error }) => {\n this.log.error(\"Request has failed\", error);\n },\n });\n\n public readonly onResponse = $hook({\n on: \"server:onResponse\",\n priority: \"last\",\n handler: ({ route, request, response }) => {\n if (!route.silent) {\n const ms = Date.now() - request.metadata.now;\n this.log.info(\"Request completed\", { status: response.status, ms });\n }\n },\n });\n}\n","import { $hook, $inject, Alepha } from \"alepha\";\nimport { HttpError } from \"../errors/HttpError.ts\";\n\n/**\n * On every request, this provider checks if the server is ready.\n *\n * If the server is not ready, it responds with a 503 status code and a message indicating that the server is not ready yet.\n *\n * The response also includes a `Retry-After` header indicating that the client should retry after 5 seconds.\n */\nexport class ServerNotReadyProvider {\n protected readonly alepha = $inject(Alepha);\n\n public readonly onRequest = $hook({\n on: \"server:onRequest\",\n priority: \"first\",\n handler: ({ request: { reply } }) => {\n if (this.alepha.isReady()) {\n return;\n }\n\n reply.headers[\"Retry-After\"] = \"5\"; // Retry after 5 seconds\n\n throw new HttpError({\n status: 503,\n message: \"Server is not ready yet. Please try again later.\",\n });\n },\n });\n}\n","export const routeMethods = [\n // list of supported http methods\n \"GET\",\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"DELETE\",\n \"HEAD\",\n \"OPTIONS\",\n \"CONNECT\",\n \"TRACE\",\n] as const;\n\nexport type RouteMethod = (typeof routeMethods)[number];\n","import { HttpError } from \"./HttpError.ts\";\n\nexport class BadRequestError extends HttpError {\n constructor(message = \"Invalid request body\", cause?: unknown) {\n super(\n {\n message,\n status: 400,\n },\n cause,\n );\n }\n}\n","import { HttpError } from \"./HttpError.ts\";\n\nexport class ConflictError extends HttpError {\n constructor(message = \"Entity already exists\", cause?: unknown) {\n super(\n {\n message,\n status: 409,\n },\n cause,\n );\n }\n}\n","import { HttpError } from \"./HttpError.ts\";\n\nexport class ForbiddenError extends HttpError {\n constructor(\n message = \"No permission to access this resource\",\n cause?: unknown,\n ) {\n super(\n {\n message,\n status: 403,\n },\n cause,\n );\n }\n}\n","import { HttpError } from \"./HttpError.ts\";\n\nexport class NotFoundError extends HttpError {\n constructor(message = \"Resource not found\", cause?: unknown) {\n super(\n {\n message,\n status: 404,\n },\n cause,\n );\n }\n}\n","import { HttpError } from \"./HttpError.ts\";\n\nexport class UnauthorizedError extends HttpError {\n readonly name = \"UnauthorizedError\";\n\n constructor(\n message = \"Not allowed to access this resource\",\n cause?: unknown,\n ) {\n super(\n {\n message,\n status: 401,\n },\n cause,\n );\n }\n}\n","import type { Static } from \"alepha\";\nimport { t } from \"alepha\";\n\nexport const okSchema = t.object(\n {\n ok: t.boolean({ description: \"True when operation succeed\" }),\n id: t.optional(t.union([t.text(), t.integer()])),\n count: t.optional(\n t.number({ description: \"Number of resources affected\" }),\n ),\n },\n {\n title: \"Ok\",\n description: \"Generic response after a successful operation on a resource\",\n },\n);\n\nexport type Ok = Static<typeof okSchema>;\n","import type { Server } from \"node:http\";\nimport { $module, type Alepha, type DescriptorFactoryLike } from \"alepha\";\nimport {\n $action,\n type ActionDescriptor,\n type ClientRequestOptions,\n} from \"./descriptors/$action.ts\";\nimport { $route } from \"./descriptors/$route.ts\";\nimport type { HttpError } from \"./errors/HttpError.ts\";\nimport type {\n NodeRequestEvent,\n RequestConfigSchema,\n ServerRequest,\n ServerRequestConfigEntry,\n ServerResponse,\n ServerRoute,\n WebRequestEvent,\n} from \"./interfaces/ServerRequest.ts\";\nimport { BunHttpServerProvider } from \"./providers/BunHttpServerProvider.ts\";\nimport { NodeHttpServerProvider } from \"./providers/NodeHttpServerProvider.ts\";\nimport { ServerBodyParserProvider } from \"./providers/ServerBodyParserProvider.ts\";\nimport { ServerLoggerProvider } from \"./providers/ServerLoggerProvider.ts\";\nimport { ServerNotReadyProvider } from \"./providers/ServerNotReadyProvider.ts\";\nimport { ServerProvider } from \"./providers/ServerProvider.ts\";\nimport { ServerTimingProvider } from \"./providers/ServerTimingProvider.ts\";\nimport type { FetchOptions, HttpAction } from \"./services/HttpClient.ts\";\nimport { HttpClient } from \"./services/HttpClient.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\ndeclare module \"alepha\" {\n interface State {\n \"alepha.node.server\"?: Server;\n }\n interface Hooks {\n // -----------------------------------------------------------------------------------------------------------------\n // Local Actions hooks\n \"action:onRequest\": {\n action: ActionDescriptor<RequestConfigSchema>;\n request: ServerRequest;\n options: ClientRequestOptions;\n };\n \"action:onResponse\": {\n action: ActionDescriptor<RequestConfigSchema>;\n request: ServerRequest;\n options: ClientRequestOptions;\n response: any;\n };\n // -----------------------------------------------------------------------------------------------------------------\n // Server hooks\n \"server:onRequest\": {\n route: ServerRoute;\n request: ServerRequest;\n };\n \"server:onError\": {\n route: ServerRoute;\n request: ServerRequest;\n error: Error;\n };\n // last chance to modify the response -\n // TODO: probably not really needed, we can also update the response in the onResponse hook...\n \"server:onSend\": {\n route: ServerRoute;\n request: ServerRequest;\n };\n // response is ready\n \"server:onResponse\": {\n route: ServerRoute;\n request: ServerRequest;\n response: ServerResponse;\n };\n // -----------------------------------------------------------------------------------------------------------------\n // Http client hooks\n \"client:onRequest\": {\n route: HttpAction;\n config: ServerRequestConfigEntry;\n options: ClientRequestOptions;\n headers: Record<string, string>;\n request: RequestInit;\n };\n \"client:beforeFetch\": {\n url: string;\n options: FetchOptions;\n request: RequestInit;\n };\n \"client:onError\": {\n route?: HttpAction;\n error: HttpError;\n };\n // -----------------------------------------------------------------------------------------------------------------\n // Internal hooks\n \"node:request\": NodeRequestEvent;\n \"web:request\": WebRequestEvent;\n }\n}\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./descriptors/$action.ts\";\nexport * from \"./descriptors/$route.ts\";\nexport * from \"./index.shared.ts\";\nexport * from \"./providers/BunHttpServerProvider.ts\";\nexport * from \"./providers/NodeHttpServerProvider.ts\";\nexport * from \"./providers/ServerLoggerProvider.ts\";\nexport * from \"./providers/ServerNotReadyProvider.ts\";\nexport * from \"./providers/ServerProvider.ts\";\nexport * from \"./providers/ServerRouterProvider.ts\";\nexport * from \"./providers/ServerTimingProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Provides high-performance HTTP server capabilities with declarative routing and action descriptors.\n *\n * The server module enables building REST APIs and web applications using `$route` and `$action` descriptors\n * on class properties. It provides automatic request/response handling, schema validation, middleware support,\n * and seamless integration with other Alepha modules for a complete backend solution.\n *\n * @see {@link $route}\n * @see {@link $action}\n * @module alepha.server\n */\nexport const AlephaServer = $module({\n name: \"alepha.server\",\n descriptors: [$route, $action as DescriptorFactoryLike],\n services: [\n ServerProvider,\n BunHttpServerProvider,\n NodeHttpServerProvider,\n ServerBodyParserProvider,\n ServerLoggerProvider,\n ServerNotReadyProvider,\n ServerTimingProvider,\n HttpClient,\n ],\n register: (alepha: Alepha) => {\n if (!alepha.isServerless() && !alepha.isViteDev()) {\n if (alepha.isBun()) {\n alepha.with({\n optional: true,\n provide: ServerProvider,\n use: BunHttpServerProvider,\n });\n } else {\n alepha.with({\n optional: true,\n provide: ServerProvider,\n use: NodeHttpServerProvider,\n });\n }\n } else {\n alepha.with(ServerProvider);\n }\n\n alepha.with(ServerBodyParserProvider);\n alepha.with(ServerLoggerProvider);\n alepha.with(ServerNotReadyProvider);\n\n if (!alepha.isProduction()) {\n alepha.with(ServerTimingProvider);\n }\n },\n});\n"],"mappings":";;;;;;;;;;;;;;AAKA,MAAa,eAAe,YAGb;AACb,KAAI,QAAQ,oBAAoB,sBAC9B,QAAO;AAGT,KAAI,QAAQ,QAAQ,QAAQ,gBAAgB,QAAQ,OAAO,MAAM;EAC/D,MAAMA,aAAkC,QAAQ,OAAO,KAAK;AAC5D,OAAK,MAAM,OAAO,WAChB,KAAI,WAAW,KAAK,WAAW,SAC7B,QAAO;;AAKb,QAAO;;;;;;;;ACnBT,IAAa,cAAb,MAAyB;CAEvB,AAAO,UAEH,EAAE;CAEN,AAAO;CAEP,AAAO;;;;CAKP,AAAO,SAAS,KAAa,SAAiB,KAAW;AACvD,OAAK,SAAS;AACd,OAAK,QAAQ,WAAW;;;;;CAQ1B,AAAO,UAAU,QAAsB;AACrC,OAAK,SAAS;AACd,SAAO;;;;;CAMT,AAAO,UAAU,MAAc,OAAqB;AAClD,OAAK,QAAQ,KAAK,aAAa,IAAI;AACnC,SAAO;;;;;CAMT,AAAO,QAAQ,MAAiB;AAC9B,OAAK,OAAO;AACZ,SAAO;;;;;;ACzCX,MAAa,eACX,OACA,WAC2B;AAS3B,KAAI,EAPF,CAAC,CAAC,SACF,OAAO,UAAU,YACjB,aAAa,SACb,OAAO,MAAM,YAAY,YACzB,YAAY,SACZ,OAAO,MAAM,WAAW,UAGxB,QAAO;AAGT,KAAI,OACF,QAAQ,MAAwB,WAAW;AAG7C,QAAO;;AAGT,IAAa,YAAb,cAA+BC,mBAAY;CACzC,AAAO,OAAO;CAEd,OAAO,KAAK;CAEZ,OAAO,OAAO,OAA+B;EAC3C,MAAMC,OAAgC;GACpC,OAAO,MAAM;GACb,QAAQ,MAAM;GACd,SAAS,MAAM;GAChB;AAED,MAAI,MAAM,QAAS,MAAK,UAAU,MAAM;AACxC,MAAI,MAAM,UAAW,MAAK,YAAY,MAAM;AAC5C,MAAI,MAAM,OAAQ,MAAK,QAAQ,MAAM;AAErC,SAAO;;CAGT,AAAgB;CAChB,AAAgB;CAEhB,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAKhB,YAAY,SAA+B,OAAiB;AAC1D,QAAM,QAAQ,SAAS,EACrB,OACD,CAAC;AAEF,OAAK,SAAS,QAAQ,UAAU;AAChC,OAAK,UAAU,QAAQ;AACvB,OAAK,YAAY,QAAQ;AAEzB,MAAI,OAAO,QAAQ,UAAU,SAC3B,MAAK,SAAS;GACZ,MAAO,QAAQ,MAA2B;GAC1C,SAAU,QAAQ,MAA8B;GACjD;WACQ,iBAAiB,MAC1B,MAAK,SAAS;GACZ,MAAM,MAAM;GACZ,SAAS,MAAM;GAChB;AAGH,MAAI,KAAK,YAAY,SAAS,YAC5B,MAAK,QACH,QAAQ,SAAS,kBAAkB,KAAK,WAAW;MAErD,MAAK,QAAQ,KAAK,YAAY;;;AAKpC,MAAaC,oBAA4C;CACvD,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACN;;;;ACnGD,IAAa,kBAAb,cAAqC,UAAU;CAC7C,YAAY,UAAU,yBAAyB,OAAiB;AAC9D,QACE;GACE;GACA,QAAQ;GACT,EACD,MACD;;;;;;;;;;;;ACyBL,IAAa,kBAAb,MAA6B;CAC3B,AAAO,MAAM,YAAoB,IAAmB;EAClD,MAAM,KAAK,UAAU,aAAa;EAGlC,IAAIC,KAA0B;EAC9B,IAAIC,UAAoC;EACxC,IAAIC,SAAkC;AAGtC,MAAI,GAAG,SAAS,gBAAgB,CAC9B,MAAK;WACI,GAAG,SAAS,UAAU,CAC/B,MAAK;WACI,GAAG,SAAS,UAAU,CAC/B,MAAK;WAEL,GAAG,SAAS,SAAS,IACrB,GAAG,SAAS,OAAO,IACnB,GAAG,SAAS,OAAO,IAClB,GAAG,SAAS,MAAM,IAAI,CAAC,GAAG,SAAS,UAAU,CAE9C,MAAK;WAEL,GAAG,SAAS,SAAS,IACrB,GAAG,SAAS,QAAQ,IACpB,GAAG,SAAS,YAAY,CAExB,MAAK;WACI,GAAG,SAAS,OAAO,IAAI,GAAG,SAAS,WAAW,CACvD,MAAK;WACI,GAAG,SAAS,SAAS,CAC9B,MAAK;WACI,GAAG,SAAS,UAAU,CAC/B,MAAK;WACI,GAAG,SAAS,UAAU,CAC/B,MAAK;WACI,GAAG,SAAS,aAAa,IAAI,GAAG,SAAS,OAAO,CACzD,MAAK;WACI,GAAG,SAAS,UAAU,IAAI,GAAG,SAAS,SAAS,CACxD,MAAK;WACI,GAAG,SAAS,QAAQ,IAAI,GAAG,SAAS,MAAM,CACnD,MAAK;AAIP,MAAI,GAAG,SAAS,YAAY,IAAI,GAAG,SAAS,SAAS,CACnD,WAAU;WACD,GAAG,SAAS,QAAQ,CAC7B,WAAU;WACD,GAAG,SAAS,UAAU,CAC/B,WAAU;WACD,GAAG,SAAS,iBAAiB,IAAI,GAAG,SAAS,UAAU,CAChE,WAAU;WACD,GAAG,SAAS,YAAY,IAAI,GAAG,SAAS,aAAa,CAC9D,WAAU;WAEV,GAAG,SAAS,QAAQ,IACpB,GAAG,SAAS,OAAO,IACnB,GAAG,SAAS,QAAQ,CAEpB,WAAU;WAEV,GAAG,SAAS,OAAO,IACnB,GAAG,SAAS,OAAO,IACnB,GAAG,SAAS,SAAS,CAErB,WAAU;WACD,GAAG,SAAS,UAAU,IAAI,CAAC,GAAG,SAAS,YAAY,CAC5D,WAAU;WACD,GAAG,SAAS,UAAU,IAAI,GAAG,SAAS,OAAO,CACtD,WAAU;WAEV,GAAG,SAAS,SAAS,IACrB,CAAC,GAAG,SAAS,SAAS,IACtB,CAAC,GAAG,SAAS,WAAW,CAExB,WAAU;WAEV,GAAG,SAAS,SAAS,IACrB,GAAG,SAAS,WAAW,IACvB,GAAG,SAAS,QAAQ,CAEpB,WAAU;EAIZ,MAAM,iBAAiB;GACrB;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD;EAaD,MAAM,WAXiB;GACrB;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAE+B,MAAM,YAAY,GAAG,SAAS,QAAQ,CAAC;EACvE,MAAM,WAAW,eAAe,MAAM,YAAY,GAAG,SAAS,QAAQ,CAAC;AAEvE,MAAI,SACF,UAAS;WACA,SACT,UAAS;MAET,UAAS;AAGX,SAAO;GAAE;GAAI;GAAS;GAAQ;;;;;;ACtJlC,IAAa,sBAAb,MAAiC;CAC/B,AAAmB,6BAAiBC,cAAO;CAC3C,AAAmB,sCAA0B,gBAAgB;CAE7D,AAAO,oBAAoB,YAA8C;EACvE,MAAM,OAAO;AACb,SAAO;GACL,QAAQ,WAAW;GACnB,KAAK,WAAW;GAChB,KAAK,WAAW;GAChB,SAAS,WAAW;GACpB,OAAO,WAAW;GAClB,QAAQ,WAAW;GAEnB,MAAM;GACN,UAAU,EAAE;GACZ,WAAW,KAAK,aAAa,WAAW,IAAI,OAAO,YAAY;GAC/D,OAAO,KAAK,OAAO,OAAO,aAAa,EAAE,UAAU,aAAa,CAAC;GACjE,IAAI,KAAK;AACP,WAAO,KAAK,aAAa,WAAW;;GAEtC,IAAI,YAAY;AACd,WAAO,KAAK,oBAAoB,WAAW;;GAE9C;;CAGH,AAAO,aAAa,SAAgD;AAClE,SAAO,QAAQ,QAAQ;;CAGzB,AAAO,oBAAoB,SAA4B;AACrD,SAAO,KAAK,gBAAgB,MAAM,QAAQ,QAAQ,cAAc;;CAGlE,AAAO,aAAa,SAAgD;EAMlE,MAAM,eAAe,QAAQ,QAAQ;AACrC,MAAI,aAEF,QAAO,MAAM,QAAQ,aAAa,GAC9B,aAAa,KACb,aAAa,MAAM,IAAI,CAAC,GAAG,MAAM;EAGvC,MAAM,UAAU,QAAQ,QAAQ;AAChC,MAAI,QACF,QAAO,MAAM,QAAQ,QAAQ,GAAG,QAAQ,KAAK;;;;;;ACrDnD,IAAa,uBAAb,MAAkC;CAChC,AAAmB,kCAAe;CAClC,AAAmB,6BAAiBC,cAAO;CAE3C,AAAO,UAAU;EACf,QAAQ,KAAK,OAAO,IAAI,WACpB,GAAG,KAAK,OAAO,IAAI,SAAS,aAAa,CAAC,KAC1C;EACJ,UAAU,KAAK,OAAO,cAAc;EACrC;CAED,AAAgB,8BAAkB;EAChC,UAAU;EACV,IAAI;EACJ,SAAS,OAAO,EAAE,cAAc;AAC9B,OAAI,KAAK,QAAQ,SACf;AAGF,WAAQ,SAAS,SAAS,EAAE;AAC5B,WAAQ,SAAS,OAAO,KAAK,eAAe,CAAC,KAAK,KAAK,CAAC;;EAE3D,CAAC;CAEF,AAAgB,+BAAmB;EACjC,UAAU;EACV,IAAI;EACJ,SAAS,OAAO,EAAE,cAAc;AAC9B,OAAI,KAAK,QAAQ,SACf;AAGF,OAAI,QAAQ,SAAS,QAAQ;AAC3B,SAAK,YAAY,KAAK,aAAa,QAAQ,SAAS,OAAO;IAE3D,IAAI,eAAe;AAEnB,SAAK,MAAM,CAAC,MAAM,CAAC,OAAO,cAAc,OAAO,QAC7C,QAAQ,SAAS,OAClB,EAAE;AACD,SAAI,OAAO,UAAU,YAAY,OAAO,aAAa,UAAU;AAC7D,WAAK,IAAI,KACP,uBAAuB,KAAK,MAAM,MAAM,IAAI,SAAS,GACtD;AACD;;KAGF,MAAM,gBACJ,KAAK,QAAQ,SAAS,KAAK,QAAQ,kBAAkB,IAAI;AAC3D,qBAAgB,GAAG,cAAc,OAAO,SAAS;;AAGnD,QAAI,QAAQ,MAAM,QAAQ,iBACxB,SAAQ,MAAM,QAAQ,oBAAoB,KAAK;QAE/C,SAAQ,MAAM,QAAQ,mBAAmB;;;EAIhD,CAAC;CAEF,IAAc,cAAc;AAC1B,SAAO;;CAGT,AAAO,YAAY,MAAoB;AACrC,MAAI,KAAK,QAAQ,SACf;EAGF,MAAM,UAAU,KAAK,OAAO,QAAQ,IAAmB,UAAU;AACjE,MAAI,CAAC,QACH;AAGF,UAAQ,aAAa,EAAE;AACvB,UAAQ,SAAS,WAAW,EAAE;AAC9B,UAAQ,SAAS,OAAO,QAAQ,CAAC,KAAK,KAAK,CAAC;;CAG9C,AAAO,UAAU,MAAoB;AACnC,MAAI,KAAK,QAAQ,SACf;EAGF,MAAM,UAAU,KAAK,OAAO,QAAQ,IAAmB,UAAU;AACjE,MAAI,CAAC,QACH;AAGF,MAAI,CAAC,QAAQ,UAAU,UAAU,EAAE,QAAQ,QAAQ,SAAS,SAAS;AACnE,QAAK,IAAI,KAAK,wBAAwB,KAAK,IAAI;AAC/C;;EAGF,MAAM,QAAQ,QAAQ,SAAS,OAAO,QAAQ;AAC9C,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAK,IAAI,KAAK,6BAA6B,KAAK,KAAK,QAAQ;AAC7D;;AAGF,OAAK,YAAY,MAAM,QAAQ,SAAS,OAAO;;CAGjD,AAAU,YAAY,MAAc,QAAyB;AAC3D,SAAO,QAAQ,CAAC,OAAO,MAAM,IAAI,KAAK,KAAK,GAAG,OAAO,MAAM,GAAG;;;;;;;;;;;;;ACpFlE,IAAa,uBAAb,cAA0CC,6BAAmC;CAC3E,AAAmB,kCAAe;CAClC,AAAmB,6BAAiBC,cAAO;CAC3C,AAAmB,SAAwB,EAAE;CAC7C,AAAmB,2CAA+B,qBAAqB;CACvE,AAAmB,0CAA8B,oBAAoB;;;;;;;CAQrE,AAAO,UAAU,SAAiC;AAChD,MAAI,QACF,KAAI,QAAQ,SAAS,IAAI,EAAE;GACzB,MAAM,cAAc,QAAQ,MAAM,GAAG,GAAG;AACxC,UAAO,KAAK,OAAO,QAAQ,UACzB,MAAM,KAAK,WAAW,YAAY,CACnC;QAED,QAAO,KAAK,OAAO,QAAQ,UAAU,MAAM,SAAS,QAAQ;AAGhE,SAAO,KAAK;;CAGd,AAAO,YACL,OACM;AACN,QAAM,WAAW;AACjB,QAAM,SAAS,MAAM,OAAO,aAAa;AAEzC,OAAK,OAAO,KAAK,MAAM;EAEvB,MAAM,OAAO,IAAI,MAAM,OAAO,GAAG,MAAM,OAAO,QAAQ,QAAQ,IAAI;EAClE,MAAM,eAAe,KAAK,gBAAgB,MAAM,OAAO;AAEvD,OAAK,IAAI,MAAM,gBAAgB,OAAO;AAEtC,OAAK,KAAK;GACR;GACA,UAAU,eAAe;IACvB,MAAM,UACJ,KAAK,oBAAoB,oBAAoB,WAAW;AAE1D,WAAO,KAAK,OAAO,QAAQ,UACnB,KAAK,eAAe,SAAS,OAAO,aAAa,EACvD,EACE,SAAS,KAAK,aAAa,WAAW,QAAQ,EAC/C,CACF;;GAEJ,CAAC;;CAGJ,AAAU,aAAa,SAAyC;EAC9D,MAAM,YAAY,QAAQ,mBAAmB,QAAQ;AAGrD,yBAAW,UAAU,CACnB,QAAO;AAGT,SAAO,OAAO,YAAY;;CAG5B,MAAgB,eACd,SACA,OACA,cACA;AACA,QAAM,KAAK,gBAAgB,OAAO,SAAS,aAAa,CAAC,OAAO,UAAU;AACxE,UAAO,KAAK,aAAa,OAAO,SAAS,MAAe;IACxD;AAEF,QAAM,KAAK,OAAO,OAAO,KACvB,iBACA;GACE;GACA;GACD,EACD,EACE,OAAO,MACR,CACF;EAGD,MAAM,WAAW;GACf,QAAQ,QAAQ,MAAM,WAAW,QAAQ,MAAM,OAAO,MAAM;GAC5D,SAAS,QAAQ,MAAM;GACvB,MAAM,QAAQ,MAAM;GACrB;AAED,QAAM,KAAK,OAAO,OAAO,KACvB,qBACA;GACE;GACA;GACA;GACD,EACD,EACE,OAAO,MACR,CACF;AAED,SAAO;;CAGT,MAAgB,gBACd,OACA,SACA,cACA;AAMA,QAAM,KAAK,OAAO,OAAO,KACvB,oBACA;GACE;GACA;GACD,EACD,EACE,KAAK,OACN,CACF;AAED,MACE,QAAQ,MAAM,QACb,QAAQ,MAAM,UAAU,QAAQ,MAAM,UAAU,IAIjD;AAIF,OAAK,OAAO,QAAQ,IAAmB,WAAW,QAAyB;AAG3E,OAAK,qBAAqB,YAAY,kBAAkB;AACxD,MAAI;AACF,QAAK,gBAAgB,OAAO,QAAQ;YAC5B;AACR,QAAK,qBAAqB,UAAU,kBAAkB;;AAIxD,OAAK,qBAAqB,YAAY,aAAa;AACnD,MAAI;GACF,MAAM,SAAS,MAAM,MAAM,QAAQ,QAAQ;AAC3C,OAAI,OACF,SAAQ,MAAM,OAAO;YAEf;AACR,QAAK,qBAAqB,UAAU,aAAa;;AAInD,OAAK,qBAAqB,YAAY,oBAAoB;AAC1D,MAAI;AACF,QAAK,kBAAkB,OAAO,QAAQ,OAAO,aAAa;YAClD;AACR,QAAK,qBAAqB,UAAU,oBAAoB;;;CAI5D,AAAO,kBACL,OACA,OACA,cACM;AACN,MAAI,iBAAiB,UAAU,MAAM,QAAQ,UAAU;AACrD,SAAM,QAAQ,kBAAkB;AAChC,SAAM,OAAO,KAAK,OAAO,MAAM,OAAO,MAAM,OAAO,UAAU,MAAM,MAAM,EACvE,IAAI,UACL,CAAC;AACF;;AAGF,MAAI,iBAAiB,QAAQ;AAC3B,OAAI,wBAAY,MAAM,KAAK,CACzB,OAAM,IAAI,UAAU;IAClB,QAAQ;IACR,SAAS;IACV,CAAC;AAEJ,SAAM,QAAQ,kBAAkB,MAAM,KAAK;AAC3C,SAAM,QAAQ,yBACZ,yBAAyB,MAAM,KAAK,KAAK,WAAW,MAAK,GAAG,CAAC;AAC/D,SAAM,OAAO,MAAM,KAAK,QAAQ;AAChC;;AAGF,MAAI,iBAAiB,QAAQ;AAC3B,SAAM,OAAO,OAAO,MAAM,KAAK;AAC/B,OAAI,MAAM,KAAK,WAAW,kBAAkB,CAC1C,OAAM,QAAQ,oBAAoB;OAElC,OAAM,QAAQ,oBAAoB;AAEpC;;AAGF,MAAI,MAAM,QAAQ,QAAQ,iBAAiB,QAAQ;AACjD,UAAO,MAAM,QAAQ;AACrB,SAAM,OAAO;AACb;;AAGF,MAAI,OAAO,SAAS,MAAM,KAAK,EAAE;AAC/B,SAAM,QAAQ,oBAAoB;AAClC;;AAGF,MACE,MAAM,gBAAgBC,kCACtB,MAAM,gBAAgBC,sBACtB;AAEA,SAAM,QAAQ,oBAAoB;AAClC;;AAGF,QAAM,QAAQ,oBAAoB;AAClC,QAAM,OAAO,OAAO,MAAM,KAAK;;CAIjC,AAAU,gBAAgB,QAA4C;AACpE,MAAI,QAAQ,UAAU;AACpB,OACEC,SAAE,OAAO,SAAS,OAAO,SAAS,IAClCA,SAAE,OAAO,SAAS,OAAO,SAAS,IAClCA,SAAE,OAAO,QAAQ,OAAO,SAAS,CAEjC,QAAO;AAGT,OACEA,SAAE,OAAO,SAAS,OAAO,SAAS,IAClCA,SAAE,OAAO,UAAU,OAAO,SAAS,IACnCA,SAAE,OAAO,SAAS,OAAO,SAAS,IAClCA,SAAE,OAAO,UAAU,OAAO,SAAS,CAEnC,QAAO;AAGT,8BAAe,OAAO,SAAS,CAC7B,QAAO;AAGT,OAAIA,SAAE,OAAO,OAAO,OAAO,SAAS,CAClC,QAAO;;AAIX,SAAO;;CAGT,MAAgB,aACd,OACA,SACA,OACA;AAGA,UAAQ,MAAM,OAAO;AAErB,QAAM,KAAK,OAAO,OAAO,KACvB,kBACA;GACE;GACA;GACA;GACD,EACD,EACE,KAAK,OACN,CACF;AAED,MAAI,CAAC,QAAQ,MAAM,QAAQ,CAAC,QAAQ,MAAM,OACxC,KAAI,iBAAiB,WAAW;AAC9B,WAAQ,MAAM,SAAS,MAAM;AAC7B,WAAQ,MAAM,QAAQ,kBAAkB;AACxC,WAAQ,MAAM,OAAO,KAAK,UAAU;IAClC,GAAG,UAAU,OAAO,MAAM;IAC1B,WAAW,QAAQ;IACpB,CAAC;SACG;AACL,OACE,YAAY,SACZ,OAAO,MAAM,WAAW,YACxB,CAAC,CAAC,kBAAkB,MAAM,SAC1B;AACA,YAAQ,MAAM,SAAS,MAAM;AAC7B,YAAQ,MAAM,QAAQ,kBAAkB;AACxC,YAAQ,MAAM,OAAO,KAAK,UAAU;KAClC,QAAQ,MAAM;KACd,OAAO,kBAAkB,MAAM;KAC/B,SAAU,MAAgB;KAC1B,WAAW,QAAQ;KACpB,CAAC;AACF;;AAGF,WAAQ,MAAM,SAAS;AACvB,WAAQ,MAAM,QAAQ,kBAAkB;AACxC,WAAQ,MAAM,OAAO,KAAK,UAAU;IAClC,QAAQ;IACR,OAAO;IACP,SAAU,MAAgB;IAC1B,WAAW,QAAQ;IACpB,CAAC;;;CAKR,AAAO,gBACL,OACA,SACA;AACA,MAAI,MAAM,QAAQ,OAChB,KAAI;AACF,WAAQ,SAAS,KAAK,OAAO,MAAM,SACjC,MAAM,OAAO,QACb,QAAQ,OACT;WACM,OAAO;AACd,SAAM,IAAI,gBAAgB,0BAA0B,MAAM;;AAI9D,MAAI,MAAM,QAAQ,MAChB,KAAI;GAEF,MAAMC,QAA6B,EAAE;AACrC,QAAK,MAAM,OAAO,MAAM,OAAO,MAAM,WACnC,KAAI,QAAQ,MAAM,QAAQ,KACxB,OAAM,OAAO,KAAK,OAAO,MAAM,OAC7B,MAAM,OAAO,MAAM,WAAW,MAC9B,QAAQ,MAAM,KACf;AAGL,WAAQ,QAAQ;WACT,OAAO;AACd,SAAM,IAAI,gBAAgB,yBAAyB,MAAM;;AAI7D,MAAI,MAAM,QAAQ,QAChB,KAAI;AACF,WAAQ,UAAU,KAAK,OAAO,MAAM,SAClC,MAAM,OAAO,SACb,QAAQ,QACT;WACM,OAAO;AACd,SAAM,IAAI,gBAAgB,0BAA0B,MAAM;;AAI9D,MAAI,MAAM,QAAQ,KAChB,KAAI;AACF,WAAQ,OAAO,KAAK,OAAO,MAAM,OAC/B,MAAM,OAAO,MACb,QAAQ,KACT;WACM,OAAO;AACd,SAAM,IAAI,gBAAgB,wBAAwB,MAAM;;;;;;;;;;;;;;AC3XhE,IAAa,iBAAb,MAA4B;CAC1B,AAAmB,kCAAe;CAClC,AAAmB,6BAAiBC,cAAO;CAC3C,AAAmB,uCAA2BC,iCAAiB;CAC/D,AAAmB,6BAAiB,qBAAqB;CAEzD,AAAmB,6BAA6B;CAEhD,IAAW,WAAmB;AAC5B,SAAO;;;;;CAMT,AAAmB,kCAAsB;EACvC,IAAI;EACJ,UAAU,OAAO,KAAK,kBAAkB,GAAG;EAC5C,CAAC;;;;CAKF,AAAmB,iCAAqB;EACtC,IAAI;EACJ,UAAU,OAAO;AACf,UAAO,KAAK,iBAAiB,GAAG;;EAEnC,CAAC;;;;;;CAOF,MAAa,kBACX,kBACe;EACf,MAAM,EAAE,KAAK,QAAQ;EACrB,MAAM,EAAE,OAAO,WAAW,KAAK,OAAO,MAAM,IAAI,IAAI,SAAS,IAAI,MAAM;AAEvE,MAAI,KAAK,eAAe,IAAI,KAAK,OAAO,OAAO,CAC7C;AAGF,MAAI,CAAC,OAAO;AAGV,OAAI,UAAU,KAAK,EAAE,gBAAgB,cAAc,CAAC;AACpD,OAAI,IAAI,YAAY;AACpB;;EAGF,MAAM,UAAW,IAAI,WAAW,EAAE;EAClC,MAAM,QAAQ,QAAQ,yBAAyB,UAAU,UAAU;EACnE,MAAM,MAAM,IAAI,IAAI,GAAG,MAAM,KAAK,QAAQ,OAAO,IAAI,MAAM;EAC3D,MAAM,QAAQ,OAAO,YAAY,IAAI,aAAa,SAAS,CAAC;EAG5D,MAAMC,UAA6B;GACjC,QAHc,IAAI,QAAQ,aAAa,IAAI;GAI3C;GACA;GACA,QAAQ,UAAU,EAAE;GACpB;GACA,KAAK,EAAE,MAAM,kBAAkB;GAChC;EAED,MAAM,WAAW,MAAM,MAAM,QAAQ,QAAQ,CAAC,YAAY;AACxD,UAAO;IACL,QAAQ;IACR,SAAS,EAAE,gBAAgB,cAAc;IACzC,MAAM,KAAK;IACZ;IACD;AAGF,MAAI,CAAC,SAAS,MAAM;AAClB,OAAI,UAAU,SAAS,QAAQ,SAAS,QAAQ,CAAC,KAAK;AACtD;;AAIF,MAAI,OAAO,SAAS,SAAS,YAAY,OAAO,SAAS,SAAS,KAAK,EAAE;AACvE,OAAI,UAAU,SAAS,QAAQ,SAAS,QAAQ,CAAC,IAAI,SAAS,KAAK;AACnE;;AAIF,MAAI,SAAS,gBAAgBC,sBAAU;AACrC,OAAI,UAAU,SAAS,QAAQ,SAAS,QAAQ;AAChD,YAAS,KAAK,KAAK,IAAI;AACvB;;AAIF,MAAI,SAAS,gBAAgB,gBAAgB;AAC3C,OAAI,UAAU,SAAS,QAAQ,SAAS,QAAQ;AAChD,OAAI;AACF,eAAW,MAAM,SAAS,SAAS,KACjC,KAAI,MAAM,MAAM;YAEX,OAAO;AACd,SAAK,IAAI,MAAM,sCAAsC,MAAM;aACnD;AACR,QAAI,KAAK;;AAEX;;AAKF,OAAK,IAAI,MAAM,+BAA+B,OAAO,SAAS,KAAK;AACnE,MAAI,UAAU,KAAK,EAAE,gBAAgB,cAAc,CAAC;AACpD,MAAI,IAAI,KAAK,2BAA2B;;;;;CAM1C,MAAa,iBAAiB,IAAoC;EAChE,MAAM,MAAM,GAAG;EACf,MAAM,MAAM,IAAI,IAAI,IAAI,IAAI;EAC5B,MAAM,EAAE,OAAO,WAAW,KAAK,OAAO,MACpC,IAAI,IAAI,SAAS,IAAI,WACtB;AAED,MAAI,KAAK,eAAe,IAAI,KAAK,OAAO,OAAO,CAC7C;AAGF,MAAI,CAAC,OAAO;AAGV,MAAG,MAAM,IAAI,SAAS,aAAa;IACjC,QAAQ;IACR,SAAS,EAAE,gBAAgB,cAAc;IAC1C,CAAC;AACF;;EAGF,MAAMC,UAAkC,EAAE;AAE1C,MAAI,QAAQ,SAAS,OAAO,QAAQ;AAClC,WAAQ,OAAO;IACf;EAEF,MAAM,QAAQ,OAAO,YAAY,IAAI,aAAa,SAAS,CAAC;EAE5D,MAAMF,UAA6B;GACjC,QAFc,IAAI,OAAO,aAAa,IAAI;GAG1C;GACA;GACA,QAAQ,UAAU,EAAE;GACpB;GACA,KAAK,EAAE,KAAK,IAAI;GACjB;EAED,MAAM,WAAW,MAAM,MAAM,QAAQ,QAAQ,CAAC,YAAY;AACxD,UAAO;IACL,QAAQ;IACR,SAAS,EAAE,gBAAgB,cAAc;IACzC,MAAM,KAAK;IACZ;IACD;AAGF,MAAI,CAAC,SAAS,MAAM;AAClB,MAAG,MAAM,IAAI,SAAS,MAAM;IAC1B,QAAQ,SAAS;IACjB,SAAS,SAAS;IACnB,CAAC;AACF;;AAIF,MAAI,OAAO,SAAS,SAAS,UAAU;AACrC,MAAG,MAAM,IAAI,SAAS,SAAS,MAAM;IACnC,QAAQ,SAAS;IACjB,SAAS,SAAS;IACnB,CAAC;AACF;;AAGF,MAAI,OAAO,SAAS,SAAS,KAAK,EAAE;AAClC,MAAG,MAAM,IAAI,SAAS,SAAS,KAAK,QAAuB;IACzD,QAAQ,SAAS;IACjB,SAAS,SAAS;IACnB,CAAC;AACF;;AAIF,MAAI,SAAS,gBAAgBC,sBAAU;AACrC,MAAG,MAAM,IAAI,SAASA,qBAAS,MAAM,SAAS,KAAK,EAAoB;IACrE,QAAQ,SAAS;IACjB,SAAS,SAAS;IACnB,CAAC;AACF;;AAIF,MAAI,SAAS,gBAAgB,gBAAgB;AAC3C,MAAG,MAAM,IAAI,SAAS,SAAS,MAAM;IACnC,QAAQ,SAAS;IACjB,SAAS,SAAS;IACnB,CAAC;AACF;;AAIF,OAAK,IAAI,MAAM,+BAA+B,OAAO,SAAS,OAAO;AACrE,KAAG,MAAM,IAAI,SAAS,KAAK,4BAA4B;GACrD,QAAQ;GACR,SAAS,EAAE,gBAAgB,cAAc;GAC1C,CAAC;;;;;CAMJ,AAAU,eACR,KACA,OACA,QACS;AACT,MAAI,KAAK,OAAO,WAAW,EAAE;AAC3B,OAAI,CAAC,MACH,QAAO;AAGT,SAAM,KAAK,MAAM,IAAI,CAAC;AAEtB,OAAI,CAAC,CAAC,SAAS,QAAQ,IAAI,SAAS,WAAW,IAC7C,QAAO;;AAIX,SAAO;;;;;;AChQX,MAAa,cAAcE,SAAE,OAC3B;CACE,OAAOA,SAAE,KAAK,EAAE,aAAa,mBAAmB,CAAC;CACjD,QAAQA,SAAE,QAAQ,EAChB,aAAa,oBACd,CAAC;CACF,SAASA,SAAE,KAAK;EACd,aAAa;EACb,MAAM;EACP,CAAC;CACF,SAASA,SAAE,SACTA,SAAE,KAAK;EACL,aAAa;EACb,MAAM;EACP,CAAC,CACH;CACD,WAAWA,SAAE,SAASA,SAAE,MAAM,CAAC;CAC/B,OAAOA,SAAE,SACPA,SAAE,OAAO;EACP,MAAMA,SAAE,MAAM;EACd,SAASA,SAAE,KAAK;GACd,aAAa;GACb,MAAM;GACP,CAAC;EACH,CAAC,CACH;CACF,EACD;CACE,OAAO;CACP,aAAa;CACd,CACF;;;;ACXD,IAAa,aAAb,MAAwB;CACtB,AAAmB,kCAAe;CAClC,AAAmB,6BAAiBC,cAAO;CAE3C,AAAgB,kCAAiC;CAEjD,AAAmB,kBAA6C,EAAE;CAElE,MAAa,YAAY,MAA+C;EACtE,MAAM,QAAQ,KAAK;EACnB,MAAM,UAAU,KAAK,WAAW,EAAE;EAClC,MAAM,SAAS,KAAK,UAAU,EAAE;EAChC,MAAM,OAAO,KAAK,QAAQ;EAE1B,MAAMC,UAAuB,EAC3B,GAAG,QAAQ,SACZ;EAED,MAAM,SAAS,MAAM;EACrB,MAAMC,UAAkC,EAAE;EAC1C,MAAM,MAAM,KAAK,IAAI,MAAM,OAAO,OAAO;AAEzC,QAAM,KAAK,OAAO,OAAO,KAAK,oBAAoB;GAChD;GACA;GACA;GACA;GACA;GACD,CAAC;AAEF,UAAQ,WAAW;AAEnB,QAAM,KAAK,KAAK,SAAS,SAAS,OAAO,OAAO;AAEhD,UAAQ,UAAU;GAChB,GAAG,OAAO;GACV,GAAG,OAAO,YAAY,IAAI,QAAQ,QAAQ,QAAQ,CAAC,SAAS,CAAC;GAC7D,GAAG;GACJ;AAED,SAAO,MAAM,KAAK,MAAM,KAAK;GAC3B,GAAG;GACH,QAAQ,MAAM;GACd,GAAG;GACJ,CAAC;;CAGJ,MAAa,MACX,KACA,UAAqC,EAAE,EACJ;EACnC,MAAM,UAAU;GACd,OAAO,QAAQ;GACf,QAAQ,QAAQ,QAAQ;GACxB,KAAK,QAAQ;GACd;AAED,UAAQ,WAAW;AAEnB,OAAK,IAAI,MAAM,WAAW;GACxB;GACA,QAAQ,QAAQ;GAChB,MAAM,QAAQ;GACd,SAAS,QAAQ;GACjB;GACD,CAAC;EAGF,MAAM,SAAS,MAAM,KAAK,MAAM,IAAI,IAAI;AACxC,MAAI,UAAU,QAAQ,WAAW,MAC/B,KAAI,OAAO,MAAM;AACf,WAAQ,UAAU,IAAI,QAAQ,QAAQ,QAAQ;AAC9C,OAAI,CAAC,QAAQ,QAAQ,IAAI,gBAAgB,CACvC,SAAQ,QAAQ,IAAI,iBAAiB,OAAO,KAAK;QAGnD,QAAO;GACL,MAAM,OAAO;GACb,QAAQ;GACR,YAAY;GACZ,SAAS,IAAI,SAAS;GACvB;AAIL,QAAM,KAAK,OAAO,OAAO,KAAK,sBAAsB;GAClD;GACA;GACA;GACD,CAAC;EAIF,MAAM,MACJ,QAAQ,OACR,KAAK,UAAU;GACb;GACA,QAAQ,QAAQ;GAChB,MAAM,QAAQ;GACf,CAAC;EAEJ,MAAM,WAAW,KAAK,gBAAgB;AACtC,MAAI,UAAU;AACZ,QAAK,IAAI,KAAK,2BAA2B,IAAI;AAC7C,UAAO;;AAGT,OAAK,gBAAgB,OAAO,MAAM,KAAK,QAAQ,CAC5C,KAAK,OAAO,aAAa;AACxB,QAAK,IAAI,MAAM,YAAY;IACzB;IACA,QAAQ,SAAS;IAClB,CAAC;GAEF,MAAMC,gBAA+B;IACnC,MAAM,MAAM,KAAK,aAAa,UAAU,QAAQ;IAChD,QAAQ,SAAS;IACjB,YAAY,SAAS;IACrB,SAAS,SAAS;IAClB,KAAK;IACN;AAED,OAAI,QAAQ,WAAW,OACrB;QAAI,QAAQ,MACV,OAAM,KAAK,MAAM,IACf,KACA,EAAE,MAAM,cAAc,MAAM,EAC5B,OAAO,QAAQ,UAAU,YAAY,SAAY,QAAQ,MAC1D;aACQ,CAAC,KAAK,OAAO,WAAW,EAAE;KAEnC,MAAM,OAAO,SAAS,QAAQ,IAAI,OAAO,IAAI;AAC7C,SAAI,KACF,OAAM,KAAK,MAAM,IAAI,KAAK;MAAE,MAAM,cAAc;MAAM;MAAM,CAAC;;;AAKnE,UAAO;IACP,CACD,cAAc;AACb,UAAO,KAAK,gBAAgB;IAC5B;AAEJ,SAAO,KAAK,gBAAgB;;CAG9B,AAAU,IACR,MACA,QACA,MACA;EACA,IAAI,MAAM;AAEV,MAAI,OAAO,OACT,QAAO,OAAO;AAGhB,SAAO,OAAO;AACd,QAAM,KAAK,cAAc,KAAK,QAAQ,KAAK;AAC3C,QAAM,KAAK,YAAY,KAAK,QAAQ,KAAK;AAEzC,SAAO;;CAGT,MAAgB,KACd,MACA,SACA,QACA,OAAiC,EAAE,EACnC;AAMA,MAJE,OAAO,KAAK,YAAY,YACxB,kBAAkB,KAAK,WACvB,KAAK,QAAQ,oBAAoB,yBAElB,YAAY,OAAO,EAAE;AACpC,OAAI,OAAO,KAAK,YAAY,YAAY,kBAAkB,KAAK,QAC7D,QAAO,KAAK,QAAQ;GAGtB,MAAM,WAAW,IAAI,UAAU;AAE/B,QAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC,EAAE;AAC1D,QAAI,OAAO,UAAU,UAAU;AAC7B,cAAS,OAAO,KAAK,MAAM;AAC3B;;AAEF,QAAI,iBAAiB,MAAM;AACzB,cAAS,OAAO,KAAK,MAAM;AAC3B;;AAEF,+BAAe,MAAM,CAEnB,UAAS,OACP,KACA,IAAI,KAAK,CAAC,MAAM,MAAM,aAAa,CAAC,EAAE,MAAM,MAAM,EAChD,MAAM,MAAM,MACb,CAAC,CACH;;AAIL,QAAK,OAAO;AAEZ;;AAGF,MAAI,CAAC,KAAK,QAAQ,OAAO,QAAQ,MAAM;AACrC,WAAQ,kBAAkB;AAC1B,QAAK,OAAO,KAAK,OAAO,MAAM,OAAO,OAAO,QAAQ,MAAM,KAAK,MAAM,EACnE,IAAI,UACL,CAAC;;;CAIN,MAAgB,aACd,UACA,SACc;AACd,MAAI,SAAS,WAAW,KAAK;GAC3B,IAAI,WAAW,SAAS;AACxB,OAAI,OAAO,WAAW,YACpB,YAAW,SAAS,QAAQ,OAAO,SAAS,QAAQ,GAAG;GAGzD,MAAM,SAAS,MAAM,KAAK,MAAM,IAAI,SAAS;AAC7C,OAAI,OACF,QAAO,OAAO;AAIhB,UAAO;;AAGT,MAAI,SAAS,WAAW,IACtB;AAGF,MAAI,KAAK,YAAY,SAAS,CAC5B,QAAO,KAAK,eAAe,SAAS;AAGtC,MAAI,SAAS,QAAQ,IAAI,eAAe,EAAE,WAAW,QAAQ,CAC3D,QAAO,MAAM,SAAS,MAAM;AAG9B,MAAI,SAAS,QAAQ,IAAI,eAAe,KAAK,oBAAoB;GAC/D,MAAM,OAAO,MAAM,SAAS,MAAM;AAElC,OAAI,SAAS,UAAU,KAAK;IAE1B,MAAM,QAAQ,IAAI,UADA,KAAK,OAAO,MAAM,OAAO,aAAa,KAAK,CACvB;AAEtC,UAAM,KAAK,OAAO,OAAO,KAAK,kBAAkB,EAC9C,OACD,CAAC;AAEF,UAAM;;AAGR,OAAI,QAAQ,OACV,QAAO,KAAK,OAAO,MAAM,OAAO,QAAQ,QAAQ,KAAK;AAGvD,UAAO;;AAGT,MAAI,SAAS,UAAU,KAAK;GAC1B,MAAM,QAAQ,IAAI,UAAU;IAC1B,QAAQ,SAAS;IACjB,SAAS,mDAAmD,SAAS,WAAW;IACjF,CAAC;AAEF,SAAM,KAAK,OAAO,OAAO,KAAK,kBAAkB,EAC9C,OACD,CAAC;AAEF,SAAM;;AAGR,SAAO;;CAGT,AAAU,YAAY,UAA6B;EACjD,MAAM,cAAc,SAAS,QAAQ,IAAI,eAAe;AACxD,MAAI,CAAC,YACH,QAAO;AAGT,MAAI,SAAS,QAAQ,IAAI,sBAAsB,EAAE,SAAS,aAAa,CACrE,QAAO;AAGT,SACE,YAAY,WAAW,2BAA2B,IAClD,YAAY,WAAW,kBAAkB,IACzC,YAAY,WAAW,kBAAkB,IACzC,YAAY,WAAW,SAAS,IAChC,YAAY,WAAW,SAAS,IAChC,YAAY,WAAW,SAAS;;CAIpC,AAAU,eAAe,UAAoB,kBAAkB,IAAc;EAC3E,MAAM,SAAS,SAAS,QAAQ,IAAI,sBAAsB,IAAI,IAAI,MAChE,kBACD;AACD,SAAO;GACL,MAAM,QAAQ,KAAK,MAAM,KAAK;GAC9B,MAAM,SAAS,QAAQ,IAAI,eAAe,IAAI;GAC9C,MAAM,OAAO,SAAS,QAAQ,IAAI,iBAAiB,IAAI,EAAE;GACzD,cAAc,KAAK,KAAK;GACxB,cAAc;AACZ,UAAM,IAAI,MAAM,kBAAkB;;GAEpC,aAAa,YAAY;AACvB,WAAO,MAAM,SAAS,aAAa;;GAErC,MAAM,YAAY;AAChB,WAAO,MAAM,SAAS,MAAM;;GAE/B;;CAGH,AAAO,cACL,KACA,QACA,OAAiC,EAAE,EAC3B;AACR,MAAI,OAAO,KAAK,WAAW,UAAU;GACnC,MAAM,SAAS,OAAO,QAAQ,SACzB,KAAK,OAAO,MAAM,OACjB,OAAO,OAAO,QACd,KAAK,OACN,GACD,KAAK;AAET,QAAK,MAAM,OAAO,OAAO,KAAK,OAAO,EAAE;AACrC,UAAM,IAAI,QAAQ,IAAI,OAAO,OAAO,KAAK;AACzC,UAAM,IAAI,QAAQ,IAAI,IAAI,IAAI,OAAO,KAAK;;;AAI9C,SAAO;;CAGT,AAAO,YACL,KACA,QACA,OAAiC,EAAE,EAC3B;AACR,MAAI,OAAO,KAAK,UAAU,UAAU;GAClC,MAAM,QAAQ,OAAO,QAAQ,QACzB,KAAK,OAAO,MAAM,OAAO,OAAO,OAAO,OAAO,KAAK,SAAS,EAAE,CAAC,GAC/D,KAAK;AAET,QAAK,MAAM,OAAO,OAAO,KAAK,MAAM,EAAE;AACpC,QAAI,MAAM,SAAS,OACjB,QAAO,MAAM;AAEf,QAAI,OAAO,MAAM,SAAS,SACxB,OAAM,OAAO,KAAK,UAAU,MAAM,KAAK;;AAI3C,UAAO,GAAG,IAAI,GAAG,IAAI,gBACnB,MACD,CAAC,UAAU;;AAEd,SAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxSX,MAAa,WACX,YACgC;CAChC,MAAM,wCAA4B,kBAA2B,QAAQ;CACrE,MAAM,MACJ,QACA,cACG;AACH,SAAO,SAAS,IAAI,QAAQC,UAAQ;;AAEtC,QAAO,eAAe,IAAI,QAAQ,EAChC,MAAc;AACZ,SAAO,SAAS,QAAQ,QAAQ,SAAS,OAAO;IAEnD,CAAC;AACF,QAAO,OAAO,eAAe,IAAI,SAAS;;AAkF5C,MAAMC,cAAYC,SAAE,OAAO,EACzB,mBAAmBA,SAAE,KAAK;CACxB,aAAa;CACb,SAAS;CACV,CAAC,EACH,CAAC;AAEF,IAAa,mBAAb,cAEUC,kBAA6C;CACrD,AAAmB,kCAAe;CAClC,AAAmB,uBAAWF,YAAU;CACxC,AAAmB,iCAAqB,WAAW;CACnD,AAAmB,qCAAyB,eAAe;CAC3D,AAAmB,2CAA+B,qBAAqB;CAEvE,AAAU,SAAS;AACjB,MAAI,KAAK,QAAQ,UAAU;AACzB,QAAK,IAAI,MACP,WAAW,KAAK,KAAK,kDACtB;AACD;;AAEF,OAAK,qBAAqB,YAAY,KAAK,MAAM;;CAGnD,IAAW,SAAS;AAClB,SAAO,KAAK,IAAI;;CAGlB,IAAW,QAAqB;AAC9B,SAAO;GACL,GAAI,KAAK;GACT,QAAQ,KAAK;GACb,MAAM,GAAG,KAAK,SAAS,KAAK;GAC7B;;;;;CAMH,IAAW,OAAe;AACxB,SAAO,KAAK,QAAQ,QAAQ,KAAK,OAAO;;;;;CAM1C,IAAW,QAAgB;AACzB,SAAO,KAAK,QAAQ,SAAS,KAAK,OAAO,QAAQ;;;;;CAMnD,IAAW,SAAsB;AAC/B,SAAO,KAAK,QAAQ,WAAW,KAAK,QAAQ,QAAQ,OAAO,SAAS;;;;;;;CAQtE,IAAW,OAAe;AACxB,MAAI,KAAK,QAAQ,KACf,QAAO,KAAK,QAAQ;EAGtB,IAAI,OAAO,IAAI,KAAK;AAEpB,MAAI,KAAK,QAAQ,QAAQ,OACvB,MAAK,MAAM,CAAC,QAAQ,OAAO,QACzB,KAAK,QAAQ,OAAO,OAAO,WAC5B,CACC,SAAQ,KAAK;AAIjB,SAAO;;CAGT,IAAW,SAA8B;AACvC,SAAO,KAAK,QAAQ;;CAGtB,AAAO,qBAAyC;AAC9C,MAAI,KAAK,QAAQ,QAAQ,MAAM;AAE7B,OAAI,YAAY,KAAK,QAAQ,CAC3B,QAAO;AAGT,OAAIC,SAAE,OAAO,SAAS,KAAK,QAAQ,OAAO,KAAK,CAE7C,QAAO;AAGT,OACEA,SAAE,OAAO,SAAS,KAAK,QAAQ,OAAO,KAAK,IAC3CA,SAAE,OAAO,QAAQ,KAAK,QAAQ,OAAO,KAAK,IAC1CA,SAAE,OAAO,SAAS,KAAK,QAAQ,OAAO,KAAK,CAG3C,QAAO;;;;;;;CAQb,MAAa,IACX,QACA,UAAgC,EAAE,EACO;EACzC,MAAM,UAAU,KAAK,QAAQ;EAC7B,MAAM,EACJ,MACA,SAAS,EAAE,EACX,QAAQ,EAAE,EACV,UAAU,EAAE,KACT,UAAU,EAAE;EACjB,MAAM,QAAQ,IAAI,aAAa;EAM/B,MAAME,sBAA8C;GAClD,QANa,KAAK;GAOlB,KAJU,IAAI,IAAI,mBAAmB,KAAK,QAAQ,KAAK;GAKvD;GACA;GACA;GACA;GACA;GACA,UAAU,EAAE;GACb;AAED,QAAM,KAAK,OAAO,OAAO,KAAK,oBAAoB;GAChD,QAAQ;GACR,SAAS;GACT;GACD,CAAC;AAEF,MAAI,oBAAoB,OAAO,KAC7B,QAAO,oBAAoB,MAAM;AAGnC,MAAI,oBAAoB,SAAS,KAAK,QAAQ,QAAQ,MACpD,qBAAoB,QAAQ,KAAK,OAAO,MAAM,OAC5C,KAAK,QAAQ,OAAO,OACpB,oBAAoB,MACrB;AAGH,MAAI,oBAAoB,WAAW,KAAK,QAAQ,QAAQ,QACtD,qBAAoB,UAAU,KAAK,OAAO,MAAM,OAC9C,KAAK,QAAQ,OAAO,SACpB,oBAAoB,QACrB;AAGH,MAAI,oBAAoB,QAAQ,KAAK,QAAQ,QAAQ,KACnD,qBAAoB,OAAO,KAAK,OAAO,MAAM,OAC3C,KAAK,QAAQ,OAAO,MACpB,oBAAoB,KACrB;AAGH,MAAI,oBAAoB,UAAU,KAAK,QAAQ,QAAQ,OACrD,qBAAoB,SAAS,KAAK,OAAO,MAAM,OAC7C,KAAK,QAAQ,OAAO,QACpB,oBAAoB,OACrB;AAGH,OAAK,qBAAqB,gBACxB,KAAK,SACL,oBACD;EAED,IAAIC,WAAgB,MAAM,QACxB,oBACD;AAGD,MACE,KAAK,QAAQ,QAAQ,YAErB,wBAAY,KAAK,QAAQ,OAAO,SAAS,CAEzC,YAAW,KAAK,OAAO,MAAM,SAC3B,KAAK,QAAQ,OAAO,UACpB,SACD;AAGH,QAAM,KAAK,OAAO,OAAO,KAAK,qBAAqB;GACjD,QAAQ;GACR,SAAS;GACT;GACA;GACD,CAAC;AAEF,SAAO;;;;;CAMT,AAAO,MACL,QACA,SACwD;AACxD,SAAO,KAAK,WAAW,YAAY;GACjC,MAAM,KAAK,eAAe;GAC1B,QAAQ;GACR;GACA;GACD,CAAC;;;AAYN,QAAQC,eAAQ;;;;;;;;;;;;AC3ZhB,MAAa,UACX,YAC6B;AAC7B,qCAAwB,iBAA0B,QAAQ;;AAW5D,IAAa,kBAAb,cAEUC,kBAA4C;CACpD,AAAmB,2CAA+B,qBAAqB;CAEvE,AAAU,SAAS;AACjB,OAAK,qBAAqB,YAAY,KAAK,QAAQ;;;AAIvD,OAAOC,eAAQ;;;;ACjCf,MAAMC,cAAYC,SAAE,OAAO;CACzB,aAAaA,SAAE,QAAQ;EACrB,SAAS;EACT,KAAK;EACL,KAAK;EACL,aAAa;EACd,CAAC;CACF,aAAaA,SAAE,KAAK;EAClB,SAAS;EACT,aAAa;EACd,CAAC;CACH,CAAC;AASF,IAAa,wBAAb,cAA2C,eAAe;CACxD,AAAmB,6BAAiBC,cAAO;CAC3C,AAAmB,uCAA2BC,iCAAiB;CAC/D,AAAmB,kCAAe;CAClC,AAAmB,uBAAWH,YAAU;CACxC,AAAmB,6BAAiB,qBAAqB;CAEzD,AAAU;CAEV,IAAW,WAAmB;AAC5B,MAAI,KAAK,UACP,QAAO,UAAU,KAAK,UAAU,SAAS,GAAG,KAAK,UAAU;AAE7D,SAAO,UAAU,KAAK,IAAI,YAAY,GAAG,KAAK,IAAI;;CAGpD,AAAgB,0BAAc;EAC5B,IAAI;EACJ,SAAS,YAAY;AACnB,SAAM,KAAK,QAAQ;;EAEtB,CAAC;CAEF,AAAmB,yBAAa;EAC9B,IAAI;EACJ,SAAS,YAAY;AACnB,OAAI,KAAK,OAAO,cAAc,EAAE;AAC9B,UAAM,KAAK,OAAO;AAClB;;AAIF,QAAK,OAAO,CAAC,YAAY,GAAG;;EAE/B,CAAC;CAEF,MAAgB,SAAS;EACvB,IAAI,OAAO,KAAK,IAAI;AAGpB,MAAI,KAAK,OAAO,QAAQ,IAAI,SAAS,IACnC,QAAO;AAGT,MAAI;AACF,QAAK,YAAY,IAAI,MAAM;IACzB;IACA,UAAU,KAAK,IAAI;IACnB,OAAO,OAAO,YAAqB;AACjC,UAAK,IAAI,MAAM,2BAA2B,QAAQ,MAAM;KAGxD,MAAM,kBAAkB;MACtB,KAAK;MACL,KAAK;MACN;AAED,SAAI;AACF,YAAM,KAAK,iBAAiB,gBAAgB;AAE5C,UAAI,CAAC,gBAAgB,IAEnB,QAAO,IAAI,SAAS,yBAAyB;OAC3C,QAAQ;OACR,SAAS,EAAE,gBAAgB,cAAc;OAC1C,CAAC;AAGJ,aAAO,gBAAgB;cAChB,KAAK;AACZ,WAAK,IAAI,MAAM,0BAA0B,IAAI;AAC7C,aAAO,IAAI,SAAS,yBAAyB;OAC3C,QAAQ;OACR,SAAS,EAAE,gBAAgB,cAAc;OAC1C,CAAC;;;IAGN,QAAQ,UAAiB;AACvB,UAAK,IAAI,MAAM,oBAAoB,MAAM;AACzC,YAAO,IAAI,SAAS,yBAAyB;MAC3C,QAAQ;MACR,SAAS,EAAE,gBAAgB,cAAc;MAC1C,CAAC;;IAEL,CAAC;AAEF,QAAK,IAAI,KAAK,uBAAuB,KAAK,WAAW;WAC9C,KAAK;AACZ,QAAK,IAAI,MAAM,8BAA8B,IAAI;AACjD,SAAM;;;CAIV,MAAgB,QAAQ;AACtB,MAAI,CAAC,KAAK,UACR;AAGF,MAAI;GAEF,MAAM,cAAc,KAAK,UAAU,MAAM;AAGzC,SAAM,QAAQ,KAAK,CAAC,KAAK,iBAAiB,KAAK,IAAM,EAAE,YAAY,CAAC;AAEpE,QAAK,YAAY;AACjB,QAAK,IAAI,KAAK,gBAAgB;WACvB,KAAK;AACZ,QAAK,IAAI,MAAM,4BAA4B,IAAI;AAC/C,SAAM;;;;;;;AC3HZ,MAAMI,cAAYC,SAAE,OAAO;CACzB,aAAaA,SAAE,QAAQ;EACrB,SAAS;EACT,KAAK;EACL,KAAK;EACL,aAAa;EACd,CAAC;CACF,aAAaA,SAAE,KAAK;EAClB,SAAS;EACT,aAAa;EACd,CAAC;CACH,CAAC;AAMF,IAAa,yBAAb,cAA4C,eAAe;CACzD,AAAmB,6BAAiBC,cAAO;CAC3C,AAAmB,uCAA2BC,iCAAiB;CAC/D,AAAmB,kCAAe;CAClC,AAAmB,uBAAWH,YAAU;CACxC,AAAmB,6BAAiB,qBAAqB;CAEzD,IAAW,WAAmB;AAC5B,MAAI,KAAK,OAAO,WAAW;GACzB,MAAM,UAAU,KAAK,OAAO,SAAS;AACrC,OAAI,OAAO,YAAY,YAAY,YAAY,KAC7C,QAAO,UAAU,KAAK,IAAI,YAAY,GAAG,QAAQ;;AAGrD,SAAO,UAAU,KAAK,IAAI,YAAY,GAAG,KAAK,IAAI;;CAGpD,AAAgB,SAAS,KAAK,kBAAkB,KAAK,QAAQ;AAC3D,OAAK,IAAI,MAAM,+BAA+B,IAAI,MAAM;AACxD,OAAK,kBAAkB;GAAE;GAAK;GAAK,CAAC,CAAC,OAAO,QAAQ;AAClD,QAAK,IAAI,MAAM,0BAA0B,IAAI;AAC7C,OAAI,aAAa;AACjB,OAAI,IAAI,wBAAwB;IAChC;GACF;CAEF,AAAgB,0BAAc;EAC5B,IAAI;EACJ,SAAS,YAAY;AACnB,SAAM,KAAK,QAAQ;AACnB,QAAK,OAAO,MAAM,IAAI,sBAAsB,KAAK,OAAO;;EAE3D,CAAC;CAEF,AAAU,iBACR,MACQ;AACR,qCACE,EAEE,WAAW,MACZ,EACD,KACD;;CAGH,AAAmB,yBAAa;EAC9B,IAAI;EACJ,SAAS,YAAY;AACnB,OAAI,KAAK,OAAO,cAAc,EAAE;AAC9B,UAAM,KAAK,OAAO;AAClB;;AAIF,QAAK,OAAO,CAAC,YAAY,GAAG;;EAE/B,CAAC;CAEF,MAAgB,SAAS;EACvB,IAAI,OAAO,KAAK,IAAI;AAGpB,MAAI,KAAK,OAAO,QAAQ,IAAI,SAAS,IACnC,QAAO;AAGT,QAAM,IAAI,SAAe,SAAS,WAAW;AAC3C,QAAK,QAAQ,OAAO,MAAM,KAAK,IAAI,mBAAmB;AACpD,SAAK,IAAI,KAAK,uBAAuB,KAAK,WAAW;AACrD,aAAS;KACT;AAEF,QAAK,QAAQ,GAAG,UAAU,QAAQ;AAChC,WAAO,IAAI;KACX;IACF;;CAGJ,MAAgB,QAAQ;EACtB,MAAM,UAAU,IAAI,SAAe,SAAS,WAAW;AACrD,QAAK,QAAQ,OAAO,QAAQ;AAC1B,QAAI,IACF,QAAO,IAAI;QAEX,UAAS;KAEX;IACF;AAEF,QAAM,QAAQ,KAAK,CAAC,KAAK,iBAAiB,KAAK,IAAK,EAAE,QAAQ,CAAC;AAE/D,OAAK,IAAI,KAAK,gBAAgB;;;;;;ACnHlC,MAAM,YAAYI,SAAE,OAAO;CACzB,4BAA4BA,SAAE,QAAQ;EACpC,SAAS;EACT,aAAa;EACd,CAAC;CACF,0BAA0BA,SAAE,QAAQ;EAClC,SAAS;EACT,KAAK;EACL,aAAa;EACd,CAAC;CACH,CAAC;AAEF,IAAa,2BAAb,MAAsC;CACpC,AAAmB,uBAAW,UAAU;CACxC,AAAmB,6BAAiBC,cAAO;CAC3C,AAAmB,kCAAe;CAElC,AAAgB,8BAAkB;EAChC,IAAI;EACJ,SAAS,OAAO,EAAE,OAAO,cAAc;AACrC,OAAI,QAAQ,KACV;GAGF,IAAIC;AAEJ,OAAI,QAAQ,IAAI,KAAK,IAAI,KACvB,UAAS,QAAQ,IAAI,IAAI,IAAI;YACpB,QAAQ,IAAI,MAAM,IAG3B,UAASC,+BAAU,KAAK,QAAQ,IAAI,KAAK,IAAI;AAG/C,OAAI,CAAC,OACH;AAGF,OAAI,MAAM,QAAQ,KAChB,KAAI;IACF,MAAM,OAAO,MAAM,KAAK,MAAM,QAAQ,QAAQ,QAAQ;AACtD,QAAI,KACF,SAAQ,OAAO;YAEV,OAAO;AACd,QAAI,iBAAiB,UACnB,OAAM;AAGR,UAAM,IAAI,UACR;KACE,QAAQ;KACR,SAAS;KACV,EACD,MACD;;;EAIR,CAAC;CAEF,MAAa,MACX,QACA,SACsC;EACtC,MAAM,cAAc,QAAQ;EAC5B,MAAM,kBAAkB,QAAQ;AAEhC,MAAI,CAAC,YAAa,QAAO;AAEzB,MAAI,YAAY,WAAW,mBAAmB,CAC5C,QAAO,KAAK,UAAU,QAAQ,gBAAgB;AAGhD,MAAI,YAAY,WAAW,aAAa,CACtC,QAAO,KAAK,UAAU,QAAQ,gBAAgB;AAGhD,MAAI,YAAY,WAAW,oCAAoC,CAC7D,QAAO,KAAK,gBAAgB,QAAQ,gBAAgB;;CAMxD,MAAa,UACX,QACA,iBACiB;EACjB,MAAM,SAAS,MAAM,KAAK,eAAe,OAAO;AAEhD,UADuB,MAAM,KAAK,gBAAgB,QAAQ,gBAAgB,EACpD,SAAS,QAAQ;;CAGzC,MAAa,gBACX,QACA,iBACiB;EACjB,MAAM,OAAO,MAAM,KAAK,UAAU,QAAQ,gBAAgB;EAC1D,MAAM,SAAS,IAAI,gBAAgB,KAAK;EACxC,MAAMC,SAAiC,EAAE;AACzC,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,SAAS,CACzC,QAAO,OAAO;AAGhB,SAAO;;CAGT,MAAa,UACX,QACA,iBACiB;EACjB,MAAM,OAAO,MAAM,KAAK,UAAU,QAAQ,gBAAgB;AAC1D,SAAO,KAAK,MAAM,KAAK;;CAGzB,MAAgB,gBACd,QACA,UACiB;AACjB,MAAI,CAAC,KAAK,IAAI,8BAA8B,SAC1C,OAAM,IAAI,UAAU;GAClB,QAAQ;GACR,SAAS,oBAAoB,SAAS;GACvC,CAAC;AAGJ,UAAQ,UAAR;GACE,KAAK,OACH,QAAO,IAAI,SAAS,KAAK,qCACT,CACX,IAAI,cAAc,GAAG,CACrB,GAAG,QAAQ,IAAI,CACf,GAAG,SAAS,IAAI,CACpB;GACH,KAAK,UACH,QAAO,IAAI,SAAS,KAAK,sCACR,CACZ,IAAI,cAAc,GAAG,CACrB,GAAG,QAAQ,IAAI,CACf,GAAG,SAAS,IAAI,CACpB;GACH,KAAK,KACH,QAAO,IAAI,SAAS,KAAK,+CACC,CACrB,IAAI,cAAc,GAAG,CACrB,GAAG,QAAQ,IAAI,CACf,GAAG,SAAS,IAAI,CACpB;GACH,KAAK;GACL,KAAK,WACH,QAAO;GACT,QACE,OAAM,IAAI,MAAM,iCAAiC,WAAW;;;;;;;;CASlE,MAAgB,eAAe,QAAyC;EACtE,MAAMC,SAAuB,EAAE;EAC/B,IAAI,cAAc;EAElB,MAAM,SAAS,OAAO,WAAW;AAEjC,MAAI;AACF,UAAO,MAAM;IACX,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAE3C,QAAI,KACF;AAGF,QAAI,OAAO;AACT,oBAAe,MAAM;AAErB,SAAI,cAAc,KAAK,IAAI,0BAA0B;AACnD,WAAK,IAAI,MACP,6BAA6B,YAAY,KAAK,KAAK,IAAI,2BACxD;AAED,YAAM,OAAO,QAAQ;AAErB,YAAM,IAAI,UAAU;OAClB,QAAQ;OACR,SAAS;OACV,CAAC;;AAGJ,YAAO,KAAK,MAAM;;;GAKtB,MAAM,iBAAiB,OAAO,QAC3B,KAAK,UAAU,MAAM,MAAM,QAC5B,EACD;GACD,MAAM,WAAW,IAAI,WAAW,eAAe;GAC/C,IAAI,SAAS;AAEb,QAAK,MAAM,SAAS,QAAQ;AAC1B,aAAS,IAAI,OAAO,OAAO;AAC3B,cAAU,MAAM;;AAGlB,UAAO,OAAO,KAAK,SAAS;WACrB,OAAO;AAEd,UAAO,aAAa;AACpB,SAAM;;;;;;;ACxNZ,IAAa,uBAAb,MAAkC;CAChC,AAAmB,kCAAe;CAClC,AAAmB,6BAAiBC,cAAO;CAE3C,AAAgB,8BAAkB;EAChC,IAAI;EACJ,UAAU;EACV,UAAU,EAAE,OAAO,cAAc;AAC/B,OAAI,CAAC,MAAM,QAAQ;AACjB,YAAQ,SAAS,MAAM,KAAK,KAAK;IAEjC,MAAMC,OAA+B;KACnC,QAAQ,QAAQ;KAChB,MAAM,QAAQ,IAAI;KACnB;AAED,QAAI,KAAK,OAAO,cAAc,EAAE;AAC9B,UAAK,QAAQ,QAAQ,QAAQ;KAC7B,MAAM,KAAK,QAAQ;AACnB,SAAI,GACF,MAAK,KAAK;;AAId,SAAK,IAAI,KAAK,oBAAoB,KAAK;;;EAG5C,CAAC;CAEF,AAAgB,4BAAgB;EAC9B,IAAI;EACJ,UAAU;EACV,UAAU,EAAE,YAAY;AACtB,QAAK,IAAI,MAAM,sBAAsB,MAAM;;EAE9C,CAAC;CAEF,AAAgB,+BAAmB;EACjC,IAAI;EACJ,UAAU;EACV,UAAU,EAAE,OAAO,SAAS,eAAe;AACzC,OAAI,CAAC,MAAM,QAAQ;IACjB,MAAM,KAAK,KAAK,KAAK,GAAG,QAAQ,SAAS;AACzC,SAAK,IAAI,KAAK,qBAAqB;KAAE,QAAQ,SAAS;KAAQ;KAAI,CAAC;;;EAGxE,CAAC;;;;;;;;;;;;ACvCJ,IAAa,yBAAb,MAAoC;CAClC,AAAmB,6BAAiBC,cAAO;CAE3C,AAAgB,8BAAkB;EAChC,IAAI;EACJ,UAAU;EACV,UAAU,EAAE,SAAS,EAAE,cAAc;AACnC,OAAI,KAAK,OAAO,SAAS,CACvB;AAGF,SAAM,QAAQ,iBAAiB;AAE/B,SAAM,IAAI,UAAU;IAClB,QAAQ;IACR,SAAS;IACV,CAAC;;EAEL,CAAC;;;;;AC5BJ,MAAa,eAAe;CAE1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;ACTD,IAAa,kBAAb,cAAqC,UAAU;CAC7C,YAAY,UAAU,wBAAwB,OAAiB;AAC7D,QACE;GACE;GACA,QAAQ;GACT,EACD,MACD;;;;;;ACRL,IAAa,gBAAb,cAAmC,UAAU;CAC3C,YAAY,UAAU,yBAAyB,OAAiB;AAC9D,QACE;GACE;GACA,QAAQ;GACT,EACD,MACD;;;;;;ACRL,IAAa,iBAAb,cAAoC,UAAU;CAC5C,YACE,UAAU,yCACV,OACA;AACA,QACE;GACE;GACA,QAAQ;GACT,EACD,MACD;;;;;;ACXL,IAAa,gBAAb,cAAmC,UAAU;CAC3C,YAAY,UAAU,sBAAsB,OAAiB;AAC3D,QACE;GACE;GACA,QAAQ;GACT,EACD,MACD;;;;;;ACRL,IAAa,oBAAb,cAAuC,UAAU;CAC/C,AAAS,OAAO;CAEhB,YACE,UAAU,uCACV,OACA;AACA,QACE;GACE;GACA,QAAQ;GACT,EACD,MACD;;;;;;ACZL,MAAa,WAAWC,SAAE,OACxB;CACE,IAAIA,SAAE,QAAQ,EAAE,aAAa,+BAA+B,CAAC;CAC7D,IAAIA,SAAE,SAASA,SAAE,MAAM,CAACA,SAAE,MAAM,EAAEA,SAAE,SAAS,CAAC,CAAC,CAAC;CAChD,OAAOA,SAAE,SACPA,SAAE,OAAO,EAAE,aAAa,gCAAgC,CAAC,CAC1D;CACF,EACD;CACE,OAAO;CACP,aAAa;CACd,CACF;;;;;;;;;;;;;;;AC2GD,MAAa,mCAAuB;CAClC,MAAM;CACN,aAAa,CAAC,QAAQ,QAAiC;CACvD,UAAU;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,WAAW,aAAmB;AAC5B,MAAI,CAACC,SAAO,cAAc,IAAI,CAACA,SAAO,WAAW,CAC/C,KAAIA,SAAO,OAAO,CAChB,UAAO,KAAK;GACV,UAAU;GACV,SAAS;GACT,KAAK;GACN,CAAC;MAEF,UAAO,KAAK;GACV,UAAU;GACV,SAAS;GACT,KAAK;GACN,CAAC;MAGJ,UAAO,KAAK,eAAe;AAG7B,WAAO,KAAK,yBAAyB;AACrC,WAAO,KAAK,qBAAqB;AACjC,WAAO,KAAK,uBAAuB;AAEnC,MAAI,CAACA,SAAO,cAAc,CACxB,UAAO,KAAK,qBAAqB;;CAGtC,CAAC"}