pydoll-python 2.1.0__tar.gz → 2.2.0__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.
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/PKG-INFO +4 -4
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/README.md +2 -2
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/chromium/base.py +20 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/tab.py +88 -12
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pyproject.toml +3 -3
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/LICENSE +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/chromium/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/chromium/chrome.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/chromium/edge.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/interfaces.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/managers/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/managers/browser_options_manager.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/managers/browser_process_manager.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/managers/proxy_manager.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/managers/temp_dir_manager.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/options.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/commands/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/commands/browser_commands.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/commands/dom_commands.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/commands/fetch_commands.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/commands/input_commands.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/commands/network_commands.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/commands/page_commands.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/commands/runtime_commands.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/commands/storage_commands.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/commands/target_commands.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/connection/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/connection/connection_handler.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/connection/managers/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/connection/managers/commands_manager.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/connection/managers/events_manager.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/constants.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/elements/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/elements/mixins/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/elements/mixins/find_elements_mixin.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/elements/web_element.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/exceptions.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/base.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/browser/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/browser/events.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/browser/methods.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/browser/params.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/browser/responses.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/browser/types.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/dom/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/dom/events.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/dom/methods.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/dom/params.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/dom/responses.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/dom/types.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/fetch/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/fetch/events.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/fetch/methods.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/fetch/params.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/fetch/responses.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/fetch/types.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/input/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/input/events.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/input/methods.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/input/params.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/input/types.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/network/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/network/events.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/network/methods.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/network/params.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/network/responses.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/network/types.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/page/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/page/events.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/page/methods.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/page/params.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/page/responses.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/page/types.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/runtime/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/runtime/events.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/runtime/methods.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/runtime/params.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/runtime/responses.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/runtime/types.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/storage/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/storage/events.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/storage/methods.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/storage/params.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/storage/responses.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/storage/types.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/target/__init__.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/target/events.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/target/methods.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/target/params.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/target/responses.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/protocol/target/types.py +0 -0
- {pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pydoll-python
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Thalison Fernandes
|
|
6
6
|
Author-email: thalissfernandes99@gmail.com
|
|
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.13
|
|
13
13
|
Requires-Dist: aiofiles (>=23.2.1,<24.0.0)
|
|
14
14
|
Requires-Dist: aiohttp (>=3.9.5,<4.0.0)
|
|
15
|
-
Requires-Dist:
|
|
15
|
+
Requires-Dist: beautifulsoup4 (>=4.12.3,<5.0.0)
|
|
16
16
|
Requires-Dist: mkdocstrings (>=0.29.1,<0.30.0)
|
|
17
17
|
Requires-Dist: websockets (>=13.1,<14.0)
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
@@ -22,8 +22,8 @@ Description-Content-Type: text/markdown
|
|
|
22
22
|
</p>
|
|
23
23
|
|
|
24
24
|
<p align="center">
|
|
25
|
-
<a href="https://codecov.io/gh/autoscrape-labs/pydoll">
|
|
26
|
-
<img src="https://codecov.io/gh/autoscrape-labs/pydoll/graph/badge.svg?token=40I938OGM9"/>
|
|
25
|
+
<a href="https://codecov.io/gh/autoscrape-labs/pydoll" >
|
|
26
|
+
<img src="https://codecov.io/gh/autoscrape-labs/pydoll/graph/badge.svg?token=40I938OGM9"/>
|
|
27
27
|
</a>
|
|
28
28
|
<img src="https://github.com/thalissonvs/pydoll/actions/workflows/tests.yml/badge.svg" alt="Tests">
|
|
29
29
|
<img src="https://github.com/thalissonvs/pydoll/actions/workflows/ruff-ci.yml/badge.svg" alt="Ruff CI">
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<a href="https://codecov.io/gh/autoscrape-labs/pydoll">
|
|
7
|
-
<img src="https://codecov.io/gh/autoscrape-labs/pydoll/graph/badge.svg?token=40I938OGM9"/>
|
|
6
|
+
<a href="https://codecov.io/gh/autoscrape-labs/pydoll" >
|
|
7
|
+
<img src="https://codecov.io/gh/autoscrape-labs/pydoll/graph/badge.svg?token=40I938OGM9"/>
|
|
8
8
|
</a>
|
|
9
9
|
<img src="https://github.com/thalissonvs/pydoll/actions/workflows/tests.yml/badge.svg" alt="Tests">
|
|
10
10
|
<img src="https://github.com/thalissonvs/pydoll/actions/workflows/ruff-ci.yml/badge.svg" alt="Ruff CI">
|
|
@@ -215,10 +215,30 @@ class Browser(ABC): # noqa: PLR0904
|
|
|
215
215
|
|
|
216
216
|
Targets include pages, service workers, shared workers, and browser process.
|
|
217
217
|
Useful for debugging and managing multiple tabs.
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
List of TargetInfo objects.
|
|
218
221
|
"""
|
|
219
222
|
response: GetTargetsResponse = await self._execute_command(TargetCommands.get_targets())
|
|
220
223
|
return response['result']['targetInfos']
|
|
221
224
|
|
|
225
|
+
async def get_opened_tabs(self) -> list[Tab]:
|
|
226
|
+
"""
|
|
227
|
+
Get all opened tabs that are not extensions and have the type 'page'
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
List of Tab instances. The last tab is the most recent one.
|
|
231
|
+
"""
|
|
232
|
+
targets = await self.get_targets()
|
|
233
|
+
valid_tab_targets = [
|
|
234
|
+
target for target in targets if target['type'] == 'page'
|
|
235
|
+
and 'extension' not in target['url']
|
|
236
|
+
]
|
|
237
|
+
return [
|
|
238
|
+
Tab(self, self._connection_port, target['targetId']) for target
|
|
239
|
+
in reversed(valid_tab_targets)
|
|
240
|
+
]
|
|
241
|
+
|
|
222
242
|
async def set_download_path(self, path: str, browser_context_id: Optional[str] = None):
|
|
223
243
|
"""Set download directory path (convenience method for set_download_behavior)."""
|
|
224
244
|
return await self._execute_command(
|
|
@@ -68,8 +68,43 @@ class Tab(FindElementsMixin): # noqa: PLR0904
|
|
|
68
68
|
Primary interface for web page automation including navigation, DOM manipulation,
|
|
69
69
|
JavaScript execution, event handling, network monitoring, and specialized tasks
|
|
70
70
|
like Cloudflare bypass.
|
|
71
|
+
|
|
72
|
+
This class implements a singleton pattern based on target_id to ensure
|
|
73
|
+
only one Tab instance exists per browser tab.
|
|
71
74
|
"""
|
|
72
75
|
|
|
76
|
+
_instances: dict[str, 'Tab'] = {}
|
|
77
|
+
|
|
78
|
+
def __new__(
|
|
79
|
+
cls,
|
|
80
|
+
browser: 'Browser',
|
|
81
|
+
connection_port: int,
|
|
82
|
+
target_id: str,
|
|
83
|
+
browser_context_id: Optional[str] = None,
|
|
84
|
+
) -> 'Tab':
|
|
85
|
+
"""
|
|
86
|
+
Create or return existing Tab instance for the given target_id.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
browser: Browser instance that created this tab.
|
|
90
|
+
connection_port: CDP WebSocket port.
|
|
91
|
+
target_id: CDP target identifier for this tab.
|
|
92
|
+
browser_context_id: Optional browser context ID.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
Tab instance (new or existing) for the target_id.
|
|
96
|
+
"""
|
|
97
|
+
if target_id in cls._instances:
|
|
98
|
+
existing_instance = cls._instances[target_id]
|
|
99
|
+
existing_instance._browser = browser
|
|
100
|
+
existing_instance._connection_port = connection_port
|
|
101
|
+
existing_instance._browser_context_id = browser_context_id
|
|
102
|
+
return existing_instance
|
|
103
|
+
|
|
104
|
+
instance = super().__new__(cls)
|
|
105
|
+
cls._instances[target_id] = instance
|
|
106
|
+
return instance
|
|
107
|
+
|
|
73
108
|
def __init__(
|
|
74
109
|
self,
|
|
75
110
|
browser: 'Browser',
|
|
@@ -86,18 +121,57 @@ class Tab(FindElementsMixin): # noqa: PLR0904
|
|
|
86
121
|
target_id: CDP target identifier for this tab.
|
|
87
122
|
browser_context_id: Optional browser context ID.
|
|
88
123
|
"""
|
|
89
|
-
self
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
self.
|
|
93
|
-
self.
|
|
94
|
-
self.
|
|
95
|
-
self.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
self.
|
|
124
|
+
if hasattr(self, '_initialized') and self._initialized:
|
|
125
|
+
return
|
|
126
|
+
|
|
127
|
+
self._browser: 'Browser' = browser
|
|
128
|
+
self._connection_port: int = connection_port
|
|
129
|
+
self._target_id: str = target_id
|
|
130
|
+
self._connection_handler: ConnectionHandler = ConnectionHandler(
|
|
131
|
+
connection_port, self._target_id
|
|
132
|
+
)
|
|
133
|
+
self._page_events_enabled: bool = False
|
|
134
|
+
self._network_events_enabled: bool = False
|
|
135
|
+
self._fetch_events_enabled: bool = False
|
|
136
|
+
self._dom_events_enabled: bool = False
|
|
137
|
+
self._runtime_events_enabled: bool = False
|
|
138
|
+
self._intercept_file_chooser_dialog_enabled: bool = False
|
|
99
139
|
self._cloudflare_captcha_callback_id: Optional[int] = None
|
|
100
|
-
self._browser_context_id = browser_context_id
|
|
140
|
+
self._browser_context_id: Optional[str] = browser_context_id
|
|
141
|
+
self._initialized: bool = True
|
|
142
|
+
|
|
143
|
+
@classmethod
|
|
144
|
+
def _remove_instance(cls, target_id: str) -> None:
|
|
145
|
+
"""
|
|
146
|
+
Remove instance from registry when tab is closed.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
target_id: Target ID to remove from registry.
|
|
150
|
+
"""
|
|
151
|
+
cls._instances.pop(target_id, None)
|
|
152
|
+
|
|
153
|
+
@classmethod
|
|
154
|
+
def get_instance(cls, target_id: str) -> Optional['Tab']:
|
|
155
|
+
"""
|
|
156
|
+
Get existing Tab instance for target_id if it exists.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
target_id: Target ID to look up.
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
Existing Tab instance or None if not found.
|
|
163
|
+
"""
|
|
164
|
+
return cls._instances.get(target_id)
|
|
165
|
+
|
|
166
|
+
@classmethod
|
|
167
|
+
def get_all_instances(cls) -> dict[str, 'Tab']:
|
|
168
|
+
"""
|
|
169
|
+
Get all active Tab instances.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
Dictionary mapping target_id to Tab instances.
|
|
173
|
+
"""
|
|
174
|
+
return cls._instances.copy()
|
|
101
175
|
|
|
102
176
|
@property
|
|
103
177
|
def page_events_enabled(self) -> bool:
|
|
@@ -283,7 +357,9 @@ class Tab(FindElementsMixin): # noqa: PLR0904
|
|
|
283
357
|
Note:
|
|
284
358
|
Tab instance becomes invalid after calling this method.
|
|
285
359
|
"""
|
|
286
|
-
|
|
360
|
+
result = await self._execute_command(PageCommands.close())
|
|
361
|
+
self._remove_instance(self._target_id)
|
|
362
|
+
return result
|
|
287
363
|
|
|
288
364
|
async def get_frame(self, frame: WebElement) -> IFrame:
|
|
289
365
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "pydoll-python"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.2.0"
|
|
4
4
|
description = ""
|
|
5
5
|
authors = ["Thalison Fernandes <thalissfernandes99@gmail.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -13,7 +13,7 @@ python = "^3.10"
|
|
|
13
13
|
websockets = "^13.1"
|
|
14
14
|
aiohttp = "^3.9.5"
|
|
15
15
|
aiofiles = "^23.2.1"
|
|
16
|
-
|
|
16
|
+
beautifulsoup4 = "^4.12.3"
|
|
17
17
|
mkdocstrings = "^0.29.1"
|
|
18
18
|
|
|
19
19
|
|
|
@@ -64,4 +64,4 @@ post_test = 'coverage html'
|
|
|
64
64
|
[tool.mypy]
|
|
65
65
|
exclude = [
|
|
66
66
|
"tests/",
|
|
67
|
-
]
|
|
67
|
+
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/managers/browser_options_manager.py
RENAMED
|
File without changes
|
{pydoll_python-2.1.0 → pydoll_python-2.2.0}/pydoll/browser/managers/browser_process_manager.py
RENAMED
|
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
|
|
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
|