§
    ÎÐj  ã                   óŠ   — d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlZd dlZ	d dl
Zd dlmZmZ d dlmZ  G d„ de¦  «        ZdS )é    N)ÚPath)ÚImageÚImageOps)ÚWAN2GPPluginc                   ó:  ‡ — e Zd Zˆ fd„Zd„ Zd„ Zdedefd„Zdedz  d	edz  d
edz  dedz  dedz  f
d„Z	dedz  d	edz  dedz  fd„Z
dedz  fd„Zdedeez  dz  defd„Zdedeedz  edz  f         fd„Zdededeeef         dz  fd„Zdefd„Zdefd„Zˆ xZS )ÚMotionDesignerPluginc                 óŽ   •— t          ¦   «                              ¦   «          d| _        d| _        d| _        d | _        d | _        d S )NúMotion Designerz1.0.0zeCut objects, design their motion paths, preview the animation, and send the mask directly into WanGP.)ÚsuperÚ__init__ÚnameÚversionÚdescriptionÚ_iframe_html_cacheÚ_iframe_cache_signature)ÚselfÚ	__class__s    €úFC:\Users\johnn\OneDrive\Documents\AI\plugins\motion_designer\plugin.pyr   zMotionDesignerPlugin.__init__   sJ   ø€ Ý‰Œ×ÒÑÔÐØ%ˆŒ	ØˆŒàsð 	Ôð /3ˆÔØDHˆÔ$Ð$Ð$ó    c                 óŠ  — |                       d¦  «         |                       d¦  «         |                      d¦  «         |                      d¦  «         |                      d¦  «         |                       d¦  «         |                      |                      ¦   «         ¦  «         |                      dd| j        ¬	¦  «         d S )
NÚupdate_video_prompt_typeÚget_model_defÚstateÚ	main_tabsÚrefresh_form_triggerÚget_current_model_settingsÚmotion_designerr
   )Útab_idÚlabelÚcomponent_constructor)Úrequest_globalÚrequest_componentÚadd_custom_jsÚ
_js_bridgeÚadd_tabÚ	_build_ui©r   s    r   Úsetup_uizMotionDesignerPlugin.setup_ui   sË   € Ø×ÒÐ6Ñ7Ô7Ð7Ø×Ò˜OÑ,Ô,Ð,Ø×Ò˜wÑ'Ô'Ð'Ø×Ò˜{Ñ+Ô+Ð+Ø×ÒÐ5Ñ6Ô6Ð6Ø×ÒÐ8Ñ9Ô9Ð9Ø×Ò˜4Ÿ?š?Ñ,Ô,Ñ-Ô-Ð-Ø�ŠØ$Ø#Ø"&¤.ð 	ñ 	
ô 	
ð 	
ð 	
ð 	
r   c           	      óZ  — |                       ¦   «         }d}t          j        d¬¦  «        5  t          j        ||z   dd ¬¦  «         t          j        ddd¬	¦  «        }t          j        d
dd¬	¦  «        }t          j        ddd¬	¦  «        }t          j        ddd¬	¦  «        }t          j        ddd¬	¦  «        }t          j        dddd¬¦  «        }t          j        ddd¬	¦  «        }	t          j        ddd¬	¦  «        }
t          j        ddd¬	¦  «        }t          j        ddd¬¦  «        }t          j        ddd ¬¦  «        }d d d ¦  «         n# 1 swxY w Y   |                     | j        | j        |	|
|g| j	        gd!¬"¦  «         
                    | j        | j        g| j        g¬#¦  «         |                     | j        | j        |||||g| j	        gd!¬"¦  «         
                    | j        | j        g| j        g¬#¦  «         |                     d$„ |gg d!dd%¬&¦  «         |g| _        d S )'NaO  
        <style>
            #motion_designer_iframe_container,
            #motion_designer_iframe_container > div {
                padding: 0 !important;
                margin: 0 !important;
            }
            #motion_designer_iframe_container iframe {
                display: block;
            }
        </style>
        Úmotion_designer_plugin)Úelem_idÚ motion_designer_iframe_container)Úvaluer+   Ú
min_heightzMask PayloadFÚmotion_designer_mask_payload)r   Úvisibler+   zMask MetadataÚmotion_designer_meta_payloadzBackground PayloadÚ"motion_designer_background_payloadzGuide PayloadÚmotion_designer_guide_payloadzGuide MetadataÚ"motion_designer_guide_meta_payloadz	Mode SyncÚcut_dragÚmotion_designer_mode_sync)r   r-   r0   r+   zTrajectory PayloadÚ"motion_designer_trajectory_payloadzTrajectory MetadataÚmotion_designer_trajectory_metazTrajectory BackgroundÚ%motion_designer_trajectory_backgroundzApply Motion Designer dataÚmotion_designer_apply_trigger)r0   r+   zApply Trajectory dataÚ"motion_designer_trajectory_triggerÚhidden)ÚfnÚinputsÚoutputsÚshow_progress)r=   r>   r?   c                 ó   — d S )N© )Ú_s    r   ú<lambda>z0MotionDesignerPlugin._build_ui.<locals>.<lambda>š   s   € ˜€ r   a  
            (mode) => {
                const raw = (mode || "").toString();
                const normalized = raw.split("|", 1)[0]?.trim().toLowerCase();
                if (!normalized) {
                    return;
                }
                if (window.motionDesignerSetRenderMode) {
                    window.motionDesignerSetRenderMode(normalized);
                } else {
                    console.warn("[MotionDesignerPlugin] motionDesignerSetRenderMode not ready yet.");
                }
            }
            )r=   r>   r?   r@   ÚqueueÚjs)Ú_get_iframe_markupÚgrÚColumnÚHTMLÚTextboxÚButtonÚclickÚ_apply_trajectoryr   r   ÚthenÚgoto_media_tabr   Ú_apply_maskÚchangeÚon_tab_outputs)r   Úiframe_htmlÚiframe_wrapper_styleÚmask_payloadÚmetadata_payloadÚbackground_payloadÚguide_payloadÚguide_metadata_payloadÚ	mode_syncÚtrajectory_payloadÚtrajectory_metadataÚtrajectory_backgroundÚtriggerÚtrajectory_triggers                 r   r&   zMotionDesignerPlugin._build_ui*   sS  € Ø×-Ò-Ñ/Ô/ˆð Ðõ ŒYÐ7Ð8Ñ8Ô8ð =	ð =	ÝŒGØ*¨[Ñ8Ø:Øðñ ô ð õ
 œ:Ø$ØØ6ðñ ô ˆLõ
  "œzØ%ØØ6ð ñ  ô  Ðõ
 "$¤Ø*ØØ<ð"ñ "ô "Ðõ
 œJØ%ØØ7ðñ ô ˆMõ
 &(¤ZØ&ØØ<ð&ñ &ô &Ð"õ
 œ
Ø!Ø ØØ3ð	ñ ô ˆIõ "$¤Ø*ØØ<ð"ñ "ô "Ðõ
 #%¤*Ø+ØØ9ð#ñ #ô #Ðõ
 %'¤JØ-ØØ?ð%ñ %ô %Ð!õ
 ”iØ,ØØ7ðñ ô ˆGõ
 "$¤Ø'ØØ<ð"ñ "ô "Ððs=	ð =	ð =	ñ =	ô =	ð =	ð =	ð =	ð =	ð =	ð =	øøøð =	ð =	ð =	ð =	ð~ 	× Ò ØÔ%à”
Ø"Ø#Ø%ð	ð Ô.Ð/Ø"ð 	!ñ 
	
ô 
	
÷ Š$ØÔ"Ø”J�<Ø”^Ð$ð ñ 
ô 
ð 
ð 	�ŠØÔà”
ØØ Ø"ØØ&ðð Ô.Ð/Ø"ð 	ñ 	
ô 	
÷ Š$ØÔ"Ø”J�<Ø”^Ð$ð ñ 
ô 
ð 
ð 	×ÒØˆ~Ø�;ØØ"Øðð 	ñ 	
ô 	
ð 	
ð*  )˜kˆÔÐÐs   ¬DEÅEÅEr   Úreturnc                 ó*  — |                       |d         ¦  «        }d}|                     dd¦  «        rd}nE|                     dd¦  «        rd}n,|                     dd¦  «        rd}nt          j        ¦   «         S |› d	t	          j        ¦   «         d
›�S )NÚ
model_typer5   Úi2v_v2vFÚ
vace_classÚclassicÚi2v_trajectoryÚ
trajectoryú|z.6f)r   ÚgetrH   ÚupdateÚtime)r   r   Ú	model_defÚmodes       r   Úon_tab_selectz"MotionDesignerPlugin.on_tab_select°   s    € Ø×&Ò& u¨\Ô':Ñ;Ô;ˆ	ØˆØ�=Š=˜ EÑ*Ô*ð 	ØˆDˆDØ�]Š]˜<¨Ñ/Ô/ð 	ØˆDˆDØ�]Š]Ð+¨UÑ3Ô3ð 	ØˆDˆDå”9‘;”;ÐØÐ*Ð*�œ™œÐ*Ð*Ð*Ð*r   Úencoded_videoNÚmetadata_jsonÚbackground_image_dataÚguide_video_dataÚguide_metadata_jsonc                 ó€	  — |st          j        d¦  «        ‚|                     ¦   «         }	 t          j        |¦  «        }n'# t
          $ r}t          j        d¦  «        |‚d }~ww xY wi }	|rD	 t          j        |¦  «        }	t          |	t          ¦  «        si }	n# t          j
        $ r i }	Y nw xY wi }
|rD	 t          j        |¦  «        }
t          |
t          ¦  «        si }
n# t          j
        $ r i }
Y nw xY w|                      |¦  «        }t          d¦  «        }|                     dd¬¦  «         t          j        d¦  «        }|d|› d�z  }|                     |¦  «         d }|rq	 t          j        |                     ¦   «         ¦  «        }|d	|› d�z  }|                     |¦  «         n+# t
          $ r}t#          d
|› �¦  «         d }Y d }~nd }~ww xY wd }d}t          |	t          ¦  «        rK|	                     d¦  «        }t'          |	                     d¦  «        pd¦  «                             ¦   «         }|€*t          |
t          ¦  «        r|
                     d¦  «        }|dvrKt          |
t          ¦  «        r6t'          |
                     d¦  «        pd¦  «                             ¦   «         }|dvrd}|                      ||¦  «        }|r|                      ||¦  «        nd }|                      d||	¦  «         |r|                      d||
