a
    ΝGd                     @   s  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
 d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZ d
dlmZ d
dlmZ d
dlmZmZmZm Z m!Z! ddl"m#Z#m$Z$m%Z%m&Z& e'djZ(e)e*Z+G dd de%Z,G dd de,Z-dd Z.dd Z/d\ddZ0dd Z1dd Z2G dd  d e#Z3d!d" Z4ej5ej6ej7fZ8ej9e8d#ej:fej;e8d$ej<fej=ej>d%ej:fej?ej>d&ej<fej=ej@ejAfd'ej:fej?ej@ejAfd(ej<fgZBd)d* ZCd+d, ZDejEejFdffejGejHejIffejJejKdffejLejHejMffejNejHejOffej7eDejPffejQejHdffej6ejRdffej5ejFdffejSejHejTffejUejHejVffejWejHejXffejYejHdffejZejHdffej[ejHej\ffej>ejHdffgZ]ejTejVd-Z^ej_ejHej`ffejWejHejXffejaejHejbffejSejHd.d/ ffej[ejHej\ffejcejHdffej>ejHdffejJejKdffej5ejFdffej6ejRdffej7eDejPffejQejHdffejNejHejOffejLejHejMffejdejHdffgZeefe(efd0k re]gejhejKdff eegejhejKdff eee] Zid1d2 Zjd3d4 Zkd5d6 Zld7d8 ZmenejKdffeoejFdffepejHdffeqejRdfferejsdffeekejPffejtejHej\ffe j ejHejMffe juejHejOffg	Zvewed9rejxZynd:d; Zyd<d= Zzevgej{ej|fezf d>d? Z}d@dA Z~G dBdC dCe#ZG dDdE dEe#ZG dFdG dGe#ZG dHdI dIe#ZG dJdK dKe#ZG dLdM dMe#ZG dNdO dOe#ZG dPdQ dQe#Zz d dRlmZ d dSlmZmZ W n$ ey   d ZZdTdU ZY n0 G dVdW dWe#Zzd dXlmZ W n$ ey   G dYdZ dZe#ZY n0 G d[dZ dZe#ZdS )]    N)version)OrderedDict)Decimal)	signature)
validators)models)serializers)api_settings   )openapi)SwaggerGenerationError)decimal_as_floatfield_value_to_representationfilter_noneget_serializer_classget_serializer_ref_name   )FieldInspector
NotHandledSerializerInspectorcall_view_methodZdjangorestframeworkc                   @   sT   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd ZdS )InlineSerializerInspectorzVProvides serializer conversions using :meth:`.FieldInspector.field_to_swagger_object`.Fc                 C   s   |  |tj| jS N)probe_field_inspectorsr   Schemause_definitionsself
serializer r   U/var/www/html/django/DPS/env/lib/python3.9/site-packages/drf_yasg/inspectors/field.py
get_schema%   s    z$InlineSerializerInspector.get_schemac                 C   s   |S )a  Add/replace parameters from the given list of automatically generated request parameters. This method
        is called only when the serializer is converted into a list of parameters for use in a form data request.

        :param serializer: serializer instance
        :param list[openapi.Parameter] parameters: generated parameters
        :return: modified parameters
        :rtype: list[openapi.Parameter]
        r   )r   r   
parametersr   r   r    add_manual_parameters(   s    	z/InlineSerializerInspector.add_manual_parametersc                    s0   t |di } fdd| D }||S )Nfieldsc              	      s:   g | ]2\}}t |d dsj|tjj| dqS )	read_onlyF)namein_)getattrr   r   	Parameterr   get_parameter_name).0keyvaluer'   r   r   r    
<listcomp>5   s   

zDInlineSerializerInspector.get_request_parameters.<locals>.<listcomp>)r(   itemsr#   )r   r   r'   r$   r"   r   r.   r    get_request_parameters3   s
    
z0InlineSerializerInspector.get_request_parametersc                 C   s   |S r   r   r   
field_namer   r   r    get_property_nameA   s    z+InlineSerializerInspector.get_property_namec                 C   s   |S r   r   r2   r   r   r    r*   D   s    z,InlineSerializerInspector.get_parameter_namec                 C   s   t |S r   )r   r   r   r   r    r   G   s    z1InlineSerializerInspector.get_serializer_ref_namec                 C   s   t |dd }t|dS )NMetaref_name)r(   hasattr)r   r   serializer_metar   r   r    _has_ref_nameJ   s    z'InlineSerializerInspector._has_ref_namec                    s4  j ||fi |\ t|tjtjfr^|j }t|pFi }f tj	|d|S t|tj
r0|tjkrtd|j |}|f fdd	}|rs| S jtj}	|	||}
|
  t|
