mops 3.4.2__tar.gz → 3.4.3__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.
- {mops-3.4.2 → mops-3.4.3}/PKG-INFO +1 -1
- {mops-3.4.2 → mops-3.4.3}/mops/__init__.py +1 -1
- {mops-3.4.2 → mops-3.4.3}/mops/abstraction/driver_wrapper_abc.py +100 -0
- {mops-3.4.2 → mops-3.4.3}/mops/base/driver_wrapper.py +108 -0
- {mops-3.4.2 → mops-3.4.3}/mops/js_scripts.py +14 -0
- {mops-3.4.2 → mops-3.4.3}/mops/playwright/play_driver.py +13 -20
- {mops-3.4.2 → mops-3.4.3}/mops/selenium/core/core_driver.py +3 -8
- {mops-3.4.2 → mops-3.4.3}/mops/selenium/driver/mobile_driver.py +14 -0
- {mops-3.4.2 → mops-3.4.3}/mops.egg-info/PKG-INFO +1 -1
- {mops-3.4.2 → mops-3.4.3}/README.md +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/abstraction/element_abc.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/abstraction/mixin_abc.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/abstraction/page_abc.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/base/element.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/base/group.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/base/page.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/exceptions.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/keyboard_keys.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/mixins/capabilities.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/mixins/driver_mixin.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/mixins/internal_mixin.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/mixins/native_context.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/mixins/objects/box.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/mixins/objects/driver.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/mixins/objects/location.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/mixins/objects/locator.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/mixins/objects/locator_type.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/mixins/objects/scrolls.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/mixins/objects/size.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/mixins/objects/visual_comaprison_mixin.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/mixins/objects/wait_result.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/playwright/play_element.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/playwright/play_page.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/selenium/core/core_element.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/selenium/core/core_page.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/selenium/driver/web_driver.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/selenium/elements/mobile_element.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/selenium/elements/web_element.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/selenium/pages/mobile_page.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/selenium/pages/web_page.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/selenium/sel_utils.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/shared_utils.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/utils/decorators.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/utils/internal_utils.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/utils/logs.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/utils/previous_object_driver.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/utils/selector_synchronizer.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops/visual_comparison.py +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops.egg-info/SOURCES.txt +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops.egg-info/dependency_links.txt +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops.egg-info/requires.txt +0 -0
- {mops-3.4.2 → mops-3.4.3}/mops.egg-info/top_level.txt +0 -0
- {mops-3.4.2 → mops-3.4.3}/pyproject.toml +0 -0
- {mops-3.4.2 → mops-3.4.3}/setup.cfg +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = '3.4.
|
|
1
|
+
__version__ = '3.4.3'
|
|
2
2
|
__project_name__ = 'mops'
|
|
@@ -207,6 +207,106 @@ class DriverWrapperABC(ABC):
|
|
|
207
207
|
"""
|
|
208
208
|
raise NotImplementedError()
|
|
209
209
|
|
|
210
|
+
def set_local_storage_item(self, items: List[dict]) -> DriverWrapper:
|
|
211
|
+
"""
|
|
212
|
+
Set one or more items in localStorage.
|
|
213
|
+
|
|
214
|
+
Each dict must contain ``key`` and ``value`` fields.
|
|
215
|
+
|
|
216
|
+
:param items: A list of dicts with ``key`` and ``value``.
|
|
217
|
+
:type items: typing.List[dict]
|
|
218
|
+
:return: :obj:`.DriverWrapper` - The current instance of the driver wrapper.
|
|
219
|
+
"""
|
|
220
|
+
raise NotImplementedError()
|
|
221
|
+
|
|
222
|
+
def set_session_storage_item(self, items: List[dict]) -> DriverWrapper:
|
|
223
|
+
"""
|
|
224
|
+
Set one or more items in sessionStorage.
|
|
225
|
+
|
|
226
|
+
Each dict must contain ``key`` and ``value`` fields.
|
|
227
|
+
|
|
228
|
+
:param items: A list of dicts with ``key`` and ``value``.
|
|
229
|
+
:type items: typing.List[dict]
|
|
230
|
+
:return: :obj:`.DriverWrapper` - The current instance of the driver wrapper.
|
|
231
|
+
"""
|
|
232
|
+
raise NotImplementedError()
|
|
233
|
+
|
|
234
|
+
def get_local_storage_item(self, key: str) -> Union[str, None]:
|
|
235
|
+
"""
|
|
236
|
+
Retrieve a single item from localStorage by key.
|
|
237
|
+
|
|
238
|
+
:param key: The key to look up.
|
|
239
|
+
:type key: str
|
|
240
|
+
:return: The value string, or :obj:`None` if the key does not exist.
|
|
241
|
+
:rtype: typing.Union[str, None]
|
|
242
|
+
"""
|
|
243
|
+
raise NotImplementedError()
|
|
244
|
+
|
|
245
|
+
def get_session_storage_item(self, key: str) -> Union[str, None]:
|
|
246
|
+
"""
|
|
247
|
+
Retrieve a single item from sessionStorage by key.
|
|
248
|
+
|
|
249
|
+
:param key: The key to look up.
|
|
250
|
+
:type key: str
|
|
251
|
+
:return: The value string, or :obj:`None` if the key does not exist.
|
|
252
|
+
:rtype: typing.Union[str, None]
|
|
253
|
+
"""
|
|
254
|
+
raise NotImplementedError()
|
|
255
|
+
|
|
256
|
+
def get_local_storage_items(self) -> dict:
|
|
257
|
+
"""
|
|
258
|
+
Retrieve all items from localStorage as a dictionary.
|
|
259
|
+
|
|
260
|
+
:return: A dict mapping every key to its value.
|
|
261
|
+
:rtype: dict
|
|
262
|
+
"""
|
|
263
|
+
raise NotImplementedError()
|
|
264
|
+
|
|
265
|
+
def get_session_storage_items(self) -> dict:
|
|
266
|
+
"""
|
|
267
|
+
Retrieve all items from sessionStorage as a dictionary.
|
|
268
|
+
|
|
269
|
+
:return: A dict mapping every key to its value.
|
|
270
|
+
:rtype: dict
|
|
271
|
+
"""
|
|
272
|
+
raise NotImplementedError()
|
|
273
|
+
|
|
274
|
+
def remove_local_storage_item(self, key: str) -> DriverWrapper:
|
|
275
|
+
"""
|
|
276
|
+
Remove a single item from localStorage by key.
|
|
277
|
+
|
|
278
|
+
:param key: The key to remove.
|
|
279
|
+
:type key: str
|
|
280
|
+
:return: :obj:`.DriverWrapper` - The current instance of the driver wrapper.
|
|
281
|
+
"""
|
|
282
|
+
raise NotImplementedError()
|
|
283
|
+
|
|
284
|
+
def remove_session_storage_item(self, key: str) -> DriverWrapper:
|
|
285
|
+
"""
|
|
286
|
+
Remove a single item from sessionStorage by key.
|
|
287
|
+
|
|
288
|
+
:param key: The key to remove.
|
|
289
|
+
:type key: str
|
|
290
|
+
:return: :obj:`.DriverWrapper` - The current instance of the driver wrapper.
|
|
291
|
+
"""
|
|
292
|
+
raise NotImplementedError()
|
|
293
|
+
|
|
294
|
+
def clear_local_storage(self) -> DriverWrapper:
|
|
295
|
+
"""
|
|
296
|
+
Remove all items from localStorage.
|
|
297
|
+
|
|
298
|
+
:return: :obj:`.DriverWrapper` - The current instance of the driver wrapper.
|
|
299
|
+
"""
|
|
300
|
+
raise NotImplementedError()
|
|
301
|
+
|
|
302
|
+
def clear_session_storage(self) -> DriverWrapper:
|
|
303
|
+
"""
|
|
304
|
+
Remove all items from sessionStorage.
|
|
305
|
+
|
|
306
|
+
:return: :obj:`.DriverWrapper` - The current instance of the driver wrapper.
|
|
307
|
+
"""
|
|
308
|
+
raise NotImplementedError()
|
|
309
|
+
|
|
210
310
|
def switch_to_frame(self, frame: Element) -> DriverWrapper:
|
|
211
311
|
"""
|
|
212
312
|
Switch to a specified frame.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import json
|
|
3
4
|
from typing import Union, Type, List, Tuple, TYPE_CHECKING
|
|
4
5
|
|
|
5
6
|
from PIL import Image
|
|
@@ -11,6 +12,7 @@ from playwright.sync_api import (
|
|
|
11
12
|
BrowserContext as PlaywrightContext,
|
|
12
13
|
)
|
|
13
14
|
|
|
15
|
+
from mops.js_scripts import storage_set_item_js, storage_get_items_js
|
|
14
16
|
from mops.mixins.objects.box import Box
|
|
15
17
|
from mops.mixins.objects.driver import Driver
|
|
16
18
|
from mops.mixins.objects.visual_comaprison_mixin import hide_before_screenshot, reveal_after_screenshot
|
|
@@ -332,6 +334,112 @@ class DriverWrapper(InternalMixin, Logging, DriverWrapperABC):
|
|
|
332
334
|
|
|
333
335
|
return True, f'No visual mismatch found for entire screen'
|
|
334
336
|
|
|
337
|
+
def set_local_storage_item(self, items: List[dict]) -> DriverWrapper:
|
|
338
|
+
"""
|
|
339
|
+
Set one or more items in localStorage.
|
|
340
|
+
|
|
341
|
+
Each dict must contain ``key`` and ``value`` fields.
|
|
342
|
+
|
|
343
|
+
:param items: A list of dicts with ``key`` and ``value``.
|
|
344
|
+
:type items: typing.List[dict]
|
|
345
|
+
:return: :obj:`.DriverWrapper` - The current instance of the driver wrapper.
|
|
346
|
+
"""
|
|
347
|
+
self.execute_script(storage_set_item_js, items, 'localStorage')
|
|
348
|
+
return self
|
|
349
|
+
|
|
350
|
+
def set_session_storage_item(self, items: List[dict]) -> DriverWrapper:
|
|
351
|
+
"""
|
|
352
|
+
Set one or more items in sessionStorage.
|
|
353
|
+
|
|
354
|
+
Each dict must contain ``key`` and ``value`` fields.
|
|
355
|
+
|
|
356
|
+
:param items: A list of dicts with ``key`` and ``value``.
|
|
357
|
+
:type items: typing.List[dict]
|
|
358
|
+
:return: :obj:`.DriverWrapper` - The current instance of the driver wrapper.
|
|
359
|
+
"""
|
|
360
|
+
self.execute_script(storage_set_item_js, items, 'sessionStorage')
|
|
361
|
+
return self
|
|
362
|
+
|
|
363
|
+
def get_local_storage_item(self, key: str) -> Union[str, None]:
|
|
364
|
+
"""
|
|
365
|
+
Retrieve a single item from localStorage by key.
|
|
366
|
+
|
|
367
|
+
:param key: The key to look up.
|
|
368
|
+
:type key: str
|
|
369
|
+
:return: The value string, or :obj:`None` if the key does not exist.
|
|
370
|
+
:rtype: typing.Union[str, None]
|
|
371
|
+
"""
|
|
372
|
+
return self.execute_script(f'return localStorage.getItem({json.dumps(key)})')
|
|
373
|
+
|
|
374
|
+
def get_session_storage_item(self, key: str) -> Union[str, None]:
|
|
375
|
+
"""
|
|
376
|
+
Retrieve a single item from sessionStorage by key.
|
|
377
|
+
|
|
378
|
+
:param key: The key to look up.
|
|
379
|
+
:type key: str
|
|
380
|
+
:return: The value string, or :obj:`None` if the key does not exist.
|
|
381
|
+
:rtype: typing.Union[str, None]
|
|
382
|
+
"""
|
|
383
|
+
return self.execute_script(f'return sessionStorage.getItem({json.dumps(key)})')
|
|
384
|
+
|
|
385
|
+
def get_local_storage_items(self) -> dict:
|
|
386
|
+
"""
|
|
387
|
+
Retrieve all items from localStorage as a dictionary.
|
|
388
|
+
|
|
389
|
+
:return: A dict mapping every key to its value.
|
|
390
|
+
:rtype: dict
|
|
391
|
+
"""
|
|
392
|
+
return self.execute_script(storage_get_items_js, 'localStorage')
|
|
393
|
+
|
|
394
|
+
def get_session_storage_items(self) -> dict:
|
|
395
|
+
"""
|
|
396
|
+
Retrieve all items from sessionStorage as a dictionary.
|
|
397
|
+
|
|
398
|
+
:return: A dict mapping every key to its value.
|
|
399
|
+
:rtype: dict
|
|
400
|
+
"""
|
|
401
|
+
return self.execute_script(storage_get_items_js, 'sessionStorage')
|
|
402
|
+
|
|
403
|
+
def remove_local_storage_item(self, key: str) -> DriverWrapper:
|
|
404
|
+
"""
|
|
405
|
+
Remove a single item from localStorage by key.
|
|
406
|
+
|
|
407
|
+
:param key: The key to remove.
|
|
408
|
+
:type key: str
|
|
409
|
+
:return: :obj:`.DriverWrapper` - The current instance of the driver wrapper.
|
|
410
|
+
"""
|
|
411
|
+
self.execute_script(f'localStorage.removeItem({json.dumps(key)})')
|
|
412
|
+
return self
|
|
413
|
+
|
|
414
|
+
def remove_session_storage_item(self, key: str) -> DriverWrapper:
|
|
415
|
+
"""
|
|
416
|
+
Remove a single item from sessionStorage by key.
|
|
417
|
+
|
|
418
|
+
:param key: The key to remove.
|
|
419
|
+
:type key: str
|
|
420
|
+
:return: :obj:`.DriverWrapper` - The current instance of the driver wrapper.
|
|
421
|
+
"""
|
|
422
|
+
self.execute_script(f'sessionStorage.removeItem({json.dumps(key)})')
|
|
423
|
+
return self
|
|
424
|
+
|
|
425
|
+
def clear_local_storage(self) -> DriverWrapper:
|
|
426
|
+
"""
|
|
427
|
+
Remove all items from localStorage.
|
|
428
|
+
|
|
429
|
+
:return: :obj:`.DriverWrapper` - The current instance of the driver wrapper.
|
|
430
|
+
"""
|
|
431
|
+
self.execute_script('localStorage.clear()')
|
|
432
|
+
return self
|
|
433
|
+
|
|
434
|
+
def clear_session_storage(self) -> DriverWrapper:
|
|
435
|
+
"""
|
|
436
|
+
Remove all items from sessionStorage.
|
|
437
|
+
|
|
438
|
+
:return: :obj:`.DriverWrapper` - The current instance of the driver wrapper.
|
|
439
|
+
"""
|
|
440
|
+
self.execute_script('sessionStorage.clear()')
|
|
441
|
+
return self
|
|
442
|
+
|
|
335
443
|
def __init_base_class__(self) -> None:
|
|
336
444
|
"""
|
|
337
445
|
Get driver wrapper class in according to given driver source, and set him as base class
|
|
@@ -2,6 +2,20 @@ get_inner_height_js = 'return window.innerHeight'
|
|
|
2
2
|
get_inner_width_js = 'return window.innerWidth'
|
|
3
3
|
js_click = 'arguments[0].click();'
|
|
4
4
|
|
|
5
|
+
storage_set_item_js = """
|
|
6
|
+
arguments[0].forEach(item => {
|
|
7
|
+
window[arguments[1]].setItem(item.key, item.value);
|
|
8
|
+
});
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
storage_get_items_js = "return Object.assign({}, window[arguments[0]])"
|
|
12
|
+
|
|
13
|
+
set_cookies_as_batch_js = """
|
|
14
|
+
arguments[0].forEach(c => {
|
|
15
|
+
document.cookie = `${c.name}=${c.value}; path=${c.path}`;
|
|
16
|
+
});
|
|
17
|
+
"""
|
|
18
|
+
|
|
5
19
|
get_element_position_on_screen_js = """
|
|
6
20
|
function getPositionOnScreen(elem) {
|
|
7
21
|
let box = elem.getBoundingClientRect();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import asdict
|
|
4
|
+
from urllib.parse import urlparse
|
|
4
5
|
from functools import cached_property
|
|
5
6
|
from typing import List, Union, Any, TYPE_CHECKING
|
|
6
7
|
|
|
@@ -193,15 +194,15 @@ class PlayDriver(Logging, DriverWrapperABC):
|
|
|
193
194
|
:type cookies: typing.List[dict]
|
|
194
195
|
:return: :obj:`.PlayDriver` - The current instance of the driver wrapper.
|
|
195
196
|
"""
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
self.context.add_cookies(
|
|
197
|
+
domain = f'.{urlparse(self.current_url).netloc}'
|
|
198
|
+
processed = [
|
|
199
|
+
{
|
|
200
|
+
**c,
|
|
201
|
+
'path': c.get('path', '/'),
|
|
202
|
+
'domain': c.get('domain', domain)
|
|
203
|
+
} for c in cookies
|
|
204
|
+
]
|
|
205
|
+
self.context.add_cookies(processed) # noqa
|
|
205
206
|
return self
|
|
206
207
|
|
|
207
208
|
def clear_cookies(self) -> PlayDriver:
|
|
@@ -262,17 +263,9 @@ class PlayDriver(Logging, DriverWrapperABC):
|
|
|
262
263
|
:type args: :obj:`typing.Any`
|
|
263
264
|
:return: :obj:`typing.Any` - The result of the JavaScript execution.
|
|
264
265
|
"""
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
args = [getattr(arg, 'element', arg) for arg in args]
|
|
269
|
-
script = f'arguments => {{{script}}}'
|
|
270
|
-
|
|
271
|
-
for index, arg in enumerate(args):
|
|
272
|
-
if isinstance(arg, Locator):
|
|
273
|
-
args[index] = arg.first.element_handle()
|
|
274
|
-
|
|
275
|
-
return self.driver.evaluate(script, args)
|
|
266
|
+
args = [getattr(arg, 'element', arg) for arg in args]
|
|
267
|
+
args = [arg.first.element_handle() if isinstance(arg, Locator) else arg for arg in args]
|
|
268
|
+
return self.driver.evaluate(f'(args) => (function() {{ {script} }}).apply(null, args)', list(args))
|
|
276
269
|
|
|
277
270
|
def evaluate(self, expression: str, arg: Any = None) -> Any:
|
|
278
271
|
"""
|
|
@@ -7,7 +7,7 @@ from typing import Union, List, Any, TYPE_CHECKING
|
|
|
7
7
|
from PIL import Image
|
|
8
8
|
from appium.webdriver.webdriver import WebDriver as AppiumDriver
|
|
9
9
|
|
|
10
|
-
from mops.js_scripts import get_inner_height_js, get_inner_width_js
|
|
10
|
+
from mops.js_scripts import get_inner_height_js, get_inner_width_js, set_cookies_as_batch_js
|
|
11
11
|
from mops.mixins.objects.size import Size
|
|
12
12
|
from mops.shared_utils import _scaled_screenshot
|
|
13
13
|
from selenium.common.exceptions import WebDriverException as SeleniumWebDriverException, NoAlertPresentException
|
|
@@ -235,13 +235,8 @@ class CoreDriver(Logging, DriverWrapperABC):
|
|
|
235
235
|
:type cookies: typing.List[dict]
|
|
236
236
|
:return: :obj:`.CoreDriver` - The current instance of the driver wrapper.
|
|
237
237
|
"""
|
|
238
|
-
for
|
|
239
|
-
|
|
240
|
-
if 'path' not in cookie:
|
|
241
|
-
cookie.update({'path': '/'})
|
|
242
|
-
|
|
243
|
-
self.driver.add_cookie(cookie)
|
|
244
|
-
|
|
238
|
+
processed = [{**c, 'path': c.get('path', '/')} for c in cookies]
|
|
239
|
+
self.driver.execute_script(set_cookies_as_batch_js, processed)
|
|
245
240
|
return self
|
|
246
241
|
|
|
247
242
|
def clear_cookies(self) -> CoreDriver:
|
|
@@ -263,6 +263,20 @@ class MobileDriver(CoreDriver):
|
|
|
263
263
|
|
|
264
264
|
return self
|
|
265
265
|
|
|
266
|
+
def clear_cookies(self) -> MobileDriver:
|
|
267
|
+
"""
|
|
268
|
+
Delete all cookies in the current session.
|
|
269
|
+
|
|
270
|
+
:return: :obj:`.MobileDriver` - The current instance of the driver wrapper.
|
|
271
|
+
"""
|
|
272
|
+
if self.is_ios and self.is_real_device:
|
|
273
|
+
for cookie_name in [cookie['name'] for cookie in self.get_cookies()]:
|
|
274
|
+
self.delete_cookie(cookie_name)
|
|
275
|
+
else:
|
|
276
|
+
CoreDriver.clear_cookies(self)
|
|
277
|
+
|
|
278
|
+
return self
|
|
279
|
+
|
|
266
280
|
|
|
267
281
|
def _set_static(obj) -> None:
|
|
268
282
|
"""
|
|
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
|