
    L^if                     F   d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlmZ d dlmZmZ d dlmZ d dlmZ d dlZd dlmZ d dlmZmZ d dlZd dlmZ d d	lmZmZ d d
lm Z m!Z!m"Z"m#Z#m$Z$m%Z% 	 d dl&m'Z( n# e)$ r dZ(Y nw xY wdZ*ej+        j
        j,        j-        Z-ej+        j
        j,        j.        Z.	 dZ/dddZ0dZ1dZ2dZ3dZ4g dZ5g dZ6g dZ7g dZ8e7e8z   Z9dddddddd d!d"d#d$d%d&Z:d'Z;d(Z<d)Z=d*Z>e=ej?        e>ej@        iZAe=fd+ZBd, ZCd- ZDd. ZEd/ ZFd0 ZGd1 ZHdd3ZId4 ZJd5 ZKd6 ZLd7 ZMd8 ZNd9 ZOd: ZPd; ZQd< ZRd= ZSd> ZTd? ZUd@ ZVdA ZWe=dBfdCZXddDZYdE ZZdF Z[dG Z\dH Z]dI Z^dJ Z_dK Z`dL ZadM ZbdN ZcddPZddQ ZedR ZfddTZgdU ZhdV ZidW ZjdX ZkdY ZldZ Zmd[ Znd\ Zod] Zpd^ Zqd_ Zrd` Zsda Ztdb Zudc Zvdd Zwde Zxdf Zydg Zzdh Z{didjdkdldmdndodpdqdrdsdtdudvZ|i dwdxdydxdzd{d|d{d}d~dd~dddddddddddddddddddddddddddddddddddZ}dd~                    e}                                          z   dz   Zd Zd Zd Zd Zd Zd Zd Zd ZddZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZddZddZd Zd ZddZd ZddZddZdS )    N)OrderedDict)datetimedate)Fraction)Number)	iteritems)ProxyManagerPoolManager)
auth_token)TCPKeepAlivePoolManagerTCPKeepAliveProxyManager)PY3to_bytesto_bytearray	to_stringstring_typesurlparse)Pathz(\$\([a-zA-Z]\w+\))res.cloudinary.comautolimit)widthcropz,^(?P<value>(\d+\.)?\d+)(?P<modifier>[%pP])?$z(^(\d+\.)?\d+[%pP]?\.\.(\d+\.)?\d+[%pP]?$z^(\d+)\.(\d+)?$zdftp:|https?:|s3:|gs:|data:([\w-]+\/[\w-]+(\+[\w-]+)?)?(;[\w-]+=[\w-]+)*;base64,([a-zA-Z0-9\/+\n=]+)$))font_weightnormal)
font_styler   )text_decorationnone)
text_alignN)stroker   )
api_secretr   cdn_subdomain
cloud_namecnameformatprivate_cdnresource_typesecuresecure_cdn_subdomainsecure_distributionshortensign_urlssl_detectedtype
url_suffixuse_root_pathversionlong_url_signaturesignature_algorithm).	public_idpublic_id_prefixcallbackr%   r.   backupfacesimage_metadatamedia_metadataexifcolorsuse_filenameunique_filenamedisplay_nameuse_filename_as_display_namediscard_original_filenamefilename_override
invalidatenotification_urleager_notification_urleager_asynceval
on_successproxyfolderasset_folder$use_asset_folder_as_public_id_prefixunique_display_name	overwrite
moderationraw_convertquality_overridequality_analysisocrcategorization	detectionsimilarity_searchvisual_searchbackground_removalupload_presetphashreturn_delete_tokenauto_taggingasynccinemagraph_analysisaccessibility_analysis)	timestamptransformationheaderseagertagsallowed_formatsface_coordinatescustom_coordinatesregionscontextr\   responsive_breakpointsaccess_controlmetadataaudio_codecaudio_frequencybit_ratecolor_spacedefault_imagedelaydensityfetch_formatgravityprefixpagestreaming_profilevideo_sampling)acafbrcsddldnfgppgspvs       sha1sha256c                     	 t           |         }n0# t          $ r# t          d                    |                    w xY w |t	          |                                                     S )a  
    Computes string hash using specified algorithm and return HEX string representation of hash.

    :param s:         String to compute hash for
    :param algorithm: The name of algorithm to use for computing hash

    :return: HEX string of computed hash value
    zUnsupported hash algorithm: {})signature_algorithmsKeyError
ValueErrorr%   r   	hexdigest)s	algorithmhash_fns      3D:\Nbitz\venv\Lib\site-packages\cloudinary/utils.pycompute_hex_hashr      sr    M&y1 M M M9@@KKLLLM78A;;))+++s    -=c                 L    t          | t          t          f          r| S | g S | gS N)
isinstancelisttuple)args    r   build_arrayr      s.    #e}%% 
		5L    c                    | g S t          | t                    rt          j        | t                    } t          | t
                    r| g} t          |           D ]b\  }}t          |t                    rt          j        |t                    | |<   t          | |         t
                    st          d          c| S )a  
    Converts a value that can be presented as a list of dict.

    In case top level item is not a list, it is wrapped with a list

    Valid values examples:
        - Valid dict: {"k": "v", "k2","v2"}
        - List of dict: [{"k": "v"}, {"k2","v2"}]
        - JSON decodable string: '{"k": "v"}', or '[{"k": "v"}]'
        - List of JSON decodable strings: ['{"k": "v"}', '{"k2","v2"}']

    Invalid values examples:
        - ["not", "a", "dict"]
        - [123, None],
        - [["another", "list"]]

    :param val: Input value
    :type val: Union[list, dict, str]

    :return: Converted(or original) list of dict
    :raises: ValueError in case value cannot be converted to a list of dict
    N)object_pairs_hookzExpected a list of dicts)r   strjsonloadsr   dict	enumerater   )valindexitems      r   build_list_of_dictsr      s    . {	#s =j<<<#t e ~~ 9 9tdC   	IDKHHHCJ#e*d++ 	97888	9Jr   c                     t          |           } t          |           dk    r:t          | d         t                    rd                    d | D                       S t          d | D                       S )Nr   |c                 f    g | ].}d                      d t          |          D                       /S ),c                 ,    g | ]}t          |          S  r   .0is     r   
<listcomp>z2encode_double_array.<locals>.<listcomp>.<listcomp>   s    "F"F"Fa3q66"F"F"Fr   joinr   )r   inners     r   r   z'encode_double_array.<locals>.<listcomp>   s;    [[[E"F"F;u3E3E"F"F"FGG[[[r   c                 ,    g | ]}t          |          S r   r   r   s     r   r   z'encode_double_array.<locals>.<listcomp>   s    ...1A...r   )r   lenr   r   r   encode_listarrays    r   encode_double_arrayr      so    E
5zzA~~*U1Xt44~xx[[UZ[[[\\\.....///r   c                     t          | t                    rOt          r|                                 }n|                                 }d                    d |D                       S | S )Nr   c              3   ,   K   | ]\  }}|d z   |z   V  dS )=Nr   r   kvs      r   	<genexpr>zencode_dict.<locals>.<genexpr>   s.      88$!QS1888888r   )r   r   r   itemsr   r   )r   r   s     r   encode_dictr      s^    #t 9 	$IIKKEEMMOOExx88%888888Jr   c                     t          | t          t          f          rt          |           } t	          |                               dd                              dd          S )z
    Escape "=" and "|" delimiter characters and json encode lists

    :param value: Value to escape
    :type value: int or str or list or tuple

    :return: The normalized value
    :rtype: str
    r   z\=r   z\|)r   r   r   json_encoder   replacevalues    r   normalize_context_valuer      sS     %$'' #E""u::c5))11#u===r   c                     t          | t                    s| S d                    d t          |           D                       S )a  
    Encode metadata fields based on incoming value.

    List and tuple values are encoded to json strings.

    :param context: dict of context to be encoded

    :return: a joined string of all keys and values properly escaped and separated by a pipe character
    r   c              3   b   K   | ]*\  }}d                      |t          |                    V  +dS )z{}={}N)r%   r   r   s      r   r   z!encode_context.<locals>.<genexpr>  s=      cc1W^^A'>q'A'ABBccccccr   )r   r   r   r   )ri   s    r   encode_contextr     sF     gt$$ 88ccPYZaPbPbccccccr   Fc                 n    t          | t                    s| | S t          j        | t          d|          S )z
    Converts value to a json encoded string

    :param value: value to be encoded
    :param sort_keys: whether to sort keys

    :return: JSON encoded string
    N)r   :)default
