
    3j                      U d Z ddlmZ ddlmZmZ ddlZddlmZ ddl	Z
ddlZddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ e
j2                  rddlmZ  ej6                  d      Z G d dej:                        Z G d dej:                        Z G d dej@                        Z! ed       G d d             Z" G d dej@                        Z# G d dejH                        Z% G d  d!e!      Z& G d" d#e!      Z' G d$ d%e!      Z( G d& d'e!      Z) G d( d)e!      Z* G d* d+e!      Z+ G d, d-ejX                        Z-e!gZ.d.e/d/<   e0d0k(  rddlZ ejb                  e-       yy)1a  
A spanner is a music21 object that represents a connection usually between
two or more music21 objects that might live in different streams but need
some sort of connection between them.  A slur is one type of spanner -- it might
connect notes in different Measure objects or even between different parts.

This package defines some of the most common spanners.  Other spanners
can be found in modules such as :ref:`moduleDynamics` (for things such as crescendos).
    )annotations)SequenceIterableN)	dataclass)base)common)opFrac)OffsetQL)defaults)environment)exceptions21)prebase)sites)stylestreamspannerc                      e Zd Zy)SpannerExceptionN__name__
__module____qualname__     </DATA/.local/lib/python3.12/site-packages/music21/spanner.pyr   r   -       r   r   c                      e Zd Zy)SpannerBundleExceptionNr   r   r   r   r   r   1   r   r   r   c                       e Zd ZdZdZ	 	 d fdZd Zddd fdZddZd d
Z	d!dZ
d Zd Zd Zd Zd Zd Z	 	 	 	 d"dZd#dZd$dZd Zd%dZ	 dddd	dd	 	 	 	 	 	 	 d&dZd Zd Zd Zd Z xZS )'Spannera  
    Spanner objects live on Streams in the same manner as other Music21Objects,
    but represent and store connections between one or more other Music21Objects.

    Commonly used Spanner subclasses include the :class:`~music21.spanner.Slur`,
    :class:`~music21.spanner.RepeatBracket`, :class:`~music21.spanner.Crescendo`,
    and :class:`~music21.spanner.Diminuendo`
    objects.

    In some cases you will want to subclass Spanner
    for specific purposes.

    In the first demo, we create
    a spanner to represent a written-out accelerando, such
    as Elliott Carter uses in his second string quartet (he marks them
    with an arrow).

    >>> class CarterAccelerandoSign(spanner.Spanner):
    ...    pass
    >>> n1 = note.Note('C4')
    >>> n2 = note.Note('D4')
    >>> n3 = note.Note('E4')
    >>> sp1 = CarterAccelerandoSign(n1, n2, n3)  # or as a list: [n1, n2, n3]
    >>> sp1.getSpannedElements()
    [<music21.note.Note C>, <music21.note.Note D>, <music21.note.Note E>]

    We can iterate over a spanner to get the contexts:

    >>> print(' '.join([repr(n) for n in sp1]))
    <music21.note.Note C> <music21.note.Note D> <music21.note.Note E>

    Now we put the notes and the spanner into a Stream object.  Note that
    the convention is to put the spanner at the beginning of the innermost
    Stream that contains all the Spanners:

    >>> s = stream.Stream()
    >>> s.append([n1, n2, n3])
    >>> s.insert(0, sp1)

    Now we can get at the spanner in one of three ways.

    (1) it is just a normal element in the stream:

    >>> for e in s:
    ...    print(e)
    <music21.note.Note C>
    <...CarterAccelerandoSign <music21.note.Note C><music21.note.Note D><music21.note.Note E>>
    <music21.note.Note D>
    <music21.note.Note E>

    (2) we can get a stream of spanners (equiv. to getElementsByClass(spanner.Spanner))
        by calling the .spanner property on the stream.

    >>> spannerCollection = s.spanners  # a stream object
    >>> for thisSpanner in spannerCollection:
    ...     print(thisSpanner)
    <...CarterAccelerandoSign <music21.note.Note C><music21.note.Note D><music21.note.Note E>>

    (3) we can get the spanner by looking at the list getSpannerSites() on
    any object that has a spanner:

    >>> n2.getSpannerSites()
    [<music21...CarterAccelerandoSign
            <music21.note.Note C><music21.note.Note D><music21.note.Note E>>]

    In this example we will slur a few notes and then iterate over the stream to
    see which are slurred:

    >>> n1 = note.Note('C4')
    >>> n2 = note.Note('D4')
    >>> n3 = note.Note('E4')
    >>> n4 = note.Note('F4')
    >>> n5 = note.Note('G4')
    >>> n6 = note.Note('A4')

    Create a slur over the second and third notes at instantiation:

    >>> slur1 = spanner.Slur([n2, n3])

    Slur the fifth and the sixth notes by adding them to an existing slur:

    >>> slur2 = spanner.Slur()
    >>> slur2.addSpannedElements([n5, n6])

    Now add them all to a stream:

    >>> part1 = stream.Part()
    >>> part1.append([n1, n2, n3, n4, n5, n6])
    >>> part1.insert(0, slur1)
    >>> part1.insert(0, slur2)

    Say we wanted to know which notes in a piece started a
    slur, here's how we could do it:

    >>> for n in part1.notes:
    ...    ss = n.getSpannerSites()
    ...    for thisSpanner in ss:
    ...       if 'Slur' in thisSpanner.classes:
    ...            if thisSpanner.isFirst(n):
    ...                print(n.nameWithOctave)
    D4
    G4

    Alternatively, you could iterate over the spanners
    of part1 and get their first elements:

    >>> for thisSpanner in part1.spanners:
    ...     firstNote = thisSpanner.getSpannedElements()[0]
    ...     print(firstNote.nameWithOctave)
    D4
    G4

    The second method is shorter, but the first is likely to
    be useful in cases where you are doing other things to
    each note object along the way.

    Oh, and of course, slurs do print properly in musicxml:

    >>> #_DOCS_SHOW part1.show()

    .. image:: images/slur1_example.*
        :width: 400

    (the Carter example would not print an arrow since that
    element has no corresponding musicxml representation).

    *Implementation notes:*

    The elements that are included in a spanner are stored in a
    Stream subclass called :class:`~music21.stream.SpannerStorage`
    found as the `.spannerStorage` attribute.  That Stream has an
    attribute called `client` which links to the original spanner.
    Thus, `spannerStorage` is smart enough to know where it's stored, but
    it makes deleting/garbage-collecting a spanner a tricky operation:

    Ex. Prove that the spannedElement Stream is linked to container via
    `client`:

    >>> sp1.spannerStorage.client is sp1
    True

    Spanners have a `.completeStatus` attribute which can be used to find out if
    all spanned elements have been added yet. It's up to the processing agent to
    set this, but it could be useful in deciding where to append a spanner.

    >>> sp1.completeStatus
    False

    When we're done adding elements:

    >>> sp1.completeStatus = True
    )spannerStoragec                V   t        |   di | ddlm}  |j                  |       | _        d| j
                  _        g }|D ]6  }t        |t        j                        r|j                  |       /|2||z  }8 | j                  |       d | _        d| _        g | _        d| _        y )Nr   r   clientFunknownr   )super__init__music21r   SpannerStorager"   autoSort
isinstancer   Music21ObjectappendaddSpannedElementsidLocalcompleteStatusfillElementTypesfilledStatus)selfspannedElementskeywordsr   procspannedElement	__class__s         r   r(   zSpanner.__init__   s     	$8$ 	# 4f334@
 (-$ *,-N.$*<*<=N++&	 .
 	% "& %* /1 8Ar   c                    g }| j                         D ]  }|}|j                  t        |               dj                  |      S )N )getSpannedElementsr.   reprjoin)r4   msgcobjRefs       r   _reprInternalzSpanner._reprInternal	  s?    ((*AFJJtF|$ + wws|r   NignoreAttributesc               Z   dh}||}n||z  }t        j                  t        t        |   ||            } t        | j                        |      |_        | j                  j                  D ]  }|j                  j                  |        |j                  j                  d       |S )z5
        see __deepcopy__ for tests and docs
        r"   rC   r$   F)updateIsFlat)
tcastr!   r'   _deepcopySubclassabletyper"   	_elements
coreAppendcoreElementsChanged)r4   memorD   defaultIgnoreSetnewr@   r9   s         r   rI   zSpanner._deepcopySubclassable  s    
 --#//2BBffWW24JZ2[]
 7T$"5"56cB$$..A))!, / 	..E.B
r   c                $    | j                  |      S )a  
        This produces a new, independent object containing references
        to the same spannedElements.
        SpannedElements linked in this Spanner must be manually re-set,
        likely using the
        replaceSpannedElement() method.

        Notice that we put the references to the same object so that
        later we can replace them;
        otherwise in a deepcopy of a stream, the notes in the stream
        will become independent of the notes in the spanner.

        >>> import copy
        >>> n1 = note.Note('g')
        >>> n2 = note.Note('f#')
        >>> c1 = clef.AltoClef()

        >>> sp1 = spanner.Spanner(n1, n2, c1)
        >>> sp2 = copy.deepcopy(sp1)
        >>> len(sp2.spannerStorage)
        3
        >>> sp1 is sp2
        False
        >>> sp2[0] is sp1[0]
        True
        >>> sp2[2] is sp1[2]
        True
        >>> sp1[0] is n1
        True
        >>> sp2[0] is n1
        True
        )rI   )r4   rN   s     r   __deepcopy__zSpanner.__deepcopy__&  s    B ))$//r   Tc                    | j                   r| j                   j                  |       t        j                  j                  | |       y N)r"   purgeOrphansr   r-   )r4   excludeStorageStreamss     r   rU   zSpanner.purgeOrphansN  s7    ,,-BC''.CDr   Fc                    | j                   r| j                   j                  |       t        j                  j                  | |       y )N)rescanIsDead)r"   purgeLocationsr   r-   )r4   rX   s     r   rY   zSpanner.purgeLocationsT  s=     ..L.I))$\)Jr   c                8    | j                   j                  |      S )a  

        >>> n1 = note.Note('g')
        >>> n2 = note.Note('f#')
        >>> c1 = clef.BassClef()
        >>> sl = spanner.Spanner(n1, n2, c1)
        >>> sl[0] == n1
        True
        >>> sl[-1] == c1
        True
        >>> sl[clef.BassClef][0] == c1
        True
        )r"   __getitem__r4   keys     r   r[   zSpanner.__getitem__^  s     ""..s33r   c                ,    t        | j                        S rT   )iterr"   r4   s    r   __iter__zSpanner.__iter__o  s    D''((r   c                @    t        | j                  j                        S rT   )lenr"   rK   r`   s    r   __len__zSpanner.__len__r  s     4&&0011r   c                @    t        | j                  j                        S )a  
        Return all the elements of `.spannerStorage` for this Spanner
        as a list of Music21Objects.

        >>> n1 = note.Note('g')
        >>> n2 = note.Note('f#')
        >>> sl = spanner.Spanner()
        >>> sl.addSpannedElements(n1)
        >>> sl.getSpannedElements() == [n1]
        True
        >>> sl.addSpannedElements(n2)
        >>> sl.getSpannedElements() == [n1, n2]
        True
        >>> sl.getSpannedElementIds() == [id(n1), id(n2)]
        True
        >>> c1 = clef.TrebleClef()
        >>> sl.addSpannedElements(c1)
        >>> sl.getSpannedElements() == [n1, n2, c1]  # make sure that not sorting
        True
        )listr"   rK   r`   s    r   r<   zSpanner.getSpannedElementsw  s    . D''1122r   c                N    | j                   j                  |      }t        |      S )aR  

        >>> n1 = note.Note('g')
        >>> n2 = note.Note('f#')
        >>> c1 = clef.AltoClef()
        >>> sl = spanner.Spanner()
        >>> sl.addSpannedElements([n1, n2, c1])
        >>> sl.getSpannedElementsByClass('Note') == [n1, n2]
        True
        >>> sl.getSpannedElementsByClass(clef.Clef) == [c1]
        True
        )r"   getElementsByClassrf   )r4   classFilterList
postStreams      r   getSpannedElementsByClassz!Spanner.getSpannedElementsByClass  s%     ((;;OL
Jr   c                f    | j                   j                  D cg c]  }t        |       c}S c c}w )z
        Return all id() for all stored objects.
        Was performance critical, until most uses removed in v7.

        Used only as a testing tool now.
        Spanner.__contains__() was optimized in 839c7e5.
        )r"   rK   id)r4   ns     r   getSpannedElementIdszSpanner.getSpannedElementIds  s.      $22<<=<!1<===s   .c                    t        j                  |      s|g}|r
|dd }||z  }|D ]2  }|| j                  |      s| j                  j	                  |       34 | j                  j                          y)aW  
        Associate one or more elements with this Spanner.

        The order in which elements are added is retained and
        may or may not be significant to the spanner.

        >>> n1 = note.Note('g')
        >>> n2 = note.Note('f#')
        >>> n3 = note.Note('e')
        >>> n4 = note.Note('d-')
        >>> n5 = note.Note('c')

        >>> sl = spanner.Spanner()
        >>> sl.addSpannedElements(n1)
        >>> sl.addSpannedElements(n2, n3)
        >>> sl.addSpannedElements([n4, n5])
        >>> sl.getSpannedElementIds() == [id(n) for n in [n1, n2, n3, n4, n5]]
        True
        N)r   
