



import colorsys
import io

import cva
import matplotlib as mpl
import matplotlib.colors as mplc
import matplotlib.figure as mplfigure
import numpy as np
import torch
from matplotlib.backends.backend_agg import FigureCanvasAgg

from utils import img_tensorize


A__     				=	10_00





class  __lowerCAmelCase			:




				def __init__(							self						,    _snake_case						,    _snake_case=1.2						,    _snake_case="g"						,    _snake_case=0.5						,    _snake_case="-"						,    _snake_case="test_out.jpg"						,    _snake_case=True						,    _snake_case=False						,    _snake_case=None						,    _snake_case=None						,    _snake_case=0.7						,    ):



									"""simple docstring"""





									if isinstance(UpperCamelCase__						,    torch.Tensor		):
														_lowerCAmelCase      =   img.numpy().astype("""np.uint8"""		)
									if isinstance(UpperCamelCase__						,    UpperCamelCase__		):
														_lowerCAmelCase      =   img_tensorize(UpperCamelCase__		)
									assert isinstance(UpperCamelCase__						,    np.ndarray		)

									_lowerCAmelCase      =   img.shape[1], img.shape[0]
									_lowerCAmelCase      =   mplfigure.Figure(frameon=UpperCamelCase__		)
									_lowerCAmelCase      =   fig.get_dpi()
									_lowerCAmelCase      =   (width * scale + 1e-2) / dpi
									_lowerCAmelCase      =   (height * scale + 1e-2) / dpi
									fig.set_size_inches(UpperCamelCase__						,    UpperCamelCase__		)
									_lowerCAmelCase      =   fig.add_axes([0.0, 0.0, 1.0, 1.0]		)
									ax.axis("""off"""		)
									ax.set_xlim(0.0						,    UpperCamelCase__		)
									ax.set_ylim(UpperCamelCase__		)

									_lowerCAmelCase      =   saveas
									_lowerCAmelCase      =   rgb
									_lowerCAmelCase      =   pynb
									_lowerCAmelCase      =   img
									_lowerCAmelCase      =   edgecolor
									_lowerCAmelCase      =   0.5
									_lowerCAmelCase      =   linestyle
									_lowerCAmelCase      =   int(np.sqrt(min(UpperCamelCase__						,    UpperCamelCase__		)		) * scale // 3		)
									_lowerCAmelCase      =   width
									_lowerCAmelCase      =   height
									_lowerCAmelCase      =   scale
									_lowerCAmelCase      =   fig
									_lowerCAmelCase      =   ax
									_lowerCAmelCase      =   pad
									_lowerCAmelCase      =   idaobj
									_lowerCAmelCase      =   idaattr
									_lowerCAmelCase      =   FigureCanvasAgg(UpperCamelCase__		)




				def 							snake_case       (							self						,    _snake_case						,    _snake_case=None		):



									"""simple docstring"""





									if color is None:
														_lowerCAmelCase      =   self.edgecolor
									(_lowerCAmelCase)      =   box
									_lowerCAmelCase      =   xa - xa
									_lowerCAmelCase      =   ya - ya
									self.ax.add_patch(
									    mpl.patches.Rectangle(
									        (xa, ya)						,    UpperCamelCase__						,    UpperCamelCase__						,    fill=UpperCamelCase__						,    edgecolor=UpperCamelCase__						,    linewidth=self.font_size // 3						,    alpha=self.alpha						,    linestyle=self.linestyle						,    )		)




				def 							snake_case       (							self						,    _snake_case						,    _snake_case=None						,    _snake_case=None						,    _snake_case=None						,    _snake_case=None		):



									"""simple docstring"""





									if len(boxes.shape		) > 2:
														_lowerCAmelCase      =   boxes[0]
									if len(obj_ids.shape		) > 1:
														_lowerCAmelCase      =   obj_ids[0]
									if len(obj_scores.shape		) > 1:
														_lowerCAmelCase      =   obj_scores[0]
									if len(attr_ids.shape		) > 1:
														_lowerCAmelCase      =   attr_ids[0]
									if len(attr_scores.shape		) > 1:
														_lowerCAmelCase      =   attr_scores[0]
									if isinstance(UpperCamelCase__						,    torch.Tensor		):
														_lowerCAmelCase      =   boxes.numpy()
									if isinstance(UpperCamelCase__						,    UpperCamelCase__		):
														_lowerCAmelCase      =   np.array(UpperCamelCase__		)
									assert isinstance(UpperCamelCase__						,    np.ndarray		)
									_lowerCAmelCase      =   np.prod(boxes[:, 2:] - boxes[:, :2]						,    axis=1		)
									_lowerCAmelCase      =   np.argsort(-areas		).tolist()
									_lowerCAmelCase      =   boxes[sorted_idxs] if boxes is not None else None
									_lowerCAmelCase      =   obj_ids[sorted_idxs] if obj_ids is not None else None
									_lowerCAmelCase      =   obj_scores[sorted_idxs] if obj_scores is not None else None
									_lowerCAmelCase      =   attr_ids[sorted_idxs] if attr_ids is not None else None
									_lowerCAmelCase      =   attr_scores[sorted_idxs] if attr_scores is not None else None

									_lowerCAmelCase      =   [self._random_color(maximum=1		) for _ in range(len(UpperCamelCase__		)		)]
									_lowerCAmelCase      =   [assigned_colors[idx] for idx in sorted_idxs]
									if obj_ids is not None:
														_lowerCAmelCase      =   self._create_text_labels_attr(UpperCamelCase__						,    UpperCamelCase__						,    UpperCamelCase__						,    UpperCamelCase__		)
														for i in range(len(UpperCamelCase__		)		):
																			_lowerCAmelCase      =   assigned_colors[i]
																			self.add_box(boxes[i]						,    UpperCamelCase__		)
																			self.draw_labels(labels[i]						,    boxes[i]						,    UpperCamelCase__		)




				def 							snake_case       (							self						,    _snake_case						,    _snake_case						,    _snake_case		):



									"""simple docstring"""





									_lowerCAmelCase      =   box
									_lowerCAmelCase      =   (xa, ya)
									_lowerCAmelCase      =   (ya - ya) * (xa - xa)
									_lowerCAmelCase      =   _SMALL_OBJ * self.scale
									if instance_area < small or ya - ya < 40 * self.scale:
														if ya >= self.height - 5:
																			_lowerCAmelCase      =   (xa, ya)
														else:
																			_lowerCAmelCase      =   (xa, ya)

									_lowerCAmelCase      =   (ya - ya) / np.sqrt(self.height * self.width		)
									_lowerCAmelCase      =   self._change_color_brightness(UpperCamelCase__						,    brightness_factor=0.7		)
									_lowerCAmelCase      =   np.clip((height_ratio - 0.02) / 0.08 + 1						,    1.2						,    2		)
									font_size *= 0.75 * self.font_size

									self.draw_text(
									    text=UpperCamelCase__						,    position=UpperCamelCase__						,    color=UpperCamelCase__						,    )




				def 							snake_case       (							self						,    _snake_case						,    _snake_case						,    _snake_case="g"						,    _snake_case="left"						,    ):



									"""simple docstring"""





									_lowerCAmelCase      =   0
									_lowerCAmelCase      =   self.font_size
									_lowerCAmelCase      =   np.maximum(list(mplc.to_rgb(UpperCamelCase__		)		)						,    0.2		)
									_lowerCAmelCase      =   max(0.8						,    np.max(UpperCamelCase__		)		)
									_lowerCAmelCase      =   {
									    "facecolor": "black",
									    "alpha": self.alpha,
									    "pad": self.pad,
									    "edgecolor": "none",
									}
									_lowerCAmelCase      =   position
									self.ax.text(
									    UpperCamelCase__						,    UpperCamelCase__						,    UpperCamelCase__						,    size=font_size * self.scale						,    family="""sans-serif"""						,    bbox=UpperCamelCase__						,    verticalalignment="""top"""						,    horizontalalignment=UpperCamelCase__						,    color=UpperCamelCase__						,    zorder=10						,    rotation=UpperCamelCase__						,    )




				def 							snake_case       (							self						,    _snake_case=None		):



									"""simple docstring"""





									if saveas is None:
														_lowerCAmelCase      =   self.saveas
									if saveas.lower().endswith(""".jpg"""		) or saveas.lower().endswith(""".png"""		):
														cva.imwrite(
														    UpperCamelCase__						,    self._get_buffer()[:, :, ::-1]						,    )
									else:
														self.fig.savefig(UpperCamelCase__		)




				def 							snake_case       (							self						,    _snake_case						,    _snake_case						,    _snake_case						,    _snake_case		):



									"""simple docstring"""





									_lowerCAmelCase      =   [self.idaobj[i] for i in classes]
									_lowerCAmelCase      =   [self.idaattr[i] for i in attr_classes]
									_lowerCAmelCase      =   [
									    F'{label} {score:.2f} {attr} {attr_score:.2f}'
									    for label, score, attr, attr_score in zip(UpperCamelCase__						,    UpperCamelCase__						,    UpperCamelCase__						,    UpperCamelCase__		)
									]
									return labels




				def 							snake_case       (							self						,    _snake_case						,    _snake_case		):



									"""simple docstring"""





									_lowerCAmelCase      =   [self.idaobj[i] for i in classes]
									if scores is not None:
														if labels is None:
																			_lowerCAmelCase      =   ["{:.0f}%".format(s * 100		) for s in scores]
														else:
																			_lowerCAmelCase      =   ["{} {:.0f}%".format(UpperCamelCase__						,    s * 100		) for li, s in zip(UpperCamelCase__						,    UpperCamelCase__		)]
									return labels




				def 							snake_case       (							self						,    _snake_case=255		):



									"""simple docstring"""





									_lowerCAmelCase      =   np.random.randint(0						,    len(_COLORS		)		)
									_lowerCAmelCase      =   _COLORS[idx] * maximum
									if not self.rgb:
														_lowerCAmelCase      =   ret[::-1]
									return ret




				def 							snake_case       (							self		):



									"""simple docstring"""





									if not self.pynb:
														_lowerCAmelCase      =   self.canvas.print_to_buffer()
														if (width, height) != (self.width, self.height):
																			_lowerCAmelCase      =   cva.resize(self.img						,    (width, height)		)
														else:
																			_lowerCAmelCase      =   self.img
									else:
														_lowerCAmelCase      =   io.BytesIO()  # works for cairo backend
														self.canvas.print_rgba(UpperCamelCase__		)
														_lowerCAmelCase      =   self.width, self.height
														_lowerCAmelCase      =   buf.getvalue()
														_lowerCAmelCase      =   self.img

									_lowerCAmelCase      =   np.frombuffer(UpperCamelCase__						,    dtype="""uint8"""		)
									_lowerCAmelCase      =   buffer.reshape(UpperCamelCase__						,    UpperCamelCase__						,    4		)
									_lowerCAmelCase      =   np.split(UpperCamelCase__						,    [3]						,    axis=2		)

									try:
														import numexpr as ne  # fuse them with numexpr

														_lowerCAmelCase      =   ne.evaluate("""img * (1 - alpha / 255.0) + rgb * (alpha / 255.0)"""		)
									except ImportError:
														_lowerCAmelCase      =   alpha.astype("""float32"""		) / 255.0
														_lowerCAmelCase      =   img * (1 - alpha) + rgb * alpha

									return visualized_image.astype("""uint8"""		)




				def 							snake_case       (							self						,    _snake_case						,    _snake_case		):



									"""simple docstring"""





									assert brightness_factor >= -1.0 and brightness_factor <= 1.0
									_lowerCAmelCase      =   mplc.to_rgb(UpperCamelCase__		)
									_lowerCAmelCase      =   colorsys.rgb_to_hls(*mplc.to_rgb(UpperCamelCase__		)		)
									_lowerCAmelCase      =   polygon_color[1] + (brightness_factor * polygon_color[1])
									_lowerCAmelCase      =   0.0 if modified_lightness < 0.0 else modified_lightness
									_lowerCAmelCase      =   1.0 if modified_lightness > 1.0 else modified_lightness
									_lowerCAmelCase      =   colorsys.hls_to_rgb(polygon_color[0]						,    UpperCamelCase__						,    polygon_color[2]		)
									return modified_color

A__     				=	(
    np.array(
        [
            0.0_0_0,
            0.4_4_7,
            0.7_4_1,
            0.8_5_0,
            0.3_2_5,
            0.0_9_8,
            0.9_2_9,
            0.6_9_4,
            0.1_2_5,
            0.4_9_4,
            0.1_8_4,
            0.5_5_6,
            0.4_6_6,
            0.6_7_4,
            0.1_8_8,
            0.3_0_1,
            0.7_4_5,
            0.9_3_3,
            0.6_3_5,
            0.0_7_8,
            0.1_8_4,
            0.3_0_0,
            0.3_0_0,
            0.3_0_0,
            0.6_0_0,
            0.6_0_0,
            0.6_0_0,
            1.0_0_0,
            0.0_0_0,
            0.0_0_0,
            1.0_0_0,
            0.5_0_0,
            0.0_0_0,
            0.7_4_9,
            0.7_4_9,
            0.0_0_0,
            0.0_0_0,
            1.0_0_0,
            0.0_0_0,
            0.0_0_0,
            0.0_0_0,
            1.0_0_0,
            0.6_6_7,
            0.0_0_0,
            1.0_0_0,
            0.3_3_3,
            0.3_3_3,
            0.0_0_0,
            0.3_3_3,
            0.6_6_7,
            0.0_0_0,
            0.3_3_3,
            1.0_0_0,
            0.0_0_0,
            0.6_6_7,
            0.3_3_3,
            0.0_0_0,
            0.6_6_7,
            0.6_6_7,
            0.0_0_0,
            0.6_6_7,
            1.0_0_0,
            0.0_0_0,
            1.0_0_0,
            0.3_3_3,
            0.0_0_0,
            1.0_0_0,
            0.6_6_7,
            0.0_0_0,
            1.0_0_0,
            1.0_0_0,
            0.0_0_0,
            0.0_0_0,
            0.3_3_3,
            0.5_0_0,
            0.0_0_0,
            0.6_6_7,
            0.5_0_0,
            0.0_0_0,
            1.0_0_0,
            0.5_0_0,
            0.3_3_3,
            0.0_0_0,
            0.5_0_0,
            0.3_3_3,
            0.3_3_3,
            0.5_0_0,
            0.3_3_3,
            0.6_6_7,
            0.5_0_0,
            0.3_3_3,
            1.0_0_0,
            0.5_0_0,
            0.6_6_7,
            0.0_0_0,
            0.5_0_0,
            0.6_6_7,
            0.3_3_3,
            0.5_0_0,
            0.6_6_7,
            0.6_6_7,
            0.5_0_0,
            0.6_6_7,
            1.0_0_0,
            0.5_0_0,
            1.0_0_0,
            0.0_0_0,
            0.5_0_0,
            1.0_0_0,
            0.3_3_3,
            0.5_0_0,
            1.0_0_0,
            0.6_6_7,
            0.5_0_0,
            1.0_0_0,
            1.0_0_0,
            0.5_0_0,
            0.0_0_0,
            0.3_3_3,
            1.0_0_0,
            0.0_0_0,
            0.6_6_7,
            1.0_0_0,
            0.0_0_0,
            1.0_0_0,
            1.0_0_0,
            0.3_3_3,
            0.0_0_0,
            1.0_0_0,
            0.3_3_3,
            0.3_3_3,
            1.0_0_0,
            0.3_3_3,
            0.6_6_7,
            1.0_0_0,
            0.3_3_3,
            1.0_0_0,
            1.0_0_0,
            0.6_6_7,
            0.0_0_0,
            1.0_0_0,
            0.6_6_7,
            0.3_3_3,
            1.0_0_0,
            0.6_6_7,
            0.6_6_7,
            1.0_0_0,
            0.6_6_7,
            1.0_0_0,
            1.0_0_0,
            1.0_0_0,
            0.0_0_0,
            1.0_0_0,
            1.0_0_0,
            0.3_3_3,
            1.0_0_0,
            1.0_0_0,
            0.6_6_7,
            1.0_0_0,
            0.3_3_3,
            0.0_0_0,
            0.0_0_0,
            0.5_0_0,
            0.0_0_0,
            0.0_0_0,
            0.6_6_7,
            0.0_0_0,
            0.0_0_0,
            0.8_3_3,
            0.0_0_0,
            0.0_0_0,
            1.0_0_0,
            0.0_0_0,
            0.0_0_0,
            0.0_0_0,
            0.1_6_7,
            0.0_0_0,
            0.0_0_0,
            0.3_3_3,
            0.0_0_0,
            0.0_0_0,
            0.5_0_0,
            0.0_0_0,
            0.0_0_0,
            0.6_6_7,
            0.0_0_0,
            0.0_0_0,
            0.8_3_3,
            0.0_0_0,
            0.0_0_0,
            1.0_0_0,
            0.0_0_0,
            0.0_0_0,
            0.0_0_0,
            0.1_6_7,
            0.0_0_0,
            0.0_0_0,
            0.3_3_3,
            0.0_0_0,
            0.0_0_0,
            0.5_0_0,
            0.0_0_0,
            0.0_0_0,
            0.6_6_7,
            0.0_0_0,
            0.0_0_0,
            0.8_3_3,
            0.0_0_0,
            0.0_0_0,
            1.0_0_0,
            0.0_0_0,
            0.0_0_0,
            0.0_0_0,
            0.1_4_3,
            0.1_4_3,
            0.1_4_3,
            0.8_5_7,
            0.8_5_7,
            0.8_5_7,
            1.0_0_0,
            1.0_0_0,
            1.0_0_0,
        ]
    )
    .astype(np.floataa)
    .reshape(-1, 3)
)








# Lint as: python3

import hashlib
from typing import Union


def 		_UpperCAmelCase    (				snake_case      ):





					"""simple docstring"""

					if isinstance(snake_case     ,						snake_case      ):
										# Data already in bytes, returns as it as
										return hash_data
					elif isinstance(snake_case     ,						snake_case      ):
										# We keep the data as it as for it ot be later encoded to UTF-8
										# However replace `\\` with `/` for Windows compatibility
										_lowerCAmelCase      =   hash_data.replace("""\\"""     ,						"""/"""      )
					elif isinstance(snake_case     ,						snake_case      ):
										_lowerCAmelCase      =   str(snake_case      )
					else:
										# If data is not of the required type, raise error
										raise InvalidKeyError(snake_case      )

					return hash_data.encode("""utf-8"""      )





class  __lowerCAmelCase			(					lowerCamelCase__	):




				def __init__(							self						,    _snake_case		):



									"""simple docstring"""





									_lowerCAmelCase      =   """\nFAILURE TO GENERATE DATASET: Invalid key type detected"""
									_lowerCAmelCase      =   F'\nFound Key {hash_data} of type {type(_snake_case		)}'
									_lowerCAmelCase      =   """\nKeys should be either str, int or bytes type"""
									super().__init__(F'{self.prefix}{self.err_msg}{self.suffix}'		)





class  __lowerCAmelCase			(					lowerCamelCase__	):




				def __init__(							self						,    _snake_case						,    _snake_case						,    _snake_case=""		):



									"""simple docstring"""





									_lowerCAmelCase      =   key
									_lowerCAmelCase      =   duplicate_key_indices
									_lowerCAmelCase      =   fix_msg
									_lowerCAmelCase      =   """Found multiple examples generated with the same key"""
									if len(_snake_case		) <= 20:
														_lowerCAmelCase      =   F'\nThe examples at index {", ".join(_snake_case		)} have the key {key}'
									else:
														_lowerCAmelCase      =   F'\nThe examples at index {", ".join(duplicate_key_indices[:20]		)}... ({len(_snake_case		) - 20} more) have the key {key}'
									_lowerCAmelCase      =   """\n""" + fix_msg if fix_msg else """"""
									super().__init__(F'{self.prefix}{self.err_msg}{self.suffix}'		)





class  __lowerCAmelCase			:




				def __init__(							self						,    _snake_case		):



									"""simple docstring"""





									_lowerCAmelCase      =   hashlib.mda(_as_bytes(_snake_case		)		)




				def 							snake_case       (							self						,    _snake_case		):



									"""simple docstring"""





									_lowerCAmelCase      =   self._split_mda.copy()
									_lowerCAmelCase      =   _as_bytes(_snake_case		)
									mda.update(_snake_case		)
									# Convert to integer with hexadecimal conversion
									return int(mda.hexdigest()						,    16		)



