





import dataclasses
import re
import string
from typing import Any, Dict, Iterator, List, Mapping, Optional, Sequence, Tuple

import numpy as np

from . import residue_constants


_UpperCAmelCase       : int			     =       Mapping[str, np.ndarray]
_UpperCAmelCase       : List[Any]			     =       Mapping[str, Any]  # Is a nested dict.
_UpperCAmelCase       : Dict			     =       0.01

@dataclasses.dataclass(frozen=__UpperCamelCase    )
class      lowerCAmelCase							:
 UpperCAmelCase__									=	42  # [num_res, num_atom_type, 3]

 # Amino-acid type for each residue represented as an integer between 0 and
 # 20, where 20 is 'X'.
 UpperCAmelCase__									=	42  # [num_res]

 # Binary float mask to indicate presence of a particular atom. 1.0 if an atom
 # is present and 0.0 if not. This should be used for loss masking.
 UpperCAmelCase__									=	42  # [num_res, num_atom_type]

 # Residue index as used in PDB. It is not necessarily continuous or 0-indexed.
 UpperCAmelCase__									=	42  # [num_res]

 # B-factors, or temperature factors, of each residue (in sq. angstroms units),
 # representing the displacement of the residue from its ground truth mean
 # value.
 UpperCAmelCase__									=	42  # [num_res, num_atom_type]

 # Chain indices for multi-chain predictions
 UpperCAmelCase__									=	None

 # Optional remark about the protein. Included as a comment in output PDB
 # files
 UpperCAmelCase__									=	None

 # Templates used to generate this protein (prediction-only)
 UpperCAmelCase__									=	None

 # Chain corresponding to each parent
 UpperCAmelCase__									=	None


