
    z	i                       S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSK	J
r
JrJrJr  SSK	JrJrJr  SSK	JrJrJrJrJrJr  SS	KJr  SS
KJr  SSKJrJrJrJrJ r   SSK!J"r"J#r#  SSK$J%r%  SSK&J'r'  SSK(J)r)  SSK*J+r+  SSK,J-r-J.r.J/r/J0r0J1r1J2r2J3r3J4r4  SSK5J6r6  Sr7Sr8Sr9 " S S\65      r: " S S5      r; " S S\;5      r< " S S\;5      r= " S S\;5      r> " S S \=5      r? " S! S"\;5      r@ " S# S$\@\=5      rA " S% S&\@5      rB " S' S(\B\=5      rC " S) S*\@\=5      rD " S+ S,\;5      rE " S- S.\@\=5      rF " S/ S0\@\=5      rG " S1 S2\@\=5      rH " S3 S4\@\<5      rI " S5 S6\B\<5      rJ " S7 S8\@\<5      rK " S9 S:\;5      rL " S; S<\L5      rM " S= S>\L5      rN " S? S@\L5      rO " SA SB\L5      rP " SC SD\L5      rQ " SE SF\;5      rR " SG SH\R5      rS " SI SJ\R5      rT " SK SL\;5      rU " SM SN\;5      rV " SO SP\;5      rW " SQ SR5      rX " SS ST5      rYg)UzN
A module for drawing circuits in ascii art or some other text representation
    )StringIO)warn)get_terminal_sizeN)QubitClbitClassicalRegisterCircuitError)ControlledGateResetMeasure)ControlFlowOpWhileLoopOpIfElseOp	ForLoopOpSwitchCaseOpBoxOp)expr)node_resources)IGateRZZGateSwapGateSXGateSXdgGate)_canonicalize_modifiersControlModifier)pi_check)ast)BasicPrinter)_ExprBuilder   )get_gate_ctrl_textget_param_strget_wire_mapget_bit_registerget_bit_reg_indexget_wire_labelget_condition_label_val_get_layered_instructions   )VisualizationErrorc                       \ rS rSrSrSrg)TextDrawerEncodingError5   zA problem with encoding N)__name__
__module____qualname____firstlineno____doc____static_attributes__r.       [/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/visualization/circuit/text.pyr,   r,   5   s    !r5   r,   c                       \ rS rSrSrSS jr\S 5       r\S 5       r\S 5       r	\S 5       r
\S	 5       r\R                  S
 5       rSS jrSrg)DrawElement;   z2An element is an operation that needs to be drawn.Nc                    S U l         U=U l        U l        S=U l        =U l        U l        S=U l        U l        S=U l        =U l	        U l
        S=U l        =U l        U l        0 U l        0 U l        S=U l        =U l        U l        SU l        g )N%s r    )_widthlabelmid_content
top_format
mid_format
bot_formattop_connectbot_connecttop_pad_mid_paddingbot_padmid_bcktop_bckbot_bckbot_connectortop_connector
right_fill	left_filllayer_width
wire_label)selfr?   s     r6   __init__DrawElement.__init__>   s    (--
T%>BBB$/DO.114+:===t(4<5888t|dl>???$.4+;r5   c                    U R                   S-  S:X  a  [        U R                  5      S-  S:X  ad  [        U R                  5      S:X  aK  U R                  U R                  U R                  -   R                  U R                   U R                  5      -  nO=U R                  U R                  R                  U R                   U R                  5      -  nU R                  (       a&  UR                  U R                  U R                  5      nU R                  (       a&  UR                  U R                  U R                  5      nUR                  U R                  U R                  5      nU$ )z&Constructs the top line of the elementr)   r   r    )widthlenrA   rD   rF   centerrN   ljustrO   rjustrP   rJ   rR   rets     r6   topDrawElement.topJ   s     JJNq S%9A%=%Bs4K[K[G\`aGa//T\\D4D4D%D$L$L

DLL% C //D$4$4$;$;DJJ$UUC??))DOOT\\:C>>))DNNDLL9Cjj))4<<8
r5   c                    U R                   U R                  R                  U R                  U R                  5      -  nU R
                  (       a&  UR                  U R
                  U R                  5      nU R                  (       a&  UR                  U R                  U R                  5      nUR                  U R                  U R                  5      nU$ )z)Constructs the middle line of the element)rB   r@   rX   rV   rG   rN   rY   rO   rZ   rP   rI   r[   s     r6   midDrawElement.midZ   s     oo 0 0 7 7

DDUDU VV??))DOOT->->?C>>))DNND,=,=>Cjj))4<<8
r5   c                    U R                   S-  S:X  ag  [        U R                  5      S-  S:X  aK  U R                  U R                  U R
                  -   R                  U R                   U R                  5      -  nO=U R                  U R
                  R                  U R                   U R                  5      -  nU R                  (       a&  UR                  U R                  U R                  5      nU R                  (       a&  UR                  U R                  U R                  5      nUR                  U R                  U R                  5      nU$ )z)Constructs the bottom line of the elementr)   r   r    )rV   rW   rA   rC   rH   rE   rX   rN   rY   rO   rZ   rP   rK   r[   s     r6   botDrawElement.bote   s     JJNq S%9A%=%B//T\\D4D4D%D$L$L

DLL% C //D$4$4$;$;DJJ$UUC??))DOOT\\:C>>))DNNDLL9Cjj))4<<8
r5   c                     [        [        U R                  5      [        U R                  5      [        U R                  5      5      $ )z<Returns the length of the element, including the box around.)maxrW   r]   r`   rc   rR   s    r6   lengthDrawElement.lengthu   s+     3txx=#dhh-TXX??r5   c                 f    U R                   (       a  U R                   $ [        U R                  5      $ z1Returns the width of the label, including padding)r>   rW   r@   rg   s    r6   rV   DrawElement.widthz   s&     ;;;;4##$$r5   c                     Xl         g N)r>   )rR   values     r6   rV   rl      s    r5   c                     SU;   a%  U R                   (       a  U R                   U   U l        SU;   a%  U R                  (       a  U R                  U   U l        U(       a!  U R                  SS U(       a  UOS-   U l        gg)u  Connects boxes and elements using wire_char and setting proper connectors.

Args:
    wire_char (char): For example '║' or '│'.
    where (list["top", "bot"]): Where the connector should be set.
    label (string): Some connectors have a label (see cu1, for example).
r]   rc   Nr=   )rM   rD   rL   rE   rA   )rR   	wire_charwherer?   s       r6   connectDrawElement.connect   sk     E>d00#11)<DE>d00#11)<D"oocr2ue"MDO r5   )rG   r>   rK   rE   rL   rC   rH   r?   rP   rO   rI   r@   rB   rN   rJ   rD   rM   rA   rF   rQ   rn   )r/   r0   r1   r2   r3   rS   propertyr]   r`   rc   rh   rV   setterrt   r4   r.   r5   r6   r8   r8   ;   s    <
       @ @ % % \\ Nr5   r8   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )BoxOnClWire   u   Draws a box on the classical wire.

::

    top: ┌───┐   ┌───┐
    mid: ╡ A ╞ ══╡ A ╞══
    bot: └───┘   └───┘
c                    > [         TU ]  U5        SU l        SU l        SU l        S=U l        U l        SU l        X l        X0l	        Xl
        g )N   ┌─%s─┐u
   ╡ %s ╞   └─%s─┘   ─   ═)superrS   rA   rB   rC   rF   rH   rI   rD   rE   r@   )rR   r?   rD   rE   	__class__s       r6   rS   BoxOnClWire.__init__   sL    *&*&++t|&& r5   )	rE   rC   rH   rI   r@   rB   rD   rA   rF   )r=   r~   r~   r/   r0   r1   r2   r3   rS   r4   __classcell__r   s   @r6   ry   ry      s    	! 	!r5   ry   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )BoxOnQuWire   u   Draws a box on the quantum wire.

::

    top: ┌───┐   ┌───┐
    mid: ┤ A ├ ──┤ A ├──
    bot: └───┘   └───┘
c                    > [         TU ]  U5        SU l        SU l        SU l        S=U l        =U l        U l        X l        U(       a  SOSU l	        Xl
        SS0U l        SS0U l        g )	Nr|   u
   ┤ %s ├r}   r~      ╥   │   ┴   ┬)r   rS   rA   rB   rC   rF   rH   rI   rD   rE   r@   rM   rL   )rR   r?   rD   conditionalr   s       r6   rS   BoxOnQuWire.__init__   sj    *&*5:::t|dl&$/5U #U^#U^r5   rE   rL   rC   rH   rI   r@   rB   rD   rM   rA   rF   r=   r~   Fr   r   s   @r6   r   r      s    
, 
,r5   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )	MeasureTo   u   The element on the classic wire to which the measure is performed.

::

    top:  ║     ║
    mid: ═╩═ ═══╩═══
    bot:
