ó
    á“,jz½  ã                   ó  • S r SSKrSSKrSSKJr  SSKJrJrJrJ	r	J
r
JrJrJrJrJrJrJr  SSKrSSKJr  SSKJrJrJr  SSKJrJr  SS	KJr  SS
KJ r   SSK!J"r"J#r#  SSK$J%r%J&r&J'r'J(r(J)r)J*r*  \(       a  SSK+r, " S S5      r-g)a«	  
##########
Annotation
##########

.. plot:: pyplots/annotation.py

:class:`pyannote.core.Annotation` instances are ordered sets of non-empty
tracks:

  - ordered, because segments are sorted by start time (and end time in case of tie)
  - set, because one cannot add twice the same track
  - non-empty, because one cannot add empty track

A track is a (support, name) pair where `support` is a Segment instance,
and `name` is an additional identifier so that it is possible to add multiple
tracks with the same support.

To define the annotation depicted above:

.. code-block:: ipython

    In [1]: from pyannote.core import Annotation, Segment

    In [6]: annotation = Annotation()
       ...: annotation[Segment(1, 5)] = 'Carol'
       ...: annotation[Segment(6, 8)] = 'Bob'
       ...: annotation[Segment(12, 18)] = 'Carol'
       ...: annotation[Segment(7, 20)] = 'Alice'
       ...:

which is actually a shortcut for

.. code-block:: ipython

    In [6]: annotation = Annotation()
       ...: annotation[Segment(1, 5), '_'] = 'Carol'
       ...: annotation[Segment(6, 8), '_'] = 'Bob'
       ...: annotation[Segment(12, 18), '_'] = 'Carol'
       ...: annotation[Segment(7, 20), '_'] = 'Alice'
       ...:

where all tracks share the same (default) name ``'_'``.

In case two tracks share the same support, use a different track name:

.. code-block:: ipython

    In [6]: annotation = Annotation(uri='my_video_file', modality='speaker')
       ...: annotation[Segment(1, 5), 1] = 'Carol'  # track name = 1
       ...: annotation[Segment(1, 5), 2] = 'Bob'    # track name = 2
       ...: annotation[Segment(12, 18)] = 'Carol'
       ...:

The track name does not have to be unique over the whole set of tracks.

.. note::

  The optional *uri* and *modality* keywords argument can be used to remember
  which document and modality (e.g. speaker or face) it describes.

Several convenient methods are available. Here are a few examples:

.. code-block:: ipython

  In [9]: annotation.labels()   # sorted list of labels
  Out[9]: ['Bob', 'Carol']

  In [10]: annotation.chart()   # label duration chart
  Out[10]: [('Carol', 10), ('Bob', 4)]

  In [11]: list(annotation.itertracks())
  Out[11]: [(<Segment(1, 5)>, 1), (<Segment(1, 5)>, 2), (<Segment(12, 18)>, u'_')]

  In [12]: annotation.label_timeline('Carol')
  Out[12]: <Timeline(uri=my_video_file, segments=[<Segment(1, 5)>, <Segment(12, 18)>])>

See :class:`pyannote.core.Annotation` for the complete reference.
é    N)Údefaultdict)ÚHashableÚOptionalÚDictÚUnionÚIterableÚListÚSetÚTextIOÚTupleÚIteratorÚTextÚTYPE_CHECKING)Ú
SortedDicté   )ÚPYANNOTE_SEGMENTÚPYANNOTE_TRACKÚPYANNOTE_LABEL)ÚSegmentÚSlidingWindow)ÚTimeline)ÚSlidingWindowFeature)Ústring_generatorÚint_generator)ÚLabelÚKeyÚSupportÚLabelGeneratorÚ	TrackNameÚCropModec                   ó6  • \ rS rSrSr\  SXSSS\\   S\\   SS 4S	 jj5       rSXS\\   S\\   4S
 jjr	\
