@aiscene/aiserver 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/api/callback.d.ts +7 -0
- package/dist/api/callback.d.ts.map +1 -0
- package/dist/api/callback.js +116 -0
- package/dist/api/callback.js.map +1 -0
- package/dist/api/device-api.d.ts +13 -0
- package/dist/api/device-api.d.ts.map +1 -0
- package/dist/api/device-api.js +98 -0
- package/dist/api/device-api.js.map +1 -0
- package/dist/api/task-api.d.ts +9 -0
- package/dist/api/task-api.d.ts.map +1 -0
- package/dist/api/task-api.js +47 -0
- package/dist/api/task-api.js.map +1 -0
- package/dist/config/cli.d.ts +30 -0
- package/dist/config/cli.d.ts.map +1 -0
- package/dist/config/cli.js +129 -0
- package/dist/config/cli.js.map +1 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +142 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +66 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +2 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/event-bus.d.ts +14 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +33 -0
- package/dist/core/event-bus.js.map +1 -0
- package/dist/core/logger.d.ts +24 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +52 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/types.d.ts +134 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +3 -0
- package/dist/core/types.js.map +1 -0
- package/dist/debug/dump-manager.d.ts +10 -0
- package/dist/debug/dump-manager.d.ts.map +1 -0
- package/dist/debug/dump-manager.js +52 -0
- package/dist/debug/dump-manager.js.map +1 -0
- package/dist/debug/screencast.d.ts +11 -0
- package/dist/debug/screencast.d.ts.map +1 -0
- package/dist/debug/screencast.js +88 -0
- package/dist/debug/screencast.js.map +1 -0
- package/dist/debug/session-manager.d.ts +14 -0
- package/dist/debug/session-manager.d.ts.map +1 -0
- package/dist/debug/session-manager.js +76 -0
- package/dist/debug/session-manager.js.map +1 -0
- package/dist/debug/types.d.ts +76 -0
- package/dist/debug/types.d.ts.map +1 -0
- package/dist/debug/types.js +2 -0
- package/dist/debug/types.js.map +1 -0
- package/dist/debug/web-screencast.d.ts +60 -0
- package/dist/debug/web-screencast.d.ts.map +1 -0
- package/dist/debug/web-screencast.js +146 -0
- package/dist/debug/web-screencast.js.map +1 -0
- package/dist/debug/websocket-server.d.ts +27 -0
- package/dist/debug/websocket-server.d.ts.map +1 -0
- package/dist/debug/websocket-server.js +681 -0
- package/dist/debug/websocket-server.js.map +1 -0
- package/dist/device/detector.d.ts +10 -0
- package/dist/device/detector.d.ts.map +1 -0
- package/dist/device/detector.js +100 -0
- package/dist/device/detector.js.map +1 -0
- package/dist/device/heartbeat.d.ts +26 -0
- package/dist/device/heartbeat.d.ts.map +1 -0
- package/dist/device/heartbeat.js +225 -0
- package/dist/device/heartbeat.js.map +1 -0
- package/dist/device/status-manager.d.ts +15 -0
- package/dist/device/status-manager.d.ts.map +1 -0
- package/dist/device/status-manager.js +58 -0
- package/dist/device/status-manager.js.map +1 -0
- package/dist/device/types.d.ts +30 -0
- package/dist/device/types.d.ts.map +1 -0
- package/dist/device/types.js +2 -0
- package/dist/device/types.js.map +1 -0
- package/dist/executor/action-executor.d.ts +25 -0
- package/dist/executor/action-executor.d.ts.map +1 -0
- package/dist/executor/action-executor.js +261 -0
- package/dist/executor/action-executor.js.map +1 -0
- package/dist/executor/android-executor.d.ts +12 -0
- package/dist/executor/android-executor.d.ts.map +1 -0
- package/dist/executor/android-executor.js +127 -0
- package/dist/executor/android-executor.js.map +1 -0
- package/dist/executor/base.d.ts +20 -0
- package/dist/executor/base.d.ts.map +1 -0
- package/dist/executor/base.js +91 -0
- package/dist/executor/base.js.map +1 -0
- package/dist/executor/cli-executor.d.ts +12 -0
- package/dist/executor/cli-executor.d.ts.map +1 -0
- package/dist/executor/cli-executor.js +94 -0
- package/dist/executor/cli-executor.js.map +1 -0
- package/dist/executor/code-executor.d.ts +13 -0
- package/dist/executor/code-executor.d.ts.map +1 -0
- package/dist/executor/code-executor.js +52 -0
- package/dist/executor/code-executor.js.map +1 -0
- package/dist/executor/code-instrument.d.ts +12 -0
- package/dist/executor/code-instrument.d.ts.map +1 -0
- package/dist/executor/code-instrument.js +116 -0
- package/dist/executor/code-instrument.js.map +1 -0
- package/dist/executor/executor-factory.d.ts +7 -0
- package/dist/executor/executor-factory.d.ts.map +1 -0
- package/dist/executor/executor-factory.js +24 -0
- package/dist/executor/executor-factory.js.map +1 -0
- package/dist/executor/ios-executor.d.ts +10 -0
- package/dist/executor/ios-executor.d.ts.map +1 -0
- package/dist/executor/ios-executor.js +91 -0
- package/dist/executor/ios-executor.js.map +1 -0
- package/dist/executor/types.d.ts +14 -0
- package/dist/executor/types.d.ts.map +1 -0
- package/dist/executor/types.js +2 -0
- package/dist/executor/types.js.map +1 -0
- package/dist/executor/worker-entry.d.ts +2 -0
- package/dist/executor/worker-entry.d.ts.map +1 -0
- package/dist/executor/worker-entry.js +61 -0
- package/dist/executor/worker-entry.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +157 -0
- package/dist/index.js.map +1 -0
- package/dist/node/service.d.ts +21 -0
- package/dist/node/service.d.ts.map +1 -0
- package/dist/node/service.js +178 -0
- package/dist/node/service.js.map +1 -0
- package/dist/node/types.d.ts +45 -0
- package/dist/node/types.d.ts.map +1 -0
- package/dist/node/types.js +3 -0
- package/dist/node/types.js.map +1 -0
- package/dist/storage/database.d.ts +6 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +154 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/storage/repositories/debug-log-repo.d.ts +29 -0
- package/dist/storage/repositories/debug-log-repo.d.ts.map +1 -0
- package/dist/storage/repositories/debug-log-repo.js +90 -0
- package/dist/storage/repositories/debug-log-repo.js.map +1 -0
- package/dist/storage/repositories/device-repo.d.ts +12 -0
- package/dist/storage/repositories/device-repo.d.ts.map +1 -0
- package/dist/storage/repositories/device-repo.js +87 -0
- package/dist/storage/repositories/device-repo.js.map +1 -0
- package/dist/storage/repositories/execution-log-repo.d.ts +9 -0
- package/dist/storage/repositories/execution-log-repo.d.ts.map +1 -0
- package/dist/storage/repositories/execution-log-repo.js +49 -0
- package/dist/storage/repositories/execution-log-repo.js.map +1 -0
- package/dist/storage/repositories/task-repo.d.ts +13 -0
- package/dist/storage/repositories/task-repo.d.ts.map +1 -0
- package/dist/storage/repositories/task-repo.js +109 -0
- package/dist/storage/repositories/task-repo.js.map +1 -0
- package/dist/task/poller.d.ts +25 -0
- package/dist/task/poller.d.ts.map +1 -0
- package/dist/task/poller.js +153 -0
- package/dist/task/poller.js.map +1 -0
- package/dist/task/queue.d.ts +13 -0
- package/dist/task/queue.d.ts.map +1 -0
- package/dist/task/queue.js +38 -0
- package/dist/task/queue.js.map +1 -0
- package/dist/task/scheduler.d.ts +25 -0
- package/dist/task/scheduler.d.ts.map +1 -0
- package/dist/task/scheduler.js +274 -0
- package/dist/task/scheduler.js.map +1 -0
- package/dist/task/types.d.ts +31 -0
- package/dist/task/types.d.ts.map +1 -0
- package/dist/task/types.js +37 -0
- package/dist/task/types.js.map +1 -0
- package/dist/web/server.d.ts +14 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +478 -0
- package/dist/web/server.js.map +1 -0
- package/package.json +49 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @aiscene/aiserver - AI Automation Server
|
|
4
|
+
*
|
|
5
|
+
* Features:
|
|
6
|
+
* 1. Device detection & heartbeat with configurable polling
|
|
7
|
+
* 2. Task polling & scheduling with configurable interval
|
|
8
|
+
* 3. Unified executor (CLI/Android/iOS/Action/Code)
|
|
9
|
+
* 4. Debug WebSocket with real-time feedback
|
|
10
|
+
* 5. Web dashboard for monitoring
|
|
11
|
+
* 6. SQLite storage for all execution data
|
|
12
|
+
*/
|
|
13
|
+
import { loadConfig } from './config/index.js';
|
|
14
|
+
import { initDatabase, closeDatabase } from './storage/database.js';
|
|
15
|
+
import { eventBus } from './core/event-bus.js';
|
|
16
|
+
import { createLogger } from './core/logger.js';
|
|
17
|
+
import { executionLogRepo } from './storage/repositories/execution-log-repo.js';
|
|
18
|
+
import { uploadReportFile, updateTaskStatusToServer } from './api/callback.js';
|
|
19
|
+
import { nodeService } from './node/service.js';
|
|
20
|
+
import { deviceHeartbeatService } from './device/heartbeat.js';
|
|
21
|
+
import { taskPollerService } from './task/poller.js';
|
|
22
|
+
import { DebugWebSocketServer } from './debug/websocket-server.js';
|
|
23
|
+
import { webServer } from './web/server.js';
|
|
24
|
+
const logger = createLogger('AIServer');
|
|
25
|
+
class AIServer {
|
|
26
|
+
debugWsServer;
|
|
27
|
+
shuttingDown = false;
|
|
28
|
+
constructor() {
|
|
29
|
+
this.debugWsServer = new DebugWebSocketServer();
|
|
30
|
+
}
|
|
31
|
+
async start() {
|
|
32
|
+
logger.info('Starting @aiscene/aiserver...');
|
|
33
|
+
// 1. Load configuration
|
|
34
|
+
const config = loadConfig();
|
|
35
|
+
logger.info('Configuration loaded');
|
|
36
|
+
// 2. Initialize database
|
|
37
|
+
initDatabase(config.storage);
|
|
38
|
+
logger.info('Database initialized');
|
|
39
|
+
// 3. Setup event listeners
|
|
40
|
+
this.setupEventListeners(config);
|
|
41
|
+
// 4. Register node and start node heartbeat
|
|
42
|
+
await nodeService.start(config.node);
|
|
43
|
+
logger.info('Node service started');
|
|
44
|
+
// 5. Start device heartbeat service
|
|
45
|
+
await deviceHeartbeatService.start(config.device, config.callback);
|
|
46
|
+
logger.info('Device heartbeat service started');
|
|
47
|
+
// 6. Start task polling service
|
|
48
|
+
await taskPollerService.start(config.task, config.callback);
|
|
49
|
+
logger.info('Task polling service started');
|
|
50
|
+
// 7. Start debug WebSocket server
|
|
51
|
+
await this.debugWsServer.start(config);
|
|
52
|
+
logger.info('Debug WebSocket server started');
|
|
53
|
+
// 8. Start web management interface
|
|
54
|
+
webServer.start(config.server);
|
|
55
|
+
logger.info('Web management interface started');
|
|
56
|
+
logger.info('========================================');
|
|
57
|
+
logger.info('@aiscene/aiserver is running!');
|
|
58
|
+
logger.info(` WebSocket: ws://${config.server.host}:${config.server.port}`);
|
|
59
|
+
logger.info(` Web UI: http://${config.server.host}:${config.server.webPort}`);
|
|
60
|
+
logger.info(` Node ID: ${config.task.nodeId}`);
|
|
61
|
+
logger.info('========================================');
|
|
62
|
+
}
|
|
63
|
+
setupEventListeners(config) {
|
|
64
|
+
// Log all task events to storage
|
|
65
|
+
eventBus.onEvent('task:log', (payload) => {
|
|
66
|
+
const data = payload.data;
|
|
67
|
+
try {
|
|
68
|
+
executionLogRepo.create({
|
|
69
|
+
taskId: data.taskId,
|
|
70
|
+
sessionId: data.sessionId,
|
|
71
|
+
level: data.level || 'info',
|
|
72
|
+
content: data.content,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// ignore storage errors
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
// Handle task completion - upload report and update status
|
|
80
|
+
eventBus.onEvent('task:completed', async (payload) => {
|
|
81
|
+
const data = payload.data;
|
|
82
|
+
try {
|
|
83
|
+
// Upload report file
|
|
84
|
+
if (data.reportFile) {
|
|
85
|
+
await uploadReportFile(data.reportFile, data.taskId, `task-${data.taskId}`, undefined, data.success, data.errorMessage, config.task.nodeId, config.callback);
|
|
86
|
+
}
|
|
87
|
+
// Update task status on server
|
|
88
|
+
await updateTaskStatusToServer(data.taskId, data.success, config.task.nodeId, data.errorMessage || null, config.callback);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
logger.error(`Task completion callback error: ${error.message}`);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
eventBus.onEvent('task:failed', async (payload) => {
|
|
95
|
+
const data = payload.data;
|
|
96
|
+
try {
|
|
97
|
+
if (data.reportFile) {
|
|
98
|
+
await uploadReportFile(data.reportFile, data.taskId, `task-${data.taskId}`, undefined, false, data.errorMessage, config.task.nodeId, config.callback);
|
|
99
|
+
}
|
|
100
|
+
await updateTaskStatusToServer(data.taskId, false, config.task.nodeId, data.errorMessage || null, config.callback);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
logger.error(`Task failure callback error: ${error.message}`);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
// Device offline events
|
|
107
|
+
eventBus.onEvent('device:offline', (payload) => {
|
|
108
|
+
const data = payload.data;
|
|
109
|
+
logger.warn(`Device offline: ${data.serialNumber}`);
|
|
110
|
+
});
|
|
111
|
+
eventBus.onEvent('device:online', (payload) => {
|
|
112
|
+
const data = payload.data;
|
|
113
|
+
logger.info(`Device online: ${data.serialNumber} (${data.platform})`);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
async shutdown() {
|
|
117
|
+
if (this.shuttingDown)
|
|
118
|
+
return;
|
|
119
|
+
this.shuttingDown = true;
|
|
120
|
+
logger.info('Shutting down @aiscene/aiserver...');
|
|
121
|
+
try {
|
|
122
|
+
await nodeService.stop();
|
|
123
|
+
await this.debugWsServer.close();
|
|
124
|
+
await taskPollerService.stop();
|
|
125
|
+
await deviceHeartbeatService.stop();
|
|
126
|
+
webServer.close();
|
|
127
|
+
closeDatabase();
|
|
128
|
+
eventBus.removeAll();
|
|
129
|
+
logger.info('Shutdown complete');
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
logger.error(`Shutdown error: ${error.message}`);
|
|
133
|
+
}
|
|
134
|
+
process.exit(0);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// ==================== Main ====================
|
|
138
|
+
const server = new AIServer();
|
|
139
|
+
// Graceful shutdown
|
|
140
|
+
process.on('SIGINT', () => server.shutdown());
|
|
141
|
+
process.on('SIGTERM', () => server.shutdown());
|
|
142
|
+
process.on('SIGHUP', () => server.shutdown());
|
|
143
|
+
// Unhandled error handling
|
|
144
|
+
process.on('uncaughtException', (error) => {
|
|
145
|
+
logger.error(`Uncaught exception: ${error.message}`);
|
|
146
|
+
logger.error(error.stack || '');
|
|
147
|
+
});
|
|
148
|
+
process.on('unhandledRejection', (reason) => {
|
|
149
|
+
logger.error(`Unhandled rejection: ${reason}`);
|
|
150
|
+
});
|
|
151
|
+
// Start the server
|
|
152
|
+
server.start().catch((error) => {
|
|
153
|
+
logger.error(`Failed to start server: ${error.message}`);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
});
|
|
156
|
+
export { AIServer };
|
|
157
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { NodeConfig } from '../config/schema.js';
|
|
2
|
+
export declare class NodeService {
|
|
3
|
+
private heartbeatInterval;
|
|
4
|
+
private config;
|
|
5
|
+
private registered;
|
|
6
|
+
private startTime;
|
|
7
|
+
private running;
|
|
8
|
+
start(config: NodeConfig): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Use hostname() as nodeId, consistent with the electron-shadcn reference project
|
|
11
|
+
*/
|
|
12
|
+
getNodeId(): string;
|
|
13
|
+
register(): Promise<boolean>;
|
|
14
|
+
private sendHeartbeat;
|
|
15
|
+
private handleCommands;
|
|
16
|
+
isRegistered(): boolean;
|
|
17
|
+
getNodeName(): string;
|
|
18
|
+
stop(): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export declare const nodeService: NodeService;
|
|
21
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/node/service.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAwBtD,qBAAa,WAAW;IACtB,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,OAAO,CAAkB;IAE3B,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B9C;;OAEG;IACH,SAAS,IAAI,MAAM;IAIb,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;YAwDpB,aAAa;IA+C3B,OAAO,CAAC,cAAc;IAOtB,YAAY,IAAI,OAAO;IAIvB,WAAW,IAAI,MAAM;IAIf,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAuB5B;AAED,eAAO,MAAM,WAAW,aAAoB,CAAC"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import { createLogger } from '../core/logger.js';
|
|
4
|
+
import { eventBus } from '../core/event-bus.js';
|
|
5
|
+
import { deviceRepo } from '../storage/repositories/device-repo.js';
|
|
6
|
+
const logger = createLogger('NodeService');
|
|
7
|
+
function getLocalIPAddress() {
|
|
8
|
+
const interfaces = os.networkInterfaces();
|
|
9
|
+
for (const name of Object.keys(interfaces)) {
|
|
10
|
+
const nets = interfaces[name];
|
|
11
|
+
if (!nets)
|
|
12
|
+
continue;
|
|
13
|
+
for (const net of nets) {
|
|
14
|
+
if (net.family === 'IPv4' && !net.internal) {
|
|
15
|
+
return net.address;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return '127.0.0.1';
|
|
20
|
+
}
|
|
21
|
+
export class NodeService {
|
|
22
|
+
heartbeatInterval = null;
|
|
23
|
+
config;
|
|
24
|
+
registered = false;
|
|
25
|
+
startTime = Date.now();
|
|
26
|
+
running = false;
|
|
27
|
+
async start(config) {
|
|
28
|
+
this.config = config;
|
|
29
|
+
this.running = true;
|
|
30
|
+
this.startTime = Date.now();
|
|
31
|
+
// Register node first
|
|
32
|
+
const registered = await this.register();
|
|
33
|
+
if (!registered) {
|
|
34
|
+
logger.warn('Node registration failed, will retry on next heartbeat cycle');
|
|
35
|
+
}
|
|
36
|
+
// Start heartbeat loop
|
|
37
|
+
this.heartbeatInterval = setInterval(async () => {
|
|
38
|
+
if (!this.running)
|
|
39
|
+
return;
|
|
40
|
+
// If not registered, try to register first
|
|
41
|
+
if (!this.registered) {
|
|
42
|
+
const regResult = await this.register();
|
|
43
|
+
if (!regResult)
|
|
44
|
+
return; // Skip heartbeat if registration still fails
|
|
45
|
+
}
|
|
46
|
+
await this.sendHeartbeat();
|
|
47
|
+
}, config.heartbeatInterval);
|
|
48
|
+
logger.info(`Node service started (nodeId: ${this.getNodeId()}, name: ${this.getNodeId()})`);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Use hostname() as nodeId, consistent with the electron-shadcn reference project
|
|
52
|
+
*/
|
|
53
|
+
getNodeId() {
|
|
54
|
+
return os.hostname();
|
|
55
|
+
}
|
|
56
|
+
async register() {
|
|
57
|
+
try {
|
|
58
|
+
const nodeId = this.getNodeId();
|
|
59
|
+
const request = {
|
|
60
|
+
nodeId: nodeId,
|
|
61
|
+
nodeName: this.config.nodeName || nodeId,
|
|
62
|
+
ipAddress: this.config.ipAddress || getLocalIPAddress(),
|
|
63
|
+
port: this.config.port,
|
|
64
|
+
nodeType: this.config.nodeType,
|
|
65
|
+
version: this.config.version,
|
|
66
|
+
maxConcurrentTasks: this.config.maxConcurrentTasks,
|
|
67
|
+
weight: this.config.weight,
|
|
68
|
+
supportedTags: this.config.supportedTags,
|
|
69
|
+
environment: this.config.environment,
|
|
70
|
+
region: this.config.region,
|
|
71
|
+
description: this.config.description,
|
|
72
|
+
configInfo: this.config.configInfo,
|
|
73
|
+
};
|
|
74
|
+
logger.info(`Registering node: ${request.nodeId} (${request.nodeName})`);
|
|
75
|
+
logger.info(`Node registration request: ${JSON.stringify(request)}`);
|
|
76
|
+
const response = await axios.post(this.config.registerUrl, request, {
|
|
77
|
+
timeout: 10000,
|
|
78
|
+
headers: { 'Content-Type': 'application/json' },
|
|
79
|
+
});
|
|
80
|
+
if (response.status === 200 && response.data?.success) {
|
|
81
|
+
this.registered = true;
|
|
82
|
+
logger.info(`Node registered successfully: ${nodeId}`);
|
|
83
|
+
eventBus.emitEvent('node:registered', 'node', { nodeId });
|
|
84
|
+
// Send heartbeat immediately after registration (consistent with reference project)
|
|
85
|
+
await this.sendHeartbeat();
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
logger.warn(`Node registration rejected: ${response.data?.message || 'Unknown error'}`);
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
const axiosError = error;
|
|
95
|
+
if (axiosError.response) {
|
|
96
|
+
logger.warn(`Node registration failed (status ${axiosError.response.status}): ${JSON.stringify(axiosError.response.data)}`);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
logger.warn(`Node registration failed: ${axiosError.message}`);
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async sendHeartbeat() {
|
|
105
|
+
try {
|
|
106
|
+
const nodeId = this.getNodeId();
|
|
107
|
+
// Simplified heartbeat data, consistent with the reference project
|
|
108
|
+
const request = {
|
|
109
|
+
nodeId: nodeId,
|
|
110
|
+
currentTaskCount: 0, // TODO: get from scheduler
|
|
111
|
+
status: 1, // Online
|
|
112
|
+
};
|
|
113
|
+
const response = await axios.post(this.config.heartbeatUrl, request, {
|
|
114
|
+
timeout: 10000,
|
|
115
|
+
headers: { 'Content-Type': 'application/json' },
|
|
116
|
+
});
|
|
117
|
+
if (response.status === 200 && response.data?.success) {
|
|
118
|
+
const onlineDevices = deviceRepo.getOnline();
|
|
119
|
+
logger.info(`Node heartbeat sent (nodeId: ${nodeId}, devices: ${onlineDevices.length})`);
|
|
120
|
+
// Handle commands from server if any
|
|
121
|
+
const commands = response.data?.data?.commands;
|
|
122
|
+
if (commands && Array.isArray(commands)) {
|
|
123
|
+
this.handleCommands(commands);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
logger.warn(`Node heartbeat rejected: ${response.data?.message || 'Unknown error'}`);
|
|
128
|
+
// If rejected, might need to re-register
|
|
129
|
+
if (response.status === 400 || response.status === 404) {
|
|
130
|
+
this.registered = false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
const axiosError = error;
|
|
136
|
+
if (axiosError.response?.status === 400 || axiosError.response?.status === 404) {
|
|
137
|
+
logger.warn(`Node heartbeat failed (status ${axiosError.response.status}), marking as unregistered`);
|
|
138
|
+
this.registered = false;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
logger.warn(`Node heartbeat failed: ${axiosError.message}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
handleCommands(commands) {
|
|
146
|
+
for (const cmd of commands) {
|
|
147
|
+
logger.info(`Received command from server: ${cmd.type}`);
|
|
148
|
+
eventBus.emitEvent('node:command', 'node', { type: cmd.type, payload: cmd.payload });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
isRegistered() {
|
|
152
|
+
return this.registered;
|
|
153
|
+
}
|
|
154
|
+
getNodeName() {
|
|
155
|
+
return this.getNodeId();
|
|
156
|
+
}
|
|
157
|
+
async stop() {
|
|
158
|
+
this.running = false;
|
|
159
|
+
if (this.heartbeatInterval) {
|
|
160
|
+
clearInterval(this.heartbeatInterval);
|
|
161
|
+
this.heartbeatInterval = null;
|
|
162
|
+
}
|
|
163
|
+
// Try to notify server about shutdown
|
|
164
|
+
if (this.registered) {
|
|
165
|
+
try {
|
|
166
|
+
await axios.delete(`${this.config.registerUrl.replace('/register', '')}/${this.getNodeId()}`, { timeout: 5000 });
|
|
167
|
+
logger.info('Node unregistered from server');
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
logger.warn('Failed to unregister node from server');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
this.registered = false;
|
|
174
|
+
logger.info('Node service stopped');
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
export const nodeService = new NodeService();
|
|
178
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/node/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface NodeRegistrationRequest {
|
|
2
|
+
nodeId: string;
|
|
3
|
+
nodeName: string;
|
|
4
|
+
ipAddress: string;
|
|
5
|
+
port: number;
|
|
6
|
+
nodeType: string;
|
|
7
|
+
version: string;
|
|
8
|
+
maxConcurrentTasks: number;
|
|
9
|
+
weight: number;
|
|
10
|
+
supportedTags: string;
|
|
11
|
+
environment: string;
|
|
12
|
+
region: string;
|
|
13
|
+
description: string;
|
|
14
|
+
configInfo?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
export interface NodeRegistrationResponse {
|
|
17
|
+
success: boolean;
|
|
18
|
+
message?: string;
|
|
19
|
+
data?: {
|
|
20
|
+
nodeId: string;
|
|
21
|
+
token?: string;
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export interface NodeHeartbeatRequest {
|
|
26
|
+
nodeId: string;
|
|
27
|
+
currentTaskCount: number;
|
|
28
|
+
status: number;
|
|
29
|
+
cpuUsage?: number;
|
|
30
|
+
memoryUsage?: number;
|
|
31
|
+
diskUsage?: number;
|
|
32
|
+
additionalInfo?: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
export interface NodeHeartbeatResponse {
|
|
35
|
+
success: boolean;
|
|
36
|
+
message?: string;
|
|
37
|
+
data?: {
|
|
38
|
+
commands?: Array<{
|
|
39
|
+
type: string;
|
|
40
|
+
payload: Record<string, unknown>;
|
|
41
|
+
}>;
|
|
42
|
+
[key: string]: unknown;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/node/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE;QACL,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SAAE,CAAC,CAAC;QACrE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/node/types.ts"],"names":[],"mappings":"AAAA,wCAAwC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import type { StorageConfig } from '../config/schema.js';
|
|
3
|
+
export declare function initDatabase(config: StorageConfig): Database.Database;
|
|
4
|
+
export declare function getDatabase(): Database.Database;
|
|
5
|
+
export declare function closeDatabase(): void;
|
|
6
|
+
//# sourceMappingURL=database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/storage/database.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAItC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMzD,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,QAAQ,CAAC,QAAQ,CAqBrE;AAqGD,wBAAgB,WAAW,IAAI,QAAQ,CAAC,QAAQ,CAK/C;AAwBD,wBAAgB,aAAa,IAAI,IAAI,CAMpC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { createLogger } from '../core/logger.js';
|
|
5
|
+
const logger = createLogger('Database');
|
|
6
|
+
let db = null;
|
|
7
|
+
export function initDatabase(config) {
|
|
8
|
+
if (db)
|
|
9
|
+
return db;
|
|
10
|
+
// Ensure directory exists
|
|
11
|
+
const dbDir = path.dirname(config.dbPath);
|
|
12
|
+
if (!fs.existsSync(dbDir)) {
|
|
13
|
+
fs.mkdirSync(dbDir, { recursive: true });
|
|
14
|
+
logger.info(`Created database directory: ${dbDir}`);
|
|
15
|
+
}
|
|
16
|
+
db = new Database(config.dbPath);
|
|
17
|
+
// Enable WAL mode for better concurrent read performance
|
|
18
|
+
db.pragma('journal_mode = WAL');
|
|
19
|
+
db.pragma('foreign_keys = ON');
|
|
20
|
+
// Run migrations
|
|
21
|
+
runMigrations(db);
|
|
22
|
+
logger.info(`Database initialized: ${config.dbPath}`);
|
|
23
|
+
return db;
|
|
24
|
+
}
|
|
25
|
+
function runMigrations(database) {
|
|
26
|
+
const migrationPath = path.resolve(import.meta.dirname, 'migrations', 'init.sql');
|
|
27
|
+
let sql;
|
|
28
|
+
if (fs.existsSync(migrationPath)) {
|
|
29
|
+
sql = fs.readFileSync(migrationPath, 'utf-8');
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
// Fallback: inline the SQL if file not found (e.g., after build)
|
|
33
|
+
sql = `
|
|
34
|
+
CREATE TABLE IF NOT EXISTS devices (
|
|
35
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
36
|
+
serial_number TEXT UNIQUE NOT NULL,
|
|
37
|
+
model TEXT,
|
|
38
|
+
brand TEXT,
|
|
39
|
+
platform TEXT DEFAULT 'android',
|
|
40
|
+
status TEXT DEFAULT 'offline',
|
|
41
|
+
last_heartbeat_at DATETIME,
|
|
42
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
43
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
44
|
+
);
|
|
45
|
+
CREATE TABLE IF NOT EXISTS tasks (
|
|
46
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
47
|
+
task_id TEXT UNIQUE NOT NULL,
|
|
48
|
+
execution_id TEXT,
|
|
49
|
+
type TEXT NOT NULL,
|
|
50
|
+
status TEXT DEFAULT 'pending',
|
|
51
|
+
priority INTEGER DEFAULT 0,
|
|
52
|
+
config TEXT,
|
|
53
|
+
result TEXT,
|
|
54
|
+
error_message TEXT,
|
|
55
|
+
report_file_path TEXT,
|
|
56
|
+
allocated_device TEXT,
|
|
57
|
+
started_at DATETIME,
|
|
58
|
+
completed_at DATETIME,
|
|
59
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
60
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
61
|
+
);
|
|
62
|
+
CREATE TABLE IF NOT EXISTS execution_logs (
|
|
63
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
64
|
+
task_id TEXT NOT NULL,
|
|
65
|
+
session_id TEXT,
|
|
66
|
+
level TEXT DEFAULT 'info',
|
|
67
|
+
content TEXT NOT NULL,
|
|
68
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
69
|
+
);
|
|
70
|
+
CREATE TABLE IF NOT EXISTS debug_sessions (
|
|
71
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
72
|
+
session_id TEXT UNIQUE NOT NULL,
|
|
73
|
+
task_id TEXT,
|
|
74
|
+
device_id TEXT,
|
|
75
|
+
platform TEXT,
|
|
76
|
+
status TEXT DEFAULT 'idle',
|
|
77
|
+
started_at DATETIME,
|
|
78
|
+
completed_at DATETIME,
|
|
79
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
80
|
+
);
|
|
81
|
+
CREATE TABLE IF NOT EXISTS debug_logs (
|
|
82
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
83
|
+
session_id TEXT NOT NULL,
|
|
84
|
+
type TEXT,
|
|
85
|
+
content TEXT NOT NULL,
|
|
86
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
87
|
+
);
|
|
88
|
+
CREATE INDEX IF NOT EXISTS idx_devices_serial ON devices(serial_number);
|
|
89
|
+
CREATE INDEX IF NOT EXISTS idx_devices_status ON devices(status);
|
|
90
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_task_id ON tasks(task_id);
|
|
91
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
|
|
92
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_type ON tasks(type);
|
|
93
|
+
CREATE INDEX IF NOT EXISTS idx_execution_logs_task_id ON execution_logs(task_id);
|
|
94
|
+
CREATE INDEX IF NOT EXISTS idx_debug_sessions_session_id ON debug_sessions(session_id);
|
|
95
|
+
CREATE INDEX IF NOT EXISTS idx_debug_logs_session_id ON debug_logs(session_id);
|
|
96
|
+
`;
|
|
97
|
+
}
|
|
98
|
+
// Execute each statement separately
|
|
99
|
+
const statements = sql
|
|
100
|
+
.split(';')
|
|
101
|
+
.map(s => s.trim())
|
|
102
|
+
.filter(s => s.length > 0);
|
|
103
|
+
for (const stmt of statements) {
|
|
104
|
+
try {
|
|
105
|
+
database.exec(stmt + ';');
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
// Ignore "already exists" errors for idempotent migrations
|
|
109
|
+
const msg = error.message;
|
|
110
|
+
if (!msg.includes('already exists')) {
|
|
111
|
+
logger.error(`Migration error: ${msg}`);
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
logger.info('Database migrations completed');
|
|
117
|
+
// Run ALTER TABLE migrations for existing databases
|
|
118
|
+
runAlterMigrations(database);
|
|
119
|
+
}
|
|
120
|
+
export function getDatabase() {
|
|
121
|
+
if (!db) {
|
|
122
|
+
throw new Error('Database not initialized. Call initDatabase() first.');
|
|
123
|
+
}
|
|
124
|
+
return db;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Run ALTER TABLE migrations for existing databases that may lack newer columns
|
|
128
|
+
*/
|
|
129
|
+
function runAlterMigrations(database) {
|
|
130
|
+
const alterMigrations = [
|
|
131
|
+
'ALTER TABLE tasks ADD COLUMN allocated_device TEXT',
|
|
132
|
+
];
|
|
133
|
+
for (const stmt of alterMigrations) {
|
|
134
|
+
try {
|
|
135
|
+
database.exec(stmt + ';');
|
|
136
|
+
logger.info(`Alter migration applied: ${stmt}`);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
// Ignore "duplicate column" errors (column already exists)
|
|
140
|
+
const msg = error.message;
|
|
141
|
+
if (!msg.includes('duplicate column name')) {
|
|
142
|
+
logger.warn(`Alter migration skipped: ${msg}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
export function closeDatabase() {
|
|
148
|
+
if (db) {
|
|
149
|
+
db.close();
|
|
150
|
+
db = null;
|
|
151
|
+
logger.info('Database connection closed');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/storage/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface DebugLogEntry {
|
|
2
|
+
id?: number;
|
|
3
|
+
sessionId: string;
|
|
4
|
+
type: string;
|
|
5
|
+
content: string;
|
|
6
|
+
createdAt?: Date;
|
|
7
|
+
}
|
|
8
|
+
export interface DebugSessionRecord {
|
|
9
|
+
id?: number;
|
|
10
|
+
sessionId: string;
|
|
11
|
+
taskId?: string;
|
|
12
|
+
deviceId?: string;
|
|
13
|
+
platform?: string;
|
|
14
|
+
status: string;
|
|
15
|
+
startedAt?: Date;
|
|
16
|
+
completedAt?: Date;
|
|
17
|
+
createdAt?: Date;
|
|
18
|
+
}
|
|
19
|
+
export declare class DebugLogRepo {
|
|
20
|
+
createSession(session: Omit<DebugSessionRecord, 'id' | 'createdAt'>): void;
|
|
21
|
+
updateSessionStatus(sessionId: string, status: string): void;
|
|
22
|
+
getSession(sessionId: string): DebugSessionRecord | undefined;
|
|
23
|
+
getAllSessions(limit?: number): DebugSessionRecord[];
|
|
24
|
+
addLog(entry: Omit<DebugLogEntry, 'id' | 'createdAt'>): void;
|
|
25
|
+
getLogsBySession(sessionId: string, limit?: number): DebugLogEntry[];
|
|
26
|
+
deleteSession(sessionId: string): void;
|
|
27
|
+
}
|
|
28
|
+
export declare const debugLogRepo: DebugLogRepo;
|
|
29
|
+
//# sourceMappingURL=debug-log-repo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug-log-repo.d.ts","sourceRoot":"","sources":["../../../src/storage/repositories/debug-log-repo.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,IAAI,CAAC;CAClB;AAiCD,qBAAa,YAAY;IACvB,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG,IAAI;IAe1E,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAW5D,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAM7D,cAAc,CAAC,KAAK,GAAE,MAAY,GAAG,kBAAkB,EAAE;IAMzD,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG,IAAI;IAY5D,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,GAAE,MAAa,GAAG,aAAa,EAAE;IAQ1E,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAKvC;AAED,eAAO,MAAM,YAAY,cAAqB,CAAC"}
|