


'''simple docstring'''


import argparse
import json
import os
from collections import OrderedDict

import numpy as np
import tensorflow as tf
import torch






def        __lowerCAmelCase       (__lowerCAmelCase      ):
		_UpperCAmelCase						:				str	    =					os.path.join(args.tf_model_dir					,       "parameters.json"      )
		_UpperCAmelCase						:				str	    =					json.loads(open(__lowerCAmelCase      ).read()      )
		if not params:
				raise ValueError(
				    F"""It seems that the json file at {parameter_file} is empty. Make sure you have a correct json file."""      )
		if not args.output.endswith(".pt"      ):
				_UpperCAmelCase						:				List[str]	    =					args.output + ".pt"
		_UpperCAmelCase						:				Optional[int]	    =					OrderedDict()
		with tf.device("/CPU:0"      ):
				_UpperCAmelCase						:				str	    =					tf.train.load_checkpoint(args.tf_model_dir      )
				_UpperCAmelCase						:				str	    =					reader.get_variable_to_shape_map()
				for key_name in shapes.keys():
						_UpperCAmelCase						:				Optional[Any]	    =					reader.get_tensor(__lowerCAmelCase      ).astype(np.floataa      )
						if key_name.endswith("/adam_m"      ) or key_name.endswith("/adam_v"      ):
								continue
						if key_name.startswith("pasts/"      ):
								if key_name.startswith("pasts/mlp"      ):
										_UpperCAmelCase						:				Optional[Any]	    =					int(key_name[9]      )
								elif key_name.startswith("pasts/out"      ):
										_UpperCAmelCase						:				str	    =					8
								_UpperCAmelCase						:				int	    =					"model.sqout.%d.weight" % (player * 2)  # enter to nn.Sequencial with Tanh, so 2 at a time
								_UpperCAmelCase						:				str	    =					vnp.transpose([1, 0]      ).copy()  # Mesh-Tensorflow is a diagonal matrix
								_UpperCAmelCase						:				Tuple	    =					torch.tensor(__lowerCAmelCase      )
						elif key_name.startswith("model/moe"      ):
								_UpperCAmelCase						:				str	    =					int(key_name[9:].split("/"      )[0]      )
								if key_name.endswith("/switch_gating/kernel"      ):
										_UpperCAmelCase						:				Tuple	    =					"model.blocks.%d.feed_forward.mlp.router.classifier.weight" % player
										_UpperCAmelCase						:				List[str]	    =					vnp.transpose([1, 0]      ).copy()  # Mesh-Tensorflow is a diagonal matrix
										_UpperCAmelCase						:				Optional[int]	    =					torch.tensor(__lowerCAmelCase      )
								elif key_name.endswith("/softmlp/kernel"      ):
										_UpperCAmelCase						:				Tuple	    =					"model.blocks.%d.feed_forward.soft_bypass_mlp.weight" % player
										_UpperCAmelCase						:				str	    =					vnp.transpose([1, 0]      ).copy()  # Mesh-Tensorflow is a diagonal matrix
										_UpperCAmelCase						:				Any	    =					torch.tensor(__lowerCAmelCase      )
								elif key_name.endswith("/wo/kernel"      ) or key_name.endswith("/wi/kernel"      ):
										_UpperCAmelCase						:				Tuple	    =					key_name[-9:-7]
										for i in range(16      ):
												_UpperCAmelCase						:				Optional[int]	    =					"model.blocks.%d.feed_forward.mlp.experts.expert_%d.%s.weight" % (player, i, nlayer)
												_UpperCAmelCase						:				Tuple	    =					(
												    vnp[i].transpose([1, 0]      ).copy()
												)  # In Mesh-Tensorflow, it is one array, so it is divided
												_UpperCAmelCase						:				Tuple	    =					torch.tensor(__lowerCAmelCase      )
						elif key_name.startswith("model/mlp"      ):
								_UpperCAmelCase						:				str	    =					int(key_name[9:].split("/"      )[0]      )
								if key_name.endswith("/p1/kernel"      ):
										_UpperCAmelCase						:				Tuple	    =					"model.blocks.%d.feed_forward.mlp.wi.weight" % player
										_UpperCAmelCase						:				Dict	    =					vnp.transpose([1, 0]      ).copy()  # Mesh-Tensorflow is a diagonal matrix
										_UpperCAmelCase						:				Union[str, Any]	    =					torch.tensor(__lowerCAmelCase      )
								elif key_name.endswith("/p1/bias"      ):
										_UpperCAmelCase						:				Optional[Any]	    =					"model.blocks.%d.feed_forward.mlp.wi.bias" % player
										_UpperCAmelCase						:				List[Any]	    =					vnp.copy()  # same because it is one dimensional
										_UpperCAmelCase						:				Union[str, Any]	    =					torch.tensor(__lowerCAmelCase      )
								elif key_name.endswith("/p2/kernel"      ):
										_UpperCAmelCase						:				Dict	    =					"model.blocks.%d.feed_forward.mlp.wo.weight" % player
										_UpperCAmelCase						:				Optional[int]	    =					vnp.transpose([1, 0]      ).copy()  # Mesh-Tensorflow is a diagonal matrix
										_UpperCAmelCase						:				Any	    =					torch.tensor(__lowerCAmelCase      )
								elif key_name.endswith("/p2/bias"      ):
										_UpperCAmelCase						:				Tuple	    =					"model.blocks.%d.feed_forward.mlp.wo.bias" % player
										_UpperCAmelCase						:				Any	    =					vnp.copy()  # same because it is one dimensional
										_UpperCAmelCase						:				List[Any]	    =					torch.tensor(__lowerCAmelCase      )
						elif key_name.startswith("model/ln"      ):
								_UpperCAmelCase						:				Any	    =					int(key_name[8:].split("/"      )[0]      )
								if key_name.endswith("/b"      ):
										_UpperCAmelCase						:				List[Any]	    =					"model.blocks.%d.feed_forward.norm.bias" % player
										_UpperCAmelCase						:				Optional[int]	    =					vnp.copy()  # same because it is one dimensional
										_UpperCAmelCase						:				Tuple	    =					torch.tensor(__lowerCAmelCase      )
								elif key_name.endswith("/g"      ):
										_UpperCAmelCase						:				List[Any]	    =					"model.blocks.%d.feed_forward.norm.weight" % player
										_UpperCAmelCase						:				Tuple	    =					vnp.copy()  # same because it is one dimensional
										_UpperCAmelCase						:				str	    =					torch.tensor(__lowerCAmelCase      )
						elif key_name.startswith("model/att"      ):
								_UpperCAmelCase						:				int	    =					int(key_name[9:].split("/"      )[0]      )
								if key_name.endswith("/qkv/kernel"      ):
										_UpperCAmelCase						:				Optional[int]	    =					vnp.copy()  # Compute same dimension as Mesh-tensorflow using einsum
										_UpperCAmelCase						:				Optional[int]	    =					state[:, 0, :, :]
										_UpperCAmelCase						:				int	    =					state[:, 1, :, :]
										_UpperCAmelCase						:				List[Any]	    =					state[:, 2, :, :]
										_UpperCAmelCase						:				Optional[int]	    =					(
										    state_q.reshape([state_q.shape[0], state_q.shape[1] * state_q.shape[2]]      )
										    .transpose([1, 0]      )
										    .copy()
										)  # Mesh-Tensorflow is a diagonal matrix
										_UpperCAmelCase						:				int	    =					(
										    state_k.reshape([state_k.shape[0], state_k.shape[1] * state_k.shape[2]]      )
										    .transpose([1, 0]      )
										    .copy()
										)  # Mesh-Tensorflow is a diagonal matrix
										_UpperCAmelCase						:				Any	    =					(
										    state_v.reshape([state_v.shape[0], state_v.shape[1] * state_v.shape[2]]      )
										    .transpose([1, 0]      )
										    .copy()
										)  # Mesh-Tensorflow is a diagonal matrix
										_UpperCAmelCase						:				Union[str, Any]	    =					"model.blocks.%d.self_attn.self_attn.q_proj.weight" % player
										_UpperCAmelCase						:				Optional[Any]	    =					torch.tensor(__lowerCAmelCase      )
										_UpperCAmelCase						:				Any	    =					"model.blocks.%d.self_attn.self_attn.k_proj.weight" % player
										_UpperCAmelCase						:				Union[str, Any]	    =					torch.tensor(__lowerCAmelCase      )
										_UpperCAmelCase						:				List[Any]	    =					"model.blocks.%d.self_attn.self_attn.v_proj.weight" % player
										_UpperCAmelCase						:				Tuple	    =					torch.tensor(__lowerCAmelCase      )
								elif key_name.endswith("/o/kernel"      ):
										_UpperCAmelCase						:				str	    =					"model.blocks.%d.self_attn.self_attn.out_proj.weight" % player
										_UpperCAmelCase						:				Optional[int]	    =					(
										    vnp.reshape([vnp.shape[0] * vnp.shape[1], vnp.shape[2]]      ).transpose([1, 0]      ).copy()
										)  # Mesh-Tensorflow is a diagonal matrix
										_UpperCAmelCase						:				str	    =					torch.tensor(__lowerCAmelCase      )
						elif key_name.startswith("model/an"      ):
								_UpperCAmelCase						:				List[str]	    =					int(key_name[8:].split("/"      )[0]      )
								if key_name.endswith("/b"      ):
										_UpperCAmelCase						:				Optional[int]	    =					"model.blocks.%d.self_attn.norm.bias" % player
										_UpperCAmelCase						:				Any	    =					vnp.copy()  # same because it is one dimensional
										_UpperCAmelCase						:				int	    =					torch.tensor(__lowerCAmelCase      )
								elif key_name.endswith("/g"      ):
										_UpperCAmelCase						:				str	    =					"model.blocks.%d.self_attn.norm.weight" % player
										_UpperCAmelCase						:				str	    =					vnp.copy()  # same because it is one dimensional
										_UpperCAmelCase						:				Dict	    =					torch.tensor(__lowerCAmelCase      )
						elif (
						    key_name.startswith("model/wte"      )
						    or key_name.startswith("model/wpe"      )
						    or key_name.startswith("model/ete"      )
						):
								_UpperCAmelCase						:				Union[str, Any]	    =					{"wte": "embed_tokens", "wpe": "position_embeddings", "ete": "extra_position_embeddings"}[
								    key_name[-3:]
								]
								_UpperCAmelCase						:				Optional[Any]	    =					"model.%s.weight" % nlayer
								_UpperCAmelCase						:				Dict	    =					vnp.copy()  # same in embedded
								_UpperCAmelCase						:				str	    =					torch.tensor(__lowerCAmelCase      )
								if key_name.startswith("model/wte"      ):
										_UpperCAmelCase						:				List[str]	    =					"lm_head.weight"
										_UpperCAmelCase						:				Dict	    =					vnp.copy()  # same in embedded
										_UpperCAmelCase						:				Optional[Any]	    =					torch.tensor(__lowerCAmelCase      )
						elif key_name.startswith("model/wob"      ):
								_UpperCAmelCase						:				int	    =					"final_logits_bias"
								_UpperCAmelCase						:				Optional[Any]	    =					vnp.copy()  # same in embedded
								_UpperCAmelCase						:				Dict	    =					state.reshape((1, -1)      )
								_UpperCAmelCase						:				Dict	    =					torch.tensor(__lowerCAmelCase      )
						elif key_name == "model/dense/kernel":
								_UpperCAmelCase						:				str	    =					"model.last_project.weight"
								_UpperCAmelCase						:				Optional[Any]	    =					vnp.transpose([1, 0]      ).copy()  # Mesh-Tensorflow is a diagonal matrix
								_UpperCAmelCase						:				Optional[Any]	    =					torch.tensor(__lowerCAmelCase      )
						elif key_name == "model/dense_1/bias":
								_UpperCAmelCase						:				Union[str, Any]	    =					"model.last_project.bias"
								_UpperCAmelCase						:				Optional[int]	    =					vnp.copy()  # same because it is one dimensional
								_UpperCAmelCase						:				Union[str, Any]	    =					torch.tensor(__lowerCAmelCase      )
		torch.save(__lowerCAmelCase					,       args.output      )


