import os
import re
import sys
import traceback
import warnings
from pathlib import Path
from typing import Dict, Optional, Union
from uuid import uuida

from huggingface_hub import HfFolder, ModelCard, ModelCardData, hf_hub_download, whoami
from huggingface_hub.file_download import REGEX_COMMIT_HASH
from huggingface_hub.utils import (
    EntryNotFoundError,
    RepositoryNotFoundError,
    RevisionNotFoundError,
    is_jinja_available,
)
from packaging import version
from requests import HTTPError

from .. import __version__
from .constants import (
    DEPRECATED_REVISION_ARGS,
    DIFFUSERS_CACHE,
    HUGGINGFACE_CO_RESOLVE_ENDPOINT,
    SAFETENSORS_WEIGHTS_NAME,
    WEIGHTS_NAME,
)
from .import_utils import (
    ENV_VARS_TRUE_VALUES,
    _flax_version,
    _jax_version,
    _onnxruntime_version,
    _torch_version,
    is_flax_available,
    is_onnx_available,
    is_torch_available,
)
from .logging import get_logger


lowerCamelCase_    :		Optional[int]							=	get_logger(__name__)


lowerCamelCase_    :		Union[str, Any]							=	Path(__file__).parent / """model_card_template.md"""
lowerCamelCase_    :		Tuple							=	uuida().hex
lowerCamelCase_    :		Optional[Any]							=	os.getenv("""HF_HUB_OFFLINE""", """""").upper() in ENV_VARS_TRUE_VALUES
lowerCamelCase_    :		Dict							=	os.getenv("""DISABLE_TELEMETRY""", """""").upper() in ENV_VARS_TRUE_VALUES
lowerCamelCase_    :		Union[str, Any]							=	HUGGINGFACE_CO_RESOLVE_ENDPOINT + """/api/telemetry/"""
def 							lowerCAmelCase(     __lowerCamelCase = None						):
					__a		 =       f'''diffusers/{__version__}; python/{sys.version.split()[0]}; session_id/{SESSION_ID}'''
					if DISABLE_TELEMETRY or HF_HUB_OFFLINE:
										return ua + "; telemetry/off"
					if is_torch_available():
										ua += f'''; torch/{_torch_version}'''
					if is_flax_available():
										ua += f'''; jax/{_jax_version}'''
										ua += f'''; flax/{_flax_version}'''
					if is_onnx_available():
										ua += f'''; onnxruntime/{_onnxruntime_version}'''
					# CI will set this value to True
					if os.environ.get('DIFFUSERS_IS_CI'				,    ''						).upper() in ENV_VARS_TRUE_VALUES:
										ua += "; is_ci/true"
					if isinstance(__lowerCamelCase				,    __lowerCamelCase						):
										ua += "; " + "; ".join(f'''{k}/{v}''' for k, v in user_agent.items()						)
					elif isinstance(__lowerCamelCase				,    __lowerCamelCase						):
										ua += "; " + user_agent
					return ua
def 							lowerCAmelCase(     __lowerCamelCase				,    __lowerCamelCase = None				,    __lowerCamelCase = None						):
					if token is None:
										__a		 =       HfFolder.get_token()
					if organization is None:
										__a		 =       whoami(__lowerCamelCase						)['name']
										return f'''{username}/{model_id}'''
					else:
										return f'''{organization}/{model_id}'''
