403Webshell
Server IP : 217.160.0.135  /  Your IP : 216.73.217.25
Web Server : Apache
System : Linux www 6.18.52-i1-ampere #1203 SMP Mon Sep 14 18:29:59 CEST 2026 aarch64
User : sws1074145052 ( 1074145052)
PHP Version : 8.3.32
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /lib/python3/dist-packages/pythran/analyses/__pycache__/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /lib/python3/dist-packages/pythran/analyses/__pycache__/range_values.cpython-311.pyc
�

cR�aV���"�dZddlZddlmZddlmZddlmZddl	m
Z
mZddlm
Z
ddlmZdd	lmZmZmZdd
lmZmZGd�de��ZGd
�de��Zd�Zd�Zdd�ZGd�de��ZGd�de��ZGd�de��Z dS)zB Module Analysing code to extract positive subscripts from code.  �N)�defaultdict)�contextmanager)�reduce)�Aliases�CFG)�	Intrinsic)�ModuleAnalysis)�Interval�
IntervalTuple�
UNKNOWN_RANGE)�MODULES�
attributesc��eZdZdS)�UnsupportedExpressionN��__name__�
__module__�__qualname__���?/usr/lib/python3/dist-packages/pythran/analyses/range_values.pyrr��������Drrc��eZdZdS)�RangeValueTooCostlyNrrrrrrrrrc���d�|jj�����}	t	t|��|��||��S#t$r
tcYSwxYw)Nz__{}__)�format�	__class__r�lower�getattr�type�AttributeErrorr)�op�node0�node1�keys    r�combiner&sr��
�/�/�"�,�/�5�5�7�7�
8�
8�C��(�w�t�E�{�{�C�(�(���6�6�6�������������s�&A�A.�-A.c�`�t|tj��rt���t|tj��r�t|jtj��rAtj|jtj	��gtj
dd��g��St|jtj��r|jSt|jtj��r|jSt|jtj
��r|jSt|tj��r�d�|jD��}t|jtj��r&tjtj��|��St|jtj��r&tjtj��|��St|tj��r|d�t%|jg|jdd�z|j|j��D��}t-|��dkr|dStjtj��|��St|tj	��rtj��St|tj��rtj	��St|tj��rtj��St|tj��rtj��St|tj��rtj��St|tj��rtj��St|tj��rtj��St|tj��rtj��St|tj��r@|jdkrtj
dd��S|jdkrtj
d	d��St���)
N���c�Z�g|](}tjtj��|����)Sr)�ast�UnaryOp�Not)�.0�vs  r�
<listcomp>znegate.<locals>.<listcomp>6s*��E�E�E�A�c�k�#�'�)�)�Q�/�/�E�E�Erc�`�g|]+\}}}tj|t|��g|g����,Sr)r*�Compare�negate)r-�x�o�ys    rr/znegate.<locals>.<listcomp>?sF��*�*�*��A�q�!���A��q�	�	�{�Q�C�0�0�*�*�*r�r�FalseT�TrueF) �
isinstancer*�Namerr+r"�Invertr1�operand�Eq�Constantr,�UAdd�USub�BoolOp�values�Or�And�zip�left�comparators�ops�len�NotEq�Gt�LtE�GtE�Lt�In�NotIn�	Attribute�attr)�node�
new_values�cmpss   rr2r2 sK���$���!�!�&�#�%�%�%��$���$�$� ��d�g�s�z�*�*�	9��;�t�|� #����z� #��R�� 6� 6�7�9�9�
9��d�g�s�w�'�'�	 ��<���d�g�s�x�(�(�	 ��<���d�g�s�x�(�(�	 ��<���$��
�#�#�4�E�E���E�E�E�
��d�g�s�v�&�&�	5��:�c�g�i�i��4�4�4��d�g�s�w�'�'�	4��:�c�f�h�h�
�3�3�3��$���$�$�*�*�*���	�{�T�%5�c�r�c�%:�:�D�H��'�)�)�*�*�*���t�9�9��>�>���7�N��z�#�&�(�(�D�)�)�)��$�������y�{�{���$��	�"�"���v�x�x���$�������w�y�y���$��� � ���v�x�x���$�������w�y�y���$��� � ���v�x�x���$�������y�{�{���$��	�"�"���v�x�x���$��
�&�&�-��9�����<��d�+�+�+��9�����<��t�,�,�,�
�
!�
!�!rc	�
���|�t��}t|tj��rdSt|tj��r:	t|j��}t�|||��dS#t$rYdSwxYwt|tj	��r�t|j
tj��r|jD]}t�|||���dSt|j
tj
��rp�fd�|jD��}t|j|��D]\}}t||||���|D]/�t�fd�|dd�|d�����<�.dSdSt|tj���r�|j}t|jtj��r|�|jj��t|j|j��D�]�\}	}
t|
tj��r|�|
j��t|tj��r�|j}n�|}t|
tj��r�|
j}n�|
}|j|j}}
|j|j}}dx}}t|	tj��rVt3|
|��t5||��}}||kr.t7t3|
|��t5||����x}}�nt|	tj��rft7t5|
|dz
��t5||dz
����}t7t3||
dz��t3||
dz����}�n�t|	tj��rZt7t5|
|��t5||����}t7t3||
��t3||
����}�n)t|	tj��rft7t3|
|dz��t3||dz����}t7t5||dz
��t5||dz
����}�n�t|	tj��rZt7t3|
|��t3||����}t7t5||��t5||����}�n5t|	tj ���rt|
tj!tj"tj#f��rX|
j$rPt5�fd�|
j$D����}t3�fd�|
j$D����}t7||��}n�t|
tj%��rw||
j&D]i}tO|d��sd}nT|�(�fd	�|
j)D����}|�|}�A|�*|�+|
����}�j|�$t|tj��r
|�|j<|�$t|
tj��r
|�|
j<|
}���dSdS)
a'
    Bound the idenifier in `mapping' with the expression in `node'.
    `aliases' is the result of aliasing analysis and `modified' is
    updated with the set of identifiers possibly `bounded' as the result
    of the call.

    Returns `modified' or a fresh set of modified identifiers.

    Nc�8��g|]}������Sr)�copy)r-�_�mappings  �rr/zbound_range.<locals>.<listcomp>s!���<�<�<�1������<�<�<rc�:��|�|���S�N)�union)r3r5�ks  �r�<lambda>zbound_range.<locals>.<lambda>�s�������1����rr6rc3�2�K�|]}�|jV��dSr\)�low�r-�eltrZs  �r�	<genexpr>zbound_range.<locals>.<genexpr>�s*�����!I�!I�s�'�#�,�"2�!I�!I�!I�!I�!I�!Irc3�2�K�|]}�|jV��dSr\)�highrbs  �rrdzbound_range.<locals>.<genexpr>�s*�����"K�"K��7�3�<�#4�"K�"K�"K�"K�"K�"Kr�return_range_contentc� ��g|]
}�|��Srr)r-�argrZs  �rr/zbound_range.<locals>.<listcomp>�s/���:I�:I�:I�3�'�#�,�:I�:I�:Ir),�setr9r*r:r+r2r<�bound_rangerrAr"rDrBrCrErr1rF�add�idrHrGrarfr=�max�minr
rNrLrKrMrO�List�Tuple�Set�elts�Call�func�hasattrrg�argsr]�return_range)rZ�aliasesrS�modified�negated�value�mappings�mapping_cpyrFr"�right�
left_interval�right_interval�l_l�l_h�r_l�r_h�r_i�l_irarf�alias�rrcr^s`                      @rrkrkasa�������5�5���$���!�!�_���	�D�#�+�	&�	&�[�	��T�\�*�*�G����'�8�<�<�<�<�<��$�	�	�	��D�D�	����
�D�#�*�	%�	%�T��d�g�s�w�'�'�
	4���
?�
?���G�W�e�X�>�>�>�>�
?�
?�
�����
(�
(�	4�<�<�<�<���<�<�<�H�&)�$�+�x�&@�&@�
C�
C�"��{��K��%��B�B�B�B��
4�
4��#�$>�$>�$>�$>�$,�Q�R�R�L�$,�Q�K��N�4�4���
�
�	4�	4�
4�
4�

�D�#�+�	&�	&�G��y���d�i���*�*�	'��L�L����&�&�&��T�X�t�'7�8�8�B	�B	�I�B���%���*�*�
'����U�X�&�&�&��$���)�)�
.� '��� 0�
�
� '��
�
��%���*�*�
0�!(���!2���!(����$�(�-�*<��C�%�)�>�+>��C���C�#��"�c�f�%�%�(
G���S�M�M�3�s�C�=�=�T���$�;�;� (��S�#����C��
�
� F� F�F�C�#���B���'�'�$
G��s�3��a��0�0�#�c�3��7�2C�2C�D�D���s�3��a��0�0�#�c�3��7�2C�2C�D�D����B���(�(�
G��s�3��}�}�c�#�s�m�m�<�<���s�3��}�}�c�#�s�m�m�<�<����B���'�'�
G��s�3��a��0�0�#�c�3��7�2C�2C�D�D���s�3��a��0�0�#�c�3��7�2C�2C�D�D����B���(�(�
G��s�3��}�}�c�#�s�m�m�<�<���s�3��}�}�c�#�s�m�m�<�<����B���'�'�
G��e�c�h��	�3�7�%C�D�D�G��z�2�!�!I�!I�!I�!I�e�j�!I�!I�!I�I�I��"�"K�"K�"K�"K��
�"K�"K�"K�K�K��&�s�D�1�1�����s�x�0�0�
G�!(���!4�	G�	G��&�u�.D�E�E�"�"&�C�!�E�#�8�8�:I�:I�:I�:I�=B�Z�:I�:I�:I�J�J���;�"%�C�C�"%�)�)�E�,>�,>�u�,E�,E�"F�"F�C�C���:�d�C�H�#=�#=��#&���� ���:�e�S�X�#>�#>��$'����!��D�D�OG�G�
B	�B	s�
&A2�2
B�?Bc���eZdZe��Z�fd�Zd�Zd�Zd�Zd�Z	d�Z
d�Zd�Zd	�Z
d
�Zd�Zd�Zd
�Zd�Zd�Zd�Z�xZS)�RangeValuesBasec���td���|_ddlm}t	t
|���tt|��||_	dS)zAInitialize instance variable and gather globals name information.c��tSr\�rrrrr_z*RangeValuesBase.__init__.<locals>.<lambda>����-�rr)�UseOMPN)
r�result�pythran.analysesr��superr��__init__rr�parent)�selfr�rs  �rr�zRangeValuesBase.__init__�sU���!�"7�"7�8�8���+�+�+�+�+�+�
�o�t�$�$�-�-�g�s�F�C�C�C�����rc��||jvr||j|<n(|j|�|��|j|<|j|S)z�
        Add a new low and high bound for a variable.

        As it is flow insensitive, it compares it with old values and update it
        if needed.
        )r�r])r��variable�range_s   rrlzRangeValuesBase.add�sN���4�;�&�&�$*�D�K��!�!�$(�K��$9�$?�$?��$G�$G�D�K��!��{�8�$�$rc��|���D]A\}}||jvr)|j|�|��|j|<�7||j|<�BdSr\)�itemsr�r])r��otherr^r.s    r�unionifyzRangeValuesBase.unionify�sb���K�K�M�M�	#�	#�D�A�q��D�K���!%��Q��!5�!5�a�!8�!8���A���!"���A���		#�	#rc���||_|���D]N\}}|j�|d��}|�||j|<�-||ur|�|��|j|<�OdSr\)r�r��get�widen)r��currr�r^r.�ws      rr�zRangeValuesBase.widen�st������K�K�M�M�	,�	,�D�A�q������4�(�(�A��y�!"���A����!���!"��������A���	,�	,rc
����tt�fd�|jD�����}��|t	t|d��t
|d������S)a� Merge right and left operands ranges.

        TODO : We could exclude some operand with this range information...

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse('''
        ... def foo():
        ...     a = 2
        ...     c = 3
        ...     d = a or c''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['d']
        Interval(low=2, high=3)
        c�^��g|])}��|�������*Sr)�visit�bounds�r-rcr�s  �rr/z0RangeValuesBase.visit_BoolOp.<locals>.<listcomp>
s/���I�I�I�c����C���/�/�1�1�I�I�Irrr6)�listrErBrlr
rorn�r�rS�ress`  r�visit_BoolOpzRangeValuesBase.visit_BoolOp�s`���"�3�I�I�I�I�T�[�I�I�I�J�K�K���x�x��h�s�3�q�6�{�{�C��A��K�K�@�@�A�A�Arc��t|j|�|j��|�|j����}|�||��S)a� Combine operands ranges for given operator.

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse('''
        ... def foo():
        ...     a = 2
        ...     c = 3
        ...     d = a - c''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['d']
        Interval(low=-1, high=-1)
        )r&r"r�rFrrlr�s   r�visit_BinOpzRangeValuesBase.visit_BinOp
sG���d�g�t�z�z�$�)�4�4�d�j�j���6L�6L�M�M���x�x��c�"�"�"rc�h�|�|j��}t|jtj��rt
dd��}n�t|jtj��rQt|jt��r7t|j
t��rt
|j|j
��}nct|jtj��rnCt|jtj��rt
|j|j
��}nt}|�||��S)ap Update range with given unary operation.

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse('''
        ... def foo():
        ...     a = 2
        ...     c = -a
        ...     d = ~a
        ...     f = +a
        ...     e = not a''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['f']
        Interval(low=2, high=2)
        >>> res['c']
        Interval(low=-2, high=-2)
        >>> res['d']
        Interval(low=-3, high=-3)
        >>> res['e']
        Interval(low=0, high=1)
        rr6)r�r<r9r"r*r,r
r;rf�intrar?r@rrlr�s   r�
visit_UnaryOpzRangeValuesBase.visit_UnaryOps���.�j�j���&�&���d�g�s�w�'�'�	 ��1�a�.�.�C�C�
�����
,�
,�		 �
���#�
&�
&�		 �
����
%�
%�		 ��C�H�9�s�w�h�/�/�C�C�
�����
*�
*�	 ��
�����
*�
*�	 ��C�H�9�s�w�h�/�/�C�C��C��x�x��c�"�"�"rc���|�|j��|�|j��}|�|j��}|�||�|����S)a� Use worst case for both possible values.

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse('''
        ... def foo():
        ...     a = 2 or 3
        ...     b = 4 or 5
        ...     c = a if a else b''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['c']
        Interval(low=2, high=5)
        )r��test�body�orelserlr])r�rS�body_res�
orelse_ress    r�visit_IfExpzRangeValuesBase.visit_IfExpEs`��	
�
�
�4�9�����:�:�d�i�(�(���Z�Z���,�,�
��x�x��j�.�.�x�8�8�9�9�9rc�$�td�|jD����r9|�|��|�|t	dd����S|�|j��}g}t|j|j��D]�\}}|�|��}tj
tjdtj��dd��|gtjdtj��dd��g��}tj
|��}tj|��ttj|��dd��}|�t%|||d	�������t'|��r$|�|t	dd����Std
�|D����r$|�|t	dd����S|�|t	dd����S)a: Boolean are possible index.

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse('''
        ... def foo():
        ...     a = 2 or 3
        ...     b = 4 or 5
        ...     c = a < b
        ...     d = b < 3
        ...     e = b == 4''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['c']
        Interval(low=1, high=1)
        >>> res['d']
        Interval(low=0, high=0)
        >>> res['e']
        Interval(low=0, high=1)
        c3�K�|]@}t|tjtjtjtjf��V��AdSr\)r9r*rOrP�Is�IsNot)r-r"s  rrdz0RangeValuesBase.visit_Compare.<locals>.<genexpr>nsQ����#�#���"�s�v�s�y�#�&�#�)�D�E�E�#�#�#�#�#�#rrr6r3Nr5z<range_values>�eval)r3r5c3�JK�|]}|j|jcxkodkncV��dS)rN)rarf)r-�rs  rrdz0RangeValuesBase.visit_Compare.<locals>.<genexpr>�sB����3�3�!���!�&�%�%�%�%�A�%�%�%�%�3�3�3�3�3�3r)�anyrH�
generic_visitrlr
r�rFrErGr*r1r:�Load�
Expression�fix_missing_locations�compile�gast_to_ast�appendr��all)r�rSr�r�r"�
comparator�fake�exprs        r�
visit_ComparezRangeValuesBase.visit_CompareYs���*�#�#���#�#�#�#�#�	2����t�$�$�$��8�8�D�(�1�a�.�.�1�1�1��z�z�$�)�$�$����!�$�(�D�,<�=�=�	A�	A�N�B�
����J�/�/�J��;�s�x��S�X�Z�Z��t�D�D� "�t� #���c�h�j�j�$�� E� E�F�H�H�D��>�$�'�'�D��%�d�+�+�+��3�?�4�0�0�2B�F�K�K�D��J�J�t�D��:�">�">�?�?�@�@�@�@��s�8�8�	2��8�8�D�(�1�a�.�.�1�1�1�
�3�3�s�3�3�3�
3�
3�	2��8�8�D�(�1�a�.�.�1�1�1��8�8�D�(�1�a�.�.�1�1�1rc�*���j|jD�]r}|tddurO|jdj}t
|d}��||�d�����gt|t��r=|��fd�|jD����}��||����t|tj��ro|�jvrC��
��}�j�|����|����|�j|����B�j�|d����|��cS�j|S)a� Function calls are not handled for now.

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse('''
        ... def foo():
        ...     a = builtins.range(10)''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['a']
        Interval(low=-inf, high=inf)
        �builtinsrr(Nc�:��g|]}��|����Sr�r��r-�nr�s  �rr/z.RangeValuesBase.visit_Call.<locals>.<listcomp>�s#���6�6�6�q�T�Z�Z��]�]�6�6�6r)ryrur
