o
    hK(                     @   s   d Z ddlZddlmZ ddlmZmZ ddlm	Z	m
Z
 g dZdd Zejdd	d
dd ZdddZe
dddejdd	d
dd Ze	de
ddddddZdS )aP  Functions for reading and writing graphs in the *sparse6* format.

The *sparse6* file format is a space-efficient format for large sparse
graphs. For small graphs or large dense graphs, use the *graph6* file
format.

For more information, see the `sparse6`_ homepage.

.. _sparse6: https://users.cecs.anu.edu.au/~bdm/data/formats.html

    N)NetworkXError)	data_to_n	n_to_data)not_implemented_for	open_file)from_sparse6_bytesread_sparse6to_sparse6_byteswrite_sparse6c                 #   s   t | }|dkrtd|rdV  dV  t|D ]}tt|d V  qdd> |k r8d7 d> |k s.fdd}td	d
 |  D }g  d}|D ]F\}}	||krd d  	||	 qO||d kr{|d7 } d  	||	 qO|} d  	||  d  	||	 qOdk r|d> krt   d kr||d k r d  	dgt   d   n 	dgt   d    fddt
dt  dD }
|
D ]}tt|d V  qdV  dS )a%  Yield bytes in the sparse6 encoding of a graph.

    `G` is an undirected simple graph. `nodes` is the list of nodes for
    which the node-induced subgraph will be encoded; if `nodes` is the
    list of all nodes in the graph, the entire graph will be
    encoded. `header` is a Boolean that specifies whether to generate
    the header ``b'>>sparse6<<'`` before the remaining data.

    This function generates `bytes` objects in the following order:

    1. the header (if requested),
    2. the encoding of the number of nodes,
    3. each character, one-at-a-time, in the encoding of the requested
       node-induced subgraph,
    4. a newline character.

    This function raises :exc:`ValueError` if the graph is too large for
    the graph6 format (that is, greater than ``2 ** 36`` nodes).

    l       @ z?sparse6 is only defined if number of nodes is less than 2 ** 36   >>sparse6<<   :?      c                    s    fddt D S )zBig endian k-bit encoding of xc                    s(   g | ]}d  d  | > @ rd ndqS )r   r    .0i)kxr   n/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/networkx/readwrite/sparse6.py
<listcomp>=   s   ( z8_generate_sparse6_bytes.<locals>.enc.<locals>.<listcomp>)ranger   )r   r   r   enc;   s   z$_generate_sparse6_bytes.<locals>.encc                 s   s(    | ]\}}t ||t||fV  qd S )N)maxmin)r   uvr   r   r   	<genexpr>?   s   & z*_generate_sparse6_bytes.<locals>.<genexpr>r      c                    sl   g | ]2} |d   d>  |d  d>   |d  d>   |d  d>   |d  d>   |d  d >  qS )r      r            r   r   )bitsr   r   r   Z   s    z+_generate_sparse6_bytes.<locals>.<listcomp>   
N)len
ValueErrorr   strencodechrsortededgesappendextendr   )Gnodesheaderndr   r,   curvr   r   datar   )r$   r   r   _generate_sparse6_bytes   sT   



2



r6   T)graphsreturns_graphc           	         s
  |  dr| dd } |  dstddd | dd D }t|\} dd> |k r7d7 d> |k s- fd	d
}d}t }|t| d}| D ]+\}}|dkr\|d7 }||ksd||krf n||krm|}qP|||rud}||| qP|st	|}|S )aV  Read an undirected graph in sparse6 format from string.

    Parameters
    ----------
    string : string
       Data in sparse6 format

    Returns
    -------
    G : Graph

    Raises
    ------
    NetworkXError
        If the string is unable to be parsed in sparse6 format

    Examples
    --------
    >>> G = nx.from_sparse6_bytes(b":A_")
    >>> sorted(G.edges())
    [(0, 1), (0, 1), (0, 1)]

    See Also
    --------
    read_sparse6, write_sparse6

    References
    ----------
    .. [1] Sparse6 specification
           <https://users.cecs.anu.edu.au/~bdm/data/formats.html>

    r      Nr   z!Expected leading colon in sparse6c                 S   s   g | ]}|d  qS )r   r   )r   cr   r   r   r      s    z&from_sparse6_bytes.<locals>.<listcomp>r   c                  3   s    t  } d}d}	 |dk r!zt| }W n
 ty   Y dS w d}|d8 }||? d@ }|d|> d @ }|}|k rZzt| }W n
 tyI   Y dS w d}|d> | }|d7 }|k s9|| ? }| }||fV  q
)z6Returns stream of pairs b[i], x[i] for sparse6 format.Nr   r   r   )iternextStopIteration)chunksr3   dLenbr   xLenr5   r   r   r   	parseData   s<   
z%from_sparse6_bytes.<locals>.parseDatar   FT)

