




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,
    FlaxDownBlockaD,
    FlaxUNetMidBlockaDCrossAttn,
)







@flax.struct.dataclass
class        __lowerCAmelCase					(			__magic_name__					):

			"""simple docstring"""







			snake_case_  						=			42
			snake_case_  						=			42







class        __lowerCAmelCase					(			nn.Module					):

			"""simple docstring"""







			snake_case_  						=			42
			snake_case_  						=			(16, 32, 96, 2_56)
			snake_case_  						=			jnp.floataa


			def  lowercase_       ( self				)       -> Any:



							'''simple docstring'''
							__lowerCamelCase									=       nn.Conv(
							    self.block_out_channels[0]     ,		kernel_size=(3, 3)     ,		padding=((1, 1), (1, 1))     ,		dtype=self.dtype     ,		)

							__lowerCamelCase									=       []
							for i in range(len(self.block_out_channels				) - 1				):
											__lowerCamelCase									=       self.block_out_channels[i]
											__lowerCamelCase									=       self.block_out_channels[i + 1]
											__lowerCamelCase									=       nn.Conv(
											    lowerCamelCase__     ,		kernel_size=(3, 3)     ,		padding=((1, 1), (1, 1))     ,		dtype=self.dtype     ,		)
											blocks.append(lowerCamelCase__				)
											__lowerCamelCase									=       nn.Conv(
											    lowerCamelCase__     ,		kernel_size=(3, 3)     ,		strides=(2, 2)     ,		padding=((1, 1), (1, 1))     ,		dtype=self.dtype     ,		)
											blocks.append(lowerCamelCase__				)
							__lowerCamelCase									=       blocks

							__lowerCamelCase									=       nn.Conv(
							    self.conditioning_embedding_channels     ,		kernel_size=(3, 3)     ,		padding=((1, 1), (1, 1))     ,		kernel_init=nn.initializers.zeros_init()     ,		bias_init=nn.initializers.zeros_init()     ,		dtype=self.dtype     ,		)






			def __call__( self     ,		lowerCamelCase__				)       -> Tuple:



							'''simple docstring'''
							__lowerCamelCase									=       self.conv_in(lowerCamelCase__				)
							__lowerCamelCase									=       nn.silu(lowerCamelCase__				)

							for block in self.blocks:
											__lowerCamelCase									=       block(lowerCamelCase__				)
											__lowerCamelCase									=       nn.silu(lowerCamelCase__				)

							__lowerCamelCase									=       self.conv_out(lowerCamelCase__				)

							return embedding