def 							lowerCAmelCase(     __lowerCamelCase				,    __lowerCamelCase						):
					if not is_jinja_available():
										raise ValueError(
										    'Modelcard rendering is based on Jinja templates.'
										    ' Please make sure to have `jinja` installed before using `create_model_card`.'
										    ' To install it, please run `pip install Jinja2`.'						)

					if hasattr(__lowerCamelCase				,    'local_rank'						) and args.local_rank not in [-1, 0]:
										return

					__a		 =       args.hub_token if hasattr(__lowerCamelCase				,    'hub_token'						) else None
					__a		 =       get_full_repo_name(__lowerCamelCase				,    token=__lowerCamelCase						)

					__a		 =       ModelCard.from_template(
					    card_data=ModelCardData(  # Card metadata object that will be converted to YAML block
					        language='en'				,    license='apache-2.0'				,    library_name='diffusers'				,    tags=[]				,    datasets=args.dataset_name				,    metrics=[]				,    )				,    template_path=__lowerCamelCase				,    model_name=__lowerCamelCase				,    repo_name=__lowerCamelCase				,    dataset_name=args.dataset_name if hasattr(__lowerCamelCase				,    'dataset_name'						) else None				,    learning_rate=args.learning_rate				,    train_batch_size=args.train_batch_size				,    eval_batch_size=args.eval_batch_size				,    gradient_accumulation_steps=(
					        args.gradient_accumulation_steps if hasattr(__lowerCamelCase				,    'gradient_accumulation_steps'						) else None
					    )				,    adam_betaa=args.adam_betaa if hasattr(__lowerCamelCase				,    'adam_beta1'						) else None				,    adam_betaa=args.adam_betaa if hasattr(__lowerCamelCase				,    'adam_beta2'						) else None				,    adam_weight_decay=args.adam_weight_decay if hasattr(__lowerCamelCase				,    'adam_weight_decay'						) else None				,    adam_epsilon=args.adam_epsilon if hasattr(__lowerCamelCase				,    'adam_epsilon'						) else None				,    lr_scheduler=args.lr_scheduler if hasattr(__lowerCamelCase				,    'lr_scheduler'						) else None				,    lr_warmup_steps=args.lr_warmup_steps if hasattr(__lowerCamelCase				,    'lr_warmup_steps'						) else None				,    ema_inv_gamma=args.ema_inv_gamma if hasattr(__lowerCamelCase				,    'ema_inv_gamma'						) else None				,    ema_power=args.ema_power if hasattr(__lowerCamelCase				,    'ema_power'						) else None				,    ema_max_decay=args.ema_max_decay if hasattr(__lowerCamelCase				,    'ema_max_decay'						) else None				,    mixed_precision=args.mixed_precision				,    )

					__a		 =       os.path.join(args.output_dir				,    'README.md'						)
					model_card.save(__lowerCamelCase						)
def 							lowerCAmelCase(     __lowerCamelCase				,    __lowerCamelCase = None						):
					if resolved_file is None or commit_hash is not None:
										return commit_hash
					__a		 =       str(Path(__lowerCamelCase						).as_posix()						)
					__a		 =       re.search(r'snapshots/([^/]+)/'				,    __lowerCamelCase						)
					if search is None:
										return None
					__a		 =       search.groups()[0]
					return commit_hash if REGEX_COMMIT_HASH.match(__lowerCamelCase						) else None


# Old default cache path, potentially to be migrated.
# This logic was more or less taken from `transformers`, with the following differences:
# - Diffusers doesn't use custom environment variables to specify the cache path.
# - There is no need to migrate the cache format, just move the files to the new location.
lowerCamelCase_    :		Tuple							=	os.path.expanduser(
    os.getenv("""HF_HOME""", os.path.join(os.getenv("""XDG_CACHE_HOME""", """~/.cache"""), """huggingface"""))
)
lowerCamelCase_    :		Union[str, Any]							=	os.path.join(hf_cache_home, """diffusers""")
def 							lowerCAmelCase(     __lowerCamelCase = None				,    __lowerCamelCase = None						):
					if new_cache_dir is None:
										__a		 =       DIFFUSERS_CACHE
					if old_cache_dir is None:
										__a		 =       old_diffusers_cache

					__a		 =       Path(__lowerCamelCase						).expanduser()
					__a		 =       Path(__lowerCamelCase						).expanduser()
					for old_blob_path in old_cache_dir.glob('**/blobs/*'						):
										if old_blob_path.is_file() and not old_blob_path.is_symlink():
															__a		 =       new_cache_dir / old_blob_path.relative_to(__lowerCamelCase						)
															new_blob_path.parent.mkdir(parents=__lowerCamelCase				,    exist_ok=__lowerCamelCase						)
															os.replace(__lowerCamelCase				,    __lowerCamelCase						)
															try:
																				os.symlink(__lowerCamelCase				,    __lowerCamelCase						)
															except OSError:
																				logger.warning(
																				    'Could not create symlink between old cache and new cache. If you use an older version of diffusers again, files will be re-downloaded.'						)
					# At this point, old_cache_dir contains symlinks to the new cache (it can still be used).


lowerCamelCase_    :		Tuple							=	os.path.join(DIFFUSERS_CACHE, """version_diffusers_cache.txt""")
if not os.path.isfile(cache_version_file):
	lowerCamelCase_    :		Union[str, Any]							=	0