separators	sort_keys)r   r   r   dumps__json_serializer)r   r   s     r   r   r   !  s:     % :e%6:Ybccccr   c                 ,    |                      d          S )z
    Encodes date object to `dd-mm-yyyy` format string

    :param date_obj: datetime.date object to encode

    :return: Encoded date as a string
    z%d-%m-%Y)strftime)date_objs    r   encode_date_to_usage_api_formatr   1  s     Z(((r   c                     |                      dt          j                    j                  }|                     dd          dk    r|sdS |                      dd          }d| vr|| d<   dS dS )z
    When upload type is fetch, remove the format options.
    In addition, set the fetch_format options to the format value unless it was already set.
    Mutates the "options" parameter!

    :param options: URL and transformation options
    use_fetch_formatr.   uploadfetchNr%   rt   )pop
cloudinaryconfigr   get)optionsr   resource_formats      r   patch_fetch_formatr   <  s     {{#5z7H7J7J7[\\{{68$$//8H/kk(D11OW$$"1 %$r   c                  F   |                      dt          j                    j                  }|                      dd           }|r|                    d          \  | d<   | d<   |                     d          }|                     d          }d| v pd| v }|                      dd           }d	                    d
 t          |                      dd                     D                       }|p|p|dk    p|dk    p|}|rIt          |          	                    d          s$t          |          dk    st          |          s|r| d= |r't          |          dk    st          |          s|r| d= |                      dd           }	|	r|	                    dd          }	|                      dd           }
|
r|
                    dd          }
t          |                      dd                     }t          d |D                       r#d }t          t          ||                    }d }nd	                    |          }g }|                      dd           }t          |t                    r d                    d |D                       }nYt          |t                     rDd                    d t          |                                          d         D                       }|                      dd           }t          |t                     rS|                    dd                              dd          }d|t          |                    dd                     d!z  }d	                    t          |                      d"d                               }|                      d#t          j                    j                  }t'          |                      d$d                     }|                      d%d           }t)          |          }|d k    r|}|                      d&d           }t'          |          }|d k    r|}t+          |                      d'd                     }|r*t)          |d                   }t'          |d(                   }t-          |                      d)d                     }|                      d*d           }t          |t.                    r,t          |j                  dz   t          |j                  z   }t5          |                      dd           d          }t5          |                      dd           d          }t7          |                      d+d                     }t9          |                      d,d                     }t;          |                      d-d                     }t=          |                      d.d                     } i d/t?          |          d0t?          |          d1|	d2|d3|d4|
d#t?          |          d5t?          |          d6t?          |          d7t?          |          d8|d9|p|d.| d:t?          |          d;tA          |                      d<d                     d=|d>t?          |                      d?d                     t?          |                      d@d                     tC          |                      dAd                     t?          |          ||t?          |          t?          |                      dd                     t?          |                      dBd                     |t?          |                      dCd                     dD
}!tD                                          D ]\  }"}#|                      |#d           |!|"<   |                      dEi           }$g }%|                                 D ]]\  }&}'tG          j$        dF|&          rC|%%                    dG&                    |&t?          t          |'                                         ^|%'                                 |$rT|$D ]Q}(|%%                    dG&                    |(d         t?          t          |(d(                                                  RdH                    |%          }$tQ          dI |!                                D                       })|$r#|))                    dt          |$                     |&|))                    ddJt          |          z              dK| v r<| dK         s| dK         dk    r(|)%                    |                      dK                     dH                    |)          }*||*gz   }+|r5t          j                    j*        ptV          },|+tY          dQi |,d         gz  }+dL                    dM |+D                       }-t          |          	                    d          s|rdN| dO<   |dk    rdN| dP<   |-| fS )RNresponsive_widthsizexr   heightunderlayoverlayr   .c                 ,    g | ]}t          |          S r   r   )r   r   s     r   r   z2generate_transformation_string.<locals>.<listcomp>X  s    VVVUc%jjVVVr   anglefitr   r   owoh
background#zrgb:colorra   c              3   @   K   | ]}t          |t                    V  d S r   )r   r   )r   bss     r   r   z1generate_transformation_string.<locals>.<genexpr>h  s,      
?
?B:b$
?
?
?
?
?
?r   c                 |    t          | t                    rt          di | d         S t          |           d         S )Nr   )ra   r   )r   r   generate_transformation_string)r   s    r   recursez/generate_transformation_string.<locals>.recursei  sC    "d## ?5;;;;A>>1DDDQGGr   effectr   c                 ,    g | ]}t          |          S r   r   r   r   s     r   r   z2generate_transformation_string.<locals>.<listcomp>v  s    222a3q66222r   c                 ,    g | ]}t          |          S r   r   r   s     r   r   z2generate_transformation_string.<locals>.<listcomp>x  s    CCCa3q66CCCr   r   borderblackz%(width)spx_solid_%(color)s   )r   r   flagsdprdurationstart_offset
end_offsetoffset   video_codecaspect_ratioifcustom_functioncustom_pre_functionfpsaarbboccodueeoflfnhkikeyframe_intervalloopacityqualityradiusyzoom)
qrsotuwr   r   vcz	variablesz^\$z{0}_{1}r   c                 N    g | ]"\  }}|s|d k    |dz   t          |          z   #S )r   _r   )r   paramr   s      r   r   z2generate_transformation_string.<locals>.<listcomp>  s=    qqq\aqejnoeoeoECK#e**4eoeoeor   if_raw_transformation/c                     g | ]}||S r   r   )r   transs     r   r   z2generate_transformation_string.<locals>.<listcomp>  s    @@@e%@E@@@r   T
responsivehidpir   )-r   r   r   r   splitr   r   r   r   
startswithis_fractionr   anyr   mapr   r   r   r  norm_range_valuenorm_auto_range_valuesplit_rangeprocess_video_codec_paramr   	numeratordenominatorprocess_layerprocess_conditionalprocess_custom_functionprocess_custom_pre_functionprocess_fpsnormalize_expression
process_kiprocess_radius_SIMPLE_TRANSFORMATION_PARAMSrematchappendr%   sortsortedinsertresponsive_width_transformation'DEFAULT_RESPONSIVE_WIDTH_TRANSFORMATIONr   ).r   r   r   r   r   	has_layerr   r   no_html_sizesr   r   base_transformationsr   named_transformationr   r   border_colorr   r  r  so_rawr  eo_rawr  r  r  r  r   r   if_valuer
  r  r  paramsr-  optionr*  