@flax_register_to_config
class        __lowerCAmelCase					(			nn.Module     ,							__magic_name__     ,							__magic_name__					):

			"""simple docstring"""







			snake_case_  						=			32
			snake_case_  						=			4
			snake_case_  						=			(
			    "CrossAttnDownBlock2D",
			    "CrossAttnDownBlock2D",
			    "CrossAttnDownBlock2D",
			    "DownBlock2D",
			)
			snake_case_  						=			False
			snake_case_  						=			(3_20, 6_40, 12_80, 12_80)
			snake_case_  						=			2
			snake_case_  						=			8
			snake_case_  						=			None
			snake_case_  						=			12_80
			snake_case_  						=			0.0
			snake_case_  						=			False
			snake_case_  						=			jnp.floataa
			snake_case_  						=			True
			snake_case_  						=			0
			snake_case_  						=			"rgb"
			snake_case_  						=			(16, 32, 96, 2_56)


			def  lowercase_       ( self     ,		lowerCamelCase__				)       -> FrozenDict:



							'''simple docstring'''
							# init input tensors
							__lowerCamelCase									=       (1, self.in_channels, self.sample_size, self.sample_size)
							__lowerCamelCase									=       jnp.zeros(lowerCamelCase__     ,		dtype=jnp.floataa				)
							__lowerCamelCase									=       jnp.ones((1,)     ,		dtype=jnp.intaa				)
							__lowerCamelCase									=       jnp.zeros((1, 1, self.cross_attention_dim)     ,		dtype=jnp.floataa				)
							__lowerCamelCase									=       (1, 3, self.sample_size * 8, self.sample_size * 8)
							__lowerCamelCase									=       jnp.zeros(lowerCamelCase__     ,		dtype=jnp.floataa				)

							__lowerCamelCase			,		__lowerCamelCase									=       jax.random.split(lowerCamelCase__				)
							__lowerCamelCase									=       {'params': params_rng, 'dropout': dropout_rng}

							return self.init(lowerCamelCase__     ,		lowerCamelCase__     ,		lowerCamelCase__     ,		lowerCamelCase__     ,		lowerCamelCase__				)["params"]


			def  lowercase_       ( self				)       -> List[Any]:



							'''simple docstring'''
							__lowerCamelCase									=       self.block_out_channels
							__lowerCamelCase									=       block_out_channels[0] * 4

							# 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									=       self.num_attention_heads or self.attention_head_dim

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

							# time
							__lowerCamelCase									=       FlaxTimesteps(
							    block_out_channels[0]     ,		flip_sin_to_cos=self.flip_sin_to_cos     ,		freq_shift=self.config.freq_shift				)
							__lowerCamelCase									=       FlaxTimestepEmbedding(lowerCamelCase__     ,		dtype=self.dtype				)

							__lowerCamelCase									=       FlaxControlNetConditioningEmbedding(
							    conditioning_embedding_channels=block_out_channels[0]     ,		block_out_channels=self.conditioning_embedding_out_channels     ,		)

							__lowerCamelCase									=       self.only_cross_attention
							if isinstance(lowerCamelCase__     ,		lowerCamelCase__				):
											__lowerCamelCase									=       (only_cross_attention,) * len(self.down_block_types				)

							if isinstance(lowerCamelCase__     ,		lowerCamelCase__				):
											__lowerCamelCase									=       (num_attention_heads,) * len(self.down_block_types				)

							# down
							__lowerCamelCase									=       []
							__lowerCamelCase									=       []

							__lowerCamelCase									=       block_out_channels[0]

							__lowerCamelCase									=       nn.Conv(
							    lowerCamelCase__     ,		kernel_size=(1, 1)     ,		padding='VALID'     ,		kernel_init=nn.initializers.zeros_init()     ,		bias_init=nn.initializers.zeros_init()     ,		dtype=self.dtype     ,		)
							controlnet_down_blocks.append(lowerCamelCase__				)

							for i, down_block_type in enumerate(self.down_block_types				):
											__lowerCamelCase									=       output_channel
											__lowerCamelCase									=       block_out_channels[i]
											__lowerCamelCase									=       i == len(lowerCamelCase__				) - 1

											if down_block_type == "CrossAttnDownBlock2D":
															__lowerCamelCase									=       FlaxCrossAttnDownBlockaD(
															    in_channels=lowerCamelCase__     ,		out_channels=lowerCamelCase__     ,		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]     ,		dtype=self.dtype     ,		)
											else:
															__lowerCamelCase									=       FlaxDownBlockaD(
															    in_channels=lowerCamelCase__     ,		out_channels=lowerCamelCase__     ,		dropout=self.dropout     ,		num_layers=self.layers_per_block     ,		add_downsample=not is_final_block     ,		dtype=self.dtype     ,		)

											down_blocks.append(lowerCamelCase__				)

											for _ in range(self.layers_per_block				):
															__lowerCamelCase									=       nn.Conv(
															    lowerCamelCase__     ,		kernel_size=(1, 1)     ,		padding='VALID'     ,		kernel_init=nn.initializers.zeros_init()     ,		bias_init=nn.initializers.zeros_init()     ,		dtype=self.dtype     ,		)
															controlnet_down_blocks.append(lowerCamelCase__				)

											if not is_final_block:
															__lowerCamelCase									=       nn.Conv(
															    lowerCamelCase__     ,		kernel_size=(1, 1)     ,		padding='VALID'     ,		kernel_init=nn.initializers.zeros_init()     ,		bias_init=nn.initializers.zeros_init()     ,		dtype=self.dtype     ,		)
															controlnet_down_blocks.append(lowerCamelCase__				)

							__lowerCamelCase									=       down_blocks
							__lowerCamelCase									=       controlnet_down_blocks

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

							__lowerCamelCase									=       nn.Conv(
							    lowerCamelCase__     ,		kernel_size=(1, 1)     ,		padding='VALID'     ,		kernel_init=nn.initializers.zeros_init()     ,		bias_init=nn.initializers.zeros_init()     ,		dtype=self.dtype     ,		)






			def __call__( self     ,		lowerCamelCase__     ,		lowerCamelCase__     ,		lowerCamelCase__     ,		lowerCamelCase__     ,		lowerCamelCase__ = 1.0     ,		lowerCamelCase__ = True     ,		lowerCamelCase__ = False     ,		)       -> Union[FlaxControlNetOutput, Tuple]:



							'''simple docstring'''
							__lowerCamelCase									=       self.controlnet_conditioning_channel_order
							if channel_order == "bgr":
											__lowerCamelCase									=       jnp.flip(lowerCamelCase__     ,		axis=1				)

							# 1. time
							if not isinstance(lowerCamelCase__     ,		jnp.ndarray				):
											__lowerCamelCase									=       jnp.array([timesteps]     ,		dtype=jnp.intaa				)
							elif isinstance(lowerCamelCase__     ,		jnp.ndarray				) and len(timesteps.shape				) == 0:
											__lowerCamelCase									=       timesteps.astype(dtype=jnp.floataa				)
											__lowerCamelCase									=       jnp.expand_dims(lowerCamelCase__     ,		0				)

							__lowerCamelCase									=       self.time_proj(lowerCamelCase__				)
							__lowerCamelCase									=       self.time_embedding(lowerCamelCase__				)

							# 2. pre-process
							__lowerCamelCase									=       jnp.transpose(lowerCamelCase__     ,		(0, 2, 3, 1)				)
							__lowerCamelCase									=       self.conv_in(lowerCamelCase__				)

							__lowerCamelCase									=       jnp.transpose(lowerCamelCase__     ,		(0, 2, 3, 1)				)
							__lowerCamelCase									=       self.controlnet_cond_embedding(lowerCamelCase__				)
							sample += controlnet_cond

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

							# 4. mid
							__lowerCamelCase									=       self.mid_block(lowerCamelCase__     ,		lowerCamelCase__     ,		lowerCamelCase__     ,		deterministic=not train				)

							# 5. contronet blocks
							__lowerCamelCase									=       ()
							for down_block_res_sample, controlnet_block in zip(lowerCamelCase__     ,		self.controlnet_down_blocks				):
											__lowerCamelCase									=       controlnet_block(lowerCamelCase__				)
											controlnet_down_block_res_samples += (down_block_res_sample,)

							__lowerCamelCase									=       controlnet_down_block_res_samples

							__lowerCamelCase									=       self.controlnet_mid_block(lowerCamelCase__				)

							# 6. scaling
							__lowerCamelCase									=       [sample * conditioning_scale for sample in down_block_res_samples]
							mid_block_res_sample *= conditioning_scale

							if not return_dict:
											return (down_block_res_samples, mid_block_res_sample)

							return FlaxControlNetOutput(
							    down_block_res_samples=lowerCamelCase__     ,		mid_block_res_sample=lowerCamelCase__				)








