o
    i*_                     @   sT  d dl mZ d dl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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Z#dZ$G d	d
 d
ej%Z&G dd dej%Z'G dd dej%Z(G dd dej%Z)G dd dej%Z*G dd dej%Z+ej,ej-g ddddZ.G dd deZ/de/fddZ0dS )    )OptionalN)override)IOComfyExtension)LumaAspectRatioLumaCharacterRefLumaConceptChainLumaGenerationLumaGenerationRequestLumaImageGenerationRequestLumaImageIdentityLumaImageModelLumaImageReferenceLumaIOLumaKeyframesLumaModifyImageRefLumaReferenceLumaReferenceChainLumaVideoModelLumaVideoModelOutputDurationLumaVideoOutputResolutionget_luma_concepts)ApiEndpointdownload_url_to_image_tensordownload_url_to_video_outputpoll_opsync_opupload_images_to_comfyapivalidate_stringi   d   c                
   @   sD   e Zd ZedejfddZed
dejde	de
dejfdd	ZdS )LumaReferenceNodereturnc                 C   s`   t jddddt jjdddt jjdd	d
d	dddt tjjdddgt tjjddgdS )Nr!   zLuma Referenceapi node/image/Lumaz@Holds an image and weight for use with Luma Generate Image node.imagezImage to use as reference.)tooltipweight      ?        {Gz?zWeight of image reference.defaultminmaxstepr%   luma_refT)optionaldisplay_namenode_idr2   categorydescriptioninputsoutputs)	r   SchemaImageInputFloatCustomr   LUMA_REFOutputcls rB   8/mnt/c/Users/fbmor/ComfyUI/comfy_api_nodes/nodes_luma.pydefine_schema*   s0   zLumaReferenceNode.define_schemaNr$   r&   r/   c                 C   s:   |d ur	|  }nt }|t|t|dd t|S )N   r$   r&   )cloner   addr   roundr   
NodeOutput)rA   r$   r&   r/   rB   rB   rC   executeF   s
   

zLumaReferenceNode.executeN)__name__
__module____qualname__classmethodr   r9   rD   torchTensorfloatr   rJ   rK   rB   rB   rB   rC   r!   )   s
    &r!   c                   @   sL   e Zd ZedejfddZe	ddedededed	edej	fd
dZ
dS )LumaConceptsNoder"   c                 C   s   t jddddt jjdtdddt jjd	tdddt jjd
tdddt jjdtdddt tjjddddgt tjjddgdS )NrT   zLuma Conceptsapi node/video/LumazNCamera Concepts for use with Luma Text to Video and Luma Image to Video nodes.concept1T)include_noneoptionsconcept2concept3concept4luma_conceptsz8Optional Camera Concepts to add to the ones chosen here.r%   r0   r1   r3   )	r   r9   Combor;   r   r=   r   LUMA_CONCEPTSr?   r@   rB   rB   rC   rD   Q   s:   zLumaConceptsNode.define_schemaNrV   rZ   r[   r\   r]   c                 C   s.   t ||||gd}|d ur||}t|S )N)str_list)r   clone_and_merger   rJ   )rA   rV   rZ   r[   r\   r]   chainrB   rB   rC   rK   r   s   	

zLumaConceptsNode.executerL   )rM   rN   rO   rP   r   r9   rD   strr   rJ   rK   rB   rB   rB   rC   rT   P   s$     rT   c                   @   s   e Zd ZedejfddZe			ddedededed	e	e
 d
e	ej de	ej dejfddZede
defddZed
ejdefddZdS )LumaImageGenerationNoder"   c                 C   s   t jddddt jjddddd	t jjd
tdt jjdttj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dt jjdddd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 )$NLumaImageNodezLuma Text to Imager#   z@Generates images synchronously based on prompt and aspect ratio.promptT Prompt for the image generation	multiliner+   r%   modelrX   aspect_ratiorY   r+   seedr       `Seed to determine if node should re-run; actual results are nondeterministic regardless of seed.r+   r,   r-   control_after_generater%   style_image_weightr'   r(   r)   z:Weight of style image. Ignored if no style_image provided.r*   image_luma_refzkLuma Reference node connection to influence generation with input images; up to 4 images can be considered.r^   style_imagez1Style reference image; only 1 image will be used.character_imagezYCharacter reference images; can be a batch of multiple, up to 4 images can be considered.widgetsV  
                (
                  $m := widgets.model;
                  $contains($m,"photon-flash-1")
                    ? {"type":"usd","usd":0.0027}
                    : $contains($m,"photon-1")
                      ? {"type":"usd","usd":0.0104}
                      : {"type":"usd","usd":0.0246}
                )
                
