supervisely 6.73.361__py3-none-any.whl → 6.73.363__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.
@@ -4,6 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import asyncio
6
6
  import io
7
+ import json
7
8
  import os
8
9
  import pickle
9
10
  import random
@@ -4465,7 +4466,7 @@ def _download_project(
4465
4466
  try:
4466
4467
  if download_blob_files:
4467
4468
  project_info = api.project.get_info_by_id(project_id)
4468
- create_blob_readme(project_fs=project_fs, project_info=project_info)
4469
+ create_blob_readme(project_fs=project_fs, project_info=project_info, api=api)
4469
4470
  else:
4470
4471
  create_readme(dest_dir, project_id, api)
4471
4472
  except Exception as e:
@@ -5092,6 +5093,10 @@ def create_readme(
5092
5093
  "{{dataset_structure_info}}", _dataset_structure_md(project_info, api)
5093
5094
  )
5094
5095
 
5096
+ template = template.replace(
5097
+ "{{dataset_description_info}}", _dataset_descriptions_md(project_info, api)
5098
+ )
5099
+
5095
5100
  with open(readme_path, "w") as f:
5096
5101
  f.write(template)
5097
5102
  return readme_path
@@ -5256,6 +5261,7 @@ def _dataset_blob_structure_md(
5256
5261
  def create_blob_readme(
5257
5262
  project_fs: Project,
5258
5263
  project_info: ProjectInfo,
5264
+ api: Api,
5259
5265
  ) -> str:
5260
5266
  """Creates a README.md file using the template, adds general information
5261
5267
  about the project and creates a dataset structure section.
@@ -5294,7 +5300,9 @@ def create_blob_readme(
5294
5300
  template = template.replace(
5295
5301
  "{{dataset_structure_info}}", _dataset_blob_structure_md(project_fs, project_info)
5296
5302
  )
5297
-
5303
+ template = template.replace(
5304
+ "{{dataset_description_info}}", _dataset_descriptions_md(project_info, api)
5305
+ )
5298
5306
  with open(readme_path, "w") as f:
5299
5307
  f.write(template)
5300
5308
  return readme_path
@@ -5430,6 +5438,37 @@ def _dataset_structure_md(
5430
5438
 
5431
5439
  return "".join(result_md)
5432
5440
 
5441
+ def _dataset_descriptions_md(project_info: sly.ProjectInfo, api: sly.Api) -> str:
5442
+ """Creates a markdown string with dictionary of descriptions and custom data of datasets.
5443
+ :param project_info: Project information.
5444
+ :type project_info: :class:`ProjectInfo<supervisely.project.project_info.ProjectInfo>`
5445
+ :param api: Supervisely API address and token.
5446
+ :type api: :class:`Api<supervisely.api.api.Api>`
5447
+ :return: Markdown string with dictionary of descriptions and custom data of datasets.
5448
+ :rtype: str
5449
+ """
5450
+
5451
+ data_found = False
5452
+ result_md = "All datasets in the project can have their own descriptions and custom data. You can add or edit the description and custom data of a dataset in the datasets list page. In this section, you can find this information for each dataset by dataset name (e.g. `ds1/ds2/ds3`, where `ds1` and `ds2` are parent datasets for `ds3` dataset).<br>"
5453
+ result_md += "\n\n```json\n{\n"
5454
+ for parents, dataset_info in api.dataset.tree(project_info.id):
5455
+ dataset_info = api.dataset.get_info_by_id(dataset_info.id)
5456
+ full_ds_name = "/".join(parents + [dataset_info.name])
5457
+ if dataset_info.description or dataset_info.custom_data:
5458
+ data_found = True
5459
+ result_md += f" \"{full_ds_name}\": {{\n"
5460
+ if dataset_info.description:
5461
+ result_md += f" \"description\": \"{dataset_info.description}\",\n"
5462
+ if dataset_info.custom_data:
5463
+ formated_custom_data = json.dumps(dataset_info.custom_data, indent=4)
5464
+ formated_custom_data = formated_custom_data.replace("\n", "\n ")
5465
+ result_md += f" \"custom_data\": {formated_custom_data}\n"
5466
+ result_md += " },\n"
5467
+ result_md += "}\n```"
5468
+ if not data_found:
5469
+ result_md = "_No dataset descriptions or custom data found in the project._"
5470
+ return result_md
5471
+
5433
5472
 
5434
5473
  async def _download_project_async(
5435
5474
  api: sly.Api,
@@ -5697,7 +5736,7 @@ async def _download_project_async(
5697
5736
  try:
5698
5737
  if download_blob_files:
5699
5738
  project_info = api.project.get_info_by_id(project_id)
5700
- create_blob_readme(project_fs=project_fs, project_info=project_info)
5739
+ create_blob_readme(project_fs=project_fs, project_info=project_info, api=api)
5701
5740
  else:
5702
5741
  create_readme(dest_dir, project_id, api)
5703
5742
  except Exception as e:
@@ -10,6 +10,10 @@ This is a general information about the project.<br>
10
10
  In this section, you can find information about the dataset structure. Dataset names are clickable and will redirect you to the corresponding folder.<br><br>
11
11
  {{dataset_structure_info}}<br>
12
12
 
13
+ ## Additional information (descriptions and custom data for datasets)
14
+
15
+ {{dataset_description_info}}
16
+
13
17
  ## Useful links
14
18
 
15
19
  Please, visit the [Supervisely blog](https://supervisely.com/blog) to keep up with the latest news, updates, and tutorials and subscribe to [our YouTube channel](https://www.youtube.com/c/Supervisely) to watch video tutorials.<br>
@@ -9,9 +9,11 @@ import numpy as np
9
9
  import pydicom
10
10
  import SimpleITK as sitk
11
11
  import stringcase
12
+ from trimesh import Trimesh
12
13
 
13
14
  import supervisely.volume.nrrd_encoder as nrrd_encoder
14
15
  from supervisely import logger
16
+ from supervisely.geometry.mask_3d import Mask3D
15
17
  from supervisely.io.fs import get_file_ext, get_file_name, list_files_recursively
16
18
 
17
19
  # Do NOT use directly for extension validation. Use is_valid_ext() / has_valid_ext() below instead.
@@ -783,7 +785,7 @@ def convert_nifti_to_nrrd(path: str) -> Tuple[np.ndarray, dict]:
783
785
  data, header = sly.volume.convert_nifti_to_nrrd(path)
784
786
  """
785
787
 
786
- import nibabel as nib # pylint: disable=import-error
788
+ import nibabel as nib # pylint: disable=import-error
787
789
 
788
790
  nifti = nib.load(path)
789
791
  reordered_to_ras_nifti = nib.as_closest_canonical(nifti)
@@ -799,6 +801,7 @@ def convert_nifti_to_nrrd(path: str) -> Tuple[np.ndarray, dict]:
799
801
  }
800
802
  return data, header
801
803
 
804
+
802
805
  def convert_3d_nifti_to_nrrd(path: str) -> Tuple[np.ndarray, dict]:
803
806
  """Convert 3D NIFTI volume to NRRD format.
804
807
  Volume automatically reordered to RAS orientation as closest to canonical.
@@ -830,14 +833,14 @@ def convert_3d_nifti_to_nrrd(path: str) -> Tuple[np.ndarray, dict]:
830
833
  space_directions = (direction.T * spacing[:, None]).tolist()
831
834
 
832
835
  header = {
833
- "dimension": 3,
834
- "space": "right-anterior-superior",
835
- "sizes": list(data.shape),
836
- "space directions": space_directions,
837
- "endian": "little",
838
- "encoding": "gzip",
839
- "space origin": origin
840
- }
836
+ "dimension": 3,
837
+ "space": "right-anterior-superior",
838
+ "sizes": list(data.shape),
839
+ "space directions": space_directions,
840
+ "endian": "little",
841
+ "encoding": "gzip",
842
+ "space origin": origin,
843
+ }
841
844
  return data, header
842
845
 
843
846
 
@@ -861,3 +864,96 @@ def is_nifti_file(path: str) -> bool:
861
864
  return True
862
865
  except nib.filebasedimages.ImageFileError:
863
866
  return False
867
+
868
+
869
+ def convert_3d_geometry_to_mesh(
870
+ geometry: Mask3D,
871
+ spacing: tuple = None,
872
+ level: float = 0.5,
873
+ apply_decimation: bool = False,
874
+ decimation_fraction: float = 0.5,
875
+ ) -> Trimesh:
876
+ """
877
+ Converts a 3D geometry (Mask3D) to a Trimesh mesh.
878
+
879
+ :param geometry: The 3D geometry to convert.
880
+ :type geometry: supervisely.geometry.mask_3d.Mask3D
881
+ :param spacing: Voxel spacing in (x, y, z). Default is taken from geometry meta.
882
+ :type spacing: tuple
883
+ :param level: Isosurface value for marching cubes. Default is 0.5.
884
+ :type level: float
885
+ :param apply_decimation: Whether to simplify the mesh. Default is False.
886
+ :type apply_decimation: bool
887
+ :param decimation_fraction: Fraction of faces to keep if decimation is applied. Default is 0.5.
888
+ :type decimation_fraction: float
889
+ :return: The resulting Trimesh mesh.
890
+ :rtype: trimesh.Trimesh
891
+
892
+ :Usage example:
893
+
894
+ .. code-block:: python
895
+
896
+ mask3d = Mask3D.create_from_file("path/to/mask3d")
897
+ mesh = convert_3d_geometry_to_mesh(mask3d, spacing=(1.0, 1.0, 1.0), level=0.7, apply_decimation=True)
898
+ """
899
+ from skimage import measure
900
+
901
+ # Flip the mask along the x-axis to correct mirroring
902
+ mask = np.flip(geometry.data, axis=0)
903
+ if spacing is None:
904
+ try:
905
+ spacing = tuple(
906
+ float(abs(direction[i])) for i, direction in enumerate(geometry._space_directions)
907
+ )
908
+ except Exception as e:
909
+ logger.warning(
910
+ "Failed to get spacing from geometry meta. Using (1.0, 1.0, 1.0).", exc_info=1
911
+ )
912
+ spacing = (1.0, 1.0, 1.0)
913
+
914
+ # marching_cubes expects (z, y, x) order
915
+ verts, faces, normals, _ = measure.marching_cubes(
916
+ mask.astype(np.float32), level=level, spacing=spacing
917
+ )
918
+ mesh = Trimesh(vertices=verts, faces=faces, vertex_normals=normals, process=False)
919
+
920
+ if apply_decimation and 0 < decimation_fraction < 1:
921
+ mesh = mesh.simplify_quadric_decimation(int(len(mesh.faces) * decimation_fraction))
922
+
923
+ return mesh
924
+
925
+
926
+ def export_3d_as_mesh(geometry: Mask3D, output_path: str, kwargs=None):
927
+ """
928
+ Exports the 3D mesh representation of the object to a file in either STL or OBJ format.
929
+
930
+ :param geometry: The 3D geometry to be exported.
931
+ :type geometry: supervisely.geometry.mask_3d.Mask3D
932
+ :param output_path: The path to the output file. Must have a ".stl" or ".obj" extension.
933
+ :type output_path: str
934
+ :param kwargs: Additional keyword arguments for mesh generation. Supported keys:
935
+ - spacing (tuple): Voxel spacing in (x, y, z). By default the value will be taken from geometry meta.
936
+ - level (float): Isosurface value for marching cubes. Default is 0.5.
937
+ - apply_decimation (bool): Whether to simplify the mesh. Default is False.
938
+ - decimation_fraction (float): Fraction of faces to keep if decimation is applied. Default is 0.5.
939
+ :type kwargs: dict, optional
940
+ :return: None
941
+
942
+ :Usage example:
943
+
944
+ .. code-block:: python
945
+
946
+ mask3d_path = "path/to/mask3d"
947
+ mask3d = Mask3D.create_from_file(mask3d_path)
948
+
949
+ mask3d.export_3d_as_mesh(mask3d, "output.stl", {"spacing": (1.0, 1.0, 1.0), "level": 0.7, "apply_decimation": True})
950
+ """
951
+
952
+ if kwargs is None:
953
+ kwargs = {}
954
+
955
+ if get_file_ext(output_path).lower() not in [".stl", ".obj"]:
956
+ raise ValueError('File extension must be either ".stl" or ".obj"')
957
+
958
+ mesh = convert_3d_geometry_to_mesh(geometry, **kwargs)
959
+ mesh.export(output_path)
@@ -11,6 +11,7 @@ from supervisely.volume_annotation.volume_figure import VolumeFigure
11
11
 
12
12
  from supervisely.project.project_meta import ProjectMeta
13
13
  from supervisely._utils import take_with_default
14
+ from supervisely.io.fs import file_exists
14
15
  from supervisely.video_annotation.key_id_map import KeyIdMap
15
16
  from supervisely.volume_annotation.slice import Slice
16
17
  from supervisely.volume_annotation.volume_tag_collection import VolumeTagCollection
@@ -30,7 +31,7 @@ from supervisely.volume_annotation.constants import (
30
31
  PLANES,
31
32
  SPATIAL_FIGURES,
32
33
  )
33
-
34
+ from supervisely.io.fs import get_file_name
34
35
  from supervisely.io.json import dump_json_file
35
36
 
36
37
 
@@ -484,7 +485,13 @@ class VolumeAnnotation:
484
485
  )
485
486
 
486
487
  @classmethod
487
- def from_json(cls, data: dict, project_meta: ProjectMeta, key_id_map: KeyIdMap = None):
488
+ def from_json(
489
+ cls,
490
+ data: dict,
491
+ project_meta: ProjectMeta,
492
+ key_id_map: KeyIdMap = None,
493
+ spatial_geometry_paths: Union[list, dict] = None,
494
+ ):
488
495
  """
489
496
  Convert a json dict to VolumeAnnotation.
490
497
 
@@ -494,6 +501,11 @@ class VolumeAnnotation:
494
501
  :type project_meta: ProjectMeta
495
502
  :param key_id_map: KeyIdMap object.
496
503
  :type key_id_map: KeyIdMap, optional
504
+ :param spatial_geometry_paths: Optional. Can be either:
505
+ - a list of file paths to spatial geometry files, where each file name should match either the figure's id or the hex value of its key,
506
+ - or a dict mapping figure ids (or keys) to their corresponding geometry file paths.
507
+ Used to load 3D geometry for spatial figures.
508
+ :type spatial_geometry_paths: list or dict, optional
497
509
  :return: VolumeAnnotation object
498
510
  :rtype: :class:`VolumeAnnotation<VolumeAnnotation>`
499
511
  :Usage example:
@@ -585,6 +597,31 @@ class VolumeAnnotation:
585
597
  slice_index=None,
586
598
  key_id_map=key_id_map,
587
599
  )
