

import math
from typing import Optional

import numpy as np
import torch
from torch import nn

from .activations import get_activation


def    _UpperCAmelCase    (					_SCREAMING_SNAKE_CASE   :						Optional[Any]  ,				_SCREAMING_SNAKE_CASE   :						int  ,				_SCREAMING_SNAKE_CASE   :						List[str] = False  ,				_SCREAMING_SNAKE_CASE   :						Any = 1  ,				_SCREAMING_SNAKE_CASE   :						List[str] = 1  ,				_SCREAMING_SNAKE_CASE   :						List[str] = 10_000  ,				):





    """simple docstring"""


    assert len(timesteps.shape    ) == 1, "Timesteps should be a 1d-array"

    SCREAMING_SNAKE_CASE_													=  embedding_dim // 2
    SCREAMING_SNAKE_CASE_													=  -math.log(_lowerCAmelCase    ) * torch.arange(
        start=0  ,				end=_lowerCAmelCase  ,				dtype=torch.floataa  ,				device=timesteps.device    )
    SCREAMING_SNAKE_CASE_													=  exponent / (half_dim - downscale_freq_shift)

    SCREAMING_SNAKE_CASE_													=  torch.exp(_lowerCAmelCase    )
    SCREAMING_SNAKE_CASE_													=  timesteps[:, None].float() * emb[None, :]

    # scale embeddings
    SCREAMING_SNAKE_CASE_													=  scale * emb

    # concat sine and cosine embeddings
    SCREAMING_SNAKE_CASE_													=  torch.cat([torch.sin(_lowerCAmelCase    ), torch.cos(_lowerCAmelCase    )]  ,				dim=-1    )

    # flip sine and cosine embeddings
    if flip_sin_to_cos:
        SCREAMING_SNAKE_CASE_													=  torch.cat([emb[:, half_dim:], emb[:, :half_dim]]  ,				dim=-1    )

    # zero pad
    if embedding_dim % 2 == 1:
        SCREAMING_SNAKE_CASE_													=  torch.nn.functional.pad(_lowerCAmelCase  ,				(0, 1, 0, 0)    )
    return emb


def    _UpperCAmelCase    (					_SCREAMING_SNAKE_CASE   :						Tuple  ,				_SCREAMING_SNAKE_CASE   :						List[Any]  ,				_SCREAMING_SNAKE_CASE   :						Union[str, Any]=False  ,				_SCREAMING_SNAKE_CASE   :						Tuple=0    ):





    """simple docstring"""


    SCREAMING_SNAKE_CASE_													=  np.arange(_lowerCAmelCase  ,				dtype=np.floataa    )
    SCREAMING_SNAKE_CASE_													=  np.arange(_lowerCAmelCase  ,				dtype=np.floataa    )
    SCREAMING_SNAKE_CASE_													=  np.meshgrid(_lowerCAmelCase  ,				_lowerCAmelCase    )  # here w goes first
    SCREAMING_SNAKE_CASE_													=  np.stack(_lowerCAmelCase  ,				axis=0    )

    SCREAMING_SNAKE_CASE_													=  grid.reshape([2, 1, grid_size, grid_size]    )
    SCREAMING_SNAKE_CASE_													=  get_ad_sincos_pos_embed_from_grid(_lowerCAmelCase  ,				_lowerCAmelCase    )
    if cls_token and extra_tokens > 0:
        SCREAMING_SNAKE_CASE_													=  np.concatenate([np.zeros([extra_tokens, embed_dim]    ), pos_embed]  ,				axis=0    )
    return pos_embed


