§
    -?Ëj>7  ã                  óÈ   — d Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	m
Z
mZ ddlZddlmZ e G d	„ d
¦  «        ¦   «         Ze G d„ d¦  «        ¦   «         Z G d„ d¦  «        ZdS )uý   
Temporal Alignment and Multimodal Matching Module.
CÄƒn chá»‰nh trá»¥c thá»�i gian báº±ng Diagonal Hough Transform / Offset Clustering Ä‘á»ƒ phÃ¡t hiá»‡n
chÃ­nh xÃ¡c cÃ¡c Ä‘oáº¡n video bá»‹ sao chÃ©p [target_start, target_end] vs [ref_start, ref_end].
é    )Úannotations)Údefaultdict)Ú	dataclass)ÚDictÚListÚOptionalÚTupleNé   )ÚOwnerDatabasec                  ó¢   — e Zd ZU ded<   ded<   ded<   ded<   ded<   ded<   ded	<   ded
<   ded<   edd„¦   «         Zdd„Zedd„¦   «         ZdS )ÚMatchSegmentÚfloatÚtarget_start_secÚtarget_end_secÚstrÚreference_video_idÚref_start_secÚref_end_secÚconfidence_scoreÚvisual_scoreÚaudio_scoreÚ
match_typeÚreturnc                ó<   — t          d| j        | j        z
  ¦  «        S )Nç        )Úmaxr   r   ©Úselfs    ú3C:\Projects\VideoDetection\src\alignment\matcher.pyÚduration_seczMatchSegment.duration_sec   s   € å�3˜Ô+¨dÔ.CÑCÑDÔDÐDó    úDict[str, object]c                ó8  — |                       | j        ¦  «        › d|                       | j        ¦  «        › �|                       | j        ¦  «        › d|                       | j        ¦  «        › �| j        t          | j        d¦  «        t          | j        d¦  «        t          | j        d¦  «        t          | j        d¦  «        t          | j        d¦  «        t          | j        d¦  «        t          | j	        d¦  «        t          | j
        d¦  «        | j        dœS )Nz - r
   é   )Útarget_rangeÚ	ref_ranger   r   r   r   r   r    r   r   r   r   )Ú_format_timer   r   r   r   r   Úroundr    r   r   r   r   r   s    r   Úto_dictzMatchSegment.to_dict!   s  € à#×0Ò0°Ô1FÑGÔGÐtÐtÈD×L]ÒL]Ð^bÔ^qÑLrÔLrÐtÐtØ ×-Ò-¨dÔ.@ÑAÔAÐkÐkÀd×FWÒFWÐX\ÔXhÑFiÔFiÐkÐkØ"&Ô"9Ý % dÔ&;¸QÑ ?Ô ?Ý# DÔ$7¸Ñ;Ô;Ý" 4Ô#5°qÑ9Ô9Ý  Ô!1°1Ñ5Ô5Ý! $Ô"3°QÑ7Ô7Ý % dÔ&;¸QÑ ?Ô ?Ý! $Ô"3°QÑ7Ô7Ý  Ô!1°1Ñ5Ô5Øœ/ð
ð 
ð 	
r!   Úsecondsc                ó    — t          t          | ¦  «        d¦  «        \  }}t          |d¦  «        \  }}|dk    r|d›d|d›d|d›�S |d›d|d›�S )Né<   r   Ú02dú:)ÚdivmodÚint)r*   ÚmÚsÚhs       r   r'   zMatchSegment._format_time1   st   € å•c˜'‘l”l BÑ'Ô'‰ˆˆ1Ý�a˜‰}Œ}‰ˆˆ1ØˆqŠ5ˆ5ØÐ-Ð-Ð-˜aÐ-Ð-Ð- aÐ-Ð-Ð-Ð-ØÐ!Ð!Ð!˜!Ð!Ð!Ð!Ð!r!   N)r   r   )r   r"   )r*   r   r   r   )	Ú__name__Ú
__module__Ú__qualname__Ú__annotations__Úpropertyr    r)   Ústaticmethodr'   © r!   r   r   r      sÕ   € € € € € € àÐÐÑØÐÐÑØÐÐÑØÐÐÑØÐÐÑØÐÐÑØÐÐÑØÐÐÑØ€O€O�OàðEð Eð Eñ „XðEð
ð 
ð 
ð 
ð  ð"ð "ð "ñ „\ð"ð "ð "r!   r   c                  óB   — e Zd ZU ded<   ded<   ded<   ded<   ded<   dS )	ÚRawPointMatchr   Út_targetÚt_refr   Úref_video_idÚscoreÚmodalityN)r4   r5   r6   r7   r:   r!   r   r<   r<   :   s@   € € € € € € à€O€O�OØ€L€L�LØÐÐÑØ€L€L�LØ€M€M�M€M€Mr!   r<   c                  óF   — e Zd Z	 	 	 	 	 	 d'd(d„Zd)d„Zd*d„Zd+d!„Zd,d-d%„Zd&S ).ÚTemporalMatcherçö(\�Âõè?ç=
×£p=ê?ç      @ç       @çÍÌÌÌÌÌä?çffffffÖ?Údbr   Úvisual_thresholdr   Úaudio_thresholdÚmin_match_duration_secÚtemporal_bin_size_secÚfusion_weight_visualÚfusion_weight_audior   ÚNonec                óh   — || _         || _        || _        || _        || _        || _        || _        d S ©N)rJ   rK   rL   rM   rN   Úw_visualÚw_audio)r   rJ   rK   rL   rM   rN   rO   rP   s           r   Ú__init__zTemporalMatcher.__init__D   s=   € ð ˆŒØ 0ˆÔØ.ˆÔØ&<ˆÔ#Ø%:ˆÔ"Ø,ˆŒØ*ˆŒˆˆr!   Úquery_visual_featuresúList[Tuple[float, np.ndarray]]Úquery_audio_featuresúList[MatchSegment]c                ó¨  — g }|�rY| j         j        j        dk    �rCd„ |D ¦   «         }t          j        d„ |D ¦   «         d¬¦  «        }| j         j                             |d¬¦  «        \  }}t          t          |¦  «        ¦  «        D ]Ö}||         }	t          |j        d         ¦  «        D ]±}
t          |||
f         ¦  «        }t          |||
f         ¦  «        }|dk     s|t          | j         j        ¦  «        k    rŒT|| j        k    rR| j         j        |         }|                     t          |	t          |d         ¦  «        |d	         |d
¬¦  «        ¦  «         Œ²Œ×|�rY| j         j        j        dk    �rCd„ |D ¦   «         }t          j        d„ |D ¦   «         d¬¦  «        }| j         j                             |d¬¦  «        \  }}t          t          |¦  «        ¦  «        D ]Ö}||         }	t          |j        d         ¦  «        D ]±}
t          |||
f         ¦  «        }t          |||
f         ¦  «        }|dk     s|t          | j         j        ¦  «        k    rŒT|| j        k    rR| j         j        |         }|                     t          |	t          |d         ¦  «        |d	         |d¬¦  «        ¦  «         Œ²Œ×|sg S t%          t&          ¦  «        }|D ]"}||j                                      |¦  «         Œ#g }|                     ¦   «         D ]0\  }}|                      ||¦  «        }|                     |¦  «         Œ1|                      |¦  «        S )uƒ   
        Ä�á»‘i soÃ¡t toÃ n diá»‡n giá»¯a cÃ¡c Ä‘áº·c trÆ°ng cá»§a target video vÃ  cÆ¡ sá»Ÿ dá»¯ liá»‡u chá»§ sá»Ÿ há»¯u.
        r   c                ó   — g | ]
}|d          ‘ŒS ©r   r:   ©Ú.0Úfs     r   ú
<listcomp>z)TemporalMatcher.match.<locals>.<listcomp>b   s   € Ð?Ð?Ð? A˜1˜Qœ4Ð?Ð?Ð?r!   c                ó   — g | ]
}|d          ‘ŒS ©é   r:   r^   s     r   ra   z)TemporalMatcher.match.<locals>.<listcomp>c   s   € Ð"GÐ"GÐ"G¨A 1 Q¤4Ð"GÐ"GÐ"Gr!   )Úaxisé   )Útop_krd   Ú	timestampÚvideo_idÚvisual©r=   r>   r?   r@   rA   c                ó   — g | ]
}|d          ‘ŒS r]   r:   r^   s     r   ra   z)TemporalMatcher.match.<locals>.<listcomp>z   s   € Ð@Ð@Ð@ a˜Q˜qœTÐ@Ð@Ð@r!   c                ó   — g | ]
}|d          ‘ŒS rc   r:   r^   s     r   ra   z)TemporalMatcher.match.<locals>.<listcomp>{   s   € Ð$HÐ$HÐ$H¨a Q q¤TÐ$HÐ$HÐ$Hr!   Úaudio)rJ   Úvisual_indexÚtotalÚnpÚstackÚsearchÚrangeÚlenÚshaper   r0   Úvisual_metarK   Úappendr<   Úaudio_indexÚ
audio_metarL   r   Úlistr?   ÚitemsÚ_cluster_and_alignÚextendÚ_temporal_nms)r   rW   rY   Úraw_matchesÚquery_timesÚ
query_vecsÚ	distancesÚindicesÚq_idxÚt_tÚk_idxÚsimÚidxÚmetaÚquery_times_aÚquery_vecs_aÚdistances_aÚ	indices_aÚby_videor1   Údetected_segmentsÚvidÚmatchesÚsegmentss                           r   ÚmatchzTemporalMatcher.matchV   s°  € ð ,.ˆð !ñ 	 T¤WÔ%9Ô%?À!Ò%CÑ%CØ?Ð?Ð)>Ð?Ñ?Ô?ˆKÝœÐ"GÐ"GÐ1FÐ"GÑ"GÔ"GÈaÐPÑPÔPˆJà!%¤Ô!5×!<Ò!<¸ZÈqÐ!<Ñ!QÔ!QÑˆI�wå�s ;Ñ/Ô/Ñ0Ô0ð ð �Ø! %Ô(�Ý" 9¤?°1Ô#5Ñ6Ô6ð ð �EÝ 	¨%°¨,Ô 7Ñ8Ô8�CÝ˜g e¨U lÔ3Ñ4Ô4�CØ˜Q’w�w #­¨T¬WÔ-@Ñ)AÔ)AÒ"AÐ"AØ Ø˜dÔ3Ò3Ð3Ø#œwÔ2°3Ô7˜Ø#×*Ò*­=Ø%(Ý"'¨¨[Ô(9Ñ":Ô":Ø)-¨jÔ)9Ø"%Ø%-ð,ñ ,ô ,ñ ô ð øðð   ñ 	 D¤GÔ$7Ô$=ÀÒ$AÑ$AØ@Ð@Ð+?Ð@Ñ@Ô@ˆMÝœ8Ð$HÐ$HÐ3GÐ$HÑ$HÔ$HÈqÐQÑQÔQˆLà%)¤WÔ%8×%?Ò%?ÀÐTUÐ%?Ñ%VÔ%VÑ"ˆK˜å�s =Ñ1Ô1Ñ2Ô2ð ð �Ø# EÔ*�Ý" ;Ô#4°QÔ#7Ñ8Ô8ð ð �EÝ ¨E°5¨LÔ 9Ñ:Ô:�CÝ˜i¨¨u¨Ô5Ñ6Ô6�CØ˜Q’w�w #­¨T¬WÔ-?Ñ)@Ô)@Ò"@Ð"@Ø Ø˜dÔ2Ò2Ð2Ø#œwÔ1°#Ô6˜Ø#×*Ò*­=Ø%(Ý"'¨¨[Ô(9Ñ":Ô":Ø)-¨jÔ)9Ø"%Ø%,ð,ñ ,ô ,ñ ô ð øðð ð 	ØˆIõ 4?½tÑ3DÔ3DˆØð 	/ð 	/ˆAØ�Q”^Ô$×+Ò+¨AÑ.Ô.Ð.Ð.à02Ðð %ŸNšNÑ,Ô,ð 	/ð 	/‰LˆC�Ø×.Ò.¨s°GÑ<Ô<ˆHØ×$Ò$ XÑ.Ô.Ð.Ð.ð ×!Ò!Ð"3Ñ4Ô4Ð4r!   r‘   r   r’   úList[RawPointMatch]c                ó   — t          t          ¦  «        }|D ]U}|j        |j        z
  }t	          t          j        || j        z  ¦  «        ¦  «        }||                              |¦  «         ŒVg }| 	                    ¦   «         D �]ù\  }}t          |¦  «        dk     rŒ|                     d„ ¬¦  «         g }	|d         g}