def  SCREAMING_SNAKE_CASE   ( _UpperCAmelCase				)    ->  Protein:
    lowerCamelCase__					:   Optional[int]      				=	r'(\[[A-Z]+\]\n)'
    lowerCamelCase__					:   List[str]      				=	[tag.strip() for tag in re.split(_UpperCAmelCase		,			_UpperCAmelCase				) if len(_UpperCAmelCase				) > 0]
    lowerCamelCase__					:   Iterator[Tuple[str, List[str]]]      				=	zip(tags[0::2]		,			[l.split('\n'				) for l in tags[1::2]]				)

    lowerCamelCase__					:   List[str]      				=	["N", "CA", "C"]
    lowerCamelCase__					:   Dict      				=	None
    lowerCamelCase__					:   str      				=	None
    lowerCamelCase__					:   int      				=	None
    for g in groups:
        if "[PRIMARY]" == g[0]:
            lowerCamelCase__					:   int      				=	g[1][0].strip()
            for i in range(len(_UpperCAmelCase				)				):
                if seq[i] not in residue_constants.restypes:
                    lowerCamelCase__					:   Union[str, Any]      				=	'X'  # FIXME: strings are immutable
            lowerCamelCase__					:   Union[str, Any]      				=	np.array(
                [residue_constants.restype_order.get(_UpperCAmelCase		,			residue_constants.restype_num				) for res_symbol in seq]				)
        elif "[TERTIARY]" == g[0]:
            lowerCamelCase__					:   List[List[float]]      				=	[]
            for axis in range(3				):
                tertiary.append(list(map(_UpperCAmelCase		,			g[1][axis].split()				)				)				)
            lowerCamelCase__					:   int      				=	np.array(_UpperCAmelCase				)
            lowerCamelCase__					:   Tuple      				=	np.zeros((len(tertiary[0]				) // 3, residue_constants.atom_type_num, 3)				).astype(np.floataa				)
            for i, atom in enumerate(_UpperCAmelCase				):
                lowerCamelCase__					:   int      				=	np.transpose(tertiary_np[:, i::3]				)
            atom_positions *= PICO_TO_ANGSTROM
        elif "[MASK]" == g[0]:
            lowerCamelCase__					:   int      				=	np.array(list(map({'-': 0, '+': 1}.get		,			g[1][0].strip()				)				)				)
            lowerCamelCase__					:   List[Any]      				=	np.zeros(
                (
                    len(_UpperCAmelCase				),
                    residue_constants.atom_type_num,
                )				).astype(np.floataa				)
            for i, atom in enumerate(_UpperCAmelCase				):
                lowerCamelCase__					:   Union[str, Any]      				=	1
            atom_mask *= mask[..., None]

    assert aatype is not None

    return Protein(
        atom_positions=_UpperCAmelCase		,			atom_mask=_UpperCAmelCase		,			aatype=_UpperCAmelCase		,			residue_index=np.arange(len(_UpperCAmelCase				)				)		,			b_factors=_UpperCAmelCase		,			)


def  SCREAMING_SNAKE_CASE   ( _UpperCAmelCase		,			_UpperCAmelCase = 0				)    ->  List[str]:
    lowerCamelCase__					:   List[str]      				=	[]

    lowerCamelCase__					:   Dict      				=	prot.remark
    if remark is not None:
        pdb_headers.append(F"""REMARK {remark}"""				)

    lowerCamelCase__					:   str      				=	prot.parents
    lowerCamelCase__					:   Union[str, Any]      				=	prot.parents_chain_index
    if parents is not None and parents_chain_index is not None:
        lowerCamelCase__					:   Any      				=	[p for i, p in zip(_UpperCAmelCase		,			_UpperCAmelCase				) if i == chain_id]

    if parents is None or len(_UpperCAmelCase				) == 0:
        lowerCamelCase__					:   List[Any]      				=	['N/A']

    pdb_headers.append(F"""PARENT {" ".join(_UpperCAmelCase				)}"""				)

    return pdb_headers


def  SCREAMING_SNAKE_CASE   ( _UpperCAmelCase		,			_UpperCAmelCase				)    ->  str:
    lowerCamelCase__					:   List[str]      				=	[]
    lowerCamelCase__					:   str      				=	pdb_str.split('\n'				)

    lowerCamelCase__					:   int      				=	prot.remark
    if remark is not None:
        out_pdb_lines.append(F"""REMARK {remark}"""				)

    lowerCamelCase__					:   List[List[str]]
    if prot.parents is not None and len(prot.parents				) > 0:
        lowerCamelCase__					:   List[Any]      				=	[]
        if prot.parents_chain_index is not None:
            lowerCamelCase__					:   Dict[str, List[str]]      				=	{}
            for p, i in zip(prot.parents		,			prot.parents_chain_index				):
                parent_dict.setdefault(str(_UpperCAmelCase				)		,			[]				)
                parent_dict[str(_UpperCAmelCase				)].append(_UpperCAmelCase				)

            lowerCamelCase__					:   str      				=	max([int(_UpperCAmelCase				) for chain_idx in parent_dict]				)
            for i in range(max_idx + 1				):
                lowerCamelCase__					:   Optional[Any]      				=	parent_dict.get(str(_UpperCAmelCase				)		,			['N/A']				)
                parents_per_chain.append(_UpperCAmelCase				)
        else:
            parents_per_chain.append(list(prot.parents				)				)
    else:
        lowerCamelCase__					:   Union[str, Any]      				=	[['N/A']]

    def make_parent_line(_UpperCAmelCase				) -> str:
        return F"""PARENT {" ".join(_UpperCAmelCase				)}"""

    out_pdb_lines.append(make_parent_line(parents_per_chain[0]				)				)

    lowerCamelCase__					:   List[Any]      				=	0
    for i, l in enumerate(_UpperCAmelCase				):
        if "PARENT" not in l and "REMARK" not in l:
            out_pdb_lines.append(_UpperCAmelCase				)
        if "TER" in l and "END" not in lines[i + 1]:
            chain_counter += 1
            if not chain_counter >= len(_UpperCAmelCase				):
                lowerCamelCase__					:   Union[str, Any]      				=	parents_per_chain[chain_counter]
            else:
                lowerCamelCase__					:   Optional[Any]      				=	['N/A']

            out_pdb_lines.append(make_parent_line(_UpperCAmelCase				)				)

    return "\n".join(_UpperCAmelCase				)


def  SCREAMING_SNAKE_CASE   ( _UpperCAmelCase				)    ->  str:
    lowerCamelCase__					:   Tuple      				=	residue_constants.restypes + ['X']

    def res_atoa(_UpperCAmelCase				) -> str:
        return residue_constants.restype_atoa.get(restypes[r]		,			'UNK'				)

    lowerCamelCase__					:   int      				=	residue_constants.atom_types

    lowerCamelCase__					:   List[str]      				=	[]

    lowerCamelCase__					:   Union[str, Any]      				=	prot.atom_mask
    lowerCamelCase__					:   Union[str, Any]      				=	prot.aatype
    lowerCamelCase__					:   int      				=	prot.atom_positions
    lowerCamelCase__					:   List[Any]      				=	prot.residue_index.astype(np.intaa				)
    lowerCamelCase__					:   Optional[int]      				=	prot.b_factors
    lowerCamelCase__					:   Any      				=	prot.chain_index

    if np.any(aatype > residue_constants.restype_num				):
        raise ValueError('Invalid aatypes.'				)

    lowerCamelCase__					:   List[Any]      				=	get_pdb_headers(_UpperCAmelCase				)
    if len(_UpperCAmelCase				) > 0:
        pdb_lines.extend(_UpperCAmelCase				)

    lowerCamelCase__					:   Union[str, Any]      				=	aatype.shape[0]
    lowerCamelCase__					:   Optional[Any]      				=	1
    lowerCamelCase__					:   str      				=	0
    lowerCamelCase__					:   Tuple      				=	string.ascii_uppercase
    lowerCamelCase__					:   str      				=	None
    # Add all atom sites.
    for i in range(_UpperCAmelCase				):
        lowerCamelCase__					:   List[Any]      				=	res_atoa(aatype[i]				)
        for atom_name, pos, mask, b_factor in zip(_UpperCAmelCase		,			atom_positions[i]		,			atom_mask[i]		,			b_factors[i]				):
            if mask < 0.5:
                continue

            lowerCamelCase__					:   Union[str, Any]      				=	'ATOM'
            lowerCamelCase__					:   Optional[int]      				=	atom_name if len(_UpperCAmelCase				) == 4 else F""" {atom_name}"""
            lowerCamelCase__					:   Any      				=	''
            lowerCamelCase__					:   Optional[Any]      				=	''
            lowerCamelCase__					:   str      				=	1.00
            lowerCamelCase__					:   str      				=	atom_name[0]  # Protein supports only C, N, O, S, this works.
            lowerCamelCase__					:   List[str]      				=	''

            lowerCamelCase__					:   str      				=	'A'
            if chain_index is not None:
                lowerCamelCase__					:   List[Any]      				=	chain_tags[chain_index[i]]

            # PDB is a columnar format, every space matters here!
            lowerCamelCase__					:   Union[str, Any]      				=	(
                F"""{record_type:<6}{atom_index:>5} {name:<4}{alt_loc:>1}"""
                F"""{res_name_a:>3} {chain_tag:>1}"""
                F"""{residue_index[i]:>4}{insertion_code:>1}   """
                F"""{pos[0]:>8.3f}{pos[1]:>8.3f}{pos[2]:>8.3f}"""
                F"""{occupancy:>6.2f}{b_factor:>6.2f}          """
                F"""{element:>2}{charge:>2}"""
            )
            pdb_lines.append(_UpperCAmelCase				)
            atom_index += 1

        lowerCamelCase__					:   Dict      				=	i == n - 1
        if chain_index is not None:
            if i != n - 1 and chain_index[i + 1] != prev_chain_index:
                lowerCamelCase__					:   List[Any]      				=	True
                lowerCamelCase__					:   List[str]      				=	chain_index[i + 1]

        if should_terminate:
            # Close the chain.
            lowerCamelCase__					:   int      				=	'TER'
            lowerCamelCase__					:   Any      				=	(
                F"""{chain_end:<6}{atom_index:>5}      {res_atoa(aatype[i]				):>3} {chain_tag:>1}{residue_index[i]:>4}"""
            )
            pdb_lines.append(_UpperCAmelCase				)
            atom_index += 1

            if i != n - 1:
                # "prev" is a misnomer here. This happens at the beginning of
                # each new chain.
                pdb_lines.extend(get_pdb_headers(_UpperCAmelCase		,			_UpperCAmelCase				)				)

    pdb_lines.append('END'				)
    pdb_lines.append(''				)
    return "\n".join(_UpperCAmelCase				)


def  SCREAMING_SNAKE_CASE   ( _UpperCAmelCase				)    ->  np.ndarray:
    return residue_constants.STANDARD_ATOM_MASK[prot.aatype]


def  SCREAMING_SNAKE_CASE   ( _UpperCAmelCase		,			_UpperCAmelCase		,			_UpperCAmelCase = None		,			_UpperCAmelCase = None		,			_UpperCAmelCase = None		,			_UpperCAmelCase = None		,			_UpperCAmelCase = None		,			)    ->  Protein:
    return Protein(
        aatype=features['aatype']		,			atom_positions=result['final_atom_positions']		,			atom_mask=result['final_atom_mask']		,			residue_index=features['residue_index'] + 1		,			b_factors=b_factors if b_factors is not None else np.zeros_like(result['final_atom_mask']				)		,			chain_index=_UpperCAmelCase		,			remark=_UpperCAmelCase		,			parents=_UpperCAmelCase		,			parents_chain_index=_UpperCAmelCase		,			)












from typing import Optional, Tuple, Union

import flax
import flax.linen as nn
import jax
import jax.numpy as jnp
from flax.core.frozen_dict import FrozenDict

from ..configuration_utils import ConfigMixin, flax_register_to_config
from ..utils import BaseOutput
from .embeddings_flax import FlaxTimestepEmbedding, FlaxTimesteps
from .modeling_flax_utils import FlaxModelMixin
from .unet_ad_blocks_flax import (
    FlaxCrossAttnDownBlockaD,
    FlaxCrossAttnUpBlockaD,
    FlaxDownBlockaD,
    FlaxUNetMidBlockaDCrossAttn,
    FlaxUpBlockaD,
)

@flax.struct.dataclass
class      lowerCAmelCase							(      __UpperCamelCase    ):
 UpperCAmelCase__									=	42


@flax_register_to_config
class      lowerCAmelCase							(      nn.Module,						__UpperCamelCase,						__UpperCamelCase    ):
 UpperCAmelCase__									=	32
 UpperCAmelCase__									=	4
 UpperCAmelCase__									=	4
 UpperCAmelCase__									=	(
     "CrossAttnDownBlock2D",
     "CrossAttnDownBlock2D",
     "CrossAttnDownBlock2D",
     "DownBlock2D",
 )
 UpperCAmelCase__									=	("UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D")
 UpperCAmelCase__									=	False
 UpperCAmelCase__									=	(3_20, 6_40, 12_80, 12_80)
 UpperCAmelCase__									=	2
 UpperCAmelCase__									=	8
 UpperCAmelCase__									=	None
 UpperCAmelCase__									=	12_80
 UpperCAmelCase__									=	0.0
 UpperCAmelCase__									=	False
 UpperCAmelCase__									=	jnp.floataa
 UpperCAmelCase__									=	True
 UpperCAmelCase__									=	0
 UpperCAmelCase__									=	False
 def   A_			(   self						:   Tuple    ,  UpperCAmelCase						:   jax.random.KeyArray			)    ->			FrozenDict:
     # init input tensors
     lowerCamelCase__					:   int      				=	(1, self.in_channels, self.sample_size, self.sample_size)
     lowerCamelCase__					:   List[str]      				=	jnp.zeros(UpperCAmelCase    ,  dtype=jnp.floataa			)
     lowerCamelCase__					:   Tuple      				=	jnp.ones((1,)    ,  dtype=jnp.intaa			)
     lowerCamelCase__					:   Dict      				=	jnp.zeros((1, 1, self.cross_attention_dim)    ,  dtype=jnp.floataa			)

     lowerCamelCase__				,							lowerCamelCase__					:   Union[str, Any]      				=	jax.random.split(UpperCAmelCase			)
     lowerCamelCase__					:   Dict      				=	{'params': params_rng, 'dropout': dropout_rng}

     return self.init(UpperCAmelCase    ,  UpperCAmelCase    ,  UpperCAmelCase    ,  UpperCAmelCase			)["params"]
 def   A_			(   self						:   Tuple			)    ->			Optional[int]:
     lowerCamelCase__					:   Any      				=	self.block_out_channels
     lowerCamelCase__					:   int      				=	block_out_channels[0] * 4

     if self.num_attention_heads is not None:
         raise ValueError(
             'At the moment it is not possible to define the number of attention heads via `num_attention_heads` because of a naming issue as described in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131. Passing `num_attention_heads` will only be supported in diffusers v0.19.'			)

     # If `num_attention_heads` is not defined (which is the case for most models)
     # it will default to `attention_head_dim`. This looks weird upon first reading it and it is.
     # The reason for this behavior is to correct for incorrectly named variables that were introduced
     # when this library was created. The incorrect naming was only discovered much later in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131
     # Changing `attention_head_dim` to `num_attention_heads` for 40,000+ configurations is too backwards breaking
     # which is why we correct for the naming here.
     lowerCamelCase__					:   Tuple      				=	self.num_attention_heads or self.attention_head_dim

     # input
     lowerCamelCase__					:   Optional[Any]      				=	nn.Conv(
         block_out_channels[0]    ,  kernel_size=(3, 3)    ,  strides=(1, 1)    ,  padding=((1, 1), (1, 1))    ,  dtype=self.dtype    ,  )

     # time
     lowerCamelCase__					:   Optional[int]      				=	FlaxTimesteps(
         block_out_channels[0]    ,  flip_sin_to_cos=self.flip_sin_to_cos    ,  freq_shift=self.config.freq_shift			)
     lowerCamelCase__					:   int      				=	FlaxTimestepEmbedding(UpperCAmelCase    ,  dtype=self.dtype			)

     lowerCamelCase__					:   Optional[int]      				=	self.only_cross_attention
     if isinstance(UpperCAmelCase    ,  UpperCAmelCase			):
         lowerCamelCase__					:   str      				=	(only_cross_attention,) * len(self.down_block_types			)

     if isinstance(UpperCAmelCase    ,  UpperCAmelCase			):
         lowerCamelCase__					:   List[Any]      				=	(num_attention_heads,) * len(self.down_block_types			)

     # down
     lowerCamelCase__					:   List[Any]      				=	[]
     lowerCamelCase__					:   Dict      				=	block_out_channels[0]
     for i, down_block_type in enumerate(self.down_block_types			):
         lowerCamelCase__					:   Dict      				=	output_channel
         lowerCamelCase__					:   Optional[int]      				=	block_out_channels[i]
         lowerCamelCase__					:   List[Any]      				=	i == len(UpperCAmelCase			) - 1

         if down_block_type == "CrossAttnDownBlock2D":
             lowerCamelCase__					:   Tuple      				=	FlaxCrossAttnDownBlockaD(
                 in_channels=UpperCAmelCase    ,  out_channels=UpperCAmelCase    ,  dropout=self.dropout    ,  num_layers=self.layers_per_block    ,  num_attention_heads=num_attention_heads[i]    ,  add_downsample=not is_final_block    ,  use_linear_projection=self.use_linear_projection    ,  only_cross_attention=only_cross_attention[i]    ,  use_memory_efficient_attention=self.use_memory_efficient_attention    ,  dtype=self.dtype    ,  )
         else:
             lowerCamelCase__					:   str      				=	FlaxDownBlockaD(
                 in_channels=UpperCAmelCase    ,  out_channels=UpperCAmelCase    ,  dropout=self.dropout    ,  num_layers=self.layers_per_block    ,  add_downsample=not is_final_block    ,  dtype=self.dtype    ,  )

         down_blocks.append(UpperCAmelCase			)
     lowerCamelCase__					:   List[Any]      				=	down_blocks

     # mid
     lowerCamelCase__					:   Dict      				=	FlaxUNetMidBlockaDCrossAttn(
         in_channels=block_out_channels[-1]    ,  dropout=self.dropout    ,  num_attention_heads=num_attention_heads[-1]    ,  use_linear_projection=self.use_linear_projection    ,  use_memory_efficient_attention=self.use_memory_efficient_attention    ,  dtype=self.dtype    ,  )

     # up
     lowerCamelCase__					:   Any      				=	[]
     lowerCamelCase__					:   Optional[int]      				=	list(reversed(UpperCAmelCase			)			)
     lowerCamelCase__					:   Any      				=	list(reversed(UpperCAmelCase			)			)
     lowerCamelCase__					:   int      				=	list(reversed(UpperCAmelCase			)			)
     lowerCamelCase__					:   Tuple      				=	reversed_block_out_channels[0]
     for i, up_block_type in enumerate(self.up_block_types			):
         lowerCamelCase__					:   str      				=	output_channel
         lowerCamelCase__					:   int      				=	reversed_block_out_channels[i]
         lowerCamelCase__					:   int      				=	reversed_block_out_channels[min(i + 1    ,  len(UpperCAmelCase			) - 1			)]

         lowerCamelCase__					:   Optional[Any]      				=	i == len(UpperCAmelCase			) - 1

         if up_block_type == "CrossAttnUpBlock2D":
             lowerCamelCase__					:   Tuple      				=	FlaxCrossAttnUpBlockaD(
                 in_channels=UpperCAmelCase    ,  out_channels=UpperCAmelCase    ,  prev_output_channel=UpperCAmelCase    ,  num_layers=self.layers_per_block + 1    ,  num_attention_heads=reversed_num_attention_heads[i]    ,  add_upsample=not is_final_block    ,  dropout=self.dropout    ,  use_linear_projection=self.use_linear_projection    ,  only_cross_attention=only_cross_attention[i]    ,  use_memory_efficient_attention=self.use_memory_efficient_attention    ,  dtype=self.dtype    ,  )
         else:
             lowerCamelCase__					:   Optional[Any]      				=	FlaxUpBlockaD(
                 in_channels=UpperCAmelCase    ,  out_channels=UpperCAmelCase    ,  prev_output_channel=UpperCAmelCase    ,  num_layers=self.layers_per_block + 1    ,  add_upsample=not is_final_block    ,  dropout=self.dropout    ,  dtype=self.dtype    ,  )

         up_blocks.append(UpperCAmelCase			)
         lowerCamelCase__					:   Tuple      				=	output_channel
     lowerCamelCase__					:   Tuple      				=	up_blocks

     # out
     lowerCamelCase__					:   Optional[int]      				=	nn.GroupNorm(num_groups=32    ,  epsilon=1e-5			)
     lowerCamelCase__					:   Any      				=	nn.Conv(
         self.out_channels    ,  kernel_size=(3, 3)    ,  strides=(1, 1)    ,  padding=((1, 1), (1, 1))    ,  dtype=self.dtype    ,  )







 def __call__(   self						:   int    ,  UpperCAmelCase						:   Any    ,  UpperCAmelCase						:   Tuple    ,  UpperCAmelCase						:   Optional[Any]    ,  UpperCAmelCase						:   Optional[Any]=None    ,  UpperCAmelCase						:   Dict=None    ,  UpperCAmelCase						:   bool = True    ,  UpperCAmelCase						:   bool = False    ,  )    ->			Union[FlaxUNetaDConditionOutput, Tuple]:
     # 1. time
     if not isinstance(UpperCAmelCase    ,  jnp.ndarray			):
         lowerCamelCase__					:   List[str]      				=	jnp.array([timesteps]    ,  dtype=jnp.intaa			)
     elif isinstance(UpperCAmelCase    ,  jnp.ndarray			) and len(timesteps.shape			) == 0:
         lowerCamelCase__					:   List[Any]      				=	timesteps.astype(dtype=jnp.floataa			)
         lowerCamelCase__					:   Any      				=	jnp.expand_dims(UpperCAmelCase    ,  0			)

     lowerCamelCase__					:   List[str]      				=	self.time_proj(UpperCAmelCase			)
     lowerCamelCase__					:   Optional[Any]      				=	self.time_embedding(UpperCAmelCase			)

     # 2. pre-process
     lowerCamelCase__					:   Dict      				=	jnp.transpose(UpperCAmelCase    ,  (0, 2, 3, 1)			)
     lowerCamelCase__					:   Optional[Any]      				=	self.conv_in(UpperCAmelCase			)

     # 3. down
     lowerCamelCase__					:   Any      				=	(sample,)
     for down_block in self.down_blocks:
         if isinstance(UpperCAmelCase    ,  UpperCAmelCase			):
             lowerCamelCase__				,							lowerCamelCase__					:   Optional[Any]      				=	down_block(UpperCAmelCase    ,  UpperCAmelCase    ,  UpperCAmelCase    ,  deterministic=not train			)
         else:
             lowerCamelCase__				,							lowerCamelCase__					:   Any      				=	down_block(UpperCAmelCase    ,  UpperCAmelCase    ,  deterministic=not train			)
         down_block_res_samples += res_samples

     if down_block_additional_residuals is not None:
         lowerCamelCase__					:   Union[str, Any]      				=	()

         for down_block_res_sample, down_block_additional_residual in zip(
             UpperCAmelCase    ,  UpperCAmelCase			):
             down_block_res_sample += down_block_additional_residual
             new_down_block_res_samples += (down_block_res_sample,)

         lowerCamelCase__					:   str      				=	new_down_block_res_samples

     # 4. mid
     lowerCamelCase__					:   List[Any]      				=	self.mid_block(UpperCAmelCase    ,  UpperCAmelCase    ,  UpperCAmelCase    ,  deterministic=not train			)

     if mid_block_additional_residual is not None:
         sample += mid_block_additional_residual

     # 5. up
     for up_block in self.up_blocks:
         lowerCamelCase__					:   str      				=	down_block_res_samples[-(self.layers_per_block + 1) :]
         lowerCamelCase__					:   List[str]      				=	down_block_res_samples[: -(self.layers_per_block + 1)]
         if isinstance(UpperCAmelCase    ,  UpperCAmelCase			):
             lowerCamelCase__					:   List[Any]      				=	up_block(
                 UpperCAmelCase    ,  temb=UpperCAmelCase    ,  encoder_hidden_states=UpperCAmelCase    ,  res_hidden_states_tuple=UpperCAmelCase    ,  deterministic=not train    ,  )
         else:
             lowerCamelCase__					:   int      				=	up_block(UpperCAmelCase    ,  temb=UpperCAmelCase    ,  res_hidden_states_tuple=UpperCAmelCase    ,  deterministic=not train			)

        # 6. post-process
     lowerCamelCase__					:   str      				=	self.conv_norm_out(UpperCAmelCase			)
     lowerCamelCase__					:   Optional[Any]      				=	nn.silu(UpperCAmelCase			)
     lowerCamelCase__					:   Any      				=	self.conv_out(UpperCAmelCase			)
     lowerCamelCase__					:   Optional[Any]      				=	jnp.transpose(UpperCAmelCase    ,  (0, 3, 1, 2)			)

     if not return_dict:
         return (sample,)

     return FlaxUNetaDConditionOutput(sample=UpperCAmelCase			)