depends_onexpr	r4   r2   r5   r6   r7   r8   hiddenis_api_nodeprice_badge)r   r9   Stringr;   r_   r   r   
ratio_16_9Intr<   r=   r   r>   r:   r?   Hiddenauth_token_comfy_orgapi_key_comfy_org	unique_id
PriceBadgePriceBadgeDependsr@   rB   rB   rC   rD      s~   
0z%LumaImageGenerationNode.define_schemaNrg   rl   rm   rt   ru   rv   rw   c	                    s   t |ddd d }	|d ur| j|ddI d H }	d }
|d ur(| j||dI d H }
d }|d ur@t| |ddI d H }tt|dd	}t| td
ddtt	||||	|
|ddI d H }t
| td|j dtdd dI d H }tt|jjI d H S )NT   strip_whitespace
min_length   max_refs)r&   
max_images)images)	identity0/proxy/luma/generations/imagePOSTpathmethod)rg   rl   rm   	image_ref	style_refcharacter_refresponse_modeldata/proxy/luma/generations/r   c                 S      | j S rL   statexrB   rB   rC   <lambda>       z1LumaImageGenerationNode.execute.<locals>.<lambda>r   status_extractor)r   _convert_luma_refs_convert_style_imager   r   r   r   r   r	   r   r   idr   rJ   r   assetsr$   )rA   rg   rl   rm   ro   rt   ru   rv   rw   api_image_refapi_style_refr   download_urlsresponse_apiresponse_pollrB   rB   rC   rK      s@   
zLumaImageGenerationNode.executer/   r   c                    s\   g }d}|j D ]}t| |jddI d H }||d  |d7 }||kr& nq|j||dS )Nr      r   )r   r   )refsr   r$   appendcreate_api_model)rA   r/   r   	luma_urls	ref_countrefr   rB   rB   rC   r      s   
z*LumaImageGenerationNode._convert_luma_refsr&   c                    s(   t t||dd}| j|ddI d H S )NrF   )	first_refr   r   )r   r   r   )rA   rv   r&   rc   rB   rB   rC   r     s   z,LumaImageGenerationNode._convert_style_imageNNN)rM   rN   rO   rP   r   r9   rD   rd   rS   r   r   rQ   rR   rJ   rK   intr   r   rB   rB   rB   rC   re      s8    L	
/re   c                   @   sF   e Zd ZedejfddZedededej	de
dejf
dd	Zd
S )LumaImageModifyNoder"   c                 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dt jjdtdt j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t jdgdddd	S )Nr   zLuma Image to Imager#   z?Modifies images synchronously based on prompt and aspect ratio.r$   rg   Trh   ri   rj   image_weightg?r(   \(\?r)   zLWeight of the image; the closer to 1.0, the less the image will be modified.r*   rl   rX   ro   r   rp   rq   rr   rx   rz   r{   r~   )r   r9   r:   r;   r   r<   r_   r   r   r?   r   r   r   r   r   r   r@   rB   rB   rC   rD     s\   
z!LumaImageModifyNode.define_schemarg   rl   r$   r   c           
         s   t | |ddI d H }|d }t| tdddtt||t|tttd| dd	d
dddI d H }t	| td|j
 dtdd dI d H }	tt|	jjI d H S )Nr   r   r   r   r   r   r'   r   r(   rE   )urlr&   )rg   rl   modify_image_refr   r   r   c                 S   r   rL   r   r   rB   rB   rC   r   i  r   z-LumaImageModifyNode.execute.<locals>.<lambda>r   )r   r   r   r	   r   r   rI   r-   r,   r   r   r   rJ   r   r   r$   )
rA   rg   rl   r$   r   ro   r   	image_urlr   r   rB   rB   rC   rK   N  s,   	
zLumaImageModifyNode.executeN)rM   rN   rO   rP   r   r9   rD   rd   rQ   rR   rS   rJ   rK   rB   rB   rB   rC   r     s    ;r   c                   @   sX   e Zd ZedejfddZe	ddedededed	ed
ede	e
 dejfddZdS )LumaTextToVideoGenerationNoder"   c                 C   s   t jddddt jjddddd	t jjd
tdt jjdttjdt jjdttj	dt jjdt
dt jj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d	S )NLumaVideoNodezLuma Text to VideorU   z?Generates videos synchronously based on prompt and output_size.rg   Trh   Prompt for the video generationrj   rl   rX   rm   rn   
resolutiondurationloopFr+   ro   r   rp   rq   rr   r]   MOptional Camera Concepts to dictate camera motion via the Luma Concepts node.r^   r~   )r   r9   r   r;   r_   r   r   r   r   res_540pr   Booleanr   r=   r   r`   Videor?   r   r   r   r   PRICE_BADGE_VIDEOr@   rB   rB   rC   rD   o  sn   
+z+LumaTextToVideoGenerationNode.define_schemaNrg   rl   rm   r   r   r   r]   c	                    s   t |ddd |tjkr|nd }|tjkr|nd }t| tdddtt|||||||r/| nd ddI d H }	t| td	|	j	 d
tdd t
dI d H }
tt|
jjI d H S )NFr   r   /proxy/luma/generationsr   r   )rg   rl   r   rm   r   r   conceptsr   r   r   c                 S   r   rL   r   r   rB   rB   rC   r     r   z7LumaTextToVideoGenerationNode.execute.<locals>.<lambda>)r   r   estimated_duration)r   r   ray_1_6r   r   r	   r
   r   r   r   LUMA_T2V_AVERAGE_DURATIONr   rJ   r   r   video)rA   rg   rl   rm   r   r   r   ro   r]   r   r   rB   rB   rC   rK     s4   
z%LumaTextToVideoGenerationNode.executerL   )rM   rN   rO   rP   r   r9   rD   rd   boolr   r   rJ   rK   rB   rB   rB   rC   r   n  s,    ;
	
r   c                   @   s   e Zd ZedejfddZe			ddedededed	ed
e	j
de	j
dedejfddZe		dd
e	j
de	j
fddZdS )LumaImageToVideoGenerationNoder"   c                 C   s   t jddddt jjddddd	t jjd
tdt jjdttjdt jjddd tD dt j	jdddt j
jdddddddt jjddddt jj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d 	S )!NLumaImageToVideoNodezLuma Image to VideorU   zNGenerates videos synchronously based on prompt, input images, and output_size.rg   Trh   r   rj   rl   rX   r   rn   r   c                 S   s   g | ]}|j qS rB   )value).0durrB   rB   rC   
<listcomp>  s    z@LumaImageToVideoGenerationNode.define_schema.<locals>.<listcomp>r   Fr   ro   r   rp   rq   rr   first_imagezFirst frame of generated video.r^   
last_imagezLast frame of generated video.r]   r   r~   )r   r9   r   r;   r_   r   r   r   r   r   r   r:   r=   r   r`   r   r?   r   r   r   r   r   r@   rB   rB   rC   rD     sx   	
5z,LumaImageToVideoGenerationNode.define_schemaNrg   rl   r   r   r   r   r   r]   c
                    s   |d u r|d u rt d| ||I d H }
|tjkr|nd }|tjkr&|nd }t| tdddtt||tj	||||
|	r?|	
 nd ddI d H }t| td|j dtd	d
 tdI d H }tt|jjI d H S )Nz=At least one of first_image and last_image requires an input.r   r   r   )rg   rl   rm   r   r   r   	keyframesr   r   r   r   c                 S   r   rL   r   r   rB   rB   rC   r   @  r   z8LumaImageToVideoGenerationNode.execute.<locals>.<lambda>)poll_endpointr   r   r   )	Exception_convert_to_keyframesr   r   r   r   r	   r
   r   r   r   r   r   LUMA_I2V_AVERAGE_DURATIONr   rJ   r   r   r   )rA   rg   rl   r   r   r   ro   r   r   r]   r   r   r   rB   rB   rC   rK     s:   
z&LumaImageToVideoGenerationNode.executec                    s   |d u r|d u rd S d }d }|d ur%t | |ddI d H }td|d d}|d ur;t | |ddI d H }td|d d}t||dS )Nr   r   r$   r   )typer   )frame0frame1)r   r   r   )rA   r   r   r   r   r   rB   rB   rC   r   E  s   z4LumaImageToVideoGenerationNode._convert_to_keyframesr   )NN)rM   rN   rO   rP   r   r9   rD   rd   r   rQ   rR   r   rJ   rK   r   rB   rB   rB   rC   r     sD    F		
)r   )rl   r   r   rx   a  
    (
      $p := {
        "ray-flash-2": {
          "5s": {"4k":3.13,"1080p":0.79,"720p":0.34,"540p":0.2},
          "9s": {"4k":5.65,"1080p":1.42,"720p":0.61,"540p":0.36}
        },
        "ray-2": {
          "5s": {"4k":9.11,"1080p":2.27,"720p":1.02,"540p":0.57},
          "9s": {"4k":16.4,"1080p":4.1,"720p":1.83,"540p":1.03}
        }
      };

      $m := widgets.model;
      $d := widgets.duration;
      $r := widgets.resolution;

      $modelKey :=
        $contains($m,"ray-flash-2") ? "ray-flash-2" :
        $contains($m,"ray-2") ? "ray-2" :
        $contains($m,"ray-1-6") ? "ray-1-6" :
        "other";

      $durKey := $contains($d,"5s") ? "5s" : $contains($d,"9s") ? "9s" : "";
      $resKey :=
        $contains($r,"4k") ? "4k" :
        $contains($r,"1080p") ? "1080p" :
        $contains($r,"720p") ? "720p" :
        $contains($r,"540p") ? "540p" : "";

      $modelPrices := $lookup($p, $modelKey);
      $durPrices := $lookup($modelPrices, $durKey);
      $v := $lookup($durPrices, $resKey);

      $price :=
        ($modelKey = "ray-1-6") ? 0.5 :
        ($modelKey = "other") ? 0.79 :
        ($exists($v) ? $v : 0.79);

      {"type":"usd","usd": $price}
    )
    r{   c                   @   s(   e Zd Zedeeej  fddZdS )LumaExtensionr"   c                    s   t tttttgS rL   )re   r   r   r   r!   rT   )selfrB   rB   rC   get_node_list  s   zLumaExtension.get_node_listN)	rM   rN   rO   r   listr   r   	ComfyNoder   rB   rB   rB   rC   r     s    r   r"   c                      s   t  S rL   )r   rB   rB   rB   rC   comfy_entrypoint  s   r   )1typingr   rQ   typing_extensionsr   comfy_api.latestr   r   comfy_api_nodes.apis.lumar   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   comfy_api_nodes.utilr   r   r   r   r   r   r   r   r   r   r!   rT   re   r   r   r   r   r   r   r   r   rB   rB   rB   rC   <module>   s,    P$
'1 ]e /