






import json
import os
from functools import lru_cache
from typing import Dict, List, Optional, Tuple, Union

import regex as re

from ...tokenization_utils import AddedToken, PreTrainedTokenizer
from ...tokenization_utils_base import BatchEncoding, EncodedInput
from ...utils import PaddingStrategy, logging


_UpperCamelCase			:	List[str]								=logging.get_logger(__name__)


_UpperCamelCase			:	str								={'vocab_file': 'vocab.json', 'merges_file': 'merges.txt'}

# See all LED models at https://huggingface.co/models?filter=LED
_UpperCamelCase			:	int								={
    'vocab_file': {
        'allenai/led-base-16384': 'https://huggingface.co/allenai/led-base-16384/resolve/main/vocab.json',
    },
    'merges_file': {
        'allenai/led-base-16384': 'https://huggingface.co/allenai/led-base-16384/resolve/main/merges.txt',
    },
    'tokenizer_file': {
        'allenai/led-base-16384': 'https://huggingface.co/allenai/led-base-16384/resolve/main/tokenizer.json',
    },
}

_UpperCamelCase			:	int								={
    'allenai/led-base-16384': 16384,
}



@lru_cache()
# Copied from transformers.models.bart.tokenization_bart.bytes_to_unicode
def  a__ ()		-> Any:
				_A	:				Tuple   =      (
				    list(range(ord('''!'''   )					,  ord('''~'''   ) + 1   )   ) + list(range(ord('''¡'''   )					,  ord('''¬'''   ) + 1   )   ) + list(range(ord('''®'''   )					,  ord('''ÿ'''   ) + 1   )   )
				)
				_A	:				str   =      bs[:]
				_A	:				Tuple   =      0
				for b in range(2**8   ):
								if b not in bs:
												bs.append(__A   )
												cs.append(2**8 + n   )
												n += 1
				_A	:				Optional[int]   =      [chr(__A   ) for n in cs]
				return dict(zip(__A					,  __A   )   )



def  a__ (__lowercase							:str   )		-> Optional[int]:
				_A	:				Optional[int]   =      set()
				_A	:				Tuple   =      word[0]
				for char in word[1:]:
								pairs.add((prev_char, char)   )
								_A	:				Any   =      char
				return pairs






class 						UpperCAmelCase__ (							SCREAMING_SNAKE_CASE_							):
		__snake_case      :       List[Any]     =   VOCAB_FILES_NAMES
		__snake_case      :       List[str]     =   PRETRAINED_VOCAB_FILES_MAP
		__snake_case      :       Optional[Any]     =   PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
		__snake_case      :       Dict     =   ["input_ids", "attention_mask"]







		def __init__(					self       ,A__       ,A__       ,A__="replace"       ,A__="<s>"       ,A__="</s>"       ,A__="</s>"       ,A__="<s>"       ,A__="<unk>"       ,A__="<pad>"       ,A__="<mask>"       ,A__=False       ,**A__       ,):
						_A	:				Union[str, Any]   =      AddedToken(__SCREAMING_SNAKE_CASE       ,lstrip=__SCREAMING_SNAKE_CASE       ,rstrip=__SCREAMING_SNAKE_CASE		) if isinstance(__SCREAMING_SNAKE_CASE       ,__SCREAMING_SNAKE_CASE		) else bos_token
						_A	:				str   =      AddedToken(__SCREAMING_SNAKE_CASE       ,lstrip=__SCREAMING_SNAKE_CASE       ,rstrip=__SCREAMING_SNAKE_CASE		) if isinstance(__SCREAMING_SNAKE_CASE       ,__SCREAMING_SNAKE_CASE		) else eos_token
						_A	:				int   =      AddedToken(__SCREAMING_SNAKE_CASE       ,lstrip=__SCREAMING_SNAKE_CASE       ,rstrip=__SCREAMING_SNAKE_CASE		) if isinstance(__SCREAMING_SNAKE_CASE       ,__SCREAMING_SNAKE_CASE		) else sep_token
						_A	:				List[str]   =      AddedToken(__SCREAMING_SNAKE_CASE       ,lstrip=__SCREAMING_SNAKE_CASE       ,rstrip=__SCREAMING_SNAKE_CASE		) if isinstance(__SCREAMING_SNAKE_CASE       ,__SCREAMING_SNAKE_CASE		) else cls_token
						_A	:				int   =      AddedToken(__SCREAMING_SNAKE_CASE       ,lstrip=__SCREAMING_SNAKE_CASE       ,rstrip=__SCREAMING_SNAKE_CASE		) if isinstance(__SCREAMING_SNAKE_CASE       ,__SCREAMING_SNAKE_CASE		) else unk_token
						_A	:				int   =      AddedToken(__SCREAMING_SNAKE_CASE       ,lstrip=__SCREAMING_SNAKE_CASE       ,rstrip=__SCREAMING_SNAKE_CASE		) if isinstance(__SCREAMING_SNAKE_CASE       ,__SCREAMING_SNAKE_CASE		) else pad_token

						# Mask token behave like a normal word, i.e. include the space before it
						_A	:				Any   =      AddedToken(__SCREAMING_SNAKE_CASE       ,lstrip=__SCREAMING_SNAKE_CASE       ,rstrip=__SCREAMING_SNAKE_CASE		) if isinstance(__SCREAMING_SNAKE_CASE       ,__SCREAMING_SNAKE_CASE		) else mask_token

						super().__init__(
						    errors=__SCREAMING_SNAKE_CASE       ,bos_token=__SCREAMING_SNAKE_CASE       ,eos_token=__SCREAMING_SNAKE_CASE       ,unk_token=__SCREAMING_SNAKE_CASE       ,sep_token=__SCREAMING_SNAKE_CASE       ,cls_token=__SCREAMING_SNAKE_CASE       ,pad_token=__SCREAMING_SNAKE_CASE       ,mask_token=__SCREAMING_SNAKE_CASE       ,add_prefix_space=__SCREAMING_SNAKE_CASE       ,**__SCREAMING_SNAKE_CASE       ,)

						with open(__SCREAMING_SNAKE_CASE       ,encoding='''utf-8'''		) as vocab_handle:
										_A	:				Dict   =      json.load(__SCREAMING_SNAKE_CASE		)
						_A	:				Any   =      {v: k for k, v in self.encoder.items()}
						_A	:				List[Any]   =      errors  # how to handle errors in decoding
						_A	:				int   =      bytes_to_unicode()
						_A	:				Dict   =      {v: k for k, v in self.byte_encoder.items()}
						with open(__SCREAMING_SNAKE_CASE       ,encoding='''utf-8'''		) as merges_handle:
										_A	:				Union[str, Any]   =      merges_handle.read().split('''\n'''		)[1:-1]
						_A	:				List[str]   =      [tuple(merge.split()		) for merge in bpe_merges]
						_A	:				Optional[Any]   =      dict(zip(__SCREAMING_SNAKE_CASE       ,range(len(__SCREAMING_SNAKE_CASE		)		)		)		)
						_A	:				List[Any]   =      {}
						_A	:				Optional[int]   =      add_prefix_space

						# Should have added re.IGNORECASE so BPE merges can happen for capitalized versions of contractions
						_A	:				Optional[int]   =      re.compile(r'''\'s|\'t|\'re|\'ve|\'m|\'ll|\'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+'''		)







		@property
		# Copied from transformers.models.bart.tokenization_bart.BartTokenizer.vocab_size
		def  A__      (					self		):
						return len(self.encoder		)







		def  A__      (					self		):
						return dict(self.encoder       ,**self.added_tokens_encoder		)







		def  A__      (					self       ,A__		):
						if token in self.cache:
										return self.cache[token]
						_A	:				List[str]   =      tuple(__SCREAMING_SNAKE_CASE		)
						_A	:				List[Any]   =      get_pairs(__SCREAMING_SNAKE_CASE		)

						if not pairs:
										return token

						while True:
										_A	:				int   =      min(__SCREAMING_SNAKE_CASE       ,key=lambda A__		: self.bpe_ranks.get(__SCREAMING_SNAKE_CASE       ,float('''inf'''		)		)		)
										if bigram not in self.bpe_ranks:
														break
										_A	:				Optional[Any]   =      bigram
										_A	:				int   =      []
										_A	:				Dict   =      0
										while i < len(__SCREAMING_SNAKE_CASE		):
														try:
																		_A	:				Optional[Any]   =      word.index(__SCREAMING_SNAKE_CASE       ,__SCREAMING_SNAKE_CASE		)
														except ValueError:
																		new_word.extend(word[i:]		)
																		break
														else:
																		new_word.extend(word[i:j]		)
																		_A	:				Dict   =      j

														if word[i] == first and i < len(__SCREAMING_SNAKE_CASE		) - 1 and word[i + 1] == second:
																		new_word.append(first + second		)
																		i += 2
														else:
																		new_word.append(word[i]		)
																		i += 1
										_A	:				Any   =      tuple(__SCREAMING_SNAKE_CASE		)
										_A	:				List[str]   =      new_word
										if len(__SCREAMING_SNAKE_CASE		) == 1:
														break
										else:
														_A	:				List[Any]   =      get_pairs(__SCREAMING_SNAKE_CASE		)
						_A	:				str   =      ''' '''.join(__SCREAMING_SNAKE_CASE		)
						_A	:				Dict   =      word
						return word







		def  A__      (					self       ,A__		):
						_A	:				Dict   =      []
						for token in re.findall(self.pat       ,__SCREAMING_SNAKE_CASE		):
										_A	:				int   =      ''''''.join(
										    self.byte_encoder[b] for b in token.encode('''utf-8'''		)		)  # Maps all our bytes to unicode strings, avoiding control tokens of the BPE (spaces in our case)
										bpe_tokens.extend(bpe_token for bpe_token in self.bpe(__SCREAMING_SNAKE_CASE		).split(''' '''		)		)
						return bpe_tokens







		def  A__      (					self       ,A__		):
						return self.encoder.get(__SCREAMING_SNAKE_CASE       ,self.encoder.get(self.unk_token		)		)







		def  A__      (					self       ,A__		):
						return self.decoder.get(__SCREAMING_SNAKE_CASE		)







		def  A__      (					self       ,A__		):
						_A	:				List[Any]   =      ''''''.join(__SCREAMING_SNAKE_CASE		)
						_A	:				str   =      bytearray([self.byte_decoder[c] for c in text]		).decode('''utf-8'''       ,errors=self.errors		)
						return text







		def  A__      (					self       ,A__       ,A__ = None		):
						if not os.path.isdir(__SCREAMING_SNAKE_CASE		):
										logger.error(f"""Vocabulary path ({save_directory}) should be a directory"""		)
										return
						_A	:				Tuple   =      os.path.join(
						    __SCREAMING_SNAKE_CASE       ,(filename_prefix + '''-''' if filename_prefix else '''''') + VOCAB_FILES_NAMES['''vocab_file''']		)
						_A	:				List[str]   =      os.path.join(
						    __SCREAMING_SNAKE_CASE       ,(filename_prefix + '''-''' if filename_prefix else '''''') + VOCAB_FILES_NAMES['''merges_file''']		)

						with open(__SCREAMING_SNAKE_CASE       ,'''w'''       ,encoding='''utf-8'''		) as f:
										f.write(json.dumps(self.encoder       ,indent=2       ,sort_keys=__SCREAMING_SNAKE_CASE       ,ensure_ascii=__SCREAMING_SNAKE_CASE		) + '''\n'''		)

						_A	:				Any   =      0
						with open(__SCREAMING_SNAKE_CASE       ,'''w'''       ,encoding='''utf-8'''		) as writer:
										writer.write('''#version: 0.2\n'''		)
										for bpe_tokens, token_index in sorted(self.bpe_ranks.items()       ,key=lambda A__		: kv[1]		):
														if index != token_index:
																		logger.warning(
																		    f"""Saving vocabulary to {merge_file}: BPE merge indices are not consecutive."""
																		    ''' Please check that the tokenizer is not corrupted!'''		)
																		_A	:				Any   =      token_index
														writer.write(''' '''.join(__SCREAMING_SNAKE_CASE		) + '''\n'''		)
														index += 1

						return vocab_file, merge_file







		def  A__      (					self       ,A__       ,A__ = None		):
						if token_ids_a is None:
										return [self.cls_token_id] + token_ids_a + [self.sep_token_id]
						_A	:				Optional[Any]   =      [self.cls_token_id]
						_A	:				Tuple   =      [self.sep_token_id]
						return cls + token_ids_a + sep + sep + token_ids_a + sep







		def  A__      (					self       ,A__       ,A__ = None       ,A__ = False		):
						if already_has_special_tokens:
										return super().get_special_tokens_mask(
										    token_ids_a=__SCREAMING_SNAKE_CASE       ,token_ids_a=__SCREAMING_SNAKE_CASE       ,already_has_special_tokens=__SCREAMING_SNAKE_CASE		)

						if token_ids_a is None:
										return [1] + ([0] * len(__SCREAMING_SNAKE_CASE		)) + [1]
						return [1] + ([0] * len(__SCREAMING_SNAKE_CASE		)) + [1, 1] + ([0] * len(__SCREAMING_SNAKE_CASE		)) + [1]







		def  A__      (					self       ,A__       ,A__ = None		):
						_A	:				Any   =      [self.sep_token_id]
						_A	:				Optional[Any]   =      [self.cls_token_id]

						if token_ids_a is None:
										return len(cls + token_ids_a + sep		) * [0]
						return len(cls + token_ids_a + sep + sep + token_ids_a + sep		) * [0]







		def  A__      (					self       ,A__       ,A__=False       ,**A__		):
						_A	:				List[Any]   =      kwargs.pop('''add_prefix_space'''       ,self.add_prefix_space		)
						if (is_split_into_words or add_prefix_space) and (len(__SCREAMING_SNAKE_CASE		) > 0 and not text[0].isspace()):
										_A	:				str   =      ''' ''' + text
						return (text, kwargs)







		def  A__      (					self       ,A__       ,A__ = None       ,A__ = PaddingStrategy.DO_NOT_PAD       ,A__ = None       ,A__ = None       ,):
						_A	:				List[str]   =      super()._pad(
						    encoded_inputs=__SCREAMING_SNAKE_CASE       ,max_length=__SCREAMING_SNAKE_CASE       ,padding_strategy=__SCREAMING_SNAKE_CASE       ,pad_to_multiple_of=__SCREAMING_SNAKE_CASE       ,return_attention_mask=__SCREAMING_SNAKE_CASE       ,)

						# Load from model defaults
						if return_attention_mask is None:
										_A	:				Tuple   =      '''attention_mask''' in self.model_input_names

						if return_attention_mask and "global_attention_mask" in encoded_inputs:
										_A	:				Tuple   =      encoded_inputs[self.model_input_names[0]]
										# `global_attention_mask` need to have the same length as other (sequential) inputs.
										_A	:				List[Any]   =      len(encoded_inputs['''global_attention_mask''']		) != len(__SCREAMING_SNAKE_CASE		)

										if needs_to_be_padded:
														_A	:				int   =      len(__SCREAMING_SNAKE_CASE		) - len(encoded_inputs['''global_attention_mask''']		)

														if self.padding_side == "right":
																		# Use `-1` since `0` in `global_attention_mask` means `local attention` instead of `not to attend`
																		_A	:				Optional[int]   =      (
																		    encoded_inputs['''global_attention_mask'''] + [-1] * difference
																		)
														elif self.padding_side == "left":
																		_A	:				List[Any]   =      [-1] * difference + encoded_inputs[
																		    '''global_attention_mask'''
																		]
														else:
																		raise ValueError('''Invalid padding strategy:''' + str(self.padding_side		)		)

						return encoded_inputs











