pyxcp 0.22.10__tar.gz → 0.22.11__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 pyxcp might be problematic. Click here for more details.

Files changed (126) hide show
  1. {pyxcp-0.22.10 → pyxcp-0.22.11}/PKG-INFO +1 -1
  2. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyproject.toml +1 -1
  3. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/__init__.py +1 -1
  4. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/config/__init__.py +4 -1
  5. pyxcp-0.22.11/pyxcp/examples/ex_csv.py +85 -0
  6. pyxcp-0.22.11/pyxcp/examples/ex_excel.py +95 -0
  7. {pyxcp-0.22.10 → pyxcp-0.22.11}/CMakeLists.txt +0 -0
  8. {pyxcp-0.22.10 → pyxcp-0.22.11}/LICENSE +0 -0
  9. {pyxcp-0.22.10 → pyxcp-0.22.11}/README.md +0 -0
  10. {pyxcp-0.22.10 → pyxcp-0.22.11}/build_ext.py +0 -0
  11. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/aml/EtasCANMonitoring.a2l +0 -0
  12. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/aml/EtasCANMonitoring.aml +0 -0
  13. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/aml/XCP_Common.aml +0 -0
  14. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/aml/XCPonCAN.aml +0 -0
  15. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/aml/XCPonEth.aml +0 -0
  16. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/aml/XCPonFlx.aml +0 -0
  17. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/aml/XCPonSxI.aml +0 -0
  18. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/aml/XCPonUSB.aml +0 -0
  19. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/aml/ifdata_CAN.a2l +0 -0
  20. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/aml/ifdata_Eth.a2l +0 -0
  21. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/aml/ifdata_Flx.a2l +0 -0
  22. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/aml/ifdata_SxI.a2l +0 -0
  23. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/aml/ifdata_USB.a2l +0 -0
  24. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/asam/__init__.py +0 -0
  25. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/asam/types.py +0 -0
  26. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/asamkeydll.c +0 -0
  27. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/asamkeydll.sh +0 -0
  28. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/checksum.py +0 -0
  29. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/cmdline.py +0 -0
  30. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/config/legacy.py +0 -0
  31. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/constants.py +0 -0
  32. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/cpp_ext/__init__.py +0 -0
  33. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/cpp_ext/bin.hpp +0 -0
  34. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/cpp_ext/blockmem.hpp +0 -0
  35. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/cpp_ext/daqlist.hpp +0 -0
  36. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/cpp_ext/event.hpp +0 -0
  37. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/cpp_ext/extension_wrapper.cpp +0 -0
  38. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/cpp_ext/helper.hpp +0 -0
  39. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/cpp_ext/mcobject.hpp +0 -0
  40. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/cpp_ext/tsqueue.hpp +0 -0
  41. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/daq_stim/__init__.py +0 -0
  42. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/daq_stim/optimize/__init__.py +0 -0
  43. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/daq_stim/optimize/binpacking.py +0 -0
  44. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/daq_stim/scheduler.cpp +0 -0
  45. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/daq_stim/scheduler.hpp +0 -0
  46. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/daq_stim/stim.cpp +0 -0
  47. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/daq_stim/stim.hpp +0 -0
  48. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/daq_stim/stim_wrapper.cpp +0 -0
  49. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/dllif.py +0 -0
  50. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/errormatrix.py +0 -0
  51. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/conf_can.toml +0 -0
  52. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/conf_can_user.toml +0 -0
  53. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/conf_can_vector.json +0 -0
  54. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/conf_can_vector.toml +0 -0
  55. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/conf_eth.toml +0 -0
  56. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/conf_nixnet.json +0 -0
  57. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/conf_socket_can.toml +0 -0
  58. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/conf_sxi.json +0 -0
  59. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/conf_sxi.toml +0 -0
  60. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/ex_arrow.py +0 -0
  61. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/ex_mdf.py +0 -0
  62. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/ex_sqlite.py +0 -0
  63. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/run_daq.py +0 -0
  64. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/xcp_policy.py +0 -0
  65. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/xcp_read_benchmark.py +0 -0
  66. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/xcp_skel.py +0 -0
  67. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/xcp_unlock.py +0 -0
  68. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/xcp_user_supplied_driver.py +0 -0
  69. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/xcphello.py +0 -0
  70. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/examples/xcphello_recorder.py +0 -0
  71. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/master/__init__.py +0 -0
  72. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/master/errorhandler.py +0 -0
  73. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/master/master.py +0 -0
  74. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/py.typed +0 -0
  75. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/__init__.py +0 -0
  76. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/build_clang.cmd +0 -0
  77. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/build_clang.sh +0 -0
  78. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/build_gcc.cmd +0 -0
  79. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/build_gcc.sh +0 -0
  80. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/build_gcc_arm.sh +0 -0
  81. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/converter/__init__.py +0 -0
  82. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/lz4.c +0 -0
  83. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/lz4.h +0 -0
  84. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/lz4hc.c +0 -0
  85. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/lz4hc.h +0 -0
  86. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/mio.hpp +0 -0
  87. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/reader.hpp +0 -0
  88. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/reco.py +0 -0
  89. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/recorder.rst +0 -0
  90. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/rekorder.cpp +0 -0
  91. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/rekorder.hpp +0 -0
  92. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/setup.py +0 -0
  93. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/test_reko.py +0 -0
  94. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/unfolder.hpp +0 -0
  95. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/wrap.cpp +0 -0
  96. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/recorder/writer.hpp +0 -0
  97. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/scripts/__init__.py +0 -0
  98. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/scripts/pyxcp_probe_can_drivers.py +0 -0
  99. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/scripts/xcp_examples.py +0 -0
  100. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/scripts/xcp_fetch_a2l.py +0 -0
  101. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/scripts/xcp_id_scanner.py +0 -0
  102. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/scripts/xcp_info.py +0 -0
  103. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/scripts/xcp_profile.py +0 -0
  104. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/stim/__init__.py +0 -0
  105. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/tests/test_asam_types.py +0 -0
  106. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/tests/test_binpacking.py +0 -0
  107. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/tests/test_can.py +0 -0
  108. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/tests/test_checksum.py +0 -0
  109. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/tests/test_daq.py +0 -0
  110. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/tests/test_frame_padding.py +0 -0
  111. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/tests/test_master.py +0 -0
  112. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/tests/test_transport.py +0 -0
  113. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/tests/test_utils.py +0 -0
  114. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/timing.py +0 -0
  115. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/transport/__init__.py +0 -0
  116. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/transport/base.py +0 -0
  117. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/transport/base_transport.hpp +0 -0
  118. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/transport/can.py +0 -0
  119. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/transport/eth.py +0 -0
  120. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/transport/sxi.py +0 -0
  121. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/transport/transport_wrapper.cpp +0 -0
  122. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/transport/usb_transport.py +0 -0
  123. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/types.py +0 -0
  124. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/utils.py +0 -0
  125. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/vector/__init__.py +0 -0
  126. {pyxcp-0.22.10 → pyxcp-0.22.11}/pyxcp/vector/map.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyxcp
3
- Version: 0.22.10
3
+ Version: 0.22.11
4
4
  Summary: Universal Calibration Protocol for Python
5
5
  Home-page: https://github.com/christoph2/pyxcp
6
6
  License: LGPLv3
@@ -36,7 +36,7 @@ dynamic = ["license", "readme", "authors", "requires-python", "description", "cl
36
36
  [tool.poetry]
37
37
  authors = ["Christoph Schueler <cpu.gems@googlemail.com>"]
38
38
  name = "pyxcp"
39
- version = "0.22.10"
39
+ version = "0.22.11"
40
40
  readme = "README.md"
41
41
  description = "Universal Calibration Protocol for Python"
42
42
  keywords = ["automotive", "ecu", "xcp", "asam", "autosar"]
@@ -17,4 +17,4 @@ tb_install(show_locals=True, max_frames=3) # Install custom exception handler.
17
17
 
18
18
  # if you update this manually, do not forget to update
19
19
  # .bumpversion.cfg and pyproject.toml.
20
- __version__ = "0.22.10"
20
+ __version__ = "0.22.11"
@@ -933,7 +933,10 @@ class PyXCP(Application):
933
933
  exit(2)
934
934
  else:
935
935
  self._read_configuration(self.config_file)
936
- self._setup_logger()
936
+ if logging.getLogger().hasHandlers():
937
+ self.log = logging.getLogger()
938
+ else:
939
+ self._setup_logger()
937
940
 
938
941
  def _setup_logger(self):
939
942
  from pyxcp.types import Command
@@ -0,0 +1,85 @@
1
+ import argparse
2
+ import logging
3
+ import os
4
+ import csv
5
+ from array import array
6
+ from dataclasses import dataclass, field
7
+ from mmap import PAGESIZE
8
+ from pathlib import Path
9
+ from typing import Any, List
10
+
11
+ from pyxcp.recorder import XcpLogFileDecoder
12
+ from pyxcp.recorder.converter import MAP_TO_ARRAY
13
+
14
+
15
+ MAP_TO_SQL = {
16
+ "U8": "INTEGER",
17
+ "I8": "INTEGER",
18
+ "U16": "INTEGER",
19
+ "I16": "INTEGER",
20
+ "U32": "INTEGER",
21
+ "I32": "INTEGER",
22
+ "U64": "INTEGER",
23
+ "I64": "INTEGER",
24
+ "F32": "FLOAT",
25
+ "F64": "FLOAT",
26
+ "F16": "FLOAT",
27
+ "BF16": "FLOAT",
28
+ }
29
+
30
+ logger = logging.getLogger("PyXCP")
31
+
32
+ parser = argparse.ArgumentParser(description="Use .xmraw files in an Apache Arrow application.")
33
+ parser.add_argument("xmraw_file", help=".xmraw file")
34
+ args = parser.parse_args()
35
+
36
+
37
+ @dataclass
38
+ class Storage:
39
+ name: str
40
+ arrow_type: Any
41
+ arr: array
42
+
43
+
44
+ @dataclass
45
+ class StorageContainer:
46
+ name: str
47
+ arr: List[Storage] = field(default_factory=[])
48
+ ts0: List[int] = field(default_factory=lambda: array("Q"))
49
+ ts1: List[int] = field(default_factory=lambda: array("Q"))
50
+
51
+
52
+ class Decoder(XcpLogFileDecoder):
53
+
54
+ def __init__(self, recording_file_name: str):
55
+ super().__init__(recording_file_name)
56
+
57
+ def initialize(self) -> None:
58
+ self.arrow_tables = []
59
+ self.csv_writers = []
60
+ for dl in self.daq_lists:
61
+ result = []
62
+ for name, type_str in dl.headers:
63
+ array_txpe = MAP_TO_ARRAY[type_str]
64
+ sql_type = MAP_TO_SQL[type_str]
65
+ sd = Storage(name, sql_type, array(array_txpe))
66
+ result.append(sd)
67
+ sc = StorageContainer(dl.name, result)
68
+ writer = csv.writer(open(f"{sc.name}.csv", "w", newline=""), dialect="excel")
69
+ headers = ["ts0", "ts1"] + [e.name for e in sc.arr]
70
+ writer.writerow(headers)
71
+ self.csv_writers.append(writer)
72
+ self.arrow_tables.append(sc)
73
+ print("\nInserting data...")
74
+
75
+ def finalize(self) -> None:
76
+ print("Done.")
77
+
78
+ def on_daq_list(self, daq_list_num: int, timestamp0: int, timestamp1: int, measurements: list) -> None:
79
+ sc = self.arrow_tables[daq_list_num]
80
+ writer = self.csv_writers[daq_list_num]
81
+ data = [timestamp0, timestamp1, *measurements]
82
+ writer.writerow(data)
83
+
84
+ decoder = Decoder(args.xmraw_file)
85
+ decoder.run()
@@ -0,0 +1,95 @@
1
+ import argparse
2
+ import logging
3
+ import os
4
+ import xlsxwriter
5
+ from array import array
6
+ from dataclasses import dataclass, field
7
+ from mmap import PAGESIZE
8
+ from pathlib import Path
9
+ from typing import Any, List
10
+
11
+ from pyxcp.recorder import XcpLogFileDecoder
12
+ from pyxcp.recorder.converter import MAP_TO_ARRAY
13
+
14
+
15
+ MAP_TO_SQL = {
16
+ "U8": "INTEGER",
17
+ "I8": "INTEGER",
18
+ "U16": "INTEGER",
19
+ "I16": "INTEGER",
20
+ "U32": "INTEGER",
21
+ "I32": "INTEGER",
22
+ "U64": "INTEGER",
23
+ "I64": "INTEGER",
24
+ "F32": "FLOAT",
25
+ "F64": "FLOAT",
26
+ "F16": "FLOAT",
27
+ "BF16": "FLOAT",
28
+ }
29
+
30
+ logger = logging.getLogger("PyXCP")
31
+
32
+ parser = argparse.ArgumentParser(description="Use .xmraw files in an Apache Arrow application.")
33
+ parser.add_argument("xmraw_file", help=".xmraw file")
34
+ args = parser.parse_args()
35
+
36
+
37
+ @dataclass
38
+ class Storage:
39
+ name: str
40
+ arrow_type: Any
41
+ arr: array
42
+
43
+
44
+ @dataclass
45
+ class StorageContainer:
46
+ name: str
47
+ arr: List[Storage] = field(default_factory=[])
48
+ ts0: List[int] = field(default_factory=lambda: array("Q"))
49
+ ts1: List[int] = field(default_factory=lambda: array("Q"))
50
+
51
+
52
+ class Decoder(XcpLogFileDecoder):
53
+
54
+ def __init__(self, recording_file_name: str):
55
+ super().__init__(recording_file_name)
56
+ self.xls_file_name = Path(recording_file_name).with_suffix(".xlsx")
57
+ try:
58
+ os.unlink(self.xls_file_name)
59
+ except Exception as e:
60
+ print(e)
61
+
62
+ def initialize(self) -> None:
63
+ self.arrow_tables = []
64
+ self.xls_workbook = xlsxwriter.Workbook(self.xls_file_name)
65
+ self.xls_sheets = []
66
+ self.rows = []
67
+ for dl in self.daq_lists:
68
+ result = []
69
+ for name, type_str in dl.headers:
70
+ array_txpe = MAP_TO_ARRAY[type_str]
71
+ sql_type = MAP_TO_SQL[type_str]
72
+ sd = Storage(name, sql_type, array(array_txpe))
73
+ result.append(sd)
74
+ sc = StorageContainer(dl.name, result)
75
+ sheet = self.xls_workbook.add_worksheet(sc.name)
76
+ self.xls_sheets.append(sheet)
77
+ headers = ["ts0", "ts1"] + [e.name for e in sc.arr]
78
+ sheet.write_row(0, 0, headers)
79
+ self.rows.append(1)
80
+ self.arrow_tables.append(sc)
81
+ print("\nInserting data...")
82
+
83
+ def finalize(self) -> None:
84
+ self.xls_workbook.close()
85
+ print("Done.")
86
+
87
+ def on_daq_list(self, daq_list_num: int, timestamp0: int, timestamp1: int, measurements: list) -> None:
88
+ sheet = self.xls_sheets[daq_list_num]
89
+ row = self.rows[daq_list_num]
90
+ data = [timestamp0, timestamp1] + measurements
91
+ sheet.write_row(row, 0, data)
92
+ self.rows[daq_list_num] += 1
93
+
94
+ decoder = Decoder(args.xmraw_file)
95
+ decoder.run()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes