biomechzoo 0.4.5__tar.gz → 0.4.8__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 biomechzoo might be problematic. Click here for more details.
- {biomechzoo-0.4.5/src/biomechzoo.egg-info → biomechzoo-0.4.8}/PKG-INFO +1 -1
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/pyproject.toml +1 -1
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/conversion/c3d2zoo_data.py +7 -4
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/conversion/csv2zoo_data.py +8 -4
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/conversion/mvnx2zoo_data.py +8 -6
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/partition_data.py +10 -4
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/engine.py +16 -5
- biomechzoo-0.4.8/src/biomechzoo/utils/set_zoosystem.py +66 -0
- biomechzoo-0.4.8/src/biomechzoo/utils/version.py +5 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8/src/biomechzoo.egg-info}/PKG-INFO +1 -1
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo.egg-info/SOURCES.txt +2 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/LICENSE +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/README.md +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/setup.cfg +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/__init__.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/__init__.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/__main__.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/__init__.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/continuous_relative_phase_data.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/continuous_relative_phase_line.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/filter_data.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/filter_line.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/normalize_data.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/normalize_line.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/phase_angle_data.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/phase_angle_line.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomechzoo.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/conversion/__init__.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/conversion/opencap2zoo_data.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/mvn/__init__.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/mvn/load_mvnx.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/mvn/main_mvnx.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/mvn/mvn.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/mvn/mvnx_file_accessor.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/__init__.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/add_channel_data.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/addchannel_data.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/addevent_data.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/explodechannel_data.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/removechannel_data.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/renamechannel_data.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/renameevent_data.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/split_trial_by_gait_cycle.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/__init__.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/batchdisp.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/compute_sampling_rate_from_time.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/findfield.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/get_split_events.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/split_trial.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/zload.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/zplot.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/zsave.py +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo.egg-info/dependency_links.txt +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo.egg-info/entry_points.txt +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo.egg-info/requires.txt +0 -0
- {biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo.egg-info/top_level.txt +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from biomechzoo.utils.set_zoosystem import set_zoosystem
|
|
2
|
+
|
|
1
3
|
def c3d2zoo_data(c3d_obj):
|
|
2
4
|
"""
|
|
3
5
|
Converts an ezc3d C3D object to zoo format.
|
|
@@ -21,7 +23,7 @@ def c3d2zoo_data(c3d_obj):
|
|
|
21
23
|
video_freq = c3d_obj['parameters']['POINT']['RATE']['value'][0]
|
|
22
24
|
if 'EVENT' in params and 'TIMES' in params['EVENT']:
|
|
23
25
|
times_array = params['EVENT']['TIMES']['value']
|
|
24
|
-
frames = times_array[1] #
|
|
26
|
+
frames = times_array[1] # should be time depending on C3D file
|
|
25
27
|
|
|
26
28
|
# Extract sides, types, subjects
|
|
27
29
|
contexts = params['EVENT']['CONTEXTS']['value'] if 'CONTEXTS' in params['EVENT'] else ['']
|
|
@@ -55,11 +57,12 @@ def c3d2zoo_data(c3d_obj):
|
|
|
55
57
|
|
|
56
58
|
# Place in correct channel
|
|
57
59
|
if 'SACR' in data:
|
|
58
|
-
data['SACR']['event'][key_name] = [frame, 0, 0]
|
|
60
|
+
data['SACR']['event'][key_name] = [frame-1, 0, 0] # remove 1 to follow python
|
|
59
61
|
else:
|
|
60
|
-
data[labels[0]]['event'][key_name] = [frame, 0, 0]
|
|
62
|
+
data[labels[0]]['event'][key_name] = [frame-1, 0, 0] # remove 1 to follow python
|
|
61
63
|
|
|
62
64
|
# todo add relevant meta data to zoosystem
|
|
63
|
-
data['zoosystem'] =
|
|
65
|
+
data['zoosystem'] = set_zoosystem()
|
|
66
|
+
data['zoosystem']['Analog']['Freq'] = int(params['ANALOG']['RATE']['value'][0])
|
|
64
67
|
|
|
65
68
|
return data
|
|
@@ -2,10 +2,11 @@ import pandas as pd
|
|
|
2
2
|
import os
|
|
3
3
|
import re
|
|
4
4
|
|
|
5
|
+
from biomechzoo.utils.set_zoosystem import set_zoosystem
|
|
5
6
|
from biomechzoo.utils.compute_sampling_rate_from_time import compute_sampling_rate_from_time
|
|
6
7
|
|
|
7
8
|
|
|
8
|
-
def csv2zoo_data(csv_path, type='csv',skip_rows=0, freq=None):
|
|
9
|
+
def csv2zoo_data(csv_path, type='csv', skip_rows=0, freq=None):
|
|
9
10
|
# todo: check calculation for sampling rate
|
|
10
11
|
|
|
11
12
|
# Read header lines until 'endheader'
|
|
@@ -51,13 +52,16 @@ def csv2zoo_data(csv_path, type='csv',skip_rows=0, freq=None):
|
|
|
51
52
|
if freq is None:
|
|
52
53
|
time_col = [col for col in df.columns if 'time' in col.lower()]
|
|
53
54
|
if time_col is not None:
|
|
54
|
-
time_data = df[time_col].to_numpy()[:,0]
|
|
55
|
+
time_data = df[time_col].to_numpy()[:, 0]
|
|
55
56
|
freq = compute_sampling_rate_from_time(time_data)
|
|
56
57
|
|
|
57
58
|
# add metadata
|
|
58
59
|
# todo update zoosystem to match biomechzoo requirements
|
|
59
|
-
zoo_data['zoosystem'] =
|
|
60
|
-
zoo_data['zoosystem']['Freq'] = freq
|
|
60
|
+
zoo_data['zoosystem'] = set_zoosystem(csv_path)
|
|
61
|
+
zoo_data['zoosystem']['Video']['Freq'] = freq
|
|
62
|
+
zoo_data['zoosystem']['Analog']['Freq'] = 'None'
|
|
63
|
+
if 'version' in metadata:
|
|
64
|
+
zoo_data['zoosystem']['collection_system_version'] = metadata['version']
|
|
61
65
|
|
|
62
66
|
return zoo_data
|
|
63
67
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
from biomechzoo.mvn.load_mvnx import load_mvnx
|
|
3
3
|
from biomechzoo.mvn.mvn import JOINTS, SEGMENTS
|
|
4
|
+
from biomechzoo.utils.set_zoosystem import set_zoosystem
|
|
4
5
|
|
|
5
6
|
def mvnx2zoo_data(fl):
|
|
6
7
|
""" loads mvnx file from xsens"""
|
|
@@ -37,10 +38,11 @@ def mvnx2zoo_data(fl):
|
|
|
37
38
|
data = _get_foot_strike_events(mvnx_file, data)
|
|
38
39
|
|
|
39
40
|
# add meta information
|
|
40
|
-
data = _get_meta_info(mvnx_file, data)
|
|
41
|
+
data = _get_meta_info(fl, mvnx_file, data)
|
|
41
42
|
|
|
42
43
|
return data
|
|
43
44
|
|
|
45
|
+
|
|
44
46
|
def is_valid_for_zoo(val):
|
|
45
47
|
"""
|
|
46
48
|
Returns True if the value is valid for a MATLAB-compatible zoo structure.
|
|
@@ -53,13 +55,13 @@ def is_valid_for_zoo(val):
|
|
|
53
55
|
return False
|
|
54
56
|
return True
|
|
55
57
|
|
|
56
|
-
|
|
58
|
+
|
|
59
|
+
def _get_meta_info(fl, mvnx_file, data):
|
|
57
60
|
# todo: add more, see mvnx_file object
|
|
58
|
-
data['zoosystem'] =
|
|
59
|
-
data['zoosystem']['Video'] = {}
|
|
61
|
+
data['zoosystem'] = set_zoosystem(fl)
|
|
60
62
|
data['zoosystem']['Video']['Freq'] = int(mvnx_file.frame_rate)
|
|
61
|
-
data['zoosystem']['
|
|
62
|
-
data['zoosystem']['
|
|
63
|
+
data['zoosystem']['mvnx_version'] = mvnx_file.version
|
|
64
|
+
data['zoosystem']['mvnx_configuration'] = mvnx_file.configuration
|
|
63
65
|
data['zoosystem']['recording_date'] = mvnx_file.recording_date
|
|
64
66
|
data['zoosystem']['original_file_name'] = mvnx_file.original_file_name
|
|
65
67
|
data['zoosystem']['frame_count'] = mvnx_file.frame_count
|
|
@@ -10,11 +10,19 @@ def partition_data(data, evt_start, evt_end):
|
|
|
10
10
|
e1, _ = findfield(data, evt_start)
|
|
11
11
|
e2, _ = findfield(data, evt_end)
|
|
12
12
|
|
|
13
|
+
if e1 is None or e2 is None or len(e1) == 0 or len(e2) == 0:
|
|
14
|
+
raise ValueError(f"Event not found: evt_start='{evt_start}' returned {e1}, evt_end='{evt_end}' returned {e2}")
|
|
15
|
+
|
|
13
16
|
data_new = copy.deepcopy(data)
|
|
14
17
|
for ch_name, ch_data in data_new.items():
|
|
15
18
|
if ch_name != 'zoosystem':
|
|
19
|
+
print(ch_name)
|
|
20
|
+
line = ch_data['line']
|
|
16
21
|
try:
|
|
17
|
-
|
|
22
|
+
if line.ndim == 1:
|
|
23
|
+
data_new[ch_name]['line'] = line[e1[0]:e2[0]]
|
|
24
|
+
else:
|
|
25
|
+
data_new[ch_name]['line'] = line[e1[0]:e2[0], :]
|
|
18
26
|
except (IndexError, ValueError) as e:
|
|
19
27
|
# IndexError: if e1[0]:e2[0] goes beyond the available indices
|
|
20
28
|
# ValueError: less likely, but may arise with shape mismatches
|
|
@@ -24,9 +32,7 @@ def partition_data(data, evt_start, evt_end):
|
|
|
24
32
|
events = ch_data['event']
|
|
25
33
|
for event_name, value in events.items():
|
|
26
34
|
original_frame = value[0]
|
|
27
|
-
if original_frame ==
|
|
28
|
-
continue # leave index 1 as is (per MATLAB version)
|
|
29
|
-
elif original_frame == 999:
|
|
35
|
+
if original_frame == 999:
|
|
30
36
|
continue # do not change outlier markers
|
|
31
37
|
else:
|
|
32
38
|
new_frame = original_frame - e1[0] + 1
|
|
@@ -22,7 +22,7 @@ def engine(root_folder, extension='.zoo', subfolders=None, name_contains=None, v
|
|
|
22
22
|
subfolders (list or str, optional): List of folder names to restrict the search to.
|
|
23
23
|
Only files inside these folders (or their subfolders) are included.
|
|
24
24
|
If None, search all subfolders.
|
|
25
|
-
name_contains (str, optional): Substring that must be present in the filename
|
|
25
|
+
name_contains (str, or list; optional): Substring that must be present in the filename
|
|
26
26
|
(case-insensitive). If None, no substring filtering is applied.
|
|
27
27
|
verbose (bool, optional): If true, displays additional information to user
|
|
28
28
|
Returns:
|
|
@@ -33,10 +33,14 @@ def engine(root_folder, extension='.zoo', subfolders=None, name_contains=None, v
|
|
|
33
33
|
if type(subfolders) is str:
|
|
34
34
|
subfolders = [subfolders]
|
|
35
35
|
|
|
36
|
+
# check format of name_contants (str or list)
|
|
37
|
+
if name_contains is not None:
|
|
38
|
+
if type(name_contains) is str:
|
|
39
|
+
name_contains = [name_contains]
|
|
40
|
+
|
|
36
41
|
matched_files = []
|
|
37
42
|
|
|
38
43
|
subfolders_set = set(subfolders) if subfolders else None
|
|
39
|
-
|
|
40
44
|
for dirpath, _, filenames in os.walk(root_folder):
|
|
41
45
|
if subfolders_set is not None:
|
|
42
46
|
rel_path = os.path.relpath(dirpath, root_folder)
|
|
@@ -51,9 +55,16 @@ def engine(root_folder, extension='.zoo', subfolders=None, name_contains=None, v
|
|
|
51
55
|
for file in filenames:
|
|
52
56
|
if not file.lower().endswith(extension.lower()):
|
|
53
57
|
continue
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
full_path = os.path.join(dirpath, file)
|
|
59
|
+
if name_contains is not None:
|
|
60
|
+
match = False
|
|
61
|
+
for name_contain in name_contains:
|
|
62
|
+
if name_contain and name_contain.lower() in full_path.lower(): # <-- check full path
|
|
63
|
+
match = True
|
|
64
|
+
break
|
|
65
|
+
if not match:
|
|
66
|
+
continue
|
|
67
|
+
matched_files.append(full_path)
|
|
57
68
|
|
|
58
69
|
if verbose:
|
|
59
70
|
print("Found {} {} files in subfolders named {} with substring {}:".format(len(matched_files), extension, subfolders, name_contains))
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from biomechzoo.utils.version import get_biomechzoo_version
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def set_zoosystem(fl=None):
|
|
7
|
+
"""
|
|
8
|
+
Create the 'zoosystem' branch for data being imported to BiomechZoo.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
fl: str
|
|
12
|
+
Path to the source file (e.g., C3D or CSV).
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
zoosystem: dict
|
|
16
|
+
Dictionary containing default BiomechZoo system parameters.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
# Default top-level fields
|
|
20
|
+
zch = ['Analog', 'Anthro', 'AVR', 'CompInfo', 'SourceFile',
|
|
21
|
+
'Units', 'Version', 'Video']
|
|
22
|
+
|
|
23
|
+
# Initialize top-level dict
|
|
24
|
+
zoosystem = {key: {} for key in zch}
|
|
25
|
+
|
|
26
|
+
# Section-specific defaults
|
|
27
|
+
section = ['Video', 'Analog']
|
|
28
|
+
for sec in section:
|
|
29
|
+
zoosystem[sec]['Channels'] = []
|
|
30
|
+
zoosystem[sec]['Freq'] = []
|
|
31
|
+
zoosystem[sec]['Indx'] = []
|
|
32
|
+
zoosystem[sec]['ORIGINAL_START_FRAME'] = []
|
|
33
|
+
zoosystem[sec]['ORIGINAL_END_FRAME'] = []
|
|
34
|
+
zoosystem[sec]['CURRENT_START_FRAME'] = []
|
|
35
|
+
zoosystem[sec]['CURRENT_END_FRAME'] = []
|
|
36
|
+
|
|
37
|
+
# Processing and AVR defaults
|
|
38
|
+
zoosystem['Processing'] = ''
|
|
39
|
+
zoosystem['AVR'] = 0
|
|
40
|
+
|
|
41
|
+
# Force plates defaults
|
|
42
|
+
zoosystem['Analog']['FPlates'] = {
|
|
43
|
+
'CORNERS': [],
|
|
44
|
+
'NUMUSED': 0,
|
|
45
|
+
'LOCALORIGIN': [],
|
|
46
|
+
'LABELS': []
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Version and source file
|
|
50
|
+
zoosystem['Version'] = get_biomechzoo_version()
|
|
51
|
+
if fl is None:
|
|
52
|
+
zoosystem['SourceFile'] = 'None' # ensure string
|
|
53
|
+
else:
|
|
54
|
+
zoosystem['SourceFile'] = str(Path(fl)) # ensure string
|
|
55
|
+
|
|
56
|
+
# Units defaults
|
|
57
|
+
zoosystem['Units'] = {
|
|
58
|
+
'Markers': 'mm',
|
|
59
|
+
'Angles': 'deg',
|
|
60
|
+
'Forces': 'N',
|
|
61
|
+
'Moments': 'Nmm',
|
|
62
|
+
'Power': 'W/kg',
|
|
63
|
+
'Scalars': 'mm'
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return zoosystem
|
|
@@ -46,7 +46,9 @@ src/biomechzoo/utils/compute_sampling_rate_from_time.py
|
|
|
46
46
|
src/biomechzoo/utils/engine.py
|
|
47
47
|
src/biomechzoo/utils/findfield.py
|
|
48
48
|
src/biomechzoo/utils/get_split_events.py
|
|
49
|
+
src/biomechzoo/utils/set_zoosystem.py
|
|
49
50
|
src/biomechzoo/utils/split_trial.py
|
|
51
|
+
src/biomechzoo/utils/version.py
|
|
50
52
|
src/biomechzoo/utils/zload.py
|
|
51
53
|
src/biomechzoo/utils/zplot.py
|
|
52
54
|
src/biomechzoo/utils/zsave.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/continuous_relative_phase_data.py
RENAMED
|
File without changes
|
{biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/biomech_ops/continuous_relative_phase_line.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/processing/split_trial_by_gait_cycle.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{biomechzoo-0.4.5 → biomechzoo-0.4.8}/src/biomechzoo/utils/compute_sampling_rate_from_time.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|