valetudo-map-parser 0.1.9b68__py3-none-any.whl → 0.1.9b69__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,7 +23,9 @@ class AsyncNumPy:
23
23
  return await make_async(np.copy, array)
24
24
 
25
25
  @staticmethod
26
- async def async_full(shape: tuple, fill_value: Any, dtype: np.dtype = None) -> np.ndarray:
26
+ async def async_full(
27
+ shape: tuple, fill_value: Any, dtype: np.dtype = None
28
+ ) -> np.ndarray:
27
29
  """Async array creation with fill value."""
28
30
  return await make_async(np.full, shape, fill_value, dtype=dtype)
29
31
 
@@ -42,20 +44,25 @@ class AsyncPIL:
42
44
  return await make_async(Image.fromarray, array, mode)
43
45
 
44
46
  @staticmethod
45
- async def async_resize(image: Image.Image, size: tuple, resample: int = None) -> Image.Image:
47
+ async def async_resize(
48
+ image: Image.Image, size: tuple, resample: int = None
49
+ ) -> Image.Image:
46
50
  """Async image resizing."""
47
51
  if resample is None:
48
52
  resample = Image.LANCZOS
49
53
  return await make_async(image.resize, size, resample)
50
54
 
51
55
  @staticmethod
52
- async def async_save_to_bytes(image: Image.Image, format_type: str = "WEBP", **kwargs) -> bytes:
56
+ async def async_save_to_bytes(
57
+ image: Image.Image, format_type: str = "WEBP", **kwargs
58
+ ) -> bytes:
53
59
  """Async image saving to bytes."""
60
+
54
61
  def save_to_bytes():
55
62
  buffer = io.BytesIO()
56
63
  image.save(buffer, format=format_type, **kwargs)
57
64
  return buffer.getvalue()
58
-
65
+
59
66
  return await make_async(save_to_bytes)
60
67
 
61
68
 
@@ -311,6 +311,79 @@ class Drawable:
311
311
 
312
312
  return layer
313
313
 
