
    
3j                     H   S SK r S SKrS SKJr  S SKJr  S SKJr  S SKr	S SK
r
S SKrS SKrS SKrS SKJr  SSKJr  SSKJrJrJrJr  S	S
KJr  S3S\S\4S jjr " S S5      r " S S5      r " S S5      r " S S5      r " S S5      r  " S S5      r! " S S5      r" " S S5      r# " S S5      r$ " S  S!5      r% " S" S#5      r& " S$ S%5      r' " S& S'5      r( " S( S)5      r) " S* S+5      r* " S, S-5      r+S. r, " S/ S05      r- " S1 S25      r.\)\%\$\#\*\\\.\!\(\'\&\-\"\\+\ \/r/g)4    N)BytesIO)Path)Literal)Image   )log)EASINGSapply_easingglob_multiple
pil2tensor   )MTB_TransformImage	hex_colorbgrc                    ^  T R                  S5      m U(       a  [        U 4S jS 5       5      $ [        U 4S jS 5       5      $ )N#c              3   F   >#    U  H  n[        TXS -    S5      v   M     g7fr      Nint.0ir   s     B/home/wildlama/comfy/ComfyUI/custom_nodes/comfy_mtb/nodes/batch.py	<genexpr>hex_to_rgb.<locals>.<genexpr>   s$     FIqS11u-r22I   !)   r   r   c              3   F   >#    U  H  n[        TXS -    S5      v   M     g7fr   r   r   s     r   r   r      s$     B	1Yqq5)2..	r   )r   r   r   )lstriptuple)r   r   s   ` r   
hex_to_rgbr#      s8      %I
FIFFFB	BBB    c                   L    \ rS rSr\S 5       rSrSrSrS\	S\
S\\   4S	 jrS
rg)MTB_BatchFloatMath   c                 $    SSSS04/ SQSS04S.0$ )NrequiredBOOLEANdefaultF)addsubmuldivpowabsr,   )reverse	operation clss    r   INPUT_TYPESMTB_BatchFloatMath.INPUT_TYPES   s3     %	5'9:>&
 	
