autoglm-gui 0.4.8__tar.gz → 0.4.9__tar.gz
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-0.4.9/AutoGLM_GUI/__init__.py +52 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/api/media.py +3 -1
- autoglm_gui-0.4.9/AutoGLM_GUI/platform_utils.py +37 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/scrcpy_stream.py +24 -80
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/PKG-INFO +4 -1
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/README.md +3 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/pyproject.toml +1 -1
- autoglm_gui-0.4.8/AutoGLM_GUI/__init__.py +0 -9
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/.gitignore +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/__main__.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/adb_plus/__init__.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/adb_plus/screenshot.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/adb_plus/touch.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/api/__init__.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/api/agents.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/api/control.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/api/devices.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/config.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/schemas.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/server.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/state.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/static/assets/about-BI6OV6gm.js +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/static/assets/chat-C_2Cot0q.js +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/static/assets/index-DCrxTz-A.css +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/static/assets/index-Dn3vR6uV.js +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/static/assets/index-Do7ha9Kf.js +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/static/index.html +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/AutoGLM_GUI/version.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/LICENSE +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/__init__.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/actions/__init__.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/actions/handler.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/adb/__init__.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/adb/connection.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/adb/device.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/adb/input.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/adb/screenshot.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/agent.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/config/__init__.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/config/apps.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/config/i18n.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/config/prompts.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/config/prompts_en.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/config/prompts_zh.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/model/__init__.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/phone_agent/model/client.py +0 -0
- {autoglm_gui-0.4.8 → autoglm_gui-0.4.9}/scrcpy-server-v3.3.3 +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""AutoGLM-GUI package metadata."""
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
from functools import wraps
|
|
6
|
+
from importlib import metadata
|
|
7
|
+
|
|
8
|
+
# ============================================================================
|
|
9
|
+
# Fix Windows encoding issue: Force UTF-8 for all subprocess calls
|
|
10
|
+
# ============================================================================
|
|
11
|
+
# On Windows, subprocess defaults to GBK encoding which fails when ADB/scrcpy
|
|
12
|
+
# output UTF-8 characters. This monkey patch ensures all subprocess calls
|
|
13
|
+
# use UTF-8 encoding by default.
|
|
14
|
+
|
|
15
|
+
_original_run = subprocess.run
|
|
16
|
+
_original_popen = subprocess.Popen
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@wraps(_original_run)
|
|
20
|
+
def _patched_run(*args, **kwargs):
|
|
21
|
+
"""Patched subprocess.run that defaults to UTF-8 encoding on Windows."""
|
|
22
|
+
if sys.platform == "win32":
|
|
23
|
+
# Add encoding='utf-8' if text=True is set but encoding is not specified
|
|
24
|
+
if kwargs.get("text") or kwargs.get("universal_newlines"):
|
|
25
|
+
if "encoding" not in kwargs:
|
|
26
|
+
kwargs["encoding"] = "utf-8"
|
|
27
|
+
return _original_run(*args, **kwargs)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class _PatchedPopen(_original_popen):
|
|
31
|
+
"""Patched subprocess.Popen that defaults to UTF-8 encoding on Windows."""
|
|
32
|
+
|
|
33
|
+
def __init__(self, *args, **kwargs):
|
|
34
|
+
if sys.platform == "win32":
|
|
35
|
+
# Add encoding='utf-8' if text=True is set but encoding is not specified
|
|
36
|
+
if kwargs.get("text") or kwargs.get("universal_newlines"):
|
|
37
|
+
if "encoding" not in kwargs:
|
|
38
|
+
kwargs["encoding"] = "utf-8"
|
|
39
|
+
super().__init__(*args, **kwargs)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# Apply the patches globally
|
|
43
|
+
subprocess.run = _patched_run
|
|
44
|
+
subprocess.Popen = _PatchedPopen
|
|
45
|
+
|
|
46
|
+
# ============================================================================
|
|
47
|
+
|
|
48
|
+
# Expose package version at runtime; fall back to "unknown" during editable/dev runs
|
|
49
|
+
try:
|
|
50
|
+
__version__ = metadata.version("autoglm-gui")
|
|
51
|
+
except metadata.PackageNotFoundError:
|
|
52
|
+
__version__ = "unknown"
|
|
@@ -91,7 +91,9 @@ async def video_stream_ws(
|
|
|
91
91
|
if DEBUG_SAVE_STREAM:
|
|
92
92
|
debug_dir = Path("debug_streams")
|
|
93
93
|
debug_dir.mkdir(exist_ok=True)
|
|
94
|
-
debug_file_path =
|
|
94
|
+
debug_file_path = (
|
|
95
|
+
debug_dir / f"{device_id}_{int(__import__('time').time())}.h264"
|
|
96
|
+
)
|
|
95
97
|
debug_file = open(debug_file_path, "wb")
|
|
96
98
|
print(f"[video/stream] DEBUG: Saving stream to {debug_file_path}")
|
|
97
99
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Platform-aware subprocess helpers to avoid duplicated Windows branches."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import platform
|
|
5
|
+
import subprocess
|
|
6
|
+
from typing import Any, Sequence
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def is_windows() -> bool:
|
|
10
|
+
"""Return True if running on Windows."""
|
|
11
|
+
return platform.system() == "Windows"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
async def run_cmd_silently(cmd: Sequence[str]) -> subprocess.CompletedProcess:
|
|
15
|
+
"""Run a command, suppressing output; safe for async contexts on all platforms."""
|
|
16
|
+
if is_windows():
|
|
17
|
+
# Avoid blocking the event loop with a blocking subprocess call on Windows.
|
|
18
|
+
return await asyncio.to_thread(
|
|
19
|
+
subprocess.run, cmd, capture_output=True, check=False
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
process = await asyncio.create_subprocess_exec(
|
|
23
|
+
*cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
|
|
24
|
+
)
|
|
25
|
+
await process.wait()
|
|
26
|
+
return subprocess.CompletedProcess(cmd, process.returncode, None, None)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
async def spawn_process(cmd: Sequence[str], *, capture_output: bool = False) -> Any:
|
|
30
|
+
"""Start a long-running process with optional stdio capture."""
|
|
31
|
+
stdout = subprocess.PIPE if capture_output else None
|
|
32
|
+
stderr = subprocess.PIPE if capture_output else None
|
|
33
|
+
|
|
34
|
+
if is_windows():
|
|
35
|
+
return subprocess.Popen(cmd, stdout=stdout, stderr=stderr)
|
|
36
|
+
|
|
37
|
+
return await asyncio.create_subprocess_exec(*cmd, stdout=stdout, stderr=stderr)
|
|
@@ -2,10 +2,12 @@
|
|
|
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.platform_utils import is_windows, run_cmd_silently, spawn_process
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
class ScrcpyStreamer:
|
|
@@ -34,7 +36,7 @@ class ScrcpyStreamer:
|
|
|
34
36
|
self.port = port
|
|
35
37
|
self.idr_interval_s = idr_interval_s
|
|
36
38
|
|
|
37
|
-
self.scrcpy_process:
|
|
39
|
+
self.scrcpy_process: Any | None = None
|
|
38
40
|
self.tcp_socket: socket.socket | None = None
|
|
39
41
|
self.forward_cleanup_needed = False
|
|
40
42
|
|
|
@@ -126,50 +128,20 @@ class ScrcpyStreamer:
|
|
|
126
128
|
if self.device_id:
|
|
127
129
|
cmd_base.extend(["-s", self.device_id])
|
|
128
130
|
|
|
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)
|
|
131
|
+
# Method 1: Try pkill
|
|
132
|
+
cmd = cmd_base + ["shell", "pkill", "-9", "-f", "app_process.*scrcpy"]
|
|
133
|
+
await run_cmd_silently(cmd)
|
|
135
134
|
|
|
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()
|
|
135
|
+
# Method 2: Find and kill by PID (more reliable)
|
|
136
|
+
cmd = cmd_base + [
|
|
137
|
+
"shell",
|
|
138
|
+
"ps -ef | grep 'app_process.*scrcpy' | grep -v grep | awk '{print $2}' | xargs kill -9",
|
|
139
|
+
]
|
|
140
|
+
await run_cmd_silently(cmd)
|
|
154
141
|
|
|
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()
|
|
142
|
+
# Method 3: Remove port forward if exists
|
|
143
|
+
cmd_remove_forward = cmd_base + ["forward", "--remove", f"tcp:{self.port}"]
|
|
144
|
+
await run_cmd_silently(cmd_remove_forward)
|
|
173
145
|
|
|
174
146
|
# Wait longer for resources to be released
|
|
175
147
|
print("[ScrcpyStreamer] Waiting for cleanup to complete...")
|
|
@@ -182,13 +154,7 @@ class ScrcpyStreamer:
|
|
|
182
154
|
cmd.extend(["-s", self.device_id])
|
|
183
155
|
cmd.extend(["push", self.scrcpy_server_path, "/data/local/tmp/scrcpy-server"])
|
|
184
156
|
|
|
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()
|
|
157
|
+
await run_cmd_silently(cmd)
|
|
192
158
|
|
|
193
159
|
async def _setup_port_forward(self) -> None:
|
|
194
160
|
"""Setup ADB port forwarding."""
|
|
@@ -197,13 +163,7 @@ class ScrcpyStreamer:
|
|
|
197
163
|
cmd.extend(["-s", self.device_id])
|
|
198
164
|
cmd.extend(["forward", f"tcp:{self.port}", "localabstract:scrcpy"])
|
|
199
165
|
|
|
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()
|
|
166
|
+
await run_cmd_silently(cmd)
|
|
207
167
|
self.forward_cleanup_needed = True
|
|
208
168
|
|
|
209
169
|
async def _start_server(self) -> None:
|
|
@@ -238,22 +198,14 @@ class ScrcpyStreamer:
|
|
|
238
198
|
cmd.extend(server_args)
|
|
239
199
|
|
|
240
200
|
# 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
|
-
)
|
|
201
|
+
self.scrcpy_process = await spawn_process(cmd, capture_output=True)
|
|
250
202
|
|
|
251
203
|
# Wait for server to start
|
|
252
204
|
await asyncio.sleep(2)
|
|
253
205
|
|
|
254
206
|
# Check if process is still running
|
|
255
207
|
error_msg = None
|
|
256
|
-
if
|
|
208
|
+
if is_windows():
|
|
257
209
|
# For Windows Popen, check returncode directly
|
|
258
210
|
if self.scrcpy_process.poll() is not None:
|
|
259
211
|
# Process has exited
|
|
@@ -314,9 +266,7 @@ class ScrcpyStreamer:
|
|
|
314
266
|
|
|
315
267
|
raise ConnectionError("Failed to connect to scrcpy server")
|
|
316
268
|
|
|
317
|
-
def _find_nal_units(
|
|
318
|
-
self, data: bytes
|
|
319
|
-
) -> list[tuple[int, int, int, bool]]:
|
|
269
|
+
def _find_nal_units(self, data: bytes) -> list[tuple[int, int, int, bool]]:
|
|
320
270
|
"""Find NAL units in H.264 data.
|
|
321
271
|
|
|
322
272
|
Returns:
|
|
@@ -392,9 +342,7 @@ class ScrcpyStreamer:
|
|
|
392
342
|
f"[ScrcpyStreamer] ✓ Cached SPS ({size} bytes, complete={is_complete}): {hex_preview}..."
|
|
393
343
|
)
|
|
394
344
|
elif size < 10:
|
|
395
|
-
print(
|
|
396
|
-
f"[ScrcpyStreamer] ✗ Skipped short SPS ({size} bytes)"
|
|
397
|
-
)
|
|
345
|
+
print(f"[ScrcpyStreamer] ✗ Skipped short SPS ({size} bytes)")
|
|
398
346
|
|
|
399
347
|
elif nal_type == 8: # PPS
|
|
400
348
|
# Only cache PPS if not yet locked
|
|
@@ -409,9 +357,7 @@ class ScrcpyStreamer:
|
|
|
409
357
|
f"[ScrcpyStreamer] ✓ Cached PPS ({size} bytes, complete={is_complete}): {hex_preview}..."
|
|
410
358
|
)
|
|
411
359
|
elif size < 6:
|
|
412
|
-
print(
|
|
413
|
-
f"[ScrcpyStreamer] ✗ Skipped short PPS ({size} bytes)"
|
|
414
|
-
)
|
|
360
|
+
print(f"[ScrcpyStreamer] ✗ Skipped short PPS ({size} bytes)")
|
|
415
361
|
|
|
416
362
|
elif nal_type == 5: # IDR frame
|
|
417
363
|
# Cache IDR if it's large enough (size check is sufficient)
|
|
@@ -422,9 +368,7 @@ class ScrcpyStreamer:
|
|
|
422
368
|
is_first = self.cached_idr is None
|
|
423
369
|
self.cached_idr = nal_data
|
|
424
370
|
if is_first:
|
|
425
|
-
print(
|
|
426
|
-
f"[ScrcpyStreamer] ✓ Cached IDR frame ({size} bytes)"
|
|
427
|
-
)
|
|
371
|
+
print(f"[ScrcpyStreamer] ✓ Cached IDR frame ({size} bytes)")
|
|
428
372
|
# Don't log every IDR update (too verbose)
|
|
429
373
|
elif size < 1024:
|
|
430
374
|
print(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: autoglm-gui
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.9
|
|
4
4
|
Summary: Web GUI for AutoGLM Phone Agent - AI-powered Android automation
|
|
5
5
|
Project-URL: Homepage, https://github.com/suyiiyii/AutoGLM-GUI
|
|
6
6
|
Project-URL: Repository, https://github.com/suyiiyii/AutoGLM-GUI
|
|
@@ -51,6 +51,9 @@ AutoGLM 手机助手的现代化 Web 图形界面 - 让 AI 自动化操作 Andro
|
|
|
51
51
|
### 任务执行完成
|
|
52
52
|

|
|
53
53
|
|
|
54
|
+
### 多设备控制
|
|
55
|
+

|
|
56
|
+
|
|
54
57
|
## 🚀 快速开始
|
|
55
58
|
|
|
56
59
|
## 🎯 模型服务配置
|
|
@@ -23,6 +23,9 @@ AutoGLM 手机助手的现代化 Web 图形界面 - 让 AI 自动化操作 Andro
|
|
|
23
23
|
### 任务执行完成
|
|
24
24
|

|
|
25
25
|
|
|
26
|
+
### 多设备控制
|
|
27
|
+

|
|
28
|
+
|
|
26
29
|
## 🚀 快速开始
|
|
27
30
|
|
|
28
31
|
## 🎯 模型服务配置
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"""AutoGLM-GUI package metadata."""
|
|
2
|
-
|
|
3
|
-
from importlib import metadata
|
|
4
|
-
|
|
5
|
-
# Expose package version at runtime; fall back to "unknown" during editable/dev runs
|
|
6
|
-
try:
|
|
7
|
-
__version__ = metadata.version("autoglm-gui")
|
|
8
|
-
except metadata.PackageNotFoundError:
|
|
9
|
-
__version__ = "unknown"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|