a
    Sicg                    @   s  d Z ddlmZmZ ddlmZmZmZmZ ddl	m
Z
mZ ddlmZmZmZ ddlZddlZddlZddlmZ dd	lmZ d
ZzddlmZ eZeZW nB ey   dZddlmZmZ  e!Zddl"m#Z# e#Ze$Ze%Z&Y n0 ddl'Z'e'j(Z)['dZ*e+Z,G dd de-Z.eddZ/dvddZ0dwddZ1dxddZ2dyddZ3dzddZ4dd Z5d d! Z6d"d# Z7d$d% Z8d&d' Z9d(d) Z:d*d+ Z;d,d- Z<d.d/ Z=d{d0d1Z>d2d3 Z?d4d5 Z@d6d7 ZAd8d9 ZBd:d; ZCd<d= ZDd>d? ZEd@dA ZFdBdC ZGd|dDdEZHd}dFdGZIdHdI ZJdJdK ZKdLdM ZLd~dNdOZMdPdQ ZNdRdS ZOdTdU ZPeQdVeRejS dW ZTdXdY ZUdZd[ ZVd\d] ZWdd^d_ZXd`da ZYdbdc ZZddde Z[dfdg Z\dhdi Z]djdk Z^dldm Z_G dndo doZ`G dpdq dqeaZbG drds dsZcG dtdu dueaZddS )zQR Code and Micro QR Code encoder.

DOES NOT belong to the public API.

"QR Code" and "Micro QR Code" are registered trademarks of DENSO WAVE INCORPORATED.
    )absolute_importdivision)
itemgettergtltxor)partialreduce)islicechainproductN)
namedtuple   )constsF)zip_longestT)izip_longestimap)Number)encodeencode_sequenceDataOverflowErrorc                   @   s   e Zd ZdZdS )r   ab      Indicates a problem that the provided data does not fit into the
    provided QR Code version or the data is too large in general.

    This exception is inherited from :py:exc:`ValueError` and is only raised
    if the data does not fit into the provided (Micro) QR Code version.

    Basically it is sufficient to catch a :py:exc:`ValueError`.
    N)__name__
__module____qualname____doc__ r   r   I/var/www/html/django/DPS/env/lib/python3.9/site-packages/segno/encoder.pyr   /   s   r   Codez"matrix version error mask segmentsc	                 C   sf  t |}|s0|dur0|tjv r0tdt||rX|durX|tjvrXtdt|t|dd}t|}|dur|durt||stdt	|t||tj
kr|s|tjv rtd|r|s|tjv rtdt| ||}	t|	|||d	}
|du r|
}n"|
|kr&td
t|t|
|du rB|tjkrBtj}|dk }t||}t|	|||||S )a      Creates a (Micro) QR code.

    See :py:func:`segno.make` for a detailed description of the parameters.

    Contrary to ``make`` this function returns a named tuple:
    ``(matrix, version, error, mask, segments)``

    Note that ``version`` is always an integer referring
    to the values of the :py:mod:`segno.consts` constants. ``error`` is ``None``
    iff a M1 QR Code was generated, otherwise it is always an integer.

    :rtype: namedtuple
    NzJA Micro QR Code version ("{0}") is provided but parameter "micro" is Falsez#Illegal Micro QR Code version "{0}"Taccept_nonez,Mode "{0}" is not available in version "{1}"z>Error correction level "H" is not available for Micro QR Codesz0The ECI mode is not available for Micro QR CodesecimicrozHThe provided data does not fit into version "{0}". Proposal: version {1}r   )normalize_versionr   MICRO_VERSIONS
ValueErrorformatget_version_namenormalize_errorlevelnormalize_modeis_mode_supportedget_mode_nameERROR_LEVEL_Hprepare_datafind_versionr   
VERSION_M1ERROR_LEVEL_Lnormalize_mask_encode)contenterrorversionmodemaskencodingr!   r"   boost_errorsegmentsguessed_versionis_micror   r   r   r   >   sD    


r   c	                    sD  fdddd }	dddfd	d
}
t 			durZ	dk rjtdt	n|du rjtd|durd|  krdksn tdtdddu rtjttddt	| }d}|du r4zt
|dd}W n ty    Y n0 |r4|	p|kr4t|	p&| dgS t|jdkrLtd|jd tjkrjt| } |durt| |k rtd|t| }|pd}	dur|
| 	}|dkrtd	|	| |}|dur
t|td}t
|ddd	ttt|d |d 	fddt|D S )z    EXPERIMENTAL: Creates a sequence of QR codes in Structured Append mode.

    :return: Iterable of named tuples, see :py:func:`encode` for details.
    c                    s   t  }|t| | d |S )z;        Creates a Segments sequence with one item.
        )r6   r8   )Segmentsadd_segmentmake_segment)chunkr6   segsr8   r   r   one_item_segmentsv   s    z*encode_sequence.<locals>.one_item_segmentsc                    s,   t t |\ fddt|D S )Nc                    s<   g | ]4} | t | |d   t |d    qS )r   )min.0idatakmr   r   
<listcomp>       z?encode_sequence.<locals>.divide_into_chunks.<locals>.<listcomp>)divmodlenrange)rI   numr   rH   r   divide_into_chunks~   s    z+encode_sequence.<locals>.divide_into_chunksNFc           
      S   s   d}|t j| | 7 }|r>|t jkr>|t jkr>|d7 }|d7 }|rJ|d7 }d}|t jkrt| d\}}	||d |	dkrzdnd 7 }nf|t jkrt| d	\}}	||d
 |	rdnd 7 }n4|t jkr|| d 7 }n|t jt jfv r|| d 7 }|| S )N         r      
   r                  )	r   CHAR_COUNT_INDICATOR_LENGTH	MODE_BYTEDEFAULT_BYTE_ENCODINGMODE_NUMERICrN   MODE_ALPHANUMERIC
MODE_KANJI
MODE_HANZI)

char_count	ver_ranger6   r8   is_eciis_saoverheadbitsrQ   	remainderr   r   r   calc_qrcode_bit_length   s&    