if __name__ == "__main__":
						lowerCamelCase__					=   argparse.ArgumentParser(
						    description='model converter.', formatter_class=argparse.ArgumentDefaultsHelpFormatter
						)
						parser.add_argument('--tf_model_dir', metavar='PATH', type=str, required=True, help='import model')
						parser.add_argument('--output', metavar='PATH', type=str, required=True, help='output model')
						lowerCamelCase__					=   parser.parse_args()
						convert_tf_gptsan_to_pt(args)







'''simple docstring'''


import json
from typing import List, Optional, Tuple

from tokenizers import normalizers

from ...tokenization_utils_fast import PreTrainedTokenizerFast
from ...utils import logging
from .tokenization_bert import BertTokenizer


lowerCamelCase__					=   logging.get_logger(__name__)

lowerCamelCase__					=   {'vocab_file': 'vocab.txt', 'tokenizer_file': 'tokenizer.json'}

lowerCamelCase__					=   {
    'vocab_file': {
        'bert-base-uncased': 'https://huggingface.co/bert-base-uncased/resolve/main/vocab.txt',
        'bert-large-uncased': 'https://huggingface.co/bert-large-uncased/resolve/main/vocab.txt',
        'bert-base-cased': 'https://huggingface.co/bert-base-cased/resolve/main/vocab.txt',
        'bert-large-cased': 'https://huggingface.co/bert-large-cased/resolve/main/vocab.txt',
        'bert-base-multilingual-uncased': (
            'https://huggingface.co/bert-base-multilingual-uncased/resolve/main/vocab.txt'
        ),
        'bert-base-multilingual-cased': 'https://huggingface.co/bert-base-multilingual-cased/resolve/main/vocab.txt',
        'bert-base-chinese': 'https://huggingface.co/bert-base-chinese/resolve/main/vocab.txt',
        'bert-base-german-cased': 'https://huggingface.co/bert-base-german-cased/resolve/main/vocab.txt',
        'bert-large-uncased-whole-word-masking': (
            'https://huggingface.co/bert-large-uncased-whole-word-masking/resolve/main/vocab.txt'
        ),
        'bert-large-cased-whole-word-masking': (
            'https://huggingface.co/bert-large-cased-whole-word-masking/resolve/main/vocab.txt'
        ),
        'bert-large-uncased-whole-word-masking-finetuned-squad': (
            'https://huggingface.co/bert-large-uncased-whole-word-masking-finetuned-squad/resolve/main/vocab.txt'
        ),
        'bert-large-cased-whole-word-masking-finetuned-squad': (
            'https://huggingface.co/bert-large-cased-whole-word-masking-finetuned-squad/resolve/main/vocab.txt'
        ),
        'bert-base-cased-finetuned-mrpc': (
            'https://huggingface.co/bert-base-cased-finetuned-mrpc/resolve/main/vocab.txt'
        ),
        'bert-base-german-dbmdz-cased': 'https://huggingface.co/bert-base-german-dbmdz-cased/resolve/main/vocab.txt',
        'bert-base-german-dbmdz-uncased': (
            'https://huggingface.co/bert-base-german-dbmdz-uncased/resolve/main/vocab.txt'
        ),
        'TurkuNLP/bert-base-finnish-cased-v1': (
            'https://huggingface.co/TurkuNLP/bert-base-finnish-cased-v1/resolve/main/vocab.txt'
        ),
        'TurkuNLP/bert-base-finnish-uncased-v1': (
            'https://huggingface.co/TurkuNLP/bert-base-finnish-uncased-v1/resolve/main/vocab.txt'
        ),
        'wietsedv/bert-base-dutch-cased': (
            'https://huggingface.co/wietsedv/bert-base-dutch-cased/resolve/main/vocab.txt'
        ),
    },
    'tokenizer_file': {
        'bert-base-uncased': 'https://huggingface.co/bert-base-uncased/resolve/main/tokenizer.json',
        'bert-large-uncased': 'https://huggingface.co/bert-large-uncased/resolve/main/tokenizer.json',
        'bert-base-cased': 'https://huggingface.co/bert-base-cased/resolve/main/tokenizer.json',
        'bert-large-cased': 'https://huggingface.co/bert-large-cased/resolve/main/tokenizer.json',
        'bert-base-multilingual-uncased': (
            'https://huggingface.co/bert-base-multilingual-uncased/resolve/main/tokenizer.json'
        ),
        'bert-base-multilingual-cased': (
            'https://huggingface.co/bert-base-multilingual-cased/resolve/main/tokenizer.json'
        ),
        'bert-base-chinese': 'https://huggingface.co/bert-base-chinese/resolve/main/tokenizer.json',
        'bert-base-german-cased': 'https://huggingface.co/bert-base-german-cased/resolve/main/tokenizer.json',
        'bert-large-uncased-whole-word-masking': (
            'https://huggingface.co/bert-large-uncased-whole-word-masking/resolve/main/tokenizer.json'
        ),
        'bert-large-cased-whole-word-masking': (
            'https://huggingface.co/bert-large-cased-whole-word-masking/resolve/main/tokenizer.json'
        ),
        'bert-large-uncased-whole-word-masking-finetuned-squad': (
            'https://huggingface.co/bert-large-uncased-whole-word-masking-finetuned-squad/resolve/main/tokenizer.json'
        ),
        'bert-large-cased-whole-word-masking-finetuned-squad': (
            'https://huggingface.co/bert-large-cased-whole-word-masking-finetuned-squad/resolve/main/tokenizer.json'
        ),
        'bert-base-cased-finetuned-mrpc': (
            'https://huggingface.co/bert-base-cased-finetuned-mrpc/resolve/main/tokenizer.json'
        ),
        'bert-base-german-dbmdz-cased': (
            'https://huggingface.co/bert-base-german-dbmdz-cased/resolve/main/tokenizer.json'
        ),
        'bert-base-german-dbmdz-uncased': (
            'https://huggingface.co/bert-base-german-dbmdz-uncased/resolve/main/tokenizer.json'
        ),
        'TurkuNLP/bert-base-finnish-cased-v1': (
            'https://huggingface.co/TurkuNLP/bert-base-finnish-cased-v1/resolve/main/tokenizer.json'
        ),
        'TurkuNLP/bert-base-finnish-uncased-v1': (
            'https://huggingface.co/TurkuNLP/bert-base-finnish-uncased-v1/resolve/main/tokenizer.json'
        ),
        'wietsedv/bert-base-dutch-cased': (
            'https://huggingface.co/wietsedv/bert-base-dutch-cased/resolve/main/tokenizer.json'
        ),
    },
}

