§
    „Øjý  ã                  óø   — d dl m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	 ej
        rd dlmZ  ej        d	¦  «        Zej        ej        ej        fd
fdd„Zedk    rd dlZ ej        ¦   «          dS dS )é    )ÚannotationsN)Úclef)Úenvironment)Úkey)Úmeter)Ústream)ÚMusic21Objectzstream.toolsTÚ
thisStreamústream.StreamÚclassesToRemoveÚtupleÚinPlaceÚboolÚreturnc                ó   ‡— t           j        t          j        t          j        f}i }|s|                      d¦  «        } t          | t          j	        ¦  «        r4t          | j        ¦  «        dk    r| j        D ]}t          ||d¬¦  «         Œ|D ]¾Št          ˆfd„|D ¦   «         ¦  «        st          d|› d�¦  «        ‚|                      ¦   «                              ‰¦  «        }t          |¦  «        dk     rŒk|d         }|d	d
…         D ]@}||k    r6|j        |v r!||j                                      |¦  «         Œ2|g||j        <   Œ>|}ŒAŒ¿|                     ¦   «         D ]\  }	}
|	                     |
d¬¦  «         Œ| S )aÃ  
    The repetition of some classes like notes is common.
    By contrast, the explicit repetition of certain other objects like clefs
    usually indicates an error e.g., resulting from a copy'n'paste.
    This function serves to remove those that are likely in error and make no change.

    Use the `classesToRemove` argument to specify which music21 classes to check and remove.
    The classes currently supported are: time signatures, key signatures, and clefs.
    The `classesToRemove` argument defaults all three.
    Sometimes there are legitimate reasons to duplicate even these classes.
    In that case, override the default by specifying the list of which of the three of classes.
    More classes may be added, but for now they will simply raise a ValueError.

    So let's create an example part with an initial set of
    time signature, key signature, and clef.

    >>> p = stream.Part()
    >>> p.append(meter.TimeSignature('3/4'))  # first TS
    >>> p.append(key.KeySignature(6))  # first KS
    >>> p.append(clef.TrebleClef())  # first Clef

    Then a few notes, followed by a duplicates of the
    key signature, and clef.

    >>> p.append(note.Note('C'))
    >>> p.append(note.Note('C'))
    >>> p.append(note.Note('D'))

    >>> p.append(meter.TimeSignature('3/4'))  # duplicate
    >>> p.append(key.KeySignature(6))  # duplicate
    >>> p.append(clef.TrebleClef())  # duplicate

    Finally, a few more notes, followed by a
    change of time signature, key signature, and clef.

    >>> p.append(note.Note('E'))
    >>> p.append(note.Note('F'))
    >>> p.append(note.Note('G'))

    >>> p.append(meter.TimeSignature('2/4'))
    >>> p.append(key.KeySignature(-5))
    >>> p.append(clef.BassClef())

    >>> p.append(note.Note('A'))
    >>> p.append(note.Note('B'))
    >>> p.append(note.Note('C5'))

    Now we'll make it into a proper part with measures and see
    how it looks in its original, unaltered form:

    >>> p.makeMeasures(inPlace=True)
    >>> p.show('t')
    {0.0} <music21.stream.Measure 1 offset=0.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.key.KeySignature of 6 sharps>
        {0.0} <music21.meter.TimeSignature 3/4>
        {0.0} <music21.note.Note C>
        {1.0} <music21.note.Note C>
        {2.0} <music21.note.Note D>
    {3.0} <music21.stream.Measure 2 offset=3.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.key.KeySignature of 6 sharps>
        {0.0} <music21.meter.TimeSignature 3/4>
        {0.0} <music21.note.Note E>
        {1.0} <music21.note.Note F>
        {2.0} <music21.note.Note G>
    {6.0} <music21.stream.Measure 3 offset=6.0>
        {0.0} <music21.clef.BassClef>
        {0.0} <music21.key.KeySignature of 5 flats>
        {0.0} <music21.meter.TimeSignature 2/4>
        {0.0} <music21.note.Note A>
        {1.0} <music21.note.Note B>
    {8.0} <music21.stream.Measure 4 offset=8.0>
        {0.0} <music21.note.Note C>
        {1.0} <music21.bar.Barline type=final>

    Calling removeDuplicates should remove the duplicates
    even with those changes now stored within measures,
    not directly on the part.
    Specifically, in our example,
    the duplicates entries are removed from measure 2
    and the actual changes in measure 3 remain.

    >>> testInPlace = stream.tools.removeDuplicates(p)
    >>> testInPlace.show('t')
    {0.0} <music21.stream.Measure 1 offset=0.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.key.KeySignature of 6 sharps>
        {0.0} <music21.meter.TimeSignature 3/4>
        {0.0} <music21.note.Note C>
        {1.0} <music21.note.Note C>
        {2.0} <music21.note.Note D>
    {3.0} <music21.stream.Measure 2 offset=3.0>
        {0.0} <music21.note.Note E>
        {1.0} <music21.note.Note F>
        {2.0} <music21.note.Note G>
    {6.0} <music21.stream.Measure 3 offset=6.0>
        {0.0} <music21.clef.BassClef>
        {0.0} <music21.key.KeySignature of 5 flats>
        {0.0} <music21.meter.TimeSignature 2/4>
        {0.0} <music21.note.Note A>
        {1.0} <music21.note.Note B>
    {8.0} <music21.stream.Measure 4 offset=8.0>
        {0.0} <music21.note.Note C>
        {1.0} <music21.bar.Barline type=final>

    As the example shows, this function defaults to working on a stream inPlace.

    >>> testInPlace == p
    True

    To avoid this, set inPlace to False.

    >>> testNotInPlace = stream.tools.removeDuplicates(p, inPlace=False)
    >>> testNotInPlace == p
    False

    This function is primarily designed and intended for use on a stream.Part object.
    If called on a steam.Score, it will simply be applied to each of that score's parts in turn.

    >>> s = stream.Score()
    >>> s.append(p)
    >>> t = stream.tools.removeDuplicates(s, inPlace=False)
    >>> s.parts[0] == testInPlace
    True

    ÚremoveDuplicatesr   T)r   r   c              3  ó8   •K  — | ]}t          ‰|¦  «        V — Œd S )N)Ú
