fastquadtree 1.2.1__tar.gz → 1.2.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.
Potentially problematic release.
This version of fastquadtree might be problematic. Click here for more details.
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/.github/workflows/release.yml +1 -1
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/Cargo.lock +1 -1
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/Cargo.toml +1 -1
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/PKG-INFO +5 -4
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/README.md +3 -2
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/docs/future_features.md +26 -10
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/mkdocs.yml +8 -5
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/pyproject.toml +1 -1
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/pysrc/fastquadtree/_base_quadtree.py +7 -1
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/pysrc/fastquadtree/point_quadtree.py +0 -12
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/pysrc/fastquadtree/rect_quadtree.py +0 -12
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/.github/workflows/docs.yml +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/.gitignore +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/.pre-commit-config.yaml +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/LICENSE +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/assets/ballpit.png +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/assets/interactive_v2_rect_screenshot.png +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/assets/interactive_v2_screenshot.png +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/assets/quadtree_bench_throughput.png +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/assets/quadtree_bench_time.png +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/benchmarks/benchmark_native_vs_shim.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/benchmarks/benchmark_np_vs_list.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/benchmarks/benchmark_serialization_vs_rebuild.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/benchmarks/cross_library_bench.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/benchmarks/quadtree_bench/__init__.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/benchmarks/quadtree_bench/engines.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/benchmarks/quadtree_bench/main.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/benchmarks/quadtree_bench/plotting.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/benchmarks/quadtree_bench/runner.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/benchmarks/requirements.txt +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/benchmarks/runner.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/benchmarks/system_info_collector.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/docs/api/point_item.md +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/docs/api/pyqtree.md +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/docs/api/quadtree.md +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/docs/api/rect_item.md +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/docs/api/rect_quadtree.md +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/docs/benchmark.md +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/docs/index.md +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/docs/quickstart.md +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/docs/runnables.md +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/docs/styles/overrides.css +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/interactive/ballpit.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/interactive/interactive.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/interactive/interactive_v2.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/interactive/interactive_v2_rect.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/interactive/requirements.txt +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/pysrc/fastquadtree/__init__.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/pysrc/fastquadtree/_item.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/pysrc/fastquadtree/_obj_store.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/pysrc/fastquadtree/py.typed +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/pysrc/fastquadtree/pyqtree.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/src/geom.rs +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/src/lib.rs +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/src/quadtree.rs +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/src/rect_quadtree.rs +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/insertions.rs +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/nearest_neighbor.rs +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/query.rs +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/rect_quadtree.rs +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/rectangle_traversal.rs +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/serialization.rs +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/test_base_quadtree.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/test_clear.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/test_delete.rs +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/test_delete_by_object.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/test_delete_python.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/test_insert_many_numpy.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/test_obj_store.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/test_point_quadtree_nn_runtime.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/test_pyqtree_shim_compat.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/test_python.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/test_rect_quadtree.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/test_serialization.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/test_unconventional_bounds.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/test_wrapper_edges.py +0 -0
- {fastquadtree-1.2.1 → fastquadtree-1.2.3}/tests/unconventional_bounds.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastquadtree
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.3
|
|
4
4
|
Classifier: Programming Language :: Python :: 3
|
|
5
5
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
6
6
|
Classifier: Programming Language :: Rust
|
|
@@ -31,7 +31,7 @@ License-File: LICENSE
|
|
|
31
31
|
Summary: Rust-accelerated quadtree for Python with fast inserts, range queries, and k-NN search.
|
|
32
32
|
Keywords: quadtree,spatial-index,geometry,rust,pyo3,nearest-neighbor,k-nn
|
|
33
33
|
Author: Ethan Anderson
|
|
34
|
-
Requires-Python: >=3.
|
|
34
|
+
Requires-Python: >=3.9
|
|
35
35
|
Description-Content-Type: text/markdown
|
|
36
36
|
Project-URL: Homepage, https://github.com/Elan456/fastquadtree
|
|
37
37
|
Project-URL: Repository, https://github.com/Elan456/fastquadtree
|
|
@@ -45,6 +45,8 @@ Project-URL: Issues, https://github.com/Elan456/fastquadtree/issues
|
|
|
45
45
|
|
|
46
46
|
Rust-optimized quadtree with a clean Python API
|
|
47
47
|
|
|
48
|
+
👉 **Check out the Docs:** https://elan456.github.io/fastquadtree/
|
|
49
|
+
|
|
48
50
|
[](https://pypi.org/project/fastquadtree/)
|
|
49
51
|
[](https://pypi.org/project/fastquadtree/)
|
|
50
52
|
[](https://pepy.tech/projects/fastquadtree)
|
|
@@ -64,7 +66,7 @@ Rust-optimized quadtree with a clean Python API
|
|
|
64
66
|
|
|
65
67
|
## Why use fastquadtree
|
|
66
68
|
|
|
67
|
-
- Clean [Python API](https://elan456.github.io/fastquadtree/api/quadtree/) with no external dependencies and modern typing hints
|
|
69
|
+
- Clean [Python API](https://elan456.github.io/fastquadtree/api/quadtree/) with **no external dependencies** and modern typing hints
|
|
68
70
|
- The fastest quadtree Python package ([>10x faster](https://elan456.github.io/fastquadtree/benchmark/) than pyqtree)
|
|
69
71
|
- Prebuilt wheels for Windows, macOS, and Linux
|
|
70
72
|
- Support for [inserting bounding boxes](https://elan456.github.io/fastquadtree/api/rect_quadtree/) or points
|
|
@@ -76,7 +78,6 @@ Rust-optimized quadtree with a clean Python API
|
|
|
76
78
|
|
|
77
79
|
----
|
|
78
80
|
|
|
79
|
-
👉 **Docs:** https://elan456.github.io/fastquadtree/
|
|
80
81
|
|
|
81
82
|
## Examples
|
|
82
83
|
See examples of how fastquadtree can be used in the [runnables](https://elan456.github.io/fastquadtree/runnables/) section.
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
Rust-optimized quadtree with a clean Python API
|
|
7
7
|
|
|
8
|
+
👉 **Check out the Docs:** https://elan456.github.io/fastquadtree/
|
|
9
|
+
|
|
8
10
|
[](https://pypi.org/project/fastquadtree/)
|
|
9
11
|
[](https://pypi.org/project/fastquadtree/)
|
|
10
12
|
[](https://pepy.tech/projects/fastquadtree)
|
|
@@ -24,7 +26,7 @@ Rust-optimized quadtree with a clean Python API
|
|
|
24
26
|
|
|
25
27
|
## Why use fastquadtree
|
|
26
28
|
|
|
27
|
-
- Clean [Python API](https://elan456.github.io/fastquadtree/api/quadtree/) with no external dependencies and modern typing hints
|
|
29
|
+
- Clean [Python API](https://elan456.github.io/fastquadtree/api/quadtree/) with **no external dependencies** and modern typing hints
|
|
28
30
|
- The fastest quadtree Python package ([>10x faster](https://elan456.github.io/fastquadtree/benchmark/) than pyqtree)
|
|
29
31
|
- Prebuilt wheels for Windows, macOS, and Linux
|
|
30
32
|
- Support for [inserting bounding boxes](https://elan456.github.io/fastquadtree/api/rect_quadtree/) or points
|
|
@@ -36,7 +38,6 @@ Rust-optimized quadtree with a clean Python API
|
|
|
36
38
|
|
|
37
39
|
----
|
|
38
40
|
|
|
39
|
-
👉 **Docs:** https://elan456.github.io/fastquadtree/
|
|
40
41
|
|
|
41
42
|
## Examples
|
|
42
43
|
See examples of how fastquadtree can be used in the [runnables](https://elan456.github.io/fastquadtree/runnables/) section.
|
|
@@ -5,26 +5,42 @@ If you really want any of these features, please let us know by opening an issue
|
|
|
5
5
|
|
|
6
6
|
If you have any suggestions or would like to contribute, please feel free to open an issue or a pull request.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
The features will likely be implemented in the order they are listed below, but this is not guaranteed.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## 🚧 Planned Features
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
### 1. Configurable Quadtree Coordinate Type
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Currently, the point quadtree only uses f32 for point coordinates, limiting precision in favor of better performance.
|
|
15
|
+
To make the quadtree more flexible, we could allow users to specify the coordinate type (e.g., f64, i32, etc.) when creating a quadtree.
|
|
16
|
+
The f32 will remain the default, but users will be able to specify a different type if needed.
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
For example, in the ball-pit demo, we use a point quadtree, but then query a larger area to account for the radius of the balls.
|
|
18
|
-
With a circle quadtree, we could directly insert circles and perform circle-circle collision detection.
|
|
18
|
+
If the type cannot be made truly generic, then only the following types would be supported: f32, f64, i32, i64
|
|
19
19
|
|
|
20
|
-
###
|
|
20
|
+
### 2. KNN with criteria function
|
|
21
21
|
|
|
22
22
|
Currently, KNN only supports finding the nearest neighbors based on euclidean distance.
|
|
23
23
|
By adding a criteria function, we could allow users to define custom criteria for finding neighbors by passing a function that
|
|
24
24
|
takes in a point and returns a score. The KNN algorithm would then use this score to determine the nearest neighbors.
|
|
25
25
|
|
|
26
|
-
###
|
|
26
|
+
### 3. KNN in rectangle quadtree
|
|
27
27
|
|
|
28
28
|
Currently, KNN is only supported in the point quadtree. By adding KNN support to the rectangle quadtree, we could allow users to find the nearest rectangles to a given point. This would be to the nearest edge of the rectangle, adding complexity to the algorithm.
|
|
29
29
|
However, it will allow for really quick collision detection between a point and a set of rectangles as the point can just do
|
|
30
|
-
robust-collision handling with the nearest rectangles.
|
|
30
|
+
robust-collision handling with the nearest rectangles.
|
|
31
|
+
|
|
32
|
+
### 4. Circle support
|
|
33
|
+
|
|
34
|
+
Currently, we support points and rectangles in two separate quadtrees.
|
|
35
|
+
For example, in the ball-pit demo, we use a point quadtree, but then query a larger area to account for the radius of the balls.
|
|
36
|
+
With a circle quadtree, we could directly insert circles and perform circle-circle collision detection.
|
|
37
|
+
|
|
38
|
+
A good alternative is to use the rectangle quadtree and insert the minimum bounding rectangles of the circles.
|
|
39
|
+
|
|
40
|
+
## ✅ Completed Planned Features
|
|
41
|
+
|
|
42
|
+
Once a feature from above is completed, it will be moved to this section.
|
|
43
|
+
|
|
44
|
+
### Quadtree serialization
|
|
45
|
+
|
|
46
|
+
By serializing the quadtree, we can save its state to a file and load it later. This will allow us to persist the quadtree structure and data across sessions. For example, you could pre build a quadtree with all the walls in your video game level, serialize it to a file, and then load it when the game starts. This will heavily reduce the game load time since you won't have to rebuild the quadtree from scratch every time.
|
|
@@ -12,10 +12,12 @@ theme:
|
|
|
12
12
|
- navigation.tracking
|
|
13
13
|
- navigation.indexes
|
|
14
14
|
- content.code.copy
|
|
15
|
-
- toc.
|
|
15
|
+
- toc.follow
|
|
16
16
|
- search.suggest
|
|
17
17
|
- search.highlight
|
|
18
18
|
- content.tooltips
|
|
19
|
+
- navigation.footer
|
|
20
|
+
- navigation.top
|
|
19
21
|
palette:
|
|
20
22
|
- scheme: slate
|
|
21
23
|
primary: indigo
|
|
@@ -37,13 +39,14 @@ plugins:
|
|
|
37
39
|
options:
|
|
38
40
|
docstring_style: google
|
|
39
41
|
merge_init_into_class: true
|
|
40
|
-
show_source:
|
|
42
|
+
show_source: false
|
|
41
43
|
show_root_heading: false
|
|
42
44
|
show_signature: true
|
|
43
45
|
show_if_no_docstring: true
|
|
44
|
-
separate_signature:
|
|
45
|
-
line_length:
|
|
46
|
-
heading_level:
|
|
46
|
+
separate_signature: false
|
|
47
|
+
line_length: 100
|
|
48
|
+
heading_level: 3
|
|
49
|
+
members_order: source
|
|
47
50
|
filters: # Exclude __slots__ and __len__ and anything with a single underscore prefix (don't filter insert_many even though it has a single underscore)
|
|
48
51
|
- "!__slots__"
|
|
49
52
|
- "!__len__"
|
|
@@ -8,7 +8,7 @@ name = "fastquadtree"
|
|
|
8
8
|
dynamic = ["version"]
|
|
9
9
|
description = "Rust-accelerated quadtree for Python with fast inserts, range queries, and k-NN search."
|
|
10
10
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
11
|
-
requires-python = ">=3.
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
12
|
dependencies = [] # No runtime dependencies
|
|
13
13
|
license = { file = "LICENSE" }
|
|
14
14
|
authors = [{ name = "Ethan Anderson" }]
|
|
@@ -18,6 +18,8 @@ from ._item import Item # base class for PointItem and RectItem
|
|
|
18
18
|
from ._obj_store import ObjStore
|
|
19
19
|
|
|
20
20
|
if TYPE_CHECKING:
|
|
21
|
+
from typing import Self # Only in Python 3.11+
|
|
22
|
+
|
|
21
23
|
from numpy.typing import NDArray
|
|
22
24
|
|
|
23
25
|
Bounds = Tuple[float, float, float, float]
|
|
@@ -59,6 +61,10 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
|
|
|
59
61
|
def _new_native(self, bounds: Bounds, capacity: int, max_depth: int | None) -> Any:
|
|
60
62
|
"""Create the native engine instance."""
|
|
61
63
|
|
|
64
|
+
@classmethod
|
|
65
|
+
def _new_native_from_bytes(cls, data: bytes) -> Any:
|
|
66
|
+
"""Create the native engine instance from serialized bytes."""
|
|
67
|
+
|
|
62
68
|
@staticmethod
|
|
63
69
|
@abstractmethod
|
|
64
70
|
def _make_item(id_: int, geom: G, obj: Any | None) -> ItemType:
|
|
@@ -132,7 +138,7 @@ class _BaseQuadTree(Generic[G, HitT, ItemType], ABC):
|
|
|
132
138
|
return pickle.dumps(self.to_dict())
|
|
133
139
|
|
|
134
140
|
@classmethod
|
|
135
|
-
def from_bytes(cls, data: bytes) ->
|
|
141
|
+
def from_bytes(cls, data: bytes) -> Self:
|
|
136
142
|
"""
|
|
137
143
|
Deserialize a quadtree from bytes.
|
|
138
144
|
|
|
@@ -49,18 +49,6 @@ class QuadTree(_BaseQuadTree[Point, _IdCoord, PointItem]):
|
|
|
49
49
|
track_objects=track_objects,
|
|
50
50
|
)
|
|
51
51
|
|
|
52
|
-
@classmethod
|
|
53
|
-
def from_bytes(cls, data: bytes) -> QuadTree:
|
|
54
|
-
"""
|
|
55
|
-
Create a QuadTree instance from serialized bytes.
|
|
56
|
-
|
|
57
|
-
Args:
|
|
58
|
-
data: Serialized byte data from `to_bytes()`.
|
|
59
|
-
Returns:
|
|
60
|
-
A QuadTree instance.
|
|
61
|
-
"""
|
|
62
|
-
return super().from_bytes(data)
|
|
63
|
-
|
|
64
52
|
@overload
|
|
65
53
|
def query(
|
|
66
54
|
self, rect: Bounds, *, as_items: Literal[False] = ...
|
|
@@ -50,18 +50,6 @@ class RectQuadTree(_BaseQuadTree[Bounds, _IdRect, RectItem]):
|
|
|
50
50
|
track_objects=track_objects,
|
|
51
51
|
)
|
|
52
52
|
|
|
53
|
-
@classmethod
|
|
54
|
-
def from_bytes(cls, data: bytes) -> RectQuadTree:
|
|
55
|
-
"""
|
|
56
|
-
Create a RectQuadTree instance from serialized bytes.
|
|
57
|
-
|
|
58
|
-
Args:
|
|
59
|
-
data: Serialized byte data from `to_bytes()`.
|
|
60
|
-
Returns:
|
|
61
|
-
A RectQuadTree instance.
|
|
62
|
-
"""
|
|
63
|
-
return super().from_bytes(data)
|
|
64
|
-
|
|
65
53
|
@overload
|
|
66
54
|
def query(
|
|
67
55
|
self, rect: Bounds, *, as_items: Literal[False] = ...
|
|
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
|