o
    iH                     @   s  d dl mZ d dlZd dlZd dlmZ d dlmZ d dlm	Z	 d dl
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mZmZmZ d dlmZmZmZm Z m!Z!m"Z"m#Z# d d	l$m%Z% 		
		dIde&ej' dej(de)dej(dB de*de*de+e fddZ,					dJde&e- dB de+e+ dB de.de)de/ej0B f
ddZ1G dd dZ2G dd  d ej'Z3G d!d" d"ej'Z4G d#d$ d$ej'Z5G d%d& d&e5Z6G d'd( d(e5Z7G d)d* d*e5Z8G d+d, d,ej'Z9G d-d. d.ej'Z:G d/d0 d0ej'Z;G d1d2 d2ej'Z<G d3d4 d4ej'Z=G d5d6 d6ej'Z>G d7d8 d8ej'Z?G d9d: d:ej'Z@G d;d< d<ej'ZAG d=d> d>ej'ZBG d?d@ d@eBZCG dAdB dBej'ZDG dCdD dDej'ZEG dEdF dFeZFdeFfdGdHZGdS )K    )BytesION)UnidentifiedImageError)override)ProgressBar)IOComfyExtension)RECRAFT_V4_PRO_SIZESRECRAFT_V4_SIZESRecraftColorRecraftColorChainRecraftControlsRecraftCreateStyleRequestRecraftCreateStyleResponseRecraftImageGenerationRequestRecraftImageGenerationResponseRecraftImageSize	RecraftIORecraftStyleRecraftStyleV3get_v3_substyles)ApiEndpointbytesio_to_image_tensordownload_url_as_bytesioresize_mask_to_imagesync_optensor_to_bytesiovalidate_string)SVG      clsimagepathmasktotal_pixelstimeoutreturnc              
      s   dt ||d i}|durt ||d |d< t| t|ddt|r%|nd|dtdd	I dH }g }	|jdurG|	t|jj	|d
I dH  |	S |j
D ]}
|	t|
j	|d
I dH  qJ|	S )zGHandle sending common Recraft file-only request to get back file bytes.r!   )r$   Nr#   POSTr"   methodmultipart/form-data   )endpointresponse_modeldatafilescontent_typemultipart_parsermax_retriesr%   )r   readr   r   r   recraft_multipart_parserr!   appendr   urlr.   )r    r!   r"   r#   r$   r%   requestr/   responseall_bytesior.    r;   ;/mnt/c/Users/fbmor/ComfyUI/comfy_api_nodes/nodes_recraft.pyhandle_recraft_file_request&   s*   




r=   Fformdata	formatterconverted_to_checkis_listreturn_modec                    s  t t  f fdd	}|du rg }|du r|nd} du r dd  t| ts>|| ||}|r/i S |r8| | giS | | iS g }	|	g}
|
| |  D ]O\}}|du rV|n| d| d}t|trp|	t|| |
  qLt|t rt|D ]\}}| d	}|	t|| |
d
d  qyqL|	| |f qL|dkrt	 }t|	 D ]\}}t|t r|D ]
}|
|t| qq|
|t| q|S t|	S )a  
    Formats data such that multipart/form-data will work with aiohttp library when both files and data are present.

    The OpenAI client that Recraft uses has a bizarre way of serializing lists:

    It does NOT keep track of indeces of each list, so for background_color, that must be serialized as:
        'background_color[rgb][]' = [0, 0, 255]
    where the array is assigned to a key that has '[]' at the end, to signal it's an array.

    This has the consequence of nested lists having the exact same key, forcing arrays to merge; all colors inputs fall under the same key:
        if 1 color  -> 'controls[colors][][rgb][]' = [0, 0, 255]
        if 2 colors -> 'controls[colors][][rgb][]' = [0, 0, 255, 255, 0, 0]
        if 3 colors -> 'controls[colors][][rgb][]' = [0, 0, 255, 255, 0, 0, 0, 255, 0]
        etc.
    Whoever made this serialization up at OpenAI added the constraint that lists must be of uniform length on objects of same 'type'.
    c                    sL   |D ]!}|D ]}|d |kr"t |d tr"|d  |    dS qqdS )Nr   r+   TF)