var_paramskeyr   varsorted_paramsra   transformationsrO  urls.                                                 r   r   r   N  s8
   {{#5z7H7J7J7[\\;;vt$$D >.2jjoo+'(+KK  E[[""Fw&AI,@I;;vt$$DHHVVk'++gt:T:T.U.UVVVWWE^^$%-^47?^N^M #e**''// 3u::3E3EUZI[I[3E_l3EG 3v;;$&&+f*=*=&&H\400J 5''V44
KK&&E +c6**&w{{3CT'J'JKK

?
?*>
?
?
??? 
"	H 	H 	H
  $C1E$F$FGG#"xx(<==![[4((F&$ E22622233	FD	!	! ECC4+?+?+BCCCDD[[4((F&$ Xzz'733;;CHH.<;>vzz'ST?U?U;V;V2X 2X X HH[Wd!;!;<<==E
++eZ.004
5
5CJ = =>>H[[..F(00Lt[[t,,F!&))JT
Xt4455F 1,VAY77%fQi00
+GKKt,L,LMMK;;~t44L,)) Y<122S83|?W;X;XXGKK	488)DDGW[[T::JGGH"7;;tT#:#:;;H-gkk:KT.R.RSSO5gkkBWY]6^6^__
gkk%..
/
/C!%(("<00 	Z 	f	
 	T 	e 	#C(( 	"8,, 	!&)) 	":.. 	e 	o4!4 	s 	!&)) 	j%8$??@@  	W!" 	!'++i">">??#$ "'++i">">??GKK$7788"<00!!%((!'++c4"8"899!'++c4"8"899!'++fd";";<<7  F< 7<<>> 2 2vFD11uK,,IJmmoo X X
U8FC   	Xj//5I#e**5U5UVVWWWOO \ 	\ 	\Cj//A8LSQTUVQW[[8Y8YZZ[[[[$$IqqqqqrrM 0QI///QH 5666w&&G4H,I&WUiMjnoMoMoW[[)=>>???XXm,,N*n-==O b*4*;*=*=*] +U-T 	(:]]=\]]^_`aa
((@@@@@
A
AC
5zzV$$ %(8 % $
f}}<r   c                      t          j        |          }t          |          }t           fdt          D                       }|                    d            ||d<   |S )a,  
    Helper function, allows chaining transformations to the end of transformations list

    The result of this function is an updated options parameter

    :param options:         Original options
    :param transformations: Transformations to chain at the end

    :return: Resulting options
    c              3   4   K   | ]}|v ||         fV  d S r   r   r   r  r   s     r   r   z(chain_transformations.<locals>.<genexpr>  /      KK1a7ll71:llllKKr   r   ra   )copydeepcopyr   r   
__URL_KEYSrN  )r   r_  url_optionss   `  r   chain_transformationsri    sj     mO44O!/22OKKKK
KKKKKK1g&&&$3K !r   c                 z    t          |           } t          j        t          |           ot	          |           dk     S )Nr  )r   rI  rJ  FLOAT_REfloat)r   s    r   r7  r7    s/    JJE8He$$9u)99r   c                 *   t          | t                    st          | t                    r#t          |           dk    r| d         | d         gS t          | t                    r0t          j        t          |           r|                     dd          S d S )Nr   r   z..r  )	r   r   r   r   r   rI  rJ  RANGE_REr5  )ranges    r   r<  r<    s    5$ $:eU#;#; $Uqa%)$$	E<	(	( $RXh-F-F ${{4###4r   c                     | d S t          j        t          t          |                     }|d S d}|                    d          d}|                    d          |z   S )N modifierr   r   )rI  rJ  RANGE_VALUE_REr   group)r   rJ  rs  s      r   r:  r:    s`    }tH^SZZ00E}tH{{:*;;w(**r   c                 0    | dk    r| S t          |           S )Nr   )r:  r   s    r   r;  r;    s    E"""r   c                     | }t          |t                    rK| d         }d| v r?|dz   | d         z   }d| v r-|dz   | d         z   }|                     d          du r|dz   dz   }|S )Ncodecprofiler   levelb_framesF
bframes_no)r   r   r   )r-  	out_params     r   r=  r=  %  s    I)T"" ?'N	!C%	*::I%%OeGn<	99Z((E11 )C, >Ir   c                    | d S t          | t          t          f          rJdt          |           cxk    rdk    sn t	          d          d                    d | D                       S t          t          |                     S )Nr     zInvalid radius paramr   c              3   4   K   | ]}t          |          V  d S r   rE  )r   r%  s     r   r   z!process_radius.<locals>.<genexpr>:  s+      ??A,Q//??????r   )r   r   r   r   r   r   rE  r   )r-  s    r   rG  rG  3  s    }%$'' @CJJ####!####3444xx????????E

+++r   c                 |   d }t          | t                    ri }|                                 D ]\  }t          |t                    st          |t                    rVt          |          dk    r|d         dk    r||<   Tfdt          |          D             }|                    |           |||<   |S )Nr   r   filec                 D    i | ]\  }}d                      |          |S )z{}[{}]r%   )r   r   i_valuer\  s      r   
<dictcomp>z"process_params.<locals>.<dictcomp>H  s-    bbb:1ghooc155wbbbr   )r   r   r   r   r   r   r   update)rY  processed_paramsr   
value_listr\  s       @r   process_paramsr  ?  s    &$ 
. ,,.. 	. 	.JC%&& .*UE*B*B .u::??uQx6'9'9,1$S)bbbbQZ[`QaQabbb
 ''
3333"(- %r   c                 X    t          d |                                 D                       S )zu
    Cleans and normalizes parameters when calculating signature in Upload API.

    :param params:
    :return:
    c                 F    g | ]\  }}||dk    |t          |          fS Nrr  )__safe_valuer   s      r   r   z"cleanup_params.<locals>.<listcomp>V  s7    ddd&1aam\]ac\c\c!\!__%\c\c\cr   )r   r   rY  s    r   cleanup_paramsr  O  s)     ddFLLNNdddeeer   c                     | rt          | t                    s| S t          d |                                 D                       S )zK
    Normalizes Admin API parameters.

    :param params:
    :return:
    c                 F    g | ]\  }}||dk    |t          |          fS r  )__bool_stringr   s      r   r   z$normalize_params.<locals>.<listcomp>c  s9    eee6Aqq}]^bd]d]d!]1%%&]d]d]dr   )r   r   r   r  s    r   normalize_paramsr  Y  sG      FD11 eeV\\^^eeefffr   c                    |                     dt          j                    j                  }|st	          d          |                     dt          j                    j                  }|st	          d          |                     dt          j                    j                  }|                     dt          j                    j                  }t          |           } t          | |||          | d<   || d<   | S )Napi_keyzMust supply api_keyr!   zMust supply api_secretr3   signature_version	signature)
r   r   r   r  r   r!   r3   r  r  api_sign_request)rY  r   r  r!   r3   r  s         r   sign_requestr  f  s    kk)Z%6%8%8%@AAG 0.///\:+<+>+>+IJJJ 31222!++&;Z=N=P=P=dee$79J9L9L9^__F##F*6:?RTeffF;F9Mr   r   c                 H    t          | |          }t          ||z   |          S )a  
    Signs API request parameters using the specified algorithm and signature version.

    :param params_to_sign: Parameters to include in the signature
    :param api_secret: API secret key
    :param algorithm: Signature algorithm (default: SHA1)
    :param signature_version: Signature version (default: 2)
        - Version 1: Original behavior without parameter encoding
        - Version 2+: Includes parameter encoding to prevent parameter smuggling
    :return: Computed signature
    )api_string_to_signr   )params_to_signr!   r   r  to_signs        r   r  r  w  s)     !1BCCGGj0)<<<r   c                    g }|                                  D ]\  }}|rt          |t                    rd                    |          }nFt          |t                    r"t          |                                          }nt          |          }|dz   |z   }|dk    rt          |          }|                    |           d                    t          |                    S )a  
    Generates a string to be signed for API requests.

    :param params_to_sign: Parameters to include in the signature
    :param signature_version: Version of signature algorithm to use:
        - Version 1: Original behavior without parameter encoding
        - Version 2+ (default): Includes parameter encoding to prevent parameter smuggling
    :return: String to be signed
    r   r   r   &)
r   r   r   r   boolr   lower_encode_paramrK  rM  )r  r  rY  r   r   r   param_strings          r   r  r    s     F$$&& ( (1 	(!T"" At$$ AAs7U?L A%%,\::MM,'''88F6NN###r   c                 H    t          |                               dd          S )a?  
    Encodes a parameter for safe inclusion in URL query strings.

    Specifically replaces "&" characters with their percent-encoded equivalent "%26"
    to prevent them from being interpreted as parameter separators in URL query strings.

    :param value: The parameter to encode
    :return: Encoded parameter
    r  z%26)r   r   r   s    r   r  r    s      u::c5)))r   c                     t          j        |           } |                     d          }|t          di |\  | d<   }| S )Nra   r   )re  rf  r   r   )breakpoint_settingsra   r,  s      r   breakpoint_settings_mapperr    sS    -(;<<(,,-=>>N!3Q3c3cTb3c3c0,-qr   c                     | d S t          |           } t          j        t          t	          t
          |                               S r   )r   r   r   r   r9  r  )breakpointss    r   &generate_responsive_breakpoints_stringr    s=    tk**K:d39;GGHHIIIr   c                 |   t          j        dd|           } t          j        d|           rt          |           } | }n|t	          |           } t
          s|                     d          } t          |           } | }|,t          j        d|          rt          d          | dz   |z   } || dz   |z   } |dz   |z   }| |fS )	N([^:])/+\1/	^https?:/utf8z[\./]z$url_suffix should not include . or /r0  r   )	rI  subrJ  smart_escapeunquoter   encodesearchr   )sourcer%   r/   source_to_signs       r   finalize_sourcer    s    VK00F	xf%% ;f%% 	+]]6**Ff%%!y:.. I !GHHHc\J.Fc\F*F+c1F:N>!!r   c                     |pd}|1| dk    r|dk    rd} d }n | dk    r|dk    rd} d }nt          d          |r(| dk    r|dk    s| dk    r|d } d }nt          d          |r| dk    r
|dk    rd} d }| |fS )	Nr   imageimagesrawfilesz9URL Suffix only supported for image/upload and raw/uploadz)Root path only supported for image/uploadiu)r   )r'   r.   r/   r0   r+   upload_types         r   finalize_resource_typer    s    "(KG##x(?(?$MKKe##x(?(?#MKKXYYY JW$$)@)@))k.A MKKHIII =G++x0G0G+%%r   c                 h   | }t          |           }	|ra||t          j        k    r|r|dz   nt          j        }|p|t          j        k    }||r|}|rt	          j        dd|	z   dz   |          }d|z   }
n2|r|rd|	z   dz   nd	}d
|z   |z   }
n|r|dz   nd}|r|dz   |	z   }d
|z   dz   }
|r|
d|z   z  }
|
S )a  cdn_subdomain and secure_cdn_subdomain
    1) Customers in shared distribution (e.g. res.cloudinary.com)
      if cdn_domain is true uses res-[1-5].cloudinary.com for both http and https.
      Setting secure_cdn_subdomain to false disables this for https.
    2) Customers with private cdn
      if cdn_domain is true uses cloudname-res-[1-5].cloudinary.com for http
      if secure_cdn_domain is true uses cloudname-res-[1-5].cloudinary.com for https
      (please contact support if you require this)
    3) Customers with cname
      if cdn_domain is true uses a[1-5].cname for http. For https, uses the same naming scheme
      as 1 for shared distribution and as 2 for private distribution.Nz-res.cloudinary.comr   zres-z.cloudinary.comzhttps://r  r   rr  zhttp://z-resres-r0  )__crcr   OLD_AKAMAI_SHARED_CDN
SHARED_CDNrI  r  )r  r#   r&   r"   r)   r$   r(   r*   shared_domainshardrv   	subdomains               r   unsigned_download_url_prefixr    s8    $OM&MME ;&*=Aa*a*a#:*/D"D"D$.$9   &U)<
@U)U'M'#0  	>"$&)=v~Pa?a)<#> #> 11	 ;)6>C%K#%%B	Y&.+6AJ''E	 	0!C%/IY&):: ##
""Mr   c           
         |                      dd          }|                      dt          j                    j        pd           }|t	          d          |                      dt          j                    j                  }|                      dt          j                    j                  }|                      dt          j                    j                  }|                      dt          j                    j                  }|                      d	t          j                    j	                  }|                      d
t          j                    j
                  }t          ||||||||          S )Nr  rr  r#   z1Must supply cloud_name in tag or in configurationr(   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)   s	            r   build_distribution_domainr    sB   [[2&&F\:+<+>+>+I+QTRRJLMMM[[:#4#6#6#=>>F++mZ->-@-@-LMMKKK!2!4!4!:;;E!++&;&0&7&9&9&MO OKK1B1D1D1RSSM";;'='1'8':':'OQ Q (
K8Lv*, , ,r   c                  p    d }| D ]0}|,||                                 }|                    |           1|S r   )re  r  )	dict_argsresult
dictionarys      r   merger  /  sJ    F * *
!~#**j)))Mr   c                 f   | }t          |           |                    dd          }t          d"i |\  }}|                    dd          }|                    dt          j                    j                  }|d}|                    dd           }|                    dd           }|                    d	t          j                    j                  }	|                    d
t          j                    j                  }
|                    dt          j                    j                  }|                    dd           }|                    dt          j                    j	                  }|                    dd           }|                    dt          j                    j
                  }|                    dt          j                    j                  }|dur&t          t          j                    j        |          }| r|dk    rt          j        d|           r||fS t!          |||||	          \  }}t#          | ||          \  } }|sG|rE|                    d          dk    r,t          j        d|          st          j        d|          sd}|rdt'          |          z   }nd }t          j        dd|          }d }|
r|r |j        dd          rd                    t-          ||g                    }|rt.          }t0          }nt2          }|t4          vr"t7          d                    |                    t4          |         }dt;          t=          j         |tA          ||z                       !                                          d|                   z   dz   }| |d<   tE          |          }d                    t-          ||||||| g                    } |
rC|rAtG          |           j$        }t          j        j%        d"i t          |d |i          }| d!|} | |fS )#Nr.   r   r'   r  force_versionTr1   r%   r+   r,   r!   r/   r0   r   r2   r3   Fz^https?:r0  r   r  z^v[0-9]+1r   r  r  set_url_signaturez$Unsupported signature algorithm '{}'zs--z--r  r`  ?r   )&r   r   r   r   r   r  r+   r,   r!   r0   r2   r3   r  r   rI  rJ  r  r  findr   r  r   	__compactSIGNATURE_SHA256LONG_URL_SIGNATURE_LENGTHSHORT_URL_SIGNATURE_LENGTHr   r   r%   r   base64urlsafe_b64encoder   digestr  r   pathgenerate)r  r   original_sourcer.   ra   r'   r  r1   r%   r+   r,   r!   r/   r0   r   r2   r3   r  r  r  chars_lengthr   rv   r  tokens                            r   cloudinary_urlr  :  sJ   Ow;;vx((D<GGwGGNGKK99MKK1B1D1D1RSSMkk)T**G[[4((Fkk)Z%6%8%8%@AAG{{:z'8':':'CDDH\:+<+>+>+IJJJ\400JKK1B1D1D1RSSM\400J %9:;L;N;N;abb!++&;Z=N=P=P=dee:,..9:FF
 (tx''BH[&,I,I'''0tZA AM4,VVZHHFN } ##C((A--H\>:: .H[.99 .  G$VK@@NI Z Z~z~6I5'Q'Q Z((9nn%EFFGG 	6"24LL5L&:::CJJK^__```&':;I$:!56677>>@@B BBCL.RS S SUYZ	 GH&w//FXXi	i&QS S T TF +J +$%.RRzE4=1Q1QRR"FFEE*7?r   c                 Z   |                     dt          j                    j                  pd}|                     dt          j                    j                  }|st          d          t          |           } t          d                    |t          j	        |g| z                       S )Nupload_prefixzhttps://api.cloudinary.comr#   zMust supply cloud_namer0  )
r   r   r   r  r#   r   r   encode_unicode_urlr   API_VERSION)r  r   cloudinary_prefixr#   s       r   base_api_urlr    s    OZ5F5H5H5VWW 87 \:+<+>+>+IJJJ 31222tDchh(9:;QS]'^ae'effgggr   r   c                 L    |                     dd          }t          || gfi |S )Nr'   r  )r   r  )actionr   r'   s      r   cloudinary_api_urlr    s0    KK99M/;;7;;;r   c                     |                                 }d|d<   t          ||          }t          | fi |dz   t          t	          |          d          z   S )Ndownloadmoder  T)re  r  r  	urlencodebracketize_seq)r  rY  r   cloudinary_paramss       r   cloudinary_api_download_urlr    s\    [[]]FF6N$VW55f000036>RcCdCdfj9k9kkkr   c                 >   t          j                  |rNt          |t                    rd|i}t	          fdt
          D                                           |           d|d}}t          |           t          ||          }t          | fi |d         S )ap  
    Generates a cloudinary url scaled to specified width.

    :param source:          The resource
    :param width:           Width in pixels of the srcset item
    :param transformation:  Custom transformation that overrides transformations provided in options
    :param options:         A dict with additional options

    :return: Resulting URL of the item
    r/  c              3   4   K   | ]}|v ||         fV  d S r   r   rc  s     r   r   z(cloudinary_scaled_url.<locals>.<genexpr>  rd  r   scale)r   r   r   )
re  rf  r   r   r   rg  r  r   ri  r  )r  r   ra   r   scale_transformationrh  s      `  r   cloudinary_scaled_urlr    s     mG$$G 'nl33 	D2NCN KKKK
KKKKK~&&&$+e<<K{###'5IJJK&00K0033r   ([^a-zA-Z0-9_.\-\/:]+)c           	          d }t          t          j        t          |          |t          |                               S )z
    Based on ruby's CGI::unescape. In addition does not escape / :

    :param source: Source string to escape
    :param unsafe: Unsafe characters

    :return: Escaped string
    c                    t          dd                    d t          j        dt	          |                     d                    z  |                     d                    D                                                       z             S )N%c                     g | ]}d |z  S )z%02Xr   r   s     r   r   z.smart_escape.<locals>.pack.<locals>.<listcomp>  s    RRRAVaZRRRr   Br  )r   r   structunpackr   ru  upper)ms    r   packzsmart_escape.<locals>.pack  sp    chhRRsS__/Daggajj!Q!QRRR
 

%''   	r   )r   rI  r  r   )r  unsafer  s      r   r  r    s?      
 RVHV,,dHV4D4DEEFFFr   c                  Z    d                     d t          d          D                       S )Nrr  c              3      K   | ]A}t          j                                        t          j        t          j        z             V  Bd S r   )randomSystemRandomchoicestringascii_lowercasedigits)r   r,  s     r   r   z#random_public_id.<locals>.<genexpr>  sW       ' ' &((//0F0VWW ' ' ' ' ' 'r      )r   rp  r   r   r   random_public_idr    s:    77 ' '!"II' ' ' ' ' 'r   c           	          d                     d | d         | d         fD                       }d                     | d         ddt          | d	                   z   |g          }|d
z   | d         z   S )Nr   c                     g | ]}||S r   r   r   s     r   r   z*signed_preloaded_image.<locals>.<listcomp>  s    QQQqqQQQQr   r4   r%   r0  r'   r   r   r1   r   r  )r   r   )r  filenamer  s      r   signed_preloaded_imager    sw    xxQQVK%8&:J$KQQQRRH88VO,hc&BS>T>T8TV^_``D#:{+++r   c                  \    t          t          t          j                                        S r   )r   inttimer   r   r   nowr    s    s49;;   r   c           
          t          t                      | ||                    d          |                    d          |                    d          d|          }t          di |dz   t	          |          z   S )Nr.   
attachment
expires_at)r`   r4   r%   r.   r  r  r  r  )r  )r  r  r   r  r  )r4   r%   r   r  s       r   private_download_urlr    s    $UUF##kk,//kk,//& &   44G44s:YGX=Y=YYYr   c           	          t          t                      | t          di |d         d|          }t          di |dz   t	          |          z   S )Nr   )r`   tagra   download_tag.zipr  r   )r  )r  r  r   r  r  )r  r   r  s      r   zip_download_urlr     sj    $UU8CC7CCAF& & 	  <<G<<sBYO`EaEaaar   c                 z    t                      }| D ])}| |         }t          |t                    r|dz  }|||<   *|S )Nz[])r   r   r   )rY  
url_params
param_nameparam_values       r   r  r    sS    J - -
Z(k4(( 	$J!,
:r   c            	      4    t          ddt          di | d| S )Ngenerate_archive)r  rY  r   )r  archive_params)r   s    r   download_archive_urlr(    s.    &n.@IbIbZaIbIbnnfmnnnr   c                  n    |                                  }|                    d           t          di |S )Nzip)target_formatr   )re  r  r(  )r   new_optionss     r   download_zip_urlr-    s:    ,,..KU+++..+...r   c                 P    | |d<   |                     dd           t          di |S )av  
    Creates and returns a URL that when invoked creates an archive of a folder.
    :param folder_path: The full path from the root that is used to generate download url.
    :type folder_path:  str
    :param options:     Additional options.
    :type options:      dict, optional
    :return:            Signed URL to download the folder.
    :rtype:             str
    prefixesr'   allr   )
setdefaultr(  )folder_pathr   s     r   download_folderr3    s8     &GJ...**'***r   c                     |                     dt                                | |d}t          ||          }t          di |dz   t	          t          |          d          z   S )a(  
    The returned url allows downloading the backedup asset based on the the asset ID and the version ID.

    Parameters asset_id and version_id are returned with api.resource(<PUBLIC_ID1>, versions=True) API call.

    :param  asset_id:   The asset ID of the asset.
    :type   asset_id:   str
    :param  version_id: The version ID of the asset.
    :type   version_id: str
    :param  options:    Additional options.
    :type   options:    dict, optional
    :return:The signed URL for downloading backup version of the asset.
    :rtype: str
    r`   )r`   asset_id
version_iddownload_backupr  T)r7  )r   r  r  r  r  r  )r5  r6  r   rY  r  s        r   download_backedup_assetr8    so      [[cee44  F
 %VW5555W55;iWhHiHiko>p>pppr   c                  p    t          t          j                    j        |           }t          j        di |S )Nr   )r  r   r   r   r  )r   token_optionss     r   generate_auth_tokenr;  4  s4    *+--8'BBM/////r   c                  ~   |                      d          t                      }n|                      d          }i d|                      d          d|                      d          d|                      d          d|                      d          d|                      d          d|                      d          d|                      d          d	|                      d	          d
|                      d
          d|                      d          o!t          |                      d                    d|                      d          o!t          |                      d                    d|                      d          o!t          |                      d                    d|                      d          d|                      d          o!t          |                      d                    d|                      d          d|                      d          d|                      d          |                      d          o!t          |                      d                    |t          |                      d                    |                      d          |                      d          d}|S )Nr`   allow_missingr]   r  flatten_foldersflatten_transformationskeep_derivedr  rD   rZ   r/  
public_idsfully_qualified_public_idsskip_transformation_namerd   r+  target_asset_foldertarget_public_idtarget_tagsr_  r.   use_original_filename)rF  r`   r_  r.   rG  )r   r  r   build_eager)r   r`   rY  s      r   r'  r'  9  s   {{;'EE		KK,,	_55W%% 	gkk,// 	7;;'899	
 	"7;;/H#I#I 	N33 	F## 	GKK(:;; 	W%% 	GKK
++TGKK
<S<S0T0T 	gkk,//ZKL@Y@Y4Z4Z 	%gkk2N&O&O '7T_KK455U7 U7 	#GKK0J$K$K 	F##HGKK4G4G(H(H  	_55!" 	w{{+@AA#$ 	GKK(:;;%& {{=11]k'++mB\B\6]6]&w{{3D'E'EFFF##!(-D!E!E/  F2 Mr   c                 b    | d S d                     d t          |           D                       S )Nr   c                 ,    g | ]}t          |          S r   )build_single_eager)r   ets     r   r   zbuild_eager.<locals>.<listcomp>^  s!    SSS'++SSSr   r   )r_  s    r   rH  rH  Z  s6    t88SSk/6R6RSSSTTTr   c                     t          | t                    r| S t          di | d         }|sdS |                     d          }||d|z   ndz   S )a9  
    Builds a single eager transformation which consists of transformation and (optionally) format joined by "/"

    :param options: Options containing transformation parameters and (optionally) a "format" key
        format can be a string value (jpg, gif, etc) or can be set to "" (empty string).
        The latter leads to transformation ending with "/", which means "No extension, use original format"
        If format is not provided or set to None, only transformation is used (without the trailing "/")

    :return: Resulting eager transformation string
    r   rr  r%   Nr0  r   )r   r   r   r   )r   	trans_strfile_formats      r   rK  rK  a  sk     '<(( .9999!<I r++h''K[-Dk))"MMr   c                     | d S t          | t                    rn6t          | t                    rd |                                 D             } n| S d                    |           S )Nc                 $    g | ]\  }}|d z   |z   S )z: r   r   s      r   r   z(build_custom_headers.<locals>.<listcomp>  s$    <<<DAq1t8a<<<<r   
)r   r   r   r   r   )rb   s    r   build_custom_headersrS  y  sg    t	GT	"	" 	GT	"	" <<GMMOO<<<99Wr   c                       fdt           D             }|                    dt          j                    j                  |d<   t                      t                               d                    t          di  d         t                               d                    t                               d                                         d          o!t          t           d                                                  d          o!t          t           d                             t                               d	                    t                               d
                    t                               d                    t                               d                                         d          o!t                               d                    t!                               d                                         d          o.t          t#                               d                              dfdt$          D             |                               |S )Nc                 D    i | ]}|v |                     |          S r   )r   )r   r#  r   s     r   r  z'build_upload_params.<locals>.<dictcomp>  s3    tttj^hls^s^sj'++j11^s^s^sr   rY   rl   r   rb   rc   rd   re   rf   rg   rh   ri   r\   rj   rk   )r`   rl   ra   rb   rc   rd   re   rf   rg   rh   ri   r\   rj   rk   c                 "    i | ]}||         S r   r   )r   r#  serialized_paramss     r   r  z'build_upload_params.<locals>.<dictcomp>  s!    pppz%6z%Bpppr   r   )__SIMPLE_UPLOAD_PARAMSr   r   r   rY   r  r   r   r   rS  rH  r   r   r   r   r   r  r   __SERIALIZED_UPLOAD_PARAMSr  )r   rY  rW  s   ` @r   build_upload_paramsrZ    s   ttttDZtttF$jj*:K:M:M:[\\F? UU"7;;z#:#:;;8CC7CCAF'I(>(>??W[[1122F##QK4P4P(Q(Q";;'899rk+V]^oVpJqJq>r>r/<N0O0OPP1'++>R2S2STTw{{95566!'++i"8"899N33XGKK<W<W8X8X"HUmInIn"o"o!++&677 @K,< = =>>=@ =@ & qpppUoppp
MM#$$$Mr   c                    | sd S t           r3t          | t                     r|p| j        }|                                 }nt          | t                    rUt          |           rd }| }n|p| }t          | d          5 }|                                }d d d            n# 1 swxY w Y   nt          | d          r^t          | j                  rJ|                                 }|p2t          | d          r!t          | j        t                    r| j        nd}n!t          | t                    r| \  }}n|pd}| }|r||fn|S )Nrbreadnamestreamr  )PathLibPathTyper   r^  
read_bytesr   is_remote_urlopenr]  hasattrcallabler   r   )r  r  r^  dataopeneds        r   handle_file_parameterrh    s    t :dO<< $49  	D,	'	'  	%DDD #tDdD!! %V{{}}% % % % % % % % % % % % % % %	v		 	8DI#6#6 	yy{{lv)>)>k:diY\C]C]kDIIck	D%	 	  
dd !6)D$<<T)s   <BB!$B!c                     |                      d          }|                      d          }t          |          t          |          k    rt          d          |                      d          t                      |                      d          |                      d          ||t	          dd|                      d          i| d	         d
}|S )zh
    Build params for multi, download_multi, generate_sprite, and download_generated_sprite methods
    r  urlsz;Either 'tag' or 'urls' parameter has to be set but not bothr  r]   rD   rt   r%   r   )r  r`   r]   rD   r  rj  ra   r   )r   r  r   r  r   )r   r  rj  rY  s       r   build_multi_and_sprite_paramsrk    s     ++e

C;;vDCyyDJJVWWWF##UUW%%#KK(:;;8gggkkRZF[F[g_fgghij F Mr   c                 F   t          |                     dd                    }|r|                                s|S |                     d          }|                     d          }g }t          D ]7\  }}|                     |          }||k    r||                    |           8|                     d          }	|	%|                    dt          |	          z              |                     d          }
|
%|                    dt          |
          z              |                     d	          }|%|                    d
t          |          z              |                     d          }|%|                    dt          |          z              ||t          |          dk    rd S |t          d|z             |t          d|z             |                    d|           |                    d|           d                    d |D                       S )N
text_stylerr  font_family	font_sizeletter_spacingletter_spacing_line_spacingline_spacing_font_antialiasing
antialias_font_hintinghinting_r   z$Must supply font_family for text in z"Must supply font_size for text in r,  c                 ,    g | ]}t          |          S r   r   )r   r   s     r   r   z*__process_text_options.<locals>.<listcomp>  s    ...SVV...r   )	r   r   isspace__LAYER_KEYWORD_PARAMSrK  r   r   rN  r   )layerlayer_parameterrm  rn  ro  keywordsattrdefault_value
attr_valuerp  rr  rt  rv  s                r   __process_text_optionsr    s%   UYY|R0011J *,,.. ))M**K		+&&IH5 ( (mYYt__
&&:+AOOJ'''YY/00N!)C,?,??@@@99^,,L#l*;*;;<<<		"566$s+<'='==>>>99^,,L
S%6%66777[0S]]a5G5Gt?/QRRR=OPPPOOAy!!!OOA{###88..X...///r   c           	      t   t          | t                    rsd }|                     d          r| t          d          d          }n8|                     ddd          dk    r|                     dd          \  }}}n| S |dd	} |r|| d
<   t          | t                    s| S |                     d
          }|                     d          }|                     d          }|                     d          }|                     d          }|                     d          }	t                      }
||d}|	r|d}|
||dz   |z   }||dk    r|dk    rt          d|z             ||dk    r|

                    |           ||dk    r|

                    |           |dk    s|dk    r$||t          d|z             t          | |          }||

                    |           |+|                    dd          }|

                    |           |t          }t          d t          j        ||                    }g }|D ]]}t          j        ||          r|
                    |           -|
                    t#          t#          |d                               ^d                    |          }|

                    |           nV|dk    r%t'          |	          }|

                    |           n+|                    dd          }|

                    |           d                    |
          S )Nzfetch:z:fetch:r      rn  r   r   r   )r`  r.   r'   textr.   r4   r%   r`  r   z'Must supply public_id for for non-text r  r   	subtitlesz(Must supply either text or public_id in r0  c                 
    | d uS r   r   )r   s    r   <lambda>zprocess_layer.<locals>.<lambda>>  s
    Qd] r   z([,/])rr  )r   r   r6  r   r  r5  r   r   r   r   rK  r  r   VAR_NAME_REfilterrI  rJ  r  r   base64url_encode)r{  r|  r'   r`  r,  r  r.   r4   r%   	fetch_url
componentstext_optionsvar_patternpartsencoded_textpartb64s                    r   r@  r@    s   %&& 3H%% 	H'CCZZ	1b))R//$)KKQ$7$7!M1cc L W-- 	3%2E/"eT"" IIo..M99VD99VD		+&&IYYx  F		%  IJM1 T\!3Of,	]f44B_TUUU ]g%=%=-(((DH,,$-;">">G/YZZZ-e_EE#l+++ !))#s33Ii(((%K22BH[$4O4OPPEL U U8K.. U ''---- ''\$	5R5R(S(STTTT77<((Dd###	y))#%%c3//	)$$$88Jr   eqneltgtltegteandormuldivaddr  pow)r   z!=<>z<=z>=z&&z||*r0  +r  ^r  r  aspectRatiocurrent_pagecpcurrentPage
face_countfc	faceCountr   r  initial_aspect_ratioiarinitialAspectRatiotrimmed_aspect_ratiotartrimmedAspectRatioinitial_heightihinitialHeightinitial_widthiwinitialWidth
page_countpc	pageCountpxpyrd   r'  r  iduilsctx)page_xpageXpage_ypageYrd   r   r  initial_durationinitialDurationillustration_scoreillustrationScoreri   zG((\|\||>=|<=|&&|!=|>|=|<|/|-|\+|\*|\^)(?=[ _])|(\$_*[^_ ]+)|(?<![\$:])(r   z))c                     |                      d          }t                              |t                              ||                    S Nr   )ru  IF_OPERATORSr   PREDEFINED_VARS)rJ  r^  s     r   translate_ifr    sC    ;;q>>DD+//046 67 7 7r   c                     t          | t                    s| S |                     d          }|                     d          }|dk    rt          |          }d                    ||g          S )Nfunction_typer  remoter   )r   r   r   r  r   )r
  r  r  s      r   rB  rB    so    ot,, #''88M  **F  !&))88]F+,,,r   c                 R    t          |           }|rd                    |          nd S )Nzpre:{0})rB  r%   )r
  r   s     r   rC  rC    s-    #O44E&+59E"""5r   c                 |    t          | t          t          f          s| S d                    d | D                       S )z
    Serializes fps transformation parameter

    :param fps: A single number, a list of mixed type, a string, including open-ended and closed range values
                Examples: '24-29.97', 24, 24.973, '-24', [24, 29.97]

    :return: string
    r  c              3   4   K   | ]}t          |          V  d S r   r  )r   r   s     r   r   zprocess_fps.<locals>.<genexpr>  s+      99(++999999r   )r   r   r   r   )r  s    r   rD  rD    s@     cD%=)) 