dd }t|}|r$||kr$|o|}|s$td||f t|	|S tS )Ntyper0   z(cannot instantiate nested serializer as c                    s   t  }g }| j D ]f\}}|}dt|jp4d i}t|}j| fi |}|||< |jrt	|dds|
| qdtj||pd d}t|dt|  |S )Nr%   F)Zuse_field_titler;   
propertiesrequired_NP_serializer)r   r$   r0   r4   boolr%   r   r   r=   r(   appendr   TYPE_OBJECTsetattrr   )r   r<   r=   Zproperty_namechildZprop_kwargschild_schemaresultChildSwaggerTypeSwaggerTyper   use_referencesr   r    make_schema_definition_   s.    
	zQInlineSerializerInspector.field_to_swagger_object.<locals>.make_schema_definitionr>   zSchema for %s would override distinct serializer %s because they implicitly share the same ref_name; explicitly set the ref_name attribute on both serializers' Meta classes)_get_partial_types
isinstancer   ListSerializer	ListFieldr   rC   find_limitsr   
TYPE_ARRAY
Serializerr   r   __name__r   
components
with_scopeSCHEMA_DEFINITIONS
setdefaultZ_remove_read_onlyr(   r   r9   	SchemaRefr   )r   fieldswagger_object_typerI   kwargsrD   limitsr6   rJ   definitionsZactual_schemaZactual_serializerZthis_serializerZexplicit_refsr   rF   r    field_to_swagger_objectN   s@    

z1InlineSerializerInspector.field_to_swagger_objectN)rR   
__module____qualname____doc__r   r!   r#   r1   r4   r*   r   r9   r]   r   r   r   r    r      s   r   c                   @   s   e Zd ZdZdS )ReferencingSerializerInspectorTN)rR   r^   r_   r   r   r   r   r    ra      s   ra   c                 C   s   t | dd}t||}||fS )a  Try to get information about a model and model field from a queryset.

    :param queryset: the queryset
    :param field_name: target field name
    :returns: the model and target field from the queryset as a 2-tuple; both elements can be ``None``
    :rtype: tuple
    modelN)r(   get_model_field)querysetr3   rb   model_fieldr   r   r    get_queryset_field   s    
rf   c                 C   s>   z$|dkr| j jW S | j |W S W n ty8   Y dS 0 dS )zTry to get the given field from a django db model.

    :param model: the model
    :param field_name: target field name
    :return: model field or ``None``
    pkN)_metarg   	get_field	Exception)rb   r3   r   r   r    rc      s    
rc   c                 C   sT   z:t | dd}|dur6|dur6t|t | ddks6J |W S  tyN   Y dS 0 dS )zTry to get the queryset of the given view

    :param view: the view instance or class
    :param serializer: if given, will check that the view's get_serializer_class return matches this serializer
    :return: queryset or ``None``
    Zget_querysetrd   Nr   Zserializer_class)r   r;   rj   )viewr   rd   r   r   r    get_queryset_from_view   s    rl   c                 C   s$   | dur t | tjr| S | j} q dS )zqGet the nearest parent ``Serializer`` instance for the given field.

    :return: ``Serializer`` or ``None``
    N)rL   r   rQ   parentrX   r   r   r    get_parent_serializer   s
    ro   c                 C   sT   z:t | |}z|jjW W S  ty6   |jjj Y W S 0 W n tyN   Y dS 0 dS )zTry to find the other side of a model relationship given the name of a related field.

    :param model: one side of the relationship
    :param str source: related field name
    :return: related model or ``None``
    N)r(   relZrelated_modelrj   rX   Zremote_fieldrb   )rb   sourceZ
