plain 0.40.0__tar.gz → 0.41.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.
Files changed (164) hide show
  1. {plain-0.40.0 → plain-0.41.0}/PKG-INFO +1 -1
  2. {plain-0.40.0 → plain-0.41.0}/plain/internal/handlers/base.py +2 -2
  3. {plain-0.40.0 → plain-0.41.0}/plain/urls/patterns.py +4 -5
  4. {plain-0.40.0 → plain-0.41.0}/plain/urls/resolvers.py +14 -65
  5. {plain-0.40.0 → plain-0.41.0}/plain/views/templates.py +1 -0
  6. {plain-0.40.0 → plain-0.41.0}/pyproject.toml +1 -1
  7. {plain-0.40.0 → plain-0.41.0}/.gitignore +0 -0
  8. {plain-0.40.0 → plain-0.41.0}/LICENSE +0 -0
  9. {plain-0.40.0 → plain-0.41.0}/README.md +0 -0
  10. {plain-0.40.0 → plain-0.41.0}/plain/README.md +0 -0
  11. {plain-0.40.0 → plain-0.41.0}/plain/__main__.py +0 -0
  12. {plain-0.40.0 → plain-0.41.0}/plain/assets/README.md +0 -0
  13. {plain-0.40.0 → plain-0.41.0}/plain/assets/__init__.py +0 -0
  14. {plain-0.40.0 → plain-0.41.0}/plain/assets/compile.py +0 -0
  15. {plain-0.40.0 → plain-0.41.0}/plain/assets/finders.py +0 -0
  16. {plain-0.40.0 → plain-0.41.0}/plain/assets/fingerprints.py +0 -0
  17. {plain-0.40.0 → plain-0.41.0}/plain/assets/urls.py +0 -0
  18. {plain-0.40.0 → plain-0.41.0}/plain/assets/views.py +0 -0
  19. {plain-0.40.0 → plain-0.41.0}/plain/chores/README.md +0 -0
  20. {plain-0.40.0 → plain-0.41.0}/plain/chores/__init__.py +0 -0
  21. {plain-0.40.0 → plain-0.41.0}/plain/chores/registry.py +0 -0
  22. {plain-0.40.0 → plain-0.41.0}/plain/cli/README.md +0 -0
  23. {plain-0.40.0 → plain-0.41.0}/plain/cli/__init__.py +0 -0
  24. {plain-0.40.0 → plain-0.41.0}/plain/cli/build.py +0 -0
  25. {plain-0.40.0 → plain-0.41.0}/plain/cli/chores.py +0 -0
  26. {plain-0.40.0 → plain-0.41.0}/plain/cli/core.py +0 -0
  27. {plain-0.40.0 → plain-0.41.0}/plain/cli/docs.py +0 -0
  28. {plain-0.40.0 → plain-0.41.0}/plain/cli/formatting.py +0 -0
  29. {plain-0.40.0 → plain-0.41.0}/plain/cli/preflight.py +0 -0
  30. {plain-0.40.0 → plain-0.41.0}/plain/cli/print.py +0 -0
  31. {plain-0.40.0 → plain-0.41.0}/plain/cli/registry.py +0 -0
  32. {plain-0.40.0 → plain-0.41.0}/plain/cli/scaffold.py +0 -0
  33. {plain-0.40.0 → plain-0.41.0}/plain/cli/settings.py +0 -0
  34. {plain-0.40.0 → plain-0.41.0}/plain/cli/shell.py +0 -0
  35. {plain-0.40.0 → plain-0.41.0}/plain/cli/startup.py +0 -0
  36. {plain-0.40.0 → plain-0.41.0}/plain/cli/urls.py +0 -0
  37. {plain-0.40.0 → plain-0.41.0}/plain/cli/utils.py +0 -0
  38. {plain-0.40.0 → plain-0.41.0}/plain/csrf/README.md +0 -0
  39. {plain-0.40.0 → plain-0.41.0}/plain/csrf/middleware.py +0 -0
  40. {plain-0.40.0 → plain-0.41.0}/plain/csrf/views.py +0 -0
  41. {plain-0.40.0 → plain-0.41.0}/plain/debug.py +0 -0
  42. {plain-0.40.0 → plain-0.41.0}/plain/exceptions.py +0 -0
  43. {plain-0.40.0 → plain-0.41.0}/plain/forms/README.md +0 -0
  44. {plain-0.40.0 → plain-0.41.0}/plain/forms/__init__.py +0 -0
  45. {plain-0.40.0 → plain-0.41.0}/plain/forms/boundfield.py +0 -0
  46. {plain-0.40.0 → plain-0.41.0}/plain/forms/exceptions.py +0 -0
  47. {plain-0.40.0 → plain-0.41.0}/plain/forms/fields.py +0 -0
  48. {plain-0.40.0 → plain-0.41.0}/plain/forms/forms.py +0 -0
  49. {plain-0.40.0 → plain-0.41.0}/plain/http/README.md +0 -0
  50. {plain-0.40.0 → plain-0.41.0}/plain/http/__init__.py +0 -0
  51. {plain-0.40.0 → plain-0.41.0}/plain/http/cookie.py +0 -0
  52. {plain-0.40.0 → plain-0.41.0}/plain/http/multipartparser.py +0 -0
  53. {plain-0.40.0 → plain-0.41.0}/plain/http/request.py +0 -0
  54. {plain-0.40.0 → plain-0.41.0}/plain/http/response.py +0 -0
  55. {plain-0.40.0 → plain-0.41.0}/plain/internal/__init__.py +0 -0
  56. {plain-0.40.0 → plain-0.41.0}/plain/internal/files/__init__.py +0 -0
  57. {plain-0.40.0 → plain-0.41.0}/plain/internal/files/base.py +0 -0
  58. {plain-0.40.0 → plain-0.41.0}/plain/internal/files/locks.py +0 -0
  59. {plain-0.40.0 → plain-0.41.0}/plain/internal/files/move.py +0 -0
  60. {plain-0.40.0 → plain-0.41.0}/plain/internal/files/temp.py +0 -0
  61. {plain-0.40.0 → plain-0.41.0}/plain/internal/files/uploadedfile.py +0 -0
  62. {plain-0.40.0 → plain-0.41.0}/plain/internal/files/uploadhandler.py +0 -0
  63. {plain-0.40.0 → plain-0.41.0}/plain/internal/files/utils.py +0 -0
  64. {plain-0.40.0 → plain-0.41.0}/plain/internal/handlers/__init__.py +0 -0
  65. {plain-0.40.0 → plain-0.41.0}/plain/internal/handlers/exception.py +0 -0
  66. {plain-0.40.0 → plain-0.41.0}/plain/internal/handlers/wsgi.py +0 -0
  67. {plain-0.40.0 → plain-0.41.0}/plain/internal/middleware/__init__.py +0 -0
  68. {plain-0.40.0 → plain-0.41.0}/plain/internal/middleware/headers.py +0 -0
  69. {plain-0.40.0 → plain-0.41.0}/plain/internal/middleware/https.py +0 -0
  70. {plain-0.40.0 → plain-0.41.0}/plain/internal/middleware/slash.py +0 -0
  71. {plain-0.40.0 → plain-0.41.0}/plain/json.py +0 -0
  72. {plain-0.40.0 → plain-0.41.0}/plain/logs/README.md +0 -0
  73. {plain-0.40.0 → plain-0.41.0}/plain/logs/__init__.py +0 -0
  74. {plain-0.40.0 → plain-0.41.0}/plain/logs/configure.py +0 -0
  75. {plain-0.40.0 → plain-0.41.0}/plain/logs/loggers.py +0 -0
  76. {plain-0.40.0 → plain-0.41.0}/plain/logs/utils.py +0 -0
  77. {plain-0.40.0 → plain-0.41.0}/plain/packages/README.md +0 -0
  78. {plain-0.40.0 → plain-0.41.0}/plain/packages/__init__.py +0 -0
  79. {plain-0.40.0 → plain-0.41.0}/plain/packages/config.py +0 -0
  80. {plain-0.40.0 → plain-0.41.0}/plain/packages/registry.py +0 -0
  81. {plain-0.40.0 → plain-0.41.0}/plain/paginator.py +0 -0
  82. {plain-0.40.0 → plain-0.41.0}/plain/preflight/README.md +0 -0
  83. {plain-0.40.0 → plain-0.41.0}/plain/preflight/__init__.py +0 -0
  84. {plain-0.40.0 → plain-0.41.0}/plain/preflight/files.py +0 -0
  85. {plain-0.40.0 → plain-0.41.0}/plain/preflight/messages.py +0 -0
  86. {plain-0.40.0 → plain-0.41.0}/plain/preflight/registry.py +0 -0
  87. {plain-0.40.0 → plain-0.41.0}/plain/preflight/security.py +0 -0
  88. {plain-0.40.0 → plain-0.41.0}/plain/preflight/urls.py +0 -0
  89. {plain-0.40.0 → plain-0.41.0}/plain/runtime/README.md +0 -0
  90. {plain-0.40.0 → plain-0.41.0}/plain/runtime/__init__.py +0 -0
  91. {plain-0.40.0 → plain-0.41.0}/plain/runtime/global_settings.py +0 -0
  92. {plain-0.40.0 → plain-0.41.0}/plain/runtime/user_settings.py +0 -0
  93. {plain-0.40.0 → plain-0.41.0}/plain/signals/README.md +0 -0
  94. {plain-0.40.0 → plain-0.41.0}/plain/signals/__init__.py +0 -0
  95. {plain-0.40.0 → plain-0.41.0}/plain/signals/dispatch/__init__.py +0 -0
  96. {plain-0.40.0 → plain-0.41.0}/plain/signals/dispatch/dispatcher.py +0 -0
  97. {plain-0.40.0 → plain-0.41.0}/plain/signals/dispatch/license.txt +0 -0
  98. {plain-0.40.0 → plain-0.41.0}/plain/signing.py +0 -0
  99. {plain-0.40.0 → plain-0.41.0}/plain/templates/README.md +0 -0
  100. {plain-0.40.0 → plain-0.41.0}/plain/templates/__init__.py +0 -0
  101. {plain-0.40.0 → plain-0.41.0}/plain/templates/core.py +0 -0
  102. {plain-0.40.0 → plain-0.41.0}/plain/templates/jinja/__init__.py +0 -0
  103. {plain-0.40.0 → plain-0.41.0}/plain/templates/jinja/environments.py +0 -0
  104. {plain-0.40.0 → plain-0.41.0}/plain/templates/jinja/extensions.py +0 -0
  105. {plain-0.40.0 → plain-0.41.0}/plain/templates/jinja/filters.py +0 -0
  106. {plain-0.40.0 → plain-0.41.0}/plain/templates/jinja/globals.py +0 -0
  107. {plain-0.40.0 → plain-0.41.0}/plain/test/README.md +0 -0
  108. {plain-0.40.0 → plain-0.41.0}/plain/test/__init__.py +0 -0
  109. {plain-0.40.0 → plain-0.41.0}/plain/test/client.py +0 -0
  110. {plain-0.40.0 → plain-0.41.0}/plain/test/encoding.py +0 -0
  111. {plain-0.40.0 → plain-0.41.0}/plain/test/exceptions.py +0 -0
  112. {plain-0.40.0 → plain-0.41.0}/plain/urls/README.md +0 -0
  113. {plain-0.40.0 → plain-0.41.0}/plain/urls/__init__.py +0 -0
  114. {plain-0.40.0 → plain-0.41.0}/plain/urls/converters.py +0 -0
  115. {plain-0.40.0 → plain-0.41.0}/plain/urls/exceptions.py +0 -0
  116. {plain-0.40.0 → plain-0.41.0}/plain/urls/routers.py +0 -0
  117. {plain-0.40.0 → plain-0.41.0}/plain/urls/utils.py +0 -0
  118. {plain-0.40.0 → plain-0.41.0}/plain/utils/README.md +0 -0
  119. {plain-0.40.0 → plain-0.41.0}/plain/utils/__init__.py +0 -0
  120. {plain-0.40.0 → plain-0.41.0}/plain/utils/cache.py +0 -0
  121. {plain-0.40.0 → plain-0.41.0}/plain/utils/connection.py +0 -0
  122. {plain-0.40.0 → plain-0.41.0}/plain/utils/crypto.py +0 -0
  123. {plain-0.40.0 → plain-0.41.0}/plain/utils/datastructures.py +0 -0
  124. {plain-0.40.0 → plain-0.41.0}/plain/utils/dateparse.py +0 -0
  125. {plain-0.40.0 → plain-0.41.0}/plain/utils/deconstruct.py +0 -0
  126. {plain-0.40.0 → plain-0.41.0}/plain/utils/decorators.py +0 -0
  127. {plain-0.40.0 → plain-0.41.0}/plain/utils/duration.py +0 -0
  128. {plain-0.40.0 → plain-0.41.0}/plain/utils/encoding.py +0 -0
  129. {plain-0.40.0 → plain-0.41.0}/plain/utils/functional.py +0 -0
  130. {plain-0.40.0 → plain-0.41.0}/plain/utils/hashable.py +0 -0
  131. {plain-0.40.0 → plain-0.41.0}/plain/utils/html.py +0 -0
  132. {plain-0.40.0 → plain-0.41.0}/plain/utils/http.py +0 -0
  133. {plain-0.40.0 → plain-0.41.0}/plain/utils/inspect.py +0 -0
  134. {plain-0.40.0 → plain-0.41.0}/plain/utils/ipv6.py +0 -0
  135. {plain-0.40.0 → plain-0.41.0}/plain/utils/itercompat.py +0 -0
  136. {plain-0.40.0 → plain-0.41.0}/plain/utils/module_loading.py +0 -0
  137. {plain-0.40.0 → plain-0.41.0}/plain/utils/regex_helper.py +0 -0
  138. {plain-0.40.0 → plain-0.41.0}/plain/utils/safestring.py +0 -0
  139. {plain-0.40.0 → plain-0.41.0}/plain/utils/text.py +0 -0
  140. {plain-0.40.0 → plain-0.41.0}/plain/utils/timesince.py +0 -0
  141. {plain-0.40.0 → plain-0.41.0}/plain/utils/timezone.py +0 -0
  142. {plain-0.40.0 → plain-0.41.0}/plain/utils/tree.py +0 -0
  143. {plain-0.40.0 → plain-0.41.0}/plain/validators.py +0 -0
  144. {plain-0.40.0 → plain-0.41.0}/plain/views/README.md +0 -0
  145. {plain-0.40.0 → plain-0.41.0}/plain/views/__init__.py +0 -0
  146. {plain-0.40.0 → plain-0.41.0}/plain/views/base.py +0 -0
  147. {plain-0.40.0 → plain-0.41.0}/plain/views/csrf.py +0 -0
  148. {plain-0.40.0 → plain-0.41.0}/plain/views/errors.py +0 -0
  149. {plain-0.40.0 → plain-0.41.0}/plain/views/exceptions.py +0 -0
  150. {plain-0.40.0 → plain-0.41.0}/plain/views/forms.py +0 -0
  151. {plain-0.40.0 → plain-0.41.0}/plain/views/objects.py +0 -0
  152. {plain-0.40.0 → plain-0.41.0}/plain/views/redirect.py +0 -0
  153. {plain-0.40.0 → plain-0.41.0}/plain/wsgi.py +0 -0
  154. {plain-0.40.0 → plain-0.41.0}/tests/.bolt/assets_collected/assets.json +0 -0
  155. {plain-0.40.0 → plain-0.41.0}/tests/.gitignore +0 -0
  156. {plain-0.40.0 → plain-0.41.0}/tests/app/.gitignore +0 -0
  157. {plain-0.40.0 → plain-0.41.0}/tests/app/settings.py +0 -0
  158. {plain-0.40.0 → plain-0.41.0}/tests/app/test/__init__.py +0 -0
  159. {plain-0.40.0 → plain-0.41.0}/tests/app/test/default_settings.py +0 -0
  160. {plain-0.40.0 → plain-0.41.0}/tests/app/urls.py +0 -0
  161. {plain-0.40.0 → plain-0.41.0}/tests/conftest.py +0 -0
  162. {plain-0.40.0 → plain-0.41.0}/tests/test_cli.py +0 -0
  163. {plain-0.40.0 → plain-0.41.0}/tests/test_runtime.py +0 -0
  164. {plain-0.40.0 → plain-0.41.0}/tests/test_wsgi.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain
3
- Version: 0.40.0
3
+ Version: 0.41.0
4
4
  Summary: A web framework for building products with Python.
5
5
  Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
6
6
  License-File: LICENSE
@@ -80,12 +80,12 @@ class BaseHandler:
80
80
  """
81
81
  resolver_match = self.resolve_request(request)
82
82
 
83
- response = resolver_match.func(
83
+ response = resolver_match.view(
84
84
  request, *resolver_match.args, **resolver_match.kwargs
85
85
  )
86
86
 
87
87
  # Complain if the view returned None (a common error).
88
- self.check_response(response, resolver_match.func)
88
+ self.check_response(response, resolver_match.view)
89
89
 
90
90
  return response
91
91
 
@@ -247,12 +247,11 @@ class URLPattern:
247
247
  from .resolvers import ResolverMatch
248
248
 
249
249
  return ResolverMatch(
250
- self.view,
251
- args,
252
- captured_kwargs,
253
- self.pattern.name,
250
+ view=self.view,
251
+ args=args,
252
+ kwargs=captured_kwargs,
253
+ url_name=self.pattern.name,
254
254
  route=str(self.pattern),
255
- captured_kwargs=captured_kwargs,
256
255
  )
257
256
 
258
257
  @cached_property
@@ -8,7 +8,6 @@ attributes of the resolved URL match.
8
8
 
9
9
  import functools
10
10
  import re
11
- from pickle import PicklingError
12
11
  from threading import local
13
12
  from urllib.parse import quote
14
13
 
@@ -26,66 +25,29 @@ from .patterns import RegexPattern, URLPattern
26
25
  class ResolverMatch:
27
26
  def __init__(
28
27
  self,
29
- func,
28
+ *,
29
+ view,
30
30
  args,
31
31
  kwargs,
32
32
  url_name=None,
33
33
  namespaces=None,
34
34
  route=None,
35
- tried=None,
36
- captured_kwargs=None,
37
- extra_kwargs=None,
38
35
  ):
39
- self.func = func
36
+ self.view = view
40
37
  self.args = args
41
38
  self.kwargs = kwargs
42
39
  self.url_name = url_name
43
40
  self.route = route
44
- self.tried = tried
45
- self.captured_kwargs = captured_kwargs
46
- self.extra_kwargs = extra_kwargs
47
41
 
48
42
  # If a URLRegexResolver doesn't have a namespace or namespace, it passes
49
43
  # in an empty value.
50
44
  self.namespaces = [x for x in namespaces if x] if namespaces else []
51
45
  self.namespace = ":".join(self.namespaces)
52
46
 
53
- if hasattr(func, "view_class"):
54
- func = func.view_class
55
- if not hasattr(func, "__name__"):
56
- # A class-based view
57
- self._func_path = func.__class__.__module__ + "." + func.__class__.__name__
58
- else:
59
- # A function-based view
60
- self._func_path = func.__module__ + "." + func.__name__
61
-
62
- view_path = url_name or self._func_path
63
- self.view_name = ":".join(self.namespaces + [view_path])
64
-
65
- def __repr__(self):
66
- if isinstance(self.func, functools.partial):
67
- func = repr(self.func)
68
- else:
69
- func = self._func_path
70
- return (
71
- "ResolverMatch(func={}, args={!r}, kwargs={!r}, url_name={!r}, "
72
- "namespaces={!r}, route={!r}{}{})".format(
73
- func,
74
- self.args,
75
- self.kwargs,
76
- self.url_name,
77
- self.namespaces,
78
- self.route,
79
- f", captured_kwargs={self.captured_kwargs!r}"
80
- if self.captured_kwargs
81
- else "",
82
- f", extra_kwargs={self.extra_kwargs!r}" if self.extra_kwargs else "",
83
- )
47
+ self.namespaced_url_name = (
48
+ ":".join(self.namespaces + [url_name]) if url_name else None
84
49
  )
85
50
 
86
- def __reduce_ex__(self, protocol):
87
- raise PicklingError(f"Cannot pickle {self.__class__.__qualname__}.")
88
-
89
51
 
90
52
  def get_resolver(router=None):
91
53
  if router is None:
@@ -257,13 +219,6 @@ class URLResolver:
257
219
  self._populate()
258
220
  return self._app_dict
259
221
 
260
- @staticmethod
261
- def _extend_tried(tried, pattern, sub_tried=None):
262
- if sub_tried is None:
263
- tried.append([pattern])
264
- else:
265
- tried.extend([pattern, *t] for t in sub_tried)
266
-
267
222
  @staticmethod
268
223
  def _join_route(route1, route2):
269
224
  """Join two routes, without the starting ^ in the second route."""
@@ -274,15 +229,14 @@ class URLResolver:
274
229
 
275
230
  def resolve(self, path):
276
231
  path = str(path) # path may be a reverse_lazy object
277
- tried = []
278
232
  match = self.pattern.match(path)
279
233
  if match:
280
234
  new_path, args, kwargs = match
281
235
  for pattern in self.url_patterns:
282
236
  try:
283
237
  sub_match = pattern.resolve(new_path)
284
- except Resolver404 as e:
285
- self._extend_tried(tried, pattern, e.args[0].get("tried"))
238
+ except Resolver404:
239
+ pass
286
240
  else:
287
241
  if sub_match:
288
242
  # Merge captured arguments in match with submatch
@@ -299,20 +253,15 @@ class URLResolver:
299
253
  if isinstance(pattern, URLPattern)
300
254
  else str(pattern.pattern)
301
255
  )
302
- self._extend_tried(tried, pattern, sub_match.tried)
303
256
  return ResolverMatch(
304
- sub_match.func,
305
- sub_match_args,
306
- sub_match_dict,
307
- sub_match.url_name,
308
- [self.namespace] + sub_match.namespaces,
309
- self._join_route(current_route, sub_match.route),
310
- tried,
311
- captured_kwargs=sub_match.captured_kwargs,
312
- extra_kwargs=sub_match.extra_kwargs,
257
+ view=sub_match.view,
258
+ args=sub_match_args,
259
+ kwargs=sub_match_dict,
260
+ url_name=sub_match.url_name,
261
+ namespaces=[self.namespace] + sub_match.namespaces,
262
+ route=self._join_route(current_route, sub_match.route),
313
263
  )
314
- tried.append([pattern])
315
- raise Resolver404({"tried": tried, "path": new_path})
264
+ raise Resolver404({"path": new_path})
316
265
  raise Resolver404({"path": path})
317
266
 
318
267
  def reverse(self, lookup_view, *args, **kwargs):
@@ -35,6 +35,7 @@ class TemplateView(View):
35
35
  def get_template_context(self) -> dict:
36
36
  return {
37
37
  "request": self.request,
38
+ "template_names": self.get_template_names(),
38
39
  "csrf_input": csrf_input_lazy(self.request),
39
40
  "csrf_token": csrf_token_lazy(self.request),
40
41
  "DEBUG": settings.DEBUG,
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "plain"
3
- version = "0.40.0"
3
+ version = "0.41.0"
4
4
  description = "A web framework for building products with Python."
5
5
  authors = [{name = "Dave Gaeddert", email = "dave.gaeddert@dropseed.dev"}]
6
6
  readme = "README.md"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes