@hyperttp/transport-bun 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,25 +1,24 @@
1
1
  # BunTransport
2
2
 
3
- `BunTransport` is a network transport implementation for `HyperTransport`, designed to run in the **Bun runtime**.
3
+ `BunTransport` is a high-performance HTTP transport for the
4
+ [HyperTransport](https://github.com/IT-IF-OR) ecosystem, designed for the **Bun runtime**.
4
5
 
5
- It wraps `fetch` and adds:
6
+ It wraps native `fetch` and adds:
6
7
 
7
- - concurrency limiting
8
+ - concurrency limiting with FIFO queue
8
9
  - request timeouts via `AbortSignal`
9
- - automatic cookie handling
10
+ - automatic cookie handling with TTL and LRU eviction
11
+ - response caching for GET/HEAD requests
12
+ - stealth / fingerprint mimicry (JA3/JA4)
10
13
  - header normalization
11
14
  - `keepalive` support
12
- - access to Bun `tls` options
15
+ - TLS configuration (ciphers, `rejectUnauthorized`)
13
16
 
14
17
  ---
15
18
 
16
19
  ## Interface
17
20
 
18
21
  ```ts
19
- /**
20
- * @ru Общий интерфейс для реализации сетевых транспортов.
21
- * @en Unified interface for building runtime-specific network transports.
22
- */
23
22
  export interface HyperTransport {
24
23
  execute(req: TransportRequest): Promise<TransportResponse>;
25
24
  close?(): Promise<void>;
@@ -34,43 +33,65 @@ export interface HyperTransport {
34
33
  ## Features
35
34
 
36
35
  - `fetch`-based implementation with `signal` support
37
- - `redirect: "manual"`
38
36
  - automatic merging of cookies from responses and subsequent requests
39
- - cookie cache per domain
40
- - request concurrency limiting
37
+ - cookie cache per domain with configurable TTL
38
+ - response cache for GET/HEAD requests (optional, via `hcacher`)
39
+ - request concurrency limiting with FIFO queue
41
40
  - request timeout support
42
- - automatic `User-Agent` injection from config (if not provided manually)
41
+ - stealth mode: browser-like TLS fingerprint emulation (Chrome, Firefox, Safari, Edge)
42
+ - `baseUrl` support for relative URLs
43
43
  - compatibility with `TransportRequest` / `TransportResponse`
44
44
 
45
45
  ---
46
46
 
47
+ ## Benchmark
48
+
49
+ Benchmark results on **Bun 1.3.14** (20K requests, 200 concurrent, 60s duration):
50
+
51
+ ```text
52
+ Environment: linux 7.1.3-zen2-1-zen | Intel Core i5-8600K @ 3.60GHz
53
+ ```
54
+
55
+ | Rank | Client | RPS | Avg | p50 | p90 | p99 | Errors |
56
+ | ---- | -------------- | ------ | -------- | -------- | -------- | -------- | ------ |
57
+ | 1 | bun-fetch | 25.92K | 7.65 ms | 7.69 ms | 10.41 ms | 14.00 ms | 0 |
58
+ | 2 | undici | 21.47K | 9.28 ms | 9.54 ms | 12.80 ms | 14.77 ms | 0 |
59
+ | 3 | @hyperttp/core | 14.70K | 13.53 ms | 12.03 ms | 17.36 ms | 19.72 ms | 0 |
60
+ | 4 | axios | 6.24K | 31.85 ms | 31.83 ms | 33.82 ms | 36.10 ms | 0 |
61
+
62
+ `BunTransport` (via `@hyperttp/core`) delivers **2.4x higher throughput** than `axios` with **2.3x lower latency** (p50).
63
+
64
+ ---
65
+
47
66
  ## Installation
48
67
 
49
68
  `BunTransport` is designed for Bun, so the project must run in the Bun runtime.
50
69
 
51
70
  ```bash
52
- bun install
71
+ bun add @hyperttp/transport-bun
53
72
  ```
54
73
 
74
+ Peer dependencies: `@hyperttp/types`, `hcacher`.
75
+
55
76
  ---
56
77
 
57
78
  ## Usage
58
79
 
59
80
  ```ts
60
- import { BunTransport } from "./BunTransport";
81
+ import { BunTransport } from "@hyperttp/transport-bun";
61
82
 
62
83
  const transport = new BunTransport({
84
+ baseUrl: "https://api.example.com",
63
85
  network: {
64
86
  timeout: 10_000,
65
87
  maxConcurrent: 32,
66
- userAgent: "Hyperttp/1.0",
67
88
  keepAliveTimeout: 30_000,
68
89
  rejectUnauthorized: true,
69
90
  },
70
91
  });
71
92
 
72
93
  const response = await transport.execute({
73
- url: "https://example.com",
94
+ url: "/users",
74
95
  method: "GET",
75
96
  headers: {},
76
97
  body: null,
@@ -84,54 +105,71 @@ console.log(await response.text());
84
105
 
85
106
  ## Configuration
86
107
 
87
- `BunTransport` reads configuration from `HttpClientOptions.network`.
108
+ `BunTransport` accepts a `BunTransportConfig` object:
109
+
110
+ ```ts
111
+ interface BunTransportConfig extends HttpClientOptions {
112
+ baseUrl?: string;
113
+ stealth?: StealthOptions;
114
+ }
115
+ ```
88
116
 
89
- Supported options:
117
+ ### Network options
90
118
 
91
119
  ```ts
92
120
  network?: {
93
121
  maxConcurrent?: number;
94
122
  timeout?: number;
95
- userAgent?: string;
96
123
  keepAliveTimeout?: number;
97
124
  rejectUnauthorized?: boolean;
125
+ cookieCache?: {
126
+ enabled?: boolean;
127
+ maxSize?: number;
128
+ ttl?: number;
129
+ };
130
+ cache?: {
131
+ enabled?: boolean;
132
+ maxSize?: number;
133
+ ttl?: number;
134
+ };
98
135
  }
99
136
  ```
100
137
 
101
- ### Option behavior
102
-
103
- - `maxConcurrent` — maximum number of concurrent active requests.
104
- - `timeout` — global request timeout in milliseconds.
105
- - `userAgent` — injected into `User-Agent` header if not explicitly set.
106
- - `keepAliveTimeout` — enables `keepalive` mode when provided.
107
- - `rejectUnauthorized` — passed to Bun `fetch` via `tls` configuration.
138
+ | Option | Description |
139
+ | -------------------- | ---------------------------------------------------------------------------------------------- |
140
+ | `maxConcurrent` | Maximum number of concurrent active requests (0 = unlimited) |
141
+ | `timeout` | Global request timeout in milliseconds (0 = no timeout) |
142
+ | `keepAliveTimeout` | Enables `keepalive` mode when provided |
143
+ | `rejectUnauthorized` | Passed to Bun `fetch` via `tls` configuration |
144
+ | `cookieCache` | Cookie cache settings: `enabled` (default true), `maxSize` (default 256), `ttl` (default 300s) |
145
+ | `cache` | Response cache settings for GET/HEAD: `enabled`, `maxSize` (default 256), `ttl` (default 30s) |
108
146
 
109
147
  ---
110
148
 
111
149
  ## Cookies
112
150
 
113
- The transport supports persistent cookie storage and reuse between requests.
151
+ The transport supports persistent cookie storage with TTL and LRU eviction, backed by `hcacher`.
114
152
 
115
153
  ### How it works
116
154
 
117
- 1. When the server returns `Set-Cookie`, cookies are stored per domain.
155
+ 1. When the server returns `Set-Cookie`, cookies are stored per domain with a TTL.
118
156
  2. On subsequent requests to the same domain, cookies are automatically attached to the `Cookie` header.
119
157
  3. If the user provides their own `Cookie` header, it is merged with stored cookies.
158
+ 4. Expired entries are evicted automatically (LRU).
120
159
 
121
160
  ### Example
122
161
 
123
162
  ```ts
124
163
  await transport.execute({
125
- url: "https://example.com/login",
164
+ url: "/login",
126
165
  method: "POST",
127
- headers: {
128
- "Content-Type": "application/json",
129
- },
166
+ headers: { "Content-Type": "application/json" },
130
167
  body: JSON.stringify({ login: "demo", password: "secret" }),
131
168
  });
132
169
 
170
+ // Cookies from /login are automatically sent
133
171
  const res = await transport.execute({
134
- url: "https://example.com/profile",
172
+ url: "/profile",
135
173
  method: "GET",
136
174
  headers: {},
137
175
  body: null,
@@ -140,6 +178,26 @@ const res = await transport.execute({
140
178
 
141
179
  ---
142
180
 
181
+ ## Response caching
182
+
183
+ When `network.cache` is configured, GET and HEAD requests are cached automatically with TTL and LRU eviction.
184
+
185
+ ```ts
186
+ const transport = new BunTransport({
187
+ network: {
188
+ cache: {
189
+ enabled: true,
190
+ maxSize: 512,
191
+ ttl: 60_000, // 1 minute
192
+ },
193
+ },
194
+ });
195
+ ```
196
+
197
+ Cached responses are returned instantly on repeated requests to the same URL within the TTL window.
198
+
199
+ ---
200
+
143
201
  ## Concurrency limiting
144
202
 
145
203
  If `maxConcurrent > 0`, incoming requests are queued until a slot becomes available.
@@ -164,16 +222,45 @@ If a request is aborted, the signal reason (or a default `AbortError`) is thrown
164
222
 
165
223
  ---
166
224
 
225
+ ## Stealth / fingerprint mimicry
226
+
227
+ `BunTransport` supports browser-like TLS fingerprint emulation to bypass fingerprint-based protections (JA3/JA4).
228
+
229
+ ### Supported profiles
230
+
231
+ | Profile | TLS ciphers | sec-ch-ua | User-Agent |
232
+ | ------- | ------------- | ------------- | ----------- |
233
+ | chrome | Chrome suite | Chrome 126 | Chrome 126 |
234
+ | firefox | Firefox suite | Firefox-style | Firefox 126 |
235
+ | safari | Safari suite | — | Safari 17.0 |
236
+ | edge | Chrome suite | Chrome 126 | Edge 126 |
237
+
238
+ ### Example
239
+
240
+ ```ts
241
+ const transport = new BunTransport({
242
+ stealth: {
243
+ fingerprint: "chrome",
244
+ },
245
+ });
246
+ ```
247
+
248
+ Stealth presets are applied per-request. Manual headers always take priority over preset values.
249
+
250
+ ---
251
+
167
252
  ## Response API
168
253
 
169
- `BunTransportResponse` wraps the native `Response` and provides:
254
+ `execute()` returns a plain `TransportResponse` object:
170
255
 
171
- - `status`
172
- - `url`
173
- - `body`
174
- - `text()`
175
- - `json()`
176
- - `headers`
256
+ ```ts
257
+ interface TransportResponse {
258
+ status: number;
259
+ url: string;
260
+ headers: Record<string, string | string[]>;
261
+ body: TransportResponsePayload | null;
262
+ }
263
+ ```
177
264
 
178
265
  ### Body behavior
179
266
 
@@ -185,22 +272,15 @@ If `body` exists, a `dump()` method may be attached to it, allowing safe stream
185
272
 
186
273
  ### `fastGetHostname(url: string): string`
187
274
 
188
- Fast hostname extraction from a URL without full parsing.
189
-
190
- ### `normalizeHeaderValue(name, value)`
191
-
192
- Normalizes header values:
193
-
194
- - `Cookie` headers are joined using `;`
195
- - other arrays are joined using `,`
275
+ Fast hostname extraction from a URL with single-entry LRU cache. Handles `//`, `scheme://`, `user@host`, and port stripping.
196
276
 
197
- ### `normalizeCookieHeader(value)`
277
+ ### `resolveUrl(baseUrl: string, url: string): string`
198
278
 
199
- Converts cookie header values into a normalized string.
279
+ Resolves a relative URL against a `baseUrl`. Absolute URLs are returned as-is.
200
280
 
201
- ### `throwIfAborted(signal)`
281
+ ### `normalizeHeaders(headers): Record<string, string>`
202
282
 
203
- Checks whether an operation has been aborted and throws if so.
283
+ Normalizes headers: lowercases all keys, joins arrays (`;` for `cookie`, `,` for others).
204
284
 
205
285
  ---
206
286
 
@@ -216,8 +296,10 @@ await transport.destroy();
216
296
  Both methods clear:
217
297
 
218
298
  - pending request queue
219
- - cookie jar
220
- - cookie cache
299
+ - cookie store
300
+ - cookie string cache
301
+ - response cache
302
+ - active request counter
221
303
 
222
304
  ---
223
305
 
@@ -226,7 +308,7 @@ Both methods clear:
226
308
  - Designed specifically for the **Bun runtime**, not Node.js.
227
309
  - Uses `redirect: "manual"` for fetch requests.
228
310
  - Minimal interference with request data; only headers, cookies, and signals are normalized or extended.
229
- - `TransportRequest.body` is treated as `BodyInit | null`.
311
+ - `TransportRequest.body` is passed directly as `BodyInit | null`.
230
312
 
231
313
  ---
232
314
 
package/bun.d.ts CHANGED
@@ -1,36 +1,71 @@
1
- import type { HttpClientOptions, HyperTransport, TransportRequest, TransportResponse } from "@hyperttp/types";
1
+ import type { HyperTransport, TransportRequest, TransportResponse } from "@hyperttp/types";
2
+ import type { BunTransportConfig } from "./types/index.js";
2
3
  /**
3
- * @ru Конфигурация транспорта Bun.
4
- * @en Bun transport configuration.
4
+ * @ru Высокопроизводительный HTTP-транспорт для Bun с нативными оптимизациями и поддержкой Stealth-мимикрии.
5
+ * Включает управление параллелизмом, cookie jar и кэширование доменов.
6
+ * @en High-performance HTTP transport for Bun with native optimizations and Stealth mimicry support.
7
+ * Includes concurrency management, cookie jar, and domain caching.
5
8
  */
6
- export interface BunTransportConfig extends HttpClientOptions {
9
+ export declare class BunTransport implements HyperTransport {
7
10
  /**
8
- * @ru Базовый URL для всех запросов.
9
- * @en Base URL for all requests.
11
+ * @ru Конфигурация транспорта.
12
+ * @en Transport configuration.
10
13
  */
11
- baseUrl?: string;
12
- }
13
- /**
14
- * @ru Высокопроизводительный HTTP-транспорт для Bun с нативными оптимизациями.
15
- * Поддерживает cookies, concurrency control, таймауты, keepalive и TLS конфигурацию.
16
- * @en High-performance HTTP transport for Bun with native optimizations.
17
- * Supports cookies, concurrency control, timeouts, keepalive, and TLS configuration.
18
- */
19
- export declare class BunTransport implements HyperTransport {
20
14
  config: BunTransportConfig;
21
- private cookieJar;
22
- private readonly cookieDomains;
23
- private cookieCache;
24
- private cookieCacheSize;
15
+ /**
16
+ * @ru Кэш cookies по доменам с TTL и LRU-эвикцией (domain -> name -> value).
17
+ * @en Cookie cache by domain with TTL and LRU eviction (domain -> name -> value).
18
+ */
19
+ private readonly cookieStore;
20
+ /**
21
+ * @ru Кэш сгенерированных строк cookies с TTL.
22
+ * @en Cache of generated cookie strings with TTL.
23
+ */
24
+ private readonly cookieStringCache;
25
+ /**
26
+ * @ru Опциональный кэш HTTP-ответов для GET/HEAD запросов.
27
+ * @en Optional HTTP response cache for GET/HEAD requests.
28
+ */
29
+ private readonly responseCache?;
30
+ /**
31
+ * @ru Счётчик активных (выполняющихся) запросов.
32
+ * @en Counter of active (in-flight) requests.
33
+ */
25
34
  private activeRequests;
35
+ /**
36
+ * @ru Очередь запросов, ожидающих свободного слота при достижении лимита параллелизма.
37
+ * @en Queue of requests waiting for a free slot when concurrency limit is reached.
38
+ */
26
39
  private concurrencyQueue;
40
+ /**
41
+ * @ru Индекс начала очереди (для FIFO обработки).
42
+ * @en Queue head index (for FIFO processing).
43
+ */
27
44
  private queueHead;
45
+ /**
46
+ * @ru Индекс конца очереди (для добавления новых элементов).
47
+ * @en Queue tail index (for adding new elements).
48
+ */
28
49
  private queueTail;
29
- private hasCookies;
50
+ /**
51
+ * @ru Максимальное количество одновременных запросов (0 = без лимита).
52
+ * @en Maximum number of concurrent requests (0 = unlimited).
53
+ */
30
54
  private _maxConcurrent;
55
+ /**
56
+ * @ru Таймаут запроса в миллисекундах (0 = без таймаута).
57
+ * @en Request timeout in milliseconds (0 = no timeout).
58
+ */
31
59
  private _timeout;
32
- private _userAgent;
60
+ /**
61
+ * @ru Флаг использования keep-alive соединений.
62
+ * @en Flag for using keep-alive connections.
63
+ */
33
64
  private _keepalive;
65
+ /**
66
+ * @ru Конфигурация TLS (отклонение невалидных сертификатов и шифры).
67
+ * @en TLS configuration (reject unauthorized certificates and ciphers).
68
+ */
34
69
  private _tlsConfig;
35
70
  /**
36
71
  * @ru Создаёт экземпляр BunTransport.
@@ -39,53 +74,62 @@ export declare class BunTransport implements HyperTransport {
39
74
  */
40
75
  constructor(config: BunTransportConfig);
41
76
  /**
42
- * @ru Инвалидирует кэшированные настройки при изменении конфигурации.
43
- * @en Invalidates cached settings when configuration changes.
77
+ * @ru Обновляет внутреннее состояние на основе конфигурации.
78
+ * Вызывается при создании и может быть вызвано при изменении конфига.
79
+ * @en Updates internal state based on configuration.
80
+ * Called on creation and can be called when config changes.
44
81
  */
45
82
  private invalidateConfig;
46
83
  /**
47
- * @ru Выполняет HTTP-запрос через нативный fetch Bun.
48
- * @en Executes an HTTP request via Bun's native fetch.
84
+ * @ru Выполняет HTTP-запрос через нативный fetch Bun с управлением параллелизмом и таймаутами.
85
+ * @en Executes an HTTP request via Bun's native fetch with concurrency management and timeouts.
49
86
  * @param req - The normalized transport request.
50
87
  * @returns Promise resolving to the transport response.
88
+ * @throws Error if the request is aborted or times out.
51
89
  */
52
90
  execute(req: TransportRequest): Promise<TransportResponse>;
53
91
  /**
54
- * @ru Подготавливает заголовки запроса, добавляя User-Agent и cookies.
55
- * @en Prepares request headers, adding User-Agent and cookies.
56
- * @param req - The transport request.
57
- * @returns The prepared headers or undefined.
92
+ * @ru Получает строку cookies для указанного домена с учётом родительских доменов.
93
+ * @en Gets the cookie string for the specified domain, considering parent domains.
94
+ * @param requestDomain - The domain to get cookies for.
95
+ * @returns Semicolon-separated cookie string.
96
+ */
97
+ private getCookiesForDomain;
98
+ /**
99
+ * @ru Возвращает все домены из cookie store.
100
+ * @en Returns all domains from the cookie store.
101
+ */
102
+ private getAllCookieDomains;
103
+ /**
104
+ * @ru Сохраняет cookies из заголовков Set-Cookie ответа в cookie jar.
105
+ * @en Stores cookies from response Set-Cookie headers into the cookie jar.
106
+ * @param requestUrl - The request URL for determining the default domain.
107
+ * @param headers - Response headers containing Set-Cookie values.
58
108
  */
59
- private prepareHeaders;
109
+ private storeCookies;
60
110
  /**
61
- * @ru Ожидает свободный слот в очереди concurrency.
62
- * @en Waits for an available slot in the concurrency queue.
63
- * @param signal - Optional abort signal.
111
+ * @ru Ожидает освобождения слота в очереди параллелизма.
112
+ * @en Waits for a slot to become available in the concurrency queue.
113
+ * @param signal - Optional abort signal to cancel waiting.
64
114
  * @returns Promise that resolves when a slot is available.
115
+ * @throws Error if the signal is aborted while waiting.
65
116
  */
66
117
  private waitForSlot;
67
118
  /**
68
- * @ru Освобождает слот и уведомляет следующий запрос в очереди.
69
- * @en Releases a slot and notifies the next request in the queue.
119
+ * @ru Освобождает слот и разблокирует следующий запрос в очереди.
120
+ * @en Releases a slot and unblocks the next request in the queue.
70
121
  */
71
122
  private releaseSlot;
72
123
  /**
73
- * @ru Извлекает cookies для указанного домена из cookie jar.
74
- * @en Retrieves cookies for the specified domain from the cookie jar.
75
- * @param requestDomain - The domain to get cookies for.
76
- * @returns The cookie string or empty string.
77
- */
78
- private getCookiesForDomain;
79
- /**
80
- * @ru Мягко закрывает транспорт, очищая очереди и cookies.
81
- * @en Gracefully closes the transport, clearing queues and cookies.
82
- * @returns Promise that resolves when the transport is closed.
124
+ * @ru Мягко закрывает транспорт, очищая очереди и cookie jar.
125
+ * @en Gracefully closes the transport, clearing queues and cookie jar.
126
+ * @returns Promise that resolves when cleanup is complete.
83
127
  */
84
128
  close(): Promise<void>;
85
129
  /**
86
- * @ru Принудительно уничтожает транспорт и все активные соединения.
87
- * @en Immediately destroys the transport and all active connections.
88
- * @returns Promise that resolves when the transport is destroyed.
130
+ * @ru Принудительно уничтожает транспорт (алиас для close()).
131
+ * @en Forcefully destroys the transport (alias for close()).
132
+ * @returns Promise that resolves when cleanup is complete.
89
133
  */
90
134
  destroy(): Promise<void>;
91
135
  }
package/bun.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bun.d.ts","sourceRoot":"","sources":["../src/bun.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EAElB,MAAM,iBAAiB,CAAC;AA4HzB;;;GAGG;AACH,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,qBAAa,YAAa,YAAW,cAAc;IAC1C,MAAM,EAAE,kBAAkB,CAAC;IAElC,OAAO,CAAC,SAAS,CAA+D;IAChF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,WAAW,CAA+C;IAClE,OAAO,CAAC,eAAe,CAAK;IAE5B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,gBAAgB,CAAmD;IAC3E,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,SAAS,CAAK;IAEtB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAgD;IAElE;;;;OAIG;gBACS,MAAM,EAAE,kBAAkB;IAKtC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IASxB;;;;;OAKG;IACU,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAsEvE;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAgCtB;;;;;OAKG;YACW,WAAW;IAmBzB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAkBnB;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAgC3B;;;;OAIG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAYnC;;;;OAIG;IACU,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAGtC"}
1
+ {"version":3,"file":"bun.d.ts","sourceRoot":"","sources":["../src/bun.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EAIlB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAgI3D;;;;;GAKG;AACH,qBAAa,YAAa,YAAW,cAAc;IACjD;;;OAGG;IACI,MAAM,EAAE,kBAAkB,CAAC;IAElC;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuC;IAEnE;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAuB;IAEzD;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAkC;IAEjE;;;OAGG;IACH,OAAO,CAAC,cAAc,CAAK;IAE3B;;;OAGG;IACH,OAAO,CAAC,gBAAgB,CAAmD;IAE3E;;;OAGG;IACH,OAAO,CAAC,SAAS,CAAK;IAEtB;;;OAGG;IACH,OAAO,CAAC,SAAS,CAAK;IAEtB;;;OAGG;IACH,OAAO,CAAC,cAAc,CAAK;IAE3B;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAK;IAErB;;;OAGG;IACH,OAAO,CAAC,UAAU,CAAS;IAE3B;;;OAGG;IACH,OAAO,CAAC,UAAU,CAAkE;IAEpF;;;;OAIG;IACH,YAAY,MAAM,EAAE,kBAAkB,EA6BrC;IAED;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAQxB;;;;;;OAMG;IACU,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAsItE;IAED;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAwB3B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAS3B;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IA8CpB;;;;;;OAMG;YACW,WAAW;IAmBzB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAkBnB;;;;OAIG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAQlC;IAED;;;;OAIG;IACU,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAEpC;CACF"}