z/encode_sequence.<locals>.calc_qrcode_bit_lengthc           	         sz   t | }t|} |||dd}tj| | }tt|| }|d|d  r`d|d  nd 7 }tt|| S )zH        Returns the number of symbols for the provided version.
        T)rf   rg   rU   r      r   )rO   version_ranger   SYMBOL_CAPACITYintmathceil)	r3   r5   r4   r6   lengthre   
bit_lengthcapacitycnt)rk   r!   r8   r   r   number_of_symbols_by_version   s    
$z5encode_sequence.<locals>.number_of_symbols_by_versionr   zEThis function does not accept Micro QR Code versions. Provided: "{0}"z;Please provide either a QR Code version or the symbol count   z)The symbol count must be in range 1 .. 16Tr   )r<   r    )r4   r5   r7   r!   r9   z<This function cannot handle more than one mode (yet). Sorry.r   z=The content is not long enough to be divided into {0} symbolsz8The data does not fit into Structured Append version {0})key)r!   r"   rg   )totalparityc                    s0   g | ](\}}t | |d qS ))r4   r5   r7   r!   r9   sa_info)r2   )rF   rG   r@   )r9   r!   r4   r7   r6   rC   r{   r5   r   r   rL      s
   z#encode_sequence.<locals>.<listcomp>)NFF)r#   r%   r&   r'   r(   r   r0   r)   r1   r-   r.   r   r2   rO   modesr`   strcalc_structured_append_paritymaxr   _StructuredAppendInfo	enumerate)r3   r4   r5   r6   r7   r8   r!   r9   symbol_countrR   rv   r:   r;   Zsa_parity_dataZnum_symbolschunksr   )
r9   rk   r!   r8   r4   r7   r6   rC   r{   r5   r   r   n   sn      







r   c                 C   s>  |dk }|du}t  }	|}
|}|s.d}
t|}|rDt||| ||d}|rt|dd D ]}|	|d qT|	|jd | D ]}t|	||
|| qxtj| | }t|	||
t	|	 t
|	|t	|	 t|	||t	|	 t|||	}	t|}t|| t|| t||	| t||||\}}t|||| t|| t||||| S )z    Creates a (Micro) QR code.

    NOTE: This function does not check if the input is valid and does not belong
    to the public API.
    r   Nrg   rV   rS   rT   )Bufferrm   boost_error_levelappend_bitsrz   write_segmentr   rn   write_terminatorrO   write_padding_bitswrite_pad_codewordsmake_final_messagemake_matrixadd_finder_patternsadd_alignment_patternsadd_codewordsfind_and_apply_best_maskadd_format_infoadd_version_infor   )r:   r4   r5   r7   r!   r9   r{   r<   Zsa_modebuffverre   rG   segmentrt   matrixr   r   r   r2      s:    


r2   c                 C   s   |t jdfvrt|dkrt jt jt jt jg}| dk rP|  | t jk rP|  |j| ||d}||	|d d D ] }t j
|  | |kr|}qv qqv|S )a      Increases the error correction level if possible.

    Returns either the provided or a better error correction level which works
    while keeping the (Micro) QR Code version.

    :param int version: Version constant.
    :param int|None error: Error level constant or ``None``
    :param Segments segments: Instance of :py:class:`Segments`
    :param bool eci: Indicates if ECI designator should be written.
    :param bool is_sa: Indicates if Structured Append mode is used.
    Nr   r   )r   r,   rO   r0   ZERROR_LEVEL_MERROR_LEVEL_Qpop
VERSION_M4bit_length_with_overheadindexrn   )r5   r4   r:   r!   rg   levelsZdata_lengthZerror_levelr   r   r   r     s    
r   c                 C   s   |j }| j}|rB|tjkrB|jtjkrB|tjd |t|jd |du rn||d |tjkrd}||d n|tj	kr|tj
| |d  ||jtj| |  | |j dS )a      Writes a segment.

    :param buff: The byte buffer.
    :param _Segment segment: The segment to serialize.
    :param ver: ``None`` if a QR Code is written, "M1", "M2", "M3", or "M4" if a
            Micro QR Code is written.
    :param ver_range: "M1", "M2", "M3", or "M4" if a Micro QR Code is written,
            otherwise a constant representing a range of QR Code versions.
    rS   rT   Nr   rV   )r6   r   r   r^   r8   r_   ZMODE_ECIget_eci_assignment_numberrc   r/   ZMODE_TO_MICRO_MODE_MAPPINGrd   r]   extendri   )r   r   r   re   r!   r6   r   subsetr   r   r   r   0  s$    



r   c                 C   s$   |  dgt|| tj|   dS )a      Writes the terminator.

    :param buff: The byte buffer.
    :param capacity: Symbol capacity.
    :param ver: ``None`` if a QR Code is written, "M1", "M2", "M3", or "M4" if a
            Micro QR Code is written.
    :param length: Length of the data bit stream.
    r   N)r   rD   r   ZTERMINATOR_LENGTH)r   rt   r   rr   r   r   r   r   O  s    r   c                 C   s,   |t jt jfvr(| dgd|d    dS )z    Writes padding bits if the data stream does not meet the codeword boundary.

    :param buff: The byte buffer.
    :param int length: Data stream length.
    r   rT   N)r   r/   
VERSION_M3r   )r   r5   rr   r   r   r   r   ]  s    r   c                 C   s\   | j }|tjtjfv r*|dg||   n.d}t|d |d  D ]}|||d   qBdS )a=      Writes the pad codewords iff the data does not fill the capacity of the
    symbol.

    :param buff: The byte buffer.
    :param int version: The (Micro) QR Code version.
    :param int capacity: The total capacity of the symbol (incl. error correction)
    :param int length: Length of the data bit stream.
    r   ))r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   rT   rY   N)r   r   r/   r   rP   )r   r5   rt   rr   writeZpad_codewordsrG   r   r   r   r   p  s    r   c           
      C   s   d}ddt | d fdf}|r"d}td}|D ]^\}}|dkrBdnd}|dkrRdnd}|D ]0}	|||	  ||d  | ||	  ||d < qZq.dS )	a      Adds the finder pattern(s) with the separators to the matrix.

    QR Codes get three finder patterns, Micro QR Codes have just one finder
    pattern.

    ISO/IEC 18004:2015(E) -- 6.3.3 Finder pattern (page 16)
    ISO/IEC 18004:2015(E) -- 6.3.4 Separator (page 17)

    :param matrix: The matrix.
    :param bool is_micro: Indicates if the matrix represents a Micro QR Code.
    )		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   r   	r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rT   )r   )r   r   NrO   rP   )
r   r<   patterncornersZfinder_rangerG   joffsetZ	sepoffsetrr   r   r   r     s    	r   c                 C   s`   |rdt | fndt | d f\}}| | }d}td|D ] }|| | |< |||< |dN }q:dS )a4      Adds the (horizontal and vertical) timinig pattern to the provided `matrix`.

    ISO/IEC 18004:2015(E) -- 6.3.5 Timing pattern (page 17)

    :param matrix: Matrix to add the timing pattern into.
    :param bool is_micro: Indicates if the timing pattern for a Micro QR Code
        should be added.
    r   r[   rT   r   Nr   )r   r<   r   stopcolbitrG   r   r   r   add_timing_pattern  s    
$r   c                 C   s   |dk rdS d}t j|d  }td}|d }|d }||f||f||ff}t|ddD ]^\}}	||	f|v rnqX|d |	d  }
}|D ]0}||d |d d  | |
|  ||d < qqXdS )z    Adds the adjustment patterns to the matrix. For versions < 2 this is a
    no-op.

    ISO/IEC 18004:2015(E) -- 6.3.6 Alignment patterns (page 17)
    ISO/IEC 18004:2015(E) -- Annex E Position of alignment patterns (page 83)
    rY   N)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   )repeat)r   ZALIGNMENT_POSrP   r   )r   r5   r   	positionsZalignment_rangemin_posmax_posZfinder_positionsxyrG   r   r   r   r   r   r     s    r   c                 C   s  t | }|dk }|tjtjfvr$dnd}d}t |}td}t|d ddD ]}	|sd|	dkrd|	d8 }	t|D ]z}
|D ]p}|	| }|	| d@ dk}|s||dk N }|r|d |
 n|
}| | }|| dkrt||k rt|| ||< |d7 }qtqlqL|t |krtd|t |dS )a7      Adds the codewords (data and error correction) to the provided matrix.

    ISO/IEC 18004:2015(E) -- 7.7.3 Symbol character placement (page 46)

    :param matrix: The matrix to add the codewords into.
    :param codewords: Sequence of bits
    :param int version: The (Micro) QR Code version constant.
    r   r   rY   r[   zMInternal error: Adding codewords to matrix failed. Added {0} of {1} codewordsN)rO   r   r/   r   rP   r%   r&   )r   	codewordsr5   matrix_sizer<   incidxZcodeword_lengthZ	range_tworightverticalzr   ZupwardsrG   rowr   r   r   r     s0    
r   c           
   
   C   s   ddd}t j|  | }t||\}}d}| t jt jfv rR||d dd? d}t }|tt	|dd	 t
t| D   |dur|| |tt	|d
d	 t
t| D   d}	| dv rd}	n| dv rd}	n| dv rd}	|d|	  |S )ad      Constructs the final message (codewords incl. error correction).

    ISO/IEC 18004:2015(E) -- 7.6 Constructing the final message codeword sequence (page 45)

    :param int version: (Micro) QR Code version constant.
    :param int error: Error level constant.
    :param buff: Byte buffer.
    :return: Byte buffer representing the final message.
    rT   c                    s    fddt t|D S )Nc                 3   s   | ]} |? d @ V  qdS r   Nr   rE   valr   r   	<genexpr>  rM   z8make_final_message.<locals>.to_binary.<locals>.<genexpr>)reversedrP   )r   rr   r   r   r   	to_binary  s    z%make_final_message.<locals>.to_binaryNr   r   rS   c                 s   s   | ]}|d ur|V  qd S Nr   rF   r   r   r   r   r   !  rM   z%make_final_message.<locals>.<genexpr>c                 s   s   | ]}|d ur|V  qd S r   r   r   r   r   r   r   %  rM   )rY   rV   rS   r   r[   rX   )      rw            rU                   !   "   rV   )                         )rT   )r   ZECCmake_blocksr/   r   r   r   r   r   mapfrom_iterabler   )
r5   r4   r   r   ec_infosdata_blockserror_blocksZcw_fourresrj   r   r   r   r     s(    
(
(r   c                 C   s  |  }g g  }}|j}|j}tj}tj}| D ]}	|	j|	j }
tj|
 }t|
}t|	j	D ]}t
t||	j}|| t|}t
|}|dg|
  t|D ]J}|| }|dkr|| }|D ](}||| d   ||||   N  < qq|||d  qZq.||fS )z{    Returns the data and error blocks.

    :param ec_infos: Iterable of ECC information
    :param buff: Byte buffer.
    r   r   N)tointsappendr   Z
GALIOS_LOGZ
GALIOS_EXPZ	num_totalZnum_dataZGEN_POLYrP   
num_blocks	bytearrayr
   rO   r   )r   r   r   r   r   Zappend_data_blockZappend_error_blockZgen_logZgen_expZec_infoZnum_error_wordsgenZrange_error_wordsrG   blockZlen_dataZerror_blockrJ   coefZlcoefnr   r   r   r   7  s0    

(r   c                    s   t | }t}t}t}|r$t}d}t}t| t | t | |sPd d d<  fdd}t	|}	|durt
| |	| || || fS d}
t|	D ]H\}}dd	 | D }t
|||| |||}|||r|}|}t|}
q||
fS )
a      Applies all mask patterns against the provided QR Code matrix and returns
    the best matrix and best pattern.

    ISO/IEC 18004:2015(E) -- 7.8.2 Data mask patterns (page 50)
    ISO/IEC 18004:2015(E) -- 7.8.3 Evaluation of data masking results (page 53)
    ISO/IEC 18004:2015(E) -- 7.8.3.1 Evaluation of QR Code symbols (page 53/54)
    ISO/IEC 18004:2015(E) -- 7.8.3.2 Evaluation of Micro QR Code symbols (page 54/55)

    :param matrix: A matrix.
    :param int version: A version (Micro) QR Code version constant.
    :param bool is_micro: Indicates if the matrix represents a Micro QR Code
    :param proposed_mask: Optional int to indicate the preferred mask.
    :rtype: tuple
    :return: A tuple of the best matrix and best data mask pattern index.
    r   r   r   rT   c                    s    |  | dkS )Nr   r   rG   r   Zfunction_matrixr   r   is_encoding_region  s    z4find_and_apply_best_mask.<locals>.is_encoding_regionNc                 S   s   g | ]}|d d  qS r   r   )rF   bar   r   r   rL     rM   z,find_and_apply_best_mask.<locals>.<listcomp>)rO   r   _MAX_PENALTY_SCOREevaluate_maskr   evaluate_micro_maskr   r   r   get_data_mask_functions
apply_maskr   tuple)r   r5   r<   Zproposed_maskr   	is_better
best_scoreZ	eval_maskr   Zmask_patternsZbest_matrixZmask_numbermask_patternrK   scoreZbest_patternr   r   r   r   Y  s<    




r   c                 C   sH   t |}|D ]6}| | }|D ]$}|||r||  |||N  < qqdS )a      Applies the provided mask pattern on the `matrix`.

    ISO/IEC 18004:2015(E) -- 7.8.2 Data mask patterns (page 50)

    :param tuple matrix: A tuple of bytearrays
    :param mask_pattern: A mask pattern (a function)
    :param int matrix_size: width or height of the matrix
    :param is_encoding_region: A function which returns ``True`` iff the
            row index / col index belongs to the data region.
    N)rP   )r   r   r   r   module_rangerG   r   r   r   r   r   r     s    
r   c                 C   s   t t| |S )a!      Evaluates the provided `matrix` of a QR code.

    ISO/IEC 18004:2015(E) -- 7.8.3 Evaluation of data masking results (page 53)

    :param matrix: The matrix to evaluate
    :param matrix_size: The width (or height) of the matrix.
    :return int: The penalty score of the matrix.
    )summask_scores)r   r   r   r   r   r     s    
r   c                    s  t d fdd}d}d}d}t }d}d}t  }	|D ]4}
| |
 }d}d}d}d}|D ]}|| }| | |
 }||	|< ||7 }||kr|d7 }n|dkr||d	 7 }d}||kr|d7 }n|dkr||d	 7 }d}|r$|r$||  kr||   kr||d  kr$n n|d
7 }|}|}q`|}|||7 }|||	7 }|dkr`||d	 7 }|dkr>||d	 7 }q>t| d	  }dtt|d d d  }||||fS )u      Returns the penalty score features of the matrix.

    The returned value is a tuple of all penalty scores (N1, N2, N3, N4).
    Use :py:func:`evaluate_mask` for a single value (sum of all scores).


    ISO/IEC 18004:2015(E) -- 7.8.3 Evaluation of data masking results - Table 11 (page 54)

    ============================================   ====================================   ===============
    Feature                                        Evaluation condition                   Points
    ============================================   ====================================   ===============
    Adjacent modules in row/column in same color   No. of modules = (5 + i)               N1 + i
    Block of modules in same color                 Block size = m × n                     N2 ×(m-1)×(n-1)
    1 : 1 : 3 : 1 : 1 ratio                        Existence of the pattern               N3
    (dark:light:dark:light:dark) pattern in
    row/column, preceded or followed by light
    area 4 modules wide
    Proportion of dark modules in entire symbol    50 × (5 × k)% to 50 × (5 × (k + 1))%   N4 × k
    ============================================   ====================================   ===============

    N1 = 3
    N2 = 3
    N3 = 40
    N4 = 10

    :param matrix: The matrix to evaluate
    :param matrix_size: The width (or height) of the matrix.
    :return tuple: A tuple of penalty scores (ints): ``(n1, n2, n3, n4)``.
    )r   r   r   r   r   r   r   c                    s   d}|  }|dkr|d }|d d fv snt| t|d dt|  rnt| t|dt|d   sx|d7 }n|d }|  |}q|S )Nr   r   rX   rS   (   )findanyr   rD   )seqcountr   r   r   Z
n3_patternr   r   n3_pattern_occurrences  s    

z+mask_scores.<locals>.n3_pattern_occurrencesr   Nr   r   r   rY   rV   rW   d   2   )r   rP   floatro   abs)r   r   r  Zscore_n1Zscore_n2Zscore_n3r   Zdark_module_counterlast_rowZ	n3_columnrG   r   Zrow_prev_bitZcol_prev_bitZn1_row_counterZn1_col_counterr   Zrow_current_bitZcol_current_bitpercentZscore_n4r   r  r   r     sX    


@
r   c                    s^   t d|}d  tfdd|D }t fdd|D }||krR|d | S |d | S )a*      Evaluates the provided `matrix` of a Micro QR code.

    ISO/IEC 18004:2015(E) -- 7.8.3.2 Evaluation of Micro QR Code symbols (page 54)

    :param matrix: The matrix to evaluate
    :param matrix_size: The width (or height) of the matrix.
    :return int: The penalty score of the matrix.
    r   r   c                 3   s   | ]} | d  V  qdS )r   Nr   rE   )r   r   r   r   /  rM   z&evaluate_micro_mask.<locals>.<genexpr>c                 3   s   | ]} | V  qd S r   r   rE   )r  r   r   r   0  rM   rw   )rP   r   )r   r   r   Zsum1sum2r   )r  r   r   r   #  s
    

r   c                 C   sv   |}| dkrR|t jkr |d7 }n&|t jkr4|d7 }n|t jkrF|d7 }t j| }n |t j|  | d> 7 }t j| }|S )uz      Returns the format information for the provided error level and mask patttern.

    ISO/IEC 18004:2015(E) -- 7.9 Format information (page 55)
    ISO/IEC 18004:2015(E) -- Table C.1 — Valid format information bit sequences (page 80)

    :param int version: Version constant
    :param int error: Error level constant.
    :param int mask_pattern: Mask pattern number.
    r   rT   rw   r   rY   )r   r0   r,   r   ZFORMAT_INFOZERROR_LEVEL_TO_MICRO_MAPPINGZFORMAT_INFO_MICRO)r5   r4   r   fmtformat_infor   r   r   calc_format_info4  s    





r  c                 C   s   |dk }t |||}t|}|}| d }tdD ]t}	||	? d@ }
|d|	 ? d@ }|	dkrh|sh|d7 }d}|
| |	|  d< |||	| < |s0|
|d|	 < || d|	  d< q0|sd| d d< dS )a      Adds the format information into the provided matrix.

    ISO/IEC 18004:2015(E) -- 7.9 Format information (page 55)
    ISO/IEC 18004:2015(E) -- 7.9.1 QR Code symbols
    ISO/IEC 18004:2015(E) -- 7.9.2 Micro QR Code symbols

    :param matrix: The matrix.
    :param int version: Version constant
    :param int error: Error level constant.
    :param int mask_pattern: Mask pattern number.
    r   rT   r   r[   r   r   N)r  ro   rP   )r   r5   r4   r   r<   r  voffsetZhoffset	row_eightrG   ZvbitZhbitr   r   r   r   N  s$    %r   c                 C   s   |dk rdS t j|d  }tdD ]}||d ? d@ }||d d ? d@ }||d d ? d@ }|| d |< || d |< || d	 |< | | }||d< ||d< ||d	< q"dS )
z    Adds the version information to the matrix, for versions < 7 this is a no-op.

    ISO/IEC 18004:2015(E) -- 7.10 Version information (page 58)
    rX   Nr[   rV   r   rY   )r   ZVERSION_INFOrP   )r   r5   version_inforG   Zbit1Zbit2Zbit3r   r   r   r   r     s    r   c           	      C   s   t  }|j}t| tttfr0|t| || |S | D ]f}|||  }}}t|tr|d }t|dkrr|d pp|}t|dkr|d p|}|t||| q4|S )a      Returns an iterable of `Segment` instances.

    If `content` is a string, an integer, or bytes, the returned tuple will
    have a single item. If `content` is a list or a tuple, a tuple of
    `Segment` instances of the same length is returned.

    :param content: Either a string, bytes, an integer or an iterable.
    :type content: str, bytes, int, tuple, list or any iterable
    :param mode: The global mode. If `content` is list/tuple, the `Segment`
            instances may have a different mode.
    :param encoding: The global encoding. If `content` is a list or a tuple,
            the `Segment` instances may have a different encoding.
    :rtype: Segments
    r   r   rY   )	r=   r>   
isinstancestr_typebytesnumericr?   r   rO   )	r3   r6   r8   r:   r>   itemZseg_contentZseg_modeZseg_encodingr   r   r   r-     s    
r-   c                 C   s   t | tr| t| |ptjfS t| } |dur:| |} n^ztj}| |} W nH ty   ztj}| |} W n  ty   d}| |} Y n0 Y n0 | t| |fS )a      Converts the provided data into bytes. If the data is already a byte
    sequence, it will be left unchanged.

    This function tries to use the provided `encoding` (if not ``None``)
    or the default encoding (ISO/IEC 8859-1). It uses UTF-8 as fallback.

    Returns the (byte) data, the length of the data and the encoding of the data.

    :param data: The data to encode
    :type data: str or bytes
    :param encoding: str or ``None``
    :rtype: tuple: data, data length, encoding
    Nutf-8)	r  r  rO   r   r_   r}   r   UnicodeErrorZKANJI_ENCODING)rI   r8   r   r   r   data_to_bytes  s     
r  c                 C   s.  |t jkrt j}t| |\}}}|}|t jkr6t|nt j}|durl||k rptdt|t	|t|n|}|t jkr~d}|t j
t jfvr|n|d }t }	|	j}
|t jkrtd|dD ].}|||d  }|
t|t|d d  qn,|t jkrlt jj}td|dD ]V}|||d  }t|dkrV|
||d d ||d  d n|
||d	 qn|t jkrtrd
d |D }|D ]}|
|d qnv|t jkrhtrdd |D }td|dD ]}|| d> ||d  B }d|  krdkrn n
|d }n4d|  kr,dkr:n n
|d }ntd||
|d? d |d@  d qntr|dd |D }td|dD ]}|| d> ||d  B }d|  krdkrn n
|d }n4d|  krdkrn n
|d }ntd||
|d? d |d@  d qt|	 |||S ) z    Creates a :py:class:`Segment`.

    :param data: The segment data
    :param mode: The mode.
    :param encoding: The encoding.
    :rtype: _Segment
    Nz@The provided mode "{0}" is not applicable for {1}. Proposal: {2}rY   r   rV   r   -   rZ   r[   c                 s   s   | ]}t |V  qd S r   ordrF   br   r   r   r   7  rM   zmake_segment.<locals>.<genexpr>rT   c                 S   s   g | ]}t |qS r   r   r"  r   r   r   rL   =  rM   z make_segment.<locals>.<listcomp>i  i  i  i  i  zInvalid Hanzi bytes: {0}`      r\   c                 S   s   g | ]}t |qS r   r   r"  r   r   r   rL   R  rM   @    @    i@  zInvalid Kanji bytes: {0}   )r   rc   ZHANZI_ENCODINGr  r^   	find_moder%   r&   r+   reprrb   r   r   r`   rP   ro   rO   ra   ALPHANUMERIC_CHARSr  _PY2_Segmentgetbits)rI   r6   r8   Zsegment_dataZsegment_lengthZsegment_encodingZsegment_modeZguessed_moderd   r   r   rG   r@   Zto_byter#  codediffr   r   r   r?     sp    	


 $

 