isListLikehasSpannedElementr"   rL   rM   )r4   r5   otherElementsr@   s       r   r/   zSpanner.addSpannedElements  s|    4   1./O-a0O},O Ay))!,##..q1 ! 	//1r   c                    t        |       }| j                  |       |dk(  ry| j                  j                  d   |u r-|f| j                  j                  dd z   | j                  _        yy)a	  
        Add a single element as the first in the spanner.

        >>> n1 = note.Note('g')
        >>> n2 = note.Note('f#')
        >>> n3 = note.Note('e')
        >>> n4 = note.Note('d-')
        >>> n5 = note.Note('c')

        >>> sl = spanner.Spanner()
        >>> sl.addSpannedElements(n2, n3)
        >>> sl.addSpannedElements([n4, n5])
        >>> sl.insertFirstSpannedElement(n1)
        >>> sl.getSpannedElementIds() == [id(n) for n in [n1, n2, n3, n4, n5]]
        True

        If the element is already in the spanner, it will not be added again, nor moved.
        (to move it to the front, remove it before running)

        >>> sl.insertFirstSpannedElement(n4)
        >>> sl.getSpannedElementIds() == [id(n) for n in [n1, n2, n3, n4, n5]]
        True
        r   N)rc   r/   r"   elements)r4   firstElorigNumElementss      r   insertFirstSpannedElementz!Spanner.insertFirstSpannedElement  sq    0  #4y(a ''+w6
T0099#2>> ( 7r   c                
    || v S )a  
        Return True if this Spanner has the spannedElement.

        >>> n1 = note.Note('g')
        >>> n2 = note.Note('f#')
        >>> span = spanner.Spanner()
        >>> span.addSpannedElements(n1)
        >>> span.hasSpannedElement(n1)
        True
        >>> span.hasSpannedElement(n2)
        False

        Note that a simple `in` does the same thing:

        >>> n1 in span
        True
        >>> n2 in span
        False
        r   r4   r8   s     r   rr   zSpanner.hasSpannedElement  s    ( %%r   c                F    | j                   j                  D ]  }||u s y y)NTF)r"   rK   )r4   r8   xs      r   __contains__zSpanner.__contains__  s*     $$..AN" / r   c                    |yt        j                  |      r=| j                  j                  |      }|| j                  j	                  ||d       yy| j                  j	                  ||d       y)a  
        When copying a Spanner, we need to update the
        spanner with new references for copied  (if the Notes of a
        Slur have been copied, that Slur's Note references need
        references to the new Notes). Given the old spanned element,
        this method will replace the old with the new.

        The `old` parameter can be either an object or object id.

        >>> n1 = note.Note('g')
        >>> n2 = note.Note('f#')
        >>> c1 = clef.AltoClef()
        >>> c2 = clef.BassClef()
        >>> sl = spanner.Spanner(n1, n2, c1)
        >>> sl.replaceSpannedElement(c1, c2)
        >>> sl[-1] == c2
        True
        NF)
allDerived)r   isNumr"   coreGetElementByMemoryLocationreplace)r4   oldrP   es       r   replaceSpannedElementzSpanner.replaceSpannedElement!  st    & ;<<##BB3GA } ##++Asu+E  ''SU'Cr   includeEndBoundarymustFinishInSpanmustBeginInSpanincludeElementsThatEndAtStartc               D   | j                   sy| j                  du ry| j                         }|y||j                  }|t	        d      t
        j                  rt        |t        j                        sJ | j                         }||u rd}d}d}	|3|j                  }|j                  }	| j                  j                  |       	 |j                  |      }
|)	 t%        |j                  |      |j&                  z         }nt%        |
|j&                  z         }|j)                         j+                  |
|||||      j-                  | j                         }|D ]  }||u r||u r| j#                  |        |#| j#                  |       |||_        |	|	|_        d| _        y# t        j                   $ r( |#| j#                  |       |||_        |	|	|_        Y yw xY w# t        j                   $ r& | j#                  |       |||_        |	|	|_        Y yw xY w)a  
        Fills in the intermediate elements of a spanner, that are found in searchStream between
        the first element's offset and the last element's offset+duration.  If searchStream
        is None, the first element's activeSite is used.  If the first element's activeSite
        is None, a SpannerException is raised.

        Ottava is an example of a Spanner that can be filled. The Ottava does not need
        to be inserted into the stream in order to be filled.

        >>> m = stream.Measure([note.Note('A'), note.Note('B'), note.Note('C')])
        >>> ott1 = spanner.Ottava(m.notes[0], m.notes[2])
        >>> ott1.fill(m)
        >>> ott1
        <music21.spanner.Ottava 8va transposing<...Note A><...Note B><...Note C>>

        If the searchStream is not passed in, fill still happens in this case, because
        the first note's activeSite is used instead.

        >>> ott2 = spanner.Ottava(m.notes[0], m.notes[2])
        >>> ott2.fill()
        >>> ott2
        <music21.spanner.Ottava 8va transposing<...Note A><...Note B><...Note C>>

        If the searchStream is not passed, and the spanner's first element doesn't have
        an activeSite, a SpannerException is raised.

        >>> ott3 = spanner.Ottava(note.Note('D'), note.Note('E'))
        >>> ott3.fill()
        Traceback (most recent call last):
        music21.spanner.SpannerException: Spanner.fill() requires a searchStream
            or getFirst().activeSite
        NTz?Spanner.fill() requires a searchStream or getFirst().activeSiter   )r2   r3   getFirst
activeSiter   rG   TYPE_CHECKINGr,   r   StreamgetLastoffsetr"   removegetOffsetInHierarchyr   SitesExceptionr/   r	   quarterLengthrecursegetElementsByOffsetInHierarchyrh   )r4   searchStreamr   r   r   r   startElement
endElementsavedEndElementOffsetsavedEndElementActiveSitestartOffsetInHierarchyendOffsetInHierarchymatchIteratorfoundElements                 r   fillzSpanner.fillN  st   T $$$04'22L#&U  ??lFMM:::.2lln
%J15:>!! %/$5$5!(2(=(=%&&z2
	/;/P/PQ]/^" !
'-j.M.Ml.[0:0H0H/I (J$ $**@<C]C]*]#^ %WY++&$#5!1 /.K , M   5 56 	 *L|+z)##L1 * !##J/$0$9
!(4(A
% o ## 	%''
3(4(=J%,8,EJ)	 '' ''
3(4(=J%,8,EJ)s$   F( 'G& (8G#"G#&6HHc                &    | j                         |u S )a  
        Given a spannedElement, is it first?

        >>> n1 = note.Note('g')
        >>> n2 = note.Note('f#')
        >>> n3 = note.Note('e')
        >>> n4 = note.Note('c')
        >>> n5 = note.Note('d-')

        >>> sl = spanner.Spanner()
        >>> sl.addSpannedElements(n1, n2, n3, n4, n5)
        >>> sl.isFirst(n2)
        False
        >>> sl.isFirst(n1)
        True
        >>> sl.isLast(n1)
        False
        >>> sl.isLast(n5)
        True
        )r   r{   s     r   isFirstzSpanner.isFirst  s    * }}.00r   c                `    	 | j                   d   S # t        t        j                  f$ r Y yw xY w)a  
        Get the object of the first spannedElement (or None if it's an empty spanner)

        >>> n1 = note.Note('g')
        >>> n2 = note.Note('f#')
        >>> n3 = note.Note('e')
        >>> n4 = note.Note('c')
        >>> n5 = note.Note('d-')

        >>> sl = spanner.Spanner()
        >>> sl.addSpannedElements(n1, n2, n3, n4, n5)
        >>> sl.getFirst() is n1
        True

        >>> spanner.Slur().getFirst() is None
        True
        r   Nr"   
IndexErrorr   StreamExceptionr`   s    r   r   zSpanner.getFirst  s5    $	&&q))L889 		    --c                &    | j                         |u S )zL
        Given a spannedElement, is it last?  Returns True or False
        )r   r{   s     r   isLastzSpanner.isLast  s     ||~//r   c                `    	 | j                   d   S # t        t        j                  f$ r Y yw xY w)a  
        Get the object of the last spannedElement (or None if it's an empty spanner)

        >>> n1 = note.Note('g')
        >>> n2 = note.Note('f#')
        >>> n3 = note.Note('e')
        >>> n4 = note.Note('c')
        >>> n5 = note.Note('d-')

        >>> sl = spanner.Spanner()
        >>> sl.addSpannedElements(n1, n2, n3, n4, n5)
        >>> sl.getLast() is n5
        True

        >>> spanner.Slur().getLast() is None
        True
        ru   Nr   r`   s    r   r   zSpanner.getLast  s5    $	&&r**L889 		r   )r5   z1base.Music21Object | Sequence[base.Music21Object]rT   )TF)r5   z1Sequence[base.Music21Object] | base.Music21Objectrs   base.Music21Object)rw   r   returnNone)r8   r   r   bool)r   r   )r   r   r   r   r   r   r   r   )r   r   r   __doc__equalityAttributesr(   rB   rI   rR   rU   rY   r[   ra   rd   r<   rk   ro   r/   ry   rr   r~   r   r   r   r   r   r   __classcell__r9   s   @r   r!   r!   6   s    Wr -2A#R2Ah4 ,!0PEK4")2
32 $>/2H/2 +/2b$L&,$D^ N! $)!& $.3N! !	N!
 N! N! (,N!`1..0r   r!   T)frozenc                  4    e Zd ZU dZded<   ded<   dZded<   y)	PendingAssignmentRefz
    A dataclass containing information about a pending first spanned element assignment.
    See :meth:`SpannerBundle.setPendingSpannedElementAssignment` for documentation
    and tests.
    r!   r   str	classNameNOffsetQL | NoneoffsetInScore)r   r   r   r   __annotations__r   r   r   r   r   r   +  s    
 N#'M='r   r   c                  *     e Zd ZdZ fdZddZ xZS )SpannerAnchoraq  
    A simple Music21Object that can be used to define the beginning or end
    of a Spanner, in the place of a GeneralNote.

    This is useful for (e.g.) a Crescendo that ends partway through a
    note (e.g. in a violin part).  Exporters (like MusicXML) are configured
    to remove the SpannerAnchor itself on output, exporting only the Spanner
    start and stop locations.

    Here's an example of a whole note that has a Crescendo for the first
    half of the note, and a Diminuendo for the second half of the note.

    >>> n = note.Note('C4', quarterLength=4)
    >>> measure = stream.Measure([n], number=1)
    >>> part = stream.Part([measure], id='violin')
    >>> score = stream.Score([part])

    Add a crescendo from the note's start to the first anchor, place in the
    middle of the note, and then a diminuendo from that first anchor to the
    second, placed at the end of the note.

    >>> anchor1 = spanner.SpannerAnchor()
    >>> anchor2 = spanner.SpannerAnchor()
    >>> measure.insert(2.0, anchor1)
    >>> measure.insert(4.0, anchor2)
    >>> cresc = dynamics.Crescendo(n, anchor1)
    >>> dim = dynamics.Diminuendo(anchor1, anchor2)
    >>> score.append((cresc, dim))
    >>> score.show('text')
    {0.0} <music21.stream.Part violin>
        {0.0} <music21.stream.Measure 1 offset=0.0>
            {0.0} <music21.note.Note C>
            {2.0} <music21.spanner.SpannerAnchor at 2.0>
            {4.0} <music21.spanner.SpannerAnchor at 4.0>
    {4.0} <music21.dynamics.Crescendo <music21.note.Note C><...SpannerAnchor at 2.0>>
    {4.0} <music21.dynamics.Diminuendo <...SpannerAnchor at 2.0><...SpannerAnchor at 4.0>>
    c                $    t        |   di | y )Nr   )r'   r(   )r4   r6   r9   s     r   r(   zSpannerAnchor.__init__\  s    $8$r   c                &   | j                   }| j                  O| j                  j                  d      }|s| j                  j                  d      }|sy| j	                  |d         }| j
                  j                  }|dk(  rd| S d| d||z    S )NMeasureVoice
unanchoredr   zat -)r   r   r   getSitesByClassr   durationr   )r4   r   siteListqls       r   rB   zSpannerAnchor._reprInternal_  s    ;;??"!ZZ77	BH::55g>#..x{;F}}227>!VHAfrk]++r   r   r   )r   r   r   r   r(   rB   r   r   s   @r   r   r   6  s    $J%,r   r   c                      e Zd ZdZdddZddZd Zd ZddZddZ	d	 Z
dd
ZdddZddZddZ	 	 	 	 	 	 ddZd dZd!dZd Zd Z	 d	 	 	 	 	 	 	 d"dZ	 d	 d#dZd$dZy)%SpannerBundleal  
    An advanced utility object for collecting and processing
    collections of Spanner objects. This is necessary because
    often processing routines that happen at many
    levels still need access to the same collection of spanners.

    Because SpannerBundles are so commonly used with
    :class:`~music21.stream.Stream` objects, the Stream has a
    :attr:`~music21.stream.Stream.spannerBundle` property that stores
    and caches a SpannerBundle of the Stream.

    If a Stream or Stream subclass is provided as an argument,
    all Spanners on this Stream will be accumulated herein.

    Not to be confused with SpannerStorage (which is a Stream class inside
    a spanner that stores Elements that are spanned)

    * Changed in v7: only argument must be a List of spanners.
      Creators of SpannerBundles are required to check that this constraint is True
    Nc                F    i | _         g | _        |r
|d d  | _        g | _        y rT   )_cache_storage _pendingSpannedElementAssignment)r4   spannerss     r   r(   zSpannerBundle.__init__  s*    (*')$QKDM MO-r   c                n    | j                   j                  |       | j                  j                          y)zu
        adds a Spanner to the bundle. Will be done automatically when adding a Spanner
        to a Stream.
        N)r   r.   r   clear)r4   others     r   r.   zSpannerBundle.append  s&    
 	U#r   c                ,    t        | j                        S rT   )rc   r   r`   s    r   rd   zSpannerBundle.__len__  s    4==!!r   c                6    | j                   j                         S rT   )r   ra   r`   s    r   ra   zSpannerBundle.__iter__  s    }}%%''r   c                     | j                   |   S rT   )r   r\   s     r   r[   zSpannerBundle.__getitem__  s    }}S!!r   c                    || j                   v r| j                   j                  |       nt        d|       | j                  j	                          y)a  
        Remove a stored Spanner from the bundle with an instance.
        Each reference must have a matching id() value.

        >>> su1 = spanner.Slur()
        >>> su1.idLocal = 1
        >>> su2 = spanner.Slur()
        >>> su2.idLocal = 2
        >>> sb = spanner.SpannerBundle()
        >>> sb.append(su1)
        >>> sb.append(su2)
        >>> len(sb)
        2
        >>> sb
        <music21.spanner.SpannerBundle of size 2>

        >>> sb.remove(su2)
        >>> len(sb)
        1
        z!cannot match object for removal: N)r   r   r   r   r   )r4   items     r   r   zSpannerBundle.remove  sE    * 4== MM  &(+LTF)STTr   c                    dt        |        S )Nzof size )rc   r`   s    r   rB   zSpannerBundle._reprInternal  s    #d)%%r   c                t    g }| j                   D ]&  }|j                  t        |j                               ( |S )zK
        Return all SpannerStorage ids from all contained Spanners
        )r   r.   rm   r"   )r4   postr}   s      r   getSpannerStorageIdsz"SpannerBundle.getSpannerStorageIds  s3     AKK1++,- r   c                   d| }|| j                   vs| j                   |   Rg }| j                  D ]#  }|j                  |k(  s|j                  |       % | j	                  |      | j                   |<   | j                   |   S )aq  
        Get spanners by `idLocal`.

        Returns a new SpannerBundle object

        >>> su = spanner.Slur()
        >>> su.idLocal = 1
        >>> rb = spanner.RepeatBracket()
        >>> rb.idLocal = 2
        >>> sb = spanner.SpannerBundle()
        >>> sb.append(su)
        >>> sb.append(rb)
        >>> len(sb)
        2

        >>> sb.getByIdLocal(2)
        <music21.spanner.SpannerBundle of size 1>
        >>> sb.getByIdLocal(2)[0]
        <music21.spanner.RepeatBracket >

        >>> len(sb.getByIdLocal(1))
        1

        >>> sb.getByIdLocal(3)
        <music21.spanner.SpannerBundle of size 0>
        zidLocal-)r   r   r0   r.   r9   )r4   r0   cacheKeyoutsps        r   getByIdLocalzSpannerBundle.getByIdLocal  s|    6 gY'4;;&$++h*?*G!#Cmm::(JJrN $ %)NN3$7DKK!{{8$$r   c                    g }| j                   D ]#  }|j                  |k(  s|j                  |       % | j                  |      S )a  
        Get spanners by matching status of `completeStatus` to the same attribute

        >>> su1 = spanner.Slur()
        >>> su1.idLocal = 1
        >>> su1.completeStatus = True
        >>> su2 = spanner.Slur()
        >>> su2.idLocal = 2
        >>> sb = spanner.SpannerBundle()
        >>> sb.append(su1)
        >>> sb.append(su2)
        >>> sb2 = sb.getByCompleteStatus(True)
        >>> len(sb2)
        1
        >>> sb2 = sb.getByIdLocal(1).getByCompleteStatus(True)
        >>> sb2[0] == su1
        True
        )r   r1   r.   r9   )r4   r1   r   r   s       r   getByCompleteStatusz!SpannerBundle.getByCompleteStatus  sA    ( !--B  N2B   ~~d##r   c                   t        |      }d| }|| j                  vs| j                  |   Gg }| j                  D ]  }||v s|j                  |        | j	                  |      | j                  |<   | j                  |   S )a}  
        Given a spanner spannedElement (an object),
        return a new SpannerBundle of all Spanner objects that
        have this object as a spannedElement.

        >>> n1 = note.Note()
        >>> n2 = note.Note()
        >>> n3 = note.Note()
        >>> su1 = spanner.Slur(n1, n2)
        >>> su2 = spanner.Slur(n2, n3)
        >>> sb = spanner.SpannerBundle()
        >>> sb.append(su1)
        >>> sb.append(su2)
        >>> list(sb.getBySpannedElement(n1)) == [su1]
        True
        >>> list(sb.getBySpannedElement(n2)) == [su1, su2]
        True
        >>> list(sb.getBySpannedElement(n3)) == [su2]
        True
        zgetBySpannedElement-)rm   r   r   r.   r9   )r4   r8   idTargetr   r   r   s         r   getBySpannedElementz!SpannerBundle.getBySpannedElement
  s    < n%)(44;;&$++h*?*G!#Cmm "R'JJrN	 $
 %)NN3$7DKK!{{8$$r   c                (   t        |t              rt        d      g }| j                  j	                          | j
                  D ]1  }i |_        ||v s|j                  ||       |j                  |       3 | j                  j	                          |S )aY  
        Given a spanner spannedElement (an object), replace all old spannedElements
        with new spannedElements
        for all Spanner objects contained in this bundle.

        The `old` parameter must be an object, not an object id.

        If no replacements are found, no errors are raised.

        Returns a list of spanners that had elements replaced.

        >>> n1 = note.Note('C')
        >>> n2 = note.Note('D')
        >>> su1 = spanner.Line(n1, n2)
        >>> su2 = spanner.Glissando(n2, n1)
        >>> sb = spanner.SpannerBundle()
        >>> sb.append(su1)
        >>> sb.append(su2)

        >>> su1
        <music21.spanner.Line <music21.note.Note C><music21.note.Note D>>
        >>> su2
        <music21.spanner.Glissando <music21.note.Note D><music21.note.Note C>>

        >>> n3 = note.Note('E')
        >>> replacedSpanners = sb.replaceSpannedElement(n2, n3)
        >>> replacedSpanners == [su1, su2]
        True

        >>> su1
        <music21.spanner.Line <music21.note.Note C><music21.note.Note E>>
        >>> su2
        <music21.spanner.Glissando <music21.note.Note E><music21.note.Note C>>

        * Changed in v7: id() is no longer allowed for `old`.

        >>> sb.replaceSpannedElement(id(n1), n2)
        Traceback (most recent call last):
        TypeError: send elements to replaceSpannedElement(), not ids.
        z2send elements to replaceSpannedElement(), not ids.)r,   int	TypeErrorr   r   r   r   r.   )r4   r   rP   replacedSpannersr   s        r   r   z#SpannerBundle.replaceSpannedElement4  s    \ c3PQQ*,--BBI by((c2 ''+   	r   c                   d| }t        |t              r|nd}t        |t              rdn|}|| j                  vs| j                  |   qg }| j                  D ]B  }|r ||j                  v r|j                  |       %t        ||      s2|j                  |       D | j                  |      | j                  |<   | j                  |   S )a  
        Given a spanner class, return a new SpannerBundle of all Spanners of the desired class.

        >>> su1 = spanner.Slur()
        >>> su2 = layout.StaffGroup()
        >>> su3 = layout.StaffGroup()
        >>> sb = spanner.SpannerBundle()
        >>> sb.append(su1)
        >>> sb.append(su2)
        >>> sb.append(su3)

        `searchClass` should be a Class.

        >>> slurs = sb.getByClass(spanner.Slur)
        >>> slurs
        <music21.spanner.SpannerBundle of size 1>
        >>> list(slurs) == [su1]
        True
        >>> list(sb.getByClass(spanner.Slur)) == [su1]
        True
        >>> list(sb.getByClass(layout.StaffGroup)) == [su2, su3]
        True

        A tuple of classes can also be given:

        >>> len(sb.getByClass((spanner.Slur, layout.StaffGroup)))
        3

        Note that the ability to search via a string will be removed in
        version 10.
        zgetByClass-r;   r   )r,   r   r   r   classesr.   r9   )r4   searchClassr   	searchStrsearchClassesr   r   s          r   
getByClasszSpannerBundle.getByClassy  s    D !.#-k3#?KR	(c:4;;&$++h*?*G!#Cmmbjj!8JJrN!"m4 

2 $ %)NN3$7DKK!{{8$$r   c                b    t        | j                  |            D ]  \  }}||z  dz   |_         y)a  
        (See :meth:`setIdLocals` for an explanation of what an idLocal is.)

        Automatically set idLocal values for all members of the provided class.
        This is necessary in cases where spanners are newly created in
        potentially overlapping boundaries and need to be tagged for MusicXML
        or other output. Note that, if some Spanners already have idLocals,
        they will be overwritten.

        The `maxId` parameter sets the largest number that is available for this
        class.  In MusicXML it is 6.

        Currently, this method just iterates over the spanners of this class
        and counts the number from 1-6 and then recycles numbers.  It does
        not check whether more than 6 overlapping spanners of the same type
        exist, nor does it reset the count to 1 after all spanners of that
        class have been closed.  The example below demonstrates that the
        position of the contents of the spanner have no bearing on
        its idLocal (since we don't even put anything into the spanners).

        >>> su1 = spanner.Slur()
        >>> su2 = layout.StaffGroup()
        >>> su3 = spanner.Slur()
        >>> sb = spanner.SpannerBundle()
        >>> sb.append(su1)
        >>> sb.append(su2)
        >>> sb.append(su3)
        >>> [sp.idLocal for sp in sb.getByClass(spanner.Slur)]
        [None, None]
        >>> sb.setIdLocalByClass('Slur')
        >>> [sp.idLocal for sp in sb.getByClass(spanner.Slur)]
        [1, 2]
           N)	enumerater   r0   )r4   r   maxIdir   s        r   setIdLocalByClasszSpannerBundle.setIdLocalByClass  s0    H ty9:EAre)qBJ ;r   c                    d}t               }| j                  D ]*  }|j                  D ]  }||vs|j                  |        * , |D ]  }| j	                  |        y)a  
        Utility method for outputting MusicXML (and potentially
        other formats) for spanners.

        Each Spanner type (slur, line, glissando, etc.) in MusicXML
        has a number assigned to it.
        We call this number, `idLocal`.  idLocal is a number from 1 to 6.
        This does not mean that your piece can only have six slurs total!
        But it does mean that within a single
        part, only up to 6 slurs can happen simultaneously.
        But as soon as a slur stops, its idLocal can be reused.

        This method sets all idLocals for all classes in this SpannerBundle.
        This will assure that each class has a unique idLocal number.

        Calling this method is destructive: existing idLocal values will be lost.

        >>> su1 = spanner.Slur()
        >>> su2 = layout.StaffGroup()
        >>> su3 = spanner.Slur()
        >>> sb = spanner.SpannerBundle()
        >>> sb.append(su1)
        >>> sb.append(su2)
        >>> sb.append(su3)
        >>> [sp.idLocal for sp in sb.getByClass('Slur')]
        [None, None]
        >>> sb.setIdLocals()
        >>> [(sp, sp.idLocal) for sp in sb]
        [(<music21.spanner.Slur>, 1),
         (<music21.layout.StaffGroup>, 1),
         (<music21.spanner.Slur>, 2)]

        :class:`~music21.dynamics.DynamicWedge` objects are commingled. That is,
        :class:`~music21.dynamics.Crescendo` and
        :class:`~music21.dynamics.Diminuendo`
        are not numbered separately:

        >>> sb2 = spanner.SpannerBundle()
        >>> c = dynamics.Crescendo()
        >>> d = dynamics.Diminuendo()
        >>> sb2.append(c)
        >>> sb2.append(d)
        >>> sb2.setIdLocals()
        >>> [(sp, sp.idLocal) for sp in sb2]
        [(<music21.dynamics.Crescendo>, 1),
         (<music21.dynamics.Diminuendo>, 2)]
        )	Crescendo
DiminuendoN)setr   r   addr   )r4   skip_classesr   r   klassr   s         r   setIdLocalszSpannerBundle.setIdLocals  s^    f 3%--B,KK& $  
 !I""9- !r   c                `    | j                  |      j                  |      j                  |      S )a  
        Get all spanners of a specified class `className`, an id `idLocal`, and a `completeStatus`.
        This is a convenience routine for multiple filtering when searching for relevant Spanners
        to pair with.

        >>> su1 = spanner.Slur()
        >>> su2 = layout.StaffGroup()
        >>> su2.idLocal = 3
        >>> sb = spanner.SpannerBundle()
        >>> sb.append(su1)
        >>> sb.append(su2)
        >>> list(sb.getByClassIdLocalComplete(layout.StaffGroup, 3, False)) == [su2]
        True
        >>> su2.completeStatus = True
        >>> list(sb.getByClassIdLocalComplete(layout.StaffGroup, 3, False)) == []
        True
        )r   r   r   )r4   r   r0   r1   s       r   getByClassIdLocalCompletez'SpannerBundle.getByClassIdLocalComplete  s.    ( y)66((8	9r   c                X    t        |||      }| j                  j                  |       |S )u<  
        A SpannerBundle can be set up so that a particular spanner (sp) is looking
        for an element of class (className) to be set as first element. Any future
        element that matches the className (and offsetInScore, if specified)
        which is passed to the SpannerBundle via freePendingSpannedElementAssignment()
        will get it.

        Call `popPendingSpannedElementAssignments` after parsing to
        recover pending spanners that never matched their expected elements
        — e.g., a MusicXML `<direction>` whose
        `<offset>` lands between notes, needing a `SpannerAnchor` instead.

        First, let's see the usage without an explicit offset:

        Create some notes and a rest.

        >>> n1 = note.Note('C')
        >>> r1 = note.Rest()
        >>> n2 = note.Note('D')

        Notes start without any associated spanners.

        >>> n1.getSpannerSites()
        []

        Create an empty Slur and a SpannerBundle to hold it.

        >>> su1 = spanner.Slur()
        >>> sb1 = spanner.SpannerBundle()
        >>> sb1.append(su1)
        >>> su1.getSpannedElements()
        []

        Now call this method to register `su1` as awaiting the next note element.
        The method returns a `PendingAssignmentRef` (frozen dataclass) with information
        about what is registered as pending assignment.

        >>> sb1.setPendingSpannedElementAssignment(su1, 'Note')
        PendingAssignmentRef(spanner=<music21.spanner.Slur>,
                             className='Note', offsetInScore=None)

        Elements are then potentially added to spanners by calling
        `freePendingSpannedElementAssignment` on the SpannerBundle.

        That method will not attach a rest like `r1` because it is not a `'Note'`:

        >>> sb1.freePendingSpannedElementAssignment(r1)
        >>> r1 in su1
        False

        But the next Note will be attached:

        >>> sb1.freePendingSpannedElementAssignment(n1)
        >>> su1
        <music21.spanner.Slur <music21.note.Note C>>
        >>> n1 in su1
        True
        >>> n1.getSpannerSites()
        [<music21.spanner.Slur <music21.note.Note C>>]

        Once the pending assignment has been satisfied, the registration is cleared
        from the SpannerBundle, so no future notes that would have satisfied the assignment
        get assigned:

        >>> sb1.freePendingSpannedElementAssignment(n2)
        >>> n2 in su1
        False
        >>> n2.getSpannerSites()
        []

        And we can see that the SpannerBundle `sb1` has no spanners still awaiting (pending)
        elements to assign:

        >>> sb1.popPendingSpannedElementAssignments()
        []

        Now a similar example using `offsetInScore`.  When `offsetInScore` is
        specified at registration, only candidates passed with a matching
        offset to `freePendingSpannedElementAssignment` will be attached.

        Create two notes and a rest.

        >>> n3 = note.Note('C#')
        >>> wrongOffsetNote = note.Note('B')
        >>> r2 = note.Rest()

        Create a slur with `n3` already in it.

        >>> sb2 = spanner.SpannerBundle()
        >>> su2 = spanner.Slur([n3])
        >>> sb2.append(su2)
        >>> su2.getSpannedElements()
        [<music21.note.Note C#>]

        Register `su2` as pending and looking for the next Note at offset 4.0:

        >>> ref = sb2.setPendingSpannedElementAssignment(su2, 'Note', 4.0)
        >>> ref
        PendingAssignmentRef(spanner=<music21.spanner.Slur <music21.note.Note C#>>,
                             className='Note', offsetInScore=4.0)

        Call `freePendingSpannedElementAssignment` to attach an element of the right class
        and offset.  Note that the offset must be passed to the method; it is not
        necessarily the offset of the object itself (most often it is the `offsetInHierarchy`
        of the Part object).

        A note offered at the wrong offset is not attached:

        >>> sb2.freePendingSpannedElementAssignment(wrongOffsetNote, 5.0)
        >>> wrongOffsetNote in su2
        False

        (Passing an offset here is important since, when parsing MusicXML,
        if a `<direction>` has `<offset>` specified, the next note might not be the one
        at the start of the spanner)

        The freePending method will not get a rest even at the correct offsetInScore
        because it is not the class being searched for.

        >>> sb2.freePendingSpannedElementAssignment(r2, 4.0)
        >>> r2 in su2
        False

        We are all out of possible notes, we can see which PendingAssignmentRef elements
        are still awaiting elements to attach to. In this case, there is one, our
        Slur:

        >>> unmatched_pendingAssignmentRefs = sb2.popPendingSpannedElementAssignments()
        >>> len(unmatched_pendingAssignmentRefs)
        1
        >>> unmatched_pendingAssignmentRefs[0]
        PendingAssignmentRef(spanner=<music21.spanner.Slur <music21.note.Note C#>>,
                             className='Note', offsetInScore=4.0)
        >>> unmatched_pendingAssignmentRefs[0].spanner is su2
        True

        Parsers can use the information from the unmatched PendingAssignmentRef to
        add additional elements to the score at places where a match was expected.
        Given this ref, the most logical choice would be to create a `SpannerAnchor`
        object and put it at score offset 4.0 and insert it as the spanner's first element
        with `insertFirstSpannedElement`.

        (If a parser needs more information about where the Spanner and SpannerAnchor
        should go, such as a staff number, etc. it can keep a dictionary mapping
        `id(PendingAssignmentRef)` to a staffKey, etc.)

        And now the happy path: a pending assignment that finds a matching note
        with the right offset. (We'll demonstrate also that you need to pass
        in your own fractions.)

        >>> frac = common.numberTools.opFrac
        >>> n4 = note.Note('G')
        >>> n5 = note.Note('A')
        >>> su3 = spanner.Slur([n4])
        >>> sb3 = spanner.SpannerBundle()
        >>> sb3.append(su3)
        >>> _ = sb3.setPendingSpannedElementAssignment(su3, 'Note', frac(77.33333))
        >>> sb3.freePendingSpannedElementAssignment(n5, frac(77.33333))
        >>> su3
        <music21.spanner.Slur <music21.note.Note A><music21.note.Note G>>
        >>> n5 in su3
        True

        An important detail demonstrated above is that a freed element is always inserted as the
        first element of the spanner, even when the spanner already has
        other elements. (Note A is before note G in the slur).
        The insert-at-front behavior is important for MusicXML parsing, since
        a `<direction>` specified is often encountered before
        the note that should *start* the spanner (because of voices, other classes, etc.),
        so when the starting note arrives it needs to go to the start.
        )r   r   r   )r   r   r.   )r4   r   r   r   refs        r   "setPendingSpannedElementAssignmentz0SpannerBundle.setPendingSpannedElementAssignment(  s3    b #'

 	--44S9
