@databehave/server 0.1.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 (162) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/LICENSE +21 -0
  3. package/README.md +87 -0
  4. package/dist/admin/admin-routes.d.ts +42 -0
  5. package/dist/admin/admin-routes.d.ts.map +1 -0
  6. package/dist/admin/admin-routes.js +472 -0
  7. package/dist/admin/admin-routes.js.map +1 -0
  8. package/dist/admin/admin-types.d.ts +170 -0
  9. package/dist/admin/admin-types.d.ts.map +1 -0
  10. package/dist/admin/admin-types.js +30 -0
  11. package/dist/admin/admin-types.js.map +1 -0
  12. package/dist/admin/banner.d.ts +11 -0
  13. package/dist/admin/banner.d.ts.map +1 -0
  14. package/dist/admin/banner.js +5 -0
  15. package/dist/admin/banner.js.map +1 -0
  16. package/dist/admin/header-parser.d.ts +14 -0
  17. package/dist/admin/header-parser.d.ts.map +1 -0
  18. package/dist/admin/header-parser.js +171 -0
  19. package/dist/admin/header-parser.js.map +1 -0
  20. package/dist/admin/inject.d.ts +48 -0
  21. package/dist/admin/inject.d.ts.map +1 -0
  22. package/dist/admin/inject.js +167 -0
  23. package/dist/admin/inject.js.map +1 -0
  24. package/dist/admin/overrides-store.d.ts +18 -0
  25. package/dist/admin/overrides-store.d.ts.map +1 -0
  26. package/dist/admin/overrides-store.js +100 -0
  27. package/dist/admin/overrides-store.js.map +1 -0
  28. package/dist/admin/resolve-cors.d.ts +22 -0
  29. package/dist/admin/resolve-cors.d.ts.map +1 -0
  30. package/dist/admin/resolve-cors.js +28 -0
  31. package/dist/admin/resolve-cors.js.map +1 -0
  32. package/dist/admin/scenarios-store.d.ts +15 -0
  33. package/dist/admin/scenarios-store.d.ts.map +1 -0
  34. package/dist/admin/scenarios-store.js +109 -0
  35. package/dist/admin/scenarios-store.js.map +1 -0
  36. package/dist/admin/ui.css +2 -0
  37. package/dist/admin/ui.html +13 -0
  38. package/dist/admin/ui.js +240 -0
  39. package/dist/bin-helpers.d.ts +46 -0
  40. package/dist/bin-helpers.d.ts.map +1 -0
  41. package/dist/bin-helpers.js +61 -0
  42. package/dist/bin-helpers.js.map +1 -0
  43. package/dist/bin.d.ts +3 -0
  44. package/dist/bin.d.ts.map +1 -0
  45. package/dist/bin.js +57 -0
  46. package/dist/bin.js.map +1 -0
  47. package/dist/cors.d.ts +57 -0
  48. package/dist/cors.d.ts.map +1 -0
  49. package/dist/cors.js +167 -0
  50. package/dist/cors.js.map +1 -0
  51. package/dist/define.d.ts +26 -0
  52. package/dist/define.d.ts.map +1 -0
  53. package/dist/define.js +55 -0
  54. package/dist/define.js.map +1 -0
  55. package/dist/index.d.ts +21 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +19 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/json-config.d.ts +170 -0
  60. package/dist/json-config.d.ts.map +1 -0
  61. package/dist/json-config.js +684 -0
  62. package/dist/json-config.js.map +1 -0
  63. package/dist/jsonc.d.ts +24 -0
  64. package/dist/jsonc.d.ts.map +1 -0
  65. package/dist/jsonc.js +125 -0
  66. package/dist/jsonc.js.map +1 -0
  67. package/dist/log.d.ts +57 -0
  68. package/dist/log.d.ts.map +1 -0
  69. package/dist/log.js +103 -0
  70. package/dist/log.js.map +1 -0
  71. package/dist/middleware/request-validation.d.ts +58 -0
  72. package/dist/middleware/request-validation.d.ts.map +1 -0
  73. package/dist/middleware/request-validation.js +328 -0
  74. package/dist/middleware/request-validation.js.map +1 -0
  75. package/dist/mock-mode.d.ts +95 -0
  76. package/dist/mock-mode.d.ts.map +1 -0
  77. package/dist/mock-mode.js +95 -0
  78. package/dist/mock-mode.js.map +1 -0
  79. package/dist/openapi/auto-schema.d.ts +83 -0
  80. package/dist/openapi/auto-schema.d.ts.map +1 -0
  81. package/dist/openapi/auto-schema.js +232 -0
  82. package/dist/openapi/auto-schema.js.map +1 -0
  83. package/dist/openapi/generate.d.ts +20 -0
  84. package/dist/openapi/generate.d.ts.map +1 -0
  85. package/dist/openapi/generate.js +121 -0
  86. package/dist/openapi/generate.js.map +1 -0
  87. package/dist/openapi/loader.d.ts +18 -0
  88. package/dist/openapi/loader.d.ts.map +1 -0
  89. package/dist/openapi/loader.js +25 -0
  90. package/dist/openapi/loader.js.map +1 -0
  91. package/dist/openapi/register.d.ts +58 -0
  92. package/dist/openapi/register.d.ts.map +1 -0
  93. package/dist/openapi/register.js +166 -0
  94. package/dist/openapi/register.js.map +1 -0
  95. package/dist/openapi/seed.d.ts +16 -0
  96. package/dist/openapi/seed.d.ts.map +1 -0
  97. package/dist/openapi/seed.js +58 -0
  98. package/dist/openapi/seed.js.map +1 -0
  99. package/dist/openapi/translate.d.ts +55 -0
  100. package/dist/openapi/translate.d.ts.map +1 -0
  101. package/dist/openapi/translate.js +319 -0
  102. package/dist/openapi/translate.js.map +1 -0
  103. package/dist/openapi/walker.d.ts +44 -0
  104. package/dist/openapi/walker.d.ts.map +1 -0
  105. package/dist/openapi/walker.js +15 -0
  106. package/dist/openapi/walker.js.map +1 -0
  107. package/dist/request.d.ts +19 -0
  108. package/dist/request.d.ts.map +1 -0
  109. package/dist/request.js +66 -0
  110. package/dist/request.js.map +1 -0
  111. package/dist/response.d.ts +13 -0
  112. package/dist/response.d.ts.map +1 -0
  113. package/dist/response.js +43 -0
  114. package/dist/response.js.map +1 -0
  115. package/dist/route-key.d.ts +60 -0
  116. package/dist/route-key.d.ts.map +1 -0
  117. package/dist/route-key.js +105 -0
  118. package/dist/route-key.js.map +1 -0
  119. package/dist/run.d.ts +27 -0
  120. package/dist/run.d.ts.map +1 -0
  121. package/dist/run.js +87 -0
  122. package/dist/run.js.map +1 -0
  123. package/dist/server.d.ts +60 -0
  124. package/dist/server.d.ts.map +1 -0
  125. package/dist/server.js +497 -0
  126. package/dist/server.js.map +1 -0
  127. package/dist/types.d.ts +274 -0
  128. package/dist/types.d.ts.map +1 -0
  129. package/dist/types.js +9 -0
  130. package/dist/types.js.map +1 -0
  131. package/dist/validation/validate.d.ts +38 -0
  132. package/dist/validation/validate.d.ts.map +1 -0
  133. package/dist/validation/validate.js +372 -0
  134. package/dist/validation/validate.js.map +1 -0
  135. package/docs/admin/error-mode.md +14 -0
  136. package/docs/admin/headers.md +63 -0
  137. package/docs/admin/index.md +111 -0
  138. package/docs/admin/overrides.md +23 -0
  139. package/docs/admin/rest-api.md +90 -0
  140. package/docs/admin/scenarios.md +28 -0
  141. package/docs/cli.md +76 -0
  142. package/docs/config/admin.md +62 -0
  143. package/docs/config/cors.md +72 -0
  144. package/docs/config/endpoints.md +162 -0
  145. package/docs/config/index.md +107 -0
  146. package/docs/config/log.md +43 -0
  147. package/docs/config/mock-mode.md +84 -0
  148. package/docs/config/openapi.md +8 -0
  149. package/docs/config/schema.md +34 -0
  150. package/docs/config/server.md +32 -0
  151. package/docs/config/validation.md +161 -0
  152. package/docs/design.md +517 -0
  153. package/docs/errors.md +192 -0
  154. package/docs/getting-started.md +146 -0
  155. package/docs/index.md +23 -0
  156. package/docs/openapi/auto-schema.md +146 -0
  157. package/docs/openapi/fallback.md +242 -0
  158. package/docs/openapi/keywords.md +78 -0
  159. package/docs/recipes.md +258 -0
  160. package/docs/stability.md +118 -0
  161. package/docs/troubleshooting.md +191 -0
  162. package/package.json +80 -0