p|	¦  «         |                      |¦  «        }|dk    r]t'          |¦  «        |d<   |                     dd ¦  «         |                     dd ¦  «         |	r|	|d<   nƒ|                     dd ¦  «         nlt'          |¦  «        |d<   |	r|	|d<   n|                     dd ¦  «         |p|}t'          |¦  «        |d<   |
r|
|d<   n|	r|	|d<   n|                     dd ¦  «         |�Y|dk    rM|                     d¦  «        }t          |t2          ¦  «        r|rt3          |¦  «        }||d<   ||d<   n|g|d<   n|g|d<   |dk    r|                      |ddd¬¦  «         n|                      |ddd¬¦  «         t          j        d¦  «         t          j        ¦   «         S )Nz,No mask video received from Motion Designer.z(Unable to decode the mask video payload.Úmask_outputsT©ÚparentsÚexist_okú%Y%m%d_%H%M%SÚmotion_designer_mask_z.webmÚmotion_designer_guide_z=[MotionDesignerPlugin] Failed to decode guide video payload: Ú ÚfpsÚ
renderMode)rf   r5   r5   ÚmaskÚguiderf   Úvideo_guideÚ
video_maskÚvideo_mask_metaÚvideo_guide_metaÚ
image_refsr   Úimage_start)Úany_video_guideÚany_background_image_refÚprocess_typeÚG)rˆ   Úany_video_maskÚdefault_updatez8Motion Designer data transferred to the Media Generator.)rH   ÚErrorÚstripÚbase64Ú	b64decodeÚ	ExceptionÚjsonÚloadsÚ
isinstanceÚdictÚJSONDecodeErrorÚ_decode_background_imager   Úmkdirrl   ÚstrftimeÚwrite_bytesÚprintrj   ÚstrÚlowerÚ_transcode_videoÚ_log_frame_checkr   ÚpopÚlistr   ÚInfo)r   r   rp   rq   rr   rs   rt   Úvideo_bytesÚexcÚmetadataÚguide_metadataÚbackground_imageÚ
output_dirÚ	timestampÚ	file_pathÚ
guide_pathÚguide_bytesÚfps_hintÚrender_modeÚsanitized_mask_pathÚsanitized_guide_pathÚui_settingsÚguide_video_pathÚexisting_refsÚnew_refss                            r   rQ   z MotionDesignerPlugin._apply_mask½   s»  € ð ð 	KÝ”(ÐIÑJÔJÐJà%×+Ò+Ñ-Ô-ˆð	PÝ Ô*¨=Ñ9Ô9ˆKˆKøÝð 	Pð 	Pð 	PÝ”(ÐEÑFÔFÈCÐOøøøøð	Pøøøð ')ˆØð 	ðÝœ: mÑ4Ô4�Ý! (­DÑ1Ô1ð "Ø!�HøøÝÔ'ð ð ð Ø���ðøøøð -/ˆØð 	$ð$Ý!%¤Ð,?Ñ!@Ô!@�Ý! .µ$Ñ7Ô7ð (Ø%'�NøøÝÔ'ð $ð $ð $Ø!#���ð$øøøð  ×8Ò8Ð9NÑOÔOÐå˜.Ñ)Ô)ˆ
Ø×Ò °ÐÑ5Ô5Ð5Ý”M /Ñ2Ô2ˆ	ØÐ!I¸Ð!IÐ!IÐ!IÑIˆ	Ø×Ò˜kÑ*Ô*Ð*à"&ˆ
Øð 	"ð"Ý$Ô.Ð/?×/EÒ/EÑ/GÔ/GÑHÔH�Ø'Ð*SÀ9Ð*SÐ*SÐ*SÑS�
Ø×&Ò& {Ñ3Ô3Ð3Ð3øÝð "ð "ð "ÝÐ[ÐVYÐ[Ð[Ñ\Ô\Ð\Ø!�
�
�
�
�
�
øøøøð"øøøð ˆØˆÝ�h¥Ñ%Ô%ð 	HØ—|’| EÑ*Ô*ˆHÝ˜hŸlšl¨<Ñ8Ô8Ð>¸BÑ?Ô?×EÒEÑGÔGˆKØÐ¥
¨>½4Ñ @Ô @ÐØ%×)Ò)¨%Ñ0Ô0ˆHØÐ5Ð5Ð5½*À^ÕUYÑ:ZÔ:ZÐ5Ý˜n×0Ò0°Ñ>Ô>ÐDÀ"ÑEÔE×KÒKÑMÔMˆKØÐ5Ð5Ð5Ø$ˆKà"×3Ò3°I¸xÑHÔHÐØNXÐb˜t×4Ò4°ZÀÑJÔJÐJÐ^bÐØ×Ò˜fÐ&9¸8ÑDÔDÐDØð 	]Ø×!Ò! 'Ð+?ÀÐA[ÐS[Ñ\Ô\Ð\ð
 ×5Ò5°eÑ<Ô<ˆØ˜)Ò#Ð#Ý),Ð-@Ñ)AÔ)AˆK˜Ñ&Ø�OŠO˜L¨$Ñ/Ô/Ð/Ø�OŠOÐ-¨tÑ4Ô4Ð4Øð :Ø2:�Ð.Ñ/Ð/à—’Ð 2°DÑ9Ô9Ð9Ð9å(+Ð,?Ñ(@Ô(@ˆK˜Ñ%Øð 9Ø19�Ð-Ñ.Ð.à—’Ð 1°4Ñ8Ô8Ð8à3ÐJÐ7JÐÝ),Ð-=Ñ)>Ô)>ˆK˜Ñ&Øð :Ø2@�Ð.Ñ/Ð/Øð :Ø2:�Ð.Ñ/Ð/à—’Ð 2°DÑ9Ô9Ð9àÐ'Ø˜iÒ'Ð'Ø +§¢°Ñ =Ô =�Ý˜m­TÑ2Ô2ð C°}ð CÝ# MÑ2Ô2�HØ"2�H˜Q‘KØ08�K Ñ-Ð-à1AÐ0B�K Ñ-Ð-à.>Ð-?�˜MÑ*Ø˜)Ò#Ð#Ø×)Ò)¨%À4ÐdhÐy{Ð)Ñ|Ô|Ð|Ð|à×)Ò)¨%À4ÐZ^ÐorÐ)ÑsÔsÐså
