@loggerjs/node 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 +102 -21
- package/dist/bullmq-integration.d.ts +9 -0
- package/dist/bullmq-integration.d.ts.map +1 -0
- package/dist/file-transport.d.ts +6 -2
- package/dist/file-transport.d.ts.map +1 -1
- package/dist/hapi-integration.d.ts +44 -0
- package/dist/hapi-integration.d.ts.map +1 -0
- package/dist/http-transport.d.ts +2 -1
- package/dist/http-transport.d.ts.map +1 -1
- package/dist/index.cjs +857 -261
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +852 -264
- package/dist/index.js.map +1 -1
- package/dist/internal-types.d.ts +2 -0
- package/dist/internal-types.d.ts.map +1 -1
- package/dist/koa-integration.d.ts +26 -0
- package/dist/koa-integration.d.ts.map +1 -0
- package/dist/logger-diagnostics.d.ts +14 -0
- package/dist/logger-diagnostics.d.ts.map +1 -0
- package/dist/nest-integration.d.ts +5 -0
- package/dist/nest-integration.d.ts.map +1 -0
- package/dist/node-destination.d.ts +32 -0
- package/dist/node-destination.d.ts.map +1 -0
- package/dist/payload-transforms.d.ts +12 -0
- package/dist/payload-transforms.d.ts.map +1 -0
- package/dist/prisma-integration.d.ts +6 -0
- package/dist/prisma-integration.d.ts.map +1 -0
- package/dist/process-integration.d.ts +4 -0
- package/dist/process-integration.d.ts.map +1 -1
- package/dist/redis-integration.d.ts +7 -0
- package/dist/redis-integration.d.ts.map +1 -0
- package/dist/rotating-file-transport.d.ts +2 -0
- package/dist/rotating-file-transport.d.ts.map +1 -1
- package/dist/stdout-transport.d.ts +2 -0
- package/dist/stdout-transport.d.ts.map +1 -1
- package/dist/worker-transport.d.ts +16 -2
- package/dist/worker-transport.d.ts.map +1 -1
- package/package.json +42 -2
package/README.md
CHANGED
|
@@ -1,26 +1,48 @@
|
|
|
1
1
|
# @loggerjs/node
|
|
2
2
|
|
|
3
|
-
Node transports,
|
|
3
|
+
> Node.js transports, AsyncLocalStorage context, and 16 automatic integrations — re-exports all of `@loggerjs/core`.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@loggerjs/node)
|
|
6
|
+
[](../../LICENSE)
|
|
7
|
+
[](package.json)
|
|
8
|
+
|
|
9
|
+
The Node platform package for [LoggerJS](../../README.md). It re-exports the entire `@loggerjs/core` API and adds stdout/stderr/file/HTTP/syslog/worker transports, an AsyncLocalStorage context bridge, and integrations that turn process crashes, HTTP frameworks, clients, and queues into structured logs — all opt-in.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @loggerjs/node @loggerjs/processors
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`@loggerjs/processors` is optional but recommended for redaction, sampling, and enrichment.
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
4
20
|
|
|
5
21
|
```ts
|
|
6
22
|
import {
|
|
7
23
|
captureProcessIntegration,
|
|
8
24
|
createLogger,
|
|
9
|
-
expressIntegration,
|
|
10
|
-
fastifyIntegration,
|
|
11
25
|
installAsyncLocalStorageContext,
|
|
26
|
+
nodeCompressionPayloadTransform,
|
|
12
27
|
nodeFetchIntegration,
|
|
13
28
|
nodeHttpClientIntegration,
|
|
14
|
-
|
|
15
|
-
rotatingFileTransport,
|
|
29
|
+
nodeHttpTransport,
|
|
16
30
|
stdoutTransport,
|
|
17
31
|
} from "@loggerjs/node";
|
|
18
32
|
|
|
19
|
-
installAsyncLocalStorageContext();
|
|
33
|
+
installAsyncLocalStorageContext(); // once at startup — context follows async execution
|
|
20
34
|
|
|
21
35
|
const logger = createLogger({
|
|
22
|
-
|
|
23
|
-
|
|
36
|
+
category: ["api"],
|
|
37
|
+
level: "info",
|
|
38
|
+
tags: { service: "checkout", env: process.env.NODE_ENV ?? "dev" },
|
|
39
|
+
transports: [
|
|
40
|
+
stdoutTransport(), // one NDJSON line per log
|
|
41
|
+
nodeHttpTransport({
|
|
42
|
+
url: "https://collector.example/logs",
|
|
43
|
+
transformPayload: nodeCompressionPayloadTransform({ format: "brotli" }),
|
|
44
|
+
}),
|
|
45
|
+
],
|
|
24
46
|
integrations: [captureProcessIntegration(), nodeHttpClientIntegration(), nodeFetchIntegration()],
|
|
25
47
|
});
|
|
26
48
|
|
|
@@ -28,26 +50,85 @@ logger.info("server started", { port: 3000 });
|
|
|
28
50
|
await logger.flush();
|
|
29
51
|
```
|
|
30
52
|
|
|
31
|
-
|
|
32
|
-
const infraLogger = createLogger({
|
|
33
|
-
name: "infra",
|
|
34
|
-
transports: [nodeSyslogTransport({ host: "127.0.0.1", port: 514, facility: 16 })],
|
|
35
|
-
});
|
|
36
|
-
```
|
|
53
|
+
### HTTP frameworks
|
|
37
54
|
|
|
38
55
|
```ts
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
transports: [rotatingFileTransport({ path: "audit.log", maxBytes: 10 * 1024 * 1024 })],
|
|
42
|
-
});
|
|
56
|
+
app.use(expressIntegration(logger, { captureAll: true })); // Express middleware
|
|
57
|
+
fastify.register(fastifyIntegration(logger, { captureAll: true })); // Fastify plugin
|
|
43
58
|
```
|
|
44
59
|
|
|
60
|
+
### Other destinations
|
|
61
|
+
|
|
45
62
|
```ts
|
|
46
|
-
|
|
63
|
+
import { nodeSyslogTransport, rotatingFileTransport } from "@loggerjs/node";
|
|
64
|
+
|
|
65
|
+
nodeSyslogTransport({ host: "127.0.0.1", port: 514, facility: 16 });
|
|
66
|
+
rotatingFileTransport({ path: "audit.log", maxBytes: 10 * 1024 * 1024 });
|
|
47
67
|
```
|
|
48
68
|
|
|
69
|
+
## Transports
|
|
70
|
+
|
|
71
|
+
| Transport | Delivers to |
|
|
72
|
+
| --- | --- |
|
|
73
|
+
| `stdoutTransport` / `stderrTransport` | process streams, one NDJSON line per log, drain-aware flush, optional `minLength` buffering, clean `EPIPE` shutdown |
|
|
74
|
+
| `fileTransport` / `rotatingFileTransport` | files, with `mkdir`/`append` controls, optional `sync: true`, crash-path `flushSync`, and size-based rotation |
|
|
75
|
+
| `nodeHttpTransport` | a collector over `fetch`, wrapped in `batchTransport` (batching + retry) |
|
|
76
|
+
| `nodeSyslogTransport` | RFC 5424 syslog over UDP/TCP |
|
|
77
|
+
| `workerTransport` | a worker thread (encodes batches with a codec, optional buffer transfer, ready/ack lifecycle, fallback on worker failure) |
|
|
78
|
+
|
|
79
|
+
File and process-stream transports share the same internal destination logic for
|
|
80
|
+
write callbacks, drain waiting, `minLength` buffering, close, and sync crash
|
|
81
|
+
flush. Use `await flush()` for normal shutdown. Use `flushSync()` only on fatal
|
|
82
|
+
paths, or configure `fileTransport({ sync: true })` when every write must reach
|
|
83
|
+
the filesystem before the log call returns.
|
|
84
|
+
|
|
85
|
+
`workerTransport()` is fire-and-forget unless you opt into lifecycle checks.
|
|
86
|
+
Use `readyTimeoutMs` for workers that send `{ type: "loggerjs:ready" }`, and
|
|
87
|
+
`ackTimeoutMs` for workers that acknowledge `{ type: "loggerjs:batch", id }`
|
|
88
|
+
with `{ type: "loggerjs:batch:ack", id }`. Pending batches fall back or are
|
|
89
|
+
counted as drops when readiness, posting, ack, or worker exit fails. Set
|
|
90
|
+
`autoEnd: false` for shared workers you close elsewhere. Explicit
|
|
91
|
+
`transport.ready()` / `logger.ready()` waits for the ready handshake when
|
|
92
|
+
`readyTimeoutMs` is configured.
|
|
93
|
+
|
|
94
|
+
Call `installLoggerDiagnosticsChannel()` to publish LoggerJS internal
|
|
95
|
+
diagnostics to Node `diagnostics_channel` channels such as `loggerjs.dispatch`,
|
|
96
|
+
`loggerjs.transport`, `loggerjs.flush`, `loggerjs.encode`, and
|
|
97
|
+
`loggerjs.worker`.
|
|
98
|
+
|
|
99
|
+
## Integrations (16)
|
|
100
|
+
|
|
101
|
+
| Group | Integrations |
|
|
102
|
+
| --- | --- |
|
|
103
|
+
| **Process & runtime** | `captureProcessIntegration`, `captureCliIntegration`, `diagnosticsChannelIntegration`, `serverlessIntegration` |
|
|
104
|
+
| **HTTP frameworks** | `expressIntegration`, `fastifyIntegration`, `koaIntegration`, `hapiIntegration`, `nestMiddlewareIntegration` |
|
|
105
|
+
| **Clients** | `nodeFetchIntegration`, `nodeHttpClientIntegration`, `redisIntegration`, `prismaIntegration`, `databaseIntegration` |
|
|
106
|
+
| **Queues** | `queueIntegration`, `bullMqIntegration` |
|
|
107
|
+
|
|
108
|
+
`captureProcessIntegration()` turns uncaught exceptions (fatal), unhandled rejections, warnings, and exit into log events; with `exitOnUncaught` it captures the fatal record, calls `flushSync()`, waits for bounded async `flush()`, then exits. Every integration is tagged `source: "integration:<name>"` and guarded against capture loops.
|
|
109
|
+
|
|
110
|
+
### Context manager
|
|
111
|
+
|
|
49
112
|
```ts
|
|
50
|
-
|
|
113
|
+
import { installAsyncLocalStorageContext, withContext } from "@loggerjs/node";
|
|
114
|
+
|
|
115
|
+
installAsyncLocalStorageContext(); // once at startup
|
|
116
|
+
await withContext({ requestId: "req_123" }, async () => {
|
|
117
|
+
logger.info("request started"); // { requestId } follows across awaits
|
|
118
|
+
});
|
|
51
119
|
```
|
|
52
120
|
|
|
53
|
-
|
|
121
|
+
## Subpath exports
|
|
122
|
+
|
|
123
|
+
Transports — `transport-stdout` · `transport-file` · `transport-rotating-file` · `transport-http` · `transport-syslog` · `transport-worker` · `payload-transforms` · `logger-diagnostics` · `context`
|
|
124
|
+
|
|
125
|
+
Integrations — `integration-process` · `integration-cli` · `integration-diagnostics` · `integration-serverless` · `integration-express` · `integration-fastify` · `integration-koa` · `integration-nest` · `integration-hapi` · `integration-fetch` · `integration-http-client` · `integration-redis` · `integration-prisma` · `integration-database` · `integration-queue` · `integration-bullmq`
|
|
126
|
+
|
|
127
|
+
## Documentation
|
|
128
|
+
|
|
129
|
+
- [Transports](../../docs/TRANSPORTS.md) · [Integrations](../../docs/INTEGRATIONS.md) · [Operations](../../docs/OPERATIONS.md)
|
|
130
|
+
- [Getting Started](../../docs/GETTING-STARTED.md) · [LoggerJS root README](../../README.md)
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
[MIT](../../LICENSE) © JS Kits
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type QueueClientLike, type QueueIntegrationOptions } from "./queue-integration.js";
|
|
2
|
+
export interface BullMqIntegrationOptions extends Omit<QueueIntegrationOptions, "client" | "system" | "methods" | "getQueueName"> {
|
|
3
|
+
client: QueueClientLike & {
|
|
4
|
+
name?: string;
|
|
5
|
+
};
|
|
6
|
+
methods?: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function bullMqIntegration(options: BullMqIntegrationOptions): import("@loggerjs/core").Integration;
|
|
9
|
+
//# sourceMappingURL=bullmq-integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bullmq-integration.d.ts","sourceRoot":"","sources":["../src/bullmq-integration.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC7B,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,wBAAyB,SAAQ,IAAI,CACpD,uBAAuB,EACvB,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,cAAc,CACjD;IACC,MAAM,EAAE,eAAe,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AASD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,wCASlE"}
|
package/dist/file-transport.d.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import { type WriteStream } from "fs";
|
|
2
1
|
import { type Codec, type LoggerLevel, type Transport } from "@loggerjs/core";
|
|
2
|
+
import type { WriteStream } from "fs";
|
|
3
3
|
export interface FileTransportOptions {
|
|
4
4
|
path: string;
|
|
5
5
|
name?: string;
|
|
6
6
|
codec?: Codec<string | Uint8Array>;
|
|
7
7
|
minLevel?: LoggerLevel;
|
|
8
8
|
flags?: string;
|
|
9
|
+
append?: boolean;
|
|
10
|
+
mkdir?: boolean;
|
|
11
|
+
sync?: boolean;
|
|
12
|
+
minLength?: number;
|
|
9
13
|
}
|
|
10
14
|
export interface FileTransport extends Transport {
|
|
11
|
-
stream
|
|
15
|
+
stream?: WriteStream;
|
|
12
16
|
flushSync: () => void;
|
|
13
17
|
}
|
|
14
18
|
export declare function fileTransport(options: FileTransportOptions): FileTransport;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-transport.d.ts","sourceRoot":"","sources":["../src/file-transport.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"file-transport.d.ts","sourceRoot":"","sources":["../src/file-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,KAAK,EAEV,KAAK,WAAW,EAChB,KAAK,SAAS,EACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;AAGtC,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAc,SAAQ,SAAS;IAC9C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAwB1E"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type LoggerLevel, type LoggerLike } from "@loggerjs/core";
|
|
2
|
+
export interface HapiRequestLike {
|
|
3
|
+
method?: string;
|
|
4
|
+
path?: string;
|
|
5
|
+
url?: {
|
|
6
|
+
pathname?: string;
|
|
7
|
+
};
|
|
8
|
+
info?: {
|
|
9
|
+
id?: string;
|
|
10
|
+
received?: number;
|
|
11
|
+
remoteAddress?: string;
|
|
12
|
+
};
|
|
13
|
+
response?: {
|
|
14
|
+
statusCode?: number;
|
|
15
|
+
} | {
|
|
16
|
+
isBoom?: boolean;
|
|
17
|
+
output?: {
|
|
18
|
+
statusCode?: number;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
app?: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
export interface HapiToolkitLike {
|
|
24
|
+
continue: unknown;
|
|
25
|
+
}
|
|
26
|
+
export interface HapiServerLike {
|
|
27
|
+
ext: (event: "onRequest", handler: (request: HapiRequestLike, h: HapiToolkitLike) => unknown) => unknown;
|
|
28
|
+
events?: {
|
|
29
|
+
on?: (event: "response", handler: (request: HapiRequestLike) => void) => unknown;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export interface HapiIntegrationOptions {
|
|
33
|
+
minStatus?: number;
|
|
34
|
+
captureAll?: boolean;
|
|
35
|
+
bindContext?: boolean;
|
|
36
|
+
getRequestId?: (request: HapiRequestLike) => string | undefined;
|
|
37
|
+
context?: (request: HapiRequestLike) => Record<string, unknown> | undefined;
|
|
38
|
+
level?: (status: number, request: HapiRequestLike) => LoggerLevel;
|
|
39
|
+
}
|
|
40
|
+
export declare function hapiIntegration(logger: LoggerLike, options?: HapiIntegrationOptions): {
|
|
41
|
+
name: string;
|
|
42
|
+
register(server: HapiServerLike): void;
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=hapi-integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hapi-integration.d.ts","sourceRoot":"","sources":["../src/hapi-integration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,WAAW,EAAE,KAAK,UAAU,EAAgB,MAAM,gBAAgB,CAAC;AAE9F,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,IAAI,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,QAAQ,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE;YAAE,UAAU,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IAC5F,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,CACH,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,CAAC,EAAE,eAAe,KAAK,OAAO,KAC/D,OAAO,CAAC;IACb,MAAM,CAAC,EAAE;QACP,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,KAAK,OAAO,CAAC;KAClF,CAAC;CACH;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,MAAM,GAAG,SAAS,CAAC;IAChE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC5E,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,KAAK,WAAW,CAAC;CACnE;AAkBD,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,GAAE,sBAA2B;;qBAQnE,cAAc;EAsClC"}
|
package/dist/http-transport.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type BatchTransportOptions, type Codec, type LoggerLevel, type Transport } from "@loggerjs/core";
|
|
1
|
+
import { type BatchTransportOptions, type Codec, type LoggerLevel, type PayloadTransform, type Transport } from "@loggerjs/core";
|
|
2
2
|
export interface NodeHttpTransportOptions extends BatchTransportOptions {
|
|
3
3
|
url: string;
|
|
4
4
|
name?: string;
|
|
@@ -7,6 +7,7 @@ export interface NodeHttpTransportOptions extends BatchTransportOptions {
|
|
|
7
7
|
codec?: Codec<string | Uint8Array>;
|
|
8
8
|
minLevel?: LoggerLevel;
|
|
9
9
|
fetchFn?: typeof fetch;
|
|
10
|
+
transformPayload?: PayloadTransform | readonly PayloadTransform[];
|
|
10
11
|
}
|
|
11
12
|
export declare function nodeHttpTransport(options: NodeHttpTransportOptions): Transport;
|
|
12
13
|
//# sourceMappingURL=http-transport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-transport.d.ts","sourceRoot":"","sources":["../src/http-transport.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"http-transport.d.ts","sourceRoot":"","sources":["../src/http-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,qBAAqB,EAC1B,KAAK,KAAK,EAGV,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACf,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,wBAAyB,SAAQ,qBAAqB;IACrE,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,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,SAAS,gBAAgB,EAAE,CAAC;CACnE;AAOD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,SAAS,CAiD9E"}
|