


'''simple docstring'''
import argparse
from collections import OrderedDict
from pathlib import Path

import torch
from huggingface_hub import hf_hub_download
from PIL import Image
from torchvision.transforms import functional as F

from transformers import DetrImageProcessor, TableTransformerConfig, TableTransformerForObjectDetection
from transformers.utils import logging


logging.set_verbosity_info()
__snake_case							   =  logging.get_logger(__name__)

# here we list all keys to be renamed (original name on the left, our name on the right)
__snake_case							   =  []
for i in range(6):
		# encoder layers: output projection, 2 feedforward neural networks and 2 layernorms
		rename_keys.append(
		    (F"""transformer.encoder.layers.{i}.self_attn.out_proj.weight""", F"""encoder.layers.{i}.self_attn.out_proj.weight""")
		)
		rename_keys.append(
		    (F"""transformer.encoder.layers.{i}.self_attn.out_proj.bias""", F"""encoder.layers.{i}.self_attn.out_proj.bias""")
		)
		rename_keys.append((F"""transformer.encoder.layers.{i}.linear1.weight""", F"""encoder.layers.{i}.fc1.weight"""))
		rename_keys.append((F"""transformer.encoder.layers.{i}.linear1.bias""", F"""encoder.layers.{i}.fc1.bias"""))
		rename_keys.append((F"""transformer.encoder.layers.{i}.linear2.weight""", F"""encoder.layers.{i}.fc2.weight"""))
		rename_keys.append((F"""transformer.encoder.layers.{i}.linear2.bias""", F"""encoder.layers.{i}.fc2.bias"""))
		rename_keys.append(
		    (F"""transformer.encoder.layers.{i}.norm1.weight""", F"""encoder.layers.{i}.self_attn_layer_norm.weight""")
		)
		rename_keys.append((F"""transformer.encoder.layers.{i}.norm1.bias""", F"""encoder.layers.{i}.self_attn_layer_norm.bias"""))
		rename_keys.append((F"""transformer.encoder.layers.{i}.norm2.weight""", F"""encoder.layers.{i}.final_layer_norm.weight"""))
		rename_keys.append((F"""transformer.encoder.layers.{i}.norm2.bias""", F"""encoder.layers.{i}.final_layer_norm.bias"""))
		# decoder layers: 2 times output projection, 2 feedforward neural networks and 3 layernorms
		rename_keys.append(
		    (F"""transformer.decoder.layers.{i}.self_attn.out_proj.weight""", F"""decoder.layers.{i}.self_attn.out_proj.weight""")
		)
		rename_keys.append(
		    (F"""transformer.decoder.layers.{i}.self_attn.out_proj.bias""", F"""decoder.layers.{i}.self_attn.out_proj.bias""")
		)
		rename_keys.append(
		    (
		        F"""transformer.decoder.layers.{i}.multihead_attn.out_proj.weight""",
		        F"""decoder.layers.{i}.encoder_attn.out_proj.weight""",
		    )
		)
		rename_keys.append(
		    (
		        F"""transformer.decoder.layers.{i}.multihead_attn.out_proj.bias""",
		        F"""decoder.layers.{i}.encoder_attn.out_proj.bias""",
		    )
		)
		rename_keys.append((F"""transformer.decoder.layers.{i}.linear1.weight""", F"""decoder.layers.{i}.fc1.weight"""))
		rename_keys.append((F"""transformer.decoder.layers.{i}.linear1.bias""", F"""decoder.layers.{i}.fc1.bias"""))
		rename_keys.append((F"""transformer.decoder.layers.{i}.linear2.weight""", F"""decoder.layers.{i}.fc2.weight"""))
		rename_keys.append((F"""transformer.decoder.layers.{i}.linear2.bias""", F"""decoder.layers.{i}.fc2.bias"""))
		rename_keys.append(
		    (F"""transformer.decoder.layers.{i}.norm1.weight""", F"""decoder.layers.{i}.self_attn_layer_norm.weight""")
		)
		rename_keys.append((F"""transformer.decoder.layers.{i}.norm1.bias""", F"""decoder.layers.{i}.self_attn_layer_norm.bias"""))
		rename_keys.append(
		    (F"""transformer.decoder.layers.{i}.norm2.weight""", F"""decoder.layers.{i}.encoder_attn_layer_norm.weight""")
		)
		rename_keys.append(
		    (F"""transformer.decoder.layers.{i}.norm2.bias""", F"""decoder.layers.{i}.encoder_attn_layer_norm.bias""")
		)
		rename_keys.append((F"""transformer.decoder.layers.{i}.norm3.weight""", F"""decoder.layers.{i}.final_layer_norm.weight"""))
		rename_keys.append((F"""transformer.decoder.layers.{i}.norm3.bias""", F"""decoder.layers.{i}.final_layer_norm.bias"""))

# convolutional projection + query embeddings + layernorm of encoder + layernorm of decoder + class and bounding box heads
rename_keys.extend(
    [
        ('''input_proj.weight''', '''input_projection.weight'''),
        ('''input_proj.bias''', '''input_projection.bias'''),
        ('''query_embed.weight''', '''query_position_embeddings.weight'''),
        ('''transformer.encoder.norm.weight''', '''encoder.layernorm.weight'''),
        ('''transformer.encoder.norm.bias''', '''encoder.layernorm.bias'''),
        ('''transformer.decoder.norm.weight''', '''decoder.layernorm.weight'''),
        ('''transformer.decoder.norm.bias''', '''decoder.layernorm.bias'''),
        ('''class_embed.weight''', '''class_labels_classifier.weight'''),
        ('''class_embed.bias''', '''class_labels_classifier.bias'''),
        ('''bbox_embed.layers.0.weight''', '''bbox_predictor.layers.0.weight'''),
        ('''bbox_embed.layers.0.bias''', '''bbox_predictor.layers.0.bias'''),
        ('''bbox_embed.layers.1.weight''', '''bbox_predictor.layers.1.weight'''),
        ('''bbox_embed.layers.1.bias''', '''bbox_predictor.layers.1.bias'''),
        ('''bbox_embed.layers.2.weight''', '''bbox_predictor.layers.2.weight'''),
        ('''bbox_embed.layers.2.bias''', '''bbox_predictor.layers.2.bias'''),
    ]
)


def     a   (    __a				,      __a				,      __a     )						->			int:



					'''simple docstring'''






					UpperCamelCase__     :Any							      =				state_dict.pop(__a     )
					UpperCamelCase__     :int							      =				val


def     a   (    __a     )						->			int:



					'''simple docstring'''






					UpperCamelCase__     :Optional[Any]							      =				OrderedDict()
					for key, value in state_dict.items():
										if "backbone.0.body" in key:
															UpperCamelCase__     :int							      =				key.replace('''backbone.0.body'''				,      '''backbone.conv_encoder.model'''     )
															UpperCamelCase__     :List[str]							      =				value
										else:
															UpperCamelCase__     :Optional[Any]							      =				value

					return new_state_dict


def     a   (    __a     )						->			str:



					'''simple docstring'''






					UpperCamelCase__     :Optional[int]							      =				''''''

					# first: transformer encoder
					for i in range(6     ):
										# read in weights + bias of input projection layer (in PyTorch's MultiHeadAttention, this is a single matrix + bias)
										UpperCamelCase__     :Union[str, Any]							      =				state_dict.pop(f'''{prefix}transformer.encoder.layers.{i}.self_attn.in_proj_weight'''     )
										UpperCamelCase__     :List[Any]							      =				state_dict.pop(f'''{prefix}transformer.encoder.layers.{i}.self_attn.in_proj_bias'''     )
										# next, add query, keys and values (in that order) to the state dict
										UpperCamelCase__     :Union[str, Any]							      =				in_proj_weight[:256, :]
										UpperCamelCase__     :Union[str, Any]							      =				in_proj_bias[:256]
										UpperCamelCase__     :Union[str, Any]							      =				in_proj_weight[256:512, :]
										UpperCamelCase__     :Tuple							      =				in_proj_bias[256:512]
										UpperCamelCase__     :List[Any]							      =				in_proj_weight[-256:, :]
										UpperCamelCase__     :Union[str, Any]							      =				in_proj_bias[-256:]
					# next: transformer decoder (which is a bit more complex because it also includes cross-attention)
					for i in range(6     ):
										# read in weights + bias of input projection layer of self-attention
										UpperCamelCase__     :str							      =				state_dict.pop(f'''{prefix}transformer.decoder.layers.{i}.self_attn.in_proj_weight'''     )
										UpperCamelCase__     :Tuple							      =				state_dict.pop(f'''{prefix}transformer.decoder.layers.{i}.self_attn.in_proj_bias'''     )
										# next, add query, keys and values (in that order) to the state dict
										UpperCamelCase__     :int							      =				in_proj_weight[:256, :]
										UpperCamelCase__     :List[str]							      =				in_proj_bias[:256]
										UpperCamelCase__     :str							      =				in_proj_weight[256:512, :]
										UpperCamelCase__     :Dict							      =				in_proj_bias[256:512]
										UpperCamelCase__     :int							      =				in_proj_weight[-256:, :]
										UpperCamelCase__     :Optional[Any]							      =				in_proj_bias[-256:]
										# read in weights + bias of input projection layer of cross-attention
										UpperCamelCase__     :List[str]							      =				state_dict.pop(
										    f'''{prefix}transformer.decoder.layers.{i}.multihead_attn.in_proj_weight'''     )
										UpperCamelCase__     :str							      =				state_dict.pop(f'''{prefix}transformer.decoder.layers.{i}.multihead_attn.in_proj_bias'''     )
										# next, add query, keys and values (in that order) of cross-attention to the state dict
										UpperCamelCase__     :Tuple							      =				in_proj_weight_cross_attn[:256, :]
										UpperCamelCase__     :Optional[Any]							      =				in_proj_bias_cross_attn[:256]
										UpperCamelCase__     :Dict							      =				in_proj_weight_cross_attn[256:512, :]
										UpperCamelCase__     :Optional[int]							      =				in_proj_bias_cross_attn[256:512]
										UpperCamelCase__     :List[str]							      =				in_proj_weight_cross_attn[-256:, :]
										UpperCamelCase__     :Dict							      =				in_proj_bias_cross_attn[-256:]


def     a   (    __a				,      __a     )						->			int:



					'''simple docstring'''






					UpperCamelCase__      ,       UpperCamelCase__     :Optional[Any]							      =				image.size
					UpperCamelCase__     :List[Any]							      =				max(__a				,      __a     )
					UpperCamelCase__     :Union[str, Any]							      =				800 if '''detection''' in checkpoint_url else 1000
					UpperCamelCase__     :List[str]							      =				target_max_size / current_max_size
					UpperCamelCase__     :Optional[int]							      =				image.resize((int(round(scale * width     )     ), int(round(scale * height     )     ))     )

					return resized_image


def     a   (    __a     )						->			str:



					'''simple docstring'''






					UpperCamelCase__     :Any							      =				F.to_tensor(__a     )
					UpperCamelCase__     :Dict							      =				F.normalize(__a				,      mean=[0.4_8_5, 0.4_5_6, 0.4_0_6]				,      std=[0.2_2_9, 0.2_2_4, 0.2_2_5]     )
					return image