S 5       r\R                  S\4S j5       rS rS rS rS rS\\\\4      4S jrS r SYS\S\\\\\4   \\\\4   4      4S jjrS rSZS\S\4S jjrS[S jrS[S jrS\\\4   4S jr S\\!   4S jr"S\!4S jr#S\$4S  jr%S\\!   4S! jr&S\!4S" jr'S\$4S# jr(S\S$\)S%\*SS 4S& jjr+ S\S'\)S%\*SS 4S( jjr,S]S)\\-\      SS*4S+ jjr.S,\S\/\   4S- jr0S,\S.\S\4S/ jr1S^S0 jr2  SXS,\S1\\   S2\\   S\4S3 jjr3S4 r4S5\54S6 jr6S5\5S\4S7 jr7S5\5S8\4S9 jr8S^S: jr9S\:\   4S; jr; SZS,\S<\S\\/\   \:\   4   4S= jjr<SYS)\-\   S>\SS 4S? jjr=SYS@S S\SS 4SA jjr>SZS8\S\S\4SB jjr?S8\S\4SC jr@S8\S\A4SD jrBSYSE\S\:\\\A4      4SF jjrCS]S$\\)   S\\   4SG jjrDS_SH\ESS 4SI jjrF   S`SJ\\G   SH\ES\SS 4SK jjrHS_SH\ESS 4SL jjrISaSM\ASS 4SN jjrJSS S\\\\\4   \\\4   4      4SO jrKSS S\LRš                  4SP jrN    SbS$\\   SQ\\A\O4   S)\\:\P      SR\\A   4SS jjrQ\  SXST\\\\\4      S\\   S\\   SS 4SU jj5       rRSV rSSWrTg)cÚ
Annotationé‘   zëAnnotation

Parameters
----------
uri : string, optional
    name of annotated resource (e.g. audio or video file)
modality : string, optional
    name of annotated modality

Returns
-------
annotation : Annotation
    New annotation

NÚdfzpd.DataFrameÚuriÚmodalityÚreturnc                 óp   • U[         [        [        /   n[        R	                  UR                  SS9X#5      $ )NF)Úindex)r   r   r   r"   Úfrom_recordsÚ
itertuples)Úclsr$   r%   r&   s       Ú¦C:\Users\johnn\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\pyannote/core/annotation.pyÚfrom_dfÚAnnotation.from_df¢   s4   € ð Ô!¤>´>ÐBÑCˆÜ×&Ñ& r§}¡}¸5 }Ð'AÀ3ÓQÐQó    c                 ór   • Xl         X l        [        5       U l        0 U l        0 U l        S U l        SU l        g )NT)Ú_urir&   r   Ú_tracksÚ_labelsÚ_labelNeedsUpdateÚ	_timelineÚ_timelineNeedsUpdate)Úselfr%   r&   s      r-   Ú__init__ÚAnnotation.__init__­   s:   € à#&Œ	Ø'/Œô
 ?I»lˆŒð
 /1ˆŒØ46ˆÔð $(ˆŒØ*.ˆÕ!r0   c                 ó   • U R                   $ ©N)r2   ©r8   s    r-   r%   ÚAnnotation.uriÁ   s   € à�y‰yÐr0   c                 ó”   • U R                  5        H  nU R                  USS9nXl        M     U R                  SS9nXl        Xl        g )NF©Úcopy)ÚlabelsÚlabel_timeliner%   Úget_timeliner2   )r8   r%   ÚlabelÚtimelines       r-   r%   r>   Å   sM   € ð —[‘[–]ˆEØ×*Ñ*¨5°uÐ*Ð=ˆHØŽLñ #ð ×$Ñ$¨%Ð$Ð0ˆØŒØ�	r0   c                 óè  • [        S U R                  R                  5        5       5      nU Vs0 s H  o"/ _M     nnU R                  SS9 H   u  pEnX!;   d  M  X2   R	                  U5        M"     U Hx  nX2   (       a4  [        X2   U R                  S9U R                  U'   SU R                  U'   M@  U R                  R                  US 5        U R                  R                  US 5        Mz     g s  snf )Nc              3   ó<   #   • U  H  u  pU(       d  M  Uv •  M     g 7fr<   © )Ú.0rE   Úupdates      r-   Ú	<genexpr>Ú+Annotation._updateLabels.<locals>.<genexpr>Ò   s   é € ð 
Ú'E‘m�eÌ�E‰EÒ'Eùs   ‚“	T©Úyield_label©Úsegmentsr%   F)	Úsetr5   ÚitemsÚ
itertracksÚappendr   r%   r4   Úpop)r8   rK   rE   Ú	_segmentsÚsegmentÚtracks         r-   Ú_updateLabelsÚAnnotation._updateLabelsÏ   sà   € ô ñ 
Ø'+×'=Ñ'=×'CÑ'CÔ'Eó
ó 
ˆñ
 -3Ó3ªF 5˜B’Y©Fˆ	Ð3Ø%)§_¡_À _Ó%FÑ!ˆG˜EØ�ØÑ ×'Ñ'¨Ö0ñ &Gó
 ˆEØ×Ü&.¸	Ñ8HÈdÏhÉhÑ&W�—‘˜UÑ#Ø05�×&Ñ& uÓ-à—‘× Ñ  ¨Ô-Ø×&Ñ&×*Ñ*¨5°$Ö7ò ùò 4s   ¯C/c                 ó,   • [        U R                  5      $ )zPNumber of segments

>>> len(annotation)  # annotation contains three segments
3
©Úlenr3   r=   s    r-   Ú__len__ÚAnnotation.__len__å   s   € ô �4—<‘<Ó Ð r0   c                 ó"   • U R                  5       $ r<   )Ú__bool__r=   s    r-   Ú__nonzero__ÚAnnotation.__nonzero__í   s   € Ø�}‰}‹Ðr0   c                 ó2   • [        U R                  5      S:„  $ )zfEmptiness

>>> if annotation:
...    # annotation is not empty
... else:
...    # annotation is empty
r   r]   r=   s    r-   rb   ÚAnnotation.__bool__ð   s   € ô �4—<‘<Ó  1Ñ$Ð$r0   c              #   óH   #   • U R                  SS9 H  u  pnX4v •  M     g7f)z«Iterate over (segment, label) pairs in chronological order

Examples
--------

>>> for segment, label in annotation:
...     # do something with the segment and its label
TrN   N)rT   )r8   rX   Ú_rE   s       r-   Ú__iter__ÚAnnotation.__iter__ú   s*   é € ð "&§¡¸T Ó!BÑˆG˜Ø�.Ô ò "Cùs   ‚ "c                 ó,   • [        U R                  5      $ )zÛIterate over segments (in chronological order)

>>> for segment in annotation.itersegments():
...     # do something with the segment

See also
--------
:class:`pyannote.core.Segment` describes how segments are sorted.
)Úiterr3   r=   s    r-   ÚitersegmentsÚAnnotation.itersegments  s   € ô �D—L‘LÓ!Ð!r0   rO   c              #   ó¾   #   • U R                   R                  5        H;  u  p#[        UR                  5       S S9 H  u  pEU(       a  X$U4v •  M  X$4v •  M     M=     g7f)aæ  Iterate over tracks (in chronological order)

Parameters
----------
yield_label : bool, optional
    When True, yield (segment, track, label) tuples, such that
    annotation[segment, track] == label. Defaults to yielding
    (segment, track) tuple.

Examples
--------

>>> for segment, track in annotation.itertracks():
...     # do something with the track

>>> for segment, track, label in annotation.itertracks(yield_label=True):
...     # do something with the track and its label
c                 ó:   • [        U S   5      [        U S   5      4$ )Nr   r   )Ústr)Útls    r-   Ú<lambda>Ú'Annotation.itertracks.<locals>.<lambda>*  s   € ´°B°q±E³
¼CÀÀ1Á»JÑ/Gr0   ©ÚkeyN)r3   rS   Úsorted)r8   rO   rX   ÚtracksrY   Úlbls         r-   rT   ÚAnnotation.itertracks  sU   é € ð,  $Ÿ|™|×1Ñ1Ö3‰OˆGÜ$Ø—‘“Ñ$Gô‘
�ö Ø!¨#Ð-Ô-à!˜.Ô(óò  4ùs   ‚AAc                 óX   • [        U R                  U R                  S9U l        SU l        g )NrP   F)r   r3   r%   r6   r7   r=   s    r-   Ú_updateTimelineÚAnnotation._updateTimeline1  s    € Ü!¨4¯<©<¸T¿X¹XÑFˆŒØ$)ˆÕ!r0   rA   c                 óž   • U R                   (       a  U R                  5         U(       a  U R                  R                  5       $ U R                  $ )aÕ  Get timeline made of all annotated segments

Parameters
----------
copy : bool, optional
    Defaults (True) to returning a copy of the internal timeline.
    Set to False to return the actual internal timeline (faster).

Returns
-------
timeline : Timeline
    Timeline made of all annotated segments.

Note
----
In case copy is set to False, be careful **not** to modify the returned
timeline, as it may lead to weird subsequent behavior of the annotation
instance.

)r7   r|   r6   rA   )r8   rA   s     r-   rD   ÚAnnotation.get_timeline5  s9   € ð* ×$×$Ø× Ñ Ô"ÞØ—>‘>×&Ñ&Ó(Ð(Ø�~‰~Ðr0   Úotherc                 óˆ   • [         R                  " U R                  SS9UR                  SS95      n[        S U 5       5      $ )zzEquality

>>> annotation == other

Two annotations are equal if and only if their tracks and associated
labels are equal.
TrN   c              3   ó.   #   • U  H  u  pX:H  v •  M     g 7fr<   rI   ©rJ   Út1Út2s      r-   rL   Ú$Annotation.__eq__.<locals>.<genexpr>[  ó   é € Ð7ª,¡ �2–8ª,ùó   ‚)Ú	itertoolsÚzip_longestrT   Úall©r8   r€   ÚpairOfTrackss      r-   Ú__eq__ÚAnnotation.__eq__P  sE   € ô !×,Ò,Ø�O‰O¨ˆOÐ-¨u×/?Ñ/?ÈDÐ/?Ð/Qó
ˆô Ñ7©,Ó7Ó7Ð7r0   c                 óˆ   • [         R                  " U R                  SS9UR                  SS95      n[        S U 5       5      $ )Ú
InequalityTrN   c              3   ó.   #   • U  H  u  pX:g  v •  M     g 7fr<   rI   rƒ   s      r-   rL   Ú$Annotation.__ne__.<locals>.<genexpr>c  r‡   rˆ   )r‰   rŠ   rT   ÚanyrŒ   s      r-   Ú__ne__ÚAnnotation.__ne__]  sC   € ä ×,Ò,Ø�O‰O¨ˆOÐ-¨u×/?Ñ/?ÈDÐ/?Ð/Qó
ˆô Ñ7©,Ó7Ó7Ð7r0   Úincludedc                 ó$   • XR                  SS9;   $ )a+  Inclusion

Check whether every segment of `included` does exist in annotation.

Parameters
----------
included : Segment or Timeline
    Segment or timeline being checked for inclusion

Returns
-------
contains : bool
    True if every segment in `included` exists in timeline,
    False otherwise

Fr@   )rD   )r8   r—   s     r-   Ú__contains__ÚAnnotation.__contains__e  s   € ð" ×,Ñ,°%Ð,Ð8Ñ8Ð8r0   c           
   #   óz  #   • U R                   (       a  U R                   OSn[        U[        5      (       a  SU;   a  SU S3n[        U5      eU R	                  SS9 HY  u  p4n[        U[        5      (       a  SU;   a  SU S3n[        U5      eSU S	UR
                  S
 SUR                  S
 SU S3	v •  M[     g7f)z‚Generate lines for an RTTM file for this annotation

Returns
-------
iterator: Iterator[str]
    An iterator over RTTM text lines
z<NA>Ú zSSpace-separated RTTM file format does not allow file URIs containing spaces (got: "ú").TrN   zPSpace-separated RTTM file format does not allow labels containing spaces (got: "zSPEAKER z 1 ú.3fz <NA> <NA> z <NA> <NA>
N)r%   Ú
isinstancer   Ú
ValueErrorrT   ÚstartÚduration)r8   r%   ÚmsgrX   rh   rE   s         r-   Ú
_iter_rttmÚAnnotation._iter_rttmx  s×   é € ð Ÿ(Ÿ(ˆd�hŠh¨ˆÜ�cœ4× Ñ  S¨C£Zð,Ø,/¨5°ð5ð ô ˜S“/Ð!Ø!%§¡¸T Ó!BÑˆG˜Ü˜%¤×&Ñ&¨3°%«<ð0Ø05¨w°cð;ð ô ! “oÐ%à˜3˜%˜s 7§=¡=°Ð"5°Q°w×7GÑ7GÈÐ6Lð MØ"˜G <ð1ôò "Cùs   ‚B9B;c                 ój   • SR                  U R                  5        Vs/ s H  oPM     sn5      $ s  snf )zdSerialize annotation as a string using RTTM format

Returns
-------
serialized: str
    RTTM string
Ú )Újoinr¤   ©r8   Úlines     r-   Úto_rttmÚAnnotation.to_rttm“  s.   € ð �w‰w¨¯©Ô):Ó;Ò): šÑ):Ñ;Ó<Ð<ùÒ;ó   ž0Úfilec                 óT   • U R                  5        H  nUR                  U5        M     g)z®Dump annotation to file using RTTM format

Parameters
----------
file : file object

Usage
-----
>>> with open('file.rttm', 'w') as file:
...     annotation.write_rttm(file)
N)r¤   Úwrite©r8   r®   rª   s      r-   Ú
write_rttmÚAnnotation.write_rttm�  s!   € ð —O‘OÖ%ˆDØ�J‰J�tÖò &r0   c              #   óö   #   • U R                  SS9 Hb  u  pn[        U[        5      (       a  SU;   a  SU S3n[        U5      eUR                  S SUR                  UR
                  -   S SU S3v •  Md     g7f)	zGenerate lines for a LAB file for this annotation

Returns
-------
iterator: Iterator[str]
    An iterator over LAB text lines
TrN   rœ   zOSpace-separated LAB file format does not allow labels containing spaces (got: "r�   rž   Ú
N)rT   rŸ   r   r    r¡   r¢   )r8   rX   rh   rE   r£   s        r-   Ú	_iter_labÚAnnotation._iter_lab¬  s‹   é € ð "&§¡¸T Ó!BÑˆG˜Ü˜%¤×&Ñ&¨3°%«<ð0Ø05¨w°cð;ð ô ! “oÐ%Ø—]‘] 3Ð' q¨¯©¸×9IÑ9IÑ)IÈ#Ð(NÈaÐPUÈwÐVXÐYÔYò "Cùs   ‚A7A9c                 ój   • SR                  U R                  5        Vs/ s H  oPM     sn5      $ s  snf )zbSerialize annotation as a string using LAB format

Returns
-------
serialized: str
    LAB string
r§   )r¨   r¶   r©   s     r-   Úto_labÚAnnotation.to_lab½  s.   € ð �w‰w¨¯©Ô)9Ó:Ò)9 šÑ)9Ñ:Ó;Ð;ùÒ:r­   c                 óT   • U R                  5        H  nUR                  U5        M     g)z«Dump annotation to file using LAB format

Parameters
----------
file : file object

Usage
-----
>>> with open('file.lab', 'w') as file:
...     annotation.write_lab(file)
N)r¶   r°   r±   s      r-   Ú	write_labÚAnnotation.write_labÇ  s!   € ð —N‘NÖ$ˆDØ�J‰J�tÖò %r0   ÚsupportÚmodec                 óJ  • [        U[        5      (       a$  [        U/U R                  S9nU R	                  XS9$ [        U[        5      (       Ga@  UR                  5       nU R                  U R                  U R                  S9nUS:X  a¿  0 n[        / 5      nU R                  SS9R                  U5       H@  u  pg[        U R                  U   5      nX„U'   UR                  UR                  5       5        MB     [        U5      Ul        U V	s0 s H  o™S_M     sn	Ul        U V	s0 s H  o™S_M     sn	Ul        SUl        SUl        U$ US	:X  aÆ  0 n[        / 5      nU R                  SS9R                  U5       HG  u  pjXj;  a  M  [        U R                  U   5      nX„U'   UR                  UR                  5       5        MI     [        U5      Ul        U V	s0 s H  o™S_M     sn	Ul        U V	s0 s H  o™S_M     sn	Ul        SUl        SUl        U$ US
:X  ag  U R                  SS9R                  U5       HC  u  pjXj-  nU R                  U   R)                  5        H  u  pÉUR+                  X¼S9nX“X¼4'   M     ME     U$ [-        SU-  5      egs  sn	f s  sn	f s  sn	f s  sn	f )a  Crop annotation to new support

Parameters
----------
support : Segment or Timeline
    If `support` is a `Timeline`, its support is used.
mode : {'strict', 'loose', 'intersection'}, optional
    Controls how segments that are not fully included in `support` are
    handled. 'strict' mode only keeps fully included segments. 'loose'
    mode keeps any intersecting segment. 'intersection' mode keeps any
    intersecting segment but replace them by their actual intersection.

Returns
-------
cropped : Annotation
    Cropped annotation

Note
----
In 'intersection' mode, the best is done to keep the track names
unchanged. However, in some cases where two original segments are
cropped into the same resulting segments, conflicting track names are
modified to make sure no track is lost.

rP   ©r¿   ©r%   r&   ÚlooseFr@   TNÚstrictÚintersection)Ú	candidatezunsupported mode: '%s')rŸ   r   r   r%   Úcropr¾   Ú	__class__r&   rR   rD   Úco_iterÚdictr3   rK   Úvaluesr   r5   r4   r7   r6   rS   Ú	new_trackÚNotImplementedError)r8   r¾   r¿   Úcroppedr3   r4   rX   rh   rx   rE   Úother_segmentrÅ   rY   s                r-   rÇ   ÚAnnotation.cropÖ  sš  € ô: �gœw×'Ñ'Ü¨¨	°t·x±xÑ@ˆGØ—9‘9˜W�9Ð0Ð0ä˜¤×*Ò*ð —o‘oÓ'ˆGØ—n‘n¨¯©¸D¿M¹M�nÐJˆGà�w‹à�Ü˜b›'�à"&×"3Ñ"3¸Ð"3Ð"?×"GÑ"GÈÖ"P‘J�GÜ! $§,¡,¨wÑ"7Ó8�FØ'-˜GÑ$Ø—N‘N 6§=¡=£?Ö3ñ #Qô
 #-¨WÓ"5�”áFMÓ,NÂg¸U°Dª[ÁgÑ,N�Ô)Ù<CÓ"DºG°5¨$¢;¹GÑ"D�”à/3�Ô,Ø$(�Ô!à�à˜Ó!à�Ü˜b›'�à.2×.?Ñ.?ÀUÐ.?Ð.K×.SÑ.SØö/Ñ*�Gð Ó3Ù ä! $§,¡,¨wÑ"7Ó8�FØ'-˜GÑ$Ø—N‘N 6§=¡=£?Ö3ñ/ô #-¨WÓ"5�”áFMÓ,NÂg¸U°Dª[ÁgÑ,N�Ô)Ù<CÓ"DºG°5¨$¢;¹GÑ"D�”à/3�Ô,Ø$(�Ô!à�à˜Ó'à.2×.?Ñ.?ÀUÐ.?Ð.K×.SÑ.SØö/Ñ*�Gð $+Ñ#:�LØ(,¯©°WÑ(=×(CÑ(CÖ(E™˜Ø '× 1Ñ 1°,Ð 1Ð P˜Ø7< Ð 3Ó4ó )Fñ/ð �ô *Ð*BÀTÑ*IÓJÐJðE +ùò$ -OùÚ"Dùò2 -OùÚ"Ds   ÄJÄ%JÇJÇ1J Úremovedc                 ó  • [        U[        5      (       a  [        U/5      n[        U R                  5       R	                  5       /U R
                  S9nUR                  US9nUS:X  a  SnOUS:X  a  SnU R                  XBS9$ )a²  Remove segments that overlap `removed` support.

A simple illustration:

.. code-block:: text

    A |------|    |------|                      #
    B                  |----------|             # self
    C |--------------|              |------|    #

                                                #
      |-------|  |-----------|                  # removed
                                                #
      
    A                                           #  
    B                        |---|              # mode="intersection"
    C         |--|                  |------|    # 
                                                 
    A                                           #
    B                                           # mode="loose"
    C                               |------|    # 

    A |------|                                  #
    B                  |----------|             # mode="strict"
    C |--------------|              |------|    #

Parameters
----------
removed : Segment or Timeline
    If `support` is a `Timeline`, its support is used.
mode : {'strict', 'loose', 'intersection'}, optional
    Controls how segments that are not fully included in `removed` are
    handled. 'strict' mode only removes fully included segments. 'loose'
    mode removes any intersecting segment. 'intersection' mode removes
    the overlapping part of any intersecting segment.

Returns
-------
extruded : Annotation
    Extruded annotation

Note
----
In 'intersection' mode, the best is done to keep the track names
unchanged. However, in some cases where two original segments are
cropped into the same resulting segments, conflicting track names are
modified to make sure no track is lost.

©r%   )r¾   rÃ   rÄ   rÁ   )rŸ   r   r   rD   Úextentr%   ÚgapsrÇ   )r8   rÑ   r¿   Ú	extent_tlÚtruncating_supports        r-   ÚextrudeÚAnnotation.extrude;  s   € ôh �gœw×'Ñ'Ü ˜yÓ)ˆGä˜d×/Ñ/Ó1×8Ñ8Ó:Ð;ÀÇÁÑJˆ	Ø$Ÿ\™\°)˜\Ð<Ðà�7‹?Ø‰DØ�XÓØˆDØ�y‰yÐ+ˆyÐ7Ð7r0   rB   r   c                 ó  • U(       a  U R                  U5      nOU n[        UR                  S9nUR                  U5       H-  u  u  pEu  pgXU4   XU4   :X  a  M  UR	                  XF-  5        M/     UR                  5       $ )a1  Get overlapping parts of the annotation.

A simple illustration:

.. code-block:: text

    annotation
    A |------|    |------|      |----|
    B  |--|    |-----|      |----------|
    C |--------------|      |------|

    annotation.get_overlap()
      |------| |-----|      |--------|

    annotation.get_overlap(for_labels=["A", "B"])
       |--|       |--|          |----|

Parameters
----------
labels : optional list of labels
    Labels for which to consider the overlap

Returns
-------
overlap : `pyannote.core.Timeline`
   Timeline of the overlaps.
rÓ   )Úsubsetr   r%   rÉ   Úaddr¾   )r8   rB   Ú
annotationÚoverlaps_tlÚs1r„   Ús2r…   s           r-   Úget_overlapÚAnnotation.get_overlap{  s}   € ö8 ØŸ™ VÓ,‰JàˆJä :§>¡>Ñ2ˆØ",×"4Ñ"4°ZÖ"@Ñ‰HˆR‘h�rà˜�F‰|˜t¨ F™|Ó+ÙØ�O‰O˜B™GÖ$ñ	 #Að
 ×"Ñ"Ó$Ð$r0   rX   c                 óh   • [        U R                  R                  U0 5      R                  5       5      $ )z¿Query tracks by segment

Parameters
----------
segment : Segment
    Query

Returns
-------
tracks : set
    Set of tracks

Note
----
This will return an empty set if segment does not exist.
)rR   r3   ÚgetÚkeys)r8   rX   s     r-   Ú
get_tracksÚAnnotation.get_tracks¤  s)   € ô" �4—<‘<×#Ñ# G¨RÓ0×5Ñ5Ó7Ó8Ð8r0   rY   c                 ó>   • X R                   R                  U0 5      ;   $ )zºCheck whether a given track exists

Parameters
----------
segment : Segment
    Query segment
track :
    Query track

Returns
-------
exists : bool
    True if track exists for segment
)r3   rä   )r8   rX   rY   s      r-   Ú	has_trackÚAnnotation.has_track·  s   € ð Ÿ™×(Ñ(¨°"Ó5Ñ5Ð5r0   c                 óÒ  • U R                  U R                  U R                  S9n/ [        / 5      p2U R                  R                  5        H@  u  pEUR                  UR                  5       5        UR                  U[        U5      45        MB     [        U5      Ul        U Vs0 s H  ofS_M     snUl        U Vs0 s H  ofS_M     snUl        SUl        SUl        U$ s  snf s  snf )zaGet a copy of the annotation

Returns
-------
annotation : Annotation
    Copy of the annotation
rÂ   NT)rÈ   r%   r&   rR   r3   rS   rK   rË   rU   rÊ   r   r4   r5   r6   r7   )r8   Úcopiedr3   r4   rv   ÚvaluerE   s          r-   rA   ÚAnnotation.copyÈ  sÇ   € ð —‘ D§H¡H°t·}±}�ÐEˆð œs 2›w�ØŸ,™,×,Ñ,Ö.‰JˆCØ�N‰N˜5Ÿ<™<›>Ô*Ø�N‰N˜C¤ e£Ð-Ö.ñ /ô $ GÓ,ˆŒá3:Ó;²7¨% š+±7Ñ;ˆŒÙ=DÓ#EºW°E¨4¢K¹WÑ#EˆÔ àˆÔØ&*ˆÔ#àˆùò <ùÚ#Es   Â#CÂ;C$rÆ   Úprefixc                 ó°   • [        U R                  R                  U0 5      5      nUb  X$;  a  U$ Uc  SnSnSX54-  U;   a  US-  nSX54-  U;   a  M  SX54-  $ )a¹  Generate a new track name for given segment

Ensures that the returned track name does not already
exist for the given segment.

Parameters
----------
segment : Segment
    Segment for which a new track name is generated.
candidate : any valid track name, optional
    When provided, try this candidate name first.
prefix : str, optional
    Track name prefix. Defaults to the empty string ''.

Returns
-------
name : str
    New track name
r§   r   z%s%dr   )rR   r3   rä   )r8   rX   rÆ   rï   Úexisting_tracksÚcounts         r-   rÌ   ÚAnnotation.new_trackä  s}   € ô6 ˜dŸl™l×.Ñ.¨w¸Ó;Ó<ˆð Ñ!¨	Ó(HØÐð ‰>ØˆFð ˆØ˜˜Ñ'¨OÓ;Ø�Q‰JˆEð ˜˜Ñ'¨OÕ;ð ˜˜Ñ'Ð'r0   c                 ó�   • SR                  U R                  SS9 VVVs/ s H  u  po1< SU< SU< 3PM     snnn5      $ s  snnnf )zHuman-friendly representationrµ   TrN   rœ   )r¨   rT   )r8   ÚsÚtÚls       r-   Ú__str__ÚAnnotation.__str__  sB   € ð �y‰yØ37·?±?Èt°?Ñ3TÕUÒ3T©¨¨aš1›a¢Ó#Ñ3TÓUó
ð 	
ùÜUs   ŸArv   c                 óæ  • [        U[        5      (       aK  U R                  R                  U5      nSU l        UR                  5        H  u  p4SU R                  U'   M     g[        U[        5      (       ar  [        U5      S:X  ac  U R                  US      nUR                  US   5      nSU R                  U'   U(       d&  U R                  R                  US   5        SU l        gg[        S5      e)zrDelete one track

>>> del annotation[segment, track]

Delete all tracks of a segment

>>> del annotation[segment]
Té   r   r   z:Deletion only works with Segment or (Segment, track) keys.N)
rŸ   r   r3   rV   r7   rS   r5   Útupler^   rÍ   )r8   rv   rx   rY   rE   s        r-   Ú__delitem__ÚAnnotation.__delitem__  sâ   € ô �cœ7×#Ñ#ð
 —\‘\×%Ñ% cÓ*ˆFð )-ˆDÔ%ð !'§¡¦‘�Ø04�×&Ñ& uÓ-ò !/ô ˜œU×#Ñ#¬¨C«°A«ð
 —\‘\ # a¡&Ñ)ˆFð
 —J‘J˜s 1™vÓ&ˆEð -1ˆD×"Ñ" 5Ñ)ö Ø—‘× Ñ   Q¡Ô(Ø,0�Õ)ð ô
 &ØLóð r0   c                 ód   • [        U[        5      (       a  US4nU R                  US      US      $ )zŠGet track label

>>> label = annotation[segment, track]

Note
----
``annotation[segment]`` is equivalent to ``annotation[segment, '_']``

rh   r   r   )rŸ   r   r3   )r8   rv   s     r-   Ú__getitem__ÚAnnotation.__getitem__R  s6   € ô �cœ7×#Ñ#Ø˜�*ˆCà�|‰|˜C ™FÑ# C¨¡FÑ+Ð+r0   rE   c                 ó>  • [        U[        5      (       a  US4nUu  p4U(       d  gX0R                  ;  a  0 U R                  U'   SU l        X@R                  U   ;   a!  U R                  U   U   nSU R                  U'   X R                  U   U'   SU R                  U'   g)aB  Add new or update existing track

>>> annotation[segment, track] = label

If (segment, track) does not exist, it is added.
If (segment, track) already exists, it is updated.

Note
----
``annotation[segment] = label`` is equivalent to ``annotation[segment, '_'] = label``

Note
----
If `segment` is empty, it does nothing.
rh   NT)rŸ   r   r3   r7   r5   )r8   rv   rE   rX   rY   Ú	old_labels         r-   Ú__setitem__ÚAnnotation.__setitem__c  s¢   € ô" �cœ7×#Ñ#Ø˜�*ˆCà‰ˆö Øð Ÿ,™,Ó&Ø$&ˆD�L‰L˜Ñ!Ø(,ˆDÔ%ð —L‘L Ñ)Ó)ØŸ™ WÑ-¨eÑ4ˆIØ04ˆD×"Ñ" 9Ñ-ð (-�‰�WÑ˜eÑ$Ø(,ˆ×Ñ˜uÒ%r0   c                 óJ   • U R                  U R                  U R                  S9$ )zReturn an empty copy

Returns
-------
empty : Annotation
    Empty annotation using the same 'uri' and 'modality' attributes.

rÂ   )rÈ   r%   r&   r=   s    r-   ÚemptyÚAnnotation.empty�  s   € ð �~‰~ $§(¡(°T·]±]ˆ~ÐCÐCr0   c                 óÌ   • [        U R                  R                  5        Vs/ s H  oPM     sn5      (       a  U R                  5         [	        U R
                  [        S9$ s  snf )zSGet sorted list of labels

Returns
-------
labels : list
    Sorted list of labels
ru   )r”   r5   rË   rZ   rw   r4   rq   )r8   Úlnus     r-   rB   ÚAnnotation.labels˜  sR   € ô ˜t×5Ñ5×<Ñ<Ô>Ó?Ò>˜’Ñ>Ñ?×@Ñ@Ø×ÑÔ Ü�d—l‘l¬Ñ,Ð,ùò @s   ¢A!Úuniquec                 ó�   • U R                   R                  U0 5      R                  5       nU(       a  [        U5      $ [	        U5      $ )a¢  Query labels by segment

Parameters
----------
segment : Segment
    Query
unique : bool, optional
    When False, return the list of (possibly repeated) labels.
    Defaults to returning the set of labels.

Returns
-------
labels : set or list
    Set (resp. list) of labels for `segment` if it exists, empty set (resp. list) otherwise
    if unique (resp. if not unique).

Examples
--------
>>> annotation = Annotation()
>>> segment = Segment(0, 2)
>>> annotation[segment, 'speaker1'] = 'Bernard'
>>> annotation[segment, 'speaker2'] = 'John'
>>> print sorted(annotation.get_labels(segment))
set(['Bernard', 'John'])
>>> print annotation.get_labels(Segment(1, 2))
set([])

)r3   rä   rË   rR   Úlist)r8   rX   r  rB   s       r-   Ú
get_labelsÚAnnotation.get_labels¤  s;   € ð@ —‘×!Ñ! '¨2Ó.×5Ñ5Ó7ˆæÜ�v“;Ðä�F‹|Ðr0   Úinvertc                 ó¬  • [        U5      nU(       a  [        U R                  5       5      U-
  nOU[        U R                  5       5      -  nU R                  U R                  U R                  S9n0 [        / 5      pTU R
                  R                  5        H\  u  pgUR                  5        VV	s0 s H  u  p‰X‘;   d  M  X‰_M     n
nn	U
(       d  M9  X¤U'   UR                  U
R                  5       5        M^     [        U5      Ul        U V	s0 s H  o™S_M     sn	Ul
        U V	s0 s H  o™S_M     sn	Ul        SUl        SUl        U$ s  sn	nf s  sn	f s  sn	f )zðFilter annotation by labels

Parameters
----------
labels : iterable
    List of filtered labels
invert : bool, optional
    If invert is True, extract all but requested labels

Returns
-------
filtered : Annotation
    Filtered annotation
rÂ   TN)rR   rB   rÈ   r%   r&   r3   rS   rK   rË   r   r5   r4   r7   r6   )r8   rB   r  Úsubr3   r4   rX   rx   rY   rE   Ú
sub_trackss              r-   rÛ   ÚAnnotation.subsetË  s)  € ô  �V“ˆæÜ˜Ÿ™›Ó'¨&Ñ0‰Fàœc $§+¡+£-Ó0Ñ0ˆFà�n‰n §¡°D·M±MˆnÐBˆàœs 2›w�Ø#Ÿ|™|×1Ñ1Ö3‰OˆGà17·±´ôÚ1?¡ À5Á?“�’±ð ñ ÷ ˆzØ#-˜Ñ Ø—‘˜z×0Ñ0Ó2Ö3ñ  4ô ! Ó)ˆŒá:AÓ Bº'°¨¢¹'Ñ BˆÔÙ07Ó8² u˜d’{±Ñ8ˆŒà#'ˆÔ ØˆŒàˆ
ùóùò !CùÚ8s   Â.EÂ=EÄ
EÄ"ErÝ   c                 ót   • U(       a  U R                  5       OU nUR                  SS9 H  u  pEnXcXE4'   M     U$ )ar  Add every track of an existing annotation (in place)

Parameters
----------
annotation : Annotation
    Annotation whose tracks are being added
copy : bool, optional
    Return a copy of the annotation. Defaults to updating the
    annotation in-place.

Returns
-------
self : Annotation
    Updated annotation

Note
----
Existing tracks are updated with the new label.
TrN   )rA   rT   )r8   rÝ   rA   ÚresultrX   rY   rE   s          r-   rK   ÚAnnotation.update÷  sD   € ö* !%�—‘”¨$ˆð &0×%:Ñ%:ÀtÐ%:Ó%LÑ!ˆG˜EØ%*�7�>Ó"ñ &Mð ˆr0   c                 óü   • XR                  5       ;  a  [        U R                  S9$ U R                  U   (       a  U R	                  5         U(       a  U R
                  U   R                  5       $ U R
                  U   $ )aN  Query segments by label

Parameters
----------
label : object
    Query
copy : bool, optional
    Defaults (True) to returning a copy of the internal timeline.
    Set to False to return the actual internal timeline (faster).

Returns
-------
timeline : Timeline
    Timeline made of all segments for which at least one track is
    annotated as label

Note
----
If label does not exist, this will return an empty timeline.

Note
----
In case copy is set to False, be careful **not** to modify the returned
timeline, as it may lead to weird subsequent behavior of the annotation
instance.

rÓ   )rB   r   r%   r5   rZ   r4   rA   )r8   rE   rA   s      r-   rC   ÚAnnotation.label_timeline  sc   € ð8 Ÿ™›Ó%Ü §¡Ñ)Ð)à×!Ñ! %×(Ø×ÑÔ æØ—<‘< Ñ&×+Ñ+Ó-Ð-à�|‰|˜EÑ"Ð"r0   c                 ó>   • U R                  USS9R                  5       $ )a  Label support

Equivalent to ``Annotation.label_timeline(label).support()``

Parameters
----------
label : object
    Query

Returns
-------
support : Timeline
    Label support

See also
--------
:func:`~pyannote.core.Annotation.label_timeline`
:func:`~pyannote.core.Timeline.support`

Fr@   )rC   r¾   ©r8   rE   s     r-   Úlabel_supportÚAnnotation.label_support;  s#   € ð* ×"Ñ" 5¨uÐ"Ð5×=Ñ=Ó?Ð?r0   c                 ó>   • U R                  USS9R                  5       $ )a(  Label duration

Equivalent to ``Annotation.label_timeline(label).duration()``

Parameters
----------
label : object
    Query

Returns
-------
duration : float
    Duration, in seconds.

See also
--------
:func:`~pyannote.core.Annotation.label_timeline`
:func:`~pyannote.core.Timeline.duration`

Fr@   )rC   r¢   r  s     r-   Úlabel_durationÚAnnotation.label_durationR  s#   € ð, ×"Ñ" 5¨uÐ"Ð5×>Ñ>Ó@Ð@r0   Úpercentc                 ó   ^ • [        U 4S jT R                  5        5       S SS9nU(       aE  [        R                  " U VVs/ s H  u  p4UPM	     snn5      nU VVs/ s H  u  pdXdU-  4PM     nnnU$ s  snnf s  snnf )a5  Get labels chart (from longest to shortest duration)

Parameters
----------
percent : bool, optional
    Return list of (label, percentage) tuples.
    Defaults to returning list of (label, duration) tuples.

Returns
-------
chart : list
    List of (label, duration), sorted by duration in decreasing order.
c              3   óH   >#   • U  H  oTR                  U5      4v •  M     g 7fr<   ©r   )rJ   ÚLr8   s     €r-   rL   Ú#Annotation.chart.<locals>.<genexpr>z  s   øé € Ð@²-¨Q�×$Ñ$ QÓ'Õ(²-ùó   ƒ"c                 ó   • U S   $ ©Nr   rI   ©Úxs    r-   rs   Ú"Annotation.chart.<locals>.<lambda>{  ó   € ˜!˜Aš$r0   T)rv   Úreverse)rw   rB   ÚnpÚsum)r8   r"  Úchartrh   r¢   ÚtotalrE   s   `      r-   r2  ÚAnnotation.chartj  ss   ø€ ô Ü@°$·+±+´-Ó@ÙØñ
ˆö Ü—F’F¹Ô>º©¨›H¹Ò>Ó?ˆEÙHMÔNÊÑ3D°E�e¨Ñ-Ó.ÉˆEÑNàˆùó ?ùÛNs   ÁA4
ÁA:c                 óŠ   ^• U mUb  TR                  USS9mT(       d  g[        U4S jTR                  5        5       S S9S   $ )a¥  Get label with longest duration

Parameters
----------
support : Segment or Timeline, optional
    Find label with longest duration within provided support.
    Defaults to whole extent.

Returns
-------
label : any existing label or None
    Label with longest intersection

Examples
--------
>>> annotation = Annotation(modality='speaker')
>>> annotation[Segment(0, 10), 'speaker1'] = 'Alice'
>>> annotation[Segment(8, 20), 'speaker1'] = 'Bob'
>>> print "%s is such a talker!" % annotation.argmax()
Bob is such a talker!
>>> segment = Segment(22, 23)
>>> if not annotation.argmax(support):
...    print "No label intersecting %s" % segment
No label intersection [22 --> 23]

NrÅ   rÁ   c              3   óH   >#   • U  H  oTR                  U5      4v •  M     g 7fr<   r%  )rJ   rh   rÎ   s     €r-   rL   Ú$Annotation.argmax.<locals>.<genexpr>©  s!   øé € ÐFÒ5E°�×'Ñ'¨Ó*Õ+Ò5Eùr(  c                 ó   • U S   $ r*  rI   r+  s    r-   rs   Ú#Annotation.argmax.<locals>.<lambda>ª  r.  r0   ru   r   )rÇ   ÚmaxrB   )r8   r¾   rÎ   s     @r-   ÚargmaxÚAnnotation.argmax…  sQ   ø€ ð8 ˆØÑØ—l‘l 7°�lÐ@ˆGæØäÜF°W·^±^Ô5EÓFÙñ
ð ñð 	r0   Ú	generatorc                 óà   • U R                  U R                  U R                  S9nUS:X  a  [        5       nOUS:X  a
  [	        5       nU R                  SS9 H  u  p4nXRU[        U5      4'   M     U$ )a«  Rename all tracks

Parameters
----------
generator : 'string', 'int', or iterable, optional
    If 'string' (default) rename tracks to 'A', 'B', 'C', etc.
    If 'int', rename tracks to 0, 1, 2, etc.
    If iterable, use it to generate track names.

Returns
-------
renamed : Annotation
    Copy of the original annotation where tracks are renamed.

Example
-------
>>> annotation = Annotation()
>>> annotation[Segment(0, 1), 'a'] = 'a'
>>> annotation[Segment(0, 1), 'b'] = 'b'
>>> annotation[Segment(1, 2), 'a'] = 'a'
>>> annotation[Segment(1, 3), 'c'] = 'c'
>>> print(annotation)
[ 00:00:00.000 -->  00:00:01.000] a a
[ 00:00:00.000 -->  00:00:01.000] b b
[ 00:00:01.000 -->  00:00:02.000] a a
[ 00:00:01.000 -->  00:00:03.000] c c
>>> print(annotation.rename_tracks(generator='int'))
[ 00:00:00.000 -->  00:00:01.000] 0 a
[ 00:00:00.000 -->  00:00:01.000] 1 b
[ 00:00:01.000 -->  00:00:02.000] 2 a
[ 00:00:01.000 -->  00:00:03.000] 3 c
rÂ   ÚstringÚintTrN   )rÈ   r%   r&   r   r   rT   Únext)r8   r=  Úrenamedrõ   rh   rE   s         r-   Úrename_tracksÚAnnotation.rename_tracks­  so   € ðD —.‘. T§X¡X¸¿¹�.ÐFˆà˜Ó Ü(Ó*‰IØ˜%ÓÜ%›ˆIð  Ÿ?™?°t˜?Ó<‰KˆA�%Ø*/�A”t˜I“Ð&Ó'ñ =àˆr0   Úmappingc           
      ó  • UcJ  US:X  a  [        5       nOUS:X  a
  [        5       nU R                  5        Vs0 s H  oD[        U5      _M     nnU(       a  U R	                  5       OU nUR                  5        H#  u  pgSUR                  U'   SUR                  U'   M%     U R                  R                  5        HF  u  p‰U	R                  5        V
Vs0 s H  u  p¤X¡R                  XD5      _M     nn
nXµR                  U'   MH     U$ s  snf s  snn
f )a‡  Rename labels

Parameters
----------
mapping : dict, optional
    {old_name: new_name} mapping dictionary.
generator : 'string', 'int' or iterable, optional
    If 'string' (default) rename label to 'A', 'B', 'C', ... If 'int',
    rename to 0, 1, 2, etc. If iterable, use it to generate labels.
copy : bool, optional
    Set to True to return a copy of the annotation. Set to False to
    update the annotation in-place. Defaults to True.

Returns
-------
renamed : Annotation
    Annotation where labels have been renamed

Note
----
Unmapped labels are kept unchanged.

Note
----
Parameter `generator` has no effect when `mapping` is provided.

r?  r@  T)	r   r   rB   rA  rA   rS   r5   r3   rä   )r8   rE  r=  rA   rE   rB  r  Ú	new_labelrX   rx   rY   Ú
new_trackss               r-   Úrename_labelsÚAnnotation.rename_labelsÛ  s÷   € ðD ‰?Ø˜HÓ$Ü,Ó.‘	Ø˜eÓ#Ü)›O�	à;?¿;¹;¼=ÓIº=°%œd 9›oÒ-¹=ˆGÐIæ!%�$—)‘)”+¨4ˆà$+§M¡M¦OÑ ˆIØ37ˆG×%Ñ% iÑ0Ø37ˆG×%Ñ% iÓ0ñ %4ð  $Ÿ|™|×1Ñ1Ö3‰OˆGàEKÇ\Á\Ä^ôÚES±\°U�—{‘{ 5Ó0Ò0Á^ð ñ ð (2�O‰O˜GÓ$ñ	  4ð ˆùò Jùós   ·DÃD	c                 ó¸   • US:X  a  [        5       nOUS:X  a
  [        5       nU R                  5       nU R                  SS9 H  u  p4n[	        U5      X#U4'   M     U$ )ar  Relabel tracks

Create a new annotation where each track has a unique label.

Parameters
----------
generator : 'string', 'int' or iterable, optional
    If 'string' (default) relabel tracks to 'A', 'B', 'C', ... If 'int'
    relabel to 0, 1, 2, ... If iterable, use it to generate labels.

Returns
-------
renamed : Annotation
    New annotation with relabeled tracks.
r?  r@  TrN   )r   r   r  rT   rA  )r8   r=  Ú	relabeledrõ   rö   rh   s         r-   Úrelabel_tracksÚAnnotation.relabel_tracks  s^   € ð" ˜Ó Ü(Ó*‰IØ˜%ÓÜ%›ˆIà—J‘J“Lˆ	Ø—‘°4�Ó8‰GˆA�!Ü" 9›oˆI˜�d‹Oñ 9ð Ðr0   Úcollarc                 óö   • [        5       nU R                  5       nU R                  5        HJ  nU R                  USS9nUR	                  U5      nUR	                  5        H  nXCU[        U5      4'   M     ML     U$ )a¼  Annotation support

The support of an annotation is an annotation where contiguous tracks
with same label are merged into one unique covering track.

A picture is worth a thousand words::

    collar
    |---|

    annotation
    |--A--| |--A--|     |-B-|
      |-B-|    |--C--|     |----B-----|

    annotation.support(collar)
    |------A------|     |------B------|
      |-B-|    |--C--|

Parameters
----------
collar : float, optional
    Merge tracks with same label and separated by less than `collar`
    seconds. This is why 'A' tracks are merged in above figure.
    Defaults to 0.

Returns
-------
support : Annotation
    Annotation support

Note
----
Track names are lost in the process.
Tr@   )r   r  rB   rC   r¾   rA  )r8   rO  r=  r¾   rE   rF   rX   s          r-   r¾   ÚAnnotation.support/  s€   € ôH %Ó&ˆ	ð —*‘*“,ˆØ—[‘[–]ˆEð ×*Ñ*¨5°tÐ*Ð<ˆHð  ×'Ñ'¨Ó/ˆHð $×+Ñ+Ö-�Ø49˜¤ i£Ð0Ó1ó .ñ #ð ˆr0   c              #   ó>  #   • U R                  SS9nUR                  SS9nUR                  U5       Hf  u  pE[        U R                  U5      [        S9n[        UR                  U5      [        S9n[
        R                  " Xg5       H  u  p‰XH4XY44v •  M     Mh     g7f)aI  Iterate over pairs of intersecting tracks

Parameters
----------
other : Annotation
    Second annotation

Returns
-------
iterable : (Segment, object), (Segment, object) iterable
    Yields pairs of intersecting tracks, in chronological (then
    alphabetical) order.

See also
--------
:func:`~pyannote.core.Timeline.co_iter`

Fr@   ru   N)rD   rÉ   rw   ræ   rq   r‰   Úproduct)
r8   r€   rF   Úother_timelinerõ   ÚSrx   Úother_tracksrö   ÚTs
             r-   rÉ   ÚAnnotation.co_iterf  s–   é € ð* ×$Ñ$¨%Ð$Ð0ˆØ×+Ñ+°Ð+Ð7ˆØ×$Ñ$ ^Ö4‰DˆAÜ˜DŸO™O¨AÓ.´CÑ8ˆFÜ! %×"2Ñ"2°1Ó"5¼3Ñ?ˆLÜ!×)Ò)¨&Ö?‘�Ø�f˜q˜f�nÔ$ó @ò 5ùs   ‚BBc                 ó  • [        U[        5      (       d  [        S5      eU R                  5       nUR                  5       n[	        U5       VVs0 s H  u  pEXT_M	     nnn[	        U5       VVs0 s H  u  puXW_M	     nnn[
        R                  " [        U5      [        U5      45      n	U R                  U5       H6  u  u  p«u  pÍX`X«4      nX�XÍ4      nX¬-  R                  nX”U4==   U-  ss'   M8     U	$ s  snnf s  snnf )a1  Cooccurrence (or confusion) matrix

>>> matrix = annotation * other

Parameters
----------
other : Annotation
    Second annotation

Returns
-------
cooccurrence : (n_self, n_other) np.ndarray
    Cooccurrence matrix where `n_self` (resp. `n_other`) is the number
    of labels in `self` (resp. `other`).
zCcomputing cooccurrence matrix only works with Annotation instances.)
rŸ   r"   Ú	TypeErrorrB   Ú	enumerater0  Úzerosr^   rÉ   r¢   )r8   r€   Úi_labelsÚj_labelsÚirE   ÚIÚjÚJÚmatrixrX   rY   rÏ   Úother_trackr¢   s                  r-   Ú__mul__ÚAnnotation.__mul__ƒ  s   € ô" ˜%¤×,Ñ,ÜØXóð ð —;‘;“=ˆØ—<‘<“>ˆä&/°Ô&9Ô:Ò&9™(˜!ˆUŠXÑ&9ˆÑ:Ü&/°Ô&9Ô:Ò&9™(˜!ˆUŠXÑ&9ˆÑ:ä—’œ3˜q›6¤3 q£6Ð*Ó+ˆð ?C¿l¹lÈ5Ö>QÑ:ÑˆWÑ:˜}Ø�w�~Ñ&Ñ'ˆAØ˜Ð2Ñ3Ñ4ˆAØÑ/×9Ñ9ˆHØ�a�4‹L˜HÑ$�Lñ	 ?Rð ˆùó ;ùÛ:s   ÁC6Á.C<Ú
resolutionr¢   c                 ó  • Uc  U R                  5       R                  5       nUu  pVU R                  USS9nUc  UR                  5       n[	        U[
        5      (       a  [        XRR                  UR                  S9nO
[        XRUS9nUR                  U5      nUc  UR                  U5      n	X˜-
  n
O [        [        XBR                  -  5      5      n
[        R                  " U
[        U5      4[        R                  S9n[        U5       HV  u  pÍUR!                  U5      nUR                  USSS9 H+  u  nnU[#        SU5      [%        UU
5      2U4==   S	-  ss'   M-     MX     [        R&                  " US	US
9n[)        X²US9$ )a?  Discretize

Parameters
----------
support : Segment, optional
    Part of annotation to discretize. 
    Defaults to annotation full extent.
resolution : float or SlidingWindow, optional
    Defaults to 10ms frames.
labels : list of labels, optional
    Defaults to self.labels()
duration : float, optional
    Overrides support duration and ensures that the number of
    returned frames is fixed (which might otherwise not be the case
    because of rounding errors).

Returns
-------
discretized : SlidingWindowFeature
    (num_frames, num_labels)-shaped binary features.
rÅ   rÁ   )r¡   Ústepr¢   )ÚdtypeÚcenterT)r¿   Úreturn_rangesr   r   )Úout)rB   )rD   rÔ   rÇ   rB   rŸ   r   ri  r¢   Úclosest_framer@  Úroundr0  r\  r^   Úuint8r[  rC   r:  ÚminÚminimumr   )r8   r¾   rg  rB   r¢   Ú
start_timeÚend_timerÎ   Ústart_frameÚ	end_frameÚ
num_framesÚdataÚkrE   rQ   r¡   Ústops                    r-   Ú
discretizeÚAnnotation.discretizeª  ss  € ð: ‰?Ø×'Ñ'Ó)×0Ñ0Ó2ˆGØ&Ñˆ
à—)‘)˜G¨.�)Ð9ˆà‰>Ø—^‘^Ó%ˆFä�j¤-×0Ñ0Ü&Ø §¡À×ATÑATñ‰Jô 'Ø ¸JñˆJð !×.Ñ.¨zÓ:ˆØÑØ"×0Ñ0°Ó:ˆIØ"Ñ0‰JäœU 8¯o©oÑ#=Ó>Ó?ˆJä�xŠx˜¤S¨£[Ð1¼¿¹ÑBˆÜ! &Ö)‰HˆAØ×-Ñ-¨eÓ4ˆHØ)Ÿ™Ø˜x°tð  /ó  ‘��tð ”S˜˜E“]¤S¨¨zÓ%:Ð:¸AÐ=Ó>À!ÑCÕ>ó ñ *ô �zŠz˜$  tÑ,ˆä# D¸VÑDÐDr0   Úrecordsc                 óP  • U " X#S9n[        [        5      n[        5       nU H  u  pxn	X•U   U'   UR                  U	5        M      [	        U5      Ul        U V	s0 s H  o™S_M     sn	Ul        UR                   V	s0 s H  o™S_M     sn	Ul        SUl        SUl	        U$ s  sn	f s  sn	f )a+  Annotation

Parameters
----------
records : iterator of tuples
    (segment, track, label) tuples
uri : string, optional
    name of annotated resource (e.g. audio or video file)
modality : string, optional
    name of annotated modality

Returns
-------
annotation : Annotation
    New annotation

rÂ   NT)
r   rÊ   rR   rÜ   r   r3   r4   r5   r6   r7   )
r,   r}  r%   r&   rÝ   rx   rB   rX   rY   rE   s
             r-   r*   ÚAnnotation.from_recordsë  s­   € ñ0 ˜SÑ4ˆ
ÜœTÓ"ˆÜ“ˆÛ%,Ñ!ˆG˜EØ%*�7‰O˜EÑ"Ø�J‰J�uÖñ &-ô (¨Ó/ˆ
ÔÙ7=Ó>²v¨e Tšk±vÑ>ˆ
ÔØAK×ASÒASÓ'TÒAS¸¨tªÑASÑ'Tˆ
Ô$Ø#ˆ
ÔØ*.ˆ
Ô'àÐùò ?ùÚ'Ts   ÁBÁ:B#c                 ó¬   • SSK JnJn  U(       d8  [        R                  " UR                  U R                  R                  S95        gSSK Jn  U" U 5      $ )zJIPython notebook support

See also
--------
:mod:`pyannote.core.notebook`
r   )ÚMATPLOTLIB_IS_AVAILABLEÚMATPLOTLIB_WARNING)ÚklassN)Úrepr_annotation)	Únotebookr�  r‚  ÚwarningsÚwarnÚformatrÈ   Ú__name__r„  )r8   r�  r‚  r„  s       r-   Ú
_repr_png_ÚAnnotation._repr_png_  sA   € ÷ 	Jæ&Ü�MŠMÐ,×3Ñ3¸$¿.¹.×:QÑ:QÐ3ÐRÔSØå-á˜tÓ$Ð$r0   )r5   r4   r6   r7   r3   r2   r&   )NN)F)T)r€   r"   )rÅ   r<   )r'   r"   )r?  )Nr?  T)g        )Ng{®Gáz„?NN)Ur‰  Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Úclassmethodr   rq   r.   r9   Úpropertyr%   ÚsetterrZ   r_   rc   rb   r   r   r   r   ri   rm   Úboolr   r   rT   r|   r   rD   rŽ   r•   r™   r   r¤   r«   r   r²   r¶   r¹   r¼   r   r    rÇ   rØ   r   rá   r
   ræ   ré   rA   rÌ   rø   r   rý   r   r  r  r	   rB   r  rÛ   rK   rC   r  Úfloatr   r2  r;  r   rC  r   rI  rM  r¾   rÉ   r0  Úndarrayre  r   r   r{  r*   rŠ  Ú__static_attributes__rI   r0   r-   r"   r"   ‘   s<  † ñð  ð "Ø"&ñ	RàðRð �c‰]ðRð ˜3‘-ð	Rð
 