descriptorr   r   r    get_related_model   s    
rr   c                   @   s   e Zd ZdZdd ZdS )RelatedFieldInspectorz-Provides conversions for ``RelatedField``\ s.c                 K   s  | j |||fi |\}}t|tjrF| |j||}|tj|ddS t|tjsVt	S t
|dd }t|tjtjfrnt
|ddr| j|j||fi |}	||	dS t
|dd}
|d urt||
\}}nt|}t
|d	d }t
|d
d }|st| j|}t
|d
d }t
|ddp|j}|s8t|jtjr8|jj}t||}t||
}t|p^dtji}|f i |S t|tjr|tjtjdS |tjdS )NT)r;   r0   Zunique_itemsrd   pk_field )Zexisting_objectZ
slug_fieldrg   r5   rb   rq   r;   )r;   formatr;   )rK   rL   r   ZManyRelatedFieldr   Zchild_relationr   rP   ZRelatedFieldr   r(   ZPrimaryKeyRelatedFieldZSlugRelatedFieldrt   rf   ro   rl   rk   r3   rm   rr   rc   get_basic_type_infoTYPE_STRINGZHyperlinkedRelatedField
FORMAT_URI)r   rX   rY   rI   rZ   rH   rG   rD   Zfield_querysetrE   Ztarget_fieldrb   re   Zparent_serializerr8   Z
this_modelZview_querysetrq   attrsr   r   r    r]      sD    


z-RelatedFieldInspector.field_to_swagger_objectNrR   r^   r_   r`   r]   r   r   r   r    rs      s   rs   c                 C   s   d}| j D ]:}t|t jr
t|t js
|t jkr2q
|dur@ dS |}q
ztt|dddd}W n* ty   tjdt	|  dd Y dS 0 |r|
ds|
dr|dd	 d
 }|S )zGiven a ``Field``, look for a ``RegexValidator`` and try to extract its pattern and return it as a string.

    :param serializers.Field regex_field: the field instance
    :return: the extracted pattern, or ``None``
    :rtype: str
    Nregexpatternz%failed to compile regex validator of T)exc_infoz\Zz\z$)r   rL   ZRegexValidatorZURLValidatorZvalidate_ipv4_addressr(   rj   loggerwarningstrendswith)Zregex_fieldZregex_validator	validatorr~   r   r   r    
find_regex   s"    
r   minimummaximum
min_length
max_lengthZ	min_itemsZ	max_itemsc                    s   i } fddt D }t tjr.t s.|S  jD ]h}t|dsDq4|j}t|trdt rdt	|}|D ]2\}}}t||rh||vs|||| rh|||< qhq4t drƈ j
s|dddk rd|d< tt| S )zGiven a ``Field``, look for min/max value/length validators and return appropriate limit validation attributes.

    :param serializers.Field field: the field instance
    :return: the extracted limits
    :rtype: OrderedDict
    c                    s(   g | ] \}}}}t  |r|||fqS r   )rL   )r+   r   field_classattrimprovesrn   r   r    r/   [  s   

zfind_limits.<locals>.<listcomp>limit_valueallow_blankr   r   r   )limit_validatorsrL   r   DecimalFieldr   r   r7   r   r   floatr   getr   sortedr0   )rX   r[   Zapplicable_limitsr   r   Zvalidator_classr   r   r   rn   r    rO   S  s(    



rO   c                 C   s   t | rtjS tjS r   )r   r   TYPE_NUMBERry   rn   r   r   r    decimal_field_typex  s    r   )Zipv4Zipv6c                 C   s   t | jd S r   )	ip_formatr   protocolrn   r   r   r    <lambda>      r   z3.14.0c                 C   s   | du rdS t D ]>\}}t| |r|\}}t|r:|| }t|rJ|| } qTqdS d}|tjkrjt| }t| }td|fd|fd|fg}|| t	|}|S )a?  Given a serializer or model ``Field``, return its basic type information - ``type``, ``format``, ``pattern``,
    and any applicable min/max limit values.

    :param field: the field instance
    :return: the extracted attributes as a dictionary, or ``None`` if the field type is not known
    :rtype: OrderedDict
    Nr;   rv   r~   )
basic_type_inforL   callabler   ry   r   rO   r   updater   )rX   r   Ztype_formatswagger_typerv   r~   r[   rE   r   r   r    rx     s.    


rx   c                   C   s   t jrtjS tjS r   )rest_framework_settingsZCOERCE_DECIMAL_TO_STRINGr   ry   r   r   r   r   r    decimal_return_type  s    r   c                 C   s   t | dd p| S )N
__origin__r(   )
hint_classr   r   r    get_origin_type  s    r   c                 C   s   t | }t|ot||S r   )r   inspectisclass
issubclass)r   check_classorigin_typer   r   r    hint_class_issubclass  s    r   get_argsc                 C   s   t | ddS )N__args__r   r   )tpr   r   r    typing_get_args  s    r   c                 C   sL   t | }|r|d nt}t|p(dtji}tdtjfdtjf i |fgS )Nr   r;   r0   )r   r   get_basic_type_info_from_hintr   ry   r   rP   Items)r   argsZchild_classZchild_type_infor   r   r    inspect_collection_hint_class  s    r   c                 C   s   t | }|tju r| jS d S r   )r   typingUnionr   )r   r   r   r   r    _get_union_types  s    
r   c                 C   s   t | }|rFt|dkrBtd|d rBt|d }|r>d|d< |S dS tD ]T\}}t| |rJt|rp||   S |\}}t|r| }td|fd|fg  S qJdS )	a[  Given a class (eg from a SerializerMethodField's return type hint,
    return its basic type information - ``type``, ``format``, ``pattern``,
    and any applicable min/max limit values.

    :param hint_class: the class
    :return: the extracted attributes as a dictionary, or ``None`` if the field type is not known
    :rtype: OrderedDict
    r
   Nr   r   Tz
x-nullabler;   rv   )r   lenrL   r   hinting_type_infor   r   r   )r   Zunion_typesrE   r   infor   rv   r   r   r    r     s(    	
r   c                   @   s   e Zd ZdZdd ZdS )SerializerMethodFieldInspectorzProvides conversion for SerializerMethodField, optionally using information from the swagger_serializer_method
    decorator.
    c                 K   sJ  t |tjstS t|j|jd }|d u r,tS t|dd }|r|j}|d u rVt|dd }|d u rd|j}|j	}|d u r~t|dd }t
|r||dd}	|jf i |	}n||_||_	d|_| j|||ddS t|j}
t
|
st|
dr|
jd }
t
|
rFt|
t
jsFt|
}|d urF| j|||fi |\}}|f i |S tS )	N_swagger_serializer	help_textlabelT)r   r   r%   )r%   r   r   )rL   r   ZSerializerMethodFieldr   r(   rm   method_namer   r`   r   r   r   r   r%   r   inspect_signaturereturn_annotationr7   r   r   _emptyr   rK   )r   rX   rY   rI   rZ   methodr   descriptionr   Zserializer_kwargsr   	type_inforH   rG   r   r   r    r]   8  sL    