def    _UpperCAmelCase    (					_SCREAMING_SNAKE_CASE   :						Optional[int]  ,				_SCREAMING_SNAKE_CASE   :						str    ):





    """simple docstring"""


    if embed_dim % 2 != 0:
        raise ValueError('embed_dim must be divisible by 2'    )

    # use half of dimensions to encode grid_h
    SCREAMING_SNAKE_CASE_													=  get_ad_sincos_pos_embed_from_grid(embed_dim // 2  ,				grid[0]    )  # (H*W, D/2)
    SCREAMING_SNAKE_CASE_													=  get_ad_sincos_pos_embed_from_grid(embed_dim // 2  ,				grid[1]    )  # (H*W, D/2)

    SCREAMING_SNAKE_CASE_													=  np.concatenate([emb_h, emb_w]  ,				axis=1    )  # (H*W, D)
    return emb


def    _UpperCAmelCase    (					_SCREAMING_SNAKE_CASE   :						Union[str, Any]  ,				_SCREAMING_SNAKE_CASE   :						Any    ):





    """simple docstring"""


    if embed_dim % 2 != 0:
        raise ValueError('embed_dim must be divisible by 2'    )

    SCREAMING_SNAKE_CASE_													=  np.arange(embed_dim // 2  ,				dtype=np.floataa    )
    omega /= embed_dim / 2.0
    SCREAMING_SNAKE_CASE_													=  1.0 / 10_000**omega  # (D/2,)

    SCREAMING_SNAKE_CASE_													=  pos.reshape(-1    )  # (M,)
    SCREAMING_SNAKE_CASE_													=  np.einsum('m,d->md'  ,				_lowerCAmelCase  ,				_lowerCAmelCase    )  # (M, D/2), outer product

    SCREAMING_SNAKE_CASE_													=  np.sin(_lowerCAmelCase    )  # (M, D/2)
    SCREAMING_SNAKE_CASE_													=  np.cos(_lowerCAmelCase    )  # (M, D/2)

    SCREAMING_SNAKE_CASE_													=  np.concatenate([emb_sin, emb_cos]  ,				axis=1    )  # (M, D)
    return emb



class  __snake_case					(      nn.Module    ):

  def __init__(   self  ,						_A=224  ,						_A=224  ,						_A=16  ,						_A=3  ,						_A=768  ,						_A=False  ,						_A=True  ,						_A=True  ,						):
      super().__init__()

      SCREAMING_SNAKE_CASE_													=  (height // patch_size) * (width // patch_size)
      SCREAMING_SNAKE_CASE_													=  flatten
      SCREAMING_SNAKE_CASE_													=  layer_norm

      SCREAMING_SNAKE_CASE_													=  nn.Convad(
          snake_case__  ,						snake_case__  ,						kernel_size=(patch_size, patch_size)  ,						stride=snake_case__  ,						bias=snake_case__)
      if layer_norm:
          SCREAMING_SNAKE_CASE_													=  nn.LayerNorm(snake_case__  ,						elementwise_affine=snake_case__  ,						eps=1E-6)
      else:
          SCREAMING_SNAKE_CASE_													=  None

      SCREAMING_SNAKE_CASE_													=  get_ad_sincos_pos_embed(snake_case__  ,						int(num_patches**0.5))
      self.register_buffer('pos_embed'  ,						torch.from_numpy(snake_case__).float().unsqueeze(0)  ,						persistent=snake_case__)


  def   lowerCAmelCase__       (   self  ,						_A):
      SCREAMING_SNAKE_CASE_													=  self.proj(snake_case__)
      if self.flatten:
          SCREAMING_SNAKE_CASE_													=  latent.flatten(2).transpose(1  ,						2)  # BCHW -> BNC
      if self.layer_norm:
          SCREAMING_SNAKE_CASE_													=  self.norm(snake_case__)
      return latent + self.pos_embed






class  __snake_case					(      nn.Module    ):

  def __init__(   self  ,						_A  ,						_A  ,						_A = "silu"  ,						_A = None  ,						_A = None  ,						_A=None  ,						):
      super().__init__()

      SCREAMING_SNAKE_CASE_													=  nn.Linear(snake_case__  ,						snake_case__)

      if cond_proj_dim is not None:
          SCREAMING_SNAKE_CASE_													=  nn.Linear(snake_case__  ,						snake_case__  ,						bias=snake_case__)
      else:
          SCREAMING_SNAKE_CASE_													=  None

      SCREAMING_SNAKE_CASE_													=  get_activation(snake_case__)

      if out_dim is not None:
          SCREAMING_SNAKE_CASE_													=  out_dim
      else:
          SCREAMING_SNAKE_CASE_													=  time_embed_dim
      SCREAMING_SNAKE_CASE_													=  nn.Linear(snake_case__  ,						snake_case__)

      if post_act_fn is None:
          SCREAMING_SNAKE_CASE_													=  None
      else:
          SCREAMING_SNAKE_CASE_													=  get_activation(snake_case__)


  def   lowerCAmelCase__       (   self  ,						_A  ,						_A=None):


      if condition is not None:
          SCREAMING_SNAKE_CASE_													=  sample + self.cond_proj(snake_case__)
      SCREAMING_SNAKE_CASE_													=  self.linear_a(snake_case__)

      if self.act is not None:
          SCREAMING_SNAKE_CASE_													=  self.act(snake_case__)

      SCREAMING_SNAKE_CASE_													=  self.linear_a(snake_case__)

      if self.post_act is not None:
          SCREAMING_SNAKE_CASE_													=  self.post_act(snake_case__)
      return sample






class  __snake_case					(      nn.Module    ):

  def __init__(   self  ,						_A  ,						_A  ,						_A):
      super().__init__()
      SCREAMING_SNAKE_CASE_													=  num_channels
      SCREAMING_SNAKE_CASE_													=  flip_sin_to_cos
      SCREAMING_SNAKE_CASE_													=  downscale_freq_shift


  def   lowerCAmelCase__       (   self  ,						_A):
      SCREAMING_SNAKE_CASE_													=  get_timestep_embedding(
          snake_case__  ,						self.num_channels  ,						flip_sin_to_cos=self.flip_sin_to_cos  ,						downscale_freq_shift=self.downscale_freq_shift  ,						)
      return t_emb






class  __snake_case					(      nn.Module    ):

  def __init__(   self  ,						_A = 256  ,						_A = 1.0  ,						_A=True  ,						_A=True  ,						_A=False):
      super().__init__()
      SCREAMING_SNAKE_CASE_													=  nn.Parameter(torch.randn(snake_case__) * scale  ,						requires_grad=snake_case__)
      SCREAMING_SNAKE_CASE_													=  log
      SCREAMING_SNAKE_CASE_													=  flip_sin_to_cos

      if set_W_to_weight:
          # to delete later
          SCREAMING_SNAKE_CASE_													=  nn.Parameter(torch.randn(snake_case__) * scale  ,						requires_grad=snake_case__)

          SCREAMING_SNAKE_CASE_													=  self.W


  def   lowerCAmelCase__       (   self  ,						_A):


      if self.log:
          SCREAMING_SNAKE_CASE_													=  torch.log(snake_case__)

      SCREAMING_SNAKE_CASE_													=  x[:, None] * self.weight[None, :] * 2 * np.pi

      if self.flip_sin_to_cos:
          SCREAMING_SNAKE_CASE_													=  torch.cat([torch.cos(snake_case__), torch.sin(snake_case__)]  ,						dim=-1)
      else:
          SCREAMING_SNAKE_CASE_													=  torch.cat([torch.sin(snake_case__), torch.cos(snake_case__)]  ,						dim=-1)
      return out






class  __snake_case					(      nn.Module    ):

  def __init__(   self  ,						_A  ,						_A  ,						_A  ,						_A  ,						):
      super().__init__()

      SCREAMING_SNAKE_CASE_													=  height
      SCREAMING_SNAKE_CASE_													=  width
      SCREAMING_SNAKE_CASE_													=  num_embed
      SCREAMING_SNAKE_CASE_													=  embed_dim

      SCREAMING_SNAKE_CASE_													=  nn.Embedding(self.num_embed  ,						snake_case__)
      SCREAMING_SNAKE_CASE_													=  nn.Embedding(self.height  ,						snake_case__)
      SCREAMING_SNAKE_CASE_													=  nn.Embedding(self.width  ,						snake_case__)


  def   lowerCAmelCase__       (   self  ,						_A):
      SCREAMING_SNAKE_CASE_													=  self.emb(snake_case__)

      SCREAMING_SNAKE_CASE_													=  self.height_emb(torch.arange(self.height  ,						device=index.device).view(1  ,						self.height))

      # 1 x H x D -> 1 x H x 1 x D
      SCREAMING_SNAKE_CASE_													=  height_emb.unsqueeze(2)

      SCREAMING_SNAKE_CASE_													=  self.width_emb(torch.arange(self.width  ,						device=index.device).view(1  ,						self.width))

      # 1 x W x D -> 1 x 1 x W x D
      SCREAMING_SNAKE_CASE_													=  width_emb.unsqueeze(1)

      SCREAMING_SNAKE_CASE_													=  height_emb + width_emb

      # 1 x H x W x D -> 1 x L xD
      SCREAMING_SNAKE_CASE_													=  pos_emb.view(1  ,						self.height * self.width  ,						-1)

      SCREAMING_SNAKE_CASE_													=  emb + pos_emb[:, : emb.shape[1], :]

      return emb






class  __snake_case					(      nn.Module    ):

  def __init__(   self  ,						_A  ,						_A  ,						_A):
      super().__init__()
      SCREAMING_SNAKE_CASE_													=  dropout_prob > 0
      SCREAMING_SNAKE_CASE_													=  nn.Embedding(num_classes + use_cfg_embedding  ,						snake_case__)
      SCREAMING_SNAKE_CASE_													=  num_classes
      SCREAMING_SNAKE_CASE_													=  dropout_prob

  def   lowerCAmelCase__       (   self  ,						_A  ,						_A=None):


      if force_drop_ids is None:
          SCREAMING_SNAKE_CASE_													=  torch.rand(labels.shape[0]  ,						device=labels.device) < self.dropout_prob
      else:
          SCREAMING_SNAKE_CASE_													=  torch.tensor(force_drop_ids == 1)
      SCREAMING_SNAKE_CASE_													=  torch.where(snake_case__  ,						self.num_classes  ,						snake_case__)
      return labels


  def   lowerCAmelCase__       (   self  ,						_A  ,						_A=None):
      SCREAMING_SNAKE_CASE_													=  self.dropout_prob > 0
      if (self.training and use_dropout) or (force_drop_ids is not None):
          SCREAMING_SNAKE_CASE_													=  self.token_drop(snake_case__  ,						snake_case__)
      SCREAMING_SNAKE_CASE_													=  self.embedding_table(snake_case__)
      return embeddings






class  __snake_case					(      nn.Module    ):

  def __init__(   self  ,						_A = 1024  ,						_A = 768  ,						_A = 768  ,						_A = 10  ,						):
      super().__init__()

      SCREAMING_SNAKE_CASE_													=  num_image_text_embeds
      SCREAMING_SNAKE_CASE_													=  nn.Linear(snake_case__  ,						self.num_image_text_embeds * cross_attention_dim)
      SCREAMING_SNAKE_CASE_													=  nn.Linear(snake_case__  ,						snake_case__)


  def   lowerCAmelCase__       (   self  ,						_A  ,						_A):
      SCREAMING_SNAKE_CASE_													=  text_embeds.shape[0]

      # image
      SCREAMING_SNAKE_CASE_													=  self.image_embeds(snake_case__)
      SCREAMING_SNAKE_CASE_													=  image_text_embeds.reshape(snake_case__  ,						self.num_image_text_embeds  ,						-1)

      # text
      SCREAMING_SNAKE_CASE_													=  self.text_proj(snake_case__)

      return torch.cat([image_text_embeds, text_embeds]  ,						dim=1)






class  __snake_case					(      nn.Module    ):

  def __init__(   self  ,						_A = 768  ,						_A = 768  ,						_A = 32  ,						):
      super().__init__()

      SCREAMING_SNAKE_CASE_													=  num_image_text_embeds
      SCREAMING_SNAKE_CASE_													=  nn.Linear(snake_case__  ,						self.num_image_text_embeds * cross_attention_dim)
      SCREAMING_SNAKE_CASE_													=  nn.LayerNorm(snake_case__)


  def   lowerCAmelCase__       (   self  ,						_A):
      SCREAMING_SNAKE_CASE_													=  image_embeds.shape[0]

      # image
      SCREAMING_SNAKE_CASE_													=  self.image_embeds(snake_case__)
      SCREAMING_SNAKE_CASE_													=  image_embeds.reshape(snake_case__  ,						self.num_image_text_embeds  ,						-1)
      SCREAMING_SNAKE_CASE_													=  self.norm(snake_case__)
      return image_embeds






class  __snake_case					(      nn.Module    ):

  def __init__(   self  ,						_A  ,						_A  ,						_A=0.1):
      super().__init__()

      SCREAMING_SNAKE_CASE_													=  Timesteps(num_channels=256  ,						flip_sin_to_cos=snake_case__  ,						downscale_freq_shift=1)
      SCREAMING_SNAKE_CASE_													=  TimestepEmbedding(in_channels=256  ,						time_embed_dim=snake_case__)
      SCREAMING_SNAKE_CASE_													=  LabelEmbedding(snake_case__  ,						snake_case__  ,						snake_case__)


  def   lowerCAmelCase__       (   self  ,						_A  ,						_A  ,						_A=None):
      SCREAMING_SNAKE_CASE_													=  self.time_proj(snake_case__)
      SCREAMING_SNAKE_CASE_													=  self.timestep_embedder(timesteps_proj.to(dtype=snake_case__))  # (N, D)

      SCREAMING_SNAKE_CASE_													=  self.class_embedder(snake_case__)  # (N, D)

      SCREAMING_SNAKE_CASE_													=  timesteps_emb + class_labels  # (N, D)

      return conditioning






class  __snake_case					(      nn.Module    ):

  def __init__(   self  ,						_A  ,						_A  ,						_A = 64):
      super().__init__()
      SCREAMING_SNAKE_CASE_													=  nn.LayerNorm(snake_case__)
      SCREAMING_SNAKE_CASE_													=  AttentionPooling(snake_case__  ,						snake_case__)
      SCREAMING_SNAKE_CASE_													=  nn.Linear(snake_case__  ,						snake_case__)
      SCREAMING_SNAKE_CASE_													=  nn.LayerNorm(snake_case__)


  def   lowerCAmelCase__       (   self  ,						_A):
      SCREAMING_SNAKE_CASE_													=  self.norma(snake_case__)
      SCREAMING_SNAKE_CASE_													=  self.pool(snake_case__)
      SCREAMING_SNAKE_CASE_													=  self.proj(snake_case__)
      SCREAMING_SNAKE_CASE_													=  self.norma(snake_case__)
      return hidden_states






class  __snake_case					(      nn.Module    ):

  def __init__(   self  ,						_A = 768  ,						_A = 768  ,						_A = 1536):
      super().__init__()
      SCREAMING_SNAKE_CASE_													=  nn.Linear(snake_case__  ,						snake_case__)
      SCREAMING_SNAKE_CASE_													=  nn.LayerNorm(snake_case__)
      SCREAMING_SNAKE_CASE_													=  nn.Linear(snake_case__  ,						snake_case__)


  def   lowerCAmelCase__       (   self  ,						_A  ,						_A):
      SCREAMING_SNAKE_CASE_													=  self.text_proj(snake_case__)
      SCREAMING_SNAKE_CASE_													=  self.text_norm(snake_case__)

      # image
      SCREAMING_SNAKE_CASE_													=  self.image_proj(snake_case__)

      return time_image_embeds + time_text_embeds






class  __snake_case					(      nn.Module    ):

  def __init__(   self  ,						_A = 768  ,						_A = 1536):
      super().__init__()
      SCREAMING_SNAKE_CASE_													=  nn.Linear(snake_case__  ,						snake_case__)
      SCREAMING_SNAKE_CASE_													=  nn.LayerNorm(snake_case__)


  def   lowerCAmelCase__       (   self  ,						_A):
      SCREAMING_SNAKE_CASE_													=  self.image_proj(snake_case__)
      SCREAMING_SNAKE_CASE_													=  self.image_norm(snake_case__)
      return time_image_embeds






class  __snake_case					(      nn.Module    ):

  def __init__(   self  ,						_A = 768  ,						_A = 1536):
      super().__init__()
      SCREAMING_SNAKE_CASE_													=  nn.Linear(snake_case__  ,						snake_case__)
      SCREAMING_SNAKE_CASE_													=  nn.LayerNorm(snake_case__)
      SCREAMING_SNAKE_CASE_													=  nn.Sequential(
          nn.Convad(3  ,						16  ,						3  ,						padding=1)  ,						nn.SiLU()  ,						nn.Convad(16  ,						16  ,						3  ,						padding=1)  ,						nn.SiLU()  ,						nn.Convad(16  ,						32  ,						3  ,						padding=1  ,						stride=2)  ,						nn.SiLU()  ,						nn.Convad(32  ,						32  ,						3  ,						padding=1)  ,						nn.SiLU()  ,						nn.Convad(32  ,						96  ,						3  ,						padding=1  ,						stride=2)  ,						nn.SiLU()  ,						nn.Convad(96  ,						96  ,						3  ,						padding=1)  ,						nn.SiLU()  ,						nn.Convad(96  ,						256  ,						3  ,						padding=1  ,						stride=2)  ,						nn.SiLU()  ,						nn.Convad(256  ,						4  ,						3  ,						padding=1)  ,						)


  def   lowerCAmelCase__       (   self  ,						_A  ,						_A):
      SCREAMING_SNAKE_CASE_													=  self.image_proj(snake_case__)
      SCREAMING_SNAKE_CASE_													=  self.image_norm(snake_case__)
      SCREAMING_SNAKE_CASE_													=  self.input_hint_block(snake_case__)
      return time_image_embeds, hint






class  __snake_case					(      nn.Module    ):

  def __init__(   self  ,						_A  ,						_A  ,						_A=None):
      super().__init__()
      SCREAMING_SNAKE_CASE_													=  dtype
      SCREAMING_SNAKE_CASE_													=  nn.Parameter(torch.randn(1  ,						snake_case__) / embed_dim**0.5)
      SCREAMING_SNAKE_CASE_													=  nn.Linear(snake_case__  ,						snake_case__  ,						dtype=self.dtype)
      SCREAMING_SNAKE_CASE_													=  nn.Linear(snake_case__  ,						snake_case__  ,						dtype=self.dtype)
      SCREAMING_SNAKE_CASE_													=  nn.Linear(snake_case__  ,						snake_case__  ,						dtype=self.dtype)
      SCREAMING_SNAKE_CASE_													=  num_heads
      SCREAMING_SNAKE_CASE_													=  embed_dim // self.num_heads


  def   lowerCAmelCase__       (   self  ,						_A):
      SCREAMING_SNAKE_CASE_							,     SCREAMING_SNAKE_CASE_							,     SCREAMING_SNAKE_CASE_													=  x.size()

      def shape(_A):
          # (bs, length, width) --> (bs, length, n_heads, dim_per_head)
          SCREAMING_SNAKE_CASE_													=  x.view(snake_case__  ,						-1  ,						self.num_heads  ,						self.dim_per_head)
          # (bs, length, n_heads, dim_per_head) --> (bs, n_heads, length, dim_per_head)
          SCREAMING_SNAKE_CASE_													=  x.transpose(1  ,						2)
          # (bs, n_heads, length, dim_per_head) --> (bs*n_heads, length, dim_per_head)
          SCREAMING_SNAKE_CASE_													=  x.reshape(bs * self.num_heads  ,						-1  ,						self.dim_per_head)
          # (bs*n_heads, length, dim_per_head) --> (bs*n_heads, dim_per_head, length)
          SCREAMING_SNAKE_CASE_													=  x.transpose(1  ,						2)
          return x

      SCREAMING_SNAKE_CASE_													=  x.mean(dim=1  ,						keepdim=snake_case__) + self.positional_embedding.to(x.dtype)
      SCREAMING_SNAKE_CASE_													=  torch.cat([class_token, x]  ,						dim=1)  # (bs, length+1, width)

      # (bs*n_heads, class_token_length, dim_per_head)
      SCREAMING_SNAKE_CASE_													=  shape(self.q_proj(snake_case__))
      # (bs*n_heads, length+class_token_length, dim_per_head)
      SCREAMING_SNAKE_CASE_													=  shape(self.k_proj(snake_case__))
      SCREAMING_SNAKE_CASE_													=  shape(self.v_proj(snake_case__))

      # (bs*n_heads, class_token_length, length+class_token_length):
      SCREAMING_SNAKE_CASE_													=  1 / math.sqrt(math.sqrt(self.dim_per_head))
      SCREAMING_SNAKE_CASE_													=  torch.einsum('bct,bcs->bts'  ,						q * scale  ,						k * scale)  # More stable with f16 than dividing afterwards
      SCREAMING_SNAKE_CASE_													=  torch.softmax(weight.float()  ,						dim=-1).type(weight.dtype)

      # (bs*n_heads, dim_per_head, class_token_length)
      SCREAMING_SNAKE_CASE_													=  torch.einsum('bts,bcs->bct'  ,						snake_case__  ,						snake_case__)

      # (bs, length+1, width)
      SCREAMING_SNAKE_CASE_													=  a.reshape(snake_case__  ,						-1  ,						1).transpose(1  ,						2)

      return a[:, 0, :]  # cls_token





def    _UpperCAmelCase    (					_SCREAMING_SNAKE_CASE   :						int	,				_SCREAMING_SNAKE_CASE   :						int	,				_SCREAMING_SNAKE_CASE   :						int    ):





    """simple docstring"""


    if power < 0:
        return -1
    base %= mod
    SCREAMING_SNAKE_CASE_													=  1

    while power > 0:
        if power & 1:
            SCREAMING_SNAKE_CASE_													=  (result * base) % mod
        SCREAMING_SNAKE_CASE_													=  power >> 1
        SCREAMING_SNAKE_CASE_													=  (base * base) % mod

    return result


def    _UpperCAmelCase    (					):





    """simple docstring"""


    print(modular_exponential(3	,				200	,				13    )    )


if __name__ == "__main__":
       import doctest

       doctest.testmod()

       main()


