devicely 2.2.4 → 2.2.6
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/bin/devicely.js +1 -105
- package/config/devices.conf +6 -22
- package/lib/androidDeviceDetection.js +1 -276
- package/lib/appMappings.js +1 -337
- package/lib/deviceDetection.js +1 -394
- package/lib/devices.js +1 -54
- package/lib/doctor.js +1 -94
- package/lib/encryption.js +1 -0
- package/lib/executor.js +1 -104
- package/lib/frontend/asset-manifest.json +3 -3
- package/lib/frontend/index.html +1 -1
- package/lib/frontend/static/css/main.23bd35c0.css.map +1 -0
- package/lib/frontend/static/js/{main.26a24c5c.js → main.4ff1ea70.js} +3 -3
- package/lib/frontend/static/js/main.4ff1ea70.js.map +1 -0
- package/lib/logger.js +1 -47
- package/lib/package-lock.json +1678 -0
- package/lib/package.json +30 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260205_225900.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260205_225942.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260205_231101.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260205_232911.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260208_095103.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260208_095720.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115040.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115047.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115118.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115125.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115143.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120107.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120118.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120137.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120201.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_134529.png +0 -0
- package/lib/scriptLoader.js +1 -20
- package/lib/server.js +1 -3546
- package/package.json +14 -3
- package/scripts/shell/android_device_control.enc +1 -1
- package/scripts/shell/connect_android_usb_multi_final.enc +1 -1
- package/scripts/shell/connect_android_wireless.enc +1 -1
- package/scripts/shell/connect_android_wireless_multi_final.enc +1 -1
- package/scripts/shell/connect_ios_usb_multi_final.enc +1 -1
- package/scripts/shell/connect_ios_wireless_multi_final.enc +1 -1
- package/scripts/shell/ios_device_control.enc +1 -1
- package/lib/frontend/static/js/main.223106ce.js +0 -3
- package/lib/frontend/static/js/main.26a24c5c.js.LICENSE.txt +0 -48
- package/lib/frontend/static/js/main.31418566.js +0 -3
- package/lib/frontend/static/js/main.31418566.js.LICENSE.txt +0 -48
- package/lib/frontend/static/js/main.a507b3fc.js +0 -3
- package/lib/frontend/static/js/main.a507b3fc.js.LICENSE.txt +0 -48
- package/lib/frontend/static/js/main.e6f081bf.js +0 -3
- package/lib/frontend/static/js/main.e6f081bf.js.LICENSE.txt +0 -48
- package/scripts/compile-shell-scripts.js +0 -208
- package/scripts/encrypt-shell-simple.js +0 -75
- package/scripts/obfuscate-shell.js +0 -160
- package/scripts/shell/apps_presets.conf +0 -271
- package/scripts/shell/devices.conf +0 -24
- /package/lib/frontend/static/js/{main.223106ce.js.LICENSE.txt → main.4ff1ea70.js.LICENSE.txt} +0 -0
package/lib/server.js
CHANGED
|
@@ -1,3546 +1 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
|
|
3
|
-
// Load environment variables from .env file in project root
|
|
4
|
-
require('dotenv').config({ path: path.join(__dirname, '../../.env') });
|
|
5
|
-
|
|
6
|
-
const express = require('express');
|
|
7
|
-
const cors = require('cors');
|
|
8
|
-
const { spawn } = require('child_process');
|
|
9
|
-
const WebSocket = require('ws');
|
|
10
|
-
const fs = require('fs').promises;
|
|
11
|
-
const AIProviderManager = require('./aiProviders');
|
|
12
|
-
const Logger = require('./logger');
|
|
13
|
-
|
|
14
|
-
// Initialize logger
|
|
15
|
-
const logger = new Logger('Server');
|
|
16
|
-
|
|
17
|
-
// Import scriptLoader for encrypted scripts
|
|
18
|
-
let scriptLoader;
|
|
19
|
-
try {
|
|
20
|
-
scriptLoader = require('./scriptLoader');
|
|
21
|
-
} catch (err) {
|
|
22
|
-
// Development mode - no encryption
|
|
23
|
-
scriptLoader = null;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Import deviceDetection from appropriate location (dev vs npm package)
|
|
27
|
-
let discoverAllDevices;
|
|
28
|
-
try {
|
|
29
|
-
// Try npm package location first (lib/)
|
|
30
|
-
({ discoverAllDevices } = require('./deviceDetection'));
|
|
31
|
-
} catch (err) {
|
|
32
|
-
// Fall back to development location
|
|
33
|
-
({ discoverAllDevices } = require('../../deviceDetection'));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const { execSync } = require('child_process');
|
|
37
|
-
|
|
38
|
-
const app = express();
|
|
39
|
-
const PORT = process.env.PORT || 3001;
|
|
40
|
-
|
|
41
|
-
// Middleware
|
|
42
|
-
app.use(cors());
|
|
43
|
-
app.use(express.json());
|
|
44
|
-
|
|
45
|
-
// Serve static frontend files - check both dev and npm package locations
|
|
46
|
-
const frontendPath = require('fs').existsSync(path.join(__dirname, '../frontend/build'))
|
|
47
|
-
? path.join(__dirname, '../frontend/build')
|
|
48
|
-
: path.join(__dirname, './frontend');
|
|
49
|
-
|
|
50
|
-
app.use(express.static(frontendPath));
|
|
51
|
-
// Frontend path: ${frontendPath}
|
|
52
|
-
|
|
53
|
-
// WebSocket server
|
|
54
|
-
const wss = new WebSocket.Server({ noServer: true });
|
|
55
|
-
|
|
56
|
-
// AI Provider Manager - supports multiple AI providers
|
|
57
|
-
const aiManager = new AIProviderManager();
|
|
58
|
-
|
|
59
|
-
// Store connected devices
|
|
60
|
-
let connectedDevices = [];
|
|
61
|
-
let activeConnections = new Map();
|
|
62
|
-
let wdaProcesses = new Map(); // Track WDA processes: Map<deviceName, {xcodebuild: pid, iproxy: pid}>
|
|
63
|
-
|
|
64
|
-
// Track UIAutomator2 sessions for Android devices
|
|
65
|
-
let androidSessions = new Map(); // Map<udid, {sessionId, port, serverPid}>
|
|
66
|
-
|
|
67
|
-
// Helper to find config files in both dev and npm package locations
|
|
68
|
-
function findConfigFile(filename) {
|
|
69
|
-
// Try development location first
|
|
70
|
-
let configPath = path.join(__dirname, '../../', filename);
|
|
71
|
-
if (require('fs').existsSync(configPath)) {
|
|
72
|
-
return configPath;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Try npm package location (lib/ -> config/)
|
|
76
|
-
configPath = path.join(__dirname, '../config/', filename);
|
|
77
|
-
if (require('fs').existsSync(configPath)) {
|
|
78
|
-
return configPath;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Fall back to dev location for creation
|
|
82
|
-
return path.join(__dirname, '../../', filename);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function findScriptFile(filename) {
|
|
86
|
-
const fsSync = require('fs');
|
|
87
|
-
const os = require('os');
|
|
88
|
-
const crypto = require('crypto');
|
|
89
|
-
|
|
90
|
-
const filenameWithoutExt = filename.replace(/\.sh$/, '');
|
|
91
|
-
const encFilename = filenameWithoutExt + '.enc';
|
|
92
|
-
|
|
93
|
-
// List of paths to try in order
|
|
94
|
-
const pathsToTry = [
|
|
95
|
-
// Development location (project root) - .sh file
|
|
96
|
-
{ path: path.join(__dirname, '../../', filename), encrypted: false },
|
|
97
|
-
// NPM package: encrypted .enc file
|
|
98
|
-
{ path: path.join(__dirname, '../scripts/shell/', encFilename), encrypted: true },
|
|
99
|
-
// NPM package: .sh file (fallback if no encryption)
|
|
100
|
-
{ path: path.join(__dirname, '../scripts/shell/', filename), encrypted: false },
|
|
101
|
-
// NPM package: compiled binary (fallback)
|
|
102
|
-
{ path: path.join(__dirname, '../scripts/shell/', filenameWithoutExt), encrypted: false },
|
|
103
|
-
];
|
|
104
|
-
|
|
105
|
-
for (const { path: scriptPath, encrypted } of pathsToTry) {
|
|
106
|
-
if (fsSync.existsSync(scriptPath)) {
|
|
107
|
-
logger.debug(`✅ Found script: ${filename} at ${scriptPath}${encrypted ? ' (encrypted)' : ''}`);
|
|
108
|
-
|
|
109
|
-
// If encrypted, decrypt to temp directory and return temp path
|
|
110
|
-
if (encrypted && scriptLoader) {
|
|
111
|
-
const tmpDir = path.join(os.tmpdir(), 'devicely_scripts_' + process.pid);
|
|
112
|
-
if (!fsSync.existsSync(tmpDir)) {
|
|
113
|
-
fsSync.mkdirSync(tmpDir, { recursive: true, mode: 0o700 });
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const tmpScript = path.join(tmpDir, filename);
|
|
117
|
-
|
|
118
|
-
// Decrypt if not already decrypted
|
|
119
|
-
if (!fsSync.existsSync(tmpScript)) {
|
|
120
|
-
try {
|
|
121
|
-
const content = scriptLoader.decryptScript(scriptPath);
|
|
122
|
-
fsSync.writeFileSync(tmpScript, content, { mode: 0o755 });
|
|
123
|
-
logger.debug(`🔓 Decrypted ${filename} to temp directory`);
|
|
124
|
-
} catch (error) {
|
|
125
|
-
console.error(`❌ Failed to decrypt ${filename}: ${error.message}`);
|
|
126
|
-
continue;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return tmpScript;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return scriptPath;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
console.error(`❌ Script not found: ${filename}`);
|
|
138
|
-
console.error(` Searched in:`);
|
|
139
|
-
pathsToTry.forEach(p => console.error(` - ${p.path}`));
|
|
140
|
-
|
|
141
|
-
// Return first path as fallback (will fail but with clear error)
|
|
142
|
-
return pathsToTry[0].path;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Device configuration paths
|
|
146
|
-
const DEVICE_CONFIG = findConfigFile('devices.conf');
|
|
147
|
-
// Use OS temp directory for session file - works for both local and npm package
|
|
148
|
-
const SESSION_MAP_FILE = path.join(require('os').tmpdir(), 'devicely_android_sessions.map');
|
|
149
|
-
const APPS_CONFIG = findConfigFile('apps_presets.conf');
|
|
150
|
-
|
|
151
|
-
// iOS scripts
|
|
152
|
-
const WIRELESS_SCRIPT_PATH = findScriptFile('connect_ios_wireless_multi_final.sh');
|
|
153
|
-
const USB_SCRIPT_PATH = findScriptFile('connect_ios_usb_multi_final.sh');
|
|
154
|
-
|
|
155
|
-
// Android scripts
|
|
156
|
-
const ANDROID_WIRELESS_SCRIPT_PATH = findScriptFile('android_device_control.sh');
|
|
157
|
-
const ANDROID_USB_SCRIPT_PATH = findScriptFile('android_device_control.sh');
|
|
158
|
-
|
|
159
|
-
// Recording storage path
|
|
160
|
-
const RECORDINGS_DIR = path.join(__dirname, '../../recordings');
|
|
161
|
-
|
|
162
|
-
// Screenshots storage path
|
|
163
|
-
const SCREENSHOTS_DIR = path.join(__dirname, './screenshots');
|
|
164
|
-
|
|
165
|
-
// Recording state
|
|
166
|
-
let currentRecording = null; // { name, devices, commands: [], startTime }
|
|
167
|
-
let isRecording = false;
|
|
168
|
-
|
|
169
|
-
// Replay state
|
|
170
|
-
let isReplaying = false;
|
|
171
|
-
let replayAborted = false;
|
|
172
|
-
|
|
173
|
-
// ============================================
|
|
174
|
-
// UIAutomator2 Session Management Functions
|
|
175
|
-
// ============================================
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Start UIAutomator2 session for Android device
|
|
179
|
-
*/
|
|
180
|
-
async function startUIAutomator2Session(udid, deviceName) {
|
|
181
|
-
console.log(`🚀 Starting UIAutomator2 session for ${deviceName} (${udid})...`);
|
|
182
|
-
|
|
183
|
-
try {
|
|
184
|
-
// Find available port
|
|
185
|
-
let port = 8200;
|
|
186
|
-
while (true) {
|
|
187
|
-
try {
|
|
188
|
-
execSync(`lsof -i:${port}`, { stdio: 'ignore' });
|
|
189
|
-
port++; // Port is in use, try next
|
|
190
|
-
} catch {
|
|
191
|
-
break; // Port is available
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
console.log(`📡 Using port ${port} for ${deviceName}`);
|
|
196
|
-
|
|
197
|
-
// Start UIAutomator2 server on device
|
|
198
|
-
const serverProcess = spawn('adb', ['-s', udid, 'shell', 'am', 'instrument', '-w',
|
|
199
|
-
'io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner'
|
|
200
|
-
], { detached: true, stdio: 'ignore' });
|
|
201
|
-
|
|
202
|
-
serverProcess.unref(); // Don't wait for process to exit
|
|
203
|
-
|
|
204
|
-
// Wait for server to start
|
|
205
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
206
|
-
|
|
207
|
-
// Forward port
|
|
208
|
-
execSync(`adb -s ${udid} forward tcp:${port} tcp:6790`);
|
|
209
|
-
|
|
210
|
-
// Wait a bit more
|
|
211
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
212
|
-
|
|
213
|
-
// Create session via HTTP
|
|
214
|
-
const axios = require('axios');
|
|
215
|
-
const sessionResponse = await axios.post(`http://localhost:${port}/wd/hub/session`, {
|
|
216
|
-
capabilities: {
|
|
217
|
-
alwaysMatch: {
|
|
218
|
-
platformName: 'Android',
|
|
219
|
-
'appium:automationName': 'UiAutomator2',
|
|
220
|
-
'appium:udid': udid
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
const sessionId = sessionResponse.data.value.sessionId || sessionResponse.data.sessionId;
|
|
226
|
-
|
|
227
|
-
// Store session info
|
|
228
|
-
androidSessions.set(udid, {
|
|
229
|
-
sessionId,
|
|
230
|
-
port,
|
|
231
|
-
serverPid: serverProcess.pid,
|
|
232
|
-
deviceName
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
// Save to session file for scripts to use - remove old entries first
|
|
236
|
-
try {
|
|
237
|
-
let content = '';
|
|
238
|
-
try {
|
|
239
|
-
content = await fs.readFile(SESSION_MAP_FILE, 'utf-8');
|
|
240
|
-
} catch (err) {
|
|
241
|
-
// File doesn't exist yet, that's ok
|
|
242
|
-
}
|
|
243
|
-
const lines = content.split('\n').filter(line => line && !line.startsWith(`${udid}:`));
|
|
244
|
-
lines.push(`${udid}:${sessionId}:${port}`);
|
|
245
|
-
await fs.writeFile(SESSION_MAP_FILE, lines.join('\n') + '\n');
|
|
246
|
-
console.log(`✅ Session file updated: ${udid}:${sessionId}:${port}`);
|
|
247
|
-
} catch (err) {
|
|
248
|
-
console.error(`⚠️ Failed to update session file: ${err.message}`);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
console.log(`✅ UIAutomator2 session created for ${deviceName}`);
|
|
252
|
-
console.log(` Session ID: ${sessionId}`);
|
|
253
|
-
console.log(` Port: ${port}`);
|
|
254
|
-
|
|
255
|
-
return { success: true, sessionId, port };
|
|
256
|
-
|
|
257
|
-
} catch (error) {
|
|
258
|
-
console.error(`❌ Failed to start UIAutomator2 for ${deviceName}:`, error.message);
|
|
259
|
-
return { success: false, error: error.message };
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Stop UIAutomator2 session for Android device
|
|
265
|
-
*/
|
|
266
|
-
async function stopUIAutomator2Session(udid, deviceName) {
|
|
267
|
-
console.log(`🛑 Stopping UIAutomator2 session for ${deviceName} (${udid})...`);
|
|
268
|
-
|
|
269
|
-
try {
|
|
270
|
-
const session = androidSessions.get(udid);
|
|
271
|
-
|
|
272
|
-
if (!session) {
|
|
273
|
-
console.log(`⚠️ No active session found for ${deviceName}`);
|
|
274
|
-
return { success: true, message: 'No active session' };
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// Delete session via HTTP
|
|
278
|
-
try {
|
|
279
|
-
const axios = require('axios');
|
|
280
|
-
await axios.delete(`http://localhost:${session.port}/wd/hub/session/${session.sessionId}`);
|
|
281
|
-
console.log(`✅ UIAutomator2 session deleted for ${deviceName}`);
|
|
282
|
-
} catch (err) {
|
|
283
|
-
console.log(`⚠️ Could not delete session via HTTP: ${err.message}`);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// Remove port forwarding
|
|
287
|
-
try {
|
|
288
|
-
execSync(`adb -s ${udid} forward --remove tcp:${session.port}`);
|
|
289
|
-
console.log(`✅ Port forwarding removed for ${deviceName}`);
|
|
290
|
-
} catch (err) {
|
|
291
|
-
console.log(`⚠️ Could not remove port forwarding: ${err.message}`);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// Kill UIAutomator2 server on device
|
|
295
|
-
try {
|
|
296
|
-
execSync(`adb -s ${udid} shell am force-stop io.appium.uiautomator2.server`);
|
|
297
|
-
execSync(`adb -s ${udid} shell am force-stop io.appium.uiautomator2.server.test`);
|
|
298
|
-
console.log(`✅ UIAutomator2 server stopped on ${deviceName}`);
|
|
299
|
-
} catch (err) {
|
|
300
|
-
console.log(`⚠️ Could not stop UIAutomator2 server: ${err.message}`);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// Remove from memory
|
|
304
|
-
androidSessions.delete(udid);
|
|
305
|
-
|
|
306
|
-
// Update session file
|
|
307
|
-
try {
|
|
308
|
-
const content = await fs.readFile(SESSION_MAP_FILE, 'utf-8');
|
|
309
|
-
const lines = content.split('\n').filter(line => !line.startsWith(`${udid}:`));
|
|
310
|
-
await fs.writeFile(SESSION_MAP_FILE, lines.join('\n'));
|
|
311
|
-
console.log(`✅ Session file updated for ${deviceName}`);
|
|
312
|
-
} catch (err) {
|
|
313
|
-
console.log(`⚠️ Could not update session file: ${err.message}`);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
console.log(`✅ UIAutomator2 session stopped for ${deviceName}`);
|
|
317
|
-
return { success: true };
|
|
318
|
-
|
|
319
|
-
} catch (error) {
|
|
320
|
-
console.error(`❌ Error stopping UIAutomator2 for ${deviceName}:`, error.message);
|
|
321
|
-
return { success: false, error: error.message };
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// ============================================
|
|
326
|
-
|
|
327
|
-
// Load device configuration
|
|
328
|
-
async function loadDeviceConfig() {
|
|
329
|
-
try {
|
|
330
|
-
const content = await fs.readFile(DEVICE_CONFIG, 'utf-8');
|
|
331
|
-
const devices = content
|
|
332
|
-
.split('\n')
|
|
333
|
-
.filter(line => line.trim() && !line.startsWith('#'))
|
|
334
|
-
.map(line => {
|
|
335
|
-
const parts = line.split(',').map(s => s.trim());
|
|
336
|
-
const [name, udid, ip, platform, type] = parts;
|
|
337
|
-
|
|
338
|
-
// Smart platform detection if not specified
|
|
339
|
-
let detectedPlatform = platform || 'ios';
|
|
340
|
-
if (!platform && udid) {
|
|
341
|
-
// Android wireless: IP:PORT format
|
|
342
|
-
if (udid.includes(':') && udid.match(/^\d+\.\d+\.\d+\.\d+:\d+$/)) {
|
|
343
|
-
detectedPlatform = 'android';
|
|
344
|
-
}
|
|
345
|
-
// Android USB: Short serial without dashes
|
|
346
|
-
else if (udid.length < 20 && !udid.includes('-')) {
|
|
347
|
-
detectedPlatform = 'android';
|
|
348
|
-
}
|
|
349
|
-
// iOS: Long UUID with dashes
|
|
350
|
-
else if (udid.includes('-') && udid.length > 30) {
|
|
351
|
-
detectedPlatform = 'ios';
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
return {
|
|
356
|
-
name,
|
|
357
|
-
udid,
|
|
358
|
-
ip: ip || '',
|
|
359
|
-
platform: detectedPlatform,
|
|
360
|
-
type: type || (ip ? 'wireless' : 'usb'),
|
|
361
|
-
status: 'unknown'
|
|
362
|
-
};
|
|
363
|
-
});
|
|
364
|
-
return devices;
|
|
365
|
-
} catch (error) {
|
|
366
|
-
console.error('Error loading device config:', error);
|
|
367
|
-
return [];
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
// Discover and check device connectivity (USB + Wireless)
|
|
372
|
-
async function discoverDevices() {
|
|
373
|
-
// Save current connection states
|
|
374
|
-
const previousStates = new Map();
|
|
375
|
-
connectedDevices.forEach(device => {
|
|
376
|
-
previousStates.set(device.udid, {
|
|
377
|
-
status: device.status,
|
|
378
|
-
sessionId: device.sessionId
|
|
379
|
-
});
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
connectedDevices = await discoverAllDevices();
|
|
383
|
-
|
|
384
|
-
// Restore connection states for devices that were previously connected
|
|
385
|
-
connectedDevices.forEach(device => {
|
|
386
|
-
const prevState = previousStates.get(device.udid);
|
|
387
|
-
if (prevState && prevState.status === 'online') {
|
|
388
|
-
// Preserve the online status for previously connected devices
|
|
389
|
-
device.status = 'online';
|
|
390
|
-
if (prevState.sessionId) {
|
|
391
|
-
device.sessionId = prevState.sessionId;
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
});
|
|
395
|
-
|
|
396
|
-
// Auto-save USB devices to config for wireless use later
|
|
397
|
-
await autoSaveUSBDevicesToConfig(connectedDevices);
|
|
398
|
-
|
|
399
|
-
return connectedDevices;
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
// Auto-save USB devices to config
|
|
403
|
-
async function autoSaveUSBDevicesToConfig(devices) {
|
|
404
|
-
try {
|
|
405
|
-
const usbDevices = devices.filter(d => d.connectionType === 'usb');
|
|
406
|
-
if (usbDevices.length === 0) return;
|
|
407
|
-
|
|
408
|
-
// Load existing config
|
|
409
|
-
const existingDevices = await loadDeviceConfig();
|
|
410
|
-
const existingUdids = new Set(existingDevices.map(d => d.udid));
|
|
411
|
-
|
|
412
|
-
// Add new USB devices
|
|
413
|
-
const newDevices = usbDevices.filter(d => !existingUdids.has(d.udid));
|
|
414
|
-
if (newDevices.length === 0) return;
|
|
415
|
-
|
|
416
|
-
// Append to config with placeholder IP (will be filled when wireless is configured)
|
|
417
|
-
const allDevices = [...existingDevices, ...newDevices.map(d => ({
|
|
418
|
-
name: d.name,
|
|
419
|
-
udid: d.udid,
|
|
420
|
-
ip: '' // Empty IP for USB devices, to be filled for wireless
|
|
421
|
-
}))];
|
|
422
|
-
|
|
423
|
-
// Save to config
|
|
424
|
-
let content = '# Device Configuration (Auto-updated)\n';
|
|
425
|
-
content += '# Format: device_name,udid,ip_address\n';
|
|
426
|
-
content += '# USB devices auto-detected. Add IP for wireless connection.\n\n';
|
|
427
|
-
|
|
428
|
-
allDevices.forEach(device => {
|
|
429
|
-
const ip = device.ip || '';
|
|
430
|
-
content += `${device.name},${device.udid},${ip}\n`;
|
|
431
|
-
});
|
|
432
|
-
|
|
433
|
-
await fs.writeFile(DEVICE_CONFIG, content);
|
|
434
|
-
console.log(`✅ Auto-saved ${newDevices.length} new USB device(s) to config`);
|
|
435
|
-
} catch (error) {
|
|
436
|
-
console.error('Error auto-saving devices:', error);
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
// Check device connectivity
|
|
441
|
-
function checkDeviceConnectivity(device) {
|
|
442
|
-
return new Promise((resolve) => {
|
|
443
|
-
const curl = spawn('curl', [
|
|
444
|
-
'-s',
|
|
445
|
-
'--connect-timeout', '2',
|
|
446
|
-
'--max-time', '3',
|
|
447
|
-
`http://${device.ip}:8100/status`
|
|
448
|
-
]);
|
|
449
|
-
|
|
450
|
-
let output = '';
|
|
451
|
-
curl.stdout.on('data', (data) => {
|
|
452
|
-
output += data.toString();
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
curl.on('close', (code) => {
|
|
456
|
-
resolve(output.includes('"state"'));
|
|
457
|
-
});
|
|
458
|
-
|
|
459
|
-
setTimeout(() => {
|
|
460
|
-
curl.kill();
|
|
461
|
-
resolve(false);
|
|
462
|
-
}, 3000);
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
// Load app presets from config file
|
|
467
|
-
function loadAppPresets() {
|
|
468
|
-
try {
|
|
469
|
-
if (!require('fs').existsSync(APPS_CONFIG)) {
|
|
470
|
-
return {};
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
const content = require('fs').readFileSync(APPS_CONFIG, 'utf-8');
|
|
474
|
-
const presets = {};
|
|
475
|
-
|
|
476
|
-
content.split('\n')
|
|
477
|
-
.filter(line => line.trim() && !line.startsWith('#'))
|
|
478
|
-
.forEach(line => {
|
|
479
|
-
const [name, packageId] = line.split(',').map(s => s.trim());
|
|
480
|
-
if (name && packageId) {
|
|
481
|
-
// Support platform-specific notation: name.ios or name.android
|
|
482
|
-
const parts = name.split('.');
|
|
483
|
-
if (parts.length === 2) {
|
|
484
|
-
const [appName, platform] = parts;
|
|
485
|
-
if (!presets[appName]) presets[appName] = {};
|
|
486
|
-
presets[appName][platform] = packageId;
|
|
487
|
-
} else {
|
|
488
|
-
// Generic app (works on both platforms)
|
|
489
|
-
if (!presets[name]) presets[name] = {};
|
|
490
|
-
presets[name].common = packageId;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
});
|
|
494
|
-
|
|
495
|
-
return presets;
|
|
496
|
-
} catch (error) {
|
|
497
|
-
console.error('Error loading app presets:', error);
|
|
498
|
-
return {};
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
// Resolve app preset based on device platform
|
|
503
|
-
function resolveAppPreset(command, platform) {
|
|
504
|
-
const appPresets = loadAppPresets();
|
|
505
|
-
|
|
506
|
-
// Check if command is "launch <appname>"
|
|
507
|
-
const launchMatch = command.match(/^launch\s+(\S+)(.*)$/);
|
|
508
|
-
if (!launchMatch) return command; // Not a launch command
|
|
509
|
-
|
|
510
|
-
const appName = launchMatch[1];
|
|
511
|
-
const restOfCommand = launchMatch[2];
|
|
512
|
-
|
|
513
|
-
// If it already looks like a bundle ID, don't resolve
|
|
514
|
-
if (appName.includes('.')) return command;
|
|
515
|
-
|
|
516
|
-
// Look up preset
|
|
517
|
-
if (appPresets[appName]) {
|
|
518
|
-
const preset = appPresets[appName];
|
|
519
|
-
let bundleId;
|
|
520
|
-
|
|
521
|
-
// Try platform-specific first, then common
|
|
522
|
-
if (preset[platform]) {
|
|
523
|
-
bundleId = preset[platform];
|
|
524
|
-
} else if (preset.common) {
|
|
525
|
-
bundleId = preset.common;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
if (bundleId) {
|
|
529
|
-
console.log(` 📱 Resolved app preset: "${appName}" → "${bundleId}" (${platform})`);
|
|
530
|
-
return `launch ${bundleId}${restOfCommand}`;
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
// No preset found, return original
|
|
535
|
-
return command;
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
// Execute command on device(s)
|
|
539
|
-
function executeCommand(deviceNames, command, wsClient) {
|
|
540
|
-
return new Promise(async (resolve, reject) => {
|
|
541
|
-
// separator removed
|
|
542
|
-
logger.debug(`Device names received: [${deviceNames.join(', ')}]`);
|
|
543
|
-
console.log(`Command: "${command}"`);
|
|
544
|
-
// separator removed
|
|
545
|
-
|
|
546
|
-
// Get full device objects from connectedDevices cache
|
|
547
|
-
// Match by name, udid, or serial
|
|
548
|
-
const devices = connectedDevices.filter(d =>
|
|
549
|
-
deviceNames.includes(d.name) ||
|
|
550
|
-
deviceNames.includes(d.udid) ||
|
|
551
|
-
deviceNames.includes(d.serial)
|
|
552
|
-
);
|
|
553
|
-
|
|
554
|
-
logger.debug(`Cache contents:`, connectedDevices.map(d => `${d.name}(${d.status})`).join(', '));
|
|
555
|
-
|
|
556
|
-
if (devices.length === 0) {
|
|
557
|
-
console.error(`❌ No devices found for: [${deviceNames.join(', ')}]`);
|
|
558
|
-
return reject({ success: false, error: 'No devices found. Please refresh device list and try again.' });
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// Check if devices are online/connected
|
|
562
|
-
// Accept both 'online' and 'connected' as valid statuses
|
|
563
|
-
const offlineDevices = devices.filter(d => !['online', 'connected'].includes(d.status));
|
|
564
|
-
if (offlineDevices.length > 0) {
|
|
565
|
-
const offlineNames = offlineDevices.map(d => `${d.name} (status: ${d.status})`).join(', ');
|
|
566
|
-
console.error(`❌ Devices not connected: [${offlineNames}]`);
|
|
567
|
-
|
|
568
|
-
// Send user-friendly message via WebSocket
|
|
569
|
-
if (wsClient) {
|
|
570
|
-
wsClient.send(JSON.stringify({
|
|
571
|
-
type: 'command_output',
|
|
572
|
-
data: `\n⚠️ Error: Devices not connected: ${offlineNames}\n\n💡 Please click the "Connect" button on each device before running commands.\n\n`,
|
|
573
|
-
devices: deviceNames
|
|
574
|
-
}));
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
return reject({
|
|
578
|
-
success: false,
|
|
579
|
-
error: `Devices not connected: ${offlineNames}. Please click "Connect" button on each device first.`
|
|
580
|
-
});
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
console.log(`✅ Found ${devices.length} connected devices`);
|
|
584
|
-
console.log('Device details:', devices.map(d => `${d.name}(${d.platform}-${d.connectionType})`).join(', '));
|
|
585
|
-
|
|
586
|
-
// Group devices by platform and connection type
|
|
587
|
-
const iosUSBDevices = devices.filter(d => d.platform === 'ios' && d.connectionType === 'usb');
|
|
588
|
-
const iosWirelessDevices = devices.filter(d => d.platform === 'ios' && d.connectionType === 'wireless');
|
|
589
|
-
const androidUSBDevices = devices.filter(d => d.platform === 'android' && d.connectionType === 'usb');
|
|
590
|
-
const androidWirelessDevices = devices.filter(d => d.platform === 'android' && d.connectionType === 'wireless');
|
|
591
|
-
|
|
592
|
-
const promises = [];
|
|
593
|
-
|
|
594
|
-
// Execute for iOS USB devices
|
|
595
|
-
if (iosUSBDevices.length > 0) {
|
|
596
|
-
const names = iosUSBDevices.map(d => d.name);
|
|
597
|
-
const iosCommand = resolveAppPreset(command, 'ios');
|
|
598
|
-
logger.debug(`Using iOS USB script for: ${names.join(', ')}`);
|
|
599
|
-
promises.push(executeWithScript(USB_SCRIPT_PATH, names, iosCommand, wsClient));
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
// Execute for iOS wireless devices
|
|
603
|
-
if (iosWirelessDevices.length > 0) {
|
|
604
|
-
const names = iosWirelessDevices.map(d => d.name);
|
|
605
|
-
const iosCommand = resolveAppPreset(command, 'ios');
|
|
606
|
-
console.log(`Using iOS wireless script for: ${names.join(', ')}`);
|
|
607
|
-
promises.push(executeWithScript(WIRELESS_SCRIPT_PATH, names, iosCommand, wsClient));
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
// Execute for Android USB devices
|
|
611
|
-
if (androidUSBDevices.length > 0) {
|
|
612
|
-
const androidCommand = resolveAppPreset(command, 'android');
|
|
613
|
-
logger.debug(`Using Android control script for USB devices: ${androidUSBDevices.map(d => d.name).join(', ')}`);
|
|
614
|
-
promises.push(executeAndroidDevices(ANDROID_USB_SCRIPT_PATH, androidUSBDevices, androidCommand, wsClient));
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
// Execute for Android wireless devices
|
|
618
|
-
if (androidWirelessDevices.length > 0) {
|
|
619
|
-
const androidCommand = resolveAppPreset(command, 'android');
|
|
620
|
-
logger.debug(`Using Android control script for wireless devices: ${androidWirelessDevices.map(d => d.name).join(', ')}`);
|
|
621
|
-
promises.push(executeAndroidDevices(ANDROID_WIRELESS_SCRIPT_PATH, androidWirelessDevices, androidCommand, wsClient));
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
if (promises.length === 0) {
|
|
625
|
-
|
|
626
|
-
return reject({ success: false, error: 'No executable devices found' });
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
try {
|
|
630
|
-
const results = await Promise.allSettled(promises);
|
|
631
|
-
const successCount = results.filter(r => r.status === 'fulfilled').length;
|
|
632
|
-
const failCount = results.filter(r => r.status === 'rejected').length;
|
|
633
|
-
|
|
634
|
-
logger.debug(`ExecuteCommand summary: ${successCount} succeeded, ${failCount} failed`);
|
|
635
|
-
|
|
636
|
-
resolve({
|
|
637
|
-
success: true,
|
|
638
|
-
results,
|
|
639
|
-
summary: `${successCount}/${promises.length} script groups completed`
|
|
640
|
-
});
|
|
641
|
-
} catch (error) {
|
|
642
|
-
console.error('Script execution error:', error);
|
|
643
|
-
reject(error);
|
|
644
|
-
}
|
|
645
|
-
});
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
function executeWithScript(scriptPath, deviceNames, command, wsClient) {
|
|
649
|
-
return new Promise((resolve, reject) => {
|
|
650
|
-
logger.debug(`\n${'='.repeat(60)}`);
|
|
651
|
-
logger.debug(`Script: ${path.basename(scriptPath)}`);
|
|
652
|
-
logger.debug(`Devices: [${deviceNames.join(', ')}]`);
|
|
653
|
-
logger.debug(`Command: "${command}"`);
|
|
654
|
-
logger.debug(`${'='.repeat(60)}\n`);
|
|
655
|
-
|
|
656
|
-
// Execute command on each device in parallel
|
|
657
|
-
const devicePromises = deviceNames.map((deviceName, index) => {
|
|
658
|
-
|
|
659
|
-
return new Promise((resolveDevice, rejectDevice) => {
|
|
660
|
-
// Use -d flag for each device
|
|
661
|
-
const args = ['-d', deviceName, command];
|
|
662
|
-
|
|
663
|
-
logger.debug(`[${index + 1}/${deviceNames.length}] Executing on: ${deviceName}`);
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
const child = spawn(scriptPath, args, {
|
|
667
|
-
cwd: path.dirname(scriptPath)
|
|
668
|
-
});
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
let output = '';
|
|
672
|
-
let error = '';
|
|
673
|
-
|
|
674
|
-
child.stdout.on('data', (data) => {
|
|
675
|
-
const text = data.toString();
|
|
676
|
-
output += text;
|
|
677
|
-
logger.debug(`[${deviceName}] STDOUT: ${text.trim()}`);
|
|
678
|
-
if (wsClient) {
|
|
679
|
-
wsClient.send(JSON.stringify({
|
|
680
|
-
type: 'command_output',
|
|
681
|
-
data: `[${deviceName}] ${text}`,
|
|
682
|
-
devices: [deviceName]
|
|
683
|
-
}));
|
|
684
|
-
}
|
|
685
|
-
});
|
|
686
|
-
|
|
687
|
-
child.stderr.on('data', (data) => {
|
|
688
|
-
const text = data.toString();
|
|
689
|
-
error += text;
|
|
690
|
-
console.error(`[${deviceName}] STDERR: ${text.trim()}`);
|
|
691
|
-
});
|
|
692
|
-
|
|
693
|
-
child.on('close', (code) => {
|
|
694
|
-
|
|
695
|
-
if (code === 0) {
|
|
696
|
-
resolveDevice({ success: true, output, device: deviceName });
|
|
697
|
-
} else {
|
|
698
|
-
rejectDevice({ success: false, error: error || `Script exited with code ${code}`, device: deviceName });
|
|
699
|
-
}
|
|
700
|
-
});
|
|
701
|
-
|
|
702
|
-
child.on('error', (err) => {
|
|
703
|
-
console.error(`[${deviceName}] Process error: ${err.message}`);
|
|
704
|
-
rejectDevice({ success: false, error: err.message, device: deviceName });
|
|
705
|
-
});
|
|
706
|
-
});
|
|
707
|
-
});
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
// Wait for all devices to complete
|
|
711
|
-
Promise.allSettled(devicePromises)
|
|
712
|
-
.then(results => {
|
|
713
|
-
const successful = results.filter(r => r.status === 'fulfilled').length;
|
|
714
|
-
const failed = results.filter(r => r.status === 'rejected').length;
|
|
715
|
-
|
|
716
|
-
// separator removed
|
|
717
|
-
|
|
718
|
-
// separator removed
|
|
719
|
-
|
|
720
|
-
resolve({
|
|
721
|
-
success: true,
|
|
722
|
-
results,
|
|
723
|
-
summary: `${successful}/${deviceNames.length} devices completed successfully`
|
|
724
|
-
});
|
|
725
|
-
})
|
|
726
|
-
.catch(error => {
|
|
727
|
-
console.error(`Promise.allSettled error: ${error.message}`);
|
|
728
|
-
reject(error);
|
|
729
|
-
});
|
|
730
|
-
});
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
// Execute Android commands (uses device UDID instead of name)
|
|
734
|
-
function executeAndroidDevices(scriptPath, devices, command, wsClient) {
|
|
735
|
-
return new Promise((resolve, reject) => {
|
|
736
|
-
logger.debug(`\n${'='.repeat(60)}`);
|
|
737
|
-
logger.debug(`Script: ${path.basename(scriptPath)}`);
|
|
738
|
-
logger.debug(`Devices: [${devices.map(d => d.name).join(', ')}]`);
|
|
739
|
-
logger.debug(`Command: "${command}"`);
|
|
740
|
-
logger.debug(`${'='.repeat(60)}\n`);
|
|
741
|
-
|
|
742
|
-
// Execute command on each device in parallel
|
|
743
|
-
const devicePromises = devices.map((device, index) => {
|
|
744
|
-
logger.debug(`[${index + 1}/${devices.length}] Creating execution promise for: ${device.name} (${device.udid}`);
|
|
745
|
-
|
|
746
|
-
return new Promise((resolveDevice, rejectDevice) => {
|
|
747
|
-
// Android script expects: <device_serial> <command> [args...]
|
|
748
|
-
// Use UDID (which is the serial for Android)
|
|
749
|
-
const args = [device.udid, ...command.split(' ')];
|
|
750
|
-
|
|
751
|
-
const child = spawn(scriptPath, args, {
|
|
752
|
-
cwd: path.dirname(scriptPath)
|
|
753
|
-
});
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
let output = '';
|
|
757
|
-
let error = '';
|
|
758
|
-
|
|
759
|
-
child.stdout.on('data', (data) => {
|
|
760
|
-
const text = data.toString();
|
|
761
|
-
output += text;
|
|
762
|
-
logger.debug(`[${device.name}] STDOUT: ${text.trim()}`);
|
|
763
|
-
if (wsClient) {
|
|
764
|
-
wsClient.send(JSON.stringify({
|
|
765
|
-
type: 'output',
|
|
766
|
-
device: device.name,
|
|
767
|
-
data: text
|
|
768
|
-
}));
|
|
769
|
-
}
|
|
770
|
-
});
|
|
771
|
-
|
|
772
|
-
child.stderr.on('data', (data) => {
|
|
773
|
-
const text = data.toString();
|
|
774
|
-
error += text;
|
|
775
|
-
logger.debug(`[${device.name}] STDERR: ${text.trim()}`);
|
|
776
|
-
});
|
|
777
|
-
|
|
778
|
-
child.on('close', (code) => {
|
|
779
|
-
|
|
780
|
-
if (code === 0) {
|
|
781
|
-
resolveDevice({ success: true, output, device: device.name });
|
|
782
|
-
} else {
|
|
783
|
-
resolveDevice({ success: false, error: error || output, device: device.name });
|
|
784
|
-
}
|
|
785
|
-
});
|
|
786
|
-
|
|
787
|
-
child.on('error', (err) => {
|
|
788
|
-
console.error(`[${device.name}] Process error:`, err);
|
|
789
|
-
resolveDevice({ success: false, error: err.message, device: device.name });
|
|
790
|
-
});
|
|
791
|
-
});
|
|
792
|
-
});
|
|
793
|
-
|
|
794
|
-
Promise.allSettled(devicePromises)
|
|
795
|
-
.then(results => {
|
|
796
|
-
// separator removed
|
|
797
|
-
|
|
798
|
-
const successCount = results.filter(r => r.status === 'fulfilled' && r.value.success).length;
|
|
799
|
-
const failCount = results.length - successCount;
|
|
800
|
-
|
|
801
|
-
// separator removed
|
|
802
|
-
|
|
803
|
-
resolve({ success: true, results });
|
|
804
|
-
})
|
|
805
|
-
.catch(error => {
|
|
806
|
-
console.error('Execution error:', error);
|
|
807
|
-
reject(error);
|
|
808
|
-
});
|
|
809
|
-
});
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
// AI-powered command conversion (supports multiple providers)
|
|
813
|
-
async function convertNaturalLanguageToCommand(text, devices, provider = null) {
|
|
814
|
-
// Determine platforms from devices
|
|
815
|
-
const deviceObjs = connectedDevices.filter(d => devices.includes(d.name));
|
|
816
|
-
|
|
817
|
-
if (deviceObjs.length === 0) {
|
|
818
|
-
// No devices found, try with null platform
|
|
819
|
-
return await aiManager.convertCommand(text, null, provider);
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
// Group devices by platform
|
|
823
|
-
const platforms = [...new Set(deviceObjs.map(d => d.platform))];
|
|
824
|
-
|
|
825
|
-
console.log(`AI converting for ${deviceObjs.length} device(s) across ${platforms.length} platform(s): ${platforms.join(', ')}`);
|
|
826
|
-
|
|
827
|
-
// For multi-platform, use 'both' to get generic app names
|
|
828
|
-
// The executeCommand function will resolve platform-specific package IDs
|
|
829
|
-
const platform = platforms.length === 1 ? platforms[0] : 'both';
|
|
830
|
-
|
|
831
|
-
console.log(`AI using platform mode: ${platform}`);
|
|
832
|
-
return await aiManager.convertCommand(text, platform, provider);
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
// Execute commands sequentially with WAIT support
|
|
836
|
-
async function executeCommandsSequentially(devices, commandsText, wsClient) {
|
|
837
|
-
const lines = commandsText.split('\n').map(line => line.trim()).filter(line => line);
|
|
838
|
-
|
|
839
|
-
// separator removed
|
|
840
|
-
|
|
841
|
-
console.log(`Total commands: ${lines.length}`);
|
|
842
|
-
console.log(`Commands:`, lines);
|
|
843
|
-
// separator removed
|
|
844
|
-
|
|
845
|
-
const results = [];
|
|
846
|
-
|
|
847
|
-
for (let i = 0; i < lines.length; i++) {
|
|
848
|
-
const line = lines[i];
|
|
849
|
-
|
|
850
|
-
// Skip comments
|
|
851
|
-
if (line.startsWith('#')) {
|
|
852
|
-
continue;
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
// Check if it's a WAIT command
|
|
856
|
-
if (line.startsWith('WAIT ')) {
|
|
857
|
-
const waitTime = parseInt(line.replace('WAIT ', ''));
|
|
858
|
-
console.log(`⏳ Waiting ${waitTime}ms before next command...`);
|
|
859
|
-
|
|
860
|
-
if (wsClient) {
|
|
861
|
-
wsClient.send(JSON.stringify({
|
|
862
|
-
type: 'command_output',
|
|
863
|
-
data: `⏳ Waiting ${waitTime}ms...\n`,
|
|
864
|
-
devices: devices
|
|
865
|
-
}));
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
869
|
-
results.push({ command: line, success: true, output: `Waited ${waitTime}ms` });
|
|
870
|
-
continue;
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
// Execute the command on ALL devices simultaneously
|
|
874
|
-
console.log(`\n▶️ Executing command ${i + 1}/${lines.length}: "${line}"`);
|
|
875
|
-
|
|
876
|
-
if (wsClient) {
|
|
877
|
-
wsClient.send(JSON.stringify({
|
|
878
|
-
type: 'command_output',
|
|
879
|
-
data: `▶️ [${i + 1}/${lines.length}] ${line}\n`,
|
|
880
|
-
devices: devices
|
|
881
|
-
}));
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
try {
|
|
885
|
-
const result = await executeCommand(devices, line, wsClient);
|
|
886
|
-
results.push({ command: line, success: true, result });
|
|
887
|
-
console.log(`✅ Command ${i + 1} completed successfully`);
|
|
888
|
-
} catch (error) {
|
|
889
|
-
console.error(`❌ Command ${i + 1} failed:`, error.message);
|
|
890
|
-
results.push({ command: line, success: false, error: error.message });
|
|
891
|
-
|
|
892
|
-
if (wsClient) {
|
|
893
|
-
wsClient.send(JSON.stringify({
|
|
894
|
-
type: 'command_output',
|
|
895
|
-
data: `❌ Error: ${error.message}\n`,
|
|
896
|
-
devices: devices
|
|
897
|
-
}));
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
// separator removed
|
|
903
|
-
|
|
904
|
-
console.log(`Total: ${results.length}, Success: ${results.filter(r => r.success).length}, Failed: ${results.filter(r => !r.success).length}`);
|
|
905
|
-
// separator removed
|
|
906
|
-
|
|
907
|
-
return {
|
|
908
|
-
success: true,
|
|
909
|
-
results,
|
|
910
|
-
summary: `Executed ${results.length} commands`
|
|
911
|
-
};
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
// Create WDA session for a device
|
|
915
|
-
async function createWDASession(host, deviceName) {
|
|
916
|
-
return new Promise(async (resolve) => {
|
|
917
|
-
const sessionFile = '/tmp/ios_multi_sessions';
|
|
918
|
-
|
|
919
|
-
// First, check if session already exists for this device
|
|
920
|
-
try {
|
|
921
|
-
const existingContent = await fs.readFile(sessionFile, 'utf-8').catch(() => '');
|
|
922
|
-
const lines = existingContent.split('\n').filter(line => line.trim());
|
|
923
|
-
|
|
924
|
-
for (const line of lines) {
|
|
925
|
-
const [name, sessionId] = line.split(':');
|
|
926
|
-
if (name === deviceName && sessionId) {
|
|
927
|
-
// Session already exists, verify it's still valid
|
|
928
|
-
const port = host === 'localhost' ? 8100 : 8100;
|
|
929
|
-
const verifyUrl = `http://${host}:${port}/session/${sessionId}`;
|
|
930
|
-
|
|
931
|
-
const verifyProcess = spawn('curl', ['-s', '-X', 'GET', verifyUrl]);
|
|
932
|
-
let verifyOutput = '';
|
|
933
|
-
|
|
934
|
-
verifyProcess.stdout.on('data', (data) => {
|
|
935
|
-
verifyOutput += data.toString();
|
|
936
|
-
});
|
|
937
|
-
|
|
938
|
-
verifyProcess.on('close', (code) => {
|
|
939
|
-
if (code === 0 && verifyOutput && !verifyOutput.includes('invalid session id')) {
|
|
940
|
-
console.log(`✅ Existing valid session found: ${sessionId}`);
|
|
941
|
-
return resolve({ success: true, sessionId, existing: true });
|
|
942
|
-
} else {
|
|
943
|
-
// Session is invalid, create a new one
|
|
944
|
-
createNewSession(host, deviceName, sessionFile, resolve);
|
|
945
|
-
}
|
|
946
|
-
});
|
|
947
|
-
|
|
948
|
-
return;
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
} catch (e) {
|
|
952
|
-
// File doesn't exist or error reading, create new session
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
// No existing session, create a new one
|
|
956
|
-
createNewSession(host, deviceName, sessionFile, resolve);
|
|
957
|
-
});
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
function createNewSession(host, deviceName, sessionFile, resolve) {
|
|
961
|
-
const port = host === 'localhost' ? 8100 : 8100;
|
|
962
|
-
const sessionUrl = `http://${host}:${port}/session`;
|
|
963
|
-
|
|
964
|
-
const curlProcess = spawn('curl', [
|
|
965
|
-
'-s',
|
|
966
|
-
'-X', 'POST',
|
|
967
|
-
sessionUrl,
|
|
968
|
-
'-H', 'Content-Type: application/json',
|
|
969
|
-
'-d', '{"capabilities":{"alwaysMatch":{}}}'
|
|
970
|
-
]);
|
|
971
|
-
|
|
972
|
-
let output = '';
|
|
973
|
-
curlProcess.stdout.on('data', (data) => {
|
|
974
|
-
output += data.toString();
|
|
975
|
-
});
|
|
976
|
-
|
|
977
|
-
curlProcess.on('close', (code) => {
|
|
978
|
-
if (code === 0 && output) {
|
|
979
|
-
try {
|
|
980
|
-
const response = JSON.parse(output);
|
|
981
|
-
const sessionId = response.sessionId || response.value?.sessionId;
|
|
982
|
-
|
|
983
|
-
if (sessionId) {
|
|
984
|
-
// Read existing sessions and update
|
|
985
|
-
fs.readFile(sessionFile, 'utf-8')
|
|
986
|
-
.catch(() => '')
|
|
987
|
-
.then(existingContent => {
|
|
988
|
-
// Remove old session for this device if exists
|
|
989
|
-
const lines = existingContent.split('\n').filter(line => {
|
|
990
|
-
const [name] = line.split(':');
|
|
991
|
-
return line.trim() && name !== deviceName;
|
|
992
|
-
});
|
|
993
|
-
|
|
994
|
-
// Add new session
|
|
995
|
-
lines.push(`${deviceName}:${sessionId}`);
|
|
996
|
-
|
|
997
|
-
// Write back to file
|
|
998
|
-
return fs.writeFile(sessionFile, lines.join('\n') + '\n');
|
|
999
|
-
})
|
|
1000
|
-
.then(() => {
|
|
1001
|
-
console.log(`✅ New session created and saved: ${sessionId}`);
|
|
1002
|
-
resolve({ success: true, sessionId });
|
|
1003
|
-
})
|
|
1004
|
-
.catch((err) => {
|
|
1005
|
-
console.error(`❌ Failed to save session for ${deviceName}:`, err);
|
|
1006
|
-
resolve({ success: false });
|
|
1007
|
-
});
|
|
1008
|
-
} else {
|
|
1009
|
-
resolve({ success: false });
|
|
1010
|
-
}
|
|
1011
|
-
} catch (e) {
|
|
1012
|
-
console.error('Failed to parse WDA session response:', e);
|
|
1013
|
-
resolve({ success: false });
|
|
1014
|
-
}
|
|
1015
|
-
} else {
|
|
1016
|
-
resolve({ success: false });
|
|
1017
|
-
}
|
|
1018
|
-
});
|
|
1019
|
-
|
|
1020
|
-
curlProcess.on('error', (err) => {
|
|
1021
|
-
console.error('Error creating WDA session:', err);
|
|
1022
|
-
resolve({ success: false });
|
|
1023
|
-
});
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
// Install UIAutomator2 on Android device
|
|
1027
|
-
async function installUIAutomator2(deviceUdid, deviceName) {
|
|
1028
|
-
return new Promise((resolve) => {
|
|
1029
|
-
console.log(`📥 Installing UIAutomator2 on ${deviceName}...`);
|
|
1030
|
-
|
|
1031
|
-
const { execSync } = require('child_process');
|
|
1032
|
-
const os = require('os');
|
|
1033
|
-
const path = require('path');
|
|
1034
|
-
|
|
1035
|
-
try {
|
|
1036
|
-
// Try multiple locations for APKs
|
|
1037
|
-
const possiblePaths = [
|
|
1038
|
-
// Appium installed location
|
|
1039
|
-
path.join(os.homedir(), '.appium', 'node_modules', 'appium-uiautomator2-driver', 'node_modules', 'appium-uiautomator2-server', 'apks'),
|
|
1040
|
-
// Global npm location
|
|
1041
|
-
execSync('npm root -g', { encoding: 'utf-8' }).trim() + '/appium-uiautomator2-driver/node_modules/appium-uiautomator2-server/apks',
|
|
1042
|
-
// Alternative npm location
|
|
1043
|
-
execSync('npm root -g', { encoding: 'utf-8' }).trim() + '/appium/node_modules/appium-uiautomator2-driver/node_modules/appium-uiautomator2-server/apks',
|
|
1044
|
-
];
|
|
1045
|
-
|
|
1046
|
-
let serverApk = null;
|
|
1047
|
-
let testApk = null;
|
|
1048
|
-
let foundPath = null;
|
|
1049
|
-
|
|
1050
|
-
// Try each path
|
|
1051
|
-
for (const apkPath of possiblePaths) {
|
|
1052
|
-
console.log(`📂 Checking: ${apkPath}`);
|
|
1053
|
-
|
|
1054
|
-
try {
|
|
1055
|
-
const serverCheck = execSync(`ls "${apkPath}"/appium-uiautomator2-server-v*.apk 2>/dev/null || echo ""`, { encoding: 'utf-8' }).trim();
|
|
1056
|
-
const testCheck = execSync(`ls "${apkPath}"/appium-uiautomator2-server-debug-androidTest.apk 2>/dev/null || echo ""`, { encoding: 'utf-8' }).trim();
|
|
1057
|
-
|
|
1058
|
-
if (serverCheck && testCheck) {
|
|
1059
|
-
serverApk = serverCheck;
|
|
1060
|
-
testApk = testCheck;
|
|
1061
|
-
foundPath = apkPath;
|
|
1062
|
-
console.log(`✅ Found APKs in: ${foundPath}`);
|
|
1063
|
-
break;
|
|
1064
|
-
}
|
|
1065
|
-
} catch (e) {
|
|
1066
|
-
continue;
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
|
|
1070
|
-
if (serverApk && testApk) {
|
|
1071
|
-
console.log(`📦 Installing server APK: ${serverApk}`);
|
|
1072
|
-
const serverOutput = execSync(`adb -s ${deviceUdid} install -r "${serverApk}" 2>&1`, { encoding: 'utf-8' });
|
|
1073
|
-
console.log(serverOutput);
|
|
1074
|
-
|
|
1075
|
-
console.log(`📦 Installing test APK: ${testApk}`);
|
|
1076
|
-
const testOutput = execSync(`adb -s ${deviceUdid} install -r "${testApk}" 2>&1`, { encoding: 'utf-8' });
|
|
1077
|
-
console.log(testOutput);
|
|
1078
|
-
|
|
1079
|
-
console.log(`✅ UIAutomator2 installed successfully on ${deviceName}`);
|
|
1080
|
-
resolve({
|
|
1081
|
-
success: true,
|
|
1082
|
-
message: 'UIAutomator2 installed successfully'
|
|
1083
|
-
});
|
|
1084
|
-
} else {
|
|
1085
|
-
console.log(`⚠️ APK files not found in any expected location`);
|
|
1086
|
-
console.log(`Tried paths:`, possiblePaths);
|
|
1087
|
-
|
|
1088
|
-
// Try using appium to install
|
|
1089
|
-
try {
|
|
1090
|
-
console.log(`🔄 Trying to install via Appium...`);
|
|
1091
|
-
const appiumOutput = execSync(`appium driver install uiautomator2 2>&1`, { encoding: 'utf-8' });
|
|
1092
|
-
console.log(appiumOutput);
|
|
1093
|
-
|
|
1094
|
-
resolve({
|
|
1095
|
-
success: false,
|
|
1096
|
-
message: 'APKs not found. Tried to reinstall driver. Please run: appium driver install uiautomator2'
|
|
1097
|
-
});
|
|
1098
|
-
} catch (appiumError) {
|
|
1099
|
-
resolve({
|
|
1100
|
-
success: false,
|
|
1101
|
-
message: 'UIAutomator2 APKs not found. Please run: appium driver install uiautomator2'
|
|
1102
|
-
});
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
} catch (error) {
|
|
1106
|
-
console.error(`❌ Failed to install UIAutomator2: ${error.message}`);
|
|
1107
|
-
resolve({
|
|
1108
|
-
success: false,
|
|
1109
|
-
message: `Failed to install UIAutomator2: ${error.message}`
|
|
1110
|
-
});
|
|
1111
|
-
}
|
|
1112
|
-
});
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
// Connect to device - starts WDA if needed
|
|
1116
|
-
async function connectToDevice(device) {
|
|
1117
|
-
return new Promise(async (resolve, reject) => {
|
|
1118
|
-
const { name, udid, type, ip, platform } = device;
|
|
1119
|
-
|
|
1120
|
-
console.log(`Connecting to ${name} (${type}, platform: ${platform})...`);
|
|
1121
|
-
|
|
1122
|
-
// Handle Android devices differently
|
|
1123
|
-
if (platform === 'android') {
|
|
1124
|
-
console.log(`📱 Android device detected: ${name}`);
|
|
1125
|
-
|
|
1126
|
-
// Check if device is connected via adb
|
|
1127
|
-
const checkAdb = spawn('adb', ['devices']);
|
|
1128
|
-
let output = '';
|
|
1129
|
-
|
|
1130
|
-
checkAdb.stdout.on('data', (data) => {
|
|
1131
|
-
output += data.toString();
|
|
1132
|
-
});
|
|
1133
|
-
|
|
1134
|
-
checkAdb.on('close', async (code) => {
|
|
1135
|
-
const deviceConnected = output.includes(udid.replace(':5555', '')) || output.includes(udid);
|
|
1136
|
-
|
|
1137
|
-
if (deviceConnected) {
|
|
1138
|
-
console.log(`✅ Android device ${name} is connected via ADB`);
|
|
1139
|
-
|
|
1140
|
-
// Don't set status to 'online' yet - wait for UIAutomator2 confirmation
|
|
1141
|
-
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1142
|
-
if (deviceIndex !== -1) {
|
|
1143
|
-
connectedDevices[deviceIndex].status = 'connecting';
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
// Broadcast connecting status
|
|
1147
|
-
wss.clients.forEach(client => {
|
|
1148
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
1149
|
-
client.send(JSON.stringify({
|
|
1150
|
-
type: 'devices_updated',
|
|
1151
|
-
devices: connectedDevices
|
|
1152
|
-
}));
|
|
1153
|
-
}
|
|
1154
|
-
});
|
|
1155
|
-
|
|
1156
|
-
// Always ensure UIAutomator2 is installed and ready
|
|
1157
|
-
console.log(`📦 Ensuring UIAutomator2 is installed on ${name}...`);
|
|
1158
|
-
|
|
1159
|
-
// Check if already installed
|
|
1160
|
-
const checkUiAutomator = spawn('adb', ['-s', udid, 'shell', 'pm', 'list', 'packages', 'io.appium.uiautomator2']);
|
|
1161
|
-
let uiautomatorOutput = '';
|
|
1162
|
-
|
|
1163
|
-
checkUiAutomator.stdout.on('data', (data) => {
|
|
1164
|
-
uiautomatorOutput += data.toString();
|
|
1165
|
-
});
|
|
1166
|
-
|
|
1167
|
-
checkUiAutomator.on('close', async () => {
|
|
1168
|
-
const isInstalled = uiautomatorOutput.includes('io.appium.uiautomator2');
|
|
1169
|
-
|
|
1170
|
-
if (!isInstalled) {
|
|
1171
|
-
console.log(`📥 UIAutomator2 not found on ${name}, installing...`);
|
|
1172
|
-
// Install UIAutomator2
|
|
1173
|
-
const installResult = await installUIAutomator2(udid, name);
|
|
1174
|
-
|
|
1175
|
-
if (!installResult.success) {
|
|
1176
|
-
console.log(`⚠️ UIAutomator2 installation failed on ${name}`);
|
|
1177
|
-
resolve({
|
|
1178
|
-
success: true,
|
|
1179
|
-
message: `Connected to ${name} - ADB Ready ✅`
|
|
1180
|
-
});
|
|
1181
|
-
return;
|
|
1182
|
-
}
|
|
1183
|
-
} else {
|
|
1184
|
-
console.log(`✅ UIAutomator2 already installed on ${name}`);
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
// Check if session already exists for this device
|
|
1188
|
-
const existingSession = androidSessions.get(udid);
|
|
1189
|
-
if (existingSession) {
|
|
1190
|
-
console.log(`♻️ Reusing existing UIAutomator2 session on ${name} (port: ${existingSession.port})`);
|
|
1191
|
-
|
|
1192
|
-
// Verify session is still valid
|
|
1193
|
-
try {
|
|
1194
|
-
const axios = require('axios');
|
|
1195
|
-
await axios.get(`http://localhost:${existingSession.port}/wd/hub/status`);
|
|
1196
|
-
console.log(`✅ Session verified and working on ${name}`);
|
|
1197
|
-
|
|
1198
|
-
// Set status to 'online'
|
|
1199
|
-
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1200
|
-
if (deviceIndex !== -1) {
|
|
1201
|
-
connectedDevices[deviceIndex].status = 'online';
|
|
1202
|
-
|
|
1203
|
-
// Broadcast updated status
|
|
1204
|
-
wss.clients.forEach(client => {
|
|
1205
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
1206
|
-
client.send(JSON.stringify({
|
|
1207
|
-
type: 'devices_updated',
|
|
1208
|
-
devices: connectedDevices
|
|
1209
|
-
}));
|
|
1210
|
-
}
|
|
1211
|
-
});
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
resolve({
|
|
1215
|
-
success: true,
|
|
1216
|
-
message: `Connected to ${name} - UIAutomator2 Ready ✅`
|
|
1217
|
-
});
|
|
1218
|
-
return;
|
|
1219
|
-
} catch (err) {
|
|
1220
|
-
console.log(`⚠️ Existing session invalid, creating new one for ${name}`);
|
|
1221
|
-
androidSessions.delete(udid);
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
|
-
// Start new UIAutomator2 session
|
|
1226
|
-
console.log(`🚀 Starting new UIAutomator2 session on ${name}...`);
|
|
1227
|
-
const sessionResult = await startUIAutomator2Session(udid, name);
|
|
1228
|
-
|
|
1229
|
-
if (sessionResult.success) {
|
|
1230
|
-
// Set status to 'online' only after UIAutomator2 is ready
|
|
1231
|
-
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1232
|
-
if (deviceIndex !== -1) {
|
|
1233
|
-
connectedDevices[deviceIndex].status = 'online';
|
|
1234
|
-
|
|
1235
|
-
// Broadcast updated status
|
|
1236
|
-
wss.clients.forEach(client => {
|
|
1237
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
1238
|
-
client.send(JSON.stringify({
|
|
1239
|
-
type: 'devices_updated',
|
|
1240
|
-
devices: connectedDevices
|
|
1241
|
-
}));
|
|
1242
|
-
}
|
|
1243
|
-
});
|
|
1244
|
-
}
|
|
1245
|
-
|
|
1246
|
-
resolve({
|
|
1247
|
-
success: true,
|
|
1248
|
-
message: `Connected to ${name} - UIAutomator2 Ready ✅`
|
|
1249
|
-
});
|
|
1250
|
-
} else {
|
|
1251
|
-
resolve({
|
|
1252
|
-
success: true,
|
|
1253
|
-
message: `Connected to ${name} - ADB Ready ✅`
|
|
1254
|
-
});
|
|
1255
|
-
}
|
|
1256
|
-
});
|
|
1257
|
-
} else {
|
|
1258
|
-
console.log(`❌ Android device ${name} not found in ADB`);
|
|
1259
|
-
|
|
1260
|
-
// If wireless, try to connect via adb
|
|
1261
|
-
if (type === 'wireless' && ip) {
|
|
1262
|
-
console.log(`📡 Attempting to connect to ${name} wirelessly at ${ip}:5555...`);
|
|
1263
|
-
const adbConnect = spawn('adb', ['connect', `${ip}:5555`]);
|
|
1264
|
-
|
|
1265
|
-
adbConnect.on('close', async (code) => {
|
|
1266
|
-
if (code === 0) {
|
|
1267
|
-
console.log(`✅ Connected to ${name} wirelessly`);
|
|
1268
|
-
|
|
1269
|
-
// Don't set status yet - wait for UIAutomator2
|
|
1270
|
-
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1271
|
-
if (deviceIndex !== -1) {
|
|
1272
|
-
connectedDevices[deviceIndex].status = 'connecting';
|
|
1273
|
-
}
|
|
1274
|
-
|
|
1275
|
-
// Always ensure UIAutomator2 is installed
|
|
1276
|
-
console.log(`📦 Ensuring UIAutomator2 is installed on ${name}...`);
|
|
1277
|
-
|
|
1278
|
-
// Check if already installed
|
|
1279
|
-
const checkUiAutomator = spawn('adb', ['-s', `${ip}:5555`, 'shell', 'pm', 'list', 'packages', 'io.appium.uiautomator2']);
|
|
1280
|
-
let uiautomatorOutput = '';
|
|
1281
|
-
|
|
1282
|
-
checkUiAutomator.stdout.on('data', (data) => {
|
|
1283
|
-
uiautomatorOutput += data.toString();
|
|
1284
|
-
});
|
|
1285
|
-
|
|
1286
|
-
checkUiAutomator.on('close', async () => {
|
|
1287
|
-
const isInstalled = uiautomatorOutput.includes('io.appium.uiautomator2');
|
|
1288
|
-
|
|
1289
|
-
if (!isInstalled) {
|
|
1290
|
-
console.log(`📥 UIAutomator2 not found on ${name}, installing...`);
|
|
1291
|
-
const installResult = await installUIAutomator2(`${ip}:5555`, name);
|
|
1292
|
-
if (!installResult.success) {
|
|
1293
|
-
console.log(`⚠️ UIAutomator2 installation failed on ${name}`);
|
|
1294
|
-
}
|
|
1295
|
-
} else {
|
|
1296
|
-
console.log(`✅ UIAutomator2 already installed on ${name}`);
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
|
-
// Check if session already exists for this device
|
|
1300
|
-
const existingSession = androidSessions.get(`${ip}:5555`);
|
|
1301
|
-
if (existingSession) {
|
|
1302
|
-
console.log(`♻️ Reusing existing UIAutomator2 session on ${name} (port: ${existingSession.port})`);
|
|
1303
|
-
|
|
1304
|
-
// Verify session is still valid
|
|
1305
|
-
try {
|
|
1306
|
-
const axios = require('axios');
|
|
1307
|
-
await axios.get(`http://localhost:${existingSession.port}/wd/hub/status`);
|
|
1308
|
-
console.log(`✅ Session verified and working on ${name}`);
|
|
1309
|
-
|
|
1310
|
-
// Set status to 'online'
|
|
1311
|
-
if (deviceIndex !== -1) {
|
|
1312
|
-
connectedDevices[deviceIndex].status = 'online';
|
|
1313
|
-
|
|
1314
|
-
// Broadcast updated status
|
|
1315
|
-
wss.clients.forEach(client => {
|
|
1316
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
1317
|
-
client.send(JSON.stringify({
|
|
1318
|
-
type: 'devices_updated',
|
|
1319
|
-
devices: connectedDevices
|
|
1320
|
-
}));
|
|
1321
|
-
}
|
|
1322
|
-
});
|
|
1323
|
-
}
|
|
1324
|
-
|
|
1325
|
-
resolve({
|
|
1326
|
-
success: true,
|
|
1327
|
-
message: `Connected to ${name} - UIAutomator2 Ready ✅`
|
|
1328
|
-
});
|
|
1329
|
-
return;
|
|
1330
|
-
} catch (err) {
|
|
1331
|
-
console.log(`⚠️ Existing session invalid, creating new one for ${name}`);
|
|
1332
|
-
androidSessions.delete(`${ip}:5555`);
|
|
1333
|
-
}
|
|
1334
|
-
}
|
|
1335
|
-
|
|
1336
|
-
// Start new UIAutomator2 session
|
|
1337
|
-
console.log(`🚀 Starting new UIAutomator2 session on ${name}...`);
|
|
1338
|
-
const sessionResult = await startUIAutomator2Session(`${ip}:5555`, name);
|
|
1339
|
-
|
|
1340
|
-
let message = '';
|
|
1341
|
-
if (sessionResult.success) {
|
|
1342
|
-
// Now set status to 'online' after UIAutomator2 is ready
|
|
1343
|
-
if (deviceIndex !== -1) {
|
|
1344
|
-
connectedDevices[deviceIndex].status = 'online';
|
|
1345
|
-
|
|
1346
|
-
// Broadcast updated status
|
|
1347
|
-
wss.clients.forEach(client => {
|
|
1348
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
1349
|
-
client.send(JSON.stringify({
|
|
1350
|
-
type: 'devices_updated',
|
|
1351
|
-
devices: connectedDevices
|
|
1352
|
-
}));
|
|
1353
|
-
}
|
|
1354
|
-
});
|
|
1355
|
-
}
|
|
1356
|
-
|
|
1357
|
-
message = `Connected to ${name} - UIAutomator2 Ready ✅`;
|
|
1358
|
-
} else {
|
|
1359
|
-
message = `Connected to ${name} - ADB Ready ✅`;
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
|
-
resolve({
|
|
1363
|
-
success: true,
|
|
1364
|
-
message: message
|
|
1365
|
-
});
|
|
1366
|
-
});
|
|
1367
|
-
} else {
|
|
1368
|
-
reject({
|
|
1369
|
-
success: false,
|
|
1370
|
-
message: `Failed to connect to ${name}. Make sure USB debugging is enabled and device is on the same network.`
|
|
1371
|
-
});
|
|
1372
|
-
}
|
|
1373
|
-
});
|
|
1374
|
-
} else {
|
|
1375
|
-
reject({
|
|
1376
|
-
success: false,
|
|
1377
|
-
message: `Android device ${name} not connected. Please connect via USB or enable wireless debugging.`
|
|
1378
|
-
});
|
|
1379
|
-
}
|
|
1380
|
-
}
|
|
1381
|
-
});
|
|
1382
|
-
|
|
1383
|
-
checkAdb.on('error', (err) => {
|
|
1384
|
-
console.error(`❌ ADB error: ${err.message}`);
|
|
1385
|
-
reject({
|
|
1386
|
-
success: false,
|
|
1387
|
-
message: `ADB not available. Please install Android SDK Platform-Tools.`
|
|
1388
|
-
});
|
|
1389
|
-
});
|
|
1390
|
-
|
|
1391
|
-
return; // Exit early for Android devices
|
|
1392
|
-
}
|
|
1393
|
-
|
|
1394
|
-
// iOS device handling continues below
|
|
1395
|
-
if (type === 'usb') {
|
|
1396
|
-
// For USB devices, check if WDA is already running
|
|
1397
|
-
const checkWDA = spawn('curl', [
|
|
1398
|
-
'-s',
|
|
1399
|
-
'--connect-timeout', '2',
|
|
1400
|
-
'http://localhost:8100/status'
|
|
1401
|
-
]);
|
|
1402
|
-
|
|
1403
|
-
let output = '';
|
|
1404
|
-
checkWDA.stdout.on('data', (data) => {
|
|
1405
|
-
output += data.toString();
|
|
1406
|
-
});
|
|
1407
|
-
|
|
1408
|
-
checkWDA.on('error', (err) => {
|
|
1409
|
-
console.error(`❌ Error checking WDA: ${err.message}`);
|
|
1410
|
-
reject({ success: false, message: `Failed to check WDA status: ${err.message}` });
|
|
1411
|
-
});
|
|
1412
|
-
|
|
1413
|
-
checkWDA.on('close', async (code) => {
|
|
1414
|
-
if (output.includes('"state"')) {
|
|
1415
|
-
console.log(`✅ WDA already running for ${name}`);
|
|
1416
|
-
|
|
1417
|
-
// Create WDA session if not exists
|
|
1418
|
-
console.log(`📱 Creating WDA session for ${name}...`);
|
|
1419
|
-
const sessionResult = await createWDASession('localhost', name);
|
|
1420
|
-
|
|
1421
|
-
if (sessionResult.success) {
|
|
1422
|
-
console.log(`✅ Session created: ${sessionResult.sessionId}`);
|
|
1423
|
-
} else {
|
|
1424
|
-
console.log(`⚠️ Session creation failed, will be created on first command`);
|
|
1425
|
-
}
|
|
1426
|
-
|
|
1427
|
-
// Update status to online
|
|
1428
|
-
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1429
|
-
if (deviceIndex !== -1) {
|
|
1430
|
-
connectedDevices[deviceIndex].status = 'online';
|
|
1431
|
-
}
|
|
1432
|
-
|
|
1433
|
-
// Broadcast updated device list
|
|
1434
|
-
wss.clients.forEach(client => {
|
|
1435
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
1436
|
-
client.send(JSON.stringify({
|
|
1437
|
-
type: 'devices_updated',
|
|
1438
|
-
devices: connectedDevices
|
|
1439
|
-
}));
|
|
1440
|
-
}
|
|
1441
|
-
});
|
|
1442
|
-
|
|
1443
|
-
resolve({ success: true, message: `Connected to ${name} - WDA Ready ✅` });
|
|
1444
|
-
} else {
|
|
1445
|
-
console.log(`🚀 Starting WDA for ${name} (UDID: ${udid})...`);
|
|
1446
|
-
|
|
1447
|
-
// Start WDA using xcodebuild
|
|
1448
|
-
// First, check if we have WebDriverAgent path
|
|
1449
|
-
const wdaPath = process.env.WDA_PATH || path.join(process.env.HOME, 'Downloads/WebDriverAgent-10.2.1');
|
|
1450
|
-
|
|
1451
|
-
console.log(`📂 WDA Path: ${wdaPath}`);
|
|
1452
|
-
console.log(`📱 Device UDID: ${udid}`);
|
|
1453
|
-
|
|
1454
|
-
// Start xcodebuild in background with piped output for debugging
|
|
1455
|
-
const wdaProcess = spawn('xcodebuild', [
|
|
1456
|
-
'test',
|
|
1457
|
-
'-project', path.join(wdaPath, 'WebDriverAgent.xcodeproj'),
|
|
1458
|
-
'-scheme', 'WebDriverAgentRunner',
|
|
1459
|
-
'-destination', `id=${udid}`,
|
|
1460
|
-
'IPHONEOS_DEPLOYMENT_TARGET=14.0'
|
|
1461
|
-
], {
|
|
1462
|
-
cwd: wdaPath,
|
|
1463
|
-
detached: true,
|
|
1464
|
-
stdio: ['ignore', 'pipe', 'pipe']
|
|
1465
|
-
});
|
|
1466
|
-
|
|
1467
|
-
// Log output for debugging
|
|
1468
|
-
wdaProcess.stdout.on('data', (data) => {
|
|
1469
|
-
const output = data.toString();
|
|
1470
|
-
if (output.includes('ServerURLHere') || output.includes('WebDriverAgent')) {
|
|
1471
|
-
console.log(`📱 WDA: ${output.trim()}`);
|
|
1472
|
-
}
|
|
1473
|
-
});
|
|
1474
|
-
|
|
1475
|
-
wdaProcess.stderr.on('data', (data) => {
|
|
1476
|
-
const error = data.toString();
|
|
1477
|
-
if (!error.includes('note:') && !error.includes('warning:')) {
|
|
1478
|
-
console.error(`⚠️ WDA Error: ${error.trim()}`);
|
|
1479
|
-
}
|
|
1480
|
-
});
|
|
1481
|
-
|
|
1482
|
-
wdaProcess.on('error', (err) => {
|
|
1483
|
-
console.error(`❌ Failed to start xcodebuild: ${err.message}`);
|
|
1484
|
-
});
|
|
1485
|
-
|
|
1486
|
-
wdaProcess.unref();
|
|
1487
|
-
|
|
1488
|
-
// Also start iproxy to forward port
|
|
1489
|
-
console.log(`🔌 Starting iproxy for port forwarding...`);
|
|
1490
|
-
const iproxyProcess = spawn('iproxy', ['8100', '8100'], {
|
|
1491
|
-
detached: true,
|
|
1492
|
-
stdio: ['ignore', 'pipe', 'pipe']
|
|
1493
|
-
});
|
|
1494
|
-
|
|
1495
|
-
iproxyProcess.stdout.on('data', (data) => {
|
|
1496
|
-
console.log(`🔌 iproxy: ${data.toString().trim()}`);
|
|
1497
|
-
});
|
|
1498
|
-
|
|
1499
|
-
iproxyProcess.on('error', (err) => {
|
|
1500
|
-
console.error(`❌ Failed to start iproxy: ${err.message}`);
|
|
1501
|
-
console.error(` Make sure libimobiledevice is installed: brew install libimobiledevice`);
|
|
1502
|
-
});
|
|
1503
|
-
|
|
1504
|
-
iproxyProcess.unref();
|
|
1505
|
-
|
|
1506
|
-
// Track WDA processes for cleanup on disconnect
|
|
1507
|
-
wdaProcesses.set(name, {
|
|
1508
|
-
xcodebuild: wdaProcess.pid,
|
|
1509
|
-
iproxy: iproxyProcess.pid
|
|
1510
|
-
});
|
|
1511
|
-
|
|
1512
|
-
console.log(`✅ WDA starting for ${name}. Process ID: ${wdaProcess.pid}`);
|
|
1513
|
-
|
|
1514
|
-
// Wait a bit for WDA to start, then verify
|
|
1515
|
-
setTimeout(() => {
|
|
1516
|
-
const verifyWDA = spawn('curl', [
|
|
1517
|
-
'-s',
|
|
1518
|
-
'--connect-timeout', '5',
|
|
1519
|
-
'http://localhost:8100/status'
|
|
1520
|
-
]);
|
|
1521
|
-
|
|
1522
|
-
let verifyOutput = '';
|
|
1523
|
-
verifyWDA.stdout.on('data', (data) => {
|
|
1524
|
-
verifyOutput += data.toString();
|
|
1525
|
-
});
|
|
1526
|
-
|
|
1527
|
-
verifyWDA.on('close', async () => {
|
|
1528
|
-
if (verifyOutput.includes('"state"')) {
|
|
1529
|
-
console.log(`✅ WDA successfully started for ${name}`);
|
|
1530
|
-
|
|
1531
|
-
// Create WDA session for USB device
|
|
1532
|
-
console.log(`📱 Creating WDA session for ${name}...`);
|
|
1533
|
-
const sessionResult = await createWDASession('localhost', name);
|
|
1534
|
-
|
|
1535
|
-
if (sessionResult.success) {
|
|
1536
|
-
console.log(`✅ Session created: ${sessionResult.sessionId}`);
|
|
1537
|
-
} else {
|
|
1538
|
-
console.log(`⚠️ Session creation failed, will be created on first command`);
|
|
1539
|
-
}
|
|
1540
|
-
|
|
1541
|
-
// Update device status to online in connectedDevices
|
|
1542
|
-
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1543
|
-
if (deviceIndex !== -1) {
|
|
1544
|
-
connectedDevices[deviceIndex].status = 'online';
|
|
1545
|
-
}
|
|
1546
|
-
|
|
1547
|
-
// Broadcast updated device list and connection status to all WebSocket clients
|
|
1548
|
-
wss.clients.forEach(client => {
|
|
1549
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
1550
|
-
client.send(JSON.stringify({
|
|
1551
|
-
type: 'devices_updated',
|
|
1552
|
-
devices: connectedDevices
|
|
1553
|
-
}));
|
|
1554
|
-
// Send connection complete message
|
|
1555
|
-
client.send(JSON.stringify({
|
|
1556
|
-
type: 'command_output',
|
|
1557
|
-
output: `✅ ${name} connected - WDA Ready!\n${'─'.repeat(50)}\n`,
|
|
1558
|
-
device: name
|
|
1559
|
-
}));
|
|
1560
|
-
}
|
|
1561
|
-
});
|
|
1562
|
-
} else {
|
|
1563
|
-
console.log(`⚠️ WDA still starting for ${name}...`);
|
|
1564
|
-
}
|
|
1565
|
-
});
|
|
1566
|
-
}, 8000); // Wait 8 seconds for WDA to start
|
|
1567
|
-
|
|
1568
|
-
// Return immediately with starting status
|
|
1569
|
-
resolve({
|
|
1570
|
-
success: true,
|
|
1571
|
-
message: `Connecting to ${name} - Starting WDA...`,
|
|
1572
|
-
wdaStarting: true
|
|
1573
|
-
});
|
|
1574
|
-
}
|
|
1575
|
-
});
|
|
1576
|
-
|
|
1577
|
-
checkWDA.on('error', () => {
|
|
1578
|
-
console.log(`⚠️ Could not check WDA status, attempting to start...`);
|
|
1579
|
-
resolve({ success: false, message: `Error checking WDA. Please start manually in Xcode.` });
|
|
1580
|
-
});
|
|
1581
|
-
} else {
|
|
1582
|
-
// For wireless devices, check if WDA is reachable
|
|
1583
|
-
const checkWDA = spawn('curl', [
|
|
1584
|
-
'-s',
|
|
1585
|
-
'--connect-timeout', '3',
|
|
1586
|
-
`http://${ip}:8100/status`
|
|
1587
|
-
]);
|
|
1588
|
-
|
|
1589
|
-
let output = '';
|
|
1590
|
-
checkWDA.stdout.on('data', (data) => {
|
|
1591
|
-
output += data.toString();
|
|
1592
|
-
});
|
|
1593
|
-
|
|
1594
|
-
checkWDA.on('close', async () => {
|
|
1595
|
-
if (output.includes('"state"')) {
|
|
1596
|
-
console.log(`✅ WDA reachable for ${name}`);
|
|
1597
|
-
|
|
1598
|
-
// Create WDA session for wireless device
|
|
1599
|
-
console.log(`📱 Creating WDA session for ${name}...`);
|
|
1600
|
-
const sessionResult = await createWDASession(ip, name);
|
|
1601
|
-
|
|
1602
|
-
if (sessionResult.success) {
|
|
1603
|
-
console.log(`✅ Session created: ${sessionResult.sessionId}`);
|
|
1604
|
-
} else {
|
|
1605
|
-
console.log(`⚠️ Session creation failed, will be created on first command`);
|
|
1606
|
-
}
|
|
1607
|
-
|
|
1608
|
-
// Update status to online
|
|
1609
|
-
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1610
|
-
if (deviceIndex !== -1) {
|
|
1611
|
-
connectedDevices[deviceIndex].status = 'online';
|
|
1612
|
-
}
|
|
1613
|
-
|
|
1614
|
-
// Broadcast updated device list
|
|
1615
|
-
wss.clients.forEach(client => {
|
|
1616
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
1617
|
-
client.send(JSON.stringify({
|
|
1618
|
-
type: 'devices_updated',
|
|
1619
|
-
devices: connectedDevices
|
|
1620
|
-
}));
|
|
1621
|
-
}
|
|
1622
|
-
});
|
|
1623
|
-
|
|
1624
|
-
resolve({ success: true, message: `Connected to ${name} - WDA Ready ✅` });
|
|
1625
|
-
} else {
|
|
1626
|
-
console.log(`❌ WDA not running on ${name}, attempting to start...`);
|
|
1627
|
-
|
|
1628
|
-
// Start WDA wirelessly using xcodebuild
|
|
1629
|
-
const wdaPath = process.env.WDA_PATH || path.join(process.env.HOME, 'Downloads/WebDriverAgent-10.2.1');
|
|
1630
|
-
|
|
1631
|
-
console.log(`📂 WDA Path: ${wdaPath}`);
|
|
1632
|
-
console.log(`📱 Device UDID: ${udid}`);
|
|
1633
|
-
console.log(`📡 Device IP: ${ip}`);
|
|
1634
|
-
|
|
1635
|
-
// Start xcodebuild in background for wireless device
|
|
1636
|
-
const wdaProcess = spawn('xcodebuild', [
|
|
1637
|
-
'test',
|
|
1638
|
-
'-project', path.join(wdaPath, 'WebDriverAgent.xcodeproj'),
|
|
1639
|
-
'-scheme', 'WebDriverAgentRunner',
|
|
1640
|
-
'-destination', `id=${udid}`,
|
|
1641
|
-
'IPHONEOS_DEPLOYMENT_TARGET=14.0'
|
|
1642
|
-
], {
|
|
1643
|
-
cwd: wdaPath,
|
|
1644
|
-
detached: true,
|
|
1645
|
-
stdio: ['ignore', 'pipe', 'pipe']
|
|
1646
|
-
});
|
|
1647
|
-
|
|
1648
|
-
// Log output for debugging
|
|
1649
|
-
wdaProcess.stdout.on('data', (data) => {
|
|
1650
|
-
const output = data.toString();
|
|
1651
|
-
if (output.includes('ServerURLHere') || output.includes('WebDriverAgent')) {
|
|
1652
|
-
console.log(`📱 WDA (${name}): ${output.trim()}`);
|
|
1653
|
-
}
|
|
1654
|
-
});
|
|
1655
|
-
|
|
1656
|
-
wdaProcess.stderr.on('data', (data) => {
|
|
1657
|
-
const error = data.toString();
|
|
1658
|
-
if (!error.includes('note:') && !error.includes('warning:')) {
|
|
1659
|
-
console.error(`⚠️ WDA Error (${name}): ${error.trim()}`);
|
|
1660
|
-
}
|
|
1661
|
-
});
|
|
1662
|
-
|
|
1663
|
-
wdaProcess.on('error', (err) => {
|
|
1664
|
-
console.error(`❌ Failed to start xcodebuild for ${name}: ${err.message}`);
|
|
1665
|
-
});
|
|
1666
|
-
|
|
1667
|
-
wdaProcess.unref();
|
|
1668
|
-
|
|
1669
|
-
// Track WDA process for cleanup on disconnect
|
|
1670
|
-
wdaProcesses.set(name, {
|
|
1671
|
-
xcodebuild: wdaProcess.pid
|
|
1672
|
-
});
|
|
1673
|
-
|
|
1674
|
-
console.log(`✅ WDA starting for ${name} (wireless). Process ID: ${wdaProcess.pid}`);
|
|
1675
|
-
|
|
1676
|
-
// Wait for WDA to start, then verify
|
|
1677
|
-
setTimeout(() => {
|
|
1678
|
-
const verifyWDA = spawn('curl', [
|
|
1679
|
-
'-s',
|
|
1680
|
-
'--connect-timeout', '5',
|
|
1681
|
-
`http://${ip}:8100/status`
|
|
1682
|
-
]);
|
|
1683
|
-
|
|
1684
|
-
let verifyOutput = '';
|
|
1685
|
-
verifyWDA.stdout.on('data', (data) => {
|
|
1686
|
-
verifyOutput += data.toString();
|
|
1687
|
-
});
|
|
1688
|
-
|
|
1689
|
-
verifyWDA.on('close', async () => {
|
|
1690
|
-
if (verifyOutput.includes('"state"')) {
|
|
1691
|
-
console.log(`✅ WDA successfully started for ${name}`);
|
|
1692
|
-
|
|
1693
|
-
// Create WDA session for wireless device
|
|
1694
|
-
console.log(`📱 Creating WDA session for ${name}...`);
|
|
1695
|
-
const sessionResult = await createWDASession(ip, name);
|
|
1696
|
-
|
|
1697
|
-
if (sessionResult.success) {
|
|
1698
|
-
console.log(`✅ Session created: ${sessionResult.sessionId}`);
|
|
1699
|
-
} else {
|
|
1700
|
-
console.log(`⚠️ Session creation failed, will be created on first command`);
|
|
1701
|
-
}
|
|
1702
|
-
|
|
1703
|
-
// Update device status to online
|
|
1704
|
-
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1705
|
-
if (deviceIndex !== -1) {
|
|
1706
|
-
connectedDevices[deviceIndex].status = 'online';
|
|
1707
|
-
}
|
|
1708
|
-
|
|
1709
|
-
// Broadcast updated device list
|
|
1710
|
-
wss.clients.forEach(client => {
|
|
1711
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
1712
|
-
client.send(JSON.stringify({
|
|
1713
|
-
type: 'devices_updated',
|
|
1714
|
-
devices: connectedDevices
|
|
1715
|
-
}));
|
|
1716
|
-
}
|
|
1717
|
-
});
|
|
1718
|
-
|
|
1719
|
-
resolve({
|
|
1720
|
-
success: true,
|
|
1721
|
-
message: `Connected to ${name} via WiFi - WDA Started!`,
|
|
1722
|
-
wdaStarted: true
|
|
1723
|
-
});
|
|
1724
|
-
} else {
|
|
1725
|
-
console.log(`⚠️ WDA starting for ${name}, may take a moment...`);
|
|
1726
|
-
resolve({
|
|
1727
|
-
success: true,
|
|
1728
|
-
message: `WDA is starting for ${name}. Please wait 10-15 seconds...`,
|
|
1729
|
-
wdaStarting: true
|
|
1730
|
-
});
|
|
1731
|
-
}
|
|
1732
|
-
});
|
|
1733
|
-
}, 10000); // Wait 10 seconds for wireless WDA to start
|
|
1734
|
-
}
|
|
1735
|
-
});
|
|
1736
|
-
|
|
1737
|
-
checkWDA.on('error', () => {
|
|
1738
|
-
console.log(`⚠️ Cannot reach ${name} at ${ip}. Check network connection.`);
|
|
1739
|
-
reject({ success: false, message: `Cannot reach ${name} at ${ip}. Check network connection.` });
|
|
1740
|
-
});
|
|
1741
|
-
}
|
|
1742
|
-
});
|
|
1743
|
-
}
|
|
1744
|
-
|
|
1745
|
-
// Disconnect from device
|
|
1746
|
-
async function disconnectFromDevice(device) {
|
|
1747
|
-
return new Promise((resolve, reject) => {
|
|
1748
|
-
const { name, connectionType, udid, platform } = device;
|
|
1749
|
-
console.log(`🔌 Disconnecting from ${name} (${connectionType}, platform: ${platform})...`);
|
|
1750
|
-
|
|
1751
|
-
// Handle Android devices
|
|
1752
|
-
if (platform === 'android') {
|
|
1753
|
-
console.log(`📱 Android device disconnect: ${name}`);
|
|
1754
|
-
|
|
1755
|
-
// Stop UIAutomator2 session first
|
|
1756
|
-
stopUIAutomator2Session(udid, name).catch(err => {
|
|
1757
|
-
console.error(`Error stopping UIAutomator2 session: ${err.message}`);
|
|
1758
|
-
});
|
|
1759
|
-
|
|
1760
|
-
// For wireless Android devices, disconnect adb
|
|
1761
|
-
if (connectionType === 'wireless') {
|
|
1762
|
-
const adbDisconnect = spawn('adb', ['disconnect', udid]);
|
|
1763
|
-
|
|
1764
|
-
adbDisconnect.on('close', (code) => {
|
|
1765
|
-
console.log(`✅ Disconnected Android device ${name} from ADB`);
|
|
1766
|
-
|
|
1767
|
-
// Update device status
|
|
1768
|
-
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1769
|
-
if (deviceIndex !== -1) {
|
|
1770
|
-
connectedDevices[deviceIndex].status = 'offline';
|
|
1771
|
-
}
|
|
1772
|
-
|
|
1773
|
-
// Broadcast update
|
|
1774
|
-
wss.clients.forEach(client => {
|
|
1775
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
1776
|
-
client.send(JSON.stringify({
|
|
1777
|
-
type: 'devices_updated',
|
|
1778
|
-
devices: connectedDevices
|
|
1779
|
-
}));
|
|
1780
|
-
}
|
|
1781
|
-
});
|
|
1782
|
-
|
|
1783
|
-
resolve({
|
|
1784
|
-
success: true,
|
|
1785
|
-
message: `Disconnected from ${name} - ADB disconnected`
|
|
1786
|
-
});
|
|
1787
|
-
});
|
|
1788
|
-
} else {
|
|
1789
|
-
// For USB Android devices, just update status
|
|
1790
|
-
|
|
1791
|
-
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1792
|
-
if (deviceIndex !== -1) {
|
|
1793
|
-
connectedDevices[deviceIndex].status = 'offline';
|
|
1794
|
-
}
|
|
1795
|
-
|
|
1796
|
-
// Broadcast update
|
|
1797
|
-
wss.clients.forEach(client => {
|
|
1798
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
1799
|
-
client.send(JSON.stringify({
|
|
1800
|
-
type: 'devices_updated',
|
|
1801
|
-
devices: connectedDevices
|
|
1802
|
-
}));
|
|
1803
|
-
}
|
|
1804
|
-
});
|
|
1805
|
-
|
|
1806
|
-
resolve({
|
|
1807
|
-
success: true,
|
|
1808
|
-
message: `Disconnected from ${name}`
|
|
1809
|
-
});
|
|
1810
|
-
}
|
|
1811
|
-
|
|
1812
|
-
return; // Exit early for Android
|
|
1813
|
-
}
|
|
1814
|
-
|
|
1815
|
-
// iOS device handling - Find the device in connectedDevices to get its port
|
|
1816
|
-
const deviceInfo = connectedDevices.find(d => d.name === name);
|
|
1817
|
-
const port = deviceInfo?.port;
|
|
1818
|
-
|
|
1819
|
-
// Strategy 1: Kill WDA processes tracked in wdaProcesses Map
|
|
1820
|
-
if (wdaProcesses.has(name)) {
|
|
1821
|
-
const processes = wdaProcesses.get(name);
|
|
1822
|
-
|
|
1823
|
-
try {
|
|
1824
|
-
if (processes.xcodebuild) {
|
|
1825
|
-
try {
|
|
1826
|
-
process.kill(processes.xcodebuild, 'SIGTERM');
|
|
1827
|
-
console.log(`✅ Killed xcodebuild for ${name} (PID: ${processes.xcodebuild})`);
|
|
1828
|
-
} catch (e) {
|
|
1829
|
-
console.log(`⚠️ xcodebuild process ${processes.xcodebuild} already stopped`);
|
|
1830
|
-
}
|
|
1831
|
-
}
|
|
1832
|
-
|
|
1833
|
-
if (processes.iproxy) {
|
|
1834
|
-
try {
|
|
1835
|
-
process.kill(processes.iproxy, 'SIGTERM');
|
|
1836
|
-
console.log(`✅ Killed iproxy for ${name} (PID: ${processes.iproxy})`);
|
|
1837
|
-
} catch (e) {
|
|
1838
|
-
console.log(`⚠️ iproxy process ${processes.iproxy} already stopped`);
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
|
|
1842
|
-
wdaProcesses.delete(name);
|
|
1843
|
-
} catch (error) {
|
|
1844
|
-
console.error(`Error cleaning up tracked processes for ${name}:`, error);
|
|
1845
|
-
}
|
|
1846
|
-
}
|
|
1847
|
-
|
|
1848
|
-
// Strategy 2: Kill processes by port (works for script-started WDA too)
|
|
1849
|
-
if (port) {
|
|
1850
|
-
console.log(`🔍 Killing processes on port ${port} for ${name}...`);
|
|
1851
|
-
const killPort = spawn('sh', ['-c', `lsof -ti:${port} | xargs kill -9 2>/dev/null || true`]);
|
|
1852
|
-
|
|
1853
|
-
killPort.on('close', () => {
|
|
1854
|
-
console.log(`✅ Cleaned up port ${port} for ${name}`);
|
|
1855
|
-
});
|
|
1856
|
-
}
|
|
1857
|
-
|
|
1858
|
-
// Strategy 3: Kill xcodebuild processes for this specific UDID
|
|
1859
|
-
if (udid && connectionType === 'usb') {
|
|
1860
|
-
console.log(`🔍 Killing WDA for UDID ${udid}...`);
|
|
1861
|
-
const killWDA = spawn('sh', ['-c', `pkill -f "xcodebuild.*${udid}" || true`]);
|
|
1862
|
-
|
|
1863
|
-
killWDA.on('close', () => {
|
|
1864
|
-
console.log(`✅ Cleaned up WDA processes for ${name}`);
|
|
1865
|
-
});
|
|
1866
|
-
}
|
|
1867
|
-
|
|
1868
|
-
// Strategy 4: For wireless, kill iproxy processes associated with this device's port
|
|
1869
|
-
if (connectionType === 'usb' && port) {
|
|
1870
|
-
const killIproxy = spawn('sh', ['-c', `pkill -f "iproxy.*${port}" || true`]);
|
|
1871
|
-
killIproxy.on('close', () => {
|
|
1872
|
-
console.log(`✅ Cleaned up iproxy for ${name}`);
|
|
1873
|
-
});
|
|
1874
|
-
}
|
|
1875
|
-
|
|
1876
|
-
// Wait a moment for all cleanup to complete
|
|
1877
|
-
setTimeout(() => {
|
|
1878
|
-
// Update device status to offline in connectedDevices
|
|
1879
|
-
const deviceIndex = connectedDevices.findIndex(d => d.name === name);
|
|
1880
|
-
if (deviceIndex !== -1) {
|
|
1881
|
-
connectedDevices[deviceIndex].status = 'offline';
|
|
1882
|
-
}
|
|
1883
|
-
|
|
1884
|
-
// Broadcast updated device list to all WebSocket clients
|
|
1885
|
-
wss.clients.forEach(client => {
|
|
1886
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
1887
|
-
client.send(JSON.stringify({
|
|
1888
|
-
type: 'devices_updated',
|
|
1889
|
-
devices: connectedDevices
|
|
1890
|
-
}));
|
|
1891
|
-
}
|
|
1892
|
-
});
|
|
1893
|
-
|
|
1894
|
-
console.log(`✅ Successfully disconnected ${name}`);
|
|
1895
|
-
resolve({
|
|
1896
|
-
success: true,
|
|
1897
|
-
message: `Disconnected from ${name} - WDA stopped`
|
|
1898
|
-
});
|
|
1899
|
-
}, 500);
|
|
1900
|
-
});
|
|
1901
|
-
}
|
|
1902
|
-
|
|
1903
|
-
// ============================================
|
|
1904
|
-
// Recording & Replay Functions
|
|
1905
|
-
// ============================================
|
|
1906
|
-
|
|
1907
|
-
// Ensure recordings directory exists
|
|
1908
|
-
async function ensureRecordingsDir() {
|
|
1909
|
-
try {
|
|
1910
|
-
await fs.access(RECORDINGS_DIR);
|
|
1911
|
-
} catch {
|
|
1912
|
-
await fs.mkdir(RECORDINGS_DIR, { recursive: true });
|
|
1913
|
-
}
|
|
1914
|
-
}
|
|
1915
|
-
|
|
1916
|
-
// Start recording
|
|
1917
|
-
async function startRecording(name, devices) {
|
|
1918
|
-
await ensureRecordingsDir();
|
|
1919
|
-
|
|
1920
|
-
currentRecording = {
|
|
1921
|
-
name: name || `recording_${Date.now()}`,
|
|
1922
|
-
devices: devices || [],
|
|
1923
|
-
commands: [],
|
|
1924
|
-
startTime: new Date().toISOString()
|
|
1925
|
-
};
|
|
1926
|
-
isRecording = true;
|
|
1927
|
-
|
|
1928
|
-
console.log(`🔴 Recording started: ${currentRecording.name}`);
|
|
1929
|
-
return { success: true, recording: currentRecording };
|
|
1930
|
-
}
|
|
1931
|
-
|
|
1932
|
-
// Add command to current recording
|
|
1933
|
-
function recordCommand(devices, command, useAI, convertedCommand) {
|
|
1934
|
-
if (!isRecording || !currentRecording) {
|
|
1935
|
-
return false;
|
|
1936
|
-
}
|
|
1937
|
-
|
|
1938
|
-
currentRecording.commands.push({
|
|
1939
|
-
timestamp: new Date().toISOString(),
|
|
1940
|
-
devices,
|
|
1941
|
-
originalCommand: command,
|
|
1942
|
-
useAI,
|
|
1943
|
-
finalCommand: convertedCommand || command
|
|
1944
|
-
});
|
|
1945
|
-
|
|
1946
|
-
console.log(`📝 Recorded command: ${command} (${currentRecording.commands.length} total)`);
|
|
1947
|
-
return true;
|
|
1948
|
-
}
|
|
1949
|
-
|
|
1950
|
-
// Stop recording and save
|
|
1951
|
-
async function stopRecording() {
|
|
1952
|
-
if (!isRecording || !currentRecording) {
|
|
1953
|
-
return { success: false, error: 'No active recording' };
|
|
1954
|
-
}
|
|
1955
|
-
|
|
1956
|
-
currentRecording.endTime = new Date().toISOString();
|
|
1957
|
-
|
|
1958
|
-
const filename = `${currentRecording.name}.json`;
|
|
1959
|
-
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
1960
|
-
|
|
1961
|
-
await fs.writeFile(filepath, JSON.stringify(currentRecording, null, 2));
|
|
1962
|
-
|
|
1963
|
-
const result = {
|
|
1964
|
-
success: true,
|
|
1965
|
-
recording: currentRecording,
|
|
1966
|
-
filepath: filename
|
|
1967
|
-
};
|
|
1968
|
-
|
|
1969
|
-
console.log(`⏹️ Recording stopped: ${currentRecording.name} (${currentRecording.commands.length} commands)`);
|
|
1970
|
-
|
|
1971
|
-
isRecording = false;
|
|
1972
|
-
currentRecording = null;
|
|
1973
|
-
|
|
1974
|
-
return result;
|
|
1975
|
-
}
|
|
1976
|
-
|
|
1977
|
-
// List all recordings
|
|
1978
|
-
async function listRecordings() {
|
|
1979
|
-
await ensureRecordingsDir();
|
|
1980
|
-
|
|
1981
|
-
try {
|
|
1982
|
-
const files = await fs.readdir(RECORDINGS_DIR);
|
|
1983
|
-
const recordings = [];
|
|
1984
|
-
|
|
1985
|
-
for (const file of files) {
|
|
1986
|
-
if (file.endsWith('.json')) {
|
|
1987
|
-
try {
|
|
1988
|
-
const filepath = path.join(RECORDINGS_DIR, file);
|
|
1989
|
-
const content = await fs.readFile(filepath, 'utf-8');
|
|
1990
|
-
const recording = JSON.parse(content);
|
|
1991
|
-
|
|
1992
|
-
// Handle both old format (array of commands) and new format (string)
|
|
1993
|
-
let commandCount = 0;
|
|
1994
|
-
if (Array.isArray(recording.commands)) {
|
|
1995
|
-
commandCount = recording.commands.length;
|
|
1996
|
-
} else if (typeof recording.commands === 'string') {
|
|
1997
|
-
commandCount = recording.commands.split('\n').filter(cmd => cmd.trim()).length;
|
|
1998
|
-
}
|
|
1999
|
-
|
|
2000
|
-
recordings.push({
|
|
2001
|
-
filename: file,
|
|
2002
|
-
name: recording.name || file.replace('.json', ''),
|
|
2003
|
-
devices: recording.devices || [],
|
|
2004
|
-
commandCount: commandCount,
|
|
2005
|
-
startTime: recording.startTime || recording.date,
|
|
2006
|
-
endTime: recording.endTime || recording.date,
|
|
2007
|
-
type: recording.type || 'manual'
|
|
2008
|
-
});
|
|
2009
|
-
} catch (e) {
|
|
2010
|
-
console.error(`Error reading recording ${file}:`, e);
|
|
2011
|
-
}
|
|
2012
|
-
}
|
|
2013
|
-
}
|
|
2014
|
-
|
|
2015
|
-
return recordings;
|
|
2016
|
-
} catch (error) {
|
|
2017
|
-
console.error('Error listing recordings:', error);
|
|
2018
|
-
return [];
|
|
2019
|
-
}
|
|
2020
|
-
}
|
|
2021
|
-
|
|
2022
|
-
// Load a recording
|
|
2023
|
-
async function loadRecording(filename) {
|
|
2024
|
-
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
2025
|
-
|
|
2026
|
-
try {
|
|
2027
|
-
const content = await fs.readFile(filepath, 'utf-8');
|
|
2028
|
-
return JSON.parse(content);
|
|
2029
|
-
} catch (error) {
|
|
2030
|
-
console.error(`Error loading recording ${filename}:`, error);
|
|
2031
|
-
throw error;
|
|
2032
|
-
}
|
|
2033
|
-
}
|
|
2034
|
-
|
|
2035
|
-
// Delete a recording
|
|
2036
|
-
async function deleteRecording(filename) {
|
|
2037
|
-
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
2038
|
-
|
|
2039
|
-
try {
|
|
2040
|
-
await fs.unlink(filepath);
|
|
2041
|
-
return { success: true };
|
|
2042
|
-
} catch (error) {
|
|
2043
|
-
console.error(`Error deleting recording ${filename}:`, error);
|
|
2044
|
-
throw error;
|
|
2045
|
-
}
|
|
2046
|
-
}
|
|
2047
|
-
|
|
2048
|
-
// Replay a recording
|
|
2049
|
-
async function replayRecording(filename, targetDevices, wsClient) {
|
|
2050
|
-
const recording = await loadRecording(filename);
|
|
2051
|
-
|
|
2052
|
-
// Normalize commands to array format
|
|
2053
|
-
let commands = [];
|
|
2054
|
-
if (Array.isArray(recording.commands)) {
|
|
2055
|
-
// Old format: array of command objects
|
|
2056
|
-
commands = recording.commands.map(cmd => cmd.finalCommand || cmd.originalCommand);
|
|
2057
|
-
} else if (typeof recording.commands === 'string') {
|
|
2058
|
-
// New format: string with newlines
|
|
2059
|
-
commands = recording.commands.split('\n').filter(cmd => cmd.trim());
|
|
2060
|
-
}
|
|
2061
|
-
|
|
2062
|
-
const devices = recording.devices && recording.devices.length > 0
|
|
2063
|
-
? recording.devices
|
|
2064
|
-
: targetDevices;
|
|
2065
|
-
|
|
2066
|
-
// separator removed
|
|
2067
|
-
console.log(`REPLAYING: ${recording.name}`);
|
|
2068
|
-
console.log(`Original devices: ${devices.join(', ')}`);
|
|
2069
|
-
console.log(`Target devices: ${targetDevices.join(', ')}`);
|
|
2070
|
-
console.log(`Commands to replay: ${commands.length}`);
|
|
2071
|
-
// separator removed
|
|
2072
|
-
|
|
2073
|
-
// Reset abort flag at start
|
|
2074
|
-
replayAborted = false;
|
|
2075
|
-
isReplaying = true;
|
|
2076
|
-
|
|
2077
|
-
// Send initial summary to terminal
|
|
2078
|
-
if (wsClient) {
|
|
2079
|
-
wsClient.send(JSON.stringify({
|
|
2080
|
-
type: 'command_output',
|
|
2081
|
-
data: `📼 Recording: ${recording.name}\n` +
|
|
2082
|
-
`📱 Devices: ${targetDevices.join(', ')}\n` +
|
|
2083
|
-
`📝 Commands: ${commands.length}\n` +
|
|
2084
|
-
`${'━'.repeat(50)}\n\n`,
|
|
2085
|
-
devices: targetDevices
|
|
2086
|
-
}));
|
|
2087
|
-
}
|
|
2088
|
-
|
|
2089
|
-
const results = [];
|
|
2090
|
-
|
|
2091
|
-
for (let i = 0; i < commands.length; i++) {
|
|
2092
|
-
// Check if replay was aborted
|
|
2093
|
-
if (replayAborted) {
|
|
2094
|
-
console.log('\n⏹️ Replay aborted by user\n');
|
|
2095
|
-
if (wsClient) {
|
|
2096
|
-
wsClient.send(JSON.stringify({
|
|
2097
|
-
type: 'command_output',
|
|
2098
|
-
data: '\n⏹️ Replay stopped by user\n',
|
|
2099
|
-
devices: targetDevices
|
|
2100
|
-
}));
|
|
2101
|
-
}
|
|
2102
|
-
isReplaying = false;
|
|
2103
|
-
throw new Error('Replay aborted by user');
|
|
2104
|
-
}
|
|
2105
|
-
|
|
2106
|
-
const cmd = commands[i];
|
|
2107
|
-
|
|
2108
|
-
console.log(`\n🎬 Replaying command ${i + 1}/${commands.length}`);
|
|
2109
|
-
console.log(` Command: ${cmd}`);
|
|
2110
|
-
|
|
2111
|
-
if (wsClient) {
|
|
2112
|
-
wsClient.send(JSON.stringify({
|
|
2113
|
-
type: 'command_output',
|
|
2114
|
-
data: `🎬 [${i + 1}/${commands.length}] Executing: ${cmd}\n`,
|
|
2115
|
-
devices: targetDevices
|
|
2116
|
-
}));
|
|
2117
|
-
}
|
|
2118
|
-
|
|
2119
|
-
try {
|
|
2120
|
-
// Execute the command
|
|
2121
|
-
const result = await executeCommand(targetDevices, cmd, null); // null to suppress websocket output from executeCommand
|
|
2122
|
-
results.push({ command: cmd, success: true, result });
|
|
2123
|
-
|
|
2124
|
-
if (wsClient) {
|
|
2125
|
-
wsClient.send(JSON.stringify({
|
|
2126
|
-
type: 'command_output',
|
|
2127
|
-
data: `✅ Completed successfully\n\n`,
|
|
2128
|
-
devices: targetDevices
|
|
2129
|
-
}));
|
|
2130
|
-
}
|
|
2131
|
-
|
|
2132
|
-
// Add a small delay between commands
|
|
2133
|
-
if (i < commands.length - 1) {
|
|
2134
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
2135
|
-
}
|
|
2136
|
-
} catch (error) {
|
|
2137
|
-
console.error(`❌ Replay command ${i + 1} failed:`, error.message);
|
|
2138
|
-
results.push({ command: cmd, success: false, error: error.message });
|
|
2139
|
-
|
|
2140
|
-
if (wsClient) {
|
|
2141
|
-
wsClient.send(JSON.stringify({
|
|
2142
|
-
type: 'command_output',
|
|
2143
|
-
data: `❌ Failed: ${error.message}\n\n`,
|
|
2144
|
-
devices: targetDevices
|
|
2145
|
-
}));
|
|
2146
|
-
}
|
|
2147
|
-
}
|
|
2148
|
-
}
|
|
2149
|
-
|
|
2150
|
-
isReplaying = false;
|
|
2151
|
-
|
|
2152
|
-
// separator removed
|
|
2153
|
-
console.log(`REPLAY COMPLETE`);
|
|
2154
|
-
console.log(`Total: ${results.length}, Success: ${results.filter(r => r.success).length}, Failed: ${results.filter(r => !r.success).length}`);
|
|
2155
|
-
// separator removed
|
|
2156
|
-
|
|
2157
|
-
return {
|
|
2158
|
-
success: true,
|
|
2159
|
-
recording: recording.name,
|
|
2160
|
-
results
|
|
2161
|
-
};
|
|
2162
|
-
}
|
|
2163
|
-
|
|
2164
|
-
// API Routes
|
|
2165
|
-
app.get('/api/devices', async (req, res) => {
|
|
2166
|
-
try {
|
|
2167
|
-
const devices = await discoverDevices();
|
|
2168
|
-
res.json({ success: true, devices });
|
|
2169
|
-
} catch (error) {
|
|
2170
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2171
|
-
}
|
|
2172
|
-
});
|
|
2173
|
-
|
|
2174
|
-
app.post('/api/devices/refresh', async (req, res) => {
|
|
2175
|
-
try {
|
|
2176
|
-
const devices = await discoverDevices();
|
|
2177
|
-
|
|
2178
|
-
// Broadcast to all WebSocket clients
|
|
2179
|
-
wss.clients.forEach(client => {
|
|
2180
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
2181
|
-
client.send(JSON.stringify({
|
|
2182
|
-
type: 'devices_updated',
|
|
2183
|
-
devices
|
|
2184
|
-
}));
|
|
2185
|
-
}
|
|
2186
|
-
});
|
|
2187
|
-
|
|
2188
|
-
res.json({ success: true, devices });
|
|
2189
|
-
} catch (error) {
|
|
2190
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2191
|
-
}
|
|
2192
|
-
});
|
|
2193
|
-
|
|
2194
|
-
app.post('/api/execute', async (req, res) => {
|
|
2195
|
-
try {
|
|
2196
|
-
const { devices, command, useAI, aiProvider } = req.body;
|
|
2197
|
-
|
|
2198
|
-
if (!devices || devices.length === 0) {
|
|
2199
|
-
return res.status(400).json({ success: false, error: 'No devices specified' });
|
|
2200
|
-
}
|
|
2201
|
-
|
|
2202
|
-
let finalCommand = command;
|
|
2203
|
-
if (useAI) {
|
|
2204
|
-
finalCommand = await convertNaturalLanguageToCommand(command, devices, aiProvider);
|
|
2205
|
-
}
|
|
2206
|
-
|
|
2207
|
-
// Check if command has multiple lines (sequential execution)
|
|
2208
|
-
const hasMultipleCommands = finalCommand.includes('\n');
|
|
2209
|
-
|
|
2210
|
-
let result;
|
|
2211
|
-
if (hasMultipleCommands) {
|
|
2212
|
-
|
|
2213
|
-
result = await executeCommandsSequentially(devices, finalCommand, null);
|
|
2214
|
-
} else {
|
|
2215
|
-
result = await executeCommand(devices, finalCommand, null);
|
|
2216
|
-
}
|
|
2217
|
-
|
|
2218
|
-
res.json(result);
|
|
2219
|
-
} catch (error) {
|
|
2220
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2221
|
-
}
|
|
2222
|
-
});
|
|
2223
|
-
|
|
2224
|
-
app.post('/api/convert-command', async (req, res) => {
|
|
2225
|
-
try {
|
|
2226
|
-
const { text, devices, provider } = req.body;
|
|
2227
|
-
const command = await convertNaturalLanguageToCommand(text, devices || [], provider);
|
|
2228
|
-
res.json({ success: true, command });
|
|
2229
|
-
} catch (error) {
|
|
2230
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2231
|
-
}
|
|
2232
|
-
});
|
|
2233
|
-
|
|
2234
|
-
// Connect to device endpoint
|
|
2235
|
-
app.post('/api/devices/connect', async (req, res) => {
|
|
2236
|
-
try {
|
|
2237
|
-
const { device } = req.body;
|
|
2238
|
-
console.log(`📡 Connect request received for device:`, device);
|
|
2239
|
-
|
|
2240
|
-
if (!device) {
|
|
2241
|
-
console.error('❌ No device provided in request');
|
|
2242
|
-
return res.status(400).json({ success: false, error: 'No device provided' });
|
|
2243
|
-
}
|
|
2244
|
-
|
|
2245
|
-
if (!device.name || !device.udid) {
|
|
2246
|
-
console.error('❌ Invalid device object:', device);
|
|
2247
|
-
return res.status(400).json({ success: false, error: 'Invalid device object' });
|
|
2248
|
-
}
|
|
2249
|
-
|
|
2250
|
-
const result = await connectToDevice(device);
|
|
2251
|
-
console.log(`✅ Connect result:`, result);
|
|
2252
|
-
res.json(result);
|
|
2253
|
-
} catch (error) {
|
|
2254
|
-
console.error(`❌ Connect error:`, error);
|
|
2255
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2256
|
-
}
|
|
2257
|
-
});
|
|
2258
|
-
|
|
2259
|
-
// Disconnect from device endpoint
|
|
2260
|
-
app.post('/api/devices/disconnect', async (req, res) => {
|
|
2261
|
-
try {
|
|
2262
|
-
const { device } = req.body;
|
|
2263
|
-
const result = await disconnectFromDevice(device);
|
|
2264
|
-
res.json(result);
|
|
2265
|
-
} catch (error) {
|
|
2266
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2267
|
-
}
|
|
2268
|
-
});
|
|
2269
|
-
|
|
2270
|
-
// Disconnect all devices endpoint
|
|
2271
|
-
app.post('/api/devices/disconnect-all', async (req, res) => {
|
|
2272
|
-
try {
|
|
2273
|
-
console.log(`🔌 Disconnecting ALL devices...`);
|
|
2274
|
-
|
|
2275
|
-
// Get all connected devices
|
|
2276
|
-
const devicesToDisconnect = connectedDevices.filter(d => d.status === 'online');
|
|
2277
|
-
|
|
2278
|
-
if (devicesToDisconnect.length === 0) {
|
|
2279
|
-
return res.json({
|
|
2280
|
-
success: true,
|
|
2281
|
-
message: 'No devices to disconnect'
|
|
2282
|
-
});
|
|
2283
|
-
}
|
|
2284
|
-
|
|
2285
|
-
console.log(`📱 Disconnecting ${devicesToDisconnect.length} device(s)...`);
|
|
2286
|
-
|
|
2287
|
-
// Disconnect all devices in parallel
|
|
2288
|
-
const disconnectPromises = devicesToDisconnect.map(device => disconnectFromDevice(device));
|
|
2289
|
-
await Promise.all(disconnectPromises);
|
|
2290
|
-
|
|
2291
|
-
console.log(`✅ All devices disconnected`);
|
|
2292
|
-
|
|
2293
|
-
res.json({
|
|
2294
|
-
success: true,
|
|
2295
|
-
message: `Disconnected ${devicesToDisconnect.length} device(s)`,
|
|
2296
|
-
count: devicesToDisconnect.length
|
|
2297
|
-
});
|
|
2298
|
-
} catch (error) {
|
|
2299
|
-
console.error(`❌ Error disconnecting all devices:`, error);
|
|
2300
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2301
|
-
}
|
|
2302
|
-
});
|
|
2303
|
-
|
|
2304
|
-
// New endpoints for AI provider management
|
|
2305
|
-
app.get('/api/ai/providers', (req, res) => {
|
|
2306
|
-
try {
|
|
2307
|
-
const providers = aiManager.getAvailableProviders();
|
|
2308
|
-
const current = aiManager.getCurrentProvider();
|
|
2309
|
-
res.json({ success: true, providers, current: current.id });
|
|
2310
|
-
} catch (error) {
|
|
2311
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2312
|
-
}
|
|
2313
|
-
});
|
|
2314
|
-
|
|
2315
|
-
app.post('/api/ai/provider', (req, res) => {
|
|
2316
|
-
try {
|
|
2317
|
-
const { provider } = req.body;
|
|
2318
|
-
const success = aiManager.setProvider(provider);
|
|
2319
|
-
if (success) {
|
|
2320
|
-
res.json({ success: true, provider });
|
|
2321
|
-
} else {
|
|
2322
|
-
res.status(400).json({ success: false, error: 'Invalid or unavailable provider' });
|
|
2323
|
-
}
|
|
2324
|
-
} catch (error) {
|
|
2325
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2326
|
-
}
|
|
2327
|
-
});
|
|
2328
|
-
|
|
2329
|
-
// Settings API - Get API configuration
|
|
2330
|
-
app.get('/api/settings/api-config', async (req, res) => {
|
|
2331
|
-
try {
|
|
2332
|
-
const configPath = path.join(__dirname, '../../.env');
|
|
2333
|
-
let config = {
|
|
2334
|
-
provider: process.env.AI_PROVIDER || 'gemini',
|
|
2335
|
-
model: process.env.AI_MODEL || '',
|
|
2336
|
-
openai_api_key: process.env.OPENAI_API_KEY || '',
|
|
2337
|
-
gemini_api_key: process.env.GEMINI_API_KEY || '',
|
|
2338
|
-
claude_api_key: process.env.CLAUDE_API_KEY || '',
|
|
2339
|
-
github_token: process.env.GITHUB_TOKEN || '',
|
|
2340
|
-
groq_api_key: process.env.GROQ_API_KEY || '',
|
|
2341
|
-
cohere_api_key: process.env.COHERE_API_KEY || '',
|
|
2342
|
-
mistral_api_key: process.env.MISTRAL_API_KEY || '',
|
|
2343
|
-
};
|
|
2344
|
-
|
|
2345
|
-
// Try to read from .env file if exists
|
|
2346
|
-
try {
|
|
2347
|
-
const envContent = await fs.readFile(configPath, 'utf-8');
|
|
2348
|
-
const lines = envContent.split('\n');
|
|
2349
|
-
lines.forEach(line => {
|
|
2350
|
-
const [key, value] = line.split('=');
|
|
2351
|
-
if (key && value) {
|
|
2352
|
-
const trimmedKey = key.trim();
|
|
2353
|
-
const trimmedValue = value.trim();
|
|
2354
|
-
if (trimmedKey === 'AI_PROVIDER') config.provider = trimmedValue;
|
|
2355
|
-
if (trimmedKey === 'AI_MODEL') config.model = trimmedValue;
|
|
2356
|
-
if (trimmedKey === 'OPENAI_API_KEY') config.openai_api_key = trimmedValue;
|
|
2357
|
-
if (trimmedKey === 'GEMINI_API_KEY') config.gemini_api_key = trimmedValue;
|
|
2358
|
-
if (trimmedKey === 'CLAUDE_API_KEY') config.claude_api_key = trimmedValue;
|
|
2359
|
-
if (trimmedKey === 'GITHUB_TOKEN') config.github_token = trimmedValue;
|
|
2360
|
-
if (trimmedKey === 'GROQ_API_KEY') config.groq_api_key = trimmedValue;
|
|
2361
|
-
if (trimmedKey === 'COHERE_API_KEY') config.cohere_api_key = trimmedValue;
|
|
2362
|
-
if (trimmedKey === 'MISTRAL_API_KEY') config.mistral_api_key = trimmedValue;
|
|
2363
|
-
}
|
|
2364
|
-
});
|
|
2365
|
-
} catch (err) {
|
|
2366
|
-
// .env doesn't exist, return defaults
|
|
2367
|
-
}
|
|
2368
|
-
|
|
2369
|
-
// Mask API keys for security - only show last 4 characters
|
|
2370
|
-
const maskKey = (key) => {
|
|
2371
|
-
if (!key || key.length < 8) return '';
|
|
2372
|
-
return '•'.repeat(key.length - 4) + key.slice(-4);
|
|
2373
|
-
};
|
|
2374
|
-
|
|
2375
|
-
res.json({
|
|
2376
|
-
provider: config.provider,
|
|
2377
|
-
model: config.model,
|
|
2378
|
-
openai_api_key: maskKey(config.openai_api_key),
|
|
2379
|
-
gemini_api_key: maskKey(config.gemini_api_key),
|
|
2380
|
-
claude_api_key: maskKey(config.claude_api_key),
|
|
2381
|
-
github_token: maskKey(config.github_token),
|
|
2382
|
-
groq_api_key: maskKey(config.groq_api_key),
|
|
2383
|
-
cohere_api_key: maskKey(config.cohere_api_key),
|
|
2384
|
-
mistral_api_key: maskKey(config.mistral_api_key),
|
|
2385
|
-
has_openai_key: !!config.openai_api_key,
|
|
2386
|
-
has_gemini_key: !!config.gemini_api_key,
|
|
2387
|
-
has_claude_key: !!config.claude_api_key,
|
|
2388
|
-
has_github_token: !!config.github_token,
|
|
2389
|
-
has_groq_key: !!config.groq_api_key,
|
|
2390
|
-
has_cohere_key: !!config.cohere_api_key,
|
|
2391
|
-
has_mistral_key: !!config.mistral_api_key,
|
|
2392
|
-
});
|
|
2393
|
-
} catch (error) {
|
|
2394
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2395
|
-
}
|
|
2396
|
-
});
|
|
2397
|
-
|
|
2398
|
-
// Settings API - Save API configuration
|
|
2399
|
-
app.post('/api/settings/api-config', async (req, res) => {
|
|
2400
|
-
try {
|
|
2401
|
-
const {
|
|
2402
|
-
provider,
|
|
2403
|
-
model,
|
|
2404
|
-
openai_api_key,
|
|
2405
|
-
gemini_api_key,
|
|
2406
|
-
claude_api_key,
|
|
2407
|
-
github_token,
|
|
2408
|
-
groq_api_key,
|
|
2409
|
-
cohere_api_key,
|
|
2410
|
-
mistral_api_key
|
|
2411
|
-
} = req.body;
|
|
2412
|
-
|
|
2413
|
-
const configPath = path.join(__dirname, '../../.env');
|
|
2414
|
-
|
|
2415
|
-
let envContent = `# AI Provider Configuration\nAI_PROVIDER=${provider}\n`;
|
|
2416
|
-
if (model) {
|
|
2417
|
-
envContent += `AI_MODEL=${model}\n`;
|
|
2418
|
-
}
|
|
2419
|
-
if (openai_api_key) {
|
|
2420
|
-
envContent += `OPENAI_API_KEY=${openai_api_key}\n`;
|
|
2421
|
-
}
|
|
2422
|
-
if (gemini_api_key) {
|
|
2423
|
-
envContent += `GEMINI_API_KEY=${gemini_api_key}\n`;
|
|
2424
|
-
}
|
|
2425
|
-
if (claude_api_key) {
|
|
2426
|
-
envContent += `CLAUDE_API_KEY=${claude_api_key}\n`;
|
|
2427
|
-
}
|
|
2428
|
-
if (github_token) {
|
|
2429
|
-
envContent += `GITHUB_TOKEN=${github_token}\n`;
|
|
2430
|
-
}
|
|
2431
|
-
if (groq_api_key) {
|
|
2432
|
-
envContent += `GROQ_API_KEY=${groq_api_key}\n`;
|
|
2433
|
-
}
|
|
2434
|
-
if (cohere_api_key) {
|
|
2435
|
-
envContent += `COHERE_API_KEY=${cohere_api_key}\n`;
|
|
2436
|
-
}
|
|
2437
|
-
if (mistral_api_key) {
|
|
2438
|
-
envContent += `MISTRAL_API_KEY=${mistral_api_key}\n`;
|
|
2439
|
-
}
|
|
2440
|
-
|
|
2441
|
-
// Add WDA path if exists
|
|
2442
|
-
if (process.env.WDA_PATH) {
|
|
2443
|
-
envContent += `WDA_PATH=${process.env.WDA_PATH}\n`;
|
|
2444
|
-
}
|
|
2445
|
-
|
|
2446
|
-
await fs.writeFile(configPath, envContent);
|
|
2447
|
-
|
|
2448
|
-
// Update environment variables
|
|
2449
|
-
process.env.AI_PROVIDER = provider;
|
|
2450
|
-
if (model) process.env.AI_MODEL = model;
|
|
2451
|
-
if (openai_api_key) process.env.OPENAI_API_KEY = openai_api_key;
|
|
2452
|
-
if (gemini_api_key) process.env.GEMINI_API_KEY = gemini_api_key;
|
|
2453
|
-
if (claude_api_key) process.env.CLAUDE_API_KEY = claude_api_key;
|
|
2454
|
-
if (github_token) process.env.GITHUB_TOKEN = github_token;
|
|
2455
|
-
if (groq_api_key) process.env.GROQ_API_KEY = groq_api_key;
|
|
2456
|
-
if (cohere_api_key) process.env.COHERE_API_KEY = cohere_api_key;
|
|
2457
|
-
if (mistral_api_key) process.env.MISTRAL_API_KEY = mistral_api_key;
|
|
2458
|
-
|
|
2459
|
-
// Reinitialize AI manager with new config
|
|
2460
|
-
aiManager.provider = provider;
|
|
2461
|
-
if (model) aiManager.model = model;
|
|
2462
|
-
aiManager.initializeProviders();
|
|
2463
|
-
|
|
2464
|
-
res.json({ success: true, message: 'API configuration saved' });
|
|
2465
|
-
} catch (error) {
|
|
2466
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2467
|
-
}
|
|
2468
|
-
});
|
|
2469
|
-
|
|
2470
|
-
// Settings API - Get available AI providers and their models
|
|
2471
|
-
app.get('/api/settings/ai-providers', (req, res) => {
|
|
2472
|
-
try {
|
|
2473
|
-
const { AI_PROVIDERS_CONFIG } = require('./aiProvidersConfig');
|
|
2474
|
-
res.json({ success: true, providers: AI_PROVIDERS_CONFIG });
|
|
2475
|
-
} catch (error) {
|
|
2476
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2477
|
-
}
|
|
2478
|
-
});
|
|
2479
|
-
|
|
2480
|
-
// Settings API - Get devices configuration
|
|
2481
|
-
app.get('/api/settings/devices', async (req, res) => {
|
|
2482
|
-
try {
|
|
2483
|
-
const devices = await loadDeviceConfig();
|
|
2484
|
-
res.json({ success: true, devices });
|
|
2485
|
-
} catch (error) {
|
|
2486
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2487
|
-
}
|
|
2488
|
-
});
|
|
2489
|
-
|
|
2490
|
-
// Settings API - Save devices configuration
|
|
2491
|
-
app.post('/api/settings/devices', async (req, res) => {
|
|
2492
|
-
try {
|
|
2493
|
-
const { devices } = req.body;
|
|
2494
|
-
|
|
2495
|
-
// Format: device_name,udid,ip_address,platform,type
|
|
2496
|
-
let content = '# Device Configuration (Auto-updated)\n';
|
|
2497
|
-
content += '# Format: device_name,udid,ip_address,platform,type\n';
|
|
2498
|
-
content += '# Platform: ios | android\n';
|
|
2499
|
-
content += '# Type: usb | wireless\n';
|
|
2500
|
-
content += '# \n';
|
|
2501
|
-
content += '# 🔌 USB DEVICES: Automatically detected and saved here\n';
|
|
2502
|
-
content += '# - No configuration needed for USB connection\n';
|
|
2503
|
-
content += '# - Add IP address to enable wireless support later\n';
|
|
2504
|
-
content += '#\n';
|
|
2505
|
-
content += '# 📡 WIRELESS DEVICES: Manually add with IP address\n';
|
|
2506
|
-
content += '# - Format: device_name,udid,ip_address,platform,wireless\n';
|
|
2507
|
-
content += '# - iOS: Device must be paired in Xcode, WebDriverAgent running\n';
|
|
2508
|
-
content += '# - Android: Enable wireless ADB first\n';
|
|
2509
|
-
content += '#\n';
|
|
2510
|
-
content += '# Example entries:\n';
|
|
2511
|
-
content += '# iPhone17,00008130-001945C63ED3401E,,ios,usb (iOS USB - auto-detected)\n';
|
|
2512
|
-
content += '# iPhone16P,00008140-001C24361E41801C,10.173.221.204,ios,wireless (iOS Wireless)\n';
|
|
2513
|
-
content += '# Pixel8,1A2B3C4D5E6F,,android,usb (Android USB - auto-detected)\n';
|
|
2514
|
-
content += '# GalaxyS23,ABCD1234,192.168.1.150,android,wireless (Android Wireless)\n\n';
|
|
2515
|
-
|
|
2516
|
-
devices.forEach(device => {
|
|
2517
|
-
const ip = device.ip || '';
|
|
2518
|
-
const platform = device.platform || 'ios';
|
|
2519
|
-
const type = device.type || device.connectionType || (ip ? 'wireless' : 'usb');
|
|
2520
|
-
content += `${device.name},${device.udid},${ip},${platform},${type}\n`;
|
|
2521
|
-
});
|
|
2522
|
-
|
|
2523
|
-
await fs.writeFile(DEVICE_CONFIG, content);
|
|
2524
|
-
|
|
2525
|
-
res.json({ success: true, message: 'Devices configuration saved' });
|
|
2526
|
-
} catch (error) {
|
|
2527
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2528
|
-
}
|
|
2529
|
-
});
|
|
2530
|
-
|
|
2531
|
-
// Get app presets
|
|
2532
|
-
app.get('/api/apps/presets', async (req, res) => {
|
|
2533
|
-
try {
|
|
2534
|
-
const content = await fs.readFile(APPS_CONFIG, 'utf-8');
|
|
2535
|
-
const apps = content
|
|
2536
|
-
.split('\n')
|
|
2537
|
-
.filter(line => line.trim() && !line.startsWith('#'))
|
|
2538
|
-
.map(line => {
|
|
2539
|
-
const [name, packageId] = line.split(',');
|
|
2540
|
-
return { name: name.trim(), packageId: packageId.trim() };
|
|
2541
|
-
});
|
|
2542
|
-
|
|
2543
|
-
res.json({ success: true, apps });
|
|
2544
|
-
} catch (error) {
|
|
2545
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2546
|
-
}
|
|
2547
|
-
});
|
|
2548
|
-
|
|
2549
|
-
// Get locators from device's current screen
|
|
2550
|
-
app.post('/api/locators', async (req, res) => {
|
|
2551
|
-
try {
|
|
2552
|
-
const { deviceName } = req.body;
|
|
2553
|
-
|
|
2554
|
-
if (!deviceName) {
|
|
2555
|
-
return res.status(400).json({ success: false, error: 'Device name required' });
|
|
2556
|
-
}
|
|
2557
|
-
|
|
2558
|
-
logger.debug(`Getting locators for device: ${deviceName}`);
|
|
2559
|
-
|
|
2560
|
-
// Find the device info
|
|
2561
|
-
const device = connectedDevices.find(d => d.name === deviceName);
|
|
2562
|
-
if (!device) {
|
|
2563
|
-
return res.status(404).json({ success: false, error: 'Device not found' });
|
|
2564
|
-
}
|
|
2565
|
-
|
|
2566
|
-
// For Android devices, ensure UIAutomator2 session exists
|
|
2567
|
-
if (device.platform === 'android') {
|
|
2568
|
-
const session = androidSessions.get(device.udid);
|
|
2569
|
-
if (!session) {
|
|
2570
|
-
// Auto-connect the device
|
|
2571
|
-
console.log(`📡 Auto-connecting ${deviceName} for getLocators...`);
|
|
2572
|
-
try {
|
|
2573
|
-
const connectResult = await connectToDevice(device);
|
|
2574
|
-
if (!connectResult.success) {
|
|
2575
|
-
return res.status(500).json({
|
|
2576
|
-
success: false,
|
|
2577
|
-
error: 'Failed to connect device. Please use the Connect button first.'
|
|
2578
|
-
});
|
|
2579
|
-
}
|
|
2580
|
-
|
|
2581
|
-
// Wait a moment for session to stabilize
|
|
2582
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
2583
|
-
} catch (err) {
|
|
2584
|
-
return res.status(500).json({
|
|
2585
|
-
success: false,
|
|
2586
|
-
error: `Auto-connection failed: ${err.message}`
|
|
2587
|
-
});
|
|
2588
|
-
}
|
|
2589
|
-
}
|
|
2590
|
-
}
|
|
2591
|
-
|
|
2592
|
-
// Execute getLocators command - this uses the fast shell script implementation
|
|
2593
|
-
const result = await executeCommand([deviceName], 'getLocators', null);
|
|
2594
|
-
|
|
2595
|
-
logger.debug(`Result success: ${result.success}`);
|
|
2596
|
-
logger.debug(`Results array length: ${result.results?.length || 0}`);
|
|
2597
|
-
|
|
2598
|
-
if (result.success && result.results) {
|
|
2599
|
-
let output = '';
|
|
2600
|
-
|
|
2601
|
-
// executeCommand returns: { success, results: [scriptResults] }
|
|
2602
|
-
// scriptResults is from executeAndroidDevices/executeWithScript
|
|
2603
|
-
// Structure: { status: 'fulfilled', value: { success, results: [allSettledResults] } }
|
|
2604
|
-
// allSettledResults contains: { status: 'fulfilled', value: { success, output, device } }
|
|
2605
|
-
|
|
2606
|
-
for (const scriptResult of result.results) {
|
|
2607
|
-
logger.debug(`Script result:`, scriptResult);
|
|
2608
|
-
|
|
2609
|
-
// Check if scriptResult has value.results (fulfilled promise)
|
|
2610
|
-
if (scriptResult.status === 'fulfilled' && scriptResult.value && scriptResult.value.results) {
|
|
2611
|
-
// This is the result from executeAndroidDevices/executeWithScript
|
|
2612
|
-
for (const r of scriptResult.value.results) {
|
|
2613
|
-
logger.debug(`Result status: ${r.status}`);
|
|
2614
|
-
if (r.status === 'fulfilled' && r.value) {
|
|
2615
|
-
// Check if it's a successful execution
|
|
2616
|
-
if (r.value.success && r.value.output) {
|
|
2617
|
-
output = r.value.output;
|
|
2618
|
-
logger.debug(`Found output: ${output.length} characters`);
|
|
2619
|
-
break;
|
|
2620
|
-
} else if (r.value.error) {
|
|
2621
|
-
// Script executed but returned an error
|
|
2622
|
-
console.log(`❌ Script error:`, r.value.error);
|
|
2623
|
-
return res.status(500).json({
|
|
2624
|
-
success: false,
|
|
2625
|
-
error: 'Failed to get UI elements. Please ensure UIAutomator2 is installed for Android devices.'
|
|
2626
|
-
});
|
|
2627
|
-
}
|
|
2628
|
-
}
|
|
2629
|
-
}
|
|
2630
|
-
}
|
|
2631
|
-
if (output) break;
|
|
2632
|
-
}
|
|
2633
|
-
|
|
2634
|
-
if (!output) {
|
|
2635
|
-
console.log('❌ No output found in results');
|
|
2636
|
-
console.log('Full result structure:', JSON.stringify(result, null, 2));
|
|
2637
|
-
return res.status(500).json({ success: false, error: 'No output received from device' });
|
|
2638
|
-
}
|
|
2639
|
-
|
|
2640
|
-
// Parse the output into locator objects
|
|
2641
|
-
const locators = parseLocatorsOutput(output);
|
|
2642
|
-
console.log(`✅ Parsed ${locators.length} locators`);
|
|
2643
|
-
|
|
2644
|
-
// Filter out empty/invalid locators
|
|
2645
|
-
const validLocators = locators.filter(loc => loc.name || loc.label || loc.text);
|
|
2646
|
-
console.log(`✅ Filtered to ${validLocators.length} valid locators`);
|
|
2647
|
-
|
|
2648
|
-
res.json({ success: true, locators: validLocators });
|
|
2649
|
-
} else {
|
|
2650
|
-
console.log('❌ Command execution failed');
|
|
2651
|
-
res.status(500).json({ success: false, error: 'Failed to get locators' });
|
|
2652
|
-
}
|
|
2653
|
-
} catch (error) {
|
|
2654
|
-
console.error(`❌ API error:`, error);
|
|
2655
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2656
|
-
}
|
|
2657
|
-
});
|
|
2658
|
-
|
|
2659
|
-
// Click on a locator
|
|
2660
|
-
app.post('/api/locators/click', async (req, res) => {
|
|
2661
|
-
try {
|
|
2662
|
-
const { deviceName, locatorName, x, y } = req.body;
|
|
2663
|
-
|
|
2664
|
-
if (!deviceName) {
|
|
2665
|
-
return res.status(400).json({ success: false, error: 'Device name required' });
|
|
2666
|
-
}
|
|
2667
|
-
|
|
2668
|
-
let command;
|
|
2669
|
-
// If coordinates are provided, use them directly
|
|
2670
|
-
if (x !== undefined && y !== undefined) {
|
|
2671
|
-
command = `tap ${x},${y}`;
|
|
2672
|
-
console.log(`\n🖱️ API: Tapping at coordinates (${x},${y}) on device: ${deviceName}`);
|
|
2673
|
-
} else if (locatorName) {
|
|
2674
|
-
command = `click "${locatorName}"`;
|
|
2675
|
-
console.log(`\n🖱️ API: Clicking locator "${locatorName}" on device: ${deviceName}`);
|
|
2676
|
-
} else {
|
|
2677
|
-
return res.status(400).json({ success: false, error: 'Locator name or coordinates required' });
|
|
2678
|
-
}
|
|
2679
|
-
|
|
2680
|
-
// Execute click command
|
|
2681
|
-
const result = await executeCommand([deviceName], command, null);
|
|
2682
|
-
|
|
2683
|
-
if (result.success) {
|
|
2684
|
-
res.json({ success: true, message: 'Tap executed successfully' });
|
|
2685
|
-
} else {
|
|
2686
|
-
res.status(500).json({ success: false, error: 'Failed to execute tap' });
|
|
2687
|
-
}
|
|
2688
|
-
} catch (error) {
|
|
2689
|
-
console.error('❌ Tap error:', error);
|
|
2690
|
-
res.status(500).json({ success: false, error: error.message });
|
|
2691
|
-
}
|
|
2692
|
-
});
|
|
2693
|
-
|
|
2694
|
-
// Helper function to parse locators output
|
|
2695
|
-
function parseLocatorsOutput(output) {
|
|
2696
|
-
logger.debug('🔍 Parsing locators output...');
|
|
2697
|
-
logger.debug('Output length:', output?.length || 0);
|
|
2698
|
-
|
|
2699
|
-
if (!output) {
|
|
2700
|
-
logger.error('❌ No output to parse');
|
|
2701
|
-
return [];
|
|
2702
|
-
}
|
|
2703
|
-
|
|
2704
|
-
// First try to parse as JSON (new format)
|
|
2705
|
-
const lines = output.split('\n');
|
|
2706
|
-
for (const line of lines) {
|
|
2707
|
-
const trimmed = line.trim();
|
|
2708
|
-
if (trimmed.startsWith('[') || trimmed.startsWith('{')) {
|
|
2709
|
-
try {
|
|
2710
|
-
const jsonData = JSON.parse(trimmed);
|
|
2711
|
-
logger.debug('✅ Parsed as JSON, elements:', Array.isArray(jsonData) ? jsonData.length : 'not array');
|
|
2712
|
-
return Array.isArray(jsonData) ? jsonData : [];
|
|
2713
|
-
} catch (err) {
|
|
2714
|
-
logger.debug('⚠️ JSON parse failed:', err.message);
|
|
2715
|
-
}
|
|
2716
|
-
}
|
|
2717
|
-
}
|
|
2718
|
-
|
|
2719
|
-
logger.debug('📝 Fallback to text parsing...');
|
|
2720
|
-
|
|
2721
|
-
// Fallback to old text parsing
|
|
2722
|
-
const locators = [];
|
|
2723
|
-
logger.debug('Total lines:', lines.length);
|
|
2724
|
-
|
|
2725
|
-
for (const line of lines) {
|
|
2726
|
-
// New format: " 1. 📍 ButtonName │ [Button] │ Label:LabelText │ Val:ValueText │ @ (x,y) WxH │ ✓Vis ✓En"
|
|
2727
|
-
// Look for lines with numbered locators starting with 📍
|
|
2728
|
-
if (line.includes('📍') && /^\s*\d+\./.test(line)) {
|
|
2729
|
-
try {
|
|
2730
|
-
const locator = {};
|
|
2731
|
-
|
|
2732
|
-
// Extract index number
|
|
2733
|
-
const indexMatch = line.match(/^\s*(\d+)\./);
|
|
2734
|
-
if (indexMatch) locator.index = parseInt(indexMatch[1]);
|
|
2735
|
-
|
|
2736
|
-
// Split by pipe separator if present (new format), otherwise use old logic
|
|
2737
|
-
if (line.includes('│')) {
|
|
2738
|
-
const parts = line.split('│').map(p => p.trim());
|
|
2739
|
-
|
|
2740
|
-
// Part 0: "1. 📍 ButtonName"
|
|
2741
|
-
const nameMatch = parts[0].match(/📍\s+(.+)/);
|
|
2742
|
-
if (nameMatch) {
|
|
2743
|
-
locator.name = nameMatch[1].trim();
|
|
2744
|
-
locator.text = nameMatch[1].trim();
|
|
2745
|
-
}
|
|
2746
|
-
|
|
2747
|
-
// Part 1: "[Button]" or "[TextView]"
|
|
2748
|
-
const typeMatch = parts[1] ? parts[1].match(/\[([^\]]+)\]/) : null;
|
|
2749
|
-
if (typeMatch) locator.type = typeMatch[1].trim();
|
|
2750
|
-
|
|
2751
|
-
// Process remaining parts for Label, Val, ID, coordinates, flags
|
|
2752
|
-
for (let i = 2; i < parts.length; i++) {
|
|
2753
|
-
const part = parts[i];
|
|
2754
|
-
|
|
2755
|
-
// Label:...
|
|
2756
|
-
if (part.includes('Label:')) {
|
|
2757
|
-
const labelMatch = part.match(/Label:([^\s]+)/);
|
|
2758
|
-
if (labelMatch) locator.label = labelMatch[1];
|
|
2759
|
-
}
|
|
2760
|
-
|
|
2761
|
-
// Val:...
|
|
2762
|
-
if (part.includes('Val:')) {
|
|
2763
|
-
const valueMatch = part.match(/Val:([^\s]+)/);
|
|
2764
|
-
if (valueMatch) locator.value = valueMatch[1];
|
|
2765
|
-
}
|
|
2766
|
-
|
|
2767
|
-
// ID:...
|
|
2768
|
-
if (part.includes('ID:')) {
|
|
2769
|
-
const idMatch = part.match(/ID:([^\s]+)/);
|
|
2770
|
-
if (idMatch) locator.resourceId = idMatch[1];
|
|
2771
|
-
}
|
|
2772
|
-
|
|
2773
|
-
// @ (x,y) WxH
|
|
2774
|
-
if (part.includes('@')) {
|
|
2775
|
-
const coordMatch = part.match(/@\s*\((\d+),(\d+)\)\s*(\d+)x(\d+)/);
|
|
2776
|
-
if (coordMatch) {
|
|
2777
|
-
locator.x = parseInt(coordMatch[1]);
|
|
2778
|
-
locator.y = parseInt(coordMatch[2]);
|
|
2779
|
-
locator.width = parseInt(coordMatch[3]);
|
|
2780
|
-
locator.height = parseInt(coordMatch[4]);
|
|
2781
|
-
locator.coordinates = `(${locator.x},${locator.y}) ${locator.width}x${locator.height}`;
|
|
2782
|
-
}
|
|
2783
|
-
}
|
|
2784
|
-
|
|
2785
|
-
// Flags
|
|
2786
|
-
if (part.includes('✓Vis')) locator.visible = true;
|
|
2787
|
-
if (part.includes('✓En')) locator.enabled = true;
|
|
2788
|
-
if (part.includes('✓Click')) locator.clickable = true;
|
|
2789
|
-
}
|
|
2790
|
-
} else {
|
|
2791
|
-
// Old format fallback
|
|
2792
|
-
const nameMatch = line.match(/📍\s+([^\[]+?)(?:\s*\[|\s*Label)/);
|
|
2793
|
-
if (nameMatch) {
|
|
2794
|
-
locator.name = nameMatch[1].trim();
|
|
2795
|
-
locator.text = nameMatch[1].trim();
|
|
2796
|
-
}
|
|
2797
|
-
|
|
2798
|
-
const typeMatch = line.match(/\[([^\]]+)\]/);
|
|
2799
|
-
if (typeMatch) locator.type = typeMatch[1].trim();
|
|
2800
|
-
|
|
2801
|
-
const labelMatch = line.match(/Label:([^\s]+?)(?:\s*Val:|\s*@|\s*✓)/);
|
|
2802
|
-
if (labelMatch) locator.label = labelMatch[1].trim();
|
|
2803
|
-
|
|
2804
|
-
const valueMatch = line.match(/Val:([^\s]+?)(?:\s*@|\s*✓)/);
|
|
2805
|
-
if (valueMatch) locator.value = valueMatch[1].trim();
|
|
2806
|
-
|
|
2807
|
-
const coordMatch = line.match(/@\s*\((\d+),(\d+)\)\s*(\d+)x(\d+)/);
|
|
2808
|
-
if (coordMatch) {
|
|
2809
|
-
locator.x = parseInt(coordMatch[1]);
|
|
2810
|
-
locator.y = parseInt(coordMatch[2]);
|
|
2811
|
-
locator.width = parseInt(coordMatch[3]);
|
|
2812
|
-
locator.height = parseInt(coordMatch[4]);
|
|
2813
|
-
locator.coordinates = `(${locator.x},${locator.y}) ${locator.width}x${locator.height}`;
|
|
2814
|
-
}
|
|
2815
|
-
|
|
2816
|
-
const idMatch = line.match(/ID:([^\s]+)/);
|
|
2817
|
-
if (idMatch) locator.resourceId = idMatch[1].trim();
|
|
2818
|
-
|
|
2819
|
-
locator.visible = line.includes('✓Vis');
|
|
2820
|
-
locator.enabled = line.includes('✓En');
|
|
2821
|
-
}
|
|
2822
|
-
|
|
2823
|
-
// Only add if we have meaningful data
|
|
2824
|
-
if (locator.name || locator.label || locator.text) {
|
|
2825
|
-
logger.debug('Parsed locator:', locator);
|
|
2826
|
-
locators.push(locator);
|
|
2827
|
-
}
|
|
2828
|
-
} catch (e) {
|
|
2829
|
-
// Skip malformed lines
|
|
2830
|
-
console.error('Error parsing locator line:', line, e);
|
|
2831
|
-
}
|
|
2832
|
-
}
|
|
2833
|
-
}
|
|
2834
|
-
|
|
2835
|
-
console.log(`✅ Total parsed locators: ${locators.length}`);
|
|
2836
|
-
return locators;
|
|
2837
|
-
}
|
|
2838
|
-
|
|
2839
|
-
// WebSocket handling
|
|
2840
|
-
wss.on('connection', (ws) => {
|
|
2841
|
-
console.log('New WebSocket connection');
|
|
2842
|
-
|
|
2843
|
-
ws.on('message', async (message) => {
|
|
2844
|
-
try {
|
|
2845
|
-
const data = JSON.parse(message);
|
|
2846
|
-
|
|
2847
|
-
switch (data.type) {
|
|
2848
|
-
case 'execute_command':
|
|
2849
|
-
const { devices, command, useAI, aiProvider } = data;
|
|
2850
|
-
|
|
2851
|
-
// separator removed
|
|
2852
|
-
console.log(`WEBSOCKET: Received execute_command`);
|
|
2853
|
-
console.log(`Devices received: [${devices.join(', ')}]`);
|
|
2854
|
-
console.log(`Command: "${command}"`);
|
|
2855
|
-
console.log(`Use AI: ${useAI}`);
|
|
2856
|
-
if (aiProvider) console.log(`AI Provider: ${aiProvider}`);
|
|
2857
|
-
// separator removed
|
|
2858
|
-
|
|
2859
|
-
let finalCommand = command;
|
|
2860
|
-
|
|
2861
|
-
if (useAI) {
|
|
2862
|
-
try {
|
|
2863
|
-
finalCommand = await convertNaturalLanguageToCommand(command, devices, aiProvider);
|
|
2864
|
-
console.log(`✅ AI converted command to:\n${finalCommand}`);
|
|
2865
|
-
ws.send(JSON.stringify({
|
|
2866
|
-
type: 'command_converted',
|
|
2867
|
-
original: command,
|
|
2868
|
-
converted: finalCommand,
|
|
2869
|
-
provider: aiProvider || aiManager.provider
|
|
2870
|
-
}));
|
|
2871
|
-
} catch (error) {
|
|
2872
|
-
console.error(`❌ AI conversion failed: ${error.message}`);
|
|
2873
|
-
|
|
2874
|
-
// Send error to frontend - DO NOT execute command
|
|
2875
|
-
ws.send(JSON.stringify({
|
|
2876
|
-
type: 'ai_error',
|
|
2877
|
-
error: error.message,
|
|
2878
|
-
original: command
|
|
2879
|
-
}));
|
|
2880
|
-
|
|
2881
|
-
// Stop execution - don't run unconverted commands
|
|
2882
|
-
return;
|
|
2883
|
-
}
|
|
2884
|
-
} else {
|
|
2885
|
-
|
|
2886
|
-
}
|
|
2887
|
-
|
|
2888
|
-
// Check if command has multiple lines (sequential execution)
|
|
2889
|
-
const hasMultipleCommands = finalCommand.includes('\n');
|
|
2890
|
-
|
|
2891
|
-
if (hasMultipleCommands) {
|
|
2892
|
-
|
|
2893
|
-
executeCommandsSequentially(devices, finalCommand, ws)
|
|
2894
|
-
.then(result => {
|
|
2895
|
-
console.log(`Sequential execution completed`);
|
|
2896
|
-
ws.send(JSON.stringify({
|
|
2897
|
-
type: 'command_complete',
|
|
2898
|
-
result
|
|
2899
|
-
}));
|
|
2900
|
-
})
|
|
2901
|
-
.catch(error => {
|
|
2902
|
-
console.error(`Sequential execution failed: ${error.message}`);
|
|
2903
|
-
ws.send(JSON.stringify({
|
|
2904
|
-
type: 'command_error',
|
|
2905
|
-
error: error.message
|
|
2906
|
-
}));
|
|
2907
|
-
});
|
|
2908
|
-
} else {
|
|
2909
|
-
executeCommand(devices, finalCommand, ws)
|
|
2910
|
-
.then(result => {
|
|
2911
|
-
|
|
2912
|
-
// Record command if recording is active
|
|
2913
|
-
if (isRecording) {
|
|
2914
|
-
recordCommand(devices, command, useAI, finalCommand);
|
|
2915
|
-
}
|
|
2916
|
-
|
|
2917
|
-
ws.send(JSON.stringify({
|
|
2918
|
-
type: 'command_complete',
|
|
2919
|
-
result
|
|
2920
|
-
}));
|
|
2921
|
-
})
|
|
2922
|
-
.catch(error => {
|
|
2923
|
-
console.error(`executeCommand failed: ${error.message}`);
|
|
2924
|
-
ws.send(JSON.stringify({
|
|
2925
|
-
type: 'command_error',
|
|
2926
|
-
error: error.message
|
|
2927
|
-
}));
|
|
2928
|
-
});
|
|
2929
|
-
}
|
|
2930
|
-
break;
|
|
2931
|
-
|
|
2932
|
-
case 'start_recording':
|
|
2933
|
-
const startResult = await startRecording(data.name, data.devices);
|
|
2934
|
-
ws.send(JSON.stringify({
|
|
2935
|
-
type: 'recording_started',
|
|
2936
|
-
...startResult
|
|
2937
|
-
}));
|
|
2938
|
-
break;
|
|
2939
|
-
|
|
2940
|
-
case 'stop_recording':
|
|
2941
|
-
const stopResult = await stopRecording();
|
|
2942
|
-
ws.send(JSON.stringify({
|
|
2943
|
-
type: 'recording_stopped',
|
|
2944
|
-
...stopResult
|
|
2945
|
-
}));
|
|
2946
|
-
break;
|
|
2947
|
-
|
|
2948
|
-
case 'replay_recording':
|
|
2949
|
-
const { filename, targetDevices } = data;
|
|
2950
|
-
|
|
2951
|
-
ws.send(JSON.stringify({
|
|
2952
|
-
type: 'command_output',
|
|
2953
|
-
data: `\n🎬 Starting replay: ${filename}\n\n`,
|
|
2954
|
-
devices: targetDevices
|
|
2955
|
-
}));
|
|
2956
|
-
|
|
2957
|
-
replayRecording(filename, targetDevices, ws)
|
|
2958
|
-
.then(result => {
|
|
2959
|
-
ws.send(JSON.stringify({
|
|
2960
|
-
type: 'replay_complete',
|
|
2961
|
-
...result
|
|
2962
|
-
}));
|
|
2963
|
-
})
|
|
2964
|
-
.catch(error => {
|
|
2965
|
-
ws.send(JSON.stringify({
|
|
2966
|
-
type: 'replay_error',
|
|
2967
|
-
error: error.message
|
|
2968
|
-
}));
|
|
2969
|
-
});
|
|
2970
|
-
break;
|
|
2971
|
-
|
|
2972
|
-
case 'stop_replay':
|
|
2973
|
-
if (isReplaying) {
|
|
2974
|
-
replayAborted = true;
|
|
2975
|
-
ws.send(JSON.stringify({
|
|
2976
|
-
type: 'command_output',
|
|
2977
|
-
data: '\n⏹️ Stopping replay...\n'
|
|
2978
|
-
}));
|
|
2979
|
-
}
|
|
2980
|
-
break;
|
|
2981
|
-
|
|
2982
|
-
case 'refresh_devices':
|
|
2983
|
-
const updatedDevices = await discoverDevices();
|
|
2984
|
-
ws.send(JSON.stringify({
|
|
2985
|
-
type: 'devices_updated',
|
|
2986
|
-
devices: updatedDevices
|
|
2987
|
-
}));
|
|
2988
|
-
break;
|
|
2989
|
-
|
|
2990
|
-
case 'get_ai_providers':
|
|
2991
|
-
ws.send(JSON.stringify({
|
|
2992
|
-
type: 'ai_providers',
|
|
2993
|
-
providers: aiManager.getAvailableProviders(),
|
|
2994
|
-
current: aiManager.provider
|
|
2995
|
-
}));
|
|
2996
|
-
break;
|
|
2997
|
-
|
|
2998
|
-
case 'set_ai_provider':
|
|
2999
|
-
const success = aiManager.setProvider(data.provider);
|
|
3000
|
-
ws.send(JSON.stringify({
|
|
3001
|
-
type: 'ai_provider_set',
|
|
3002
|
-
success,
|
|
3003
|
-
provider: data.provider
|
|
3004
|
-
}));
|
|
3005
|
-
break;
|
|
3006
|
-
}
|
|
3007
|
-
} catch (error) {
|
|
3008
|
-
ws.send(JSON.stringify({
|
|
3009
|
-
type: 'error',
|
|
3010
|
-
message: error.message
|
|
3011
|
-
}));
|
|
3012
|
-
}
|
|
3013
|
-
});
|
|
3014
|
-
|
|
3015
|
-
ws.on('close', () => {
|
|
3016
|
-
console.log('WebSocket connection closed');
|
|
3017
|
-
});
|
|
3018
|
-
|
|
3019
|
-
// Send initial device list
|
|
3020
|
-
discoverDevices().then(devices => {
|
|
3021
|
-
ws.send(JSON.stringify({
|
|
3022
|
-
type: 'devices_updated',
|
|
3023
|
-
devices
|
|
3024
|
-
}));
|
|
3025
|
-
});
|
|
3026
|
-
});
|
|
3027
|
-
|
|
3028
|
-
// Android UIAutomator2 Installation
|
|
3029
|
-
app.post('/api/android/install-uiautomator2', async (req, res) => {
|
|
3030
|
-
const { device } = req.body;
|
|
3031
|
-
|
|
3032
|
-
if (!device) {
|
|
3033
|
-
return res.status(400).json({ success: false, error: 'Device name required' });
|
|
3034
|
-
}
|
|
3035
|
-
|
|
3036
|
-
try {
|
|
3037
|
-
console.log(`📥 Installing UIAutomator2 on ${device}...`);
|
|
3038
|
-
|
|
3039
|
-
// Find device UDID
|
|
3040
|
-
const deviceObj = connectedDevices.find(d => d.name === device);
|
|
3041
|
-
if (!deviceObj) {
|
|
3042
|
-
return res.json({
|
|
3043
|
-
success: false,
|
|
3044
|
-
error: 'Device not found or not connected'
|
|
3045
|
-
});
|
|
3046
|
-
}
|
|
3047
|
-
|
|
3048
|
-
// Use the helper function
|
|
3049
|
-
const result = await installUIAutomator2(deviceObj.udid, device);
|
|
3050
|
-
|
|
3051
|
-
res.json(result);
|
|
3052
|
-
|
|
3053
|
-
} catch (error) {
|
|
3054
|
-
console.error('❌ UIAutomator2 installation error:', error.message);
|
|
3055
|
-
res.json({
|
|
3056
|
-
success: false,
|
|
3057
|
-
error: error.message,
|
|
3058
|
-
suggestion: 'Please install manually using: npm install -g appium-uiautomator2-driver'
|
|
3059
|
-
});
|
|
3060
|
-
}
|
|
3061
|
-
});
|
|
3062
|
-
|
|
3063
|
-
// ============================================
|
|
3064
|
-
// Recording & Replay API Endpoints
|
|
3065
|
-
// ============================================
|
|
3066
|
-
|
|
3067
|
-
// Start recording
|
|
3068
|
-
app.post('/api/recording/start', async (req, res) => {
|
|
3069
|
-
try {
|
|
3070
|
-
const { name, devices } = req.body;
|
|
3071
|
-
const result = await startRecording(name, devices);
|
|
3072
|
-
res.json(result);
|
|
3073
|
-
} catch (error) {
|
|
3074
|
-
res.status(500).json({ success: false, error: error.message });
|
|
3075
|
-
}
|
|
3076
|
-
});
|
|
3077
|
-
|
|
3078
|
-
// Stop recording
|
|
3079
|
-
app.post('/api/recording/stop', async (req, res) => {
|
|
3080
|
-
try {
|
|
3081
|
-
const result = await stopRecording();
|
|
3082
|
-
res.json(result);
|
|
3083
|
-
} catch (error) {
|
|
3084
|
-
res.status(500).json({ success: false, error: error.message });
|
|
3085
|
-
}
|
|
3086
|
-
});
|
|
3087
|
-
|
|
3088
|
-
// Get recording status
|
|
3089
|
-
app.get('/api/recording/status', (req, res) => {
|
|
3090
|
-
res.json({
|
|
3091
|
-
isRecording,
|
|
3092
|
-
recording: currentRecording
|
|
3093
|
-
});
|
|
3094
|
-
});
|
|
3095
|
-
|
|
3096
|
-
// List all recordings
|
|
3097
|
-
app.get('/api/recordings', async (req, res) => {
|
|
3098
|
-
try {
|
|
3099
|
-
const recordings = await listRecordings();
|
|
3100
|
-
res.json({ success: true, recordings });
|
|
3101
|
-
} catch (error) {
|
|
3102
|
-
res.status(500).json({ success: false, error: error.message });
|
|
3103
|
-
}
|
|
3104
|
-
});
|
|
3105
|
-
|
|
3106
|
-
// Get specific recording
|
|
3107
|
-
app.get('/api/recordings/:filename', async (req, res) => {
|
|
3108
|
-
try {
|
|
3109
|
-
const recording = await loadRecording(req.params.filename);
|
|
3110
|
-
res.json({ success: true, recording });
|
|
3111
|
-
} catch (error) {
|
|
3112
|
-
res.status(404).json({ success: false, error: 'Recording not found' });
|
|
3113
|
-
}
|
|
3114
|
-
});
|
|
3115
|
-
|
|
3116
|
-
// Delete recording
|
|
3117
|
-
app.delete('/api/recordings/:filename', async (req, res) => {
|
|
3118
|
-
try {
|
|
3119
|
-
await deleteRecording(req.params.filename);
|
|
3120
|
-
res.json({ success: true });
|
|
3121
|
-
} catch (error) {
|
|
3122
|
-
res.status(500).json({ success: false, error: error.message });
|
|
3123
|
-
}
|
|
3124
|
-
});
|
|
3125
|
-
|
|
3126
|
-
// Update recording
|
|
3127
|
-
app.put('/api/recordings/:filename', async (req, res) => {
|
|
3128
|
-
try {
|
|
3129
|
-
const { filename } = req.params;
|
|
3130
|
-
const updatedRecording = req.body;
|
|
3131
|
-
|
|
3132
|
-
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
3133
|
-
await fs.writeFile(filepath, JSON.stringify(updatedRecording, null, 2));
|
|
3134
|
-
|
|
3135
|
-
res.json({ success: true, recording: updatedRecording });
|
|
3136
|
-
} catch (error) {
|
|
3137
|
-
res.status(500).json({ success: false, error: error.message });
|
|
3138
|
-
}
|
|
3139
|
-
});
|
|
3140
|
-
|
|
3141
|
-
// Save new recording
|
|
3142
|
-
app.post('/api/recordings/save', async (req, res) => {
|
|
3143
|
-
try {
|
|
3144
|
-
const { name, commands, date, type } = req.body;
|
|
3145
|
-
|
|
3146
|
-
if (!name || !commands) {
|
|
3147
|
-
return res.status(400).json({ success: false, error: 'Name and commands required' });
|
|
3148
|
-
}
|
|
3149
|
-
|
|
3150
|
-
// Create filename from name (sanitize)
|
|
3151
|
-
const sanitizedName = name.replace(/[^a-z0-9_-]/gi, '_');
|
|
3152
|
-
const filename = `${sanitizedName}_${Date.now()}.json`;
|
|
3153
|
-
const filepath = path.join(RECORDINGS_DIR, filename);
|
|
3154
|
-
|
|
3155
|
-
const recording = {
|
|
3156
|
-
name,
|
|
3157
|
-
commands,
|
|
3158
|
-
date: date || new Date().toISOString(),
|
|
3159
|
-
type: type || 'manual'
|
|
3160
|
-
};
|
|
3161
|
-
|
|
3162
|
-
await fs.writeFile(filepath, JSON.stringify(recording, null, 2));
|
|
3163
|
-
|
|
3164
|
-
res.json({ success: true, filename, recording });
|
|
3165
|
-
} catch (error) {
|
|
3166
|
-
console.error('Error saving recording:', error);
|
|
3167
|
-
res.status(500).json({ success: false, error: error.message });
|
|
3168
|
-
}
|
|
3169
|
-
});
|
|
3170
|
-
|
|
3171
|
-
// Replay recording
|
|
3172
|
-
app.post('/api/recording/replay', async (req, res) => {
|
|
3173
|
-
try {
|
|
3174
|
-
const { filename, devices } = req.body;
|
|
3175
|
-
|
|
3176
|
-
if (!filename) {
|
|
3177
|
-
return res.status(400).json({ success: false, error: 'Filename required' });
|
|
3178
|
-
}
|
|
3179
|
-
|
|
3180
|
-
if (!devices || devices.length === 0) {
|
|
3181
|
-
return res.status(400).json({ success: false, error: 'Target devices required' });
|
|
3182
|
-
}
|
|
3183
|
-
|
|
3184
|
-
// Start replay in background, send immediate response
|
|
3185
|
-
res.json({ success: true, message: 'Replay started' });
|
|
3186
|
-
|
|
3187
|
-
// Replay will send updates via WebSocket
|
|
3188
|
-
// This is handled by WebSocket message 'replay_recording'
|
|
3189
|
-
} catch (error) {
|
|
3190
|
-
res.status(500).json({ success: false, error: error.message });
|
|
3191
|
-
}
|
|
3192
|
-
});
|
|
3193
|
-
|
|
3194
|
-
// Screenshots API
|
|
3195
|
-
app.get('/api/screenshots', async (req, res) => {
|
|
3196
|
-
try {
|
|
3197
|
-
// Ensure screenshots directory exists
|
|
3198
|
-
await fs.mkdir(SCREENSHOTS_DIR, { recursive: true });
|
|
3199
|
-
|
|
3200
|
-
const files = await fs.readdir(SCREENSHOTS_DIR);
|
|
3201
|
-
const screenshots = files
|
|
3202
|
-
.filter(f => f.endsWith('.png'))
|
|
3203
|
-
.map(f => {
|
|
3204
|
-
const stat = require('fs').statSync(path.join(SCREENSHOTS_DIR, f));
|
|
3205
|
-
return {
|
|
3206
|
-
filename: f,
|
|
3207
|
-
path: `/api/screenshots/${f}`,
|
|
3208
|
-
size: stat.size,
|
|
3209
|
-
timestamp: stat.mtime.getTime(),
|
|
3210
|
-
created: stat.mtime
|
|
3211
|
-
};
|
|
3212
|
-
})
|
|
3213
|
-
.sort((a, b) => b.timestamp - a.timestamp);
|
|
3214
|
-
|
|
3215
|
-
res.json({ success: true, screenshots });
|
|
3216
|
-
} catch (error) {
|
|
3217
|
-
res.status(500).json({ success: false, error: error.message });
|
|
3218
|
-
}
|
|
3219
|
-
});
|
|
3220
|
-
|
|
3221
|
-
// Serve screenshot files
|
|
3222
|
-
app.get('/api/screenshots/:filename', (req, res) => {
|
|
3223
|
-
const filepath = path.join(SCREENSHOTS_DIR, req.params.filename);
|
|
3224
|
-
res.sendFile(filepath, (err) => {
|
|
3225
|
-
if (err) {
|
|
3226
|
-
res.status(404).json({ success: false, error: 'Screenshot not found' });
|
|
3227
|
-
}
|
|
3228
|
-
});
|
|
3229
|
-
});
|
|
3230
|
-
|
|
3231
|
-
// Delete screenshot
|
|
3232
|
-
app.delete('/api/screenshots/:filename', async (req, res) => {
|
|
3233
|
-
try {
|
|
3234
|
-
const filepath = path.join(SCREENSHOTS_DIR, req.params.filename);
|
|
3235
|
-
await fs.unlink(filepath);
|
|
3236
|
-
res.json({ success: true });
|
|
3237
|
-
} catch (error) {
|
|
3238
|
-
res.status(500).json({ success: false, error: error.message });
|
|
3239
|
-
}
|
|
3240
|
-
});
|
|
3241
|
-
|
|
3242
|
-
// List installed apps on device
|
|
3243
|
-
app.post('/api/apps/list', async (req, res) => {
|
|
3244
|
-
try {
|
|
3245
|
-
const { devices } = req.body;
|
|
3246
|
-
|
|
3247
|
-
if (!devices || devices.length === 0) {
|
|
3248
|
-
return res.status(400).json({ success: false, error: 'Device selection required' });
|
|
3249
|
-
}
|
|
3250
|
-
|
|
3251
|
-
const deviceObjects = connectedDevices.filter(d =>
|
|
3252
|
-
devices.includes(d.name) || devices.includes(d.udid) || devices.includes(d.serial)
|
|
3253
|
-
);
|
|
3254
|
-
|
|
3255
|
-
if (deviceObjects.length === 0) {
|
|
3256
|
-
return res.status(400).json({ success: false, error: 'No connected devices found' });
|
|
3257
|
-
}
|
|
3258
|
-
|
|
3259
|
-
const results = {};
|
|
3260
|
-
|
|
3261
|
-
for (const device of deviceObjects) {
|
|
3262
|
-
try {
|
|
3263
|
-
let apps = [];
|
|
3264
|
-
|
|
3265
|
-
if (device.platform === 'android') {
|
|
3266
|
-
// List Android apps
|
|
3267
|
-
const { execSync } = require('child_process');
|
|
3268
|
-
const serial = device.udid || device.serial;
|
|
3269
|
-
const output = execSync(`adb -s ${serial} shell pm list packages -3`, { encoding: 'utf-8' });
|
|
3270
|
-
apps = output
|
|
3271
|
-
.split('\n')
|
|
3272
|
-
.filter(line => line.startsWith('package:'))
|
|
3273
|
-
.map(line => line.replace('package:', '').trim())
|
|
3274
|
-
.filter(pkg => pkg)
|
|
3275
|
-
.sort();
|
|
3276
|
-
} else if (device.platform === 'ios') {
|
|
3277
|
-
// List iOS apps - requires ideviceinstaller
|
|
3278
|
-
const { execSync } = require('child_process');
|
|
3279
|
-
const udid = device.udid;
|
|
3280
|
-
try {
|
|
3281
|
-
// Try new syntax first (ideviceinstaller list)
|
|
3282
|
-
let output;
|
|
3283
|
-
try {
|
|
3284
|
-
output = execSync(`ideviceinstaller -u ${udid} list --user`, { encoding: 'utf-8', timeout: 30000 });
|
|
3285
|
-
} catch (e) {
|
|
3286
|
-
// Fallback to old syntax
|
|
3287
|
-
output = execSync(`ideviceinstaller -u ${udid} -l`, { encoding: 'utf-8', timeout: 30000 });
|
|
3288
|
-
}
|
|
3289
|
-
|
|
3290
|
-
// Parse output - format is "BundleID - AppName" or CFBundleIdentifier format
|
|
3291
|
-
apps = output
|
|
3292
|
-
.split('\n')
|
|
3293
|
-
.filter(line => {
|
|
3294
|
-
const trimmed = line.trim();
|
|
3295
|
-
// Skip empty lines, Total: line, and CSV header
|
|
3296
|
-
return trimmed &&
|
|
3297
|
-
!trimmed.startsWith('Total:') &&
|
|
3298
|
-
!trimmed.startsWith('CFBundleIdentifier');
|
|
3299
|
-
})
|
|
3300
|
-
.map(line => {
|
|
3301
|
-
// Try different formats
|
|
3302
|
-
if (line.includes(' - ')) {
|
|
3303
|
-
const match = line.match(/^(.+?)\s+-\s+(.+?)$/);
|
|
3304
|
-
return match ? { id: match[1].trim(), name: match[2].trim() } : null;
|
|
3305
|
-
} else if (line.includes(',')) {
|
|
3306
|
-
// Format: "BundleID", "Version", "Name"
|
|
3307
|
-
const parts = line.split(',').map(p => p.trim().replace(/"/g, ''));
|
|
3308
|
-
return parts.length >= 3 ? { id: parts[0], name: parts[2] } : null;
|
|
3309
|
-
} else if (line.match(/^[a-zA-Z0-9.-]+$/)) {
|
|
3310
|
-
// Just bundle ID
|
|
3311
|
-
return { id: line.trim(), name: line.trim() };
|
|
3312
|
-
}
|
|
3313
|
-
return null;
|
|
3314
|
-
})
|
|
3315
|
-
.filter(app => app)
|
|
3316
|
-
.sort((a, b) => a.name.localeCompare(b.name));
|
|
3317
|
-
|
|
3318
|
-
if (apps.length === 0) {
|
|
3319
|
-
apps = [{ error: 'No user apps found or unable to parse output' }];
|
|
3320
|
-
}
|
|
3321
|
-
} catch (error) {
|
|
3322
|
-
console.error('iOS apps list error:', error.message);
|
|
3323
|
-
apps = [{ error: `Failed to list apps: ${error.message}` }];
|
|
3324
|
-
}
|
|
3325
|
-
}
|
|
3326
|
-
|
|
3327
|
-
results[device.name] = {
|
|
3328
|
-
success: true,
|
|
3329
|
-
platform: device.platform,
|
|
3330
|
-
apps: apps,
|
|
3331
|
-
count: Array.isArray(apps) ? apps.length : 0
|
|
3332
|
-
};
|
|
3333
|
-
} catch (error) {
|
|
3334
|
-
results[device.name] = {
|
|
3335
|
-
success: false,
|
|
3336
|
-
error: error.message
|
|
3337
|
-
};
|
|
3338
|
-
}
|
|
3339
|
-
}
|
|
3340
|
-
|
|
3341
|
-
res.json({ success: true, results });
|
|
3342
|
-
} catch (error) {
|
|
3343
|
-
res.status(500).json({ success: false, error: error.message });
|
|
3344
|
-
}
|
|
3345
|
-
});
|
|
3346
|
-
|
|
3347
|
-
// Get app info
|
|
3348
|
-
app.post('/api/apps/info', async (req, res) => {
|
|
3349
|
-
try {
|
|
3350
|
-
const { device, bundleId } = req.body;
|
|
3351
|
-
|
|
3352
|
-
if (!device || !bundleId) {
|
|
3353
|
-
return res.status(400).json({ success: false, error: 'Device and bundle ID required' });
|
|
3354
|
-
}
|
|
3355
|
-
|
|
3356
|
-
const deviceObj = discoveredDevices.find(d => d.name === device);
|
|
3357
|
-
if (!deviceObj) {
|
|
3358
|
-
return res.status(404).json({ success: false, error: 'Device not found' });
|
|
3359
|
-
}
|
|
3360
|
-
|
|
3361
|
-
const { execSync } = require('child_process');
|
|
3362
|
-
let appInfo = {};
|
|
3363
|
-
|
|
3364
|
-
try {
|
|
3365
|
-
if (deviceObj.platform === 'android') {
|
|
3366
|
-
// Get Android app info
|
|
3367
|
-
const serial = deviceObj.udid || deviceObj.serial;
|
|
3368
|
-
|
|
3369
|
-
// Get app version
|
|
3370
|
-
try {
|
|
3371
|
-
const versionOutput = execSync(
|
|
3372
|
-
`adb -s ${serial} shell dumpsys package ${bundleId} | grep versionName`,
|
|
3373
|
-
{ encoding: 'utf-8', timeout: 10000 }
|
|
3374
|
-
);
|
|
3375
|
-
const versionMatch = versionOutput.match(/versionName=([^\s]+)/);
|
|
3376
|
-
if (versionMatch) {
|
|
3377
|
-
appInfo.version = versionMatch[1];
|
|
3378
|
-
}
|
|
3379
|
-
} catch (e) {
|
|
3380
|
-
appInfo.version = 'Unknown';
|
|
3381
|
-
}
|
|
3382
|
-
|
|
3383
|
-
// Get app label/name
|
|
3384
|
-
try {
|
|
3385
|
-
const labelOutput = execSync(
|
|
3386
|
-
`adb -s ${serial} shell dumpsys package ${bundleId} | grep -A 1 "applicationInfo"`,
|
|
3387
|
-
{ encoding: 'utf-8', timeout: 10000 }
|
|
3388
|
-
);
|
|
3389
|
-
appInfo.name = bundleId;
|
|
3390
|
-
} catch (e) {
|
|
3391
|
-
appInfo.name = bundleId;
|
|
3392
|
-
}
|
|
3393
|
-
|
|
3394
|
-
// Get install location
|
|
3395
|
-
try {
|
|
3396
|
-
const pathOutput = execSync(
|
|
3397
|
-
`adb -s ${serial} shell pm path ${bundleId}`,
|
|
3398
|
-
{ encoding: 'utf-8', timeout: 10000 }
|
|
3399
|
-
);
|
|
3400
|
-
appInfo.path = pathOutput.replace('package:', '').trim();
|
|
3401
|
-
} catch (e) {
|
|
3402
|
-
appInfo.path = 'Unknown';
|
|
3403
|
-
}
|
|
3404
|
-
|
|
3405
|
-
appInfo.bundleId = bundleId;
|
|
3406
|
-
appInfo.platform = 'Android';
|
|
3407
|
-
|
|
3408
|
-
} else if (deviceObj.platform === 'ios') {
|
|
3409
|
-
// Get iOS app info
|
|
3410
|
-
const udid = deviceObj.udid;
|
|
3411
|
-
|
|
3412
|
-
try {
|
|
3413
|
-
// Try to get app info using ideviceinstaller
|
|
3414
|
-
const output = execSync(
|
|
3415
|
-
`ideviceinstaller -u ${udid} list --user | grep "${bundleId}"`,
|
|
3416
|
-
{ encoding: 'utf-8', timeout: 10000 }
|
|
3417
|
-
);
|
|
3418
|
-
|
|
3419
|
-
// Parse CSV format: BundleID, Version, Name
|
|
3420
|
-
const parts = output.split(',').map(p => p.trim().replace(/"/g, ''));
|
|
3421
|
-
if (parts.length >= 3) {
|
|
3422
|
-
appInfo.bundleId = parts[0];
|
|
3423
|
-
appInfo.version = parts[1];
|
|
3424
|
-
appInfo.name = parts[2];
|
|
3425
|
-
} else {
|
|
3426
|
-
appInfo.bundleId = bundleId;
|
|
3427
|
-
appInfo.name = bundleId;
|
|
3428
|
-
appInfo.version = 'Unknown';
|
|
3429
|
-
}
|
|
3430
|
-
} catch (e) {
|
|
3431
|
-
// Fallback
|
|
3432
|
-
appInfo.bundleId = bundleId;
|
|
3433
|
-
appInfo.name = bundleId;
|
|
3434
|
-
appInfo.version = 'Unknown';
|
|
3435
|
-
appInfo.error = 'Could not retrieve detailed info';
|
|
3436
|
-
}
|
|
3437
|
-
|
|
3438
|
-
appInfo.platform = 'iOS';
|
|
3439
|
-
}
|
|
3440
|
-
|
|
3441
|
-
res.json({ success: true, appInfo });
|
|
3442
|
-
|
|
3443
|
-
} catch (error) {
|
|
3444
|
-
res.json({
|
|
3445
|
-
success: false,
|
|
3446
|
-
error: error.message,
|
|
3447
|
-
appInfo: {
|
|
3448
|
-
bundleId: bundleId,
|
|
3449
|
-
platform: deviceObj.platform,
|
|
3450
|
-
error: 'Failed to get app info'
|
|
3451
|
-
}
|
|
3452
|
-
});
|
|
3453
|
-
}
|
|
3454
|
-
|
|
3455
|
-
} catch (error) {
|
|
3456
|
-
res.status(500).json({ success: false, error: error.message });
|
|
3457
|
-
}
|
|
3458
|
-
});
|
|
3459
|
-
|
|
3460
|
-
// Upgrade HTTP server to WebSocket
|
|
3461
|
-
let server;
|
|
3462
|
-
|
|
3463
|
-
function startServer(options = {}) {
|
|
3464
|
-
const port = options.port || PORT;
|
|
3465
|
-
const shouldOpenBrowser = options.browser !== false;
|
|
3466
|
-
const frontendUrl = 'https://devicely-ai.vercel.app';
|
|
3467
|
-
|
|
3468
|
-
console.log(`Frontend available at: ${frontendUrl}\n`);
|
|
3469
|
-
|
|
3470
|
-
return new Promise((resolve, reject) => {
|
|
3471
|
-
server = app.listen(port, () => {
|
|
3472
|
-
console.log(`✅ Server running on port ${port}`);
|
|
3473
|
-
console.log(`✅ WebSocket server ready`);
|
|
3474
|
-
|
|
3475
|
-
// Initial device discovery
|
|
3476
|
-
discoverDevices().then(devices => {
|
|
3477
|
-
console.log(`✅ Discovered ${devices.length} devices`);
|
|
3478
|
-
|
|
3479
|
-
// Open browser if not disabled
|
|
3480
|
-
if (shouldOpenBrowser) {
|
|
3481
|
-
console.log(`\n🌐 Opening browser to ${frontendUrl}...`);
|
|
3482
|
-
const open = require('open');
|
|
3483
|
-
open(frontendUrl).catch(err => {
|
|
3484
|
-
console.log(`\n📱 Please open ${frontendUrl} in your browser`);
|
|
3485
|
-
});
|
|
3486
|
-
}
|
|
3487
|
-
|
|
3488
|
-
resolve();
|
|
3489
|
-
}).catch(err => {
|
|
3490
|
-
logger.error('Device discovery failed:', err.message);
|
|
3491
|
-
resolve();
|
|
3492
|
-
});
|
|
3493
|
-
});
|
|
3494
|
-
|
|
3495
|
-
// Handle WebSocket upgrades
|
|
3496
|
-
server.on('upgrade', (request, socket, head) => {
|
|
3497
|
-
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
3498
|
-
wss.emit('connection', ws, request);
|
|
3499
|
-
});
|
|
3500
|
-
});
|
|
3501
|
-
|
|
3502
|
-
server.on('error', (err) => {
|
|
3503
|
-
if (err.code === 'EADDRINUSE') {
|
|
3504
|
-
logger.error(`\n❌ Port ${port} is already in use!`);
|
|
3505
|
-
logger.error(`\nTry one of these solutions:`);
|
|
3506
|
-
logger.error(` 1. Kill the process using port ${port}: lsof -ti:${port} | xargs kill -9`);
|
|
3507
|
-
logger.error(` 2. Use a different port: PORT=3002 devicely`);
|
|
3508
|
-
logger.error(` 3. Set PORT in .env file\n`);
|
|
3509
|
-
}
|
|
3510
|
-
reject(err);
|
|
3511
|
-
});
|
|
3512
|
-
});
|
|
3513
|
-
}
|
|
3514
|
-
|
|
3515
|
-
function stopServer() {
|
|
3516
|
-
return new Promise((resolve) => {
|
|
3517
|
-
if (server) {
|
|
3518
|
-
server.close(resolve);
|
|
3519
|
-
} else {
|
|
3520
|
-
resolve();
|
|
3521
|
-
}
|
|
3522
|
-
});
|
|
3523
|
-
}
|
|
3524
|
-
|
|
3525
|
-
// Export for CLI usage
|
|
3526
|
-
module.exports = {
|
|
3527
|
-
startServer,
|
|
3528
|
-
stopServer
|
|
3529
|
-
};
|
|
3530
|
-
|
|
3531
|
-
// Start server if run directly (not imported as module)
|
|
3532
|
-
if (require.main === module) {
|
|
3533
|
-
startServer().catch(err => {
|
|
3534
|
-
if (err.code === 'EADDRINUSE') {
|
|
3535
|
-
logger.error(`\n❌ Port 3001 is already in use!`);
|
|
3536
|
-
logger.error(`\nTry one of these solutions:`);
|
|
3537
|
-
logger.error(` 1. Kill the process using port 3001: lsof -ti:3001 | xargs kill -9`);
|
|
3538
|
-
logger.error(` 2. Use a different port: PORT=3002 devicely`);
|
|
3539
|
-
logger.error(` Note: Vercel frontend connects to port 3001 by default`);
|
|
3540
|
-
logger.error(` 3. Use local frontend at http://localhost:3001\n`);
|
|
3541
|
-
} else {
|
|
3542
|
-
console.error('Failed to start server:', err.message);
|
|
3543
|
-
}
|
|
3544
|
-
process.exit(1);
|
|
3545
|
-
});
|
|
3546
|
-
}
|
|
1
|
+
const _0x320de1=_0x8de2;(function(_0xeb198a,_0x27ba51){const _0x3b3b22=_0x8de2,_0x3dc278=_0xeb198a();while(!![]){try{const _0x4e8c8b=-parseInt(_0x3b3b22(0x732))/0x1+parseInt(_0x3b3b22(0x3ab))/0x2*(parseInt(_0x3b3b22(0x593))/0x3)+parseInt(_0x3b3b22(0x29c))/0x4+-parseInt(_0x3b3b22(0xda))/0x5+-parseInt(_0x3b3b22(0x73f))/0x6+-parseInt(_0x3b3b22(0x57a))/0x7+parseInt(_0x3b3b22(0x26c))/0x8;if(_0x4e8c8b===_0x27ba51)break;else _0x3dc278['push'](_0x3dc278['shift']());}catch(_0xb6a1a2){_0x3dc278['push'](_0x3dc278['shift']());}}}(_0x3ee9,0xa60bd));function _0x8de2(_0x527251,_0x1d8700){_0x527251=_0x527251-0xd2;const _0x3ee9cd=_0x3ee9();let _0x8de2d2=_0x3ee9cd[_0x527251];if(_0x8de2['oIxYjS']===undefined){var _0x52e923=function(_0x319a7a){const _0x202f58='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x159c73='',_0x101765='';for(let _0x314276=0x0,_0x49a15c,_0x38c41e,_0x25ee7d=0x0;_0x38c41e=_0x319a7a['charAt'](_0x25ee7d++);~_0x38c41e&&(_0x49a15c=_0x314276%0x4?_0x49a15c*0x40+_0x38c41e:_0x38c41e,_0x314276++%0x4)?_0x159c73+=String['fromCharCode'](0xff&_0x49a15c>>(-0x2*_0x314276&0x6)):0x0){_0x38c41e=_0x202f58['indexOf'](_0x38c41e);}for(let _0x3804a5=0x0,_0x5e61a9=_0x159c73['length'];_0x3804a5<_0x5e61a9;_0x3804a5++){_0x101765+='%'+('00'+_0x159c73['charCodeAt'](_0x3804a5)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x101765);};_0x8de2['wPhnZm']=_0x52e923,_0x8de2['gZOLkC']={},_0x8de2['oIxYjS']=!![];}const _0x16745a=_0x3ee9cd[0x0],_0x28dd5d=_0x527251+_0x16745a,_0x5d097a=_0x8de2['gZOLkC'][_0x28dd5d];return!_0x5d097a?(_0x8de2d2=_0x8de2['wPhnZm'](_0x8de2d2),_0x8de2['gZOLkC'][_0x28dd5d]=_0x8de2d2):_0x8de2d2=_0x5d097a,_0x8de2d2;}const path=require(_0x320de1(0x433));require('dotenv')[_0x320de1(0x349)]({'path':path['join'](__dirname,_0x320de1(0x36d))});const express=require('express'),cors=require(_0x320de1(0x460)),{spawn}=require(_0x320de1(0x710)),WebSocket=require('ws'),fs=require('fs')[_0x320de1(0x44d)],AIProviderManager=require('./aiProviders'),Logger=require(_0x320de1(0x622)),logger=new Logger('Server');let scriptLoader;try{scriptLoader=require(_0x320de1(0x6f0));}catch(_0x125156){scriptLoader=null;}let discoverAllDevices;try{({discoverAllDevices}=require(_0x320de1(0x6d2)));}catch(_0x1c0f9a){({discoverAllDevices}=require(_0x320de1(0x711)));}const {execSync}=require('child_process'),app=express(),PORT=process.env.PORT||0xbb9;app[_0x320de1(0x28f)](cors()),app['use'](express['json']());const frontendPath=require('fs')[_0x320de1(0x19a)](path[_0x320de1(0x4dd)](__dirname,_0x320de1(0x2f1)))?path['join'](__dirname,_0x320de1(0x2f1)):path[_0x320de1(0x4dd)](__dirname,_0x320de1(0x464));app[_0x320de1(0x28f)](express['static'](frontendPath));const _0x1ccb5d={};_0x1ccb5d[_0x320de1(0x667)]=!![];const wss=new WebSocket[(_0x320de1(0x13d))](_0x1ccb5d),aiManager=new AIProviderManager();let connectedDevices=[],activeConnections=new Map(),wdaProcesses=new Map(),androidSessions=new Map();function findConfigFile(_0x41ce35){const _0x41dd20=_0x320de1,_0x330aa3={'PcqAx':'ios','zzhaw':_0x41dd20(0x4b1),'JxDSH':function(_0x2e38c0,_0x21d1a9){return _0x2e38c0(_0x21d1a9);},'gkDmp':_0x41dd20(0x398),'WWLyw':_0x41dd20(0x43d),'DjmxD':'../config/'};let _0x37e36c=path['join'](__dirname,_0x330aa3[_0x41dd20(0x5cd)],_0x41ce35);if(_0x330aa3[_0x41dd20(0x4cc)](require,'fs')[_0x41dd20(0x19a)](_0x37e36c)){if(_0x330aa3[_0x41dd20(0x66e)]===_0x330aa3[_0x41dd20(0x524)])_0x36706e=_0x330aa3[_0x41dd20(0x511)];else return _0x37e36c;}_0x37e36c=path[_0x41dd20(0x4dd)](__dirname,_0x330aa3[_0x41dd20(0x1f0)],_0x41ce35);if(require('fs')[_0x41dd20(0x19a)](_0x37e36c))return _0x37e36c;return path[_0x41dd20(0x4dd)](__dirname,_0x330aa3[_0x41dd20(0x5cd)],_0x41ce35);}function findScriptFile(_0x28e3b6){const _0x4f977a=_0x320de1,_0x27b289={'ZrbFt':'command_output','nqguN':_0x4f977a(0x191),'PNyIE':function(_0x5bb985,_0x2de21b){return _0x5bb985(_0x2de21b);},'izhSx':_0x4f977a(0x20c),'NjJzY':function(_0x562eb5,_0x1594b4){return _0x562eb5+_0x1594b4;},'xchgN':_0x4f977a(0x4b1),'mAxMt':'../scripts/shell/','XfBZA':_0x4f977a(0x37f),'FPnFR':_0x4f977a(0x2dd),'XLfRT':_0x4f977a(0x3f1),'CjTgh':_0x4f977a(0x223),'KQptk':'MQHSe','djClG':_0x4f977a(0x585),'XQdPG':'dmGEm'},_0x537e9c=require('fs'),_0x187b12=_0x27b289['PNyIE'](require,'os'),_0x40844a=_0x27b289[_0x4f977a(0x40f)](require,_0x27b289[_0x4f977a(0x337)]),_0x4e579e=_0x28e3b6[_0x4f977a(0x15d)](/\.sh$/,''),_0x3aa696=_0x27b289['NjJzY'](_0x4e579e,_0x4f977a(0x503)),_0x3fa252=[{'path':path[_0x4f977a(0x4dd)](__dirname,_0x27b289[_0x4f977a(0x38f)],_0x28e3b6),'encrypted':![]},{'path':path[_0x4f977a(0x4dd)](__dirname,_0x27b289[_0x4f977a(0x315)],_0x3aa696),'encrypted':!![]},{'path':path['join'](__dirname,_0x27b289[_0x4f977a(0x315)],_0x28e3b6),'encrypted':![]},{'path':path['join'](__dirname,_0x4f977a(0xff),_0x4e579e),'encrypted':![]}];for(const {path:_0x13c8aa,encrypted:_0x1d488a}of _0x3fa252){if(_0x27b289[_0x4f977a(0x306)]===_0x4f977a(0x6d5)){const _0x192b5b=_0x2f3efd['ip']||'';_0x3f1933+=_0x42d9dc[_0x4f977a(0x4b8)]+','+_0x20cbd0[_0x4f977a(0x23d)]+','+_0x192b5b+'\x0a';}else{if(_0x537e9c[_0x4f977a(0x19a)](_0x13c8aa)){logger[_0x4f977a(0x3d0)](_0x4f977a(0x212)+_0x28e3b6+_0x4f977a(0x320)+_0x13c8aa+(_0x1d488a?_0x27b289['FPnFR']:''));if(_0x1d488a&&scriptLoader){const _0x43d5d1=path[_0x4f977a(0x4dd)](_0x187b12[_0x4f977a(0x2b9)](),_0x27b289['NjJzY'](_0x27b289[_0x4f977a(0x4f2)],process[_0x4f977a(0x519)]));if(!_0x537e9c[_0x4f977a(0x19a)](_0x43d5d1)){const _0x42e143={};_0x42e143['recursive']=!![],_0x42e143[_0x4f977a(0x284)]=0x1c0,_0x537e9c[_0x4f977a(0x13a)](_0x43d5d1,_0x42e143);}const _0x261138=path[_0x4f977a(0x4dd)](_0x43d5d1,_0x28e3b6);if(!_0x537e9c[_0x4f977a(0x19a)](_0x261138)){if(_0x27b289[_0x4f977a(0x4a8)]===_0x27b289[_0x4f977a(0x6e2)]){const _0x4a0107={};_0x4a0107[_0x4f977a(0x14d)]=_0x27b289['ZrbFt'],_0x4a0107[_0x4f977a(0x760)]=_0x4f977a(0x317)+_0x459144+_0x4f977a(0x657),_0x4a0107[_0x4f977a(0x1a6)]=_0x5c15b4,_0x22f9af[_0x4f977a(0x475)](_0x150d91['stringify'](_0x4a0107));}else try{if(_0x4f977a(0x41e)!==_0x27b289[_0x4f977a(0x43f)]){const _0x2924c3=scriptLoader['decryptScript'](_0x13c8aa),_0x5525ba={};_0x5525ba[_0x4f977a(0x284)]=0x1ed,_0x537e9c['writeFileSync'](_0x261138,_0x2924c3,_0x5525ba),logger['debug'](_0x4f977a(0x44a)+_0x28e3b6+'\x20to\x20temp\x20directory');}else return _0x276a58;}catch(_0x5b2583){if(_0x27b289[_0x4f977a(0x1e3)]===_0x27b289[_0x4f977a(0x1e3)]){console[_0x4f977a(0x644)]('❌\x20Failed\x20to\x20decrypt\x20'+_0x28e3b6+':\x20'+_0x5b2583[_0x4f977a(0x4f1)]);continue;}else{const _0x42999f={};_0x42999f[_0x4f977a(0x66c)]=![],_0x42999f[_0x4f977a(0x644)]=_0x27b289[_0x4f977a(0x201)],_0x12473a[_0x4f977a(0x365)](0x194)[_0x4f977a(0x169)](_0x42999f);}}}return _0x261138;}return _0x13c8aa;}}}return console[_0x4f977a(0x644)](_0x4f977a(0x6d0)+_0x28e3b6),console[_0x4f977a(0x644)](_0x4f977a(0x680)),_0x3fa252[_0x4f977a(0x11d)](_0x5a5661=>console[_0x4f977a(0x644)](_0x4f977a(0x718)+_0x5a5661[_0x4f977a(0x433)])),_0x3fa252[0x0][_0x4f977a(0x433)];}const DEVICE_CONFIG=findConfigFile('devices.conf'),SESSION_MAP_FILE=path['join'](require('os')[_0x320de1(0x2b9)](),_0x320de1(0x1b6)),APPS_CONFIG=findConfigFile('apps_presets.conf'),WIRELESS_SCRIPT_PATH=findScriptFile(_0x320de1(0x3cb)),USB_SCRIPT_PATH=findScriptFile(_0x320de1(0x49c)),ANDROID_WIRELESS_SCRIPT_PATH=findScriptFile(_0x320de1(0x632)),ANDROID_USB_SCRIPT_PATH=findScriptFile('android_device_control.sh'),RECORDINGS_DIR=path[_0x320de1(0x4dd)](__dirname,_0x320de1(0x4a5)),SCREENSHOTS_DIR=path['join'](__dirname,_0x320de1(0x1e6));let currentRecording=null,isRecording=![],isReplaying=![],replayAborted=![];async function startUIAutomator2Session(_0x2d4dbf,_0x2e536a){const _0x2e1c10=_0x320de1,_0x4c5afd={'rAHWC':function(_0x2895d2,_0x4a212f){return _0x2895d2===_0x4a212f;},'hnzOx':_0x2e1c10(0x42b),'ziOsm':_0x2e1c10(0x6f2),'yZxmV':_0x2e1c10(0x535),'ChCQY':_0x2e1c10(0x75e),'MNpTi':'instrument','KlZeX':_0x2e1c10(0x497),'ETHyn':function(_0x492493,_0x3d064b){return _0x492493(_0x3d064b);},'erZmz':_0x2e1c10(0x124),'PuEHt':_0x2e1c10(0x206),'aFFmq':'UiAutomator2','bUEFR':_0x2e1c10(0x1ef),'XpYAZ':_0x2e1c10(0x438),'FYglL':_0x2e1c10(0x20b)};console[_0x2e1c10(0x49e)](_0x2e1c10(0x1c8)+_0x2e536a+'\x20('+_0x2d4dbf+_0x2e1c10(0x6b4));try{if(_0x4c5afd['rAHWC'](_0x2e1c10(0x42b),_0x4c5afd[_0x2e1c10(0x19f)])){let _0x1fb2f4=0x2008;while(!![]){if(_0x2e1c10(0x331)!==_0x4c5afd['ziOsm'])try{const _0x2a86ea={};_0x2a86ea[_0x2e1c10(0x33b)]=_0x4c5afd[_0x2e1c10(0x60d)],execSync(_0x2e1c10(0x257)+_0x1fb2f4,_0x2a86ea),_0x1fb2f4++;}catch{break;}else{const _0x267c72={};_0x267c72[_0x2e1c10(0x66c)]=![],_0x267c72[_0x2e1c10(0x644)]=_0x2f1bc0['message'],_0x5bb900[_0x2e1c10(0x365)](0x1f4)[_0x2e1c10(0x169)](_0x267c72);}}console['log'](_0x2e1c10(0x2a4)+_0x1fb2f4+_0x2e1c10(0x1d6)+_0x2e536a);const _0x2888b3=spawn(_0x2e1c10(0x42e),['-s',_0x2d4dbf,_0x4c5afd[_0x2e1c10(0x314)],'am',_0x4c5afd[_0x2e1c10(0x3a0)],'-w',_0x4c5afd['KlZeX']],{'detached':!![],'stdio':_0x4c5afd['yZxmV']});_0x2888b3['unref'](),await new Promise(_0x498cbb=>setTimeout(_0x498cbb,0x7d0)),_0x4c5afd[_0x2e1c10(0x2a3)](execSync,'adb\x20-s\x20'+_0x2d4dbf+_0x2e1c10(0x6be)+_0x1fb2f4+_0x2e1c10(0x34e)),await new Promise(_0x3dde1e=>setTimeout(_0x3dde1e,0x7d0));const _0x138eba=_0x4c5afd['ETHyn'](require,_0x4c5afd[_0x2e1c10(0x2ba)]),_0x1aa5ce={};_0x1aa5ce[_0x2e1c10(0x6ad)]=_0x4c5afd[_0x2e1c10(0x248)],_0x1aa5ce['appium:automationName']=_0x4c5afd[_0x2e1c10(0x473)],_0x1aa5ce['appium:udid']=_0x2d4dbf;const _0x493067={};_0x493067[_0x2e1c10(0x64a)]=_0x1aa5ce;const _0x44af35={};_0x44af35[_0x2e1c10(0x638)]=_0x493067;const _0x23b8a3=await _0x138eba[_0x2e1c10(0x70f)](_0x2e1c10(0x765)+_0x1fb2f4+_0x2e1c10(0x6f3),_0x44af35),_0x4d81c4=_0x23b8a3['data'][_0x2e1c10(0x527)][_0x2e1c10(0x143)]||_0x23b8a3[_0x2e1c10(0x760)]['sessionId'],_0x184285={};_0x184285[_0x2e1c10(0x143)]=_0x4d81c4,_0x184285['port']=_0x1fb2f4,_0x184285[_0x2e1c10(0x472)]=_0x2888b3[_0x2e1c10(0x519)],_0x184285[_0x2e1c10(0x2ef)]=_0x2e536a,androidSessions[_0x2e1c10(0x2db)](_0x2d4dbf,_0x184285);try{let _0x4af07c='';try{_0x4af07c=await fs[_0x2e1c10(0x5e8)](SESSION_MAP_FILE,_0x4c5afd[_0x2e1c10(0x478)]);}catch(_0xd0e9e){}const _0x238c8b=_0x4af07c['split']('\x0a')[_0x2e1c10(0x47e)](_0x3365f3=>_0x3365f3&&!_0x3365f3[_0x2e1c10(0x59e)](_0x2d4dbf+':'));_0x238c8b[_0x2e1c10(0x507)](_0x2d4dbf+':'+_0x4d81c4+':'+_0x1fb2f4),await fs['writeFile'](SESSION_MAP_FILE,_0x238c8b[_0x2e1c10(0x4dd)]('\x0a')+'\x0a'),console[_0x2e1c10(0x49e)](_0x2e1c10(0x52d)+_0x2d4dbf+':'+_0x4d81c4+':'+_0x1fb2f4);}catch(_0x2f9842){if(_0x4c5afd[_0x2e1c10(0x72d)]!==_0x4c5afd[_0x2e1c10(0x160)])console['error']('⚠️\x20\x20Failed\x20to\x20update\x20session\x20file:\x20'+_0x2f9842[_0x2e1c10(0x4f1)]);else{const _0x490829={};_0x490829[_0x2e1c10(0x66c)]=![],_0x490829['error']=_0x4f5b36['message'],_0x5edea5['status'](0x1f4)[_0x2e1c10(0x169)](_0x490829);}}console[_0x2e1c10(0x49e)](_0x2e1c10(0x144)+_0x2e536a),console[_0x2e1c10(0x49e)](_0x2e1c10(0x3ef)+_0x4d81c4),console[_0x2e1c10(0x49e)]('\x20\x20\x20Port:\x20'+_0x1fb2f4);const _0x287b09={};return _0x287b09['success']=!![],_0x287b09[_0x2e1c10(0x143)]=_0x4d81c4,_0x287b09[_0x2e1c10(0x2cf)]=_0x1fb2f4,_0x287b09;}else _0x400509+=_0x2e1c10(0x1e9)+_0x39b708+'\x0a';}catch(_0xcdacd2){console['error']('❌\x20Failed\x20to\x20start\x20UIAutomator2\x20for\x20'+_0x2e536a+':',_0xcdacd2[_0x2e1c10(0x4f1)]);const _0x35d085={};return _0x35d085[_0x2e1c10(0x66c)]=![],_0x35d085['error']=_0xcdacd2[_0x2e1c10(0x4f1)],_0x35d085;}}async function stopUIAutomator2Session(_0x1b838d,_0x19ab61){const _0x5b3994=_0x320de1,_0x70f160={'aRGlS':function(_0x29c720,_0x1e98f6){return _0x29c720(_0x1e98f6);},'BaAEX':'No\x20active\x20session','sQbAE':function(_0x1beb31,_0x324410){return _0x1beb31(_0x324410);},'qxryf':_0x5b3994(0x124),'GvECv':function(_0x29637a,_0x2a3c85){return _0x29637a(_0x2a3c85);},'mbikn':_0x5b3994(0x2f9),'UBMGl':_0x5b3994(0x757),'iddvC':_0x5b3994(0x6ff)};console['log'](_0x5b3994(0x58f)+_0x19ab61+'\x20('+_0x1b838d+_0x5b3994(0x6b4));try{const _0x3f91a5=androidSessions['get'](_0x1b838d);if(!_0x3f91a5){console[_0x5b3994(0x49e)]('⚠️\x20\x20No\x20active\x20session\x20found\x20for\x20'+_0x19ab61);const _0x557ba3={};return _0x557ba3[_0x5b3994(0x66c)]=!![],_0x557ba3['message']=_0x70f160[_0x5b3994(0x399)],_0x557ba3;}try{const _0x23c2e5=_0x70f160[_0x5b3994(0x748)](require,_0x70f160['qxryf']);await _0x23c2e5[_0x5b3994(0x4fe)](_0x5b3994(0x765)+_0x3f91a5[_0x5b3994(0x2cf)]+_0x5b3994(0x573)+_0x3f91a5[_0x5b3994(0x143)]),console[_0x5b3994(0x49e)](_0x5b3994(0x6f4)+_0x19ab61);}catch(_0x7f90ac){console['log'](_0x5b3994(0x4ac)+_0x7f90ac['message']);}try{_0x70f160[_0x5b3994(0x52e)](execSync,_0x5b3994(0x600)+_0x1b838d+_0x5b3994(0x276)+_0x3f91a5['port']),console[_0x5b3994(0x49e)](_0x5b3994(0x11b)+_0x19ab61);}catch(_0x5b6f90){console[_0x5b3994(0x49e)]('⚠️\x20\x20Could\x20not\x20remove\x20port\x20forwarding:\x20'+_0x5b6f90[_0x5b3994(0x4f1)]);}try{_0x70f160[_0x5b3994(0x540)](execSync,'adb\x20-s\x20'+_0x1b838d+_0x5b3994(0x3f6)),execSync('adb\x20-s\x20'+_0x1b838d+_0x5b3994(0x232)),console['log']('✅\x20UIAutomator2\x20server\x20stopped\x20on\x20'+_0x19ab61);}catch(_0x4e73f3){if(_0x70f160['mbikn']!==_0x5b3994(0x6f6))console[_0x5b3994(0x49e)](_0x5b3994(0x3d7)+_0x4e73f3[_0x5b3994(0x4f1)]);else{_0x45edc2[_0x5b3994(0x644)](_0x5b3994(0x112)+_0x8c95a6+':',_0x22cbdb);const _0x1a5b16={};_0x1a5b16['success']=![],_0x70f160[_0x5b3994(0x540)](_0x73059e,_0x1a5b16);}}androidSessions['delete'](_0x1b838d);try{if(_0x70f160['UBMGl']===_0x70f160['UBMGl']){const _0x311185=await fs[_0x5b3994(0x5e8)](SESSION_MAP_FILE,'utf-8'),_0x17f1ca=_0x311185[_0x5b3994(0x722)]('\x0a')['filter'](_0x17bcca=>!_0x17bcca[_0x5b3994(0x59e)](_0x1b838d+':'));await fs[_0x5b3994(0x184)](SESSION_MAP_FILE,_0x17f1ca[_0x5b3994(0x4dd)]('\x0a')),console[_0x5b3994(0x49e)](_0x5b3994(0x617)+_0x19ab61);}else _0x5e5ab3[_0x5b3994(0x143)]=_0x519200[_0x5b3994(0x143)];}catch(_0x1832de){console[_0x5b3994(0x49e)](_0x5b3994(0x4de)+_0x1832de[_0x5b3994(0x4f1)]);}console['log'](_0x5b3994(0x586)+_0x19ab61);const _0xfde7d1={};return _0xfde7d1['success']=!![],_0xfde7d1;}catch(_0xcf1db4){if(_0x70f160[_0x5b3994(0x39a)]!=='uLxwt')_0x388dfd=_0x4879e6[_0x5b3994(0xf7)][_0x5b3994(0x722)]('\x0a')[_0x5b3994(0x47e)](_0x1d2304=>_0x1d2304[_0x5b3994(0x5cf)]());else{console[_0x5b3994(0x644)](_0x5b3994(0x3b4)+_0x19ab61+':',_0xcf1db4[_0x5b3994(0x4f1)]);const _0x2167c1={};return _0x2167c1[_0x5b3994(0x66c)]=![],_0x2167c1['error']=_0xcf1db4[_0x5b3994(0x4f1)],_0x2167c1;}}}async function loadDeviceConfig(){const _0x207338=_0x320de1,_0xc82cf8={'ejGxX':_0x207338(0x4d4),'OgqrE':function(_0x569457,_0x2d0c82,_0x5d7839,_0x330832){return _0x569457(_0x2d0c82,_0x5d7839,_0x330832);},'AEfOA':function(_0x50a98e,_0x4a9e50){return _0x50a98e===_0x4a9e50;},'Motik':_0x207338(0x491),'plniR':_0x207338(0x148),'njNsE':_0x207338(0x3b7),'nEOoJ':function(_0x194d5e,_0x1ee736){return _0x194d5e!==_0x1ee736;},'XWtto':_0x207338(0x321),'eaYGK':'zrToN','KkVCP':'android','emKJU':function(_0x2490d6,_0x151b87){return _0x2490d6<_0x151b87;},'oaUmU':_0x207338(0x342),'sPibr':function(_0x3f360e,_0x129db4){return _0x3f360e>_0x129db4;},'ELGyA':function(_0x59a87e,_0x2004c6){return _0x59a87e||_0x2004c6;},'QyfPs':_0x207338(0x4a0),'vDZdW':'usb','MphMa':function(_0x65e31a,_0x1c25d3){return _0x65e31a===_0x1c25d3;},'djmOH':_0x207338(0x21f),'dgYEK':_0x207338(0x35c),'etXlv':_0x207338(0x1ef),'nENFG':_0x207338(0x6c7)};try{if(_0xc82cf8[_0x207338(0x2f5)](_0xc82cf8['djmOH'],_0xc82cf8[_0x207338(0x61a)]))return _0x7c0147[_0x207338(0x49e)]('\x20\x20📱\x20Resolved\x20app\x20preset:\x20\x22'+_0x5c9596+_0x207338(0x4d6)+_0x2375ab+_0x207338(0x714)+_0x568b88+')'),_0x207338(0x46e)+_0x1a7e3d+_0x31da3a;else{const _0x1d6245=await fs['readFile'](DEVICE_CONFIG,_0xc82cf8[_0x207338(0x4eb)]),_0x522e74=_0x1d6245[_0x207338(0x722)]('\x0a')[_0x207338(0x47e)](_0x4d1e8c=>_0x4d1e8c[_0x207338(0x5cf)]()&&!_0x4d1e8c[_0x207338(0x59e)]('#'))[_0x207338(0x240)](_0x31f342=>{const _0x22fb13=_0x207338,_0x1e86ed={'BDyQk':function(_0x268095,_0x88f9f9){return _0xc82cf8['AEfOA'](_0x268095,_0x88f9f9);},'wUCQT':_0xc82cf8[_0x22fb13(0x121)]};if(_0xc82cf8['plniR']===_0xc82cf8[_0x22fb13(0x250)]){const _0x235ac6=_0x31f342[_0x22fb13(0x722)](',')['map'](_0x4ab227=>_0x4ab227[_0x22fb13(0x5cf)]()),[_0x3408af,_0x294f83,_0x4a9e6a,_0x403661,_0x2da9b5]=_0x235ac6;let _0x44f93f=_0x403661||_0xc82cf8[_0x22fb13(0x630)];if(!_0x403661&&_0x294f83){if(_0xc82cf8[_0x22fb13(0x6af)](_0xc82cf8[_0x22fb13(0x53c)],_0x22fb13(0x262))){if(_0x294f83[_0x22fb13(0x58b)](':')&&_0x294f83[_0x22fb13(0x65a)](/^\d+\.\d+\.\d+\.\d+:\d+$/)){if(_0xc82cf8[_0x22fb13(0x4d1)]!==_0x22fb13(0xfd)){if(_0x1e86ed[_0x22fb13(0x252)](_0x65f006[_0x22fb13(0x4aa)],_0x5ad280[_0x22fb13(0x717)])){const _0x3e600c={};_0x3e600c['type']=_0x22fb13(0x230),_0x3e600c[_0x22fb13(0x1a6)]=_0x1db8fe,_0x4042a1[_0x22fb13(0x475)](_0x37fdde[_0x22fb13(0x2a5)](_0x3e600c));}}else _0x44f93f=_0xc82cf8[_0x22fb13(0x72c)];}else{if(_0xc82cf8[_0x22fb13(0x137)](_0x294f83[_0x22fb13(0x162)],0x14)&&!_0x294f83[_0x22fb13(0x58b)]('-')){if(_0xc82cf8[_0x22fb13(0x6d1)]===_0xc82cf8['oaUmU'])_0x44f93f=_0xc82cf8[_0x22fb13(0x72c)];else{const _0x5c1749={};_0x5c1749[_0x22fb13(0x6f9)]=_0xc82cf8[_0x22fb13(0x46d)];const _0x45267d=_0x5c1749;_0xc82cf8[_0x22fb13(0x3d9)](_0x52b841,_0x20e775,_0x2cfb1d,_0x10a123)[_0x22fb13(0x4cb)](_0x307248=>{const _0x54e476=_0x22fb13;_0x3139a8['log'](_0x54e476(0x424));const _0x35a6ab={};_0x35a6ab['type']=_0x45267d[_0x54e476(0x6f9)],_0x35a6ab[_0x54e476(0x34f)]=_0x307248,_0x8c825d[_0x54e476(0x475)](_0x14bda3[_0x54e476(0x2a5)](_0x35a6ab));})[_0x22fb13(0x153)](_0x1ac5ba=>{const _0x5c5f7d=_0x22fb13;_0x30c5e1[_0x5c5f7d(0x644)](_0x5c5f7d(0x625)+_0x1ac5ba[_0x5c5f7d(0x4f1)]);const _0x2f9ab1={};_0x2f9ab1[_0x5c5f7d(0x14d)]=_0x1e86ed[_0x5c5f7d(0x547)],_0x2f9ab1[_0x5c5f7d(0x644)]=_0x1ac5ba['message'],_0x522468[_0x5c5f7d(0x475)](_0x32501c['stringify'](_0x2f9ab1));});}}else _0x294f83[_0x22fb13(0x58b)]('-')&&_0xc82cf8[_0x22fb13(0x631)](_0x294f83[_0x22fb13(0x162)],0x1e)&&(_0x44f93f=_0xc82cf8['njNsE']);}}else{const _0x15ec8a={};_0x15ec8a[_0x22fb13(0x66c)]=![],_0x15ec8a[_0x22fb13(0x644)]=_0x1f55f8['message'],_0x34db40[_0x22fb13(0x365)](0x1f4)['json'](_0x15ec8a);}}return{'name':_0x3408af,'udid':_0x294f83,'ip':_0xc82cf8['ELGyA'](_0x4a9e6a,''),'platform':_0x44f93f,'type':_0x2da9b5||(_0x4a9e6a?_0xc82cf8[_0x22fb13(0x390)]:_0xc82cf8[_0x22fb13(0x383)]),'status':_0x22fb13(0x2a1)};}else _0x2e750e+=_0x3d16d2[_0x22fb13(0x4e4)]();});return _0x522e74;}}catch(_0xff778a){return console['error'](_0xc82cf8[_0x207338(0xd3)],_0xff778a),[];}}async function discoverDevices(){const _0x5e3d15=_0x320de1,_0x7144f5={'kNWuE':function(_0x59e7d9,_0x346771){return _0x59e7d9===_0x346771;},'MVbVF':_0x5e3d15(0x4e6),'tdgqQ':function(_0x920f90,_0x2abe10){return _0x920f90(_0x2abe10);}},_0x1dafe6=new Map();return connectedDevices[_0x5e3d15(0x11d)](_0x19a476=>{const _0x33f7ef=_0x5e3d15;_0x1dafe6[_0x33f7ef(0x2db)](_0x19a476[_0x33f7ef(0x23d)],{'status':_0x19a476[_0x33f7ef(0x365)],'sessionId':_0x19a476[_0x33f7ef(0x143)]});}),connectedDevices=await discoverAllDevices(),connectedDevices[_0x5e3d15(0x11d)](_0x329230=>{const _0x4eb5d8=_0x5e3d15,_0x671b41=_0x1dafe6[_0x4eb5d8(0x5af)](_0x329230[_0x4eb5d8(0x23d)]);_0x671b41&&_0x7144f5[_0x4eb5d8(0x25e)](_0x671b41[_0x4eb5d8(0x365)],'online')&&(_0x329230['status']=_0x7144f5[_0x4eb5d8(0x574)],_0x671b41['sessionId']&&(_0x329230[_0x4eb5d8(0x143)]=_0x671b41['sessionId']));}),await _0x7144f5[_0x5e3d15(0x572)](autoSaveUSBDevicesToConfig,connectedDevices),connectedDevices;}async function autoSaveUSBDevicesToConfig(_0x4c8bce){const _0x4fe0f0=_0x320de1,_0x28bd63={'cNYmP':function(_0xe6063){return _0xe6063();},'aBPQk':_0x4fe0f0(0x755),'kWeRx':_0x4fe0f0(0x39e),'guyLJ':'#\x20USB\x20devices\x20auto-detected.\x20Add\x20IP\x20for\x20wireless\x20connection.\x0a\x0a','oJVrI':_0x4fe0f0(0x727)};try{const _0x131b7f=_0x4c8bce['filter'](_0x3789d2=>_0x3789d2['connectionType']==='usb');if(_0x131b7f[_0x4fe0f0(0x162)]===0x0)return;const _0x5dd250=await _0x28bd63[_0x4fe0f0(0x17a)](loadDeviceConfig),_0x290856=new Set(_0x5dd250[_0x4fe0f0(0x240)](_0x13da95=>_0x13da95['udid'])),_0x5995f4=_0x131b7f[_0x4fe0f0(0x47e)](_0x4e9b74=>!_0x290856['has'](_0x4e9b74[_0x4fe0f0(0x23d)]));if(_0x5995f4[_0x4fe0f0(0x162)]===0x0)return;const _0x3c66b7=[..._0x5dd250,..._0x5995f4[_0x4fe0f0(0x240)](_0x1a65ab=>({'name':_0x1a65ab[_0x4fe0f0(0x4b8)],'udid':_0x1a65ab['udid'],'ip':''}))];let _0x314fd8=_0x28bd63['aBPQk'];_0x314fd8+=_0x28bd63[_0x4fe0f0(0x5c2)],_0x314fd8+=_0x28bd63[_0x4fe0f0(0x432)],_0x3c66b7['forEach'](_0x2e07ff=>{const _0x379925=_0x4fe0f0,_0x2b3600=_0x2e07ff['ip']||'';_0x314fd8+=_0x2e07ff[_0x379925(0x4b8)]+','+_0x2e07ff[_0x379925(0x23d)]+','+_0x2b3600+'\x0a';}),await fs[_0x4fe0f0(0x184)](DEVICE_CONFIG,_0x314fd8),console[_0x4fe0f0(0x49e)](_0x4fe0f0(0x16b)+_0x5995f4[_0x4fe0f0(0x162)]+_0x4fe0f0(0x6b0));}catch(_0x33efbe){console[_0x4fe0f0(0x644)](_0x28bd63['oJVrI'],_0x33efbe);}}function checkDeviceConnectivity(_0x139c61){const _0x341d02=_0x320de1,_0x2d644d={'hduTh':function(_0x1d31e5,_0x457a11){return _0x1d31e5(_0x457a11);},'zhdrX':_0x341d02(0x24e),'NMOZB':function(_0x19ada8,_0x356d1a){return _0x19ada8!==_0x356d1a;},'cckcv':'alDmJ','sNrMa':_0x341d02(0x761),'Fnlhc':'--connect-timeout','UHmmS':_0x341d02(0x4e1),'nCZMT':_0x341d02(0x760),'ehAOk':function(_0x63dce1,_0x1bdfbb,_0x4b59e5){return _0x63dce1(_0x1bdfbb,_0x4b59e5);}};return new Promise(_0x1e5c7c=>{const _0x202066=_0x341d02,_0x28c89c={'YORbc':function(_0x481954,_0x169cc1){return _0x2d644d['NMOZB'](_0x481954,_0x169cc1);},'gVebd':_0x2d644d[_0x202066(0x665)],'ICOKK':function(_0x416028,_0x5a5647){return _0x416028(_0x5a5647);}},_0x13615c=spawn(_0x2d644d[_0x202066(0x4d3)],['-s',_0x2d644d[_0x202066(0x650)],'2',_0x2d644d['UHmmS'],'3',_0x202066(0x3de)+_0x139c61['ip']+_0x202066(0x2d4)]);let _0x364144='';_0x13615c['stdout']['on'](_0x2d644d['nCZMT'],_0x34b4e1=>{const _0x12a7a0=_0x202066;if(_0x28c89c['YORbc']('CcZqu',_0x28c89c[_0x12a7a0(0x68f)]))_0x364144+=_0x34b4e1[_0x12a7a0(0x4e4)]();else{_0x16237a[_0x12a7a0(0x644)](_0x12a7a0(0x106),_0x51c086);const _0xf6b42d={};_0xf6b42d[_0x12a7a0(0x66c)]=![],_0xf6b42d['error']=_0x198e45[_0x12a7a0(0x4f1)],_0xa278c3[_0x12a7a0(0x365)](0x1f4)['json'](_0xf6b42d);}}),_0x13615c['on'](_0x202066(0x4f6),_0x5044ec=>{const _0x57cd79=_0x202066;_0x2d644d['hduTh'](_0x1e5c7c,_0x364144[_0x57cd79(0x58b)](_0x2d644d[_0x57cd79(0x65b)]));}),_0x2d644d[_0x202066(0x5ea)](setTimeout,()=>{const _0x59c96c=_0x202066;_0x13615c['kill'](),_0x28c89c[_0x59c96c(0x4dc)](_0x1e5c7c,![]);},0xbb8);});}function loadAppPresets(){const _0x3ab254=_0x320de1,_0x5da56c={'qOAPU':function(_0x129f52,_0x537d4f){return _0x129f52===_0x537d4f;},'KOopq':_0x3ab254(0x669),'FISAF':function(_0xdf9ada,_0x1d7100){return _0xdf9ada&&_0x1d7100;},'CvtUR':function(_0x321b72,_0x2fafcf){return _0x321b72===_0x2fafcf;},'CaFcc':_0x3ab254(0x1ec),'eGqAn':function(_0x23b033,_0x6b332a){return _0x23b033(_0x6b332a);},'oiVku':_0x3ab254(0x1ef),'qMrHE':'rqkUi'};try{if(!_0x5da56c[_0x3ab254(0x11e)](require,'fs')[_0x3ab254(0x19a)](APPS_CONFIG))return{};const _0x409cab=_0x5da56c['eGqAn'](require,'fs')[_0x3ab254(0x3be)](APPS_CONFIG,_0x5da56c[_0x3ab254(0x6a7)]),_0x336bd4={};return _0x409cab[_0x3ab254(0x722)]('\x0a')[_0x3ab254(0x47e)](_0x190aaa=>_0x190aaa[_0x3ab254(0x5cf)]()&&!_0x190aaa[_0x3ab254(0x59e)]('#'))[_0x3ab254(0x11d)](_0x4d89c6=>{const _0x27f8c4=_0x3ab254;if(_0x5da56c[_0x27f8c4(0x651)](_0x5da56c['KOopq'],_0x27f8c4(0x669))){const [_0x47ec22,_0x4d5d0a]=_0x4d89c6[_0x27f8c4(0x722)](',')[_0x27f8c4(0x240)](_0x592553=>_0x592553[_0x27f8c4(0x5cf)]());if(_0x5da56c['FISAF'](_0x47ec22,_0x4d5d0a)){const _0x437990=_0x47ec22[_0x27f8c4(0x722)]('.');if(_0x5da56c[_0x27f8c4(0x360)](_0x437990[_0x27f8c4(0x162)],0x2)){const [_0x1b7b27,_0x395517]=_0x437990;if(!_0x336bd4[_0x1b7b27])_0x336bd4[_0x1b7b27]={};_0x336bd4[_0x1b7b27][_0x395517]=_0x4d5d0a;}else{if(!_0x336bd4[_0x47ec22])_0x336bd4[_0x47ec22]={};_0x336bd4[_0x47ec22][_0x27f8c4(0x372)]=_0x4d5d0a;}}}else _0x4e1b76[_0x27f8c4(0x644)](_0x27f8c4(0x178)+_0x1160c9+':\x20'+_0x192d24[_0x27f8c4(0x4f1)]);}),_0x336bd4;}catch(_0x3255a7){if(_0x3ab254(0x40a)===_0x5da56c[_0x3ab254(0x326)])return console[_0x3ab254(0x644)](_0x3ab254(0x12f),_0x3255a7),{};else{if(_0x5da56c[_0x3ab254(0x651)](_0x25df22['readyState'],_0x143289[_0x3ab254(0x717)])){const _0x4fa657={};_0x4fa657[_0x3ab254(0x14d)]='devices_updated',_0x4fa657[_0x3ab254(0x1a6)]=_0x262941,_0x5d3b39[_0x3ab254(0x475)](_0x5a23e0[_0x3ab254(0x2a5)](_0x4fa657)),_0x3d20f6[_0x3ab254(0x475)](_0x529f12[_0x3ab254(0x2a5)]({'type':_0x5da56c[_0x3ab254(0x5e9)],'output':'✅\x20'+_0x373381+'\x20connected\x20-\x20WDA\x20Ready!\x0a'+'─'[_0x3ab254(0x5fb)](0x32)+'\x0a','device':_0x288687}));}}}}function resolveAppPreset(_0x2bc204,_0x3dd65f){const _0x1543b5=_0x320de1,_0x58e7d5={'EnzKY':_0x1543b5(0x230),'OXzVp':function(_0x146b79){return _0x146b79();},'ckosA':_0x1543b5(0x4e9),'XDKhS':_0x1543b5(0x550)},_0x123ce4=_0x58e7d5['OXzVp'](loadAppPresets),_0x3891be=_0x2bc204[_0x1543b5(0x65a)](/^launch\s+(\S+)(.*)$/);if(!_0x3891be)return _0x2bc204;const _0x204c95=_0x3891be[0x1],_0xb82981=_0x3891be[0x2];if(_0x204c95[_0x1543b5(0x58b)]('.'))return _0x2bc204;if(_0x123ce4[_0x204c95]){if(_0x1543b5(0x6e5)!==_0x58e7d5[_0x1543b5(0x37b)]){const _0x1a2392=_0x123ce4[_0x204c95];let _0xc0af07;if(_0x1a2392[_0x3dd65f])_0xc0af07=_0x1a2392[_0x3dd65f];else _0x1a2392[_0x1543b5(0x372)]&&(_0xc0af07=_0x1a2392[_0x1543b5(0x372)]);if(_0xc0af07){if(_0x58e7d5['XDKhS']===_0x58e7d5[_0x1543b5(0x4ce)])return console[_0x1543b5(0x49e)]('\x20\x20📱\x20Resolved\x20app\x20preset:\x20\x22'+_0x204c95+_0x1543b5(0x4d6)+_0xc0af07+'\x22\x20('+_0x3dd65f+')'),_0x1543b5(0x46e)+_0xc0af07+_0xb82981;else _0x984cf9+=_0x1543b5(0x444)+_0x5e3158+'\x0a';}}else{if(_0x2aa574['readyState']===_0x4d28e9[_0x1543b5(0x717)]){const _0x374eb4={};_0x374eb4['type']=_0x58e7d5[_0x1543b5(0x629)],_0x374eb4[_0x1543b5(0x1a6)]=_0x9a3c27,_0xae86a7[_0x1543b5(0x475)](_0x1de4f1[_0x1543b5(0x2a5)](_0x374eb4));}}}return _0x2bc204;}function executeCommand(_0x2d75b0,_0x3b7c73,_0x2ae6d5){const _0x3c9f49=_0x320de1,_0x1d64ef={'hkgJl':function(_0x4dc206,_0xcdb39d){return _0x4dc206===_0xcdb39d;},'SAlnP':_0x3c9f49(0x4e6),'uOcVb':function(_0x40f2c8,_0x13b865){return _0x40f2c8===_0x13b865;},'WIDfB':_0x3c9f49(0x5b5),'eLlQa':function(_0x5ea34d,_0xbc0a1){return _0x5ea34d(_0xbc0a1);},'yMvjV':'No\x20devices\x20found.\x20Please\x20refresh\x20device\x20list\x20and\x20try\x20again.','RSMqm':function(_0x2ff938,_0x2c8acb){return _0x2ff938>_0x2c8acb;},'qlrjG':_0x3c9f49(0x328),'ZSAdf':_0x3c9f49(0x1ec),'WTJrd':_0x3c9f49(0x17b),'XJAxu':function(_0x587820,_0x5d3300,_0x4f13e4){return _0x587820(_0x5d3300,_0x4f13e4);},'rEsBU':'ios','CwQGO':function(_0x4d53ab,_0x5dbaa4,_0x588aa9,_0x1ade84,_0x41b046){return _0x4d53ab(_0x5dbaa4,_0x588aa9,_0x1ade84,_0x41b046);},'QhZpH':function(_0x318966,_0x2c1dae){return _0x318966>_0x2c1dae;},'hlPlt':function(_0x469ab7,_0x386ec0){return _0x469ab7===_0x386ec0;},'PJcUR':'BTZPO','YBrfG':function(_0x231bb7,_0x45eb14){return _0x231bb7(_0x45eb14);},'lvBEl':function(_0xd4c16b,_0x58f7ed){return _0xd4c16b(_0x58f7ed);},'WAHiO':'Script\x20execution\x20error:','EYYqw':function(_0x4b9b82,_0x2197ed){return _0x4b9b82(_0x2197ed);}};return new Promise(async(_0x2925cd,_0x286c9b)=>{const _0x12aa6d=_0x3c9f49;logger[_0x12aa6d(0x3d0)](_0x12aa6d(0x155)+_0x2d75b0[_0x12aa6d(0x4dd)](',\x20')+']'),console[_0x12aa6d(0x49e)]('Command:\x20\x22'+_0x3b7c73+'\x22');const _0x43d2eb=connectedDevices[_0x12aa6d(0x47e)](_0x1dd1dd=>_0x2d75b0[_0x12aa6d(0x58b)](_0x1dd1dd[_0x12aa6d(0x4b8)])||_0x2d75b0[_0x12aa6d(0x58b)](_0x1dd1dd['udid'])||_0x2d75b0[_0x12aa6d(0x58b)](_0x1dd1dd[_0x12aa6d(0x54d)]));logger['debug']('Cache\x20contents:',connectedDevices[_0x12aa6d(0x240)](_0x4d5bb7=>_0x4d5bb7[_0x12aa6d(0x4b8)]+'('+_0x4d5bb7[_0x12aa6d(0x365)]+')')[_0x12aa6d(0x4dd)](',\x20'));if(_0x1d64ef[_0x12aa6d(0x558)](_0x43d2eb[_0x12aa6d(0x162)],0x0)){if(_0x1d64ef[_0x12aa6d(0x568)]==='obhyX')return console[_0x12aa6d(0x644)](_0x12aa6d(0x635)+_0x2d75b0[_0x12aa6d(0x4dd)](',\x20')+']'),_0x1d64ef[_0x12aa6d(0x34d)](_0x286c9b,{'success':![],'error':_0x1d64ef[_0x12aa6d(0x381)]});else _0x139090[_0x12aa6d(0x49e)]('\x0a📱\x20Please\x20open\x20'+_0x48c5a4+_0x12aa6d(0x69e));}const _0x119d60=_0x43d2eb[_0x12aa6d(0x47e)](_0x4e4b17=>![_0x12aa6d(0x4e6),'connected']['includes'](_0x4e4b17['status']));if(_0x1d64ef['RSMqm'](_0x119d60[_0x12aa6d(0x162)],0x0)){if(_0x1d64ef[_0x12aa6d(0x1a1)](_0x1d64ef[_0x12aa6d(0x6a5)],'VUMfK')){const _0x49fd36=_0x119d60[_0x12aa6d(0x240)](_0x1baf30=>_0x1baf30['name']+'\x20(status:\x20'+_0x1baf30[_0x12aa6d(0x365)]+')')[_0x12aa6d(0x4dd)](',\x20');console[_0x12aa6d(0x644)]('❌\x20Devices\x20not\x20connected:\x20['+_0x49fd36+']');if(_0x2ae6d5){const _0x884590={};_0x884590[_0x12aa6d(0x14d)]=_0x1d64ef[_0x12aa6d(0x6bd)],_0x884590['data']='\x0a⚠️\x20\x20Error:\x20Devices\x20not\x20connected:\x20'+_0x49fd36+'\x0a\x0a💡\x20Please\x20click\x20the\x20\x22Connect\x22\x20button\x20on\x20each\x20device\x20before\x20running\x20commands.\x0a\x0a',_0x884590[_0x12aa6d(0x1a6)]=_0x2d75b0,_0x2ae6d5['send'](JSON[_0x12aa6d(0x2a5)](_0x884590));}const _0x59060e={};return _0x59060e[_0x12aa6d(0x66c)]=![],_0x59060e['error']=_0x12aa6d(0x56e)+_0x49fd36+'.\x20Please\x20click\x20\x22Connect\x22\x20button\x20on\x20each\x20device\x20first.',_0x1d64ef[_0x12aa6d(0x34d)](_0x286c9b,_0x59060e);}else{const _0x230130={'eQWut':function(_0x2a7fae,_0x5f0587){const _0x32c919=_0x12aa6d;return _0x1d64ef[_0x32c919(0x1a1)](_0x2a7fae,_0x5f0587);}};_0x3df139[_0x3a1a20][_0x12aa6d(0x365)]=_0x1d64ef[_0x12aa6d(0x58a)],_0x20d0a5[_0x12aa6d(0x374)][_0x12aa6d(0x11d)](_0x22e425=>{const _0x414797=_0x12aa6d;if(_0x230130[_0x414797(0x2ab)](_0x22e425[_0x414797(0x4aa)],_0x36b893[_0x414797(0x717)])){const _0x53e372={};_0x53e372[_0x414797(0x14d)]=_0x414797(0x230),_0x53e372[_0x414797(0x1a6)]=_0x19a46f,_0x22e425[_0x414797(0x475)](_0x2e3277[_0x414797(0x2a5)](_0x53e372));}});}}console['log'](_0x12aa6d(0x649)+_0x43d2eb[_0x12aa6d(0x162)]+_0x12aa6d(0x668)),console[_0x12aa6d(0x49e)](_0x1d64ef['WTJrd'],_0x43d2eb['map'](_0x4516c2=>_0x4516c2[_0x12aa6d(0x4b8)]+'('+_0x4516c2[_0x12aa6d(0x5d6)]+'-'+_0x4516c2[_0x12aa6d(0x762)]+')')[_0x12aa6d(0x4dd)](',\x20'));const _0x782215=_0x43d2eb['filter'](_0x4fbc4d=>_0x4fbc4d['platform']===_0x12aa6d(0x3b7)&&_0x4fbc4d[_0x12aa6d(0x762)]==='usb'),_0x200eea=_0x43d2eb['filter'](_0x44b9c3=>_0x44b9c3['platform']===_0x12aa6d(0x3b7)&&_0x44b9c3['connectionType']===_0x12aa6d(0x4a0)),_0x141d8f=_0x43d2eb[_0x12aa6d(0x47e)](_0xc2d5cf=>_0xc2d5cf[_0x12aa6d(0x5d6)]===_0x12aa6d(0x5a0)&&_0xc2d5cf[_0x12aa6d(0x762)]===_0x12aa6d(0x57d)),_0x5a7e99=_0x43d2eb[_0x12aa6d(0x47e)](_0x5f1266=>_0x5f1266[_0x12aa6d(0x5d6)]===_0x12aa6d(0x5a0)&&_0x5f1266[_0x12aa6d(0x762)]===_0x12aa6d(0x4a0)),_0x1c7bf6=[];if(_0x1d64ef[_0x12aa6d(0x205)](_0x782215[_0x12aa6d(0x162)],0x0)){const _0x25f7a5=_0x782215[_0x12aa6d(0x240)](_0x1a66e5=>_0x1a66e5[_0x12aa6d(0x4b8)]),_0x32d362=_0x1d64ef[_0x12aa6d(0x6cb)](resolveAppPreset,_0x3b7c73,_0x1d64ef['rEsBU']);logger[_0x12aa6d(0x3d0)](_0x12aa6d(0x308)+_0x25f7a5[_0x12aa6d(0x4dd)](',\x20')),_0x1c7bf6[_0x12aa6d(0x507)](_0x1d64ef[_0x12aa6d(0x733)](executeWithScript,USB_SCRIPT_PATH,_0x25f7a5,_0x32d362,_0x2ae6d5));}if(_0x1d64ef[_0x12aa6d(0x1b0)](_0x200eea['length'],0x0)){const _0x109076=_0x200eea[_0x12aa6d(0x240)](_0x396cc1=>_0x396cc1[_0x12aa6d(0x4b8)]),_0x87ec9e=_0x1d64ef['XJAxu'](resolveAppPreset,_0x3b7c73,_0x1d64ef[_0x12aa6d(0x5e0)]);console[_0x12aa6d(0x49e)]('Using\x20iOS\x20wireless\x20script\x20for:\x20'+_0x109076[_0x12aa6d(0x4dd)](',\x20')),_0x1c7bf6[_0x12aa6d(0x507)](executeWithScript(WIRELESS_SCRIPT_PATH,_0x109076,_0x87ec9e,_0x2ae6d5));}if(_0x141d8f[_0x12aa6d(0x162)]>0x0){const _0x5123e2=resolveAppPreset(_0x3b7c73,_0x12aa6d(0x5a0));logger[_0x12aa6d(0x3d0)](_0x12aa6d(0x335)+_0x141d8f[_0x12aa6d(0x240)](_0x15af3e=>_0x15af3e[_0x12aa6d(0x4b8)])[_0x12aa6d(0x4dd)](',\x20')),_0x1c7bf6[_0x12aa6d(0x507)](executeAndroidDevices(ANDROID_USB_SCRIPT_PATH,_0x141d8f,_0x5123e2,_0x2ae6d5));}if(_0x1d64ef[_0x12aa6d(0x1b0)](_0x5a7e99[_0x12aa6d(0x162)],0x0)){const _0x8de1c1=_0x1d64ef[_0x12aa6d(0x6cb)](resolveAppPreset,_0x3b7c73,_0x12aa6d(0x5a0));logger['debug'](_0x12aa6d(0x5ef)+_0x5a7e99[_0x12aa6d(0x240)](_0x19d86f=>_0x19d86f[_0x12aa6d(0x4b8)])[_0x12aa6d(0x4dd)](',\x20')),_0x1c7bf6[_0x12aa6d(0x507)](_0x1d64ef[_0x12aa6d(0x733)](executeAndroidDevices,ANDROID_WIRELESS_SCRIPT_PATH,_0x5a7e99,_0x8de1c1,_0x2ae6d5));}if(_0x1d64ef['hlPlt'](_0x1c7bf6[_0x12aa6d(0x162)],0x0)){if(_0x1d64ef[_0x12aa6d(0x4e8)]===_0x1d64ef['PJcUR']){const _0x3b2f1a={};return _0x3b2f1a[_0x12aa6d(0x66c)]=![],_0x3b2f1a['error']='No\x20executable\x20devices\x20found',_0x1d64ef['YBrfG'](_0x286c9b,_0x3b2f1a);}else{const _0x20eb79=_0x1350c6['match'](/Label:([^\s]+)/);if(_0x20eb79)_0x3d08a5[_0x12aa6d(0x3a5)]=_0x20eb79[0x1];}}try{const _0x453153=await Promise[_0x12aa6d(0x57e)](_0x1c7bf6),_0x545988=_0x453153[_0x12aa6d(0x47e)](_0x425e9e=>_0x425e9e[_0x12aa6d(0x365)]===_0x12aa6d(0x1e7))[_0x12aa6d(0x162)],_0x52f89e=_0x453153[_0x12aa6d(0x47e)](_0x55475d=>_0x55475d[_0x12aa6d(0x365)]===_0x12aa6d(0x1f2))[_0x12aa6d(0x162)];logger[_0x12aa6d(0x3d0)](_0x12aa6d(0x1c3)+_0x545988+_0x12aa6d(0x30c)+_0x52f89e+_0x12aa6d(0x576));const _0x5490b5={};_0x5490b5[_0x12aa6d(0x66c)]=!![],_0x5490b5[_0x12aa6d(0x3a2)]=_0x453153,_0x5490b5[_0x12aa6d(0x347)]=_0x545988+'/'+_0x1c7bf6['length']+'\x20script\x20groups\x20completed',_0x1d64ef[_0x12aa6d(0x3c1)](_0x2925cd,_0x5490b5);}catch(_0x1d8f48){console[_0x12aa6d(0x644)](_0x1d64ef[_0x12aa6d(0x3fb)],_0x1d8f48),_0x1d64ef['EYYqw'](_0x286c9b,_0x1d8f48);}});}function executeWithScript(_0x47d1f3,_0x153114,_0x4581ee,_0x2119fb){const _0xd9c60f=_0x320de1,_0x1b0c79={'ZSYLB':'CcONs','jVDGh':function(_0x554869,_0x5d12b9){return _0x554869(_0x5d12b9);},'KvoMZ':_0xd9c60f(0x4d4),'UIQvC':function(_0x38721c,_0x4f08e2,_0x1e9e18,_0x1888bf){return _0x38721c(_0x4f08e2,_0x1e9e18,_0x1888bf);},'PXfcq':function(_0x306088,_0x2e0591){return _0x306088===_0x2e0591;},'KJfgs':function(_0x295ff2,_0x4e5c4f){return _0x295ff2(_0x4e5c4f);},'zXuuh':function(_0x58d372,_0x1c9ae9){return _0x58d372+_0x1c9ae9;},'ZjPfc':_0xd9c60f(0x760)};return new Promise((_0xfe4e7d,_0x3a3ca0)=>{const _0x4ef623=_0xd9c60f,_0x8e2ae0={'eDVry':_0x1b0c79[_0x4ef623(0x739)],'IJioz':function(_0x268080,_0x26d0b8,_0x998281,_0x453f9c){const _0x170367=_0x4ef623;return _0x1b0c79[_0x170367(0x2e0)](_0x268080,_0x26d0b8,_0x998281,_0x453f9c);},'fYCsB':function(_0x5490b8,_0x1103f2){const _0x1b2356=_0x4ef623;return _0x1b0c79[_0x1b2356(0x741)](_0x5490b8,_0x1103f2);},'rmnhA':function(_0x181b17,_0x12090e){const _0x5d2465=_0x4ef623;return _0x1b0c79[_0x5d2465(0x54c)](_0x181b17,_0x12090e);},'gfwJM':function(_0x130f07,_0x34d17d){const _0x1649dd=_0x4ef623;return _0x1b0c79[_0x1649dd(0x126)](_0x130f07,_0x34d17d);},'HcUMd':_0x1b0c79['ZjPfc'],'xXiBk':function(_0x152d76,_0x47e9f0){const _0x2696ab=_0x4ef623;return _0x1b0c79[_0x2696ab(0x54c)](_0x152d76,_0x47e9f0);}};logger[_0x4ef623(0x3d0)]('\x0a'+'='[_0x4ef623(0x5fb)](0x3c)),logger[_0x4ef623(0x3d0)](_0x4ef623(0x16a)+path[_0x4ef623(0x484)](_0x47d1f3)),logger[_0x4ef623(0x3d0)](_0x4ef623(0x6ba)+_0x153114['join'](',\x20')+']'),logger[_0x4ef623(0x3d0)](_0x4ef623(0x43b)+_0x4581ee+'\x22'),logger[_0x4ef623(0x3d0)]('='[_0x4ef623(0x5fb)](0x3c)+'\x0a');const _0x79a52f=_0x153114['map']((_0x31572d,_0x2222dd)=>{const _0x470507=_0x4ef623,_0x89ba61={'ghvTn':_0x8e2ae0[_0x470507(0x707)],'pJxeA':function(_0x456e09,_0x3dbbf6,_0x4b678e,_0x268a36){return _0x8e2ae0['IJioz'](_0x456e09,_0x3dbbf6,_0x4b678e,_0x268a36);},'sRnKI':_0x470507(0x1ec),'tTaUL':function(_0x42a1c5,_0x41130a){const _0x2aa949=_0x470507;return _0x8e2ae0[_0x2aa949(0x271)](_0x42a1c5,_0x41130a);},'JAlwV':function(_0x1f5421,_0x12d704){const _0x5cdca3=_0x470507;return _0x8e2ae0[_0x5cdca3(0x2cd)](_0x1f5421,_0x12d704);},'MkmFz':function(_0x3c8f91,_0x40f889){const _0x585504=_0x470507;return _0x8e2ae0[_0x585504(0x3b5)](_0x3c8f91,_0x40f889);},'TPezM':_0x8e2ae0[_0x470507(0x534)],'ykyMq':_0x470507(0x644)};if(_0x470507(0x60a)!==_0x470507(0x60a))_0x89ba61[_0x470507(0x5d2)](_0xde4526,_0x20a43b,_0x1fd550,_0x32a96a)[_0x470507(0x4cb)](_0x1d2fdb=>{const _0x439892=_0x470507;_0x32eb96&&_0x27160a(_0x2dc8f7,_0x392f98,_0x51e111,_0x4aac6c);const _0x2baca6={};_0x2baca6[_0x439892(0x14d)]=_0x89ba61[_0x439892(0x55c)],_0x2baca6[_0x439892(0x34f)]=_0x1d2fdb,_0x2970a3[_0x439892(0x475)](_0x18d58f[_0x439892(0x2a5)](_0x2baca6));})['catch'](_0x1d9056=>{const _0x573a16=_0x470507;_0x13966e[_0x573a16(0x644)]('executeCommand\x20failed:\x20'+_0x1d9056[_0x573a16(0x4f1)]);const _0x1c2f06={};_0x1c2f06[_0x573a16(0x14d)]=_0x573a16(0x491),_0x1c2f06[_0x573a16(0x644)]=_0x1d9056[_0x573a16(0x4f1)],_0x3ebe5c[_0x573a16(0x475)](_0x255b81[_0x573a16(0x2a5)](_0x1c2f06));});else return new Promise((_0x2e705a,_0xce33f8)=>{const _0x5cfef8=_0x470507,_0x4f9bab={'lxIcW':function(_0x4171bf,_0x1c4c70){return _0x89ba61['tTaUL'](_0x4171bf,_0x1c4c70);},'vSSCm':function(_0x5d7f0e,_0x4d1c25){const _0x55e48a=_0x8de2;return _0x89ba61[_0x55e48a(0x730)](_0x5d7f0e,_0x4d1c25);}},_0x3aa6f7=['-d',_0x31572d,_0x4581ee];logger[_0x5cfef8(0x3d0)]('['+_0x89ba61['MkmFz'](_0x2222dd,0x1)+'/'+_0x153114['length']+']\x20Executing\x20on:\x20'+_0x31572d);const _0x48d715=_0x89ba61[_0x5cfef8(0x5d2)](spawn,_0x47d1f3,_0x3aa6f7,{'cwd':path[_0x5cfef8(0x664)](_0x47d1f3)});let _0x26f1ee='',_0x1bee8d='';_0x48d715[_0x5cfef8(0x259)]['on'](_0x89ba61[_0x5cfef8(0x73b)],_0x552f57=>{const _0x26f510=_0x5cfef8,_0x2c4bd8=_0x552f57[_0x26f510(0x4e4)]();_0x26f1ee+=_0x2c4bd8,logger[_0x26f510(0x3d0)]('['+_0x31572d+_0x26f510(0x1fc)+_0x2c4bd8[_0x26f510(0x5cf)]());if(_0x2119fb){const _0x36d773={};_0x36d773[_0x26f510(0x14d)]=_0x89ba61[_0x26f510(0x37a)],_0x36d773['data']='['+_0x31572d+']\x20'+_0x2c4bd8,_0x36d773[_0x26f510(0x1a6)]=[_0x31572d],_0x2119fb[_0x26f510(0x475)](JSON[_0x26f510(0x2a5)](_0x36d773));}}),_0x48d715[_0x5cfef8(0xe9)]['on'](_0x89ba61['TPezM'],_0x1f0440=>{const _0x3e2b3a=_0x5cfef8,_0x4d2ae7=_0x1f0440['toString']();_0x1bee8d+=_0x4d2ae7,console[_0x3e2b3a(0x644)]('['+_0x31572d+_0x3e2b3a(0x1e0)+_0x4d2ae7['trim']());}),_0x48d715['on'](_0x5cfef8(0x4f6),_0x1b9dbc=>{const _0x264da5=_0x5cfef8;if(_0x4f9bab['lxIcW'](_0x1b9dbc,0x0)){const _0x1beaae={};_0x1beaae[_0x264da5(0x66c)]=!![],_0x1beaae[_0x264da5(0x22c)]=_0x26f1ee,_0x1beaae['device']=_0x31572d,_0x4f9bab[_0x264da5(0x602)](_0x2e705a,_0x1beaae);}else{const _0xab6a78={};_0xab6a78[_0x264da5(0x66c)]=![],_0xab6a78[_0x264da5(0x644)]=_0x1bee8d||'Script\x20exited\x20with\x20code\x20'+_0x1b9dbc,_0xab6a78['device']=_0x31572d,_0x4f9bab[_0x264da5(0x602)](_0xce33f8,_0xab6a78);}}),_0x48d715['on'](_0x89ba61[_0x5cfef8(0x532)],_0x4fb6e2=>{const _0x58b217=_0x5cfef8;console[_0x58b217(0x644)]('['+_0x31572d+_0x58b217(0x446)+_0x4fb6e2[_0x58b217(0x4f1)]);const _0x478e79={};_0x478e79[_0x58b217(0x66c)]=![],_0x478e79[_0x58b217(0x644)]=_0x4fb6e2[_0x58b217(0x4f1)],_0x478e79[_0x58b217(0x120)]=_0x31572d,_0xce33f8(_0x478e79);});});});Promise[_0x4ef623(0x57e)](_0x79a52f)[_0x4ef623(0x4cb)](_0x1a9593=>{const _0x478d63=_0x4ef623,_0x536726=_0x1a9593[_0x478d63(0x47e)](_0x3b63d0=>_0x3b63d0[_0x478d63(0x365)]===_0x478d63(0x1e7))[_0x478d63(0x162)],_0xd5f0d9=_0x1a9593['filter'](_0xddcd51=>_0xddcd51[_0x478d63(0x365)]===_0x478d63(0x1f2))['length'],_0x3d7276={};_0x3d7276[_0x478d63(0x66c)]=!![],_0x3d7276[_0x478d63(0x3a2)]=_0x1a9593,_0x3d7276[_0x478d63(0x347)]=_0x536726+'/'+_0x153114['length']+'\x20devices\x20completed\x20successfully',_0x8e2ae0[_0x478d63(0x6ec)](_0xfe4e7d,_0x3d7276);})[_0x4ef623(0x153)](_0x18ce97=>{const _0x11cfb0=_0x4ef623;if(_0x11cfb0(0x343)===_0x1b0c79['ZSYLB']){_0xadb0b0['error'](_0x11cfb0(0x5c0),_0x39f4f5[_0x11cfb0(0x4f1)]);const _0x4e8068={};_0x4e8068[_0x11cfb0(0x644)]=_0x11cfb0(0x297)+_0x44a8d4[_0x11cfb0(0x4f1)],_0x1ea37d=[_0x4e8068];}else console[_0x11cfb0(0x644)]('Promise.allSettled\x20error:\x20'+_0x18ce97[_0x11cfb0(0x4f1)]),_0x1b0c79['jVDGh'](_0x3a3ca0,_0x18ce97);});});}function executeAndroidDevices(_0x1c07a1,_0x3d287e,_0x5662a9,_0x3628af){const _0x205343=_0x320de1,_0x464d91={'wolXS':function(_0x4649f1,_0x1b4db2){return _0x4649f1!==_0x1b4db2;},'RSsgW':function(_0x46630c,_0xf577c8){return _0x46630c===_0xf577c8;},'nLjwv':_0x205343(0x758),'xkuMk':function(_0x1f1c69,_0x3f7b83){return _0x1f1c69(_0x3f7b83);},'KMpkM':_0x205343(0x760),'XWyWG':_0x205343(0x4f6),'shCzX':_0x205343(0x75c),'ZGzGQ':_0x205343(0x6f8),'sWmVW':function(_0x4248c6,_0x1e7b4a){return _0x4248c6(_0x1e7b4a);},'CfFAa':_0x205343(0x1f4)};return new Promise((_0x2540e4,_0x426a46)=>{const _0x4936b2=_0x205343,_0x30d3ec={'LccLa':function(_0x4e4c5c,_0x13c48e){const _0x82806a=_0x8de2;return _0x464d91[_0x82806a(0x53b)](_0x4e4c5c,_0x13c48e);}};if(_0x464d91[_0x4936b2(0x323)]==='NbUPp'){const _0x23c104={};_0x23c104[_0x4936b2(0x66c)]=![],_0x23c104['error']=_0xe33bd8[_0x4936b2(0x4f1)],_0x587e5e[_0x4936b2(0x365)](0x1f4)[_0x4936b2(0x169)](_0x23c104);}else{logger['debug']('\x0a'+'='[_0x4936b2(0x5fb)](0x3c)),logger['debug'](_0x4936b2(0x16a)+path[_0x4936b2(0x484)](_0x1c07a1)),logger['debug']('Devices:\x20['+_0x3d287e[_0x4936b2(0x240)](_0x3d02a2=>_0x3d02a2['name'])[_0x4936b2(0x4dd)](',\x20')+']'),logger[_0x4936b2(0x3d0)]('Command:\x20\x22'+_0x5662a9+'\x22'),logger[_0x4936b2(0x3d0)]('='['repeat'](0x3c)+'\x0a');const _0x2128c6=_0x3d287e['map']((_0x2abcfa,_0x10e564)=>{const _0x3f0622=_0x4936b2,_0x4591ab={'XQsBF':function(_0x1778ee,_0x20950f){return _0x464d91['wolXS'](_0x1778ee,_0x20950f);},'SqHcl':_0x3f0622(0x375),'cmKDk':function(_0x5f519e,_0x11d6ff){const _0x52822b=_0x3f0622;return _0x464d91[_0x52822b(0x410)](_0x5f519e,_0x11d6ff);},'WdhzZ':_0x3f0622(0x330),'JRYTq':_0x464d91[_0x3f0622(0x2f4)],'vZOma':function(_0x36947b,_0x19c507){const _0x5b2e28=_0x3f0622;return _0x464d91[_0x5b2e28(0x53b)](_0x36947b,_0x19c507);},'cGvGT':_0x464d91[_0x3f0622(0x266)],'eVyoE':_0x464d91[_0x3f0622(0x41b)],'TUPmi':_0x3f0622(0x644)};return logger['debug']('['+(_0x10e564+0x1)+'/'+_0x3d287e[_0x3f0622(0x162)]+_0x3f0622(0x388)+_0x2abcfa[_0x3f0622(0x4b8)]+'\x20('+_0x2abcfa[_0x3f0622(0x23d)]),new Promise((_0x2ff962,_0x54b287)=>{const _0x1acadb=_0x3f0622,_0x2aac36={'onqfc':function(_0x214b6a,_0x165c39){return _0x4591ab['vZOma'](_0x214b6a,_0x165c39);}},_0x259291=[_0x2abcfa['udid'],..._0x5662a9[_0x1acadb(0x722)]('\x20')],_0x8ab0ad=spawn(_0x1c07a1,_0x259291,{'cwd':path[_0x1acadb(0x664)](_0x1c07a1)});let _0x1dd13b='',_0x121049='';_0x8ab0ad[_0x1acadb(0x259)]['on'](_0x1acadb(0x760),_0x5b7180=>{const _0x3ac4b7=_0x1acadb,_0x4916f0=_0x5b7180[_0x3ac4b7(0x4e4)]();_0x1dd13b+=_0x4916f0,logger['debug']('['+_0x2abcfa[_0x3ac4b7(0x4b8)]+_0x3ac4b7(0x1fc)+_0x4916f0[_0x3ac4b7(0x5cf)]());if(_0x3628af){const _0x187a37={};_0x187a37[_0x3ac4b7(0x14d)]=_0x3ac4b7(0x22c),_0x187a37[_0x3ac4b7(0x120)]=_0x2abcfa['name'],_0x187a37['data']=_0x4916f0,_0x3628af['send'](JSON[_0x3ac4b7(0x2a5)](_0x187a37));}}),_0x8ab0ad[_0x1acadb(0xe9)]['on'](_0x4591ab[_0x1acadb(0x12d)],_0x3adcb0=>{const _0x211ca6=_0x1acadb,_0x5af888=_0x3adcb0[_0x211ca6(0x4e4)]();_0x121049+=_0x5af888,logger[_0x211ca6(0x3d0)]('['+_0x2abcfa[_0x211ca6(0x4b8)]+_0x211ca6(0x1e0)+_0x5af888['trim']());}),_0x8ab0ad['on'](_0x4591ab[_0x1acadb(0x742)],_0x5e9c20=>{const _0x34b0c3=_0x1acadb;if(_0x4591ab[_0x34b0c3(0x427)](_0x4591ab['SqHcl'],'tQnfW')){if(_0x4591ab[_0x34b0c3(0x3b0)](_0x5e9c20,0x0)){if(_0x4591ab['WdhzZ']!==_0x4591ab['JRYTq']){const _0x2efdec={};_0x2efdec[_0x34b0c3(0x66c)]=!![],_0x2efdec[_0x34b0c3(0x22c)]=_0x1dd13b,_0x2efdec[_0x34b0c3(0x120)]=_0x2abcfa['name'],_0x4591ab[_0x34b0c3(0x368)](_0x2ff962,_0x2efdec);}else{const _0x42bc16={};_0x42bc16[_0x34b0c3(0x66c)]=![],_0x42bc16['error']=_0x3433e2[_0x34b0c3(0x4f1)],_0x3f947d[_0x34b0c3(0x365)](0x1f4)[_0x34b0c3(0x169)](_0x42bc16);}}else{const _0x18fd77={};_0x18fd77[_0x34b0c3(0x66c)]=![],_0x18fd77['error']=_0x121049||_0x1dd13b,_0x18fd77[_0x34b0c3(0x120)]=_0x2abcfa['name'],_0x4591ab['vZOma'](_0x2ff962,_0x18fd77);}}else{const _0x5c107f={};_0x5c107f[_0x34b0c3(0x66c)]=![],_0x2aac36[_0x34b0c3(0x66d)](_0x18786a,_0x5c107f);}}),_0x8ab0ad['on'](_0x4591ab['TUPmi'],_0x342a66=>{const _0x1529e6=_0x1acadb;console[_0x1529e6(0x644)]('['+_0x2abcfa['name']+_0x1529e6(0x688),_0x342a66);const _0x363dd9={};_0x363dd9['success']=![],_0x363dd9[_0x1529e6(0x644)]=_0x342a66['message'],_0x363dd9['device']=_0x2abcfa['name'],_0x2ff962(_0x363dd9);});});});Promise['allSettled'](_0x2128c6)['then'](_0x2ccd41=>{const _0x5c41ba=_0x4936b2,_0x18bd25=_0x2ccd41[_0x5c41ba(0x47e)](_0x35e904=>_0x35e904[_0x5c41ba(0x365)]==='fulfilled'&&_0x35e904['value']['success'])[_0x5c41ba(0x162)],_0x49fd8a=_0x2ccd41[_0x5c41ba(0x162)]-_0x18bd25,_0x4b925d={};_0x4b925d[_0x5c41ba(0x66c)]=!![],_0x4b925d[_0x5c41ba(0x3a2)]=_0x2ccd41,_0x2540e4(_0x4b925d);})[_0x4936b2(0x153)](_0x33e13a=>{const _0x11b7cd=_0x4936b2;if(_0x464d91['wolXS'](_0x464d91[_0x11b7cd(0x588)],_0x11b7cd(0x75c))){const _0x435e90=_0x3e3a4d[_0x11b7cd(0x47e)](_0x427b76=>_0x427b76[_0x11b7cd(0x365)]===_0x11b7cd(0x1e7))[_0x11b7cd(0x162)],_0x33aa3d=_0x392a78[_0x11b7cd(0x47e)](_0x535256=>_0x535256[_0x11b7cd(0x365)]===_0x11b7cd(0x1f2))[_0x11b7cd(0x162)],_0x1e7616={};_0x1e7616['success']=!![],_0x1e7616[_0x11b7cd(0x3a2)]=_0x3ecd6b,_0x1e7616[_0x11b7cd(0x347)]=_0x435e90+'/'+_0x465deb[_0x11b7cd(0x162)]+_0x11b7cd(0x2e5),rTNcKD[_0x11b7cd(0x195)](_0x5b1e6a,_0x1e7616);}else console[_0x11b7cd(0x644)](_0x464d91['ZGzGQ'],_0x33e13a),_0x464d91['sWmVW'](_0x426a46,_0x33e13a);});}});}function _0x3ee9(){const _0x4ec238=['rw5LDgG','ChvmqK8','Avb2B00','v3Pyugm','sKfuBeu','CKvZqLu','vevWExi','qxfOBeK','rhvtwg4','BvvwzKq','BLvwALa','CMvJB3jKAw5N','tKfpDfC','CMvHzezPBgu','q2fgy2m','zwHbt2S','AxHpthO','tK1Su0G','l2fWAs9Zzxr0Aw5NCY9KzxzPy2vZ','sMTnA0O','vxnPBMCGqw5KCM9PzcbJB250CM9SihnJCMLWDcbMB3iGD2LYzwXLC3mGzgv2AwnLCZOG','zw5JB2rPBMC','u2nxz2y','4P2mifDeqsbUB3qGCNvUBMLUzYbVBIa','z2L0AhvIx3rVA2vU','uxjrCMC','rMfbuNq','z2nZvvK','u2DxuLa','rxjYB3iGy2HLy2TPBMCGv0rblIbqBgvHC2uGC3rHCNqGBwfUDwfSBhKGAw4GwgnVzguU','sLnMvhu','Aw5PDgLHBgL6zvbYB3zPzgvYCW','CMvWzwf0','sMnXB1y','s2fvD3q','ktOG','qK9gvM4','ywrIic1Zia','rMfPBgvKihrVigv4zwn1DguGDgfW','DLntq20','cVcFLRhVUi8GqvbjoIbdBgLJA2LUzYbSB2nHDg9Yici','zKLoDNO','reD2yLm','BhfhB1e','BfLnEvq','Bw9KzwW','uKvqtefzsu5hoIa','Ae10CKu','iI9HChbPDw0TDwLHDxrVBwf0B3iYlxnLCNzLCI5HCgSGmJ4Vzgv2l251BgWGFhWGzwnOBYaIiG','vu9JDwO','EvP4Bvy','D21AveG','EKzdrvO','CeXrwLm','rxPWBxq','4PYfifvjqxv0B21HDg9YmIbPBNn0ywXSzwqGC3vJy2vZC2z1BgX5ig9Uia','DgP1q3C','C3rVCf9YzxbSyxK','ueTjD2G','CgHHEw8','4PYfifnLC3nPB24GzMLSzsb1CgrHDgvKigzVCIa','8j+tOsbezxzPy2uGsva6ia','yvvStLi','zgDzruS','wwzrDK0','zMvQreq','AxPetvm','t0n1v0q','wfLcDgi','vfjIsLC','y1voy3a','lI9SB2DNzxi','zhvRzKq','u2rkA0m','u2vXDwvUDgLHBcbLEgvJDxrPB24GzMfPBgvKoIa','vuLbDxrVBwf0B3iYiefqs3mGBM90igzVDw5KlIbqBgvHC2uGCNvUoIbHChbPDw0GzhjPDMvYigLUC3rHBgWGDwLHDxrVBwf0B3iY','icaYlIbvC2uGysbKAwzMzxjLBNqGCg9YDdOGue9svd0ZmdaYigrLDMLJzwX5','AwLKC3O','rw56s1K','yNrkDxu','tfjHtNa','uKnyB2G','tezJuhC','DMLZAwjSzq','Cg5NBwS','BMPoC0u','C1bPyNi','yw5KCM9Pzf9KzxzPy2vFy29UDhjVBc5ZAa','EKPiu3K','4PYfiefSBcbKzxzPy2vZigrPC2nVBM5Ly3rLza','4P2mie5VigrLDMLJzxmGzM91BMqGzM9YoIbB','BNbTihjVB3qGlwC','CvDfExi','y2fWywjPBgL0AwvZ','ruTUC3C','BwLZDNa','vKznCMi','ruPWz3a','wvrzseS','sxP6zhy','EwDtDgu','cUkDJcbqB3j0idmWmdeGAxmGywXYzwfKEsbPBIb1C2uH','8j+uTcbszwnVCMrPBMCGC3rHCNrLzdOG','tNHMvxq','D3bUvNm','zxjYB3i','zwXewhq','4PYtq2XPy2S','BhDLCum','C0POsge','4PYfiezVDw5Kia','ywX3yxLZtwf0y2G','yKLXDvG','r0vnsu5jx0fqsv9lrvK','ueXps2y','C2jRB0q','suq6','rM5SAgm','Cu9bufu','CgfYC2u','BuXltgK','BLbMuuW','DhjQwhC','wwDhtwO','cGRWN5kHifbSzwfZzsbJBgLJAYb0AguGiKnVBM5Ly3qIigj1DhrVBIbVBIbLywnOigrLDMLJzsbIzwzVCMuGCNvUBMLUzYbJB21Tyw5KCY4kcG','Ee9jrNK','rhfcsKO','Bwf0y2G','EMHKCLG','ruPgyxq','yvPcANe','rMzMwxK','AeHyt0K','DejXC0m','AvjQqMC','qKX1tKe','vNDNAhi','zgLYBMfTzq','y2nRy3y','BLH2uM8','BM9tzxj2zxi','ignVBM5Ly3rLzcbKzxzPy2vZ','ru1Kv0u','CMvJB3jKAw5NxW','u2TUEwe','C3vJy2vZCW','B25XzMm','z2TeBxa','4PYfieTPBgXLzcbPChjVEhKGzM9Yia','cVcFJjaGt3bLBMLUzYbICM93C2vYihrVia','Bgvyrwu','y29TBwfUzf9JB252zxj0zwq','ChDYzKi','weToEvm','sKrhzK4','A3vzq1i','DgvgCwi','v0zczLq','vuzAuhe','rMfPBgvKihrVigDLDcbvssbLBgvTzw50CY4GugXLyxnLigvUC3vYzsbvsuf1Dg9TyxrVCJiGAxmGAw5ZDgfSBgvKigzVCIbbBMrYB2LKigrLDMLJzxmU','ufL1DhO','zgjxEKS','DxbMzfK','vg90ywWGBgLUzxm6','zxHPC3rPBMC','icaGu2vHCMnOzwqGAw46','ihzPysbxAuzPic0Gv0rbifn0yxj0zwqH','D3f1yxq','zxPbBxi','D1bcyNm','zMLSzxbHDgG','CKHtruS','tu5JChq','xsbqCM9JzxnZigvYCM9YoG','AfjRC2e','CxPnshC','z1nJDNG','DffPzuy','shzswu8','q29rwxO','z1zLyMq','DxHbt00','A2zKtMu','lxbYB2PLy3q','u0LgEfm','A0Lorue','q29UDgvUDc1uExbLoIbHChbSAwnHDgLVBI9QC29U','r1jpuv9bueLFs0vzpq','D3nfvM4','r3nctNm','4P2miefjignVBNzLCNnPB24GzMfPBgvKoIa','Cg5gy1C','rMHJDNq','ExfjAwS','teTWsfa','igLUihLVDxiGyNjVD3nLCG','ihrVDgfSkq','BvrczKe','tM8GDxnLCIbHChbZigzVDw5Kig9YihvUywjSzsb0BYbWyxjZzsbVDxrWDxq','whH3tee','shL1qMy','A2fbrfG','CwXYAKC','BuP1q2O','B2LwA3u','z0XIBuq','l3rTCc9PB3nFBxvSDgLFC2vZC2LVBNm','A29KCgC','wMPHvvu','weXZyuC','CgXHDgzVCM1oyw1L','tufpBwK','BKvpB0O','ig5LDYbvu0iGzgv2AwnLkhmPihrVignVBMzPzW','4PYfienSzwfUzwqGDxaGv0rbihbYB2nLC3nLCYbMB3iG','wvblq3y','ExjAq3i','ks4UlG','4P2miezHAwXLzdOG','qvjkC2K','z2vTAw5P','y29VCMrPBMf0zxm','BgLZDa','rgv2AwnLCZOGwW','sujWu3C','lxnJAgvTzq','wLnbzgy','igzVCNDHCMqGDgnWoG','wKfQAgS','vvHSELu','te1MEKy','yMTeD3y','CMXltvi','u1Deyu8','Evf2BM4','qNzQy3G','rxjYB3iGBg9HzgLUzYbKzxzPy2uGy29UzMLNoG','rxfduMK','CgfJA2fNzxm','ExLmCuu','wePbEhu','BND0t3a','sw52ywXPzcbKzxzPy2uGB2jQzwn0','A2PdALm','CMvWBgf5x2vYCM9Y','4P2mifnJCMLWDcbUB3qGzM91BMq6ia','B2fvBvu','lI9KzxzPy2vezxrLy3rPB24','DvLUzNO','Ahr0CdOVl2XVy2fSAg9ZDdO4mtaWl3n0yxr1CW','sufAA2C','l3nLC3nPB24V','l2fWAs9SB2nHDg9YCY9JBgLJAW','lNbUzW','vhz3BxK','tK9czM0','zfrbDva','yNvUzgXLswq','D2DdAw0','4PQG77IpicbbueSGzMLSzxmGBM90igzVDw5KigLUigfUEsbLEhbLy3rLzcbSB2nHDgLVBG','v1fruu8','iIb8Fcb0CNvL','vMXWueO','s1fWDgS','BgDxBxK','v29wtNO','yxvPvLC','A3r3qMi','yND2ruy','vK9fs3a','s21YwgG','tM8GB3v0Chv0ihjLy2vPDMvKigzYB20Gzgv2AwnL','CLfctva','EfHPqMS','igXVy2f0B3jZ','uxnyDNG','yvH2y04','lI9Zy3jPChrmB2fKzxi','ALbwAuW','BvvIB1a','l3DKl2H1yI9ZzxnZAw9U','4PYfifvjqxv0B21HDg9YmIbZzxnZAw9UigrLBgv0zwqGzM9Yia','y29UBMvJDgLUzW','qKHyBM8','8j+tNsbszwnVCMrLzcbJB21Tyw5KoIa','rxHLy3v0Aw9UigvYCM9YoG','wwzSqLu','zKn4wuu','zfr0BuG','CxHQu1m','z0LyDNu','CNnNv0O','DuX4D3q','AfL1EMe','Aw52ywXPzcbZzxnZAw9UigLK','4P2mifnJCMLWDcbLCNjVCJO','v1fHDvK','ig5VDcbMB3vUzcbPBIbbrei','rKjUugO','4PQG77IpifDeqsbfCNjVCIaO','zurwCNK','4PYfieTPBgXLzcb4y29Kzwj1AwXKigzVCIa','z0TPsfe','AgDvsvG','8j+tSsbbBMrYB2LKigrLDMLJzsbKAxnJB25Uzwn0oIa','ic0Gu3rHCNrPBMCGv0rblI4U','r0ngr2K','D2Tsqw8','Cg9ZDa','y2HPBgrFChjVy2vZCW','lI4VlI4Vzgv2AwnLrgv0zwn0Aw9U','CgTPBgWGlwyGiNHJB2rLyNvPBgqUkG','tNrLCLy','iIaO','4PQG77IpifDeqsbfCNjVCJOG','vg90ywW6ia','t1bftG','icaGlsa','ALrqDui','BKnxBgm','iYbhywXHEhLtmJmSqujdrdeYmZqSmtKYlJe2oc4XlJe1mcXHBMrYB2LKlhDPCMvSzxnZicaGicaOqw5KCM9PzcbxAxjLBgvZCYKkcG','tg5yrha','8j+tPsbvsuf1Dg9TyxrVCJiGBM90igzVDw5Kig9Uia','Ag9TzwrPCG','quPUvLy','rMfPBgvKihrVignVBM5Ly3qGzgv2AwnLlIbqBgvHC2uGDxnLihrOzsbdB25Uzwn0igj1DhrVBIbMAxjZDc4','qMTnBeK','C3bSAxq','z2v0qxzHAwXHyMXLuhjVDMLKzxjZ','EezpA20','rMfPBgvKihrVigDLDcbHChaGAw5MBW','cUkDJcbqB3j0ia','rxjYB3iGyxv0BY1ZyxzPBMCGzgv2AwnLCZO','8j+tOsbbDxrVlwnVBM5Ly3rPBMCG','tuz2zfm','BhrvDhy','vxnLiefjoIa','s2Twq1a','whbzqvO','vgLHzxG','yKP5tNi','sKfSD1y','z1LND00','nZuZntu5wMPSAwzI','q3Drr08','vvzPEMy','CMvJDxjZAxzL','igrLDMLJzxm','u3rZD0O','rxjYB3iGy2XLyw5PBMCGDxaGDhjHy2TLzcbWCM9JzxnZzxmGzM9Yia','s3zVtvO','q29UBMvJDgvKihrVia','vfbLEK0','Eur5Dxa','qLr3u00','ve5Yrgm','mJeWmJeXoePtr0fgtW','vLnys2C','ufHMy3e','zvz5B0u','C3vNz2vZDgLVBG','CMvZB3vYy2vjza','Eg1rteW','lcbPBNn0ywXSAw5NlI4U','B25YsLO','C1fIquu','zgz3C2y','svncz3K','Ce9sq1y','uKfIs00','BNvIv3y','qNHNrw8','wLj3uNm','ic0GqurcifjLywr5iokCHq','B3fPseO','Bu9fz0C','ugfQz2y','DwDxD1u','iYbezxzPy2uGq29UzMLNDxjHDgLVBIaOqxv0BY11CgrHDgvKkqO','cVcFLRhVUi8GqvbjoIbuyxbWAw5Nigf0ignVB3jKAw5HDgvZicG','thjhseG','t1fUA2S','yvvQC2O','lIbqCM9JzxnZieLeoIa','q0zcDw5KBgvjzgvUDgLMAwvY','ufrvCuq','D09Wz3C','C2HLBgW','yunpqui','zgf0yq','y3vYBa','y29UBMvJDgLVBLr5Cgu','v21rr1G','shHHA2m','Ahr0CdOVl2XVy2fSAg9ZDdO','BfzOqLO','rgv2AwnLCYbYzwnLAxzLzdOGwW','BKvorKC','quHWCvO','seXmruC','BxrPBwu','uufzCxa','DNLbDhe','oJu1ntu','mZy3nty4nurwuwfQqG','s3PfEw0','A3PQBuC','8j+uJcbeAxnJB25Uzwn0Aw5NiefmtcbKzxzPy2vZlI4U','ignVBM5Ly3rLzcaTifDeqsbszwfKEsek','t05KtMq','DwfJrwe','DNjrzxi','B0X1C1m','CKf6u1u','oIbSC29Mic10AtO','y2XHDwrLx2fWAv9RzxK','AgT1AfO','r2v0DgLUzYbSB2nHDg9YCYbMB3iGzgv2AwnLoIa','t1DABgq','C3rKzxjY','v2fPDgvKia','y3Dhtfq','iYbgB3jTyxq6igrLDMLJzv9Uyw1LlhvKAwqSAxbFywrKCMvZCYXWBgf0zM9YBsX0ExbLcG','q01lrg8','vejlvLG','yKfAsvu','vfnjCeG','tgfIzwW6','wgL2AMy','vM5JC0y','4PYfifDeqsbZDwnJzxnZzNvSBhKGC3rHCNrLzcbMB3iG','ELb5yuC','t0HJu3K','y29TBwfUzhm','D1Dbs3m','y29UBMvJDa','ihzHBgLKigXVy2f0B3jZ','DvPbv08','tfnLrwm','ENjuB04','4PQG77IpicbdB3vSzcbUB3qGCMvTB3zLihbVCNqGzM9YD2fYzgLUzZOG','lI4VC2nYAxb0CY9ZAgvSBc8','quKGDxnPBMCGCgXHDgzVCM0GBw9KztOG','tuLtvfjbtf9bueLFs0vz','8j+tPsbjBNn0ywXSAw5Nifvjqxv0B21HDg9YmIbVBIa','wKnpAKK','qKjSqvi','txLus24','4P2mievYCM9YigrPC2nVBM5Ly3rPBMCGywXSigrLDMLJzxm6','zeTNtfi','q2znthm','yMzfDKO','vuvHywW','zxHLy3v0zv9JB21Tyw5K','8j+uJcbtDgfYDgLUzYbPChjVEhKGzM9YihbVCNqGzM9YD2fYzgLUzY4UlG','sKDnzg8','ls1JB25Uzwn0lxrPBwvVDxq','CMvWBgf5x2nVBxbSzxrL','iYbqBgf0zM9YBtOGAw9ZihWGyw5KCM9PzaO','4PYfiefUzhjVAwqGzgv2AwnLia','4P2miezHAwXLzcb0BYbZyxzLihnLC3nPB24GzM9Yia','uxDfChC','EYjJyxbHyMLSAxrPzxmIoNSIywX3yxLZtwf0y2GIoNT9Fx0','t05jCvq','BxmUlI4k','sNvQA2e','DKjlz0m','CgTPBgWGlwyGiMLWCM94Es4Q','zhH3yvu','4PYfifbVCNqGzM9YD2fYzgLUzYbYzw1VDMvKigzVCIa','r0vnsu5jx0fqsv9lrvK9','zM9YrwfJAa','zuDXqw4','q01Rvue','zgv2AwnL','tw90AwS','qLvLz2e','l2fWAs9JB252zxj0lwnVBw1HBMq','yxHPB3m','C2DrtxC','ELH1DwG','tvjeBNq','q2zyuMS','ugfYC2vKigXVy2f0B3i6','DeDrsfq','vMLLCMq','C2XPy2u','y0D2r1q','qMnTrKq','rxjYB3iGBg9HzgLUzYbHChaGChjLC2v0CZO','rxzuz2G','vxDWCvq','tg1MAwC','y1b3D3K','iI9HChbPDw0TDwLHDxrVBwf0B3iYlxnLCNzLCI12kI5HCgSGmJ4Vzgv2l251BgWGFhWGzwnOBYaIiG','l2fWAs9YzwnVCMrPBMDZlZPMAwXLBMfTzq','wLLxwuK','zw1lsLu','yuXUwvi','s0r2C1y','BwTKAxjtEw5J','CujuBeu','r0Lusfvcx1rps0vo','u2vYDMvY','B0nwqNq','yvHMrLG','iYaGicaTigLpuZOGrgv2AwnLig11C3qGyMuGCgfPCMvKigLUifHJB2rLlcbxzwjeCML2zxjbz2vUDcbYDw5UAw5NcG','q2fUBM90ihjLywnOia','whzLANK','C2vZC2LVBKLK','4PYfifvjqxv0B21HDg9YmIbZzxnZAw9UignYzwf0zwqGzM9Yia','BwvuEfC','vw5lB3a','seDVCuS','CufPEKS','r1LeB2q','ELjNDKe','sMvTtKG','CgTnCKm','DhLWzq','zej1s3y','4PQG77Ipifvjqxv0B21HDg9YmIbPBNn0ywXSyxrPB24GzMfPBgvKig9Uia','DvPSy00','BMfVwMS','uLPbDhC','y2f0y2G','vg90ywWGy29TBwfUzhm6ia','rgv2AwnLig5HBwvZihjLy2vPDMvKoIbB','tw1st2m','8j+tOsbdB25Uzwn0ihjLCxvLC3qGCMvJzwL2zwqGzM9YigrLDMLJztO','DMfYzuO','vvrAEMu','B3jPz2LUywXdB21Tyw5K','rgv2AwnLCYbJB25MAwD1CMf0Aw9UihnHDMvK','yvnpDfu','CMvWBgfJzq','D3z4EeS','DLfYuxa','rLLNBeW','C29YDa','BgvUz3rO','uNzozeO','wuHPDxq','rxjYB3iGBgLZDgLUzYbYzwnVCMrPBMDZoG','zNrruee','DgLTzw91Da','tuPxD3G','ANnVBG','u2nYAxb0oIa','4PYfief1Dg8TC2f2zwqG','tLrsyMe','Awq9','D3nHrvy','zg1nyLe','l2fWAs9KzxzPy2vZl2rPC2nVBM5Ly3qTywXS','BgfwzNC','vfLUAMC','lcbTyxKGDgfRzsbHig1VBwvUDc4UlG','yNfdCNu','CMvJB3jKAw5Nx3n0yxj0zwq','l2fWAs9KzxzPy2vZ','wNz2AeW','4P2miezHAwXLzcb0BYbZDgfYDcb4y29Kzwj1AwXKigzVCIa','rK5UBLe','y05zBva','rgv2AwnLigrLDgfPBhm6','8j+uJsblAwXSAw5NihbYB2nLC3nLCYbVBIbWB3j0ia','z2fUz04','teDMBM4','wxzAyLm','zerKs2y','teXbshK','tMXesKO','uMvZDwX0ihn0yxr1CZOG','D3jPDgvgAwXL','D0PAsfO','rgv2AwnLihnLBgvJDgLVBIbYzxf1AxjLza','EgvsA24','sefuque','B3jPz2LUywW','sg9ArLC','4PYfifnLC3nPB24GDMvYAwzPzwqGyw5KihDVCMTPBMCGB24G','EvHOshO','zxjWqw4','zMLUywXdB21Tyw5K','D0Hns08','wvvRDey','u2nYzwvUC2HVDcbUB3qGzM91BMq','rMfPBgvKihrVignVBM5Ly3qGDg8G','Aurfy2S','vNjPzgi','tgnJtge','Denjt00','vuLbDxrVBwf0B3iYigLUC3rHBgXLzcbZDwnJzxnZzNvSBhK','CwDdywu','4PYfierPC2nVDMvYzwqG','zxHPC3rZu3LUyW','yxPXzeq','BwLZDhjHBf9HCgLFA2v5','DKj2y1y','z2Llq1m','Ag56t3G','t0zltxu','AgTNsMW','AKDiAeO','ignVBw1HBMrZ','AxbYB3H5','Cxn4sNy','zgv2AwnLCW','DNDyAKi','yxbRCW','4P2miefqssbLCNjVCJO','BNLgCMy','ywHXsNm','tMXvzg4','sxL2uw0','8j+uJcbeAxnJB25Uzwn0Aw5NigzYB20G','yvbPCgi','uwHACeG','BKjiqxG','iYbbssbqCM92AwrLCIbdB25MAwD1CMf0Aw9UcKfjx1bst1zjrevspq','4P2miezHAwXLzcb0BYbPBNn0ywXSifvjqxv0B21HDg9YmJOG','B1bfr3e','Aw14DLK','zgv2AwnLBhLFyw5KCM9Pzf9ZzxnZAw9UCY5Tyxa','vgXgELy','uKHhz0u','rwjmzNm','Ee9SD2W','zMvxzwq','wM9nC2S','CxL4EgC','uMvJB3jKAw5Nig5VDcbMB3vUza','qxbvEhy','DMnlufK','cVcFJQWGu3rHCNrPBMCGCMvWBgf5oIa','v2vIrhjPDMvYqwDLBNrsDw5Uzxi','rxHLy3v0zunVBw1HBMqGC3vTBwfYEtOG','Dg9ju09tDhjPBMC','sffmquG','yKrTBwK','r1jpuv9bueLFs0vz','8j+AGcbtDgfYDgLUzYbvsuf1Dg9TyxrVCJiGC2vZC2LVBIbMB3iG','ihWGEgfYz3mGA2LSBcaTosaYpI9KzxyVBNvSBcb8Fcb0CNvL','4PYtvMLZ','ihnOzwXSihbTihbHDgGG','wxPlA1y','uw9dvMe','z2v0q3vYCMvUDfbYB3zPzgvY','BKnztgK','tujysha','BvbzC1i','D2PyuNK','wu1sC1K','C3rHCNrFCMvJB3jKAw5N','C2L6zq','igzVCIa','sfDmzKe','C2rlqMe','u2H3BM4','ChjVDMLKzxjZ','ywLFChjVDMLKzxjFC2v0','EefUywK','C3rYAw5N','vervrxK','zwvwCKm','xsbtverfuLi6ia','uMvZDwX0CYbHCNjHEsbSzw5NDgG6ia','BfrVDwm','wffKueC','ENjby2e','4PYfifDeqsbYzwfJAgfIBguGzM9Yia','lI9Zy3jLzw5ZAg90CW','zNvSzMLSBgvK','vuLjEue','quLFtu9eruW9','r3zwrLi','BeP0teC','y29TBwfUzf9VDxrWDxq','lIbqBgvHC2uGD2fPDcaXmc0XnsbZzwnVBMrZlI4U','t3v0Chv0igXLBMD0AdO','DxrMltG','rgPTEeq','ANzmBgS','CMvQzwn0zwq','tvf5ENi','DwfYCeO','CuLkt28','tM8Gzgv2AwnLCYb0BYbKAxnJB25Uzwn0','Cgjot0G','zujXyui','rMfPBgvKihrVihn0yxj0ihnLCNzLCJO','rxjYB3iGzgvSzxrPBMCGCMvJB3jKAw5Nia','zfDoEha','xsbtverpvvq6ia','8j+tSsbezxzPy2vZoIa','Aw8UyxbWAxvTlNvPyxv0B21HDg9YmG','vu9UuLm','Chv0','BNfNDu4','A0frz2u','D2fYBMLUzZO','CgLWzq','uLnnCw0','qw5KCM9Pza','rxjYB3iGC3rVChbPBMCGvuLbDxrVBwf0B3iYihnLC3nPB246ia','quDetfC','icaGq29TBwfUzdOG','vezzAwq','Bhzusuy','y3j5ChrV','C29IwxO','q3vJsK8','DgD0EeS','q0Xbvurfx0fqsv9lrvK','z09xDMy','4PYfiezVDw5KihnJCMLWDdOG','zgLuthq','4PYfienSzwfUzwqGDxaGAxbYB3H5igzVCIa','4PYfienSzwfUzwqGDxaGCg9YDca','uKDJwgW','v0vcu09ds0vuoIbszwnLAxzLzcbLEgvJDxrLx2nVBw1HBMq','D2rrrfq','l2fWAs9YzwnVCMrPBMDZ','4P2mievYCM9YignOzwnRAw5NifDeqtOG','CNfrr3e','EM9qDw8','C3rVCf9YzwnVCMrPBMC','yujtqNy','uxbRsuu','z2jqDMe','uLj1Exm','tMHNruS','yxPtreC','rwvvyKm','CLjlrvq','CvrXB1O','ywPZtvu','v2vIu29JA2v0ignVBM5Ly3rPB24Gy2XVC2vK','CvDUv0u','vKDsr1K','Du5hDhq','B3v0Chv0','A3HQvgm','8j+AGcbtDgfYDgLUzYbUzxCGvuLbDxrVBwf0B3iYihnLC3nPB24GB24G','DhHAAui','zgv2AwnLC191CgrHDgvK','yLrbrKm','ihnOzwXSigfTigzVCMnLlxn0B3aGAw8UyxbWAxvTlNvPyxv0B21HDg9YmI5Zzxj2zxiUDgvZDa','v2vIrhjPDMvYqwDLBNq','D3fitwi','EhvWzvu','AuPdBum','zeXxy2m','C1bhChO','yMnQthK','rhb4CfK','vfP4shK','lI4VlI4VlI4VyxbRCW','DwrPza','EgnVzgvIDwLSza','zhbjq2W','BwfW','svnvww8','zw5KC1DPDgG','q09irvjfx0fqsv9lrvK','DNHSy04','ugnAv1q','ywXS','C1DZzwC','uhvfshq','AwrLDMLJzwLUC3rHBgXLCIaTDsa','qMnot3m','u0nbzxm','z0DPuuW','suzOEMK','iNn0yxrLiG','ihWGz3jLCcb2zxjZAw9UtMfTzq','CgXUAvi','l2fWAs9HChbZl2LUzM8','qKr5uwS','4PYfierPC2nVBM5Ly3rLzcbbBMrYB2LKigrLDMLJzsa','vvz0C2q','l2fWAs9YzwnVCMrPBMDZl3nHDMu','u2vYDMvYvvjmsgvYzq','BhnVzIaTAtO','EKfWwxC','C3rKB3v0','wfrsreC','CLrPrem','Bvf0uNK','CLrttfi','A05xDuu','B2Liu1q','vNn3sg0','BgPjAw4','rgDZDLG','rwvyC04','ugrhwMi','r0fqA2u','s01WA00','zwfLAMS','qK1YEK4','igrLDMLJzsHZksbHy3jVC3mG','BM90ztO','EKT4Aei','mJC1mZe3nJHxywHQBxq','CMvHzgrPCG','igLUC3rHBgWGlxiGiG','8j+uJsblAwXSAw5NifDeqsbMB3iGvurjrca','icdWN5oXifjLC29SDMvKigfWCcbWCMvZzxq6ici','zLLdC0i','ENzutfm','q3Huzg8','Dfr6q2q','sgPKreW','igzVCNDHCMqGls1Yzw1VDMuGDgnWoG','4O+577IpicbszwnVCMrPBMCGC3rVChbLzdOG','uxrZAwu','4P2miezHAwXLzcb0BYbZDgfYDcbvsuf1Dg9TyxrVCJiGzM9Yia','rgTLDvm','uNzxCKO','DNjgwNy','AMPbuNe','uLrlrLy','DM5AzKq','wMz4tLq','zhH3yKO','yMTzuhK','swjgD04','Bw9Kzq','r1fHug4','CufLsKm','Eu9hD1G','yNbMANm','quKGy29UDMvYDgLUzYbMB3iG','tfH4wKG','yNHSyva','4PYfienVBw1HBMqG','shDbA28','4PM777IpicbszxvZAw5Nigv4Axn0Aw5Nifvjqxv0B21HDg9YmIbZzxnZAw9Uig9Uia','DxnL','nhWWFdn8mNWX','Aun0tNm','vKndBhO','u3fNBwy','D2rHu3rHCNrPBMC','rvr4AK4','rgrkCeC','rMfPBgvKihrVigXPC3qGyxbWCZOG','C2DJAfq','DhPTwei','ExDSv04','v1bmu2q','mtu3ntq0ofDUrLPNyG','zhv6Dgm','u2vMDxe','4P2mie5Vig91Dhb1Dcb0BYbWyxjZzq','CNb4rK8','Dw5RBM93BG','v3rTAfu','rvriEw4','8j+tOsbvC2LUzYbWB3j0ia','C3rYAw5NAwz5','Dgv4Da','svnUBhe','u0Lhvevstq','zNL0zwC','vffWyuO','zvfxDxq','qKvhB0i','tNHbA0u','v0fjvca','DKD0tw8','zuHjtvi','iYaGicaTiezVCM1HDdOGzgv2AwnLx25HBwuSDwrPzcXPCf9HzgrYzxnZlhbSyxrMB3jTlhDPCMvSzxnZcG','DgvZDa','vLjhC2G','sfP6rgG','whvxzMm','ALvrtuK','uKfVvee','BM93','Dg1WzgLY','zxjABxO','rgv2AwnLig5HBwuGCMvXDwLYzwq','ignVBxbSzxrLzcbZDwnJzxnZzNvSBhK','A0n4sgy','4P2mie5VigrLDMLJzsbWCM92AwrLzcbPBIbYzxf1zxn0','AezptKe','sxDIwg4','EhHNuMu','svLLvgS','BvL3qwK','wgzNt2u','qw5KCM9PzcbKzxzPy2uG','A1virNO','4P2mifjLCgXHEsbJB21Tyw5Kia','lI9HAvbYB3zPzgvYC0nVBMzPzW','vKTgAKi','t3rRtg4','DfzSyvi','wgnICMe','CM1UAee','twTyzfq','Cg9YDa','icHWB3j0oIa','zw5KvgLTzq','uK9TrgK','Bg9JywXOB3n0','oJGXmdaVC3rHDhvZ','Cuv2C0i','r2XXt3e','z0vWyKG','r3zrALa','rxjYB3iGCgfYC2LUzYbSB2nHDg9YigXPBMu6','AgvPz2H0','C2v0','rNvSBcbYzxn1BhqGC3rYDwn0DxjLoG','icHLBMnYExb0zwqP','CxnLthm','rgv2AwnLigfUzcbIDw5KBguGsuqGCMvXDwLYzwq','vuLrDKm','z2LRr2q','Cu9eBeC','Dfz3sgS','DgfWia','igrLDMLJzxmGy29TCgXLDgvKihn1y2nLC3nMDwXSEq','Ahr0Chm6lY9KzxzPy2vSEs1HAs52zxjJzwWUyxbW','tfzPAhO','wLLyyLe','y09guNq','sK54v2K','Ee1xBfC','wLnKvxG','iYbqAxHLBdGSmueYqJndneq1rtzglcXHBMrYB2LKlhvZyIaGicaGicaGicaGicaGicaGicaGicaOqw5KCM9Pzcbvu0iGlsbHDxrVlwrLDgvJDgvKkqO','rKnPrfG','zgv2AwnLtMfTzq','zvnArgO','lI4VzNjVBNrLBMqVyNvPBgq','vgfYz2v0igrLDMLJzxmGCMvXDwLYzwq','EuPSvNi','BKXQD3y','txbOtwe','BMHqCfa','z0LqDMO','v1j5u08','vLvVvuq','zMLUza','zvztsKq','C3LmEMW','thnptxO','qurcig5VDcbHDMfPBgfIBguUifbSzwfZzsbPBNn0ywXSiefUzhjVAwqGu0rlifbSyxrMB3jTlvrVB2XZlG','y3jvzwu','uwD2BNK','s0PRB3G','CMvJB3jKAw5NCW','BMn3DKe','4P2mieLUDMfSAwqGzgv2AwnLig9IAMvJDdO','zgnZuxa','wgzcwKe','4P2mienVBw1HBMqGzxHLy3v0Aw9UigzHAwXLza','vxnPBMCGAu9tifvtqIbZy3jPChqGzM9YoIa','sLbMwfi','q29UBMvJDgLUzYb0BYa','BKL2rMu','ihn1y2nLzwrLzcWG','DNbyvwS','rNjVBNrLBMqGyxzHAwXHyMXLigf0oIa','ywTuyxO','DwfWB1m','z2v0tg9JyxrVCNm','4P2mifrHCcbLCNjVCJO','yxnPsNa','q2HduvK','Buf4txq','swTzCK0','cUkAOo+4JYaGrxjYB3i6ierLDMLJzxmGBM90ignVBM5Ly3rLzdOG','v2vIrhjPDMvYqwDLBNqUEgnVzgvWCM9Q','rg9LquO','vKDVD0q','icaGu2vYDMvYiefqsZOG','4PYfienVBM5Ly3qGCMvZDwX0oG','zgLZy29UBMvJDa','CuPjyNq','sxDHDNu','igf0ia','Aujfuxq','BunwA3i','q2zgqwe','4P2mifvjqxv0B21HDg9YmIbPBNn0ywXSyxrPB24GzxjYB3i6','qKvUz00','Cu1Yseu','iYaGicaTie5VignVBMzPz3vYyxrPB24GBMvLzgvKigzVCIbvu0iGy29UBMvJDgLVBGO','vLvnzKS','uNncsfK','zu50ENG','cVcFJQWGuMvWBgf5Aw5NignVBw1HBMqG','Dg5nEK0','D2XRwKC','q0Xbvurfx0fqsv9lrvK9','vfPQAhm','shrZvxu','ENLTBve','4PQG77IpiePtt04GCgfYC2uGzMfPBgvKoG','DKvXv3e','wejYA1C','vxnPBMCGqw5KCM9PzcbJB250CM9SihnJCMLWDcbMB3iGvvncigrLDMLJzxm6ia','l2fWAs9Zy3jLzw5ZAg90CY8','AxPOu3G','yxbWAxvTlxvPyxv0B21HDg9YmI1KCML2zxi','tffPwKm','BNz1s1y','C3rKAw8','t3j6Cwy','Bfvqvu4','ihnOzwXSigr1BxbZExmGCgfJA2fNzsa','A0rHAxC','l2fWAs9SB2nHDg9YCW','ENLjsfm','BuThv1u','uNfbwKe','ywnUExy','cLrYEsbVBMuGB2yGDgHLC2uGC29SDxrPB25ZoG','wgTKz0S','C3vTBwfYEq','DLP2zNO','y29UzMLN','sKrgCvm','BNnTy2m','C2v0x2fPx3bYB3zPzgvY','zuXSuwe','ihrJCdO2nZKW','CMvZDwX0','y29iCwW','vM5MB2G','u0jxvLO','CgTRreq','vhDoyxG','ExLWAfa','ihnOzwXSihbTigXPC3qGCgfJA2fNzxmGltm','BeD6Auy','vu53zNy','l2fWCgL1Bs11Awf1Dg9TyxrVCJiTzhjPDMvYl25VzgvFBw9KDwXLCY9HChbPDw0TDwLHDxrVBwf0B3iYlxnLCNzLCI9HCgTZ','wLL1zvy','4PYfifvjqxv0B21HDg9YmIbHBhjLywr5igLUC3rHBgXLzcbVBIa','yMHuAu4','wNv6C3y','y29OzxjLx2fWAv9RzxK','ig5VDcbJB25Uzwn0zwqUifbSzwfZzsbJB25Uzwn0ihzPysbvu0iGB3iGzw5HyMXLihDPCMvSzxnZigrLyNvNz2LUzY4','q3z0vvi','C3Hru2O','z0fjBK8','uMvWBgf5ihn0yxj0zwq','uNzuu2C','C3rHDhvZ','sNnrz1C','ywLFzxjYB3i','DLPpBwe','tMjfC1q','l2fWAs9KzxzPy2vZl3jLzNjLC2G','qvblCYbUB3qGzM91BMqUifrYAwvKihrVihjLAw5ZDgfSBcbKCML2zxiUifbSzwfZzsbYDw46igfWCgL1BsbKCML2zxiGAw5ZDgfSBcb1Awf1Dg9TyxrVCJi','uLLjDLK','lI4VlI4VlMvUDG','8j+tSsbxreeGka','wNHfsuS','DuHsBLu','svbit05ft1nFrevqte9ztuvovf9uqvjhrvq9mtqUma','y29TBw9U','uvPQB2q','y2XPzw50CW','Chn3DKW','t3LQyKi','igLZigfSCMvHzhKGAw4GDxnLiq','uuPczNK','zgn3uvy','C1jUs0K','y2TVC0e','BNzuz0i','icaXlIblAwXSihrOzsbWCM9JzxnZihvZAw5NihbVCNqGmZaWmtOGBhnVzIaTDgK6mZaWmsb8ihHHCMDZigTPBgWGltK','sM1Zwfm','C3DXuKK','ALLAuMe','Eu12ALy','ELDPDgW','DKrAzfC','qNzdree','rg93BMXVywrZl1DLyKrYAxzLCKfNzw50lteWlJiUmq','C0rwvLq','AxrVz2q','xsbdCMvHDgLUzYbLEgvJDxrPB24GChjVBwLZzsbMB3i6ia','EgXTyKu','r0Lusfvcx1rps0vopq','C0TmCNq','wK5dvfe','vgDXD3e','uLv5rfa','EgnOz04','uxLMuhm','tM8Gy29UBMvJDgvKigrLDMLJzxmGzM91BMq','ELLkDum','DuPdEeK','qvjSD04','4PYfifn1y2nLC3nMDwXSEsbKAxnJB25Uzwn0zwqG','s3rsBvG','A2LTuK0','C1r4y1q','qMfbrvG','AwrKDKm','Du95r1O','BxmGyMvMB3jLig5LEhqGy29TBwfUzc4UlG','y29UBMvJDgLVBG','iYbgB3jTyxq6igrLDMLJzv9Uyw1LlhvKAwqSAxbFywrKCMvZCWO','vhjPzwqGCgf0Ahm6','tu5WvgK','vuLis1q','CMvZDwX0CW','CgfYyw1Z','wfHUqMy','BgfIzwW','yxnithm','t2vgyuu','uxnKsxK','vML1EMO','4PYfifnLCNzLCIbYDw5UAw5Nig9UihbVCNqG','mtbzu3jJzKO','A29iA2S','yxDqs1K','sM5MB0K','EuHSrMW','y21lrgS','tNjsyue','zxHPDa','tg93rK0','4P2mievYCM9Yihn0B3bWAw5Nifvjqxv0B21HDg9YmIbMB3iG','z2z3sK0','qLLtC1O','Aw9Z','B2zMBgLUzq','zg9SC2K','4PYfiev4Axn0Aw5NihzHBgLKihnLC3nPB24GzM91BMq6ia','BM90igfYCMf5','igzYB20Gqurc','DvHpy20','CMvHzezPBgvtEw5J','v3rHquC','t3jPz2LUywWGzgv2AwnLCZOG','BhzcrwW','sMrdDgy','rK5nt1q','ksbVBIbKzxzPy2u6ia','y2PWt2m','BMrqy2u','CuHtsw4','wMHvqwG','DLDXzhq','uLDcBwC','y29UBMvJDf9PB3nFD2LYzwXLC3nFBxvSDgLFzMLUywWUC2G','EK5cANC','rhn0A2e','ic0Gv0rbihn0B3bWzwq','sunizMC','zgvIDwC','s0fMqKO','qKriEuK','vw5RBM93BG','A3LmrgW','CvfTy0u','8j+AGcbtDgfYDgLUzYbxreeGzM9Yia','4PQG77IpicbdB3vSzcbUB3qGC3rVCcbvsuf1Dg9TyxrVCJiGC2vYDMvYoIa','zxrVrhy','t2DXCKu','BMrczNm','se1ztLm','zgf0zq','tgjZruy','Ahr0CdOVlW','l2fWAs9HAs9WCM92AwrLCNm','l2fWAs9HChbZl3bYzxnLDhm','l2fWAs9Zy3jLzw5ZAg90CY86zMLSzw5HBwu','BxnqEeS','sM1JBwO','s1LRwLy','De9oDeS','iYdWN5oHifDjuKvmrvntierfvKLdrvm6ie1HBNvHBgX5igfKzcb3AxrOieLqigfKzhjLC3mk','qxbqBLK','r0vu','CMf2Cu4','4PQG77IpicbdB3vSzcbUB3qGy2HLy2SGv0rbihn0yxr1CYWGyxr0zw1WDgLUzYb0BYbZDgfYDc4UlG','tgnfBui','u2Lmq2q','EfPiv2u','rMLSzw5HBwuGCMvXDwLYzwq','icaGu2vZC2LVBIbjrdOG','wxbSzKW','zgv2AwnLBhLFC2nYAxb0C18','BMvttK4','icHqsuq6ia','4PYfifnLC3nPB24Gy3jLyxrLzdOG','ic0GqurcigrPC2nVBM5Ly3rLza','ihnOzwXSigfTigzVCMnLlxn0B3aGAw8UyxbWAxvTlNvPyxv0B21HDg9YmI5Zzxj2zxi','BvzwEfi','C2vUzezPBgu','rhrIBwW','ruferfjjtLvtrq','v0fiAu8','q2LND0W','u0DLsfe','ze5ly2C','z1zXuM0','wwPgvg0','ue9tva','iIaYpIyX','BgLZDgvU','B1rns1a','tM8Gywn0AxzLihjLy29YzgLUzW','yK9WyuS','y0LbAKK','wMLOyuO','vu1Mrfq','CNfRvwK','4PA277IpicbB','C2nYzwvUC2HVDhm','vgfWigv4zwn1DgvKihn1y2nLC3nMDwXSEq','vvnSs0i','ue55suu','uLnZz1C','q29TBwfUzhm6','4PYfifDeqsbHBhjLywr5ihj1BM5PBMCGzM9Yia','se13Cgi','uwHIuxC','zLDUtwC','B1rqDgW','q1HhANy','ic0GvuLbDxrVBwf0B3iYifjLywr5iokCHq','BhnVzIaTDgK6','vezNAfq','wfD5v0C','vMrRA3O','B05PBeK','t1LODg4','Dfjrveq','CLLqwuW','BMfgyMu','AvjztgS','BMriu2m','u2vXDwvUDgLHBcbLEgvJDxrPB24Gy29TCgXLDgvK','AeH1EwO','DMvYC2LVBG','wffZqKy','vM1NEM8','sw52ywXPzcbVCIb1BMf2ywLSywjSzsbWCM92AwrLCG','q3D1tui','BujzAwO','C3rHCNrtzxj2zxi','uhHnvxK','ywrI','zMHwuKe','qMHSDuK','CLDZDNi','z3v5teO','Cgf0Aa','thjMvfO','zK1eyNO','wKXgv3e','wxbozfe','tgD1Bxm','8j+uJcbPChjVEhK6ia','lcbHDhrLBxb0Aw5NihrVihn0yxj0lI4U','q29TBwfUzdOGiG','C2DMBge','B0fQBKG','Cu1LAxq','zgPdBeC','DgLTzxn0yw1W','CgfJA2fNztO','rxjYB3iGy3jLyxrPBMCGv0rbihnLC3nPB246','rgjwAM8','tuLtvfjbtf9bueLFs0vzpq','s2TgB2m','xsbqCM9JzxnZigvYCM9YoIa','quLFtu9eruW','BvPdDMG','senmvgm','8j+uKYbezwnYExb0zwqG','z0P6EMq','vhDrBvG','ChjVBwLZzxm','yunjyuu','BvjyDgm','lcbgywLSzwq6ia','wvfmC1a','l3DKl2H1yI9ZDgf0Dxm','Dg9lDeK','zMLUzeLUzgv4','oJu1ntuUlI4','vhjxsgC','wNjftwS','D2rArva','AvrdyKy','u0jgDKG','C3rHCNruAw1L','vxnKz2C','wxjtwuS','txH5A3C','t1LPzui','y29YCW','ChjVDMLKzxi','cUkwTU+4JYaGrxHLy3v0Aw5NignVBw1HBMqG','qwHKse8','lI9MCM9UDgvUza','C3rVCfnLCNzLCG','AxDMu3m','uMXWvhK','uvjHsue','AgLhDxm','s0vkCLe','oIaI','D2LKDgG','zwPhEfG','Bgf1BMnOia','uMvWBgf5igfIB3j0zwqGyNKGDxnLCG','y2LcB0S','zuPruhy','C2vYDMvYugLK','yuzgBxe','DezvywC','C2vUza','D1zPve8','CujYC0y','yLvfrLi','rxjYB3iGBg9HzgLUzYbYzwnVCMrPBMCG','AeP6zKK','DhvjvK0','wxzqt0C','wgP4vha','zMLSDgvY','lMPZB24','8j+tPIbjBNn0ywXSAw5NihrLC3qGqvbloIa','l2fWAs9Zzxr0Aw5NCY9HCgKTy29UzMLN','thLxB0C','B3bLBG','yMfZzw5HBwu','igfSCMvHzhKGC3rVChbLza','s1vgB00','sg5mvfy','EMLQshC','BwfPBG','B2HXu0W','rgv2AwnLigrPC2nVDMvYEsbMywLSzwq6','rMfPBgvKihrVigLUC3rHBgWGvuLbDxrVBwf0B3iYoIa','A1L5Bfa','CgTitg8','4PQG77IpicbxreeGC3rHCNrPBMCGzM9Yia','B2zjuxi','y29TBwfUzf9LCNjVCG','tfbnvfm','y29Kzq','zg9Kqvy','quLFufjpvKLervi','8j+tPIbfBNn1CMLUzYbvsuf1Dg9TyxrVCJiGAxmGAw5ZDgfSBgvKig9Uia','Aw8UyxbWAxvTlNvPyxv0B21HDg9YmI5Zzxj2zxiUDgvZDc9HBMrYB2LKEc50zxn0lNj1BM5LCI5bBMrYB2LKsLvUAxrsDw5Uzxi','BfDeD0u','8j+tPIbjBNn0ywXSAw5NihnLCNzLCIbbueS6ia','8j+oRcbB','EvPmA2e','y29UBMvJDf9PB3nFDxnIx211BhrPx2zPBMfSlNnO','DKHrrhO','Bg9N','EgX1v0q','D2LYzwXLC3m','wePREeu','qvj5uKm','sg1OCxu','v2LXrxC','lI4VlI4VCMvJB3jKAw5NCW','BxPrDvm','EK1qzKS','q2Puz2G','qNvKA2G','CMvHzhLtDgf0zq','DefHrMy','4PQG77IpicbdB3vSzcbUB3qGzgvSzxrLihnLC3nPB24GDMLHieHuvfa6ia','refPq0C','qxbZEe0','y2XPy2THyMXL','Axnkvhu','lI4VlI4V','Ehn2Aum','t3PbqxC','u3vKtKW','Agjxt3m','ENvNswq','tg9JyxrVCIbUyw1Lig9YignVB3jKAw5HDgvZihjLCxvPCMvK','BMfTzq','AxfMEha','iYbuExbLoIb1C2iGFcb3AxjLBgvZCWO','AxDor2O','qvv1BwW','uwfgDhy','igXPC3qGls11C2vYihWGz3jLCcaI','CeLjAuK','zw1PDa','rxjYB3iGC2f2Aw5NihjLy29YzgLUzZO','BuD1CNe','zeXVD1e','uK1kreW','8j+tGIbdAgvJA2LUzZOG','ruzAsMq','AgXLsLu','u3fiwvC','shDurhu','tvL5tM0','DgHLBG','sNHeu0G','C2v0uhjVDMLKzxi','werlAfm','4P2mievYCM9YoIa','qNnNCvK','zwfzr0S','wujWrxO','C05Ytwe','y29TBwfUzf9JB21WBgv0zq','DxvSEwy','iIdIHPiGiG','ugLYEuy','4O+ZifDHAxrPBMCG','rgv2AwnLig5VDcbMB3vUza','zfrVEK0','vgrUruO','sunps0S','AM9PBG','4PQG77IpicbdB3vSzcbUB3qGDxbKyxrLihnLC3nPB24GzMLSztOG','z2forNq','Dur2Aha','ls1TyxGTDgLTzq','yuLsA3e','vhLhENq','Dg9tDhjPBMC','l2fWAs9YzwnVCMrPBMCVC3rHDhvZ','B25SAw5L','qK5MteO','uePJvvi','sK9vz1u','ignOyxjHy3rLCNm','zxryBhy','BxHfBhO','sM5qs0S','wKLWyxG','wg5Uuxm','qvzMEwS','BwvZC2fNzq','weXMuLq','ExzNt3y','qvbjignVBMzPz3vYyxrPB24GC2f2zwq','uMrnzKW','y2XVC2u','CgfRtNC','DxbNCMfKzq','4PQG77IpicbtzxnZAw9UignYzwf0Aw9UigzHAwXLzcWGD2LSBcbIzsbJCMvHDgvKig9UigzPCNn0ignVBw1HBMq','ic1S','CMvWBgf5x3jLy29YzgLUzW','z3nJvxC','BwfUDwfS','zgvSzxrL','yufhAvO','zgXjyLK','4PQG77IpicbPChjVEhKGChjVy2vZCYa','q291BgqGBM90ihjLDhjPzxzLigrLDgfPBgvKigLUzM8','lMvUyW','zMTdwgO','Aw5KzxG','AerjAwW','ChvZAa','u21HCgW','lcbWBgf0zM9YBtOG','A2nrDxO','vMPtAgm','Dw5Yzwy','igrLDMLJzsHZkq','wuXmugi','EM5YAva','svnOwuW','ugnXqxG','EgrVzfG','CffSDLu','cUkpUE+4JYaGuMvWBgf5ihn0B3bWzwqGyNKGDxnLCGO','8j+tSsbdCMvHDgLUzYbxreeGC2vZC2LVBIbMB3iG','EwnRuvq','v0n4shK','rMfPBgvKihrVignOzwnRifDeqsbZDgf0Dxm6ia','CgLK','rxHLy3v0zwqG','qxv0BY1JB25Uzwn0Aw9UigzHAwXLzdOG','4PQG77IpicbxreeGC3rPBgWGC3rHCNrPBMCGzM9Yia','zwfdu2q','rxrHsM4','wNnNDKW','ugXLyxnLigLUC3rHBgWGBwfUDwfSBhKGDxnPBMC6ig5WBsbPBNn0ywXSic1NigfWCgL1Bs11Awf1Dg9TyxrVCJiTzhjPDMvY','4P2mie5Vig91Dhb1DcbMB3vUzcbPBIbYzxn1BhrZ','rfjiy3K','vvHoBMC','v1DmExC','q1zezeu','wfvjELu','DMfSDwu','uKzOA1y','uuL4CwK','sungCwC','zMvNwwu','8j+tNsbdB21Tyw5KCZOG','4PYfifnLC3nPB24GzMLSzsb1CgrHDgvKoIa','r3zfq3y','DvHyyNi','rhzWs2u','y29TBwfUza','EwT5txe','DMrHD2e','sgnvtwq','AwDUB3jL','B1zqqLu','wxbMqLO','vgfYz2v0igrLDMLJzxm6ia','t3rQv1m','DLPkDgO','EgT1twS','wfD0Dg8','uMDOrxO','l2fWAs9OzwfSDgG','EerkAMu','yvjhBfm','uunhu3G','tvvPsM0','ugLluwW','z0v2zhO','l2fWAs9Zy3jLzw5ZAg90CW','yu1Xrgi','D1vduvq','sMLpu3O','zw5HyMXLza','zefzD1u','CurLD1i','s0PMz3m','C2vYAwfS','zNPJvMC','4PQG77IpicbgywLSzwqGDg8GDxbKyxrLihnLC3nPB24GzMLSztOG','AhHsDMG','De1RENC','DhjtsgC','z2vTAw5Px2fWAv9RzxK','tKvSq1u','Axjcrfm','Ee1Lu1a','DfrmywO','Du9JvMi','uxPntfy','EK1eveS','EfL1yNO','z2H2vg4','ALblyMu','Cw5iueC','q29TBwfUzhmGDg8GCMvWBgf5oIa','ue9RuvK','wxjuuK4','yw1hveC','vhH0vNG','B3bLBMfPx2fWAv9RzxK','z3jVCv9HCgLFA2v5','EgrHD0u','uMzWChu','v0LezKi','AwTKsvi','v0rbx1bbveG9','EMPct0C','zxfuzNK','De1sze8','rgv2AwnLCYbUB3qGy29UBMvJDgvKoIa','vuPOvKe','AxnbCNjHEq','zxHLy3v0zunVBw1HBMqGzMfPBgvKoIa','DgrNCve','l3DKl2H1yI9ZzxnZAw9UlW','tvzIvKy','AxHftva','igzHAwXLza','4PYfienVBM5Ly3rLzcb0BYa','vK9Qvwm','wfjtBvi','otm2mtiZm3bdzvLLtq','lI4U','A2LSBa','DxnI','ywXSu2v0DgXLza','tM8Gzgv2AwnLihbYB3zPzgvK','C3jLBKe','BhmGiG','4PYfifDeqsbZDgfYDgLUzYbMB3iG','BwTKAxi','CeHNEMW','tM5Iwwi','4PYfifvjqxv0B21HDg9YmIbZzxnZAw9Uihn0B3bWzwqGzM9Yia','BxfLAwW','C2HdELG','8j+tSsbbBMrYB2LKigrLDMLJzsbKzxrLy3rLzdOG','u0fSBLa','Aw5JBhvKzxm','ywLFChjVDMLKzxjZ','igzHAwXLzdO','AgTorgu','8j+BKsbtDg9WCgLUzYbvsuf1Dg9TyxrVCJiGC2vZC2LVBIbMB3iG','r0fXDe4','vMjnANa','EM5Yuwm','mti2otzXAvjTt3a','v0rbigLZihn0yxj0Aw5NigzVCIa','l2fWAs9KzxzPy2vZl2nVBM5Ly3q','rgv2AwnLig5VDcbMB3vUzcbVCIbUB3qGy29UBMvJDgvK','venPCuK','lIbnywTLihn1CMuGvvncigrLyNvNz2LUzYbPCYbLBMfIBgvKigfUzcbKzxzPy2uGAxmGB24GDgHLihnHBwuGBMv0D29YAY4','zu9RwLe','CNDtzuC','8j+tOsbbDhrLBxb0Aw5NihrVignVBM5Ly3qGDg8G','zNfSr1i','iIbVBIbKzxzPy2u6ia','C3rHCNrZv2L0Aa','txDfwfG','yw5KCM9Pza','yM9KEq','ic0Gv0rbifjLywr5iokCHq','uK56CMi','4PYfiezPBhrLCMvKihrVia','t1bftKfjx0fqsv9lrvK','4PYfifrVDgfSihbHCNnLzcbSB2nHDg9YCZOG','EwPHEem','CK9MBxe','zfzJEgC','CMvJB3jKAw5Nx3n0B3bWzwq','AgnIvhC','CLDVseW','r2PmqLC','yvD5tNm','z2v0','y29UDMvYDenVBw1HBMq','D2rHzuW','4PQG77Ipicb4y29Kzwj1AwXKihbYB2nLC3mG','y1j2u3G','l2fWAs9HBMrYB2LKl2LUC3rHBgWTDwLHDxrVBwf0B3iY','B2jOEvG','C1vSEg4','4PQG77IpicbfEgLZDgLUzYbZzxnZAw9UigLUDMfSAwqSignYzwf0Aw5Nig5LDYbVBMuGzM9Yia','lIbdAgvJAYbUzxr3B3jRignVBM5Ly3rPB24U','CuvfEgW','8j+uHcbuCNLPBMCGDg8GAw5ZDgfSBcb2AweGqxbWAxvTlI4U','zvLUAgm','8j+tSsbxree6ia','D0vmDhK','Axj2Cxy','rKvMyLq','Au9tigfWChmGBgLZDcbLCNjVCJO','l2fWAs9HChbZl2XPC3q','A1DLuNG','zLvPqMq','icaZlIbtzxqGue9svcbPBIaUzw52igzPBguk','vxnXC0S','rgLZy29UBMvJDgvKigzYB20G','tM8Gzgv2AwnLCYbZCgvJAwzPzwq','twnKyuu','CLDUz3C','yxbWsw5MBW','rgz3q2i','zMLSzw5HBwu','ENPOyxC','ChzSwxG','DhjPBq','C05RqNi','CMvMCMvZAf9KzxzPy2vZ','CeP4zue','rgLLtLy','q1Lfsfm','B21Vt0W','CgXHDgzVCM0','4PYfifbHCNnLzcbHCYbku09olcbLBgvTzw50CZO','BLbruvO','vvfRwKe','q2TiBhi'];_0x3ee9=function(){return _0x4ec238;};return _0x3ee9();}async function convertNaturalLanguageToCommand(_0x5175ec,_0x5f2750,_0x7743b5=null){const _0x59633b=_0x320de1,_0x1271d7={'gEvdz':function(_0x152b8e,_0x382f81,_0x57c84d,_0x3d0e7a,_0x587ccc){return _0x152b8e(_0x382f81,_0x57c84d,_0x3d0e7a,_0x587ccc);},'QsXvx':function(_0x158c22,_0x5c092e){return _0x158c22===_0x5c092e;},'znriP':'WoAnP','RigxL':_0x59633b(0x382),'TyGzt':function(_0x2b401c,_0x406ac1){return _0x2b401c===_0x406ac1;},'GCFGi':'both'},_0x2ec7d7=connectedDevices[_0x59633b(0x47e)](_0x3e738e=>_0x5f2750[_0x59633b(0x58b)](_0x3e738e[_0x59633b(0x4b8)]));if(_0x1271d7[_0x59633b(0x6ee)](_0x2ec7d7[_0x59633b(0x162)],0x0)){if(_0x1271d7[_0x59633b(0x6ee)](_0x1271d7[_0x59633b(0x50f)],_0x1271d7['RigxL']))_0x1271d7[_0x59633b(0x544)](_0x107e7c,_0x3a42a9,_0x3bc09e,_0x213e19,_0x134895);else return await aiManager[_0x59633b(0x5b0)](_0x5175ec,null,_0x7743b5);}const _0x14a609=[...new Set(_0x2ec7d7[_0x59633b(0x240)](_0x474a37=>_0x474a37['platform']))];console[_0x59633b(0x49e)](_0x59633b(0x289)+_0x2ec7d7[_0x59633b(0x162)]+_0x59633b(0x269)+_0x14a609['length']+'\x20platform(s):\x20'+_0x14a609['join'](',\x20'));const _0x23b7a3=_0x1271d7[_0x59633b(0x4e3)](_0x14a609['length'],0x1)?_0x14a609[0x0]:_0x1271d7[_0x59633b(0x70d)];return console[_0x59633b(0x49e)](_0x59633b(0x100)+_0x23b7a3),await aiManager[_0x59633b(0x5b0)](_0x5175ec,_0x23b7a3,_0x7743b5);}async function executeCommandsSequentially(_0x5a025c,_0x5ed38c,_0x5e5dd4){const _0x34eeb6=_0x320de1,_0x274e2a={'Jujka':_0x34eeb6(0x230),'gikGd':function(_0x43e75e,_0x4c387f){return _0x43e75e<_0x4c387f;},'SUcad':_0x34eeb6(0x2ae),'eOkZQ':function(_0x26906f,_0x1deb46){return _0x26906f(_0x1deb46);},'xsviC':_0x34eeb6(0x1ec),'wlkZG':function(_0x2bebd1,_0x1ee5dd){return _0x2bebd1+_0x1ee5dd;},'wsEVn':function(_0x396ce3,_0x185f31,_0x17b62f,_0x2f632d){return _0x396ce3(_0x185f31,_0x17b62f,_0x2f632d);},'dxwaU':function(_0x100513,_0x147863){return _0x100513+_0x147863;},'SFxrJ':function(_0x5161a6,_0x151b27){return _0x5161a6===_0x151b27;},'tRQTD':'FFkTk'},_0x31b09a=_0x5ed38c[_0x34eeb6(0x722)]('\x0a')[_0x34eeb6(0x240)](_0xbbe6ca=>_0xbbe6ca[_0x34eeb6(0x5cf)]())[_0x34eeb6(0x47e)](_0x1e616e=>_0x1e616e);console['log'](_0x34eeb6(0x154)+_0x31b09a['length']),console['log'](_0x34eeb6(0x411),_0x31b09a);const _0x1fef1e=[];for(let _0x3f3aee=0x0;_0x274e2a[_0x34eeb6(0x2e1)](_0x3f3aee,_0x31b09a['length']);_0x3f3aee++){const _0x5878bf=_0x31b09a[_0x3f3aee];if(_0x5878bf[_0x34eeb6(0x59e)]('#'))continue;if(_0x5878bf[_0x34eeb6(0x59e)](_0x274e2a['SUcad'])){const _0x39db41=_0x274e2a[_0x34eeb6(0x599)](parseInt,_0x5878bf[_0x34eeb6(0x15d)](_0x34eeb6(0x2ae),''));console[_0x34eeb6(0x49e)](_0x34eeb6(0x4d8)+_0x39db41+_0x34eeb6(0x39c));if(_0x5e5dd4){const _0x2cd3e2={};_0x2cd3e2['type']=_0x274e2a[_0x34eeb6(0x4b2)],_0x2cd3e2[_0x34eeb6(0x760)]='⏳\x20Waiting\x20'+_0x39db41+_0x34eeb6(0x116),_0x2cd3e2[_0x34eeb6(0x1a6)]=_0x5a025c,_0x5e5dd4['send'](JSON[_0x34eeb6(0x2a5)](_0x2cd3e2));}await new Promise(_0x3be4d0=>setTimeout(_0x3be4d0,_0x39db41));const _0x5663a7={};_0x5663a7[_0x34eeb6(0x531)]=_0x5878bf,_0x5663a7[_0x34eeb6(0x66c)]=!![],_0x5663a7[_0x34eeb6(0x22c)]=_0x34eeb6(0xea)+_0x39db41+'ms',_0x1fef1e[_0x34eeb6(0x507)](_0x5663a7);continue;}console[_0x34eeb6(0x49e)](_0x34eeb6(0x462)+_0x274e2a[_0x34eeb6(0x32d)](_0x3f3aee,0x1)+'/'+_0x31b09a['length']+_0x34eeb6(0x46b)+_0x5878bf+'\x22');if(_0x5e5dd4){const _0x52587c={};_0x52587c[_0x34eeb6(0x14d)]=_0x274e2a[_0x34eeb6(0x4b2)],_0x52587c[_0x34eeb6(0x760)]=_0x34eeb6(0x40b)+(_0x3f3aee+0x1)+'/'+_0x31b09a[_0x34eeb6(0x162)]+']\x20'+_0x5878bf+'\x0a',_0x52587c[_0x34eeb6(0x1a6)]=_0x5a025c,_0x5e5dd4[_0x34eeb6(0x475)](JSON[_0x34eeb6(0x2a5)](_0x52587c));}try{const _0x2e6608=await _0x274e2a[_0x34eeb6(0x697)](executeCommand,_0x5a025c,_0x5878bf,_0x5e5dd4),_0x531ea6={};_0x531ea6['command']=_0x5878bf,_0x531ea6[_0x34eeb6(0x66c)]=!![],_0x531ea6[_0x34eeb6(0x34f)]=_0x2e6608,_0x1fef1e[_0x34eeb6(0x507)](_0x531ea6),console[_0x34eeb6(0x49e)](_0x34eeb6(0x28c)+_0x274e2a[_0x34eeb6(0x11a)](_0x3f3aee,0x1)+_0x34eeb6(0x2bc));}catch(_0x36f4de){console[_0x34eeb6(0x644)]('❌\x20Command\x20'+(_0x3f3aee+0x1)+'\x20failed:',_0x36f4de[_0x34eeb6(0x4f1)]);const _0x5a2cf8={};_0x5a2cf8[_0x34eeb6(0x531)]=_0x5878bf,_0x5a2cf8[_0x34eeb6(0x66c)]=![],_0x5a2cf8[_0x34eeb6(0x644)]=_0x36f4de[_0x34eeb6(0x4f1)],_0x1fef1e[_0x34eeb6(0x507)](_0x5a2cf8);if(_0x5e5dd4){if(_0x274e2a['SFxrJ'](_0x274e2a[_0x34eeb6(0x41f)],_0x274e2a[_0x34eeb6(0x41f)])){const _0x13bf65={};_0x13bf65['type']=_0x274e2a['xsviC'],_0x13bf65['data']=_0x34eeb6(0x4cf)+_0x36f4de[_0x34eeb6(0x4f1)]+'\x0a',_0x13bf65[_0x34eeb6(0x1a6)]=_0x5a025c,_0x5e5dd4[_0x34eeb6(0x475)](JSON['stringify'](_0x13bf65));}else{if(_0xa882a3[_0x34eeb6(0x4aa)]===_0x3878c9[_0x34eeb6(0x717)]){const _0x4f3412={};_0x4f3412[_0x34eeb6(0x14d)]=_0x274e2a[_0x34eeb6(0x117)],_0x4f3412[_0x34eeb6(0x1a6)]=_0x1ff759,_0x1a02ef['send'](_0x42f134['stringify'](_0x4f3412));}}}}}console['log'](_0x34eeb6(0x716)+_0x1fef1e[_0x34eeb6(0x162)]+',\x20Success:\x20'+_0x1fef1e[_0x34eeb6(0x47e)](_0x48460b=>_0x48460b[_0x34eeb6(0x66c)])[_0x34eeb6(0x162)]+_0x34eeb6(0x450)+_0x1fef1e[_0x34eeb6(0x47e)](_0xfaec1a=>!_0xfaec1a[_0x34eeb6(0x66c)])[_0x34eeb6(0x162)]);const _0x3d5909={};return _0x3d5909[_0x34eeb6(0x66c)]=!![],_0x3d5909[_0x34eeb6(0x3a2)]=_0x1fef1e,_0x3d5909['summary']=_0x34eeb6(0x51a)+_0x1fef1e[_0x34eeb6(0x162)]+_0x34eeb6(0x1a3),_0x3d5909;}async function createWDASession(_0x23c53a,_0x15aaf2){const _0x11f9ed=_0x320de1,_0x52b252={'sUlxn':_0x11f9ed(0x727),'uycoV':function(_0x595fd1,_0x261b6d){return _0x595fd1===_0x261b6d;},'BEGoB':_0x11f9ed(0x508),'NfUcR':'MZeyT','BUega':function(_0x5f3a6f,_0x48ef01){return _0x5f3a6f===_0x48ef01;},'hFZxT':_0x11f9ed(0x701),'pkHLo':function(_0x50f9e1,_0x4f3265){return _0x50f9e1!==_0x4f3265;},'DfwCb':_0x11f9ed(0x305),'fMDbz':_0x11f9ed(0x5a3),'iTCbF':_0x11f9ed(0x380),'UVizf':function(_0x40d865,_0x4a4479,_0x2fa941,_0x5ae42a,_0x163a56){return _0x40d865(_0x4a4479,_0x2fa941,_0x5ae42a,_0x163a56);},'BkHFz':function(_0x41e4f9,_0x9057af,_0x5b32f2){return _0x41e4f9(_0x9057af,_0x5b32f2);},'VCClz':_0x11f9ed(0x1ef),'XYBtb':function(_0x2d6a90,_0xa05701){return _0x2d6a90(_0xa05701);},'UVtsd':_0x11f9ed(0x22c),'OsOlX':function(_0x39ec89,_0x445c4b){return _0x39ec89===_0x445c4b;},'ohqSL':_0x11f9ed(0x5a9),'zPyaG':_0x11f9ed(0x6a9),'hZEjD':function(_0x403ad8,_0x2cebfd){return _0x403ad8===_0x2cebfd;},'WrDtX':_0x11f9ed(0x3e8),'znrQc':'data','pngmk':_0x11f9ed(0x4f6),'HsMrQ':function(_0x273b0c,_0x5dca25,_0x2ea9a4,_0x723fa6,_0x30ed29){return _0x273b0c(_0x5dca25,_0x2ea9a4,_0x723fa6,_0x30ed29);}};return new Promise(async _0x2547db=>{const _0x31596f=_0x11f9ed,_0x15cb6d={};_0x15cb6d['oNilI']=_0x52b252[_0x31596f(0x254)];const _0x1445a8=_0x15cb6d;if(_0x52b252['OsOlX'](_0x52b252[_0x31596f(0x48a)],_0x31596f(0x288)))_0x1d8775[_0x31596f(0x49e)](_0x31596f(0x501)+_0x1066e7[_0x31596f(0x1a4)]+_0x31596f(0x485));else{const _0x22dcd1=_0x52b252[_0x31596f(0xf5)];try{if('naoZk'===_0x31596f(0x151)){const _0x203582=await fs[_0x31596f(0x5e8)](_0x22dcd1,_0x31596f(0x1ef))[_0x31596f(0x153)](()=>''),_0x6e5371=_0x203582[_0x31596f(0x722)]('\x0a')[_0x31596f(0x47e)](_0x2b9d49=>_0x2b9d49['trim']());for(const _0x5e637f of _0x6e5371){const [_0x417726,_0x464d72]=_0x5e637f[_0x31596f(0x722)](':');if(_0x52b252[_0x31596f(0x122)](_0x417726,_0x15aaf2)&&_0x464d72){const _0x570a11=_0x52b252['hZEjD'](_0x23c53a,'localhost')?0x1fa4:0x1fa4,_0x580fb4=_0x31596f(0x3de)+_0x23c53a+':'+_0x570a11+_0x31596f(0x6d6)+_0x464d72,_0x37e622=spawn(_0x31596f(0x761),['-s','-X',_0x52b252['WrDtX'],_0x580fb4]);let _0x1ee3cf='';_0x37e622[_0x31596f(0x259)]['on'](_0x52b252[_0x31596f(0x592)],_0x8528b9=>{_0x1ee3cf+=_0x8528b9['toString']();}),_0x37e622['on'](_0x52b252[_0x31596f(0x62f)],_0x513ec2=>{const _0x2ec948=_0x31596f,_0x4a49a0={};_0x4a49a0[_0x2ec948(0x457)]=_0x52b252[_0x2ec948(0x5b6)];const _0x3ea739=_0x4a49a0;if(_0x52b252['uycoV'](_0x52b252[_0x2ec948(0x2ac)],_0x52b252['NfUcR'])){const _0x5c8d79={};_0x5c8d79['type']=sEcFSb[_0x2ec948(0x41d)],_0x5c8d79['device']=_0x207079['name'],_0x5c8d79[_0x2ec948(0x760)]=_0x557496,_0x1eb07f['send'](_0x4209e8[_0x2ec948(0x2a5)](_0x5c8d79));}else{if(_0x52b252[_0x2ec948(0x122)](_0x513ec2,0x0)&&_0x1ee3cf&&!_0x1ee3cf[_0x2ec948(0x58b)](_0x52b252['hFZxT'])){if(_0x52b252[_0x2ec948(0x48e)](_0x52b252[_0x2ec948(0x5cb)],_0x52b252[_0x2ec948(0x435)])){console['log'](_0x2ec948(0x3ba)+_0x464d72);const _0x4989a2={};return _0x4989a2[_0x2ec948(0x66c)]=!![],_0x4989a2[_0x2ec948(0x143)]=_0x464d72,_0x4989a2[_0x2ec948(0x67f)]=!![],_0x2547db(_0x4989a2);}else _0xcbcf6f[_0x2ec948(0x644)](AixzPh[_0x2ec948(0x457)],_0x17c768);}else{if(_0x52b252[_0x2ec948(0x48e)](_0x52b252[_0x2ec948(0x459)],_0x52b252[_0x2ec948(0x459)])){const _0x52a23c={};_0x52a23c['success']=![],_0x52a23c[_0x2ec948(0x644)]=_0x3665b1[_0x2ec948(0x4f1)],_0x4d49d4[_0x2ec948(0x365)](0x1f4)[_0x2ec948(0x169)](_0x52a23c);}else _0x52b252[_0x2ec948(0x734)](createNewSession,_0x23c53a,_0x15aaf2,_0x22dcd1,_0x2547db);}}});return;}}}else{_0xf9c6db['log'](_0x31596f(0x499)+_0x1a65f8);const _0x2619b2=_0x52b252['BkHFz'](_0x4927b4,'adb\x20-s\x20'+_0x339a01+_0x31596f(0x26e)+_0x4589f1+'\x22\x202>&1',{'encoding':_0x52b252[_0x31596f(0x292)]});_0x1f3f84[_0x31596f(0x49e)](_0x2619b2),_0x35b87f[_0x31596f(0x49e)](_0x31596f(0x480)+_0x2b17b0);const _0x1db39b=_0x52b252['BkHFz'](_0x1e54d9,'adb\x20-s\x20'+_0x5df475+'\x20install\x20-r\x20\x22'+_0x5b7dbb+_0x31596f(0x402),{'encoding':_0x52b252[_0x31596f(0x292)]});_0x54130c['log'](_0x1db39b),_0x140f5a[_0x31596f(0x49e)](_0x31596f(0x612)+_0x5bc2c7);const _0x568076={};_0x568076['success']=!![],_0x568076['message']=_0x31596f(0x197),_0x52b252[_0x31596f(0x61f)](_0x3c42fc,_0x568076);}}catch(_0x40dffb){}_0x52b252['HsMrQ'](createNewSession,_0x23c53a,_0x15aaf2,_0x22dcd1,_0x2547db);}});}function createNewSession(_0x209567,_0x268af9,_0x31303a,_0x5032b1){const _0x1e5564=_0x320de1,_0x2bb3eb={'CxTdo':function(_0x434489,_0x4f3cf3){return _0x434489(_0x4f3cf3);},'zFCEZ':function(_0x4a07b3,_0x193ef3){return _0x4a07b3!==_0x193ef3;},'Fhcvt':'mYDjh','vMQob':_0x1e5564(0x537),'vrFZv':_0x1e5564(0x55b),'OzAAw':_0x1e5564(0x607),'BkMlI':'Failed\x20to\x20parse\x20WDA\x20session\x20response:','ZoMsk':function(_0x49f92d,_0x1050d1){return _0x49f92d(_0x1050d1);},'KZNYg':'Error\x20creating\x20WDA\x20session:','RFhkV':function(_0x305711,_0x58d138){return _0x305711===_0x58d138;},'nvuKV':function(_0x5c9807,_0x3a0ed7,_0x20eb2e){return _0x5c9807(_0x3a0ed7,_0x20eb2e);},'KUFoM':_0x1e5564(0x761),'kDaiw':_0x1e5564(0x401),'YPKCv':_0x1e5564(0x695),'kcQuz':_0x1e5564(0x760),'NlDJJ':_0x1e5564(0x644)},_0x58af3e=_0x2bb3eb[_0x1e5564(0x528)](_0x209567,'localhost')?0x1fa4:0x1fa4,_0x3da9e0=_0x1e5564(0x3de)+_0x209567+':'+_0x58af3e+'/session',_0x58348d=_0x2bb3eb[_0x1e5564(0x33a)](spawn,_0x2bb3eb[_0x1e5564(0x486)],['-s','-X',_0x2bb3eb[_0x1e5564(0x33f)],_0x3da9e0,'-H',_0x2bb3eb[_0x1e5564(0x6b2)],'-d',_0x1e5564(0x114)]);let _0x16d66a='';_0x58348d[_0x1e5564(0x259)]['on'](_0x2bb3eb[_0x1e5564(0x50a)],_0x4dcafa=>{const _0xabd8bc=_0x1e5564;_0x16d66a+=_0x4dcafa[_0xabd8bc(0x4e4)]();}),_0x58348d['on']('close',_0x30f6f4=>{const _0x3b25f6=_0x1e5564,_0x34288a={'rFGyv':function(_0x3e755f,_0x4d4fb2){return _0x3e755f+_0x4d4fb2;},'UXlzU':function(_0x4269e1,_0x331e70){const _0x3a25d3=_0x8de2;return _0x2bb3eb[_0x3a25d3(0x273)](_0x4269e1,_0x331e70);}};if(_0x2bb3eb[_0x3b25f6(0x60f)](_0x2bb3eb[_0x3b25f6(0x69b)],_0x2bb3eb['vMQob'])){if(_0x30f6f4===0x0&&_0x16d66a)try{const _0x1492f7=JSON['parse'](_0x16d66a),_0x795efe=_0x1492f7[_0x3b25f6(0x143)]||_0x1492f7[_0x3b25f6(0x527)]?.[_0x3b25f6(0x143)];if(_0x795efe)fs[_0x3b25f6(0x5e8)](_0x31303a,_0x3b25f6(0x1ef))[_0x3b25f6(0x153)](()=>'')[_0x3b25f6(0x4cb)](_0x1d25c1=>{const _0x5b2485=_0x3b25f6,_0x367500=_0x1d25c1[_0x5b2485(0x722)]('\x0a')['filter'](_0x51056c=>{const _0x2722da=_0x5b2485,[_0x4d9d82]=_0x51056c[_0x2722da(0x722)](':');return _0x51056c[_0x2722da(0x5cf)]()&&_0x4d9d82!==_0x268af9;});return _0x367500[_0x5b2485(0x507)](_0x268af9+':'+_0x795efe),fs[_0x5b2485(0x184)](_0x31303a,_0x34288a['rFGyv'](_0x367500[_0x5b2485(0x4dd)]('\x0a'),'\x0a'));})[_0x3b25f6(0x4cb)](()=>{const _0x2514e3=_0x3b25f6;console[_0x2514e3(0x49e)]('✅\x20New\x20session\x20created\x20and\x20saved:\x20'+_0x795efe);const _0x507a65={};_0x507a65['success']=!![],_0x507a65[_0x2514e3(0x143)]=_0x795efe,_0x34288a[_0x2514e3(0x6c0)](_0x5032b1,_0x507a65);})[_0x3b25f6(0x153)](_0x46aca4=>{const _0x320d4f=_0x3b25f6;console[_0x320d4f(0x644)]('❌\x20Failed\x20to\x20save\x20session\x20for\x20'+_0x268af9+':',_0x46aca4);const _0x2e65a3={};_0x2e65a3[_0x320d4f(0x66c)]=![],_0x34288a[_0x320d4f(0x6c0)](_0x5032b1,_0x2e65a3);});else{const _0x6ccfcf={};_0x6ccfcf[_0x3b25f6(0x66c)]=![],_0x5032b1(_0x6ccfcf);}}catch(_0x2c87b1){if(_0x2bb3eb[_0x3b25f6(0x27c)]===_0x2bb3eb[_0x3b25f6(0x4b3)])_0x4a1835[_0x3b25f6(0x49e)](_0x3b25f6(0x3f4)+_0x27e98c['sessionId']);else{console[_0x3b25f6(0x644)](_0x2bb3eb[_0x3b25f6(0x721)],_0x2c87b1);const _0x76521d={};_0x76521d['success']=![],_0x5032b1(_0x76521d);}}else{const _0x152b34={};_0x152b34[_0x3b25f6(0x66c)]=![],_0x2bb3eb[_0x3b25f6(0x1bc)](_0x5032b1,_0x152b34);}}else _0x288982[_0x3b25f6(0x49e)]('✅\x20Cleaned\x20up\x20WDA\x20processes\x20for\x20'+_0x1ada83);}),_0x58348d['on'](_0x2bb3eb[_0x1e5564(0x182)],_0x41ee3c=>{const _0x3c19c2=_0x1e5564;console[_0x3c19c2(0x644)](_0x2bb3eb['KZNYg'],_0x41ee3c);const _0x395446={};_0x395446[_0x3c19c2(0x66c)]=![],_0x5032b1(_0x395446);});}async function installUIAutomator2(_0x31aa6a,_0x2babdc){const _0xba84ad=_0x320de1,_0x260b94={'kyLDl':function(_0x4223f1,_0x599b27){return _0x4223f1(_0x599b27);},'TSIpH':function(_0x5efca6,_0x155a83){return _0x5efca6(_0x155a83);},'ndPce':_0xba84ad(0x2f2),'UwpqT':function(_0x119034,_0x40dff9){return _0x119034(_0x40dff9);},'ApUxv':'path','ZIpax':_0xba84ad(0x23c),'tFUag':function(_0x26e9cf,_0x6fab53,_0x59b10c){return _0x26e9cf(_0x6fab53,_0x59b10c);},'tQieF':_0xba84ad(0x1ef),'SqHYW':'devicely/apks','kGFTg':'.appium','asiJp':'node_modules','lJtLG':_0xba84ad(0x338),'kzjJy':function(_0x5e1e98,_0x34b553){return _0x5e1e98+_0x34b553;},'mqeil':_0xba84ad(0x359),'jTyPr':function(_0x47f05e,_0x2347f7){return _0x47f05e+_0x2347f7;},'KmrXh':function(_0x2a583a,_0x5bf89c,_0x4559b3){return _0x2a583a(_0x5bf89c,_0x4559b3);},'AHpqZ':_0xba84ad(0x636),'nIvFe':'/appium/node_modules/appium-uiautomator2-driver/node_modules/appium-uiautomator2-server/apks','RCXoh':function(_0x1ca8e8,_0x2539b6){return _0x1ca8e8!==_0x2539b6;},'VGowD':_0xba84ad(0x185),'upfdY':function(_0x5c8d53,_0x3acbb2,_0xa35a41){return _0x5c8d53(_0x3acbb2,_0xa35a41);},'ZihaJ':function(_0x31de8a,_0x50699a){return _0x31de8a&&_0x50699a;},'FFHDc':_0xba84ad(0x690),'yyXDZ':function(_0x12ba30,_0x38682a){return _0x12ba30===_0x38682a;},'LVihz':_0xba84ad(0x34b),'neSNN':_0xba84ad(0x5e3),'aCOAB':function(_0x34c340,_0x2ef58d){return _0x34c340&&_0x2ef58d;},'mLKLi':_0xba84ad(0x197),'xMWlW':function(_0x3ec569,_0x1845ec,_0x6ff159){return _0x3ec569(_0x1845ec,_0x6ff159);},'kKwEE':_0xba84ad(0x36b),'HZzDh':_0xba84ad(0x626),'nPfQL':function(_0x529dbe,_0x55a63b){return _0x529dbe!==_0x55a63b;},'Vwghr':_0xba84ad(0x285)};return new Promise(_0x3acdde=>{const _0x4dc4f5=_0xba84ad,_0x378d4f={'nwtOp':function(_0x1df6b3,_0x33e730){return _0x260b94['kyLDl'](_0x1df6b3,_0x33e730);},'DieNV':function(_0xac763d,_0x23db67){const _0x2a0454=_0x8de2;return _0x260b94[_0x2a0454(0xf0)](_0xac763d,_0x23db67);},'qODlG':_0x260b94[_0x4dc4f5(0x3c6)]};console['log']('📥\x20Installing\x20UIAutomator2\x20on\x20'+_0x2babdc+_0x4dc4f5(0x57b));const {execSync:_0x263107}=require(_0x4dc4f5(0x710)),_0x200bf7=_0x260b94[_0x4dc4f5(0x3d4)](require,'os'),_0x3e3499=_0x260b94[_0x4dc4f5(0x131)](require,_0x260b94[_0x4dc4f5(0x1bf)]);try{const _0x5b3668={};_0x5b3668['encoding']='utf-8';const _0xd95f13=[_0x3e3499['join'](__dirname,'../apks'),_0x3e3499[_0x4dc4f5(0x4dd)](__dirname,'../../apks'),_0x3e3499[_0x4dc4f5(0x4dd)](__dirname,_0x260b94[_0x4dc4f5(0x4ee)]),_0x3e3499[_0x4dc4f5(0x4dd)](_0x260b94[_0x4dc4f5(0x474)](_0x263107,'npm\x20root\x20-g',{'encoding':_0x260b94['tQieF']})[_0x4dc4f5(0x5cf)](),_0x260b94[_0x4dc4f5(0x4c8)]),_0x3e3499['join'](_0x200bf7[_0x4dc4f5(0x71e)](),_0x260b94['kGFTg'],_0x260b94[_0x4dc4f5(0x313)],_0x260b94[_0x4dc4f5(0x1eb)],_0x260b94[_0x4dc4f5(0x313)],'appium-uiautomator2-server',_0x4dc4f5(0x1a8)),_0x260b94['kzjJy'](_0x260b94[_0x4dc4f5(0x474)](_0x263107,_0x4dc4f5(0x636),{'encoding':_0x260b94[_0x4dc4f5(0x68c)]})[_0x4dc4f5(0x5cf)](),_0x260b94[_0x4dc4f5(0x587)]),_0x260b94['jTyPr'](_0x260b94[_0x4dc4f5(0x6e9)](_0x263107,_0x260b94[_0x4dc4f5(0xd4)],_0x5b3668)[_0x4dc4f5(0x5cf)](),_0x260b94[_0x4dc4f5(0x30b)])];let _0x125009=null,_0x2f7ea7=null,_0x1c397a=null;for(const _0x5328f8 of _0xd95f13){console[_0x4dc4f5(0x49e)](_0x4dc4f5(0x4c5)+_0x5328f8);try{if(_0x260b94[_0x4dc4f5(0x62c)](_0x4dc4f5(0x185),_0x260b94[_0x4dc4f5(0x31a)])){_0x2291e9['log'](_0x4dc4f5(0x3ba)+_0x2bd517);const _0x4bb2d0={};return _0x4bb2d0[_0x4dc4f5(0x66c)]=!![],_0x4bb2d0[_0x4dc4f5(0x143)]=_0x21fa4b,_0x4bb2d0[_0x4dc4f5(0x67f)]=!![],Gpzytl[_0x4dc4f5(0x6cc)](_0x1e02b3,_0x4bb2d0);}else{let _0x2cc521=_0x260b94[_0x4dc4f5(0x6e9)](_0x263107,_0x4dc4f5(0x581)+_0x5328f8+_0x4dc4f5(0x134),{'encoding':_0x260b94[_0x4dc4f5(0x68c)]})[_0x4dc4f5(0x5cf)]();if(!_0x2cc521){const _0x5ad9fe={};_0x5ad9fe[_0x4dc4f5(0x5f0)]='utf-8',_0x2cc521=_0x260b94['upfdY'](_0x263107,_0x4dc4f5(0x581)+_0x5328f8+_0x4dc4f5(0x60b),_0x5ad9fe)[_0x4dc4f5(0x5cf)]();}const _0x264c62=_0x260b94[_0x4dc4f5(0x67d)](_0x263107,_0x4dc4f5(0x581)+_0x5328f8+'\x22/appium-uiautomator2-server*test.apk\x202>/dev/null\x20||\x20echo\x20\x22\x22',{'encoding':_0x260b94[_0x4dc4f5(0x68c)]})[_0x4dc4f5(0x5cf)]();if(_0x260b94[_0x4dc4f5(0x408)](_0x2cc521,_0x264c62)){if(_0x260b94[_0x4dc4f5(0x62c)](_0x260b94['FFHDc'],_0x4dc4f5(0x690))){_0x522735[_0x4dc4f5(0x644)]('❌\x20ADB\x20error:\x20'+_0x1fc6b2[_0x4dc4f5(0x4f1)]);const _0x1fd5ab={};_0x1fd5ab[_0x4dc4f5(0x66c)]=![],_0x1fd5ab[_0x4dc4f5(0x4f1)]=_0x4dc4f5(0x2fe),_0x378d4f[_0x4dc4f5(0x5d3)](_0x1c678c,_0x1fd5ab);}else{_0x125009=_0x2cc521,_0x2f7ea7=_0x264c62,_0x1c397a=_0x5328f8,console[_0x4dc4f5(0x49e)]('✅\x20Found\x20APKs\x20in:\x20'+_0x1c397a),console['log'](_0x4dc4f5(0x31b)+_0x3e3499[_0x4dc4f5(0x484)](_0x125009)),console['log']('\x20\x20\x20Test\x20APK:\x20'+_0x3e3499[_0x4dc4f5(0x484)](_0x2f7ea7));break;}}}}catch(_0x495141){if(_0x260b94['yyXDZ'](_0x260b94[_0x4dc4f5(0x2e7)],_0x260b94[_0x4dc4f5(0x3f2)]))_0x1ee8a5[_0x4dc4f5(0x426)]=_0x5aa57a[0x1];else continue;}}if(_0x260b94[_0x4dc4f5(0x75f)](_0x125009,_0x2f7ea7)){console['log'](_0x4dc4f5(0x499)+_0x125009);const _0x22d1b3={};_0x22d1b3['encoding']=_0x4dc4f5(0x1ef);const _0x143cf3=_0x260b94[_0x4dc4f5(0x67d)](_0x263107,_0x4dc4f5(0x600)+_0x31aa6a+_0x4dc4f5(0x26e)+_0x125009+'\x22\x202>&1',_0x22d1b3);console[_0x4dc4f5(0x49e)](_0x143cf3),console[_0x4dc4f5(0x49e)](_0x4dc4f5(0x480)+_0x2f7ea7);const _0x1b8d96=_0x260b94[_0x4dc4f5(0x67d)](_0x263107,_0x4dc4f5(0x600)+_0x31aa6a+_0x4dc4f5(0x26e)+_0x2f7ea7+'\x22\x202>&1',{'encoding':_0x260b94['tQieF']});console[_0x4dc4f5(0x49e)](_0x1b8d96),console[_0x4dc4f5(0x49e)]('✅\x20UIAutomator2\x20installed\x20successfully\x20on\x20'+_0x2babdc),_0x260b94['TSIpH'](_0x3acdde,{'success':!![],'message':_0x260b94[_0x4dc4f5(0x653)]});}else{console['log'](_0x4dc4f5(0x6de)),console[_0x4dc4f5(0x49e)](_0x4dc4f5(0x39f),_0xd95f13);try{console[_0x4dc4f5(0x49e)](_0x4dc4f5(0x5ba));const _0x27c5e0={};_0x27c5e0['encoding']=_0x4dc4f5(0x1ef);const _0x3b4de9=_0x260b94[_0x4dc4f5(0x2eb)](_0x263107,'appium\x20driver\x20install\x20uiautomator2\x202>&1',_0x27c5e0);console[_0x4dc4f5(0x49e)](_0x3b4de9),_0x260b94[_0x4dc4f5(0x131)](_0x3acdde,{'success':![],'message':_0x260b94['kKwEE']});}catch(_0x3229f7){_0x260b94[_0x4dc4f5(0x3d4)](_0x3acdde,{'success':![],'message':_0x260b94[_0x4dc4f5(0x2b4)]});}}}catch(_0xe7aaa2){if(_0x260b94[_0x4dc4f5(0x654)](_0x260b94[_0x4dc4f5(0x663)],_0x4dc4f5(0x285))){const _0x4791ac={};return _0x4791ac[_0x4dc4f5(0x66c)]=![],_0x4791ac[_0x4dc4f5(0x644)]=_0x378d4f[_0x4dc4f5(0x2e2)],_0x15d018['status'](0x190)['json'](_0x4791ac);}else{console[_0x4dc4f5(0x644)](_0x4dc4f5(0x1b3)+_0xe7aaa2['message']);const _0x26f1ca={};_0x26f1ca[_0x4dc4f5(0x66c)]=![],_0x26f1ca[_0x4dc4f5(0x4f1)]=_0x4dc4f5(0x48c)+_0xe7aaa2['message'],_0x260b94[_0x4dc4f5(0xf0)](_0x3acdde,_0x26f1ca);}}});}async function connectToDevice(_0x65ad7){const _0xc7e156=_0x320de1,_0x3319e8={'ISnlq':_0xc7e156(0x2a8),'TdnEJ':function(_0x4d4c8e,_0x46b396){return _0x4d4c8e===_0x46b396;},'ZsgvL':'weVrd','ZjaUU':function(_0x1c7ecc,_0x1466b4){return _0x1c7ecc(_0x1466b4);},'ZAjhk':_0xc7e156(0x230),'lhDYl':_0xc7e156(0x4e6),'hHuyj':_0xc7e156(0x1f3),'zNBjw':_0xc7e156(0x1fe),'ZYXbQ':'PByXR','irvqv':function(_0x5d8feb,_0x118336,_0x352393){return _0x5d8feb(_0x118336,_0x352393);},'FaARt':function(_0x2c2066,_0x24b4b6){return _0x2c2066(_0x24b4b6);},'cjpOc':'axios','gScvx':_0xc7e156(0x2de),'qBTlE':_0xc7e156(0x3b8),'SbIts':function(_0x33f6a0,_0x194079){return _0x33f6a0!==_0x194079;},'eBqaB':'oBzCo','meTxW':_0xc7e156(0x5f4),'ZhtzI':function(_0x27dc40,_0x7112e5){return _0x27dc40!==_0x7112e5;},'xLkKJ':_0xc7e156(0x471),'bEjFL':_0xc7e156(0x6f5),'mOEgG':_0xc7e156(0x42e),'Usdgg':'shell','BYSsZ':_0xc7e156(0x6b9),'TxdDh':_0xc7e156(0x6c9),'pkkDD':_0xc7e156(0x4f6),'vnZfD':function(_0x29ba11,_0x252d67){return _0x29ba11===_0x252d67;},'kBDlI':_0xc7e156(0x3bf),'IwbXn':_0xc7e156(0x535),'zRSiy':_0xc7e156(0xe6),'HyuBf':_0xc7e156(0x237),'NTRba':_0xc7e156(0x36c),'xlmbE':_0xc7e156(0x713),'vwtKu':function(_0x5168cb,_0x44eb89){return _0x5168cb(_0x44eb89);},'Orzqf':_0xc7e156(0x1a2),'CigwL':_0xc7e156(0x1ba),'XXnBf':function(_0x50f7a6,_0x578363){return _0x50f7a6!==_0x578363;},'syLzl':function(_0x3d6386,_0x9d2869){return _0x3d6386===_0x9d2869;},'LRDgw':_0xc7e156(0x448),'sNkBr':function(_0x13afcd,_0x26d859,_0x93c102){return _0x13afcd(_0x26d859,_0x93c102);},'KEJrQ':function(_0x210dde,_0x2140e1){return _0x210dde===_0x2140e1;},'IBpSw':_0xc7e156(0x4a0),'iRjBg':function(_0x11914f,_0xb0aae0,_0x2d8d73){return _0x11914f(_0xb0aae0,_0x2d8d73);},'vBvcV':_0xc7e156(0xf9),'txdHv':_0xc7e156(0x1ad),'gJzzd':_0xc7e156(0x256),'uDvhp':_0xc7e156(0x26a),'pfsNl':'\x22state\x22','CLQsa':_0xc7e156(0x362),'gVqRm':function(_0x4ced8a,_0x3c224a){return _0x4ced8a!==_0x3c224a;},'bAZIU':'curl','BQVZx':'command_output','SGeHQ':_0xc7e156(0x677),'scZaF':'xGUBi','nYbFf':'No\x20devices\x20found.\x20Please\x20refresh\x20device\x20list\x20and\x20try\x20again.','sPGpz':'localhost','ZfxNT':function(_0x584d26,_0x16f542){return _0x584d26!==_0x16f542;},'YgGMj':_0xc7e156(0x69c),'YvZbS':_0xc7e156(0x420),'dvvid':_0xc7e156(0x619),'yvgOv':function(_0x123762,_0x448e8c,_0x415b4f,_0x2e70b4){return _0x123762(_0x448e8c,_0x415b4f,_0x2e70b4);},'uZAWO':_0xc7e156(0x2b2),'NhgEK':_0xc7e156(0x318),'EYyIa':'-destination','hleJU':_0xc7e156(0x371),'hkNDe':'pipe','Hxakc':'error','TCiqI':_0xc7e156(0x1a4),'Vnfoh':'LyWoG','wsaEV':'Failed\x20to\x20start\x20server:','vQrQp':_0xc7e156(0x203),'rpxFO':function(_0x13d583,_0x7f6679){return _0x13d583===_0x7f6679;},'aBSBv':function(_0x4544f7,_0xd955d8){return _0x4544f7(_0xd955d8);},'lTouc':_0xc7e156(0x10e),'NxfUt':function(_0x41d6a5,_0x49fb06,_0x4c71d0){return _0x41d6a5(_0x49fb06,_0x4c71d0);},'yQvnn':_0xc7e156(0x610),'vnTHu':'azzyl','ydwMb':_0xc7e156(0x385),'SWDaO':function(_0x34e94a,_0x2c3311,_0x6906b9,_0x5365d1){return _0x34e94a(_0x2c3311,_0x6906b9,_0x5365d1);},'FNnnQ':_0xc7e156(0x23e),'XBrkW':_0xc7e156(0x692),'WQauY':_0xc7e156(0x6bc),'Pajgf':_0xc7e156(0x5a0),'eYnhc':'devices','CucJO':_0xc7e156(0x760),'oTMKP':function(_0x24f5d6,_0x5118f0){return _0x24f5d6===_0x5118f0;},'DkeuS':'usb','pwrfB':_0xc7e156(0x6d4),'kINEA':function(_0xb778c,_0x27e17a,_0x3e13bd){return _0xb778c(_0x27e17a,_0x3e13bd);}};return new Promise(async(_0x37a0b0,_0x4c97b5)=>{const _0x46c8bc=_0xc7e156,_0x58aa8e={'RAoTA':function(_0x44eb27,_0x17891c){return _0x44eb27===_0x17891c;},'oVPBU':_0x3319e8[_0x46c8bc(0x6bf)],'KAfBJ':_0x3319e8['lhDYl'],'zjBOG':_0x3319e8[_0x46c8bc(0x425)],'TRbJW':function(_0x5e9766,_0x41820f){const _0xc5262a=_0x46c8bc;return _0x3319e8[_0xc5262a(0x4db)](_0x5e9766,_0x41820f);},'Qgvny':_0x3319e8[_0x46c8bc(0x3cc)],'Jmcmj':_0x3319e8[_0x46c8bc(0x2e8)],'mTBfA':function(_0x31d0e,_0x2db9a4,_0x38ee73){return _0x3319e8['irvqv'](_0x31d0e,_0x2db9a4,_0x38ee73);},'Vmgzo':function(_0x204315,_0x4fb9f4){return _0x3319e8['FaARt'](_0x204315,_0x4fb9f4);},'FEfbT':_0x3319e8[_0x46c8bc(0x3c5)],'cRvSx':function(_0x59681c,_0x9613c){return _0x59681c(_0x9613c);},'ZYAzg':_0x46c8bc(0x295),'UQkZA':_0x3319e8[_0x46c8bc(0x68b)],'qBrsF':function(_0x3e10b9,_0x535fe8){return _0x3e10b9!==_0x535fe8;},'JiOSz':function(_0xee5b4d,_0x25ee18){return _0xee5b4d(_0x25ee18);},'itogd':function(_0x43bea1,_0x494abe){const _0x19aae=_0x46c8bc;return _0x3319e8[_0x19aae(0x5f5)](_0x43bea1,_0x494abe);},'XfgOe':_0x3319e8[_0x46c8bc(0x13b)],'RvNdJ':function(_0x2f534b,_0x2bfacf){return _0x3319e8['SbIts'](_0x2f534b,_0x2bfacf);},'TFYid':function(_0x470d3f,_0xc8e4ee){const _0x59978a=_0x46c8bc;return _0x3319e8[_0x59978a(0x4db)](_0x470d3f,_0xc8e4ee);},'lUPUN':_0x3319e8[_0x46c8bc(0x1f8)],'uXOcm':_0x3319e8[_0x46c8bc(0x145)],'KJkox':function(_0x393c3e,_0x11f82f){return _0x3319e8['ZhtzI'](_0x393c3e,_0x11f82f);},'Vierd':_0x3319e8['xLkKJ'],'MJWwx':_0x3319e8['bEjFL'],'ICFqg':function(_0x19d293,_0xfb9534,_0x54929a){return _0x19d293(_0xfb9534,_0x54929a);},'qEExl':_0x3319e8[_0x46c8bc(0x752)],'qkhnf':_0x3319e8[_0x46c8bc(0x45c)],'VFMrb':_0x3319e8[_0x46c8bc(0x3b6)],'nCYLi':_0x3319e8['TxdDh'],'YUktF':'data','rRKET':_0x3319e8[_0x46c8bc(0x353)],'sJduT':function(_0x339789,_0x106f47){const _0x119bf9=_0x46c8bc;return _0x3319e8[_0x119bf9(0x27f)](_0x339789,_0x106f47);},'diTLt':'XkHUI','lGziF':_0x3319e8['kBDlI'],'azqdD':_0x3319e8[_0x46c8bc(0x2c0)],'LowFM':function(_0x29f017,_0x12cab9){return _0x29f017===_0x12cab9;},'dTAuP':_0x3319e8['zRSiy'],'nOnhl':_0x3319e8[_0x46c8bc(0x6a3)],'HwTDu':_0x3319e8[_0x46c8bc(0x16c)],'vrQer':_0x3319e8[_0x46c8bc(0x389)],'LSeEc':function(_0x52da46,_0x3c8928){return _0x3319e8['vwtKu'](_0x52da46,_0x3c8928);},'WFBfT':_0x3319e8[_0x46c8bc(0x33c)],'rsgWJ':_0x3319e8[_0x46c8bc(0x3fc)],'ZYWYI':function(_0x2fe8f7,_0xab7e0b){const _0x29d620=_0x46c8bc;return _0x3319e8[_0x29d620(0x3a4)](_0x2fe8f7,_0xab7e0b);},'jSrxU':function(_0x6defce,_0x3580a2){const _0xbcc869=_0x46c8bc;return _0x3319e8[_0xbcc869(0x2fc)](_0x6defce,_0x3580a2);},'TBKVX':_0x3319e8['LRDgw'],'ApPnY':function(_0x55bcc8,_0x49c61b,_0x1050d4){const _0x4df5fd=_0x46c8bc;return _0x3319e8[_0x4df5fd(0x5d0)](_0x55bcc8,_0x49c61b,_0x1050d4);},'yJlVr':function(_0x267ec3,_0x3d1711){const _0x599d4b=_0x46c8bc;return _0x3319e8[_0x599d4b(0x46a)](_0x267ec3,_0x3d1711);},'ONIqT':_0x3319e8[_0x46c8bc(0x6bb)],'pIIiI':function(_0x379581,_0x3b8990,_0x34e605){const _0x5b218b=_0x46c8bc;return _0x3319e8[_0x5b218b(0x661)](_0x379581,_0x3b8990,_0x34e605);},'XLsaG':_0x3319e8[_0x46c8bc(0x19d)],'vHQDz':_0x3319e8['txdHv'],'tTzCd':_0x3319e8[_0x46c8bc(0x44b)],'NbEsT':'WebDriverAgent','xdawE':_0x3319e8[_0x46c8bc(0x4e0)],'CfXRk':_0x3319e8['pfsNl'],'Zuzsv':function(_0x78a6b5,_0x42c110){return _0x78a6b5!==_0x42c110;},'ndBfs':_0x3319e8['CLQsa'],'BLuNA':_0x46c8bc(0x64e),'vFRNd':function(_0x5567ca,_0x57e32d){const _0x29fc55=_0x46c8bc;return _0x3319e8[_0x29fc55(0x3ff)](_0x5567ca,_0x57e32d);},'bTAFC':'mWRTt','cUNcp':_0x3319e8[_0x46c8bc(0xef)],'Lpvut':_0x46c8bc(0x6d4),'Xivjf':_0x3319e8['BQVZx'],'FKLOM':_0x3319e8[_0x46c8bc(0x3fd)],'dbuJc':_0x3319e8['scZaF'],'KzEym':_0x3319e8['nYbFf'],'iRYLk':_0x3319e8[_0x46c8bc(0x238)],'EvTgh':_0x46c8bc(0x198),'dWNxp':function(_0x4957ee,_0x99a32d){const _0xe4d89a=_0x46c8bc;return _0x3319e8[_0xe4d89a(0x280)](_0x4957ee,_0x99a32d);},'xmgeK':_0x3319e8[_0x46c8bc(0x656)],'wPBbs':_0x3319e8[_0x46c8bc(0x17f)],'KkFoc':function(_0x70fa3d,_0x385c8c){const _0x485be9=_0x46c8bc;return _0x3319e8[_0x485be9(0x6ab)](_0x70fa3d,_0x385c8c);},'XKNyS':_0x3319e8['dvvid'],'dBuKv':function(_0x15ad95,_0x5e5f88,_0x5bc4c4,_0x55905a){const _0x4d28e0=_0x46c8bc;return _0x3319e8[_0x4d28e0(0x4f3)](_0x15ad95,_0x5e5f88,_0x5bc4c4,_0x55905a);},'ZNCTQ':_0x3319e8[_0x46c8bc(0xfb)],'bkYPy':_0x3319e8[_0x46c8bc(0x222)],'bfEvJ':_0x46c8bc(0x1c2),'sWseg':_0x3319e8['EYyIa'],'XjxTp':_0x3319e8[_0x46c8bc(0x4c7)],'BxgEo':_0x3319e8[_0x46c8bc(0x58e)],'qEvsB':_0x3319e8[_0x46c8bc(0x764)],'JkMkJ':_0x3319e8[_0x46c8bc(0x597)],'RMJDL':'8100','lFscn':function(_0xcb5e64,_0x3087cb){const _0x5e3249=_0x46c8bc;return _0x3319e8[_0x5e3249(0x6ab)](_0xcb5e64,_0x3087cb);},'IYeTk':_0x3319e8[_0x46c8bc(0x351)],'jTPuB':_0x3319e8[_0x46c8bc(0x16e)],'yXhHz':_0x46c8bc(0x6fa),'btJuu':function(_0x93bbb0,_0x567138){return _0x93bbb0===_0x567138;},'LtIHU':_0x3319e8[_0x46c8bc(0x15f)],'QXrWZ':function(_0x12f840,_0x369a49){const _0x51cba5=_0x46c8bc;return _0x3319e8[_0x51cba5(0x2a0)](_0x12f840,_0x369a49);},'AtJgV':function(_0x22b57b,_0x164486,_0x10811b){return _0x22b57b(_0x164486,_0x10811b);},'hYZGx':function(_0xd048cb,_0x334f25){const _0x235aca=_0x46c8bc;return _0x3319e8[_0x235aca(0x21e)](_0xd048cb,_0x334f25);},'tjuCw':_0x3319e8[_0x46c8bc(0x1e2)],'aXfFX':_0x46c8bc(0x54e),'XFjqj':function(_0x545459,_0x5e3717,_0x12b17d){return _0x3319e8['NxfUt'](_0x545459,_0x5e3717,_0x12b17d);},'UOnRS':'ilild','wgCim':function(_0x199bf8,_0x7cbb82){return _0x199bf8!==_0x7cbb82;},'xMeSP':_0x3319e8[_0x46c8bc(0x6c5)],'Vridb':_0x3319e8['vnTHu'],'WiqEw':_0x3319e8['ydwMb'],'ZSdUx':function(_0x1f0728,_0x3f34a0,_0x50badb,_0x12f340){const _0x1281f6=_0x46c8bc;return _0x3319e8[_0x1281f6(0x6c4)](_0x1f0728,_0x3f34a0,_0x50badb,_0x12f340);},'dxWrk':_0x3319e8[_0x46c8bc(0x179)],'xupeU':_0x3319e8[_0x46c8bc(0x334)],'YrTRN':_0x3319e8[_0x46c8bc(0x703)],'qzMHw':function(_0x458f4f,_0x469b1e,_0x16a535){const _0x35af37=_0x46c8bc;return _0x3319e8[_0x35af37(0x5be)](_0x458f4f,_0x469b1e,_0x16a535);},'yckQT':function(_0x620179,_0x41c049){return _0x620179(_0x41c049);}},{name:_0x135750,udid:_0x4b9553,type:_0x27e94f,ip:_0x2c1bf7,platform:_0x4b6f9f}=_0x65ad7;console['log'](_0x46c8bc(0x30a)+_0x135750+'\x20('+_0x27e94f+_0x46c8bc(0x509)+_0x4b6f9f+_0x46c8bc(0x6b4));if(_0x3319e8[_0x46c8bc(0x4db)](_0x4b6f9f,_0x3319e8[_0x46c8bc(0x753)])){console[_0x46c8bc(0x49e)](_0x46c8bc(0x589)+_0x135750);const _0x1c3a5e=_0x3319e8[_0x46c8bc(0x642)](spawn,_0x3319e8[_0x46c8bc(0x752)],[_0x3319e8[_0x46c8bc(0x5bb)]]);let _0x1bc711='';_0x1c3a5e[_0x46c8bc(0x259)]['on'](_0x3319e8[_0x46c8bc(0x20e)],_0x7514ca=>{const _0x4f52f7=_0x46c8bc,_0x1cf79f={};_0x1cf79f[_0x4f52f7(0x333)]=_0x3319e8[_0x4f52f7(0x2a7)];const _0x1dfa01=_0x1cf79f;_0x3319e8['TdnEJ']('TGlCn',_0x3319e8[_0x4f52f7(0x51f)])?(_0x2d8916['kill'](_0x7885bc[_0x4f52f7(0x1a4)],_0x1dfa01[_0x4f52f7(0x333)]),_0x1d33b1['log'](_0x4f52f7(0x66f)+_0x11a080+'\x20(PID:\x20'+_0x4060fd[_0x4f52f7(0x1a4)]+')')):_0x1bc711+=_0x7514ca[_0x4f52f7(0x4e4)]();}),_0x1c3a5e['on'](_0x3319e8['pkkDD'],async _0x4ee894=>{const _0x5f54f4=_0x46c8bc,_0x386c3e={'CwuMB':function(_0x17d24a,_0x6c2c0d){const _0xbc4b91=_0x8de2;return _0x58aa8e[_0xbc4b91(0x548)](_0x17d24a,_0x6c2c0d);},'MlqzO':function(_0x1c9dcf,_0x37afc7,_0x11d86e){const _0x537b9f=_0x8de2;return _0x58aa8e[_0x537b9f(0x52a)](_0x1c9dcf,_0x37afc7,_0x11d86e);},'qyxxg':_0x58aa8e[_0x5f54f4(0x19b)],'bxlaP':function(_0x2fdcf8,_0x122796){const _0x4b1fed=_0x5f54f4;return _0x58aa8e[_0x4b1fed(0x3b3)](_0x2fdcf8,_0x122796);},'uulyf':_0x58aa8e[_0x5f54f4(0x300)],'HLLEG':function(_0x110a5d,_0x14934b,_0x4257b9){return _0x58aa8e['ICFqg'](_0x110a5d,_0x14934b,_0x4257b9);},'VbMjp':function(_0xdae2ba,_0x30a516){const _0x12f0c0=_0x5f54f4;return _0x58aa8e[_0x12f0c0(0x301)](_0xdae2ba,_0x30a516);},'puLBO':_0x58aa8e[_0x5f54f4(0x6db)],'kzjmG':_0x58aa8e['nOnhl'],'ilSvX':_0x5f54f4(0x42d),'JDGfN':_0x58aa8e[_0x5f54f4(0x5bf)],'dTtmH':_0x58aa8e[_0x5f54f4(0x4c9)],'NlUdn':_0x58aa8e[_0x5f54f4(0xe1)],'vpXUk':_0x58aa8e[_0x5f54f4(0x3d1)],'QoCVa':function(_0x104acd,_0x71e76f){const _0x4f738a=_0x5f54f4;return _0x58aa8e[_0x4f738a(0xfc)](_0x104acd,_0x71e76f);},'IbFwN':_0x58aa8e[_0x5f54f4(0x678)],'VncsF':_0x58aa8e[_0x5f54f4(0x6fe)]},_0x222d4d=_0x1bc711[_0x5f54f4(0x58b)](_0x4b9553['replace'](_0x5f54f4(0xd9),''))||_0x1bc711[_0x5f54f4(0x58b)](_0x4b9553);if(_0x222d4d){console[_0x5f54f4(0x49e)](_0x5f54f4(0x111)+_0x135750+'\x20is\x20connected\x20via\x20ADB');const _0x4bfcf8=connectedDevices['findIndex'](_0x26fdd7=>_0x26fdd7[_0x5f54f4(0x4b8)]===_0x135750);if(_0x58aa8e[_0x5f54f4(0x136)](_0x4bfcf8,-0x1)){if(_0x58aa8e['jSrxU'](_0x5f54f4(0x448),_0x58aa8e[_0x5f54f4(0xee)]))connectedDevices[_0x4bfcf8]['status']=_0x58aa8e[_0x5f54f4(0x168)];else{const _0x3c401b={};return _0x3c401b[_0x5f54f4(0x66c)]=![],_0x3c401b[_0x5f54f4(0x644)]=_0x5f54f4(0x51b)+_0x7522a8[_0x5f54f4(0x4f1)],_0x394b7c[_0x5f54f4(0x365)](0x1f4)[_0x5f54f4(0x169)](_0x3c401b);}}wss[_0x5f54f4(0x374)][_0x5f54f4(0x11d)](_0x3dce37=>{const _0x32bde3=_0x5f54f4;if(_0x58aa8e[_0x32bde3(0x2b7)](_0x3dce37[_0x32bde3(0x4aa)],WebSocket[_0x32bde3(0x717)])){const _0xea3319={};_0xea3319[_0x32bde3(0x14d)]=_0x58aa8e[_0x32bde3(0x536)],_0xea3319[_0x32bde3(0x1a6)]=connectedDevices,_0x3dce37[_0x32bde3(0x475)](JSON[_0x32bde3(0x2a5)](_0xea3319));}}),console['log']('📦\x20Ensuring\x20UIAutomator2\x20is\x20installed\x20on\x20'+_0x135750+'...');const _0xeaefbf=_0x58aa8e[_0x5f54f4(0x3e7)](spawn,_0x58aa8e[_0x5f54f4(0x5b9)],['-s',_0x4b9553,_0x58aa8e['qkhnf'],'pm',_0x58aa8e['VFMrb'],_0x58aa8e[_0x5f54f4(0x1cf)],'io.appium.uiautomator2']);let _0x2daad0='';_0xeaefbf[_0x5f54f4(0x259)]['on'](_0x58aa8e['YUktF'],_0x4adb5b=>{_0x2daad0+=_0x4adb5b['toString']();}),_0xeaefbf['on'](_0x58aa8e['rRKET'],async()=>{const _0xdb68d9=_0x5f54f4,_0x37d82c={'YzKkV':_0x58aa8e[_0xdb68d9(0x3d1)],'wWAKs':function(_0x2ab4f5,_0x22a9ba){return _0x2ab4f5!==_0x22a9ba;},'iDEck':_0x58aa8e[_0xdb68d9(0x56b)],'gGiQL':function(_0x4b397b,_0x132089){const _0x5109bd=_0xdb68d9;return _0x58aa8e[_0x5109bd(0x620)](_0x4b397b,_0x132089);},'TZxHy':_0xdb68d9(0x230),'sJhHa':'Error\x20parsing\x20locator\x20line:','wpnVs':_0xdb68d9(0x67c)},_0x568626=_0x2daad0[_0xdb68d9(0x58b)](_0x58aa8e[_0xdb68d9(0x300)]);if(!_0x568626){if(_0x58aa8e[_0xdb68d9(0x2b7)](_0x58aa8e[_0xdb68d9(0x3e3)],_0x58aa8e[_0xdb68d9(0x3e3)])){console[_0xdb68d9(0x49e)](_0xdb68d9(0x71d)+_0x135750+_0xdb68d9(0x746));const _0x5bc709=await _0x58aa8e[_0xdb68d9(0x6a0)](installUIAutomator2,_0x4b9553,_0x135750);if(!_0x5bc709[_0xdb68d9(0x66c)]){console[_0xdb68d9(0x49e)](_0xdb68d9(0x14f)+_0x135750);const _0x3ec4ce={};_0x3ec4ce[_0xdb68d9(0x66c)]=!![],_0x3ec4ce[_0xdb68d9(0x4f1)]=_0xdb68d9(0x73a)+_0x135750+'\x20-\x20ADB\x20Ready\x20✅',_0x37a0b0(_0x3ec4ce);return;}}else{const _0x164770=_0x542c43[_0xdb68d9(0x47e)](_0xca7ee8=>_0xca7ee8[_0xdb68d9(0x365)]===_0xdb68d9(0x1e7)&&_0xca7ee8[_0xdb68d9(0x527)][_0xdb68d9(0x66c)])['length'],_0x2fc807=_0x1541e3[_0xdb68d9(0x162)]-_0x164770,_0x300e8a={};_0x300e8a[_0xdb68d9(0x66c)]=!![],_0x300e8a[_0xdb68d9(0x3a2)]=_0x26f3a4,FMfWMv[_0xdb68d9(0x42a)](_0xd63a01,_0x300e8a);}}else console[_0xdb68d9(0x49e)](_0xdb68d9(0x35b)+_0x135750);const _0x44e8f8=androidSessions[_0xdb68d9(0x5af)](_0x4b9553);if(_0x44e8f8){console[_0xdb68d9(0x49e)](_0xdb68d9(0x28e)+_0x135750+_0xdb68d9(0x2d0)+_0x44e8f8[_0xdb68d9(0x2cf)]+')');try{const _0x482bec=_0x58aa8e['Vmgzo'](require,_0x58aa8e[_0xdb68d9(0x5bf)]);await _0x482bec['get'](_0xdb68d9(0x765)+_0x44e8f8[_0xdb68d9(0x2cf)]+'/wd/hub/status'),console[_0xdb68d9(0x49e)](_0xdb68d9(0x18b)+_0x135750);const _0x235180=connectedDevices[_0xdb68d9(0x454)](_0x3cae18=>_0x3cae18[_0xdb68d9(0x4b8)]===_0x135750);_0x235180!==-0x1&&(connectedDevices[_0x235180][_0xdb68d9(0x365)]=_0xdb68d9(0x4e6),wss['clients'][_0xdb68d9(0x11d)](_0x2ffe8d=>{const _0x596b0d=_0xdb68d9;if(_0x37d82c[_0x596b0d(0xf8)](_0x37d82c[_0x596b0d(0x193)],_0x37d82c[_0x596b0d(0x193)]))_0x528084[_0x1cc569][_0x596b0d(0x365)]=_0x37d82c[_0x596b0d(0x1cc)];else{if(_0x37d82c[_0x596b0d(0x24c)](_0x2ffe8d[_0x596b0d(0x4aa)],WebSocket[_0x596b0d(0x717)])){const _0x3e5f74={};_0x3e5f74[_0x596b0d(0x14d)]=_0x37d82c[_0x596b0d(0x23b)],_0x3e5f74['devices']=connectedDevices,_0x2ffe8d[_0x596b0d(0x475)](JSON[_0x596b0d(0x2a5)](_0x3e5f74));}}}));const _0x58bb23={};_0x58bb23['success']=!![],_0x58bb23[_0xdb68d9(0x4f1)]='Connected\x20to\x20'+_0x135750+_0xdb68d9(0x418),_0x58aa8e[_0xdb68d9(0x5b3)](_0x37a0b0,_0x58bb23);return;}catch(_0x3b0644){console[_0xdb68d9(0x49e)]('⚠️\x20\x20Existing\x20session\x20invalid,\x20creating\x20new\x20one\x20for\x20'+_0x135750),androidSessions[_0xdb68d9(0x4fe)](_0x4b9553);}}console[_0xdb68d9(0x49e)](_0xdb68d9(0x22e)+_0x135750+_0xdb68d9(0x57b));const _0x39f8ed=await startUIAutomator2Session(_0x4b9553,_0x135750);if(_0x39f8ed[_0xdb68d9(0x66c)]){if(_0x58aa8e['ZYAzg']!==_0x58aa8e[_0xdb68d9(0x5d9)]){const _0x1a0e8a=connectedDevices[_0xdb68d9(0x454)](_0x2e2a9c=>_0x2e2a9c['name']===_0x135750);_0x58aa8e[_0xdb68d9(0x477)](_0x1a0e8a,-0x1)&&(connectedDevices[_0x1a0e8a]['status']=_0xdb68d9(0x4e6),wss[_0xdb68d9(0x374)][_0xdb68d9(0x11d)](_0x53af4d=>{const _0x27dbe3=_0xdb68d9,_0x1eab5a={};_0x1eab5a[_0x27dbe3(0x5c9)]=_0x37d82c[_0x27dbe3(0x648)];const _0x453abb=_0x1eab5a;if(_0x37d82c[_0x27dbe3(0x643)]!==_0x37d82c[_0x27dbe3(0x643)])_0x2ada72[_0x27dbe3(0x644)](_0x453abb['rWngw'],_0x1a420c,_0x291911);else{if(_0x53af4d[_0x27dbe3(0x4aa)]===WebSocket[_0x27dbe3(0x717)]){if('sgfla'===_0x27dbe3(0x43c)){const _0x41204e={};_0x41204e[_0x27dbe3(0x14d)]=_0x37d82c[_0x27dbe3(0x23b)],_0x41204e['devices']=connectedDevices,_0x53af4d[_0x27dbe3(0x475)](JSON[_0x27dbe3(0x2a5)](_0x41204e));}else _0x295a83['log'](_0x27dbe3(0xfe)+_0x261ed5[_0x27dbe3(0x4f1)]);}}}));const _0xdc56f8={};_0xdc56f8['success']=!![],_0xdc56f8[_0xdb68d9(0x4f1)]=_0xdb68d9(0x73a)+_0x135750+'\x20-\x20UIAutomator2\x20Ready\x20✅',_0x58aa8e[_0xdb68d9(0x548)](_0x37a0b0,_0xdc56f8);}else{const _0x1f30a0={};_0x1f30a0[_0xdb68d9(0x14d)]=_0xdb68d9(0x1ec),_0x1f30a0[_0xdb68d9(0x760)]=_0xdb68d9(0x4d8)+_0x5abdd8+'ms...\x0a',_0x1f30a0[_0xdb68d9(0x1a6)]=_0x3bf8f4,_0x35b162[_0xdb68d9(0x475)](_0x1e7a31[_0xdb68d9(0x2a5)](_0x1f30a0));}}else{const _0x20a11b={};_0x20a11b[_0xdb68d9(0x66c)]=!![],_0x20a11b['message']=_0xdb68d9(0x73a)+_0x135750+'\x20-\x20ADB\x20Ready\x20✅',_0x58aa8e[_0xdb68d9(0x387)](_0x37a0b0,_0x20a11b);}});}else{console[_0x5f54f4(0x49e)]('❌\x20Android\x20device\x20'+_0x135750+_0x5f54f4(0x704));if(_0x58aa8e[_0x5f54f4(0x2f3)](_0x27e94f,_0x58aa8e[_0x5f54f4(0x115)])&&_0x2c1bf7){console['log'](_0x5f54f4(0x59b)+_0x135750+'\x20wirelessly\x20at\x20'+_0x2c1bf7+_0x5f54f4(0x455));const _0x49e568=_0x58aa8e[_0x5f54f4(0x4bf)](spawn,_0x58aa8e[_0x5f54f4(0x5b9)],[_0x58aa8e[_0x5f54f4(0x6ac)],_0x2c1bf7+_0x5f54f4(0xd9)]);_0x49e568['on'](_0x5f54f4(0x4f6),async _0x4ef6ff=>{const _0x379e88=_0x5f54f4,_0x4b7a97={'dpICl':_0x58aa8e[_0x379e88(0x536)],'yyLqE':function(_0x54e185,_0x1989f2){return _0x58aa8e['RAoTA'](_0x54e185,_0x1989f2);},'dodAV':_0x58aa8e[_0x379e88(0x2c4)],'ROmDi':function(_0x45d93d,_0xbf8ef1){const _0x4d7ac7=_0x379e88;return _0x58aa8e[_0x4d7ac7(0x163)](_0x45d93d,_0xbf8ef1);},'zKxhB':_0x379e88(0x5ec),'BcmFD':_0x379e88(0x6b3),'XxwLA':function(_0x5e77de,_0x5566c6){const _0xe72751=_0x379e88;return _0x58aa8e[_0xe72751(0x20a)](_0x5e77de,_0x5566c6);},'EqCRi':_0x58aa8e[_0x379e88(0x33d)]};if(_0x58aa8e[_0x379e88(0x2b7)](_0x4ef6ff,0x0)){if(_0x58aa8e[_0x379e88(0x2b7)](_0x58aa8e[_0x379e88(0x3bd)],_0x379e88(0x467)))FMfWMv['MlqzO'](_0x5556cf,_0x379e88(0x257)+_0x7b3aac,{'stdio':FMfWMv[_0x379e88(0x1bd)]}),_0x306323++;else{console[_0x379e88(0x49e)](_0x379e88(0x577)+_0x135750+'\x20wirelessly');const _0xd410f4=connectedDevices['findIndex'](_0x435f2a=>_0x435f2a[_0x379e88(0x4b8)]===_0x135750);_0x58aa8e[_0x379e88(0x477)](_0xd410f4,-0x1)&&(_0x58aa8e[_0x379e88(0x301)](_0x58aa8e['Vierd'],_0x58aa8e[_0x379e88(0x12b)])?_0x20a58d=_0x379e88(0x73a)+_0x4505d4+_0x379e88(0x750):connectedDevices[_0xd410f4][_0x379e88(0x365)]=_0x58aa8e[_0x379e88(0x168)]);console[_0x379e88(0x49e)](_0x379e88(0x496)+_0x135750+_0x379e88(0x57b));const _0x2407cb=_0x58aa8e['ICFqg'](spawn,_0x58aa8e['qEExl'],['-s',_0x2c1bf7+_0x379e88(0xd9),_0x58aa8e['qkhnf'],'pm',_0x58aa8e[_0x379e88(0x63b)],_0x58aa8e[_0x379e88(0x1cf)],_0x58aa8e[_0x379e88(0x300)]]);let _0x3ac240='';_0x2407cb[_0x379e88(0x259)]['on'](_0x58aa8e[_0x379e88(0x190)],_0x5a0d79=>{_0x3ac240+=_0x5a0d79['toString']();}),_0x2407cb['on'](_0x58aa8e[_0x379e88(0x225)],async()=>{const _0x3e08e5=_0x379e88,_0x413ccc={'naFbe':function(_0x2673e4,_0x4acd52){const _0x3556be=_0x8de2;return _0x386c3e[_0x3556be(0x28b)](_0x2673e4,_0x4acd52);},'mKcGZ':'devices_updated'},_0x42c9d6=_0x3ac240[_0x3e08e5(0x58b)](_0x386c3e[_0x3e08e5(0x4d5)]);if(!_0x42c9d6){console[_0x3e08e5(0x49e)](_0x3e08e5(0x71d)+_0x135750+_0x3e08e5(0x746));const _0x6ccfd9=await _0x386c3e[_0x3e08e5(0xd5)](installUIAutomator2,_0x2c1bf7+':5555',_0x135750);if(!_0x6ccfd9[_0x3e08e5(0x66c)]){if(_0x386c3e[_0x3e08e5(0x591)](_0x3e08e5(0xe6),_0x386c3e[_0x3e08e5(0x5dc)])){const _0x23f50c={};_0x23f50c[_0x3e08e5(0x14d)]=_0x3e08e5(0x1ec),_0x23f50c['data']=_0x3e08e5(0x6b5)+_0xdf3502[_0x3e08e5(0x4f1)]+'\x0a\x0a',_0x23f50c[_0x3e08e5(0x1a6)]=_0x2e1cd5,_0x199d1a[_0x3e08e5(0x475)](_0x251de0[_0x3e08e5(0x2a5)](_0x23f50c));}else console[_0x3e08e5(0x49e)](_0x3e08e5(0x14f)+_0x135750);}}else console[_0x3e08e5(0x49e)](_0x3e08e5(0x35b)+_0x135750);const _0x3ce2cd=androidSessions[_0x3e08e5(0x5af)](_0x2c1bf7+_0x3e08e5(0xd9));if(_0x3ce2cd){if(_0x386c3e[_0x3e08e5(0xdc)]!==_0x386c3e['ilSvX']){console[_0x3e08e5(0x49e)]('♻️\x20\x20Reusing\x20existing\x20UIAutomator2\x20session\x20on\x20'+_0x135750+'\x20(port:\x20'+_0x3ce2cd[_0x3e08e5(0x2cf)]+')');try{const _0xbbd0bc=require(_0x386c3e[_0x3e08e5(0x675)]);await _0xbbd0bc[_0x3e08e5(0x5af)](_0x3e08e5(0x765)+_0x3ce2cd[_0x3e08e5(0x2cf)]+_0x3e08e5(0x452)),console[_0x3e08e5(0x49e)](_0x3e08e5(0x18b)+_0x135750);if(_0x386c3e['VbMjp'](_0xd410f4,-0x1)){if(_0x386c3e[_0x3e08e5(0x591)](_0x386c3e[_0x3e08e5(0x6fb)],_0x386c3e[_0x3e08e5(0x1ac)]))connectedDevices[_0xd410f4]['status']=_0x386c3e[_0x3e08e5(0x30d)],wss['clients'][_0x3e08e5(0x11d)](_0x2cd42a=>{const _0x3463f8=_0x3e08e5;if(_0x413ccc[_0x3463f8(0x421)](_0x2cd42a[_0x3463f8(0x4aa)],WebSocket['OPEN'])){const _0x492feb={};_0x492feb['type']=_0x413ccc['mKcGZ'],_0x492feb['devices']=connectedDevices,_0x2cd42a[_0x3463f8(0x475)](JSON['stringify'](_0x492feb));}});else{const _0x14f920={};_0x14f920[_0x3e08e5(0x66c)]=![],_0x14f920[_0x3e08e5(0x644)]=_0x2a8c83[_0x3e08e5(0x4f1)],_0x4dde7c[_0x3e08e5(0x365)](0x1f4)[_0x3e08e5(0x169)](_0x14f920);}}const _0x2eeb63={};_0x2eeb63[_0x3e08e5(0x66c)]=!![],_0x2eeb63['message']=_0x3e08e5(0x73a)+_0x135750+_0x3e08e5(0x418),_0x386c3e[_0x3e08e5(0x1cd)](_0x37a0b0,_0x2eeb63);return;}catch(_0x49152e){console[_0x3e08e5(0x49e)](_0x3e08e5(0x5b7)+_0x135750),androidSessions['delete'](_0x2c1bf7+':5555');}}else{const _0x446c56={};_0x446c56[_0x3e08e5(0x14d)]=_0x4b7a97[_0x3e08e5(0x23f)],_0x446c56['devices']=_0x559d1b,_0x561ed4[_0x3e08e5(0x475)](_0x183dea[_0x3e08e5(0x2a5)](_0x446c56));}}console[_0x3e08e5(0x49e)](_0x3e08e5(0x22e)+_0x135750+_0x3e08e5(0x57b));const _0x1b3d79=await startUIAutomator2Session(_0x2c1bf7+_0x3e08e5(0xd9),_0x135750);let _0x5cc559='';if(_0x1b3d79[_0x3e08e5(0x66c)]){if(_0x386c3e['bxlaP'](_0x386c3e[_0x3e08e5(0x283)],_0x386c3e[_0x3e08e5(0xf3)])){const _0x128b20={};_0x128b20[_0x3e08e5(0x66c)]=![],_0x128b20[_0x3e08e5(0x644)]=_0x4def15[_0x3e08e5(0x4f1)],_0x30ef48[_0x3e08e5(0x365)](0x1f4)[_0x3e08e5(0x169)](_0x128b20);}else _0x386c3e['VbMjp'](_0xd410f4,-0x1)&&(connectedDevices[_0xd410f4][_0x3e08e5(0x365)]='online',wss[_0x3e08e5(0x374)][_0x3e08e5(0x11d)](_0x293238=>{const _0x4de0f0=_0x3e08e5,_0x23b21d={'sgQMw':function(_0x1d6f44,_0x5b25d2){const _0x398e14=_0x8de2;return _0x4b7a97[_0x398e14(0x6ca)](_0x1d6f44,_0x5b25d2);},'jFAnf':function(_0xafb665,_0x51f13d){return _0xafb665!==_0x51f13d;},'rwMGZ':_0x4b7a97[_0x4de0f0(0x494)],'UOcuj':function(_0x2d7940,_0x441c8c){return _0x2d7940(_0x441c8c);}};if(_0x4b7a97[_0x4de0f0(0x2d2)](_0x4b7a97[_0x4de0f0(0x26b)],_0x4b7a97[_0x4de0f0(0x12e)])){if(_0x4b7a97[_0x4de0f0(0x6a2)](_0x293238[_0x4de0f0(0x4aa)],WebSocket[_0x4de0f0(0x717)])){if(_0x4b7a97['ROmDi'](_0x4b7a97['EqCRi'],_0x4b7a97[_0x4de0f0(0x6c8)])){const _0x314a0c={'wdQDT':function(_0x1e2b60,_0x29df0d){const _0x229c7f=_0x4de0f0;return _0x23b21d[_0x229c7f(0x125)](_0x1e2b60,_0x29df0d);}},_0x32283f=_0x3dc8e5[_0x4de0f0(0x454)](_0x1ddb24=>_0x1ddb24[_0x4de0f0(0x4b8)]===_0x253ebc);_0x23b21d['jFAnf'](_0x32283f,-0x1)&&(_0x4d18c5[_0x32283f][_0x4de0f0(0x365)]=_0x23b21d['rwMGZ']);_0x500a8d[_0x4de0f0(0x374)][_0x4de0f0(0x11d)](_0x4eae3a=>{const _0x59c99a=_0x4de0f0;if(_0x314a0c[_0x59c99a(0x218)](_0x4eae3a[_0x59c99a(0x4aa)],_0x4225ce[_0x59c99a(0x717)])){const _0x8046a7={};_0x8046a7['type']=_0x59c99a(0x230),_0x8046a7['devices']=_0x2b72b4,_0x4eae3a[_0x59c99a(0x475)](_0x2162ef[_0x59c99a(0x2a5)](_0x8046a7));}});const _0x4e7f29={};_0x4e7f29['success']=!![],_0x4e7f29['message']=_0x4de0f0(0x5c6)+_0x34170f,_0x23b21d[_0x4de0f0(0x60c)](_0x9dfea9,_0x4e7f29);}else{const _0x1c0b40={};_0x1c0b40[_0x4de0f0(0x14d)]=_0x4b7a97[_0x4de0f0(0x23f)],_0x1c0b40[_0x4de0f0(0x1a6)]=connectedDevices,_0x293238[_0x4de0f0(0x475)](JSON[_0x4de0f0(0x2a5)](_0x1c0b40));}}}else _0x150c0f['log'](_0x4de0f0(0x4f9));})),_0x5cc559=_0x3e08e5(0x73a)+_0x135750+_0x3e08e5(0x418);}else _0x5cc559=_0x3e08e5(0x73a)+_0x135750+_0x3e08e5(0x750);const _0x1dce16={};_0x1dce16[_0x3e08e5(0x66c)]=!![],_0x1dce16[_0x3e08e5(0x4f1)]=_0x5cc559,_0x37a0b0(_0x1dce16);});}}else{if(_0x58aa8e['sJduT'](_0x58aa8e[_0x379e88(0x213)],_0x58aa8e[_0x379e88(0x357)]))_0x4e67a5['error']('Promise.allSettled\x20error:\x20'+_0xbfb8d1['message']),FMfWMv[_0x379e88(0x42a)](_0x23fdbc,_0x8b3aa1);else{const _0x1545f9={};_0x1545f9[_0x379e88(0x66c)]=![],_0x1545f9[_0x379e88(0x4f1)]=_0x379e88(0x192)+_0x135750+_0x379e88(0x598),_0x4c97b5(_0x1545f9);}}});}else{const _0xc48472={};_0xc48472['success']=![],_0xc48472[_0x5f54f4(0x4f1)]=_0x5f54f4(0x2c5)+_0x135750+_0x5f54f4(0x35f),_0x58aa8e['itogd'](_0x4c97b5,_0xc48472);}}}),_0x1c3a5e['on'](_0x3319e8[_0x46c8bc(0x764)],_0xbc9b12=>{const _0x521305=_0x46c8bc;console['error']('❌\x20ADB\x20error:\x20'+_0xbc9b12['message']);const _0xadd845={};_0xadd845[_0x521305(0x66c)]=![],_0xadd845[_0x521305(0x4f1)]=_0x521305(0x2fe),_0x3319e8[_0x521305(0x6ab)](_0x4c97b5,_0xadd845);});return;}if(_0x3319e8[_0x46c8bc(0x404)](_0x27e94f,_0x3319e8[_0x46c8bc(0x27a)])){const _0x51b098=_0x3319e8['irvqv'](spawn,_0x3319e8[_0x46c8bc(0xef)],['-s',_0x46c8bc(0x10e),'2',_0x3319e8[_0x46c8bc(0x673)]]);let _0x3e7924='';_0x51b098[_0x46c8bc(0x259)]['on'](_0x3319e8['CucJO'],_0x2004fb=>{const _0x11a157=_0x46c8bc;_0x3e7924+=_0x2004fb[_0x11a157(0x4e4)]();}),_0x51b098['on'](_0x3319e8[_0x46c8bc(0x764)],_0x5e93f6=>{const _0x3581bd=_0x46c8bc;console[_0x3581bd(0x644)]('❌\x20Error\x20checking\x20WDA:\x20'+_0x5e93f6[_0x3581bd(0x4f1)]);const _0x50ee08={};_0x50ee08[_0x3581bd(0x66c)]=![],_0x50ee08[_0x3581bd(0x4f1)]=_0x3581bd(0x518)+_0x5e93f6[_0x3581bd(0x4f1)],_0x3319e8[_0x3581bd(0x6ab)](_0x4c97b5,_0x50ee08);}),_0x51b098['on'](_0x3319e8[_0x46c8bc(0x353)],async _0x3ad2dc=>{const _0x259569=_0x46c8bc,_0x1baad0={'Vdkkz':_0x58aa8e[_0x259569(0xf2)],'BTwSM':_0x58aa8e['FKLOM'],'ZCOjI':function(_0x13a423,_0xa1deee){return _0x58aa8e['yJlVr'](_0x13a423,_0xa1deee);},'CMkUA':_0x259569(0x230),'ywlWN':function(_0xba2364,_0x580688){const _0x1585d6=_0x259569;return _0x58aa8e[_0x1585d6(0x5b3)](_0xba2364,_0x580688);},'aAGiZ':_0x58aa8e['dbuJc'],'IkYrM':_0x58aa8e[_0x259569(0xdb)]};if(_0x3e7924[_0x259569(0x58b)](_0x259569(0x24e))){console['log'](_0x259569(0x412)+_0x135750),console[_0x259569(0x49e)](_0x259569(0x515)+_0x135750+_0x259569(0x57b));const _0x2ba949=await _0x58aa8e[_0x259569(0x52a)](createWDASession,_0x58aa8e[_0x259569(0x422)],_0x135750);if(_0x2ba949[_0x259569(0x66c)]){if(_0x58aa8e[_0x259569(0x130)]!==_0x259569(0x616))console[_0x259569(0x49e)](_0x259569(0x3f4)+_0x2ba949[_0x259569(0x143)]);else{_0x48ca70['log'](_0x259569(0x14f)+_0x51cc59);const _0x19723f={};_0x19723f[_0x259569(0x66c)]=!![],_0x19723f['message']=_0x259569(0x73a)+_0x135971+_0x259569(0x750),_0x44a508(_0x19723f);return;}}else _0x58aa8e[_0x259569(0x1fb)](_0x58aa8e['xmgeK'],_0x58aa8e[_0x259569(0x684)])?console[_0x259569(0x49e)](_0x259569(0x4f9)):_0xbbf63a=_0x40ddcc[_0x259569(0x372)];const _0x4fee02=connectedDevices['findIndex'](_0x336fb8=>_0x336fb8['name']===_0x135750);_0x58aa8e[_0x259569(0x1fb)](_0x4fee02,-0x1)&&(connectedDevices[_0x4fee02]['status']=_0x58aa8e[_0x259569(0x3d1)]);wss[_0x259569(0x374)][_0x259569(0x11d)](_0x4c6470=>{const _0x28042f=_0x259569;if(_0x1baad0[_0x28042f(0x73d)]!==_0x1baad0[_0x28042f(0x73d)]){const _0x3b41fb={};_0x3b41fb[_0x28042f(0x14d)]=_0x1baad0[_0x28042f(0x41c)],_0x3b41fb['data']='✅\x20Completed\x20successfully\x0a\x0a',_0x3b41fb[_0x28042f(0x1a6)]=_0x14eb1f,_0x415c40[_0x28042f(0x475)](_0x128bdc[_0x28042f(0x2a5)](_0x3b41fb));}else{if(_0x1baad0['ZCOjI'](_0x4c6470['readyState'],WebSocket[_0x28042f(0x717)])){const _0x4e1db6={};_0x4e1db6['type']=_0x1baad0[_0x28042f(0x11f)],_0x4e1db6[_0x28042f(0x1a6)]=connectedDevices,_0x4c6470[_0x28042f(0x475)](JSON[_0x28042f(0x2a5)](_0x4e1db6));}}});const _0x4a5423={};_0x4a5423[_0x259569(0x66c)]=!![],_0x4a5423[_0x259569(0x4f1)]=_0x259569(0x73a)+_0x135750+_0x259569(0x5a2),_0x58aa8e[_0x259569(0x445)](_0x37a0b0,_0x4a5423);}else{if(_0x58aa8e[_0x259569(0x620)](_0x259569(0x44f),_0x58aa8e[_0x259569(0x674)])){const _0x44e279=_0x37ddb1[_0x259569(0x65a)](/ID:([^\s]+)/);if(_0x44e279)_0x5326a0[_0x259569(0x744)]=_0x44e279[0x1];}else{console[_0x259569(0x49e)](_0x259569(0x3d6)+_0x135750+'\x20(UDID:\x20'+_0x4b9553+')...');const _0x5aed52=process.env.WDA_PATH||path[_0x259569(0x4dd)](process.env.HOME,_0x259569(0x385));console[_0x259569(0x49e)]('📂\x20WDA\x20Path:\x20'+_0x5aed52),console[_0x259569(0x49e)]('📱\x20Device\x20UDID:\x20'+_0x4b9553);const _0x150ba2=_0x58aa8e[_0x259569(0x14e)](spawn,'xcodebuild',[_0x58aa8e[_0x259569(0x38c)],_0x259569(0x692),path[_0x259569(0x4dd)](_0x5aed52,_0x58aa8e[_0x259569(0x282)]),'-scheme',_0x58aa8e[_0x259569(0x109)],_0x58aa8e[_0x259569(0x247)],_0x259569(0x16d)+_0x4b9553,_0x58aa8e['XjxTp']],{'cwd':_0x5aed52,'detached':!![],'stdio':[_0x58aa8e[_0x259569(0x19b)],_0x259569(0x204),_0x58aa8e[_0x259569(0x74e)]]});_0x150ba2['stdout']['on'](_0x58aa8e[_0x259569(0x190)],_0x30234d=>{const _0x2a5eb7=_0x259569;if(_0x58aa8e[_0x2a5eb7(0x477)](_0x58aa8e[_0x2a5eb7(0x49d)],_0x2a5eb7(0x1ad))){_0x439021[_0x2a5eb7(0x644)](_0x2a5eb7(0x21a)+_0x3fbc8f[_0x2a5eb7(0x4f1)]);const _0x280607={};_0x280607[_0x2a5eb7(0x66c)]=![],_0x280607['message']=_0x2a5eb7(0x518)+_0x2a3663['message'],dBhRxg[_0x2a5eb7(0x29a)](_0x3de3b2,_0x280607);}else{const _0x96202c=_0x30234d[_0x2a5eb7(0x4e4)]();(_0x96202c[_0x2a5eb7(0x58b)](_0x58aa8e[_0x2a5eb7(0x274)])||_0x96202c['includes'](_0x58aa8e[_0x2a5eb7(0x369)]))&&console[_0x2a5eb7(0x49e)](_0x2a5eb7(0x5bc)+_0x96202c[_0x2a5eb7(0x5cf)]());}}),_0x150ba2[_0x259569(0xe9)]['on'](_0x58aa8e[_0x259569(0x190)],_0x945749=>{const _0x64f6f3=_0x259569,_0x966969=_0x945749['toString']();!_0x966969[_0x64f6f3(0x58b)](_0x58aa8e[_0x64f6f3(0x566)])&&!_0x966969[_0x64f6f3(0x58b)](_0x64f6f3(0x203))&&console[_0x64f6f3(0x644)](_0x64f6f3(0x715)+_0x966969[_0x64f6f3(0x5cf)]());}),_0x150ba2['on'](_0x58aa8e['qEvsB'],_0x49ddd1=>{const _0x5eb34d=_0x259569;if(_0x58aa8e[_0x5eb34d(0x620)](_0x5eb34d(0x468),_0x5eb34d(0x468)))console[_0x5eb34d(0x644)]('❌\x20Failed\x20to\x20start\x20xcodebuild:\x20'+_0x49ddd1[_0x5eb34d(0x4f1)]);else{_0x186061[_0x5eb34d(0x644)](_0x5eb34d(0x479)+_0x242364+':',_0x5cfa75);throw _0x2f4e15;}}),_0x150ba2[_0x259569(0x50c)](),console['log'](_0x259569(0x10c));const _0x10ea50=_0x58aa8e['dBuKv'](spawn,_0x58aa8e[_0x259569(0x5ee)],[_0x58aa8e['RMJDL'],_0x58aa8e[_0x259569(0x4c4)]],{'detached':!![],'stdio':[_0x58aa8e[_0x259569(0x19b)],_0x58aa8e['BxgEo'],_0x58aa8e[_0x259569(0x74e)]]});_0x10ea50[_0x259569(0x259)]['on'](_0x58aa8e[_0x259569(0x190)],_0x463a12=>{const _0x31e651=_0x259569;if(_0x1baad0[_0x31e651(0x103)](_0x1baad0['aAGiZ'],_0x1baad0[_0x31e651(0x4ff)]))console[_0x31e651(0x49e)](_0x31e651(0x439)+_0x463a12[_0x31e651(0x4e4)]()[_0x31e651(0x5cf)]());else return{};}),_0x10ea50['on'](_0x58aa8e[_0x259569(0x2d5)],_0x385d93=>{const _0x54ab8d=_0x259569;console['error']('❌\x20Failed\x20to\x20start\x20iproxy:\x20'+_0x385d93[_0x54ab8d(0x4f1)]),console[_0x54ab8d(0x644)]('\x20\x20\x20Make\x20sure\x20libimobiledevice\x20is\x20installed:\x20brew\x20install\x20libimobiledevice');}),_0x10ea50[_0x259569(0x50c)]();const _0xacd90d={};_0xacd90d['xcodebuild']=_0x150ba2[_0x259569(0x519)],_0xacd90d[_0x259569(0x1a4)]=_0x10ea50[_0x259569(0x519)],wdaProcesses[_0x259569(0x2db)](_0x135750,_0xacd90d),console[_0x259569(0x49e)](_0x259569(0x582)+_0x135750+_0x259569(0x75a)+_0x150ba2[_0x259569(0x519)]),_0x58aa8e[_0x259569(0x52a)](setTimeout,()=>{const _0x31708c=_0x259569,_0x2456b2={'toKtI':function(_0x552c78,_0x5dffae){const _0x44b763=_0x8de2;return _0x58aa8e[_0x44b763(0x163)](_0x552c78,_0x5dffae);},'JNxWi':function(_0x374ae3,_0x392641){const _0x39576a=_0x8de2;return _0x58aa8e[_0x39576a(0x428)](_0x374ae3,_0x392641);},'yjaxC':_0x58aa8e[_0x31708c(0x536)],'kfdNe':_0x31708c(0x1ec),'RRuys':_0x58aa8e[_0x31708c(0x128)],'kxjTc':function(_0x356d5e,_0x4a48a5){const _0x2f0f82=_0x31708c;return _0x58aa8e[_0x2f0f82(0x35d)](_0x356d5e,_0x4a48a5);},'uJCxI':_0x31708c(0x413),'KaUwt':_0x31708c(0x2d3),'AUuml':_0x58aa8e[_0x31708c(0x3da)],'tuIVM':_0x58aa8e[_0x31708c(0x3d1)],'gbPva':_0x58aa8e[_0x31708c(0x662)]};if(_0x58aa8e['vFRNd'](_0x58aa8e[_0x31708c(0x231)],_0x58aa8e['bTAFC']))return _0x24ba37['error'](_0x31708c(0x635)+_0x4b2a49[_0x31708c(0x4dd)](',\x20')+']'),dBhRxg['ywlWN'](_0x9bcfb9,{'success':![],'error':dBhRxg[_0x31708c(0x316)]});else{const _0xf54894=_0x58aa8e[_0x31708c(0x6a0)](spawn,_0x58aa8e[_0x31708c(0x621)],['-s',_0x31708c(0x10e),'5',_0x58aa8e['Lpvut']]);let _0x3a4a90='';_0xf54894[_0x31708c(0x259)]['on'](_0x58aa8e[_0x31708c(0x190)],_0x59abb5=>{const _0x2d0a7e=_0x31708c;_0x3a4a90+=_0x59abb5[_0x2d0a7e(0x4e4)]();}),_0xf54894['on'](_0x58aa8e['rRKET'],async()=>{const _0x39368a=_0x31708c,_0x4b7c20={};_0x4b7c20[_0x39368a(0x498)]=function(_0x2fae8f,_0x4d3aa1){return _0x2fae8f===_0x4d3aa1;},_0x4b7c20[_0x39368a(0x392)]=_0x2456b2[_0x39368a(0x5a7)],_0x4b7c20['sUTIs']=_0x2456b2[_0x39368a(0x691)];const _0x526649=_0x4b7c20;if(_0x3a4a90[_0x39368a(0x58b)](_0x2456b2[_0x39368a(0x221)])){if(_0x2456b2[_0x39368a(0x22d)](_0x2456b2[_0x39368a(0x393)],_0x2456b2['uJCxI']))_0x21d748[_0x39368a(0x644)](_0x39368a(0x54f)+_0x1253e4[_0x39368a(0x4f1)]);else{console['log'](_0x39368a(0xf4)+_0x135750),console[_0x39368a(0x49e)]('📱\x20Creating\x20WDA\x20session\x20for\x20'+_0x135750+_0x39368a(0x57b));const _0xed82b0=await createWDASession(_0x2456b2[_0x39368a(0x5fd)],_0x135750);_0xed82b0['success']?console['log'](_0x39368a(0x3f4)+_0xed82b0[_0x39368a(0x143)]):console['log']('⚠️\x20\x20Session\x20creation\x20failed,\x20will\x20be\x20created\x20on\x20first\x20command');const _0x9dbfbd=connectedDevices[_0x39368a(0x454)](_0x4bb617=>_0x4bb617[_0x39368a(0x4b8)]===_0x135750);if(_0x2456b2[_0x39368a(0x453)](_0x9dbfbd,-0x1)){if(_0x2456b2[_0x39368a(0x453)](_0x2456b2[_0x39368a(0x4bc)],_0x2456b2[_0x39368a(0x4bc)])){_0xbf940f[_0x39368a(0x49e)](_0x39368a(0x253)+_0x559667+'\x20from\x20ADB');const _0x44cee9=_0x28e232[_0x39368a(0x454)](_0x113419=>_0x113419['name']===_0x4866af);_0x2456b2['toKtI'](_0x44cee9,-0x1)&&(_0x23708d[_0x44cee9][_0x39368a(0x365)]=_0x39368a(0x3b8));_0x4f0502[_0x39368a(0x374)][_0x39368a(0x11d)](_0x5e441c=>{const _0x3413c7=_0x39368a;if(_0x526649[_0x3413c7(0x498)](_0x5e441c['readyState'],_0x190f73[_0x3413c7(0x717)])){const _0x5e20c9={};_0x5e20c9[_0x3413c7(0x14d)]=_0x526649['zYJuC'],_0x5e20c9[_0x3413c7(0x1a6)]=_0x28bc60,_0x5e441c['send'](_0x12b76b[_0x3413c7(0x2a5)](_0x5e20c9));}});const _0x3906fa={};_0x3906fa[_0x39368a(0x66c)]=!![],_0x3906fa['message']=_0x39368a(0x5c6)+_0x1001c5+_0x39368a(0x3f5),_0x2456b2[_0x39368a(0x2ea)](_0x3ab201,_0x3906fa);}else connectedDevices[_0x9dbfbd]['status']=_0x2456b2[_0x39368a(0x47b)];}wss[_0x39368a(0x374)]['forEach'](_0x393609=>{const _0x549ffe=_0x39368a;if(_0x393609[_0x549ffe(0x4aa)]===WebSocket[_0x549ffe(0x717)]){const _0x16929c={};_0x16929c[_0x549ffe(0x14d)]=_0x526649[_0x549ffe(0x392)],_0x16929c[_0x549ffe(0x1a6)]=connectedDevices,_0x393609[_0x549ffe(0x475)](JSON['stringify'](_0x16929c)),_0x393609[_0x549ffe(0x475)](JSON[_0x549ffe(0x2a5)]({'type':_0x526649['sUTIs'],'output':'✅\x20'+_0x135750+_0x549ffe(0xde)+'─'[_0x549ffe(0x5fb)](0x32)+'\x0a','device':_0x135750}));}});}}else _0x2456b2['toKtI'](_0x2456b2[_0x39368a(0x220)],_0x2456b2[_0x39368a(0x220)])?_0x26a801+='GEMINI_API_KEY='+_0x1c7ac9+'\x0a':console[_0x39368a(0x49e)](_0x39368a(0x51c)+_0x135750+_0x39368a(0x57b));});}},0x1f40);const _0x8756ab={};_0x8756ab[_0x259569(0x66c)]=!![],_0x8756ab[_0x259569(0x4f1)]='Connecting\x20to\x20'+_0x135750+_0x259569(0x70c),_0x8756ab[_0x259569(0x294)]=!![],_0x58aa8e['lFscn'](_0x37a0b0,_0x8756ab);}}}),_0x51b098['on'](_0x3319e8[_0x46c8bc(0x764)],()=>{const _0x18f223=_0x46c8bc;if(_0x58aa8e['dWNxp'](_0x58aa8e[_0x18f223(0x2c2)],_0x18f223(0x482))){_0x961d7b[_0x18f223(0x644)](_0x18f223(0x279)+_0x1c6030+':',_0x1743e1[_0x18f223(0x4f1)]);const _0x2bc61e={};return _0x2bc61e[_0x18f223(0x66c)]=![],_0x2bc61e['error']=_0x3f55d2[_0x18f223(0x4f1)],_0x2bc61e;}else{console[_0x18f223(0x49e)](_0x18f223(0x3ea));const _0xe59a6a={};_0xe59a6a['success']=![],_0xe59a6a[_0x18f223(0x4f1)]=_0x18f223(0x5f8),_0x58aa8e[_0x18f223(0x387)](_0x37a0b0,_0xe59a6a);}});}else{const _0xb4af03=_0x3319e8[_0x46c8bc(0x694)](spawn,_0x3319e8['bAZIU'],['-s',_0x46c8bc(0x10e),'3','http://'+_0x2c1bf7+':8100/status']);let _0x4343d6='';_0xb4af03['stdout']['on'](_0x3319e8['CucJO'],_0x39bf51=>{_0x4343d6+=_0x39bf51['toString']();}),_0xb4af03['on'](_0x3319e8[_0x46c8bc(0x353)],async()=>{const _0x4130c5=_0x46c8bc,_0x76abb7={'EeUbC':_0x58aa8e['LtIHU'],'PcZWT':function(_0x1823db,_0x28daf5){return _0x1823db!==_0x28daf5;},'OyjbB':function(_0x1fe0f8,_0x339e53){return _0x58aa8e['QXrWZ'](_0x1fe0f8,_0x339e53);},'trSHg':_0x58aa8e['oVPBU'],'coHql':_0x4130c5(0x24e),'tONtK':function(_0x294f0b,_0x2ab2b1,_0x18e0b6){return _0x58aa8e['AtJgV'](_0x294f0b,_0x2ab2b1,_0x18e0b6);},'VGRGY':_0x58aa8e['KAfBJ'],'QCGSx':function(_0x465328,_0x1b8257){return _0x58aa8e['hYZGx'](_0x465328,_0x1b8257);},'OWZld':_0x58aa8e[_0x4130c5(0x621)],'POkQY':_0x58aa8e[_0x4130c5(0x613)],'mJiCz':_0x4130c5(0x760),'mTtHA':_0x58aa8e[_0x4130c5(0x225)]};if(_0x58aa8e[_0x4130c5(0x13f)]===_0x4130c5(0x698))_0x2cb1d9[_0x4130c5(0x644)](_0x58aa8e[_0x4130c5(0x719)],_0x5bb444[_0x4130c5(0x4f1)]);else{if(_0x4343d6[_0x4130c5(0x58b)](_0x58aa8e[_0x4130c5(0x128)])){console[_0x4130c5(0x49e)](_0x4130c5(0x1e5)+_0x135750),console[_0x4130c5(0x49e)](_0x4130c5(0x515)+_0x135750+_0x4130c5(0x57b));const _0x76a6a1=await _0x58aa8e['XFjqj'](createWDASession,_0x2c1bf7,_0x135750);_0x76a6a1[_0x4130c5(0x66c)]?_0x4130c5(0x37c)!==_0x58aa8e[_0x4130c5(0x1ff)]?console[_0x4130c5(0x49e)]('✅\x20Session\x20created:\x20'+_0x76a6a1['sessionId']):(_0xd5bf4c[_0x4130c5(0x49e)](_0x4130c5(0x5b7)+_0x55c785),_0x5542d2[_0x4130c5(0x4fe)](_0x19feea+':5555')):_0x58aa8e[_0x4130c5(0x6dd)](_0x58aa8e[_0x4130c5(0x556)],_0x58aa8e[_0x4130c5(0x194)])?console['log']('⚠️\x20\x20Session\x20creation\x20failed,\x20will\x20be\x20created\x20on\x20first\x20command'):_0x2ee154[_0x4130c5(0x49e)](_0x4130c5(0x4de)+_0x4260d2[_0x4130c5(0x4f1)]);const _0x8a8fab=connectedDevices[_0x4130c5(0x454)](_0x186e69=>_0x186e69[_0x4130c5(0x4b8)]===_0x135750);_0x58aa8e['ZYWYI'](_0x8a8fab,-0x1)&&(connectedDevices[_0x8a8fab][_0x4130c5(0x365)]=_0x58aa8e[_0x4130c5(0x3d1)]);wss['clients']['forEach'](_0x321dc1=>{const _0x1ce669=_0x4130c5;if(_0x58aa8e[_0x1ce669(0x20a)](_0x58aa8e['yXhHz'],_0x58aa8e[_0x1ce669(0x18c)])){if(_0x58aa8e[_0x1ce669(0x62a)](_0x321dc1[_0x1ce669(0x4aa)],WebSocket[_0x1ce669(0x717)])){const _0x22fd37={};_0x22fd37[_0x1ce669(0x14d)]=_0x58aa8e[_0x1ce669(0x536)],_0x22fd37[_0x1ce669(0x1a6)]=connectedDevices,_0x321dc1[_0x1ce669(0x475)](JSON[_0x1ce669(0x2a5)](_0x22fd37));}}else _0x5961e3+=_0x20c9a2[_0x1ce669(0x4e4)]();});const _0x753db4={};_0x753db4[_0x4130c5(0x66c)]=!![],_0x753db4['message']=_0x4130c5(0x73a)+_0x135750+_0x4130c5(0x5a2),_0x58aa8e['JiOSz'](_0x37a0b0,_0x753db4);}else{console[_0x4130c5(0x49e)](_0x4130c5(0x5f2)+_0x135750+_0x4130c5(0x43a));const _0x23e789=process.env.WDA_PATH||path[_0x4130c5(0x4dd)](process.env.HOME,_0x58aa8e[_0x4130c5(0x4a4)]);console[_0x4130c5(0x49e)]('📂\x20WDA\x20Path:\x20'+_0x23e789),console[_0x4130c5(0x49e)]('📱\x20Device\x20UDID:\x20'+_0x4b9553),console[_0x4130c5(0x49e)](_0x4130c5(0x618)+_0x2c1bf7);const _0x1266b2=_0x58aa8e[_0x4130c5(0x2ec)](spawn,_0x58aa8e['dxWrk'],[_0x4130c5(0x2b2),_0x58aa8e[_0x4130c5(0x235)],path[_0x4130c5(0x4dd)](_0x23e789,_0x58aa8e[_0x4130c5(0x282)]),_0x58aa8e[_0x4130c5(0x561)],_0x4130c5(0x1c2),_0x58aa8e[_0x4130c5(0x247)],_0x4130c5(0x16d)+_0x4b9553,_0x58aa8e[_0x4130c5(0x47d)]],{'cwd':_0x23e789,'detached':!![],'stdio':[_0x58aa8e[_0x4130c5(0x19b)],_0x58aa8e['BxgEo'],_0x58aa8e[_0x4130c5(0x74e)]]});_0x1266b2['stdout']['on'](_0x58aa8e['YUktF'],_0x3df4e7=>{const _0x382bd4=_0x4130c5,_0x16e489=_0x3df4e7[_0x382bd4(0x4e4)]();(_0x16e489[_0x382bd4(0x58b)](_0x58aa8e[_0x382bd4(0x274)])||_0x16e489[_0x382bd4(0x58b)](_0x58aa8e['NbEsT']))&&console[_0x382bd4(0x49e)](_0x382bd4(0x36e)+_0x135750+_0x382bd4(0x5fe)+_0x16e489[_0x382bd4(0x5cf)]());}),_0x1266b2[_0x4130c5(0xe9)]['on'](_0x58aa8e[_0x4130c5(0x190)],_0x489a6b=>{const _0x137d62=_0x4130c5,_0x375fda=_0x489a6b['toString']();!_0x375fda[_0x137d62(0x58b)]('note:')&&!_0x375fda[_0x137d62(0x58b)](_0x76abb7[_0x137d62(0x224)])&&console[_0x137d62(0x644)](_0x137d62(0x706)+_0x135750+_0x137d62(0x5fe)+_0x375fda[_0x137d62(0x5cf)]());}),_0x1266b2['on'](_0x58aa8e[_0x4130c5(0x2d5)],_0x86d5f3=>{const _0x50d36a=_0x4130c5;console['error'](_0x50d36a(0x178)+_0x135750+':\x20'+_0x86d5f3[_0x50d36a(0x4f1)]);}),_0x1266b2[_0x4130c5(0x50c)]();const _0x3e6b0a={};_0x3e6b0a[_0x4130c5(0x23e)]=_0x1266b2[_0x4130c5(0x519)],wdaProcesses[_0x4130c5(0x2db)](_0x135750,_0x3e6b0a),console[_0x4130c5(0x49e)]('✅\x20WDA\x20starting\x20for\x20'+_0x135750+'\x20(wireless).\x20Process\x20ID:\x20'+_0x1266b2[_0x4130c5(0x519)]),_0x58aa8e[_0x4130c5(0x68a)](setTimeout,()=>{const _0x47ce42=_0x4130c5,_0xdaa932={'XnnQs':function(_0x4ea8a5,_0x17157e){const _0x455255=_0x8de2;return _0x76abb7[_0x455255(0x245)](_0x4ea8a5,_0x17157e);},'wvxxK':'GZXiW','hGGUx':function(_0x3ae06a,_0xff224f){const _0x390320=_0x8de2;return _0x76abb7[_0x390320(0x376)](_0x3ae06a,_0xff224f);},'wkRAo':_0x76abb7[_0x47ce42(0x552)],'Sefuq':_0x76abb7[_0x47ce42(0x350)],'VtJGX':function(_0x563497,_0x3b578b,_0x5beb2d){const _0x1ac085=_0x47ce42;return _0x76abb7[_0x1ac085(0x3e5)](_0x563497,_0x3b578b,_0x5beb2d);},'gYgwM':function(_0xf9ec8d,_0xa4da00){const _0x5843a1=_0x47ce42;return _0x76abb7[_0x5843a1(0x245)](_0xf9ec8d,_0xa4da00);},'hFONA':_0x76abb7[_0x47ce42(0x22a)],'hbWOs':function(_0x1d69be,_0x3334c8){const _0xcbd4bc=_0x47ce42;return _0x76abb7[_0xcbd4bc(0x541)](_0x1d69be,_0x3334c8);},'gyABu':function(_0x5d1cfd,_0x2be35a){const _0x120de1=_0x47ce42;return _0x76abb7[_0x120de1(0x541)](_0x5d1cfd,_0x2be35a);}},_0x423752=spawn(_0x76abb7[_0x47ce42(0xe8)],['-s',_0x76abb7[_0x47ce42(0x560)],'5',_0x47ce42(0x3de)+_0x2c1bf7+_0x47ce42(0x2d4)]);let _0x3ff0b5='';_0x423752[_0x47ce42(0x259)]['on'](_0x76abb7['mJiCz'],_0x279479=>{const _0x2afd71=_0x47ce42;_0x3ff0b5+=_0x279479[_0x2afd71(0x4e4)]();}),_0x423752['on'](_0x76abb7['mTtHA'],async()=>{const _0x2d4130=_0x47ce42,_0xdd402c={};_0xdd402c[_0x2d4130(0x5ab)]=_0xdaa932['wkRAo'];const _0x489507=_0xdd402c;if(_0x3ff0b5[_0x2d4130(0x58b)](_0xdaa932[_0x2d4130(0x29e)])){console[_0x2d4130(0x49e)](_0x2d4130(0xf4)+_0x135750),console['log'](_0x2d4130(0x515)+_0x135750+_0x2d4130(0x57b));const _0x4be1a1=await _0xdaa932['VtJGX'](createWDASession,_0x2c1bf7,_0x135750);_0x4be1a1['success']?console[_0x2d4130(0x49e)](_0x2d4130(0x3f4)+_0x4be1a1[_0x2d4130(0x143)]):console[_0x2d4130(0x49e)]('⚠️\x20\x20Session\x20creation\x20failed,\x20will\x20be\x20created\x20on\x20first\x20command');const _0x1679df=connectedDevices[_0x2d4130(0x454)](_0x3ec616=>_0x3ec616[_0x2d4130(0x4b8)]===_0x135750);_0xdaa932[_0x2d4130(0x731)](_0x1679df,-0x1)&&(connectedDevices[_0x1679df][_0x2d4130(0x365)]=_0xdaa932[_0x2d4130(0x2bf)]);wss[_0x2d4130(0x374)]['forEach'](_0x2845fe=>{const _0xecd3e5=_0x2d4130;if(_0xdaa932[_0xecd3e5(0x4ef)](_0xdaa932[_0xecd3e5(0x15e)],_0xdaa932[_0xecd3e5(0x15e)])){if(_0x92ec26['readyState']===_0xe91cf8[_0xecd3e5(0x717)]){const _0x2a190e={};_0x2a190e['type']=_0x489507[_0xecd3e5(0x5ab)],_0x2a190e['devices']=_0x2ed64b,_0x304214[_0xecd3e5(0x475)](_0x4ec7bd[_0xecd3e5(0x2a5)](_0x2a190e));}}else{if(_0xdaa932['hGGUx'](_0x2845fe['readyState'],WebSocket['OPEN'])){const _0xd0c734={};_0xd0c734['type']=_0xdaa932[_0xecd3e5(0x70e)],_0xd0c734['devices']=connectedDevices,_0x2845fe[_0xecd3e5(0x475)](JSON[_0xecd3e5(0x2a5)](_0xd0c734));}}});const _0x2a108a={};_0x2a108a[_0x2d4130(0x66c)]=!![],_0x2a108a[_0x2d4130(0x4f1)]=_0x2d4130(0x73a)+_0x135750+_0x2d4130(0x681),_0x2a108a['wdaStarted']=!![],_0xdaa932[_0x2d4130(0x4b5)](_0x37a0b0,_0x2a108a);}else{console[_0x2d4130(0x49e)](_0x2d4130(0x48f)+_0x135750+_0x2d4130(0x173));const _0x161f15={};_0x161f15['success']=!![],_0x161f15['message']=_0x2d4130(0x594)+_0x135750+_0x2d4130(0x1ed),_0x161f15[_0x2d4130(0x294)]=!![],_0xdaa932['gyABu'](_0x37a0b0,_0x161f15);}});},0x2710);}}}),_0xb4af03['on'](_0x3319e8['Hxakc'],()=>{const _0x24e5f8=_0x46c8bc;console[_0x24e5f8(0x49e)]('⚠️\x20\x20Cannot\x20reach\x20'+_0x135750+_0x24e5f8(0x320)+_0x2c1bf7+_0x24e5f8(0x5b8));const _0x4a50df={};_0x4a50df[_0x24e5f8(0x66c)]=![],_0x4a50df[_0x24e5f8(0x4f1)]=_0x24e5f8(0x141)+_0x135750+_0x24e5f8(0x320)+_0x2c1bf7+'.\x20Check\x20network\x20connection.',_0x58aa8e[_0x24e5f8(0x516)](_0x4c97b5,_0x4a50df);});}});}async function disconnectFromDevice(_0x21ca1a){const _0x4e6106=_0x320de1,_0x2c8f11={'hDIil':function(_0x10c4e9,_0x4a6c91){return _0x10c4e9!==_0x4a6c91;},'MAOmi':_0x4e6106(0x50e),'cIAjI':'devices_updated','tBqsC':_0x4e6106(0x2be),'fejDD':_0x4e6106(0x57f),'Shwnn':function(_0x5f0720,_0x1d968b){return _0x5f0720!==_0x1d968b;},'mGurq':'cHLhi','ApsxM':_0x4e6106(0x236),'DoeAJ':'offline','Tgqwq':_0x4e6106(0x256),'zMDTK':function(_0x4b812a,_0x820e50){return _0x4b812a===_0x820e50;},'zrAca':_0x4e6106(0xd7),'tzmXB':_0x4e6106(0x4e6),'fkCXj':_0x4e6106(0x27e),'ZvvhL':_0x4e6106(0x584),'OUjSG':_0x4e6106(0x416),'VjShc':function(_0x175589,_0x10e0af,_0x2fd1ad){return _0x175589(_0x10e0af,_0x2fd1ad);},'ixEMP':function(_0x187c96,_0x489f89){return _0x187c96===_0x489f89;},'xdodX':_0x4e6106(0x4a0),'DvpKe':_0x4e6106(0x42e),'oiHST':function(_0x2e31ef,_0x2ebea5){return _0x2e31ef!==_0x2ebea5;},'ltUtv':_0x4e6106(0x2a8),'pFOJX':function(_0x2e71b5,_0x30c03d){return _0x2e71b5!==_0x30c03d;},'bkDwv':'EYspO','EtaJn':_0x4e6106(0x138),'aMqDb':'JNImj','SCAes':_0x4e6106(0x267),'HGoqK':function(_0xb6eae7,_0x5eac12){return _0xb6eae7===_0x5eac12;},'Viuzj':_0x4e6106(0x57d),'HMYNS':function(_0x82b1bd,_0x49e016,_0x53c322){return _0x82b1bd(_0x49e016,_0x53c322);},'ndHSc':_0x4e6106(0x4f6),'UIHKT':function(_0x3ec12e,_0x5e11ba,_0x58946f){return _0x3ec12e(_0x5e11ba,_0x58946f);}};return new Promise((_0x137d59,_0x24d4a0)=>{const _0xcec65e=_0x4e6106,_0x4fd9b8={'dmMbQ':function(_0x3de07f,_0x328068){return _0x3de07f||_0x328068;},'OIssk':_0x2c8f11[_0xcec65e(0x299)],'EbLfs':function(_0x4acff1,_0x34aac4){const _0x3738c6=_0xcec65e;return _0x2c8f11[_0x3738c6(0x55a)](_0x4acff1,_0x34aac4);},'vBKgC':_0x2c8f11[_0xcec65e(0x504)],'qJIbt':function(_0x2d0221,_0x3da498){return _0x2d0221!==_0x3da498;},'Eneth':_0x2c8f11[_0xcec65e(0x177)],'uRuWT':_0x2c8f11['OUjSG'],'ikncH':_0x2c8f11[_0xcec65e(0x319)],'tEhln':function(_0x1876fd,_0x57316c){return _0x1876fd(_0x57316c);}},{name:_0x11b376,connectionType:_0x54de5f,udid:_0x6d10d,platform:_0x25d101}=_0x21ca1a;console[_0xcec65e(0x49e)](_0xcec65e(0x1ae)+_0x11b376+'\x20('+_0x54de5f+_0xcec65e(0x509)+_0x25d101+_0xcec65e(0x6b4));if(_0x2c8f11[_0xcec65e(0x55a)](_0x25d101,_0xcec65e(0x5a0))){console[_0xcec65e(0x49e)](_0xcec65e(0x70b)+_0x11b376),_0x2c8f11[_0xcec65e(0x50b)](stopUIAutomator2Session,_0x6d10d,_0x11b376)['catch'](_0x219268=>{const _0x5a1463=_0xcec65e;console[_0x5a1463(0x644)](_0x5a1463(0x207)+_0x219268['message']);});if(_0x2c8f11[_0xcec65e(0x575)](_0x54de5f,_0x2c8f11[_0xcec65e(0x512)])){const _0x452405=_0x2c8f11['VjShc'](spawn,_0x2c8f11[_0xcec65e(0x530)],[_0xcec65e(0x31d),_0x6d10d]);_0x452405['on'](_0xcec65e(0x4f6),_0x50efa0=>{const _0x32994c=_0xcec65e,_0x5f18a6={'xYUCw':function(_0x2a2ba5,_0x380ac6){return _0x2a2ba5===_0x380ac6;},'uNGtt':function(_0x504ad8,_0x27499a){const _0x4f422e=_0x8de2;return _0x2c8f11[_0x4f422e(0x506)](_0x504ad8,_0x27499a);},'gIPvj':_0x2c8f11[_0x32994c(0x6ae)],'wNAdL':_0x2c8f11[_0x32994c(0x407)],'SBWVZ':_0x2c8f11[_0x32994c(0x660)],'uacEa':_0x2c8f11[_0x32994c(0x61c)]};if(_0x2c8f11[_0x32994c(0x1d9)](_0x2c8f11[_0x32994c(0x4c2)],_0x2c8f11[_0x32994c(0x4ae)])){console[_0x32994c(0x49e)]('✅\x20Disconnected\x20Android\x20device\x20'+_0x11b376+_0x32994c(0x3bc));const _0x4b425a=connectedDevices[_0x32994c(0x454)](_0x1601ab=>_0x1601ab[_0x32994c(0x4b8)]===_0x11b376);_0x2c8f11[_0x32994c(0x506)](_0x4b425a,-0x1)&&(connectedDevices[_0x4b425a]['status']=_0x2c8f11[_0x32994c(0x319)]);wss[_0x32994c(0x374)]['forEach'](_0x4df7de=>{const _0x347b4a=_0x32994c;if(_0x5f18a6['xYUCw'](_0x4df7de['readyState'],WebSocket['OPEN'])){if(_0x5f18a6[_0x347b4a(0x22b)](_0x347b4a(0x50e),_0x5f18a6[_0x347b4a(0x2f7)]))_0xcbefff[_0x347b4a(0x49e)](_0x347b4a(0x3d7)+_0x4c259d[_0x347b4a(0x4f1)]);else{const _0x131dbc={};_0x131dbc[_0x347b4a(0x14d)]=_0x5f18a6['wNAdL'],_0x131dbc['devices']=connectedDevices,_0x4df7de[_0x347b4a(0x475)](JSON[_0x347b4a(0x2a5)](_0x131dbc));}}});const _0x529a80={};_0x529a80['success']=!![],_0x529a80[_0x32994c(0x4f1)]=_0x32994c(0x5c6)+_0x11b376+_0x32994c(0x3f5),_0x137d59(_0x529a80);}else{_0x55310b[_0x32994c(0x644)](_0x5f18a6[_0x32994c(0x352)]);const _0x23327f={};return _0x23327f[_0x32994c(0x66c)]=![],_0x23327f['error']=_0x5f18a6[_0x32994c(0xe0)],_0x49127e[_0x32994c(0x365)](0x190)[_0x32994c(0x169)](_0x23327f);}});}else{const _0x5c96e1=connectedDevices['findIndex'](_0x1620bb=>_0x1620bb[_0xcec65e(0x4b8)]===_0x11b376);_0x2c8f11[_0xcec65e(0x25f)](_0x5c96e1,-0x1)&&(connectedDevices[_0x5c96e1][_0xcec65e(0x365)]=_0xcec65e(0x3b8));wss[_0xcec65e(0x374)]['forEach'](_0x5d4f8d=>{const _0x1bff54=_0xcec65e;if(_0x5d4f8d[_0x1bff54(0x4aa)]===WebSocket[_0x1bff54(0x717)]){const _0x5ccd95={};_0x5ccd95[_0x1bff54(0x14d)]=_0x1bff54(0x230),_0x5ccd95[_0x1bff54(0x1a6)]=connectedDevices,_0x5d4f8d[_0x1bff54(0x475)](JSON[_0x1bff54(0x2a5)](_0x5ccd95));}});const _0x2e5810={};_0x2e5810[_0xcec65e(0x66c)]=!![],_0x2e5810[_0xcec65e(0x4f1)]=_0xcec65e(0x5c6)+_0x11b376,_0x137d59(_0x2e5810);}return;}const _0x406041=connectedDevices[_0xcec65e(0x2fa)](_0x20461c=>_0x20461c[_0xcec65e(0x4b8)]===_0x11b376),_0x118c76=_0x406041?.[_0xcec65e(0x2cf)];if(wdaProcesses['has'](_0x11b376)){const _0x1b0178=wdaProcesses[_0xcec65e(0x5af)](_0x11b376);try{if(_0x1b0178[_0xcec65e(0x23e)])try{process[_0xcec65e(0x57c)](_0x1b0178[_0xcec65e(0x23e)],_0x2c8f11[_0xcec65e(0x72a)]),console[_0xcec65e(0x49e)](_0xcec65e(0x708)+_0x11b376+_0xcec65e(0x3f3)+_0x1b0178['xcodebuild']+')');}catch(_0x1c8a1e){if(_0x2c8f11['pFOJX'](_0x2c8f11[_0xcec65e(0x6c2)],_0x2c8f11[_0xcec65e(0x51e)]))console['log'](_0xcec65e(0x5b2)+_0x1b0178[_0xcec65e(0x23e)]+_0xcec65e(0x485));else{if(!_0x53959d||!_0x75e93c)return![];return _0x11bd7a['commands'][_0xcec65e(0x507)]({'timestamp':new _0xb02c36()[_0xcec65e(0x1c4)](),'devices':_0x40415b,'originalCommand':_0x8a6e5a,'useAI':_0x316603,'finalCommand':_0x4fd9b8[_0xcec65e(0x16f)](_0x5e4bb1,_0x27f6bb)}),_0x1100b3[_0xcec65e(0x49e)](_0xcec65e(0x6f7)+_0x39ede9+'\x20('+_0x470f9c['commands'][_0xcec65e(0x162)]+_0xcec65e(0x69f)),!![];}}if(_0x1b0178[_0xcec65e(0x1a4)])try{process[_0xcec65e(0x57c)](_0x1b0178[_0xcec65e(0x1a4)],_0x2c8f11['ltUtv']),console['log'](_0xcec65e(0x66f)+_0x11b376+'\x20(PID:\x20'+_0x1b0178[_0xcec65e(0x1a4)]+')');}catch(_0x15b0da){console['log'](_0xcec65e(0x501)+_0x1b0178[_0xcec65e(0x1a4)]+_0xcec65e(0x485));}wdaProcesses[_0xcec65e(0x4fe)](_0x11b376);}catch(_0x401ce4){_0x2c8f11[_0xcec65e(0x546)]!==_0x2c8f11[_0xcec65e(0x24b)]?console[_0xcec65e(0x644)]('Error\x20cleaning\x20up\x20tracked\x20processes\x20for\x20'+_0x11b376+':',_0x401ce4):_0x3123f4['json']({'status':'ok','timestamp':_0x593c1f[_0xcec65e(0x2b8)]()});}}if(_0x118c76){console[_0xcec65e(0x49e)](_0xcec65e(0x17c)+_0x118c76+_0xcec65e(0x1d6)+_0x11b376+_0xcec65e(0x57b));const _0x3542d5=_0x2c8f11[_0xcec65e(0x50b)](spawn,'sh',['-c','lsof\x20-ti:'+_0x118c76+_0xcec65e(0x1c9)]);_0x3542d5['on']('close',()=>{const _0x5ef26f=_0xcec65e,_0x24748c={};_0x24748c['YHiut']=_0x2c8f11[_0x5ef26f(0x38d)],_0x24748c[_0x5ef26f(0x3a7)]=_0x5ef26f(0x233);const _0x3b7f94=_0x24748c;if(_0x2c8f11[_0x5ef26f(0x55a)](_0x5ef26f(0x431),_0x2c8f11[_0x5ef26f(0x1e4)])){const _0x58d874=_0x35fbdb['toString']();(_0x58d874['includes'](pfxWCj[_0x5ef26f(0x164)])||_0x58d874[_0x5ef26f(0x58b)](pfxWCj['OeFaE']))&&_0x176c4d[_0x5ef26f(0x49e)](_0x5ef26f(0x36e)+_0x5c6035+_0x5ef26f(0x5fe)+_0x58d874[_0x5ef26f(0x5cf)]());}else console[_0x5ef26f(0x49e)](_0x5ef26f(0x215)+_0x118c76+_0x5ef26f(0x1d6)+_0x11b376);});}if(_0x6d10d&&_0x2c8f11[_0xcec65e(0x147)](_0x54de5f,_0x2c8f11[_0xcec65e(0x3a9)])){console[_0xcec65e(0x49e)](_0xcec65e(0x26f)+_0x6d10d+_0xcec65e(0x57b));const _0x10496c=_0x2c8f11[_0xcec65e(0x3db)](spawn,'sh',['-c',_0xcec65e(0x712)+_0x6d10d+_0xcec65e(0x6e0)]);_0x10496c['on'](_0x2c8f11[_0xcec65e(0x423)],()=>{const _0x49c40c=_0xcec65e;console['log'](_0x49c40c(0x6b1)+_0x11b376);});}if(_0x2c8f11['ixEMP'](_0x54de5f,_0x2c8f11[_0xcec65e(0x3a9)])&&_0x118c76){const _0x3ed048=_0x2c8f11[_0xcec65e(0x3db)](spawn,'sh',['-c',_0xcec65e(0x119)+_0x118c76+_0xcec65e(0x6e0)]);_0x3ed048['on'](_0x2c8f11[_0xcec65e(0x423)],()=>{const _0x56b841=_0xcec65e;console[_0x56b841(0x49e)](_0x56b841(0x214)+_0x11b376);});}_0x2c8f11[_0xcec65e(0x3a1)](setTimeout,()=>{const _0x4cb65e=_0xcec65e,_0x517bc2={'rHSEK':function(_0x460b78,_0x3a5139){return _0x460b78(_0x3a5139);},'sdKBa':function(_0x7d13d2,_0x5208d5){const _0x2aef1e=_0x8de2;return _0x4fd9b8[_0x2aef1e(0x1b9)](_0x7d13d2,_0x5208d5);}};if(_0x4fd9b8[_0x4cb65e(0x118)]!==_0x4fd9b8[_0x4cb65e(0x118)]){_0x21fe33['error']('['+_0xad2d5b[_0x4cb65e(0x4b8)]+_0x4cb65e(0x688),_0x16912b);const _0x1803ec={};_0x1803ec['success']=![],_0x1803ec[_0x4cb65e(0x644)]=_0x20fd33[_0x4cb65e(0x4f1)],_0x1803ec[_0x4cb65e(0x120)]=_0x320164[_0x4cb65e(0x4b8)],mIIEpf[_0x4cb65e(0x686)](_0x803390,_0x1803ec);}else{const _0x478bba=connectedDevices[_0x4cb65e(0x454)](_0x5c5468=>_0x5c5468[_0x4cb65e(0x4b8)]===_0x11b376);_0x478bba!==-0x1&&(_0x4fd9b8[_0x4cb65e(0x31e)](_0x4fd9b8[_0x4cb65e(0x5db)],_0x4fd9b8['uRuWT'])?connectedDevices[_0x478bba][_0x4cb65e(0x365)]=_0x4fd9b8['ikncH']:_0x209c58[_0x105b31][_0x4cb65e(0x365)]=FZeYnB['OIssk']);wss[_0x4cb65e(0x374)][_0x4cb65e(0x11d)](_0x48bb12=>{const _0x1f5d1e=_0x4cb65e;if(_0x517bc2[_0x1f5d1e(0x1d8)](_0x48bb12[_0x1f5d1e(0x4aa)],WebSocket['OPEN'])){const _0x5f3932={};_0x5f3932['type']=_0x1f5d1e(0x230),_0x5f3932[_0x1f5d1e(0x1a6)]=connectedDevices,_0x48bb12[_0x1f5d1e(0x475)](JSON[_0x1f5d1e(0x2a5)](_0x5f3932));}}),console[_0x4cb65e(0x49e)](_0x4cb65e(0x395)+_0x11b376);const _0x51dfdb={};_0x51dfdb[_0x4cb65e(0x66c)]=!![],_0x51dfdb[_0x4cb65e(0x4f1)]='Disconnected\x20from\x20'+_0x11b376+_0x4cb65e(0x3ce),_0x4fd9b8['tEhln'](_0x137d59,_0x51dfdb);}},0x1f4);});}async function ensureRecordingsDir(){const _0x572a15=_0x320de1;try{await fs['access'](RECORDINGS_DIR);}catch{const _0x3f5d9b={};_0x3f5d9b[_0x572a15(0x735)]=!![],await fs['mkdir'](RECORDINGS_DIR,_0x3f5d9b);}}async function startRecording(_0x2d46ae,_0xcfe83e){const _0x5e21bd=_0x320de1,_0x5bee23={'VEJPs':function(_0x418820){return _0x418820();}};await _0x5bee23['VEJPs'](ensureRecordingsDir),currentRecording={'name':_0x2d46ae||_0x5e21bd(0x66a)+Date[_0x5e21bd(0x2b8)](),'devices':_0xcfe83e||[],'commands':[],'startTime':new Date()[_0x5e21bd(0x1c4)]()},isRecording=!![],console['log'](_0x5e21bd(0x641)+currentRecording[_0x5e21bd(0x4b8)]);const _0x5a9488={};return _0x5a9488[_0x5e21bd(0x66c)]=!![],_0x5a9488[_0x5e21bd(0x5e6)]=currentRecording,_0x5a9488;}function recordCommand(_0x18fa0e,_0x155de2,_0x4f1e84,_0x23c8f9){const _0x5103c3=_0x320de1,_0xfedfd0={};_0xfedfd0[_0x5103c3(0x378)]=function(_0x2ecb62,_0x122ae8){return _0x2ecb62||_0x122ae8;};const _0xe23e10=_0xfedfd0;if(_0xe23e10[_0x5103c3(0x378)](!isRecording,!currentRecording))return![];return currentRecording[_0x5103c3(0xf7)][_0x5103c3(0x507)]({'timestamp':new Date()[_0x5103c3(0x1c4)](),'devices':_0x18fa0e,'originalCommand':_0x155de2,'useAI':_0x4f1e84,'finalCommand':_0xe23e10['QJBfy'](_0x23c8f9,_0x155de2)}),console[_0x5103c3(0x49e)]('📝\x20Recorded\x20command:\x20'+_0x155de2+'\x20('+currentRecording[_0x5103c3(0xf7)][_0x5103c3(0x162)]+_0x5103c3(0x69f)),!![];}async function stopRecording(){const _0x3efbb9=_0x320de1,_0x36ee4e={};_0x36ee4e[_0x3efbb9(0x559)]=_0x3efbb9(0x405);const _0x34517c=_0x36ee4e;if(!isRecording||!currentRecording){const _0x39435f={};return _0x39435f['success']=![],_0x39435f[_0x3efbb9(0x644)]=_0x34517c['QzMLV'],_0x39435f;}currentRecording['endTime']=new Date()[_0x3efbb9(0x1c4)]();const _0xcc2849=currentRecording[_0x3efbb9(0x4b8)]+_0x3efbb9(0x47f),_0x305ede=path[_0x3efbb9(0x4dd)](RECORDINGS_DIR,_0xcc2849);await fs[_0x3efbb9(0x184)](_0x305ede,JSON[_0x3efbb9(0x2a5)](currentRecording,null,0x2));const _0x5edcc7={};_0x5edcc7[_0x3efbb9(0x66c)]=!![],_0x5edcc7['recording']=currentRecording,_0x5edcc7[_0x3efbb9(0x685)]=_0xcc2849;const _0x5c2966=_0x5edcc7;return console[_0x3efbb9(0x49e)](_0x3efbb9(0x277)+currentRecording[_0x3efbb9(0x4b8)]+'\x20('+currentRecording[_0x3efbb9(0xf7)]['length']+'\x20commands)'),isRecording=![],currentRecording=null,_0x5c2966;}async function listRecordings(){const _0x5f1bce=_0x320de1,_0x1214ce={'eWNyz':'android','TwNax':function(_0x2306cf,_0x489fee){return _0x2306cf>_0x489fee;},'CfMLs':_0x5f1bce(0x3b7),'vKTQk':_0x5f1bce(0x228),'JnPKK':_0x5f1bce(0x230),'FNMOT':function(_0x30696a){return _0x30696a();},'kYylP':function(_0x4abff0,_0x1df4a0){return _0x4abff0!==_0x1df4a0;},'PsYeJ':_0x5f1bce(0x2d6),'Fwvah':_0x5f1bce(0x24a),'VswHm':_0x5f1bce(0x47f),'Izzdv':function(_0x3731f9,_0x5149f7){return _0x3731f9===_0x5149f7;},'tnMzM':_0x5f1bce(0x417),'etoDv':'utf-8','sxQSj':function(_0x232473,_0x39eab9){return _0x232473===_0x39eab9;},'gIXvu':'string','GAPke':function(_0x1955d1,_0x419d61){return _0x1955d1===_0x419d61;},'gaNFt':_0x5f1bce(0x2c1),'QIxqi':_0x5f1bce(0x4fd),'RWBmg':'XqCQq','oNTwH':_0x5f1bce(0x1dc),'feWed':_0x5f1bce(0x165)};await _0x1214ce[_0x5f1bce(0x3c3)](ensureRecordingsDir);try{if(_0x1214ce[_0x5f1bce(0x48d)](_0x1214ce['PsYeJ'],_0x1214ce['Fwvah'])){const _0x48cd6b=await fs[_0x5f1bce(0x26d)](RECORDINGS_DIR),_0x15b490=[];for(const _0x4edfb8 of _0x48cd6b){if(_0x4edfb8[_0x5f1bce(0x242)](_0x1214ce[_0x5f1bce(0x260)])){if(_0x1214ce[_0x5f1bce(0x63e)](_0x1214ce[_0x5f1bce(0x32c)],_0x1214ce[_0x5f1bce(0x32c)]))try{const _0x239f85=path['join'](RECORDINGS_DIR,_0x4edfb8),_0x1fd269=await fs[_0x5f1bce(0x5e8)](_0x239f85,_0x1214ce[_0x5f1bce(0x3d8)]),_0x2807f8=JSON[_0x5f1bce(0x652)](_0x1fd269);let _0x49947a=0x0;if(Array['isArray'](_0x2807f8[_0x5f1bce(0xf7)]))_0x49947a=_0x2807f8[_0x5f1bce(0xf7)][_0x5f1bce(0x162)];else{if(_0x1214ce[_0x5f1bce(0x361)](typeof _0x2807f8[_0x5f1bce(0xf7)],_0x1214ce[_0x5f1bce(0x6fd)])){if(_0x1214ce[_0x5f1bce(0x265)](_0x1214ce[_0x5f1bce(0x4df)],_0x5f1bce(0x2c1)))_0x49947a=_0x2807f8[_0x5f1bce(0xf7)]['split']('\x0a')[_0x5f1bce(0x47e)](_0x1116e5=>_0x1116e5[_0x5f1bce(0x5cf)]())[_0x5f1bce(0x162)];else{if(_0x2e7ed9[_0x5f1bce(0x58b)](':')&&_0x786d51[_0x5f1bce(0x65a)](/^\d+\.\d+\.\d+\.\d+:\d+$/))_0x5a70bb=wNJeMr['eWNyz'];else{if(_0x27a3aa['length']<0x14&&!_0x54dc33['includes']('-'))_0x199e0c=wNJeMr['eWNyz'];else _0x23a5d5[_0x5f1bce(0x58b)]('-')&&wNJeMr[_0x5f1bce(0x354)](_0x513e75[_0x5f1bce(0x162)],0x1e)&&(_0x3af7f0=wNJeMr[_0x5f1bce(0x108)]);}}}}_0x15b490[_0x5f1bce(0x507)]({'filename':_0x4edfb8,'name':_0x2807f8[_0x5f1bce(0x4b8)]||_0x4edfb8[_0x5f1bce(0x15d)](_0x1214ce['VswHm'],''),'devices':_0x2807f8[_0x5f1bce(0x1a6)]||[],'commandCount':_0x49947a,'startTime':_0x2807f8[_0x5f1bce(0x45b)]||_0x2807f8[_0x5f1bce(0x3dc)],'endTime':_0x2807f8[_0x5f1bce(0x2d1)]||_0x2807f8[_0x5f1bce(0x3dc)],'type':_0x2807f8[_0x5f1bce(0x14d)]||_0x1214ce[_0x5f1bce(0x529)]});}catch(_0x23c884){_0x1214ce[_0x5f1bce(0x63e)]('HFSqZ',_0x1214ce[_0x5f1bce(0x3ca)])?_0x2fba4a=_0x1358d0[_0x5f1bce(0xf7)][_0x5f1bce(0x240)](_0x23f275=>_0x23f275[_0x5f1bce(0x18e)]||_0x23f275[_0x5f1bce(0x15a)]):console[_0x5f1bce(0x644)]('Error\x20reading\x20recording\x20'+_0x4edfb8+':',_0x23c884);}else _0x1dd92a[_0x5f1bce(0x49e)](_0x1214ce['vKTQk']);}}return _0x15b490;}else{const _0x120a1e={};_0x120a1e[_0x5f1bce(0x14d)]=wNJeMr[_0x5f1bce(0x4ed)],_0x120a1e['devices']=_0x539bc0,_0x418b78[_0x5f1bce(0x475)](_0xa8c896['stringify'](_0x120a1e));}}catch(_0x2131d5){if(_0x1214ce['oNTwH']!==_0x5f1bce(0x687))return console[_0x5f1bce(0x644)](_0x1214ce[_0x5f1bce(0x1bb)],_0x2131d5),[];else{const _0x1a075a={};_0x1a075a[_0x5f1bce(0x66c)]=!![],_0x1a075a['output']=_0x5d1e5c,_0x1a075a['device']=_0xbb410b[_0x5f1bce(0x4b8)],_0x10404b(_0x1a075a);}}}async function loadRecording(_0x5db55a){const _0x3acaaa=_0x320de1,_0x4d5703={'gEpbH':function(_0x160044,_0x3d5976){return _0x160044(_0x3d5976);},'tVwHk':_0x3acaaa(0x747),'EeXsN':_0x3acaaa(0x68e),'CYEHS':_0x3acaaa(0x1ef)},_0x41fb70=path[_0x3acaaa(0x4dd)](RECORDINGS_DIR,_0x5db55a);try{if(_0x4d5703[_0x3acaaa(0x2e3)]!==_0x4d5703[_0x3acaaa(0x263)]){const _0x1ae9b0=await fs[_0x3acaaa(0x5e8)](_0x41fb70,_0x4d5703[_0x3acaaa(0x5d4)]);return JSON[_0x3acaaa(0x652)](_0x1ae9b0);}else cFWcjp[_0x3acaaa(0x2d7)](_0x1db830,_0x3acaaa(0x600)+_0x445f09+_0x3acaaa(0x276)+_0x43611a['port']),_0xc65b6c['log'](_0x3acaaa(0x11b)+_0x5cef38);}catch(_0x36c297){console[_0x3acaaa(0x644)](_0x3acaaa(0x479)+_0x5db55a+':',_0x36c297);throw _0x36c297;}}async function deleteRecording(_0x16d186){const _0x5a402a=_0x320de1,_0x4062db={};_0x4062db['tMkzw']='ISZNz';const _0x50b56f=_0x4062db,_0x4994da=path[_0x5a402a(0x4dd)](RECORDINGS_DIR,_0x16d186);try{if(_0x50b56f['tMkzw']!==_0x50b56f[_0x5a402a(0x551)])_0x26cc85[_0x5a402a(0x644)](_0x5a402a(0x738)+_0x49bf73+':',_0x3d07b8);else{await fs['unlink'](_0x4994da);const _0x228111={};return _0x228111['success']=!![],_0x228111;}}catch(_0xcff622){console[_0x5a402a(0x644)](_0x5a402a(0x1fa)+_0x16d186+':',_0xcff622);throw _0xcff622;}}async function replayRecording(_0x49253c,_0x5802ae,_0xad7e44){const _0x423039=_0x320de1,_0x4dd67d={'TQpaJ':_0x423039(0x521),'PupNU':_0x423039(0x2dc),'IyzIk':'No\x20output\x20received\x20from\x20device','eaCSd':function(_0x4fb9e0,_0x3d291d){return _0x4fb9e0(_0x3d291d);},'pORCV':function(_0x1e1919,_0x48b730){return _0x1e1919===_0x48b730;},'nMBfQ':_0x423039(0x1dd),'XTRDG':_0x423039(0x1ec),'elDXt':function(_0x3a3a27,_0x5f3f4f){return _0x3a3a27+_0x5f3f4f;},'GjLBW':function(_0x404c40,_0x2ca1cd){return _0x404c40+_0x2ca1cd;},'vWqdt':function(_0x435c97,_0x9314e5){return _0x435c97<_0x9314e5;},'OHcSy':'tCCvG','jvLlk':_0x423039(0x5c5),'EpiEG':'\x0a⏹️\x20\x20Replay\x20aborted\x20by\x20user\x0a','OFKMu':'\x0a⏹️\x20\x20Replay\x20stopped\x20by\x20user\x0a','UkrcC':'Replay\x20aborted\x20by\x20user','vZvfz':function(_0x30830f,_0x3d8dcd){return _0x30830f+_0x3d8dcd;},'PpsGo':function(_0x1b5728,_0x43af53){return _0x1b5728+_0x43af53;},'dAYwU':_0x423039(0x3c7),'yVVrj':function(_0x400cf9,_0x36815,_0x18ea83,_0x31d20f){return _0x400cf9(_0x36815,_0x18ea83,_0x31d20f);},'BluOy':function(_0x1b2466,_0x8d6cc){return _0x1b2466-_0x8d6cc;},'imxvY':function(_0x4da5c4,_0x409fa3){return _0x4da5c4+_0x409fa3;}},_0x24a2db=await _0x4dd67d[_0x423039(0x51d)](loadRecording,_0x49253c);let _0x577e67=[];if(Array['isArray'](_0x24a2db[_0x423039(0xf7)]))_0x577e67=_0x24a2db[_0x423039(0xf7)]['map'](_0x4d6d62=>_0x4d6d62[_0x423039(0x18e)]||_0x4d6d62[_0x423039(0x15a)]);else _0x4dd67d[_0x423039(0x74b)](typeof _0x24a2db[_0x423039(0xf7)],_0x4dd67d['nMBfQ'])&&(_0x577e67=_0x24a2db['commands']['split']('\x0a')[_0x423039(0x47e)](_0x791a6=>_0x791a6[_0x423039(0x5cf)]()));const _0x1f9164=_0x24a2db['devices']&&_0x24a2db[_0x423039(0x1a6)]['length']>0x0?_0x24a2db[_0x423039(0x1a6)]:_0x5802ae;console[_0x423039(0x49e)](_0x423039(0x609)+_0x24a2db[_0x423039(0x4b8)]),console[_0x423039(0x49e)](_0x423039(0x3c0)+_0x1f9164[_0x423039(0x4dd)](',\x20')),console[_0x423039(0x49e)](_0x423039(0x538)+_0x5802ae[_0x423039(0x4dd)](',\x20')),console[_0x423039(0x49e)](_0x423039(0x55f)+_0x577e67[_0x423039(0x162)]),replayAborted=![],isReplaying=!![];_0xad7e44&&_0xad7e44[_0x423039(0x475)](JSON['stringify']({'type':_0x4dd67d[_0x423039(0x25a)],'data':_0x4dd67d['elDXt'](_0x4dd67d[_0x423039(0x5ad)](_0x4dd67d[_0x423039(0x645)]('📼\x20Recording:\x20'+_0x24a2db[_0x423039(0x4b8)]+'\x0a',_0x423039(0x1fd)+_0x5802ae[_0x423039(0x4dd)](',\x20')+'\x0a'),_0x423039(0x52c)+_0x577e67[_0x423039(0x162)]+'\x0a'),'━'[_0x423039(0x5fb)](0x32)+'\x0a\x0a'),'devices':_0x5802ae}));const _0x1f5bf3=[];for(let _0x5cc5d5=0x0;_0x4dd67d['vWqdt'](_0x5cc5d5,_0x577e67['length']);_0x5cc5d5++){if(_0x4dd67d[_0x423039(0xf6)]===_0x4dd67d[_0x423039(0x1f1)]){_0x29a8a7[_0x423039(0x49e)](_0x4dd67d[_0x423039(0x2aa)]),_0x91cba[_0x423039(0x49e)](_0x4dd67d['PupNU'],_0x27f28b['stringify'](_0x1ced28,null,0x2));const _0x5b1c33={};return _0x5b1c33['success']=![],_0x5b1c33[_0x423039(0x644)]=_0x4dd67d['IyzIk'],_0x56b28b['status'](0x1f4)[_0x423039(0x169)](_0x5b1c33);}else{if(replayAborted){console['log'](_0x4dd67d['EpiEG']);if(_0xad7e44){const _0xad6baf={};_0xad6baf['type']=_0x4dd67d[_0x423039(0x25a)],_0xad6baf[_0x423039(0x760)]=_0x4dd67d[_0x423039(0x1a0)],_0xad6baf['devices']=_0x5802ae,_0xad7e44[_0x423039(0x475)](JSON['stringify'](_0xad6baf));}isReplaying=![];throw new Error(_0x4dd67d['UkrcC']);}const _0x5b8331=_0x577e67[_0x5cc5d5];console[_0x423039(0x49e)](_0x423039(0x32b)+_0x4dd67d[_0x423039(0x348)](_0x5cc5d5,0x1)+'/'+_0x577e67[_0x423039(0x162)]),console['log'](_0x423039(0x209)+_0x5b8331);_0xad7e44&&_0xad7e44[_0x423039(0x475)](JSON['stringify']({'type':_0x423039(0x1ec),'data':_0x423039(0x49a)+_0x4dd67d['PpsGo'](_0x5cc5d5,0x1)+'/'+_0x577e67[_0x423039(0x162)]+']\x20Executing:\x20'+_0x5b8331+'\x0a','devices':_0x5802ae}));try{if(_0x4dd67d[_0x423039(0x54a)]!==_0x423039(0x3c7)){const _0x4accbc={};_0x4accbc[_0x423039(0x14d)]='devices_updated',_0x4accbc[_0x423039(0x1a6)]=_0x21c92d,_0x3b4b4b[_0x423039(0x475)](_0x5dfc3d[_0x423039(0x2a5)](_0x4accbc));}else{const _0x26eb12=await _0x4dd67d['yVVrj'](executeCommand,_0x5802ae,_0x5b8331,null),_0x5498a3={};_0x5498a3[_0x423039(0x531)]=_0x5b8331,_0x5498a3[_0x423039(0x66c)]=!![],_0x5498a3[_0x423039(0x34f)]=_0x26eb12,_0x1f5bf3['push'](_0x5498a3);if(_0xad7e44){const _0x35e218={};_0x35e218['type']=_0x4dd67d['XTRDG'],_0x35e218[_0x423039(0x760)]='✅\x20Completed\x20successfully\x0a\x0a',_0x35e218[_0x423039(0x1a6)]=_0x5802ae,_0xad7e44[_0x423039(0x475)](JSON[_0x423039(0x2a5)](_0x35e218));}_0x4dd67d[_0x423039(0x3c9)](_0x5cc5d5,_0x4dd67d['BluOy'](_0x577e67[_0x423039(0x162)],0x1))&&await new Promise(_0x5efb19=>setTimeout(_0x5efb19,0x3e8));}}catch(_0x126120){console[_0x423039(0x644)](_0x423039(0x2c7)+_0x4dd67d[_0x423039(0x1b5)](_0x5cc5d5,0x1)+_0x423039(0x58d),_0x126120[_0x423039(0x4f1)]);const _0x3be6c0={};_0x3be6c0[_0x423039(0x531)]=_0x5b8331,_0x3be6c0['success']=![],_0x3be6c0['error']=_0x126120[_0x423039(0x4f1)],_0x1f5bf3['push'](_0x3be6c0);if(_0xad7e44){const _0x32c116={};_0x32c116[_0x423039(0x14d)]=_0x4dd67d['XTRDG'],_0x32c116['data']=_0x423039(0x6b5)+_0x126120['message']+'\x0a\x0a',_0x32c116['devices']=_0x5802ae,_0xad7e44[_0x423039(0x475)](JSON['stringify'](_0x32c116));}}}}isReplaying=![],console[_0x423039(0x49e)]('REPLAY\x20COMPLETE'),console[_0x423039(0x49e)](_0x423039(0x716)+_0x1f5bf3[_0x423039(0x162)]+',\x20Success:\x20'+_0x1f5bf3[_0x423039(0x47e)](_0x4ab4aa=>_0x4ab4aa['success'])['length']+_0x423039(0x450)+_0x1f5bf3['filter'](_0x288e2b=>!_0x288e2b[_0x423039(0x66c)])[_0x423039(0x162)]);const _0x3e8c06={};return _0x3e8c06[_0x423039(0x66c)]=!![],_0x3e8c06[_0x423039(0x5e6)]=_0x24a2db[_0x423039(0x4b8)],_0x3e8c06[_0x423039(0x3a2)]=_0x1f5bf3,_0x3e8c06;}app[_0x320de1(0x5af)](_0x320de1(0x53e),(_0x406724,_0x5080ad)=>{_0x5080ad['json']({'status':'ok','timestamp':Date['now']()});}),app[_0x320de1(0x5af)](_0x320de1(0x176),async(_0x4f8adb,_0x1dfeeb)=>{const _0x29e664=_0x320de1,_0x30113a={};_0x30113a['avUsU']=function(_0x75ea7a,_0x3bf7f7){return _0x75ea7a===_0x3bf7f7;},_0x30113a[_0x29e664(0x579)]=_0x29e664(0x230),_0x30113a[_0x29e664(0x647)]=function(_0x57a4c9,_0x1b16e3){return _0x57a4c9===_0x1b16e3;},_0x30113a[_0x29e664(0x32a)]='xwSom';const _0x191468=_0x30113a;try{if(_0x191468[_0x29e664(0x647)](_0x191468[_0x29e664(0x32a)],_0x29e664(0x4e7))){if(FpJiHV['avUsU'](_0x2c3340['readyState'],_0x548aee['OPEN'])){const _0x614e97={};_0x614e97[_0x29e664(0x14d)]=FpJiHV[_0x29e664(0x579)],_0x614e97[_0x29e664(0x1a6)]=_0x4e5f47,_0x2d8ade[_0x29e664(0x475)](_0x573d28[_0x29e664(0x2a5)](_0x614e97));}}else{const _0x551fcf=await discoverDevices(),_0x49f788={};_0x49f788[_0x29e664(0x66c)]=!![],_0x49f788[_0x29e664(0x1a6)]=_0x551fcf,_0x1dfeeb['json'](_0x49f788);}}catch(_0x2d7ef3){const _0x37ed0f={};_0x37ed0f['success']=![],_0x37ed0f['error']=_0x2d7ef3[_0x29e664(0x4f1)],_0x1dfeeb[_0x29e664(0x365)](0x1f4)[_0x29e664(0x169)](_0x37ed0f);}}),app['post'](_0x320de1(0x36a),async(_0x353bd5,_0xddb7b9)=>{const _0x3e33a7=_0x320de1,_0x3a7e56={'zfmRf':function(_0x3506b3,_0x50a33d){return _0x3506b3(_0x50a33d);},'ftQPA':_0x3e33a7(0x682),'vcKPY':function(_0x3c5981,_0x3e87c9){return _0x3c5981===_0x3e87c9;},'TgtKl':_0x3e33a7(0x73e),'wHMKO':_0x3e33a7(0x230),'uHRnU':function(_0x168270){return _0x168270();},'rTSLR':function(_0x3deb88,_0x1dbab8){return _0x3deb88===_0x1dbab8;},'TVJvw':_0x3e33a7(0x679),'yHlFl':_0x3e33a7(0x105)};try{const _0x5ad9ae=await _0x3a7e56[_0x3e33a7(0x370)](discoverDevices);wss['clients'][_0x3e33a7(0x11d)](_0x493f51=>{const _0x2af3e0=_0x3e33a7,_0x334ddf={'qnHPG':function(_0x2cbc4f,_0x5fdfc9){return _0x3a7e56['zfmRf'](_0x2cbc4f,_0x5fdfc9);}};if(_0x3a7e56[_0x2af3e0(0x166)]===_0x2af3e0(0x682)){if(_0x3a7e56[_0x2af3e0(0x1c0)](_0x493f51[_0x2af3e0(0x4aa)],WebSocket[_0x2af3e0(0x717)])){if(_0x3a7e56['TgtKl']!==_0x2af3e0(0x437)){const _0x5c7b12={};_0x5c7b12[_0x2af3e0(0x14d)]=_0x3a7e56[_0x2af3e0(0x18f)],_0x5c7b12[_0x2af3e0(0x1a6)]=_0x5ad9ae,_0x493f51['send'](JSON['stringify'](_0x5c7b12));}else{const _0x1c1698={};_0x1c1698[_0x2af3e0(0x66c)]=![],_0x1c1698[_0x2af3e0(0x4f1)]=_0x2af3e0(0x192)+_0x2f0247+_0x2af3e0(0x598),VZUptS[_0x2af3e0(0x55e)](_0x42fbf,_0x1c1698);}}}else{const _0x113ded={};return _0x113ded['success']=![],_0x113ded[_0x2af3e0(0x644)]='No\x20devices\x20specified',_0x2de27b['status'](0x190)[_0x2af3e0(0x169)](_0x113ded);}});const _0x1244fa={};_0x1244fa['success']=!![],_0x1244fa[_0x3e33a7(0x1a6)]=_0x5ad9ae,_0xddb7b9[_0x3e33a7(0x169)](_0x1244fa);}catch(_0x20cfbf){if(_0x3a7e56[_0x3e33a7(0x25d)](_0x3a7e56['TVJvw'],_0x3a7e56[_0x3e33a7(0x3af)]))return{'id':_0x1e1c73['trim'](),'name':_0x3dc6d3['trim']()};else{const _0x2afdfd={};_0x2afdfd[_0x3e33a7(0x66c)]=![],_0x2afdfd[_0x3e33a7(0x644)]=_0x20cfbf['message'],_0xddb7b9[_0x3e33a7(0x365)](0x1f4)[_0x3e33a7(0x169)](_0x2afdfd);}}}),app[_0x320de1(0x70f)]('/api/execute',async(_0x5f2529,_0x2a024)=>{const _0xe0c9dd=_0x320de1,_0x7505ed={'wUJmA':'android','XUIzU':function(_0xfe8504,_0x2aa39e){return _0xfe8504(_0x2aa39e);},'bqCru':function(_0x5168e2,_0x17c565){return _0x5168e2===_0x17c565;},'JPfXR':_0xe0c9dd(0x230),'kaADX':function(_0x346012,_0x5d35f4){return _0x346012!==_0x5d35f4;},'vxlcN':_0xe0c9dd(0x4e6),'LRaNp':function(_0x279aee,_0x10f74e){return _0x279aee<_0x10f74e;},'CMKDo':function(_0x192711,_0x4201d4){return _0x192711+_0x4201d4;},'nubWv':'wZFcy','zMPfK':function(_0x3bbc16,_0x467bcc){return _0x3bbc16===_0x467bcc;},'LTSas':function(_0x255757,_0x45bf91){return _0x255757!==_0x45bf91;},'nBHAx':'UlgZD','KpkOo':_0xe0c9dd(0x5c7),'lgWmy':_0xe0c9dd(0x229),'fyteg':_0xe0c9dd(0x172),'dSGOY':_0xe0c9dd(0x159),'HvRYO':function(_0x46ef79,_0x248178,_0x114b85,_0x29bdad){return _0x46ef79(_0x248178,_0x114b85,_0x29bdad);},'fazgl':_0xe0c9dd(0x2b5)};try{if(_0x7505ed[_0xe0c9dd(0x74d)]!==_0x7505ed[_0xe0c9dd(0x74d)])_0x58de96=vIAjfO['wUJmA'];else{const {devices:_0x8962eb,command:_0x57dce9,useAI:_0x13df64,aiProvider:_0x5eca0}=_0x5f2529['body'];if(!_0x8962eb||_0x7505ed[_0xe0c9dd(0x4a7)](_0x8962eb['length'],0x0)){if(_0x7505ed['LTSas']('UlgZD',_0x7505ed[_0xe0c9dd(0x1b1)]))_0x3e5724[_0xe0c9dd(0x4b8)]=_0x17ca90[0x1]['trim'](),_0x287223[_0xe0c9dd(0x2a6)]=_0x589d61[0x1][_0xe0c9dd(0x5cf)]();else{const _0x6c3a5d={};return _0x6c3a5d[_0xe0c9dd(0x66c)]=![],_0x6c3a5d[_0xe0c9dd(0x644)]=_0x7505ed['KpkOo'],_0x2a024[_0xe0c9dd(0x365)](0x190)[_0xe0c9dd(0x169)](_0x6c3a5d);}}let _0x14109b=_0x57dce9;if(_0x13df64){if(_0x7505ed['bqCru']('CdaYq',_0x7505ed[_0xe0c9dd(0x6e3)])){const _0xcff009={};_0xcff009[_0xe0c9dd(0x66c)]=![],_0xcff009[_0xe0c9dd(0x4f1)]=_0xe0c9dd(0x2c5)+_0x263877+_0xe0c9dd(0x35f),vIAjfO[_0xe0c9dd(0x526)](_0x24a560,_0xcff009);}else _0x14109b=await convertNaturalLanguageToCommand(_0x57dce9,_0x8962eb,_0x5eca0);}const _0x341dd7=_0x14109b[_0xe0c9dd(0x58b)]('\x0a');let _0xa2ec2a;if(_0x341dd7){if(_0x7505ed[_0xe0c9dd(0x2a9)]===_0x7505ed['dSGOY']){const _0x4b52f7={'RvWrJ':function(_0x8c0887,_0x27c79c){const _0x1c939d=_0xe0c9dd;return vIAjfO[_0x1c939d(0x174)](_0x8c0887,_0x27c79c);},'RtKUO':vIAjfO[_0xe0c9dd(0x309)]};vIAjfO[_0xe0c9dd(0x6a4)](_0x5748f9,-0x1)&&(_0x517d0c[_0x2690a6][_0xe0c9dd(0x365)]=vIAjfO[_0xe0c9dd(0x244)],_0x47283f[_0xe0c9dd(0x374)][_0xe0c9dd(0x11d)](_0x57874c=>{const _0x41e077=_0xe0c9dd;if(_0x4b52f7[_0x41e077(0x27b)](_0x57874c[_0x41e077(0x4aa)],_0x17eb3a[_0x41e077(0x717)])){const _0x4c1f88={};_0x4c1f88[_0x41e077(0x14d)]=_0x4b52f7['RtKUO'],_0x4c1f88['devices']=_0x598043,_0x57874c[_0x41e077(0x475)](_0x1447a0[_0x41e077(0x2a5)](_0x4c1f88));}})),_0x27a6c7='Connected\x20to\x20'+_0x287361+_0xe0c9dd(0x418);}else _0xa2ec2a=await _0x7505ed[_0xe0c9dd(0x68d)](executeCommandsSequentially,_0x8962eb,_0x14109b,null);}else _0xa2ec2a=await _0x7505ed[_0xe0c9dd(0x68d)](executeCommand,_0x8962eb,_0x14109b,null);_0x2a024[_0xe0c9dd(0x169)](_0xa2ec2a);}}catch(_0x2dc75a){if(_0x7505ed['fazgl']!==_0xe0c9dd(0x5c8)){const _0xf4398d={};_0xf4398d['success']=![],_0xf4398d[_0xe0c9dd(0x644)]=_0x2dc75a[_0xe0c9dd(0x4f1)],_0x2a024[_0xe0c9dd(0x365)](0x1f4)[_0xe0c9dd(0x169)](_0xf4398d);}else{if(!_0xd85e50||_0x7505ed[_0xe0c9dd(0x62b)](_0xc871ea[_0xe0c9dd(0x162)],0x8))return'';return _0x7505ed[_0xe0c9dd(0xed)]('•'[_0xe0c9dd(0x5fb)](_0x47dfc2[_0xe0c9dd(0x162)]-0x4),_0x4e9cf5[_0xe0c9dd(0x12c)](-0x4));}}}),app['post'](_0x320de1(0x123),async(_0x5ac9fd,_0x5a8204)=>{const _0x2b2568=_0x320de1,_0xf7803c={'ikdIR':_0x2b2568(0x67a),'EYnrf':function(_0x56a7ff,_0x308114){return _0x56a7ff!==_0x308114;},'jlivA':_0x2b2568(0x146),'DdJpG':_0x2b2568(0x4b4),'tMRdO':function(_0x16c1c4,_0x3590a3,_0x54bf7e,_0x5e5d68){return _0x16c1c4(_0x3590a3,_0x54bf7e,_0x5e5d68);},'dNKcg':function(_0x36cc01,_0x40f693){return _0x36cc01!==_0x40f693;},'BsgqY':'kjvmX'};try{if(_0xf7803c['EYnrf'](_0xf7803c['jlivA'],_0xf7803c[_0x2b2568(0x296)])){const {text:_0x4fee41,devices:_0x3f7b9a,provider:_0x3de83f}=_0x5ac9fd[_0x2b2568(0x5a1)],_0x5828ff=await _0xf7803c[_0x2b2568(0x56d)](convertNaturalLanguageToCommand,_0x4fee41,_0x3f7b9a||[],_0x3de83f),_0x126873={};_0x126873[_0x2b2568(0x66c)]=!![],_0x126873['command']=_0x5828ff,_0x5a8204['json'](_0x126873);}else{_0x82e480[_0x2b2568(0x49e)](_0x2b2568(0x702),_0x30dc3a[_0x2b2568(0x527)][_0x2b2568(0x644)]);const _0x233f3c={};return _0x233f3c[_0x2b2568(0x66c)]=![],_0x233f3c[_0x2b2568(0x644)]=_0xf7803c[_0x2b2568(0x569)],_0x3fe041[_0x2b2568(0x365)](0x1f4)[_0x2b2568(0x169)](_0x233f3c);}}catch(_0x42fb26){if(_0xf7803c[_0x2b2568(0x3fe)](_0xf7803c[_0x2b2568(0x4d0)],_0xf7803c['BsgqY'])){const _0x28761a={};_0x28761a[_0x2b2568(0x66c)]=![],_0x28761a[_0x2b2568(0x644)]=_0xa8d852[_0x2b2568(0x4f1)],_0x492a9e['status'](0x1f4)[_0x2b2568(0x169)](_0x28761a);}else{const _0x4f9163={};_0x4f9163['success']=![],_0x4f9163['error']=_0x42fb26[_0x2b2568(0x4f1)],_0x5a8204[_0x2b2568(0x365)](0x1f4)[_0x2b2568(0x169)](_0x4f9163);}}}),app[_0x320de1(0x70f)](_0x320de1(0x595),async(_0xedbe58,_0x482c55)=>{const _0x223b4a=_0x320de1,_0x360459={'nPQQZ':'❌\x20No\x20device\x20provided\x20in\x20request','ONdNd':_0x223b4a(0x57f),'nQFAV':function(_0x3f496d,_0x2ef5ec){return _0x3f496d!==_0x2ef5ec;},'qDewR':'LhdIa','wqRTF':_0x223b4a(0x304),'nhPpP':function(_0x29545d,_0xc27fc2){return _0x29545d(_0xc27fc2);}};try{const {device:_0x45caa6}=_0xedbe58[_0x223b4a(0x5a1)];console['log'](_0x223b4a(0x157),_0x45caa6);if(!_0x45caa6){console[_0x223b4a(0x644)](_0x360459[_0x223b4a(0x5d8)]);const _0x24d994={};return _0x24d994[_0x223b4a(0x66c)]=![],_0x24d994['error']=_0x360459[_0x223b4a(0xdf)],_0x482c55[_0x223b4a(0x365)](0x190)[_0x223b4a(0x169)](_0x24d994);}if(!_0x45caa6[_0x223b4a(0x4b8)]||!_0x45caa6[_0x223b4a(0x23d)]){if(_0x360459['nQFAV'](_0x360459['qDewR'],_0x360459[_0x223b4a(0x54b)])){const _0x357282={};_0x357282['recursive']=!![],_0x357282['mode']=0x1c0,_0x42f23d[_0x223b4a(0x13a)](_0x517de5,_0x357282);}else{console['error'](_0x360459['wqRTF'],_0x45caa6);const _0x5e456a={};return _0x5e456a[_0x223b4a(0x66c)]=![],_0x5e456a[_0x223b4a(0x644)]=_0x223b4a(0x6cd),_0x482c55[_0x223b4a(0x365)](0x190)[_0x223b4a(0x169)](_0x5e456a);}}const _0x136316=await _0x360459[_0x223b4a(0x2f6)](connectToDevice,_0x45caa6);console[_0x223b4a(0x49e)](_0x223b4a(0x31c),_0x136316),_0x482c55['json'](_0x136316);}catch(_0x4cd430){console[_0x223b4a(0x644)]('❌\x20Connect\x20error:',_0x4cd430);const _0x23292b={};_0x23292b[_0x223b4a(0x66c)]=![],_0x23292b[_0x223b4a(0x644)]=_0x4cd430[_0x223b4a(0x4f1)],_0x482c55[_0x223b4a(0x365)](0x1f4)[_0x223b4a(0x169)](_0x23292b);}}),app[_0x320de1(0x70f)]('/api/devices/disconnect',async(_0x12e0e3,_0x4e97bf)=>{const _0x467346=_0x320de1,_0x41006d={'JDFqS':_0x467346(0x129),'MYyNm':function(_0x31c609,_0x443796){return _0x31c609!==_0x443796;},'TrWHg':_0x467346(0x5bd),'SIFxS':_0x467346(0x671),'dexhp':function(_0x20b547,_0xedf4ca){return _0x20b547(_0xedf4ca);}};try{if(_0x41006d[_0x467346(0x4ca)](_0x41006d[_0x467346(0x456)],_0x41006d[_0x467346(0x693)])){const {device:_0xf2d876}=_0x12e0e3['body'],_0x416ee7=await _0x41006d['dexhp'](disconnectFromDevice,_0xf2d876);_0x4e97bf[_0x467346(0x169)](_0x416ee7);}else _0xf3df86[_0x467346(0x3d0)](_0x41006d[_0x467346(0x34a)],_0x413696),_0x407415[_0x467346(0x507)](_0x43ca88);}catch(_0x40a804){const _0x4cc5d0={};_0x4cc5d0['success']=![],_0x4cc5d0[_0x467346(0x644)]=_0x40a804['message'],_0x4e97bf[_0x467346(0x365)](0x1f4)[_0x467346(0x169)](_0x4cc5d0);}}),app[_0x320de1(0x70f)](_0x320de1(0x170),async(_0xc2eacf,_0xfb312c)=>{const _0x4d69c7=_0x320de1,_0x42d1={};_0x42d1[_0x4d69c7(0x1de)]=function(_0x30ae5b,_0x3eb6c4){return _0x30ae5b===_0x3eb6c4;},_0x42d1[_0x4d69c7(0x44c)]=_0x4d69c7(0x3fa),_0x42d1[_0x4d69c7(0x6e4)]=function(_0x1ca2db,_0x3ba097){return _0x1ca2db!==_0x3ba097;},_0x42d1[_0x4d69c7(0x2a2)]=_0x4d69c7(0x3cf),_0x42d1[_0x4d69c7(0x766)]='No\x20devices\x20to\x20disconnect';const _0x20651c=_0x42d1;try{console[_0x4d69c7(0x49e)](_0x4d69c7(0xdd));const _0x5c4878=connectedDevices[_0x4d69c7(0x47e)](_0x2cf467=>_0x2cf467[_0x4d69c7(0x365)]==='online');if(_0x5c4878['length']===0x0){if(_0x20651c[_0x4d69c7(0x6e4)](_0x20651c[_0x4d69c7(0x2a2)],_0x20651c['WtmhU']))_0x20651c[_0x4d69c7(0x1de)](_0x4f8362[_0x4d69c7(0x493)],_0x20651c[_0x4d69c7(0x44c)])&&(_0x5827c8[_0x4d69c7(0x644)](_0x4d69c7(0x726)+_0x559d9d+'\x20is\x20already\x20in\x20use!'),_0x1d8174[_0x4d69c7(0x644)](_0x4d69c7(0x345)),_0x4013c4[_0x4d69c7(0x644)]('\x20\x201.\x20Kill\x20the\x20process\x20using\x20port\x20'+_0x556814+_0x4d69c7(0xe4)+_0x516cd7+'\x20|\x20xargs\x20kill\x20-9'),_0x497a1b['error'](_0x4d69c7(0x627)),_0x2cb74d['error'](_0x4d69c7(0x5c4))),_0x3ad98e(_0x2a8ad0);else{const _0x43345d={};return _0x43345d[_0x4d69c7(0x66c)]=!![],_0x43345d[_0x4d69c7(0x4f1)]=_0x20651c[_0x4d69c7(0x766)],_0xfb312c[_0x4d69c7(0x169)](_0x43345d);}}console[_0x4d69c7(0x49e)]('📱\x20Disconnecting\x20'+_0x5c4878[_0x4d69c7(0x162)]+'\x20device(s)...');const _0x417b63=_0x5c4878[_0x4d69c7(0x240)](_0x3d2ef3=>disconnectFromDevice(_0x3d2ef3));await Promise[_0x4d69c7(0x246)](_0x417b63),console[_0x4d69c7(0x49e)](_0x4d69c7(0x634));const _0x242c93={};_0x242c93[_0x4d69c7(0x66c)]=!![],_0x242c93['message']='Disconnected\x20'+_0x5c4878[_0x4d69c7(0x162)]+_0x4d69c7(0x50d),_0x242c93['count']=_0x5c4878[_0x4d69c7(0x162)],_0xfb312c['json'](_0x242c93);}catch(_0x3ad6aa){console[_0x4d69c7(0x644)]('❌\x20Error\x20disconnecting\x20all\x20devices:',_0x3ad6aa);const _0xe697d8={};_0xe697d8[_0x4d69c7(0x66c)]=![],_0xe697d8[_0x4d69c7(0x644)]=_0x3ad6aa[_0x4d69c7(0x4f1)],_0xfb312c['status'](0x1f4)[_0x4d69c7(0x169)](_0xe697d8);}}),app[_0x320de1(0x5af)](_0x320de1(0x3df),(_0x713681,_0xcbb9c2)=>{const _0x1b4148=_0x320de1,_0x2c7253={'dfwsf':function(_0x307aae,_0x28b74d){return _0x307aae(_0x28b74d);},'QaFtv':function(_0x3db6a4,_0x1fc1eb){return _0x3db6a4===_0x1fc1eb;},'MwEXX':_0x1b4148(0x659)};try{const _0x3f715b=aiManager[_0x1b4148(0x723)](),_0x45198e=aiManager[_0x1b4148(0x1ce)](),_0xe5d36={};_0xe5d36[_0x1b4148(0x66c)]=!![],_0xe5d36[_0x1b4148(0x1da)]=_0x3f715b,_0xe5d36['current']=_0x45198e['id'],_0xcbb9c2[_0x1b4148(0x169)](_0xe5d36);}catch(_0x3a142a){if(_0x2c7253[_0x1b4148(0x4bd)](_0x2c7253[_0x1b4148(0x59f)],_0x2c7253[_0x1b4148(0x59f)])){const _0x4b33e7={};_0x4b33e7[_0x1b4148(0x66c)]=![],_0x4b33e7['error']=_0x3a142a['message'],_0xcbb9c2[_0x1b4148(0x365)](0x1f4)['json'](_0x4b33e7);}else{_0x4a8ed6['error']('['+_0x223d2a+_0x1b4148(0x446)+_0x48f9b0[_0x1b4148(0x4f1)]);const _0x56b463={};_0x56b463['success']=![],_0x56b463[_0x1b4148(0x644)]=_0x45dc4d['message'],_0x56b463[_0x1b4148(0x120)]=_0x482879,tHDpsJ[_0x1b4148(0x749)](_0x28bed7,_0x56b463);}}}),app[_0x320de1(0x70f)]('/api/ai/provider',(_0x1e2c24,_0x4cb03d)=>{const _0x307cb8=_0x320de1,_0x5c29dc={'hFBwl':_0x307cb8(0x230),'DjEFv':'Script\x20execution\x20error:','erpAn':function(_0x14ab2b,_0x40b12e){return _0x14ab2b(_0x40b12e);},'kCxHf':_0x307cb8(0x655),'JsQgW':function(_0x24a7df,_0x7fa777){return _0x24a7df===_0x7fa777;},'RdMfL':_0x307cb8(0x5b1)};try{const {provider:_0x33f735}=_0x1e2c24['body'],_0x1a0431=aiManager[_0x307cb8(0x4cd)](_0x33f735);if(_0x1a0431){if(_0x5c29dc[_0x307cb8(0x2bd)]!==_0x5c29dc['kCxHf']){const _0x42625a={};_0x42625a[_0x307cb8(0x14d)]=IGENtK['hFBwl'],_0x42625a[_0x307cb8(0x1a6)]=_0x4d8a12,_0x3a5d6a[_0x307cb8(0x475)](_0x54bcd8[_0x307cb8(0x2a5)](_0x42625a));}else{const _0x518f84={};_0x518f84[_0x307cb8(0x66c)]=!![],_0x518f84[_0x307cb8(0x461)]=_0x33f735,_0x4cb03d[_0x307cb8(0x169)](_0x518f84);}}else{if(_0x5c29dc[_0x307cb8(0x366)](_0x5c29dc[_0x307cb8(0x4f5)],_0x5c29dc[_0x307cb8(0x4f5)])){const _0xb0fc98={};_0xb0fc98['success']=![],_0xb0fc98[_0x307cb8(0x644)]=_0x307cb8(0x429),_0x4cb03d[_0x307cb8(0x365)](0x190)['json'](_0xb0fc98);}else _0xdbd526[_0x307cb8(0x644)](IGENtK['DjEFv'],_0x27035e),IGENtK[_0x307cb8(0x18d)](_0x2e060e,_0x1827c4);}}catch(_0x1c3a16){const _0x29f409={};_0x29f409[_0x307cb8(0x66c)]=![],_0x29f409[_0x307cb8(0x644)]=_0x1c3a16['message'],_0x4cb03d[_0x307cb8(0x365)](0x1f4)[_0x307cb8(0x169)](_0x29f409);}}),app[_0x320de1(0x5af)](_0x320de1(0x481),async(_0x38138d,_0x22d5e4)=>{const _0x45eeea=_0x320de1,_0x4b7f12={'ubiXy':function(_0x532bcf,_0x5066a6){return _0x532bcf&&_0x5066a6;},'SBFvH':function(_0x540301,_0x5b8cf3){return _0x540301===_0x5b8cf3;},'nCWlc':'AI_PROVIDER','HWLfA':function(_0x5a106e,_0x96a0dd){return _0x5a106e===_0x96a0dd;},'aqKDw':_0x45eeea(0x5a5),'YDscd':_0x45eeea(0x64c),'duztc':_0x45eeea(0x13c),'zJHSy':_0x45eeea(0x1c7),'pnFcW':function(_0x3a2aec,_0xda56d9){return _0x3a2aec===_0xda56d9;},'YvPOG':_0x45eeea(0x243),'bIquX':function(_0x57ca6d,_0x1d2de8,_0x12c25d){return _0x57ca6d(_0x1d2de8,_0x12c25d);},'Mxykw':'utf-8','JATlE':function(_0x14a71b,_0x288012){return _0x14a71b<_0x288012;},'mVVxR':function(_0x566c5e,_0xe628b2){return _0x566c5e+_0xe628b2;},'msPxK':function(_0x239a79,_0x42c202){return _0x239a79-_0x42c202;},'xPUWv':_0x45eeea(0x1ab),'YgthQ':function(_0x402e44,_0x2cae70){return _0x402e44(_0x2cae70);},'WQQQO':function(_0x170108,_0x1ee6f5){return _0x170108(_0x1ee6f5);},'FcwPe':function(_0x2cc7ba,_0x569b5e){return _0x2cc7ba(_0x569b5e);}};try{const _0x49fd7d=path['join'](__dirname,'../../.env'),_0x37f155={};_0x37f155[_0x45eeea(0x461)]=process.env.AI_PROVIDER||_0x45eeea(0x6b7),_0x37f155[_0x45eeea(0x608)]=process.env.AI_MODEL||'',_0x37f155[_0x45eeea(0x564)]=process.env.OPENAI_API_KEY||'',_0x37f155[_0x45eeea(0x553)]=process.env.GEMINI_API_KEY||'',_0x37f155[_0x45eeea(0xe5)]=process.env.CLAUDE_API_KEY||'',_0x37f155[_0x45eeea(0x5f3)]=process.env.GITHUB_TOKEN||'',_0x37f155['groq_api_key']=process.env.GROQ_API_KEY||'',_0x37f155[_0x45eeea(0x35e)]=process.env.COHERE_API_KEY||'',_0x37f155[_0x45eeea(0x19c)]=process.env.MISTRAL_API_KEY||'';let _0x1b8c9f=_0x37f155;try{if(_0x4b7f12['xPUWv']!=='UjRvP'){const _0x29802b=await fs['readFile'](_0x49fd7d,_0x4b7f12['Mxykw']),_0x5afb53=_0x29802b['split']('\x0a');_0x5afb53['forEach'](_0x4a6a41=>{const _0x59d4af=_0x45eeea,[_0x20e4ef,_0x5ab56b]=_0x4a6a41[_0x59d4af(0x722)]('=');if(_0x4b7f12['ubiXy'](_0x20e4ef,_0x5ab56b)){const _0x150994=_0x20e4ef[_0x59d4af(0x5cf)](),_0x539d4d=_0x5ab56b[_0x59d4af(0x5cf)]();if(_0x4b7f12['SBFvH'](_0x150994,_0x4b7f12[_0x59d4af(0x71a)]))_0x1b8c9f[_0x59d4af(0x461)]=_0x539d4d;if(_0x4b7f12[_0x59d4af(0x45a)](_0x150994,_0x59d4af(0x447)))_0x1b8c9f[_0x59d4af(0x608)]=_0x539d4d;if(_0x4b7f12[_0x59d4af(0x1d7)](_0x150994,_0x4b7f12['aqKDw']))_0x1b8c9f['openai_api_key']=_0x539d4d;if(_0x4b7f12['SBFvH'](_0x150994,_0x4b7f12['YDscd']))_0x1b8c9f[_0x59d4af(0x553)]=_0x539d4d;if(_0x150994===_0x59d4af(0x210))_0x1b8c9f[_0x59d4af(0xe5)]=_0x539d4d;if(_0x150994===_0x4b7f12[_0x59d4af(0x29d)])_0x1b8c9f[_0x59d4af(0x5f3)]=_0x539d4d;if(_0x150994===_0x4b7f12[_0x59d4af(0x633)])_0x1b8c9f['groq_api_key']=_0x539d4d;if(_0x4b7f12[_0x59d4af(0x69a)](_0x150994,_0x4b7f12[_0x59d4af(0x47c)]))_0x1b8c9f[_0x59d4af(0x35e)]=_0x539d4d;if(_0x4b7f12[_0x59d4af(0x1d7)](_0x150994,_0x59d4af(0x101)))_0x1b8c9f[_0x59d4af(0x19c)]=_0x539d4d;}});}else _0x1441a1=QqbhUJ[_0x45eeea(0x64b)](_0x127e3b,_0x45eeea(0x581)+_0x952835+_0x45eeea(0x60b),{'encoding':QqbhUJ[_0x45eeea(0x45e)]})[_0x45eeea(0x5cf)]();}catch(_0x27418d){}const _0x1d1b07=_0x7476f3=>{const _0x3be024=_0x45eeea;if(!_0x7476f3||_0x4b7f12[_0x3be024(0x5df)](_0x7476f3[_0x3be024(0x162)],0x8))return'';return _0x4b7f12[_0x3be024(0x3f7)]('•'[_0x3be024(0x5fb)](_0x4b7f12[_0x3be024(0x3e2)](_0x7476f3[_0x3be024(0x162)],0x4)),_0x7476f3[_0x3be024(0x12c)](-0x4));};_0x22d5e4[_0x45eeea(0x169)]({'provider':_0x1b8c9f['provider'],'model':_0x1b8c9f[_0x45eeea(0x608)],'openai_api_key':_0x4b7f12['YgthQ'](_0x1d1b07,_0x1b8c9f[_0x45eeea(0x564)]),'gemini_api_key':_0x4b7f12[_0x45eeea(0x6df)](_0x1d1b07,_0x1b8c9f['gemini_api_key']),'claude_api_key':_0x1d1b07(_0x1b8c9f['claude_api_key']),'github_token':_0x1d1b07(_0x1b8c9f[_0x45eeea(0x5f3)]),'groq_api_key':_0x1d1b07(_0x1b8c9f['groq_api_key']),'cohere_api_key':_0x4b7f12['FcwPe'](_0x1d1b07,_0x1b8c9f['cohere_api_key']),'mistral_api_key':_0x4b7f12[_0x45eeea(0x6df)](_0x1d1b07,_0x1b8c9f[_0x45eeea(0x19c)]),'has_openai_key':!!_0x1b8c9f[_0x45eeea(0x564)],'has_gemini_key':!!_0x1b8c9f[_0x45eeea(0x553)],'has_claude_key':!!_0x1b8c9f[_0x45eeea(0xe5)],'has_github_token':!!_0x1b8c9f[_0x45eeea(0x5f3)],'has_groq_key':!!_0x1b8c9f['groq_api_key'],'has_cohere_key':!!_0x1b8c9f[_0x45eeea(0x35e)],'has_mistral_key':!!_0x1b8c9f[_0x45eeea(0x19c)]});}catch(_0x29954e){const _0x2f5146={};_0x2f5146[_0x45eeea(0x66c)]=![],_0x2f5146['error']=_0x29954e[_0x45eeea(0x4f1)],_0x22d5e4['status'](0x1f4)['json'](_0x2f5146);}}),app[_0x320de1(0x70f)](_0x320de1(0x481),async(_0x138e65,_0x5bf89d)=>{const _0xf64d0d=_0x320de1,_0x266742={};_0x266742['tAaFf']=_0xf64d0d(0x1f6),_0x266742['DbVjo']=_0xf64d0d(0x307),_0x266742[_0xf64d0d(0x6c6)]='Failed\x20to\x20get\x20locators',_0x266742[_0xf64d0d(0x45f)]=_0xf64d0d(0x1ec),_0x266742[_0xf64d0d(0x451)]=_0xf64d0d(0x36d),_0x266742[_0xf64d0d(0x107)]=_0xf64d0d(0x6ce),_0x266742[_0xf64d0d(0x1b7)]=function(_0x26af2b,_0x1d02e2){return _0x26af2b!==_0x1d02e2;},_0x266742[_0xf64d0d(0x15c)]=_0xf64d0d(0x150),_0x266742[_0xf64d0d(0x539)]=_0xf64d0d(0x6d9),_0x266742[_0xf64d0d(0x6e1)]='uyAif',_0x266742[_0xf64d0d(0x666)]=_0xf64d0d(0x3cd),_0x266742[_0xf64d0d(0x580)]=_0xf64d0d(0x4f4),_0x266742[_0xf64d0d(0x436)]=_0xf64d0d(0x409);const _0x1d1f8c=_0x266742;try{if('vCSLz'===_0xf64d0d(0x53d)){const _0x5534f5={};return _0x5534f5[_0xf64d0d(0x66c)]=!![],_0x5534f5[_0xf64d0d(0x4f1)]=Oqdntq[_0xf64d0d(0x4ab)],_0x3533db[_0xf64d0d(0x169)](_0x5534f5);}else{const {provider:_0x473f3e,model:_0x1227f3,openai_api_key:_0x11b620,gemini_api_key:_0x1091dc,claude_api_key:_0x14e265,github_token:_0x32b3b8,groq_api_key:_0x129e9c,cohere_api_key:_0x3b7896,mistral_api_key:_0x532006}=_0x138e65[_0xf64d0d(0x5a1)],_0x4fc3a0=path[_0xf64d0d(0x4dd)](__dirname,_0x1d1f8c[_0xf64d0d(0x451)]);let _0x33551c=_0xf64d0d(0x1b2)+_0x473f3e+'\x0a';if(_0x1227f3){if(_0x1d1f8c[_0xf64d0d(0x107)]!==_0x1d1f8c['dKgLR']){_0x487811[_0xf64d0d(0x49e)](_0x1d1f8c[_0xf64d0d(0x443)]);const _0x2cf65f={};_0x2cf65f[_0xf64d0d(0x66c)]=![],_0x2cf65f[_0xf64d0d(0x644)]=_0x1d1f8c[_0xf64d0d(0x6c6)],_0xa95691[_0xf64d0d(0x365)](0x1f4)[_0xf64d0d(0x169)](_0x2cf65f);}else _0x33551c+=_0xf64d0d(0x1e9)+_0x1227f3+'\x0a';}if(_0x11b620){if(_0x1d1f8c['TlFzV'](_0xf64d0d(0x709),_0x1d1f8c[_0xf64d0d(0x15c)]))_0x33551c+='OPENAI_API_KEY='+_0x11b620+'\x0a';else{const _0x3980ee={};_0x3980ee[_0xf64d0d(0x14d)]=Oqdntq['OYieB'],_0x3980ee['data']='['+_0x133bb0+']\x20'+_0x9b2720,_0x3980ee[_0xf64d0d(0x1a6)]=[_0x932079],_0x3f10ce['send'](_0x5609ac[_0xf64d0d(0x2a5)](_0x3980ee));}}_0x1091dc&&(_0x33551c+=_0xf64d0d(0x11c)+_0x1091dc+'\x0a');_0x14e265&&(_0x1d1f8c[_0xf64d0d(0x539)]!==_0x1d1f8c[_0xf64d0d(0x6e1)]?_0x33551c+=_0xf64d0d(0x32e)+_0x14e265+'\x0a':_0x561219['log'](_0xf64d0d(0x3f4)+_0x46269b[_0xf64d0d(0x143)]));_0x32b3b8&&(_0x1d1f8c[_0xf64d0d(0x666)]===_0x1d1f8c[_0xf64d0d(0x666)]?_0x33551c+=_0xf64d0d(0x38a)+_0x32b3b8+'\x0a':_0x2415b4+=_0xf64d0d(0x696)+_0x183bd4+'\x0a');_0x129e9c&&(_0x33551c+=_0xf64d0d(0x696)+_0x129e9c+'\x0a');_0x3b7896&&(_0x33551c+='COHERE_API_KEY='+_0x3b7896+'\x0a');_0x532006&&(_0x33551c+=_0xf64d0d(0x444)+_0x532006+'\x0a');process.env.WDA_PATH&&(_0x33551c+=_0xf64d0d(0x56a)+process.env.WDA_PATH+'\x0a');await fs[_0xf64d0d(0x184)](_0x4fc3a0,_0x33551c),process.env.AI_PROVIDER=_0x473f3e;if(_0x1227f3)process.env.AI_MODEL=_0x1227f3;if(_0x11b620)process.env.OPENAI_API_KEY=_0x11b620;if(_0x1091dc)process.env.GEMINI_API_KEY=_0x1091dc;if(_0x14e265)process.env.CLAUDE_API_KEY=_0x14e265;if(_0x32b3b8)process.env.GITHUB_TOKEN=_0x32b3b8;if(_0x129e9c)process.env.GROQ_API_KEY=_0x129e9c;if(_0x3b7896)process.env.COHERE_API_KEY=_0x3b7896;if(_0x532006)process.env.MISTRAL_API_KEY=_0x532006;aiManager[_0xf64d0d(0x461)]=_0x473f3e;if(_0x1227f3)aiManager[_0xf64d0d(0x608)]=_0x1227f3;aiManager[_0xf64d0d(0x5fa)]();const _0x5915c6={};_0x5915c6[_0xf64d0d(0x66c)]=!![],_0x5915c6[_0xf64d0d(0x4f1)]=_0x1d1f8c[_0xf64d0d(0x580)],_0x5bf89d[_0xf64d0d(0x169)](_0x5915c6);}}catch(_0x5b84f6){if(_0xf64d0d(0x37e)!==_0x1d1f8c[_0xf64d0d(0x436)]){const _0x3b9cc3={};_0x3b9cc3['success']=![],_0x3b9cc3[_0xf64d0d(0x644)]=_0x5b84f6['message'],_0x5bf89d[_0xf64d0d(0x365)](0x1f4)[_0xf64d0d(0x169)](_0x3b9cc3);}else{const _0x5e4d8c={};_0x5e4d8c[_0xf64d0d(0x66c)]=![],_0x5e4d8c[_0xf64d0d(0x644)]=_0x51122f[_0xf64d0d(0x4f1)],_0x15b599[_0xf64d0d(0x365)](0x1f4)[_0xf64d0d(0x169)](_0x5e4d8c);}}}),app[_0x320de1(0x5af)]('/api/settings/ai-providers',(_0x619ddd,_0x550bac)=>{const _0x5b73f7=_0x320de1,_0x38bb0c={'oNFgX':function(_0x8e3164,_0x21033c){return _0x8e3164(_0x21033c);},'jbhsg':_0x5b73f7(0x2c8)};try{const {AI_PROVIDERS_CONFIG:_0x93a4c1}=_0x38bb0c['oNFgX'](require,_0x38bb0c['jbhsg']),_0x4e5687={};_0x4e5687['success']=!![],_0x4e5687['providers']=_0x93a4c1,_0x550bac[_0x5b73f7(0x169)](_0x4e5687);}catch(_0xa92c61){const _0x50161d={};_0x50161d['success']=![],_0x50161d[_0x5b73f7(0x644)]=_0xa92c61['message'],_0x550bac[_0x5b73f7(0x365)](0x1f4)[_0x5b73f7(0x169)](_0x50161d);}}),app[_0x320de1(0x5af)]('/api/settings/devices',async(_0x728ace,_0x2964c5)=>{const _0x37f497=_0x320de1,_0x2d7c3a={'nUVjP':function(_0xd22796){return _0xd22796();}};try{const _0x5a7902=await _0x2d7c3a[_0x37f497(0x5e5)](loadDeviceConfig),_0x2ec721={};_0x2ec721[_0x37f497(0x66c)]=!![],_0x2ec721[_0x37f497(0x1a6)]=_0x5a7902,_0x2964c5['json'](_0x2ec721);}catch(_0x4176ad){const _0x164f38={};_0x164f38[_0x37f497(0x66c)]=![],_0x164f38[_0x37f497(0x644)]=_0x4176ad[_0x37f497(0x4f1)],_0x2964c5[_0x37f497(0x365)](0x1f4)[_0x37f497(0x169)](_0x164f38);}}),app[_0x320de1(0x70f)](_0x320de1(0x5ed),async(_0x5de189,_0x7063e6)=>{const _0x523e74=_0x320de1,_0x3107ea={};_0x3107ea[_0x523e74(0x47a)]=_0x523e74(0x4a0),_0x3107ea[_0x523e74(0x65c)]=_0x523e74(0x57d),_0x3107ea[_0x523e74(0x49b)]=function(_0x1dd1fe,_0x1fbf5f){return _0x1dd1fe===_0x1fbf5f;},_0x3107ea['GMzgJ']=_0x523e74(0x492),_0x3107ea[_0x523e74(0x500)]=_0x523e74(0x724),_0x3107ea[_0x523e74(0x745)]=_0x523e74(0x755),_0x3107ea['MBXHp']=_0x523e74(0xec),_0x3107ea['UIIyA']=_0x523e74(0x110),_0x3107ea[_0x523e74(0x63a)]=_0x523e74(0x4ba),_0x3107ea[_0x523e74(0x533)]='#\x20🔌\x20USB\x20DEVICES:\x20Automatically\x20detected\x20and\x20saved\x20here\x0a',_0x3107ea['SiLCd']='#\x20\x20\x20\x20-\x20Add\x20IP\x20address\x20to\x20enable\x20wireless\x20support\x20later\x0a',_0x3107ea[_0x523e74(0x2b3)]=_0x523e74(0x3e6),_0x3107ea[_0x523e74(0x12a)]=_0x523e74(0x140),_0x3107ea[_0x523e74(0x4f7)]='#\x20Example\x20entries:\x0a',_0x3107ea[_0x523e74(0x2ff)]='#\x20iPhone16P,00008140-001C24361E41801C,10.173.221.204,ios,wireless\x20\x20(iOS\x20Wireless)\x0a',_0x3107ea[_0x523e74(0x23a)]=_0x523e74(0x2ed),_0x3107ea[_0x523e74(0x158)]=_0x523e74(0x71b),_0x3107ea[_0x523e74(0x281)]=_0x523e74(0x15b);const _0x5d9b39=_0x3107ea;try{if(_0x5d9b39[_0x523e74(0x49b)](_0x5d9b39['GMzgJ'],_0x5d9b39[_0x523e74(0x500)]))_0x2cf4d7=_0x523e74(0x2e4)+_0x63431b+','+_0x38111e,_0xe817f0['log'](_0x523e74(0x756)+_0x4fe656+','+_0x3f428a+_0x523e74(0x3c4)+_0x4184d3);else{const {devices:_0x52c82d}=_0x5de189[_0x523e74(0x5a1)];let _0x3197b4=_0x5d9b39[_0x523e74(0x745)];_0x3197b4+=_0x5d9b39[_0x523e74(0x1d0)],_0x3197b4+=_0x5d9b39[_0x523e74(0x1e8)],_0x3197b4+=_0x5d9b39[_0x523e74(0x63a)],_0x3197b4+='#\x20\x0a',_0x3197b4+=_0x5d9b39[_0x523e74(0x533)],_0x3197b4+=_0x523e74(0x327),_0x3197b4+=_0x5d9b39[_0x523e74(0x3ec)],_0x3197b4+='#\x0a',_0x3197b4+=_0x5d9b39[_0x523e74(0x2b3)],_0x3197b4+=_0x523e74(0x2b1),_0x3197b4+=_0x5d9b39['tGQHT'],_0x3197b4+='#\x20\x20\x20\x20-\x20Android:\x20Enable\x20wireless\x20ADB\x20first\x0a',_0x3197b4+='#\x0a',_0x3197b4+=_0x5d9b39[_0x523e74(0x4f7)],_0x3197b4+='#\x20iPhone17,00008130-001945C63ED3401E,,ios,usb\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(iOS\x20USB\x20-\x20auto-detected)\x0a',_0x3197b4+=_0x5d9b39[_0x523e74(0x2ff)],_0x3197b4+=_0x5d9b39['DpxpY'],_0x3197b4+=_0x5d9b39[_0x523e74(0x158)],_0x52c82d['forEach'](_0x1cd194=>{const _0x304774=_0x523e74,_0x25e9e7=_0x1cd194['ip']||'',_0x181d9c=_0x1cd194[_0x304774(0x5d6)]||'ios',_0x2b4964=_0x1cd194['type']||_0x1cd194['connectionType']||(_0x25e9e7?_0x5d9b39[_0x304774(0x47a)]:_0x5d9b39[_0x304774(0x65c)]);_0x3197b4+=_0x1cd194[_0x304774(0x4b8)]+','+_0x1cd194[_0x304774(0x23d)]+','+_0x25e9e7+','+_0x181d9c+','+_0x2b4964+'\x0a';}),await fs[_0x523e74(0x184)](DEVICE_CONFIG,_0x3197b4);const _0x2b9902={};_0x2b9902[_0x523e74(0x66c)]=!![],_0x2b9902[_0x523e74(0x4f1)]=_0x5d9b39['dxwbJ'],_0x7063e6[_0x523e74(0x169)](_0x2b9902);}}catch(_0xc6cf52){const _0x28e623={};_0x28e623[_0x523e74(0x66c)]=![],_0x28e623['error']=_0xc6cf52[_0x523e74(0x4f1)],_0x7063e6[_0x523e74(0x365)](0x1f4)[_0x523e74(0x169)](_0x28e623);}}),app['get'](_0x320de1(0x3e0),async(_0x595f9a,_0x411e39)=>{const _0x25b6e6=_0x320de1,_0x3c27a3={};_0x3c27a3['ajsMU']=function(_0x4ad4b8,_0x53ba23){return _0x4ad4b8!==_0x53ba23;},_0x3c27a3['cOFRt']='pnnEx';const _0x4fe664=_0x3c27a3;try{const _0x27823a=await fs['readFile'](APPS_CONFIG,_0x25b6e6(0x1ef)),_0x5ef7fd=_0x27823a[_0x25b6e6(0x722)]('\x0a')[_0x25b6e6(0x47e)](_0x96135e=>_0x96135e['trim']()&&!_0x96135e[_0x25b6e6(0x59e)]('#'))[_0x25b6e6(0x240)](_0x50bd24=>{const _0x48d4a8=_0x25b6e6;if(_0x4fe664[_0x48d4a8(0x227)](_0x4fe664[_0x48d4a8(0x2e9)],'pnnEx')){const _0x3ad757={};return _0x3ad757[_0x48d4a8(0x66c)]=![],_0x3ad757[_0x48d4a8(0x644)]=_0x48d4a8(0x391),_0x3fb87c[_0x48d4a8(0x365)](0x190)[_0x48d4a8(0x169)](_0x3ad757);}else{const [_0x347f84,_0x317f69]=_0x50bd24[_0x48d4a8(0x722)](',');return{'name':_0x347f84[_0x48d4a8(0x5cf)](),'packageId':_0x317f69[_0x48d4a8(0x5cf)]()};}}),_0xce3cca={};_0xce3cca[_0x25b6e6(0x66c)]=!![],_0xce3cca['apps']=_0x5ef7fd,_0x411e39[_0x25b6e6(0x169)](_0xce3cca);}catch(_0x3806eb){const _0x491a45={};_0x491a45[_0x25b6e6(0x66c)]=![],_0x491a45['error']=_0x3806eb[_0x25b6e6(0x4f1)],_0x411e39[_0x25b6e6(0x365)](0x1f4)[_0x25b6e6(0x169)](_0x491a45);}}),app[_0x320de1(0x70f)](_0x320de1(0x340),async(_0x3d9276,_0x10c32d)=>{const _0x3b889c=_0x320de1,_0x33c452={'DAiCG':_0x3b889c(0x1ec),'txZiB':_0x3b889c(0x4f6),'rQBMP':_0x3b889c(0x495),'irBDS':'AI_MODEL','laVfw':function(_0x2c3968,_0x487943){return _0x2c3968===_0x487943;},'vGtMo':_0x3b889c(0x64c),'XfWuF':_0x3b889c(0x13c),'KtRmX':_0x3b889c(0x243),'pvlYx':_0x3b889c(0x101),'Rfppu':_0x3b889c(0x596),'pQlvU':function(_0x544d5c,_0x5af686,_0x1c8ce0){return _0x544d5c(_0x5af686,_0x1c8ce0);},'fegYe':'utf-8','yDyup':_0x3b889c(0x441),'OCuWD':_0x3b889c(0x1be),'QuMfe':_0x3b889c(0x442),'GYDod':function(_0x5a747d,_0x484d58){return _0x5a747d(_0x484d58);},'vZJtj':_0x3b889c(0x394),'MFvdS':'BmwBg','dDdKf':_0x3b889c(0x30f),'dLowQ':_0x3b889c(0x346),'ARJsi':_0x3b889c(0x5a0),'WCxHy':_0x3b889c(0x458),'RAbKM':function(_0x1ab1fa,_0x16137d){return _0x1ab1fa!==_0x16137d;},'oLusS':_0x3b889c(0x628),'JlbIO':function(_0x7c7cb9,_0x53a461,_0x4520ad,_0x1d6012){return _0x7c7cb9(_0x53a461,_0x4520ad,_0x1d6012);},'uXXbr':_0x3b889c(0x311),'xOIFy':_0x3b889c(0x1aa),'rAzSU':_0x3b889c(0x5f6),'uapoS':_0x3b889c(0x1e7),'DffSO':function(_0x597d4e,_0x3f4536){return _0x597d4e===_0x3f4536;},'qAeJC':function(_0x20081d,_0x46b5d7){return _0x20081d!==_0x46b5d7;},'ezAmr':_0x3b889c(0x3b1),'LcEmB':'Failed\x20to\x20get\x20UI\x20elements.\x20Please\x20ensure\x20UIAutomator2\x20is\x20installed\x20for\x20Android\x20devices.','QwEpw':_0x3b889c(0x1c6),'ARyRC':_0x3b889c(0x187),'HnLTV':'❌\x20No\x20output\x20found\x20in\x20results','JGMdo':function(_0xb59827,_0x4e1448){return _0xb59827(_0x4e1448);},'FCiDX':function(_0x2474a5,_0x41c6ac){return _0x2474a5!==_0x41c6ac;},'czVOc':_0x3b889c(0x606),'YMRsY':_0x3b889c(0x2d8),'VKFjB':_0x3b889c(0x307),'ncwvA':'Failed\x20to\x20get\x20locators','uOyGZ':function(_0x41399c,_0x38c7de){return _0x41399c!==_0x38c7de;},'OtkLn':_0x3b889c(0x13e),'KQjhf':_0x3b889c(0x6fc)};try{const {deviceName:_0x4dae7b}=_0x3d9276[_0x3b889c(0x5a1)];if(!_0x4dae7b){if(_0x33c452[_0x3b889c(0x53a)]!==_0x33c452[_0x3b889c(0x729)]){const _0x947b27={};return _0x947b27[_0x3b889c(0x66c)]=![],_0x947b27[_0x3b889c(0x644)]=_0x3b889c(0x2bb),_0x10c32d[_0x3b889c(0x365)](0x190)[_0x3b889c(0x169)](_0x947b27);}else _0x5a6782+=_0x59afc6['toString']();}logger['debug'](_0x3b889c(0xe7)+_0x4dae7b);const _0x108564=connectedDevices[_0x3b889c(0x2fa)](_0xaa21f5=>_0xaa21f5[_0x3b889c(0x4b8)]===_0x4dae7b);if(!_0x108564){if(_0x33c452[_0x3b889c(0x180)]===_0x33c452[_0x3b889c(0x4c3)]){const _0x50ff11={};_0x50ff11[_0x3b889c(0x14d)]=BygXTj[_0x3b889c(0x4ad)],_0x50ff11[_0x3b889c(0x760)]='❌\x20Error:\x20'+_0x3d959f[_0x3b889c(0x4f1)]+'\x0a',_0x50ff11[_0x3b889c(0x1a6)]=_0x39dea9,_0x2eee98[_0x3b889c(0x475)](_0x3cd9aa['stringify'](_0x50ff11));}else{const _0x23ba7c={};return _0x23ba7c[_0x3b889c(0x66c)]=![],_0x23ba7c['error']=_0x3b889c(0x4d9),_0x10c32d[_0x3b889c(0x365)](0x194)['json'](_0x23ba7c);}}if(_0x33c452[_0x3b889c(0x171)](_0x108564['platform'],_0x33c452[_0x3b889c(0x6b6)])){const _0x16f2e7=androidSessions['get'](_0x108564[_0x3b889c(0x23d)]);if(!_0x16f2e7){if(_0x33c452[_0x3b889c(0x517)]!==_0x33c452['WCxHy']){_0x1b4fe6[_0x3b889c(0x49e)]('🔍\x20Killing\x20processes\x20on\x20port\x20'+_0x4f38fa+_0x3b889c(0x1d6)+_0x33091d+_0x3b889c(0x57b));const _0x5a1035=_0x8107a0('sh',['-c',_0x3b889c(0x419)+_0xa906d2+'\x20|\x20xargs\x20kill\x20-9\x202>/dev/null\x20||\x20true']);_0x5a1035['on'](BygXTj[_0x3b889c(0x22f)],()=>{const _0x1ae1cf=_0x3b889c;_0x15bb26[_0x1ae1cf(0x49e)]('✅\x20Cleaned\x20up\x20port\x20'+_0x49db8a+_0x1ae1cf(0x1d6)+_0x1c2f19);});}else{console[_0x3b889c(0x49e)](_0x3b889c(0x728)+_0x4dae7b+'\x20for\x20getLocators...');try{const _0x3d1d53=await _0x33c452[_0x3b889c(0x149)](connectToDevice,_0x108564);if(!_0x3d1d53[_0x3b889c(0x66c)]){if(_0x33c452[_0x3b889c(0x74c)](_0x33c452[_0x3b889c(0xe2)],_0x33c452[_0x3b889c(0xe2)])){const _0x2061ff=_0x1f7941[_0x3b889c(0x5cf)](),_0x591f70=_0x440f83[_0x3b889c(0x5cf)]();if(_0x2061ff===BygXTj[_0x3b889c(0x6eb)])_0x22df9b['provider']=_0x591f70;if(_0x2061ff===BygXTj[_0x3b889c(0x555)])_0x363ba4[_0x3b889c(0x608)]=_0x591f70;if(_0x2061ff===_0x3b889c(0x5a5))_0x4aa1ee['openai_api_key']=_0x591f70;if(BygXTj[_0x3b889c(0x171)](_0x2061ff,BygXTj[_0x3b889c(0x2af)]))_0x5cdad3['gemini_api_key']=_0x591f70;if(BygXTj['laVfw'](_0x2061ff,_0x3b889c(0x210)))_0x268a2f[_0x3b889c(0xe5)]=_0x591f70;if(_0x2061ff===BygXTj['XfWuF'])_0x5ecdd8[_0x3b889c(0x5f3)]=_0x591f70;if(BygXTj[_0x3b889c(0x171)](_0x2061ff,_0x3b889c(0x1c7)))_0x5abe48[_0x3b889c(0x565)]=_0x591f70;if(BygXTj['laVfw'](_0x2061ff,BygXTj[_0x3b889c(0x396)]))_0x2ce069['cohere_api_key']=_0x591f70;if(BygXTj[_0x3b889c(0x171)](_0x2061ff,BygXTj[_0x3b889c(0x5ce)]))_0x5b7ca6[_0x3b889c(0x19c)]=_0x591f70;}else{const _0x5107c9={};return _0x5107c9[_0x3b889c(0x66c)]=![],_0x5107c9[_0x3b889c(0x644)]=_0x3b889c(0x720),_0x10c32d[_0x3b889c(0x365)](0x1f4)[_0x3b889c(0x169)](_0x5107c9);}}await new Promise(_0x2cae1d=>setTimeout(_0x2cae1d,0x7d0));}catch(_0x54ce1e){const _0x27008c={};return _0x27008c[_0x3b889c(0x66c)]=![],_0x27008c[_0x3b889c(0x644)]=_0x3b889c(0x51b)+_0x54ce1e[_0x3b889c(0x4f1)],_0x10c32d[_0x3b889c(0x365)](0x1f4)[_0x3b889c(0x169)](_0x27008c);}}}}const _0x5bb8bc=await _0x33c452['JlbIO'](executeCommand,[_0x4dae7b],_0x33c452[_0x3b889c(0x52f)],null);logger[_0x3b889c(0x3d0)]('Result\x20success:\x20'+_0x5bb8bc[_0x3b889c(0x66c)]),logger[_0x3b889c(0x3d0)](_0x3b889c(0x1e1)+(_0x5bb8bc[_0x3b889c(0x3a2)]?.['length']||0x0));if(_0x5bb8bc[_0x3b889c(0x66c)]&&_0x5bb8bc[_0x3b889c(0x3a2)]){if(_0x33c452[_0x3b889c(0x74c)](_0x33c452[_0x3b889c(0x658)],_0x3b889c(0x1aa))){const _0x38bdc7={};return _0x38bdc7['success']=![],_0x38bdc7[_0x3b889c(0x644)]=_0x33c452[_0x3b889c(0x567)],_0x536b4b[_0x3b889c(0x169)](_0x38bdc7);}else{let _0x554378='';for(const _0x61ec55 of _0x5bb8bc['results']){if(_0x33c452[_0x3b889c(0xe3)]!==_0x33c452[_0x3b889c(0xe3)]){const _0x1d1b46=_0x33c452[_0x3b889c(0x513)](_0xdb017a,_0x3b889c(0x600)+_0x4c64de+_0x3b889c(0x1cb)+_0x1ded34,{'encoding':_0x33c452[_0x3b889c(0x52b)],'timeout':0x2710});_0x5d6608[_0x3b889c(0x433)]=_0x1d1b46['replace'](_0x33c452[_0x3b889c(0x73c)],'')['trim']();}else{logger[_0x3b889c(0x3d0)]('Script\x20result:',_0x61ec55);if(_0x61ec55['status']===_0x33c452['uapoS']&&_0x61ec55[_0x3b889c(0x527)]&&_0x61ec55['value'][_0x3b889c(0x3a2)])for(const _0x202b1f of _0x61ec55[_0x3b889c(0x527)][_0x3b889c(0x3a2)]){logger[_0x3b889c(0x3d0)](_0x3b889c(0x183)+_0x202b1f[_0x3b889c(0x365)]);if(_0x33c452['DffSO'](_0x202b1f[_0x3b889c(0x365)],_0x33c452[_0x3b889c(0x310)])&&_0x202b1f[_0x3b889c(0x527)]){if(_0x33c452[_0x3b889c(0x286)](_0x33c452[_0x3b889c(0x683)],_0x3b889c(0x3b1)))_0x233f7d+=_0x179f21[_0x3b889c(0x4e4)]();else{if(_0x202b1f['value'][_0x3b889c(0x66c)]&&_0x202b1f['value']['output']){_0x554378=_0x202b1f[_0x3b889c(0x527)][_0x3b889c(0x22c)],logger['debug']('Found\x20output:\x20'+_0x554378[_0x3b889c(0x162)]+_0x3b889c(0x4ea));break;}else{if(_0x202b1f[_0x3b889c(0x527)][_0x3b889c(0x644)]){console[_0x3b889c(0x49e)]('❌\x20Script\x20error:',_0x202b1f[_0x3b889c(0x527)][_0x3b889c(0x644)]);const _0x3cec20={};return _0x3cec20[_0x3b889c(0x66c)]=![],_0x3cec20[_0x3b889c(0x644)]=_0x33c452[_0x3b889c(0x3eb)],_0x10c32d[_0x3b889c(0x365)](0x1f4)[_0x3b889c(0x169)](_0x3cec20);}}}}}if(_0x554378)break;}}if(!_0x554378){if(_0x33c452[_0x3b889c(0x113)]===_0x33c452[_0x3b889c(0x4a2)]){const _0xf2346a={};_0xf2346a[_0x3b889c(0x14d)]=_0x3b889c(0x230),_0xf2346a['devices']=_0x486580,_0x56b2d6[_0x3b889c(0x475)](_0x285366[_0x3b889c(0x2a5)](_0xf2346a));}else{console[_0x3b889c(0x49e)](_0x33c452[_0x3b889c(0x487)]),console[_0x3b889c(0x49e)](_0x3b889c(0x2dc),JSON[_0x3b889c(0x2a5)](_0x5bb8bc,null,0x2));const _0x51cb77={};return _0x51cb77[_0x3b889c(0x66c)]=![],_0x51cb77['error']=_0x3b889c(0x6ea),_0x10c32d[_0x3b889c(0x365)](0x1f4)[_0x3b889c(0x169)](_0x51cb77);}}const _0x59f333=_0x33c452[_0x3b889c(0x10d)](parseLocatorsOutput,_0x554378);console[_0x3b889c(0x49e)]('✅\x20Parsed\x20'+_0x59f333[_0x3b889c(0x162)]+_0x3b889c(0x6ed));const _0x49889e=_0x59f333[_0x3b889c(0x47e)](_0x1affdd=>_0x1affdd[_0x3b889c(0x4b8)]||_0x1affdd[_0x3b889c(0x3a5)]||_0x1affdd[_0x3b889c(0x2a6)]);console[_0x3b889c(0x49e)](_0x3b889c(0x5a4)+_0x49889e[_0x3b889c(0x162)]+_0x3b889c(0xfa));const _0x14fcc8={};_0x14fcc8['success']=!![],_0x14fcc8['locators']=_0x49889e,_0x10c32d[_0x3b889c(0x169)](_0x14fcc8);}}else{if(_0x33c452[_0x3b889c(0x2ee)](_0x33c452['czVOc'],_0x33c452[_0x3b889c(0x1d3)])){console[_0x3b889c(0x49e)](_0x33c452[_0x3b889c(0x2c9)]);const _0x25a54f={};_0x25a54f[_0x3b889c(0x66c)]=![],_0x25a54f[_0x3b889c(0x644)]=_0x33c452[_0x3b889c(0x303)],_0x10c32d[_0x3b889c(0x365)](0x1f4)[_0x3b889c(0x169)](_0x25a54f);}else{const _0x598562={};_0x598562[_0x3b889c(0x66c)]=![],_0x598562[_0x3b889c(0x644)]=_0x33c452[_0x3b889c(0x61e)],_0x13558d['status'](0x194)[_0x3b889c(0x169)](_0x598562);}}}catch(_0x85f20f){if(_0x33c452[_0x3b889c(0x39b)](_0x33c452[_0x3b889c(0x2ca)],_0x33c452['KQjhf'])){console[_0x3b889c(0x644)](_0x3b889c(0x1a9),_0x85f20f);const _0x4366c3={};_0x4366c3[_0x3b889c(0x66c)]=![],_0x4366c3['error']=_0x85f20f[_0x3b889c(0x4f1)],_0x10c32d[_0x3b889c(0x365)](0x1f4)[_0x3b889c(0x169)](_0x4366c3);}else{_0x7471b3[_0x3b889c(0x644)](BygXTj['QuMfe'],_0xc91311);const _0x1f50e0={};_0x1f50e0[_0x3b889c(0x66c)]=![],BygXTj[_0x3b889c(0x149)](_0xb56021,_0x1f50e0);}}}),app['post'](_0x320de1(0x6d7),async(_0x327a6e,_0x1f240c)=>{const _0x235a47=_0x320de1,_0x354af8={'BEngM':function(_0x566f8b,_0x45d19f){return _0x566f8b===_0x45d19f;},'CkHlr':_0x235a47(0x10f),'Ezpmt':_0x235a47(0x3b7),'URTMX':function(_0x2deaa6,_0x30d0b0,_0x55f912,_0xf4d611,_0x4e156b){return _0x2deaa6(_0x30d0b0,_0x55f912,_0xf4d611,_0x4e156b);},'rrVHb':_0x235a47(0x2bb),'yOGwX':function(_0x426247,_0x138044){return _0x426247!==_0x138044;},'ISBgy':_0x235a47(0x63d),'BDHyI':_0x235a47(0x5eb),'KYkZV':'imthE','ravqN':'KpVbz','rlKMR':function(_0xbc1f4e,_0x37657a,_0x1bfa8f,_0xb9fa58){return _0xbc1f4e(_0x37657a,_0x1bfa8f,_0xb9fa58);},'QhbQw':_0x235a47(0x40d),'CVDdE':'StswJ','rVhNq':_0x235a47(0x74f),'fhVRA':_0x235a47(0x312)};try{const {deviceName:_0x46ea28,locatorName:_0x451cb1,x:_0x2d9308,y:_0x308de5}=_0x327a6e[_0x235a47(0x5a1)];if(!_0x46ea28){const _0x1f95ee={};return _0x1f95ee['success']=![],_0x1f95ee[_0x235a47(0x644)]=_0x354af8['rrVHb'],_0x1f240c[_0x235a47(0x365)](0x190)[_0x235a47(0x169)](_0x1f95ee);}let _0x83523;if(_0x2d9308!==undefined&&_0x354af8['yOGwX'](_0x308de5,undefined)){if(_0x354af8[_0x235a47(0x74a)]===_0x354af8[_0x235a47(0x74a)])_0x83523='tap\x20'+_0x2d9308+','+_0x308de5,console['log']('\x0a🖱️\x20API:\x20Tapping\x20at\x20coordinates\x20('+_0x2d9308+','+_0x308de5+')\x20on\x20device:\x20'+_0x46ea28);else{const _0x56ae02=_0x4ea846[_0x235a47(0x65a)](/Val:([^\s]+)/);if(_0x56ae02)_0x1b24cb[_0x235a47(0x527)]=_0x56ae02[0x1];}}else{if(_0x451cb1){if(_0x354af8[_0x235a47(0x287)](_0x354af8[_0x235a47(0x3d2)],_0x354af8[_0x235a47(0x3e4)]))_0x83523='click\x20\x22'+_0x451cb1+'\x22',console[_0x235a47(0x49e)](_0x235a47(0x603)+_0x451cb1+_0x235a47(0x59d)+_0x46ea28);else{if(kdgbsR[_0x235a47(0x325)](_0x105745[_0x235a47(0x4aa)],_0x4b9e81[_0x235a47(0x717)])){const _0x48f814={};_0x48f814['type']=_0x235a47(0x230),_0x48f814[_0x235a47(0x1a6)]=_0x4a98fc,_0x439de8[_0x235a47(0x475)](_0x21ea5e[_0x235a47(0x2a5)](_0x48f814));}}}else{if(_0x354af8[_0x235a47(0x325)](_0x354af8[_0x235a47(0x3e9)],_0x235a47(0x61b))){const _0x23f51e={'type':_0x354af8[_0x235a47(0x5da)],..._0x3ef8b0};_0x25e4b4[_0x235a47(0x475)](_0x257c08[_0x235a47(0x2a5)](_0x23f51e));}else{const _0x4713e2={};return _0x4713e2[_0x235a47(0x66c)]=![],_0x4713e2[_0x235a47(0x644)]=_0x235a47(0x4b7),_0x1f240c[_0x235a47(0x365)](0x190)[_0x235a47(0x169)](_0x4713e2);}}}const _0x24d37a=await _0x354af8[_0x235a47(0x6c3)](executeCommand,[_0x46ea28],_0x83523,null);if(_0x24d37a[_0x235a47(0x66c)]){const _0x24da23={};_0x24da23[_0x235a47(0x66c)]=!![],_0x24da23['message']=_0x354af8[_0x235a47(0x414)],_0x1f240c['json'](_0x24da23);}else{if(_0x354af8[_0x235a47(0x287)](_0x354af8[_0x235a47(0x525)],_0x235a47(0x737)))_0x2cb70c+=_0x57d0d9[_0x235a47(0x4e4)]();else{const _0x5b192e={};_0x5b192e[_0x235a47(0x66c)]=![],_0x5b192e[_0x235a47(0x644)]=_0x235a47(0x601),_0x1f240c[_0x235a47(0x365)](0x1f4)['json'](_0x5b192e);}}}catch(_0x5af10f){if(_0x354af8[_0x235a47(0x287)](_0x235a47(0x74f),_0x354af8['rVhNq'])){const _0x118723=_0x46555e[_0x235a47(0x240)](_0x59f70d=>_0x59f70d[_0x235a47(0x4b8)]),_0xc91889=_0x21c994(_0x11d55b,kdgbsR[_0x235a47(0x611)]);_0x14f894[_0x235a47(0x49e)]('Using\x20iOS\x20wireless\x20script\x20for:\x20'+_0x118723[_0x235a47(0x4dd)](',\x20')),_0x3df827['push'](kdgbsR['URTMX'](_0x773181,_0x196a00,_0x118723,_0xc91889,_0xe537ca));}else{console['error'](_0x354af8[_0x235a47(0x42f)],_0x5af10f);const _0x4d08b1={};_0x4d08b1[_0x235a47(0x66c)]=![],_0x4d08b1[_0x235a47(0x644)]=_0x5af10f[_0x235a47(0x4f1)],_0x1f240c[_0x235a47(0x365)](0x1f4)[_0x235a47(0x169)](_0x4d08b1);}}});function parseLocatorsOutput(_0x235dfa){const _0x2791d2=_0x320de1,_0x1bea42={'rOfmq':function(_0x45761d,_0x2b4ed6){return _0x45761d(_0x2b4ed6);},'giKCS':function(_0x365f52,_0x3e937a){return _0x365f52>=_0x3e937a;},'TZjhs':'🔍\x20Parsing\x20locators\x20output...','CCmiB':_0x2791d2(0x1ee),'MPKrU':_0x2791d2(0x29f),'ugWwU':function(_0x46b672,_0x212f43){return _0x46b672===_0x212f43;},'Sqgmf':_0x2791d2(0x196),'sobYz':_0x2791d2(0x5d7),'UJhVA':_0x2791d2(0x3bb),'LsOMz':_0x2791d2(0x67e),'RZAtw':function(_0x3dc22b,_0x4ab99b){return _0x3dc22b!==_0x4ab99b;},'VOEKp':_0x2791d2(0x63c),'HjdDL':_0x2791d2(0x3f9),'ktwBb':_0x2791d2(0x384),'JdCtf':_0x2791d2(0x133),'eVSJD':function(_0x4db6c9,_0x45476c){return _0x4db6c9(_0x45476c);},'BBlAR':function(_0x26ebbc,_0x37d5a8){return _0x26ebbc<_0x37d5a8;},'FffYy':_0x2791d2(0xf1),'aZBjq':_0x2791d2(0x5fc),'rWoHL':'Val:','IKVSm':_0x2791d2(0x64f),'PKIwh':_0x2791d2(0x6d3),'bcjLy':_0x2791d2(0x132),'QTxGl':function(_0x29131c,_0x1c6d6d){return _0x29131c!==_0x1c6d6d;},'xluWD':_0x2791d2(0x2ad),'cwGLT':function(_0x4b587d,_0x297425){return _0x4b587d(_0x297425);},'beqCC':function(_0x37ba3d,_0x3d9599){return _0x37ba3d(_0x3d9599);},'jjARq':function(_0xac49d2,_0x26285e){return _0xac49d2(_0x26285e);},'MmROc':_0x2791d2(0x1ca),'JemNH':'✓En','GAqtN':_0x2791d2(0x1b4),'amGTG':'rslMJ','IbdTf':'1|4|2|3|0','aXvcN':function(_0x333252,_0x26180f){return _0x333252(_0x26180f);},'qIJOo':function(_0x5a08d8,_0x1d4fae){return _0x5a08d8(_0x1d4fae);},'QsdIy':function(_0xa5b01f,_0x19f783){return _0xa5b01f!==_0x19f783;},'KDvsV':_0x2791d2(0x60e),'jPViL':'Parsed\x20locator:','IShYL':_0x2791d2(0x188),'GvVFR':_0x2791d2(0x2d9)};logger[_0x2791d2(0x3d0)](_0x1bea42[_0x2791d2(0x32f)]),logger[_0x2791d2(0x3d0)](_0x1bea42['CCmiB'],_0x235dfa?.['length']||0x0);if(!_0x235dfa)return logger[_0x2791d2(0x644)](_0x1bea42['MPKrU']),[];const _0x3f1d74=_0x235dfa[_0x2791d2(0x722)]('\x0a');for(const _0x5501b6 of _0x3f1d74){if(_0x1bea42[_0x2791d2(0x754)](_0x1bea42[_0x2791d2(0x293)],_0x2791d2(0x196))){const _0x16745d=_0x5501b6[_0x2791d2(0x5cf)]();if(_0x16745d[_0x2791d2(0x59e)]('[')||_0x16745d[_0x2791d2(0x59e)]('{'))try{const _0x3827b8=JSON['parse'](_0x16745d);return logger['debug'](_0x1bea42[_0x2791d2(0x20d)],Array[_0x2791d2(0x570)](_0x3827b8)?_0x3827b8[_0x2791d2(0x162)]:_0x1bea42[_0x2791d2(0x56f)]),Array[_0x2791d2(0x570)](_0x3827b8)?_0x3827b8:[];}catch(_0x2f41dc){logger[_0x2791d2(0x3d0)]('⚠️\x20JSON\x20parse\x20failed:',_0x2f41dc[_0x2791d2(0x4f1)]);}}else _0x58772b=_0x3115a9['commands'][_0x2791d2(0x162)];}logger[_0x2791d2(0x3d0)]('📝\x20Fallback\x20to\x20text\x20parsing...');const _0x33052e=[];logger[_0x2791d2(0x3d0)](_0x1bea42[_0x2791d2(0x2fd)],_0x3f1d74[_0x2791d2(0x162)]);for(const _0x1474cb of _0x3f1d74){if(_0x1474cb[_0x2791d2(0x58b)]('📍')&&/^\s*\d+\./[_0x2791d2(0x2b2)](_0x1474cb)){if(_0x1bea42[_0x2791d2(0x152)](_0x1bea42[_0x2791d2(0x6e8)],_0x1bea42[_0x2791d2(0x275)]))try{if(_0x1bea42['RZAtw'](_0x1bea42[_0x2791d2(0x6e6)],_0x1bea42[_0x2791d2(0x3c2)])){const _0xc2bcf6={},_0x23424b=_0x1474cb['match'](/^\s*(\d+)\./);if(_0x23424b)_0xc2bcf6[_0x2791d2(0x505)]=_0x1bea42[_0x2791d2(0x2fb)](parseInt,_0x23424b[0x1]);if(_0x1474cb[_0x2791d2(0x58b)]('│')){const _0x45e28c=_0x1474cb[_0x2791d2(0x722)]('│')[_0x2791d2(0x240)](_0x41dd3a=>_0x41dd3a[_0x2791d2(0x5cf)]()),_0x2cc9b6=_0x45e28c[0x0][_0x2791d2(0x65a)](/📍\s+(.+)/);_0x2cc9b6&&(_0xc2bcf6['name']=_0x2cc9b6[0x1]['trim'](),_0xc2bcf6['text']=_0x2cc9b6[0x1][_0x2791d2(0x5cf)]());const _0xb39759=_0x45e28c[0x1]?_0x45e28c[0x1][_0x2791d2(0x65a)](/\[([^\]]+)\]/):null;if(_0xb39759)_0xc2bcf6[_0x2791d2(0x14d)]=_0xb39759[0x1][_0x2791d2(0x5cf)]();for(let _0x20e736=0x2;_0x1bea42[_0x2791d2(0x104)](_0x20e736,_0x45e28c[_0x2791d2(0x162)]);_0x20e736++){const _0xdd4565=_0x45e28c[_0x20e736];if(_0xdd4565[_0x2791d2(0x58b)](_0x1bea42[_0x2791d2(0x65e)])){if(_0x1bea42[_0x2791d2(0x152)](_0x1bea42['aZBjq'],_0x1bea42[_0x2791d2(0x65d)]))_0x2f5107+=_0x2791d2(0x38a)+_0x8b0f97+'\x0a';else{const _0x24379f=_0xdd4565['match'](/Label:([^\s]+)/);if(_0x24379f)_0xc2bcf6[_0x2791d2(0x3a5)]=_0x24379f[0x1];}}if(_0xdd4565[_0x2791d2(0x58b)](_0x1bea42[_0x2791d2(0x5ac)])){const _0x2985e1=_0xdd4565['match'](/Val:([^\s]+)/);if(_0x2985e1)_0xc2bcf6[_0x2791d2(0x527)]=_0x2985e1[0x1];}if(_0xdd4565[_0x2791d2(0x58b)](_0x1bea42['IKVSm'])){if(_0x1bea42[_0x2791d2(0x152)](_0x1bea42[_0x2791d2(0x615)],_0x1bea42[_0x2791d2(0x239)])){const _0x420924=_0xdd4565[_0x2791d2(0x65a)](/ID:([^\s]+)/);if(_0x420924)_0xc2bcf6[_0x2791d2(0x744)]=_0x420924[0x1];}else{const _0x2b7cfb=_0x215d00[_0x37bc41];let _0x511671;if(_0x2b7cfb[_0x42f999])_0x511671=_0x2b7cfb[_0x5cb7b9];else _0x2b7cfb['common']&&(_0x511671=_0x2b7cfb['common']);if(_0x511671)return _0x535093[_0x2791d2(0x49e)](_0x2791d2(0x270)+_0x2579a9+_0x2791d2(0x4d6)+_0x511671+_0x2791d2(0x714)+_0x2b1f99+')'),_0x2791d2(0x46e)+_0x511671+_0x3e99e7;}}if(_0xdd4565['includes']('@')){const _0xd44bbc=_0xdd4565[_0x2791d2(0x65a)](/@\s*\((\d+),(\d+)\)\s*(\d+)x(\d+)/);if(_0xd44bbc){if(_0x1bea42['QTxGl'](_0x2791d2(0x2ad),_0x1bea42[_0x2791d2(0x49f)])){_0x999239[_0x2791d2(0x49e)]('⚠️\x20\x20Cannot\x20reach\x20'+_0x58e929+_0x2791d2(0x320)+_0x30fabe+_0x2791d2(0x5b8));const _0x3b3f79={};_0x3b3f79[_0x2791d2(0x66c)]=![],_0x3b3f79[_0x2791d2(0x4f1)]=_0x2791d2(0x141)+_0x5b51a0+_0x2791d2(0x320)+_0x2c90b2+_0x2791d2(0x5b8),yoMhkz['rOfmq'](_0x5f4954,_0x3b3f79);}else{const _0x2fb642=_0x2791d2(0x290)['split']('|');let _0x350c79=0x0;while(!![]){switch(_0x2fb642[_0x350c79++]){case'0':_0xc2bcf6['y']=parseInt(_0xd44bbc[0x2]);continue;case'1':_0xc2bcf6[_0x2791d2(0x6b8)]='('+_0xc2bcf6['x']+','+_0xc2bcf6['y']+')\x20'+_0xc2bcf6[_0x2791d2(0x46c)]+'x'+_0xc2bcf6[_0x2791d2(0x2da)];continue;case'2':_0xc2bcf6[_0x2791d2(0x2da)]=_0x1bea42[_0x2791d2(0xeb)](parseInt,_0xd44bbc[0x4]);continue;case'3':_0xc2bcf6[_0x2791d2(0x46c)]=_0x1bea42['beqCC'](parseInt,_0xd44bbc[0x3]);continue;case'4':_0xc2bcf6['x']=_0x1bea42[_0x2791d2(0x27d)](parseInt,_0xd44bbc[0x1]);continue;}break;}}}}if(_0xdd4565['includes'](_0x1bea42[_0x2791d2(0x156)]))_0xc2bcf6[_0x2791d2(0x62e)]=!![];if(_0xdd4565['includes'](_0x1bea42['JemNH']))_0xc2bcf6[_0x2791d2(0x549)]=!![];if(_0xdd4565[_0x2791d2(0x58b)](_0x2791d2(0x646)))_0xc2bcf6[_0x2791d2(0x4af)]=!![];}}else{const _0x45e0d8=_0x1474cb[_0x2791d2(0x65a)](/📍\s+([^\[]+?)(?:\s*\[|\s*Label)/);_0x45e0d8&&(_0x1bea42[_0x2791d2(0x590)]!==_0x1bea42[_0x2791d2(0x562)]?(_0xc2bcf6[_0x2791d2(0x4b8)]=_0x45e0d8[0x1][_0x2791d2(0x5cf)](),_0xc2bcf6[_0x2791d2(0x2a6)]=_0x45e0d8[0x1]['trim']()):_0x1257b5+='COHERE_API_KEY='+_0xf16c9a+'\x0a');const _0x5c01bf=_0x1474cb[_0x2791d2(0x65a)](/\[([^\]]+)\]/);if(_0x5c01bf)_0xc2bcf6['type']=_0x5c01bf[0x1]['trim']();const _0x463f71=_0x1474cb['match'](/Label:([^\s]+?)(?:\s*Val:|\s*@|\s*✓)/);if(_0x463f71)_0xc2bcf6[_0x2791d2(0x3a5)]=_0x463f71[0x1][_0x2791d2(0x5cf)]();const _0x5b4a45=_0x1474cb['match'](/Val:([^\s]+?)(?:\s*@|\s*✓)/);if(_0x5b4a45)_0xc2bcf6[_0x2791d2(0x527)]=_0x5b4a45[0x1][_0x2791d2(0x5cf)]();const _0x5c2a36=_0x1474cb['match'](/@\s*\((\d+),(\d+)\)\s*(\d+)x(\d+)/);if(_0x5c2a36){const _0x4461a7=_0x1bea42['IbdTf']['split']('|');let _0x771595=0x0;while(!![]){switch(_0x4461a7[_0x771595++]){case'0':_0xc2bcf6[_0x2791d2(0x6b8)]='('+_0xc2bcf6['x']+','+_0xc2bcf6['y']+')\x20'+_0xc2bcf6[_0x2791d2(0x46c)]+'x'+_0xc2bcf6['height'];continue;case'1':_0xc2bcf6['x']=_0x1bea42[_0x2791d2(0x6ef)](parseInt,_0x5c2a36[0x1]);continue;case'2':_0xc2bcf6[_0x2791d2(0x46c)]=_0x1bea42[_0x2791d2(0x5a8)](parseInt,_0x5c2a36[0x3]);continue;case'3':_0xc2bcf6[_0x2791d2(0x2da)]=parseInt(_0x5c2a36[0x4]);continue;case'4':_0xc2bcf6['y']=_0x1bea42[_0x2791d2(0x1f5)](parseInt,_0x5c2a36[0x2]);continue;}break;}}const _0x26c646=_0x1474cb[_0x2791d2(0x65a)](/ID:([^\s]+)/);if(_0x26c646)_0xc2bcf6[_0x2791d2(0x744)]=_0x26c646[0x1][_0x2791d2(0x5cf)]();_0xc2bcf6[_0x2791d2(0x62e)]=_0x1474cb[_0x2791d2(0x58b)](_0x2791d2(0x1ca)),_0xc2bcf6['enabled']=_0x1474cb['includes'](_0x1bea42[_0x2791d2(0x14b)]);}if(_0xc2bcf6[_0x2791d2(0x4b8)]||_0xc2bcf6[_0x2791d2(0x3a5)]||_0xc2bcf6[_0x2791d2(0x2a6)]){if(_0x1bea42[_0x2791d2(0x3a8)](_0x1bea42[_0x2791d2(0x139)],_0x1bea42[_0x2791d2(0x139)])){const [_0x3c6965,_0x4055b1]=_0x7ff8d0;if(!_0x3527a2[_0x3c6965])_0xdf41b0[_0x3c6965]={};_0x28f470[_0x3c6965][_0x4055b1]=_0x163761;}else logger[_0x2791d2(0x3d0)](_0x1bea42[_0x2791d2(0x6f1)],_0xc2bcf6),_0x33052e[_0x2791d2(0x507)](_0xc2bcf6);}}else{const _0x109f6a=_0x23a359[_0x2791d2(0x65a)](/^(.+?)\s+-\s+(.+?)$/);return _0x109f6a?{'id':_0x109f6a[0x1][_0x2791d2(0x5cf)](),'name':_0x109f6a[0x2][_0x2791d2(0x5cf)]()}:null;}}catch(_0x303eb7){if(_0x1bea42[_0x2791d2(0x510)]===_0x2791d2(0x466)){const _0x54af48=_0x5d4120[_0x2791d2(0x722)](',')['map'](_0x32edb7=>_0x32edb7['trim']()[_0x2791d2(0x15d)](/"/g,''));return _0x1bea42[_0x2791d2(0x19e)](_0x54af48['length'],0x3)?{'id':_0x54af48[0x0],'name':_0x54af48[0x2]}:null;}else console[_0x2791d2(0x644)](_0x1bea42[_0x2791d2(0x1ea)],_0x1474cb,_0x303eb7);}else _0x8a17dc[_0x2791d2(0x644)]('❌\x20Failed\x20to\x20start\x20xcodebuild:\x20'+_0x225ab9['message']);}}return console['log'](_0x2791d2(0x5a6)+_0x33052e['length']),_0x33052e;}wss['on'](_0x320de1(0x39d),_0x333338=>{const _0x2b2914=_0x320de1,_0x5e152b={'mCVkr':function(_0x549500,_0x1b96cc){return _0x549500!==_0x1b96cc;},'PYutz':_0x2b2914(0x522),'LLAHy':'JLYMD','TFghT':_0x2b2914(0x491),'Qtsie':function(_0x258565,_0x47b1b3){return _0x258565===_0x47b1b3;},'VSXKg':_0x2b2914(0x21c),'nuGTV':function(_0x31f830,_0x167986,_0x368f82,_0x4995cb,_0x23f287){return _0x31f830(_0x167986,_0x368f82,_0x4995cb,_0x23f287);},'hRksa':_0x2b2914(0x4d4),'sgchT':'Screenshot\x20not\x20found','PLOKf':_0x2b2914(0x6cf),'TEpyr':function(_0x12ab31,_0x1c209a){return _0x12ab31!==_0x1c209a;},'asHLs':_0x2b2914(0x604),'wOpgw':'CnChk','WmQGX':function(_0x4d3cc0,_0x13f379){return _0x4d3cc0!==_0x13f379;},'PiryF':_0x2b2914(0x10b),'izDMS':function(_0x55a00d,_0x5f7795){return _0x55a00d===_0x5f7795;},'OfNff':'JmLBw','mxElz':_0x2b2914(0x4a3),'YplfL':function(_0x3f2a30,_0x4abbb8,_0x3d98b8,_0x1629c0){return _0x3f2a30(_0x4abbb8,_0x3d98b8,_0x1629c0);},'zApYw':_0x2b2914(0x672),'Nqxff':_0x2b2914(0x367),'VOjUc':function(_0x394b63,_0x2bed46){return _0x394b63===_0x2bed46;},'LQiZC':_0x2b2914(0x175),'gOWvf':_0x2b2914(0x21d),'HwAko':function(_0x1c2749){return _0x1c2749();},'NElCU':_0x2b2914(0x5aa),'LvTpf':_0x2b2914(0x4fb),'wViTO':_0x2b2914(0x1ec),'RvTSg':_0x2b2914(0x614),'qMeit':'\x0a⏹️\x20\x20Stopping\x20replay...\x0a','WPLSd':_0x2b2914(0x230),'LFcPw':_0x2b2914(0x58c),'ZrjzE':_0x2b2914(0x34c),'dolsi':_0x2b2914(0x1db),'EFZJd':'dxUok','GnAmZ':_0x2b2914(0x72f),'yyphP':'error','Xvejy':function(_0x1d7488,_0x1a026d){return _0x1d7488===_0x1a026d;},'jUQMI':_0x2b2914(0x379),'ScWgf':_0x2b2914(0x272),'rqQGq':_0x2b2914(0x228),'BMrzN':_0x2b2914(0x4f6)};console[_0x2b2914(0x49e)]('New\x20WebSocket\x20connection'),_0x333338['on'](_0x2b2914(0x4f1),async _0x3b8112=>{const _0x444c06=_0x2b2914,_0x42d46d={};_0x42d46d['WzXPc']=_0x444c06(0x491),_0x42d46d['RNrSJ']=_0x5e152b[_0x444c06(0x64d)];const _0x381b75=_0x42d46d;if(_0x5e152b[_0x444c06(0x5e1)](_0x5e152b[_0x444c06(0x3a6)],_0x5e152b[_0x444c06(0x75d)]))try{if(_0x5e152b[_0x444c06(0x763)](_0x444c06(0x3d5),_0x444c06(0x3d5))){_0x27f4fb[_0x444c06(0x644)](_0x444c06(0x571)+_0x5471ee[_0x444c06(0x4f1)]);const _0x106ce0={};_0x106ce0['type']=_0x444c06(0x491),_0x106ce0[_0x444c06(0x644)]=_0x3c5ad2[_0x444c06(0x4f1)],_0x1b027a['send'](_0x2249c9[_0x444c06(0x2a5)](_0x106ce0));}else{const _0x372a57=JSON[_0x444c06(0x652)](_0x3b8112);switch(_0x372a57[_0x444c06(0x14d)]){case _0x5e152b[_0x444c06(0x4d7)]:const {devices:_0x94b631,command:_0x305b58,useAI:_0x41e387,aiProvider:_0x58f90a}=_0x372a57;console['log'](_0x444c06(0x217)),console[_0x444c06(0x49e)](_0x444c06(0xd2)+_0x94b631[_0x444c06(0x4dd)](',\x20')+']'),console['log']('Command:\x20\x22'+_0x305b58+'\x22'),console[_0x444c06(0x49e)](_0x444c06(0x72b)+_0x41e387);if(_0x58f90a)console[_0x444c06(0x49e)]('AI\x20Provider:\x20'+_0x58f90a);let _0x298380=_0x305b58;if(_0x41e387){if(_0x5e152b[_0x444c06(0x61d)](_0x5e152b['OfNff'],_0x5e152b[_0x444c06(0x4ec)])){const _0x274290={};_0x274290['success']=![],_0x274290[_0x444c06(0x644)]=_0x356e82['message'],_0x4b5e4b[_0x444c06(0x365)](0x1f4)[_0x444c06(0x169)](_0x274290);}else try{_0x298380=await _0x5e152b[_0x444c06(0x3f0)](convertNaturalLanguageToCommand,_0x305b58,_0x94b631,_0x58f90a),console[_0x444c06(0x49e)]('✅\x20AI\x20converted\x20command\x20to:\x0a'+_0x298380);const _0xd8507={};_0xd8507[_0x444c06(0x14d)]=_0x5e152b[_0x444c06(0x258)],_0xd8507['original']=_0x305b58,_0xd8507['converted']=_0x298380,_0xd8507[_0x444c06(0x461)]=_0x58f90a||aiManager[_0x444c06(0x461)],_0x333338[_0x444c06(0x475)](JSON[_0x444c06(0x2a5)](_0xd8507));}catch(_0x1d26c6){console['error'](_0x444c06(0x699)+_0x1d26c6['message']);const _0x5cc929={};_0x5cc929['type']=_0x5e152b['Nqxff'],_0x5cc929['error']=_0x1d26c6[_0x444c06(0x4f1)],_0x5cc929[_0x444c06(0x189)]=_0x305b58,_0x333338[_0x444c06(0x475)](JSON[_0x444c06(0x2a5)](_0x5cc929));return;}}else{}const _0x2f7fe9=_0x298380[_0x444c06(0x58b)]('\x0a');if(_0x2f7fe9)_0x5e152b[_0x444c06(0x3f0)](executeCommandsSequentially,_0x94b631,_0x298380,_0x333338)[_0x444c06(0x4cb)](_0x2b2ed4=>{const _0x1eb037=_0x444c06;console['log'](_0x1eb037(0x424));const _0x5497cc={};_0x5497cc[_0x1eb037(0x14d)]='command_complete',_0x5497cc[_0x1eb037(0x34f)]=_0x2b2ed4,_0x333338['send'](JSON[_0x1eb037(0x2a5)](_0x5497cc));})['catch'](_0x4d8a27=>{const _0x1da894=_0x444c06;if(_0x5e152b[_0x1da894(0x322)](_0x5e152b[_0x1da894(0x67b)],_0x5e152b[_0x1da894(0x181)])){console[_0x1da894(0x644)](_0x1da894(0x625)+_0x4d8a27[_0x1da894(0x4f1)]);const _0x3d0e79={};_0x3d0e79['type']=_0x5e152b[_0x1da894(0x41a)],_0x3d0e79['error']=_0x4d8a27['message'],_0x333338[_0x1da894(0x475)](JSON['stringify'](_0x3d0e79));}else _0x12dc9c+=_0x1da894(0x32e)+_0x3cf9a5+'\x0a';});else{if(_0x5e152b[_0x444c06(0x578)](_0x444c06(0x4da),_0x444c06(0x4da)))_0x5e152b[_0x444c06(0x3f0)](executeCommand,_0x94b631,_0x298380,_0x333338)['then'](_0x5cf442=>{const _0x3d2dfd=_0x444c06;if(_0x5e152b[_0x3d2dfd(0x278)](_0x5e152b[_0x3d2dfd(0x740)],_0x3d2dfd(0x4bb))){const _0x240c0d={};_0x240c0d[_0x3d2dfd(0x66c)]=![],_0x240c0d[_0x3d2dfd(0x644)]=_0x5804f3['message'],_0x49707a[_0x3d2dfd(0x365)](0x1f4)['json'](_0x240c0d);}else{isRecording&&_0x5e152b['nuGTV'](recordCommand,_0x94b631,_0x305b58,_0x41e387,_0x298380);const _0x33f3f7={};_0x33f3f7['type']=_0x5e152b[_0x3d2dfd(0x689)],_0x33f3f7[_0x3d2dfd(0x34f)]=_0x5cf442,_0x333338['send'](JSON[_0x3d2dfd(0x2a5)](_0x33f3f7));}})[_0x444c06(0x153)](_0xbaaba2=>{const _0xd7a922=_0x444c06;console[_0xd7a922(0x644)](_0xd7a922(0x571)+_0xbaaba2[_0xd7a922(0x4f1)]);const _0x53927f={};_0x53927f[_0xd7a922(0x14d)]=_0x381b75[_0xd7a922(0x5de)],_0x53927f[_0xd7a922(0x644)]=_0xbaaba2[_0xd7a922(0x4f1)],_0x333338[_0xd7a922(0x475)](JSON[_0xd7a922(0x2a5)](_0x53927f));});else{if(_0x1d1090){const _0x4d41a9={};_0x4d41a9[_0x444c06(0x66c)]=![],_0x4d41a9['error']=_0x5e152b[_0x444c06(0x298)],_0x383ae1['status'](0x194)[_0x444c06(0x169)](_0x4d41a9);}}}break;case _0x444c06(0x1d4):const _0xc3e3ac=await startRecording(_0x372a57[_0x444c06(0x4b8)],_0x372a57[_0x444c06(0x1a6)]),_0x3c1f27={'type':_0x5e152b[_0x444c06(0x339)],..._0xc3e3ac};_0x333338[_0x444c06(0x475)](JSON[_0x444c06(0x2a5)](_0x3c1f27));break;case _0x5e152b[_0x444c06(0x211)]:const _0x3f2440=await _0x5e152b[_0x444c06(0x28d)](stopRecording),_0x833615={'type':_0x5e152b[_0x444c06(0x554)],..._0x3f2440};_0x333338[_0x444c06(0x475)](JSON[_0x444c06(0x2a5)](_0x833615));break;case _0x5e152b['LvTpf']:const {filename:_0x49727f,targetDevices:_0x51563b}=_0x372a57,_0x2f5f9b={};_0x2f5f9b['type']=_0x5e152b[_0x444c06(0x476)],_0x2f5f9b[_0x444c06(0x760)]=_0x444c06(0x1c1)+_0x49727f+'\x0a\x0a',_0x2f5f9b[_0x444c06(0x1a6)]=_0x51563b,_0x333338[_0x444c06(0x475)](JSON[_0x444c06(0x2a5)](_0x2f5f9b)),_0x5e152b['YplfL'](replayRecording,_0x49727f,_0x51563b,_0x333338)['then'](_0x15910c=>{const _0x1bfbdc=_0x444c06,_0x97afc2={'type':_0x1bfbdc(0x10f),..._0x15910c};_0x333338['send'](JSON[_0x1bfbdc(0x2a5)](_0x97afc2));})[_0x444c06(0x153)](_0x231cf3=>{const _0x130c7c=_0x444c06,_0x4cb222={};_0x4cb222[_0x130c7c(0x14d)]=_0x130c7c(0x6cf),_0x4cb222['error']=_0x231cf3[_0x130c7c(0x4f1)],_0x333338['send'](JSON[_0x130c7c(0x2a5)](_0x4cb222));});break;case _0x5e152b[_0x444c06(0x364)]:if(isReplaying){replayAborted=!![];const _0x47f467={};_0x47f467['type']=_0x444c06(0x1ec),_0x47f467[_0x444c06(0x760)]=_0x5e152b[_0x444c06(0x43e)],_0x333338[_0x444c06(0x475)](JSON[_0x444c06(0x2a5)](_0x47f467));}break;case _0x444c06(0x5d1):const _0x32be20=await _0x5e152b[_0x444c06(0x28d)](discoverDevices),_0x46b585={};_0x46b585[_0x444c06(0x14d)]=_0x5e152b[_0x444c06(0x29b)],_0x46b585[_0x444c06(0x1a6)]=_0x32be20,_0x333338[_0x444c06(0x475)](JSON[_0x444c06(0x2a5)](_0x46b585));break;case'get_ai_providers':_0x333338['send'](JSON['stringify']({'type':_0x5e152b[_0x444c06(0x62d)],'providers':aiManager[_0x444c06(0x723)](),'current':aiManager[_0x444c06(0x461)]}));break;case _0x5e152b['ZrjzE']:const _0x4d8987=aiManager[_0x444c06(0x4cd)](_0x372a57[_0x444c06(0x461)]),_0x247cd7={};_0x247cd7[_0x444c06(0x14d)]=_0x5e152b[_0x444c06(0x3b9)],_0x247cd7['success']=_0x4d8987,_0x247cd7[_0x444c06(0x461)]=_0x372a57['provider'],_0x333338[_0x444c06(0x475)](JSON[_0x444c06(0x2a5)](_0x247cd7));break;}}}catch(_0x5181b0){if(_0x5e152b[_0x444c06(0x278)](_0x5e152b[_0x444c06(0x4c6)],_0x5e152b['GnAmZ']))_0x2a7ec5[_0x444c06(0x49e)]('⚠️\x20\x20Existing\x20session\x20invalid,\x20creating\x20new\x20one\x20for\x20'+_0x46f4e5),_0x28e71c[_0x444c06(0x4fe)](_0x265842);else{const _0x46f827={};_0x46f827['type']=_0x5e152b[_0x444c06(0x355)],_0x46f827[_0x444c06(0x4f1)]=_0x5181b0[_0x444c06(0x4f1)],_0x333338[_0x444c06(0x475)](JSON[_0x444c06(0x2a5)](_0x46f827));}}else{const _0x54f6a3={};_0x54f6a3[_0x444c06(0x14d)]=_0x381b75['RNrSJ'],_0x54f6a3[_0x444c06(0x644)]=_0x2086bc[_0x444c06(0x4f1)],_0x53bb2d[_0x444c06(0x475)](_0x44a7a3[_0x444c06(0x2a5)](_0x54f6a3));}}),_0x333338['on'](_0x5e152b[_0x2b2914(0x268)],()=>{const _0x31b58c=_0x2b2914,_0x52cac3={};_0x52cac3[_0x31b58c(0x45d)]='\x0a⏹️\x20\x20Replay\x20aborted\x20by\x20user\x0a',_0x52cac3[_0x31b58c(0x17d)]=_0x5e152b[_0x31b58c(0x476)],_0x52cac3[_0x31b58c(0x5f9)]=_0x31b58c(0x46f);const _0x52fc31=_0x52cac3;if(_0x5e152b[_0x31b58c(0x142)](_0x5e152b[_0x31b58c(0x2b6)],_0x5e152b[_0x31b58c(0x5f1)])){_0x23d71f['log'](jEbUog[_0x31b58c(0x45d)]);if(_0x5f0719){const _0x4f77b8={};_0x4f77b8[_0x31b58c(0x14d)]=jEbUog[_0x31b58c(0x17d)],_0x4f77b8[_0x31b58c(0x760)]=_0x31b58c(0x514),_0x4f77b8[_0x31b58c(0x1a6)]=_0x538463,_0x1cc686[_0x31b58c(0x475)](_0x448413[_0x31b58c(0x2a5)](_0x4f77b8));}_0x14457d=![];throw new _0x2cbfe9(jEbUog['JSfTu']);}else console[_0x31b58c(0x49e)](_0x5e152b[_0x31b58c(0x21b)]);}),discoverDevices()[_0x2b2914(0x4cb)](_0x3cb268=>{const _0x45b750=_0x2b2914,_0x59066e={};_0x59066e[_0x45b750(0x14d)]=_0x5e152b[_0x45b750(0x29b)],_0x59066e[_0x45b750(0x1a6)]=_0x3cb268,_0x333338[_0x45b750(0x475)](JSON[_0x45b750(0x2a5)](_0x59066e));});}),app[_0x320de1(0x70f)](_0x320de1(0x5b4),async(_0x9ac342,_0x3ac88f)=>{const _0x1987ba=_0x320de1,_0x326d8b={'aIRkq':_0x1987ba(0x2bb),'ZYueV':_0x1987ba(0x596),'sKLrt':function(_0x586d6c,_0x54c2f2,_0x10bdb6){return _0x586d6c(_0x54c2f2,_0x10bdb6);},'ygSte':function(_0x1fd4a0,_0x42ea6a){return _0x1fd4a0===_0x42ea6a;},'NAOtW':_0x1987ba(0x264),'AVfyk':_0x1987ba(0x324)},{device:_0x273de6}=_0x9ac342[_0x1987ba(0x5a1)];if(!_0x273de6){const _0x1d1f3a={};return _0x1d1f3a['success']=![],_0x1d1f3a[_0x1987ba(0x644)]=_0x326d8b[_0x1987ba(0x4e2)],_0x3ac88f['status'](0x190)[_0x1987ba(0x169)](_0x1d1f3a);}try{console['log'](_0x1987ba(0x102)+_0x273de6+'...');const _0x5bec91=connectedDevices[_0x1987ba(0x2fa)](_0x4bb77c=>_0x4bb77c[_0x1987ba(0x4b8)]===_0x273de6);if(!_0x5bec91){const _0x46a865={};return _0x46a865[_0x1987ba(0x66c)]=![],_0x46a865[_0x1987ba(0x644)]=_0x326d8b[_0x1987ba(0x35a)],_0x3ac88f['json'](_0x46a865);}const _0x3b40bf=await _0x326d8b[_0x1987ba(0x38b)](installUIAutomator2,_0x5bec91['udid'],_0x273de6);_0x3ac88f[_0x1987ba(0x169)](_0x3b40bf);}catch(_0x2f798c){if(_0x326d8b[_0x1987ba(0x63f)](_0x326d8b[_0x1987ba(0x5e7)],'mTAJd')){const _0x46e2cd=_0x37581e[_0x1987ba(0x4e4)]();_0x41d553+=_0x46e2cd,_0x3c28b8[_0x1987ba(0x3d0)]('['+_0x12a63d[_0x1987ba(0x4b8)]+_0x1987ba(0x1e0)+_0x46e2cd[_0x1987ba(0x5cf)]());}else{console[_0x1987ba(0x644)](_0x326d8b[_0x1987ba(0x4f0)],_0x2f798c[_0x1987ba(0x4f1)]);const _0xb3156d={};_0xb3156d['success']=![],_0xb3156d[_0x1987ba(0x644)]=_0x2f798c['message'],_0xb3156d[_0x1987ba(0x743)]=_0x1987ba(0x520),_0x3ac88f['json'](_0xb3156d);}}}),app[_0x320de1(0x70f)]('/api/recording/start',async(_0x25c9d,_0x5c3059)=>{const _0x4d503c=_0x320de1,_0x2f88b4={'BhluI':function(_0x586664,_0x39db31,_0x530a90){return _0x586664(_0x39db31,_0x530a90);}};try{const {name:_0x1c752b,devices:_0x46b8b8}=_0x25c9d[_0x4d503c(0x5a1)],_0x120e9c=await _0x2f88b4[_0x4d503c(0x430)](startRecording,_0x1c752b,_0x46b8b8);_0x5c3059['json'](_0x120e9c);}catch(_0x1dc21d){const _0x274c58={};_0x274c58['success']=![],_0x274c58['error']=_0x1dc21d['message'],_0x5c3059[_0x4d503c(0x365)](0x1f4)[_0x4d503c(0x169)](_0x274c58);}}),app[_0x320de1(0x70f)]('/api/recording/stop',async(_0x38ea00,_0x546a94)=>{const _0x470c5e=_0x320de1,_0x2df6ff={'wjXRy':function(_0xa85a8d,_0x1d12af){return _0xa85a8d(_0x1d12af);},'LKpHP':function(_0x29bec3,_0x59573e){return _0x29bec3!==_0x59573e;},'rfZgM':_0x470c5e(0x25c),'RHGgE':function(_0x1b983c){return _0x1b983c();},'aWyNs':_0x470c5e(0x18a)};try{if(_0x2df6ff[_0x470c5e(0x69d)](_0x2df6ff['rfZgM'],_0x2df6ff['rfZgM']))({discoverAllDevices:_0x12afb3}=DtpWEZ[_0x470c5e(0x1d2)](_0x4586ac,_0x470c5e(0x6d2)));else{const _0x59376e=await _0x2df6ff[_0x470c5e(0x1b8)](stopRecording);_0x546a94['json'](_0x59376e);}}catch(_0x53396a){if(_0x2df6ff[_0x470c5e(0x69d)](_0x2df6ff[_0x470c5e(0x5ae)],_0x2df6ff[_0x470c5e(0x5ae)])){_0x440f52[_0x470c5e(0x644)]('❌\x20Connect\x20error:',_0x23c094);const _0x35b210={};_0x35b210['success']=![],_0x35b210[_0x470c5e(0x644)]=_0x853b81[_0x470c5e(0x4f1)],_0x4ce3ca[_0x470c5e(0x365)](0x1f4)[_0x470c5e(0x169)](_0x35b210);}else{const _0x114d9f={};_0x114d9f[_0x470c5e(0x66c)]=![],_0x114d9f[_0x470c5e(0x644)]=_0x53396a[_0x470c5e(0x4f1)],_0x546a94[_0x470c5e(0x365)](0x1f4)['json'](_0x114d9f);}}}),app[_0x320de1(0x5af)](_0x320de1(0x4e5),(_0x2b40bc,_0x22b644)=>{const _0x21e7ba=_0x320de1,_0xb77e3e={};_0xb77e3e['isRecording']=isRecording,_0xb77e3e[_0x21e7ba(0x5e6)]=currentRecording,_0x22b644['json'](_0xb77e3e);}),app[_0x320de1(0x5af)](_0x320de1(0x219),async(_0x53a653,_0x403947)=>{const _0x14121e=_0x320de1,_0x595cdc={'StpRx':function(_0x193ebf){return _0x193ebf();}};try{const _0x357c9b=await _0x595cdc['StpRx'](listRecordings),_0x268940={};_0x268940[_0x14121e(0x66c)]=!![],_0x268940[_0x14121e(0x302)]=_0x357c9b,_0x403947[_0x14121e(0x169)](_0x268940);}catch(_0x45249d){const _0x56d820={};_0x56d820[_0x14121e(0x66c)]=![],_0x56d820[_0x14121e(0x644)]=_0x45249d[_0x14121e(0x4f1)],_0x403947[_0x14121e(0x365)](0x1f4)[_0x14121e(0x169)](_0x56d820);}}),app['get'](_0x320de1(0x135),async(_0x49f214,_0x22af84)=>{const _0x3ccbf4=_0x320de1,_0x817ab7={};_0x817ab7[_0x3ccbf4(0x3ae)]=_0x3ccbf4(0x1be);const _0x3eb326=_0x817ab7;try{const _0x3dcee0=await loadRecording(_0x49f214[_0x3ccbf4(0x3a3)][_0x3ccbf4(0x5cc)]),_0x2012ba={};_0x2012ba[_0x3ccbf4(0x66c)]=!![],_0x2012ba[_0x3ccbf4(0x5e6)]=_0x3dcee0,_0x22af84[_0x3ccbf4(0x169)](_0x2012ba);}catch(_0x28f6ac){const _0x25a89f={};_0x25a89f[_0x3ccbf4(0x66c)]=![],_0x25a89f[_0x3ccbf4(0x644)]=_0x3eb326[_0x3ccbf4(0x3ae)],_0x22af84[_0x3ccbf4(0x365)](0x194)[_0x3ccbf4(0x169)](_0x25a89f);}}),app[_0x320de1(0x4fe)](_0x320de1(0x135),async(_0x4eb357,_0x24c80e)=>{const _0x2a8c5c=_0x320de1,_0x4d3026={'RUyDP':function(_0x36a601,_0x57f26d){return _0x36a601(_0x57f26d);}};try{await _0x4d3026[_0x2a8c5c(0x38e)](deleteRecording,_0x4eb357[_0x2a8c5c(0x3a3)][_0x2a8c5c(0x5cc)]);const _0x34ef13={};_0x34ef13[_0x2a8c5c(0x66c)]=!![],_0x24c80e[_0x2a8c5c(0x169)](_0x34ef13);}catch(_0x4091bc){const _0x2c804f={};_0x2c804f['success']=![],_0x2c804f['error']=_0x4091bc[_0x2a8c5c(0x4f1)],_0x24c80e[_0x2a8c5c(0x365)](0x1f4)[_0x2a8c5c(0x169)](_0x2c804f);}}),app[_0x320de1(0x200)](_0x320de1(0x135),async(_0x4b3d71,_0x54e415)=>{const _0x5da671=_0x320de1,_0x3ddc43={};_0x3ddc43[_0x5da671(0x406)]=function(_0x1f2b9f,_0x107c08){return _0x1f2b9f===_0x107c08;},_0x3ddc43['zijHw']='HLqGU',_0x3ddc43[_0x5da671(0x1af)]=_0x5da671(0x1a7);const _0xa4b3d7=_0x3ddc43;try{if(_0xa4b3d7[_0x5da671(0x406)](_0xa4b3d7[_0x5da671(0x488)],_0xa4b3d7['zijHw'])){const {filename:_0x200cf4}=_0x4b3d71[_0x5da671(0x3a3)],_0xed2ee6=_0x4b3d71[_0x5da671(0x5a1)],_0x8d72ff=path['join'](RECORDINGS_DIR,_0x200cf4);await fs[_0x5da671(0x184)](_0x8d72ff,JSON[_0x5da671(0x2a5)](_0xed2ee6,null,0x2));const _0x2fdc3f={};_0x2fdc3f['success']=!![],_0x2fdc3f[_0x5da671(0x5e6)]=_0xed2ee6,_0x54e415[_0x5da671(0x169)](_0x2fdc3f);}else _0x453e38+=_0x3f7cf6[_0x5da671(0x4e4)]();}catch(_0x5ba46f){if(_0xa4b3d7[_0x5da671(0x406)]('vwXjB',_0xa4b3d7['aPipb'])){const _0x56df6d={};_0x56df6d[_0x5da671(0x66c)]=![],_0x56df6d[_0x5da671(0x644)]=_0x5ba46f[_0x5da671(0x4f1)],_0x54e415['status'](0x1f4)[_0x5da671(0x169)](_0x56df6d);}else _0x5d1e4d+=_0xab0818['toString']();}}),app[_0x320de1(0x70f)](_0x320de1(0x255),async(_0x12cb2f,_0x1e66e9)=>{const _0x1566df=_0x320de1,_0x43ad0f={};_0x43ad0f[_0x1566df(0x53f)]='Name\x20and\x20commands\x20required',_0x43ad0f['UNwfv']=_0x1566df(0x4fd),_0x43ad0f['zugId']=_0x1566df(0x5ff);const _0x59cec1=_0x43ad0f;try{const {name:_0x46c539,commands:_0x1d6c24,date:_0x55f548,type:_0x254bd0}=_0x12cb2f[_0x1566df(0x5a1)];if(!_0x46c539||!_0x1d6c24){const _0x535a9e={};return _0x535a9e[_0x1566df(0x66c)]=![],_0x535a9e[_0x1566df(0x644)]=_0x59cec1[_0x1566df(0x53f)],_0x1e66e9['status'](0x190)[_0x1566df(0x169)](_0x535a9e);}const _0x4ad7da=_0x46c539[_0x1566df(0x15d)](/[^a-z0-9_-]/gi,'_'),_0x354ee6=_0x4ad7da+'_'+Date[_0x1566df(0x2b8)]()+'.json',_0x3902db=path[_0x1566df(0x4dd)](RECORDINGS_DIR,_0x354ee6),_0x38d4b5={'name':_0x46c539,'commands':_0x1d6c24,'date':_0x55f548||new Date()[_0x1566df(0x1c4)](),'type':_0x254bd0||_0x59cec1[_0x1566df(0x358)]};await fs[_0x1566df(0x184)](_0x3902db,JSON[_0x1566df(0x2a5)](_0x38d4b5,null,0x2));const _0x1671a8={};_0x1671a8[_0x1566df(0x66c)]=!![],_0x1671a8['filename']=_0x354ee6,_0x1671a8[_0x1566df(0x5e6)]=_0x38d4b5,_0x1e66e9[_0x1566df(0x169)](_0x1671a8);}catch(_0x26f0af){if('BOFVn'===_0x59cec1[_0x1566df(0x4b6)]){console[_0x1566df(0x644)](_0x1566df(0x4c1),_0x26f0af);const _0x202aae={};_0x202aae[_0x1566df(0x66c)]=![],_0x202aae[_0x1566df(0x644)]=_0x26f0af[_0x1566df(0x4f1)],_0x1e66e9[_0x1566df(0x365)](0x1f4)[_0x1566df(0x169)](_0x202aae);}else _0x56bd13[_0x1566df(0x49e)]('⚠️\x20\x20Session\x20creation\x20failed,\x20will\x20be\x20created\x20on\x20first\x20command');}}),app['post']('/api/recording/replay',async(_0x3dcd46,_0x16658b)=>{const _0x3942c2=_0x320de1,_0x593db6={};_0x593db6['mUVfD']=_0x3942c2(0x1ec),_0x593db6[_0x3942c2(0x70a)]=function(_0x20494c,_0x4f5de8){return _0x20494c!==_0x4f5de8;},_0x593db6[_0x3942c2(0x344)]=_0x3942c2(0x557),_0x593db6[_0x3942c2(0x234)]='MjPNO',_0x593db6[_0x3942c2(0x329)]=function(_0x4b6ae7,_0x43f423){return _0x4b6ae7===_0x43f423;},_0x593db6[_0x3942c2(0x17e)]='qWEyr',_0x593db6[_0x3942c2(0x44e)]=_0x3942c2(0x2f2);const _0x4b75d1=_0x593db6;try{if(_0x4b75d1[_0x3942c2(0x70a)](_0x4b75d1['acnyv'],_0x4b75d1[_0x3942c2(0x234)])){const {filename:_0x2bd869,devices:_0x3ccbe1}=_0x3dcd46[_0x3942c2(0x5a1)];if(!_0x2bd869){if(_0x4b75d1[_0x3942c2(0x329)](_0x3942c2(0x637),_0x4b75d1[_0x3942c2(0x17e)])){const _0xef3344={};return _0xef3344['success']=![],_0xef3344[_0x3942c2(0x644)]=_0x3942c2(0x3ee),_0x16658b['status'](0x190)[_0x3942c2(0x169)](_0xef3344);}else{const _0x39ecd9={};_0x39ecd9['success']=![],_0x39ecd9[_0x3942c2(0x644)]=_0xe8794d[_0x3942c2(0x4f1)],_0x5c6b24[_0x3942c2(0x365)](0x1f4)['json'](_0x39ecd9);}}if(!_0x3ccbe1||_0x4b75d1[_0x3942c2(0x329)](_0x3ccbe1[_0x3942c2(0x162)],0x0)){const _0x3714d5={};return _0x3714d5[_0x3942c2(0x66c)]=![],_0x3714d5[_0x3942c2(0x644)]=_0x4b75d1['aCIaE'],_0x16658b[_0x3942c2(0x365)](0x190)['json'](_0x3714d5);}const _0x2b7088={};_0x2b7088['success']=!![],_0x2b7088[_0x3942c2(0x4f1)]=_0x3942c2(0x363),_0x16658b[_0x3942c2(0x169)](_0x2b7088);}else{const _0x23c58d=_0x1bcc47[_0x3942c2(0x4e4)]();_0x33c0e5+=_0x23c58d,_0x5f0aa7[_0x3942c2(0x3d0)]('['+_0x639cfc+']\x20STDOUT:\x20'+_0x23c58d[_0x3942c2(0x5cf)]());if(_0x1b5def){const _0x36d15f={};_0x36d15f[_0x3942c2(0x14d)]=YoIvUH[_0x3942c2(0x5e4)],_0x36d15f['data']='['+_0x3d61bc+']\x20'+_0x23c58d,_0x36d15f['devices']=[_0x2c068f],_0x2a53ca[_0x3942c2(0x475)](_0x4d0562[_0x3942c2(0x2a5)](_0x36d15f));}}}catch(_0x44a2d9){const _0x534da0={};_0x534da0['success']=![],_0x534da0['error']=_0x44a2d9[_0x3942c2(0x4f1)],_0x16658b['status'](0x1f4)['json'](_0x534da0);}}),app[_0x320de1(0x5af)](_0x320de1(0x545),async(_0x31d716,_0x74a797)=>{const _0x5584cd=_0x320de1,_0x40fb6d={'rTiDC':function(_0x178fc0,_0x4ef7da){return _0x178fc0(_0x4ef7da);},'LMfzF':function(_0x5e6608,_0x11880e){return _0x5e6608===_0x11880e;},'MuQpp':_0x5584cd(0x386)};try{const _0x3def63={};_0x3def63[_0x5584cd(0x735)]=!![],await fs[_0x5584cd(0x583)](SCREENSHOTS_DIR,_0x3def63);const _0x1d1a03=await fs['readdir'](SCREENSHOTS_DIR),_0x72e5e6=_0x1d1a03['filter'](_0x386c4a=>_0x386c4a['endsWith'](_0x5584cd(0x6d8)))[_0x5584cd(0x240)](_0x9c757=>{const _0x1b3437=_0x5584cd,_0x39b17e=_0x40fb6d[_0x1b3437(0x25b)](require,'fs')['statSync'](path['join'](SCREENSHOTS_DIR,_0x9c757));return{'filename':_0x9c757,'path':_0x1b3437(0x336)+_0x9c757,'size':_0x39b17e[_0x1b3437(0x1d5)],'timestamp':_0x39b17e[_0x1b3437(0xd6)]['getTime'](),'created':_0x39b17e[_0x1b3437(0xd6)]};})[_0x5584cd(0x161)]((_0x49eebf,_0x2657ac)=>_0x2657ac[_0x5584cd(0x440)]-_0x49eebf[_0x5584cd(0x440)]),_0x416775={};_0x416775[_0x5584cd(0x66c)]=!![],_0x416775[_0x5584cd(0x40c)]=_0x72e5e6,_0x74a797[_0x5584cd(0x169)](_0x416775);}catch(_0x174fa3){if(_0x40fb6d[_0x5584cd(0x6c1)](_0x5584cd(0x386),_0x40fb6d['MuQpp'])){const _0x21a4a9={};_0x21a4a9[_0x5584cd(0x66c)]=![],_0x21a4a9[_0x5584cd(0x644)]=_0x174fa3['message'],_0x74a797[_0x5584cd(0x365)](0x1f4)[_0x5584cd(0x169)](_0x21a4a9);}else return _0x1ab82e;}}),app[_0x320de1(0x5af)]('/api/screenshots/:filename',(_0x38230b,_0x4385eb)=>{const _0x3697e1=_0x320de1,_0x500c70={};_0x500c70[_0x3697e1(0x2f0)]=_0x3697e1(0x191);const _0x4a5af8=_0x500c70,_0x25a474=path[_0x3697e1(0x4dd)](SCREENSHOTS_DIR,_0x38230b[_0x3697e1(0x3a3)]['filename']);_0x4385eb[_0x3697e1(0x3f8)](_0x25a474,_0x11861f=>{const _0x1935c=_0x3697e1;if(_0x11861f){const _0xf89412={};_0xf89412[_0x1935c(0x66c)]=![],_0xf89412[_0x1935c(0x644)]=_0x4a5af8[_0x1935c(0x2f0)],_0x4385eb[_0x1935c(0x365)](0x194)[_0x1935c(0x169)](_0xf89412);}});}),app['delete'](_0x320de1(0x3e1),async(_0x2cbdda,_0x234242)=>{const _0xed06d8=_0x320de1,_0x4f8169={};_0x4f8169[_0xed06d8(0x4a1)]=function(_0x1df5dd,_0x3a0414){return _0x1df5dd===_0x3a0414;},_0x4f8169[_0xed06d8(0x470)]=_0xed06d8(0x226);const _0x26664b=_0x4f8169;try{if(_0x26664b[_0xed06d8(0x4a1)](_0x26664b[_0xed06d8(0x470)],_0x26664b['ciBoK'])){const _0x2c1dc2=path['join'](SCREENSHOTS_DIR,_0x2cbdda[_0xed06d8(0x3a3)][_0xed06d8(0x5cc)]);await fs['unlink'](_0x2c1dc2);const _0x392fac={};_0x392fac[_0xed06d8(0x66c)]=!![],_0x234242['json'](_0x392fac);}else return _0x35f062['error'](_0xed06d8(0x12f),_0x4e6f7a),{};}catch(_0x86ae22){const _0x4fcc30={};_0x4fcc30[_0xed06d8(0x66c)]=![],_0x4fcc30[_0xed06d8(0x644)]=_0x86ae22[_0xed06d8(0x4f1)],_0x234242['status'](0x1f4)[_0xed06d8(0x169)](_0x4fcc30);}}),app['post'](_0x320de1(0x5c1),async(_0x549936,_0x1d2f44)=>{const _0x13320b=_0x320de1,_0x300c60={'TxtVx':'Total:','zyIHS':_0x13320b(0x75b),'Iwavu':function(_0x130e35,_0x3e61ca){return _0x130e35(_0x3e61ca);},'uRwNa':'\x20-\x20','AqWVj':_0x13320b(0x4d2),'MkXdT':function(_0x1c92bf,_0x26e2e6){return _0x1c92bf===_0x26e2e6;},'ljIin':_0x13320b(0x55d),'SiVPV':'rFOCz','rwSeG':_0x13320b(0x2c8),'UEaal':function(_0x5b5bc2,_0x4704b4){return _0x5b5bc2===_0x4704b4;},'MjGXX':_0x13320b(0x2f2),'QZjod':'Replay\x20started','iqfxp':_0x13320b(0x186),'ofIQr':function(_0x313f57,_0x23b1e6){return _0x313f57===_0x23b1e6;},'Xcbra':_0x13320b(0x391),'uBqwk':_0x13320b(0x2f8),'LrfTZ':_0x13320b(0x208),'LbsEF':_0x13320b(0x710),'USlKB':function(_0x17bac5,_0x4ff65f,_0x186f0d){return _0x17bac5(_0x4ff65f,_0x186f0d);},'kuYCR':'utf-8','eHIMR':_0x13320b(0x3b7),'AJnVV':function(_0x4f7da1,_0x27ce95,_0x102615){return _0x4f7da1(_0x27ce95,_0x102615);},'eqTfy':'TTqfu','RGcXl':_0x13320b(0x624),'kimRM':_0x13320b(0x6a1),'HCLTc':_0x13320b(0x5c0)};try{const {devices:_0x5383b6}=_0x549936['body'];if(!_0x5383b6||_0x300c60[_0x13320b(0x10a)](_0x5383b6['length'],0x0)){const _0x264a69={};return _0x264a69[_0x13320b(0x66c)]=![],_0x264a69[_0x13320b(0x644)]=_0x300c60[_0x13320b(0x4b9)],_0x1d2f44[_0x13320b(0x365)](0x190)[_0x13320b(0x169)](_0x264a69);}const _0x21dd45=connectedDevices['filter'](_0x55a8f0=>_0x5383b6['includes'](_0x55a8f0[_0x13320b(0x4b8)])||_0x5383b6[_0x13320b(0x58b)](_0x55a8f0[_0x13320b(0x23d)])||_0x5383b6['includes'](_0x55a8f0[_0x13320b(0x54d)]));if(_0x300c60[_0x13320b(0x490)](_0x21dd45['length'],0x0)){const _0x2f85f8={};return _0x2f85f8[_0x13320b(0x66c)]=![],_0x2f85f8[_0x13320b(0x644)]=_0x300c60[_0x13320b(0x2cc)],_0x1d2f44[_0x13320b(0x365)](0x190)[_0x13320b(0x169)](_0x2f85f8);}const _0x12473c={};for(const _0x165e6a of _0x21dd45){try{if(_0x300c60['uBqwk']!==_0x300c60[_0x13320b(0x434)]){let _0x4169c0=[];if(_0x300c60[_0x13320b(0x10a)](_0x165e6a[_0x13320b(0x5d6)],_0x13320b(0x5a0))){const {execSync:_0x576312}=_0x300c60['Iwavu'](require,_0x300c60[_0x13320b(0x3dd)]),_0x4178b2=_0x165e6a['udid']||_0x165e6a[_0x13320b(0x54d)],_0x4cac9b=_0x300c60['USlKB'](_0x576312,_0x13320b(0x600)+_0x4178b2+_0x13320b(0x356),{'encoding':_0x300c60['kuYCR']});_0x4169c0=_0x4cac9b[_0x13320b(0x722)]('\x0a')[_0x13320b(0x47e)](_0x4ce007=>_0x4ce007[_0x13320b(0x59e)]('package:'))[_0x13320b(0x240)](_0x465708=>_0x465708[_0x13320b(0x15d)]('package:','')['trim']())['filter'](_0x19f94b=>_0x19f94b)['sort']();}else{if(_0x300c60[_0x13320b(0x490)](_0x165e6a['platform'],_0x300c60[_0x13320b(0x2b0)])){const {execSync:_0x36efc7}=require(_0x300c60[_0x13320b(0x3dd)]),_0x154f9b=_0x165e6a[_0x13320b(0x23d)];try{let _0x3a78e0;try{_0x3a78e0=_0x300c60[_0x13320b(0x40e)](_0x36efc7,_0x13320b(0x249)+_0x154f9b+'\x20list\x20--user',{'encoding':_0x300c60[_0x13320b(0x676)],'timeout':0x7530});}catch(_0x2c9372){_0x3a78e0=_0x300c60[_0x13320b(0x71f)](_0x36efc7,_0x13320b(0x249)+_0x154f9b+_0x13320b(0x4fa),{'encoding':_0x300c60[_0x13320b(0x676)],'timeout':0x7530});}_0x4169c0=_0x3a78e0[_0x13320b(0x722)]('\x0a')[_0x13320b(0x47e)](_0x414e94=>{const _0x4d7321=_0x13320b,_0x3d0302=_0x414e94['trim']();return _0x3d0302&&!_0x3d0302['startsWith'](_0x300c60[_0x4d7321(0x563)])&&!_0x3d0302[_0x4d7321(0x59e)](_0x300c60[_0x4d7321(0x341)]);})['map'](_0x39a3dc=>{const _0x30e2a5=_0x13320b,_0xf4accc={'HQLAH':function(_0x2c8086,_0x1f4320){const _0x1fb6b4=_0x8de2;return _0x300c60[_0x1fb6b4(0x31f)](_0x2c8086,_0x1f4320);}};if(_0x39a3dc[_0x30e2a5(0x58b)](_0x300c60['uRwNa'])){if(_0x30e2a5(0x71c)===_0x300c60['AqWVj']){const _0x30f661={};return _0x30f661[_0x30e2a5(0x66c)]=![],_0x30f661[_0x30e2a5(0x644)]=_0x30e2a5(0x2bb),_0x49db08['status'](0x190)['json'](_0x30f661);}else{const _0x2e87bb=_0x39a3dc[_0x30e2a5(0x65a)](/^(.+?)\s+-\s+(.+?)$/);return _0x2e87bb?{'id':_0x2e87bb[0x1]['trim'](),'name':_0x2e87bb[0x2]['trim']()}:null;}}else{if(_0x39a3dc['includes'](',')){if(_0x300c60[_0x30e2a5(0x2ce)](_0x300c60[_0x30e2a5(0x261)],_0x300c60['SiVPV']))_0x606567['x']=_0x31b5f(_0x348804[0x1]),_0x13e49d['y']=eMsPsX[_0x30e2a5(0x1c5)](_0x35c96b,_0x5098f6[0x2]),_0x5f384e[_0x30e2a5(0x46c)]=eMsPsX[_0x30e2a5(0x1c5)](_0x3e56ff,_0x4eb54c[0x3]),_0x4fdc81['height']=eMsPsX[_0x30e2a5(0x1c5)](_0x25b8b2,_0x5c5cf0[0x4]),_0x38010a[_0x30e2a5(0x6b8)]='('+_0x3dff1b['x']+','+_0x272e25['y']+')\x20'+_0x55b45a['width']+'x'+_0x12dfc9[_0x30e2a5(0x2da)];else{const _0x42897b=_0x39a3dc['split'](',')[_0x30e2a5(0x240)](_0x26f6d9=>_0x26f6d9['trim']()['replace'](/"/g,''));return _0x42897b[_0x30e2a5(0x162)]>=0x3?{'id':_0x42897b[0x0],'name':_0x42897b[0x2]}:null;}}else{if(_0x39a3dc[_0x30e2a5(0x65a)](/^[a-zA-Z0-9.-]+$/))return{'id':_0x39a3dc[_0x30e2a5(0x5cf)](),'name':_0x39a3dc[_0x30e2a5(0x5cf)]()};}}return null;})[_0x13320b(0x47e)](_0x9ce5e8=>_0x9ce5e8)[_0x13320b(0x161)]((_0x870d5a,_0x4f1dcf)=>_0x870d5a[_0x13320b(0x4b8)]['localeCompare'](_0x4f1dcf['name']));if(_0x300c60[_0x13320b(0x490)](_0x4169c0[_0x13320b(0x162)],0x0)){if(_0x300c60[_0x13320b(0x56c)]===_0x300c60[_0x13320b(0x216)]){const {AI_PROVIDERS_CONFIG:_0x537701}=ondSjn[_0x13320b(0x31f)](_0x387c82,ondSjn[_0x13320b(0x59a)]),_0x1ec33c={};_0x1ec33c[_0x13320b(0x66c)]=!![],_0x1ec33c['providers']=_0x537701,_0x13f561['json'](_0x1ec33c);}else{const _0x1490bf={};_0x1490bf[_0x13320b(0x644)]=_0x300c60[_0x13320b(0x397)],_0x4169c0=[_0x1490bf];}}}catch(_0x5c6d82){console[_0x13320b(0x644)](_0x300c60[_0x13320b(0x449)],_0x5c6d82['message']);const _0x202b8f={};_0x202b8f[_0x13320b(0x644)]=_0x13320b(0x297)+_0x5c6d82[_0x13320b(0x4f1)],_0x4169c0=[_0x202b8f];}}}_0x12473c[_0x165e6a['name']]={'success':!![],'platform':_0x165e6a[_0x13320b(0x5d6)],'apps':_0x4169c0,'count':Array['isArray'](_0x4169c0)?_0x4169c0[_0x13320b(0x162)]:0x0};}else{const {filename:_0x47dbd0,devices:_0x1b8f65}=_0x20a382[_0x13320b(0x5a1)];if(!_0x47dbd0){const _0x5babfe={};return _0x5babfe[_0x13320b(0x66c)]=![],_0x5babfe[_0x13320b(0x644)]=_0x13320b(0x3ee),_0x2ca10a[_0x13320b(0x365)](0x190)['json'](_0x5babfe);}if(!_0x1b8f65||ondSjn[_0x13320b(0x10a)](_0x1b8f65[_0x13320b(0x162)],0x0)){const _0x12a899={};return _0x12a899[_0x13320b(0x66c)]=![],_0x12a899[_0x13320b(0x644)]=ondSjn['MjGXX'],_0x187ed4['status'](0x190)['json'](_0x12a899);}const _0x39941f={};_0x39941f['success']=!![],_0x39941f['message']=ondSjn[_0x13320b(0x373)],_0xfb3774['json'](_0x39941f);}}catch(_0x286b47){const _0x339581={};_0x339581['success']=![],_0x339581[_0x13320b(0x644)]=_0x286b47[_0x13320b(0x4f1)],_0x12473c[_0x165e6a[_0x13320b(0x4b8)]]=_0x339581;}}const _0x566c87={};_0x566c87[_0x13320b(0x66c)]=!![],_0x566c87['results']=_0x12473c,_0x1d2f44[_0x13320b(0x169)](_0x566c87);}catch(_0x4d45c6){const _0x2da554={};_0x2da554['success']=![],_0x2da554['error']=_0x4d45c6['message'],_0x1d2f44[_0x13320b(0x365)](0x1f4)[_0x13320b(0x169)](_0x2da554);}}),app['post'](_0x320de1(0x251),async(_0x1b8c22,_0x1bc198)=>{const _0x53b303=_0x320de1,_0x5ed18e={'iCtNs':_0x53b303(0x3d3),'yxbYq':'Could\x20not\x20retrieve\x20detailed\x20info','awPKY':_0x53b303(0x6a1),'bwvEF':'Device\x20not\x20found','hHXOI':function(_0x21a87f,_0x5ee081){return _0x21a87f(_0x5ee081);},'omoOL':_0x53b303(0x710),'ONulx':_0x53b303(0x1a5),'Budkh':_0x53b303(0x1f7),'aUjsj':function(_0x534a3d,_0x167fee){return _0x534a3d===_0x167fee;},'eeVrC':_0x53b303(0x5a0),'PjCDS':function(_0x81d93f,_0x39afbc,_0x220e7c){return _0x81d93f(_0x39afbc,_0x220e7c);},'EKnsw':_0x53b303(0x1ef),'dukfD':_0x53b303(0x206),'NOBfm':'ios','mzQuS':'nZolq','YEIDo':function(_0x57f265,_0x3ba483){return _0x57f265!==_0x3ba483;},'zRgvA':_0x53b303(0x700),'VlnmI':'iOS'};try{const {device:_0x13f036,bundleId:_0x3cf02a}=_0x1b8c22[_0x53b303(0x5a1)];if(!_0x13f036||!_0x3cf02a){const _0x1faa34={};return _0x1faa34[_0x53b303(0x66c)]=![],_0x1faa34['error']=_0x53b303(0x2df),_0x1bc198[_0x53b303(0x365)](0x190)['json'](_0x1faa34);}const _0x58ba3a=discoveredDevices['find'](_0x1a3ed5=>_0x1a3ed5[_0x53b303(0x4b8)]===_0x13f036);if(!_0x58ba3a){const _0xe74faa={};return _0xe74faa[_0x53b303(0x66c)]=![],_0xe74faa['error']=_0x5ed18e[_0x53b303(0x6e7)],_0x1bc198[_0x53b303(0x365)](0x194)[_0x53b303(0x169)](_0xe74faa);}const {execSync:_0x291c42}=_0x5ed18e[_0x53b303(0x65f)](require,_0x5ed18e[_0x53b303(0x5d5)]);let _0x2bdd00={};try{if(_0x5ed18e['ONulx']===_0x5ed18e[_0x53b303(0x4a9)])_0x2958c8[_0x53b303(0x49e)](_0x53b303(0x3f4)+_0x169ac3[_0x53b303(0x143)]);else{if(_0x5ed18e[_0x53b303(0x759)](_0x58ba3a[_0x53b303(0x5d6)],_0x5ed18e[_0x53b303(0x1df)])){const _0x31a145=_0x58ba3a[_0x53b303(0x23d)]||_0x58ba3a[_0x53b303(0x54d)];try{const _0x2c7e23={};_0x2c7e23['encoding']=_0x53b303(0x1ef),_0x2c7e23[_0x53b303(0x167)]=0x2710;const _0x3eaabe=_0x5ed18e['PjCDS'](_0x291c42,_0x53b303(0x600)+_0x31a145+_0x53b303(0x33e)+_0x3cf02a+_0x53b303(0x24f),_0x2c7e23),_0x2b000f=_0x3eaabe[_0x53b303(0x65a)](/versionName=([^\s]+)/);_0x2b000f&&(_0x2bdd00[_0x53b303(0x426)]=_0x2b000f[0x1]);}catch(_0x53c2c7){_0x2bdd00[_0x53b303(0x426)]=_0x5ed18e[_0x53b303(0x291)];}try{const _0x394898={};_0x394898['encoding']=_0x5ed18e['EKnsw'],_0x394898[_0x53b303(0x167)]=0x2710;const _0x434eb1=_0x291c42(_0x53b303(0x600)+_0x31a145+_0x53b303(0x33e)+_0x3cf02a+'\x20|\x20grep\x20-A\x201\x20\x22applicationInfo\x22',_0x394898);_0x2bdd00[_0x53b303(0x4b8)]=_0x3cf02a;}catch(_0x136772){_0x2bdd00[_0x53b303(0x4b8)]=_0x3cf02a;}try{const _0x434c82={};_0x434c82[_0x53b303(0x5f0)]=_0x53b303(0x1ef),_0x434c82[_0x53b303(0x167)]=0x2710;const _0x1095b1=_0x291c42(_0x53b303(0x600)+_0x31a145+_0x53b303(0x1cb)+_0x3cf02a,_0x434c82);_0x2bdd00[_0x53b303(0x433)]=_0x1095b1[_0x53b303(0x15d)](_0x53b303(0x441),'')[_0x53b303(0x5cf)]();}catch(_0x528349){_0x2bdd00['path']=_0x53b303(0x3d3);}_0x2bdd00[_0x53b303(0x6dc)]=_0x3cf02a,_0x2bdd00[_0x53b303(0x5d6)]=_0x5ed18e[_0x53b303(0x623)];}else{if(_0x58ba3a[_0x53b303(0x5d6)]===_0x5ed18e[_0x53b303(0x6da)]){if(_0x5ed18e['aUjsj'](_0x5ed18e[_0x53b303(0x4a6)],_0x5ed18e[_0x53b303(0x4a6)])){const _0x4a98f1=_0x58ba3a[_0x53b303(0x23d)];try{const _0x43afc6=_0x5ed18e['PjCDS'](_0x291c42,'ideviceinstaller\x20-u\x20'+_0x4a98f1+_0x53b303(0x4be)+_0x3cf02a+'\x22',{'encoding':_0x5ed18e[_0x53b303(0x639)],'timeout':0x2710}),_0x45a60b=_0x43afc6[_0x53b303(0x722)](',')[_0x53b303(0x240)](_0xf6511e=>_0xf6511e[_0x53b303(0x5cf)]()[_0x53b303(0x15d)](/"/g,''));_0x45a60b[_0x53b303(0x162)]>=0x3?_0x5ed18e['YEIDo'](_0x5ed18e[_0x53b303(0x14a)],_0x5ed18e['zRgvA'])?(_0x1039c9[_0x53b303(0x6dc)]=_0x4c5fc1,_0x4392cd[_0x53b303(0x4b8)]=_0x45e793,_0x7311e2[_0x53b303(0x426)]=_0x5ed18e[_0x53b303(0x291)],_0x169c2b[_0x53b303(0x644)]=_0x5ed18e['yxbYq']):(_0x2bdd00[_0x53b303(0x6dc)]=_0x45a60b[0x0],_0x2bdd00[_0x53b303(0x426)]=_0x45a60b[0x1],_0x2bdd00[_0x53b303(0x4b8)]=_0x45a60b[0x2]):(_0x2bdd00['bundleId']=_0x3cf02a,_0x2bdd00[_0x53b303(0x4b8)]=_0x3cf02a,_0x2bdd00[_0x53b303(0x426)]='Unknown');}catch(_0x2fba5c){_0x2bdd00[_0x53b303(0x6dc)]=_0x3cf02a,_0x2bdd00[_0x53b303(0x4b8)]=_0x3cf02a,_0x2bdd00[_0x53b303(0x426)]=_0x5ed18e[_0x53b303(0x291)],_0x2bdd00[_0x53b303(0x644)]=_0x53b303(0x502);}_0x2bdd00['platform']=_0x5ed18e['VlnmI'];}else{const _0x1db73c={};_0x1db73c[_0x53b303(0x644)]=LZKvLF[_0x53b303(0x3ad)],_0x43529c=[_0x1db73c];}}}const _0x3f1c15={};_0x3f1c15[_0x53b303(0x66c)]=!![],_0x3f1c15[_0x53b303(0x5ca)]=_0x2bdd00,_0x1bc198[_0x53b303(0x169)](_0x3f1c15);}}catch(_0x4a933e){const _0x58208e={};_0x58208e[_0x53b303(0x6dc)]=_0x3cf02a,_0x58208e[_0x53b303(0x5d6)]=_0x58ba3a['platform'],_0x58208e[_0x53b303(0x644)]=_0x53b303(0x725);const _0x4f265e={};_0x4f265e[_0x53b303(0x66c)]=![],_0x4f265e[_0x53b303(0x644)]=_0x4a933e[_0x53b303(0x4f1)],_0x4f265e[_0x53b303(0x5ca)]=_0x58208e,_0x1bc198[_0x53b303(0x169)](_0x4f265e);}}catch(_0x131e87){const _0x1e597c={};_0x1e597c[_0x53b303(0x66c)]=![],_0x1e597c[_0x53b303(0x644)]=_0x131e87[_0x53b303(0x4f1)],_0x1bc198[_0x53b303(0x365)](0x1f4)[_0x53b303(0x169)](_0x1e597c);}});let server;function startServer(_0x519023={}){const _0x56018a=_0x320de1,_0x1bab9a={'xLSTR':function(_0x29a002,_0xd7ba4){return _0x29a002(_0xd7ba4);},'iPvoM':_0x56018a(0x483),'ArpuD':function(_0x485bba){return _0x485bba();},'iZsdl':_0x56018a(0x332),'PiKQl':function(_0x51f5fa,_0x36edd0){return _0x51f5fa!==_0x36edd0;},'koHkk':_0x56018a(0x6aa),'mYwAi':_0x56018a(0x3ed),'tVlaR':function(_0x1e3352){return _0x1e3352();},'axhkv':_0x56018a(0x48b),'oqiHJ':'connection','gscUw':function(_0x2e94f5,_0x1f85d5){return _0x2e94f5&&_0x1f85d5;},'mJuCj':function(_0x56ff98,_0x3ec5a7){return _0x56ff98===_0x3ec5a7;},'TnngH':_0x56018a(0x3fa),'fqlGR':function(_0x10ff0e,_0x1ca564){return _0x10ff0e!==_0x1ca564;},'EPRVh':'4|3|1|2|0','tgtxK':function(_0x18f637,_0x1b9f62){return _0x18f637(_0x1b9f62);},'Tiaex':function(_0xb5f97c,_0x2aa526){return _0xb5f97c!==_0x2aa526;},'isJTu':'Uitfk','Sknya':_0x56018a(0x4f8),'LXxZH':_0x56018a(0x644),'fWnMg':function(_0x56fc04,_0x28d6a3){return _0x56fc04!==_0x28d6a3;},'lQuzF':_0x56018a(0x2e6)},_0x4c0186=_0x519023[_0x56018a(0x2cf)]||PORT,_0x17ab36=_0x1bab9a[_0x56018a(0x415)](_0x519023['browser'],![]),_0x12ed36=_0x1bab9a['lQuzF'];return console[_0x56018a(0x49e)](_0x56018a(0x30e)+_0x12ed36+'\x0a'),new Promise((_0x277599,_0x10a4c5)=>{const _0x696a75=_0x56018a,_0x279d6a={'SgWRP':_0x1bab9a['axhkv'],'RLkjk':function(_0x1c5ad7){return _0x1c5ad7();},'MRDnt':_0x1bab9a[_0x696a75(0x751)],'ZxEIK':function(_0x433c7d,_0x47264f){const _0x5cc4a4=_0x696a75;return _0x1bab9a[_0x5cc4a4(0x4fc)](_0x433c7d,_0x47264f);},'FBnPj':function(_0x5e5df9,_0x52da14){const _0x3a92a9=_0x696a75;return _0x1bab9a[_0x3a92a9(0x6a6)](_0x5e5df9,_0x52da14);},'IFhzi':_0x1bab9a['TnngH'],'YjFTm':function(_0x50972a,_0xbab7fa){const _0x5850cf=_0x696a75;return _0x1bab9a[_0x5850cf(0x59c)](_0x50972a,_0xbab7fa);},'ISUYo':_0x696a75(0x202),'gLbmD':_0x1bab9a['EPRVh'],'IdThF':function(_0x8d0968,_0x206cc){const _0x11a51b=_0x696a75;return _0x1bab9a[_0x11a51b(0x20f)](_0x8d0968,_0x206cc);}};if(_0x1bab9a[_0x696a75(0x72e)](_0x1bab9a[_0x696a75(0x4b0)],_0x696a75(0x3c8)))server=app[_0x696a75(0x403)](_0x4c0186,()=>{const _0xabb6f6=_0x696a75,_0x493105={'MUiJm':function(_0x2277a6,_0x4d0a04){return _0x1bab9a['xLSTR'](_0x2277a6,_0x4d0a04);},'zhFKo':_0x1bab9a[_0xabb6f6(0x5dd)],'RrpZJ':function(_0x204721){return _0x1bab9a['ArpuD'](_0x204721);},'ArLRc':_0x1bab9a['iZsdl']};if(_0x1bab9a[_0xabb6f6(0x543)](_0x1bab9a[_0xabb6f6(0x3ac)],_0x1bab9a[_0xabb6f6(0x2c3)]))console[_0xabb6f6(0x49e)](_0xabb6f6(0x3aa)+_0x4c0186),console[_0xabb6f6(0x49e)]('✅\x20WebSocket\x20server\x20ready'),_0x1bab9a[_0xabb6f6(0x2cb)](discoverDevices)[_0xabb6f6(0x4cb)](_0xb16b36=>{const _0x3cbfc2=_0xabb6f6;console['log'](_0x3cbfc2(0x199)+_0xb16b36[_0x3cbfc2(0x162)]+_0x3cbfc2(0x736));if(_0x17ab36){console['log'](_0x3cbfc2(0x670)+_0x12ed36+_0x3cbfc2(0x57b));const _0xa37d8e=_0x493105['MUiJm'](require,_0x493105['zhFKo']);_0x493105[_0x3cbfc2(0x542)](_0xa37d8e,_0x12ed36)[_0x3cbfc2(0x153)](_0xd0c366=>{const _0x533295=_0x3cbfc2;console['log']('\x0a📱\x20Please\x20open\x20'+_0x12ed36+_0x533295(0x69e));});}_0x493105['RrpZJ'](_0x277599);})['catch'](_0x5103d3=>{const _0x17da22=_0xabb6f6;if('UXNng'!==_0x17da22(0x523)){_0x2bf169['log'](_0x17da22(0x48f)+_0x1da1b9+_0x17da22(0x173));const _0x563e84={};_0x563e84['success']=!![],_0x563e84[_0x17da22(0x4f1)]=_0x17da22(0x594)+_0x534409+_0x17da22(0x1ed),_0x563e84[_0x17da22(0x294)]=!![],YPxkgX['MUiJm'](_0x33c986,_0x563e84);}else logger[_0x17da22(0x644)](_0x279d6a[_0x17da22(0x5f7)],_0x5103d3[_0x17da22(0x4f1)]),_0x279d6a['RLkjk'](_0x277599);});else try{const _0x40a536=_0x52f63c[_0xabb6f6(0x652)](_0x3a3f2d);return _0xd4ae72[_0xabb6f6(0x3d0)]('✅\x20Parsed\x20as\x20JSON,\x20elements:',_0x3d58f2[_0xabb6f6(0x570)](_0x40a536)?_0x40a536[_0xabb6f6(0x162)]:'not\x20array'),_0x331d67[_0xabb6f6(0x570)](_0x40a536)?_0x40a536:[];}catch(_0x1c955b){_0x31d126[_0xabb6f6(0x3d0)](YPxkgX['ArLRc'],_0x1c955b[_0xabb6f6(0x4f1)]);}}),server['on'](_0x1bab9a[_0x696a75(0x66b)],(_0x378b34,_0x1e8300,_0x47cddb)=>{wss['handleUpgrade'](_0x378b34,_0x1e8300,_0x47cddb,_0x498d76=>{const _0xb48dd8=_0x8de2;wss[_0xb48dd8(0x4c0)](_0x279d6a[_0xb48dd8(0x127)],_0x498d76,_0x378b34);});}),server['on'](_0x1bab9a[_0x696a75(0x28a)],_0x21df3b=>{const _0x1298f0=_0x696a75;if(_0x279d6a['FBnPj'](_0x21df3b[_0x1298f0(0x493)],_0x279d6a[_0x1298f0(0x24d)])){if(_0x279d6a[_0x1298f0(0x400)](_0x279d6a[_0x1298f0(0x241)],_0x1298f0(0x202))){const [_0x24ec04,_0x2b04f9]=_0x4ffbb3[_0x1298f0(0x722)](',')[_0x1298f0(0x240)](_0x419b58=>_0x419b58[_0x1298f0(0x5cf)]());if(rSphZv[_0x1298f0(0x36f)](_0x24ec04,_0x2b04f9)){const _0x48a0fc=_0x24ec04[_0x1298f0(0x722)]('.');if(rSphZv[_0x1298f0(0x705)](_0x48a0fc[_0x1298f0(0x162)],0x2)){const [_0x141b59,_0x18759f]=_0x48a0fc;if(!_0x5a8375[_0x141b59])_0x13dbbe[_0x141b59]={};_0x4ed460[_0x141b59][_0x18759f]=_0x2b04f9;}else{if(!_0x3178eb[_0x24ec04])_0x5372c1[_0x24ec04]={};_0x8a37c0[_0x24ec04][_0x1298f0(0x372)]=_0x2b04f9;}}}else{const _0x370eea=_0x279d6a[_0x1298f0(0x6a8)][_0x1298f0(0x722)]('|');let _0x2f8178=0x0;while(!![]){switch(_0x370eea[_0x2f8178++]){case'0':logger[_0x1298f0(0x644)](_0x1298f0(0x5c4));continue;case'1':logger[_0x1298f0(0x644)]('\x20\x201.\x20Kill\x20the\x20process\x20using\x20port\x20'+_0x4c0186+':\x20lsof\x20-ti:'+_0x4c0186+'\x20|\x20xargs\x20kill\x20-9');continue;case'2':logger[_0x1298f0(0x644)](_0x1298f0(0x627));continue;case'3':logger['error'](_0x1298f0(0x345));continue;case'4':logger[_0x1298f0(0x644)]('\x0a❌\x20Port\x20'+_0x4c0186+_0x1298f0(0x377));continue;}break;}}}_0x279d6a['IdThF'](_0x10a4c5,_0x21df3b);});else{_0x180e87[_0x696a75(0x644)]('Error\x20deleting\x20recording\x20'+_0x246dd5+':',_0xb7204a);throw _0x54c8c0;}});}function stopServer(){const _0x393ef3={'pkMrC':function(_0x32362f){return _0x32362f();}};return new Promise(_0x2c575d=>{const _0xf0afa=_0x8de2;server?server[_0xf0afa(0x4f6)](_0x2c575d):_0x393ef3[_0xf0afa(0x14c)](_0x2c575d);});}const _0x2993ba={};_0x2993ba[_0x320de1(0x42c)]=startServer,_0x2993ba[_0x320de1(0x465)]=stopServer,module['exports']=_0x2993ba;require[_0x320de1(0x489)]===module&&startServer()[_0x320de1(0x153)](_0x36a52f=>{const _0x10a1a7=_0x320de1,_0x421d62={};_0x421d62['MxfTC']=function(_0x852b05,_0x207266){return _0x852b05===_0x207266;},_0x421d62[_0x10a1a7(0x1d1)]=_0x10a1a7(0x3fa),_0x421d62[_0x10a1a7(0x5e2)]=function(_0x3681d7,_0x4e3291){return _0x3681d7===_0x4e3291;},_0x421d62[_0x10a1a7(0x463)]='zcbzz',_0x421d62['kUHFz']=_0x10a1a7(0xd8),_0x421d62[_0x10a1a7(0x469)]=function(_0x3f1031,_0x2e0650){return _0x3f1031===_0x2e0650;},_0x421d62[_0x10a1a7(0x5c3)]=_0x10a1a7(0x1f9);const _0x4f984a=_0x421d62;if(_0x36a52f['code']===_0x4f984a['mPYsR']){if(_0x4f984a[_0x10a1a7(0x5e2)](_0x4f984a['AhdHO'],_0x4f984a[_0x10a1a7(0x2c6)])){const _0x2c4582={};_0x2c4582['IIgKX']=function(_0x37c748,_0x341bdd){return _0x37c748===_0x341bdd;};const _0x515768=_0x2c4582;_0xaccce9[_0xcd8488]['status']=_0x10a1a7(0x4e6),_0x194c8c['clients']['forEach'](_0x23afa=>{const _0x554668=_0x10a1a7;if(_0x515768['IIgKX'](_0x23afa['readyState'],_0x1d400a['OPEN'])){const _0x1ea136={};_0x1ea136['type']=_0x554668(0x230),_0x1ea136[_0x554668(0x1a6)]=_0x38448e,_0x23afa[_0x554668(0x475)](_0x4f193d[_0x554668(0x2a5)](_0x1ea136));}});}else logger[_0x10a1a7(0x644)](_0x10a1a7(0x640)),logger[_0x10a1a7(0x644)](_0x10a1a7(0x345)),logger[_0x10a1a7(0x644)](_0x10a1a7(0x37d)),logger[_0x10a1a7(0x644)](_0x10a1a7(0x627)),logger[_0x10a1a7(0x644)]('\x20\x20\x20\x20\x20Note:\x20Vercel\x20frontend\x20connects\x20to\x20port\x203001\x20by\x20default'),logger[_0x10a1a7(0x644)]('\x20\x203.\x20Use\x20local\x20frontend\x20at\x20http://localhost:3001\x0a');}else{if(_0x4f984a[_0x10a1a7(0x469)](_0x10a1a7(0x605),_0x10a1a7(0x605)))console['error'](_0x4f984a['fUiBd'],_0x36a52f[_0x10a1a7(0x4f1)]);else{const _0xbe610c=_0x5d368a[_0x10a1a7(0x722)]('.');if(iERWPo['MxfTC'](_0xbe610c[_0x10a1a7(0x162)],0x2)){const [_0x252747,_0x55f37a]=_0xbe610c;if(!_0x13d41c[_0x252747])_0x448fe0[_0x252747]={};_0x47ca71[_0x252747][_0x55f37a]=_0x5ca01c;}else{if(!_0x2decac[_0xe4963c])_0xf3a988[_0x52110b]={};_0x46ac60[_0x395155]['common']=_0x542b94;}}}process[_0x10a1a7(0x3b2)](0x1);});
|