lowerCamelCase__					=   {
    'bert-base-uncased': 512,
    'bert-large-uncased': 512,
    'bert-base-cased': 512,
    'bert-large-cased': 512,
    'bert-base-multilingual-uncased': 512,
    'bert-base-multilingual-cased': 512,
    'bert-base-chinese': 512,
    'bert-base-german-cased': 512,
    'bert-large-uncased-whole-word-masking': 512,
    'bert-large-cased-whole-word-masking': 512,
    'bert-large-uncased-whole-word-masking-finetuned-squad': 512,
    'bert-large-cased-whole-word-masking-finetuned-squad': 512,
    'bert-base-cased-finetuned-mrpc': 512,
    'bert-base-german-dbmdz-cased': 512,
    'bert-base-german-dbmdz-uncased': 512,
    'TurkuNLP/bert-base-finnish-cased-v1': 512,
    'TurkuNLP/bert-base-finnish-uncased-v1': 512,
    'wietsedv/bert-base-dutch-cased': 512,
}

lowerCamelCase__					=   {
    'bert-base-uncased': {'do_lower_case': True},
    'bert-large-uncased': {'do_lower_case': True},
    'bert-base-cased': {'do_lower_case': False},
    'bert-large-cased': {'do_lower_case': False},
    'bert-base-multilingual-uncased': {'do_lower_case': True},
    'bert-base-multilingual-cased': {'do_lower_case': False},
    'bert-base-chinese': {'do_lower_case': False},
    'bert-base-german-cased': {'do_lower_case': False},
    'bert-large-uncased-whole-word-masking': {'do_lower_case': True},
    'bert-large-cased-whole-word-masking': {'do_lower_case': False},
    'bert-large-uncased-whole-word-masking-finetuned-squad': {'do_lower_case': True},
    'bert-large-cased-whole-word-masking-finetuned-squad': {'do_lower_case': False},
    'bert-base-cased-finetuned-mrpc': {'do_lower_case': False},
    'bert-base-german-dbmdz-cased': {'do_lower_case': False},
    'bert-base-german-dbmdz-uncased': {'do_lower_case': True},
    'TurkuNLP/bert-base-finnish-cased-v1': {'do_lower_case': False},
    'TurkuNLP/bert-base-finnish-uncased-v1': {'do_lower_case': True},
    'wietsedv/bert-base-dutch-cased': {'do_lower_case': False},
}






