pytrilogy 0.0.1.111__tar.gz → 0.0.1.112__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 pytrilogy might be problematic. Click here for more details.
- {pytrilogy-0.0.1.111/pytrilogy.egg-info → pytrilogy-0.0.1.112}/PKG-INFO +1 -1
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112/pytrilogy.egg-info}/PKG-INFO +1 -1
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_parsing.py +24 -1
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/__init__.py +1 -1
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/models.py +8 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/optimization.py +11 -12
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parsing/parse_engine.py +16 -1
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/LICENSE.md +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/README.md +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/pyproject.toml +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/pytrilogy.egg-info/SOURCES.txt +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/pytrilogy.egg-info/dependency_links.txt +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/pytrilogy.egg-info/entry_points.txt +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/pytrilogy.egg-info/requires.txt +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/pytrilogy.egg-info/top_level.txt +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/setup.cfg +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/setup.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_declarations.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_derived_concepts.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_discovery_nodes.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_environment.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_functions.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_imports.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_metadata.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_models.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_multi_join_assignments.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_partial_handling.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_query_processing.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_select.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_statements.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_undefined_concept.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/tests/test_where_clause.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/compiler.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/constants.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/__init__.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/constants.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/enums.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/env_processor.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/environment_helpers.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/ergonomics.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/exceptions.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/functions.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/graph_models.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/internal.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/__init__.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/concept_strategies_v3.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/graph_utils.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/__init__.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/basic_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/common.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/concept_merge_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/filter_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/group_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/select_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/window_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/__init__.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/base_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/filter_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/group_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/merge_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/unnest_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/nodes/window_node.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/utility.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/query_processor.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/__init__.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/base.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/bigquery.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/common.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/config.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/duckdb.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/enums.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/postgres.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/presto.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/snowflake.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/dialect/sql_server.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/engine.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/executor.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/hooks/__init__.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/hooks/base_hook.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/hooks/graph_hook.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/hooks/query_debugger.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/metadata/__init__.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parser.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parsing/__init__.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parsing/common.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parsing/config.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parsing/exceptions.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parsing/helpers.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/parsing/render.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/py.typed +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/scripts/__init__.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/scripts/trilogy.py +0 -0
- {pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/utility.py +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from trilogy.core.enums import Purpose
|
|
1
|
+
from trilogy.core.enums import Purpose, ComparisonOperator
|
|
2
2
|
from trilogy.core.models import (
|
|
3
3
|
DataType,
|
|
4
4
|
Parenthetical,
|
|
@@ -6,6 +6,7 @@ from trilogy.core.models import (
|
|
|
6
6
|
ShowStatement,
|
|
7
7
|
SelectStatement,
|
|
8
8
|
Environment,
|
|
9
|
+
Comparison,
|
|
9
10
|
)
|
|
10
11
|
from trilogy.core.functions import argument_to_purpose, function_args_to_output_purpose
|
|
11
12
|
from trilogy.parsing.parse_engine import (
|
|
@@ -217,3 +218,25 @@ select
|
|
|
217
218
|
for name in ["test_name_count"]:
|
|
218
219
|
assert name in env.concepts
|
|
219
220
|
assert env.concepts[name].purpose == Purpose.METRIC
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def test_between():
|
|
224
|
+
_, parsed = parse_text(
|
|
225
|
+
"const order_id <- 4; SELECT order_id WHERE order_id BETWEEN 3 and 5;"
|
|
226
|
+
)
|
|
227
|
+
query: ProcessedQuery = parsed[-1]
|
|
228
|
+
left = query.where_clause.conditional.left
|
|
229
|
+
assert isinstance(
|
|
230
|
+
left,
|
|
231
|
+
Comparison,
|
|
232
|
+
), type(left)
|
|
233
|
+
assert left.operator == ComparisonOperator.GTE
|
|
234
|
+
assert left.right == 3
|
|
235
|
+
|
|
236
|
+
right = query.where_clause.conditional.right
|
|
237
|
+
assert isinstance(
|
|
238
|
+
right,
|
|
239
|
+
Comparison,
|
|
240
|
+
), type(right)
|
|
241
|
+
assert right.operator == ComparisonOperator.LTE
|
|
242
|
+
assert right.right == 5
|
|
@@ -2041,6 +2041,14 @@ class CTE(BaseModel):
|
|
|
2041
2041
|
ds_being_inlined = qds_being_inlined.datasources[0]
|
|
2042
2042
|
if not isinstance(ds_being_inlined, Datasource):
|
|
2043
2043
|
return False
|
|
2044
|
+
if any(
|
|
2045
|
+
[
|
|
2046
|
+
x.identifier == ds_being_inlined.identifier
|
|
2047
|
+
for x in self.source.datasources
|
|
2048
|
+
]
|
|
2049
|
+
):
|
|
2050
|
+
return False
|
|
2051
|
+
|
|
2044
2052
|
self.source.datasources = [
|
|
2045
2053
|
ds_being_inlined,
|
|
2046
2054
|
*[
|
|
@@ -12,9 +12,6 @@ from trilogy.constants import logger, CONFIG
|
|
|
12
12
|
from abc import ABC
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
REGISTERED_RULES: list["OptimizationRule"] = []
|
|
16
|
-
|
|
17
|
-
|
|
18
15
|
class OptimizationRule(ABC):
|
|
19
16
|
|
|
20
17
|
def optimize(self, cte: CTE, inverse_map: dict[str, list[CTE]]) -> bool:
|
|
@@ -66,13 +63,15 @@ class InlineDatasource(OptimizationRule):
|
|
|
66
63
|
to_inline.append(parent_cte)
|
|
67
64
|
|
|
68
65
|
for replaceable in to_inline:
|
|
69
|
-
self.log(f"Inlining parent {replaceable.name}")
|
|
70
|
-
cte.inline_parent_datasource(replaceable, force_group=force_group)
|
|
71
66
|
|
|
67
|
+
result = cte.inline_parent_datasource(replaceable, force_group=force_group)
|
|
68
|
+
if result:
|
|
69
|
+
self.log(f"Inlined parent {replaceable.name}")
|
|
70
|
+
else:
|
|
71
|
+
self.log(f"Failed to inline {replaceable.name}")
|
|
72
72
|
return optimized
|
|
73
73
|
|
|
74
74
|
|
|
75
|
-
# This will be used in the future for more complex condition decomposition
|
|
76
75
|
def decompose_condition(conditional: Conditional):
|
|
77
76
|
chunks = []
|
|
78
77
|
if conditional.operator == BooleanOperator.AND:
|
|
@@ -154,12 +153,6 @@ class PredicatePushdown(OptimizationRule):
|
|
|
154
153
|
return optimized
|
|
155
154
|
|
|
156
155
|
|
|
157
|
-
if CONFIG.optimizations.datasource_inlining:
|
|
158
|
-
REGISTERED_RULES.append(InlineDatasource())
|
|
159
|
-
if CONFIG.optimizations.predicate_pushdown:
|
|
160
|
-
REGISTERED_RULES.append(PredicatePushdown())
|
|
161
|
-
|
|
162
|
-
|
|
163
156
|
def filter_irrelevant_ctes(
|
|
164
157
|
input: list[CTE],
|
|
165
158
|
root_cte: CTE,
|
|
@@ -233,6 +226,12 @@ def optimize_ctes(
|
|
|
233
226
|
input: list[CTE], root_cte: CTE, select: SelectStatement | MultiSelectStatement
|
|
234
227
|
):
|
|
235
228
|
complete = False
|
|
229
|
+
REGISTERED_RULES: list["OptimizationRule"] = []
|
|
230
|
+
|
|
231
|
+
if CONFIG.optimizations.datasource_inlining:
|
|
232
|
+
REGISTERED_RULES.append(InlineDatasource())
|
|
233
|
+
if CONFIG.optimizations.predicate_pushdown:
|
|
234
|
+
REGISTERED_RULES.append(PredicatePushdown())
|
|
236
235
|
|
|
237
236
|
while not complete:
|
|
238
237
|
actions_taken = False
|
|
@@ -250,6 +250,8 @@ grammar = r"""
|
|
|
250
250
|
|
|
251
251
|
comparison: (expr COMPARISON_OPERATOR expr)
|
|
252
252
|
|
|
253
|
+
between_comparison: expr "BETWEEN"i expr "AND"i expr
|
|
254
|
+
|
|
253
255
|
subselect_comparison: expr array_comparison expr | (expr array_comparison expr_tuple)
|
|
254
256
|
|
|
255
257
|
expr_tuple: "(" (expr ",")* expr ","? ")"
|
|
@@ -262,7 +264,7 @@ grammar = r"""
|
|
|
262
264
|
|
|
263
265
|
parenthetical: "(" (conditional | expr) ")"
|
|
264
266
|
|
|
265
|
-
expr: window_item | filter_item | comparison | subselect_comparison | fgroup | aggregate_functions | unnest | _string_functions | _math_functions | _generic_functions | _constant_functions| _date_functions | literal | expr_reference | index_access | attr_access | parenthetical
|
|
267
|
+
expr: window_item | filter_item | between_comparison | comparison | subselect_comparison | fgroup | aggregate_functions | unnest | _string_functions | _math_functions | _generic_functions | _constant_functions| _date_functions | literal | expr_reference | index_access | attr_access | parenthetical
|
|
266
268
|
|
|
267
269
|
// functions
|
|
268
270
|
|
|
@@ -1241,6 +1243,19 @@ class ParseToObjects(Transformer):
|
|
|
1241
1243
|
raise SyntaxError
|
|
1242
1244
|
return Comparison(left=args[0], right=args[2], operator=args[1])
|
|
1243
1245
|
|
|
1246
|
+
def between_comparison(self, args) -> Conditional:
|
|
1247
|
+
left_bound = args[1]
|
|
1248
|
+
right_bound = args[2]
|
|
1249
|
+
return Conditional(
|
|
1250
|
+
left=Comparison(
|
|
1251
|
+
left=args[0], right=left_bound, operator=ComparisonOperator.GTE
|
|
1252
|
+
),
|
|
1253
|
+
right=Comparison(
|
|
1254
|
+
left=args[0], right=right_bound, operator=ComparisonOperator.LTE
|
|
1255
|
+
),
|
|
1256
|
+
operator=BooleanOperator.AND,
|
|
1257
|
+
)
|
|
1258
|
+
|
|
1244
1259
|
@v_args(meta=True)
|
|
1245
1260
|
def subselect_comparison(self, meta: Meta, args) -> SubselectComparison:
|
|
1246
1261
|
right = args[2]
|
|
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
|
{pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/concept_strategies_v3.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/__init__.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/basic_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/common.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/filter_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/group_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/group_to_node.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/rowset_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/select_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/unnest_node.py
RENAMED
|
File without changes
|
{pytrilogy-0.0.1.111 → pytrilogy-0.0.1.112}/trilogy/core/processing/node_generators/window_node.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
|