ôRó ðRñ/˜H S™Mð /¸HÀS¹Mõ /ð( ñó ðð 	‡Z�Zð�só ó ðò8ò,!òò%ð
!˜( 5¨°%¨Ñ#8Ñ9ô 
!ò
"ð #(ñ)Øð)à	�%˜˜g yÐ0Ñ1°5¸À)ÈUÐ9RÑ3SÐSÑTÑ	Uõ)ò>*ñ ð °õ ô68ô8ð9 U¨7°HÐ+<Ñ%=ô 9ð&˜H T™Nô ð6=˜ô =ð˜vô ðZ˜8 D™>ô Zð"<˜ô <ð˜fô ñcK˜Gð cK¨8ð cKÈõ cKðL 2@ñ>8Øð>8Ø&.ð>8à	õ>8ñ@'% (¨8°E©?Ñ";ð '%Àzõ '%ðR9 'ð 9¨c°)©nô 9ð&6 ð 6°ð 6¸tô 6ô"ð> *.Ø $ñ	0(àð0(ð ˜IÑ&ð0(ð ˜‘ð	0(ð
 
õ0(òd
ð2˜sô 2ðj,˜sð , uô ,ð"(-˜sð (-¨5ô (-ôT	Dð
-˜˜U™ô 
-ð 04ñ%Øð%Ø(,ð%à	ˆs�5‰z˜4 ™;Ð&Ñ	'õ%ñN*˜X e™_ð *°dð *À|õ *ñX ð °Tð Àlõ ñ:%# Eð %#°ð %#Àõ %#ðN@ 5ð @¨Xô @ð.A Eð A¨eô Añ0˜Tð ¨d°5¸À¸Ñ3FÑ.Gõ ñ6&˜h wÑ/ð &¸8ÀE¹?õ &ñP, ~ð ,À\õ ,ð` #'Ø$,Øñ	6à˜$‘ð6ð "ð6ð ð	6ð
 
õ6ñp¨ð Àlõ ñ85˜eð 5¨lõ 5ðn%Ø!ð%à	�%˜˜g yÐ0Ñ1°5¸À)Ð9KÑ3LÐLÑMÑ	Nô%ð:%˜\ð %¨b¯j©jô %ðR &*Ø26Ø+/Ø$(ñ?Eà˜'Ñ"ð?Eð ˜% Ð.Ñ/ð?Eð ˜˜h™Ñ(ð	?Eð
 ˜5‘/õ?EðB ð "Ø"&ñ	#à˜% ¨°EÐ 9Ñ:Ñ;ð#ð �c‰]ð#ð ˜3‘-ð	#ð
 
ô#ó ð#õJ%r0   r"   ).r�  r‰   r†  Úcollectionsr   Útypingr   r   r   r   r   r	   r
   r   r   r   r   r   Únumpyr0  Úsortedcontainersr   r§   r   r   r   rX   r   r   rF   r   Úfeaturer   Úutils.generatorsr   r   Úutils.typesr   r   r   r   r   r    ÚpandasÚpdr"   rI   r0   r-   Ú<module>r      sc   ðñ<Nó^ Û Ý #÷÷ ÷ ó ó Ý '÷ñ ÷
 ,Ý Ý )ß =ß Q× QæÛ÷O%ò O%r0   