8899S999999r   c                     | dS t          | t                    r| S t          | t                    st          d          | dk    rt          d          t	          t          |                     S )z
    Serializes keyframe_interval parameter
    :param ki: Keyframe interval. Should be either a string or a positive real number.
    :return: string
    Nz0Keyframe interval should be a number or a stringr   z-Keyframe interval should be greater than zero)r   r   r   r   r   rl  )r  s    r   rF  rF    sq     
zt"l## 	b&!! MKLLL	QwwHIIIuRyy>>r   c                 ,    | | S t          |           }|S r   r  )conditionalr  s     r   rA  rA    s     !+..FMr   c                     t          j        dt          |                     r| S | rGt          |           }t          j        t          t
          |          }t          j        dd|          }|S | S )Nz^!.+!$z[ _]+r,  )rI  rJ  r   r  	replaceREr  )
expressionr  s     r   rE  rE    sf    	x	3z??++ 	 Z	<88f--r   c                 N    ||dk    rd S |du r| S d                     | |          S )Nrr  Tz	{0}="{1}"r  )r\  r   s     r   __join_pairr    s8    }t	$
  e,,,r   c                     d                     t          fd|                                 D                                 S )N c                 B    g | ]\  }}|v t          ||          S r   )r  )r   r\  r   onlys      r   r   zhtml_attrs.<locals>.<listcomp>  s9    sss