class 		lowerCAmelCase__	(	UpperCAmelCase__		):
			lowerCAmelCase       :		Union[str, Any]				      =   VOCAB_FILES_NAMES
			lowerCAmelCase       :		Dict				      =   PRETRAINED_VOCAB_FILES_MAP
			lowerCAmelCase       :		Tuple				      =   PRETRAINED_INIT_CONFIGURATION
			lowerCAmelCase       :		Optional[int]				      =   PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
			lowerCAmelCase       :		Any				      =   BertTokenizer




			def __init__(						self     :   int		,     lowerCamelCase__     :   Optional[Any]=None		,     lowerCamelCase__     :   Optional[int]=None		,     lowerCamelCase__     :   str=True		,     lowerCamelCase__     :   Tuple="[UNK]"		,     lowerCamelCase__     :   str="[SEP]"		,     lowerCamelCase__     :   Optional[Any]="[PAD]"		,     lowerCamelCase__     :   List[str]="[CLS]"		,     lowerCamelCase__     :   Union[str, Any]="[MASK]"		,     lowerCamelCase__     :   str=True		,     lowerCamelCase__     :   Dict=None		,     **lowerCamelCase__     :   Union[str, Any]		,     )      ->Tuple:



					'''simple docstring'''







					super().__init__(
					    lowerCamelCase__		,     tokenizer_file=lowerCamelCase__		,     do_lower_case=lowerCamelCase__		,     unk_token=lowerCamelCase__		,     sep_token=lowerCamelCase__		,     pad_token=lowerCamelCase__		,     cls_token=lowerCamelCase__		,     mask_token=lowerCamelCase__		,     tokenize_chinese_chars=lowerCamelCase__		,     strip_accents=lowerCamelCase__		,     **lowerCamelCase__		,     )

					_UpperCAmelCase						:				Optional[Any]	    =					json.loads(self.backend_tokenizer.normalizer.__getstate__()       )
					if (
					    normalizer_state.get("lowercase"		,     lowerCamelCase__       ) != do_lower_case
					    or normalizer_state.get("strip_accents"		,     lowerCamelCase__       ) != strip_accents
					    or normalizer_state.get("handle_chinese_chars"		,     lowerCamelCase__       ) != tokenize_chinese_chars
					):
							_UpperCAmelCase						:				str	    =					getattr(lowerCamelCase__		,     normalizer_state.pop("type"       )       )
							_UpperCAmelCase						:				Optional[Any]	    =					do_lower_case
							_UpperCAmelCase						:				Any	    =					strip_accents
							_UpperCAmelCase						:				List[Any]	    =					tokenize_chinese_chars
							_UpperCAmelCase						:				int	    =					normalizer_class(**lowerCamelCase__       )

					_UpperCAmelCase						:				Union[str, Any]	    =					do_lower_case




			def 							lowerCAmelCase__			(						self     :   List[str]		,     lowerCamelCase__     :   List[str]		,     lowerCamelCase__     :   str=None       )      ->List[Any]:



					'''simple docstring'''







					_UpperCAmelCase						:				List[str]	    =					[self.cls_token_id] + token_ids_a + [self.sep_token_id]

					if token_ids_a:
							output += token_ids_a + [self.sep_token_id]

					return output




			def 							lowerCAmelCase__			(						self     :   List[Any]		,     lowerCamelCase__     :   List[int]		,     lowerCamelCase__     :   Optional[List[int]] = None       )      ->List[int]:



					'''simple docstring'''







					_UpperCAmelCase						:				Tuple	    =					[self.sep_token_id]
					_UpperCAmelCase						:				int	    =					[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       ) * [0] + len(token_ids_a + sep       ) * [1]






			def 							lowerCAmelCase__			(						self     :   List[Any]		,     lowerCamelCase__     :   str		,     lowerCamelCase__     :   Optional[str] = None       )      ->Tuple[str]:



					'''simple docstring'''







					_UpperCAmelCase						:				List[str]	    =					self._tokenizer.model.save(lowerCamelCase__		,     name=lowerCamelCase__       )
					return tuple(lowerCamelCase__       )