else:
	with open(cache_version_file) as f:
		try:
			lowerCamelCase_    :		List[Any]							=	int(f.read())
		except ValueError:
			lowerCamelCase_    :		Dict							=	0

if cache_version < 1:
	lowerCamelCase_    :		List[Any]							=	os.path.isdir(old_diffusers_cache) and len(os.listdir(old_diffusers_cache)) > 0
	if old_cache_is_not_empty:
		logger.warning(
		    """The cache for model files in Diffusers v0.14.0 has moved to a new location. Moving your """
		    """existing cached models. This is a one-time operation, you can interrupt it or run it """
		    """later by calling `diffusers.utils.hub_utils.move_cache()`."""
		)
		try:
			move_cache()
		except Exception as e:
			lowerCamelCase_    :		Tuple							=	"""\n""".join(traceback.format_tb(e.__traceback__))
			logger.error(
			    F'''There was a problem when trying to move your cache:\n\n{trace}\n{e.__class__.__name__}: {e}\n\nPlease '''
			    """file an issue at https://github.com/huggingface/diffusers/issues/new/choose, copy paste this whole """
			    """message and we will do our best to help."""
			)

if cache_version < 1:
	try:
		os.makedirs(DIFFUSERS_CACHE, exist_ok=True)
		with open(cache_version_file, """w""") as f:
			f.write("""1""")
	except Exception:
		logger.warning(
		    F'''There was a problem when trying to write in your cache folder ({DIFFUSERS_CACHE}). Please, ensure '''
		    """the directory exists and can be written to."""
		)
def 							lowerCAmelCase(     __lowerCamelCase				,    __lowerCamelCase = None						):
					if variant is not None:
										__a		 =       weights_name.split('.'						)
										__a		 =       splits[:-1] + [variant] + splits[-1:]
										__a		 =       '.'.join(__lowerCamelCase						)

					return weights_name