isinstancelistr6   )item
parent_keylists_to_check
check_list
conv_tupler?   r;   r<   handle_converted_listsd   s   z8recraft_multipart_parser.<locals>.handle_converted_listsNdictc                 S   s   | S Nr;   )vr;   r;   r<   <lambda>r   s    z*recraft_multipart_parser.<locals>.<lambda>[]z[]T)rA   r>   )rD   rC   rL   extenditemsr5   	enumerater6   aiohttpFormData	add_fieldstr)r.   rF   r?   r@   rA   rB   rK   effective_modeadded	converted
next_checkkeyvaluecurrent_keyind
list_valueiter_keyfdkrN   rE   r;   rJ   r<   r5   I   sL   	





r5   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	handle_recraft_image_outputz|
    Catch an exception related to receiving SVG data instead of image, when Infinite Style Library style_id is in use.
    c                 C      d S rM   r;   selfr;   r;   r<   __init__      z$handle_recraft_image_output.__init__c                 C   rf   rM   r;   rg   r;   r;   r<   	__enter__   rj   z%handle_recraft_image_output.__enter__c                 C   s    |d ur|t u rtdd S d S )NzsReceived output data was not an image; likely an SVG. If you used style_id, make sure it is not a Vector art style.)r   	Exception)rh   exc_typeexc_valexc_tbr;   r;   r<   __exit__   s
   z$handle_recraft_image_output.__exit__N)__name__
__module____qualname____doc__ri   rk   rp   r;   r;   r;   r<   re      s
    re   c                   @   s>   e Zd Zedd Zeddededededejf
d	d
Z	dS )RecraftColorRGBNodec                 C   sx   t jddddt jjdddddd	t jjd
ddddd	t jjdddddd	t tjjdddgt tjjddgdS )NRecraftColorRGBzRecraft Color RGBapi node/image/Recraftz5Create Recraft Color by choosing specific RGB values.rr      zRed value of color.defaultminmaxtooltipgzGreen value of color.bzBlue value of color.recraft_colorToptionaldisplay_namenode_idr   categorydescriptioninputsoutputs)r   SchemaIntInputCustomr   COLOROutputr    r;   r;   r<   define_schema   s   z!RecraftColorRGBNode.define_schemaNrx   r   r   r   r&   c                 C   s.   |r|  nt }|t||| t|S rM   )cloner   addr
   r   
NodeOutput)r    rx   r   r   r   r;   r;   r<   execute   s   
zRecraftColorRGBNode.executerM   )
rq   rr   rs   classmethodr   intr   r   r   r   r;   r;   r;   r<   ru      s
    
(ru   c                   @   s6   e Zd Zedd Zed	dededejfddZdS )
RecraftControlsNodec              
   C   sP   t jddddt tjjdddt tjjdddgt tjjd	d
gdS )Nr   zRecraft Controlsrw   z;Create Recraft Controls for customizing Recraft generation.colorsTr   background_colorrecraft_controlsr   r   )r   r   r   r   r   r   CONTROLSr   r   r;   r;   r<   r      s   z!RecraftControlsNode.define_schemaNr   r   r&   c                 C   s   t t||dS )N)r   r   )r   r   r   )r    r   r   r;   r;   r<   r      s   zRecraftControlsNode.executeNN)	rq   rr   rs   r   r   r   r   r   r   r;   r;   r;   r<   r      s
    
 r   c                   @   s6   e Zd ZejZedd Zedede	j
fddZdS ) RecraftStyleV3RealisticImageNodec              	   C   <   t jddddt jjdt| jdgt tjj	ddgd	S )
NRecraftStyleV3RealisticImageRecraft Style - Realistic Imagerw   3Select realistic_image style and optional substyle.substyleoptionsrecraft_styler   r   
r   r   Combor   r   RECRAFT_STYLEr   r   STYLEV3r   r   r;   r;   r<   r         z.RecraftStyleV3RealisticImageNode.define_schemar   r&   c                 C   s   |dkrd }t t| j|S )NNone)r   r   r   r   )r    r   r;   r;   r<   r      s   z(RecraftStyleV3RealisticImageNode.executeN)rq   rr   rs   r   realistic_imager   r   r   rX   r   r   r   r;   r;   r;   r<   r      s    
r   c                   @      e Zd ZejZedd ZdS )%RecraftStyleV3DigitalIllustrationNodec              	   C   r   )
N!RecraftStyleV3DigitalIllustrationz$Recraft Style - Digital Illustrationrw   r   r   r   r   r   r   r   r   r;   r;   r<   r      r   z3RecraftStyleV3DigitalIllustrationNode.define_schemaN)rq   rr   rs   r   digital_illustrationr   r   r   r;   r;   r;   r<   r          r   c                   @   r   )$RecraftStyleV3VectorIllustrationNodec              	   C   r   )
Nr   r   rw   r   r   r   r   r   r   r   r   r;   r;   r<   r     r   z2RecraftStyleV3VectorIllustrationNode.define_schemaN)rq   rr   rs   r   vector_illustrationr   r   r   r;   r;   r;   r<   r     r   r   c                   @   r   )RecraftStyleV3LogoRasterNodec                 C   s@   t jddddt jjdt| jdddgt tjj	d	d
gdS )NRecraftStyleV3LogoRasterzRecraft Style - Logo Rasterrw   r   r   F)include_noner   r   r   r   r   r   r;   r;   r<   r   !  s   z*RecraftStyleV3LogoRasterNode.define_schemaN)rq   rr   rs   r   logo_rasterr   r   r   r;   r;   r;   r<   r     r   r   c                   @   s0   e Zd Zedd ZededejfddZdS ) RecraftStyleInfiniteStyleLibraryc              
   C   s8   t jddddt jjddddgt tjjd	d
gdS )N"RecraftStyleV3InfiniteStyleLibraryz&Recraft Style - Infinite Style Libraryrw   zMChoose style based on preexisting UUID from Recraft's Infinite Style Library.style_id z*UUID of style from Infinite Style Library.)r{   r~   r   r   r   )r   r   Stringr   r   r   r   r   r   r;   r;   r<   r   2  s   z.RecraftStyleInfiniteStyleLibrary.define_schemar   r&   c                 C   s   |st dtt|dS )Nz#The style_id input cannot be empty.)r   )rl   r   r   r   )r    r   r;   r;   r<   r   A  s   z(RecraftStyleInfiniteStyleLibrary.executeN)	rq   rr   rs   r   r   rX   r   r   r   r;   r;   r;   r<   r   1  s
    
r   c                   @   s8   e Zd Zedd Zededejjdej	fddZ
dS )	RecraftCreateStyleNodec                 C   s|   t jddddt jjdddgdd	t jjd
t jjt jddddddgt jjddgt j	j
t j	jt j	jgdt jddd	S )Nr   zRecraft Create Stylerw   zCreate a custom style from reference images. Upload 1-5 images to use as style references. Total size of all images is limited to 5 MB.styler   r   z'The base style of the generated images.r   r~   imagesr!   r+      )prefixr|   r}   )templater   r   Tz{"type":"usd","usd": 0.04}expr	r   r   r   r   r   r   hiddenis_api_nodeprice_badge)r   r   r   r   AutogrowTemplatePrefixImager   r   Hiddenauth_token_comfy_orgapi_key_comfy_org	unique_id
PriceBadger   r;   r;   r<   r   I  s>   
z$RecraftCreateStyleNode.define_schemar   r   r&   c           
   	      s   g }d}d}t t| D ]'\}}t|ddd }|t|7 }||kr*td|d|d  |f qt| t	d	d
dt
|t|ddddI d H }	t|	jS )Nr   i  P i  @ z
image/webp)r$   	mime_typez,Total size of all images exceeds 5 MB limit.filer+   z/proxy/recraft/stylesr'   r(   )r   r*   )r,   r-   r/   r.   r0   r2   )rT   rD   valuesr   r4   lenrl   r6   r   r   r   r   r   r   id)
r    r   r   r/   
total_sizemax_total_sizeiimg
file_bytesr9   r;   r;   r<   r   p  s(   

zRecraftCreateStyleNode.executeN)rq   rr   rs   r   r   rX   r   r   Typer   r   r;   r;   r;   r<   r   H  s    
&r   c                   @   sL   e Zd Zedd Ze			ddededededed	ed
e	j
fddZdS )RecraftTextToImageNodec                 C   s   t jddddt jjddddd	t jjd
dd tD tjddt jjddddddt jjdddddddt t	j
jdddt jjddddddt t	jjdddd gt j gt jjt jjt jjgdt jt jdgd!d"d#d$	S )%Nr   zRecraft Text to Imagerw   z>Generates images synchronously based on prompt and resolution.promptTr    Prompt for the image generation.	multiliner{   r~   sizec                 S      g | ]}|j qS r;   r^   .0resr;   r;   r<   
<listcomp>      z8RecraftTextToImageNode.define_schema.<locals>.<listcomp> The size of the generated image.r   r{   r~   nr+      !The number of images to generate.rz   seedr       `Seed to determine if node should re-run; actual results are nondeterministic regardless of seed.r{   r|   r}   control_after_generater~   r   r   negative_prompt?An optional text description of undesired elements on an image.r{   force_inputr~   r   r   OOptional additional controls over the generation via the Recraft Controls node.r~   r   widgets1{"type":"usd","usd": $round(0.04 * widgets.n, 2)}
depends_onr   r   )r   r   r   r   r   r   res_1024x1024r   r   r   r   r   r   r   r   r   r   r   r   PriceBadgeDependsr   r;   r;   r<   r     sj   	'z$RecraftTextToImageNode.define_schemaNr   r   r   r   r   r   r&   c                    s   t |dddd ttj}|d u r|}d }	|r| }	|s d }t| tdddtt||d|||j	|j
|j|	d		dd
I d H }
g }|
jD ]2}t  tt|jddI d H }W d    n1 s_w   Y  t|jdk rp|d}|| qCttj|ddS )NFr+     strip_whitespace
min_length
max_length/proxy/recraft/image_generationr'   r(   	recraftv3)	r   r   modelr   r   r   r   r   controlsr-   r.   r2   r   r3      r   dim)r   r   r   r   create_api_modelr   r   r   r   r   r   r   r.   re   r   r   r7   r   shape	unsqueezer6   r   r   torchcat)r    r   r   r   r   r   r   r   default_stylecontrols_apir9   r   r.   r!   r;   r;   r<   r     sH   



zRecraftTextToImageNode.executeNNN)rq   rr   rs   r   r   rX   r   r   r   r   r   r   r;   r;   r;   r<   r     s,    
;	r   c                   @   sR   e Zd Zedd Ze			ddejdedede	de
d	ed
edejfddZdS )RecraftImageToImageNodec                 C   s   t jddddt jdt jjdddd	d
t jjddddddt jjdddddddt jjdddddddt tj	jdddt jjdddddd t tj
jd!d"dd#gt j gt jjt jjt jjgdt jt jdgd$d%d&d'	S )(Nr  zRecraft Image to Imagerw   z*Modify image based on prompt and strength.r!   r   Tr   r   r   r   r+   r   r   rz   strengthg      ?g        g      ?g{Gz?zDefines the difference with the original image, should lie in [0, 1], where 0 means almost identical, and 1 means miserable similarity.)r{   r|   r}   stepr~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r   Floatr   r   r   r   r   r   r   r   r   r   r  r   r;   r;   r<   r     sp   
		+z%RecraftImageToImageNode.define_schemaNr!   r   r   r  r   r   r   r&   c	                    s  t |ddd ttj}	|d u r|	}d }
|r| }
|sd }t||d|t|d|j|j|j	|
d	}g }|j
d }t|}t|D ]6}t| || d|d	I d H }t  |tjd
d |D dd W d    n1 smw   Y  |d qAttj|ddS )NFr  r  r  r
     )	r   r   r  r   r  r   r   r   r  r   z"/proxy/recraft/images/imageToImager!   r"   r8   c                 S      g | ]}t |qS r;   r   r   xr;   r;   r<   r   m      z3RecraftImageToImageNode.execute.<locals>.<listcomp>r  r+   )r   r   r   r   r  r   roundr   r   r   r  r   ranger=   re   r6   r  r  updater   r   )r    r!   r   r   r  r   r   r   r   r  r  r8   r   totalpbarr   	sub_bytesr;   r;   r<   r   >  sH   

 zRecraftImageToImageNode.executer  )rq   rr   rs   r   r   r  TensorrX   r   floatr   r   r   r   r   r;   r;   r;   r<   r    s0    
?	
r  c                   @   sN   e Zd Zedd Ze		ddejdejdedede	d	ed
e
jfddZdS )RecraftImageInpaintingNodec                 C   s   t jddddt jdt jdt jjddd	d
dt jjddddddt jjdddddddt tj	jdddt j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dgdddd	S )Nr-  zRecraft Image Inpaintingrw   z&Modify image based on prompt and mask.r!   r#   r   Tr   r   r   r   r+   r   r   rz   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   Maskr   r   r   r   r   r   r   r   r   r   r   r  r   r;   r;   r<   r   t  sX   

	z(RecraftImageInpaintingNode.define_schemaNr!   r#   r   r   r   r   r&   c              	      s  t |ddd ttj}|d u r|}|sd }t||d||j|j|jd}	t||ddd}g }
|j	d }t
|}t|D ]=}t| || |||d	  d
|	dI d H }t  |
tjdd |D dd W d    n1 sow   Y  |d	 q<ttj|
ddS )NFr  r  r
  r   r   r  r   r   r   r   T)allow_gradientadd_channel_dimr   r+   z/proxy/recraft/images/inpaint)r!   r#   r"   r8   c                 S   r   r;   r!  r"  r;   r;   r<   r     r$  z6RecraftImageInpaintingNode.execute.<locals>.<listcomp>r  )r   r   r   r   r   r   r   r   r   r  r   r&  r=   re   r6   r  r  r'  r   r   )r    r!   r#   r   r   r   r   r   r  r8   r   r(  r)  r   r*  r;   r;   r<   r     sB   

 z"RecraftImageInpaintingNode.executer   rq   rr   rs   r   r   r  r+  rX   r   r   r   r   r   r;   r;   r;   r<   r-  s  s*    
2	r-  c                   @   sJ   e Zd Zedd Ze		ddededededed	ed
ej	fddZ
dS )RecraftTextToVectorNodec                 C   s   t jddddt jjddddd	t jjd
ttjdt jjddd tD tj	ddt j
jddddddt j
jdddddddt jjddddddt tjjdddd gt j gt jjt jjt jjgdt jt jdgd!d"d#d$	S )%Nr3  zRecraft Text to Vectorrw   z;Generates SVG synchronously based on prompt and resolution.r   r   r   T)r{   r~   r   r   r   r   c                 S   r   r;   r   r   r;   r;   r<   r     r   z9RecraftTextToVectorNode.define_schema.<locals>.<listcomp>r   r   r   r+   r   r   rz   r   r   r   r   r   r   r   r   r   r   r   r   z1{"type":"usd","usd": $round(0.08 * widgets.n, 2)}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     s^   	!z%RecraftTextToVectorNode.define_schemaNr   r   r   r   r   r   r&   c                    s   t |ddd ttj|d}d }	|r| }	|sd }t| tdddtt||d|||j	|j
|	d	d
dI d H }
g }|
jD ]}|t|jddI d H  q<tt|S )NFr  r  )r   r	  r'   r(   r
  r   r   r  r   r   r   r   r  r+   r  r   r3   )r   r   r   r   r  r   r   r   r   r   r   r.   r6   r   r7   r   r   r   )r    r   r   r   r   r   r   r   r   r  r9   svg_datar.   r;   r;   r<   r     s8   


zRecraftTextToVectorNode.executer   )rq   rr   rs   r   r   rX   r   r   r   r   r   r;   r;   r;   r<   r3    s*    
5	r3  c                   @   2   e Zd Zedd ZedejdejfddZ	dS )RecraftVectorizeImageNodec                 C   sP   t jdddddt jdgt j gt jjt jjt jj	gdt j
t  dd	d

S )Nr7  zRecraft Vectorize Imagerw   Image Toolsz0Generates SVG synchronously from an input image.r!   Tz{"type":"usd","usd": 0.01}r   
r   r   r   essentials_categoryr   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r  r   r;   r;   r<   r   >  s(   
z'RecraftVectorizeImageNode.define_schemar!   r&   c                    sf   g }|j d }t|}t|D ]}t| || ddI d H }|t| |d qtt	|S )Nr   z/proxy/recraft/images/vectorizer!   r"   r+   )
r  r   r&  r=   r6   r   r'  r   r   combine_all)r    r!   svgsr(  r)  r   r*  r;   r;   r<   r   X  s   
z!RecraftVectorizeImageNode.executeN
rq   rr   rs   r   r   r  r+  r   r   r   r;   r;   r;   r<   r7  =  
    
r7  c                   @   sH   e Zd Zedd Ze		ddejdedede	ded	e
jfd
dZdS )RecraftReplaceBackgroundNodec                 C   s   t jddddt jdt jjdddd	d
t jjddddddt jjddddd	ddt tjjdd	dt j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dd	S )Nr@  zRecraft Replace Backgroundrw   z6Replace background on image, based on provided prompt.r!   r   r   r   T)r~   r{   r   r   r+   r   r   rz   r   r   r   r   r   r   r   r   r   r   z{"type":"usd","usd":0.04}r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r;   r;   r<   r   j  sH   
	z*RecraftReplaceBackgroundNode.define_schemaNr!   r   r   r   r   r&   c              	      s   t tj}|d u r|}|sd }t||d||j|j|jd}g }	|jd }
t|
}t	|
D ]#}t
| || d|dI d H }|	tjdd |D dd |d	 q-ttj|	ddS )
Nr
  r/  r   z'/proxy/recraft/images/replaceBackgroundr  c                 S   r   r;   r!  r"  r;   r;   r<   r     r$  z8RecraftReplaceBackgroundNode.execute.<locals>.<listcomp>r  r+   )r   r   r   r   r   r   r   r  r   r&  r=   r6   r  r  r'  r   r   )r    r!   r   r   r   r   r   r  r8   r   r(  r)  r   r*  r;   r;   r<   r     s8   



z$RecraftReplaceBackgroundNode.executer   r2  r;   r;   r;   r<   r@  i  s&    
*r@  c                   @   r6  )RecraftRemoveBackgroundNodec                 C   sR   t jdddddt jdgt j t j gt jjt jjt jj	gdt j
dd	d

S )NrA  zRecraft Remove Backgroundrw   r8  zBRemove background from image, and return processed image and mask.r!   Tz{"type":"usd","usd":0.01}r   r9  )r   r   r   r   r   r.  r   r   r   r   r   r   r;   r;   r<   r     s(   
z)RecraftRemoveBackgroundNode.define_schemar!   r&   c           	         s   g }|j d }t|}t|D ]"}t| || ddI d H }|tjdd |D dd |d qtj|dd}|d d d d d d dd f d}t	
||S )	Nr   z&/proxy/recraft/images/removeBackgroundr;  c                 S   r   r;   r!  r"  r;   r;   r<   r     r$  z7RecraftRemoveBackgroundNode.execute.<locals>.<listcomp>r  r+   )r  r   r&  r=   r6   r  r  r'  squeezer   r   )	r    r!   r   r(  r)  r   r*  images_tensormasks_tensorr;   r;   r<   r     s   
&z#RecraftRemoveBackgroundNode.executeNr>  r;   r;   r;   r<   rA    r?  rA  c                   @   s6   e Zd ZdZedd Zedejdej	fddZ
dS )	RecraftCrispUpscaleNodez"/proxy/recraft/images/crispUpscalec                 C   H   t jddddt jdgt j gt jjt jjt jjgdt j	ddd		S )
NrF  zRecraft Crisp Upscale Imagerw   u   Upscale image synchronously.
Enhances a given raster image using ‘crisp upscale’ tool, increasing image resolution, making the image sharper and cleaner.r!   Tz{"type":"usd","usd":0.004}r   r   
r   r   r   r   r   r   r   r   r   r   r   r;   r;   r<   r     $   
z%RecraftCrispUpscaleNode.define_schemar!   r&   c                    s|   g }|j d }t|}t|D ]#}t| || | jdI d H }|tjdd |D dd |d qt	
tj|ddS )Nr   r;  c                 S   r   r;   r!  r"  r;   r;   r<   r     r$  z3RecraftCrispUpscaleNode.execute.<locals>.<listcomp>r  r+   )r  r   r&  r=   RECRAFT_PATHr6   r  r  r'  r   r   )r    r!   r   r(  r)  r   r*  r;   r;   r<   r     s   
zRecraftCrispUpscaleNode.executeN)rq   rr   rs   rJ  r   r   r  r+  r   r   r   r;   r;   r;   r<   rF    s    
rF  c                   @   s   e Zd ZdZedd ZdS )RecraftCreativeUpscaleNodez%/proxy/recraft/images/creativeUpscalec                 C   rG  )
NrK  zRecraft Creative Upscale Imagerw   u   Upscale image synchronously.
Enhances a given raster image using ‘creative upscale’ tool, boosting resolution with a focus on refining small details and faces.r!   Tz{"type":"usd","usd":0.25}r   r   rH  r   r;   r;   r<   r      rI  z(RecraftCreativeUpscaleNode.define_schemaN)rq   rr   rs   rJ  r   r   r;   r;   r;   r<   rK    s    rK  c                   @   L   e Zd Zedd Ze	ddededededed	edB d
e	j
fddZdS )RecraftV4TextToImageNodec                 C      t jddddt jjddddt jjd	dd
dt jjdt jdt jjdtdddgt jdt jjdtdddggddt j	jddddddt j	jdddddddt 
tjjd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"d#d$d%	S )&NrM  zRecraft V4 Text to Imagerw   z3Generates images using Recraft V4 or V4 Pro models.r   T;Prompt for the image generation. Maximum 10,000 characters.r   r~   r   r   r  	recraftv4r   	1024x1024r   r   recraftv4_pro	2048x2048 The model to use for generation.r   r   r+   r   r   rz   r   r   r   r   r   r   r   r   r   z
                (
                    $prices := {"recraftv4": 0.04, "recraftv4_pro": 0.25};
                    {"type":"usd","usd": $lookup($prices, widgets.model) * widgets.n}
                )
                r   r   )r   r   r   r   DynamicComboOptionr   r	   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r;   r;   r<   r   <     	>z&RecraftV4TextToImageNode.define_schemaNr   r   r  r   r   r   r&   c                    s   t |dddd t| tdddtt||r|nd |d |d	 ||r%| nd d
ddI d H }g }|jD ]2}	t  tt	|	j
ddI d H }
W d    n1 sPw   Y  t|
jdk ra|
d}
||
 q4ttj|ddS )NFr+   '  r  r	  r'   r(   r  r   )r   r   r  r   r   r  r  r   r3   r  r   r  )r   r   r   r   r   r  r.   re   r   r   r7   r   r  r  r6   r   r   r  r  )r    r   r   r  r   r   r   r9   r   r.   r!   r;   r;   r<   r     s2   




z RecraftV4TextToImageNode.executerM   rq   rr   rs   r   r   rX   rL   r   r   r   r   r   r;   r;   r;   r<   rM  ;  (    
WrM  c                   @   rL  )RecraftV4TextToVectorNodec                 C   rN  )&Nr\  zRecraft V4 Text to Vectorrw   z0Generates SVG using Recraft V4 or V4 Pro models.r   TrO  rP  r   r   r  rQ  r   rR  r   r   rS  rT  rU  r   r   r+   r   r   rz   r   r   r   r   r   r   r   r   r   z
                (
                    $prices := {"recraftv4": 0.08, "recraftv4_pro": 0.30};
                    {"type":"usd","usd": $lookup($prices, widgets.model) * widgets.n}
                )
                r   r   )r   r   r   r   rV  rW  r   r	   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r;   r;   r<   r     rX  z'RecraftV4TextToVectorNode.define_schemaNr   r   r  r   r   r   r&   c           
         s   t |dddd t| tdddtt||r|nd |d |d	 |d
d |r'| nd dddI d H }g }|jD ]}	|t|	j	ddI d H  q6t
t|S )NFr+   rY  r  r	  r'   r(   r  r   r   r4  r  r   r3   )r   r   r   r   r   r  r.   r6   r   r7   r   r   r   )
r    r   r   r  r   r   r   r9   r5  r.   r;   r;   r<   r     s,   




z!RecraftV4TextToVectorNode.executerM   rZ  r;   r;   r;   r<   r\    r[  r\  c                   @   s(   e Zd Zedeeej  fddZdS )RecraftExtensionr&   c                    s*   t ttttttttt	t
tttttttgS rM   )r   r  r-  r3  r7  rA  r@  rF  rK  r   r   r   r   r   ru   r   rM  r\  rg   r;   r;   r<   get_node_list2  s(   zRecraftExtension.get_node_listN)	rq   rr   rs   r   rD   typer   	ComfyNoder^  r;   r;   r;   r<   r]  1  s    r]  c                      s   t  S rM   )r]  r;   r;   r;   r<   comfy_entrypointJ  s   ra  )Nr   r   N)NNNFr>   )Hior   rU   r  PILr   typing_extensionsr   comfy.utilsr   comfy_api.latestr   r   comfy_api_nodes.apis.recraftr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   comfy_api_nodes.utilr   r   r   r   r   r   r   comfy_extras.nodes_imagesr   r_  r`  r+  rX   r   rD   r=   callableboolrL   rV   r5   re   ru   r   r   r   r   r   r   r   r   r  r-  r3  r7  r@  rA  rF  rK  rM  r\  r]  ra  r;   r;   r;   r<   <module>   s    @$	
%


SEpvfd,W/.|z