├── .python-version ├── map.pgm ├── room.stl ├── map_2.pgm ├── map_3.pgm ├── pics ├── input_map.png └── output_sdf_world.png ├── map.yaml ├── map_2.yaml ├── map_3.yaml ├── .gitignore ├── pyproject.toml ├── readme.md ├── README.md ├── pgm_to_sdf.py ├── slam_world.sdf └── uv.lock /.python-version: -------------------------------------------------------------------------------- 1 | 3.13 2 | -------------------------------------------------------------------------------- /map.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arseni1919/Converter_PGM_to_SDF/HEAD/map.pgm -------------------------------------------------------------------------------- /room.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arseni1919/Converter_PGM_to_SDF/HEAD/room.stl -------------------------------------------------------------------------------- /map_2.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arseni1919/Converter_PGM_to_SDF/HEAD/map_2.pgm -------------------------------------------------------------------------------- /map_3.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arseni1919/Converter_PGM_to_SDF/HEAD/map_3.pgm -------------------------------------------------------------------------------- /pics/input_map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arseni1919/Converter_PGM_to_SDF/HEAD/pics/input_map.png -------------------------------------------------------------------------------- /pics/output_sdf_world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arseni1919/Converter_PGM_to_SDF/HEAD/pics/output_sdf_world.png -------------------------------------------------------------------------------- /map.yaml: -------------------------------------------------------------------------------- 1 | image: map.pgm 2 | mode: trinary 3 | resolution: 0.05 4 | origin: [-5.61, -3.15, 0] 5 | negate: 0 6 | occupied_thresh: 0.65 7 | free_thresh: 0.25 8 | -------------------------------------------------------------------------------- /map_2.yaml: -------------------------------------------------------------------------------- 1 | image: map_2.pgm 2 | mode: trinary 3 | resolution: 0.05 4 | origin: [-8.29, -8.64, 0] 5 | negate: 0 6 | occupied_thresh: 0.65 7 | free_thresh: 0.25 8 | -------------------------------------------------------------------------------- /map_3.yaml: -------------------------------------------------------------------------------- 1 | image: map_3.pgm 2 | mode: trinary 3 | resolution: 0.05 4 | origin: [-8.29, -8.64, 0] 5 | negate: 0 6 | occupied_thresh: 0.65 7 | free_thresh: 0.25 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Python-generated files 2 | __pycache__/ 3 | *.py[oc] 4 | build/ 5 | dist/ 6 | wheels/ 7 | *.egg-info 8 | 9 | # Virtual environments 10 | .venv 11 | .idea 12 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "converter-pgm-to-sdf" 3 | version = "0.1.0" 4 | description = "Add your description here" 5 | readme = "README.md" 6 | requires-python = ">=3.13" 7 | dependencies = [ 8 | "matplotlib>=3.10.3", 9 | "opencv-python>=4.12.0.88", 10 | "pillow>=11.3.0", 11 | "pyyaml>=6.0.2", 12 | "scikit-image>=0.25.2", 13 | "scipy>=1.16.1", 14 | ] 15 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "converter-pgm-to-sdf-implementation" 3 | version = "0.1.0" 4 | description = "Add your description here" 5 | requires-python = ">=3.12" 6 | dependencies = [ 7 | "matplotlib>=3.10.3", 8 | "numpy>=2.3.2", 9 | "opencv-python>=4.11.0.86", 10 | "pillow>=11.3.0", 11 | "pyyaml>=6.0.2", 12 | "scikit-image>=0.25.2", 13 | "scipy>=1.16.0", 14 | ] 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # :world_map: PGM to SDF Converter 2 | 3 | Convert 2D SLAM maps (PGM + YAML) into 3D Gazebo worlds (SDF format) for robot simulation. 4 | 5 | ## :package: Installation 6 | 7 | **No cloning needed!** Just download the single file: 8 | 9 | 1. Download [`pgm_to_sdf.py`](pgm_to_sdf.py) 10 | 2. Install dependencies (see below) 11 | 3. Run it! 12 | 13 | ## :rocket: Quick Start 14 | 15 | ```bash 16 | python pgm_to_sdf.py map.pgm map.yaml 17 | ``` 18 | 19 | This creates `slam_world.sdf` ready for Gazebo. 20 | 21 | ## :clipboard: Requirements 22 | 23 | ```bash 24 | pip install numpy PyYAML Pillow opencv-python scipy scikit-image 25 | ``` 26 | 27 | ## :dart: Usage 28 | 29 | ### Basic Usage 30 | ```bash 31 | python pgm_to_sdf.py your_map.pgm your_map.yaml 32 | ``` 33 | 34 | ### Custom Options 35 | ```bash 36 | python pgm_to_sdf.py map.pgm map.yaml -o my_world.sdf --height 3.0 --thickness 0.2 --threshold 100 37 | ``` 38 | 39 | ## :gear: Parameters 40 | 41 | | Parameter | Default | Description | 42 | |-----------|---------|-------------| 43 | | `--output` / `-o` | `slam_world.sdf` | Output SDF filename | 44 | | `--height` | `2.0` | Wall height in meters | 45 | | `--thickness` | `0.1` | Wall thickness in meters | 46 | | `--threshold` | `128` | Pixel threshold for wall detection | 47 | | `--sensitivity` | `1.0` | Line detection sensitivity (higher = detect more curved/short walls) | 48 | 49 | ## :wrench: How It Works 50 | 51 | 1. **Load Map** :inbox_tray: - Reads PGM image and YAML metadata 52 | 2. **Detect Lines** :mag: - Uses OpenCV Hough transform to find wall edges 53 | 3. **Scale to World** :earth_americas: - Converts pixel coordinates to real-world meters 54 | 4. **Generate Walls** :bricks: - Creates 3D wall boxes from detected lines 55 | 5. **Export SDF** :outbox_tray: - Outputs Gazebo-compatible world file 56 | 57 | ## :camera: Example: Input vs Output 58 | 59 | | Input (2D SLAM Map) | Output (3D Gazebo World) | 60 | |---------------------|--------------------------| 61 | | ![Input Map](pics/input_map.png) | ![Output SDF World](pics/output_sdf_world.png) | 62 | 63 | **Input YAML metadata:** 64 | ```yaml 65 | image: map_3.pgm 66 | mode: trinary 67 | resolution: 0.05 68 | origin: [-8.29, -8.64, 0] 69 | negate: 0 70 | occupied_thresh: 0.65 71 | free_thresh: 0.25 72 | ``` 73 | 74 | ## :file_folder: File Structure 75 | 76 | Your map files should look like: 77 | - `map_3.pgm` - Grayscale occupancy grid (black = walls, white = free space) 78 | - `map_3.yaml` - Metadata with resolution, origin, and other parameters 79 | 80 | ## :video_game: Using in Gazebo 81 | 82 | ```bash 83 | gz sim slam_world.sdf 84 | ``` 85 | 86 | The generated world includes: 87 | - :sunrise: Proper lighting 88 | - :office: 3D walls from your 2D map 89 | - :earth_americas: Ground plane 90 | - :zap: Physics simulation ready -------------------------------------------------------------------------------- /pgm_to_sdf.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import yaml # requires: pip install PyYAML 3 | from PIL import Image 4 | import xml.etree.ElementTree as ET 5 | from xml.dom import minidom 6 | import argparse 7 | import os 8 | from scipy import ndimage 9 | from scipy.ndimage import binary_opening, binary_closing, binary_erosion, binary_dilation 10 | from skimage import morphology, measure 11 | from skimage.feature import canny 12 | import cv2 13 | 14 | 15 | def load_map_data(pgm_file, yaml_file): 16 | """Load PGM image and YAML metadata""" 17 | # Load YAML metadata 18 | with open(yaml_file, 'r') as f: 19 | map_metadata = yaml.safe_load(f) 20 | 21 | # Load PGM image 22 | image = Image.open(pgm_file).convert('L') # Convert to grayscale 23 | map_array = np.array(image) 24 | 25 | return map_array, map_metadata 26 | 27 | 28 | def apply_noise_filtering(map_array, filter_config=None): 29 | """Apply noise filtering to clean up SLAM map artifacts""" 30 | if filter_config is None: 31 | filter_config = { 32 | 'remove_isolated_pixels': True, 33 | 'fill_small_gaps': True, 34 | 'smooth_edges': False, # Made more conservative 35 | 'remove_small_components': True, 36 | 'min_component_size': 1, # Much less aggressive - keep single pixels 37 | 'opening_iterations': 0, # Disable opening to preserve thin walls 38 | 'closing_iterations': 1, # Keep closing to fill small gaps 39 | 'edge_smooth_kernel_size': 3 40 | } 41 | 42 | # Debug: Check initial map statistics 43 | print(f"Map array shape: {map_array.shape}") 44 | print(f"Map array dtype: {map_array.dtype}") 45 | print(f"Map array min/max: {map_array.min()}/{map_array.max()}") 46 | unique_values = np.unique(map_array) 47 | print(f"Unique pixel values: {unique_values}") 48 | 49 | # Work with binary image (walls = 1, free space = 0) 50 | # Convert to binary: occupied pixels (< 128) become walls (1) 51 | binary_map = (map_array < 128).astype(np.uint8) 52 | original_wall_count = np.sum(binary_map) 53 | 54 | print(f"Original wall pixels: {original_wall_count}") 55 | 56 | # Safety check: If no walls detected, return original 57 | if original_wall_count == 0: 58 | print("WARNING: No wall pixels detected! Check your threshold value.") 59 | print("Returning original map without filtering.") 60 | return map_array 61 | 62 | # Safety check: If too many walls (likely inverted), warn user 63 | total_pixels = map_array.shape[0] * map_array.shape[1] 64 | wall_percentage = (original_wall_count / total_pixels) * 100 65 | print(f"Wall coverage: {wall_percentage:.1f}% of map") 66 | 67 | if wall_percentage > 80: 68 | print("WARNING: Very high wall coverage detected!") 69 | print("Your map might be inverted (walls=white instead of black)") 70 | print("Consider adjusting the threshold parameter.") 71 | 72 | # 1. Remove isolated pixels (salt noise) - Morphological Opening 73 | if filter_config['remove_isolated_pixels'] and filter_config['opening_iterations'] > 0: 74 | kernel = np.ones((3, 3), np.uint8) 75 | binary_map = binary_opening(binary_map, structure=kernel, 76 | iterations=filter_config['opening_iterations']) 77 | after_opening = np.sum(binary_map) 78 | print(f"After removing isolated pixels: {after_opening} ({original_wall_count - after_opening} removed)") 79 | else: 80 | after_opening = original_wall_count 81 | 82 | # 2. Fill small gaps in walls - Morphological Closing 83 | if filter_config['fill_small_gaps'] and filter_config['closing_iterations'] > 0: 84 | kernel = np.ones((3, 3), np.uint8) 85 | binary_map = binary_closing(binary_map, structure=kernel, 86 | iterations=filter_config['closing_iterations']) 87 | after_closing = np.sum(binary_map) 88 | print(f"After filling gaps: {after_closing} ({after_closing - after_opening} added)") 89 | else: 90 | after_closing = after_opening 91 | 92 | # 3. Remove small disconnected components 93 | if filter_config['remove_small_components']: 94 | # Label connected components 95 | labeled_map = measure.label(binary_map, connectivity=2) # 8-connectivity 96 | component_props = measure.regionprops(labeled_map) 97 | 98 | print(f"Found {len(component_props)} connected components") 99 | 100 | # Remove components smaller than threshold 101 | min_size = filter_config['min_component_size'] 102 | removed_components = 0 103 | for prop in component_props: 104 | if prop.area < min_size: 105 | binary_map[labeled_map == prop.label] = 0 106 | removed_components += 1 107 | 108 | after_component_removal = np.sum(binary_map) 109 | print(f"After removing {removed_components} small components (< {min_size} pixels): {after_component_removal}") 110 | else: 111 | after_component_removal = after_closing 112 | 113 | # 4. Smooth edges using morphological operations (disabled by default) 114 | if filter_config['smooth_edges']: 115 | kernel_size = filter_config['edge_smooth_kernel_size'] 116 | if kernel_size > 1: 117 | # Use diamond-shaped kernel for edge smoothing 118 | kernel = morphology.diamond(kernel_size // 2) 119 | 120 | # Light erosion followed by dilation to smooth edges 121 | smoothed = binary_erosion(binary_map, structure=kernel) 122 | smoothed = binary_dilation(smoothed, structure=kernel) 123 | binary_map = smoothed.astype(np.uint8) 124 | 125 | after_smoothing = np.sum(binary_map) 126 | print(f"After edge smoothing: {after_smoothing}") 127 | else: 128 | after_smoothing = after_component_removal 129 | else: 130 | after_smoothing = after_component_removal 131 | 132 | # Skip thin protrusion removal for now - it was too aggressive 133 | 134 | # Convert back to grayscale format (walls = 0, free space = 255) 135 | filtered_map = np.where(binary_map == 1, 0, 255).astype(np.uint8) 136 | 137 | final_wall_count = np.sum(binary_map) 138 | 139 | # Safety check: If we removed too many walls, warn user 140 | if final_wall_count == 0: 141 | print("ERROR: All walls were removed by filtering! Returning original map.") 142 | return map_array 143 | 144 | if final_wall_count < original_wall_count * 0.1: # Lost more than 90% 145 | print("WARNING: Filtering removed more than 90% of walls!") 146 | print("Consider using --no-filter or adjusting filter parameters.") 147 | 148 | reduction_percent = ((original_wall_count - final_wall_count) / original_wall_count) * 100 149 | print( 150 | f"Noise filtering complete: {original_wall_count} → {final_wall_count} pixels ({reduction_percent:.1f}% reduction)") 151 | 152 | return filtered_map 153 | 154 | 155 | def simple_line_detection(map_array, threshold=128, sensitivity=1.0): 156 | """Line detection with adjustable sensitivity for detecting curved/short walls""" 157 | print(f"Line detection starting (sensitivity: {sensitivity})...") 158 | 159 | # Create binary image: walls are black (< threshold) 160 | binary = (map_array < threshold).astype(np.uint8) * 255 161 | print(f"Binary image created: {binary.shape}") 162 | 163 | # Simple edge detection 164 | edges = cv2.Canny(binary, 50, 150) 165 | 166 | # Adjust Hough parameters based on sensitivity 167 | # Higher sensitivity = detect more/shorter/weaker lines 168 | base_hough_threshold = 50 169 | base_min_length = 20 170 | base_max_gap = 10 171 | 172 | hough_threshold = max(1, int(base_hough_threshold / sensitivity)) 173 | min_line_length = max(1, int(base_min_length / sensitivity)) 174 | max_gap = int(base_max_gap * sensitivity) 175 | 176 | print(f"Hough parameters: threshold={hough_threshold}, minLength={min_line_length}, maxGap={max_gap}") 177 | 178 | # Hough line detection with sensitivity-adjusted parameters 179 | lines = cv2.HoughLinesP( 180 | edges, 181 | rho=1, # Distance resolution in pixels 182 | theta=np.pi/180, # Angle resolution in radians 183 | threshold=hough_threshold, # Minimum number of votes (lower = more sensitive) 184 | minLineLength=min_line_length, # Minimum line length (lower = detect shorter lines) 185 | maxLineGap=max_gap # Maximum gap between segments (higher = connect more) 186 | ) 187 | 188 | # Convert to simple line format 189 | line_segments = [] 190 | if lines is not None: 191 | for line in lines: 192 | x1, y1, x2, y2 = line[0] 193 | line_segments.append({ 194 | 'x1': x1, 'y1': y1, 195 | 'x2': x2, 'y2': y2, 196 | 'length': np.sqrt((x2-x1)**2 + (y2-y1)**2) 197 | }) 198 | 199 | print(f"Found {len(line_segments)} line segments") 200 | return line_segments 201 | 202 | 203 | def scale_lines_to_world(line_segments, resolution, origin, map_height): 204 | """Convert line coordinates from image pixels to world coordinates""" 205 | world_lines = [] 206 | 207 | for line in line_segments: 208 | # Convert pixel coordinates to world coordinates 209 | # Fix Y-axis flip: PGM origin is top-left, world origin is bottom-left 210 | world_x1 = origin[0] + line['x1'] * resolution 211 | world_y1 = origin[1] + (map_height - line['y1']) * resolution 212 | world_x2 = origin[0] + line['x2'] * resolution 213 | world_y2 = origin[1] + (map_height - line['y2']) * resolution 214 | 215 | world_lines.append({ 216 | 'x1': world_x1, 'y1': world_y1, 217 | 'x2': world_x2, 'y2': world_y2, 218 | 'length': np.sqrt((world_x2-world_x1)**2 + (world_y2-world_y1)**2) 219 | }) 220 | 221 | print(f"Scaled {len(world_lines)} lines to world coordinates") 222 | return world_lines 223 | 224 | 225 | def create_walls_from_lines(world_lines, wall_height=2.0, wall_thickness=0.1): 226 | """Create wall boxes from world coordinate lines""" 227 | walls = [] 228 | 229 | for i, line in enumerate(world_lines): 230 | # Calculate center point of the line 231 | center_x = (line['x1'] + line['x2']) / 2.0 232 | center_y = (line['y1'] + line['y2']) / 2.0 233 | center_z = wall_height / 2.0 234 | 235 | # Calculate line length and angle 236 | length = line['length'] 237 | angle = np.arctan2(line['y2'] - line['y1'], line['x2'] - line['x1']) 238 | 239 | # Create wall box 240 | wall = { 241 | 'name': f'wall_{i}', 242 | 'x': center_x, 243 | 'y': center_y, 244 | 'z': center_z, 245 | 'length': length, # Along the line 246 | 'width': wall_thickness, # Perpendicular to line 247 | 'height': wall_height, # Vertical 248 | 'yaw': angle # Rotation around Z-axis 249 | } 250 | walls.append(wall) 251 | 252 | print(f"Created {len(walls)} wall boxes") 253 | return walls 254 | 255 | 256 | def create_simple_sdf(walls, world_name="slam_world"): 257 | """Create simple SDF world with walls""" 258 | 259 | # Create root SDF element 260 | sdf = ET.Element("sdf", version="1.6") 261 | world = ET.SubElement(sdf, "world", name=world_name) 262 | 263 | # Add basic lighting 264 | light = ET.SubElement(world, "light", name="sun", type="directional") 265 | ET.SubElement(light, "pose").text = "0 0 10 0 0 0" 266 | ET.SubElement(light, "diffuse").text = "0.8 0.8 0.8 1" 267 | ET.SubElement(light, "direction").text = "-0.5 0.1 -0.9" 268 | 269 | # Add ground plane 270 | ground = ET.SubElement(world, "model", name="ground_plane") 271 | ET.SubElement(ground, "static").text = "true" 272 | ground_link = ET.SubElement(ground, "link", name="link") 273 | 274 | # Ground collision 275 | ground_coll = ET.SubElement(ground_link, "collision", name="collision") 276 | ground_geom = ET.SubElement(ground_coll, "geometry") 277 | ground_plane = ET.SubElement(ground_geom, "plane") 278 | ET.SubElement(ground_plane, "normal").text = "0 0 1" 279 | ET.SubElement(ground_plane, "size").text = "100 100" 280 | 281 | # Ground visual 282 | ground_vis = ET.SubElement(ground_link, "visual", name="visual") 283 | ground_vis_geom = ET.SubElement(ground_vis, "geometry") 284 | ground_vis_plane = ET.SubElement(ground_vis_geom, "plane") 285 | ET.SubElement(ground_vis_plane, "normal").text = "0 0 1" 286 | ET.SubElement(ground_vis_plane, "size").text = "100 100" 287 | 288 | # Ground material 289 | ground_material = ET.SubElement(ground_vis, "material") 290 | ET.SubElement(ground_material, "ambient").text = "0.8 0.8 0.8 1" 291 | ET.SubElement(ground_material, "diffuse").text = "0.8 0.8 0.8 1" 292 | ET.SubElement(ground_material, "specular").text = "0.8 0.8 0.8 1" 293 | 294 | # Add each wall 295 | for wall in walls: 296 | wall_model = ET.SubElement(world, "model", name=wall['name']) 297 | ET.SubElement(wall_model, "static").text = "true" 298 | ET.SubElement(wall_model, "pose").text = f"{wall['x']} {wall['y']} {wall['z']} 0 0 {wall['yaw']}" 299 | 300 | wall_link = ET.SubElement(wall_model, "link", name="link") 301 | 302 | # Collision 303 | wall_coll = ET.SubElement(wall_link, "collision", name="collision") 304 | coll_geom = ET.SubElement(wall_coll, "geometry") 305 | coll_box = ET.SubElement(coll_geom, "box") 306 | ET.SubElement(coll_box, "size").text = f"{wall['length']} {wall['width']} {wall['height']}" 307 | 308 | # Visual 309 | wall_vis = ET.SubElement(wall_link, "visual", name="visual") 310 | vis_geom = ET.SubElement(wall_vis, "geometry") 311 | vis_box = ET.SubElement(vis_geom, "box") 312 | ET.SubElement(vis_box, "size").text = f"{wall['length']} {wall['width']} {wall['height']}" 313 | 314 | # Material 315 | material = ET.SubElement(wall_vis, "material") 316 | ET.SubElement(material, "ambient").text = "0.5 0.5 0.5 1" 317 | ET.SubElement(material, "diffuse").text = "0.7 0.7 0.7 1" 318 | 319 | return sdf 320 | 321 | 322 | def merge_collinear_segments(segments, angle_tolerance=5, distance_tolerance=3): 323 | """Merge collinear and adjacent line segments into longer straight lines""" 324 | if not segments: 325 | return [] 326 | 327 | # Convert angle tolerance to radians 328 | angle_tol_rad = np.radians(angle_tolerance) 329 | 330 | merged = [] 331 | used = set() 332 | 333 | for i, seg1 in enumerate(segments): 334 | if i in used: 335 | continue 336 | 337 | # Start with current segment 338 | current_seg = { 339 | 'start': seg1['start'], 340 | 'end': seg1['end'], 341 | 'length': seg1['length'], 342 | 'angle': seg1['angle'] 343 | } 344 | used.add(i) 345 | 346 | # Try to extend this segment by merging with others 347 | extended = True 348 | while extended: 349 | extended = False 350 | best_merge = None 351 | best_j = None 352 | 353 | for j, seg2 in enumerate(segments): 354 | if j in used: 355 | continue 356 | 357 | # Check if segments can be merged (similar angle and close/touching) 358 | angle_diff = abs(current_seg['angle'] - seg2['angle']) 359 | angle_diff = min(angle_diff, np.pi - angle_diff) # Handle wraparound 360 | 361 | if angle_diff <= angle_tol_rad: 362 | # Check if segments are close enough to merge 363 | merge_info = can_merge_segments(current_seg, seg2, distance_tolerance) 364 | if merge_info: 365 | best_merge = merge_info 366 | best_j = j 367 | extended = True 368 | break 369 | 370 | if extended and best_j is not None: 371 | # Merge the best candidate 372 | current_seg = best_merge 373 | used.add(best_j) 374 | 375 | merged.append(current_seg) 376 | 377 | return merged 378 | 379 | 380 | def can_merge_segments(seg1, seg2, distance_tolerance): 381 | """Check if two segments can be merged and return merged segment if possible""" 382 | 383 | def distance_point_to_point(p1, p2): 384 | return np.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2) 385 | 386 | # Get all four endpoints 387 | points = [seg1['start'], seg1['end'], seg2['start'], seg2['end']] 388 | 389 | # Find the two points that are furthest apart (these will be the new endpoints) 390 | max_dist = 0 391 | best_endpoints = None 392 | 393 | for i in range(4): 394 | for j in range(i+1, 4): 395 | dist = distance_point_to_point(points[i], points[j]) 396 | if dist > max_dist: 397 | max_dist = dist 398 | best_endpoints = (points[i], points[j]) 399 | 400 | if best_endpoints is None: 401 | return None 402 | 403 | # Check if segments are close enough (endpoints should be close to each other) 404 | min_endpoint_dist = float('inf') 405 | for p1 in [seg1['start'], seg1['end']]: 406 | for p2 in [seg2['start'], seg2['end']]: 407 | dist = distance_point_to_point(p1, p2) 408 | min_endpoint_dist = min(min_endpoint_dist, dist) 409 | 410 | if min_endpoint_dist > distance_tolerance: 411 | return None 412 | 413 | # Create merged segment 414 | start, end = best_endpoints 415 | length = distance_point_to_point(start, end) 416 | angle = np.arctan2(end[1] - start[1], end[0] - start[0]) 417 | 418 | return { 419 | 'start': start, 420 | 'end': end, 421 | 'length': length, 422 | 'angle': angle 423 | } 424 | 425 | 426 | def extract_walls(map_array, threshold=128, apply_filtering=True, filter_config=None): 427 | """Extract wall positions from the map array with optional noise filtering (legacy)""" 428 | 429 | # Apply noise filtering if requested 430 | if apply_filtering: 431 | print("Applying noise filtering...") 432 | map_array = apply_noise_filtering(map_array, filter_config) 433 | 434 | # Find all occupied pixels (walls) 435 | wall_pixels = np.where(map_array < threshold) 436 | wall_positions = list(zip(wall_pixels[1], wall_pixels[0])) # (x, y) format 437 | 438 | return wall_positions 439 | 440 | 441 | def find_rectangular_walls(wall_positions): 442 | """Find rectangular wall segments from individual wall pixels""" 443 | if not wall_positions: 444 | return [] 445 | 446 | # Convert to set for O(1) lookup 447 | wall_set = set(wall_positions) 448 | processed = set() 449 | rectangles = [] 450 | 451 | for x, y in wall_positions: 452 | if (x, y) in processed: 453 | continue 454 | 455 | # Try to grow a rectangle starting from this pixel 456 | # First, find the maximum width (horizontal extent) 457 | max_width = 1 458 | while (x + max_width, y) in wall_set: 459 | max_width += 1 460 | 461 | # For each possible width, find the maximum height 462 | best_rect = {'x': x, 'y': y, 'width': 1, 'height': 1} 463 | best_area = 1 464 | 465 | for width in range(1, max_width + 1): 466 | # Check if we can extend vertically 467 | height = 1 468 | while height <= 1000: # reasonable limit 469 | # Check if all pixels in this row exist 470 | valid_row = True 471 | for dx in range(width): 472 | if (x + dx, y + height) not in wall_set: 473 | valid_row = False 474 | break 475 | 476 | if not valid_row: 477 | break 478 | height += 1 479 | 480 | area = width * height 481 | if area > best_area: 482 | best_area = area 483 | best_rect = {'x': x, 'y': y, 'width': width, 'height': height} 484 | 485 | # Mark all pixels in this rectangle as processed 486 | for dx in range(best_rect['width']): 487 | for dy in range(best_rect['height']): 488 | processed.add((x + dx, y + dy)) 489 | 490 | rectangles.append(best_rect) 491 | 492 | return rectangles 493 | 494 | 495 | def merge_adjacent_pixels(wall_positions): 496 | """Merge adjacent wall pixels into larger rectangular segments""" 497 | if not wall_positions: 498 | return [] 499 | 500 | # Convert list to numpy array for easier processing 501 | wall_array = np.array(wall_positions) 502 | 503 | # Create a binary image for processing 504 | if len(wall_array) == 0: 505 | return [] 506 | 507 | min_x, min_y = wall_array.min(axis=0) 508 | max_x, max_y = wall_array.max(axis=0) 509 | 510 | # Create binary image 511 | img_width = max_x - min_x + 3 # +3 for padding 512 | img_height = max_y - min_y + 3 513 | binary_img = np.zeros((img_height, img_width), dtype=np.uint8) 514 | 515 | # Fill in wall pixels (offset by 1 for padding) 516 | for x, y in wall_positions: 517 | binary_img[y - min_y + 1, x - min_x + 1] = 1 518 | 519 | # Find rectangles using a greedy approach 520 | rectangles = [] 521 | processed = np.zeros_like(binary_img, dtype=bool) 522 | 523 | for y in range(img_height): 524 | for x in range(img_width): 525 | if binary_img[y, x] == 1 and not processed[y, x]: 526 | # Find the largest rectangle starting from this point 527 | rect = find_largest_rectangle(binary_img, processed, x, y) 528 | if rect: 529 | # Convert back to original coordinates 530 | rect['x'] += min_x - 1 531 | rect['y'] += min_y - 1 532 | rectangles.append(rect) 533 | 534 | return rectangles 535 | 536 | 537 | def find_largest_rectangle(binary_img, processed, start_x, start_y): 538 | """Find the largest rectangle starting from a given point""" 539 | height, width = binary_img.shape 540 | 541 | if processed[start_y, start_x] or binary_img[start_y, start_x] == 0: 542 | return None 543 | 544 | # Find maximum width for the first row 545 | max_width = 0 546 | for x in range(start_x, width): 547 | if binary_img[start_y, x] == 1 and not processed[start_y, x]: 548 | max_width += 1 549 | else: 550 | break 551 | 552 | if max_width == 0: 553 | return None 554 | 555 | # Find the maximum height for each possible width 556 | best_rect = {'x': start_x, 'y': start_y, 'width': 1, 'height': 1} 557 | best_area = 1 558 | 559 | for w in range(1, max_width + 1): 560 | h = 1 561 | # Extend downward while possible 562 | while start_y + h < height: 563 | # Check if the entire row is available 564 | valid_row = True 565 | for x in range(start_x, start_x + w): 566 | if (binary_img[start_y + h, x] == 0 or 567 | processed[start_y + h, x]): 568 | valid_row = False 569 | break 570 | 571 | if valid_row: 572 | h += 1 573 | else: 574 | break 575 | 576 | area = w * h 577 | if area > best_area: 578 | best_area = area 579 | best_rect = {'x': start_x, 'y': start_y, 'width': w, 'height': h} 580 | 581 | # Mark the rectangle as processed 582 | for y in range(best_rect['y'], best_rect['y'] + best_rect['height']): 583 | for x in range(best_rect['x'], best_rect['x'] + best_rect['width']): 584 | processed[y, x] = True 585 | 586 | return best_rect 587 | 588 | 589 | def create_wall_boxes_from_segments(line_segments, resolution, origin, wall_height=2.0, wall_thickness=0.1, map_width=None, map_height=None): 590 | """Create wall boxes from line segments""" 591 | if not line_segments: 592 | return [] 593 | 594 | walls = [] 595 | 596 | for i, segment in enumerate(line_segments): 597 | x1, y1 = segment['start'] 598 | x2, y2 = segment['end'] 599 | 600 | # Calculate center point 601 | center_x = (x1 + x2) / 2.0 602 | center_y = (y1 + y2) / 2.0 603 | 604 | # Convert to world coordinates (flip Y-axis to fix 180-degree rotation) 605 | if map_height is not None: 606 | # Flip Y coordinate to correct orientation (PGM origin top-left -> SDF origin bottom-left) 607 | world_x = origin[0] + center_x * resolution 608 | world_y = origin[1] + (map_height - center_y) * resolution 609 | else: 610 | # Fallback to original coordinates 611 | world_x = origin[0] + center_x * resolution 612 | world_y = origin[1] + center_y * resolution 613 | 614 | # Calculate length and angle 615 | length = segment['length'] * resolution 616 | angle = np.arctan2(y2 - y1, x2 - x1) 617 | 618 | # Create wall box 619 | walls.append({ 620 | 'x': world_x, 621 | 'y': world_y, 622 | 'z': wall_height / 2, 623 | 'width': length, 624 | 'length': wall_thickness, # Thickness of the wall 625 | 'height': wall_height, 626 | 'angle': angle, 627 | 'segment_id': i 628 | }) 629 | 630 | print(f"Created {len(walls)} wall boxes from line segments") 631 | return walls 632 | 633 | def create_wall_boxes(wall_positions, resolution, origin, wall_height=2.0, merge_adjacent=True): 634 | """Create wall boxes from wall positions (legacy method)""" 635 | if not wall_positions: 636 | return [] 637 | 638 | walls = [] 639 | 640 | if merge_adjacent: 641 | print("Merging adjacent wall pixels...") 642 | rectangles = merge_adjacent_pixels(wall_positions) 643 | print(f"Merged {len(wall_positions)} pixels into {len(rectangles)} rectangles") 644 | 645 | for rect in rectangles: 646 | # Calculate center position and size in world coordinates 647 | center_x = rect['x'] + rect['width'] / 2.0 648 | center_y = rect['y'] + rect['height'] / 2.0 649 | 650 | world_x = origin[0] + center_x * resolution 651 | world_y = origin[1] + center_y * resolution 652 | 653 | walls.append({ 654 | 'x': world_x, 655 | 'y': world_y, 656 | 'z': wall_height / 2, 657 | 'width': rect['width'] * resolution, 658 | 'length': rect['height'] * resolution, 659 | 'height': wall_height 660 | }) 661 | else: 662 | # Create individual boxes for each wall pixel 663 | for x, y in wall_positions: 664 | world_x = origin[0] + x * resolution 665 | world_y = origin[1] + y * resolution 666 | 667 | walls.append({ 668 | 'x': world_x, 669 | 'y': world_y, 670 | 'z': wall_height / 2, 671 | 'width': resolution, 672 | 'length': resolution, 673 | 'height': wall_height 674 | }) 675 | 676 | return walls 677 | 678 | 679 | def create_sdf_world(walls, world_name="slam_world"): 680 | """Create SDF XML structure""" 681 | # Create root SDF element 682 | sdf = ET.Element("sdf", version="1.6") 683 | 684 | # Create world element 685 | world = ET.SubElement(sdf, "world", name=world_name) 686 | 687 | # Add basic world properties 688 | # Physics 689 | physics = ET.SubElement(world, "physics", name="default_physics", default="0", type="ode") 690 | ET.SubElement(physics, "max_step_size").text = "0.001" 691 | ET.SubElement(physics, "real_time_factor").text = "1" 692 | ET.SubElement(physics, "real_time_update_rate").text = "1000" 693 | 694 | # Gravity 695 | ET.SubElement(world, "gravity").text = "0 0 -9.8" 696 | 697 | # Scene 698 | scene = ET.SubElement(world, "scene") 699 | ET.SubElement(scene, "ambient").text = "0.4 0.4 0.4 1" 700 | ET.SubElement(scene, "background").text = "0.7 0.7 0.7 1" 701 | ET.SubElement(scene, "shadows").text = "true" 702 | 703 | # Add sun light 704 | light = ET.SubElement(world, "light", name="sun", type="directional") 705 | ET.SubElement(light, "cast_shadows").text = "1" 706 | ET.SubElement(light, "pose").text = "0 0 10 0 0 0" 707 | ET.SubElement(light, "diffuse").text = "0.8 0.8 0.8 1" 708 | ET.SubElement(light, "specular").text = "0.2 0.2 0.2 1" 709 | ET.SubElement(light, "attenuation").text = "1 0.0 0.0" 710 | ET.SubElement(light, "direction").text = "-0.5 0.1 -0.9" 711 | 712 | # Add ground plane 713 | ground_model = ET.SubElement(world, "model", name="ground_plane") 714 | ET.SubElement(ground_model, "static").text = "true" 715 | ground_link = ET.SubElement(ground_model, "link", name="link") 716 | ground_collision = ET.SubElement(ground_link, "collision", name="collision") 717 | ground_geom = ET.SubElement(ground_collision, "geometry") 718 | ground_plane = ET.SubElement(ground_geom, "plane") 719 | ET.SubElement(ground_plane, "normal").text = "0 0 1" 720 | ET.SubElement(ground_plane, "size").text = "100 100" 721 | 722 | ground_visual = ET.SubElement(ground_link, "visual", name="visual") 723 | ground_vis_geom = ET.SubElement(ground_visual, "geometry") 724 | ground_vis_plane = ET.SubElement(ground_vis_geom, "plane") 725 | ET.SubElement(ground_vis_plane, "normal").text = "0 0 1" 726 | ET.SubElement(ground_vis_plane, "size").text = "100 100" 727 | 728 | ground_material = ET.SubElement(ground_visual, "material") 729 | ET.SubElement(ground_material, "ambient").text = "0.8 0.8 0.8 1" 730 | ET.SubElement(ground_material, "diffuse").text = "0.8 0.8 0.8 1" 731 | ET.SubElement(ground_material, "specular").text = "0.8 0.8 0.8 1" 732 | 733 | # Add wall models 734 | for i, wall in enumerate(walls): 735 | wall_model = ET.SubElement(world, "model", name=f"wall_{i}") 736 | ET.SubElement(wall_model, "static").text = "true" 737 | 738 | # Handle rotation if angle is specified 739 | if 'angle' in wall: 740 | pose_str = f"{wall['x']} {wall['y']} {wall['z']} 0 0 {wall['angle']}" 741 | else: 742 | pose_str = f"{wall['x']} {wall['y']} {wall['z']} 0 0 0" 743 | 744 | ET.SubElement(wall_model, "pose").text = pose_str 745 | 746 | wall_link = ET.SubElement(wall_model, "link", name="link") 747 | 748 | # Collision 749 | wall_collision = ET.SubElement(wall_link, "collision", name="collision") 750 | coll_geometry = ET.SubElement(wall_collision, "geometry") 751 | coll_box = ET.SubElement(coll_geometry, "box") 752 | ET.SubElement(coll_box, "size").text = f"{wall['width']} {wall['length']} {wall['height']}" 753 | 754 | # Visual 755 | wall_visual = ET.SubElement(wall_link, "visual", name="visual") 756 | vis_geometry = ET.SubElement(wall_visual, "geometry") 757 | vis_box = ET.SubElement(vis_geometry, "box") 758 | ET.SubElement(vis_box, "size").text = f"{wall['width']} {wall['length']} {wall['height']}" 759 | 760 | # Material 761 | wall_material = ET.SubElement(wall_visual, "material") 762 | ET.SubElement(wall_material, "ambient").text = "0.5 0.5 0.5 1" 763 | ET.SubElement(wall_material, "diffuse").text = "0.7 0.7 0.7 1" 764 | ET.SubElement(wall_material, "specular").text = "0.1 0.1 0.1 1" 765 | 766 | return sdf 767 | 768 | 769 | def simple_pgm_to_sdf(pgm_file, yaml_file, output_sdf, wall_height=2.0, wall_thickness=0.1, threshold=128, sensitivity=1.0): 770 | """Simple, clean conversion from PGM/YAML to SDF""" 771 | print(f"Simple conversion: {pgm_file} + {yaml_file} -> {output_sdf}") 772 | 773 | # 1. Load map data 774 | map_array, map_metadata = load_map_data(pgm_file, yaml_file) 775 | print(f"Map: {map_array.shape}, Resolution: {map_metadata['resolution']}, Origin: {map_metadata['origin']}") 776 | 777 | # 2. Detect lines from image with sensitivity control 778 | line_segments = simple_line_detection(map_array, threshold, sensitivity) 779 | 780 | # 3. Scale lines to world coordinates 781 | world_lines = scale_lines_to_world( 782 | line_segments, 783 | map_metadata['resolution'], 784 | map_metadata['origin'], 785 | map_array.shape[0] # map height for Y-axis flip 786 | ) 787 | 788 | # 4. Create wall boxes from lines 789 | walls = create_walls_from_lines(world_lines, wall_height, wall_thickness) 790 | 791 | # 5. Generate SDF 792 | sdf_root = create_simple_sdf(walls) 793 | 794 | # 6. Save to file 795 | rough_string = ET.tostring(sdf_root, 'unicode') 796 | reparsed = minidom.parseString(rough_string) 797 | pretty_xml = reparsed.toprettyxml(indent=" ") 798 | pretty_xml = '\n'.join([line for line in pretty_xml.split('\n') if line.strip()]) 799 | 800 | with open(output_sdf, 'w') as f: 801 | f.write(pretty_xml) 802 | 803 | print(f"Simple conversion complete: {output_sdf}") 804 | return output_sdf 805 | 806 | 807 | def main(): 808 | parser = argparse.ArgumentParser(description='Simple PGM/YAML to SDF converter') 809 | parser.add_argument('pgm_file', help='Path to PGM map file') 810 | parser.add_argument('yaml_file', help='Path to YAML metadata file') 811 | parser.add_argument('-o', '--output', default='slam_world.sdf', help='Output SDF file') 812 | parser.add_argument('--height', type=float, default=2.0, help='Wall height (default: 2.0m)') 813 | parser.add_argument('--thickness', type=float, default=0.1, help='Wall thickness (default: 0.1m)') 814 | parser.add_argument('--threshold', type=int, default=128, help='Wall threshold (default: 128)') 815 | parser.add_argument('--sensitivity', type=float, default=1.0, help='Line detection sensitivity (default: 1.0, higher = detect more curved/short walls)') 816 | 817 | args = parser.parse_args() 818 | 819 | # Check input files 820 | if not os.path.exists(args.pgm_file): 821 | print(f"Error: {args.pgm_file} not found") 822 | return 823 | if not os.path.exists(args.yaml_file): 824 | print(f"Error: {args.yaml_file} not found") 825 | return 826 | 827 | try: 828 | # Simple conversion 829 | simple_pgm_to_sdf( 830 | args.pgm_file, 831 | args.yaml_file, 832 | args.output, 833 | args.height, 834 | args.thickness, 835 | args.threshold, 836 | args.sensitivity 837 | ) 838 | print("Success!") 839 | 840 | except Exception as e: 841 | print(f"Error: {e}") 842 | import traceback 843 | traceback.print_exc() 844 | 845 | 846 | if __name__ == "__main__": 847 | main() 848 | -------------------------------------------------------------------------------- /slam_world.sdf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 0 0 10 0 0 0 6 | 0.8 0.8 0.8 1 7 | -0.5 0.1 -0.9 8 | 9 | 10 | true 11 | 12 | 13 | 14 | 15 | 0 0 1 16 | 100 100 17 | 18 | 19 | 20 | 21 | 22 | 23 | 0 0 1 24 | 100 100 25 | 26 | 27 | 28 | 0.8 0.8 0.8 1 29 | 0.8 0.8 0.8 1 30 | 0.8 0.8 0.8 1 31 | 32 | 33 | 34 | 35 | 36 | true 37 | 7.635000000000002 7.485 1.0 0 0 -0.22796707182150797 38 | 39 | 40 | 41 | 42 | 6.4159956359087404 0.1 2.0 43 | 44 | 45 | 46 | 47 | 48 | 49 | 6.4159956359087404 0.1 2.0 50 | 51 | 52 | 53 | 0.5 0.5 0.5 1 54 | 0.7 0.7 0.7 1 55 | 56 | 57 | 58 | 59 | 60 | true 61 | 9.410000000000002 6.76 1.0 0 0 -0.21406068356382144 62 | 63 | 64 | 65 | 66 | 2.3537204591879646 0.1 2.0 67 | 68 | 69 | 70 | 71 | 72 | 73 | 2.3537204591879646 0.1 2.0 74 | 75 | 76 | 77 | 0.5 0.5 0.5 1 78 | 0.7 0.7 0.7 1 79 | 80 | 81 | 82 | 83 | 84 | true 85 | 1.160000000000001 -5.34 1.0 0 0 1.2860658882721843 86 | 87 | 88 | 89 | 90 | 4.272001872658766 0.1 2.0 91 | 92 | 93 | 94 | 95 | 96 | 97 | 4.272001872658766 0.1 2.0 98 | 99 | 100 | 101 | 0.5 0.5 0.5 1 102 | 0.7 0.7 0.7 1 103 | 104 | 105 | 106 | 107 | 108 | true 109 | -4.1899999999999995 -6.19 1.0 0 0 1.2882413743253092 110 | 111 | 112 | 113 | 114 | 3.228002478313794 0.1 2.0 115 | 116 | 117 | 118 | 119 | 120 | 121 | 3.228002478313794 0.1 2.0 122 | 123 | 124 | 125 | 0.5 0.5 0.5 1 126 | 0.7 0.7 0.7 1 127 | 128 | 129 | 130 | 131 | 132 | true 133 | 12.010000000000003 5.91 1.0 0 0 -0.24497866312686387 134 | 135 | 136 | 137 | 138 | 2.886173937932363 0.1 2.0 139 | 140 | 141 | 142 | 143 | 144 | 145 | 2.886173937932363 0.1 2.0 146 | 147 | 148 | 149 | 0.5 0.5 0.5 1 150 | 0.7 0.7 0.7 1 151 | 152 | 153 | 154 | 155 | 156 | true 157 | 1.1850000000000014 -6.590000000000001 1.0 0 0 1.3258176636680328 158 | 159 | 160 | 161 | 162 | 1.4430869689661816 0.1 2.0 163 | 164 | 165 | 166 | 167 | 168 | 169 | 1.4430869689661816 0.1 2.0 170 | 171 | 172 | 173 | 0.5 0.5 0.5 1 174 | 0.7 0.7 0.7 1 175 | 176 | 177 | 178 | 179 | 180 | true 181 | -3.9149999999999987 8.735000000000001 1.0 0 0 1.308676485529424 182 | 183 | 184 | 185 | 186 | 2.122498527679113 0.1 2.0 187 | 188 | 189 | 190 | 191 | 192 | 193 | 2.122498527679113 0.1 2.0 194 | 195 | 196 | 197 | 0.5 0.5 0.5 1 198 | 0.7 0.7 0.7 1 199 | 200 | 201 | 202 | 203 | 204 | true 205 | -6.539999999999999 -2.215 1.0 0 0 1.3101939350475553 206 | 207 | 208 | 209 | 210 | 2.328626204439004 0.1 2.0 211 | 212 | 213 | 214 | 215 | 216 | 217 | 2.328626204439004 0.1 2.0 218 | 219 | 220 | 221 | 0.5 0.5 0.5 1 222 | 0.7 0.7 0.7 1 223 | 224 | 225 | 226 | 227 | 228 | true 229 | -1.4899999999999993 9.56 1.0 0 0 -0.25255427577805983 230 | 231 | 232 | 233 | 234 | 3.2015621187164243 0.1 2.0 235 | 236 | 237 | 238 | 239 | 240 | 241 | 3.2015621187164243 0.1 2.0 242 | 243 | 244 | 245 | 0.5 0.5 0.5 1 246 | 0.7 0.7 0.7 1 247 | 248 | 249 | 250 | 251 | 252 | true 253 | -4.889999999999999 -7.69 1.0 0 0 -0.2624593998262763 254 | 255 | 256 | 257 | 258 | 6.937578828380978 0.1 2.0 259 | 260 | 261 | 262 | 263 | 264 | 265 | 6.937578828380978 0.1 2.0 266 | 267 | 268 | 269 | 0.5 0.5 0.5 1 270 | 0.7 0.7 0.7 1 271 | 272 | 273 | 274 | 275 | 276 | true 277 | 3.985000000000002 5.5600000000000005 1.0 0 0 1.3164282682416306 278 | 279 | 280 | 281 | 282 | 2.583118270617898 0.1 2.0 283 | 284 | 285 | 286 | 287 | 288 | 289 | 2.583118270617898 0.1 2.0 290 | 291 | 292 | 293 | 0.5 0.5 0.5 1 294 | 0.7 0.7 0.7 1 295 | 296 | 297 | 298 | 299 | 300 | true 301 | 2.035000000000001 -1.6400000000000001 1.0 0 0 1.2769269917624289 302 | 303 | 304 | 305 | 306 | 3.9702015062210636 0.1 2.0 307 | 308 | 309 | 310 | 311 | 312 | 313 | 3.9702015062210636 0.1 2.0 314 | 315 | 316 | 317 | 0.5 0.5 0.5 1 318 | 0.7 0.7 0.7 1 319 | 320 | 321 | 322 | 323 | 324 | true 325 | 9.185 3.4850000000000003 1.0 0 0 -0.21608497229678686 326 | 327 | 328 | 329 | 330 | 2.0988091861815366 0.1 2.0 331 | 332 | 333 | 334 | 335 | 336 | 337 | 2.0988091861815366 0.1 2.0 338 | 339 | 340 | 341 | 0.5 0.5 0.5 1 342 | 0.7 0.7 0.7 1 343 | 344 | 345 | 346 | 347 | 348 | true 349 | -0.9399999999999991 8.66 1.0 0 0 1.373400766945016 350 | 351 | 352 | 353 | 354 | 1.5297058540778354 0.1 2.0 355 | 356 | 357 | 358 | 359 | 360 | 361 | 1.5297058540778354 0.1 2.0 362 | 363 | 364 | 365 | 0.5 0.5 0.5 1 366 | 0.7 0.7 0.7 1 367 | 368 | 369 | 370 | 371 | 372 | true 373 | -1.3649999999999989 3.5100000000000007 1.0 0 0 1.3431070070262408 374 | 375 | 376 | 377 | 378 | 4.208622102303793 0.1 2.0 379 | 380 | 381 | 382 | 383 | 384 | 385 | 4.208622102303793 0.1 2.0 386 | 387 | 388 | 389 | 0.5 0.5 0.5 1 390 | 0.7 0.7 0.7 1 391 | 392 | 393 | 394 | 395 | 396 | true 397 | -4.414999999999999 8.06 1.0 0 0 1.3194685426340562 398 | 399 | 400 | 401 | 402 | 3.8200130889828103 0.1 2.0 403 | 404 | 405 | 406 | 407 | 408 | 409 | 3.8200130889828103 0.1 2.0 410 | 411 | 412 | 413 | 0.5 0.5 0.5 1 414 | 0.7 0.7 0.7 1 415 | 416 | 417 | 418 | 419 | 420 | true 421 | -2.564999999999999 -0.565 1.0 0 0 1.3439974787410107 422 | 423 | 424 | 425 | 426 | 2.00124960961895 0.1 2.0 427 | 428 | 429 | 430 | 431 | 432 | 433 | 2.00124960961895 0.1 2.0 434 | 435 | 436 | 437 | 0.5 0.5 0.5 1 438 | 0.7 0.7 0.7 1 439 | 440 | 441 | 442 | 443 | 444 | true 445 | -4.3149999999999995 -7.515000000000001 1.0 0 0 -0.26750518132705736 446 | 447 | 448 | 449 | 450 | 6.998928489418935 0.1 2.0 451 | 452 | 453 | 454 | 455 | 456 | 457 | 6.998928489418935 0.1 2.0 458 | 459 | 460 | 461 | 0.5 0.5 0.5 1 462 | 0.7 0.7 0.7 1 463 | 464 | 465 | 466 | 467 | 468 | true 469 | 10.260000000000002 2.0600000000000005 1.0 0 0 -0.2013171083746408 470 | 471 | 472 | 473 | 474 | 5.000999900019994 0.1 2.0 475 | 476 | 477 | 478 | 479 | 480 | 481 | 5.000999900019994 0.1 2.0 482 | 483 | 484 | 485 | 0.5 0.5 0.5 1 486 | 0.7 0.7 0.7 1 487 | 488 | 489 | 490 | 491 | 492 | true 493 | 10.460000000000003 2.3599999999999994 1.0 0 0 -0.20539538918976735 494 | 495 | 496 | 497 | 498 | 4.903060268852506 0.1 2.0 499 | 500 | 501 | 502 | 503 | 504 | 505 | 4.903060268852506 0.1 2.0 506 | 507 | 508 | 509 | 0.5 0.5 0.5 1 510 | 0.7 0.7 0.7 1 511 | 512 | 513 | 514 | 515 | 516 | true 517 | -1.1649999999999991 7.660000000000001 1.0 0 0 1.3654009376051295 518 | 519 | 520 | 521 | 522 | 1.2257650672131273 0.1 2.0 523 | 524 | 525 | 526 | 527 | 528 | 529 | 1.2257650672131273 0.1 2.0 530 | 531 | 532 | 533 | 0.5 0.5 0.5 1 534 | 0.7 0.7 0.7 1 535 | 536 | 537 | 538 | 539 | 540 | true 541 | 1.9350000000000023 -4.015000000000001 1.0 0 0 1.3370531459259951 542 | 543 | 544 | 545 | 546 | 1.079351657246145 0.1 2.0 547 | 548 | 549 | 550 | 551 | 552 | 553 | 1.079351657246145 0.1 2.0 554 | 555 | 556 | 557 | 0.5 0.5 0.5 1 558 | 0.7 0.7 0.7 1 559 | 560 | 561 | 562 | 563 | 564 | true 565 | 0.3850000000000011 5.335 1.0 0 0 -0.22082876972934792 566 | 567 | 568 | 569 | 570 | 2.510975905897944 0.1 2.0 571 | 572 | 573 | 574 | 575 | 576 | 577 | 2.510975905897944 0.1 2.0 578 | 579 | 580 | 581 | 0.5 0.5 0.5 1 582 | 0.7 0.7 0.7 1 583 | 584 | 585 | 586 | 587 | 588 | true 589 | 2.410000000000001 9.084999999999999 1.0 0 0 -0.2244160090371457 590 | 591 | 592 | 593 | 594 | 4.718315377335432 0.1 2.0 595 | 596 | 597 | 598 | 599 | 600 | 601 | 4.718315377335432 0.1 2.0 602 | 603 | 604 | 605 | 0.5 0.5 0.5 1 606 | 0.7 0.7 0.7 1 607 | 608 | 609 | 610 | 611 | 612 | true 613 | 5.985000000000002 3.76 1.0 0 0 -0.20963984587421255 614 | 615 | 616 | 617 | 618 | 2.402602755346792 0.1 2.0 619 | 620 | 621 | 622 | 623 | 624 | 625 | 2.402602755346792 0.1 2.0 626 | 627 | 628 | 629 | 0.5 0.5 0.5 1 630 | 0.7 0.7 0.7 1 631 | 632 | 633 | 634 | 635 | 636 | true 637 | 7.835000000000001 -0.5400000000000005 1.0 0 0 -0.21576619640704234 638 | 639 | 640 | 641 | 642 | 3.7366428783066743 0.1 2.0 643 | 644 | 645 | 646 | 647 | 648 | 649 | 3.7366428783066743 0.1 2.0 650 | 651 | 652 | 653 | 0.5 0.5 0.5 1 654 | 0.7 0.7 0.7 1 655 | 656 | 657 | 658 | 659 | 660 | true 661 | 4.110000000000002 -0.6150000000000002 1.0 0 0 -0.23893644058616323 662 | 663 | 664 | 665 | 666 | 4.014037867285261 0.1 2.0 667 | 668 | 669 | 670 | 671 | 672 | 673 | 4.014037867285261 0.1 2.0 674 | 675 | 676 | 677 | 0.5 0.5 0.5 1 678 | 0.7 0.7 0.7 1 679 | 680 | 681 | 682 | 683 | 684 | true 685 | -1.5649999999999986 7.335 1.0 0 0 1.3419974814076712 686 | 687 | 688 | 689 | 690 | 3.7476659402887025 0.1 2.0 691 | 692 | 693 | 694 | 695 | 696 | 697 | 3.7476659402887025 0.1 2.0 698 | 699 | 700 | 701 | 0.5 0.5 0.5 1 702 | 0.7 0.7 0.7 1 703 | 704 | 705 | 706 | 707 | 708 | true 709 | -4.514999999999999 6.359999999999999 1.0 0 0 1.3140879963615109 710 | 711 | 712 | 713 | 714 | 4.135516896350443 0.1 2.0 715 | 716 | 717 | 718 | 719 | 720 | 721 | 4.135516896350443 0.1 2.0 722 | 723 | 724 | 725 | 0.5 0.5 0.5 1 726 | 0.7 0.7 0.7 1 727 | 728 | 729 | 730 | 731 | 732 | true 733 | -7.014999999999999 -2.8400000000000003 1.0 0 0 1.3334220798217258 734 | 735 | 736 | 737 | 738 | 3.189435686763413 0.1 2.0 739 | 740 | 741 | 742 | 743 | 744 | 745 | 3.189435686763413 0.1 2.0 746 | 747 | 748 | 749 | 0.5 0.5 0.5 1 750 | 0.7 0.7 0.7 1 751 | 752 | 753 | 754 | 755 | 756 | true 757 | 6.310000000000001 1.0599999999999996 1.0 0 0 1.343997478741011 758 | 759 | 760 | 761 | 762 | 2.668332812825266 0.1 2.0 763 | 764 | 765 | 766 | 767 | 768 | 769 | 2.668332812825266 0.1 2.0 770 | 771 | 772 | 773 | 0.5 0.5 0.5 1 774 | 0.7 0.7 0.7 1 775 | 776 | 777 | 778 | 779 | 780 | true 781 | 1.9600000000000017 3.3600000000000003 1.0 0 0 1.304544277643971 782 | 783 | 784 | 785 | 786 | 3.420526275297413 0.1 2.0 787 | 788 | 789 | 790 | 791 | 792 | 793 | 3.420526275297413 0.1 2.0 794 | 795 | 796 | 797 | 0.5 0.5 0.5 1 798 | 0.7 0.7 0.7 1 799 | 800 | 801 | 802 | 803 | 804 | true 805 | 7.960000000000002 -0.24000000000000066 1.0 0 0 -0.23860932250820077 806 | 807 | 808 | 809 | 810 | 3.807886552931955 0.1 2.0 811 | 812 | 813 | 814 | 815 | 816 | 817 | 3.807886552931955 0.1 2.0 818 | 819 | 820 | 821 | 0.5 0.5 0.5 1 822 | 0.7 0.7 0.7 1 823 | 824 | 825 | 826 | 827 | 828 | true 829 | 5.985000000000002 3.9850000000000003 1.0 0 0 -0.2046418098297775 830 | 831 | 832 | 833 | 834 | 2.7064737205448717 0.1 2.0 835 | 836 | 837 | 838 | 839 | 840 | 841 | 2.7064737205448717 0.1 2.0 842 | 843 | 844 | 845 | 0.5 0.5 0.5 1 846 | 0.7 0.7 0.7 1 847 | 848 | 849 | 850 | 851 | 852 | true 853 | -7.3149999999999995 -5.215 1.0 0 0 1.3020933021597254 854 | 855 | 856 | 857 | 858 | 3.5784074670165777 0.1 2.0 859 | 860 | 861 | 862 | 863 | 864 | 865 | 3.5784074670165777 0.1 2.0 866 | 867 | 868 | 869 | 0.5 0.5 0.5 1 870 | 0.7 0.7 0.7 1 871 | 872 | 873 | 874 | 875 | 876 | true 877 | 6.060000000000001 7.535 1.0 0 0 -0.23737424697317083 878 | 879 | 880 | 881 | 882 | 3.189435686763412 0.1 2.0 883 | 884 | 885 | 886 | 887 | 888 | 889 | 3.189435686763412 0.1 2.0 890 | 891 | 892 | 893 | 0.5 0.5 0.5 1 894 | 0.7 0.7 0.7 1 895 | 896 | 897 | 898 | 899 | 900 | true 901 | -1.0149999999999988 3.4350000000000005 1.0 0 0 1.328587739685276 902 | 903 | 904 | 905 | 906 | 4.377784827969506 0.1 2.0 907 | 908 | 909 | 910 | 911 | 912 | 913 | 4.377784827969506 0.1 2.0 914 | 915 | 916 | 917 | 0.5 0.5 0.5 1 918 | 0.7 0.7 0.7 1 919 | 920 | 921 | 922 | 923 | 924 | true 925 | -0.48999999999999844 -7.040000000000001 1.0 0 0 1.2490457723982544 926 | 927 | 928 | 929 | 930 | 3.1622776601683795 0.1 2.0 931 | 932 | 933 | 934 | 935 | 936 | 937 | 3.1622776601683795 0.1 2.0 938 | 939 | 940 | 941 | 0.5 0.5 0.5 1 942 | 0.7 0.7 0.7 1 943 | 944 | 945 | 946 | 947 | 948 | true 949 | -4.714999999999999 -1.5150000000000001 1.0 0 0 -0.26147881571224924 950 | 951 | 952 | 953 | 954 | 3.6749149650025923 0.1 2.0 955 | 956 | 957 | 958 | 959 | 960 | 961 | 3.6749149650025923 0.1 2.0 962 | 963 | 964 | 965 | 0.5 0.5 0.5 1 966 | 0.7 0.7 0.7 1 967 | 968 | 969 | 970 | 971 | 972 | true 973 | 13.185000000000002 3.285 1.0 0 0 1.3292306196995702 974 | 975 | 976 | 977 | 978 | 3.5531676008879733 0.1 2.0 979 | 980 | 981 | 982 | 983 | 984 | 985 | 3.5531676008879733 0.1 2.0 986 | 987 | 988 | 989 | 0.5 0.5 0.5 1 990 | 0.7 0.7 0.7 1 991 | 992 | 993 | 994 | 995 | 996 | true 997 | 3.785000000000001 -0.815 1.0 0 0 -0.2546246661945415 998 | 999 | 1000 | 1001 | 1002 | 3.7716044331292222 0.1 2.0 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 3.7716044331292222 0.1 2.0 1010 | 1011 | 1012 | 1013 | 0.5 0.5 0.5 1 1014 | 0.7 0.7 0.7 1 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | true 1021 | -1.6899999999999986 -5.140000000000001 1.0 0 0 -0.23554498072086355 1022 | 1023 | 1024 | 1025 | 1026 | 2.570992026436488 0.1 2.0 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 2.570992026436488 0.1 2.0 1034 | 1035 | 1036 | 1037 | 0.5 0.5 0.5 1 1038 | 0.7 0.7 0.7 1 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | true 1045 | 7.610000000000001 5.185 1.0 0 0 1.3363806510710856 1046 | 1047 | 1048 | 1049 | 1050 | 3.4441980198589044 0.1 2.0 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 3.4441980198589044 0.1 2.0 1058 | 1059 | 1060 | 1061 | 0.5 0.5 0.5 1 1062 | 0.7 0.7 0.7 1 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | true 1069 | 4.485000000000001 2.535 1.0 0 0 -0.22679884805388562 1070 | 1071 | 1072 | 1073 | 1074 | 2.001249609618949 0.1 2.0 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | 1081 | 2.001249609618949 0.1 2.0 1082 | 1083 | 1084 | 1085 | 0.5 0.5 0.5 1 1086 | 0.7 0.7 0.7 1 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | true 1093 | 12.210000000000003 6.21 1.0 0 0 -0.24497866312686445 1094 | 1095 | 1096 | 1097 | 1098 | 2.886173937932363 0.1 2.0 1099 | 1100 | 1101 | 1102 | 1103 | 1104 | 1105 | 2.886173937932363 0.1 2.0 1106 | 1107 | 1108 | 1109 | 0.5 0.5 0.5 1 1110 | 0.7 0.7 0.7 1 1111 | 1112 | 1113 | 1114 | 1115 | 1116 | true 1117 | -3.864999999999999 -6.115 1.0 0 0 1.3386924887197411 1118 | 1119 | 1120 | 1121 | 1122 | 2.825774230188958 0.1 2.0 1123 | 1124 | 1125 | 1126 | 1127 | 1128 | 1129 | 2.825774230188958 0.1 2.0 1130 | 1131 | 1132 | 1133 | 0.5 0.5 0.5 1 1134 | 0.7 0.7 0.7 1 1135 | 1136 | 1137 | 1138 | 1139 | 1140 | true 1141 | 7.360000000000001 5.41 1.0 0 0 1.3415643935179016 1142 | 1143 | 1144 | 1145 | 1146 | 3.080584360149872 0.1 2.0 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | 1153 | 3.080584360149872 0.1 2.0 1154 | 1155 | 1156 | 1157 | 0.5 0.5 0.5 1 1158 | 0.7 0.7 0.7 1 1159 | 1160 | 1161 | 1162 | 1163 | 1164 | true 1165 | -3.364999999999999 6.685 1.0 0 0 -0.27300870308671016 1166 | 1167 | 1168 | 1169 | 1170 | 1.2980754985747178 0.1 2.0 1171 | 1172 | 1173 | 1174 | 1175 | 1176 | 1177 | 1.2980754985747178 0.1 2.0 1178 | 1179 | 1180 | 1181 | 0.5 0.5 0.5 1 1182 | 0.7 0.7 0.7 1 1183 | 1184 | 1185 | 1186 | 1187 | 1188 | true 1189 | 10.260000000000002 4.8100000000000005 1.0 0 0 1.3554386270971577 1190 | 1191 | 1192 | 1193 | 1194 | 3.27566787083184 0.1 2.0 1195 | 1196 | 1197 | 1198 | 1199 | 1200 | 1201 | 3.27566787083184 0.1 2.0 1202 | 1203 | 1204 | 1205 | 0.5 0.5 0.5 1 1206 | 0.7 0.7 0.7 1 1207 | 1208 | 1209 | 1210 | 1211 | 1212 | true 1213 | -0.3899999999999988 1.0099999999999998 1.0 0 0 -0.25367409613864256 1214 | 1215 | 1216 | 1217 | 1218 | 2.7892651361962697 0.1 2.0 1219 | 1220 | 1221 | 1222 | 1223 | 1224 | 1225 | 2.7892651361962697 0.1 2.0 1226 | 1227 | 1228 | 1229 | 0.5 0.5 0.5 1 1230 | 0.7 0.7 0.7 1 1231 | 1232 | 1233 | 1234 | 1235 | 1236 | true 1237 | -2.4649999999999985 -3.1150000000000007 1.0 0 0 1.2944690518198314 1238 | 1239 | 1240 | 1241 | 1242 | 3.4820970692960302 0.1 2.0 1243 | 1244 | 1245 | 1246 | 1247 | 1248 | 1249 | 3.4820970692960302 0.1 2.0 1250 | 1251 | 1252 | 1253 | 0.5 0.5 0.5 1 1254 | 0.7 0.7 0.7 1 1255 | 1256 | 1257 | 1258 | 1259 | 1260 | true 1261 | 1.6850000000000014 3.585000000000001 1.0 0 0 1.3226828776982198 1262 | 1263 | 1264 | 1265 | 1266 | 3.86846222677694 0.1 2.0 1267 | 1268 | 1269 | 1270 | 1271 | 1272 | 1273 | 3.86846222677694 0.1 2.0 1274 | 1275 | 1276 | 1277 | 0.5 0.5 0.5 1 1278 | 0.7 0.7 0.7 1 1279 | 1280 | 1281 | 1282 | 1283 | 1284 | true 1285 | 12.985000000000003 3.7350000000000003 1.0 0 0 1.335784111074239 1286 | 1287 | 1288 | 1289 | 1290 | 3.6503424496887953 0.1 2.0 1291 | 1292 | 1293 | 1294 | 1295 | 1296 | 1297 | 3.6503424496887953 0.1 2.0 1298 | 1299 | 1300 | 1301 | 0.5 0.5 0.5 1 1302 | 0.7 0.7 0.7 1 1303 | 1304 | 1305 | 1306 | 1307 | 1308 | true 1309 | 3.0100000000000016 1.4349999999999996 1.0 0 0 1.361156480920684 1310 | 1311 | 1312 | 1313 | 1314 | 2.402602755346792 0.1 2.0 1315 | 1316 | 1317 | 1318 | 1319 | 1320 | 1321 | 2.402602755346792 0.1 2.0 1322 | 1323 | 1324 | 1325 | 0.5 0.5 0.5 1 1326 | 0.7 0.7 0.7 1 1327 | 1328 | 1329 | 1330 | 1331 | 1332 | true 1333 | 5.710000000000002 2.5600000000000005 1.0 0 0 -0.20539538918976735 1334 | 1335 | 1336 | 1337 | 1338 | 2.451530134426253 0.1 2.0 1339 | 1340 | 1341 | 1342 | 1343 | 1344 | 1345 | 2.451530134426253 0.1 2.0 1346 | 1347 | 1348 | 1349 | 0.5 0.5 0.5 1 1350 | 0.7 0.7 0.7 1 1351 | 1352 | 1353 | 1354 | 1355 | 1356 | true 1357 | 10.110000000000001 0.4849999999999999 1.0 0 0 1.3299498715534852 1358 | 1359 | 1360 | 1361 | 1362 | 2.934706118165838 0.1 2.0 1363 | 1364 | 1365 | 1366 | 1367 | 1368 | 1369 | 2.934706118165838 0.1 2.0 1370 | 1371 | 1372 | 1373 | 0.5 0.5 0.5 1 1374 | 0.7 0.7 0.7 1 1375 | 1376 | 1377 | 1378 | 1379 | 1380 | true 1381 | -2.939999999999999 -0.7900000000000005 1.0 0 0 1.2924966677897853 1382 | 1383 | 1384 | 1385 | 1386 | 2.912043955712207 0.1 2.0 1387 | 1388 | 1389 | 1390 | 1391 | 1392 | 1393 | 2.912043955712207 0.1 2.0 1394 | 1395 | 1396 | 1397 | 0.5 0.5 0.5 1 1398 | 0.7 0.7 0.7 1 1399 | 1400 | 1401 | 1402 | 1403 | 1404 | true 1405 | -2.5399999999999987 2.2350000000000003 1.0 0 0 1.3329603993374461 1406 | 1407 | 1408 | 1409 | 1410 | 1.6977926846349647 0.1 2.0 1411 | 1412 | 1413 | 1414 | 1415 | 1416 | 1417 | 1.6977926846349647 0.1 2.0 1418 | 1419 | 1420 | 1421 | 0.5 0.5 0.5 1 1422 | 0.7 0.7 0.7 1 1423 | 1424 | 1425 | 1426 | 1427 | 1428 | true 1429 | 2.3350000000000017 8.785 1.0 0 0 -0.23281381310673402 1430 | 1431 | 1432 | 1433 | 1434 | 4.984475900232641 0.1 2.0 1435 | 1436 | 1437 | 1438 | 1439 | 1440 | 1441 | 4.984475900232641 0.1 2.0 1442 | 1443 | 1444 | 1445 | 0.5 0.5 0.5 1 1446 | 0.7 0.7 0.7 1 1447 | 1448 | 1449 | 1450 | 1451 | 1452 | true 1453 | -0.714999999999999 -6.715000000000001 1.0 0 0 1.2490457723982549 1454 | 1455 | 1456 | 1457 | 1458 | 3.3203915431767985 0.1 2.0 1459 | 1460 | 1461 | 1462 | 1463 | 1464 | 1465 | 3.3203915431767985 0.1 2.0 1466 | 1467 | 1468 | 1469 | 0.5 0.5 0.5 1 1470 | 0.7 0.7 0.7 1 1471 | 1472 | 1473 | 1474 | 1475 | 1476 | true 1477 | -4.614999999999998 4.26 1.0 0 0 -0.20401797959254903 1478 | 1479 | 1480 | 1481 | 1482 | 1.480709289496085 0.1 2.0 1483 | 1484 | 1485 | 1486 | 1487 | 1488 | 1489 | 1.480709289496085 0.1 2.0 1490 | 1491 | 1492 | 1493 | 0.5 0.5 0.5 1 1494 | 0.7 0.7 0.7 1 1495 | 1496 | 1497 | 1498 | 1499 | 1500 | -------------------------------------------------------------------------------- /uv.lock: -------------------------------------------------------------------------------- 1 | version = 1 2 | revision = 2 3 | requires-python = ">=3.13" 4 | 5 | [[package]] 6 | name = "contourpy" 7 | version = "1.3.3" 8 | source = { registry = "https://pypi.org/simple" } 9 | dependencies = [ 10 | { name = "numpy" }, 11 | ] 12 | sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } 13 | wheels = [ 14 | { url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257, upload-time = "2025-07-26T12:01:39.367Z" }, 15 | { url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034, upload-time = "2025-07-26T12:01:40.645Z" }, 16 | { url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672, upload-time = "2025-07-26T12:01:41.942Z" }, 17 | { url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234, upload-time = "2025-07-26T12:01:43.499Z" }, 18 | { url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169, upload-time = "2025-07-26T12:01:45.219Z" }, 19 | { url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859, upload-time = "2025-07-26T12:01:46.519Z" }, 20 | { url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062, upload-time = "2025-07-26T12:01:48.964Z" }, 21 | { url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932, upload-time = "2025-07-26T12:01:51.979Z" }, 22 | { url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024, upload-time = "2025-07-26T12:01:53.245Z" }, 23 | { url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578, upload-time = "2025-07-26T12:01:54.422Z" }, 24 | { url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524, upload-time = "2025-07-26T12:01:55.73Z" }, 25 | { url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730, upload-time = "2025-07-26T12:01:57.051Z" }, 26 | { url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897, upload-time = "2025-07-26T12:01:58.663Z" }, 27 | { url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751, upload-time = "2025-07-26T12:02:00.343Z" }, 28 | { url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486, upload-time = "2025-07-26T12:02:02.128Z" }, 29 | { url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106, upload-time = "2025-07-26T12:02:03.615Z" }, 30 | { url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548, upload-time = "2025-07-26T12:02:05.165Z" }, 31 | { url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297, upload-time = "2025-07-26T12:02:07.379Z" }, 32 | { url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023, upload-time = "2025-07-26T12:02:10.171Z" }, 33 | { url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157, upload-time = "2025-07-26T12:02:11.488Z" }, 34 | { url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570, upload-time = "2025-07-26T12:02:12.754Z" }, 35 | { url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713, upload-time = "2025-07-26T12:02:14.4Z" }, 36 | { url = "https://files.pythonhosted.org/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a", size = 292189, upload-time = "2025-07-26T12:02:16.095Z" }, 37 | { url = "https://files.pythonhosted.org/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77", size = 273251, upload-time = "2025-07-26T12:02:17.524Z" }, 38 | { url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810, upload-time = "2025-07-26T12:02:18.9Z" }, 39 | { url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871, upload-time = "2025-07-26T12:02:20.418Z" }, 40 | { url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264, upload-time = "2025-07-26T12:02:21.916Z" }, 41 | { url = "https://files.pythonhosted.org/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819, upload-time = "2025-07-26T12:02:23.759Z" }, 42 | { url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650, upload-time = "2025-07-26T12:02:26.181Z" }, 43 | { url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833, upload-time = "2025-07-26T12:02:28.782Z" }, 44 | { url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692, upload-time = "2025-07-26T12:02:30.128Z" }, 45 | { url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424, upload-time = "2025-07-26T12:02:31.395Z" }, 46 | { url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300, upload-time = "2025-07-26T12:02:32.956Z" }, 47 | { url = "https://files.pythonhosted.org/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772", size = 306769, upload-time = "2025-07-26T12:02:34.2Z" }, 48 | { url = "https://files.pythonhosted.org/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77", size = 287892, upload-time = "2025-07-26T12:02:35.807Z" }, 49 | { url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748, upload-time = "2025-07-26T12:02:37.193Z" }, 50 | { url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554, upload-time = "2025-07-26T12:02:38.894Z" }, 51 | { url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118, upload-time = "2025-07-26T12:02:40.642Z" }, 52 | { url = "https://files.pythonhosted.org/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555, upload-time = "2025-07-26T12:02:42.25Z" }, 53 | { url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295, upload-time = "2025-07-26T12:02:44.668Z" }, 54 | { url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027, upload-time = "2025-07-26T12:02:47.09Z" }, 55 | { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload-time = "2025-07-26T12:02:48.691Z" }, 56 | { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload-time = "2025-07-26T12:02:50.137Z" }, 57 | { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" }, 58 | ] 59 | 60 | [[package]] 61 | name = "converter-pgm-to-sdf" 62 | version = "0.1.0" 63 | source = { virtual = "." } 64 | dependencies = [ 65 | { name = "matplotlib" }, 66 | { name = "opencv-python" }, 67 | { name = "pillow" }, 68 | { name = "pyyaml" }, 69 | { name = "scikit-image" }, 70 | { name = "scipy" }, 71 | ] 72 | 73 | [package.metadata] 74 | requires-dist = [ 75 | { name = "matplotlib", specifier = ">=3.10.3" }, 76 | { name = "opencv-python", specifier = ">=4.12.0.88" }, 77 | { name = "pillow", specifier = ">=11.3.0" }, 78 | { name = "pyyaml", specifier = ">=6.0.2" }, 79 | { name = "scikit-image", specifier = ">=0.25.2" }, 80 | { name = "scipy", specifier = ">=1.16.1" }, 81 | ] 82 | 83 | [[package]] 84 | name = "cycler" 85 | version = "0.12.1" 86 | source = { registry = "https://pypi.org/simple" } 87 | sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" } 88 | wheels = [ 89 | { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, 90 | ] 91 | 92 | [[package]] 93 | name = "fonttools" 94 | version = "4.59.0" 95 | source = { registry = "https://pypi.org/simple" } 96 | sdist = { url = "https://files.pythonhosted.org/packages/8a/27/ec3c723bfdf86f34c5c82bf6305df3e0f0d8ea798d2d3a7cb0c0a866d286/fonttools-4.59.0.tar.gz", hash = "sha256:be392ec3529e2f57faa28709d60723a763904f71a2b63aabe14fee6648fe3b14", size = 3532521, upload-time = "2025-07-16T12:04:54.613Z" } 97 | wheels = [ 98 | { url = "https://files.pythonhosted.org/packages/f3/bb/390990e7c457d377b00890d9f96a3ca13ae2517efafb6609c1756e213ba4/fonttools-4.59.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:78813b49d749e1bb4db1c57f2d4d7e6db22c253cb0a86ad819f5dc197710d4b2", size = 2758704, upload-time = "2025-07-16T12:04:22.217Z" }, 99 | { url = "https://files.pythonhosted.org/packages/df/6f/d730d9fcc9b410a11597092bd2eb9ca53e5438c6cb90e4b3047ce1b723e9/fonttools-4.59.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:401b1941ce37e78b8fd119b419b617277c65ae9417742a63282257434fd68ea2", size = 2330764, upload-time = "2025-07-16T12:04:23.985Z" }, 100 | { url = "https://files.pythonhosted.org/packages/75/b4/b96bb66f6f8cc4669de44a158099b249c8159231d254ab6b092909388be5/fonttools-4.59.0-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:efd7e6660674e234e29937bc1481dceb7e0336bfae75b856b4fb272b5093c5d4", size = 4890699, upload-time = "2025-07-16T12:04:25.664Z" }, 101 | { url = "https://files.pythonhosted.org/packages/b5/57/7969af50b26408be12baa317c6147588db5b38af2759e6df94554dbc5fdb/fonttools-4.59.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51ab1ff33c19e336c02dee1e9fd1abd974a4ca3d8f7eef2a104d0816a241ce97", size = 4952934, upload-time = "2025-07-16T12:04:27.733Z" }, 102 | { url = "https://files.pythonhosted.org/packages/d6/e2/dd968053b6cf1f46c904f5bd409b22341477c017d8201619a265e50762d3/fonttools-4.59.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a9bf8adc9e1f3012edc8f09b08336272aec0c55bc677422273e21280db748f7c", size = 4892319, upload-time = "2025-07-16T12:04:30.074Z" }, 103 | { url = "https://files.pythonhosted.org/packages/6b/95/a59810d8eda09129f83467a4e58f84205dc6994ebaeb9815406363e07250/fonttools-4.59.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:37e01c6ec0c98599778c2e688350d624fa4770fbd6144551bd5e032f1199171c", size = 5034753, upload-time = "2025-07-16T12:04:32.292Z" }, 104 | { url = "https://files.pythonhosted.org/packages/a5/84/51a69ee89ff8d1fea0c6997e946657e25a3f08513de8435fe124929f3eef/fonttools-4.59.0-cp313-cp313-win32.whl", hash = "sha256:70d6b3ceaa9cc5a6ac52884f3b3d9544e8e231e95b23f138bdb78e6d4dc0eae3", size = 2199688, upload-time = "2025-07-16T12:04:34.444Z" }, 105 | { url = "https://files.pythonhosted.org/packages/a0/ee/f626cd372932d828508137a79b85167fdcf3adab2e3bed433f295c596c6a/fonttools-4.59.0-cp313-cp313-win_amd64.whl", hash = "sha256:26731739daa23b872643f0e4072d5939960237d540c35c14e6a06d47d71ca8fe", size = 2248560, upload-time = "2025-07-16T12:04:36.034Z" }, 106 | { url = "https://files.pythonhosted.org/packages/d0/9c/df0ef2c51845a13043e5088f7bb988ca6cd5bb82d5d4203d6a158aa58cf2/fonttools-4.59.0-py3-none-any.whl", hash = "sha256:241313683afd3baacb32a6bd124d0bce7404bc5280e12e291bae1b9bba28711d", size = 1128050, upload-time = "2025-07-16T12:04:52.687Z" }, 107 | ] 108 | 109 | [[package]] 110 | name = "imageio" 111 | version = "2.37.0" 112 | source = { registry = "https://pypi.org/simple" } 113 | dependencies = [ 114 | { name = "numpy" }, 115 | { name = "pillow" }, 116 | ] 117 | sdist = { url = "https://files.pythonhosted.org/packages/0c/47/57e897fb7094afb2d26e8b2e4af9a45c7cf1a405acdeeca001fdf2c98501/imageio-2.37.0.tar.gz", hash = "sha256:71b57b3669666272c818497aebba2b4c5f20d5b37c81720e5e1a56d59c492996", size = 389963, upload-time = "2025-01-20T02:42:37.089Z" } 118 | wheels = [ 119 | { url = "https://files.pythonhosted.org/packages/cb/bd/b394387b598ed84d8d0fa90611a90bee0adc2021820ad5729f7ced74a8e2/imageio-2.37.0-py3-none-any.whl", hash = "sha256:11efa15b87bc7871b61590326b2d635439acc321cf7f8ce996f812543ce10eed", size = 315796, upload-time = "2025-01-20T02:42:34.931Z" }, 120 | ] 121 | 122 | [[package]] 123 | name = "kiwisolver" 124 | version = "1.4.8" 125 | source = { registry = "https://pypi.org/simple" } 126 | sdist = { url = "https://files.pythonhosted.org/packages/82/59/7c91426a8ac292e1cdd53a63b6d9439abd573c875c3f92c146767dd33faf/kiwisolver-1.4.8.tar.gz", hash = "sha256:23d5f023bdc8c7e54eb65f03ca5d5bb25b601eac4d7f1a042888a1f45237987e", size = 97538, upload-time = "2024-12-24T18:30:51.519Z" } 127 | wheels = [ 128 | { url = "https://files.pythonhosted.org/packages/79/b3/e62464a652f4f8cd9006e13d07abad844a47df1e6537f73ddfbf1bc997ec/kiwisolver-1.4.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1c8ceb754339793c24aee1c9fb2485b5b1f5bb1c2c214ff13368431e51fc9a09", size = 124156, upload-time = "2024-12-24T18:29:45.368Z" }, 129 | { url = "https://files.pythonhosted.org/packages/8d/2d/f13d06998b546a2ad4f48607a146e045bbe48030774de29f90bdc573df15/kiwisolver-1.4.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a62808ac74b5e55a04a408cda6156f986cefbcf0ada13572696b507cc92fa1", size = 66555, upload-time = "2024-12-24T18:29:46.37Z" }, 130 | { url = "https://files.pythonhosted.org/packages/59/e3/b8bd14b0a54998a9fd1e8da591c60998dc003618cb19a3f94cb233ec1511/kiwisolver-1.4.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:68269e60ee4929893aad82666821aaacbd455284124817af45c11e50a4b42e3c", size = 65071, upload-time = "2024-12-24T18:29:47.333Z" }, 131 | { url = "https://files.pythonhosted.org/packages/f0/1c/6c86f6d85ffe4d0ce04228d976f00674f1df5dc893bf2dd4f1928748f187/kiwisolver-1.4.8-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34d142fba9c464bc3bbfeff15c96eab0e7310343d6aefb62a79d51421fcc5f1b", size = 1378053, upload-time = "2024-12-24T18:29:49.636Z" }, 132 | { url = "https://files.pythonhosted.org/packages/4e/b9/1c6e9f6dcb103ac5cf87cb695845f5fa71379021500153566d8a8a9fc291/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc373e0eef45b59197de815b1b28ef89ae3955e7722cc9710fb91cd77b7f47", size = 1472278, upload-time = "2024-12-24T18:29:51.164Z" }, 133 | { url = "https://files.pythonhosted.org/packages/ee/81/aca1eb176de671f8bda479b11acdc42c132b61a2ac861c883907dde6debb/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77e6f57a20b9bd4e1e2cedda4d0b986ebd0216236f0106e55c28aea3d3d69b16", size = 1478139, upload-time = "2024-12-24T18:29:52.594Z" }, 134 | { url = "https://files.pythonhosted.org/packages/49/f4/e081522473671c97b2687d380e9e4c26f748a86363ce5af48b4a28e48d06/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08e77738ed7538f036cd1170cbed942ef749137b1311fa2bbe2a7fda2f6bf3cc", size = 1413517, upload-time = "2024-12-24T18:29:53.941Z" }, 135 | { url = "https://files.pythonhosted.org/packages/8f/e9/6a7d025d8da8c4931522922cd706105aa32b3291d1add8c5427cdcd66e63/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5ce1e481a74b44dd5e92ff03ea0cb371ae7a0268318e202be06c8f04f4f1246", size = 1474952, upload-time = "2024-12-24T18:29:56.523Z" }, 136 | { url = "https://files.pythonhosted.org/packages/82/13/13fa685ae167bee5d94b415991c4fc7bb0a1b6ebea6e753a87044b209678/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fc2ace710ba7c1dfd1a3b42530b62b9ceed115f19a1656adefce7b1782a37794", size = 2269132, upload-time = "2024-12-24T18:29:57.989Z" }, 137 | { url = "https://files.pythonhosted.org/packages/ef/92/bb7c9395489b99a6cb41d502d3686bac692586db2045adc19e45ee64ed23/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3452046c37c7692bd52b0e752b87954ef86ee2224e624ef7ce6cb21e8c41cc1b", size = 2425997, upload-time = "2024-12-24T18:29:59.393Z" }, 138 | { url = "https://files.pythonhosted.org/packages/ed/12/87f0e9271e2b63d35d0d8524954145837dd1a6c15b62a2d8c1ebe0f182b4/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7e9a60b50fe8b2ec6f448fe8d81b07e40141bfced7f896309df271a0b92f80f3", size = 2376060, upload-time = "2024-12-24T18:30:01.338Z" }, 139 | { url = "https://files.pythonhosted.org/packages/02/6e/c8af39288edbce8bf0fa35dee427b082758a4b71e9c91ef18fa667782138/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:918139571133f366e8362fa4a297aeba86c7816b7ecf0bc79168080e2bd79957", size = 2520471, upload-time = "2024-12-24T18:30:04.574Z" }, 140 | { url = "https://files.pythonhosted.org/packages/13/78/df381bc7b26e535c91469f77f16adcd073beb3e2dd25042efd064af82323/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e063ef9f89885a1d68dd8b2e18f5ead48653176d10a0e324e3b0030e3a69adeb", size = 2338793, upload-time = "2024-12-24T18:30:06.25Z" }, 141 | { url = "https://files.pythonhosted.org/packages/d0/dc/c1abe38c37c071d0fc71c9a474fd0b9ede05d42f5a458d584619cfd2371a/kiwisolver-1.4.8-cp313-cp313-win_amd64.whl", hash = "sha256:a17b7c4f5b2c51bb68ed379defd608a03954a1845dfed7cc0117f1cc8a9b7fd2", size = 71855, upload-time = "2024-12-24T18:30:07.535Z" }, 142 | { url = "https://files.pythonhosted.org/packages/a0/b6/21529d595b126ac298fdd90b705d87d4c5693de60023e0efcb4f387ed99e/kiwisolver-1.4.8-cp313-cp313-win_arm64.whl", hash = "sha256:3cd3bc628b25f74aedc6d374d5babf0166a92ff1317f46267f12d2ed54bc1d30", size = 65430, upload-time = "2024-12-24T18:30:08.504Z" }, 143 | { url = "https://files.pythonhosted.org/packages/34/bd/b89380b7298e3af9b39f49334e3e2a4af0e04819789f04b43d560516c0c8/kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:370fd2df41660ed4e26b8c9d6bbcad668fbe2560462cba151a721d49e5b6628c", size = 126294, upload-time = "2024-12-24T18:30:09.508Z" }, 144 | { url = "https://files.pythonhosted.org/packages/83/41/5857dc72e5e4148eaac5aa76e0703e594e4465f8ab7ec0fc60e3a9bb8fea/kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:84a2f830d42707de1d191b9490ac186bf7997a9495d4e9072210a1296345f7dc", size = 67736, upload-time = "2024-12-24T18:30:11.039Z" }, 145 | { url = "https://files.pythonhosted.org/packages/e1/d1/be059b8db56ac270489fb0b3297fd1e53d195ba76e9bbb30e5401fa6b759/kiwisolver-1.4.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7a3ad337add5148cf51ce0b55642dc551c0b9d6248458a757f98796ca7348712", size = 66194, upload-time = "2024-12-24T18:30:14.886Z" }, 146 | { url = "https://files.pythonhosted.org/packages/e1/83/4b73975f149819eb7dcf9299ed467eba068ecb16439a98990dcb12e63fdd/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7506488470f41169b86d8c9aeff587293f530a23a23a49d6bc64dab66bedc71e", size = 1465942, upload-time = "2024-12-24T18:30:18.927Z" }, 147 | { url = "https://files.pythonhosted.org/packages/c7/2c/30a5cdde5102958e602c07466bce058b9d7cb48734aa7a4327261ac8e002/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f0121b07b356a22fb0414cec4666bbe36fd6d0d759db3d37228f496ed67c880", size = 1595341, upload-time = "2024-12-24T18:30:22.102Z" }, 148 | { url = "https://files.pythonhosted.org/packages/ff/9b/1e71db1c000385aa069704f5990574b8244cce854ecd83119c19e83c9586/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6d6bd87df62c27d4185de7c511c6248040afae67028a8a22012b010bc7ad062", size = 1598455, upload-time = "2024-12-24T18:30:24.947Z" }, 149 | { url = "https://files.pythonhosted.org/packages/85/92/c8fec52ddf06231b31cbb779af77e99b8253cd96bd135250b9498144c78b/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:291331973c64bb9cce50bbe871fb2e675c4331dab4f31abe89f175ad7679a4d7", size = 1522138, upload-time = "2024-12-24T18:30:26.286Z" }, 150 | { url = "https://files.pythonhosted.org/packages/0b/51/9eb7e2cd07a15d8bdd976f6190c0164f92ce1904e5c0c79198c4972926b7/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:893f5525bb92d3d735878ec00f781b2de998333659507d29ea4466208df37bed", size = 1582857, upload-time = "2024-12-24T18:30:28.86Z" }, 151 | { url = "https://files.pythonhosted.org/packages/0f/95/c5a00387a5405e68ba32cc64af65ce881a39b98d73cc394b24143bebc5b8/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b47a465040146981dc9db8647981b8cb96366fbc8d452b031e4f8fdffec3f26d", size = 2293129, upload-time = "2024-12-24T18:30:30.34Z" }, 152 | { url = "https://files.pythonhosted.org/packages/44/83/eeb7af7d706b8347548313fa3a3a15931f404533cc54fe01f39e830dd231/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:99cea8b9dd34ff80c521aef46a1dddb0dcc0283cf18bde6d756f1e6f31772165", size = 2421538, upload-time = "2024-12-24T18:30:33.334Z" }, 153 | { url = "https://files.pythonhosted.org/packages/05/f9/27e94c1b3eb29e6933b6986ffc5fa1177d2cd1f0c8efc5f02c91c9ac61de/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:151dffc4865e5fe6dafce5480fab84f950d14566c480c08a53c663a0020504b6", size = 2390661, upload-time = "2024-12-24T18:30:34.939Z" }, 154 | { url = "https://files.pythonhosted.org/packages/d9/d4/3c9735faa36ac591a4afcc2980d2691000506050b7a7e80bcfe44048daa7/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:577facaa411c10421314598b50413aa1ebcf5126f704f1e5d72d7e4e9f020d90", size = 2546710, upload-time = "2024-12-24T18:30:37.281Z" }, 155 | { url = "https://files.pythonhosted.org/packages/4c/fa/be89a49c640930180657482a74970cdcf6f7072c8d2471e1babe17a222dc/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:be4816dc51c8a471749d664161b434912eee82f2ea66bd7628bd14583a833e85", size = 2349213, upload-time = "2024-12-24T18:30:40.019Z" }, 156 | ] 157 | 158 | [[package]] 159 | name = "lazy-loader" 160 | version = "0.4" 161 | source = { registry = "https://pypi.org/simple" } 162 | dependencies = [ 163 | { name = "packaging" }, 164 | ] 165 | sdist = { url = "https://files.pythonhosted.org/packages/6f/6b/c875b30a1ba490860c93da4cabf479e03f584eba06fe5963f6f6644653d8/lazy_loader-0.4.tar.gz", hash = "sha256:47c75182589b91a4e1a85a136c074285a5ad4d9f39c63e0d7fb76391c4574cd1", size = 15431, upload-time = "2024-04-05T13:03:12.261Z" } 166 | wheels = [ 167 | { url = "https://files.pythonhosted.org/packages/83/60/d497a310bde3f01cb805196ac61b7ad6dc5dcf8dce66634dc34364b20b4f/lazy_loader-0.4-py3-none-any.whl", hash = "sha256:342aa8e14d543a154047afb4ba8ef17f5563baad3fc610d7b15b213b0f119efc", size = 12097, upload-time = "2024-04-05T13:03:10.514Z" }, 168 | ] 169 | 170 | [[package]] 171 | name = "matplotlib" 172 | version = "3.10.3" 173 | source = { registry = "https://pypi.org/simple" } 174 | dependencies = [ 175 | { name = "contourpy" }, 176 | { name = "cycler" }, 177 | { name = "fonttools" }, 178 | { name = "kiwisolver" }, 179 | { name = "numpy" }, 180 | { name = "packaging" }, 181 | { name = "pillow" }, 182 | { name = "pyparsing" }, 183 | { name = "python-dateutil" }, 184 | ] 185 | sdist = { url = "https://files.pythonhosted.org/packages/26/91/d49359a21893183ed2a5b6c76bec40e0b1dcbf8ca148f864d134897cfc75/matplotlib-3.10.3.tar.gz", hash = "sha256:2f82d2c5bb7ae93aaaa4cd42aca65d76ce6376f83304fa3a630b569aca274df0", size = 34799811, upload-time = "2025-05-08T19:10:54.39Z" } 186 | wheels = [ 187 | { url = "https://files.pythonhosted.org/packages/3b/c1/23cfb566a74c696a3b338d8955c549900d18fe2b898b6e94d682ca21e7c2/matplotlib-3.10.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9f2efccc8dcf2b86fc4ee849eea5dcaecedd0773b30f47980dc0cbeabf26ec84", size = 8180318, upload-time = "2025-05-08T19:10:20.426Z" }, 188 | { url = "https://files.pythonhosted.org/packages/6c/0c/02f1c3b66b30da9ee343c343acbb6251bef5b01d34fad732446eaadcd108/matplotlib-3.10.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3ddbba06a6c126e3301c3d272a99dcbe7f6c24c14024e80307ff03791a5f294e", size = 8051132, upload-time = "2025-05-08T19:10:22.569Z" }, 189 | { url = "https://files.pythonhosted.org/packages/b4/ab/8db1a5ac9b3a7352fb914133001dae889f9fcecb3146541be46bed41339c/matplotlib-3.10.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:748302b33ae9326995b238f606e9ed840bf5886ebafcb233775d946aa8107a15", size = 8457633, upload-time = "2025-05-08T19:10:24.749Z" }, 190 | { url = "https://files.pythonhosted.org/packages/f5/64/41c4367bcaecbc03ef0d2a3ecee58a7065d0a36ae1aa817fe573a2da66d4/matplotlib-3.10.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a80fcccbef63302c0efd78042ea3c2436104c5b1a4d3ae20f864593696364ac7", size = 8601031, upload-time = "2025-05-08T19:10:27.03Z" }, 191 | { url = "https://files.pythonhosted.org/packages/12/6f/6cc79e9e5ab89d13ed64da28898e40fe5b105a9ab9c98f83abd24e46d7d7/matplotlib-3.10.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:55e46cbfe1f8586adb34f7587c3e4f7dedc59d5226719faf6cb54fc24f2fd52d", size = 9406988, upload-time = "2025-05-08T19:10:29.056Z" }, 192 | { url = "https://files.pythonhosted.org/packages/b1/0f/eed564407bd4d935ffabf561ed31099ed609e19287409a27b6d336848653/matplotlib-3.10.3-cp313-cp313-win_amd64.whl", hash = "sha256:151d89cb8d33cb23345cd12490c76fd5d18a56581a16d950b48c6ff19bb2ab93", size = 8068034, upload-time = "2025-05-08T19:10:31.221Z" }, 193 | { url = "https://files.pythonhosted.org/packages/3e/e5/2f14791ff69b12b09e9975e1d116d9578ac684460860ce542c2588cb7a1c/matplotlib-3.10.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:c26dd9834e74d164d06433dc7be5d75a1e9890b926b3e57e74fa446e1a62c3e2", size = 8218223, upload-time = "2025-05-08T19:10:33.114Z" }, 194 | { url = "https://files.pythonhosted.org/packages/5c/08/30a94afd828b6e02d0a52cae4a29d6e9ccfcf4c8b56cc28b021d3588873e/matplotlib-3.10.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:24853dad5b8c84c8c2390fc31ce4858b6df504156893292ce8092d190ef8151d", size = 8094985, upload-time = "2025-05-08T19:10:35.337Z" }, 195 | { url = "https://files.pythonhosted.org/packages/89/44/f3bc6b53066c889d7a1a3ea8094c13af6a667c5ca6220ec60ecceec2dabe/matplotlib-3.10.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68f7878214d369d7d4215e2a9075fef743be38fa401d32e6020bab2dfabaa566", size = 8483109, upload-time = "2025-05-08T19:10:37.611Z" }, 196 | { url = "https://files.pythonhosted.org/packages/ba/c7/473bc559beec08ebee9f86ca77a844b65747e1a6c2691e8c92e40b9f42a8/matplotlib-3.10.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6929fc618cb6db9cb75086f73b3219bbb25920cb24cee2ea7a12b04971a4158", size = 8618082, upload-time = "2025-05-08T19:10:39.892Z" }, 197 | { url = "https://files.pythonhosted.org/packages/d8/e9/6ce8edd264c8819e37bbed8172e0ccdc7107fe86999b76ab5752276357a4/matplotlib-3.10.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6c7818292a5cc372a2dc4c795e5c356942eb8350b98ef913f7fda51fe175ac5d", size = 9413699, upload-time = "2025-05-08T19:10:42.376Z" }, 198 | { url = "https://files.pythonhosted.org/packages/1b/92/9a45c91089c3cf690b5badd4be81e392ff086ccca8a1d4e3a08463d8a966/matplotlib-3.10.3-cp313-cp313t-win_amd64.whl", hash = "sha256:4f23ffe95c5667ef8a2b56eea9b53db7f43910fa4a2d5472ae0f72b64deab4d5", size = 8139044, upload-time = "2025-05-08T19:10:44.551Z" }, 199 | ] 200 | 201 | [[package]] 202 | name = "networkx" 203 | version = "3.5" 204 | source = { registry = "https://pypi.org/simple" } 205 | sdist = { url = "https://files.pythonhosted.org/packages/6c/4f/ccdb8ad3a38e583f214547fd2f7ff1fc160c43a75af88e6aec213404b96a/networkx-3.5.tar.gz", hash = "sha256:d4c6f9cf81f52d69230866796b82afbccdec3db7ae4fbd1b65ea750feed50037", size = 2471065, upload-time = "2025-05-29T11:35:07.804Z" } 206 | wheels = [ 207 | { url = "https://files.pythonhosted.org/packages/eb/8d/776adee7bbf76365fdd7f2552710282c79a4ead5d2a46408c9043a2b70ba/networkx-3.5-py3-none-any.whl", hash = "sha256:0030d386a9a06dee3565298b4a734b68589749a544acbb6c412dc9e2489ec6ec", size = 2034406, upload-time = "2025-05-29T11:35:04.961Z" }, 208 | ] 209 | 210 | [[package]] 211 | name = "numpy" 212 | version = "2.2.6" 213 | source = { registry = "https://pypi.org/simple" } 214 | sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } 215 | wheels = [ 216 | { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload-time = "2025-05-17T21:37:56.699Z" }, 217 | { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload-time = "2025-05-17T21:38:18.291Z" }, 218 | { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload-time = "2025-05-17T21:38:27.319Z" }, 219 | { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload-time = "2025-05-17T21:38:38.141Z" }, 220 | { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload-time = "2025-05-17T21:38:58.433Z" }, 221 | { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload-time = "2025-05-17T21:39:22.638Z" }, 222 | { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload-time = "2025-05-17T21:39:45.865Z" }, 223 | { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload-time = "2025-05-17T21:40:13.331Z" }, 224 | { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload-time = "2025-05-17T21:43:46.099Z" }, 225 | { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload-time = "2025-05-17T21:44:05.145Z" }, 226 | { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload-time = "2025-05-17T21:40:44Z" }, 227 | { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload-time = "2025-05-17T21:41:05.695Z" }, 228 | { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload-time = "2025-05-17T21:41:15.903Z" }, 229 | { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload-time = "2025-05-17T21:41:27.321Z" }, 230 | { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload-time = "2025-05-17T21:41:49.738Z" }, 231 | { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload-time = "2025-05-17T21:42:14.046Z" }, 232 | { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload-time = "2025-05-17T21:42:37.464Z" }, 233 | { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload-time = "2025-05-17T21:43:05.189Z" }, 234 | { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload-time = "2025-05-17T21:43:16.254Z" }, 235 | { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload-time = "2025-05-17T21:43:35.479Z" }, 236 | ] 237 | 238 | [[package]] 239 | name = "opencv-python" 240 | version = "4.12.0.88" 241 | source = { registry = "https://pypi.org/simple" } 242 | dependencies = [ 243 | { name = "numpy" }, 244 | ] 245 | sdist = { url = "https://files.pythonhosted.org/packages/ac/71/25c98e634b6bdeca4727c7f6d6927b056080668c5008ad3c8fc9e7f8f6ec/opencv-python-4.12.0.88.tar.gz", hash = "sha256:8b738389cede219405f6f3880b851efa3415ccd674752219377353f017d2994d", size = 95373294, upload-time = "2025-07-07T09:20:52.389Z" } 246 | wheels = [ 247 | { url = "https://files.pythonhosted.org/packages/85/68/3da40142e7c21e9b1d4e7ddd6c58738feb013203e6e4b803d62cdd9eb96b/opencv_python-4.12.0.88-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:f9a1f08883257b95a5764bf517a32d75aec325319c8ed0f89739a57fae9e92a5", size = 37877727, upload-time = "2025-07-07T09:13:31.47Z" }, 248 | { url = "https://files.pythonhosted.org/packages/33/7c/042abe49f58d6ee7e1028eefc3334d98ca69b030e3b567fe245a2b28ea6f/opencv_python-4.12.0.88-cp37-abi3-macosx_13_0_x86_64.whl", hash = "sha256:812eb116ad2b4de43ee116fcd8991c3a687f099ada0b04e68f64899c09448e81", size = 57326471, upload-time = "2025-07-07T09:13:41.26Z" }, 249 | { url = "https://files.pythonhosted.org/packages/62/3a/440bd64736cf8116f01f3b7f9f2e111afb2e02beb2ccc08a6458114a6b5d/opencv_python-4.12.0.88-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:51fd981c7df6af3e8f70b1556696b05224c4e6b6777bdd2a46b3d4fb09de1a92", size = 45887139, upload-time = "2025-07-07T09:13:50.761Z" }, 250 | { url = "https://files.pythonhosted.org/packages/68/1f/795e7f4aa2eacc59afa4fb61a2e35e510d06414dd5a802b51a012d691b37/opencv_python-4.12.0.88-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:092c16da4c5a163a818f120c22c5e4a2f96e0db4f24e659c701f1fe629a690f9", size = 67041680, upload-time = "2025-07-07T09:14:01.995Z" }, 251 | { url = "https://files.pythonhosted.org/packages/02/96/213fea371d3cb2f1d537612a105792aa0a6659fb2665b22cad709a75bd94/opencv_python-4.12.0.88-cp37-abi3-win32.whl", hash = "sha256:ff554d3f725b39878ac6a2e1fa232ec509c36130927afc18a1719ebf4fbf4357", size = 30284131, upload-time = "2025-07-07T09:14:08.819Z" }, 252 | { url = "https://files.pythonhosted.org/packages/fa/80/eb88edc2e2b11cd2dd2e56f1c80b5784d11d6e6b7f04a1145df64df40065/opencv_python-4.12.0.88-cp37-abi3-win_amd64.whl", hash = "sha256:d98edb20aa932fd8ebd276a72627dad9dc097695b3d435a4257557bbb49a79d2", size = 39000307, upload-time = "2025-07-07T09:14:16.641Z" }, 253 | ] 254 | 255 | [[package]] 256 | name = "packaging" 257 | version = "25.0" 258 | source = { registry = "https://pypi.org/simple" } 259 | sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } 260 | wheels = [ 261 | { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, 262 | ] 263 | 264 | [[package]] 265 | name = "pillow" 266 | version = "11.3.0" 267 | source = { registry = "https://pypi.org/simple" } 268 | sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload-time = "2025-07-01T09:16:30.666Z" } 269 | wheels = [ 270 | { url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload-time = "2025-07-01T09:14:35.276Z" }, 271 | { url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload-time = "2025-07-01T09:14:37.203Z" }, 272 | { url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload-time = "2025-07-01T09:14:39.344Z" }, 273 | { url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload-time = "2025-07-01T09:14:41.843Z" }, 274 | { url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload-time = "2025-07-01T09:14:44.008Z" }, 275 | { url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload-time = "2025-07-03T13:10:15.628Z" }, 276 | { url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload-time = "2025-07-03T13:10:21.857Z" }, 277 | { url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload-time = "2025-07-01T09:14:45.698Z" }, 278 | { url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload-time = "2025-07-01T09:14:47.415Z" }, 279 | { url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload-time = "2025-07-01T09:14:49.636Z" }, 280 | { url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload-time = "2025-07-01T09:14:51.962Z" }, 281 | { url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload-time = "2025-07-01T09:14:54.142Z" }, 282 | { url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload-time = "2025-07-01T09:14:56.436Z" }, 283 | { url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload-time = "2025-07-01T09:14:58.072Z" }, 284 | { url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload-time = "2025-07-01T09:14:59.79Z" }, 285 | { url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload-time = "2025-07-01T09:15:01.648Z" }, 286 | { url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload-time = "2025-07-03T13:10:27.018Z" }, 287 | { url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload-time = "2025-07-03T13:10:33.01Z" }, 288 | { url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload-time = "2025-07-01T09:15:03.365Z" }, 289 | { url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload-time = "2025-07-01T09:15:05.655Z" }, 290 | { url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload-time = "2025-07-01T09:15:07.358Z" }, 291 | { url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload-time = "2025-07-01T09:15:09.317Z" }, 292 | { url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload-time = "2025-07-01T09:15:11.311Z" }, 293 | { url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload-time = "2025-07-01T09:15:13.164Z" }, 294 | { url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload-time = "2025-07-01T09:15:15.695Z" }, 295 | { url = "https://files.pythonhosted.org/packages/73/f4/04905af42837292ed86cb1b1dabe03dce1edc008ef14c473c5c7e1443c5d/pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", size = 5278520, upload-time = "2025-07-01T09:15:17.429Z" }, 296 | { url = "https://files.pythonhosted.org/packages/41/b0/33d79e377a336247df6348a54e6d2a2b85d644ca202555e3faa0cf811ecc/pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", size = 4686116, upload-time = "2025-07-01T09:15:19.423Z" }, 297 | { url = "https://files.pythonhosted.org/packages/49/2d/ed8bc0ab219ae8768f529597d9509d184fe8a6c4741a6864fea334d25f3f/pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", size = 5864597, upload-time = "2025-07-03T13:10:38.404Z" }, 298 | { url = "https://files.pythonhosted.org/packages/b5/3d/b932bb4225c80b58dfadaca9d42d08d0b7064d2d1791b6a237f87f661834/pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", size = 7638246, upload-time = "2025-07-03T13:10:44.987Z" }, 299 | { url = "https://files.pythonhosted.org/packages/09/b5/0487044b7c096f1b48f0d7ad416472c02e0e4bf6919541b111efd3cae690/pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", size = 5973336, upload-time = "2025-07-01T09:15:21.237Z" }, 300 | { url = "https://files.pythonhosted.org/packages/a8/2d/524f9318f6cbfcc79fbc004801ea6b607ec3f843977652fdee4857a7568b/pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", size = 6642699, upload-time = "2025-07-01T09:15:23.186Z" }, 301 | { url = "https://files.pythonhosted.org/packages/6f/d2/a9a4f280c6aefedce1e8f615baaa5474e0701d86dd6f1dede66726462bbd/pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", size = 6083789, upload-time = "2025-07-01T09:15:25.1Z" }, 302 | { url = "https://files.pythonhosted.org/packages/fe/54/86b0cd9dbb683a9d5e960b66c7379e821a19be4ac5810e2e5a715c09a0c0/pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", size = 6720386, upload-time = "2025-07-01T09:15:27.378Z" }, 303 | { url = "https://files.pythonhosted.org/packages/e7/95/88efcaf384c3588e24259c4203b909cbe3e3c2d887af9e938c2022c9dd48/pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", size = 6370911, upload-time = "2025-07-01T09:15:29.294Z" }, 304 | { url = "https://files.pythonhosted.org/packages/2e/cc/934e5820850ec5eb107e7b1a72dd278140731c669f396110ebc326f2a503/pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", size = 7117383, upload-time = "2025-07-01T09:15:31.128Z" }, 305 | { url = "https://files.pythonhosted.org/packages/d6/e9/9c0a616a71da2a5d163aa37405e8aced9a906d574b4a214bede134e731bc/pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", size = 2511385, upload-time = "2025-07-01T09:15:33.328Z" }, 306 | { url = "https://files.pythonhosted.org/packages/1a/33/c88376898aff369658b225262cd4f2659b13e8178e7534df9e6e1fa289f6/pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", size = 5281129, upload-time = "2025-07-01T09:15:35.194Z" }, 307 | { url = "https://files.pythonhosted.org/packages/1f/70/d376247fb36f1844b42910911c83a02d5544ebd2a8bad9efcc0f707ea774/pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", size = 4689580, upload-time = "2025-07-01T09:15:37.114Z" }, 308 | { url = "https://files.pythonhosted.org/packages/eb/1c/537e930496149fbac69efd2fc4329035bbe2e5475b4165439e3be9cb183b/pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", size = 5902860, upload-time = "2025-07-03T13:10:50.248Z" }, 309 | { url = "https://files.pythonhosted.org/packages/bd/57/80f53264954dcefeebcf9dae6e3eb1daea1b488f0be8b8fef12f79a3eb10/pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", size = 7670694, upload-time = "2025-07-03T13:10:56.432Z" }, 310 | { url = "https://files.pythonhosted.org/packages/70/ff/4727d3b71a8578b4587d9c276e90efad2d6fe0335fd76742a6da08132e8c/pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", size = 6005888, upload-time = "2025-07-01T09:15:39.436Z" }, 311 | { url = "https://files.pythonhosted.org/packages/05/ae/716592277934f85d3be51d7256f3636672d7b1abfafdc42cf3f8cbd4b4c8/pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", size = 6670330, upload-time = "2025-07-01T09:15:41.269Z" }, 312 | { url = "https://files.pythonhosted.org/packages/e7/bb/7fe6cddcc8827b01b1a9766f5fdeb7418680744f9082035bdbabecf1d57f/pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", size = 6114089, upload-time = "2025-07-01T09:15:43.13Z" }, 313 | { url = "https://files.pythonhosted.org/packages/8b/f5/06bfaa444c8e80f1a8e4bff98da9c83b37b5be3b1deaa43d27a0db37ef84/pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", size = 6748206, upload-time = "2025-07-01T09:15:44.937Z" }, 314 | { url = "https://files.pythonhosted.org/packages/f0/77/bc6f92a3e8e6e46c0ca78abfffec0037845800ea38c73483760362804c41/pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", size = 6377370, upload-time = "2025-07-01T09:15:46.673Z" }, 315 | { url = "https://files.pythonhosted.org/packages/4a/82/3a721f7d69dca802befb8af08b7c79ebcab461007ce1c18bd91a5d5896f9/pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", size = 7121500, upload-time = "2025-07-01T09:15:48.512Z" }, 316 | { url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload-time = "2025-07-01T09:15:50.399Z" }, 317 | ] 318 | 319 | [[package]] 320 | name = "pyparsing" 321 | version = "3.2.3" 322 | source = { registry = "https://pypi.org/simple" } 323 | sdist = { url = "https://files.pythonhosted.org/packages/bb/22/f1129e69d94ffff626bdb5c835506b3a5b4f3d070f17ea295e12c2c6f60f/pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be", size = 1088608, upload-time = "2025-03-25T05:01:28.114Z" } 324 | wheels = [ 325 | { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120, upload-time = "2025-03-25T05:01:24.908Z" }, 326 | ] 327 | 328 | [[package]] 329 | name = "python-dateutil" 330 | version = "2.9.0.post0" 331 | source = { registry = "https://pypi.org/simple" } 332 | dependencies = [ 333 | { name = "six" }, 334 | ] 335 | sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } 336 | wheels = [ 337 | { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, 338 | ] 339 | 340 | [[package]] 341 | name = "pyyaml" 342 | version = "6.0.2" 343 | source = { registry = "https://pypi.org/simple" } 344 | sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } 345 | wheels = [ 346 | { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, 347 | { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, 348 | { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, 349 | { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, 350 | { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, 351 | { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, 352 | { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, 353 | { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, 354 | { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, 355 | ] 356 | 357 | [[package]] 358 | name = "scikit-image" 359 | version = "0.25.2" 360 | source = { registry = "https://pypi.org/simple" } 361 | dependencies = [ 362 | { name = "imageio" }, 363 | { name = "lazy-loader" }, 364 | { name = "networkx" }, 365 | { name = "numpy" }, 366 | { name = "packaging" }, 367 | { name = "pillow" }, 368 | { name = "scipy" }, 369 | { name = "tifffile" }, 370 | ] 371 | sdist = { url = "https://files.pythonhosted.org/packages/c7/a8/3c0f256012b93dd2cb6fda9245e9f4bff7dc0486880b248005f15ea2255e/scikit_image-0.25.2.tar.gz", hash = "sha256:e5a37e6cd4d0c018a7a55b9d601357e3382826d3888c10d0213fc63bff977dde", size = 22693594, upload-time = "2025-02-18T18:05:24.538Z" } 372 | wheels = [ 373 | { url = "https://files.pythonhosted.org/packages/e6/7c/9814dd1c637f7a0e44342985a76f95a55dd04be60154247679fd96c7169f/scikit_image-0.25.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7efa888130f6c548ec0439b1a7ed7295bc10105458a421e9bf739b457730b6da", size = 13921841, upload-time = "2025-02-18T18:05:03.963Z" }, 374 | { url = "https://files.pythonhosted.org/packages/84/06/66a2e7661d6f526740c309e9717d3bd07b473661d5cdddef4dd978edab25/scikit_image-0.25.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:dd8011efe69c3641920614d550f5505f83658fe33581e49bed86feab43a180fc", size = 13196862, upload-time = "2025-02-18T18:05:06.986Z" }, 375 | { url = "https://files.pythonhosted.org/packages/4e/63/3368902ed79305f74c2ca8c297dfeb4307269cbe6402412668e322837143/scikit_image-0.25.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28182a9d3e2ce3c2e251383bdda68f8d88d9fff1a3ebe1eb61206595c9773341", size = 14117785, upload-time = "2025-02-18T18:05:10.69Z" }, 376 | { url = "https://files.pythonhosted.org/packages/cd/9b/c3da56a145f52cd61a68b8465d6a29d9503bc45bc993bb45e84371c97d94/scikit_image-0.25.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8abd3c805ce6944b941cfed0406d88faeb19bab3ed3d4b50187af55cf24d147", size = 14977119, upload-time = "2025-02-18T18:05:13.871Z" }, 377 | { url = "https://files.pythonhosted.org/packages/8a/97/5fcf332e1753831abb99a2525180d3fb0d70918d461ebda9873f66dcc12f/scikit_image-0.25.2-cp313-cp313-win_amd64.whl", hash = "sha256:64785a8acefee460ec49a354706db0b09d1f325674107d7fa3eadb663fb56d6f", size = 12885116, upload-time = "2025-02-18T18:05:17.844Z" }, 378 | { url = "https://files.pythonhosted.org/packages/10/cc/75e9f17e3670b5ed93c32456fda823333c6279b144cd93e2c03aa06aa472/scikit_image-0.25.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:330d061bd107d12f8d68f1d611ae27b3b813b8cdb0300a71d07b1379178dd4cd", size = 13862801, upload-time = "2025-02-18T18:05:20.783Z" }, 379 | ] 380 | 381 | [[package]] 382 | name = "scipy" 383 | version = "1.16.1" 384 | source = { registry = "https://pypi.org/simple" } 385 | dependencies = [ 386 | { name = "numpy" }, 387 | ] 388 | sdist = { url = "https://files.pythonhosted.org/packages/f5/4a/b927028464795439faec8eaf0b03b011005c487bb2d07409f28bf30879c4/scipy-1.16.1.tar.gz", hash = "sha256:44c76f9e8b6e8e488a586190ab38016e4ed2f8a038af7cd3defa903c0a2238b3", size = 30580861, upload-time = "2025-07-27T16:33:30.834Z" } 389 | wheels = [ 390 | { url = "https://files.pythonhosted.org/packages/93/0b/b5c99382b839854a71ca9482c684e3472badc62620287cbbdab499b75ce6/scipy-1.16.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5451606823a5e73dfa621a89948096c6528e2896e40b39248295d3a0138d594f", size = 36533717, upload-time = "2025-07-27T16:28:51.706Z" }, 391 | { url = "https://files.pythonhosted.org/packages/eb/e5/69ab2771062c91e23e07c12e7d5033a6b9b80b0903ee709c3c36b3eb520c/scipy-1.16.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:89728678c5ca5abd610aee148c199ac1afb16e19844401ca97d43dc548a354eb", size = 28570009, upload-time = "2025-07-27T16:28:57.017Z" }, 392 | { url = "https://files.pythonhosted.org/packages/f4/69/bd75dbfdd3cf524f4d753484d723594aed62cfaac510123e91a6686d520b/scipy-1.16.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e756d688cb03fd07de0fffad475649b03cb89bee696c98ce508b17c11a03f95c", size = 20841942, upload-time = "2025-07-27T16:29:01.152Z" }, 393 | { url = "https://files.pythonhosted.org/packages/ea/74/add181c87663f178ba7d6144b370243a87af8476664d5435e57d599e6874/scipy-1.16.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5aa2687b9935da3ed89c5dbed5234576589dd28d0bf7cd237501ccfbdf1ad608", size = 23498507, upload-time = "2025-07-27T16:29:05.202Z" }, 394 | { url = "https://files.pythonhosted.org/packages/1d/74/ece2e582a0d9550cee33e2e416cc96737dce423a994d12bbe59716f47ff1/scipy-1.16.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0851f6a1e537fe9399f35986897e395a1aa61c574b178c0d456be5b1a0f5ca1f", size = 33286040, upload-time = "2025-07-27T16:29:10.201Z" }, 395 | { url = "https://files.pythonhosted.org/packages/e4/82/08e4076df538fb56caa1d489588d880ec7c52d8273a606bb54d660528f7c/scipy-1.16.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fedc2cbd1baed37474b1924c331b97bdff611d762c196fac1a9b71e67b813b1b", size = 35176096, upload-time = "2025-07-27T16:29:17.091Z" }, 396 | { url = "https://files.pythonhosted.org/packages/fa/79/cd710aab8c921375711a8321c6be696e705a120e3011a643efbbcdeeabcc/scipy-1.16.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2ef500e72f9623a6735769e4b93e9dcb158d40752cdbb077f305487e3e2d1f45", size = 35490328, upload-time = "2025-07-27T16:29:22.928Z" }, 397 | { url = "https://files.pythonhosted.org/packages/71/73/e9cc3d35ee4526d784520d4494a3e1ca969b071fb5ae5910c036a375ceec/scipy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:978d8311674b05a8f7ff2ea6c6bce5d8b45a0cb09d4c5793e0318f448613ea65", size = 37939921, upload-time = "2025-07-27T16:29:29.108Z" }, 398 | { url = "https://files.pythonhosted.org/packages/21/12/c0efd2941f01940119b5305c375ae5c0fcb7ec193f806bd8f158b73a1782/scipy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:81929ed0fa7a5713fcdd8b2e6f73697d3b4c4816d090dd34ff937c20fa90e8ab", size = 38479462, upload-time = "2025-07-27T16:30:24.078Z" }, 399 | { url = "https://files.pythonhosted.org/packages/7a/19/c3d08b675260046a991040e1ea5d65f91f40c7df1045fffff412dcfc6765/scipy-1.16.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:bcc12db731858abda693cecdb3bdc9e6d4bd200213f49d224fe22df82687bdd6", size = 36938832, upload-time = "2025-07-27T16:29:35.057Z" }, 400 | { url = "https://files.pythonhosted.org/packages/81/f2/ce53db652c033a414a5b34598dba6b95f3d38153a2417c5a3883da429029/scipy-1.16.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:744d977daa4becb9fc59135e75c069f8d301a87d64f88f1e602a9ecf51e77b27", size = 29093084, upload-time = "2025-07-27T16:29:40.201Z" }, 401 | { url = "https://files.pythonhosted.org/packages/a9/ae/7a10ff04a7dc15f9057d05b33737ade244e4bd195caa3f7cc04d77b9e214/scipy-1.16.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:dc54f76ac18073bcecffb98d93f03ed6b81a92ef91b5d3b135dcc81d55a724c7", size = 21365098, upload-time = "2025-07-27T16:29:44.295Z" }, 402 | { url = "https://files.pythonhosted.org/packages/36/ac/029ff710959932ad3c2a98721b20b405f05f752f07344622fd61a47c5197/scipy-1.16.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:367d567ee9fc1e9e2047d31f39d9d6a7a04e0710c86e701e053f237d14a9b4f6", size = 23896858, upload-time = "2025-07-27T16:29:48.784Z" }, 403 | { url = "https://files.pythonhosted.org/packages/71/13/d1ef77b6bd7898720e1f0b6b3743cb945f6c3cafa7718eaac8841035ab60/scipy-1.16.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4cf5785e44e19dcd32a0e4807555e1e9a9b8d475c6afff3d21c3c543a6aa84f4", size = 33438311, upload-time = "2025-07-27T16:29:54.164Z" }, 404 | { url = "https://files.pythonhosted.org/packages/2d/e0/e64a6821ffbb00b4c5b05169f1c1fddb4800e9307efe3db3788995a82a2c/scipy-1.16.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3d0b80fb26d3e13a794c71d4b837e2a589d839fd574a6bbb4ee1288c213ad4a3", size = 35279542, upload-time = "2025-07-27T16:30:00.249Z" }, 405 | { url = "https://files.pythonhosted.org/packages/57/59/0dc3c8b43e118f1e4ee2b798dcc96ac21bb20014e5f1f7a8e85cc0653bdb/scipy-1.16.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8503517c44c18d1030d666cb70aaac1cc8913608816e06742498833b128488b7", size = 35667665, upload-time = "2025-07-27T16:30:05.916Z" }, 406 | { url = "https://files.pythonhosted.org/packages/45/5f/844ee26e34e2f3f9f8febb9343748e72daeaec64fe0c70e9bf1ff84ec955/scipy-1.16.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:30cc4bb81c41831ecfd6dc450baf48ffd80ef5aed0f5cf3ea775740e80f16ecc", size = 38045210, upload-time = "2025-07-27T16:30:11.655Z" }, 407 | { url = "https://files.pythonhosted.org/packages/8d/d7/210f2b45290f444f1de64bc7353aa598ece9f0e90c384b4a156f9b1a5063/scipy-1.16.1-cp313-cp313t-win_amd64.whl", hash = "sha256:c24fa02f7ed23ae514460a22c57eca8f530dbfa50b1cfdbf4f37c05b5309cc39", size = 38593661, upload-time = "2025-07-27T16:30:17.825Z" }, 408 | { url = "https://files.pythonhosted.org/packages/81/ea/84d481a5237ed223bd3d32d6e82d7a6a96e34756492666c260cef16011d1/scipy-1.16.1-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:796a5a9ad36fa3a782375db8f4241ab02a091308eb079746bc0f874c9b998318", size = 36525921, upload-time = "2025-07-27T16:30:30.081Z" }, 409 | { url = "https://files.pythonhosted.org/packages/4e/9f/d9edbdeff9f3a664807ae3aea383e10afaa247e8e6255e6d2aa4515e8863/scipy-1.16.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:3ea0733a2ff73fd6fdc5fecca54ee9b459f4d74f00b99aced7d9a3adb43fb1cc", size = 28564152, upload-time = "2025-07-27T16:30:35.336Z" }, 410 | { url = "https://files.pythonhosted.org/packages/3b/95/8125bcb1fe04bc267d103e76516243e8d5e11229e6b306bda1024a5423d1/scipy-1.16.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:85764fb15a2ad994e708258bb4ed8290d1305c62a4e1ef07c414356a24fcfbf8", size = 20836028, upload-time = "2025-07-27T16:30:39.421Z" }, 411 | { url = "https://files.pythonhosted.org/packages/77/9c/bf92e215701fc70bbcd3d14d86337cf56a9b912a804b9c776a269524a9e9/scipy-1.16.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:ca66d980469cb623b1759bdd6e9fd97d4e33a9fad5b33771ced24d0cb24df67e", size = 23489666, upload-time = "2025-07-27T16:30:43.663Z" }, 412 | { url = "https://files.pythonhosted.org/packages/5e/00/5e941d397d9adac41b02839011594620d54d99488d1be5be755c00cde9ee/scipy-1.16.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e7cc1ffcc230f568549fc56670bcf3df1884c30bd652c5da8138199c8c76dae0", size = 33358318, upload-time = "2025-07-27T16:30:48.982Z" }, 413 | { url = "https://files.pythonhosted.org/packages/0e/87/8db3aa10dde6e3e8e7eb0133f24baa011377d543f5b19c71469cf2648026/scipy-1.16.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ddfb1e8d0b540cb4ee9c53fc3dea3186f97711248fb94b4142a1b27178d8b4b", size = 35185724, upload-time = "2025-07-27T16:30:54.26Z" }, 414 | { url = "https://files.pythonhosted.org/packages/89/b4/6ab9ae443216807622bcff02690262d8184078ea467efee2f8c93288a3b1/scipy-1.16.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4dc0e7be79e95d8ba3435d193e0d8ce372f47f774cffd882f88ea4e1e1ddc731", size = 35554335, upload-time = "2025-07-27T16:30:59.765Z" }, 415 | { url = "https://files.pythonhosted.org/packages/9c/9a/d0e9dc03c5269a1afb60661118296a32ed5d2c24298af61b676c11e05e56/scipy-1.16.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f23634f9e5adb51b2a77766dac217063e764337fbc816aa8ad9aaebcd4397fd3", size = 37960310, upload-time = "2025-07-27T16:31:06.151Z" }, 416 | { url = "https://files.pythonhosted.org/packages/5e/00/c8f3130a50521a7977874817ca89e0599b1b4ee8e938bad8ae798a0e1f0d/scipy-1.16.1-cp314-cp314-win_amd64.whl", hash = "sha256:57d75524cb1c5a374958a2eae3d84e1929bb971204cc9d52213fb8589183fc19", size = 39319239, upload-time = "2025-07-27T16:31:59.942Z" }, 417 | { url = "https://files.pythonhosted.org/packages/f2/f2/1ca3eda54c3a7e4c92f6acef7db7b3a057deb135540d23aa6343ef8ad333/scipy-1.16.1-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:d8da7c3dd67bcd93f15618938f43ed0995982eb38973023d46d4646c4283ad65", size = 36939460, upload-time = "2025-07-27T16:31:11.865Z" }, 418 | { url = "https://files.pythonhosted.org/packages/80/30/98c2840b293a132400c0940bb9e140171dcb8189588619048f42b2ce7b4f/scipy-1.16.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:cc1d2f2fd48ba1e0620554fe5bc44d3e8f5d4185c8c109c7fbdf5af2792cfad2", size = 29093322, upload-time = "2025-07-27T16:31:17.045Z" }, 419 | { url = "https://files.pythonhosted.org/packages/c1/e6/1e6e006e850622cf2a039b62d1a6ddc4497d4851e58b68008526f04a9a00/scipy-1.16.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:21a611ced9275cb861bacadbada0b8c0623bc00b05b09eb97f23b370fc2ae56d", size = 21365329, upload-time = "2025-07-27T16:31:21.188Z" }, 420 | { url = "https://files.pythonhosted.org/packages/8e/02/72a5aa5b820589dda9a25e329ca752842bfbbaf635e36bc7065a9b42216e/scipy-1.16.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:8dfbb25dffc4c3dd9371d8ab456ca81beeaf6f9e1c2119f179392f0dc1ab7695", size = 23897544, upload-time = "2025-07-27T16:31:25.408Z" }, 421 | { url = "https://files.pythonhosted.org/packages/2b/dc/7122d806a6f9eb8a33532982234bed91f90272e990f414f2830cfe656e0b/scipy-1.16.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f0ebb7204f063fad87fc0a0e4ff4a2ff40b2a226e4ba1b7e34bf4b79bf97cd86", size = 33442112, upload-time = "2025-07-27T16:31:30.62Z" }, 422 | { url = "https://files.pythonhosted.org/packages/24/39/e383af23564daa1021a5b3afbe0d8d6a68ec639b943661841f44ac92de85/scipy-1.16.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f1b9e5962656f2734c2b285a8745358ecb4e4efbadd00208c80a389227ec61ff", size = 35286594, upload-time = "2025-07-27T16:31:36.112Z" }, 423 | { url = "https://files.pythonhosted.org/packages/95/47/1a0b0aff40c3056d955f38b0df5d178350c3d74734ec54f9c68d23910be5/scipy-1.16.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e1a106f8c023d57a2a903e771228bf5c5b27b5d692088f457acacd3b54511e4", size = 35665080, upload-time = "2025-07-27T16:31:42.025Z" }, 424 | { url = "https://files.pythonhosted.org/packages/64/df/ce88803e9ed6e27fe9b9abefa157cf2c80e4fa527cf17ee14be41f790ad4/scipy-1.16.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:709559a1db68a9abc3b2c8672c4badf1614f3b440b3ab326d86a5c0491eafae3", size = 38050306, upload-time = "2025-07-27T16:31:48.109Z" }, 425 | { url = "https://files.pythonhosted.org/packages/6e/6c/a76329897a7cae4937d403e623aa6aaea616a0bb5b36588f0b9d1c9a3739/scipy-1.16.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c0c804d60492a0aad7f5b2bb1862f4548b990049e27e828391ff2bf6f7199998", size = 39427705, upload-time = "2025-07-27T16:31:53.96Z" }, 426 | ] 427 | 428 | [[package]] 429 | name = "six" 430 | version = "1.17.0" 431 | source = { registry = "https://pypi.org/simple" } 432 | sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } 433 | wheels = [ 434 | { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, 435 | ] 436 | 437 | [[package]] 438 | name = "tifffile" 439 | version = "2025.6.11" 440 | source = { registry = "https://pypi.org/simple" } 441 | dependencies = [ 442 | { name = "numpy" }, 443 | ] 444 | sdist = { url = "https://files.pythonhosted.org/packages/11/9e/636e3e433c24da41dd639e0520db60750dbf5e938d023b83af8097382ea3/tifffile-2025.6.11.tar.gz", hash = "sha256:0ece4c2e7a10656957d568a093b07513c0728d30c1bd8cc12725901fffdb7143", size = 370125, upload-time = "2025-06-12T04:49:38.839Z" } 445 | wheels = [ 446 | { url = "https://files.pythonhosted.org/packages/3a/d8/1ba8f32bfc9cb69e37edeca93738e883f478fbe84ae401f72c0d8d507841/tifffile-2025.6.11-py3-none-any.whl", hash = "sha256:32effb78b10b3a283eb92d4ebf844ae7e93e151458b0412f38518b4e6d2d7542", size = 230800, upload-time = "2025-06-12T04:49:37.458Z" }, 447 | ] 448 | --------------------------------------------------------------------------------