


import importlib
import inspect
import json
import os
import re
import shutil
import sys
from pathlib import Path
from typing import Dict, Optional, Union
from urllib import request

from huggingface_hub import HfFolder, cached_download, hf_hub_download, model_info
from packaging import version

from .. import __version__
from . import DIFFUSERS_DYNAMIC_MODULE_NAME, HF_MODULES_CACHE, logging


snake_case							:       Dict     			=      (
    """https://raw.githubusercontent.com/huggingface/diffusers/{revision}/examples/community/{pipeline}.py"""
)


snake_case							:       List[Any]     			=      logging.get_logger(__name__)  # pylint: disable=invalid-name






def 							__lowercase   ( ):
							a__             =     "https://pypi.org/pypi/diffusers/json"
							a__             =     json.loads(request.urlopen(_UpperCAmelCase   ).read()   )["releases"].keys()
							return sorted(_UpperCAmelCase					,    key=lambda __lowerCAmelCase   : version.Version(_UpperCAmelCase   )   )






def 							__lowercase   ( ):







							if HF_MODULES_CACHE in sys.path:
														return

							sys.path.append(_UpperCAmelCase   )
							os.makedirs(_UpperCAmelCase					,    exist_ok=_UpperCAmelCase   )
							a__             =     Path(_UpperCAmelCase   ) / "__init__.py"
							if not init_path.exists():
														init_path.touch()






def 							__lowercase   ( __lowerCAmelCase							:				Union[str, os.PathLike]   ):
							init_hf_modules()
							a__             =     Path(_UpperCAmelCase   ) / name
							# If the parent module does not exist yet, recursively create it.
							if not dynamic_module_path.parent.exists():
														create_dynamic_module(dynamic_module_path.parent   )
							os.makedirs(_UpperCAmelCase					,    exist_ok=_UpperCAmelCase   )
							a__             =     dynamic_module_path / "__init__.py"
							if not init_path.exists():
														init_path.touch()






def 							__lowercase   ( __lowerCAmelCase							:				Optional[Any]   ):







							with open(_UpperCAmelCase					,    'r'					,    encoding='utf-8'   ) as f:
														a__             =     f.read()

							# Imports of the form `import .xxx`
							a__             =     re.findall('^\s*import\s+\.(\S+)\s*$'					,    _UpperCAmelCase					,    flags=re.MULTILINE   )
							# Imports of the form `from .xxx import yyy`
							relative_imports += re.findall('^\s*from\s+\.(\S+)\s+import'					,    _UpperCAmelCase					,    flags=re.MULTILINE   )
							# Unique-ify
							return list(set(_UpperCAmelCase   )   )






def 							__lowercase   ( __lowerCAmelCase							:				Optional[int]   ):
							a__             =     False
							a__             =     [module_file]
							a__             =     []

							# Let's recurse through all relative imports
							while not no_change:
														a__             =     []
														for f in files_to_check:
																					new_imports.extend(get_relative_imports(_UpperCAmelCase   )   )

														a__             =     Path(_UpperCAmelCase   ).parent
														a__             =     [str(module_path / m   ) for m in new_imports]
														a__             =     [f for f in new_import_files if f not in all_relative_imports]
														a__             =     [F'{f}.py' for f in new_import_files]

														a__             =     len(_UpperCAmelCase   ) == 0
														all_relative_imports.extend(_UpperCAmelCase   )

							return all_relative_imports






def 							__lowercase   ( __lowerCAmelCase							:				Union[str, Any]   ):







							with open(_UpperCAmelCase					,    'r'					,    encoding='utf-8'   ) as f:
														a__             =     f.read()

							# Imports of the form `import xxx`
							a__             =     re.findall('^\s*import\s+(\S+)\s*$'					,    _UpperCAmelCase					,    flags=re.MULTILINE   )
							# Imports of the form `from xxx import yyy`
							imports += re.findall('^\s*from\s+(\S+)\s+import'					,    _UpperCAmelCase					,    flags=re.MULTILINE   )
							# Only keep the top-level module
							a__             =     [imp.split('.'   )[0] for imp in imports if not imp.startswith('.'   )]

							# Unique-ify and test we got them all
							a__             =     list(set(_UpperCAmelCase   )   )
							a__             =     []
							for imp in imports:
														try:
																					importlib.import_module(_UpperCAmelCase   )
														except ImportError:
																					missing_packages.append(_UpperCAmelCase   )

							if len(_UpperCAmelCase   ) > 0:
														raise ImportError(
														    'This modeling file requires the following packages that were not found in your environment: '
														    F'{", ".join(_UpperCAmelCase   )}. Run `pip install {" ".join(_UpperCAmelCase   )}`'   )

							return get_relative_imports(_UpperCAmelCase   )