r   c                *   | j                   syd}t        | j                         D ]N  \  }}|j                  |j                  v s|||j                  k(  s1|j
                  j                  |       |} n || j                   j                  |       yy)a7  
        Assigns and frees up a pendingSpannedElementAssignment if one
        is active and the candidate matches the class (and offsetInScore,
        if specified).  See setPendingSpannedElementAssignment for
        documentation and tests.

        It is set up via a first-in, first-out priority.
        N)r   r   r   classSetr   r   ry   pop)r4   spannedElementCandidater   r   r   r  s         r   #freePendingSpannedElementAssignmentz1SpannerBundle.freePendingSpannedElementAssignment  s     44 E EFFAs}} 7 @ @@!)(C,=,==KK99:QRF G 1155f= r   c                ,    | j                   }g | _         |S )a  
        Removes and returns all pendingSpannedElementAssignments.
        This can be called when there will be no more calls to
        freePendingSpannedElementAssignment, and SpannerAnchors
        need to be created for each remaining pending assignment.
        The SpannerAnchors should be created at the appropriate
        offset, dictated by the assignment's offsetInScore.

        >>> sb = spanner.SpannerBundle()
        >>> sl = spanner.Slur()
        >>> sb.append(sl)
        >>> sb.setPendingSpannedElementAssignment(sl, 'Note', 0.0)
        PendingAssignmentRef(spanner=<music21.spanner.Slur>,
                             className='Note', offsetInScore=0.0)

        `popPendingSpannedElementAssignments` returns the full list and leaves
        an empty list behind:

        >>> expectedPending = list(sb._pendingSpannedElementAssignment)
        >>> pending = sb.popPendingSpannedElementAssignments()
        >>> pending == expectedPending
        True
        >>> sb._pendingSpannedElementAssignment
        []
        )r   )r4   outputs     r   #popPendingSpannedElementAssignmentsz1SpannerBundle.popPendingSpannedElementAssignments  s    4 .2-R-R02-r   rT   )r   zlist[Spanner] | None)r   r!   )r   r!   )r   r!   )r   z	list[int])r0   z
int | Noner   r   )r1   r   r   r   )r8   r!   r   r   )r   r   rP   r   r   zlist[Spanner])r   zstr | type | tuple[type, ...]r   z'SpannerBundle')   )r   r!   r   r   r   r   r   r   )r   r   )r   zlist[PendingAssignmentRef])r   r   r   r   r(   r.   rd   ra   r[   r   rB   r   r   r   r   r   r   r   r   r  r  r	  r  r   r   r   r   r   q  s    *O"("6&"%H$4(%TC C   C  
	C J1%f&)P;.z96 (,	ww w %	w
 
wx (,> %>6r   r   c                  "     e Zd ZdZ fdZ xZS )Slurz
    A slur represented as a spanner between two Notes.

    Slurs have `.placement` options ('above' or 'below') and `.lineType` ('dashed' or None)
    c                @    t        |   |i | d | _        d | _        y rT   )r'   r(   	placementlineTyper4   r5   r6   r9   s      r   r(   zSlur.__init__#  s#    /6X6r   )r   r   r   r   r(   r   r   s   @r   r  r    s     r   r  c                       e Zd ZU dZej
                  ZdddZded<    fdZ	d Z
ed	        Zej                  d
        Z xZS )MultiMeasureRestzb
    A grouping symbol that indicates that a collection of rests lasts
    multiple measures.
    a>  
            Boolean to indicate whether rest symbols
            (breve, longa, etc.) should be used when
            displaying the rest. Your music21 inventor
            is a medievalist, so this defaults to True.

            Change defaults.multiMeasureRestUseSymbols to
            change globally.
            a"  
            An int, specifying the maximum number of rests
            to display as symbols.  Default is 11.
            If useSymbols is False then this setting
            does nothing.

            Change defaults.multiMeasureRestMaxSymbols to
            change globally.
            )
