awaitly 1.35.0 → 2.0.0

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 (241) hide show
  1. package/dist/{duration.d.ts → di-BDlT7InM.d.cts} +15 -1
  2. package/dist/{duration.d.cts → di-BbFFfO8y.d.ts} +15 -1
  3. package/dist/errors-DtXvrCiO.d.cts +708 -0
  4. package/dist/errors-DtXvrCiO.d.ts +708 -0
  5. package/dist/index.cjs +4594 -1
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.cts +1970 -141
  8. package/dist/index.d.ts +1970 -141
  9. package/dist/index.js +4398 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/result.cjs +641 -1
  12. package/dist/result.cjs.map +1 -1
  13. package/dist/result.d.cts +29 -4
  14. package/dist/result.d.ts +29 -4
  15. package/dist/result.js +561 -1
  16. package/dist/result.js.map +1 -1
  17. package/dist/testing.cjs +4202 -8
  18. package/dist/testing.cjs.map +1 -1
  19. package/dist/testing.d.cts +2 -6
  20. package/dist/testing.d.ts +2 -6
  21. package/dist/testing.js +4154 -8
  22. package/dist/testing.js.map +1 -1
  23. package/dist/{run-entry-DGs0tySr.d.cts → types-B8NfNRGX.d.ts} +1078 -1502
  24. package/dist/{run-entry-BOuNyVoO.d.ts → types-BZ2f4MRR.d.cts} +1078 -1502
  25. package/dist/workflow.cjs +7096 -6
  26. package/dist/workflow.cjs.map +1 -1
  27. package/dist/workflow.d.cts +3346 -22
  28. package/dist/workflow.d.ts +3346 -22
  29. package/dist/workflow.js +6929 -6
  30. package/dist/workflow.js.map +1 -1
  31. package/package.json +3 -168
  32. package/dist/adapters.cjs +0 -7
  33. package/dist/adapters.cjs.map +0 -1
  34. package/dist/adapters.d.cts +0 -179
  35. package/dist/adapters.d.ts +0 -179
  36. package/dist/adapters.js +0 -7
  37. package/dist/adapters.js.map +0 -1
  38. package/dist/batch.cjs +0 -7
  39. package/dist/batch.cjs.map +0 -1
  40. package/dist/batch.d.cts +0 -200
  41. package/dist/batch.d.ts +0 -200
  42. package/dist/batch.js +0 -7
  43. package/dist/batch.js.map +0 -1
  44. package/dist/bind-deps.cjs +0 -2
  45. package/dist/bind-deps.cjs.map +0 -1
  46. package/dist/bind-deps.d.cts +0 -28
  47. package/dist/bind-deps.d.ts +0 -28
  48. package/dist/bind-deps.js +0 -2
  49. package/dist/bind-deps.js.map +0 -1
  50. package/dist/cache.cjs +0 -2
  51. package/dist/cache.cjs.map +0 -1
  52. package/dist/cache.d.cts +0 -269
  53. package/dist/cache.d.ts +0 -269
  54. package/dist/cache.js +0 -2
  55. package/dist/cache.js.map +0 -1
  56. package/dist/circuit-breaker.cjs +0 -7
  57. package/dist/circuit-breaker.cjs.map +0 -1
  58. package/dist/circuit-breaker.d.cts +0 -211
  59. package/dist/circuit-breaker.d.ts +0 -211
  60. package/dist/circuit-breaker.js +0 -7
  61. package/dist/circuit-breaker.js.map +0 -1
  62. package/dist/conditional.cjs +0 -2
  63. package/dist/conditional.cjs.map +0 -1
  64. package/dist/conditional.d.cts +0 -252
  65. package/dist/conditional.d.ts +0 -252
  66. package/dist/conditional.js +0 -2
  67. package/dist/conditional.js.map +0 -1
  68. package/dist/core.cjs +0 -7
  69. package/dist/core.cjs.map +0 -1
  70. package/dist/core.d.cts +0 -5
  71. package/dist/core.d.ts +0 -5
  72. package/dist/core.js +0 -7
  73. package/dist/core.js.map +0 -1
  74. package/dist/di-By77n4Fa.d.ts +0 -15
  75. package/dist/di-OJfsohf-.d.cts +0 -15
  76. package/dist/diagnostics.cjs +0 -8
  77. package/dist/diagnostics.cjs.map +0 -1
  78. package/dist/diagnostics.d.cts +0 -68
  79. package/dist/diagnostics.d.ts +0 -68
  80. package/dist/diagnostics.js +0 -8
  81. package/dist/diagnostics.js.map +0 -1
  82. package/dist/durable.cjs +0 -11
  83. package/dist/durable.cjs.map +0 -1
  84. package/dist/durable.d.cts +0 -9
  85. package/dist/durable.d.ts +0 -9
  86. package/dist/durable.js +0 -11
  87. package/dist/durable.js.map +0 -1
  88. package/dist/duration.cjs +0 -2
  89. package/dist/duration.cjs.map +0 -1
  90. package/dist/duration.js +0 -2
  91. package/dist/duration.js.map +0 -1
  92. package/dist/engine.cjs +0 -11
  93. package/dist/engine.cjs.map +0 -1
  94. package/dist/engine.d.cts +0 -115
  95. package/dist/engine.d.ts +0 -115
  96. package/dist/engine.js +0 -11
  97. package/dist/engine.js.map +0 -1
  98. package/dist/errors.cjs +0 -2
  99. package/dist/errors.cjs.map +0 -1
  100. package/dist/errors.d.cts +0 -361
  101. package/dist/errors.d.ts +0 -361
  102. package/dist/errors.js +0 -2
  103. package/dist/errors.js.map +0 -1
  104. package/dist/fetch.cjs +0 -7
  105. package/dist/fetch.cjs.map +0 -1
  106. package/dist/fetch.d.cts +0 -86
  107. package/dist/fetch.d.ts +0 -86
  108. package/dist/fetch.js +0 -7
  109. package/dist/fetch.js.map +0 -1
  110. package/dist/flow.cjs +0 -7
  111. package/dist/flow.cjs.map +0 -1
  112. package/dist/flow.d.cts +0 -163
  113. package/dist/flow.d.ts +0 -163
  114. package/dist/flow.js +0 -7
  115. package/dist/flow.js.map +0 -1
  116. package/dist/functional.cjs +0 -2
  117. package/dist/functional.cjs.map +0 -1
  118. package/dist/functional.d.cts +0 -444
  119. package/dist/functional.d.ts +0 -444
  120. package/dist/functional.js +0 -2
  121. package/dist/functional.js.map +0 -1
  122. package/dist/guards-4sV7mTqj.d.cts +0 -72
  123. package/dist/guards-BIX05ALH.d.ts +0 -72
  124. package/dist/hitl-DFn4Xa_l.d.cts +0 -468
  125. package/dist/hitl-DU5VpKq7.d.ts +0 -468
  126. package/dist/hitl.cjs +0 -7
  127. package/dist/hitl.cjs.map +0 -1
  128. package/dist/hitl.d.cts +0 -442
  129. package/dist/hitl.d.ts +0 -442
  130. package/dist/hitl.js +0 -7
  131. package/dist/hitl.js.map +0 -1
  132. package/dist/index-CnvBryQB.d.ts +0 -417
  133. package/dist/index-DEZEf8Fs.d.cts +0 -417
  134. package/dist/match-entry-DjI2bLpD.d.cts +0 -209
  135. package/dist/match-entry-DjI2bLpD.d.ts +0 -209
  136. package/dist/match.cjs +0 -2
  137. package/dist/match.cjs.map +0 -1
  138. package/dist/match.d.cts +0 -1
  139. package/dist/match.d.ts +0 -1
  140. package/dist/match.js +0 -2
  141. package/dist/match.js.map +0 -1
  142. package/dist/otel.cjs +0 -2
  143. package/dist/otel.cjs.map +0 -1
  144. package/dist/otel.d.cts +0 -188
  145. package/dist/otel.d.ts +0 -188
  146. package/dist/otel.js +0 -2
  147. package/dist/otel.js.map +0 -1
  148. package/dist/persistence-entry-B-8PjnSR.d.cts +0 -831
  149. package/dist/persistence-entry-D8zRkLiT.d.ts +0 -831
  150. package/dist/persistence.cjs +0 -2
  151. package/dist/persistence.cjs.map +0 -1
  152. package/dist/persistence.d.cts +0 -7
  153. package/dist/persistence.d.ts +0 -7
  154. package/dist/persistence.js +0 -2
  155. package/dist/persistence.js.map +0 -1
  156. package/dist/policies.cjs +0 -2
  157. package/dist/policies.cjs.map +0 -1
  158. package/dist/policies.d.cts +0 -379
  159. package/dist/policies.d.ts +0 -379
  160. package/dist/policies.js +0 -2
  161. package/dist/policies.js.map +0 -1
  162. package/dist/ratelimit.cjs +0 -7
  163. package/dist/ratelimit.cjs.map +0 -1
  164. package/dist/ratelimit.d.cts +0 -458
  165. package/dist/ratelimit.d.ts +0 -458
  166. package/dist/ratelimit.js +0 -7
  167. package/dist/ratelimit.js.map +0 -1
  168. package/dist/reliability.cjs +0 -11
  169. package/dist/reliability.cjs.map +0 -1
  170. package/dist/reliability.d.cts +0 -11
  171. package/dist/reliability.d.ts +0 -11
  172. package/dist/reliability.js +0 -11
  173. package/dist/reliability.js.map +0 -1
  174. package/dist/resolver.cjs +0 -7
  175. package/dist/resolver.cjs.map +0 -1
  176. package/dist/resolver.d.cts +0 -68
  177. package/dist/resolver.d.ts +0 -68
  178. package/dist/resolver.js +0 -7
  179. package/dist/resolver.js.map +0 -1
  180. package/dist/resource.cjs +0 -7
  181. package/dist/resource.cjs.map +0 -1
  182. package/dist/resource.d.cts +0 -174
  183. package/dist/resource.d.ts +0 -174
  184. package/dist/resource.js +0 -7
  185. package/dist/resource.js.map +0 -1
  186. package/dist/result/retry.cjs +0 -2
  187. package/dist/result/retry.cjs.map +0 -1
  188. package/dist/result/retry.d.cts +0 -70
  189. package/dist/result/retry.d.ts +0 -70
  190. package/dist/result/retry.js +0 -2
  191. package/dist/result/retry.js.map +0 -1
  192. package/dist/retry.cjs +0 -2
  193. package/dist/retry.cjs.map +0 -1
  194. package/dist/retry.d.cts +0 -388
  195. package/dist/retry.d.ts +0 -388
  196. package/dist/retry.js +0 -2
  197. package/dist/retry.js.map +0 -1
  198. package/dist/run.cjs +0 -7
  199. package/dist/run.cjs.map +0 -1
  200. package/dist/run.d.cts +0 -4
  201. package/dist/run.d.ts +0 -4
  202. package/dist/run.js +0 -7
  203. package/dist/run.js.map +0 -1
  204. package/dist/saga.cjs +0 -11
  205. package/dist/saga.cjs.map +0 -1
  206. package/dist/saga.d.cts +0 -164
  207. package/dist/saga.d.ts +0 -164
  208. package/dist/saga.js +0 -11
  209. package/dist/saga.js.map +0 -1
  210. package/dist/singleflight.cjs +0 -2
  211. package/dist/singleflight.cjs.map +0 -1
  212. package/dist/singleflight.d.cts +0 -145
  213. package/dist/singleflight.d.ts +0 -145
  214. package/dist/singleflight.js +0 -2
  215. package/dist/singleflight.js.map +0 -1
  216. package/dist/slugs.cjs +0 -2
  217. package/dist/slugs.cjs.map +0 -1
  218. package/dist/slugs.d.cts +0 -67
  219. package/dist/slugs.d.ts +0 -67
  220. package/dist/slugs.js +0 -2
  221. package/dist/slugs.js.map +0 -1
  222. package/dist/streaming.cjs +0 -9
  223. package/dist/streaming.cjs.map +0 -1
  224. package/dist/streaming.d.cts +0 -596
  225. package/dist/streaming.d.ts +0 -596
  226. package/dist/streaming.js +0 -9
  227. package/dist/streaming.js.map +0 -1
  228. package/dist/tagged-error.cjs +0 -2
  229. package/dist/tagged-error.cjs.map +0 -1
  230. package/dist/tagged-error.d.cts +0 -275
  231. package/dist/tagged-error.d.ts +0 -275
  232. package/dist/tagged-error.js +0 -2
  233. package/dist/tagged-error.js.map +0 -1
  234. package/dist/types-BziYHFkD.d.ts +0 -323
  235. package/dist/types-C5jLEUqY.d.cts +0 -323
  236. package/dist/webhook.cjs +0 -7
  237. package/dist/webhook.cjs.map +0 -1
  238. package/dist/webhook.d.cts +0 -499
  239. package/dist/webhook.d.ts +0 -499
  240. package/dist/webhook.js +0 -7
  241. package/dist/webhook.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/result/index.ts","../src/slugs.ts","../src/tagged-error.ts","../src/errors.ts","../src/functional/index.ts","../src/di.ts"],"sourcesContent":["/**\n * awaitly\n *\n * Result types for typed error handling without exceptions.\n * Optimized for serverless with minimal bundle size.\n *\n * ## Quick Start\n *\n * ```typescript\n * import { Awaitly, type AsyncResult } from 'awaitly';\n * import { run } from 'awaitly/run';\n *\n * // Define Result-returning functions\n * async function getUser(id: string): AsyncResult<User, 'NOT_FOUND'> {\n * const user = await db.find(id);\n * return user ? Awaitly.ok(user) : Awaitly.err('NOT_FOUND');\n * }\n *\n * // Compose with run() - clean do-notation style\n * const result = await run(async ({ step }) => {\n * const user = await step(getUser(id));\n * const posts = await step(getPosts(user.id));\n * return { user, posts };\n * });\n * ```\n *\n * ## Entry Points\n *\n * **Core (this package):**\n * - `awaitly` - Awaitly namespace (Result types, transformers, tagged errors, pipe/flow)\n * - `awaitly/result` - Result types only (minimal bundle, no namespace)\n * - `awaitly/run` - run() function with step orchestration\n *\n * **Workflow Engine:**\n * - `awaitly/workflow` - createWorkflow, Duration, state management\n * - `awaitly/hitl` - Human-in-the-loop approval flows\n *\n * **Reliability:**\n * - `awaitly/retry` - Composable retry/backoff strategies\n * - `awaitly/circuit-breaker` - Circuit breaker pattern\n * - `awaitly/ratelimit` - Rate limiting\n * - `awaitly/saga` - Saga compensation pattern\n *\n * **Utilities:**\n * - `awaitly/duration` - Type-safe time durations\n * - `awaitly/match` - Pattern matching\n * - `awaitly/persistence` - State persistence\n * - `awaitly/durable` - Durable execution with automatic checkpointing\n */\n\nimport * as result from \"./result\";\nimport { TaggedError } from \"./tagged-error\";\nimport {\n pipe,\n flow,\n compose,\n identity,\n R,\n recoverWith,\n getOrElse,\n getOrElseLazy,\n mapAsync,\n flatMapAsync,\n tapAsync,\n tapErrorAsync,\n race,\n traverse,\n traverseAsync,\n traverseParallel,\n} from \"./functional\";\n\n// =============================================================================\n// Awaitly namespace (Effect-style single export)\n// =============================================================================\n\nconst Awaitly = {\n // Result (all value exports)\n ...result,\n // Tagged errors\n TaggedError,\n // Functional (non-clashing: pipe, flow, R, async helpers, etc.)\n pipe,\n flow,\n compose,\n identity,\n R,\n recoverWith,\n getOrElse,\n getOrElseLazy,\n mapAsync,\n flatMapAsync,\n tapAsync,\n tapErrorAsync,\n race,\n traverse,\n traverseAsync,\n traverseParallel,\n} as const;\n\nexport { Awaitly };\n\n// =============================================================================\n// Named value exports (tree-shake friendly)\n// =============================================================================\n\nexport {\n UnexpectedError,\n PROMISE_REJECTED,\n AWAITLY_UNEXPECTED,\n AWAITLY_CANCELLED,\n AWAITLY_TIMEOUT,\n tags,\n ok,\n err,\n isOk,\n isErr,\n isUnexpectedError,\n isPromiseRejectedError,\n matchError,\n UnwrapError,\n unwrap,\n unwrapOr,\n unwrapOrElse,\n runOrThrow,\n runOrThrowAsync,\n runOrNull,\n runOrUndefined,\n from,\n fromPromise,\n tryAsync,\n fromNullable,\n map,\n mapError,\n match,\n andThen,\n tap,\n tapError,\n mapTry,\n mapErrorTry,\n bimap,\n orElse,\n orElseAsync,\n recover,\n recoverAsync,\n hydrate,\n isSerializedResult,\n all,\n allAsync,\n allSettled,\n allSettledAsync,\n partition,\n any,\n anyAsync,\n zip,\n zipAsync,\n flatten,\n deserialize,\n DESERIALIZATION_ERROR,\n serialize,\n matchErrorPartial,\n} from \"./result\";\n\nexport { withDeps } from \"./di\";\n\nexport { TaggedError } from \"./tagged-error\";\n\nexport {\n pipe,\n flow,\n compose,\n identity,\n R,\n recoverWith,\n getOrElse,\n getOrElseLazy,\n mapAsync,\n flatMapAsync,\n tapAsync,\n tapErrorAsync,\n race,\n traverse,\n traverseAsync,\n traverseParallel,\n} from \"./functional\";\n\n// =============================================================================\n// Type exports (cannot live on runtime object)\n// =============================================================================\n\nexport type {\n Ok,\n Err,\n Result,\n AsyncResult,\n PromiseRejectedError,\n PromiseRejectionCause,\n EmptyInputError,\n MaybeAsyncResult,\n ErrorOf,\n Errors,\n ErrorsOf,\n ExtractValue,\n ExtractError,\n ExtractCause,\n CauseOf,\n MatchErrorHandlers,\n SettledError,\n DeserializationError,\n SerializedResult,\n} from \"./result\";\n\nexport type {\n TaggedErrorBase,\n TaggedErrorOptions,\n TaggedErrorCreateOptions,\n TaggedErrorConstructor,\n TagOf,\n ErrorByTag,\n PropsOf,\n} from \"./tagged-error\";\n\nexport type { RetryOptions, BackoffStrategy, BoundSteps } from \"./core\";\n\n// Slug Namespace — types only at the root to keep the bundle lean.\n// For runtime helpers (slugDocsUrl, isAwaitlySlug, AWAITLY_SLUGS, etc.),\n// import from \"awaitly/slugs\" or \"awaitly/core\".\nexport type { AwaitlySlug, AwaitlySlugCategory } from \"./slugs\";\n","/**\n * awaitly/result (internal)\n *\n * Core Result primitives - minimal bundle for typed error handling.\n * This file is intentionally kept small for optimal tree-shaking.\n * The full orchestration (run, step, etc.) lives in core.ts.\n */\n\n// =============================================================================\n// Core Result Types\n// =============================================================================\n\n/**\n * Represents a successful result.\n * Use `ok(value)` to create instances.\n */\nexport type Ok<T> = {\n ok: true;\n value: T;\n};\n\n/**\n * Represents a failed result.\n * Use `err(error)` to create instances.\n */\nexport type Err<E, C = unknown> = {\n ok: false;\n error: E;\n cause?: C;\n};\n\n/**\n * Represents a successful computation or a failed one.\n */\nexport type Result<T, E = unknown, C = unknown> = Ok<T> | Err<E, C>;\n\n/**\n * A Promise that resolves to a Result.\n */\nexport type AsyncResult<T, E = unknown, C = unknown> = Promise<Result<T, E, C>>;\n\n/** Discriminant for PromiseRejectedError type - use in switch statements */\nexport const PROMISE_REJECTED = \"PROMISE_REJECTED\" as const;\n\n// =============================================================================\n// Named Error Constants (for static analysis)\n// =============================================================================\n\n/**\n * Named error constant for unexpected/unhandled errors.\n * Used by the analyzer when a step doesn't declare errors.\n */\nexport const AWAITLY_UNEXPECTED = \"AWAITLY_UNEXPECTED\" as const;\n\n/**\n * Named error constant for cancelled operations.\n */\nexport const AWAITLY_CANCELLED = \"AWAITLY_CANCELLED\" as const;\n\n/**\n * Named error constant for timed-out operations.\n */\nexport const AWAITLY_TIMEOUT = \"AWAITLY_TIMEOUT\" as const;\n\n// =============================================================================\n// Static Analysis Helpers\n// =============================================================================\n\n/**\n * Helper to create a tuple of string literal tags with preserved literal types.\n * Use this when you need to store error tags in a variable while keeping\n * TypeScript's literal type inference (avoiding widening to string[]).\n *\n * @param t - The string literal tags\n * @returns The same array with preserved literal types\n *\n * @example\n * ```typescript\n * // Without tags() - type widens to string[]\n * const errs = ['CART_NOT_FOUND', 'CART_EMPTY']; // string[]\n *\n * // With tags() - literal types preserved\n * const errs = tags('CART_NOT_FOUND', 'CART_EMPTY'); // readonly ['CART_NOT_FOUND', 'CART_EMPTY']\n *\n * await step('getCart', () => getCart(id), {\n * errors: errs, // Analyzer can extract literal types\n * out: 'cart',\n * });\n * ```\n */\nexport const tags = <const T extends readonly string[]>(...t: T): T => t;\n\nimport { UnexpectedError } from \"../errors\";\nexport { UnexpectedError };\nexport type PromiseRejectedError = { type: typeof PROMISE_REJECTED; cause: unknown };\n/** Cause type for promise rejections in async batch helpers */\nexport type PromiseRejectionCause = { type: \"PROMISE_REJECTION\"; reason: unknown };\nexport type EmptyInputError = { type: \"EMPTY_INPUT\"; message: string };\nexport type MaybeAsyncResult<T, E, C = unknown> = Result<T, E, C> | Promise<Result<T, E, C>>;\n\n// =============================================================================\n// Result Constructors\n// =============================================================================\n\n/**\n * Creates a successful Result.\n *\n * @remarks When to use: Wrap a successful value in a Result for consistent return types.\n */\nexport function ok(): Ok<void>;\nexport function ok<T>(value: T): Ok<T>;\nexport function ok<T>(value?: T): Ok<T | void> {\n return { ok: true as const, value: value as T | void };\n}\n\n/**\n * Creates a failed Result.\n *\n * @remarks When to use: Return a typed failure without throwing so callers can handle it explicitly.\n */\nexport function err<E, C = unknown>(error: E, options?: { cause?: C }): Err<E, C> {\n const cause = options?.cause;\n return { ok: false as const, error, ...(cause !== undefined ? { cause } : {}) } as Err<E, C>;\n}\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Checks if a Result is successful.\n *\n * @remarks When to use: Prefer functional-style checks or array filtering over `result.ok`.\n */\nexport const isOk = <T, E, C>(r: Result<T, E, C>): r is Ok<T> => r.ok;\n\n/**\n * Checks if a Result is a failure.\n *\n * @remarks When to use: Prefer functional-style checks or array filtering over `result.ok`.\n */\nexport const isErr = <T, E, C>(r: Result<T, E, C>): r is Err<E, C> => !r.ok;\n\n/**\n * Checks if an error is an UnexpectedError.\n *\n * @remarks When to use: Distinguish unexpected failures from your typed error union.\n */\nexport const isUnexpectedError = (e: unknown): e is UnexpectedError =>\n e instanceof UnexpectedError ||\n (typeof e === \"object\" &&\n e !== null &&\n \"_tag\" in e &&\n (e as { _tag: string })._tag === \"UnexpectedError\");\n\n/**\n * Checks if an error is a PromiseRejectedError.\n */\nexport const isPromiseRejectedError = (e: unknown): e is PromiseRejectedError =>\n typeof e === \"object\" &&\n e !== null &&\n \"type\" in e &&\n e.type === PROMISE_REJECTED;\n\n// =============================================================================\n// Error Matching\n// =============================================================================\n\nexport type MatchErrorHandlers<E extends string, R> = {\n [K in Exclude<E, \"UnexpectedError\">]: (error: K) => R;\n} & {\n UnexpectedError: (error: UnexpectedError) => R;\n};\n\n/**\n * Match on string error types with exhaustive checking.\n * Takes an error value (not a Result) and handlers for each error type.\n */\nexport function matchError<E extends string, R>(\n handlers: MatchErrorHandlers<E, R>\n): (error: E | UnexpectedError) => R;\nexport function matchError<E extends string, R>(\n error: E | UnexpectedError,\n handlers: MatchErrorHandlers<E, R>\n): R;\nexport function matchError<E extends string, R>(\n errorOrHandlers: E | UnexpectedError | MatchErrorHandlers<E, R>,\n handlers?: MatchErrorHandlers<E, R>\n): R | ((error: E | UnexpectedError) => R) {\n if (handlers === undefined) {\n const h = errorOrHandlers as MatchErrorHandlers<E, R>;\n return (e: E | UnexpectedError) => matchError(e, h);\n }\n const error = errorOrHandlers as E | UnexpectedError;\n // Handle UnexpectedError instances\n if (isUnexpectedError(error)) {\n return handlers.UnexpectedError(error as UnexpectedError);\n }\n // Handle string literal errors\n type StringErrors = Exclude<E, \"UnexpectedError\">;\n return (handlers as unknown as Record<string, (e: string) => R>)[error as StringErrors](error as StringErrors);\n}\n\n// =============================================================================\n// Type Utilities\n// =============================================================================\n\ntype AnyFunction = (...args: never[]) => unknown;\n\n/**\n * Helper to extract the error type from Result or AsyncResult return values.\n * Works even when a function is declared to return a union of both forms.\n * Plain (non-Result) return types contribute `never` — without the [never]\n * guard they would infer `unknown` and poison error unions built from\n * mixed deps.\n */\ntype ErrorOfReturn<R> = [Extract<Awaited<R>, { ok: false }>] extends [never]\n ? never\n : Extract<Awaited<R>, { ok: false }> extends { error: infer E }\n ? E\n : never;\n\n/**\n * Extract error type from a single function's return type\n */\nexport type ErrorOf<T extends AnyFunction> = ErrorOfReturn<ReturnType<T>>;\n\n/**\n * Extract union of error types from multiple functions (tuple form)\n */\nexport type Errors<T extends AnyFunction[]> = {\n [K in keyof T]: ErrorOf<T[K]>;\n}[number];\n\n/**\n * Extract union of error types from a deps object.\n *\n * @example\n * ```typescript\n * const deps = { getUser, createOrder, sendEmail };\n * type E = ErrorsOf<typeof deps>;\n * // = \"NOT_FOUND\" | \"ORDER_FAILED\" | \"EMAIL_ERROR\"\n * ```\n */\nexport type ErrorsOf<Deps extends Record<string, AnyFunction>> = {\n [K in keyof Deps]: ErrorOf<Deps[K]>;\n}[keyof Deps];\n\n/**\n * Extract value type from Result\n */\nexport type ExtractValue<T> = T extends { ok: true; value: infer U }\n ? U\n : never;\n\n/**\n * Extract error type from Result\n */\nexport type ExtractError<T> = T extends { ok: false; error: infer E }\n ? E\n : never;\n\n/**\n * Extract cause type from Result\n */\nexport type ExtractCause<T> = T extends { ok: false; cause?: infer C }\n ? C\n : never;\n\n/**\n * Helper to extract the cause type from Result or AsyncResult return values.\n * Works even when a function is declared to return a union of both forms.\n */\ntype CauseOfReturn<R> = Extract<Awaited<R>, { ok: false }> extends { cause?: infer C }\n ? C\n : never;\n\n/**\n * Extract cause type from a function's return type\n */\nexport type CauseOf<T extends AnyFunction> = CauseOfReturn<ReturnType<T>>;\n\n// =============================================================================\n// Unwrap Utilities\n// =============================================================================\n\n/**\n * Error thrown when attempting to unwrap an Err result.\n */\nexport class UnwrapError extends Error {\n public readonly error: unknown;\n public readonly cause?: unknown;\n\n constructor(result: Err<unknown, unknown>) {\n const errorStr =\n typeof result.error === \"string\"\n ? result.error\n : JSON.stringify(result.error);\n super(`Attempted to unwrap an Err: ${errorStr}`);\n this.name = \"UnwrapError\";\n this.error = result.error;\n this.cause = result.cause;\n }\n}\n\n/**\n * Extracts the value from an Ok result, or throws UnwrapError if it's an Err.\n *\n * @remarks When to use: Only at boundaries or tests where a failure should be fatal.\n */\nexport const unwrap = <T, E, C>(r: Result<T, E, C>): T => {\n if (r.ok) return r.value;\n throw new UnwrapError(r);\n};\n\n/**\n * Extracts the value from an Ok result, or returns a default value if it's an Err.\n *\n * @remarks When to use: Provide a safe fallback without branching.\n */\nexport const unwrapOr = <T, E, C>(r: Result<T, E, C>, defaultValue: T): T =>\n r.ok ? r.value : defaultValue;\n\n/**\n * Extracts the value from an Ok result, or calls a function to get a default value if it's an Err.\n *\n * @remarks When to use: Compute a fallback from the error (logging, metrics, or derived defaults).\n */\nexport const unwrapOrElse = <T, E, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => T\n): T => (r.ok ? r.value : fn(r.error, r.cause));\n\n/**\n * Alias for `unwrap`. Returns the success value or throws.\n *\n * The Result is already computed; use when you want the value or throw (e.g. at boundaries or in tests).\n *\n * @param r - The Result to unwrap\n * @returns The success value if the Result is successful\n * @throws {UnwrapError} If the Result is an error (includes the error and cause)\n */\nexport const runOrThrow = <T, E, C>(r: Result<T, E, C>): T => unwrap(r);\n\n/**\n * Awaits a Promise of a Result, then returns the success value or rejects.\n *\n * The returned promise **resolves with T** on success and **rejects with UnwrapError** on failure.\n * UnwrapError extends Error and carries the original `error` and `cause` from the Err.\n *\n * @param ar - A Promise or thenable that resolves to a Result\n * @returns A Promise that resolves with the success value or rejects with UnwrapError\n */\nexport const runOrThrowAsync = <T, E, C>(\n ar: PromiseLike<Result<T, E, C>>\n): Promise<T> => Promise.resolve(ar).then(unwrap);\n\n/**\n * Convenience alias for `unwrapOr(r, null)`. Returns the success value or null.\n *\n * @param r - The Result to unwrap\n * @returns The success value if successful, otherwise null\n */\nexport const runOrNull = <T, E, C>(r: Result<T, E, C>): T | null =>\n r.ok ? r.value : null;\n\n/**\n * Convenience alias for `unwrapOr(r, undefined)`. Returns the success value or undefined.\n *\n * @param r - The Result to unwrap\n * @returns The success value if successful, otherwise undefined\n */\nexport const runOrUndefined = <T, E, C>(r: Result<T, E, C>): T | undefined =>\n r.ok ? r.value : undefined;\n\n// =============================================================================\n// Wrapping Functions\n// =============================================================================\n\n/**\n * Wraps a synchronous function that might throw into a Result.\n *\n * @remarks When to use: Wrap sync code that might throw so exceptions become Err values.\n */\nexport function from<T>(fn: () => T): Ok<T> | Err<unknown, unknown>;\nexport function from<T, E>(fn: () => T, onError: (cause: unknown) => E): Ok<T> | Err<E, unknown>;\nexport function from<T, E>(fn: () => T, onError?: (cause: unknown) => E) {\n try {\n return ok(fn());\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Wraps a Promise into a Result.\n *\n * @remarks When to use: Wrap a Promise and keep the raw rejection as Err; use tryAsync to map errors.\n */\nexport function fromPromise<T>(promise: Promise<T>): Promise<Ok<T> | Err<unknown, unknown>>;\nexport function fromPromise<T, E>(\n promise: Promise<T>,\n onError: (cause: unknown) => E\n): Promise<Ok<T> | Err<E, unknown>>;\nexport async function fromPromise<T, E>(\n promise: Promise<T>,\n onError?: (cause: unknown) => E\n): Promise<Ok<T> | Err<E | unknown, unknown>> {\n try {\n return ok(await promise);\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Wraps an async function that might throw into an AsyncResult.\n *\n * @remarks When to use: Wrap async work and map thrown/rejected values into your typed error union.\n */\nexport function tryAsync<T>(fn: () => Promise<T>): AsyncResult<T, unknown>;\nexport function tryAsync<T, E>(\n fn: () => Promise<T>,\n onError: (cause: unknown) => E\n): AsyncResult<T, E>;\nexport async function tryAsync<T, E>(\n fn: () => Promise<T>,\n onError?: (cause: unknown) => E\n): AsyncResult<T, E | unknown> {\n try {\n return ok(await fn());\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Converts a nullable value into a Result.\n *\n * @remarks When to use: Turn null/undefined into a typed error before continuing.\n */\nexport function fromNullable<T, E>(\n value: T | null | undefined,\n onNull: () => E\n): Result<T, E> {\n return value != null ? ok(value) : err(onNull());\n}\n\n// =============================================================================\n// Transformers\n// =============================================================================\n\n/**\n * Transforms the value inside an Ok result.\n *\n * @remarks When to use: Transform only the Ok value while leaving Err untouched.\n */\nexport function map<T, U>(r: Ok<T>, fn: (value: T) => U): Ok<U>;\nexport function map<T, U, E, C>(r: Err<E, C>, fn: (value: T) => U): Err<E, C>;\nexport function map<T, U, E, C>(r: Result<T, E, C>, fn: (value: T) => U): Result<U, E, C>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function map(r: any, fn: any): any {\n return r.ok ? ok(fn(r.value)) : r;\n}\n\n/**\n * Transforms the error inside an Err result.\n *\n * @remarks When to use: Retype or normalize errors while leaving Ok values unchanged.\n */\nexport function mapError<T, E, F, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => F\n): Result<T, F, C> {\n return r.ok ? r : err(fn(r.error, r.cause), { cause: r.cause });\n}\n\n/**\n * Pattern match on a Result.\n *\n * @remarks When to use: Handle both Ok and Err in a single expression that returns a value.\n */\nexport function match<T, E, C, R>(handlers: { ok: (value: T) => R; err: (error: E, cause?: C) => R }): (r: Result<T, E, C>) => R;\nexport function match<T, E, C, R>(r: Ok<T>, handlers: { ok: (value: T) => R; err: (error: E, cause?: C) => R }): R;\nexport function match<T, E, C, R>(r: Err<E, C>, handlers: { ok: (value: T) => R; err: (error: E, cause?: C) => R }): R;\nexport function match<T, E, C, R>(r: Result<T, E, C>, handlers: { ok: (value: T) => R; err: (error: E, cause?: C) => R }): R;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function match(r: any, handlers?: any): any {\n if (handlers === undefined) {\n const h = r;\n return (result: Result<unknown, unknown, unknown>) => match(result, h);\n }\n return r.ok ? handlers.ok(r.value) : handlers.err(r.error, r.cause);\n}\n\n/**\n * Chain Result-returning functions.\n *\n * @remarks When to use: Chain dependent operations that return Result without nested branching.\n */\nexport function andThen<T, U>(r: Ok<T>, fn: (value: T) => Ok<U>): Ok<U>;\nexport function andThen<T, F, C2>(r: Ok<T>, fn: (value: T) => Err<F, C2>): Err<F, C2>;\nexport function andThen<T, U, F, C2>(r: Ok<T>, fn: (value: T) => Result<U, F, C2>): Result<U, F, C2>;\nexport function andThen<T, U, E, F, C1, C2>(r: Err<E, C1>, fn: (value: T) => Result<U, F, C2>): Err<E, C1>;\nexport function andThen<T, U, E, F, C1, C2>(r: Result<T, E, C1>, fn: (value: T) => Result<U, F, C2>): Result<U, E | F, C1 | C2>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function andThen(r: any, fn: any): any {\n return r.ok ? fn(r.value) : r;\n}\n\n/**\n * Execute a side effect on Ok values.\n *\n * @remarks When to use: Add side effects (logging, metrics) on Ok without changing the Result.\n */\nexport function tap<T, E, C>(\n r: Result<T, E, C>,\n fn: (value: T) => void\n): Result<T, E, C> {\n if (r.ok) fn(r.value);\n return r;\n}\n\n/**\n * Execute a side effect on Err values.\n *\n * @remarks When to use: Add side effects (logging, metrics) on Err without changing the Result.\n */\nexport function tapError<T, E, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => void\n): Result<T, E, C> {\n if (!r.ok) fn(r.error, r.cause);\n return r;\n}\n\n/**\n * Transform value with a function that might throw.\n *\n * @remarks When to use: Transform Ok values with a function that might throw and capture the failure.\n */\nexport function mapTry<T, U, E, F, C>(\n r: Result<T, E, C>,\n fn: (value: T) => U,\n onError: (thrown: unknown) => F\n): Result<U, E | F, C | unknown> {\n if (!r.ok) return r;\n try {\n return ok(fn(r.value));\n } catch (error) {\n return err(onError(error), { cause: error });\n }\n}\n\n/**\n * Transform error with a function that might throw.\n *\n * @remarks When to use: Transform errors when the mapping might throw and you want that captured.\n */\nexport function mapErrorTry<T, E, F, G, C>(\n r: Result<T, E, C>,\n fn: (error: E) => F,\n onError: (thrown: unknown) => G\n): Result<T, F | G, C | unknown> {\n if (r.ok) return r;\n try {\n return err(fn(r.error), { cause: r.cause });\n } catch (error) {\n return err(onError(error), { cause: error });\n }\n}\n\n/**\n * Transform both value and error.\n */\nexport function bimap<T, U, E, F, C>(\n r: Result<T, E, C>,\n onOk: (value: T) => U,\n onErr: (error: E, cause?: C) => F\n): Result<U, F, C> {\n return r.ok ? ok(onOk(r.value)) : err(onErr(r.error, r.cause), { cause: r.cause });\n}\n\n/**\n * Provide an alternative Result if the first is an Err.\n *\n * @remarks When to use: Recover from Err by returning a fallback Result or retyping the error.\n */\nexport function orElse<T, E, E2, C, C2>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => Result<T, E2, C2>\n): Result<T, E2, C | C2> {\n return r.ok ? r : fn(r.error, r.cause);\n}\n\n/**\n * Async version of orElse.\n */\nexport async function orElseAsync<T, E, E2, C, C2>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => Promise<Result<T, E2, C2>>\n): Promise<Result<T, E2, C | C2>> {\n return r.ok ? r : fn(r.error, r.cause);\n}\n\n/**\n * Recover from errors - always returns Ok<T>.\n */\nexport function recover<T, E, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => T\n): Ok<T> {\n return r.ok ? ok(r.value) : ok(fn(r.error, r.cause));\n}\n\n/**\n * Async version of recover - always returns Promise<Ok<T>>.\n */\nexport async function recoverAsync<T, E, C>(\n r: Result<T, E, C> | Promise<Result<T, E, C>>,\n fn: (error: E, cause?: C) => T | Promise<T>\n): Promise<Ok<T>> {\n const resolved = await r;\n if (resolved.ok) return ok(resolved.value);\n return ok(await fn(resolved.error, resolved.cause));\n}\n\n// =============================================================================\n// Result Hydration (Serialization)\n// =============================================================================\n\n/**\n * Hydrate a serialized Result back into a proper Result object.\n */\nexport function hydrate<T, E, C = unknown>(value: unknown): Result<T, E, C> | null {\n if (typeof value !== \"object\" || value === null) return null;\n if (!(\"ok\" in value)) return null;\n\n const obj = value as Record<string, unknown>;\n if (obj.ok === true && \"value\" in obj) {\n return ok(obj.value as T);\n }\n if (obj.ok === false && \"error\" in obj) {\n return err(obj.error as E, { cause: obj.cause as C });\n }\n return null;\n}\n\n/**\n * Type guard to check if a value is a serialized Result.\n */\nexport function isSerializedResult(\n value: unknown\n): value is { ok: boolean; value?: unknown; error?: unknown; cause?: unknown } {\n if (typeof value !== \"object\" || value === null) return false;\n if (!(\"ok\" in value)) return false;\n const obj = value as Record<string, unknown>;\n return (\n (obj.ok === true && \"value\" in obj) ||\n (obj.ok === false && \"error\" in obj)\n );\n}\n\n// =============================================================================\n// Batch Operations\n// =============================================================================\n\ntype AllValues<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Ok<infer V>\n ? V\n : T[K] extends Err<unknown, unknown>\n ? never\n : T[K] extends Result<infer V, unknown, unknown>\n ? V\n : never;\n};\ntype AllErrors<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Ok<unknown>\n ? never\n : T[K] extends Err<infer E, unknown>\n ? E\n : T[K] extends Result<unknown, infer E, unknown>\n ? E\n : never;\n}[number];\ntype AllCauses<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Ok<unknown>\n ? never\n : T[K] extends Err<unknown, infer C>\n ? C\n : T[K] extends Result<unknown, unknown, infer C>\n ? C\n : never;\n}[number];\n\n// Conditional type: returns Ok<...> when there are no errors, Result<...> otherwise\n// Note: We only check AllErrors, not AllCauses - causes only matter when there are errors\ntype AllResult<T extends readonly Result<unknown, unknown, unknown>[]> =\n [AllErrors<T>] extends [never]\n ? Ok<AllValues<T>>\n : Result<AllValues<T>, AllErrors<T>, AllCauses<T>>;\n\n/**\n * Combines multiple Results into a single Result containing an array of values.\n * Returns the first Err encountered, or Ok with all values.\n */\nexport function all<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): AllResult<T> {\n const values: unknown[] = [];\n for (const result of results) {\n if (!result.ok) {\n return result as unknown as AllResult<T>;\n }\n values.push(result.value);\n }\n return ok(values) as AllResult<T>;\n}\n\n/**\n * Async version of all - works with Promises of Results.\n */\nexport async function allAsync<\n const T extends readonly (Result<unknown, unknown, unknown> | Promise<Result<unknown, unknown, unknown>>)[]\n>(\n results: T\n): Promise<\n Result<\n { [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> | Promise<Result<infer V, unknown, unknown>> ? V : never },\n | { [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> | Promise<Result<unknown, infer E, unknown>> ? E : never }[number]\n | PromiseRejectedError,\n | { [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> | Promise<Result<unknown, unknown, infer C>> ? C : never }[number]\n | PromiseRejectionCause\n >\n> {\n const values: unknown[] = [];\n for (const resultOrPromise of results) {\n try {\n const r = await resultOrPromise;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (!r.ok) return r as any;\n values.push(r.value);\n } catch (reason) {\n return err(\n { type: PROMISE_REJECTED, cause: reason } as PromiseRejectedError,\n { cause: { type: \"PROMISE_REJECTION\", reason } as PromiseRejectionCause }\n );\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return ok(values) as any;\n}\n\nexport type SettledError<E, C = unknown> = { error: E; cause?: C };\n\n// Conditional type: returns Ok<...> when there are no errors, Result<...> otherwise\ntype AllSettledResult<T extends readonly Result<unknown, unknown, unknown>[]> =\n [AllErrors<T>] extends [never]\n ? Ok<AllValues<T>>\n : Result<AllValues<T>, SettledError<AllErrors<T>, AllCauses<T>>[]>;\n\n/**\n * Collects all Results, returning Ok with values if all succeed,\n * or Err with array of errors if any fail.\n */\nexport function allSettled<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): AllSettledResult<T> {\n const values: unknown[] = [];\n const errors: SettledError<unknown>[] = [];\n\n for (const result of results) {\n if (result.ok) {\n values.push(result.value);\n } else {\n errors.push({ error: result.error, cause: result.cause });\n }\n }\n\n if (errors.length > 0) {\n return err(errors) as unknown as AllSettledResult<T>;\n }\n\n return ok(values) as unknown as AllSettledResult<T>;\n}\n\n/**\n * Async version of allSettled.\n */\nexport async function allSettledAsync<\n const T extends readonly (Result<unknown, unknown, unknown> | Promise<Result<unknown, unknown, unknown>>)[]\n>(\n results: T\n): Promise<\n Result<\n { [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> | Promise<Result<infer V, unknown, unknown>> ? V : never },\n SettledError<\n | { [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> | Promise<Result<unknown, infer E, unknown>> ? E : never }[number]\n | PromiseRejectedError,\n | { [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> | Promise<Result<unknown, unknown, infer C>> ? C : never }[number]\n | PromiseRejectionCause\n >[]\n >\n> {\n const settled = await Promise.all(\n results.map((item) =>\n Promise.resolve(item)\n .then((result) => ({ status: \"result\" as const, result }))\n .catch((reason) => ({\n status: \"rejected\" as const,\n error: { type: PROMISE_REJECTED, cause: reason } as PromiseRejectedError,\n cause: { type: \"PROMISE_REJECTION\", reason } as PromiseRejectionCause,\n }))\n )\n );\n\n const values: unknown[] = [];\n const errors: SettledError<unknown, unknown>[] = [];\n\n for (const item of settled) {\n if (item.status === \"rejected\") {\n errors.push({ error: item.error, cause: item.cause });\n } else if (item.result.ok) {\n values.push(item.result.value);\n } else {\n errors.push({ error: item.result.error, cause: item.result.cause });\n }\n }\n\n if (errors.length > 0) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return err(errors) as any;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return ok(values) as any;\n}\n\n/**\n * Partitions Results into { values, errors }.\n */\nexport function partition<T, E, C>(\n results: readonly Result<T, E, C>[]\n): { values: T[]; errors: E[] } {\n const values: T[] = [];\n const errors: E[] = [];\n for (const r of results) {\n if (r.ok) values.push(r.value);\n else errors.push(r.error);\n }\n return { values, errors };\n}\n\n/**\n * Returns the first Ok result, or an EmptyInputError/first Err if all fail.\n */\nexport function any<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): T extends readonly []\n ? Err<EmptyInputError, unknown>\n : Result<\n { [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> ? V : never }[number],\n AllErrors<T> | EmptyInputError,\n AllCauses<T>\n >;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function any(results: any): any {\n if (results.length === 0) {\n return err({ type: \"EMPTY_INPUT\", message: \"any() requires at least one Result\" });\n }\n let firstErr: Err<unknown, unknown> | undefined;\n for (const r of results) {\n if (r.ok) return r;\n if (!firstErr) firstErr = r;\n }\n return firstErr;\n}\n\n/**\n * Async version of any - races promises and returns first success.\n */\nexport async function anyAsync<\n const T extends readonly (Result<unknown, unknown, unknown> | Promise<Result<unknown, unknown, unknown>>)[]\n>(\n results: T\n): Promise<\n T extends readonly []\n ? Err<EmptyInputError, unknown>\n : Result<\n { [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> | Promise<Result<infer V, unknown, unknown>> ? V : never }[number],\n | { [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> | Promise<Result<unknown, infer E, unknown>> ? E : never }[number]\n | EmptyInputError\n | PromiseRejectedError,\n | { [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> | Promise<Result<unknown, unknown, infer C>> ? C : never }[number]\n | PromiseRejectionCause\n >\n> {\n if (results.length === 0) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return err({ type: \"EMPTY_INPUT\", message: \"anyAsync() requires at least one Result\" }) as any;\n }\n\n return new Promise((resolve) => {\n let settled = false;\n let pendingCount = results.length;\n let firstError: Err<unknown, unknown> | null = null;\n\n for (const item of results) {\n Promise.resolve(item)\n .catch((reason) =>\n err(\n { type: PROMISE_REJECTED, cause: reason } as PromiseRejectedError,\n { cause: { type: \"PROMISE_REJECTION\", reason } as PromiseRejectionCause }\n )\n )\n .then((result) => {\n if (settled) return;\n\n if (result.ok) {\n settled = true;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n resolve(result as any);\n return;\n }\n\n if (!firstError) firstError = result;\n pendingCount--;\n\n if (pendingCount === 0) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n resolve(firstError as any);\n }\n });\n }\n });\n}\n\n/**\n * Combines exactly two Results into a tuple.\n */\nexport function zip<A, EA, CA, B, EB, CB>(\n a: Result<A, EA, CA>,\n b: Result<B, EB, CB>\n): Result<[A, B], EA | EB, CA | CB> {\n if (!a.ok) return a;\n if (!b.ok) return b;\n return ok([a.value, b.value]);\n}\n\n/**\n * Async version of zip.\n */\nexport async function zipAsync<A, EA, CA, B, EB, CB>(\n a: Result<A, EA, CA> | Promise<Result<A, EA, CA>>,\n b: Result<B, EB, CB> | Promise<Result<B, EB, CB>>\n): Promise<Result<[A, B], EA | EB | PromiseRejectedError, CA | CB | PromiseRejectionCause>> {\n // Wrap rejections into PromiseRejectedError (consistent with allAsync)\n const wrapRejection = <T, E, C>(\n p: Result<T, E, C> | Promise<Result<T, E, C>>\n ): Promise<Result<T, E | PromiseRejectedError, C | PromiseRejectionCause>> =>\n Promise.resolve(p).catch((reason) =>\n err(\n { type: PROMISE_REJECTED, cause: reason } as PromiseRejectedError,\n { cause: { type: \"PROMISE_REJECTION\", reason } as PromiseRejectionCause }\n )\n );\n\n const [ra, rb] = await Promise.all([wrapRejection(a), wrapRejection(b)]);\n return zip(ra, rb);\n}\n\n// =============================================================================\n// Flatten\n// =============================================================================\n\n/**\n * Flattens a nested Result into a single Result.\n *\n * @remarks When to use: Unwrap a Result<Result<T, E1>, E2> into Result<T, E1 | E2> after an operation that returns nested Results.\n */\nexport function flatten<T, E1, C1, E2, C2>(\n result: Result<Result<T, E1, C1>, E2, C2>\n): Result<T, E1 | E2, C1 | C2> {\n if (!result.ok) return result as Err<E2, C2>;\n return result.value;\n}\n\n// =============================================================================\n// Deserialization (improved hydrate)\n// =============================================================================\n\n/** Discriminant for deserialization errors */\nexport const DESERIALIZATION_ERROR = \"DESERIALIZATION_ERROR\" as const;\n\n/** Error type returned when deserialize() receives invalid input */\nexport type DeserializationError = { type: typeof DESERIALIZATION_ERROR; value: unknown };\n\n/**\n * Deserialize a value back into a Result.\n * Returns a typed DeserializationError on invalid input instead of null.\n *\n * @remarks When to use: Rehydrate Results from JSON, RPC, or server actions with type-safe error handling.\n */\nexport function deserialize<T, E, C = unknown>(\n value: unknown\n): Result<T, E | DeserializationError, C> {\n if (typeof value !== \"object\" || value === null) {\n return err({ type: DESERIALIZATION_ERROR, value } as DeserializationError);\n }\n if (!(\"ok\" in value)) {\n return err({ type: DESERIALIZATION_ERROR, value } as DeserializationError);\n }\n\n const obj = value as Record<string, unknown>;\n if (obj.ok === true && \"value\" in obj) {\n return ok(obj.value as T);\n }\n if (obj.ok === false && \"error\" in obj) {\n return err(obj.error as E, { cause: obj.cause as C });\n }\n return err({ type: DESERIALIZATION_ERROR, value } as DeserializationError);\n}\n\n// =============================================================================\n// Serialization\n// =============================================================================\n\n/** A plain serialized form of a Result, safe to JSON.stringify. */\nexport type SerializedResult<T, E> = { ok: true; value: T } | { ok: false; error: E };\n\n/**\n * Serialize a Result to a plain object (inverse of `deserialize`).\n * Strips cause — safe for JSON.stringify, RPC, and server actions.\n *\n * @remarks When to use: Sending Results over the wire or storing them in JSON.\n */\nexport function serialize<T, E>(result: Result<T, E>): SerializedResult<T, E> {\n return result.ok\n ? { ok: true, value: result.value }\n : { ok: false, error: result.error };\n}\n\n// =============================================================================\n// Partial error matching\n// =============================================================================\n\n/**\n * Non-exhaustive error match — handle the errors you care about; let the rest fall through to fallback.\n *\n * @example\n * ```typescript\n * const message = matchErrorPartial(\n * error,\n * { NOT_FOUND: () => 'Resource not found' },\n * (e) => `Unexpected: ${e}`\n * );\n * ```\n */\nexport function matchErrorPartial<E extends string, R>(\n error: E | UnexpectedError,\n handlers: Partial<MatchErrorHandlers<E, R>>,\n fallback: (error: E | UnexpectedError) => R\n): R {\n if (isUnexpectedError(error)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const h = (handlers as any).UnexpectedError as ((e: UnexpectedError) => R) | undefined;\n return h ? h(error) : fallback(error);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const h = (handlers as any)[error as string] as ((e: E) => R) | undefined;\n return h ? h(error as E) : fallback(error);\n}\n\n// Retry helper is intentionally NOT re-exported here.\n// Import from the dedicated subpath to keep awaitly/result minimal:\n// import { tryAsyncRetry } from 'awaitly/result/retry';\n","/**\n * awaitly/slugs\n *\n * Source-of-truth slug namespace. Every concept that surfaces as a runtime\n * error, lint rule, static-analyzer diagnostic, visualizer event, or skill rule\n * has exactly one canonical kebab-case slug here.\n *\n * Slugs are public API. Renames are a major version bump. Adds are non-breaking.\n *\n * Categories:\n * - step-* step() discipline\n * - workflow-* createWorkflow / run / runWithState shape\n * - result-* Result usage\n * - error-* Boundary handling\n * - concurrency-* step.all/map/race vs Promise.*\n * - runtime-* Failures only observable at runtime\n */\n\nexport const AWAITLY_SLUGS = {\n // --- step-* ---\n \"step-require-id\": \"step-require-id\",\n \"step-no-immediate-execution\": \"step-no-immediate-execution\",\n \"step-require-thunk-for-key\": \"step-require-thunk-for-key\",\n \"step-no-bare-await\": \"step-no-bare-await\",\n \"step-no-try-catch-wrap\": \"step-no-try-catch-wrap\",\n \"step-stable-cache-keys\": \"step-stable-cache-keys\",\n\n // --- workflow-* ---\n \"workflow-no-floating\": \"workflow-no-floating\",\n \"workflow-options-position\": \"workflow-options-position\",\n \"workflow-callback-shape\": \"workflow-callback-shape\",\n \"workflow-no-callable-form\": \"workflow-no-callable-form\",\n \"workflow-no-dynamic-import\": \"workflow-no-dynamic-import\",\n\n // --- result-* ---\n \"result-no-floating\": \"result-no-floating\",\n \"result-require-handling\": \"result-require-handling\",\n \"result-no-double-wrap\": \"result-no-double-wrap\",\n \"result-no-manual-propagation\": \"result-no-manual-propagation\",\n \"result-no-direct-ok-err\": \"result-no-direct-ok-err\",\n\n // --- error-* ---\n \"error-check-unexpected-first\": \"error-check-unexpected-first\",\n \"error-access-cause\": \"error-access-cause\",\n \"error-normalize\": \"error-normalize\",\n \"error-no-throw-in-deps\": \"error-no-throw-in-deps\",\n\n // --- concurrency-* ---\n \"concurrency-no-promise-all\": \"concurrency-no-promise-all\",\n \"concurrency-no-promise-race\": \"concurrency-no-promise-race\",\n \"concurrency-no-promise-allsettled\": \"concurrency-no-promise-allsettled\",\n\n // --- runtime-* ---\n \"runtime-step-timeout\": \"runtime-step-timeout\",\n \"runtime-step-aborted\": \"runtime-step-aborted\",\n \"runtime-retry-exhausted\": \"runtime-retry-exhausted\",\n \"runtime-rate-limit\": \"runtime-rate-limit\",\n \"runtime-circuit-open\": \"runtime-circuit-open\",\n \"runtime-unexpected\": \"runtime-unexpected\",\n \"runtime-resolver-not-found\": \"runtime-resolver-not-found\",\n \"runtime-saga-compensation\": \"runtime-saga-compensation\",\n} as const;\n\n/** All canonical awaitly slugs as a string-literal union. */\nexport type AwaitlySlug = keyof typeof AWAITLY_SLUGS;\n\n/** Categories derived from slug prefixes. */\nexport type AwaitlySlugCategory =\n | \"step\"\n | \"workflow\"\n | \"result\"\n | \"error\"\n | \"concurrency\"\n | \"runtime\";\n\n/** Returns the category (prefix) of a slug. */\nexport function slugCategory(slug: AwaitlySlug): AwaitlySlugCategory {\n return slug.split(\"-\")[0] as AwaitlySlugCategory;\n}\n\n/**\n * Returns the canonical docs URL for a slug. Resolves to the matching\n * anchored section on the consolidated rule index page.\n */\nexport function slugDocsUrl(slug: AwaitlySlug): string {\n return `https://jagreehal.github.io/awaitly/rules/#${slug}`;\n}\n\n/** Type guard: is a string a known awaitly slug? */\nexport function isAwaitlySlug(value: string): value is AwaitlySlug {\n return Object.prototype.hasOwnProperty.call(AWAITLY_SLUGS, value);\n}\n\n/** All slugs as an array. */\n// Object.keys returns string[] — cast is safe because AWAITLY_SLUGS is `as const`\n// and the module's keys are never mutated.\nexport const ALL_SLUGS: readonly AwaitlySlug[] = Object.keys(\n AWAITLY_SLUGS\n) as AwaitlySlug[];\n","/**\n * awaitly/tagged-error\n *\n * Factory for creating tagged error types with exhaustive pattern matching.\n * Enables TypeScript to enforce that all error variants are handled.\n *\n * @example\n * ```typescript\n * // Define error types (Props via generic)\n * class NotFoundError extends TaggedError(\"NotFoundError\")<{\n * id: string;\n * resource: string;\n * }> {}\n *\n * // Define with type-safe message (Props inferred from callback annotation)\n * class ValidationError extends TaggedError(\"ValidationError\", {\n * message: (p: { field: string; reason: string }) => `Invalid ${p.field}: ${p.reason}`,\n * }) {}\n *\n * // Create instances\n * const error = new NotFoundError({ id: \"123\", resource: \"User\" });\n *\n * // Runtime type check: instanceof TaggedError works!\n * console.log(error instanceof TaggedError); // true\n *\n * // Exhaustive matching\n * type AppError = NotFoundError | ValidationError;\n * const message = TaggedError.match(error as AppError, {\n * NotFoundError: (e) => `Missing: ${e.resource} ${e.id}`,\n * ValidationError: (e) => `Invalid ${e.field}: ${e.reason}`,\n * });\n * ```\n */\n\nimport { type AwaitlySlug, slugDocsUrl } from \"./slugs\";\n\n/**\n * Options for Error constructor (compatible with ES2022 ErrorOptions).\n */\nexport interface TaggedErrorOptions {\n cause?: unknown;\n}\n\n/**\n * Options for TaggedError factory with type-safe message callback.\n */\nexport interface TaggedErrorCreateOptions<Props extends Record<string, unknown>> {\n /** Custom message generator from props. Annotate parameter for type safety. */\n message: (props: Props) => string;\n /**\n * Canonical awaitly slug for this error class. When set, instances carry\n * `code`, `hint`, and `docsUrl` populated from the slugs namespace.\n * Required together with `hint` for awaitly-system errors.\n */\n slug?: AwaitlySlug;\n /**\n * One-line \"do X instead\" guidance shown alongside the error.\n * Required when `slug` is set.\n */\n hint?: string;\n}\n\n/**\n * Base interface for all tagged errors.\n */\nexport interface TaggedErrorBase extends Error {\n readonly _tag: string;\n /** Canonical slug for awaitly-system errors. Undefined for user errors that opt out. */\n readonly code?: AwaitlySlug;\n /** One-line guidance. Undefined when no slug is set. */\n readonly hint?: string;\n /** Canonical docs URL. Undefined when no slug is set. */\n readonly docsUrl?: string;\n}\n\n/**\n * Internal base class for instanceof checks.\n * All TaggedError-created classes extend this.\n * @internal\n */\nclass InternalTaggedErrorBase extends Error implements TaggedErrorBase {\n readonly _tag!: string;\n}\n\n/**\n * Instance type for factory-created TaggedErrors.\n */\ntype TaggedErrorInstance<Tag extends string, Props> = TaggedErrorBase & {\n readonly _tag: Tag;\n} & Readonly<Props>;\n\n/**\n * Constructor args type - conditionally optional based on whether Props has required fields.\n * - If Props is empty or all properties are optional: props argument is optional\n * - If Props has any required properties: props argument is required\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\ntype ConstructorArgs<Props extends Record<string, unknown>> = {} extends Props\n ? [props?: Props | void, options?: TaggedErrorOptions]\n : [props: Props, options?: TaggedErrorOptions];\n\n/**\n * Constructor type returned by TaggedError factory.\n */\nexport interface TaggedErrorConstructor<\n Tag extends string,\n Props extends Record<string, unknown>,\n> {\n new (...args: ConstructorArgs<Props>): TaggedErrorInstance<Tag, Props>;\n readonly prototype: TaggedErrorInstance<Tag, Props>;\n}\n\n/**\n * Generic class factory type that allows `<Props>` parameterization.\n * This enables the Effect.js-style syntax: `class X extends TaggedError(\"X\")<Props> {}`\n * @internal\n */\nexport interface TaggedErrorClassFactory<Tag extends string> {\n new <Props extends Record<string, unknown> = Record<string, never>>(\n ...args: ConstructorArgs<Props>\n ): TaggedErrorInstance<Tag, Props>;\n}\n\n/**\n * Helper type to extract return type from a function type.\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype FnReturnType<T> = T extends (...args: any[]) => infer R ? R : never;\n\n/**\n * Helper type to get union of return types from all handlers.\n * @internal\n */\ntype HandlersReturnType<H> = { [K in keyof H]: FnReturnType<H[K]> }[keyof H];\n\n/**\n * Helper type to extract keys whose values are definitely functions (not undefined).\n * Only excludes a tag from the fallback type if its handler is guaranteed to be\n * a function. Keys where the value type includes undefined are NOT excluded,\n * ensuring type safety with dynamic/conditional handlers.\n * @internal\n */\ntype DefinitelyHandledKeys<H> = {\n [K in keyof H]-?: undefined extends H[K] ? never : K;\n}[keyof H];\n\n/**\n * Factory function to create tagged error classes.\n *\n * Two usage patterns:\n *\n * 1. **Props via generic** (default message is tag name):\n * ```typescript\n * class NotFoundError extends TaggedError(\"NotFoundError\")<{ id: string }> {}\n * ```\n *\n * 2. **Props inferred from message callback** (type-safe message):\n * ```typescript\n * class NotFoundError extends TaggedError(\"NotFoundError\", {\n * message: (p: { id: string }) => `Not found: ${p.id}`,\n * }) {}\n * ```\n *\n * Both support `instanceof TaggedError` checks at runtime.\n *\n * @param tag - The unique tag string for this error type\n * @param options - Optional configuration with message generator (annotate param for type safety)\n * @returns A class constructor that can be extended\n */\n\n// Overload 1: No options - use <Props> generic syntax, default message is tag\nfunction TaggedError<Tag extends string>(\n tag: Tag\n): TaggedErrorClassFactory<Tag>;\n\n// Overload 2: With message option - Props inferred from callback parameter annotation\nfunction TaggedError<Tag extends string, Props extends Record<string, unknown>>(\n tag: Tag,\n options: TaggedErrorCreateOptions<Props>\n): TaggedErrorConstructor<Tag, Props>;\n\n// Implementation\nfunction TaggedError<Tag extends string, Props extends Record<string, unknown>>(\n tag: Tag,\n options?: TaggedErrorCreateOptions<Props>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n return class extends InternalTaggedErrorBase {\n override readonly _tag: Tag = tag;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(props?: any, errorOptions?: TaggedErrorOptions) {\n // Generate message: call callback if provided (even for prop-less errors), else use tag\n const message = options?.message ? options.message(props ?? {}) : tag;\n\n super(message);\n this.name = tag;\n\n // Spine fields: populate when factory was given a slug\n if (options?.slug !== undefined) {\n if (!options.hint) {\n throw new TypeError(\n `TaggedError: 'hint' is required when 'slug' is set (slug: \"${options.slug}\")`\n );\n }\n Object.defineProperty(this, \"code\", {\n value: options.slug,\n enumerable: true,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(this, \"hint\", {\n value: options.hint,\n enumerable: true,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(this, \"docsUrl\", {\n value: slugDocsUrl(options.slug),\n enumerable: true,\n writable: false,\n configurable: false,\n });\n }\n\n // Maintains proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n // Assign props to instance, stripping reserved keys:\n // - _tag: discriminant for pattern matching (cannot be forged)\n // - name, message, stack: Error internals (preserve for logging/debugging)\n // - code, hint, docsUrl: spine fields stripped when slug is set, to prevent\n // Object.assign from clobbering the non-configurable/non-writable own props\n // Note: 'cause' is allowed as a user prop (common for domain errors)\n if (props && typeof props === \"object\") {\n let safeProps: Record<string, unknown>;\n if (options?.slug !== undefined) {\n const {\n _tag: _,\n name: _n,\n message: _m,\n stack: _s,\n code: _c,\n hint: _h,\n docsUrl: _d,\n ...rest\n } = props;\n safeProps = rest;\n } else {\n const {\n _tag: _,\n name: _n,\n message: _m,\n stack: _s,\n ...rest\n } = props;\n safeProps = rest;\n }\n\n const hasUserCause = Object.prototype.hasOwnProperty.call(\n safeProps,\n \"cause\"\n );\n const userCause = hasUserCause\n ? (safeProps as { cause?: unknown }).cause\n : undefined;\n if (hasUserCause) {\n delete (safeProps as { cause?: unknown }).cause;\n }\n\n const hasOptionsCause = errorOptions?.cause !== undefined;\n if (hasUserCause && hasOptionsCause) {\n throw new TypeError(\n \"TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause\"\n );\n }\n\n Object.assign(this, safeProps);\n\n if (hasUserCause) {\n (this as { cause?: unknown }).cause = userCause;\n }\n if (hasOptionsCause) {\n (this as { cause?: unknown }).cause = errorOptions?.cause;\n }\n } else if (errorOptions?.cause !== undefined) {\n (this as { cause?: unknown }).cause = errorOptions.cause;\n }\n }\n };\n}\n\n// Add Symbol.hasInstance so `instanceof TaggedError` works\nObject.defineProperty(TaggedError, Symbol.hasInstance, {\n value: (instance: unknown): boolean => instance instanceof InternalTaggedErrorBase,\n});\n\n/**\n * Namespace for static methods on TaggedError.\n */\n// eslint-disable-next-line @typescript-eslint/no-namespace\nnamespace TaggedError {\n /**\n * Type guard to check if a value is an Error instance.\n */\n export function isError(value: unknown): value is Error {\n return value instanceof Error;\n }\n\n /**\n * Type guard to check if a value is a TaggedError instance.\n * Uses the same check as `instanceof TaggedError` - only genuine\n * TaggedError instances (created via the factory) pass this guard.\n */\n export function isTaggedError(value: unknown): value is TaggedErrorBase {\n return value instanceof InternalTaggedErrorBase;\n }\n\n /**\n * Exhaustively matches on a tagged error, requiring handlers for all variants.\n *\n * TypeScript will error if any variant in the error union is not handled.\n *\n * @remarks When to use: You want compile-time enforcement that every tagged variant is handled.\n *\n * @param error - The tagged error to match\n * @param handlers - Object mapping _tag values to handler functions\n * @returns The return value of the matched handler\n *\n * @example\n * ```typescript\n * type AppError = NotFoundError | ValidationError;\n *\n * const message = TaggedError.match(error, {\n * NotFoundError: (e) => `Not found: ${e.id}`,\n * ValidationError: (e) => `Invalid: ${e.field}`,\n * });\n * ```\n */\n export function match<\n E extends TaggedErrorBase,\n H extends { [K in E[\"_tag\"]]: (e: Extract<E, { _tag: K }>) => unknown },\n >(error: E, handlers: H): HandlersReturnType<H> {\n const tag = error._tag as E[\"_tag\"];\n const handler = handlers[tag];\n return handler(\n error as Extract<E, { _tag: typeof tag }>\n ) as HandlersReturnType<H>;\n }\n\n /**\n * Partially matches on a tagged error with a fallback for unhandled variants.\n *\n * The fallback receives variants that are NOT definitely handled. A tag is\n * considered \"definitely handled\" only if its handler is a function (not\n * `undefined`). This ensures type safety even with dynamic/conditional handlers:\n *\n * ```typescript\n * const maybeHandle = featureFlag ? (e) => e.id : undefined;\n * TaggedError.matchPartial(\n * error,\n * { NotFoundError: maybeHandle }, // maybeHandle might be undefined\n * (e) => e._tag // e correctly includes NotFoundError\n * );\n * ```\n *\n * @param error - The tagged error to match\n * @param handlers - Partial object mapping _tag values to handler functions\n * @param otherwise - Fallback handler for unmatched variants\n * @returns The return value of the matched handler or fallback\n *\n * @example\n * ```typescript\n * const message = TaggedError.matchPartial(\n * error,\n * { NotFoundError: (e) => `Not found: ${e.id}` },\n * (e) => `Other error: ${e.message}`\n * );\n * ```\n */\n export function matchPartial<\n E extends TaggedErrorBase,\n H extends Partial<{\n [K in E[\"_tag\"]]: (e: Extract<E, { _tag: K }>) => unknown;\n }>,\n T,\n >(\n error: E,\n handlers: H,\n otherwise: (e: Exclude<E, { _tag: DefinitelyHandledKeys<H> }>) => T\n ): HandlersReturnType<H> | T {\n const tag = error._tag as E[\"_tag\"];\n const handler = handlers[tag];\n if (handler) {\n return handler(\n error as Extract<E, { _tag: typeof tag }>\n ) as HandlersReturnType<H>;\n }\n return otherwise(error as Exclude<E, { _tag: DefinitelyHandledKeys<H> }>);\n }\n}\n\nexport { TaggedError };\n\n/**\n * Helper type to extract the _tag literal type from a TaggedError.\n *\n * @example\n * ```typescript\n * class MyError extends TaggedError(\"MyError\")<{ id: string }> {}\n * type Tag = TagOf<MyError>; // \"MyError\"\n * ```\n */\nexport type TagOf<E extends TaggedErrorBase> = E[\"_tag\"];\n\n/**\n * Helper type to extract a specific variant from a TaggedError union by tag.\n *\n * @example\n * ```typescript\n * type AppError = NotFoundError | ValidationError;\n * type NotFound = ErrorByTag<AppError, \"NotFoundError\">; // NotFoundError\n * ```\n */\nexport type ErrorByTag<\n E extends TaggedErrorBase,\n Tag extends E[\"_tag\"],\n> = Extract<E, { _tag: Tag }>;\n\n/**\n * Reserved keys that are stripped from user props at runtime.\n * These keys cannot be used as user-defined properties:\n * - _tag: discriminant for pattern matching\n * - name, message, stack: Error internals (preserved for logging/debugging)\n * - code, hint, docsUrl: spine fields (non-configurable own properties when slug is set)\n *\n * Note: 'cause' is NOT reserved - it can be used as a user prop.\n */\ntype ReservedErrorKeys = \"_tag\" | \"name\" | \"message\" | \"stack\" | \"code\" | \"hint\" | \"docsUrl\";\n\n/**\n * Helper type to extract props from a TaggedError.\n * Excludes reserved keys that are stripped at runtime.\n *\n * @example\n * ```typescript\n * class MyError extends TaggedError(\"MyError\")<{ id: string }> {}\n * type Props = PropsOf<MyError>; // { id: string }\n *\n * // 'cause' is allowed as a user prop\n * class DomainError extends TaggedError(\"DomainError\")<{ cause: { field: string } }> {}\n * type DomainProps = PropsOf<DomainError>; // { cause: { field: string } }\n * ```\n */\nexport type PropsOf<E extends TaggedErrorBase> = Omit<E, ReservedErrorKeys>;\n","/**\n * awaitly/errors\n *\n * Pre-built error types for common failure scenarios.\n * Uses TaggedError for type-safe exhaustive matching.\n *\n * @example\n * ```typescript\n * import { TimeoutError, RetryExhaustedError, RateLimitError, CircuitBreakerOpenError } from 'awaitly/errors';\n *\n * // Create errors\n * const timeout = new TimeoutError({ operation: 'fetchUser', ms: 5000 });\n * const retryFailed = new RetryExhaustedError({ operation: 'sendEmail', attempts: 3 });\n *\n * // Pattern match\n * TaggedError.match(error, {\n * TimeoutError: (e) => `${e.operation} timed out after ${e.ms}ms`,\n * RetryExhaustedError: (e) => `${e.operation} failed after ${e.attempts} attempts`,\n * RateLimitError: (e) => `Rate limit exceeded, retry after ${e.retryAfterMs}ms`,\n * CircuitBreakerOpenError: (e) => `Circuit ${e.circuitName} is open`,\n * });\n * ```\n */\n\n/**\n * Spine policy:\n *\n * Awaitly-system errors (raised by awaitly internals on workflow execution\n * failure modes) carry a `slug` + `hint` so they participate in the\n * AI-DX spine: TimeoutError, RetryExhaustedError, RateLimitError,\n * CircuitBreakerOpenError, CompensationError, UnexpectedError.\n *\n * Convenience domain errors (ValidationError, NotFoundError,\n * UnauthorizedError, NetworkError) are deliberately NOT slugged — they\n * represent USER domain failures and would force user code into the\n * awaitly slug namespace. Users can opt in by adding `slug` + `hint`\n * to their own TaggedError subclasses.\n */\n\nimport { TaggedError } from \"./tagged-error\";\n\n// =============================================================================\n// Error Factory\n// =============================================================================\n\n/**\n * Factory function to create tagged error classes with default values.\n *\n * This is a convenience wrapper around TaggedError that allows specifying\n * default property values for error types.\n *\n * @example\n * ```typescript\n * const NetworkError = makeError('NetworkError', {\n * defaults: { retryable: true },\n * message: (p) => `Network error: ${p.reason}`,\n * });\n *\n * class MyNetworkError extends NetworkError<{ reason: string; code?: number }> {}\n * ```\n */\nexport function makeError<Tag extends string>(\n tag: Tag,\n options?: {\n message?: (props: Record<string, unknown>) => string;\n defaults?: Record<string, unknown>;\n }\n) {\n const messageGenerator = options?.message ?? (() => tag);\n const defaults = options?.defaults ?? {};\n\n const BaseClass = TaggedError(tag, {\n message: (props: Record<string, unknown>) =>\n messageGenerator({ ...defaults, ...props }),\n });\n\n return class extends BaseClass {\n constructor(props?: Record<string, unknown>) {\n super({ ...defaults, ...props } as Record<string, unknown>);\n Object.assign(this, { ...defaults, ...props });\n }\n };\n}\n\n// =============================================================================\n// Pre-built Error Types\n// =============================================================================\n\n/**\n * Error thrown when an operation times out.\n *\n * @example\n * ```typescript\n * const error = new TimeoutError({\n * operation: 'fetchUser',\n * ms: 5000,\n * });\n * console.log(error.message); // \"TimeoutError: fetchUser timed out after 5000ms\"\n * ```\n */\nexport class TimeoutError extends TaggedError(\"TimeoutError\", {\n slug: \"runtime-step-timeout\",\n hint: \"Increase the step's timeout option, or check why the upstream operation is slow.\",\n message: (p: {\n /** Name of the operation that timed out */\n operation?: string;\n /** Timeout duration in milliseconds */\n ms: number;\n }) =>\n p.operation\n ? `TimeoutError: ${p.operation} timed out after ${p.ms}ms`\n : `TimeoutError: Operation timed out after ${p.ms}ms`,\n}) {}\n\n/**\n * Error thrown when all retry attempts are exhausted.\n *\n * @example\n * ```typescript\n * const error = new RetryExhaustedError({\n * operation: 'sendEmail',\n * attempts: 3,\n * lastError: originalError,\n * });\n * console.log(error.message); // \"RetryExhaustedError: sendEmail failed after 3 attempts\"\n * ```\n */\nexport class RetryExhaustedError extends TaggedError(\"RetryExhaustedError\", {\n slug: \"runtime-retry-exhausted\",\n hint: \"All retry attempts failed. Inspect lastError and decide whether to surface it or compensate.\",\n message: (p: {\n /** Name of the operation that failed */\n operation?: string;\n /** Total number of retry attempts made */\n attempts: number;\n /** The last error encountered before giving up */\n lastError?: unknown;\n }) =>\n p.operation\n ? `RetryExhaustedError: ${p.operation} failed after ${p.attempts} attempts`\n : `RetryExhaustedError: Operation failed after ${p.attempts} attempts`,\n}) {}\n\n/**\n * Error thrown when a rate limit is exceeded.\n *\n * @example\n * ```typescript\n * const error = new RateLimitError({\n * limiterName: 'api-calls',\n * retryAfterMs: 1000,\n * });\n * console.log(error.message); // \"RateLimitError: Rate limit exceeded for api-calls\"\n * ```\n */\nexport class RateLimitError extends TaggedError(\"RateLimitError\", {\n slug: \"runtime-rate-limit\",\n hint: \"Wait retryAfterMs before retrying, or apply step.cache to deduplicate calls.\",\n message: (p: {\n /** Name of the rate limiter that was exceeded */\n limiterName?: string;\n /** Time in milliseconds until the rate limit resets */\n retryAfterMs?: number;\n }) =>\n p.limiterName\n ? `RateLimitError: Rate limit exceeded for ${p.limiterName}${p.retryAfterMs ? `, retry after ${p.retryAfterMs}ms` : \"\"}`\n : `RateLimitError: Rate limit exceeded${p.retryAfterMs ? `, retry after ${p.retryAfterMs}ms` : \"\"}`,\n}) {}\n\n/**\n * Error thrown when a circuit breaker is open.\n *\n * @example\n * ```typescript\n * const error = new CircuitBreakerOpenError({\n * circuitName: 'payment-api',\n * state: 'OPEN',\n * retryAfterMs: 30000,\n * });\n * console.log(error.message); // \"CircuitBreakerOpenError: Circuit payment-api is OPEN\"\n * ```\n */\nexport class CircuitBreakerOpenError extends TaggedError(\n \"CircuitBreakerOpenError\",\n {\n slug: \"runtime-circuit-open\",\n hint: \"The circuit is open. Wait for it to half-open or fall back to a degraded path.\",\n message: (p: {\n /** Name of the circuit breaker */\n circuitName: string;\n /** Current state of the circuit */\n state?: \"OPEN\" | \"HALF_OPEN\";\n /** Time in milliseconds until the circuit may close */\n retryAfterMs?: number;\n }) =>\n `CircuitBreakerOpenError: Circuit ${p.circuitName} is ${p.state ?? \"OPEN\"}${p.retryAfterMs ? `, retry after ${Math.ceil(p.retryAfterMs / 1000)}s` : \"\"}`,\n }\n) {}\n\n/**\n * Error thrown when validation fails.\n *\n * @example\n * ```typescript\n * const error = new ValidationError({\n * field: 'email',\n * reason: 'Invalid email format',\n * });\n * console.log(error.message); // \"ValidationError: Invalid email - Invalid email format\"\n * ```\n */\nexport class ValidationError extends TaggedError(\"ValidationError\", {\n message: (p: {\n /** Field that failed validation */\n field: string;\n /** Reason for validation failure */\n reason: string;\n /** Raw value that failed validation */\n value?: unknown;\n }) => `ValidationError: Invalid ${p.field} - ${p.reason}`,\n}) {}\n\n/**\n * Error thrown when a resource is not found.\n *\n * @example\n * ```typescript\n * const error = new NotFoundError({\n * resource: 'User',\n * id: '123',\n * });\n * console.log(error.message); // \"NotFoundError: User with id 123 not found\"\n * ```\n */\nexport class NotFoundError extends TaggedError(\"NotFoundError\", {\n message: (p: {\n /** Type of resource that was not found */\n resource: string;\n /** Identifier of the missing resource */\n id?: string;\n }) =>\n p.id\n ? `NotFoundError: ${p.resource} with id ${p.id} not found`\n : `NotFoundError: ${p.resource} not found`,\n}) {}\n\n/**\n * Error thrown when access is denied.\n *\n * @example\n * ```typescript\n * const error = new UnauthorizedError({\n * action: 'delete',\n * resource: 'User',\n * });\n * console.log(error.message); // \"UnauthorizedError: Not authorized to delete User\"\n * ```\n */\nexport class UnauthorizedError extends TaggedError(\"UnauthorizedError\", {\n message: (p: {\n /** Action that was attempted */\n action?: string;\n /** Resource that was being accessed */\n resource?: string;\n /** Reason for denial */\n reason?: string;\n }) =>\n p.reason\n ? `UnauthorizedError: ${p.reason}`\n : p.action && p.resource\n ? `UnauthorizedError: Not authorized to ${p.action} ${p.resource}`\n : \"UnauthorizedError: Access denied\",\n}) {}\n\n/**\n * Error thrown for network-related failures.\n *\n * @example\n * ```typescript\n * const error = new NetworkError({\n * url: 'https://api.example.com/users',\n * reason: 'Connection refused',\n * retryable: true,\n * });\n * ```\n */\nexport class NetworkError extends TaggedError(\"NetworkError\", {\n message: (p: {\n /** URL that was being accessed */\n url?: string;\n /** Reason for the network failure */\n reason: string;\n /** Whether this error is retryable */\n retryable?: boolean;\n /** HTTP status code if applicable */\n statusCode?: number;\n }) =>\n p.url\n ? `NetworkError: ${p.reason} (${p.url})`\n : `NetworkError: ${p.reason}`,\n}) {}\n\n/**\n * Error thrown when a saga compensation fails.\n *\n * @example\n * ```typescript\n * const error = new CompensationError({\n * step: 'chargeCard',\n * originalError: paymentError,\n * compensationError: refundError,\n * });\n * ```\n */\nexport class CompensationError extends TaggedError(\"CompensationError\", {\n slug: \"runtime-saga-compensation\",\n hint: \"A saga compensation step failed. Inspect compensationError and ensure compensation is idempotent.\",\n message: (p: {\n /** Step that triggered compensation */\n step: string;\n /** The original error that caused compensation */\n originalError?: unknown;\n /** Error that occurred during compensation */\n compensationError?: unknown;\n }) => `CompensationError: Failed to compensate step ${p.step}`,\n}) {}\n\n// =============================================================================\n// Unexpected Error\n// =============================================================================\n\n/**\n * Default error type for uncaught exceptions and cancellation in workflows.\n * This is the default `U` type when `catchUnexpected` is not provided.\n *\n * @example\n * ```typescript\n * // Automatically used as the default — no need to pass catchUnexpected:\n * const workflow = createWorkflow(\"checkout\", { chargeCard, sendEmail });\n *\n * // Equivalent to:\n * const workflow = createWorkflow(\"checkout\", { chargeCard, sendEmail }, {\n * catchUnexpected: (cause) => new UnexpectedError({ cause }),\n * });\n * ```\n */\nexport class UnexpectedError extends TaggedError(\"UnexpectedError\", {\n slug: \"runtime-unexpected\",\n hint: \"An unexpected exception escaped a step. Inspect cause; consider returning a typed Result instead of throwing.\",\n message: (p: {\n /** The original thrown value or cancellation error */\n cause?: unknown;\n }) => `UnexpectedError: ${p.cause instanceof Error ? p.cause.message : String(p.cause ?? \"unknown\")}`,\n}) {}\n\n// =============================================================================\n// Union Type for Common Errors\n// =============================================================================\n\n/**\n * Union of all pre-built error types.\n * Useful for exhaustive pattern matching.\n *\n * @example\n * ```typescript\n * function handleError(error: AwaitlyError): string {\n * return TaggedError.match(error, {\n * TimeoutError: (e) => `Timeout: ${e.ms}ms`,\n * RetryExhaustedError: (e) => `Retries: ${e.attempts}`,\n * RateLimitError: (e) => `Rate limited`,\n * CircuitBreakerOpenError: (e) => `Circuit open: ${e.circuitName}`,\n * ValidationError: (e) => `Invalid: ${e.field}`,\n * NotFoundError: (e) => `Not found: ${e.resource}`,\n * UnauthorizedError: (e) => `Unauthorized`,\n * NetworkError: (e) => `Network: ${e.reason}`,\n * CompensationError: (e) => `Compensation failed: ${e.step}`,\n * UnexpectedError: (e) => e.message,\n * });\n * }\n * ```\n */\nexport type AwaitlyError =\n | TimeoutError\n | RetryExhaustedError\n | RateLimitError\n | CircuitBreakerOpenError\n | ValidationError\n | NotFoundError\n | UnauthorizedError\n | NetworkError\n | CompensationError\n | UnexpectedError;\n\n/**\n * The six awaitly-system errors that carry slug + hint + docsUrl spine fields.\n *\n * Distinguishes spine-bearing errors from user-domain convenience errors\n * (ValidationError, NotFoundError, UnauthorizedError, NetworkError) so that\n * downstream tooling (lint, analyzer, docs generator) can target the spine\n * roster without duplicating the class list.\n */\nexport type AwaitlySystemError =\n | TimeoutError\n | RetryExhaustedError\n | RateLimitError\n | CircuitBreakerOpenError\n | CompensationError\n | UnexpectedError;\n\n/**\n * Roster of awaitly-system error classes that participate in the slug spine.\n *\n * Adding a new system error means adding it to `AwaitlySystemError`, this\n * roster, and `slugs.ts`. The integrity test in `spine-integrity.test.ts`\n * iterates this roster, so a missing entry there is caught at CI time.\n *\n * @internal Tooling integration point (docs generator, integrity tests). Not\n * a stable user-facing API — application code should not depend on this\n * array's identity or order.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const AWAITLY_SYSTEM_ERROR_CLASSES: ReadonlyArray<new (...args: any[]) => AwaitlySystemError> = [\n TimeoutError,\n RetryExhaustedError,\n RateLimitError,\n CircuitBreakerOpenError,\n CompensationError,\n UnexpectedError,\n];\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Check if an error is a TimeoutError.\n */\nexport function isTimeoutError(error: unknown): error is TimeoutError {\n return TaggedError.isTaggedError(error) && error._tag === \"TimeoutError\";\n}\n\n/**\n * Check if an error is a RetryExhaustedError.\n */\nexport function isRetryExhaustedError(\n error: unknown\n): error is RetryExhaustedError {\n return (\n TaggedError.isTaggedError(error) && error._tag === \"RetryExhaustedError\"\n );\n}\n\n/**\n * Check if an error is a RateLimitError.\n */\nexport function isRateLimitError(error: unknown): error is RateLimitError {\n return TaggedError.isTaggedError(error) && error._tag === \"RateLimitError\";\n}\n\n/**\n * Check if an error is a CircuitBreakerOpenError.\n */\nexport function isCircuitBreakerOpenError(\n error: unknown\n): error is CircuitBreakerOpenError {\n return (\n TaggedError.isTaggedError(error) && error._tag === \"CircuitBreakerOpenError\"\n );\n}\n\n/**\n * Check if an error is a ValidationError.\n */\nexport function isValidationError(error: unknown): error is ValidationError {\n return TaggedError.isTaggedError(error) && error._tag === \"ValidationError\";\n}\n\n/**\n * Check if an error is a NotFoundError.\n */\nexport function isNotFoundError(error: unknown): error is NotFoundError {\n return TaggedError.isTaggedError(error) && error._tag === \"NotFoundError\";\n}\n\n/**\n * Check if an error is an UnauthorizedError.\n */\nexport function isUnauthorizedError(\n error: unknown\n): error is UnauthorizedError {\n return TaggedError.isTaggedError(error) && error._tag === \"UnauthorizedError\";\n}\n\n/**\n * Check if an error is a NetworkError.\n */\nexport function isNetworkError(error: unknown): error is NetworkError {\n return TaggedError.isTaggedError(error) && error._tag === \"NetworkError\";\n}\n\n/**\n * Check if an error is a CompensationError.\n */\nexport function isCompensationError(\n error: unknown\n): error is CompensationError {\n return TaggedError.isTaggedError(error) && error._tag === \"CompensationError\";\n}\n\n/**\n * Check if an error is any AwaitlyError.\n */\nexport function isAwaitlyError(error: unknown): error is AwaitlyError {\n if (!TaggedError.isTaggedError(error)) return false;\n const tag = error._tag;\n return [\n \"TimeoutError\",\n \"RetryExhaustedError\",\n \"RateLimitError\",\n \"CircuitBreakerOpenError\",\n \"ValidationError\",\n \"NotFoundError\",\n \"UnauthorizedError\",\n \"NetworkError\",\n \"CompensationError\",\n \"UnexpectedError\",\n ].includes(tag);\n}\n","/**\n * awaitly/functional\n *\n * Effect-inspired functional utilities for Result types.\n * Provides pipe-based composition with automatic error short-circuiting.\n */\n\nimport type { Result, AsyncResult, PromiseRejectedError, PromiseRejectionCause } from \"../result\";\nimport { ok, err, isOk, isErr, PROMISE_REJECTED } from \"../result\";\n\n// =============================================================================\n// Composition\n// =============================================================================\n\n/**\n * Pipe a value through a series of functions left-to-right.\n *\n * @example\n * ```typescript\n * const result = pipe(\n * 5,\n * (x) => x * 2,\n * (x) => x + 1\n * ); // 11\n * ```\n */\nexport function pipe<A>(a: A): A;\nexport function pipe<A, B>(a: A, ab: (a: A) => B): B;\nexport function pipe<A, B, C>(a: A, ab: (a: A) => B, bc: (b: B) => C): C;\nexport function pipe<A, B, C, D>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D;\nexport function pipe<A, B, C, D, E>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E\n): E;\nexport function pipe<A, B, C, D, E, F>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F\n): F;\nexport function pipe<A, B, C, D, E, F, G>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G\n): G;\nexport function pipe<A, B, C, D, E, F, G, H>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H\n): H;\nexport function pipe<A, B, C, D, E, F, G, H, I>(\n a: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I\n): I;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function pipe(a: unknown, ...fns: Array<(x: any) => any>): unknown {\n return fns.reduce((acc, fn) => fn(acc), a);\n}\n\n/**\n * Compose functions left-to-right (returns a function).\n *\n * @example\n * ```typescript\n * const double = (x: number) => x * 2;\n * const addOne = (x: number) => x + 1;\n * const transform = flow(double, addOne);\n * transform(5); // 11\n * ```\n */\nexport function flow<A, B>(ab: (a: A) => B): (a: A) => B;\nexport function flow<A, B, C>(ab: (a: A) => B, bc: (b: B) => C): (a: A) => C;\nexport function flow<A, B, C, D>(ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): (a: A) => D;\nexport function flow<A, B, C, D, E>(\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E\n): (a: A) => E;\nexport function flow<A, B, C, D, E, F>(\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F\n): (a: A) => F;\nexport function flow<A, B, C, D, E, F, G>(\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G\n): (a: A) => G;\nexport function flow<A, B, C, D, E, F, G, H>(\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H\n): (a: A) => H;\nexport function flow<A, B, C, D, E, F, G, H, I>(\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I\n): (a: A) => I;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function flow(...fns: Array<(x: any) => any>): (a: unknown) => unknown {\n return (a: unknown) => fns.reduce((acc, fn) => fn(acc), a);\n}\n\n/**\n * Compose functions right-to-left.\n *\n * @example\n * ```typescript\n * const double = (x: number) => x * 2;\n * const addOne = (x: number) => x + 1;\n * const transform = compose(addOne, double);\n * transform(5); // 11 (double first, then addOne)\n * ```\n */\nexport function compose<A, B>(ab: (a: A) => B): (a: A) => B;\nexport function compose<A, B, C>(bc: (b: B) => C, ab: (a: A) => B): (a: A) => C;\nexport function compose<A, B, C, D>(cd: (c: C) => D, bc: (b: B) => C, ab: (a: A) => B): (a: A) => D;\nexport function compose<A, B, C, D, E>(\n de: (d: D) => E,\n cd: (c: C) => D,\n bc: (b: B) => C,\n ab: (a: A) => B\n): (a: A) => E;\nexport function compose<A, B, C, D, E, F>(\n ef: (e: E) => F,\n de: (d: D) => E,\n cd: (c: C) => D,\n bc: (b: B) => C,\n ab: (a: A) => B\n): (a: A) => F;\nexport function compose<A, B, C, D, E, F, G>(\n fg: (f: F) => G,\n ef: (e: E) => F,\n de: (d: D) => E,\n cd: (c: C) => D,\n bc: (b: B) => C,\n ab: (a: A) => B\n): (a: A) => G;\nexport function compose<A, B, C, D, E, F, G, H>(\n gh: (g: G) => H,\n fg: (f: F) => G,\n ef: (e: E) => F,\n de: (d: D) => E,\n cd: (c: C) => D,\n bc: (b: B) => C,\n ab: (a: A) => B\n): (a: A) => H;\nexport function compose<A, B, C, D, E, F, G, H, I>(\n hi: (h: H) => I,\n gh: (g: G) => H,\n fg: (f: F) => G,\n ef: (e: E) => F,\n de: (d: D) => E,\n cd: (c: C) => D,\n bc: (b: B) => C,\n ab: (a: A) => B\n): (a: A) => I;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function compose(...fns: Array<(x: any) => any>): (a: unknown) => unknown {\n return (a: unknown) => fns.reduceRight((acc, fn) => fn(acc), a);\n}\n\n/**\n * Identity function - returns its argument unchanged.\n *\n * @example\n * ```typescript\n * identity(42); // 42\n * ```\n */\nexport const identity = <A>(a: A): A => a;\n\n// =============================================================================\n// Result Combinators (sync)\n// =============================================================================\n\n/**\n * Transform the success value of a Result.\n *\n * @example\n * ```typescript\n * const result = Awaitly.ok(5);\n * map(result, (x) => x * 2); // Awaitly.ok(10)\n *\n * const error = Awaitly.err(\"not found\");\n * map(error, (x) => x * 2); // Awaitly.err(\"not found\")\n * ```\n */\nexport function map<T, U, E, C>(result: Result<T, E, C>, fn: (value: T) => U): Result<U, E, C> {\n if (isOk(result)) {\n return ok(fn(result.value));\n }\n return result as Result<U, E, C>;\n}\n\n/**\n * Transform and flatten (short-circuits on error).\n *\n * @example\n * ```typescript\n * const divide = (a: number, b: number): Result<number, string> =>\n * b === 0 ? Awaitly.err(\"division by zero\") : Awaitly.ok(a / b);\n *\n * const result = Awaitly.ok(10);\n * flatMap(result, (x) => divide(x, 2)); // Awaitly.ok(5)\n * flatMap(result, (x) => divide(x, 0)); // Awaitly.err(\"division by zero\")\n * ```\n */\nexport function flatMap<T, U, E1, E2, C1, C2>(\n result: Result<T, E1, C1>,\n fn: (value: T) => Result<U, E2, C2>\n): Result<U, E1 | E2, C1 | C2> {\n if (isOk(result)) {\n return fn(result.value);\n }\n return result as Result<U, E1 | E2, C1 | C2>;\n}\n\n/**\n * Transform both success and error values.\n *\n * @example\n * ```typescript\n * const result = Awaitly.ok(5);\n * bimap(result, (x) => x * 2, (e) => `Error: ${e}`); // Awaitly.ok(10)\n *\n * const error = Awaitly.err(\"not found\");\n * bimap(error, (x) => x * 2, (e) => `Error: ${e}`); // Awaitly.err(\"Error: not found\")\n * ```\n */\nexport function bimap<T, U, E1, E2, C>(\n result: Result<T, E1, C>,\n onOk: (value: T) => U,\n onErr: (error: E1) => E2\n): Result<U, E2, C> {\n if (isOk(result)) {\n return ok(onOk(result.value));\n }\n return err(onErr(result.error), { cause: result.cause }) as Result<U, E2, C>;\n}\n\n/**\n * Transform the error value.\n *\n * @example\n * ```typescript\n * const error = Awaitly.err(\"not found\");\n * mapError(error, (e) => ({ type: \"ERROR\", message: e }));\n * // Awaitly.err({ type: \"ERROR\", message: \"not found\" })\n * ```\n */\nexport function mapError<T, E1, E2, C>(\n result: Result<T, E1, C>,\n fn: (error: E1) => E2\n): Result<T, E2, C> {\n if (isErr(result)) {\n return err(fn(result.error), { cause: result.cause }) as Result<T, E2, C>;\n }\n return result as Result<T, E2, C>;\n}\n\n/**\n * Side effect on success (returns original result).\n *\n * @example\n * ```typescript\n * const result = Awaitly.ok(5);\n * tap(result, (x) => console.log(`Value: ${x}`)); // logs \"Value: 5\", returns Awaitly.ok(5)\n * ```\n */\nexport function tap<T, E, C>(result: Result<T, E, C>, fn: (value: T) => void): Result<T, E, C> {\n if (isOk(result)) {\n fn(result.value);\n }\n return result;\n}\n\n/**\n * Side effect on error (returns original result).\n *\n * @example\n * ```typescript\n * const error = Awaitly.err(\"not found\");\n * tapError(error, (e) => console.log(`Error: ${e}`)); // logs \"Error: not found\", returns err\n * ```\n */\nexport function tapError<T, E, C>(result: Result<T, E, C>, fn: (error: E) => void): Result<T, E, C> {\n if (isErr(result)) {\n fn(result.error);\n }\n return result;\n}\n\n/**\n * Pattern match on Result.\n *\n * @example\n * ```typescript\n * const result = Awaitly.ok(5);\n * match(result, {\n * ok: (x) => `Success: ${x}`,\n * err: (e) => `Error: ${e}`\n * }); // \"Success: 5\"\n * ```\n */\nexport function match<T, E, U, C>(\n result: Result<T, E, C>,\n patterns: { ok: (value: T) => U; err: (error: E, cause?: C) => U }\n): U {\n if (isOk(result)) {\n return patterns.ok(result.value);\n }\n return patterns.err(result.error, result.cause);\n}\n\n/**\n * Recover from error by providing fallback value.\n *\n * @example\n * ```typescript\n * const error = Awaitly.err(\"not found\");\n * recover(error, () => 0); // 0\n *\n * const success = Awaitly.ok(5);\n * recover(success, () => 0); // 5\n * ```\n */\nexport function recover<T, E, C>(result: Result<T, E, C>, fn: (error: E) => T): T {\n if (isOk(result)) {\n return result.value;\n }\n return fn(result.error);\n}\n\n/**\n * Recover from error with another Result.\n *\n * @example\n * ```typescript\n * const error = Awaitly.err(\"not found\");\n * recoverWith(error, (e) => ok(0)); // ok(0)\n * recoverWith(error, (e) => err(\"still failed\")); // err(\"still failed\")\n * ```\n */\nexport function recoverWith<T, E1, E2, C1, C2>(\n result: Result<T, E1, C1>,\n fn: (error: E1) => Result<T, E2, C2>\n): Result<T, E2, C1 | C2> {\n if (isOk(result)) {\n return result as Result<T, E2, C1 | C2>;\n }\n return fn(result.error);\n}\n\n/**\n * Get the value or a default.\n *\n * @example\n * ```typescript\n * const error = Awaitly.err(\"not found\");\n * getOrElse(error, 0); // 0\n *\n * const success = Awaitly.ok(5);\n * getOrElse(success, 0); // 5\n * ```\n */\nexport function getOrElse<T, E, C>(result: Result<T, E, C>, defaultValue: T): T {\n if (isOk(result)) {\n return result.value;\n }\n return defaultValue;\n}\n\n/**\n * Get the value or compute a default lazily.\n *\n * @example\n * ```typescript\n * const error = Awaitly.err(\"not found\");\n * getOrElseLazy(error, () => expensiveComputation()); // calls expensiveComputation()\n *\n * const success = Awaitly.ok(5);\n * getOrElseLazy(success, () => expensiveComputation()); // 5, doesn't call expensiveComputation\n * ```\n */\nexport function getOrElseLazy<T, E, C>(result: Result<T, E, C>, fn: () => T): T {\n if (isOk(result)) {\n return result.value;\n }\n return fn();\n}\n\n// =============================================================================\n// Result Combinators (async)\n// =============================================================================\n\n/**\n * Transform success value asynchronously.\n *\n * @example\n * ```typescript\n * const result = Awaitly.ok(5);\n * await mapAsync(result, async (x) => x * 2); // ok(10)\n * ```\n */\nexport async function mapAsync<T, U, E, C>(\n result: Result<T, E, C> | AsyncResult<T, E, C>,\n fn: (value: T) => Promise<U>\n): AsyncResult<U, E, C> {\n const resolved = await result;\n if (isOk(resolved)) {\n return ok(await fn(resolved.value));\n }\n return resolved as Result<U, E, C>;\n}\n\n/**\n * Async flatMap.\n *\n * @example\n * ```typescript\n * const fetchUser = async (id: string): AsyncResult<User, \"NOT_FOUND\"> => { ... };\n * const result = Awaitly.ok(\"user-123\");\n * await flatMapAsync(result, fetchUser); // AsyncResult<User, \"NOT_FOUND\">\n * ```\n */\nexport async function flatMapAsync<T, U, E1, E2, C1, C2>(\n result: Result<T, E1, C1> | AsyncResult<T, E1, C1>,\n fn: (value: T) => AsyncResult<U, E2, C2>\n): AsyncResult<U, E1 | E2, C1 | C2> {\n const resolved = await result;\n if (isOk(resolved)) {\n return fn(resolved.value);\n }\n return resolved as Result<U, E1 | E2, C1 | C2>;\n}\n\n/**\n * Async tap - side effect on success.\n *\n * @example\n * ```typescript\n * const result = Awaitly.ok(5);\n * await tapAsync(result, async (x) => {\n * await logToServer(x);\n * }); // ok(5)\n * ```\n */\nexport async function tapAsync<T, E, C>(\n result: Result<T, E, C> | AsyncResult<T, E, C>,\n fn: (value: T) => Promise<void>\n): AsyncResult<T, E, C> {\n const resolved = await result;\n if (isOk(resolved)) {\n await fn(resolved.value);\n }\n return resolved;\n}\n\n/**\n * Async tapError - side effect on error.\n *\n * @example\n * ```typescript\n * const error = Awaitly.err(\"not found\");\n * await tapErrorAsync(error, async (e) => {\n * await logErrorToServer(e);\n * }); // err(\"not found\")\n * ```\n */\nexport async function tapErrorAsync<T, E, C>(\n result: Result<T, E, C> | AsyncResult<T, E, C>,\n fn: (error: E) => Promise<void>\n): AsyncResult<T, E, C> {\n const resolved = await result;\n if (isErr(resolved)) {\n await fn(resolved.error);\n }\n return resolved;\n}\n\n// =============================================================================\n// Collection Utilities (Result-aware)\n// =============================================================================\n\n/**\n * Combine array of Results - fails fast on first error.\n *\n * @example\n * ```typescript\n * all([ok(1), ok(2), ok(3)]); // ok([1, 2, 3])\n * all([ok(1), err(\"fail\"), ok(3)]); // err(\"fail\")\n * ```\n */\nexport function all<T, E, C>(results: Result<T, E, C>[]): Result<T[], E, C> {\n const values: T[] = [];\n for (const result of results) {\n if (isErr(result)) {\n return result as Result<T[], E, C>;\n }\n values.push(result.value);\n }\n return ok(values);\n}\n\n/**\n * Combine array of AsyncResults - parallel execution, fails fast.\n *\n * Returns immediately when any result fails, without waiting for\n * pending promises. Only returns all values if every result succeeds.\n *\n * @example\n * ```typescript\n * await allAsync([\n * fetchUser(\"1\"),\n * fetchUser(\"2\"),\n * fetchUser(\"3\")\n * ]); // AsyncResult<User[], \"NOT_FOUND\">\n * ```\n */\nexport async function allAsync<T, E, C>(\n results: AsyncResult<T, E, C>[]\n): AsyncResult<T[], E | PromiseRejectedError, C | PromiseRejectionCause> {\n if (results.length === 0) {\n return ok([]);\n }\n\n const values: T[] = new Array(results.length);\n let settledCount = 0;\n let done = false;\n\n return new Promise((resolve) => {\n results.forEach((resultPromise, index) => {\n resultPromise.then(\n (result) => {\n if (done) return;\n if (isErr(result)) {\n done = true;\n resolve(result as Result<T[], E | PromiseRejectedError, C | PromiseRejectionCause>);\n } else {\n values[index] = result.value;\n settledCount++;\n if (settledCount === results.length) {\n done = true;\n resolve(ok(values));\n }\n }\n },\n (reason) => {\n if (done) return;\n done = true;\n resolve(\n err(\n { type: PROMISE_REJECTED, cause: reason } as PromiseRejectedError,\n { cause: { type: \"PROMISE_REJECTION\" as const, reason } as PromiseRejectionCause }\n )\n );\n }\n );\n });\n });\n}\n\n/**\n * Collect all results, separating successes and failures.\n *\n * @example\n * ```typescript\n * allSettled([ok(1), err(\"a\"), ok(2), err(\"b\")]);\n * // { ok: [1, 2], err: [\"a\", \"b\"] }\n * ```\n */\nexport function allSettled<T, E, C>(results: Result<T, E, C>[]): { ok: T[]; err: E[] } {\n const okValues: T[] = [];\n const errValues: E[] = [];\n for (const result of results) {\n if (isOk(result)) {\n okValues.push(result.value);\n } else {\n errValues.push(result.error);\n }\n }\n return { ok: okValues, err: errValues };\n}\n\n/**\n * Async version of allSettled.\n *\n * Handles rejected promises by treating them as errors with\n * type PROMISE_REJECTED.\n *\n * @example\n * ```typescript\n * await allSettledAsync([\n * fetchUser(\"1\"),\n * fetchUser(\"2\"),\n * fetchUser(\"3\")\n * ]); // { ok: [...users], err: [...errors] }\n * ```\n */\nexport async function allSettledAsync<T, E, C>(\n results: AsyncResult<T, E, C>[]\n): Promise<{ ok: T[]; err: (E | PromiseRejectedError)[] }> {\n if (results.length === 0) {\n return { ok: [], err: [] };\n }\n\n type Settled = { type: \"ok\"; value: T } | { type: \"err\"; error: E | PromiseRejectedError };\n const settled: Settled[] = new Array(results.length);\n let settledCount = 0;\n\n return new Promise((resolve) => {\n results.forEach((resultPromise, index) => {\n resultPromise.then(\n (result) => {\n if (isOk(result)) {\n settled[index] = { type: \"ok\", value: result.value };\n } else {\n settled[index] = { type: \"err\", error: result.error };\n }\n settledCount++;\n if (settledCount === results.length) {\n const okValues: T[] = [];\n const errValues: (E | PromiseRejectedError)[] = [];\n for (const s of settled) {\n if (s.type === \"ok\") {\n okValues.push(s.value);\n } else {\n errValues.push(s.error);\n }\n }\n resolve({ ok: okValues, err: errValues });\n }\n },\n (reason) => {\n settled[index] = { type: \"err\", error: { type: PROMISE_REJECTED, cause: reason } as PromiseRejectedError };\n settledCount++;\n if (settledCount === results.length) {\n const okValues: T[] = [];\n const errValues: (E | PromiseRejectedError)[] = [];\n for (const s of settled) {\n if (s.type === \"ok\") {\n okValues.push(s.value);\n } else {\n errValues.push(s.error);\n }\n }\n resolve({ ok: okValues, err: errValues });\n }\n }\n );\n });\n });\n}\n\n/**\n * Return first success, or all errors if all fail.\n *\n * @example\n * ```typescript\n * any([err(\"a\"), ok(1), err(\"b\")]); // ok(1)\n * any([err(\"a\"), err(\"b\"), err(\"c\")]); // err([\"a\", \"b\", \"c\"])\n * ```\n */\nexport function any<T, E, C>(results: Result<T, E, C>[]): Result<T, E[], C> {\n const errors: E[] = [];\n for (const result of results) {\n if (isOk(result)) {\n return result as Result<T, E[], C>;\n }\n errors.push(result.error);\n }\n return err(errors);\n}\n\n/**\n * Async version of any - returns first success immediately.\n *\n * Returns as soon as any result succeeds, without waiting for\n * pending promises. Only returns all errors if every result fails.\n *\n * @example\n * ```typescript\n * await anyAsync([\n * fetchFromCache(key),\n * fetchFromDb(key),\n * fetchFromApi(key)\n * ]); // First successful result\n * ```\n */\nexport async function anyAsync<T, E, C>(\n results: AsyncResult<T, E, C>[]\n): AsyncResult<T, (E | PromiseRejectedError)[], C | PromiseRejectionCause> {\n if (results.length === 0) {\n return err([]);\n }\n\n const errors: (E | PromiseRejectedError | undefined)[] = new Array(results.length);\n let settledCount = 0;\n let done = false;\n\n return new Promise((resolve) => {\n results.forEach((resultPromise, index) => {\n resultPromise.then(\n (result) => {\n if (done) return;\n if (isOk(result)) {\n done = true;\n resolve(result as Result<T, (E | PromiseRejectedError)[], C | PromiseRejectionCause>);\n } else {\n errors[index] = result.error;\n settledCount++;\n if (settledCount === results.length) {\n done = true;\n resolve(err(errors.filter((e): e is E | PromiseRejectedError => e !== undefined)));\n }\n }\n },\n (reason) => {\n if (done) return;\n errors[index] = { type: PROMISE_REJECTED, cause: reason } as PromiseRejectedError;\n settledCount++;\n if (settledCount === results.length) {\n done = true;\n resolve(err(errors.filter((e): e is E | PromiseRejectedError => e !== undefined)));\n }\n }\n );\n });\n });\n}\n\n/**\n * Race async results - first to complete wins.\n *\n * Handles rejected promises by converting them to err() results\n * with type PROMISE_REJECTED.\n *\n * @example\n * ```typescript\n * await race([\n * fetchFromPrimaryServer(id),\n * fetchFromBackupServer(id)\n * ]); // Result from whichever server responds first\n * ```\n */\nexport async function race<T, E, C>(\n results: AsyncResult<T, E, C>[]\n): AsyncResult<T, E | PromiseRejectedError, C | PromiseRejectionCause> {\n return Promise.race(\n results.map((p) =>\n p.catch(\n (reason) =>\n err(\n { type: PROMISE_REJECTED, cause: reason } as PromiseRejectedError,\n { cause: { type: \"PROMISE_REJECTION\" as const, reason } as PromiseRejectionCause }\n ) as Result<T, E | PromiseRejectedError, C | PromiseRejectionCause>\n )\n )\n );\n}\n\n/**\n * Sequence an array through a Result-returning function.\n * Stops on first error.\n *\n * @example\n * ```typescript\n * const validate = (x: number): Result<number, string> =>\n * x > 0 ? ok(x) : err(\"must be positive\");\n *\n * traverse([1, 2, 3], validate); // ok([1, 2, 3])\n * traverse([1, -2, 3], validate); // err(\"must be positive\")\n * ```\n */\nexport function traverse<T, U, E, C>(\n items: T[],\n fn: (item: T, index: number) => Result<U, E, C>\n): Result<U[], E, C> {\n const results: U[] = [];\n for (let i = 0; i < items.length; i++) {\n const result = fn(items[i]!, i);\n if (isErr(result)) {\n return result as Result<U[], E, C>;\n }\n results.push(result.value);\n }\n return ok(results);\n}\n\n/**\n * Async version of traverse.\n *\n * @example\n * ```typescript\n * await traverseAsync(userIds, async (id) => fetchUser(id));\n * ```\n */\nexport async function traverseAsync<T, U, E, C>(\n items: T[],\n fn: (item: T, index: number) => AsyncResult<U, E, C>\n): AsyncResult<U[], E, C> {\n const results: U[] = [];\n for (let i = 0; i < items.length; i++) {\n const result = await fn(items[i]!, i);\n if (isErr(result)) {\n return result as Result<U[], E, C>;\n }\n results.push(result.value);\n }\n return ok(results);\n}\n\n/**\n * Parallel traverse - executes all in parallel, fails fast.\n *\n * Returns immediately when any result fails, without waiting for\n * pending operations. Only returns all values if every result succeeds.\n *\n * @example\n * ```typescript\n * await traverseParallel(userIds, fetchUser);\n * ```\n */\nexport async function traverseParallel<T, U, E, C>(\n items: T[],\n fn: (item: T, index: number) => AsyncResult<U, E, C>\n): AsyncResult<U[], E | PromiseRejectedError, C | PromiseRejectionCause> {\n return allAsync(items.map((item, index) => fn(item, index)));\n}\n\n// =============================================================================\n// Pipeable Result Functions (R namespace)\n// =============================================================================\n\n/**\n * Curried Result combinators for use in pipe().\n *\n * @example\n * ```typescript\n * import { pipe, R } from 'awaitly/functional';\n *\n * const result = pipe(\n * fetchUser(id),\n * R.flatMap(user => fetchPosts(user.id)),\n * R.map(posts => posts.filter(p => p.published)),\n * R.tap(posts => console.log(`Found ${posts.length} posts`)),\n * R.match({\n * ok: posts => `Found ${posts.length} posts`,\n * err: error => `Failed: ${error}`\n * })\n * );\n * ```\n */\nexport const R = {\n /** Curried map for use in pipe() */\n map:\n <T, U, E, C>(fn: (value: T) => U) =>\n (result: Result<T, E, C>): Result<U, E, C> =>\n map(result, fn),\n\n /** Curried flatMap for use in pipe() */\n flatMap:\n <T, U, E1, E2, C1, C2>(fn: (value: T) => Result<U, E2, C2>) =>\n (result: Result<T, E1, C1>): Result<U, E1 | E2, C1 | C2> =>\n flatMap(result, fn),\n\n /** Curried bimap for use in pipe() */\n bimap:\n <T, U, E1, E2, C>(onOk: (value: T) => U, onErr: (error: E1) => E2) =>\n (result: Result<T, E1, C>): Result<U, E2, C> =>\n bimap(result, onOk, onErr),\n\n /** Curried mapError for use in pipe() */\n mapError:\n <T, E1, E2, C>(fn: (error: E1) => E2) =>\n (result: Result<T, E1, C>): Result<T, E2, C> =>\n mapError(result, fn),\n\n /** Curried tap for use in pipe() */\n tap:\n <T, E, C>(fn: (value: T) => void) =>\n (result: Result<T, E, C>): Result<T, E, C> =>\n tap(result, fn),\n\n /** Curried tapError for use in pipe() */\n tapError:\n <T, E, C>(fn: (error: E) => void) =>\n (result: Result<T, E, C>): Result<T, E, C> =>\n tapError(result, fn),\n\n /** Curried match for use in pipe() */\n match:\n <T, E, U, C>(patterns: { ok: (value: T) => U; err: (error: E, cause?: C) => U }) =>\n (result: Result<T, E, C>): U =>\n match(result, patterns),\n\n /** Curried recover for use in pipe() */\n recover:\n <T, E, C>(fn: (error: E) => T) =>\n (result: Result<T, E, C>): T =>\n recover(result, fn),\n\n /** Curried recoverWith for use in pipe() */\n recoverWith:\n <T, E1, E2, C1, C2>(fn: (error: E1) => Result<T, E2, C2>) =>\n (result: Result<T, E1, C1>): Result<T, E2, C1 | C2> =>\n recoverWith(result, fn),\n\n /** Curried getOrElse for use in pipe() */\n getOrElse:\n <T, E, C>(defaultValue: T) =>\n (result: Result<T, E, C>): T =>\n getOrElse(result, defaultValue),\n\n /** Curried getOrElseLazy for use in pipe() */\n getOrElseLazy:\n <T, E, C>(fn: () => T) =>\n (result: Result<T, E, C>): T =>\n getOrElseLazy(result, fn),\n};\n","import type { UnexpectedError } from \"./core\";\nimport type { RunConfig, Workflow } from \"./workflow/types\";\n\n/**\n * Pre-bind dependency overrides on a workflow.\n *\n * Returns another `Workflow` with the same shape — chain `.withDeps()`,\n * call `.run()` / `.runWithState()` exactly as before.\n *\n * Precedence (lowest → highest):\n * createWorkflow deps < withDeps deps < run config deps\n */\nexport function withDeps<E, U = UnexpectedError, Deps = unknown, C = void>(\n workflow: Workflow<E, U, Deps, C>,\n overrides: Partial<Deps>\n): Workflow<E, U, Deps, C> {\n const forward = <Method extends \"run\" | \"runWithState\">(method: Method) =>\n ((...args: unknown[]) => {\n const last = args.at(-1);\n const hasConfig =\n args.length > 0 &&\n typeof last === \"object\" &&\n last !== null &&\n !Array.isArray(last) &&\n typeof last !== \"function\";\n\n const config = hasConfig ? (last as RunConfig<E, U, C, Deps>) : undefined;\n const head = hasConfig ? args.slice(0, -1) : args;\n\n const mergedDeps = { ...overrides, ...(config?.deps ?? {}) } as Partial<Deps>;\n const mergedConfig: RunConfig<E, U, C, Deps> = config\n ? { ...config, deps: mergedDeps }\n : ({ deps: mergedDeps } as RunConfig<E, U, C, Deps>);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (workflow[method] as any)(...head, mergedConfig);\n }) as Workflow<E, U, Deps, C>[Method];\n\n return {\n run: forward(\"run\"),\n runWithState: forward(\"runWithState\"),\n withDeps(nextOverrides: Partial<Deps>) {\n return withDeps(workflow, { ...overrides, ...nextOverrides });\n },\n };\n}\n"],"mappings":"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","names":["src_exports","__export","AWAITLY_CANCELLED","AWAITLY_TIMEOUT","AWAITLY_UNEXPECTED","Awaitly","DESERIALIZATION_ERROR","PROMISE_REJECTED","R","TaggedError","UnexpectedError","UnwrapError","all","allAsync","allSettled","allSettledAsync","andThen","any","anyAsync","bimap","compose","deserialize","err","flatMapAsync","flatten","flow","from","fromNullable","fromPromise","getOrElse","getOrElseLazy","hydrate","identity","isErr","isOk","isPromiseRejectedError","isSerializedResult","isUnexpectedError","map","mapAsync","mapError","mapErrorTry","mapTry","match","matchError","matchErrorPartial","ok","orElse","orElseAsync","partition","pipe","race","recover","recoverAsync","recoverWith","runOrNull","runOrThrow","runOrThrowAsync","runOrUndefined","serialize","tags","tap","tapAsync","tapError","tapErrorAsync","traverse","traverseAsync","traverseParallel","tryAsync","unwrap","unwrapOr","unwrapOrElse","withDeps","zip","zipAsync","__toCommonJS","result_exports","__export","AWAITLY_CANCELLED","AWAITLY_TIMEOUT","AWAITLY_UNEXPECTED","DESERIALIZATION_ERROR","PROMISE_REJECTED","UnexpectedError","UnwrapError","all","allAsync","allSettled","allSettledAsync","andThen","any","anyAsync","bimap","deserialize","err","flatten","from","fromNullable","fromPromise","hydrate","isErr","isOk","isPromiseRejectedError","isSerializedResult","isUnexpectedError","map","mapError","mapErrorTry","mapTry","match","matchError","matchErrorPartial","ok","orElse","orElseAsync","partition","recover","recoverAsync","runOrNull","runOrThrow","runOrThrowAsync","runOrUndefined","serialize","tags","tap","tapError","tryAsync","unwrap","unwrapOr","unwrapOrElse","zip","zipAsync","AWAITLY_SLUGS","slugDocsUrl","slug","ALL_SLUGS","AWAITLY_SLUGS","InternalTaggedErrorBase","TaggedError","tag","options","props","errorOptions","message","slugDocsUrl","safeProps","_","_n","_m","_s","_c","_h","_d","rest","hasUserCause","userCause","hasOptionsCause","instance","isError","value","isTaggedError","match","error","handlers","handler","matchPartial","otherwise","TimeoutError","TaggedError","p","RetryExhaustedError","RateLimitError","CircuitBreakerOpenError","ValidationError","NotFoundError","UnauthorizedError","NetworkError","CompensationError","UnexpectedError","PROMISE_REJECTED","AWAITLY_UNEXPECTED","AWAITLY_CANCELLED","AWAITLY_TIMEOUT","tags","t","ok","value","err","error","options","cause","isOk","r","isErr","isUnexpectedError","UnexpectedError","isPromiseRejectedError","PROMISE_REJECTED","matchError","errorOrHandlers","handlers","h","e","UnwrapError","result","errorStr","unwrap","unwrapOr","defaultValue","unwrapOrElse","fn","runOrThrow","runOrThrowAsync","ar","runOrNull","runOrUndefined","from","onError","fromPromise","promise","tryAsync","fromNullable","onNull","map","mapError","match","andThen","tap","tapError","mapTry","mapErrorTry","bimap","onOk","onErr","orElse","orElseAsync","recover","recoverAsync","resolved","hydrate","obj","isSerializedResult","all","results","values","allAsync","resultOrPromise","reason","allSettled","errors","allSettledAsync","settled","item","partition","any","firstErr","anyAsync","resolve","pendingCount","firstError","zip","a","b","zipAsync","wrapRejection","p","ra","rb","flatten","DESERIALIZATION_ERROR","deserialize","serialize","matchErrorPartial","fallback","pipe","a","fns","acc","fn","flow","compose","identity","map","result","isOk","ok","flatMap","bimap","onOk","onErr","err","mapError","isErr","tap","tapError","match","patterns","recover","recoverWith","getOrElse","defaultValue","getOrElseLazy","mapAsync","resolved","flatMapAsync","tapAsync","tapErrorAsync","allAsync","results","ok","values","settledCount","done","resolve","resultPromise","index","result","isErr","reason","err","PROMISE_REJECTED","race","results","p","reason","err","PROMISE_REJECTED","traverse","items","fn","i","result","isErr","ok","traverseAsync","traverseParallel","allAsync","item","index","R","map","flatMap","onOk","onErr","bimap","mapError","tap","tapError","patterns","match","recover","recoverWith","defaultValue","getOrElse","getOrElseLazy","withDeps","workflow","overrides","forward","method","args","last","hasConfig","config","head","mergedDeps","mergedConfig","nextOverrides","Awaitly","result_exports","TaggedError","pipe","flow","compose","identity","R","recoverWith","getOrElse","getOrElseLazy","mapAsync","flatMapAsync","tapAsync","tapErrorAsync","race","traverse","traverseAsync","traverseParallel"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/slugs.ts","../src/tagged-error.ts","../src/errors.ts","../src/result/index.ts","../src/di.ts","../src/duration.ts","../src/core/bound-steps.ts","../src/core/policies.ts","../src/core/index.ts","../src/match.ts","../src/circuit-breaker.ts","../src/rate-limiter/index.ts","../src/cache.ts","../src/singleflight.ts","../src/policies.ts","../src/conditional.ts"],"sourcesContent":["/**\n * awaitly\n *\n * Result types for typed error handling without exceptions — built for\n * plain async/await, automatic error inference, and code that agents can\n * write and humans can eyeball.\n *\n * ## Quick Start\n *\n * ```typescript\n * import { ok, err, run, type AsyncResult } from 'awaitly';\n *\n * // Define Result-returning functions\n * async function getUser(id: string): AsyncResult<User, 'NOT_FOUND'> {\n * const user = await db.find(id);\n * return user ? ok(user) : err('NOT_FOUND');\n * }\n *\n * // Deps-first composition: no type params, no step IDs, no thunks\n * const result = await run({ getUser, getPosts }, async (s) => {\n * const user = await s.getUser(id);\n * const posts = await s.getPosts(user.id);\n * return { user, posts };\n * });\n * ```\n *\n * ## Entry Points (canonical: exactly four)\n *\n * - `awaitly` — the front door: Result primitives, run() + step engine,\n * per-dep policies (retry/timeout/fallback), TaggedError, errors,\n * pattern matching, durations, reliability instances\n * - `awaitly/result` — the size guarantee: Result primitives only, whole\n * entry stays tiny with zero bundler trust required\n * - `awaitly/workflow` — the production tier: createWorkflow, durable\n * execution, persistence, human-in-the-loop, sagas, streaming, webhooks\n * - `awaitly/testing` — test utilities\n */\n\n// =============================================================================\n// Named value exports (tree-shake friendly)\n//\n// Canonical core: there is no `Awaitly` namespace object and no pipe/flow\n// re-exports. One way to write it — named imports of the canonical\n// surface. A runtime namespace holding every export defeats tree-shaking\n// (the whole module graph gets materialized as getters) and is a second\n// dialect for every operation.\n// =============================================================================\n\nexport {\n UnexpectedError,\n PROMISE_REJECTED,\n AWAITLY_UNEXPECTED,\n AWAITLY_CANCELLED,\n AWAITLY_TIMEOUT,\n tags,\n ok,\n err,\n isOk,\n isErr,\n isUnexpectedError,\n isPromiseRejectedError,\n matchError,\n UnwrapError,\n unwrap,\n unwrapOr,\n unwrapOrElse,\n runOrThrow,\n runOrThrowAsync,\n runOrNull,\n runOrUndefined,\n from,\n fromPromise,\n tryAsync,\n fromNullable,\n map,\n mapError,\n match,\n andThen,\n tap,\n tapError,\n mapTry,\n mapErrorTry,\n bimap,\n orElse,\n orElseAsync,\n recover,\n recoverAsync,\n hydrate,\n isSerializedResult,\n all,\n allAsync,\n allSettled,\n allSettledAsync,\n partition,\n any,\n anyAsync,\n zip,\n zipAsync,\n flatten,\n deserialize,\n DESERIALIZATION_ERROR,\n serialize,\n matchErrorPartial,\n} from \"./result\";\n\nexport { withDeps } from \"./di\";\n\nexport { TaggedError } from \"./tagged-error\";\n\n// =============================================================================\n// Type exports (cannot live on runtime object)\n// =============================================================================\n\nexport type {\n Ok,\n Err,\n Result,\n AsyncResult,\n PromiseRejectedError,\n PromiseRejectionCause,\n EmptyInputError,\n MaybeAsyncResult,\n ErrorOf,\n Errors,\n ErrorsOf,\n ExtractValue,\n ExtractError,\n ExtractCause,\n CauseOf,\n MatchErrorHandlers,\n SettledError,\n DeserializationError,\n SerializedResult,\n} from \"./result\";\n\nexport type {\n TaggedErrorBase,\n TaggedErrorOptions,\n TaggedErrorCreateOptions,\n TaggedErrorConstructor,\n TagOf,\n ErrorByTag,\n PropsOf,\n} from \"./tagged-error\";\n\nexport type { RetryOptions, BackoffStrategy, BoundSteps } from \"./core\";\n// Per-dep policies re-export from the leaf module (NOT the ./core barrel):\n// the root entry has a strict bundle budget and the core engine must not\n// be pulled into it.\nexport {\n retry,\n timeout,\n fallback,\n type RetryPolicyOptions,\n type PolicyFn,\n type PolicyDelay,\n} from \"./core/policies\";\n\n// Slug spine — type-only names surfaced here; the runtime helpers\n// (slugDocsUrl, isAwaitlySlug, AWAITLY_SLUGS, etc.) are re-exported from the\n// root entry below (`export * from \"./slugs\"`).\nexport type { AwaitlySlug, AwaitlySlugCategory } from \"./slugs\";\n\n// =============================================================================\n// Canonical core (v2): the root entry is the front door.\n//\n// The exports map is four entries — `awaitly`, `awaitly/result`,\n// `awaitly/workflow`, `awaitly/testing`. Former sub-path entries are\n// absorbed here (explicit exports above always win over star re-exports,\n// so curated names take precedence on any clash). Consumers pay only for\n// what they import: the package ships unminified ESM with sideEffects:\n// false, so bundlers tree-shake.\n//\n// Dropped (not absorbed): flow, functional, bind-deps, resolver,\n// diagnostics (internal), otel / fetch / adapters (future ecosystem\n// packages), and the Schedule combinators from awaitly/retry (their\n// map/tap/andThen/once names clash with Result combinators; per-dep\n// policies cover retry/timeout).\n// =============================================================================\n\n// run() and the step engine surface (formerly awaitly/run, awaitly/core)\nexport { run } from \"./core\";\nexport {\n type RunStep,\n type StepOptions,\n type RunOptions,\n type RunOptionsWithCatch,\n type RunOptionsWithoutCatch,\n type WorkflowEvent,\n type ScopeType,\n type TimeoutOptions,\n type StepTimeoutError,\n type StepTimeoutMarkerMeta,\n STEP_TIMEOUT_MARKER,\n isStepTimeoutError,\n getStepTimeoutMeta,\n type EarlyExit,\n type StepFailureMeta,\n EARLY_EXIT_SYMBOL,\n createEarlyExit,\n isEarlyExit,\n} from \"./core\";\n\n// Pre-built error types (formerly awaitly/errors)\nexport * from \"./errors-entry\";\n// Durations (formerly awaitly/duration)\nexport * from \"./duration-entry\";\n// Pattern matching (formerly awaitly/match — clashing names ship pre-renamed:\n// matchTag, matchTags, matchOrElse)\nexport * from \"./match-entry\";\n// Reliability instances (formerly awaitly/circuit-breaker, awaitly/ratelimit)\nexport * from \"./circuit-breaker-entry\";\nexport * from \"./ratelimit-entry\";\n// Caching + deduplication (formerly awaitly/cache, awaitly/singleflight)\nexport * from \"./cache-entry\";\nexport * from \"./singleflight-entry\";\n// Legacy StepOptions policy bundles (formerly awaitly/policies)\nexport * from \"./policies-entry\";\n// Declarative conditionals (formerly awaitly/conditional) — when/unless are\n// first-class analyzable constructs: the analyzer renders them as branches.\nexport * from \"./conditional-entry\";\n// AI-DX slug spine runtime (formerly awaitly/slugs) — needed by tooling\n// (analyzer, lint). Pure data + helpers; tree-shakes when unused.\nexport * from \"./slugs\";\n","/**\n * awaitly/slugs\n *\n * Source-of-truth slug namespace. Every concept that surfaces as a runtime\n * error, lint rule, static-analyzer diagnostic, visualizer event, or skill rule\n * has exactly one canonical kebab-case slug here.\n *\n * Slugs are public API. Renames are a major version bump. Adds are non-breaking.\n *\n * Categories:\n * - step-* step() discipline\n * - workflow-* createWorkflow / run / runWithState shape\n * - result-* Result usage\n * - error-* Boundary handling\n * - concurrency-* step.all/map/race vs Promise.*\n * - runtime-* Failures only observable at runtime\n */\n\nexport const AWAITLY_SLUGS = {\n // --- step-* ---\n \"step-require-id\": \"step-require-id\",\n \"step-no-immediate-execution\": \"step-no-immediate-execution\",\n \"step-require-thunk-for-key\": \"step-require-thunk-for-key\",\n \"step-no-bare-await\": \"step-no-bare-await\",\n \"step-no-try-catch-wrap\": \"step-no-try-catch-wrap\",\n \"step-stable-cache-keys\": \"step-stable-cache-keys\",\n\n // --- workflow-* ---\n \"workflow-no-floating\": \"workflow-no-floating\",\n \"workflow-options-position\": \"workflow-options-position\",\n \"workflow-callback-shape\": \"workflow-callback-shape\",\n \"workflow-no-callable-form\": \"workflow-no-callable-form\",\n \"workflow-no-dynamic-import\": \"workflow-no-dynamic-import\",\n \"workflow-prefer-step-if\": \"workflow-prefer-step-if\",\n \"workflow-prefer-step-foreach\": \"workflow-prefer-step-foreach\",\n\n // --- result-* ---\n \"result-no-floating\": \"result-no-floating\",\n \"result-require-handling\": \"result-require-handling\",\n \"result-no-double-wrap\": \"result-no-double-wrap\",\n \"result-no-manual-propagation\": \"result-no-manual-propagation\",\n \"result-no-direct-ok-err\": \"result-no-direct-ok-err\",\n\n // --- error-* ---\n \"error-check-unexpected-first\": \"error-check-unexpected-first\",\n \"error-access-cause\": \"error-access-cause\",\n \"error-normalize\": \"error-normalize\",\n \"error-no-throw-in-deps\": \"error-no-throw-in-deps\",\n\n // --- concurrency-* ---\n \"concurrency-no-promise-all\": \"concurrency-no-promise-all\",\n \"concurrency-no-promise-race\": \"concurrency-no-promise-race\",\n \"concurrency-no-promise-allsettled\": \"concurrency-no-promise-allsettled\",\n\n // --- runtime-* ---\n \"runtime-step-timeout\": \"runtime-step-timeout\",\n \"runtime-step-aborted\": \"runtime-step-aborted\",\n \"runtime-retry-exhausted\": \"runtime-retry-exhausted\",\n \"runtime-rate-limit\": \"runtime-rate-limit\",\n \"runtime-circuit-open\": \"runtime-circuit-open\",\n \"runtime-unexpected\": \"runtime-unexpected\",\n \"runtime-resolver-not-found\": \"runtime-resolver-not-found\",\n \"runtime-saga-compensation\": \"runtime-saga-compensation\",\n} as const;\n\n/** All canonical awaitly slugs as a string-literal union. */\nexport type AwaitlySlug = keyof typeof AWAITLY_SLUGS;\n\n/** Categories derived from slug prefixes. */\nexport type AwaitlySlugCategory =\n | \"step\"\n | \"workflow\"\n | \"result\"\n | \"error\"\n | \"concurrency\"\n | \"runtime\";\n\n/** Returns the category (prefix) of a slug. */\nexport function slugCategory(slug: AwaitlySlug): AwaitlySlugCategory {\n return slug.split(\"-\")[0] as AwaitlySlugCategory;\n}\n\n/**\n * Returns the canonical docs URL for a slug. Resolves to the matching\n * anchored section on the consolidated rule index page.\n */\nexport function slugDocsUrl(slug: AwaitlySlug): string {\n return `https://jagreehal.github.io/awaitly/rules/#${slug}`;\n}\n\n/** Type guard: is a string a known awaitly slug? */\nexport function isAwaitlySlug(value: string): value is AwaitlySlug {\n return Object.prototype.hasOwnProperty.call(AWAITLY_SLUGS, value);\n}\n\n/** All slugs as an array. */\n// Object.keys returns string[] — cast is safe because AWAITLY_SLUGS is `as const`\n// and the module's keys are never mutated.\nexport const ALL_SLUGS: readonly AwaitlySlug[] = Object.keys(\n AWAITLY_SLUGS\n) as AwaitlySlug[];\n","/**\n * awaitly/tagged-error\n *\n * Factory for creating tagged error types with exhaustive pattern matching.\n * Enables TypeScript to enforce that all error variants are handled.\n *\n * @example\n * ```typescript\n * // Define error types (Props via generic)\n * class NotFoundError extends TaggedError(\"NotFoundError\")<{\n * id: string;\n * resource: string;\n * }> {}\n *\n * // Define with type-safe message (Props inferred from callback annotation)\n * class ValidationError extends TaggedError(\"ValidationError\", {\n * message: (p: { field: string; reason: string }) => `Invalid ${p.field}: ${p.reason}`,\n * }) {}\n *\n * // Create instances\n * const error = new NotFoundError({ id: \"123\", resource: \"User\" });\n *\n * // Runtime type check: instanceof TaggedError works!\n * console.log(error instanceof TaggedError); // true\n *\n * // Exhaustive matching\n * type AppError = NotFoundError | ValidationError;\n * const message = TaggedError.match(error as AppError, {\n * NotFoundError: (e) => `Missing: ${e.resource} ${e.id}`,\n * ValidationError: (e) => `Invalid ${e.field}: ${e.reason}`,\n * });\n * ```\n */\n\nimport { type AwaitlySlug, slugDocsUrl } from \"./slugs\";\n\n/**\n * Options for Error constructor (compatible with ES2022 ErrorOptions).\n */\nexport interface TaggedErrorOptions {\n cause?: unknown;\n}\n\n/**\n * Options for TaggedError factory with type-safe message callback.\n */\nexport interface TaggedErrorCreateOptions<Props extends Record<string, unknown>> {\n /** Custom message generator from props. Annotate parameter for type safety. */\n message: (props: Props) => string;\n /**\n * Canonical awaitly slug for this error class. When set, instances carry\n * `code`, `hint`, and `docsUrl` populated from the slugs namespace.\n * Required together with `hint` for awaitly-system errors.\n */\n slug?: AwaitlySlug;\n /**\n * One-line \"do X instead\" guidance shown alongside the error.\n * Required when `slug` is set.\n */\n hint?: string;\n}\n\n/**\n * Base interface for all tagged errors.\n *\n * `type` is the canonical discriminant (the same key plain tagged-object\n * errors use, so one `match` works across shapes). `_tag` is a deprecated\n * alias kept through the migration window.\n */\nexport interface TaggedErrorBase extends Error {\n /** Canonical discriminant — matches the tag passed to TaggedError(tag). */\n readonly type: string;\n /** @deprecated Use `type`. Effect-style alias retained for migration. */\n readonly _tag: string;\n /** Canonical slug for awaitly-system errors. Undefined for user errors that opt out. */\n readonly code?: AwaitlySlug;\n /** One-line guidance. Undefined when no slug is set. */\n readonly hint?: string;\n /** Canonical docs URL. Undefined when no slug is set. */\n readonly docsUrl?: string;\n}\n\n/**\n * Internal base class for instanceof checks.\n * All TaggedError-created classes extend this.\n * @internal\n */\nclass InternalTaggedErrorBase extends Error implements TaggedErrorBase {\n readonly type!: string;\n /** @deprecated Use `type`. */\n readonly _tag!: string;\n}\n\n/**\n * Instance type for factory-created TaggedErrors.\n */\ntype TaggedErrorInstance<Tag extends string, Props> = TaggedErrorBase & {\n readonly type: Tag;\n /** @deprecated Use `type`. */\n readonly _tag: Tag;\n} & Readonly<Props>;\n\n/**\n * Constructor args type - conditionally optional based on whether Props has required fields.\n * - If Props is empty or all properties are optional: props argument is optional\n * - If Props has any required properties: props argument is required\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\ntype ConstructorArgs<Props extends Record<string, unknown>> = {} extends Props\n ? [props?: Props | void, options?: TaggedErrorOptions]\n : [props: Props, options?: TaggedErrorOptions];\n\n/**\n * Constructor type returned by TaggedError factory.\n */\nexport interface TaggedErrorConstructor<\n Tag extends string,\n Props extends Record<string, unknown>,\n> {\n new (...args: ConstructorArgs<Props>): TaggedErrorInstance<Tag, Props>;\n readonly prototype: TaggedErrorInstance<Tag, Props>;\n}\n\n/**\n * Generic class factory type that allows `<Props>` parameterization.\n * This enables the Effect.js-style syntax: `class X extends TaggedError(\"X\")<Props> {}`\n * @internal\n */\nexport interface TaggedErrorClassFactory<Tag extends string> {\n new <Props extends Record<string, unknown> = Record<string, never>>(\n ...args: ConstructorArgs<Props>\n ): TaggedErrorInstance<Tag, Props>;\n}\n\n/**\n * Helper type to extract return type from a function type.\n * @internal\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype FnReturnType<T> = T extends (...args: any[]) => infer R ? R : never;\n\n/**\n * Helper type to get union of return types from all handlers.\n * @internal\n */\ntype HandlersReturnType<H> = { [K in keyof H]: FnReturnType<H[K]> }[keyof H];\n\n/**\n * Helper type to extract keys whose values are definitely functions (not undefined).\n * Only excludes a tag from the fallback type if its handler is guaranteed to be\n * a function. Keys where the value type includes undefined are NOT excluded,\n * ensuring type safety with dynamic/conditional handlers.\n * @internal\n */\ntype DefinitelyHandledKeys<H> = {\n [K in keyof H]-?: undefined extends H[K] ? never : K;\n}[keyof H];\n\n/**\n * Factory function to create tagged error classes.\n *\n * Two usage patterns:\n *\n * 1. **Props via generic** (default message is tag name):\n * ```typescript\n * class NotFoundError extends TaggedError(\"NotFoundError\")<{ id: string }> {}\n * ```\n *\n * 2. **Props inferred from message callback** (type-safe message):\n * ```typescript\n * class NotFoundError extends TaggedError(\"NotFoundError\", {\n * message: (p: { id: string }) => `Not found: ${p.id}`,\n * }) {}\n * ```\n *\n * Both support `instanceof TaggedError` checks at runtime.\n *\n * @param tag - The unique tag string for this error type\n * @param options - Optional configuration with message generator (annotate param for type safety)\n * @returns A class constructor that can be extended\n */\n\n// Overload 1: No options - use <Props> generic syntax, default message is tag\nfunction TaggedError<Tag extends string>(\n tag: Tag\n): TaggedErrorClassFactory<Tag>;\n\n// Overload 2: With message option - Props inferred from callback parameter annotation\nfunction TaggedError<Tag extends string, Props extends Record<string, unknown>>(\n tag: Tag,\n options: TaggedErrorCreateOptions<Props>\n): TaggedErrorConstructor<Tag, Props>;\n\n// Implementation\nfunction TaggedError<Tag extends string, Props extends Record<string, unknown>>(\n tag: Tag,\n options?: TaggedErrorCreateOptions<Props>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any {\n return class extends InternalTaggedErrorBase {\n override readonly type: Tag = tag;\n /** @deprecated Use `type`. */\n override readonly _tag: Tag = tag;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(props?: any, errorOptions?: TaggedErrorOptions) {\n // Generate message: call callback if provided (even for prop-less errors), else use tag\n const message = options?.message ? options.message(props ?? {}) : tag;\n\n super(message);\n this.name = tag;\n\n // Spine fields: populate when factory was given a slug\n if (options?.slug !== undefined) {\n if (!options.hint) {\n throw new TypeError(\n `TaggedError: 'hint' is required when 'slug' is set (slug: \"${options.slug}\")`\n );\n }\n Object.defineProperty(this, \"code\", {\n value: options.slug,\n enumerable: true,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(this, \"hint\", {\n value: options.hint,\n enumerable: true,\n writable: false,\n configurable: false,\n });\n Object.defineProperty(this, \"docsUrl\", {\n value: slugDocsUrl(options.slug),\n enumerable: true,\n writable: false,\n configurable: false,\n });\n }\n\n // Maintains proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n // Assign props to instance, stripping reserved keys:\n // - type/_tag: discriminants for pattern matching (cannot be forged)\n // - name, message, stack: Error internals (preserve for logging/debugging)\n // - code, hint, docsUrl: spine fields stripped when slug is set, to prevent\n // Object.assign from clobbering the non-configurable/non-writable own props\n // Note: 'cause' is allowed as a user prop (common for domain errors)\n if (props && typeof props === \"object\") {\n let safeProps: Record<string, unknown>;\n if (options?.slug !== undefined) {\n const {\n _tag: _,\n type: _t,\n name: _n,\n message: _m,\n stack: _s,\n code: _c,\n hint: _h,\n docsUrl: _d,\n ...rest\n } = props;\n safeProps = rest;\n } else {\n const {\n _tag: _,\n type: _t,\n name: _n,\n message: _m,\n stack: _s,\n ...rest\n } = props;\n safeProps = rest;\n }\n\n const hasUserCause = Object.prototype.hasOwnProperty.call(\n safeProps,\n \"cause\"\n );\n const userCause = hasUserCause\n ? (safeProps as { cause?: unknown }).cause\n : undefined;\n if (hasUserCause) {\n delete (safeProps as { cause?: unknown }).cause;\n }\n\n const hasOptionsCause = errorOptions?.cause !== undefined;\n if (hasUserCause && hasOptionsCause) {\n throw new TypeError(\n \"TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause\"\n );\n }\n\n Object.assign(this, safeProps);\n\n if (hasUserCause) {\n (this as { cause?: unknown }).cause = userCause;\n }\n if (hasOptionsCause) {\n (this as { cause?: unknown }).cause = errorOptions?.cause;\n }\n } else if (errorOptions?.cause !== undefined) {\n (this as { cause?: unknown }).cause = errorOptions.cause;\n }\n }\n };\n}\n\n// Add Symbol.hasInstance so `instanceof TaggedError` works\nObject.defineProperty(TaggedError, Symbol.hasInstance, {\n value: (instance: unknown): boolean => instance instanceof InternalTaggedErrorBase,\n});\n\n/**\n * Namespace for static methods on TaggedError.\n */\n// eslint-disable-next-line @typescript-eslint/no-namespace\nnamespace TaggedError {\n /**\n * Type guard to check if a value is an Error instance.\n */\n export function isError(value: unknown): value is Error {\n return value instanceof Error;\n }\n\n /**\n * Type guard to check if a value is a TaggedError instance.\n * Uses the same check as `instanceof TaggedError` - only genuine\n * TaggedError instances (created via the factory) pass this guard.\n */\n export function isTaggedError(value: unknown): value is TaggedErrorBase {\n return value instanceof InternalTaggedErrorBase;\n }\n\n /**\n * Exhaustively matches on a tagged error, requiring handlers for all variants.\n *\n * TypeScript will error if any variant in the error union is not handled.\n *\n * @remarks When to use: You want compile-time enforcement that every tagged variant is handled.\n *\n * @param error - The tagged error to match\n * @param handlers - Object mapping _tag values to handler functions\n * @returns The return value of the matched handler\n *\n * @example\n * ```typescript\n * type AppError = NotFoundError | ValidationError;\n *\n * const message = TaggedError.match(error, {\n * NotFoundError: (e) => `Not found: ${e.id}`,\n * ValidationError: (e) => `Invalid: ${e.field}`,\n * });\n * ```\n */\n export function match<\n E extends TaggedErrorBase,\n H extends { [K in E[\"_tag\"]]: (e: Extract<E, { _tag: K }>) => unknown },\n >(error: E, handlers: H): HandlersReturnType<H> {\n const tag = error._tag as E[\"_tag\"];\n const handler = handlers[tag];\n return handler(\n error as Extract<E, { _tag: typeof tag }>\n ) as HandlersReturnType<H>;\n }\n\n /**\n * Partially matches on a tagged error with a fallback for unhandled variants.\n *\n * The fallback receives variants that are NOT definitely handled. A tag is\n * considered \"definitely handled\" only if its handler is a function (not\n * `undefined`). This ensures type safety even with dynamic/conditional handlers:\n *\n * ```typescript\n * const maybeHandle = featureFlag ? (e) => e.id : undefined;\n * TaggedError.matchPartial(\n * error,\n * { NotFoundError: maybeHandle }, // maybeHandle might be undefined\n * (e) => e._tag // e correctly includes NotFoundError\n * );\n * ```\n *\n * @param error - The tagged error to match\n * @param handlers - Partial object mapping _tag values to handler functions\n * @param otherwise - Fallback handler for unmatched variants\n * @returns The return value of the matched handler or fallback\n *\n * @example\n * ```typescript\n * const message = TaggedError.matchPartial(\n * error,\n * { NotFoundError: (e) => `Not found: ${e.id}` },\n * (e) => `Other error: ${e.message}`\n * );\n * ```\n */\n export function matchPartial<\n E extends TaggedErrorBase,\n H extends Partial<{\n [K in E[\"_tag\"]]: (e: Extract<E, { _tag: K }>) => unknown;\n }>,\n T,\n >(\n error: E,\n handlers: H,\n otherwise: (e: Exclude<E, { _tag: DefinitelyHandledKeys<H> }>) => T\n ): HandlersReturnType<H> | T {\n const tag = error._tag as E[\"_tag\"];\n const handler = handlers[tag];\n if (handler) {\n return handler(\n error as Extract<E, { _tag: typeof tag }>\n ) as HandlersReturnType<H>;\n }\n return otherwise(error as Exclude<E, { _tag: DefinitelyHandledKeys<H> }>);\n }\n}\n\nexport { TaggedError };\n\n/**\n * Helper type to extract the _tag literal type from a TaggedError.\n *\n * @example\n * ```typescript\n * class MyError extends TaggedError(\"MyError\")<{ id: string }> {}\n * type Tag = TagOf<MyError>; // \"MyError\"\n * ```\n */\nexport type TagOf<E extends TaggedErrorBase> = E[\"_tag\"];\n\n/**\n * Helper type to extract a specific variant from a TaggedError union by tag.\n *\n * @example\n * ```typescript\n * type AppError = NotFoundError | ValidationError;\n * type NotFound = ErrorByTag<AppError, \"NotFoundError\">; // NotFoundError\n * ```\n */\nexport type ErrorByTag<\n E extends TaggedErrorBase,\n Tag extends E[\"_tag\"],\n> = Extract<E, { _tag: Tag }>;\n\n/**\n * Reserved keys that are stripped from user props at runtime.\n * These keys cannot be used as user-defined properties:\n * - _tag: discriminant for pattern matching\n * - name, message, stack: Error internals (preserved for logging/debugging)\n * - code, hint, docsUrl: spine fields (non-configurable own properties when slug is set)\n *\n * Note: 'cause' is NOT reserved - it can be used as a user prop.\n */\ntype ReservedErrorKeys = \"_tag\" | \"name\" | \"message\" | \"stack\" | \"code\" | \"hint\" | \"docsUrl\";\n\n/**\n * Helper type to extract props from a TaggedError.\n * Excludes reserved keys that are stripped at runtime.\n *\n * @example\n * ```typescript\n * class MyError extends TaggedError(\"MyError\")<{ id: string }> {}\n * type Props = PropsOf<MyError>; // { id: string }\n *\n * // 'cause' is allowed as a user prop\n * class DomainError extends TaggedError(\"DomainError\")<{ cause: { field: string } }> {}\n * type DomainProps = PropsOf<DomainError>; // { cause: { field: string } }\n * ```\n */\nexport type PropsOf<E extends TaggedErrorBase> = Omit<E, ReservedErrorKeys>;\n","/**\n * awaitly/errors\n *\n * Pre-built error types for common failure scenarios.\n * Uses TaggedError for type-safe exhaustive matching.\n *\n * @example\n * ```typescript\n * import { TimeoutError, RetryExhaustedError, RateLimitError, CircuitBreakerOpenError } from 'awaitly';\n *\n * // Create errors\n * const timeout = new TimeoutError({ operation: 'fetchUser', ms: 5000 });\n * const retryFailed = new RetryExhaustedError({ operation: 'sendEmail', attempts: 3 });\n *\n * // Pattern match\n * TaggedError.match(error, {\n * TimeoutError: (e) => `${e.operation} timed out after ${e.ms}ms`,\n * RetryExhaustedError: (e) => `${e.operation} failed after ${e.attempts} attempts`,\n * RateLimitError: (e) => `Rate limit exceeded, retry after ${e.retryAfterMs}ms`,\n * CircuitBreakerOpenError: (e) => `Circuit ${e.circuitName} is open`,\n * });\n * ```\n */\n\n/**\n * Spine policy:\n *\n * Awaitly-system errors (raised by awaitly internals on workflow execution\n * failure modes) carry a `slug` + `hint` so they participate in the\n * AI-DX spine: TimeoutError, RetryExhaustedError, RateLimitError,\n * CircuitBreakerOpenError, CompensationError, UnexpectedError.\n *\n * Convenience domain errors (ValidationError, NotFoundError,\n * UnauthorizedError, NetworkError) are deliberately NOT slugged — they\n * represent USER domain failures and would force user code into the\n * awaitly slug namespace. Users can opt in by adding `slug` + `hint`\n * to their own TaggedError subclasses.\n */\n\nimport { TaggedError } from \"./tagged-error\";\n\n// =============================================================================\n// Error Factory\n// =============================================================================\n\n/**\n * Factory function to create tagged error classes with default values.\n *\n * This is a convenience wrapper around TaggedError that allows specifying\n * default property values for error types.\n *\n * @example\n * ```typescript\n * const NetworkError = makeError('NetworkError', {\n * defaults: { retryable: true },\n * message: (p) => `Network error: ${p.reason}`,\n * });\n *\n * class MyNetworkError extends NetworkError<{ reason: string; code?: number }> {}\n * ```\n */\nexport function makeError<Tag extends string>(\n tag: Tag,\n options?: {\n message?: (props: Record<string, unknown>) => string;\n defaults?: Record<string, unknown>;\n }\n) {\n const messageGenerator = options?.message ?? (() => tag);\n const defaults = options?.defaults ?? {};\n\n const BaseClass = TaggedError(tag, {\n message: (props: Record<string, unknown>) =>\n messageGenerator({ ...defaults, ...props }),\n });\n\n return class extends BaseClass {\n constructor(props?: Record<string, unknown>) {\n super({ ...defaults, ...props } as Record<string, unknown>);\n Object.assign(this, { ...defaults, ...props });\n }\n };\n}\n\n// =============================================================================\n// Pre-built Error Types\n// =============================================================================\n\n/**\n * Error thrown when an operation times out.\n *\n * @example\n * ```typescript\n * const error = new TimeoutError({\n * operation: 'fetchUser',\n * ms: 5000,\n * });\n * console.log(error.message); // \"TimeoutError: fetchUser timed out after 5000ms\"\n * ```\n */\nexport class TimeoutError extends /* @__PURE__ */ TaggedError(\"TimeoutError\", {\n slug: \"runtime-step-timeout\",\n hint: \"Increase the step's timeout option, or check why the upstream operation is slow.\",\n message: (p: {\n /** Name of the operation that timed out */\n operation?: string;\n /** Timeout duration in milliseconds */\n ms: number;\n }) =>\n p.operation\n ? `TimeoutError: ${p.operation} timed out after ${p.ms}ms`\n : `TimeoutError: Operation timed out after ${p.ms}ms`,\n}) {}\n\n/**\n * Error thrown when all retry attempts are exhausted.\n *\n * @example\n * ```typescript\n * const error = new RetryExhaustedError({\n * operation: 'sendEmail',\n * attempts: 3,\n * lastError: originalError,\n * });\n * console.log(error.message); // \"RetryExhaustedError: sendEmail failed after 3 attempts\"\n * ```\n */\nexport class RetryExhaustedError extends /* @__PURE__ */ TaggedError(\"RetryExhaustedError\", {\n slug: \"runtime-retry-exhausted\",\n hint: \"All retry attempts failed. Inspect lastError and decide whether to surface it or compensate.\",\n message: (p: {\n /** Name of the operation that failed */\n operation?: string;\n /** Total number of retry attempts made */\n attempts: number;\n /** The last error encountered before giving up */\n lastError?: unknown;\n }) =>\n p.operation\n ? `RetryExhaustedError: ${p.operation} failed after ${p.attempts} attempts`\n : `RetryExhaustedError: Operation failed after ${p.attempts} attempts`,\n}) {}\n\n/**\n * Error thrown when a rate limit is exceeded.\n *\n * @example\n * ```typescript\n * const error = new RateLimitError({\n * limiterName: 'api-calls',\n * retryAfterMs: 1000,\n * });\n * console.log(error.message); // \"RateLimitError: Rate limit exceeded for api-calls\"\n * ```\n */\nexport class RateLimitError extends /* @__PURE__ */ TaggedError(\"RateLimitError\", {\n slug: \"runtime-rate-limit\",\n hint: \"Wait retryAfterMs before retrying, or apply step.cache to deduplicate calls.\",\n message: (p: {\n /** Name of the rate limiter that was exceeded */\n limiterName?: string;\n /** Time in milliseconds until the rate limit resets */\n retryAfterMs?: number;\n }) =>\n p.limiterName\n ? `RateLimitError: Rate limit exceeded for ${p.limiterName}${p.retryAfterMs ? `, retry after ${p.retryAfterMs}ms` : \"\"}`\n : `RateLimitError: Rate limit exceeded${p.retryAfterMs ? `, retry after ${p.retryAfterMs}ms` : \"\"}`,\n}) {}\n\n/**\n * Error thrown when a circuit breaker is open.\n *\n * @example\n * ```typescript\n * const error = new CircuitBreakerOpenError({\n * circuitName: 'payment-api',\n * state: 'OPEN',\n * retryAfterMs: 30000,\n * });\n * console.log(error.message); // \"CircuitBreakerOpenError: Circuit payment-api is OPEN\"\n * ```\n */\nexport class CircuitBreakerOpenError extends /* @__PURE__ */ TaggedError(\n \"CircuitBreakerOpenError\",\n {\n slug: \"runtime-circuit-open\",\n hint: \"The circuit is open. Wait for it to half-open or fall back to a degraded path.\",\n message: (p: {\n /** Name of the circuit breaker */\n circuitName: string;\n /** Current state of the circuit */\n state?: \"OPEN\" | \"HALF_OPEN\";\n /** Time in milliseconds until the circuit may close */\n retryAfterMs?: number;\n }) =>\n `CircuitBreakerOpenError: Circuit ${p.circuitName} is ${p.state ?? \"OPEN\"}${p.retryAfterMs ? `, retry after ${Math.ceil(p.retryAfterMs / 1000)}s` : \"\"}`,\n }\n) {}\n\n/**\n * Error thrown when validation fails.\n *\n * @example\n * ```typescript\n * const error = new ValidationError({\n * field: 'email',\n * reason: 'Invalid email format',\n * });\n * console.log(error.message); // \"ValidationError: Invalid email - Invalid email format\"\n * ```\n */\nexport class ValidationError extends /* @__PURE__ */ TaggedError(\"ValidationError\", {\n message: (p: {\n /** Field that failed validation */\n field: string;\n /** Reason for validation failure */\n reason: string;\n /** Raw value that failed validation */\n value?: unknown;\n }) => `ValidationError: Invalid ${p.field} - ${p.reason}`,\n}) {}\n\n/**\n * Error thrown when a resource is not found.\n *\n * @example\n * ```typescript\n * const error = new NotFoundError({\n * resource: 'User',\n * id: '123',\n * });\n * console.log(error.message); // \"NotFoundError: User with id 123 not found\"\n * ```\n */\nexport class NotFoundError extends /* @__PURE__ */ TaggedError(\"NotFoundError\", {\n message: (p: {\n /** Type of resource that was not found */\n resource: string;\n /** Identifier of the missing resource */\n id?: string;\n }) =>\n p.id\n ? `NotFoundError: ${p.resource} with id ${p.id} not found`\n : `NotFoundError: ${p.resource} not found`,\n}) {}\n\n/**\n * Error thrown when access is denied.\n *\n * @example\n * ```typescript\n * const error = new UnauthorizedError({\n * action: 'delete',\n * resource: 'User',\n * });\n * console.log(error.message); // \"UnauthorizedError: Not authorized to delete User\"\n * ```\n */\nexport class UnauthorizedError extends /* @__PURE__ */ TaggedError(\"UnauthorizedError\", {\n message: (p: {\n /** Action that was attempted */\n action?: string;\n /** Resource that was being accessed */\n resource?: string;\n /** Reason for denial */\n reason?: string;\n }) =>\n p.reason\n ? `UnauthorizedError: ${p.reason}`\n : p.action && p.resource\n ? `UnauthorizedError: Not authorized to ${p.action} ${p.resource}`\n : \"UnauthorizedError: Access denied\",\n}) {}\n\n/**\n * Error thrown for network-related failures.\n *\n * @example\n * ```typescript\n * const error = new NetworkError({\n * url: 'https://api.example.com/users',\n * reason: 'Connection refused',\n * retryable: true,\n * });\n * ```\n */\nexport class NetworkError extends /* @__PURE__ */ TaggedError(\"NetworkError\", {\n message: (p: {\n /** URL that was being accessed */\n url?: string;\n /** Reason for the network failure */\n reason: string;\n /** Whether this error is retryable */\n retryable?: boolean;\n /** HTTP status code if applicable */\n statusCode?: number;\n }) =>\n p.url\n ? `NetworkError: ${p.reason} (${p.url})`\n : `NetworkError: ${p.reason}`,\n}) {}\n\n/**\n * Error thrown when a saga compensation fails.\n *\n * @example\n * ```typescript\n * const error = new CompensationError({\n * step: 'chargeCard',\n * originalError: paymentError,\n * compensationError: refundError,\n * });\n * ```\n */\nexport class CompensationError extends /* @__PURE__ */ TaggedError(\"CompensationError\", {\n slug: \"runtime-saga-compensation\",\n hint: \"A saga compensation step failed. Inspect compensationError and ensure compensation is idempotent.\",\n message: (p: {\n /** Step that triggered compensation */\n step: string;\n /** The original error that caused compensation */\n originalError?: unknown;\n /** Error that occurred during compensation */\n compensationError?: unknown;\n }) => `CompensationError: Failed to compensate step ${p.step}`,\n}) {}\n\n// =============================================================================\n// Unexpected Error\n// =============================================================================\n\n/**\n * Default error type for uncaught exceptions and cancellation in workflows.\n * This is the default `U` type when `catchUnexpected` is not provided.\n *\n * @example\n * ```typescript\n * // Automatically used as the default — no need to pass catchUnexpected:\n * const workflow = createWorkflow(\"checkout\", { chargeCard, sendEmail });\n *\n * // Equivalent to:\n * const workflow = createWorkflow(\"checkout\", { chargeCard, sendEmail }, {\n * catchUnexpected: (cause) => new UnexpectedError({ cause }),\n * });\n * ```\n */\nexport class UnexpectedError extends /* @__PURE__ */ TaggedError(\"UnexpectedError\", {\n slug: \"runtime-unexpected\",\n hint: \"An unexpected exception escaped a step. Inspect cause; consider returning a typed Result instead of throwing.\",\n message: (p: {\n /** The original thrown value or cancellation error */\n cause?: unknown;\n }) => `UnexpectedError: ${p.cause instanceof Error ? p.cause.message : String(p.cause ?? \"unknown\")}`,\n}) {}\n\n// =============================================================================\n// Union Type for Common Errors\n// =============================================================================\n\n/**\n * Union of all pre-built error types.\n * Useful for exhaustive pattern matching.\n *\n * @example\n * ```typescript\n * function handleError(error: AwaitlyError): string {\n * return TaggedError.match(error, {\n * TimeoutError: (e) => `Timeout: ${e.ms}ms`,\n * RetryExhaustedError: (e) => `Retries: ${e.attempts}`,\n * RateLimitError: (e) => `Rate limited`,\n * CircuitBreakerOpenError: (e) => `Circuit open: ${e.circuitName}`,\n * ValidationError: (e) => `Invalid: ${e.field}`,\n * NotFoundError: (e) => `Not found: ${e.resource}`,\n * UnauthorizedError: (e) => `Unauthorized`,\n * NetworkError: (e) => `Network: ${e.reason}`,\n * CompensationError: (e) => `Compensation failed: ${e.step}`,\n * UnexpectedError: (e) => e.message,\n * });\n * }\n * ```\n */\nexport type AwaitlyError =\n | TimeoutError\n | RetryExhaustedError\n | RateLimitError\n | CircuitBreakerOpenError\n | ValidationError\n | NotFoundError\n | UnauthorizedError\n | NetworkError\n | CompensationError\n | UnexpectedError;\n\n/**\n * The six awaitly-system errors that carry slug + hint + docsUrl spine fields.\n *\n * Distinguishes spine-bearing errors from user-domain convenience errors\n * (ValidationError, NotFoundError, UnauthorizedError, NetworkError) so that\n * downstream tooling (lint, analyzer, docs generator) can target the spine\n * roster without duplicating the class list.\n */\nexport type AwaitlySystemError =\n | TimeoutError\n | RetryExhaustedError\n | RateLimitError\n | CircuitBreakerOpenError\n | CompensationError\n | UnexpectedError;\n\n/**\n * Roster of awaitly-system error classes that participate in the slug spine.\n *\n * Adding a new system error means adding it to `AwaitlySystemError`, this\n * roster, and `slugs.ts`. The integrity test in `spine-integrity.test.ts`\n * iterates this roster, so a missing entry there is caught at CI time.\n *\n * @internal Tooling integration point (docs generator, integrity tests). Not\n * a stable user-facing API — application code should not depend on this\n * array's identity or order.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const AWAITLY_SYSTEM_ERROR_CLASSES: ReadonlyArray<new (...args: any[]) => AwaitlySystemError> = [\n TimeoutError,\n RetryExhaustedError,\n RateLimitError,\n CircuitBreakerOpenError,\n CompensationError,\n UnexpectedError,\n];\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Check if an error is a TimeoutError.\n */\nexport function isTimeoutError(error: unknown): error is TimeoutError {\n return TaggedError.isTaggedError(error) && error._tag === \"TimeoutError\";\n}\n\n/**\n * Check if an error is a RetryExhaustedError.\n */\nexport function isRetryExhaustedError(\n error: unknown\n): error is RetryExhaustedError {\n return (\n TaggedError.isTaggedError(error) && error._tag === \"RetryExhaustedError\"\n );\n}\n\n/**\n * Check if an error is a RateLimitError.\n */\nexport function isRateLimitError(error: unknown): error is RateLimitError {\n return TaggedError.isTaggedError(error) && error._tag === \"RateLimitError\";\n}\n\n/**\n * Check if an error is a CircuitBreakerOpenError.\n */\nexport function isCircuitBreakerOpenError(\n error: unknown\n): error is CircuitBreakerOpenError {\n return (\n TaggedError.isTaggedError(error) && error._tag === \"CircuitBreakerOpenError\"\n );\n}\n\n/**\n * Check if an error is a ValidationError.\n */\nexport function isValidationError(error: unknown): error is ValidationError {\n return TaggedError.isTaggedError(error) && error._tag === \"ValidationError\";\n}\n\n/**\n * Check if an error is a NotFoundError.\n */\nexport function isNotFoundError(error: unknown): error is NotFoundError {\n return TaggedError.isTaggedError(error) && error._tag === \"NotFoundError\";\n}\n\n/**\n * Check if an error is an UnauthorizedError.\n */\nexport function isUnauthorizedError(\n error: unknown\n): error is UnauthorizedError {\n return TaggedError.isTaggedError(error) && error._tag === \"UnauthorizedError\";\n}\n\n/**\n * Check if an error is a NetworkError.\n */\nexport function isNetworkError(error: unknown): error is NetworkError {\n return TaggedError.isTaggedError(error) && error._tag === \"NetworkError\";\n}\n\n/**\n * Check if an error is a CompensationError.\n */\nexport function isCompensationError(\n error: unknown\n): error is CompensationError {\n return TaggedError.isTaggedError(error) && error._tag === \"CompensationError\";\n}\n\n/**\n * Check if an error is any AwaitlyError.\n */\nexport function isAwaitlyError(error: unknown): error is AwaitlyError {\n if (!TaggedError.isTaggedError(error)) return false;\n const tag = error._tag;\n return [\n \"TimeoutError\",\n \"RetryExhaustedError\",\n \"RateLimitError\",\n \"CircuitBreakerOpenError\",\n \"ValidationError\",\n \"NotFoundError\",\n \"UnauthorizedError\",\n \"NetworkError\",\n \"CompensationError\",\n \"UnexpectedError\",\n ].includes(tag);\n}\n","/**\n * awaitly/result (internal)\n *\n * Core Result primitives - minimal bundle for typed error handling.\n * This file is intentionally kept small for optimal tree-shaking.\n * The full orchestration (run, step, etc.) lives in core.ts.\n */\n\n// =============================================================================\n// Core Result Types\n// =============================================================================\n\n/**\n * Represents a successful result.\n * Use `ok(value)` to create instances.\n */\nexport type Ok<T> = {\n ok: true;\n value: T;\n};\n\n/**\n * Represents a failed result.\n * Use `err(error)` to create instances.\n */\nexport type Err<E, C = unknown> = {\n ok: false;\n error: E;\n cause?: C;\n};\n\n/**\n * Represents a successful computation or a failed one.\n */\nexport type Result<T, E = unknown, C = unknown> = Ok<T> | Err<E, C>;\n\n/**\n * A Promise that resolves to a Result.\n */\nexport type AsyncResult<T, E = unknown, C = unknown> = Promise<Result<T, E, C>>;\n\n/** Discriminant for PromiseRejectedError type - use in switch statements */\nexport const PROMISE_REJECTED = \"PROMISE_REJECTED\" as const;\n\n// =============================================================================\n// Named Error Constants (for static analysis)\n// =============================================================================\n\n/**\n * Named error constant for unexpected/unhandled errors.\n * Used by the analyzer when a step doesn't declare errors.\n */\nexport const AWAITLY_UNEXPECTED = \"AWAITLY_UNEXPECTED\" as const;\n\n/**\n * Named error constant for cancelled operations.\n */\nexport const AWAITLY_CANCELLED = \"AWAITLY_CANCELLED\" as const;\n\n/**\n * Named error constant for timed-out operations.\n */\nexport const AWAITLY_TIMEOUT = \"AWAITLY_TIMEOUT\" as const;\n\n// =============================================================================\n// Static Analysis Helpers\n// =============================================================================\n\n/**\n * Helper to create a tuple of string literal tags with preserved literal types.\n * Use this when you need to store error tags in a variable while keeping\n * TypeScript's literal type inference (avoiding widening to string[]).\n *\n * @param t - The string literal tags\n * @returns The same array with preserved literal types\n *\n * @example\n * ```typescript\n * // Without tags() - type widens to string[]\n * const errs = ['CART_NOT_FOUND', 'CART_EMPTY']; // string[]\n *\n * // With tags() - literal types preserved\n * const errs = tags('CART_NOT_FOUND', 'CART_EMPTY'); // readonly ['CART_NOT_FOUND', 'CART_EMPTY']\n *\n * await step('getCart', () => getCart(id), {\n * errors: errs, // Analyzer can extract literal types\n * out: 'cart',\n * });\n * ```\n */\nexport const tags = <const T extends readonly string[]>(...t: T): T => t;\n\nimport { UnexpectedError } from \"../errors\";\nexport { UnexpectedError };\nexport type PromiseRejectedError = { type: typeof PROMISE_REJECTED; cause: unknown };\n/** Cause type for promise rejections in async batch helpers */\nexport type PromiseRejectionCause = { type: \"PROMISE_REJECTION\"; reason: unknown };\nexport type EmptyInputError = { type: \"EMPTY_INPUT\"; message: string };\nexport type MaybeAsyncResult<T, E, C = unknown> = Result<T, E, C> | Promise<Result<T, E, C>>;\n\n// =============================================================================\n// Result Constructors\n// =============================================================================\n\n/**\n * Creates a successful Result.\n *\n * @remarks When to use: Wrap a successful value in a Result for consistent return types.\n */\nexport function ok(): Ok<void>;\nexport function ok<T>(value: T): Ok<T>;\nexport function ok<T>(value?: T): Ok<T | void> {\n return { ok: true as const, value: value as T | void };\n}\n\n/**\n * Creates a failed Result.\n *\n * @remarks When to use: Return a typed failure without throwing so callers can handle it explicitly.\n */\nexport function err<E, C = unknown>(error: E, options?: { cause?: C }): Err<E, C> {\n const cause = options?.cause;\n return { ok: false as const, error, ...(cause !== undefined ? { cause } : {}) } as Err<E, C>;\n}\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Checks if a Result is successful.\n *\n * @remarks When to use: Prefer functional-style checks or array filtering over `result.ok`.\n */\nexport const isOk = <T, E, C>(r: Result<T, E, C>): r is Ok<T> => r.ok;\n\n/**\n * Checks if a Result is a failure.\n *\n * @remarks When to use: Prefer functional-style checks or array filtering over `result.ok`.\n */\nexport const isErr = <T, E, C>(r: Result<T, E, C>): r is Err<E, C> => !r.ok;\n\n/**\n * Checks if an error is an UnexpectedError.\n *\n * @remarks When to use: Distinguish unexpected failures from your typed error union.\n */\nexport const isUnexpectedError = (e: unknown): e is UnexpectedError =>\n e instanceof UnexpectedError ||\n (typeof e === \"object\" &&\n e !== null &&\n \"_tag\" in e &&\n (e as { _tag: string })._tag === \"UnexpectedError\");\n\n/**\n * Checks if an error is a PromiseRejectedError.\n */\nexport const isPromiseRejectedError = (e: unknown): e is PromiseRejectedError =>\n typeof e === \"object\" &&\n e !== null &&\n \"type\" in e &&\n e.type === PROMISE_REJECTED;\n\n// =============================================================================\n// Error Matching\n// =============================================================================\n\nexport type MatchErrorHandlers<E extends string, R> = {\n [K in Exclude<E, \"UnexpectedError\">]: (error: K) => R;\n} & {\n UnexpectedError: (error: UnexpectedError) => R;\n};\n\n/**\n * Match on string error types with exhaustive checking.\n * Takes an error value (not a Result) and handlers for each error type.\n */\nexport function matchError<E extends string, R>(\n handlers: MatchErrorHandlers<E, R>\n): (error: E | UnexpectedError) => R;\nexport function matchError<E extends string, R>(\n error: E | UnexpectedError,\n handlers: MatchErrorHandlers<E, R>\n): R;\nexport function matchError<E extends string, R>(\n errorOrHandlers: E | UnexpectedError | MatchErrorHandlers<E, R>,\n handlers?: MatchErrorHandlers<E, R>\n): R | ((error: E | UnexpectedError) => R) {\n if (handlers === undefined) {\n const h = errorOrHandlers as MatchErrorHandlers<E, R>;\n return (e: E | UnexpectedError) => matchError(e, h);\n }\n const error = errorOrHandlers as E | UnexpectedError;\n // Handle UnexpectedError instances\n if (isUnexpectedError(error)) {\n return handlers.UnexpectedError(error as UnexpectedError);\n }\n // Handle string literal errors\n type StringErrors = Exclude<E, \"UnexpectedError\">;\n return (handlers as unknown as Record<string, (e: string) => R>)[error as StringErrors](error as StringErrors);\n}\n\n// =============================================================================\n// Type Utilities\n// =============================================================================\n\ntype AnyFunction = (...args: never[]) => unknown;\n\n/**\n * Helper to extract the error type from Result or AsyncResult return values.\n * Works even when a function is declared to return a union of both forms.\n * Plain (non-Result) return types contribute `never` — without the [never]\n * guard they would infer `unknown` and poison error unions built from\n * mixed deps.\n */\ntype ErrorOfReturn<R> = [Extract<Awaited<R>, { ok: false }>] extends [never]\n ? never\n : Extract<Awaited<R>, { ok: false }> extends { error: infer E }\n ? E\n : never;\n\n/**\n * Extract error type from a single function's return type\n */\nexport type ErrorOf<T extends AnyFunction> = ErrorOfReturn<ReturnType<T>>;\n\n/**\n * Extract union of error types from multiple functions (tuple form)\n */\nexport type Errors<T extends AnyFunction[]> = {\n [K in keyof T]: ErrorOf<T[K]>;\n}[number];\n\n/**\n * Extract union of error types from a deps object.\n *\n * @example\n * ```typescript\n * const deps = { getUser, createOrder, sendEmail };\n * type E = ErrorsOf<typeof deps>;\n * // = \"NOT_FOUND\" | \"ORDER_FAILED\" | \"EMAIL_ERROR\"\n * ```\n */\nexport type ErrorsOf<Deps extends Record<string, AnyFunction>> = {\n [K in keyof Deps]: ErrorOf<Deps[K]>;\n}[keyof Deps];\n\n/**\n * Extract value type from Result\n */\nexport type ExtractValue<T> = T extends { ok: true; value: infer U }\n ? U\n : never;\n\n/**\n * Extract error type from Result\n */\nexport type ExtractError<T> = T extends { ok: false; error: infer E }\n ? E\n : never;\n\n/**\n * Extract cause type from Result\n */\nexport type ExtractCause<T> = T extends { ok: false; cause?: infer C }\n ? C\n : never;\n\n/**\n * Helper to extract the cause type from Result or AsyncResult return values.\n * Works even when a function is declared to return a union of both forms.\n */\ntype CauseOfReturn<R> = Extract<Awaited<R>, { ok: false }> extends { cause?: infer C }\n ? C\n : never;\n\n/**\n * Extract cause type from a function's return type\n */\nexport type CauseOf<T extends AnyFunction> = CauseOfReturn<ReturnType<T>>;\n\n// =============================================================================\n// Unwrap Utilities\n// =============================================================================\n\n/**\n * Error thrown when attempting to unwrap an Err result.\n */\nexport class UnwrapError extends Error {\n public readonly error: unknown;\n public readonly cause?: unknown;\n\n constructor(result: Err<unknown, unknown>) {\n const errorStr =\n typeof result.error === \"string\"\n ? result.error\n : JSON.stringify(result.error);\n super(`Attempted to unwrap an Err: ${errorStr}`);\n this.name = \"UnwrapError\";\n this.error = result.error;\n this.cause = result.cause;\n }\n}\n\n/**\n * Extracts the value from an Ok result, or throws UnwrapError if it's an Err.\n *\n * @remarks When to use: Only at boundaries or tests where a failure should be fatal.\n */\nexport const unwrap = <T, E, C>(r: Result<T, E, C>): T => {\n if (r.ok) return r.value;\n throw new UnwrapError(r);\n};\n\n/**\n * Extracts the value from an Ok result, or returns a default value if it's an Err.\n *\n * @remarks When to use: Provide a safe fallback without branching.\n */\nexport const unwrapOr = <T, E, C>(r: Result<T, E, C>, defaultValue: T): T =>\n r.ok ? r.value : defaultValue;\n\n/**\n * Extracts the value from an Ok result, or calls a function to get a default value if it's an Err.\n *\n * @remarks When to use: Compute a fallback from the error (logging, metrics, or derived defaults).\n */\nexport const unwrapOrElse = <T, E, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => T\n): T => (r.ok ? r.value : fn(r.error, r.cause));\n\n/**\n * Alias for `unwrap`. Returns the success value or throws.\n *\n * The Result is already computed; use when you want the value or throw (e.g. at boundaries or in tests).\n *\n * @param r - The Result to unwrap\n * @returns The success value if the Result is successful\n * @throws {UnwrapError} If the Result is an error (includes the error and cause)\n */\nexport const runOrThrow = <T, E, C>(r: Result<T, E, C>): T => unwrap(r);\n\n/**\n * Awaits a Promise of a Result, then returns the success value or rejects.\n *\n * The returned promise **resolves with T** on success and **rejects with UnwrapError** on failure.\n * UnwrapError extends Error and carries the original `error` and `cause` from the Err.\n *\n * @param ar - A Promise or thenable that resolves to a Result\n * @returns A Promise that resolves with the success value or rejects with UnwrapError\n */\nexport const runOrThrowAsync = <T, E, C>(\n ar: PromiseLike<Result<T, E, C>>\n): Promise<T> => Promise.resolve(ar).then(unwrap);\n\n/**\n * Convenience alias for `unwrapOr(r, null)`. Returns the success value or null.\n *\n * @param r - The Result to unwrap\n * @returns The success value if successful, otherwise null\n */\nexport const runOrNull = <T, E, C>(r: Result<T, E, C>): T | null =>\n r.ok ? r.value : null;\n\n/**\n * Convenience alias for `unwrapOr(r, undefined)`. Returns the success value or undefined.\n *\n * @param r - The Result to unwrap\n * @returns The success value if successful, otherwise undefined\n */\nexport const runOrUndefined = <T, E, C>(r: Result<T, E, C>): T | undefined =>\n r.ok ? r.value : undefined;\n\n// =============================================================================\n// Wrapping Functions\n// =============================================================================\n\n/**\n * Wraps a synchronous function that might throw into a Result.\n *\n * @remarks When to use: Wrap sync code that might throw so exceptions become Err values.\n */\nexport function from<T>(fn: () => T): Ok<T> | Err<unknown, unknown>;\nexport function from<T, E>(fn: () => T, onError: (cause: unknown) => E): Ok<T> | Err<E, unknown>;\nexport function from<T, E>(fn: () => T, onError?: (cause: unknown) => E) {\n try {\n return ok(fn());\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Wraps a Promise into a Result.\n *\n * @remarks When to use: Wrap a Promise and keep the raw rejection as Err; use tryAsync to map errors.\n */\nexport function fromPromise<T>(promise: Promise<T>): Promise<Ok<T> | Err<unknown, unknown>>;\nexport function fromPromise<T, E>(\n promise: Promise<T>,\n onError: (cause: unknown) => E\n): Promise<Ok<T> | Err<E, unknown>>;\nexport async function fromPromise<T, E>(\n promise: Promise<T>,\n onError?: (cause: unknown) => E\n): Promise<Ok<T> | Err<E | unknown, unknown>> {\n try {\n return ok(await promise);\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Wraps an async function that might throw into an AsyncResult.\n *\n * @remarks When to use: Wrap async work and map thrown/rejected values into your typed error union.\n */\nexport function tryAsync<T>(fn: () => Promise<T>): AsyncResult<T, unknown>;\nexport function tryAsync<T, E>(\n fn: () => Promise<T>,\n onError: (cause: unknown) => E\n): AsyncResult<T, E>;\nexport async function tryAsync<T, E>(\n fn: () => Promise<T>,\n onError?: (cause: unknown) => E\n): AsyncResult<T, E | unknown> {\n try {\n return ok(await fn());\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Converts a nullable value into a Result.\n *\n * @remarks When to use: Turn null/undefined into a typed error before continuing.\n */\nexport function fromNullable<T, E>(\n value: T | null | undefined,\n onNull: () => E\n): Result<T, E> {\n return value != null ? ok(value) : err(onNull());\n}\n\n// =============================================================================\n// Transformers\n// =============================================================================\n\n/**\n * Transforms the value inside an Ok result.\n *\n * @remarks When to use: Transform only the Ok value while leaving Err untouched.\n */\nexport function map<T, U>(r: Ok<T>, fn: (value: T) => U): Ok<U>;\nexport function map<T, U, E, C>(r: Err<E, C>, fn: (value: T) => U): Err<E, C>;\nexport function map<T, U, E, C>(r: Result<T, E, C>, fn: (value: T) => U): Result<U, E, C>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function map(r: any, fn: any): any {\n return r.ok ? ok(fn(r.value)) : r;\n}\n\n/**\n * Transforms the error inside an Err result.\n *\n * @remarks When to use: Retype or normalize errors while leaving Ok values unchanged.\n */\nexport function mapError<T, E, F, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => F\n): Result<T, F, C> {\n return r.ok ? r : err(fn(r.error, r.cause), { cause: r.cause });\n}\n\n/**\n * Pattern match on a Result.\n *\n * @remarks When to use: Handle both Ok and Err in a single expression that returns a value.\n */\n/**\n * The discriminant of an error value: the string itself for string-literal\n * errors, or the `type` field for tagged objects and TaggedError instances\n * (`_tag` accepted as a deprecated alias during migration).\n */\nexport type ErrorTypeOf<E> = E extends string\n ? E\n : E extends { type: infer K extends string }\n ? K\n : E extends { _tag: infer K extends string }\n ? K\n : never;\n\n/** Narrow an error union to the member(s) identified by a type string. */\nexport type ErrorByType<E, K extends string> = Extract<\n E,\n K | { type: K } | { _tag: K }\n>;\n\n/**\n * Exhaustive per-type match arms: one handler per member of the error\n * union, keyed by its type string, plus the `ok` arm. Each handler\n * receives the full narrowed error (string, tagged object, or TaggedError).\n */\nexport type MatchTypeHandlers<T, E, C, R> = { ok: (value: T) => R } & {\n [K in ErrorTypeOf<E>]: (error: ErrorByType<E, K>, cause?: C) => R;\n};\n\n// Two-arm form (ok/err catch-all), curried and direct\nexport function match<T, E, C, R>(handlers: { ok: (value: T) => R; err: (error: E, cause?: C) => R }): (r: Result<T, E, C>) => R;\nexport function match<T, E, C, R>(r: Ok<T>, handlers: { ok: (value: T) => R; err: (error: E, cause?: C) => R }): R;\nexport function match<T, E, C, R>(r: Err<E, C>, handlers: { ok: (value: T) => R; err: (error: E, cause?: C) => R }): R;\nexport function match<T, E, C, R>(r: Result<T, E, C>, handlers: { ok: (value: T) => R; err: (error: E, cause?: C) => R }): R;\n// Exhaustive per-type form: match(result, { ok, USER_NOT_FOUND, CHARGE_DECLINED, ... })\nexport function match<T, E, C, R>(r: Result<T, E, C>, handlers: MatchTypeHandlers<T, E, C, R>): R;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function match(r: any, handlers?: any): any {\n if (handlers === undefined) {\n const h = r;\n return (result: Result<unknown, unknown, unknown>) => match(result, h);\n }\n if (r.ok) return handlers.ok(r.value);\n // Catch-all arm wins when present (the simple two-arm form)\n if (typeof handlers.err === \"function\") return handlers.err(r.error, r.cause);\n // Per-type dispatch: string errors match themselves; tagged errors match\n // their `type` (or legacy `_tag`)\n const e = r.error;\n const key = typeof e === \"string\" ? e : (e?.type ?? e?._tag);\n const handler = key === undefined ? undefined : handlers[key];\n if (typeof handler === \"function\") return handler(e, r.cause);\n throw new TypeError(\n `match: no handler for error type \"${String(key)}\". ` +\n `Add a handler for it, or use the { ok, err } form for a catch-all.`\n );\n}\n\n/**\n * Chain Result-returning functions.\n *\n * @remarks When to use: Chain dependent operations that return Result without nested branching.\n */\nexport function andThen<T, U>(r: Ok<T>, fn: (value: T) => Ok<U>): Ok<U>;\nexport function andThen<T, F, C2>(r: Ok<T>, fn: (value: T) => Err<F, C2>): Err<F, C2>;\nexport function andThen<T, U, F, C2>(r: Ok<T>, fn: (value: T) => Result<U, F, C2>): Result<U, F, C2>;\nexport function andThen<T, U, E, F, C1, C2>(r: Err<E, C1>, fn: (value: T) => Result<U, F, C2>): Err<E, C1>;\nexport function andThen<T, U, E, F, C1, C2>(r: Result<T, E, C1>, fn: (value: T) => Result<U, F, C2>): Result<U, E | F, C1 | C2>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function andThen(r: any, fn: any): any {\n return r.ok ? fn(r.value) : r;\n}\n\n/**\n * Execute a side effect on Ok values.\n *\n * @remarks When to use: Add side effects (logging, metrics) on Ok without changing the Result.\n */\nexport function tap<T, E, C>(\n r: Result<T, E, C>,\n fn: (value: T) => void\n): Result<T, E, C> {\n if (r.ok) fn(r.value);\n return r;\n}\n\n/**\n * Execute a side effect on Err values.\n *\n * @remarks When to use: Add side effects (logging, metrics) on Err without changing the Result.\n */\nexport function tapError<T, E, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => void\n): Result<T, E, C> {\n if (!r.ok) fn(r.error, r.cause);\n return r;\n}\n\n/**\n * Transform value with a function that might throw.\n *\n * @remarks When to use: Transform Ok values with a function that might throw and capture the failure.\n */\nexport function mapTry<T, U, E, F, C>(\n r: Result<T, E, C>,\n fn: (value: T) => U,\n onError: (thrown: unknown) => F\n): Result<U, E | F, C | unknown> {\n if (!r.ok) return r;\n try {\n return ok(fn(r.value));\n } catch (error) {\n return err(onError(error), { cause: error });\n }\n}\n\n/**\n * Transform error with a function that might throw.\n *\n * @remarks When to use: Transform errors when the mapping might throw and you want that captured.\n */\nexport function mapErrorTry<T, E, F, G, C>(\n r: Result<T, E, C>,\n fn: (error: E) => F,\n onError: (thrown: unknown) => G\n): Result<T, F | G, C | unknown> {\n if (r.ok) return r;\n try {\n return err(fn(r.error), { cause: r.cause });\n } catch (error) {\n return err(onError(error), { cause: error });\n }\n}\n\n/**\n * Transform both value and error.\n */\nexport function bimap<T, U, E, F, C>(\n r: Result<T, E, C>,\n onOk: (value: T) => U,\n onErr: (error: E, cause?: C) => F\n): Result<U, F, C> {\n return r.ok ? ok(onOk(r.value)) : err(onErr(r.error, r.cause), { cause: r.cause });\n}\n\n/**\n * Provide an alternative Result if the first is an Err.\n *\n * @remarks When to use: Recover from Err by returning a fallback Result or retyping the error.\n */\nexport function orElse<T, E, E2, C, C2>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => Result<T, E2, C2>\n): Result<T, E2, C | C2> {\n return r.ok ? r : fn(r.error, r.cause);\n}\n\n/**\n * Async version of orElse.\n */\nexport async function orElseAsync<T, E, E2, C, C2>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => Promise<Result<T, E2, C2>>\n): Promise<Result<T, E2, C | C2>> {\n return r.ok ? r : fn(r.error, r.cause);\n}\n\n/**\n * Recover from errors - always returns Ok<T>.\n */\nexport function recover<T, E, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => T\n): Ok<T> {\n return r.ok ? ok(r.value) : ok(fn(r.error, r.cause));\n}\n\n/**\n * Async version of recover - always returns Promise<Ok<T>>.\n */\nexport async function recoverAsync<T, E, C>(\n r: Result<T, E, C> | Promise<Result<T, E, C>>,\n fn: (error: E, cause?: C) => T | Promise<T>\n): Promise<Ok<T>> {\n const resolved = await r;\n if (resolved.ok) return ok(resolved.value);\n return ok(await fn(resolved.error, resolved.cause));\n}\n\n// =============================================================================\n// Result Hydration (Serialization)\n// =============================================================================\n\n/**\n * Hydrate a serialized Result back into a proper Result object.\n */\nexport function hydrate<T, E, C = unknown>(value: unknown): Result<T, E, C> | null {\n if (typeof value !== \"object\" || value === null) return null;\n if (!(\"ok\" in value)) return null;\n\n const obj = value as Record<string, unknown>;\n if (obj.ok === true && \"value\" in obj) {\n return ok(obj.value as T);\n }\n if (obj.ok === false && \"error\" in obj) {\n return err(obj.error as E, { cause: obj.cause as C });\n }\n return null;\n}\n\n/**\n * Type guard to check if a value is a serialized Result.\n */\nexport function isSerializedResult(\n value: unknown\n): value is { ok: boolean; value?: unknown; error?: unknown; cause?: unknown } {\n if (typeof value !== \"object\" || value === null) return false;\n if (!(\"ok\" in value)) return false;\n const obj = value as Record<string, unknown>;\n return (\n (obj.ok === true && \"value\" in obj) ||\n (obj.ok === false && \"error\" in obj)\n );\n}\n\n// =============================================================================\n// Batch Operations\n// =============================================================================\n\ntype AllValues<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Ok<infer V>\n ? V\n : T[K] extends Err<unknown, unknown>\n ? never\n : T[K] extends Result<infer V, unknown, unknown>\n ? V\n : never;\n};\ntype AllErrors<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Ok<unknown>\n ? never\n : T[K] extends Err<infer E, unknown>\n ? E\n : T[K] extends Result<unknown, infer E, unknown>\n ? E\n : never;\n}[number];\ntype AllCauses<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Ok<unknown>\n ? never\n : T[K] extends Err<unknown, infer C>\n ? C\n : T[K] extends Result<unknown, unknown, infer C>\n ? C\n : never;\n}[number];\n\n// Conditional type: returns Ok<...> when there are no errors, Result<...> otherwise\n// Note: We only check AllErrors, not AllCauses - causes only matter when there are errors\ntype AllResult<T extends readonly Result<unknown, unknown, unknown>[]> =\n [AllErrors<T>] extends [never]\n ? Ok<AllValues<T>>\n : Result<AllValues<T>, AllErrors<T>, AllCauses<T>>;\n\n/**\n * Combines multiple Results into a single Result containing an array of values.\n * Returns the first Err encountered, or Ok with all values.\n */\nexport function all<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): AllResult<T> {\n const values: unknown[] = [];\n for (const result of results) {\n if (!result.ok) {\n return result as unknown as AllResult<T>;\n }\n values.push(result.value);\n }\n return ok(values) as AllResult<T>;\n}\n\n/**\n * Async version of all - works with Promises of Results.\n */\nexport async function allAsync<\n const T extends readonly (Result<unknown, unknown, unknown> | Promise<Result<unknown, unknown, unknown>>)[]\n>(\n results: T\n): Promise<\n Result<\n { [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> | Promise<Result<infer V, unknown, unknown>> ? V : never },\n | { [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> | Promise<Result<unknown, infer E, unknown>> ? E : never }[number]\n | PromiseRejectedError,\n | { [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> | Promise<Result<unknown, unknown, infer C>> ? C : never }[number]\n | PromiseRejectionCause\n >\n> {\n const values: unknown[] = [];\n for (const resultOrPromise of results) {\n try {\n const r = await resultOrPromise;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (!r.ok) return r as any;\n values.push(r.value);\n } catch (reason) {\n return err(\n { type: PROMISE_REJECTED, cause: reason } as PromiseRejectedError,\n { cause: { type: \"PROMISE_REJECTION\", reason } as PromiseRejectionCause }\n );\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return ok(values) as any;\n}\n\nexport type SettledError<E, C = unknown> = { error: E; cause?: C };\n\n// Conditional type: returns Ok<...> when there are no errors, Result<...> otherwise\ntype AllSettledResult<T extends readonly Result<unknown, unknown, unknown>[]> =\n [AllErrors<T>] extends [never]\n ? Ok<AllValues<T>>\n : Result<AllValues<T>, SettledError<AllErrors<T>, AllCauses<T>>[]>;\n\n/**\n * Collects all Results, returning Ok with values if all succeed,\n * or Err with array of errors if any fail.\n */\nexport function allSettled<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): AllSettledResult<T> {\n const values: unknown[] = [];\n const errors: SettledError<unknown>[] = [];\n\n for (const result of results) {\n if (result.ok) {\n values.push(result.value);\n } else {\n errors.push({ error: result.error, cause: result.cause });\n }\n }\n\n if (errors.length > 0) {\n return err(errors) as unknown as AllSettledResult<T>;\n }\n\n return ok(values) as unknown as AllSettledResult<T>;\n}\n\n/**\n * Async version of allSettled.\n */\nexport async function allSettledAsync<\n const T extends readonly (Result<unknown, unknown, unknown> | Promise<Result<unknown, unknown, unknown>>)[]\n>(\n results: T\n): Promise<\n Result<\n { [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> | Promise<Result<infer V, unknown, unknown>> ? V : never },\n SettledError<\n | { [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> | Promise<Result<unknown, infer E, unknown>> ? E : never }[number]\n | PromiseRejectedError,\n | { [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> | Promise<Result<unknown, unknown, infer C>> ? C : never }[number]\n | PromiseRejectionCause\n >[]\n >\n> {\n const settled = await Promise.all(\n results.map((item) =>\n Promise.resolve(item)\n .then((result) => ({ status: \"result\" as const, result }))\n .catch((reason) => ({\n status: \"rejected\" as const,\n error: { type: PROMISE_REJECTED, cause: reason } as PromiseRejectedError,\n cause: { type: \"PROMISE_REJECTION\", reason } as PromiseRejectionCause,\n }))\n )\n );\n\n const values: unknown[] = [];\n const errors: SettledError<unknown, unknown>[] = [];\n\n for (const item of settled) {\n if (item.status === \"rejected\") {\n errors.push({ error: item.error, cause: item.cause });\n } else if (item.result.ok) {\n values.push(item.result.value);\n } else {\n errors.push({ error: item.result.error, cause: item.result.cause });\n }\n }\n\n if (errors.length > 0) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return err(errors) as any;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return ok(values) as any;\n}\n\n/**\n * Partitions Results into { values, errors }.\n */\nexport function partition<T, E, C>(\n results: readonly Result<T, E, C>[]\n): { values: T[]; errors: E[] } {\n const values: T[] = [];\n const errors: E[] = [];\n for (const r of results) {\n if (r.ok) values.push(r.value);\n else errors.push(r.error);\n }\n return { values, errors };\n}\n\n/**\n * Returns the first Ok result, or an EmptyInputError/first Err if all fail.\n */\nexport function any<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): T extends readonly []\n ? Err<EmptyInputError, unknown>\n : Result<\n { [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> ? V : never }[number],\n AllErrors<T> | EmptyInputError,\n AllCauses<T>\n >;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function any(results: any): any {\n if (results.length === 0) {\n return err({ type: \"EMPTY_INPUT\", message: \"any() requires at least one Result\" });\n }\n let firstErr: Err<unknown, unknown> | undefined;\n for (const r of results) {\n if (r.ok) return r;\n if (!firstErr) firstErr = r;\n }\n return firstErr;\n}\n\n/**\n * Async version of any - races promises and returns first success.\n */\nexport async function anyAsync<\n const T extends readonly (Result<unknown, unknown, unknown> | Promise<Result<unknown, unknown, unknown>>)[]\n>(\n results: T\n): Promise<\n T extends readonly []\n ? Err<EmptyInputError, unknown>\n : Result<\n { [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> | Promise<Result<infer V, unknown, unknown>> ? V : never }[number],\n | { [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> | Promise<Result<unknown, infer E, unknown>> ? E : never }[number]\n | EmptyInputError\n | PromiseRejectedError,\n | { [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> | Promise<Result<unknown, unknown, infer C>> ? C : never }[number]\n | PromiseRejectionCause\n >\n> {\n if (results.length === 0) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return err({ type: \"EMPTY_INPUT\", message: \"anyAsync() requires at least one Result\" }) as any;\n }\n\n return new Promise((resolve) => {\n let settled = false;\n let pendingCount = results.length;\n let firstError: Err<unknown, unknown> | null = null;\n\n for (const item of results) {\n Promise.resolve(item)\n .catch((reason) =>\n err(\n { type: PROMISE_REJECTED, cause: reason } as PromiseRejectedError,\n { cause: { type: \"PROMISE_REJECTION\", reason } as PromiseRejectionCause }\n )\n )\n .then((result) => {\n if (settled) return;\n\n if (result.ok) {\n settled = true;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n resolve(result as any);\n return;\n }\n\n if (!firstError) firstError = result;\n pendingCount--;\n\n if (pendingCount === 0) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n resolve(firstError as any);\n }\n });\n }\n });\n}\n\n/**\n * Combines exactly two Results into a tuple.\n */\nexport function zip<A, EA, CA, B, EB, CB>(\n a: Result<A, EA, CA>,\n b: Result<B, EB, CB>\n): Result<[A, B], EA | EB, CA | CB> {\n if (!a.ok) return a;\n if (!b.ok) return b;\n return ok([a.value, b.value]);\n}\n\n/**\n * Async version of zip.\n */\nexport async function zipAsync<A, EA, CA, B, EB, CB>(\n a: Result<A, EA, CA> | Promise<Result<A, EA, CA>>,\n b: Result<B, EB, CB> | Promise<Result<B, EB, CB>>\n): Promise<Result<[A, B], EA | EB | PromiseRejectedError, CA | CB | PromiseRejectionCause>> {\n // Wrap rejections into PromiseRejectedError (consistent with allAsync)\n const wrapRejection = <T, E, C>(\n p: Result<T, E, C> | Promise<Result<T, E, C>>\n ): Promise<Result<T, E | PromiseRejectedError, C | PromiseRejectionCause>> =>\n Promise.resolve(p).catch((reason) =>\n err(\n { type: PROMISE_REJECTED, cause: reason } as PromiseRejectedError,\n { cause: { type: \"PROMISE_REJECTION\", reason } as PromiseRejectionCause }\n )\n );\n\n const [ra, rb] = await Promise.all([wrapRejection(a), wrapRejection(b)]);\n return zip(ra, rb);\n}\n\n// =============================================================================\n// Flatten\n// =============================================================================\n\n/**\n * Flattens a nested Result into a single Result.\n *\n * @remarks When to use: Unwrap a Result<Result<T, E1>, E2> into Result<T, E1 | E2> after an operation that returns nested Results.\n */\nexport function flatten<T, E1, C1, E2, C2>(\n result: Result<Result<T, E1, C1>, E2, C2>\n): Result<T, E1 | E2, C1 | C2> {\n if (!result.ok) return result as Err<E2, C2>;\n return result.value;\n}\n\n// =============================================================================\n// Deserialization (improved hydrate)\n// =============================================================================\n\n/** Discriminant for deserialization errors */\nexport const DESERIALIZATION_ERROR = \"DESERIALIZATION_ERROR\" as const;\n\n/** Error type returned when deserialize() receives invalid input */\nexport type DeserializationError = { type: typeof DESERIALIZATION_ERROR; value: unknown };\n\n/**\n * Deserialize a value back into a Result.\n * Returns a typed DeserializationError on invalid input instead of null.\n *\n * @remarks When to use: Rehydrate Results from JSON, RPC, or server actions with type-safe error handling.\n */\nexport function deserialize<T, E, C = unknown>(\n value: unknown\n): Result<T, E | DeserializationError, C> {\n if (typeof value !== \"object\" || value === null) {\n return err({ type: DESERIALIZATION_ERROR, value } as DeserializationError);\n }\n if (!(\"ok\" in value)) {\n return err({ type: DESERIALIZATION_ERROR, value } as DeserializationError);\n }\n\n const obj = value as Record<string, unknown>;\n if (obj.ok === true && \"value\" in obj) {\n return ok(obj.value as T);\n }\n if (obj.ok === false && \"error\" in obj) {\n return err(obj.error as E, { cause: obj.cause as C });\n }\n return err({ type: DESERIALIZATION_ERROR, value } as DeserializationError);\n}\n\n// =============================================================================\n// Serialization\n// =============================================================================\n\n/** A plain serialized form of a Result, safe to JSON.stringify. */\nexport type SerializedResult<T, E> = { ok: true; value: T } | { ok: false; error: E };\n\n/**\n * Serialize a Result to a plain object (inverse of `deserialize`).\n * Strips cause — safe for JSON.stringify, RPC, and server actions.\n *\n * @remarks When to use: Sending Results over the wire or storing them in JSON.\n */\nexport function serialize<T, E>(result: Result<T, E>): SerializedResult<T, E> {\n return result.ok\n ? { ok: true, value: result.value }\n : { ok: false, error: result.error };\n}\n\n// =============================================================================\n// Partial error matching\n// =============================================================================\n\n/**\n * Non-exhaustive error match — handle the errors you care about; let the rest fall through to fallback.\n *\n * @example\n * ```typescript\n * const message = matchErrorPartial(\n * error,\n * { NOT_FOUND: () => 'Resource not found' },\n * (e) => `Unexpected: ${e}`\n * );\n * ```\n */\nexport function matchErrorPartial<E extends string, R>(\n error: E | UnexpectedError,\n handlers: Partial<MatchErrorHandlers<E, R>>,\n fallback: (error: E | UnexpectedError) => R\n): R {\n if (isUnexpectedError(error)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const h = (handlers as any).UnexpectedError as ((e: UnexpectedError) => R) | undefined;\n return h ? h(error) : fallback(error);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const h = (handlers as any)[error as string] as ((e: E) => R) | undefined;\n return h ? h(error as E) : fallback(error);\n}\n\n// Retry helpers live in ./retry as internal building blocks and are\n// intentionally NOT re-exported here (keeps awaitly/result minimal).\n// The public retry surface is the `retry` policy on the root `awaitly` entry.\n","import type { UnexpectedError } from \"./core\";\nimport type { RunConfig, Workflow } from \"./workflow/types\";\n\n/**\n * Pre-bind dependency overrides on a workflow.\n *\n * Returns another `Workflow` with the same shape — chain `.withDeps()`,\n * call `.run()` / `.runWithState()` exactly as before.\n *\n * Precedence (lowest → highest):\n * createWorkflow deps < withDeps deps < run config deps\n */\nexport function withDeps<E, U = UnexpectedError, Deps = unknown, C = void>(\n workflow: Workflow<E, U, Deps, C>,\n overrides: Partial<Deps>\n): Workflow<E, U, Deps, C> {\n const forward = <Method extends \"run\" | \"runWithState\">(method: Method) =>\n ((...args: unknown[]) => {\n const last = args.at(-1);\n const hasConfig =\n args.length > 0 &&\n typeof last === \"object\" &&\n last !== null &&\n !Array.isArray(last) &&\n typeof last !== \"function\";\n\n const config = hasConfig ? (last as RunConfig<E, U, C, Deps>) : undefined;\n const head = hasConfig ? args.slice(0, -1) : args;\n\n const mergedDeps = { ...overrides, ...(config?.deps ?? {}) } as Partial<Deps>;\n const mergedConfig: RunConfig<E, U, C, Deps> = config\n ? { ...config, deps: mergedDeps }\n : ({ deps: mergedDeps } as RunConfig<E, U, C, Deps>);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (workflow[method] as any)(...head, mergedConfig);\n }) as Workflow<E, U, Deps, C>[Method];\n\n return {\n run: forward(\"run\"),\n runWithState: forward(\"runWithState\"),\n withDeps(nextOverrides: Partial<Deps>) {\n return withDeps(workflow, { ...overrides, ...nextOverrides });\n },\n };\n}\n","/**\n * awaitly/duration\n *\n * Type-safe duration handling inspired by Effect's Duration module.\n * Prevents unit confusion (milliseconds vs seconds) with explicit constructors.\n */\n\n// =============================================================================\n// Duration Type\n// =============================================================================\n\n/**\n * A type-safe representation of a time duration.\n * Use the constructor functions (millis, seconds, etc.) to create durations.\n */\nexport interface Duration {\n readonly _tag: \"Duration\";\n readonly millis: number;\n}\n\n// =============================================================================\n// Constructors\n// =============================================================================\n\n/**\n * Create a Duration from milliseconds.\n *\n * @example\n * ```typescript\n * const d = Duration.millis(500)\n * ```\n */\nexport function millis(ms: number): Duration {\n return { _tag: \"Duration\", millis: ms };\n}\n\n/**\n * Create a Duration from seconds.\n *\n * @example\n * ```typescript\n * const d = Duration.seconds(5) // 5000ms\n * ```\n */\nexport function seconds(s: number): Duration {\n return { _tag: \"Duration\", millis: s * 1000 };\n}\n\n/**\n * Create a Duration from minutes.\n *\n * @example\n * ```typescript\n * const d = Duration.minutes(2) // 120000ms\n * ```\n */\nexport function minutes(m: number): Duration {\n return { _tag: \"Duration\", millis: m * 60 * 1000 };\n}\n\n/**\n * Create a Duration from hours.\n *\n * @example\n * ```typescript\n * const d = Duration.hours(1) // 3600000ms\n * ```\n */\nexport function hours(h: number): Duration {\n return { _tag: \"Duration\", millis: h * 60 * 60 * 1000 };\n}\n\n/**\n * Create a Duration from days.\n *\n * @example\n * ```typescript\n * const d = Duration.days(1) // 86400000ms\n * ```\n */\nexport function days(d: number): Duration {\n return { _tag: \"Duration\", millis: d * 24 * 60 * 60 * 1000 };\n}\n\n/**\n * Zero duration.\n */\nexport const zero: Duration = { _tag: \"Duration\", millis: 0 };\n\n/**\n * Infinite duration (represented as Infinity milliseconds).\n */\nexport const infinity: Duration = { _tag: \"Duration\", millis: Infinity };\n\n// =============================================================================\n// Conversions\n// =============================================================================\n\n/**\n * Convert a Duration to milliseconds.\n */\nexport function toMillis(duration: Duration): number {\n return duration.millis;\n}\n\n/**\n * Convert a Duration to seconds.\n */\nexport function toSeconds(duration: Duration): number {\n return duration.millis / 1000;\n}\n\n/**\n * Convert a Duration to minutes.\n */\nexport function toMinutes(duration: Duration): number {\n return duration.millis / (60 * 1000);\n}\n\n/**\n * Convert a Duration to hours.\n */\nexport function toHours(duration: Duration): number {\n return duration.millis / (60 * 60 * 1000);\n}\n\n/**\n * Convert a Duration to days.\n */\nexport function toDays(duration: Duration): number {\n return duration.millis / (24 * 60 * 60 * 1000);\n}\n\n// =============================================================================\n// Operations\n// =============================================================================\n\n/**\n * Add two durations.\n *\n * @example\n * ```typescript\n * const total = Duration.add(Duration.seconds(5), Duration.millis(500))\n * // 5500ms\n * ```\n */\nexport function add(a: Duration, b: Duration): Duration {\n return { _tag: \"Duration\", millis: a.millis + b.millis };\n}\n\n/**\n * Subtract duration b from duration a.\n * Result is clamped to zero (no negative durations).\n *\n * @example\n * ```typescript\n * const remaining = Duration.subtract(Duration.seconds(5), Duration.seconds(2))\n * // 3000ms\n * ```\n */\nexport function subtract(a: Duration, b: Duration): Duration {\n return { _tag: \"Duration\", millis: Math.max(0, a.millis - b.millis) };\n}\n\n/**\n * Multiply a duration by a factor.\n *\n * @example\n * ```typescript\n * const doubled = Duration.multiply(Duration.seconds(5), 2)\n * // 10000ms\n * ```\n */\nexport function multiply(duration: Duration, factor: number): Duration {\n return { _tag: \"Duration\", millis: duration.millis * factor };\n}\n\n/**\n * Divide a duration by a divisor.\n *\n * @example\n * ```typescript\n * const half = Duration.divide(Duration.seconds(10), 2)\n * // 5000ms\n * ```\n */\nexport function divide(duration: Duration, divisor: number): Duration {\n return { _tag: \"Duration\", millis: duration.millis / divisor };\n}\n\n// =============================================================================\n// Comparisons\n// =============================================================================\n\n/**\n * Check if duration a is less than duration b.\n */\nexport function lessThan(a: Duration, b: Duration): boolean {\n return a.millis < b.millis;\n}\n\n/**\n * Check if duration a is less than or equal to duration b.\n */\nexport function lessThanOrEqual(a: Duration, b: Duration): boolean {\n return a.millis <= b.millis;\n}\n\n/**\n * Check if duration a is greater than duration b.\n */\nexport function greaterThan(a: Duration, b: Duration): boolean {\n return a.millis > b.millis;\n}\n\n/**\n * Check if duration a is greater than or equal to duration b.\n */\nexport function greaterThanOrEqual(a: Duration, b: Duration): boolean {\n return a.millis >= b.millis;\n}\n\n/**\n * Check if two durations are equal.\n */\nexport function equals(a: Duration, b: Duration): boolean {\n return a.millis === b.millis;\n}\n\n/**\n * Get the minimum of two durations.\n */\nexport function min(a: Duration, b: Duration): Duration {\n return a.millis <= b.millis ? a : b;\n}\n\n/**\n * Get the maximum of two durations.\n */\nexport function max(a: Duration, b: Duration): Duration {\n return a.millis >= b.millis ? a : b;\n}\n\n/**\n * Clamp a duration between a minimum and maximum.\n */\nexport function clamp(duration: Duration, minimum: Duration, maximum: Duration): Duration {\n return min(max(duration, minimum), maximum);\n}\n\n// =============================================================================\n// Predicates\n// =============================================================================\n\n/**\n * Check if a duration is zero.\n */\nexport function isZero(duration: Duration): boolean {\n return duration.millis === 0;\n}\n\n/**\n * Check if a duration is infinite.\n */\nexport function isInfinite(duration: Duration): boolean {\n return duration.millis === Infinity;\n}\n\n/**\n * Check if a duration is finite and positive.\n */\nexport function isFinite(duration: Duration): boolean {\n return Number.isFinite(duration.millis) && duration.millis > 0;\n}\n\n/**\n * Type guard to check if a value is a Duration.\n */\nexport function isDuration(value: unknown): value is Duration {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"_tag\" in value &&\n value._tag === \"Duration\" &&\n \"millis\" in value &&\n typeof value.millis === \"number\"\n );\n}\n\n// =============================================================================\n// Formatting\n// =============================================================================\n\n/**\n * Format a duration as a human-readable string.\n *\n * @example\n * ```typescript\n * Duration.format(Duration.seconds(90)) // \"1m 30s\"\n * Duration.format(Duration.millis(500)) // \"500ms\"\n * ```\n */\nexport function format(duration: Duration): string {\n const ms = duration.millis;\n\n if (ms === Infinity) return \"∞\";\n if (ms === 0) return \"0ms\";\n\n const days = Math.floor(ms / (24 * 60 * 60 * 1000));\n const hours = Math.floor((ms % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000));\n const minutes = Math.floor((ms % (60 * 60 * 1000)) / (60 * 1000));\n const seconds = Math.floor((ms % (60 * 1000)) / 1000);\n const millis = ms % 1000;\n\n const parts: string[] = [];\n if (days > 0) parts.push(`${days}d`);\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n if (seconds > 0) parts.push(`${seconds}s`);\n if (millis > 0 && parts.length === 0) parts.push(`${millis}ms`);\n\n return parts.join(\" \") || \"0ms\";\n}\n\n// =============================================================================\n// Parsing\n// =============================================================================\n\n/**\n * Parse a duration from a string like \"100ms\", \"5s\", \"2m\", \"1h\", \"1d\".\n * Returns undefined if parsing fails.\n *\n * @example\n * ```typescript\n * Duration.parse(\"5s\") // Duration.seconds(5)\n * Duration.parse(\"100ms\") // Duration.millis(100)\n * Duration.parse(\"2m\") // Duration.minutes(2)\n * ```\n */\nexport function parse(input: string): Duration | undefined {\n const match = input.trim().match(/^(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d)$/i);\n if (!match) return undefined;\n\n const value = parseFloat(match[1]);\n const unit = match[2].toLowerCase();\n\n switch (unit) {\n case \"ms\":\n return millis(value);\n case \"s\":\n return seconds(value);\n case \"m\":\n return minutes(value);\n case \"h\":\n return hours(value);\n case \"d\":\n return days(value);\n default:\n return undefined;\n }\n}\n\n// =============================================================================\n// Namespace Export\n// =============================================================================\n\n/**\n * Duration namespace with all functions for convenient access.\n *\n * @example\n * ```typescript\n * import { Duration } from \"awaitly\";\n *\n * const timeout = Duration.seconds(30);\n * const delay = Duration.millis(100);\n * const total = Duration.add(timeout, delay);\n *\n * console.log(Duration.format(total)); // \"30s 100ms\"\n * ```\n */\nexport const Duration = {\n // Constructors\n millis,\n seconds,\n minutes,\n hours,\n days,\n zero,\n infinity,\n\n // Conversions\n toMillis,\n toSeconds,\n toMinutes,\n toHours,\n toDays,\n\n // Operations\n add,\n subtract,\n multiply,\n divide,\n\n // Comparisons\n lessThan,\n lessThanOrEqual,\n greaterThan,\n greaterThanOrEqual,\n equals,\n min,\n max,\n clamp,\n\n // Predicates\n isZero,\n isInfinite,\n isFinite,\n isDuration,\n\n // Formatting\n format,\n parse,\n} as const;\n\nexport type { Duration as DurationType };\n","/**\n * Bound steps for the deps-first forms: run(deps, fn) and workflow({ steps }).\n *\n * Each dep key becomes a step function with the dep's own arguments that\n * unwraps the ok value and early-exits on err. Kept out of core/index.ts\n * so the core stays focused on the run/step engine.\n */\n\nimport { ok, type AsyncResult, type Result } from \"../result\";\n\ntype AnyFunction = (...args: never[]) => unknown;\n\n/**\n * Success value of a dependency's return type. Result-returning deps\n * contribute their `ok` value; plain (non-Result) deps pass through as-is.\n * Shared with the policy wrappers, which normalize the same way.\n */\nexport type DepValueOfReturn<R> = [Extract<Awaited<R>, { ok: true }>] extends [never]\n ? Awaited<R>\n : Extract<Awaited<R>, { ok: true }> extends { value: infer V }\n ? V\n : never;\n\n/**\n * The steps object passed to `run(deps, fn)`: each dep key becomes a step\n * function with the same arguments that resolves to the unwrapped value\n * (early-exiting the run on error).\n *\n * @example\n * ```typescript\n * const result = await run({ getUser, getOrder }, async (s) => {\n * const user = await s.getUser(userId); // User — unwrapped\n * const order = await s.getOrder(user.id); // Order\n * return { user, order };\n * });\n * ```\n */\nexport type BoundSteps<Deps extends Record<string, AnyFunction>> = {\n [K in keyof Deps]: (\n ...args: Parameters<Deps[K]>\n ) => Promise<DepValueOfReturn<ReturnType<Deps[K]>>>;\n};\n\n/**\n * The step-shaped callable bindSteps needs: the classic RunStep instantiated\n * for a single (id, operation) call. Both core run's stepFn and the\n * workflow's cached step satisfy this structurally.\n */\nexport type StepCallable = (\n id: string,\n operation: () => AsyncResult<unknown, unknown, unknown>\n) => Promise<unknown>;\n\n/**\n * Detects a Result-shaped value returned by a dependency. Stricter than\n * core's isResultLike (which also matches thenables to tell Results from\n * functions): requires a boolean `ok` plus the matching payload key, so\n * plain domain objects that happen to have an `ok` field are less likely\n * to be misread as Results.\n */\nexport const isDepResultShaped = (\n value: unknown\n): value is Result<unknown, unknown, unknown> =>\n typeof value === \"object\" &&\n value !== null &&\n \"ok\" in value &&\n typeof (value as { ok: unknown }).ok === \"boolean\" &&\n ((value as { ok: boolean }).ok ? \"value\" in value : \"error\" in value);\n\n/**\n * Builds the bound-steps object for `run(deps, fn)` and workflow parity:\n * each dep key becomes `(...args) => step(key, () => deps[key](...args))`,\n * with plain return values coerced to ok() so non-Result deps work as an\n * on-ramp.\n *\n * Repeat invocations of the same dep within one execution auto-suffix the\n * step key (`getUser`, `getUser#2`, ...). This keeps loop iterations\n * distinct — critical in workflows, where the step key doubles as the\n * cache key and a bare repeat would silently return the first result.\n * Invocation order is deterministic for deterministic code, so suffixed\n * keys stay stable across durable-workflow replays.\n *\n * @internal Used by core run() and the workflow layer; not public API.\n */\nexport const bindSteps = <Deps extends Record<string, AnyFunction>>(\n deps: Deps,\n step: StepCallable\n): BoundSteps<Deps> => {\n const steps: Record<string, (...args: unknown[]) => Promise<unknown>> = {};\n const invocationCounts = new Map<string, number>();\n for (const key of Object.keys(deps)) {\n const dep = deps[key] as unknown as (...args: unknown[]) => unknown;\n // Types say deps are functions, but untyped JS callers may pass\n // metadata alongside them — skip anything that isn't callable.\n if (typeof dep !== \"function\") continue;\n steps[key] = (...args: unknown[]) => {\n const count = (invocationCounts.get(key) ?? 0) + 1;\n invocationCounts.set(key, count);\n const stepKey = count === 1 ? key : `${key}#${count}`;\n // eslint-disable-next-line awaitly/step-require-id -- internal binding: the dep key IS the step ID\n return step(stepKey, async () => {\n const value = await dep(...args);\n return isDepResultShaped(value) ? value : ok(value);\n });\n };\n }\n return steps as BoundSteps<Deps>;\n};\n","/**\n * Per-dependency policies: retry, timeout, fallback.\n *\n * Policies are value-level function wrappers declared where dependencies\n * are declared — in the deps object — so call sites stay pristine and the\n * policy is statically visible in the deps literal (the analyzer reads it\n * as fact, not inference):\n *\n * ```typescript\n * const result = await run(\n * {\n * getUser,\n * charge: retry(timeout(charge, 5000), { attempts: 3 }),\n * sendEmail: fallback(sendEmail, () => ({ queued: true })),\n * },\n * async (s) => {\n * const user = await s.getUser(userId); // call sites unchanged\n * const payment = await s.charge(user.id);\n * return s.sendEmail(user.id);\n * }\n * );\n * ```\n *\n * Every policy returns a Result-returning function with exact error-union\n * math:\n * - `retry(fn, opts)` — same errors as `fn` (the last failure propagates)\n * - `timeout(fn, ms)` — errors of `fn` plus `TimeoutError`\n * - `fallback(fn, fb)` — errors of `fn` are consumed; only `fb`'s errors remain\n *\n * Plain (non-Result) functions are valid inputs: their values are\n * normalized to `ok()`, and their throws keep throwing (so they surface as\n * `UnexpectedError` at the run/workflow layer, same as unwrapped deps).\n */\n\nimport { err, ok, type AsyncResult, type Err, type ErrorOf } from \"../result\";\nimport { TimeoutError, UnexpectedError } from \"../errors\";\nimport { type Duration, toMillis } from \"../duration\";\nimport { isDepResultShaped, type DepValueOfReturn } from \"./bound-steps\";\n\ntype AnyFunction = (...args: never[]) => unknown;\n\n/** Milliseconds or a Duration value. */\nexport type PolicyDelay = number | Duration;\n\nconst toMs = (d: PolicyDelay): number => (typeof d === \"number\" ? d : toMillis(d));\n\n/** The unwrapped success value a policy resolves to for a given function. */\ntype PolicyValue<F extends AnyFunction> = DepValueOfReturn<ReturnType<F>>;\n\n/** A function wrapped by a policy: same arguments, Result-returning. */\nexport type PolicyFn<F extends AnyFunction, E> = (\n ...args: Parameters<F>\n) => AsyncResult<PolicyValue<F>, E>;\n\n/** One observed call outcome, with Result errs kept intact (cause included). */\ntype Attempt =\n | { kind: \"ok\"; value: unknown }\n | { kind: \"err\"; error: unknown; result: Err<unknown, unknown> }\n | { kind: \"threw\"; thrown: unknown };\n\nconst attemptCall = async (fn: AnyFunction, args: readonly unknown[]): Promise<Attempt> => {\n try {\n const value = await (fn as unknown as (...a: unknown[]) => unknown)(...args);\n if (isDepResultShaped(value)) {\n return value.ok\n ? { kind: \"ok\", value: value.value }\n : { kind: \"err\", error: value.error, result: value };\n }\n return { kind: \"ok\", value };\n } catch (thrown) {\n return { kind: \"threw\", thrown };\n }\n};\n\n/** Preserve the wrapped function's name so events, diagrams, and stack traces stay readable. */\nconst named = <T extends (...args: never[]) => unknown>(wrapped: T, source: AnyFunction): T => {\n const name = source.name;\n if (name) {\n Object.defineProperty(wrapped, \"name\", { value: name, configurable: true });\n }\n return wrapped;\n};\n\nconst sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\n// =============================================================================\n// retry\n// =============================================================================\n\nexport interface RetryPolicyOptions {\n /** Total attempts including the first call (minimum 1). */\n attempts: number;\n /** Base delay between attempts. Default: no delay. */\n delay?: PolicyDelay;\n /** How the delay grows per attempt. Default: \"fixed\". */\n backoff?: \"fixed\" | \"linear\" | \"exponential\";\n /** Upper bound for the computed delay. */\n maxDelay?: PolicyDelay;\n /**\n * Decide whether a failure is retryable. Receives the Result error, or\n * the thrown value for plain functions. Default: retry everything.\n */\n retryIf?: (failure: unknown) => boolean;\n /** Observer invoked before each re-attempt. */\n onRetry?: (info: { attempt: number; failure: unknown }) => void;\n}\n\n/**\n * Retry a dependency. The error union is unchanged: if all attempts fail,\n * the last failure propagates exactly as it would have without the policy\n * (typed err for Result functions, throw for plain functions).\n */\nexport function retry<F extends AnyFunction>(\n fn: F,\n options: RetryPolicyOptions\n): PolicyFn<F, ErrorOf<F>> {\n const attempts = Math.max(1, Math.trunc(options.attempts));\n const baseDelay = options.delay === undefined ? 0 : toMs(options.delay);\n const maxDelay = options.maxDelay === undefined ? Infinity : toMs(options.maxDelay);\n const backoff = options.backoff ?? \"fixed\";\n\n const delayFor = (attempt: number): number => {\n const raw =\n backoff === \"exponential\"\n ? baseDelay * 2 ** (attempt - 1)\n : backoff === \"linear\"\n ? baseDelay * attempt\n : baseDelay;\n return Math.min(raw, maxDelay);\n };\n\n const wrapped = async (...args: Parameters<F>) => {\n let last: Attempt = { kind: \"threw\", thrown: undefined };\n for (let attempt = 1; attempt <= attempts; attempt++) {\n last = await attemptCall(fn, args);\n if (last.kind === \"ok\") return ok(last.value);\n const failure = last.kind === \"err\" ? last.error : last.thrown;\n if (options.retryIf && !options.retryIf(failure)) break;\n if (attempt < attempts) {\n options.onRetry?.({ attempt, failure });\n const ms = delayFor(attempt);\n if (ms > 0) await sleep(ms);\n }\n }\n if (last.kind === \"err\") return last.result;\n throw last.thrown;\n };\n\n return named(wrapped, fn) as PolicyFn<F, ErrorOf<F>>;\n}\n\n// =============================================================================\n// timeout\n// =============================================================================\n\n/**\n * Bound a dependency's execution time. On timeout, resolves to\n * `err(TimeoutError)` — adding `TimeoutError` to the error union. The\n * underlying operation is not cancelled (no AbortSignal is threaded);\n * its eventual result is discarded.\n */\nexport function timeout<F extends AnyFunction>(\n fn: F,\n after: PolicyDelay\n): PolicyFn<F, ErrorOf<F> | TimeoutError> {\n const ms = toMs(after);\n const TIMED_OUT = Symbol(\"timed-out\");\n\n const wrapped = async (...args: Parameters<F>) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n const outcome = await Promise.race([\n attemptCall(fn, args),\n new Promise<typeof TIMED_OUT>((resolve) => {\n timer = setTimeout(() => resolve(TIMED_OUT), ms);\n }),\n ]);\n if (outcome === TIMED_OUT) {\n return err(new TimeoutError({ operation: fn.name || undefined, ms }));\n }\n if (outcome.kind === \"ok\") return ok(outcome.value);\n if (outcome.kind === \"err\") return outcome.result;\n throw outcome.thrown;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n };\n\n return named(wrapped, fn) as PolicyFn<F, ErrorOf<F> | TimeoutError>;\n}\n\n// =============================================================================\n// fallback\n// =============================================================================\n\n/**\n * Recover from a dependency's failure. The handler receives the failure\n * (the typed Result error, or `UnexpectedError` wrapping a throw) plus the\n * original arguments, and its result becomes the outcome. The base\n * function's errors are consumed; only the handler's errors remain in the\n * union — `fallback(fn, () => defaultValue)` has no typed errors at all.\n */\nexport function fallback<\n F extends AnyFunction,\n FB extends (failure: ErrorOf<F> | UnexpectedError, ...args: Parameters<F>) => unknown,\n>(\n fn: F,\n onFailure: FB\n): (\n ...args: Parameters<F>\n) => AsyncResult<PolicyValue<F> | DepValueOfReturn<ReturnType<FB>>, ErrorOf<FB>> {\n const wrapped = async (...args: Parameters<F>) => {\n const outcome = await attemptCall(fn, args);\n if (outcome.kind === \"ok\") return ok(outcome.value);\n\n const failure =\n outcome.kind === \"err\" ? outcome.error : new UnexpectedError({ cause: outcome.thrown });\n const recovered = await attemptCall(onFailure, [failure, ...args]);\n if (recovered.kind === \"ok\") return ok(recovered.value);\n if (recovered.kind === \"err\") return recovered.result;\n throw recovered.thrown;\n };\n\n return named(wrapped, fn) as (\n ...args: Parameters<F>\n ) => AsyncResult<PolicyValue<F> | DepValueOfReturn<ReturnType<FB>>, ErrorOf<FB>>;\n}\n","/**\n * Core module (internal): Result primitives and the run() function.\n *\n * Surfaced through the root `awaitly` entry (formerly `awaitly/core`).\n * Use this module for minimal bundle size when you don't need the full workflow capabilities\n * (like retries, timeout, or state persistence) provided by `createWorkflow`.\n *\n * This module provides:\n * 1. `Result` types for error handling without try/catch\n * 2. `run()` function for executing steps with standardized error management\n * 3. Utilities for transforming and combining Results\n */\n\n// Inline duration type and parser to avoid importing the full duration module\n// This keeps the core bundle minimal (~1KB saved)\n\n/** Duration object with tagged type for type safety */\ntype DurationObject = { readonly _tag: \"Duration\"; readonly millis: number };\n\n/** Duration input: either a string (\"5s\", \"100ms\") or a Duration object */\ntype DurationInput = string | DurationObject;\n\n/** Parse a duration string like \"100ms\", \"5s\", \"2m\", \"1h\", \"1d\" */\nfunction parseDurationString(input: string): DurationObject | undefined {\n const match = input.trim().match(/^(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d)$/i);\n if (!match) return undefined;\n const value = parseFloat(match[1]);\n const unit = match[2].toLowerCase();\n const multipliers: Record<string, number> = { ms: 1, s: 1000, m: 60000, h: 3600000, d: 86400000 };\n return { _tag: \"Duration\", millis: value * (multipliers[unit] ?? 1) };\n}\n\n// =============================================================================\n// Core Result Types\n// =============================================================================\n\n/**\n * Represents a successful result.\n * Use `ok(value)` to create instances.\n *\n * @template T - The type of the success value\n *\n * @example\n * ```typescript\n * const success = ok(42);\n * // Type shown: Ok<number>\n * ```\n */\nexport type Ok<T> = {\n ok: true;\n value: T;\n};\n\n/**\n * Represents a failed result.\n * Use `err(error)` to create instances.\n *\n * @template E - The type of the error value\n * @template C - The type of the cause (defaults to unknown)\n * @template T - Phantom type for the success value (preserved after narrowing)\n *\n * @example\n * ```typescript\n * const failure = err({ type: \"NOT_FOUND\", message: \"User not found\" });\n * // Type shown: Err<{ type: string; message: string }>\n * ```\n */\nexport type Err<E, C = unknown> = {\n ok: false;\n error: E;\n cause?: C;\n};\n\n/**\n * Represents a successful computation or a failed one.\n * Use this type to represent the outcome of an operation that might fail,\n * instead of throwing exceptions.\n *\n * @template T - The type of the success value\n * @template E - The type of the error value (defaults to unknown)\n * @template C - The type of the cause (defaults to unknown)\n */\nexport type Result<T, E = unknown, C = unknown> = Ok<T> | Err<E, C>;\n\n/**\n * A Promise that resolves to a Result.\n * Use this for asynchronous operations that might fail.\n */\nexport type AsyncResult<T, E = unknown, C = unknown> = Promise<Result<T, E, C>>;\n\n/** Discriminant for PromiseRejectedError type - use in switch statements */\nexport const PROMISE_REJECTED = \"PROMISE_REJECTED\" as const;\n\n// =============================================================================\n// Named Error Constants (for static analysis)\n// =============================================================================\n\n/**\n * Named error constant for unexpected/unhandled errors.\n * Used by the analyzer when a step doesn't declare errors.\n */\nexport const AWAITLY_UNEXPECTED = \"AWAITLY_UNEXPECTED\" as const;\n\n/**\n * Named error constant for cancelled operations.\n */\nexport const AWAITLY_CANCELLED = \"AWAITLY_CANCELLED\" as const;\n\n/**\n * Named error constant for timed-out operations.\n */\nexport const AWAITLY_TIMEOUT = \"AWAITLY_TIMEOUT\" as const;\n\n// =============================================================================\n// Static Analysis Helpers\n// =============================================================================\n\n/**\n * Helper to create a tuple of string literal tags with preserved literal types.\n * Use this when you need to store error tags in a variable while keeping\n * TypeScript's literal type inference (avoiding widening to string[]).\n *\n * @param t - The string literal tags\n * @returns The same array with preserved literal types\n *\n * @example\n * ```typescript\n * // Without tags() - type widens to string[]\n * const errs = ['CART_NOT_FOUND', 'CART_EMPTY']; // string[]\n *\n * // With tags() - literal types preserved\n * const errs = tags('CART_NOT_FOUND', 'CART_EMPTY'); // ['CART_NOT_FOUND', 'CART_EMPTY']\n *\n * await step('getCart', () => getCart(id), {\n * errors: errs, // Analyzer can extract literal types\n * out: 'cart',\n * });\n * ```\n */\nexport const tags = <const T extends readonly string[]>(...t: T): T => t;\n\nimport { UnexpectedError } from \"../errors\";\nimport { bindSteps, type BoundSteps, type StepCallable } from \"./bound-steps\";\n\nexport { bindSteps, type BoundSteps } from \"./bound-steps\";\nexport {\n retry,\n timeout,\n fallback,\n type RetryPolicyOptions,\n type PolicyFn,\n type PolicyDelay,\n} from \"./policies\";\nexport { UnexpectedError };\n\n/**\n * Default mapper for unexpected causes (uncaught exceptions, cancellation, etc.).\n * Returns an UnexpectedError TaggedError instance.\n * Used when run() is called without catchUnexpected.\n *\n * @param cause - The thrown value\n * @returns An UnexpectedError instance\n */\nexport function defaultCatchUnexpected(cause: unknown): UnexpectedError {\n return new UnexpectedError({ cause });\n}\n\nexport type PromiseRejectedError = { type: typeof PROMISE_REJECTED; cause: unknown };\n/** Cause type for promise rejections in async batch helpers */\nexport type PromiseRejectionCause = { type: \"PROMISE_REJECTION\"; reason: unknown };\nexport type EmptyInputError = { type: \"EMPTY_INPUT\"; message: string };\nexport type MaybeAsyncResult<T, E, C = unknown> = Result<T, E, C> | Promise<Result<T, E, C>>;\n\n// =============================================================================\n// Result Constructors\n// =============================================================================\n\n/**\n * Creates a successful Result.\n * Use this when an operation completes successfully.\n *\n * @remarks When to use: Wrap a successful value in a Result for consistent return types.\n *\n * @param value - The success value to wrap\n * @returns An Ok object with `{ ok: true, value }`\n *\n * @example\n * ```typescript\n * const success = ok(42);\n * // Type: Ok<number>\n *\n * function divide(a: number, b: number): Result<number, string> {\n * if (b === 0) return err(\"Division by zero\");\n * return ok(a / b);\n * }\n * ```\n */\nexport function ok<T>(value: T): Ok<T> {\n return { ok: true as const, value };\n}\n\n/**\n * Creates a failed Result.\n * Use this when an operation fails.\n *\n * @remarks When to use: Return a typed failure without throwing so callers can handle it explicitly.\n *\n * @param error - The error value describing what went wrong (e.g., error code, object)\n * @returns An Err object with `{ ok: false, error }`\n *\n * @example\n * ```typescript\n * // Simple error\n * const r1 = err(\"NOT_FOUND\");\n * // Type: Err<\"NOT_FOUND\">\n *\n * // Error with context (include in error object)\n * const r2 = err({ type: \"PROCESSING_FAILED\", cause: originalError });\n * // Type: Err<{ type: string; cause: Error }>\n * ```\n */\nexport function err<E, C = unknown>(error: E, options?: { cause?: C }): Err<E, C> {\n const cause = options?.cause;\n return { ok: false as const, error, ...(cause !== undefined ? { cause } : {}) } as Err<E, C>;\n}\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Checks if a Result is successful.\n * Use this to narrow the type of a Result to the success case.\n *\n * @remarks When to use: Prefer functional-style checks or array filtering over `result.ok`.\n *\n * @param r - The Result to check\n * @returns `true` if successful, allowing access to `r.value`\n *\n * @example\n * ```typescript\n * const r = someOperation();\n * if (isOk(r)) {\n * // Use r.value (Type is T)\n * processValue(r.value);\n * } else {\n * // Handle r.error (Type is E)\n * handleError(r.error);\n * }\n * ```\n */\nexport const isOk = <T, E, C>(r: Result<T, E, C>): r is Ok<T> => r.ok;\n\n/**\n * Checks if a Result is a failure.\n * Use this to narrow the type of a Result to the error case.\n *\n * @remarks When to use: Prefer functional-style checks or array filtering over `result.ok`.\n *\n * @param r - The Result to check\n * @returns `true` if failed, allowing access to `r.error` and `r.cause`\n *\n * @example\n * ```typescript\n * if (isErr(r)) {\n * // Handle error case early\n * return;\n * }\n * // Proceed with success case\n * ```\n */\nexport const isErr = <T, E, C>(r: Result<T, E, C>): r is Err<E, C> => !r.ok;\n\n/**\n * Checks if an error is an UnexpectedError.\n * Used internally by the framework but exported for advanced custom handling.\n * Indicates an error that wasn't typed/expected in the `run` signature.\n *\n * @remarks When to use: Distinguish unexpected failures from your typed error union.\n */\nexport const isUnexpectedError = (e: unknown): e is UnexpectedError =>\n e instanceof UnexpectedError ||\n (typeof e === \"object\" &&\n e !== null &&\n \"_tag\" in e &&\n (e as { _tag: string })._tag === \"UnexpectedError\");\n\n/**\n * Checks if an error is a PromiseRejectedError.\n * Occurs when a Promise rejects in batch operations (allAsync, anyAsync, zipAsync).\n *\n * @example\n * ```typescript\n * onError: (error): FetchError => {\n * if (isPromiseRejectedError(error)) return 'FETCH_FAILED';\n * return error; // TypeScript narrows to FetchError\n * }\n * ```\n */\nexport const isPromiseRejectedError = (e: unknown): e is PromiseRejectedError =>\n typeof e === \"object\" &&\n e !== null &&\n (e as PromiseRejectedError).type === PROMISE_REJECTED;\n\n// =============================================================================\n// Error Matching\n// =============================================================================\n\n/**\n * Type for exhaustive error handlers mapping string literal errors and UnexpectedError.\n * Each key in E gets a handler, plus UnexpectedError is required.\n */\nexport type MatchErrorHandlers<E extends string, R> = {\n [K in Exclude<E, \"UnexpectedError\">]: (error: K) => R;\n} & {\n UnexpectedError: (error: UnexpectedError) => R;\n};\n\n/**\n * Exhaustive pattern matching for error types.\n * Handles both string literal errors and UnexpectedError, ensuring all cases are covered.\n *\n * @param error - The error to match (string literal or UnexpectedError)\n * @param handlers - Object with a handler for each error case plus UnexpectedError\n * @returns The result of the matched handler\n *\n * @example\n * ```typescript\n * type FetchError = \"NOT_FOUND\" | \"FETCH_ERROR\";\n * const result: Result<User, FetchError | UnexpectedError> = await fetchUser();\n *\n * if (!result.ok) {\n * return matchError(result.error, {\n * NOT_FOUND: () => 404,\n * FETCH_ERROR: () => 500,\n * UnexpectedError: (e) => { throw e.cause; }\n * });\n * }\n * ```\n */\nexport function matchError<E extends string, R>(\n handlers: MatchErrorHandlers<E, R>\n): (error: E | UnexpectedError) => R;\nexport function matchError<E extends string, R>(\n error: E | UnexpectedError,\n handlers: MatchErrorHandlers<E, R>\n): R;\nexport function matchError<E extends string, R>(\n errorOrHandlers: E | UnexpectedError | MatchErrorHandlers<E, R>,\n handlers?: MatchErrorHandlers<E, R>\n): R | ((error: E | UnexpectedError) => R) {\n if (handlers === undefined) {\n const h = errorOrHandlers as MatchErrorHandlers<E, R>;\n return (e: E | UnexpectedError) => matchError(e, h);\n }\n const error = errorOrHandlers as E | UnexpectedError;\n // Handle UnexpectedError instances\n if (isUnexpectedError(error)) {\n return handlers.UnexpectedError(error as UnexpectedError);\n }\n // Handle string literal errors\n type StringErrors = Exclude<E, \"UnexpectedError\">;\n return handlers[error as StringErrors](error as StringErrors);\n}\n\n// =============================================================================\n// Type Utilities\n// =============================================================================\n\ntype AnyFunction = (...args: never[]) => unknown;\n\n/**\n * Helper to extract the error type from Result or AsyncResult return values.\n * Works even when a function is declared to return a union of both forms.\n * Plain (non-Result) return types contribute `never` — without the [never]\n * guard they would infer `unknown` and poison error unions built from\n * mixed deps.\n */\ntype ErrorOfReturn<R> = [Extract<Awaited<R>, { ok: false }>] extends [never]\n ? never\n : Extract<Awaited<R>, { ok: false }> extends { error: infer E }\n ? E\n : never;\n\n/**\n * Extract error type from a single function's return type\n */\nexport type ErrorOf<T extends AnyFunction> = ErrorOfReturn<ReturnType<T>>;\n\n/**\n * Extract union of error types from multiple functions (tuple form)\n */\nexport type Errors<T extends AnyFunction[]> = {\n [K in keyof T]: ErrorOf<T[K]>;\n}[number];\n\n/**\n * Extract union of error types from a deps object.\n *\n * @example\n * ```typescript\n * const deps = { getUser, createOrder, sendEmail };\n * type E = ErrorsOf<typeof deps>;\n * // = \"NOT_FOUND\" | \"ORDER_FAILED\" | \"EMAIL_ERROR\"\n * ```\n */\nexport type ErrorsOf<Deps extends Record<string, AnyFunction>> = {\n [K in keyof Deps]: ErrorOf<Deps[K]>;\n}[keyof Deps];\n\n/**\n * Extract value type from Result\n */\nexport type ExtractValue<T> = T extends { ok: true; value: infer U }\n ? U\n : never;\n\n/**\n * Extract error type from Result\n */\nexport type ExtractError<T> = T extends { ok: false; error: infer E }\n ? E\n : never;\n\n/**\n * Extract cause type from Result\n */\nexport type ExtractCause<T> = T extends { ok: false; cause?: infer C }\n ? C\n : never;\n\n/**\n * Helper to extract the cause type from Result or AsyncResult return values.\n * Works even when a function is declared to return a union of both forms.\n */\ntype CauseOfReturn<R> = Extract<Awaited<R>, { ok: false }> extends { cause?: infer C }\n ? C\n : never;\n\n/**\n * Extract cause type from a function's return type\n */\nexport type CauseOf<T extends AnyFunction> = CauseOfReturn<ReturnType<T>>;\n\n// =============================================================================\n// Step Options\n// =============================================================================\n\n/**\n * Options for configuring a step within a workflow.\n * Use these to enable tracing, caching, state persistence, and static analysis.\n */\nexport type StepOptions<\n Errs extends readonly string[] = readonly string[],\n Out extends string | undefined = undefined,\n> = {\n /**\n * Stable identity key for the step.\n * REQUIRED for:\n * 1. Caching: Used as the cache key.\n * 2. Resuming: Used to identify which steps have already completed.\n *\n * Must be unique within the workflow.\n */\n key?: string;\n\n /**\n * Short description for labels/tooltips.\n * Used by static analysis visualization tools.\n */\n description?: string;\n\n /**\n * Full markdown documentation for the step.\n * Used by static analysis visualization tools.\n */\n markdown?: string;\n\n /**\n * Retry configuration for transient failures.\n * When specified, the step will retry on errors according to this config.\n */\n retry?: RetryOptions;\n\n /**\n * Timeout configuration for the operation.\n * When specified, each attempt will be aborted after the timeout duration.\n */\n timeout?: TimeoutOptions;\n\n /**\n * Time-to-live for this step's cache entry in milliseconds.\n * Overrides any global cache TTL. Requires `key` for caching.\n */\n ttl?: number;\n\n // ==========================================================================\n // Static Analysis Options\n // ==========================================================================\n\n /**\n * Declared tagged errors this step may return.\n * Used by the static analyzer to build error flow graphs.\n *\n * Use `tags()` helper when storing in a variable:\n * @example\n * ```typescript\n * const cartErrors = tags('CART_NOT_FOUND', 'CART_EMPTY');\n * await step('getCart', () => getCart(id), { errors: cartErrors });\n *\n * // Or inline (no helper needed)\n * await step('getCart', () => getCart(id), {\n * errors: ['CART_NOT_FOUND', 'CART_EMPTY'],\n * });\n * ```\n */\n errors?: Errs;\n\n /**\n * Write the step's return value to this context key.\n * Replaces manual `ctx.set()` calls for the happy path.\n *\n * @example\n * ```typescript\n * await step('getCart', () => getCart(id), { out: 'cart' });\n * // Now ctx.cart contains the result\n * ```\n */\n out?: Out;\n\n /**\n * Override auto-detected reads from context.\n * Use when the analyzer can't trace complex data dependencies.\n *\n * @example\n * ```typescript\n * await step('charge', () => chargeCard(getCartTotal()), {\n * reads: ['cart'], // Explicitly declare dependency\n * });\n * ```\n */\n reads?: readonly string[];\n\n /**\n * Hint for dependency source tracking.\n * Use when the callback is complex and the analyzer can't detect\n * which dependency function is being called.\n *\n * @example\n * ```typescript\n * await step('getCart', () => {\n * const id = transform(ctx.input.cartId);\n * return deps.getCart(id);\n * }, {\n * dep: 'getCart', // Hint for analyzer\n * });\n * ```\n */\n dep?: string;\n\n // ==========================================================================\n // Agent Metadata — Architecture & Intent\n // ==========================================================================\n\n /**\n * Why this step exists in the business flow.\n * Unlike `description` (which says *what* the step does), `intent` explains\n * the business reason it exists in the workflow.\n *\n * @example\n * ```typescript\n * await step('validateCart', () => validate(cart), {\n * description: 'Validates cart contents and pricing',\n * intent: 'Prevent charging customers for out-of-stock items',\n * });\n * ```\n */\n intent?: string;\n\n /**\n * Business domain this step belongs to.\n * Used by the static analyzer to group steps by bounded context.\n *\n * @example\n * ```typescript\n * await step('chargeCard', () => charge(card, amount), {\n * domain: 'payments',\n * });\n * ```\n */\n domain?: string;\n\n /**\n * Team, service, or bounded-context that owns this step.\n *\n * @example\n * ```typescript\n * await step('shipOrder', () => ship(order), {\n * owner: 'fulfillment-team',\n * });\n * ```\n */\n owner?: string;\n\n /**\n * Classification tags for this step.\n *\n * Recommended vocabulary:\n * `'side-effect'`, `'external-api'`, `'idempotent'`, `'read-only'`,\n * `'cacheable'`, `'pii'`, `'pci'`, `'compensatable'`\n *\n * @example\n * ```typescript\n * await step('chargeCard', () => charge(card, amount), {\n * tags: ['side-effect', 'external-api', 'pci'],\n * });\n * ```\n */\n tags?: readonly string[];\n\n // ==========================================================================\n // Agent Metadata — Effects & Dependencies\n // ==========================================================================\n\n /**\n * Human-oriented descriptions of state mutations this step performs.\n * These are free-text labels for documentation and visualization — they are\n * not machine-parsed at runtime.\n *\n * A future `stateEffects` field will provide structured effect declarations.\n *\n * @example\n * ```typescript\n * await step('placeOrder', () => place(cart), {\n * stateChanges: ['order.status → PLACED', 'inventory.reserved += qty'],\n * });\n * ```\n */\n stateChanges?: readonly string[];\n\n /**\n * Domain events this step produces.\n * Used by the static analyzer to build event flow graphs.\n *\n * @example\n * ```typescript\n * await step('placeOrder', () => place(cart), {\n * emits: ['OrderPlaced', 'InventoryReserved'],\n * });\n * ```\n */\n emits?: readonly string[];\n\n /**\n * External systems or services this step calls.\n * Used by the static analyzer to map external dependencies.\n *\n * @example\n * ```typescript\n * await step('chargeCard', () => charge(card, amount), {\n * calls: ['stripe-api', 'fraud-detection-service'],\n * });\n * ```\n */\n calls?: readonly string[];\n\n // ==========================================================================\n // Agent Metadata — Error Classification\n // ==========================================================================\n\n /**\n * Structured metadata for each error this step may produce.\n * Keys should match entries in the `errors` array.\n *\n * Note: `retryable` classifies the error's nature (whether it CAN be retried),\n * separate from whether this step actually retries it (that's `retry.shouldRetry`).\n * Both dimensions are useful — \"this error IS retryable\" vs \"this step DOES retry it\".\n * Defaults to `undefined` (unknown), not `true`.\n *\n * @example\n * ```typescript\n * await step('chargeCard', () => charge(card, amount), {\n * errors: ['CARD_DECLINED', 'GATEWAY_TIMEOUT'],\n * errorMeta: {\n * CARD_DECLINED: {\n * retryable: false,\n * severity: 'business',\n * description: 'Card was declined by issuer',\n * },\n * GATEWAY_TIMEOUT: {\n * retryable: true,\n * severity: 'infrastructure',\n * description: 'Payment gateway did not respond in time',\n * },\n * },\n * });\n * ```\n */\n errorMeta?: Record<string, ErrorClassification>;\n\n /**\n * Compensation action to run if a later step fails.\n *\n * When set, the step's return value is captured. If the workflow later fails\n * (any step error, or the user callback throws), every step that recorded a\n * compensation runs its `compensate` callback in reverse order.\n *\n * If a compensation throws, errors are collected. When at least one fails,\n * the workflow result becomes a `SagaCompensationError` containing the\n * original error and all compensation failures.\n *\n * @example\n * ```typescript\n * const reservation = await step('reserve', () => deps.reserve(items), {\n * compensate: (r) => deps.release(r.id),\n * });\n * ```\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n compensate?: (value: any) => void | Promise<void>;\n};\n\n/** Shared error classification — used in StepOptions.errorMeta, diagnostics, and wide events. */\nexport interface ErrorClassification {\n retryable?: boolean;\n severity?: 'business' | 'infrastructure' | 'validation';\n description?: string;\n}\n\n/** Runtime-visible business context from StepOptions. Does NOT include errorMeta. */\nexport interface StepMetadata {\n intent?: string;\n domain?: string;\n owner?: string;\n tags?: readonly string[];\n stateChanges?: readonly string[];\n emits?: readonly string[];\n calls?: readonly string[];\n}\n\n/** Runtime error diagnostics. classification is the matched ErrorClassification for this error. */\nexport interface StepErrorDiagnostics {\n tag: string;\n classification?: ErrorClassification;\n attempt?: number; // 1-based\n cumulativeDurationMs?: number; // execution only, excludes backoff\n origin: 'result' | 'throw' | 'timeout';\n}\n\n/** Extract canonical error tag. Priority: _tag > tag > code > Error.name > \"unknown\".\n * Tags are case-sensitive, whitespace-trimmed, otherwise raw.\n * Note: Error.name is fallback-grade (often too coarse like \"Error\", \"TypeError\"). */\nexport function extractErrorTag(error: unknown): string {\n if (error == null) return 'unknown';\n\n if (typeof error === 'string') return error.trim() || 'unknown';\n\n if (typeof error === 'object') {\n // Priority 1: _tag (TaggedError pattern)\n const tagged = error as Record<string, unknown>;\n if (typeof tagged._tag === 'string') {\n const trimmed = tagged._tag.trim();\n if (trimmed) return trimmed;\n }\n // Priority 2: tag\n if (typeof tagged.tag === 'string') {\n const trimmed = tagged.tag.trim();\n if (trimmed) return trimmed;\n }\n // Priority 3: code — string used directly, number stringified, anything else skipped\n if (typeof tagged.code === 'string') {\n const trimmed = tagged.code.trim();\n if (trimmed) return trimmed;\n } else if (typeof tagged.code === 'number') {\n return String(tagged.code);\n }\n // Priority 4: Error.name (fallback-grade)\n if (error instanceof Error && error.name) {\n const trimmed = error.name.trim();\n if (trimmed) return trimmed;\n }\n }\n\n return 'unknown';\n}\n\n/** Look up ErrorClassification from errorMeta for a given tag. */\nexport function lookupErrorClassification(\n tag: string,\n errorMeta?: Record<string, ErrorClassification>,\n): ErrorClassification | undefined {\n if (!errorMeta || !tag) return undefined;\n return errorMeta[tag];\n}\n\n/** Extract StepMetadata from StepOptions (returns undefined when empty). */\nexport function extractStepMetadata(options: StepOptions): StepMetadata | undefined {\n const { intent, domain, owner, tags, stateChanges, emits, calls } = options;\n if (!intent && !domain && !owner && !tags?.length && !stateChanges?.length && !emits?.length && !calls?.length) {\n return undefined;\n }\n const metadata: StepMetadata = {};\n if (intent) metadata.intent = intent;\n if (domain) metadata.domain = domain;\n if (owner) metadata.owner = owner;\n if (tags?.length) metadata.tags = tags;\n if (stateChanges?.length) metadata.stateChanges = stateChanges;\n if (emits?.length) metadata.emits = emits;\n if (calls?.length) metadata.calls = calls;\n return metadata;\n}\n\n/** Build StepErrorDiagnostics from error + errorMeta. */\nfunction buildStepErrorPayload(\n error: unknown,\n errorMeta: StepOptions['errorMeta'],\n origin: StepErrorDiagnostics['origin'],\n attempt?: number,\n cumulativeDurationMs?: number,\n): StepErrorDiagnostics {\n const tag = extractErrorTag(error);\n const classification = lookupErrorClassification(tag, errorMeta);\n const diagnostics: StepErrorDiagnostics = { tag, origin };\n if (classification !== undefined) diagnostics.classification = classification;\n if (attempt !== undefined) diagnostics.attempt = attempt;\n if (cumulativeDurationMs !== undefined) diagnostics.cumulativeDurationMs = cumulativeDurationMs;\n return diagnostics;\n}\n\n// =============================================================================\n// Retry and Timeout Types\n// =============================================================================\n\n/**\n * Backoff strategy for retry operations.\n */\nexport type BackoffStrategy = \"fixed\" | \"linear\" | \"exponential\";\n\n/**\n * Configuration for step retry behavior.\n */\nexport type RetryOptions<E = unknown> = {\n /**\n * Total number of attempts (1 = no retry, 3 = initial + 2 retries).\n * Must be >= 1.\n */\n attempts: number;\n\n /**\n * Backoff strategy between retries.\n * - 'fixed': Same delay each time (initialDelay)\n * - 'linear': Delay increases linearly (initialDelay * attempt)\n * - 'exponential': Delay doubles each time (initialDelay * 2^(attempt-1))\n * @default 'exponential'\n */\n backoff?: BackoffStrategy;\n\n /**\n * Initial delay in milliseconds before first retry.\n * @default 100\n */\n initialDelay?: number;\n\n /**\n * Maximum delay cap in milliseconds.\n * Prevents exponential backoff from growing too large.\n * @default 30000 (30 seconds)\n */\n maxDelay?: number;\n\n /**\n * Whether to add random jitter (0-25% of delay).\n * Helps prevent thundering herd when multiple workflows retry simultaneously.\n * @default true\n */\n jitter?: boolean;\n\n /**\n * Predicate to determine if a retry should occur.\n * Receives the error and current attempt number (1-indexed).\n * Return true to retry, false to fail immediately.\n * @default Always retry on any error\n */\n shouldRetry?: (error: E, attempt: number) => boolean;\n\n /**\n * Callback invoked before each retry attempt.\n * Useful for logging, metrics, or side effects.\n */\n onRetry?: (error: E, attempt: number, delayMs: number) => void;\n};\n\n/**\n * Timeout behavior when the timeout is reached.\n *\n * - 'error' (default): Return an error result with StepTimeoutError\n * - 'option': Return Ok(undefined) instead of an error (useful for optional operations)\n * - 'disconnect': Let the operation complete in background, return timeout error immediately\n * - function: Custom handler to generate the timeout error\n */\nexport type TimeoutBehavior =\n | \"error\"\n | \"option\"\n | \"disconnect\"\n | ((stepInfo: { name?: string; key?: string; ms: number }) => unknown);\n\n/**\n * Configuration for step timeout behavior.\n */\nexport type TimeoutOptions = {\n /**\n * Timeout duration in milliseconds per attempt.\n * When combined with retry, each attempt gets its own timeout.\n */\n ms: number;\n\n /**\n * Custom error to use when timeout occurs.\n * @default StepTimeoutError with step details\n */\n error?: unknown;\n\n /**\n * Whether to pass an AbortSignal to the operation.\n * When true, the operation function receives (signal: AbortSignal) as argument.\n * Useful for fetch() and other APIs that support cancellation.\n * @default false\n */\n signal?: boolean;\n\n /**\n * Behavior when timeout is reached.\n *\n * - 'error' (default): Return StepTimeoutError (or custom error if provided)\n * - 'option': Return Ok(undefined) instead of error (operation treated as optional)\n * - 'disconnect': Let operation complete in background, return error immediately\n * - function: Custom handler `(stepInfo) => customError`\n *\n * @default 'error'\n *\n * @example\n * ```typescript\n * // Default: Return timeout error\n * step.withTimeout(() => slowOp(), { ms: 5000 });\n *\n * // Optional: Return undefined if times out\n * step.withTimeout(() => optionalOp(), { ms: 5000, onTimeout: 'option' });\n *\n * // Disconnect: Don't wait for slow operation\n * step.withTimeout(() => fireAndForget(), { ms: 5000, onTimeout: 'disconnect' });\n *\n * // Custom error\n * step.withTimeout(() => apiCall(), {\n * ms: 5000,\n * onTimeout: ({ name, ms }) => ({ type: 'API_TIMEOUT', name, ms })\n * });\n * ```\n */\n onTimeout?: TimeoutBehavior;\n};\n\n/**\n * Standard timeout error type.\n */\nexport type StepTimeoutError = {\n type: \"STEP_TIMEOUT\";\n stepName?: string;\n stepKey?: string;\n timeoutMs: number;\n attempt?: number;\n};\n\n/**\n * Symbol used to mark any error (including custom errors) as a timeout error.\n * This allows detection of timeout errors even when users provide custom error payloads.\n */\nexport const STEP_TIMEOUT_MARKER: unique symbol = Symbol.for(\"step_timeout_marker\");\n\n/**\n * Metadata attached to timeout-marked errors.\n */\nexport type StepTimeoutMarkerMeta = {\n timeoutMs: number;\n stepName?: string;\n stepKey?: string;\n attempt?: number;\n};\n\n/**\n * Type guard to check if an error is a StepTimeoutError.\n * This checks both the standard type field AND the timeout marker symbol,\n * so custom errors provided via timeout.error are also detected.\n */\nexport function isStepTimeoutError(e: unknown): e is StepTimeoutError {\n if (typeof e !== \"object\" || e === null) {\n return false;\n }\n // Check for standard type field\n if ((e as StepTimeoutError).type === \"STEP_TIMEOUT\") {\n return true;\n }\n // Check for timeout marker (custom errors)\n return STEP_TIMEOUT_MARKER in e;\n}\n\n/**\n * Get timeout metadata from a timeout error (works with both standard and custom errors).\n * Returns undefined if the error is not a timeout error.\n */\nexport function getStepTimeoutMeta(e: unknown): StepTimeoutMarkerMeta | undefined {\n if (typeof e !== \"object\" || e === null) {\n return undefined;\n }\n // Check for standard type field first\n if ((e as StepTimeoutError).type === \"STEP_TIMEOUT\") {\n const err = e as StepTimeoutError;\n return {\n timeoutMs: err.timeoutMs,\n stepName: err.stepName,\n stepKey: err.stepKey,\n attempt: err.attempt,\n };\n }\n // Check for timeout marker (custom errors)\n if (STEP_TIMEOUT_MARKER in e) {\n return (e as Record<symbol, StepTimeoutMarkerMeta>)[STEP_TIMEOUT_MARKER];\n }\n return undefined;\n}\n\n// =============================================================================\n// RunStep Interface\n// =============================================================================\n\n/**\n * The `step` object passed to the function in `run(async ({ step }) => { ... })`.\n * acts as the bridge between your business logic and the workflow engine.\n *\n * It provides methods to:\n * 1. Execute operations that return `Result` types.\n * 2. safely wrap operations that might throw exceptions (using `step.try`).\n * 3. Assign names and keys to operations for tracing and caching.\n *\n * @template E - The union of all known error types expected in this workflow.\n */\nexport interface RunStep<E = unknown> {\n /**\n * Execute a Result-returning operation with explicit step ID.\n *\n * The ID is used for:\n * - Static analysis visualization\n * - Error flow tracking\n * - Step identification in diagrams\n * - Caching and resume (ID is used as the cache key)\n *\n * @param id - Unique step identifier (string literal for static analysis)\n * @param operation - A function that returns a Result or AsyncResult\n * @param options - Step options\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If the result is an error (stops execution safely)\n *\n * @example\n * ```typescript\n * const cart = await step('getCart', () => getCart(ctx.input.cartId), {\n * errors: ['CART_NOT_FOUND', 'CART_EMPTY'],\n * out: 'cart',\n * });\n * ```\n */\n <T, StepE extends E, StepC = unknown>(\n id: string,\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n options?: StepOptions\n ): Promise<T>;\n\n /**\n * Execute a standard throwing operation safely.\n * Catches exceptions and maps them to a typed error.\n *\n * Use this when integrating with libraries that throw exceptions.\n * Supports retry, timeout, and compensate options inline.\n *\n * @param id - Unique identifier for this step (required for analysis and caching)\n * @param operation - A function that returns a value or Promise (may throw)\n * @param options - Configuration including error mapping, retry, timeout, compensate\n * @returns The success value\n * @throws {EarlyExit} If the operation throws (stops execution safely)\n *\n * @example\n * ```typescript\n * // Basic\n * const data = await step.try(\"db-query\", () => db.query(), {\n * onError: (e) => ({ type: \"DB_ERROR\", cause: e }),\n * });\n *\n * // With retry + timeout\n * const data = await step.try(\"api-call\", () => callApi(), {\n * onError: (e) => \"API_ERROR\" as const,\n * retry: { attempts: 3, initialDelay: 100 },\n * timeout: { ms: 5000 },\n * });\n * ```\n */\n try: <T, const Err extends E>(\n id: string,\n operation: () => T | Promise<T>,\n options:\n | {\n error: Err;\n key?: string;\n ttl?: number;\n retry?: RetryOptions<Err>;\n timeout?: TimeoutOptions;\n compensate?: (value: T) => void | Promise<void>;\n }\n | {\n onError: (cause: unknown) => Err;\n key?: string;\n ttl?: number;\n retry?: RetryOptions<Err>;\n timeout?: TimeoutOptions;\n compensate?: (value: T) => void | Promise<void>;\n }\n ) => Promise<T>;\n\n /**\n * Execute a Result-returning function and map its error to a typed error.\n *\n * Use this when calling functions that return Result<T, E> and you want to\n * map their typed errors to your workflow's error type. Unlike step.try(),\n * the error passed to onError is typed (not unknown).\n *\n * @param id - Unique identifier for this step (required for analysis and caching)\n * @param operation - A function that returns a Result or AsyncResult\n * @param options - Configuration including error mapping\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If the result is an error (stops execution safely)\n *\n * @example\n * ```typescript\n * const response = await step.fromResult(\n * \"call-provider\",\n * () => callProvider(input),\n * {\n * onError: (providerError) => ({\n * type: \"PROVIDER_FAILED\",\n * provider: providerError.provider,\n * cause: providerError\n * })\n * }\n * );\n * ```\n */\n fromResult: <T, ResultE, const Err extends E>(\n id: string,\n operation: () => Result<T, ResultE, unknown> | AsyncResult<T, ResultE, unknown>,\n options:\n | { error: Err; key?: string; ttl?: number }\n | { onError: (resultError: ResultE) => Err; key?: string; ttl?: number }\n ) => Promise<T>;\n\n /**\n * Execute an operation that may return null/undefined and convert to a typed error.\n *\n * Shorthand for wrapping `fromNullable()` in a step — avoids boilerplate when\n * looking up optional values (database finds, map lookups, etc.).\n *\n * @param id - Unique step identifier\n * @param operation - A function that returns `T | null | undefined` (or a Promise thereof)\n * @param onNull - Returns the typed error when operation returns null/undefined\n *\n * @example\n * ```typescript\n * const user = await step.fromNullable(\n * 'getUser',\n * () => db.users.findById(id),\n * () => ({ type: 'NOT_FOUND' as const, id })\n * );\n * ```\n */\n fromNullable: <T, const Err extends E>(\n id: string,\n operation: () => T | null | undefined | Promise<T | null | undefined>,\n onNull: () => Err,\n options?: { key?: string; ttl?: number }\n ) => Promise<T>;\n\n /**\n * Execute parallel operations with scope events for visualization.\n *\n * This wraps the operations with scope_start and scope_end events, enabling\n * visualization of parallel execution branches.\n *\n * @overload Object form - step.all(name, { key: () => ... })\n * @overload Array form - step.all(name, () => allAsync([...]))\n *\n * @example Object form\n * ```typescript\n * const { user, posts } = await step.all('Fetch user data', {\n * user: () => fetchUser(id),\n * posts: () => fetchPosts(id),\n * });\n * ```\n *\n * @example Canonical form (strict mode)\n * ```typescript\n * const { user, posts } = await step.all('Fetch user data', {\n * user: { fn: () => fetchUser(id), errors: ['NOT_FOUND'] },\n * posts: { fn: () => fetchPosts(id), errors: ['FETCH_ERROR'] },\n * });\n * ```\n *\n * @example Array form\n * ```typescript\n * const [user, posts] = await step.all('Fetch all data', () =>\n * allAsync([fetchUser(id), fetchPosts(id)])\n * );\n * ```\n */\n all: {\n // Object form: step.all(name, { key: () => ... })\n <\n TOperations extends Record<\n string,\n () => MaybeAsyncResult<unknown, E, unknown>\n >\n >(\n name: string,\n operations: TOperations\n ): Promise<{\n [K in keyof TOperations]: TOperations[K] extends () => MaybeAsyncResult<\n infer V,\n E,\n unknown\n >\n ? V\n : never;\n }>;\n\n // Object form canonical: step.all(name, { key: { fn, errors } })\n <\n TOperations extends Record<\n string,\n ParallelOperationDescriptor<unknown, readonly string[]>\n >\n >(\n name: string,\n operations: TOperations\n ): Promise<{\n [K in keyof TOperations]: TOperations[K] extends ParallelOperationDescriptor<\n infer V,\n readonly string[]\n >\n ? V\n : never;\n }>;\n\n // Array form: step.all(name, () => allAsync([...]))\n <T, StepE extends E, StepC = unknown>(\n name: string,\n operation: () => Result<T[], StepE, StepC> | AsyncResult<T[], StepE, StepC>\n ): Promise<T[]>;\n };\n\n /**\n * Execute a race operation (anyAsync) with scope events for visualization.\n *\n * This wraps the operation with scope_start and scope_end events, enabling\n * visualization of racing execution branches.\n *\n * @param name - Name for this race block (used in visualization)\n * @param operation - A function that returns a Result from anyAsync\n * @returns The success value (first to succeed)\n *\n * @example\n * ```typescript\n * const data = await step.race('Fastest API', () =>\n * anyAsync([fetchFromPrimary(id), fetchFromFallback(id)])\n * );\n * ```\n */\n race: <T, StepE extends E, StepC = unknown>(\n name: string,\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>\n ) => Promise<T>;\n\n /**\n * Execute a primary operation with a fallback if the primary fails.\n *\n * If the primary operation returns an error, the fallback is executed instead.\n * When `on` is specified, the fallback only runs for that specific error;\n * other errors propagate without invoking the fallback.\n *\n * Returns `Promise<T>` — errors escape via earlyExit into the workflow's error channel.\n * The error union `E1 | E2` is the generic constraint propagated to the workflow.\n *\n * @overload Fallback on ANY error from primary\n * @overload Fallback on SPECIFIC error literal only (via `on`)\n *\n * @param id - Unique step identifier (single step ID for events)\n * @param operation - Primary operation that returns AsyncResult\n * @param options - Fallback configuration\n * @returns The success value from primary or fallback\n *\n * @example\n * ```typescript\n * const user = await step.withFallback(\n * 'getUser',\n * () => fetchFromPrimary(id),\n * { fallback: () => fetchFromCache(id) }\n * );\n *\n * // With specific error filter\n * const data = await step.withFallback(\n * 'getData',\n * () => fetchFromApi(id),\n * { on: 'NOT_FOUND', fallback: () => getDefault(id) }\n * );\n * ```\n */\n withFallback: {\n // Overload 1: fallback on ANY error from primary\n <T, E1 extends E, E2 extends E>(\n id: string,\n operation: () => AsyncResult<T, E1>,\n options: { fallback: () => AsyncResult<T, E2>; key?: string }\n ): Promise<T>;\n\n // Overload 2: fallback on SPECIFIC error literal only\n <T, E1 extends E & string, E2 extends E>(\n id: string,\n operation: () => AsyncResult<T, E1>,\n options: { on: E1; fallback: () => AsyncResult<T, E2>; key?: string }\n ): Promise<T>;\n };\n\n /**\n * Execute an operation with automatic resource lifecycle management.\n *\n * Acquires a resource, uses it, and guarantees release regardless of outcome.\n * Release always runs after use completes (even on error or throw).\n * Release errors are logged via console.warn but never override the use result.\n *\n * No caching support — caching resource-using steps is dangerous.\n *\n * @param id - Unique step identifier\n * @param options - Resource lifecycle configuration\n * @returns The success value from the use function\n *\n * @example\n * ```typescript\n * const data = await step.withResource('useDb', {\n * acquire: () => connectToDb(),\n * use: (db) => db.query('SELECT * FROM users'),\n * release: (db) => db.close(),\n * });\n * ```\n */\n withResource: <T, R, AcquireE extends E, UseE extends E>(\n id: string,\n options: {\n acquire: () => AsyncResult<R, AcquireE>;\n use: (resource: R) => AsyncResult<T, UseE>;\n release: (resource: R) => void | Promise<void>;\n }\n ) => Promise<T>;\n\n /**\n * Execute an operation with retry and optional timeout.\n *\n * Use this for operations that may fail transiently (network issues, rate limits)\n * and benefit from automatic retry with backoff.\n *\n * @param id - Unique identifier for this step (required for analysis and caching)\n * @param operation - A function that returns a Result or AsyncResult\n * @param options - Retry configuration and optional timeout\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If all retries are exhausted (stops execution safely)\n *\n * @example\n * ```typescript\n * const data = await step.retry(\n * \"fetch-external\",\n * () => fetchFromExternalApi(id),\n * {\n * attempts: 3,\n * backoff: 'exponential',\n * initialDelay: 200,\n * shouldRetry: (error) => error === 'RATE_LIMITED' || error === 'TRANSIENT',\n * onRetry: (error, attempt, delay) => {\n * console.log(`Retry ${attempt} after ${delay}ms`);\n * },\n * }\n * );\n * ```\n */\n retry: <T, StepE extends E, StepC = unknown>(\n id: string,\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n options: RetryOptions<StepE> & { key?: string; timeout?: TimeoutOptions }\n ) => Promise<T>;\n\n /**\n * Execute an operation with a timeout.\n *\n * Use this for operations that may hang indefinitely (external APIs, connections)\n * and need to be aborted after a certain duration.\n *\n * When `signal: true` is set, an AbortSignal is passed to your operation,\n * which you can use with APIs like fetch() for proper cancellation.\n *\n * @param id - Unique identifier for this step (required for analysis and caching)\n * @param operation - A function that returns a Result (may receive AbortSignal)\n * @param options - Timeout configuration\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If the operation times out (stops execution safely)\n *\n * @example\n * ```typescript\n * // Without AbortSignal\n * const data = await step.withTimeout(\n * \"fetch-data\",\n * () => fetchData(id),\n * { ms: 5000 }\n * );\n *\n * // With AbortSignal for fetch()\n * const data = await step.withTimeout(\n * \"fetch-url\",\n * (signal) => fetch(url, { signal }).then(r => ok(r.json())),\n * { ms: 5000, signal: true }\n * );\n * ```\n */\n withTimeout: <T, StepE extends E, StepC = unknown>(\n id: string,\n operation:\n | (() => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>)\n | ((signal: AbortSignal) => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>),\n options: TimeoutOptions & { key?: string }\n ) => Promise<T>;\n\n /**\n * Pause execution for a specified duration.\n *\n * Use this for intentional delays between operations (rate limiting,\n * polling intervals, debouncing). Respects workflow cancellation.\n *\n * @param id - Unique identifier for this step (required for analysis and caching)\n * @param duration - Duration as string (\"5s\", \"100ms\") or Duration object\n * @param options - Optional key for per-iteration identity, ttl, description\n * @returns Promise that resolves after the duration\n * @throws {AbortError} If the workflow is cancelled during sleep\n *\n * @example\n * ```typescript\n * // String duration\n * await step.sleep(\"rate-limit-delay\", \"5s\");\n *\n * // Duration object\n * await step.sleep(\"my-sleep\", seconds(5));\n * ```\n */\n sleep(\n id: string,\n duration: DurationInput,\n options?: { key?: string; ttl?: number; description?: string; signal?: AbortSignal }\n ): Promise<void>;\n\n // ===========================================================================\n // Streaming Methods\n // ===========================================================================\n\n /**\n * Get a writable stream for this workflow.\n *\n * Use this to write values that can be consumed by readers\n * (e.g., HTTP response streaming, AI token streaming).\n *\n * @param options - Stream options (namespace, highWaterMark)\n * @returns StreamWriter for writing values\n *\n * @example\n * ```typescript\n * const writer = step.getWritable<string>({ namespace: 'ai-response' });\n *\n * await step(() => generateAI({\n * prompt: 'Hello',\n * onToken: async (token) => { await writer.write(token); }\n * }), { key: 'generate' });\n *\n * await writer.close();\n * ```\n */\n getWritable: <T>(options?: StreamWritableOptions) => StreamWriterInterface<T>;\n\n /**\n * Get a readable stream for this workflow.\n *\n * Use this to consume values from a stream, with support for\n * resuming from a specific position.\n *\n * @param options - Read options (namespace, startIndex)\n * @returns StreamReader for reading values\n *\n * @example\n * ```typescript\n * const reader = step.getReadable<string>({ namespace: 'ai-response' });\n *\n * let result = await reader.read();\n * while (result.ok) {\n * response.write(result.value);\n * result = await reader.read();\n * }\n * ```\n */\n getReadable: <T>(options?: StreamReadableOptions) => StreamReaderInterface<T>;\n\n /**\n * Process stream items with checkpointing.\n *\n * Combines streaming with batch processing - each item is processed\n * and checkpointed, enabling resume from the last successful item.\n *\n * @param source - StreamReader or AsyncIterable to process\n * @param processor - Function to process each item\n * @param options - Processing options\n * @returns Results from all processed items\n *\n * @example\n * ```typescript\n * const reader = step.getReadable<Message>({ namespace: 'messages' });\n *\n * const result = await step.streamForEach(\n * reader,\n * async (message, index) => {\n * const processed = await processMessage(message);\n * return ok(processed);\n * },\n * { name: 'process-messages', checkpointInterval: 10 }\n * );\n *\n * console.log(`Processed ${result.value.processedCount} messages`);\n * ```\n */\n streamForEach: <T, R, StepE extends E>(\n source: StreamReaderInterface<T> | AsyncIterable<T>,\n processor: (item: T, index: number) => AsyncResult<R, StepE>,\n options?: StreamForEachStepOptions\n ) => Promise<StreamForEachResultType<R>>;\n\n // ===========================================================================\n // Static Analysis Methods\n // ===========================================================================\n\n /**\n * Mark a conditional for static analysis with a stable ID and condition label.\n * Runtime: returns the boolean result of condition().\n * Analysis: emits a DecisionNode with stable id and conditionLabel, and attaches\n * the then/else subgraphs from the if/else branches.\n *\n * @param id - Stable identifier for this decision point (string literal for static analysis)\n * @param conditionLabel - Human-readable label describing the condition\n * @param condition - Function that returns the boolean condition\n * @returns The result of the condition function\n *\n * @example\n * ```typescript\n * if (step.if('payment', 'cart.total > 0', () => ctx.ref('cart').total > 0)) {\n * await step('chargeCard', () => deps.chargeCard(ctx.ref('cart').total), {\n * errors: ['CARD_DECLINED'],\n * });\n * } else {\n * await step('skipPayment', async () => ({ skipped: true }), {\n * errors: [],\n * });\n * }\n * ```\n */\n if: <T extends boolean>(\n id: string,\n conditionLabel: string,\n condition: () => T\n ) => T;\n\n /**\n * Alias for `step.if()`. Mark a conditional for static analysis with a stable ID.\n * Use this to label conditionals in strict mode when they contain step calls.\n *\n * @param id - Stable identifier for this decision point\n * @param conditionLabel - Human-readable label describing the condition\n * @param condition - Function that returns the boolean condition\n * @returns The result of the condition function\n *\n * @example\n * ```typescript\n * if (step.label('email-type', 'user.isPremium', () => user.isPremium)) {\n * await step('premium', () => sendPriorityEmail(user), { errors: ['EMAIL_FAILED'] });\n * } else {\n * await step('free', () => sendRegularEmail(user), { errors: ['EMAIL_FAILED'] });\n * }\n * ```\n */\n label: <T extends boolean>(\n id: string,\n conditionLabel: string,\n condition: () => T\n ) => T;\n\n /**\n * Execute a branch with explicit metadata for static analysis.\n * Use when you want richer analyzer metadata (conditionLabel, per-arm errors).\n * For most cases, use natural if/else with step.label() instead.\n *\n * @param id - Stable identifier for this branch point\n * @param options - Branch configuration with condition, then/else arms, and errors\n * @returns The result from the executed arm\n *\n * @example\n * ```typescript\n * const charge = await step.branch('payment', {\n * conditionLabel: 'cart.total > 0',\n * condition: () => ctx.ref('cart').total > 0,\n * out: 'charge',\n * then: () => chargeCard(ctx.ref('cart').total),\n * thenErrors: ['CARD_DECLINED'],\n * else: () => ok({ skipped: true }),\n * elseErrors: [],\n * });\n * ```\n */\n branch: <\n T,\n const ThenErrs extends readonly string[] = readonly [],\n const ElseErrs extends readonly string[] = readonly [],\n const Out extends string | undefined = undefined,\n >(\n id: string,\n options: BranchOptions<T, ThenErrs, ElseErrs, Out>\n ) => Promise<T>;\n\n /**\n * Create an arm definition for use with step.branch().\n * Runtime: returns the arm definition unchanged.\n * Analyzer: extracts arm metadata for visualization.\n *\n * @param fn - The arm function\n * @param errors - Declared errors for this arm\n * @returns The arm definition\n *\n * @example\n * ```typescript\n * const thenArm = step.arm(() => chargeCard(total), ['CARD_DECLINED']);\n * const elseArm = step.arm(() => ok({ skipped: true }), []);\n * ```\n */\n arm: <T, const Errs extends readonly string[] = readonly []>(\n fn: () => T | Promise<T>,\n errors?: Errs\n ) => ArmDefinition<T, Errs>;\n\n /**\n * Execute a forEach loop with static analysis support.\n * Supports both simple (run) and complex (item) forms.\n *\n * @param id - Stable identifier for this loop\n * @param items - Iterable to loop over\n * @param options - Loop configuration\n * @returns Array of results from each iteration\n *\n * @example Simple form:\n * ```typescript\n * await step.forEach('process-items', items, {\n * maxIterations: 100,\n * stepIdPattern: 'process-{i}',\n * errors: ['PROCESS_ERROR'],\n * run: (item) => processItem(item),\n * });\n * ```\n *\n * @example Complex form with multiple steps:\n * ```typescript\n * await step.forEach('process-items', items, {\n * maxIterations: 100,\n * item: step.item((item, i, innerStep) => {\n * await innerStep('validate', () => validate(item), { errors: ['INVALID'] });\n * await innerStep('process', () => process(item), { errors: ['FAILED'] });\n * }),\n * });\n * ```\n */\n forEach: {\n // Simple form with run callback\n <T, R, const Errs extends readonly string[] = readonly []>(\n id: string,\n items: Iterable<T> | AsyncIterable<T>,\n options: ForEachRunOptions<T, R, Errs>\n ): Promise<R[]>;\n\n // Complex form with item callback\n <T, R>(\n id: string,\n items: Iterable<T> | AsyncIterable<T>,\n options: ForEachItemOptions<T, R>\n ): Promise<R[]>;\n };\n\n /**\n * Create an item handler for use with step.forEach().\n * Runtime: returns the handler unchanged.\n * Analyzer: extracts the inner step structure.\n *\n * @param handler - Function to process each item\n * @returns The item handler\n *\n * @example\n * ```typescript\n * step.item((item, index, innerStep) => {\n * await innerStep('validate', () => validate(item));\n * await innerStep('process', () => process(item));\n * });\n * ```\n */\n item: <T, R>(\n handler: (item: T, index: number, step: RunStep<E>) => R | Promise<R>\n ) => ForEachItemHandler<T, R>;\n\n /**\n * Wrap a dependency function for static analysis tracking.\n * Returns the function unchanged but marks it for the analyzer.\n *\n * @param name - Name of the dependency (for analyzer tracking)\n * @param fn - The dependency function to wrap\n * @returns The same function, unchanged\n *\n * @example\n * ```typescript\n * await step('getCart', step.dep('getCart', () => deps.getCart(ctx.input.cartId)), {\n * errors: ['CART_NOT_FOUND'],\n * out: 'cart',\n * });\n * ```\n */\n dep: <T extends (...args: unknown[]) => unknown>(name: string, fn: T) => T;\n\n // ===========================================================================\n // Effect-Style Ergonomics\n // ===========================================================================\n\n /**\n /**\n * Run a sub-workflow (or any AsyncResult-returning operation) as a step.\n * Use for workflow composition; the getter's error type (SubE) flows into the parent's error union.\n *\n * @param id - Unique step identifier\n * @param getter - Function that returns AsyncResult (e.g. () => subWorkflow.run(fn))\n * @param options - Step options (key, ttl, etc.)\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If the result is an error\n *\n * @example\n * ```typescript\n * const authResult = await step.workflow(\"authorize\", () => authorizeWorkflow.run(fn));\n * ```\n */\n workflow: <T, SubE extends E, StepC = unknown>(\n id: string,\n getter: () => AsyncResult<T, SubE, StepC>,\n options?: StepOptions\n ) => Promise<T>;\n\n /**\n * Map over an array with parallel execution and error tracking.\n *\n * Similar to Effect.forEach - executes mapper function for each item\n * in parallel and collects results.\n *\n * @param id - Unique step identifier\n * @param items - Array of items to process\n * @param mapper - Function to process each item (returns AsyncResult)\n * @param options - Optional concurrency limit and cache key\n * @returns Array of results in original order\n *\n * @example\n * ```typescript\n * const users = await step.map('fetchUsers', userIds, (id) =>\n * fetchUser(id)\n * );\n * // Automatic parallel execution with error union\n * ```\n */\n map: <T, U, StepE extends E, StepC = unknown>(\n id: string,\n items: T[],\n mapper: (item: T, index: number) => AsyncResult<U, StepE, StepC>,\n options?: { concurrency?: number; key?: string }\n ) => Promise<U[]>;\n\n}\n\n// =============================================================================\n// Parallel Types\n// =============================================================================\n\n/**\n * Operation descriptor for canonical parallel form.\n * Use this for analyzable parallel operations with explicit error declarations.\n */\nexport type ParallelOperationDescriptor<\n T,\n Errs extends readonly string[] = readonly [],\n> = {\n /** The operation function */\n fn: () => MaybeAsyncResult<T, unknown, unknown>;\n /** Declared errors for this operation (for static analysis) */\n errors?: Errs;\n};\n\n// =============================================================================\n// Branch and ForEach Types\n// =============================================================================\n\n/**\n * Options for step.branch().\n */\nexport type BranchOptions<\n T,\n ThenErrs extends readonly string[] = readonly [],\n ElseErrs extends readonly string[] = readonly [],\n Out extends string | undefined = undefined,\n> = {\n /** Human-readable label describing the condition */\n conditionLabel: string;\n /** Function that evaluates the condition */\n condition: () => boolean;\n /** Output key for data flow (writes result to ctx[out]) */\n out?: Out;\n /** Function to execute when condition is true */\n then: () => T | Promise<T>;\n /** Declared errors for the then arm */\n thenErrors?: ThenErrs;\n /** Function to execute when condition is false */\n else?: () => T | Promise<T>;\n /** Declared errors for the else arm */\n elseErrors?: ElseErrs;\n};\n\n/**\n * Arm definition for step.branch().\n */\nexport type ArmDefinition<T, Errs extends readonly string[] = readonly []> = {\n fn: () => T | Promise<T>;\n errors?: Errs;\n};\n\n/**\n * Options for step.forEach() with simple run form.\n */\nexport type ForEachRunOptions<T, R, Errs extends readonly string[] = readonly []> = {\n /** Maximum iterations (for bounded analysis) */\n maxIterations?: number;\n /** Step ID pattern for iterations (e.g., 'process-{i}') */\n stepIdPattern?: string;\n /** Declared errors for the loop body */\n errors?: Errs;\n /** Output key for results (requires collect option in strict mode) */\n out?: string;\n /** How to collect results when out is specified */\n collect?: \"array\" | \"last\";\n /** Simple callback for each item */\n run: (item: T, index: number) => R | Promise<R>;\n};\n\n/**\n * Options for step.forEach() with complex item form.\n */\nexport type ForEachItemOptions<T, R> = {\n /** Maximum iterations (for bounded analysis) */\n maxIterations?: number;\n /** Step ID pattern for iterations (e.g., 'process-{i}') */\n stepIdPattern?: string;\n /** Output key for results (requires collect option in strict mode) */\n out?: string;\n /** How to collect results when out is specified */\n collect?: \"array\" | \"last\";\n /** Complex item handler with inner step access */\n item: ForEachItemHandler<T, R>;\n};\n\n/**\n * Item handler for step.forEach() with inner step access.\n */\nexport type ForEachItemHandler<T, R> = {\n __forEachItemHandler: true;\n handler: (item: T, index: number, step: RunStep<unknown>) => R | Promise<R>;\n};\n\n// =============================================================================\n// Streaming Types (minimal interfaces for RunStep)\n// =============================================================================\n\n/**\n * Options for getWritable.\n */\nexport interface StreamWritableOptions {\n /** Named streams (default: 'default') */\n namespace?: string;\n /** Backpressure threshold (default: 16) */\n highWaterMark?: number;\n}\n\n/**\n * Options for getReadable.\n */\nexport interface StreamReadableOptions {\n /** Named streams (default: 'default') */\n namespace?: string;\n /** Resume from position (0-indexed) */\n startIndex?: number;\n /** Poll interval in ms when waiting for new items (default: 10) */\n pollInterval?: number;\n /** Stop polling after this many ms with no new items (default: 30000) */\n pollTimeout?: number;\n}\n\n/**\n * Options for streamForEach.\n */\nexport interface StreamForEachStepOptions {\n /** Checkpoint after every N items (default: 1) */\n checkpointInterval?: number;\n /** Maximum concurrent processors (default: 1 = sequential) */\n concurrency?: number;\n}\n\n/**\n * Result from streamForEach operation.\n */\nexport interface StreamForEachResultType<R> {\n /** Results from each processed item */\n results: R[];\n /** Total items processed */\n processedCount: number;\n /** Position of last processed item */\n lastPosition: number;\n}\n\n/**\n * Writable stream interface used in RunStep.\n * @see StreamWriter in awaitly/streaming for full interface\n */\nexport interface StreamWriterInterface<T> {\n write(value: T): AsyncResult<void, StreamWriteErrorType>;\n close(): AsyncResult<void, StreamCloseErrorType>;\n abort(reason: unknown): void;\n readonly writable: boolean;\n readonly position: number;\n readonly namespace: string;\n}\n\n/**\n * Readable stream interface used in RunStep.\n * @see StreamReader in awaitly/streaming for full interface\n */\nexport interface StreamReaderInterface<T> {\n read(): AsyncResult<T, StreamReadErrorType | StreamEndedMarkerType>;\n close(): void;\n readonly readable: boolean;\n readonly position: number;\n readonly namespace: string;\n}\n\n/**\n * Stream write error type.\n */\nexport interface StreamWriteErrorType {\n type: \"STREAM_WRITE_ERROR\";\n reason: \"closed\" | \"aborted\" | \"store_error\";\n message: string;\n cause?: unknown;\n}\n\n/**\n * Stream read error type.\n */\nexport interface StreamReadErrorType {\n type: \"STREAM_READ_ERROR\";\n reason: \"closed\" | \"store_error\";\n message: string;\n cause?: unknown;\n}\n\n/**\n * Stream close error type.\n */\nexport interface StreamCloseErrorType {\n type: \"STREAM_CLOSE_ERROR\";\n reason: \"already_closed\" | \"store_error\";\n message: string;\n cause?: unknown;\n}\n\n/**\n * Stream ended marker type.\n */\nexport interface StreamEndedMarkerType {\n type: \"STREAM_ENDED\";\n finalPosition: number;\n}\n\n// =============================================================================\n// Event Types (for run() optional event support)\n// =============================================================================\n\n/**\n * Unified event stream for workflow execution.\n *\n * Note: step_complete.result uses Result<unknown, unknown, unknown> because events\n * aggregate results from heterogeneous steps. At runtime, the actual Result object\n * preserves its original types, but the event type cannot statically represent them.\n * Use runtime checks or the meta field to interpret cause values.\n */\n/**\n * Scope types for parallel and race operations.\n */\nexport type ScopeType = \"parallel\" | \"race\" | \"allSettled\";\n\nexport type WorkflowEvent<E, C = unknown> =\n | { type: \"workflow_start\"; workflowId: string; workflowName?: string; ts: number; context?: C }\n | { type: \"workflow_success\"; workflowId: string; workflowName?: string; ts: number; durationMs: number; context?: C }\n | { type: \"workflow_error\"; workflowId: string; workflowName?: string; ts: number; durationMs: number; error: E; context?: C }\n | { type: \"step_start\"; workflowId: string; workflowName?: string; stepId: string; stepKey?: string; name?: string; description?: string; ts: number; metadata?: StepMetadata; context?: C }\n | { type: \"step_success\"; workflowId: string; workflowName?: string; stepId: string; stepKey?: string; name?: string; description?: string; ts: number; durationMs: number; metadata?: StepMetadata; context?: C }\n | { type: \"step_error\"; workflowId: string; workflowName?: string; stepId: string; stepKey?: string; name?: string; description?: string; ts: number; durationMs: number; error: E; metadata?: StepMetadata; diagnostics?: StepErrorDiagnostics; context?: C }\n | { type: \"step_aborted\"; workflowId: string; workflowName?: string; stepId: string; stepKey?: string; name?: string; description?: string; ts: number; durationMs: number; metadata?: StepMetadata; context?: C }\n | { type: \"step_complete\"; workflowId: string; workflowName?: string; stepKey: string; name?: string; description?: string; ts: number; durationMs: number; result: Result<unknown, unknown, unknown>; meta?: StepFailureMeta; metadata?: StepMetadata; context?: C }\n | { type: \"step_cache_hit\"; workflowId: string; workflowName?: string; stepKey: string; name?: string; ts: number; metadata?: StepMetadata; context?: C }\n | { type: \"step_cache_miss\"; workflowId: string; workflowName?: string; stepKey: string; name?: string; ts: number; metadata?: StepMetadata; context?: C }\n | { type: \"step_skipped\"; workflowId: string; workflowName?: string; stepKey?: string; name?: string; reason?: string; decisionId?: string; ts: number; metadata?: StepMetadata; context?: C }\n | { type: \"decision\"; workflowId: string; workflowName?: string; decisionId: string; label?: string; branch: string; value: unknown; phase?: \"start\" | \"end\"; durationMs?: number; ts: number; context?: C }\n | { type: \"scope_start\"; workflowId: string; workflowName?: string; scopeId: string; scopeType: ScopeType; name?: string; ts: number; context?: C }\n | { type: \"scope_end\"; workflowId: string; workflowName?: string; scopeId: string; ts: number; durationMs: number; winnerId?: string; context?: C }\n // Retry events\n | {\n type: \"step_retry\";\n workflowId: string;\n workflowName?: string;\n stepId: string;\n stepKey?: string;\n name?: string;\n ts: number;\n attempt: number;\n maxAttempts: number;\n delayMs: number;\n error: E;\n metadata?: StepMetadata;\n diagnostics?: StepErrorDiagnostics;\n context?: C;\n }\n | {\n type: \"step_retries_exhausted\";\n workflowId: string;\n workflowName?: string;\n stepId: string;\n stepKey?: string;\n name?: string;\n ts: number;\n durationMs: number;\n attempts: number;\n lastError: E;\n metadata?: StepMetadata;\n diagnostics?: StepErrorDiagnostics;\n context?: C;\n }\n // Timeout event\n | {\n type: \"step_timeout\";\n workflowId: string;\n workflowName?: string;\n stepId: string;\n stepKey?: string;\n name?: string;\n ts: number;\n timeoutMs: number;\n attempt?: number;\n metadata?: StepMetadata;\n diagnostics?: StepErrorDiagnostics;\n context?: C;\n }\n // Hook events\n | {\n type: \"hook_should_run\";\n workflowId: string;\n workflowName?: string;\n ts: number;\n durationMs: number;\n result: boolean;\n skipped: boolean;\n context?: C;\n }\n | {\n type: \"hook_should_run_error\";\n workflowId: string;\n workflowName?: string;\n ts: number;\n durationMs: number;\n error: E;\n context?: C;\n }\n | {\n type: \"hook_before_start\";\n workflowId: string;\n workflowName?: string;\n ts: number;\n durationMs: number;\n result: boolean;\n skipped: boolean;\n context?: C;\n }\n | {\n type: \"hook_before_start_error\";\n workflowId: string;\n workflowName?: string;\n ts: number;\n durationMs: number;\n error: E;\n context?: C;\n }\n | {\n type: \"hook_after_step\";\n workflowId: string;\n workflowName?: string;\n stepKey: string;\n ts: number;\n durationMs: number;\n context?: C;\n }\n | {\n type: \"hook_after_step_error\";\n workflowId: string;\n workflowName?: string;\n stepKey: string;\n ts: number;\n durationMs: number;\n error: E;\n context?: C;\n }\n // Stream events\n | {\n type: \"stream_created\";\n workflowId: string;\n workflowName?: string;\n namespace: string;\n ts: number;\n context?: C;\n }\n | {\n type: \"stream_write\";\n workflowId: string;\n workflowName?: string;\n namespace: string;\n position: number;\n ts: number;\n context?: C;\n }\n | {\n type: \"stream_read\";\n workflowId: string;\n workflowName?: string;\n namespace: string;\n position: number;\n ts: number;\n context?: C;\n }\n | {\n type: \"stream_close\";\n workflowId: string;\n workflowName?: string;\n namespace: string;\n finalPosition: number;\n ts: number;\n context?: C;\n }\n | {\n type: \"stream_error\";\n workflowId: string;\n workflowName?: string;\n namespace: string;\n error: unknown;\n position: number;\n ts: number;\n context?: C;\n }\n | {\n type: \"stream_backpressure\";\n workflowId: string;\n workflowName?: string;\n namespace: string;\n bufferedCount: number;\n state: \"paused\" | \"flowing\";\n ts: number;\n context?: C;\n }\n // Workflow cancellation event\n | {\n type: \"workflow_cancelled\";\n workflowId: string;\n workflowName?: string;\n ts: number;\n durationMs: number;\n /** Reason from AbortSignal.reason (if provided) */\n reason?: string;\n /** Last successfully completed keyed step before cancellation (for resume purposes) */\n lastStepKey?: string;\n context?: C;\n };\n\n// =============================================================================\n// Run Options\n// =============================================================================\n\n/**\n * A declared workflow graph for strict runtime validation.\n *\n * Pass either a list of step/decision ids or a WorkflowDiagramDSL-shaped\n * object (`{ states: [{ id }] }`, as produced by awaitly-analyze).\n * When provided, any runtime step or decision id not present in the graph\n * fails the workflow immediately — so the static diagram is guaranteed to\n * match what actually runs. Ids containing `{...}` placeholders\n * (e.g. \"item-{i}\") match any value in that position.\n */\nexport type DeclaredGraph =\n | readonly string[]\n | {\n readonly states: ReadonlyArray<{\n readonly id: string;\n /** Authored id when the unique diagram id needed a collision suffix. */\n readonly semanticId?: string;\n }>;\n };\n\nexport type RunOptionsWithCatch<E, C = void> = {\n /**\n * Handler for expected errors.\n * Called when a step fails with a known error type.\n */\n onError?: (error: E, stepName?: string, ctx?: C) => void;\n /**\n * Listener for workflow events (start, success, error, step events).\n * Use this for logging, telemetry, or debugging.\n *\n * Context is automatically included in `event.context` when provided via the `context` option.\n * The separate `ctx` parameter is provided for convenience.\n */\n onEvent?: (event: WorkflowEvent<E | UnexpectedError, C>, ctx: C) => void;\n /**\n * Catch-all mapper for unexpected exceptions.\n * Converts unknown exceptions (and cancellation) into your typed error union E.\n */\n catchUnexpected: (cause: unknown) => E;\n /**\n * Unique ID for this workflow execution.\n * Defaults to a random UUID.\n * Useful for correlating logs across distributed systems.\n */\n workflowId?: string;\n /**\n * Human-readable workflow name included on emitted events.\n * Useful for observability and visualization.\n */\n workflowName?: string;\n /**\n * Arbitrary context object passed to onEvent and onError.\n * Useful for passing request IDs, user IDs, or loggers.\n */\n context?: C;\n /**\n * Declared workflow graph for strict runtime validation.\n * Undeclared step/decision ids fail the workflow immediately.\n */\n graph?: DeclaredGraph;\n /**\n * @internal External signal for workflow-level cancellation.\n * Used by createWorkflow() to pass the workflow signal to steps.\n */\n _workflowSignal?: AbortSignal;\n};\n\nexport type RunOptionsWithoutCatch<E, C = void> = {\n /**\n * Handler for expected errors AND unexpected errors.\n * Unexpected errors will be wrapped in `UnexpectedError`.\n */\n onError?: (error: E | UnexpectedError, stepName?: string, ctx?: C) => void;\n /**\n * Listener for workflow events (start, success, error, step events).\n *\n * Note: Context is available both on `event.context` and as the separate `ctx` parameter.\n * The `ctx` parameter is provided for convenience and backward compatibility.\n */\n onEvent?: (event: WorkflowEvent<E | UnexpectedError, C>, ctx: C) => void;\n catchUnexpected?: undefined;\n workflowId?: string;\n /**\n * Human-readable workflow name included on emitted events.\n * Useful for observability and visualization.\n */\n workflowName?: string;\n context?: C;\n /**\n * Declared workflow graph for strict runtime validation.\n * Undeclared step/decision ids fail the workflow immediately.\n */\n graph?: DeclaredGraph;\n /**\n * @internal External signal for workflow-level cancellation.\n * Used by createWorkflow() to pass the workflow signal to steps.\n */\n _workflowSignal?: AbortSignal;\n};\n\nexport type RunOptions<E, C = void> = RunOptionsWithCatch<E, C> | RunOptionsWithoutCatch<E, C>;\n\n// =============================================================================\n// Early Exit Mechanism (exported for caching layer)\n// =============================================================================\n\n/**\n * Symbol used to identify early exit throws.\n * Exported for the caching layer in workflow.ts.\n * @internal\n */\nexport const EARLY_EXIT_SYMBOL: unique symbol = Symbol(\"early-exit\");\n\n/**\n * Metadata about how a step failed.\n * @internal\n */\nexport type StepFailureMeta =\n | { origin: \"result\"; resultCause?: unknown }\n | { origin: \"throw\"; thrown: unknown }\n | { origin: \"fallback\"; fallbackUsed: true; fallbackReason: string };\n\n/**\n * Early exit object thrown to short-circuit workflow execution.\n * @internal\n */\nexport type EarlyExit<E> = {\n [EARLY_EXIT_SYMBOL]: true;\n error: E;\n meta: StepFailureMeta;\n};\n\n/**\n * Create an early exit throw object.\n * Used by the caching layer to synthesize early exits for cached errors.\n * @internal\n */\nexport function createEarlyExit<E>(error: E, meta: StepFailureMeta): EarlyExit<E> {\n return {\n [EARLY_EXIT_SYMBOL]: true,\n error,\n meta,\n };\n}\n\n/**\n * Type guard for early exit objects.\n * @internal\n */\nexport function isEarlyExit<E>(e: unknown): e is EarlyExit<E> {\n return (\n typeof e === \"object\" &&\n e !== null &&\n (e as Record<PropertyKey, unknown>)[EARLY_EXIT_SYMBOL] === true\n );\n}\n\n/**\n * Symbol to mark exceptions thrown by catchUnexpected mappers.\n * These should propagate without being re-processed.\n * @internal\n */\nconst MAPPER_EXCEPTION_SYMBOL: unique symbol = Symbol(\"mapper-exception\");\n\ntype MapperException = {\n [MAPPER_EXCEPTION_SYMBOL]: true;\n thrown: unknown;\n};\n\nfunction createMapperException(thrown: unknown): MapperException {\n return { [MAPPER_EXCEPTION_SYMBOL]: true, thrown };\n}\n\nfunction isMapperException(e: unknown): e is MapperException {\n return (\n typeof e === \"object\" &&\n e !== null &&\n (e as Record<PropertyKey, unknown>)[MAPPER_EXCEPTION_SYMBOL] === true\n );\n}\n\n// =============================================================================\n// Retry and Timeout Utilities\n// =============================================================================\n\n/**\n * Calculate the delay for a retry attempt based on the backoff strategy.\n * @internal\n */\nfunction calculateRetryDelay(\n attempt: number,\n options: {\n backoff: BackoffStrategy;\n initialDelay: number;\n maxDelay: number;\n jitter: boolean;\n }\n): number {\n const { backoff, initialDelay, maxDelay, jitter } = options;\n\n let delay: number;\n\n switch (backoff) {\n case \"fixed\":\n delay = initialDelay;\n break;\n case \"linear\":\n delay = initialDelay * attempt;\n break;\n case \"exponential\":\n delay = initialDelay * Math.pow(2, attempt - 1);\n break;\n }\n\n // Apply max cap\n delay = Math.min(delay, maxDelay);\n\n // Apply jitter (0-25% of delay)\n if (jitter) {\n const jitterAmount = delay * 0.25 * Math.random();\n delay = delay + jitterAmount;\n }\n\n return Math.floor(delay);\n}\n\n/**\n * Sleep for a specified number of milliseconds.\n * @internal\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nconst DEFAULT_RETRY_ASYNC_CONFIG = {\n backoff: \"exponential\" as BackoffStrategy,\n initialDelay: 100,\n maxDelay: 30000,\n jitter: true,\n shouldRetry: (_error: unknown, _attempt: number) => true,\n onRetry: (_error: unknown, _attempt: number, _delayMs: number) => {},\n} as const;\n\n/**\n * Run an async function with retry. Reuses the same backoff and shouldRetry semantics as step.retry.\n * Use this when you want retries without the workflow/step machinery (e.g. in fetch).\n *\n * @param fn - Function that returns a Promise<Result<T, E>>\n * @param options - Retry configuration (attempts, backoff, shouldRetry, etc.)\n * @returns Promise that resolves to the last Result (ok or err). Rejects only if fn throws and shouldRetry returns false.\n */\nexport async function retryAsync<T, E>(\n fn: () => Promise<Result<T, E>>,\n options: RetryOptions\n): Promise<Result<T, E>> {\n const attempts = Math.max(1, options.attempts);\n const effective = {\n backoff: options.backoff ?? DEFAULT_RETRY_ASYNC_CONFIG.backoff,\n initialDelay: options.initialDelay ?? DEFAULT_RETRY_ASYNC_CONFIG.initialDelay,\n maxDelay: options.maxDelay ?? DEFAULT_RETRY_ASYNC_CONFIG.maxDelay,\n jitter: options.jitter ?? DEFAULT_RETRY_ASYNC_CONFIG.jitter,\n shouldRetry: options.shouldRetry ?? DEFAULT_RETRY_ASYNC_CONFIG.shouldRetry,\n onRetry: options.onRetry ?? DEFAULT_RETRY_ASYNC_CONFIG.onRetry,\n };\n\n let lastResult: Result<T, E> | undefined;\n for (let attempt = 1; attempt <= attempts; attempt++) {\n try {\n const result = await fn();\n if (result.ok) return result;\n lastResult = result;\n if (attempt < attempts && effective.shouldRetry(result.error, attempt)) {\n const delay = calculateRetryDelay(attempt, effective);\n effective.onRetry(result.error, attempt, delay);\n await sleep(delay);\n continue;\n }\n return result;\n } catch (thrown) {\n if (attempt < attempts && effective.shouldRetry(thrown, attempt)) {\n const delay = calculateRetryDelay(attempt, effective);\n effective.onRetry(thrown, attempt, delay);\n await sleep(delay);\n continue;\n }\n throw thrown;\n }\n }\n return lastResult!;\n}\n\n/**\n * Symbol used internally to identify timeout rejection.\n */\nconst TIMEOUT_SYMBOL: unique symbol = Symbol(\"timeout\");\nconst TIMEOUT_OPTION_SYMBOL: unique symbol = Symbol(\"timeout-option\");\n\n/**\n * Check if an error is a timeout option marker (should return undefined instead of error).\n * @internal\n */\nfunction isTimeoutOptionMarker(\n value: unknown\n): value is { [TIMEOUT_OPTION_SYMBOL]: true; ms: number } {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as Record<symbol, unknown>)[TIMEOUT_OPTION_SYMBOL] === true\n );\n}\n\n/**\n * Execute an operation with a timeout using Promise.race.\n * @internal\n */\nasync function executeWithTimeout<T>(\n operation: (() => Promise<T>) | ((signal: AbortSignal) => Promise<T>),\n options: TimeoutOptions,\n stepInfo: { name?: string; key?: string; attempt?: number },\n /** External signal (e.g., workflow cancellation) to combine with timeout signal */\n externalSignal?: AbortSignal\n): Promise<T> {\n const controller = new AbortController();\n const behavior = options.onTimeout ?? \"error\";\n\n // Create the timeout error based on behavior\n const createTimeoutError = (): unknown => {\n // For function behavior, call the handler to generate the error\n if (typeof behavior === \"function\") {\n return behavior({\n name: stepInfo.name,\n key: stepInfo.key,\n ms: options.ms,\n });\n }\n\n // For other behaviors, use custom error or default StepTimeoutError\n return (\n (options.error as StepTimeoutError) ?? {\n type: \"STEP_TIMEOUT\",\n stepName: stepInfo.name,\n stepKey: stepInfo.key,\n timeoutMs: options.ms,\n attempt: stepInfo.attempt,\n }\n );\n };\n\n // Track the timeout ID for cleanup\n let timeoutId: ReturnType<typeof setTimeout>;\n\n // If external signal is already aborted, abort immediately\n if (externalSignal?.aborted) {\n controller.abort(externalSignal.reason);\n }\n\n // Forward external signal abort to internal controller\n let externalAbortHandler: (() => void) | undefined;\n if (externalSignal && !externalSignal.aborted) {\n externalAbortHandler = () => controller.abort(externalSignal.reason);\n externalSignal.addEventListener(\"abort\", externalAbortHandler, { once: true });\n }\n\n // Create a timeout promise that rejects after the specified duration\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n // For 'disconnect', don't abort - let operation continue in background\n if (behavior !== \"disconnect\") {\n controller.abort();\n }\n\n // For 'option', throw special marker to return undefined\n if (behavior === \"option\") {\n reject({ [TIMEOUT_OPTION_SYMBOL]: true, ms: options.ms });\n return;\n }\n\n // For all other behaviors, throw the timeout error\n reject({ [TIMEOUT_SYMBOL]: true, error: createTimeoutError() });\n }, options.ms);\n });\n\n // Execute the operation\n let operationPromise: Promise<T>;\n if (options.signal) {\n // Operation expects an AbortSignal\n // Pass the internal controller's signal which is linked to both timeout and external signal\n operationPromise = Promise.resolve(\n (operation as (signal: AbortSignal) => Promise<T>)(controller.signal)\n );\n } else {\n // Standard operation\n operationPromise = Promise.resolve((operation as () => Promise<T>)());\n }\n\n try {\n // Race between operation and timeout\n const result = await Promise.race([operationPromise, timeoutPromise]);\n return result;\n } catch (error) {\n // Check if this was an 'option' timeout - return undefined as success\n if (\n typeof error === \"object\" &&\n error !== null &&\n (error as Record<symbol, unknown>)[TIMEOUT_OPTION_SYMBOL] === true\n ) {\n // Throw special marker that step handler will convert to ok(undefined)\n throw { [TIMEOUT_OPTION_SYMBOL]: true, ms: options.ms };\n }\n\n // Check if this was our timeout\n if (\n typeof error === \"object\" &&\n error !== null &&\n (error as Record<symbol, unknown>)[TIMEOUT_SYMBOL] === true\n ) {\n // For 'disconnect' behavior, the operation continues in the background\n // Attach a catch handler to prevent unhandled rejection if it fails later\n if (behavior === \"disconnect\") {\n operationPromise.catch(() => {\n // Intentionally swallowed - operation was disconnected\n });\n }\n\n const errorToThrow = (error as { error: unknown }).error;\n\n // Mark the error with STEP_TIMEOUT_MARKER if it's a custom error (not already a StepTimeoutError)\n // This allows isStepTimeoutError() and getStepTimeoutMeta() to work with custom errors\n // Note: Always update metadata to reflect the current attempt (same error may be reused across retries)\n if (\n typeof errorToThrow === \"object\" &&\n errorToThrow !== null &&\n (errorToThrow as StepTimeoutError).type !== \"STEP_TIMEOUT\"\n ) {\n const meta: StepTimeoutMarkerMeta = {\n timeoutMs: options.ms,\n stepName: stepInfo.name,\n stepKey: stepInfo.key,\n attempt: stepInfo.attempt,\n };\n\n if (STEP_TIMEOUT_MARKER in errorToThrow) {\n // Update existing marker with current attempt's metadata\n (errorToThrow as Record<symbol, StepTimeoutMarkerMeta>)[STEP_TIMEOUT_MARKER] = meta;\n } else {\n // Define new marker (writable so it can be updated on retry)\n Object.defineProperty(errorToThrow, STEP_TIMEOUT_MARKER, {\n value: meta,\n enumerable: false,\n writable: true,\n configurable: false,\n });\n }\n }\n\n throw errorToThrow;\n }\n // Re-throw other errors\n throw error;\n } finally {\n // Always clear the timeout to prevent leaks\n clearTimeout(timeoutId!);\n // Clean up external signal listener\n if (externalAbortHandler && externalSignal) {\n externalSignal.removeEventListener(\"abort\", externalAbortHandler);\n }\n }\n}\n\n/**\n * Default retry configuration values.\n * @internal\n */\nconst DEFAULT_RETRY_CONFIG = {\n backoff: \"exponential\" as BackoffStrategy,\n initialDelay: 100,\n maxDelay: 30000,\n jitter: true,\n shouldRetry: () => true,\n onRetry: () => {},\n} as const;\n\n// =============================================================================\n// run() Function\n// =============================================================================\n\n/**\n * Execute a workflow with step-based error handling.\n *\n * ## When to Use run()\n *\n * Use `run()` when:\n * - Dependencies are dynamic (passed at runtime, not known at compile time)\n * - You don't need step caching or resume state\n * - Error types are known upfront and can be specified manually\n * - Building lightweight, one-off workflows\n *\n * For automatic error type inference from static dependencies, use `createWorkflow()`.\n *\n * ## Error union\n *\n * `run()` returns:\n * - **`catchUnexpected`**: Maps uncaught exceptions to your type E → `Result<T, E>`\n * - **No catchUnexpected**: Step errors pass through + `UnexpectedError` for exceptions → `Result<T, E | UnexpectedError>`\n *\n * When `E` is not specified, it defaults to `never`, giving `Result<T, UnexpectedError>`.\n *\n * @see createWorkflow - For static dependencies with auto error inference\n */\n\n/**\n * run() with catchUnexpected: closed union Result<T, E>.\n */\nfunction runFn<T, E, C = void>(\n fn: (context: { step: RunStep<E> }) => Promise<T> | T,\n options: RunOptionsWithCatch<E, C>\n): AsyncResult<T, E, unknown>;\n\n/**\n * run() without catchUnexpected.\n * Always adds UnexpectedError to the error union so callers know\n * uncaught exceptions are possible. Step errors pass through as-is.\n * When E is never (default), step is RunStep<unknown> so any operation is allowed.\n */\nfunction runFn<T, E = never, C = void>(\n fn: (context: {\n step: [E] extends [never] ? RunStep<unknown> : RunStep<E>;\n }) => Promise<T> | T,\n options?: {\n onError?: (error: E | UnexpectedError, stepName?: string, ctx?: C) => void;\n onEvent?: (event: WorkflowEvent<E | UnexpectedError, C>, ctx: C) => void;\n workflowId?: string;\n workflowName?: string;\n context?: C;\n graph?: DeclaredGraph;\n /** @internal External signal for workflow-level cancellation. */\n _workflowSignal?: AbortSignal;\n }\n): AsyncResult<T, E | UnexpectedError, unknown>;\n\n/**\n * run() with dependencies: auto-bound steps and automatic error inference.\n *\n * Pass your functions as the first argument; the callback receives a steps\n * object mirroring them. Calling `s.getUser(id)` behaves exactly like\n * `step('getUser', () => getUser(id))` — unwraps ok, early-exits on err —\n * and the result's error union is inferred from the deps. No type\n * parameters, no string IDs, no thunks.\n *\n * Plain (non-Result) functions are valid deps: their values pass through\n * and their throws become UnexpectedError, so existing code works unchanged\n * and can adopt typed errors incrementally.\n *\n * @example\n * ```typescript\n * const result = await run({ getOrder, getUser, charge }, async (s) => {\n * const order = await s.getOrder(orderId);\n * const user = await s.getUser(order.userId);\n * return s.charge(order.total);\n * });\n * // result.error: OrderNotFound | UserNotFound | ChargeDeclined | UnexpectedError\n * ```\n */\nfunction runFn<const Deps extends Record<string, AnyFunction>, T, C = void>(\n deps: Deps,\n fn: (\n steps: BoundSteps<Deps>,\n context: {\n step: [ErrorsOf<Deps>] extends [never]\n ? RunStep<unknown>\n : RunStep<ErrorsOf<Deps>>;\n }\n ) => Promise<T> | T,\n options?: {\n onError?: (\n error: ErrorsOf<Deps> | UnexpectedError,\n stepName?: string,\n ctx?: C\n ) => void;\n onEvent?: (\n event: WorkflowEvent<ErrorsOf<Deps> | UnexpectedError, C>,\n ctx: C\n ) => void;\n workflowId?: string;\n workflowName?: string;\n context?: C;\n graph?: DeclaredGraph;\n /** @internal External signal for workflow-level cancellation. */\n _workflowSignal?: AbortSignal;\n }\n): AsyncResult<T, ErrorsOf<Deps> | UnexpectedError, unknown>;\n\n// Implementation\nasync function runFn<T, E, C = void>(\n fnOrDeps:\n | ((context: { step: RunStep<E> }) => Promise<T> | T)\n | Record<string, AnyFunction>,\n optionsOrFn?:\n | RunOptions<E, C>\n | ((\n steps: BoundSteps<Record<string, AnyFunction>>,\n context: { step: RunStep<E> }\n ) => Promise<T> | T),\n maybeOptions?: RunOptions<E, C>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): AsyncResult<T, any> {\n // Deps-first form: run(deps, fn, options?) — bind deps as steps and\n // re-enter through the classic form.\n if (typeof fnOrDeps !== \"function\") {\n const deps = fnOrDeps;\n const boundFn = optionsOrFn as (\n steps: BoundSteps<Record<string, AnyFunction>>,\n context: { step: RunStep<E> }\n ) => Promise<T> | T;\n if (typeof boundFn !== \"function\") {\n throw new TypeError(\n \"[awaitly] run(deps, fn) requires a callback as the second argument. \" +\n \"Example: run({ getUser }, async (s) => s.getUser(id))\"\n );\n }\n // Re-enter the implementation with the classic (fn, options) shape;\n // cast past the public overloads (same approach as runInternal).\n const classicRun = runFn as unknown as (\n fn: (context: { step: RunStep<E> }) => Promise<T> | T,\n options?: RunOptions<E, C>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ) => AsyncResult<T, any>;\n return classicRun(\n ({ step }) => boundFn(bindSteps(deps, step as StepCallable), { step }),\n maybeOptions\n );\n }\n\n const fn = fnOrDeps;\n const options = optionsOrFn as RunOptions<E, C> | undefined;\n const {\n onError,\n onEvent,\n catchUnexpected,\n workflowId: providedWorkflowId,\n workflowName,\n context,\n graph,\n _workflowSignal,\n } = options && typeof options === \"object\"\n ? (options as RunOptions<E, C>)\n : ({} as RunOptions<E, C>);\n\n const workflowId = providedWorkflowId ?? crypto.randomUUID();\n\n // Strict graph validation: when a declared graph is provided, every runtime\n // step/decision id must be one of its state ids. Ids with {placeholder}\n // segments (e.g. step.forEach's \"item-{i}\") match any value in that slot.\n const declaredIds = graph\n ? new Set(\n Array.isArray(graph)\n ? (graph as readonly string[])\n : (graph as {\n states: ReadonlyArray<{ id: string; semanticId?: string }>;\n }).states.map((state) => state.semanticId ?? state.id)\n )\n : undefined;\n const declaredPatterns = declaredIds\n ? [...declaredIds]\n .filter((id) => id.includes(\"{\"))\n .map(\n (id) =>\n new RegExp(\n `^${id.replaceAll(/[.*+?^$()[\\]\\\\|]/g, String.raw`\\$&`).replaceAll(/\\{[^}]*\\}/g, \".+\")}$`\n )\n )\n : undefined;\n const assertDeclared = (id: string, kind: \"step\" | \"decision\"): void => {\n if (!declaredIds || declaredIds.has(id)) return;\n if (declaredPatterns?.some((re) => re.test(id))) return;\n throw new Error(\n `[awaitly] ${kind} id \"${id}\" is not in the declared workflow graph. ` +\n `Declared ids: ${[...declaredIds].join(\", \")}. ` +\n `Either add it to the graph or remove the graph option.`\n );\n };\n const effectiveCatchUnexpected = catchUnexpected ?? defaultCatchUnexpected;\n\n // Track active scopes as a stack for proper nesting\n // When a step succeeds, only the innermost race scope gets the winner\n const activeScopeStack: Array<{ scopeId: string; type: ScopeType; winnerId?: string }> = [];\n\n // Counter for generating unique step IDs\n let stepIdCounter = 0;\n\n // Generate a unique step ID\n // Uses stepKey when provided (for cache stability), otherwise generates a unique ID.\n // Note: name is NOT used for stepId because multiple concurrent steps may share a name,\n // which would cause them to collide in activeSteps tracking and race winner detection.\n const generateStepId = (stepKey?: string): string => {\n return stepKey ?? `step_${++stepIdCounter}`;\n };\n\n const emitEvent = (event: WorkflowEvent<E | UnexpectedError, C>) => {\n // Add context to event only if:\n // 1. Event doesn't already have context (preserves replayed events or per-step overrides)\n // 2. Workflow actually has a context (don't add context: undefined property)\n const eventWithContext =\n event.context !== undefined || context === undefined\n ? event\n : ({ ...event, context: context as C } as WorkflowEvent<E | UnexpectedError, C>);\n\n const eventWithName =\n workflowName !== undefined && eventWithContext.workflowName === undefined\n ? ({ ...eventWithContext, workflowName } as WorkflowEvent<E | UnexpectedError, C>)\n : eventWithContext;\n \n // Track first successful step in the innermost race scope for winnerId\n if (eventWithName.type === \"step_success\") {\n // Use the stepId from the event (already generated at step start)\n const stepId = eventWithName.stepId;\n\n // Find innermost race scope (search from end of stack)\n for (let i = activeScopeStack.length - 1; i >= 0; i--) {\n const scope = activeScopeStack[i];\n if (scope.type === \"race\" && !scope.winnerId) {\n scope.winnerId = stepId;\n break; // Only update innermost race scope\n }\n }\n }\n onEvent?.(eventWithName, context as C);\n };\n\n // Use the exported early exit function with proper type parameter\n const earlyExit = createEarlyExit<E>;\n\n // Local type guard that narrows to EarlyExit<E> specifically\n const isEarlyExitE = (e: unknown): e is EarlyExit<E> => isEarlyExit(e);\n\n // Step errors always pass through — they are typed Result errors.\n // Only truly uncaught exceptions get mapped via effectiveCatchUnexpected.\n const wrapForStep = (\n error: unknown,\n _meta?: StepFailureMeta\n ): E => {\n return error as E;\n };\n\n // Helper to check if a value is a Result (has ok property) vs a function\n const isResultLike = (value: unknown): value is Result<unknown, unknown, unknown> | Promise<Result<unknown, unknown, unknown>> => {\n if (typeof value === 'function') return false;\n if (value && typeof value === 'object' && 'ok' in value) return true;\n // Check for Promise<Result> - it will have a then method\n if (value && typeof value === 'object' && 'then' in value && typeof (value as Promise<unknown>).then === 'function') return true;\n return false;\n };\n\n try {\n // Step function: requires step('id', fn, opts) or step('id', result, opts)\n const stepFn = <T, StepE, StepC = unknown>(\n id: string,\n operationOrResult: (() => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>) | Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n stepOptions?: StepOptions\n ): Promise<T> => {\n return (async () => {\n // Validate required string ID\n if (typeof id !== 'string' || id.length === 0) {\n throw new Error(\n '[awaitly] step() requires an explicit string ID as the first argument. ' +\n 'Example: step(\"fetchUser\", () => fetchUser(id))'\n );\n }\n assertDeclared(id, \"step\");\n\n const parsedOptions: StepOptions = stepOptions ?? {};\n const stepMetadata = extractStepMetadata(parsedOptions);\n\n // Name is always derived from ID\n const stepName = id;\n const stepKey = parsedOptions.key ?? id; // For general events (step_start, step_success, etc.)\n const explicitKey = parsedOptions.key ?? id; // For step_complete and caching (ID is used when no key)\n const { description: stepDescription, retry: retryConfig, timeout: timeoutConfig } = parsedOptions;\n const stepId = generateStepId(stepKey);\n const hasEventListeners = onEvent;\n const overallStartTime = hasEventListeners ? performance.now() : 0;\n\n // Determine if this is a direct Result or a function\n const isDirectResult = isResultLike(operationOrResult);\n const operation = isDirectResult\n ? () => operationOrResult as Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>\n : operationOrResult as () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>;\n\n // Build effective retry config with defaults\n // Ensure at least 1 attempt (0 would skip the loop entirely and crash)\n const maxAttempts = Math.max(1, retryConfig?.attempts ?? 1);\n const effectiveRetry = {\n attempts: maxAttempts,\n backoff: retryConfig?.backoff ?? DEFAULT_RETRY_CONFIG.backoff,\n initialDelay: retryConfig?.initialDelay ?? DEFAULT_RETRY_CONFIG.initialDelay,\n maxDelay: retryConfig?.maxDelay ?? DEFAULT_RETRY_CONFIG.maxDelay,\n jitter: retryConfig?.jitter ?? DEFAULT_RETRY_CONFIG.jitter,\n shouldRetry: retryConfig?.shouldRetry ?? DEFAULT_RETRY_CONFIG.shouldRetry,\n onRetry: retryConfig?.onRetry ?? DEFAULT_RETRY_CONFIG.onRetry,\n };\n\n // Emit step_start only once (before first attempt)\n if (onEvent) {\n emitEvent({\n type: \"step_start\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n description: stepDescription,\n ts: Date.now(),\n ...(stepMetadata && { metadata: stepMetadata }),\n });\n }\n\n let lastResult: Result<T, StepE, StepC> | undefined;\n\n for (let attempt = 1; attempt <= effectiveRetry.attempts; attempt++) {\n const attemptStartTime = hasEventListeners ? performance.now() : 0;\n\n try {\n // Execute operation with optional timeout\n let result: Result<T, StepE, StepC>;\n\n if (timeoutConfig) {\n // Wrap with timeout, passing workflow signal for { signal: true } steps\n result = await executeWithTimeout(\n operation as () => Promise<Result<T, StepE, StepC>>,\n timeoutConfig,\n { name: stepName, key: stepKey, attempt },\n _workflowSignal\n );\n } else {\n result = await operation();\n }\n\n // Success case\n if (result.ok) {\n const durationMs = performance.now() - overallStartTime;\n emitEvent({\n type: \"step_success\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n description: stepDescription,\n ts: Date.now(),\n durationMs,\n ...(stepMetadata && { metadata: stepMetadata }),\n });\n if (explicitKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey: explicitKey,\n name: stepName,\n description: stepDescription,\n ts: Date.now(),\n durationMs,\n result,\n ...(stepMetadata && { metadata: stepMetadata }),\n });\n }\n return result.value;\n }\n\n // Result error case - check if we should retry\n lastResult = result;\n\n if (attempt < effectiveRetry.attempts && effectiveRetry.shouldRetry(result.error, attempt)) {\n const delay = calculateRetryDelay(attempt, effectiveRetry);\n\n // Emit retry event\n emitEvent({\n type: \"step_retry\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n attempt: attempt + 1,\n maxAttempts: effectiveRetry.attempts,\n delayMs: delay,\n error: result.error as unknown as E,\n ...(stepMetadata && { metadata: stepMetadata }),\n diagnostics: buildStepErrorPayload(result.error, parsedOptions.errorMeta, 'result', attempt, performance.now() - overallStartTime),\n });\n\n effectiveRetry.onRetry(result.error, attempt, delay);\n await sleep(delay);\n continue;\n }\n\n // No more retries or shouldRetry returned false - emit exhausted event if we retried\n if (effectiveRetry.attempts > 1) {\n emitEvent({\n type: \"step_retries_exhausted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: performance.now() - overallStartTime,\n attempts: attempt,\n lastError: result.error as unknown as E,\n ...(stepMetadata && { metadata: stepMetadata }),\n diagnostics: buildStepErrorPayload(result.error, parsedOptions.errorMeta, 'result', attempt, performance.now() - overallStartTime),\n });\n }\n\n // Fall through to final error handling below\n break;\n\n } catch (thrown) {\n const durationMs = performance.now() - attemptStartTime;\n\n // Handle timeout with 'option' behavior - return undefined as success\n if (isTimeoutOptionMarker(thrown)) {\n const timeoutMs = thrown.ms;\n emitEvent({\n type: \"step_timeout\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n timeoutMs,\n attempt,\n ...(stepMetadata && { metadata: stepMetadata }),\n diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, 'timeout', attempt),\n });\n emitEvent({\n type: \"step_success\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n description: stepDescription,\n ts: Date.now(),\n durationMs: performance.now() - overallStartTime,\n ...(stepMetadata && { metadata: stepMetadata }),\n });\n if (explicitKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey: explicitKey,\n name: stepName,\n description: stepDescription,\n ts: Date.now(),\n durationMs: performance.now() - overallStartTime,\n result: ok(undefined),\n ...(stepMetadata && { metadata: stepMetadata }),\n });\n }\n // Return undefined as success value (timeout was treated as optional)\n return undefined as T;\n }\n\n // Handle early exit - propagate immediately\n if (isEarlyExitE(thrown)) {\n emitEvent({\n type: \"step_aborted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n description: stepDescription,\n ts: Date.now(),\n durationMs,\n ...(stepMetadata && { metadata: stepMetadata }),\n });\n throw thrown;\n }\n\n // Handle timeout error\n if (isStepTimeoutError(thrown)) {\n // Get timeout metadata from the error (works for both standard and custom errors)\n const timeoutMeta = getStepTimeoutMeta(thrown);\n const timeoutMs = timeoutConfig?.ms ?? timeoutMeta?.timeoutMs ?? 0;\n emitEvent({\n type: \"step_timeout\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n timeoutMs,\n attempt,\n ...(stepMetadata && { metadata: stepMetadata }),\n diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, 'timeout', attempt),\n });\n\n // Check if we should retry after timeout\n if (attempt < effectiveRetry.attempts && effectiveRetry.shouldRetry(thrown, attempt)) {\n const delay = calculateRetryDelay(attempt, effectiveRetry);\n\n emitEvent({\n type: \"step_retry\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n attempt: attempt + 1,\n maxAttempts: effectiveRetry.attempts,\n delayMs: delay,\n error: thrown as unknown as E,\n ...(stepMetadata && { metadata: stepMetadata }),\n diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, 'timeout', attempt, performance.now() - overallStartTime),\n });\n\n effectiveRetry.onRetry(thrown, attempt, delay);\n await sleep(delay);\n continue;\n }\n\n // No more retries - emit exhausted if we retried\n if (effectiveRetry.attempts > 1) {\n emitEvent({\n type: \"step_retries_exhausted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: performance.now() - overallStartTime,\n attempts: attempt,\n lastError: thrown as unknown as E,\n ...(stepMetadata && { metadata: stepMetadata }),\n diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, 'timeout', attempt, performance.now() - overallStartTime),\n });\n }\n\n // Treat STEP_TIMEOUT as a typed error - exit directly without UnexpectedError wrapper\n // This provides better DX: users get STEP_TIMEOUT directly in result.error\n const totalDurationMs = performance.now() - overallStartTime;\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n description: stepDescription,\n ts: Date.now(),\n durationMs: totalDurationMs,\n error: thrown as unknown as E,\n ...(stepMetadata && { metadata: stepMetadata }),\n diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, 'timeout', attempt, totalDurationMs),\n });\n if (explicitKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey: explicitKey,\n name: stepName,\n description: stepDescription,\n ts: Date.now(),\n durationMs: totalDurationMs,\n result: err(thrown as unknown as E, { cause: thrown }),\n meta: { origin: \"throw\", thrown },\n ...(stepMetadata && { metadata: stepMetadata }),\n });\n }\n onError?.(thrown as unknown as E, stepName, context);\n throw earlyExit(thrown as unknown as E, { origin: \"throw\", thrown });\n }\n\n // Handle other thrown errors (continue to error handling below)\n\n // Check if we should retry thrown errors\n if (attempt < effectiveRetry.attempts && effectiveRetry.shouldRetry(thrown, attempt)) {\n const delay = calculateRetryDelay(attempt, effectiveRetry);\n\n emitEvent({\n type: \"step_retry\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n attempt: attempt + 1,\n maxAttempts: effectiveRetry.attempts,\n delayMs: delay,\n error: thrown as unknown as E,\n ...(stepMetadata && { metadata: stepMetadata }),\n diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, 'throw', attempt, performance.now() - overallStartTime),\n });\n\n effectiveRetry.onRetry(thrown, attempt, delay);\n await sleep(delay);\n continue;\n }\n\n // No more retries for thrown errors - emit exhausted if we retried\n if (effectiveRetry.attempts > 1 && !isStepTimeoutError(thrown)) {\n emitEvent({\n type: \"step_retries_exhausted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: performance.now() - overallStartTime,\n attempts: attempt,\n lastError: thrown as unknown as E,\n ...(stepMetadata && { metadata: stepMetadata }),\n diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, 'throw', attempt, performance.now() - overallStartTime),\n });\n }\n\n // Handle the error using effectiveCatchUnexpected\n const totalDurationMs = performance.now() - overallStartTime;\n\n let mappedError: E | UnexpectedError;\n try {\n mappedError = effectiveCatchUnexpected(thrown) as E | UnexpectedError;\n } catch (mapperError) {\n throw createMapperException(mapperError);\n }\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n description: stepDescription,\n ts: Date.now(),\n durationMs: totalDurationMs,\n error: mappedError,\n ...(stepMetadata && { metadata: stepMetadata }),\n diagnostics: buildStepErrorPayload(thrown, parsedOptions.errorMeta, 'throw', attempt, totalDurationMs),\n });\n if (explicitKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey: explicitKey,\n name: stepName,\n description: stepDescription,\n ts: Date.now(),\n durationMs: totalDurationMs,\n result: err(mappedError, { cause: thrown }),\n meta: { origin: \"throw\", thrown },\n ...(stepMetadata && { metadata: stepMetadata }),\n });\n }\n onError?.(mappedError as E, stepName, context);\n throw earlyExit(mappedError as E, { origin: \"throw\", thrown });\n }\n }\n\n // All retries exhausted with Result error - handle final error\n // At this point lastResult must be an error result (we only reach here on error)\n const errorResult = lastResult as Err<StepE, StepC>;\n const totalDurationMs = performance.now() - overallStartTime;\n const wrappedError = wrapForStep(errorResult.error, {\n origin: \"result\",\n resultCause: errorResult.cause,\n });\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n description: stepDescription,\n ts: Date.now(),\n durationMs: totalDurationMs,\n error: wrappedError,\n ...(stepMetadata && { metadata: stepMetadata }),\n diagnostics: buildStepErrorPayload(errorResult.error, parsedOptions.errorMeta, 'result', effectiveRetry.attempts, totalDurationMs),\n });\n if (explicitKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey: explicitKey,\n name: stepName,\n description: stepDescription,\n ts: Date.now(),\n durationMs: totalDurationMs,\n result: errorResult,\n meta: { origin: \"result\", resultCause: errorResult.cause },\n ...(stepMetadata && { metadata: stepMetadata }),\n });\n }\n onError?.(wrappedError as unknown as E, stepName, context);\n throw earlyExit(wrappedError as unknown as E, {\n origin: \"result\",\n resultCause: errorResult.cause,\n });\n })();\n };\n\n stepFn.try = <T, Err>(\n id: string,\n operation: () => T | Promise<T>,\n opts:\n | {\n error: Err;\n key?: string;\n ttl?: number;\n retry?: RetryOptions<Err>;\n timeout?: TimeoutOptions;\n compensate?: (value: T) => void | Promise<void>;\n }\n | {\n onError: (cause: unknown) => Err;\n key?: string;\n ttl?: number;\n retry?: RetryOptions<Err>;\n timeout?: TimeoutOptions;\n compensate?: (value: T) => void | Promise<void>;\n }\n ): Promise<T> => {\n // Validate required string ID\n if (typeof id !== 'string' || id.length === 0) {\n throw new Error(\n '[awaitly] step.try() requires an explicit string ID as the first argument. ' +\n 'Example: step.try(\"parse\", () => JSON.parse(str), { error: \"PARSE_ERROR\" })'\n );\n }\n assertDeclared(id, \"step\");\n\n const mapToError = \"error\" in opts ? () => opts.error : opts.onError;\n\n // If retry or timeout is requested, delegate to step.retry (which handles both).\n if (opts.retry || opts.timeout) {\n return stepFn.retry(\n id,\n async () => {\n try {\n return ok(await operation());\n } catch (cause) {\n return err(mapToError(cause), { cause });\n }\n },\n {\n attempts: opts.retry?.attempts ?? 1,\n ...(opts.retry ?? {}),\n key: opts.key,\n timeout: opts.timeout,\n }\n );\n }\n\n const stepKey = opts.key ?? id; // Use id as key if not provided\n const stepName = id; // Name is always the id\n const stepId = id;\n const hasEventListeners = onEvent;\n\n return (async () => {\n const startTime = hasEventListeners ? performance.now() : 0;\n\n if (onEvent) {\n emitEvent({\n type: \"step_start\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n });\n }\n\n try {\n const value = await operation();\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_success\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n });\n // Emit step_complete for keyed steps (for state persistence)\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: ok(value),\n });\n }\n return value;\n } catch (error) {\n const mapped = mapToError(error);\n const durationMs = performance.now() - startTime;\n const wrappedError = wrapForStep(mapped, { origin: \"throw\", thrown: error });\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: wrappedError,\n });\n // Emit step_complete for keyed steps (for state persistence)\n // Note: For step.try errors, we encode the mapped error, not the original thrown\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: err(mapped, { cause: error }),\n meta: { origin: \"throw\", thrown: error },\n });\n }\n onError?.(wrappedError as unknown as E, stepName, context);\n throw earlyExit(wrappedError as unknown as E, { origin: \"throw\", thrown: error });\n }\n })();\n };\n\n // step.fromResult: Execute a Result-returning function and map its typed error\n stepFn.fromResult = <T, ResultE, Err>(\n id: string,\n operation: () => Result<T, ResultE, unknown> | AsyncResult<T, ResultE, unknown>,\n opts:\n | { error: Err; key?: string }\n | { onError: (resultError: ResultE) => Err; key?: string }\n ): Promise<T> => {\n // Validate required string ID\n if (typeof id !== 'string' || id.length === 0) {\n throw new Error(\n '[awaitly] step.fromResult() requires an explicit string ID as the first argument. ' +\n 'Example: step.fromResult(\"callProvider\", () => callProvider(input), { onError: (e) => ({ type: \"FAILED\" }) })'\n );\n }\n assertDeclared(id, \"step\");\n\n const stepKey = opts.key ?? id; // Use id as key if not provided\n const stepName = id; // Name is always the id\n const stepId = id;\n const mapToError = \"error\" in opts ? () => opts.error : opts.onError;\n const hasEventListeners = onEvent;\n\n return (async () => {\n const startTime = hasEventListeners ? performance.now() : 0;\n\n if (onEvent) {\n emitEvent({\n type: \"step_start\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n });\n }\n\n const result = await operation();\n\n if (result.ok) {\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_success\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n });\n // Emit step_complete for keyed steps (for state persistence)\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: ok(result.value),\n });\n }\n return result.value;\n } else {\n const mapped = mapToError(result.error);\n const durationMs = performance.now() - startTime;\n // For fromResult, the cause is the original result.error (what got mapped)\n // This is analogous to step.try using thrown exception as cause\n const wrappedError = wrapForStep(mapped, {\n origin: \"result\",\n resultCause: result.error,\n });\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: wrappedError,\n });\n // Emit step_complete for keyed steps (for state persistence)\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: err(mapped, { cause: result.error }),\n meta: { origin: \"result\", resultCause: result.error },\n });\n }\n onError?.(wrappedError as unknown as E, stepName, context);\n throw earlyExit(wrappedError as unknown as E, {\n origin: \"result\",\n resultCause: result.error,\n });\n }\n })();\n };\n\n // step.fromNullable: Execute an operation returning T | null/undefined and convert to typed error\n stepFn.fromNullable = <T, Err>(\n id: string,\n operation: () => T | null | undefined | Promise<T | null | undefined>,\n onNull: () => Err,\n options?: { key?: string; ttl?: number }\n ): Promise<T> => {\n if (typeof id !== 'string' || id.length === 0) {\n throw new Error(\n '[awaitly] step.fromNullable() requires an explicit string ID as the first argument. ' +\n 'Example: step.fromNullable(\"getUser\", () => db.find(id), () => ({ type: \"NOT_FOUND\" }))'\n );\n }\n return stepFn(\n id,\n async () => {\n const value = await operation();\n return value != null ? ok(value) : err(onNull());\n },\n options\n );\n };\n\n // step.retry: Execute an operation with retry and optional timeout\n stepFn.retry = <T, StepE, StepC = unknown>(\n id: string,\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n options: RetryOptions<StepE> & { key?: string; timeout?: TimeoutOptions }\n ): Promise<T> => {\n // Validate required string ID\n if (typeof id !== 'string' || id.length === 0) {\n throw new Error(\n '[awaitly] step.retry() requires an explicit string ID as the first argument. ' +\n 'Example: step.retry(\"fetchData\", () => fetchData(), { attempts: 3 })'\n );\n }\n\n // Delegate to stepFn with retry options merged into StepOptions\n // Use key for caching if provided, otherwise use id\n return stepFn(id, operation, {\n key: options.key ?? id,\n retry: {\n attempts: options.attempts,\n backoff: options.backoff,\n initialDelay: options.initialDelay,\n maxDelay: options.maxDelay,\n jitter: options.jitter,\n shouldRetry: options.shouldRetry as RetryOptions[\"shouldRetry\"],\n onRetry: options.onRetry as RetryOptions[\"onRetry\"],\n },\n timeout: options.timeout,\n });\n };\n\n // step.withTimeout: Execute an operation with a timeout\n stepFn.withTimeout = <T, StepE, StepC = unknown>(\n id: string,\n operation:\n | (() => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>)\n | ((signal: AbortSignal) => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>),\n options: TimeoutOptions & { key?: string }\n ): Promise<T> => {\n // Validate required string ID\n if (typeof id !== 'string' || id.length === 0) {\n throw new Error(\n '[awaitly] step.withTimeout() requires an explicit string ID as the first argument. ' +\n 'Example: step.withTimeout(\"slowOp\", () => slowOp(), { ms: 5000 })'\n );\n }\n\n // Delegate to stepFn with timeout options\n // The signal handling happens in executeWithTimeout when timeout.signal is true\n // Use key for caching if provided, otherwise use id\n return stepFn(\n id,\n operation as () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n {\n key: options.key ?? id,\n timeout: options,\n }\n );\n };\n\n // step.sleep: Pause execution for a specified duration\n stepFn.sleep = (\n id: string,\n duration: DurationInput,\n options?: { key?: string; ttl?: number; description?: string; signal?: AbortSignal }\n ): Promise<void> => {\n // Validate required string ID\n if (typeof id !== 'string' || id.length === 0) {\n throw new Error(\n '[awaitly] step.sleep() requires an explicit string ID as the first argument. ' +\n 'Example: step.sleep(\"delay\", \"5s\")'\n );\n }\n\n // Parse duration - inline to avoid importing duration module\n const d = typeof duration === \"string\" ? parseDurationString(duration) : duration;\n if (!d) {\n throw new Error(`step.sleep: invalid duration '${duration}'`);\n }\n const ms = d.millis;\n const userSignal = options?.signal;\n\n // Delegate to stepFn with a cancellation-aware sleep operation\n // Use key for caching if provided, otherwise use id\n return stepFn(\n id,\n async (): AsyncResult<void, never> => {\n // Check if already aborted (workflow or user signal)\n if (_workflowSignal?.aborted || userSignal?.aborted) {\n const e = new Error(\"Sleep aborted\");\n e.name = \"AbortError\";\n throw e;\n }\n\n return new Promise<Result<void, never>>((resolve, reject) => {\n // Using object to avoid prefer-const warning while allowing\n // onAbort to reference the timeout before it's assigned\n const state = { timeoutId: undefined as ReturnType<typeof setTimeout> | undefined };\n\n const onAbort = () => {\n if (state.timeoutId) clearTimeout(state.timeoutId);\n const e = new Error(\"Sleep aborted\");\n e.name = \"AbortError\";\n reject(e);\n };\n\n _workflowSignal?.addEventListener(\"abort\", onAbort, { once: true });\n userSignal?.addEventListener(\"abort\", onAbort, { once: true });\n\n state.timeoutId = setTimeout(() => {\n _workflowSignal?.removeEventListener(\"abort\", onAbort);\n userSignal?.removeEventListener(\"abort\", onAbort);\n resolve(ok(undefined));\n }, ms);\n });\n },\n {\n key: options?.key ?? id,\n description: options?.description,\n }\n );\n };\n\n // step.all: Execute parallel operations with scope events\n // 1. Object form: step.all(name, { key: fn | { fn, errors } })\n // 2. Array form: step.all(name, () => allAsync([...]))\n stepFn.all = ((...args: unknown[]): Promise<unknown> => {\n if (typeof args[0] !== \"string\") {\n throw new TypeError(\n \"step.all(name, ...): first argument must be a string (step name). Example: step.all('Fetch data', { user: () => fetchUser(), posts: () => fetchPosts() })\"\n );\n }\n const name = args[0] as string;\n const second = args[1];\n if (typeof second === \"function\") {\n return executeParallelArray(name, second as () => MaybeAsyncResult<unknown[], unknown, unknown>);\n }\n if (second && typeof second === \"object\" && !Array.isArray(second)) {\n const rawOperations = second as Record<string, (() => MaybeAsyncResult<unknown, unknown, unknown>) | ParallelOperationDescriptor<unknown, readonly string[]>>;\n const normalizedOperations = normalizeParallelOperations(rawOperations);\n return executeParallelNamed(normalizedOperations, { name });\n }\n throw new TypeError(\n \"step.all(name, ...): second argument must be a function (array form) or an object of operations (object form).\"\n );\n }) as RunStep<E>[\"all\"];\n\n function normalizeParallelOperations(\n rawOperations: Record<string, (() => MaybeAsyncResult<unknown, unknown, unknown>) | ParallelOperationDescriptor<unknown, readonly string[]>>\n ): Record<string, () => MaybeAsyncResult<unknown, unknown, unknown>> {\n const out: Record<string, () => MaybeAsyncResult<unknown, unknown, unknown>> = {};\n for (const [key, value] of Object.entries(rawOperations)) {\n if (typeof value === \"function\") {\n out[key] = value;\n } else if (value && typeof value === \"object\" && \"fn\" in value) {\n out[key] = value.fn;\n } else {\n throw new TypeError(`step.all: operation \"${key}\" must be a function or { fn, errors? } object`);\n }\n }\n return out;\n }\n\n // Array form implementation\n function executeParallelArray<T>(\n name: string,\n operation: () => MaybeAsyncResult<T[], unknown, unknown>\n ): Promise<T[]> {\n const scopeId = `scope_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n return (async () => {\n const startTime = performance.now();\n let scopeEnded = false;\n\n // Push this scope onto the stack for proper nesting tracking\n activeScopeStack.push({ scopeId, type: \"parallel\" });\n\n // Helper to emit scope_end exactly once\n const emitScopeEnd = () => {\n if (scopeEnded) return;\n scopeEnded = true;\n // Pop this scope from the stack\n const idx = activeScopeStack.findIndex(s => s.scopeId === scopeId);\n if (idx !== -1) activeScopeStack.splice(idx, 1);\n emitEvent({\n type: \"scope_end\",\n workflowId,\n scopeId,\n ts: Date.now(),\n durationMs: performance.now() - startTime,\n });\n };\n\n // Emit scope_start event\n emitEvent({\n type: \"scope_start\",\n workflowId,\n scopeId,\n scopeType: \"parallel\",\n name,\n ts: Date.now(),\n });\n\n try {\n const result = await operation();\n\n // Emit scope_end before processing result\n emitScopeEnd();\n\n if (!result.ok) {\n onError?.(result.error as unknown as E, name, context);\n throw earlyExit(result.error as unknown as E, {\n origin: \"result\",\n resultCause: result.cause,\n });\n }\n\n return result.value;\n } catch (error) {\n // Always emit scope_end in finally-like fashion\n emitScopeEnd();\n throw error;\n }\n })();\n }\n\n // Named object form implementation - execute each operation in parallel\n function executeParallelNamed<T extends Record<string, unknown>>(\n operations: Record<string, () => MaybeAsyncResult<unknown, unknown, unknown>>,\n options: { name?: string }\n ): Promise<T> {\n const keys = Object.keys(operations);\n const name = options.name ?? `Parallel(${keys.join(\", \")})`;\n const scopeId = `scope_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n return (async () => {\n const startTime = performance.now();\n let scopeEnded = false;\n\n // Push this scope onto the stack for proper nesting tracking\n activeScopeStack.push({ scopeId, type: \"parallel\" });\n\n // Helper to emit scope_end exactly once\n const emitScopeEnd = () => {\n if (scopeEnded) return;\n scopeEnded = true;\n const idx = activeScopeStack.findIndex(s => s.scopeId === scopeId);\n if (idx !== -1) activeScopeStack.splice(idx, 1);\n emitEvent({\n type: \"scope_end\",\n workflowId,\n scopeId,\n ts: Date.now(),\n durationMs: performance.now() - startTime,\n });\n };\n\n // Emit scope_start event with operation names in metadata\n emitEvent({\n type: \"scope_start\",\n workflowId,\n scopeId,\n scopeType: \"parallel\",\n name,\n ts: Date.now(),\n });\n\n try {\n // Execute all operations in parallel, fail-fast on first error\n const results = await new Promise<{ key: string; result: Result<unknown, unknown, unknown> }[]>((resolve) => {\n if (keys.length === 0) {\n resolve([]);\n return;\n }\n\n let settled = false;\n let pendingCount = keys.length;\n const resultArray: { key: string; result: Result<unknown, unknown, unknown> }[] = new Array(keys.length);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const index = i;\n\n Promise.resolve(operations[key]())\n .catch((reason) => err(\n { type: \"PROMISE_REJECTED\" as const, cause: reason },\n { cause: { type: \"PROMISE_REJECTION\" as const, reason } }\n ))\n .then((result) => {\n if (settled) return;\n\n // Fail-fast: if any operation fails, resolve immediately with just the failed entry\n if (!result.ok) {\n settled = true;\n resolve([{ key, result }]);\n return;\n }\n\n resultArray[index] = { key, result };\n pendingCount--;\n\n if (pendingCount === 0) {\n resolve(resultArray);\n }\n });\n }\n });\n\n // Emit scope_end before processing results\n emitScopeEnd();\n\n // Check for errors and build result object\n const output: Record<string, unknown> = {};\n for (const { key, result } of results) {\n if (!result.ok) {\n onError?.(result.error as unknown as E, key, context);\n throw earlyExit(result.error as unknown as E, {\n origin: \"result\",\n resultCause: result.cause,\n });\n }\n output[key] = result.value;\n }\n\n return output as T;\n } catch (error) {\n // Always emit scope_end in finally-like fashion\n emitScopeEnd();\n throw error;\n }\n })();\n }\n\n // step.race: Execute a race operation with scope events\n stepFn.race = <T, StepE, StepC>(\n name: string,\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>\n ): Promise<T> => {\n const scopeId = `scope_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n return (async () => {\n const startTime = performance.now();\n let scopeEnded = false;\n\n // Push this race scope onto the stack to track the first successful step as winner\n const scopeEntry = { scopeId, type: \"race\" as const, winnerId: undefined as string | undefined };\n activeScopeStack.push(scopeEntry);\n\n // Helper to emit scope_end exactly once, including winnerId\n const emitScopeEnd = () => {\n if (scopeEnded) return;\n scopeEnded = true;\n // Pop this scope from the stack\n const idx = activeScopeStack.findIndex(s => s.scopeId === scopeId);\n if (idx !== -1) activeScopeStack.splice(idx, 1);\n emitEvent({\n type: \"scope_end\",\n workflowId,\n scopeId,\n ts: Date.now(),\n durationMs: performance.now() - startTime,\n winnerId: scopeEntry.winnerId,\n });\n };\n\n // Emit scope_start event\n emitEvent({\n type: \"scope_start\",\n workflowId,\n scopeId,\n scopeType: \"race\",\n name,\n ts: Date.now(),\n });\n\n try {\n const result = await operation();\n\n // Emit scope_end before processing result\n emitScopeEnd();\n\n if (!result.ok) {\n onError?.(result.error as unknown as E, name, context);\n throw earlyExit(result.error as unknown as E, {\n origin: \"result\",\n resultCause: result.cause,\n });\n }\n\n return result.value;\n } catch (error) {\n // Always emit scope_end in finally-like fashion\n emitScopeEnd();\n throw error;\n }\n })();\n };\n\n // step.if: Mark a conditional for static analysis\n // Runtime: executes the condition and emits a decision event so\n // visualizers see which branch fired without manual instrumentation\n // Analyzer: extracts the id and conditionLabel for DecisionNode\n stepFn.if = <T extends boolean>(\n id: string,\n conditionLabel: string,\n condition: () => T\n ): T => {\n assertDeclared(id, \"decision\");\n const value = condition();\n emitEvent({\n type: \"decision\",\n workflowId,\n decisionId: id,\n label: conditionLabel,\n branch: value ? \"then\" : \"else\",\n value,\n ts: Date.now(),\n });\n return value;\n };\n\n // step.label: Alias for step.if - mark a conditional for static analysis\n // Use step.label for strict mode when conditionals contain step calls\n stepFn.label = stepFn.if;\n\n // step.branch: Execute a branch with explicit metadata for static analysis\n // Runtime: evaluates condition and executes appropriate arm\n // Analyzer: extracts branch metadata (conditionLabel, per-arm errors, out)\n stepFn.branch = async <\n T,\n const ThenErrs extends readonly string[] = readonly [],\n const ElseErrs extends readonly string[] = readonly [],\n const Out extends string | undefined = undefined,\n >(\n id: string,\n options: BranchOptions<T, ThenErrs, ElseErrs, Out>\n ): Promise<T> => {\n const { condition, then: thenFn, else: elseFn } = options;\n assertDeclared(id, \"decision\");\n const conditionResult = condition();\n const branch = conditionResult ? \"then\" : \"else\";\n const startTime = performance.now();\n // step.branch owns arm execution, so the decision is a real scope:\n // phase \"start\" before the arm runs, phase \"end\" after it settles.\n // Visualizers nest the arm's steps inside the taken branch.\n emitEvent({\n type: \"decision\",\n workflowId,\n decisionId: id,\n label: options.conditionLabel,\n branch,\n value: conditionResult,\n phase: \"start\",\n ts: Date.now(),\n });\n const emitEnd = () => {\n emitEvent({\n type: \"decision\",\n workflowId,\n decisionId: id,\n label: options.conditionLabel,\n branch,\n value: conditionResult,\n phase: \"end\",\n durationMs: performance.now() - startTime,\n ts: Date.now(),\n });\n };\n try {\n if (conditionResult) {\n return await thenFn();\n } else if (elseFn) {\n return await elseFn();\n }\n return undefined as T;\n } finally {\n emitEnd();\n }\n };\n\n // step.arm: Create an arm definition for use with step.branch\n // Runtime: returns the arm definition unchanged\n // Analyzer: extracts arm metadata\n stepFn.arm = <T, const Errs extends readonly string[] = readonly []>(\n fn: () => T | Promise<T>,\n errors?: Errs\n ): ArmDefinition<T, Errs> => {\n return { fn, errors };\n };\n\n // step.forEach: Execute a forEach loop with static analysis support\n // Supports both simple (run) and complex (item) forms\n stepFn.forEach = async <T, R>(\n _id: string,\n items: Iterable<T> | AsyncIterable<T>,\n options: ForEachRunOptions<T, R, readonly string[]> | ForEachItemOptions<T, R>\n ): Promise<R[]> => {\n const results: R[] = [];\n const maxIterations = options.maxIterations;\n let index = 0;\n\n // Check if this is the run form or item form\n const isRunForm = 'run' in options;\n\n // Convert items to async iterable for uniform handling\n const asyncItems = Symbol.asyncIterator in (items as object)\n ? (items as AsyncIterable<T>)\n : (async function* () { yield* items as Iterable<T>; })();\n\n for await (const item of asyncItems) {\n if (maxIterations !== undefined && index >= maxIterations) {\n break;\n }\n\n let result: R;\n if (isRunForm) {\n const runOptions = options as ForEachRunOptions<T, R, readonly string[]>;\n result = await runOptions.run(item, index);\n } else {\n const itemOptions = options as ForEachItemOptions<T, R>;\n result = await itemOptions.item.handler(item, index, stepFn as unknown as RunStep<unknown>);\n }\n\n results.push(result);\n index++;\n }\n\n return results;\n };\n\n // step.item: Create an item handler for use with step.forEach\n // Runtime: returns the handler wrapped in a marker object\n // Analyzer: extracts the inner step structure\n stepFn.item = <T, R>(\n handler: (item: T, index: number, step: RunStep<unknown>) => R | Promise<R>\n ): ForEachItemHandler<T, R> => {\n return {\n __forEachItemHandler: true as const,\n handler,\n };\n };\n\n // step.dep: Wrap a dependency function for static analysis tracking\n // Runtime: returns the function unchanged\n // Analyzer: records the dependency name\n stepFn.dep = <T extends (...args: unknown[]) => unknown>(\n _name: string,\n fn: T\n ): T => {\n return fn;\n };\n\n // ===========================================================================\n // Effect-Style Ergonomics\n // ===========================================================================\n\n // step.workflow: Run sub-workflow (or any AsyncResult getter) as a step; same engine as step(id, getter, opts)\n stepFn.workflow = <T, SubE, StepC = unknown>(\n id: string,\n getter: () => AsyncResult<T, SubE, StepC>,\n options?: StepOptions\n ): Promise<T> => {\n return stepFn(id, getter as () => AsyncResult<T, E, StepC>, options);\n };\n\n // step.map: Map over array with parallel execution\n stepFn.map = async <T, U, StepE, StepC = unknown>(\n id: string,\n items: T[],\n mapper: (item: T, index: number) => AsyncResult<U, StepE, StepC>,\n options?: { concurrency?: number; key?: string }\n ): Promise<U[]> => {\n const concurrency = options?.concurrency ?? items.length;\n\n // Use allAsync for parallel execution with fail-fast\n return stepFn(\n id,\n () => {\n if (concurrency >= items.length) {\n // Full parallelism - execute all at once\n return allAsync(items.map((item, index) => mapper(item, index)));\n } else {\n // Limited concurrency - batch execution\n return (async () => {\n const results: U[] = [];\n for (let i = 0; i < items.length; i += concurrency) {\n const batch = items.slice(i, i + concurrency);\n const batchResult = await allAsync(\n batch.map((item, batchIndex) => mapper(item, i + batchIndex))\n );\n // allAsync returns Result<U[], E, C>, so we need to check if it's ok\n if (!batchResult.ok) {\n return batchResult; // Propagate the error\n }\n results.push(...batchResult.value);\n }\n return ok(results);\n })();\n }\n },\n { key: options?.key }\n );\n };\n\n // step.withFallback: Execute primary with fallback on error\n stepFn.withFallback = <T, E1, E2>(\n id: string,\n operation: () => AsyncResult<T, E1>,\n options: { on?: E1 & string; fallback: () => AsyncResult<T, E2>; key?: string }\n ): Promise<T> => {\n if (typeof id !== 'string' || id.length === 0) {\n throw new Error(\n '[awaitly] step.withFallback() requires an explicit string ID as the first argument. ' +\n 'Example: step.withFallback(\"getUser\", () => fetchUser(id), { fallback: () => fetchFromCache(id) })'\n );\n }\n assertDeclared(id, \"step\");\n\n const stepKey = options.key ?? id;\n const stepName = id;\n const stepId = generateStepId(stepKey);\n const hasEventListeners = onEvent;\n\n return (async () => {\n const startTime = hasEventListeners ? performance.now() : 0;\n\n if (onEvent) {\n emitEvent({\n type: \"step_start\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n });\n }\n\n // Try the primary operation\n let primaryResult: Result<T, E1>;\n try {\n primaryResult = await operation();\n } catch (thrown) {\n // If it's an earlyExit from a nested step, propagate\n if (isEarlyExitE(thrown)) {\n emitEvent({\n type: \"step_aborted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: performance.now() - startTime,\n });\n throw thrown;\n }\n\n // Primary threw — map to UnexpectedError\n let mappedError: E | UnexpectedError;\n try {\n mappedError = effectiveCatchUnexpected(thrown) as E | UnexpectedError;\n } catch (mapperError) {\n throw createMapperException(mapperError);\n }\n\n // If `on` is specified, only run fallback if it matches the mapped error\n if (options.on !== undefined && options.on !== mappedError) {\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: mappedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: err(mappedError, { cause: thrown }),\n meta: { origin: \"throw\", thrown },\n });\n }\n onError?.(mappedError as E, stepName, context);\n throw earlyExit(mappedError as E, { origin: \"throw\", thrown });\n }\n\n // Run fallback for thrown error\n let fallbackResultFromThrow: Result<T, E2>;\n try {\n fallbackResultFromThrow = await options.fallback();\n } catch (fallbackThrown) {\n if (isEarlyExitE(fallbackThrown)) {\n emitEvent({\n type: \"step_aborted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: performance.now() - startTime,\n });\n throw fallbackThrown;\n }\n let fallbackMappedError: E | UnexpectedError;\n try {\n fallbackMappedError = effectiveCatchUnexpected(fallbackThrown) as E | UnexpectedError;\n } catch (mapperError) {\n throw createMapperException(mapperError);\n }\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: fallbackMappedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: err(fallbackMappedError, { cause: fallbackThrown }),\n meta: { origin: \"throw\", thrown: fallbackThrown },\n });\n }\n onError?.(fallbackMappedError as E, stepName, context);\n throw earlyExit(fallbackMappedError as E, { origin: \"throw\", thrown: fallbackThrown });\n }\n\n if (fallbackResultFromThrow.ok) {\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_success\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: fallbackResultFromThrow,\n meta: { origin: \"fallback\" as const, fallbackUsed: true as const, fallbackReason: String(mappedError) },\n });\n }\n return fallbackResultFromThrow.value;\n } else {\n // Fallback also failed\n const durationMs = performance.now() - startTime;\n const wrappedError = wrapForStep(fallbackResultFromThrow.error, {\n origin: \"result\",\n resultCause: fallbackResultFromThrow.cause,\n });\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: wrappedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: fallbackResultFromThrow,\n meta: { origin: \"result\", resultCause: fallbackResultFromThrow.cause },\n });\n }\n onError?.(wrappedError as unknown as E, stepName, context);\n throw earlyExit(wrappedError as unknown as E, {\n origin: \"result\",\n resultCause: fallbackResultFromThrow.cause,\n });\n }\n }\n\n // Primary returned a result (didn't throw)\n if (primaryResult.ok) {\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_success\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: primaryResult,\n });\n }\n return primaryResult.value;\n }\n\n // Primary returned an error\n const primaryError = primaryResult.error;\n\n // If `on` is specified and doesn't match, earlyExit with primary error (no fallback)\n if (options.on !== undefined && options.on !== primaryError) {\n const durationMs = performance.now() - startTime;\n const wrappedError = wrapForStep(primaryError, {\n origin: \"result\",\n resultCause: primaryResult.cause,\n });\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: wrappedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: primaryResult,\n meta: { origin: \"result\", resultCause: primaryResult.cause },\n });\n }\n onError?.(wrappedError as unknown as E, stepName, context);\n throw earlyExit(wrappedError as unknown as E, {\n origin: \"result\",\n resultCause: primaryResult.cause,\n });\n }\n\n // Run fallback\n let fallbackResult: Result<T, E2>;\n try {\n fallbackResult = await options.fallback();\n } catch (thrown) {\n if (isEarlyExitE(thrown)) {\n emitEvent({\n type: \"step_aborted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: performance.now() - startTime,\n });\n throw thrown;\n }\n // Fallback threw — map via effectiveCatchUnexpected\n let mappedError: E | UnexpectedError;\n try {\n mappedError = effectiveCatchUnexpected(thrown) as E | UnexpectedError;\n } catch (mapperError) {\n throw createMapperException(mapperError);\n }\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: mappedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: err(mappedError, { cause: thrown }),\n meta: { origin: \"throw\", thrown },\n });\n }\n onError?.(mappedError as E, stepName, context);\n throw earlyExit(mappedError as E, { origin: \"throw\", thrown });\n }\n\n if (fallbackResult.ok) {\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_success\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: fallbackResult,\n meta: { origin: \"fallback\" as const, fallbackUsed: true as const, fallbackReason: String(primaryError) },\n });\n }\n return fallbackResult.value;\n }\n\n // Fallback also returned an error\n const durationMs = performance.now() - startTime;\n const wrappedError = wrapForStep(fallbackResult.error, {\n origin: \"result\",\n resultCause: fallbackResult.cause,\n });\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: wrappedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: fallbackResult,\n meta: { origin: \"result\", resultCause: fallbackResult.cause },\n });\n }\n onError?.(wrappedError as unknown as E, stepName, context);\n throw earlyExit(wrappedError as unknown as E, {\n origin: \"result\",\n resultCause: fallbackResult.cause,\n });\n })();\n };\n\n // step.withResource: Acquire/use/release lifecycle with guaranteed release\n stepFn.withResource = <T, R, AcquireE, UseE>(\n id: string,\n options: {\n acquire: () => AsyncResult<R, AcquireE>;\n use: (resource: R) => AsyncResult<T, UseE>;\n release: (resource: R) => void | Promise<void>;\n }\n ): Promise<T> => {\n if (typeof id !== 'string' || id.length === 0) {\n throw new Error(\n '[awaitly] step.withResource() requires an explicit string ID as the first argument. ' +\n 'Example: step.withResource(\"useDb\", { acquire: () => connect(), use: (db) => query(db), release: (db) => db.close() })'\n );\n }\n assertDeclared(id, \"step\");\n\n const stepKey = id;\n const stepName = id;\n const stepId = generateStepId(stepKey);\n const hasEventListeners = onEvent;\n\n return (async () => {\n const startTime = hasEventListeners ? performance.now() : 0;\n\n if (onEvent) {\n emitEvent({\n type: \"step_start\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n });\n }\n\n // Acquire\n let acquireResult: Result<R, AcquireE>;\n try {\n acquireResult = await options.acquire();\n } catch (thrown) {\n if (isEarlyExitE(thrown)) {\n emitEvent({\n type: \"step_aborted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: performance.now() - startTime,\n });\n throw thrown;\n }\n let mappedError: E | UnexpectedError;\n try {\n mappedError = effectiveCatchUnexpected(thrown) as E | UnexpectedError;\n } catch (mapperError) {\n throw createMapperException(mapperError);\n }\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: mappedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: err(mappedError, { cause: thrown }),\n meta: { origin: \"throw\", thrown },\n });\n }\n onError?.(mappedError as E, stepName, context);\n throw earlyExit(mappedError as E, { origin: \"throw\", thrown });\n }\n\n if (!acquireResult.ok) {\n // Acquire failed — no release needed\n const durationMs = performance.now() - startTime;\n const wrappedError = wrapForStep(acquireResult.error, {\n origin: \"result\",\n resultCause: acquireResult.cause,\n });\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: wrappedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: acquireResult,\n meta: { origin: \"result\", resultCause: acquireResult.cause },\n });\n }\n onError?.(wrappedError as unknown as E, stepName, context);\n throw earlyExit(wrappedError as unknown as E, {\n origin: \"result\",\n resultCause: acquireResult.cause,\n });\n }\n\n const resource = acquireResult.value;\n let useResult: Result<T, UseE> | undefined;\n let useThrown: unknown;\n let useThrewNonResult = false;\n\n // Use\n try {\n useResult = await options.use(resource);\n } catch (thrown) {\n if (isEarlyExitE(thrown)) {\n // Release before propagating\n try {\n await options.release(resource);\n } catch (releaseErr) {\n console.warn(\n `[awaitly] step.withResource(\"${id}\"): release threw after earlyExit:`,\n releaseErr\n );\n }\n throw thrown;\n }\n useThrown = thrown;\n useThrewNonResult = true;\n }\n\n // Release — ALWAYS runs after use (unless acquire failed)\n try {\n await options.release(resource);\n } catch (releaseErr) {\n console.warn(\n `[awaitly] step.withResource(\"${id}\"): release threw:`,\n releaseErr\n );\n }\n\n // Emit events AFTER release completes\n if (useThrewNonResult) {\n let mappedError: E | UnexpectedError;\n try {\n mappedError = effectiveCatchUnexpected(useThrown) as E | UnexpectedError;\n } catch (mapperError) {\n throw createMapperException(mapperError);\n }\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: mappedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: err(mappedError, { cause: useThrown }),\n meta: { origin: \"throw\", thrown: useThrown },\n });\n }\n onError?.(mappedError as E, stepName, context);\n throw earlyExit(mappedError as E, { origin: \"throw\", thrown: useThrown });\n }\n\n // useResult is defined if useThrewNonResult is false\n const result = useResult!;\n if (result.ok) {\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_success\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result,\n });\n }\n return result.value;\n }\n\n // Use returned an error\n const durationMs = performance.now() - startTime;\n const wrappedError = wrapForStep(result.error, {\n origin: \"result\",\n resultCause: result.cause,\n });\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: wrappedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result,\n meta: { origin: \"result\", resultCause: result.cause },\n });\n }\n onError?.(wrappedError as unknown as E, stepName, context);\n throw earlyExit(wrappedError as unknown as E, {\n origin: \"result\",\n resultCause: result.cause,\n });\n })();\n };\n\n const step = stepFn as unknown as RunStep<E | UnexpectedError>;\n const value = await fn({ step });\n\n // Dev-only warning: Detect common mistake of returning ok() or err() from executor\n if (\n process.env.NODE_ENV !== \"production\" &&\n value !== null &&\n typeof value === \"object\" &&\n \"ok\" in value &&\n typeof (value as { ok: unknown }).ok === \"boolean\"\n ) {\n const maybeResult = value as { ok: boolean; value?: unknown; error?: unknown };\n if (\n (maybeResult.ok === true && \"value\" in maybeResult) ||\n (maybeResult.ok === false && \"error\" in maybeResult)\n ) {\n console.warn(\n `awaitly: Workflow executor returned a Result-like object. ` +\n `Return raw values, not ok() or err().\\n\\n` +\n ` Incorrect: return ok({ data });\\n` +\n ` Correct: return { data };\\n\\n` +\n `See: https://jagreehal.github.io/awaitly/guides/troubleshooting/#returning-ok-from-workflow-executor-double-wrapping`\n );\n }\n }\n\n return ok(value);\n } catch (error) {\n // If a catchUnexpected mapper threw, propagate without re-processing\n if (isMapperException(error)) {\n throw error.thrown;\n }\n\n if (isEarlyExitE(error)) {\n // Extract original cause from early exit metadata\n const originalCause = error.meta.origin === \"throw\"\n ? error.meta.thrown\n : error.meta.origin === \"result\"\n ? error.meta.resultCause\n : undefined;\n\n return err(error.error, { cause: originalCause });\n }\n\n const mapped = effectiveCatchUnexpected(error);\n onError?.(mapped as E, \"unexpected\", context);\n return err(mapped, { cause: error });\n }\n}\n\n/**\n * Non-overloaded re-typing of `run()`. Same function at runtime — just\n * exposed with one signature so other awaitly modules (e.g. `awaitly/flow`)\n * can call the engine without dancing through TS overload resolution.\n *\n * End-users should call `run()` instead; the overloads give better inference\n * at call sites.\n *\n * @internal\n */\nexport const runInternal: <T, E, U = UnexpectedError, C = void>(\n fn: (context: { step: RunStep<E> }) => Promise<T> | T,\n options?: {\n catchUnexpected?: (cause: unknown) => U;\n onEvent?: (event: WorkflowEvent<E | U, C>, ctx: C) => void;\n onError?: (error: E | U, stepName?: string, ctx?: C) => void;\n workflowId?: string;\n workflowName?: string;\n context?: C;\n }\n) => Promise<Result<T, E | U>> = runFn as never;\n\n/**\n * Convenience for run() with catchUnexpected: closed union Result<T, E>.\n * You must provide catchUnexpected to map uncaught exceptions to E.\n */\nconst runStrict = <T, E, C = void>(\n fn: (context: { step: RunStep<E> }) => Promise<T> | T,\n options: {\n onError?: (error: E, stepName?: string, ctx?: C) => void;\n /**\n * Listener for workflow events (start, success, error, step events).\n *\n * Note: Context is available both on `event.context` and as the separate `ctx` parameter.\n * The `ctx` parameter is provided for convenience and backward compatibility.\n */\n onEvent?: (event: WorkflowEvent<E | UnexpectedError, C>, ctx: C) => void;\n catchUnexpected: (cause: unknown) => E;\n workflowId?: string;\n context?: C;\n /** @internal External signal for workflow-level cancellation. */\n _workflowSignal?: AbortSignal;\n }\n): AsyncResult<T, E, unknown> => {\n return runFn<T, E, C>(fn, options);\n};\n\n/**\n * The public run(): the engine with `.strict` attached.\n *\n * Assembled with a PURE-annotated Object.assign instead of a top-level\n * `run.strict = ...` mutation — a top-level property assignment is a side\n * effect that pins run (and the whole step engine) into every consumer\n * bundle even when only Result primitives are imported.\n */\nexport const run = /* @__PURE__ */ Object.assign(runFn, { strict: runStrict });\n\n// =============================================================================\n// Unwrap Utilities\n// =============================================================================\n\n/**\n * Error thrown when `unwrap()` is called on an error Result.\n *\n * This error is thrown to prevent silent failures when using `unwrap()`.\n * Prefer using `unwrapOr`, `unwrapOrElse`, or pattern matching with `match` or `isOk`/`isErr`.\n */\nexport class UnwrapError<E = unknown, C = unknown> extends Error {\n constructor(\n public readonly error: E,\n public readonly cause?: C\n ) {\n super(`Unwrap called on an error result: ${String(error)}`);\n this.name = \"UnwrapError\";\n }\n}\n\n/**\n * Unwraps a Result, throwing an error if it's a failure.\n *\n * @remarks When to use: Only at boundaries or tests where a failure should be fatal.\n *\n * ## When to Use\n *\n * Use `unwrap()` when:\n * - You're certain the Result is successful (e.g., after checking with `isOk`)\n * - You're in a context where errors should crash (e.g., tests, initialization)\n * - You need the value immediately and can't handle errors gracefully\n *\n * ## Why Avoid This\n *\n * **Prefer alternatives** in production code:\n * - `unwrapOr(defaultValue)` - Provide a fallback value\n * - `unwrapOrElse(fn)` - Compute fallback from error\n * - `match()` - Handle both cases explicitly\n * - `isOk()` / `isErr()` - Type-safe pattern matching\n *\n * Throwing errors makes error handling harder and can crash your application.\n *\n * @param r - The Result to unwrap\n * @returns The success value if the Result is successful\n * @throws {UnwrapError} If the Result is an error (includes the error and cause)\n *\n * @example\n * ```typescript\n * // Safe usage after checking\n * const result = someOperation();\n * if (isOk(result)) {\n * const value = unwrap(result); // Safe - we know it's ok\n * }\n *\n * // Unsafe usage (not recommended)\n * const value = unwrap(someOperation()); // May throw!\n * ```\n */\nexport const unwrap = <T, E, C>(r: Result<T, E, C>): T => {\n if (r.ok) return r.value;\n throw new UnwrapError<E, C>(r.error, r.cause);\n};\n\n/**\n * Unwraps a Result, returning a default value if it's a failure.\n *\n * @remarks When to use: Provide a safe fallback without branching.\n *\n * ## When to Use\n *\n * Use `unwrapOr()` when:\n * - You have a sensible default value for errors\n * - You want to continue execution even on failure\n * - The default value is cheap to compute (use `unwrapOrElse` if expensive)\n *\n * ## Why Use This\n *\n * - **Safe**: Never throws, always returns a value\n * - **Simple**: One-liner for common error handling\n * - **Type-safe**: TypeScript knows you'll always get a `T`\n *\n * @param r - The Result to unwrap\n * @param defaultValue - The value to return if the Result is an error\n * @returns The success value if successful, otherwise the default value\n *\n * @example\n * ```typescript\n * // Provide default for missing data\n * const user = unwrapOr(fetchUser(id), { id: 'anonymous', name: 'Guest' });\n *\n * // Provide default for numeric operations\n * const count = unwrapOr(parseCount(input), 0);\n *\n * // Provide default for optional features\n * const config = unwrapOr(loadConfig(), getDefaultConfig());\n * ```\n */\nexport const unwrapOr = <T, E, C>(r: Result<T, E, C>, defaultValue: T): T =>\n r.ok ? r.value : defaultValue;\n\n/**\n * Unwraps a Result, computing a default value from the error if it's a failure.\n *\n * @remarks When to use: Compute a fallback from the error (logging, metrics, or derived defaults).\n *\n * ## When to Use\n *\n * Use `unwrapOrElse()` when:\n * - The default value is expensive to compute (lazy evaluation)\n * - You need to log or handle the error before providing a default\n * - The default depends on the error type or cause\n * - You want to transform the error into a success value\n *\n * ## Why Use This Instead of `unwrapOr`\n *\n * - **Lazy**: Default is only computed if needed (better performance)\n * - **Error-aware**: You can inspect the error before providing default\n * - **Flexible**: Default can depend on error type or cause\n *\n * @param r - The Result to unwrap\n * @param fn - Function that receives the error and optional cause, returns the default value\n * @returns The success value if successful, otherwise the result of calling `fn(error, cause)`\n *\n * @example\n * ```typescript\n * // Compute default based on error type\n * const port = unwrapOrElse(parsePort(env.PORT), (error) => {\n * if (error === 'INVALID_FORMAT') return 3000;\n * if (error === 'OUT_OF_RANGE') return 8080;\n * return 4000; // default\n * });\n *\n * // Log error before providing default\n * const data = unwrapOrElse(fetchData(), (error, cause) => {\n * console.error('Failed to fetch:', error, cause);\n * return getCachedData();\n * });\n *\n * // Transform error into success value\n * const result = unwrapOrElse(operation(), (error) => {\n * return { success: false, reason: String(error) };\n * });\n * ```\n */\nexport const unwrapOrElse = <T, E, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => T\n): T => (r.ok ? r.value : fn(r.error, r.cause));\n\n/**\n * Alias for `unwrap`. Returns the success value or throws.\n *\n * The Result is already computed; use when you want the value or throw (e.g. at boundaries or in tests).\n *\n * @param r - The Result to unwrap\n * @returns The success value if the Result is successful\n * @throws {UnwrapError} If the Result is an error (includes the error and cause)\n */\nexport const runOrThrow = <T, E, C>(r: Result<T, E, C>): T => unwrap(r);\n\n/**\n * Awaits a Promise of a Result, then returns the success value or rejects.\n *\n * The returned promise **resolves with T** on success and **rejects with UnwrapError** on failure.\n * UnwrapError extends Error and carries the original `error` and `cause` from the Err.\n *\n * @param ar - A Promise or thenable that resolves to a Result\n * @returns A Promise that resolves with the success value or rejects with UnwrapError\n */\nexport const runOrThrowAsync = <T, E, C>(\n ar: PromiseLike<Result<T, E, C>>\n): Promise<T> => Promise.resolve(ar).then(unwrap);\n\n/**\n * Convenience alias for `unwrapOr(r, null)`. Returns the success value or null.\n *\n * @param r - The Result to unwrap\n * @returns The success value if successful, otherwise null\n */\nexport const runOrNull = <T, E, C>(r: Result<T, E, C>): T | null =>\n r.ok ? r.value : null;\n\n/**\n * Convenience alias for `unwrapOr(r, undefined)`. Returns the success value or undefined.\n *\n * @param r - The Result to unwrap\n * @returns The success value if successful, otherwise undefined\n */\nexport const runOrUndefined = <T, E, C>(r: Result<T, E, C>): T | undefined =>\n r.ok ? r.value : undefined;\n\n// =============================================================================\n// Wrapping Functions\n// =============================================================================\n\n/**\n * Wraps a synchronous throwing function in a Result.\n *\n * @remarks When to use: Wrap sync code that might throw so exceptions become Err values.\n *\n * ## When to Use\n *\n * Use `from()` when:\n * - You have a synchronous function that throws exceptions\n * - You want to convert exceptions to typed errors\n * - You're integrating with libraries that throw (e.g., JSON.parse, fs.readFileSync)\n * - You need to handle errors without try/catch blocks\n *\n * ## Why Use This\n *\n * - **Type-safe errors**: Convert thrown exceptions to typed Result errors\n * - **No try/catch**: Cleaner code without nested try/catch blocks\n * - **Composable**: Results can be chained with `andThen`, `map`, etc.\n * - **Explicit errors**: Forces you to handle errors explicitly\n *\n * @param fn - The synchronous function to execute (may throw)\n * @returns A Result with the function's return value or the thrown error\n *\n * @example\n * ```typescript\n * // Wrap JSON.parse\n * const parsed = from(() => JSON.parse('{\"key\": \"value\"}'));\n * // parsed: { ok: true, value: { key: \"value\" } }\n *\n * const error = from(() => JSON.parse('invalid'));\n * // error: { ok: false, error: SyntaxError }\n * ```\n */\nexport function from<T>(fn: () => T): Ok<T> | Err<unknown, unknown>;\n/**\n * Wraps a synchronous throwing function in a Result with custom error mapping.\n *\n * Use this overload when you want to map thrown exceptions to your typed error union.\n *\n * @param fn - The synchronous function to execute (may throw)\n * @param onError - Function to map the thrown exception to a typed error\n * @returns A Result with the function's return value or the mapped error\n *\n * @example\n * ```typescript\n * // Map exceptions to typed errors\n * const parsed = from(\n * () => JSON.parse(input),\n * (cause) => ({ type: 'PARSE_ERROR' as const, cause })\n * );\n * // parsed.error: { type: 'PARSE_ERROR', cause: SyntaxError }\n *\n * // Map to simple error codes\n * const value = from(\n * () => riskyOperation(),\n * () => 'OPERATION_FAILED' as const\n * );\n * ```\n */\nexport function from<T, E>(fn: () => T, onError: (cause: unknown) => E): Ok<T> | Err<E, unknown>;\nexport function from<T, E>(fn: () => T, onError?: (cause: unknown) => E) {\n try {\n return ok(fn());\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Wraps a Promise in a Result, converting rejections to errors.\n *\n * @remarks When to use: Wrap a Promise and keep the raw rejection as Err; use tryAsync to map errors.\n *\n * ## When to Use\n *\n * Use `fromPromise()` when:\n * - You have an existing Promise that might reject\n * - You want to convert Promise rejections to typed errors\n * - You're working with libraries that return Promises (fetch, database clients)\n * - You need to handle rejections without .catch() chains\n *\n * ## Why Use This\n *\n * - **Type-safe errors**: Convert Promise rejections to typed Result errors\n * - **Composable**: Results can be chained with `andThen`, `map`, etc.\n * - **Explicit handling**: Forces you to handle errors explicitly\n * - **No .catch() chains**: Cleaner than Promise.catch() patterns\n *\n * @param promise - The Promise to await (may reject)\n * @returns A Promise resolving to a Result with the resolved value or rejection reason\n *\n * @example\n * ```typescript\n * // Wrap fetch\n * const result = await fromPromise(\n * fetch('/api').then(r => r.json())\n * );\n * // result.ok: true if fetch succeeded, false if rejected\n * ```\n */\nexport function fromPromise<T>(promise: Promise<T>): Promise<Ok<T> | Err<unknown, unknown>>;\n/**\n * Wraps a Promise in a Result with custom error mapping.\n *\n * Use this overload when you want to map Promise rejections to your typed error union.\n *\n * @param promise - The Promise to await (may reject)\n * @param onError - Function to map the rejection reason to a typed error\n * @returns A Promise resolving to a Result with the resolved value or mapped error\n *\n * @example\n * ```typescript\n * // Map fetch errors to typed errors\n * const result = await fromPromise(\n * fetch('/api').then(r => {\n * if (!r.ok) throw new Error(`HTTP ${r.status}`);\n * return r.json();\n * }),\n * () => 'FETCH_FAILED' as const\n * );\n * // result.error: 'FETCH_FAILED' if fetch failed\n *\n * // Map with error details\n * const data = await fromPromise(\n * db.query(sql),\n * (cause) => ({ type: 'DB_ERROR' as const, message: String(cause) })\n * );\n * ```\n */\nexport function fromPromise<T, E>(\n promise: Promise<T>,\n onError: (cause: unknown) => E\n): Promise<Ok<T> | Err<E, unknown>>;\nexport async function fromPromise<T, E>(\n promise: Promise<T>,\n onError?: (cause: unknown) => E\n): Promise<Ok<T> | Err<E, unknown> | Err<unknown, unknown>> {\n try {\n return ok(await promise);\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Wraps an async function in a Result, catching both thrown exceptions and Promise rejections.\n *\n * @remarks When to use: Wrap async work and map thrown/rejected values into your typed error union.\n *\n * ## When to Use\n *\n * Use `tryAsync()` when:\n * - You have an async function that might throw or reject\n * - You want to convert both exceptions and rejections to typed errors\n * - You're creating new async functions (use `fromPromise` for existing Promises)\n * - You need to handle errors without try/catch or .catch()\n *\n * ## Why Use This Instead of `fromPromise`\n *\n * - **Function form**: Takes a function, not a Promise (lazy evaluation)\n * - **Catches both**: Handles both thrown exceptions and Promise rejections\n * - **Cleaner syntax**: No need to wrap in Promise manually\n *\n * @param fn - The async function to execute (may throw or reject)\n * @returns A Promise resolving to a Result with the function's return value or error\n *\n * @example\n * ```typescript\n * // Wrap async function\n * const result = await tryAsync(async () => {\n * const data = await fetchData();\n * return processData(data);\n * });\n * ```\n */\nexport function tryAsync<T>(fn: () => Promise<T>): AsyncResult<T, unknown>;\n/**\n * Wraps an async function in a Result with custom error mapping.\n *\n * Use this overload when you want to map errors to your typed error union.\n *\n * @param fn - The async function to execute (may throw or reject)\n * @param onError - Function to map the error (exception or rejection) to a typed error\n * @returns A Promise resolving to a Result with the function's return value or mapped error\n *\n * @example\n * ```typescript\n * // Map errors to typed errors\n * const result = await tryAsync(\n * async () => await fetchData(),\n * () => 'FETCH_ERROR' as const\n * );\n *\n * // Map with error details\n * const data = await tryAsync(\n * async () => await processFile(path),\n * (cause) => ({ type: 'PROCESSING_ERROR' as const, cause })\n * );\n * ```\n */\nexport function tryAsync<T, E>(\n fn: () => Promise<T>,\n onError: (cause: unknown) => E\n): AsyncResult<T, E>;\nexport async function tryAsync<T, E>(\n fn: () => Promise<T>,\n onError?: (cause: unknown) => E\n): AsyncResult<T, E | unknown> {\n try {\n return ok(await fn());\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Converts a nullable value to a Result.\n *\n * @remarks When to use: Turn null/undefined into a typed error before continuing.\n *\n * ## When to Use\n *\n * Use `fromNullable()` when:\n * - You have a value that might be `null` or `undefined`\n * - You want to treat null/undefined as an error case\n * - You're working with APIs that return nullable values (DOM APIs, optional properties)\n * - You want to avoid null checks scattered throughout your code\n *\n * ## Why Use This\n *\n * - **Type-safe**: Converts nullable types to non-nullable Results\n * - **Explicit errors**: Forces you to handle null/undefined cases\n * - **Composable**: Results can be chained with `andThen`, `map`, etc.\n * - **No null checks**: Eliminates need for `if (value == null)` checks\n *\n * @param value - The value that may be null or undefined\n * @param onNull - Function that returns an error when value is null/undefined\n * @returns A Result with the value if not null/undefined, otherwise the error from `onNull`\n *\n * @example\n * ```typescript\n * // Convert DOM element lookup\n * const element = fromNullable(\n * document.getElementById('app'),\n * () => 'ELEMENT_NOT_FOUND' as const\n * );\n *\n * // Convert optional property\n * const userId = fromNullable(\n * user.id,\n * () => 'USER_ID_MISSING' as const\n * );\n *\n * // Convert database query result\n * const record = fromNullable(\n * await db.find(id),\n * () => ({ type: 'NOT_FOUND' as const, id })\n * );\n * ```\n */\nexport function fromNullable<T, E>(\n value: T | null | undefined,\n onNull: () => E\n): Result<T, E> {\n return value != null ? ok(value) : err(onNull());\n}\n\n// =============================================================================\n// Transformers\n// =============================================================================\n\n/**\n * Transforms the success value of a Result.\n *\n * @remarks When to use: Transform only the Ok value while leaving Err untouched.\n *\n * ## When to Use\n *\n * Use `map()` when:\n * - You need to transform a success value to another type\n * - You want to apply a pure function to the value\n * - You're building a pipeline of transformations\n * - The transformation cannot fail (use `andThen` if it can fail)\n *\n * ## Why Use This\n *\n * - **Functional style**: Composable, chainable transformations\n * - **Error-preserving**: Errors pass through unchanged\n * - **Type-safe**: TypeScript tracks the transformation\n * - **No unwrapping**: Avoids manual `if (r.ok)` checks\n *\n * @param r - The Result to transform\n * @param fn - Pure function that transforms the success value (must not throw)\n * @returns A new Result with the transformed value, or the original error if `r` was an error\n *\n * @example\n * ```typescript\n * // Transform numeric value\n * const doubled = map(ok(21), n => n * 2);\n * // doubled: { ok: true, value: 42 }\n *\n * // Transform object property\n * const name = map(fetchUser(id), user => user.name);\n *\n * // Chain transformations\n * const formatted = map(\n * map(parseNumber(input), n => n * 2),\n * n => `Result: ${n}`\n * );\n * ```\n */\nexport function map<T, U>(r: Ok<T>, fn: (value: T) => U): Ok<U>;\nexport function map<T, U, E, C>(r: Err<E, C>, fn: (value: T) => U): Err<E, C>;\nexport function map<T, U, E, C>(r: Result<T, E, C>, fn: (value: T) => U): Result<U, E, C>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function map(r: any, fn: any): any {\n return r.ok ? ok(fn(r.value)) : r;\n}\n\n/**\n * Transforms the error value of a Result.\n *\n * @remarks When to use: Retype or normalize errors while leaving Ok values unchanged.\n *\n * ## When to Use\n *\n * Use `mapError()` when:\n * - You need to normalize or transform error types\n * - You want to convert errors to a different error type\n * - You're building error handling pipelines\n * - You need to format error messages or codes\n *\n * ## Why Use This\n *\n * - **Error normalization**: Convert errors to a common format\n * - **Type transformation**: Change error type while preserving value type\n * - **Composable**: Can be chained with other transformers\n * - **Success-preserving**: Success values pass through unchanged\n *\n * @param r - The Result to transform\n * @param fn - Function that transforms the error value (must not throw)\n * @returns A new Result with the original value, or the transformed error if `r` was an error\n *\n * @example\n * ```typescript\n * // Normalize error codes\n * const normalized = mapError(err('not_found'), e => e.toUpperCase());\n * // normalized: { ok: false, error: 'NOT_FOUND' }\n *\n * // Convert error types\n * const typed = mapError(\n * err('404'),\n * code => ({ type: 'HTTP_ERROR' as const, status: parseInt(code) })\n * );\n *\n * // Format error messages\n * const formatted = mapError(\n * err('PARSE_ERROR'),\n * code => `Failed to parse: ${code}`\n * );\n * ```\n */\nexport function mapError<T, E, F, C>(\n r: Result<T, E, C>,\n fn: (error: E) => F\n): Result<T, F, C> {\n return r.ok ? r : err(fn(r.error), { cause: r.cause });\n}\n\n/**\n * Pattern matches on a Result, calling the appropriate handler.\n *\n * @remarks When to use: Handle both Ok and Err in a single expression that returns a value.\n *\n * ## When to Use\n *\n * Use `match()` when:\n * - You need to handle both success and error cases\n * - You want to transform a Result to a different type\n * - You need exhaustive handling (both cases must be handled)\n * - You're building user-facing messages or responses\n *\n * ## Why Use This\n *\n * - **Exhaustive**: Forces you to handle both success and error cases\n * - **Type-safe**: TypeScript ensures both handlers are provided\n * - **Functional**: Pattern matching style, similar to Rust's `match` or Haskell's `case`\n * - **Single expression**: Can be used in expressions, not just statements\n *\n * @param r - The Result to match\n * @param handlers - Object with `ok` and `err` handler functions\n * @param handlers.ok - Function called with the success value\n * @param handlers.err - Function called with the error and optional cause\n * @returns The return value of the appropriate handler (both must return the same type `R`)\n *\n * @example\n * ```typescript\n * // Build user-facing messages\n * const message = match(result, {\n * ok: (user) => `Hello ${user.name}`,\n * err: (error) => `Error: ${error}`,\n * });\n *\n * // Transform to API response\n * const response = match(operation(), {\n * ok: (data) => ({ status: 200, body: data }),\n * err: (error) => ({ status: 400, error: String(error) }),\n * });\n *\n * // Handle with cause\n * const response = match(result, {\n * ok: (value) => ({ status: 'success', data: value }),\n * err: (error, cause) => ({ status: 'error', error, cause }),\n * });\n * ```\n */\nexport function match<T, E, C, R>(handlers: { ok: (value: T) => R; err: (error: E, cause?: C) => R }): (r: Result<T, E, C>) => R;\nexport function match<T, E, C, R>(r: Ok<T>, handlers: { ok: (value: T) => R; err: (error: E, cause?: C) => R }): R;\nexport function match<T, E, C, R>(r: Err<E, C>, handlers: { ok: (value: T) => R; err: (error: E, cause?: C) => R }): R;\nexport function match<T, E, C, R>(r: Result<T, E, C>, handlers: { ok: (value: T) => R; err: (error: E, cause?: C) => R }): R;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function match(r: any, handlers?: any): any {\n if (handlers === undefined) {\n const h = r;\n return (result: Result<unknown, unknown, unknown>) => match(result, h);\n }\n return r.ok ? handlers.ok(r.value) : handlers.err(r.error, r.cause);\n}\n\n/**\n * Chains Results together (flatMap/monadic bind).\n *\n * @remarks When to use: Chain dependent operations that return Result without nested branching.\n *\n * ## When to Use\n *\n * Use `andThen()` when:\n * - You need to chain operations that can fail\n * - The next operation depends on the previous success value\n * - You're building a pipeline of dependent operations\n * - You want to avoid nested `if (r.ok)` checks\n *\n * ## Why Use This Instead of `map`\n *\n * - **Can fail**: The chained function returns a Result (can fail)\n * - **Short-circuits**: If first Result fails, second operation never runs\n * - **Error accumulation**: Errors from both operations are in the union\n * - **Composable**: Can chain multiple operations together\n *\n * ## Common Pattern\n *\n * This is the fundamental building block for Result pipelines:\n * ```typescript\n * andThen(operation1(), value1 =>\n * andThen(operation2(value1), value2 =>\n * ok({ value1, value2 })\n * )\n * )\n * ```\n *\n * @param r - The first Result\n * @param fn - Function that takes the success value and returns a new Result (may fail)\n * @returns The Result from `fn` if `r` was successful, otherwise the original error\n *\n * @example\n * ```typescript\n * // Chain dependent operations\n * const userPosts = andThen(\n * fetchUser('1'),\n * user => fetchPosts(user.id)\n * );\n *\n * // Build complex pipelines\n * const result = andThen(parseInput(input), parsed =>\n * andThen(validate(parsed), validated =>\n * process(validated)\n * )\n * );\n *\n * // Chain with different error types\n * const data = andThen(\n * fetchUser(id), // Returns Result<User, 'FETCH_ERROR'>\n * user => fetchPosts(user.id) // Returns Result<Post[], 'NOT_FOUND'>\n * );\n * // data.error: 'FETCH_ERROR' | 'NOT_FOUND'\n * ```\n */\nexport function andThen<T, U>(r: Ok<T>, fn: (value: T) => Ok<U>): Ok<U>;\nexport function andThen<T, F, C2>(r: Ok<T>, fn: (value: T) => Err<F, C2>): Err<F, C2>;\nexport function andThen<T, U, F, C2>(r: Ok<T>, fn: (value: T) => Result<U, F, C2>): Result<U, F, C2>;\nexport function andThen<T, U, E, F, C1, C2>(r: Err<E, C1>, fn: (value: T) => Result<U, F, C2>): Err<E, C1>;\nexport function andThen<T, U, E, F, C1, C2>(r: Result<T, E, C1>, fn: (value: T) => Result<U, F, C2>): Result<U, E | F, C1 | C2>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function andThen(r: any, fn: any): any {\n return r.ok ? fn(r.value) : r;\n}\n\n/**\n * Executes a side effect on a successful Result without changing it.\n *\n * @remarks When to use: Add side effects (logging, metrics) on Ok without changing the Result.\n *\n * ## When to Use\n *\n * Use `tap()` when:\n * - You need to log, debug, or observe success values\n * - You want to perform side effects in a pipeline\n * - You need to mutate external state based on success\n * - You're debugging and want to inspect values without breaking the chain\n *\n * ## Why Use This\n *\n * - **Non-breaking**: Doesn't change the Result, just performs side effect\n * - **Composable**: Can be inserted anywhere in a pipeline\n * - **Type-preserving**: Returns the same Result type\n * - **Lazy**: Side effect only runs if Result is successful\n *\n * @param r - The Result to tap\n * @param fn - Side effect function called with the success value (return value ignored)\n * @returns The original Result unchanged (for chaining)\n *\n * @example\n * ```typescript\n * // Log success values\n * const logged = tap(result, user => console.log('Got user:', user.name));\n * // logged === result, but console.log was called\n *\n * // Debug in pipeline\n * const debugged = pipe(\n * fetchUser(id),\n * r => tap(r, user => console.log('Fetched:', user)),\n * r => map(r, user => user.name)\n * );\n *\n * // Mutate external state\n * const tracked = tap(result, data => {\n * analytics.track('operation_success', data);\n * });\n * ```\n */\nexport function tap<T, E, C>(\n r: Result<T, E, C>,\n fn: (value: T) => void\n): Result<T, E, C> {\n if (r.ok) fn(r.value);\n return r;\n}\n\n/**\n * Executes a side effect on an error Result without changing it.\n *\n * @remarks When to use: Add side effects (logging, metrics) on Err without changing the Result.\n *\n * ## When to Use\n *\n * Use `tapError()` when:\n * - You need to log, debug, or observe error values\n * - You want to perform side effects on errors in a pipeline\n * - You need to report errors to external systems (logging, monitoring)\n * - You're debugging and want to inspect errors without breaking the chain\n *\n * ## Why Use This\n *\n * - **Non-breaking**: Doesn't change the Result, just performs side effect\n * - **Composable**: Can be inserted anywhere in a pipeline\n * - **Type-preserving**: Returns the same Result type\n * - **Lazy**: Side effect only runs if Result is an error\n *\n * @param r - The Result to tap\n * @param fn - Side effect function called with the error and optional cause (return value ignored)\n * @returns The original Result unchanged (for chaining)\n *\n * @example\n * ```typescript\n * // Log errors\n * const logged = tapError(result, (error, cause) => {\n * console.error('Error:', error, cause);\n * });\n *\n * // Report to error tracking\n * const tracked = tapError(result, (error, cause) => {\n * errorTracker.report(error, cause);\n * });\n *\n * // Debug in pipeline\n * const debugged = pipe(\n * operation(),\n * r => tapError(r, (err, cause) => console.error('Failed:', err)),\n * r => mapError(r, err => 'FORMATTED_ERROR')\n * );\n * ```\n */\nexport function tapError<T, E, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => void\n): Result<T, E, C> {\n if (!r.ok) fn(r.error, r.cause);\n return r;\n}\n\n/**\n * Transforms the success value of a Result, catching any errors thrown by the transform.\n *\n * @remarks When to use: Transform Ok values with a function that might throw and capture the failure.\n *\n * ## When to Use\n *\n * Use `mapTry()` when:\n * - Your transform function might throw exceptions\n * - You want to convert transform errors to typed errors\n * - You're working with libraries that throw (e.g., JSON.parse, Date parsing)\n * - You need to handle both Result errors and transform exceptions\n *\n * ## Why Use This Instead of `map`\n *\n * - **Exception-safe**: Catches exceptions from the transform function\n * - **Error mapping**: Converts thrown exceptions to typed errors\n * - **Dual error handling**: Handles both Result errors and transform exceptions\n *\n * @param result - The Result to transform\n * @param transform - Function to transform the success value (may throw exceptions)\n * @param onError - Function to map thrown exceptions to a typed error\n * @returns A Result with:\n * - Transformed value if both Result and transform succeed\n * - Original error if Result was an error\n * - Transform error if transform threw an exception\n *\n * @example\n * ```typescript\n * // Safe JSON parsing\n * const parsed = mapTry(\n * ok('{\"key\": \"value\"}'),\n * JSON.parse,\n * () => 'PARSE_ERROR' as const\n * );\n *\n * // Safe date parsing\n * const date = mapTry(\n * ok('2024-01-01'),\n * str => new Date(str),\n * () => 'INVALID_DATE' as const\n * );\n *\n * // Transform with error details\n * const processed = mapTry(\n * result,\n * value => riskyTransform(value),\n * (cause) => ({ type: 'TRANSFORM_ERROR' as const, cause })\n * );\n * ```\n */\nexport function mapTry<T, U, E, F, C>(\n result: Result<T, E, C>,\n transform: (value: T) => U,\n onError: (cause: unknown) => F\n): Result<U, E | F, C | unknown> {\n if (!result.ok) return result;\n try {\n return ok(transform(result.value));\n } catch (error) {\n return err(onError(error), { cause: error });\n }\n}\n\n/**\n * Transforms the error value of a Result, catching any errors thrown by the transform.\n *\n * @remarks When to use: Transform errors when the mapping might throw and you want that captured.\n *\n * ## When to Use\n *\n * Use `mapErrorTry()` when:\n * - Your error transform function might throw exceptions\n * - You're doing complex error transformations (e.g., string formatting, object construction)\n * - You want to handle both Result errors and transform exceptions\n * - You need to safely normalize error types\n *\n * ## Why Use This Instead of `mapError`\n *\n * - **Exception-safe**: Catches exceptions from the error transform function\n * - **Error mapping**: Converts thrown exceptions to typed errors\n * - **Dual error handling**: Handles both Result errors and transform exceptions\n *\n * @param result - The Result to transform\n * @param transform - Function to transform the error value (may throw exceptions)\n * @param onError - Function to map thrown exceptions to a typed error\n * @returns A Result with:\n * - Original value if Result was successful\n * - Transformed error if both Result was error and transform succeeded\n * - Transform error if transform threw an exception\n *\n * @example\n * ```typescript\n * // Safe error formatting\n * const formatted = mapErrorTry(\n * err('not_found'),\n * e => e.toUpperCase(), // Might throw if e is not a string\n * () => 'FORMAT_ERROR' as const\n * );\n *\n * // Complex error transformation\n * const normalized = mapErrorTry(\n * result,\n * error => ({ type: 'NORMALIZED', message: String(error) }),\n * () => 'TRANSFORM_ERROR' as const\n * );\n * ```\n */\nexport function mapErrorTry<T, E, F, G, C>(\n result: Result<T, E, C>,\n transform: (error: E) => F,\n onError: (cause: unknown) => G\n): Result<T, F | G, C | unknown> {\n if (result.ok) return result;\n try {\n return err(transform(result.error), { cause: result.cause });\n } catch (error) {\n return err(onError(error), { cause: error });\n }\n}\n\n/**\n * Transforms both the success value and error value of a Result simultaneously.\n *\n * ## When to Use\n *\n * Use `bimap()` when:\n * - You need to transform both success and error in one operation\n * - You're normalizing Results to a common format\n * - You want symmetric transformation of both cases\n * - You're building adapters between different Result types\n *\n * ## Why Use This Instead of `map` + `mapError`\n *\n * - **Single operation**: Transforms both cases in one call\n * - **Clearer intent**: Shows you're handling both cases symmetrically\n * - **Less code**: Avoids chaining map and mapError\n *\n * @param r - The Result to transform\n * @param onOk - Function that transforms the success value\n * @param onErr - Function that transforms the error value\n * @returns A new Result with transformed value or transformed error\n *\n * @example\n * ```typescript\n * // Normalize to API response format\n * const response = bimap(\n * fetchUser(id),\n * user => ({ status: 'success', data: user }),\n * error => ({ status: 'error', code: error })\n * );\n *\n * // Transform types\n * const stringified = bimap(\n * parseNumber(input),\n * n => `Value: ${n}`,\n * e => `Error: ${e}`\n * );\n *\n * // Adapt between error types\n * const adapted = bimap(\n * externalResult,\n * value => internalValue(value),\n * error => internalError(error)\n * );\n * ```\n */\nexport function bimap<T, U, E, F, C>(\n r: Result<T, E, C>,\n onOk: (value: T) => U,\n onErr: (error: E) => F\n): Result<U, F, C> {\n return r.ok ? ok(onOk(r.value)) : err(onErr(r.error), { cause: r.cause });\n}\n\n/**\n * Recovers from an error by returning a new Result.\n * Similar to neverthrow's `.orElse()`.\n *\n * @remarks When to use: Recover from Err by returning a fallback Result or retyping the error.\n *\n * ## When to Use\n *\n * Use `orElse()` when:\n * - You want to recover from errors with fallback operations\n * - The recovery might also fail (returns a Result)\n * - You need to chain fallback strategies\n * - You're implementing retry or fallback patterns\n *\n * ## Why Use This\n *\n * - **Fallback chains**: Try alternative operations on failure\n * - **Error recovery**: Convert errors to success with fallback values\n * - **Composable**: Can chain multiple orElse calls for cascading fallbacks\n * - **Type-safe**: TypeScript tracks the error union through recovery\n *\n * @param r - The Result to potentially recover from\n * @param fn - Function that takes the error and returns a new Result (may succeed or fail)\n * @returns The original Result if successful, or the result of the recovery function\n *\n * @example\n * ```typescript\n * // Fallback to default user\n * const user = orElse(\n * fetchUser(id),\n * error => error === 'NOT_FOUND' ? ok(defaultUser) : err(error)\n * );\n *\n * // Try cache, then database, then fail\n * const data = orElse(\n * orElse(\n * fetchFromCache(key),\n * () => fetchFromDatabase(key)\n * ),\n * () => err('DATA_UNAVAILABLE' as const)\n * );\n *\n * // Convert specific errors to success\n * const result = orElse(\n * riskyOperation(),\n * error => error.code === 'RETRY' ? ok(defaultValue) : err(error)\n * );\n * ```\n */\nexport function orElse<T, E, E2, C, C2>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => Result<T, E2, C2>\n): Result<T, E2, C2> {\n return r.ok ? r : fn(r.error, r.cause);\n}\n\n/**\n * Async version of orElse for recovering from errors with async operations.\n *\n * @param r - The Result or AsyncResult to potentially recover from\n * @param fn - Async function that takes the error and returns a new Result\n * @returns Promise of the original Result if successful, or the result of the recovery function\n *\n * @example\n * ```typescript\n * // Try primary API, fall back to secondary\n * const data = await orElseAsync(\n * await fetchFromPrimaryApi(),\n * async (error) => {\n * if (error === 'UNAVAILABLE') {\n * return await fetchFromSecondaryApi();\n * }\n * return err(error);\n * }\n * );\n * ```\n */\nexport async function orElseAsync<T, E, E2, C, C2>(\n r: Result<T, E, C> | Promise<Result<T, E, C>>,\n fn: (error: E, cause?: C) => Result<T, E2, C2> | Promise<Result<T, E2, C2>>\n): Promise<Result<T, E2, C2>> {\n const resolved = await r;\n return resolved.ok ? resolved : fn(resolved.error, resolved.cause);\n}\n\n/**\n * Recovers from an error by returning a plain value (not a Result).\n * Useful when you want to provide a default value on error.\n *\n * ## When to Use\n *\n * Use `recover()` when:\n * - You want to provide a fallback value on error\n * - Recovery cannot fail (unlike orElse which returns a Result)\n * - You're implementing default value patterns\n * - You want to guarantee a successful Result\n *\n * ## Why Use This Instead of `orElse`\n *\n * - **Simpler**: Recovery function returns plain value, not Result\n * - **Guaranteed success**: Always returns ok() after recovery\n * - **Clearer intent**: Shows recovery cannot fail\n *\n * @param r - The Result to potentially recover from\n * @param fn - Function that takes the error and returns a recovery value\n * @returns The original Result if successful, or ok(recoveryValue) if error\n *\n * @example\n * ```typescript\n * // Provide default user on NOT_FOUND\n * const user = recover(\n * fetchUser(id),\n * error => error === 'NOT_FOUND' ? defaultUser : guestUser\n * );\n *\n * // Convert all errors to default\n * const config = recover(\n * loadConfig(),\n * () => defaultConfig\n * );\n *\n * // Recover with error-based defaults\n * const value = recover(\n * parseNumber(input),\n * error => error === 'EMPTY' ? 0 : -1\n * );\n * ```\n */\nexport function recover<T, E, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => T\n): Ok<T> {\n return r.ok ? ok(r.value) : ok(fn(r.error, r.cause));\n}\n\n/**\n * Async version of recover for recovering with async operations.\n *\n * @param r - The Result or AsyncResult to potentially recover from\n * @param fn - Async function that takes the error and returns a recovery value\n * @returns Promise of ok(value) - either original or recovered\n *\n * @example\n * ```typescript\n * // Recover by fetching default from API\n * const user = await recoverAsync(\n * await fetchUser(id),\n * async (error) => await fetchDefaultUser()\n * );\n * ```\n */\nexport async function recoverAsync<T, E, C>(\n r: Result<T, E, C> | Promise<Result<T, E, C>>,\n fn: (error: E, cause?: C) => T | Promise<T>\n): Promise<Ok<T>> {\n const resolved = await r;\n if (resolved.ok) return ok(resolved.value);\n return ok(await fn(resolved.error, resolved.cause));\n}\n\n// =============================================================================\n// Result Hydration (Serialization)\n// =============================================================================\n\n/**\n * Validates and type-narrows a value to a Result.\n *\n * Since this library uses plain objects for Results, serialization is trivial -\n * the serialized form IS the Result. This function validates the structure and\n * provides type-safe narrowing.\n *\n * ## When to Use\n *\n * Use `hydrate()` when:\n * - Receiving Results over RPC/network\n * - Deserializing Results from storage\n * - Validating untrusted data as Results\n *\n * @param value - The unknown value to validate as a Result\n * @returns The value as a typed Result, or null if invalid\n *\n * @example\n * ```typescript\n * // Deserialize from JSON\n * const parsed = JSON.parse(jsonString);\n * const result = hydrate<User, ApiError>(parsed);\n * if (result) {\n * // result is Result<User, ApiError>\n * }\n *\n * // Validate RPC response\n * const rpcResponse = await fetchFromService();\n * const result = hydrate<Data, ServiceError>(rpcResponse);\n * ```\n */\nexport function hydrate<T, E, C = unknown>(value: unknown): Result<T, E, C> | null {\n if (\n value !== null &&\n typeof value === \"object\" &&\n \"ok\" in value &&\n typeof value.ok === \"boolean\"\n ) {\n if (value.ok === true && \"value\" in value) {\n return value as Result<T, E, C>;\n }\n if (value.ok === false && \"error\" in value) {\n return value as Result<T, E, C>;\n }\n }\n return null;\n}\n\n/**\n * Type guard to check if a value is a valid serialized Result.\n *\n * @param value - The value to check\n * @returns True if the value is a valid Result structure\n *\n * @example\n * ```typescript\n * if (isSerializedResult(data)) {\n * // data is Result<unknown, unknown, unknown>\n * if (data.ok) {\n * console.log(data.value);\n * }\n * }\n * ```\n */\nexport function isSerializedResult(\n value: unknown\n): value is Result<unknown, unknown, unknown> {\n return hydrate(value) !== null;\n}\n\n// =============================================================================\n// Batch Operations\n// =============================================================================\n\ntype AllValues<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Ok<infer V>\n ? V\n : T[K] extends Err<unknown, unknown>\n ? never\n : T[K] extends Result<infer V, unknown, unknown>\n ? V\n : never;\n};\ntype AllErrors<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Ok<unknown>\n ? never\n : T[K] extends Err<infer E, unknown>\n ? E\n : T[K] extends Result<unknown, infer E, unknown>\n ? E\n : never;\n}[number];\ntype AllCauses<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Ok<unknown>\n ? never\n : T[K] extends Err<unknown, infer C>\n ? C\n : T[K] extends Result<unknown, unknown, infer C>\n ? C\n : never;\n}[number];\n\n// Conditional type: returns Ok<...> when there are no errors, Result<...> otherwise\n// Note: We only check AllErrors, not AllCauses - causes only matter when there are errors\ntype AllResult<T extends readonly Result<unknown, unknown, unknown>[]> =\n [AllErrors<T>] extends [never]\n ? Ok<AllValues<T>>\n : Result<AllValues<T>, AllErrors<T>, AllCauses<T>>;\n\n/**\n * Combines multiple Results into one, requiring all to succeed.\n *\n * ## When to Use\n *\n * Use `all()` when:\n * - You have multiple independent operations that all must succeed\n * - You want to short-circuit on the first error (fail-fast)\n * - You need all values together (e.g., combining API responses)\n * - Performance matters (stops on first error, doesn't wait for all)\n *\n * ## Why Use This\n *\n * - **Fail-fast**: Stops immediately on first error (better performance)\n * - **Type-safe**: TypeScript infers the array type from input\n * - **Short-circuit**: Doesn't evaluate remaining Results after error\n * - **Composable**: Can be chained with other operations\n *\n * ## Important\n *\n * - **Short-circuits**: Returns first error immediately, doesn't wait for all Results\n * - **All must succeed**: If any Result fails, the entire operation fails\n * - **Use `allSettled`**: If you need to collect all errors (e.g., form validation)\n *\n * @param results - Array of Results to combine (all must succeed)\n * @returns A Result with an array of all success values, or the first error encountered\n *\n * @example\n * ```typescript\n * // Combine multiple successful Results\n * const combined = all([ok(1), ok(2), ok(3)]);\n * // combined: { ok: true, value: [1, 2, 3] }\n *\n * // Short-circuits on first error\n * const error = all([ok(1), err('ERROR'), ok(3)]);\n * // error: { ok: false, error: 'ERROR' }\n * // Note: ok(3) is never evaluated\n *\n * // Combine API responses\n * const data = all([\n * fetchUser(id),\n * fetchPosts(id),\n * fetchComments(id)\n * ]);\n * // data.value: [user, posts, comments] if all succeed\n * ```\n */\nexport function all<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): AllResult<T> {\n const values: unknown[] = [];\n for (const result of results) {\n if (!result.ok) {\n return result as unknown as AllResult<T>;\n }\n values.push(result.value);\n }\n return ok(values) as AllResult<T>;\n}\n\n/**\n * Combines multiple Results or Promises of Results into one (async version of `all`).\n *\n * ## When to Use\n *\n * Use `allAsync()` when:\n * - You have multiple async operations that all must succeed\n * - You want to run operations in parallel (better performance)\n * - You want to short-circuit on the first error (fail-fast)\n * - You need all values together from parallel operations\n *\n * ## Why Use This Instead of `all`\n *\n * - **Parallel execution**: All Promises start immediately (faster)\n * - **Async support**: Works with Promises and AsyncResults\n * - **Promise rejection handling**: Converts Promise rejections to `PromiseRejectedError`\n *\n * ## Important\n *\n * - **Short-circuits**: Returns first error immediately, cancels remaining operations\n * - **Parallel**: All operations start simultaneously (unlike sequential `andThen`)\n * - **Use `allSettledAsync`**: If you need to collect all errors\n *\n * @param results - Array of Results or Promises of Results to combine (all must succeed)\n * @returns A Promise resolving to a Result with an array of all success values, or the first error\n *\n * @example\n * ```typescript\n * // Parallel API calls\n * const combined = await allAsync([\n * fetchUser('1'),\n * fetchPosts('1'),\n * fetchComments('1')\n * ]);\n * // All three calls start simultaneously\n * // combined: { ok: true, value: [user, posts, comments] } if all succeed\n *\n * // Mix Results and Promises\n * const data = await allAsync([\n * ok(cachedUser), // Already resolved\n * fetchPosts(userId), // Promise\n * ]);\n * ```\n */\nexport async function allAsync<\n const T extends readonly (Result<unknown, unknown, unknown> | Promise<Result<unknown, unknown, unknown>>)[]\n>(\n results: T\n): Promise<\n Result<\n { [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> | Promise<Result<infer V, unknown, unknown>> ? V : never },\n { [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> | Promise<Result<unknown, infer E, unknown>> ? E : never }[number] | PromiseRejectedError,\n { [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> | Promise<Result<unknown, unknown, infer C>> ? C : never }[number] | PromiseRejectionCause\n >\n> {\n type Values = { [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> | Promise<Result<infer V, unknown, unknown>> ? V : never };\n type Errors = { [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> | Promise<Result<unknown, infer E, unknown>> ? E : never }[number] | PromiseRejectedError;\n type Causes = { [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> | Promise<Result<unknown, unknown, infer C>> ? C : never }[number] | PromiseRejectionCause;\n\n if (results.length === 0) {\n return ok([]) as Result<Values, Errors, Causes>;\n }\n\n return new Promise((resolve) => {\n let settled = false;\n let pendingCount = results.length;\n const values: unknown[] = new Array(results.length);\n\n for (let i = 0; i < results.length; i++) {\n const index = i;\n Promise.resolve(results[index])\n .catch((reason) => err(\n { type: \"PROMISE_REJECTED\" as const, cause: reason },\n { cause: { type: \"PROMISE_REJECTION\" as const, reason } as PromiseRejectionCause }\n ))\n .then((result) => {\n if (settled) return;\n\n if (!result.ok) {\n settled = true;\n resolve(result as Result<Values, Errors, Causes>);\n return;\n }\n\n values[index] = result.value;\n pendingCount--;\n\n if (pendingCount === 0) {\n resolve(ok(values) as Result<Values, Errors, Causes>);\n }\n });\n }\n });\n}\n\nexport type SettledError<E, C = unknown> = { error: E; cause?: C };\n\n// Conditional type: returns Ok<...> when there are no errors, Result<...> otherwise\ntype AllSettledResult<T extends readonly Result<unknown, unknown, unknown>[]> =\n [AllErrors<T>] extends [never]\n ? Ok<AllValues<T>>\n : Result<AllValues<T>, SettledError<AllErrors<T>, AllCauses<T>>[]>;\n\n/**\n * Combines multiple Results, collecting all errors instead of short-circuiting.\n *\n * ## When to Use\n *\n * Use `allSettled()` when:\n * - You need to see ALL errors, not just the first one\n * - You're doing form validation (show all field errors)\n * - You want to collect partial results (some succeed, some fail)\n * - You need to process all Results regardless of failures\n *\n * ## Why Use This Instead of `all`\n *\n * - **Collects all errors**: Returns array of all errors, not just first\n * - **No short-circuit**: Evaluates all Results even if some fail\n * - **Partial success**: Can see which operations succeeded and which failed\n * - **Better UX**: Show users all validation errors at once\n *\n * ## Important\n *\n * - **No short-circuit**: All Results are evaluated (slower if many fail early)\n * - **Error array**: Returns array of `{ error, cause }` objects, not single error\n * - **Use `all`**: If you want fail-fast behavior (better performance)\n *\n * @param results - Array of Results to combine (all are evaluated)\n * @returns A Result with:\n * - Array of all success values if all succeed\n * - Array of `{ error, cause }` objects if any fail\n *\n * @example\n * ```typescript\n * // Form validation - show all errors\n * const validated = allSettled([\n * validateEmail(email),\n * validatePassword(password),\n * validateAge(age),\n * ]);\n * // If email and password fail:\n * // { ok: false, error: [\n * // { error: 'INVALID_EMAIL' },\n * // { error: 'WEAK_PASSWORD' }\n * // ]}\n *\n * // Collect partial results\n * const results = allSettled([\n * fetchUser('1'), // succeeds\n * fetchUser('2'), // fails\n * fetchUser('3'), // succeeds\n * ]);\n * // Can see which succeeded and which failed\n * ```\n */\nexport function allSettled<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): AllSettledResult<T> {\n const values: unknown[] = [];\n const errors: SettledError<unknown>[] = [];\n\n for (const result of results) {\n if (result.ok) {\n values.push(result.value);\n } else {\n errors.push({ error: result.error, cause: result.cause });\n }\n }\n\n if (errors.length > 0) {\n return err(errors) as unknown as AllSettledResult<T>;\n }\n\n return ok(values) as unknown as AllSettledResult<T>;\n}\n\n/**\n * Splits an array of Results into separate arrays of success values and errors.\n *\n * ## When to Use\n *\n * Use `partition()` when:\n * - You have an array of Results and need to separate successes from failures\n * - You want to process successes and errors separately\n * - You're collecting results from multiple operations (some may fail)\n * - You need to handle partial success scenarios\n *\n * ## Why Use This\n *\n * - **Simple separation**: One call splits successes and errors\n * - **Type-safe**: TypeScript knows `values` is `T[]` and `errors` is `E[]`\n * - **No unwrapping**: Doesn't require manual `if (r.ok)` checks\n * - **Preserves order**: Maintains original array order in both arrays\n *\n * ## Common Pattern\n *\n * Often used after `Promise.all()` with Results:\n * ```typescript\n * const results = await Promise.all(ids.map(id => fetchUser(id)));\n * const { values: users, errors } = partition(results);\n * // Process successful users, handle errors separately\n * ```\n *\n * @param results - Array of Results to partition\n * @returns An object with:\n * - `values`: Array of all success values (type `T[]`)\n * - `errors`: Array of all error values (type `E[]`)\n *\n * @example\n * ```typescript\n * // Split successes and errors\n * const results = [ok(1), err('ERROR_1'), ok(3), err('ERROR_2')];\n * const { values, errors } = partition(results);\n * // values: [1, 3]\n * // errors: ['ERROR_1', 'ERROR_2']\n *\n * // Process batch operations\n * const userResults = await Promise.all(userIds.map(id => fetchUser(id)));\n * const { values: users, errors: fetchErrors } = partition(userResults);\n *\n * // Process successful users\n * users.forEach(user => processUser(user));\n *\n * // Handle errors\n * fetchErrors.forEach(error => logError(error));\n * ```\n */\nexport function partition<T, E, C>(\n results: readonly Result<T, E, C>[]\n): { values: T[]; errors: E[] } {\n const values: T[] = [];\n const errors: E[] = [];\n\n for (const result of results) {\n if (result.ok) {\n values.push(result.value);\n } else {\n errors.push(result.error);\n }\n }\n\n return { values, errors };\n}\n\ntype AnyValue<T extends readonly Result<unknown, unknown, unknown>[]> =\n T[number] extends Result<infer U, unknown, unknown> ? U : never;\ntype AnyErrors<T extends readonly Result<unknown, unknown, unknown>[]> = {\n -readonly [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> ? E : never;\n}[number];\ntype AnyCauses<T extends readonly Result<unknown, unknown, unknown>[]> = {\n -readonly [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> ? C : never;\n}[number];\n\n/**\n * Returns the first successful Result from an array (succeeds fast).\n *\n * ## When to Use\n *\n * Use `any()` when:\n * - You have multiple fallback options and need the first that succeeds\n * - You're trying multiple strategies (e.g., cache → DB → API)\n * - You want fail-fast success (stops on first success)\n * - You have redundant data sources and any one will do\n *\n * ## Why Use This\n *\n * - **Succeeds fast**: Returns immediately on first success (better performance)\n * - **Fallback pattern**: Perfect for trying multiple options\n * - **Short-circuits**: Stops evaluating after first success\n * - **Type-safe**: TypeScript infers the success type\n *\n * ## Important\n *\n * - **First success wins**: Returns first successful Result, ignores rest\n * - **All errors**: If all fail, returns first error (not all errors)\n * - **Empty array**: Returns `EmptyInputError` if array is empty\n * - **Use `all`**: If you need ALL to succeed\n *\n * @param results - Array of Results to check (evaluated in order)\n * @returns The first successful Result, or first error if all fail, or `EmptyInputError` if empty\n *\n * @example\n * ```typescript\n * // Try multiple fallback strategies\n * const data = any([\n * fetchFromCache(id),\n * fetchFromDB(id),\n * fetchFromAPI(id)\n * ]);\n * // Returns first that succeeds\n *\n * // Try multiple formats\n * const parsed = any([\n * parseJSON(input),\n * parseXML(input),\n * parseYAML(input)\n * ]);\n *\n * // All errors case\n * const allErrors = any([err('A'), err('B'), err('C')]);\n * // allErrors: { ok: false, error: 'A' } (first error)\n * ```\n */\nexport function any<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): Result<AnyValue<T>, AnyErrors<T> | EmptyInputError, AnyCauses<T>> {\n type ReturnErr = Result<never, AnyErrors<T> | EmptyInputError, AnyCauses<T>>;\n type ReturnOk = Result<AnyValue<T>, never, AnyCauses<T>>;\n\n if (results.length === 0) {\n return err({\n type: \"EMPTY_INPUT\",\n message: \"any() requires at least one Result\",\n }) as ReturnErr;\n }\n let firstError: Result<never, unknown, unknown> | null = null;\n for (const result of results) {\n if (result.ok) return result as ReturnOk;\n if (!firstError) firstError = result;\n }\n return firstError as ReturnErr;\n}\n\ntype AnyAsyncValue<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> =\n Awaited<T[number]> extends Result<infer U, unknown, unknown> ? U : never;\ntype AnyAsyncErrors<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n -readonly [K in keyof T]: Awaited<T[K]> extends Result<unknown, infer E, unknown>\n ? E\n : never;\n}[number];\ntype AnyAsyncCauses<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n -readonly [K in keyof T]: Awaited<T[K]> extends Result<unknown, unknown, infer C>\n ? C\n : never;\n}[number];\n\n/**\n * Returns the first successful Result from an array of Results or Promises (async version of `any`).\n *\n * ## When to Use\n *\n * Use `anyAsync()` when:\n * - You have multiple async fallback options and need the first that succeeds\n * - You're trying multiple async strategies in parallel (cache → DB → API)\n * - You want fail-fast success from parallel operations\n * - You have redundant async data sources and any one will do\n *\n * ## Why Use This Instead of `any`\n *\n * - **Parallel execution**: All Promises start immediately (faster)\n * - **Async support**: Works with Promises and AsyncResults\n * - **Promise rejection handling**: Converts Promise rejections to `PromiseRejectedError`\n *\n * ## Important\n *\n * - **First success wins**: Returns first successful Result (from any Promise)\n * - **Parallel**: All operations run simultaneously\n * - **All errors**: If all fail, returns first error encountered\n *\n * @param results - Array of Results or Promises of Results to check (all start in parallel)\n * @returns A Promise resolving to the first successful Result, or first error if all fail\n *\n * @example\n * ```typescript\n * // Try multiple async fallbacks in parallel\n * const data = await anyAsync([\n * fetchFromCache(id), // Fastest wins\n * fetchFromDB(id),\n * fetchFromAPI(id)\n * ]);\n *\n * // Try multiple API endpoints\n * const response = await anyAsync([\n * fetch('/api/v1/data'),\n * fetch('/api/v2/data'),\n * fetch('/backup-api/data')\n * ]);\n * ```\n */\nexport async function anyAsync<\n const T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[],\n>(\n results: T\n): Promise<\n Result<AnyAsyncValue<T>, AnyAsyncErrors<T> | EmptyInputError | PromiseRejectedError, AnyAsyncCauses<T> | PromiseRejectionCause>\n> {\n type ReturnErr = Result<\n never,\n AnyAsyncErrors<T> | EmptyInputError | PromiseRejectedError,\n AnyAsyncCauses<T> | PromiseRejectionCause\n >;\n type ReturnOk = Result<AnyAsyncValue<T>, never, AnyAsyncCauses<T>>;\n\n if (results.length === 0) {\n return err({\n type: \"EMPTY_INPUT\",\n message: \"anyAsync() requires at least one Result\",\n }) as ReturnErr;\n }\n\n return new Promise((resolve) => {\n let settled = false;\n let pendingCount = results.length;\n let firstError: Result<never, unknown, unknown> | null = null;\n\n for (const item of results) {\n Promise.resolve(item)\n .catch((reason) =>\n err(\n { type: \"PROMISE_REJECTED\" as const, cause: reason },\n { cause: { type: \"PROMISE_REJECTION\" as const, reason } as PromiseRejectionCause }\n )\n )\n .then((result) => {\n if (settled) return;\n\n if (result.ok) {\n settled = true;\n resolve(result as ReturnOk);\n return;\n }\n\n if (!firstError) firstError = result;\n pendingCount--;\n\n if (pendingCount === 0) {\n resolve(firstError as ReturnErr);\n }\n });\n }\n });\n}\n\ntype AllAsyncValues<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n [K in keyof T]: Awaited<T[K]> extends Result<infer V, unknown, unknown> ? V : never;\n};\ntype AllAsyncErrors<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n [K in keyof T]: Awaited<T[K]> extends Result<unknown, infer E, unknown> ? E : never;\n}[number];\ntype AllAsyncCauses<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n [K in keyof T]: Awaited<T[K]> extends Result<unknown, unknown, infer C> ? C : never;\n}[number];\n\n/**\n * Combines multiple Results or Promises of Results, collecting all errors (async version of `allSettled`).\n *\n * ## When to Use\n *\n * Use `allSettledAsync()` when:\n * - You have multiple async operations and need ALL errors reported\n * - You're doing async form validation (show all field errors at once)\n * - You want to run operations in parallel and collect all results\n *\n * ## Behavior\n *\n * **Note:** Unlike `Promise.allSettled()`, this returns a Result:\n * - `ok(values[])` if ALL succeed\n * - `err(SettledError[])` if ANY fail (with all collected errors)\n *\n * This is consistent with awaitly's philosophy - all functions return Results.\n * `Promise.allSettled()` always succeeds with per-item status objects; this function\n * returns a single Result indicating overall success or failure.\n *\n * ## Why Use This Instead of `allSettled`\n *\n * - **Parallel execution**: All Promises start immediately (faster)\n * - **Async support**: Works with Promises and AsyncResults\n * - **Promise rejection handling**: Converts Promise rejections to `PromiseRejectedError`\n *\n * ## Important\n *\n * - **No short-circuit**: All operations complete (even if some fail)\n * - **Parallel**: All operations run simultaneously\n * - **Error array**: Returns array of `SettledError` objects (`{ error, cause? }`)\n *\n * @param results - Array of Results or Promises of Results to combine (all are evaluated)\n * @returns A Promise resolving to a Result with:\n * - `ok(values[])` - Array of all success values if ALL succeed\n * - `err(errors[])` - Array of `SettledError` objects if ANY fail\n *\n * @example\n * ```typescript\n * // Async form validation - see all errors at once\n * const validated = await allSettledAsync([\n * validateEmailAsync(email),\n * validatePasswordAsync(password),\n * checkUsernameAvailableAsync(username),\n * ]);\n *\n * if (!validated.ok) {\n * // validated.error is array of all validation failures\n * console.log('Errors:', validated.error.map(e => e.error));\n * }\n *\n * // Parallel API calls with error collection\n * const results = await allSettledAsync([\n * fetchUser('1'),\n * fetchUser('2'),\n * fetchUser('3'),\n * ]);\n * ```\n */\nexport async function allSettledAsync<\n const T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[],\n>(\n results: T\n): Promise<Result<AllAsyncValues<T>, SettledError<AllAsyncErrors<T> | PromiseRejectedError, AllAsyncCauses<T> | PromiseRejectionCause>[]>> {\n const settled = await Promise.all(\n results.map((item) =>\n Promise.resolve(item)\n .then((result) => ({ status: \"result\" as const, result }))\n .catch((reason) => ({\n status: \"rejected\" as const,\n error: { type: \"PROMISE_REJECTED\" as const, cause: reason } as PromiseRejectedError,\n cause: { type: \"PROMISE_REJECTION\" as const, reason } as PromiseRejectionCause,\n }))\n )\n );\n\n const values: unknown[] = [];\n const errors: SettledError<unknown, unknown>[] = [];\n\n for (const item of settled) {\n if (item.status === \"rejected\") {\n errors.push({ error: item.error, cause: item.cause });\n } else if (item.result.ok) {\n values.push(item.result.value);\n } else {\n errors.push({ error: item.result.error, cause: item.result.cause });\n }\n }\n\n if (errors.length > 0) {\n return err(errors) as unknown as Result<AllAsyncValues<T>, SettledError<AllAsyncErrors<T> | PromiseRejectedError, AllAsyncCauses<T> | PromiseRejectionCause>[]>;\n }\n return ok(values) as unknown as Result<AllAsyncValues<T>, SettledError<AllAsyncErrors<T> | PromiseRejectedError, AllAsyncCauses<T> | PromiseRejectionCause>[]>;\n}\n\n/**\n * Combines two Results into a tuple Result.\n *\n * ## When to Use\n *\n * Use `zip()` when:\n * - You have two independent Results and need both values together\n * - You want to combine validation results before processing\n * - You need a pair/tuple from two separate operations\n *\n * ## Why Use This Instead of `all()`\n *\n * - **Simpler types**: Returns `[A, B]` instead of array inference\n * - **Two-argument**: Cleaner API for common case of combining two Results\n * - **Compose with andThen**: Chain multiple zips for complex combinations\n *\n * ## Important\n *\n * - **Short-circuits**: Returns first error if either fails\n * - **Order matters**: If both fail, returns error from first argument\n * - **Use `all()`**: For more than 2 Results\n *\n * @param a - First Result\n * @param b - Second Result\n * @returns A Result containing a tuple `[A, B]` if both succeed, or the first error\n *\n * @example\n * ```typescript\n * // Combine two Results\n * const userResult = await fetchUser('1');\n * const postsResult = await fetchPosts('1');\n * const combined = zip(userResult, postsResult);\n * // combined: Result<[User, Post[]], UserError | PostsError>\n *\n * // Use with andThen for chaining\n * const result = andThen(\n * zip(fetchUser('1'), fetchPosts('1')),\n * ([user, posts]) => createDashboard(user, posts)\n * );\n *\n * // Validation combination\n * const validated = zip(\n * validateEmail(email),\n * validatePassword(password)\n * );\n * if (validated.ok) {\n * const [email, password] = validated.value;\n * createAccount(email, password);\n * }\n * ```\n */\nexport function zip<A, EA, CA, B, EB, CB>(\n a: Result<A, EA, CA>,\n b: Result<B, EB, CB>\n): Result<[A, B], EA | EB, CA | CB> {\n if (!a.ok) return a as Result<never, EA, CA>;\n if (!b.ok) return b as Result<never, EB, CB>;\n return ok([a.value, b.value]) as Result<[A, B], never, never>;\n}\n\n/**\n * Async version of `zip()` - combines two Results or Promises of Results into a tuple.\n *\n * ## When to Use\n *\n * Use `zipAsync()` when:\n * - You have two async operations and need both results together\n * - You want to run two fetches in parallel and combine results\n * - You need to combine Promises of Results into a single Result\n *\n * ## Why Use This Instead of `allAsync()`\n *\n * - **Simpler types**: Returns `[A, B]` instead of array inference\n * - **Two-argument**: Cleaner API for common case of combining two async Results\n * - **Parallel execution**: Both Promises start immediately\n *\n * ## Important\n *\n * - **Parallel**: Both operations run simultaneously (faster than sequential)\n * - **Short-circuits result**: Returns first argument's error if it fails, else second's\n * - **Waits for both**: Both Promises complete before returning (unlike `allAsync` fail-fast)\n * - **Rejection handling**: Promise rejections are wrapped as `PromiseRejectedError`\n * - **Use `allAsync()`**: For more than 2 Results\n *\n * @param a - First Result or Promise of Result\n * @param b - Second Result or Promise of Result\n * @returns A Promise of Result containing a tuple `[A, B]` if both succeed\n *\n * @example\n * ```typescript\n * // Parallel async operations\n * const result = await zipAsync(\n * fetchUser('1'),\n * fetchPosts('1')\n * );\n * // Both fetches run in parallel\n * // result: Result<[User, Post[]], UserError | PostsError>\n *\n * // Mix sync and async\n * const combined = await zipAsync(\n * ok({ cached: true }), // Already resolved\n * fetchFromAPI(id), // Async fetch\n * );\n *\n * // With chaining\n * const dashboard = await zipAsync(fetchUser('1'), fetchPosts('1'))\n * .then(result => andThen(result, ([user, posts]) => createDashboard(user, posts)));\n * ```\n */\nexport async function zipAsync<A, EA, CA, B, EB, CB>(\n a: Result<A, EA, CA> | Promise<Result<A, EA, CA>>,\n b: Result<B, EB, CB> | Promise<Result<B, EB, CB>>\n): AsyncResult<[A, B], EA | EB | PromiseRejectedError, CA | CB | PromiseRejectionCause> {\n // Wrap rejections into PromiseRejectedError (consistent with allAsync)\n const wrapRejection = <T, E, C>(\n p: Result<T, E, C> | Promise<Result<T, E, C>>\n ): Promise<Result<T, E | PromiseRejectedError, C | PromiseRejectionCause>> =>\n Promise.resolve(p).catch((reason) =>\n err(\n { type: \"PROMISE_REJECTED\" as const, cause: reason } as PromiseRejectedError,\n { cause: { type: \"PROMISE_REJECTION\" as const, reason } as PromiseRejectionCause }\n )\n );\n\n const [ra, rb] = await Promise.all([wrapRejection(a), wrapRejection(b)]);\n return zip(ra, rb);\n}\n","/**\n * awaitly/match\n *\n * Exhaustive pattern matching for discriminated unions.\n * Extends the TaggedError.match pattern to work with any tagged union.\n *\n * @example\n * ```typescript\n * type Event =\n * | { _tag: 'UserCreated'; user: User }\n * | { _tag: 'UserUpdated'; userId: string }\n * | { _tag: 'UserDeleted'; userId: string }\n *\n * const message = Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => `Created: ${e.user.name}`))\n * .pipe(Match.tag(\"UserUpdated\", e => `Updated: ${e.userId}`))\n * .pipe(Match.tag(\"UserDeleted\", e => `Deleted: ${e.userId}`))\n * .pipe(Match.exhaustive)\n * ```\n */\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Any object with a _tag discriminator.\n */\nexport type Tagged<Tag extends string = string> = { readonly _tag: Tag };\n\n/**\n * Extract the tag from a tagged union member.\n */\nexport type TagOf<T extends Tagged> = T[\"_tag\"];\n\n/**\n * Extract union members that match a specific tag.\n */\nexport type MatchTag<T extends Tagged, Tag extends string> = Extract<T, { _tag: Tag }>;\n\n/**\n * A matcher that is accumulating handlers for a tagged union.\n *\n * @typeParam Input - The full union type being matched\n * @typeParam Remaining - Union members that haven't been handled yet\n * @typeParam Output - The output type (union of all handler return types)\n */\nexport interface Matcher<Input extends Tagged, Remaining extends Tagged, Output> {\n readonly _tag: \"Matcher\";\n readonly value: Input;\n readonly handlers: Map<string, (value: Tagged) => unknown>;\n readonly _remaining: Remaining;\n readonly _output: Output;\n}\n\n/**\n * A completed matcher that has handled all cases.\n */\nexport interface CompletedMatcher<Output> {\n readonly _tag: \"CompletedMatcher\";\n readonly result: Output;\n}\n\n// =============================================================================\n// Core Functions\n// =============================================================================\n\n\n/**\n * Add a handler for a specific tag.\n *\n * @example\n * ```typescript\n * Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => e.user.name))\n * ```\n */\nexport function tag<\n Input extends Tagged,\n Remaining extends Tagged,\n Output,\n Tag extends TagOf<Remaining>,\n NewOutput,\n>(\n tagValue: Tag,\n handler: (value: MatchTag<Remaining, Tag>) => NewOutput\n): (\n matcher: Matcher<Input, Remaining, Output>\n) => Matcher<Input, Exclude<Remaining, { _tag: Tag }>, Output | NewOutput> {\n return (matcher) => {\n const newHandlers = new Map(matcher.handlers);\n newHandlers.set(tagValue, handler as (value: Tagged) => unknown);\n\n return {\n _tag: \"Matcher\",\n value: matcher.value,\n handlers: newHandlers,\n _remaining: undefined as unknown as Exclude<Remaining, { _tag: Tag }>,\n _output: undefined as unknown as Output | NewOutput,\n };\n };\n}\n\n/**\n * Add handlers for multiple tags at once.\n *\n * @example\n * ```typescript\n * Match.value(event)\n * .pipe(Match.tags({\n * UserCreated: e => e.user.name,\n * UserUpdated: e => e.userId,\n * }))\n * ```\n */\nexport function tags<\n Input extends Tagged,\n Remaining extends Tagged,\n Output,\n Handlers extends {\n [K in TagOf<Remaining>]?: (value: MatchTag<Remaining, K>) => unknown;\n },\n>(\n handlers: Handlers\n): (\n matcher: Matcher<Input, Remaining, Output>\n) => Matcher<\n Input,\n Exclude<Remaining, { _tag: keyof Handlers }>,\n Output | ReturnType<NonNullable<Handlers[keyof Handlers]>>\n> {\n return (matcher) => {\n const newHandlers = new Map(matcher.handlers);\n for (const [tagValue, handler] of Object.entries(handlers)) {\n if (handler) {\n newHandlers.set(tagValue, handler as (value: Tagged) => unknown);\n }\n }\n\n return {\n _tag: \"Matcher\",\n value: matcher.value,\n handlers: newHandlers,\n _remaining: undefined as unknown as Exclude<Remaining, { _tag: keyof Handlers }>,\n _output: undefined as unknown as Output | ReturnType<NonNullable<Handlers[keyof Handlers]>>,\n };\n };\n}\n\n/**\n * Complete the match, requiring all cases to be handled.\n * This is a compile-time check - if any cases are missing, TypeScript will error.\n *\n * @example\n * ```typescript\n * // TypeScript error if any tag is not handled\n * const result = Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => e.user))\n * .pipe(Match.tag(\"UserUpdated\", e => e.userId))\n * .pipe(Match.tag(\"UserDeleted\", e => e.userId))\n * .pipe(Match.exhaustive)\n * ```\n */\nexport function exhaustive<Input extends Tagged, Output>(\n matcher: Matcher<Input, never, Output>\n): Output {\n const handler = matcher.handlers.get(matcher.value._tag);\n if (!handler) {\n throw new Error(`No handler for tag: ${matcher.value._tag}`);\n }\n return handler(matcher.value) as Output;\n}\n\n/**\n * Complete the match with a default handler for any remaining cases.\n *\n * @example\n * ```typescript\n * const result = Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => `Created: ${e.user.name}`))\n * .pipe(Match.orElse(e => `Other event: ${e._tag}`))\n * ```\n */\nexport function orElse<Input extends Tagged, Remaining extends Tagged, Output, DefaultOutput>(\n handler: (value: Remaining) => DefaultOutput\n): (matcher: Matcher<Input, Remaining, Output>) => Output | DefaultOutput {\n return (matcher) => {\n const specificHandler = matcher.handlers.get(matcher.value._tag);\n if (specificHandler) {\n return specificHandler(matcher.value) as Output;\n }\n return handler(matcher.value as unknown as Remaining);\n };\n}\n\n/**\n * Complete the match with a default value for any remaining cases.\n *\n * @example\n * ```typescript\n * const result = Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => e.user.name))\n * .pipe(Match.orElseValue(\"Unknown event\"))\n * ```\n */\nexport function orElseValue<Input extends Tagged, Remaining extends Tagged, Output, DefaultOutput>(\n defaultValue: DefaultOutput\n): (matcher: Matcher<Input, Remaining, Output>) => Output | DefaultOutput {\n return orElse(() => defaultValue);\n}\n\n// =============================================================================\n// Predicates & Guards\n// =============================================================================\n\n/**\n * Add a handler with an additional predicate.\n * The handler only runs if both the tag matches AND the predicate returns true.\n *\n * @example\n * ```typescript\n * Match.value(event)\n * .pipe(Match.when(\n * \"UserCreated\",\n * e => e.user.isAdmin,\n * e => `Admin created: ${e.user.name}`\n * ))\n * ```\n */\nexport function when<\n Input extends Tagged,\n Remaining extends Tagged,\n Output,\n Tag extends TagOf<Input>,\n NewOutput,\n>(\n tagValue: Tag,\n predicate: (value: MatchTag<Input, Tag>) => boolean,\n handler: (value: MatchTag<Input, Tag>) => NewOutput\n): (matcher: Matcher<Input, Remaining, Output>) => Matcher<Input, Remaining, Output | NewOutput> {\n return (matcher) => {\n const newHandlers = new Map(matcher.handlers);\n const existingHandler = matcher.handlers.get(tagValue);\n\n newHandlers.set(tagValue, (value: Tagged) => {\n const typedValue = value as MatchTag<Input, Tag>;\n if (predicate(typedValue)) {\n return handler(typedValue);\n }\n if (existingHandler) {\n return existingHandler(value);\n }\n throw new Error(`No handler matched for tag: ${tagValue}`);\n });\n\n return {\n _tag: \"Matcher\",\n value: matcher.value,\n handlers: newHandlers,\n _remaining: matcher._remaining,\n _output: undefined as unknown as Output | NewOutput,\n };\n };\n}\n\n// =============================================================================\n// Type Narrowing Utilities\n// =============================================================================\n\n/**\n * Check if a tagged value has a specific tag.\n * Type guard that narrows the type.\n *\n * @example\n * ```typescript\n * if (Match.is(\"UserCreated\")(event)) {\n * // event is narrowed to { _tag: 'UserCreated'; user: User }\n * console.log(event.user.name);\n * }\n * ```\n */\nexport function is<T extends Tagged, Tag extends string>(\n tagValue: Tag\n): (value: T) => value is Extract<T, { _tag: Tag }> {\n return (value): value is Extract<T, { _tag: Tag }> => value._tag === tagValue;\n}\n\n/**\n * Check if a tagged value has one of several tags.\n *\n * @example\n * ```typescript\n * if (Match.isOneOf(\"UserCreated\", \"UserUpdated\")(event)) {\n * // event is narrowed to UserCreated | UserUpdated\n * }\n * ```\n */\nexport function isOneOf<T extends Tagged, Tags extends TagOf<T>[]>(\n ...tags: Tags\n): (value: T) => value is Extract<T, { _tag: Tags[number] }> {\n const tagSet = new Set(tags);\n return (value): value is Extract<T, { _tag: Tags[number] }> =>\n tagSet.has(value._tag as Tags[number]);\n}\n\n// =============================================================================\n// Pipe Helper\n// =============================================================================\n\n/**\n * Type guard to check if a value is a Matcher.\n */\nfunction isMatcher(value: unknown): value is Matcher<Tagged, Tagged, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"_tag\" in value &&\n (value as { _tag: unknown })._tag === \"Matcher\"\n );\n}\n\ntype PipedMatcher<Input extends Tagged, Remaining extends Tagged, Output> =\n Matcher<Input, Remaining, Output> & {\n pipe: <NewRemaining extends Tagged, NewOutput>(\n fn: (self: Matcher<Input, Remaining, Output>) => Matcher<Input, NewRemaining, NewOutput>\n ) => PipedMatcher<Input, NewRemaining, NewOutput>;\n } & {\n pipe: <R>(fn: (self: Matcher<Input, Remaining, Output>) => R) => R;\n };\n\nfunction addPipe<Input extends Tagged, Remaining extends Tagged, Output>(\n matcher: Matcher<Input, Remaining, Output>\n): PipedMatcher<Input, Remaining, Output> {\n return {\n ...matcher,\n pipe(fn: (self: Matcher<Input, Remaining, Output>) => unknown): unknown {\n const result = fn(matcher);\n // If result is a Matcher, add pipe to it too\n if (isMatcher(result)) {\n return addPipe(result as Matcher<Tagged, Tagged, unknown>);\n }\n return result;\n },\n } as PipedMatcher<Input, Remaining, Output>;\n}\n\n/**\n * Start matching on a value (with pipe support).\n *\n * @example\n * ```typescript\n * const result = Match.value(event)\n * .pipe(Match.tag(\"Created\", e => e.id))\n * .pipe(Match.exhaustive)\n * ```\n */\nexport function matchValue<T extends Tagged>(input: T): PipedMatcher<T, T, never> {\n const matcher: Matcher<T, T, never> = {\n _tag: \"Matcher\",\n value: input,\n handlers: new Map(),\n _remaining: input as T,\n _output: undefined as never,\n };\n\n return addPipe(matcher);\n}\n\n// =============================================================================\n// Namespace Export\n// =============================================================================\n\n/**\n * Match namespace for exhaustive pattern matching.\n *\n * @example\n * ```typescript\n * import { Match } from \"awaitly\";\n *\n * type Event =\n * | { _tag: 'Created'; id: string }\n * | { _tag: 'Updated'; id: string; data: unknown }\n * | { _tag: 'Deleted'; id: string }\n *\n * function handle(event: Event): string {\n * return Match.value(event)\n * .pipe(Match.tag(\"Created\", e => `Created: ${e.id}`))\n * .pipe(Match.tag(\"Updated\", e => `Updated: ${e.id}`))\n * .pipe(Match.tag(\"Deleted\", e => `Deleted: ${e.id}`))\n * .pipe(Match.exhaustive)\n * }\n * ```\n */\nexport const Match = {\n value: matchValue,\n tag,\n tags,\n when,\n exhaustive,\n orElse,\n orElseValue,\n is,\n isOneOf,\n} as const;\n","/**\n * Circuit Breaker for Steps\n *\n * Prevents cascading failures by tracking step failure rates and\n * short-circuiting calls when a threshold is exceeded.\n *\n * Uses the circuit breaker pattern with three states:\n * - CLOSED: Normal operation (steps executing)\n * - OPEN: Fast-fail mode (steps blocked)\n * - HALF_OPEN: Testing if service recovered\n *\n * @example\n * ```typescript\n * import { createCircuitBreaker } from 'awaitly';\n *\n * const breaker = createCircuitBreaker({\n * failureThreshold: 5,\n * resetTimeout: 30000,\n * halfOpenMax: 3,\n * });\n *\n * const result = await workflow(async ({ step }) => {\n * const data = await breaker.execute(\n * () => step(() => callExternalApi()),\n * { name: 'external-api' }\n * );\n * return data;\n * });\n * ```\n */\n\nimport { err, type Result, type AsyncResult } from \"./core\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Circuit breaker state.\n */\nexport type CircuitState = \"CLOSED\" | \"OPEN\" | \"HALF_OPEN\";\n\n/**\n * Configuration for circuit breaker behavior.\n */\nexport interface CircuitBreakerConfig {\n /**\n * Number of failures within the window before opening the circuit.\n * @default 5\n */\n failureThreshold: number;\n\n /**\n * Time in ms to wait before transitioning from OPEN to HALF_OPEN.\n * @default 30000 (30 seconds)\n */\n resetTimeout: number;\n\n /**\n * Time window in ms for counting failures.\n * Failures older than this are discarded.\n * @default 60000 (1 minute)\n */\n windowSize: number;\n\n /**\n * Maximum number of test requests allowed in HALF_OPEN state.\n * If all succeed, circuit closes. If any fail, circuit reopens.\n * @default 3\n */\n halfOpenMax: number;\n\n /**\n * Optional callback when circuit state changes.\n */\n onStateChange?: (from: CircuitState, to: CircuitState, name?: string) => void;\n}\n\n/**\n * Error thrown when the circuit is open and calls are blocked.\n */\nexport class CircuitOpenError extends Error {\n readonly type = \"CIRCUIT_OPEN\" as const;\n readonly circuitName: string;\n readonly state: CircuitState;\n readonly retryAfterMs: number;\n\n constructor(options: {\n circuitName: string;\n state: CircuitState;\n retryAfterMs: number;\n message?: string;\n }) {\n super(\n options.message ??\n `Circuit breaker \"${options.circuitName}\" is ${options.state}. ` +\n `Retry after ${Math.ceil(options.retryAfterMs / 1000)}s`\n );\n this.name = \"CircuitOpenError\";\n this.circuitName = options.circuitName;\n this.state = options.state;\n this.retryAfterMs = options.retryAfterMs;\n }\n}\n\n/**\n * Type guard for CircuitOpenError.\n */\nexport function isCircuitOpenError(error: unknown): error is CircuitOpenError {\n return (\n typeof error === \"object\" &&\n error !== null &&\n (error as CircuitOpenError).type === \"CIRCUIT_OPEN\"\n );\n}\n\n/**\n * Failure record for tracking failures within the window.\n */\ninterface FailureRecord {\n timestamp: number;\n error: unknown;\n}\n\n/**\n * Circuit breaker statistics.\n */\nexport interface CircuitBreakerStats {\n state: CircuitState;\n failureCount: number;\n successCount: number;\n lastFailureTime: number | null;\n lastSuccessTime: number | null;\n halfOpenSuccesses: number;\n}\n\n// =============================================================================\n// Default Configuration\n// =============================================================================\n\nconst DEFAULT_CONFIG: CircuitBreakerConfig = {\n failureThreshold: 5,\n resetTimeout: 30_000,\n windowSize: 60_000,\n halfOpenMax: 3,\n};\n\n// =============================================================================\n// Circuit Breaker Implementation\n// =============================================================================\n\n/**\n * Circuit breaker instance for protecting external calls.\n */\nexport interface CircuitBreaker {\n /**\n * Execute an operation with circuit breaker protection.\n * Throws CircuitOpenError if the circuit is open.\n *\n * @param operation - The operation to execute\n * @param options - Optional name for logging/metrics\n * @returns The operation result\n * @throws CircuitOpenError if circuit is open\n */\n execute<T>(\n operation: () => T | Promise<T>,\n options?: { name?: string }\n ): Promise<T>;\n\n /**\n * Execute a Result-returning operation with circuit breaker protection.\n * Returns a CircuitOpenError result instead of throwing.\n *\n * @param operation - The operation returning a Result\n * @param options - Optional name for logging/metrics\n * @returns Result with the value or CircuitOpenError\n */\n executeResult<T, E>(\n operation: () => Result<T, E> | AsyncResult<T, E>,\n options?: { name?: string }\n ): AsyncResult<T, E | CircuitOpenError>;\n\n /**\n * Get current circuit state.\n */\n getState(): CircuitState;\n\n /**\n * Get circuit breaker statistics.\n */\n getStats(): CircuitBreakerStats;\n\n /**\n * Manually reset the circuit breaker to CLOSED state.\n */\n reset(): void;\n\n /**\n * Manually open the circuit (for testing or manual intervention).\n */\n forceOpen(): void;\n\n /**\n * Record a manual success (useful for health checks).\n */\n recordSuccess(): void;\n\n /**\n * Record a manual failure (useful for health checks).\n */\n recordFailure(error?: unknown): void;\n}\n\n/**\n * Create a circuit breaker instance.\n *\n * @param name - Name for this circuit breaker (used in errors and logging)\n * @param config - Configuration options\n * @returns A CircuitBreaker instance\n *\n * @example\n * ```typescript\n * const apiBreaker = createCircuitBreaker('external-api', {\n * failureThreshold: 5,\n * resetTimeout: 30000,\n * });\n *\n * // In workflow\n * const data = await apiBreaker.execute(() =>\n * step(() => fetchFromApi(id))\n * );\n * ```\n */\nexport function createCircuitBreaker(\n name: string,\n config?: Partial<CircuitBreakerConfig>\n): CircuitBreaker {\n const effectiveConfig: CircuitBreakerConfig = {\n ...DEFAULT_CONFIG,\n ...config,\n };\n\n let state: CircuitState = \"CLOSED\";\n let failures: FailureRecord[] = [];\n let lastFailureTime: number | null = null;\n let lastSuccessTime: number | null = null;\n let successCount = 0;\n let halfOpenSuccesses = 0;\n\n /**\n * Clean up old failures outside the time window.\n */\n function cleanupFailures(): void {\n const now = Date.now();\n failures = failures.filter(\n (f) => now - f.timestamp < effectiveConfig.windowSize\n );\n }\n\n /**\n * Transition to a new state.\n */\n function transitionTo(newState: CircuitState): void {\n if (state !== newState) {\n const oldState = state;\n state = newState;\n if (newState === \"HALF_OPEN\") {\n halfOpenSuccesses = 0;\n }\n effectiveConfig.onStateChange?.(oldState, newState, name);\n }\n }\n\n /**\n * Check if we should transition from OPEN to HALF_OPEN.\n */\n function checkOpenToHalfOpen(): boolean {\n if (state !== \"OPEN\" || lastFailureTime === null) {\n return false;\n }\n const now = Date.now();\n if (now - lastFailureTime >= effectiveConfig.resetTimeout) {\n transitionTo(\"HALF_OPEN\");\n return true;\n }\n return false;\n }\n\n /**\n * Record a successful operation.\n */\n function handleSuccess(): void {\n lastSuccessTime = Date.now();\n successCount++;\n\n if (state === \"HALF_OPEN\") {\n halfOpenSuccesses++;\n if (halfOpenSuccesses >= effectiveConfig.halfOpenMax) {\n // All test requests succeeded, close the circuit\n transitionTo(\"CLOSED\");\n failures = [];\n }\n }\n }\n\n /**\n * Record a failed operation.\n */\n function handleFailure(error: unknown): void {\n const now = Date.now();\n lastFailureTime = now;\n\n // Clean up old failures first\n cleanupFailures();\n\n // Add new failure\n failures.push({ timestamp: now, error });\n\n if (state === \"HALF_OPEN\") {\n // Any failure in HALF_OPEN reopens the circuit\n transitionTo(\"OPEN\");\n } else if (state === \"CLOSED\") {\n // Check if we should open the circuit\n if (failures.length >= effectiveConfig.failureThreshold) {\n transitionTo(\"OPEN\");\n }\n }\n }\n\n /**\n * Check if the circuit allows execution.\n * Returns the remaining wait time if blocked, or 0 if allowed.\n */\n function canExecute(): number {\n if (state === \"CLOSED\") {\n return 0;\n }\n\n if (state === \"OPEN\") {\n // Check if we should transition to HALF_OPEN\n if (checkOpenToHalfOpen()) {\n return 0; // Now in HALF_OPEN, allow execution\n }\n // Still OPEN, calculate remaining wait time\n const now = Date.now();\n const elapsed = lastFailureTime ? now - lastFailureTime : 0;\n return Math.max(0, effectiveConfig.resetTimeout - elapsed);\n }\n\n // HALF_OPEN - allow limited test requests\n return 0;\n }\n\n return {\n async execute<T>(\n operation: () => T | Promise<T>,\n _options?: { name?: string }\n ): Promise<T> {\n const waitTime = canExecute();\n if (waitTime > 0) {\n throw new CircuitOpenError({\n circuitName: name,\n state,\n retryAfterMs: waitTime,\n });\n }\n\n try {\n const result = await operation();\n handleSuccess();\n return result;\n } catch (error) {\n handleFailure(error);\n throw error;\n }\n },\n\n async executeResult<T, E>(\n operation: () => Result<T, E> | AsyncResult<T, E>,\n _options?: { name?: string }\n ): AsyncResult<T, E | CircuitOpenError> {\n const waitTime = canExecute();\n if (waitTime > 0) {\n return err(\n new CircuitOpenError({\n circuitName: name,\n state,\n retryAfterMs: waitTime,\n })\n );\n }\n\n try {\n const result = await operation();\n if (result.ok) {\n handleSuccess();\n } else {\n handleFailure(result.error);\n }\n return result;\n } catch (error) {\n handleFailure(error);\n throw error;\n }\n },\n\n getState(): CircuitState {\n // Check for automatic transition before returning\n if (state === \"OPEN\") {\n checkOpenToHalfOpen();\n }\n return state;\n },\n\n getStats(): CircuitBreakerStats {\n cleanupFailures();\n return {\n state: this.getState(),\n failureCount: failures.length,\n successCount,\n lastFailureTime,\n lastSuccessTime,\n halfOpenSuccesses,\n };\n },\n\n reset(): void {\n transitionTo(\"CLOSED\");\n failures = [];\n halfOpenSuccesses = 0;\n },\n\n forceOpen(): void {\n lastFailureTime = Date.now();\n transitionTo(\"OPEN\");\n },\n\n recordSuccess(): void {\n handleSuccess();\n },\n\n recordFailure(error?: unknown): void {\n handleFailure(error ?? new Error(\"Manual failure\"));\n },\n };\n}\n\n// =============================================================================\n// Presets\n// =============================================================================\n\n/**\n * Preset configurations for common use cases.\n */\nexport const circuitBreakerPresets = {\n /**\n * Aggressive circuit breaker for critical paths.\n * Opens quickly (3 failures) and recovers slowly (60s).\n */\n critical: {\n failureThreshold: 3,\n resetTimeout: 60_000,\n windowSize: 30_000,\n halfOpenMax: 1,\n } satisfies Partial<CircuitBreakerConfig>,\n\n /**\n * Standard circuit breaker for typical API calls.\n * Balanced between stability and availability.\n */\n standard: {\n failureThreshold: 5,\n resetTimeout: 30_000,\n windowSize: 60_000,\n halfOpenMax: 3,\n } satisfies Partial<CircuitBreakerConfig>,\n\n /**\n * Lenient circuit breaker for non-critical operations.\n * Opens slowly (10 failures) and recovers quickly (15s).\n */\n lenient: {\n failureThreshold: 10,\n resetTimeout: 15_000,\n windowSize: 120_000,\n halfOpenMax: 5,\n } satisfies Partial<CircuitBreakerConfig>,\n} as const;\n","/**\n * Rate Limiting / Concurrency Control\n *\n * Control throughput for steps that hit rate-limited APIs or shared resources.\n *\n * @example\n * ```typescript\n * import { createRateLimiter, createConcurrencyLimiter } from 'awaitly';\n *\n * // Rate limiting (requests per second)\n * const rateLimiter = createRateLimiter({ maxPerSecond: 10 });\n *\n * // Concurrency limiting (max concurrent)\n * const concurrencyLimiter = createConcurrencyLimiter({ maxConcurrent: 5 });\n *\n * const result = await workflow(async ({ step }) => {\n * // Wrap operations with rate limiting\n * const data = await rateLimiter.execute(() =>\n * step(() => callRateLimitedApi())\n * );\n *\n * // Wrap batch operations with concurrency control\n * const results = await concurrencyLimiter.executeAll(\n * ids.map(id => () => step(() => fetchItem(id)))\n * );\n *\n * return { data, results };\n * });\n * ```\n */\n\nimport { err, type Result, type AsyncResult } from \"../core\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Configuration for rate limiter.\n */\nexport interface RateLimiterConfig {\n /**\n * Maximum operations per second.\n */\n maxPerSecond: number;\n\n /**\n * Burst capacity - allows brief spikes above the rate.\n * @default maxPerSecond * 2\n */\n burstCapacity?: number;\n\n /**\n * Strategy when rate limit is exceeded.\n * - 'wait': Wait until a slot is available (default)\n * - 'reject': Reject immediately with error\n * @default 'wait'\n */\n strategy?: \"wait\" | \"reject\";\n}\n\n/**\n * Configuration for concurrency limiter.\n */\nexport interface ConcurrencyLimiterConfig {\n /**\n * Maximum concurrent operations.\n */\n maxConcurrent: number;\n\n /**\n * Strategy when limit is reached.\n * - 'queue': Queue and wait (default)\n * - 'reject': Reject immediately\n * @default 'queue'\n */\n strategy?: \"queue\" | \"reject\";\n\n /**\n * Maximum queue size (only for 'queue' strategy).\n * @default Infinity\n */\n maxQueueSize?: number;\n}\n\n/**\n * Error when rate/concurrency limit is exceeded and strategy is 'reject'.\n */\nexport interface RateLimitExceededError {\n type: \"RATE_LIMIT_EXCEEDED\";\n limiterName: string;\n retryAfterMs?: number;\n}\n\n/**\n * Error when concurrency limit queue is full.\n */\nexport interface QueueFullError {\n type: \"QUEUE_FULL\";\n limiterName: string;\n queueSize: number;\n maxQueueSize: number;\n}\n\n/**\n * Type guard for RateLimitExceededError.\n */\nexport function isRateLimitExceededError(\n error: unknown\n): error is RateLimitExceededError {\n return (\n typeof error === \"object\" &&\n error !== null &&\n (error as RateLimitExceededError).type === \"RATE_LIMIT_EXCEEDED\"\n );\n}\n\n/**\n * Type guard for QueueFullError.\n */\nexport function isQueueFullError(error: unknown): error is QueueFullError {\n return (\n typeof error === \"object\" &&\n error !== null &&\n (error as QueueFullError).type === \"QUEUE_FULL\"\n );\n}\n\n/**\n * Statistics for rate limiter.\n */\nexport interface RateLimiterStats {\n availableTokens: number;\n maxTokens: number;\n tokensPerSecond: number;\n waitingCount: number;\n}\n\n/**\n * Statistics for concurrency limiter.\n */\nexport interface ConcurrencyLimiterStats {\n activeCount: number;\n maxConcurrent: number;\n queueSize: number;\n maxQueueSize: number;\n}\n\n// =============================================================================\n// Rate Limiter (Token Bucket)\n// =============================================================================\n\n/**\n * Rate limiter interface.\n */\nexport interface RateLimiter {\n /**\n * Execute an operation with rate limiting.\n * @param operation - The operation to execute\n * @returns The operation result\n */\n execute<T>(operation: () => T | Promise<T>): Promise<T>;\n\n /**\n * Execute a Result-returning operation with rate limiting.\n */\n executeResult<T, E>(\n operation: () => Result<T, E> | AsyncResult<T, E>\n ): AsyncResult<T, E | RateLimitExceededError>;\n\n /**\n * Get current statistics.\n */\n getStats(): RateLimiterStats;\n\n /**\n * Reset the rate limiter.\n */\n reset(): void;\n}\n\n/**\n * Create a token bucket rate limiter.\n *\n * @param name - Name for the limiter (used in errors)\n * @param config - Rate limiter configuration\n * @returns A RateLimiter instance\n *\n * @example\n * ```typescript\n * const limiter = createRateLimiter('api-calls', {\n * maxPerSecond: 10,\n * burstCapacity: 20,\n * });\n *\n * // In workflow\n * const data = await limiter.execute(() =>\n * step(() => callApi())\n * );\n * ```\n */\nexport function createRateLimiter(\n name: string,\n config: RateLimiterConfig\n): RateLimiter {\n const { maxPerSecond, strategy = \"wait\" } = config;\n const maxTokens = config.burstCapacity ?? maxPerSecond * 2;\n\n let tokens = maxTokens;\n let lastRefill = Date.now();\n const refillRate = maxPerSecond / 1000; // tokens per ms\n\n // Queue for waiting requests\n const waitQueue: Array<() => void> = [];\n\n /**\n * Refill tokens based on elapsed time.\n */\n function refill(): void {\n const now = Date.now();\n const elapsed = now - lastRefill;\n const tokensToAdd = elapsed * refillRate;\n tokens = Math.min(maxTokens, tokens + tokensToAdd);\n lastRefill = now;\n }\n\n /**\n * Try to consume a token.\n * Returns remaining wait time if no tokens available.\n */\n function tryConsume(): number {\n refill();\n if (tokens >= 1) {\n tokens -= 1;\n return 0;\n }\n // Calculate wait time for next token\n const tokensNeeded = 1 - tokens;\n return Math.ceil(tokensNeeded / refillRate);\n }\n\n /**\n * Wait for a token to be available.\n */\n async function waitForToken(): Promise<void> {\n return new Promise((resolve) => {\n const check = () => {\n const waitTime = tryConsume();\n if (waitTime === 0) {\n resolve();\n } else {\n waitQueue.push(check);\n setTimeout(() => {\n const idx = waitQueue.indexOf(check);\n if (idx !== -1) {\n waitQueue.splice(idx, 1);\n check();\n }\n }, waitTime);\n }\n };\n check();\n });\n }\n\n return {\n async execute<T>(operation: () => T | Promise<T>): Promise<T> {\n const waitTime = tryConsume();\n\n if (waitTime > 0) {\n if (strategy === \"reject\") {\n throw {\n type: \"RATE_LIMIT_EXCEEDED\",\n limiterName: name,\n retryAfterMs: waitTime,\n } as RateLimitExceededError;\n }\n\n // Wait strategy\n await waitForToken();\n }\n\n return operation();\n },\n\n async executeResult<T, E>(\n operation: () => Result<T, E> | AsyncResult<T, E>\n ): AsyncResult<T, E | RateLimitExceededError> {\n const waitTime = tryConsume();\n\n if (waitTime > 0) {\n if (strategy === \"reject\") {\n return err({\n type: \"RATE_LIMIT_EXCEEDED\",\n limiterName: name,\n retryAfterMs: waitTime,\n });\n }\n\n // Wait strategy\n await waitForToken();\n }\n\n return operation();\n },\n\n getStats(): RateLimiterStats {\n refill();\n return {\n availableTokens: Math.floor(tokens),\n maxTokens,\n tokensPerSecond: maxPerSecond,\n waitingCount: waitQueue.length,\n };\n },\n\n reset(): void {\n tokens = maxTokens;\n lastRefill = Date.now();\n // Clear wait queue\n waitQueue.length = 0;\n },\n };\n}\n\n// =============================================================================\n// Concurrency Limiter\n// =============================================================================\n\n/**\n * Concurrency limiter interface.\n */\nexport interface ConcurrencyLimiter {\n /**\n * Execute an operation with concurrency limiting.\n * @param operation - The operation to execute\n * @returns The operation result\n */\n execute<T>(operation: () => T | Promise<T>): Promise<T>;\n\n /**\n * Execute multiple operations with concurrency control.\n * @param operations - Array of operation factories\n * @returns Array of results (in order)\n */\n executeAll<T>(operations: Array<() => T | Promise<T>>): Promise<T[]>;\n\n /**\n * Execute a Result-returning operation with concurrency limiting.\n */\n executeResult<T, E>(\n operation: () => Result<T, E> | AsyncResult<T, E>\n ): AsyncResult<T, E | QueueFullError>;\n\n /**\n * Get current statistics.\n */\n getStats(): ConcurrencyLimiterStats;\n\n /**\n * Reset the concurrency limiter.\n */\n reset(): void;\n}\n\n/**\n * Create a concurrency limiter.\n *\n * @param name - Name for the limiter (used in errors)\n * @param config - Concurrency limiter configuration\n * @returns A ConcurrencyLimiter instance\n *\n * @example\n * ```typescript\n * const limiter = createConcurrencyLimiter('db-pool', {\n * maxConcurrent: 10,\n * });\n *\n * // Execute with concurrency control\n * const results = await limiter.executeAll(\n * ids.map(id => () => fetchItem(id))\n * );\n * ```\n */\nexport function createConcurrencyLimiter(\n name: string,\n config: ConcurrencyLimiterConfig\n): ConcurrencyLimiter {\n const { maxConcurrent, strategy = \"queue\", maxQueueSize = Infinity } = config;\n\n let activeCount = 0;\n const queue: Array<{ resolve: () => void; reject: (e: unknown) => void }> = [];\n\n /**\n * Acquire a slot.\n */\n async function acquire(): Promise<void> {\n if (activeCount < maxConcurrent) {\n activeCount++;\n return;\n }\n\n if (strategy === \"reject\") {\n throw {\n type: \"QUEUE_FULL\",\n limiterName: name,\n queueSize: queue.length,\n maxQueueSize,\n } as QueueFullError;\n }\n\n // Queue strategy\n if (queue.length >= maxQueueSize) {\n throw {\n type: \"QUEUE_FULL\",\n limiterName: name,\n queueSize: queue.length,\n maxQueueSize,\n } as QueueFullError;\n }\n\n return new Promise<void>((resolve, reject) => {\n queue.push({ resolve, reject });\n });\n }\n\n /**\n * Release a slot.\n */\n function release(): void {\n activeCount--;\n if (queue.length > 0 && activeCount < maxConcurrent) {\n activeCount++;\n const next = queue.shift();\n next?.resolve();\n }\n }\n\n return {\n async execute<T>(operation: () => T | Promise<T>): Promise<T> {\n await acquire();\n try {\n return await operation();\n } finally {\n release();\n }\n },\n\n async executeAll<T>(operations: Array<() => T | Promise<T>>): Promise<T[]> {\n const results: T[] = new Array(operations.length);\n const executing: Promise<void>[] = [];\n\n for (let i = 0; i < operations.length; i++) {\n const index = i;\n const promise = this.execute(operations[index]).then((result) => {\n results[index] = result;\n });\n executing.push(promise);\n }\n\n await Promise.all(executing);\n return results;\n },\n\n async executeResult<T, E>(\n operation: () => Result<T, E> | AsyncResult<T, E>\n ): AsyncResult<T, E | QueueFullError> {\n try {\n await acquire();\n } catch (error) {\n if (isQueueFullError(error)) {\n return err(error);\n }\n throw error;\n }\n\n try {\n return await operation();\n } finally {\n release();\n }\n },\n\n getStats(): ConcurrencyLimiterStats {\n return {\n activeCount,\n maxConcurrent,\n queueSize: queue.length,\n maxQueueSize,\n };\n },\n\n reset(): void {\n activeCount = 0;\n // Reject all queued operations\n while (queue.length > 0) {\n const item = queue.shift();\n item?.reject(new Error(\"Limiter reset\"));\n }\n },\n };\n}\n\n// =============================================================================\n// Combined Limiter\n// =============================================================================\n\n/**\n * Configuration for combined rate + concurrency limiter.\n */\nexport interface CombinedLimiterConfig {\n /**\n * Rate limiting configuration.\n */\n rate?: RateLimiterConfig;\n\n /**\n * Concurrency limiting configuration.\n */\n concurrency?: ConcurrencyLimiterConfig;\n}\n\n/**\n * Create a combined rate + concurrency limiter.\n *\n * Operations are first rate-limited, then concurrency-limited.\n *\n * @param name - Name for the limiter\n * @param config - Combined limiter configuration\n * @returns An object with both limiters and a combined execute function\n *\n * @example\n * ```typescript\n * const limiter = createCombinedLimiter('api', {\n * rate: { maxPerSecond: 10 },\n * concurrency: { maxConcurrent: 5 },\n * });\n *\n * const result = await limiter.execute(() => callApi());\n * ```\n */\nexport function createCombinedLimiter(\n name: string,\n config: CombinedLimiterConfig\n): {\n rate?: RateLimiter;\n concurrency?: ConcurrencyLimiter;\n execute: <T>(operation: () => T | Promise<T>) => Promise<T>;\n} {\n const rate = config.rate ? createRateLimiter(`${name}-rate`, config.rate) : undefined;\n const concurrency = config.concurrency\n ? createConcurrencyLimiter(`${name}-concurrency`, config.concurrency)\n : undefined;\n\n return {\n rate,\n concurrency,\n\n async execute<T>(operation: () => T | Promise<T>): Promise<T> {\n // Apply rate limiting first\n let op = operation;\n if (rate) {\n const originalOp = op;\n op = () => rate.execute(originalOp);\n }\n\n // Then apply concurrency limiting\n if (concurrency) {\n return concurrency.execute(op);\n }\n\n return op();\n },\n };\n}\n\n// =============================================================================\n// Fixed Window Rate Limiter\n// =============================================================================\n\n/**\n * Configuration for fixed window rate limiter.\n */\nexport interface FixedWindowLimiterConfig {\n /**\n * Maximum requests allowed per window.\n */\n limit: number;\n\n /**\n * Window duration in milliseconds.\n * @default 1000 (1 second)\n */\n windowMs?: number;\n\n /**\n * Strategy when rate limit is exceeded.\n * - 'wait': Wait until window resets (default)\n * - 'reject': Reject immediately with error\n * @default 'wait'\n */\n strategy?: \"wait\" | \"reject\";\n}\n\n/**\n * Statistics for fixed window rate limiter.\n */\nexport interface FixedWindowLimiterStats {\n /** Requests made in current window */\n requestCount: number;\n /** Maximum requests allowed per window */\n limit: number;\n /** Window duration in milliseconds */\n windowMs: number;\n /** Time remaining until window reset (ms) */\n remainingMs: number;\n /** Number of requests waiting for next window */\n waitingCount: number;\n}\n\n/**\n * Fixed window rate limiter interface.\n */\nexport interface FixedWindowLimiter {\n /**\n * Execute an operation with rate limiting.\n * @param operation - The operation to execute\n * @param cost - Optional cost for this operation (default: 1)\n * @returns The operation result\n */\n execute<T>(operation: () => T | Promise<T>, cost?: number): Promise<T>;\n\n /**\n * Execute a Result-returning operation with rate limiting.\n * @param operation - The operation to execute\n * @param cost - Optional cost for this operation (default: 1)\n */\n executeResult<T, E>(\n operation: () => Result<T, E> | AsyncResult<T, E>,\n cost?: number\n ): AsyncResult<T, E | RateLimitExceededError>;\n\n /**\n * Get current statistics.\n */\n getStats(): FixedWindowLimiterStats;\n\n /**\n * Reset the rate limiter.\n */\n reset(): void;\n}\n\n/**\n * Create a fixed window rate limiter.\n *\n * Unlike token bucket, fixed window resets at fixed intervals.\n * Simpler to reason about but can allow bursts at window boundaries.\n *\n * @param name - Name for the limiter (used in errors)\n * @param config - Rate limiter configuration\n * @returns A FixedWindowLimiter instance\n *\n * @example\n * ```typescript\n * const limiter = createFixedWindowLimiter('api-calls', {\n * limit: 100, // 100 requests\n * windowMs: 60000, // per minute\n * });\n *\n * // In workflow\n * const data = await limiter.execute(() => callApi());\n *\n * // Cost-based limiting (e.g., batch operations cost more)\n * const batchData = await limiter.execute(() => callBatchApi(), 10);\n * ```\n */\nexport function createFixedWindowLimiter(\n name: string,\n config: FixedWindowLimiterConfig\n): FixedWindowLimiter {\n const { limit, windowMs = 1000, strategy = \"wait\" } = config;\n\n let windowStart = Date.now();\n let requestCount = 0;\n const waitQueue: Array<{ resolve: () => void; cost: number }> = [];\n\n /**\n * Reset window if needed and return remaining time.\n */\n function checkWindow(): number {\n const now = Date.now();\n const elapsed = now - windowStart;\n\n if (elapsed >= windowMs) {\n // New window\n windowStart = now;\n requestCount = 0;\n return 0;\n }\n\n return windowMs - elapsed;\n }\n\n /**\n * Try to consume capacity.\n * Returns remaining wait time if insufficient capacity.\n */\n function tryConsume(cost: number): number {\n const remainingMs = checkWindow();\n\n if (requestCount + cost <= limit) {\n requestCount += cost;\n return 0;\n }\n\n return remainingMs;\n }\n\n /**\n * Wait for next window.\n */\n async function waitForWindow(cost: number): Promise<void> {\n return new Promise((resolve) => {\n const check = () => {\n const waitTime = tryConsume(cost);\n if (waitTime === 0) {\n resolve();\n } else {\n waitQueue.push({ resolve: check, cost });\n setTimeout(() => {\n const idx = waitQueue.findIndex((w) => w.resolve === check);\n if (idx !== -1) {\n waitQueue.splice(idx, 1);\n check();\n }\n }, waitTime);\n }\n };\n check();\n });\n }\n\n return {\n async execute<T>(operation: () => T | Promise<T>, cost = 1): Promise<T> {\n // Reject immediately if cost exceeds limit - can never succeed\n if (cost > limit) {\n throw {\n type: \"RATE_LIMIT_EXCEEDED\",\n limiterName: name,\n retryAfterMs: windowMs,\n } as RateLimitExceededError;\n }\n\n const waitTime = tryConsume(cost);\n\n if (waitTime > 0) {\n if (strategy === \"reject\") {\n throw {\n type: \"RATE_LIMIT_EXCEEDED\",\n limiterName: name,\n retryAfterMs: waitTime,\n } as RateLimitExceededError;\n }\n\n await waitForWindow(cost);\n }\n\n return operation();\n },\n\n async executeResult<T, E>(\n operation: () => Result<T, E> | AsyncResult<T, E>,\n cost = 1\n ): AsyncResult<T, E | RateLimitExceededError> {\n // Reject immediately if cost exceeds limit - can never succeed\n if (cost > limit) {\n return err({\n type: \"RATE_LIMIT_EXCEEDED\",\n limiterName: name,\n retryAfterMs: windowMs,\n });\n }\n\n const waitTime = tryConsume(cost);\n\n if (waitTime > 0) {\n if (strategy === \"reject\") {\n return err({\n type: \"RATE_LIMIT_EXCEEDED\",\n limiterName: name,\n retryAfterMs: waitTime,\n });\n }\n\n await waitForWindow(cost);\n }\n\n return operation();\n },\n\n getStats(): FixedWindowLimiterStats {\n const remainingMs = checkWindow();\n return {\n requestCount,\n limit,\n windowMs,\n remainingMs,\n waitingCount: waitQueue.length,\n };\n },\n\n reset(): void {\n windowStart = Date.now();\n requestCount = 0;\n waitQueue.length = 0;\n },\n };\n}\n\n// =============================================================================\n// Cost-Based Token Bucket Rate Limiter\n// =============================================================================\n\n/**\n * Configuration for cost-based rate limiter.\n */\nexport interface CostBasedRateLimiterConfig {\n /**\n * Maximum tokens (credits) per second refill rate.\n */\n tokensPerSecond: number;\n\n /**\n * Maximum token capacity (burst capacity).\n * @default tokensPerSecond * 2\n */\n maxTokens?: number;\n\n /**\n * Strategy when rate limit is exceeded.\n * - 'wait': Wait until tokens are available (default)\n * - 'reject': Reject immediately with error\n * @default 'wait'\n */\n strategy?: \"wait\" | \"reject\";\n}\n\n/**\n * Statistics for cost-based rate limiter.\n */\nexport interface CostBasedRateLimiterStats {\n /** Available tokens (can be fractional) */\n availableTokens: number;\n /** Maximum token capacity */\n maxTokens: number;\n /** Token refill rate per second */\n tokensPerSecond: number;\n /** Number of operations waiting */\n waitingCount: number;\n}\n\n/**\n * Cost-based rate limiter interface.\n */\nexport interface CostBasedRateLimiter {\n /**\n * Execute an operation with cost-based rate limiting.\n * @param operation - The operation to execute\n * @param cost - Token cost for this operation (default: 1)\n * @returns The operation result\n */\n execute<T>(operation: () => T | Promise<T>, cost?: number): Promise<T>;\n\n /**\n * Execute a Result-returning operation with cost-based rate limiting.\n * @param operation - The operation to execute\n * @param cost - Token cost for this operation (default: 1)\n */\n executeResult<T, E>(\n operation: () => Result<T, E> | AsyncResult<T, E>,\n cost?: number\n ): AsyncResult<T, E | RateLimitExceededError>;\n\n /**\n * Get current statistics.\n */\n getStats(): CostBasedRateLimiterStats;\n\n /**\n * Reset the rate limiter.\n */\n reset(): void;\n}\n\n/**\n * Create a cost-based token bucket rate limiter.\n *\n * Different operations can have different costs, allowing fine-grained\n * control over resource usage. For example, a batch API call might cost\n * 10 tokens while a simple query costs 1.\n *\n * @param name - Name for the limiter (used in errors)\n * @param config - Rate limiter configuration\n * @returns A CostBasedRateLimiter instance\n *\n * @example\n * ```typescript\n * const limiter = createCostBasedRateLimiter('api', {\n * tokensPerSecond: 100, // 100 tokens/second refill\n * maxTokens: 200, // Can burst up to 200 tokens\n * });\n *\n * // Simple query costs 1 token\n * await limiter.execute(() => simpleQuery());\n *\n * // Batch operation costs 10 tokens\n * await limiter.execute(() => batchOperation(), 10);\n *\n * // Heavy export costs 50 tokens\n * await limiter.execute(() => exportData(), 50);\n * ```\n */\nexport function createCostBasedRateLimiter(\n name: string,\n config: CostBasedRateLimiterConfig\n): CostBasedRateLimiter {\n const { tokensPerSecond, strategy = \"wait\" } = config;\n const maxTokens = config.maxTokens ?? tokensPerSecond * 2;\n\n let tokens = maxTokens;\n let lastRefill = Date.now();\n const refillRate = tokensPerSecond / 1000; // tokens per ms\n\n const waitQueue: Array<{ check: () => void; cost: number }> = [];\n\n /**\n * Refill tokens based on elapsed time.\n */\n function refill(): void {\n const now = Date.now();\n const elapsed = now - lastRefill;\n const tokensToAdd = elapsed * refillRate;\n tokens = Math.min(maxTokens, tokens + tokensToAdd);\n lastRefill = now;\n }\n\n /**\n * Try to consume tokens.\n * Returns remaining wait time if insufficient tokens.\n */\n function tryConsume(cost: number): number {\n refill();\n if (tokens >= cost) {\n tokens -= cost;\n return 0;\n }\n // Calculate wait time for needed tokens\n const tokensNeeded = cost - tokens;\n return Math.ceil(tokensNeeded / refillRate);\n }\n\n /**\n * Wait for tokens to be available.\n */\n async function waitForTokens(cost: number): Promise<void> {\n return new Promise((resolve) => {\n const check = () => {\n const waitTime = tryConsume(cost);\n if (waitTime === 0) {\n resolve();\n } else {\n waitQueue.push({ check, cost });\n setTimeout(() => {\n const idx = waitQueue.findIndex((w) => w.check === check);\n if (idx !== -1) {\n waitQueue.splice(idx, 1);\n check();\n }\n }, waitTime);\n }\n };\n check();\n });\n }\n\n return {\n async execute<T>(operation: () => T | Promise<T>, cost = 1): Promise<T> {\n // Reject immediately if cost exceeds maxTokens - can never succeed\n if (cost > maxTokens) {\n throw {\n type: \"RATE_LIMIT_EXCEEDED\",\n limiterName: name,\n retryAfterMs: Math.ceil(cost / refillRate),\n } as RateLimitExceededError;\n }\n\n const waitTime = tryConsume(cost);\n\n if (waitTime > 0) {\n if (strategy === \"reject\") {\n throw {\n type: \"RATE_LIMIT_EXCEEDED\",\n limiterName: name,\n retryAfterMs: waitTime,\n } as RateLimitExceededError;\n }\n\n await waitForTokens(cost);\n }\n\n return operation();\n },\n\n async executeResult<T, E>(\n operation: () => Result<T, E> | AsyncResult<T, E>,\n cost = 1\n ): AsyncResult<T, E | RateLimitExceededError> {\n // Reject immediately if cost exceeds maxTokens - can never succeed\n if (cost > maxTokens) {\n return err({\n type: \"RATE_LIMIT_EXCEEDED\",\n limiterName: name,\n retryAfterMs: Math.ceil(cost / refillRate),\n });\n }\n\n const waitTime = tryConsume(cost);\n\n if (waitTime > 0) {\n if (strategy === \"reject\") {\n return err({\n type: \"RATE_LIMIT_EXCEEDED\",\n limiterName: name,\n retryAfterMs: waitTime,\n });\n }\n\n await waitForTokens(cost);\n }\n\n return operation();\n },\n\n getStats(): CostBasedRateLimiterStats {\n refill();\n return {\n availableTokens: tokens,\n maxTokens,\n tokensPerSecond,\n waitingCount: waitQueue.length,\n };\n },\n\n reset(): void {\n tokens = maxTokens;\n lastRefill = Date.now();\n waitQueue.length = 0;\n },\n };\n}\n\n// =============================================================================\n// Presets\n// =============================================================================\n\n/**\n * Preset configurations for common use cases.\n */\nexport const rateLimiterPresets = {\n /**\n * Typical API rate limit (10 req/s).\n */\n api: {\n maxPerSecond: 10,\n burstCapacity: 20,\n strategy: \"wait\",\n } satisfies RateLimiterConfig,\n\n /**\n * Database pool limit (concurrent connections).\n */\n database: {\n maxConcurrent: 10,\n strategy: \"queue\",\n maxQueueSize: 100,\n } satisfies ConcurrencyLimiterConfig,\n\n /**\n * Aggressive rate limit for external APIs (5 req/s).\n */\n external: {\n maxPerSecond: 5,\n burstCapacity: 10,\n strategy: \"wait\",\n } satisfies RateLimiterConfig,\n} as const;\n","/**\n * awaitly/cache\n *\n * Caching utilities for memoization and deduplication.\n * Inspired by Effect.js caching patterns.\n *\n * @example\n * ```typescript\n * import { cached, cachedWithTTL, cachedFunction, once } from 'awaitly';\n *\n * // Compute once, reuse forever\n * const getConfig = cached(() => loadConfig());\n *\n * // Expire after duration\n * const getUser = cachedWithTTL(() => fetchUser(id), { ttl: '5m' });\n *\n * // Memoize by arguments\n * const fetchUserMemo = cachedFunction((id: string) => fetchUser(id));\n *\n * // Execute exactly once (for initialization)\n * const initDb = once(() => connectToDatabase());\n * ```\n */\n\nimport { Duration, parse as parseDuration } from \"./duration\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Duration input type - supports Duration objects or string shorthand.\n */\nexport type DurationInput = Duration | string;\n\n/**\n * Cache entry with metadata.\n */\nexport interface CacheEntry<T> {\n value: T;\n timestamp: number;\n expiresAt?: number;\n}\n\n/**\n * Cache options.\n */\nexport interface CacheOptions {\n /**\n * Time-to-live for cached values.\n * Accepts Duration or string shorthand like \"5m\", \"1h\", \"30s\".\n */\n ttl?: DurationInput;\n}\n\n/**\n * Cached function options.\n */\nexport interface CachedFunctionOptions<Args extends unknown[]> {\n /**\n * Custom key generator for arguments.\n * Default: JSON.stringify(args)\n */\n keyFn?: (...args: Args) => string;\n\n /**\n * Time-to-live for cached values.\n */\n ttl?: DurationInput;\n\n /**\n * Maximum cache size. When exceeded, oldest entries are evicted.\n * @default Infinity\n */\n maxSize?: number;\n}\n\n/**\n * Cache statistics.\n */\nexport interface CacheStats {\n hits: number;\n misses: number;\n size: number;\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Convert DurationInput to milliseconds.\n */\nfunction toMs(duration: DurationInput): number {\n if (typeof duration === \"string\") {\n const parsed = parseDuration(duration);\n if (!parsed) {\n throw new Error(`Invalid duration string: ${duration}`);\n }\n return parsed.millis;\n }\n return duration.millis;\n}\n\n// =============================================================================\n// cached() - Compute once, reuse forever\n// =============================================================================\n\n/**\n * State for a cached value.\n */\ntype CachedState<T> =\n | { status: \"empty\" }\n | { status: \"pending\"; promise: Promise<T> }\n | { status: \"filled\"; value: T };\n\n/**\n * Create a cached computation that executes once and reuses the result.\n *\n * The function is called at most once, even with concurrent calls.\n * Subsequent calls return the cached value immediately.\n *\n * @param fn - Function to compute the cached value\n * @returns Function that returns the cached value\n *\n * @example\n * ```typescript\n * const getConfig = cached(async () => {\n * console.log('Loading config...');\n * return await loadConfigFromFile();\n * });\n *\n * // First call executes the function\n * const config1 = await getConfig(); // \"Loading config...\"\n *\n * // Subsequent calls return cached value\n * const config2 = await getConfig(); // No log, instant return\n * const config3 = await getConfig(); // No log, instant return\n * ```\n */\nexport function cached<T>(fn: () => T | Promise<T>): () => Promise<T> {\n let state: CachedState<T> = { status: \"empty\" };\n\n return async () => {\n if (state.status === \"filled\") {\n return state.value;\n }\n\n if (state.status === \"pending\") {\n return state.promise;\n }\n\n // Compute the value\n const promise = Promise.resolve(fn()).then((value) => {\n state = { status: \"filled\", value };\n return value;\n });\n\n state = { status: \"pending\", promise };\n return promise;\n };\n}\n\n// =============================================================================\n// cachedWithTTL() - Expire after duration\n// =============================================================================\n\n/**\n * State for a TTL-cached value.\n */\ntype CachedTTLState<T> =\n | { status: \"empty\" }\n | { status: \"pending\"; promise: Promise<T> }\n | { status: \"filled\"; value: T; expiresAt: number };\n\n/**\n * Create a cached computation that expires after a duration.\n *\n * The function is re-executed when the TTL expires.\n * Concurrent calls while computing share the same promise.\n *\n * @param fn - Function to compute the cached value\n * @param options - Cache options including TTL\n * @returns Function that returns the cached value\n *\n * @example\n * ```typescript\n * const getUser = cachedWithTTL(\n * async () => await fetchUser(userId),\n * { ttl: '5m' } // Cache for 5 minutes\n * );\n *\n * const user1 = await getUser(); // Fetches from API\n * const user2 = await getUser(); // Returns cached (within 5 min)\n *\n * // After 5 minutes...\n * const user3 = await getUser(); // Fetches again\n * ```\n */\nexport function cachedWithTTL<T>(\n fn: () => T | Promise<T>,\n options: { ttl: DurationInput }\n): () => Promise<T> {\n const ttlMs = toMs(options.ttl);\n let state: CachedTTLState<T> = { status: \"empty\" };\n\n return async () => {\n const now = Date.now();\n\n // Check if cached value is still valid\n if (state.status === \"filled\" && now < state.expiresAt) {\n return state.value;\n }\n\n // Check if already computing\n if (state.status === \"pending\") {\n return state.promise;\n }\n\n // Compute the value\n const promise = Promise.resolve(fn()).then((value) => {\n state = {\n status: \"filled\",\n value,\n expiresAt: Date.now() + ttlMs,\n };\n return value;\n });\n\n state = { status: \"pending\", promise };\n return promise;\n };\n}\n\n// =============================================================================\n// cachedFunction() - Memoize by arguments\n// =============================================================================\n\n/**\n * Cache entry for memoized functions.\n */\ninterface MemoEntry<T> {\n value: T;\n timestamp: number;\n expiresAt?: number;\n}\n\n/**\n * Memoized function interface.\n */\nexport interface MemoizedFunction<Args extends unknown[], T> {\n (...args: Args): Promise<T>;\n /** Clear the entire cache */\n clear(): void;\n /** Clear a specific cache entry */\n delete(...args: Args): boolean;\n /** Check if an entry exists */\n has(...args: Args): boolean;\n /** Get cache statistics */\n getStats(): CacheStats;\n}\n\n/**\n * Create a memoized function that caches results by arguments.\n *\n * Each unique set of arguments produces a cached result.\n * Supports TTL and max size limits.\n *\n * @param fn - Function to memoize\n * @param options - Memoization options\n * @returns Memoized function with cache control methods\n *\n * @example\n * ```typescript\n * const fetchUserMemo = cachedFunction(\n * async (id: string) => await fetchUser(id),\n * { ttl: '5m', maxSize: 100 }\n * );\n *\n * const user1 = await fetchUserMemo('user-1'); // Fetches\n * const user2 = await fetchUserMemo('user-2'); // Fetches\n * const user1Again = await fetchUserMemo('user-1'); // Cached!\n *\n * // Cache control\n * fetchUserMemo.delete('user-1'); // Remove specific entry\n * fetchUserMemo.clear(); // Clear all\n * console.log(fetchUserMemo.getStats()); // { hits: 1, misses: 2, size: 0 }\n * ```\n */\nexport function cachedFunction<Args extends unknown[], T>(\n fn: (...args: Args) => T | Promise<T>,\n options: CachedFunctionOptions<Args> = {}\n): MemoizedFunction<Args, T> {\n const {\n keyFn = (...args: Args) => JSON.stringify(args),\n maxSize = Infinity,\n } = options;\n const ttlMs = options.ttl ? toMs(options.ttl) : undefined;\n\n const cache = new Map<string, MemoEntry<T>>();\n const pending = new Map<string, Promise<T>>();\n let hits = 0;\n let misses = 0;\n\n /**\n * Evict oldest entries if over max size.\n */\n function evictOldest(): void {\n if (cache.size <= maxSize) return;\n\n // Find oldest entry\n let oldestKey: string | null = null;\n let oldestTime = Infinity;\n\n for (const [key, entry] of cache.entries()) {\n if (entry.timestamp < oldestTime) {\n oldestTime = entry.timestamp;\n oldestKey = key;\n }\n }\n\n if (oldestKey) {\n cache.delete(oldestKey);\n }\n }\n\n const memoized = async (...args: Args): Promise<T> => {\n const key = keyFn(...args);\n const now = Date.now();\n\n // Check cache\n const cached = cache.get(key);\n if (cached) {\n // Check if expired\n if (cached.expiresAt && now >= cached.expiresAt) {\n cache.delete(key);\n } else {\n hits++;\n return cached.value;\n }\n }\n\n // Check if already computing\n const pendingPromise = pending.get(key);\n if (pendingPromise) {\n return pendingPromise;\n }\n\n // Compute the value\n misses++;\n const promise = Promise.resolve(fn(...args)).then((value) => {\n const entry: MemoEntry<T> = {\n value,\n timestamp: Date.now(),\n expiresAt: ttlMs ? Date.now() + ttlMs : undefined,\n };\n cache.set(key, entry);\n pending.delete(key);\n evictOldest();\n return value;\n });\n\n pending.set(key, promise);\n\n try {\n return await promise;\n } catch (error) {\n pending.delete(key);\n throw error;\n }\n };\n\n memoized.clear = () => {\n cache.clear();\n pending.clear();\n };\n\n memoized.delete = (...args: Args) => {\n const key = keyFn(...args);\n return cache.delete(key);\n };\n\n memoized.has = (...args: Args) => {\n const key = keyFn(...args);\n const entry = cache.get(key);\n if (!entry) return false;\n if (entry.expiresAt && Date.now() >= entry.expiresAt) {\n cache.delete(key);\n return false;\n }\n return true;\n };\n\n memoized.getStats = () => ({\n hits,\n misses,\n size: cache.size,\n });\n\n return memoized;\n}\n\n// =============================================================================\n// once() - Execute exactly once\n// =============================================================================\n\n/**\n * State for a once-executed function.\n */\ntype OnceState<T> =\n | { status: \"idle\" }\n | { status: \"running\"; promise: Promise<T> }\n | { status: \"done\"; value: T }\n | { status: \"failed\"; error: unknown };\n\n/**\n * Once-executed function interface.\n */\nexport interface OnceFunction<T> {\n (): Promise<T>;\n /** Check if the function has been called */\n called: boolean;\n /** Check if execution completed successfully */\n completed: boolean;\n /** Check if execution failed */\n failed: boolean;\n /** Reset to allow re-execution */\n reset(): void;\n}\n\n/**\n * Create a function that executes exactly once.\n *\n * Useful for initialization code that should only run once.\n * Subsequent calls return the same result or re-throw the same error.\n *\n * @param fn - Function to execute once\n * @returns Function that executes once and returns the result\n *\n * @example\n * ```typescript\n * const initDb = once(async () => {\n * console.log('Connecting to database...');\n * const conn = await createConnection();\n * return conn;\n * });\n *\n * // First call executes\n * const db1 = await initDb(); // \"Connecting to database...\"\n *\n * // Subsequent calls return cached result\n * const db2 = await initDb(); // Instant, same connection\n * const db3 = await initDb(); // Instant, same connection\n *\n * console.log(initDb.called); // true\n * console.log(initDb.completed); // true\n * ```\n */\nexport function once<T>(fn: () => T | Promise<T>): OnceFunction<T> {\n let state: OnceState<T> = { status: \"idle\" };\n\n const onceFn = async (): Promise<T> => {\n if (state.status === \"done\") {\n return state.value;\n }\n\n if (state.status === \"failed\") {\n throw state.error;\n }\n\n if (state.status === \"running\") {\n return state.promise;\n }\n\n // Execute the function\n const promise = Promise.resolve(fn())\n .then((value) => {\n state = { status: \"done\", value };\n return value;\n })\n .catch((error) => {\n state = { status: \"failed\", error };\n throw error;\n });\n\n state = { status: \"running\", promise };\n return promise;\n };\n\n Object.defineProperty(onceFn, \"called\", {\n get: () => state.status !== \"idle\",\n });\n\n Object.defineProperty(onceFn, \"completed\", {\n get: () => state.status === \"done\",\n });\n\n Object.defineProperty(onceFn, \"failed\", {\n get: () => state.status === \"failed\",\n });\n\n onceFn.reset = () => {\n state = { status: \"idle\" };\n };\n\n return onceFn as OnceFunction<T>;\n}\n\n// =============================================================================\n// createCache() - General purpose cache\n// =============================================================================\n\n/**\n * General purpose cache interface.\n */\nexport interface Cache<K, V> {\n /** Get a value from the cache */\n get(key: K): V | undefined;\n /** Set a value in the cache */\n set(key: K, value: V, options?: { ttl?: DurationInput }): void;\n /** Check if a key exists */\n has(key: K): boolean;\n /** Delete a key from the cache */\n delete(key: K): boolean;\n /** Clear the entire cache */\n clear(): void;\n /** Get the cache size */\n size: number;\n /** Get cache statistics */\n getStats(): CacheStats;\n}\n\n/**\n * Cache configuration.\n */\nexport interface CacheConfig {\n /**\n * Default TTL for all entries.\n */\n defaultTTL?: DurationInput;\n\n /**\n * Maximum cache size.\n * @default Infinity\n */\n maxSize?: number;\n}\n\n/**\n * Create a general-purpose cache with TTL and size limits.\n *\n * @param config - Cache configuration\n * @returns A Cache instance\n *\n * @example\n * ```typescript\n * const cache = createCache<string, User>({\n * defaultTTL: '5m',\n * maxSize: 1000,\n * });\n *\n * cache.set('user:1', user);\n * cache.set('user:2', user2, { ttl: '1h' }); // Override TTL\n *\n * const user = cache.get('user:1');\n * ```\n */\nexport function createCache<K, V>(config: CacheConfig = {}): Cache<K, V> {\n const { maxSize = Infinity } = config;\n const defaultTTLMs = config.defaultTTL ? toMs(config.defaultTTL) : undefined;\n\n interface Entry {\n value: V;\n timestamp: number;\n expiresAt?: number;\n }\n\n const store = new Map<K, Entry>();\n let hits = 0;\n let misses = 0;\n\n /**\n * Check if an entry is expired.\n */\n function isExpired(entry: Entry): boolean {\n return entry.expiresAt !== undefined && Date.now() >= entry.expiresAt;\n }\n\n /**\n * Evict oldest entries if over max size.\n */\n function evictOldest(): void {\n if (store.size <= maxSize) return;\n\n let oldestKey: K | null = null;\n let oldestTime = Infinity;\n\n for (const [key, entry] of store.entries()) {\n if (entry.timestamp < oldestTime) {\n oldestTime = entry.timestamp;\n oldestKey = key;\n }\n }\n\n if (oldestKey !== null) {\n store.delete(oldestKey);\n }\n }\n\n return {\n get(key: K): V | undefined {\n const entry = store.get(key);\n if (!entry) {\n misses++;\n return undefined;\n }\n if (isExpired(entry)) {\n store.delete(key);\n misses++;\n return undefined;\n }\n hits++;\n return entry.value;\n },\n\n set(key: K, value: V, options?: { ttl?: DurationInput }): void {\n const ttlMs = options?.ttl ? toMs(options.ttl) : defaultTTLMs;\n const now = Date.now();\n\n store.set(key, {\n value,\n timestamp: now,\n expiresAt: ttlMs ? now + ttlMs : undefined,\n });\n\n evictOldest();\n },\n\n has(key: K): boolean {\n const entry = store.get(key);\n if (!entry) return false;\n if (isExpired(entry)) {\n store.delete(key);\n return false;\n }\n return true;\n },\n\n delete(key: K): boolean {\n return store.delete(key);\n },\n\n clear(): void {\n store.clear();\n },\n\n get size(): number {\n return store.size;\n },\n\n getStats(): CacheStats {\n return { hits, misses, size: store.size };\n },\n };\n}\n","/**\n * awaitly/singleflight\n *\n * Request coalescing - dedupe concurrent identical requests.\n * Multiple concurrent calls with the same key share one in-flight request.\n *\n * @example\n * ```typescript\n * import { singleflight } from 'awaitly';\n *\n * const fetchUserOnce = singleflight(\n * (id: string) => fetchUser(id),\n * { key: (id) => `user:${id}` }\n * );\n *\n * // All concurrent calls share one request\n * const [user1, user2] = await Promise.all([\n * fetchUserOnce('1'),\n * fetchUserOnce('1'), // Same key - shares request\n * ]);\n * ```\n */\n\nimport { type Result, type AsyncResult } from \"./core\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Options for the singleflight wrapper.\n */\nexport type SingleflightOptions<Args extends unknown[]> = {\n /**\n * Extract cache key from arguments.\n * Calls with the same key will share one in-flight request.\n */\n key: (...args: Args) => string;\n\n /**\n * Optional TTL in milliseconds to cache successful results.\n * After TTL expires, next call will trigger a fresh request.\n * @default 0 (no caching after completion - only dedupes in-flight requests)\n */\n ttl?: number;\n};\n\n/**\n * Internal cache entry for TTL-based caching.\n */\ninterface CacheEntry<T, E, C> {\n result: Result<T, E, C>;\n expiresAt: number;\n}\n\n// =============================================================================\n// Implementation\n// =============================================================================\n\n/**\n * Create a singleflight-wrapped function.\n * Concurrent calls with the same key share one in-flight request.\n *\n * ## How It Works\n *\n * 1. First caller with a key starts the operation\n * 2. Subsequent callers with the same key get the same Promise\n * 3. When operation completes, all callers receive the same Result\n * 4. Key is removed from in-flight tracking (unless TTL is set)\n *\n * ## Use Cases\n *\n * - **Prevent thundering herd**: Multiple requests for the same user\n * - **API deduplication**: Avoid duplicate network calls\n * - **Expensive operations**: Share computation across callers\n *\n * @param operation - The async operation that returns an AsyncResult\n * @param options - Configuration with key extraction function\n * @returns A wrapped function that deduplicates concurrent calls\n *\n * @example\n * ```typescript\n * import { singleflight } from 'awaitly';\n * import { ok, err, type AsyncResult } from 'awaitly';\n *\n * const fetchUser = async (id: string): AsyncResult<User, 'NOT_FOUND'> =>\n * id !== '0' ? ok({ id, name: `User ${id}` }) : err('NOT_FOUND');\n *\n * const fetchUserOnce = singleflight(fetchUser, {\n * key: (id) => `user:${id}`,\n * });\n *\n * // Concurrent calls share one request\n * const [a, b, c] = await Promise.all([\n * fetchUserOnce('1'), // Triggers fetch\n * fetchUserOnce('1'), // Joins existing fetch\n * fetchUserOnce('2'), // Different key - new fetch\n * ]);\n * ```\n *\n * @example\n * ```typescript\n * // With TTL for result caching\n * const fetchUserCached = singleflight(fetchUser, {\n * key: (id) => `user:${id}`,\n * ttl: 5000, // Cache successful results for 5 seconds\n * });\n *\n * const user1 = await fetchUserCached('1'); // Fetches\n * const user2 = await fetchUserCached('1'); // Returns cached (within TTL)\n * // After 5 seconds...\n * const user3 = await fetchUserCached('1'); // Fetches again\n * ```\n */\nexport function singleflight<Args extends unknown[], T, E, C = unknown>(\n operation: (...args: Args) => AsyncResult<T, E, C>,\n options: SingleflightOptions<Args>\n): (...args: Args) => AsyncResult<T, E, C> {\n // In-flight requests by key\n const inflight = new Map<string, Promise<Result<T, E, C>>>();\n\n // Cached results by key (only if TTL is set)\n const cache = options.ttl ? new Map<string, CacheEntry<T, E, C>>() : null;\n\n return async (...args: Args): AsyncResult<T, E, C> => {\n const key = options.key(...args);\n\n // Check TTL cache first (if enabled)\n if (cache) {\n const cached = cache.get(key);\n if (cached && cached.expiresAt > Date.now()) {\n return cached.result;\n }\n // Expired - remove from cache\n if (cached) {\n cache.delete(key);\n }\n }\n\n // Check for existing in-flight request\n const existing = inflight.get(key);\n if (existing) {\n return existing;\n }\n\n // Start new request\n // Use .finally() to ensure cleanup happens even if operation throws\n const promise = operation(...args)\n .then((result) => {\n // Cache successful results if TTL is set\n if (cache && options.ttl && result.ok) {\n cache.set(key, {\n result,\n expiresAt: Date.now() + options.ttl,\n });\n }\n return result;\n })\n .finally(() => {\n // Always remove from in-flight tracking, success or failure\n inflight.delete(key);\n });\n\n inflight.set(key, promise);\n return promise;\n };\n}\n\n/**\n * Create a singleflight group with manual key management.\n * More flexible but lower-level API than the `singleflight` wrapper.\n *\n * @returns A group object with execute, isInflight, and clear methods\n *\n * @example\n * ```typescript\n * import { createSingleflightGroup } from 'awaitly';\n *\n * const group = createSingleflightGroup<User, 'NOT_FOUND'>();\n *\n * // Execute with manual key\n * const user1 = await group.execute('user:1', () => fetchUser('1'));\n * const user2 = await group.execute('user:1', () => fetchUser('1')); // Shares request\n *\n * // Check if request is in-flight\n * if (group.isInflight('user:1')) {\n * console.log('Request pending');\n * }\n *\n * // Clear all in-flight requests\n * group.clear();\n * ```\n */\nexport function createSingleflightGroup<T, E, C = unknown>(): {\n /**\n * Execute or join an in-flight request for the given key.\n */\n execute: (\n key: string,\n operation: () => AsyncResult<T, E, C>\n ) => AsyncResult<T, E, C>;\n\n /**\n * Check if a request is currently in-flight for the key.\n */\n isInflight: (key: string) => boolean;\n\n /**\n * Get the number of in-flight requests.\n */\n size: () => number;\n\n /**\n * Clear all in-flight tracking (does not cancel operations).\n */\n clear: () => void;\n} {\n const inflight = new Map<string, Promise<Result<T, E, C>>>();\n\n return {\n execute: async (\n key: string,\n operation: () => AsyncResult<T, E, C>\n ): AsyncResult<T, E, C> => {\n // Return existing in-flight promise if present\n const existing = inflight.get(key);\n if (existing) {\n return existing;\n }\n\n // Start new request\n // Use .finally() to ensure cleanup happens even if operation throws\n const promise = operation()\n .then((result) => result)\n .finally(() => {\n inflight.delete(key);\n });\n\n inflight.set(key, promise);\n return promise;\n },\n\n isInflight: (key: string) => inflight.has(key),\n\n size: () => inflight.size,\n\n clear: () => inflight.clear(),\n };\n}\n","/**\n * awaitly/policies\n *\n * Policy-Driven Step Middleware - Reusable bundles of StepOptions\n * that can be composed and applied per-workflow or per-step.\n */\n\nimport type { StepOptions, RetryOptions, TimeoutOptions } from \"./core\";\n\n// =============================================================================\n// Policy Types\n// =============================================================================\n\n/**\n * A policy is a partial StepOptions that can be merged with other policies.\n */\nexport type Policy = Partial<StepOptions>;\n\n/**\n * A policy factory that creates policies based on context.\n */\nexport type PolicyFactory<T = void> = T extends void\n ? () => Policy\n : (context: T) => Policy;\n\n/**\n * Named policy with metadata.\n */\nexport interface NamedPolicy {\n name: string;\n policy: Policy;\n description?: string;\n}\n\n// =============================================================================\n// Policy Composition\n// =============================================================================\n\n/**\n * Merge multiple policies into a single StepOptions object.\n * Later policies override earlier ones for conflicting properties.\n * Retry and timeout options are deep-merged.\n *\n * @param policies - Policies to merge (in order of precedence)\n * @returns Merged StepOptions\n *\n * @example\n * ```typescript\n * const merged = mergePolicies(\n * timeoutPolicies.api, // timeout: 5000ms\n * retryPolicies.transient, // retry: 3 attempts\n * { name: 'fetch-user' } // name override\n * );\n * ```\n */\nexport function mergePolicies(...policies: Policy[]): StepOptions {\n const result: StepOptions = {};\n\n for (const policy of policies) {\n if (policy.key !== undefined) result.key = policy.key;\n\n // Deep merge retry options\n if (policy.retry !== undefined) {\n result.retry = result.retry\n ? { ...result.retry, ...policy.retry }\n : { ...policy.retry };\n }\n\n // Deep merge timeout options\n if (policy.timeout !== undefined) {\n result.timeout = result.timeout\n ? { ...result.timeout, ...policy.timeout }\n : { ...policy.timeout };\n }\n }\n\n return result;\n}\n\n/**\n * Create a policy applier that merges base policies with step-specific options.\n *\n * @param basePolicies - Base policies to apply to all steps\n * @returns A function that applies policies to step options\n *\n * @example\n * ```typescript\n * const applyPolicy = createPolicyApplier(\n * timeoutPolicies.api,\n * retryPolicies.transient\n * );\n *\n * // In workflow\n * const user = await step(\n * 'fetch-user',\n * () => fetchUser(id),\n * applyPolicy({ key: 'user:' + id })\n * );\n * ```\n */\nexport function createPolicyApplier(\n ...basePolicies: Policy[]\n): (stepOptions?: StepOptions) => StepOptions {\n const basePolicy = mergePolicies(...basePolicies);\n\n return (stepOptions?: StepOptions): StepOptions => {\n const opts = stepOptions ?? {};\n return mergePolicies(basePolicy, opts);\n };\n}\n\n/**\n * Create a named policy bundle for reuse across workflows.\n *\n * @param name - Policy bundle name\n * @param policies - Policies to include in the bundle\n * @returns Named policy object\n */\nexport function createPolicyBundle(\n name: string,\n ...policies: Policy[]\n): NamedPolicy {\n return {\n name,\n policy: mergePolicies(...policies),\n };\n}\n\n// =============================================================================\n// Retry Policies\n// =============================================================================\n\n/**\n * Create a retry policy with the given options.\n */\nexport function retryPolicy(options: RetryOptions): Policy {\n return { retry: options };\n}\n\n/**\n * Pre-built retry policies for common scenarios.\n */\nexport const retryPolicies = {\n /**\n * No retry - fail immediately on error.\n */\n none: retryPolicy({ attempts: 1 }),\n\n /**\n * Quick retry for transient errors (3 attempts, fast backoff).\n */\n transient: retryPolicy({\n attempts: 3,\n backoff: \"exponential\",\n initialDelay: 100,\n maxDelay: 1000,\n jitter: true,\n }),\n\n /**\n * Standard retry for API calls (3 attempts, moderate backoff).\n */\n standard: retryPolicy({\n attempts: 3,\n backoff: \"exponential\",\n initialDelay: 200,\n maxDelay: 5000,\n jitter: true,\n }),\n\n /**\n * Aggressive retry for critical operations (5 attempts, longer backoff).\n */\n aggressive: retryPolicy({\n attempts: 5,\n backoff: \"exponential\",\n initialDelay: 500,\n maxDelay: 30000,\n jitter: true,\n }),\n\n /**\n * Fixed interval retry (useful for polling).\n */\n fixed: (attempts: number, delayMs: number): Policy =>\n retryPolicy({\n attempts,\n backoff: \"fixed\",\n initialDelay: delayMs,\n jitter: false,\n }),\n\n /**\n * Linear backoff retry.\n */\n linear: (attempts: number, initialDelay: number): Policy =>\n retryPolicy({\n attempts,\n backoff: \"linear\",\n initialDelay,\n jitter: true,\n }),\n\n /**\n * Custom retry policy builder.\n */\n custom: (options: Partial<RetryOptions> & { attempts: number }): Policy =>\n retryPolicy({\n backoff: \"exponential\",\n initialDelay: 100,\n maxDelay: 30000,\n jitter: true,\n ...options,\n }),\n} as const;\n\n// =============================================================================\n// Timeout Policies\n// =============================================================================\n\n/**\n * Create a timeout policy with the given options.\n */\nexport function timeoutPolicy(options: TimeoutOptions): Policy {\n return { timeout: options };\n}\n\n/**\n * Pre-built timeout policies for common scenarios.\n */\nexport const timeoutPolicies = {\n /**\n * No timeout.\n */\n none: {} as Policy,\n\n /**\n * Fast timeout for quick operations (1 second).\n */\n fast: timeoutPolicy({ ms: 1000 }),\n\n /**\n * Standard API timeout (5 seconds).\n */\n api: timeoutPolicy({ ms: 5000 }),\n\n /**\n * Extended timeout for slower operations (30 seconds).\n */\n extended: timeoutPolicy({ ms: 30000 }),\n\n /**\n * Long timeout for batch operations (2 minutes).\n */\n long: timeoutPolicy({ ms: 120000 }),\n\n /**\n * Custom timeout in milliseconds.\n */\n ms: (ms: number): Policy => timeoutPolicy({ ms }),\n\n /**\n * Custom timeout in seconds.\n */\n seconds: (seconds: number): Policy => timeoutPolicy({ ms: seconds * 1000 }),\n\n /**\n * Timeout with custom error.\n */\n withError: <E>(ms: number, error: E): Policy =>\n timeoutPolicy({ ms, error }),\n\n /**\n * Timeout with AbortSignal support.\n */\n withSignal: (ms: number): Policy =>\n timeoutPolicy({ ms, signal: true }),\n} as const;\n\n// =============================================================================\n// Combined Policies\n// =============================================================================\n\n/**\n * Pre-built combined policies for common service patterns.\n */\nexport const servicePolicies = {\n /**\n * Policy for external HTTP APIs.\n * - 5 second timeout\n * - 3 retries with exponential backoff\n */\n httpApi: mergePolicies(\n timeoutPolicies.api,\n retryPolicies.standard\n ),\n\n /**\n * Policy for database operations.\n * - 30 second timeout\n * - 2 retries for transient errors\n */\n database: mergePolicies(\n timeoutPolicies.extended,\n retryPolicy({\n attempts: 2,\n backoff: \"exponential\",\n initialDelay: 100,\n maxDelay: 2000,\n jitter: true,\n })\n ),\n\n /**\n * Policy for cache operations.\n * - 1 second timeout\n * - No retry (cache misses are not errors)\n */\n cache: mergePolicies(\n timeoutPolicies.fast,\n retryPolicies.none\n ),\n\n /**\n * Policy for message queue operations.\n * - 30 second timeout\n * - 5 retries with longer backoff\n */\n messageQueue: mergePolicies(\n timeoutPolicies.extended,\n retryPolicies.aggressive\n ),\n\n /**\n * Policy for file operations.\n * - 2 minute timeout\n * - 3 retries\n */\n fileSystem: mergePolicies(\n timeoutPolicies.long,\n retryPolicies.standard\n ),\n\n /**\n * Policy for third-party services with rate limits.\n * - 10 second timeout\n * - 5 retries with linear backoff\n */\n rateLimited: mergePolicies(\n timeoutPolicy({ ms: 10000 }),\n retryPolicy({\n attempts: 5,\n backoff: \"linear\",\n initialDelay: 1000,\n maxDelay: 10000,\n jitter: true,\n })\n ),\n} as const;\n\n// =============================================================================\n// Policy Decorators\n// =============================================================================\n\n/**\n * Options for withPolicies workflow wrapper.\n */\nexport interface WithPoliciesOptions {\n /**\n * Base policies applied to all steps.\n */\n policies: Policy[];\n\n /**\n * Step-specific policy overrides by name or key pattern.\n */\n overrides?: Record<string, Policy>;\n}\n\n/**\n * Create step options with policies applied.\n * This is a helper for applying policies inline.\n *\n * @param policies - Policies to apply\n * @param stepOptions - Step-specific options\n * @returns Merged StepOptions\n *\n * @example\n * ```typescript\n * const user = await step(\n * () => fetchUser(id),\n * withPolicy(servicePolicies.httpApi, { name: 'fetch-user' })\n * );\n * ```\n */\nexport function withPolicy(\n policy: Policy,\n stepOptions?: StepOptions\n): StepOptions {\n const opts = stepOptions ?? {};\n return mergePolicies(policy, opts);\n}\n\n/**\n * Create step options with multiple policies applied.\n *\n * @param policies - Policies to apply (in order)\n * @param stepOptions - Step-specific options\n * @returns Merged StepOptions\n *\n * @example\n * ```typescript\n * const user = await step(\n * 'fetch-user',\n * () => fetchUser(id),\n * withPolicies([timeoutPolicies.api, retryPolicies.standard])\n * );\n * ```\n */\nexport function withPolicies(\n policies: Policy[],\n stepOptions?: StepOptions\n): StepOptions {\n const opts = stepOptions ?? {};\n return mergePolicies(...policies, opts);\n}\n\n// =============================================================================\n// Conditional Policies\n// =============================================================================\n\n/**\n * Create a policy that applies conditionally.\n *\n * @param condition - Condition to check\n * @param policy - Policy to apply if condition is true\n * @param elsePolicy - Policy to apply if condition is false (optional)\n * @returns The selected policy\n *\n * @example\n * ```typescript\n * const policy = conditionalPolicy(\n * isProduction,\n * servicePolicies.httpApi, // Use in production\n * retryPolicies.none // Skip in development\n * );\n * ```\n */\nexport function conditionalPolicy(\n condition: boolean,\n policy: Policy,\n elsePolicy: Policy = {}\n): Policy {\n return condition ? policy : elsePolicy;\n}\n\n/**\n * Create a policy based on environment.\n *\n * @param envPolicies - Map of environment names to policies\n * @param currentEnv - Current environment (defaults to NODE_ENV)\n * @param defaultPolicy - Default policy if environment not found\n * @returns The selected policy\n *\n * @example\n * ```typescript\n * const policy = envPolicy({\n * production: servicePolicies.httpApi,\n * development: retryPolicies.none,\n * test: retryPolicies.none,\n * });\n * ```\n */\nexport function envPolicy(\n envPolicies: Record<string, Policy>,\n currentEnv: string = process.env.NODE_ENV ?? \"development\",\n defaultPolicy: Policy = {}\n): Policy {\n return envPolicies[currentEnv] ?? defaultPolicy;\n}\n\n// =============================================================================\n// Policy Registry\n// =============================================================================\n\n/**\n * A registry for managing named policies.\n */\nexport interface PolicyRegistry {\n /**\n * Register a named policy.\n */\n register(name: string, policy: Policy): void;\n\n /**\n * Get a policy by name.\n */\n get(name: string): Policy | undefined;\n\n /**\n * Check if a policy exists.\n */\n has(name: string): boolean;\n\n /**\n * Get all registered policy names.\n */\n names(): string[];\n\n /**\n * Create step options using a registered policy.\n */\n apply(policyName: string, stepOptions?: StepOptions): StepOptions;\n}\n\n/**\n * Create a policy registry for managing named policies.\n *\n * @returns PolicyRegistry instance\n *\n * @example\n * ```typescript\n * const registry = createPolicyRegistry();\n *\n * // Register policies\n * registry.register('api', servicePolicies.httpApi);\n * registry.register('db', servicePolicies.database);\n *\n * // Use in workflow\n * const user = await step(\n * 'fetch-user',\n * () => fetchUser(id),\n * registry.apply('api')\n * );\n * ```\n */\nexport function createPolicyRegistry(): PolicyRegistry {\n const policies = new Map<string, Policy>();\n\n return {\n register(name: string, policy: Policy): void {\n policies.set(name, policy);\n },\n\n get(name: string): Policy | undefined {\n return policies.get(name);\n },\n\n has(name: string): boolean {\n return policies.has(name);\n },\n\n names(): string[] {\n return Array.from(policies.keys());\n },\n\n apply(policyName: string, stepOptions?: StepOptions): StepOptions {\n const policy = policies.get(policyName);\n if (!policy) {\n throw new Error(`Policy not found: ${policyName}`);\n }\n return withPolicy(policy, stepOptions);\n },\n };\n}\n\n// =============================================================================\n// Step Options Builder (Fluent API)\n// =============================================================================\n\n/**\n * Fluent builder for constructing step options.\n */\nexport interface StepOptionsBuilder {\n /**\n * Set step key for caching.\n */\n key(key: string): StepOptionsBuilder;\n\n /**\n * Apply a policy.\n */\n policy(policy: Policy): StepOptionsBuilder;\n\n /**\n * Set timeout in milliseconds.\n */\n timeout(ms: number): StepOptionsBuilder;\n\n /**\n * Set retry options.\n */\n retry(options: RetryOptions): StepOptionsBuilder;\n\n /**\n * Set retry attempts (with default exponential backoff).\n */\n retries(attempts: number): StepOptionsBuilder;\n\n /**\n * Build the final StepOptions.\n */\n build(): StepOptions;\n}\n\n/**\n * Create a fluent builder for step options.\n *\n * @returns StepOptionsBuilder instance\n *\n * @example\n * ```typescript\n * const options = stepOptions()\n * .key('user:123')\n * .timeout(5000)\n * .retries(3)\n * .build();\n *\n * const user = await step('fetch-user', () => fetchUser(id), options);\n * ```\n */\nexport function stepOptions(): StepOptionsBuilder {\n const policies: Policy[] = [];\n\n const builder: StepOptionsBuilder = {\n key(key: string) {\n policies.push({ key });\n return builder;\n },\n\n policy(policy: Policy) {\n policies.push(policy);\n return builder;\n },\n\n timeout(ms: number) {\n policies.push(timeoutPolicy({ ms }));\n return builder;\n },\n\n retry(options: RetryOptions) {\n policies.push(retryPolicy(options));\n return builder;\n },\n\n retries(attempts: number) {\n policies.push(retryPolicies.custom({ attempts }));\n return builder;\n },\n\n build(): StepOptions {\n return mergePolicies(...policies);\n },\n };\n\n return builder;\n}\n","/**\n * awaitly/conditional\n *\n * Conditional step execution helpers for workflows.\n * These helpers allow you to conditionally execute steps based on runtime conditions,\n * with proper event emission for skipped steps.\n */\n\nimport type { WorkflowEvent } from \"./core\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Options for conditional execution.\n */\nexport type ConditionalOptions = {\n /**\n * Human-readable name for the conditional step.\n * Used in step_skipped events for debugging and visualization.\n */\n name?: string;\n\n /**\n * Stable identity key for the conditional step.\n * Used in step_skipped events for tracking and visualization.\n */\n key?: string;\n\n /**\n * Optional reason explaining why the step was skipped.\n * Included in step_skipped events.\n */\n reason?: string;\n};\n\n/**\n * Context for conditional execution, used to emit events.\n */\nexport type ConditionalContext<C = unknown> = {\n /**\n * The workflow ID for event emission.\n */\n workflowId: string;\n\n /**\n * Event emitter function.\n */\n onEvent?: (event: WorkflowEvent<unknown, C>) => void;\n\n /**\n * Optional context value to include in emitted events.\n * When provided, this context is automatically added to step_skipped events.\n */\n context?: C;\n};\n\n/**\n * Type for operations that can be either sync or async.\n */\ntype MaybeAsync<T> = T | Promise<T>;\n\n/**\n * Type for the operation function passed to conditional helpers.\n */\ntype Operation<T> = () => MaybeAsync<T>;\n\n// =============================================================================\n// Internal Helpers\n// =============================================================================\n\n/**\n * Generate a unique decision ID for tracking conditional decisions.\n * @internal\n */\nfunction generateDecisionId(): string {\n return `decision_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\n/**\n * Emit a step_skipped event.\n * @internal\n */\nfunction emitSkipped<C = unknown>(\n ctx: ConditionalContext<C> | undefined,\n options: ConditionalOptions | undefined,\n decisionId: string\n): void {\n if (!ctx?.onEvent) return;\n\n // Create event with context if provided (similar to emitEvent logic)\n const event: WorkflowEvent<unknown, C> = {\n type: \"step_skipped\",\n workflowId: ctx.workflowId,\n stepKey: options?.key,\n name: options?.name,\n reason: options?.reason,\n decisionId,\n ts: Date.now(),\n };\n\n // Add context to event only if:\n // 1. Event doesn't already have context (preserves replayed events)\n // 2. Context is actually provided (don't add context: undefined property)\n const eventWithContext =\n event.context !== undefined || ctx.context === undefined\n ? event\n : ({ ...event, context: ctx.context } as WorkflowEvent<unknown, C>);\n\n ctx.onEvent(eventWithContext);\n}\n\n// =============================================================================\n// Conditional Helpers\n// =============================================================================\n\n/**\n * Run a step only if condition is true, return undefined if skipped.\n *\n * Use this when you want to conditionally execute a step and handle\n * the undefined case yourself. For a version with a default value,\n * use `whenOr`.\n *\n * @param condition - Boolean condition to evaluate\n * @param operation - Function that performs the step (only called if condition is true)\n * @param options - Optional configuration for the conditional step\n * @param ctx - Optional context for event emission\n * @returns The result of the operation if condition is true, undefined otherwise\n *\n * @example\n * ```typescript\n * const result = await workflow(async ({ step }) => {\n * const user = await step('fetchUser', () => fetchUser(id));\n *\n * // Only runs if user is premium\n * const premium = await when(\n * user.isPremium,\n * () => step('fetchPremiumData', () => fetchPremiumData(user.id)),\n * { name: 'check-premium', reason: 'User is not premium' }\n * );\n *\n * return { user, premium };\n * });\n * ```\n */\nexport function when<T, C = unknown>(\n condition: boolean,\n operation: Operation<T>,\n options?: ConditionalOptions,\n ctx?: ConditionalContext<C>\n): Promise<T | undefined>;\n\n/**\n * Synchronous overload for when the operation returns a non-Promise value.\n */\nexport function when<T, C = unknown>(\n condition: boolean,\n operation: () => T,\n options?: ConditionalOptions,\n ctx?: ConditionalContext<C>\n): T | undefined | Promise<T | undefined>;\n\nexport function when<T, C = unknown>(\n condition: boolean,\n operation: Operation<T>,\n options?: ConditionalOptions,\n ctx?: ConditionalContext<C>\n): MaybeAsync<T | undefined> {\n if (condition) {\n return operation();\n }\n\n const decisionId = generateDecisionId();\n emitSkipped(ctx, options, decisionId);\n return undefined;\n}\n\n/**\n * Run a step only if condition is false, return undefined if skipped.\n *\n * Use this when you want to conditionally execute a step when a condition\n * is NOT met. For a version with a default value, use `unlessOr`.\n *\n * @param condition - Boolean condition to evaluate\n * @param operation - Function that performs the step (only called if condition is false)\n * @param options - Optional configuration for the conditional step\n * @param ctx - Optional context for event emission\n * @returns The result of the operation if condition is false, undefined otherwise\n *\n * @example\n * ```typescript\n * const result = await workflow(async ({ step }) => {\n * const user = await step(fetchUser(id));\n *\n * // Only runs if user is NOT verified\n * const verification = await unless(\n * user.isVerified,\n * () => step(() => sendVerificationEmail(user.email), { name: 'send-verification' }),\n * { name: 'check-verification', reason: 'User is already verified' }\n * );\n *\n * return { user, verification };\n * });\n * ```\n */\nexport function unless<T, C = unknown>(\n condition: boolean,\n operation: Operation<T>,\n options?: ConditionalOptions,\n ctx?: ConditionalContext<C>\n): Promise<T | undefined>;\n\n/**\n * Synchronous overload for unless when the operation returns a non-Promise value.\n */\nexport function unless<T, C = unknown>(\n condition: boolean,\n operation: () => T,\n options?: ConditionalOptions,\n ctx?: ConditionalContext<C>\n): T | undefined | Promise<T | undefined>;\n\nexport function unless<T, C = unknown>(\n condition: boolean,\n operation: Operation<T>,\n options?: ConditionalOptions,\n ctx?: ConditionalContext<C>\n): MaybeAsync<T | undefined> {\n return when(!condition, operation, options, ctx);\n}\n\n/**\n * Run a step only if condition is true, return default value if skipped.\n *\n * Use this when you want to conditionally execute a step and provide\n * a fallback value when the condition is not met.\n *\n * @param condition - Boolean condition to evaluate\n * @param operation - Function that performs the step (only called if condition is true)\n * @param defaultValue - Value to return if condition is false\n * @param options - Optional configuration for the conditional step\n * @param ctx - Optional context for event emission\n * @returns The result of the operation if condition is true, defaultValue otherwise\n *\n * @example\n * ```typescript\n * const result = await workflow(async ({ step }) => {\n * const user = await step(fetchUser(id));\n *\n * // Get premium limits or use default for non-premium users\n * const limits = await whenOr(\n * user.isPremium,\n * () => step(() => fetchPremiumLimits(user.id), { name: 'premium-limits' }),\n * { maxRequests: 100, maxStorage: 1000 }, // default for non-premium\n * { name: 'check-premium-limits', reason: 'Using default limits for non-premium user' }\n * );\n *\n * return { user, limits };\n * });\n * ```\n */\nexport function whenOr<T, D, C = unknown>(\n condition: boolean,\n operation: Operation<T>,\n defaultValue: D,\n options?: ConditionalOptions,\n ctx?: ConditionalContext<C>\n): Promise<T | D>;\n\n/**\n * Synchronous overload for whenOr when the operation returns a non-Promise value.\n */\nexport function whenOr<T, D, C = unknown>(\n condition: boolean,\n operation: () => T,\n defaultValue: D,\n options?: ConditionalOptions,\n ctx?: ConditionalContext<C>\n): T | D | Promise<T | D>;\n\nexport function whenOr<T, D, C = unknown>(\n condition: boolean,\n operation: Operation<T>,\n defaultValue: D,\n options?: ConditionalOptions,\n ctx?: ConditionalContext<C>\n): MaybeAsync<T | D> {\n if (condition) {\n return operation();\n }\n\n const decisionId = generateDecisionId();\n emitSkipped(ctx, options, decisionId);\n return defaultValue;\n}\n\n/**\n * Run a step only if condition is false, return default value if skipped.\n *\n * Use this when you want to conditionally execute a step when a condition\n * is NOT met, with a fallback value for when the condition is true.\n *\n * @param condition - Boolean condition to evaluate\n * @param operation - Function that performs the step (only called if condition is false)\n * @param defaultValue - Value to return if condition is true\n * @param options - Optional configuration for the conditional step\n * @param ctx - Optional context for event emission\n * @returns The result of the operation if condition is false, defaultValue otherwise\n *\n * @example\n * ```typescript\n * const result = await workflow(async ({ step }) => {\n * const user = await step(fetchUser(id));\n *\n * // Generate new token if user is NOT authenticated, otherwise use existing\n * const token = await unlessOr(\n * user.isAuthenticated,\n * () => step(() => generateNewToken(user.id), { name: 'generate-token' }),\n * user.existingToken, // use existing token if authenticated\n * { name: 'check-auth-for-token', reason: 'Using existing token for authenticated user' }\n * );\n *\n * return { user, token };\n * });\n * ```\n */\nexport function unlessOr<T, D, C = unknown>(\n condition: boolean,\n operation: Operation<T>,\n defaultValue: D,\n options?: ConditionalOptions,\n ctx?: ConditionalContext<C>\n): Promise<T | D>;\n\n/**\n * Synchronous overload for unlessOr when the operation returns a non-Promise value.\n */\nexport function unlessOr<T, D, C = unknown>(\n condition: boolean,\n operation: () => T,\n defaultValue: D,\n options?: ConditionalOptions,\n ctx?: ConditionalContext<C>\n): T | D | Promise<T | D>;\n\nexport function unlessOr<T, D, C = unknown>(\n condition: boolean,\n operation: Operation<T>,\n defaultValue: D,\n options?: ConditionalOptions,\n ctx?: ConditionalContext<C>\n): MaybeAsync<T | D> {\n return whenOr(!condition, operation, defaultValue, options, ctx);\n}\n\n// =============================================================================\n// Factory Functions for Workflow Integration\n// =============================================================================\n\n/**\n * Create a set of conditional helpers bound to a workflow context.\n *\n * Use this factory when you want to automatically emit step_skipped events\n * to the workflow's event stream without passing context manually.\n *\n * @param ctx - The workflow context containing workflowId, onEvent, and optional context\n * @returns Object with bound when, unless, whenOr, and unlessOr functions\n *\n * @example\n * ```typescript\n * // With run() - context is automatically included in events\n * const result = await run(async ({ step }) => {\n * const ctx = { workflowId, onEvent, context: requestContext };\n * const { when, whenOr } = createConditionalHelpers(ctx);\n *\n * const user = await step(fetchUser(id));\n *\n * const premium = await when(\n * user.isPremium,\n * () => step(() => fetchPremiumData(user.id)),\n * { name: 'premium-data' }\n * );\n *\n * return { user, premium };\n * }, { onEvent, workflowId, context: requestContext });\n * \n * // With createWorkflow - access context from onEvent callback\n * const workflow = createWorkflow({ fetchUser }, {\n * createContext: () => ({ requestId: 'req-123' }),\n * onEvent: (event, ctx) => {\n * // ctx is available here, can be passed to conditional helpers\n * }\n * });\n * ```\n */\nexport function createConditionalHelpers<C = unknown>(ctx: ConditionalContext<C>) {\n return {\n /**\n * Run a step only if condition is true, return undefined if skipped.\n */\n when: <T>(\n condition: boolean,\n operation: Operation<T>,\n options?: ConditionalOptions\n ): MaybeAsync<T | undefined> => when(condition, operation, options, ctx),\n\n /**\n * Run a step only if condition is false, return undefined if skipped.\n */\n unless: <T>(\n condition: boolean,\n operation: Operation<T>,\n options?: ConditionalOptions\n ): MaybeAsync<T | undefined> => unless(condition, operation, options, ctx),\n\n /**\n * Run a step only if condition is true, return default value if skipped.\n */\n whenOr: <T, D>(\n condition: boolean,\n operation: Operation<T>,\n defaultValue: D,\n options?: ConditionalOptions\n ): MaybeAsync<T | D> => whenOr(condition, operation, defaultValue, options, ctx),\n\n /**\n * Run a step only if condition is false, return default value if skipped.\n */\n unlessOr: <T, D>(\n condition: boolean,\n operation: Operation<T>,\n defaultValue: D,\n options?: ConditionalOptions\n ): MaybeAsync<T | D> => unlessOr(condition, operation, defaultValue, options, ctx),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAAA;AAAA,EAAA;AAAA,mBAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACkBO,IAAM,gBAAgB;AAAA;AAAA,EAE3B,mBAAmB;AAAA,EACnB,+BAA+B;AAAA,EAC/B,8BAA8B;AAAA,EAC9B,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,0BAA0B;AAAA;AAAA,EAG1B,wBAAwB;AAAA,EACxB,6BAA6B;AAAA,EAC7B,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,8BAA8B;AAAA,EAC9B,2BAA2B;AAAA,EAC3B,gCAAgC;AAAA;AAAA,EAGhC,sBAAsB;AAAA,EACtB,2BAA2B;AAAA,EAC3B,yBAAyB;AAAA,EACzB,gCAAgC;AAAA,EAChC,2BAA2B;AAAA;AAAA,EAG3B,gCAAgC;AAAA,EAChC,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,0BAA0B;AAAA;AAAA,EAG1B,8BAA8B;AAAA,EAC9B,+BAA+B;AAAA,EAC/B,qCAAqC;AAAA;AAAA,EAGrC,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,8BAA8B;AAAA,EAC9B,6BAA6B;AAC/B;AAeO,SAAS,aAAa,MAAwC;AACnE,SAAO,KAAK,MAAM,GAAG,EAAE,CAAC;AAC1B;AAMO,SAAS,YAAY,MAA2B;AACrD,SAAO,8CAA8C,IAAI;AAC3D;AAGO,SAAS,cAAc,OAAqC;AACjE,SAAO,OAAO,UAAU,eAAe,KAAK,eAAe,KAAK;AAClE;AAKO,IAAM,YAAoC,OAAO;AAAA,EACtD;AACF;;;ACbA,IAAM,0BAAN,cAAsC,MAAiC;AAAA,EAC5D;AAAA;AAAA,EAEA;AACX;AAwGA,SAAS,YACPC,MACA,SAEK;AACL,SAAO,cAAc,wBAAwB;AAAA,IACzB,OAAYA;AAAA;AAAA,IAEZ,OAAYA;AAAA;AAAA,IAG9B,YAAY,OAAa,cAAmC;AAE1D,YAAM,UAAU,SAAS,UAAU,QAAQ,QAAQ,SAAS,CAAC,CAAC,IAAIA;AAElE,YAAM,OAAO;AACb,WAAK,OAAOA;AAGZ,UAAI,SAAS,SAAS,QAAW;AAC/B,YAAI,CAAC,QAAQ,MAAM;AACjB,gBAAM,IAAI;AAAA,YACR,8DAA8D,QAAQ,IAAI;AAAA,UAC5E;AAAA,QACF;AACA,eAAO,eAAe,MAAM,QAAQ;AAAA,UAClC,OAAO,QAAQ;AAAA,UACf,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,cAAc;AAAA,QAChB,CAAC;AACD,eAAO,eAAe,MAAM,QAAQ;AAAA,UAClC,OAAO,QAAQ;AAAA,UACf,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,cAAc;AAAA,QAChB,CAAC;AACD,eAAO,eAAe,MAAM,WAAW;AAAA,UACrC,OAAO,YAAY,QAAQ,IAAI;AAAA,UAC/B,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,cAAc;AAAA,QAChB,CAAC;AAAA,MACH;AAGA,aAAO,eAAe,MAAM,WAAW,SAAS;AAQhD,UAAI,SAAS,OAAO,UAAU,UAAU;AACtC,YAAI;AACJ,YAAI,SAAS,SAAS,QAAW;AAC/B,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,OAAO;AAAA,YACP,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,GAAG;AAAA,UACL,IAAI;AACJ,sBAAY;AAAA,QACd,OAAO;AACL,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,OAAO;AAAA,YACP,GAAG;AAAA,UACL,IAAI;AACJ,sBAAY;AAAA,QACd;AAEA,cAAM,eAAe,OAAO,UAAU,eAAe;AAAA,UACnD;AAAA,UACA;AAAA,QACF;AACA,cAAM,YAAY,eACb,UAAkC,QACnC;AACJ,YAAI,cAAc;AAChB,iBAAQ,UAAkC;AAAA,QAC5C;AAEA,cAAM,kBAAkB,cAAc,UAAU;AAChD,YAAI,gBAAgB,iBAAiB;AACnC,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAEA,eAAO,OAAO,MAAM,SAAS;AAE7B,YAAI,cAAc;AAChB,UAAC,KAA6B,QAAQ;AAAA,QACxC;AACA,YAAI,iBAAiB;AACnB,UAAC,KAA6B,QAAQ,cAAc;AAAA,QACtD;AAAA,MACF,WAAW,cAAc,UAAU,QAAW;AAC5C,QAAC,KAA6B,QAAQ,aAAa;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;AAGA,OAAO,eAAe,aAAa,OAAO,aAAa;AAAA,EACrD,OAAO,CAAC,aAA+B,oBAAoB;AAC7D,CAAC;AAAA,CAMD,CAAUC,iBAAV;AAIS,WAAS,QAAQ,OAAgC;AACtD,WAAO,iBAAiB;AAAA,EAC1B;AAFO,EAAAA,aAAS;AAST,WAAS,cAAc,OAA0C;AACtE,WAAO,iBAAiB;AAAA,EAC1B;AAFO,EAAAA,aAAS;AAyBT,WAASC,OAGd,OAAU,UAAoC;AAC9C,UAAMF,OAAM,MAAM;AAClB,UAAM,UAAU,SAASA,IAAG;AAC5B,WAAO;AAAA,MACL;AAAA,IACF;AAAA,EACF;AATO,EAAAC,aAAS,QAAAC;AAyCT,WAAS,aAOd,OACA,UACA,WAC2B;AAC3B,UAAMF,OAAM,MAAM;AAClB,UAAM,UAAU,SAASA,IAAG;AAC5B,QAAI,SAAS;AACX,aAAO;AAAA,QACL;AAAA,MACF;AAAA,IACF;AACA,WAAO,UAAU,KAAuD;AAAA,EAC1E;AAnBO,EAAAC,aAAS;AAAA,GA/ER;;;ACjQH,SAAS,UACdE,MACA,SAIA;AACA,QAAM,mBAAmB,SAAS,YAAY,MAAMA;AACpD,QAAM,WAAW,SAAS,YAAY,CAAC;AAEvC,QAAM,YAAY,YAAYA,MAAK;AAAA,IACjC,SAAS,CAAC,UACR,iBAAiB,EAAE,GAAG,UAAU,GAAG,MAAM,CAAC;AAAA,EAC9C,CAAC;AAED,SAAO,cAAc,UAAU;AAAA,IAC7B,YAAY,OAAiC;AAC3C,YAAM,EAAE,GAAG,UAAU,GAAG,MAAM,CAA4B;AAC1D,aAAO,OAAO,MAAM,EAAE,GAAG,UAAU,GAAG,MAAM,CAAC;AAAA,IAC/C;AAAA,EACF;AACF;AAkBO,IAAM,eAAN,eAA2C,4BAAY,gBAAgB;AAAA,EAC5E,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS,CAAC,MAMR,EAAE,YACE,iBAAiB,EAAE,SAAS,oBAAoB,EAAE,EAAE,OACpD,2CAA2C,EAAE,EAAE;AACvD,CAAC,GAAE;AAAC;AAeG,IAAM,sBAAN,eAAkD,4BAAY,uBAAuB;AAAA,EAC1F,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS,CAAC,MAQR,EAAE,YACE,wBAAwB,EAAE,SAAS,iBAAiB,EAAE,QAAQ,cAC9D,+CAA+C,EAAE,QAAQ;AACjE,CAAC,GAAE;AAAC;AAcG,IAAM,iBAAN,eAA6C,4BAAY,kBAAkB;AAAA,EAChF,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS,CAAC,MAMR,EAAE,cACE,2CAA2C,EAAE,WAAW,GAAG,EAAE,eAAe,iBAAiB,EAAE,YAAY,OAAO,EAAE,KACpH,sCAAsC,EAAE,eAAe,iBAAiB,EAAE,YAAY,OAAO,EAAE;AACvG,CAAC,GAAE;AAAC;AAeG,IAAM,0BAAN,eAAsD;AAAA,EAC3D;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS,CAAC,MAQR,oCAAoC,EAAE,WAAW,OAAO,EAAE,SAAS,MAAM,GAAG,EAAE,eAAe,iBAAiB,KAAK,KAAK,EAAE,eAAe,GAAI,CAAC,MAAM,EAAE;AAAA,EAC1J;AACF,GAAE;AAAC;AAcI,IAAM,kBAAN,eAA8C,4BAAY,mBAAmB;AAAA,EAClF,SAAS,CAAC,MAOJ,4BAA4B,EAAE,KAAK,MAAM,EAAE,MAAM;AACzD,CAAC,GAAE;AAAC;AAcG,IAAM,gBAAN,eAA4C,4BAAY,iBAAiB;AAAA,EAC9E,SAAS,CAAC,MAMR,EAAE,KACE,kBAAkB,EAAE,QAAQ,YAAY,EAAE,EAAE,eAC5C,kBAAkB,EAAE,QAAQ;AACpC,CAAC,GAAE;AAAC;AAcG,IAAM,oBAAN,eAAgD,4BAAY,qBAAqB;AAAA,EACtF,SAAS,CAAC,MAQR,EAAE,SACE,sBAAsB,EAAE,MAAM,KAC9B,EAAE,UAAU,EAAE,WACZ,wCAAwC,EAAE,MAAM,IAAI,EAAE,QAAQ,KAC9D;AACV,CAAC,GAAE;AAAC;AAcG,IAAM,eAAN,eAA2C,4BAAY,gBAAgB;AAAA,EAC5E,SAAS,CAAC,MAUR,EAAE,MACE,iBAAiB,EAAE,MAAM,KAAK,EAAE,GAAG,MACnC,iBAAiB,EAAE,MAAM;AACjC,CAAC,GAAE;AAAC;AAcG,IAAM,oBAAN,eAAgD,4BAAY,qBAAqB;AAAA,EACtF,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS,CAAC,MAOJ,gDAAgD,EAAE,IAAI;AAC9D,CAAC,GAAE;AAAC;AAqBG,IAAM,kBAAN,eAA8C,4BAAY,mBAAmB;AAAA,EAClF,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS,CAAC,MAGJ,oBAAoB,EAAE,iBAAiB,QAAQ,EAAE,MAAM,UAAU,OAAO,EAAE,SAAS,SAAS,CAAC;AACrG,CAAC,GAAE;AAAC;AAoEG,IAAM,+BAA0F;AAAA,EACrG;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AASO,SAAS,eAAe,OAAuC;AACpE,SAAO,YAAY,cAAc,KAAK,KAAK,MAAM,SAAS;AAC5D;AAKO,SAAS,sBACd,OAC8B;AAC9B,SACE,YAAY,cAAc,KAAK,KAAK,MAAM,SAAS;AAEvD;AAKO,SAAS,iBAAiB,OAAyC;AACxE,SAAO,YAAY,cAAc,KAAK,KAAK,MAAM,SAAS;AAC5D;AAKO,SAAS,0BACd,OACkC;AAClC,SACE,YAAY,cAAc,KAAK,KAAK,MAAM,SAAS;AAEvD;AAKO,SAAS,kBAAkB,OAA0C;AAC1E,SAAO,YAAY,cAAc,KAAK,KAAK,MAAM,SAAS;AAC5D;AAKO,SAAS,gBAAgB,OAAwC;AACtE,SAAO,YAAY,cAAc,KAAK,KAAK,MAAM,SAAS;AAC5D;AAKO,SAAS,oBACd,OAC4B;AAC5B,SAAO,YAAY,cAAc,KAAK,KAAK,MAAM,SAAS;AAC5D;AAKO,SAAS,eAAe,OAAuC;AACpE,SAAO,YAAY,cAAc,KAAK,KAAK,MAAM,SAAS;AAC5D;AAKO,SAAS,oBACd,OAC4B;AAC5B,SAAO,YAAY,cAAc,KAAK,KAAK,MAAM,SAAS;AAC5D;AAKO,SAAS,eAAe,OAAuC;AACpE,MAAI,CAAC,YAAY,cAAc,KAAK,EAAG,QAAO;AAC9C,QAAMA,OAAM,MAAM;AAClB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,SAASA,IAAG;AAChB;;;ACreO,IAAM,mBAAmB;AAUzB,IAAM,qBAAqB;AAK3B,IAAM,oBAAoB;AAK1B,IAAM,kBAAkB;AA4BxB,IAAM,OAAO,IAAuC,MAAY;AAqBhE,SAAS,GAAM,OAAyB;AAC7C,SAAO,EAAE,IAAI,MAAe,MAAyB;AACvD;AAOO,SAAS,IAAoB,OAAU,SAAoC;AAChF,QAAM,QAAQ,SAAS;AACvB,SAAO,EAAE,IAAI,OAAgB,OAAO,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC,EAAG;AAChF;AAWO,IAAM,OAAO,CAAU,MAAmC,EAAE;AAO5D,IAAM,QAAQ,CAAU,MAAuC,CAAC,EAAE;AAOlE,IAAM,oBAAoB,CAAC,MAChC,aAAa,mBACZ,OAAO,MAAM,YACZ,MAAM,QACN,UAAU,KACT,EAAuB,SAAS;AAK9B,IAAM,yBAAyB,CAAC,MACrC,OAAO,MAAM,YACb,MAAM,QACN,UAAU,KACV,EAAE,SAAS;AAuBN,SAAS,WACd,iBACA,UACyC;AACzC,MAAI,aAAa,QAAW;AAC1B,UAAM,IAAI;AACV,WAAO,CAAC,MAA2B,WAAW,GAAG,CAAC;AAAA,EACpD;AACA,QAAM,QAAQ;AAEd,MAAI,kBAAkB,KAAK,GAAG;AAC5B,WAAO,SAAS,gBAAgB,KAAwB;AAAA,EAC1D;AAGA,SAAQ,SAAyD,KAAqB,EAAE,KAAqB;AAC/G;AAwFO,IAAM,cAAN,cAA0B,MAAM;AAAA,EACrB;AAAA,EACA;AAAA,EAEhB,YAAY,QAA+B;AACzC,UAAM,WACJ,OAAO,OAAO,UAAU,WACpB,OAAO,QACP,KAAK,UAAU,OAAO,KAAK;AACjC,UAAM,+BAA+B,QAAQ,EAAE;AAC/C,SAAK,OAAO;AACZ,SAAK,QAAQ,OAAO;AACpB,SAAK,QAAQ,OAAO;AAAA,EACtB;AACF;AAOO,IAAM,SAAS,CAAU,MAA0B;AACxD,MAAI,EAAE,GAAI,QAAO,EAAE;AACnB,QAAM,IAAI,YAAY,CAAC;AACzB;AAOO,IAAM,WAAW,CAAU,GAAoB,iBACpD,EAAE,KAAK,EAAE,QAAQ;AAOZ,IAAM,eAAe,CAC1B,GACA,OACO,EAAE,KAAK,EAAE,QAAQ,GAAG,EAAE,OAAO,EAAE,KAAK;AAWtC,IAAM,aAAa,CAAU,MAA0B,OAAO,CAAC;AAW/D,IAAM,kBAAkB,CAC7B,OACe,QAAQ,QAAQ,EAAE,EAAE,KAAK,MAAM;AAQzC,IAAM,YAAY,CAAU,MACjC,EAAE,KAAK,EAAE,QAAQ;AAQZ,IAAM,iBAAiB,CAAU,MACtC,EAAE,KAAK,EAAE,QAAQ;AAaZ,SAAS,KAAW,IAAa,SAAiC;AACvE,MAAI;AACF,WAAO,GAAG,GAAG,CAAC;AAAA,EAChB,SAAS,OAAO;AACd,WAAO,UAAU,IAAI,QAAQ,KAAK,GAAG,EAAE,MAAM,CAAC,IAAI,IAAI,KAAK;AAAA,EAC7D;AACF;AAYA,eAAsB,YACpB,SACA,SAC4C;AAC5C,MAAI;AACF,WAAO,GAAG,MAAM,OAAO;AAAA,EACzB,SAAS,OAAO;AACd,WAAO,UAAU,IAAI,QAAQ,KAAK,GAAG,EAAE,MAAM,CAAC,IAAI,IAAI,KAAK;AAAA,EAC7D;AACF;AAYA,eAAsB,SACpB,IACA,SAC6B;AAC7B,MAAI;AACF,WAAO,GAAG,MAAM,GAAG,CAAC;AAAA,EACtB,SAAS,OAAO;AACd,WAAO,UAAU,IAAI,QAAQ,KAAK,GAAG,EAAE,MAAM,CAAC,IAAI,IAAI,KAAK;AAAA,EAC7D;AACF;AAOO,SAAS,aACd,OACA,QACc;AACd,SAAO,SAAS,OAAO,GAAG,KAAK,IAAI,IAAI,OAAO,CAAC;AACjD;AAeO,SAAS,IAAI,GAAQ,IAAc;AACxC,SAAO,EAAE,KAAK,GAAG,GAAG,EAAE,KAAK,CAAC,IAAI;AAClC;AAOO,SAAS,SACd,GACA,IACiB;AACjB,SAAO,EAAE,KAAK,IAAI,IAAI,GAAG,EAAE,OAAO,EAAE,KAAK,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC;AAChE;AA2CO,SAAS,MAAM,GAAQ,UAAqB;AACjD,MAAI,aAAa,QAAW;AAC1B,UAAM,IAAI;AACV,WAAO,CAAC,WAA8C,MAAM,QAAQ,CAAC;AAAA,EACvE;AACA,MAAI,EAAE,GAAI,QAAO,SAAS,GAAG,EAAE,KAAK;AAEpC,MAAI,OAAO,SAAS,QAAQ,WAAY,QAAO,SAAS,IAAI,EAAE,OAAO,EAAE,KAAK;AAG5E,QAAM,IAAI,EAAE;AACZ,QAAM,MAAM,OAAO,MAAM,WAAW,IAAK,GAAG,QAAQ,GAAG;AACvD,QAAM,UAAU,QAAQ,SAAY,SAAY,SAAS,GAAG;AAC5D,MAAI,OAAO,YAAY,WAAY,QAAO,QAAQ,GAAG,EAAE,KAAK;AAC5D,QAAM,IAAI;AAAA,IACR,qCAAqC,OAAO,GAAG,CAAC;AAAA,EAElD;AACF;AAaO,SAAS,QAAQ,GAAQ,IAAc;AAC5C,SAAO,EAAE,KAAK,GAAG,EAAE,KAAK,IAAI;AAC9B;AAOO,SAAS,IACd,GACA,IACiB;AACjB,MAAI,EAAE,GAAI,IAAG,EAAE,KAAK;AACpB,SAAO;AACT;AAOO,SAAS,SACd,GACA,IACiB;AACjB,MAAI,CAAC,EAAE,GAAI,IAAG,EAAE,OAAO,EAAE,KAAK;AAC9B,SAAO;AACT;AAOO,SAAS,OACd,GACA,IACA,SAC+B;AAC/B,MAAI,CAAC,EAAE,GAAI,QAAO;AAClB,MAAI;AACF,WAAO,GAAG,GAAG,EAAE,KAAK,CAAC;AAAA,EACvB,SAAS,OAAO;AACd,WAAO,IAAI,QAAQ,KAAK,GAAG,EAAE,OAAO,MAAM,CAAC;AAAA,EAC7C;AACF;AAOO,SAAS,YACd,GACA,IACA,SAC+B;AAC/B,MAAI,EAAE,GAAI,QAAO;AACjB,MAAI;AACF,WAAO,IAAI,GAAG,EAAE,KAAK,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC;AAAA,EAC5C,SAAS,OAAO;AACd,WAAO,IAAI,QAAQ,KAAK,GAAG,EAAE,OAAO,MAAM,CAAC;AAAA,EAC7C;AACF;AAKO,SAAS,MACd,GACA,MACA,OACiB;AACjB,SAAO,EAAE,KAAK,GAAG,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,MAAM,EAAE,OAAO,EAAE,KAAK,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC;AACnF;AAOO,SAAS,OACd,GACA,IACuB;AACvB,SAAO,EAAE,KAAK,IAAI,GAAG,EAAE,OAAO,EAAE,KAAK;AACvC;AAKA,eAAsB,YACpB,GACA,IACgC;AAChC,SAAO,EAAE,KAAK,IAAI,GAAG,EAAE,OAAO,EAAE,KAAK;AACvC;AAKO,SAAS,QACd,GACA,IACO;AACP,SAAO,EAAE,KAAK,GAAG,EAAE,KAAK,IAAI,GAAG,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC;AACrD;AAKA,eAAsB,aACpB,GACA,IACgB;AAChB,QAAM,WAAW,MAAM;AACvB,MAAI,SAAS,GAAI,QAAO,GAAG,SAAS,KAAK;AACzC,SAAO,GAAG,MAAM,GAAG,SAAS,OAAO,SAAS,KAAK,CAAC;AACpD;AASO,SAAS,QAA2B,OAAwC;AACjF,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,MAAI,EAAE,QAAQ,OAAQ,QAAO;AAE7B,QAAM,MAAM;AACZ,MAAI,IAAI,OAAO,QAAQ,WAAW,KAAK;AACrC,WAAO,GAAG,IAAI,KAAU;AAAA,EAC1B;AACA,MAAI,IAAI,OAAO,SAAS,WAAW,KAAK;AACtC,WAAO,IAAI,IAAI,OAAY,EAAE,OAAO,IAAI,MAAW,CAAC;AAAA,EACtD;AACA,SAAO;AACT;AAKO,SAAS,mBACd,OAC6E;AAC7E,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,MAAI,EAAE,QAAQ,OAAQ,QAAO;AAC7B,QAAM,MAAM;AACZ,SACG,IAAI,OAAO,QAAQ,WAAW,OAC9B,IAAI,OAAO,SAAS,WAAW;AAEpC;AA6CO,SAAS,IACd,SACc;AACd,QAAM,SAAoB,CAAC;AAC3B,aAAW,UAAU,SAAS;AAC5B,QAAI,CAAC,OAAO,IAAI;AACd,aAAO;AAAA,IACT;AACA,WAAO,KAAK,OAAO,KAAK;AAAA,EAC1B;AACA,SAAO,GAAG,MAAM;AAClB;AAKA,eAAsB,SAGpB,SASA;AACA,QAAM,SAAoB,CAAC;AAC3B,aAAW,mBAAmB,SAAS;AACrC,QAAI;AACF,YAAM,IAAI,MAAM;AAEhB,UAAI,CAAC,EAAE,GAAI,QAAO;AAClB,aAAO,KAAK,EAAE,KAAK;AAAA,IACrB,SAAS,QAAQ;AACf,aAAO;AAAA,QACL,EAAE,MAAM,kBAAkB,OAAO,OAAO;AAAA,QACxC,EAAE,OAAO,EAAE,MAAM,qBAAqB,OAAO,EAA2B;AAAA,MAC1E;AAAA,IACF;AAAA,EACF;AAEA,SAAO,GAAG,MAAM;AAClB;AAcO,SAAS,WACd,SACqB;AACrB,QAAM,SAAoB,CAAC;AAC3B,QAAM,SAAkC,CAAC;AAEzC,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,IAAI;AACb,aAAO,KAAK,OAAO,KAAK;AAAA,IAC1B,OAAO;AACL,aAAO,KAAK,EAAE,OAAO,OAAO,OAAO,OAAO,OAAO,MAAM,CAAC;AAAA,IAC1D;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,WAAO,IAAI,MAAM;AAAA,EACnB;AAEA,SAAO,GAAG,MAAM;AAClB;AAKA,eAAsB,gBAGpB,SAWA;AACA,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,QAAQ;AAAA,MAAI,CAAC,SACX,QAAQ,QAAQ,IAAI,EACjB,KAAK,CAAC,YAAY,EAAE,QAAQ,UAAmB,OAAO,EAAE,EACxD,MAAM,CAAC,YAAY;AAAA,QAClB,QAAQ;AAAA,QACR,OAAO,EAAE,MAAM,kBAAkB,OAAO,OAAO;AAAA,QAC/C,OAAO,EAAE,MAAM,qBAAqB,OAAO;AAAA,MAC7C,EAAE;AAAA,IACN;AAAA,EACF;AAEA,QAAM,SAAoB,CAAC;AAC3B,QAAM,SAA2C,CAAC;AAElD,aAAW,QAAQ,SAAS;AAC1B,QAAI,KAAK,WAAW,YAAY;AAC9B,aAAO,KAAK,EAAE,OAAO,KAAK,OAAO,OAAO,KAAK,MAAM,CAAC;AAAA,IACtD,WAAW,KAAK,OAAO,IAAI;AACzB,aAAO,KAAK,KAAK,OAAO,KAAK;AAAA,IAC/B,OAAO;AACL,aAAO,KAAK,EAAE,OAAO,KAAK,OAAO,OAAO,OAAO,KAAK,OAAO,MAAM,CAAC;AAAA,IACpE;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,GAAG;AAErB,WAAO,IAAI,MAAM;AAAA,EACnB;AAEA,SAAO,GAAG,MAAM;AAClB;AAKO,SAAS,UACd,SAC8B;AAC9B,QAAM,SAAc,CAAC;AACrB,QAAM,SAAc,CAAC;AACrB,aAAW,KAAK,SAAS;AACvB,QAAI,EAAE,GAAI,QAAO,KAAK,EAAE,KAAK;AAAA,QACxB,QAAO,KAAK,EAAE,KAAK;AAAA,EAC1B;AACA,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAeO,SAAS,IAAI,SAAmB;AACrC,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,IAAI,EAAE,MAAM,eAAe,SAAS,qCAAqC,CAAC;AAAA,EACnF;AACA,MAAI;AACJ,aAAW,KAAK,SAAS;AACvB,QAAI,EAAE,GAAI,QAAO;AACjB,QAAI,CAAC,SAAU,YAAW;AAAA,EAC5B;AACA,SAAO;AACT;AAKA,eAAsB,SAGpB,SAYA;AACA,MAAI,QAAQ,WAAW,GAAG;AAExB,WAAO,IAAI,EAAE,MAAM,eAAe,SAAS,0CAA0C,CAAC;AAAA,EACxF;AAEA,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI,UAAU;AACd,QAAI,eAAe,QAAQ;AAC3B,QAAI,aAA2C;AAE/C,eAAW,QAAQ,SAAS;AAC1B,cAAQ,QAAQ,IAAI,EACjB;AAAA,QAAM,CAAC,WACN;AAAA,UACE,EAAE,MAAM,kBAAkB,OAAO,OAAO;AAAA,UACxC,EAAE,OAAO,EAAE,MAAM,qBAAqB,OAAO,EAA2B;AAAA,QAC1E;AAAA,MACF,EACC,KAAK,CAAC,WAAW;AAChB,YAAI,QAAS;AAEb,YAAI,OAAO,IAAI;AACb,oBAAU;AAEV,kBAAQ,MAAa;AACrB;AAAA,QACF;AAEA,YAAI,CAAC,WAAY,cAAa;AAC9B;AAEA,YAAI,iBAAiB,GAAG;AAEtB,kBAAQ,UAAiB;AAAA,QAC3B;AAAA,MACF,CAAC;AAAA,IACL;AAAA,EACF,CAAC;AACH;AAKO,SAAS,IACd,GACA,GACkC;AAClC,MAAI,CAAC,EAAE,GAAI,QAAO;AAClB,MAAI,CAAC,EAAE,GAAI,QAAO;AAClB,SAAO,GAAG,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC;AAC9B;AAKA,eAAsB,SACpB,GACA,GAC0F;AAE1F,QAAM,gBAAgB,CACpB,MAEA,QAAQ,QAAQ,CAAC,EAAE;AAAA,IAAM,CAAC,WACxB;AAAA,MACE,EAAE,MAAM,kBAAkB,OAAO,OAAO;AAAA,MACxC,EAAE,OAAO,EAAE,MAAM,qBAAqB,OAAO,EAA2B;AAAA,IAC1E;AAAA,EACF;AAEF,QAAM,CAAC,IAAI,EAAE,IAAI,MAAM,QAAQ,IAAI,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC;AACvE,SAAO,IAAI,IAAI,EAAE;AACnB;AAWO,SAAS,QACd,QAC6B;AAC7B,MAAI,CAAC,OAAO,GAAI,QAAO;AACvB,SAAO,OAAO;AAChB;AAOO,IAAM,wBAAwB;AAW9B,SAAS,YACd,OACwC;AACxC,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,WAAO,IAAI,EAAE,MAAM,uBAAuB,MAAM,CAAyB;AAAA,EAC3E;AACA,MAAI,EAAE,QAAQ,QAAQ;AACpB,WAAO,IAAI,EAAE,MAAM,uBAAuB,MAAM,CAAyB;AAAA,EAC3E;AAEA,QAAM,MAAM;AACZ,MAAI,IAAI,OAAO,QAAQ,WAAW,KAAK;AACrC,WAAO,GAAG,IAAI,KAAU;AAAA,EAC1B;AACA,MAAI,IAAI,OAAO,SAAS,WAAW,KAAK;AACtC,WAAO,IAAI,IAAI,OAAY,EAAE,OAAO,IAAI,MAAW,CAAC;AAAA,EACtD;AACA,SAAO,IAAI,EAAE,MAAM,uBAAuB,MAAM,CAAyB;AAC3E;AAeO,SAAS,UAAgB,QAA8C;AAC5E,SAAO,OAAO,KACV,EAAE,IAAI,MAAM,OAAO,OAAO,MAAM,IAChC,EAAE,IAAI,OAAO,OAAO,OAAO,MAAM;AACvC;AAkBO,SAAS,kBACd,OACA,UACAC,WACG;AACH,MAAI,kBAAkB,KAAK,GAAG;AAE5B,UAAMC,KAAK,SAAiB;AAC5B,WAAOA,KAAIA,GAAE,KAAK,IAAID,UAAS,KAAK;AAAA,EACtC;AAEA,QAAM,IAAK,SAAiB,KAAe;AAC3C,SAAO,IAAI,EAAE,KAAU,IAAIA,UAAS,KAAK;AAC3C;;;AC7kCO,SAAS,SACd,UACA,WACyB;AACzB,QAAM,UAAU,CAAwC,YACrD,IAAI,SAAoB;AACvB,UAAM,OAAO,KAAK,GAAG,EAAE;AACvB,UAAM,YACJ,KAAK,SAAS,KACd,OAAO,SAAS,YAChB,SAAS,QACT,CAAC,MAAM,QAAQ,IAAI,KACnB,OAAO,SAAS;AAElB,UAAM,SAAS,YAAa,OAAoC;AAChE,UAAM,OAAO,YAAY,KAAK,MAAM,GAAG,EAAE,IAAI;AAE7C,UAAM,aAAa,EAAE,GAAG,WAAW,GAAI,QAAQ,QAAQ,CAAC,EAAG;AAC3D,UAAM,eAAyC,SAC3C,EAAE,GAAG,QAAQ,MAAM,WAAW,IAC7B,EAAE,MAAM,WAAW;AAGxB,WAAQ,SAAS,MAAM,EAAU,GAAG,MAAM,YAAY;AAAA,EACxD;AAEF,SAAO;AAAA,IACL,KAAK,QAAQ,KAAK;AAAA,IAClB,cAAc,QAAQ,cAAc;AAAA,IACpC,SAAS,eAA8B;AACrC,aAAO,SAAS,UAAU,EAAE,GAAG,WAAW,GAAG,cAAc,CAAC;AAAA,IAC9D;AAAA,EACF;AACF;;;ACbO,SAAS,OAAO,IAAsB;AAC3C,SAAO,EAAE,MAAM,YAAY,QAAQ,GAAG;AACxC;AAUO,SAAS,QAAQ,GAAqB;AAC3C,SAAO,EAAE,MAAM,YAAY,QAAQ,IAAI,IAAK;AAC9C;AAUO,SAAS,QAAQ,GAAqB;AAC3C,SAAO,EAAE,MAAM,YAAY,QAAQ,IAAI,KAAK,IAAK;AACnD;AAUO,SAAS,MAAM,GAAqB;AACzC,SAAO,EAAE,MAAM,YAAY,QAAQ,IAAI,KAAK,KAAK,IAAK;AACxD;AAUO,SAAS,KAAK,GAAqB;AACxC,SAAO,EAAE,MAAM,YAAY,QAAQ,IAAI,KAAK,KAAK,KAAK,IAAK;AAC7D;AAKO,IAAM,OAAiB,EAAE,MAAM,YAAY,QAAQ,EAAE;AAKrD,IAAM,WAAqB,EAAE,MAAM,YAAY,QAAQ,SAAS;AAShE,SAAS,SAAS,UAA4B;AACnD,SAAO,SAAS;AAClB;AAKO,SAAS,UAAU,UAA4B;AACpD,SAAO,SAAS,SAAS;AAC3B;AAKO,SAAS,UAAU,UAA4B;AACpD,SAAO,SAAS,UAAU,KAAK;AACjC;AAKO,SAAS,QAAQ,UAA4B;AAClD,SAAO,SAAS,UAAU,KAAK,KAAK;AACtC;AAKO,SAAS,OAAO,UAA4B;AACjD,SAAO,SAAS,UAAU,KAAK,KAAK,KAAK;AAC3C;AAeO,SAAS,IAAI,GAAa,GAAuB;AACtD,SAAO,EAAE,MAAM,YAAY,QAAQ,EAAE,SAAS,EAAE,OAAO;AACzD;AAYO,SAAS,SAAS,GAAa,GAAuB;AAC3D,SAAO,EAAE,MAAM,YAAY,QAAQ,KAAK,IAAI,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE;AACtE;AAWO,SAAS,SAAS,UAAoB,QAA0B;AACrE,SAAO,EAAE,MAAM,YAAY,QAAQ,SAAS,SAAS,OAAO;AAC9D;AAWO,SAAS,OAAO,UAAoB,SAA2B;AACpE,SAAO,EAAE,MAAM,YAAY,QAAQ,SAAS,SAAS,QAAQ;AAC/D;AASO,SAAS,SAAS,GAAa,GAAsB;AAC1D,SAAO,EAAE,SAAS,EAAE;AACtB;AAKO,SAAS,gBAAgB,GAAa,GAAsB;AACjE,SAAO,EAAE,UAAU,EAAE;AACvB;AAKO,SAAS,YAAY,GAAa,GAAsB;AAC7D,SAAO,EAAE,SAAS,EAAE;AACtB;AAKO,SAAS,mBAAmB,GAAa,GAAsB;AACpE,SAAO,EAAE,UAAU,EAAE;AACvB;AAKO,SAAS,OAAO,GAAa,GAAsB;AACxD,SAAO,EAAE,WAAW,EAAE;AACxB;AAKO,SAAS,IAAI,GAAa,GAAuB;AACtD,SAAO,EAAE,UAAU,EAAE,SAAS,IAAI;AACpC;AAKO,SAAS,IAAI,GAAa,GAAuB;AACtD,SAAO,EAAE,UAAU,EAAE,SAAS,IAAI;AACpC;AAKO,SAAS,MAAM,UAAoB,SAAmB,SAA6B;AACxF,SAAO,IAAI,IAAI,UAAU,OAAO,GAAG,OAAO;AAC5C;AASO,SAAS,OAAO,UAA6B;AAClD,SAAO,SAAS,WAAW;AAC7B;AAKO,SAAS,WAAW,UAA6B;AACtD,SAAO,SAAS,WAAW;AAC7B;AAKO,SAAS,SAAS,UAA6B;AACpD,SAAO,OAAO,SAAS,SAAS,MAAM,KAAK,SAAS,SAAS;AAC/D;AAKO,SAAS,WAAW,OAAmC;AAC5D,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,cACf,YAAY,SACZ,OAAO,MAAM,WAAW;AAE5B;AAeO,SAAS,OAAO,UAA4B;AACjD,QAAM,KAAK,SAAS;AAEpB,MAAI,OAAO,SAAU,QAAO;AAC5B,MAAI,OAAO,EAAG,QAAO;AAErB,QAAME,QAAO,KAAK,MAAM,MAAM,KAAK,KAAK,KAAK,IAAK;AAClD,QAAMC,SAAQ,KAAK,MAAO,MAAM,KAAK,KAAK,KAAK,QAAU,KAAK,KAAK,IAAK;AACxE,QAAMC,WAAU,KAAK,MAAO,MAAM,KAAK,KAAK,QAAU,KAAK,IAAK;AAChE,QAAMC,WAAU,KAAK,MAAO,MAAM,KAAK,OAAS,GAAI;AACpD,QAAMC,UAAS,KAAK;AAEpB,QAAM,QAAkB,CAAC;AACzB,MAAIJ,QAAO,EAAG,OAAM,KAAK,GAAGA,KAAI,GAAG;AACnC,MAAIC,SAAQ,EAAG,OAAM,KAAK,GAAGA,MAAK,GAAG;AACrC,MAAIC,WAAU,EAAG,OAAM,KAAK,GAAGA,QAAO,GAAG;AACzC,MAAIC,WAAU,EAAG,OAAM,KAAK,GAAGA,QAAO,GAAG;AACzC,MAAIC,UAAS,KAAK,MAAM,WAAW,EAAG,OAAM,KAAK,GAAGA,OAAM,IAAI;AAE9D,SAAO,MAAM,KAAK,GAAG,KAAK;AAC5B;AAiBO,SAAS,MAAM,OAAqC;AACzD,QAAMC,SAAQ,MAAM,KAAK,EAAE,MAAM,mCAAmC;AACpE,MAAI,CAACA,OAAO,QAAO;AAEnB,QAAM,QAAQ,WAAWA,OAAM,CAAC,CAAC;AACjC,QAAM,OAAOA,OAAM,CAAC,EAAE,YAAY;AAElC,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,OAAO,KAAK;AAAA,IACrB,KAAK;AACH,aAAO,QAAQ,KAAK;AAAA,IACtB,KAAK;AACH,aAAO,QAAQ,KAAK;AAAA,IACtB,KAAK;AACH,aAAO,MAAM,KAAK;AAAA,IACpB,KAAK;AACH,aAAO,KAAK,KAAK;AAAA,IACnB;AACE,aAAO;AAAA,EACX;AACF;AAoBO,IAAM,WAAW;AAAA;AAAA,EAEtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AACF;;;AC1WO,IAAM,oBAAoB,CAC/B,UAEA,OAAO,UAAU,YACjB,UAAU,QACV,QAAQ,SACR,OAAQ,MAA0B,OAAO,cACvC,MAA0B,KAAK,WAAW,QAAQ,WAAW;AAiB1D,IAAM,YAAY,CACvB,MACA,SACqB;AACrB,QAAM,QAAkE,CAAC;AACzE,QAAM,mBAAmB,oBAAI,IAAoB;AACjD,aAAW,OAAO,OAAO,KAAK,IAAI,GAAG;AACnC,UAAM,MAAM,KAAK,GAAG;AAGpB,QAAI,OAAO,QAAQ,WAAY;AAC/B,UAAM,GAAG,IAAI,IAAI,SAAoB;AACnC,YAAM,SAAS,iBAAiB,IAAI,GAAG,KAAK,KAAK;AACjD,uBAAiB,IAAI,KAAK,KAAK;AAC/B,YAAM,UAAU,UAAU,IAAI,MAAM,GAAG,GAAG,IAAI,KAAK;AAEnD,aAAO,KAAK,SAAS,YAAY;AAC/B,cAAM,QAAQ,MAAM,IAAI,GAAG,IAAI;AAC/B,eAAO,kBAAkB,KAAK,IAAI,QAAQ,GAAG,KAAK;AAAA,MACpD,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;;;AC/DA,IAAM,OAAO,CAAC,MAA4B,OAAO,MAAM,WAAW,IAAI,SAAS,CAAC;AAgBhF,IAAM,cAAc,OAAO,IAAiB,SAA+C;AACzF,MAAI;AACF,UAAM,QAAQ,MAAO,GAA+C,GAAG,IAAI;AAC3E,QAAI,kBAAkB,KAAK,GAAG;AAC5B,aAAO,MAAM,KACT,EAAE,MAAM,MAAM,OAAO,MAAM,MAAM,IACjC,EAAE,MAAM,OAAO,OAAO,MAAM,OAAO,QAAQ,MAAM;AAAA,IACvD;AACA,WAAO,EAAE,MAAM,MAAM,MAAM;AAAA,EAC7B,SAAS,QAAQ;AACf,WAAO,EAAE,MAAM,SAAS,OAAO;AAAA,EACjC;AACF;AAGA,IAAM,QAAQ,CAA0C,SAAY,WAA2B;AAC7F,QAAM,OAAO,OAAO;AACpB,MAAI,MAAM;AACR,WAAO,eAAe,SAAS,QAAQ,EAAE,OAAO,MAAM,cAAc,KAAK,CAAC;AAAA,EAC5E;AACA,SAAO;AACT;AAEA,IAAM,QAAQ,CAAC,OAA8B,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AA6BtF,SAAS,MACd,IACA,SACyB;AACzB,QAAM,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,QAAQ,CAAC;AACzD,QAAM,YAAY,QAAQ,UAAU,SAAY,IAAI,KAAK,QAAQ,KAAK;AACtE,QAAM,WAAW,QAAQ,aAAa,SAAY,WAAW,KAAK,QAAQ,QAAQ;AAClF,QAAM,UAAU,QAAQ,WAAW;AAEnC,QAAM,WAAW,CAAC,YAA4B;AAC5C,UAAM,MACJ,YAAY,gBACR,YAAY,MAAM,UAAU,KAC5B,YAAY,WACV,YAAY,UACZ;AACR,WAAO,KAAK,IAAI,KAAK,QAAQ;AAAA,EAC/B;AAEA,QAAM,UAAU,UAAU,SAAwB;AAChD,QAAI,OAAgB,EAAE,MAAM,SAAS,QAAQ,OAAU;AACvD,aAAS,UAAU,GAAG,WAAW,UAAU,WAAW;AACpD,aAAO,MAAM,YAAY,IAAI,IAAI;AACjC,UAAI,KAAK,SAAS,KAAM,QAAO,GAAG,KAAK,KAAK;AAC5C,YAAM,UAAU,KAAK,SAAS,QAAQ,KAAK,QAAQ,KAAK;AACxD,UAAI,QAAQ,WAAW,CAAC,QAAQ,QAAQ,OAAO,EAAG;AAClD,UAAI,UAAU,UAAU;AACtB,gBAAQ,UAAU,EAAE,SAAS,QAAQ,CAAC;AACtC,cAAM,KAAK,SAAS,OAAO;AAC3B,YAAI,KAAK,EAAG,OAAM,MAAM,EAAE;AAAA,MAC5B;AAAA,IACF;AACA,QAAI,KAAK,SAAS,MAAO,QAAO,KAAK;AACrC,UAAM,KAAK;AAAA,EACb;AAEA,SAAO,MAAM,SAAS,EAAE;AAC1B;AAYO,SAAS,QACd,IACA,OACwC;AACxC,QAAM,KAAK,KAAK,KAAK;AACrB,QAAM,YAAY,uBAAO,WAAW;AAEpC,QAAM,UAAU,UAAU,SAAwB;AAChD,QAAI;AACJ,QAAI;AACF,YAAM,UAAU,MAAM,QAAQ,KAAK;AAAA,QACjC,YAAY,IAAI,IAAI;AAAA,QACpB,IAAI,QAA0B,CAAC,YAAY;AACzC,kBAAQ,WAAW,MAAM,QAAQ,SAAS,GAAG,EAAE;AAAA,QACjD,CAAC;AAAA,MACH,CAAC;AACD,UAAI,YAAY,WAAW;AACzB,eAAO,IAAI,IAAI,aAAa,EAAE,WAAW,GAAG,QAAQ,QAAW,GAAG,CAAC,CAAC;AAAA,MACtE;AACA,UAAI,QAAQ,SAAS,KAAM,QAAO,GAAG,QAAQ,KAAK;AAClD,UAAI,QAAQ,SAAS,MAAO,QAAO,QAAQ;AAC3C,YAAM,QAAQ;AAAA,IAChB,UAAE;AACA,UAAI,UAAU,OAAW,cAAa,KAAK;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO,MAAM,SAAS,EAAE;AAC1B;AAaO,SAAS,SAId,IACA,WAG+E;AAC/E,QAAM,UAAU,UAAU,SAAwB;AAChD,UAAM,UAAU,MAAM,YAAY,IAAI,IAAI;AAC1C,QAAI,QAAQ,SAAS,KAAM,QAAO,GAAG,QAAQ,KAAK;AAElD,UAAM,UACJ,QAAQ,SAAS,QAAQ,QAAQ,QAAQ,IAAI,gBAAgB,EAAE,OAAO,QAAQ,OAAO,CAAC;AACxF,UAAM,YAAY,MAAM,YAAY,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC;AACjE,QAAI,UAAU,SAAS,KAAM,QAAO,GAAG,UAAU,KAAK;AACtD,QAAI,UAAU,SAAS,MAAO,QAAO,UAAU;AAC/C,UAAM,UAAU;AAAA,EAClB;AAEA,SAAO,MAAM,SAAS,EAAE;AAG1B;;;AC3MA,SAAS,oBAAoB,OAA2C;AACtE,QAAMC,SAAQ,MAAM,KAAK,EAAE,MAAM,mCAAmC;AACpE,MAAI,CAACA,OAAO,QAAO;AACnB,QAAM,QAAQ,WAAWA,OAAM,CAAC,CAAC;AACjC,QAAM,OAAOA,OAAM,CAAC,EAAE,YAAY;AAClC,QAAM,cAAsC,EAAE,IAAI,GAAG,GAAG,KAAM,GAAG,KAAO,GAAG,MAAS,GAAG,MAAS;AAChG,SAAO,EAAE,MAAM,YAAY,QAAQ,SAAS,YAAY,IAAI,KAAK,GAAG;AACtE;AAqIO,SAAS,uBAAuB,OAAiC;AACtE,SAAO,IAAI,gBAAgB,EAAE,MAAM,CAAC;AACtC;AAgCO,SAASC,IAAM,OAAiB;AACrC,SAAO,EAAE,IAAI,MAAe,MAAM;AACpC;AAsBO,SAASC,KAAoB,OAAU,SAAoC;AAChF,QAAM,QAAQ,SAAS;AACvB,SAAO,EAAE,IAAI,OAAgB,OAAO,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC,EAAG;AAChF;AAghBO,SAAS,gBAAgB,OAAwB;AACtD,MAAI,SAAS,KAAM,QAAO;AAE1B,MAAI,OAAO,UAAU,SAAU,QAAO,MAAM,KAAK,KAAK;AAEtD,MAAI,OAAO,UAAU,UAAU;AAE7B,UAAM,SAAS;AACf,QAAI,OAAO,OAAO,SAAS,UAAU;AACnC,YAAM,UAAU,OAAO,KAAK,KAAK;AACjC,UAAI,QAAS,QAAO;AAAA,IACtB;AAEA,QAAI,OAAO,OAAO,QAAQ,UAAU;AAClC,YAAM,UAAU,OAAO,IAAI,KAAK;AAChC,UAAI,QAAS,QAAO;AAAA,IACtB;AAEA,QAAI,OAAO,OAAO,SAAS,UAAU;AACnC,YAAM,UAAU,OAAO,KAAK,KAAK;AACjC,UAAI,QAAS,QAAO;AAAA,IACtB,WAAW,OAAO,OAAO,SAAS,UAAU;AAC1C,aAAO,OAAO,OAAO,IAAI;AAAA,IAC3B;AAEA,QAAI,iBAAiB,SAAS,MAAM,MAAM;AACxC,YAAM,UAAU,MAAM,KAAK,KAAK;AAChC,UAAI,QAAS,QAAO;AAAA,IACtB;AAAA,EACF;AAEA,SAAO;AACT;AAGO,SAAS,0BACdC,MACA,WACiC;AACjC,MAAI,CAAC,aAAa,CAACA,KAAK,QAAO;AAC/B,SAAO,UAAUA,IAAG;AACtB;AAGO,SAAS,oBAAoB,SAAgD;AAClF,QAAM,EAAE,QAAQ,QAAQ,OAAO,MAAAC,OAAM,cAAc,OAAO,MAAM,IAAI;AACpE,MAAI,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAACA,OAAM,UAAU,CAAC,cAAc,UAAU,CAAC,OAAO,UAAU,CAAC,OAAO,QAAQ;AAC9G,WAAO;AAAA,EACT;AACA,QAAM,WAAyB,CAAC;AAChC,MAAI,OAAQ,UAAS,SAAS;AAC9B,MAAI,OAAQ,UAAS,SAAS;AAC9B,MAAI,MAAO,UAAS,QAAQ;AAC5B,MAAIA,OAAM,OAAQ,UAAS,OAAOA;AAClC,MAAI,cAAc,OAAQ,UAAS,eAAe;AAClD,MAAI,OAAO,OAAQ,UAAS,QAAQ;AACpC,MAAI,OAAO,OAAQ,UAAS,QAAQ;AACpC,SAAO;AACT;AAGA,SAAS,sBACP,OACA,WACA,QACA,SACA,sBACsB;AACtB,QAAMD,OAAM,gBAAgB,KAAK;AACjC,QAAM,iBAAiB,0BAA0BA,MAAK,SAAS;AAC/D,QAAM,cAAoC,EAAE,KAAAA,MAAK,OAAO;AACxD,MAAI,mBAAmB,OAAW,aAAY,iBAAiB;AAC/D,MAAI,YAAY,OAAW,aAAY,UAAU;AACjD,MAAI,yBAAyB,OAAW,aAAY,uBAAuB;AAC3E,SAAO;AACT;AAqJO,IAAM,sBAAqC,uBAAO,IAAI,qBAAqB;AAiB3E,SAAS,mBAAmB,GAAmC;AACpE,MAAI,OAAO,MAAM,YAAY,MAAM,MAAM;AACvC,WAAO;AAAA,EACT;AAEA,MAAK,EAAuB,SAAS,gBAAgB;AACnD,WAAO;AAAA,EACT;AAEA,SAAO,uBAAuB;AAChC;AAMO,SAAS,mBAAmB,GAA+C;AAChF,MAAI,OAAO,MAAM,YAAY,MAAM,MAAM;AACvC,WAAO;AAAA,EACT;AAEA,MAAK,EAAuB,SAAS,gBAAgB;AACnD,UAAME,OAAM;AACZ,WAAO;AAAA,MACL,WAAWA,KAAI;AAAA,MACf,UAAUA,KAAI;AAAA,MACd,SAASA,KAAI;AAAA,MACb,SAASA,KAAI;AAAA,IACf;AAAA,EACF;AAEA,MAAI,uBAAuB,GAAG;AAC5B,WAAQ,EAA4C,mBAAmB;AAAA,EACzE;AACA,SAAO;AACT;AAwxCO,IAAM,oBAAmC,uBAAO,YAAY;AA0B5D,SAAS,gBAAmB,OAAU,MAAqC;AAChF,SAAO;AAAA,IACL,CAAC,iBAAiB,GAAG;AAAA,IACrB;AAAA,IACA;AAAA,EACF;AACF;AAMO,SAAS,YAAe,GAA+B;AAC5D,SACE,OAAO,MAAM,YACb,MAAM,QACL,EAAmC,iBAAiB,MAAM;AAE/D;AAOA,IAAM,0BAAyC,uBAAO,kBAAkB;AAOxE,SAAS,sBAAsB,QAAkC;AAC/D,SAAO,EAAE,CAAC,uBAAuB,GAAG,MAAM,OAAO;AACnD;AAEA,SAAS,kBAAkB,GAAkC;AAC3D,SACE,OAAO,MAAM,YACb,MAAM,QACL,EAAmC,uBAAuB,MAAM;AAErE;AAUA,SAAS,oBACP,SACA,SAMQ;AACR,QAAM,EAAE,SAAS,cAAc,UAAU,OAAO,IAAI;AAEpD,MAAI;AAEJ,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,cAAQ;AACR;AAAA,IACF,KAAK;AACH,cAAQ,eAAe;AACvB;AAAA,IACF,KAAK;AACH,cAAQ,eAAe,KAAK,IAAI,GAAG,UAAU,CAAC;AAC9C;AAAA,EACJ;AAGA,UAAQ,KAAK,IAAI,OAAO,QAAQ;AAGhC,MAAI,QAAQ;AACV,UAAM,eAAe,QAAQ,OAAO,KAAK,OAAO;AAChD,YAAQ,QAAQ;AAAA,EAClB;AAEA,SAAO,KAAK,MAAM,KAAK;AACzB;AAMA,SAASC,OAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AA8DA,IAAM,iBAAgC,uBAAO,SAAS;AACtD,IAAM,wBAAuC,uBAAO,gBAAgB;AAMpE,SAAS,sBACP,OACwD;AACxD,SACE,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,qBAAqB,MAAM;AAElE;AAMA,eAAe,mBACb,WACA,SACA,UAEA,gBACY;AACZ,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,WAAW,QAAQ,aAAa;AAGtC,QAAM,qBAAqB,MAAe;AAExC,QAAI,OAAO,aAAa,YAAY;AAClC,aAAO,SAAS;AAAA,QACd,MAAM,SAAS;AAAA,QACf,KAAK,SAAS;AAAA,QACd,IAAI,QAAQ;AAAA,MACd,CAAC;AAAA,IACH;AAGA,WACG,QAAQ,SAA8B;AAAA,MACrC,MAAM;AAAA,MACN,UAAU,SAAS;AAAA,MACnB,SAAS,SAAS;AAAA,MAClB,WAAW,QAAQ;AAAA,MACnB,SAAS,SAAS;AAAA,IACpB;AAAA,EAEJ;AAGA,MAAI;AAGJ,MAAI,gBAAgB,SAAS;AAC3B,eAAW,MAAM,eAAe,MAAM;AAAA,EACxC;AAGA,MAAI;AACJ,MAAI,kBAAkB,CAAC,eAAe,SAAS;AAC7C,2BAAuB,MAAM,WAAW,MAAM,eAAe,MAAM;AACnE,mBAAe,iBAAiB,SAAS,sBAAsB,EAAE,MAAM,KAAK,CAAC;AAAA,EAC/E;AAGA,QAAM,iBAAiB,IAAI,QAAe,CAAC,GAAG,WAAW;AACvD,gBAAY,WAAW,MAAM;AAE3B,UAAI,aAAa,cAAc;AAC7B,mBAAW,MAAM;AAAA,MACnB;AAGA,UAAI,aAAa,UAAU;AACzB,eAAO,EAAE,CAAC,qBAAqB,GAAG,MAAM,IAAI,QAAQ,GAAG,CAAC;AACxD;AAAA,MACF;AAGA,aAAO,EAAE,CAAC,cAAc,GAAG,MAAM,OAAO,mBAAmB,EAAE,CAAC;AAAA,IAChE,GAAG,QAAQ,EAAE;AAAA,EACf,CAAC;AAGD,MAAI;AACJ,MAAI,QAAQ,QAAQ;AAGlB,uBAAmB,QAAQ;AAAA,MACxB,UAAkD,WAAW,MAAM;AAAA,IACtE;AAAA,EACF,OAAO;AAEL,uBAAmB,QAAQ,QAAS,UAA+B,CAAC;AAAA,EACtE;AAEA,MAAI;AAEF,UAAM,SAAS,MAAM,QAAQ,KAAK,CAAC,kBAAkB,cAAc,CAAC;AACpE,WAAO;AAAA,EACT,SAAS,OAAO;AAEd,QACE,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,qBAAqB,MAAM,MAC9D;AAEA,YAAM,EAAE,CAAC,qBAAqB,GAAG,MAAM,IAAI,QAAQ,GAAG;AAAA,IACxD;AAGA,QACE,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,cAAc,MAAM,MACvD;AAGA,UAAI,aAAa,cAAc;AAC7B,yBAAiB,MAAM,MAAM;AAAA,QAE7B,CAAC;AAAA,MACH;AAEA,YAAM,eAAgB,MAA6B;AAKnD,UACE,OAAO,iBAAiB,YACxB,iBAAiB,QAChB,aAAkC,SAAS,gBAC5C;AACA,cAAM,OAA8B;AAAA,UAClC,WAAW,QAAQ;AAAA,UACnB,UAAU,SAAS;AAAA,UACnB,SAAS,SAAS;AAAA,UAClB,SAAS,SAAS;AAAA,QACpB;AAEA,YAAI,uBAAuB,cAAc;AAEvC,UAAC,aAAuD,mBAAmB,IAAI;AAAA,QACjF,OAAO;AAEL,iBAAO,eAAe,cAAc,qBAAqB;AAAA,YACvD,OAAO;AAAA,YACP,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,cAAc;AAAA,UAChB,CAAC;AAAA,QACH;AAAA,MACF;AAEA,YAAM;AAAA,IACR;AAEA,UAAM;AAAA,EACR,UAAE;AAEA,iBAAa,SAAU;AAEvB,QAAI,wBAAwB,gBAAgB;AAC1C,qBAAe,oBAAoB,SAAS,oBAAoB;AAAA,IAClE;AAAA,EACF;AACF;AAMA,IAAM,uBAAuB;AAAA,EAC3B,SAAS;AAAA,EACT,cAAc;AAAA,EACd,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,aAAa,MAAM;AAAA,EACnB,SAAS,MAAM;AAAA,EAAC;AAClB;AAiHA,eAAe,MACb,UAGA,aAMA,cAEqB;AAGrB,MAAI,OAAO,aAAa,YAAY;AAClC,UAAM,OAAO;AACb,UAAM,UAAU;AAIhB,QAAI,OAAO,YAAY,YAAY;AACjC,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AAGA,UAAM,aAAa;AAKnB,WAAO;AAAA,MACL,CAAC,EAAE,KAAK,MAAM,QAAQ,UAAU,MAAM,IAAoB,GAAG,EAAE,KAAK,CAAC;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AAEA,QAAM,KAAK;AACX,QAAM,UAAU;AAChB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,WAAW,OAAO,YAAY,WAC7B,UACA,CAAC;AAEN,QAAM,aAAa,sBAAsB,OAAO,WAAW;AAK3D,QAAM,cAAc,QAChB,IAAI;AAAA,IACF,MAAM,QAAQ,KAAK,IACd,QACA,MAEE,OAAO,IAAI,CAAC,UAAU,MAAM,cAAc,MAAM,EAAE;AAAA,EAC3D,IACA;AACJ,QAAM,mBAAmB,cACrB,CAAC,GAAG,WAAW,EACZ,OAAO,CAAC,OAAO,GAAG,SAAS,GAAG,CAAC,EAC/B;AAAA,IACC,CAAC,OACC,IAAI;AAAA,MACF,IAAI,GAAG,WAAW,qBAAqB,OAAO,QAAQ,EAAE,WAAW,cAAc,IAAI,CAAC;AAAA,IACxF;AAAA,EACJ,IACF;AACJ,QAAM,iBAAiB,CAAC,IAAY,SAAoC;AACtE,QAAI,CAAC,eAAe,YAAY,IAAI,EAAE,EAAG;AACzC,QAAI,kBAAkB,KAAK,CAAC,OAAO,GAAG,KAAK,EAAE,CAAC,EAAG;AACjD,UAAM,IAAI;AAAA,MACR,aAAa,IAAI,QAAQ,EAAE,0DACR,CAAC,GAAG,WAAW,EAAE,KAAK,IAAI,CAAC;AAAA,IAEhD;AAAA,EACF;AACA,QAAM,2BAA2B,mBAAmB;AAIpD,QAAM,mBAAmF,CAAC;AAG1F,MAAI,gBAAgB;AAMpB,QAAM,iBAAiB,CAAC,YAA6B;AACnD,WAAO,WAAW,QAAQ,EAAE,aAAa;AAAA,EAC3C;AAEA,QAAM,YAAY,CAAC,UAAiD;AAIlE,UAAM,mBACJ,MAAM,YAAY,UAAa,YAAY,SACvC,QACC,EAAE,GAAG,OAAO,QAAsB;AAEzC,UAAM,gBACJ,iBAAiB,UAAa,iBAAiB,iBAAiB,SAC3D,EAAE,GAAG,kBAAkB,aAAa,IACrC;AAGN,QAAI,cAAc,SAAS,gBAAgB;AAEzC,YAAM,SAAS,cAAc;AAG7B,eAAS,IAAI,iBAAiB,SAAS,GAAG,KAAK,GAAG,KAAK;AACrD,cAAM,QAAQ,iBAAiB,CAAC;AAChC,YAAI,MAAM,SAAS,UAAU,CAAC,MAAM,UAAU;AAC5C,gBAAM,WAAW;AACjB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,cAAU,eAAe,OAAY;AAAA,EACvC;AAGA,QAAM,YAAY;AAGlB,QAAM,eAAe,CAAC,MAAkC,YAAY,CAAC;AAIrE,QAAM,cAAc,CAClB,OACA,UACM;AACN,WAAO;AAAA,EACT;AAGA,QAAM,eAAe,CAAC,UAA4G;AAChI,QAAI,OAAO,UAAU,WAAY,QAAO;AACxC,QAAI,SAAS,OAAO,UAAU,YAAY,QAAQ,MAAO,QAAO;AAEhE,QAAI,SAAS,OAAO,UAAU,YAAY,UAAU,SAAS,OAAQ,MAA2B,SAAS,WAAY,QAAO;AAC5H,WAAO;AAAA,EACT;AAEA,MAAI;AA80BF,QAASC,+BAAT,SACE,eACmE;AACnE,YAAM,MAAyE,CAAC;AAChF,iBAAW,CAAC,KAAKC,MAAK,KAAK,OAAO,QAAQ,aAAa,GAAG;AACxD,YAAI,OAAOA,WAAU,YAAY;AAC/B,cAAI,GAAG,IAAIA;AAAA,QACb,WAAWA,UAAS,OAAOA,WAAU,YAAY,QAAQA,QAAO;AAC9D,cAAI,GAAG,IAAIA,OAAM;AAAA,QACnB,OAAO;AACL,gBAAM,IAAI,UAAU,wBAAwB,GAAG,gDAAgD;AAAA,QACjG;AAAA,MACF;AACA,aAAO;AAAA,IACT,GAGSC,wBAAT,SACE,MACA,WACc;AACd,YAAM,UAAU,SAAS,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAE7E,cAAQ,YAAY;AAClB,cAAM,YAAY,YAAY,IAAI;AAClC,YAAI,aAAa;AAGjB,yBAAiB,KAAK,EAAE,SAAS,MAAM,WAAW,CAAC;AAGnD,cAAM,eAAe,MAAM;AACzB,cAAI,WAAY;AAChB,uBAAa;AAEb,gBAAM,MAAM,iBAAiB,UAAU,OAAK,EAAE,YAAY,OAAO;AACjE,cAAI,QAAQ,GAAI,kBAAiB,OAAO,KAAK,CAAC;AAC9C,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA,IAAI,KAAK,IAAI;AAAA,YACb,YAAY,YAAY,IAAI,IAAI;AAAA,UAClC,CAAC;AAAA,QACH;AAGA,kBAAU;AAAA,UACR,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA,WAAW;AAAA,UACX;AAAA,UACA,IAAI,KAAK,IAAI;AAAA,QACf,CAAC;AAED,YAAI;AACF,gBAAM,SAAS,MAAM,UAAU;AAG/B,uBAAa;AAEb,cAAI,CAAC,OAAO,IAAI;AACd,sBAAU,OAAO,OAAuB,MAAM,OAAO;AACrD,kBAAM,UAAU,OAAO,OAAuB;AAAA,cAC5C,QAAQ;AAAA,cACR,aAAa,OAAO;AAAA,YACtB,CAAC;AAAA,UACH;AAEA,iBAAO,OAAO;AAAA,QAChB,SAAS,OAAO;AAEd,uBAAa;AACb,gBAAM;AAAA,QACR;AAAA,MACF,GAAG;AAAA,IACL,GAGSC,wBAAT,SACE,YACAC,UACY;AACZ,YAAM,OAAO,OAAO,KAAK,UAAU;AACnC,YAAM,OAAOA,SAAQ,QAAQ,YAAY,KAAK,KAAK,IAAI,CAAC;AACxD,YAAM,UAAU,SAAS,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAE7E,cAAQ,YAAY;AAClB,cAAM,YAAY,YAAY,IAAI;AAClC,YAAI,aAAa;AAGjB,yBAAiB,KAAK,EAAE,SAAS,MAAM,WAAW,CAAC;AAGnD,cAAM,eAAe,MAAM;AACzB,cAAI,WAAY;AAChB,uBAAa;AACb,gBAAM,MAAM,iBAAiB,UAAU,OAAK,EAAE,YAAY,OAAO;AACjE,cAAI,QAAQ,GAAI,kBAAiB,OAAO,KAAK,CAAC;AAC9C,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA,IAAI,KAAK,IAAI;AAAA,YACb,YAAY,YAAY,IAAI,IAAI;AAAA,UAClC,CAAC;AAAA,QACH;AAGA,kBAAU;AAAA,UACR,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA,WAAW;AAAA,UACX;AAAA,UACA,IAAI,KAAK,IAAI;AAAA,QACf,CAAC;AAED,YAAI;AAEF,gBAAM,UAAU,MAAM,IAAI,QAAsE,CAAC,YAAY;AAC3G,gBAAI,KAAK,WAAW,GAAG;AACrB,sBAAQ,CAAC,CAAC;AACV;AAAA,YACF;AAEA,gBAAI,UAAU;AACd,gBAAI,eAAe,KAAK;AACxB,kBAAM,cAA4E,IAAI,MAAM,KAAK,MAAM;AAEvG,qBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,oBAAM,MAAM,KAAK,CAAC;AAClB,oBAAM,QAAQ;AAEd,sBAAQ,QAAQ,WAAW,GAAG,EAAE,CAAC,EAC9B,MAAM,CAAC,WAAWC;AAAA,gBACjB,EAAE,MAAM,oBAA6B,OAAO,OAAO;AAAA,gBACnD,EAAE,OAAO,EAAE,MAAM,qBAA8B,OAAO,EAAE;AAAA,cAC1D,CAAC,EACA,KAAK,CAAC,WAAW;AAChB,oBAAI,QAAS;AAGb,oBAAI,CAAC,OAAO,IAAI;AACd,4BAAU;AACV,0BAAQ,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;AACzB;AAAA,gBACF;AAEA,4BAAY,KAAK,IAAI,EAAE,KAAK,OAAO;AACnC;AAEA,oBAAI,iBAAiB,GAAG;AACtB,0BAAQ,WAAW;AAAA,gBACrB;AAAA,cACF,CAAC;AAAA,YACL;AAAA,UACF,CAAC;AAGD,uBAAa;AAGb,gBAAM,SAAkC,CAAC;AACzC,qBAAW,EAAE,KAAK,OAAO,KAAK,SAAS;AACrC,gBAAI,CAAC,OAAO,IAAI;AACd,wBAAU,OAAO,OAAuB,KAAK,OAAO;AACpD,oBAAM,UAAU,OAAO,OAAuB;AAAA,gBAC5C,QAAQ;AAAA,gBACR,aAAa,OAAO;AAAA,cACtB,CAAC;AAAA,YACH;AACA,mBAAO,GAAG,IAAI,OAAO;AAAA,UACvB;AAEA,iBAAO;AAAA,QACT,SAAS,OAAO;AAEd,uBAAa;AACb,gBAAM;AAAA,QACR;AAAA,MACF,GAAG;AAAA,IACL;AAxLS,sCAAAL,8BAiBA,uBAAAE,uBA+DA,uBAAAC;AA55BT,UAAM,SAAS,CACb,IACA,mBACAG,iBACe;AACf,cAAQ,YAAY;AAElB,YAAI,OAAO,OAAO,YAAY,GAAG,WAAW,GAAG;AAC7C,gBAAM,IAAI;AAAA,YACR;AAAA,UAEF;AAAA,QACF;AACA,uBAAe,IAAI,MAAM;AAEzB,cAAM,gBAA6BA,gBAAe,CAAC;AACnD,cAAM,eAAe,oBAAoB,aAAa;AAGtD,cAAM,WAAW;AACjB,cAAM,UAAU,cAAc,OAAO;AACrC,cAAM,cAAc,cAAc,OAAO;AACzC,cAAM,EAAE,aAAa,iBAAiB,OAAO,aAAa,SAAS,cAAc,IAAI;AACrF,cAAM,SAAS,eAAe,OAAO;AACrC,cAAM,oBAAoB;AAC1B,cAAM,mBAAmB,oBAAoB,YAAY,IAAI,IAAI;AAGjE,cAAM,iBAAiB,aAAa,iBAAiB;AACrD,cAAM,YAAY,iBACd,MAAM,oBACN;AAIJ,cAAM,cAAc,KAAK,IAAI,GAAG,aAAa,YAAY,CAAC;AAC1D,cAAM,iBAAiB;AAAA,UACrB,UAAU;AAAA,UACV,SAAS,aAAa,WAAW,qBAAqB;AAAA,UACtD,cAAc,aAAa,gBAAgB,qBAAqB;AAAA,UAChE,UAAU,aAAa,YAAY,qBAAqB;AAAA,UACxD,QAAQ,aAAa,UAAU,qBAAqB;AAAA,UACpD,aAAa,aAAa,eAAe,qBAAqB;AAAA,UAC9D,SAAS,aAAa,WAAW,qBAAqB;AAAA,QACxD;AAGA,YAAI,SAAS;AACX,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,aAAa;AAAA,YACb,IAAI,KAAK,IAAI;AAAA,YACb,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,UAC/C,CAAC;AAAA,QACH;AAEA,YAAI;AAEJ,iBAAS,UAAU,GAAG,WAAW,eAAe,UAAU,WAAW;AACnE,gBAAM,mBAAmB,oBAAoB,YAAY,IAAI,IAAI;AAEjE,cAAI;AAEF,gBAAI;AAEJ,gBAAI,eAAe;AAEjB,uBAAS,MAAM;AAAA,gBACb;AAAA,gBACA;AAAA,gBACA,EAAE,MAAM,UAAU,KAAK,SAAS,QAAQ;AAAA,gBACxC;AAAA,cACF;AAAA,YACF,OAAO;AACL,uBAAS,MAAM,UAAU;AAAA,YAC3B;AAGA,gBAAI,OAAO,IAAI;AACb,oBAAM,aAAa,YAAY,IAAI,IAAI;AACvC,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,aAAa;AAAA,gBACb,IAAI,KAAK,IAAI;AAAA,gBACb;AAAA,gBACA,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,cAC/C,CAAC;AACD,kBAAI,aAAa;AACf,0BAAU;AAAA,kBACR,MAAM;AAAA,kBACN;AAAA,kBACA,SAAS;AAAA,kBACT,MAAM;AAAA,kBACN,aAAa;AAAA,kBACb,IAAI,KAAK,IAAI;AAAA,kBACb;AAAA,kBACA;AAAA,kBACA,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,gBAC/C,CAAC;AAAA,cACH;AACA,qBAAO,OAAO;AAAA,YAChB;AAGA,yBAAa;AAEb,gBAAI,UAAU,eAAe,YAAY,eAAe,YAAY,OAAO,OAAO,OAAO,GAAG;AAC1F,oBAAM,QAAQ,oBAAoB,SAAS,cAAc;AAGzD,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,IAAI,KAAK,IAAI;AAAA,gBACb,SAAS,UAAU;AAAA,gBACnB,aAAa,eAAe;AAAA,gBAC5B,SAAS;AAAA,gBACT,OAAO,OAAO;AAAA,gBACd,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,gBAC7C,aAAa,sBAAsB,OAAO,OAAO,cAAc,WAAW,UAAU,SAAS,YAAY,IAAI,IAAI,gBAAgB;AAAA,cACnI,CAAC;AAED,6BAAe,QAAQ,OAAO,OAAO,SAAS,KAAK;AACnD,oBAAMC,OAAM,KAAK;AACjB;AAAA,YACF;AAGA,gBAAI,eAAe,WAAW,GAAG;AAC/B,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,IAAI,KAAK,IAAI;AAAA,gBACb,YAAY,YAAY,IAAI,IAAI;AAAA,gBAChC,UAAU;AAAA,gBACV,WAAW,OAAO;AAAA,gBAClB,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,gBAC7C,aAAa,sBAAsB,OAAO,OAAO,cAAc,WAAW,UAAU,SAAS,YAAY,IAAI,IAAI,gBAAgB;AAAA,cACnI,CAAC;AAAA,YACH;AAGA;AAAA,UAEF,SAAS,QAAQ;AACf,kBAAM,aAAa,YAAY,IAAI,IAAI;AAGvC,gBAAI,sBAAsB,MAAM,GAAG;AACjC,oBAAM,YAAY,OAAO;AACzB,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,IAAI,KAAK,IAAI;AAAA,gBACb;AAAA,gBACA;AAAA,gBACA,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,gBAC7C,aAAa,sBAAsB,QAAQ,cAAc,WAAW,WAAW,OAAO;AAAA,cACxF,CAAC;AACD,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,aAAa;AAAA,gBACb,IAAI,KAAK,IAAI;AAAA,gBACb,YAAY,YAAY,IAAI,IAAI;AAAA,gBAChC,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,cAC/C,CAAC;AACD,kBAAI,aAAa;AACf,0BAAU;AAAA,kBACR,MAAM;AAAA,kBACN;AAAA,kBACA,SAAS;AAAA,kBACT,MAAM;AAAA,kBACN,aAAa;AAAA,kBACb,IAAI,KAAK,IAAI;AAAA,kBACb,YAAY,YAAY,IAAI,IAAI;AAAA,kBAChC,QAAQC,IAAG,MAAS;AAAA,kBACpB,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,gBAC/C,CAAC;AAAA,cACH;AAEA,qBAAO;AAAA,YACT;AAGA,gBAAI,aAAa,MAAM,GAAG;AACxB,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,aAAa;AAAA,gBACb,IAAI,KAAK,IAAI;AAAA,gBACb;AAAA,gBACA,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,cAC/C,CAAC;AACD,oBAAM;AAAA,YACR;AAGA,gBAAI,mBAAmB,MAAM,GAAG;AAE9B,oBAAM,cAAc,mBAAmB,MAAM;AAC7C,oBAAM,YAAY,eAAe,MAAM,aAAa,aAAa;AACjE,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,IAAI,KAAK,IAAI;AAAA,gBACb;AAAA,gBACA;AAAA,gBACA,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,gBAC7C,aAAa,sBAAsB,QAAQ,cAAc,WAAW,WAAW,OAAO;AAAA,cACxF,CAAC;AAGD,kBAAI,UAAU,eAAe,YAAY,eAAe,YAAY,QAAQ,OAAO,GAAG;AACpF,sBAAM,QAAQ,oBAAoB,SAAS,cAAc;AAEzD,0BAAU;AAAA,kBACR,MAAM;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,MAAM;AAAA,kBACN,IAAI,KAAK,IAAI;AAAA,kBACb,SAAS,UAAU;AAAA,kBACnB,aAAa,eAAe;AAAA,kBAC5B,SAAS;AAAA,kBACT,OAAO;AAAA,kBACP,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,kBAC7C,aAAa,sBAAsB,QAAQ,cAAc,WAAW,WAAW,SAAS,YAAY,IAAI,IAAI,gBAAgB;AAAA,gBAC9H,CAAC;AAED,+BAAe,QAAQ,QAAQ,SAAS,KAAK;AAC7C,sBAAMD,OAAM,KAAK;AACjB;AAAA,cACF;AAGA,kBAAI,eAAe,WAAW,GAAG;AAC/B,0BAAU;AAAA,kBACR,MAAM;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA,MAAM;AAAA,kBACN,IAAI,KAAK,IAAI;AAAA,kBACb,YAAY,YAAY,IAAI,IAAI;AAAA,kBAChC,UAAU;AAAA,kBACV,WAAW;AAAA,kBACX,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,kBAC7C,aAAa,sBAAsB,QAAQ,cAAc,WAAW,WAAW,SAAS,YAAY,IAAI,IAAI,gBAAgB;AAAA,gBAC9H,CAAC;AAAA,cACH;AAIA,oBAAME,mBAAkB,YAAY,IAAI,IAAI;AAC5C,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,aAAa;AAAA,gBACb,IAAI,KAAK,IAAI;AAAA,gBACb,YAAYA;AAAA,gBACZ,OAAO;AAAA,gBACP,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,gBAC7C,aAAa,sBAAsB,QAAQ,cAAc,WAAW,WAAW,SAASA,gBAAe;AAAA,cACzG,CAAC;AACD,kBAAI,aAAa;AACf,0BAAU;AAAA,kBACR,MAAM;AAAA,kBACN;AAAA,kBACA,SAAS;AAAA,kBACT,MAAM;AAAA,kBACN,aAAa;AAAA,kBACb,IAAI,KAAK,IAAI;AAAA,kBACb,YAAYA;AAAA,kBACZ,QAAQJ,KAAI,QAAwB,EAAE,OAAO,OAAO,CAAC;AAAA,kBACrD,MAAM,EAAE,QAAQ,SAAS,OAAO;AAAA,kBAChC,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,gBAC/C,CAAC;AAAA,cACH;AACA,wBAAU,QAAwB,UAAU,OAAO;AACnD,oBAAM,UAAU,QAAwB,EAAE,QAAQ,SAAS,OAAO,CAAC;AAAA,YACrE;AAKA,gBAAI,UAAU,eAAe,YAAY,eAAe,YAAY,QAAQ,OAAO,GAAG;AACpF,oBAAM,QAAQ,oBAAoB,SAAS,cAAc;AAEzD,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,IAAI,KAAK,IAAI;AAAA,gBACb,SAAS,UAAU;AAAA,gBACnB,aAAa,eAAe;AAAA,gBAC5B,SAAS;AAAA,gBACT,OAAO;AAAA,gBACP,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,gBAC7C,aAAa,sBAAsB,QAAQ,cAAc,WAAW,SAAS,SAAS,YAAY,IAAI,IAAI,gBAAgB;AAAA,cAC5H,CAAC;AAED,6BAAe,QAAQ,QAAQ,SAAS,KAAK;AAC7C,oBAAME,OAAM,KAAK;AACjB;AAAA,YACF;AAGA,gBAAI,eAAe,WAAW,KAAK,CAAC,mBAAmB,MAAM,GAAG;AAC9D,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,IAAI,KAAK,IAAI;AAAA,gBACb,YAAY,YAAY,IAAI,IAAI;AAAA,gBAChC,UAAU;AAAA,gBACV,WAAW;AAAA,gBACX,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,gBAC7C,aAAa,sBAAsB,QAAQ,cAAc,WAAW,SAAS,SAAS,YAAY,IAAI,IAAI,gBAAgB;AAAA,cAC5H,CAAC;AAAA,YACH;AAGA,kBAAME,mBAAkB,YAAY,IAAI,IAAI;AAE5C,gBAAI;AACJ,gBAAI;AACF,4BAAc,yBAAyB,MAAM;AAAA,YAC/C,SAAS,aAAa;AACpB,oBAAM,sBAAsB,WAAW;AAAA,YACzC;AACA,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,aAAa;AAAA,cACb,IAAI,KAAK,IAAI;AAAA,cACb,YAAYA;AAAA,cACZ,OAAO;AAAA,cACP,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,cAC7C,aAAa,sBAAsB,QAAQ,cAAc,WAAW,SAAS,SAASA,gBAAe;AAAA,YACvG,CAAC;AACD,gBAAI,aAAa;AACf,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA,SAAS;AAAA,gBACT,MAAM;AAAA,gBACN,aAAa;AAAA,gBACb,IAAI,KAAK,IAAI;AAAA,gBACb,YAAYA;AAAA,gBACZ,QAAQJ,KAAI,aAAa,EAAE,OAAO,OAAO,CAAC;AAAA,gBAC1C,MAAM,EAAE,QAAQ,SAAS,OAAO;AAAA,gBAChC,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,cAC/C,CAAC;AAAA,YACH;AACA,sBAAU,aAAkB,UAAU,OAAO;AAC7C,kBAAM,UAAU,aAAkB,EAAE,QAAQ,SAAS,OAAO,CAAC;AAAA,UAC/D;AAAA,QACF;AAIA,cAAM,cAAc;AACpB,cAAM,kBAAkB,YAAY,IAAI,IAAI;AAC5C,cAAM,eAAe,YAAY,YAAY,OAAO;AAAA,UAClD,QAAQ;AAAA,UACR,aAAa,YAAY;AAAA,QAC3B,CAAC;AACD,kBAAU;AAAA,UACR,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,aAAa;AAAA,UACb,IAAI,KAAK,IAAI;AAAA,UACb,YAAY;AAAA,UACZ,OAAO;AAAA,UACP,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,UAC7C,aAAa,sBAAsB,YAAY,OAAO,cAAc,WAAW,UAAU,eAAe,UAAU,eAAe;AAAA,QACnI,CAAC;AACD,YAAI,aAAa;AACf,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA,SAAS;AAAA,YACT,MAAM;AAAA,YACN,aAAa;AAAA,YACb,IAAI,KAAK,IAAI;AAAA,YACb,YAAY;AAAA,YACZ,QAAQ;AAAA,YACR,MAAM,EAAE,QAAQ,UAAU,aAAa,YAAY,MAAM;AAAA,YACzD,GAAI,gBAAgB,EAAE,UAAU,aAAa;AAAA,UAC/C,CAAC;AAAA,QACH;AACA,kBAAU,cAA8B,UAAU,OAAO;AACzD,cAAM,UAAU,cAA8B;AAAA,UAC5C,QAAQ;AAAA,UACR,aAAa,YAAY;AAAA,QAC3B,CAAC;AAAA,MACH,GAAG;AAAA,IACL;AAEA,WAAO,MAAM,CACX,IACA,WACA,SAiBe;AAEf,UAAI,OAAO,OAAO,YAAY,GAAG,WAAW,GAAG;AAC7C,cAAM,IAAI;AAAA,UACR;AAAA,QAEF;AAAA,MACF;AACA,qBAAe,IAAI,MAAM;AAEzB,YAAM,aAAa,WAAW,OAAO,MAAM,KAAK,QAAQ,KAAK;AAG7D,UAAI,KAAK,SAAS,KAAK,SAAS;AAC9B,eAAO,OAAO;AAAA,UACZ;AAAA,UACA,YAAY;AACV,gBAAI;AACF,qBAAOG,IAAG,MAAM,UAAU,CAAC;AAAA,YAC7B,SAAS,OAAO;AACd,qBAAOH,KAAI,WAAW,KAAK,GAAG,EAAE,MAAM,CAAC;AAAA,YACzC;AAAA,UACF;AAAA,UACA;AAAA,YACE,UAAU,KAAK,OAAO,YAAY;AAAA,YAClC,GAAI,KAAK,SAAS,CAAC;AAAA,YACnB,KAAK,KAAK;AAAA,YACV,SAAS,KAAK;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAEA,YAAM,UAAU,KAAK,OAAO;AAC5B,YAAM,WAAW;AACjB,YAAM,SAAS;AACf,YAAM,oBAAoB;AAE1B,cAAQ,YAAY;AAClB,cAAM,YAAY,oBAAoB,YAAY,IAAI,IAAI;AAE1D,YAAI,SAAS;AACX,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,UACf,CAAC;AAAA,QACH;AAEA,YAAI;AACF,gBAAMJ,SAAQ,MAAM,UAAU;AAC9B,gBAAM,aAAa,YAAY,IAAI,IAAI;AACvC,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,YACb;AAAA,UACF,CAAC;AAED,cAAI,SAAS;AACX,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb;AAAA,cACA,QAAQO,IAAGP,MAAK;AAAA,YAClB,CAAC;AAAA,UACH;AACA,iBAAOA;AAAA,QACT,SAAS,OAAO;AACd,gBAAM,SAAS,WAAW,KAAK;AAC/B,gBAAM,aAAa,YAAY,IAAI,IAAI;AACvC,gBAAM,eAAe,YAAY,QAAQ,EAAE,QAAQ,SAAS,QAAQ,MAAM,CAAC;AAC3E,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,YACb;AAAA,YACA,OAAO;AAAA,UACT,CAAC;AAGD,cAAI,SAAS;AACX,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb;AAAA,cACA,QAAQI,KAAI,QAAQ,EAAE,OAAO,MAAM,CAAC;AAAA,cACpC,MAAM,EAAE,QAAQ,SAAS,QAAQ,MAAM;AAAA,YACzC,CAAC;AAAA,UACH;AACA,oBAAU,cAA8B,UAAU,OAAO;AACzD,gBAAM,UAAU,cAA8B,EAAE,QAAQ,SAAS,QAAQ,MAAM,CAAC;AAAA,QAClF;AAAA,MACF,GAAG;AAAA,IACL;AAGA,WAAO,aAAa,CAClB,IACA,WACA,SAGe;AAEf,UAAI,OAAO,OAAO,YAAY,GAAG,WAAW,GAAG;AAC7C,cAAM,IAAI;AAAA,UACR;AAAA,QAEF;AAAA,MACF;AACA,qBAAe,IAAI,MAAM;AAEzB,YAAM,UAAU,KAAK,OAAO;AAC5B,YAAM,WAAW;AACjB,YAAM,SAAS;AACf,YAAM,aAAa,WAAW,OAAO,MAAM,KAAK,QAAQ,KAAK;AAC7D,YAAM,oBAAoB;AAE1B,cAAQ,YAAY;AAClB,cAAM,YAAY,oBAAoB,YAAY,IAAI,IAAI;AAE1D,YAAI,SAAS;AACX,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,UACf,CAAC;AAAA,QACH;AAEA,cAAM,SAAS,MAAM,UAAU;AAE/B,YAAI,OAAO,IAAI;AACb,gBAAM,aAAa,YAAY,IAAI,IAAI;AACvC,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,YACb;AAAA,UACF,CAAC;AAED,cAAI,SAAS;AACX,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb;AAAA,cACA,QAAQG,IAAG,OAAO,KAAK;AAAA,YACzB,CAAC;AAAA,UACH;AACA,iBAAO,OAAO;AAAA,QAChB,OAAO;AACL,gBAAM,SAAS,WAAW,OAAO,KAAK;AACtC,gBAAM,aAAa,YAAY,IAAI,IAAI;AAGvC,gBAAM,eAAe,YAAY,QAAQ;AAAA,YACvC,QAAQ;AAAA,YACR,aAAa,OAAO;AAAA,UACtB,CAAC;AACD,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,YACb;AAAA,YACA,OAAO;AAAA,UACT,CAAC;AAED,cAAI,SAAS;AACX,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb;AAAA,cACA,QAAQH,KAAI,QAAQ,EAAE,OAAO,OAAO,MAAM,CAAC;AAAA,cAC3C,MAAM,EAAE,QAAQ,UAAU,aAAa,OAAO,MAAM;AAAA,YACtD,CAAC;AAAA,UACH;AACA,oBAAU,cAA8B,UAAU,OAAO;AACzD,gBAAM,UAAU,cAA8B;AAAA,YAC5C,QAAQ;AAAA,YACR,aAAa,OAAO;AAAA,UACtB,CAAC;AAAA,QACH;AAAA,MACF,GAAG;AAAA,IACL;AAGA,WAAO,eAAe,CACpB,IACA,WACA,QACAD,aACe;AACf,UAAI,OAAO,OAAO,YAAY,GAAG,WAAW,GAAG;AAC7C,cAAM,IAAI;AAAA,UACR;AAAA,QAEF;AAAA,MACF;AACA,aAAO;AAAA,QACL;AAAA,QACA,YAAY;AACV,gBAAMH,SAAQ,MAAM,UAAU;AAC9B,iBAAOA,UAAS,OAAOO,IAAGP,MAAK,IAAII,KAAI,OAAO,CAAC;AAAA,QACjD;AAAA,QACAD;AAAA,MACF;AAAA,IACF;AAGA,WAAO,QAAQ,CACb,IACA,WACAA,aACe;AAEf,UAAI,OAAO,OAAO,YAAY,GAAG,WAAW,GAAG;AAC7C,cAAM,IAAI;AAAA,UACR;AAAA,QAEF;AAAA,MACF;AAIA,aAAO,OAAO,IAAI,WAAW;AAAA,QAC3B,KAAKA,SAAQ,OAAO;AAAA,QACpB,OAAO;AAAA,UACL,UAAUA,SAAQ;AAAA,UAClB,SAASA,SAAQ;AAAA,UACjB,cAAcA,SAAQ;AAAA,UACtB,UAAUA,SAAQ;AAAA,UAClB,QAAQA,SAAQ;AAAA,UAChB,aAAaA,SAAQ;AAAA,UACrB,SAASA,SAAQ;AAAA,QACnB;AAAA,QACA,SAASA,SAAQ;AAAA,MACnB,CAAC;AAAA,IACH;AAGA,WAAO,cAAc,CACnB,IACA,WAGAA,aACe;AAEf,UAAI,OAAO,OAAO,YAAY,GAAG,WAAW,GAAG;AAC7C,cAAM,IAAI;AAAA,UACR;AAAA,QAEF;AAAA,MACF;AAKA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,UACE,KAAKA,SAAQ,OAAO;AAAA,UACpB,SAASA;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAGA,WAAO,QAAQ,CACb,IACA,UACAA,aACkB;AAElB,UAAI,OAAO,OAAO,YAAY,GAAG,WAAW,GAAG;AAC7C,cAAM,IAAI;AAAA,UACR;AAAA,QAEF;AAAA,MACF;AAGA,YAAM,IAAI,OAAO,aAAa,WAAW,oBAAoB,QAAQ,IAAI;AACzE,UAAI,CAAC,GAAG;AACN,cAAM,IAAI,MAAM,iCAAiC,QAAQ,GAAG;AAAA,MAC9D;AACA,YAAM,KAAK,EAAE;AACb,YAAM,aAAaA,UAAS;AAI5B,aAAO;AAAA,QACL;AAAA,QACA,YAAsC;AAEpC,cAAI,iBAAiB,WAAW,YAAY,SAAS;AACnD,kBAAM,IAAI,IAAI,MAAM,eAAe;AACnC,cAAE,OAAO;AACT,kBAAM;AAAA,UACR;AAEA,iBAAO,IAAI,QAA6B,CAAC,SAAS,WAAW;AAG3D,kBAAM,QAAQ,EAAE,WAAW,OAAuD;AAElF,kBAAM,UAAU,MAAM;AACpB,kBAAI,MAAM,UAAW,cAAa,MAAM,SAAS;AACjD,oBAAM,IAAI,IAAI,MAAM,eAAe;AACnC,gBAAE,OAAO;AACT,qBAAO,CAAC;AAAA,YACV;AAEA,6BAAiB,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAClE,wBAAY,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAE7D,kBAAM,YAAY,WAAW,MAAM;AACjC,+BAAiB,oBAAoB,SAAS,OAAO;AACrD,0BAAY,oBAAoB,SAAS,OAAO;AAChD,sBAAQI,IAAG,MAAS,CAAC;AAAA,YACvB,GAAG,EAAE;AAAA,UACP,CAAC;AAAA,QACH;AAAA,QACA;AAAA,UACE,KAAKJ,UAAS,OAAO;AAAA,UACrB,aAAaA,UAAS;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAKA,WAAO,OAAO,IAAI,SAAsC;AACtD,UAAI,OAAO,KAAK,CAAC,MAAM,UAAU;AAC/B,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,YAAM,OAAO,KAAK,CAAC;AACnB,YAAM,SAAS,KAAK,CAAC;AACrB,UAAI,OAAO,WAAW,YAAY;AAChC,eAAOF,sBAAqB,MAAM,MAA6D;AAAA,MACjG;AACA,UAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,MAAM,GAAG;AAClE,cAAM,gBAAgB;AACtB,cAAM,uBAAuBF,6BAA4B,aAAa;AACtE,eAAOG,sBAAqB,sBAAsB,EAAE,KAAK,CAAC;AAAA,MAC5D;AACA,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AA6LA,WAAO,OAAO,CACZ,MACA,cACe;AACf,YAAM,UAAU,SAAS,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAE7E,cAAQ,YAAY;AAClB,cAAM,YAAY,YAAY,IAAI;AAClC,YAAI,aAAa;AAGjB,cAAM,aAAa,EAAE,SAAS,MAAM,QAAiB,UAAU,OAAgC;AAC/F,yBAAiB,KAAK,UAAU;AAGhC,cAAM,eAAe,MAAM;AACzB,cAAI,WAAY;AAChB,uBAAa;AAEb,gBAAM,MAAM,iBAAiB,UAAU,OAAK,EAAE,YAAY,OAAO;AACjE,cAAI,QAAQ,GAAI,kBAAiB,OAAO,KAAK,CAAC;AAC9C,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA,IAAI,KAAK,IAAI;AAAA,YACb,YAAY,YAAY,IAAI,IAAI;AAAA,YAChC,UAAU,WAAW;AAAA,UACvB,CAAC;AAAA,QACH;AAGA,kBAAU;AAAA,UACR,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA,WAAW;AAAA,UACX;AAAA,UACA,IAAI,KAAK,IAAI;AAAA,QACf,CAAC;AAED,YAAI;AACF,gBAAM,SAAS,MAAM,UAAU;AAG/B,uBAAa;AAEb,cAAI,CAAC,OAAO,IAAI;AACd,sBAAU,OAAO,OAAuB,MAAM,OAAO;AACrD,kBAAM,UAAU,OAAO,OAAuB;AAAA,cAC5C,QAAQ;AAAA,cACR,aAAa,OAAO;AAAA,YACtB,CAAC;AAAA,UACH;AAEA,iBAAO,OAAO;AAAA,QAChB,SAAS,OAAO;AAEd,uBAAa;AACb,gBAAM;AAAA,QACR;AAAA,MACF,GAAG;AAAA,IACL;AAMA,WAAO,KAAK,CACV,IACA,gBACA,cACM;AACN,qBAAe,IAAI,UAAU;AAC7B,YAAMF,SAAQ,UAAU;AACxB,gBAAU;AAAA,QACR,MAAM;AAAA,QACN;AAAA,QACA,YAAY;AAAA,QACZ,OAAO;AAAA,QACP,QAAQA,SAAQ,SAAS;AAAA,QACzB,OAAAA;AAAA,QACA,IAAI,KAAK,IAAI;AAAA,MACf,CAAC;AACD,aAAOA;AAAA,IACT;AAIA,WAAO,QAAQ,OAAO;AAKtB,WAAO,SAAS,OAMd,IACAG,aACe;AACf,YAAM,EAAE,WAAW,MAAM,QAAQ,MAAM,OAAO,IAAIA;AAClD,qBAAe,IAAI,UAAU;AAC7B,YAAM,kBAAkB,UAAU;AAClC,YAAM,SAAS,kBAAkB,SAAS;AAC1C,YAAM,YAAY,YAAY,IAAI;AAIlC,gBAAU;AAAA,QACR,MAAM;AAAA,QACN;AAAA,QACA,YAAY;AAAA,QACZ,OAAOA,SAAQ;AAAA,QACf;AAAA,QACA,OAAO;AAAA,QACP,OAAO;AAAA,QACP,IAAI,KAAK,IAAI;AAAA,MACf,CAAC;AACD,YAAM,UAAU,MAAM;AACpB,kBAAU;AAAA,UACR,MAAM;AAAA,UACN;AAAA,UACA,YAAY;AAAA,UACZ,OAAOA,SAAQ;AAAA,UACf;AAAA,UACA,OAAO;AAAA,UACP,OAAO;AAAA,UACP,YAAY,YAAY,IAAI,IAAI;AAAA,UAChC,IAAI,KAAK,IAAI;AAAA,QACf,CAAC;AAAA,MACH;AACA,UAAI;AACF,YAAI,iBAAiB;AACnB,iBAAO,MAAM,OAAO;AAAA,QACtB,WAAW,QAAQ;AACjB,iBAAO,MAAM,OAAO;AAAA,QACtB;AACA,eAAO;AAAA,MACT,UAAE;AACA,gBAAQ;AAAA,MACV;AAAA,IACF;AAKA,WAAO,MAAM,CACXM,KACA,WAC2B;AAC3B,aAAO,EAAE,IAAAA,KAAI,OAAO;AAAA,IACtB;AAIA,WAAO,UAAU,OACf,KACA,OACAN,aACiB;AACjB,YAAM,UAAe,CAAC;AACtB,YAAM,gBAAgBA,SAAQ;AAC9B,UAAI,QAAQ;AAGZ,YAAM,YAAY,SAASA;AAG3B,YAAM,aAAa,OAAO,iBAAkB,QACvC,SACA,mBAAmB;AAAE,eAAO;AAAA,MAAsB,GAAG;AAE1D,uBAAiB,QAAQ,YAAY;AACnC,YAAI,kBAAkB,UAAa,SAAS,eAAe;AACzD;AAAA,QACF;AAEA,YAAI;AACJ,YAAI,WAAW;AACb,gBAAM,aAAaA;AACnB,mBAAS,MAAM,WAAW,IAAI,MAAM,KAAK;AAAA,QAC3C,OAAO;AACL,gBAAM,cAAcA;AACpB,mBAAS,MAAM,YAAY,KAAK,QAAQ,MAAM,OAAO,MAAqC;AAAA,QAC5F;AAEA,gBAAQ,KAAK,MAAM;AACnB;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAKA,WAAO,OAAO,CACZ,YAC6B;AAC7B,aAAO;AAAA,QACL,sBAAsB;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAKA,WAAO,MAAM,CACX,OACAM,QACM;AACN,aAAOA;AAAA,IACT;AAOA,WAAO,WAAW,CAChB,IACA,QACAN,aACe;AACf,aAAO,OAAO,IAAI,QAA0CA,QAAO;AAAA,IACrE;AAGA,WAAO,MAAM,OACX,IACA,OACA,QACAA,aACiB;AACjB,YAAM,cAAcA,UAAS,eAAe,MAAM;AAGlD,aAAO;AAAA,QACL;AAAA,QACA,MAAM;AACJ,cAAI,eAAe,MAAM,QAAQ;AAE/B,mBAAOO,UAAS,MAAM,IAAI,CAAC,MAAM,UAAU,OAAO,MAAM,KAAK,CAAC,CAAC;AAAA,UACjE,OAAO;AAEL,oBAAQ,YAAY;AAClB,oBAAM,UAAe,CAAC;AACtB,uBAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,aAAa;AAClD,sBAAM,QAAQ,MAAM,MAAM,GAAG,IAAI,WAAW;AAC5C,sBAAM,cAAc,MAAMA;AAAA,kBACxB,MAAM,IAAI,CAAC,MAAM,eAAe,OAAO,MAAM,IAAI,UAAU,CAAC;AAAA,gBAC9D;AAEA,oBAAI,CAAC,YAAY,IAAI;AACnB,yBAAO;AAAA,gBACT;AACA,wBAAQ,KAAK,GAAG,YAAY,KAAK;AAAA,cACnC;AACA,qBAAOH,IAAG,OAAO;AAAA,YACnB,GAAG;AAAA,UACL;AAAA,QACF;AAAA,QACA,EAAE,KAAKJ,UAAS,IAAI;AAAA,MACtB;AAAA,IACF;AAGA,WAAO,eAAe,CACpB,IACA,WACAA,aACe;AACf,UAAI,OAAO,OAAO,YAAY,GAAG,WAAW,GAAG;AAC7C,cAAM,IAAI;AAAA,UACR;AAAA,QAEF;AAAA,MACF;AACA,qBAAe,IAAI,MAAM;AAEzB,YAAM,UAAUA,SAAQ,OAAO;AAC/B,YAAM,WAAW;AACjB,YAAM,SAAS,eAAe,OAAO;AACrC,YAAM,oBAAoB;AAE1B,cAAQ,YAAY;AAClB,cAAM,YAAY,oBAAoB,YAAY,IAAI,IAAI;AAE1D,YAAI,SAAS;AACX,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,UACf,CAAC;AAAA,QACH;AAGA,YAAI;AACJ,YAAI;AACF,0BAAgB,MAAM,UAAU;AAAA,QAClC,SAAS,QAAQ;AAEf,cAAI,aAAa,MAAM,GAAG;AACxB,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAY,YAAY,IAAI,IAAI;AAAA,YAClC,CAAC;AACD,kBAAM;AAAA,UACR;AAGA,cAAI;AACJ,cAAI;AACF,0BAAc,yBAAyB,MAAM;AAAA,UAC/C,SAAS,aAAa;AACpB,kBAAM,sBAAsB,WAAW;AAAA,UACzC;AAGA,cAAIA,SAAQ,OAAO,UAAaA,SAAQ,OAAO,aAAa;AAC1D,kBAAMQ,cAAa,YAAY,IAAI,IAAI;AACvC,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAAA;AAAA,cACA,OAAO;AAAA,YACT,CAAC;AACD,gBAAI,SAAS;AACX,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,IAAI,KAAK,IAAI;AAAA,gBACb,YAAAA;AAAA,gBACA,QAAQP,KAAI,aAAa,EAAE,OAAO,OAAO,CAAC;AAAA,gBAC1C,MAAM,EAAE,QAAQ,SAAS,OAAO;AAAA,cAClC,CAAC;AAAA,YACH;AACA,sBAAU,aAAkB,UAAU,OAAO;AAC7C,kBAAM,UAAU,aAAkB,EAAE,QAAQ,SAAS,OAAO,CAAC;AAAA,UAC/D;AAGA,cAAI;AACJ,cAAI;AACF,sCAA0B,MAAMD,SAAQ,SAAS;AAAA,UACnD,SAAS,gBAAgB;AACvB,gBAAI,aAAa,cAAc,GAAG;AAChC,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,IAAI,KAAK,IAAI;AAAA,gBACb,YAAY,YAAY,IAAI,IAAI;AAAA,cAClC,CAAC;AACD,oBAAM;AAAA,YACR;AACA,gBAAI;AACJ,gBAAI;AACF,oCAAsB,yBAAyB,cAAc;AAAA,YAC/D,SAAS,aAAa;AACpB,oBAAM,sBAAsB,WAAW;AAAA,YACzC;AACA,kBAAMQ,cAAa,YAAY,IAAI,IAAI;AACvC,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAAA;AAAA,cACA,OAAO;AAAA,YACT,CAAC;AACD,gBAAI,SAAS;AACX,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,IAAI,KAAK,IAAI;AAAA,gBACb,YAAAA;AAAA,gBACA,QAAQP,KAAI,qBAAqB,EAAE,OAAO,eAAe,CAAC;AAAA,gBAC1D,MAAM,EAAE,QAAQ,SAAS,QAAQ,eAAe;AAAA,cAClD,CAAC;AAAA,YACH;AACA,sBAAU,qBAA0B,UAAU,OAAO;AACrD,kBAAM,UAAU,qBAA0B,EAAE,QAAQ,SAAS,QAAQ,eAAe,CAAC;AAAA,UACvF;AAEA,cAAI,wBAAwB,IAAI;AAC9B,kBAAMO,cAAa,YAAY,IAAI,IAAI;AACvC,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAAA;AAAA,YACF,CAAC;AACD,gBAAI,SAAS;AACX,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,IAAI,KAAK,IAAI;AAAA,gBACb,YAAAA;AAAA,gBACA,QAAQ;AAAA,gBACR,MAAM,EAAE,QAAQ,YAAqB,cAAc,MAAe,gBAAgB,OAAO,WAAW,EAAE;AAAA,cACxG,CAAC;AAAA,YACH;AACA,mBAAO,wBAAwB;AAAA,UACjC,OAAO;AAEL,kBAAMA,cAAa,YAAY,IAAI,IAAI;AACvC,kBAAMC,gBAAe,YAAY,wBAAwB,OAAO;AAAA,cAC9D,QAAQ;AAAA,cACR,aAAa,wBAAwB;AAAA,YACvC,CAAC;AACD,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAAD;AAAA,cACA,OAAOC;AAAA,YACT,CAAC;AACD,gBAAI,SAAS;AACX,wBAAU;AAAA,gBACR,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA,gBACN,IAAI,KAAK,IAAI;AAAA,gBACb,YAAAD;AAAA,gBACA,QAAQ;AAAA,gBACR,MAAM,EAAE,QAAQ,UAAU,aAAa,wBAAwB,MAAM;AAAA,cACvE,CAAC;AAAA,YACH;AACA,sBAAUC,eAA8B,UAAU,OAAO;AACzD,kBAAM,UAAUA,eAA8B;AAAA,cAC5C,QAAQ;AAAA,cACR,aAAa,wBAAwB;AAAA,YACvC,CAAC;AAAA,UACH;AAAA,QACF;AAGA,YAAI,cAAc,IAAI;AACpB,gBAAMD,cAAa,YAAY,IAAI,IAAI;AACvC,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,YACb,YAAAA;AAAA,UACF,CAAC;AACD,cAAI,SAAS;AACX,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAAA;AAAA,cACA,QAAQ;AAAA,YACV,CAAC;AAAA,UACH;AACA,iBAAO,cAAc;AAAA,QACvB;AAGA,cAAM,eAAe,cAAc;AAGnC,YAAIR,SAAQ,OAAO,UAAaA,SAAQ,OAAO,cAAc;AAC3D,gBAAMQ,cAAa,YAAY,IAAI,IAAI;AACvC,gBAAMC,gBAAe,YAAY,cAAc;AAAA,YAC7C,QAAQ;AAAA,YACR,aAAa,cAAc;AAAA,UAC7B,CAAC;AACD,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,YACb,YAAAD;AAAA,YACA,OAAOC;AAAA,UACT,CAAC;AACD,cAAI,SAAS;AACX,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAAD;AAAA,cACA,QAAQ;AAAA,cACR,MAAM,EAAE,QAAQ,UAAU,aAAa,cAAc,MAAM;AAAA,YAC7D,CAAC;AAAA,UACH;AACA,oBAAUC,eAA8B,UAAU,OAAO;AACzD,gBAAM,UAAUA,eAA8B;AAAA,YAC5C,QAAQ;AAAA,YACR,aAAa,cAAc;AAAA,UAC7B,CAAC;AAAA,QACH;AAGA,YAAI;AACJ,YAAI;AACF,2BAAiB,MAAMT,SAAQ,SAAS;AAAA,QAC1C,SAAS,QAAQ;AACf,cAAI,aAAa,MAAM,GAAG;AACxB,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAY,YAAY,IAAI,IAAI;AAAA,YAClC,CAAC;AACD,kBAAM;AAAA,UACR;AAEA,cAAI;AACJ,cAAI;AACF,0BAAc,yBAAyB,MAAM;AAAA,UAC/C,SAAS,aAAa;AACpB,kBAAM,sBAAsB,WAAW;AAAA,UACzC;AACA,gBAAMQ,cAAa,YAAY,IAAI,IAAI;AACvC,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,YACb,YAAAA;AAAA,YACA,OAAO;AAAA,UACT,CAAC;AACD,cAAI,SAAS;AACX,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAAA;AAAA,cACA,QAAQP,KAAI,aAAa,EAAE,OAAO,OAAO,CAAC;AAAA,cAC1C,MAAM,EAAE,QAAQ,SAAS,OAAO;AAAA,YAClC,CAAC;AAAA,UACH;AACA,oBAAU,aAAkB,UAAU,OAAO;AAC7C,gBAAM,UAAU,aAAkB,EAAE,QAAQ,SAAS,OAAO,CAAC;AAAA,QAC/D;AAEA,YAAI,eAAe,IAAI;AACrB,gBAAMO,cAAa,YAAY,IAAI,IAAI;AACvC,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,YACb,YAAAA;AAAA,UACF,CAAC;AACD,cAAI,SAAS;AACX,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAAA;AAAA,cACA,QAAQ;AAAA,cACR,MAAM,EAAE,QAAQ,YAAqB,cAAc,MAAe,gBAAgB,OAAO,YAAY,EAAE;AAAA,YACzG,CAAC;AAAA,UACH;AACA,iBAAO,eAAe;AAAA,QACxB;AAGA,cAAM,aAAa,YAAY,IAAI,IAAI;AACvC,cAAM,eAAe,YAAY,eAAe,OAAO;AAAA,UACrD,QAAQ;AAAA,UACR,aAAa,eAAe;AAAA,QAC9B,CAAC;AACD,kBAAU;AAAA,UACR,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,IAAI,KAAK,IAAI;AAAA,UACb;AAAA,UACA,OAAO;AAAA,QACT,CAAC;AACD,YAAI,SAAS;AACX,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,YACb;AAAA,YACA,QAAQ;AAAA,YACR,MAAM,EAAE,QAAQ,UAAU,aAAa,eAAe,MAAM;AAAA,UAC9D,CAAC;AAAA,QACH;AACA,kBAAU,cAA8B,UAAU,OAAO;AACzD,cAAM,UAAU,cAA8B;AAAA,UAC5C,QAAQ;AAAA,UACR,aAAa,eAAe;AAAA,QAC9B,CAAC;AAAA,MACH,GAAG;AAAA,IACL;AAGA,WAAO,eAAe,CACpB,IACAR,aAKe;AACf,UAAI,OAAO,OAAO,YAAY,GAAG,WAAW,GAAG;AAC7C,cAAM,IAAI;AAAA,UACR;AAAA,QAEF;AAAA,MACF;AACA,qBAAe,IAAI,MAAM;AAEzB,YAAM,UAAU;AAChB,YAAM,WAAW;AACjB,YAAM,SAAS,eAAe,OAAO;AACrC,YAAM,oBAAoB;AAE1B,cAAQ,YAAY;AAClB,cAAM,YAAY,oBAAoB,YAAY,IAAI,IAAI;AAE1D,YAAI,SAAS;AACX,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,UACf,CAAC;AAAA,QACH;AAGA,YAAI;AACJ,YAAI;AACF,0BAAgB,MAAMA,SAAQ,QAAQ;AAAA,QACxC,SAAS,QAAQ;AACf,cAAI,aAAa,MAAM,GAAG;AACxB,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAY,YAAY,IAAI,IAAI;AAAA,YAClC,CAAC;AACD,kBAAM;AAAA,UACR;AACA,cAAI;AACJ,cAAI;AACF,0BAAc,yBAAyB,MAAM;AAAA,UAC/C,SAAS,aAAa;AACpB,kBAAM,sBAAsB,WAAW;AAAA,UACzC;AACA,gBAAMQ,cAAa,YAAY,IAAI,IAAI;AACvC,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,YACb,YAAAA;AAAA,YACA,OAAO;AAAA,UACT,CAAC;AACD,cAAI,SAAS;AACX,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAAA;AAAA,cACA,QAAQP,KAAI,aAAa,EAAE,OAAO,OAAO,CAAC;AAAA,cAC1C,MAAM,EAAE,QAAQ,SAAS,OAAO;AAAA,YAClC,CAAC;AAAA,UACH;AACA,oBAAU,aAAkB,UAAU,OAAO;AAC7C,gBAAM,UAAU,aAAkB,EAAE,QAAQ,SAAS,OAAO,CAAC;AAAA,QAC/D;AAEA,YAAI,CAAC,cAAc,IAAI;AAErB,gBAAMO,cAAa,YAAY,IAAI,IAAI;AACvC,gBAAMC,gBAAe,YAAY,cAAc,OAAO;AAAA,YACpD,QAAQ;AAAA,YACR,aAAa,cAAc;AAAA,UAC7B,CAAC;AACD,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,YACb,YAAAD;AAAA,YACA,OAAOC;AAAA,UACT,CAAC;AACD,cAAI,SAAS;AACX,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAAD;AAAA,cACA,QAAQ;AAAA,cACR,MAAM,EAAE,QAAQ,UAAU,aAAa,cAAc,MAAM;AAAA,YAC7D,CAAC;AAAA,UACH;AACA,oBAAUC,eAA8B,UAAU,OAAO;AACzD,gBAAM,UAAUA,eAA8B;AAAA,YAC5C,QAAQ;AAAA,YACR,aAAa,cAAc;AAAA,UAC7B,CAAC;AAAA,QACH;AAEA,cAAM,WAAW,cAAc;AAC/B,YAAI;AACJ,YAAI;AACJ,YAAI,oBAAoB;AAGxB,YAAI;AACF,sBAAY,MAAMT,SAAQ,IAAI,QAAQ;AAAA,QACxC,SAAS,QAAQ;AACf,cAAI,aAAa,MAAM,GAAG;AAExB,gBAAI;AACF,oBAAMA,SAAQ,QAAQ,QAAQ;AAAA,YAChC,SAAS,YAAY;AACnB,sBAAQ;AAAA,gBACN,gCAAgC,EAAE;AAAA,gBAClC;AAAA,cACF;AAAA,YACF;AACA,kBAAM;AAAA,UACR;AACA,sBAAY;AACZ,8BAAoB;AAAA,QACtB;AAGA,YAAI;AACF,gBAAMA,SAAQ,QAAQ,QAAQ;AAAA,QAChC,SAAS,YAAY;AACnB,kBAAQ;AAAA,YACN,gCAAgC,EAAE;AAAA,YAClC;AAAA,UACF;AAAA,QACF;AAGA,YAAI,mBAAmB;AACrB,cAAI;AACJ,cAAI;AACF,0BAAc,yBAAyB,SAAS;AAAA,UAClD,SAAS,aAAa;AACpB,kBAAM,sBAAsB,WAAW;AAAA,UACzC;AACA,gBAAMQ,cAAa,YAAY,IAAI,IAAI;AACvC,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,YACb,YAAAA;AAAA,YACA,OAAO;AAAA,UACT,CAAC;AACD,cAAI,SAAS;AACX,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAAA;AAAA,cACA,QAAQP,KAAI,aAAa,EAAE,OAAO,UAAU,CAAC;AAAA,cAC7C,MAAM,EAAE,QAAQ,SAAS,QAAQ,UAAU;AAAA,YAC7C,CAAC;AAAA,UACH;AACA,oBAAU,aAAkB,UAAU,OAAO;AAC7C,gBAAM,UAAU,aAAkB,EAAE,QAAQ,SAAS,QAAQ,UAAU,CAAC;AAAA,QAC1E;AAGA,cAAM,SAAS;AACf,YAAI,OAAO,IAAI;AACb,gBAAMO,cAAa,YAAY,IAAI,IAAI;AACvC,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,YACb,YAAAA;AAAA,UACF,CAAC;AACD,cAAI,SAAS;AACX,sBAAU;AAAA,cACR,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA,MAAM;AAAA,cACN,IAAI,KAAK,IAAI;AAAA,cACb,YAAAA;AAAA,cACA;AAAA,YACF,CAAC;AAAA,UACH;AACA,iBAAO,OAAO;AAAA,QAChB;AAGA,cAAM,aAAa,YAAY,IAAI,IAAI;AACvC,cAAM,eAAe,YAAY,OAAO,OAAO;AAAA,UAC7C,QAAQ;AAAA,UACR,aAAa,OAAO;AAAA,QACtB,CAAC;AACD,kBAAU;AAAA,UACR,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,IAAI,KAAK,IAAI;AAAA,UACb;AAAA,UACA,OAAO;AAAA,QACT,CAAC;AACD,YAAI,SAAS;AACX,oBAAU;AAAA,YACR,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,IAAI,KAAK,IAAI;AAAA,YACb;AAAA,YACA;AAAA,YACA,MAAM,EAAE,QAAQ,UAAU,aAAa,OAAO,MAAM;AAAA,UACtD,CAAC;AAAA,QACH;AACA,kBAAU,cAA8B,UAAU,OAAO;AACzD,cAAM,UAAU,cAA8B;AAAA,UAC5C,QAAQ;AAAA,UACR,aAAa,OAAO;AAAA,QACtB,CAAC;AAAA,MACH,GAAG;AAAA,IACL;AAEA,UAAM,OAAO;AACb,UAAM,QAAQ,MAAM,GAAG,EAAE,KAAK,CAAC;AAG/B,QACE,QAAQ,IAAI,aAAa,gBACzB,UAAU,QACV,OAAO,UAAU,YACjB,QAAQ,SACR,OAAQ,MAA0B,OAAO,WACzC;AACA,YAAM,cAAc;AACpB,UACG,YAAY,OAAO,QAAQ,WAAW,eACtC,YAAY,OAAO,SAAS,WAAW,aACxC;AACA,gBAAQ;AAAA,UACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAKF;AAAA,MACF;AAAA,IACF;AAEA,WAAOJ,IAAG,KAAK;AAAA,EACjB,SAAS,OAAO;AAEd,QAAI,kBAAkB,KAAK,GAAG;AAC5B,YAAM,MAAM;AAAA,IACd;AAEA,QAAI,aAAa,KAAK,GAAG;AAEvB,YAAM,gBAAgB,MAAM,KAAK,WAAW,UACxC,MAAM,KAAK,SACX,MAAM,KAAK,WAAW,WACpB,MAAM,KAAK,cACX;AAEN,aAAOH,KAAI,MAAM,OAAO,EAAE,OAAO,cAAc,CAAC;AAAA,IAClD;AAEA,UAAM,SAAS,yBAAyB,KAAK;AAC7C,cAAU,QAAa,cAAc,OAAO;AAC5C,WAAOA,KAAI,QAAQ,EAAE,OAAO,MAAM,CAAC;AAAA,EACrC;AACF;AA4BA,IAAM,YAAY,CAChB,IACA,YAe+B;AAC/B,SAAO,MAAe,IAAI,OAAO;AACnC;AAUO,IAAM,MAAsB,uBAAO,OAAO,OAAO,EAAE,QAAQ,UAAU,CAAC;AAq0C7E,eAAsBS,UAGpB,SAOA;AAKA,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAOC,IAAG,CAAC,CAAC;AAAA,EACd;AAEA,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI,UAAU;AACd,QAAI,eAAe,QAAQ;AAC3B,UAAM,SAAoB,IAAI,MAAM,QAAQ,MAAM;AAElD,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,YAAM,QAAQ;AACd,cAAQ,QAAQ,QAAQ,KAAK,CAAC,EAC3B,MAAM,CAAC,WAAWC;AAAA,QACjB,EAAE,MAAM,oBAA6B,OAAO,OAAO;AAAA,QACnD,EAAE,OAAO,EAAE,MAAM,qBAA8B,OAAO,EAA2B;AAAA,MACnF,CAAC,EACA,KAAK,CAAC,WAAW;AAChB,YAAI,QAAS;AAEb,YAAI,CAAC,OAAO,IAAI;AACd,oBAAU;AACV,kBAAQ,MAAwC;AAChD;AAAA,QACF;AAEA,eAAO,KAAK,IAAI,OAAO;AACvB;AAEA,YAAI,iBAAiB,GAAG;AACtB,kBAAQD,IAAG,MAAM,CAAmC;AAAA,QACtD;AAAA,MACF,CAAC;AAAA,IACL;AAAA,EACF,CAAC;AACH;;;AChsMO,SAAS,IAOd,UACA,SAGyE;AACzE,SAAO,CAAC,YAAY;AAClB,UAAM,cAAc,IAAI,IAAI,QAAQ,QAAQ;AAC5C,gBAAY,IAAI,UAAU,OAAqC;AAE/D,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,QAAQ;AAAA,MACf,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAcO,SAASE,MAQd,UAOA;AACA,SAAO,CAAC,YAAY;AAClB,UAAM,cAAc,IAAI,IAAI,QAAQ,QAAQ;AAC5C,eAAW,CAAC,UAAU,OAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG;AAC1D,UAAI,SAAS;AACX,oBAAY,IAAI,UAAU,OAAqC;AAAA,MACjE;AAAA,IACF;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,QAAQ;AAAA,MACf,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAgBO,SAAS,WACd,SACQ;AACR,QAAM,UAAU,QAAQ,SAAS,IAAI,QAAQ,MAAM,IAAI;AACvD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,uBAAuB,QAAQ,MAAM,IAAI,EAAE;AAAA,EAC7D;AACA,SAAO,QAAQ,QAAQ,KAAK;AAC9B;AAYO,SAASC,QACd,SACwE;AACxE,SAAO,CAAC,YAAY;AAClB,UAAM,kBAAkB,QAAQ,SAAS,IAAI,QAAQ,MAAM,IAAI;AAC/D,QAAI,iBAAiB;AACnB,aAAO,gBAAgB,QAAQ,KAAK;AAAA,IACtC;AACA,WAAO,QAAQ,QAAQ,KAA6B;AAAA,EACtD;AACF;AAYO,SAAS,YACd,cACwE;AACxE,SAAOA,QAAO,MAAM,YAAY;AAClC;AAoBO,SAAS,KAOd,UACA,WACA,SAC+F;AAC/F,SAAO,CAAC,YAAY;AAClB,UAAM,cAAc,IAAI,IAAI,QAAQ,QAAQ;AAC5C,UAAM,kBAAkB,QAAQ,SAAS,IAAI,QAAQ;AAErD,gBAAY,IAAI,UAAU,CAAC,UAAkB;AAC3C,YAAM,aAAa;AACnB,UAAI,UAAU,UAAU,GAAG;AACzB,eAAO,QAAQ,UAAU;AAAA,MAC3B;AACA,UAAI,iBAAiB;AACnB,eAAO,gBAAgB,KAAK;AAAA,MAC9B;AACA,YAAM,IAAI,MAAM,+BAA+B,QAAQ,EAAE;AAAA,IAC3D,CAAC;AAED,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,QAAQ;AAAA,MACf,UAAU;AAAA,MACV,YAAY,QAAQ;AAAA,MACpB,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAkBO,SAAS,GACd,UACkD;AAClD,SAAO,CAAC,UAA8C,MAAM,SAAS;AACvE;AAYO,SAAS,WACXD,OACwD;AAC3D,QAAM,SAAS,IAAI,IAAIA,KAAI;AAC3B,SAAO,CAAC,UACN,OAAO,IAAI,MAAM,IAAoB;AACzC;AASA,SAAS,UAAU,OAA2D;AAC5E,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACT,MAA4B,SAAS;AAE1C;AAWA,SAAS,QACP,SACwC;AACxC,SAAO;AAAA,IACL,GAAG;AAAA,IACH,KAAK,IAAmE;AACtE,YAAM,SAAS,GAAG,OAAO;AAEzB,UAAI,UAAU,MAAM,GAAG;AACrB,eAAO,QAAQ,MAA0C;AAAA,MAC3D;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAYO,SAAS,WAA6B,OAAqC;AAChF,QAAM,UAAgC;AAAA,IACpC,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU,oBAAI,IAAI;AAAA,IAClB,YAAY;AAAA,IACZ,SAAS;AAAA,EACX;AAEA,SAAO,QAAQ,OAAO;AACxB;AA2BO,IAAM,QAAQ;AAAA,EACnB,OAAO;AAAA,EACP;AAAA,EACA,MAAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AClUO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EACjC,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAKT;AACD;AAAA,MACE,QAAQ,WACN,oBAAoB,QAAQ,WAAW,QAAQ,QAAQ,KAAK,iBAC7C,KAAK,KAAK,QAAQ,eAAe,GAAI,CAAC;AAAA,IACzD;AACA,SAAK,OAAO;AACZ,SAAK,cAAc,QAAQ;AAC3B,SAAK,QAAQ,QAAQ;AACrB,SAAK,eAAe,QAAQ;AAAA,EAC9B;AACF;AAKO,SAAS,mBAAmB,OAA2C;AAC5E,SACE,OAAO,UAAU,YACjB,UAAU,QACT,MAA2B,SAAS;AAEzC;AA0BA,IAAM,iBAAuC;AAAA,EAC3C,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,aAAa;AACf;AAwFO,SAAS,qBACd,MACA,QACgB;AAChB,QAAM,kBAAwC;AAAA,IAC5C,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAEA,MAAI,QAAsB;AAC1B,MAAI,WAA4B,CAAC;AACjC,MAAI,kBAAiC;AACrC,MAAI,kBAAiC;AACrC,MAAI,eAAe;AACnB,MAAI,oBAAoB;AAKxB,WAAS,kBAAwB;AAC/B,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW,SAAS;AAAA,MAClB,CAAC,MAAM,MAAM,EAAE,YAAY,gBAAgB;AAAA,IAC7C;AAAA,EACF;AAKA,WAAS,aAAa,UAA8B;AAClD,QAAI,UAAU,UAAU;AACtB,YAAM,WAAW;AACjB,cAAQ;AACR,UAAI,aAAa,aAAa;AAC5B,4BAAoB;AAAA,MACtB;AACA,sBAAgB,gBAAgB,UAAU,UAAU,IAAI;AAAA,IAC1D;AAAA,EACF;AAKA,WAAS,sBAA+B;AACtC,QAAI,UAAU,UAAU,oBAAoB,MAAM;AAChD,aAAO;AAAA,IACT;AACA,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,MAAM,mBAAmB,gBAAgB,cAAc;AACzD,mBAAa,WAAW;AACxB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAKA,WAAS,gBAAsB;AAC7B,sBAAkB,KAAK,IAAI;AAC3B;AAEA,QAAI,UAAU,aAAa;AACzB;AACA,UAAI,qBAAqB,gBAAgB,aAAa;AAEpD,qBAAa,QAAQ;AACrB,mBAAW,CAAC;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAKA,WAAS,cAAc,OAAsB;AAC3C,UAAM,MAAM,KAAK,IAAI;AACrB,sBAAkB;AAGlB,oBAAgB;AAGhB,aAAS,KAAK,EAAE,WAAW,KAAK,MAAM,CAAC;AAEvC,QAAI,UAAU,aAAa;AAEzB,mBAAa,MAAM;AAAA,IACrB,WAAW,UAAU,UAAU;AAE7B,UAAI,SAAS,UAAU,gBAAgB,kBAAkB;AACvD,qBAAa,MAAM;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAMA,WAAS,aAAqB;AAC5B,QAAI,UAAU,UAAU;AACtB,aAAO;AAAA,IACT;AAEA,QAAI,UAAU,QAAQ;AAEpB,UAAI,oBAAoB,GAAG;AACzB,eAAO;AAAA,MACT;AAEA,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,UAAU,kBAAkB,MAAM,kBAAkB;AAC1D,aAAO,KAAK,IAAI,GAAG,gBAAgB,eAAe,OAAO;AAAA,IAC3D;AAGA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,MAAM,QACJ,WACA,UACY;AACZ,YAAM,WAAW,WAAW;AAC5B,UAAI,WAAW,GAAG;AAChB,cAAM,IAAI,iBAAiB;AAAA,UACzB,aAAa;AAAA,UACb;AAAA,UACA,cAAc;AAAA,QAChB,CAAC;AAAA,MACH;AAEA,UAAI;AACF,cAAM,SAAS,MAAM,UAAU;AAC/B,sBAAc;AACd,eAAO;AAAA,MACT,SAAS,OAAO;AACd,sBAAc,KAAK;AACnB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,MAAM,cACJ,WACA,UACsC;AACtC,YAAM,WAAW,WAAW;AAC5B,UAAI,WAAW,GAAG;AAChB,eAAOC;AAAA,UACL,IAAI,iBAAiB;AAAA,YACnB,aAAa;AAAA,YACb;AAAA,YACA,cAAc;AAAA,UAChB,CAAC;AAAA,QACH;AAAA,MACF;AAEA,UAAI;AACF,cAAM,SAAS,MAAM,UAAU;AAC/B,YAAI,OAAO,IAAI;AACb,wBAAc;AAAA,QAChB,OAAO;AACL,wBAAc,OAAO,KAAK;AAAA,QAC5B;AACA,eAAO;AAAA,MACT,SAAS,OAAO;AACd,sBAAc,KAAK;AACnB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IAEA,WAAyB;AAEvB,UAAI,UAAU,QAAQ;AACpB,4BAAoB;AAAA,MACtB;AACA,aAAO;AAAA,IACT;AAAA,IAEA,WAAgC;AAC9B,sBAAgB;AAChB,aAAO;AAAA,QACL,OAAO,KAAK,SAAS;AAAA,QACrB,cAAc,SAAS;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IAEA,QAAc;AACZ,mBAAa,QAAQ;AACrB,iBAAW,CAAC;AACZ,0BAAoB;AAAA,IACtB;AAAA,IAEA,YAAkB;AAChB,wBAAkB,KAAK,IAAI;AAC3B,mBAAa,MAAM;AAAA,IACrB;AAAA,IAEA,gBAAsB;AACpB,oBAAc;AAAA,IAChB;AAAA,IAEA,cAAc,OAAuB;AACnC,oBAAc,SAAS,IAAI,MAAM,gBAAgB,CAAC;AAAA,IACpD;AAAA,EACF;AACF;AASO,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKnC,UAAU;AAAA,IACR,kBAAkB;AAAA,IAClB,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,aAAa;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU;AAAA,IACR,kBAAkB;AAAA,IAClB,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,aAAa;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS;AAAA,IACP,kBAAkB;AAAA,IAClB,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,aAAa;AAAA,EACf;AACF;;;AC5XO,SAAS,yBACd,OACiC;AACjC,SACE,OAAO,UAAU,YACjB,UAAU,QACT,MAAiC,SAAS;AAE/C;AAKO,SAAS,iBAAiB,OAAyC;AACxE,SACE,OAAO,UAAU,YACjB,UAAU,QACT,MAAyB,SAAS;AAEvC;AA2EO,SAAS,kBACd,MACA,QACa;AACb,QAAM,EAAE,cAAc,WAAW,OAAO,IAAI;AAC5C,QAAM,YAAY,OAAO,iBAAiB,eAAe;AAEzD,MAAI,SAAS;AACb,MAAI,aAAa,KAAK,IAAI;AAC1B,QAAM,aAAa,eAAe;AAGlC,QAAM,YAA+B,CAAC;AAKtC,WAAS,SAAe;AACtB,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,UAAU,MAAM;AACtB,UAAM,cAAc,UAAU;AAC9B,aAAS,KAAK,IAAI,WAAW,SAAS,WAAW;AACjD,iBAAa;AAAA,EACf;AAMA,WAAS,aAAqB;AAC5B,WAAO;AACP,QAAI,UAAU,GAAG;AACf,gBAAU;AACV,aAAO;AAAA,IACT;AAEA,UAAM,eAAe,IAAI;AACzB,WAAO,KAAK,KAAK,eAAe,UAAU;AAAA,EAC5C;AAKA,iBAAe,eAA8B;AAC3C,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,QAAQ,MAAM;AAClB,cAAM,WAAW,WAAW;AAC5B,YAAI,aAAa,GAAG;AAClB,kBAAQ;AAAA,QACV,OAAO;AACL,oBAAU,KAAK,KAAK;AACpB,qBAAW,MAAM;AACf,kBAAM,MAAM,UAAU,QAAQ,KAAK;AACnC,gBAAI,QAAQ,IAAI;AACd,wBAAU,OAAO,KAAK,CAAC;AACvB,oBAAM;AAAA,YACR;AAAA,UACF,GAAG,QAAQ;AAAA,QACb;AAAA,MACF;AACA,YAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,MAAM,QAAW,WAA6C;AAC5D,YAAM,WAAW,WAAW;AAE5B,UAAI,WAAW,GAAG;AAChB,YAAI,aAAa,UAAU;AACzB,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN,aAAa;AAAA,YACb,cAAc;AAAA,UAChB;AAAA,QACF;AAGA,cAAM,aAAa;AAAA,MACrB;AAEA,aAAO,UAAU;AAAA,IACnB;AAAA,IAEA,MAAM,cACJ,WAC4C;AAC5C,YAAM,WAAW,WAAW;AAE5B,UAAI,WAAW,GAAG;AAChB,YAAI,aAAa,UAAU;AACzB,iBAAOC,KAAI;AAAA,YACT,MAAM;AAAA,YACN,aAAa;AAAA,YACb,cAAc;AAAA,UAChB,CAAC;AAAA,QACH;AAGA,cAAM,aAAa;AAAA,MACrB;AAEA,aAAO,UAAU;AAAA,IACnB;AAAA,IAEA,WAA6B;AAC3B,aAAO;AACP,aAAO;AAAA,QACL,iBAAiB,KAAK,MAAM,MAAM;AAAA,QAClC;AAAA,QACA,iBAAiB;AAAA,QACjB,cAAc,UAAU;AAAA,MAC1B;AAAA,IACF;AAAA,IAEA,QAAc;AACZ,eAAS;AACT,mBAAa,KAAK,IAAI;AAEtB,gBAAU,SAAS;AAAA,IACrB;AAAA,EACF;AACF;AA6DO,SAAS,yBACd,MACA,QACoB;AACpB,QAAM,EAAE,eAAe,WAAW,SAAS,eAAe,SAAS,IAAI;AAEvE,MAAI,cAAc;AAClB,QAAM,QAAsE,CAAC;AAK7E,iBAAe,UAAyB;AACtC,QAAI,cAAc,eAAe;AAC/B;AACA;AAAA,IACF;AAEA,QAAI,aAAa,UAAU;AACzB,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,aAAa;AAAA,QACb,WAAW,MAAM;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAGA,QAAI,MAAM,UAAU,cAAc;AAChC,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,aAAa;AAAA,QACb,WAAW,MAAM;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAEA,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,YAAM,KAAK,EAAE,SAAS,OAAO,CAAC;AAAA,IAChC,CAAC;AAAA,EACH;AAKA,WAAS,UAAgB;AACvB;AACA,QAAI,MAAM,SAAS,KAAK,cAAc,eAAe;AACnD;AACA,YAAM,OAAO,MAAM,MAAM;AACzB,YAAM,QAAQ;AAAA,IAChB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,QAAW,WAA6C;AAC5D,YAAM,QAAQ;AACd,UAAI;AACF,eAAO,MAAM,UAAU;AAAA,MACzB,UAAE;AACA,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,IAEA,MAAM,WAAc,YAAuD;AACzE,YAAM,UAAe,IAAI,MAAM,WAAW,MAAM;AAChD,YAAM,YAA6B,CAAC;AAEpC,eAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,cAAM,QAAQ;AACd,cAAM,UAAU,KAAK,QAAQ,WAAW,KAAK,CAAC,EAAE,KAAK,CAAC,WAAW;AAC/D,kBAAQ,KAAK,IAAI;AAAA,QACnB,CAAC;AACD,kBAAU,KAAK,OAAO;AAAA,MACxB;AAEA,YAAM,QAAQ,IAAI,SAAS;AAC3B,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,cACJ,WACoC;AACpC,UAAI;AACF,cAAM,QAAQ;AAAA,MAChB,SAAS,OAAO;AACd,YAAI,iBAAiB,KAAK,GAAG;AAC3B,iBAAOA,KAAI,KAAK;AAAA,QAClB;AACA,cAAM;AAAA,MACR;AAEA,UAAI;AACF,eAAO,MAAM,UAAU;AAAA,MACzB,UAAE;AACA,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,IAEA,WAAoC;AAClC,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,WAAW,MAAM;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAAA,IAEA,QAAc;AACZ,oBAAc;AAEd,aAAO,MAAM,SAAS,GAAG;AACvB,cAAM,OAAO,MAAM,MAAM;AACzB,cAAM,OAAO,IAAI,MAAM,eAAe,CAAC;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AACF;AAwCO,SAAS,sBACd,MACA,QAKA;AACA,QAAM,OAAO,OAAO,OAAO,kBAAkB,GAAG,IAAI,SAAS,OAAO,IAAI,IAAI;AAC5E,QAAM,cAAc,OAAO,cACvB,yBAAyB,GAAG,IAAI,gBAAgB,OAAO,WAAW,IAClE;AAEJ,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IAEA,MAAM,QAAW,WAA6C;AAE5D,UAAI,KAAK;AACT,UAAI,MAAM;AACR,cAAM,aAAa;AACnB,aAAK,MAAM,KAAK,QAAQ,UAAU;AAAA,MACpC;AAGA,UAAI,aAAa;AACf,eAAO,YAAY,QAAQ,EAAE;AAAA,MAC/B;AAEA,aAAO,GAAG;AAAA,IACZ;AAAA,EACF;AACF;AAuGO,SAAS,yBACd,MACA,QACoB;AACpB,QAAM,EAAE,OAAO,WAAW,KAAM,WAAW,OAAO,IAAI;AAEtD,MAAI,cAAc,KAAK,IAAI;AAC3B,MAAI,eAAe;AACnB,QAAM,YAA0D,CAAC;AAKjE,WAAS,cAAsB;AAC7B,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,UAAU,MAAM;AAEtB,QAAI,WAAW,UAAU;AAEvB,oBAAc;AACd,qBAAe;AACf,aAAO;AAAA,IACT;AAEA,WAAO,WAAW;AAAA,EACpB;AAMA,WAAS,WAAW,MAAsB;AACxC,UAAM,cAAc,YAAY;AAEhC,QAAI,eAAe,QAAQ,OAAO;AAChC,sBAAgB;AAChB,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAKA,iBAAe,cAAc,MAA6B;AACxD,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,QAAQ,MAAM;AAClB,cAAM,WAAW,WAAW,IAAI;AAChC,YAAI,aAAa,GAAG;AAClB,kBAAQ;AAAA,QACV,OAAO;AACL,oBAAU,KAAK,EAAE,SAAS,OAAO,KAAK,CAAC;AACvC,qBAAW,MAAM;AACf,kBAAM,MAAM,UAAU,UAAU,CAAC,MAAM,EAAE,YAAY,KAAK;AAC1D,gBAAI,QAAQ,IAAI;AACd,wBAAU,OAAO,KAAK,CAAC;AACvB,oBAAM;AAAA,YACR;AAAA,UACF,GAAG,QAAQ;AAAA,QACb;AAAA,MACF;AACA,YAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,MAAM,QAAW,WAAiC,OAAO,GAAe;AAEtE,UAAI,OAAO,OAAO;AAChB,cAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,cAAc;AAAA,QAChB;AAAA,MACF;AAEA,YAAM,WAAW,WAAW,IAAI;AAEhC,UAAI,WAAW,GAAG;AAChB,YAAI,aAAa,UAAU;AACzB,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN,aAAa;AAAA,YACb,cAAc;AAAA,UAChB;AAAA,QACF;AAEA,cAAM,cAAc,IAAI;AAAA,MAC1B;AAEA,aAAO,UAAU;AAAA,IACnB;AAAA,IAEA,MAAM,cACJ,WACA,OAAO,GACqC;AAE5C,UAAI,OAAO,OAAO;AAChB,eAAOA,KAAI;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,UACb,cAAc;AAAA,QAChB,CAAC;AAAA,MACH;AAEA,YAAM,WAAW,WAAW,IAAI;AAEhC,UAAI,WAAW,GAAG;AAChB,YAAI,aAAa,UAAU;AACzB,iBAAOA,KAAI;AAAA,YACT,MAAM;AAAA,YACN,aAAa;AAAA,YACb,cAAc;AAAA,UAChB,CAAC;AAAA,QACH;AAEA,cAAM,cAAc,IAAI;AAAA,MAC1B;AAEA,aAAO,UAAU;AAAA,IACnB;AAAA,IAEA,WAAoC;AAClC,YAAM,cAAc,YAAY;AAChC,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,UAAU;AAAA,MAC1B;AAAA,IACF;AAAA,IAEA,QAAc;AACZ,oBAAc,KAAK,IAAI;AACvB,qBAAe;AACf,gBAAU,SAAS;AAAA,IACrB;AAAA,EACF;AACF;AAyGO,SAAS,2BACd,MACA,QACsB;AACtB,QAAM,EAAE,iBAAiB,WAAW,OAAO,IAAI;AAC/C,QAAM,YAAY,OAAO,aAAa,kBAAkB;AAExD,MAAI,SAAS;AACb,MAAI,aAAa,KAAK,IAAI;AAC1B,QAAM,aAAa,kBAAkB;AAErC,QAAM,YAAwD,CAAC;AAK/D,WAAS,SAAe;AACtB,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,UAAU,MAAM;AACtB,UAAM,cAAc,UAAU;AAC9B,aAAS,KAAK,IAAI,WAAW,SAAS,WAAW;AACjD,iBAAa;AAAA,EACf;AAMA,WAAS,WAAW,MAAsB;AACxC,WAAO;AACP,QAAI,UAAU,MAAM;AAClB,gBAAU;AACV,aAAO;AAAA,IACT;AAEA,UAAM,eAAe,OAAO;AAC5B,WAAO,KAAK,KAAK,eAAe,UAAU;AAAA,EAC5C;AAKA,iBAAe,cAAc,MAA6B;AACxD,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,QAAQ,MAAM;AAClB,cAAM,WAAW,WAAW,IAAI;AAChC,YAAI,aAAa,GAAG;AAClB,kBAAQ;AAAA,QACV,OAAO;AACL,oBAAU,KAAK,EAAE,OAAO,KAAK,CAAC;AAC9B,qBAAW,MAAM;AACf,kBAAM,MAAM,UAAU,UAAU,CAAC,MAAM,EAAE,UAAU,KAAK;AACxD,gBAAI,QAAQ,IAAI;AACd,wBAAU,OAAO,KAAK,CAAC;AACvB,oBAAM;AAAA,YACR;AAAA,UACF,GAAG,QAAQ;AAAA,QACb;AAAA,MACF;AACA,YAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,MAAM,QAAW,WAAiC,OAAO,GAAe;AAEtE,UAAI,OAAO,WAAW;AACpB,cAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,UACb,cAAc,KAAK,KAAK,OAAO,UAAU;AAAA,QAC3C;AAAA,MACF;AAEA,YAAM,WAAW,WAAW,IAAI;AAEhC,UAAI,WAAW,GAAG;AAChB,YAAI,aAAa,UAAU;AACzB,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN,aAAa;AAAA,YACb,cAAc;AAAA,UAChB;AAAA,QACF;AAEA,cAAM,cAAc,IAAI;AAAA,MAC1B;AAEA,aAAO,UAAU;AAAA,IACnB;AAAA,IAEA,MAAM,cACJ,WACA,OAAO,GACqC;AAE5C,UAAI,OAAO,WAAW;AACpB,eAAOA,KAAI;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,UACb,cAAc,KAAK,KAAK,OAAO,UAAU;AAAA,QAC3C,CAAC;AAAA,MACH;AAEA,YAAM,WAAW,WAAW,IAAI;AAEhC,UAAI,WAAW,GAAG;AAChB,YAAI,aAAa,UAAU;AACzB,iBAAOA,KAAI;AAAA,YACT,MAAM;AAAA,YACN,aAAa;AAAA,YACb,cAAc;AAAA,UAChB,CAAC;AAAA,QACH;AAEA,cAAM,cAAc,IAAI;AAAA,MAC1B;AAEA,aAAO,UAAU;AAAA,IACnB;AAAA,IAEA,WAAsC;AACpC,aAAO;AACP,aAAO;AAAA,QACL,iBAAiB;AAAA,QACjB;AAAA,QACA;AAAA,QACA,cAAc,UAAU;AAAA,MAC1B;AAAA,IACF;AAAA,IAEA,QAAc;AACZ,eAAS;AACT,mBAAa,KAAK,IAAI;AACtB,gBAAU,SAAS;AAAA,IACrB;AAAA,EACF;AACF;AASO,IAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA,EAIhC,KAAK;AAAA,IACH,cAAc;AAAA,IACd,eAAe;AAAA,IACf,UAAU;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AAAA,IACR,eAAe;AAAA,IACf,UAAU;AAAA,IACV,cAAc;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AAAA,IACR,cAAc;AAAA,IACd,eAAe;AAAA,IACf,UAAU;AAAA,EACZ;AACF;;;AC3+BA,SAASC,MAAK,UAAiC;AAC7C,MAAI,OAAO,aAAa,UAAU;AAChC,UAAM,SAAS,MAAc,QAAQ;AACrC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,4BAA4B,QAAQ,EAAE;AAAA,IACxD;AACA,WAAO,OAAO;AAAA,EAChB;AACA,SAAO,SAAS;AAClB;AAsCO,SAAS,OAAU,IAA4C;AACpE,MAAI,QAAwB,EAAE,QAAQ,QAAQ;AAE9C,SAAO,YAAY;AACjB,QAAI,MAAM,WAAW,UAAU;AAC7B,aAAO,MAAM;AAAA,IACf;AAEA,QAAI,MAAM,WAAW,WAAW;AAC9B,aAAO,MAAM;AAAA,IACf;AAGA,UAAM,UAAU,QAAQ,QAAQ,GAAG,CAAC,EAAE,KAAK,CAAC,UAAU;AACpD,cAAQ,EAAE,QAAQ,UAAU,MAAM;AAClC,aAAO;AAAA,IACT,CAAC;AAED,YAAQ,EAAE,QAAQ,WAAW,QAAQ;AACrC,WAAO;AAAA,EACT;AACF;AAsCO,SAAS,cACd,IACA,SACkB;AAClB,QAAM,QAAQA,MAAK,QAAQ,GAAG;AAC9B,MAAI,QAA2B,EAAE,QAAQ,QAAQ;AAEjD,SAAO,YAAY;AACjB,UAAM,MAAM,KAAK,IAAI;AAGrB,QAAI,MAAM,WAAW,YAAY,MAAM,MAAM,WAAW;AACtD,aAAO,MAAM;AAAA,IACf;AAGA,QAAI,MAAM,WAAW,WAAW;AAC9B,aAAO,MAAM;AAAA,IACf;AAGA,UAAM,UAAU,QAAQ,QAAQ,GAAG,CAAC,EAAE,KAAK,CAAC,UAAU;AACpD,cAAQ;AAAA,QACN,QAAQ;AAAA,QACR;AAAA,QACA,WAAW,KAAK,IAAI,IAAI;AAAA,MAC1B;AACA,aAAO;AAAA,IACT,CAAC;AAED,YAAQ,EAAE,QAAQ,WAAW,QAAQ;AACrC,WAAO;AAAA,EACT;AACF;AAyDO,SAAS,eACd,IACA,UAAuC,CAAC,GACb;AAC3B,QAAM;AAAA,IACJ,QAAQ,IAAI,SAAe,KAAK,UAAU,IAAI;AAAA,IAC9C,UAAU;AAAA,EACZ,IAAI;AACJ,QAAM,QAAQ,QAAQ,MAAMA,MAAK,QAAQ,GAAG,IAAI;AAEhD,QAAM,QAAQ,oBAAI,IAA0B;AAC5C,QAAM,UAAU,oBAAI,IAAwB;AAC5C,MAAI,OAAO;AACX,MAAI,SAAS;AAKb,WAAS,cAAoB;AAC3B,QAAI,MAAM,QAAQ,QAAS;AAG3B,QAAI,YAA2B;AAC/B,QAAI,aAAa;AAEjB,eAAW,CAAC,KAAK,KAAK,KAAK,MAAM,QAAQ,GAAG;AAC1C,UAAI,MAAM,YAAY,YAAY;AAChC,qBAAa,MAAM;AACnB,oBAAY;AAAA,MACd;AAAA,IACF;AAEA,QAAI,WAAW;AACb,YAAM,OAAO,SAAS;AAAA,IACxB;AAAA,EACF;AAEA,QAAM,WAAW,UAAU,SAA2B;AACpD,UAAM,MAAM,MAAM,GAAG,IAAI;AACzB,UAAM,MAAM,KAAK,IAAI;AAGrB,UAAMC,UAAS,MAAM,IAAI,GAAG;AAC5B,QAAIA,SAAQ;AAEV,UAAIA,QAAO,aAAa,OAAOA,QAAO,WAAW;AAC/C,cAAM,OAAO,GAAG;AAAA,MAClB,OAAO;AACL;AACA,eAAOA,QAAO;AAAA,MAChB;AAAA,IACF;AAGA,UAAM,iBAAiB,QAAQ,IAAI,GAAG;AACtC,QAAI,gBAAgB;AAClB,aAAO;AAAA,IACT;AAGA;AACA,UAAM,UAAU,QAAQ,QAAQ,GAAG,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,UAAU;AAC3D,YAAM,QAAsB;AAAA,QAC1B;AAAA,QACA,WAAW,KAAK,IAAI;AAAA,QACpB,WAAW,QAAQ,KAAK,IAAI,IAAI,QAAQ;AAAA,MAC1C;AACA,YAAM,IAAI,KAAK,KAAK;AACpB,cAAQ,OAAO,GAAG;AAClB,kBAAY;AACZ,aAAO;AAAA,IACT,CAAC;AAED,YAAQ,IAAI,KAAK,OAAO;AAExB,QAAI;AACF,aAAO,MAAM;AAAA,IACf,SAAS,OAAO;AACd,cAAQ,OAAO,GAAG;AAClB,YAAM;AAAA,IACR;AAAA,EACF;AAEA,WAAS,QAAQ,MAAM;AACrB,UAAM,MAAM;AACZ,YAAQ,MAAM;AAAA,EAChB;AAEA,WAAS,SAAS,IAAI,SAAe;AACnC,UAAM,MAAM,MAAM,GAAG,IAAI;AACzB,WAAO,MAAM,OAAO,GAAG;AAAA,EACzB;AAEA,WAAS,MAAM,IAAI,SAAe;AAChC,UAAM,MAAM,MAAM,GAAG,IAAI;AACzB,UAAM,QAAQ,MAAM,IAAI,GAAG;AAC3B,QAAI,CAAC,MAAO,QAAO;AACnB,QAAI,MAAM,aAAa,KAAK,IAAI,KAAK,MAAM,WAAW;AACpD,YAAM,OAAO,GAAG;AAChB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,WAAS,WAAW,OAAO;AAAA,IACzB;AAAA,IACA;AAAA,IACA,MAAM,MAAM;AAAA,EACd;AAEA,SAAO;AACT;AA0DO,SAAS,KAAQ,IAA2C;AACjE,MAAI,QAAsB,EAAE,QAAQ,OAAO;AAE3C,QAAM,SAAS,YAAwB;AACrC,QAAI,MAAM,WAAW,QAAQ;AAC3B,aAAO,MAAM;AAAA,IACf;AAEA,QAAI,MAAM,WAAW,UAAU;AAC7B,YAAM,MAAM;AAAA,IACd;AAEA,QAAI,MAAM,WAAW,WAAW;AAC9B,aAAO,MAAM;AAAA,IACf;AAGA,UAAM,UAAU,QAAQ,QAAQ,GAAG,CAAC,EACjC,KAAK,CAAC,UAAU;AACf,cAAQ,EAAE,QAAQ,QAAQ,MAAM;AAChC,aAAO;AAAA,IACT,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,cAAQ,EAAE,QAAQ,UAAU,MAAM;AAClC,YAAM;AAAA,IACR,CAAC;AAEH,YAAQ,EAAE,QAAQ,WAAW,QAAQ;AACrC,WAAO;AAAA,EACT;AAEA,SAAO,eAAe,QAAQ,UAAU;AAAA,IACtC,KAAK,MAAM,MAAM,WAAW;AAAA,EAC9B,CAAC;AAED,SAAO,eAAe,QAAQ,aAAa;AAAA,IACzC,KAAK,MAAM,MAAM,WAAW;AAAA,EAC9B,CAAC;AAED,SAAO,eAAe,QAAQ,UAAU;AAAA,IACtC,KAAK,MAAM,MAAM,WAAW;AAAA,EAC9B,CAAC;AAED,SAAO,QAAQ,MAAM;AACnB,YAAQ,EAAE,QAAQ,OAAO;AAAA,EAC3B;AAEA,SAAO;AACT;AA6DO,SAAS,YAAkB,SAAsB,CAAC,GAAgB;AACvE,QAAM,EAAE,UAAU,SAAS,IAAI;AAC/B,QAAM,eAAe,OAAO,aAAaD,MAAK,OAAO,UAAU,IAAI;AAQnE,QAAM,QAAQ,oBAAI,IAAc;AAChC,MAAI,OAAO;AACX,MAAI,SAAS;AAKb,WAAS,UAAU,OAAuB;AACxC,WAAO,MAAM,cAAc,UAAa,KAAK,IAAI,KAAK,MAAM;AAAA,EAC9D;AAKA,WAAS,cAAoB;AAC3B,QAAI,MAAM,QAAQ,QAAS;AAE3B,QAAI,YAAsB;AAC1B,QAAI,aAAa;AAEjB,eAAW,CAAC,KAAK,KAAK,KAAK,MAAM,QAAQ,GAAG;AAC1C,UAAI,MAAM,YAAY,YAAY;AAChC,qBAAa,MAAM;AACnB,oBAAY;AAAA,MACd;AAAA,IACF;AAEA,QAAI,cAAc,MAAM;AACtB,YAAM,OAAO,SAAS;AAAA,IACxB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI,KAAuB;AACzB,YAAM,QAAQ,MAAM,IAAI,GAAG;AAC3B,UAAI,CAAC,OAAO;AACV;AACA,eAAO;AAAA,MACT;AACA,UAAI,UAAU,KAAK,GAAG;AACpB,cAAM,OAAO,GAAG;AAChB;AACA,eAAO;AAAA,MACT;AACA;AACA,aAAO,MAAM;AAAA,IACf;AAAA,IAEA,IAAI,KAAQ,OAAU,SAAyC;AAC7D,YAAM,QAAQ,SAAS,MAAMA,MAAK,QAAQ,GAAG,IAAI;AACjD,YAAM,MAAM,KAAK,IAAI;AAErB,YAAM,IAAI,KAAK;AAAA,QACb;AAAA,QACA,WAAW;AAAA,QACX,WAAW,QAAQ,MAAM,QAAQ;AAAA,MACnC,CAAC;AAED,kBAAY;AAAA,IACd;AAAA,IAEA,IAAI,KAAiB;AACnB,YAAM,QAAQ,MAAM,IAAI,GAAG;AAC3B,UAAI,CAAC,MAAO,QAAO;AACnB,UAAI,UAAU,KAAK,GAAG;AACpB,cAAM,OAAO,GAAG;AAChB,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,IAEA,OAAO,KAAiB;AACtB,aAAO,MAAM,OAAO,GAAG;AAAA,IACzB;AAAA,IAEA,QAAc;AACZ,YAAM,MAAM;AAAA,IACd;AAAA,IAEA,IAAI,OAAe;AACjB,aAAO,MAAM;AAAA,IACf;AAAA,IAEA,WAAuB;AACrB,aAAO,EAAE,MAAM,QAAQ,MAAM,MAAM,KAAK;AAAA,IAC1C;AAAA,EACF;AACF;;;ACtiBO,SAAS,aACd,WACA,SACyC;AAEzC,QAAM,WAAW,oBAAI,IAAsC;AAG3D,QAAM,QAAQ,QAAQ,MAAM,oBAAI,IAAiC,IAAI;AAErE,SAAO,UAAU,SAAqC;AACpD,UAAM,MAAM,QAAQ,IAAI,GAAG,IAAI;AAG/B,QAAI,OAAO;AACT,YAAME,UAAS,MAAM,IAAI,GAAG;AAC5B,UAAIA,WAAUA,QAAO,YAAY,KAAK,IAAI,GAAG;AAC3C,eAAOA,QAAO;AAAA,MAChB;AAEA,UAAIA,SAAQ;AACV,cAAM,OAAO,GAAG;AAAA,MAClB;AAAA,IACF;AAGA,UAAM,WAAW,SAAS,IAAI,GAAG;AACjC,QAAI,UAAU;AACZ,aAAO;AAAA,IACT;AAIA,UAAM,UAAU,UAAU,GAAG,IAAI,EAC9B,KAAK,CAAC,WAAW;AAEhB,UAAI,SAAS,QAAQ,OAAO,OAAO,IAAI;AACrC,cAAM,IAAI,KAAK;AAAA,UACb;AAAA,UACA,WAAW,KAAK,IAAI,IAAI,QAAQ;AAAA,QAClC,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT,CAAC,EACA,QAAQ,MAAM;AAEb,eAAS,OAAO,GAAG;AAAA,IACrB,CAAC;AAEH,aAAS,IAAI,KAAK,OAAO;AACzB,WAAO;AAAA,EACT;AACF;AA2BO,SAAS,0BAuBd;AACA,QAAM,WAAW,oBAAI,IAAsC;AAE3D,SAAO;AAAA,IACL,SAAS,OACP,KACA,cACyB;AAEzB,YAAM,WAAW,SAAS,IAAI,GAAG;AACjC,UAAI,UAAU;AACZ,eAAO;AAAA,MACT;AAIA,YAAM,UAAU,UAAU,EACvB,KAAK,CAAC,WAAW,MAAM,EACvB,QAAQ,MAAM;AACb,iBAAS,OAAO,GAAG;AAAA,MACrB,CAAC;AAEH,eAAS,IAAI,KAAK,OAAO;AACzB,aAAO;AAAA,IACT;AAAA,IAEA,YAAY,CAAC,QAAgB,SAAS,IAAI,GAAG;AAAA,IAE7C,MAAM,MAAM,SAAS;AAAA,IAErB,OAAO,MAAM,SAAS,MAAM;AAAA,EAC9B;AACF;;;ACjMO,SAAS,iBAAiB,UAAiC;AAChE,QAAM,SAAsB,CAAC;AAE7B,aAAW,UAAU,UAAU;AAC7B,QAAI,OAAO,QAAQ,OAAW,QAAO,MAAM,OAAO;AAGlD,QAAI,OAAO,UAAU,QAAW;AAC9B,aAAO,QAAQ,OAAO,QAClB,EAAE,GAAG,OAAO,OAAO,GAAG,OAAO,MAAM,IACnC,EAAE,GAAG,OAAO,MAAM;AAAA,IACxB;AAGA,QAAI,OAAO,YAAY,QAAW;AAChC,aAAO,UAAU,OAAO,UACpB,EAAE,GAAG,OAAO,SAAS,GAAG,OAAO,QAAQ,IACvC,EAAE,GAAG,OAAO,QAAQ;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO;AACT;AAuBO,SAAS,uBACX,cACyC;AAC5C,QAAM,aAAa,cAAc,GAAG,YAAY;AAEhD,SAAO,CAACC,iBAA2C;AACjD,UAAM,OAAOA,gBAAe,CAAC;AAC7B,WAAO,cAAc,YAAY,IAAI;AAAA,EACvC;AACF;AASO,SAAS,mBACd,SACG,UACU;AACb,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,cAAc,GAAG,QAAQ;AAAA,EACnC;AACF;AASO,SAAS,YAAY,SAA+B;AACzD,SAAO,EAAE,OAAO,QAAQ;AAC1B;AAKO,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA,EAI3B,MAAM,YAAY,EAAE,UAAU,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA,EAKjC,WAAW,YAAY;AAAA,IACrB,UAAU;AAAA,IACV,SAAS;AAAA,IACT,cAAc;AAAA,IACd,UAAU;AAAA,IACV,QAAQ;AAAA,EACV,CAAC;AAAA;AAAA;AAAA;AAAA,EAKD,UAAU,YAAY;AAAA,IACpB,UAAU;AAAA,IACV,SAAS;AAAA,IACT,cAAc;AAAA,IACd,UAAU;AAAA,IACV,QAAQ;AAAA,EACV,CAAC;AAAA;AAAA;AAAA;AAAA,EAKD,YAAY,YAAY;AAAA,IACtB,UAAU;AAAA,IACV,SAAS;AAAA,IACT,cAAc;AAAA,IACd,UAAU;AAAA,IACV,QAAQ;AAAA,EACV,CAAC;AAAA;AAAA;AAAA;AAAA,EAKD,OAAO,CAAC,UAAkB,YACxB,YAAY;AAAA,IACV;AAAA,IACA,SAAS;AAAA,IACT,cAAc;AAAA,IACd,QAAQ;AAAA,EACV,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,QAAQ,CAAC,UAAkB,iBACzB,YAAY;AAAA,IACV;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,QAAQ;AAAA,EACV,CAAC;AAAA;AAAA;AAAA;AAAA,EAKH,QAAQ,CAAC,YACP,YAAY;AAAA,IACV,SAAS;AAAA,IACT,cAAc;AAAA,IACd,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,GAAG;AAAA,EACL,CAAC;AACL;AASO,SAAS,cAAc,SAAiC;AAC7D,SAAO,EAAE,SAAS,QAAQ;AAC5B;AAKO,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA,EAI7B,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA,EAKP,MAAM,cAAc,EAAE,IAAI,IAAK,CAAC;AAAA;AAAA;AAAA;AAAA,EAKhC,KAAK,cAAc,EAAE,IAAI,IAAK,CAAC;AAAA;AAAA;AAAA;AAAA,EAK/B,UAAU,cAAc,EAAE,IAAI,IAAM,CAAC;AAAA;AAAA;AAAA;AAAA,EAKrC,MAAM,cAAc,EAAE,IAAI,KAAO,CAAC;AAAA;AAAA;AAAA;AAAA,EAKlC,IAAI,CAAC,OAAuB,cAAc,EAAE,GAAG,CAAC;AAAA;AAAA;AAAA;AAAA,EAKhD,SAAS,CAACC,aAA4B,cAAc,EAAE,IAAIA,WAAU,IAAK,CAAC;AAAA;AAAA;AAAA;AAAA,EAK1E,WAAW,CAAI,IAAY,UACzB,cAAc,EAAE,IAAI,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA,EAK7B,YAAY,CAAC,OACX,cAAc,EAAE,IAAI,QAAQ,KAAK,CAAC;AACtC;AASO,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM7B,SAAS;AAAA,IACP,gBAAgB;AAAA,IAChB,cAAc;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAU;AAAA,IACR,gBAAgB;AAAA,IAChB,YAAY;AAAA,MACV,UAAU;AAAA,MACV,SAAS;AAAA,MACT,cAAc;AAAA,MACd,UAAU;AAAA,MACV,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO;AAAA,IACL,gBAAgB;AAAA,IAChB,cAAc;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,cAAc;AAAA,IACZ,gBAAgB;AAAA,IAChB,cAAc;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY;AAAA,IACV,gBAAgB;AAAA,IAChB,cAAc;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa;AAAA,IACX,cAAc,EAAE,IAAI,IAAM,CAAC;AAAA,IAC3B,YAAY;AAAA,MACV,UAAU;AAAA,MACV,SAAS;AAAA,MACT,cAAc;AAAA,MACd,UAAU;AAAA,MACV,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AACF;AAqCO,SAAS,WACd,QACAD,cACa;AACb,QAAM,OAAOA,gBAAe,CAAC;AAC7B,SAAO,cAAc,QAAQ,IAAI;AACnC;AAkBO,SAAS,aACd,UACAA,cACa;AACb,QAAM,OAAOA,gBAAe,CAAC;AAC7B,SAAO,cAAc,GAAG,UAAU,IAAI;AACxC;AAuBO,SAAS,kBACd,WACA,QACA,aAAqB,CAAC,GACd;AACR,SAAO,YAAY,SAAS;AAC9B;AAmBO,SAAS,UACd,aACA,aAAqB,QAAQ,IAAI,YAAY,eAC7C,gBAAwB,CAAC,GACjB;AACR,SAAO,YAAY,UAAU,KAAK;AACpC;AAyDO,SAAS,uBAAuC;AACrD,QAAM,WAAW,oBAAI,IAAoB;AAEzC,SAAO;AAAA,IACL,SAAS,MAAc,QAAsB;AAC3C,eAAS,IAAI,MAAM,MAAM;AAAA,IAC3B;AAAA,IAEA,IAAI,MAAkC;AACpC,aAAO,SAAS,IAAI,IAAI;AAAA,IAC1B;AAAA,IAEA,IAAI,MAAuB;AACzB,aAAO,SAAS,IAAI,IAAI;AAAA,IAC1B;AAAA,IAEA,QAAkB;AAChB,aAAO,MAAM,KAAK,SAAS,KAAK,CAAC;AAAA,IACnC;AAAA,IAEA,MAAM,YAAoBA,cAAwC;AAChE,YAAM,SAAS,SAAS,IAAI,UAAU;AACtC,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI,MAAM,qBAAqB,UAAU,EAAE;AAAA,MACnD;AACA,aAAO,WAAW,QAAQA,YAAW;AAAA,IACvC;AAAA,EACF;AACF;AAyDO,SAAS,cAAkC;AAChD,QAAM,WAAqB,CAAC;AAE5B,QAAM,UAA8B;AAAA,IAClC,IAAI,KAAa;AACf,eAAS,KAAK,EAAE,IAAI,CAAC;AACrB,aAAO;AAAA,IACT;AAAA,IAEA,OAAO,QAAgB;AACrB,eAAS,KAAK,MAAM;AACpB,aAAO;AAAA,IACT;AAAA,IAEA,QAAQ,IAAY;AAClB,eAAS,KAAK,cAAc,EAAE,GAAG,CAAC,CAAC;AACnC,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,SAAuB;AAC3B,eAAS,KAAK,YAAY,OAAO,CAAC;AAClC,aAAO;AAAA,IACT;AAAA,IAEA,QAAQ,UAAkB;AACxB,eAAS,KAAK,cAAc,OAAO,EAAE,SAAS,CAAC,CAAC;AAChD,aAAO;AAAA,IACT;AAAA,IAEA,QAAqB;AACnB,aAAO,cAAc,GAAG,QAAQ;AAAA,IAClC;AAAA,EACF;AAEA,SAAO;AACT;;;ACpkBA,SAAS,qBAA6B;AACpC,SAAO,YAAY,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AACzE;AAMA,SAAS,YACP,KACA,SACA,YACM;AACN,MAAI,CAAC,KAAK,QAAS;AAGnB,QAAM,QAAmC;AAAA,IACvC,MAAM;AAAA,IACN,YAAY,IAAI;AAAA,IAChB,SAAS,SAAS;AAAA,IAClB,MAAM,SAAS;AAAA,IACf,QAAQ,SAAS;AAAA,IACjB;AAAA,IACA,IAAI,KAAK,IAAI;AAAA,EACf;AAKA,QAAM,mBACJ,MAAM,YAAY,UAAa,IAAI,YAAY,SAC3C,QACC,EAAE,GAAG,OAAO,SAAS,IAAI,QAAQ;AAExC,MAAI,QAAQ,gBAAgB;AAC9B;AAoDO,SAASE,MACd,WACA,WACA,SACA,KAC2B;AAC3B,MAAI,WAAW;AACb,WAAO,UAAU;AAAA,EACnB;AAEA,QAAM,aAAa,mBAAmB;AACtC,cAAY,KAAK,SAAS,UAAU;AACpC,SAAO;AACT;AA+CO,SAAS,OACd,WACA,WACA,SACA,KAC2B;AAC3B,SAAOA,MAAK,CAAC,WAAW,WAAW,SAAS,GAAG;AACjD;AAmDO,SAAS,OACd,WACA,WACA,cACA,SACA,KACmB;AACnB,MAAI,WAAW;AACb,WAAO,UAAU;AAAA,EACnB;AAEA,QAAM,aAAa,mBAAmB;AACtC,cAAY,KAAK,SAAS,UAAU;AACpC,SAAO;AACT;AAmDO,SAAS,SACd,WACA,WACA,cACA,SACA,KACmB;AACnB,SAAO,OAAO,CAAC,WAAW,WAAW,cAAc,SAAS,GAAG;AACjE;AA0CO,SAAS,yBAAsC,KAA4B;AAChF,SAAO;AAAA;AAAA;AAAA;AAAA,IAIL,MAAM,CACJ,WACA,WACA,YAC8BA,MAAK,WAAW,WAAW,SAAS,GAAG;AAAA;AAAA;AAAA;AAAA,IAKvE,QAAQ,CACN,WACA,WACA,YAC8B,OAAO,WAAW,WAAW,SAAS,GAAG;AAAA;AAAA;AAAA;AAAA,IAKzE,QAAQ,CACN,WACA,WACA,cACA,YACsB,OAAO,WAAW,WAAW,cAAc,SAAS,GAAG;AAAA;AAAA;AAAA;AAAA,IAK/E,UAAU,CACR,WACA,WACA,cACA,YACsB,SAAS,WAAW,WAAW,cAAc,SAAS,GAAG;AAAA,EACnF;AACF;","names":["orElse","tags","when","tag","TaggedError","match","tag","fallback","h","days","hours","minutes","seconds","millis","match","match","ok","err","tag","tags","err","sleep","normalizeParallelOperations","value","executeParallelArray","executeParallelNamed","options","err","stepOptions","sleep","ok","totalDurationMs","fn","allAsync","durationMs","wrappedError","allAsync","ok","err","tags","orElse","err","err","toMs","cached","cached","stepOptions","seconds","when"]}