r?   c                    s   t | }dg|  t fddt|D }|r| dkrtdD ]H}||  d d< d d< d d< d|d |< d|d |< d|d |< q@|d	 }td
D ]8}d|| d	< d||< | dkrd||  d	< d|| < q|rt|| dk  |S )a3      Creates a matrix of the provided `size` (w x h) initialized with the
    (illegal) value 0x2.

    The "timing pattern" is already added to the matrix and the version
    and format areas are initialized with 0x0.

    :param int version: The (Micro) QR Code version
    :rtype: tuple of bytearrays
    rY   c                 3   s   | ]}t  V  qd S r   )r   rE   r   r   r   r   s  rM   zmake_matrix.<locals>.<genexpr>r[   r   r  r  r  rT   	   r   )calc_matrix_sizer   rP   r   )r5   Zreserve_regionsZ
add_timingsizer   rG   r  r   r3  r   r   f  s.    
r   c                 C   s   | du rdS d}zt | } | dk }W nD ttfyh   ztj|   } W n ttfyb   d}Y n0 Y n0 |sd|   k rdk sn | tjvrtd	| d
ttj | S )	a      Canonicalization of the provided `version`.

    If the `version` is ``None``, this function returns ``None``. Otherwise
    this function checks if `version` is an integer or a Micro QR Code version.
    In case the string represents a Micro QR Code version, an uppercased
    string identifier is returned.

    If the `version` does not represent a valid version identifier (aside of
    ``None``) a :py:exc:`ValueError` is raised.

    :param version: An integer, a string or ``None``.
    :raises: :py:exc:`ValueError`: In case the version is not ``None`` and does not
                represent a valid (Micro) QR Code version.
    :rtype: int, str or ``None``
    NFr   Tr   )   z5Unsupported version "{0}". Supported: {1} and 1 .. 40, )ro   r%   	TypeErrorr   MICRO_VERSION_MAPPINGupperKeyErrorAttributeErrorr$   r&   joinsortedkeys)r5   r4   r   r   r   r#     s     $r#   c                 C   sf   | du s| t j v r| S zt j|   W S  ttfy`   td| dt	t j
 Y n0 dS )a      Returns a (Micro) QR Code mode constant which is equivalent to the
    provided `mode`.

    In case the provided `mode` is ``None``, this function returns ``None``.
    Otherwise a mode constant is returned unless the provided parameter cannot
    be mapped to a valid mode. In the latter case, a :py:exc:`ValueError` is raised.

    :param mode: An integer or string or ``None``.
    :raises: :py:exc:`ValueError` In case the provided `mode` does not represent a valid
             QR Code mode.
    :rtype: int or None
    Nz)Illegal mode "{0}". Supported values: {1}r8  )r   MODE_MAPPINGvalueslowerr<  r=  r%   r&   r>  r?  r@  )r6   r   r   r   r)     s    r)   c                 C   s   | du rdS zt | } W n  ty8   td| Y n0 |rdd|   krRdk sn td| n$d|   krxdk sn td| | S )a      Normalizes the (user specified) mask.

    :param mask: A mask constant
    :type mask: int or None
    :param bool is_micro: Indicates if the mask is meant to be used for a
            Micro QR Code.
    :raises: :py:exc:`ValueError` in case of an invalid mask.
    :rtype: int
    NzZInvalid data mask "{0}". Must be an integer or a string which represents an integer value.r   rS   zBInvalid data mask "{0}" for Micro QR Code. Must be in range 0 .. 3rT   z0Invalid data mask "{0}". Must be in range 0 .. 7)ro   r%   r&   )r7   r<   r   r   r   r1     s    r1   c              	   C   sh   | du r|st d| S ztj|   W S  ttfyb   | tj v rP|  Y S t d| Y n0 dS )a4      Returns a constant for the provided error level.

    This function returns ``None`` if the provided parameter is ``None`` and
    `accept_none` is set to ``True`` (default: ``False``). If `error` is ``None``
    and `accept_none` is ``False`` or if the provided parameter cannot be
    mapped to a valid QR Code error level, a :py:exc:`ValueError` is raised.

    :param error: String or ``None``.
    :param bool accept_none: Indicates if ``None`` is accepted as error level.
    :raises: :py:exc:`ValueError` in case of an invalid mode.
    :rtype: int
    Nz The error level must be providedzCIllegal error correction level: "{0}". Supported levels: L, M, Q, H)r%   r   ERROR_MAPPINGr;  r<  r=  rB  r&   )r4   r   r   r   r   r(     s    r(   c                 C   s6   t j D ]\}}|| kr
|  S q
td| dS )z    Returns the mode name for the provided mode constant.

    :param int mode_const: The mode constant (see :py:module:`segno.consts`)
    :raises: :py:exc:`ValueError` in case of an unknown mode constant.
    :rtype: str
    Unknown mode "{0}"N)r   rA  itemsr%   r&   )Z
mode_constnamer   r   r   r   r+     s    
r+   c                 C   s6   t j D ]\}}|| kr
|  S q
td| dS )z    Returns the error name for the provided error constant.

    :param int error_const: The error constant (see :py:module:`segno.consts`)
    :raises: :py:exc:`ValueError` in case of an unknown error correction level.
    :rtype: str
    zUnknown error level "{0}"N)r   rD  rF  r%   r&   )Zerror_constrG  r   r   r   r   get_error_name  s    
rH  c                 C   sR   d|   k rdk rn n| S t j D ]\}}|| kr&|  S q&td| dS )a      Returns the version name.

    For version 1 .. 40 it returns the version as integer, for Micro QR Codes
    it returns a string like ``M1`` etc.

    :raises: :py:exc:`VersionError`: In case the `version_constant` is unknown.
    :rtype: str or int
    r   r7  zUnknown version constant "{0}"N)r   r:  rF  r%   r&   )Zversion_constrG  vr   r   r   r'     s    

r'   s   ^[s   ]+\Zc                 C   s
   t | S )z    Returns if the provided `data` can be encoded in "alphanumeric" mode.

    :param bytes data: The data to check.
    :rtype: bool
    )_ALPHANUMERIC_PATTERNmatchrI   r   r   r   is_alphanumeric0  s    rM  c                 C   s   t | }|r|d rdS tr*dd | D } t| }td|dD ]J}t|d> t|B }d|  krjdks>n d	|  krd
ks>n  dS q>dS )zz    Returns if the `data` can be encoded in "kanji" mode.

    :param bytes data: The data to check.
    :rtype: bool
    rY   Fc                 s   s   | ]}t |V  qd S r   r   rF   cr   r   r   r   E  rM   zis_kanji.<locals>.<genexpr>r   rT   r&  r'  r(  r)  T)rO   r.  iterrP   next)rI   data_len	data_iterrG   r1  r   r   r   is_kanji:  s    ,rT  c                 C   s0   |   rtjS t| rtjS t| r*tjS tjS )z    Returns the appropriate QR Code mode (an integer constant) for the
    provided `data`.

    :param bytes data: Data to check.
    :rtype: int
    )isdigitr   r`   rM  ra   rT  rb   r^   rL  r   r   r   r+  N  s    r+  c           
   	   C   s   |r|rJ |p|du }|r"t jnd}|r0t jnd}|dk rPtdd | jD }|durb|rbt j}t||d D ]Z}|du r|t jkrt j}z*t j| | | 	|||kr|W   S W qp t
y   Y qp0 qpd}	|du rd}	n|rd}	td	|	dS )
a)      Returns the minimal (Micro) QR Code version constant for the provided input.

    :param segments: Iterable of Segment instances.
    :param error: The error correction level constant.
    :type error: int or None
    :param bool eci: Indicates if the ECI mode should be used.
    :param micro: Boolean value if a Micro QR Code should be created or ``None``
    :type micro: bool or None
    :param bool is_sa: Indicator if Structured Append is used.
    :raises: :py:exc:`ValueError` if the content does not fit into a QR Code.
    :rtype: int
    Nr   r   c                 S   s   g | ]}t |qS r   )find_minimum_version_for_moderF   r6   r   r   r   rL   r  rM   z find_version.<locals>.<listcomp> z(Micro) zMicro z:Data too large. No {0}QR Code can handle the provided data)r   r/   r   r   r|   Z
VERSION_M2rP   r0   rn   r   r<  r   r&   )
r:   r4   r!   r"   rg   Zmicro_allowedmin_versionmax_versionr5   Zhelp_txtr   r   r   r.   _  s,    r.   c                 C   s$   | dkr| d d S | d d d S )a.      Returns the matrix size according to the provided `version`.

    Note: This function does not check if `version` is actually a valid
    (Micro) QR Code version. Invalid versions like ``41`` may return a
    size as well.

    :param int ver: (Micro) QR Code version constant.
    :rtype: int
    r   rS   r   rY   r4  r   )r   r   r   r   r5    s    r5  c                 C   s   t | tst| } z| d}W nB tyb   z| d}W n  ttfy\   | d}Y n0 Y n0 trvdd |D }tt|S )zy    Calculates the parity data for the Structured Append mode.

    :param str content: The content.
    :rtype: int
    z
iso-8859-1z	shift-jisr  c                 s   s   | ]}t |V  qd S r   r   rN  r   r   r   r     rM   z0calc_structured_append_parity.<locals>.<genexpr>)	r  r  r}   r   r  LookupErrorr.  r	   r   )r3   rI   r   r   r   r~     s    
r~   c                 C   sF   |dkrdn|}z|t j|  v W S  ty@   td| Y n0 dS )aR      Returns if `mode` is supported by `version`.

    Note: This function does not check if `version` is actually a valid
    (Micro) QR Code version. Invalid versions like ``41`` may return an illegal
    value.

    :param int mode: Canonicalized mode.
    :param int or None ver: (Micro) QR Code version constant.
    :rtype: bool
    r   NrE  )r   ZSUPPORTED_MODESr<  r%   r&   )r6   r   r   r   r   r*     s
    r*   c                 C   s"   t jD ]}t| |r|  S qdS )z    Returns the minimum Micro QR Code version which supports the provided mode.

    :param int mode: Canonicalized mode.
    :rtype: int
    r   )r   r$   r*   )r6   rI  r   r   r   rV    s    


rV  c                 C   sl   d|   k rdk rn nt jS d|   k r2dk r<n nt jS d|   k rPdk rZn nt jS td| dS )	z    Returns the version range for the provided version. This applies to QR Code
    versions, only.

    :param int version: The QR Code version (1 .. 40)
    :rtype: int
    r   rW   r4  r   r   r7  zUnknown version "{0}"N)r   ZVERSION_RANGE_01_09ZVERSION_RANGE_10_26ZVERSION_RANGE_27_40r%   r&   )r5   r   r   r   rm     s    
rm   c                 C   s:   zt jt| j W S  ty4   td| Y n0 dS )z    Returns the ECI number for the provided encoding.

    :param str encoding: A encoding name
    :return str: The ECI number.
    z1Unknown ECI assignment number for encoding "{0}".N)r   ZECI_ASSIGNMENT_NUMcodecslookuprG  r<  r%   r&   rB   r   r   r   r     s    r   c           	      C   sd   dd }dd }dd }dd }d	d
 }dd }dd }dd }| rP||||fS ||||||||fS )u  
    Returns the data mask functions.

    ISO/IEC 18004:2015(E) -- 7.8.2 Data mask patterns (page 50)
    Table 10 — Data mask pattern generation conditions (page 50)

    ===============     =====================   =====================================
    QR Code Pattern     Micro QR Code Pattern￼  Condition
    ===============     =====================   =====================================
    000                                         (i + j) mod 2 = 0
    001                 00                      i mod 2 = 0
    010                                         j mod 3 = 0
    011                                         (i + j) mod 3 = 0
    100                 01                      ((i div 2) + (j div 3)) mod 2 = 0
    101                                         (i j) mod 2 + (i j) mod 3 = 0
    110                 10                      ((i j) mod 2 + (i j) mod 3) mod 2 = 0
    111                 11                      ((i+j) mod 2 + (i j) mod 3) mod 2 = 0
    ===============     =====================   =====================================

    :param is_micro: Indicates if data mask functions for a Micro QR Code
            should be returned
    :return: A tuple of functions
    c                 S   s   | | d@ dkS Nr   r   r   r   r   r   r   fn0  s    z$get_data_mask_functions.<locals>.fn0c                 S   s   | d@ dkS r^  r   r   r   r   r   fn1  s    z$get_data_mask_functions.<locals>.fn1c                 S   s   |d dkS NrV   r   r   r   r   r   r   fn2  s    z$get_data_mask_functions.<locals>.fn2c                 S   s   | | d dkS ra  r   r   r   r   r   fn3  s    z$get_data_mask_functions.<locals>.fn3c                 S   s   | d |d  d@ dkS )NrY   rV   r   r   r   r   r   r   r   fn4  s    z$get_data_mask_functions.<locals>.fn4c                 S   s   | | }|d@ |d  dkS Nr   rV   r   r   rG   r   tmpr   r   r   fn5  s    z$get_data_mask_functions.<locals>.fn5c                 S   s    | | }|d@ |d  d@ dkS re  r   rf  r   r   r   fn6  s    z$get_data_mask_functions.<locals>.fn6c                 S   s    | | d@ | | d  d@ dkS re  r   r   r   r   r   fn7  s    z$get_data_mask_functions.<locals>.fn7r   )	r<   r_  r`  rb  rc  rd  rh  ri  rj  r   r   r   r     s    r   c                   @   sF   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dddZ
