
    +j                     >   d dl Z d dlmZ d dlmZ d dlmZmZmZ d dl	m
Z
mZmZmZmZmZmZmZmZmZ d dlmZmZmZmZmZmZmZmZmZmZmZ  G d dej                   Z! G d	 d
ej                   Z" G d de"          Z# G d dej                   Z$ G d dej                   Z% G d dej                   Z& G d dej                   Z' G d dej                   Z( G d de(          Z)dddZ*d Z+ G d dej                   Z, G d d e          Z-d!e-fd"Z.dS )#    N)	BaseModel)override)IOComfyExtensionInput)
BFLFluxEraseRequestBFLFluxExpandImageRequestBFLFluxFillImageRequest BFLFluxKontextProGenerateRequestBFLFluxProGenerateResponseBFLFluxProUltraGenerateRequestBFLFluxStatusResponseBFLFluxVTORequest	BFLStatusFlux2ProGenerateRequest)ApiEndpointconvert_mask_to_imagedownload_url_to_image_tensorget_number_of_imagespoll_opresize_mask_to_imagesync_optensor_to_base64_stringvalidate_aspect_ratio_stringvalidate_image_dimensionsvalidate_stringc                       e Zd Zedej        fd            Zedefd            Ze	 	 	 	 	 dd	eded
e	de	de
dej        dz  dedej        fd            ZdS )FluxProUltraImageNodereturnc                    t          j        ddddt           j                            dddd	          t           j                            d
ddd          t           j                            dddddd          t           j                            ddd          t           j                            ddd          t           j                            dd          t           j                            dddddd d!          gt           j                                        gt           j	        j
        t           j	        j        t           j	        j        gdt          j        d"#          $	  	        S )%Nr   zFlux 1.1 [pro] Ultra Imagepartner/image/BFLzQGenerates images using Flux Pro 1.1 Ultra via api based on prompt and resolution.promptT Prompt for the image generation	multilinedefaulttooltipprompt_upsamplingFWhether to perform upsampling on the prompt. If active, automatically modifies the prompt for more creative generation, but results are nondeterministic (same seed will not produce exactly the same result).r'   r(   advancedseedr       ,The random seed used for creating the noise.r'   minmaxcontrol_after_generater(   aspect_ratio16:93Aspect ratio of image; must be between 1:4 and 4:1.r'   r(   rawz@When True, generate less processed, more natural-looking images.image_promptoptionalimage_prompt_strength皙?g        g      ?g{Gz?z.Blend between the prompt and the image prompt.)r'   r1   r2   stepr(   r;   z{"type":"usd","usd":0.06}expr	node_iddisplay_namecategorydescriptioninputsoutputshiddenis_api_nodeprice_badge)r   SchemaStringr   BooleanIntImageFloatOutputHiddenauth_token_comfy_orgapi_key_comfy_org	unique_id
PriceBadgeclss    9/home/wildlama/comfy/ComfyUI/comfy_api_nodes/nodes_bfl.pydefine_schemaz#FluxProUltraImageNode.define_schema#   s   y+5(k	"=	     
  '!m " !   *+/J    	""Q    
 
  !^ !  
 "!    +L!   K.^ X__&&'	.	+	#
 4  w>
 >
 >
 >	
    r4   c                 (    t          |dd           dS )N      r_   r^   T)r   )rX   r4   s     rY   validate_inputsz%FluxProUltraImageNode.validate_inputse   s    $\66BBBtr[   Fr   Nr=   r"   r)   r8   r-   r9   r<   c                 2  K   |t          |d           t          | t          dd          t          t	          |||||||nt          |          |d nt          |d                               d {V }t          | t          |j                  t          d	 d
 t          j        gt          j        t          j        t          j        t          j        gg            d {V }	t!          j        t%          |	j        d                    d {V           S )NFstrip_whitespacez&/proxy/bfl/flux-pro-1.1-ultra/generatePOSTpathmethod   )r"   r)   r-   r4   r8   r9   r<   response_modeldatac                     | j         S Nstatusrs    rY   <lambda>z/FluxProUltraImageNode.execute.<locals>.<lambda>       qx r[   c                     | j         S rn   progressrq   s    rY   rs   z/FluxProUltraImageNode.execute.<locals>.<lambda>        r[   rk   status_extractorprogress_extractorcompleted_statusesfailed_statusesqueued_statusessample)r   r   r   r   r   r   roundr   polling_urlr   r   readyrequest_moderatedcontent_moderatederrortask_not_foundr   