def 							lowerCAmelCase(     __lowerCamelCase				,    *,
    __lowerCamelCase				,    __lowerCamelCase				,    __lowerCamelCase				,    __lowerCamelCase				,    __lowerCamelCase				,    __lowerCamelCase				,    __lowerCamelCase				,    __lowerCamelCase				,    __lowerCamelCase				,    __lowerCamelCase				,    __lowerCamelCase=None				,    ):
					__a		 =       str(__lowerCamelCase						)
					if os.path.isfile(__lowerCamelCase						):
										return pretrained_model_name_or_path
					elif os.path.isdir(__lowerCamelCase						):
										if os.path.isfile(os.path.join(__lowerCamelCase				,    __lowerCamelCase						)						):
															# Load from a PyTorch checkpoint
															__a		 =       os.path.join(__lowerCamelCase				,    __lowerCamelCase						)
															return model_file
										elif subfolder is not None and os.path.isfile(
										    os.path.join(__lowerCamelCase				,    __lowerCamelCase				,    __lowerCamelCase						)						):
															__a		 =       os.path.join(__lowerCamelCase				,    __lowerCamelCase				,    __lowerCamelCase						)
															return model_file
										else:
															raise EnvironmentError(
															    f'''Error no file named {weights_name} found in directory {pretrained_model_name_or_path}.'''						)
					else:
										# 1. First check if deprecated way of loading from branches is used
										if (
										    revision in DEPRECATED_REVISION_ARGS
										    and (weights_name == WEIGHTS_NAME or weights_name == SAFETENSORS_WEIGHTS_NAME)
										    and version.parse(version.parse(__lowerCamelCase						).base_version						) >= version.parse('0.20.0'						)
										):
															try:
																				__a		 =       hf_hub_download(
																				    __lowerCamelCase				,    filename=_add_variant(__lowerCamelCase				,    __lowerCamelCase						)				,    cache_dir=__lowerCamelCase				,    force_download=__lowerCamelCase				,    proxies=__lowerCamelCase				,    resume_download=__lowerCamelCase				,    local_files_only=__lowerCamelCase				,    use_auth_token=__lowerCamelCase				,    user_agent=__lowerCamelCase				,    subfolder=__lowerCamelCase				,    revision=revision or commit_hash				,    )
																				warnings.warn(
																				    f'''Loading the variant {revision} from {pretrained_model_name_or_path} via `revision=\'{revision}\'` is deprecated. Loading instead from `revision=\'main\'` with `variant={revision}`. Loading model variants via `revision=\'{revision}\'` will be removed in diffusers v1. Please use `variant=\'{revision}\'` instead.'''				,    __lowerCamelCase				,    )
																				return model_file
															except:  # noqa: E722
																				warnings.warn(
																				    f'''You are loading the variant {revision} from {pretrained_model_name_or_path} via `revision=\'{revision}\'`. This behavior is deprecated and will be removed in diffusers v1. One should use `variant=\'{revision}\'` instead. However, it appears that {pretrained_model_name_or_path} currently does not have a {_add_variant(__lowerCamelCase				,    __lowerCamelCase						)} file in the \'main\' branch of {pretrained_model_name_or_path}. \n The Diffusers team and community would be very grateful if you could open an issue: https://github.com/huggingface/diffusers/issues/new with the title \'{pretrained_model_name_or_path} is missing {_add_variant(__lowerCamelCase				,    __lowerCamelCase						)}\' so that the correct variant file can be added.'''				,    __lowerCamelCase				,    )
										try:
															# 2. Load model file as usual
															__a		 =       hf_hub_download(
															    __lowerCamelCase				,    filename=__lowerCamelCase				,    cache_dir=__lowerCamelCase				,    force_download=__lowerCamelCase				,    proxies=__lowerCamelCase				,    resume_download=__lowerCamelCase				,    local_files_only=__lowerCamelCase				,    use_auth_token=__lowerCamelCase				,    user_agent=__lowerCamelCase				,    subfolder=__lowerCamelCase				,    revision=revision or commit_hash				,    )
															return model_file

										except RepositoryNotFoundError:
															raise EnvironmentError(
															    f'''{pretrained_model_name_or_path} is not a local folder and is not a valid model identifier '''
															    'listed on \'https://huggingface.co/models\'\nIf this is a private repository, make sure to pass a '
															    'token having permission to this repo with `use_auth_token` or log in with `huggingface-cli '
															    'login`.'						)
										except RevisionNotFoundError:
															raise EnvironmentError(
															    f'''{revision} is not a valid git identifier (branch name, tag name or commit id) that exists for '''
															    'this model name. Check the model page at '
															    f'''\'https://huggingface.co/{pretrained_model_name_or_path}\' for available revisions.'''						)
										except EntryNotFoundError:
															raise EnvironmentError(
															    f'''{pretrained_model_name_or_path} does not appear to have a file named {weights_name}.'''						)
										except HTTPError as err:
															raise EnvironmentError(
															    f'''There was a specific connection error when trying to load {pretrained_model_name_or_path}:\n{err}'''						)
										except ValueError:
															raise EnvironmentError(
															    f'''We couldn\'t connect to \'{HUGGINGFACE_CO_RESOLVE_ENDPOINT}\' to load this model, couldn\'t find it'''
															    f''' in the cached files and it looks like {pretrained_model_name_or_path} is not the path to a'''
															    f''' directory containing a file named {weights_name} or'''
															    ' \nCheckout your internet connection or see how to run the library in'
															    ' offline mode at \'https://huggingface.co/docs/diffusers/installation#offline-mode\'.'						)
										except EnvironmentError:
															raise EnvironmentError(
															    f'''Can\'t load the model for \'{pretrained_model_name_or_path}\'. If you were trying to load it from '''
															    '\'https://huggingface.co/models\', make sure you don\'t have a local directory with the same name. '
															    f'''Otherwise, make sure \'{pretrained_model_name_or_path}\' is the correct path to a directory '''
															    f'''containing a file named {weights_name}'''						)





from typing import Any, Dict, List, Union

from ..utils import add_end_docstrings, is_torch_available, is_vision_available, logging, requires_backends
from .base import PIPELINE_INIT_ARGS, ChunkPipeline


if is_vision_available():
	from PIL import Image

	from ..image_utils import load_image

if is_torch_available():
	import torch

	from transformers.modeling_outputs import BaseModelOutput

	from ..models.auto.modeling_auto import MODEL_FOR_ZERO_SHOT_OBJECT_DETECTION_MAPPING

lowerCamelCase_    :		Dict							=	logging.get_logger(__name__)


