



import argparse
import json

import torch

from diffusers import DDPMScheduler, LDMPipeline, UNetaDModel, VQModel






def      lowerCAmelCase__		(   lowerCamelCase_		:		Optional[int]	,lowerCamelCase_		:		Union[str, Any]=1):





				'''simple docstring'''

				if n_shave_prefix_segments >= 0:
								return ".".join(path.split('''.''')[n_shave_prefix_segments:])
				else:
								return ".".join(path.split('''.''')[:n_shave_prefix_segments])






def      lowerCAmelCase__		(   lowerCamelCase_		:		Union[str, Any]	,lowerCamelCase_		:		List[Any]=0):





				'''simple docstring'''

				lowerCAmelCase__					:    Tuple												=					[]
				for old_item in old_list:
								lowerCAmelCase__					:    Dict												=					old_item.replace('''in_layers.0'''	,'''norm1''')
								lowerCAmelCase__					:    Optional[int]												=					new_item.replace('''in_layers.2'''	,'''conv1''')

								lowerCAmelCase__					:    str												=					new_item.replace('''out_layers.0'''	,'''norm2''')
								lowerCAmelCase__					:    Optional[Any]												=					new_item.replace('''out_layers.3'''	,'''conv2''')

								lowerCAmelCase__					:    Any												=					new_item.replace('''emb_layers.1'''	,'''time_emb_proj''')
								lowerCAmelCase__					:    Union[str, Any]												=					new_item.replace('''skip_connection'''	,'''conv_shortcut''')

								lowerCAmelCase__					:    Tuple												=					shave_segments(lowerCamelCase_	,n_shave_prefix_segments=lowerCamelCase_)

								mapping.append({'''old''': old_item, '''new''': new_item})

				return mapping






def      lowerCAmelCase__		(   lowerCamelCase_		:		List[Any]	,lowerCamelCase_		:		Tuple=0):





				'''simple docstring'''

				lowerCAmelCase__					:    int												=					[]
				for old_item in old_list:
								lowerCAmelCase__					:    Dict												=					old_item

								lowerCAmelCase__					:    Optional[Any]												=					new_item.replace('''norm.weight'''	,'''group_norm.weight''')
								lowerCAmelCase__					:    Union[str, Any]												=					new_item.replace('''norm.bias'''	,'''group_norm.bias''')

								lowerCAmelCase__					:    str												=					new_item.replace('''proj_out.weight'''	,'''proj_attn.weight''')
								lowerCAmelCase__					:    str												=					new_item.replace('''proj_out.bias'''	,'''proj_attn.bias''')

								lowerCAmelCase__					:    List[Any]												=					shave_segments(lowerCamelCase_	,n_shave_prefix_segments=lowerCamelCase_)

								mapping.append({'''old''': old_item, '''new''': new_item})

				return mapping