z6SerializerMethodFieldInspector.field_to_swagger_objectNr|   r   r   r   r    r   3  s   r   c                   @   s   e Zd ZdZdd ZdS )SimpleFieldInspectorzProvides conversions for fields which can be described using just ``type``, ``format``, ``pattern``
    and min/max validators.
    c                 K   s<   t |}|d u rtS | j|||fi |\}}|f i |S r   )rx   r   rK   )r   rX   rY   rI   rZ   r   rH   rG   r   r   r    r]   v  s
    z,SimpleFieldInspector.field_to_swagger_objectNr|   r   r   r   r    r   q  s   r   c                   @   s   e Zd ZdZdd ZdS )ChoiceFieldInspectorzEProvides conversions for ``ChoiceField`` and ``MultipleChoiceField``.c                 K   s|  | j |||fi |\}}t|tjrxtj}g }|j D ]6}	t|tjr^t	||	gd }	n
t	||	}	|
|	 q<t|}
t|
tjrtt|
dd}t||jp|jj}t|dd r|j}|rt|}|r|d|}n>dd |D }t|dkrttt|}|r|d|}t|tjrh|tj|||d	d
}|tjkrt|d tjtjfv rtd|_n|||d	}|S tS )Nr   r5   rb   
base_fieldr;   c                 S   s   h | ]}t |qS r   rw   )r+   vr   r   r    	<setcomp>  r   z?ChoiceFieldInspector.field_to_swagger_object.<locals>.<setcomp>r   )r;   enumr:   inmulti)rK   rL   r   ZChoiceFieldr   ry   choiceskeysZMultipleChoiceFieldr   r@   ro   ZModelSerializerr(   rc   rq   rm   r   rx   r   r   r   nextiterrP   r)   IN_FORMZIN_QUERYZcollection_formatr   )r   rX   rY   rI   rZ   rH   rG   Z	enum_typeZenum_valueschoicer   rb   re   Z
model_typeZenum_value_typesZvalues_typerE   r   r   r    r]     sL    
z,ChoiceFieldInspector.field_to_swagger_objectNr|   r   r   r   r    r     s   r   c                   @   s   e Zd ZdZdd ZdS )FileFieldInspectorz*Provides conversions for ``FileField``\ s.c           
      K   s   | j |||fi |\}}t|tjrtd}|tjkr`|tjdd}t|dt	j
r\tj|_|S |tjkr|tjd}	|	d tjkr||	S |tS )NzFFileField is supported only in a formData Parameter or response SchemaT)r;   r%   Zuse_urlrw   r   )rK   rL   r   Z	FileFieldr   r   r   ry   r(   r   ZUPLOADED_FILES_USE_URLrz   rv   r)   Z	TYPE_FILEr   r   )
r   rX   rY   rI   rZ   rH   rG   errrE   paramr   r   r    r]     s    

z*FileFieldInspector.field_to_swagger_objectNr|   r   r   r   r    r     s   r   c                   @   s   e Zd ZdZdd ZdS )DictFieldInspectorz&Provides conversion for ``DictField``.c                 K   sR   | j |||fi |\}}t|tjrN|tjkrN| |j||}|tj|dS t	S )N)r;   Zadditional_properties)
rK   rL   r   Z	DictFieldr   r   r   rC   rA   r   )r   rX   rY   rI   rZ   rH   rG   rD   r   r   r    r]     s    z*DictFieldInspector.field_to_swagger_objectNr|   r   r   r   r    r     s   r   c                   @   s   e Zd ZdZdd ZdS )HiddenFieldInspectorzHide ``HiddenField``.c                 K   s   t |tjrd S tS r   )rL   r   ZHiddenFieldr   )r   rX   rY   rI   rZ   r   r   r    r]     s    z,HiddenFieldInspector.field_to_swagger_objectNr|   r   r   r   r    r     s   r   c                   @   s   e Zd ZdZdd ZdS )JSONFieldInspectorz&Provides conversion for ``JSONField``.c                 K   s@   | j |||fi |\}}t|tjr<|tjkr<|tjdS tS Nrw   )rK   rL   r   Z	JSONFieldr   r   rA   r   r   rX   rY   rI   rZ   rH   rG   r   r   r    r]     s    z*JSONFieldInspector.field_to_swagger_objectNr|   r   r   r   r    r     s   r   c                   @   s   e Zd ZdZdd ZdS )StringDefaultFieldInspectorzRFor otherwise unhandled fields, return them as plain :data:`.TYPE_STRING` objects.c                 K   s&   | j |||fi |\}}|tjdS r   )rK   r   ry   r   r   r   r    r]     s    z3StringDefaultFieldInspector.field_to_swagger_objectNr|   r   r   r   r    r     s   r   )CamelCaseJSONParser)CamelCaseJSONRenderercamelizec                 C   s   | S r   r   )datar   r   r    r     s    r   c                   @   sB   e Zd ZdZdd Zdd Zdd Zer6er6dd	 Z	nd
d	 Z	dS )CamelCaseJSONFilterzSConverts property names to camelCase if ``djangorestframework_camel_case`` is used.c                 C   s   t tt|diS )zHack to force ``djangorestframework_camel_case`` to camelize a plain string.

        :param str s: the string
        :return: camelized string
        :rtype: str
        ru   )r   r   r   )r   sr   r   r    camelize_string  s    z#CamelCaseJSONFilter.camelize_stringc                    sP   t |di rLt fdd|j D |_t |dg rL fdd|jD |_dS )zRecursively camelize property names for the given schema using ``djangorestframework_camel_case``.
        The target schema object must be modified in-place.

        :param openapi.Schema schema: the :class:`.Schema` object
        r<   c                 3   s4   | ],\}}  | t| jp(|fV  qd S r   )r   camelize_schemar   resolve_refrS   )r+   r,   valr   r   r    	<genexpr>  s   z6CamelCaseJSONFilter.camelize_schema.<locals>.<genexpr>r=   c                    s   g | ]}  |qS r   )r   )r+   pr   r   r    r/   %  r   z7CamelCaseJSONFilter.camelize_schema.<locals>.<listcomp>N)r(   r   r<   r0   r=   )r   schemar   r   r    r     s    
z#CamelCaseJSONFilter.camelize_schemac                 K   s2   t |tjjr.|  r.t|| j}| | |S r   )rL   r   r   ZOR_REFis_camel_caser   rS   r   )r   rE   r   objrZ   r   r   r   r    process_result'  s    
z"CamelCaseJSONFilter.process_resultc                 C   s,   t dd |  D p*t dd |  D S )Nc                 s   s   | ]}t |tV  qd S r   )r   r   )r+   parserr   r   r    r   1  r   z4CamelCaseJSONFilter.is_camel_case.<locals>.<genexpr>c                 s   s   | ]}t |tV  qd S r   )r   r   )r+   rendererr   r   r    r   2  r   )anyZget_parser_classesZget_renderer_classesr   r   r   r    r   /  s    z!CamelCaseJSONFilter.is_camel_casec                 C   s   dS )NFr   r   r   r   r    r   5  s    N)
rR   r^   r_   r`   r   r   r   r   r   r   r   r   r   r    r     s   	
r   )RecursiveFieldc                   @   s   e Zd ZdZdS )RecursiveFieldInspectorbProvides conversion for RecursiveField (https://github.com/heywbj/django-rest-framework-recursive)N)rR   r^   r_   r`   r   r   r   r    r   <  s   r   c                   @   s   e Zd ZdZdd ZdS )r   r   c           	      K   s   t |tr|tjkr|du s$J d|j}t |jtjr>|j}t|}|d usbJ dt	t
| | jtj}tj||dd}t |jtjrtjtj|d}|S tS )NTzECan not create schema for RecursiveField when use_references is Falsez.Can't create RecursiveField schema for inline )Zignore_unresolvedr:   )rL   r   r   r   proxiedr   rM   rC   r   r   r;   rS   rT   rU   rW   r   rP   r   )	r   rX   rY   rI   rZ   r   r6   r\   refr   r   r    r]   C  s    z/RecursiveFieldInspector.field_to_swagger_objectNr|   r   r   r   r    r   @  s   )N)datetimer   loggingoperatorr   uuidpkg_resources	packagingr   collectionsr   decimalr   r   r   Zdjango.corer   Z	django.dbr   Zrest_frameworkr   Zrest_framework.settingsr	   r   ru   r   errorsr   utilsr   r   r   r   r   baser   r   r   r   get_distributionZdrf_version	getLoggerrR   r   r   ra   rf   rc   rl   ro   rr   rs   r   ZIntegerFieldZ
FloatFieldr   Znumeric_fieldsZMinValueValidator__gt__ZMaxValueValidator__lt__ZMinLengthValidatorZ	CharFieldZMaxLengthValidatorrN   rM   r   rO   r   Z	AutoFieldZTYPE_INTEGERZBinaryFieldry   ZFORMAT_BINARYZBooleanFieldZTYPE_BOOLEANZDateTimeFieldZFORMAT_DATETIMEZ	DateFieldZFORMAT_DATEZFORMAT_DECIMALZDurationFieldr   ZIPAddressFieldZFORMAT_IPV4ZGenericIPAddressFieldZFORMAT_IPV6Z	SlugFieldZFORMAT_SLUGZ	TextFieldZ	TimeFieldZ	UUIDFieldZFORMAT_UUIDZmodel_field_to_basic_typer   Z
EmailFieldZFORMAT_EMAILZURLFieldrz   Z
RegexFieldZ
ModelFieldZserializer_field_to_basic_typeparser@   ZNullBooleanFieldr   rx   r   r   r   r?   intr   r   dictrA   UUIDdater   r7   r   r   r   SequenceAbstractSetr   r   r   r   r   r   r   r   r   r   Z%djangorestframework_camel_case.parserr   Z%djangorestframework_camel_case.renderr   r   ImportErrorr   Zrest_framework_recursive.fieldsr   r   r   r   r   r    <module>   s   
t
:#%&'>9
	-