c                 X   > [         TU ]  5         SU l        SU l        Xl        SU l        g )Nu    ║ u	   ═╩═r   )r   rS   rD   r@   rE   rI   rR   r?   r   s     r6   rS   MeasureTo.__init__   s+    "& r5   )rE   rI   r@   rD   r=   r   r   s   @r6   r   r      s     r5   r   c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )MeasureFrom   u   The element on the quantum wire in which the measure is performed.

::

    top: ┌─┐    ┌─┐
    mid: ┤M├ ───┤M├───
    bot: └╥┘    └╥┘
c                    > [         TU ]  5         S=U l        =U l        U l        SU l        SU l        SU l        S=U l        U l	        SU l
        g )Nr;   u	   ┌─┐u   ┤M├u	   └╥┘r<   r~   )r   rS   rA   rB   rC   rD   r@   rE   rF   rH   rG   )rR   r   s    r6   rS   MeasureFrom.__init__   sQ    >BBB$/DO&$&&))t|!r5   )	rG   rE   rC   rH   r@   rB   rD   rA   rF   r   r   s   @r6   r   r      s    " "r5   r   c                   .    \ rS rSrSrS r\S 5       rSrg)MultiBox   z,Elements that are drawn over multiple wires.c                 V   Xs=:X  a  S:X  a  O  OU R                   U l        gSR                  US-  S-
  5      R                  S5      S-   nUS-  S-   nUS-   nXCs=::  a  U:  aF  O  gX4:X  a  U R                   U l        gX4S-   :X  a  U R                   U l        gU R                   U l        gg)zIn multi-bit elements, the label is centered vertically.

Args:
    input_length (int): Rhe amount of wires affected.
    order (int): Which middle element is this one?
r   N*r)   r    )r?   rD   rX   indexr@   rE   )rR   input_lengthorderlocation_in_the_box	top_limit	bot_limits         r6   center_labelMultiBox.center_label   s     %A%#zzD!jj)9A)=>DDSIAMAIM	M	7i7"/#':: $A5#':: #'::  8r5   c                 f    U R                   (       a  U R                   $ [        U R                  5      $ rk   )r>   rW   r?   rg   s    r6   rV   MultiBox.width  s#     ;;;;4::r5   )rE   r@   rD   N)	r/   r0   r1   r2   r3   r   rv   rV   r4   r.   r5   r6   r   r      s    6.*  r5   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )BoxOnQuWireTopi  zCDraws the top part of a box that affects more than one quantum wirec                   > [         TU ]  U5        X0l        S=U l        U l        SU l        [        U R                  5      U l        SSR                  U R                  S-   S5      -   S-   U l	        U R                  R                  SS5      U l	        S	U R                   S
3U l        SU R                  U R                  -   S3U l        U(       a  X l        g SU l        g )Nr<   r=      ┌─sr    r~      ─┐r;      ┤    %s ├r       %s │)r   rS   rQ   rE   rH   r@   rW   rO   rX   rA   replacerB   rC   rD   rR   r?   rD   rQ   r   s       r6   rS   BoxOnQuWireTop.__init__  s    $*--4<T__-"SZZ0BE%JJXU//11#t<08t~~ =>gF*5;5r5   	rE   rC   rH   rO   r@   rB   rD   rA   rQ   r=   Nr=   r   r   s   @r6   r   r     s    M
A 
Ar5   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )BoxOnWireMidi  zA generic middle boxc                 p  > [         TU ]  U5        S=U l        =U l        =U l        U l        X@l        [        U R                  5      U l        SU R                  U R                  -   S3U l	        SU R                  U R                  -   S3U l
        S=U l        =U l        U l        U R                  X#5        g )Nr<   r   r   r=   )r   rS   rF   rH   rD   rE   rQ   rW   rO   rA   rC   r@   r   )rR   r?   r   r   rQ   r   s        r6   rS   BoxOnWireMid.__init__  s    LOOOt|Od&69I$T__-t~~ =>gFt~~ =>gFACCC4+d.>,.r5   )	rE   rC   rH   rO   r@   rD   rA   rF   rQ   r   r   r   s   @r6   r   r     s    / /r5   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )BoxOnQuWireMidi*  zFDraws the middle part of a box that affects more than one quantum wirec                    > [         TU ]  XX4S9  U(       a  U U R                   S3U l        g SU R                   S3U l        g )NrQ   r   r   r   rS   rQ   rB   )rR   r?   r   r   rQ   control_labelr   s         r6   rS   BoxOnQuWireMid.__init__-  sD    eK!./@HDO #DOO#4G<DOr5   rB   )r=   Nr   r   s   @r6   r   r   *  s    P= =r5   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )BoxOnQuWireBoti5  zFDraws the bottom part of a box that affects more than one quantum wirec                   > [         TU ]  U5        X@l        SU l        [	        U R                  5      U l        SU R                  U R
                  -   S3U l        SU R                   S3U l        SSR                  U R
                  S-   S	5      -   S
-   U l	        U R                  R                  SS5      U l	        U(       a  UOS	nU(       a  SOUU l        S=U l        U l        US::  a  Xl        g g )Nr<   r   r   r   r      └─r   r    r~      ─┘r;   r   r=   r)   )r   rS   rQ   rF   rW   rO   rA   rB   rX   rC   r   rE   r@   rD   )rR   r?   r   rE   rQ   r   r   s         r6   rS   BoxOnQuWireBot.__init__8  s    $T__-t~~ =>gF08"SZZ0BE%JJXU//11#t<%0ke$/5[.004+1$ r5   	rE   rC   rO   r@   rB   rD   rA   rF   rQ   Nr=   Fr   r   s   @r6   r   r   5  s    P% %r5   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )FlowOnQuWireiI  z5Draws a box for a ControlFlowOp using a single qubit.c                   > [         TU ]  U5        U[        :X  a  SU l        SU l        SU l        OSU l        SU l        SU l        S=U l        =U l        U l        X0l	        U(       a  SOSU l
        X l        S	S
0U l        S	S0U l        g )Nu    ─%s─┐u     %s ├u    ─%s─┘u   ┌─%s─ u   ┤ %s  u   └─%s─ r~   r   r   r   r   )r   rS   CF_RIGHTrA   rB   rC   rF   rH   rI   rD   rE   r@   rM   rL   )rR   sectionr?   rD   r   r   s        r6   rS   FlowOnQuWire.__init__L  s    h,DO(DO,DO,DO(DO,DO5:::t|dl&$/5U #U^#U^r5   r   r   r   r   s   @r6   r   r   I  s    ?, ,r5   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )FlowOnQuWireTopi^  zIDraws the top of a box for a ControlFlowOp that uses more than one qubit.c                   > [         TU ]  U5        X@l        S=U l        U l        SU l        [        U R                  5      U l        U[        :X  a  SR                  U R                  S-   S5      S-   U l
        U R                  R                  SS5      U l
        SU R                   S3U l        SU R                  U R                  -   S	3U l        OS
SR                  U R                  S-   S5      -   S-   U l
        U R                  R                  SS5      U l
        SU R                   S3U l        SU R                  U R                  -   S3U l        U(       a  X0l        g SU l        g )Nr<   r=   r   r)   r~   r   r;   r   r   r   r    %s  r   )r   rS   rQ   rE   rH   r@   rW   rO   r   rX   rA   r   rB   rC   rD   )rR   r   r?   rD   rQ   r   s        r6   rS   FlowOnQuWireTop.__init__a  s/   $*--4<T__-h!jj!);UChNDO"oo55c4@DO !$//!2':DO !$,,"?!@HDO&DNNQ4F)NNQTTDO"oo55c4@DO #DOO#4E:DO #DLL4>>$A#B%HDO*5;5r5   r   r   r   r   s   @r6   r   r   ^  s    SA Ar5   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )FlowOnQuWireMidit  zLDraws the middle of a box for a ControlFlowOp that uses more than one qubit.c                 b  > [         TU ]  U5        S=U l        =U l        =U l        U l        XPl        [        U R                  5      U l        U[        :X  aZ  SU R                  U R                  -   S3U l
        SU R                  U R                  -   S3U l        SU R                   S3U l        OYSU R                  U R                  -   S3U l
        SU R                  U R                  -   S3U l        SU R                   S3U l        S=U l        =U l        U l        U R                  X45        g )Nr<   r   r   r   r   r   r=   )r   rS   rF   rH   rD   rE   rQ   rW   rO   r   rA   rC   rB   r@   r   )rR   r   r?   r   r   rQ   r   s         r6   rS   FlowOnQuWireMid.__init__w  s   LOOOt|Od&69I$T__-h !$,,"?!@HDO !$,,"?!@HDO !$//!2':DO #DLL4>>$A#B%HDO #DLL4>>$A#B%HDO #DOO#4E:DOACCC4+d.>,.r5   
rE   rC   rH   rO   r@   rB   rD   rA   rF   rQ   r   r   r   s   @r6   r   r   t  s    V/ /r5   r   c                   6   ^  \ rS rSrSr   SU 4S jjrSrU =r$ )FlowOnQuWireBoti  zLDraws the bottom of a box for a ControlFlowOp that uses more than one qubit.c                   > [         TU ]  U5        XPl        SU l        [	        U R                  5      U l        U[        :X  a  SU R                  U R
                  -   S3U l        SU R                   S3U l        SSR                  U R
                  S-   S5      -   S-   U l
        U R                  R                  SS5      U l
        OS	U R                  U R
                  -   S
3U l        SU R                   S
3U l        SSR                  U R
                  S-   S5      -   S-   U l
        U R                  R                  SS5      U l
        U(       a  UOSnU(       a  SOUU l        S=U l        U l        US::  a  X l        g g )Nr<   r   r   r   r)   r~   r   r;   r   r   r   r   r   r=   )r   rS   rQ   rF   rW   rO   r   rA   rB   rX   rC   r   rE   r@   rD   )rR   r   r?   r   rE   rQ   r   r   s          r6   rS   FlowOnQuWireBot.__init__  sO    	$T__-h !$,,"?!@HDO !$//!2':DO!CJJt~~/A5$IIHTDO"oo55c4@DO #DLL4>>$A#B%HDO #DOO#4E:DO&DNNQ4F)NNQTTDO"oo55c4@DO%0ke$/5[.004+1$ r5   r   r   r   r   s   @r6   r   r     s    V % %r5   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )BoxOnClWireTopi  zQDraws the top part of a conditional box that affects more than one classical wirec                    > [         TU ]  U5        X0l        SU l        SU l        U(       a  UOSU l        S=U l        U l        g )Nr=   u
   │ %s │r~   r<   )r   rS   rQ   r@   rC   rD   rE   rH   r   s       r6   rS   BoxOnClWireTop.__init__  s?    $&*5;5*--4<r5   )rE   rC   rH   r@   rD   rQ   r   r   r   s   @r6   r   r     s    [. .r5   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )BoxOnClWireMidi  zTDraws the middle part of a conditional box that affects more than one classical wirec                 L   > [         TU ]  XX4S9  SU R                   S3U l        g )Nr      ╡    %s ╞r   )rR   r?   r   r   rQ   _r   s         r6   rS   BoxOnClWireMid.__init__  s*    eK08r5   r   r   r   r   s   @r6   r   r     s    ^9 9r5   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )BoxOnClWireBoti  zTDraws the bottom part of a conditional box that affects more than one classical wirec                   > [         TU ]  U5        X@l        [        U R                  5      U l        SU l        SU l        SU R
                  U R                  -   S3U l        SU R                   S3U l        SSR                  U R                  S	-   S5      -   S
-   U l
        U R                  R                  SS5      U l
        U(       a  UOSnX0l        S=U l        U l        US::  a  Xl        g g )Nr<   r~   r   r   r   r   r   r   r    r   r;   r=   r)   )r   rS   rQ   rW   rO   rF   rH   rA   rB   rX   rC   r   rE   r@   rD   )rR   r?   r   rE   rQ   r   r   s         r6   rS   BoxOnClWireBot.__init__  s    $T__-t~~ =>gF08"SZZ0BE%JJXU//11#t<%0ke&.004+1$ r5   r   )r~   r=   r   r   s   @r6   r   r     s    ^% %r5   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )DirectOnQuWirei  z(
Element to the wire (without the box).
c                    > [         TU ]  U5        SU l        SU l        SU l        S=U l        U l        SSS.U l        SSS.U l        g )N %s u   ─%s─r~   r      ║r   r   	r   rS   rA   rB   rC   rG   rI   rM   rL   r   s     r6   rS   DirectOnQuWire.__init__  N     $ +00DL%*59%*59r5   rG   rL   rC   rI   rB   rM   rA   r   r   r   s   @r6   r   r         : :r5   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )Barrieri  u   Draws a barrier with a label at the top if there is one.

::

    top:  ░   label
    mid: ─░─ ───░───
    bot:  ░     ░
c                 n   > [         TU ]  S5        U(       a  UOSU l        SU l        0 U l        0 U l        g )Nu   ░)r   rS   rD   rE   rM   rL   r   s     r6   rS   Barrier.__init__  s4    $)5u r5   )rE   rL   rD   rM   r   r   r   s   @r6   r   r     s       r5   r   c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )Exi  u   Draws an X (usually with a connector). E.g. the top part of a swap gate.

::

    top:
    mid: ─X─ ───X───
    bot:  │     │
c                 P   > [         TU ]  S5        U(       a  SOUU l        X l        g )NXr   )r   rS   rE   rD   )rR   rE   rD   r   r   s       r6   rS   Ex.__init__  s"    $/5[&r5   )rE   rD   )r<   r<   Fr   r   s   @r6   r  r    s    ' 'r5   r  c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )ResetDisplayi  zDraws a reset gatec                 B   > [         TU ]  S5        U(       a  SU l        g g )N|0>r   )r   rS   rE   )rR   r   r   s     r6   rS   ResetDisplay.__init__  s     $D r5   )rE   Fr   r   s   @r6   r  r    s    % %r5   r  c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )Bulleti  u   Draws a bullet (usually with a connector). E.g. the top part of a CX gate.

::

    top:
    mid: ─■─  ───■───
    bot:  │      │
c                    > [         TU ]  S5        X0l        Xl        U(       a  SOUU l        U(       a  U(       a  X@l        OU(       a  X@l        SU l        g )N   ■r   r~   r   rS   r   rD   rE   rI   rR   rD   rE   r   r?   bottomr   s         r6   rS   Bullet.__init__  sC    &&$/5[V$$r5   rE   r   rI   rD   r=   r=   FNFr   r   s   @r6   r  r        	 	r5   r  c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )
OpenBulleti#  u   Draws an open bullet (usually with a connector). E.g. the top part of a CX gate.

::

    top:
    mid: ─o─  ───o───
    bot:  │      │
c                    > [         TU ]  S5        X0l        Xl        U(       a  SOUU l        U(       a  U(       a  X@l        OU(       a  X@l        SU l        g )Nor   r~   r  r  s         r6   rS   OpenBullet.__init__-  sC    &&$/5[V$$r5   r  r  r   r   s   @r6   r  r  #  r  r5   r  c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )DirectOnClWirei9  z2
Element to the classical wire (without the box).
c                    > [         TU ]  U5        SU l        SU l        SU l        S=U l        U l        SSS.U l        SSS.U l        g )Nr   u   ═%s═r   r   r   r   r   r   s     r6   rS   DirectOnClWire.__init__>  r   r5   r   r   r   r   s   @r6   r  r  9  r   r5   r  c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )ClBulletiH  u   Draws a bullet on classical wire (usually with a connector). E.g. the top part of a CX gate.

::

    top:
    mid: ═■═  ═══■═══
    bot:  │      │
c                    > [         TU ]  S5        Xl        U(       a  SOUU l        U(       a  U(       a  X@l        OU(       a  X@l        SU l        g )Nr  r   r   r   rS   rD   rE   rI   r  s         r6   rS   ClBullet.__init__R  s=    &$/5[V$$r5   rE   rI   rD   r  r   r   s   @r6   r!  r!  H       r5   r!  c                   0   ^  \ rS rSrSrSU 4S jjrSrU =r$ )ClOpenBulleti]  u   Draws an open bullet on classical wire (usually with a connector). E.g. the top part of a CX gate.

::

    top:
    mid: ═o═  ═══o═══
    bot:  │      │
c                    > [         TU ]  S5        Xl        U(       a  SOUU l        U(       a  U(       a  X@l        OU(       a  X@l        SU l        g )Nr  r   r   r#  r  s         r6   rS   ClOpenBullet.__init__g  s=    &$/5[V$$r5   r%  r  r   r   s   @r6   r(  r(  ]  r&  r5   r(  c                   <   ^  \ rS rSrSrU 4S jr\S 5       rSrU =r	$ )	EmptyWireir  z2This element is just the wire, with no operations.c                 @   > [         TU ]  U5        U=U l        U l        g rn   )r   rS   rG   rI   )rR   wirer   s     r6   rS   EmptyWire.__init__u  s    +//DLr5   c                     [        U 5       VVs/ s H  u  p#Ub  M
  UPM     snn H   nXA:  a  [        S5      O
[        S5      X'   M"     U $ s  snnf )zGiven a layer, replace the Nones in it with EmptyWire elements.

Args:
    layer (list): The layer that contains Nones.
    first_clbit (int): The first wire that is classic.

Returns:
    list: The new layer, with no Nones.
r   r~   )	enumerater,  )layerfirst_clbitixnoness        r6   fillup_layerEmptyWire.fillup_layery  sM     %.e$4B$4DAa$4BE/4/C9U+SXIYEL C Cs
   	AA)rG   rI   
r/   r0   r1   r2   r3   rS   staticmethodr7  r4   r   r   s   @r6   r,  r,  r  s    <0  r5   r,  c                   <   ^  \ rS rSrSrU 4S jr\S 5       rSrU =r	$ )	BreakWirei  z;This element is used to break the drawing in several pages.c                 p   > [         TU ]  5         S=U l        =U l        U l        Xl        Xl        Xl        g )Nr;   )r   rS   rA   rB   rC   rD   r@   rE   )rR   
arrow_charr   s     r6   rS   BreakWire.__init__  s5    >BBB$/DO%%%r5   c                 b    / n[        U 5       H  nUR                  [        U5      5        M     U$ )zCreates a layer with BreakWire elements.

Args:
    layer_length (int): The length of the layer to create
    arrow_char (char): The char used to create the BreakWire element.

Returns:
    list: The new layer.
)rangeappendr<  )layer_lengthr>  breakwire_layerr   s       r6   r7  BreakWire.fillup_layer  s1     |$A""9Z#89 %r5   )rE   rC   r@   rB   rD   rA   r9  r   s   @r6   r<  r<    s    E&  r5   r<  c                   <   ^  \ rS rSrSrU 4S jr\S 5       rSrU =r	$ )	InputWirei  z:This element is the label and the initial value of a wire.c                 $   > [         TU ]  U5        g rn   )r   rS   r   s     r6   rS   InputWire.__init__  s    r5   c                     [        S U  5       5      n/ nU  H,  nUR                  [        UR                  U5      5      5        M.     U$ )zCreates a layer with InputWire elements.

Args:
    names (list): List of names for the wires.

Returns:
    list: The new layer
c              3   8   #    U  H  n[        U5      v   M     g 7frn   )rW   ).0names     r6   	<genexpr>)InputWire.fillup_layer.<locals>.<genexpr>  s     2EDc$iiE   )rf   rB  rG  rZ   )nameslongestinputs_wiresrM  s       r6   r7  InputWire.fillup_layer  sE     2E22D	$**W*= >? r5   r.   r9  r   s   @r6   rG  rG    s    D   r5   rG  c                       \ rS rSrSr          SS jrS rS rS rS r	SS	 jr
SS
 jrSS jrS rS r\S 5       r\SS j5       r\S 5       r\S 5       rS rS rS rSS jrSrg)TextDrawingi  zThe text drawingNc                     Xl         X l        X0l        X@l        U(       aI  U R                  R                  (       a&  U R                  R                  R
                  U l        OS U l        OS U l        Xl        UR                  U l        X`l	        XPl
        Xpl        Xl        Xl        US;  a  [        S5      eXl        0 U l        Xl        U=(       d#    [$        R&                  R(                  =(       d    SU l        SU l        SU l        SU l        g )N)highmediumlowz;Vertical compression can only be 'high', 'medium', or 'low'utf8r   r=   )qubitsclbitsnodes_circuit_layoutinitial_layoutlayoutinitial_stateglobal_phaseplotbarriersreverse_bitsline_lengthexpr_lenmeasure_arrows
ValueErrorvertical_compression	_wire_map
cregbundlesysstdoutencoding_nest_depth
_expr_text_single_string)rR   r\  r]  r^  circuitrf  re  rg  rk  rc  rm  rp  with_layoutrh  ri  s                  r6   rS   TextDrawing.__init__  s    " 
}}$$"mm33BB"DK*#00((& ,'@@Z[[$8!$ ACJJ$7$7A6
 !r5   c                 "    U R                  5       $ rn   single_stringrg   s    r6   __str__TextDrawing.__str__      !!##r5   c                 *    SU R                  5        S3$ )Nz<pre style="word-wrap: normal;white-space: pre;background: #fff0;line-height: 1.1;font-family: &quot;Courier New&quot;,Courier,monospace">z</pre>rx  rg   s    r6   _repr_html_TextDrawing._repr_html_  s%    G
 !!#$F,	
r5   c                 "    U R                  5       $ rn   rx  rg   s    r6   __repr__TextDrawing.__repr__  r|  r5   c                 :   U R                   (       a  U R                   $  SR                  U R                  5       5      R                  U R                  5      R                  U R                  5      U l         U R                   $ ! [        [        4 a    [        SU R                   S3[        5        SU l        SR                  U R                  5       5      R                  U R                  5      R                  U R                  5      U l          U R                   $ f = f)zcCreates a long string with the ascii art.
Returns:
    str: The lines joined by a newline (``\n``)

zThe encoding zf has a limited charset. Consider a different encoding in your environment. UTF-8 is being used insteadzutf-8)
rs  joinlinesencoderp  decodeUnicodeEncodeErrorUnicodeDecodeErrorr   RuntimeWarningrg   s    r6   ry  TextDrawing.single_string  s     &&&			$**,'..t}}=DDT]]S  """ #$67 
	 /; ; 	 $DM		$**,'..t}}=DDT]]S  """
	s   AB BDDc                     [        USU=(       d    U R                  S9 nUR                  U R                  5       5        SSS5        g! , (       d  f       g= f)zDumps the ascii art in the file.

Args:
    filename (str): File to dump the ascii art.
    encoding (str): Optional. Force encoding, instead of self.encoding.
w)moderp  N)openrp  writery  )rR   filenamerp  	text_files       r6   dumpTextDrawing.dump  s=     (x/H4==IYOOD..01 JIIs    A
Ac           	         Uc  U R                   nU(       d7  S[        R                  ;   a  S[        R                  ;  a  SnO[        5       u  p[	        U R
                  5      nU R                  5       n/ /nUn[        U5       GHk  u  px[        R                  X5      XG'   [        R                  U5        US:X  a  US   R                  U5        MN  XG   S   R                  n	X:  a  US   R                  U5        Xi-  nM~  US   R                  [        R                  [	        U5      S5      5        UR                  [        R                  [	        U5      S5      /5        XS   S   S   R                  -
  nUS   R                  [        R                  U R!                  SS	95      5        XeS   S   S   R                  -  nUS   R                  U5        XeS   S   S   R                  -  nGMn     / n
U R"                  (       a&  U
R                  S
[%        U R"                  SS9 35        U H'  n['        [)        U6 5      nXR+                  U5      -  n
M)     U
$ )a  Generates a list with lines. These lines form the text drawing.

Args:
    line_length (int): Optional. Breaks the circuit drawing to this length. This is
                       useful when the drawing does not fit in the console. If
                       None (default), it will try to guess the console width using
                       shutil.get_terminal_size(). If you don't want pagination
                       at all, set line_length=-1.

Returns:
    list: A list of lines with the text drawing.
	ipykernelspyderP   rq   r      »   «Fwith_initial_statezglobal phase:    ndigits)rg  rn  modulesr   rW   r\  build_layersr1  r,  r7  rV  normalize_widthrB  rh   r<  rG  
wire_namesrd  r   listzip
draw_wires)rR   rg  r   noqubitslayerslayer_groupsrest_of_the_linelayernor2  rC  r  layer_groupwiress                r6   r  TextDrawing.lines&  s2    **Ks{{*1L !2!4t{{#""$t&'/NG'44UEFO''.b R ''. "?1-44L.R ''. 0 R ''	(>(>s5z4(PQ ##Y%;%;CJ%M$NO#.b1A"1Ea1H1O1O#O R ''**4??e?+TU !$4R$8$;$B$BB R ''. $4R$8$;$B$BB = 0@ LL>(43D3Da*P)QRS'Kk*+E__U++E ( r5   c           	         U(       a  SnSnOSnSn[        U R                  U R                  U R                  -   U R                  5      U l        / nU R
                  R                  5        H  u  pV[        U[        5      (       a  UnO [        U R                  U5      u  pxn	Uc  UOU	n[        SXvU R                  U R                  S9n
XR                  b  [        U[        5      (       a  SOS-  n
Sn[        U[        5      (       a  UnO.UnU R                  (       a  Ub  [        UR                  5      S-   nUR                  X-   U-   5        M     U$ )	zReturns a list of names for each wire.

Args:
    with_initial_state (bool): Optional (Default: False). If true, adds
        the initial value to the name.

Returns:
    List: The list of wire names.
r	  z0 r=   text)rb  rm  r<   z: /)r#   r_  r\  r]  rm  rl  items
isinstancer   r%   r&   rb  r   strsizerB  )rR   r  initial_qubit_valueinitial_clbit_valuewire_labelsr.  r   register	bit_index	reg_indexrQ   	cregb_addinitial_bit_values                r6   r  TextDrawing.wire_namesk  s2    "'"&"$"$%dmmdkkDKK6ORVRaRab>>//1KD$ 1221B4==RV1W.Y%-%5	9'J !8Ze=T=T#Z^^JI$&&$7!$7!??x'; #HMM 2S 8Iz=	IJ' 2* r5   c                     U R                   S:X  a  gU R                   S:X  a  g[        X5       HM  u  p4US;   a  US;   a    gUR                  5       (       a  US:w  d  UR                  5       (       d  ME  US:w  d  MM    g   g)z\Decides if the top_line and bot_line should be merged,
based on `self.vertical_compression`.rX  TrZ  F)r      ╨)r   r   r<   )rk  r  isalnum)rR   top_linebot_liner]   rc   s        r6   should_compressTextDrawing.should_compress  sr     $$.$$-H/HCn$)>#*#++--C3J	 0
 r5   c           	      b   / nSnU GH#  nSnU H  nXVR                   -  nM     Uc  UR                  U5        OqU R                  XS5      (       a4  UR                  [        R	                  UR                  5       U5      5        O'UR                  [        R	                  US   USS95        SnU H  nXvR                  -  nM     UR                  [        R	                  US   USS95        SnU H  nX6R                  -  nM     UR                  [        R	                  US   USS95        GM&     U$ )zGiven a list of wires, creates a list of lines with the text drawing.

Args:
    wires (list): A list of wires with nodes.
Returns:
    list: A list of lines with the text drawing.
Nr=   rq   rc   )icod)r]   rB  r  rV  merge_linespopr`   rc   )rR   r  r  r  r.  r  nodemid_lines           r6   r  TextDrawing.draw_wires  s    DHHH$  X&'';;LL!8!8h!OPLL!8!8rHSX!8!YZ HHH$ LL00rH50QR HHH$ LL00rH50QR1 4 r5   c                 h    [         S[        S[        S0n[        U SS5      nUR	                  US5      $ )z%Some instructions have special labelsIu   √Xu   √Xdg
base_classN)r   r   r   getattrget)r  labels	node_types      r6   special_labelTextDrawing.special_label  s5     ffhAD,5	zz)T**r5   c                    Sn[        X5       GH  u  pEXE:X  a  X4-  nM  US;   a  US:X  a  US-  nM$  US:X  a  X5-  nM0  US;   a  US;   a  US:X  a  X4-  nMH  US;   a  US:X  a  US	:X  a  US-  nMa  US
;   a  US:X  a  US	:X  a  US-  nMz  US;   a  US:X  a  US-  nM  US;   a  US:X  a  US-  nM  US;   a  US:X  a  US:X  a  X4-  nM  US;   a  US:X  a  US:X  a  X4-  nM  US;   a  US:X  a  US	:X  a  X5-  nM  US;   a  US;   a  US-  nM  US;   a  US;   a  US-  nGM  US;   a  US;   a  US-  nGM#  US;   a  US;   a  US-  nGM7  US:X  a  US:X  a  US:X  a  US-  nGMQ  US:X  a  US:X  a  US:X  a  US-  nGMk  US;   a  US:X  a  US-  nGM  US;   a  US;   a  US:X  a  US -  nGM  US:X  a  US:X  a  X4-  nGM  X5-  nGM     U$ )!a  Merges two lines (top and bot) in a way that the overlapping makes sense.

Args:
    top (str): the top line
    bot (str): the bottom line
    icod (top or bot): in case of doubt, which line should have priority? Default: "top".
Returns:
    str: The merge of both lines.
r=   u   ┼╪r<   r   u   ┬╥u    ║│r]   r   rc   r   r   u   ┬│r   u   ╪r~   u   ┼u   └┘║│░u   ─═u   ║╥u   ╬u   ╫u	   ║╫╬u	   │┼╪u   └u   ┌u   ├u   ┘u   ┐r   u   ┐┌u   ┘└r   )r  )r]   rc   r  r\   topcbotcs         r6   r  TextDrawing.merge_lines  s
    c-JD|!dcku!di&7DEM43;45=u43;45=u!demu!demu**ts{tu}!dckdem!dckdem!demu!demu$u$u45=TU]u45=TU]u!demu!demuU (V 
r5   c                 r    [        [        S U 5      5      n[        S U 5       5      nU H	  nX#l        M     g)z
When the elements of the layer have different widths, sets the width to the max elements.

Args:
    layer (list): A list of elements.
c                 
    U S L$ rn   r.   )r5  s    r6   <lambda>-TextDrawing.normalize_width.<locals>.<lambda>  s    atmr5   c              3   8   #    U  H  oR                   v   M     g 7frn   )rh   )rL  r  s     r6   rN  .TextDrawing.normalize_width.<locals>.<genexpr>  s     4edkkerP  N)r  filterrf   rP   )r2  r^  rR  r  s       r6   r  TextDrawing.normalize_width	  s6     V3U;<4e44D& r5   c           
      (  ^^ U R                   nU(       a  UR                  OUR                  nU R                  SU nU R                  US mU(       a  UR                  OUR                  nUS R	                  US5      SSS2   n/ n	/ n
/ n[        UU4S jT 5       5      n[        Xx5       Hd  n[        U5      TUS      :  a  U
R                  U5        M+  [        U5      TUS      :  a  UR                  U5        MS  U	R                  U5        Mf     / n[        [        U5      5       Ha  n[        USS5      b  SnX   S	:X  a$  UR                  [        X2[        U5      S
95        M?  UR                  [        X2[        U5      S
95        Mc     XXT4$ )a  
Analyzes the node in the layer and checks if the controlled arguments are in
the box or out of the box.

Args:
    node (DAGNode): node to analyse
    wire_map (dict): map of qubits/clbits to position
    ctrl_text (str): text for a control label
    conditional (bool): is this a node with a condition
    mod_control (ControlModifier): an instance of a modifier for an
        AnnotatedOperation

Returns:
    Tuple(list, list, list):
      - tuple: controlled arguments on top of the "node box", and its status
      - tuple: controlled arguments on bottom of the "node box", and its status
      - tuple: controlled arguments in the "node box", and its status
      - the rest of the arguments
Nb0rq   c              3   <   >#    U  H  oT;   d  M
  TU   v   M     g 7frn   r.   )rL  r5  args_qubitswire_maps     r6   rN  /TextDrawing.controlled_wires.<locals>.<genexpr>6  s     QHq[@P{x{Hs   	r   	conditionT1)r   r?   r  )opnum_ctrl_qubitsqargs
ctrl_staterZ   sortedr  minrB  rf   rA  rW   r  r  boolr  )r  r  	ctrl_textr   mod_controlr  r  ctrl_qubitsr  in_boxtop_boxbot_boxqubit_indices
ctrl_qubitgatesr4  r  s    `              @r6   controlled_wiresTextDrawing.controlled_wires  sv   * WW9D+55"J\J\jj!1/2jj!12/:[++
"1~,,_cB4R4H
QHQQk6J=!HZ]$;;z*]#hz!}&==z*j) 7 s;'(A r;-9"}#VUYZaUbcd;PTU\P]^ ) ==r5   c           	      R  ^  UR                   n/ n/ nSnSn[        USS5      n	[        U[        5      (       aP  T R                  (       d?  [        T R                  UR                  S   5      u  pnU
b  U
R                   SU 3nOU nO[        USSS9n[        U[        [        45      (       dC  [        US	S5      (       d1  [        US5      u  pn[        R                  U5      =(       d    UnX-   n[        US
S5      b  XbR                  UR                   USS9-  nSnS nSn[        USS5      (       a7  [#        UR$                  5      nU H  n[        U[&        5      (       d  M  Un  O   T R                  (       a  [        U[        5      (       a  [)        5       nUR+                  UR,                  S   U5        [        T R                  UR                  S   5      u  pnT R.                  (       a6  U
b3  UR1                  UR                  S   [3        [5        U5      5      5        GOUR1                  UR                  S   [3        5       5        GO[        US	S5      (       a  T R6                  (       d  X%Xg4$ [9        UR,                  U 4S jS9nUR,                   HD  nUT R:                  ;   d  M  UU:X  a  UR<                  OSnUR+                  U[?        U5      5        MF     GO[[        U[        5      (       aB  [A        [C        UR,                  5      5       Vs/ s H  n[E        US9PM     nnU" UUX%U5        GO[        U[        5      (       a(  UR+                  UR,                  S   [G        US95        GO[        U[H        5      (       a$  SU 3n[K        US9[K        US9/nU" UUX%U5        GO[C        UR,                  5      S:X  a  UR                  (       a&  T R                  (       d>  [        U[        5      (       a)  UR+                  UR,                  S   [M        WUS95        GO[        U[N        5      (       d  U(       Ga1  [        RQ                  XWUU5      nUu  nnnnnU(       a  [C        U5      S:X  a  URS                  [M        WUS95        GOU(       a  SOSnU(       a  SOSnURU                  UWUUUUS9n [A        [9        U 5      [W        U 5      S-   5       H  n!URS                  U![Y        S5      45        M!     GOdU	R                  S:X  a  URS                  [K        US95        GO:U	R                  S;   a7  U	R                  R[                  5        U 3nURS                  [K        US95        OU	R                  S:X  a!  U[E        US9[E        US9/-  nU" UUX%U5        OU	R                  S:X  a  SU 3nU[K        US9[K        US9/-  nO[C        U5      S:  ao  U(       a  SOSnU(       a  SOSnURU                  UWUUUUS9n [A        [9        U 5      [W        U 5      S-   5       H  n!URS                  U![Y        S5      45        M!     OURS                  [M        WUS95        U" UUX%U5        O[C        UR,                  5      S:  aO  UR                  (       d>  UR,                   V"s/ s H  n"T R:                  UU"      PM     n#n"URU                  U#WUS9  O_UR,                  (       a8  UR                  (       a'  UR]                  WUR,                  UR                  US9  O[_        SUR                  5      eURa                  S  S9  U V"V$s/ s H  u  n"n$U$PM
     nn"n$URa                  S! S9  U V%V$s/ s H  u  n%n$U$PM
     nn%n$X%Xg4$ s  snf s  sn"f s  sn$n"f s  sn$n%f )"zConvert a dag op node into its corresponding Gate object, and establish
any connections it introduces between qubits. gate_wire_map is the flow_wire_map
if gate is inside a ControlFlowOp, else it's self._wire_mapNF	base_gater   r   r  r  r  
_directiver  r  rD   Tc                     [        U5       Hc  u  pVX@R                  U      nXs VVs/ s H  u  pXUPM	     snn;  d  M2  UR                  U R                  W   U5        UR                  Xv45        Me     g s  snnf rn   )r1  r  	set_qubitrB  )	r  r  r2  current_consgate_wire_mapr4  gateactual_indexjs	            r6   add_connected_gate5TextDrawing._node_to_gate.<locals>.add_connected_gatem  sf    $U+,ZZ];l'Cldal'CCOODJJqM48 ''(<=	 ,'Cs   A4
	modifiersc                 N   > TR                   R                  U [        S5      5      $ )Ninf)rl  r  float)qrR   s    r6   r  +TextDrawing._node_to_gate.<locals>.<lambda>  s    dnn6H6HERWL6Yr5   keyr=   r   ZZr    r   r   )r   controlled_edgerD   rE   z)u1pswaprzzr)   )r  cargsr   z7Text visualizer does not know how to handle this node: c                     U S   $ Nr   r.   tups    r6   r  r    s    #a&r5   c                     U S   $ r  r.   r  s    r6   r  r    s    s1vr5   )1r  r  r  r   ri  r%   r_  r  rM  r"   r   r   r!   rV  r  set_cl_multiboxr  r   r  r   r   r  r  rm  	set_clbitr   r  re  r  r\  r?   r   rA  rW   r  r  r   r  r   r
   r  rB  set_qu_multiboxrf   r8   upper_set_multiboxr*   sort)&rR   r  r2  r  r  r  current_cons_condconnection_labelr   r  r  r   r  params	gate_textr  r	  r  canonical_modifiersmodifierr  	top_qubitqubitr?   r  controls_arraycontrolled_topcontrolled_botr  restrD   rE   indexesr   r  mapped_qargsgcs&   `                                     r6   _node_to_gateTextDrawing._node_to_gateN  s    WWBT2	 b'""4+>+>%6t}}djjQRm%T"H#$MM?!I;7%;"2vq9F"x/00\SX9Y9Y&8V&D#I!#11"5BI!*I2{D)5!6!6r||]`e!6!ffK	> 2{D))"9",,"G/h88"*K 0
 :b'#:#:=DOODJJqM40%6t}}djjQRm%T"H8#7JJqMc)n-
 

1y{;Ru--$$,=OODJJ,YZIDKK'(-(:BHHEOOE75>: $
 H%%:?DJJ:PQ:PQRK0:PEQtUEOE""OODJJqM<K+PQG$$!#F8}4f6UVEtUEO$**o"4::##
2w(?(? OODJJqM;yk+Z[N++{(99Y[N LZHE>>?Dt9>LLYK!PQ+9%tK+9%tK#33!$/(7$/$/ 4 G "'s7|S\A5E!F$++UKO,DE "G 3&V<=;.&/nn&:&:&<%=fX#F V<=6)"5rk7RSS"4]S5(%'x= &[96k;Z[[TQ'5e4'5e4// +$3 + + 0  #3w<W1ABE ''B(@A C [LMtUEO_!$**CG::N:aDKKa(89:LN!!,	{!SZZDJJjjjj'	    %I277  	01&23ldal3#56+<=+<41aQ+<=$5GGE RX O$ 4=s   ^2^^=^#c                    U R                  U R                  S9nU(       d  / $ [        R                  U5      /nU R                   GH  n[        U R                  U R                  U R                  U R                  U R                  5      nU H  n[        UR                  [        5      (       a%  SU l        U R                  XRU R                  5        MG  U R!                  XTU R                  5      u  pFpxUR"                  R%                  X45        UR"                  R%                  SU45        M     UR'                  S5        UR%                  UR(                  5        GM     U$ )z
Constructs layers.
Returns:
    list: List of DrawElements.
Raises:
    VisualizationError: When the drawing is, for some reason, impossible to be drawn.
r  r   Nr   )r  rc  rG  r7  r^  Layerr\  r]  rm  r_  rl  r  r  r   rq  add_control_flowr7  connectionsrB  connect_with
full_layer)	rR   r  r  
node_layerr2  r  r  r'  r(  s	            r6   r  TextDrawing.build_layers  s&    __8J8J_K
I((45**JE #dgg}55'(D$))$GOSOaOaT^^PLE): %%,,.>-MN%%,,d4E-FG # u%MM%**+' %* r5   c           
      `
  ^ ^ [        UR                  [        5      (       a3  [        UR                  R                  [        R
                  5      (       dQ  [        UR                  SS5      (       Ga9  [        UR                  R                  [        R
                  5      (       Ga  U U4S jn[        UR                  [        5      (       a  UR                  R                  OUR                  R                  n[        [        U5      R                  5      n[        5       n[        USS9R                  UR                  [        U5      5      5        UR!                  5       T l        [%        T R"                  5      T R&                  :  a!  T R"                  ST R&                   S-   T l        O%[        UR                  [(        [*        [        45      nT R-                  UT[.        US9nUR1                  UR2                  5        [5        UR                  R6                  5      n	[        UR                  [        5      (       aG  U	R9                  S[5        UR                  R;                  5       5      S   S	   R=                  5       5        [?        U	5       GHb  u  pTRA                  5       nURC                  [E        URF                  URH                  5       VVs0 s H  u  pUTU   _M     snn5        [E        URJ                  UR                  5       Hs  u  pT RL                  (       aG  [O        T RP                  U5      =nb.  [O        T RP                  U5      nURC                  UTU   05        M]  URC                  UTU   05        Mu     U
S:  a4  T R-                  X[R        U
S	-
  S
S9nUR1                  UR2                  5        [U        XS9u    nnU GH  n[W        T RH                  T R                  T RL                  T RP                  U5      nU H  n[        UR                  [X        5      (       a>  T =RZ                  S	-  sl-        T R]                  UX,5        T =RZ                  S	-  sl-        M`  T R_                  UUU5      u  nnnnUR`                  R1                  UU45        UR`                  R1                  SU45        M     URc                  S5        UR1                  UR2                  5        GM"     GMe     T R-                  UT[d        S
S9nUR1                  UR2                  5        gs  snnf )z,Add control flow ops to the circuit drawing.r  Nc                   > [        U [        R                  5      (       a   [        R                  " U R
                  5      $ [        U [        5      (       a   [        R                  " U R
                  5      $  [        TR                  U 5      u  pnUc  [        R                  " SU 35      $ [        R                  " UR
                  [        R                  " U5      5      $ ! [         a    [        R                  " STU     35      s $ f = f)zxLook up a classical-expression variable or register/bit in our internal symbol
table, and return an OQ3-like identifier._bit)r  r   Varr   
IdentifierrM  r   r%   r_  r	   SubscriptedIdentifierIntegerLiteral)varr  r  r  rR   r  s       r6   
lookup_var0TextDrawing.add_control_flow.<locals>.lookup_var&  s    
 c488,,>>#((33c#455>>#((33B5Ft}}VY5Z2H
 #>>D*<==00@R@RS\@]^^ $ B >>D#*@AABs   7C! !&D
	D
z  )indentz...r  r   r    F)r  r   )3r  r  r   targetr   Exprr  r  r  r   r]  r   r   visitacceptr   getvaluerr  rW   rh  r   r   draw_flow_boxCF_LEFTrB  r>  r  blocksinsertcases_specifiercopy_empty_liker1  copyupdater  r  r\  r  rm  r$   r_  CF_MIDr(   r:  r   rq  r;  r7  r<  r=  r   )rR   r  r  r  rI  r  draw_conditionalstream
flow_layercircuit_listcirc_numrt  flow_wire_mapouterinnerin_regout_regr   r^  layer_nodesflow_layer2
layer_noder  r'  r(  s   `  `                     r6   r;  TextDrawing.add_control_flow  s    tww--*TWW^^TYY2W2WDGG[$//Jtww?P?PRVR[R[4\4\_0 +5TWWl*K*KQUQXQXQbQbI#N9$=$D$DEZF-33I4D4D\R\E]4^_$oo/DO4??#dmm3"&///DMM"BU"J)$''Hk<3XY ''hM]'^
j++, DGGNN+dgg|,,4(?(?(A#B1#Ea#H#X#X#Z[!*<!8H$MMOM  <?

GNN<[\<[LE'<[\ !$DJJ ???/uEEVR.t}}eDG!((&(72C)DE!((%%)AB !@ !|!//A5 0 
 j3343GTKAq%$#KKdoot}}m #.J!*--??((A-(--j&P((A-( !..z;V'(-,#//668H,7WX#//66>O7PQ #.  ((/k445-  %/ "9` ''he'T
j++,[ ]s   T*c                    UR                   n[        U R                  5      nU[        :X  Ga$  SnU R                  (       a  SU R                  -   n[        U[        5      (       a
  SU-   U-   n	GO[        U[        5      (       a
  SU-   U-   n	GOc[        U[        5      (       a[  UR                  S   n
S[        U
5      ;  a&  [        U
5      S:  a  [        U
SS 5      nUSS	 S
-   nO[        U
5      nSU-   S-   U-   n	O[        U[        5      (       a	  SU-   U-   n	O[        U[        5      (       a	  SU-   U-   n	O[        SUR                   35      eU[        :X  a  [        U[        5      (       a  SU-   n	Oz/ n[!        UR#                  5       5       H  u  pUR%                  U5        M     S[        X   S   5      ;   a  SnO[        X   5      R'                  SS5      nSU-   S-   U-   n	OSU-   n	[)        U R*                  U R,                  U R.                  U R0                  U5      n[        UR2                  5      S:X  a7  UR5                  U R*                  X!R2                  S         [7        X9US95        OUR2                   Vs/ s H  nUU   PM
     nn[9        U5      n[;        U5      nUU-
  S-   nUR5                  U R*                  U   [=        X9SS95        [?        [A        US-   U5      5       H0  u  nnUR5                  U R*                  U   [C        UU	UUSS95        M2     UR5                  U R*                  U   [E        UU	UUSS95        U(       Ga  [        UR                   [        5      (       a  [        UR                   RF                  [H        RJ                  5      (       a  UR                   RF                  nO[        UR                   RF                  [L        5      (       a  UR                   RF                  S4nOSUR                   RF                  SUR                   RF                  RN                  -  S-
  4nOUR                   RP                  nURS                  UUSS9nU$ s  snf )z5Draw the left, middle, or right of a control flow boxr=   r<   zIf-zWhile-r   rA     Nrq   z, ...)zFor-zBox-zSwitch-z"unhandled control-flow operation: zElse-defaultz,))zCase-zEnd-r    )r?   r   )r?   rQ   )r?   r   r   rQ   )r?   r   r   rQ   r)   r  r  )*r  r  rq  rR  rr  r  r   r   r   r)  rW   r   r   RuntimeErrorrM  rY  r  rU  rB  r   r:  r\  r]  rm  r_  r  r  r   r  rf   r   r1  rA  r   r   rL  r   rM  r   r  r  r!  )rR   r  r_  r   r^  r   r  depthetextr?   indexset	index_str	jump_listjump_valuesr   jump_strr\  qargidx_listmin_idxmax_idx
box_heightr   r4  r  s                            r6   rQ  TextDrawing.draw_flow_box  s    WWD$$%gEdoo-"h''-B,, 5(50B	**99Q<#h-/CMA4E #HRaL 1I )#2 9I #HI,y8B&&.B--!E)E1"%G		{#STT"h''%	&*2+=+=+?&@NK$$[1 'A I$7$: ;;(H"9#67??cJH%#-8 UNEKKKKOOMM

 tzz?a  M**Q-89W{K 9=

C
d+
HC(mG(mG 7*Q.J  G$ogWY&Z &eGaK&ABq$$KKN##%/##%	 C   G$!+ +!	 $''<00dggnndii88 $I66!% 3I!%tww~~7J7J1Ka1O PI GG--	**9mQV*WAS Ds   Q*)r_  rr  rq  rs  rl  r]  rm  rp  rh  rd  rc  rb  rg  ri  r^  re  r\  rf  rk  )
FTNrX  TNNF   Nrn   r  )r]   )r   F)r/   r0   r1   r2   r3   rS   rz  r~  r  ry  r  r  r  r  r  r:  r  r  r  r  r7  r  r;  rQ  r4   r.   r5   r6   rV  rV    s     #2!h$
$#42CJ(T$L + + 6 6p 
' 
' 5> 5>njHX#Jf-Per5   rV  c                   x    \ rS rSrSrS r\S 5       rS rS r	      SS jr
SS	 jrS
 r    SS jrS rSrg)r:  i  z'A layer is the "column" of the circuit.c                    Xl         X@l        U(       at  / U l        S nU Hd  n[        U R                  U5      nU(       a  Xh:X  a  M'  Uc  U R                  R	                  U5        MG  UnU R                  R	                  U5        Mf     OX l        S /[        U5      -  U l        / U l        S /[        U5      -  U l        X0l	        XPl
        g rn   )r\  r_  r]  r$   rB  rW   qubit_layerr<  clbit_layerrm  rl  )	rR   r\  r]  rm  rt  r  previous_cregbitr  s	            r6   rS   Layer.__init__  s    DK M+DMM3? ]%>#KK&&s+$,MKK&&}5  !K 6CK/ 6CK/$!r5   c                 4    U R                   U R                  -   $ )zo
Returns the composition of qubits and classic wires.
Returns:
    String: self.qubit_layer + self.clbit_layer
)r}  r~  rg   s    r6   r>  Layer.full_layer	  s     $"2"222r5   c                 :    X R                   U R                  U   '   g)zSets the qubit to the element.

Args:
    qubit (qbit): Element of self.qubits.
    element (DrawElement): Element to set in the qubit
N)r}  rl  )rR   r.  elements      r6   r  Layer.set_qubit  s     3:./r5   c                    [        U R                  U5      nU R                  (       a5  Ub2  X R                  U R                  U   [        U R                  5      -
  '   gX R                  U R                  U   [        U R                  5      -
  '   g)zSets the clbit to the element.

Args:
    clbit (cbit): Element of self.clbits.
    element (DrawElement): Element to set in the clbit
N)r$   r_  rm  r~  rl  rW   r\  )rR   clbitr  r  s       r6   r"  Layer.set_clbit  sj     $DMM59??x3LST^^H5DKK8HHIIPT^^E2S5EEFr5   Nc                   ^^^  TGb,  TGb(  [        U4S j[        U R                  5       5       5      n[        U4S j[        U R                  5       5       5      n	[	        [        [        [        T5      S-
  5      5      [        [        [        T5      S-
  5      5      5      n
U R                   Vs/ s H5  nUT;   d  M  [        TR                  U5      5      R                  U
S5      PM7     nnU R                   Vs/ s H5  nUT;   d  M  [        TR                  U5      5      R                  U
S5      PM7     nn[        TU R                  R                  S9m[        TU R                  R                  S9m[        U R                  5      [        U5      -
  [	        U	5      -   S-   nU R                  TR                  S5      [        XR                  S5      S95        Sn[        [        [        U5      S-   [        U R                  5      5      5       H^  u  nnUU;   a#  TR                  S5      nUR                  S5      nOU R                  U   nSU
-  nU R                  U[        XUUS95        M`     [        [        [	        U	5      5      US-   5       H^  u  nnUU	;   a#  TR                  S5      nUR                  S5      nOU R                  U   nSU
-  nU R                  U[!        XUUS95        M`     U R                  TR                  S5      [#        XUR                  S5      S95        U	$ Tc  Tb  [%        T5      m [        U 4S j[        U R                  5       5       5      n[        [        [        T 5      S-
  5      5      n
T R'                  U R                  R                  S9  S	/[        T 5      -  nU R                  n[(        n[*        n[         n["        nOTc  Tb  [%        T5      m [        U 4S
 j[        U R                  5       5       5      n[        [        [        T 5      S-
  5      5      n
U R                   Vs/ s H5  nUT ;   d  M  [        T R                  U5      5      R                  U
S5      PM7     nnT R'                  U R                  R                  S9  U R                  n[,        n[        n[        n[.        nO[1        S5      e0 nU(       a@  [        U R                  5       H'  u  nnU H  u  nnUU:X  d  M  US:X  a  SOSUU'   M     M)     [        U5      S:X  a  U" T S   U" XS95        U$ [	        U5      [        U5      -
  S-   nU" T R                  S5      U" XUR                  S5      S95        [        [        [        U5      S-   [	        U5      5      5       Hq  u  nnUU;   a#  T R                  S5      nUR                  S5      nO!U R                  U R                  -   U   nSU
-  nUR3                  U5      nU" UU" XUUUS95        Ms     U" T R                  S5      U" UUUUR                  S5      US95        U$ s  snf s  snf s  snf )Nc              3   <   >#    U  H  u  pUT;   d  M  Uv   M     g 7frn   r.   )rL  r4  r5  r  s      r6   rN  &Layer._set_multibox.<locals>.<genexpr>3       !U0F!u*!!0F   	c              3   <   >#    U  H  u  pUT;   d  M  Uv   M     g 7frn   r.   )rL  r4  r5  r  s      r6   rN  r  4  r  r  r    r<   r  r   r   c              3   <   >#    U  H  u  pUT;   d  M  Uv   M     g 7frn   r.   rL  r4  r5  bitss      r6   rN  r  f        S/Etqd/Er  r=   c              3   <   >#    U  H  u  pUT;   d  M  Uv   M     g 7frn   r.   r  s      r6   rN  r  r  r  r  z_set_multibox error!.r  r  r  r  )rD   rQ   )rQ   r   )rE   rQ   r   )r  r1  r\  r]  rf   rW   r  r   rY   r  r  r  r   rA  r   r"  r   r   r  r&  ry   r   r   r   r*   r  )!rR   r?   r  r  rD   rE   r   r  qarg_indicescarg_indiceswire_label_lenqbit	qargs_strcbit	cargs_strrx  r   bit_i	named_bitrQ   bit_indicesset_bitOnWire	OnWireTop	OnWireMid	OnWireBotcontrol_indexr   r.  qubit_in_edgero   r   r  s!     ``                            @r6   r%  Layer._set_multibox(  s    !2!!U	$++0F!UUL!!U	$++0F!UUL !SUa%8!93s3u:PQ>?R;STN !KK'D5= BEKK%&,,^SA'   !KK'D5= BEKK%&,,^SA'   5dkk&7&78E5dkk&7&78ET[[)C,==L@QQTUUJNN599Q<--XYJZ)[\E )%L0AA0Es4;;GW*X YuL( %		!I!*q!1J $E 2I!$~!5J~eS]^ !Z !*%L0A*BEAI NuL( %		!I!*q!1J $E 2I!$~!5J~eS]^ !O NN		!nU9==YZK[\  =U.;D  Sy/E SSK SY]!34NII$++++I,s4y(InnG F&I&I&I]u0;D  Sy/E SSK SY]!34N !KK'D4< ADJJt$%++NC@'  
 II$++++I,nnG F&I&I&I$%<== )$++ 6u,;(M5-8=u#e, -< !7 {q DGVECD> ; [)C,<<q@JYuR[R_R_`aRbc !*%K0@10Dc+FV*W XuK' $I!*q!1J!%t{{!:E BI!$~!5J - 1 1% 85ZWd !Y  +(}}Q/ +	 _
ls$   2
Y .Y>
Y!.Y!
Y&.Y&c           
         [        U[        R                  5      (       Ga.  Sn/ n[        U5      R                  n[
        R                  " [        5      nU H+  nU[        U R                  U5         R                  U5        M-     UR                  SS5      =n	(       a/  UR                  U R                  US/[        U	5      -  X5      5        U R                  (       a'  U H  n
U R!                  U
S   [#        XCS95        M!     U$ UR%                  5        H4  u  pUR                  U R                  US/[        U5      -  X5      5        M6     U$ ['        XR                  U R                  5      u  pL[        US   [(        5      (       a  US   nO[        U R                  US   5      nU R                  (       at  [        US   [*        5      (       a;  Uc  U R                  XLUS   /U5        / $ U R!                  US   [#        XCS95         / $ U R!                  US   S   [#        XCS95        / $ [        US   [*        5      (       a  US   /nO'[-        UR.                  5       Vs/ s H  oU   PM	     nnU R                  XLX5      $ s  snf )a1  Sets the multi clbit box.

Args:
    condition (list[Union(Clbit, ClassicalRegister), int]): The condition
    wire_map (dict): Map of bits to indices
    top_connect (char): The char to connect the box on the top.

Returns:
    List: list of tuples of connections between clbits for multi-bit conditions
z[expr]Nr.   r  r   )r?   rD   )r  r   rM  r   r]  collectionsdefaultdictr  r$   r_  rB  r  extendset_cond_bulletsrW   rm  r"  ry   r  r'   r   r   rA  r  )rR   r  r  rD   r?   outcondition_bits	registersr  registerlessr  r  val_bitscond_regr]  idxs                   r6   r!  Layer.set_cl_multibox  s7    i++ EC+I6==N#//5I%*4==#>?FFsK &(}}T266|6

))%#\9J1JLc  !*HNN8A;%0ab !*
 J '0oo&7NHJJt44USECI<Mt^_ '8J1)]]DOO\il$566 |H'y|DH??)A,..#))%IaL>8T I	 NN9Q<51bc I y|A%0abI)A,..#A,383GH3GC3-3GH((&KK Is   #Jc           	        ^ / n[        U4S jU 5       5      n[        U5       H  u  pxSn	TU   U:X  a  Un	X'   S:X  a1  [        SU	S9U R                  TU   [	        U R
                  5      -
  '   O8X'   S:X  a0  [        SU	S9U R                  TU   [	        U R
                  5      -
  '   TU   n
X VVs/ s H  u  p{UPM	     snn;  d  M  UR                  XR                  TU   [	        U R
                  5      -
     45        M     U$ s  snnf )a  Sets bullets for classical conditioning when cregbundle=False.

Args:
    label (str): String to display below the condition
    val_bits (list(int)): A list of bit values
    clbits (list[Clbit]): The list of classical bits on
        which the instruction is conditioned.
    wire_map (dict): Map of bits to indices

Returns:
    List: list of tuples of open or closed bullets for condition bits
c              3   .   >#    U  H
  nTU   v   M     g 7frn   r.   )rL  r  r  s     r6   rN  )Layer.set_cond_bullets.<locals>.<genexpr>  s     7x}s   r<   r  r   )rD   rE   r  )rf   r1  r!  r~  rW   r\  r(  rB  )rR   r?   r  r]  r  r  wire_maxr4  r  rE   r  r  s       `       r6   r  Layer.set_cond_bullets  s    777'FAK}(#{c!EM %;F  #T[[1A!AB #EQ %;F  #T[[1A!AB $C=L,#?,$!A,#??##!#3#3HSMCDT4T#UV (" 	 $@s   1D
c           	      *    U R                  UUUUUUS9$ )a  Sets the multi qubit box.

Args:
    bits (list[int]): A list of affected bits.
    label (string): The label for the multi qubit box.
    top_connect (char): None or a char connector on the top
    bot_connect (char): None or a char connector on the bottom
    conditional (bool): If the box has a conditional
    controlled_edge (list): A list of bit that are controlled (to draw them at the edge)
Return:
    List: A list of indexes of the box.
)r  rD   rE   r   r  )r%  )rR   r  r?   rD   rE   r   r  s          r6   r#  Layer.set_qu_multibox  s.    * !!###+ " 
 	
r5   c                 @   U R                    GH  u  p#U(       d  M  [        U5       H  u  pE[        U[        [        45      (       ai  SnUS:X  a$  [        U5      S:  a  UR                  US/5        ML  U[        U5      S-
  :X  a  UR                  US/5        Ms  UR                  USS/5        M  US:X  a  UR                  US/5        M  U[        U5      S-
  :X  a  UR                  US/U5        M  UR                  USS/5        M     U(       d  GM  U H  n[        U5      [        UR                  5      -   Ul        [        U[        [        45      (       d  MF  UR                  (       d  MY  [        U5      [        UR                  5      -   Ul        M     GM     g)um   Connects the elements in the layer using wire_char.

Args:
    wire_char (char): For example '║' or '│'.
r   r   r    rc   r]   N)r<  r1  r  r!  r(  rW   rt   r`   rN   r  r  r   rO   )rR   rr   r?   affected_bitsr   affected_bits         r6   r=  Layer.connect_with%  s]    %)$4$4 E '0'?#lX|,DEE %Izc-&81&<$,,Y@#m"4q"88$,,Y@$,,YGz$,,Y@#m"4q"88$,,YG$,,YG (@" u$1L.1%j3|?O?O;P.PL+!,0DEE,JbJbJb14Uc,BRBR>S1S. %2/ %5r5   )r_  rl  r~  r]  r<  rm  r}  r\  )NNNNFN)r   )NNFN)r/   r0   r1   r2   r3   rS   rv   r>  r  r"  r%  r!  r  r#  r=  r4   r.   r5   r6   r:  r:    sj    1". 3 3:Q  @D9Lv L 
<!Tr5   r:  )Zr3   ior   warningsr   shutilr   r  rn  qiskit.circuitr   r   r   r	   r
   r   r   r   r   r   r   r   r   qiskit.circuit.classicalr   qiskit.circuit.controlflowr   %qiskit.circuit.library.standard_gatesr   r   r   r   r   "qiskit.circuit.annotated_operationr   r   qiskit.circuit.tools.pi_checkr   qiskit.qasm3r   qiskit.qasm3.printerr   qiskit.qasm3.exporterr   _utilsr!   r"   r#   r$   r%   r&   r'   r(   
exceptionsr*   rR  rY  r   r,   r8   ry   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<  rG  rV  r:  r.   r5   r6   <module>r     s     $  
 H H 9 9 _ _ ) 5 \ \ W 2  - .	 	 	 , 	
	0 	ZN ZNz!+ !,,+ ,. $"+ "*{ @AX{ A /8 /=\; =%X{ %(,; ,*Ah A,/h /(%h %D	.X{ 	.9\; 9%X{ %*:[ : n  $' ' %> %^ , ,:[ :~ *> * . 6 .q qhWT WTr5   