r$   FLOATSz	mtb/utilsexecuter2   r3   kwargsc                 $  ^	 / n[        UR                  5       5      nU(       a  US S S2   n[        US   5      nU H-  n[        U5      U:w  d  M  [        S[        U5       SU S35      e   U=S:X  a<    [	        U5       H)  m	[        U	4S jU 5       5      nUR                  U5        M+     U4$ =S:X  aH    [	        U5       H5  m	US   T	   [        U	4S	 jUS
S   5       5      -
  nUR                  U5        M7     U4$ =S:X  a8    [	        U5       H%  m	US   T	   US
   T	   -  nUR                  U5        M'     U4$ =S:X  a8    [	        U5       H%  m	US   T	   US
   T	   -  nUR                  U5        M'     U4$ =S:X  a8    [	        U5       H%  m	US   T	   US
   T	   -  nUR                  U5        M'     U4$ S:X  a7  [	        U5       H%  m	[        US   T	   5      nUR                  U5        M'     U4$  [        R                  " SU S35        U4$ )Nr   z/All values must have the same length (current: z, ref: )r,   c              3   ,   >#    U  H	  oT   v   M     g 7fNr4   r   vr   s     r   r   -MTB_BatchFloatMath.execute.<locals>.<genexpr>=   s      4t!1t   r-   c              3   ,   >#    U  H	  oT   v   M     g 7frA   r4   rB   s     r   r   rD   A   s     -EHqdHrE   r   r.   r/   r0   r1   zFor now this mode (z) is not implemented)
listvalueslen
ValueErrorrangesumappendr1   r   info)
selfr2   r3   r<   resvals	ref_countrC   resultr   s
            @r   r;   MTB_BatchFloatMath.execute,   s   FMMO$":DQL	A1v" Ec!fXWU^T__`a   y)A  4t 44FJJv& *4 v/ y)A!!WQZ#-EDH-E*EEFJJv& *, v' y)A!!WQZ$q'!*4FJJv& *$ v y)A!!WQZ$q'!*4FJJv& * v y)A$(GAJ$q'!*$<FJJv& * v y)A a_FJJv& * v .yk9MNOvr$   r4   N)__name__
__module____qualname____firstlineno__classmethodr7   RETURN_TYPESCATEGORYFUNCTIONboolstrrG   floatr;   __static_attributes__r4   r$   r   r&   r&      sC    	
 	
 LHH*t * *tE{ *r$   r&   c                   L    \ rS rSrSr\S 5       rSrSrSr	Sr
S\\   4S	 jrS
rg)MTB_BatchFloatNormalizeY   z*Normalize the values in the list of floatsc                     SSS00$ )Nr)   floatsr9   r4   r5   s    r   r7   #MTB_BatchFloatNormalize.INPUT_TYPES\   s     ;/
 	
r$   r9   )normalized_floats	mtb/batchr;   re   c                     [        U5      n[        U5      nU Vs/ s H  oDU-
  X2-
  -  PM     nn[        R                  " SU 35        [        R                  " SU 35        U4$ s  snf )NzFloats: zNormalized Floats: )minmaxr   debug)rO   re   	min_value	max_valuexrg   s         r   r;   MTB_BatchFloatNormalize.executeg   sy     K	K	 @F
?E!]y45v 	 
 			HVH%&		'(9':;<!##
s   A%r4   N)rU   rV   rW   rX   __doc__rY   r7   rZ   RETURN_NAMESr[   r\   rG   r_   r;   r`   r4   r$   r   rb   rb   Y   s>    4
 

 L)LHH$U$r$   rb   c                   h    \ rS rSrSr\S 5       rSrSrSr	Sr
S\S	\R                  S
\\   4S jrSrg)MTB_BatchTimeWrapw   z)Remap a batch using a time curve (FLOATS)c                     SSSSS.4SSS.0$ )	Nr)   INT   r   r+   rj   IMAGEr9   )target_countframescurver4   r5   s    r   r7   MTB_BatchTimeWrap.INPUT_TYPESz   s)     !&Bq(A B$$
 	
r$   )r{   r:   )imageinterpolated_floatsrh   r;   r|   r}   r~   c           
         [         R                  " SUR                   35        [         R                  " SU 35        [        U5      n[         R                  " SU 35        UR                  u  pVpx[         R                  " SU 35        [        R
                  " SSU5      n	[        R                  " U	[        R
                  " SS[        U5      5      U5      R                  5       n
[         R                  " SU
 35        U
 Vs/ s H
  oS-
  U-  PM     nn[         R                  " SU 35        U Vs/ s H  n[        [        U5      5      PM     nn[        R                  " USUS-
  5      n/ nU H&  nUR                  UU   R                  S5      5        M(     [        R                  " USS	9n[         R                  " S
UR                   35        UU
4$ s  snf s  snf )z>Apply time warping to a list of video frames based on a curve.zInput frames shape: zCurve: zTotal duration: zBatch Size: r   r   zInterpolated curve: zInterpolated frame indices: dimzWarped frames shape: )r   rl   shaperL   nplinspaceinterprI   tolistr   roundcliprM   	unsqueezetorchcat)rO   r|   r}   r~   total_durationBHWCnormalized_timesinterpolated_curvevalueinterpolated_frame_indicesidxrounded_indiceswarped_framesindexwarped_tensors                     r   r;   MTB_BatchTimeWrap.execute   s    			(78		GE7#$U		$^$456\\
a		L$%;;q!\:YYbkk!QE
;U

&( 	 			();(<=> *<&
);UeO); 	# &
 			01K0LMN (B
'ACc
O'A 	 
 ''/1a!e< $E  !8!8!;< % 		-Q7		)-*=*=)>?@122#&


s   G3Gr4   N)rU   rV   rW   rX   rq   rY   r7   rZ   rr   r[   r\   r   r   TensorrG   r_   r;   r`   r4   r$   r   rt   rt   w   sR    3
 
 'L3LHH&3&3).&3>B5k&3r$   rt   c                       \ rS rSrSr\S 5       rSrSrSr	Sr
Sr  SS
\S\R                  S	-  S\R                  S	-  4S jjrSrg	)MTB_ImageBatchToSublist   ux   
# Image Batch To Sublist 🔄

Splits a large batched tensor into smaller sub-batches for memory-efficient processing.
c                 $    SSSSSSS.40SSS.S	.$ )
Nsub_batch_sizerw   r     r+   rj   rk   steprz   MASK)r   maskr)   optionalr4   r5   s    r   r7   #MTB_ImageBatchToSublist.INPUT_TYPES   s7     ! !!D!D# $!
 	
r$   )r{   r   rw   )
image_list	mask_list
item_countTTsplit_batchbatch_processingNr   r   r   c                 v   Uc  Uc  [        S5      eSnUb  UR                  S5      nSnUb  UR                  S5      nUS:  a;  US:  a5  XT:w  a0  [        SUR                  S5       SUR                  S5       S35      e[        XE5      nXa-  n/ n/ n	[        U5       HG  n
X-  nX-   nUS:  a  UR	                  X+U2S4   5        US:  d  M0  U	R	                  X;U2S4   5        MI     Xa-  S:w  a>  Xq-  nUS:  a  UR	                  X-S 2S4   5        US:  a  U	R	                  X=S 2S4   5        X[        U5      4$ )Nz1You must either pass mask or image, none receivedr   z:When providing image and mask, batch size must match (got z
 mask and z images).)rJ   sizerk   rK   rM   rI   )rO   r   r   r   image_count
mask_count
batch_sizenum_full_batches
im_batchesmask_batchesr   	start_idxend_idxremaining_starts                 r   r   #MTB_ImageBatchToSublist.split_batch   s    =T\C  **Q-K
1J?zA~*2KLTYYWX\NZdejeoeopqerdss{|  1
%7
'(A*I0GQ!!%'(93(>"?@A~##D7):C)?$@A ) &!+.?OQ!!%(8#(=">?A~##D)93)>$?@#j/::r$   r4   )NN)rU   rV   rW   rX   rq   rY   r7   rZ   rr   OUTPUT_IS_LISTr\   r[   r   r   r   r   r`   r4   r$   r   r   r      sv     
 
 ,L<L!NH!H
 &*$(	/;/; ||d"/; llT!	/; /;r$   r   c                   `    \ rS rSr\S 5       rSrSrSrSr	Sr
S\\R                     4S	 jrS
rg)MTB_SublistToImageBatchi  c                     SSS00$ )Nr)   tensorsrz   r4   r5   s    r   r7   #MTB_SublistToImageBatch.INPUT_TYPES  s     :
 	
r$   Trz   merge_batchesr   ud   # Sublist to Image Batch 🔄

Merges a list of sub-batched tensors back into a single large batch.
r   c                 z   [        U5      S::  a  US   4$ US   nUSS   H  nUR                  SS  UR                  SS  :w  a]  [        R                  R	                  UR                  SS5      UR                  S   UR                  S   SS5      R                  SS5      n[        R                  " X#4SS9nM     U4$ )Nr   r   r>   r   lanczoscenterr   )rI   r   comfyutilscommon_upscalemovedimr   r   )rO   r   rS   next_tensors       r   r   %MTB_SublistToImageBatch.merge_batches  s    w<1AJ= "12;K||AB;#4#4QR#88#kk88''A.LLOLLO '!R.  YY4!<F ' yr$   r4   N)rU   rV   rW   rX   rY   r7   INPUT_IS_LISTrZ   r\   r[   DOCUMENTATIONrG   r   r   r   r`   r4   r$   r   r   r     sF    
 
 MLH!HM
T%,,%7 r$   r   c                   Z    \ rS rSrSr\S 5       rSrSrSr	SS\
R                  4S	 jjrS
rg)MTB_BatchMakei(  z,Simply duplicates the input frame as a batchc                     SSSS04S.SS0S.$ )	Nrz   rw   r+   r   )r   countr   r   r   r4   r5   s    r   r7   MTB_BatchMake.INPUT_TYPES+  s,     $)Q0  +
 	
r$   rz   generate_batchrh   Nr   c                     [        UR                  5      S:X  a  UR                  S5      nUR                  USSS5      U(       a  UR                  USS5      4$ U4$ )N   r   r   )rI   r   r   repeat)rO   r   r   r   s       r   r   MTB_BatchMake.generate_batch9  s^    u{{q OOA&E LL1a((,DKKq!$
 	
26
 	
r$   r4   rA   )rU   rV   rW   rX   rq   rY   r7   rZ   r\   r[   r   r   r   r`   r4   r$   r   r   r   (  s=    6
 
 LHH
ELL 
 
r$   r   c                   :    \ rS rSrSr\S 5       rSrSrSr	S r
Srg	)
MTB_BatchShapeiC  zCGenerates a batch of 2D shapes with optional shading (experimental)c                     SSSS04/ SQSS04SSS04SSS04SSS04S	S
SS.4S	SSS.4S	SSS.4SSS04SSS04SSS04S.0$ )Nr)   rw   r+   r   )BoxCircleDiamondTuber      d   COLORz#ffffff	MTB_COLORr+   
widgetType#000000   FLOAT        )r   r   image_widthimage_height
shape_sizecolorbg_colorshade_color	thicknessshadexshadeyr4   r5   s    r   r7   MTB_BatchShape.INPUT_TYPESF  s     )Q08) !&	3'78!&C(8 9$y#&67!y{#ST$)+&VW 'Y[)YZ#i^4"Y$45"Y$45
 	
r$   rz   generate_shapesrh   c                    [         R                  " SU 35        [         R                  " SU 35        [         R                  " SU 35        [        U5      n[        U5      n[        U5      n/ n[        U5       GHU  n[        R
                  " XCS4U[        R                  S9n[        R                  " XC4[        R                  S9nUS-  US-  4nUS:X  a@  US-  nUS   U-
  US	   U-
  4nUS   U-   US	   U-   4n[        R                  " UUUS
S5        OUS:X  a  [        R                  " UUUS-  S
S5        OUS:X  al  [        R                  " US   US	   US-  -
  /US   US-  -   US	   /US   US	   US-  -   /US   US-  -
  US	   //5      n[        R                  " UU/S
5        O+US:X  a%  [        R                  " UUUS-  US-  4SSSS
U	5        XnUS
:H  '   [        R                  " U[        R                  S9nU
[        R                   " SS	U5      -  US S 2S S 2S4'   U[        R                   " SS	U5      R#                  SS	5      -  US S 2S S 2S	4'   [        R$                  " UR'                  [        R                  5      S	US	S5      R'                  [        R                  5      nUUS
:H     XS
:H  '   UR)                  U5        GMX     [+        U5      4$ )NzCOLOR: z
BG_COLOR: zSHADE_COLOR: r   )dtyper   r   r   r      r>   r   r   r   ih  )r   rl   r#   rK   r   fulluint8zeroscv2	rectanglecirclearrayfillPolyellipse
zeros_likefloat32r   reshapeaddWeightedastyperM   r   )rO   r   r   r   r   r   r   r   r   r   r   r   rP   ro   canvasr   r   	half_sizetop_leftbottom_rightptsshadingshading_canvass                          r   r   MTB_BatchShape.generate_shapes_  s    			GE7#$		Jxj)*		M+/0 5!h' -uAWWA.F 88\7rxxHD "Q&(9:F~&!O	"1I	16!9y3HI &q	I 5vay97LMdHlCD("

4q#rB)#hhF1I
a$?@Z1_4fQi@F1I
a$?@Z1_4fQi@	 TC5#.&1_jAo6	 #(43; mmF"**=G%Aq+(FFGAq!G%1l)gb!n GAq!G !__bjj)1gq!fRXX 
 #1"=F3;JJvo r 3!!r$   r4   N)rU   rV   rW   rX   rq   rY   r7   rZ   r\   r[   r   r`   r4   r$   r   r   r   C  s.    M
 
( L HHP"r$   r   c                   :    \ rS rSrSr\S 5       rSrSrSr	S r
Srg	)
MTB_BatchFloatFilli  zJFills a batch float with a single value until it reaches the target lengthc                 0    SSSS/SS04SSS04SSS	04S
.0$ )Nr)   r9   headtailr+   r   r   rw   r   )re   	directionr   r   r4   r5   s    r   r7   MTB_BatchFloatFill.INPUT_TYPES  sD     %%v.F0CD!Is#34)Q0	
 	
r$   fill_floatsr9   rh   c                     [        U5      nXT:  a  [        SU SU S35      eXE-
  nUS:X  a  X/U-  -   nU4$ U/U-  U-   nU4$ )NzSize (z) is less then target count (r?   r  )rI   rJ   )rO   re   r  r   r   r   rems          r   r  MTB_BatchFloatFill.fill_floats  ss    6{<;E7!D  lgm+F y Ws]V+Fyr$   r4   N)rU   rV   rW   rX   rq   rY   r7   r\   rZ   r[   r  r`   r4   r$   r   r  r    s-    T
 
 HLHr$   r  c                   L    \ rS rSrSr\S 5       rSrSrSr	S\
S\\   4S	 jrS
rg)MTB_BatchFloatAssemblei  z@Assembles mutiple batches of floats into a single stream (batch)c                     SSSSS0400$ Nr)   r2   r*   r+   Fr4   r5   s    r   r7   "MTB_BatchFloatAssemble.INPUT_TYPES  s    YY4F(GHIIr$   r9   rh   assemble_floatsr2   r<   c                     / nU(       a0  [        UR                  5       5       H  nU(       d  M  X4-  nM     U4$ UR                  5        H  nU(       d  M  X4-  nM     U4$ rA   )reversedrH   )rO   r2   r<   rP   ro   s        r   r   &MTB_BatchFloatAssemble.assemble_floats  s[    fmmo.1HC / v	 ]]_1HC % vr$   r4   N)rU   rV   rW   rX   rq   rY   r7   rZ   r[   r\   r]   rG   r_   r   r`   r4   r$   r   r  r    sA    JJ J LH Ht tE{ r$   r  c                   r    \ rS rSrSr\S 5       rSrSrSr	     SS\
S   \
S	   -  S
\S\S\S\4
S jjrSrg)MTB_BatchFloati  z4Generates a batch of float values with interpolationc           
      R    SSS/SS04SSS04SSS	S
SS.4SSS	S
SS.4/ SQSS04S.0$ )Nr)   SingleStepsr+   rw   r   r   r   g     g     @gMbP?r         ?)LinearzSine InzSine OutzSine In/OutzQuart Inz	Quart OutzQuart In/OutzCubic Inz	Cubic OutzCubic In/OutzCirc InzCirc OutzCirc In/OutzBack InzBack OutzBack In/Outz
Elastic InzElastic OutzElastic In/Outz	Bounce Inz
Bounce OutzBounce In/Outr*  )moder   rj   rk   easingr4   r5   s    r   r7   MTB_BatchFloat.INPUT_TYPES  sw     w'(  )Q0 #DeL
  #DeL
0 )3)+
 +	
r$   
set_floatsr9   rh   r(  r+  r'  r   rj   rk   r,  c                     US:X  a  US:X  a  [        S5      e/ nUS:X  a	  U/U-  nU4$ [        U5       H0  nXrS-
  -  n[        X5      n	X4U-
  U	-  -   n
UR                  U
5        M2     U4$ )Nr(  r   z0Steps mode requires at least a count of 2 valuesr'  )rJ   rK   r
   rM   )rO   r+  r   rj   rk   r,  	keyframesr   normalized_step
eased_stepeased_values              r   r.  MTB_BatchFloat.set_floats#  s     7?uzB  	8I<uA19oO%o>Jsj 88K[)	  |r$   r4   N)r(  r   r   r)  r*  )rU   rV   rW   rX   rq   rY   r7   r\   rZ   r[   r   r   r_   r^   r.  r`   r4   r$   r   r%  r%    s    >,
 ,
\ HLH 6=g!22  	
   r$   r%  c                       \ rS rSrSr\S 5       rSrSrSr	S\
R                  S\
R                  S	\S
\4S jrS	\S\S\4S jrSrg)MTB_BatchSequencePlusi=  z9Sequences multiple image batches with transition effects.c                 4    S/ SQSS04SSSSSS	.4S
SS04S.0$ )Nr)   )none	crossfade
slide_leftslide_rightslide_up
slide_down	wipe_left
wipe_rightwipe_up	wipe_downband_wipe_hband_wipe_vr+   r8  rw   r   x   r   r   r*   F)
transitionoverlap_framesr2   r4   r5   s    r   r7   !MTB_BatchSequencePlus.INPUT_TYPES@  sO      '$  !!CC# &	5'9:-
 	
r$   rz   sequence_batchesrh   frame1frame2rE  progressc                    US:X  a
  US:  a  U$ U$ US:X  a  USU-
  -  X$-  -   $ UR                  S5      (       a  UR                  SS u  pVUS:X  a$  [        Xd-  5      n[        R                  " X'* SS	9nO{US
:X  a#  [        Xd-  5      n[        R                  " X'SS	9nORUS:X  a$  [        XT-  5      n[        R                  " X'* SS	9nO(US:X  a"  [        XT-  5      n[        R                  " X'SS	9nUSU-
  -  X$-  -   $ UR                  S5      (       a  UR                  SS u  pV[        R
                  " U5      nUS:X  a  [        Xd-  5      n	SUSS2SS2SU	2SS24'   OvUS:X  a#  [        USU-
  -  5      n	SUSS2SS2U	S2SS24'   OMUS:X  a  [        XT-  5      n	SUSS2SU	2SS2SS24'   O(US:X  a"  [        USU-
  -  5      n	SUSS2U	S2SS2SS24'   USU-
  -  X(-  -   $ UR                  S5      (       Ga  UR                  SS u  pV[        R
                  " U5      nSn
US:X  aj  Xj-  n[        U
5       HV  n[        Xd-  X-  -
  5      n	[        X-  5      n[        [        X-   US-   U-  5      5      nX:  d  MF  SUSS2SS2X2SS24'   MX     OiXZ-  n[        U
5       HV  n[        XT-  X-  -
  5      n	[        X-  5      n[        [        X-   US-   U-  5      5      nX:  d  MF  SUSS2X2SS2SS24'   MX     USU-
  -  X(-  -   $ U$ )z+Apply transition effect between two frames.r8        ?r9  r   slide_r   r:  r   )shiftsdimsr;  r<  r=  wipe_r>  Nr?  r@  rA  
band_wipe_
   rB  )
startswithr   r   r   rollr  rK   rj   )rO   rI  rJ  rE  rK  hwoffsetr   edge	num_bands
band_widthr   startendband_heights                   r   apply_transition&MTB_BatchSequencePlus.apply_transitiona  s:    %^677;&Q\*V->>>""8,,<<!$DA\)Q\*F7C},Q\*FBz)Q\*F7C|+Q\*FBQ\*V->>>""7++<<!$DA##F+D[(1<('(Q5D5!^$|+1H-.'(Q45!^$y(1<('(Qq!^${*1H-.'(Qq!^$QX&66""<00<<!$DA##F+DI]*]
y)A@AD/Ec%,Q*0DEFC{34Q59a/0 *  my)AABD0Ec%,Q+0EFGC{34Q	1a/0 * QX&66r$   rF  r2   c           	         [        UR                  5       5      nU(       a  US S S2   n/ nU H>  n[        UR                  5      S:X  a  UR	                  S5      nUR                  U5        M@     US:X  d  US:X  a  [        R                  " USS94$ / n[        U5      S:  a$  UR                  [        US   S U* S-   5      5        [        S[        U5      5       GHN  n	XiS-
     n
Xi   n[        US-  [        U
5      5      n[        US-  [        U5      5      nX-   nUS:  a<  UR                  [        X* S  5      5        UR                  [        US U 5      5        M  [        U5       Hi  nXS-
  -  n[        U
5      U-
  [        XS-
  5      -   n[        SX-
  5      nU R                  U
UUS-    UUUS-    UU5      nUR                  US   5        Mk     U	[        U5      S-
  :  a#  UR                  [        XU* S-   5      5        GM2  UR                  [        XS  5      5        GMQ     [        R                  " USS9nU4$ )Nr>   r   r   r8  r   r   r   )rG   rH   rI   r   r   rM   r   r   extendrK   rj   rk   r_  stack)rO   rE  rF  r2   r<   imagesprocessed_imagesimgresult_framesr   
prev_batch
curr_batchprev_framesnext_framestotal_overlaptrK  prev_idxnext_idxtransition_framerS   s                        r   rH  &MTB_BatchSequencePlus.sequence_batches  se    &*&--/%:DbD\F/1C399~"mmA&##C( 
 Q*"6II.A688,. 1$  %a()?N?a+?@A q#./0A)a%0J),Jn13z?CKn13z?CK'5Mq $$T*\]*C%DE$$T*\k*B%CD=) 12 
Ok1C?4KK  q!/2#'#8#8x(Q,7x(Q,7	$  $$%5a%89 *  3'(1,,$$>/Q2FGH $$T*\*B%CDG 1J ]2yr$   r4   N)rU   rV   rW   rX   rq   rY   r7   rZ   r\   r[   r   r   r^   r_   r_  r   r]   rH  r`   r4   r$   r   r6  r6  =  s~    C
 
8 L!HHGG G 	G
 GR??/2?=A?r$   r6  c                   B    \ rS rSrSr\S 5       rSrSrSr	S\
4S jrS	rg
)MTB_BatchSequencei  z2Sequences multiple image batches one after anotherc                     SSSSS0400$ r  r4   r5   s    r   r7   MTB_BatchSequence.INPUT_TYPES  s%     I	5'9:
 	
r$   rz   rH  rh   r2   c                 
   [        UR                  5       5      nU(       a  US S S2   n/ nU H>  n[        UR                  5      S:X  a  UR	                  S5      nUR                  U5        M@     [        R                  " USS94$ )Nr>   r   r   r   )rG   rH   rI   r   r   rM   r   r   )rO   r2   r<   rd  	processedrf  s         r   rH  "MTB_BatchSequence.sequence_batches  ss    fmmo&DbD\F	C399~"mmA&S! 
 		)+--r$   r4   N)rU   rV   rW   rX   rq   rY   r7   rZ   r\   r[   r]   rH  r`   r4   r$   r   rs  rs    s4    <
 
 L!HH. .r$   rs  c                   F    \ rS rSrSr\S 5       rSrSrSr	S\
S\
4S	 jrS
rg)MTB_BatchMergei	  z9Merges multiple image batches with different frame countsc                 (    S/ SQSS04SS/SS04S.0$ )Nr)   )r,   multiplyaverager+   r}  r  r  )fusion_modefillr4   r5   s    r   r7   MTB_BatchMerge.INPUT_TYPES  s:     2	*  !&)Iv+>?
 	
r$   rz   r   rh   r~  r  c                    UR                  5       n[        S U 5       5      n/ nU H  nUR                  S   nX:  aY  US:X  a  US   OUS   n	U	R                  XX-
  SSS5      n
US:X  a  [        R
                  " X4SS9O[        R
                  " Xz4SS9nOUnUR                  U5        M     S nU H1  nUc  UnM
  US:X  a  X-  nM  US:X  a  X-  nM"  US	:X  d  M*  X-   S
-  nM3     U4$ )Nc              3   >   #    U  H  oR                   S    v   M     g7fr   N)r   )r   rf  s     r   r   /MTB_BatchMerge.merge_batches.<locals>.<genexpr>  s     8#1s   r   r  r>   r   r   r,   r|  r}  r   )rH   rk   r   r   r   r   rM   )rO   r~  r  r<   rd  
max_framesadjusted_imagesrf  frame_count
fill_framefill_framesadjusted_batchmerged_images                r   r   MTB_BatchMerge.merge_batches  s   888
C))A,K''+v~SV3r7
(//,aA
 v~ II{0a8C#51=  "%"">2 " "C#"%' 'L J. 'L I-$0$6!#;L # r$   r4   N)rU   rV   rW   rX   rq   rY   r7   rZ   r\   r[   r^   r   r`   r4   r$   r   rz  rz  	  s;    C	
 	
 LHH" "C "r$   rz  c                      \ rS rSrSr\S 5       rSrSrSr	SS\
R                  -  \\
R                     -  \\   -  S	\4S
 jr      SS\
R                  S\S\S\\   S-  S\\   S-  S\\   S-  S\\   S-  S\\   S-  S\4S jjrSrg)MTB_Batch2dTransformiA  z6Transform a batch of images using a batch of keyframesc           
      B    S/ SQSS04SSSS.4S	.S
S
S
S
S
SSSS.4S.S.$ )Nrz   )rY  constantreflect	symmetricr+   rY  r   r   r   r   )r   border_handlingconstant_colorr9   r*   Fz=If true, transform values will be scaled to image dimensions.r+   tooltip)ro   yzoomangleshearuse_normalizedr   r4   r5   s    r   r7    MTB_Batch2dTransform.INPUT_TYPESD  s_     $@'$ $+	P[,\"] ! #$$#(#b#
 	
r$   rz   transform_batchrh   paramNreturnc                     [        U[        R                  5      (       a  [        R                  " U5      $ [        U[        5      (       a  [        U5      $ g)Nr   )
isinstancer   r   numelrG   rI   )rO   r  s     r   get_num_elements%MTB_Batch2dTransform.get_num_elementsc  s>     eU\\**;;u%%t$$u:r$   r   r  r  ro   r  r  r  r  r  c
                   ^  [        U 4S jXEXgU4 5       5      (       a  [        S5      e/ / / / / S.n
SSSSSS.nU(       a  T R                  U5      S:  a  XJS'   U(       a  T R                  U5      S:  a  XZS'   U(       a5  T R                  U5      S:  a   U Vs/ s H  n[        US5      PM     snU
S	'   U(       a  T R                  U5      S:  a  XzS
'   U(       a  T R                  U5      S:  a  XS'   U
R	                  5        Hi  u  p[        U5      nUS:  a4  XR                  S   :w  a"  [        SU SU SUR                  S    S35      eUS:X  d  MR  X   /UR                  S   -  X'   Mk     [        5       n[        UR                  S   5       Vs/ s HM  nUR                  UU   R                  S5      U
S   U   U
S   U   U
S	   U   U
S
   U   U
S   U   UUU	S9	S   PMO     nn[        R                  " USS94$ s  snf s  snf )Nc              3   L   >#    U  H  nTR                  U5      S :*  v   M     g7fr  )r  )r   r  rO   s     r   r   7MTB_Batch2dTransform.transform_batch.<locals>.<genexpr>z  s(      
3 !!%(A-3s   !$z1At least one transform parameter must be provided)ro   r  r  r  r  r   r)  ro   r  gh㈵>r  r  r  z
Length of z	 values (z) must match number of images (r?   )r  r   )allrJ   r  rk   itemsrI   r   r   rK   	transformr   r   r   )rO   r   r  r  ro   r  r  r  r  r  r0  default_valsnamerH   r   transformerr   rP   s   `                 r   r  $MTB_Batch2dTransform.transform_batchn  sb     
U3
 
 
 C 
 -
	 Qa!L&&q)A-cN&&q)A-cND))$/!3:> ?$QQ$ ?IfT**51A5!&gT**51A5!&g%OO-LDKEqyUkk!n4  iw6UV[VaVabcVdUeefg  z#/#5"6Q"G	 . )* 5;;q>*
 + !!a""1%#q!#q!&!!$'"1%'"1%- " 
 
 + 	 
 		#1%''= !@ 
s   HAHr4   )NNNNNF)rU   rV   rW   rX   rq   rY   r7   rZ   r\   r[   r   r   rG   r_   r   r  r^   r]   r  r`   r4   r$   r   r  r  A  s   @
 
4 L HH	ELL(4+==UK			  !% $#'$($($B(||B( B( 	B(
 ;B( ;B( 5kD B( E{T!B( E{T!B( B( B(r$   r  c                   h    \ rS rSrSr\S 5       rSrSrSr	Sr
S\\   S\S	\S
\S\S\S\S\4S jrSrg)MTB_BatchFloatFiti  z4Fit a list of floats using a source and target rangec                 l    SSSS04SSS04SSS04SS	S
S.4SSS
S.4SS	S
S.4SSS
S.4[         SS04S.0$ )Nr)   r:   
forceInputTr*   r+   Fr   r   g{Gz?)r+   r   r)  r*  )rH   clampauto_compute_source
source_min
source_max
target_min
target_maxr,  )r	   r5   s    r   r7   MTB_BatchFloatFit.INPUT_TYPES  s     #lD%9:#i%78(1Iu3E'F&C(FG&C(FG&C(FG&C(FG)
 	
r$   	fit_ranger9   rh   rH   r  r  r  r  r  r  r,  c	           
          U(       a  [        U5      n[        U5      nSSKJn	  / n
U	" 5       nU H-  nUR	                  UUUUUUU5      u  nU
R                  U5        M/     U
4$ )Nr   )MTB_FitNumber)rj   rk   graph_utilsr  	set_rangerM   )rO   rH   r  r  r  r  r  r  r,  r  rP   
fit_numberr   transformed_values                 r   r  MTB_BatchFloatFit.fit_range  ss     VJVJ."_
E#-#7#7$  JJ()  vr$   r4   N)rU   rV   rW   rX   rq   rY   r7   r\   rZ   r[   DESCRIPTIONrG   r_   r]   r^   r  r`   r4   r$   r   r  r    s    >
 
" HLHHKU  "	
     r$   r  c                   l    \ rS rSrSr\S 5       rSrSrSr	Sr
 SS\S	\S
\S\S\S\4S jjrS rS rSrg)MTB_PlotBatchFloati  zPlot floatsc                 >    SSSS04SSS04SSS04SSS04SSS04S	.0$ )
Nr)   rw   r+   i   r   r   r*   F)widthheight
point_sizeseedstart_at_zeror4   r5   s    r   r7   MTB_PlotBatchFloat.INPUT_TYPES  sU     )S!12 9c"23$y!n5A/"+i-?!@
 	
r$   rz   )plotr  rh   r  r  r  r  r  interactive_backendc                    SS K nU(       d  UR                  S5        SS KJn	  U	R	                  US-  US-  4SS9u  pU
R                  S5        U
R                  R                  S5        UR                  S5        UR                  SSS	S	S
9  UR                  5        VVs/ s H  o  H  oPM     M     nnn[        U5      n[        U5      nSUU-
  -  nUR                  UU-
  UU-   5        [        S UR                  5        5       5      nU(       a  [        R                  " SUS-
  U5      nO[        R                  " SUU5      nUR                  SU5        [        R                   R#                  U5        [        R                   R%                  ['        U5      S5      n[)        UUR+                  5       SS9 H'  u  nu  nnUR-                  US ['        U5       UUUS9  M)     UR/                  SSSSSS9  UR1                  SSSS9  UR3                  SSSS9  UR5                  SSSS9  UR7                  SS9  UR8                  R+                  5        H  u  nnUR                  S5        M     [;        5       nU	R=                  USSS 9  UR?                  S5        [@        RB                  " U5      nU	RE                  U
5        [G        U5      4$ s  snnf )!Nr   Aggr   )figsizedpiblackz#2e2e2egray-rM  )r   	linestyle	linewidthalphag?c              3   8   #    U  H  n[        U5      v   M     g 7frA   )rI   )r   rH   s     r   r   *MTB_PlotBatchFloat.plot.<locals>.<genexpr>#  s     C?V?s   r   r   F)strict)labelr   Legendlargemediumbest)titletitle_fontsizefontsize	edgecolorlocTimewhite)r  r   ValuezPlot of Values over Timezx-large)colorspngtight)formatbbox_inches)$
matplotlibusematplotlib.pyplotpyplotsubplotsset_edgecolorpatchset_facecolorgridrH   rj   rk   set_ylimr   r   set_xlimrandomr  randrI   zipr  r  legend
set_xlabel
set_ylabel	set_titletick_paramsspinesr   savefigseekr   opencloser   )rO   r  r  r  r  r  r  r<   r  pltfigaxrH   r   
all_values
global_min
global_max	y_padding
max_lengthx_valuesr  r   r  _spinebufr   s                              r   r  MTB_PlotBatchFloat.plot  s    	 #NN5!',,Vc\'B,L'"			*
#
fs#F +1--/N/veeve/
N_
_
J34	
J*J,BCC6==?CC
{{1j1njAH{{1j*=H
Az"
		tFQ/&)FLLN5'
"E?E6 GGH]s6{+V5GN'
 			" 	 	
 	fwg>
gw?
&' 	 	

 	g& 		)HAu( * iC7;

3		#5!##c Os   Kc                     Uu  pVUR                   S   S-
  U-
  nUS-  n[        SXW-
  5      [        UR                   S   XW-   S-   5      p[        SXg-
  5      [        UR                   S   Xg-   S-   5      pX1X2X24'   g )Nr   r   r   )r   rk   rj   )rO   r   pointr   r  ro   r  r	  x_startx_endy_starty_ends               r   
draw_pointMTB_PlotBatchFloat.draw_pointO  s    KKNQ"!O	1=!A 12 
 1=!A 12  /4gmW]*+r$   c                    Uu  pVUu  pxUR                   S   S-
  U-
  nUR                   S   S-
  U-
  nXu-
  n	X-
  n
[        U
5      [        U	5      :  nU(       a  XepeXpSnXW:  a  XupuXpSnXu-
  n	X-
  n
[        U	S-  5      nUnS nXh:  a  SnOSn[        XWS-   5       H4  nU(       a  UU4OUU4nXAU'   U[        U
5      -  nUS:  d  M,  X-  nX-  nM6     U(       a  XAXV4'   XAXx4'   g g )Nr   r   FTg       @r>   )r   r1   r   rK   )rO   r   r\  r]  r   x1y1x2y2dxdyis_steepswappederrorr  ystepro   coords                     r   	draw_lineMTB_PlotBatchFloat.draw_line]  s$    [[^a"$[[^a"$WWr7SW$7GWWBH7EEr6"A&QFQFE %LSWEqy
 # #2(O#2(O r$   r4   NF)rU   rV   rW   rX   rq   rY   r7   rZ   rr   r\   r[   r   r]   r  r  r&  r`   r4   r$   r   r  r    s    	
 	
 LLHH %*J$J$ J$ 	J$
 J$ J$ "J$X4%$r$   r  c                 ,    X -  U -  X S-  S-
  -  S-   -  $ )N      rS  r4   )rm  s    r   <lambda>r,    s    	Qa%"*-=-B Cr$   c                   d    \ rS rSrSr\S 5       rSrSrSr	Sr
 SS	 jr     SS
 jrS rS rSrg)MTB_BatchShakei  z.Applies a shaking effect to batches of images.c                 Z    SSSSS04SSS04SSS04SSSS.4SSSS.4S	S
S
S.4S	SS04S.0$ )Nr)   rz   r   r+   r)  g      $@g{Gzt?ry   rw   r   r   )rd  position_amount_xposition_amount_yrotation_amount	frequencyfrequency_divideroctavesr  r4   r5   s    r   r7   MTB_BatchShake.INPUT_TYPES  ss     $&-	3/?%@&-	3/?%@$+i->#?%3u'EF&-3u/M%N!q#;<A/	
 	
r$   )r{   r:   r:   r:   )r   pos_xpos_yrotapply_shakerh   Nc           	      t   U=(       d    [         nUS   US   -  US   US   -  4nUS   US   -  US   US   -  4n[        R                  SUS   US   2SUS   US   24   R                  SSS5      S-  nS[        R                  -  [        R
                  R                  US   S-   US   S-   5      -  n[        R                  " [        R                  " U5      [        R                  " U5      45      n	US   (       a  U	SSS24   U	SSS24'   US   (       a  U	SS2S4   U	SS2S4'   U	R                  US   S5      R                  US   S5      n	U	SUS   * 2SUS   * 24   n
XS   S2SUS   * 24   nU	SUS   * 2US   S24   nXS   S2US   S24   n[        R                  " [        R                  " USS2SS2S4   USS2SS2S4   45      U
-  S5      n[        R                  " [        R                  " USS2SS2S4   S-
  USS2SS2S4   45      U-  S5      n[        R                  " [        R                  " USS2SS2S4   USS2SS2S4   S-
  45      U-  S5      n[        R                  " [        R                  " USS2SS2S4   S-
  USS2SS2S4   S-
  45      U-  S5      nU" U5      nUSUSS2SS2S4   -
  -  USS2SS2S4   U-  -   nUSUSS2SS2S4   -
  -  USS2SS2S4   U-  -   n[        R                  " S5      SUSS2SS2S4   -
  U-  USS2SS2S4   U-  -   -  $ )a  Generate a 2D numpy array of perlin noise.

Args:
    shape: The shape of the generated array (tuple of two ints).
        This must be a multple of res.
    res: The number of periods of noise to generate along each
        axis (tuple of two ints). Note shape must be a multiple of
        res.
    tileable: If the noise should be tileable along each axis
        (tuple of two bools). Defaults to (False, False).
    interpolant: The interpolation function, defaults to
        t*t*t*(t*(t*6 - 15) + 10).

Returns
-------
    A numpy array of shape shape with the generated noise.

Raises
------
    ValueError: If shape is not a multiple of res.
r   r   r   Nr>   )DEFAULT_INTERPOLANTr   mgrid	transposepir  r  dstackcossinr   rL   sqrt)rO   r   rP   tileableinterpolantdeltadr  angles	gradientsg00g10g01g11n00n10n01n11rm  n0n1s                        r   generate_perlin_noise_2d'MTB_BatchShake.generate_perlin_noise_2d  sc   0 "8%8Q%("CFU1X$561XQqSV!34HHQQ%(*AAq,AABLL1a  	 RUURYY^^CFQJA
CCIIrvvf~rvvf~>?	A;(AIb!eA;(AIae$$QqT1-44QqT1=	1Q4%AaD5()!1Q4%(1Q4%1(!!'ffRYYQ1WtAq!G}=>DaHffRYYQ1W 141a=ABSH!LffRYYQ1WtAq!G}q/@ABSH!LffIItAq!G}q($q!Qw-!*;<=CQ
 A!Q'
N#a1aj3&66A!Q'
N#a1aj3&66wwqza!Aq!G*n2Qq!QwZ"_DEEr$   c           
          U=(       d    [         n[        R                  " U5      nSn	Sn
[        U5       H0  nXU R	                  UXS   -  XS   -  4UU5      -  -  nX-  n	X-  n
M2     U$ )a  Generate a 2D numpy array of fractal noise.

Args:
    shape: The shape of the generated array (tuple of two ints).
        This must be a multiple of lacunarity**(octaves-1)*res.
    res: The number of periods of noise to generate along each
        axis (tuple of two ints). Note shape must be a multiple of
        (lacunarity**(octaves-1)*res).
    octaves: The number of octaves in the noise. Defaults to 1.
    persistence: The scaling factor between two octaves.
    lacunarity: The frequency factor between two octaves.
    tileable: If the noise should be tileable along each axis
        (tuple of two bools). Defaults to (True,True).
    interpolant: The, interpolation function, defaults to
        t*t*t*(t*(t*6 - 15) + 10).

Returns
-------
    A numpy array of fractal noise and of shape shape generated by
    combining several octaves of perlin noise.

Raises
------
    ValueError: If shape is not a multiple of
        (lacunarity**(octaves-1)*res).
r   r   )r<  r   r   rK   rT  )rO   r   rP   r5  persistence
lacunarityrD  rE  noiser3  	amplituder  s               r   generate_fractal_noise_2d(MTB_BatchShake.generate_fractal_noise_2d  s    H "8%8		wA!>!>V#YQ%78	"  E #I$I   r$   c                 Z    [        U5      S-  n[        U5      S-  nU R                  XE4   $ )N   )r   noise_pattern)rO   ro   r  r5  x_idxy_idxs         r   fbmMTB_BatchShake.fbm  s1     AA!!%,//r$   c	                    [         R                  R                  U5        [         R                  R                  SSS5      U l        [         R                  R                  SSS5      U l        U R                  SSS5      U l        UR                  S   n	XV-  n/ n
/ n/ n[        U	5       H  nX-  nU R                  S   U-   S-  nU R                  S	   U-   S-  n[         R                  " U R                  XU5      U R                  UX5      /5      nU R
                  S
   U-   S-  nU R                  UX5      nU
R                  US   U-  5        UR                  US	   U-  5        UR                  UU-  5        M     [        5       n[        R                  " SU SU SU SU SU 3
5        UR!                  USSU
UUS9S   nUXU4$ )Ng     @g     @@r   )r   r   )    re  r   r   r^  r   r   z,Applying shaking with parameters: 
position z, z

rotation z
frequency z	
octaves rY  r   )r  r  ro   r  r  )r   r  r  uniformposition_offsetrotation_offsetrT  r_  r   rK   r   rb  rM   r  r   rl   r  )rO   rd  r0  r1  r2  r3  r4  r5  r  r  x_translationsy_translations	rotations	frame_numtimer`  ra  np_positionrot_idxnp_rotationr  shaken_imagess                         r   r:  MTB_BatchShake.apply_shake  s    			t!yy00sA>!yy00sA>!::,

 ll1o1	 	{+I(D))!,y8C?E))!,y8C?E((HHU'2HHUD2K ++A.:cAG((7D:K!!+a.3D"DE!!+a.3D"DE[?:;3 ,B )*			;<M;NbQbPccno~n  @L  MV  LW  Wa  bi  aj  k	

 "11"$ 2 
  ~yIIr$   )r_  rg  rh  ))FFN)r   rM  r   r   N)rU   rV   rW   rX   rq   rY   r7   rZ   rr   r\   r[   rT  r[  rb  r:  r`   r4   r$   r   r.  r.    s^    8
 
 ;L5LHH @D8F| 2h0NJr$   r.  c                   \    \ rS rSrSr\S 5       rSrSrSr	Sr
 SS	\S
\S\S\S\4
S jjrSrg)MTB_BatchFromFolderih  zOLoad images from a folder with options for latest, oldest, or random selection.c           	      ^    SSSS.4SSSS.4/ SQS	S
S.4SSSSSS.4SSSS.4S.SSSS040S.$ )Nr*   TzVEnable or disable the node. If disabled, returns passthrough_image or an empty tensor.r  STRING zbPath to the folder containing images. Relative paths are resolved to the ComfyUI output directory.)latestoldestr  rx  z0How to select images: latest, oldest, or random.rw   rS  r   r   z)Number of images to load from the folder.)r+   rj   rk   r  *z-Glob filter for image filenames (e.g. *.png).)enablefolder_pathr+  r   filterpassthrough_imager{   r  zdIf provided and node is disabled, this image is passed through instead of returning an empty tensor.r   r4   r5   s    r   r7   MTB_BatchFromFolder.INPUT_TYPESk  s    
 #'#{ #% $H  3#+#U #% ##N	 #&#R?&P $!  $J&Q0
 0	
r$   rz   )rd  rh   load_from_folderNr{  r|  r+  r   r}  c                 (   U(       dL  Ub  [         R                  " S5        U4$ [         R                  " S5        [        R                  " SSSS5      4$ [	        U5      nUR                  5       (       d2  [	        [        R                  " 5       5      nX-  nUR                  5       nUR                  5       (       d3  [         R                  " SU 35        [        R                  " SSSS5      4$ UR                  5       (       d3  [         R                  " SU 35        [        R                  " SSSS5      4$ U(       a  U/OS/n	[        Xy5      n
/ S	QnU
 Vs/ s H$  oR                  R                  5       U;   d  M"  UPM&     nnU(       d6  [         R                  " S
U SU 35        [        R                  " SSSS5      4$ US:X  a  UR!                  S SS9  O3US:X  a  UR!                  S S9  OUS:X  a  ["        R$                  " U5        USU n['        U5      U:  a%  [         R                  " SU S['        U5       35        / nU HL  n [(        R*                  " U5      nUR,                  S:w  a  UR/                  S5      nUR1                  U5        MN     U(       d0  [         R                  " S5        [        R                  " SSSS5      4$ [5        U5      4$ s  snf ! [2         a'  n[         R                  " SU SU 35         SnAM  SnAff = f)z<Load images from a folder with the specified selection mode.Nz7MTB_BatchFromFolder: Using passthrough image (disabled)zWMTB_BatchFromFolder: Disabled and no passthrough_image provided, returning empty tensorr   r   zFolder path does not exist: zPath is not a directory: rz  )z.pngz.jpgz.jpegz.bmpz.webpz.tiffzNo image files found in z with filter rx  c                 @    [         R                  R                  U 5      $ rA   ospathgetmtimero   s    r   r,  6MTB_BatchFromFolder.load_from_folder.<locals>.<lambda>      277+;+;A+>r$   T)keyr2   ry  c                 @    [         R                  R                  U 5      $ rA   r  r  s    r   r,  r    r  r$   )r  r  z
Requested z images but only found RGBzError loading image z: zFailed to load any images)r   rl   r   r   r   is_absolutefolder_pathsget_output_directoryresolveexistsr#  is_dirr   suffixlowerwarningsortr  shufflerI   r   r  r+  convertrM   	Exceptionr   )rO   r{  r|  r+  r   r}  r~  path_obj
output_dirpatternsfilesimage_extensionsfimage_filesselected_filesloaded_images	file_pathrf  es                      r   r  $MTB_BatchFromFolder.load_from_folder  s     ,		M *++IIi KK1a+--$##%%l??ABJ!/H'')H  II4XJ?@KK1a+--  II1(<=KK1a+--%F8C5h1N
! 04D DAu 	 
 KK*8*M&J KK1a+--8!>MX!>?XNN;'$Ve,~&KKUG#:3~;N:OP 'ICjj+88u$++e,C$$S) ( II12KK1a+--=)++M
>  C		02aSABBCs%   !K;KAK  
L*LLr4   rA   )rU   rV   rW   rX   rq   rY   r7   rZ   rr   r[   r\   r]   r^   r   r  r`   r4   r$   r   rt  rt  h  st    Y1
 1
f LLH!H M,M, M, 	M,
 M, M, M,r$   rt  r(  )0r  r  ior   pathlibr   typingr   comfy.utilsr   r   r  numpyr   r   PILr   r   r   r	   r
   r   r   r  r   r^   r]   r#   r&   rb   rt   r   r   r   r   r  r  r%  r6  rs  rz  r  r  r  r<  r.  rt  	__nodes__r4   r$   r   <module>r     sd   	      
      D D )C# CD C; ;|$ $<83 83vL; L;^$ $N
 
6l" l"^ B 4M M`l l^. .:5 5po( o(d9 9xS$ S$l D ]J ]J@I, I,Z %	r$   