ŒÐJÑKÔKÐKÝŒy‰{Œ{ÐsT   ¬A Á
A%ÁA Á A%Á-+B ÂB-Â,B-Â5+C! Ã!C5Ã4C5Å*AF/ Æ/
GÆ9GÇGÚtrajectory_jsonÚbackground_data_urlc                 óž  — |st          j        d¦  «        ‚	 t          j        |¦  «        }t	          |t
          ¦  «        rt          |¦  «        dk    rt          j        d¦  «        ‚n,# t          j        $ r}t          j        d¦  «        |‚d }~ww xY wi }|rD	 t          j        |¦  «        }t	          |t          ¦  «        si }n# t          j        $ r i }Y nw xY wt          j
        |t          j        ¬¦  «        }t          |j        ¦  «        dk    s|j        d         dk    rt          j        d|j        › �¦  «        ‚t          d	¦  «        }	|	                     d
d
¬¦  «         t          j        d¦  «        }
|	d|
› d�z  }t          j        ||¦  «         t%          d|› d|j        › d�¦  «         |                      |¦  «        }t)          |                     ¦   «         ¦  «        |d<   |                      |¦  «        }|�|g|d<   t          j        d|j        d         › d|j        d         › d�¦  «         t          j        ¦   «         S )Nz1No trajectory data received from Motion Designer.r   z2Invalid trajectory data: expected non-empty array.z Unable to parse trajectory data.)Údtypeé   é   z2Invalid trajectory shape: expected [T, N, 2], got rv   Trw   rz   Úmotion_designer_trajectory_z.npyz)[MotionDesignerPlugin] Trajectory saved: z	 (shape: ú)Úcustom_guider‡   zTrajectory data saved (z	 frames, é   z trajectories).)rH   rŽ   r“   r”   r•   r¢   Úlenr—   r–   ÚnpÚarrayÚfloat32Úshaper   r™   rl   rš   Úsaverœ   r   r�   Úabsoluter˜   r£   )r   r   r¶   rq   r·   Útrajectoriesr¥   r¦   Útrajectory_arrayr©   rª   r«   r²   r¨   s                 r   rN   z&MotionDesignerPlugin._apply_trajectory4  s’  € ð ð 	PÝ”(ÐNÑOÔOÐOð	HÝœ: oÑ6Ô6ˆLÝ˜l­DÑ1Ô1ð UµS¸Ñ5FÔ5FÈ!Ò5KÐ5KÝ”hÐSÑTÔTÐTð 6LøåÔ#ð 	Hð 	Hð 	HÝ”(Ð=Ñ>Ô>ÀCÐGøøøøð	Høøøð ')ˆØð 	ðÝœ: mÑ4Ô4�Ý! (­DÑ1Ô1ð "Ø!�HøøÝÔ'ð ð ð Ø���ðøøøõ
 œ8 L½¼
ÐCÑCÔCÐõ ÐÔ%Ñ&Ô&¨!Ò+Ð+Ð/?Ô/EÀaÔ/HÈAÒ/MÐ/MÝ”(ÐhÐP`ÔPfÐhÐhÑiÔiÐiõ ˜.Ñ)Ô)ˆ
Ø×Ò °ÐÑ5Ô5Ð5Ý”M /Ñ2Ô2ˆ	ØÐ!N¸yÐ!NÐ!NÐ!NÑNˆ	Ý
Œ�	Ð+Ñ,Ô,Ð,åÐg¸)ÐgÐgÐN^ÔNdÐgÐgÐgÑhÔhÐhð ×5Ò5°eÑ<Ô<ˆÝ&)¨)×*<Ò*<Ñ*>Ô*>Ñ&?Ô&?ˆ�NÑ#ð  ×8Ò8Ð9LÑMÔMÐØÐ'Ø*:Ð);ˆK˜Ñ&å
ŒÐxÐ*:Ô*@ÀÔ*CÐxÐxÐN^ÔNdÐefÔNgÐxÐxÐxÑyÔyÐyÝŒy‰{Œ{Ðs*   ˜AA) Á)BÁ8BÂBÂ+C ÃCÃCÚdata_urlc                 ó¾  — |sd S |}t          |t          ¦  «        rd|v r|                     dd¦  «        \  }}	 t          j        |¦  «        }t          j        t          j        |¦  «        ¦  «        5 }t          j
        |                     d¦  «        ¦  «        cd d d ¦  «         S # 1 swxY w Y   d S # t          $ r}t          d|› �¦  «         Y d }~d S d }~ww xY w)Nú,r¿   ÚRGBz:[MotionDesignerPlugin] Failed to decode background image: )r•   r�   Úsplitr�   r‘   r   ÚopenÚioÚBytesIOr   Úexif_transposeÚconvertr’   rœ   )r   rÉ   ÚpayloadrC   Úimage_bytesÚimgr¥   s          r   r˜   z-MotionDesignerPlugin._decode_background_imagek  sE  € Øð 	Ø�4ØˆÝ�g�sÑ#Ô#ð 	/¨¨w¨¨Ø Ÿš s¨AÑ.Ô.‰JˆAˆwð	Ý Ô*¨7Ñ3Ô3ˆKÝ”�BœJ {Ñ3Ô3Ñ4Ô4ð C¸ÝÔ.¨s¯{ª{¸5Ñ/AÔ/AÑBÔBðCð Cð Cð Cñ Cô Cð Cð Cð Cð Cð Cð Cøøøð Cð Cð Cð Cð Cð Cøåð 	ð 	ð 	ÝÐTÈsÐTÐTÑUÔUÐUØ�4�4�4�4�4øøøøð	øøøs;   º:B5 Á4'B(ÂB5 Â(B,Â,B5 Â/B,Â0B5 Â5
CÂ?CÃCÚsource_pathr~   c           	      óf  — t          |t          t          f¦  «        r|rt          t          |¦  «        d¦  «        nd}|                     d¦  «        }	  t          j        t          |¦  «        ¦  «        j        t          |¦  «        fd|dœdddd dœ¤Ž 	                    ¦   «          
                    d	¬
¦  «         |                     ¦   «         r|                     ¦   «          |                     |¦  «         n·# t
          j        $ r�}t          |dd¦  «        }t          |t           t"          f¦  «        r|                     dd¬¦  «        nt          |¦  «        }t'          d|                     ¦   «         › �¦  «         Y d }~n,d }~wt*          $ r}t'          d|› �¦  «         Y d }~nd }~ww xY w|S )Nr¿   é   z.clean.webmÚcopy)ÚcÚrÚcfrz+genpts)ÚvsyncÚfps_modeÚfflagsÚcopytsT)ÚquietÚstderrr   úutf-8Úignore)Úerrorsz=[MotionDesignerPlugin] FFmpeg failed to sanitize mask video: zE[MotionDesignerPlugin] Unexpected error while sanitizing mask video: )r•   ÚintÚfloatÚmaxÚwith_suffixÚffmpegÚinputr�   ÚoutputÚoverwrite_outputÚrunÚexistsÚunlinkÚreplacerŽ   ÚgetattrÚbytesÚ	bytearrayÚdecoderœ   r�   r’   )	r   rÖ   r~   Ú
frame_rateÚ	temp_pathÚerrrâ   Údecodedr¥   s	            r   rŸ   z%MotionDesignerPlugin._transcode_videoy  sô  € Ý)3°C½#½u¸Ñ)FÔ)FÐVÈ3ÐV•S�˜S™œ 1Ñ%Ô%Ð%ÐTVˆ
Ø×+Ò+¨MÑ:Ô:ˆ	ð	að•Ü•s˜;Ñ'Ô'ñ)ô )äÝ˜	‘N”Nðð Ø ðð ð "'Ø$)Ø"+Ø"&ð	ð ðð ÷ "Ò!Ñ#Ô#ß’˜4�‘”�à×!Ò!Ñ#Ô#ð %Ø×"Ò"Ñ$Ô$Ð$Ø×Ò˜kÑ*Ô*Ð*Ð*øÝŒ|ð 	eð 	eð 	eÝ˜S (¨CÑ0Ô0ˆFÝAKÈFÕUZÕ\eÐTfÑAgÔAgÐx�f—m’m G°H�mÑ=Ô=Ð=ÕmpÐqwÑmxÔmxˆGÝÐcÐRY×R_ÒR_ÑRaÔRaÐcÐcÑdÔdÐdÐdÐdÐdÐdÐdøøøøÝð 	að 	að 	aÝÐ_ÐZ]Ð_Ð_Ñ`Ô`Ð`Ð`Ð`Ð`Ð`Ð`øøøøð	aøøøàÐs&   ÁB%C: Ã:F.Ä	A7FÆF.ÆF)Æ)F.Ú
video_pathc                 óþ  — |r|                      ¦   «         sdS t          d¦  «        }|                      ¦   «         st          d¦  «        }t          |¦  «        dddddd	d
ddt          |¦  «        g}	 t          j        |ddd¬¦  «        }|j        pd                     ¦   «                              ¦   «         }d }d }|D ]«}|                     ¦   «                              ¦   «         r$t          |                     ¦   «         ¦  «        }	|	}ŒLd|v r[| 
                    d¦  «        \  }
}}	 t          |
¦  «        }t          |¦  «        }|dk    r||z  }Œ”# t          t          f$ r Y Œ§w xY wŒ¬||fS # t          $ r Y dS w xY w)N)NNzffprobe.exeÚffprobez-vÚerrorz-select_streamszv:0z-count_framesz-show_entriesz;stream=nb_read_frames,nb_frames,avg_frame_rate,r_frame_ratez-ofz"default=noprint_wrappers=1:nokey=1TF)Úcapture_outputÚtextÚcheckr}   ú/r   )rï   r   r�   Ú
subprocessrî   Ústdoutr�   Ú
splitlinesÚisdigitræ   Ú	partitionrç   Ú
ValueErrorÚZeroDivisionErrorr’   )r   rú   Úffprobe_pathÚcmdÚresultrì   Úframe_countÚfps_valÚlineÚvalÚnumrC   ÚdenomÚnÚds                  r   Ú_probe_frames_fpsz&MotionDesignerPlugin._probe_frames_fpsš  s¾  € Øð 	  ×!2Ò!2Ñ!4Ô!4ð 	 Ø�<Ý˜MÑ*Ô*ˆØ×"Ò"Ñ$Ô$ð 	+Ý 	™?œ?ˆLå�ÑÔØØØØØØØIØØ0Ý�
‰OŒOð
ˆð	 Ý”^ C¸À4ÈuÐUÑUÔUˆFØ”mÐ) r×0Ò0Ñ2Ô2×=Ò=Ñ?Ô?ˆFàˆKØˆGØð !ð !�Ø—:’:‘<”<×'Ò'Ñ)Ô)ð !å˜dŸjšj™lœlÑ+Ô+�CØ"%�K�KØ˜D�[�[Ø$(§N¢N°3Ñ$7Ô$7‘M�C˜˜Eð!Ý! #™JœJ˜Ý! %™LœL˜Ø š6˜6Ø&'¨!¡e˜GøøÝ&Õ(9Ð:ð !ð !ð !Ø ˜ð!øøøð !ð   Ð)Ð)øÝð 	 ð 	 ð 	 Ø�<�<ð	 øøøs7   Á3B4E. Ä()EÅE. ÅE&Å#E. Å%E&Å&E. Å.
E<Å;E<r   r¦   c                 ó<  — d }t          |t          ¦  «        r@|                     d¦  «        }t          |t          t          f¦  «        rt          |¦  «        }|                      |¦  «        \  }}|�|€d S ||k    r t          d|› d|› d|› d|pd› d�	¦  «         d S d S )NÚexpectedFramesz0[MotionDesignerPlugin] Frame count mismatch for z: expected z, got z (fps probed: zn/ar½   )r•   r–   rj   ræ   rç   r  rœ   )r   r   rú   r¦   Úexpected_framesÚexpÚactual_framesr~   s           r   r    z%MotionDesignerPlugin._log_frame_checkÅ  sð   € ØˆÝ�h¥Ñ%Ô%ð 	+Ø—,’,Ð/Ñ0Ô0ˆCÝ˜#¥¥U˜|Ñ,Ô,ð +Ý"% c¡(¤(�Ø!×3Ò3°JÑ?Ô?Ñˆ�sØÐ" mÐ&;ØˆFØ˜mÒ+Ð+Ýð`À5ð `ð `Ø+ð`ð `Ø3@ð`ð `ØPSÐP\ÐW\ð`ð `ð `ñô ð ð ð ð ,Ð+r   c                 óà  — t          t          ¦  «        j        dz  }|dz  }|dz  }|dz  }d }	 |                     ¦   «         j        |                     ¦   «         j        |                     ¦   «         j        f}n# t
          $ r d }Y nw xY w| j        r|r|| j        k    r| j        S |                     d¬¦  «        }|                     d¬¦  «        }|                     d¬¦  «        }| 	                    dd|› d	�¦  «        }	|	 	                    d
d|› d�¦  «        }	t          j        |	                     d¦  «        ¦  «                             d¦  «        }
d|
› d�| _        || _        | j        S )NÚassetsz$motion_designer_iframe_template.htmlzapp.jsz	style.cssrã   )Úencodingz%<!-- MOTION_DESIGNER_STYLE_INLINE -->z<style>z</style>z&<!-- MOTION_DESIGNER_SCRIPT_INLINE -->z<script>z	</script>Úasciizå<iframe id='motion-designer-iframe' title='Motion Designer' sandbox='allow-scripts allow-same-origin allow-pointer-lock allow-downloads' style='width:100%;border:none;border-radius:12px;display:block;' src='data:text/html;base64,z'></iframe>)r   Ú__file__ÚparentÚstatÚst_mtime_nsÚFileNotFoundErrorr   r   Ú	read_textrñ   r�   Ú	b64encodeÚencoderõ   )r   Ú
assets_dirÚtemplate_pathÚscript_pathÚ
style_pathÚcache_signatureÚtemplate_htmlÚ	script_jsÚ	style_cssrT   Úencodeds              r   rG   z'MotionDesignerPlugin._get_iframe_markupÔ  s·  € Ý�(‘^”^Ô*¨XÑ5ˆ
Ø"Ð%KÑKˆØ  8Ñ+ˆØ +Ñ-ˆ
à7;ˆð	#à×"Ò"Ñ$Ô$Ô0Ø× Ò Ñ"Ô"Ô.Ø—’Ñ!Ô!Ô-ðˆOˆOøõ
 !ð 	#ð 	#ð 	#Ø"ˆOˆOˆOð	#øøøð Ô#ð	+àð	+ð   4Ô#?Ò?Ð?àÔ*Ð*à%×/Ò/¸Ð/ÑAÔAˆØ×)Ò)°7Ð)Ñ;Ô;ˆ	Ø×(Ò(°'Ð(Ñ:Ô:ˆ	à#×+Ò+Ð,SÐUrÐ_hÐUrÐUrÐUrÑsÔsˆØ!×)Ò)Ð*RÐTsÐ_hÐTsÐTsÐTsÑtÔtˆåÔ" ;×#5Ò#5°gÑ#>Ô#>Ñ?Ô?×FÒFÀwÑOÔOˆð?ð +2ð	?ð ?ð ?ð 	Ôð (7ˆÔ$ØÔ&Ð&s   ¯A
A: Á:B	ÂB	c                 ó   — dS )NaS.  
    const MOTION_DESIGNER_EVENT_TYPE = "WAN2GP_MOTION_DESIGNER";
    const MOTION_DESIGNER_CONTROL_MESSAGE_TYPE = "WAN2GP_MOTION_DESIGNER_CONTROL";
    const MOTION_DESIGNER_MODE_INPUT_SELECTOR = "#motion_designer_mode_sync textarea, #motion_designer_mode_sync input";
    const MOTION_DESIGNER_IFRAME_SELECTOR = "#motion-designer-iframe";
    const MOTION_DESIGNER_MODAL_LOCK = "WAN2GP_MOTION_DESIGNER_MODAL_LOCK";
    const MODAL_PLACEHOLDER_ID = "motion-designer-iframe-placeholder";
    let modalLockState = {
        locked: false,
        scrollX: 0,
        scrollY: 0,
        placeholder: null,
        prevStyles: {},
        unlockTimeout: null,
    };
    console.log("[MotionDesignerPlugin] Bridge script injected");

    function motionDesignerRoot() {
        if (window.gradioApp) {
            return window.gradioApp();
        }
        const app = document.querySelector("gradio-app");
        return app ? (app.shadowRoot || app) : document;
    }

    function motionDesignerDispatchInput(element, value) {
        if (!element) {
            return;
        }
        element.value = value;
        element.dispatchEvent(new Event("input", { bubbles: true }));
    }

    function motionDesignerTriggerButton(appRoot) {
        return appRoot.querySelector("#motion_designer_apply_trigger button, #motion_designer_apply_trigger");
    }

    function motionDesignerGetIframe() {
        return document.querySelector(MOTION_DESIGNER_IFRAME_SELECTOR);
    }

    function motionDesignerSendControlMessage(action, value) {
        const iframe = motionDesignerGetIframe();
        if (!iframe || !iframe.contentWindow) {
            console.warn("[MotionDesignerPlugin] Unable to locate Motion Designer iframe for", action);
            return;
        }
        console.debug("[MotionDesignerPlugin] Posting control message", action, value);
        iframe.contentWindow.postMessage(
            { type: MOTION_DESIGNER_CONTROL_MESSAGE_TYPE, action, value },
            "*",
        );
    }

    function motionDesignerExtractMode(value) {
        if (!value) {
            return "";
        }
        return value.split("|", 1)[0]?.trim().toLowerCase() || "";
    }

    window.motionDesignerSetRenderMode = (mode) => {
        const normalized = motionDesignerExtractMode(mode);
        if (!normalized) {
            return;
        }
        let target;
        if (normalized === "classic") {
            target = "classic";
        } else if (normalized === "trajectory") {
            target = "trajectory";
        } else {
            target = "cut_drag";
        }
        console.log("[MotionDesignerPlugin] Mode sync triggered:", target);
        motionDesignerSendControlMessage("setMode", target);
    };

    window.addEventListener("message", (event) => {
        if (event?.data?.type === "WAN2GP_MOTION_DESIGNER_RESIZE") {
            if (typeof event.data.height === "number") {
                const iframe = document.querySelector("#motion-designer-iframe");
                if (iframe) {
                    iframe.style.height = `${Math.max(event.data.height, 400)}px`;
                }
            }
            return;
        }
        if (event?.data?.type === MOTION_DESIGNER_MODAL_LOCK) {
            const iframe = document.querySelector(MOTION_DESIGNER_IFRAME_SELECTOR);
            if (!iframe) {
                return;
            }
            const lock = Boolean(event.data.open);
            const clearUnlockTimeout = () => {
                if (modalLockState.unlockTimeout) {
                    clearTimeout(modalLockState.unlockTimeout);
                    modalLockState.unlockTimeout = null;
                }
            };
            if (lock) {
                clearUnlockTimeout();
                if (modalLockState.locked) {
                    return;
                }
                modalLockState.locked = true;
                modalLockState.scrollX = window.scrollX;
                modalLockState.scrollY = window.scrollY;
                const rect = iframe.getBoundingClientRect();
                const placeholder = document.createElement("div");
                placeholder.id = MODAL_PLACEHOLDER_ID;
                placeholder.style.width = `${rect.width}px`;
                placeholder.style.height = `${iframe.offsetHeight}px`;
                placeholder.style.pointerEvents = "none";
                placeholder.style.flex = iframe.style.flex || "0 0 auto";
                iframe.insertAdjacentElement("afterend", placeholder);
                modalLockState.placeholder = placeholder;
                modalLockState.prevStyles = {
                    position: iframe.style.position,
                    top: iframe.style.top,
                    left: iframe.style.left,
                    right: iframe.style.right,
                    bottom: iframe.style.bottom,
                    width: iframe.style.width,
                    height: iframe.style.height,
                    maxHeight: iframe.style.maxHeight,
                    zIndex: iframe.style.zIndex,
                };
                iframe.style.position = "fixed";
                iframe.style.top = "0";
                iframe.style.left = `${rect.left}px`;
                iframe.style.right = "auto";
                iframe.style.bottom = "auto";
                iframe.style.width = `${rect.width}px`;
                iframe.style.height = "100vh";
                iframe.style.maxHeight = "100vh";
                iframe.style.zIndex = "2147483647";
                document.documentElement.classList.add("modal-open");
                document.body.classList.add("modal-open");
            } else {
                clearUnlockTimeout();
                modalLockState.unlockTimeout = setTimeout(() => {
                    if (!modalLockState.locked) {
                        return;
                    }
                    modalLockState.locked = false;
                    iframe.style.position = modalLockState.prevStyles.position || "";
                    iframe.style.top = modalLockState.prevStyles.top || "";
                    iframe.style.left = modalLockState.prevStyles.left || "";
                    iframe.style.right = modalLockState.prevStyles.right || "";
                    iframe.style.bottom = modalLockState.prevStyles.bottom || "";
                    iframe.style.width = modalLockState.prevStyles.width || "";
                    iframe.style.height = modalLockState.prevStyles.height || "";
                    iframe.style.maxHeight = modalLockState.prevStyles.maxHeight || "";
                    iframe.style.zIndex = modalLockState.prevStyles.zIndex || "";
                    if (modalLockState.placeholder?.parentNode) {
                        modalLockState.placeholder.parentNode.removeChild(modalLockState.placeholder);
                    }
                    modalLockState.placeholder = null;
                    modalLockState.prevStyles = {};
                    document.documentElement.classList.remove("modal-open");
                    document.body.classList.remove("modal-open");
                    window.scrollTo(modalLockState.scrollX, modalLockState.scrollY);
                }, 120);
            }
            return;
        }
        if (!event?.data || event.data.type !== MOTION_DESIGNER_EVENT_TYPE) {
            return;
        }
        console.debug("[MotionDesignerPlugin] Received iframe payload", event.data);
        const appRoot = motionDesignerRoot();

        // Handle trajectory export separately
        if (event.data.isTrajectoryExport) {
            const trajectoryInput = appRoot.querySelector("#motion_designer_trajectory_payload textarea, #motion_designer_trajectory_payload input");
            const trajectoryMetaInput = appRoot.querySelector("#motion_designer_trajectory_meta textarea, #motion_designer_trajectory_meta input");
            const trajectoryBgInput = appRoot.querySelector("#motion_designer_trajectory_background textarea, #motion_designer_trajectory_background input");
            const trajectoryButton = appRoot.querySelector("#motion_designer_trajectory_trigger button, #motion_designer_trajectory_trigger");
            if (!trajectoryInput || !trajectoryMetaInput || !trajectoryBgInput || !trajectoryButton) {
                console.warn("[MotionDesignerPlugin] Trajectory bridge components missing in Gradio DOM.");
                return;
            }
            const trajectoryData = event.data.trajectoryData || [];
            const trajectoryMetadata = event.data.metadata || {};
            const backgroundImage = event.data.backgroundImage || "";
            motionDesignerDispatchInput(trajectoryInput, JSON.stringify(trajectoryData));
            motionDesignerDispatchInput(trajectoryMetaInput, JSON.stringify(trajectoryMetadata));
            motionDesignerDispatchInput(trajectoryBgInput, backgroundImage);
            trajectoryButton.click();
            return;
        }

        const maskInput = appRoot.querySelector("#motion_designer_mask_payload textarea, #motion_designer_mask_payload input");
        const metaInput = appRoot.querySelector("#motion_designer_meta_payload textarea, #motion_designer_meta_payload input");
        const bgInput = appRoot.querySelector("#motion_designer_background_payload textarea, #motion_designer_background_payload input");
        const guideInput = appRoot.querySelector("#motion_designer_guide_payload textarea, #motion_designer_guide_payload input");
        const guideMetaInput = appRoot.querySelector("#motion_designer_guide_meta_payload textarea, #motion_designer_guide_meta_payload input");
        const button = motionDesignerTriggerButton(appRoot);
        if (!maskInput || !metaInput || !bgInput || !guideInput || !guideMetaInput || !button) {
            console.warn("[MotionDesignerPlugin] Bridge components missing in Gradio DOM.");
            return;
        }

        const payload = event.data.payload || "";
        const metadata = event.data.metadata || {};
        const backgroundImage = event.data.backgroundImage || "";
        const guidePayload = event.data.guidePayload || "";
        const guideMetadata = event.data.guideMetadata || {};

        motionDesignerDispatchInput(maskInput, payload);
        motionDesignerDispatchInput(metaInput, JSON.stringify(metadata));
        motionDesignerDispatchInput(bgInput, backgroundImage);
        motionDesignerDispatchInput(guideInput, guidePayload);
        motionDesignerDispatchInput(guideMetaInput, JSON.stringify(guideMetadata));
        button.click();
    });

    function motionDesignerBindModeInput() {
        const appRoot = motionDesignerRoot();
        if (!appRoot) {
            setTimeout(motionDesignerBindModeInput, 300);
            return;
        }
        const input = appRoot.querySelector(MOTION_DESIGNER_MODE_INPUT_SELECTOR);
        if (!input) {
            setTimeout(motionDesignerBindModeInput, 300);
            return;
        }
        if (input.dataset.motionDesignerModeBound === "1") {
            return;
        }
        input.dataset.motionDesignerModeBound = "1";
        let lastValue = "";
        const handleChange = () => {
            const rawValue = input.value || "";
            const extracted = motionDesignerExtractMode(rawValue);
            if (!extracted || extracted === lastValue) {
                return;
            }
            lastValue = extracted;
            window.motionDesignerSetRenderMode(extracted);
        };
        const observer = new MutationObserver(handleChange);
        observer.observe(input, { attributes: true, attributeFilter: ["value"] });
        input.addEventListener("input", handleChange);
        handleChange();
    }

    motionDesignerBindModeInput();
    console.log("[MotionDesignerPlugin] Bridge initialization complete");
rB   r'   s    r   r$   zMotionDesignerPlugin._js_bridgeü  s   € ð{ð {r   )Ú__name__Ú
__module__Ú__qualname__r   r(   r&   r–   r�   ro   rQ   rN   r˜   r   ræ   rç   rŸ   Útupler  Úobjectr    rG   r$   Ú__classcell__)r   s   @r   r   r      s$  ø€ € € € € ðIð Ið Ið Ið Ið
ð 
ð 
ðD*ð D*ð D*ðL+ 4ð +¨Cð +ð +ð +ð +ðuð ˜T‘zðuð ˜T‘zð	uð
  # T™zðuð  ™*ðuð ! 4™Zðuð uð uð uðn5ð ˜t™ð5ð ˜T‘zð	5ð
 ! 4™Zð5ð 5ð 5ð 5ðn°°t±ð ð ð ð ð¨Dð °s¸U±{ÀTÑ7Ið Èdð ð ð ð ðB) ¨Dð ) °U¸3À¹:ÀuÈtÁ|Ð;SÔ5Tð ) ð ) ð ) ð ) ðV cð °tð ÀtÈCÐQWÈKÔGXÐ[_ÑG_ð ð ð ð ð&' Cð &'ð &'ð &'ð &'ðP|˜Cð |ð |ð |ð |ð |ð |ð |ð |r   r   )r�   rÏ   r“   r  rl   Úpathlibr   rê   ÚgradiorH   ÚnumpyrÁ   ÚPILr   r   Úshared.utils.pluginsr   r   rB   r   r   ú<module>r;     sÐ   ðà €€€Ø 	€	€	€	Ø €€€Ø Ð Ð Ð Ø €€€Ø Ð Ð Ð Ð Ð à €€€Ø Ð Ð Ð Ø Ð Ð Ð Ø Ð Ð Ð Ð Ð Ð Ð à -Ð -Ð -Ð -Ð -Ð -ðgð gð gð gð g˜<ñ gô gð gð gð gr   