@@ -0,0 +1,274 @@
1
+ /**
2
+ * Public types for @databehave/server.
3
+ *
4
+ * Everything a consumer needs to type a config and a handler is exported
5
+ * from here. Internal types (route table, dispatch result, etc.) stay
6
+ * inside their respective modules.
7
+ */
8
+ /** HTTP methods @databehave/server dispatches on. */
9
+ export type Method = 'get' | 'post' | 'put' | 'delete' | 'patch';
10
+ /**
11
+ * HTTP methods that may appear on a {@link MockRequest} but
12
+ * never on a route key. `options` is handled by the CORS preflight
13
+ * pipeline; `head` is allowed through but is never matched by a
14
+ * route (returns 404 by default).
15
+ */
16
+ export type ObservedMethod = Method | 'options' | 'head';
17
+ /**
18
+ * Config key shape: `'METHOD /absolute-path'`.
19
+ *
20
+ * Method is upper-case. Path must start with `/`. Path segments
21
+ * starting with `:` are dynamic parameters captured into
22
+ * `MockRequest.params` (e.g. `'GET /users/:id'`).
23
+ */
24
+ export type RouteKey = `${Uppercase<Method>} /${string}`;
25
+ /**
26
+ * Request facade for the mock framework. Hides the underlying web
27
+ * `Request` so handlers stay decoupled from the HTTP runtime.
28
+ *
29
+ * Named `MockRequest` (not `Request`) to avoid shadowing the Web
30
+ * Fetch `globalThis.Request` at consumer call sites.
31
+ */
32
+ export interface MockRequest {
33
+ readonly method: ObservedMethod;
34
+ /** Full URL as received. */
35
+ readonly url: string;
36
+ /** Pathname only, e.g. `/api/v1/foo`. */
37
+ readonly path: string;
38
+ /**
39
+ * Query parameters. Multi-valued keys keep only the last value here;
40
+ * use `queryAll` to get every value.
41
+ */
42
+ readonly query: Readonly<Record<string, string>>;
43
+ /** Every query value, indexed by key. */
44
+ readonly queryAll: Readonly<Record<string, readonly string[]>>;
45
+ /**
46
+ * Path parameters extracted by the matcher.
47
+ *
48
+ * E.g. a route `'GET /users/:id'` matched against `/users/42`
49
+ * yields `{ id: '42' }`. Empty for routes without `:` segments.
50
+ */
51
+ readonly params: Readonly<Record<string, string>>;
52
+ /** Header names are lower-cased. */
53
+ readonly headers: Readonly<Record<string, string>>;
54
+ /** Parse the request body as JSON. Throws on invalid JSON. */
55
+ json<T = unknown>(): Promise<T>;
56
+ /** Read the request body as text. */
57
+ text(): Promise<string>;
58
+ /** Escape hatch: get the raw web `Request`. Use sparingly. */
59
+ raw(): globalThis.Request;
60
+ }
61
+ /**
62
+ * Response body variants. Exactly one of `json` / `text` / `html` /
63
+ * `raw` / `empty` must be set.
64
+ */
65
+ export type MockResponseBody = {
66
+ json: unknown;
67
+ text?: never;
68
+ html?: never;
69
+ raw?: never;
70
+ empty?: never;
71
+ } | {
72
+ json?: never;
73
+ text: string;
74
+ html?: never;
75
+ raw?: never;
76
+ empty?: never;
77
+ } | {
78
+ json?: never;
79
+ text?: never;
80
+ html: string;
81
+ raw?: never;
82
+ empty?: never;
83
+ } | {
84
+ json?: never;
85
+ text?: never;
86
+ html?: never;
87
+ raw: BodyInit;
88
+ empty?: never;
89
+ } | {
90
+ json?: never;
91
+ text?: never;
92
+ html?: never;
93
+ raw?: never;
94
+ empty: true;
95
+ };
96
+ /**
97
+ * Full response shape for the mock framework. Status defaults to 200.
98
+ * Headers are merged into the runtime-provided defaults (Content-Type
99
+ * from the body variant).
100
+ *
101
+ * Named `MockResponse` (not `Response`) to avoid shadowing the Web
102
+ * Fetch `globalThis.Response` at consumer call sites.
103
+ */
104
+ export type MockResponse = MockResponseBody & {
105
+ status?: number;
106
+ headers?: Readonly<Record<string, string>>;
107
+ };
108
+ /** Handler signature. May be sync or async. */
109
+ export type Handler = (req: MockRequest) => MockResponse | Promise<MockResponse>;
110
+ /**
111
+ * Top-level config consumed by `createServer`.
112
+ *
113
+ * Hand-written `routes` always win over OAS-derived ones — duplicate keys
114
+ * raise an error at construction time only when both are hand-written.
115
+ */
116
+ export interface Config {
117
+ /** Hand-written handlers. Keyed by `'METHOD /path'` or `'METHOD /a/:id'`. */
118
+ routes?: Partial<Record<RouteKey, Handler>>;
119
+ /**
120
+ * Raw OpenAPI document as JSON text. When present, @databehave/server
121
+ * generates a handler for every `paths.*.<method>` not already
122
+ * declared in `routes`. Set to `undefined` (the default) to disable.
123
+ */
124
+ openapi?: string;
125
+ /**
126
+ * Reporter for OpenAPI walker failures. Walker errors are
127
+ * recoverable — the offending route falls back to a small stub —
128
+ * but consumers usually want to log them so the OAS gap is fixed.
129
+ */
130
+ onOpenApiWalkError?: (method: Method, routePath: string, err: unknown) => void;
131
+ /**
132
+ * Reporter for OAS responses declared with an empty / permissive
133
+ * schema (`schema: {}`). Per JSON Schema this matches any value,
134
+ * so @databehave/server still serves a deterministic stub — but consumers
135
+ * usually want to surface it so the spec gets filled in.
136
+ */
137
+ onOpenApiEmptySchema?: (method: Method, routePath: string, status: number) => void;
138
+ /**
139
+ * Per-request lifecycle hooks.
140
+ *
141
+ * - `onRequest` — runs before route dispatch. Returning a
142
+ * `MockResponse` short-circuits the handler
143
+ * (use for auth / kill-switch / mock-mode).
144
+ * - `onResponse` — runs after the handler. Returning a new
145
+ * `MockResponse` replaces it (use to inject
146
+ * headers like `x-mock-mode`).
147
+ * - `onError` — invoked on any thrown handler error. Returning
148
+ * a `MockResponse` replaces the default 500.
149
+ * - `onServerError` — invoked on a runtime `http.Server` `'error'`
150
+ * event after a successful bind (EMFILE, accept
151
+ * failures, etc.). When absent, errors are logged
152
+ * via `console.error`. Provide a handler to forward
153
+ * them to your structured logger or metrics pipe.
154
+ */
155
+ hooks?: {
156
+ onRequest?: (req: MockRequest) => MockResponse | void | Promise<MockResponse | void>;
157
+ onResponse?: (req: MockRequest, res: MockResponse) => MockResponse | void | Promise<MockResponse | void>;
158
+ onError?: (req: MockRequest, err: unknown) => MockResponse | Promise<MockResponse>;
159
+ onServerError?: (err: Error) => void;
160
+ };
161
+ /**
162
+ * CORS settings. When provided, @databehave/server:
163
+ * - reflects `Access-Control-Allow-Origin` from `origin()`
164
+ * - handles `OPTIONS` preflight requests for every declared route
165
+ * - exposes the listed headers via `Access-Control-Expose-Headers`
166
+ */
167
+ cors?: CorsConfig;
168
+ /**
169
+ * Opt-in admin / error-injection panel. Default: disabled. See
170
+ * `AdminModeConfig` and the `Admin mode` section in
171
+ * the README. Existing consumers see zero behavior change.
172
+ */
173
+ admin?: import('./admin/admin-types.js').AdminModeConfig;
174
+ /**
175
+ * Opt-in per-request access logs (method, path, status, duration).
176
+ * Default: disabled — no stdout output, no per-request overhead.
177
+ *
178
+ * - `false` (default) — silent.
179
+ * - `true` — shorthand for `{ access: true }` with default knobs.
180
+ * - object — see {@link LogConfig}.
181
+ *
182
+ * Lines are written to **stdout**. The admin enable banner also
183
+ * writes to stdout via `console.info`; stderr carries only runtime
184
+ * warnings and errors. See the `Access logs` README section.
185
+ */
186
+ log?: LogConfig;
187
+ /**
188
+ * Opt-in inbound request validation against the OpenAPI document.
189
+ * Default: disabled — `server.fetch(Request)` is byte-identical to
190
+ * the no-validation behaviour when `validation` is omitted or
191
+ * `validation.request !== true`.
192
+ */
193
+ validation?: {
194
+ /** Master switch for inbound request validation. Default `false`. */
195
+ request?: boolean;
196
+ /**
197
+ * Hard cap on the JSON request body size (UTF-8 bytes) before
198
+ * `JSON.parse` runs. A request whose body exceeds this is rejected
199
+ * with `413 Payload Too Large` (RFC 7807 problem+json). Default
200
+ * `102400` (100 KB) — matches express's body-parser default. Raise
201
+ * only if the OpenAPI document genuinely declares large request
202
+ * bodies.
203
+ */
204
+ maxBodyBytes?: number;
205
+ };
206
+ }
207
+ /**
208
+ * Per-request access-log configuration. See `Config.log`.
209
+ *
210
+ * - `access` — enable the one-line-per-request access log. Default `true`
211
+ * when an object is supplied.
212
+ * - `includeAdmin` — when `true`, log admin-panel requests too. Default
213
+ * `false` so dev consoles aren't flooded by UI traffic.
214
+ * - `colors` — `'auto'` (detect `process.stdout.isTTY`), `'always'`, or
215
+ * `'never'`. Default `'auto'`. Has no effect on the `json` format.
216
+ * - `format` — `'pretty'` (default, ANSI-coloured one-liner) or `'json'`
217
+ * (newline-terminated JSON object, suitable for log shippers).
218
+ */
219
+ export type LogConfig = false | true | {
220
+ access?: boolean;
221
+ includeAdmin?: boolean;
222
+ colors?: 'auto' | 'always' | 'never';
223
+ format?: 'pretty' | 'json';
224
+ };
225
+ /** CORS knobs. All fields are optional. */
226
+ export interface CorsConfig {
227
+ /**
228
+ * Resolve the value for `Access-Control-Allow-Origin`. Receives
229
+ * the request `Origin` header (empty string if absent). Defaults
230
+ * to mirroring the request origin, or `'*'` when none is present.
231
+ */
232
+ origin?: (origin: string) => string;
233
+ /** Allow credentials (cookies). Defaults to `false`. */
234
+ credentials?: boolean;
235
+ /** Headers exposed to the browser via `Access-Control-Expose-Headers`. */
236
+ exposeHeaders?: readonly string[];
237
+ /** Methods accepted on preflight. Defaults to `['GET','POST','PUT','DELETE','PATCH','OPTIONS']`. */
238
+ allowMethods?: readonly string[];
239
+ /** Headers accepted on preflight. Defaults to `['content-type','authorization']`. */
240
+ allowHeaders?: readonly string[];
241
+ /** Cache-time for preflight in seconds. Defaults to `86400`. */
242
+ maxAge?: number;
243
+ }
244
+ /** Options for `Server.listen`. */
245
+ export interface ListenOptions {
246
+ /**
247
+ * Port to bind. Use `0` (the default) to ask the OS for a free
248
+ * port — the actual port is returned in the handle.
249
+ */
250
+ port?: number;
251
+ /** Host to bind. Defaults to `127.0.0.1`. */
252
+ host?: string;
253
+ }
254
+ /** Handle returned from a successful `listen()`. */
255
+ export interface ListenHandle {
256
+ /** Actual port the server is bound to. */
257
+ readonly port: number;
258
+ /** Actual host the server is bound to. */
259
+ readonly host: string;
260
+ /** Stop the server. Resolves when every socket is closed. */
261
+ close(): Promise<void>;
262
+ }
263
+ /**
264
+ * Server facade. Pure `fetch(Request) → Response` for tests, plus a
265
+ * Node HTTP `listen()` for dev / e2e usage. The underlying HTTP
266
+ * runtime is an implementation detail and never leaks to consumers.
267
+ */
268
+ export interface Server {
269
+ /** Process a single Request → Response. Pure, no socket. */
270
+ fetch(req: globalThis.Request): Promise<globalThis.Response>;
271
+ /** Start a Node HTTP server bound to the given port/host. */
272
+ listen(opts?: ListenOptions): Promise<ListenHandle>;
273
+ }
274
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Public types for @databehave/server.
3
+ *
4
+ * Everything a consumer needs to type a config and a handler is exported
5
+ * from here. Internal types (route table, dispatch result, etc.) stay
6
+ * inside their respective modules.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Hand-rolled, zero-runtime-dependency JSON-Schema-subset validator.
3
+ *
4
+ * Audit-it-yourself moat: small, defensive, top-to-bottom readable.
5
+ * FAIL LOUD on unsupported keywords at build time — never silently
6
+ * pass an unrecognised constraint at runtime.
7
+ *
8
+ * Supported keywords (see README → "Validator scope" for the table):
9
+ * type / enum / required / properties / additionalProperties /
10
+ * items / pattern / minLength / maxLength / minimum / maximum /
11
+ * exclusiveMinimum / exclusiveMaximum / minItems / maxItems /
12
+ * $ref (intra-document only) / oneOf / anyOf / allOf /
13
+ * discriminator / format (date | date-time | email | uuid | uri) /
14
+ * nullable (OAS 3.0) and ["X","null"] (OAS 3.1).
15
+ *
16
+ * Security guarantees implemented in this file:
17
+ * - No `eval`, no `new Function`, no dynamic `require`. Pure recursion.
18
+ * - Prototype-pollution guard: input objects whose own keys include
19
+ * `__proto__` / `constructor` / `prototype` are rejected as a
20
+ * per-property violation rather than coerced or thrown on.
21
+ * - ReDoS mitigation: pattern length capped at 1024 chars; invalid
22
+ * regexes rejected at build time (never at request time).
23
+ * - Recursion bounded: hard-cap depth at 64 levels.
24
+ * - $ref cycle detection via a build-time visited-pointer set.
25
+ * - No `JSON.parse` on user input — input arrives as a JS value.
26
+ */
27
+ import type { OasDoc, OasNode } from '../openapi/walker.js';
28
+ export interface Violation {
29
+ /** JSON-Pointer style path from the validation root. */
30
+ readonly path: string;
31
+ /** The JSON Schema keyword that rejected the value. */
32
+ readonly keyword: string;
33
+ /** Short, human-readable description. Never echoes user input. */
34
+ readonly message: string;
35
+ }
36
+ export type Validator = (value: unknown, pointer: string) => Violation[];
37
+ export declare const compileValidator: (node: OasNode, doc: OasDoc, schemaPointer?: string) => Validator;
38
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/validation/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAE3D,MAAM,WAAW,SAAS;IACxB,wDAAwD;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uDAAuD;IACvD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,SAAS,EAAE,CAAA;AAqHxE,eAAO,MAAM,gBAAgB,GAC3B,MAAM,OAAO,EACb,KAAK,MAAM,EACX,sBAAmB,KAClB,SAAwE,CAAA"}