useSymbols
maxSymbolszdict[str, str]	_DOC_ATTRc                    t        |   |i | d | _        |j                  dt        j
                        | _        |j                  dt        j                        | _        y )Nr  r  )	r'   r(   _overriddenNumbergetr   multiMeasureRestUseSymbolsr  multiMeasureRestMaxSymbolsr  r  s      r   r(   zMultiMeasureRest.__init__K  sO    /6X6 "&",,|X5X5XY",,|X5X5XYr   c                J    | j                   dk7  rdnd}| j                    d| S )Nr   sr;   z measure)numRests)r4   plurals     r   rB   zMultiMeasureRest._reprInternalT  s)    *--11r   c                H    | j                   | j                   S t        |       S )a  
        Returns the number of measures involved in the
        multi-measure rest.

        Calculated automatically from the number of rests in
        the spanner.  Or can be set manually to override the number.

        >>> mmr = spanner.MultiMeasureRest()
        >>> for i in range(6):
        ...     mmr.addSpannedElements([note.Rest(type='whole')])
        >>> mmr.numRests
        6
        >>> mmr.numRests = 10
        >>> mmr.numRests
        10
        )r  rc   r`   s    r   r   zMultiMeasureRest.numRestsX  s&    $ !!-)))t9r   c                    || _         y rT   )r  )r4   
overriddens     r   r   zMultiMeasureRest.numRestso  s
    !+r   )r   r   r   r   r   	TextStyle_styleClassr  r   r(   rB   propertyr   setterr   r   s   @r   r  r  /  sb     //K!I~ *Z2  , __, ,r   r  c                       e Zd ZdZdddZddd	 	 	 d fdZedd	       Zedd
       ZddZ	ddZ
 ee	e
d      Z fdZ xZS )RepeatBracketa  
    A grouping of one or more measures, presumably in sequence, that mark an alternate repeat.

    These gather what are sometimes called first-time bars and second-time bars.

    It is assumed that numbering starts from 1. Numberings above 2 are permitted.
    The `number` keyword argument can be used to pass in the desired number.

    `overrideDisplay` if set will display something other than the number.  For instance
    `ouvert` and `clos` for medieval music.  However, if you use it for something like '1-3'
    be sure to set number properly too.

    >>> m = stream.Measure()
    >>> sp = spanner.RepeatBracket(m, number=1)
    >>> sp  # can be one or more measures
    <music21.spanner.RepeatBracket 1 <music21.stream.Measure 0 offset=0.0>>

    >>> sp.number = 3
    >>> sp
    <music21.spanner.RepeatBracket 3 <music21.stream.Measure 0 offset=0.0>>
    >>> sp.numberRange  # the list of repeat numbers
    [3]
    >>> sp.number
    '3'

    Range of repeats as string:

    >>> sp.number = '1-3'
    >>> sp.numberRange
    [1, 2, 3]
    >>> sp.number
    '1-3'

    Range of repeats as list:

    >>> sp.number = [2, 3]
    >>> sp.numberRange
    [2, 3]
    >>> sp.number
    '2, 3'

    Comma separated numbers:

    >>> sp.number = '1, 2, 3'
    >>> sp.numberRange
    [1, 2, 3]
    >>> sp.number
    '1-3'

    Disjunct numbers:

    >>> sp.number = '1, 2, 3, 7'
    >>> sp.numberRange
    [1, 2, 3, 7]
    >>> sp.number
    '1, 2, 3, 7'

    Override the display.

    >>> sp.overrideDisplay = '1-3, 7'
    >>> sp
    <music21.spanner.RepeatBracket 1-3, 7
         <music21.stream.Measure 0 offset=0.0>>

    number is not affected by display overrides:

    >>> sp.number
    '1, 2, 3, 7'
    ab  
            Get a contiguous list of repeat numbers that are applicable for this instance.

            Will always have at least one element, but [0] means undefined

            >>> rb = spanner.RepeatBracket()
            >>> rb.numberRange
            [0]

            >>> rb.number = '1,2'
            >>> rb.numberRange
            [1, 2]
        zr
            Override the string representation of this bracket, or use
            None to not override.
        )numberRangeoverrideDisplayr   N)numberr,  c               N    t        |   |i | g | _        || _        || _        y rT   )r'   r(   r+  r,  r-  )r4   r-  r,  r5   r6   r9   s        r   r(   zRepeatBracket.__init__  s0    
 	/6X6 ').r   c                z    t        | j                        dk(  xr" | j                  d   | j                  d   dz
  k(  S )zW
        are there exactly two numbers that should be written as 3, 4 not 3-4.
           r   r   )rc   r+  r`   s    r   _numberSpanIsAdjacentz#RepeatBracket._numberSpanIsAdjacent  sA    
 4##$)\d.>.>q.ATEUEUVWEX[\E\.\\r   c                @    t        j                  | j                        S )zK
        can we write as '3, 4' or '5-10' and not as '1, 5, 6, 11'
        )r   contiguousListr+  r`   s    r   _numberSpanIsContiguousz%RepeatBracket._numberSpanIsContiguous  s    
 $$T%5%566r   c                   t        | j                        dk(  r+| j                  d   dk(  ryt        | j                  d         S | j                  s2dj	                  | j                  D cg c]  }t        |       c}      S | j
                  r!| j                  d    d| j                  d    S | j                  d    d| j                  d    S c c}w )z
        This must return a string, as we may have single numbers or lists.
        For a raw numerical list, look at `.numberRange`.
        r   r   r;   z, ru   r   )rc   r+  r   r4  r>   r1  )r4   r}   s     r   
_getNumberzRepeatBracket._getNumber  s    
 t A%"a't''*++//yy$2B2B!C2BQ#a&2B!CDD++**1-.b1A1A"1E0FGG**1-.a0@0@0D/EFF	 "Ds   )Cc                   |dk(  r	dg| _         yt        j                  |t              r*g | _         |D ]  }| j                   j	                  |        yt        |t              rd|v rD|j                  d      \  }}t        t        t        |      t        |      dz               | _         yd|v rRg | _         |j                  d      D ]6  }t        |j                               }| j                   j	                  |       8 y|j                         rt        |      g| _         yt        d|      t        j                  |      r2g | _         || j                   vr| j                   j	                  |       yyt        d|      )zO
        Set the bracket number. There may be range of values provided
        r;   r   r   r   ,z/number for RepeatBracket must be a number, not N)r+  r   	holdsTyper   r.   r,   r   splitrf   rangestripisdigitr   isInt)r4   valuer}   startendone_letter_value
one_numbers          r   
_setNumberzRepeatBracket._setNumber  sY    B; !sDeS)!D  ''* s#e|"[[-
s#'c%j#c(Q,(G#H #% (-C(8$!$%5%;%;%=!>J$$++J7 )9 $'J< &)XY^Xa'bcc\\% !DD,,,  ''. - #%TUZT]#^__r   aA  
            Get or set the number -- returning a string always.

            >>> rb = spanner.RepeatBracket()
            >>> rb.number
            ''
            >>> rb.number = '5-7'
            >>> rb.number
            '5-7'
            >>> rb.numberRange
            [5, 6, 7]
            >>> rb.number = 1
        docc                |    | j                   | j                   dz   }n| j                  dz   }|t        |          z   S )N )r,  r-  r'   rB   )r4   r?   r9   s     r   rB   zRepeatBracket._reprInternal0  s@    +&&,C++#CUW*,,,r   )r-  int | str | Iterable[int]r,  
str | None)r   r   r   )r?  rI  )r   r   r   r   r  r(   r'  r1  r4  r6  rD  r-  rB   r   r   s   @r   r*  r*  w  s    DNI, 23-1. #+ ] ] 7 7G"`B j* 3 F- -r   r*  c                       e Zd ZdZdZdddd	 	 	 	 	 d fdZd Zd	 Z eeed
      Z	 fdZ
d ZddZddZd Zd Z xZS )Ottavaa  
    An octave shift line:

    >>> ottava = spanner.Ottava(type='8va')
    >>> ottava.type
    '8va'
    >>> ottava.type = 15
    >>> ottava.type
    '15ma'
    >>> ottava.type = (8, 'down')
    >>> ottava.type
    '8vb'
    >>> print(ottava)
    <music21.spanner.Ottava 8vb transposing>

    An Ottava spanner can either be transposing or non-transposing.
    In a transposing Ottava spanner, the notes in the stream should be
    in their written octave (as if the spanner were not there) and all the
    notes in the spanner will be transposed on Stream.toSoundingPitch().

    A non-transposing spanner has notes that are at the pitch that
    they would sound (therefore the Ottava spanner is a decorative
    line).

    >>> ottava.transposing
    True
    >>> n1 = note.Note('D4')
    >>> n2 = note.Note('E4')
    >>> n2.offset = 2.0
    >>> ottava.addSpannedElements([n1, n2])

    >>> s = stream.Stream([ottava, n1, n2])
    >>> s.atSoundingPitch = False
    >>> s2 = s.toSoundingPitch()
    >>> s2.show('text')
    {0.0} <music21.spanner.Ottava 8vb non-transposing<music21.note.Note D><music21.note.Note E>>
    {0.0} <music21.note.Note D>
    {2.0} <music21.note.Note E>

    >>> for n in s2.notes:
    ...     print(n.nameWithOctave)
    D3
    E3

    All valid types are given below:

    >>> ottava.validOttavaTypes
    ('8va', '8vb', '15ma', '15mb', '22da', '22db')

    OMIT_FROM_DOCS

    Test the round-trip back:

    >>> s3 = s2.toWrittenPitch()
    >>> s3.show('text')
    {0.0} <music21.spanner.Ottava 8vb transposing<music21.note.Note D><music21.note.Note E>>
    {0.0} <music21.note.Note D>
    {2.0} <music21.note.Note E>

    >>> for n in s3.notes:
    ...    print(n.nameWithOctave)
    D4
    E4
    )8va8vb15ma15mb22da22dbrM  Tabove)rJ   transposingr  c                   ddl m} t        |   |i | |j                  g| _        d | _        || _        || _        || _	        y )Nr   note)
r)   rW  r'   r(   NotRestr2   _typerJ   r  rT  )r4   rJ   rT  r  r5   r6   rW  r9   s          r   r(   zOttava.__init__~  sE     	!/6X6!%
	"&r   c                    | j                   S rT   )rY  r`   s    r   _getTypezOttava._getType  s    zzr   c                   t        j                  |      r|dv r|dk(  rd| _        y d| _        y t        j                  |      rt	        |      dk\  rg }|d   dv r/|j                  t        |d                |j                  d       n5|d   d	v r.|j                  t        |d                |j                  d
       t	        |      dk\  r|d   dk(  r|j                  d       n|j                  d       dj                  |      | _        y t        |t              r|j                         | j                  vrt        d|       |j                         | _        y )N)      r]  rM  rO  r   r   )r]  8v)r^  15mr0  downbar;   zcannot create Ottava of type: )r   r   rY  rq   rc   r.   r   r>   r,   lowervalidOttavaTypesr   )r4   newTypestubs      r   _setTypezOttava._setType  s"   << W%7!|"
#
w'CLA,=DqzX%C
O,C z)C
O,C 7|q WQZ6%9C C DJw,}}d.C.CC&4WI>@ @ DJr   a@  
        Get or set Ottava type. This can be set by as complete string
        (such as 8va or 15mb) or with a pair specifying size and direction.

        >>> os = spanner.Ottava()
        >>> os.type = '8vb'
        >>> os.type
        '8vb'
        >>> os.type = 15, 'down'
        >>> os.type
        '15mb'
        rE  c                d    d}| j                   sd}| j                   d| t        |          z   S )NrT  znon-transposingrH  )rT  rJ   r'   rB   )r4   rT  r9   s     r   rB   zOttava._reprInternal  s8    #+K))Ak]+eg.C.EEEr   c                    | j                   j                  d      ry| j                   j                  d      ry| j                   j                  d      ryt        d| j                         )zv
        Get basic parameters of shift.

        Returns either 8, 15, or 22 depending on the amount of shift
        r_  r]  ra  r^  22   z Cannot get shift magnitude from )rY  