UW[WcgjnrgrgrKU33grgrgrr   )r   rM  r   )attrsr  s    `r   
html_attrsr    s:    88Fssssekkmmsssttuuur   c                 <    t          | t                    r| rdndS | S )Nr  0r   r  r   s    r   r  r    s(    !T ! ssS Hr   c                 <    t          | t                    r| rdndS | S )Ntruefalser  r  s    r   r  r    s(    !T ('vv'Hr   c                 p    t          t          j        t          |                     dz  dz  dz             S )Nl       r  )r   zlibcrc32r   )r  s    r   r  r    s1    
<//00:=BQFGGGr   c                 $    t          d |           S )Nc                     | S r   r   r   s    r   r  z__compact.<locals>.<lambda>  s    A r   )r  r   s    r   r  r    s    ++u%%%r   c                     	 t          |           } n# t          $ r Y nw xY wt          |           } t          j        |                     d                    }|                    d          S )z
    Returns the Base64-decoded version of url.
    The method tries to unquote the url because quoting it

    :param str url:
        the url to encode. the value is URIdecoded and then
        re-encoded before converting to base64 representation

    utf-8ascii)r  	Exceptionr  r  	b64encoder  decode)r`  r  s     r   base64_encode_urlr    so    cll   
s

C

3::g..
/
/C::gs    
c                 ^    t          t          j        t          |                               S )z
    Url safe version of urlsafe_b64encode with stripped `=` sign at the end.

    :param data: input data

    :return: Base64 URL safe encoded string
    )r   r  r  r   )rf  s    r   r  r    s#     V-htnn==>>>r   c                 n    t           j        r(t          j        |                     d          d          } | S )z
    Quote and encode possible unicode url string (applicable for python2)

    :param url_str: Url string to encode

    :return: Encoded string
    r  z:/?#[]@!$&'()*+,;=)sixPY2urllibquoter  )url_strs    r   r  r    s2     w N,w~~g668LMMNr   c                     t          | t          t          f          r|                                 S t	          dt          |           z            )zAJSON serializer for objects not serializable by default json codez*Object of type %s is not JSON serializable)r   r   r   	isoformat	TypeErrorr.   objs    r   r   r     sA    #$'(( }}
