supervisely 6.73.322__py3-none-any.whl → 6.73.323__py3-none-any.whl
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.
- supervisely/annotation/annotation.py +1 -1
- supervisely/convert/base_converter.py +1 -0
- supervisely/convert/volume/__init__.py +1 -0
- supervisely/convert/volume/nii/__init__.py +0 -0
- supervisely/convert/volume/nii/nii_volume_converter.py +151 -0
- supervisely/convert/volume/nii/nii_volume_helper.py +38 -0
- supervisely/volume/volume.py +43 -0
- {supervisely-6.73.322.dist-info → supervisely-6.73.323.dist-info}/METADATA +1 -1
- {supervisely-6.73.322.dist-info → supervisely-6.73.323.dist-info}/RECORD +13 -10
- {supervisely-6.73.322.dist-info → supervisely-6.73.323.dist-info}/LICENSE +0 -0
- {supervisely-6.73.322.dist-info → supervisely-6.73.323.dist-info}/WHEEL +0 -0
- {supervisely-6.73.322.dist-info → supervisely-6.73.323.dist-info}/entry_points.txt +0 -0
- {supervisely-6.73.322.dist-info → supervisely-6.73.323.dist-info}/top_level.txt +0 -0
|
@@ -404,7 +404,7 @@ class Annotation:
|
|
|
404
404
|
f"Failed to deserialize one of the label from JSON format annotation: \n{repr(e)}"
|
|
405
405
|
)
|
|
406
406
|
|
|
407
|
-
custom_data = data.get(AnnotationJsonFields.CUSTOM_DATA, {})
|
|
407
|
+
custom_data = data.get(AnnotationJsonFields.CUSTOM_DATA, {}) or {}
|
|
408
408
|
prob_labels = None
|
|
409
409
|
if (
|
|
410
410
|
AnnotationJsonFields.PROBABILITY_LABELS in custom_data
|
|
File without changes
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import magic
|
|
5
|
+
|
|
6
|
+
from supervisely import ProjectMeta, generate_free_name, logger
|
|
7
|
+
from supervisely._utils import batched, is_development
|
|
8
|
+
from supervisely.annotation.obj_class import ObjClass
|
|
9
|
+
from supervisely.annotation.obj_class_collection import ObjClassCollection
|
|
10
|
+
from supervisely.api.api import Api
|
|
11
|
+
from supervisely.convert.base_converter import AvailableVolumeConverters
|
|
12
|
+
from supervisely.convert.volume.nii import nii_volume_helper as helper
|
|
13
|
+
from supervisely.convert.volume.volume_converter import VolumeConverter
|
|
14
|
+
from supervisely.geometry.mask_3d import Mask3D
|
|
15
|
+
from supervisely.io.fs import (
|
|
16
|
+
get_file_ext,
|
|
17
|
+
get_file_name,
|
|
18
|
+
get_file_name_with_ext,
|
|
19
|
+
list_files,
|
|
20
|
+
)
|
|
21
|
+
from supervisely.volume.volume import is_nifti_file
|
|
22
|
+
from supervisely.volume_annotation.volume_annotation import VolumeAnnotation
|
|
23
|
+
from supervisely.volume_annotation.volume_object import VolumeObject
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class NiiConverter(VolumeConverter):
|
|
27
|
+
|
|
28
|
+
def __str__(self) -> str:
|
|
29
|
+
return AvailableVolumeConverters.NII
|
|
30
|
+
|
|
31
|
+
def validate_format(self) -> bool:
|
|
32
|
+
# create Items
|
|
33
|
+
converted_dir_name = "converted"
|
|
34
|
+
# nrrds_dict = {}
|
|
35
|
+
nifti_dict = {}
|
|
36
|
+
nifti_dirs = {}
|
|
37
|
+
for root, _, files in os.walk(self._input_data):
|
|
38
|
+
dir_name = os.path.basename(root)
|
|
39
|
+
nifti_dirs[dir_name] = root
|
|
40
|
+
if converted_dir_name in root:
|
|
41
|
+
continue
|
|
42
|
+
for file in files:
|
|
43
|
+
path = os.path.join(root, file)
|
|
44
|
+
mime = magic.from_file(path, mime=True)
|
|
45
|
+
if mime == "application/gzip" or mime == "application/octet-stream":
|
|
46
|
+
if is_nifti_file(path): # is nifti
|
|
47
|
+
name = get_file_name(path)
|
|
48
|
+
if name.endswith(".nii"):
|
|
49
|
+
name = get_file_name(name)
|
|
50
|
+
nifti_dict[name] = path
|
|
51
|
+
|
|
52
|
+
self._items = []
|
|
53
|
+
skip_files = []
|
|
54
|
+
for name, nrrd_path in nifti_dict.items():
|
|
55
|
+
if name in nifti_dirs:
|
|
56
|
+
item = self.Item(item_path=nrrd_path)
|
|
57
|
+
ann_dir = nifti_dirs[name]
|
|
58
|
+
item.ann_data = list_files(ann_dir, [".nii", ".nii.gz", ".gz"], None, True)
|
|
59
|
+
self._items.append(item)
|
|
60
|
+
skip_files.extend(item.ann_data)
|
|
61
|
+
skip_files.append(nrrd_path)
|
|
62
|
+
|
|
63
|
+
for name, nrrd_path in nifti_dict.items():
|
|
64
|
+
if nrrd_path in skip_files:
|
|
65
|
+
continue
|
|
66
|
+
item = self.Item(item_path=nrrd_path)
|
|
67
|
+
self._items.append(item)
|
|
68
|
+
|
|
69
|
+
self._meta = ProjectMeta()
|
|
70
|
+
return self.items_count > 0
|
|
71
|
+
|
|
72
|
+
def upload_dataset(
|
|
73
|
+
self,
|
|
74
|
+
api: Api,
|
|
75
|
+
dataset_id: int,
|
|
76
|
+
batch_size: int = 1,
|
|
77
|
+
log_progress=True,
|
|
78
|
+
):
|
|
79
|
+
"""Upload converted data to Supervisely"""
|
|
80
|
+
|
|
81
|
+
meta, renamed_classes, renamed_tags = self.merge_metas_with_conflicts(api, dataset_id)
|
|
82
|
+
|
|
83
|
+
existing_names = set([vol.name for vol in api.volume.get_list(dataset_id)])
|
|
84
|
+
|
|
85
|
+
if log_progress:
|
|
86
|
+
progress, progress_cb = self.get_progress(
|
|
87
|
+
self.items_count, "Converting and uploading volumes..."
|
|
88
|
+
)
|
|
89
|
+
else:
|
|
90
|
+
progress_cb = None
|
|
91
|
+
|
|
92
|
+
converted_dir_name = "converted"
|
|
93
|
+
converted_dir = os.path.join(self._input_data, converted_dir_name)
|
|
94
|
+
meta_changed = False
|
|
95
|
+
|
|
96
|
+
for batch in batched(self._items, batch_size=batch_size):
|
|
97
|
+
item_names = []
|
|
98
|
+
item_paths = []
|
|
99
|
+
|
|
100
|
+
for item in batch:
|
|
101
|
+
# nii_path = item.path
|
|
102
|
+
item.path = helper.nifti_to_nrrd(item.path, converted_dir)
|
|
103
|
+
ext = get_file_ext(item.path)
|
|
104
|
+
if ext.lower() != ext:
|
|
105
|
+
new_volume_path = Path(item.path).with_suffix(ext.lower()).as_posix()
|
|
106
|
+
os.rename(item.path, new_volume_path)
|
|
107
|
+
item.path = new_volume_path
|
|
108
|
+
item.name = get_file_name_with_ext(item.path)
|
|
109
|
+
item.name = generate_free_name(
|
|
110
|
+
existing_names, item.name, with_ext=True, extend_used_names=True
|
|
111
|
+
)
|
|
112
|
+
item_names.append(item.name)
|
|
113
|
+
item_paths.append(item.path)
|
|
114
|
+
|
|
115
|
+
volume_info = api.volume.upload_nrrd_serie_path(
|
|
116
|
+
dataset_id, name=item.name, path=item.path
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
if isinstance(item.ann_data, list) and len(item.ann_data) > 0:
|
|
120
|
+
objs = []
|
|
121
|
+
spatial_figures = []
|
|
122
|
+
for ann_path in item.ann_data:
|
|
123
|
+
ann_name = get_file_name(ann_path)
|
|
124
|
+
if ann_name.endswith(".nii"):
|
|
125
|
+
ann_name = get_file_name(ann_name)
|
|
126
|
+
for mask, _ in helper.get_annotation_from_nii(ann_path):
|
|
127
|
+
obj_class = meta.get_obj_class(ann_name)
|
|
128
|
+
if obj_class is None:
|
|
129
|
+
obj_class = ObjClass(ann_name, Mask3D)
|
|
130
|
+
meta = meta.add_obj_class(obj_class)
|
|
131
|
+
meta_changed = True
|
|
132
|
+
obj = VolumeObject(obj_class, mask_3d=mask)
|
|
133
|
+
spatial_figures.append(obj.figure)
|
|
134
|
+
objs.append(obj)
|
|
135
|
+
ann = VolumeAnnotation(
|
|
136
|
+
volume_info.meta, objects=objs, spatial_figures=spatial_figures
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
if meta_changed:
|
|
140
|
+
self._meta = meta
|
|
141
|
+
_, _, _ = self.merge_metas_with_conflicts(api, dataset_id)
|
|
142
|
+
|
|
143
|
+
api.volume.annotation.append(volume_info.id, ann)
|
|
144
|
+
|
|
145
|
+
if log_progress:
|
|
146
|
+
progress_cb(len(batch))
|
|
147
|
+
|
|
148
|
+
if log_progress:
|
|
149
|
+
if is_development():
|
|
150
|
+
progress.close()
|
|
151
|
+
logger.info(f"Dataset ID:{dataset_id} has been successfully uploaded.")
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Generator
|
|
3
|
+
|
|
4
|
+
import nrrd
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
from supervisely.geometry.mask_3d import Mask3D
|
|
8
|
+
from supervisely.io.fs import ensure_base_path, get_file_ext, get_file_name
|
|
9
|
+
from supervisely.volume.volume import convert_3d_nifti_to_nrrd
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def nifti_to_nrrd(nii_file_path: str, converted_dir: str) -> str:
|
|
13
|
+
"""Convert NIfTI 3D volume file to NRRD 3D volume file."""
|
|
14
|
+
|
|
15
|
+
output_name = get_file_name(nii_file_path)
|
|
16
|
+
if get_file_ext(output_name) == ".nii":
|
|
17
|
+
output_name = get_file_name(output_name)
|
|
18
|
+
|
|
19
|
+
data, header = convert_3d_nifti_to_nrrd(nii_file_path)
|
|
20
|
+
|
|
21
|
+
nrrd_file_path = os.path.join(converted_dir, f"{output_name}.nrrd")
|
|
22
|
+
ensure_base_path(nrrd_file_path)
|
|
23
|
+
|
|
24
|
+
nrrd.write(nrrd_file_path, data, header)
|
|
25
|
+
return nrrd_file_path
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_annotation_from_nii(path: str) -> Generator[Mask3D, None, None]:
|
|
29
|
+
"""Get annotation from NIfTI 3D volume file."""
|
|
30
|
+
|
|
31
|
+
data, _ = convert_3d_nifti_to_nrrd(path)
|
|
32
|
+
unique_classes = np.unique(data)
|
|
33
|
+
|
|
34
|
+
for class_id in unique_classes:
|
|
35
|
+
if class_id == 0:
|
|
36
|
+
continue
|
|
37
|
+
mask = Mask3D(data == class_id)
|
|
38
|
+
yield mask, class_id
|
supervisely/volume/volume.py
CHANGED
|
@@ -799,6 +799,49 @@ def convert_nifti_to_nrrd(path: str) -> Tuple[np.ndarray, dict]:
|
|
|
799
799
|
}
|
|
800
800
|
return data, header
|
|
801
801
|
|
|
802
|
+
def convert_3d_nifti_to_nrrd(path: str) -> Tuple[np.ndarray, dict]:
|
|
803
|
+
"""Convert 3D NIFTI volume to NRRD format.
|
|
804
|
+
Volume automatically reordered to RAS orientation as closest to canonical.
|
|
805
|
+
|
|
806
|
+
:param path: Path to NIFTI volume file.
|
|
807
|
+
:type path: str
|
|
808
|
+
:return: Volume data in NumPy array format and dictionary with metadata (NRRD header).
|
|
809
|
+
:rtype: Tuple[np.ndarray, dict]
|
|
810
|
+
:Usage example:
|
|
811
|
+
|
|
812
|
+
.. code-block:: python
|
|
813
|
+
|
|
814
|
+
import supervisely as sly
|
|
815
|
+
|
|
816
|
+
path = "/home/admin/work/volumes/vol_01.nii"
|
|
817
|
+
data, header = sly.volume.convert_nifti_to_nrrd(path)
|
|
818
|
+
"""
|
|
819
|
+
|
|
820
|
+
import nibabel as nib # pylint: disable=import-error
|
|
821
|
+
|
|
822
|
+
orientation_map = {
|
|
823
|
+
('R', 'A', 'S'): "right-anterior-superior",
|
|
824
|
+
('L', 'P', 'S'): "left-posterior-superior",
|
|
825
|
+
('R', 'P', 'I'): "right-posterior-inferior",
|
|
826
|
+
('L', 'A', 'I'): "left-anterior-inferior"
|
|
827
|
+
}
|
|
828
|
+
nifti = nib.load(path)
|
|
829
|
+
reordered_to_ras_nifti = nib.as_closest_canonical(nifti)
|
|
830
|
+
data = reordered_to_ras_nifti.get_fdata()
|
|
831
|
+
affine = reordered_to_ras_nifti.affine
|
|
832
|
+
orientation = nib.aff2axcodes(affine)
|
|
833
|
+
space_directions = affine[:3, :3].tolist()
|
|
834
|
+
space_origin = affine[:3, 3].tolist()
|
|
835
|
+
header = {
|
|
836
|
+
"space": orientation_map.get(orientation, "unknown"),
|
|
837
|
+
"space directions": space_directions,
|
|
838
|
+
"space origin": space_origin,
|
|
839
|
+
"sizes": data.shape,
|
|
840
|
+
"type": str(data.dtype),
|
|
841
|
+
"dimension": len(data.shape),
|
|
842
|
+
}
|
|
843
|
+
return data, header
|
|
844
|
+
|
|
802
845
|
|
|
803
846
|
def is_nifti_file(path: str) -> bool:
|
|
804
847
|
"""Check if the file is a NIFTI file.
|
|
@@ -5,7 +5,7 @@ supervisely/function_wrapper.py,sha256=R5YajTQ0GnRp2vtjwfC9hINkzQc0JiyGsu8TER373
|
|
|
5
5
|
supervisely/sly_logger.py,sha256=z92Vu5hmC0GgTIJO1n6kPDayRW9__8ix8hL6poDZj-Y,6274
|
|
6
6
|
supervisely/tiny_timer.py,sha256=hkpe_7FE6bsKL79blSs7WBaktuPavEVu67IpEPrfmjE,183
|
|
7
7
|
supervisely/annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
supervisely/annotation/annotation.py,sha256=
|
|
8
|
+
supervisely/annotation/annotation.py,sha256=x1RizD9DPiwk14Mf8xGvuwPdzx_zI5Zx1CVvmCy_sII,114665
|
|
9
9
|
supervisely/annotation/annotation_transforms.py,sha256=TlVy_gUbM-XH6GbLpZPrAi6pMIGTr7Ow02iSKOSTa-I,9582
|
|
10
10
|
supervisely/annotation/json_geometries_map.py,sha256=nL6AmMhFy02fw9ryBm75plKyOkDh61QdOToSuLAcz_Q,1659
|
|
11
11
|
supervisely/annotation/label.py,sha256=NpHZ5o2H6dI4KiII22o2HpiLXG1yekh-bEy8WvI2Ljg,37498
|
|
@@ -565,7 +565,7 @@ supervisely/collection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
|
565
565
|
supervisely/collection/key_indexed_collection.py,sha256=x2UVlkprspWhhae9oLUzjTWBoIouiWY9UQSS_MozfH0,37643
|
|
566
566
|
supervisely/collection/str_enum.py,sha256=Zp29yFGvnxC6oJRYNNlXhO2lTSdsriU1wiGHj6ahEJE,1250
|
|
567
567
|
supervisely/convert/__init__.py,sha256=ropgB1eebG2bfLoJyf2jp8Vv9UkFujaW3jVX-71ho1g,1353
|
|
568
|
-
supervisely/convert/base_converter.py,sha256=
|
|
568
|
+
supervisely/convert/base_converter.py,sha256=O2SP4I_Hd0aSn8kbOUocy8orkc_-iD-TQ-z4ieUqabA,18579
|
|
569
569
|
supervisely/convert/converter.py,sha256=tWxTDfFv7hwzQhUQrBxzfr6WP8FUGFX_ewg5T2HbUYo,8959
|
|
570
570
|
supervisely/convert/image/__init__.py,sha256=JEuyaBiiyiYmEUYqdn8Mog5FVXpz0H1zFubKkOOm73I,1395
|
|
571
571
|
supervisely/convert/image/image_converter.py,sha256=8vak8ZoKTN1ye2ZmCTvCZ605-Rw1AFLIEo7bJMfnR68,10426
|
|
@@ -658,11 +658,14 @@ supervisely/convert/video/mot/mot_converter.py,sha256=wXbv-9Psc2uVnhzHuOt5VnRIvS
|
|
|
658
658
|
supervisely/convert/video/sly/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
659
659
|
supervisely/convert/video/sly/sly_video_converter.py,sha256=S2qif7JFxqIi9VN_ez_iBtoJXpG9W6Ky2k5Er3-DtUo,4418
|
|
660
660
|
supervisely/convert/video/sly/sly_video_helper.py,sha256=D8PgoXpi0y3z-VEqvBLDf_gSUQ2hTL3irrfJyGhaV0Y,6758
|
|
661
|
-
supervisely/convert/volume/__init__.py,sha256=
|
|
661
|
+
supervisely/convert/volume/__init__.py,sha256=NjVfOa9uH1BdYvB-RynW6L28x0f_tqL9p7tHSIQ6Sso,245
|
|
662
662
|
supervisely/convert/volume/volume_converter.py,sha256=3jpt2Yn_G4FSP_vHFsJHQfYNQpT7q6ar_sRyr_xrPnA,5335
|
|
663
663
|
supervisely/convert/volume/dicom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
664
664
|
supervisely/convert/volume/dicom/dicom_converter.py,sha256=__QP8fMAaq_BdWFYh1_nAYT2gpY1WwZzdlDj39YwHhw,3195
|
|
665
665
|
supervisely/convert/volume/dicom/dicom_helper.py,sha256=1EXmxl5Z8Xi3ZkZnfJ4EbiPCVyITSXUc0Cn_oo02pPE,1284
|
|
666
|
+
supervisely/convert/volume/nii/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
667
|
+
supervisely/convert/volume/nii/nii_volume_converter.py,sha256=kI2JmeFuLfLWgYGCEozoaka1QH4TocnfgyN0em6maa0,5946
|
|
668
|
+
supervisely/convert/volume/nii/nii_volume_helper.py,sha256=kzh20fsdeI8efA0vawW0M6Wh48nMlCLzHBQFuSNVFmc,1136
|
|
666
669
|
supervisely/convert/volume/sly/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
667
670
|
supervisely/convert/volume/sly/sly_volume_converter.py,sha256=XmSuxnRqxchG87b244f3h0UHvOt6IkajMquL1drWlCM,5595
|
|
668
671
|
supervisely/convert/volume/sly/sly_volume_helper.py,sha256=gUY0GW3zDMlO2y-zQQG36uoXMrKkKz4-ErM1CDxFCxE,5620
|
|
@@ -1056,7 +1059,7 @@ supervisely/volume/__init__.py,sha256=EBZBY_5mzabXzMUQh5akusIGd16XnX9n8J0jIi_JmW
|
|
|
1056
1059
|
supervisely/volume/nrrd_encoder.py,sha256=1lqwwyqxEvctw1ysQ70x4xPSV1uy1g5YcH5CURwL7-c,4084
|
|
1057
1060
|
supervisely/volume/nrrd_loader.py,sha256=_yqahKcqSRxunHZ5LtnUWIRA7UvIhPKOhAUwYijSGY4,9065
|
|
1058
1061
|
supervisely/volume/stl_converter.py,sha256=WIMQgHO_u4JT58QdcMXcb_euF1BFhM7D52IVX_0QTxE,6285
|
|
1059
|
-
supervisely/volume/volume.py,sha256
|
|
1062
|
+
supervisely/volume/volume.py,sha256=7ebCIICqZMwRP3ruRy3PtSeiUpBpSlyRH20VJybBQbI,25828
|
|
1060
1063
|
supervisely/volume_annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
1061
1064
|
supervisely/volume_annotation/constants.py,sha256=BdFIh56fy7vzLIjt0gH8xP01EIU-qgQIwbSHVUcABCU,569
|
|
1062
1065
|
supervisely/volume_annotation/plane.py,sha256=wyezAcc8tLp38O44CwWY0wjdQxf3VjRdFLWooCrk-Nw,16301
|
|
@@ -1078,9 +1081,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
1078
1081
|
supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
|
|
1079
1082
|
supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
|
|
1080
1083
|
supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
|
|
1081
|
-
supervisely-6.73.
|
|
1082
|
-
supervisely-6.73.
|
|
1083
|
-
supervisely-6.73.
|
|
1084
|
-
supervisely-6.73.
|
|
1085
|
-
supervisely-6.73.
|
|
1086
|
-
supervisely-6.73.
|
|
1084
|
+
supervisely-6.73.323.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
1085
|
+
supervisely-6.73.323.dist-info/METADATA,sha256=uIqQoH6i-OiLhSZSLt6SqL7O1ZWPV0D6ZRJICli80eE,33596
|
|
1086
|
+
supervisely-6.73.323.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
1087
|
+
supervisely-6.73.323.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
|
|
1088
|
+
supervisely-6.73.323.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
|
|
1089
|
+
supervisely-6.73.323.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|