NodeOutputr   result)
rX   r"   r4   r)   r8   r-   r9   r<   initial_responseresponses
             rY   executezFluxProUltraImageNode.executej   sm      FU;;;;!(EfUUU5/"3).:.BllH_`lHmHm/;/CttOdfgIhIh  	"
 "
 "
 
 
 
 
 
 
 !(4550//33 )0++(	 
 
 
 
 
 
 
 
 
 }#?PX@Y#Z#ZZZZZZZ[[[r[   )FFr   Nr=   )__name__
__module____qualname__classmethodr   rK   rZ   strra   boolintr   rO   floatr   r    r[   rY   r   r   !   s        ?
bi ?
 ?
 ?
 [?
B 3    [ 
 #(+/'*)\ )\)\ )\  	)\
 )\ )\ kD()\  %)\ 
)\ )\ )\ [)\ )\ )\r[   r   c                       e Zd Zedej        fd            ZdZd ZdZ	e	 	 	 dde
d	e
d
ededej        dz  dej        fd            ZdS )FluxKontextProImageNoder   c                    t          j        | j        | j        ddt           j                            dddd          t           j                            dd	d
          t           j                            dddddd          t           j                            ddddd          t           j                            dddddd          t           j                            ddd d!          t           j	                            d"d#          gt           j	        
                                gt           j        j        t           j        j        t           j        j        gd$          S )%Nr!   zQEdits images using Flux.1 Kontext [pro] via api based on prompt and aspect ratio.r"   Tr#   z?Prompt for the image generation - specify what and how to edit.r%   r4   r5   r6   r7   guidanceg      @r=   g     X@2Guidance strength for the image generation process)r'   r1   r2   r>   r(   steps2   r^      0Number of steps for the image generation processr'   r1   r2   r(   r-   i  r   r.   r/   r0   r)   Fr*   r+   input_imager:   )rB   rC   rD   rE   rF   rG   rH   rI   )r   rK   NODE_IDDISPLAY_NAMErL   r   rP   rN   rM   rO   rQ   rR   rS   rT   rU   rW   s    rY   rZ   z%FluxKontextProImageNode.define_schema   s}   yK)(k	"]	     	""Q    
 P    N     *+/J    
  '! m!	 !   !!   S-\ X__&&'	.	+	#
 s:
 :
 :
 :	
r[   z$/proxy/bfl/flux-kontext-pro/generatezFlux.1 Kontext [pro] ImageNr   Fr"   r4   r   r   r   c                 V  K   t          |dd           |t          |d           t          | t          | j        d          t
          t          ||t          |d          |||||nt          |                    	           d {V }t          | t          |j
                  t          d
 d t          j        gt          j        t          j        t          j        t          j        gg            d {V }	t%          j        t)          |	j        d                    d {V           S )Nr]   r`   Frc   re   rf   r^   )r"   r)   r   r   r-   r4   r   rj   c                     | j         S rn   ro   rq   s    rY   rs   z1FluxKontextProImageNode.execute.<locals>.<lambda>   rt   r[   c                     | j         S rn   rv   rq   s    rY   rs   z1FluxKontextProImageNode.execute.<locals>.<lambda>   rx   r[   ry   r   )r   r   r   r   BFL_PATHr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )
rX   r"   r4   r   r   r   r-   r)   r   r   s
             rY   r   zFluxKontextProImageNode.execute   su      	%\66BBBFU;;;;!(S\&99951"3x++),7,?[[E\]hEiEi  	"
 "
 "
 
 
 
 
 
 
 !(4550//33 )0++(	 
 
 
 
 
 
 
 
 
 }#?PX@Y#Z#ZZZZZZZ[[[r[   )Nr   F)r   r   r   r   r   rK   rZ   r   r   r   r   r   r   r   rO   r   r   r   r[   rY   r   r      s        ;
bi ;
 ;
 ;
 [;
z 6H'G/L +/*\ *\*\ *\ 	*\
 *\ [4'*\ 
*\ *\ *\ [*\ *\ *\r[   r   c                       e Zd ZdZdZd ZdZdS )FluxKontextMaxImageNodezQEdits images using Flux.1 Kontext [max] via api based on prompt and aspect ratio.z$/proxy/bfl/flux-kontext-max/generatezFlux.1 Kontext [max] ImageN)r   r   r   DESCRIPTIONr   r   r   r   r[   rY   r   r   	  s"        eK5H'G/LLLr[   r   c                       e Zd Zedej        fd            Ze	 ddej        de	de
deded	ed
edededej        fd            ZdS )FluxProExpandNoder   c                    t          j        ddddt           j                            d          t           j                            dddd	
          t           j                            dddd          t           j                            ddddd          t           j                            ddddd          t           j                            ddddd          t           j                            ddddd          t           j                            ddddd          t           j                            dd d!d d"          t           j                            d#ddd$dd%&          g
t           j                                        gt           j	        j
        t           j	        j        t           j	        j        gdt          j        d'(          )	  	        S )*Nr   zFlux.1 Expand Imager!   z Outpaints image based on prompt.imager"   Tr#   r$   r%   r)   Fr*   r+   topr      z2Number of pixels to expand at the top of the imager   bottomz5Number of pixels to expand at the bottom of the imageleftz3Number of pixels to expand at the left of the imagerightz4Number of pixels to expand at the right of the imager   <         ?d   r   r   r      r   r-   r.   r/   r0   {"type":"usd","usd":0.05}r?   rA   )r   rK   rO   r   rL   rM   rN   rP   rQ   rR   rS   rT   rU   rV   rW   s    rY   rZ   zFluxProExpandNode.define_schema  s   y'.(:w''	"=	     
  '!m " !   P    S    Q    R    P    N    *+/J   uBF X__&&'	.	+	#
 4  _R
 R
 R
 R	
r[   r   r   r"   r)   r   r   r   r   r   r   c                   K   t          | t          dd          t          t          ||||||||	|
t	          |          
  
                   d {V }t          | t          |j                  t          d d t          j	        gt          j
        t          j        t          j        t          j        gg            d {V }t          j        t!          |j        d	                    d {V           S )
Nz'/proxy/bfl/flux-pro-1.0-expand/generatere   rf   )
r"   r)   r   r   r   r   r   r   r-   r   rj   c                     | j         S rn   ro   rq   s    rY   rs   z+FluxProExpandNode.execute.<locals>.<lambda>  rt   r[   c                     | j         S rn   rv   rq   s    rY   rs   z+FluxProExpandNode.execute.<locals>.<lambda>  rx   r[   ry   r   )r   r   r   r	   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )rX   r   r"   r)   r   r   r   r   r   r   r-   r   r   s                rY   r   zFluxProExpandNode.executei  s=      ")FvVVV5*"3!-e44  	"
 "
 "
 
 
 
 
 
 
" !(4550//33 )0++(	 
 
 
 
 
 
 
 
 
 }#?PX@Y#Z#ZZZZZZZ[[[r[   Nr   r   r   r   r   r   rK   rZ   r   rO   r   r   r   r   r   r   r   r[   rY   r   r     s        S
bi S
 S
 S
 [S
j  -\ -\{-\ -\  	-\
 -\ -\ -\ -\ -\ -\ 
-\ -\ -\ [-\ -\ -\r[   r   c                       e Zd Zedej        fd            Ze	 ddej        dej        de	de
ded	edej        fd
            ZdS )FluxProFillNoder   c                    t          j        ddddt           j                            d          t           j                            d          t           j                            ddd	d
          t           j                            dddd          t           j                            ddddd          t           j                            ddddd          t           j                            dddddd          gt           j        	                                gt           j
        j        t           j
        j        t           j
        j        gdt          j        d           !	  	        S )"Nr   zFlux.1 Fill Imager!   z(Inpaints image based on mask and prompt.r   maskr"   Tr#   r$   r%   r)   Fr*   r+   r   r   r   r   r   r   r   r   r   r   r-   r   r.   r/   r0   r   r?   rA   )r   rK   rO   r   MaskrL   rM   rP   rN   rQ   rR   rS   rT   rU   rV   rW   s    rY   rZ   zFluxProFillNode.define_schema  sl   y%,(Bw''f%%	"=	     
  '!m " !   P    N    *+/J   ?'P X__&&'	.	+	#
 4  i7
 7
 7
 7	
r[   r   r   r   r"   r)   r   r   c                 \  K   t          ||          }t          t          |                    }t          | t	          dd          t
          t          |||||t          |d d d d d d d df                   |                     d {V }t          | t	          |j                  t          d d t          j        gt          j        t          j        t          j        t          j        gg 	           d {V }	t!          j        t%          |	j        d
                    d {V           S )Nz%/proxy/bfl/flux-pro-1.0-fill/generatere   rf      )r"   r)   r   r   r-   r   r   rj   c                     | j         S rn   ro   rq   s    rY   rs   z)FluxProFillNode.execute.<locals>.<lambda>  rt   r[   c                     | j         S rn   rv   rq   s    rY   rs   z)FluxProFillNode.execute.<locals>.<lambda>  rx   r[   ry   r   )r   r   r   r   r   r   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   )
rX   r   r   r"   r)   r   r   r-   r   r   s
             rY   r   zFluxProFillNode.execute  sv      $D%00&'<T'B'BCC!(DVTTT5("3!-eAAAqqq!!!RaRK.@AA  	"
 "
 "
 
 
 
 
 
 
 !(4550//33 )0++(	 
 
 
 
 
 
 
 
 
 }#?PX@Y#Z#ZZZZZZZ[[[r[   Nr   r   r   r[   rY   r   r     s        8
bi 8
 8
 8
 [8
t  *\ *\{*\ k*\ 	*\
  *\ *\ *\ 
*\ *\ *\ [*\ *\ *\r[   r   c                       e Zd Zedej        fd            Ze	 	 ddej        dej        de	de	dej
        f
d	            Zd
S )FluxEraseNoder   c                    t          j        ddddt           j                            d          t           j                            dd          t           j                            d	d
ddd          t           j                            ddddddd          gt           j                                        gt           j        j        t           j        j	        t           j        j
        gdt          j        d          	  	        S )Nr   zFlux Erase Imager!   ztRemoves the masked object from an image and reconstructs the background. Paint the mask over what you want to erase.r   r   z3White areas are removed; black areas are preserved.r(   dilate_pixels
   r      zKExpands the mask boundaries to ensure clean coverage of the object's edges.r   r-   iTr/   )r'   r1   r2   r3   r(   r;   zP{"type":"range_usd","min_usd":0.03,"max_usd":0.06,"format":{"approximate":true}}r?   rA   )r   rK   rO   r   r   rN   rQ   rR   rS   rT   rU   rV   rW   s    rY   rZ   zFluxEraseNode.define_schema  s    y#+(: w''f.cdd#i    "+/J!   ( X__&&'	.	+	#
 k  C$
 $
 $
 $	
r[   r   r   r   r   r   r-   c                   K   t          |dd           t          ||          }t          t          |                    }t	          | t          dd          t          t          t          |d d d d d d d df                   |||                     d {V d	t          d
t          d z  ffd}t          | t          j                  t          d d |t          j        gt          j        t          j        t          j        t          j        gg 	  	         d {V }t'          j        t+          |j        d                    d {V           S )N   )	min_width
min_heightz!/proxy/bfl/v1/flux-tools/erase-v1re   rf   r   )r   r   r   r-   rj   _rr   c                 *    j         d n	j         dz  S Nr   costr   r   s    rY   price_extractorz.FluxEraseNode.execute.<locals>.price_extractorF      +0844>N>SVY>YYr[   c                     | j         S rn   ro   rq   s    rY   rs   z'FluxEraseNode.execute.<locals>.<lambda>M  rt   r[   c                     | j         S rn   rv   rq   s    rY   rs   z'FluxEraseNode.execute.<locals>.<lambda>N  rx   r[   rk   rz   r{   r   r|   r}   r~   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )rX   r   r   r   r-   r   r   r   s          @rY   r   zFluxEraseNode.execute/  s      	"%33GGGG#D%00&'<T'B'BCC!(@PPP5$-eAAAqqq!!!RaRK.@AA+	  	
"
 
"
 
"
 

 

 

 

 

 

	Z	 	Zedl 	Z 	Z 	Z 	Z 	Z 	Z !(4550//33+ )0++(	 
 
 
 
 
 
 
 
 
  }#?PX@Y#Z#ZZZZZZZ[[[r[   N)r   r   )r   r   r   r   r   rK   rZ   r   rO   r   r   r   r   r[   rY   r   r     s        %
bi %
 %
 %
 [%
N 
  )\ )\{)\ k)\ 	)\
 )\ 
)\ )\ )\ [)\ )\ )\r[   r   c                       e Zd Zedej        fd            Ze	 	 ddej        dej        de	de
dej        f
d	            Zd
S )FluxVTONoder   c                    t          j        ddddt           j                            dd          t           j                            dd	          t           j                            d
ddd          t           j                            dddddd          gt           j                                        gt           j        j        t           j        j	        t           j        j
        gdt          j        d          	  	        S )Nr   zFlux Virtual Try-Onr!   z;Virtual try-on: dresses the person in the provided garment.personzImage of the person to dress.r   garmentzImage of the garment to apply.r"   Tr#   zPOptional natural-language styling instruction (e.g. how the garment should fit).r%   r-   r   r.   r/   r0   zS{"type":"range_usd","min_usd":0.0375,"max_usd":0.075,"format":{"approximate":true}}r?   rA   )r   rK   rO   r   rL   rN   rQ   rR   rS   rT   rU   rV   rW   s    rY   rZ   zFluxVTONode.define_schema^  s    y!.(Ux1PQQy2RSS	"n	     *+/J   $ X__&&'	.	+	#
 n  =!
 !
 !
 !	
r[   r#   r   r   r   r"   r-   c                 n  K   t          | t          dd          t          t          |t	          |d d d d d d d df                   t	          |d d d d d d d df                   |                     d {V dt
          dt          d z  ffd	}t          | t          j                  t          d
 d |t          j        gt          j        t          j        t          j        t          j        gg 	  	         d {V }t!          j        t%          |j        d                    d {V           S )Nz/proxy/bfl/v1/flux-tools/vto-v1re   rf   r   )r"   r   r   r-   rj   r   r   c                 *    j         d n	j         dz  S r   r   r   s    rY   r   z,FluxVTONode.execute.<locals>.price_extractor  r   r[   c                     | j         S rn   ro   rq   s    rY   rs   z%FluxVTONode.execute.<locals>.<lambda>  rt   r[   c                     | j         S rn   rv   rq   s    rY   rs   z%FluxVTONode.execute.<locals>.<lambda>  rx   r[   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )rX   r   r   r"   r-   r   r   r   s          @rY   r   zFluxVTONode.execute  s      ")>vNNN5".vaaaAAArrk/BCC/111aaa!0DEE	  	
"
 
"
 
"
 

 

 

 

 

 

	Z	 	Zedl 	Z 	Z 	Z 	Z 	Z 	Z !(4550//33+ )0++(	 
 
 
 
 
 
 
 
 
  }#?PX@Y#Z#ZZZZZZZ[[[r[   N)r#   r   )r   r   r   r   r   rK   rZ   r   rO   r   r   r   r   r   r[   rY   r   r   \  s        "
bi "
 "
 "
 ["
H 
 &\ &\&\ &\ 	&\
 &\ 
&\ &\ &\ [&\ &\ &\r[   r   c                       e Zd Zd ZdZdZdZedej	        fd            Z
e	 ddeded	ed
ededej        dz  dej        fd            ZdS )Flux2ProImageNodezFlux.2 [pro] Image/proxy/bfl/flux-2-pro/generatea  
    (
      $MP := 1024 * 1024;
      $outMP := $max([1, $floor(((widgets.width * widgets.height) + $MP - 1) / $MP)]);
      $outputCost := 0.03 + 0.015 * ($outMP - 1);
      inputs.images.connected
        ? {
            "type":"range_usd",
            "min_usd": $outputCost + 0.015,
            "max_usd": $outputCost + 0.12,
            "format": { "approximate": true }
          }
        : {"type":"usd","usd": $outputCost}
    )
    r   c                    t          j        | j        | j        ddt           j                            dddd          t           j                            dd	d
dd          t           j                            ddd
dd          t           j                            dddddd          t           j                            dddd          t           j                            ddd          gt           j        	                                gt           j
        j        t           j
        j        t           j
        j        gdt          j        t          j        ddgdg          | j                  d
  
        S )Nr!   z>Generates images synchronously based on prompt and resolution.r"   Tr#   'Prompt for the image generation or editr%   width   r   r       r'   r1   r2   r>   height   r-   r   r.   r/   r0   r)   zwWhether to perform upsampling on the prompt. If active, automatically modifies the prompt for more creative generation.r+   imagesz(Up to 9 images to be used as references.)r;   r(   )widgetsrF   
depends_onr@   )
rB   rC   rD   rE   rF   rG   rH   rI   rJ   is_deprecated)r   rK   r   r   rL   r   rN   rM   rO   rQ   rR   rS   rT   rU   rV   PriceBadgeDependsPRICE_BADGE_EXPRrW   s    rY   rZ   zFlux2ProImageNode.define_schema  s   yK)(X	"E	              *+/J    
  ' a! !   x$@jkkI%L X__&&'	.	+	#
 /(8KU]T^___)   m7
 7
 7
 7	
r[   Nr"   r   r   r-   r)   r   c                   K   i }|et          |          dk    rt          d          t          |j        d                   D ](}|rd|dz    nd}	t	          ||         d          ||	<   )t          | t          | j        d	
          t          t          d|||||d|           d {V dt          dt          d z  ffd}
t          | t          j                  t          d d |
t          j        gt          j        t          j        t          j        t          j        gg 	  	         d {V }t+          j        t/          |j        d                    d {V           S )N	   z4The current maximum number of supported images is 9.r   input_image_r^   r     @ total_pixelsre   rf   )r"   r   r   r-   r)   rj   r   r   c                 *    j         d n	j         dz  S r   r   r   s    rY   r   z2Flux2ProImageNode.execute.<locals>.price_extractor  r   r[   c                     | j         S rn   ro   rq   s    rY   rs   z+Flux2ProImageNode.execute.<locals>.<lambda>#  rt   r[   c                     | j         S rn   rv   rq   s    rY   rs   z+Flux2ProImageNode.execute.<locals>.<lambda>$  rx   r[   r   r   r   )r   
ValueErrorrangeshaper   r   r   API_ENDPOINTr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )rX   r"   r   r   r-   r)   r   reference_imagesimage_indexkey_namer   r   r   s               @rY   r   zFlux2ProImageNode.execute  s      #F++a// !WXXX$V\!_55 t t?J];+/;;;P]-DVKEXgr-s-s-s **!(S-f===5( "3  # 	"
 "
 "
 
 
 
 
 
 
	Z	 	Zedl 	Z 	Z 	Z 	Z 	Z 	Z !(4550//33+ )0++(	 
 
 
 
 
 
 
 
 
  }#?PX@Y#Z#ZZZZZZZ[[[r[   rn   )r   r   r   r   r   r  r   r   r   rK   rZ   r   r   r   r   rO   r   r   r   r[   rY   r   r     s        !G'L3L  8
bi 8
 8
 8
 [8
t  &*1\ 1\1\ 1\ 	1\
 1\  1\ d"1\ 
1\ 1\ 1\ [1\ 1\ 1\r[   r   c                       e Zd Zd ZdZdZdZdS )Flux2MaxImageNodezFlux.2 [max] Image/proxy/bfl/flux-2-max/generatea  
    (
      $MP := 1024 * 1024;
      $outMP := $max([1, $floor(((widgets.width * widgets.height) + $MP - 1) / $MP)]);
      $outputCost := 0.07 + 0.03 * ($outMP - 1);

      inputs.images.connected
        ? {
            "type":"range_usd",
            "min_usd": $outputCost + 0.03,
            "max_usd": $outputCost + 0.24,
            "format": { "approximate": true }
          }
        : {"type":"usd","usd": $outputCost}
    )
    N)r   r   r   r   r   r  r   r   r[   rY   r  r  2  s'        !G'L3Lr[   r  r   r  )Flux.2 [pro]Flux.2 [max]c                  ~   t           j                            ddddd          t           j                            ddddd          t           j                            d	t           j                            t           j                            d
          d t          dd          D             d          d          gS )Nr   r   r   r   r   r   r   r   r   r   c                     g | ]}d | S )image_r   ).0is     rY   
<listcomp>z'_flux2_model_inputs.<locals>.<listcomp>c  s    999|||999r[   r^   r   r   )namesr1   zJOptional reference image(s) for image-to-image generation. Up to 8 images.)templater(   )r   rN   r   AutogrowTemplateNamesrO   r   r   r[   rY   _flux2_model_inputsr  O  s    
 	 	
 	
 	 	 	
 	
 	[..w''99U1a[[999 /  
 a 	 	
 	
 r[   c            	       f    e Zd Zedej        fd            Zededede	dej
        fd            ZdS )Flux2ImageNoder   c                    t          j        ddddt           j                            dddd	          t           j                            d
t           j                            dt                                t           j                            dt                                g          t           j                            dddddd          gt           j        	                                gt           j
        j        t           j
        j        t           j
        j        gdt          j        t          j        g ddg          d          	  	        S )Nr  zFlux.2 Imager!   z]Generate images via Flux.2 [pro] or Flux.2 [max] from a prompt and optional reference images.r"   Tr#   r   r%   modelr	  r
  )optionsr-   r   r.   r/   r0   )r  zmodel.widthzmodel.heightzmodel.images)r   input_groupsa  
                (
                  $isMax := widgets.model = "flux.2 [max]";
                  $MP := 1024 * 1024;
                  $w := $lookup(widgets, "model.width");
                  $h := $lookup(widgets, "model.height");
                  $outMP := $max([1, $floor((($w * $h) + $MP - 1) / $MP)]);
                  $outputCost := $isMax
                    ? (0.07 + 0.03 * ($outMP - 1))
                    : (0.03 + 0.015 * ($outMP - 1));
                  $refMin := $isMax ? 0.03 : 0.015;
                  $refMax := $isMax ? 0.24 : 0.12;
                  $hasRefs := $lookup(inputGroups, "model.images") > 0;
                  $hasRefs
                    ? {
                        "type": "range_usd",
                        "min_usd": $outputCost + $refMin,
                        "max_usd": $outputCost + $refMax,
                        "format": { "approximate": true }
                      }
                    : {"type": "usd", "usd": $outputCost}
                )
                r   rA   )r   rK   rL   r   DynamicComboOptionr  rN   rO   rQ   rR   rS   rT   rU   rV   r   rW   s    rY   rZ   zFlux2ImageNode.define_schemam  sP   y$'(w	"E	     %%..~?R?T?TUU..~?R?T?TUU &   *+/J   . X__&&'	.	+	#
 /DDD"0!1    G@
 @
 @
 @	
r[   r"   r  r-   c                 J  K   |d         }t           |         }|d         }|d         }|                    d          pi }d |                                D             }	t          d |	D                       }
|
dk    rt	          d          g }|	D ]it          j                  d	k    r:|                    fd
t          j        d                   D                        T|	                               ji }t          |          D ]%\  }|rd|dz    nd}t          d          ||<   &t          | t          |d          t          t          d||||d|           d {V dt           dt"          d z  ffd}t%          | t          j                  t(          d d |t*          j        gt*          j        t*          j        t*          j        t*          j        gg 	  	         d {V }t7          j        t;          |j        d                    d {V           S )Nr  r   r   r   c                     g | ]}||S rn   r   r  ts     rY   r  z*Flux2ImageNode.execute.<locals>.<listcomp>  s    +]+]+]!q}A}}}r[   c              3   4   K   | ]}t          |          V  d S rn   )r   r   s     rY   	<genexpr>z)Flux2ImageNode.execute.<locals>.<genexpr>  s+      FF1+A..FFFFFFr[      z4The current maximum number of supported images is 8.r_   c              3   (   K   | ]}|         V  d S rn   r   )r  r  tensors     rY   r#  z)Flux2ImageNode.execute.<locals>.<genexpr>  s'      #N#N!F1I#N#N#N#N#N#Nr[   r   r   r^   r   r   r   re   rf   )r"   r   r   r-   rj   r   r   c                 *    j         d n	j         dz  S r   r   r   s    rY   r   z/Flux2ImageNode.execute.<locals>.price_extractor  r   r[   c                     | j         S rn   ro   rq   s    rY   rs   z(Flux2ImageNode.execute.<locals>.<lambda>  rt   r[   c                     | j         S rn   rv   rq   s    rY   rs   z(Flux2ImageNode.execute.<locals>.<lambda>  rx   r[   r   r   r   )_FLUX2_MODEL_ENDPOINTSgetvaluessumr   lenr  extendr   append	enumerater   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )rX   r"   r  r-   model_choiceendpointr   r   images_dictimage_tensorsn_imagesflat_tensorsr  idxr  r   r   r   r&  s                    @@rY   r   zFlux2ImageNode.execute  s      W~),7gxii))/R+]+]{7I7I7K7K+]+]+]FFFFFFFa<<STTT+-# 	, 	,F6<  A%%###N#N#N#NuV\!_7M7M#N#N#NNNNN##F+++++-$\22 	c 	cKC36I/cAg///MH)@Va)b)b)bX&&!(Xf5555( 	 
 # 	"
 "
 "
 
 
 
 
 
 
	Z	 	Zedl 	Z 	Z 	Z 	Z 	Z 	Z !(4550//33+ )0++(	 
 
 
 
 
 
 
 
 
  }#?PX@Y#Z#ZZZZZZZ[[[r[   N)r   r   r   r   r   rK   rZ   r   dictr   r   r   r   r[   rY   r  r  k  s        A
bi A
 A
 A
 [A
F =\=\ =\ 	=\
 
=\ =\ =\ [=\ =\ =\r[   r  c                   L    e Zd Zedeeej                          fd            ZdS )BFLExtensionr   c           
         K   t           t          t          t          t          t
          t          t          t          t          g
S rn   )
r   r   r   r   r   r   r   r   r  r  )selfs    rY   get_node_listzBFLExtension.get_node_list  s0       "##
 	
r[   N)	r   r   r   r   listtyper   	ComfyNoder>  r   r[   rY   r;  r;    sE        
T$r|*<%= 
 
 
 X
 
 
r[   r;  r   c                  "   K   t                      S rn   )r;  r   r[   rY   comfy_entrypointrC    s      >>r[   )/torchpydanticr   typing_extensionsr   comfy_api.latestr   r   r   comfy_api_nodes.apis.bflr   r	   r
   r   r   r   r   r   r   r   comfy_api_nodes.utilr   r   r   r   r   r   r   r   r   r   r   rA  r   r   r   r   r   r   r   r   r  r*  r  r  r;  rC  r   r[   rY   <module>rJ     s          & & & & & & 6 6 6 6 6 6 6 6 6 6                                                s\ s\ s\ s\ s\BL s\ s\ s\lo\ o\ o\ o\ o\bl o\ o\ o\d0 0 0 0 05 0 0 0F\ F\ F\ F\ F\ F\ F\ F\Rh\ h\ h\ h\ h\bl h\ h\ h\VT\ T\ T\ T\ T\BL T\ T\ T\nN\ N\ N\ N\ N\", N\ N\ N\bB\ B\ B\ B\ B\ B\ B\ B\J    )   0 54    8D\ D\ D\ D\ D\R\ D\ D\ D\N
 
 
 
 
> 
 
 
"      r[   