@499L
M
MMr   c                 `    t          | t                    ot          j        t          |           S )z3Basic URL scheme check to define if it's remote URL)r   r   rI  rJ  REMOTE_URL_RE)r  s    r   rb  rb  $  s#    dL))Kbh}d.K.KKr   c                     |                                  }|                     dt          j                   |                                  }|                     |t          j                   |S )z
    Helper function for getting file-like object size(suitable for both files and streams)

    :param file_io: io.IOBase

    :return: size
    r   )tellseekosSEEK_ENDSEEK_SET)file_ioinitial_positionr   s      r   file_io_sizer  )  sQ     ||~~LLBK   <<>>DLL!2;///Kr   c                       fd}|S )z
    Used as a class method decorator to check whether class is enabled(self.enabled is True)

    :param f: function to call

    :return: None if not enabled, otherwise calls function f
    c                  2    | d         j         sd S  | i |S r  )enabled)argskwargsr   s     r   wrapperz'check_property_enabled.<locals>.wrapperA  s+    Aw 	4q$!&!!!r   r   )r   r  s   ` r   check_property_enabledr  9  s#    " " " " "
 Nr   c                     t          j                    j        st          d          | |d}|t	          |t          j                    j        |pt          j                    j        d          k    S )a  
    Verifies the authenticity of an API response signature

    :param public_id: The public id of the asset as returned in the API response
    :param version:   The version of the asset as returned in the API response
    :param signature: Actual signature. Can be retrieved from the X-Cld-Signature header
    :param algorithm: Name of hashing algorithm to use for calculation of HMACs.
                      By default, uses `cloudinary.config().signature_algorithm`

    :return: Boolean result of the validation
    Api secret key is empty)r4   r1   r  )r  )r   r   r!   r  r  r3   )r4   r1   r  r   parameters_to_signs        r   verify_api_response_signaturer  I  s     ) 31222'0%,. . (&<Z&((<	    r      c           	      ~   t          j                    j        st          d          |t	          j                    |z
  k     rdS t          | t                    st          d          |t          d	                    | |t          j                    j                  |pt          j                    j
                  k    S )aA  
    Verifies the authenticity of a notification signature

    :param body: Json of the request's body
    :param timestamp: Unix timestamp. Can be retrieved from the X-Cld-Timestamp header
    :param signature: Actual signature. Can be retrieved from the X-Cld-Signature header
    :param valid_for: The desired time in seconds for considering the request valid
    :param algorithm: Name of hashing algorithm to use for calculation of HMACs.
                      By default, uses `cloudinary.config().signature_algorithm`

    :return: Boolean result of the validation
    r  FzBody should be type of stringz{}{}{})r   r   r!   r  r  r   r   r   r   r%   r3   )bodyr`   r  	valid_forr   s        r   verify_notification_signaturer  d  s     ) 3122249;;***udC   :8999(i):)<)<)GHH<Z&((<> > > >r   c                     | j         r+| j        rt          | j         fi |S t          | j         fi |S | j        rt	          di |S t          di |S )a  
    Used to create http connector, depends on api_proxy and disable_tcp_keep_alive configuration parameters.

    :param conf: configuration object
    :param options: additional options

    :return: ProxyManager if api_proxy is set, otherwise PoolManager object
    r   )	api_proxydisable_tcp_keep_aliver	   r   r
   r   )confr   s     r   get_http_connectorr     s}     ~ C& 	;::':::'BB'BBB" &%%W%%%"--W---r   c                 Z    t          | t                    rd                    |           S | S )Nr   )r   r   r   r  s    r   r   r     s)    #t xx}}Jr   c                 L    	  ||           S # t           t          f$ r |cY S w xY w)a  
    Attempts to cast a value to another using a given casting function
    Will return a default value if casting fails (configurable, defaults to None)

    :param val: The value to cast
    :param casting_fn: The casting function that will receive the value to cast
    :param default: The return value if casting fails

    :return: Result of casting the value or the value of the default parameter
    )r   r  )r   
casting_fnr   s      r   	safe_castr$    s>    z#	"   s   
 ##c                     | S )z:
    Identity function. Returns the passed in values.
    r   r  s    r   __idr&    s	     Hr   c                     |t           }t                      }| D ]}|| ||          <   t          |                                          S )z
    Removes duplicates from collection using key function

    :param collection: The collection to remove duplicates from
    :param key: The function to generate key from each element. If not passed, identity function is used
    )r&  r   r   values)
collectionr\  	to_returnelements       r   uniquer,    sU     {I * *")	##g,,	  ""###r   r  c                 2    d                     |||           S )a^  
    Returns the fully qualified public id of form resource_type/type/public_id.

    :param public_id: The public ID of the asset.
    :type public_id: str
    :param resource_type: The type of the asset. Defaults to "image".
    :type resource_type: str
    :param type: The upload type. Defaults to "upload".
    :type type: str

    :return:
    z"{resource_type}/{type}/{public_id})r'   r.   r4   r  )r4   r'   r.   s      r   fq_public_idr.    s!     066]Y]ir6sssr   )F)r   )r   )r  r   )r  N)r  r   )r  re  hashlibr   r  r	  rI  r  r  r  r  r  collectionsr   r   r   	fractionsr   numbersr   six.moves.urllib.parser  r   urllib3r	   r
   r   r   ,cloudinary.api_client.tcp_keep_alive_managerr   r   cloudinary.compatr   r   r   r   r   r   pathlibr   r`  ImportErrorr  movesparser  r  r  rP  rt  ro  rk  r  rz  rg  rX  rY  upload_paramsrH  r  r  SIGNATURE_SHA1r  r   r   r   r   r   r   r   r   r   r   r   r   r   r   ri  r7  r<  r:  r;  r=  rG  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-  r3  r8  r;  r'  rH  rK  rS  rZ  rh  rk  r  r@  r  r  r   keysr  r  rB  rC  rD  rF  rA  rE  r  r  r  r  r  r  r  r  r  r   rb  r  r  r  r  r   r   r$  r&  r,  r.  r   r   r   <module>r>     s	       				  				      # # # # # # # # # # # # # #                       - - - - - - - -     ! ! ! ! ! ! j j j j j j j j \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \///////   OOO %I",	
)

 
( .!
4:G*L*L '@6w. . .   
./ / / b   " ')CC !! !       GLgn  #1 , , , ,   ' ' 'T0 0 0  > > >"d d d d d d d ) ) )2 2 2$Y Y Yx  2: : :
  + + +# # #  	, 	, 	,   f f f
g 
g 
g  " <J]^ = = = = $ $ $ $8
* 
* 
*  J J J" " ",& & &6) ) )X, , ,&  I I IX
h 
h 
h< < < <l l l4 4 4@G G G G"' ' '
, , ,! ! !
Z 
Z 
Zb b b  o o o/ / /+ + + q q q20 0 0
  BU U UN N N0	 	 	  <* * *>  ()0 )0 )0XM  M  M b 

		



					  D4 D 4	
 $  c E % E % d T T D  $!" #$ ;  @ ]HH_))++,,-/34	7 7 7	- 	- 	-6 6 6
: : :  "    - - -v v v v    H H H& & &  (? ? ?  N N NL L L
         6> > > >6. . .*     "  $ $ $ $$t t t t t ts    B BB