o
    pi                     @   s   d Z ddlZddlmZmZmZmZmZmZm	Z	m
Z
mZmZm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 e
rHdd	lmZ ddlZG d
d dZdS )aW  
########
Timeline
########

.. plot:: pyplots/timeline.py

:class:`pyannote.core.Timeline` instances are ordered sets of non-empty
segments:

  - ordered, because segments are sorted by start time (and end time in case of tie)
  - set, because one cannot add twice the same segment
  - non-empty, because one cannot add empty segments (*i.e.* start >= end)

There are two ways to define the timeline depicted above:

.. code-block:: ipython

  In [25]: from pyannote.core import Timeline, Segment

  In [26]: timeline = Timeline()
     ....: timeline.add(Segment(1, 5))
     ....: timeline.add(Segment(6, 8))
     ....: timeline.add(Segment(12, 18))
     ....: timeline.add(Segment(7, 20))
     ....:

  In [27]: segments = [Segment(1, 5), Segment(6, 8), Segment(12, 18), Segment(7, 20)]
     ....: timeline = Timeline(segments=segments, uri='my_audio_file')  # faster
     ....:

  In [9]: for segment in timeline:
     ...:     print(segment)
     ...:
  [ 00:00:01.000 -->  00:00:05.000]
  [ 00:00:06.000 -->  00:00:08.000]
  [ 00:00:07.000 -->  00:00:20.000]
  [ 00:00:12.000 -->  00:00:18.000]


.. note::

  The optional *uri*  keyword argument can be used to remember which document it describes.

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

.. code-block:: ipython

  In [3]: timeline.extent()    # extent
  Out[3]: <Segment(1, 20)>

  In [5]: timeline.support()  # support
  Out[5]: <Timeline(uri=my_audio_file, segments=[<Segment(1, 5)>, <Segment(6, 20)>])>

  In [6]: timeline.duration()  # support duration
  Out[6]: 18


See :class:`pyannote.core.Timeline` for the complete reference.
    N)OptionalIterableListUnionCallableTextIOTupleTYPE_CHECKINGIteratorDictText)
SortedList   )PYANNOTE_SEGMENT)Segment)SupportLabelCropMode
Annotationc                   @   sB  e Zd ZdZedpdddee dd fddZ		dqd	eee	  defd
dZ
dd Zdd Zdd Zdee	 fddZdede	fddZdrddZdrddZde	defddZde	dd fdd Zde	dd fd!d"Zde	dd fd#d$Zdsd&d'Zd%e	dd fd(d)Zdsd*d+Zdsd,d-Zdd deee	e	f  fd.d/Z	0	1dtd2ed3ed4e dee!ee	e	f e	f  fd5d6Z"	0	1dtd2ed3ed4e de!d ed e#e	e	f f f fd7d8Z$d9e%de&e	 fd:d;Z'd9e%dee	 fd<d=Z(dud>d?Z)	0dvd@ed3edd fdAdBZ*dCdD Z+dEdF Z,dGe!e	d f fdHdIZ-dudJdKZ.dd de fdLdMZ/dpdNee0e	ge	f  dd fdOdPZ1de	fdQdRZ2dwdTe%dee	 fdUdVZ3dwdTe%dd fdWdXZ4de%fdYdZZ5dpd2ee dee	 fd[d\Z6dpd2ee dd fd]d^Z7dud_d`Z8	a	dxdbe!eee9 ddf dcee dddfdedfZ:dee; fdgdhZ<de;fdidjZ=dke>fdldmZ?dndo Z@dS )yTimelinea  
    Ordered set of segments.

    A timeline can be seen as an ordered set of non-empty segments (Segment).
    Segments can overlap -- though adding an already exisiting segment to a
    timeline does nothing.

    Parameters
    ----------
    segments : Segment iterator, optional
        initial set of (non-empty) segments
    uri : string, optional
        name of segmented resource

    Returns
    -------
    timeline : Timeline
        New timeline
    Ndfzpd.DataFrameurireturnc                 C   s   t |t }| ||d}|S )Nsegmentsr   )listr   )clsr   r   r   timeline r   J/home/ubuntu/.local/lib/python3.10/site-packages/pyannote/core/timeline.pyfrom_df   s   zTimeline.from_dfr   c                 C   sP   |d u rd}t dd |D }|| _t|| _dd |D }t|| _|| _d S )Nr   c                 S   s   g | ]}|r|qS r   r   ).0segmentr   r   r    
<listcomp>       z%Timeline.__init__.<locals>.<listcomp>c                 s       | ]
}|D ]}|V  qqd S Nr   r"   r#   boundaryr   r   r    	<genexpr>       z$Timeline.__init__.<locals>.<genexpr>)setsegments_set_r   segments_list_segments_boundaries_r   )selfr   r   segments_set
boundariesr   r   r    __init__   s   


zTimeline.__init__c                 C   
   t | jS )zdNumber of segments

        >>> len(timeline)  # timeline contains three segments
        3
        lenr-   r0   r   r   r    __len__      
zTimeline.__len__c                 C   s   |   S r'   )__bool__r7   r   r   r    __nonzero__   s   zTimeline.__nonzero__c                 C   s   t | jdkS )zEmptiness

        >>> if timeline:
        ...    # timeline is not empty
        ... else:
        ...    # timeline is empty
        r   r5   r7   r   r   r    r:      s   zTimeline.__bool__c                 C   r4   )zIterate over segments (in chronological order)

        >>> for segment in timeline:
        ...     # do something with the segment

        See also
        --------
        :class:`pyannote.core.Segment` describes how segments are sorted.
        )iterr.   r7   r   r   r    __iter__   s   

zTimeline.__iter__kc                 C   s
   | j | S )zGet segment by index (in chronological order)

        >>> first_segment = timeline[0]
        >>> penultimate_segment = timeline[-2]
        )r.   )r0   r>   r   r   r    __getitem__   r9   zTimeline.__getitem__otherc                 C   s   | j |j kS )aq  Equality

        Two timelines are equal if and only if their segments are equal.

        >>> timeline1 = Timeline([Segment(0, 1), Segment(2, 3)])
        >>> timeline2 = Timeline([Segment(2, 3), Segment(0, 1)])
        >>> timeline3 = Timeline([Segment(2, 3)])
        >>> timeline1 == timeline2
        True
        >>> timeline1 == timeline3
        False
        r-   r0   r@   r   r   r    __eq__   s   zTimeline.__eq__c                 C   s   | j |j kS )
InequalityrA   rB   r   r   r    __ne__   s   zTimeline.__ne__r#   c                 C   s   | j |S )aI  Get index of (existing) segment

        Parameters
        ----------
        segment : Segment
            Segment that is being looked for.

        Returns
        -------
        position : int
            Index of `segment` in timeline

        Raises
        ------
        ValueError if `segment` is not present.
        )r.   indexr0   r#   r   r   r    rF      s   zTimeline.indexc                 C   sN   | j }||v s	|s| S || | j| | j}||j ||j | S )a  Add a segment (in place)

        Parameters
        ----------
        segment : Segment
            Segment that is being added

        Returns
        -------
        self : Timeline
            Updated timeline.

        Note
        ----
        If the timeline already contains this segment, it will not be added
        again, as a timeline is meant to be a **set** of segments (not a list).

        If the segment is empty, it will not be added either, as a timeline
        only contains non-empty segments.
        )r-   addr.   r/   startendr0   r#   r-   r/   r   r   r    rH      s   
zTimeline.addc                 C   sJ   | j }||vr	| S || | j| | j}||j ||j | S )aJ  Remove a segment (in place)

        Parameters
        ----------
        segment : Segment
            Segment that is being removed

        Returns
        -------
        self : Timeline
            Updated timeline.

        Note
        ----
        If the timeline does not contain this segment, this does nothing
        )r-   remover.   r/   rI   rJ   rK   r   r   r    rL     s   
zTimeline.removec                 C   
   |  |S )zjSame as `remove`

        See also
        --------
        :func:`pyannote.core.Timeline.remove`
        )rL   rG   r   r   r    discard7  s   
zTimeline.discardr   c                 C   rM   r'   )updater0   r   r   r   r    __ior__@     
zTimeline.__ior__c                 C   s6   | j }||j O }t|| _dd |D }t|| _| S )a  Add every segments of an existing timeline (in place)

        Parameters
        ----------
        timeline : Timeline
            Timeline whose segments are being added

        Returns
        -------
        self : Timeline
            Updated timeline

        Note
        ----
        Only segments that do not already exist will be added, as a timeline is
        meant to be a **set** of segments (not a list).

        c                 s   r&   r'   r   r(   r   r   r    r*   _  r+   z"Timeline.update.<locals>.<genexpr>)r-   r   r.   r/   )r0   r   r1   r2   r   r   r    rO   C  s   


