@loggerjs/browser 0.0.2 → 0.3.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.
package/README.md CHANGED
@@ -1,93 +1,110 @@
1
1
  # @loggerjs/browser
2
2
 
3
- Browser transports and integrations for automatic client-side collection.
3
+ > Browser transports, offline persistence, and 19 automatic integrations — re-exports all of `@loggerjs/core`.
4
+
5
+ [![npm](https://img.shields.io/npm/v/@loggerjs/browser.svg)](https://www.npmjs.com/package/@loggerjs/browser)
6
+ [![license](https://img.shields.io/npm/l/@loggerjs/browser)](../../LICENSE)
7
+
8
+ The browser platform package for [LoggerJS](../../README.md). It re-exports the entire `@loggerjs/core` API and adds HTTP / IndexedDB / WebSocket / service-worker / broadcast-channel transports, offline queues with replay, ZIP export, and a broad suite of integrations that turn console calls, errors, network failures, Web Vitals, routing, and lifecycle events into structured logs — all opt-in.
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ npm install @loggerjs/browser @loggerjs/processors
14
+ ```
15
+
16
+ ## Usage
4
17
 
5
18
  ```ts
6
19
  import {
7
20
  browserHttpTransport,
8
- browserBroadcastChannelTransport,
9
- browserServiceWorkerTransport,
10
- browserWebSocketTransport,
11
21
  captureBrowserErrorsIntegration,
12
22
  captureConsoleIntegration,
13
23
  captureFetchIntegration,
14
- captureFrameworkErrorsIntegration,
15
- capturePerformanceIntegration,
16
- captureReportingIntegration,
17
- captureRouterIntegration,
18
- captureRuntimeHostIntegration,
19
- captureServiceWorkerIntegration,
20
- captureUserActionsIntegration,
21
- captureWebSocketIntegration,
22
24
  captureWebVitalsIntegration,
23
25
  createLogger,
24
- downloadBlob,
25
- exportLogsToZip,
26
- indexedDbBrowserHttpOfflineQueue,
27
- indexedDbTransport,
28
26
  memoryBrowserHttpOfflineQueue,
29
27
  pageLifecycleIntegration,
30
28
  } from "@loggerjs/browser";
31
-
32
- const frameworkErrors = captureFrameworkErrorsIntegration({ framework: "react" });
33
- const localStore = indexedDbTransport({
34
- durability: "relaxed",
35
- maxEntries: 50_000,
36
- storageBucketName: "loggerjs-logs",
37
- storageBucketDurability: "relaxed",
38
- ttlMs: 7 * 24 * 60 * 60 * 1000,
39
- });
29
+ import { redactProcessor } from "@loggerjs/processors";
40
30
 
41
31
  const logger = createLogger({
42
- name: "web",
32
+ category: ["web"],
33
+ level: "info",
34
+ processors: [redactProcessor()],
43
35
  transports: [
44
36
  browserHttpTransport({
45
37
  url: "/api/logs",
46
- offlineQueue: indexedDbBrowserHttpOfflineQueue({ maxEntries: 500 }),
38
+ offlineQueue: memoryBrowserHttpOfflineQueue({ maxEntries: 500 }),
47
39
  useBeaconOnPageHide: true,
48
40
  }),
49
- browserBroadcastChannelTransport({ channelName: "loggerjs" }),
50
- browserServiceWorkerTransport(),
51
- browserWebSocketTransport({ url: "wss://example.com/logs" }),
52
- localStore,
53
41
  ],
54
42
  integrations: [
55
43
  captureConsoleIntegration({ levels: ["warn", "error"] }),
56
44
  captureBrowserErrorsIntegration(),
57
45
  captureFetchIntegration(),
58
- frameworkErrors,
59
- captureReportingIntegration(),
60
- captureRouterIntegration(),
61
- captureRuntimeHostIntegration({ electronChannels: ["main:error"] }),
62
- captureServiceWorkerIntegration(),
63
- captureUserActionsIntegration(),
64
- captureWebSocketIntegration(),
65
46
  captureWebVitalsIntegration(),
66
- capturePerformanceIntegration({ entryTypes: ["navigation", "resource", "longtask"] }),
67
47
  pageLifecycleIntegration(),
68
48
  ],
69
49
  });
70
50
 
71
51
  logger.info("page loaded");
52
+ ```
53
+
54
+ Logs batch over HTTP, queue while offline, replay with backoff when the network returns, and attempt a last-chance best-effort `sendBeacon` flush when the tab closes.
55
+
56
+ ## Transports
57
+
58
+ | Transport | Delivers to |
59
+ | --- | --- |
60
+ | `browserHttpTransport` | your collector — batching, offline queue, online replay with backoff, `sendBeacon` on page hide |
61
+ | `indexedDbTransport` | a local, queryable IndexedDB store (TTL, pruning, optional Storage Buckets and durability hints) |
62
+ | `browserWebSocketTransport` | a WebSocket (codec-encoded batches, queues while closed) |
63
+ | `browserServiceWorkerTransport` | a service worker for centralized delivery; `ready()` waits for `serviceWorker.ready` with `target: "ready"` |
64
+ | `browserBroadcastChannelTransport` | other tabs via `BroadcastChannel` |
65
+ | `offlineFirstTransport` | a local store first, then forwards online |
72
66
 
73
- const zip = await exportLogsToZip(localStore, { source: "indexeddb" });
74
- downloadBlob(zip, "loggerjs-logs.zip");
67
+ ### Offline queues & export
75
68
 
76
- // React ErrorBoundary: componentDidCatch(error, info) {
77
- // frameworkErrors.reactComponentDidCatch(error, info);
78
- // }
69
+ - `memoryBrowserHttpOfflineQueue()` — short-lived in-memory retry buffer.
70
+ - `indexedDbBrowserHttpOfflineQueue()` — survives page reloads.
71
+ - `exportLogsToZip()` + `downloadBlob()` — export a persisted store as a zip containing `logs.ndjson` and `manifest.json`.
72
+ - Call the `indexedDbTransport()` instance's `stats()` to read flush, prune, query, drop, and buffer-depth counters.
73
+
74
+ Browser delivery has runtime loss windows: tab close can cut off async work,
75
+ `sendBeacon` is size- and user-agent-limited, service worker delivery depends on
76
+ activation and lifetime, and IndexedDB persistence depends on quota and browser
77
+ storage policy. Use an IndexedDB offline queue when reload survival matters.
78
+
79
+ ## Integrations (19)
80
+
81
+ | Group | Integrations |
82
+ | --- | --- |
83
+ | **Console & errors** | `captureConsoleIntegration`, `captureBrowserErrorsIntegration`, `captureFrameworkErrorsIntegration`, `captureReportingIntegration` |
84
+ | **Network** | `captureFetchIntegration`, `captureXHRIntegration`, `captureWebSocketIntegration` |
85
+ | **Performance** | `captureWebVitalsIntegration`, `capturePerformanceIntegration` |
86
+ | **Navigation** | `captureRouterIntegration`, `nextRouterIntegration`, `reactRouterIntegration`, `vueRouterIntegration`, `nuxtRouterIntegration` |
87
+ | **Lifecycle & context** | `pageLifecycleIntegration`, `captureUserActionsIntegration`, `captureServiceWorkerIntegration`, `captureRuntimeHostIntegration`, `browserContextPropagationIntegration` |
88
+
89
+ Integrations patch through an unpatched-original registry and a re-entrancy guard, so the console transport never loops back through console capture. Framework error hooks expose `reactComponentDidCatch()`, `vueErrorHandler()`, etc.:
90
+
91
+ ```ts
92
+ const frameworkErrors = captureFrameworkErrorsIntegration({ framework: "react" });
93
+ // In a React ErrorBoundary:
94
+ // componentDidCatch(error, info) { frameworkErrors.reactComponentDidCatch(error, info); }
79
95
  ```
80
96
 
81
- Use `memoryBrowserHttpOfflineQueue()` for short-lived in-memory retry buffers, or
82
- `indexedDbBrowserHttpOfflineQueue()` when payloads must survive page reloads.
83
- Use `indexedDbTransport()` when the browser should keep a local, queryable log store.
84
- It can opt into IndexedDB transaction durability hints and Chrome Storage Buckets
85
- for better isolation when the browser supports them. For high-throughput local
86
- capture on modern Chrome, prefer `durability: "relaxed"` with a dedicated
87
- `storageBucketName` and `storageBucketDurability: "relaxed"`; unsupported browsers
88
- fall back to the regular IndexedDB instance. Call `localStore.stats()` to read
89
- flush, prune, query, drop, and buffer-depth counters for observability.
90
- Use `exportLogsToZip()` and `downloadBlob()` to export persisted browser logs as a
91
- standard zip file containing `logs.ndjson` and `manifest.json`.
92
-
93
- Subpaths expose `transport-http`, `transport-broadcast-channel`, `transport-service-worker`, `transport-websocket`, `transport-indexeddb`, `offline-indexeddb`, `export-zip`, `integration-console`, `integration-errors`, `integration-fetch`, `integration-xhr`, `integration-framework-errors`, `integration-reporting`, `integration-router`, `integration-runtime-host`, `integration-service-worker`, `integration-user-actions`, `integration-websocket`, `integration-web-vitals`, `integration-performance`, and `integration-page-lifecycle`.
97
+ ## Subpath exports
98
+
99
+ Transports — `transport-http` · `transport-indexeddb` · `transport-websocket` · `transport-service-worker` · `transport-broadcast-channel` · `offline-first-transport` · `offline-indexeddb` · `export-zip` · `payload-transforms`
100
+
101
+ Integrations — `integration-console` · `integration-errors` · `integration-framework-errors` · `integration-reporting` · `integration-fetch` · `integration-xhr` · `integration-websocket` · `integration-web-vitals` · `integration-performance` · `integration-router` · `integration-framework-routers` · `integration-page-lifecycle` · `integration-user-actions` · `integration-service-worker` · `integration-runtime-host` · `integration-context`
102
+
103
+ ## Documentation
104
+
105
+ - [Transports](../../docs/TRANSPORTS.md) · [Integrations](../../docs/INTEGRATIONS.md) · [Operations](../../docs/OPERATIONS.md)
106
+ - [Getting Started](../../docs/GETTING-STARTED.md) · [LoggerJS root README](../../README.md)
107
+
108
+ ## License
109
+
110
+ [MIT](../../LICENSE) © JS Kits
@@ -0,0 +1,20 @@
1
+ import { type Baggage, type Integration, type TraceContext } from "@loggerjs/core";
2
+ export type BrowserContextActionEventName = "change" | "click" | "input" | "keydown" | "submit";
3
+ export interface BrowserContextEventTargetLike {
4
+ addEventListener: typeof globalThis.addEventListener;
5
+ removeEventListener: typeof globalThis.removeEventListener;
6
+ }
7
+ export interface BrowserContextPropagationOptions {
8
+ sessionId?: string | (() => string | undefined);
9
+ requestId?: () => string | undefined;
10
+ trace?: TraceContext | (() => TraceContext | undefined);
11
+ traceparent?: string | (() => string | undefined);
12
+ baggage?: Baggage | string | (() => Baggage | string | undefined);
13
+ actionEvents?: readonly BrowserContextActionEventName[];
14
+ actionTtlMs?: number;
15
+ root?: BrowserContextEventTargetLike;
16
+ clock?: () => number;
17
+ idFactory?: () => string;
18
+ }
19
+ export declare function browserContextPropagationIntegration(options?: BrowserContextPropagationOptions): Integration;
20
+ //# sourceMappingURL=context-propagation-integration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-propagation-integration.d.ts","sourceRoot":"","sources":["../src/context-propagation-integration.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,6BAA6B,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEhG,MAAM,WAAW,6BAA6B;IAC5C,gBAAgB,EAAE,OAAO,UAAU,CAAC,gBAAgB,CAAC;IACrD,mBAAmB,EAAE,OAAO,UAAU,CAAC,mBAAmB,CAAC;CAC5D;AAED,MAAM,WAAW,gCAAgC;IAC/C,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC;IAChD,SAAS,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACrC,KAAK,CAAC,EAAE,YAAY,GAAG,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC;IACxD,WAAW,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC;IAClD,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;IAClE,YAAY,CAAC,EAAE,SAAS,6BAA6B,EAAE,CAAC;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,6BAA6B,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,MAAM,CAAC;CAC1B;AAgCD,wBAAgB,oCAAoC,CAClD,OAAO,GAAE,gCAAqC,GAC7C,WAAW,CAiEb"}
@@ -0,0 +1,36 @@
1
+ import { type Integration, type LoggerLevel } from "@loggerjs/core";
2
+ export interface FrameworkRouterIntegrationOptions {
3
+ level?: LoggerLevel;
4
+ sanitizeUrl?: (url: string) => string;
5
+ includeState?: boolean;
6
+ }
7
+ export interface NextRouterLike {
8
+ asPath?: string;
9
+ events?: {
10
+ on?: (event: string, listener: (url: string) => void) => void;
11
+ off?: (event: string, listener: (url: string) => void) => void;
12
+ };
13
+ }
14
+ export interface ReactRouterHistoryLike {
15
+ location?: unknown;
16
+ listen?: (listener: (update: unknown) => void) => void | (() => void);
17
+ }
18
+ export interface VueRouterLike {
19
+ currentRoute?: unknown;
20
+ afterEach?: (listener: (to: unknown, from: unknown) => void) => void | (() => void);
21
+ }
22
+ export interface NextRouterIntegrationOptions extends FrameworkRouterIntegrationOptions {
23
+ router: NextRouterLike;
24
+ }
25
+ export interface ReactRouterIntegrationOptions extends FrameworkRouterIntegrationOptions {
26
+ history: ReactRouterHistoryLike;
27
+ }
28
+ export interface VueRouterIntegrationOptions extends FrameworkRouterIntegrationOptions {
29
+ router: VueRouterLike;
30
+ framework?: "vue-router" | "nuxt";
31
+ }
32
+ export declare function nextRouterIntegration(options: NextRouterIntegrationOptions): Integration;
33
+ export declare function reactRouterIntegration(options: ReactRouterIntegrationOptions): Integration;
34
+ export declare function vueRouterIntegration(options: VueRouterIntegrationOptions): Integration;
35
+ export declare function nuxtRouterIntegration(options: Omit<VueRouterIntegrationOptions, "framework">): Integration;
36
+ //# sourceMappingURL=framework-router-integrations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-router-integrations.d.ts","sourceRoot":"","sources":["../src/framework-router-integrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAEhB,KAAK,WAAW,EACjB,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,iCAAiC;IAChD,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE;QACP,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;QAC9D,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;KAChE,CAAC;CACH;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;CACrF;AAED,MAAM,WAAW,4BAA6B,SAAQ,iCAAiC;IACrF,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,6BAA8B,SAAQ,iCAAiC;IACtF,OAAO,EAAE,sBAAsB,CAAC;CACjC;AAED,MAAM,WAAW,2BAA4B,SAAQ,iCAAiC;IACpF,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;CACnC;AAgDD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,WAAW,CAkBxF;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,6BAA6B,GAAG,WAAW,CAgB1F;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,WAAW,CActF;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,IAAI,CAAC,2BAA2B,EAAE,WAAW,CAAC,GACtD,WAAW,CAEb"}
@@ -1,4 +1,4 @@
1
- import { type Codec, type LogEvent, type LoggerLevel, type Transport } from "@loggerjs/core";
1
+ import { type Codec, type LogEvent, type LoggerLevel, type PayloadTransform, type Transport } from "@loggerjs/core";
2
2
  export type BrowserHttpDropPolicy = "drop-oldest" | "drop-newest";
3
3
  export interface BrowserHttpOfflineEntry {
4
4
  id: string;
@@ -40,6 +40,7 @@ export interface BrowserHttpTransportOptions {
40
40
  offlineReplayMaxDelayMs?: number;
41
41
  random?: () => number;
42
42
  fetchFn?: typeof fetch;
43
+ transformPayload?: PayloadTransform | readonly PayloadTransform[];
43
44
  onDrop?: (event: LogEvent, reason: string) => void;
44
45
  }
45
46
  export declare function memoryBrowserHttpOfflineQueue(options?: MemoryBrowserHttpOfflineQueueOptions): BrowserHttpOfflineQueue & {
@@ -1 +1 @@
1
- {"version":3,"file":"http-transport.d.ts","sourceRoot":"","sources":["../src/http-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,KAAK,EACV,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,SAAS,EAEf,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,aAAa,CAAC;AAOlE,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IAC1B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3F;AAED,MAAM,WAAW,oCAAoC;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACnE;AAED,MAAM,WAAW,2BAA2B;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,uBAAuB,CAAC;IACvC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,GAAE,oCAAyC,GACjD,uBAAuB,GAAG;IAAE,IAAI,EAAE,MAAM,MAAM,CAAA;CAAE,CAoClD;AAiCD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,SAAS,CA6PpF"}
1
+ {"version":3,"file":"http-transport.d.ts","sourceRoot":"","sources":["../src/http-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,KAAK,EAEV,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,SAAS,EAEf,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,aAAa,CAAC;AAOlE,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IAC1B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3F;AAED,MAAM,WAAW,oCAAoC;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACnE;AAED,MAAM,WAAW,2BAA2B;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,uBAAuB,CAAC;IACvC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,SAAS,gBAAgB,EAAE,CAAC;IAClE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,GAAE,oCAAyC,GACjD,uBAAuB,GAAG;IAAE,IAAI,EAAE,MAAM,MAAM,CAAA;CAAE,CAoClD;AAiCD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,SAAS,CAqSpF"}