+
    i                     	   R t ^ RIHt ^ RIHtHtHt ^ RIH	t	H
t
  ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIt^ RIt^ RIt]P0                  ! ]4      t^ RIt^ RIt^ RIt^ RIt^ RIt]'       d    ^ RI t M^ RI t ^ RI"t"] '       d   ^ RI#t# ^ RI$t$^ RI%t%^ RI&t&^ R
I'H(t( ^ RI)H*t*H+t+H,t,H-t-H.t.H/t/H0t0H1t1H2t2H3t3H4t4H5t5H6t6 ^ RI7H8t8H9t9H:t:H;t;H<t< ^ RI=H>t>H?t? ^ RIH@t@HAtAHBtBHCtCHDtDHEtEHFtFHGtGHHtHHItIHJtJHKtKHLtLHMtMHNtNHOtOHPtP . R_OtQ]R! ]P4                  ! ]F'       d   ]P                  M]P                  ^4      R,           4      tU. R`OtVRR.tW^ RI=HXtX RtY]G! R4      tZ]G! R4      t[]R! ]P                  P                  R4      ;'       g    R4      t^ ! R R]_4      t`]F'       d9   ]P                  P                  tc]d! ]c]P                  P                  .4      tfR tgMR tgRaR lthR tiR tj]jtk ^ R IlHmtj RbR! ltnRcR" lto] f   RcR# ltoR$ tp]F'       d   R% tqR& trM^ R'IHstsHttt R( tqR) tr]@! ]qR*4       ]@! ]rR+4       R, tuR- tvR. twR/tx]G! R04      tyRdR1 ltzR2 t{R3t|]|P                  R44      t~R5 tR6 t^t]G! R74      tR8 tReR9 ltRfR: lt]F'       d   RfR; ltMRfR< lt]@! ]R=4       ]8! R>R?R@7      RgRA l4       t]d! RBEP                  4       4      t]d! RCEP                  4       4      t]d! RRD.4      tRhRE ltRF t ^ RGIHt RHtR0t]$'       d;   ]P'       d3   Ri]EP$                  u;8:  d   Rj8:  d   M M]$EP&                  ! 4       tRHtM^ RIIHt ]! 4       tRt]G! RJ4      t]F'       d   RHt ]! RKRL4       RM tMRHtRN t ]@! ]RP4       RQ t]%EP8                  t]tRR t ]EP@                  ! ^4       RHtRdRS lt]'       d   ]EPH                  ! 4       tM]EPL                  ! ]! 4       4      tRT tRU tRVt]8! R?RWRXRY7      ^
]3RZ l4       tRktR[ tRltR\ tR] tR^ tR#   ] d    ^ RIHt ^ RIHt  ELi ; i  ] d	    Rt R	t! ELi ; i  ] d    Rt$ ELi ; i  ] d     ELai ; i  ] d    Rt L  L; i  ] d    RtRtRtRtRtRO t ELi ; i  ] d    Rt Li ; i)mz4passlib.utils -- helpers for writing password hashes)JYTHON)
b2a_base64
a2b_base64Error)	b64encode	b64decode)Sequence)Iterable)lookup)update_wrapperNznot present under Jython)warn)BASE64_CHARS
AB64_CHARSHASH64_CHARSBCRYPT_CHARSBase64EngineLazyBase64Engineh64h64bigbcrypt64ab64_encodeab64_decodeb64s_encodeb64s_decode)deprecated_functiondeprecated_methodmemoized_propertyclasspropertyhybrid_method)ExpectedStringErrorExpectedTypeError)add_doc
join_bytesjoin_byte_valuesjoin_byte_elemsirangeimapPY3ujoin_unicodeunicodebyte_elem_value
nextgetterunicode_or_strunicode_or_bytes_typesget_method_functionsuppress_causePYPYg      ?linearlog2)MissingBackendError      PASSLIB_MAX_PASSWORD_SIZEi   c                   N   a  ] tR t^t o RtR tR tR tR tR t	R t
R tR	tV tR
# )SequenceMixinzw
helper which lets result object act like a fixed-length sequence.
subclass just needs to provide :meth:`_as_tuple()`.
c                    \        R 4      h)zimplement in subclass)NotImplementedErrorselfs   &T/var/www/html/photoedit/myenv/lib/python3.14/site-packages/passlib/utils/__init__.py	_as_tupleSequenceMixin._as_tuple   s    !"9::r5   c                4    \        V P                  4       4      # N)reprr@   r=   s   &r?   __repr__SequenceMixin.__repr__       DNN$%%r5   c                0    V P                  4       V,          # rC   r@   )r>   idxs   &&r?   __getitem__SequenceMixin.__getitem__   s    ~~$$r5   c                4    \        V P                  4       4      # rC   )iterr@   r=   s   &r?   __iter__SequenceMixin.__iter__   rG   r5   c                4    \        V P                  4       4      # rC   )lenr@   r=   s   &r?   __len__SequenceMixin.__len__   s    4>>#$$r5   c                (    V P                  4       V8H  # rC   rI   r>   others   &&r?   __eq__SequenceMixin.__eq__   s    ~~5((r5   c                .    V P                  V4      '       * # rC   )rX   rV   s   &&r?   __ne__SequenceMixin.__ne__   s    ;;u%%%r5    N)__name__
__module____qualname____firstlineno____doc__r@   rE   rK   rO   rS   rX   r[   __static_attributes____classdictcell__)__classdict__s   @r?   r:   r:      s2     ;&%&%)& &r5   r:   c                   \         P                  ! \        V 4      4      P                  pV'       g   R# VP	                  V4      pV'       d   VP
                  \        9  d   R# V\        V4      R,          ,          P
                  \        8H  # )*test if function accepts specified keywordFT)	inspect	signaturer/   
parametersgetkind_VAR_ANY_SETlist_VAR_KEYWORD)funckeyparamsargs   &&  r?   accepts_keywordru      sa    ""#6t#<=HHjjo388</d6l2&',,<<r5   c                    \         P                  ! \        V 4      4      pWP                  9   ;'       g    VP                  RJ# )rg   N)ri   
getargspecr/   argskeywords)rq   rr   specs   && r?   ru   ru      s6    !!"5d";<ii<<4==#<<r5   Fc                  a \        V\        4      '       d   V.p\        V P                  4      pV'       dN   \        V\        4      '       d   V.pV F.  oV'       d
   SV9   d   K  SV9   g   K  VP	                  S4       K0  	  V'       Ed   V EF  o\
        ;QJ d    V3R lV 4       F  '       g   K   RM	  RM! V3R lV 4       4      '       d   KF  V'       dR   \        V4       F6  w  r\        SV	4      '       d    MV'       g   K#  \        W4      '       g   K6   Ms	  \        V4      pMeV'       d\   \        \        V4      4       F@  w  r\        W4      '       g   K  \        V4      V
,
          pWx^,
          ,          V	8X  g   Q h M	  ^ pM^ pVP                  VS4       EK  	  V'       g   \        V4      V n        R# R# )a  
helper to update mixin classes installed in target class.

:param target:
    target class whose bases will be modified.

:param add:
    class / classes to install into target's base class list.

:param remove:
    class / classes to remove from target's base class list.

:param append:
    by default, prepends mixins to front of list.
    if True, appends to end of list instead.

:param after:
    optionally make sure all mixins are inserted after
    this class / classes.

:param before:
    optionally make sure all mixins are inserted before
    this class / classes.

:param dryrun:
    optionally perform all calculations / raise errors,
    but don't actually modify the class.
