
    wg,                        d Z ddlmZ ddlZddlmZ ddlmZm	Z	 g dZ
d Z ej                  dd	      d
        Z ed       ed      dd              Z e	dd       ej                  dd	      d               Z ed       ed       e	dd      dd                     Z ed       ed      dd              Zd Zd Zy)a7  Functions for reading and writing graphs in the *graph6* format.

The *graph6* file format is suitable for small graphs or large dense
graphs. For large sparse graphs, use the *sparse6* format.

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

.. _graph6: http://users.cecs.anu.edu.au/~bdm/data/formats.html

    )isliceN)NetworkXError)not_implemented_for	open_file)from_graph6_bytesread_graph6to_graph6_byteswrite_graph6c              #      K   t               }|dk\  rt        d      |rd t        |      D ]%  }t        j	                  t        |dz                '  fdt        d|      D        }t        t        |d            }|rVt        d t        |      D              }t        j	                  t        |dz                t        t        |d            }|rVd	 y
w)a#  Yield bytes in the graph6 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'>>graph6<<'`` 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>graph6 is only defined if number of nodes is less than 2 ** 36
   >>graph6<<?   c              3   X   K   | ]!  }t        |      D ]  }|   |      v   # y wNrange).0jiGnodess      ^/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/networkx/readwrite/graph6.py	<genexpr>z)_generate_graph6_bytes.<locals>.<genexpr>7   s3     K%(KQE!H%(#K#Ks   '*      c              3   2   K   | ]  \  }}|d |z
  z    yw)   N )r   r   bs      r   r   z)_generate_graph6_bytes.<locals>.<genexpr>:   s     8tq!QU
8s      
N)len
ValueError	n_to_datastrencodechrr   listr   sum	enumerate)r   r   headerndbitschunks   ``     r   _generate_graph6_bytesr.      s     * 	AAEzL
 	
 q\ &jjQV%%& LU1a[KDa!E
8y'788jjQV%%VD!_%  Ks   CC!C!T)graphsreturns_graphc                 0  	 	fd}| j                  d      r| dd } | D cg c]  }|dz
  	 c}	t        d 	D              rt        d      t        	      \  }	||dz
  z  d	z  d
z   dz  }t	        	      |k7  r't        d||dz
  z  d	z   dt	        	      dz   d      t        j                         }|j                  t        |             t        d t        d|      D         |             D ]  \  \  }}}|s|j                  ||        |S c c}w )a  Read a simple undirected graph in graph6 format from bytes.

    Parameters
    ----------
    bytes_in : bytes
       Data in graph6 format, without a trailing newline.

    Returns
    -------
    G : Graph

    Raises
    ------
    NetworkXError
        If bytes_in is unable to be parsed in graph6 format

    ValueError
        If any character ``c`` in bytes_in does not satisfy
        ``63 <= ord(c) < 127``.

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

    See Also
    --------
    read_graph6, write_graph6

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

    c               3   >   K   D ]  } dD ]  }| |z	  dz     yw)zUReturns sequence of individual bits from 6-bit-per-value
        list of data values.)r            r   r   r   Nr   )r+   r   datas     r   r,   zfrom_graph6_bytes.<locals>.bitsg   s5       	#A' #Avl"#	#s   r   
   Nr   c              3   &   K   | ]	  }|d kD    yw)r   Nr   )r   cs     r   r   z$from_graph6_bytes.<locals>.<genexpr>r   s     
 a1r6
 s   z.each input character must be in range(63, 127)r   r5   r   r   z	Expected z bits but got z
 in graph6c              3   D   K   | ]  }t        |      D ]  }||f 
  y wr   r   )r   r   r   s      r   r   z$from_graph6_bytes.<locals>.<genexpr>~   s$     HQuQxH!1a&H&Hs    )
startswithanyr!   	data_to_nr    r   nxGraphadd_nodes_fromr   zipadd_edge)
bytes_inr,   r9   r*   ndr   r   r   r   r6   s
            @r   r   r   @   s#   N# =)BC=$%qAF%D

 4
  IJJoGAt
q1u+
Q
1	$B
4yBQUq()D	AjQ
 	
 	
AU1XH%1+H$&Q 	AJJq! H# &s   Ddirected
multigraphc                     || j                  |      } t        j                  |       }t        |j	                               }dj                  t        |||            S )a_  Convert a simple undirected graph to bytes in graph6 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 '>>graph6<<' bytes to head of data.

    Raises
    ------
    NetworkXNotImplemented
        If the graph is directed or is a multigraph.

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

    Examples
    --------
    >>> nx.to_graph6_bytes(nx.path_graph(2))
    b'>>graph6<<A_\n'

    See Also
    --------
    from_graph6_bytes, read_graph6, write_graph6_bytes

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

    The format does not support edge or node labels, parallel edges or
    self loops. If self loops are present they are silently ignored.

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

        )subgraphr>   convert_node_labels_to_integerssortedr   joinr.   )r   r   r)   Hs       r   r	   r	      sR    ^ JJu
