autoglm-gui 0.4.8__py3-none-any.whl → 0.4.11__py3-none-any.whl
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.
- AutoGLM_GUI/__init__.py +43 -0
- AutoGLM_GUI/__main__.py +63 -15
- AutoGLM_GUI/adb_plus/__init__.py +2 -0
- AutoGLM_GUI/adb_plus/keyboard_installer.py +380 -0
- AutoGLM_GUI/api/agents.py +123 -1
- AutoGLM_GUI/api/media.py +39 -44
- AutoGLM_GUI/config_manager.py +124 -0
- AutoGLM_GUI/logger.py +85 -0
- AutoGLM_GUI/platform_utils.py +43 -0
- AutoGLM_GUI/resources/apks/ADBKeyBoard.LICENSE.txt +339 -0
- AutoGLM_GUI/resources/apks/ADBKeyBoard.README.txt +1 -0
- AutoGLM_GUI/resources/apks/ADBKeyboard.apk +0 -0
- AutoGLM_GUI/schemas.py +17 -0
- AutoGLM_GUI/scrcpy_stream.py +58 -118
- AutoGLM_GUI/state.py +2 -1
- AutoGLM_GUI/static/assets/{about-BI6OV6gm.js → about-wSo3UgQ-.js} +1 -1
- AutoGLM_GUI/static/assets/chat-BcY2K0yj.js +25 -0
- AutoGLM_GUI/static/assets/{index-Do7ha9Kf.js → index-B5u1xtK1.js} +1 -1
- AutoGLM_GUI/static/assets/index-CHrYo3Qj.css +1 -0
- AutoGLM_GUI/static/assets/{index-Dn3vR6uV.js → index-D5BALRbT.js} +5 -5
- AutoGLM_GUI/static/index.html +2 -2
- {autoglm_gui-0.4.8.dist-info → autoglm_gui-0.4.11.dist-info}/METADATA +17 -2
- autoglm_gui-0.4.11.dist-info/RECORD +52 -0
- AutoGLM_GUI/static/assets/chat-C_2Cot0q.js +0 -25
- AutoGLM_GUI/static/assets/index-DCrxTz-A.css +0 -1
- autoglm_gui-0.4.8.dist-info/RECORD +0 -45
- {autoglm_gui-0.4.8.dist-info → autoglm_gui-0.4.11.dist-info}/WHEEL +0 -0
- {autoglm_gui-0.4.8.dist-info → autoglm_gui-0.4.11.dist-info}/entry_points.txt +0 -0
- {autoglm_gui-0.4.8.dist-info → autoglm_gui-0.4.11.dist-info}/licenses/LICENSE +0 -0
AutoGLM_GUI/scrcpy_stream.py
CHANGED
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import os
|
|
5
|
-
import platform
|
|
6
5
|
import socket
|
|
7
6
|
import subprocess
|
|
8
7
|
from pathlib import Path
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from AutoGLM_GUI.logger import logger
|
|
11
|
+
from AutoGLM_GUI.platform_utils import is_windows, run_cmd_silently, spawn_process
|
|
9
12
|
|
|
10
13
|
|
|
11
14
|
class ScrcpyStreamer:
|
|
@@ -34,7 +37,7 @@ class ScrcpyStreamer:
|
|
|
34
37
|
self.port = port
|
|
35
38
|
self.idr_interval_s = idr_interval_s
|
|
36
39
|
|
|
37
|
-
self.scrcpy_process:
|
|
40
|
+
self.scrcpy_process: Any | None = None
|
|
38
41
|
self.tcp_socket: socket.socket | None = None
|
|
39
42
|
self.forward_cleanup_needed = False
|
|
40
43
|
|
|
@@ -59,13 +62,13 @@ class ScrcpyStreamer:
|
|
|
59
62
|
project_root = Path(__file__).parent.parent
|
|
60
63
|
project_server = project_root / "scrcpy-server-v3.3.3"
|
|
61
64
|
if project_server.exists():
|
|
62
|
-
|
|
65
|
+
logger.info(f"Using project scrcpy-server: {project_server}")
|
|
63
66
|
return str(project_server)
|
|
64
67
|
|
|
65
68
|
# Priority 2: Environment variable
|
|
66
69
|
scrcpy_server = os.getenv("SCRCPY_SERVER_PATH")
|
|
67
70
|
if scrcpy_server and os.path.exists(scrcpy_server):
|
|
68
|
-
|
|
71
|
+
logger.info(f"Using env scrcpy-server: {scrcpy_server}")
|
|
69
72
|
return scrcpy_server
|
|
70
73
|
|
|
71
74
|
# Priority 3: Common system locations
|
|
@@ -77,7 +80,7 @@ class ScrcpyStreamer:
|
|
|
77
80
|
|
|
78
81
|
for path in paths:
|
|
79
82
|
if os.path.exists(path):
|
|
80
|
-
|
|
83
|
+
logger.info(f"Using system scrcpy-server: {path}")
|
|
81
84
|
return path
|
|
82
85
|
|
|
83
86
|
raise FileNotFoundError(
|
|
@@ -88,35 +91,32 @@ class ScrcpyStreamer:
|
|
|
88
91
|
"""Start scrcpy server and establish connection."""
|
|
89
92
|
# Clear NAL reading buffer to ensure clean state
|
|
90
93
|
self._nal_read_buffer.clear()
|
|
91
|
-
|
|
94
|
+
logger.debug("Cleared NAL read buffer")
|
|
92
95
|
|
|
93
96
|
try:
|
|
94
97
|
# 0. Kill existing scrcpy server processes on device
|
|
95
|
-
|
|
98
|
+
logger.info("Cleaning up existing scrcpy processes...")
|
|
96
99
|
await self._cleanup_existing_server()
|
|
97
100
|
|
|
98
101
|
# 1. Push scrcpy-server to device
|
|
99
|
-
|
|
102
|
+
logger.info("Pushing server to device...")
|
|
100
103
|
await self._push_server()
|
|
101
104
|
|
|
102
105
|
# 2. Setup port forwarding
|
|
103
|
-
|
|
106
|
+
logger.info(f"Setting up port forwarding on port {self.port}...")
|
|
104
107
|
await self._setup_port_forward()
|
|
105
108
|
|
|
106
109
|
# 3. Start scrcpy server
|
|
107
|
-
|
|
110
|
+
logger.info("Starting scrcpy server...")
|
|
108
111
|
await self._start_server()
|
|
109
112
|
|
|
110
113
|
# 4. Connect TCP socket
|
|
111
|
-
|
|
114
|
+
logger.info("Connecting to TCP socket...")
|
|
112
115
|
await self._connect_socket()
|
|
113
|
-
|
|
116
|
+
logger.info("Successfully connected!")
|
|
114
117
|
|
|
115
118
|
except Exception as e:
|
|
116
|
-
|
|
117
|
-
import traceback
|
|
118
|
-
|
|
119
|
-
traceback.print_exc()
|
|
119
|
+
logger.exception(f"Failed to start: {e}")
|
|
120
120
|
self.stop()
|
|
121
121
|
raise RuntimeError(f"Failed to start scrcpy server: {e}") from e
|
|
122
122
|
|
|
@@ -126,53 +126,23 @@ class ScrcpyStreamer:
|
|
|
126
126
|
if self.device_id:
|
|
127
127
|
cmd_base.extend(["-s", self.device_id])
|
|
128
128
|
|
|
129
|
-
#
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
# Method 1: Try pkill
|
|
133
|
-
cmd = cmd_base + ["shell", "pkill", "-9", "-f", "app_process.*scrcpy"]
|
|
134
|
-
subprocess.run(cmd, capture_output=True, check=False)
|
|
129
|
+
# Method 1: Try pkill
|
|
130
|
+
cmd = cmd_base + ["shell", "pkill", "-9", "-f", "app_process.*scrcpy"]
|
|
131
|
+
await run_cmd_silently(cmd)
|
|
135
132
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
# Method 3: Remove port forward if exists
|
|
144
|
-
cmd_remove_forward = cmd_base + ["forward", "--remove", f"tcp:{self.port}"]
|
|
145
|
-
subprocess.run(cmd_remove_forward, capture_output=True, check=False)
|
|
146
|
-
else:
|
|
147
|
-
# Original asyncio-based implementation for Unix systems
|
|
148
|
-
# Method 1: Try pkill
|
|
149
|
-
cmd = cmd_base + ["shell", "pkill", "-9", "-f", "app_process.*scrcpy"]
|
|
150
|
-
process = await asyncio.create_subprocess_exec(
|
|
151
|
-
*cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
|
152
|
-
)
|
|
153
|
-
await process.wait()
|
|
133
|
+
# Method 2: Find and kill by PID (more reliable)
|
|
134
|
+
cmd = cmd_base + [
|
|
135
|
+
"shell",
|
|
136
|
+
"ps -ef | grep 'app_process.*scrcpy' | grep -v grep | awk '{print $2}' | xargs kill -9",
|
|
137
|
+
]
|
|
138
|
+
await run_cmd_silently(cmd)
|
|
154
139
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
"ps -ef | grep 'app_process.*scrcpy' | grep -v grep | awk '{print $2}' | xargs kill -9",
|
|
159
|
-
]
|
|
160
|
-
process = await asyncio.create_subprocess_exec(
|
|
161
|
-
*cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
|
162
|
-
)
|
|
163
|
-
await process.wait()
|
|
164
|
-
|
|
165
|
-
# Method 3: Remove port forward if exists
|
|
166
|
-
cmd_remove_forward = cmd_base + ["forward", "--remove", f"tcp:{self.port}"]
|
|
167
|
-
process = await asyncio.create_subprocess_exec(
|
|
168
|
-
*cmd_remove_forward,
|
|
169
|
-
stdout=subprocess.DEVNULL,
|
|
170
|
-
stderr=subprocess.DEVNULL,
|
|
171
|
-
)
|
|
172
|
-
await process.wait()
|
|
140
|
+
# Method 3: Remove port forward if exists
|
|
141
|
+
cmd_remove_forward = cmd_base + ["forward", "--remove", f"tcp:{self.port}"]
|
|
142
|
+
await run_cmd_silently(cmd_remove_forward)
|
|
173
143
|
|
|
174
144
|
# Wait longer for resources to be released
|
|
175
|
-
|
|
145
|
+
logger.debug("Waiting for cleanup to complete...")
|
|
176
146
|
await asyncio.sleep(2)
|
|
177
147
|
|
|
178
148
|
async def _push_server(self) -> None:
|
|
@@ -182,13 +152,7 @@ class ScrcpyStreamer:
|
|
|
182
152
|
cmd.extend(["-s", self.device_id])
|
|
183
153
|
cmd.extend(["push", self.scrcpy_server_path, "/data/local/tmp/scrcpy-server"])
|
|
184
154
|
|
|
185
|
-
|
|
186
|
-
subprocess.run(cmd, capture_output=True, check=False)
|
|
187
|
-
else:
|
|
188
|
-
process = await asyncio.create_subprocess_exec(
|
|
189
|
-
*cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
|
190
|
-
)
|
|
191
|
-
await process.wait()
|
|
155
|
+
await run_cmd_silently(cmd)
|
|
192
156
|
|
|
193
157
|
async def _setup_port_forward(self) -> None:
|
|
194
158
|
"""Setup ADB port forwarding."""
|
|
@@ -197,13 +161,7 @@ class ScrcpyStreamer:
|
|
|
197
161
|
cmd.extend(["-s", self.device_id])
|
|
198
162
|
cmd.extend(["forward", f"tcp:{self.port}", "localabstract:scrcpy"])
|
|
199
163
|
|
|
200
|
-
|
|
201
|
-
subprocess.run(cmd, capture_output=True, check=False)
|
|
202
|
-
else:
|
|
203
|
-
process = await asyncio.create_subprocess_exec(
|
|
204
|
-
*cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
|
205
|
-
)
|
|
206
|
-
await process.wait()
|
|
164
|
+
await run_cmd_silently(cmd)
|
|
207
165
|
self.forward_cleanup_needed = True
|
|
208
166
|
|
|
209
167
|
async def _start_server(self) -> None:
|
|
@@ -238,22 +196,14 @@ class ScrcpyStreamer:
|
|
|
238
196
|
cmd.extend(server_args)
|
|
239
197
|
|
|
240
198
|
# Capture stderr to see error messages
|
|
241
|
-
|
|
242
|
-
# On Windows, use subprocess.Popen for async-like behavior
|
|
243
|
-
self.scrcpy_process = subprocess.Popen(
|
|
244
|
-
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
|
245
|
-
)
|
|
246
|
-
else:
|
|
247
|
-
self.scrcpy_process = await asyncio.create_subprocess_exec(
|
|
248
|
-
*cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
|
249
|
-
)
|
|
199
|
+
self.scrcpy_process = await spawn_process(cmd, capture_output=True)
|
|
250
200
|
|
|
251
201
|
# Wait for server to start
|
|
252
202
|
await asyncio.sleep(2)
|
|
253
203
|
|
|
254
204
|
# Check if process is still running
|
|
255
205
|
error_msg = None
|
|
256
|
-
if
|
|
206
|
+
if is_windows():
|
|
257
207
|
# For Windows Popen, check returncode directly
|
|
258
208
|
if self.scrcpy_process.poll() is not None:
|
|
259
209
|
# Process has exited
|
|
@@ -270,8 +220,8 @@ class ScrcpyStreamer:
|
|
|
270
220
|
# Check if it's an "Address already in use" error
|
|
271
221
|
if "Address already in use" in error_msg:
|
|
272
222
|
if attempt < max_retries - 1:
|
|
273
|
-
|
|
274
|
-
f"
|
|
223
|
+
logger.warning(
|
|
224
|
+
f"Address in use, retrying in {retry_delay}s (attempt {attempt + 1}/{max_retries})..."
|
|
275
225
|
)
|
|
276
226
|
await self._cleanup_existing_server()
|
|
277
227
|
await asyncio.sleep(retry_delay)
|
|
@@ -299,9 +249,9 @@ class ScrcpyStreamer:
|
|
|
299
249
|
self.tcp_socket.setsockopt(
|
|
300
250
|
socket.SOL_SOCKET, socket.SO_RCVBUF, 2 * 1024 * 1024
|
|
301
251
|
) # 2MB
|
|
302
|
-
|
|
252
|
+
logger.debug("Set socket receive buffer to 2MB")
|
|
303
253
|
except OSError as e:
|
|
304
|
-
|
|
254
|
+
logger.warning(f"Failed to set socket buffer size: {e}")
|
|
305
255
|
|
|
306
256
|
# Retry connection
|
|
307
257
|
for _ in range(5):
|
|
@@ -314,9 +264,7 @@ class ScrcpyStreamer:
|
|
|
314
264
|
|
|
315
265
|
raise ConnectionError("Failed to connect to scrcpy server")
|
|
316
266
|
|
|
317
|
-
def _find_nal_units(
|
|
318
|
-
self, data: bytes
|
|
319
|
-
) -> list[tuple[int, int, int, bool]]:
|
|
267
|
+
def _find_nal_units(self, data: bytes) -> list[tuple[int, int, int, bool]]:
|
|
320
268
|
"""Find NAL units in H.264 data.
|
|
321
269
|
|
|
322
270
|
Returns:
|
|
@@ -388,13 +336,11 @@ class ScrcpyStreamer:
|
|
|
388
336
|
hex_preview = " ".join(
|
|
389
337
|
f"{b:02x}" for b in nal_data[: min(12, len(nal_data))]
|
|
390
338
|
)
|
|
391
|
-
|
|
392
|
-
f"
|
|
339
|
+
logger.debug(
|
|
340
|
+
f"✓ Cached SPS ({size} bytes, complete={is_complete}): {hex_preview}..."
|
|
393
341
|
)
|
|
394
342
|
elif size < 10:
|
|
395
|
-
|
|
396
|
-
f"[ScrcpyStreamer] ✗ Skipped short SPS ({size} bytes)"
|
|
397
|
-
)
|
|
343
|
+
logger.debug(f"✗ Skipped short SPS ({size} bytes)")
|
|
398
344
|
|
|
399
345
|
elif nal_type == 8: # PPS
|
|
400
346
|
# Only cache PPS if not yet locked
|
|
@@ -405,13 +351,11 @@ class ScrcpyStreamer:
|
|
|
405
351
|
hex_preview = " ".join(
|
|
406
352
|
f"{b:02x}" for b in nal_data[: min(12, len(nal_data))]
|
|
407
353
|
)
|
|
408
|
-
|
|
409
|
-
f"
|
|
354
|
+
logger.debug(
|
|
355
|
+
f"✓ Cached PPS ({size} bytes, complete={is_complete}): {hex_preview}..."
|
|
410
356
|
)
|
|
411
357
|
elif size < 6:
|
|
412
|
-
|
|
413
|
-
f"[ScrcpyStreamer] ✗ Skipped short PPS ({size} bytes)"
|
|
414
|
-
)
|
|
358
|
+
logger.debug(f"✗ Skipped short PPS ({size} bytes)")
|
|
415
359
|
|
|
416
360
|
elif nal_type == 5: # IDR frame
|
|
417
361
|
# Cache IDR if it's large enough (size check is sufficient)
|
|
@@ -422,19 +366,17 @@ class ScrcpyStreamer:
|
|
|
422
366
|
is_first = self.cached_idr is None
|
|
423
367
|
self.cached_idr = nal_data
|
|
424
368
|
if is_first:
|
|
425
|
-
|
|
426
|
-
f"[ScrcpyStreamer] ✓ Cached IDR frame ({size} bytes)"
|
|
427
|
-
)
|
|
369
|
+
logger.debug(f"✓ Cached IDR frame ({size} bytes)")
|
|
428
370
|
# Don't log every IDR update (too verbose)
|
|
429
371
|
elif size < 1024:
|
|
430
|
-
|
|
431
|
-
f"
|
|
372
|
+
logger.debug(
|
|
373
|
+
f"✗ Skipped small IDR ({size} bytes, likely incomplete)"
|
|
432
374
|
)
|
|
433
375
|
|
|
434
376
|
# Lock SPS/PPS once we have complete initial parameters
|
|
435
377
|
if self.cached_sps and self.cached_pps and not self.sps_pps_locked:
|
|
436
378
|
self.sps_pps_locked = True
|
|
437
|
-
|
|
379
|
+
logger.debug("🔒 SPS/PPS locked (IDR will continue updating)")
|
|
438
380
|
|
|
439
381
|
def get_initialization_data(self) -> bytes | None:
|
|
440
382
|
"""Get cached SPS/PPS/IDR for initializing new connections.
|
|
@@ -449,18 +391,18 @@ class ScrcpyStreamer:
|
|
|
449
391
|
init_data += self.cached_idr
|
|
450
392
|
|
|
451
393
|
# Validate data integrity
|
|
452
|
-
|
|
453
|
-
|
|
394
|
+
logger.debug("Returning init data:")
|
|
395
|
+
logger.debug(
|
|
454
396
|
f" - SPS: {len(self.cached_sps)} bytes, starts with {' '.join(f'{b:02x}' for b in self.cached_sps[:8])}"
|
|
455
397
|
)
|
|
456
|
-
|
|
398
|
+
logger.debug(
|
|
457
399
|
f" - PPS: {len(self.cached_pps)} bytes, starts with {' '.join(f'{b:02x}' for b in self.cached_pps[:8])}"
|
|
458
400
|
)
|
|
459
401
|
if self.cached_idr:
|
|
460
|
-
|
|
402
|
+
logger.debug(
|
|
461
403
|
f" - IDR: {len(self.cached_idr)} bytes, starts with {' '.join(f'{b:02x}' for b in self.cached_idr[:8])}"
|
|
462
404
|
)
|
|
463
|
-
|
|
405
|
+
logger.debug(f" - Total: {len(init_data)} bytes")
|
|
464
406
|
|
|
465
407
|
return init_data
|
|
466
408
|
return None
|
|
@@ -491,9 +433,7 @@ class ScrcpyStreamer:
|
|
|
491
433
|
|
|
492
434
|
# Log large chunks (might indicate complex frames)
|
|
493
435
|
if len(data) > 200 * 1024: # > 200KB
|
|
494
|
-
|
|
495
|
-
f"[ScrcpyStreamer] Large chunk received: {len(data) / 1024:.1f} KB"
|
|
496
|
-
)
|
|
436
|
+
logger.debug(f"Large chunk received: {len(data) / 1024:.1f} KB")
|
|
497
437
|
|
|
498
438
|
# Optionally cache SPS/PPS/IDR from this chunk
|
|
499
439
|
if auto_cache:
|
|
@@ -508,8 +448,8 @@ class ScrcpyStreamer:
|
|
|
508
448
|
except ConnectionError:
|
|
509
449
|
raise
|
|
510
450
|
except Exception as e:
|
|
511
|
-
|
|
512
|
-
f"
|
|
451
|
+
logger.error(
|
|
452
|
+
f"Unexpected error in read_h264_chunk: {type(e).__name__}: {e}"
|
|
513
453
|
)
|
|
514
454
|
raise ConnectionError(f"Failed to read from socket: {e}") from e
|
|
515
455
|
|
|
@@ -588,8 +528,8 @@ class ScrcpyStreamer:
|
|
|
588
528
|
except ConnectionError:
|
|
589
529
|
raise
|
|
590
530
|
except Exception as e:
|
|
591
|
-
|
|
592
|
-
f"
|
|
531
|
+
logger.error(
|
|
532
|
+
f"Unexpected error in read_nal_unit: {type(e).__name__}: {e}"
|
|
593
533
|
)
|
|
594
534
|
raise ConnectionError(f"Failed to read from socket: {e}") from e
|
|
595
535
|
|
AutoGLM_GUI/state.py
CHANGED
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import asyncio
|
|
6
6
|
from typing import TYPE_CHECKING
|
|
7
7
|
|
|
8
|
+
from AutoGLM_GUI.logger import logger
|
|
8
9
|
from phone_agent.agent import AgentConfig
|
|
9
10
|
from phone_agent.model import ModelConfig
|
|
10
11
|
|
|
@@ -24,4 +25,4 @@ scrcpy_locks: dict[str, asyncio.Lock] = {}
|
|
|
24
25
|
|
|
25
26
|
def non_blocking_takeover(message: str) -> None:
|
|
26
27
|
"""Log takeover requests without blocking for console input."""
|
|
27
|
-
|
|
28
|
+
logger.warning(f"Takeover requested: {message}")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as o}from"./index-
|
|
1
|
+
import{j as o}from"./index-D5BALRbT.js";function t(){return o.jsx("div",{className:"p-2",children:o.jsx("h3",{children:"About"})})}export{t as component};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import{j as l,r as p,g as Ie,a as Oe,s as Pe,b as Ne,c as $e,d as Ue,e as He,f as ze,i as Ye,h as Ve,k as We,l as Xe,m as Ge,n as Ke}from"./index-D5BALRbT.js";function Je({id:g,model:oe,status:P,isInitialized:N,isActive:C,onClick:$}){const L=P==="device";return l.jsx("button",{onClick:$,className:`w-full text-left px-4 py-3 rounded-lg transition-all duration-500 ease-[cubic-bezier(0.4,0.0,0.2,1)] h-12 shrink-0 ${C?"bg-blue-500 text-white shadow-md":"bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700"}`,children:l.jsxs("div",{className:"flex items-center justify-between gap-2",children:[l.jsxs("div",{className:"flex items-center gap-3 min-w-0 flex-1",children:[l.jsx("div",{className:`w-2.5 h-2.5 rounded-full flex-shrink-0 ${L?"bg-green-400 shadow-[0_0_4px_rgba(74,222,128,0.6)]":"bg-gray-400"}`,title:L?"在线":"离线"}),l.jsxs("div",{className:"min-w-0 flex-1",children:[l.jsx("div",{className:`font-medium text-sm truncate ${C?"text-white":"text-gray-900 dark:text-gray-100"}`,children:oe||"未知设备"}),l.jsx("div",{className:`text-xs truncate ${C?"text-blue-100":"text-gray-500 dark:text-gray-400"}`,children:g})]})]}),N&&l.jsx("div",{className:`flex-shrink-0 w-5 h-5 rounded-full flex items-center justify-center ${C?"bg-white/20":"bg-green-100 dark:bg-green-900"}`,children:l.jsx("svg",{className:`w-3 h-3 ${C?"text-white":"text-green-600 dark:text-green-400"}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})})})]})})}const qe=()=>{try{const g=localStorage.getItem("sidebar-collapsed");return g!==null?JSON.parse(g):!1}catch(g){return console.warn("Failed to load sidebar collapsed state:",g),!1}};function Ze({devices:g,currentDeviceId:oe,onSelectDevice:P,onOpenConfig:N}){const[C,$]=p.useState(qe);p.useEffect(()=>{localStorage.setItem("sidebar-collapsed",JSON.stringify(C))},[C]),p.useEffect(()=>{const w=H=>{(H.metaKey||H.ctrlKey)&&H.key==="b"&&(H.preventDefault(),$(!C))};return window.addEventListener("keydown",w),()=>window.removeEventListener("keydown",w)},[C]);const L=()=>{$(!C)};return l.jsxs(l.Fragment,{children:[C&&l.jsx("button",{onClick:L,className:"fixed left-0 top-20 w-8 h-16 bg-blue-500 hover:bg-blue-600 text-white rounded-r-full shadow-lg transition-all duration-300 z-50 flex items-center justify-center",title:"展开侧边栏",children:l.jsx("svg",{className:"w-4 h-4 transition-transform duration-300",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9 5l7 7-7 7"})})}),l.jsxs("div",{className:`${C?"w-0 -ml-8":"w-64"} transition-all duration-500 ease-[cubic-bezier(0.4,0.0,0.2,1)] h-full min-h-0 bg-gray-50 dark:bg-gray-900 border-r border-gray-200 dark:border-gray-700 flex flex-col overflow-hidden`,children:[l.jsxs("div",{className:"border-b border-gray-200 dark:border-gray-700 flex items-center justify-between p-4 whitespace-nowrap",children:[l.jsxs("div",{children:[l.jsxs("h2",{className:"text-lg font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2",children:[l.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"})}),"设备列表"]}),l.jsxs("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:["共 ",g.length," 个设备"]})]}),l.jsx("button",{onClick:L,className:"p-1.5 hover:bg-gray-200 dark:hover:bg-gray-700 rounded transition-all duration-300 ease-[cubic-bezier(0.4,0.0,0.2,1)]",title:"收缩侧边栏",children:l.jsx("svg",{className:"w-4 h-4 text-gray-500 dark:text-gray-400 transition-transform duration-500 ease-[cubic-bezier(0.4,0.0,0.2,1)]",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})})})]}),l.jsx("div",{className:"flex-1 overflow-y-auto p-3 space-y-2 min-h-0",children:g.length===0?l.jsxs("div",{className:"text-center py-8 text-gray-500 dark:text-gray-400",children:[l.jsx("svg",{className:"w-12 h-12 mx-auto mb-2 opacity-50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"})}),l.jsx("p",{className:"text-sm",children:"未检测到设备"}),l.jsx("p",{className:"text-xs mt-1",children:"请连接 ADB 设备"})]}):g.map(w=>l.jsx(Je,{id:w.id,model:w.model,status:w.status,isInitialized:w.is_initialized,isActive:w.id===oe,onClick:()=>P(w.id)},w.id))}),l.jsx("div",{className:"p-3 border-t border-gray-200 dark:border-gray-700 space-y-2 whitespace-nowrap",children:l.jsxs("button",{onClick:N,className:"w-full px-4 py-2 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-lg transition-all duration-500 ease-[cubic-bezier(0.4,0.0,0.2,1)] font-medium text-gray-700 dark:text-gray-300 flex items-center justify-center gap-2",children:[l.jsxs("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:[l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"}),l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"})]}),"全局配置"]})})]})]})}var Ce={exports:{}};const Qe={},et=Object.freeze(Object.defineProperty({__proto__:null,default:Qe},Symbol.toStringTag,{value:"Module"})),tt=Ie(et);var rt=Ce.exports,Te;function nt(){return Te||(Te=1,(function(g,oe){(function(P,N){g.exports=N(tt)})(rt,(function(P){function N(r,a){(a==null||a>r.length)&&(a=r.length);for(var e=0,t=Array(a);e<a;e++)t[e]=r[e];return t}function C(r){if(Array.isArray(r))return r}function $(r){if(Array.isArray(r))return N(r)}function L(r){if(r===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return r}function w(r,a){if(!(r instanceof a))throw new TypeError("Cannot call a class as a function")}function H(r,a){for(var e=0;e<a.length;e++){var t=a[e];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(r,me(t.key),t)}}function U(r,a,e){return a&&H(r.prototype,a),e&&H(r,e),Object.defineProperty(r,"prototype",{writable:!1}),r}function x(r,a){var e=typeof Symbol<"u"&&r[Symbol.iterator]||r["@@iterator"];if(!e){if(Array.isArray(r)||(e=I(r))||a){e&&(r=e);var t=0,n=function(){};return{s:n,n:function(){return t>=r.length?{done:!0}:{done:!1,value:r[t++]}},e:function(c){throw c},f:n}}throw new TypeError(`Invalid attempt to iterate non-iterable instance.
|
|
2
|
+
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var i,s=!0,o=!1;return{s:function(){e=e.call(r)},n:function(){var c=e.next();return s=c.done,c},e:function(c){o=!0,i=c},f:function(){try{s||e.return==null||e.return()}finally{if(o)throw i}}}}function D(r){var a=M();return function(){var e,t=_(r);if(a){var n=_(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return re(this,e)}}function S(r,a,e){return(a=me(a))in r?Object.defineProperty(r,a,{value:e,enumerable:!0,configurable:!0,writable:!0}):r[a]=e,r}function _(r){return _=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(a){return a.__proto__||Object.getPrototypeOf(a)},_(r)}function k(r,a){if(typeof a!="function"&&a!==null)throw new TypeError("Super expression must either be null or a function");r.prototype=Object.create(a&&a.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),Object.defineProperty(r,"prototype",{writable:!1}),a&&ce(r,a)}function M(){try{var r=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch{}return(M=function(){return!!r})()}function ge(r){if(typeof Symbol<"u"&&r[Symbol.iterator]!=null||r["@@iterator"]!=null)return Array.from(r)}function he(r,a){var e=r==null?null:typeof Symbol<"u"&&r[Symbol.iterator]||r["@@iterator"];if(e!=null){var t,n,i,s,o=[],c=!0,u=!1;try{if(i=(e=e.call(r)).next,a!==0)for(;!(c=(t=i.call(e)).done)&&(o.push(t.value),o.length!==a);c=!0);}catch(d){u=!0,n=d}finally{try{if(!c&&e.return!=null&&(s=e.return(),Object(s)!==s))return}finally{if(u)throw n}}return o}}function Z(){throw new TypeError(`Invalid attempt to destructure non-iterable instance.
|
|
3
|
+
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function le(){throw new TypeError(`Invalid attempt to spread non-iterable instance.
|
|
4
|
+
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function re(r,a){if(a&&(typeof a=="object"||typeof a=="function"))return a;if(a!==void 0)throw new TypeError("Derived constructors may only return object or undefined");return L(r)}function ce(r,a){return ce=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},ce(r,a)}function ie(r,a){return C(r)||he(r,a)||I(r,a)||Z()}function A(r){return $(r)||ge(r)||I(r)||le()}function V(r,a){if(typeof r!="object"||!r)return r;var e=r[Symbol.toPrimitive];if(e!==void 0){var t=e.call(r,a);if(typeof t!="object")return t;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(r)}function me(r){var a=V(r,"string");return typeof a=="symbol"?a:a+""}function W(r){"@babel/helpers - typeof";return W=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(a){return typeof a}:function(a){return a&&typeof Symbol=="function"&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},W(r)}function I(r,a){if(r){if(typeof r=="string")return N(r,a);var e={}.toString.call(r).slice(8,-1);return e==="Object"&&r.constructor&&(e=r.constructor.name),e==="Map"||e==="Set"?Array.from(r):e==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?N(r,a):void 0}}var ae,ne;function G(r,a){ae=r,ne=a}function b(r){if(ae){for(var a=arguments.length,e=new Array(a>1?a-1:0),t=1;t<a;t++)e[t-1]=arguments[t];ae.apply(void 0,[r].concat(e))}}function K(r){if(ne){for(var a=arguments.length,e=new Array(a>1?a-1:0),t=1;t<a;t++)e[t-1]=arguments[t];ne.apply(void 0,[r].concat(e))}}var ue=(function(){function r(a){w(this,r),this.listener={},this.type=a|""}return U(r,[{key:"on",value:function(e,t){return this.listener[e]||(this.listener[e]=[]),this.listener[e].push(t),!0}},{key:"off",value:function(e,t){if(this.listener[e]){var n=this.listener[e].indexOf(t);return n>-1&&this.listener[e].splice(n,1),!0}return!1}},{key:"offAll",value:function(){this.listener={}}},{key:"dispatch",value:function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),i=1;i<t;i++)n[i-1]=arguments[i];return this.listener[e]?(this.listener[e].map(function(s){s.apply(null,n)}),!0):!1}}]),r})(),xe=(function(){function r(){w(this,r)}return U(r,null,[{key:"init",value:function(){r.types={avc1:[],avcC:[],btrt:[],dinf:[],dref:[],esds:[],ftyp:[],hdlr:[],hev1:[],hvcC:[],mdat:[],mdhd:[],mdia:[],mfhd:[],minf:[],moof:[],moov:[],mp4a:[],mvex:[],mvhd:[],sdtp:[],stbl:[],stco:[],stsc:[],stsd:[],stsz:[],stts:[],tfdt:[],tfhd:[],traf:[],trak:[],trun:[],trex:[],tkhd:[],vmhd:[],smhd:[]};var e;for(e in r.types)r.types.hasOwnProperty(e)&&(r.types[e]=[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]);var t=new Uint8Array([0,0,0,0,0,0,0,0,118,105,100,101,0,0,0,0,0,0,0,0,0,0,0,0,86,105,100,101,111,72,97,110,100,108,101,114,0]),n=new Uint8Array([0,0,0,0,0,0,0,0,115,111,117,110,0,0,0,0,0,0,0,0,0,0,0,0,83,111,117,110,100,72,97,110,100,108,101,114,0]);r.HDLR_TYPES={video:t,audio:n};var i=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,12,117,114,108,32,0,0,0,1]),s=new Uint8Array([0,0,0,0,0,0,0,0]);r.STTS=r.STSC=r.STCO=s,r.STSZ=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0]),r.VMHD=new Uint8Array([0,0,0,1,0,0,0,0,0,0,0,0]),r.SMHD=new Uint8Array([0,0,0,0,0,0,0,0]),r.STSD=new Uint8Array([0,0,0,0,0,0,0,1]);var o=new Uint8Array([105,115,111,109]),c=new Uint8Array([97,118,99,49]),u=new Uint8Array([0,0,0,1]);r.FTYP=r.box(r.types.ftyp,o,u,o,c),r.DINF=r.box(r.types.dinf,r.box(r.types.dref,i))}},{key:"box",value:function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),i=1;i<t;i++)n[i-1]=arguments[i];for(var s=8,o=n.length,c=o,u;o--;)s+=n[o].byteLength;for(u=new Uint8Array(s),u[0]=s>>24&255,u[1]=s>>16&255,u[2]=s>>8&255,u[3]=s&255,u.set(e,4),o=0,s=8;o<c;++o)u.set(n[o],s),s+=n[o].byteLength;return u}},{key:"hdlr",value:function(e){return r.box(r.types.hdlr,r.HDLR_TYPES[e])}},{key:"mdat",value:function(e){return r.box(r.types.mdat,e)}},{key:"mdhd",value:function(e,t){return r.box(r.types.mdhd,new Uint8Array([0,0,0,0,0,0,0,2,0,0,0,3,e>>24&255,e>>16&255,e>>8&255,e&255,t>>>24&255,t>>>16&255,t>>>8&255,t&255,85,196,0,0]))}},{key:"mdia",value:function(e){return r.box(r.types.mdia,r.mdhd(e.timescale,e.duration),r.hdlr(e.type),r.minf(e))}},{key:"mfhd",value:function(e){return r.box(r.types.mfhd,new Uint8Array([0,0,0,0,e>>24,e>>16&255,e>>8&255,e&255]))}},{key:"minf",value:function(e){return e.type==="audio"?r.box(r.types.minf,r.box(r.types.smhd,r.SMHD),r.DINF,r.stbl(e)):r.box(r.types.minf,r.box(r.types.vmhd,r.VMHD),r.DINF,r.stbl(e))}},{key:"moof",value:function(e,t,n){return r.box(r.types.moof,r.mfhd(e),r.traf(n,t))}},{key:"moov",value:function(e,t,n){for(var i=e.length,s=[];i--;)s[i]=r.trak(e[i]);return r.box.apply(null,[r.types.moov,r.mvhd(n,t)].concat(s).concat(r.mvex(e)))}},{key:"mvex",value:function(e){for(var t=e.length,n=[];t--;)n[t]=r.trex(e[t]);return r.box.apply(null,[r.types.mvex].concat(n))}},{key:"mvhd",value:function(e,t){var n=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,2,e>>24&255,e>>16&255,e>>8&255,e&255,t>>>24&255,t>>>16&255,t>>>8&255,t&255,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255]);return r.box(r.types.mvhd,n)}},{key:"sdtp",value:function(e){var t=e.samples||[],n=new Uint8Array(4+t.length),i,s;for(s=0;s<t.length;s++)i=t[s].flags,n[s+4]=i.dependsOn<<4|i.isDependedOn<<2|i.hasRedundancy;return r.box(r.types.sdtp,n)}},{key:"stbl",value:function(e){return r.box(r.types.stbl,r.stsd(e),r.box(r.types.stts,r.STTS),r.box(r.types.stsc,r.STSC),r.box(r.types.stsz,r.STSZ),r.box(r.types.stco,r.STCO))}},{key:"avc1",value:function(e){var t=[],n=[],i,s,o;for(i=0;i<e.sps.length;i++)s=e.sps[i],o=s.byteLength,t.push(o>>>8&255),t.push(o&255),t=t.concat(Array.prototype.slice.call(s));for(i=0;i<e.pps.length;i++)s=e.pps[i],o=s.byteLength,n.push(o>>>8&255),n.push(o&255),n=n.concat(Array.prototype.slice.call(s));var c=r.box(r.types.avcC,new Uint8Array([1,t[3],t[4],t[5],255,224|e.sps.length].concat(t).concat([e.pps.length]).concat(n))),u=e.width,d=e.height;return r.box(r.types.avc1,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,u>>8&255,u&255,d>>8&255,d&255,0,72,0,0,0,72,0,0,0,0,0,0,0,1,18,98,105,110,101,108,112,114,111,46,114,117,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,17,17]),c,r.box(r.types.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192])))}},{key:"hev1",value:function(e){for(var t=[],n=[],i=[],s,o,c=0;c<(((u=e.vps)===null||u===void 0?void 0:u.length)||0);c++){var u;s=e.vps[c],o=s.byteLength,t.push(o>>>8&255,o&255),t=t.concat(Array.prototype.slice.call(s))}for(var d=0;d<(((f=e.sps)===null||f===void 0?void 0:f.length)||0);d++){var f;s=e.sps[d],o=s.byteLength,n.push(o>>>8&255,o&255),n=n.concat(Array.prototype.slice.call(s))}for(var h=0;h<(((y=e.pps)===null||y===void 0?void 0:y.length)||0);h++){var y;s=e.pps[h],o=s.byteLength,i.push(o>>>8&255,o&255),i=i.concat(Array.prototype.slice.call(s))}var F=e.hvcC,B=F.profile_space,R=F.tier_flag,E=F.profile_idc,O=F.profile_compatibility_flags,T=F.constraint_indicator_flags,ye=F.level_idc,te=F.chroma_format_idc,ve=r.box(r.types.hvcC,new Uint8Array([1,B<<6|R<<5|E,O>>24&255,O>>16&255,O>>8&255,O&255].concat(A(T),[ye,240,0,252,252|te,248,248,0,0,3,3,32,0,1],A(t),[33,0,1],A(n),[34,0,1],A(i)))),fe=e.width,j=e.height;return r.box(r.types.hev1,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,fe>>8&255,fe&255,j>>8&255,j&255,0,72,0,0,0,72,0,0,0,0,0,0,0,1,18,98,105,110,101,108,112,114,111,46,114,117,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,17,17]),ve,r.box(r.types.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192])))}},{key:"esds",value:function(e){var t=e.config.byteLength,n=new Uint8Array(26+t+3);return n.set([0,0,0,0,3,23+t,0,1,0,4,15+t,64,21,0,0,0,0,0,0,0,0,0,0,0,5,t]),n.set(e.config,26),n.set([6,1,2],26+t),n}},{key:"mp4a",value:function(e){var t=e.audiosamplerate;return r.box(r.types.mp4a,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,e.channelCount,0,16,0,0,0,0,t>>8&255,t&255,0,0]),r.box(r.types.esds,r.esds(e)))}},{key:"stsd",value:function(e){return e.type==="audio"?r.box(r.types.stsd,r.STSD,r.mp4a(e)):e.codec.startsWith("hvc1")?r.box(r.types.stsd,r.STSD,r.hev1(e)):r.box(r.types.stsd,r.STSD,r.avc1(e))}},{key:"tkhd",value:function(e){var t=e.id,n=e.duration,i=e.width,s=e.height,o=e.volume;return r.box(r.types.tkhd,new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,t>>24&255,t>>16&255,t>>8&255,t&255,0,0,0,0,n>>>24&255,n>>>16&255,n>>>8&255,n&255,0,0,0,0,0,0,0,0,0,0,0,0,o>>0&255,o%1*10>>0&255,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,i>>8&255,i&255,0,0,s>>8&255,s&255,0,0]))}},{key:"traf",value:function(e,t){var n=r.sdtp(e),i=e.id;return r.box(r.types.traf,r.box(r.types.tfhd,new Uint8Array([0,0,0,0,i>>24,i>>16&255,i>>8&255,i&255])),r.box(r.types.tfdt,new Uint8Array([0,0,0,0,t>>24,t>>16&255,t>>8&255,t&255])),r.trun(e,n.length+16+16+8+16+8+8),n)}},{key:"trak",value:function(e){return e.duration=e.duration||4294967295,r.box(r.types.trak,r.tkhd(e),r.mdia(e))}},{key:"trex",value:function(e){var t=e.id;return r.box(r.types.trex,new Uint8Array([0,0,0,0,t>>24,t>>16&255,t>>8&255,t&255,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]))}},{key:"trun",value:function(e,t){var n=e.samples||[],i=n.length,s=12+16*i,o=new Uint8Array(s),c,u,d,f,h,y;for(t+=8+s,o.set([0,0,15,1,i>>>24&255,i>>>16&255,i>>>8&255,i&255,t>>>24&255,t>>>16&255,t>>>8&255,t&255],0),c=0;c<i;c++)u=n[c],d=u.duration,f=u.size,h=u.flags,y=u.cts,o.set([d>>>24&255,d>>>16&255,d>>>8&255,d&255,f>>>24&255,f>>>16&255,f>>>8&255,f&255,h.isLeading<<2|h.dependsOn,h.isDependedOn<<6|h.hasRedundancy<<4|h.paddingValue<<1|h.isNonSync,h.degradPrio&61440,h.degradPrio&15,y>>>24&255,y>>>16&255,y>>>8&255,y&255],12+16*c);return r.box(r.types.trun,o)}},{key:"initSegment",value:function(e,t,n){r.types||r.init();var i=r.moov(e,t,n),s;return s=new Uint8Array(r.FTYP.byteLength+i.byteLength),s.set(r.FTYP),s.set(i,r.FTYP.byteLength),s}}]),r})(),ke=(function(){function r(){w(this,r)}return U(r,null,[{key:"samplingRateMap",get:function(){return[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350]}},{key:"getHeaderLength",value:function(e){return e[1]&1?7:9}},{key:"getFrameLength",value:function(e){return(e[3]&3)<<11|e[4]<<3|(e[5]&224)>>>5}},{key:"isAACPattern",value:function(e){return e[0]===255&&(e[1]&240)===240&&(e[1]&6)===0}},{key:"extractAAC",value:function(e){var t=0,n=e.byteLength,i=[],s,o;if(!r.isAACPattern(e))return K("Invalid ADTS audio format"),{valid:!1};s=r.getHeaderLength(e);for(var c=e.subarray(0,s);t<n;)o=r.getFrameLength(e),i.push(e.subarray(s,o)),e=e.slice(o),t+=o;return{valid:!0,header:c,slices:i}}}]),r})(),we=1,Q=(function(r){k(e,r);var a=D(e);function e(){return w(this,e),a.apply(this,arguments)}return U(e,[{key:"flush",value:function(){this.mp4track.len=0,this.mp4track.samples=[]}},{key:"isReady",value:function(){return!this.readyToDecode||!this.samples.length?null:!0}}],[{key:"getTrackID",value:function(){return we++}}]),e})(ue),v=(function(r){k(e,r);var a=D(e);function e(t,n,i){var s;return w(this,e),s=a.call(this,"AACRemuxer"),s.frameDuration=i,s.readyToDecode=!1,s.header=null,s.nextDts=0,s.dts=0,s.mp4track={id:Q.getTrackID(),type:"audio",channelCount:0,len:0,fragmented:!0,timescale:t,duration:n,samples:[],config:"",codec:""},s.samples=[],s}return U(e,[{key:"resetTrack",value:function(){this.readyToDecode=!1,this.header=null,this.mp4track.codec="",this.mp4track.channelCount="",this.mp4track.config="",this.mp4track.timescale=this.timescale,this.nextDts=0,this.dts=0}},{key:"feed",value:function(n,i){var s=ke.extractAAC(n),o=s.valid,c=s.header,u=s.slices;return this.header||(this.header=c),o&&u.length>0?(this.remux(this.getAudioFrames(u,i)),!0):(K("Failed to extract audio data from:",n),this.dispatch("outOfData"),!1)}},{key:"getAudioFrames",value:function(n,i){var s=[],o=0,c=0,u=x(n),d;try{for(u.s();!(d=u.n()).done;){var f=d.value;s.push({units:f})}}catch(h){u.e(h)}finally{u.f()}return o=i?i/s.length|0:this.frameDuration,c=i?i-o*s.length:0,s.map(function(h){h.duration=o,c>0&&(h.duration++,c--)}),s}},{key:"remux",value:function(n){if(n.length>0)for(var i=0;i<n.length;i++){var s=n[i],o=s.units,c=o.byteLength;this.samples.push({units:o,size:c,duration:s.duration}),this.mp4track.len+=c,this.readyToDecode||this.setAACConfig()}}},{key:"getPayload",value:function(){if(!this.isReady())return null;var n=new Uint8Array(this.mp4track.len),i=0,s=this.mp4track.samples,o,c;for(this.dts=this.nextDts;this.samples.length;){var u=this.samples.shift();if(u.units,c=u.duration,c<=0){b("remuxer: invalid sample duration at DTS: ".concat(this.nextDts," :").concat(c)),this.mp4track.len-=u.size;continue}this.nextDts+=c,o={size:u.size,duration:c,cts:0,flags:{isLeading:0,isDependedOn:0,hasRedundancy:0,degradPrio:0,dependsOn:1}},n.set(u.units,i),i+=u.size,s.push(o)}return s.length?new Uint8Array(n.buffer,0,this.mp4track.len):null}},{key:"setAACConfig",value:function(){var n,i,s,o=new Uint8Array(2);this.header&&(n=((this.header[2]&192)>>>6)+1,i=(this.header[2]&60)>>>2,s=(this.header[2]&1)<<2,s|=(this.header[3]&192)>>>6,o[0]=n<<3,o[0]|=(i&14)>>1,o[1]|=(i&1)<<7,o[1]|=s<<3,this.mp4track.codec="mp4a.40."+n,this.mp4track.channelCount=s,this.mp4track.config=o,this.readyToDecode=!0)}}]),e})(Q),X=(function(){function r(a){w(this,r),this.data=a,this.index=0,this.bitLength=a.byteLength*8}return U(r,[{key:"setData",value:function(e){this.data=e,this.index=0,this.bitLength=e.byteLength*8}},{key:"bitsAvailable",get:function(){return this.bitLength-this.index}},{key:"skipBits",value:function(e){if(this.bitsAvailable<e)return!1;this.index+=e}},{key:"readBits",value:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,n=this.getBits(e,this.index,t);return n}},{key:"getBits",value:function(e,t){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;if(this.bitsAvailable<e)return 0;var i=t%8,s=this.data[t/8|0]&255>>>i,o=8-i;if(o>=e)return n&&(this.index+=e),s>>o-e;n&&(this.index+=o);var c=e-o;return s<<c|this.getBits(c,t+o,n)}},{key:"skipLZ",value:function(){var e;for(e=0;e<this.bitLength-this.index;++e)if(this.getBits(1,this.index+e,!1)!==0)return this.index+=e,e;return e}},{key:"skipUEG",value:function(){this.skipBits(1+this.skipLZ())}},{key:"skipEG",value:function(){this.skipBits(1+this.skipLZ())}},{key:"readUEG",value:function(){var e=this.skipLZ();return this.readBits(e+1)-1}},{key:"readEG",value:function(){var e=this.readUEG();return 1&e?1+e>>>1:-1*(e>>>1)}},{key:"readBoolean",value:function(){return this.readBits(1)===1}},{key:"readUByte",value:function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:1;return this.readBits(e*8)}},{key:"readUShort",value:function(){return this.readBits(16)}},{key:"readUInt",value:function(){return this.readBits(32)}}]),r})(),ee=(function(){function r(){w(this,r)}return U(r,null,[{key:"extractNALu",value:function(e){for(var t=0,n=e.byteLength,i=[],s=0,o=0;t<n;){var c=e[t++];if(c===0)o++;else if(c===1&&o>=2){var u=o+1;s!==t-u&&i.push(e.subarray(s,t-u)),s=t,o=0}else o=0}var d=null;return s<n&&(d=e.subarray(s,n)),[i,d]}},{key:"skipScalingList",value:function(e,t){for(var n=8,i=8,s,o=0;o<t;o++)i!==0&&(s=e.readEG(),i=(n+s+256)%256),n=i===0?n:i}},{key:"readSPS",value:function(e){var t=new X(e),n=0,i=0,s=0,o=0,c=1,u,d,f,h,y,F,B=0;t.readUByte();for(var R=[],E=1,O=e.byteLength,T=E;T<O;T++)T+2<O&&t.readBits(24,!1)===3?(R.push(t.readBits(8)),R.push(t.readBits(8)),T+=2,t.readBits(8)):R.push(t.readBits(8));if(t.setData(new Uint8Array(R)),u=t.readUByte(),t.readBits(5),t.skipBits(3),t.readUByte(),t.skipUEG(),u===100||u===110||u===122||u===244||u===44||u===83||u===86||u===118||u===128){var ye=t.readUEG();if(ye===3&&t.skipBits(1),t.skipUEG(),t.skipUEG(),t.skipBits(1),t.readBoolean()){F=ye!==3?8:12;for(var te=0;te<F;++te)t.readBoolean()&&(te<6?r.skipScalingList(t,16):r.skipScalingList(t,64))}}t.skipUEG();var ve=t.readUEG();if(ve===0)t.readUEG();else if(ve===1){t.skipBits(1),t.skipEG(),t.skipEG(),d=t.readUEG();for(var fe=0;fe<d;++fe)t.skipEG()}if(t.skipUEG(),t.skipBits(1),f=t.readUEG(),h=t.readUEG(),y=t.readBits(1),y===0&&t.skipBits(1),t.skipBits(1),t.readBoolean()&&(n=t.readUEG(),i=t.readUEG(),s=t.readUEG(),o=t.readUEG()),t.readBoolean()){if(t.readBoolean()){var j,be=t.readUByte();switch(be){case 1:j=[1,1];break;case 2:j=[12,11];break;case 3:j=[10,11];break;case 4:j=[16,11];break;case 5:j=[40,33];break;case 6:j=[24,11];break;case 7:j=[20,11];break;case 8:j=[32,11];break;case 9:j=[80,33];break;case 10:j=[18,11];break;case 11:j=[15,11];break;case 12:j=[64,33];break;case 13:j=[160,99];break;case 14:j=[4,3];break;case 15:j=[3,2];break;case 16:j=[2,1];break;case 255:{j=[t.readUByte()<<8|t.readUByte(),t.readUByte()<<8|t.readUByte()];break}}j&&j[0]>0&&j[1]>0&&(c=j[0]/j[1])}if(t.readBoolean()&&t.skipBits(1),t.readBoolean()&&(t.skipBits(4),t.readBoolean()&&t.skipBits(24)),t.readBoolean()&&(t.skipUEG(),t.skipUEG()),t.readBoolean()){var Se=t.readUInt(),De=t.readUInt(),Fe=t.readBoolean(),Ae=De/(2*Se);Fe&&(B=Ae)}}return{fps:B>0?B:void 0,width:Math.ceil(((f+1)*16-n*2-i*2)*c),height:(2-y)*(h+1)*16-(y?2:4)*(s+o)}}}]),r})(),z=(function(){function r(a){w(this,r),this.payload=a,this.nri=(this.payload[0]&96)>>5,this.nalUnitType=this.payload[0]&31,this._sliceType=null,this._isFirstSlice=!1}return U(r,[{key:"toString",value:function(){return"".concat(r.TYPES[this.type()]||"UNKNOWN",": NRI: ").concat(this.getNri())}},{key:"getNri",value:function(){return this.nri}},{key:"type",value:function(){return this.nalUnitType}},{key:"isKeyframe",get:function(){return this.nalUnitType===r.IDR}},{key:"isVCL",get:function(){return this.nalUnitType==r.IDR||this.nalUnitType==r.NDR}},{key:"parseHeader",value:function(){var e=new X(this.getPayload());e.readUByte(),this._isFirstSlice=e.readUEG()===0,this._sliceType=e.readUEG()}},{key:"isFirstSlice",get:function(){return this._isFirstSlice||this.parseHeader(),this._isFirstSlice}},{key:"sliceType",get:function(){return this._sliceType||this.parseHeader(),this._sliceType}},{key:"getPayload",value:function(){return this.payload}},{key:"getPayloadSize",value:function(){return this.payload.byteLength}},{key:"getSize",value:function(){return 4+this.getPayloadSize()}},{key:"getData",value:function(){var e=new Uint8Array(this.getSize()),t=new DataView(e.buffer);return t.setUint32(0,this.getSize()-4),e.set(this.getPayload(),4),e}}],[{key:"NDR",get:function(){return 1}},{key:"IDR",get:function(){return 5}},{key:"SEI",get:function(){return 6}},{key:"SPS",get:function(){return 7}},{key:"PPS",get:function(){return 8}},{key:"AUD",get:function(){return 9}},{key:"TYPES",get:function(){var e;return e={},S(e,r.IDR,"IDR"),S(e,r.SEI,"SEI"),S(e,r.SPS,"SPS"),S(e,r.PPS,"PPS"),S(e,r.NDR,"NDR"),S(e,r.AUD,"AUD"),e}}]),r})();function se(r,a){var e=new Uint8Array((r.byteLength|0)+(a.byteLength|0));return e.set(r,0),e.set(a,r.byteLength|0),e}function pe(r){var a,e,t,n="";return a=Math.floor(r),e=parseInt(a/3600,10)%24,t=parseInt(a/60,10)%60,a=a<0?0:a%60,e>0&&(n+=(e<10?"0"+e:e)+":"),n+=(t<10?"0"+t:t)+":"+(a<10?"0"+a:a),n}var de=(function(r){k(e,r);var a=D(e);function e(t,n,i){var s;return w(this,e),s=a.call(this,"H264Remuxer"),s.frameDuration=i,s.readyToDecode=!1,s.nextDts=0,s.dts=0,s.mp4track={id:Q.getTrackID(),type:"video",len:0,fragmented:!0,sps:"",pps:"",fps:30,width:0,height:0,timescale:t,duration:n,samples:[]},s.samples=[],s.remainingData=new Uint8Array,s.kfCounter=0,s.pendingUnits={},s}return U(e,[{key:"resetTrack",value:function(){this.readyToDecode=!1,this.mp4track.sps="",this.mp4track.pps="",this.nextDts=0,this.dts=0,this.remainingData=new Uint8Array,this.kfCounter=0,this.pendingUnits={}}},{key:"feed",value:function(n,i,s){var o=[],c;n=se(this.remainingData,n);var u=ee.extractNALu(n),d=ie(u,2);return o=d[0],c=d[1],this.remainingData=c||new Uint8Array,o.length>0?(this.remux(this.getVideoFrames(o,i,s)),!0):(K("Failed to extract any NAL units from video data:",c),this.dispatch("outOfData"),!1)}},{key:"getVideoFrames",value:function(n,i,s){var o=this,c=[],u=[],d=0,f=0,h=!1,y=!1;this.pendingUnits.units&&(c=this.pendingUnits.units,y=this.pendingUnits.vcl,h=this.pendingUnits.keyFrame,this.pendingUnits={});var F=x(n),B;try{for(F.s();!(B=F.n()).done;){var R=B.value,E=new z(R);c.length&&y&&(E.isFirstSlice||!E.isVCL)&&(u.push({units:c,keyFrame:h}),c=[],h=!1,y=!1),c.push(E),h=h||E.isKeyframe,y=y||E.isVCL}}catch(T){F.e(T)}finally{F.f()}if(c.length)if(!i)this.pendingUnits={units:c,keyFrame:h,vcl:y};else if(y)u.push({units:c,keyFrame:h});else{var O=u.length-1;O>=0&&(u[O].units=u[O].units.concat(c))}return d=i?i/u.length|0:this.frameDuration,f=i?i-d*u.length:0,u.map(function(T){T.duration=d,T.compositionTimeOffset=s,f>0&&(T.duration++,f--),o.kfCounter++,T.keyFrame&&o.dispatch("keyframePosition",o.kfCounter*d/1e3)}),b("jmuxer: No. of H264 frames of the last chunk: ".concat(u.length)),u}},{key:"remux",value:function(n){var i=x(n),s;try{for(i.s();!(s=i.n()).done;){var o=s.value,c=[],u=0,d=x(o.units),f;try{for(d.s();!(f=d.n()).done;){var h=f.value;this.parseNAL(h)&&(c.push(h),u+=h.getSize())}}catch(y){d.e(y)}finally{d.f()}c.length>0&&this.readyToDecode&&(this.mp4track.len+=u,this.samples.push({units:c,size:u,keyFrame:o.keyFrame,duration:o.duration,compositionTimeOffset:o.compositionTimeOffset}))}}catch(y){i.e(y)}finally{i.f()}}},{key:"getPayload",value:function(){if(!this.isReady())return null;var n=new Uint8Array(this.mp4track.len),i=0,s=this.mp4track.samples,o,c;for(this.dts=this.nextDts;this.samples.length;){var u=this.samples.shift(),d=u.units;if(c=u.duration,c<=0){b("remuxer: invalid sample duration at DTS: ".concat(this.nextDts," :").concat(c)),this.mp4track.len-=u.size;continue}this.nextDts+=c,o={size:u.size,duration:c,cts:u.compositionTimeOffset||0,flags:{isLeading:0,isDependedOn:0,hasRedundancy:0,degradPrio:0,isNonSync:u.keyFrame?0:1,dependsOn:u.keyFrame?2:1}};var f=x(d),h;try{for(f.s();!(h=f.n()).done;){var y=h.value;n.set(y.getData(),i),i+=y.getSize()}}catch(F){f.e(F)}finally{f.f()}s.push(o)}return s.length?new Uint8Array(n.buffer,0,this.mp4track.len):null}},{key:"parseSPS",value:function(n){var i=ee.readSPS(new Uint8Array(n));this.mp4track.fps=i.fps||this.mp4track.fps,this.mp4track.width=i.width,this.mp4track.height=i.height,this.mp4track.sps=[new Uint8Array(n)],this.mp4track.codec="avc1.";for(var s=new DataView(n.buffer,n.byteOffset+1,4),o=0;o<3;++o){var c=s.getUint8(o).toString(16);c.length<2&&(c="0"+c),this.mp4track.codec+=c}}},{key:"parsePPS",value:function(n){this.mp4track.pps=[new Uint8Array(n)]}},{key:"parseNAL",value:function(n){if(!n)return!1;if(n.isVCL)return!0;var i=!1;switch(n.type()){case z.PPS:this.mp4track.pps||this.parsePPS(n.getPayload()),i=!0;break;case z.SPS:this.mp4track.sps||this.parseSPS(n.getPayload()),i=!0;break;case z.AUD:b("AUD - ignoing");break;case z.SEI:b("SEI - ignoing");break}return!this.readyToDecode&&this.mp4track.pps&&this.mp4track.sps&&(this.readyToDecode=!0),i}}]),e})(Q),Y=(function(){function r(){w(this,r)}return U(r,null,[{key:"extractNALu",value:function(e){for(var t=0,n=e.byteLength,i=[],s=0,o=0;t<n;){var c=e[t++];if(c===0)o++;else if(c===1&&o>=2){var u=o+1;s!==t-u&&i.push(e.subarray(s,t-u)),s=t,o=0}else o=0}var d=null;return s<n&&(d=e.subarray(s,n)),[i,d]}},{key:"removeEmulationPreventionBytes",value:function(e){for(var t=[],n=0,i=0;i<e.length;i++){var s=e[i];if(n===2&&s===3){n=0;continue}t.push(s),s===0?n++:n=0}return new Uint8Array(t)}},{key:"readSPS",value:function(e){var t=new X(e);t.readUByte(),t.readUByte(),t.readBits(4),t.readBits(3),t.readBits(1);for(var n=t.readBits(2),i=t.readBits(1),s=t.readBits(5),o=t.readUInt(),c=new Uint8Array(6),u=0;u<6;u++)c[u]=t.readUByte();var d=t.readUByte();t.readUEG();var f=t.readUEG();f===3&&t.readBits(1);var h=t.readUEG(),y=t.readUEG(),F=t.readBoolean(),B=0,R=0,E=0,O=0;F&&(B=t.readUEG(),R=t.readUEG(),E=t.readUEG(),O=t.readUEG());var T=null,ye=t.readBoolean();if(ye){var te=t.readBoolean();if(te){var ve=t.readUByte();ve===255&&(t.readUShort(),t.readUShort())}var fe=t.readBoolean();fe&&t.readBoolean();var j=t.readBoolean();if(j){t.readBits(3),t.readBoolean();var be=t.readBoolean();be&&(t.readUByte(),t.readUByte(),t.readUByte())}var Se=t.readBoolean();Se&&(t.readUEG(),t.readUEG()),t.readBoolean(),t.readBoolean(),t.readBoolean();var De=t.readBoolean();if(De){var Fe=t.readUInt(),Ae=t.readUInt();t.readBoolean(),Fe&&(T=Ae/(2*Fe))}}var Be=f===1||f===2?2:1,Re=f===1?2:1,Le=h-Be*(R+B),Me=y-Re*(E+O);return{width:Le,height:Me,profile_space:n,tier_flag:i,profile_idc:s,profile_compatibility_flags:o,constraint_indicator_flags:c,level_idc:d,chroma_format_idc:f,fps:T}}}]),r})(),J=(function(){function r(a){w(this,r),this.payload=a,this.nalUnitType=(a[0]&126)>>1,this.nuhLayerId=(a[0]&1)<<5|(a[1]&248)>>3,this.nuhTemporalIdPlus1=a[1]&7,this._isFirstSlice=null,this._sliceType=null}return U(r,[{key:"toString",value:function(){return"".concat(r.TYPES[this.type()]||"UNKNOWN ("+this.type()+")",": Layer: ").concat(this.nuhLayerId,", Temporal Id: ").concat(this.nuhTemporalIdPlus1)}},{key:"type",value:function(){return this.nalUnitType}},{key:"isKeyframe",get:function(){return[r.IDR_W_RADL,r.IDR_N_LP,r.CRA].includes(this.nalUnitType)}},{key:"isVCL",get:function(){return this.nalUnitType<=31}},{key:"parseHeader",value:function(){var e=new X(this.getPayload());e.readUByte(),e.readUByte(),this._isFirstSlice=e.readBoolean(),this.isKeyframe&&e.readBits(1),e.readUEG(),this._sliceType=e.readUEG()}},{key:"isFirstSlice",get:function(){return this._isFirstSlice||this.parseHeader(),this._isFirstSlice}},{key:"sliceType",get:function(){return this._sliceType||this.parseHeader(),this._sliceType}},{key:"getPayload",value:function(){return this.payload}},{key:"getPayloadSize",value:function(){return this.payload.byteLength}},{key:"getSize",value:function(){return 4+this.getPayloadSize()}},{key:"getData",value:function(){var e=new Uint8Array(this.getSize()),t=new DataView(e.buffer);return t.setUint32(0,this.getSize()-4),e.set(this.getPayload(),4),e}}],[{key:"TRAIL_N",get:function(){return 0}},{key:"TRAIL_R",get:function(){return 1}},{key:"IDR_W_RADL",get:function(){return 19}},{key:"IDR_N_LP",get:function(){return 20}},{key:"CRA",get:function(){return 21}},{key:"VPS",get:function(){return 32}},{key:"SPS",get:function(){return 33}},{key:"PPS",get:function(){return 34}},{key:"AUD",get:function(){return 35}},{key:"SEI",get:function(){return 39}},{key:"SEI2",get:function(){return 40}},{key:"TYPES",get:function(){var e;return e={},S(e,r.TRAIL_N,"TRAIL_N"),S(e,r.TRAIL_R,"TRAIL_R"),S(e,r.IDR_W_RADL,"IDR"),S(e,r.IDR_N_LP,"IDR2"),S(e,r.CRA,"CRA"),S(e,r.VPS,"VPS"),S(e,r.SPS,"SPS"),S(e,r.PPS,"PPS"),S(e,r.AUD,"AUD"),S(e,r.SEI,"SEI"),S(e,r.SEI2,"SEI2"),e}}]),r})(),q=(function(r){k(e,r);var a=D(e);function e(t,n,i){var s;return w(this,e),s=a.call(this,"H264Remuxer"),s.frameDuration=i,s.readyToDecode=!1,s.nextDts=0,s.dts=0,s.mp4track={id:Q.getTrackID(),type:"video",len:0,fragmented:!0,vps:"",sps:"",pps:"",hvcC:{},fps:30,width:0,height:0,timescale:t,duration:n,samples:[]},s.samples=[],s.remainingData=new Uint8Array,s.kfCounter=0,s.pendingUnits={},s}return U(e,[{key:"resetTrack",value:function(){this.readyToDecode=!1,this.mp4track.vps="",this.mp4track.sps="",this.mp4track.pps="",this.mp4track.hvcC={},this.nextDts=0,this.dts=0,this.remainingData=new Uint8Array,this.kfCounter=0,this.pendingUnits={}}},{key:"feed",value:function(n,i,s){var o=[],c;n=se(this.remainingData,n);var u=Y.extractNALu(n),d=ie(u,2);return o=d[0],c=d[1],this.remainingData=c||new Uint8Array,o.length>0?(this.remux(this.getVideoFrames(o,i,s)),!0):(K("Failed to extract any NAL units from video data:",c),this.dispatch("outOfData"),!1)}},{key:"getVideoFrames",value:function(n,i,s){var o=this,c=[],u=[],d=0,f=0,h=!1,y=!1;this.pendingUnits.units&&(c=this.pendingUnits.units,y=this.pendingUnits.vcl,h=this.pendingUnits.keyFrame,this.pendingUnits={});var F=x(n),B;try{for(F.s();!(B=F.n()).done;){var R=B.value,E=new J(R);c.length&&y&&(E.isFirstSlice||!E.isVCL)&&(u.push({units:c,keyFrame:h}),c=[],h=!1,y=!1),c.push(E),h=h||E.isKeyframe,y=y||E.isVCL}}catch(T){F.e(T)}finally{F.f()}if(c.length)if(!i)this.pendingUnits={units:c,keyFrame:h,vcl:y};else if(y)u.push({units:c,keyFrame:h});else{var O=u.length-1;O>=0&&(u[O].units=u[O].units.concat(c))}return d=i?i/u.length|0:this.frameDuration,f=i?i-d*u.length:0,u.map(function(T){T.duration=d,T.compositionTimeOffset=s,f>0&&(T.duration++,f--),o.kfCounter++,T.keyFrame&&o.dispatch("keyframePosition",o.kfCounter*d/1e3)}),b("jmuxer: No. of H265 frames of the last chunk: ".concat(u.length)),u}},{key:"remux",value:function(n){var i=x(n),s;try{for(i.s();!(s=i.n()).done;){var o=s.value,c=[],u=0,d=x(o.units),f;try{for(d.s();!(f=d.n()).done;){var h=f.value;this.parseNAL(h)&&(c.push(h),u+=h.getSize())}}catch(y){d.e(y)}finally{d.f()}c.length>0&&this.readyToDecode&&(this.mp4track.len+=u,this.samples.push({units:c,size:u,keyFrame:o.keyFrame,duration:o.duration,compositionTimeOffset:o.compositionTimeOffset}))}}catch(y){i.e(y)}finally{i.f()}}},{key:"getPayload",value:function(){if(!this.isReady())return null;var n=new Uint8Array(this.mp4track.len),i=0,s=this.mp4track.samples,o,c;for(this.dts=this.nextDts;this.samples.length;){var u=this.samples.shift(),d=u.units;if(c=u.duration,c<=0){b("remuxer: invalid sample duration at DTS: ".concat(this.nextDts," :").concat(c)),this.mp4track.len-=u.size;continue}this.nextDts+=c,o={size:u.size,duration:c,cts:u.compositionTimeOffset||0,flags:{isLeading:0,isDependedOn:0,hasRedundancy:0,degradPrio:0,isNonSync:u.keyFrame?0:1,dependsOn:u.keyFrame?2:1}};var f=x(d),h;try{for(f.s();!(h=f.n()).done;){var y=h.value;n.set(y.getData(),i),i+=y.getSize()}}catch(F){f.e(F)}finally{f.f()}s.push(o)}return s.length?new Uint8Array(n.buffer,0,this.mp4track.len):null}},{key:"parseSPS",value:function(n){this.mp4track.sps=[new Uint8Array(n)],n=Y.removeEmulationPreventionBytes(n);var i=Y.readSPS(new Uint8Array(n));this.mp4track.fps=i.fps||this.mp4track.fps,this.mp4track.width=i.width,this.mp4track.height=i.height,this.mp4track.codec="hvc1.".concat(i.profile_idc,".").concat(i.profile_compatibility_flags.toString(16))+".L".concat(i.level_idc).concat(i.tier_flag?"H":"L")+".".concat(i.constraint_indicator_flags.map(function(s){return s.toString(16)}).join(".").toUpperCase()),this.mp4track.hvcC={profile_space:i.profile_space,tier_flag:i.tier_flag,profile_idc:i.profile_idc,profile_compatibility_flags:i.profile_compatibility_flags,constraint_indicator_flags:i.constraint_indicator_flags,level_idc:i.level_idc,chroma_format_idc:i.chroma_format_idc}}},{key:"parsePPS",value:function(n){this.mp4track.pps=[n]}},{key:"parseVPS",value:function(n){this.mp4track.vps=[n]}},{key:"parseNAL",value:function(n){if(!n)return!1;if(n.isVCL)return!0;var i=!1;switch(n.type()){case J.VPS:this.mp4track.vps||this.parseVPS(n.getPayload()),i=!0;break;case J.SPS:this.mp4track.sps||this.parseSPS(n.getPayload()),i=!0;break;case J.PPS:this.mp4track.pps||this.parsePPS(n.getPayload()),i=!0;break;case J.AUD:b("AUD - ignoing");break;case J.SEI:case J.SEI2:b("SEI - ignoing");break}return!this.readyToDecode&&this.mp4track.vps&&this.mp4track.sps&&this.mp4track.pps&&(this.readyToDecode=!0),i}}]),e})(Q),je=(function(r){k(e,r);var a=D(e);function e(t,n,i,s){var o;return w(this,e),o=a.call(this,"remuxer"),o.videoCodec=i,o.frameDuration=s,o.initialized=!1,o.tracks={},o.seq=1,o.env=t,o.timescale=1e3,o.mediaDuration=n?4294967295:0,o}return U(e,[{key:"addTrack",value:function(n){var i=this;if((n==="video"||n==="both")&&(this.videoCodec=="H265"?this.tracks.video=new q(this.timescale,this.mediaDuration,this.frameDuration):this.tracks.video=new de(this.timescale,this.mediaDuration,this.frameDuration),this.tracks.video.on("outOfData",function(){i.dispatch("missingVideoFrames")}),this.tracks.video.on("keyframePosition",function(o){i.dispatch("keyframePosition",o)})),n==="audio"||n==="both"){var s=new v(this.timescale,this.mediaDuration,this.frameDuration);this.tracks.audio=s,this.tracks.video.on("outOfData",function(){i.dispatch("missingAudioFrames")})}}},{key:"reset",value:function(){for(var n in this.tracks)this.tracks[n].resetTrack();this.initialized=!1}},{key:"destroy",value:function(){this.tracks={},this.offAll()}},{key:"flush",value:function(){if(!this.initialized){if(!this.isReady())return;this.dispatch("ready"),this.initSegment(),this.initialized=!0}for(var n in this.tracks){var i=this.tracks[n],s=i.getPayload();if(s&&s.byteLength){var o=xe.moof(this.seq,i.dts,i.mp4track),c=xe.mdat(s),u=se(o,c),d={type:n,payload:u,dts:i.dts};n==="video"&&(d.fps=i.mp4track.fps),this.dispatch("buffer",d);var f=pe(i.dts/this.timescale);b("put segment (".concat(n,"): dts: ").concat(i.dts," frames: ").concat(i.mp4track.samples.length," second: ").concat(f)),i.flush(),this.seq++}}}},{key:"initSegment",value:function(){var n=[];for(var i in this.tracks){var s=this.tracks[i];if(this.env=="browser"){var o={type:i,payload:xe.initSegment([s.mp4track],this.mediaDuration,this.timescale)};this.dispatch("buffer",o)}else n.push(s.mp4track)}if(this.env=="node"){var c={type:"all",payload:xe.initSegment(n,this.mediaDuration,this.timescale)};this.dispatch("buffer",c)}b("Initial segment generated.")}},{key:"isReady",value:function(){for(var n in this.tracks)if(!this.tracks[n].readyToDecode||!this.tracks[n].samples.length)return!1;return!0}},{key:"feed",value:function(n){var i=!1;if(n.video&&this.tracks.video&&(i|=this.tracks.video.feed(n.video,n.duration,n.compositionTimeOffset)),n.audio&&this.tracks.audio&&(i|=this.tracks.audio.feed(n.audio,n.duration)),!i){K("Input object must have video and/or audio property. Make sure it is a valid typed array");return}this.flush()}}]),e})(ue),_e=(function(r){k(e,r);var a=D(e);function e(t,n){var i;return w(this,e),i=a.call(this,"buffer"),i.type=n,i.queue=new Uint8Array,i.cleaning=!1,i.pendingCleaning=0,i.cleanOffset=30,i.cleanRanges=[],i.sourceBuffer=t,i.sourceBuffer.addEventListener("updateend",function(){if(i.pendingCleaning>0&&(i.initCleanup(i.pendingCleaning),i.pendingCleaning=0),i.cleaning=!1,i.cleanRanges.length){i.doCleanup();return}}),i.sourceBuffer.addEventListener("error",function(){i.dispatch("error",{type:i.type,name:"buffer",error:"buffer error"})}),i}return U(e,[{key:"destroy",value:function(){this.queue=null,this.sourceBuffer=null,this.offAll()}},{key:"doCleanup",value:function(){if(!this.cleanRanges.length){this.cleaning=!1;return}var n=this.cleanRanges.shift();b("".concat(this.type," remove range [").concat(n[0]," - ").concat(n[1],")")),this.cleaning=!0,this.sourceBuffer.remove(n[0],n[1])}},{key:"initCleanup",value:function(n){try{if(this.sourceBuffer.updating){this.pendingCleaning=n;return}if(this.sourceBuffer.buffered&&this.sourceBuffer.buffered.length&&!this.cleaning){for(var i=0;i<this.sourceBuffer.buffered.length;++i){var s=this.sourceBuffer.buffered.start(i),o=this.sourceBuffer.buffered.end(i);n-s>this.cleanOffset&&(o=n-this.cleanOffset,s<o&&this.cleanRanges.push([s,o]))}this.doCleanup()}}catch(c){K("Error occured while cleaning ".concat(this.type," buffer - ").concat(c.name,": ").concat(c.message))}}},{key:"doAppend",value:function(){if(this.queue.length&&!(!this.sourceBuffer||this.sourceBuffer.updating))try{this.sourceBuffer.appendBuffer(this.queue),this.queue=new Uint8Array}catch(i){var n="unexpectedError";i.name==="QuotaExceededError"?(b("".concat(this.type," buffer quota full")),n="QuotaExceeded"):(K("Error occured while appending ".concat(this.type," buffer - ").concat(i.name,": ").concat(i.message)),n="InvalidStateError"),this.dispatch("error",{type:this.type,name:n,error:"buffer error"})}}},{key:"feed",value:function(n){this.queue=se(this.queue,n)}}]),e})(ue),m=(function(r){k(e,r);var a=D(e);function e(t){var n;w(this,e),n=a.call(this,"jmuxer"),n.isReset=!1;var i={node:"",mode:"both",videoCodec:"H264",flushingTime:500,maxDelay:500,clearBuffer:!0,fps:30,readFpsFromTrack:!1,debug:!1,onReady:function(){},onData:function(){},onError:function(){},onUnsupportedCodec:function(){},onMissingVideoFrames:function(){},onMissingAudioFrames:function(){},onKeyframePosition:function(){},onLoggerLog:console.log,onLoggerErr:console.error};return n.options=Object.assign({},i,t),n.env=(typeof process>"u"?"undefined":W(process))==="object"&&typeof window>"u"?"node":"browser",n.options.debug&&G(n.options.onLoggerLog,n.options.onLoggerErr),n.options.fps||(n.options.fps=30),n.frameDuration=1e3/n.options.fps|0,n.remuxController=new je(n.env,t.live,n.options.videoCodec,n.frameDuration),n.remuxController.addTrack(n.options.mode),n.initData(),n.remuxController.on("buffer",n.onBuffer.bind(L(n))),n.env=="browser"&&(n.remuxController.on("ready",n.createBuffer.bind(L(n))),n.initBrowser()),n.remuxController.on("missingVideoFrames",function(){typeof n.options.onMissingVideoFrames=="function"&&n.options.onMissingVideoFrames.call(null)}),n.remuxController.on("missingAudioFrames",function(){typeof n.options.onMissingAudioFrames=="function"&&n.options.onMissingAudioFrames.call(null)}),n.clearBuffer&&n.remuxController.on("keyframePosition",function(s){n.kfPosition.push(s)}),typeof n.options.onKeyframePosition=="function"&&n.remuxController.on("keyframePosition",function(s){n.options.onKeyframePosition.call(null,s)}),n}return U(e,[{key:"initData",value:function(){this.lastCleaningTime=Date.now(),this.kfPosition=[],this.pendingUnits={},this.remainingData=new Uint8Array,this.startInterval()}},{key:"initBrowser",value:function(){typeof this.options.node=="string"&&this.options.node==""&&K("no video element were found to render, provide a valid video element"),this.node=typeof this.options.node=="string"?document.getElementById(this.options.node):this.options.node,this.mseReady=!1,this.setupMSE()}},{key:"createStream",value:function(){var n=this.feed.bind(this),i=this.destroy.bind(this);return this.stream=new P.Duplex({writableObjectMode:!0,read:function(o){},write:function(o,c,u){n(o),u()},final:function(o){i(),o()}}),this.stream}},{key:"setupMSE",value:function(){if(window.MediaSource=window.MediaSource||window.WebKitMediaSource||window.ManagedMediaSource,!window.MediaSource)throw"Oops! Browser does not support Media Source Extension or Managed Media Source (IOS 17+).";if(this.isMSESupported=!!window.MediaSource,this.mediaSource=new window.MediaSource,this.url=URL.createObjectURL(this.mediaSource),window.MediaSource===window.ManagedMediaSource)try{this.node.removeAttribute("src"),this.node.disableRemotePlayback=!0;var n=document.createElement("source");n.type="video/mp4",n.src=this.url,this.node.appendChild(n),this.node.load()}catch{this.node.src=this.url}else this.node.src=this.url;this.mseEnded=!1,this.mediaSource.addEventListener("sourceopen",this.onMSEOpen.bind(this)),this.mediaSource.addEventListener("sourceclose",this.onMSEClose.bind(this)),this.mediaSource.addEventListener("webkitsourceopen",this.onMSEOpen.bind(this)),this.mediaSource.addEventListener("webkitsourceclose",this.onMSEClose.bind(this))}},{key:"endMSE",value:function(){if(!this.mseEnded)try{this.mseEnded=!0,this.mediaSource.endOfStream()}catch{K("mediasource is not available to end")}}},{key:"feed",value:function(n){!n||!this.remuxController||(n.duration=n.duration?parseInt(n.duration):0,this.remuxController.feed(n))}},{key:"destroy",value:function(){if(this.stopInterval(),this.stream&&(this.remuxController.flush(),this.stream.push(null),this.stream=null),this.remuxController&&(this.remuxController.destroy(),this.remuxController=null),this.bufferControllers){for(var n in this.bufferControllers)this.bufferControllers[n].destroy();this.bufferControllers=null,this.endMSE()}this.node=!1,this.mseReady=!1,this.videoStarted=!1,this.mediaSource=null}},{key:"reset",value:function(){if(this.stopInterval(),this.isReset=!0,this.node.pause(),this.remuxController&&this.remuxController.reset(),this.bufferControllers){for(var n in this.bufferControllers)this.bufferControllers[n].destroy();this.bufferControllers=null,this.endMSE()}this.initData(),this.env=="browser"&&this.initBrowser(),b("JMuxer was reset")}},{key:"createBuffer",value:function(){if(!(!this.mseReady||!this.remuxController||!this.remuxController.isReady()||this.bufferControllers)){this.bufferControllers={};for(var n in this.remuxController.tracks){var i=this.remuxController.tracks[n];if(!e.isSupported("".concat(n,'/mp4; codecs="').concat(i.mp4track.codec,'"')))return K("Browser does not support codec: ".concat(n,'/mp4; codecs="').concat(i.mp4track.codec,'"')),typeof this.options.onUnsupportedCodec=="function"&&this.options.onUnsupportedCodec.call(null,i.mp4track.codec),!1;var s=this.mediaSource.addSourceBuffer("".concat(n,'/mp4; codecs="').concat(i.mp4track.codec,'"'));this.bufferControllers[n]=new _e(s,n),this.bufferControllers[n].on("error",this.onBufferError.bind(this))}}}},{key:"startInterval",value:function(){var n=this;this.interval=setInterval(function(){n.options.flushingTime?n.applyAndClearBuffer():n.bufferControllers&&n.cancelDelay()},this.options.flushingTime||1e3)}},{key:"stopInterval",value:function(){this.interval&&clearInterval(this.interval)}},{key:"cancelDelay",value:function(){if(this.node.buffered&&this.node.buffered.length>0&&!this.node.seeking){var n=this.node.buffered.end(0);n-this.node.currentTime>this.options.maxDelay/1e3&&(b("delay"),this.node.paused&&this.node.play().catch(K),this.node.currentTime=n-.001)}}},{key:"releaseBuffer",value:function(){for(var n in this.bufferControllers)this.bufferControllers[n].doAppend()}},{key:"applyAndClearBuffer",value:function(){this.bufferControllers&&(this.releaseBuffer(),this.clearBuffer())}},{key:"getSafeClearOffsetOfBuffer",value:function(n){for(var i=this.options.mode==="audio"&&n||0,s,o=0;o<this.kfPosition.length&&!(this.kfPosition[o]>=n);o++)s=this.kfPosition[o];return s&&(this.kfPosition=this.kfPosition.filter(function(c){return c<s&&(i=c),c>=s})),i}},{key:"clearBuffer",value:function(){if(this.options.clearBuffer&&Date.now()-this.lastCleaningTime>1e4){for(var n in this.bufferControllers){var i=this.getSafeClearOffsetOfBuffer(this.node.currentTime);this.bufferControllers[n].initCleanup(i)}this.lastCleaningTime=Date.now()}}},{key:"onBuffer",value:function(n){this.options.readFpsFromTrack&&typeof n.fps<"u"&&this.options.fps!=n.fps&&(this.options.fps=n.fps,this.frameDuration=Math.ceil(1e3/n.fps),b("JMuxer changed FPS to ".concat(n.fps," from track data"))),this.env=="browser"?this.bufferControllers&&this.bufferControllers[n.type]&&this.bufferControllers[n.type].feed(n.payload):this.stream&&this.stream.push(n.payload),this.options.onData&&this.options.onData(n.payload),this.options.flushingTime===0&&this.applyAndClearBuffer()}},{key:"onMSEOpen",value:function(){this.mseReady=!0,URL.revokeObjectURL(this.url),typeof this.options.onReady=="function"&&this.options.onReady.call(null,this.isReset)}},{key:"onMSEClose",value:function(){this.mseReady=!1,this.videoStarted=!1}},{key:"onBufferError",value:function(n){if(n.name=="QuotaExceeded"){b("JMuxer cleaning ".concat(n.type," buffer due to QuotaExceeded error")),this.bufferControllers[n.type].initCleanup(this.node.currentTime);return}else n.name=="InvalidStateError"?(b("JMuxer is reseting due to InvalidStateError"),this.reset()):this.endMSE();typeof this.options.onError=="function"&&this.options.onError.call(null,n)}}],[{key:"isSupported",value:function(n){return window.MediaSource&&window.MediaSource.isTypeSupported(n)}}]),e})(ue);return m}))})(Ce)),Ce.exports}var it=nt();const st=Oe(it),at=400,Ee=50;function ot({deviceId:g,className:oe,onFallback:P,fallbackTimeout:N=5e3,enableControl:C=!1,onTapSuccess:$,onTapError:L,onSwipeSuccess:w,onSwipeError:H,onStreamReady:U}){const x=p.useRef(null),D=p.useRef(null),S=p.useRef(null),_=p.useRef(g),[k,M]=p.useState("connecting"),[ge,he]=p.useState(null),Z=p.useRef(null),le=p.useRef(!1),[re,ce]=p.useState([]),ie=p.useRef(!1),A=p.useRef(null),[V,me]=p.useState(null),W=p.useRef(null),I=p.useRef(null),ae=p.useRef(0),ne=p.useRef(null),G=p.useRef(null),[b,K]=p.useState(null),ue=p.useRef(0),xe=p.useRef(0),ke=p.useRef(0),we=p.useRef(0),Q=p.useRef(0),v=p.useRef(0),X=3,ee=1e3,z=p.useRef(P),se=p.useRef(N),pe=p.useRef(U),de=(m,r,a)=>{const e=a.getBoundingClientRect(),t=e.width,n=e.height,i=a.videoWidth,s=a.videoHeight;if(i===0||s===0)return console.warn("[ScrcpyPlayer] Video dimensions not available yet"),null;const o=i/s,c=t/n;let u,d,f,h;c>o?(d=n,u=o*n,f=(t-u)/2,h=0):(u=t,d=t/o,f=0,h=(n-d)/2);const y=m-f,F=r-h;if(y<0||y>u||F<0||F>d)return console.warn("[ScrcpyPlayer] Click outside video area (in letterbox)"),null;const B=Math.round(y/u*i),R=Math.round(F/d*s);return console.log(`[ScrcpyPlayer] Coordinate transform:
|
|
5
|
+
Click: (${m}, ${r})
|
|
6
|
+
Display: ${t}x${n}
|
|
7
|
+
Video: ${i}x${s}
|
|
8
|
+
Rendered: ${u}x${d} at offset (${f}, ${h})
|
|
9
|
+
Device: (${B}, ${R})`),{x:B,y:R}},Y=async m=>{if(!C||!x.current||k!=="connected")return;ie.current=!0,A.current={x:m.clientX,y:m.clientY,time:Date.now()};const r=x.current.getBoundingClientRect(),a=m.clientX-r.left,e=m.clientY-r.top,t=de(a,e,x.current);if(!t||!b)return;const n=x.current.videoWidth,i=x.current.videoHeight,s=b.width/n,o=b.height/i,c=Math.round(t.x*s),u=Math.round(t.y*o);try{await He(c,u,g),console.log(`[Touch] DOWN: (${c}, ${u}) for device ${g}`)}catch(d){console.error("[Touch] DOWN failed:",d)}},J=m=>{if(!ie.current||!A.current)return;me({id:Date.now(),startX:A.current.x,startY:A.current.y,endX:m.clientX,endY:m.clientY});const r=x.current?.getBoundingClientRect();if(!r||!x.current||!b)return;const a=m.clientX-r.left,e=m.clientY-r.top,t=de(a,e,x.current);if(!t)return;const n=x.current.videoWidth,i=x.current.videoHeight,s=b.width/n,o=b.height/i,c=Math.round(t.x*s),u=Math.round(t.y*o),d=Date.now();d-ae.current>=Ee?(ae.current=d,Ue(c,u,g).catch(f=>{console.error("[Touch] MOVE failed:",f)})):(ne.current={x:c,y:u},G.current&&clearTimeout(G.current),G.current=setTimeout(()=>{if(ne.current){const{x:f,y:h}=ne.current;ae.current=Date.now(),Ue(f,h,g).catch(y=>{console.error("[Touch] MOVE (throttled) failed:",y)}),ne.current=null}},Ee-(d-ae.current)))},q=async m=>{if(!ie.current||!A.current)return;const r=m.clientX-A.current.x,a=m.clientY-A.current.y,e=Date.now()-A.current.time;if(me(null),ie.current=!1,G.current&&(clearTimeout(G.current),G.current=null),ne.current=null,Math.sqrt(r*r+a*a)<10&&e<200){_e(m),A.current=null;return}const n=x.current?.getBoundingClientRect();if(!n||!x.current||!b){A.current=null;return}const i=m.clientX-n.left,s=m.clientY-n.top,o=de(i,s,x.current);if(!o){A.current=null;return}const c=x.current.videoWidth,u=x.current.videoHeight,d=b.width/c,f=b.height/u,h=Math.round(o.x*d),y=Math.round(o.y*f);try{await Pe(h,y,g),console.log(`[Touch] UP: (${h}, ${y}) for device ${g}`),$?.()}catch(F){console.error("[Touch] UP failed:",F),L?.(String(F))}A.current=null},je=async m=>{if(!C||!x.current||k!=="connected")return;const r=Date.now(),a=m.deltaY;I.current||(I.current={deltaY:0,lastTime:r,mouseX:m.clientX,mouseY:m.clientY}),I.current.deltaY+=a,I.current.lastTime=r;const e=.3;I.current.mouseX=Math.round(I.current.mouseX*(1-e)+m.clientX*e),I.current.mouseY=Math.round(I.current.mouseY*(1-e)+m.clientY*e),W.current&&clearTimeout(W.current),W.current=setTimeout(async()=>{if(!I.current||!x.current)return;const t=I.current;if(I.current=null,t.mouseX===void 0||t.mouseY===void 0)return;const n=x.current.getBoundingClientRect(),i=t.mouseX,s=t.mouseY,o=Math.abs(t.deltaY),c=Math.min(Math.max(300,o),800),u=de(i-n.left,s-n.top,x.current);if(!u||!b){console.warn("[ScrcpyPlayer] Cannot execute scroll: coordinate transformation failed");return}const d=x.current.videoWidth,f=x.current.videoHeight,h=b.width/d,y=b.height/f,F=Math.round(u.x*h),B=Math.round(u.y*y);let R,E;t.deltaY>0?(R=B,E=B-o):(R=B,E=B+o);const O=Math.abs(E-R),T=Math.max(O/b.height*n.height,20),ye=Math.min(Math.max(c*.8,200),800),te=document.createElement("div");te.style.cssText=`
|
|
10
|
+
position: fixed;
|
|
11
|
+
left: ${i}px;
|
|
12
|
+
top: ${s}px;
|
|
13
|
+
width: 20px;
|
|
14
|
+
height: 20px;
|
|
15
|
+
pointer-events: none;
|
|
16
|
+
z-index: 50;
|
|
17
|
+
transform: translateX(-50%) translateY(-50%);
|
|
18
|
+
background: radial-gradient(circle,
|
|
19
|
+
rgba(59, 130, 246, 0.8) 0%,
|
|
20
|
+
rgba(59, 130, 246, 0.4) 30%,
|
|
21
|
+
rgba(59, 130, 246, 0.2) 60%,
|
|
22
|
+
rgba(59, 130, 246, 0) 100%);
|
|
23
|
+
border-radius: 50%;
|
|
24
|
+
box-shadow: 0 0 10px rgba(59, 130, 246, 0.6);
|
|
25
|
+
`;const ve=Date.now(),fe=setInterval(()=>{const j=Date.now()-ve,be=Math.min(j/ye,1),Se=t.deltaY>0?s-T*be:s+T*be;te.style.top=Se+"px",be>=1&&clearInterval(fe)},16);document.body.appendChild(te),setTimeout(()=>{te.parentNode&&te.parentNode.removeChild(te),clearInterval(fe)},ye);try{const j=await $e(F,R,F,E,c,g);j.success?w?.():H?.(j.error||"Scroll failed")}catch(j){H?.(String(j))}},at)},_e=async m=>{if(!C||!x.current||k!=="connected"||x.current.videoWidth===0||x.current.videoHeight===0||!b)return;const r=x.current.getBoundingClientRect(),a=m.clientX-r.left,e=m.clientY-r.top,t=de(a,e,x.current);if(!t)return;const n=x.current.videoWidth,i=x.current.videoHeight,s=b.width/n,o=b.height/i,c=Math.round(t.x*s),u=Math.round(t.y*o),d=Date.now();ce(f=>[...f,{id:d,x:m.clientX,y:m.clientY}]),setTimeout(()=>{ce(f=>f.filter(h=>h.id!==d))},500);try{const f=await ze(c,u,g);f.success?$?.():L?.(f.error||"Unknown error")}catch(f){L?.(String(f))}};return p.useEffect(()=>{z.current=P,se.current=N,pe.current=U},[P,N,U]),p.useEffect(()=>{(async()=>{try{const r=await Ne(g);r.success&&(K({width:r.width,height:r.height}),console.log(`[ScrcpyPlayer] Device actual resolution: ${r.width}x${r.height} for device ${g}`))}catch(r){console.error("[ScrcpyPlayer] Failed to fetch device resolution:",r)}})()},[g]),p.useEffect(()=>{_.current=g;let m=null,r=null;const a=async()=>{if(x.current){if(console.log("[ScrcpyPlayer] connect() called"),we.current=Date.now(),M("connecting"),he(null),S.current){console.log("[ScrcpyPlayer] Closing existing WebSocket");try{S.current.onclose=null,S.current.onerror=null,S.current.onmessage=null,S.current.close()}catch(e){console.error("[ScrcpyPlayer] Error closing old WebSocket:",e)}S.current=null}if(D.current){console.log("[ScrcpyPlayer] Destroying old jMuxer instance");try{D.current.destroy()}catch(e){console.error("[ScrcpyPlayer] Error destroying old jMuxer:",e)}D.current=null}await new Promise(e=>setTimeout(e,300));try{console.log("[ScrcpyPlayer] Creating new jMuxer instance (after cleanup delay)"),D.current=new st({node:x.current,mode:"video",flushingTime:0,fps:30,debug:!1,clearBuffer:!0,onError:i=>{if(console.error("[jMuxer] Decoder error:",i),i.name==="InvalidStateError"&&i.error==="buffer error"){const s=Date.now(),o=s-v.current;if(o<ee){console.warn(`[jMuxer] Reset debounced (${o}ms since last reset)`);return}if(v.current=s,Q.current++,console.warn(`[jMuxer] ⚠️ Buffer error detected (attempt ${Q.current}/${X})`),Q.current<=X&&D.current)try{console.log("[jMuxer] Attempting lightweight reset()..."),D.current.reset(),console.log("[jMuxer] ✓ Reset successful");return}catch(u){console.error("[jMuxer] Reset failed:",u)}console.log("[jMuxer] Reset successful, reconnecting to get fresh initialization data..."),ke.current=s;const c=e;r&&setTimeout(()=>{_.current===c?r&&r():console.log(`[jMuxer] Device changed (${c} -> ${_.current}), skip reconnect`)},100)}},onMissingVideoFrames:i=>{console.warn("[jMuxer] Missing video frames detected:",i)}});const e=_.current,t=`ws://localhost:8000/api/video/stream?device_id=${encodeURIComponent(e)}`,n=new WebSocket(t);S.current=n,n.binaryType="arraybuffer",n.onopen=()=>{console.log(`[ScrcpyPlayer] WebSocket connected for device ${e}`),M("connected"),Q.current=0,v.current=0,pe.current&&pe.current({close:()=>{n.close()}}),Z.current=setTimeout(()=>{le.current||(console.log("[ScrcpyPlayer] No data received within timeout, triggering fallback"),M("error"),he("Video stream timeout"),n.close(),z.current&&z.current())},se.current)},n.onmessage=i=>{if(typeof i.data=="string"){try{const s=JSON.parse(i.data);console.error("[ScrcpyPlayer] Server error:",s),he(s.error||"Unknown error"),M("error"),z.current&&!le.current&&z.current()}catch{console.error("[ScrcpyPlayer] Received non-JSON string:",i.data)}return}if(!le.current){const s=new Uint8Array(i.data);console.log(`[ScrcpyPlayer] ✓ Received initialization data (${s.length} bytes)`);let o=0;for(let c=0;c<s.length-3;c++)s[c]===0&&s[c+1]===0&&(s[c+2]===1||s[c+2]===0&&s[c+3]===1)&&o++;console.log(`[ScrcpyPlayer] Initialization data contains ${o} NAL units`)}le.current||(le.current=!0,console.log("[ScrcpyPlayer] First video data received, canceling fallback timer"),Z.current&&(clearTimeout(Z.current),Z.current=null));try{if(D.current&&i.data.byteLength>0){const s=new Uint8Array(i.data);if(s[0]===0&&s[1]===0&&(s[2]===0||s[2]===1)||console.warn(`[ScrcpyPlayer] Invalid NAL unit: missing start code, first bytes = ${Array.from(s.slice(0,8)).map(d=>d.toString(16).padStart(2,"0")).join(" ")}`),le.current){const d=s[2]===1?3:4,f=s[d]&31;(f===5||f===7||f===8)&&console.log(`[ScrcpyPlayer] Received ${{5:"IDR",7:"SPS",8:"PPS"}[f]} NAL unit (${s.length} bytes)`)}D.current.feed({video:s}),ue.current++;const c=Date.now(),u=c-xe.current;if(u>5e3){const d=ue.current/u*1e3,f=x.current,h=f&&f.buffered.length>0?f.buffered.end(0)-f.currentTime:0;console.log(`[ScrcpyPlayer] Stats: ${d.toFixed(1)} fps, buffer: ${h.toFixed(2)}s`),h>2&&console.warn(`[ScrcpyPlayer] ⚠ High latency detected: ${h.toFixed(2)}s buffer`),ue.current=0,xe.current=c}}}catch(s){console.error("[ScrcpyPlayer] Feed error:",s)}},n.onerror=i=>{console.error("[ScrcpyPlayer] WebSocket error:",i),he("Connection error"),M("error")},n.onclose=()=>{console.log("[ScrcpyPlayer] WebSocket closed"),M("disconnected"),pe.current&&pe.current(null);const i=e;m=setTimeout(()=>{_.current===i?(console.log("[ScrcpyPlayer] Attempting to reconnect..."),a()):console.log(`[ScrcpyPlayer] Device changed (${i} -> ${_.current}), skip reconnect`)},3e3)}}catch(e){console.error("[ScrcpyPlayer] Initialization error:",e),he("Initialization failed"),M("error")}}};return r=a,a(),()=>{if(m&&clearTimeout(m),Z.current&&(clearTimeout(Z.current),Z.current=null),S.current&&(S.current.close(),S.current=null),G.current&&(clearTimeout(G.current),G.current=null),D.current){try{D.current.destroy()}catch(e){console.error("[ScrcpyPlayer] Cleanup error:",e)}D.current=null}}},[g]),l.jsxs("div",{className:`relative w-full h-full flex items-center justify-center ${oe||""}`,children:[l.jsx("video",{ref:x,autoPlay:!0,muted:!0,playsInline:!0,onError:m=>{const a=m.currentTarget.error;a&&console.error("[Video Element] Error occurred:",{code:a.code,message:a.message,MEDIA_ERR_ABORTED:a.code===1,MEDIA_ERR_NETWORK:a.code===2,MEDIA_ERR_DECODE:a.code===3,MEDIA_ERR_SRC_NOT_SUPPORTED:a.code===4})},onMouseDown:Y,onMouseMove:J,onMouseUp:q,onMouseLeave:async()=>{if(ie.current&&x.current&&b){if(A.current){const m=x.current.getBoundingClientRect(),r=de(A.current.x-m.left,A.current.y-m.top,x.current);if(r){const a=b.width/x.current.videoWidth,e=b.height/x.current.videoHeight,t=Math.round(r.x*a),n=Math.round(r.y*e);try{await Pe(t,n,g),console.log(`[Touch] UP (mouse leave) for device ${g}`)}catch(i){console.error("[Touch] UP (mouse leave) failed:",i)}}}ie.current=!1,me(null),A.current=null}},onWheel:je,className:`max-w-full max-h-full object-contain ${C?"cursor-pointer":""}`,style:{backgroundColor:"#000"}}),C&&V&&l.jsxs("svg",{className:"fixed inset-0 pointer-events-none z-40",children:[l.jsx("line",{x1:V.startX,y1:V.startY,x2:V.endX,y2:V.endY,stroke:"rgba(59, 130, 246, 0.8)",strokeWidth:"3",strokeLinecap:"round"}),l.jsx("circle",{cx:V.startX,cy:V.startY,r:"6",fill:"rgba(59, 130, 246, 0.8)"}),l.jsx("circle",{cx:V.endX,cy:V.endY,r:"6",fill:"rgba(239, 68, 68, 0.8)"})]}),C&&re.map(m=>l.jsx("div",{className:"fixed pointer-events-none z-50",style:{left:m.x,top:m.y},children:l.jsx("div",{className:"ripple-circle"})},m.id)),k!=="connected"&&l.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-black/50 backdrop-blur-sm",children:l.jsxs("div",{className:"text-center text-white",children:[k==="connecting"&&l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"w-8 h-8 border-4 border-white border-t-transparent rounded-full animate-spin mx-auto mb-2"}),l.jsx("p",{children:"正在连接..."})]}),k==="disconnected"&&l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"w-8 h-8 border-4 border-yellow-500 border-t-transparent rounded-full animate-spin mx-auto mb-2"}),l.jsx("p",{children:"连接断开,正在重连..."})]}),k==="error"&&l.jsxs(l.Fragment,{children:[l.jsx("div",{className:"text-red-500 text-xl mb-2",children:"✗"}),l.jsx("p",{className:"text-red-400",children:"连接失败"}),ge&&l.jsx("p",{className:"text-sm text-gray-400 mt-1",children:ge})]})]})})]})}function lt({deviceId:g,deviceName:oe,config:P,isConfigured:N}){const[C,$]=p.useState([]),[L,w]=p.useState(""),[H,U]=p.useState(!1),[x,D]=p.useState(null),[S,_]=p.useState(!1),[k,M]=p.useState(null),[ge,he]=p.useState(!0),[Z,le]=p.useState(!1),[re,ce]=p.useState("auto"),[ie,A]=p.useState(null),[V,me]=p.useState(()=>{try{const v=localStorage.getItem("display-tabs-visible");return v!==null?JSON.parse(v):!0}catch(v){return console.warn("Failed to load tabs visibility state:",v),!0}});p.useEffect(()=>{localStorage.setItem("display-tabs-visible",JSON.stringify(V))},[V]);const W=p.useRef(null),I=p.useRef(null),ae=p.useRef(null),ne=p.useRef(!1),G=p.useCallback(async()=>{if(!P){console.warn("[DevicePanel] config is required for handleInit");return}try{await Ye({model_config:{base_url:P?.base_url||void 0,api_key:P?.api_key||void 0,model_name:P?.model_name||void 0},agent_config:{device_id:g}}),_(!0),D(null)}catch(v){const X=v instanceof Error?v.message:"初始化失败,请检查配置";D(X)}},[g,P]),b=p.useCallback(async()=>{const v=L.trim();if(!v||H)return;S||await G();const X={id:Date.now().toString(),role:"user",content:v,timestamp:new Date};$(Y=>[...Y,X]),w(""),U(!0),D(null);const ee=[],z=[],se=(Date.now()+1).toString(),pe={id:se,role:"agent",content:"",timestamp:new Date,thinking:[],actions:[],isStreaming:!0};$(Y=>[...Y,pe]);const de=Ve(X.content,g,Y=>{ee.push(Y.thinking),z.push(Y.action),$(J=>J.map(q=>q.id===se?{...q,thinking:[...ee],actions:[...z],steps:Y.step}:q))},Y=>{$(J=>J.map(q=>q.id===se?{...q,content:Y.message,success:Y.success,isStreaming:!1}:q)),U(!1),W.current=null},Y=>{$(J=>J.map(q=>q.id===se?{...q,content:`错误: ${Y.message}`,success:!1,isStreaming:!1}:q)),U(!1),D(Y.message),W.current=null});W.current=de},[L,H,S,g,G]),K=p.useCallback(async()=>{W.current&&W.current.close(),$([]),U(!1),D(null),W.current=null,await We(g)},[g]),ue=()=>{ae.current?.scrollIntoView({behavior:"smooth"})};p.useEffect(()=>{ue()},[C]),p.useEffect(()=>()=>{console.log(`[DevicePanel] 设备 ${g} 卸载,清理资源`),W.current&&(W.current.close(),W.current=null),I.current&&(I.current.close(),I.current=null)},[g]),p.useEffect(()=>{if(!g||!(re==="screenshot"||re==="auto"&&Z))return;const X=async()=>{if(!ne.current){ne.current=!0;try{const z=await Ne(g);z.success&&M(z)}catch(z){console.error("Failed to fetch screenshot:",z)}finally{ne.current=!1}}};X();const ee=setInterval(X,500);return()=>clearInterval(ee)},[g,Z,re]);const xe=v=>{v.key==="Enter"&&(v.metaKey||v.ctrlKey)&&(v.preventDefault(),b())},ke=p.useCallback(v=>{I.current=v},[]),we=p.useCallback(()=>{le(!0),he(!1)},[]),Q=()=>{me(!V)};return l.jsxs("div",{className:"flex-1 flex gap-4 p-4 items-stretch justify-center min-h-0",children:[l.jsxs("div",{className:"flex flex-col w-full max-w-2xl min-h-0 border border-gray-200 dark:border-gray-700 rounded-2xl shadow-lg bg-white dark:bg-gray-800",children:[l.jsxs("div",{className:"flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700 rounded-t-2xl",children:[l.jsxs("div",{children:[l.jsx("h2",{className:"text-lg font-semibold",children:oe}),l.jsx("p",{className:"text-xs text-gray-500 dark:text-gray-400",children:g})]}),l.jsxs("div",{className:"flex flex-col gap-2",children:[!S&&!N&&l.jsx("div",{className:"p-2 bg-yellow-50 dark:bg-yellow-900/20 rounded text-xs text-yellow-800 dark:text-yellow-200",children:'⚠️ 请先配置 Base URL(点击左下角"全局配置"按钮)'}),l.jsxs("div",{className:"flex gap-2",children:[S?l.jsx("span",{className:"px-3 py-1 bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 rounded-full text-sm",children:"已初始化"}):l.jsx("button",{onClick:G,disabled:!N||!P,className:`px-4 py-2 rounded-lg transition-colors text-sm ${!N||!P?"bg-gray-300 dark:bg-gray-600 cursor-not-allowed text-gray-500 dark:text-gray-400":"bg-blue-500 text-white hover:bg-blue-600"}`,children:"初始化设备"}),l.jsx("button",{onClick:K,className:"px-4 py-2 bg-gray-200 dark:bg-gray-700 rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors text-sm",children:"重置"})]})]})]}),x&&l.jsx("div",{className:"mx-4 mt-4 p-3 bg-red-100 dark:bg-red-900 text-red-700 dark:text-red-200 rounded-lg text-sm",children:x}),l.jsxs("div",{className:"flex-1 overflow-y-auto p-4 space-y-4 min-h-0",children:[C.length===0?l.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400 mt-8",children:[l.jsx("p",{className:"text-lg",children:"设备已选择"}),l.jsx("p",{className:"text-sm mt-2",children:"输入任务描述,让 AI 帮你操作手机"})]}):null,C.map(v=>l.jsx("div",{className:`flex ${v.role==="user"?"justify-end":"justify-start"}`,children:v.role==="agent"?l.jsxs("div",{className:"max-w-[80%] space-y-2",children:[v.thinking?.map((X,ee)=>l.jsxs("div",{className:"bg-gray-100 dark:bg-gray-700 rounded-2xl px-4 py-3 border-l-4 border-blue-500",children:[l.jsxs("div",{className:"text-xs text-gray-500 dark:text-gray-400 mb-1",children:["💭 步骤 ",ee+1," - 思考过程"]}),l.jsx("p",{className:"text-sm whitespace-pre-wrap",children:X}),v.actions?.[ee]&&l.jsxs("details",{className:"mt-2 text-xs",children:[l.jsx("summary",{className:"cursor-pointer text-blue-500 hover:text-blue-600",children:"查看动作"}),l.jsx("pre",{className:"mt-1 p-2 bg-gray-800 text-gray-200 rounded overflow-x-auto text-xs",children:JSON.stringify(v.actions[ee],null,2)})]})]},ee)),v.content&&l.jsxs("div",{className:`rounded-2xl px-4 py-3 ${v.success===!1?"bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200":"bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200"}`,children:[l.jsx("p",{className:"whitespace-pre-wrap",children:v.content}),v.steps!==void 0&&l.jsxs("p",{className:"text-xs mt-2 opacity-70",children:["总步数: ",v.steps]})]}),v.isStreaming&&l.jsx("div",{className:"text-sm text-gray-500 dark:text-gray-400 animate-pulse",children:"正在执行..."})]}):l.jsx("div",{className:"max-w-[70%] rounded-2xl px-4 py-3 bg-blue-500 text-white",children:l.jsx("p",{className:"whitespace-pre-wrap",children:v.content})})},v.id)),l.jsx("div",{ref:ae})]}),l.jsx("div",{className:"p-4 border-t border-gray-200 dark:border-gray-700 rounded-b-2xl",children:l.jsxs("div",{className:"flex gap-2",children:[l.jsx("input",{type:"text",value:L,onChange:v=>w(v.target.value),onKeyDown:xe,placeholder:N?S?"输入任务描述...":"请先初始化设备":"请先配置 Base URL",disabled:H,className:"flex-1 px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-xl bg-white dark:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed"}),l.jsx("button",{onClick:b,disabled:H||!L.trim(),className:"px-6 py-3 bg-blue-500 text-white rounded-xl hover:bg-blue-600 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",children:"发送"})]})})]}),l.jsxs("div",{className:"w-full max-w-xs min-h-0 border border-gray-200 dark:border-gray-700 rounded-2xl shadow-lg bg-gray-900 overflow-hidden relative",children:[!V&&l.jsx("button",{onClick:Q,className:"absolute top-2 right-2 z-10 w-8 h-8 bg-gray-500 hover:bg-blue-600 text-white rounded-full shadow-lg transition-all duration-300 flex items-center justify-center opacity-20 hover:opacity-100 cursor-pointer",title:"显示选项卡",children:l.jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"})})}),l.jsxs("div",{className:`${V?"absolute top-2 right-2":"hidden"} z-10 flex gap-1 bg-black/70 rounded-lg p-1`,children:[l.jsx("button",{onClick:()=>ce("auto"),className:`px-3 py-1 text-xs rounded transition-colors ${re==="auto"?"bg-blue-500 text-white":"bg-gray-700 text-gray-300 hover:bg-gray-600"}`,children:"自动"}),l.jsx("button",{onClick:()=>ce("video"),className:`px-3 py-1 text-xs rounded transition-colors ${re==="video"?"bg-blue-500 text-white":"bg-gray-700 text-gray-300 hover:bg-gray-600"}`,children:"视频流"}),l.jsx("button",{onClick:()=>ce("screenshot"),className:`px-3 py-1 text-xs rounded transition-colors ${re==="screenshot"?"bg-blue-500 text-white":"bg-gray-700 text-gray-300 hover:bg-gray-600"}`,children:"截图"}),l.jsx("button",{onClick:Q,className:"ml-1 px-2 py-1 text-xs rounded transition-colors bg-gray-600 text-gray-300 hover:bg-gray-500",title:"隐藏选项卡",children:l.jsx("svg",{className:"w-3 h-3",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),re==="video"||re==="auto"&&ge&&!Z?l.jsxs(l.Fragment,{children:[ie&&l.jsx("div",{className:"absolute top-14 right-2 z-20 px-3 py-2 bg-blue-500 text-white text-sm rounded-lg shadow-lg",children:ie}),l.jsx(ot,{deviceId:g,className:"w-full h-full",enableControl:!0,onFallback:we,onTapSuccess:()=>{A("Tap executed"),setTimeout(()=>A(null),2e3)},onTapError:v=>{A(`Tap failed: ${v}`),setTimeout(()=>A(null),3e3)},onSwipeSuccess:()=>{A("Swipe executed"),setTimeout(()=>A(null),2e3)},onSwipeError:v=>{A(`Swipe failed: ${v}`),setTimeout(()=>A(null),3e3)},onStreamReady:ke,fallbackTimeout:1e5})]}):l.jsx("div",{className:"w-full h-full flex items-center justify-center bg-gray-900 min-h-0",children:k&&k.success?l.jsxs("div",{className:"relative w-full h-full flex items-center justify-center min-h-0",children:[l.jsx("img",{src:`data:image/png;base64,${k.image}`,alt:"Device Screenshot",className:"max-w-full max-h-full object-contain",style:{width:k.width>k.height?"100%":"auto",height:k.width>k.height?"auto":"100%"}}),k.is_sensitive&&l.jsx("div",{className:"absolute top-12 right-2 px-2 py-1 bg-yellow-500 text-white text-xs rounded",children:"敏感内容"}),l.jsxs("div",{className:"absolute bottom-2 left-2 px-2 py-1 bg-blue-500 text-white text-xs rounded",children:["截图模式 (0.5s 刷新)",re==="auto"&&Z&&" - 视频流不可用"]})]}):k?.error?l.jsxs("div",{className:"text-center text-red-500 dark:text-red-400",children:[l.jsx("p",{className:"mb-2",children:"截图失败"}),l.jsx("p",{className:"text-xs",children:k.error})]}):l.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[l.jsx("div",{className:"w-8 h-8 border-4 border-gray-300 border-t-blue-500 rounded-full animate-spin mx-auto mb-2"}),l.jsx("p",{children:"加载中..."})]})})]})]})}function ut(){const[g,oe]=p.useState([]),[P,N]=p.useState(""),[C,$]=p.useState(null),[L,w]=p.useState(!1),[H,U]=p.useState(!1),[x,D]=p.useState({base_url:"",model_name:"",api_key:""});p.useEffect(()=>{(async()=>{try{const k=await Xe();$({base_url:k.base_url,model_name:k.model_name,api_key:k.api_key||void 0}),D({base_url:k.base_url,model_name:k.model_name,api_key:k.api_key||""}),k.base_url||w(!0)}catch(k){console.error("Failed to load config:",k),w(!0)}})()},[]),p.useEffect(()=>{const _=async()=>{try{const M=await Ge();oe(M.devices),M.devices.length>0&&!P&&N(M.devices[0].id),P&&!M.devices.find(ge=>ge.id===P)&&N(M.devices[0]?.id||"")}catch(M){console.error("Failed to load devices:",M)}};_();const k=setInterval(_,3e3);return()=>clearInterval(k)},[P]);const S=async()=>{try{if(!x.base_url){alert("Base URL 是必需的");return}await Ke({base_url:x.base_url,model_name:x.model_name||"autoglm-phone-9b",api_key:x.api_key||void 0}),$({base_url:x.base_url,model_name:x.model_name,api_key:x.api_key||void 0}),w(!1),console.log("Configuration saved successfully")}catch(_){console.error("Failed to save config:",_),alert(`保存配置失败: ${_ instanceof Error?_.message:"Unknown error"}`)}};return l.jsxs("div",{className:"h-full flex relative min-h-0",children:[L&&l.jsx("div",{className:"absolute inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50",children:l.jsxs("div",{className:"bg-white dark:bg-gray-800 p-6 rounded-2xl w-96 shadow-xl border border-gray-200 dark:border-gray-700",children:[l.jsxs("div",{className:"flex items-center justify-between mb-4",children:[l.jsx("h2",{className:"text-xl font-bold text-gray-900 dark:text-gray-100",children:"全局配置"}),C&&C.base_url&&l.jsx("span",{className:"text-xs text-green-600 dark:text-green-400",children:"✓ 已配置"})]}),l.jsxs("div",{className:"space-y-4",children:[l.jsxs("div",{children:[l.jsx("label",{className:"block text-sm font-medium mb-1 text-gray-700 dark:text-gray-300",children:"Base URL *"}),l.jsx("input",{type:"text",value:x.base_url,onChange:_=>D({...x,base_url:_.target.value}),placeholder:"http://localhost:8080/v1",className:"w-full px-3 py-2 border rounded-lg bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 outline-none"}),!x.base_url&&l.jsx("p",{className:"text-xs text-red-500 mt-1",children:"⚠️ Base URL 是必需的"})]}),l.jsxs("div",{children:[l.jsx("label",{className:"block text-sm font-medium mb-1 text-gray-700 dark:text-gray-300",children:"API Key"}),l.jsxs("div",{className:"relative",children:[l.jsx("input",{type:H?"text":"password",value:x.api_key,onChange:_=>D({...x,api_key:_.target.value}),placeholder:"留空表示不设置",className:"w-full px-3 py-2 pr-10 border rounded-lg bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 outline-none"}),l.jsx("button",{type:"button",onClick:()=>U(!H),className:"absolute right-2 top-1/2 -translate-y-1/2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200",children:H?l.jsx("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21"})}):l.jsxs("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:[l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"}),l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"})]})})]})]}),l.jsxs("div",{children:[l.jsx("label",{className:"block text-sm font-medium mb-1 text-gray-700 dark:text-gray-300",children:"Model Name"}),l.jsx("input",{type:"text",value:x.model_name,onChange:_=>D({...x,model_name:_.target.value}),placeholder:"autoglm-phone-9b",className:"w-full px-3 py-2 border rounded-lg bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 outline-none"})]}),l.jsxs("div",{className:"flex justify-end gap-2 mt-6",children:[l.jsx("button",{onClick:()=>{w(!1),C&&D({base_url:C.base_url,model_name:C.model_name,api_key:C.api_key||""})},className:"px-4 py-2 text-gray-600 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200",children:"取消"}),l.jsx("button",{onClick:S,className:"px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors",children:"保存配置"})]})]})]})}),l.jsx(Ze,{devices:g,currentDeviceId:P,onSelectDevice:N,onOpenConfig:()=>w(!0)}),l.jsx("div",{className:"flex-1 relative flex items-stretch justify-center min-h-0",children:g.length===0?l.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-gray-50 dark:bg-gray-900",children:l.jsxs("div",{className:"text-center text-gray-500 dark:text-gray-400",children:[l.jsx("svg",{className:"w-16 h-16 mx-auto mb-4 opacity-50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:l.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"})}),l.jsx("h3",{className:"text-lg font-medium mb-2",children:"欢迎使用 AutoGLM Chat"}),l.jsx("p",{className:"text-sm",children:"未检测到设备,请连接 ADB 设备"})]})}):g.map(_=>l.jsx("div",{className:`w-full h-full flex items-stretch justify-center min-h-0 ${_.id===P?"":"hidden"}`,children:l.jsx(lt,{deviceId:_.id,deviceName:_.model,config:C,isVisible:_.id===P,isConfigured:!!C?.base_url})},_.id))})]})}export{ut as component};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as o,r as s,j as t}from"./index-
|
|
1
|
+
import{u as o,r as s,j as t}from"./index-D5BALRbT.js";function n(){const e=o();return s.useEffect(()=>{e({to:"/chat"})},[e]),t.jsx("div",{className:"p-2",children:t.jsx("h3",{children:"Welcome Home!"})})}export{n as component};
|