c              3   <   <"   T F  p\        VS4      x  K  	  R # 5irC   )
issubclass).0basemixins   & r?   	<genexpr>'update_mixin_classes.<locals>.<genexpr>   s     =ut:dE**u   TFN)
isinstancetypero   	__bases__removeany	enumerater}   rR   reversedinserttuple)targetaddr   appendbeforeafterdryrunbasesrJ   r   end_idxr   s   &&&&&&&    @r?   update_mixin_classesr      sa   < #te!!"E fd##XFEu|~U#	  sEs=u=sss=u=== !*5!1IC!%..v*T":": "2 e*C%.x%?MG!$..!%j72$U|t333 &@ C  LLe$? D  < r5   c              #    "   V^8  d   \        R4      h\        V \        4      '       d(   \        V 4      p^ pW28  d   W1,           pWV x  TpK  R# \        V \        4      '       dK   \        V 4      p \        P                  ! WQ4      p \        V4      p\        P                  ! T3T4      x  K?  \        R4      h  \         d     R# i ; i5i)z0
split iterable into chunks of <size> elements.
zsize must be positive integerzsource must be iterableN)
ValueErrorr   r   rR   r	   rN   	itertoolsislicenextStopIterationchain	TypeError)sourcesizeendinitr	chunk_itrfirsts   &&      r?   batchr     s      ax899&(##&kgA1+A  
FH	%	%6l!((3IY //5(I66122	 ! s*   BCB= 'C=CCCCc                @   \        V \        4      '       d%   \        V\        4      '       g   \        R4      hRpMI\        V \        4      '       d)   \        V\        4      '       g   \        R4      h\        pM\        R4      h\        V 4      \        V4      8H  pV'       d   T p^ pV'       g   Tp^pV'       d*   \        XV4       F  w  rgXWg,          ,          pK  	  X^ 8H  # \        XV4       F'  w  rgX\        V4      \        V4      ,          ,          pK)  	  X^ 8H  # )a  Check two strings/bytes for equality.

This function uses an approach designed to prevent
timing analysis, making it appropriate for cryptography.
a and b must both be of the same type: either str (ASCII only),
or any type that supports the buffer protocol (e.g. bytes).

Note: If a and b are of different lengths, or if an error occurs,
a timing attack could theoretically reveal information about the
types and lengths of a and b--but not their values.
z)inputs must be both unicode or both bytesF)r   r*   r   bytesr'   rR   zipord)leftrightis_py3_bytes	same_sizetmpresultlrs   &&      r?   consteqr   ;  s    * $  %))GHH	D%	 	 %''GHHCDD Tc%j(I  sE?CAaeOF #
 Q; sE?CAc!fs1vo%F #Q;r5   )compare_digestc                    V P                  4       p V P                  V4      '       d   V RR p V '       g   . # V P                  V4       Uu. uF  q"P                  4       NK  	  up# u upi )zJsplit comma-separated string into list of elements,
stripping whitespace.
Nrh   )stripendswithsplit)r   sepelems   && r?   
splitcommar     sX     \\^Fs	&,ll3&79&7dZZ\&7999s   
A%c                  aa \        V \        4      '       g   \        R\        V 4      : 24      h\        P
                  o\        P                  o\        VV3R lV  4       4      p\        P                  ! RV4      pV'       g   \        # \        P                  pV! V^ ,          4      '       d9   V! VR,          4      '       g   \        RV,           4      h\        P                  pMTp\        P                  p\        P                  p\        P                   p\        P"                  p\        P$                  p	\        P&                  p
\        P(                  p\        P*                  p\        P,                  pV EFn  pS! V4      '       d   Q R4       hS! V4      '       d   Q R4       hV! V4      '       d   \        RV,           4      hV! V4      '       d   \        RV,           4      hV! V4      '       d   \        R	V,           4      hV! V4      '       d   \        R
V,           4      hV	! V4      '       d   \        RV,           4      hV
! V4      '       d   \        RV,           4      hV! V4      '       d   \        RV,           4      hV! V4      '       d   \        RV,           4      hV! V4      '       d   \        RV,           4      hV! V4      '       g   EK_  \        RV,           4      h	  V# )a  Normalizes unicode strings using SASLPrep stringprep profile.

The SASLPrep profile is defined in :rfc:`4013`.
It provides a uniform scheme for normalizing unicode usernames
and passwords before performing byte-value sensitive operations
such as hashing. Among other things, it normalizes diacritic
representations, removes non-printing characters, and forbids
invalid characters such as ``\n``. Properly internationalized
applications should run user passwords through this function
before hashing.

:arg source:
    unicode string to normalize & validate

:param param:
    Optional noun identifying source parameter in error messages
    (Defaults to the string ``"value"``). This is mainly useful to make the caller's error
    messages make more sense contextually.

:raises ValueError:
    if any characters forbidden by the SASLPrep profile are encountered.

:raises TypeError:
    if input is not :class:`!unicode`

:returns:
    normalized unicode string

.. note::

    This function is not available under Jython,
    as the Jython stdlib is missing the :mod:`!stringprep` module
    (`Jython issue 1758320 <http://bugs.jython.org/issue1758320>`_).

.. versionadded:: 1.6
z"input must be unicode string, not c              3   p   <"   T F+  pS! V4      '       d   K  S! V4      '       d   \         MTx  K-  	  R # 5irC   )_USPACE)r~   cin_table_b1in_table_c12s   & r?   r   saslprep.<locals>.<genexpr>  s.      
A1~ 	*<??)s   666NFKCzmalformed bidi sequence in z$failed to strip B.1 in mapping stagez(failed to replace C.1.2 in mapping stagez$unassigned code points forbidden in z control characters forbidden in z$private use characters forbidden in z"non-char code points forbidden in zsurrogate codes forbidden in z!non-plaintext chars forbidden in z!non-canonical chars forbidden in z1display-modifying / deprecated chars forbidden inztagged characters forbidden in zforbidden bidi character in rh   )r   r*   r   r   
stringprepr   r   r)   unicodedata	normalize_UEMPTYin_table_d1r   in_table_d2in_table_a1in_table_c21_c22in_table_c3in_table_c4in_table_c5in_table_c6in_table_c7in_table_c8in_table_c9)r   paramdatais_ral_charis_forbidden_bidi_charr   r   r   r   r   r   r   r   r   r   r   r   s   &&             @@r?   saslprepr     s   X fg&&f( ) 	) **L((K 

 
D   .D ((K4748$$:UBCC!+!7!7 "- ((K!22((K((K((K((K((K((K((Kq>>I#II!??N$NN" q>>CeKLLA?%GHHq>>CeKLLq>>AEIJJq>><uDEEq>>@5HIIq>> @5HIIq>> ,.34 5 5q>>>FGG "!$$;eCDD= @ Kr5   c                .    \        R\        ,           4      h)zstub for saslprep()z>saslprep() support requires the 'stringprep' module, which is )r<   _stringprep_missing_reason)r   r   s   &&r?   r   r     s    ! #02L#M N 	Nr5   c                    \        V \        4      '       d   V P                  R4      p T \        ;QJ d    . R V 4       F  NK  	  5M! R V 4       4      ,          pVP	                  R4      # )at  Peform ``%`` formating using bytes in a uniform manner across Python 2/3.

This function is motivated by the fact that
:class:`bytes` instances do not support ``%`` or ``{}`` formatting under Python 3.
This function is an attempt to provide a replacement:
it converts everything to unicode (decoding bytes instances as ``latin-1``),
performs the required formatting, then encodes the result to ``latin-1``.

Calling ``render_bytes(source, *args)`` should function roughly the same as
``source % args`` under Python 2.

.. todo::
    python >= 3.5 added back limited support for bytes %,
    can revisit when 3.3/3.4 is dropped.
latin-1c              3   t   "   T F.  p\        V\        4      '       d   VP                  R 4      MTx  K0  	  R# 5i)r   N)r   r   decode)r~   rt   s   & r?   r   render_bytes.<locals>.<genexpr>,  s5      604 6@U5K5KCJJy1!$%04s   68)r   r   r   r   encode)r   rx   r   s   &* r?   render_bytesr     s_      &%  y)ee 6046ee 6046 6 6F==##r5   c                 .    \         P                  V R 4      # big)int
from_bytesvalues   &r?   bytes_to_intr   2  s    ~~eU++r5   c                 &    V P                  VR 4      # r   )to_bytesr   counts   &&r?   int_to_bytesr   4  s    ~~eU++r5   )hexlify	unhexlifyc                 ,    \        \        V 4      ^4      # )   )r   r   r   s   &r?   r   r   9  s    75>"%%r5   c                 B    \        R V^,          ,          V ,          4      # )z%%0%dx)r   r   s   &&r?   r   r   ;  s    (eQh/5899r5   z/decode byte string as single big-endian integerz/encode integer as single big-endian byte stringc                ^    \        \        V 4      \        V4      ,          \        V 4      4      # )z;Perform bitwise-xor of two byte strings (must be same size))r   r   rR   r   r   s   &&r?   	xor_bytesr   A  s"    T*\%-@@#d)LLr5   c                X    ^V^,
          \        V 4      ,          ,           pW,          RV # )z=
repeat or truncate <source> string, so it has length <size>
N)rR   r   r   mults   && r?   repeat_stringr   E  s*     qS[((DM5D!!r5   c                f    ^V^,
          \        V 4      ,          ,           p\        W,          V4      # )zF
variant of repeat_string() which truncates to nearest UTF8 boundary.
)rR   utf8_truncater   s   && r?   utf8_repeat_stringr   M  s*     qS[((D--r5        c                    \        V 4      pW8  d<   Vf#   \        V \        4      '       d   \        M\        pWW,
          ,          ,           # V RV # )z>right-pad or truncate <source> string, so it has length <size>N)rR   r   r*   _UNULL_BNULL)r   r   padcurs   &&& r?   right_pad_stringr  X  sC    
f+Cz;&vw77&VC48n$$et}r5   c                |  a a \        S \        4      '       g   \        S \        R4      h\        S 4      pV^ 8  d   \	        ^ W,           4      pW8  d   S # \        V^,           V4      pW8  d+   \        S V,          4      ^,          ^8w  d   MV^,          pK0  W8X  g   Q hS RV oVV 3R lpV! 4       '       g   Q hS# )a  
helper to truncate UTF8 byte string to nearest character boundary ON OR AFTER <index>.
returned prefix will always have length of at least <index>, and will stop on the
first byte that's not a UTF8 continuation byte (128 - 191 inclusive).
since utf8 should never take more than 4 bytes to encode known unicode values,
we can stop after ``index+3`` is reached.

:param bytes source:
:param int index:
:rtype: bytes
r   Nc                     <  SP                  R 4      p T P                  SP                  R 4      4      '       g   Q hR#   \         d     R# i ; i)utf-8T)r   UnicodeDecodeError
startswith)textr   r   s    r?   sanity_check#utf8_truncate.<locals>.sanity_check  sM    	==)D v}}W56666 " 		s   > AA)r   r   r    rR   maxminr+   )r   indexr   r  r   s   f&  @r?   r   r   c  s    2 fe$$x88 f+CqyAu{#| eai
C +6%=)D0D8
|| FU^F
 >>>Mr5   s	    
 aA:#!asciic                :    \         P                  V 4      \        8H  # )zRTest if codec is compatible with 7-bit ascii (e.g. latin-1, utf-8; but not utf-16))_ASCII_TEST_UNICODEr   _ASCII_TEST_BYTES)codecs   &r?   is_ascii_codecr    s    %%e,0AAAr5   c                    W8X  d   R# V '       d	   V'       g   R# \        V 4      P                  \        V4      P                  8H  # )z3Check if two codec names are aliases for same codecTF)_lookup_codecnamer   s   &&r?   is_same_codecr    s3    }U##}U';'@'@@@r5      c                   a \        V \        4      '       d   \        M\        o\        ;QJ d    V3R lV  4       F  '       d   K   R# 	  R# ! V3R lV  4       4      # )z<Check if string (bytes or unicode) contains only 7-bit asciic              3   ,   <"   T F	  qS8  x  K  	  R # 5irC   r]   )r~   r   r   s   & r?   r    is_ascii_safe.<locals>.<genexpr>  s     %f1ufs   FT)r   r   _B80_U80all)r   r   s   &@r?   is_ascii_safer!    s?    65))tA3%f%33%3%3%f%%%r5   c                   V'       g   Q h\        V \        4      '       d<   V'       d2   \        W14      '       g!   V P                  V4      P	                  V4      # V # \        V \
        4      '       d   V P	                  V4      # \        W4      h)a  Helper to normalize input to bytes.

:arg source:
    Source bytes/unicode to process.

:arg encoding:
    Target encoding (defaults to ``"utf-8"``).

:param param:
    Optional name of variable/noun to reference when raising errors

:param source_encoding:
    If this is specified, and the source is bytes,
    the source will be transcoded from *source_encoding* to *encoding*
    (via unicode).

:raises TypeError: if source is not unicode or bytes.

:returns:
    * unicode strings will be encoded using *encoding*, and returned.
    * if *source_encoding* is not specified, byte strings will be
      returned unchanged.
    * if *source_encoding* is specified, byte strings will be transcoded
      to *encoding*.
)r   r   r  r   r   r*   r   )r   encodingr   source_encodings   &&&&r?   r   r     sk    4 O8&%  =#K#K==188BBM	FG	$	$}}X&&!&00r5   c                    V'       g   Q h\        V \        4      '       d   V # \        V \        4      '       d   V P                  V4      # \	        W4      h)a  Helper to normalize input to unicode.

:arg source:
    source bytes/unicode to process.

:arg encoding:
    encoding to use when decoding bytes instances.

:param param:
    optional name of variable/noun to reference when raising errors.

:raises TypeError: if source is not unicode or bytes.

:returns:
    * returns unicode strings unchanged.
    * returns bytes strings decoded using *encoding*
)r   r*   r   r   r   r   r#  r   s   &&&r?   
to_unicoder'    sD    $ O8&'""	FE	"	"}}X&&!&00r5   c                     \        V \        4      '       d   V P                  V4      # \        V \        4      '       d   V # \	        W4      hrC   )r   r   r   r*   r   r&  s   &&&r?   to_native_strr)    s;    fe$$==**((M%f44r5   c                     \        V \        4      '       d   V # \        V \        4      '       d   V P                  V4      # \	        W4      hrC   )r   r   r*   r   r   r&  s   &&&r?   r)  r)    s;    fe$$M((==**%f44r5   a>  Take in unicode or bytes, return native string.

    Python 2: encodes unicode using specified encoding, leaves bytes alone.
    Python 3: leaves unicode alone, decodes bytes using specified encoding.

    :raises TypeError: if source is not unicode or bytes.

    :arg source:
        source unicode or bytes string.

    :arg encoding:
        encoding to use when encoding unicode or decoding bytes.
        this defaults to ``"utf-8"``.

    :param param:
        optional name of variable/noun to reference when raising errors.

    :returns: :class:`str` instance
    z1.6z1.7)