rwr|rrlrxr9rr*�FunctionDefr��
save_stater�r��
restore_state�popr�)r�rSr��	attr_name�	attribute�alias_range�states`      r�
visit_CallzRangeValuesBase.visit_Call�s�����\�$�)�,�	0�	0�E���
�+�I�6�6�6� �I�b�M�/�	�&�y�1�"�5�	�����y�5�5�d�;�;�<�<�<�<��E�9�-�-�
0�#�0�0�6�6�6�6�D�I�6�6�6�8�8������{�+�+�+�+��E�3�?�3�3�
0����+�+� �O�O�-�-�E��K�%�%�e�,�,�,��&�&�u�-�-�-�����t�{�5�1�2�2�2�2������d�+�+�+��)�)�$�/�/�/�/�/��{�4� � rc��t|jttf��r.|�|t|j|j����StS)z" Handle literals integers values. )r9r|�boolr�rlr
r�r�rSs  r�visit_ConstantzRangeValuesBase.visit_Constant�sC���d�j�4��+�.�.�	D��8�8�D�(�4�:�t�z�"B�"B�C�C�C��rc�N�|�||j|j��S)z; Get range for parameters for examples or false branching. )rlr�rmr�s  r�
visit_NamezRangeValuesBase.visit_Name�s���x�x��d�k�$�'�2�3�3�3rc�l����|t�fd�|jD������S)Nc3�B�K�|]}��|��V��dSr\r�r�s  �rrdz.RangeValuesBase.visit_Tuple.<locals>.<genexpr>�s-�����%K�%K�#�d�j�j��o�o�%K�%K�%K�%K�%K�%Kr)rlrrsr�s` r�visit_TuplezRangeValuesBase.visit_Tuple�s@����x�x��%�%K�%K�%K�%K���%K�%K�%K�K�K�M�M�	Mrc�^�|�||�|j����Sr\)rlr�r|r�s  r�visit_IndexzRangeValuesBase.visit_Index�s$���x�x��d�j�j���4�4�5�5�5rc�f��t|jtj���rA�j|jjD]�}|tddurT|jjdj}t|d}��	||�
d�����kt|t��r@��	||�
�fd�|jjD����������|��cS�j|jjs��|��S��
|j���j|S��
|j��}��
|j��}��	|||��S)Nr�rr(c�:��g|]}��|����Srr�r�s  �rr/z3RangeValuesBase.visit_Subscript.<locals>.<listcomp>�s#���!I�!I�!I�A�$�*�*�Q�-�-�!I�!I�!Ir)r9r|r*rtryrur
rwrrlrgrr�r��slicer�)r�rSr�r�r�r|r�s`      r�visit_SubscriptzRangeValuesBase.visit_Subscript�s�����d�j�#�(�+�+�	0���d�j�o�6�

4�

4���G�J�/�	�:�:�:� $�
��� 3� 9�I� *�9� 5�b� 9�I��H�H�T�9�#A�#A�$�#G�#G�H�H�H�H���y�1�1�4��H�H�T�"�7�7�!I�!I�!I�!I����!I�!I�!I�K�K�L�L�L�L� �-�-�d�3�3�3�3�3��<��
��0�
0��)�)�$�/�/�/��J�J�t�z�"�"�"��;�t�$�$��J�J�t�z�*�*�E��J�J�t�z�*�*�E��8�8�D�%��,�/�/�/rc�z�||jvrdS|jrdSt|j|<|j�tjd��}|�|��|j|=|�||jtj��|�||jtj<dS|jtj=dS)a` Set default range value for globals and attributes.

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse("def foo(a, b): pass")
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['a']
        Interval(low=-inf, high=inf)
        N)r��use_omprr�r��ResultHolder�function_visitorrl)r�rS�prev_results   r�visit_FunctionDefz!RangeValuesBase.visit_FunctionDef�s����4�;����F��<�	��F�)���D���k�o�o�o�&B�D�I�I�����d�#�#�#��K�������t�{�?�#?�@�A�A�A��"�8C�D�K��4�5�5�5���O�8�9�9�9r)rrr�objectr�r�rlr�r�r�r�r�r�r�r�r�r�r�r�r�r��
__classcell__�rs@rr�r��s-��������6�8�8�L������%�%�%�#�#�#�,�,�,�B�B�B�(#�#�#�$$#�$#�$#�L:�:�:�(*2�*2�*2�X!�!�!�B���4�4�4�M�M�M�6�6�6�0�0�0�,:�:�:�:�:�:�:rr�c�x��eZdZdZd�fd�	Z�fd�Zd�Zd�Zd�Zd�Z	d	�Z
d
�Zd�Zd�Z
dd
�Zd�Zd�Zd�Z�xZS)�RangeValuesSimplea*
    This analyse extract positive subscripts from code.

    It is flow sensitive and aliasing is not taken into account as integer
    doesn't create aliasing in Python.

    >>> import gast as ast
    >>> from pythran import passmanager, backend
    >>> node = ast.parse('''
    ... def foo(a):
    ...     for i in builtins.range(1, 10):
    ...         c = i // 2''')
    >>> pm = passmanager.PassManager("test")
    >>> res = pm.gather(RangeValuesSimple, node)
    >>> res['c'], res['i']
    (Interval(low=0, high=5), Interval(low=1, high=10))
    Nc����|�E||_|j|_|j|_|j|_|j|_|j|_dSt
t|�����dSr\)	r��ctx�depsr�ry�passmanagerr�r�r�)r�r�rs  �rr�zRangeValuesSimple.__init__sh����� �D�K��z�D�H���D�I� �-�D�K�!�>�D�L�%�1�D�����#�T�*�*�3�3�5�5�5�5�5rc���tt|���|��|�|t��S)�4 Other nodes are not known and range value neither. )r�r�r�rlr�r�rSrs  �rr�zRangeValuesSimple.generic_visit
s6���
���&�&�4�4�T�:�:�:��x�x��m�,�,�,rc��|jfSr\�ry�r�s rr�zRangeValuesSimple.save_states���|�}�rc��|\|_dSr\r��r�r�s  rr�zRangeValuesSimple.restore_states���
����rc�D�|jD]}|�|���dSr\)r�r�)r�rS�stmts   rr�z"RangeValuesSimple.function_visitors2���I�	�	�D��J�J�t�����	�	rc��|jr:|�|j��}|�tj|��S|�|��Sr\)r|r�rl�RangeValuesr�r��r�rSrxs   r�visit_ReturnzRangeValuesSimple.visit_ReturnsJ���:�	,��:�:�d�j�1�1�L��8�8�K�4�l�C�C�C��%�%�d�+�+�+rc�p�|�|��t|j|j|j��dS)a�
        Constraint the range of variables

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse("def foo(a): assert a >= 1; b = a + 1")
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValuesSimple, node)
        >>> res['a']
        Interval(low=1, high=inf)
        >>> res['b']
        Interval(low=2, high=inf)
        N)r�rkr�ryr�r�s  r�visit_AssertzRangeValuesSimple.visit_Assert#s6��	