zTimeline.updatec                 C   rM   r'   )unionrP   r   r   r    __or__d  rR   zTimeline.__or__c                 C   s   | j |j B }t|| jdS )a  Create new timeline made of union of segments

        Parameters
        ----------
        timeline : Timeline
            Timeline whose segments are being added

        Returns
        -------
        union : Timeline
            New timeline containing the union of both timelines.

        Note
        ----
        This does the same as timeline.update(...) except it returns a new
        timeline, and the original one is not modified.
        r   )r-   r   r   )r0   r   r   r   r   r    rS   g  s   zTimeline.unionc                 c   sJ    | j D ]}t|j|jd}|j j|dD ]}||r!||fV  qqdS )a  Iterate over pairs of intersecting segments

        >>> timeline1 = Timeline([Segment(0, 2), Segment(1, 2), Segment(3, 4)])
        >>> timeline2 = Timeline([Segment(1, 3), Segment(3, 5)])
        >>> for segment1, segment2 in timeline1.co_iter(timeline2):
        ...     print(segment1, segment2)
        (<Segment(0, 2)>, <Segment(1, 3)>)
        (<Segment(1, 2)>, <Segment(1, 3)>)
        (<Segment(3, 4)>, <Segment(3, 5)>)

        Parameters
        ----------
        other : Timeline
            Second timeline

        Returns
        -------
        iterable : (Segment, Segment) iterable
            Yields pairs of intersecting segments in chronological order.
        rI   rJ   maximumN)r.   r   rJ   irange
intersects)r0   r@   r#   tempother_segmentr   r   r    co_iter|  s   


