import json import re import logging from typing import Iterable, Final, Any import copy import datetime import os import voluptuous as vol import struct import numpy as np import collections import math from io import BytesIO from PIL import Image, ImageDraw from random import SystemRandom from homeassistant.components import mqtt from homeassistant.components.mqtt.models import ReceiveMessage from homeassistant.helpers.entity import DeviceInfo, EntityCategory from homeassistant.util import slugify from homeassistant.core import HomeAssistant, callback, ServiceCall from homeassistant.config_entries import ConfigEntry from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers import config_validation as cv, entity_platform from homeassistant.components.image import ImageEntity, DOMAIN, ImageEntityDescription #from homeassistant.components.camera import Camera, DOMAIN, CameraEntityDescription, CameraEntityFeature from homeassistant.helpers.typing import ( UNDEFINED, ) from .common import PolarisBaseEntity # Import global values. from .const import ( MANUFACTURER, MQTT_ROOT_TOPIC, DEVICEID, DEVICETYPE, POLARIS_DEVICE, CUSTOM_SELECT_FILE_PATH, PolarisImageEntityDescription, POLARIS_VACUUM_TYPE, IMAGE, ) DEFAULT_IMAGE_WIDTH = 500 DEFAULT_IMAGE_HEIGHT = 500 DEFAULT_RECTANGLE_COLOR = 'red' ATTR_GENERATED_AT = "access_token" _RND: Final = SystemRandom() _LOGGER = logging.getLogger(__name__) _LOGGER.setLevel(logging.DEBUG) async def async_setup_entry( hass: HomeAssistant, config: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: integrationUniqueID = config.unique_id mqtt_root = config.data[MQTT_ROOT_TOPIC] device_id = config.data["DEVICEID"] device_type = config.data[DEVICETYPE] device_prefix_topic = config.data["DEVPREFIXTOPIC"] imageList = [] if (device_type in POLARIS_VACUUM_TYPE): IMAGE_LC = copy.deepcopy(IMAGE) for description in IMAGE_LC: description.mqttTopicCommandGoArea = f"{mqtt_root}/{device_prefix_topic}/{description.mqttTopicCommandGoArea}" imageList.append( PolarisImage( description=description, device_friendly_name=device_id, mqtt_root=mqtt_root, device_type=device_type, device_id=device_id, ) ) async_add_entities(imageList, update_before_add=True) class PolarisImage(PolarisBaseEntity, ImageEntity): entity_description: PolarisImageEntityDescription def __init__( self, device_friendly_name: str, description: PolarisImageEntityDescription, mqtt_root: str, device_id: str | None=None, device_type: str | None=None, ) -> None: super().__init__( device_friendly_name=device_friendly_name, mqtt_root=mqtt_root, device_type=device_type, device_id=device_id, ) self.entity_description = description self._attr_unique_id = slugify(f"{device_id}_{description.name}") self.entity_id = f"{DOMAIN}.{POLARIS_DEVICE[int(device_type)]['class']}_{POLARIS_DEVICE[int(device_type)]['model']}_{description.name}" self._attr_has_entity_name = True self._available = True self._last_update = False self._attr_model = "polaris" self.access_tokens: collections.deque = collections.deque([], 2) # self._name = name # self._entity_id = entity_id self._image = None self._attr_content_type = "image/png" self.async_update_token() # self._generated_at = None self._custom_data_select = self._read_file() self.coord_rooms = {} if self._custom_data_select is not None: if POLARIS_DEVICE[int(self.device_type)]['class'] == "cleaner" and "SELECT_VACUUM_rooms" in self._custom_data_select: for key, value in self._custom_data_select["SELECT_VACUUM_rooms"].items(): self.coord_rooms[key] = value["coordinate"] _LOGGER.debug("rooms %s", self.coord_rooms) def image(self) -> bytes | None: """Return bytes of image.""" # if self._image: # return self._image # Создание изображения img = Image.new('RGB', (DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT), color='#c4c4c4') d = ImageDraw.Draw(img) rectangles = [] for key, value in self.coord_rooms.items(): rectangles.append(value) # _LOGGER.debug("rectangles %s", rectangles) self.draw_quadrilaterals(d, value, angle=89, color="yellow") no_go_area = b'\x018\x00\x04\x00:\x00\x9e\xffk\x00\x9f\xffj\x00\x05\x00\x01\x1f\x00N\x00\x1f\x00?\x00t\x00A\x00s\x00O\x00\x01d\x00\x93\x00e\x00P\x00v\x00P\x00u\x00\x94\x00\x01\x1e\x00\x93\x00\x1f\x00\x85\x00`\x00\x87\x00`\x00\x94\x00\x00\x17\x00\x84\x00\x18\x00N\x00%\x00O\x00$\x00\x84\x00\x00-\x00,\x00-\x00 \x00[\x00!\x00Z\x00,\x00\x00\xfb\xff\xc8\xff\xfc\xff\x9f\xff\t\x00\x9f\xff\x08\x00\xc8\xff\x01\x83\xff\x8d\x00\x85\xff>\x00\xa2\xff>\x00\xa1\xff\x8d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # _LOGGER.debug("no go area %s", self.parse_no_go_area(no_go_area)) for i in range(0, len(self.parse_no_go_area(no_go_area)["coord_area"])): self.draw_quadrilaterals(d, self.parse_no_go_area(no_go_area)["coord_area"][i], angle=89, color="red" if self.parse_no_go_area(no_go_area)["type_area"][i] == 0 else "blue") #Поиск маршрута bbuf = b'\x00\x98\x00\xd0\x01~\x03\xa32\x01\x11\x03\xbd\x02\x01\t\x03\'\x01\x01\x02\x05\x01\x01\x02\t\x01\x01\x03\xbd\x02\x01\x01\x02\x07\x01\x01\x03&\x01\x01\x02\x06\x01\x01\x02\t\x01\x01\x03\xbd\x02\x01\x01\x02\x07\x01\x01\x03&\x01\x01\x02\x06\x01\x01\x02\t\x01\x01\x03\xbd\x02\x01\x01\x02\x07\x01\x08\x03\x1f\x01\x01\x02\x06\x01\x01\x02\t\x01\x01\x03\xbd\x02\x01\x01\x02\x0e\x01\x01\x03\x1f\x01\x01\x02\x06\x01\x01\x02\t\x01\x01\x03\xbd\x02\x01\x01\x02\x0e\x01\x02\x03\x1e\x01\x01\x02\x06\x01\x01\x02\t\x01\x01\x03\xbd\x02\x01\x07\x02\t\x01\x01\x03\x1e\x01\x01\x02\x10\x01\x05\x03\xbc\x02\x01\x02\x02\x0b\x01\x05\x03\x1a\x01\x01\x02\x14\x01\x01\x03\xbc\x02\x01\x01\x02\x10\x01\x01\x03\x1a\x01\x01\x02\x14\x01\x01\x03d\x01\x12\x03\xc6\x01\x01\x01\x02\x10\x01\x01\x03\x1a\x01\x01\x02\x14\x01\x01\x03d\x01\x01\x02\x10\x01\x01\x03\xc6\x01\x01\x01\x02\x10\x01\x01\x03\x1a\x01\x01\x02\x14\x01\x01\x03d\x01\x01\x02\x10\x01\x01\x03\xc6\x01\x01\x01\x02\x10\x01\x01\x03\x1a\x01\x01\x02\x14\x01\x01\x03d\x01\x01\x02\x11\x01\x03\x03\xc2\x01\x01\x02\x02\x10\x01\x01\x03\x1a\x01\x01\x02\x14\x01\x01\x03d\x01\x01\x02\x13\x01\x01\x03\xc2\x01\x01\x01\x02\x11\x01\x01\x03\x1a\x01\x01\x02\x14\x01\x01\x03d\x01\x01\x02\x13\x01\x06\x03\xbd\x01\x01\x01\x02\x11\x01\x1d\x02\x13\x01\x01\x03d\x01\x01\x02\x18\x01\x01\x03\xba\x01\x01\x04\x02\x11\x01\x1e\x02\x12\x01\x01\x03d\x01\x01\x02\x18\x01"\x03\x93\x01\x01\x07\x02D\x01\x01\x03d\x01\x01\x029\x01\x01\x03\x93\x01\x01\x01\x02:\x01\x02\x02\x0e\x01\x01\x03d\x01\x01\x029\x01\x01\x03\x93\x01\x01\x01\x02F\x01\x06\x03c\x01\x01\x029\x01\x01\x03\x93\x01\x01\x01\x02\x0b\x01\x01\x02\n\x01\x02\x02.\x01\x0f\x03Z\x01\x01\x029\x01\x01\x03\x93\x01\x01\x01\x02\x16\x01\x02\x02<\x01\x01\x03Z\x01\x01\x029\x01p\x03$\x01\x01\x02T\x01\x01\x03Z\x01\x01\x02\xa8\x01\x01\x01\x03"\x01\x03\x02T\x01\x01\x03Z\x01\x01\x02\xa8\x01\x01\x01\x03"\x01\x01\x02V\x01\x01\x03Z\x01\x01\x02\xa8\x01\x01\x01\x03 \x01\x03\x02V\x01\x01\x03Z\x01\x01\x02\xa8\x01\x01\x01\x03 \x01\x01\x02X\x01\x01\x03Z\x01\x01\x02\xa8\x01\x01\x01\x03\x1e\x01\x03\x02X\x01\x02\x03S\x01\x07\x02\xa8\x01\x01\x01\x03\x1e\x01\x01\x02[\x01\x01\x03S\x01\x01\x02\xae\x01\x01\x01\x03\x1c\x01\x03\x02[\x01\x01\x03S\x01\x01\x02?\x01\x02\x02m\x01\x01\x03\x1c\x01\x01\x02]\x01\x01\x03S\x01\x01\x02\xae\x01\x01\x01\x03\x1b\x01\x02\x02]\x01\x01\x03S\x01\x01\x02\xae\x01\x01\x01\x03\x1b\x01\x02\x02]\x01\x01\x03S\x01\x01\x02\x11\x01\x01\x02\x9c\x01\x01\x01\x03\x1b\x01\x02\x02]\x01\x01\x03S\x01\x01\x02\x11\x01\x01\x02\x9c\x01\x01\x01\x03\x1b\x01\x02\x02]\x01\x02\x03R\x01\x01\x02\x11\x01\x01\x02\x9c\x01\x01\x01\x03\x1b\x01\x02\x02^\x01\x01\x03R\x01\x01\x02\x11\x01\x01\x02\x9c\x01\x01\x01\x03\x1b\x01\x02\x02^\x01\x01\x03R\x01\x01\x02\x11\x01\x01\x02\x9c\x01\x01\x01\x03\x1b\x01\x02\x02^\x01\x04\x03O\x01\x01\x02\x11\x01\x02\x02\x06\x01\x02\x02\x93\x01\x01\x01\x03\x1b\x01\x02\x02a\x01\x04\x03L\x01\x01\x02\x10\x01\n\x02\x94\x01\x01\x01\x03\x1b\x01\x01\x02e\x01\x01\x03L\x01\x01\x02\n\x01\t\x03\x03\x01\x02\x02\x96\x01\x01\x01\x03\x1b\x01\x01\x02e\x01\x01\x03L\x01\x01\x02\x12\x01\x01\x03\x03\x01\x01\x02\x80\x01\x01\x06\x02\x11\x01\x01\x03\x1b\x01\x01\x02e\x01\x01\x03L\x01\x01\x02\x12\x01\x05\x02\x97\x01\x01\x01\x03\x19\x01\x03\x02e\x01\x01\x03L\x01\x01\x02\xae\x01\x01\x01\x03\x18\x01\x02\x02g\x01\x01\x03L\x01\x01\x02\x8b\x01\x01\x02\x02\x11\x01\x05\x02\x0b\x01\x01\x03\r\x01\x0b\x02U\x01\x01\x02\x13\x01\x01\x03L\x01\x01\x02\x9e\x01\x01\x01\x03\x03\x01\x05\x02\x07\x01\x01\x03\x07\x01\x07\x02)\x01\x02\x024\x01\x01\x02\x13\x01\x01\x03L\x01\x01\x02\x17\x01\x01\x02\x86\x01\x01\x01\x03\x07\x01\x01\x02\x07\x01\x01\x03\x07\x01\x01\x02\x05\x01\x01\x02)\x01\x02\x024\x01\x01\x02\x13\x01\x01\x03L\x01\x01\x02\x0f\x01\x01\x02\x07\x01\x01\x02\x86\x01\x01\t\x02\x07\x01\x01\x03\x07\x01\x01\x02\x05\x01\x01\x02)\x01\x02\x02H\x01\x01\x03L\x01\x01\x02\x0e\x01\x01\x02\x08\x01\x01\x02h\x01\x01\x02-\x01\x01\x03\x07\x01\x01\x02\x05\x01\x01\x02B\x01\x04\x02-\x01\x01\x03L\x01\x01\x02\x17\x01\x01\x02h\x01\x02\x02,\x01\x01\x03\x07\x01\x01\x02H\x01\x01\x03\x02\x01\x01\x02-\x01\x01\x03L\x01\x01\x02\x17\x01\x01\x02\x96\x01\x01\x01\x03\x07\x01\x01\x02H\x01\x01\x03\x02\x01\x01\x02-\x01\x01\x03L\x01\x01\x02\x16\x01\x13\x02\x85\x01\x01\x01\x03\x07\x01\x01\x02H\x01\x01\x03\x02\x01\x01\x02-\x01\x01\x03L\x01\x01\x02\x14\x01\x02\x03\x12\x01\x01\x02\x85\x01\x01\x01\x03\x07\x01\x01\x02H\x01\x02\x03\x01\x01\x01\x02-\x01\x01\x03L\x01\x01\x02\x14\x01\x01\x03\x13\x01\x01\x02\x85\x01\x01\x01\x03\x07\x01\x01\x02I\x01\x01\x03\x01\x01\x01\x02-\x01\x01\x03L\x01\x01\x02\x14\x01\x01\x03\x13\x01\x01\x02\x85\x01\x01\x01\x03\x07\x01\x01\x02I\x01\x01\x03\x01\x01\x01\x02-\x01\x01\x03L\x01\x01\x02\x13\x03\x15\x01\x01\x02g\x01\x01\x02\x1d\x01\x01\x03\x07\x01\x01\x02I\x01\x03\x02-\x01\x01\x03L\x01\x01\x02\x13\x03\x07\x01\x0f\x02g\x01\x01\x02\x1d\x01\x01\x03\x07\x01\x01\x02J\x01\x02\x02-\x01\x01\x03L\x01\x01\x02\x12\x03\x08\x01\x01\x02\x93\x01\x01\x01\x03\x07\x01\x01\x02y\x01\x01\x03L\x01\x01\x02\x11\x03\t\x01\x01\x02\x93\x01\x01\x01\x03\x07\x01\x01\x02y\x01\x01\x03L\x01\x01\x02\x11\x03\t\x01\x01\x02\x93\x01\x01\x01\x03\x07\x01\x01\x02y\x01\x01\x03L\x01\x01\x02\x11\x03\t\x01\x01\x02j\x01\x01\x02(\x01\x01\x03\x07\x01\x01\x02y\x01\x01\x03L\x01\x01\x02\x11\x03\t\x01\x01\x02\x93\x01\x01\x01\x03\x07\x01\x01\x02y\x01\x01\x03L\x01\x01\x02\x11\x03\t\x01\x01\x02\x93\x01\x01\x01\x03\x07\x01\x01\x02y\x01\x01\x03L\x01\x01\x02\x11\x03\t\x01\x01\x02\x93\x01\x01\x01\x03\x07\x01\x01\x02y\x01\x01\x03L\x01\x01\x02\x11\x03\t\x01\x01\x02\x93\x01\x01\x01\x03\x07\x01\x01\x02K\x01\x01\x02-\x01\x01\x03L\x01\x01\x02\x11\x03\t\x01\x01\x02\x93\x01\x01\x01\x03\x07\x01\x01\x02K\x01\x01\x02-\x01\x01\x03L\x01\x01\x02\x11\x03\t\x01\x01\x02\x93\x01\x01\x01\x03\x07\x01\x01\x02u\x01\x01\x02\x03\x01\x01\x03L\x01\x01\x02\x11\x03\t\x01\x01\x02\x93\x01\x01\x01\x03\x07\x01\x01\x02u\x01\x01\x02\x03\x01\x01\x03L\x01\x01\x02\x11\x03\t\x01\t\x02\x8b\x01\x01\x01\x03\x07\x01\x01\x02u\x01\x01\x02\x03\x01\x01\x03L\x01\x01\x02\x11\x03\x11\x01\x01\x02\x8b\x01\x01\x01\x03\x07\x01\x01\x02u\x01\x01\x02\x03\x01\x01\x03L\x01\x01\x02\x11\x03\x11\x01\x01\x02\x82\x01\x01\x02\x02\x07\x01\x01\x03\x07\x01\x01\x02u\x01\x01\x02\x03\x01\x01\x03L\x01\x01\x02\x11\x03\x11\x01\x01\x02\x8b\x01\x01\x01\x03\x07\x01\x01\x02s\x01\x03\x02\x03\x01\x01\x03L\x01\x01\x02\x11\x03\x11\x01\x02\x02\x8a\x01\x01\x01\x03\x07\x01\x01\x02s\x01\x01\x03\x01\x01\x05\x03L\x01\x01\x02\x11\x03\x12\x01\x01\x02\x8a\x01\x01\x01\x03\x07\x01\x01\x02s\x01\x01\x03R\x01\x01\x02\x0e\x03\x15\x01\x01\x02\x8a\x01\x01\x01\x03\x07\x01\x01\x02s\x01\x01\x03R\x01\x01\x02\x0e\x03\x15\x01\x01\x02\n\x01\x01\x02\x7f\x01\x01\x03\x07\x01\x01\x02s\x01\x01\x03R\x01\x01\x02\x0e\x03\x15\x01\x0b\x02\x80\x01\x01\x01\x03\x07\x01\x01\x02s\x01\x01\x03R\x01\x01\x02\x06\x01\x07\x03\x1f\x01\x01\x02\x81\x01\x01\x01\x03\x07\x01\x01\x02s\x01\x01\x03R\x01\x01\x02\x06\x01\x01\x03%\x01\x01\x02\x81\x01\x01\x01\x03\x07\x01\x01\x02q\x01\x03\x03S\x02\x06\x01\x01\x03%\x01\x01\x02\x81\x01\x01\x01\x03\x07\x01\x01\x02q\x01\x01\x03U\x02\x06\x01\x01\x03%\x01\x01\x02\x81\x01\x01\x01\x03\x07\x01\x01\x02q\x01\x01\x03\x81\x01\x01\x01\x02\x81\x01\x01\x01\x03\x07\x01\x01\x02q\x01\x01\x03\x81\x01\x01\x01\x02\x81\x01\x01\x01\x03\x07\x01\x01\x02q\x01\x03\x03\x7f\x01\x01\x02\x81\x01\x01\x01\x03\x07\x01\x01\x02s\x01\x01\x03\x7f\x01\x01\x02\x81\x01\x01\x01\x03\x07\x01\x01\x02s\x01\x01\x03\x7f\x01\x01\x02\x81\x01\x01\x01\x03\x07\x01\x01\x02s\x01\x01\x03\x7f\x01\x01\x02\x81\x01\x01\x01\x03\x07\x01\x01\x02s\x01\x01\x03\x7f\x01\x01\x02!\x01=\x02#\x01\x01\x03\x07\x01\x01\x02s\x01\x01\x03\x7f\x01\x01\x02 \x01\x01\x03<\x01\x01\x02#\x01\x01\x03\x07\x01\x01\x02s\x01\x01\x03\x7f\x01\x01\x02\x16\x01\n\x03=\x01\x01\x02#\x01\x01\x03\x07\x01\x01\x02s\x01\x01\x03\x7f\x01\x01\x02\x14\x01\x03\x03F\x01\x01\x02 \x01\x04\x03\x07\x01\x01\x02s\x01\x01\x03\x7f\x01\x01\x02\x14\x01\x01\x03H\x01\x03\x02\x1c\x01\x03\x03\n\x01\x01\x02s\x01\x01\x03\x7f\x01\x01\x02\x14\x01\x01\x03J\x01\x01\x02\x1d\x01\x02\x03\n\x01\x01\x02s\x01\x01\x03\x7f\x01\x01\x02\x14\x01\x01\x03J\x01\x01\x02\x1e\x01\x01\x03\n\x01\x01\x02s\x01\x02\x03~\x01\x01\x02\x14\x01\x02\x03I\x01\x01\x02\x1e\x01\x02\x03\t\x01\x01\x02t\x01\x01\x03~\x01\x01\x02\x15\x01\x01\x03I\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02K\x01\x01\x02(\x01\x01\x03~\x01\x01\x02\x15\x01\x01\x03I\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02t\x01\x01\x03~\x01\x0b\x02\x0b\x01\x01\x03I\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02t\x01\x04\x03\x85\x01\x01\x01\x02\x0b\x01\x01\x03I\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02w\x01\x01\x03\x85\x01\x01\x04\x02\x08\x01\x01\x03I\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02w\x01\x01\x03\x88\x01\x01\x01\x02\x08\x01\x01\x03I\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02w\x01\x01\x03\x88\x01\x01\x01\x02\x08\x01\x01\x03I\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02+\x01\x01\x02?\x01\x01\x02\x0b\x01\x03\x03\x86\x01\x01\n\x03I\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02\x1f\x01\x01\x02\x0b\x01\x01\x02M\x01\x01\x03\xd9\x01\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02\x1f\x01\x01\x02Y\x01\x01\x03\xd9\x01\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02y\x01\x01\x03\xd9\x01\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02y\x01\x01\x03\xd9\x01\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02y\x01\x01\x03\xd9\x01\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02y\x01\x01\x03\xd9\x01\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02+\x01\x0b\x02C\x01\x01\x03\xd9\x01\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02+\x01\x01\x03\t\x01\x01\x02C\x01\x01\x03\xd9\x01\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02+\x01\x01\x03\t\x01\x01\x02C\x01\x01\x03\xd9\x01\x01\x01\x02\x1f\x01\x01\x03\t\x01\x01\x02%\x01\x07\x03\t\x01\x02\x02B\x01\x01\x03\xd9\x01\x01\x02\x02\x1e\x01\x02\x03\x08\x01\x01\x02%\x01\x01\x03\x10\x01\x01\x02@\x01\x03\x03\xda\x01\x01\x01\x02\x1f\x01\x01\x03\x08\x01\x01\x02\x1e\x01\x01\x02\x06\x01\x01\x03\x10\x01\x01\x02@\x01\x01\x03\xdc\x01\x01\x01\x02\x1f\x01\x01\x03\x08\x01\x01\x02\x1e\x01\x01\x02\x06\x01\x01\x03\x10\x01B\x03\xdc\x01\x01\x01\x02\x1f\x01\x01\x03\x08\x01\x01\x02\x1e\x01\x02\x02\x05\x01\x01\x03\xae\x02\x01\x01\x02\x1f\x01\x01\x03\x08\x01\x01\x02\x1b\x01\x0b\x03\xae\x02\x01\x05\x02\x1b\x01\x02\x03\x07\x01\x01\x02\x19\x01\x02\x03\xbd\x02\x01\x01\x02\x1c\x01\x01\x03\x07\x01\x01\x02\x19\x01\x01\x03\xbe\x02\x01\x01\x02\x1c\x01\x01\x03\x07\x01\x01\x02\x19\x01\x01\x03\xbe\x02\x01\x01\x02\x1c\x01\x01\x03\x07\x01\x01\x02\x19\x01\x01\x03\xbe\x02\x01\x01\x02\x1c\x01\t\x02\x19\x01\x01\x03\xbe\x02\x01\x01\x02>\x01\x01\x03\xbe\x02\x01\x01\x02>\x01\x01\x03\xb8\x02\x01\x07\x02>\x01\x07\x03\xb2\x02\x01\x01\x02E\x01\x02\x02\x03\x01\x01\x03\xc1\x01\x01\x1c\x03U\x01\x01\x02E\x01\x01\x02\x04\x01\x01\x03\xc1\x01\x01\x01\x02\x1a\x01\x14\x03.\x01\x15\x02E\x01\x01\x02\x04\x01\x01\x03\xc1\x01\x01\x01\x02\x1a\x01\x02\x02\x11\x01\x01\x03.\x01\x01\x02Y\x01\x01\x02\x04\x01\x01\x03\xc1\x01\x01\x01\x02\x1a\x01\x01\x02\x12\x01\x01\x03.\x01\x01\x02Y\x01\x01\x02\x04\x01\x01\x03\xc1\x01\x01\x01\x02\x1a\x01\x01\x02\x12\x01\x01\x03.\x01\x01\x02Y\x01\x01\x02\x04\x01\x01\x03\xc1\x01\x01\x01\x02\x1a\x01\x01\x02\x12\x01\x01\x03.\x01\x01\x02Y\x01\x01\x02\x04\x01\x01\x03\xc1\x01\x01\x01\x02\x1a\x01\x01\x02\x12\x01\x0f\x03 \x01\x01\x02Y\x01\x01\x02\x04\x01\x01\x03\xc1\x01\x01\x01\x02\x1a\x01\x01\x02 \x01\x01\x03 \x01\x01\x02Y\x01\x01\x02\x04\x01\x01\x03\xc1\x01\x01\x01\x02\x1a\x01\x01\x02 \x01\x01\x03 \x01\x01\x02^\x01\x01\x03\xc1\x01\x01\x01\x02\x1a\x01\x01\x02 \x01\x01\x03 \x01\x01\x02^\x01\x01\x03\xc1\x01\x01\x01\x02\x1a\x01\x01\x02!\x01\x01\x03\x1f\x01\x01\x02^\x01\x01\x03\xbb\x01\x01\x07\x02\x1a\x01\x01\x02!\x01\x05\x03\x1b\x01\x01\x02^\x01\x01\x03\xbb\x01\x01\x01\x02 \x01\x01\x02%\x01\x01\x03\x1b\x01\x01\x02^\x01\x01\x03\xbb\x01\x01\x01\x02 \x01\x02\x02%\x01\x01\x03\x1a\x01\x01\x02^\x01\x01\x03\xbb\x01\x01\x01\x02 \x01\x03\x02$\x01\x01\x03\x13\x01\x08\x02^\x01\x01\x03\xbb\x01\x01\x01\x02 \x01\x03\x02$\x01\x01\x03\x13\x01\x01\x02e\x01\x01\x03\xbb\x01\x01\x01\x02 \x01\x03\x02$\x01\x01\x03\x13\x01\x01\x02e\x01\x01\x03\xa8\x01\x01\x14\x02 \x01\x03\x02$\x01\x01\x03\x13\x01\x01\x02e\x01\x01\x03\xa8\x01\x01\x01\x025\x01\x01\x02$\x01\x15\x02e\x01\x01\x03\xa8\x01\x01\x01\x02\xd4\x01\x01\x01\x03\xa8\x01\x01\x01\x02\xcf\x01\x01\x06\x03\xa8\x01\x01\x01\x02\xcf\x01\x01\x01\x03\x84\x01\x01\x1e\x03\x0b\x01\x01\x02\xcf\x01\x01\x01\x03\x84\x01\x01\x01\x02\x1c\x01\x01\x03\x0b\x01\x02\x02\xce\x01\x01\x01\x03\x84\x01\x01\x01\x02\x1c\x01\x01\x03\x0c\x01\x01\x02\xcb\x01\x01\x04\x03\x84\x01\x01\x01\x02\x1c\x01\x01\x03\x0c\x01\x01\x02\xcb\x01\x01\x01\x03\x87\x01\x01\x01\x02\x1c\x01\x01\x03\x0c\x01\x01\x02\xcb\x01\x01\x01\x03\x87\x01\x01\x01\x02\x1c\x01\x02\x03\x0b\x01\x01\x02\xcb\x01\x01\x01\x03\x87\x01\x01\x01\x02\x1e\x01\x05\x03\x06\x01\x01\x02\xcb\x01\x01\x01\x03\x87\x01\x01\x01\x02"\x01\x01\x03\x06\x01\x01\x02\xcb\x01\x01\x01\x03\x87\x01\x01\x01\x02"\x01\x01\x03\x06\x01\x01\x02\xcb\x01\x01\x01\x03\x87\x01\x01\x01\x02"\x01\x01\x03\x06\x01\x01\x02\xcb\x01\x01\x01\x03\x87\x01\x01\x01\x02"\x01\x01\x03\x06\x01\x01\x02\xcb\x01\x01\x01\x03\x87\x01\x01\x01\x02#\x01\x01\x03\x05\x01\x01\x02\xcb\x01\x01\x01\x03\x87\x01\x01\x01\x02#\x01\x05\x03\x01\x01\x01\x022\x01\x03\x02\x8f\x01\x01\x08\x03\x87\x01\x01\x01\x02\'\x01\x01\x03\x01\x01\x01\x022\x01\x01\x03\x01\x01\x01\x02\x92\x01\x01\x01\x03\x8b\x01\x01\x01\x02\'\x01\x04\x02\x0e\x01\x04\x02\x1f\x01\x03\x02\x92\x01\x01\x01\x03\x8b\x01\x01\x01\x02\'\x01\x11\x02\xb9\x01\x01\x01\x03\x8b\x01\x01\x01\x02\xbe\x01\x01\x01\x022\x01\x01\x03\x8b\x01\x01\x01\x02\xbe\x01\x01\x01\x022\x01\x02\x03\x8a\x01\x01\x01\x02\xbd\x01\x01\x04\x022\x01\x06\x03\x84\x01\x01\x01\x02\xac\x01\x01\x11\x03\x03\x01\x01\x027\x01\x01\x03\x84\x01\x01\x01\x02\xac\x01\x01\x01\x03\x13\x01\x01\x027\x01\x01\x03\x84\x01\x01\x01\x02\xac\x01\x01\x01\x03\x13\x01\x01\x027\x01\x01\x03\x84\x01\x01\x01\x02\xac\x01\x01\x01\x03\x13\x01\x03\x025\x01\x01\x03\x84\x01\x01\x01\x02\xa7\x01\x01\x06\x03\x14\x01\x02\x025\x01\x01\x03\x84\x01\x01\x01\x02\xab\x01\x01\x01\x03\x15\x01\x02\x025\x01\x01\x03\x84\x01\x01\x01\x02\xab\x01\x01\x01\x03\x15\x01\x02\x025\x01\x01\x03\x84\x01\x01\x01\x02\xab\x01\x01\x01\x03\x15\x01\x02\x025\x01\x01\x03\x84\x01\x01\x01\x02\xab\x01\x01\x01\x03\x15\x01\x02\x021\x01\x06\x03\x83\x01\x01\x01\x02\xab\x01\x01\x01\x03\x15\x01\x02\x021\x01\x0f\x03z\x01\x01\x02\xab\x01\x01\x01\x03\x0f\x01\x08\x02?\x01B\x039\x01\x02\x02\xaa\x01\x01\x01\x03\x0f\x01\x01\x02\x06\x01\x01\x02\x80\x01\x01\x01\x03:\x01\x01\x02\xaa\x01\x01\x01\x03\r\x01\x03\x02\x06\x01\x01\x02\x80\x01\x01\x01\x03:\x01\x01\x02\xaa\x01\x01\x01\x03\r\x01\x01\x02\x89\x01\x01\x01\x03:\x01\x17\x02\x94\x01\x01\x01\x03\r\x01\x01\x02\x89\x01\x01\x01\x03P\x01\x01\x02\x94\x01\x01\x01\x03\r\x01\x01\x02\x89\x01\x01\x01\x03P\x01\x01\x02\x94\x01\x01\x01\x03\r\x01\x01\x02\x89\x01\x01\x01\x03P\x01\x01\x02\x7f\x01\x16\x03\r\x01\x01\x02\x89\x01\x01\x01\x03P\x01\x07\x02y\x01\x01\x03"\x01\x01\x02\x89\x01\x01\x01\x03V\x01\x01\x02s\x01\x07\x03"\x01\x01\x02\x89\x01\x01\x01\x03V\x01\x0c\x02*\x01?\x03(\x01\x01\x02\x89\x01\x01\x01\x03a\x01\x01\x02\x18\x01;\x02\x15\x01\x05\x03$\x01\x01\x02\x89\x01\x01\x01\x03a\x01\x01\x02\r\x01\x0c\x035\x01\x02\x02\x1c\x01\x01\x03$\x01\x01\x02\x89\x01\x01\x01\x03a\x01\x01\x02\t\x01\x05\x03@\x01\x01\x02\x1d\x01\x01\x03$\x01\x01\x02\x89\x01\x01\x01\x03a\x01\x01\x02\t\x01\x01\x03D\x01\x01\x02\x1d\x01\x01\x03$\x01\x01\x02\x89\x01\x01\x01\x03a\x01\x01\x02\t\x01\x01\x03D\x01\x01\x02\x1d\x01\x01\x03$\x01\x01\x02\x89\x01\x01\x01\x03a\x01\x01\x02\x07\x01\x03\x03D\x01\x01\x02\x1d\x01\x01\x03$\x01\x01\x02\x89\x01\x01\x01\x03a\x01\x01\x02\x07\x01\x01\x03F\x01\x01\x02\x1d\x01\x01\x03$\x01\x01\x02\x89\x01\x01\x01\x03a\x01\t\x03F\x01\x01\x02\x1d\x01\x01\x03$\x01\x01\x02\x89\x01\x01\x01\x03\xb0\x01\x01\x01\x02\x1d\x01\x01\x03$\x01\x01\x02\x89\x01\x01\x01\x03\xb0\x01\x01\x01\x02\x1d\x01\x01\x03$\x01\x01\x02\x89\x01\x01\x01\x03\xb0\x01\x01\x01\x02\x1d\x01\x01\x03$\x01\x01\x02\x89\x01\x01\x01\x03\xb0\x01\x01\x05\x02\x15\x01\x05\x03$\x01\x01\x02\x89\x01\x01\x01\x03\xb4\x01\x01\x01\x02\x15\x01\x01\x03(\x01\x01\x02\x89\x01\x01\x01\x03\xb4\x01\x01\x17\x03(\x01\x01\x02\x89\x01\x01\x01\x03\xf3\x01\x01\x01\x02\x89\x01\x01\x01\x03\xf3\x01\x01\x01\x02\x89\x01\x01\x01\x03\xf3\x01\x01\x01\x02\x89\x01\x01\x01\x03\xf3\x01\x01\x01\x02\x89\x01\x01\x01\x03\xf3\x01\x01\x01\x02\x89\x01\x01\x01\x03\xf3\x01\x01C\x02\x1a\x01.\x03\xb5\x02\x01\x01\x02\x1a\x01\x01\x03\xe2\x02\x01\x01\x02\x1a\x01\x01\x03\xe2\x02\x01\x01\x02\x1a\x01\x01\x03\xe2\x02\x01\x01\x02\x1a\x01\x01\x03\xe2\x02\x01\x02\x02\x19\x01\x01\x03\xe3\x02\x01\x01\x02\x19\x01,\x03\xb8\x02\x01\x01\x02D\x01\x01\x03\xb8\x02\x01\x01\x02D\x01\x01\x03\xb8\x02\x01\x01\x02D\x01\x01\x03\xb8\x02\x01\x01\x02D\x01\x01\x03\xb8\x02\x01\x02\x02C\x01\x01\x03\xb9\x02\x01\x01\x02C\x01\x01\x03\xb9\x02\x01\x01\x02A\x03\x01\x02\x01\x01\x01\x03\xb9\x02\x01\x01\x02A\x01\x03\x03\xb9\x02\x01\x01\x02>\x01\x04\x03\xbb\x02\x01\x01\x02>\x01\x01\x03\xbe\x02\x01\x01\x02>\x01\x01\x03\xbe\x02\x01\x01\x02>\x01\x01\x03\x0b\x01\x14\x03\x9f\x02\x01\x01\x02>\x01\x01\x03\t\x01\x02\x02\x13\x01\x01\x03\x9f\x02\x01\x02\x02=\x01\x01\x03\t\x01\x01\x02\x14\x01\x01\x03\xa0\x02\x01\x01\x02=\x01\x01\x03\t\x01\x01\x02\x14\x01\x01\x03\xa0\x02\x01\x01\x02=\x01\x01\x03\t\x01\x01\x02\x14\x01\x01\x03\xa0\x02\x01\x01\x02=\x01\x01\x03\x08\x01\x02\x02\x14\x01\x01\x03\xa0\x02\x01\x01\x02=\x01\t\x02\x16\x01\x01\x03\xa0\x02\x01\x01\x02\\\x01\x01\x03\xa0\x02\x01\x01\x02\\\x01\x01\x03\xa0\x02\x01\x01\x02\\\x01\x01\x03\xa0\x02\x01\x01\x02\\\x01\x01\x03\xa0\x02\x01\x02\x02[\x01\x01\x03\xa0\x02\x01\x02\x02[\x01\x01\x03\x9a\x02\x01\x08\x02[\x01\x01\x03\x9a\x02\x01\x01\x02\x06\x01\x01\x02[\x01\x01\x03\x9a\x02\x01\x01\x02\x06\x01\x01\x02[\x01\x01\x03\x9a\x02\x01\x01\x02b\x01\x01\x03\x9a\x02\x01\x01\x02b\x01\x01\x03\x9a\x02\x01\x01\x02b\x01\x01\x03\x9a\x02\x01\x01\x02b\x01\x01\x03\x9a\x02\x01\x01\x02b\x01\x01\x03\x9a\x02\x01\x01\x02b\x01\x01\x03\x9a\x02\x01\x01\x02b\x01\x01\x03\x94\x02\x01\x07\x02\x05\x01\x01\x02\\\x01\x01\x03\x94\x02\x01\x01\x02\x0b\x01\x01\x02\\\x01\x01\x03\x94\x02\x01\x01\x02h\x01\x01\x03\x94\x02\x01\x01\x02h\x01\x01\x03\x94\x02\x01\x01\x02h\x01\x01\x03\x94\x02\x01\x01\x02h\x01\x01\x03\x94\x02\x01\x01\x02h\x01\x01\x03\x94\x02\x01\x01\x02h\x01\x01\x03\x94\x02\x01\x01\x02h\x01\x01\x03\x94\x02\x01\x01\x02h\x01\x01\x03\x94\x02\x01\x01\x02h\x01\x01\x03\x94\x02\x01\x01\x02h\x01\x01\x03\x94\x02\x01\x01\x02h\x01\x01\x03\x94\x02\x01\x01\x02h\x01\x01\x03\x94\x02\x01\x01\x02P\x01\x13\x02\x05\x01\x01\x03\x94\x02\x01\x01\x02P\x01\x01\x03\x12\x02\x05\x01\x01\x03\x94\x02\x01\x01\x02P\x01\x01\x03\x12\x02\x05\x01\x01\x03\x94\x02\x01\x01\x02P\x01\x01\x03\x12\x02\x05\x01\x01\x03\x94\x02\x01\x01\x02P\x01\x01\x03\x13\x02\x04\x01\x01\x03\x94\x02\x01\x01\x02P\x01\x01\x03\x13\x02\x04\x01\x01\x03\x94\x02\x01\x01\x02P\x01\x01\x03\x13\x02\x04\x01\x01\x03\x94\x02\x01\x01\x02P\x01\x01\x03\x13\x02\x04\x01\x01\x03\x94\x02\x01\x01\x02P\x01\x01\x03\x13\x02\x04\x01\x01\x03\x94\x02\x01\x01\x02P\x01\x01\x03\x13\x02\x04\x01\x01\x03\x94\x02\x01\x01\x02P\x01\x01\x03\x13\x02\x04\x01\x01\x03\x94\x02\x01\x02\x02O\x01\x01\x03\x14\x02\x03\x01\x01\x03\x95\x02\x01\x01\x02H\x01\x08\x03\x14\x02\x03\x01\x01\x03\x95\x02\x01\x01\x02H\x01\x01\x03\x1b\x02\x03\x01\x01\x03\x95\x02\x01\x01\x02@\x01\t\x03\x1b\x02\x03\x01\x01\x03\x95\x02\x01\x01\x02\t\x018\x03#\x02\x03\x01\x01\x03\x95\x02\x01\x01\x02\x06\x01\x04\x03[\x02\x02\x01\x01\x03\x95\x02\x01\x08\x03^\x02\x02\x01\x01\x03\xfb\x02\x02\x02\x01\x01\x03\xfb\x02\x02\x02\x01\x01\x03\xfb\x02\x02\x02\x01\x01\x03\xfc\x02\x02\x01\x01\x01\x03\xfc\x02\x02\x01\x01\x01\x03\xfc\x02\x02\x01\x01\x01\x03\xfc\x02\x02\x01\x01\x01\x03\xfd\x02\x01\x01\x03\xd4Y' map_data0 = b'\x00\x00 \x06\x00\x00\x00 \x05\x00\x02\x00 \x05\x00\x05\x00\xa5 \x02\x00\x02\x00 \x03\x00\x00\x00\xa6 \x02\x00\x02\x00 \x02\x00\x04\x00 \x00\x00\x02\x00 \x00\x00\x00\x00 \x01\x00\xfe\xff \x00\x00\x00\x00 \x00\x00\x03\x00 \xff\xff\x01\x00\xa5 \x00\x00\xfe\xff \x00\x00\xfc\xff \xfe\xff\x00\x00\xa5 \xfd\xff\xfc\xff \xff\xff\xfb\xff\xa6\xa3 \xfb\xff\xfe\xff \xfb\xff\xfc\xff \xfc\xff\xfa\xff \xfe\xff\xf8\xff \xfb\xff\xfa\xff \xf9\xff\xfc\xff \xf9\xff\xfa\xff \xfa\xff\xf7\xff \xfc\xff\xf7\xff\xa7 \xff\xff\xf6\xff \xfd\xff\xf6\xff\xa1\xa7\xa4 \xfb\xff\xf9\xff\xa5 \xfa\xff\xf6\xff \xfc\xff\xf5\xff \xfe\xff\xf4\xff\xa0\xa7\xa2 \x00\x00\xf7\xff \x00\x00\xfb\xff \x02\x00\xfc\xff\xa0 \x06\x00\xfc\xff\xa6\xa7\xa7\xa0\xa0\xa4\xa3\xa7\xa0\xa4\xa2 \x08\x00\xfc\xff\xa4\xa2\xa4 \x05\x00\xfb\xff \x04\x00\xf9\xff \x04\x00\xf7\xff \x04\x00\xf5\xff\xa0\xa4\xa3\xa3\xa3 \x03\x00\xfb\xff\xa1\xa2 \x06\x00\xfc\xff\xa7\xa7\xa0\xa6\xa6 \t\x00\xf6\xff\xa6 \t\x00\xf3\xff\xa6\xa5\xa5\xa6\xa6\xa6\xa0\xa6 \x07\x00\xea\xff\xa6\xa4\xa2\xa3 \x03\x00\xeb\xff\xa4\xa4\xa4 \x00\x00\xe9\xff\xa6\xa5\xa5 \xfe\xff\xe4\xff \xfe\xff\xe2\xff\xa0\xa4\xa6\xa6 \xfe\xff\xde\xff\xa7\xa7\xa0\xa0 \x03\x00\xde\xff\xa0\xa2 \x04\x00\xe1\xff\xa2\xa1 \x06\x00\xe5\xff\xa6 \x06\x00\xe0\xff \x06\x00\xdd\xff \x06\x00\xd9\xff \x06\x00\xd6\xff \x06\x00\xd4\xff\xa6\xa4\xa6\xa6\xa0\xa6\xa7\xa6\xa6\xa0 \x08\x00\xcb\xff\xa5 \x07\x00\xc8\xff\xa6 \x08\x00\xc5\xff \x08\x00\xc2\xff \x08\x00\xbe\xff \x08\x00\xbc\xff\xa6 \x08\x00\xb9\xff\xa6\xa6 \x08\x00\xb5\xff \x08\x00\xb3\xff\xa6 \x08\x00\xb0\xff\xa6 \x08\x00\xad\xff\xa6 \x08\x00\xaa\xff\xa4 \x04\x00\xaa\xff \x00\x00\xaa\xff\xa4 \xff\xff\xac\xff\xa2\xa3 \xfe\xff\xb0\xff \xfe\xff\xb2\xff \xfe\xff\xb6\xff\xa3 \xfb\xff\xb7\xff \xf9\xff\xb7\xff \xf6\xff\xb7\xff \xf2\xff\xb7\xff \xee\xff\xb7\xff \xeb\xff\xb7\xff \xe7\xff\xb7\xff \xe5\xff\xb8\xff\xa2 \xe5\xff\xbb\xff \xe5\xff\xbd\xff \xe5\xff\xc1\xff \xe5\xff\xc5\xff \xe5\xff\xc9\xff \xe5\xff\xcd\xff \xe5\xff\xd1\xff \xe5\xff\xd5\xff \xe5\xff\xd9\xff \xe5\xff\xdd\xff \xe5\xff\xe1\xff \xe6\xff\xe3\xff \xe6\xff\xe5\xff \xe6\xff\xe7\xff \xe8\xff\xe8\xff \xe9\xff\xea\xff \xe9\xff\xec\xff\xa2 \xe9\xff\xf0\xff \xe9\xff\xf4\xff \xe9\xff\xf6\xff\xa1\xa2\xa0 \xed\xff\xf9\xff\xa0\xa2\xa2\xa2 \xee\xff\xfe\xff\xa2\xa2 \xee\xff\x02\x00 \xee\xff\x06\x00 \xee\xff\t\x00 \xef\xff\x0b\x00 \xef\xff\r\x00\xa6 \xef\xff\n\x00\xa5 \xee\xff\x07\x00 \xf0\xff\x06\x00 \xf2\xff\x06\x00 \xf3\xff\x08\x00 \xf2\xff\n\x00\xa1\xa0\xa7 \xf7\xff\t\x00\xa0 \xfa\xff\x0b\x00\xa2\xa3 \xfb\xff\r\x00 \xfe\xff\r\x00 \x01\x00\r\x00 \x03\x00\r\x00\xa7\xa6\xa2\xa7\xa2 \x06\x00\n\x00 \x06\x00\x08\x00 \x06\x00\x04\x00\xa7\xa4 \x04\x00\x01\x00 \x01\x00\xff\xff \x00\x00\xfd\xff \xfd\xff\xfa\xff \xfb\xff\xf8\xff\xa7 \xf2\xff\xfe\xff \xf5\xff\xfc\xff \xf7\xff\xf9\xff \xfa\xff\xf6\xff \xfd\xff\xf4\xff\xa7 \xff\xff\xf5\xff \x00\x00\xf8\xff \x03\x00\xfb\xff\xa0\xa0\xa0\xa7\xa0\xa7\xa6\xa6\xa6\xa6 \t\x00\xf3\xff \t\x00\xf1\xff\xa4\xa6\xa4 \x07\x00\xee\xff\xa6\xa0\xa6 \x07\x00\xea\xff \x07\x00\xe8\xff\xa3\xa3\xa2\xa2\xa1 \x06\x00\xef\xff \x06\x00\xf1\xff\xa3 \x03\x00\xf2\xff\xa4 \x00\x00\xf2\xff \x00\x00\xf0\xff \x00\x00\xee\xff \x00\x00\xec\xff\xa2 \x00\x00\xeb\xff \x02\x00\xeb\xff\xa0\xa0\xa0\xa2\xa6 \x03\x00\xeb\xff\xa4\xa4\xa4 \xfe\xff\xec\xff \xfc\xff\xec\xff \xf8\xff\xec\xff \xf5\xff\xec\xff \xf1\xff\xec\xff \xee\xff\xec\xff\xa4\xa2\xa2\xa2\xa0 \xf1\xff\xef\xff \xf5\xff\xef\xff \xf9\xff\xef\xff\xa0\xa0\xa2\xa2\xa2\xa4 \xf8\xff\xf2\xff \xf5\xff\xf2\xff \xf1\xff\xf2\xff \xee\xff\xf2\xff\xa4\xa2\xa2\xa2\xa0\xa0 \xf3\xff\xf5\xff\xff' # Ваши двоичные данные data = list(map(int, map_data0)) dp = [] dpp = [] dppp = [] for i in data: if i == 32: dp.append(dpp) dpp = [] else: dpp.append(i) l_old = [250,250] for i in range(1, len(dp)-1): if dp[i][1] == 255: intX = dp[i][0] - 256 + DEFAULT_IMAGE_WIDTH/2 else: intX = dp[i][0] + DEFAULT_IMAGE_WIDTH/2 if dp[i][3] == 255: intY = dp[i][2] - 256 + DEFAULT_IMAGE_WIDTH/2 else: intY = dp[i][2] + DEFAULT_IMAGE_WIDTH/2 coord = [intX, intY] dppp.append(coord) for i in range(1, len(dppp)-1): d.line((l_old[0],l_old[1],dppp[i][0],dppp[i][1]), fill='blue') l_old = [dppp[i][0],dppp[i][1]] # Сохранение изображения в байты buffer = BytesIO() # img_width = 208 # img_height = 152 # img = Image.open(BytesIO(bytearray(bbuf, offset=4))).convert("RGB") # img_width, img_height = img.size img.save(buffer, format="PNG") self._image = buffer.getvalue() # _LOGGER.debug("async_image %s", self._image) self._last_update = True return self._image async def async_update(self) -> None: """Update the image (e.g., to trigger a new image generation).""" self.async_update_token() # self._image = None # Invalidate cached image, triggering async_image() to regenerate it async def async_image(self) -> bytes | None: """Return bytes of image.""" _LOGGER.debug("async_image") if self._last_update: self._last_update = False self._image = self.image() return self._image return await super().async_image() @property def available(self) -> bool: """Return if the robot is available.""" return self._available # @property # def extra_state_attributes(self) -> dict[str, Any]: # """Return the state attributes of the vacuum cleaner.""" # data: dict[str, Any] = {} # if self._generated_at is not None: # data[ATTR_GENERATED_AT] = datetime.datetime.now() # data["model_name"] = "polaris" # return data @callback def async_update_token(self) -> None: """Update the used token.""" self.access_tokens.append(hex(_RND.getrandbits(256))[2:]) def _read_file(self): file_path = CUSTOM_SELECT_FILE_PATH if os.path.exists(file_path): with open(file_path, 'r', encoding='utf-8') as file: content = json.loads(file.read()) else: content = None return content def draw_quadrilaterals(self, draw, array, angle=0, color="grey"): # Определяем смещение, чтобы центрировать фигуры offset_x = DEFAULT_IMAGE_WIDTH / 2 offset_y = DEFAULT_IMAGE_HEIGHT / 2 center = (offset_x, offset_y) # Преобразуем массив в список кортежей (x, y) points = [(array[i], array[i+1]) for i in range(0, len(array), 2)] # Смещаем координаты для центрирования shifted_points = [(p[0] + offset_x, p[1] + offset_y) for p in points] # Поворачиваем каждую точку rotated_points = [self.rotate_point(p, angle, center) for p in shifted_points] # Добавляем первую точку в конец, чтобы замкнуть четырехугольник rotated_points.append(rotated_points[0]) # Рисуем четырехугольник draw.line(rotated_points, fill=color, width=3) def rotate_point(self, point, angle_degrees, center): # Переводим угол из градусов в радианы angle_radians = math.radians(angle_degrees) # Переносим точку в начало координат translated_point = (point[0] - center[0], point[1] - center[1]) # Применяем матрицу поворота rotated_x = translated_point[0] * math.cos(angle_radians) - translated_point[1] * math.sin(angle_radians) rotated_y = translated_point[0] * math.sin(angle_radians) + translated_point[1] * math.cos(angle_radians) # Переносим точку обратно rotated_point = (rotated_x + center[0], rotated_y + center[1]) return rotated_point def parse_no_go_area(self, no_go_area_array): data = list(map(int, no_go_area_array)) result = {"type_area": [], "coord_area": []} for i in range(0, len(data), 17): sublist = data[i:i+17] if all(x == 0 for x in sublist): # Проверяем, что все элементы coord равны 0 continue # Пропускаем такие подмассивы if len(sublist) < 17: break # Пропускаем неполные подмассивы (если длина не кратна 17) result["type_area"].append(sublist[0]) sublist_int16 = sublist[1:17] coord_int16 = [] for j in range(0, 16, 2): two_bytes = bytes(sublist_int16[j:j+2]) int16_value = struct.unpack('