'''simple docstring'''







from binascii import hexlify
from hashlib import shaaaa
from os import urandom

# RFC 3526 - More Modular Exponential (MODP) Diffie-Hellman groups for
# Internet Key Exchange (IKE) https://tools.ietf.org/html/rfc3526

__lowerCAmelCase									=   {
    # 1536-bit
    5: {
        'prime': int(
            'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'
            + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'
            + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'
            + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'
            + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'
            + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'
            + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'
            + '670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF',
            base=16,
        ),
        'generator': 2,
    },
    # 2048-bit
    14: {
        'prime': int(
            'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'
            + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'
            + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'
            + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'
            + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'
            + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'
            + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'
            + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'
            + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'
            + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'
            + '15728E5A8AACAA68FFFFFFFFFFFFFFFF',
            base=16,
        ),
        'generator': 2,
    },
    # 3072-bit
    15: {
        'prime': int(
            'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'
            + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'
            + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'
            + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'
            + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'
            + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'
            + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'
            + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'
            + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'
            + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'
            + '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'
            + 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'
            + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'
            + 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'
            + 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'
            + '43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF',
            base=16,
        ),
        'generator': 2,
    },
    # 4096-bit
    16: {
        'prime': int(
            'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'
            + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'
            + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'
            + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'
            + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'
            + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'
            + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'
            + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'
            + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'
            + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'
            + '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'
            + 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'
            + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'
            + 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'
            + 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'
            + '43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7'
            + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA'
            + '2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6'
            + '287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED'
            + '1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9'
            + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199'
            + 'FFFFFFFFFFFFFFFF',
            base=16,
        ),
        'generator': 2,
    },
    # 6144-bit
    17: {
        'prime': int(
            'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08'
            + '8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B'
            + '302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9'
            + 'A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE6'
            + '49286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8'
            + 'FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D'
            + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C'
            + '180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718'
            + '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D'
            + '04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7D'
            + 'B3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D226'
            + '1AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200C'
            + 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFC'
            + 'E0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B26'
            + '99C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB'
            + '04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2'
            + '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127'
            + 'D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492'
            + '36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406'
            + 'AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918'
            + 'DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B33205151'
            + '2BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03'
            + 'F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97F'
            + 'BEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA'
            + 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58B'
            + 'B7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632'
            + '387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E'
            + '6DCC4024FFFFFFFFFFFFFFFF',
            base=16,
        ),
        'generator': 2,
    },
    # 8192-bit
    18: {
        'prime': int(
            'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1'
            + '29024E088A67CC74020BBEA63B139B22514A08798E3404DD'
            + 'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245'
            + 'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED'
            + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D'
            + 'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F'
            + '83655D23DCA3AD961C62F356208552BB9ED529077096966D'
            + '670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B'
            + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9'
            + 'DE2BCBF6955817183995497CEA956AE515D2261898FA0510'
            + '15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64'
            + 'ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7'
            + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B'
            + 'F12FFA06D98A0864D87602733EC86A64521F2B18177B200C'
            + 'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31'
            + '43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7'
            + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA'
            + '2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6'
            + '287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED'
            + '1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9'
            + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492'
            + '36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD'
            + 'F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831'
            + '179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B'
            + 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF'
            + '5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6'
            + 'D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3'
            + '23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA'
            + 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328'
            + '06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C'
            + 'DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE'
            + '12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4'
            + '38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300'
            + '741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568'
            + '3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9'
            + '22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B'
            + '4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A'
            + '062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36'
            + '4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1'
            + 'B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92'
            + '4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47'
            + '9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71'
            + '60C980DD98EDD3DFFFFFFFFFFFFFFFFF',
            base=16,
        ),
        'generator': 2,
    },
}