deprecatedremovedc                    \        WRR7      # )z'deprecated, use to_native_str() insteadhash)r   )r)  )r   r#  s   &&r?   to_hash_strr/  $  s     88r5   z true t yes y on 1 enable enabledz#false f no n off 0 disable disablednonec                B   VR9   g   Q h\        V \        4      '       dY   V P                  4       P                  4       pV\        9   d   R# V\
        9   d   R# V\        9   d   V# \        RV: RV : 24      h\        V \        4      '       d   V # V f   V# \        V 4      # )zP
helper to convert value to boolean.
recognizes strings such as "true", "false"
TFzunrecognized z value: )TFN)	r   r.   lowerr   	_true_set
_false_set	_none_setr   bool)r   r0  r   cleans   &&& r?   as_boolr8  -  s    
 &&&&%/00##%IJIKuEFF	E4	 	 	E{r5   c                    \         '       g   \        V \        4      '       g   R#  V P                  R4       R#   \         d     R# i ; i)zs
UT helper --
test if value is safe to pass to crypt.crypt();
under PY3, can't pass non-UTF8 bytes to crypt.crypt.
Tr  F)crypt_accepts_bytesr   r   r   r  r   s   &r?   is_safe_crypt_inputr;  G  s?     *UE":":W s   9 AA)cryptT)nullcontextz*:!   xxc                 *   \         '       df   \        V \        4      '       d   V P                  R 4      p \        V 9   d   \        R4      h\        V\        4      '       d   VP                  R4      pM\        V \        4      '       d2   T p V P                  R 4      p T P                  R 4      T8X  g   Q R4       h\        V 9   d   \        R4      h\        V\        4      '       d   VP                  R4      p \        ;_uu_ 4        \        W4      pRRR4       \        X\        4      '       d   TP                  R4      pT'       d   T^ ,          \        9   d   R# T#   \         d     R# i ; i  + '       g   i     Lg; i  \         d     R# i ; i)r  null character in secretr  Nz"utf-8 spec says this can't happen!)r:  r   r*   r   r  r   r   r   r  _NULL_safe_crypt_lock_cryptOSError_invalid_prefixes)secretr.  origr   s   &&  r?   
safe_cryptrI    sM   "" fg..#]]73FV#$%?@@dG,,;;w/D
 fe,,!D$!'w!7
 "==1T9 E DE9F?$%?@@dE**;;w/D%%#F1F & &%((w/VAY*;;M3 . $#$ &%  	sB   E 7F E0F E-,E-0F 	;F  F FFc                    \        V \        4      '       d   V P                  R 4      p \        V 9   d   \	        R4      h\        V\        4      '       d   VP                  R4      p\
        ;_uu_ 4        \        W4      pRRR4       X'       g   R# VP                  R4      pV^ ,          \        9   d   R# V#   + '       g   i     LA; i)r  rA  r  N)	r   r*   r   rB  r   rC  rD  r   rF  )rG  r.  r   s   && r?   rI  rI    s    &'**w/ !;<<$(({{7+!!- "]]7+Fay--M "!s   3B88C	c                     R # rC   r]   rG  r.  s   &&r?   rI  rI  ]  s    r5   a  Wrapper around stdlib's crypt.

    This is a wrapper around stdlib's :func:`!crypt.crypt`, which attempts
    to provide uniform behavior across Python 2 and 3.

    :arg secret:
        password, as bytes or unicode (unicode will be encoded as ``utf-8``).

    :arg hash:
        hash or config string, as ascii bytes or unicode.

    :returns:
        resulting hash as ascii unicode; or ``None`` if the password
        couldn't be hashed due to one of the issues:

        * :func:`crypt()` not available on platform.

        * Under Python 3, if *secret* is specified as bytes,
          it must be use ``utf-8`` or it can't be passed
          to :func:`crypt()`.

        * Some OSes will return ``None`` if they don't recognize
          the algorithm being used (though most will simply fall
          back to des-crypt).

        * Some OSes will return an error string if the input config
          is recognized but malformed; current code converts these to ``None``
          as well.
    c                    \        V\        4      '       g   Q R\        V4      ,          4       hV'       g   Q R4       h\        W4      V8H  # )zcheck if :func:`crypt.crypt` supports specific hash