startswithr   r`   s    r   shiftMagnitudezOttava.shiftMagnitude  sZ     ::  %ZZ""4(ZZ""4("%Edjj^#TUUr   c                    | j                   j                  d      r|ryy| j                   j                  d      r|ryyy)zD
        Returns up or down depending on the type of shift:
        re  rc  uprd  N)rY  endswith)r4   reverses     r   shiftDirectionzOttava.shiftDirection  s?    
 ::s#::s#	 $r   c                    ddl m} | j                  |      dk(  rd}nd}|t        | j	                               z  } ||      S )z
        return an interval.Interval() object representing this ottava

        >>> ottava = spanner.Ottava(type='15mb')
        >>> i = ottava.interval()
        >>> i
        <music21.interval.Interval P-15>
        r   )Intervalrt  rc  zP-P)music21.intervalrw  ru  r   rp  )r4   rt  rw  headers       r   intervalzOttava.interval  sJ     	.w/69FF#d))+,,r   c                    | j                   syd| _         | j                         }| j                         D ]3  }t        |d      s|j                  D ]  }|j                  |d        5 y)a  
        On a transposing spanner, switch to non-transposing,
        and transpose all notes and chords in the spanner.
        The note/chords will all be transposed to their sounding
        pitch (at least as far as the ottava is concerned;
        transposing instruments are handled separately).

        >>> ottava = spanner.Ottava(type='8va')
        >>> n1 = note.Note('D#4')
        >>> n2 = note.Note('E#4')
        >>> ottava.addSpannedElements([n1, n2])
        >>> ottava.transposing
        True

        >>> ottava.performTransposition()

        >>> ottava.transposing
        False
        >>> n1.nameWithOctave
        'D#5'
        NFpitchesTinPlacerT  r|  r<   hasattrr~  	transposer4   
myIntervalrn   ps       r   performTranspositionzOttava.performTransposition  sa    ,  ]]_
((*A1i(YYJ5  +r   c                    | j                   ryd| _         | j                  d      }| j                         D ]3  }t        |d      s|j                  D ]  }|j                  |d        5 y)a  
        Change a non-transposing spanner to a transposing spanner,
        and transpose back all the notes and chords in the spanner.
        The notes/chords will all be transposed to their written
        pitch (at least as far as the ottava is concerned;
        transposing instruments are handled separately).

        >>> ottava = spanner.Ottava(type='8va')
        >>> n1 = note.Note('D#4')
        >>> n2 = note.Note('E#4')
        >>> ottava.addSpannedElements([n1, n2])
        >>> ottava.transposing = False

        >>> ottava.undoTransposition()

        >>> ottava.transposing
        True
        >>> n1.nameWithOctave
        'D#3'
        NTrx  r~  r  r  r  s       r   undoTranspositionzOttava.undoTransposition  sf    * ]]4]0
((*A1i(YYJ5  +r   )rJ   r   rT  r   r  zt.Literal['above', 'below']r   )r   r   r   r   rg  r(   r[  rj  r'  rJ   rB   rp  ru  r|  r  r  r   r   s   @r   rL  rL  ;  s~    ?@ F #%):A	'' #' 8	')6 Hh - DFV" $6B6r   rL  c                      e Zd ZdZdZdZddddddd	 	 	 	 	 	 	 	 	 	 	 d fdZd	 Zd
 Z e	eed      Z
d Zd Z e	eed      Zd Zd Z e	eed      Zd Zd Z e	eed      Zd Zd Z e	eed      Zd Zd Z e	eed      Z xZS )Linea	  
    A line or bracket represented as a spanner above two Notes.

    Brackets can take many line types.

    >>> b = spanner.Line()
    >>> b.lineType = 'dotted'
    >>> b.lineType
    'dotted'
    >>> b = spanner.Line(endHeight=20)
    >>> b.endHeight
    20
    soliddasheddottedwavy)rr  rc  arrowbothnoner  rc  N)r  tick	startTickendTickstartHeight	endHeightc               
   t        |   |i | d}	|	| _        |	| _        d | _        d | _        d}
|
| _        d}|| _        ||
k7  r|| _        ||	k7  r|| _	        ||	k7  r|| _
        ||	k7  r|| _        ||| _        ||| _        y y )Nrc  r  rS  )r'   r(   _endTick
_startTick
_endHeight_startHeight	_lineTyper  r  r  r  r  r  r  )r4   r  r  r  r  r  r  r5   r6   DEFAULT_TICKDEFAULT_LINE_TYPEDEFAULT_PLACEMENTr9   s               r   r(   zLine.__init__D  s     	/6X6 $& #*#*(($DM$&DNl""DL<DI &DN"*D #r   c                    | j                   S rT   )r  r`   s    r   _getEndTickzLine._getEndTicko  s    }}r   c                    |j                         | j                  vrt        d|       |j                         | _        y Nnot a valid value: )rf  validTickTypesr   r  r4   r?  s     r   _setEndTickzLine._setEndTickr  s6    ;;= 3 33"%8#@AAr   z2
        Get or set the endTick property.
        rE  c                    | j                   S rT   r  r`   s    r   _getStartTickzLine._getStartTick{      r   c                    |j                         | j                  vrt        d|       |j                         | _        y r  )rf  r  r   r  r  s     r   _setStartTickzLine._setStartTick~  s6    ;;= 3 33"%8#@AA++-r   z4
        Get or set the startTick property.
        c                    | j                   S rT   r  r`   s    r   _getTickzLine._getTick  r  r   c                    |j                         | j                  vrt        d|       |j                         | _        |j                         | _        y r  )rf  r  r   r  r  r  s     r   _setTickzLine._setTick  sC    ;;= 3 33"%8#@AA++-r   z
        Set the start and end tick to the same value


        >>> b = spanner.Line()
        >>> b.tick = 'arrow'
        >>> b.startTick
        'arrow'
        >>> b.endTick
        'arrow'
        c                    | j                   S rT   r  r`   s    r   _getLineTypezLine._getLineType      ~~r   c                    |*|j                         | j                  vrt        d|       ||j                         | _        y y r  rf  validLineTypesr   r  r  s     r   _setLineTypezLine._setLineType  sF    d6I6I!I"%8#@AA"[[]DN r   a  
        Get or set the lineType property. Valid line types are listed in .validLineTypes.

        >>> b = spanner.Line()
        >>> b.lineType = 'dotted'
        >>> b.lineType = 'navyblue'
        Traceback (most recent call last):
        music21.spanner.SpannerException: not a valid value: navyblue

        >>> b.validLineTypes
        ('solid', 'dashed', 'dotted', 'wavy')
        c                    | j                   S rT   )r  r`   s    r   _getEndHeightzLine._getEndHeight  r  r   c                b    t        j                  |      r|dk\  st        d|       || _        y Nr   r  )r   r   r   r  r  s     r   _setEndHeightzLine._setEndHeight  s.    U#
"%8#@AAr   z
        Get or set the endHeight property.

        >>> b = spanner.Line()
        >>> b.endHeight = -20
        Traceback (most recent call last):
        music21.spanner.SpannerException: not a valid value: -20
        c                    | j                   S rT   )r  r`   s    r   _getStartHeightzLine._getStartHeight  s       r   c                b    t        j                  |      r|dk\  st        d|       || _        y r  )r   r   r   r  r  s     r   _setStartHeightzLine._setStartHeight  s/    U#
"%8#@AA!r   z
        Get or set the startHeight property.

        >>> b = spanner.Line()
        >>> b.startHeight = None
        Traceback (most recent call last):
        music21.spanner.SpannerException: not a valid value: None
        )r  r   r  r   r  r   r  r   r  int | float | Noner  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   r   s   @r   r  r  3  s%    ;N<N
  &*$()+ )+ 	)+
 )+ )+ $)+ ")+V&
 {K 6 G(
  < I& Hh 
- 
D+ l 9 H 
  < I!"
 ?O B Kr   r  c                       e Zd ZdZdZdZddd	 	 	 d fdZd Zd	 Z e	eed
      Z
e	d        Zej                  d        Z xZS )	Glissandoa  
    A between two Notes specifying a glissando or similar alteration.
    Different line types can be specified.

    Glissandos can have a label and a lineType.  Label is a string or None.
    lineType defaults to 'wavy'

    >>> gl = spanner.Glissando()
    >>> gl.lineType
    'wavy'
    >>> print(gl.label)
    None

    >>> gl.label = 'gliss.'

    Note -- not a Line subclass for now, but that might change.
    r  )	chromatic
continuousdiatonicwhiteblackr  N)r  labelc               ~    t        |   |i | d}|| _        d| _        d | _        ||k7  r|| _        ||| _        y y )Nr  r  )r'   r(   r  
_slideTyper  r  )r4   r  r  r5   r6   GLISSANDO_DEFAULT_LINE_TYPEr9   s         r   r(   zGlissando.__init__  sV    
 	/6X6 '-#4%
22$DMDJ r   c                    | j                   S rT   r  r`   s    r   r  zGlissando._getLineType  r  r   c                    |j                         | j                  vrt        d|       |j                         | _        y r  r  r  s     r   r  zGlissando._setLineType	  s6    ;;= 3 33"%8#@AAr   zR
        Get or set the lineType property. See Line for valid line types.
        rE  c                    | j                   S )a  
        Get or set the slideType which determines how
        the glissando or slide is to be played.  Values
        are 'chromatic' (default), 'continuous' (like a slide or smear),
        'diatonic' (like a harp gliss), 'white' (meaning a white-key gliss
        as on a marimba), or 'black' (black-key gliss).

        'continuous' slides export to MusicXML as a <slide> object.
        All others export as <glissando>.
        )r  r`   s    r   	slideTypezGlissando.slideType	  s     r   c                    |j                         | j                  vrt        d|       |j                         | _        y r  )rf  validSlideTypesr   r  r  s     r   r  zGlissando.slideType	  s6    ;;= 4 44"%8#@AA++-r   )r  r   r  rJ  )r   r   r   r   r  r  r(   r  r  r'  r  r  r(  r   r   s   @r   r  r    s    " ;NOO "(#' !('
 l 9 H   ( (r   r  c                      e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d  Z"y!)"Testc                (    ddl m}  |       | _        y )Nr   )GeneralObjectExporter)music21.musicxml.m21ToXmlr  GEX)r4   r  s     r   setUpz
Test.setUp$	  s    C(*r   c                Z    | j                   j                  |      }|j                  d      S )Nzutf-8)r  parsedecode)r4   objxmlBytess      r   xmlStrzTest.xmlStr(	  s#    88>>#&w''r   c                2    ddl m}  || t                      y )Nr   )testCopyAll)music21.test.commonTestr  globals)r4   r  s     r   testCopyAndDeepcopyzTest.testCopyAndDeepcopy,	  s    7D')$r   c                   ddl m} ddl m} ddl m}  |j                         } |j
                         } |j
                         }|j                  ||      }|j                  d|       |j                  d|       |j                  d|       | j                  t        |      d       | j                  |j                         ||g       |j                         }|j                         }	|j                         }
|j                  |       |j                  |	       |j                  |
       t               }|j                  ||
g       |j                  |       | j                  t        |      d       | j                  |j                         ||
g       | j                  |j                         |g       t               }t               }t               }t!        |||g      }| j                  t        |j                               d       | j                  |j                         |||g       | j                  |j                         |g       y )Nr   r   rV  )layout   )r)   r   rW  r  ScorePart
StaffGroupinsertassertEqualrc   r<   Noter.   r  r/   getSpannerSitesr!   )r4   r   rW  r  r  p1p2sg1n1n2n3slur1sl1sl2sl3r   s                   r   	testBasiczTest.testBasic0	  s    	# "FLLNV[[]V[[]B' 	
B	B	CQ#//1B8<
 YY[YY[YY[
		"
		"
		"  "b*
		%Q#113b"X> 	++-w7 fffc3_%R2245q9..03S/B,,.5r   c                2   ddl m} ddl m} |j                         }| j	                  t        |      d        |j                         }|j                  d|       | j	                  t        |      d       d|_        | j	                  t        |      d       y )	Nr   r   r   z*<music21.spanner.SpannerAnchor unanchored>g      ?z&<music21.spanner.SpannerAnchor at 0.5>g      @z*<music21.spanner.SpannerAnchor at 0.5-3.0>)	r)   r   r   r   r  r=   r   r  r   )r4   r   r   sa1rb  s        r   testSpannerAnchorReprzTest.testSpannerAnchorReprc	  s    "# ##%c$PQ FNN	cc$LM  c$PQr   c                f    ddl m} |j                         }| j                  t	        |      d       y )Nr   r  z<music21.spanner.Slur>)r)   r   r  r  r=   )r4   r   su1s      r   testSpannerReprzTest.testSpannerReprt	  s%    #llnc$<=r   c                ~   ddl m} ddl m} ddl m} |j	                  d      |j	                  d      |j	                  d      |j	                  d      g} |j
                  |      }|j                  |d   |d	         }|j                  |       |d   |d	   g}| j                  t        |      d
       t        |j                               D ]  \  }}	| j                  |	||           |j                  |      }
d|
_        |
j                  |       | j                  t        |      d
       t        |j                               D ]  \  }}	| j                  |	||           d|
_        |
j                  |       | j                  |
j                  d       | j                  t        |
      d       t        |
j                               D ]  \  }}	| j                  |	||           |j                         }|j                  |       | j                  t        |      d       |j	                  d      g}|j                  |      }|j                  |       | j                  t        |      d       | j                  |j                         |d          |j	                  d      |j                   d   g}|j                  |      }|j                  |       | j                  t        |      d
       t        |j                               D ]  \  }}	| j                  |	||           |j                   d   |j	                  d      g}|j                  |      }|j                  |       | j                  t        |      d
       t        |j                               D ]  \  }}	| j                  |	||           y )Nr   r   rV  r  ABCDr  r0  TF   Er   FG)r)   r   rW  r   r  r   r!   r   r  rc   r   r<   assertIsrL  r3   r   notes)r4   r   rW  r   theNotesrb  r   noFillElementsr   elott1ott2expectedElementsott3ott4ott5s                   r   testSpannerFillzTest.testSpannerFilly	  s   " #IIcNDIIcNDIIcNDIIcNSFNN8$ __Xa[(1+6

"1+x{3R!$r4467EArMM"nQ/0 8 ~~n- 		!R!$r4467EArMM"nQ/0 8 "		!d''.TA&t6689EArMM"hqk* : ~~		!TA& !IIcN+~~./		!TA&dmmo'7':; !IIcNAGGAJ7~~./		!TA&t6689EArMM".q12 : GGAJ		#7~~./		!TA&t6689EArMM".q12 :r   c                   ddl m} ddl m} |j                         }d|_        |j                         }d|_        |j                         }|j                  |       |j                  |       | j                  t        |      d       | j                  |d   |       | j                  |d   |       |j                         }|j                         } |j                         }|j                  |       |j                  |       |j                  t        |            }	| j                  t        |	      d       | j                  |	d   |       | j                  |	d   |       y )Nr   r  r   r   r0  )r)   r   r   r  r0   r   r.   r  rc   r   rf   )
r4   r   r   r  su2sbsu3su4r  sb2s
             r   testSpannerBundlezTest.testSpannerBundle	  s   #"llnlln""$
		#
		#R!$A$A$llnllnFMMO		##DG,S1%Q%Q%r   c                   ddl m} ddl m} |j                         }|j                         }t	               }|j                  ||g       | j                  |j                         |g       | j                  |j                         |g       t        j                  |      }| j                  |j                         ||g       | j                  |j                         ||g       | j                  |j                         ||g       | j                  |j                         ||g       |j                  ||g      }t        j                  |      }| j                  |d   j                         ||g       | j                  |d   j                         ||g       | j                  t        |d         t        |d                y )Nr   r  rV  )r)   r   rW  r  r  r/   r  r  copydeepcopyr<   r   assertNotEqualrm   )	r4   r   rW  r  r  r  r  sb1r  s	            r   testDeepcopySpannerzTest.testDeepcopySpanner	  su   #  YY[YY[fBx(++-u5++-u5mmC //1B8<//1B8<++-Sz:++-Sz:##S#J/mmC Q224r2h?Q224r2h?Bs1vJ3q6
3r   c                   ddl m} ddl m} |j                         }|j                         }|j                         }|j                         }|j                         }|j	                         }|j                  ||g       | j                  |j                         ||g       | j                  |j                         |g       |j                  ||       | j                  |j                         ||g       | j                  |j                         g        | j                  |j                         |g       |j                  ||       | j                  |j                         ||g       | j                  |j                         g        | j                  |j                         |g       |j	                         }	|	j                  ||g       |j	                         }
|
j                  ||g       |j                         }|j                         }|j                  ||	|
g      }| j                  t        |      d       | j                  t        |      ||	|
g       |j                  ||       | j                  t        |      d       | j                  t        |      ||	|
g       | j                  |d   j                         ||g       | j                  |d   j                         ||g       |j                  ||       | j                  |d   j                         ||g       | j                  |d   j                         ||g       y )Nr   rV  r  r  r   r0  )r)   rW  r   r  r  r/   r  r<   r  r   r   rc   rf   )r4   rW  r   r  r  r  n4n5r  r  r  n3an4ar%  s                 r   testReplaceSpannedElementzTest.testReplaceSpannedElement	  s    #YY[YY[YY[YY[YY[llnBx(//1B8<++-u5!!"b)//1B8<++-r2++-u5 	!!"b)//1B8<++-r2++-u5llnBx(llnBx( iikiik ##S#sO4S1%cS#sO4 	!!"c*S1%cS#sO4Q224r3i@Q224sBi@!!"c*Q224sCjA 	Q224sBi@r   c                    ddl m} ddl m}  |j                         }|j	                  |      }|j                  |       | j                  t        |      d       y )Nr   r  r   r   )r)   r   r   r   r*  r/   r  rc   )r4   r   r   m1rb1s        r   testRepeatBracketAzTest.testRepeatBracketA+
  sH    #"V^^##B'r"S1%r   c                   ddl m} ddl m} ddl m} ddl m}  |j
                         } |j                         }|j                  |j                  d      d       |j                  |        |j                         }|j                  |j                  d      d       |j                  |        |j                         }|j                  |j                  d	      d       |j                  d
      |_        |j                  |       |j                  |j                  |d              |j                         }	|	j                  |j                  d      d       |j                  d
      |	_        |j                  |	       |j                  |j                  |	d              |j                         }
|
j                  |j                  d      d       |j                  d
      |
_        |j                  |
       |j                  |j                  |
d              |j                         }|j                  |j                  d      d       |j                  |       | j                  t        |j                        d       y )Nr   rV  r  r   barc4r
  d#4g#4rA  	directionr   r-  a4r0  b4r  c#5)r)   rW  r   r   r3  r  r   repeatAppendr  r.   RepeatrightBarliner*  r  rc   r   )r4   rW  r   r   r3  r  r.  m2m3m4m5m6s               r   testRepeatBracketBzTest.testRepeatBracketB5
  s    #"FKKMV^^
		$+	V^^
		%(!,	V^^
		%(!,**u*5		&&r!&45V^^
		$+**u*5		&&r!&45V^^
		$+**u*5		&&r!&45V^^
		%(!,	 	QZZ!,r   c                h   ddl m} ddl m} ddl m} ddl m}  |j
                         } |j                         }|j                  |j                  d      d       |j                  |        |j                         }|j                  |j                  d      d       |j                  |        |j                         }|j                  |j                  d	      d       |j                  d
      |_        |j                  |       |j                  d      }	|	j                  ||       | j                  t        |	      d       |j!                  d|	        |j                         }
|
j                  |j                  d      d       |j                  d
      |
_        |j                  |
       |j                  |j                  |
d              |j                         }|j                  |j                  d      d       |j                  |       | j                  t        |j"                        d       | j%                  |      }| j'                  |j)                  d      d       | j'                  |j)                  d      d       | j'                  |j)                  d      d       y )Nr   rV  r  r   r2  r4  r
  r5  r6  rA  r7  r   r9  r0  r:  r;  "<ending number="1" type="start" />!<ending number="2" type="stop" />"<ending number="2" type="start" />)r)   rW  r   r   r3  r  r   r=  r  r.   r>  r?  r*  r/   r  rc   r  r   r  assertGreaterfind)r4   rW  r   r   r3  r  r.  r@  rA  r/  rB  rC  raws                r   testRepeatBracketCzTest.testRepeatBracketC]
  s    #"FKKMV^^
		$+	V^^
		%(!,	V^^
		%(!,**u*5	##1#-r2&S1%	CV^^
		$+**u*5		&&r!&45V^^
		$+	 	QZZ!, kk!n388$LMqQ388$KLaP388$LMqQr   c                   ddl m} ddl m} ddl m} ddl m}  |j
                         } |j                         }|j                  |j                  d      d       |j                  |        |j                         }|j                  |j                  d      d       |j                  |        |j                         }|j                  |j                  d	      d       |j                  d
      |_        |j                  |       |j                  d      }	|	j                  ||       | j                  t        |	      d       |j!                  d|	        |j                         }
|
j                  |j                  d      d       |j                  |
        |j                         }|j                  |j                  d      d       |j                  d
      |_        |j                  |       |j                  d      }|j                  |
|       | j                  t        |      d       |j!                  d|        |j                         }|j                  |j                  d      d       |j                  |        |j                         }|j                  |j                  d      d       |j                  |        |j                         }|j                  |j                  d      d       |j                  d
      |_        |j                  |       |j                  d      }|j                  ||       | j                  t        |      d       |j!                  d|        |j                         }|j                  |j                  d      d       |j                  |        |j                         }|j                  |j                  d      d       |j                  |        |j                         }|j                  |j                  d      d       |j                  |        |j                         }|j                  |j                  d      d       |j                  d
      |_        |j                  |       |j                  d      }|j                  ||||       | j                  t        |      d       |j!                  d|       | j                  t        |j#                  |j                              d       | j                  t        |j$                        d       | j'                  |      }| j)                  |j+                  d      d       | j)                  |j+                  d      d       | j)                  |j+                  d      d       t-        j.                  |      }| j'                  |      }| j)                  |j+                  d      d       | j)                  |j+                  d      d       | j)                  |j+                  d      d       t-        j.                  |      }| j'                  |      }| j)                  |j+                  d      d       | j)                  |j+                  d      d       | j)                  |j+                  d      d       y )Nr   rV  r  r   r2  r4  r
  r5  r6  rA  r7  r   r9  r0  r:  r;  r     rG  rH  rI  )r)   rW  r   r   r3  r  r   r=  r  r.   r>  r?  r*  r/   r  rc   r  rh   r   r  rJ  rK  r"  r#  )r4   rW  r   r   r3  r  r.  r@  rA  r/  rB  rC  rb2rD  m7m8rb3m9m10m11m12rb4rL  r  r  s                            r   testRepeatBracketDzTest.testRepeatBracketD
  s#    #"FKKMV^^
		$+	V^^
		%(!,	V^^
		%(!,**u*5	##1#-r2&S1%	CV^^
		$+	V^^
		$+**u*5	##1#-r2&S1%	CV^^
		$+	V^^
		$+	V^^
		$+**u*5	##1#-r2&S1%	CV^^
		$+	fnn4!,	fnn4!,	fnn4!,:::6	##1#-r3S1S1%	C 	Q11&..ABBGQZZ!,kk!n388$LMqQ388$KLaP388$LMqQ]]1kk"o388$LMqQ388$KLaP388$LMqQ]]2kk"o388$LMqQ388$KLaP388$LMqQr   c                \   ddl m} ddl m} ddl m} ddl m}  |j
                         } |j                  d      }|j                  |j                  d      d       |j                  |        |j                  d	      }|j                  |j                  d
      d       |j                  |        |j                  d      }|j                  |j                  d      d       |j                  d      |_        |j                  |       |j                  |j                  |d              |j                  d      }	|	j                  |j                  d      d       |j                  d      |	_        |j                  |	       |j                  |j                  |	d	              |j                  d      }
|
j                  |j                  d      d       |j                  d      |
_        |j                  |
       |j                  |j                  |
d              |j                  d      }|j                  |j                  d      d       |j                  |       | j                  t        |j                        d       t!        j"                  |      }| j                  t        |j                        d       |j%                  |j                        d   }
|j                  d	   }| j'                  |j)                  |
             t!        j"                  |      }| j                  t        |j                        d       |j%                  |j                        d   }
|j                  d	   }| j'                  |j)                  |
             t!        j"                  |      }| j                  t        |j                        d       |j%                  |j                        d   }
|j                  d	   }| j'                  |j)                  |
             y )Nr   rV  r  r   r2  r   r9  r4  r0  r5  r  r6  rA  r7  r
  r:     r;  r  r<  )r)   rW  r   r   r3  r  r   r=  r  r.   r>  r?  r*  r  rc   r   r"  r#  rh   
assertTruerr   )r4   rW  r   r   r3  r  r.  r@  rA  rB  rC  rD  r  sp3r  p3s                   r   testRepeatBracketEzTest.testRepeatBracketE
  s    #"FKKMV^^1%
		$+	V^^1%
		%(!,	V^^1%
		%(!,**u*5		&&r!&45V^^1%
		$+**u*5		&&r!&45V^^1%
		$+**u*5		&&r!&45V^^1%
		%(!,	 	QZZ!, ]]1R[[)1-""6>>226kk!n--b12 ]]2R[[)1-""6>>226kk!n--b12]]2R[[)1-""6>>226kk!n--b12r   c                &   ddl m} ddl m} ddl m} ddlm}  |j                         }|j                  |j                  ddg      d       |j                  d   }|j                  d	   } |||      }|j                  |       | j                  |      }	| j                  |	j                  d
      d       | j                  |	j                  d      d        |j                         }|j                  |j                         d       |j                  d   }|j                  d	   } |||d      }|j                  |       | j                  |      }	| j                  |	j                  d
      d       | j                  |	j                  d      d        |j                         }|j                  |j                         d       |j                  d   }|j                  d	   } |||d      }|j                  |       | j                  |      }	| j                  |	j                  d
      d       | j                  |	j                  d      d        |j                         }|j                  |j                         d       |j                  d   }|j                  d	   } |||d      }|j                  |       | j                  |      }	| j                  |	j                  d
      d       | j                  |	j                  d      d       y)z}
        Test basic octave shift creation and output, as well as passing
        objects through make measure calls.
        r   r   rV  )chord)rL  zc-3g4rO  ru   octave-shiftr0  type="down"r   rN  rJ   z	type="up"rO  rP  N)r)   r   rW  rb  music21.spannerrL  r   r=  Chordr  r.   r  r  countr  )
r4   r   rW  rb  rL  r  r  r  sp1rL  s
             r   testOttavaShiftAzTest.testOttavaShiftA-  sb   
 	# !*FMMO	u{{E4=126WWQZWWR[Rn	kk!n>2A6=115 FMMO	tyy{B'WWQZWWR[R%(	kk!n>2A6;/3FMMO	tyy{B'WWQZWWR[R&)	kk!n>2A6=115FMMO	tyy{B'WWQZWWR[R&)	kk!n>2A6;/3r   c                x   ddl m} ddl m} ddl m}  |j                         }|j                  d      }|j                  |      }|j                  |       |j                  |       | j                  |      }| j                  |j                  d      d       | j                  |j                  d      d	       y
)z+
        Test a single note octave
        r   r   rV  r  r4  rd  r0  re  r   N)r)   r   rW  r   r   r  rL  r.   r  r  ri  )r4   r   rW  r   r  rn   r   rL  s           r   testOttavaShiftBzTest.testOttavaShiftBc  s     	# #FMMOIIdO^^A		kk!n>2A6=115r   c                j   ddl m} ddl m} ddl m}  |j                         }|j                  |j                  d      d       |j                  d   }d|j                  _	        |j                  t        |j                        d	z     }d
|j                  _	        |j                  d   }d|j                  _	        |j                  ||      }|j                  ||      }	|j                  |       |j                  |	       | j                  |      }
| j                  |
j!                  d      d       y )Nr   r   rV  )dynamicshalfrf  r
  r	  r0  r  ru   r  z<wedge)r)   r   rW  ro  r   r=  r  r  pitchsteprc   r   r   r.   r  r  ri  )r4   r   rW  ro  r  r  r  r  rj  sp2rL  s              r   testCrescendoAzTest.testCrescendoAt  s    " $FMMO 	
tyyfy-q1WWQZWWS\Q&'WWR[!!"b)  R(		 kk!n8,a0r   c                   ddl m} ddl m} ddl m}  |j                         }|j                  |j                         d       |j                  d   }|j                  t        |j                        dz     }|j                  d   }|j                  ||dd	
      }|j                  ||ddd      }	|j                  |       |j                  |	       | j                  |      }
| j                  |
j                  d      d       y )Nr   r   rV  r  rO  r0  ru   rr  r  )r  r  rc  r  (   )r  r  r  <bracketr
  )r)   r   rW  r   r   r=  r  r  rc   r  r.   r  r  ri  )r4   r   rW  r   r  r  r  r  rj  rs  rL  s              r   	testLineAzTest.testLineA  s    " #FMMO	tyy{B'WWQZWWS\Q&'WWR[ll2rTHlEll2rVh.0  2		kk!n:.2r   c                
   ddl m} ddl m} ddl m}  |j                         }|j                  |j                         d       |j                  d   }|j                  d   }|j                  d   }|j                  d   }|j                  ||d	d
d      }	|j                  ||ddd      }
|j                  |	       |j                  |
       | j                  |      }| j                  |j                  d      d       | j                  |j                  d      d       | j                  |j                  d      d       | j                  |j                  d      d       | j                  |j                  d      d       y )Nr   r   rV  r  rO  r
  ru   r0  rr  rc  r  )r  r  r  r  r  rw  zline-end="arrow"r   zline-end="none"zline-end="up"zline-end="down")r)   r   rW  r   r   r=  r  r  r  r.   r  r  ri  )r4   r   rW  r   r  r  r  r  r(  rj  rs  rL  s               r   	testLineBzTest.testLineB  s5   " #FMMO	tyy{B'WWQZWWR[WWQZWWQZll2rT6GlTll2rWfwlW		 kk!n:.2#56:#45q9?3Q7#45q9r   c                   ddl m} ddl m} ddl m}  |j                         }|j                  |j                         d       t        |j                        D ]!  \  }}|j                  ||dz  dz  z   d	       # |j                  d   }|j                  t        |j                        dz     }|j                  d
   }	|j                  ||      }
|j                  ||	      }d|_        |j                  |
       |j                  |       |j                         }| j                  |      }| j!                  |j#                  d      d       | j!                  |j#                  d      d       y )Nr   r   rV  r  r  r0  rO  Tr  ru   r  
<glissandor
  zline-type="dashed")r)   r   rW  r   r   r=  r  r   r  r  rc   r  r  r.   makeNotationr  r  ri  )r4   r   rW  r   r  r   rn   r  r  r  rj  rs  rL  s                r   testGlissandoAzTest.testGlissandoA  s$   " #FMMO	tyy{A&agg&DAqKKQURZ($K7 ' WWQZWWS\Q&'WWR[B'B'		NNkk!n<0!4#78!<r   c                   ddl m} ddl m} ddl m}  |j                         }|j                  |j                         d       t        |j                        D ]!  \  }}|j                  ||dz  dz  z   d       # |j                  d   }|j                  d	   }|j                  ||      }	d
|	_        d|	_        |j                  |	       | j                  |      }
| j                  |
j!                  d      d       | j                  |
j!                  d      d       | j                  |
j!                  d      d	       y )Nr   r   rV  r  rO  r0  Tr  r   r  zgliss.r|  zline-type="solid"z>gliss.<)r)   r   rW  r   r   r=  r  r   r  r  r  r  r  r.   r  r  ri  )r4   r   rW  r   r  r   rn   r  r  rj  rL  s              r   testGlissandoBzTest.testGlissandoB  s   " #FMMO	tyy{B'agg&DAqKKQURZ($K7 ' WWQZWWQZB'		 kk!n<0!4#67;:.2r   c                0   ddl m} ddlm} |j	                         } |       }|j                  |       d|_        | j                  |j                         | j                  |j                  |             | j                  |j                  |             y )Nr   rV  r!   T)
r)   rW  rg  r!   r  r/   r1   r]  r   r   )r4   rW  r!   r  r   s        r   testOneElementSpannerszTest.testOneElementSpanners  sj     +YY[Y
b! ))*

2'		"&r   c                R   ddl m} ddl m} ddlm}m}  |j                         } |j                         } |j                         }d|_        d|_        |j                  dd	      }|j                  d
d	      }	|j                  d|       |j                  d|	       |j                  |       |j                  |        |||	g      }
|j                  d|
       |D ]   }t        ||      s|j                  |       " | j                  t        |j                         d       y )Nr   r   rV  )r!   r  r   r0  C#4wholerf  D#4)r)   r   rW  rg  r!   r  r  r   r-  r  r  r.   r,   r   r  rc   r   )r4   r   rW  r!   r  r  r.  r@  r  r  slr}   s               r   testRemoveSpannerszTest.testRemoveSpanners  s    " 1FKKMV^^V^^		YYu7Y+YYu7Y+
		!R
		!R		2r(^	BA!W%  	QZZ!,r   c                   ddl m} ddl m} ddl m} ddlm}  |j                         } |j                         } |j                         }d|_        d|_        |j                  dd	
      }|j                  dd	
      }	|j                  d|       |j                  d|	       |j                  |       |j                  |        |||	g      }
|j                  d|
       |j                  |d      }y )Nr   r   rV  	converterr  r   r0  r  r  rf  r  pickle)fmt)r)   r   rW  r  rg  r  r  r   r-  r  r  r.   	freezeStr)r4   r   rW  r  r  r  r.  r@  r  r  r  unused_datas               r   testFreezeSpannerszTest.testFreezeSpanners0  s    " %(FKKMV^^V^^		YYu7Y+YYu7Y+
		!R
		!R		2r(^	B))!):r   c                   ddl m} ddl m} ddlm} |j                  d      }|j                  d      }|j                         } ||||      }t        j                  |      }| j                  t        |j                        d       | j                  ||       | j                  |d   |d          | j                  |d   |d          | j                  |d   |       | j                  |d   |       y )	Nr   rV  clefr  gf#r  r0  )r)   rW  r  rg  r!   r  AltoClefr"  r#  r  rc   r"   assertIsNotr  )	r4   rW  r  r!   r  r  c1rj  rs  s	            r   testDeepcopyJustSpannerAndNotesz$Test.testDeepcopyJustSpannerAndNotesE  s      +YYs^YYt_]]_b"b!mmC S//0!4c"c!fc!f%c!fc!f%c!fb!c!fb!r   c                \   ddl m} ddl m} ddl m} ddlm} |j                  d      }|j                  d      }|j                         } ||||      } |j                         }	|	j                  d|       t        j                  |	      }
|
j                  d   }| j                  t        |j                        d	       | j!                  ||       | j#                  |d   |d          | j#                  |d
   |d
          | j#                  |d   |       | j#                  |d   |       y )Nr   rV  r  r   r  r  r          r  r0  )r)   rW  r  r   rg  r!   r  r  r   r  r"  r#  r   r  rc   r"   r  r  )r4   rW  r  r   r!   r  r  r  rj  st1st2rs  s               r   #testDeepcopySpannerInStreamNotNotesz(Test.testDeepcopySpannerInStreamNotNotesW  s      "+YYs^YYt_]]_b"b!fmmo

3mmC ll1oS//0!4c"c!fc!f%c!fc!f%c!fb!c!fb!r   c                   ddl m} ddl m} ddl m} ddlm} |j                  d      }|j                  d      }|j                         } ||||      } |j                         }	|	j                  d|       |	j                  d	|       t        j                  |	      }
|
j                  d   }| j                  t        |j                               d
       |j                         d   }| j!                  ||       | j#                  ||       | j!                  |d   |d          | j!                  |d   |       | j!                  |d   |       y )Nr   rV  r  r   r  r  r  r        ?r   r0  )r)   rW  r  r   rg  r!   r  r  r   r  r"  r#  r  r  rc   r  r  r  )r4   rW  r  r   r!   r  r  r  rj  r  r  r  rs  s                r   #testDeepcopyNotesInStreamNotSpannerz(Test.testDeepcopyNotesInStreamNotSpannern  s     "+YYs^YYt_]]_b"b!fmmo

3

3mmC YYq\R//12A6  "1%c3R c!fc!f%c!fb!c!fb!r   c                   ddl m} ddl m} ddlm} |j                  d      }|j                  d      } |||      } |j                         }|j                  d|       |j                  d|       |j                  d|       t        j                  |      }|j                  d   }	| j                  t        |	j                               d	       |	j                         d   }
| j                  ||
       | j                  ||	       |j                  d   }| j!                  |
|       | j!                  |d   |       | j!                  |
d   |	       y )
Nr   rV  r   r  G4zF#4r  r  r   )r)   rW  r   rg  r!   r  r   r  r"  r#  r  r  rc   r  r  r   r  )r4   rW  r   r!   r  r  rj  r  r  r  rs  r^  s               r   #testDeepcopyNotesAndSpannerInStreamz(Test.testDeepcopyNotesAndSpannerInStream  s    "+YYt_YYub"ofmmo

3

3

3mmC YYq\R//12A6  "1%c"R ll1oc3c!fb!c!fb!r   c                   ddl m} ddl m} ddlm} |j                         } ||f      } |j                         }|j                  d|       |j                  d|       | j                  |j                  d   j                         |       | j                  |j                  d   j                         d   |       t        j                  |      }|j                  d   }|j                  d   }	| j                  ||       | j                  |	|       | j                  |j                  d   j                         |	       | j                  |j                  d   j                         d   |       | j                  |j                  d   j                         d   |       | j!                  t#        |j$                        d       |j$                  j'                  |	      }
| j!                  t#        |
      d       y )Nr   rV  r   r  r  r   )r)   rW  r   rg  r  r  r   r  r  r   r   r  r  r"  r#  r  r  rc   spannerBundler   )r4   rW  r   r  r  r  r  s2r  r  tn2s              r   testDeepcopyStreamWithSpannersz#Test.testDeepcopyStreamWithSpanners  s    "(YY[B5kFMMO	c	bajjm,,.3aggaj00215s;]]1kk!nXXa[c"R bkk!n--/4bhhqk113A6<335a8#>R--.22226S1%r   c                   ddl m} ddlm} |j	                  d      }|j	                  d      }|j	                  d      }|j	                  d      }|j	                  d      } |       }|j                  |       |j                  ||       |j                  ||g       |||||fD 	cg c]  }	t        |	       }
}	|j                         }| j                  |
|       y c c}	w )	Nr   rV  r  r  r  r   zd-r@   )	r)   rW  rg  r!   r  r/   rm   ro   r  )r4   rW  r!   r  r  r  r(  r)  r  rn   idListslLists               r   testGetSpannedElementIdszTest.testGetSpannedElementIds  s     +YYs^YYt_YYs^YYt_YYs^Y
b!
b"%
r2h'"$b"b"!56!5A"Q%!56((*( 7s   (Cc                r   ddl m} ddlm} |j	                  |j
                        }t        |j                         j                  d            }t        |j                         j                  d            }| j                  |d       | j                  |d       |j                         j                  d      d   }|j                         d   }|j                         d   }| j                  |j                         d   |       | j                  |j                         d   |       |j                         j                  d      d   }	|	j                         d   }
|	j                         d   }| j                  |
j                         d   |	       | j                  |j                         d   |	       y )Nr   r  )testPrimitiveHammerOnPullOffr   )r)   r  music21.musicxmlr  r  notations32arc   flattenrh   r  r<   r  )r4   r  r  r  num_hammer_onnum_pull_off	hammer_on	hammer_n0	hammer_n1pull_offpull_n0pull_n1s               r   testHammerOnPullOffzTest.testHammerOnPullOff  sl   %2OOM667AIIK:::FG199;99)DE*q)IIK22:>qA	00215	00215	224Q7C224Q7C99;11)<Q?--/2--/200215x@00215x@r   N)#r   r   r   r  r  r  r  r  r  r  r   r&  r,  r0  rE  rM  rY  r`  rk  rm  rt  rx  rz  r~  r  r  r  r  r  r  r  r  r  r  r  r   r   r   r  r  "	  s    +(%16fR">
<3|&44<:Ax&%-P*RZbRH=3~44l6""1L3(:6=43T
'-.;*"$"."2"2&2)$Ar   r  z
list[type]
_DOC_ORDER__main__)2r   
__future__r   collections.abcr   r   r"  dataclassesr   typingrG   unittestr)   r   r   music21.common.numberToolsr	   music21.common.typesr
   r   r   r   r   r   r   r   r   EnvironmentenvironLocalMusic21Exceptionr   r   r-   r!   r   r   ProtoM21Objectr   r  r  r*  rL  r  r  TestCaser  r  r   r   mainTestr   r   r   <module>r     su   # .  !     - )       ??&{&&y1	|44 		\:: 	
qd   qj $( ( (8,D&& 8,vg
G** g
V
7 
&B,w B,P~-G ~-Ht6W t6p`7 `FG( G(X~A8 ~AF "
J " zGT r   