@torch.no_grad()
def     a   (    __a				,      __a				,      __a     )						->			Optional[int]:



					'''simple docstring'''






					logger.info('''Converting model...'''     )

					# load original state dict
					UpperCamelCase__     :int							      =				torch.hub.load_state_dict_from_url(__a				,      map_location='''cpu'''     )
					# rename keys
					for src, dest in rename_keys:
										rename_key(__a				,      __a				,      __a     )
					UpperCamelCase__     :List[Any]							      =				rename_backbone_keys(__a     )
					# query, key and value matrices need special treatment
					read_in_q_k_v(__a     )
					# important: we need to prepend a prefix to each of the base model keys as the head models use different attributes for them
					UpperCamelCase__     :Optional[int]							      =				'''model.'''
					for key in state_dict.copy().keys():
										if not key.startswith('''class_labels_classifier'''     ) and not key.startswith('''bbox_predictor'''     ):
															UpperCamelCase__     :Optional[Any]							      =				state_dict.pop(__a     )
															UpperCamelCase__     :Any							      =				val
    # create HuggingFace model and load state dict
					UpperCamelCase__     :Any							      =				TableTransformerConfig(
					    backbone='''resnet18'''				,      mask_loss_coefficient=1				,      dice_loss_coefficient=1				,      ce_loss_coefficient=1				,      bbox_loss_coefficient=5				,      giou_loss_coefficient=2				,      eos_coefficient=0.4				,      class_cost=1				,      bbox_cost=5				,      giou_cost=2				,      )

					if "detection" in checkpoint_url:
										UpperCamelCase__     :List[Any]							      =				15
										UpperCamelCase__     :List[str]							      =				2
										UpperCamelCase__     :Tuple							      =				{0: '''table''', 1: '''table rotated'''}
										UpperCamelCase__     :str							      =				idalabel
										UpperCamelCase__     :Union[str, Any]							      =				{v: k for k, v in idalabel.items()}
					else:
										UpperCamelCase__     :Any							      =				125
										UpperCamelCase__     :List[str]							      =				6
										UpperCamelCase__     :List[str]							      =				{
										    0: '''table''',
										    1: '''table column''',
										    2: '''table row''',
										    3: '''table column header''',
										    4: '''table projected row header''',
										    5: '''table spanning cell''',
										}
										UpperCamelCase__     :Any							      =				idalabel
										UpperCamelCase__     :str							      =				{v: k for k, v in idalabel.items()}

					UpperCamelCase__     :Union[str, Any]							      =				DetrImageProcessor(
					    format='''coco_detection'''				,      max_size=800 if '''detection''' in checkpoint_url else 1000     )
					UpperCamelCase__     :int							      =				TableTransformerForObjectDetection(__a     )
					model.load_state_dict(__a     )
					model.eval()

					# verify our conversion
					UpperCamelCase__     :List[Any]							      =				'''example_pdf.png''' if '''detection''' in checkpoint_url else '''example_table.png'''
					UpperCamelCase__     :str							      =				hf_hub_download(repo_id='''nielsr/example-pdf'''				,      repo_type='''dataset'''				,      filename=__a     )
					UpperCamelCase__     :Tuple							      =				Image.open(__a     ).convert('''RGB'''     )
					UpperCamelCase__     :Any							      =				normalize(resize(__a				,      __a     )     ).unsqueeze(0     )

					UpperCamelCase__     :List[Any]							      =				model(__a     )

					if "detection" in checkpoint_url:
										UpperCamelCase__     :str							      =				(1, 15, 3)
										UpperCamelCase__     :Optional[int]							      =				torch.tensor(
										    [[-6.7_8_9_7, -1_6.9_9_8_5, 6.7_9_3_7], [-8.0_1_8_6, -2_2.2_1_9_2, 6.9_6_7_7], [-7.3_1_1_7, -2_1.0_7_0_8, 7.4_0_5_5]]     )
										UpperCamelCase__     :Union[str, Any]							      =				torch.tensor([[0.4_8_6_7, 0.1_7_6_7, 0.6_7_3_2], [0.6_7_1_8, 0.4_4_7_9, 0.3_8_3_0], [0.4_7_1_6, 0.1_7_6_0, 0.6_3_6_4]]     )

					else:
										UpperCamelCase__     :int							      =				(1, 125, 7)
										UpperCamelCase__     :Optional[Any]							      =				torch.tensor(
										    [[-1_8.1_4_3_0, -8.3_2_1_4, 4.8_2_7_4], [-1_8.4_6_8_5, -7.1_3_6_1, -4.2_6_6_7], [-2_6.3_6_9_3, -9.3_4_2_9, -4.9_9_6_2]]     )
										UpperCamelCase__     :List[Any]							      =				torch.tensor([[0.4_9_8_3, 0.5_5_9_5, 0.9_4_4_0], [0.4_9_1_6, 0.6_3_1_5, 0.5_9_5_4], [0.6_1_0_8, 0.8_6_3_7, 0.1_1_3_5]]     )

					assert outputs.logits.shape == expected_shape
					assert torch.allclose(outputs.logits[0, :3, :3]				,      __a				,      atol=1e-4     )
					assert torch.allclose(outputs.pred_boxes[0, :3, :3]				,      __a				,      atol=1e-4     )
					print('''Looks ok!'''     )

					if pytorch_dump_folder_path is not None:
										# Save model and image processor
										logger.info(f'''Saving PyTorch model and image processor to {pytorch_dump_folder_path}...'''     )
										Path(__a     ).mkdir(exist_ok=__a     )
										model.save_pretrained(__a     )
										image_processor.save_pretrained(__a     )

					if push_to_hub:
										# Push model to HF hub
										logger.info('''Pushing model to the hub...'''     )
										UpperCamelCase__     :Dict							      =				(
										    '''microsoft/table-transformer-detection'''
										    if '''detection''' in checkpoint_url
										    else '''microsoft/table-transformer-structure-recognition'''
										)
										model.push_to_hub(__a     )
										image_processor.push_to_hub(__a     )