314
+ @staticmethod
315
+ def draw_lines_batch(
316
+ layer: NumpyArray,
317
+ line_segments: list,
318
+ color: Color,
319
+ width: int = 3,
320
+ ) -> NumpyArray:
321
+ """
322
+ Draw multiple line segments with batch processing for better performance.
323
+
324
+ Args:
325
+ layer: The numpy array to draw on
326
+ line_segments: List of tuples [(x1, y1, x2, y2), ...]
327
+ color: Color to draw with
328
+ width: Width of the lines
329
+ """
330
+ if not line_segments:
331
+ return layer
332
+
333
+ # Pre-calculate blended color once for the entire batch
334
+ # Use the first line segment for color sampling
335
+ x1, y1, x2, y2 = line_segments[0]
336
+ blended_color = get_blended_color(x1, y1, x2, y2, layer, color)
337
+
338
+ # Fast path for fully opaque colors - skip individual blending
339
+ if color[3] == 255:
340
+ blended_color = color
341
+
342
+ # Process all line segments with the same blended color
343
+ for x1, y1, x2, y2 in line_segments:
344
+ # Ensure coordinates are integers
345
+ x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
346
+
347
+ # Calculate line length
348
+ length = max(abs(x2 - x1), abs(y2 - y1))
349
+ if length == 0: # Handle case of a single point
350
+ # Draw a dot with the specified width
351
+ for i in range(-width // 2, (width + 1) // 2):
352
+ for j in range(-width // 2, (width + 1) // 2):
353
+ if (
354
+ 0 <= x1 + i < layer.shape[1]
355
+ and 0 <= y1 + j < layer.shape[0]
356
+ ):
357
+ layer[y1 + j, x1 + i] = blended_color
358
+ continue
359
+
360
+ # Create parametric points along the line
361
+ t = np.linspace(0, 1, length + 1) # Reduced from length * 2 to length + 1
362
+ x_coords = np.round(x1 * (1 - t) + x2 * t).astype(int)
363
+ y_coords = np.round(y1 * (1 - t) + y2 * t).astype(int)
364
+
365
+ # Draw the line with the specified width
366
+ if width == 1:
367
+ # Fast path for width=1
368
+ for x, y in zip(x_coords, y_coords):
369
+ if 0 <= x < layer.shape[1] and 0 <= y < layer.shape[0]:
370
+ layer[y, x] = blended_color
371
+ else:
372
+ # For thicker lines, draw a rectangle at each point
373
+ half_width = width // 2
374
+ for x, y in zip(x_coords, y_coords):
375
+ for i in range(-half_width, half_width + 1):
376
+ for j in range(-half_width, half_width + 1):
377
+ if (
378
+ i * i + j * j
379
+ <= half_width * half_width # Make it round
380
+ and 0 <= x + i < layer.shape[1]
381
+ and 0 <= y + j < layer.shape[0]
382
+ ):
383
+ layer[y + j, x + i] = blended_color
384
+
385
+ return layer
386
+
314
387
  @staticmethod
315
388
  async def draw_virtual_walls(
316
389
  layer: NumpyArray, virtual_walls, color: Color
@@ -329,14 +402,16 @@ class Drawable:
329
402
  async def lines(arr: NumpyArray, coords, width: int, color: Color) -> NumpyArray:
330
403
  """
331
404
  Join the coordinates creating a continuous line (path).
332
- Optimized with vectorized operations for better performance.
405
+ Optimized with batch processing for better performance.
333
406
  """
334
407
 
335
408
  # Handle case where arr might be a coroutine (shouldn't happen but let's be safe)
336
409
  if inspect.iscoroutine(arr):
337
410
  arr = await arr
338
411
 
339
- for i, coord in enumerate(coords):
412
+ # Collect all line segments for batch processing
413
+ line_segments = []
414
+ for coord in coords:
340
415
  x0, y0 = coord[0]
341
416
  try:
342
417
  x1, y1 = coord[1]
@@ -347,15 +422,16 @@ class Drawable:
347
422
  if x0 == x1 and y0 == y1:
348
423
  continue
349
424
 
350
- # Get blended color for this line segment
351
- blended_color = get_blended_color(x0, y0, x1, y1, arr, color)
425
+ line_segments.append((x0, y0, x1, y1))
352
426
 
353
- # Use the optimized line drawing method
354
- arr = Drawable._line(arr, x0, y0, x1, y1, blended_color, width)
427
+ # Process all line segments in batches
428
+ batch_size = 100 # Process 100 lines at a time
429
+ for i in range(0, len(line_segments), batch_size):
430
+ batch = line_segments[i : i + batch_size]
431
+ arr = Drawable.draw_lines_batch(arr, batch, color, width)
355
432
 
356
- # Yield control every 100 operations to prevent blocking
357
- if i % 100 == 0:
358
- await asyncio.sleep(0)
433
+ # Yield control between batches to prevent blocking
434
+ await asyncio.sleep(0)
359
435
 
360
436
  return arr
361
437
 
@@ -513,7 +589,11 @@ class Drawable:
513
589
  # Create tasks for parallel zone processing
514
590
  zone_tasks = []
515
591
  for zone in coordinates:
516
- zone_tasks.append(Drawable._process_single_zone(layers.copy(), zone, color, dot_radius, dot_spacing))
592
+ zone_tasks.append(
593
+ Drawable._process_single_zone(
594
+ layers.copy(), zone, color, dot_radius, dot_spacing
595
+ )
596
+ )
517
597
 
518
598
  # Execute all zone processing tasks in parallel
519
599
  zone_results = await asyncio.gather(*zone_tasks, return_exceptions=True)
@@ -567,7 +647,9 @@ class Drawable:
567
647
  y_indices, x_indices = np.ogrid[y_min:y_max, x_min:x_max]
568
648
 
569
649
  # Create a circular mask
570
- mask = (y_indices - y) ** 2 + (x_indices - x) ** 2 <= dot_radius**2
650
+ mask = (y_indices - y) ** 2 + (
651
+ x_indices - x
652
+ ) ** 2 <= dot_radius**2
571
653
 
572
654
  # Apply the color to the masked region
573
655
  layers[y_min:y_max, x_min:x_max][mask] = blended_color
@@ -575,7 +657,9 @@ class Drawable:
575
657
  return layers
576
658
 
577
659
  @staticmethod
578
- async def _process_single_zone(layers: NumpyArray, zone, color: Color, dot_radius: int, dot_spacing: int) -> NumpyArray:
660
+ async def _process_single_zone(
661
+ layers: NumpyArray, zone, color: Color, dot_radius: int, dot_spacing: int
662
+ ) -> NumpyArray:
579
663
  """Process a single zone for parallel execution."""
580
664
  await asyncio.sleep(0) # Yield control
581
665
 
@@ -613,7 +697,9 @@ class Drawable:
613
697
 
614
698
  if y_min < y_max and x_min < x_max:
615
699
  y_indices, x_indices = np.ogrid[y_min:y_max, x_min:x_max]
616
- mask = (y_indices - y) ** 2 + (x_indices - x) ** 2 <= dot_radius**2
700
+ mask = (y_indices - y) ** 2 + (
701
+ x_indices - x
702
+ ) ** 2 <= dot_radius**2
617
703
  layers[y_min:y_max, x_min:x_max][mask] = blended_color
618
704
 
619
705
  return layers
@@ -1,12 +1,13 @@
1
1
  """
2
2
  Class Camera Shared.
3
3
  Keep the data between the modules.
4
- Version: v2024.12.0
4
+ Version: v0.1.9
5
5
  """
6
6
 
7
7
  import asyncio
8
8
  import logging
9
9
  from typing import List
10
+ from PIL import Image
10
11
 
11
12
  from .types import (
12
13
  ATTR_CALIBRATION_POINTS,
@@ -59,7 +60,10 @@ class CameraShared:
59
60
  self.rand256_active_zone: list = [] # Active zone for rand256
60
61
  self.is_rand: bool = False # MQTT rand data
61
62
  self._new_mqtt_message = False # New MQTT message
62
- self.last_image = PilPNG | None # Last image received
63
+ # Initialize last_image with default gray image (250x150 minimum)
64
+ self.last_image = Image.new(
65
+ "RGBA", (250, 150), (128, 128, 128, 255)
66
+ ) # Gray default image
63
67
  self.new_image: PilPNG | None = None # New image received
64
68
  self.binary_image: bytes | None = None # Current image in binary format
65
69
  self.image_last_updated: float = 0.0 # Last image update time
@@ -115,8 +119,6 @@ class CameraShared:
115
119
  self.skip_room_ids: List[str] = []
116
120
  self.device_info = None # Store the device_info
117
121
 
118
-
119
-
120
122
  def vacuum_bat_charged(self) -> bool:
121
123
  """Check if the vacuum is charging."""
122
124
  return (self.vacuum_state == "docked") and (int(self.vacuum_battery) < 100)
@@ -11,7 +11,7 @@ import numpy as np
11
11
  from PIL import Image, ImageOps
12
12
 
13
13
  from .drawable import Drawable
14
- from .drawable_elements import DrawableElement, DrawingConfig
14
+ from .drawable_elements import DrawingConfig
15
15
  from .enhanced_drawable import EnhancedDrawable
16
16
  from .types import (
17
17
  LOGGER,
@@ -80,10 +80,11 @@ class BaseHandler:
80
80
  """Return the robot position."""
81
81
  return self.robot_pos
82
82
 
83
- async def async_get_pil_image(
83
+ async def async_get_image(
84
84
  self,
85
85
  m_json: dict | None,
86
86
  destinations: list | None = None,
87
+ bytes_format: bool = False,
87
88
  ) -> PilPNG | None:
88
89
  """
89
90
  Unified async function to get PIL image from JSON data for both Hypfer and Rand256 handlers.
@@ -96,50 +97,89 @@ class BaseHandler:
96
97
 
97
98
  @param m_json: The JSON data to use to draw the image
98
99
  @param destinations: MQTT destinations for labels (used by Rand256)
100
+ @param bytes_format: If True, also convert to PNG bytes and store in shared.binary_image
99
101
  @return: PIL Image or None
100
102
  """
101
103
  try:
102
104
  # Backup current image to last_image before processing new one
103
- if hasattr(self.shared, 'new_image') and self.shared.new_image is not None:
105
+ if hasattr(self.shared, "new_image") and self.shared.new_image is not None:
104
106
  self.shared.last_image = self.shared.new_image
105
107
 
106
108
  # Call the appropriate handler method based on handler type
107
- if hasattr(self, 'get_image_from_rrm'):
109
+ if hasattr(self, "get_image_from_rrm"):
108
110
  # This is a Rand256 handler
109
111
  new_image = await self.get_image_from_rrm(
110
112
  m_json=m_json,
111
113
  destinations=destinations,
112
- return_webp=False # Always return PIL Image
114
+ return_webp=False, # Always return PIL Image
113
115
  )
114
- elif hasattr(self, 'async_get_image_from_json'):
116
+ elif hasattr(self, "async_get_image_from_json"):
115
117
  # This is a Hypfer handler
116
118
  new_image = await self.async_get_image_from_json(
117
119
  m_json=m_json,
118
- return_webp=False # Always return PIL Image
120
+ return_webp=False, # Always return PIL Image
119
121
  )
120
122
  else:
121
- LOGGER.warning("%s: Handler type not recognized for async_get_pil_image", self.file_name)
122
- return None
123
+ LOGGER.warning(
124
+ "%s: Handler type not recognized for async_get_image",
125
+ self.file_name,
126
+ )
127
+ return (
128
+ self.shared.last_image
129
+ if hasattr(self.shared, "last_image")
130
+ else None
131
+ )
123
132
 
124
133
  # Store the new image in shared data
125
134
  if new_image is not None:
126
135
  self.shared.new_image = new_image
136
+
137
+ # Convert to binary (PNG bytes) if requested
138
+ if bytes_format:
139
+ try:
140
+ png_buffer = io.BytesIO()
141
+ new_image.save(png_buffer, format="PNG")
142
+ self.shared.binary_image = png_buffer.getvalue()
143
+ png_buffer.close()
144
+ LOGGER.debug(
145
+ "%s: Binary image conversion completed", self.file_name
146
+ )
147
+ except Exception as e:
148
+ LOGGER.warning(
149
+ "%s: Failed to convert image to binary: %s",
150
+ self.file_name,
151
+ str(e),
152
+ )
153
+ self.shared.binary_image = None
154
+ else:
155
+ self.shared.binary_image = None
156
+
127
157
  # Update the timestamp with current datetime
128
158
  self.shared.image_last_updated = datetime.datetime.now().timestamp()
129
- LOGGER.debug("%s: Image processed and stored in shared data", self.file_name)
159
+ LOGGER.debug(
160
+ "%s: Image processed and stored in shared data", self.file_name
161
+ )
162
+ return new_image
130
163
  else:
131
- LOGGER.warning("%s: Failed to generate image from JSON data", self.file_name)
132
-
133
- return new_image
164
+ LOGGER.warning(
165
+ "%s: Failed to generate image from JSON data", self.file_name
166
+ )
167
+ return (
168
+ self.shared.last_image
169
+ if hasattr(self.shared, "last_image")
170
+ else None
171
+ )
134
172
 
135
173
  except Exception as e:
136
174
  LOGGER.error(
137
- "%s: Error in async_get_pil_image: %s",
175
+ "%s: Error in async_get_image: %s",
138
176
  self.file_name,
139
177
  str(e),
140
- exc_info=True
178
+ exc_info=True,
179
+ )
180
+ return (
181
+ self.shared.last_image if hasattr(self.shared, "last_image") else None
141
182
  )
142
- return None
143
183
 
144
184
  def get_charger_position(self) -> ChargerPosition | None:
145
185
  """Return the charger position."""
@@ -337,39 +337,30 @@ class ImageDraw:
337
337
  _LOGGER.info("%s: Got zones.", self.file_name)
338
338
 
339
339
  if zone_clean:
340
- # Prepare zone drawing tasks for parallel execution
341
- zone_tasks = []
340
+ # Process zones sequentially to avoid memory-intensive array copies
341
+ # This is more memory-efficient than parallel processing with copies
342
342
 
343
343
  # Active zones
344
344
  zones_active = zone_clean.get("active_zone")
345
345
  if zones_active:
346
- zone_tasks.append(
347
- self.img_h.draw.zones(np_array.copy(), zones_active, color_zone_clean)
346
+ np_array = await self.img_h.draw.zones(
347
+ np_array, zones_active, color_zone_clean
348
348
  )
349
349
 
350
350
  # No-go zones
351
351
  no_go_zones = zone_clean.get("no_go_area")
352
352
  if no_go_zones:
353
- zone_tasks.append(
354
- self.img_h.draw.zones(np_array.copy(), no_go_zones, color_no_go)
353
+ np_array = await self.img_h.draw.zones(
354
+ np_array, no_go_zones, color_no_go
355
355
  )
356
356
 
357
357
  # No-mop zones
358
358
  no_mop_zones = zone_clean.get("no_mop_area")
359
359
  if no_mop_zones:
360
- zone_tasks.append(
361
- self.img_h.draw.zones(np_array.copy(), no_mop_zones, color_no_go)
360
+ np_array = await self.img_h.draw.zones(
361
+ np_array, no_mop_zones, color_no_go
362
362
  )
363
363
 
364
- # Execute all zone drawing tasks in parallel
365
- if zone_tasks:
366
- zone_results = await asyncio.gather(*zone_tasks)
367
- # Merge results back into the main array
368
- for result in zone_results:
369
- # Simple overlay - in practice you might want more sophisticated blending
370
- mask = result != np_array
371
- np_array[mask] = result[mask]
372
-
373
364
  return np_array
374
365
 
375
366
  async def async_draw_virtual_walls(
@@ -439,7 +430,6 @@ class ImageDraw:
439
430
  def _check_active_zone_and_set_zooming(self) -> None:
440
431
  """Helper function to check active zones and set zooming state."""
441
432
  if self.img_h.active_zones and self.img_h.robot_in_room:
442
-
443
433
  segment_id = str(self.img_h.robot_in_room["id"])
444
434
  room_store = RoomStore(self.file_name)
445
435
  room_keys = list(room_store.get_rooms().keys())
@@ -615,7 +605,6 @@ class ImageDraw:
615
605
 
616
606
  # Handle active zones - Map segment ID to active_zones position
617
607
  if self.img_h.active_zones:
618
-
619
608
  segment_id = str(self.img_h.robot_in_room["id"])
620
609
  room_store = RoomStore(self.file_name)
621
610
  room_keys = list(room_store.get_rooms().keys())
@@ -301,11 +301,17 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
301
301
 
302
302
  # Prepare path data extraction
303
303
  path_enabled = self.drawing_config.is_enabled(DrawableElement.PATH)
304
- LOGGER.info("%s: PATH element enabled: %s", self.file_name, path_enabled)
304
+ LOGGER.info(
305
+ "%s: PATH element enabled: %s", self.file_name, path_enabled
306
+ )
305
307
  if path_enabled:
306
308
  LOGGER.info("%s: Drawing path", self.file_name)
307
309
  data_tasks.append(self._prepare_path_data(m_json))
308
310
 
311
+ # Await all data preparation tasks if any were created
312
+ if data_tasks:
313
+ await asyncio.gather(*data_tasks)
314
+
309
315
  # Process drawing operations sequentially (since they modify the same array)
310
316
  # Draw zones if enabled
311
317
  if self.drawing_config.is_enabled(DrawableElement.RESTRICTED_AREA):
@@ -19,14 +19,14 @@ class ImageData:
19
19
  @staticmethod
20
20
  def sublist(lst, n):
21
21
  """Split a list into n chunks of specified size."""
22
- return [lst[i: i + n] for i in range(0, len(lst), n)]
22
+ return [lst[i : i + n] for i in range(0, len(lst), n)]
23
23
 
24
24
  @staticmethod
25
25
  def sublist_join(lst, n):
26
26
  """Join the lists in a unique list of n elements."""
27
27
  arr = np.array(lst)
28
28
  num_windows = len(lst) - n + 1
29
- result = [arr[i: i + n].tolist() for i in range(num_windows)]
29
+ result = [arr[i : i + n].tolist() for i in range(num_windows)]
30
30
  return result
31
31
 
32
32
  @staticmethod
@@ -39,15 +39,19 @@ class ImageData:
39
39
  points = obstacle.get("points", [])
40
40
  image_id = obstacle.get("metaData", {}).get("id")
41
41
  if label and points:
42
- obstacle_positions.append({
43
- "label": label,
44
- "points": {"x": points[0], "y": points[1]},
45
- "id": image_id,
46
- })
42
+ obstacle_positions.append(
43
+ {
44
+ "label": label,
45
+ "points": {"x": points[0], "y": points[1]},
46
+ "id": image_id,
47
+ }
48
+ )
47
49
  return obstacle_positions
48
50
 
49
51
  @staticmethod
50
- def find_layers(json_obj: JsonType, layer_dict: dict, active_list: list) -> tuple[dict, list]:
52
+ def find_layers(
53
+ json_obj: JsonType, layer_dict: dict, active_list: list
54
+ ) -> tuple[dict, list]:
51
55
  """Find the layers in the json object."""
52
56
  layer_dict = {} if layer_dict is None else layer_dict
53
57
  active_list = [] if active_list is None else active_list
@@ -56,7 +60,9 @@ class ImageData:
56
60
  layer_type = json_obj.get("type")
57
61
  active_type = json_obj.get("metaData")
58
62
  if layer_type:
59
- layer_dict.setdefault(layer_type, []).append(json_obj.get("compressedPixels", []))
63
+ layer_dict.setdefault(layer_type, []).append(
64
+ json_obj.get("compressedPixels", [])
65
+ )
60
66
  if layer_type == "segment":
61
67
  active_list.append(int(active_type.get("active", 0)))
62
68
  for value in json_obj.values():
@@ -121,7 +127,10 @@ class ImageData:
121
127
 
122
128
  def _recursive(obj):
123
129
  if isinstance(obj, dict):
124
- if obj.get("__class") == "LineMapEntity" and obj.get("type") == "virtual_wall":
130
+ if (
131
+ obj.get("__class") == "LineMapEntity"
132
+ and obj.get("type") == "virtual_wall"
133
+ ):
125
134
  walls.append(obj["points"])
126
135
  for value in obj.values():
127
136
  _recursive(value)
@@ -133,7 +142,9 @@ class ImageData:
133
142
  return walls
134
143
 
135
144
  @staticmethod
136
- async def async_get_rooms_coordinates(pixels: list, pixel_size: int = 5, rand: bool = False) -> tuple:
145
+ async def async_get_rooms_coordinates(
146
+ pixels: list, pixel_size: int = 5, rand: bool = False
147
+ ) -> tuple:
137
148
  """Extract the room coordinates from the vacuum pixels data."""
138
149
  df = pd.DataFrame(pixels, columns=["x", "y", "length"])
139
150
  if rand:
@@ -672,5 +672,3 @@ class ReImageHandler(BaseHandler, AutoCrop):
672
672
  async def async_copy_array(self, original_array):
673
673
  """Copy the array using async utilities."""
674
674
  return await AsyncNumPy.async_copy(original_array)
675
-
676
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: valetudo-map-parser
3
- Version: 0.1.9b68
3
+ Version: 0.1.9b69
4
4
  Summary: A Python library to parse Valetudo map data returning a PIL Image object.
5
5
  License: Apache-2.0
6
6
  Author: Sandro Cantarella
@@ -1,27 +1,27 @@
1
1
  valetudo_map_parser/__init__.py,sha256=XO_eJwFDyU7hXJ4tAa2zY-n-SM2_kmIGMWDKY3GcauY,1163
2
2
  valetudo_map_parser/config/__init__.py,sha256=DQ9plV3ZF_K25Dp5ZQHPDoG-40dQoJNdNi-dfNeR3Zc,48
3
- valetudo_map_parser/config/async_utils.py,sha256=r96x4rVis2y57KSnWfVxraSGi0cOz0fsOg-njRIggfs,3169
3
+ valetudo_map_parser/config/async_utils.py,sha256=e1j9uTtg4dhPVWvB2_XgqaH4aeSjRAPz-puRMbGoOs8,3204
4
4
  valetudo_map_parser/config/auto_crop.py,sha256=Aes7vfv4z8ihYvGaH5Nryj6Y9mHDerZLIeyvePjf9aQ,19259
5
5
  valetudo_map_parser/config/color_utils.py,sha256=nXD6WeNmdFdoMxPDW-JFpjnxJSaZR1jX-ouNfrx6zvE,4502
6
6
  valetudo_map_parser/config/colors.py,sha256=DG-oPQoN5gsnwDbEsuFr8a0hRCxmbFHObWa4_5pr-70,29910
7
- valetudo_map_parser/config/drawable.py,sha256=UpmXlCqZX_D7rqepk8IzTrzflgweLQ7n05ZeGIFRur8,37850
7
+ valetudo_map_parser/config/drawable.py,sha256=nAOoPQmNz6LJ4-WN7WF5iHTYEAzT43YVnTpiqzjNva0,41180
8
8
  valetudo_map_parser/config/drawable_elements.py,sha256=o-5oiXmfqPwNQLzKIhkEcZD_A47rIU9E0CqKgWipxgc,11516
9
9
  valetudo_map_parser/config/enhanced_drawable.py,sha256=QlGxlUMVgECUXPtFwIslyjubWxQuhIixsRymWV3lEvk,12586
10
10
  valetudo_map_parser/config/optimized_element_map.py,sha256=52BCnkvVv9bre52LeVIfT8nhnEIpc0TuWTv1xcNu0Rk,15744
11
11
  valetudo_map_parser/config/rand256_parser.py,sha256=LU3y7XvRRQxVen9iwom0dOaDnJJvhZdg97NqOYRZFas,16279
12
- valetudo_map_parser/config/shared.py,sha256=AQ73878TGCxbHQhgrAxSROLqFE-Zz4fJhTdoi9gBvJo,12736
12
+ valetudo_map_parser/config/shared.py,sha256=98CgGDY0tbc5BSg2TIHbGcDFZZ2acgIYnoPjAwENmBU,12885
13
13
  valetudo_map_parser/config/types.py,sha256=saL7pULKAdTRQ_ShR2arT8IV472e9MBC_SohTthlGp8,17567
14
- valetudo_map_parser/config/utils.py,sha256=MR1UIOwHWYJ8lFrPYhfyi9IV7C08S-DqCyIPppsB2tM,33913
15
- valetudo_map_parser/hypfer_draw.py,sha256=ZK_WybvukHd8nNk2mq5icrOu1Ue3SVCIC6_Hc9bTg0Q,29396
16
- valetudo_map_parser/hypfer_handler.py,sha256=f9SCphArA-LO2ySrTKpxn6k4htM-JRrbrxKFh3AjnD8,23171
14
+ valetudo_map_parser/config/utils.py,sha256=lRLvQbqCQ44knnIJr-UAlkEOO1d14mFCmHKDor989VE,35468
15
+ valetudo_map_parser/hypfer_draw.py,sha256=vlrfBSDpHNnjh0dRA1BE5_4MsKMMWS_O1QErrd-VRKE,28995
16
+ valetudo_map_parser/hypfer_handler.py,sha256=U452BEi3kmU0O27aNN7BY42J_zrpjhDuebpqxwGxe50,23366
17
17
  valetudo_map_parser/hypfer_rooms_handler.py,sha256=NkpOA6Gdq-2D3lLAxvtNuuWMvPXHxeMY2TO5RZLSHlU,22652
18
- valetudo_map_parser/map_data.py,sha256=Op0LTCakcTJ1Q0rxQhl6BpgSby_6nJenCQS2Y2FHtRk,17243
18
+ valetudo_map_parser/map_data.py,sha256=Flq5t9QQQiD5ylObIniHhPP1VB7VhNoMcMeJrOey3Go,17433
19
19
  valetudo_map_parser/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- valetudo_map_parser/rand256_handler.py,sha256=6Qt-xFJ3PITQNSAJTaEo6jl6TdgFms7ay1rnk4vekgk,27653
20
+ valetudo_map_parser/rand256_handler.py,sha256=daaSQ5ktMUYMnYxJkjS75UdBchpXVZ58HIomwHBFivs,27651
21
21
  valetudo_map_parser/reimg_draw.py,sha256=1q8LkNTPHEA9Tsapc_JnVw51kpPYNhaBU-KmHkefCQY,12507
22
22
  valetudo_map_parser/rooms_handler.py,sha256=ovqQtAjauAqwUNPR0aX27P2zhheQmqfaFhDE3_AwYWk,17821
23
- valetudo_map_parser-0.1.9b68.dist-info/LICENSE,sha256=Lh-qBbuRV0-jiCIBhfV7NgdwFxQFOXH3BKOzK865hRs,10480
24
- valetudo_map_parser-0.1.9b68.dist-info/METADATA,sha256=hBV8Inc5QpIw-TcGWC-sLqhRb60TlFq1OVkMmm1iBek,3353
25
- valetudo_map_parser-0.1.9b68.dist-info/NOTICE.txt,sha256=5lTOuWiU9aiEnJ2go8sc7lTJ7ntMBx0g0GFnNrswCY4,2533
26
- valetudo_map_parser-0.1.9b68.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
27
- valetudo_map_parser-0.1.9b68.dist-info/RECORD,,
23
+ valetudo_map_parser-0.1.9b69.dist-info/LICENSE,sha256=Lh-qBbuRV0-jiCIBhfV7NgdwFxQFOXH3BKOzK865hRs,10480
24
+ valetudo_map_parser-0.1.9b69.dist-info/METADATA,sha256=Ex2vOq_SjHDzJqk5dNNL78hXqOnkhz9Y7anOUC-XsmE,3353
25
+ valetudo_map_parser-0.1.9b69.dist-info/NOTICE.txt,sha256=5lTOuWiU9aiEnJ2go8sc7lTJ7ntMBx0g0GFnNrswCY4,2533
26
+ valetudo_map_parser-0.1.9b69.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
27
+ valetudo_map_parser-0.1.9b69.dist-info/RECORD,,