§
    �M§j'˜  ã                   ó<  — d dl Z 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 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Zd dlZd dlmZ d dlmZ d dlmZmZ dZd	d
gdfddgdfddgdfddgdfddgdfddgdfddgdfddgdfddgdfddgdfddgdfddgdfdd	gdfd
d	gdfdd	gdfdœZi dddgdf“dddgdf“ddd gdf“d!dd"gdf“d#ddgdf“d$dd
gdf“d%ddgdf“d&ddgdf“d'ddgdf“d(ddgdf“d)ddgdf“d*ddgdf“d+d
dgdf“d,ddgdf“d-d.dgdf“d/d"dgdf“d0d1dgdf“d2dgdfd3dgdfd4dgdfd5dgdfd6œ¥Zd7„ Zdnd9„Zdod:„Z d;„ Z!dpd=„Z"d>„ Z# G d?„ d@ej$        ¦  «        Z%dqdC„Z&	 	 	 	 	 	 	 drdI„Z'dsdL„Z( G dM„ dN¦  «        Z)dOej*        dPej*        fdQ„Z+	 	 	 dtdTej*        dUej*        dVe)dWe,dXe,f
dY„Z-dZej*        d[ej*        d\e,d]ej*        fd^„Z.d dlmZ d d_l/m0Z0 d d`l1m2Z2m3Z3 	 	 	 dudZej*        dbej*        dcej*        d\e,dde4dee5dfe5d]ej*        fdg„Z6dh„ Z7di„ Z8dj„ Z9dk„ Z:dl„ Z;dm„ Z<dS )vé    N)Ú	rearrange)r   Úrepeat)Ú	lru_cache)Útqdm)Úcolor)Ú	get_cacheÚclear_caches)ú.mp4z.aviz.movz.mkvi@  iÀ  é   i€  i   iÀ  i€  i   i   i@  iÀ  i€  i@  iÀ  i@  i€  i   )z0.26z0.38z0.50z0.67z0.82ú1.00z1.22ú1.50z1.86z2.00z2.50z2.83z3.60z3.80z4.00z0.22i   z0.29i   z0.36i@  z0.45i€  z0.55z0.63z0.76z0.88r   z1.14z1.31r   z1.58z1.82z1.91i@  z2.20z2.30iÀ  i   i€  i@  i€  )z2.67z2.89z3.62z3.75c                  ó~   — t           j                             ¦   «          t           j                             ¦   «          d S ©N)ÚtorchÚcudaÚempty_cacheÚipc_collect© ó    úLC:\Users\johnn\OneDrive\Documents\AI\models\wan\multitalk\multitalk_utils.pyÚtorch_gcr   '   s0   € Ý	„J×ÒÑÔÐÝ	„J×ÒÑÔÐÐÐr   ç:Œ0âŽyE>c                 óL   — |\  }}|\  }}| |z
  ||z
  |z   z  }|||z
  z  |z   }	|	S r   r   )
ÚcolumnÚsource_rangeÚtarget_rangeÚepsilonÚ
source_minÚ
source_maxÚnew_minÚnew_maxÚ
normalizedÚscaleds
             r   Únormalize_and_scaler$   ,   sH   € à)Ñ€J�
Ø#Ñ€GˆWà˜:Ñ%¨*°zÑ*AÀGÑ*KÑL€JØ˜7 WÑ,Ñ-°Ñ7€FØ€Mr   c                 ó~  — | j         }|                     |¦  «                             | j        ¦  «        }d| j        d         dz  z  }| |z  } |                      dd¦  «        } |                     dd¦  «        }| j        }|                      d|d         ¦  «        } |d         |j        d         z  dz  dz  }t          |d         |z  ¦  «        }	t          j        | |	¦  «        }
d„ |D ¦   «         }|
D ]Ã}||                     dd¦  «        z  }| 	                    d¦  «        }~|                     |¦  «        }|                     |¦  «        }t          |¦  «        D ]W\  }}|d	         }||z  }|                     d¦  «        |                     ¦   «         z  }||                              |¦  «         ŒX~ŒÄg }t          |¦  «        D ]`\  }}t          j        |d¬
¦  «        }|                     d|d         d¦  «                             d¦  «        }|                     |¦  «         Œat          j        |d¬
¦  «        S )Nç      ð?éÿÿÿÿç      à?r   é   éþÿÿÿi4*c                 ó   — g | ]}g ‘ŒS r   r   )Ú.0Ú_s     r   ú
<listcomp>z5calculate_x_ref_attn_map_per_head.<locals>.<listcomp>C   s   € Ð0Ð0Ð0˜!�2Ð0Ð0Ð0r   ©NNN.©Údimr   )ÚdtypeÚtoÚdeviceÚshapeÚ	transposeÚviewÚintr   ÚsplitÚsoftmaxÚ	enumerateÚsumÚappendÚconcatÚsqueeze)Úvisual_qÚref_kÚref_target_masksÚref_images_countÚ	attn_biasr2   ÚscaleÚvisual_q_shapeÚnumber_chunksÚ
chunk_sizeÚchunksÚ
maps_listsÚq_chunkÚattnÚx_ref_attn_map_sourceÚ	class_idxÚref_target_maskÚx_ref_attnmapÚx_ref_attn_mapsÚ	maps_listÚattn_map_fuses                        r   Ú!calculate_x_ref_attn_map_per_headrT   7   sS  € ØŒN€EØ�HŠH�U‰OŒO×Ò˜xœÑ/Ô/€EØ�(”. Ô$¨Ñ+Ñ+€EØ˜%Ñ€HØ×!Ò! ! QÑ'Ô'€HØ�OŠO˜A˜qÑ!Ô!€EØ”^€NØ�}Š}˜R °Ô!3Ñ5Ô5€HØ" 2Ô& u¤{°2¤Ñ6¸(ÑBÀQÑF€MÝ�n RÔ(¨=Ñ8Ñ9Ô9€JÝŒK˜ *Ñ-Ô-€FØ0Ð0Ð/Ð0Ñ0Ô0€JØð "ð "ˆØ˜Ÿš¨¨RÑ0Ô0Ñ0ˆØ $§¢¨RÑ 0Ô 0ÐØØ+×.Ò.¨uÑ5Ô5ÐØ 5× 8Ò 8¸Ñ ?Ô ?Ðå*3Ð4DÑ*EÔ*Eð 	8ð 	8Ñ&ˆI�Ø-Ð.CÔDˆOØ1°OÑCˆMØ)×-Ò-¨bÑ1Ô1°O×4GÒ4GÑ4IÔ4IÑIˆMØ�yÔ!×(Ò(¨Ñ7Ô7Ð7Ð7à!Ð!à€OÝ )¨*Ñ 5Ô 5ð 0ð 0Ñˆ	�9Ýœ Y°RÐ8Ñ8Ô8ˆØ%×*Ò*¨1¨n¸QÔ.?ÀÑDÔD×LÒLÈQÑOÔOˆØ×Ò Ñ/Ô/Ð/Ð/õ Œ<˜¨QÐ/Ñ/Ô/Ð/r   c                 óð  — | j         }|                     |¦  «                             | j        ¦  «        }d| j        d         dz  z  }| |z  } |                      dd¦  «        } |                     dd¦  «        }| |                     dd¦  «        z  }|                     d¦  «        }~g }|                     |¦  «        }|                     |¦  «        }t          |¦  «        D ]}\  }	}
|
d         }
||
z  }|                     d¦  «        |
                     ¦   «         z  }|                     ddd¦  «        }| 	                    d¦  «        }| 
                    |¦  «         Œ~~t          j        |d¬	¦  «        S )
Nr&   r'   r(   r   r)   r*   r/   r   r0   )r2   r3   r4   r5   r6   r:   r;   r<   ÚpermuteÚmeanr=   r   r>   )r@   rA   rB   rC   r2   rE   rL   rM   rQ   rN   rO   rP   s               r   Úcalculate_x_ref_attn_maprX   \   sy  € ØŒN€EØ�HŠH�U‰OŒO×Ò˜xœÑ/Ô/€EØ�(”. Ô$¨Ñ+Ñ+€EØ˜%Ñ€HØ×!Ò! ! QÑ'Ô'€HØ�OŠO˜A˜qÑ!Ô!€EØ�e—o’o b¨"Ñ-Ô-Ñ-€Dà ŸLšL¨Ñ,Ô,ÐØØ€OØ'×*Ò*¨5Ñ1Ô1ÐØ1×4Ò4°UÑ;Ô;Ðå&/Ð0@Ñ&AÔ&Að .ð .Ñ"ˆ	�?Ø)Ð*?Ô@ˆØ-°Ñ?ˆØ%×)Ò)¨"Ñ-Ô-°×0CÒ0CÑ0EÔ0EÑEˆØ%×-Ò-¨a°°AÑ6Ô6ˆØ%×*Ò*¨2Ñ.Ô.ˆØ×Ò˜}Ñ-Ô-Ð-Ð-àåŒ<˜¨QÐ/Ñ/Ô/Ð/r   é
   c           
      óþ  — |\  }}}||z  }	|	dk    rd}n
|	dk    rdnd}|dd…d|	…f         }|dk    rO| j         }
|                      |
d         |d¦  «        } | dd…|d…f         }  | j        |
d         dg|
d	d…         ¢R Ž } | j         \  }}}}|j         \  }}t          j        ||| j        | j        ¬
¦  «        }||z  }|dk    rTt          |¦  «        D ]C}t          | dd…dd…||dz   …dd…f         |dd…dd…||dz   …dd…f         ||¦  «        }||z  }ŒDn_t          |¦  «        D ]O}t          | dd…dd…||z  |dz   |z  …dd…f         |dd…dd…||z  |dz   |z  …dd…f         ||¦  «        }||z  }ŒP||z  }|S )z¤Args:
        query (torch.tensor): B M H K
        key (torch.tensor): B M H K
        shape (tuple): (N_t, N_h, N_w)
        ref_target_masks: [B, N_h * N_w]
    iä  rY   i  é   é(   Nr   r'   r*   )r2   r4   r   )	r5   Úreshaper   Úzerosr2   r4   ÚrangerT   rX   )r@   rA   r5   rB   Ú	split_numrC   ÚN_tÚN_hÚN_wÚ	x_seqlensrF   r-   Úseq_lensÚheadsÚ	class_numrQ   Úsplit_chunkÚiÚx_ref_attn_maps_perheads                      r   Úget_attn_map_with_targetrk   w   sÅ  € ð �M€Cˆˆcà�c‘	€IØ�DÒÐØˆ	ˆ	à# tÒ+Ð+�B�B°ˆ	à�a�a�a˜˜)˜�mÔ$€EØ˜!ÒÐØ!œˆØ×#Ò# N°1Ô$5°s¸BÑ?Ô?ˆØ˜A˜A˜AÐ/Ð0Ð0Ð0Ô1ˆØ#�8Ô# N°1Ô$5°rÐP¸NÈ2È3È3Ô<OÐPÐPÐPˆà$œNÑ€A€x�˜Ø#Ô)�L€IˆqÝ”k )¨X¸X¼^ÐT\ÔTcÐdÑdÔd€Oà˜9Ñ$€Kà�aÒÐÝ�yÑ!Ô!ð 	7ð 	7ˆAÝ&GÈÐQRÐQRÐQRÐTUÐTUÐTUÐWXÐZ[Ð\]ÑZ]ÐW^Ð`aÐ`aÐ`aÐQaÔHbÐdiÐjkÐjkÐjkÐmnÐmnÐmnÐpqÐstÐuvÑsvÐpwÐyzÐyzÐyzÐjzÔd{ð  ~Nð  P`ñ  'aô  'aÐ#ØÐ6Ñ6ˆOˆOð	7õ �yÑ!Ô!ð 	7ð 	7ˆAÝ&>¸xÈÈÈÈ1È1È1ÈaÐP[ÉmÐ]^Ð_`Ñ]`ÐbmÑ\mÐNmÐopÐopÐopÐHpÔ?qÐsxÐyzÐyzÐyzÐ|}Ð|}Ð|}ð  @Að  BMñ  @Mð  OPð  QRñ  ORð  T_ñ  N_ð  @_ð  abð  abð  abð  zbô  tcð  euð  wGñ  'Hô  'HÐ#ØÐ6Ñ6ˆOˆOà�yÑ €OØÐr   c                 óª   — t          | dd¬¦  «        } |                      d¬¦  «        \  }}t          j        | |fd¬¦  «        } t          | d¦  «        S )Nz... (d r) -> ... d rr)   ©Úrr'   r0   z... d r -> ... (d r))r   Úunbindr   Ústack)ÚxÚx1Úx2s      r   Úrotate_halfrt   ¡   sY   € Ý�!Ð+¨qÐ1Ñ1Ô1€AØ�XŠX˜"ˆXÑÔ�F€BˆÝŒ�b�S˜"�I 2Ð&Ñ&Ô&€AÝ�QÐ.Ñ/Ô/Ð/r   c                   ó,   ‡ — e Zd Zˆ fd„Zd„ Zdd„Zˆ xZS )ÚRotaryPositionalEmbedding1Dc                 ód   •— t          ¦   «                              ¦   «          || _        d| _        d S )Ni'  )ÚsuperÚ__init__Úhead_dimÚbase)Úselfrz   Ú	__class__s     €r   ry   z$RotaryPositionalEmbedding1D.__init__ª   s-   ø€ õ 	‰Œ×ÒÑÔÐØ ˆŒØˆŒ	ˆ	ˆ	r   c                 óN  — d| j         t          j        d| j        d¦  «        d | j        dz  …                              ¦   «         | j        z  z  z  }|                     |j        ¦  «        }t          j        d|                     ¦   «         |¦  «        }t          |dd¬¦  «        }|S )Nr&   r   r)   z..., f -> ... fz... n -> ... (n r)rm   )	r{   r   Úarangerz   Úfloatr3   r4   Úeinsumr   )r|   Úpos_indicesÚfreqss      r   Úprecompute_freqs_cis_1dz3RotaryPositionalEmbedding1D.precompute_freqs_cis_1d²   s™   € à�t”y¥U¤\°!°T´]ÀAÑ%FÔ%FÐG]È$Ì-Ð[\ÑJ\ÐG]Ô%^×%dÒ%dÑ%fÔ%fÐimÔivÑ%vÑwÑxˆØ—’˜Ô+Ñ,Ô,ˆÝ”Ð.°×0AÒ0AÑ0CÔ0CÀUÑKÔKˆÝ�uÐ2°aÐ8Ñ8Ô8ˆØˆr   Nc                 ó`  — |d         }|                      ¦   «          t          d¦  «        }|                     |d¦  «        }|€|                      |¦  «        x}||<   |                     ¦   «                              d¦  «                             d¦  «        |                     ¦   «                              d¦  «                             d¦  «        }}|j        }	|                     t          j
        ¦  «        }