def 							__lowercase   ( __lowerCAmelCase							:				List[Any]					,    __lowerCAmelCase							:				Any   ):
							a__             =     module_path.replace(os.path.sep					,    '.'   )
							a__             =     importlib.import_module(_UpperCAmelCase   )

							if class_name is None:
														return find_pipeline_class(_UpperCAmelCase   )
							return getattr(_UpperCAmelCase					,    _UpperCAmelCase   )






def 							__lowercase   ( __lowerCAmelCase							:				List[str]   ):
							from ..pipelines import DiffusionPipeline

							a__             =     dict(inspect.getmembers(_UpperCAmelCase					,    inspect.isclass   )   )

							a__             =     None
							for cls_name, cls in cls_members.items():
														if (
														    cls_name != DiffusionPipeline.__name__
														    and issubclass(cls					,    _UpperCAmelCase   )
														    and cls.__module__.split('.'   )[0] != "diffusers"
														):
																					if pipeline_class is not None:
																												raise ValueError(
																												    F'Multiple classes that inherit from {DiffusionPipeline.__name__} have been found:'
																												    F' {pipeline_class.__name__}, and {cls_name}. Please make sure to define only one in'
																												    F' {loaded_module}.'   )
																					a__             =     cls

							return pipeline_class






def 							__lowercase   ( __lowerCAmelCase							:				Union[str, os.PathLike]					,    __lowerCAmelCase							:				str					,    __lowerCAmelCase							:				Optional[Union[str, os.PathLike]] = None					,    __lowerCAmelCase							:				bool = False					,    __lowerCAmelCase							:				bool = False					,    __lowerCAmelCase							:				Optional[Dict[str, str]] = None					,    __lowerCAmelCase							:				Optional[Union[bool, str]] = None					,    __lowerCAmelCase							:				Optional[str] = None					,    __lowerCAmelCase							:				bool = False					,    ):
							a__             =     str(_UpperCAmelCase   )

							a__             =     os.path.join(_UpperCAmelCase					,    _UpperCAmelCase   )

							if os.path.isfile(_UpperCAmelCase   ):
														a__             =     module_file_or_url
														a__             =     "local"
							elif pretrained_model_name_or_path.count('/'   ) == 0:
														a__             =     get_diffusers_versions()
														# cut ".dev0"
														a__             =     "v" + ".".join(__version__.split('.'   )[:3]   )

														# retrieve github version that matches
														if revision is None:
																					a__             =     latest_version if latest_version[1:] in available_versions else "main"
																					logger.info(F'Defaulting to latest_version: {revision}.'   )
														elif revision in available_versions:
																					a__             =     F'v{revision}'
														elif revision == "main":
																					a__             =     revision
														else:
																					raise ValueError(
																					    F'`custom_revision`: {revision} does not exist. Please make sure to choose one of'
																					    F' {", ".join(available_versions + ["main"]   )}.'   )

														# community pipeline on GitHub
														a__             =     COMMUNITY_PIPELINES_URL.format(revision=_UpperCAmelCase					,    pipeline=_UpperCAmelCase   )
														try:
																					a__             =     cached_download(
																					    _UpperCAmelCase					,    cache_dir=_UpperCAmelCase					,    force_download=_UpperCAmelCase					,    proxies=_UpperCAmelCase					,    resume_download=_UpperCAmelCase					,    local_files_only=_UpperCAmelCase					,    use_auth_token=_UpperCAmelCase					,    )
																					a__             =     "git"
																					a__             =     pretrained_model_name_or_path + ".py"
														except EnvironmentError:
																					logger.error(F'Could not locate the {module_file} inside {pretrained_model_name_or_path}.'   )
																					raise
							else:
														try:
																					# Load from URL or cache if already cached
																					a__             =     hf_hub_download(
																					    _UpperCAmelCase					,    _UpperCAmelCase					,    cache_dir=_UpperCAmelCase					,    force_download=_UpperCAmelCase					,    proxies=_UpperCAmelCase					,    resume_download=_UpperCAmelCase					,    local_files_only=_UpperCAmelCase					,    use_auth_token=_UpperCAmelCase					,    )
																					a__             =     os.path.join('local'					,    '--'.join(pretrained_model_name_or_path.split('/'   )   )   )
														except EnvironmentError:
																					logger.error(F'Could not locate the {module_file} inside {pretrained_model_name_or_path}.'   )
																					raise

    # Check we have all the requirements in our environment
							a__             =     check_imports(_UpperCAmelCase   )

							# Now we move the module inside our cached dynamic modules.
							a__             =     DIFFUSERS_DYNAMIC_MODULE_NAME + os.path.sep + submodule
							create_dynamic_module(_UpperCAmelCase   )
							a__             =     Path(_UpperCAmelCase   ) / full_submodule
							if submodule == "local" or submodule == "git":
														# We always copy local files (we could hash the file to see if there was a change, and give them the name of
														# that hash, to only copy when there is a modification but it seems overkill for now).
														# The only reason we do the copy is to avoid putting too many folders in sys.path.
														shutil.copy(_UpperCAmelCase					,    submodule_path / module_file   )
														for module_needed in modules_needed:
																					a__             =     F'{module_needed}.py'
																					shutil.copy(os.path.join(_UpperCAmelCase					,    _UpperCAmelCase   )					,    submodule_path / module_needed   )
							else:
														# Get the commit hash
														# TODO: we will get this info in the etag soon, so retrieve it from there and not here.
														if isinstance(_UpperCAmelCase					,    _UpperCAmelCase   ):
																					a__             =     use_auth_token
														elif use_auth_token is True:
																					a__             =     HfFolder.get_token()
														else:
																					a__             =     None

														a__             =     model_info(_UpperCAmelCase					,    revision=_UpperCAmelCase					,    token=_UpperCAmelCase   ).sha

														# The module file will end up being placed in a subfolder with the git hash of the repo. This way we get the
														# benefit of versioning.
														a__             =     submodule_path / commit_hash
														a__             =     full_submodule + os.path.sep + commit_hash
														create_dynamic_module(_UpperCAmelCase   )

														if not (submodule_path / module_file).exists():
																					shutil.copy(_UpperCAmelCase					,    submodule_path / module_file   )
														# Make sure we also have every file with relative
														for module_needed in modules_needed:
																					if not (submodule_path / module_needed).exists():
																												get_cached_module_file(
																												    _UpperCAmelCase					,    F'{module_needed}.py'					,    cache_dir=_UpperCAmelCase					,    force_download=_UpperCAmelCase					,    resume_download=_UpperCAmelCase					,    proxies=_UpperCAmelCase					,    use_auth_token=_UpperCAmelCase					,    revision=_UpperCAmelCase					,    local_files_only=_UpperCAmelCase					,    )
							return os.path.join(_UpperCAmelCase					,    _UpperCAmelCase   )