dS )r=   z    Represents a sequence of `Segment` instances.

    Note: len(segments) returns the number of Segments and not the data length;
    use segments.data_length
    r:   rs   r|   c                 C   s   g | _ d| _g | _d S )Nr   rk  selfr   r   r   __init__*  s    zSegments.__init__c                 C   s   | j rn| j d }|j|jkrn|j|jkrnt|j|j |j|j |j|j}|  jt|j8  _| j d= | jd= | j 	| |  jt|j7  _| j	|j dS )z:
        :param _Segment segment: Segment to add.
        r   N)
r:   r6   r8   r/  ri   rd   rs   rO   r|   r   )rm  r   Zprev_segr   r   r   r>   /  s    

zSegments.add_segmentc                 C   s
   t | jS r   )rO   r:   rl  r   r   r   __len__B  s    zSegments.__len__c                 C   s
   | j | S r   )r:   rm  r  r   r   r   __getitem__E  s    zSegments.__getitem__c                 C   s
   t | jS r   )rP  r:   rl  r   r   r   __iter__H  s    zSegments.__iter__Fc                    s   d}|r4t dd | jD }||d 7 }||d 7 }|r@|d7 }|dkr\|t| jd 7 }n |tjkr||t| j|d  7 }|dkrt|n| |t  fdd| jD 7 }|| j S )	Nr   c                 s   s*   | ]"}|j tjkr|jtjkrd V  qdS r   )r6   r   r^   r8   r_   )rF   r   r   r   r   r   O  s   z4Segments.bit_length_with_overhead.<locals>.<genexpr>rS   rT   rU   rV   c                 3   s   | ]}t j|   V  qd S r   )r   r]   rW  re   r   r   r   _  rM   )r   r:   rO   r|   r   r/   rm   rs   )rm  r5   r!   rg   rh   Zno_eci_indicatorsr   rs  r   r   K  s    
z!Segments.bit_length_with_overheadN)F)r   r   r   r   	__slots__rn  r>   ro  rq  rr  r   r   r   r   r   r=   !  s   r=   c                   @   sN   e Zd ZdZdZd
ddZeedZeedZ	eedZ
eed	ZdS )r/  aN      Represents a data segment.

    A segment provides the (encoding specific) byte data, the data length,
    the QR Code mode, and the used encoding. The latter is ``None`` iff mode
    is not "byte".

    Note that `data_length` may not be equal to len(data)!

    See also ISO/IEC 18004:2015(E) - 7.4.7 Mixing modes (page 30)
    r   Nc                 C   s   t | ||||fS r   )r   __new__)clsri   rd   r6   r8   r   r   r   ru  q  s    z_Segment.__new__r   r   rY   rV   )N)r   r   r   r   rt  ru  propertyr   ri   rd   r6   r8   r   r   r   r   r/  c  s   
r/  c                   @   sP   e Zd ZdZdgZdddZdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )r   zO    Wraps a :cls:`bytearray` and provides some useful methods to add bits.
    _datar   c                 C   s   t || _d S r   )r   rx  rm  iterabler   r   r   rn    s    zBuffer.__init__c                 C   s   | j | d S r   )rx  r   ry  r   r   r   r     s    zBuffer.extendc                    s&   | j  fddtt|D  d S )Nc                 3   s   | ]} |? d @ V  qdS r   r   rE   r   r   r   r     rM   z%Buffer.append_bits.<locals>.<genexpr>)rx  r   r   rP   )rm  r   rr   r   r   r   r     s    zBuffer.append_bitsc                 C   s   | j S r   rx  rl  r   r   r   r0    s    zBuffer.getbitsc                 C   s$   dd t t| jgd ddiD S )z        Returns an iterable of integers interpreting the content of `seq`
        as sequence of binary numbers of length 8.
        c                 s   s$   | ]}t d tt|dV  qdS )rX  rY   N)ro   r>  r   r}   )rF   gr   r   r   r     rM   z Buffer.toints.<locals>.<genexpr>rT   	fillvaluer   )r   rP  rx  rl  r   r   r   r     s    zBuffer.tointsc                 C   s
   t | jS r   )rO   rx  rl  r   r   r   ro    s    zBuffer.__len__c                 C   s
   | j | S r   r{  rp  r   r   r   rq    s    zBuffer.__getitem__N)r   )r   r   r   r   rt  rn  r   r   r0  r   ro  rq  r   r   r   r   r   z  s   
r   c                       sT   e Zd ZdZdZ fddZeedZeedZ	eedZ
eedZ  ZS )	r   z    Represents Structured Append information.

    Note: This class provides the Structured Append header information in
    correct order (incl. Structured Append mode indicator); cf.
    ISO/IEC 18004:2015(E) -- 8 Structured Append (page 59).
    r   c                    s   t t| | tj|||fS )z        :param int number: Symbol number ``[0 .. 15]``
        :param int total: Total symbol count ``[2 .. 15]``
        :param int parity: Parity data.
        )superr   ru  r   ZMODE_STRUCTURED_APPEND)rv  numberry   rz   	__class__r   r   ru    s    z_StructuredAppendInfo.__new__r   r   rY   rV   )r   r   r   r   rt  ru  rw  r   r6   r  ry   rz   __classcell__r   r   r  r   r     s   r   )NNNNNFNT)NNNNNFTN)N)F)F)N)N)TT)F)F)er   
__future__r   r   operatorr   r   r   r   	functoolsr   r	   	itertoolsr
   r   r   rerp   r\  collectionsr   rX  r   r.  r   r}   r  ro   r  ImportErrorr   r   r   
basestringnumbersr   unicodexrangerP   sysmaxsizer   __all__type__metaclass__r%   r   r   r   r   r2   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)   r1   r(   r+   rH  r'   compileescaper-  rJ  rM  rT  r+  r.   r5  r~   r*   rV  rm   r   r   r=   r   r/  r   r   r   r   r   r   <module>   s   

  
0   
q
4

"+/"
?j>'!&
l
)#


&8B 