graphql-api 1.6.8__tar.gz → 1.6.9__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.
- {graphql_api-1.6.8 → graphql_api-1.6.9}/PKG-INFO +1 -1
- graphql_api-1.6.9/VERSION +1 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/api.py +24 -1
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/executor.py +6 -14
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/middleware.py +95 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api.egg-info/PKG-INFO +1 -1
- graphql_api-1.6.8/VERSION +0 -1
- {graphql_api-1.6.8 → graphql_api-1.6.9}/.github/workflows/pages.yml +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/.github/workflows/python-package.yml +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/.gitignore +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/.vscode/settings.json +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/AGENTS.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/CLAUDE.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/LICENSE +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/README.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/README.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/_index.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/_index.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/advanced-features/_index.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/advanced-features/directives.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/advanced-features/performance.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/advanced-features/schema-filtering.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/building-applications/_index.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/building-applications/documentation.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/building-applications/error-handling.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/distributed-systems/_index.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/distributed-systems/federation.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/distributed-systems/pagination-relay.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/distributed-systems/remote-graphql.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/fundamentals/_index.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/fundamentals/async-and-subscriptions.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/fundamentals/defining-schemas.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/fundamentals/enums-interfaces.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/fundamentals/field-types.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/fundamentals/getting-started.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/fundamentals/mutations.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/fundamentals/object-types.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/fundamentals/pydantic-and-dataclasses.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/production/_index.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/production/context-metadata.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/production/middleware.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/reference/_index.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/reference/api-reference.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/reference/contributing.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/reference/examples.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/hugo.toml +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/docs/index.md +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/__init__.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/context.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/dataclass_mapping.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/decorators.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/directives.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/error.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/exception.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/federation/__init__.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/federation/directives.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/federation/federation.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/federation/types.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/mapper.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/mutation_schema.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/pydantic.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/pydantic_utils.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/reduce.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/relay.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/remote.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/schema.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/schema_filter.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/type_utils.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/types.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api/utils.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api.egg-info/SOURCES.txt +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api.egg-info/dependency_links.txt +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api.egg-info/requires.txt +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/graphql_api.egg-info/top_level.txt +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/pyproject.toml +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/setup.cfg +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/__init__.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_async.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_calculator.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_custom_suffixes.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_custom_types.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_dataclass.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_dataclass_relationships.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_decorator_patterns.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_directives.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_docs_advanced.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_docs_async_subscriptions.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_docs_defining_schemas.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_docs_field_types.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_docs_getting_started.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_docs_relay.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_docstrings.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_error.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_federation.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_federation_example.graphql +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_federation_example.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_filtering.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_graphql.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_middleware.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_performance.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_plain_functions.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_pydantic.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_relay.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_remote.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_schema.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_subscriptions.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/tests/test_unified_vs_explicit_schema.py +0 -0
- {graphql_api-1.6.8 → graphql_api-1.6.9}/uv.lock +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.6.9
|
|
@@ -262,6 +262,7 @@ class GraphQLAPI(GraphQLBaseExecutor):
|
|
|
262
262
|
self.error_protection = error_protection
|
|
263
263
|
self.federation = federation
|
|
264
264
|
self._cached_schema: Optional[Tuple[GraphQLSchema, Dict]] = None
|
|
265
|
+
self._cached_executor: Optional[GraphQLExecutor] = None
|
|
265
266
|
self.max_docstring_length = max_docstring_length
|
|
266
267
|
self.enum_suffix = enum_suffix
|
|
267
268
|
self.interface_suffix = interface_suffix
|
|
@@ -904,10 +905,32 @@ class GraphQLAPI(GraphQLBaseExecutor):
|
|
|
904
905
|
operation_name=None,
|
|
905
906
|
root_value: Any = None,
|
|
906
907
|
) -> ExecutionResult:
|
|
907
|
-
|
|
908
|
+
# Reuse one executor across execute() calls: constructing one
|
|
909
|
+
# validates the schema and builds the middleware chain, which only
|
|
910
|
+
# depend on the (cached) schema. The root value keeps its per-call
|
|
911
|
+
# semantics — a fresh root instance per execution when root_type is
|
|
912
|
+
# callable — by being passed to execute() rather than frozen into
|
|
913
|
+
# the executor.
|
|
914
|
+
schema, meta = self.build()
|
|
915
|
+
executor = self._cached_executor
|
|
916
|
+
if executor is None or executor.schema is not schema:
|
|
917
|
+
executor = GraphQLExecutor(
|
|
918
|
+
schema=schema,
|
|
919
|
+
meta=meta,
|
|
920
|
+
root_value=None,
|
|
921
|
+
middleware=self.middleware,
|
|
922
|
+
error_protection=self.error_protection,
|
|
923
|
+
)
|
|
924
|
+
self._cached_executor = executor
|
|
925
|
+
|
|
926
|
+
if callable(self.root_type) and root_value is None:
|
|
927
|
+
root_value = self.root_type()
|
|
928
|
+
|
|
929
|
+
return executor.execute(
|
|
908
930
|
query=query,
|
|
909
931
|
variables=variables,
|
|
910
932
|
operation_name=operation_name,
|
|
933
|
+
root_value=root_value,
|
|
911
934
|
)
|
|
912
935
|
|
|
913
936
|
def executor(
|
|
@@ -19,14 +19,7 @@ from graphql.language import DocumentNode
|
|
|
19
19
|
from graphql.type.schema import GraphQLSchema
|
|
20
20
|
|
|
21
21
|
from graphql_api.context import GraphQLContext
|
|
22
|
-
from graphql_api.middleware import
|
|
23
|
-
middleware_adapt_enum,
|
|
24
|
-
middleware_call_coroutine,
|
|
25
|
-
middleware_catch_exception,
|
|
26
|
-
middleware_field_context,
|
|
27
|
-
middleware_local_proxy,
|
|
28
|
-
middleware_request_context,
|
|
29
|
-
)
|
|
22
|
+
from graphql_api.middleware import middleware_combined
|
|
30
23
|
|
|
31
24
|
|
|
32
25
|
class GraphQLBaseExecutor:
|
|
@@ -132,14 +125,13 @@ class GraphQLExecutor(GraphQLBaseExecutor):
|
|
|
132
125
|
self.meta = meta if meta is not None else {}
|
|
133
126
|
self.root_value = root_value
|
|
134
127
|
|
|
128
|
+
# The six built-in middleware are merged into one function: they run
|
|
129
|
+
# on every field resolution, and separate functions cost five extra
|
|
130
|
+
# call frames per field. Custom middleware stay innermost (closest to
|
|
131
|
+
# the resolver), exactly as with the individual built-ins.
|
|
135
132
|
self.middleware = [
|
|
136
133
|
*(middleware if middleware else []),
|
|
137
|
-
|
|
138
|
-
middleware_field_context,
|
|
139
|
-
middleware_request_context,
|
|
140
|
-
middleware_local_proxy,
|
|
141
|
-
middleware_adapt_enum,
|
|
142
|
-
middleware_call_coroutine,
|
|
134
|
+
middleware_combined,
|
|
143
135
|
]
|
|
144
136
|
|
|
145
137
|
# Build the middleware chain once. graphql-core constructs a fresh
|
|
@@ -145,3 +145,98 @@ def middleware_field_context(next_, root, info, **args):
|
|
|
145
145
|
info.context.field = None
|
|
146
146
|
|
|
147
147
|
return value
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def middleware_combined(next_, root, info, **args):
|
|
151
|
+
"""
|
|
152
|
+
All six built-in middleware merged into one function.
|
|
153
|
+
|
|
154
|
+
Runs on every field resolution, so the individual middleware — each a
|
|
155
|
+
trivial check — cost more in nested call frames than in work. This
|
|
156
|
+
preserves their exact composed semantics (outermost to innermost:
|
|
157
|
+
call_coroutine, adapt_enum, local_proxy, request_context, field_context,
|
|
158
|
+
catch_exception) in a single frame. The individual functions above remain
|
|
159
|
+
exported and behaviourally identical.
|
|
160
|
+
"""
|
|
161
|
+
from graphql_api.api import GraphQLFieldContext, GraphQLRequestContext
|
|
162
|
+
|
|
163
|
+
context = info.context
|
|
164
|
+
|
|
165
|
+
# -- field_context (set up) --
|
|
166
|
+
field_meta = context.meta.get(
|
|
167
|
+
(info.parent_type.name, to_snake_case(info.field_name)), {}
|
|
168
|
+
)
|
|
169
|
+
if field_meta is None:
|
|
170
|
+
field_meta = {}
|
|
171
|
+
return_type = info.return_type
|
|
172
|
+
unwrapped_type = (
|
|
173
|
+
return_type.of_type
|
|
174
|
+
if return_type and isinstance(return_type, GraphQLNonNull)
|
|
175
|
+
else return_type
|
|
176
|
+
)
|
|
177
|
+
kwargs = {}
|
|
178
|
+
if unwrapped_type and isinstance(unwrapped_type, GraphQLObjectType):
|
|
179
|
+
sub_loc = info.field_nodes[0].selection_set.loc
|
|
180
|
+
kwargs["query"] = sub_loc.source.body[sub_loc.start: sub_loc.end]
|
|
181
|
+
context.field = GraphQLFieldContext(meta=field_meta, **kwargs)
|
|
182
|
+
|
|
183
|
+
# -- request_context (set up) --
|
|
184
|
+
request_created = False
|
|
185
|
+
if not context.request:
|
|
186
|
+
context.request = GraphQLRequestContext(
|
|
187
|
+
args={to_snake_case(key): arg for key, arg in args.items()}, info=info
|
|
188
|
+
)
|
|
189
|
+
request_created = True
|
|
190
|
+
|
|
191
|
+
try:
|
|
192
|
+
# -- catch_exception --
|
|
193
|
+
try:
|
|
194
|
+
value = next_(root, info, **args)
|
|
195
|
+
except Exception as err:
|
|
196
|
+
from graphql_api.executor import ErrorProtectionExecutionContext
|
|
197
|
+
|
|
198
|
+
if field_meta.get(GraphQLMetaKey.error_protection) is not None:
|
|
199
|
+
setattr(
|
|
200
|
+
err,
|
|
201
|
+
ErrorProtectionExecutionContext.error_protection,
|
|
202
|
+
field_meta.get(GraphQLMetaKey.error_protection),
|
|
203
|
+
)
|
|
204
|
+
ignored = isinstance(info.return_type, GraphQLNonNull)
|
|
205
|
+
print(
|
|
206
|
+
f"GraphQLField '{info.field_name}' on '{info.parent_type.name}' "
|
|
207
|
+
f"resolver {'(ignored) ' if ignored else ''}Exception: {err} ",
|
|
208
|
+
file=sys.stderr,
|
|
209
|
+
)
|
|
210
|
+
traceback.print_exc()
|
|
211
|
+
raise err
|
|
212
|
+
finally:
|
|
213
|
+
if request_created:
|
|
214
|
+
context.request = None
|
|
215
|
+
context.field = None
|
|
216
|
+
|
|
217
|
+
# -- local_proxy --
|
|
218
|
+
try:
|
|
219
|
+
if hasattr(value, "_get_current_object"):
|
|
220
|
+
# noinspection PyProtectedMember
|
|
221
|
+
value = value._get_current_object()
|
|
222
|
+
except GraphQLError:
|
|
223
|
+
# hasattr calls getattr and remote.getattr() can raise a GraphQLError
|
|
224
|
+
# if the object doesn't have the attr
|
|
225
|
+
pass
|
|
226
|
+
if isinstance(value, Exception):
|
|
227
|
+
raise value
|
|
228
|
+
|
|
229
|
+
# -- adapt_enum --
|
|
230
|
+
if isinstance(value, enum.Enum) and not isinstance(value, TypeKind):
|
|
231
|
+
value = value.value
|
|
232
|
+
|
|
233
|
+
# -- call_coroutine --
|
|
234
|
+
if inspect.iscoroutine(value):
|
|
235
|
+
# Async GraphQL execution already awaits resolver coroutines.
|
|
236
|
+
# Only force resolution when called from a sync context.
|
|
237
|
+
try:
|
|
238
|
+
asyncio.get_running_loop()
|
|
239
|
+
except RuntimeError:
|
|
240
|
+
value = asyncio.run(value)
|
|
241
|
+
|
|
242
|
+
return value
|
graphql_api-1.6.8/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1.6.8
|
|
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
|
{graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/advanced-features/schema-filtering.md
RENAMED
|
File without changes
|
|
File without changes
|
{graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/building-applications/documentation.md
RENAMED
|
File without changes
|
{graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/building-applications/error-handling.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/distributed-systems/pagination-relay.md
RENAMED
|
File without changes
|
{graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/distributed-systems/remote-graphql.md
RENAMED
|
File without changes
|
|
File without changes
|
{graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/fundamentals/async-and-subscriptions.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphql_api-1.6.8 → graphql_api-1.6.9}/docs/content/docs/fundamentals/pydantic-and-dataclasses.md
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
|