@elizaos/plugin-browser 1.0.3 → 2.0.0-alpha.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/README.md +75 -23
- package/dist/actions/click.d.ts +3 -0
- package/dist/actions/click.d.ts.map +1 -0
- package/dist/actions/click.js +98 -0
- package/dist/actions/click.js.map +1 -0
- package/dist/actions/extract.d.ts +3 -0
- package/dist/actions/extract.d.ts.map +1 -0
- package/dist/actions/extract.js +110 -0
- package/dist/actions/extract.js.map +1 -0
- package/dist/actions/index.d.ts +7 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/dist/actions/index.js +7 -0
- package/dist/actions/index.js.map +1 -0
- package/dist/actions/navigate.d.ts +3 -0
- package/dist/actions/navigate.d.ts.map +1 -0
- package/dist/actions/navigate.js +129 -0
- package/dist/actions/navigate.js.map +1 -0
- package/dist/actions/screenshot.d.ts +3 -0
- package/dist/actions/screenshot.d.ts.map +1 -0
- package/dist/actions/screenshot.js +107 -0
- package/dist/actions/screenshot.js.map +1 -0
- package/dist/actions/select.d.ts +3 -0
- package/dist/actions/select.d.ts.map +1 -0
- package/dist/actions/select.js +105 -0
- package/dist/actions/select.js.map +1 -0
- package/dist/actions/type.d.ts +3 -0
- package/dist/actions/type.d.ts.map +1 -0
- package/dist/actions/type.js +105 -0
- package/dist/actions/type.js.map +1 -0
- package/dist/index.d.ts +17 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +119 -348
- package/dist/index.js.map +1 -1
- package/dist/providers/browser-state.d.ts +3 -0
- package/dist/providers/browser-state.d.ts.map +1 -0
- package/dist/providers/browser-state.js +47 -0
- package/dist/providers/browser-state.js.map +1 -0
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +2 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/services/browser-service.d.ts +30 -0
- package/dist/services/browser-service.d.ts.map +1 -0
- package/dist/services/browser-service.js +164 -0
- package/dist/services/browser-service.js.map +1 -0
- package/dist/services/index.d.ts +4 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +4 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/process-manager.d.ts +15 -0
- package/dist/services/process-manager.d.ts.map +1 -0
- package/dist/services/process-manager.js +186 -0
- package/dist/services/process-manager.js.map +1 -0
- package/dist/services/websocket-client.d.ts +35 -0
- package/dist/services/websocket-client.d.ts.map +1 -0
- package/dist/services/websocket-client.js +219 -0
- package/dist/services/websocket-client.js.map +1 -0
- package/dist/types.d.ts +101 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/captcha.d.ts +33 -0
- package/dist/utils/captcha.d.ts.map +1 -0
- package/dist/utils/captcha.js +219 -0
- package/dist/utils/captcha.js.map +1 -0
- package/dist/utils/errors.d.ts +37 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +81 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/retry.d.ts +26 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +55 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/security.d.ts +27 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +138 -0
- package/dist/utils/security.js.map +1 -0
- package/dist/utils/url.d.ts +12 -0
- package/dist/utils/url.d.ts.map +1 -0
- package/dist/utils/url.js +38 -0
- package/dist/utils/url.js.map +1 -0
- package/package.json +60 -42
- package/LICENSE +0 -21
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type IAgentRuntime, Service } from "@elizaos/core";
|
|
2
|
+
import type { BrowserSession } from "../types.js";
|
|
3
|
+
import { BrowserWebSocketClient } from "./websocket-client.js";
|
|
4
|
+
export declare class Session implements BrowserSession {
|
|
5
|
+
id: string;
|
|
6
|
+
createdAt: Date;
|
|
7
|
+
constructor(id: string, createdAt?: Date);
|
|
8
|
+
}
|
|
9
|
+
export declare class BrowserService extends Service {
|
|
10
|
+
static serviceType: "browser";
|
|
11
|
+
capabilityDescription: string;
|
|
12
|
+
private sessions;
|
|
13
|
+
private currentSessionId;
|
|
14
|
+
private processManager;
|
|
15
|
+
private client;
|
|
16
|
+
private isInitialized;
|
|
17
|
+
constructor(runtime?: IAgentRuntime);
|
|
18
|
+
static start(runtime: IAgentRuntime): Promise<BrowserService>;
|
|
19
|
+
static stopRuntime(runtime: IAgentRuntime): Promise<void>;
|
|
20
|
+
stop(): Promise<void>;
|
|
21
|
+
initialize(): Promise<void>;
|
|
22
|
+
createSession(sessionId: string): Promise<Session>;
|
|
23
|
+
getSession(sessionId: string): Promise<Session | undefined>;
|
|
24
|
+
getCurrentSession(): Promise<Session | undefined>;
|
|
25
|
+
getOrCreateSession(): Promise<Session>;
|
|
26
|
+
destroySession(sessionId: string): Promise<void>;
|
|
27
|
+
getClient(): BrowserWebSocketClient;
|
|
28
|
+
private waitForReady;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=browser-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-service.d.ts","sourceRoot":"","sources":["../../src/services/browser-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAU,OAAO,EAAe,MAAM,eAAe,CAAC;AACjF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,qBAAa,OAAQ,YAAW,cAAc;IAEnC,EAAE,EAAE,MAAM;IACV,SAAS,EAAE,IAAI;gBADf,EAAE,EAAE,MAAM,EACV,SAAS,GAAE,IAAiB;CAEtC;AAED,qBAAa,cAAe,SAAQ,OAAO;IACzC,MAAM,CAAC,WAAW,YAAuB;IACzC,qBAAqB,SAAgC;IAErD,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,aAAa,CAAS;gBAElB,OAAO,CAAC,EAAE,aAAa;WAYtB,KAAK,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;WA2BtD,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IASzD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAYrB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B3B,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkBlD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAI3D,iBAAiB,IAAI,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAOjD,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;IAUtC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWtD,SAAS,IAAI,sBAAsB;YAOrB,YAAY;CAyB3B"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { logger, Service, ServiceType } from "@elizaos/core";
|
|
2
|
+
import { BrowserProcessManager } from "./process-manager.js";
|
|
3
|
+
import { BrowserWebSocketClient } from "./websocket-client.js";
|
|
4
|
+
export class Session {
|
|
5
|
+
id;
|
|
6
|
+
createdAt;
|
|
7
|
+
constructor(id, createdAt = new Date()) {
|
|
8
|
+
this.id = id;
|
|
9
|
+
this.createdAt = createdAt;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export class BrowserService extends Service {
|
|
13
|
+
static serviceType = ServiceType.BROWSER;
|
|
14
|
+
capabilityDescription = "Browser automation service";
|
|
15
|
+
sessions = new Map();
|
|
16
|
+
currentSessionId = null;
|
|
17
|
+
processManager;
|
|
18
|
+
client;
|
|
19
|
+
isInitialized = false;
|
|
20
|
+
constructor(runtime) {
|
|
21
|
+
super(runtime);
|
|
22
|
+
if (!runtime) {
|
|
23
|
+
throw new Error("BrowserService requires a runtime");
|
|
24
|
+
}
|
|
25
|
+
this.runtime = runtime;
|
|
26
|
+
const portSetting = runtime.getSetting("BROWSER_SERVER_PORT");
|
|
27
|
+
const port = typeof portSetting === "string" ? parseInt(portSetting, 10) : 3456;
|
|
28
|
+
this.processManager = new BrowserProcessManager(port);
|
|
29
|
+
this.client = new BrowserWebSocketClient(`ws://localhost:${port}`);
|
|
30
|
+
}
|
|
31
|
+
static async start(runtime) {
|
|
32
|
+
logger.info("Starting browser automation service");
|
|
33
|
+
try {
|
|
34
|
+
const service = new BrowserService(runtime);
|
|
35
|
+
logger.info("Starting browser server process...");
|
|
36
|
+
try {
|
|
37
|
+
await service.processManager.start();
|
|
38
|
+
logger.info("Browser server started successfully");
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
42
|
+
logger.error(`Failed to start browser server: ${errorMessage}`);
|
|
43
|
+
logger.warn("Browser plugin will be available but automation will not work");
|
|
44
|
+
logger.warn("To fix this, run: cd packages/plugin-browser && npm run build");
|
|
45
|
+
}
|
|
46
|
+
logger.info("Initializing WebSocket client...");
|
|
47
|
+
await service.initialize();
|
|
48
|
+
return service;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
52
|
+
logger.error(`Failed to start browser service: ${errorMessage}`);
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
static async stopRuntime(runtime) {
|
|
57
|
+
logger.info("Stopping browser automation service");
|
|
58
|
+
const service = runtime.getService(BrowserService.serviceType);
|
|
59
|
+
if (!service) {
|
|
60
|
+
throw new Error("Browser service not found");
|
|
61
|
+
}
|
|
62
|
+
await service.stop();
|
|
63
|
+
}
|
|
64
|
+
async stop() {
|
|
65
|
+
logger.info("Cleaning up browser sessions");
|
|
66
|
+
for (const sessionId of this.sessions.keys()) {
|
|
67
|
+
await this.destroySession(sessionId);
|
|
68
|
+
}
|
|
69
|
+
this.client.disconnect();
|
|
70
|
+
await this.processManager.stop();
|
|
71
|
+
this.isInitialized = false;
|
|
72
|
+
}
|
|
73
|
+
async initialize() {
|
|
74
|
+
if (this.isInitialized) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
if (!this.processManager.isServerRunning()) {
|
|
79
|
+
logger.warn("Browser server is not running, attempting to start...");
|
|
80
|
+
await this.processManager.start();
|
|
81
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
82
|
+
}
|
|
83
|
+
logger.info("Connecting to browser server...");
|
|
84
|
+
await this.client.connect();
|
|
85
|
+
await this.waitForReady();
|
|
86
|
+
this.isInitialized = true;
|
|
87
|
+
logger.info("Browser service initialized successfully");
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
91
|
+
logger.error(`Failed to initialize browser service: ${errorMessage}`);
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async createSession(sessionId) {
|
|
96
|
+
if (!this.isInitialized) {
|
|
97
|
+
throw new Error("Browser service not initialized");
|
|
98
|
+
}
|
|
99
|
+
const response = await this.client.sendMessage("createSession", {});
|
|
100
|
+
const serverSessionId = response.data?.sessionId;
|
|
101
|
+
if (!serverSessionId) {
|
|
102
|
+
throw new Error("Failed to create session on server");
|
|
103
|
+
}
|
|
104
|
+
const session = new Session(serverSessionId);
|
|
105
|
+
this.sessions.set(sessionId, session);
|
|
106
|
+
this.currentSessionId = sessionId;
|
|
107
|
+
return session;
|
|
108
|
+
}
|
|
109
|
+
async getSession(sessionId) {
|
|
110
|
+
return this.sessions.get(sessionId);
|
|
111
|
+
}
|
|
112
|
+
async getCurrentSession() {
|
|
113
|
+
if (!this.currentSessionId) {
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
return this.sessions.get(this.currentSessionId);
|
|
117
|
+
}
|
|
118
|
+
async getOrCreateSession() {
|
|
119
|
+
const currentSession = await this.getCurrentSession();
|
|
120
|
+
if (currentSession) {
|
|
121
|
+
return currentSession;
|
|
122
|
+
}
|
|
123
|
+
const sessionId = `session-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
124
|
+
return this.createSession(sessionId);
|
|
125
|
+
}
|
|
126
|
+
async destroySession(sessionId) {
|
|
127
|
+
const session = this.sessions.get(sessionId);
|
|
128
|
+
if (session) {
|
|
129
|
+
await this.client.sendMessage("destroySession", { sessionId: session.id });
|
|
130
|
+
this.sessions.delete(sessionId);
|
|
131
|
+
if (this.currentSessionId === sessionId) {
|
|
132
|
+
this.currentSessionId = null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
getClient() {
|
|
137
|
+
if (!this.isInitialized) {
|
|
138
|
+
throw new Error("Browser service not initialized");
|
|
139
|
+
}
|
|
140
|
+
return this.client;
|
|
141
|
+
}
|
|
142
|
+
async waitForReady(maxAttempts = 60, delayMs = 3000) {
|
|
143
|
+
logger.info("Waiting for browser server to be ready...");
|
|
144
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
145
|
+
try {
|
|
146
|
+
const isHealthy = await this.client.health();
|
|
147
|
+
if (isHealthy) {
|
|
148
|
+
logger.info("Browser server is ready");
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
154
|
+
logger.debug(`Health check attempt ${attempt}/${maxAttempts} failed: ${errorMessage}`);
|
|
155
|
+
}
|
|
156
|
+
if (attempt < maxAttempts) {
|
|
157
|
+
logger.info(`Server not ready yet, retrying in ${delayMs / 1000}s... (attempt ${attempt}/${maxAttempts})`);
|
|
158
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
throw new Error(`Browser server did not become ready after ${maxAttempts} attempts`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=browser-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-service.js","sourceRoot":"","sources":["../../src/services/browser-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { type IAgentRuntime, logger, Service, ServiceType } from \"@elizaos/core\";\nimport type { BrowserSession } from \"../types.js\";\nimport { BrowserProcessManager } from \"./process-manager.js\";\nimport { BrowserWebSocketClient } from \"./websocket-client.js\";\n\nexport class Session implements BrowserSession {\n constructor(\n public id: string,\n public createdAt: Date = new Date()\n ) {}\n}\n\nexport class BrowserService extends Service {\n static serviceType = ServiceType.BROWSER;\n capabilityDescription = \"Browser automation service\";\n\n private sessions = new Map<string, Session>();\n private currentSessionId: string | null = null;\n private processManager: BrowserProcessManager;\n private client: BrowserWebSocketClient;\n private isInitialized = false;\n\n constructor(runtime?: IAgentRuntime) {\n super(runtime);\n if (!runtime) {\n throw new Error(\"BrowserService requires a runtime\");\n }\n this.runtime = runtime;\n const portSetting = runtime.getSetting(\"BROWSER_SERVER_PORT\");\n const port = typeof portSetting === \"string\" ? parseInt(portSetting, 10) : 3456;\n this.processManager = new BrowserProcessManager(port);\n this.client = new BrowserWebSocketClient(`ws://localhost:${port}`);\n }\n\n static async start(runtime: IAgentRuntime): Promise<BrowserService> {\n logger.info(\"Starting browser automation service\");\n try {\n const service = new BrowserService(runtime);\n\n logger.info(\"Starting browser server process...\");\n try {\n await service.processManager.start();\n logger.info(\"Browser server started successfully\");\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(`Failed to start browser server: ${errorMessage}`);\n logger.warn(\"Browser plugin will be available but automation will not work\");\n logger.warn(\"To fix this, run: cd packages/plugin-browser && npm run build\");\n }\n\n logger.info(\"Initializing WebSocket client...\");\n await service.initialize();\n\n return service;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(`Failed to start browser service: ${errorMessage}`);\n throw error;\n }\n }\n\n static async stopRuntime(runtime: IAgentRuntime): Promise<void> {\n logger.info(\"Stopping browser automation service\");\n const service = runtime.getService<BrowserService>(BrowserService.serviceType);\n if (!service) {\n throw new Error(\"Browser service not found\");\n }\n await service.stop();\n }\n\n async stop(): Promise<void> {\n logger.info(\"Cleaning up browser sessions\");\n\n for (const sessionId of this.sessions.keys()) {\n await this.destroySession(sessionId);\n }\n\n this.client.disconnect();\n await this.processManager.stop();\n this.isInitialized = false;\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized) {\n return;\n }\n\n try {\n if (!this.processManager.isServerRunning()) {\n logger.warn(\"Browser server is not running, attempting to start...\");\n await this.processManager.start();\n await new Promise((resolve) => setTimeout(resolve, 2000));\n }\n\n logger.info(\"Connecting to browser server...\");\n await this.client.connect();\n\n await this.waitForReady();\n\n this.isInitialized = true;\n logger.info(\"Browser service initialized successfully\");\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(`Failed to initialize browser service: ${errorMessage}`);\n throw error;\n }\n }\n\n async createSession(sessionId: string): Promise<Session> {\n if (!this.isInitialized) {\n throw new Error(\"Browser service not initialized\");\n }\n\n const response = await this.client.sendMessage(\"createSession\", {});\n const serverSessionId = (response.data as { sessionId?: string })?.sessionId;\n if (!serverSessionId) {\n throw new Error(\"Failed to create session on server\");\n }\n\n const session = new Session(serverSessionId);\n this.sessions.set(sessionId, session);\n this.currentSessionId = sessionId;\n\n return session;\n }\n\n async getSession(sessionId: string): Promise<Session | undefined> {\n return this.sessions.get(sessionId);\n }\n\n async getCurrentSession(): Promise<Session | undefined> {\n if (!this.currentSessionId) {\n return undefined;\n }\n return this.sessions.get(this.currentSessionId);\n }\n\n async getOrCreateSession(): Promise<Session> {\n const currentSession = await this.getCurrentSession();\n if (currentSession) {\n return currentSession;\n }\n\n const sessionId = `session-${Date.now()}-${Math.random().toString(36).substring(7)}`;\n return this.createSession(sessionId);\n }\n\n async destroySession(sessionId: string): Promise<void> {\n const session = this.sessions.get(sessionId);\n if (session) {\n await this.client.sendMessage(\"destroySession\", { sessionId: session.id });\n this.sessions.delete(sessionId);\n if (this.currentSessionId === sessionId) {\n this.currentSessionId = null;\n }\n }\n }\n\n getClient(): BrowserWebSocketClient {\n if (!this.isInitialized) {\n throw new Error(\"Browser service not initialized\");\n }\n return this.client;\n }\n\n private async waitForReady(maxAttempts = 60, delayMs = 3000): Promise<void> {\n logger.info(\"Waiting for browser server to be ready...\");\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n const isHealthy = await this.client.health();\n if (isHealthy) {\n logger.info(\"Browser server is ready\");\n return;\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.debug(`Health check attempt ${attempt}/${maxAttempts} failed: ${errorMessage}`);\n }\n\n if (attempt < maxAttempts) {\n logger.info(\n `Server not ready yet, retrying in ${delayMs / 1000}s... (attempt ${attempt}/${maxAttempts})`\n );\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n }\n }\n\n throw new Error(`Browser server did not become ready after ${maxAttempts} attempts`);\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC","sourcesContent":["export { BrowserService, Session } from \"./browser-service.js\";\nexport { BrowserProcessManager } from \"./process-manager.js\";\nexport { BrowserWebSocketClient } from \"./websocket-client.js\";\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare class BrowserProcessManager {
|
|
2
|
+
private serverPort;
|
|
3
|
+
private process;
|
|
4
|
+
private isRunning;
|
|
5
|
+
private binaryPath;
|
|
6
|
+
constructor(serverPort?: number);
|
|
7
|
+
private getBinaryName;
|
|
8
|
+
private findBinary;
|
|
9
|
+
start(): Promise<void>;
|
|
10
|
+
private waitForServer;
|
|
11
|
+
stop(): Promise<void>;
|
|
12
|
+
isServerRunning(): boolean;
|
|
13
|
+
getServerUrl(): string;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=process-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-manager.d.ts","sourceRoot":"","sources":["../../src/services/process-manager.ts"],"names":[],"mappings":"AAOA,qBAAa,qBAAqB;IAKpB,OAAO,CAAC,UAAU;IAJ9B,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAuB;gBAErB,UAAU,GAAE,MAAa;IAI7C,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,UAAU;IA+CZ,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YA6Ed,aAAa;IAqCrB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB3B,eAAe,IAAI,OAAO;IAI1B,YAAY,IAAI,MAAM;CAGvB"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { platform } from "node:os";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { logger } from "@elizaos/core";
|
|
7
|
+
export class BrowserProcessManager {
|
|
8
|
+
serverPort;
|
|
9
|
+
process = null;
|
|
10
|
+
isRunning = false;
|
|
11
|
+
binaryPath = null;
|
|
12
|
+
constructor(serverPort = 3456) {
|
|
13
|
+
this.serverPort = serverPort;
|
|
14
|
+
this.binaryPath = this.findBinary();
|
|
15
|
+
}
|
|
16
|
+
getBinaryName() {
|
|
17
|
+
const platformName = platform();
|
|
18
|
+
const arch = process.arch;
|
|
19
|
+
const ext = platformName === "win32" ? ".exe" : "";
|
|
20
|
+
return {
|
|
21
|
+
primary: `browser-server-${platformName}-${arch}${ext}`,
|
|
22
|
+
fallback: `browser-server-${platformName}${ext}`,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
findBinary() {
|
|
26
|
+
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
27
|
+
const isDocker = process.env.DOCKER_CONTAINER === "true" || existsSync("/.dockerenv");
|
|
28
|
+
const binaryNames = this.getBinaryName();
|
|
29
|
+
const possiblePaths = [
|
|
30
|
+
...(isDocker
|
|
31
|
+
? [
|
|
32
|
+
"/usr/local/bin/browser-server",
|
|
33
|
+
"/usr/local/bin/browser-server-linux",
|
|
34
|
+
"/app/browser-server",
|
|
35
|
+
`/app/binaries/${binaryNames.primary}`,
|
|
36
|
+
`/app/binaries/${binaryNames.fallback}`,
|
|
37
|
+
]
|
|
38
|
+
: []),
|
|
39
|
+
...(!isDocker ? [join(moduleDir, "../server/dist/index.js")] : []),
|
|
40
|
+
join(moduleDir, "../server/binaries", binaryNames.primary),
|
|
41
|
+
join(moduleDir, "../server/binaries", binaryNames.fallback),
|
|
42
|
+
join(moduleDir, "../../../browser-server", binaryNames.primary),
|
|
43
|
+
join(moduleDir, "../../../browser-server", binaryNames.fallback),
|
|
44
|
+
join(moduleDir, "../../.bin", "browser-server"),
|
|
45
|
+
join(moduleDir, "../server/dist/index.js"),
|
|
46
|
+
...(isDocker
|
|
47
|
+
? ["/app/packages/plugin-browser/server/dist/index.js", "/app/browser-server/dist/index.js"]
|
|
48
|
+
: []),
|
|
49
|
+
];
|
|
50
|
+
for (const path of possiblePaths) {
|
|
51
|
+
if (existsSync(path)) {
|
|
52
|
+
logger.info(`Found browser server at: ${path}`);
|
|
53
|
+
return path;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const srcPath = join(moduleDir, "../server/src/index.ts");
|
|
57
|
+
if (existsSync(srcPath)) {
|
|
58
|
+
logger.warn("No compiled binary found, will try to run from source with tsx");
|
|
59
|
+
return srcPath;
|
|
60
|
+
}
|
|
61
|
+
logger.error("Could not find browser server binary or source files");
|
|
62
|
+
logger.error(`Searched paths: ${possiblePaths.join(", ")}`);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
async start() {
|
|
66
|
+
if (this.isRunning) {
|
|
67
|
+
logger.warn("Browser server is already running");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (!this.binaryPath) {
|
|
71
|
+
throw new Error("Browser server binary not found - please ensure server is built");
|
|
72
|
+
}
|
|
73
|
+
const binaryPath = this.binaryPath;
|
|
74
|
+
return new Promise((resolve, reject) => {
|
|
75
|
+
const env = {
|
|
76
|
+
...process.env,
|
|
77
|
+
BROWSER_SERVER_PORT: this.serverPort.toString(),
|
|
78
|
+
NODE_ENV: process.env.NODE_ENV ?? "production",
|
|
79
|
+
BROWSERBASE_API_KEY: process.env.BROWSERBASE_API_KEY,
|
|
80
|
+
BROWSERBASE_PROJECT_ID: process.env.BROWSERBASE_PROJECT_ID,
|
|
81
|
+
OPENAI_API_KEY: process.env.OPENAI_API_KEY,
|
|
82
|
+
ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
|
|
83
|
+
BROWSER_HEADLESS: process.env.BROWSER_HEADLESS,
|
|
84
|
+
CAPSOLVER_API_KEY: process.env.CAPSOLVER_API_KEY,
|
|
85
|
+
OLLAMA_BASE_URL: process.env.OLLAMA_BASE_URL ?? "http://ollama:11434",
|
|
86
|
+
OLLAMA_MODEL: process.env.OLLAMA_MODEL ?? "llama3.2-vision",
|
|
87
|
+
DISPLAY: process.env.DISPLAY ?? ":99",
|
|
88
|
+
};
|
|
89
|
+
const isBinary = !binaryPath.endsWith(".js") && !binaryPath.endsWith(".ts");
|
|
90
|
+
const isTypeScript = binaryPath.endsWith(".ts");
|
|
91
|
+
if (isBinary) {
|
|
92
|
+
this.process = spawn(binaryPath, [], { env });
|
|
93
|
+
}
|
|
94
|
+
else if (isTypeScript) {
|
|
95
|
+
const tsxPath = require.resolve("tsx/cli", { paths: [process.cwd()] });
|
|
96
|
+
this.process = spawn("node", [tsxPath, binaryPath], { env });
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
this.process = spawn("node", [binaryPath], { env });
|
|
100
|
+
}
|
|
101
|
+
this.process.stdout?.on("data", (data) => {
|
|
102
|
+
const message = data.toString().trim();
|
|
103
|
+
logger.debug(`[BrowserServer] ${message}`);
|
|
104
|
+
if (message.includes("listening on port")) {
|
|
105
|
+
this.isRunning = true;
|
|
106
|
+
resolve();
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
this.process.stderr?.on("data", (data) => {
|
|
110
|
+
logger.error(`[BrowserServer Error] ${data.toString()}`);
|
|
111
|
+
});
|
|
112
|
+
this.process.on("error", (error) => {
|
|
113
|
+
logger.error(`Failed to start browser server: ${error.message}`);
|
|
114
|
+
this.isRunning = false;
|
|
115
|
+
reject(error);
|
|
116
|
+
});
|
|
117
|
+
this.process.on("exit", (code) => {
|
|
118
|
+
logger.info(`Browser server exited with code ${code}`);
|
|
119
|
+
this.isRunning = false;
|
|
120
|
+
});
|
|
121
|
+
this.waitForServer()
|
|
122
|
+
.then(() => resolve())
|
|
123
|
+
.catch((error) => {
|
|
124
|
+
this.isRunning = false;
|
|
125
|
+
if (this.process) {
|
|
126
|
+
this.process.kill("SIGTERM");
|
|
127
|
+
}
|
|
128
|
+
reject(error);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
async waitForServer() {
|
|
133
|
+
const maxAttempts = 30;
|
|
134
|
+
const delay = 1000;
|
|
135
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
136
|
+
try {
|
|
137
|
+
const ws = require("ws");
|
|
138
|
+
const wsConnection = new ws(`ws://localhost:${this.serverPort}`);
|
|
139
|
+
await new Promise((resolve, reject) => {
|
|
140
|
+
const timeout = setTimeout(() => {
|
|
141
|
+
wsConnection.close();
|
|
142
|
+
reject(new Error("Connection timeout"));
|
|
143
|
+
}, 5000);
|
|
144
|
+
wsConnection.on("open", () => {
|
|
145
|
+
clearTimeout(timeout);
|
|
146
|
+
wsConnection.close();
|
|
147
|
+
resolve();
|
|
148
|
+
});
|
|
149
|
+
wsConnection.on("error", (error) => {
|
|
150
|
+
clearTimeout(timeout);
|
|
151
|
+
reject(error);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
logger.info("Browser server is ready");
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
catch { }
|
|
158
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
159
|
+
}
|
|
160
|
+
throw new Error("Browser server failed to start");
|
|
161
|
+
}
|
|
162
|
+
async stop() {
|
|
163
|
+
if (!this.process || !this.isRunning) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
return new Promise((resolve) => {
|
|
167
|
+
this.process?.on("exit", () => {
|
|
168
|
+
this.isRunning = false;
|
|
169
|
+
resolve();
|
|
170
|
+
});
|
|
171
|
+
this.process?.kill("SIGTERM");
|
|
172
|
+
setTimeout(() => {
|
|
173
|
+
if (this.isRunning && this.process) {
|
|
174
|
+
this.process.kill("SIGKILL");
|
|
175
|
+
}
|
|
176
|
+
}, 5000);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
isServerRunning() {
|
|
180
|
+
return this.isRunning;
|
|
181
|
+
}
|
|
182
|
+
getServerUrl() {
|
|
183
|
+
return `ws://localhost:${this.serverPort}`;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=process-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-manager.js","sourceRoot":"","sources":["../../src/services/process-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ChildProcess, spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { platform } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { logger } from \"@elizaos/core\";\n\nexport class BrowserProcessManager {\n private process: ChildProcess | null = null;\n private isRunning = false;\n private binaryPath: string | null = null;\n\n constructor(private serverPort: number = 3456) {\n this.binaryPath = this.findBinary();\n }\n\n private getBinaryName(): { primary: string; fallback: string } {\n const platformName = platform();\n const arch = process.arch;\n const ext = platformName === \"win32\" ? \".exe\" : \"\";\n\n return {\n primary: `browser-server-${platformName}-${arch}${ext}`,\n fallback: `browser-server-${platformName}${ext}`,\n };\n }\n\n private findBinary(): string | null {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const isDocker = process.env.DOCKER_CONTAINER === \"true\" || existsSync(\"/.dockerenv\");\n const binaryNames = this.getBinaryName();\n\n const possiblePaths = [\n ...(isDocker\n ? [\n \"/usr/local/bin/browser-server\",\n \"/usr/local/bin/browser-server-linux\",\n \"/app/browser-server\",\n `/app/binaries/${binaryNames.primary}`,\n `/app/binaries/${binaryNames.fallback}`,\n ]\n : []),\n\n ...(!isDocker ? [join(moduleDir, \"../server/dist/index.js\")] : []),\n join(moduleDir, \"../server/binaries\", binaryNames.primary),\n join(moduleDir, \"../server/binaries\", binaryNames.fallback),\n join(moduleDir, \"../../../browser-server\", binaryNames.primary),\n join(moduleDir, \"../../../browser-server\", binaryNames.fallback),\n join(moduleDir, \"../../.bin\", \"browser-server\"),\n join(moduleDir, \"../server/dist/index.js\"),\n\n ...(isDocker\n ? [\"/app/packages/plugin-browser/server/dist/index.js\", \"/app/browser-server/dist/index.js\"]\n : []),\n ];\n\n for (const path of possiblePaths) {\n if (existsSync(path)) {\n logger.info(`Found browser server at: ${path}`);\n return path;\n }\n }\n\n const srcPath = join(moduleDir, \"../server/src/index.ts\");\n if (existsSync(srcPath)) {\n logger.warn(\"No compiled binary found, will try to run from source with tsx\");\n return srcPath;\n }\n\n logger.error(\"Could not find browser server binary or source files\");\n logger.error(`Searched paths: ${possiblePaths.join(\", \")}`);\n return null;\n }\n\n async start(): Promise<void> {\n if (this.isRunning) {\n logger.warn(\"Browser server is already running\");\n return;\n }\n\n if (!this.binaryPath) {\n throw new Error(\"Browser server binary not found - please ensure server is built\");\n }\n\n const binaryPath = this.binaryPath;\n\n return new Promise((resolve, reject) => {\n const env = {\n ...process.env,\n BROWSER_SERVER_PORT: this.serverPort.toString(),\n NODE_ENV: process.env.NODE_ENV ?? \"production\",\n BROWSERBASE_API_KEY: process.env.BROWSERBASE_API_KEY,\n BROWSERBASE_PROJECT_ID: process.env.BROWSERBASE_PROJECT_ID,\n OPENAI_API_KEY: process.env.OPENAI_API_KEY,\n ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,\n BROWSER_HEADLESS: process.env.BROWSER_HEADLESS,\n CAPSOLVER_API_KEY: process.env.CAPSOLVER_API_KEY,\n OLLAMA_BASE_URL: process.env.OLLAMA_BASE_URL ?? \"http://ollama:11434\",\n OLLAMA_MODEL: process.env.OLLAMA_MODEL ?? \"llama3.2-vision\",\n DISPLAY: process.env.DISPLAY ?? \":99\",\n };\n\n const isBinary = !binaryPath.endsWith(\".js\") && !binaryPath.endsWith(\".ts\");\n const isTypeScript = binaryPath.endsWith(\".ts\");\n\n if (isBinary) {\n this.process = spawn(binaryPath, [], { env });\n } else if (isTypeScript) {\n const tsxPath = require.resolve(\"tsx/cli\", { paths: [process.cwd()] });\n this.process = spawn(\"node\", [tsxPath, binaryPath], { env });\n } else {\n this.process = spawn(\"node\", [binaryPath], { env });\n }\n\n this.process.stdout?.on(\"data\", (data: Buffer) => {\n const message = data.toString().trim();\n logger.debug(`[BrowserServer] ${message}`);\n\n if (message.includes(\"listening on port\")) {\n this.isRunning = true;\n resolve();\n }\n });\n\n this.process.stderr?.on(\"data\", (data: Buffer) => {\n logger.error(`[BrowserServer Error] ${data.toString()}`);\n });\n\n this.process.on(\"error\", (error: Error) => {\n logger.error(`Failed to start browser server: ${error.message}`);\n this.isRunning = false;\n reject(error);\n });\n\n this.process.on(\"exit\", (code) => {\n logger.info(`Browser server exited with code ${code}`);\n this.isRunning = false;\n });\n\n this.waitForServer()\n .then(() => resolve())\n .catch((error) => {\n this.isRunning = false;\n if (this.process) {\n this.process.kill(\"SIGTERM\");\n }\n reject(error);\n });\n });\n }\n\n private async waitForServer(): Promise<void> {\n const maxAttempts = 30;\n const delay = 1000;\n\n for (let i = 0; i < maxAttempts; i++) {\n try {\n const ws = require(\"ws\");\n const wsConnection = new ws(`ws://localhost:${this.serverPort}`);\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n wsConnection.close();\n reject(new Error(\"Connection timeout\"));\n }, 5000);\n\n wsConnection.on(\"open\", () => {\n clearTimeout(timeout);\n wsConnection.close();\n resolve();\n });\n\n wsConnection.on(\"error\", (error: Error) => {\n clearTimeout(timeout);\n reject(error);\n });\n });\n\n logger.info(\"Browser server is ready\");\n return;\n } catch {}\n\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n throw new Error(\"Browser server failed to start\");\n }\n\n async stop(): Promise<void> {\n if (!this.process || !this.isRunning) {\n return;\n }\n\n return new Promise((resolve) => {\n this.process?.on(\"exit\", () => {\n this.isRunning = false;\n resolve();\n });\n\n this.process?.kill(\"SIGTERM\");\n\n setTimeout(() => {\n if (this.isRunning && this.process) {\n this.process.kill(\"SIGKILL\");\n }\n }, 5000);\n });\n }\n\n isServerRunning(): boolean {\n return this.isRunning;\n }\n\n getServerUrl(): string {\n return `ws://localhost:${this.serverPort}`;\n }\n}\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { NavigationResult, WebSocketResponse } from "../types.js";
|
|
2
|
+
export declare class BrowserWebSocketClient {
|
|
3
|
+
private serverUrl;
|
|
4
|
+
private ws;
|
|
5
|
+
private messageHandlers;
|
|
6
|
+
private connected;
|
|
7
|
+
private reconnectAttempts;
|
|
8
|
+
private maxReconnectAttempts;
|
|
9
|
+
private reconnectDelay;
|
|
10
|
+
constructor(serverUrl: string);
|
|
11
|
+
connect(): Promise<void>;
|
|
12
|
+
private rawDataToString;
|
|
13
|
+
private attemptReconnect;
|
|
14
|
+
sendMessage(type: string, data: Record<string, unknown>): Promise<WebSocketResponse>;
|
|
15
|
+
disconnect(): void;
|
|
16
|
+
isConnected(): boolean;
|
|
17
|
+
navigate(sessionId: string, url: string): Promise<NavigationResult>;
|
|
18
|
+
getState(sessionId: string): Promise<{
|
|
19
|
+
url: string;
|
|
20
|
+
title: string;
|
|
21
|
+
sessionId: string;
|
|
22
|
+
createdAt: Date;
|
|
23
|
+
}>;
|
|
24
|
+
goBack(sessionId: string): Promise<NavigationResult>;
|
|
25
|
+
goForward(sessionId: string): Promise<NavigationResult>;
|
|
26
|
+
refresh(sessionId: string): Promise<NavigationResult>;
|
|
27
|
+
click(sessionId: string, description: string): Promise<WebSocketResponse>;
|
|
28
|
+
type(sessionId: string, text: string, field: string): Promise<WebSocketResponse>;
|
|
29
|
+
select(sessionId: string, option: string, dropdown: string): Promise<WebSocketResponse>;
|
|
30
|
+
extract(sessionId: string, instruction: string): Promise<WebSocketResponse>;
|
|
31
|
+
screenshot(sessionId: string): Promise<WebSocketResponse>;
|
|
32
|
+
solveCaptcha(sessionId: string): Promise<WebSocketResponse>;
|
|
33
|
+
health(): Promise<boolean>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=websocket-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-client.d.ts","sourceRoot":"","sources":["../../src/services/websocket-client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAoB,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIzF,qBAAa,sBAAsB;IAQrB,OAAO,CAAC,SAAS;IAP7B,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,oBAAoB,CAAK;IACjC,OAAO,CAAC,cAAc,CAAQ;gBAEV,SAAS,EAAE,MAAM;IAE/B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAqD9B,OAAO,CAAC,eAAe;YAgBT,gBAAgB;IAkBxB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAgC1F,UAAU,IAAI,IAAI;IAUlB,WAAW,IAAI,OAAO;IAIhB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAanE,QAAQ,CACZ,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,IAAI,CAAA;KAAE,CAAC;IAWxE,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAUpD,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAUvD,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAUrD,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAOzE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAOhF,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAOvF,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAO3E,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAIzD,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAI3D,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;CAUjC"}
|