XspecT 0.2.6__tar.gz → 0.2.7__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 XspecT might be problematic. Click here for more details.

Files changed (94) hide show
  1. {xspect-0.2.6 → xspect-0.2.7}/PKG-INFO +1 -1
  2. {xspect-0.2.6 → xspect-0.2.7}/pyproject.toml +1 -1
  3. {xspect-0.2.6 → xspect-0.2.7}/src/XspecT.egg-info/PKG-INFO +1 -1
  4. {xspect-0.2.6 → xspect-0.2.7}/src/XspecT.egg-info/SOURCES.txt +0 -1
  5. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/mlst_feature/mlst_helper.py +1 -1
  6. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/models/result.py +1 -1
  7. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/pipeline.py +1 -1
  8. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/run.py +1 -1
  9. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/train.py +1 -6
  10. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/train_filter/extract_and_concatenate.py +1 -1
  11. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/train_filter/ncbi_api/download_assemblies.py +2 -2
  12. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/train_filter/ncbi_api/ncbi_assembly_metadata.py +13 -13
  13. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/train_filter/ncbi_api/ncbi_children_tree.py +1 -1
  14. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/train_filter/ncbi_api/ncbi_taxon_metadata.py +2 -2
  15. {xspect-0.2.6 → xspect-0.2.7}/tests/test_probabilistic_filter_svm_model.py +1 -1
  16. xspect-0.2.6/src/xspect/train_filter/html_scrap.py +0 -114
  17. {xspect-0.2.6 → xspect-0.2.7}/.github/workflows/black.yml +0 -0
  18. {xspect-0.2.6 → xspect-0.2.7}/.github/workflows/docs.yml +0 -0
  19. {xspect-0.2.6 → xspect-0.2.7}/.github/workflows/pylint.yml +0 -0
  20. {xspect-0.2.6 → xspect-0.2.7}/.github/workflows/pypi.yml +0 -0
  21. {xspect-0.2.6 → xspect-0.2.7}/.github/workflows/test.yml +0 -0
  22. {xspect-0.2.6 → xspect-0.2.7}/.gitignore +0 -0
  23. {xspect-0.2.6 → xspect-0.2.7}/LICENSE +0 -0
  24. {xspect-0.2.6 → xspect-0.2.7}/README.md +0 -0
  25. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/About.png +0 -0
  26. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/AddFilter.png +0 -0
  27. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/AddSpecies1.png +0 -0
  28. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/AddSpecies2.png +0 -0
  29. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/BF.png +0 -0
  30. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/ClAssT_Ergebnis1.png +0 -0
  31. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/ClAssT_Ergebnis2.png +0 -0
  32. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/ClAssT_Ergebnis3.png +0 -0
  33. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/ClAssT_Hauptseite.png +0 -0
  34. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/CommandLine_Input.png +0 -0
  35. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/CommandLine_results.png +0 -0
  36. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/CommandLine_whole.png +0 -0
  37. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/How2Use.png +0 -0
  38. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/HowtouseAspecT.png +0 -0
  39. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/XspecT_Ergebnis1.png +0 -0
  40. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/XspecT_Ergebnis2.png +0 -0
  41. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/XspecT_Ergebnis3.png +0 -0
  42. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/XspecT_Ergebnis4.png +0 -0
  43. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/XspecT_Hauptseite.png +0 -0
  44. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/XspecT_Runtime.png +0 -0
  45. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/XspecT_Runtime_Oxa.png +0 -0
  46. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/XspecT_Startseite.png +0 -0
  47. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/change_pw.png +0 -0
  48. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/modify_vecs.png +0 -0
  49. {xspect-0.2.6 → xspect-0.2.7}/docs/Instructions/pictures/secretkey.png +0 -0
  50. {xspect-0.2.6 → xspect-0.2.7}/docs/Makefile +0 -0
  51. {xspect-0.2.6 → xspect-0.2.7}/docs/cli.md +0 -0
  52. {xspect-0.2.6 → xspect-0.2.7}/docs/conf.py +0 -0
  53. {xspect-0.2.6 → xspect-0.2.7}/docs/diagrams/probabilistic_filter_models.md +0 -0
  54. {xspect-0.2.6 → xspect-0.2.7}/docs/img/logo.png +0 -0
  55. {xspect-0.2.6 → xspect-0.2.7}/docs/index.md +0 -0
  56. {xspect-0.2.6 → xspect-0.2.7}/docs/input_data.md +0 -0
  57. {xspect-0.2.6 → xspect-0.2.7}/docs/installation.md +0 -0
  58. {xspect-0.2.6 → xspect-0.2.7}/docs/make.bat +0 -0
  59. {xspect-0.2.6 → xspect-0.2.7}/docs/quickstart.md +0 -0
  60. {xspect-0.2.6 → xspect-0.2.7}/docs/web.md +0 -0
  61. {xspect-0.2.6 → xspect-0.2.7}/setup.cfg +0 -0
  62. {xspect-0.2.6 → xspect-0.2.7}/src/XspecT.egg-info/dependency_links.txt +0 -0
  63. {xspect-0.2.6 → xspect-0.2.7}/src/XspecT.egg-info/entry_points.txt +0 -0
  64. {xspect-0.2.6 → xspect-0.2.7}/src/XspecT.egg-info/requires.txt +0 -0
  65. {xspect-0.2.6 → xspect-0.2.7}/src/XspecT.egg-info/top_level.txt +0 -0
  66. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/__init__.py +0 -0
  67. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/definitions.py +0 -0
  68. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/download_models.py +0 -0
  69. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/fastapi.py +0 -0
  70. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/file_io.py +0 -0
  71. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/main.py +0 -0
  72. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/mlst_feature/__init__.py +0 -0
  73. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/mlst_feature/pub_mlst_handler.py +0 -0
  74. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/model_management.py +0 -0
  75. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/models/__init__.py +0 -0
  76. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/models/probabilistic_filter_mlst_model.py +0 -0
  77. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/models/probabilistic_filter_model.py +0 -0
  78. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/models/probabilistic_filter_svm_model.py +0 -0
  79. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/models/probabilistic_single_filter_model.py +0 -0
  80. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/train_filter/__init__.py +0 -0
  81. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/train_filter/create_svm.py +0 -0
  82. {xspect-0.2.6 → xspect-0.2.7}/src/xspect/train_filter/ncbi_api/__init__.py +0 -0
  83. {xspect-0.2.6 → xspect-0.2.7}/tests/__init__.py +0 -0
  84. {xspect-0.2.6 → xspect-0.2.7}/tests/conftest.py +0 -0
  85. {xspect-0.2.6 → xspect-0.2.7}/tests/test_cli.py +0 -0
  86. {xspect-0.2.6 → xspect-0.2.7}/tests/test_file_io.py +0 -0
  87. {xspect-0.2.6 → xspect-0.2.7}/tests/test_model_management.py +0 -0
  88. {xspect-0.2.6 → xspect-0.2.7}/tests/test_model_result.py +0 -0
  89. {xspect-0.2.6 → xspect-0.2.7}/tests/test_pipeline.py +0 -0
  90. {xspect-0.2.6 → xspect-0.2.7}/tests/test_probabilisitc_filter_mlst_model.py +0 -0
  91. {xspect-0.2.6 → xspect-0.2.7}/tests/test_probabilistic_filter_model.py +0 -0
  92. {xspect-0.2.6 → xspect-0.2.7}/tests/test_probabilistic_single_filter_model.py +0 -0
  93. {xspect-0.2.6 → xspect-0.2.7}/tests/test_pub_mlst_handler.py +0 -0
  94. {xspect-0.2.6 → xspect-0.2.7}/tests/test_train.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: XspecT