d}t          |
¦  «        }|
|z  }
||z  }|
|z  }
~|
                     |	¦  «        }
|
S )zË1D RoPE.

        Args:
            query (torch.tensor): [B, head, seq, head_dim]
            pos_indices (torch.tensor): [seq,]
        Returns:
            query with the same shape as input.
        r   Úmultitalk_ropeN)Úclearr   Úgetr„   ÚcosÚ	unsqueezeÚsinr2   r3   r   r€   rt   )r|   Úqlistr‚   Úcache_entryÚxqÚcacheÚ	freqs_cisr‰   r‹   Úxq_dtypeÚxq_outÚxq_rots               r   Úforwardz#RotaryPositionalEmbedding1D.forwardº   s  € ð �!ŒHˆØ�Š‰ŒˆÝÐ*Ñ+Ô+ˆØ—9’9˜[¨$Ñ/Ô/ˆ	ØÐØ-1×-IÒ-IÈ+Ñ-VÔ-VÐVˆI˜˜kÑ*Ø—=’=‘?”?×,Ò,¨QÑ/Ô/×9Ò9¸!Ñ<Ô<¸i¿mºm¹o¼o×>WÒ>WÐXYÑ>ZÔ>Z×>dÒ>dÐefÑ>gÔ>gˆSˆð ”8ˆØ—’•u”{Ñ#Ô#ˆØˆÝ˜VÑ$Ô$ˆØ�#‰ˆØ�#‰ˆØ�&ÑˆØØ—’˜8Ñ$Ô$ˆØˆr   r   )Ú__name__Ú
__module__Ú__qualname__ry   r„   r”   Ú__classcell__)r}   s   @r   rv   rv   ¨   s[   ø€ € € € € ðð ð ð ð ðð ð ðð ð ð ð ð ð ð r   rv   é   Ú c                 óº   — t          j        t          j        | ¦  «        ¦  «                             d¦  «        }|r|                     d¦  «        sd|z   }||z  }|S )Nzutf-8ú.)ÚbinasciiÚb2a_hexÚosÚurandomÚdecodeÚ
startswith)ÚlengthÚsuffixÚnames      r   Ú	rand_namer¦   Ú   s_   € ÝÔ�BœJ vÑ.Ô.Ñ/Ô/×6Ò6°wÑ?Ô?€DØð Ø× Ò  Ñ%Ô%ð 	"Ø˜6‘\ˆFØ�‰ˆØ€Kr   é   r
   T©r'   r   é   c           	      ó¢  ‡‡‡— |€#t          j        dt          |¬¦  «        ¦  «        n|}d }	t          |¦  «        D �]}
|                      t          ‰¦  «        t          ‰¦  «        ¦  «        } t          j        ˆˆˆfd„|  	                    d¦  «        D ¦   «         d¬¦  «         
                    dddd¦  «        } | d	z                       t          j        ¦  «                             ¦   «         } t          j        ||d
