a
    &0_C                     @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	m
Z
mZ dZdZd	Zd
ZededediZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZejG d d! d!eZd"d# Zd$d% ZdS )&a>  supports walking the history as DAGs suitable for graphical output

The most basic format we use is that of::

  (id, type, data, [parentids])

The node and parent ids are arbitrary integers which identify a node in the
context of the graph returned. Type is a constant specifying the node type.
Data depends on type.
    )absolute_import   )nullrev)attr)dagoppycompatsmartsetutil   C   P   G   M   |   :Nc           	   	   #   s   i }D ]}| | }fdd|  D   fdd|  D }dd t D }|D ]}||}|du rttjstttt| |g }||< |s|	t
|f  | qV| fdd|D   | qV| t||fV  qdS )	a  cset DAG generator yielding (id, CHANGESET, ctx, [parentinfo]) tuples

    This generator function walks through revisions (which should be ordered
    from bigger to lower). It returns a tuple for each node.

    Each parentinfo entry is a tuple with (edgetype, parentid), where edgetype
    is one of PARENT, GRANDPARENT or MISSINGPARENT. The node and parent ids
    are arbitrary integers which identify a node in the context of the graph
    returned.

    c                    s    h | ]}|   v r|  qS  rev.0p)revsr   4/usr/lib/python3/dist-packages/mercurial/graphmod.py	<setcomp>=       zdagwalker.<locals>.<setcomp>c                    s,   g | ]$}|  tkr|   vr|  qS r   )r   r   r   psetr   r   
<listcomp>>   s   zdagwalker.<locals>.<listcomp>c                 S   s   g | ]}t |fqS r   )PARENTr   r   r   r   r   C   r   Nc                 3   s   | ]}| vrt |fV  qd S N)GRANDPARENT)r   gr   r   r   	<genexpr>S   r   zdagwalker.<locals>.<genexpr>)parentssortedget
isinstancer   Zbasesetsetr   ZreachablerootsappendMISSINGPARENTaddextendupdater   	CHANGESET)	repor   Zgpcacher   ctxZmparsr"   ZmparZgpr   )r   r   r   	dagwalker*   s,    


r/   c                 #   sJ   t | |D ]8}| | } fdd| D }| t|t|fV  qdS )zcset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples

    This generator function walks the given nodes. It only returns parents
    that are in nodes, too.
    c                    s$   h | ]}|   v rt| fqS r   )noder   r   r   Zincluder   r   r   b   s   znodes.<locals>.<setcomp>N)r&   r"   r   r,   r#   )r-   nodesr0   r.   r"   r   r1   r   r2   Y   s    
r2   c                 #   s  g }i }d}i  j dD ]f\}}d|v r|dd\}}|dkrb| rbt| |i |< q|dkr| r| |i |< q rt fdd}	ndd }	| D ]b\}
}}}|
|vr|	|
 |||
< |d7 }|
|
}||
}|d	d	 fd
d|D }|||d < t|D ]*\}}|s<|||< n|||< |d7 }q$g }t|D ]\}}|v r|	|}|	|
||| |dd|ddf nL||
kr\|D ]<\}}|	|}|	|
|||dd|ddf qq\|
||||f|fV  }qd	S )ax  annotates a DAG with colored edge information

    For each DAG node this function emits tuples::

      (id, type, data, (col, color), [(col, nextcol, color)])

    with the following new elements:

      - Tuple (col, color) with column and color index for the current node
      - A list of tuples indicating the edges between the current node and its
        parents.
    r   s   graph   .s   widths   colorc                    s     |   i S r   )r$   branchr   )configr-   r   r   <lambda>   r   zcolored.<locals>.<lambda>c                 S   s   i S r   r   r   r   r   r   r6      r   Nc                    s   g | ]\}}| vr|qS r   r   )r   Zptr   )nextr   r   r      r   zcolored.<locals>.<listcomp>r   )uiZconfigitemsrsplitisdigitint
setdefaultisalnumr	   Zlrucachefuncr'   indexpop	enumerater$   )Zdagr-   seenZcolorsZnewcolorkeyvalr4   ZsettingZgetconfZcurtypedatar"   colZcolorZ
addparentsir   edgesZecolZeidZbconfptyper   )r5   r7   r-   r   coloredh   sp    






	


rK   c                 #   s  |j }||vr|| ||g }g }|D ]D\}}	|	|kr@q.|	|v rT||	 q.||	 |j|d|j|	< q.t|}
d|
d  }|dd  | d <  fdd|D } |dd< t|dkr4|f |d f d}|d7 }| ||||
|ffV  d}d7 |
d7 }
g }|d= qt|dkrP|f t|dkrp|d f t |
 }|dkr|d7 }|j|d | ||||
|ffV  dS )	z9adds edge info to changelog DAG walk suitable for ascii()r   r      Nc                    s   g | ]}  |fqS r   )r?   r   ZnextseenZnodeidxr   r   r      r   zasciiedges.<locals>.<listcomp>   \r   )rB   r'   r?   stylesr$   rI   lenr@   )rE   charstater   r"   rB   ZknownparentsZ
newparentsrJ   parentncolswidthrI   Z	nmorecolsr   rM   r   
asciiedges   sN    



rV   c                 C   s2   t | D ]$\}\}}||kr||d f| |< qd S )Nr   )rA   )rI   rH   startendr   r   r   _fixlongrightedges   s    rY   c           
      C   s   |rr||krr|dkrr|dkr\t |d |}| |d |d d  }|ddg||   |S ddg|| d  S n*|| d }	|	dkr| |	d  d  S g S d S )Nr   r8   r   rL      /    rN   )maxr*   )