issubclass)Ú.0ÚsupportedClassÚ	thisClasss     €ú‰/Users/tedpeters/Documents/Projects/Claude Projects/Misc Tools/notename-sheets/.venv/lib/python3.11/site-packages/music21/stream/tools.pyú	<genexpr>z#removeDuplicates.<locals>.<genexpr>®   s-   øè è € Ð`Ð`¸^•:˜i¨Ñ8Ô8Ð`Ð`Ð`Ð`Ð`Ð`ó    zInvalid class. Only z are supported.é   é   N)Úrecurse)r   ÚTimeSignaturer   ÚKeySignaturer   ÚClefÚcoreCopyAsDerivationÚ
isinstancer   ÚScoreÚlenÚpartsr   ÚanyÚ
ValueErrorr   ÚgetElementsByClassÚ
activeSiteÚappendÚitemsÚremove)r
   r   r   ÚsupportedClassesÚremovalDictÚpÚ	allStatesÚcurrentStateÚ	thisStateÚactiveSiteKeyÚvaluesToRemover   s              @r   r   r      sÒ  ø€ õH Ô+­SÔ-=½t¼yÐIÐà<>€Kàð IØ×4Ò4Ð5GÑHÔHˆ
å�*�fœlÑ+Ô+ð SÝˆzÔÑ Ô  1Ò$Ð$ØÔ%ð Sð S�Ý  °OÈTÐRÑRÔRÐRÐRà$ð )ð )ˆ	åÐ`Ð`Ð`Ð`ÐO_Ð`Ñ`Ô`Ñ`Ô`ð 	WÝÐUÐ4DÐUÐUÐUÑVÔVÐVà×&Ò&Ñ(Ô(×;Ò;¸IÑFÔFˆ	åˆy‰>Œ>˜AÒÐØà  ”|ˆØ" 1 2 2œð 	)ð 	)ˆIØ˜LÒ(Ð(ØÔ'¨;Ð6Ð6Ø 	Ô 4Ô5×<Ò<¸YÑGÔGÐGÐGà9B¸�K 	Ô 4Ñ5Ð5à(��ð	)ð *5×):Ò):Ñ)<Ô)<ð ;ð ;Ñ%ˆ�~Ø×Ò˜^°TÐÑ:Ô:Ð:Ð:àÐr   Ú__main__)r
   r   r   r   r   r   r   r   )Ú
__future__r   ÚtypingÚtÚmusic21r   r   r   r   r   ÚTYPE_CHECKINGÚmusic21.baser	   ÚEnvironmentÚenvironLocalr   r   r    r   Ú__name__ÚmainTest© r   r   ú<module>rA      s  ðð #Ð "Ð "Ð "Ð "Ð "Ø Ð Ð Ð à Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð à„?ð +Ø*Ð*Ð*Ð*Ð*Ð*à&ˆ{Ô& ~Ñ6Ô6€ð 05Ô/BÀCÔDTÐVZÔV_Ð.`Ø%)ðgð gð gð gð gðX ˆzÒÐØ€N€N€NØ€GÔÑÔÐÐÐð Ðr   