esper 2.4.1__zip → 2.5__zip
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.
- esper-2.4.1/.github/workflows/python-package.yml → esper-2.5/.github/workflows/unit-tests.yml +9 -8
- {esper-2.4.1 → esper-2.5}/LICENSE.rst +1 -1
- {esper-2.4.1 → esper-2.5}/PKG-INFO +7 -4
- {esper-2.4.1 → esper-2.5}/README.md +6 -3
- {esper-2.4.1 → esper-2.5}/RELEASE_NOTES +11 -0
- {esper-2.4.1 → esper-2.5}/esper/__init__.py +28 -19
- {esper-2.4.1 → esper-2.5}/esper.egg-info/PKG-INFO +7 -4
- {esper-2.4.1 → esper-2.5}/esper.egg-info/SOURCES.txt +1 -2
- {esper-2.4.1 → esper-2.5}/tests/test_world.py +82 -23
- esper-2.4.1/.travis.yml +0 -12
- {esper-2.4.1 → esper-2.5}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {esper-2.4.1 → esper-2.5}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {esper-2.4.1 → esper-2.5}/.github/ISSUE_TEMPLATE/question-or-comment.md +0 -0
- {esper-2.4.1 → esper-2.5}/.gitignore +0 -0
- {esper-2.4.1 → esper-2.5}/MANIFEST.in +0 -0
- {esper-2.4.1 → esper-2.5}/docs/Makefile +0 -0
- {esper-2.4.1 → esper-2.5}/docs/conf.py +0 -0
- {esper-2.4.1 → esper-2.5}/docs/index.rst +0 -0
- {esper-2.4.1 → esper-2.5}/docs/make.bat +0 -0
- {esper-2.4.1 → esper-2.5}/esper/py.typed +0 -0
- {esper-2.4.1 → esper-2.5}/esper.egg-info/dependency_links.txt +0 -0
- {esper-2.4.1 → esper-2.5}/esper.egg-info/top_level.txt +0 -0
- {esper-2.4.1 → esper-2.5}/examples/benchmark.py +0 -0
- {esper-2.4.1 → esper-2.5}/examples/benchmark_cache.py +0 -0
- {esper-2.4.1 → esper-2.5}/examples/bluesquare.png +0 -0
- {esper-2.4.1 → esper-2.5}/examples/headless_example.py +0 -0
- {esper-2.4.1 → esper-2.5}/examples/pygame_example.py +0 -0
- {esper-2.4.1 → esper-2.5}/examples/pyglet_example.py +0 -0
- {esper-2.4.1 → esper-2.5}/examples/pyglet_example_batch.py +0 -0
- {esper-2.4.1 → esper-2.5}/examples/pysdl2_example.py +0 -0
- {esper-2.4.1 → esper-2.5}/examples/pythonista_ios_example.py +0 -0
- {esper-2.4.1 → esper-2.5}/examples/redsquare.png +0 -0
- {esper-2.4.1 → esper-2.5}/make.py +0 -0
- {esper-2.4.1 → esper-2.5}/setup.cfg +0 -0
- {esper-2.4.1 → esper-2.5}/setup.py +0 -0
- {esper-2.4.1 → esper-2.5}/tests/__init__.py +0 -0
esper-2.4.1/.github/workflows/python-package.yml → esper-2.5/.github/workflows/unit-tests.yml
RENAMED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: unit tests
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
5
|
pull_request:
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
jobs:
|
|
8
|
-
|
|
9
|
-
runs-on:
|
|
9
|
+
tests:
|
|
10
|
+
runs-on: ${{ matrix.os }}
|
|
10
11
|
strategy:
|
|
11
12
|
matrix:
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
os: [ 'ubuntu-latest', 'macos-latest', 'windows-latest' ]
|
|
14
|
+
python-version: [ '3.8', '3.9', '3.10', '3.11', '3.12-dev', 'pypy-3.7' ]
|
|
14
15
|
steps:
|
|
15
|
-
- name:
|
|
16
|
-
uses: actions/checkout@
|
|
16
|
+
- name: Python ${{ matrix.python-version }} ${{ matrix.os }}
|
|
17
|
+
uses: actions/checkout@v3
|
|
17
18
|
- name: Set up Python ${{ matrix.python-version }}
|
|
18
|
-
uses: actions/setup-python@
|
|
19
|
+
uses: actions/setup-python@v4
|
|
19
20
|
with:
|
|
20
21
|
python-version: ${{ matrix.python-version }}
|
|
21
22
|
- name: Install test dependencies
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: esper
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5
|
|
4
4
|
Summary: esper is a lightweight Entity System (ECS) for Python, with a focus on performance.
|
|
5
5
|
Home-page: https://github.com/benmoran56/esper
|
|
6
6
|
Download-URL: https://github.com/benmoran56/esper/releases
|
|
@@ -20,8 +20,9 @@ Classifier: Topic :: Games/Entertainment
|
|
|
20
20
|
Classifier: Topic :: Software Development :: Libraries
|
|
21
21
|
License-File: LICENSE.rst
|
|
22
22
|
|
|
23
|
-
[](https://pypi.python.org/pypi/esper)
|
|
24
|
+
[](https://esper.readthedocs.io)
|
|
25
|
+
[](https://github.com/benmoran56/esper/actions/workflows/unit-tests.yml)
|
|
25
26
|
|
|
26
27
|
Esper is a lightweight Entity System module for Python, with a focus on performance
|
|
27
28
|
===================================================================================
|
|
@@ -393,4 +394,6 @@ Contributions to Esper are always welcome, but there are some specific project g
|
|
|
393
394
|
- Avoid bloat as much as possible. New features will be considered if they are commonly useful. Generally speaking, we don't want to add functionality that is better handled in another module or library.
|
|
394
395
|
- Performance is preferrable to readability.
|
|
395
396
|
|
|
396
|
-
If you have any questions before contributing, feel free to
|
|
397
|
+
If you have any questions before contributing, feel free to [open an issue].
|
|
398
|
+
|
|
399
|
+
[open an issue]: https://github.com/benmoran56/esper/issues
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
[](https://pypi.python.org/pypi/esper)
|
|
2
|
+
[](https://esper.readthedocs.io)
|
|
3
|
+
[](https://github.com/benmoran56/esper/actions/workflows/unit-tests.yml)
|
|
3
4
|
|
|
4
5
|
Esper is a lightweight Entity System module for Python, with a focus on performance
|
|
5
6
|
===================================================================================
|
|
@@ -371,4 +372,6 @@ Contributions to Esper are always welcome, but there are some specific project g
|
|
|
371
372
|
- Avoid bloat as much as possible. New features will be considered if they are commonly useful. Generally speaking, we don't want to add functionality that is better handled in another module or library.
|
|
372
373
|
- Performance is preferrable to readability.
|
|
373
374
|
|
|
374
|
-
If you have any questions before contributing, feel free to
|
|
375
|
+
If you have any questions before contributing, feel free to [open an issue].
|
|
376
|
+
|
|
377
|
+
[open an issue]: https://github.com/benmoran56/esper/issues
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
esper 2.5
|
|
2
|
+
=========
|
|
3
|
+
Maintenance release
|
|
4
|
+
|
|
5
|
+
Changes
|
|
6
|
+
-------
|
|
7
|
+
- Removing all Components from an Entity will no longer automatically delete the Entity.
|
|
8
|
+
- Typing fixes and additions.
|
|
9
|
+
- Entity DB check and creation is done once when Entity is created, not when adding Components.
|
|
10
|
+
|
|
11
|
+
|
|
1
12
|
esper 2.4
|
|
2
13
|
=========
|
|
3
14
|
Maintenance release
|
|
@@ -2,18 +2,20 @@ import time as _time
|
|
|
2
2
|
|
|
3
3
|
from types import MethodType as _MethodType
|
|
4
4
|
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import Any as _Any
|
|
6
6
|
from typing import List as _List
|
|
7
|
-
from typing import Optional as _Optional
|
|
8
|
-
from typing import Tuple as _Tuple
|
|
9
7
|
from typing import Type as _Type
|
|
8
|
+
from typing import Tuple as _Tuple
|
|
10
9
|
from typing import TypeVar as _TypeVar
|
|
10
|
+
from typing import Iterable as _Iterable
|
|
11
|
+
from typing import Optional as _Optional
|
|
12
|
+
from typing import overload as _overload
|
|
11
13
|
|
|
12
14
|
from weakref import ref as _ref
|
|
13
15
|
from weakref import WeakMethod as _WeakMethod
|
|
14
16
|
|
|
15
17
|
|
|
16
|
-
version = '2.
|
|
18
|
+
version = '2.5'
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
###################
|
|
@@ -86,6 +88,9 @@ def remove_handler(name: str, func) -> None:
|
|
|
86
88
|
|
|
87
89
|
|
|
88
90
|
_C = _TypeVar('_C')
|
|
91
|
+
_C2 = _TypeVar('_C2')
|
|
92
|
+
_C3 = _TypeVar('_C3')
|
|
93
|
+
_C4 = _TypeVar('_C4')
|
|
89
94
|
|
|
90
95
|
|
|
91
96
|
class Processor:
|
|
@@ -210,6 +215,9 @@ class World:
|
|
|
210
215
|
|
|
211
216
|
entity = self._next_entity_id
|
|
212
217
|
|
|
218
|
+
if entity not in self._entities:
|
|
219
|
+
self._entities[entity] = {}
|
|
220
|
+
|
|
213
221
|
for component_instance in components:
|
|
214
222
|
|
|
215
223
|
component_type = type(component_instance)
|
|
@@ -219,9 +227,6 @@ class World:
|
|
|
219
227
|
|
|
220
228
|
self._components[component_type].add(entity)
|
|
221
229
|
|
|
222
|
-
if entity not in self._entities:
|
|
223
|
-
self._entities[entity] = {}
|
|
224
|
-
|
|
225
230
|
self._entities[entity][component_type] = component_instance
|
|
226
231
|
self.clear_cache()
|
|
227
232
|
|
|
@@ -309,16 +314,13 @@ class World:
|
|
|
309
314
|
|
|
310
315
|
self._components[component_type].add(entity)
|
|
311
316
|
|
|
312
|
-
if entity not in self._entities:
|
|
313
|
-
self._entities[entity] = {}
|
|
314
|
-
|
|
315
317
|
self._entities[entity][component_type] = component_instance
|
|
316
318
|
self.clear_cache()
|
|
317
319
|
|
|
318
|
-
def remove_component(self, entity: int, component_type: _Type[_C]) ->
|
|
320
|
+
def remove_component(self, entity: int, component_type: _Type[_C]) -> _C:
|
|
319
321
|
"""Remove a Component instance from an Entity, by type.
|
|
320
322
|
|
|
321
|
-
A Component instance can be removed by providing its type.
|
|
323
|
+
A Component instance can only be removed by providing its type.
|
|
322
324
|
For example: world.delete_component(enemy_a, Velocity) will remove
|
|
323
325
|
the Velocity instance from the Entity enemy_a.
|
|
324
326
|
|
|
@@ -330,13 +332,8 @@ class World:
|
|
|
330
332
|
if not self._components[component_type]:
|
|
331
333
|
del self._components[component_type]
|
|
332
334
|
|
|
333
|
-
del self._entities[entity][component_type]
|
|
334
|
-
|
|
335
|
-
if not self._entities[entity]:
|
|
336
|
-
del self._entities[entity]
|
|
337
|
-
|
|
338
335
|
self.clear_cache()
|
|
339
|
-
return entity
|
|
336
|
+
return self._entities[entity].pop(component_type)
|
|
340
337
|
|
|
341
338
|
def _get_component(self, component_type: _Type[_C]) -> _Iterable[_Tuple[int, _C]]:
|
|
342
339
|
entity_db = self._entities
|
|
@@ -363,7 +360,19 @@ class World:
|
|
|
363
360
|
component_type, list(self._get_component(component_type))
|
|
364
361
|
)
|
|
365
362
|
|
|
366
|
-
|
|
363
|
+
@_overload
|
|
364
|
+
def get_components(self, __c1: _Type[_C], __c2: _Type[_C2]) -> _List[_Tuple[int, _Tuple[_C, _C2]]]:
|
|
365
|
+
...
|
|
366
|
+
|
|
367
|
+
@_overload
|
|
368
|
+
def get_components(self, __c1: _Type[_C], __c2: _Type[_C2], __c3: _Type[_C3]) -> _List[_Tuple[int, _Tuple[_C, _C2, _C3]]]:
|
|
369
|
+
...
|
|
370
|
+
|
|
371
|
+
@_overload
|
|
372
|
+
def get_components(self, __c1: _Type[_C], __c2: _Type[_C2], __c3: _Type[_C3], __c4: _Type[_C4]) -> _List[_Tuple[int, _Tuple[_C, _C2, _C3, _C4]]]:
|
|
373
|
+
...
|
|
374
|
+
|
|
375
|
+
def get_components(self, *component_types: _Type[_Any]) -> _Iterable[_Tuple[int, _Tuple[_Any, ...]]]:
|
|
367
376
|
"""Get an iterator for Entity and multiple Component sets."""
|
|
368
377
|
try:
|
|
369
378
|
return self._get_components_cache[component_types]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: esper
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5
|
|
4
4
|
Summary: esper is a lightweight Entity System (ECS) for Python, with a focus on performance.
|
|
5
5
|
Home-page: https://github.com/benmoran56/esper
|
|
6
6
|
Download-URL: https://github.com/benmoran56/esper/releases
|
|
@@ -20,8 +20,9 @@ Classifier: Topic :: Games/Entertainment
|
|
|
20
20
|
Classifier: Topic :: Software Development :: Libraries
|
|
21
21
|
License-File: LICENSE.rst
|
|
22
22
|
|
|
23
|
-
[](https://pypi.python.org/pypi/esper)
|
|
24
|
+
[](https://esper.readthedocs.io)
|
|
25
|
+
[](https://github.com/benmoran56/esper/actions/workflows/unit-tests.yml)
|
|
25
26
|
|
|
26
27
|
Esper is a lightweight Entity System module for Python, with a focus on performance
|
|
27
28
|
===================================================================================
|
|
@@ -393,4 +394,6 @@ Contributions to Esper are always welcome, but there are some specific project g
|
|
|
393
394
|
- Avoid bloat as much as possible. New features will be considered if they are commonly useful. Generally speaking, we don't want to add functionality that is better handled in another module or library.
|
|
394
395
|
- Performance is preferrable to readability.
|
|
395
396
|
|
|
396
|
-
If you have any questions before contributing, feel free to
|
|
397
|
+
If you have any questions before contributing, feel free to [open an issue].
|
|
398
|
+
|
|
399
|
+
[open an issue]: https://github.com/benmoran56/esper/issues
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
.gitignore
|
|
2
|
-
.travis.yml
|
|
3
2
|
LICENSE.rst
|
|
4
3
|
MANIFEST.in
|
|
5
4
|
README.md
|
|
@@ -9,7 +8,7 @@ setup.py
|
|
|
9
8
|
.github/ISSUE_TEMPLATE/bug_report.md
|
|
10
9
|
.github/ISSUE_TEMPLATE/feature_request.md
|
|
11
10
|
.github/ISSUE_TEMPLATE/question-or-comment.md
|
|
12
|
-
.github/workflows/
|
|
11
|
+
.github/workflows/unit-tests.yml
|
|
13
12
|
docs/Makefile
|
|
14
13
|
docs/conf.py
|
|
15
14
|
docs/index.rst
|
|
@@ -39,6 +39,11 @@ def test_create_entity_with_components(world):
|
|
|
39
39
|
assert world.has_component(entity2, ComponentB) is True
|
|
40
40
|
|
|
41
41
|
|
|
42
|
+
def test_adding_component_to_not_existing_entity_raises_error(world):
|
|
43
|
+
with pytest.raises(KeyError):
|
|
44
|
+
world.add_component(123, ComponentA())
|
|
45
|
+
|
|
46
|
+
|
|
42
47
|
def test_create_entity_and_add_components(world):
|
|
43
48
|
entity1 = world.create_entity()
|
|
44
49
|
world.add_component(entity1, ComponentA())
|
|
@@ -59,18 +64,17 @@ def test_delete_entity(world):
|
|
|
59
64
|
world.add_component(entity1, ComponentC())
|
|
60
65
|
entity2 = world.create_entity()
|
|
61
66
|
world.add_component(entity2, ComponentD())
|
|
62
|
-
|
|
63
|
-
world.add_component(
|
|
64
|
-
|
|
67
|
+
entity_with_component = world.create_entity()
|
|
68
|
+
world.add_component(entity_with_component, ComponentE())
|
|
69
|
+
empty_entity = world.create_entity()
|
|
65
70
|
|
|
66
|
-
assert
|
|
67
|
-
world.delete_entity(
|
|
71
|
+
assert entity_with_component == 3
|
|
72
|
+
world.delete_entity(entity_with_component, immediate=True)
|
|
68
73
|
with pytest.raises(KeyError):
|
|
69
|
-
world.components_for_entity(
|
|
74
|
+
world.components_for_entity(entity_with_component)
|
|
70
75
|
with pytest.raises(KeyError):
|
|
71
76
|
world.delete_entity(999, immediate=True)
|
|
72
|
-
|
|
73
|
-
world.delete_entity(entity4, immediate=True)
|
|
77
|
+
world.delete_entity(empty_entity, immediate=True)
|
|
74
78
|
|
|
75
79
|
|
|
76
80
|
def test_component_for_entity(world):
|
|
@@ -256,17 +260,71 @@ def test_cache_results(world):
|
|
|
256
260
|
assert len(list(query for query in world.get_components(ComponentB, ComponentC))) == 1
|
|
257
261
|
|
|
258
262
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
263
|
+
class TestEntityExists:
|
|
264
|
+
def test_dead_entity(self, world):
|
|
265
|
+
dead_entity = world.create_entity(ComponentB())
|
|
266
|
+
world.delete_entity(dead_entity)
|
|
267
|
+
assert not world.entity_exists(dead_entity)
|
|
268
|
+
|
|
269
|
+
def test_not_created_entity(self, world):
|
|
270
|
+
assert not world.entity_exists(123)
|
|
271
|
+
|
|
272
|
+
def test_empty_entity(self, world):
|
|
273
|
+
empty_entity = world.create_entity()
|
|
274
|
+
assert world.entity_exists(empty_entity)
|
|
275
|
+
|
|
276
|
+
def test_entity_with_component(self, world):
|
|
277
|
+
entity_with_component = world.create_entity(ComponentA())
|
|
278
|
+
assert world.entity_exists(entity_with_component)
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
class TestRemoveComponent:
|
|
282
|
+
def test_remove_from_not_existing_entity_raises_key_error(self, world):
|
|
283
|
+
with pytest.raises(KeyError):
|
|
284
|
+
world.remove_component(123, ComponentA)
|
|
285
|
+
|
|
286
|
+
def test_remove_not_existing_component_raises_key_error(self, world):
|
|
287
|
+
entity = world.create_entity(ComponentB())
|
|
288
|
+
|
|
289
|
+
with pytest.raises(KeyError):
|
|
290
|
+
world.remove_component(entity, ComponentA)
|
|
265
291
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
292
|
+
def test_remove_component_with_object_raises_key_error(self, populated_world):
|
|
293
|
+
entity = 2
|
|
294
|
+
component = ComponentD()
|
|
295
|
+
|
|
296
|
+
assert populated_world.has_component(entity, type(component))
|
|
297
|
+
with pytest.raises(KeyError):
|
|
298
|
+
populated_world.remove_component(entity, component)
|
|
299
|
+
|
|
300
|
+
def test_remove_component_returns_removed_instance(self, world):
|
|
301
|
+
component = ComponentA()
|
|
302
|
+
entity = world.create_entity(component)
|
|
303
|
+
|
|
304
|
+
result = world.remove_component(entity, type(component))
|
|
305
|
+
|
|
306
|
+
assert result is component
|
|
307
|
+
|
|
308
|
+
def test_remove_last_component_leaves_empty_entity(self, world):
|
|
309
|
+
entity = world.create_entity()
|
|
310
|
+
world.add_component(entity, ComponentA())
|
|
311
|
+
|
|
312
|
+
world.remove_component(entity, ComponentA)
|
|
313
|
+
|
|
314
|
+
assert not world.has_component(entity, ComponentA)
|
|
315
|
+
assert world.entity_exists(entity)
|
|
316
|
+
|
|
317
|
+
def test_removing_one_component_leaves_other_intact(self, world):
|
|
318
|
+
component_a = ComponentA()
|
|
319
|
+
component_b = ComponentB()
|
|
320
|
+
component_c = ComponentC()
|
|
321
|
+
entity = world.create_entity(component_a, component_b, component_c)
|
|
322
|
+
|
|
323
|
+
world.remove_component(entity, ComponentB)
|
|
324
|
+
|
|
325
|
+
assert world.component_for_entity(entity, ComponentA) is component_a
|
|
326
|
+
assert not world.has_component(entity, ComponentB)
|
|
327
|
+
assert world.component_for_entity(entity, ComponentC) is component_c
|
|
270
328
|
|
|
271
329
|
|
|
272
330
|
def test_event_dispatch_no_handlers():
|
|
@@ -301,13 +359,14 @@ def test_set_methoad_as_handler_in_init():
|
|
|
301
359
|
def __init__(self):
|
|
302
360
|
esper.set_handler("foo", self._my_handler)
|
|
303
361
|
|
|
304
|
-
|
|
362
|
+
@staticmethod
|
|
363
|
+
def _my_handler():
|
|
305
364
|
print("OK")
|
|
306
365
|
|
|
307
366
|
def process(self, dt):
|
|
308
367
|
pass
|
|
309
368
|
|
|
310
|
-
|
|
369
|
+
_myclass = MyClass()
|
|
311
370
|
esper.dispatch_event("foo")
|
|
312
371
|
esper.event_registry.clear()
|
|
313
372
|
|
|
@@ -315,7 +374,8 @@ def test_set_methoad_as_handler_in_init():
|
|
|
315
374
|
def test_set_instance_methoad_as_handler():
|
|
316
375
|
class MyClass(esper.Processor):
|
|
317
376
|
|
|
318
|
-
|
|
377
|
+
@staticmethod
|
|
378
|
+
def my_handler():
|
|
319
379
|
print("OK")
|
|
320
380
|
|
|
321
381
|
def process(self, dt):
|
|
@@ -377,8 +437,7 @@ class ComponentE:
|
|
|
377
437
|
|
|
378
438
|
|
|
379
439
|
class ComponentF:
|
|
380
|
-
|
|
381
|
-
pass
|
|
440
|
+
pass
|
|
382
441
|
|
|
383
442
|
|
|
384
443
|
class CorrectProcessorA(esper.Processor):
|
esper-2.4.1/.travis.yml
DELETED
|
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
|