@wgtechlabs/log-engine 2.1.0 → 2.1.1
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/dist/cjs/__tests__/async-test-utils.cjs +276 -0
- package/dist/cjs/__tests__/async-test-utils.d.ts +51 -0
- package/dist/cjs/__tests__/async-test-utils.d.ts.map +1 -0
- package/dist/cjs/__tests__/async-test-utils.js.map +1 -0
- package/dist/cjs/__tests__/redaction/test-utils.cjs +72 -0
- package/dist/cjs/__tests__/redaction/test-utils.d.ts +33 -0
- package/dist/cjs/__tests__/redaction/test-utils.d.ts.map +1 -0
- package/dist/cjs/__tests__/redaction/test-utils.js.map +1 -0
- package/dist/cjs/__tests__/test-utils.cjs +49 -0
- package/dist/cjs/__tests__/test-utils.d.ts +41 -0
- package/dist/cjs/__tests__/test-utils.d.ts.map +1 -0
- package/dist/cjs/__tests__/test-utils.js.map +1 -0
- package/dist/{formatter/colors.js → cjs/formatter/colors.cjs} +1 -0
- package/dist/cjs/formatter/colors.d.ts.map +1 -0
- package/dist/cjs/formatter/colors.js.map +1 -0
- package/dist/{formatter/data-formatter.js → cjs/formatter/data-formatter.cjs} +1 -0
- package/dist/cjs/formatter/data-formatter.d.ts.map +1 -0
- package/dist/cjs/formatter/data-formatter.js.map +1 -0
- package/dist/{formatter/index.js → cjs/formatter/index.cjs} +6 -5
- package/dist/cjs/formatter/index.d.ts.map +1 -0
- package/dist/cjs/formatter/index.js.map +1 -0
- package/dist/{formatter/message-formatter.js → cjs/formatter/message-formatter.cjs} +5 -4
- package/dist/cjs/formatter/message-formatter.d.ts.map +1 -0
- package/dist/cjs/formatter/message-formatter.js.map +1 -0
- package/dist/{formatter/timestamp.js → cjs/formatter/timestamp.cjs} +1 -0
- package/dist/cjs/formatter/timestamp.d.ts.map +1 -0
- package/dist/cjs/formatter/timestamp.js.map +1 -0
- package/dist/{index.js → cjs/index.cjs} +5 -4
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/{logger/advanced-outputs.js → cjs/logger/advanced-outputs.cjs} +1 -0
- package/dist/cjs/logger/advanced-outputs.d.ts.map +1 -0
- package/dist/cjs/logger/advanced-outputs.js.map +1 -0
- package/dist/{logger/config.js → cjs/logger/config.cjs} +4 -3
- package/dist/cjs/logger/config.d.ts.map +1 -0
- package/dist/cjs/logger/config.js.map +1 -0
- package/dist/{logger/core.js → cjs/logger/core.cjs} +7 -6
- package/dist/cjs/logger/core.d.ts.map +1 -0
- package/dist/cjs/logger/core.js.map +1 -0
- package/dist/{logger/environment.js → cjs/logger/environment.cjs} +2 -1
- package/dist/cjs/logger/environment.d.ts.map +1 -0
- package/dist/cjs/logger/environment.js.map +1 -0
- package/dist/{logger/filtering.js → cjs/logger/filtering.cjs} +2 -1
- package/dist/cjs/logger/filtering.d.ts.map +1 -0
- package/dist/cjs/logger/filtering.js.map +1 -0
- package/dist/{logger/index.js → cjs/logger/index.cjs} +6 -5
- package/dist/cjs/logger/index.d.ts.map +1 -0
- package/dist/cjs/logger/index.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/{redaction/config.js → cjs/redaction/config.cjs} +1 -0
- package/dist/cjs/redaction/config.d.ts.map +1 -0
- package/dist/cjs/redaction/config.js.map +1 -0
- package/dist/{redaction/index.js → cjs/redaction/index.cjs} +3 -2
- package/dist/cjs/redaction/index.d.ts.map +1 -0
- package/dist/cjs/redaction/index.js.map +1 -0
- package/dist/{redaction/redactor.js → cjs/redaction/redactor.cjs} +2 -1
- package/dist/cjs/redaction/redactor.d.ts.map +1 -0
- package/dist/cjs/redaction/redactor.js.map +1 -0
- package/dist/{types/index.js → cjs/types/index.cjs} +1 -0
- package/dist/cjs/types/index.d.ts.map +1 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/esm/__tests__/async-test-utils.d.ts +51 -0
- package/dist/esm/__tests__/async-test-utils.d.ts.map +1 -0
- package/dist/esm/__tests__/async-test-utils.js +231 -0
- package/dist/esm/__tests__/async-test-utils.js.map +1 -0
- package/dist/esm/__tests__/redaction/test-utils.d.ts +33 -0
- package/dist/esm/__tests__/redaction/test-utils.d.ts.map +1 -0
- package/dist/esm/__tests__/redaction/test-utils.js +65 -0
- package/dist/esm/__tests__/redaction/test-utils.js.map +1 -0
- package/dist/esm/__tests__/test-utils.d.ts +41 -0
- package/dist/esm/__tests__/test-utils.d.ts.map +1 -0
- package/dist/esm/__tests__/test-utils.js +42 -0
- package/dist/esm/__tests__/test-utils.js.map +1 -0
- package/dist/esm/formatter/colors.d.ts +32 -0
- package/dist/esm/formatter/colors.d.ts.map +1 -0
- package/dist/esm/formatter/colors.js +32 -0
- package/dist/esm/formatter/colors.js.map +1 -0
- package/dist/esm/formatter/data-formatter.d.ts +26 -0
- package/dist/esm/formatter/data-formatter.d.ts.map +1 -0
- package/dist/esm/formatter/data-formatter.js +50 -0
- package/dist/esm/formatter/data-formatter.js.map +1 -0
- package/dist/esm/formatter/index.d.ts +10 -0
- package/dist/esm/formatter/index.d.ts.map +1 -0
- package/dist/esm/formatter/index.js +11 -0
- package/dist/esm/formatter/index.js.map +1 -0
- package/dist/esm/formatter/message-formatter.d.ts +41 -0
- package/dist/esm/formatter/message-formatter.d.ts.map +1 -0
- package/dist/esm/formatter/message-formatter.js +84 -0
- package/dist/esm/formatter/message-formatter.js.map +1 -0
- package/dist/esm/formatter/timestamp.d.ts +27 -0
- package/dist/esm/formatter/timestamp.d.ts.map +1 -0
- package/dist/esm/formatter/timestamp.js +36 -0
- package/dist/esm/formatter/timestamp.js.map +1 -0
- package/dist/esm/index.d.ts +180 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +194 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/logger/advanced-outputs.d.ts +159 -0
- package/dist/esm/logger/advanced-outputs.d.ts.map +1 -0
- package/dist/esm/logger/advanced-outputs.js +542 -0
- package/dist/esm/logger/advanced-outputs.js.map +1 -0
- package/dist/esm/logger/config.d.ts +42 -0
- package/dist/esm/logger/config.d.ts.map +1 -0
- package/dist/esm/logger/config.js +101 -0
- package/dist/esm/logger/config.js.map +1 -0
- package/dist/esm/logger/core.d.ts +152 -0
- package/dist/esm/logger/core.d.ts.map +1 -0
- package/dist/esm/logger/core.js +367 -0
- package/dist/esm/logger/core.js.map +1 -0
- package/dist/esm/logger/environment.d.ts +36 -0
- package/dist/esm/logger/environment.d.ts.map +1 -0
- package/dist/esm/logger/environment.js +58 -0
- package/dist/esm/logger/environment.js.map +1 -0
- package/dist/esm/logger/filtering.d.ts +36 -0
- package/dist/esm/logger/filtering.d.ts.map +1 -0
- package/dist/esm/logger/filtering.js +77 -0
- package/dist/esm/logger/filtering.js.map +1 -0
- package/dist/esm/logger/index.d.ts +10 -0
- package/dist/esm/logger/index.d.ts.map +1 -0
- package/dist/esm/logger/index.js +11 -0
- package/dist/esm/logger/index.js.map +1 -0
- package/dist/esm/redaction/config.d.ts +29 -0
- package/dist/esm/redaction/config.d.ts.map +1 -0
- package/dist/esm/redaction/config.js +92 -0
- package/dist/esm/redaction/config.js.map +1 -0
- package/dist/esm/redaction/index.d.ts +8 -0
- package/dist/esm/redaction/index.d.ts.map +1 -0
- package/dist/esm/redaction/index.js +7 -0
- package/dist/esm/redaction/index.js.map +1 -0
- package/dist/esm/redaction/redactor.d.ts +99 -0
- package/dist/esm/redaction/redactor.d.ts.map +1 -0
- package/dist/esm/redaction/redactor.js +259 -0
- package/dist/esm/redaction/redactor.js.map +1 -0
- package/dist/esm/types/index.d.ts +310 -0
- package/dist/esm/types/index.d.ts.map +1 -0
- package/dist/esm/types/index.js +41 -0
- package/dist/esm/types/index.js.map +1 -0
- package/package.json +19 -5
- package/dist/formatter/colors.d.ts.map +0 -1
- package/dist/formatter/data-formatter.d.ts.map +0 -1
- package/dist/formatter/index.d.ts.map +0 -1
- package/dist/formatter/message-formatter.d.ts.map +0 -1
- package/dist/formatter/timestamp.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/logger/advanced-outputs.d.ts.map +0 -1
- package/dist/logger/config.d.ts.map +0 -1
- package/dist/logger/core.d.ts.map +0 -1
- package/dist/logger/environment.d.ts.map +0 -1
- package/dist/logger/filtering.d.ts.map +0 -1
- package/dist/logger/index.d.ts.map +0 -1
- package/dist/redaction/config.d.ts.map +0 -1
- package/dist/redaction/index.d.ts.map +0 -1
- package/dist/redaction/redactor.d.ts.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- /package/dist/{formatter → cjs/formatter}/colors.d.ts +0 -0
- /package/dist/{formatter → cjs/formatter}/data-formatter.d.ts +0 -0
- /package/dist/{formatter → cjs/formatter}/index.d.ts +0 -0
- /package/dist/{formatter → cjs/formatter}/message-formatter.d.ts +0 -0
- /package/dist/{formatter → cjs/formatter}/timestamp.d.ts +0 -0
- /package/dist/{index.d.ts → cjs/index.d.ts} +0 -0
- /package/dist/{logger → cjs/logger}/advanced-outputs.d.ts +0 -0
- /package/dist/{logger → cjs/logger}/config.d.ts +0 -0
- /package/dist/{logger → cjs/logger}/core.d.ts +0 -0
- /package/dist/{logger → cjs/logger}/environment.d.ts +0 -0
- /package/dist/{logger → cjs/logger}/filtering.d.ts +0 -0
- /package/dist/{logger → cjs/logger}/index.d.ts +0 -0
- /package/dist/{redaction → cjs/redaction}/config.d.ts +0 -0
- /package/dist/{redaction → cjs/redaction}/index.d.ts +0 -0
- /package/dist/{redaction → cjs/redaction}/redactor.d.ts +0 -0
- /package/dist/{types → cjs/types}/index.d.ts +0 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Advanced output handlers for log-engine
|
|
3
|
+
* Provides file, HTTP, and other production-ready output handlers
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import type { FileOutputConfig, HttpOutputConfig } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* Secure filesystem operations for logging operations
|
|
9
|
+
*
|
|
10
|
+
* SECURITY NOTE: These functions implement comprehensive path validation and access controls
|
|
11
|
+
* to prevent path traversal attacks, directory injection, and unauthorized file access.
|
|
12
|
+
* ESLint security rules are disabled for specific fs operations because:
|
|
13
|
+
*
|
|
14
|
+
* 1. All paths are validated through validatePath() which:
|
|
15
|
+
* - Prevents directory traversal (../)
|
|
16
|
+
* - Restricts access to predefined safe directories
|
|
17
|
+
* - Blocks access to system directories
|
|
18
|
+
* - Normalizes and resolves paths securely
|
|
19
|
+
*
|
|
20
|
+
* 2. The logging library requires dynamic file paths by design (user-configurable log files)
|
|
21
|
+
* 3. All operations are wrapped in try-catch with comprehensive error handling
|
|
22
|
+
* 4. File operations are restricted to log and temp directories only
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Predefined safe base directories for different operation types
|
|
26
|
+
* Restricted to specific subdirectories to prevent unauthorized access
|
|
27
|
+
*/
|
|
28
|
+
declare const SAFE_BASE_DIRS: {
|
|
29
|
+
readonly LOG_FILES: readonly [string, string, string];
|
|
30
|
+
readonly TEMP_FILES: readonly [string, string, string, string];
|
|
31
|
+
readonly CONFIG_FILES: readonly [string, string, string];
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Validates file path with comprehensive security checks
|
|
35
|
+
* Prevents path traversal, restricts to safe directories, blocks system paths
|
|
36
|
+
*/
|
|
37
|
+
declare function validatePath(filePath: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Secure file existence check
|
|
40
|
+
* Uses fs.accessSync instead of fs.existsSync for better security practices
|
|
41
|
+
*/
|
|
42
|
+
declare function secureExistsSync(filePath: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Secure directory creation with recursive option support
|
|
45
|
+
* Restricted to log and temp directories only
|
|
46
|
+
*/
|
|
47
|
+
declare function secureMkdirSync(dirPath: string, options?: {
|
|
48
|
+
recursive?: boolean;
|
|
49
|
+
}): void;
|
|
50
|
+
/**
|
|
51
|
+
* Secure file stat operation
|
|
52
|
+
* Returns file system statistics for validated paths only
|
|
53
|
+
*/
|
|
54
|
+
declare function secureStatSync(filePath: string): fs.Stats;
|
|
55
|
+
/**
|
|
56
|
+
* Secure file write operation
|
|
57
|
+
* Validates path and data before writing to prevent injection attacks
|
|
58
|
+
*/
|
|
59
|
+
declare function secureWriteFileSync(filePath: string, data: string, options?: {
|
|
60
|
+
flag?: string;
|
|
61
|
+
}): void;
|
|
62
|
+
/**
|
|
63
|
+
* Secure file deletion
|
|
64
|
+
* Restricted to log and temp files only for safety
|
|
65
|
+
*/
|
|
66
|
+
declare function secureUnlinkSync(filePath: string): void;
|
|
67
|
+
/**
|
|
68
|
+
* Secure file rename/move operation
|
|
69
|
+
* Both source and destination must be in safe directories
|
|
70
|
+
*/
|
|
71
|
+
declare function secureRenameSync(oldPath: string, newPath: string): void;
|
|
72
|
+
/**
|
|
73
|
+
* File output handler with rotation support and concurrency protection
|
|
74
|
+
* Implements atomic file operations and write queuing to prevent corruption
|
|
75
|
+
*/
|
|
76
|
+
export declare class FileOutputHandler {
|
|
77
|
+
private config;
|
|
78
|
+
private currentFileSize;
|
|
79
|
+
private rotationInProgress;
|
|
80
|
+
private writeQueue;
|
|
81
|
+
constructor(config: FileOutputConfig);
|
|
82
|
+
/**
|
|
83
|
+
* Default formatter for file output
|
|
84
|
+
*/
|
|
85
|
+
private defaultFormatter;
|
|
86
|
+
/**
|
|
87
|
+
* Write log to file with rotation support and concurrency protection
|
|
88
|
+
* Queues writes during rotation to prevent file corruption
|
|
89
|
+
*/
|
|
90
|
+
write: (level: string, message: string, data?: unknown) => void;
|
|
91
|
+
/**
|
|
92
|
+
* Write to file with concurrency protection and rotation check
|
|
93
|
+
* If rotation is in progress, messages are queued to prevent corruption
|
|
94
|
+
*/
|
|
95
|
+
private writeToFile;
|
|
96
|
+
/**
|
|
97
|
+
* Process queued writes after rotation completes
|
|
98
|
+
*/
|
|
99
|
+
private processWriteQueue;
|
|
100
|
+
/**
|
|
101
|
+
* Rotate log files when size limit is reached
|
|
102
|
+
* Implements concurrency protection to prevent corruption during rotation
|
|
103
|
+
*/
|
|
104
|
+
private rotateFile;
|
|
105
|
+
/**
|
|
106
|
+
* Clean up resources and process any remaining queued writes
|
|
107
|
+
*/
|
|
108
|
+
destroy(): void;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* HTTP output handler for sending logs to remote endpoints
|
|
112
|
+
*/
|
|
113
|
+
export declare class HttpOutputHandler {
|
|
114
|
+
private config;
|
|
115
|
+
private logBuffer;
|
|
116
|
+
private flushTimeout;
|
|
117
|
+
constructor(config: HttpOutputConfig);
|
|
118
|
+
/**
|
|
119
|
+
* Default formatter for HTTP output
|
|
120
|
+
*/
|
|
121
|
+
private defaultFormatter;
|
|
122
|
+
/**
|
|
123
|
+
* Write log to HTTP endpoint with batching support
|
|
124
|
+
*/
|
|
125
|
+
write: (level: string, message: string, data?: unknown) => void;
|
|
126
|
+
/**
|
|
127
|
+
* Flush buffered logs to HTTP endpoint
|
|
128
|
+
*/
|
|
129
|
+
private flush;
|
|
130
|
+
/**
|
|
131
|
+
* Send HTTP request with appropriate method based on environment
|
|
132
|
+
*/
|
|
133
|
+
private sendHttpRequest;
|
|
134
|
+
/**
|
|
135
|
+
* Fallback HTTP implementation for Node.js environments without fetch
|
|
136
|
+
*/
|
|
137
|
+
private sendHttpRequestNodeJS;
|
|
138
|
+
/**
|
|
139
|
+
* Cleanup method to prevent memory leaks
|
|
140
|
+
*/
|
|
141
|
+
destroy(): void;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Returns a logging handler function based on the specified type and configuration.
|
|
145
|
+
*
|
|
146
|
+
* Supported types are:
|
|
147
|
+
* - `'console'`: Logs to the console using the appropriate method for the log level.
|
|
148
|
+
* - `'silent'`: Returns a no-op handler that discards all logs.
|
|
149
|
+
* - `'file'`: Writes logs to a file with optional rotation; requires `filePath` in config.
|
|
150
|
+
* - `'http'`: Sends logs to a remote HTTP endpoint; requires `url` in config.
|
|
151
|
+
*
|
|
152
|
+
* If required configuration is missing or initialization fails, logs an error and returns either a fallback handler or `null`.
|
|
153
|
+
*
|
|
154
|
+
* @param type - The type of output handler to create (`'console'`, `'silent'`, `'file'`, or `'http'`)
|
|
155
|
+
* @returns A log handler function or `null` if the handler cannot be created
|
|
156
|
+
*/
|
|
157
|
+
export declare function createBuiltInHandler(type: string, config?: Record<string, unknown>): ((level: string, message: string, data?: unknown) => void) | null;
|
|
158
|
+
export { secureExistsSync, secureMkdirSync, secureStatSync, secureWriteFileSync, secureUnlinkSync, secureRenameSync, validatePath, SAFE_BASE_DIRS };
|
|
159
|
+
//# sourceMappingURL=advanced-outputs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advanced-outputs.d.ts","sourceRoot":"","sources":["../../../src/logger/advanced-outputs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAGzB,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAuBnE;;;;;;;;;;;;;;;;GAgBG;AAEH;;;GAGG;AACH,QAAA,MAAM,cAAc;;;;CAIV,CAAC;AAEX;;;GAGG;AACH,iBAAS,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAqC9C;AAED;;;GAGG;AACH,iBAAS,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CASnD;AAED;;;GAGG;AACH,iBAAS,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAWjF;AAED;;;GAGG;AACH,iBAAS,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE,CAAC,KAAK,CAUlD;AAED;;;GAGG;AACH,iBAAS,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAgB9F;AAED;;;GAGG;AACH,iBAAS,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAkBhD;AAED;;;GAGG;AACH,iBAAS,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAoBhE;AAED;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,UAAU,CAAiE;gBAEvE,MAAM,EAAE,gBAAgB;IA6BpC;;SAEK;IACL,OAAO,CAAC,gBAAgB,CAItB;IAEF;;;SAGK;IACE,KAAK,GAAI,OAAO,MAAM,EAAE,SAAS,MAAM,EAAE,OAAO,OAAO,KAAG,IAAI,CAcnE;IAEF;;;OAGG;IACH,OAAO,CAAC,WAAW;IAgBnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;SAGK;IACL,OAAO,CAAC,UAAU;IAwClB;;OAEG;IACI,OAAO,IAAI,IAAI;CAUvB;AAED;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,YAAY,CAA+B;gBAEvC,MAAM,EAAE,gBAAgB;IAYpC;;SAEK;IACL,OAAO,CAAC,gBAAgB,CAStB;IAEF;;SAEK;IACE,KAAK,GAAI,OAAO,MAAM,EAAE,SAAS,MAAM,EAAE,OAAO,OAAO,KAAG,IAAI,CA0BnE;IAEF;;SAEK;IACL,OAAO,CAAC,KAAK;IAqBb;;SAEK;IACL,OAAO,CAAC,eAAe;IAiBvB;;SAEK;IACL,OAAO,CAAC,qBAAqB;IAgD7B;;OAEG;IACI,OAAO,IAAI,IAAI;CAQvB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CA2CtJ;AAGD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACf,CAAC"}
|