openclaw-observability 1.0.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/dist/config.d.ts +60 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +140 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1114 -0
- package/dist/index.js.map +1 -0
- package/dist/redaction.d.ts +20 -0
- package/dist/redaction.d.ts.map +1 -0
- package/dist/redaction.js +93 -0
- package/dist/redaction.js.map +1 -0
- package/dist/security/chain-detector.d.ts +37 -0
- package/dist/security/chain-detector.d.ts.map +1 -0
- package/dist/security/chain-detector.js +187 -0
- package/dist/security/chain-detector.js.map +1 -0
- package/dist/security/rules.d.ts +22 -0
- package/dist/security/rules.d.ts.map +1 -0
- package/dist/security/rules.js +479 -0
- package/dist/security/rules.js.map +1 -0
- package/dist/security/scanner.d.ts +47 -0
- package/dist/security/scanner.d.ts.map +1 -0
- package/dist/security/scanner.js +150 -0
- package/dist/security/scanner.js.map +1 -0
- package/dist/security/types.d.ts +47 -0
- package/dist/security/types.d.ts.map +1 -0
- package/dist/security/types.js +23 -0
- package/dist/security/types.js.map +1 -0
- package/dist/storage/buffer.d.ts +64 -0
- package/dist/storage/buffer.d.ts.map +1 -0
- package/dist/storage/buffer.js +120 -0
- package/dist/storage/buffer.js.map +1 -0
- package/dist/storage/duckdb-local-writer.d.ts +26 -0
- package/dist/storage/duckdb-local-writer.d.ts.map +1 -0
- package/dist/storage/duckdb-local-writer.js +454 -0
- package/dist/storage/duckdb-local-writer.js.map +1 -0
- package/dist/storage/mysql-writer.d.ts +55 -0
- package/dist/storage/mysql-writer.d.ts.map +1 -0
- package/dist/storage/mysql-writer.js +287 -0
- package/dist/storage/mysql-writer.js.map +1 -0
- package/dist/storage/schema.d.ts +13 -0
- package/dist/storage/schema.d.ts.map +1 -0
- package/dist/storage/schema.js +94 -0
- package/dist/storage/schema.js.map +1 -0
- package/dist/storage/writer.d.ts +31 -0
- package/dist/storage/writer.d.ts.map +1 -0
- package/dist/storage/writer.js +7 -0
- package/dist/storage/writer.js.map +1 -0
- package/dist/types.d.ts +72 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +44 -0
- package/dist/types.js.map +1 -0
- package/dist/web/api.d.ts +115 -0
- package/dist/web/api.d.ts.map +1 -0
- package/dist/web/api.js +219 -0
- package/dist/web/api.js.map +1 -0
- package/dist/web/routes.d.ts +20 -0
- package/dist/web/routes.d.ts.map +1 -0
- package/dist/web/routes.js +175 -0
- package/dist/web/routes.js.map +1 -0
- package/dist/web/ui.d.ts +9 -0
- package/dist/web/ui.d.ts.map +1 -0
- package/dist/web/ui.js +1327 -0
- package/dist/web/ui.js.map +1 -0
- package/openclaw.plugin.json +231 -0
- package/package.json +41 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin configuration schema and defaults
|
|
3
|
+
*/
|
|
4
|
+
/** MySQL connection config */
|
|
5
|
+
export interface MySQLConfig {
|
|
6
|
+
host: string;
|
|
7
|
+
port: number;
|
|
8
|
+
user: string;
|
|
9
|
+
password: string;
|
|
10
|
+
database: string;
|
|
11
|
+
}
|
|
12
|
+
/** Local DuckDB config */
|
|
13
|
+
export interface DuckDBConfig {
|
|
14
|
+
/** Database file path (':memory:' for in-memory mode) */
|
|
15
|
+
path: string;
|
|
16
|
+
}
|
|
17
|
+
/** Buffer config */
|
|
18
|
+
export interface BufferConfig {
|
|
19
|
+
/** Batch write threshold (number of records) */
|
|
20
|
+
batchSize: number;
|
|
21
|
+
/** Flush interval (milliseconds) */
|
|
22
|
+
flushIntervalMs: number;
|
|
23
|
+
}
|
|
24
|
+
/** Redaction config */
|
|
25
|
+
export interface RedactionConfig {
|
|
26
|
+
/** Whether redaction is enabled */
|
|
27
|
+
enabled: boolean;
|
|
28
|
+
/** Redaction pattern list (case-insensitive regex) */
|
|
29
|
+
patterns: string[];
|
|
30
|
+
}
|
|
31
|
+
/** Security detection config */
|
|
32
|
+
export interface SecurityPluginConfig {
|
|
33
|
+
/** Whether security scanning is enabled */
|
|
34
|
+
enabled: boolean;
|
|
35
|
+
/** Enabled rule categories */
|
|
36
|
+
rules: {
|
|
37
|
+
secretLeakage: boolean;
|
|
38
|
+
highRiskOps: boolean;
|
|
39
|
+
promptInjection: boolean;
|
|
40
|
+
chainDetection: boolean;
|
|
41
|
+
};
|
|
42
|
+
/** Domain whitelist for external request detection */
|
|
43
|
+
domainWhitelist: string[];
|
|
44
|
+
}
|
|
45
|
+
/** Full plugin config */
|
|
46
|
+
export interface AuditPluginConfig {
|
|
47
|
+
/** Storage mode: local (embedded, zero config) | remote (external MySQL) */
|
|
48
|
+
mode: 'local' | 'remote';
|
|
49
|
+
mysql: MySQLConfig;
|
|
50
|
+
duckdb: DuckDBConfig;
|
|
51
|
+
buffer: BufferConfig;
|
|
52
|
+
redaction: RedactionConfig;
|
|
53
|
+
security: SecurityPluginConfig;
|
|
54
|
+
}
|
|
55
|
+
/** Default DuckDB path */
|
|
56
|
+
export declare const DEFAULT_DUCKDB_PATH: string;
|
|
57
|
+
/** Default config */
|
|
58
|
+
export declare const DEFAULT_CONFIG: AuditPluginConfig;
|
|
59
|
+
export declare function resolveConfig(userConfig: Partial<AuditPluginConfig> | undefined): AuditPluginConfig;
|
|
60
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,8BAA8B;AAC9B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,0BAA0B;AAC1B,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,oBAAoB;AACpB,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,uBAAuB;AACvB,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,gCAAgC;AAChC,MAAM,WAAW,oBAAoB;IACnC,2CAA2C;IAC3C,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,KAAK,EAAE;QACL,aAAa,EAAE,OAAO,CAAC;QACvB,WAAW,EAAE,OAAO,CAAC;QACrB,eAAe,EAAE,OAAO,CAAC;QACzB,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,sDAAsD;IACtD,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,yBAAyB;AACzB,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,eAAe,CAAC;IAC3B,QAAQ,EAAE,oBAAoB,CAAC;CAChC;AAED,0BAA0B;AAC1B,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AAEF,qBAAqB;AACrB,eAAO,MAAM,cAAc,EAAE,iBA6C5B,CAAC;AAeF,wBAAgB,aAAa,CAC3B,UAAU,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,SAAS,GACjD,iBAAiB,CAkCnB"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Plugin configuration schema and defaults
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.DEFAULT_CONFIG = exports.DEFAULT_DUCKDB_PATH = void 0;
|
|
40
|
+
exports.resolveConfig = resolveConfig;
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const os = __importStar(require("os"));
|
|
43
|
+
/** Default DuckDB path */
|
|
44
|
+
exports.DEFAULT_DUCKDB_PATH = path.join(os.homedir(), '.openclaw', 'audit.duckdb');
|
|
45
|
+
/** Default config */
|
|
46
|
+
exports.DEFAULT_CONFIG = {
|
|
47
|
+
mode: 'local', // default: local DuckDB, zero config
|
|
48
|
+
mysql: {
|
|
49
|
+
host: 'localhost',
|
|
50
|
+
port: 3306,
|
|
51
|
+
user: 'root',
|
|
52
|
+
password: '',
|
|
53
|
+
database: 'openclaw_audit',
|
|
54
|
+
},
|
|
55
|
+
duckdb: {
|
|
56
|
+
path: exports.DEFAULT_DUCKDB_PATH,
|
|
57
|
+
},
|
|
58
|
+
buffer: {
|
|
59
|
+
batchSize: 50,
|
|
60
|
+
flushIntervalMs: 30000,
|
|
61
|
+
},
|
|
62
|
+
redaction: {
|
|
63
|
+
enabled: true,
|
|
64
|
+
patterns: [
|
|
65
|
+
'api_key',
|
|
66
|
+
'api[-_]?secret',
|
|
67
|
+
'password',
|
|
68
|
+
'passwd',
|
|
69
|
+
'access_token',
|
|
70
|
+
'auth_token',
|
|
71
|
+
'refresh_token',
|
|
72
|
+
'bearer_token',
|
|
73
|
+
'client_secret',
|
|
74
|
+
'app_secret',
|
|
75
|
+
'secret_key',
|
|
76
|
+
'authorization',
|
|
77
|
+
'private_key',
|
|
78
|
+
'credential',
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
security: {
|
|
82
|
+
enabled: true,
|
|
83
|
+
rules: {
|
|
84
|
+
secretLeakage: true,
|
|
85
|
+
highRiskOps: true,
|
|
86
|
+
promptInjection: true,
|
|
87
|
+
chainDetection: true,
|
|
88
|
+
},
|
|
89
|
+
domainWhitelist: [],
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Smart mode inference:
|
|
94
|
+
* - User explicitly specified -> use user value
|
|
95
|
+
* - Not specified but valid MySQL config provided -> auto-switch to remote
|
|
96
|
+
* - Otherwise -> local (zero config)
|
|
97
|
+
*/
|
|
98
|
+
function inferMode(userConfig) {
|
|
99
|
+
if (userConfig.mode)
|
|
100
|
+
return userConfig.mode;
|
|
101
|
+
const m = userConfig.mysql;
|
|
102
|
+
if (m && m.host && m.host !== 'localhost' && m.password)
|
|
103
|
+
return 'remote';
|
|
104
|
+
return 'local';
|
|
105
|
+
}
|
|
106
|
+
function resolveConfig(userConfig) {
|
|
107
|
+
if (!userConfig) {
|
|
108
|
+
return { ...exports.DEFAULT_CONFIG };
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
mode: inferMode(userConfig),
|
|
112
|
+
mysql: {
|
|
113
|
+
...exports.DEFAULT_CONFIG.mysql,
|
|
114
|
+
...userConfig.mysql,
|
|
115
|
+
},
|
|
116
|
+
duckdb: {
|
|
117
|
+
...exports.DEFAULT_CONFIG.duckdb,
|
|
118
|
+
...userConfig.duckdb,
|
|
119
|
+
},
|
|
120
|
+
buffer: {
|
|
121
|
+
...exports.DEFAULT_CONFIG.buffer,
|
|
122
|
+
...userConfig.buffer,
|
|
123
|
+
},
|
|
124
|
+
redaction: {
|
|
125
|
+
...exports.DEFAULT_CONFIG.redaction,
|
|
126
|
+
...userConfig.redaction,
|
|
127
|
+
patterns: userConfig.redaction?.patterns ?? exports.DEFAULT_CONFIG.redaction.patterns,
|
|
128
|
+
},
|
|
129
|
+
security: {
|
|
130
|
+
...exports.DEFAULT_CONFIG.security,
|
|
131
|
+
...userConfig.security,
|
|
132
|
+
rules: {
|
|
133
|
+
...exports.DEFAULT_CONFIG.security.rules,
|
|
134
|
+
...(userConfig.security?.rules),
|
|
135
|
+
},
|
|
136
|
+
domainWhitelist: userConfig.security?.domainWhitelist ?? exports.DEFAULT_CONFIG.security.domainWhitelist,
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgIH,sCAoCC;AAlKD,2CAA6B;AAC7B,uCAAyB;AA2DzB,0BAA0B;AACb,QAAA,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAC1C,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,cAAc,CAC1C,CAAC;AAEF,qBAAqB;AACR,QAAA,cAAc,GAAsB;IAC/C,IAAI,EAAE,OAAO,EAAG,qCAAqC;IACrD,KAAK,EAAE;QACL,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,EAAE;QACZ,QAAQ,EAAE,gBAAgB;KAC3B;IACD,MAAM,EAAE;QACN,IAAI,EAAE,2BAAmB;KAC1B;IACD,MAAM,EAAE;QACN,SAAS,EAAE,EAAE;QACb,eAAe,EAAE,KAAK;KACvB;IACD,SAAS,EAAE;QACT,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE;YACR,SAAS;YACT,gBAAgB;YAChB,UAAU;YACV,QAAQ;YACR,cAAc;YACd,YAAY;YACZ,eAAe;YACf,cAAc;YACd,eAAe;YACf,YAAY;YACZ,YAAY;YACZ,eAAe;YACf,aAAa;YACb,YAAY;SACb;KACF;IACD,QAAQ,EAAE;QACR,OAAO,EAAE,IAAI;QACb,KAAK,EAAE;YACL,aAAa,EAAE,IAAI;YACnB,WAAW,EAAE,IAAI;YACjB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,IAAI;SACrB;QACD,eAAe,EAAE,EAAE;KACpB;CACF,CAAC;AAEF;;;;;GAKG;AACH,SAAS,SAAS,CAAC,UAAsC;IACvD,IAAI,UAAU,CAAC,IAAI;QAAE,OAAO,UAAU,CAAC,IAAI,CAAC;IAC5C,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC;IAC3B,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,QAAQ;QAAE,OAAO,QAAQ,CAAC;IACzE,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAgB,aAAa,CAC3B,UAAkD;IAElD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,EAAE,GAAG,sBAAc,EAAE,CAAC;IAC/B,CAAC;IAED,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC;QAC3B,KAAK,EAAE;YACL,GAAG,sBAAc,CAAC,KAAK;YACvB,GAAG,UAAU,CAAC,KAAK;SACpB;QACD,MAAM,EAAE;YACN,GAAG,sBAAc,CAAC,MAAM;YACxB,GAAG,UAAU,CAAC,MAAM;SACrB;QACD,MAAM,EAAE;YACN,GAAG,sBAAc,CAAC,MAAM;YACxB,GAAG,UAAU,CAAC,MAAM;SACrB;QACD,SAAS,EAAE;YACT,GAAG,sBAAc,CAAC,SAAS;YAC3B,GAAG,UAAU,CAAC,SAAS;YACvB,QAAQ,EAAE,UAAU,CAAC,SAAS,EAAE,QAAQ,IAAI,sBAAc,CAAC,SAAS,CAAC,QAAQ;SAC9E;QACD,QAAQ,EAAE;YACR,GAAG,sBAAc,CAAC,QAAQ;YAC1B,GAAG,UAAU,CAAC,QAAQ;YACtB,KAAK,EAAE;gBACL,GAAG,sBAAc,CAAC,QAAQ,CAAC,KAAK;gBAChC,GAAG,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC;aAChC;YACD,eAAe,EAAE,UAAU,CAAC,QAAQ,EAAE,eAAe,IAAI,sBAAc,CAAC,QAAQ,CAAC,eAAe;SACjG;KACF,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw audit plugin entry point
|
|
3
|
+
* Registers all 24 Plugin Hooks, assembles capture -> buffer -> writer pipeline
|
|
4
|
+
*
|
|
5
|
+
* OpenClaw hooks:
|
|
6
|
+
* Agent: before_model_resolve, before_prompt_build, before_agent_start, agent_end
|
|
7
|
+
* LLM: llm_input, llm_output
|
|
8
|
+
* Tool: before_tool_call, after_tool_call, tool_result_persist
|
|
9
|
+
* Msg: message_received, message_sending, message_sent, before_message_write
|
|
10
|
+
* Ctx: before_compaction, after_compaction, before_reset
|
|
11
|
+
* Session: session_start, session_end
|
|
12
|
+
* Subagent: subagent_spawning, subagent_delivery_target, subagent_spawned, subagent_ended
|
|
13
|
+
* Gateway: gateway_start, gateway_stop
|
|
14
|
+
*/
|
|
15
|
+
import { AuditPluginConfig } from './config';
|
|
16
|
+
interface PluginAPI {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
version: string;
|
|
20
|
+
config?: Record<string, unknown>;
|
|
21
|
+
pluginConfig?: Partial<AuditPluginConfig>;
|
|
22
|
+
on(slot: string, handler: (...args: unknown[]) => unknown): void;
|
|
23
|
+
registerHttpRoute?: (params: {
|
|
24
|
+
path: string;
|
|
25
|
+
handler: (req: import('node:http').IncomingMessage, res: import('node:http').ServerResponse) => Promise<boolean | void> | boolean | void;
|
|
26
|
+
auth: 'gateway' | 'plugin';
|
|
27
|
+
match?: 'exact' | 'prefix';
|
|
28
|
+
replaceExisting?: boolean;
|
|
29
|
+
}) => void;
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
}
|
|
32
|
+
declare function activate(api: PluginAPI): {
|
|
33
|
+
deactivate: () => Promise<void>;
|
|
34
|
+
};
|
|
35
|
+
export { activate };
|
|
36
|
+
export default activate;
|
|
37
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,iBAAiB,EAAiB,MAAM,UAAU,CAAC;AAe5D,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC1C,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;IACjE,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE;QAC3B,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,WAAW,EAAE,eAAe,EAAE,GAAG,EAAE,OAAO,WAAW,EAAE,cAAc,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC;QACzI,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;QAC3B,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;QAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;KAC3B,KAAK,IAAI,CAAC;IACX,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAmbD,iBAAS,QAAQ,CAAC,GAAG,EAAE,SAAS,GAAG;IAAE,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAs+BrE;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,eAAe,QAAQ,CAAC"}
|