600
+ if spatial_geometry_paths:
601
+ figure_id = figure_json["id"]
602
+ if isinstance(spatial_geometry_paths, list):
603
+ spatial_geometry_paths = {
604
+ get_file_name(path): path for path in spatial_geometry_paths
605
+ }
606
+ geometry_path = spatial_geometry_paths.get(
607
+ figure.key().hex
608
+ ) or spatial_geometry_paths.get(str(figure_id))
609
+ elif isinstance(spatial_geometry_paths, dict):
610
+ geometry_path = spatial_geometry_paths.get(figure_id, None)
611
+ else:
612
+ raise ValueError(
613
+ f"spatial_geometry_paths should be either a list or a dict. Got: {type(spatial_geometry_paths)}"
614
+ )
615
+
616
+ if geometry_path is not None:
617
+ if not file_exists(geometry_path):
618
+ raise RuntimeError(
619
+ f"Geometry file {geometry_path} for figure {figure_id} does not exist."
620
+ )
621
+ mask3d = Mask3D.create_from_file(geometry_path)
622
+ mask3d.sly_id = figure_id
623
+ figure._set_3d_geometry(mask3d)
624
+
588
625
  spatial_figures.append(figure)
589
626
 
590
627
  return cls(
@@ -1,28 +1,30 @@
1
1
  # coding: utf-8
2
2
  from __future__ import annotations
3
+
3
4
  import uuid
4
- from typing import Union, Optional, Literal
5
- from numpy import ndarray
5
+ from typing import Literal, Optional, Union
6
6
  from uuid import UUID
7
- from supervisely.video_annotation.video_figure import VideoFigure
8
- from supervisely.video_annotation.key_id_map import KeyIdMap
9
- from supervisely.geometry.closed_surface_mesh import ClosedSurfaceMesh
10
- from supervisely.geometry.mask_3d import Mask3D
7
+
8
+ from numpy import ndarray
9
+
10
+ import supervisely.volume_annotation.constants as constants
11
+ from supervisely._utils import take_with_default
12
+ from supervisely.annotation.json_geometries_map import GET_GEOMETRY_FROM_STR
11
13
  from supervisely.api.module_api import ApiField
12
14
  from supervisely.geometry.any_geometry import AnyGeometry
13
- from supervisely.annotation.json_geometries_map import GET_GEOMETRY_FROM_STR
14
- from supervisely._utils import take_with_default
15
- from supervisely.volume_annotation.volume_object import VolumeObject
16
- from supervisely.geometry.geometry import Geometry
17
- import supervisely.volume_annotation.constants as constants
18
- from supervisely.volume_annotation.constants import ID, KEY, OBJECT_ID, OBJECT_KEY, META
15
+ from supervisely.geometry.closed_surface_mesh import ClosedSurfaceMesh
19
16
  from supervisely.geometry.constants import (
17
+ CLASS_ID,
18
+ CREATED_AT,
20
19
  LABELER_LOGIN,
21
20
  UPDATED_AT,
22
- CREATED_AT,
23
- CLASS_ID,
24
21
  )
25
-
22
+ from supervisely.geometry.geometry import Geometry
23
+ from supervisely.geometry.mask_3d import Mask3D
24
+ from supervisely.video_annotation.key_id_map import KeyIdMap
25
+ from supervisely.video_annotation.video_figure import VideoFigure
26
+ from supervisely.volume_annotation.constants import ID, KEY, META, OBJECT_ID, OBJECT_KEY
27
+ from supervisely.volume_annotation.volume_object import VolumeObject
26
28
  from supervisely.volume_annotation.volume_object_collection import (
27
29
  VolumeObjectCollection,
28
30
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: supervisely
3
- Version: 6.73.361
3
+ Version: 6.73.363
4
4
  Summary: Supervisely Python SDK.
5
5
  Home-page: https://github.com/supervisely/supervisely
6
6
  Author: Supervisely
@@ -1035,11 +1035,11 @@ supervisely/project/data_version.py,sha256=P5Lui6i64pYeJWmAdGJDv8GRXxjfpSSZ8zT_M
1035
1035
  supervisely/project/download.py,sha256=nhxID-kbsNTgIY9l1lnRuUlzKrsJw80X07jEElyl3sE,28466
1036
1036
  supervisely/project/pointcloud_episode_project.py,sha256=yiWdNBQiI6f1O9sr1pg8JHW6O-w3XUB1rikJNn3Oung,41866
1037
1037
  supervisely/project/pointcloud_project.py,sha256=Kx1Vaes-krwG3BiRRtHRLQxb9G5m5bTHPN9IzRqmNWo,49399
1038
- supervisely/project/project.py,sha256=k0eE6Jy9eDYO-WUbDK0a-IVA34VVWYRzMBVkPY9XdGw,235812
1038
+ supervisely/project/project.py,sha256=RokArUC17P7HXssoYXSKVCBo6DJvclwD-ozW7ysMWww,238002
1039
1039
  supervisely/project/project_meta.py,sha256=26s8IiHC5Pg8B1AQi6_CrsWteioJP2in00cRNe8QlW0,51423
1040
1040
  supervisely/project/project_settings.py,sha256=NLThzU_DCynOK6hkHhVdFyezwprn9UqlnrLDe_3qhkY,9347
1041
1041
  supervisely/project/project_type.py,sha256=7mQ7zg6r7Bm2oFn5aR8n_PeLqMmOaPZd6ph7Z8ZISTw,608
1042
- supervisely/project/readme_template.md,sha256=NKYEoJubNWLV_HmhVmdB6L4dneLqDkvl2b71xy5fc54,9150
1042
+ supervisely/project/readme_template.md,sha256=VovSn591tcpz2xiwGgErm34iGHVxuGxXGPX6-iDiS88,9251
1043
1043
  supervisely/project/upload.py,sha256=AjgHYgVZwUE25ygC5pqvFjdAladbyB8T78mlet5Qpho,3750
1044
1044
  supervisely/project/video_project.py,sha256=zAtB3YpW9tC9Tc3qfapbQ9O2nhAWU2wDjMuS5sepXqc,65297
1045
1045
  supervisely/project/volume_project.py,sha256=Kn9VEvWuKKZvL2nx6B6bjSvHuoZhAOxEc6DvPRexUco,22666
@@ -1075,13 +1075,13 @@ supervisely/volume/__init__.py,sha256=EBZBY_5mzabXzMUQh5akusIGd16XnX9n8J0jIi_JmW
1075
1075
  supervisely/volume/nrrd_encoder.py,sha256=1lqwwyqxEvctw1ysQ70x4xPSV1uy1g5YcH5CURwL7-c,4084
1076
1076
  supervisely/volume/nrrd_loader.py,sha256=_yqahKcqSRxunHZ5LtnUWIRA7UvIhPKOhAUwYijSGY4,9065
1077
1077
  supervisely/volume/stl_converter.py,sha256=WIMQgHO_u4JT58QdcMXcb_euF1BFhM7D52IVX_0QTxE,6285
1078
- supervisely/volume/volume.py,sha256=bUPrDQAr4ZIkSQMzpSWXjsHRqcXUq2Z2H6Fe1uLdYmw,25687
1078
+ supervisely/volume/volume.py,sha256=ekU8gYhSXrTvWISd_HJT7lwtQ9Uh5t7qgVcFwzJ2NOc,29273
1079
1079
  supervisely/volume_annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1080
1080
  supervisely/volume_annotation/constants.py,sha256=BdFIh56fy7vzLIjt0gH8xP01EIU-qgQIwbSHVUcABCU,569
1081
1081
  supervisely/volume_annotation/plane.py,sha256=wyezAcc8tLp38O44CwWY0wjdQxf3VjRdFLWooCrk-Nw,16301
1082
1082
  supervisely/volume_annotation/slice.py,sha256=9m3jtUYz4PYKV3rgbeh2ofDebkyg4TomNbkC6BwZ0lA,4635
1083
- supervisely/volume_annotation/volume_annotation.py,sha256=T-50ZmfhQDUtoXkSB9ur3LySCp9xZ1AmUT9KqjPy1DA,30179
1084
- supervisely/volume_annotation/volume_figure.py,sha256=3_X2drnt_zCGBLWPanW8_O-jM-tI9-34rSacUWqTflk,25329
1083
+ supervisely/volume_annotation/volume_annotation.py,sha256=pGu6n8_5JkFpir4HTVRf302gGD2EqJ96Gh4M0_236Qg,32047
1084
+ supervisely/volume_annotation/volume_figure.py,sha256=B4rXacAMM-eVPLZHQTBpT2USBv8Zh6eTzj0_e3tmuSA,25331
1085
1085
  supervisely/volume_annotation/volume_object.py,sha256=rWzOnycoSJ4-CvFgDOP_rPortU4CdcYR26txe5wJHNo,3577
1086
1086
  supervisely/volume_annotation/volume_object_collection.py,sha256=Tc4AovntgoFj5hpTLBv7pCQ3eL0BjorOVpOh2nAE_tA,5706
1087
1087
  supervisely/volume_annotation/volume_tag.py,sha256=N2eOhAlbRDVVdSVQ83dzg7URDGtb1xHjxL2g9BW6ljU,9488
@@ -1097,9 +1097,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
1097
1097
  supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
1098
1098
  supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
1099
1099
  supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
1100
- supervisely-6.73.361.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1101
- supervisely-6.73.361.dist-info/METADATA,sha256=ZGEe4t9l88XpSPZES9bz3rmND8dJK-rMzlsXosDmXBU,35151
1102
- supervisely-6.73.361.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1103
- supervisely-6.73.361.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1104
- supervisely-6.73.361.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1105
- supervisely-6.73.361.dist-info/RECORD,,
1100
+ supervisely-6.73.363.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1101
+ supervisely-6.73.363.dist-info/METADATA,sha256=6PAf_uEkpJWOi9CeWKDgUCmCGH7wEJeK7Gu41pIYqu8,35151
1102
+ supervisely-6.73.363.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1103
+ supervisely-6.73.363.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1104
+ supervisely-6.73.363.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1105
+ supervisely-6.73.363.dist-info/RECORD,,