3
- Version: 0.2.6
3
+ Version: 0.2.7
4
4
  Summary: Tool to monitor and characterize pathogens using Bloom filters.
5
5
  License: MIT License
6
6
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "XspecT"
3
- version = "0.2.6"
3
+ version = "0.2.7"
4
4
  description = "Tool to monitor and characterize pathogens using Bloom filters."
5
5
  readme = {file = "README.md", content-type = "text/markdown"}
6
6
  license = {file = "LICENSE"}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: XspecT
3
- Version: 0.2.6
3
+ Version: 0.2.7
4
4
  Summary: Tool to monitor and characterize pathogens using Bloom filters.
5
5
  License: MIT License
6
6
 
@@ -71,7 +71,6 @@ src/xspect/models/result.py
71
71
  src/xspect/train_filter/__init__.py
72
72
  src/xspect/train_filter/create_svm.py
73
73
  src/xspect/train_filter/extract_and_concatenate.py
74
- src/xspect/train_filter/html_scrap.py
75
74
  src/xspect/train_filter/ncbi_api/__init__.py
76
75
  src/xspect/train_filter/ncbi_api/download_assemblies.py
77
76
  src/xspect/train_filter/ncbi_api/ncbi_assembly_metadata.py
@@ -1,4 +1,4 @@
1
- """ Module for utility functions used in other modules regarding MLST. """
1
+ """Module for utility functions used in other modules regarding MLST."""
2
2
 