:arg secret: password to test
:arg hash: known hash of password to use as reference
:returns: True or False
z#hash must be unicode_or_str, got %szhash must be non-empty)r   r-   r   rI  rL  s   &&r?   
test_cryptrN    sH     dN++ ;-T
:;+)))4f#t++r5   c                   \         P                  ! RV 4      pV'       di   \        ;QJ d2    . R VP                  ^4      P	                  R4       4       F  NK  	  5# ! R VP                  ^4      P	                  R4       4       4      # R# )zhelper to parse version stringz(\d+(?:\.\d+)+)c              3   8   "   T F  p\        V4      x  K  	  R # 5irC   )r   )r~   r   s   & r?   r    parse_version.<locals>.<genexpr>  s     A+@4SYY+@s   .N)researchr   groupr   )r   ms   & r?   parse_versionrW    sa    
		$f-AuA1771:+;+;C+@AuAuA1771:+;+;C+@AAAr5   c           	     Z   ^ RI Hp \        V R4      '       d$   \        V R4      '       d    V P                  4       p \        R4      T \        \        R4      '       d   \        P                  ! 4       MR\        \        4       4      \        P                  ! 4       \        4       \        '       d&   \        P                  ! ^ 4      P                  R4      M^ 3,          p\!        V! VP#                  R4      4      P%                  4       ^4      #   \         d    T P                  R	4      p  Li ; i)