t          dt          |¦  «        ¦  «        D ]q}||         j        ||dz
           j        z
  dk    r|
                     ||         ¦  «         Œ@t          |
¦  «        dk    r|	                     |
¦  «         ||         g}
Œrt          |
¦  «        dk    r|	                     |
¦  «         |	D �]}|d         j        }|d         j        dz   }||z
  }|| j        k     rŒ1|d         j        }|d         j        dz   }d	„ |D ¦   «         }d
„ |D ¦   «         }|r!t          t          j        |¦  «        ¦  «        nd}|r!t          t          j        |¦  «        ¦  «        nd}|r|r|| j        z  || j        z  z   }d}n|r|}d}n|}d}|                     t%          |||||||||¬¦	  «	        ¦  «         �Œ�Œû|S )uŒ   
        TÃ­nh offset Delta = t_ref - t_target.
        CÃ¡c Ä‘iá»ƒm khá»›p cÃ¹ng Ä‘oáº¡n sao chÃ©p sáº½ cÃ³ Delta xáº¥p xá»‰ nhau.
        r
   c                ó   — | j         S rS   )r=   )Úxs    r   ú<lambda>z4TemporalMatcher._cluster_and_align.<locals>.<lambda>µ   s   €  q¤z€ r!   ©Úkeyr   rd   g      @éÿÿÿÿg      ð?c                ó2   — g | ]}|j         d k    ¯|j        ‘ŒS )rj   ©rA   r@   ©r_   Úpts     r   ra   z6TemporalMatcher._cluster_and_align.<locals>.<listcomp>Ñ   s&   € ÐPÐPÐP¨2¸¼ÀxÒ8OÐ8O˜bœhÐ8OÐ8OÐ8Or!   c                ó2   — g | ]}|j         d k    ¯|j        ‘ŒS )rn   rž   rŸ   s     r   ra   z6TemporalMatcher._cluster_and_align.<locals>.<listcomp>Ò   s&   € ÐOÐOÐO¨2¸¼ÀwÒ8NÐ8N˜bœhÐ8NÐ8NÐ8Nr!   r   Ú
multimodalÚvisual_onlyÚ
audio_only)	r   r   r   r   r   r   r   r   r   )r   r{   r>   r=   r0   rq   r(   rN   rx   r|   ru   Úsortrt   rM   r   ÚmeanrT   rU   r   )r   r‘   r’   Úoffset_binsr1   ÚdeltaÚbin_idxr“   ÚclusterÚsub_clustersÚcurrent_subÚiÚsubÚt_target_startÚt_target_endÚdurationÚt_ref_startÚ	t_ref_endÚ
vis_scoresÚ
aud_scoresÚvis_avgÚaud_avgÚconfÚmtypes                           r   r}   z"TemporalMatcher._cluster_and_align¢   sò  € õ 7BÅ$Ñ6GÔ6GˆØð 	+ð 	+ˆAØ”G˜aœjÑ(ˆEÝ�"œ( 5¨4Ô+EÑ#EÑFÔFÑGÔGˆGØ˜Ô ×'Ò'¨Ñ*Ô*Ð*Ð*à')ˆà +× 1Ò 1Ñ 3Ô 3ð ;	ñ ;	ÑˆG�WÝ�7‰|Œ|˜aÒÐØð �LŠLÐ1Ð1ˆLÑ2Ô2Ð2ð 79ˆLØ07¸´
¨|ˆKå˜1�c '™lœlÑ+Ô+ð /ð /�Ø˜1”:Ô&¨°°Q±¬Ô)@Ñ@ÀCÒGÐGØ×&Ò& w¨q¤zÑ2Ô2Ð2Ð2å˜;Ñ'Ô'¨1Ò,Ð,Ø$×+Ò+¨KÑ8Ô8Ð8Ø#*¨1¤: ,�K�KÝ�;ÑÔ 1Ò$Ð$Ø×#Ò# KÑ0Ô0Ð0à#ð &ñ &�Ø!$ Q¤¤�Ø" 2œwÔ/°#Ñ5�Ø'¨.Ñ8�à˜dÔ9Ò9Ð9Øà! !œfœl�Ø œGœM¨CÑ/�	ð QÐP°ÐPÑPÔP�
ØOÐO°ÐOÑOÔO�
à8BÐK�%¥¤¨
Ñ 3Ô 3Ñ4Ô4Ð4È�Ø8BÐK�%¥¤¨
Ñ 3Ô 3Ñ4Ô4Ð4È�àð ) *ð )Ø# d¤mÑ3¸À$Ä,Ñ8NÑO�DØ(�E�EØð )Ø"�DØ)�E�Eà"�DØ(�Eà—’¥Ø%3Ø#/Ø'*Ø"-Ø )Ø%)Ø!(Ø 'Ø$ð
!ñ 
!ô 
!ñ 
ô 
ð 
ñ 
ñ9&ðP ˆr!   Útarget_featuresÚAnyÚreference_features_listú	List[Any]c                óˆ  — g }|j         }|j        }|j        }|j        }|D �]}g }	t	          |¦  «        dk    rÙt	          |j        ¦  «        dk    rÁt          j        ||j        j        ¦  «        }
t          j        |
| j	        k    ¦  «        \  }}t          ||¦  «        D ]q\  }}|	                     t          t          ||         ¦  «        t          |j         |         ¦  «        |j        t          |
||f         ¦  «        d¬¦  «        ¦  «         Œr|j        �ö|j        �ït	          |j        ¦  «        dk    r×t	          |j        ¦  «        dk    r¿ddlm}  ||j        |j        ¦  «        }t          j        || j        k    ¦  «        \  }}t          ||¦  «        D ]q\  }}|	                     t          t          ||         ¦  «        t          |j        |         ¦  «        |j        t          |||f         ¦  «        d¬¦  «        ¦  «         Œrnìt	          |¦  «        dk    rÙt	          |j        ¦  «        dk    rÁt          j        ||j        j        ¦  «        }t          j        || j        k    ¦  «        \  }}t          ||¦  «        D ]q\  }}|	                     t          t          ||         ¦  «        t          |j        |         ¦  «        |j        t          |||f         ¦  «        d¬¦  «        ¦  «         Œr|	r0|                      |j        |	¦  «        }|                     |¦  «         �Œ|                      |¦  «        S )uß   
        Ä�á»‘i soÃ¡t tá»©c thÃ¬ (<0.1s) giá»¯a 1 video target vÃ  danh sÃ¡ch video tham chiáº¿u (1, vÃ i video hoáº·c cáº£ kho)
        báº±ng ma tráº­n Ä‘áº·c trÆ°ng Ä‘Ã£ tÃ­nh toÃ¡n vÃ  lÆ°u cache tá»« trÆ°á»›c.
        r   rj   rk   Nr
   )Úcompute_hamming_similarityrn   )Úvisual_timesÚvisual_embsÚaudio_timesÚ	audio_fpsru   rq   ÚdotÚTÚwhererK   Úziprx   r<   r   ri   Ú