3
3
  __author__ = "Cetin, Oemer"
4
4
 
@@ -1,4 +1,4 @@
1
- """ Module for storing the results of XspecT models. """
1
+ """Module for storing the results of XspecT models."""
2
2
 
3
3
  from enum import Enum
4
4
 
@@ -1,4 +1,4 @@
1
- """ Module for defining the Pipeline class. """
1
+ """Module for defining the Pipeline class."""
2
2
 
3
3
  import json
4
4
  from pathlib import Path
@@ -1,4 +1,4 @@
1
- """ Module with XspecT global run class, which summarizes individual model results. """
1
+ """Module with XspecT global run class, which summarizes individual model results."""
2
2
 
3
3
  import json
4
4
  from pathlib import Path
@@ -22,7 +22,6 @@ from xspect.train_filter.ncbi_api import (
22
22
  )
23
23
  from xspect.train_filter import (
24
24
  create_svm,
25
- html_scrap,
26
25
  extract_and_concatenate,
27
26
  )
28
27
 
@@ -136,14 +135,10 @@ def train_ncbi(genus: str, svm_step: int = 1):
136
135
  children_ids = ncbi_children_tree.NCBIChildrenTree(genus).children_ids()
137
136
  species_dict = ncbi_taxon_metadata.NCBITaxonMetadata(children_ids).get_metadata()
138
137
 
139
- # Get all gcf accessions that have Taxonomy check result OK.
140
- logger.info("Checking ANI data for updates")
141
- ani_gcf = html_scrap.TaxonomyCheck().ani_gcf()
142
-
143
138
  # Look for up to 8 assembly accessions per species.
144
139
  logger.info("Getting assembly metadata")
145
140
  all_metadata = ncbi_assembly_metadata.NCBIAssemblyMetadata(
146
- all_metadata=species_dict, ani_gcf=ani_gcf, count=8, contig_n50=10000
141
+ all_metadata=species_dict, count=8, contig_n50=10000
147
142
  )
148
143
  all_metadata = all_metadata.get_all_metadata()
149
144
 
@@ -1,4 +1,4 @@
1
- """ Module for extracting and concatenating assemblies. """
1
+ """Module for extracting and concatenating assemblies."""
2
2
 
3
3
  __author__ = "Berger, Phillip"
4
4
 
