xradio 0.0.27__tar.gz → 0.0.28__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.
- {xradio-0.0.27/src/xradio.egg-info → xradio-0.0.28}/PKG-INFO +1 -1
- {xradio-0.0.27 → xradio-0.0.28}/pyproject.toml +1 -1
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/_fits/xds_from_fits.py +10 -5
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/_zarr/zarr_low_level.py +27 -24
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/common.py +4 -1
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_processing_set.py +18 -5
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/_tables/read.py +54 -3
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/_tables/read_main_table.py +3 -1
- {xradio-0.0.27 → xradio-0.0.28/src/xradio.egg-info}/PKG-INFO +1 -1
- {xradio-0.0.27 → xradio-0.0.28}/LICENSE.txt +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/MANIFEST.in +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/README.md +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/setup.cfg +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/__init__.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/_utils/__init__.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/_utils/_casacore/tables.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/_utils/common.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/_utils/zarr/__init__.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/_utils/zarr/common.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/__init__.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/__init__.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/_casacore/__init__.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/_casacore/common.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/_casacore/xds_from_casacore.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/_casacore/xds_to_casacore.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/_zarr/common.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/_zarr/xds_from_zarr.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/_zarr/xds_to_zarr.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/casacore.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/fits.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/image_factory.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/_util/zarr.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/image/image.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/schema/__init__.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/schema/bases.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/schema/check.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/schema/dataclass.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/schema/metamodel.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/schema/typing.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/__init__.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/__init__.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/_tables/load.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/_tables/load_main_table.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/_tables/read_subtables.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/_tables/table_query.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/_tables/write.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/_tables/write_exp_api.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/chunks.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/conversion.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/descr.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/msv2_msv3.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/msv2_to_msv4_meta.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/msv4_infos.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/msv4_sub_xdss.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/optimised_functions.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/partition_queries.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/partitions.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_ms/subtables.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_utils/cds.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_utils/partition_attrs.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_utils/stokes_types.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_utils/xds_helper.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_zarr/encoding.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_zarr/read.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/_zarr/write.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/ms.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/ms_column_descriptions_dicts.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/_vis_utils/zarr.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/convert_msv2_to_processing_set.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/load_processing_set.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/model.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/read_processing_set.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio/vis/vis_io.py +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio.egg-info/SOURCES.txt +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio.egg-info/dependency_links.txt +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio.egg-info/requires.txt +0 -0
- {xradio-0.0.27 → xradio-0.0.28}/src/xradio.egg-info/top_level.txt +0 -0
|
@@ -101,7 +101,7 @@ def _add_vel_attrs(xds: xr.Dataset, helpers: dict) -> xr.Dataset:
|
|
|
101
101
|
vel_coord = xds.coords["velocity"]
|
|
102
102
|
meta = {"units": "m/s"}
|
|
103
103
|
if helpers["has_freq"]:
|
|
104
|
-
meta["doppler_type"] = helpers
|
|
104
|
+
meta["doppler_type"] = helpers.get("doppler", "RADIO")
|
|
105
105
|
else:
|
|
106
106
|
meta["doppler_type"] = _doppler_types[0]
|
|
107
107
|
meta["type"] = "doppler"
|
|
@@ -570,8 +570,8 @@ def _get_freq_values(helpers: dict) -> list:
|
|
|
570
570
|
crval=helpers["crval"][freq_idx],
|
|
571
571
|
crpix=helpers["crpix"][freq_idx],
|
|
572
572
|
cdelt=helpers["cdelt"][freq_idx],
|
|
573
|
-
cunit=helpers["cunit"][freq_idx],
|
|
574
573
|
)
|
|
574
|
+
cunit = helpers["cunit"][freq_idx]
|
|
575
575
|
helpers["frequency"] = vals * u.Unit(cunit)
|
|
576
576
|
return vals
|
|
577
577
|
elif "VOPT" in ctype:
|
|
@@ -606,9 +606,9 @@ def _get_velocity_values(helpers: dict) -> list:
|
|
|
606
606
|
return helpers["velocity"].to(u.m / u.s).value
|
|
607
607
|
elif "frequency" in helpers:
|
|
608
608
|
v = _compute_velocity_values(
|
|
609
|
-
restfreq=helpers["
|
|
609
|
+
restfreq=helpers["restfreq"],
|
|
610
610
|
freq_values=helpers["frequency"].to("Hz").value,
|
|
611
|
-
doppler=helpers
|
|
611
|
+
doppler=helpers.get("doppler", "RADIO"),
|
|
612
612
|
)
|
|
613
613
|
helpers["velocity"] = v * (u.m / u.s)
|
|
614
614
|
return v
|
|
@@ -796,7 +796,12 @@ def _get_transpose_list(helpers: dict) -> tuple:
|
|
|
796
796
|
transpose_list[4] = i
|
|
797
797
|
not_covered.remove("m")
|
|
798
798
|
not_covered.remove("v")
|
|
799
|
-
elif
|
|
799
|
+
elif (
|
|
800
|
+
b.startswith("frequency")
|
|
801
|
+
or b.startswith("freq")
|
|
802
|
+
or b.startswith("vopt")
|
|
803
|
+
or b.startswith("vrad")
|
|
804
|
+
):
|
|
800
805
|
transpose_list[2] = i
|
|
801
806
|
not_covered.remove("f")
|
|
802
807
|
elif b.startswith("stok"):
|
|
@@ -110,53 +110,56 @@ def write_binary_blob_to_disk(arr, file_path, compressor):
|
|
|
110
110
|
- None
|
|
111
111
|
"""
|
|
112
112
|
import graphviper.utils.logger as logger
|
|
113
|
+
|
|
113
114
|
# Encode the NumPy array using the codec
|
|
114
|
-
logger.debug(
|
|
115
|
+
logger.debug("1. Before compressor " + file_path)
|
|
115
116
|
compressed_arr = compressor.encode(np.ascontiguousarray(arr))
|
|
116
117
|
|
|
117
|
-
logger.debug(
|
|
118
|
+
logger.debug("2. Before makedir")
|
|
118
119
|
# Ensure the directory exists before saving the file
|
|
119
120
|
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
|
120
121
|
|
|
121
122
|
arr_len = len(compressed_arr)
|
|
122
|
-
logger.debug(
|
|
123
|
-
#Save the compressed array to disk
|
|
123
|
+
logger.debug("3. Before write the len is: " + str(arr_len))
|
|
124
|
+
# Save the compressed array to disk
|
|
124
125
|
# with open(file_path, "wb") as file:
|
|
125
126
|
# file.write(compressed_arr)
|
|
126
|
-
|
|
127
|
-
logger.debug(
|
|
127
|
+
|
|
128
|
+
logger.debug("4. Using new writer: " + str(arr_len))
|
|
128
129
|
write_to_lustre_chunked(file_path, compressed_arr)
|
|
129
|
-
|
|
130
|
+
|
|
130
131
|
# /.lustre/aoc/sciops/pford/CHILES/cube_image/uid___A002_Xee7674_X2844_Cube_3.img.zarr/SKY/0.0.110.0.0
|
|
131
132
|
# 348192501 bytes
|
|
132
133
|
# 332.0622453689575 M
|
|
133
|
-
|
|
134
|
+
|
|
134
135
|
# from io import BufferedWriter
|
|
135
136
|
# # Calculate buffer size based on compressed_arr size (adjust multiplier)
|
|
136
137
|
# buffer_size = min(len(compressed_arr), 1024 * 1024 * 4) # Max 4 MB buffer
|
|
137
138
|
# with BufferedWriter(open(file_path, "wb"), buffer_size) as f:
|
|
138
139
|
# f.write(compressed_arr)
|
|
139
|
-
# f.flush() # Ensure data gets written to disk
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
logger.debug('4. Write completed')
|
|
140
|
+
# f.flush() # Ensure data gets written to disk
|
|
141
|
+
|
|
142
|
+
logger.debug("4. Write completed")
|
|
143
143
|
|
|
144
144
|
# print(f"Compressed array saved to {file_path}")
|
|
145
145
|
|
|
146
146
|
|
|
147
|
-
def write_to_lustre_chunked(
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
def write_to_lustre_chunked(
|
|
148
|
+
file_path, compressed_arr, chunk_size=1024 * 1024 * 128
|
|
149
|
+
): # 128 MiB chunks
|
|
150
|
+
"""
|
|
151
|
+
Writes compressed data to a Lustre file path with chunking.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
file_path: Path to the file for writing.
|
|
155
|
+
compressed_arr: Compressed data array to write.
|
|
156
|
+
chunk_size: Size of each data chunk in bytes (default: 128 MiB).
|
|
157
|
+
"""
|
|
158
|
+
with open(file_path, "wb") as f:
|
|
159
|
+
for i in range(0, len(compressed_arr), chunk_size):
|
|
160
|
+
chunk = compressed_arr[i : i + chunk_size]
|
|
161
|
+
f.write(chunk)
|
|
150
162
|
|
|
151
|
-
Args:
|
|
152
|
-
file_path: Path to the file for writing.
|
|
153
|
-
compressed_arr: Compressed data array to write.
|
|
154
|
-
chunk_size: Size of each data chunk in bytes (default: 128 MiB).
|
|
155
|
-
"""
|
|
156
|
-
with open(file_path, "wb") as f:
|
|
157
|
-
for i in range(0, len(compressed_arr), chunk_size):
|
|
158
|
-
chunk = compressed_arr[i:i + chunk_size]
|
|
159
|
-
f.write(chunk)
|
|
160
163
|
|
|
161
164
|
def read_binary_blob_from_disk(file_path, compressor, dtype=np.float64):
|
|
162
165
|
"""
|
|
@@ -33,7 +33,10 @@ def _convert_beam_to_rad(beam: dict) -> dict:
|
|
|
33
33
|
"""
|
|
34
34
|
mybeam = {}
|
|
35
35
|
for k in beam:
|
|
36
|
-
|
|
36
|
+
try:
|
|
37
|
+
q = u.quantity.Quantity(f"{beam[k]['value']}{beam[k]['unit']}")
|
|
38
|
+
except:
|
|
39
|
+
q = u.quantity.Quantity(f"{beam[k]['value']}{beam[k]['units']}")
|
|
37
40
|
q = q.to("rad")
|
|
38
41
|
j = "pa" if k == "positionangle" else k
|
|
39
42
|
mybeam[j] = {"type": "quantity", "value": q.value, "units": "rad"}
|
|
@@ -43,10 +43,11 @@ class processing_set(dict):
|
|
|
43
43
|
"start_frequency": [],
|
|
44
44
|
"end_frequency": [],
|
|
45
45
|
"shape": [],
|
|
46
|
-
"field_coords": []
|
|
46
|
+
"field_coords": [],
|
|
47
47
|
}
|
|
48
48
|
from astropy.coordinates import SkyCoord
|
|
49
49
|
import astropy.units as u
|
|
50
|
+
|
|
50
51
|
for key, value in self.items():
|
|
51
52
|
summary_data["name"].append(key)
|
|
52
53
|
summary_data["ddi"].append(value.attrs["ddi"])
|
|
@@ -69,11 +70,23 @@ class processing_set(dict):
|
|
|
69
70
|
summary_data["start_frequency"].append(value["frequency"].values[0])
|
|
70
71
|
summary_data["end_frequency"].append(value["frequency"].values[-1])
|
|
71
72
|
|
|
72
|
-
ra_dec_rad = value[data_name].attrs["field_info"][
|
|
73
|
-
frame =
|
|
74
|
-
|
|
73
|
+
ra_dec_rad = value[data_name].attrs["field_info"]["phase_direction"]["data"]
|
|
74
|
+
frame = (
|
|
75
|
+
value[data_name]
|
|
76
|
+
.attrs["field_info"]["phase_direction"]["attrs"]["frame"]
|
|
77
|
+
.lower()
|
|
78
|
+
)
|
|
79
|
+
coord = SkyCoord(
|
|
80
|
+
ra=ra_dec_rad[0] * u.rad, dec=ra_dec_rad[1] * u.rad, frame=frame
|
|
81
|
+
)
|
|
75
82
|
|
|
76
|
-
summary_data["field_coords"].append(
|
|
83
|
+
summary_data["field_coords"].append(
|
|
84
|
+
[
|
|
85
|
+
frame,
|
|
86
|
+
coord.ra.to_string(unit=u.hour),
|
|
87
|
+
coord.dec.to_string(unit=u.deg),
|
|
88
|
+
]
|
|
89
|
+
)
|
|
77
90
|
summary_df = pd.DataFrame(summary_data)
|
|
78
91
|
return summary_df
|
|
79
92
|
|
|
@@ -619,10 +619,61 @@ def read_col_conversion(
|
|
|
619
619
|
Function to perform delayed reads from table columns when converting
|
|
620
620
|
(no need for didxs)
|
|
621
621
|
"""
|
|
622
|
-
|
|
622
|
+
|
|
623
|
+
# Workaround for https://github.com/casacore/python-casacore/issues/130
|
|
624
|
+
# WARNING: Assumes tb_tool is a single measurement set not an MMS.
|
|
625
|
+
# WARNING: Assumes the num_frequencies * num_polarisations > 2**29. If false,
|
|
626
|
+
# https://github.com/casacore/python-casacore/issues/130 isn't mitigated.
|
|
627
|
+
|
|
628
|
+
# Use casacore to get the shape of a row for this column
|
|
629
|
+
|
|
630
|
+
#################################################################################
|
|
631
|
+
|
|
632
|
+
# Get the total number of rows in the base measurement set
|
|
633
|
+
nrows_total = tb_tool.nrows()
|
|
634
|
+
|
|
635
|
+
# getcolshapestring() only works on columns where a row element is an
|
|
636
|
+
# array (ie fails for TIME, etc)
|
|
637
|
+
# Assumes RuntimeError is because the column is a scalar
|
|
638
|
+
try:
|
|
639
|
+
|
|
640
|
+
shape_string = tb_tool.getcolshapestring(col)[0]
|
|
641
|
+
extra_dimensions = tuple(
|
|
642
|
+
[
|
|
643
|
+
int(idx)
|
|
644
|
+
for idx in shape_string.replace("[", "").replace("]", "").split(", ")
|
|
645
|
+
]
|
|
646
|
+
)
|
|
647
|
+
full_shape = tuple(
|
|
648
|
+
[nrows_total]
|
|
649
|
+
+ [
|
|
650
|
+
int(idx)
|
|
651
|
+
for idx in shape_string.replace("[", "").replace("]", "").split(", ")
|
|
652
|
+
]
|
|
653
|
+
)
|
|
654
|
+
except RuntimeError:
|
|
655
|
+
extra_dimensions = ()
|
|
656
|
+
full_shape = (nrows_total,)
|
|
657
|
+
|
|
658
|
+
#################################################################################
|
|
659
|
+
|
|
660
|
+
# Get dtype of the column. Only read first row from disk
|
|
661
|
+
col_dtype = np.array(tb_tool.col(col)[0]).dtype
|
|
662
|
+
|
|
663
|
+
# Construct the numpy array to populate with data
|
|
664
|
+
data = np.empty(full_shape, dtype=col_dtype)
|
|
665
|
+
|
|
666
|
+
# Use built-in casacore table iterator to populate the data column by unique times.
|
|
667
|
+
start_row = 0
|
|
668
|
+
for ts in tb_tool.iter("TIME", sort=False):
|
|
669
|
+
num_rows = ts.nrows()
|
|
670
|
+
# Note don't use getcol() because it's less safe. See:
|
|
671
|
+
# https://github.com/casacore/python-casacore/issues/130#issuecomment-463202373
|
|
672
|
+
ts.getcolnp(col, data[start_row : start_row + num_rows])
|
|
673
|
+
start_row += num_rows
|
|
623
674
|
|
|
624
675
|
# TODO
|
|
625
|
-
#
|
|
626
|
-
fulldata = np.full(cshape +
|
|
676
|
+
# Can we return a view of `data` instead of copying?
|
|
677
|
+
fulldata = np.full(cshape + extra_dimensions, np.nan, dtype=col_dtype)
|
|
627
678
|
fulldata[tidxs, bidxs] = data
|
|
628
679
|
return fulldata
|
|
@@ -196,7 +196,9 @@ def read_main_table_chunks(
|
|
|
196
196
|
# loop over time chunks
|
|
197
197
|
for time_chunk in range(0, n_unique_times, n_time_chunks):
|
|
198
198
|
time_start = unique_times[time_chunk] - tol
|
|
199
|
-
time_end =
|
|
199
|
+
time_end = (
|
|
200
|
+
unique_times[min(n_unique_times, time_chunk + n_time_chunks) - 1] + tol
|
|
201
|
+
)
|
|
200
202
|
|
|
201
203
|
# chunk time length
|
|
202
204
|
ctlen = min(n_unique_times, time_chunk + n_time_chunks) - time_chunk
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|