dddg¬¦  «        }|                      ¦   «         D ]}|                     |¦  «         Œ|                     ¦   «          |c S d S )Nz/tmp)r¤   c                 óV   •— g | ]%}t           j                             |‰‰‰¬ ¦  «        ‘Œ&S ))ÚnrowÚ	normalizeÚvalue_range)ÚtorchvisionÚutilsÚ	make_grid)r,   Úur­   r¬   r®   s     €€€r   r.   zcache_video.<locals>.<listcomp>õ   sN   ø€ ð ð ð ð õ Ô!×+Ò+Ø˜D¨IÀ;ð ,ñ Pô Pðð ð r   r)   r   r0   é   r   éÿ   Úlibx264rY   ú-crfÚ10)ÚfpsÚcodecÚqualityÚffmpeg_params)ÚospÚjoinr¦   r_   ÚclampÚminÚmaxr   rp   ro   rV   ÚtypeÚuint8ÚcpuÚimageioÚ
get_writerÚnumpyÚappend_dataÚclose)ÚtensorÚ	save_filer¸   r¤   r¬   r­   r®   ÚretryÚ
cache_fileÚerrorr-   ÚwriterÚframes       ```      r   Úcache_videorÐ   â   s�  øøø€ ð %Ð,õ ”˜&¥)Øð#ñ #ô #ñ ô ð Ø2;ð ð €EÝ�5‰\Œ\ð ñ ˆð —’�c +Ñ.Ô.µ°KÑ0@Ô0@ÑAÔAˆÝ”ð ð ð ð ð ð ð  Ÿš qÑ)Ô)ðñ ô ð
 &'ð(ñ (ô (÷
 )0ª°°1°a¸Ñ(;Ô(;ð 	ð ˜3‘,×$Ò$¥U¤[Ñ1Ô1×5Ò5Ñ7Ô7ˆõ Ô# J°C¸yÐRTÐekÐmqÐdrÐsÑsÔsˆØ—\’\‘^”^ð 	&ð 	&ˆEØ×Ò˜uÑ%Ô%Ð%Ð%Ø�Š‰ŒˆØÐÐÐð#ð r   é   Fc                 ó@  — dd„}|dz   }|r)t          |                      d¦  «        ||ddd¬¦  «         n‰| dz   d	z  }|                     dd	d
d¦  «                             ¦   «                              ¦   «         }t          j        |dz  dd¦  «                             t
          j        ¦  «        } |||||¬¦  «         | j	        \  }	}
}	}	|
|z  }|dz   }dd|d         d|› |g}t          j        |d¬¦  «         |dz   }|rRddd|d|ddddddddd|g}t          j        |d¬¦  «         t          j        |¦  «         t          j        |¦  «         d S ddd|d|ddddd|g}t          j        |d¬¦  «         t          j        |¦  «         t          j        |¦  «         d S )Né	   c                 óØ   — t          j        ||||¬¦  «        }t          | d¬¦  «        D ]+}t          j        |¦  «        }|                     |¦  «         Œ,|                     ¦   «          d S )N)r¸   rº   r»   zSaving video)Údesc)rÄ   rÅ   r   ÚnpÚarrayrÇ   rÈ   )ÚframesÚ	save_pathr¸   rº   r»   rÎ   rÏ   s          r   Ú
save_videoz%save_video_ffmpeg.<locals>.save_video  su   € ÝÔ#Ø˜3¨¸}ð
ñ 
ô 
ˆõ ˜& ~Ð6Ñ6Ô6ð 	&ð 	&ˆEÝ”H˜U‘O”OˆEØ×Ò˜uÑ%Ô%Ð%Ð%Ø�Š‰Œˆˆˆr   z	-temp.mp4r   r   Tr¨   )rÉ   rÊ   r¸   r¬   r­   r®   r)   r³   r´   )r¸   rº   z-cropaudio.wavÚffmpegz-iz-t)Úcheckr
   z-yz-c:vrµ   r¶   Ú0z-presetÚveryslowz-c:aÚaacz	-shortest)rÓ   N)rÐ   rŠ   rV   rÃ   rÆ   rÖ   ÚclipÚastyperÂ   r5   Ú
subprocessÚrunrŸ   Úremove)Úgen_video_samplesrÙ   Úvocal_audio_listr¸   rº   Úhigh_quality_saverÚ   Úsave_path_tmpÚvideo_audior-   ÚTÚdurationÚsave_path_crop_audioÚfinal_commands                 r   Úsave_video_ffmpegrî     s5  € ðð ð ð ð  Ñ+€Màð IÝØ,×6Ò6°qÑ9Ô9Ø+ØØØ"Ø 'ð	ñ 	ô 	ð 	ð 	ð )¨Ñ*¨AÑ-ˆØ!×)Ò)¨!¨Q°°1Ñ5Ô5×9Ò9Ñ;Ô;×AÒAÑCÔCˆÝ”g˜k¨CÑ/°°CÑ8Ô8×?Ò?ÅÄÑIÔIˆØˆ
�; °3ÀÐHÑHÔHÐHð #Ô(�J€A€qˆ!ˆQØ�3‰w€HØ$Ð'7Ñ7ÐàØØ˜ÔØØˆØð€Mõ „N�=¨Ð-Ñ-Ô-Ð-à˜FÑ"€IØð !(àØØ�-ØÐ&Ø�IØ�CØ�zØ�EØØð
ˆõ 	Œ�}¨DÐ1Ñ1Ô1Ð1Ý
Œ	�-Ñ Ô Ð Ý
Œ	Ð&Ñ'Ô'Ð'Ð'Ð'ð ØØØØØ ØØØØØØð
ˆõ 	Œ�}¨DÐ1Ñ1Ô1Ð1Ý
Œ	�-Ñ Ô Ð Ý
Œ	Ð&Ñ'Ô'Ð'Ð'Ð'r   c                   ó0   — e Zd Zdefd„Zdej        fd„ZdS )ÚMomentumBufferÚmomentumc                 ó"   — || _         d| _        d S )Nr   ©rñ   Úrunning_average)r|   rñ   s     r   ry   zMomentumBuffer.__init__T  s   € Ø ˆŒØ ˆÔÐÐr   Úupdate_valuec                 ó8   — | j         | j        z  }||z   | _        d S r   ró   )r|   rõ   Únew_averages      r   ÚupdatezMomentumBuffer.updateX  s$   € Ø”m dÔ&:Ñ:ˆØ+¨kÑ9ˆÔÐÐr   N)r•   r–   r—   r€   ry   r   ÚTensorrø   r   r   r   rð   rð   S  sL   € € € € € ð! ð !ð !ð !ð !ð: 5¤<ð :ð :ð :ð :ð :ð :r   rð   Úv0Úv1c                 óL  — | j         }|                      ¦   «         |                     ¦   «         }} t          j        j                             |g d¢¬¦  «        }| |z                       g d¢d¬¦  «        |z  }| |z
  }|                     |¦  «        |                     |¦  «        fS )N©r'   r*   éýÿÿÿéüÿÿÿr0   T)r1   Úkeepdim)r2   Údoubler   ÚnnÚ
functionalr­   r<   r3   )rú   rû   r2   Úv0_parallelÚv0_orthogonals        r   Úprojectr  ^  sœ   € ð ŒH€EØ�YŠY‰[Œ[˜"Ÿ)š)™+œ+ˆ€BÝ	ŒÔ	×	&Ò	& rÐ/?Ð/?Ð/?Ð	&Ñ	@Ô	@€BØ˜‘7—-’-Ð$4Ð$4Ð$4¸d�-ÑCÔCÀbÑH€KØ˜Ñ$€MØ�>Š>˜%Ñ Ô  -×"2Ò"2°5Ñ"9Ô"9Ð9Ð9r   ç        é7   ÚdiffÚ	pred_condÚmomentum_bufferÚetaÚnorm_thresholdc                 ó>  — |�|                      | ¦  «         |j        } |dk    r]t          j        | ¦  «        }|                      dg d¢d¬¦  «        }t          d|› �¦  «         t          j        |||z  ¦  «        }| |z  } t          | |¦  «        \  }}	|	||z  z   }
|
S )Nr   r)   rý   T)Úpr1   r   zdiff_norm: )rø   rô   r   Ú	ones_likeÚnormÚprintÚminimumr  )r	  r
  r  r  r  ÚonesÚ	diff_normÚscale_factorÚdiff_parallelÚdiff_orthogonalÚnormalized_updates              r   Úadaptive_projected_guidancer  j  s¿   € ð Ð"Ø×Ò˜tÑ$Ô$Ð$ØÔ.ˆØ˜ÒÐÝŒ˜tÑ$Ô$ˆØ—I’I Ð'7Ð'7Ð'7À�IÑFÔFˆ	ÝÐ'˜IÐ'Ð'Ñ(Ô(Ð(Ý”} T¨>¸IÑ+EÑFÔFˆØ�lÑ"ˆÝ%,¨T°9Ñ%=Ô%=Ñ"€M�?Ø'¨#°Ñ*=Ñ=ÐØÐr   Úsource_chunkÚreference_imageÚstrengthÚreturnc           	      óÆ  — |dk    r| S d|cxk    rdk    sn t          d|› �¦  «        ‚| j        }| j        }|                      d¦  «                             dddd¦  «                             ¦   «                              ¦   «         }|                     d¦  «                             d¦  «                             ddd¦  «                             ¦   «                              ¦   «         }|dz   dz  }|dz   dz  }t          j        |dd¦  «        }t          j        |dd¦  «        }	 t          j
        |¦  «        }	n,# t           $ r}
t          d	|
› d
�¦  «         | cY d}
~
S d}
~
ww xY wg }t          |j        d         ¦  «        D �]×}||         }	 t          j
        |¦  «        }nB# t           $ r5}
t          d|› d|
› d�¦  «         |                     |¦  «         Y d}
~
Œ[d}
~
ww xY w|                     ¦   «         }t          d¦  «        D ]¾}|dd…dd…|f                              ¦   «         |dd…dd…|f                              ¦   «         }}|	dd…dd…|f                              ¦   «         |	dd…dd…|f                              ¦   «         }}|dk    r||dd…dd…|f<   Œ™|dd…dd…|f         |z
  ||z  z  |z   |dd…dd…|f<   Œ¿	 t          j        |¦  «        }nC# t           $ r6}
t          d|› d|
› d�¦  «         |                     |¦  «         Y d}
~
�Œ–d}
~
ww xY wt          j        |dd¦  «        }d|z
  |z  ||z  z   }|                     |¦  «         �ŒÙt          j        |d¬¦  «        }|dz  dz
  }t)          j        |¦  «                             dddd¦  «                             d¦  «        }|                     ¦   «         }|                     ||¬¦  «        }|S )aÂ  
    Matches the color of a source video chunk to a reference image and blends with the original.

    Args:
        source_chunk (torch.Tensor): The video chunk to be color-corrected (B, C, T, H, W) in range [-1, 1].
                                     Assumes B=1 (batch size of 1).
        reference_image (torch.Tensor): The reference image (B, C, 1, H, W) in range [-1, 1].
                                        Assumes B=1 and T=1 (single reference frame).
        strength (float): The strength of the color correction (0.0 to 1.0).
                          0.0 means no correction, 1.0 means full correction.

    Returns:
        torch.Tensor: The color-corrected and blended video chunk.
    r  r&   ú*Strength must be between 0.0 and 1.0, got r   r   r)   r³   ç       @z3Warning: Could not convert reference image to Lab: z+. Skipping color correction for this chunk.Nz(Warning: Could not convert source frame z	 to Lab: ú. Using original frame.z+Warning: Could not convert corrected frame z back to RGB: ©Úaxis©r4   r2   )Ú
ValueErrorr4   r2   r?   rV   rÃ   rÆ   rÖ   rà   r   Úrgb2labr  r_   r5   r=   ÚcopyrW   ÚstdÚlab2rgbrp   r   Ú
from_numpyrŠ   Ú
contiguousr3   )r  r  r  r4   r2   Ú	source_npÚref_npÚsource_np_01Ú	ref_np_01Úref_labÚeÚcorrected_frames_np_01ri   Úsource_frame_rgb_01Ú
source_labÚcorrected_lab_frameÚjÚmean_srcÚstd_srcÚmean_refÚstd_refÚfully_corrected_frame_rgb_01Úblended_frame_rgb_01Úcorrected_chunk_np_01Úcorrected_chunk_np_minus1_1Úcorrected_chunk_tensorÚoutput_tensors                              r   Úmatch_and_blend_colorsrB  ~  s»  € ð" �3‚€àÐà�(Ð!Ð!Ò!Ð!˜cÒ!Ð!Ð!Ð!ÝÐPÀhÐPÐPÑQÔQÐQàÔ €FØÔ€Eð ×$Ò$ QÑ'Ô'×/Ò/°°1°a¸Ñ;Ô;×?Ò?ÑAÔA×GÒGÑIÔI€Ià×$Ò$ QÑ'Ô'×/Ò/°Ñ2Ô2×:Ò:¸1¸aÀÑCÔC×GÒGÑIÔI×OÒOÑQÔQ€Fð  ‘O sÑ*€LØ˜#‘ Ñ$€Iõ ”7˜<¨¨cÑ2Ô2€LÝ”˜	 3¨Ñ,Ô,€IðÝ”- 	Ñ*Ô*ˆˆøÝð ð ð åÐrÀAÐrÐrÐrÑsÔsÐsØÐÐÐÐÐÐøøøøðøøøð  ÐÝ�<Ô% aÔ(Ñ)Ô)ð &<ñ &<ˆØ*¨1œoÐð	ÝœÐ':Ñ;Ô;ˆJˆJøÝð 	ð 	ð 	ÝÐc¸QÐcÐcÈÐcÐcÐcÑdÔdÐdØ"×)Ò)Ð*=Ñ>Ô>Ð>ØˆHˆHˆHˆHøøøøð	øøøð
 )ŸošoÑ/Ô/Ðõ �q‘”ð 	zð 	zˆAØ *¨1¨1¨1¨a¨a¨a°¨7Ô 3× 8Ò 8Ñ :Ô :¸JÀqÀqÀqÈ!È!È!ÈQÀwÔ<O×<SÒ<SÑ<UÔ<U�gˆHØ '¨¨¨¨1¨1¨1¨a¨Ô 0× 5Ò 5Ñ 7Ô 7¸ÀÀÀÀAÀAÀAÀqÀÔ9I×9MÒ9MÑ9OÔ9O�gˆHð ˜!Š|ˆ|ð 08Ð# A A A q q q¨! GÑ,Ð,à0CÀAÀAÀAÀqÀqÀqÈ!ÀGÔ0LÈxÑ0WÐ\cÐfmÑ\mÑ/nÐqyÑ/yÐ# A A A q q q¨! GÑ,Ð,ð	Ý+0¬=Ð9LÑ+MÔ+MÐ(Ð(øÝð 	ð 	ð 	ÝÐkÀÐkÐkÐQRÐkÐkÐkÑlÔlÐlØ"×)Ò)Ð*=Ñ>Ô>Ð>ØˆHˆHˆH‰Høøøøð	øøøõ (*¤wÐ/KÈSÐRUÑ'VÔ'VÐ$ð !" H¡Ð0CÑCÀhÐQmÑFmÑmÐØ×%Ò%Ð&:Ñ;Ô;Ð;Ñ;åœHÐ%;À!ÐDÑDÔDÐð $9¸3Ñ#>À#Ñ"EÐõ #Ô-Ð.IÑJÔJ×RÒRÐSTÐVWÐYZÐ\]Ñ^Ô^×hÒhÐijÑkÔkÐØ3×>Ò>Ñ@Ô@ÐØ*×-Ò-°VÀ5Ð-ÑIÔI€MàÐsN   Ä%D: Ä:
E#ÅEÅE#ÅE#ÆF#Æ#
G"Æ-+GÇG"ËKË
LË'+LÌL)Úndimage)Úbinary_erosionÚdistance_transform_edtÚ	correctedÚreference_videoÚmaskÚ	copy_modeÚsource_border_distanceÚreference_border_distancec           
      óÊ  — |dk    r| S d|cxk    rdk    sn t          d|› �¦  «        ‚|dvrt          d|› �¦  «        ‚| j        }| j        }| j        \  }	}
}}}|                     ¦   «         dk    rS|                     d¦  «                             d¦  «                             d¦  «                             |	d|||¦  «        }n…|                     ¦   «         d	k    r@|                     d¦  «                             d¦  «                             |	d|||¦  «        }n-|                     ¦   «         d
k    r|                     d¦  «        }|                      d¦  «                             ddd	d¦  «         	                    ¦   «          
                    ¦   «         }|                     d¦  «                             ddd	d¦  «         	                    ¦   «          
                    ¦   «         }|                     d¦  «                             d¦  «         	                    ¦   «          
                    ¦   «         }|dz   dz  }|dz   dz  }t          j        |dd¦  «        }t          j        |dd¦  «        }g }t          |¦  «        D �]Y}||         }||         }||         }t          |||¦  «        }|d         }|d         }	 t          ||¦  «        }t          ||¦  «        }nB# t           $ r5}t!          d|› d|› d�¦  «         |                     |¦  «         Y d}~Œ˜d}~ww xY wt%          |||||¦  «        }|dk    rt'          |||d¦  «        }nx|dk    rt'          |||d¦  «        }n_|dk    rYt)          ||||d         |d         |d         |¦  «        }t'          |||d¦  «        }t+          ||||d         |d         |¦  «        }|                     |¦  «         �Œ[t          j        |d¬¦  «        }|dz  dz
  } t/          j        | ¦  «                             d	ddd¦  «                             d¦  «        }!|!                     ¦   «         }!|!                     ||¬¦  «        }"|"S )u4  
    Matches the color of a source video chunk to a reference video using mask-based region sampling.

    Args:
        source_chunk (torch.Tensor): The video chunk to be color-corrected (B, C, T, H, W) in range [-1, 1].
                                     Assumes B=1 (batch size of 1).
        reference_video (torch.Tensor): The reference video (B, C, T, H, W) in range [-1, 1].
                                        Must have same temporal dimension as source_chunk.
        mask (torch.Tensor): Binary mask (B, 1, T, H, W) or (T, H, W) or (H, W) with values 0 and 1.
                            Color correction is applied to pixels where mask=1.
        strength (float): The strength of the color correction (0.0 to 1.0).
                          0.0 means no correction, 1.0 means full correction.
        copy_mode (str): What to do with mask=0 pixels: 
                        "corrected" (keep original), "reference", "source", 
                        "progressive_blend" (double-sided progressive blending near borders).
        source_border_distance (int): Distance in pixels from mask border to sample source video (mask=1 side).
        reference_border_distance (int): Distance in pixels from mask border to sample reference video (mask=0 side).
                                         For "progressive_blend" mode, this also defines the blending falloff distance.

    Returns:
        torch.Tensor: The color-corrected and blended video chunk.
        
    Notes:
        - Color statistics are sampled from border regions to determine source and reference tints
        - Progressive blending creates smooth double-sided transitions:
          * mask=1 side: 60% source + 40% reference at border â†’ 100% source deeper in
          * mask=0 side: 60% reference + 40% source at border â†’ 100% reference deeper in
    r  r&   r   )rF  Ú	referenceÚsourceÚprogressive_blendzRcopy_mode must be 'corrected', 'reference', 'source', or 'progressive_blend', got r)   r   r   r³   é   r!  Úsource_regionÚreference_regionz6Warning: Could not compute color statistics for frame z: r"  NrM  rN  rO  Úsource_distancesÚreference_distancesr#  r%  )r&  r4   r2   r5   r1   rŠ   Úexpandr?   rV   rÃ   rÆ   rÖ   rà   r_   Úget_border_sampling_regionsÚcompute_color_statsr  r=   Ú apply_color_correction_with_maskÚapply_copy_with_maskÚ)apply_progressive_blend_in_corrected_areaÚ)apply_progressive_blend_in_reference_arearp   r   r+  r,  r3   )#r  rG  rH  r  rI  rJ  rK  r4   r2   ÚBÚCrê   ÚHÚWr-  Úreference_npÚmask_npr/  Úreference_np_01r3  ÚtÚsource_frameÚreference_frameÚ
frame_maskÚborder_regionsÚsource_sample_regionÚreference_sample_regionÚsource_statsÚreference_statsr2  Úcorrected_framer>  r?  r@  rA  s#                                      r   Ú match_and_blend_colors_with_maskrm  ì  sÄ  € ðL �3‚€ØÐà�(Ð!Ð!Ò!Ð!˜cÒ!Ð!Ð!Ð!ÝÐPÀhÐPÐPÑQÔQÐQàÐQÐQÐQÝÐyÐnwÐyÐyÑzÔzÐzàÔ €FØÔ€EØ Ô&�M€A€qˆ!ˆQ�ð ‡x‚x�z„z�Q‚€Ø�~Š~˜aÑ Ô ×*Ò*¨1Ñ-Ô-×7Ò7¸Ñ:Ô:×AÒAÀ!ÀQÈÈ1ÈaÑPÔPˆˆØ	�Š‰Œ�qŠˆØ�~Š~˜aÑ Ô ×*Ò*¨1Ñ-Ô-×4Ò4°Q¸¸1¸aÀÑCÔCˆˆØ	�Š‰Œ�qŠˆØ�~Š~˜aÑ Ô ˆð ×$Ò$ QÑ'Ô'×/Ò/°°1°a¸Ñ;Ô;×?Ò?ÑAÔA×GÒGÑIÔI€IØ"×*Ò*¨1Ñ-Ô-×5Ò5°a¸¸A¸qÑAÔA×EÒEÑGÔG×MÒMÑOÔO€LØ�lŠl˜1‰oŒo×%Ò% aÑ(Ô(×,Ò,Ñ.Ô.×4Ò4Ñ6Ô6€Gð  ‘O sÑ*€LØ# cÑ)¨SÑ0€Oõ ”7˜<¨¨cÑ2Ô2€LÝ”g˜o¨s°CÑ8Ô8€OàÐå�1‰XŒXð -7ñ -7ˆØ# A”ˆØ)¨!Ô,ˆØ˜Q”Zˆ
õ 5°ZÐAWÐYrÑsÔsˆØ-¨oÔ>ÐØ"0Ð1CÔ"DÐð	Ý.¨|Ð=QÑRÔRˆLÝ1°/ÐCZÑ[Ô[ˆOˆOøÝð 	ð 	ð 	ÝÐjÈ1ÐjÐjÐPQÐjÐjÐjÑkÔkÐkØ"×)Ò)¨,Ñ7Ô7Ð7ØˆHˆHˆHˆHøøøøð	øøøõ ;Ø˜* l°OÀXñ
ô 
ˆð
 ˜Ò#Ð#Ý2°?ÀOÐU_ÐalÑmÔmˆOˆOØ˜(Ò"Ð"Ý2°?ÀLÐR\Ð^fÑgÔgˆOˆOØÐ-Ò-Ð-åGØ °*Ø˜Ô/°Ð@RÔ1SØÐ1Ô2Ð4Jñô ˆOõ 3°?ÀOÐU_ÐalÑmÔmˆOåGØ ¨zØÐ1Ô2°NÐCXÔ4YØ)ñô ˆOð 	×%Ò% oÑ6Ô6Ð6Ñ6åœHÐ%;À!ÐDÑDÔDÐð $9¸3Ñ#>À#Ñ"EÐÝ"Ô-Ð.IÑJÔJ×RÒRÐSTÐVWÐYZÐ\]Ñ^Ô^×hÒhÐijÑkÔkÐØ3×>Ò>Ñ@Ô@ÐØ*×-Ò-°VÀ5Ð-ÑIÔI€MàÐs   Ê? K Ë 
LË*+LÌLc                 ó¨   — |                       t          ¦  «        }t          |¦  «        }t          | ¦  «        }|||k    z  }| ||k    z  }||||dœS )aÈ  
    Create regions for sampling near mask borders with separate distances for source and reference.
    
    Args:
        mask: Binary mask (H, W) with 0s and 1s
        source_border_distance: Distance from border to include in source sampling (mask=1 side)
        reference_border_distance: Distance from border to include in reference sampling (mask=0 side)
        
    Returns:
        Dict with sampling regions and distance maps for blending
    )rQ  rR  rS  rT  )rá   ÚboolrE  )rH  rJ  rK  Ú	mask_boolÚdist_from_mask0Údist_from_mask1rQ  rR  s           r   rV  rV  q  sy   € ð —’�DÑ!Ô!€Iõ -¨YÑ7Ô7€Oõ -¨i¨ZÑ8Ô8€Oð  Ð4JÒ!JÑK€Mð #˜
 Ð:SÒ'SÑTÐð 'Ø,Ø+Ø.ð	ð ð r   c                 ó*  — t          j        |¦  «        st          d¦  «        ‚	 t          j        | ¦  «        }n$# t          $ r}t          d|› �¦  «        ‚d}~ww xY w||         }t          j        |d¬¦  «        t          j        |d¬¦  «        dœ}|S )a/  
    Compute color statistics (mean and std) for Lab channels in the sampling region.
    
    Args:
        image: RGB image (H, W, C) in range [0, 1]
        sample_region: Boolean mask (H, W) indicating pixels to sample
        
    Returns:
        Dict with 'mean' and 'std' for Lab components
    zNo pixels in sampling regionz Could not convert image to Lab: Nr   r#  )rW   r)  )rÖ   Úanyr&  r   r'  rW   r)  )ÚimageÚsample_regionÚ	image_labr2  Úsampled_pixelsÚstatss         r   rW  rW  ”  s»   € õ Œ6�-Ñ Ô ð 9ÝÐ7Ñ8Ô8Ð8ðAÝ”M %Ñ(Ô(ˆ	ˆ	øÝð Að Að AÝÐ?¸AÐ?Ð?Ñ@Ô@Ð@øøøøðAøøøð ˜}Ô-€Nõ ”˜¨QÐ/Ñ/Ô/ÝŒv�n¨1Ð-Ñ-Ô-ðð €Eð
 €Ls   ¥: º
AÁAÁAc                 ó¶  — 	 t          j        | ¦  «        }n,# t          $ r}t          d|› d�¦  «         | cY d}~S d}~ww xY w|                     ¦   «         }|dk    }t          d¦  «        D ]c}	|d         |	         }
|d         |	         }|d         |	         }|d         |	         }|dk    r||||	f<   ŒH|||	f         |
z
  ||z  z  |z   |||	f<   Œd	 t          j        |¦  «        }n,# t          $ r}t          d	|› d�¦  «         | cY d}~S d}~ww xY wt          j        |d
d¦  «        }|                      ¦   «         }d|z
  | |         z  |||         z  z   ||<   |S )aŽ  
    Apply color correction to pixels where mask=1.
    
    Args:
        source_frame: RGB image (H, W, C) in range [0, 1]
        mask: Binary mask (H, W)
        source_stats: Color statistics from source sampling region
        reference_stats: Color statistics from reference sampling region
        strength: Blending strength
        
    Returns:
        Corrected RGB image (H, W, C)
    z0Warning: Could not convert source frame to Lab: r"  Nr   r³   rW   r)  r   z8Warning: Could not convert corrected frame back to RGB: r  r&   )	r   r'  r&  r  r(  r_   r*  rÖ   rà   )rd  rH  rj  rk  r  r5  r2  Úcorrected_labÚcorrection_regionÚcr8  r9  r:  r;  Úfully_corrected_rgbÚresults                   r   rX  rX  ´  sð  € ðÝ”] <Ñ0Ô0ˆ
ˆ
øÝð ð ð ÝÐ[ÀÐ[Ð[Ð[Ñ\Ô\Ð\ØÐÐÐÐÐÐøøøøðøøøð —O’OÑ%Ô%€MØ šÐõ �1‰XŒXð ð ˆØ Ô'¨Ô*ˆØ˜uÔ% aÔ(ˆØ" 6Ô*¨1Ô-ˆØ! %Ô(¨Ô+ˆà�aŠ<ˆ<à2:ˆMÐ+¨QÐ.Ñ/Ð/ð Ð0°!Ð3Ô4°xÑ?ÀGÈgÑDUÑVÐYaÑað Ð+¨QÐ.Ñ/Ð/ðÝ#œm¨MÑ:Ô:ÐÐøÝð ð ð ÝÐcÈÐcÐcÐcÑdÔdÐdØÐÐÐÐÐÐøøøøðøøøõ
 œ'Ð"5°s¸CÑ@Ô@Ðð ×ÒÑ Ô €Fà	
ˆX‰˜Ð&7Ô8Ñ8ØÐ&Ð'8Ô9Ñ9ñ	:ð ÐÑð
 €Ms5   ‚ —
A ¡;µA »A ÃC& Ã&
DÃ0D
ÄDÄ
Dc                 ó,  — |                       ¦   «         }|}t          j        |¦  «        �rhddlm}	  |	|dk    t          j        d¦  «        ¬¦  «        }
|dk    |
z  }t          j        |¦  «        �r!t          j        t          j        |¦  «        ¦  «        }t          j        t          j        |¦  «        ¦  «        }ddlm	}  |||d¬¦  «        }t          j
        |d¬	¦  «        }t          j        ||         ¦  «        }t          j        ||         ¦  «        }||k    rq||         }||z
  ||z
  z  }d
d|z
  z  }t          |¦  «        D ]F\  }\  }}||         }||         \  }}||         }d|z
  | ||f         z  ||||f         z  z   |||f<   ŒG|S )a›  
    Apply progressive blending in the corrected area (mask=1) near the border.
    
    Args:
        corrected_frame: RGB image (H, W, C) - the color-corrected source frame
        reference_frame: RGB image (H, W, C) - the reference frame
        mask: Binary mask (H, W)
        source_region: Boolean mask (H, W) indicating the source blending region (mask=1 near border)
        source_distances: Distance map (H, W) into mask=1 area from mask=0 border
        reference_region: Boolean mask (H, W) indicating the reference sampling region (mask=0 near border)
        source_border_distance: Maximum distance for source blending
        
    Returns:
        Blended RGB image (H, W, C)
        
            Notes:
        - Each source pixel blends with its closest reference border pixel (for speed)
        - At mask border: 60% source + 40% reference
        - Deeper into mask=1 area: 100% corrected source
    r   ©Úbinary_dilationr   ©r³   r³   ©Ú	structure©ÚcdistÚ	euclidean©Úmetricr#  çš™™™™™Ù?r&   ©r(  rÖ   rt  Úscipy.ndimager‚  r  Úcolumn_stackÚwhereÚscipy.spatial.distancer‡  Úargminr¿   rÀ   r;   )rl  re  rH  rQ  rS  rR  rJ  r  Úblend_regionr‚  Úmask_1_dilatedÚborder_pixelsÚsource_coordsÚborder_coordsr‡  Údistances_matrixÚclosest_border_indicesÚmin_distance_in_regionÚmax_distance_in_regionÚsource_dist_valuesÚnormalized_distancesÚblend_weightsri   Úsource_yÚsource_xÚclosest_border_idxÚborder_yÚborder_xÚweights                                r   rZ  rZ  î  s   € ð* ×!Ò!Ñ#Ô#€Fð !€Lå	„vˆlÑÔñ 'ð 	2Ð1Ð1Ð1Ð1Ð1ð )˜¨°ª½b¼gÀf¹o¼oÐNÑNÔNˆØ š nÑ4ˆåŒ6�-Ñ Ô ñ 	åœO­B¬H°\Ñ,BÔ,BÑCÔCˆMÝœO­B¬H°]Ñ,CÔ,CÑDÔDˆMð 5Ð4Ð4Ð4Ð4Ð4Ø$˜u ]°MÈ+ÐVÑVÔVÐÝ%'¤YÐ/?ÀaÐ%HÑ%HÔ%HÐ"õ &(¤VÐ,<¸\Ô,JÑ%KÔ%KÐ"Ý%'¤VÐ,<¸\Ô,JÑ%KÔ%KÐ"à%Ð(>Ò>Ð>à%5°lÔ%CÐ"Ø(:Ð=SÑ(SÐXnð  rHñ  YHñ  (IÐ$Ø # sÐ-AÑ'AÑ B�õ 09¸Ñ/GÔ/Gð 	ð 	Ñ+�AÑ+˜ (Ø)?ÀÔ)BÐ&Ø)6Ð7IÔ)JÑ&�H˜hà*¨1Ô-�Fð ˜v™¨¸À8Ð9KÔ)LÑLØ °¸8Ð1CÔ!DÑDñEð ˜8 XÐ-Ñ.Ð.ð
 €Mr   c                 ó,  — |                       ¦   «         }|}t          j        |¦  «        �rhddlm}  ||dk    t          j        d¦  «        ¬¦  «        }	|dk    |	z  }
t          j        |
¦  «        �r!t          j        t          j        |¦  «        ¦  «        }t          j        t          j        |
¦  «        ¦  «        }ddlm	}  |||d¬¦  «        }t          j
        |d¬	¦  «        }t          j        ||         ¦  «        }t          j        ||         ¦  «        }||k    rq||         }||z
  ||z
  z  }d
d|z
  z  }t          |¦  «        D ]F\  }\  }}||         }||         \  }}||         }d|z
  | ||f         z  ||||f         z  z   |||f<   ŒG|S )aB  
    Apply progressive blending in the reference area (mask=0) near the border.
    
    Args:
        reference_frame: RGB image (H, W, C) - the reference frame with copied reference pixels
        source_frame: RGB image (H, W, C) - the original source frame
        mask: Binary mask (H, W)
        reference_region: Boolean mask (H, W) indicating the reference blending region (mask=0 near border)
        reference_distances: Distance map (H, W) into mask=0 area from mask=1 border
        reference_border_distance: Maximum distance for reference blending
        
    Returns:
        Blended RGB image (H, W, C)
        
    Notes:
        - Each reference pixel blends with its closest source border pixel (for speed)
        - At mask border: 60% reference + 40% source
        - Deeper into mask=0 area: 100% reference
    r   r�  rƒ  r„  r   r†  rˆ  r‰  r#  r‹  r&   rŒ  )re  rd  rH  rR  rT  rK  r  r’  r‚  Úmask_0_dilatedÚsource_border_pixelsÚreference_coordsÚsource_border_coordsr‡  r—  Úclosest_source_indicesr™  rš  Úreference_dist_valuesrœ  r�  ri   Úref_yÚref_xÚclosest_source_idxrž  rŸ  r£  s                               r   r[  r[  4  s  € ð( ×!Ò!Ñ#Ô#€Fð $€Lå	„vˆlÑÔñ &à1Ð1Ð1Ð1Ð1Ð1ð )˜¨°ª½b¼gÀf¹o¼oÐNÑNÔNˆØ $¨¢	¨^Ñ;ÐåŒ6Ð&Ñ'Ô'ñ 	å!œ­r¬x¸Ñ/EÔ/EÑFÔFÐÝ#%¤?µ2´8Ð<PÑ3QÔ3QÑ#RÔ#RÐ ð 5Ð4Ð4Ð4Ð4Ð4Ø$˜uÐ%5Ð7KÐT_Ð`Ñ`Ô`ÐÝ%'¤YÐ/?ÀaÐ%HÑ%HÔ%HÐ"õ &(¤VÐ,?ÀÔ,MÑ%NÔ%NÐ"Ý%'¤VÐ,?ÀÔ,MÑ%NÔ%NÐ"à%Ð(>Ò>Ð>à(;¸LÔ(IÐ%Ø(=Ð@VÑ(VÐ[qð  uKñ  \Kñ  (LÐ$Ø # sÐ-AÑ'AÑ B�õ *3Ð3CÑ)DÔ)Dð 	ð 	Ñ%�A‘~˜˜uØ)?ÀÔ)BÐ&Ø)=Ð>PÔ)QÑ&�H˜hà*¨1Ô-�Fð ˜v™¨¸À¸Ô)FÑFØ ¨h¸Ð.@Ô!AÑAñBð ˜5 %˜<Ñ(Ð(ð
 €Mr   c                 ó\   — |                       ¦   «         }|dk    }|dk    r||         ||<   |S )a6  
    Copy pixels to mask=0 regions based on copy_source parameter.
    
    Args:
        source_frame: RGB image (H, W, C)
        reference_frame: RGB image (H, W, C)
        mask: Binary mask (H, W)
        copy_source: "reference" or "source"
        
    Returns:
        Combined RGB image (H, W, C)
    r   rM  )r(  )rd  re  rH  Úcopy_sourcer  Úmask_0_regions         r   rY  rY  x  s?   € ð ×ÒÑ Ô €FØ˜Q’Y€Mà�kÒ!Ð!Ø /°Ô >ˆˆ}Ñð €Mr   )r   r   )NrY   r   )r™   rš   )Nr§   r
   r™   Tr¨   r©   )rÑ   r©   F)Nr  r  )rF  rY   rY   )=rŸ   Úeinopsr   r   Útorch.nnr  r   Ú	functoolsr   rÄ   Úuuidr   rÆ   rÖ   râ   Ú	soundfileÚsfr¯   r�   Úos.pathÚpathr¼   Úskimager   Úmmgp.offloadr   r	   ÚVID_EXTENSIONSÚASPECT_RATIO_627ÚASPECT_RATIO_960r   r$   rT   rX   rk   rt   ÚModulerv   r¦   rÐ   rî   rð   rù   r  r€   r  rB  ÚscipyrC  r�  rD  rE  Ústrr8   rm  rV  rW  rX  rZ  r[  rY  r   r   r   ú<module>rÁ     s€  ðØ 	€	€	€	Ø Ð Ð Ð Ð Ð à €€€Ø Ð Ð Ð Ð Ð à $Ð $Ð $Ð $Ð $Ð $Ð $Ð $Ø Ð Ð Ð Ð Ð Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ø Ð Ð Ð Ø Ð Ð Ð Ø Ð Ð Ð Ø €€€Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0Ð 0à1€à�Dˆk˜1Ð¨¨d¨°QÐ'7À3ÈÀ*ÈaÀÐ\_ÐadÐ[eÐghÐZiØ�Cˆj˜!ˆ_¨¨c¨
°A À3ÈÀ*ÈaÀÐ\_ÐadÐ[eÐghÐZiØ�Cˆj˜!ˆ_¨¨c¨
°A À3ÈÀ*ÈaÀÐ\`ÐbeÐ[fÐhiÐZjØ�Sˆk˜1Ð¨¨s¨°QÐ'7À4ÈÀ+ÈqÐAQð	Sð SÐ ðØˆs�Dˆk˜1ÐðØ%¨¨d¨°QÐ'7ðØ9?À3ÈÀ+ÈqÐAQðØSYÐ]`ÐbfÐ\gÐijÐ[kðàˆs�Dˆk˜1Ððà%¨¨d¨°QÐ'7ðà9?À3ÈÀ+ÈqÐAQðàSYÐ]`ÐbfÐ\gÐijÐ[kðð ˆs�Cˆj˜!ˆ_ðð %¨¨c {°AÐ&6ðð 9?À$ÈÀÈaÐ@Pðð SYÐ\`ÐbeÐ[fÐhiÐZjðð ˆt�Sˆk˜1Ðð	ð  &¨¨s¨°QÐ'7ð	ð :@À4ÈÀ+ÈqÐAQð	ð TZÐ]aÐcfÐ\gÐijÐ[kð	ð
 ˆt�Sˆk˜1Ððð
 *.¨s¨°QÐ'7À4ÈÀ+ÈqÐAQÐ]aÐcfÐ\gÐijÐ[kØ�Sˆk˜1Ððð ð Ð ðð ð ð
ð ð ð ð#0ð #0ð #0ð #0ðJ0ð 0ð 0ð6'ð 'ð 'ð 'ðT0ð 0ð 0ð.ð .ð .ð .ð . "¤)ñ .ô .ð .ðdð ð ð ð ØØØØØ#Øð ð  ð  ð  ðDL(ð L(ð L(ð L(ð^:ð :ð :ð :ð :ñ :ô :ð :ð	:ØŒLð	:àŒLð	:ð 	:ð 	:ð 	:ð -1ØØ"$ðð Ø”ðà”\ðð *ðð ð	ð
  ðð ð ð ð(f¨¬ð fÈÌð fÐ`eð fÐjoÔjvð fð fð fð fðR Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø @Ð @Ð @Ð @Ð @Ð @Ð @Ð @ð !Ø"$Ø%'ðBð BØ”,ðBà”\ðBð Œ,ðBð ð	Bð
 ðBð  ðBð  #ðBð „\ðBð Bð Bð BðJ ð  ð  ðFð ð ð@7ð 7ð 7ðtCð Cð CðLAð Að AðHð ð ð ð r   