class 						SCREAMING_SNAKE_CASE       :






			def __init__(			self   :      Any	,    __SCREAMING_SNAKE_CASE   :      int = 14       )      ->      None:
							if group not in primes:
											raise ValueError('''Unsupported Group'''       )
							a_		:	Union[str, Any]									=   primes[group]['''prime''']
							a_		:	List[str]									=   primes[group]['''generator''']

							a_		:	str									=   int(hexlify(urandom(32       )       )	,    base=16       )






			def       SCREAMING_SNAKE_CASE   (			self   :      str       )      ->      str:
							return hex(self.__private_key       )[2:]






			def       SCREAMING_SNAKE_CASE   (			self   :      List[Any]       )      ->      str:
							a_		:	Dict									=   pow(self.generator	,    self.__private_key	,    self.prime       )
							return hex(__SCREAMING_SNAKE_CASE       )[2:]






			def       SCREAMING_SNAKE_CASE   (			self   :      Any	,    __SCREAMING_SNAKE_CASE   :      int       )      ->      bool:
							# check if the other public key is valid based on NIST SP800-56
							return (
							    2 <= key <= self.prime - 2
							    and pow(__SCREAMING_SNAKE_CASE	,    (self.prime - 1) // 2	,    self.prime       ) == 1
							)






			def       SCREAMING_SNAKE_CASE   (			self   :      Optional[Any]	,    __SCREAMING_SNAKE_CASE   :      str       )      ->      str:
							a_		:	str									=   int(__SCREAMING_SNAKE_CASE	,    base=16       )
							if not self.is_valid_public_key(__SCREAMING_SNAKE_CASE       ):
											raise ValueError('''Invalid public key'''       )
							a_		:	Optional[int]									=   pow(__SCREAMING_SNAKE_CASE	,    self.__private_key	,    self.prime       )
							return shaaaa(str(__SCREAMING_SNAKE_CASE       ).encode()       ).hexdigest()






			@staticmethod
			def       SCREAMING_SNAKE_CASE   (			__SCREAMING_SNAKE_CASE   :      int	,    __SCREAMING_SNAKE_CASE   :      int       )      ->      bool:
							# check if the other public key is valid based on NIST SP800-56
							return (
							    2 <= remote_public_key_str <= prime - 2
							    and pow(__SCREAMING_SNAKE_CASE	,    (prime - 1) // 2	,    __SCREAMING_SNAKE_CASE       ) == 1
							)







			@staticmethod
			def       SCREAMING_SNAKE_CASE   (			__SCREAMING_SNAKE_CASE   :      str	,    __SCREAMING_SNAKE_CASE   :      str	,    __SCREAMING_SNAKE_CASE   :      int = 14       )      ->      str:
							a_		:	Tuple									=   int(__SCREAMING_SNAKE_CASE	,    base=16       )
							a_		:	Any									=   int(__SCREAMING_SNAKE_CASE	,    base=16       )
							a_		:	List[str]									=   primes[group]['''prime''']
							if not DiffieHellman.is_valid_public_key_static(__SCREAMING_SNAKE_CASE	,    __SCREAMING_SNAKE_CASE       ):
											raise ValueError('''Invalid public key'''       )
							a_		:	Optional[int]									=   pow(__SCREAMING_SNAKE_CASE	,    __SCREAMING_SNAKE_CASE	,    __SCREAMING_SNAKE_CASE       )
							return shaaaa(str(__SCREAMING_SNAKE_CASE       ).encode()       ).hexdigest()


if __name__ == "__main__":
		import doctest

		doctest.testmod()