echarsidxZpidxrT   coldiffZpdiffZfix_tailrW   tail	remainderr   r   r   _getnodelineedgestail   s    rb   c                 C   s   |D ]\}}||d kr*d|d| d < q||d krHd|d| d < q||krf| d|  |d| < qd| t |krxqd|d| < ||kr|| }}td| d d| D ]}|| dkrd||< qqd S )Nr   rZ   rL   rN      +   -)rP   range)r]   rI   nodelineZ	interlinerW   rX   rH   r   r   r   
_drawedges  s    
rg   c                 C   s   | d |d  }||d f|v s,||f|v rL| | |d |d d   n| ddg || d }|dkr| | |d  d   |S )NrL   r   r[   r   )r*   )r]   r^   rT   rI   linera   r   r   r   _getpaddingline   s     ri   c                    s  d|  vrdS |ddd }|r8|d du r8|  qt|dd d d}|jsZdnd}t| || k r| |dd  q^|rg }g }	|d}
t||
dd |
d D ].\ }|du r| d  q|	 d  qt	t
|
|
t|	d  d}|	dd }| | d D ]t}dgt||
  ||
d< t
t|D ]F |  d }t||  | < ||  krvdn
||	   ||< qBq|jsd	d
dndd
it| D ]4\ }d|vrƐq fdd|D |dd< qdd | D }|D ]}||= || qdS )zDraw ending lines for missing parent edges

    None indicates an edge that ends at between this node and the next
    Replace with a short line ending in ~ and add / lines to any edges to
    the right.

    NrL   r8   r   r      r[   rZ   r      ~)r   rL   c                    s   g | ]}|p  d qS )r[   r$   r   crH   mapr   r   r   `  r   z$_drawendinglines.<locals>.<listcomp>c                 S   s   g | ]\}}|d u r|qS r   r   r   r   rn   r   r   r   r   c  r   )valuesr@   r\   countgraphshortenrP   r'   r?   rA   listre   itemsremove)linesZextraedgemaprB   rR   Z	edgecharsZ
shift_sizeZminlinesZemptiesZtoshiftZfirst_emptyrn   targetsZ	positionsrh   posrw   rS   r   ro   r   _drawendinglines5  sD    

 *
 r|   c                   @   sx   e Zd ZdZejdeedZejdee	dZ
ejdddZejdddZejdeejdZejdddZdS )
asciistatez State of ascii() graph renderingF)Zinitdefaultr   N)__name__
__module____qualname____doc__r   ZibZFactoryru   rB   dictrI   lastcoldiff	lastindexEDGEScopyrO   rt   r   r   r   r   r}   i  s   r}   c                 C   s(   |D ]\}}|  ||  d  qdS )aX  outputs an ASCII graph of a DAG

    this is a helper function for 'ascii' below.

    takes the following arguments:

    - ui to write to
    - graph data: list of { graph nodes/edges, text }

    this function can be monkey-patched by extensions to alter graph display
    without needing to mimic all of the edge-fixup logic in ascii()
       
N)writerstrip)r9   ZgraphZlnZlogstrr   r   r   outputgraphu  s    r   c              
      s  |\}}}}	d|	  k r dk s&n J |j |j  }
 fdd|
D }|dt||	 t|
 d  |	dkrvt| t|dko|	dkodd |D }t|dko| }|d	|d  }||d
g |t|||j||	|j| |d	|d  }t	
d|	 D ]}|d
 q|| d }|	dkrNt	
|D ]}|dd
g q6nJ|	dkrx|||d d |d   n t	
|D ]}|dd
g qt|||| |g}|r|t|||| |jrtdd |D r|| n
|| |d	||	 d  }t|t|k rFt|t|k rF||d	d	  qt|| |
| t|t|k rv|d qVt|||	 fdd|D }t| t|| |	|_||_d	S )a  prints an ASCII graph of the DAG

    takes the following arguments (one call per node in the graph):

      - ui to write to
      - Somewhere to keep the needed state in (init to asciistate())
      - Column of the current node in the set of ongoing edges.
      - Type indicator of node data, usually 'C' for changesets.
      - Payload: (char, lines):
        - Character to use as node's symbol.
        - List of lines to display as the node's text.
      - Edges; a list of (col, next_col) indicating the edges between
        the current node and its parents.
      - Number of columns (ongoing edges) in the current revision.
      - The difference between the number of columns (ongoing edges)
        in the next revision and the number of columns (ongoing edges)
        in the current revision. That is: -1 means one column removed;
        0 means no columns added or removed; 1 means one column added.
    rL   c                    s&   g | ]}  |d dfD ]}|qqS r   r[   rl   rq   )ry   r   r   r     r   zascii.<locals>.<listcomp>r   r   r8   c                 S   s    g | ]\}}|d  |k r|qS )r   r   )r   xyr   r   r   r     r   Nr[   r   rZ   rN   c                 s   s   | ]}|r|d v V  qdS )s   \/Nr   rm   r   r   r   r!     r   zascii.<locals>.<genexpr>r   c                    s"   g | ]}d d  d |f qS )s   %-*s rL   r   )join)r   rh   )indentation_levelr   r   r     s   )rI   rB   r*   r\   rP   rY   rb   r   r   r   Zxranger'   rg   ri   rt   anyr|   r   zip)r9   rR   rE   rQ   textZcoldatar^   rI   rT   r_   rB   r]   Zadd_padding_lineZfix_nodeline_tailrf   Zshift_interlinerH   rs   rx   Zextra_interliner   )ry   r   r   ascii  sp     
 

 

r   )r   Z
__future__r   r0   r   Z
thirdpartyr    r   r   r   r	   r,   r   r   r(   r   r/   r2   rK   rV   rY   rb   rg   ri   r|   sobjectr}   r   r   r   r   r   r   <module>	   s,   /Z64