if __name__ == "__main__":
		__snake_case							   =  argparse.ArgumentParser()

		parser.add_argument(
		    '''--checkpoint_url''',
		    default='''https://pubtables1m.blob.core.windows.net/model/pubtables1m_detection_detr_r18.pth''',
		    type=str,
		    choices=[
		        '''https://pubtables1m.blob.core.windows.net/model/pubtables1m_detection_detr_r18.pth''',
		        '''https://pubtables1m.blob.core.windows.net/model/pubtables1m_structure_detr_r18.pth''',
		    ],
		    help='''URL of the Table Transformer checkpoint you\'d like to convert.''',
		)
		parser.add_argument(
		    '''--pytorch_dump_folder_path''', default=None, type=str, help='''Path to the folder to output PyTorch model.'''
		)
		parser.add_argument(
		    '''--push_to_hub''', action='''store_true''', help='''Whether or not to push the converted model to the 🤗 hub.'''
		)
		__snake_case							   =  parser.parse_args()
		convert_table_transformer_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path, args.push_to_hub)



'''simple docstring'''
import sys

__snake_case							   =  (
    '''73167176531330624919225119674426574742355349194934'''
    '''96983520312774506326239578318016984801869478851843'''
    '''85861560789112949495459501737958331952853208805511'''
    '''12540698747158523863050715693290963295227443043557'''
    '''66896648950445244523161731856403098711121722383113'''
    '''62229893423380308135336276614282806444486645238749'''
    '''30358907296290491560440772390713810515859307960866'''
    '''70172427121883998797908792274921901699720888093776'''
    '''65727333001053367881220235421809751254540594752243'''
    '''52584907711670556013604839586446706324415722155397'''
    '''53697817977846174064955149290862569321978468622482'''
    '''83972241375657056057490261407972968652414535100474'''
    '''82166370484403199890008895243450658541227588666881'''
    '''16427171479924442928230863465674813919123162824586'''
    '''17866458359124566529476545682848912883142607690042'''
    '''24219022671055626321111109370544217506941658960408'''
    '''07198403850962455444362981230987879927244284909188'''
    '''84580156166097919133875499200524063689912560717606'''
    '''05886116467109405077541002256983155200055935729725'''
    '''71636269561882670428252483600823257530420752963450'''
)


def     a   (    __a     )						->			int:



					'''simple docstring'''






					UpperCamelCase__     :Tuple							      =				1
					for digit in s:
										product *= int(__a     )
					return product


def     a   (    __a = N     )						->			int:



					'''simple docstring'''






					UpperCamelCase__     :Tuple							      =				-sys.maxsize - 1
					UpperCamelCase__     :Dict							      =				n[:13]
					UpperCamelCase__     :Dict							      =				13
					while cur_index < len(__a     ) - 13:
										if int(n[cur_index]     ) >= int(substr[0]     ):
															UpperCamelCase__     :Dict							      =				substr[1:] + n[cur_index]
															cur_index += 1
										else:
															UpperCamelCase__     :List[str]							      =				max(__a				,      str_eval(__a     )     )
															UpperCamelCase__     :Union[str, Any]							      =				n[cur_index : cur_index + 13]
															cur_index += 13
					return largest_product


if __name__ == "__main__":
		print(F"""{solution() = }""")