**1-A1779E88*1eV<==rH   rb)modec                     g }| D ]8  }|j                         }t        |      s|j                  t        |             : t        |      dk(  r|d   S |S )a  Read simple undirected graphs in graph6 format from path.

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

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

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

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

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

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

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

    See Also
    --------
    from_graph6_bytes, write_graph6

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

    r   r   )stripr    appendr   )pathglistlines      r   r   r      s[    h E .zz|4y&t,-	.
 5zQQxrH   r   wbc                      t        | |||      S )a  Write a simple undirected graph to a path in graph6 format.

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

    path : str
       The path naming the file to which to write the graph.

    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 '>>graph6<<' string to head of data

    Raises
    ------
    NetworkXNotImplemented
        If the graph is directed or is a multigraph.

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

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

        >>> import tempfile
        >>> with tempfile.NamedTemporaryFile(delete=False) as f:
        ...     nx.write_graph6(nx.path_graph(2), f.name)
        ...     _ = f.seek(0)
        ...     print(f.read())
        b'>>graph6<<A_\n'

    See Also
    --------
    from_graph6_bytes, read_graph6

    Notes
    -----
    The function writes a newline character after writing the encoding
    of the graph.

    The format does not support edge or node labels, parallel edges or
    self loops.  If self loops are present they are silently ignored.

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

    )r   r)   )write_graph6_file)r   rS   r   r)   s       r   r
   r
      s    t QE&AArH   c                     || j                  |      } t        j                  |       }t        |j	                               }t        |||      D ]  }|j                  |        y)a  Write a simple undirected graph to a file-like object in graph6 format.

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

    f : file-like object
       The file 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 '>>graph6<<' string to head of data

    Raises
    ------
    NetworkXNotImplemented
        If the graph is directed or is a multigraph.

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

    Examples
    --------
    You can write a graph6 file by giving an open file-like object::

        >>> import tempfile
        >>> with tempfile.NamedTemporaryFile() as f:
        ...     nx.write_graph6(nx.path_graph(2), f)
        ...     _ = f.seek(0)
        ...     print(f.read())
        b'>>graph6<<A_\n'

    See Also
    --------
    from_graph6_bytes, read_graph6

    Notes
    -----
    The function writes a newline character after writing the encoding
    of the graph.

    The format does not support edge or node labels, parallel edges or
    self loops.  If self loops are present they are silently ignored.

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

    N)rI   r>   rJ   rK   r   r.   write)r   fr   r)   rM   r   s         r   rX   rX   8  s\    r JJu
**1-A1779E#Auf5 	
rH   c                     | d   dk  r
| d   | dd fS | d   dk  r| d   dz  | d   dz  z   | d   z   | d	d fS | d   d
z  | d   dz  z   | d	   dz  z   | d   dz  z   | d   dz  z   | d   z   | dd fS )zpRead initial one-, four- or eight-unit value from graph6
    integer sequence.

    Return (value, rest of seq.)r   >   r   N   r5   r   r4   r3            r         r   )r6   s    r   r=   r=   y  s    
 Aw"}AwQR  Aw"}Q2$q'Q,/$q'948CC	aB7b=	7b=	 7b=	 7a<		
 q'	 	QR rH   c           	          | dk  r| gS | dk  rd| dz	  dz  | dz	  dz  | dz  gS dd| dz	  dz  | dz	  dz  | dz	  dz  | dz	  dz  | dz	  dz  | dz  gS )	zConvert an integer to one-, four- or eight-unit graph6 sequence.

    This function is undefined if `n` is not in ``range(2 ** 36)``.

    r]   i r   r^   r   r_   r`   ra   r   )r*   s    r   r"   r"     s     	Bws
	
fQ"W$qAvoq4x@@ "W"W"W"W!VtOH	
 		
rH   )NT)__doc__	itertoolsr   networkxr>   networkx.exceptionr   networkx.utilsr   r   __all__r.   _dispatchabler   r	   r   r
   rX   r=   r"   r   rH   r   <module>rl      s  	   , 9
Q&R T2A 3AH Z \"1> # !1>h 14T2; 3 ;| Z \"
147B  # !7Bt Z \"< # !<~(
rH   