zTimeline.co_iterintersectionFsupportmodereturns_mappingc           
      c   s   |dvr	t dt|ttfstdt|tr8|r|g}ng }t|| jd}| j|||dD ]}|V  q0dS | }|dkrO| |D ]\}}|V  qEdS |dkrf| |D ]\}}||v rc|V  qXdS | |D ]\}}||@ }	|	svqk|r~||	fV  qk|	V  qkdS )	zLike `crop` but returns a segment iterator instead

        See also
        --------
        :func:`pyannote.core.Timeline.crop`
        >   loosestrictr]   z9Mode must be one of 'loose', 'strict', or 'intersection'.z(Support must be a Segment or a Timeline.r   r_   r`   Nra   rb   )	
ValueError
isinstancer   r   	TypeErrorr   	crop_iterr^   r\   )
r0   r^   r_   r`   r   yieldedr#   _r[   	mapped_tor   r   r    rg     sD   

zTimeline.crop_iterc                 C   s|   |dkr2|r2g i }}| j |dddD ]\}}|| ||t |g ||< qt|| jd|fS t| j ||d| jdS )a  Crop timeline 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_mapping : bool, optional
            In 'intersection' mode, return a dictionary whose keys are segments
            of the cropped timeline, and values are list of the original
            segments that were cropped. Defaults to False.

        Returns
        -------
        cropped : Timeline
            Cropped timeline
        mapping : dict
            When 'returns_mapping' is True, dictionary whose keys are segments
            of 'cropped', and values are lists of corresponding original
            segments.

        Examples
        --------

        >>> timeline = Timeline([Segment(0, 2), Segment(1, 2), Segment(3, 4)])
        >>> timeline.crop(Segment(1, 3))
        <Timeline(uri=None, segments=[<Segment(1, 2)>])>

        >>> timeline.crop(Segment(1, 3), mode='loose')
        <Timeline(uri=None, segments=[<Segment(0, 2)>, <Segment(1, 2)>])>

        >>> timeline.crop(Segment(1, 3), mode='strict')
        <Timeline(uri=None, segments=[<Segment(1, 2)>])>

        >>> cropped, mapping = timeline.crop(Segment(1, 3), returns_mapping=True)
        >>> print(mapping)
        {<Segment(1, 2)>: [<Segment(0, 2)>, <Segment(1, 2)>]}

        r]   Trc   r   r_   )rg   appendgetr   r   r   )r0   r^   r_   r`   r   mappingr#   rj   r   r   r    crop  s   1

zTimeline.croptc                 C   s   t | |S )a  Get list of segments overlapping `t`

        Parameters
        ----------
        t : float
            Timestamp, in seconds.

        Returns
        -------
        segments : list
            List of all segments of timeline containing time t
        )r   overlapping_iter)r0   rp   r   r   r    overlapping  s   zTimeline.overlappingc                 c   s6    t ||d}| jj|dD ]
}||r|V  qdS )zLike `overlapping` but returns a segment iterator instead

        See also
        --------
        :func:`pyannote.core.Timeline.overlapping`
        rU   rV   N)r   r.   rX   overlaps)r0   rp   r#   r   r   r    rq      s   
zTimeline.overlapping_iterc                 C   s@   t | jd}| | D ]\}}||krq|||@  q| S )a  Get overlapping parts of the timeline.

        A simple illustration:

        .. code-block:: text

            timeline
            |------|    |------|      |----|
              |--|    |-----|      |----------|

            timeline.get_overlap()
              |--|      |---|         |----|

        Returns
        -------
        overlap : `pyannote.core.Timeline`
           Timeline of the overlaps.
        r   )r   r   r\   rH   r^   )r0   overlaps_tls1s2r   r   r    get_overlap,  s   zTimeline.get_overlapremovedc                 C   s\   t |tr
t|g}t|  g| jd}|j|d}|dkr!d}n|dkr'd}| j||dS )am  Remove segments that overlap `removed` support.

        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 : Timeline
            Extruded timeline

        Examples
        --------

        >>> timeline = Timeline([Segment(0, 2), Segment(1, 2), Segment(3, 5)])
        >>> timeline.extrude(Segment(1, 2))
        <Timeline(uri=None, segments=[<Segment(0, 1)>, <Segment(3, 5)>])>

        >>> timeline.extrude(Segment(1, 3), mode='loose')
        <Timeline(uri=None, segments=[<Segment(3, 5)>])>

        >>> timeline.extrude(Segment(1, 3), mode='strict')
        <Timeline(uri=None, segments=[<Segment(0, 2)>, <Segment(3, 5)>])>

        rt   r^   ra   rb   rk   )re   r   r   extentr   gapsro   )r0   ry   r_   	extent_tltruncating_supportr   r   r    extrudeF  s   
"
zTimeline.extrudec                 C   sR   t | j}d}t| jD ]\}}|t|7 }||d |k rdnd7 }q|d7 }|S )zHuman-readable representation

        >>> timeline = Timeline(segments=[Segment(0, 10), Segment(1, 13.37)])
        >>> print(timeline)
        [[ 00:00:00.000 -->  00:00:10.000]
         [ 00:00:01.000 -->  00:00:13.370]]

        [r   z
  ])r6   r.   	enumeratestr)r0   nstringir#   r   r   r    __str__t  s   

zTimeline.__str__c                 C   s   d| j t| jf S )zComputer-readable representation

        >>> Timeline(segments=[Segment(0, 10), Segment(1, 13.37)])
        <Timeline(uri=None, segments=[<Segment(0, 10)>, <Segment(1, 13.37)>])>

        z<Timeline(uri=%s, segments=%s)>)r   r   r.   r7   r   r   r    __repr__  s   zTimeline.__repr__includedc                 C   s4   t |tr
|| jv S t |tr| j|jS td)a  Inclusion

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

        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

        Examples
        --------
        >>> timeline1 = Timeline(segments=[Segment(0, 10), Segment(1, 13.37)])
        >>> timeline2 = Timeline(segments=[Segment(0, 10)])
        >>> timeline1 in timeline2
        False
        >>> timeline2 in timeline1
        >>> Segment(1, 13.37) in timeline1
        True

        zCChecking for inclusion only supports Segment and Timeline instances)re   r   r-   r   
issupersetrf   )r0   r   r   r   r    __contains__  s   


zTimeline.__contains__c                 C   s   t | jdS )zReturn an empty copy

        Returns
        -------
        empty : Timeline
            Empty timeline using the same 'uri' attribute.

        rt   )r   r   r7   r   r   r    empty  s   	zTimeline.emptyc                 C   s(   | j | d}||D ]} dS dS )at  Check whether other timeline is fully covered by the timeline
        
        Parameter
        ---------
        other : Timeline
            Second timeline

        Returns
        -------
        covers : bool
            True if timeline covers "other" timeline entirely. False if at least
            one segment of "other" is not fully covered by timeline
        rz   FT)r|   r{   r\   )r0   r@   r|   ri   r   r   r    covers  s   zTimeline.coverssegment_funcc                    s6    du rt | j| jdS t  fdd| jD | jdS )a  Get a copy of the timeline

        If `segment_func` is provided, it is applied to each segment first.

        Parameters
        ----------
        segment_func : callable, optional
            Callable that takes a segment as input, and returns a segment.
            Defaults to identity function (segment_func(segment) = segment)

        Returns
        -------
        timeline : Timeline
            Copy of the timeline

        Nr   c                    s   g | ]} |qS r   r   r"   sr   r   r    r$     r%   z!Timeline.copy.<locals>.<listcomp>)r   r.   r   )r0   r   r   r   r    copy  s
   zTimeline.copyc                 C   s4   | j r| j}|d }|d }t||dS tdddS )a  Extent

        The extent of a timeline is the segment of minimum duration that
        contains every segments of the timeline. It is unique, by definition.
        The extent of an empty timeline is an empty segment.

        A picture is worth a thousand words::

            timeline
            |------|    |------|     |----|
              |--|    |-----|     |----------|

            timeline.extent()
            |--------------------------------|

        Returns
        -------
        extent : Segment
            Timeline extent

        Examples
        --------
        >>> timeline = Timeline(segments=[Segment(0, 1), Segment(9, 10)])
        >>> timeline.extent()
        <Segment(0, 10)>

        r   rU           )r-   r/   r   )r0   r/   rI   rJ   r   r   r    r{     s   zTimeline.extentr   collarc                 c   sR    | sdS | j d }| D ]}||A }|r|j|k r||O }q|V  |}q|V  dS )zLike `support` but returns a segment generator instead

        See also
        --------
        :func:`pyannote.core.Timeline.support`
        Nr   )r.   duration)r0   r   new_segmentr#   possible_gapr   r   r    support_iter   s   	


zTimeline.support_iterc                 C   s   t | || jdS )a  Timeline support

        The support of a timeline is the timeline with the minimum number of
        segments with exactly the same time span as the original timeline. It
        is (by definition) unique and does not contain any overlapping
        segments.

        A picture is worth a thousand words::

            collar
            |---|

            timeline
            |------|    |------|      |----|
              |--|    |-----|      |----------|

            timeline.support()
            |------|  |--------|   |----------|

            timeline.support(collar)
            |------------------|   |----------|

        Parameters
        ----------
        collar : float, optional
            Merge separated by less than `collar` seconds. This is why there
            are only two segments in the final timeline in the above figure.
            Defaults to 0.

        Returns
        -------
        support : Timeline
            Timeline support
        r   )r   r   r   )r0   r   r   r   r    r^   M  s   #zTimeline.supportc                 C   s   t dd |  D S )zTimeline duration

        The timeline duration is the sum of the durations of the segments
        in the timeline support.

        Returns
        -------
        duration : float
            Duration of timeline support, in seconds.
        c                 s   s    | ]}|j V  qd S r'   )r   r   r   r   r    r*     s    z$Timeline.duration.<locals>.<genexpr>)sumr   r7   r   r   r    r   r  s   zTimeline.durationc                 c   s    |du r	|   }t|ttfstdt|j t|trL|j}| j|dd	 D ]}t||jd}|r8|V  |j
}q*t||j
d}|rJ|V  dS dS t|trd|	 D ]}| j|dD ]}|V  q]qUdS dS )zLike `gaps` but returns a segment generator instead

        See also
        --------
        :func:`pyannote.core.Timeline.gaps`

        Nz3unsupported operand type(s) for -':%s and Timeline.r]   rk   rU   rz   )r{   re   r   r   rf   type__name__rI   ro   r^   rJ   	gaps_iter)r0   r^   rJ   r#   gapr   r   r    r     s2   	


zTimeline.gaps_iterc                 C   s   t | j|d| jdS )a  Gaps

        A picture is worth a thousand words::

            timeline
            |------|    |------|     |----|
              |--|    |-----|     |----------|

            timeline.gaps()
                   |--|        |--|

        Parameters
        ----------
        support : None, Segment or Timeline
            Support in which gaps are looked for. Defaults to timeline extent

        Returns
        -------
        gaps : Timeline
            Timeline made of all gaps from original timeline, and delimited
            by provided support

        See also
        --------
        :func:`pyannote.core.Timeline.extent`

        rz   r   )r   r   r   )r0   r^   r   r   r    r|     s   zTimeline.gapsc                 C   s   |   }tg }| D ]\}}|| || q
t|}t| jd}t|dkr/t| jdS g }|d }|dd D ]}t||d}|rP||j	rP|
| |}q;t|| jdS )av  Segmentation

        Create the unique timeline with same support and same set of segment
        boundaries as original timeline, but with no overlapping segments.

        A picture is worth a thousand words::

            timeline
            |------|    |------|     |----|
              |--|    |-----|     |----------|

            timeline.segmentation()
            |-|--|-|  |-|---|--|  |--|----|--|

        Returns
        -------
        timeline : Timeline
            (unique) timeline with same support and same set of segment
            boundaries as original timeline, but with no overlapping segments.
        rt   r   r   NrU   r   )r^   r,   rH   sortedr   r   r6   r   rr   middlerl   )r0   r^   
timestampsrI   rJ   r   r   r#   r   r   r    segmentation  s"   

zTimeline.segmentationr   	generatormodalityr   c                 C   sj   ddl m} || j|d}|dkrddlm} | }n|dkr(ddlm} | }| D ]}t|||< q*|S )a  Turn timeline into an annotation

        Each segment is labeled by a unique label.

        Parameters
        ----------
        generator : 'string', 'int', or iterable, optional
            If 'string' (default) generate string labels. If 'int', generate
            integer labels. If iterable, use it to generate labels.
        modality : str, optional

        Returns
        -------
        annotation : Annotation
            Annotation
        r   r   )r   r   r   )string_generatorint)int_generator)
annotationr   r   utils.generatorsr   r   next)r0   r   r   r   r   r   r   r#   r   r   r    to_annotation  s   zTimeline.to_annotationc                 c   sf    | j r| j nd}t|trd|v rd| d}t|| D ]}| d|jdd|jddV  qdS )	zGenerate lines for a UEM file for this timeline

        Returns
        -------
        iterator: Iterator[str]
            An iterator over UEM text lines
        z<NA> zRSpace-separated UEM file format does not allow file URIs containing spaces (got: "z").z 1 z.3f
N)r   re   r   rd   rI   rJ   )r0   r   msgr#   r   r   r    	_iter_uem0  s   "zTimeline._iter_uemc                 C   s   d dd |  D S )zSerialize timeline as a string using UEM format

        Returns
        -------
        serialized: str
            UEM string
        r   c                 S   s   g | ]}|qS r   r   )r"   liner   r   r    r$   H  s    z#Timeline.to_uem.<locals>.<listcomp>)joinr   r7   r   r   r    to_uem@  s   zTimeline.to_uemfilec                 C   s   |   D ]}|| qdS )zDump timeline to file using UEM format

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

        Usage
        -----
        >>> with open('file.uem', 'w') as file:
        ...    timeline.write_uem(file)
        N)r   write)r0   r   r   r   r   r    	write_uemJ  s   zTimeline.write_uemc                 C   sB   ddl m}m} |st|j| jjd dS ddl m} || S )zjIPython notebook support

        See also
        --------
        :mod:`pyannote.core.notebook`
        r   )MATPLOTLIB_IS_AVAILABLEMATPLOTLIB_WARNING)klassN)repr_timeline)	notebookr   r   warningswarnformat	__class__r   r   )r0   r   r   r   r   r   r    
_repr_png_Y  s   zTimeline._repr_png_r'   )NN)r@   r   )r   r   r   r   )r]   F)r   r   )r]   )r   )r   N)Ar   
__module____qualname____doc__classmethodr   r   r!   r   r   r3   r8   r;   r:   r
   r=   r   r?   rC   rE   rF   rH   rL   rN   rQ   rO   rT   rS   r   r\   r   r   boolr   rg   r   ro   floatr   rr   rq   rx   r   r   r   r   r   r   r   r   r{   r   r^   r   r   r|   r   r   r   r   r   r   r   r   r   r   r   r   r    r   s   s    




$ 
	
!
 
<
=

.
'
$-%0

 <
#
r   )r   r   typingr   r   r   r   r   r   r   r	   r
   r   r   sortedcontainersr   r   r   r#   r   utils.typesr   r   r   r   r   pandaspdr   r   r   r   r    <module>   s   <4