def      lowerCamelCase_						(			UpperCamelCase__							: str					,	UpperCamelCase__							: int )	->			list:





				"""simple docstring"""


				__lowerCamelCase									=       word.split()

				def justify(UpperCamelCase__							: list					,	UpperCamelCase__							: int					,	UpperCamelCase__							: int ) -> str:
								__lowerCamelCase									=       max_width - width
								__lowerCamelCase									=       len(UpperCamelCase__ )
								if len(UpperCamelCase__ ) == 1:
												# if there is only word in line
												# just insert overall_spaces_count for the remainder of line
												return line[0] + " " * overall_spaces_count
								else:
												__lowerCamelCase									=       words_count - 1
												# num_spaces_between_words_list[i] : tells you to insert
												# num_spaces_between_words_list[i] spaces
												# after word on line[i]
												__lowerCamelCase									=       spaces_to_insert_between_words * [
												    overall_spaces_count // spaces_to_insert_between_words
												]
												__lowerCamelCase									=       (
												    overall_spaces_count % spaces_to_insert_between_words
												)
												# distribute spaces via round robin to the left words
												for i in range(UpperCamelCase__ ):
																num_spaces_between_words_list[i] += 1
												__lowerCamelCase									=       []
												for i in range(UpperCamelCase__ ):
																# add the word
																aligned_words_list.append(line[i] )
																# add the spaces to insert
																aligned_words_list.append(num_spaces_between_words_list[i] * ' ' )
												# just add the last word to the sentence
												aligned_words_list.append(line[-1] )
												# join the aligned words list to form a justified line
												return "".join(UpperCamelCase__ )

				__lowerCamelCase									=       []
				__lowerCamelCase									=       []
				__lowerCamelCase									=       0
				for word in words:
								if width + len(UpperCamelCase__ ) + len(UpperCamelCase__ ) <= max_width:
												# keep adding words until we can fill out max_width
												# width = sum of length of all words (without overall_spaces_count)
												# len(word) = length of current word
												# len(line) = number of overall_spaces_count to insert between words
												line.append(UpperCamelCase__ )
												width += len(UpperCamelCase__ )
								else:
												# justify the line and add it to result
												answer.append(justify(UpperCamelCase__					,	UpperCamelCase__					,	UpperCamelCase__ ) )
												# reset new line and new width
												__lowerCamelCase			,		__lowerCamelCase									=       [word], len(UpperCamelCase__ )
				__lowerCamelCase									=       max_width - width - len(UpperCamelCase__ )
				answer.append(' '.join(UpperCamelCase__ ) + (remaining_spaces + 1) * ' ' )
				return answer


if __name__ == "__main__":
					from doctest import testmod

					testmod()