@add_end_docstrings(__snake_case		)
class 						a__							(       __snake_case		):



			def __init__(						self				,						**UpperCAmelCase   )			->   List[str]:
								super().__init__(**UpperCAmelCase   )

								if self.framework == "tf":
													raise ValueError(f'''The {self.__class__} is only available in PyTorch.'''   )

								requires_backends(self				,						'vision'   )
								self.check_model_type(UpperCAmelCase   )



			def __call__(						self				,						UpperCAmelCase				,						UpperCAmelCase = None				,						**UpperCAmelCase				,						)			->   Tuple:
								if "text_queries" in kwargs:
													__a		 =       kwargs.pop('text_queries'   )

								if isinstance(UpperCAmelCase				,						(str, Image.Image)   ):
													__a		 =       {'image': image, 'candidate_labels': candidate_labels}
								else:
													__a		 =       image
								__a		 =       super().__call__(UpperCAmelCase				,						**UpperCAmelCase   )
								return results



			def __SCREAMING_SNAKE_CASE							(						self				,						**UpperCAmelCase   )			->   List[str]:
								__a		 =       {}
								if "threshold" in kwargs:
													__a		 =       kwargs['threshold']
								if "top_k" in kwargs:
													__a		 =       kwargs['top_k']
								return {}, {}, postprocess_params



			def __SCREAMING_SNAKE_CASE							(						self				,						UpperCAmelCase   )			->   Union[str, Any]:
								__a		 =       load_image(inputs['image']   )
								__a		 =       inputs['candidate_labels']
								if isinstance(UpperCAmelCase				,						UpperCAmelCase   ):
													__a		 =       candidate_labels.split(','   )

								__a		 =       torch.tensor([[image.height, image.width]]				,						dtype=torch.intaa   )
								for i, candidate_label in enumerate(UpperCAmelCase   ):
													__a		 =       self.tokenizer(UpperCAmelCase				,						return_tensors=self.framework   )
													__a		 =       self.image_processor(UpperCAmelCase				,						return_tensors=self.framework   )
													yield {
													    "is_last": i == len(UpperCAmelCase   ) - 1,
													    "target_size": target_size,
													    "candidate_label": candidate_label,
													    **text_inputs,
													    **image_features,
													}



			def __SCREAMING_SNAKE_CASE							(						self				,						UpperCAmelCase   )			->   str:
								__a		 =       model_inputs.pop('target_size'   )
								__a		 =       model_inputs.pop('candidate_label'   )
								__a		 =       model_inputs.pop('is_last'   )

								__a		 =       self.model(**UpperCAmelCase   )

								__a		 =       {'target_size': target_size, 'candidate_label': candidate_label, 'is_last': is_last, **outputs}
								return model_outputs



			def __SCREAMING_SNAKE_CASE							(						self				,						UpperCAmelCase				,						UpperCAmelCase=0.1				,						UpperCAmelCase=None   )			->   Tuple:
								__a		 =       []
								for model_output in model_outputs:
													__a		 =       model_output['candidate_label']
													__a		 =       BaseModelOutput(UpperCAmelCase   )
													__a		 =       self.image_processor.post_process_object_detection(
													    outputs=UpperCAmelCase				,						threshold=UpperCAmelCase				,						target_sizes=model_output['target_size']   )[0]

													for index in outputs["scores"].nonzero():
																		__a		 =       outputs['scores'][index].item()
																		__a		 =       self._get_bounding_box(outputs['boxes'][index][0]   )

																		__a		 =       {'score': score, 'label': label, 'box': box}
																		results.append(UpperCAmelCase   )

								__a		 =       sorted(UpperCAmelCase				,						key=lambda UpperCAmelCase   : x["score"]				,						reverse=UpperCAmelCase   )
								if top_k:
													__a		 =       results[:top_k]

								return results







			def __SCREAMING_SNAKE_CASE							(						self				,						UpperCAmelCase   )			->   Dict[str, int]:
								if self.framework != "pt":
													raise ValueError('The ZeroShotObjectDetectionPipeline is only available in PyTorch.'   )
								__a ,				__a ,				__a ,				__a		 =       box.int().tolist()
								__a		 =       {
								    'xmin': xmin,
								    'ymin': ymin,
								    'xmax': xmax,
								    'ymax': ymax,
								}
								return bbox