@@ -23,9 +23,9 @@ def download_assemblies(accessions, dir_name, target_folder, zip_file_name):
23
23
  """
24
24
 
25
25
  path = get_xspect_tmp_path() / dir_name / target_folder / zip_file_name
26
- api_url = f"https://api.ncbi.nlm.nih.gov/datasets/v1/genome/accession/{','.join(accessions)}/download"
26
+ api_url = f"https://api.ncbi.nlm.nih.gov/datasets/v2/genome/accession/{','.join(accessions)}/download"
27
27
  parameters = {"include_annotation_type": "GENOME_FASTA", "filename": zip_file_name}
28
28
  os.makedirs(os.path.dirname(path), exist_ok=True)
29
- genome_download = requests.get(api_url, params=parameters, timeout=20)
29
+ genome_download = requests.get(api_url, params=parameters, timeout=30)
30
30
  with open(path, "wb") as f:
31
31
  f.write(genome_download.content)
@@ -1,4 +1,4 @@
1
- """ Collects metadata of assemblies from NCBI API """
1
+ """Collects metadata of assemblies from NCBI API"""
2
2
 
3
3
  __author__ = "Berger, Phillip"
4
4
 
@@ -14,16 +14,14 @@ class NCBIAssemblyMetadata:
14
14
 
15
15
  _all_metadata: dict
16
16
  _count: int
17
- _ani_gcf: list
18
17
  _parameters: dict
19
18
  _accessions: list[str]
20
19
  _contig_n50: int
21
20
  _all_metadata_complete: dict
22
21
 
23
- def __init__(self, all_metadata: dict, ani_gcf: list, count=8, contig_n50=10000):
22
+ def __init__(self, all_metadata: dict, count=8, contig_n50=10000):
24
23
  self._all_metadata = all_metadata
25
24
  self._count = count
26
- self._ani_gcf = ani_gcf
27
25
  self._contig_n50 = contig_n50
28
26
 
29
27
  self._set_parameters()
@@ -72,7 +70,7 @@ class NCBIAssemblyMetadata:
72
70
  }
73
71
 
74
72
  def _make_request(self, taxon: str):
75
- api_url = f"https://api.ncbi.nlm.nih.gov/datasets/v1/genome/taxon/{taxon}"
73
+ api_url = f"https://api.ncbi.nlm.nih.gov/datasets/v2/genome/taxon/{taxon}/dataset_report"
76
74
  accessions = []
77
75
  count = 0
78
76
  for request_type, parameters in self._parameters.items():
@@ -80,17 +78,19 @@ class NCBIAssemblyMetadata:
80
78
  response = raw_response.json()
81
79
  if response:
82
80
  try:
83
- assemblies = response["assemblies"]
84
- for assembly in assemblies:
85
- curr_assembly = assembly["assembly"]
86
- curr_accession = curr_assembly["assembly_accession"]
87
- curr_contig_n50 = curr_assembly["contig_n50"]
81
+ reports = response["reports"]
82
+ for report in reports:
83
+ accession = report["accession"]
84
+ contig_n50 = report["assembly_stats"]["contig_n50"]
85
+ taxonomy_check_status = report["average_nucleotide_identity"][
86
+ "taxonomy_check_status"
87
+ ]
88
88
  if count < self._count:
89
89
  if (
90
- curr_accession in self._ani_gcf
91
- and curr_contig_n50 > self._contig_n50
90
+ taxonomy_check_status == "OK"
91
+ and contig_n50 > self._contig_n50
92
92
  ):
93
- accessions.append(curr_accession)
93
+ accessions.append(accession)
94
94
  count += 1
95
95
  else:
96
96
  break
@@ -24,7 +24,7 @@ class NCBIChildrenTree:
24
24
 
25
25
  def _request_tree(self):
26
26
  """Make the request for the children tree at the NCBI Datasets API."""
27
- api_url = f"https://api.ncbi.nlm.nih.gov/datasets/v1/taxonomy/taxon/{self._taxon}/filtered_subtree"
27
+ api_url = f"https://api.ncbi.nlm.nih.gov/datasets/v2/taxonomy/taxon/{self._taxon}/filtered_subtree"
28
28
  raw_response = requests.get(api_url, timeout=5)
29
29
  self._response = raw_response.json()["edges"]
30
30
  self._parent_taxon_id = str(self._response["1"]["visible_children"][0])
@@ -1,4 +1,4 @@
1
- """ This module is used to retrieve metadata from the NCBI taxonomy database. """
1
+ """This module is used to retrieve metadata from the NCBI taxonomy database."""
2
2
 
3
3
  __author__ = "Berger, Phillip"
4
4
 
@@ -21,7 +21,7 @@ class NCBITaxonMetadata:
21
21
  self._collect_all_metadata()
22
22
 
23
23
  def _request_metadata(self):
24
- api_url = f"https://api.ncbi.nlm.nih.gov/datasets/v1/taxonomy/taxon/{str(self._taxon)}"
24
+ api_url = f"https://api.ncbi.nlm.nih.gov/datasets/v2/taxonomy/taxon/{str(self._taxon)}"
25
25
  raw_response = requests.get(api_url, timeout=5)
26
26
  self._response = raw_response.json()["taxonomy_nodes"]
27
27
 
@@ -1,4 +1,4 @@
1
- """ Tests for the ProbabilisticFilterSVMModel class. """
1
+ """Tests for the ProbabilisticFilterSVMModel class."""
2
2
 
3
3
  # pylint: disable=redefined-outer-name
4
4
 
@@ -1,114 +0,0 @@
1
- """ HTML Scraping for the taxonomy check results from NCBI."""
2
-
3
- __author__ = "Berger, Phillip"
4
-
5
- import datetime
6
- import pickle
7
- import sys
8
- import time
9
- import requests
10
- from loguru import logger
11
- from xspect.definitions import get_xspect_root_path
12
-
13
-
14
- class TaxonomyCheck:
15
- """Class to get the GCFs that passed the taxonomy check from NCBI."""
16
-
17
- _main_url = "https://ftp.ncbi.nlm.nih.gov/genomes/ASSEMBLY_REPORTS/ANI_report_prokaryotes.txt"
18
- _test_url = "https://ftp.ncbi.nlm.nih.gov/genomes/ASSEMBLY_REPORTS/"
19
- _main_path = get_xspect_root_path() / "taxonomy_check.txt"
20
- _test_path = get_xspect_root_path() / "tax_check_date.txt"
21
- _new_time: list
22
- _tax_check_ok = []
23
-
24
- def __init__(self):
25
- old_time = self._get_old_tax_date()
26
- self._new_time = self._get_new_tax_date()
27
- # Both Dates could be found.
28
- # Check if the html file was updated since the last time it was downloaded.
29
- # If yes than update the file.
30
- if self._new_time and old_time:
31
- if self._new_time == old_time:
32
- logger.info("File was not updated")
33
- self._get_old_file()
34
- else:
35
- logger.info("Updating file")
36
- self._update_tax_check()
37
-
38
- # The old date does not exist.
39
- # Get the html file for the taxonomy check results.
40
- elif self._new_time and not old_time:
41
- logger.info("No file was found. Creating new file")
42
- self._update_tax_check()
43
-
44
- elif not self._new_time and old_time:
45
- self._get_old_file()
46
-
47
- else:
48
- logger.error("Nothing was found")
49
- logger.error("Aborting")
50
- sys.exit()
51
-
52
- def _get_old_tax_date(self):
53
- try:
54
- with open(self._test_path, "rb") as f:
55
- old_time = pickle.load(f)
56
- return old_time
57
- except FileNotFoundError:
58
- return None
59
-
60
- def _get_new_tax_date(self):
61
- raw_response = requests.get(self._test_url, timeout=5)
62
- data = raw_response.text.split("\n")
63
- for line in data:
64
- if "ANI_report_prokaryotes.txt" in line:
65
- line_parts = line.split()
66
- date_parts = line_parts[-3].split("-")
67
- date = datetime.date(
68
- int(date_parts[0]), int(date_parts[1]), int(date_parts[2])
69
- )
70
- time_parts = line_parts[-2].split(":")
71
- combined_time = datetime.time(int(time_parts[0]), int(time_parts[1]))
72
- new_time = [date, combined_time]
73
-
74
- return new_time
75
-
76
- return None
77
-
78
- def _update_tax_check(self):
79
- raw_response = requests.get(self._main_url, timeout=5)
80
- all_tax_checks = raw_response.text.split("\n")[1:-1]
81
- self._get_gcf_ok(all_tax_checks)
82
- self._save_time()
83
- self._save_file()
84
-
85
- def _get_gcf_ok(self, all_tax_checks: list):
86
- tax_check_ok = []
87
- for line in all_tax_checks:
88
- line_parts = line.split("\t")
89
- gcf = line_parts[1]
90
- tax_check_status = line_parts[-1]
91
- if tax_check_status == "OK":
92
- tax_check_ok.append(gcf)
93
-
94
- self._tax_check_ok = tax_check_ok
95
-
96
- def _save_time(self):
97
- with open(self._test_path, "wb") as f:
98
- pickle.dump(self._new_time, f)
99
-
100
- def _save_file(self):
101
- with open(self._main_path, "wb") as f:
102
- pickle.dump(self._tax_check_ok, f)
103
-
104
- def _get_old_file(self):
105
- with open(self._main_path, "rb") as f:
106
- self._tax_check_ok = pickle.load(f)
107
-
108
- @staticmethod
109
- def _get_current_time():
110
- return time.asctime(time.localtime()).split()[3]
111
-
112
- def ani_gcf(self):
113
- """Returns ANI GCFs that passed the taxonomy check."""
114
- return self._tax_check_ok
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes