
    >Tf]                         d dl Z d dlmZ d dlmZmZ dZd ZddZ e	            fd	Z
d
 Zd Z e j        d          fdZd Zd Zd ZdS )    N)NumericRange)countgroupby)	array_to_rangesarray_to_stringcheck_ranges_overlap	deepmergedrangeflatten_dictranges_to_stringshallow_compare_dictstring_to_rangesc                    t          |           }|                                D ]Z\  }}|| v rLt          | |         t                     r1|r/t          |t                     rt          | |         |          ||<   U|||<   [|S )zO
    Deep merge two dictionaries (new into original) and return a new dict
    )dictitems
isinstancer	   )originalnewmergedkeyvals        3/var/www/html/netbox-4.1.3/netbox/utilities/data.pyr	   r	      s     (^^FIIKK  S(??z(3->>?3?:VY[_K`K`?#HSM377F3KKF3KKM     .c                     i }|                                  D ]a\  }}|r|                    ||g          n|}t          |          t          u r&|                    t          |||                     \|||<   b|S )a  
    Flatten nested dictionaries into a single level by joining key names with a separator.

    :param d: The dictionary to be flattened
    :param prefix: Initial prefix (if any)
    :param separator: The character to use when concatenating key names
    )prefix	separator)r   jointyper   updater   )dr   r   retkvr   s          r   r   r   #   s     C		  1-3:innfa[)))77d??JJ|AcYGGGHHHHCHHJr   c                     i }|                                 D ](\  }}||v r
|                     |          |k    r|||<   )|S )z
    Return a new dictionary of the different keys. The values of `destination_dict` are returned. Only the equality of
    the first layer of keys/values is checked. `exclude` is a list or tuple of keys to be ignored.
    )r   get)source_dictdestination_dictexclude
differencer   values         r   r   r   5   s[    
 J&,,.. $ $
U'>>??35((#JsOr   c                     d t          t          |           t                      fd          D             }d |D             S )z
    Convert an arbitrary array of integers to a list of consecutive values. Nonconsecutive values are returned as
    single-item tuples. For example:
        [0, 1, 2, 10, 14, 15, 16] => [(0, 2), (10,), (14, 16)]"
    c              3   :   K   | ]\  }}t          |          V  d S N)list).0_xs      r   	<genexpr>z"array_to_ranges.<locals>.<genexpr>O   s=        AqQ     r   c                 &    t          |          | z
  S r/   )next)r3   cs     r   <lambda>z!array_to_ranges.<locals>.<lambda>P   s    QRS r   c                 X    g | ]'}|d          |d         fdt          |                   (S )r   N)len)r1   gs     r   
<listcomp>z#array_to_ranges.<locals>.<listcomp>R   s@       #$1qugs1vvg  r   )r   sortedr   )arraygroups     r   r   r   I   s^     #F5MMuww3S3S3STT  E (-   r   c                    g }t          |           }|D ]d}t          |          dk    r)|                    t          |d                              >|                    |d          d|d                     ed                    |          S )z
    Generate an efficient, human-friendly string from a set of integers. Intended for use with ArrayField.
    For example:
        [0, 1, 2, 10, 14, 15, 16] => "0-2, 10, 14-16"
       r   -z, )r   r;   appendstrr   )r?   r#   rangesr,   s       r   r   r   W   s     CU##F 1 1u::??JJs58}}%%%%JJ%(//U1X//000099S>>r   rB   c              #      K   t          j        |           t          j        |          t          j        |          }}} | |k     r| |k     r| V  | |z  } | |k     dS dS | |k    r| V  | |z  } | |k    dS dS )z?
    Decimal-compatible implementation of Python's range()
    N)decimalDecimal)startendsteps      r   r
   r
   k   s       u--ws/C/CW_UYEZEZ3Es{{ckkKKKTME ckkkkkk ckkKKKTME ckkkkkkr   c                     |                      d            t          dt          |                     D ]X}| |dz
           }|j        r|j        n	|j        dz
  }| |         j        r| |         j        n| |         j        dz   }||k    r dS YdS )z<
    Check for overlap in an iterable of NumericRanges.
    c                     | j         S r/   )lower)r3   s    r   r8   z&check_ranges_overlap.<locals>.<lambda>~   s    ag r   )r   rB   TF)sortranger;   	upper_incupper	lower_incrO   )rF   i
prev_range
prev_upperrO   s        r   r   r   z   s     KK%%K&&&1c&kk""  AE]
)3)=WZ%%:CSVWCW
#)!9#6Oq	F1IOa<O44  5r   c                     | sdS g }| D ]L}|j         r|j        n	|j        dz   }|j        r|j        n	|j        dz
  }|                    | d|            Md                    |          S )z
    Generate a human-friendly string from a set of ranges. Intended for use with ArrayField. For example:
        [[1, 100)], [200, 300)] => "1-99,200-299"
    r   rB   rC   ,)rT   rO   rR   rS   rD   r   )rF   outputrrO   rS   s        r   r   r      s    
  rF * *;7AGaK;7AGaK(((())))88Fr   c           	      *   | sdS |                      dd           g }|                     d          D ]`}d|vr dS |                    d          \  }}|                    t          t	          |          t	          |          d                     a|S )z
    Given a string in the format "1-100, 200-300" return an list of NumericRanges. Intended for use with ArrayField.
    For example:
        "1-99,200-299" => [NumericRange(1, 100), NumericRange(200, 300)]
    N r   rY   rC   z[])bounds)replacesplitrD   r   int)r,   values
dash_rangerO   rS   s        r   r   r      s      t	MM#rFkk#&& I I
j  44!'',,ul3u::s5zz$GGGHHHHMr   )r   r   )rH   )django.db.backends.postgresql.psycopg_anyr   	itertoolsr   r   __all__r	   r   tupler   r   r   rI   r
   r   r   r    r   r   <module>ri      s     B B B B B B $ $ $ $ $ $ $ $
"
 
 
   $ AF    (    ( ,GOA..             r   