syncloud-lib 364__tar.gz → 366__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.
- {syncloud_lib-364/syncloud_lib.egg-info → syncloud_lib-366}/PKG-INFO +1 -1
- {syncloud_lib-364 → syncloud_lib-366/syncloud_lib.egg-info}/PKG-INFO +1 -1
- {syncloud_lib-364 → syncloud_lib-366}/syncloud_lib.egg-info/SOURCES.txt +1 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/integration/conftest.py +9 -109
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/integration/device.py +2 -0
- syncloud_lib-366/syncloudlib/integration/selenium_conftest.py +109 -0
- syncloud_lib-366/version +1 -0
- syncloud_lib-364/version +0 -1
- {syncloud_lib-364 → syncloud_lib-366}/LICENSE +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/MANIFEST.in +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/requirements.txt +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/setup.cfg +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/setup.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloud_lib.egg-info/dependency_links.txt +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloud_lib.egg-info/requires.txt +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloud_lib.egg-info/top_level.txt +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/__init__.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/application/__init__.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/application/config.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/application/connection.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/application/paths.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/application/ports.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/application/service.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/application/storage.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/application/urls.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/application/users.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/error.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/fs.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/http.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/integration/__init__.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/integration/hosts.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/integration/installer.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/integration/loop.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/integration/screenshots.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/integration/selenium_wrapper.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/integration/ssh.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/json/__init__.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/json/convertible.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/linux.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/syncloudlib/logger.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/test/application/test_connection.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/test/application/test_paths.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/test/application/test_service.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/test/application/test_storage.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/test/application/test_urls.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/test/integration/test_hosts.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/test/integration/test_installer.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/test/integration/test_loop.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/test/integration/test_ssh.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/test/json/test_convertible.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/test/test_fs.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/test/test_linux.py +0 -0
- {syncloud_lib-364 → syncloud_lib-366}/test/test_logger.py +0 -0
|
@@ -31,6 +31,7 @@ syncloudlib/integration/hosts.py
|
|
|
31
31
|
syncloudlib/integration/installer.py
|
|
32
32
|
syncloudlib/integration/loop.py
|
|
33
33
|
syncloudlib/integration/screenshots.py
|
|
34
|
+
syncloudlib/integration/selenium_conftest.py
|
|
34
35
|
syncloudlib/integration/selenium_wrapper.py
|
|
35
36
|
syncloudlib/integration/ssh.py
|
|
36
37
|
syncloudlib/json/__init__.py
|
|
@@ -4,12 +4,10 @@ import platform
|
|
|
4
4
|
from os.path import join, exists
|
|
5
5
|
|
|
6
6
|
import pytest
|
|
7
|
-
from selenium import webdriver
|
|
8
7
|
|
|
9
8
|
from syncloudlib.integration.device import Device
|
|
10
9
|
from syncloudlib.integration.installer import get_data_dir, get_app_dir, get_service_prefix, get_ssh_env_vars, \
|
|
11
10
|
get_snap_data_dir
|
|
12
|
-
from syncloudlib.integration.selenium_wrapper import SeleniumWrapper
|
|
13
11
|
|
|
14
12
|
log = logging.getLogger()
|
|
15
13
|
|
|
@@ -30,11 +28,8 @@ def pytest_addoption(parser):
|
|
|
30
28
|
parser.addoption("--device-host", action="store")
|
|
31
29
|
parser.addoption("--app-archive-path", action="store")
|
|
32
30
|
parser.addoption("--app", action="store")
|
|
33
|
-
parser.addoption("--ui-mode", action="store", default="desktop")
|
|
34
31
|
parser.addoption("--device-user", action="store", default="user")
|
|
35
32
|
parser.addoption("--build-number", action="store", default="local")
|
|
36
|
-
parser.addoption("--browser", action="store", default="firefox")
|
|
37
|
-
parser.addoption("--browser-height", action="store", default=2000)
|
|
38
33
|
parser.addoption("--redirect-user", action="store", default="redirect-user-notset")
|
|
39
34
|
parser.addoption("--redirect-password", action="store", default="redirect-password-notset")
|
|
40
35
|
parser.addoption("--distro", action="store", default="distro")
|
|
@@ -45,17 +40,17 @@ def pytest_addoption(parser):
|
|
|
45
40
|
@pytest.fixture(scope='session')
|
|
46
41
|
def build_number(request):
|
|
47
42
|
return request.config.getoption("--build-number")
|
|
48
|
-
|
|
43
|
+
|
|
49
44
|
|
|
50
45
|
@pytest.fixture(scope='session')
|
|
51
46
|
def device_user(request):
|
|
52
47
|
return request.config.getoption("--device-user")
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
|
|
49
|
+
|
|
55
50
|
@pytest.fixture(scope='session')
|
|
56
51
|
def device_password():
|
|
57
52
|
return 'Password1'
|
|
58
|
-
|
|
53
|
+
|
|
59
54
|
|
|
60
55
|
@pytest.fixture(scope='session')
|
|
61
56
|
def redirect_user(request):
|
|
@@ -65,16 +60,11 @@ def redirect_user(request):
|
|
|
65
60
|
@pytest.fixture(scope='session')
|
|
66
61
|
def redirect_password(request):
|
|
67
62
|
return request.config.getoption("--redirect-password")
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
@pytest.fixture(scope='session')
|
|
71
|
-
def app(request):
|
|
72
|
-
return request.config.getoption("--app")
|
|
73
63
|
|
|
74
64
|
|
|
75
65
|
@pytest.fixture(scope='session')
|
|
76
|
-
def
|
|
77
|
-
return request.config.getoption("--
|
|
66
|
+
def app(request):
|
|
67
|
+
return request.config.getoption("--app")
|
|
78
68
|
|
|
79
69
|
|
|
80
70
|
@pytest.fixture(scope='session')
|
|
@@ -115,16 +105,6 @@ def domain(request, distro):
|
|
|
115
105
|
return '{0}.com'.format(distro)
|
|
116
106
|
|
|
117
107
|
|
|
118
|
-
@pytest.fixture(scope='session')
|
|
119
|
-
def browser(request):
|
|
120
|
-
return request.config.getoption("--browser")
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
@pytest.fixture(scope='session')
|
|
124
|
-
def browser_height(request):
|
|
125
|
-
return int(request.config.getoption("--browser-height"))
|
|
126
|
-
|
|
127
|
-
|
|
128
108
|
@pytest.fixture(scope='session')
|
|
129
109
|
def distro(request):
|
|
130
110
|
return request.config.getoption("--distro")
|
|
@@ -141,13 +121,13 @@ def arch(request):
|
|
|
141
121
|
@pytest.fixture(scope='session')
|
|
142
122
|
def app_domain(app, domain):
|
|
143
123
|
return '{0}.{1}'.format(app, domain)
|
|
144
|
-
|
|
124
|
+
|
|
145
125
|
|
|
146
126
|
@pytest.fixture(scope="session")
|
|
147
127
|
def platform_data_dir():
|
|
148
128
|
return get_data_dir('platform')
|
|
149
129
|
|
|
150
|
-
|
|
130
|
+
|
|
151
131
|
@pytest.fixture(scope="session")
|
|
152
132
|
def data_dir(app):
|
|
153
133
|
return get_data_dir(app)
|
|
@@ -161,72 +141,13 @@ def snap_data_dir(app):
|
|
|
161
141
|
@pytest.fixture(scope="session")
|
|
162
142
|
def app_dir(app):
|
|
163
143
|
return get_app_dir(app)
|
|
164
|
-
|
|
144
|
+
|
|
165
145
|
|
|
166
146
|
@pytest.fixture(scope="session")
|
|
167
147
|
def service_prefix():
|
|
168
148
|
return get_service_prefix()
|
|
169
149
|
|
|
170
150
|
|
|
171
|
-
def new_firefox_driver(hub_url, ui_mode):
|
|
172
|
-
mobile_agent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Mobile/15E148 Safari/604.1"
|
|
173
|
-
options = webdriver.FirefoxOptions()
|
|
174
|
-
options.set_preference('app.update.auto', False)
|
|
175
|
-
options.set_preference('app.update.enabled', False)
|
|
176
|
-
if ui_mode == "mobile":
|
|
177
|
-
options.set_preference("general.useragent.override", mobile_agent)
|
|
178
|
-
options.set_preference("devtools.console.stdout.content", True)
|
|
179
|
-
options.set_capability('acceptInsecureCerts', True)
|
|
180
|
-
options.set_capability('se:recordVideo', True)
|
|
181
|
-
options.set_preference("media.navigator.streams.fake", True)
|
|
182
|
-
options.set_preference("media.navigator.permission.disabled", True)
|
|
183
|
-
|
|
184
|
-
return webdriver.Remote(
|
|
185
|
-
command_executor=hub_url,
|
|
186
|
-
options=options
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
def new_chrome_driver(hub_url, ui_mode):
|
|
191
|
-
mobile_agent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Mobile/15E148 Safari/604.1"
|
|
192
|
-
options = webdriver.ChromeOptions()
|
|
193
|
-
if ui_mode == "mobile":
|
|
194
|
-
options.add_argument('user-agent={}'.format(mobile_agent))
|
|
195
|
-
#options.add_argument('--headless')
|
|
196
|
-
options.add_argument('--no-sandbox')
|
|
197
|
-
options.add_argument('--disable-dev-shm-usage')
|
|
198
|
-
options.set_capability('goog:loggingPrefs', {'performance': 'ALL'})
|
|
199
|
-
options.set_capability('acceptInsecureCerts', True)
|
|
200
|
-
options.set_capability('se:recordVideo', True)
|
|
201
|
-
options.add_argument("--use-fake-ui-for-media-stream")
|
|
202
|
-
options.add_argument("--use-fake-device-for-media-stream")
|
|
203
|
-
return webdriver.Remote(
|
|
204
|
-
command_executor=hub_url,
|
|
205
|
-
options=options
|
|
206
|
-
)
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
@pytest.fixture(scope="session")
|
|
210
|
-
def driver(ui_mode, browser, browser_height, request):
|
|
211
|
-
hub_url = 'http://selenium:4444/wd/hub'
|
|
212
|
-
width = 1024
|
|
213
|
-
if ui_mode == "mobile":
|
|
214
|
-
width = 400
|
|
215
|
-
|
|
216
|
-
if browser == "firefox":
|
|
217
|
-
driver = new_firefox_driver(hub_url, ui_mode)
|
|
218
|
-
else:
|
|
219
|
-
driver = new_chrome_driver(hub_url, ui_mode)
|
|
220
|
-
driver.set_window_rect(0, 0, width, browser_height)
|
|
221
|
-
|
|
222
|
-
def driver_quit():
|
|
223
|
-
driver.quit()
|
|
224
|
-
|
|
225
|
-
request.addfinalizer(driver_quit)
|
|
226
|
-
|
|
227
|
-
return driver
|
|
228
|
-
|
|
229
|
-
|
|
230
151
|
@pytest.fixture(scope="session")
|
|
231
152
|
def ssh_env_vars(app):
|
|
232
153
|
return get_ssh_env_vars(app)
|
|
@@ -258,24 +179,3 @@ def artifact_dir(project_dir, distro):
|
|
|
258
179
|
if not exists(artifact_dir):
|
|
259
180
|
os.mkdir(artifact_dir)
|
|
260
181
|
return artifact_dir
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
@pytest.fixture(scope="session")
|
|
264
|
-
def screenshot_dir(artifact_dir: str, ui_mode: str):
|
|
265
|
-
ui_dir = join(artifact_dir, ui_mode)
|
|
266
|
-
if not exists(ui_dir):
|
|
267
|
-
os.mkdir(ui_dir)
|
|
268
|
-
screenshot_dir = join(ui_dir, 'screenshot')
|
|
269
|
-
if not exists(screenshot_dir):
|
|
270
|
-
os.mkdir(screenshot_dir)
|
|
271
|
-
return screenshot_dir
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
@pytest.fixture(scope="session")
|
|
275
|
-
def selenium_timeout():
|
|
276
|
-
return 10
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
@pytest.fixture(scope="session")
|
|
280
|
-
def selenium(driver, ui_mode, screenshot_dir, app_domain, selenium_timeout, browser):
|
|
281
|
-
return SeleniumWrapper(driver, ui_mode, screenshot_dir, app_domain, selenium_timeout, browser)
|
|
@@ -42,6 +42,8 @@ class Device:
|
|
|
42
42
|
def activate_custom(self, channel="stable"):
|
|
43
43
|
ip = socket.gethostbyname(self.domain)
|
|
44
44
|
run_ssh(self.domain, 'echo "{0} auth.{1}" >> /etc/hosts'.format(ip, self.domain), password=self.ssh_password, retries=10)
|
|
45
|
+
run_ssh(self.domain, 'snap set system refresh.hold=$(date -d "+90 days" -u +%Y-%m-%dT%H:%M:%SZ)', password=self.ssh_password)
|
|
46
|
+
run_ssh(self.domain, 'rm -f /var/snap/platform/current/syncloud.crt', password=self.ssh_password)
|
|
45
47
|
|
|
46
48
|
wait_for_rest(requests.session(), "https://{0}/rest/id".format(self.domain), 200, 10)
|
|
47
49
|
response = requests.post('https://{0}/rest/activate/custom'.format(self.domain),
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from os.path import join, exists
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
from selenium import webdriver
|
|
6
|
+
|
|
7
|
+
from syncloudlib.integration.conftest import pytest_addoption as _base_pytest_addoption
|
|
8
|
+
from syncloudlib.integration.selenium_wrapper import SeleniumWrapper
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def pytest_addoption(parser):
|
|
12
|
+
_base_pytest_addoption(parser)
|
|
13
|
+
parser.addoption("--ui-mode", action="store", default="desktop")
|
|
14
|
+
parser.addoption("--browser", action="store", default="firefox")
|
|
15
|
+
parser.addoption("--browser-height", action="store", default=2000)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.fixture(scope='session')
|
|
19
|
+
def ui_mode(request):
|
|
20
|
+
return request.config.getoption("--ui-mode")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@pytest.fixture(scope='session')
|
|
24
|
+
def browser(request):
|
|
25
|
+
return request.config.getoption("--browser")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@pytest.fixture(scope='session')
|
|
29
|
+
def browser_height(request):
|
|
30
|
+
return int(request.config.getoption("--browser-height"))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def new_firefox_driver(hub_url, ui_mode):
|
|
34
|
+
mobile_agent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Mobile/15E148 Safari/604.1"
|
|
35
|
+
options = webdriver.FirefoxOptions()
|
|
36
|
+
options.set_preference('app.update.auto', False)
|
|
37
|
+
options.set_preference('app.update.enabled', False)
|
|
38
|
+
if ui_mode == "mobile":
|
|
39
|
+
options.set_preference("general.useragent.override", mobile_agent)
|
|
40
|
+
options.set_preference("devtools.console.stdout.content", True)
|
|
41
|
+
options.set_capability('acceptInsecureCerts', True)
|
|
42
|
+
options.set_capability('se:recordVideo', True)
|
|
43
|
+
options.set_preference("media.navigator.streams.fake", True)
|
|
44
|
+
options.set_preference("media.navigator.permission.disabled", True)
|
|
45
|
+
|
|
46
|
+
return webdriver.Remote(
|
|
47
|
+
command_executor=hub_url,
|
|
48
|
+
options=options
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def new_chrome_driver(hub_url, ui_mode):
|
|
53
|
+
mobile_agent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Mobile/15E148 Safari/604.1"
|
|
54
|
+
options = webdriver.ChromeOptions()
|
|
55
|
+
if ui_mode == "mobile":
|
|
56
|
+
options.add_argument('user-agent={}'.format(mobile_agent))
|
|
57
|
+
options.add_argument('--no-sandbox')
|
|
58
|
+
options.add_argument('--disable-dev-shm-usage')
|
|
59
|
+
options.set_capability('goog:loggingPrefs', {'performance': 'ALL'})
|
|
60
|
+
options.set_capability('acceptInsecureCerts', True)
|
|
61
|
+
options.set_capability('se:recordVideo', True)
|
|
62
|
+
options.add_argument("--use-fake-ui-for-media-stream")
|
|
63
|
+
options.add_argument("--use-fake-device-for-media-stream")
|
|
64
|
+
return webdriver.Remote(
|
|
65
|
+
command_executor=hub_url,
|
|
66
|
+
options=options
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@pytest.fixture(scope="session")
|
|
71
|
+
def driver(ui_mode, browser, browser_height, request):
|
|
72
|
+
hub_url = 'http://selenium:4444/wd/hub'
|
|
73
|
+
width = 1024
|
|
74
|
+
if ui_mode == "mobile":
|
|
75
|
+
width = 400
|
|
76
|
+
|
|
77
|
+
if browser == "firefox":
|
|
78
|
+
driver = new_firefox_driver(hub_url, ui_mode)
|
|
79
|
+
else:
|
|
80
|
+
driver = new_chrome_driver(hub_url, ui_mode)
|
|
81
|
+
driver.set_window_rect(0, 0, width, browser_height)
|
|
82
|
+
|
|
83
|
+
def driver_quit():
|
|
84
|
+
driver.quit()
|
|
85
|
+
|
|
86
|
+
request.addfinalizer(driver_quit)
|
|
87
|
+
|
|
88
|
+
return driver
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@pytest.fixture(scope="session")
|
|
92
|
+
def screenshot_dir(artifact_dir, ui_mode):
|
|
93
|
+
ui_dir = join(artifact_dir, ui_mode)
|
|
94
|
+
if not exists(ui_dir):
|
|
95
|
+
os.mkdir(ui_dir)
|
|
96
|
+
screenshot_dir = join(ui_dir, 'screenshot')
|
|
97
|
+
if not exists(screenshot_dir):
|
|
98
|
+
os.mkdir(screenshot_dir)
|
|
99
|
+
return screenshot_dir
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@pytest.fixture(scope="session")
|
|
103
|
+
def selenium_timeout():
|
|
104
|
+
return 10
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@pytest.fixture(scope="session")
|
|
108
|
+
def selenium(driver, ui_mode, screenshot_dir, app_domain, selenium_timeout, browser):
|
|
109
|
+
return SeleniumWrapper(driver, ui_mode, screenshot_dir, app_domain, selenium_timeout, browser)
|
syncloud_lib-366/version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
366
|
syncloud_lib-364/version
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
364
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|