z.generate prng seed value from system resources)sha512getstategetrandbitsz%s %s %s %.15f %.15f %sgetpidNr   r  i   )hashlibrY  hasattrrZ  r<   r[  r(   osr\  idobjecttimetickhas_urandomurandomr   r   r   	hexdigest)r   rY  r
  s   &  r?   genseedrg    s    uj!!ge]&C&C	/NN$E
 &' r8,,		$ 	68 			 -8K

2i(Q#+
 
D( vdkk'*+557<<1 # 	/ %%g.E	/s   D D*)D*c                P   a a S'       g   \         # VV 3R lp\        V! 4       4      # )z]return byte-string containing *count* number of randomly generated bytes, using specified rngc               3      <"   SP                  S^,          4      p ^ pVS8  d    V ^,          x  V ^,          p V^,          pK&  R# 5i)   N)r[  )r   r   r   rngs     r?   helpergetrandbytes.<locals>.helperM  sE     q)%i$,aKEFA s   AA)_BEMPTYr#   )rk  r   rl  s   ff r?   getrandbytesro  B  s!      FH%%r5   c                  a aaa S^ 8  d   \        R4      h\        S4      oS^ 8X  d   \        R4      hS^8X  d
   SS,          # VVVV 3R lp\        S\        4      '       d   \	        V! 4       4      # \        V! 4       4      # )z|return string containing *count* number of chars/bytes, whose elements are drawn from specified charset, using specified rngzcount must be >= 0zalphabet must not be emptyc               3      <"   SP                  ^ SS,          4      p ^ pVS8  d'   SV S,          ,          x  V S,          p V^,          pK-  R# 5i)    N)	randrange)r   r   charsetr   lettersrk  s     r?   rl  getrandstr.<locals>.helperf  sM     a%0%i%'/**gEFA s   AA)r   rR   r   r*   r)   r$   )rk  rt  r   rl  ru  s   fff @r?   
getrandstrrw  W  sx     qy-..'lG!|566!|  '7##FH%%vx((r5   42346789ABCDEFGHJKMNPQRTUVWXYZabcdefghjkmnpqrstuvwxyzz2.0z/passlib.pwd.genword() / passlib.pwd.genphrase())r+  r,  replacementc                "    \        \        W4      # )aG  generate random password using given length & charset

:param size:
    size of password.

:param charset:
    optional string specified set of characters to draw from.

    the default charset contains all normal alphanumeric characters,
    except for the characters ``1IiLl0OoS5``, which were omitted
    due to their visual similarity.

:returns: :class:`!str` containing randomly generated password.

.. note::

    Using the default character set, on a OS with :class:`!SystemRandom` support,
    this function should generate passwords with 5.7 bits of entropy per character.
)rw  rk  )r   rt  s   &&r?   generate_passwordr{  v  s    , c7))r5   c                   a  \         ;QJ d#    V 3R l\         4       F  '       d   K   R# 	  R# ! V 3R l\         4       4      # )z4check if object follows the :ref:`password-hash-api`c              3   <   <"   T F  p\        SV4      x  K  	  R # 5irC   r^  r~   r  objs   & r?   r   #is_crypt_handler.<locals>.<genexpr>       =ndwsD!!nr   FT)r   _handler_attrsr  s   fr?   is_crypt_handlerr    .     3=n=33=3=3=n===r5   c                   a  \         ;QJ d#    V 3R l\         4       F  '       d   K   R# 	  R# ! V 3R l\         4       4      # )zOcheck if object appears to be a :class:`~passlib.context.CryptContext` instancec              3   <   <"   T F  p\        SV4      x  K  	  R # 5irC   r~  r  s   & r?   r   #is_crypt_context.<locals>.<genexpr>  r  r   FT)r   _context_attrsr  s   fr?   is_crypt_contextr    r  r5   c                N    RV P                   9   ;'       d    \        V RR4      RJ# )z_check if handler provides the optional :ref:`rounds information <rounds-attributes>` attributesrounds
min_roundsNsetting_kwdsgetattrhandlers   &r?   has_rounds_infor    s0    ,,, = =G\40<>r5   c                N    RV P                   9   ;'       d    \        V RR4      RJ# )z[check if handler provides the optional :ref:`salt information <salt-attributes>` attributessaltmin_salt_sizeNr  r  s   &r?   has_salt_infor    s3    g*** @ @G_d34?Ar5   )r   sys_bitsunix_crypt_schemesrounds_cost_valuesr   r   r   r   r  r!  r   r'  r)  	has_cryptrN  rI  rc  rk  ro  rw  r{  r  r  r  r  )sha512_cryptsha256_crypt
sha1_cryptbcrypt	md5_crypt
bsdi_crypt	des_crypt)NNFNNF),r   rC   )r  r   N)r  r   )r  )Nboolean)      rr  )r  rj  rj  )r  r  context_kwdsverifyr.  identify)needs_update	genconfiggenhashr  encryptr  )rb   passlib.utils.compatr   binasciir   r   r   _BinAsciiErrorbase64r   r   collections.abcr   r	   ImportErrorcollectionscodecsr
   r  	functoolsr   r   ri   logging	getLoggerr^   logmathr_  sysrandomrS  r   r   rb  r   	threadingtimeittypeswarningsr   passlib.utils.binaryr   r   r   r   r   r   r   r   r   r   r   r   r   passlib.utils.decorr   r   r   r   r   passlib.excr   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   __all__r   maxsizemaxintr  r  r  r4   rn  r   r   environrl   MAX_PASSWORD_SIZEra  r:   	ParameterVAR_KEYWORDrp   setVAR_POSITIONALrn   ru   r   r   r   str_consteqhmacr   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   r3  r4  r5  r8  r;  r<  rD  r  rB  pypy_version_infoLockrC  crypt_needs_lockr=  rF  r:  r   rI  rN  default_timertimerrc  rW  re  rd  r<   rg  SystemRandomrk  Randomro  rw  
_52charsetr{  r  r  r  r  r  r  r]   r5   r?   <module>r     s   : ( D D '%((
 + $   g''1  	 
  		@
          ?M M M M M'\ txxs

A>DE   )  , 
B%
C& 

'BCKKtL &F &4  $$00Lg&7&7&F&FGHL	==
R(n3>8| 	.	:}@ N$, ,, ,&: G H G HM". 
	
6AL ( '..w7 BA y&
#1J14 55 	* u59 69 288:;	6<<>?
V	4s% IE Ti3+@+@MIM %>>+   	5&=  %

 #	7D!+	^ #	  
  	<, 	,JJqMK=B 



C --	
"C
&*): D
u!RTz *T*2
>

>>
AK%  %$$$%&  @
%?"@  Ij
  		D  	("'	 _  FIz  Ks}   O? /P 	P+ P; #Q 	Q	 Q5 ?PPP('P(+	P87P8;QQ		QQQ21Q25	R R