startswithr   r   nx
MultiGraphadd_nodes_fromr   has_edgeadd_edgeGraph)	stringcharsr2   rC   r   r/   
multigraphr@   r   r   rB   r   r   i   s8   
"

r   c                 C   s2   |dur	|  |} tj| dd} dt| ||S )a  Convert an undirected graph to bytes in sparse6 format.

    Parameters
    ----------
    G : Graph (undirected)

    nodes: list or iterable
       Nodes are labeled 0...n-1 in the order provided.  If None the ordering
       given by ``G.nodes()`` is used.

    header: bool
       If True add '>>sparse6<<' bytes to head of data.

    Raises
    ------
    NetworkXNotImplemented
        If the graph is directed.

    ValueError
        If the graph has at least ``2 ** 36`` nodes; the sparse6 format
        is only defined for graphs of order less than ``2 ** 36``.

    Examples
    --------
    >>> nx.to_sparse6_bytes(nx.path_graph(2))
    b'>>sparse6<<:An\n'

    See Also
    --------
    to_sparse6_bytes, read_sparse6, write_sparse6_bytes

    Notes
    -----
    The returned bytes end with a newline character.

    The format does not support edge or node labels.

    References
    ----------
    .. [1] Graph6 specification
           <https://users.cecs.anu.edu.au/~bdm/data/formats.html>

    Nr+   ordering    )subgraphrE   convert_node_labels_to_integersjoinr6   )r/   r0   r1   r   r   r   r	      s   ,
r	   rb)modec                 C   sF   g }| D ]}|  }t|sq|t| qt|dkr!|d S |S )a  Read an undirected graph in sparse6 format from path.

    Parameters
    ----------
    path : file or string
       File or filename to write.

    Returns
    -------
    G : Graph/Multigraph or list of Graphs/MultiGraphs
       If the file contains multiple lines then a list of graphs is returned

    Raises
    ------
    NetworkXError
        If the string is unable to be parsed in sparse6 format

    Examples
    --------
    You can read a sparse6 file by giving the path to the file::

        >>> import tempfile
        >>> with tempfile.NamedTemporaryFile(delete=False) as f:
        ...     _ = f.write(b">>sparse6<<:An\n")
        ...     _ = f.seek(0)
        ...     G = nx.read_sparse6(f.name)
        >>> list(G.edges())
        [(0, 1)]

    You can also read a sparse6 file by giving an open file-like object::

        >>> import tempfile
        >>> with tempfile.NamedTemporaryFile() as f:
        ...     _ = f.write(b">>sparse6<<:An\n")
        ...     _ = f.seek(0)
        ...     G = nx.read_sparse6(f)
        >>> list(G.edges())
        [(0, 1)]

    See Also
    --------
    read_sparse6, from_sparse6_bytes

    References
    ----------
    .. [1] Sparse6 specification
           <https://users.cecs.anu.edu.au/~bdm/data/formats.html>

    r   r   )stripr&   r-   r   )pathglistliner   r   r   r      s   4r   directedr   wbc                 C   s@   |dur	|  |} tj| dd} t| ||D ]}|| qdS )a  Write graph G to given path in sparse6 format.

    Parameters
    ----------
    G : Graph (undirected)

    path : file or string
       File or filename to write

    nodes: list or iterable
       Nodes are labeled 0...n-1 in the order provided.  If None the ordering
       given by G.nodes() is used.

    header: bool
       If True add '>>sparse6<<' string to head of data

    Raises
    ------
    NetworkXError
        If the graph is directed

    Examples
    --------
    You can write a sparse6 file by giving the path to the file::

        >>> import tempfile
        >>> with tempfile.NamedTemporaryFile(delete=False) as f:
        ...     nx.write_sparse6(nx.path_graph(2), f.name)
        ...     print(f.read())
        b'>>sparse6<<:An\n'

    You can also write a sparse6 file by giving an open file-like object::

        >>> with tempfile.NamedTemporaryFile() as f:
        ...     nx.write_sparse6(nx.path_graph(2), f)
        ...     _ = f.seek(0)
        ...     print(f.read())
        b'>>sparse6<<:An\n'

    See Also
    --------
    read_sparse6, from_sparse6_bytes

    Notes
    -----
    The format does not support edge or node labels.

    References
    ----------
    .. [1] Sparse6 specification
           <https://users.cecs.anu.edu.au/~bdm/data/formats.html>

    Nr+   rN   )rQ   rE   rR   r6   write)r/   rW   r0   r1   r@   r   r   r   r
   =  s   8
r
   )NT)__doc__networkxrE   networkx.exceptionr   networkx.readwrite.graph6r   r   networkx.utilsr   r   __all__r6   _dispatchabler   r	   r   r
   r   r   r   r   <module>   s    R

a
2>