audio_bitsÚindexing.quantizerr¿   rL   r}   r~   r   )r   rº   r¼   Úall_segmentsÚt_vis_timesÚ
t_vis_embsÚt_aud_timesÚ	t_aud_fpsÚrefr€   Úsim_visÚq_idxsÚr_idxsÚq_iÚr_ir¿   Úsim_audr“   s                     r   Úmatch_cachedzTemporalMatcher.match_cachedï   s[  € ð ,.ˆà%Ô2ˆØ$Ô0ˆ
Ø%Ô1ˆØ#Ô-ˆ	à*ð 1	.ñ 1	.ˆCØ/1ˆKõ �:‰Œ Ò"Ð"¥s¨3¬?Ñ';Ô';¸aÒ'?Ð'?åœ& ¨S¬_Ô->Ñ?Ô?�Ý!#¤¨'°TÔ5JÒ*JÑ!KÔ!K‘�˜Ý # F¨FÑ 3Ô 3ð ð ‘H�C˜Ø×&Ò&¥}Ý!& {°3Ô'7Ñ!8Ô!8Ý# CÔ$4°SÔ$9Ñ:Ô:Ø%(¤\Ý# G¨C°¨HÔ$5Ñ6Ô6Ø!)ð(ñ (ô (ñ ô ð ð ð  Ô*Ð6Ø”NÐ.Ý˜Ô2Ñ3Ô3°aÒ7Ð7Ý˜œÑ'Ô'¨!Ò+Ð+àKÐKÐKÐKÐKÐKØ4Ð4°_Ô5OÐQTÔQ_Ñ`Ô`�Ý!#¤¨'°TÔ5IÒ*IÑ!JÔ!J‘�˜Ý # F¨FÑ 3Ô 3ð ð ‘H�C˜Ø×&Ò&¥}Ý!& {°3Ô'7Ñ!8Ô!8Ý# C¤O°CÔ$8Ñ9Ô9Ø%(¤\Ý# G¨C°¨HÔ$5Ñ6Ô6Ø!(ð(ñ (ô (ñ ô ð ð ðõ �Y‘” !Ò#Ð#­¨C¬MÑ(:Ô(:¸QÒ(>Ð(>Ýœ& ¨C¬M¬OÑ<Ô<�Ý!#¤¨'°TÔ5IÒ*IÑ!JÔ!J‘�˜Ý # F¨FÑ 3Ô 3ð ð ‘H�C˜Ø×&Ò&¥}Ý!& {°3Ô'7Ñ!8Ô!8Ý# C¤O°CÔ$8Ñ9Ô9Ø%(¤\Ý# G¨C°¨HÔ$5Ñ6Ô6Ø!(ð(ñ (ô (ñ ô ð ð ð ð .Ø×2Ò2°3´<ÀÑMÔM�Ø×#Ò# HÑ-Ô-Ð-ùà×!Ò! ,Ñ/Ô/Ð/r!   ç333333Ó?r“   Úiou_thresholdc                óÚ  — |sg S t          |d„ d¬¦  «        }g }|D ]·}d}|D ]™}t          |j        |j        ¦  «        }t          |j        |j        ¦  «        }	t          d|	|z
  ¦  «        }
|
dk    rJ|j        |j        z   |
z
  }|dk    r|
|z  nd}||k    s!|
t          |j        |j        ¦  «        dz  k    rd} nŒš|s|                     |¦  «         Œ¸|                     d„ ¬	¦  «         |S )
uü   
        Non-Maximum Suppression (NMS) theo trá»¥c thá»�i gian:
        Loáº¡i bá»� cÃ¡c Ä‘oáº¡n trÃ¹ng láº·p chá»“ng láº¥n cá»§a cÃ¹ng má»™t video tham chiáº¿u,
        chá»‰ giá»¯ láº¡i phÃ¢n Ä‘oáº¡n cÃ³ Ä‘á»™ dÃ i vÃ  confidence cao nháº¥t.
        c                ó   — | j         | j        fS rS   )r   r    ©r2   s    r   r™   z/TemporalMatcher._temporal_nms.<locals>.<lambda>>  s   € °aÔ6HÈ!Ì.Ð5Y€ r!   T)r›   ÚreverseFr   r   gffffffæ?c                ó   — | j         S rS   )r   rÛ   s    r   r™   z/TemporalMatcher._temporal_nms.<locals>.<lambda>R  s	   €  Ô 2€ r!   rš   )Úsortedr   r   Úminr   r    rx   r¥   )r   r“   rØ   Úsorted_segsÚkeptÚsegÚoverlapÚkÚinter_startÚ	inter_endÚinterÚunionÚious                r   r   zTemporalMatcher._temporal_nms4  s3  € ð ð 	ØˆIõ ˜XÐ+YÐ+YÐcgÐhÑhÔhˆØ#%ˆàð 	!ð 	!ˆCØˆGØð 
ð 
�å! #Ô"6¸Ô8JÑKÔK�Ý Ô 2°AÔ4DÑEÔE�	Ý˜C ¨[Ñ!8Ñ9Ô9�Ø˜1’9�9Ø Ô-°´Ñ>À%ÑG�EØ+0°1ª9¨9˜% %™-˜-¸!�CØ˜]Ò*Ð*¨eµs¸3Ô;KÈQÌ^Ñ7\Ô7\Ð_bÑ7bÒ.bÐ.bØ"&˜Ø˜øØð !Ø—’˜CÑ Ô Ð øð 	�	Š	Ð2Ð2ˆ	Ñ3Ô3Ð3Øˆr!   N)rD   rE   rF   rG   rH   rI   )rJ   r   rK   r   rL   r   rM   r   rN   r   rO   r   rP   r   r   rQ   )rW   rX   rY   rX   r   rZ   )r‘   r   r’   r•   r   rZ   )rº   r»   r¼   r½   r   rZ   )r×   )r“   rZ   rØ   r   r   rZ   )r4   r5   r6   rV   r”   r}   rÖ   r   r:   r!   r   rC   rC   C   s¥   € € € € € ð #'Ø!%Ø(+Ø'*Ø&*Ø%)ð+ð +ð +ð +ð +ð$J5ð J5ð J5ð J5ðXKð Kð Kð KðZC0ð C0ð C0ð C0ðJð ð ð ð ð ð r!   rC   )Ú__doc__Ú
__future__r   Úcollectionsr   Údataclassesr   Útypingr   r   r   r	   Únumpyrq   Úindexing.databaser   r   r<   rC   r:   r!   r   ú<module>rñ      s.  ððð ð
 #Ð "Ð "Ð "Ð "Ð "à #Ð #Ð #Ð #Ð #Ð #Ø !Ð !Ð !Ð !Ð !Ð !Ø .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .à Ð Ð Ð à -Ð -Ð -Ð -Ð -Ð -ð ð%"ð %"ð %"ð %"ð %"ñ %"ô %"ñ „ð%"ðP ðð ð ð ð ñ ô ñ „ððPð Pð Pð Pð Pñ Pô Pð Pð Pð Pr!   