def      lowerCAmelCase__		(   lowerCamelCase_		:		Optional[Any]	,lowerCamelCase_		:		Any	,lowerCamelCase_		:		str	,lowerCamelCase_		:		Union[str, Any]=None	,lowerCamelCase_		:		Any=None	,lowerCamelCase_		:		List[str]=None):





				'''simple docstring'''

				assert isinstance(lowerCamelCase_	,lowerCamelCase_), "Paths should be a list of dicts containing 'old' and 'new' keys."

				# Splits the attention layers into three variables.
				if attention_paths_to_split is not None:
								for path, path_map in attention_paths_to_split.items():
												lowerCAmelCase__					:    Optional[Any]												=					old_checkpoint[path]
												lowerCAmelCase__					:    Optional[Any]												=					old_tensor.shape[0] // 3

												lowerCAmelCase__					:    Any												=					(-1, channels) if len(old_tensor.shape) == 3 else (-1)

												lowerCAmelCase__					:    Dict												=					old_tensor.shape[0] // config['''num_head_channels'''] // 3

												lowerCAmelCase__					:    List[Any]												=					old_tensor.reshape((num_heads, 3 * channels // num_heads) + old_tensor.shape[1:])
												lowerCAmelCase__						,		lowerCAmelCase__						,		lowerCAmelCase__					:    List[str]												=					old_tensor.split(channels // num_heads	,dim=1)

												lowerCAmelCase__					:    List[Any]												=					query.reshape(lowerCamelCase_)
												lowerCAmelCase__					:    List[Any]												=					key.reshape(lowerCamelCase_)
												lowerCAmelCase__					:    Union[str, Any]												=					value.reshape(lowerCamelCase_)

				for path in paths:
								lowerCAmelCase__					:    Optional[int]												=					path['''new''']

								# These have already been assigned
								if attention_paths_to_split is not None and new_path in attention_paths_to_split:
												continue

								# Global renaming happens here
								lowerCAmelCase__					:    Union[str, Any]												=					new_path.replace('''middle_block.0'''	,'''mid_block.resnets.0''')
								lowerCAmelCase__					:    int												=					new_path.replace('''middle_block.1'''	,'''mid_block.attentions.0''')
								lowerCAmelCase__					:    Any												=					new_path.replace('''middle_block.2'''	,'''mid_block.resnets.1''')

								if additional_replacements is not None:
												for replacement in additional_replacements:
																lowerCAmelCase__					:    Dict												=					new_path.replace(replacement['''old''']	,replacement['''new'''])

        # proj_attn.weight has to be converted from conv 1D to linear
								if "proj_attn.weight" in new_path:
												lowerCAmelCase__					:    int												=					old_checkpoint[path['''old''']][:, :, 0]
								else:
												lowerCAmelCase__					:    Dict												=					old_checkpoint[path['''old''']]






def      lowerCAmelCase__		(   lowerCamelCase_		:		List[str]	,lowerCamelCase_		:		Dict):





				'''simple docstring'''

				lowerCAmelCase__					:    str												=					{}

				lowerCAmelCase__					:    List[str]												=					checkpoint['''time_embed.0.weight''']
				lowerCAmelCase__					:    str												=					checkpoint['''time_embed.0.bias''']
				lowerCAmelCase__					:    str												=					checkpoint['''time_embed.2.weight''']
				lowerCAmelCase__					:    Optional[int]												=					checkpoint['''time_embed.2.bias''']

				lowerCAmelCase__					:    Optional[Any]												=					checkpoint['''input_blocks.0.0.weight''']
				lowerCAmelCase__					:    int												=					checkpoint['''input_blocks.0.0.bias''']

				lowerCAmelCase__					:    Any												=					checkpoint['''out.0.weight''']
				lowerCAmelCase__					:    Tuple												=					checkpoint['''out.0.bias''']
				lowerCAmelCase__					:    str												=					checkpoint['''out.2.weight''']
				lowerCAmelCase__					:    Optional[Any]												=					checkpoint['''out.2.bias''']

				# Retrieves the keys for the input blocks only
				lowerCAmelCase__					:    int												=					len({'''.'''.join(layer.split('''.''')[:2]) for layer in checkpoint if '''input_blocks''' in layer})
				lowerCAmelCase__					:    Dict												=					{
				    layer_id: [key for key in checkpoint if f"""input_blocks.{layer_id}""" in key]
				    for layer_id in range(lowerCamelCase_)
				}

				# Retrieves the keys for the middle blocks only
				lowerCAmelCase__					:    Optional[int]												=					len({'''.'''.join(layer.split('''.''')[:2]) for layer in checkpoint if '''middle_block''' in layer})
				lowerCAmelCase__					:    List[str]												=					{
				    layer_id: [key for key in checkpoint if f"""middle_block.{layer_id}""" in key]
				    for layer_id in range(lowerCamelCase_)
				}

				# Retrieves the keys for the output blocks only
				lowerCAmelCase__					:    Any												=					len({'''.'''.join(layer.split('''.''')[:2]) for layer in checkpoint if '''output_blocks''' in layer})
				lowerCAmelCase__					:    str												=					{
				    layer_id: [key for key in checkpoint if f"""output_blocks.{layer_id}""" in key]
				    for layer_id in range(lowerCamelCase_)
				}

				for i in range(1	,lowerCamelCase_):
								lowerCAmelCase__					:    List[Any]												=					(i - 1) // (config['''num_res_blocks'''] + 1)
								lowerCAmelCase__					:    Optional[int]												=					(i - 1) % (config['''num_res_blocks'''] + 1)

								lowerCAmelCase__					:    List[Any]												=					[key for key in input_blocks[i] if f"""input_blocks.{i}.0""" in key]
								lowerCAmelCase__					:    Tuple												=					[key for key in input_blocks[i] if f"""input_blocks.{i}.1""" in key]

								if f"""input_blocks.{i}.0.op.weight""" in checkpoint:
												lowerCAmelCase__					:    Optional[Any]												=					checkpoint[
												    f"""input_blocks.{i}.0.op.weight"""
												]
												lowerCAmelCase__					:    Optional[Any]												=					checkpoint[
												    f"""input_blocks.{i}.0.op.bias"""
												]
												continue

								lowerCAmelCase__					:    List[Any]												=					renew_resnet_paths(lowerCamelCase_)
								lowerCAmelCase__					:    Tuple												=					{'''old''': f"""input_blocks.{i}.0""", '''new''': f"""down_blocks.{block_id}.resnets.{layer_in_block_id}"""}
								lowerCAmelCase__					:    Tuple												=					{'''old''': '''resnets.2.op''', '''new''': '''downsamplers.0.op'''}
								assign_to_checkpoint(
								    lowerCamelCase_	,lowerCamelCase_	,lowerCamelCase_	,additional_replacements=[meta_path, resnet_op]	,config=lowerCamelCase_)

								if len(lowerCamelCase_):
												lowerCAmelCase__					:    int												=					renew_attention_paths(lowerCamelCase_)
												lowerCAmelCase__					:    str												=					{
												    '''old''': f"""input_blocks.{i}.1""",
												    '''new''': f"""down_blocks.{block_id}.attentions.{layer_in_block_id}""",
												}
												lowerCAmelCase__					:    Optional[int]												=					{
												    f"""input_blocks.{i}.1.qkv.bias""": {
												        '''key''': f"""down_blocks.{block_id}.attentions.{layer_in_block_id}.key.bias""",
												        '''query''': f"""down_blocks.{block_id}.attentions.{layer_in_block_id}.query.bias""",
												        '''value''': f"""down_blocks.{block_id}.attentions.{layer_in_block_id}.value.bias""",
												    },
												    f"""input_blocks.{i}.1.qkv.weight""": {
												        '''key''': f"""down_blocks.{block_id}.attentions.{layer_in_block_id}.key.weight""",
												        '''query''': f"""down_blocks.{block_id}.attentions.{layer_in_block_id}.query.weight""",
												        '''value''': f"""down_blocks.{block_id}.attentions.{layer_in_block_id}.value.weight""",
												    },
												}
												assign_to_checkpoint(
												    lowerCamelCase_	,lowerCamelCase_	,lowerCamelCase_	,additional_replacements=[meta_path]	,attention_paths_to_split=lowerCamelCase_	,config=lowerCamelCase_	,)

				lowerCAmelCase__					:    List[Any]												=					middle_blocks[0]
				lowerCAmelCase__					:    Dict												=					middle_blocks[1]
				lowerCAmelCase__					:    int												=					middle_blocks[2]

				lowerCAmelCase__					:    Optional[Any]												=					renew_resnet_paths(lowerCamelCase_)
				assign_to_checkpoint(lowerCamelCase_	,lowerCamelCase_	,lowerCamelCase_	,config=lowerCamelCase_)

				lowerCAmelCase__					:    Optional[int]												=					renew_resnet_paths(lowerCamelCase_)
				assign_to_checkpoint(lowerCamelCase_	,lowerCamelCase_	,lowerCamelCase_	,config=lowerCamelCase_)

				lowerCAmelCase__					:    List[Any]												=					renew_attention_paths(lowerCamelCase_)
				lowerCAmelCase__					:    Union[str, Any]												=					{
				    '''middle_block.1.qkv.bias''': {
				        '''key''': '''mid_block.attentions.0.key.bias''',
				        '''query''': '''mid_block.attentions.0.query.bias''',
				        '''value''': '''mid_block.attentions.0.value.bias''',
				    },
				    '''middle_block.1.qkv.weight''': {
				        '''key''': '''mid_block.attentions.0.key.weight''',
				        '''query''': '''mid_block.attentions.0.query.weight''',
				        '''value''': '''mid_block.attentions.0.value.weight''',
				    },
				}
				assign_to_checkpoint(
				    lowerCamelCase_	,lowerCamelCase_	,lowerCamelCase_	,attention_paths_to_split=lowerCamelCase_	,config=lowerCamelCase_)

				for i in range(lowerCamelCase_):
								lowerCAmelCase__					:    Union[str, Any]												=					i // (config['''num_res_blocks'''] + 1)
								lowerCAmelCase__					:    str												=					i % (config['''num_res_blocks'''] + 1)
								lowerCAmelCase__					:    str												=					[shave_segments(lowerCamelCase_	,2) for name in output_blocks[i]]
								lowerCAmelCase__					:    Any												=					{}

								for layer in output_block_layers:
												lowerCAmelCase__						,		lowerCAmelCase__					:    Tuple												=					layer.split('''.''')[0], shave_segments(lowerCamelCase_	,1)
												if layer_id in output_block_list:
																output_block_list[layer_id].append(lowerCamelCase_)
												else:
																lowerCAmelCase__					:    Dict												=					[layer_name]

								if len(lowerCamelCase_) > 1:
												lowerCAmelCase__					:    Union[str, Any]												=					[key for key in output_blocks[i] if f"""output_blocks.{i}.0""" in key]
												lowerCAmelCase__					:    Tuple												=					[key for key in output_blocks[i] if f"""output_blocks.{i}.1""" in key]

												lowerCAmelCase__					:    int												=					renew_resnet_paths(lowerCamelCase_)
												lowerCAmelCase__					:    Dict												=					renew_resnet_paths(lowerCamelCase_)

												lowerCAmelCase__					:    str												=					{'''old''': f"""output_blocks.{i}.0""", '''new''': f"""up_blocks.{block_id}.resnets.{layer_in_block_id}"""}
												assign_to_checkpoint(lowerCamelCase_	,lowerCamelCase_	,lowerCamelCase_	,additional_replacements=[meta_path]	,config=lowerCamelCase_)

												if ["conv.weight", "conv.bias"] in output_block_list.values():
																lowerCAmelCase__					:    Dict												=					list(output_block_list.values()).index(['''conv.weight''', '''conv.bias'''])
																lowerCAmelCase__					:    Dict												=					checkpoint[
																    f"""output_blocks.{i}.{index}.conv.weight"""
																]
																lowerCAmelCase__					:    Union[str, Any]												=					checkpoint[
																    f"""output_blocks.{i}.{index}.conv.bias"""
																]

																# Clear attentions as they have been attributed above.
																if len(lowerCamelCase_) == 2:
																				lowerCAmelCase__					:    Any												=					[]

												if len(lowerCamelCase_):
																lowerCAmelCase__					:    Union[str, Any]												=					renew_attention_paths(lowerCamelCase_)
																lowerCAmelCase__					:    List[Any]												=					{
																    '''old''': f"""output_blocks.{i}.1""",
																    '''new''': f"""up_blocks.{block_id}.attentions.{layer_in_block_id}""",
																}
																lowerCAmelCase__					:    Dict												=					{
																    f"""output_blocks.{i}.1.qkv.bias""": {
																        '''key''': f"""up_blocks.{block_id}.attentions.{layer_in_block_id}.key.bias""",
																        '''query''': f"""up_blocks.{block_id}.attentions.{layer_in_block_id}.query.bias""",
																        '''value''': f"""up_blocks.{block_id}.attentions.{layer_in_block_id}.value.bias""",
																    },
																    f"""output_blocks.{i}.1.qkv.weight""": {
																        '''key''': f"""up_blocks.{block_id}.attentions.{layer_in_block_id}.key.weight""",
																        '''query''': f"""up_blocks.{block_id}.attentions.{layer_in_block_id}.query.weight""",
																        '''value''': f"""up_blocks.{block_id}.attentions.{layer_in_block_id}.value.weight""",
																    },
																}
																assign_to_checkpoint(
																    lowerCamelCase_	,lowerCamelCase_	,lowerCamelCase_	,additional_replacements=[meta_path]	,attention_paths_to_split=to_split if any('''qkv''' in key for key in attentions) else None	,config=lowerCamelCase_	,)
								else:
												lowerCAmelCase__					:    Tuple												=					renew_resnet_paths(lowerCamelCase_	,n_shave_prefix_segments=1)
												for path in resnet_0_paths:
																lowerCAmelCase__					:    Tuple												=					'''.'''.join(['''output_blocks''', str(lowerCamelCase_), path['''old''']])
																lowerCAmelCase__					:    Any												=					'''.'''.join(['''up_blocks''', str(lowerCamelCase_), '''resnets''', str(lowerCamelCase_), path['''new''']])

																lowerCAmelCase__					:    List[str]												=					checkpoint[old_path]

				return new_checkpoint


if __name__ == "__main__":
							__snake_case    :		List[Any]  =argparse.ArgumentParser()

							parser.add_argument(
							    '--checkpoint_path', default=None, type=str, required=True, help='Path to the checkpoint to convert.'
							)

							parser.add_argument(
							    '--config_file',
							    default=None,
							    type=str,
							    required=True,
							    help='The config json file corresponding to the architecture.',
							)

							parser.add_argument('--dump_path', default=None, type=str, required=True, help='Path to the output model.')

							__snake_case    :		Optional[int]  =parser.parse_args()

							__snake_case    :		int  =torch.load(args.checkpoint_path)

							with open(args.config_file) as f:
														__snake_case    :		List[Any]  =json.loads(f.read())

							__snake_case    :		str  =convert_ldm_checkpoint(checkpoint, config)

							if "ldm" in config:
														del config["ldm"]

							__snake_case    :		str  =UNetaDModel(**config)
							model.load_state_dict(converted_checkpoint)

							try:
														__snake_case    :		List[str]  =DDPMScheduler.from_config('/'.join(args.checkpoint_path.split('/')[:-1]))
														__snake_case    :		Any  =VQModel.from_pretrained('/'.join(args.checkpoint_path.split('/')[:-1]))

														__snake_case    :		List[str]  =LDMPipeline(unet=model, scheduler=scheduler, vae=vqvae)
														pipe.save_pretrained(args.dump_path)
							except:  # noqa: E722
														model.save_pretrained(args.dump_path)






import string

import numpy






def      lowerCAmelCase__		(   lowerCamelCase_		:		int	,lowerCamelCase_		:		int):





				'''simple docstring'''

				return b if a == 0 else greatest_common_divisor(b % a	,lowerCamelCase_)



class 	lowerCamelCase__      :




		'''simple docstring'''



		snake_case_     =string.ascii_uppercase + string.digits
		# This cipher takes alphanumerics into account
		# i.e. a total of 36 characters

		# take x and return x % len(key_string)
		snake_case_     =numpy.vectorize(lambda lowerCamelCase__: x % 36)

		snake_case_     =numpy.vectorize(lowerCamelCase__)



		def __init__(self		,__lowerCamelCase			)					->      None:

						"""simple docstring"""






						lowerCAmelCase__					:    Tuple												=					self.modulus(__lowerCamelCase			)  # mod36 calc's on the encrypt key
						self.check_determinant()  # validate the determinant of the encryption key
						lowerCAmelCase__					:    Optional[int]												=					encrypt_key.shape[0]



		def 		lowerCAmelCase__				(self		,__lowerCamelCase			)					->      int:

						"""simple docstring"""






						return self.key_string.index(__lowerCamelCase			)



		def 		lowerCAmelCase__				(self		,__lowerCamelCase			)					->      str:

						"""simple docstring"""






						return self.key_string[round(__lowerCamelCase			)]



		def 		lowerCAmelCase__				(self			)					->      None:

						"""simple docstring"""






						lowerCAmelCase__					:    Tuple												=					round(numpy.linalg.det(self.encrypt_key			)			)

						if det < 0:
										lowerCAmelCase__					:    str												=					det % len(self.key_string			)

						lowerCAmelCase__					:    Optional[Any]												=					len(self.key_string			)
						if greatest_common_divisor(__lowerCamelCase		,len(self.key_string			)			) != 1:
										lowerCAmelCase__					:    List[str]												=					(
										    f"""determinant modular {req_l} of encryption key({det}) """
										    f"""is not co prime w.r.t {req_l}.\nTry another key."""
										)
										raise ValueError(__lowerCamelCase			)



		def 		lowerCAmelCase__				(self		,__lowerCamelCase			)					->      str:

						"""simple docstring"""






						lowerCAmelCase__					:    Dict												=					[char for char in text.upper() if char in self.key_string]

						lowerCAmelCase__					:    int												=					chars[-1]
						while len(__lowerCamelCase			) % self.break_key != 0:
										chars.append(__lowerCamelCase			)

						return "".join(__lowerCamelCase			)



		def 		lowerCAmelCase__				(self		,__lowerCamelCase			)					->      str:

						"""simple docstring"""






						lowerCAmelCase__					:    List[str]												=					self.process_text(text.upper()			)
						lowerCAmelCase__					:    str												=					''''''

						for i in range(0		,len(__lowerCamelCase			) - self.break_key + 1		,self.break_key			):
										lowerCAmelCase__					:    Any												=					text[i : i + self.break_key]
										lowerCAmelCase__					:    Dict												=					[self.replace_letters(__lowerCamelCase			) for char in batch]
										lowerCAmelCase__					:    int												=					numpy.array([vec]			).T
										lowerCAmelCase__					:    Union[str, Any]												=					self.modulus(self.encrypt_key.dot(__lowerCamelCase			)			).T.tolist()[
										    0
										]
										lowerCAmelCase__					:    Union[str, Any]												=					''''''.join(
										    self.replace_digits(__lowerCamelCase			) for num in batch_encrypted			)
										encrypted += encrypted_batch

						return encrypted



		def 		lowerCAmelCase__				(self			)					->      numpy.ndarray:

						"""simple docstring"""






						lowerCAmelCase__					:    Tuple												=					round(numpy.linalg.det(self.encrypt_key			)			)

						if det < 0:
										lowerCAmelCase__					:    int												=					det % len(self.key_string			)
						lowerCAmelCase__					:    Dict												=					None
						for i in range(len(self.key_string			)			):
										if (det * i) % len(self.key_string			) == 1:
														lowerCAmelCase__					:    Optional[Any]												=					i
														break

						lowerCAmelCase__					:    Optional[Any]												=					(
						    det_inv
						    * numpy.linalg.det(self.encrypt_key			)
						    * numpy.linalg.inv(self.encrypt_key			)
						)

						return self.to_int(self.modulus(__lowerCamelCase			)			)



		def 		lowerCAmelCase__				(self		,__lowerCamelCase			)					->      str:

						"""simple docstring"""






						lowerCAmelCase__					:    str												=					self.make_decrypt_key()
						lowerCAmelCase__					:    List[str]												=					self.process_text(text.upper()			)
						lowerCAmelCase__					:    Optional[Any]												=					''''''

						for i in range(0		,len(__lowerCamelCase			) - self.break_key + 1		,self.break_key			):
										lowerCAmelCase__					:    List[Any]												=					text[i : i + self.break_key]
										lowerCAmelCase__					:    Tuple												=					[self.replace_letters(__lowerCamelCase			) for char in batch]
										lowerCAmelCase__					:    Optional[Any]												=					numpy.array([vec]			).T
										lowerCAmelCase__					:    Tuple												=					self.modulus(decrypt_key.dot(__lowerCamelCase			)			).T.tolist()[0]
										lowerCAmelCase__					:    Optional[int]												=					''''''.join(
										    self.replace_digits(__lowerCamelCase			) for num in batch_decrypted			)
										decrypted += decrypted_batch

						return decrypted






def      lowerCAmelCase__		(   ):





				'''simple docstring'''

				lowerCAmelCase__					:    Any												=					int(input('''Enter the order of the encryption key: '''))
				lowerCAmelCase__					:    Union[str, Any]												=					[]

				print('''Enter each row of the encryption key with space separated integers''')
				for _ in range(lowerCamelCase_):
								lowerCAmelCase__					:    int												=					[int(lowerCamelCase_) for x in input().split()]
								hill_matrix.append(lowerCamelCase_)

				lowerCAmelCase__					:    List[str]												=					HillCipher(numpy.array(lowerCamelCase_))

				print('''Would you like to encrypt or decrypt some text? (1 or 2)''')
				lowerCAmelCase__					:    List[Any]												=					input('''\n1. Encrypt\n2. Decrypt\n''')
				if option == "1":
								lowerCAmelCase__					:    Optional[int]												=					input('''What text would you like to encrypt?: ''')
								print('''Your encrypted text is:''')
								print(hc.encrypt(lowerCamelCase_))
				elif option == "2":
								lowerCAmelCase__					:    Dict												=					input('''What text would you like to decrypt?: ''')
								print('''Your decrypted text is:''')
								print(hc.decrypt(lowerCamelCase_))


if __name__ == "__main__":
							import doctest

							doctest.testmod()

							main()