���4� � � ��D�K���t�y�9�9�9�9�9rc���|�|j��}|jD]M}t|tj��r|�|j|���8|�|���NdS)a�
        Set range value for assigned variable.

        We do not handle container values.

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse("def foo(): a = b = 2")
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValuesSimple, node)
        >>> res['a']
        Interval(low=2, high=2)
        >>> res['b']
        Interval(low=2, high=2)
        N)r�r|�targetsr9r*r:rlrm�r�rS�assigned_range�targets    r�visit_AssignzRangeValuesSimple.visit_Assign4st�� ���D�J�/�/���l�	#�	#�F��&�#�(�+�+�
#������N�3�3�3�3��
�
�6�"�"�"�"�	#�	#rc��|�|��t|jtj��rI|jj}t
|j|j||j|j	��}||j|<dSdS)a` Update range value for augassigned variables.

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse("def foo(): a = 2; a -= 1")
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValuesSimple, node)
        >>> res['a']
        Interval(low=1, high=1)
        N)
r�r9r
r*r:rmr&r"r�r|�r�rS�namer�s    r�visit_AugAssignz!RangeValuesSimple.visit_AugAssignLs~��	
���4� � � ��d�k�3�8�,�,�	$��;�>�D��$�'��+�d�+��+�d�j�1�3�3�C�!$�D�K�����	$�	$rc�J��t|jtj��s
Jd�����|j��t|jtj��rx�j|jjD]`}t|t��rI��
|jj|��fd�|jj
D�������a��|tj|jtj��g|jg����dS)a` Handle iterate variable in for loops.

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse('''
        ... def foo():
        ...     a = b = c = 2
        ...     for i in builtins.range(1):
        ...         a -= 1
        ...         b += 1''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValuesSimple, node)
        >>> res['a']
        Interval(low=-inf, high=2)
        >>> res['b']
        Interval(low=2, high=inf)
        >>> res['c']
        Interval(low=2, high=2)

        >>> node = ast.parse('''
        ... def foo():
        ...     for i in (1, 2, 4):
        ...         a = i''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValuesSimple, node)
        >>> res['a']
        Interval(low=1, high=4)
        �For apply on variables.c�:��g|]}��|����Srr�r�s  �rr/z/RangeValuesSimple.visit_For.<locals>.<listcomp>�s#���!H�!H�!H�A�$�*�*�Q�-�-�!H�!H�!HrN)r9r
r*r:r��iterrtryrurrlrmrgrw�
visit_loopr1rO)r�rSr�s`  r�	visit_ForzRangeValuesSimple.visit_For_s���:�$�+�s�x�0�0�K�K�2K�K�K�K��
�
�4�9�����d�i���*�*�	K���d�i�n�5�
K�
K���e�Y�/�/�K��H�H�T�[�^�"�7�7�!H�!H�!H�!H����!H�!H�!H�J�J�K�K�K��	
������D�K�#�&�(�(��d�i�[�I�I�	K�	K�	K�	K�	Krc���|�@|j}|j���|_t|j|j|��|jD]}|�|���|j���}|jD]}|�|���|���D]-\}}|j|�|��|j|<�.|�dt|j|j|��|jD]}|�|���|�|��|�|��|j	D]}|�|���dS)a= Handle incremented variables in loop body.

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse('''
        ... def foo():
        ...     a = b = c = 2
        ...     while a > 0:
        ...         a -= 1
        ...         b += 1''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValuesSimple, node)
        >>> res['a']
        Interval(low=0, high=2)
        >>> res['b']
        Interval(low=2, high=inf)
        >>> res['c']
        Interval(low=2, high=2)
        N)
r�rXrkryr�r�r�r�r�r�)r�rS�cond�
init_ranger�	old_ranger�r�s        rrzRangeValuesSimple.visit_loop�s~��*����J��+�*�*�,�,�D�K����T�\�4�8�8�8��I�	�	�D��J�J�t������K�$�$�&�&�	��I�	�	�D��J�J�t�����&�O�O�-�-�	@�	@�L�D�&� $��D� 1� 7� 7�� ?� ?�D�K���������T�\�4�8�8�8��	�
!�
!���
�
�4� � � � ��M�M�*�%�%�%��J�J�t�����K�	�	�D��J�J�t�����	�	rc�l�|�|j��|�||j��Sr\)r�r�rr�s  r�visit_WhilezRangeValuesSimple.visit_While�s,���
�
�4�9�������t�T�Y�/�/�/rc��|�|j��|j}|���|_t	|j|j|j��|jD]}|�|���|j}|���|_|jD]}|�|���|j}||_|�|��dS)aO Handle iterate variable across branches

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> pm = passmanager.PassManager("test")

        >>> node = ast.parse('''
        ... def foo(a):
        ...     if a > 1: b = 1
        ...     else: b = 3''')

        >>> res = pm.gather(RangeValuesSimple, node)
        >>> res['b']
        Interval(low=1, high=3)

        >>> node = ast.parse('''
        ... def foo(a):
        ...     if a > 1: b = a
        ...     else: b = 3''')
        >>> res = pm.gather(RangeValuesSimple, node)
        >>> res['b']
        Interval(low=2, high=inf)

        >>> node = ast.parse('''
        ... def foo(a):
        ...     if 0 < a < 4: b = a
        ...     else: b = 3''')
        >>> res = pm.gather(RangeValuesSimple, node)
        >>> res['b']
        Interval(low=1, high=3)

        >>> node = ast.parse('''
        ... def foo(a):
        ...     if (0 < a) and (a < 4): b = a
        ...     else: b = 3''')
        >>> res = pm.gather(RangeValuesSimple, node)
        >>> res['b']
        Interval(low=1, high=3)

        >>> node = ast.parse('''
        ... def foo(a):
        ...     if (a == 1) or (a == 2): b = a
        ...     else: b = 3''')
        >>> res = pm.gather(RangeValuesSimple, node)
        >>> res['b']
        Interval(low=1, high=3)
        N)	r�r�r�rXrkryr�r�r�)r�rSrr�
body_range�orelse_ranges      r�visit_IfzRangeValuesSimple.visit_If�s���`	
�
�
�4�9�����K�	��n�n�&�&����D�K���t�y�9�9�9��I�	�	�D��J�J�t������[�
��n�n�&�&����K�	�	�D��J�J�t������{�� ����
�
�l�#�#�#�#�#rc�b�|j}|���|_|jD]}|�|���|�|��|j���}|jD]W}|���|jc|_}|jD]}|�|���|�|���X||jc|_}|jD]}|�|���|�|��|jD]}|�|���dSr\)r�rXr�r�r��handlersr��	finalbody)r�rSrr�handler�
prev_states      r�	visit_TryzRangeValuesSimple.visit_TrysC���[�
� �o�o�'�'����I�	�	�D��J�J�t������
�
�j�!�!�!��[�%�%�'�'�
��}�	&�	&�G�&0�o�o�&7�&7���#�D�K����
!�
!���
�
�4� � � � ��M�M�*�%�%�%�%�",�d�k����Z��K�	�	�D��J�J�t������
�
�j�!�!�!��N�	�	�D��J�J�t�����	�	rr\)rrr�__doc__r�r�r�r�r�rrrrrrrr"r(r�r�s@rr�r��s"���������$	6�	6�	6�	6�	6�	6�-�-�-�-�-�
���������,�,�,�:�:�:�"#�#�#�0$�$�$�&'K�'K�'K�R2�2�2�2�h0�0�0�@$�@$�@$�D������rr�c�|��eZdZdZ�fd�Z�fd�Zdd�Zd�Zd�Zd�Z	d	�Z
d
�Zd�Zd�Z
d
�Zd�Zd�Zd�Zd�Z�xZS)ra7
    This analyse extract positive subscripts from code.

    It is flow sensitive and aliasing is not taken into account as integer
    doesn't create aliasing in Python.

    >>> import gast as ast
    >>> from pythran import passmanager, backend
    >>> node = ast.parse('''
    ... def foo(a):
    ...     for i in builtins.range(1, 10):
    ...         c = i // 2
    ...     return''')
    >>> pm = passmanager.PassManager("test")
    >>> res = pm.gather(RangeValues, node)
    >>> res['c'], res['i']
    (Interval(low=0, high=5), Interval(low=1, high=10))
    c�V��tt|�����dSr\)r�rr�)r�rs �rr�zRangeValues.__init__0s%���
�k�4� � �)�)�+�+�+�+�+rc���tt|���|��t|tj��r%||jvr|j�|��SdS|�|t��S)r�N)
r�rr�r9r*r�cfg�
successorsrlrr�s  �rr�zRangeValues.generic_visit3sv���
�k�4� � �.�.�t�4�4�4��d�C�H�%�%�	1��t�x����x�*�*�4�0�0�0� ���8�8�D�-�0�0�0rNc�(�|g}|�t��n|���}|rh|���}||vr�|�|��|�|��}|r|�d�|D����|�fdSdS)Nc3�6K�|]}|tju�|V��dSr\)r�NIL)r-r�s  rrdz(RangeValues.cfg_visit.<locals>.<genexpr>Gs.����"H�"H��q���7G�7G�1�7G�7G�7G�7G�"H�"Hr)rjrXr�rlr��extend)r�rS�skipr.�visited�	successor�nextss       r�	cfg_visitzRangeValues.cfg_visit=s����V�
��<�#�%�%�%�T�Y�Y�[�[���	J�"���(�(�I��G�#�#���K�K�	�"�"�"��J�J�y�)�)�E��
J��!�!�"H�"H�e�"H�"H�"H�I�I�I��	J�	J�	J�	J�	Jrc�B�|j|j|j|j|jfSr\�r-ryr��no_backward�no_if_splitr�s rr�zRangeValues.save_stateIs$����$�,���d�6F�� �"�	"rc�H�|\|_|_|_|_|_dSr\r9rs  rr�zRangeValues.restore_stateMs'��"�	���4�<���t�/?�	
�	�	�	rc��|j}td���|_|���D])\}}t|tj��r
||j|<�*	d|_d|_|�t|j
�|������|j���D]
\}}|||<�||_dS#t$r/||_t|��}|�|��YdSwxYw)Nc��tSr\r�rrrr_z.RangeValues.function_visitor.<locals>.<lambda>Sr�rr)r�rr�r9r*r�r:r;r7�nextr-r.rr�r�)r�rS�
parent_resultr^r.�rvss      rr�zRangeValues.function_visitorQs����
�!�"7�"7�8�8���!�'�'�)�)�	#�	#�D�A�q��!�S�_�-�-�
#�!"���A���	� �D�� �D���N�N�4��� 3� 3�D� 9� 9�:�:�;�;�;���)�)�+�+�
%�
%���1�#$�
�a� � �'�D�K�K�K��#�	�	�	�'�D�K�#�D�)�)�C��I�I�d�O�O�O�O�O�O�	���s�A3C�5D
�	D
c��|jr:|�|j��}|�tj|��|j�|��Sr\)r|r�rlrr�r-r.rs   rrzRangeValues.visit_ReturngsL���:�	=��:�:�d�j�1�1�L��H�H�[�-�|�<�<�<��x�"�"�4�(�(�(rc��|�|j��t|j|j|j��|j�|��S)a�
        Constraint the range of variables

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse("def foo(a): assert a >= 1; b = a + 1")
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['a']
        Interval(low=1, high=inf)
        >>> res['b']
        Interval(low=2, high=inf)
        )r�r�rkr�ryr-r.r�s  rrzRangeValues.visit_AssertmsF��	
�
�
�4�9�����D�K���t�y�9�9�9��x�"�"�4�(�(�(rc��|�|j��}|jD]A}t|tj��r||j|j<�,|�|���B|j�	|��S)a�
        Set range value for assigned variable.

        We do not handle container values.

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse("def foo(): a = b = 2")
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['a']
        Interval(low=2, high=2)
        >>> res['b']
        Interval(low=2, high=2)
        )
r�r|r
r9r*r:r�rmr-r.rs    rrzRangeValues.visit_Assignsx�� ���D�J�/�/���l�	#�	#�F��&�#�(�+�+�
#�)7���F�I�&�&��
�
�6�"�"�"�"��x�"�"�4�(�(�(rc�,�|�|��t|jtj��rG|jj}t
|j|j||j|j	��}||j|<|j
�|��S)aZ Update range value for augassigned variables.

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse("def foo(): a = 2; a -= 1")
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['a']
        Interval(low=1, high=1)
        )r�r9r
r*r:rmr&r"r�r|r-r.rs    rrzRangeValues.visit_AugAssign�s���	
���4� � � ��d�k�3�8�,�,�	$��;�>�D��$�'��+�d�+��+�d�j�1�3�3�C�!$�D�K����x�"�"�4�(�(�(rc	�$�|j�|��D]t}||jdurct|tj��rDt
|j|jt	j	t	j
��|j����|gcS�udS�Nr)r-r.r�r9r*�Whilerkr�ryr+r,r�)r�rSr5s   r�visit_loop_successorz RangeValues.visit_loop_successor�s�����,�,�T�2�2�	#�	#�I���	�!��,�,��d�C�I�.�.�C����T�\� #��C�G�I�I�t�y� A� A�C�C�C�!�{�"�"�"�	-�	#�	#rc	���t�jtj��s
Jd���|��j��|j���}t|j|j	tj
�jtj��g�jg�����fd�|j�
���D��}|����|��jd|���}|jr|����S	|j}|���|_|��jd|���|�|j|��|��jd|���|�|��	|����S)a� Handle iterate variable in for loops.

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse('''
        ... def foo():
        ...     a = b = c = 2
        ...     for i in builtins.range(1):
        ...         a -= 1
        ...         b += 1
        ...     return''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['a']
        Interval(low=-inf, high=2)
        >>> res['b']
        Interval(low=2, high=inf)
        >>> res['c']
        Interval(low=2, high=2)

        >>> node = ast.parse('''
        ... def foo():
        ...     for i in (1, 2, 4):
        ...         a = i
        ...     return''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['a']
        Interval(low=1, high=4)
        rc�2��h|]}|�jdu�|��S�r�r��r-r3rSs  �r�	<setcomp>z(RangeValues.visit_For.<locals>.<setcomp>��)���N�N�N�a����1��8M�8M��8M�8M�8Mrr�r3)r9r
r*r:r�rr�rXrkryr1rOr-r.rlr7r�r:rIr�r�)r�rS�
init_stater3�next_r's `    rrzRangeValues.visit_For�s����>�$�+�s�x�0�0�K�K�2K�K�K�K��
�
�4�9�����[�%�%�'�'�
��D�K���s�{�4�;�<?�F�H�H�:�<@�I�;�0H�0H�	I�	I�	I�
O�N�N�N�4�8�.�.�t�4�4�N�N�N������������t�y��|�$��7�7����	��,�,�T�2�2�2���[�
� �o�o�'�'������t�y��|�$��/�/�/��
�
�4�;�
�+�+�+����t�y��|�$��/�/�/��
�
�j�!�!�!���(�(��.�.�.rc�4��|��j��}|j���}�fd�|j����D��}|����d|vrPt|j������D](}|�jdur|�	||����)t|j|j�j��|�	�jd|���|jr.d|vr|�
|��|����S	|j}|���|_|�	�jd|���|�|j|��|�	�jd|���d|vr|�
|��n|�
|��|��j��	|����S)aU Handle incremented variables in loop body.

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse('''
        ... def foo():
        ...     a = b = c = 10
        ...     while a > 0:
        ...         a -= 1
        ...         b += 1
        ...     return''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['a']
        Interval(low=-inf, high=0)
        >>> res['b']
        Interval(low=11, high=inf)
        >>> res['c']
        Interval(low=10, high=10)
        c�2��h|]}|�jdu�|��SrLrMrNs  �rrOz*RangeValues.visit_While.<locals>.<setcomp>rPrrrQ)r�r�r�rXr-r.rlr�r�r7rkryr:r�rIr�)r�rS�
test_rangerRr3r5r's `     rrzRangeValues.visit_While�s����*�Z�Z��	�*�*�
��[�%�%�'�'�
�N�N�N�N�4�8�.�.�t�4�4�N�N�N���������
�
�?�?�!�$�(�"5�"5�d�";�";�<�<�
9�
9�	��D�I�a�L�0�0��N�N�9�4�N�8�8�8���D�K���t�y�9�9�9�	
���t�y��|�$��/�/�/���	��J����
�
�j�)�)�)��,�,�T�2�2�2���[�
� �o�o�'�'������t�y��|�$��/�/�/��
�
�4�;�
�+�+�+�	
���t�y��|�$��/�/�/��
�?�?��M�M�*�%�%�%�%��M�M�*�%�%�%��
�
�4�9������(�(��.�.�.rc	��|jdkrt���|xjdz
c_|�|j��}|j���}d|vr@t
|j|j|j��|�|j	d��|j	dh}|j
r�d|vr�|j}|���|_t
|j|jtjtj
��|j����|�|j
d��|�|��|�|j
d��n�d|vr�|j�|��}t%|��D]�}||vr�|���|jc|_}t
|j|jtjtj
��|j����|�|��|�|����|xjdzc_dS)a� Handle iterate variable across branches

        >>> import gast as ast
        >>> from pythran import passmanager, backend
        >>> pm = passmanager.PassManager("test")

        >>> node = ast.parse('''
        ... def foo(a):
        ...     if a > 1: b = 1
        ...     else: b = 3
        ...     pass''')

        >>> res = pm.gather(RangeValues, node)
        >>> res['b']
        Interval(low=1, high=3)

        >>> node = ast.parse('''
        ... def foo(a):
        ...     if a > 1: b = a
        ...     else: b = 3
        ...     pass''')
        >>> res = pm.gather(RangeValues, node)
        >>> res['b']
        Interval(low=2, high=inf)

        >>> node = ast.parse('''
        ... def foo(a):
        ...     if 0 < a < 4: b = a
        ...     else: b = 3
        ...     pass''')
        >>> res = pm.gather(RangeValues, node)
        >>> res['b']
        Interval(low=1, high=3)

        >>> node = ast.parse('''
        ... def foo(a):
        ...     if (0 < a) and (a < 4): b = a
        ...     else: b = 3
        ...     pass''')
        >>> res = pm.gather(RangeValues, node)
        >>> res['b']
        Interval(low=1, high=3)

        >>> node = ast.parse('''
        ... def foo(a):
        ...     if (a == 1) or (a == 2): b = a
        ...     else: b = 3
        ...     pass''')
        >>> res = pm.gather(RangeValues, node)
        >>> res['b']
        Interval(low=1, high=3)

        >>> node = ast.parse('''
        ... def foo(a):
        ...     b = 5
        ...     if a > 0: b = a
        ...     pass''')
        >>> res = pm.gather(RangeValues, node)
        >>> res['a'], res['b']
        (Interval(low=-inf, high=inf), Interval(low=1, high=inf))

        >>> node = ast.parse('''
        ... def foo(a):
        ...     if a > 3: b = 1
        ...     else: b = 2
        ...     if a > 1: b = 2
        ...     pass''')
        >>> res = pm.gather(RangeValues, node)
        >>> res['b']
        Interval(low=2, high=2)
        �r6rN)r;rr�r�r�rXrkryr7r�r�r*r+r,r�rlr-r.r�)r�rSrVrR�visited_successorsr'r.r5s        rr"zRangeValues.visit_If3s��T��q� � �%�'�'�'����A�����Z�Z��	�*�*�
��[�%�%�'�'�
��
�?�?����T�\�4�9�=�=�=��N�N�4�9�Q�<�(�(�(�"�i��l�^���;�	.��J���!�[�
�(�o�o�/�/����D�K����K���	�	�4�9�=�=�?�?�?����t�{�1�~�.�.�.��
�
�j�)�)�)��"�"�4�;�q�>�2�2�2�2�
�*�_�_���,�,�T�2�2�J�!�*�-�-�
.�
.�	��$6�6�6�.8�o�o�.?�.?���+�D�K�����T�\� #��C�G�I�I�t�y� A� A�C�C�C��N�N�9�-�-�-��M�M�*�-�-�-�����A�����rc��|j}|���|_|�|jd��|�|��|j���}|jD]X}|���|jc|_}|�|jd��|�|���YdSrG)r�rXr7r�r�r$)r�rSrr&r's     rr(zRangeValues.visit_Try�s����[�
� �o�o�'�'������t�y��|�$�$�$��
�
�j�!�!�!��[�%�%�'�'�
��}�	&�	&�G�&0�o�o�&7�&7���#�D�K���N�N�7�<��?�+�+�+��M�M�*�%�%�%�%�	&�	&rr\)rrrr)r�r�r7r�r�r�rrrrrIrrr"r(r�r�s@rrrs0���������&,�,�,�,�,�1�1�1�1�1�
J�
J�
J�
J�"�"�"�#�#�#����,)�)�)�)�)�)�$)�)�)�2)�)�)�(#�#�#�;/�;/�;/�z@/�@/�@/�Dm�m�m�^&�&�&�&�&�&�&rrr\)!r)�gastr*�collectionsr�
contextlibr�	functoolsrr�rr�pythran.intrinsicr�pythran.passmanagerr	�pythran.intervalr
rr�pythran.tablesr
r�NotImplementedErrorr�RuntimeErrorrr&r2rkr�r�rrrr�<module>res���H�H�����#�#�#�#�#�#�%�%�%�%�%�%�������)�)�)�)�)�)�)�)�'�'�'�'�'�'�.�.�.�.�.�.�C�C�C�C�C�C�C�C�C�C�.�.�.�.�.�.�.�.�	�	�	�	�	�/�	�	�	�	�	�	�	�	�,�	�	�	����>"�>"�>"�Bm�m�m�m�`Z:�Z:�Z:�Z:�Z:�n�Z:�Z:�Z:�zj�j�j�j�j��j�j�j�Z	R&�R&�R&�R&�R&�/�R&�R&�R&�R&�R&r

Youez - 2016 - github.com/yon3zu
LinuXploit