def 							__lowercase   ( __lowerCAmelCase							:				Union[str, os.PathLike]					,    __lowerCAmelCase							:				str					,    __lowerCAmelCase							:				Optional[str] = None					,    __lowerCAmelCase							:				Optional[Union[str, os.PathLike]] = None					,    __lowerCAmelCase							:				bool = False					,    __lowerCAmelCase							:				bool = False					,    __lowerCAmelCase							:				Optional[Dict[str, str]] = None					,    __lowerCAmelCase							:				Optional[Union[bool, str]] = None					,    __lowerCAmelCase							:				Optional[str] = None					,    __lowerCAmelCase							:				bool = False					,    **__lowerCAmelCase							:				Any					,    ):
							a__             =     get_cached_module_file(
							    _UpperCAmelCase					,    _UpperCAmelCase					,    cache_dir=_UpperCAmelCase					,    force_download=_UpperCAmelCase					,    resume_download=_UpperCAmelCase					,    proxies=_UpperCAmelCase					,    use_auth_token=_UpperCAmelCase					,    revision=_UpperCAmelCase					,    local_files_only=_UpperCAmelCase					,    )
							return get_class_in_module(_UpperCAmelCase					,    final_module.replace('.py'					,    ''   )   )





'''simple docstring'''




def 	UpperCamelCase_							(					_UpperCAmelCase  :      int			,	_UpperCAmelCase  :      int    )    ->    int:


       """simple docstring"""







       _UpperCAmelCase     :  List[str]							      =    1  # To kept the Calculated Value
       # Since C(n, k) = C(n, n-k)
       if k > (n - k):
              _UpperCAmelCase     :  Any							      =    n - k
       # Calculate C(n,k)
       for i in range(_UpperCAmelCase    ):
              result *= n - i
              result //= i + 1
       return result

def 	UpperCamelCase_							(					_UpperCAmelCase  :      int    )    ->    int:


       """simple docstring"""







       return binomial_coefficient(2 * node_count			,	_UpperCAmelCase    ) // (node_count + 1)

def 	UpperCamelCase_							(					_UpperCAmelCase  :      int    )    ->    int:


       """simple docstring"""







       if n < 0:
              raise ValueError("factorial() not defined for negative values"    )
       _UpperCAmelCase     :  List[str]							      =    1
       for i in range(1			,	n + 1    ):
              result *= i
       return result

def 	UpperCamelCase_							(					_UpperCAmelCase  :      int    )    ->    int:


       """simple docstring"""







       return catalan_number(_UpperCAmelCase    ) * factorial(_UpperCAmelCase    )


if __name__ == "__main__":
  __SCREAMING_SNAKE_CASE       :     Dict     =  int(input("""Enter the number of nodes: """).strip() or 0)
  if node_count <= 0:
    raise ValueError("""We need some nodes to work with.""")
  print(
      F'Given {node_count} nodes, there are {binary_tree_count(node_count)} '
      F'binary trees and {catalan_number(node_count)} binary search trees.'
  )

