U
    hjz                     @  s6  d Z ddlmZ ddlmZmZ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mZmZmZmZ ddlmZ ddlmZmZ z$dd	lmZmZmZmZmZmZ W n4 e k
r   dd	l!mZmZmZmZmZmZ Y nX dd
lm"Z" eeeedf Z#eee$df Z%G dd deZ&ee$eee$e'f e&f f Z(G dd deZ)G dd de)Z*G dd de)Z+G dd de)Z,G dd deZ-G dd de$e	Z.G dd deZ/G dd de/Z0G dd deZ1d d! Z2G d"d# d#eZ3G d$d% d%e3Z4G d&d' d'e$e	Z5G d(d) d)ed*d+Z6G d,d- d-e3Z7G d.d/ d/eZ8G d0d1 d1e8Z9G d2d3 d3e8Z:G d4d5 d5e	Z;G d6d7 d7eZ<G d8d9 d9ed*d+Z=G d:d; d;ed*d+Z>G d<d= d=e<Z?G d>d? d?e<Z@G d@dA dAeZAG dBdC dCeAZBeG dDdE dEeZCG dFdG dGed*d+ZDG dHdI dIeZEG dJdK dKed*d+ZFG dLdM dMeZGe+H  G dNdO dOeZIG dPdQ dQeZJG dRdS dSed*d+ZKG dTdU dUed*d+ZLG dVdW dWeZMG dXdY dYeZNG dZd[ d[eZOG d\d] d]eZPG d^d_ d_eZQG d`da daeZRG dbdc dce$e	ZSG ddde deed*d+ZTG dfdg dged*d+ZUG dhdi dieZVdS )jzSchemas for the LangSmith API.    )annotations)datetime	timedeltatimezone)Decimal)Enum)	AnyDictList
NamedTupleOptionalProtocolTupleUnionruntime_checkable)UUID)NotRequired	TypedDict)	BaseModelFieldPrivateAttr
StrictBoolStrictFloat	StrictInt)LiteralNc                   @  s"   e Zd ZU dZded< ded< dS )
AttachmentaB  Annotated type that will be stored as an attachment if used.

    Examples:
        --------
        .. code-block:: python

        @traceable
        def my_function(bar: int, my_val: Attachment):
            # my_val will be stored as an attachment
            # bar will be stored as inputs
            return bar
    strZ	mime_typebytesdataN__name__
__module____qualname____doc____annotations__ r%   r%   5/tmp/pip-unpacked-wheel-cqvhoa9t/langsmith/schemas.pyr   0   s   
r   c                   @  s^   e Zd ZU dZded< eedZded< eddZd	ed
< eddZ	d	ed< G dd dZ
dS )ExampleBasezExample base model.r   
dataset_iddefault_factoryDict[str, Any]inputsNdefaultOptional[Dict[str, Any]]outputsmetadatac                   @  s   e Zd ZdZdZdS )zExampleBase.Config#Configuration class for the schema.TNr    r!   r"   r#   frozenr%   r%   r%   r&   ConfigN   s   r5   )r    r!   r"   r#   r$   r   dictr,   r0   r1   r5   r%   r%   r%   r&   r'   F   s   
r'   c                   @  s<   e Zd ZU dZded< edd dZded< d	Zd
ed< d	S )ExampleCreatezExample create model.Optional[UUID]idc                   C  s   t tjS Nr   nowr   utcr%   r%   r%   r&   <lambda>X       zExampleCreate.<lambda>r)   r   
created_atNOptional[Union[str, List[str]]]split)r    r!   r"   r#   r$   r   r@   rB   r%   r%   r%   r&   r7   T   s   
r7   c                      s   e Zd ZU dZded< edd dZded< eed	d
Zded< edd
Z	ded< ee
dZded< dZded< edd
Zded< edd
Zded< d ddddd fddZeddddZdd Z  ZS )!ExamplezExample model.r   r9   c                   C  s   t jdtjdS )Nr   )tz)r   fromtimestampr   r=   r%   r%   r%   r&   r>   a   r?   zExample.<lambda>r)   r   r@   z$00000000-0000-0000-0000-000000000000r-   r(   NOptional[datetime]modified_atz	List[Run]runsr8   source_run_idOptional[str]	_host_url
_tenant_idr   None)rK   rL   kwargsreturnc                   s   t  jf | || _|| _dS )Initialize a Dataset object.N)super__init__rK   rL   )selfrK   rL   rN   	__class__r%   r&   rR   j   s    zExample.__init__rO   c                 C  sL   | j rHd| j d| j }| jr:| j  dt| j | S | j  | S dS )URL of this run within the app.
/datasets/z/e//o/N)rK   r(   r9   rL   r   )rS   pathr%   r%   r&   urlu   s    zExample.urlc                 C  s$   | j  d| j d| j d| j dS )5Return a string representation of the RunBase object.(id=z, dataset_id=z, link=''))rU   r9   r(   r[   rS   r%   r%   r&   __repr__   s    zExample.__repr__)NN)r    r!   r"   r#   r$   r   r@   r   r(   rG   listrH   rI   r   rK   rL   rR   propertyr[   r`   __classcell__r%   r%   rT   r&   rC   \   s"   
  	rC   c                   @  s   e Zd ZU dZded< dS )ExampleSearchzExample returned via search.r   r9   Nr   r%   r%   r%   r&   rd      s   
rd   c                   @  s\   e Zd ZU dZdZded< dZded< dZded< dZded< dZ	d	ed
< G dd dZ
dS )ExampleUpdatezUpdate class for Example.Nr8   r(   r/   r,   r0   r1   rA   rB   c                   @  s   e Zd ZdZdZdS )zExampleUpdate.Configr2   TNr3   r%   r%   r%   r&   r5      s   r5   )r    r!   r"   r#   r(   r$   r,   r0   r1   rB   r5   r%   r%   r%   r&   re      s   
re   c                   @  s   e Zd ZdZdZdZdZdS )DataTypezEnum for dataset data types.kvllmchatN)r    r!   r"   r#   rg   rh   ri   r%   r%   r%   r&   rf      s   rf   c                   @  s@   e Zd ZU dZded< dZded< dZded< G d	d
 d
ZdS )DatasetBasezDataset base model.r   nameNrJ   descriptionzOptional[DataType]	data_typec                   @  s   e Zd ZdZdZdS )zDatasetBase.Configr2   TNr3   r%   r%   r%   r&   r5      s   r5   )r    r!   r"   r#   r$   rl   rm   r5   r%   r%   r%   r&   rj      s
   
rj   c                      s   e Zd ZU dZded< ded< eddZded	< dZd
ed< dZd
ed< dZ	ded< dZ
ded< dZded< eddZded< eddZded< eddZded< ddddddd fddZeddddZ  ZS )DatasetzDataset ORM model.r   r9   r   r@   Nr-   rF   rG   Optional[int]example_countsession_countlast_session_start_timer/   inputs_schemaoutputs_schemarJ   rK   r8   rL   _public_pathr   rM   )rK   rL   ru   rN   rO   c                   sP   d|kr| d|d< d|kr,| d|d< t jf | || _|| _|| _dS )rP   Zinputs_schema_definitionrs   Zoutputs_schema_definitionrt   N)poprQ   rR   rK   rL   ru   )rS   rK   rL   ru   rN   rT   r%   r&   rR      s    zDataset.__init__rV   c                 C  sV   | j rR| jr| j  | j S | jr@| j  dt| j d| j S | j  d| j S dS )rW   rY   rX   N)rK   ru   rL   r   r9   r_   r%   r%   r&   r[      s    zDataset.url)NNN)r    r!   r"   r#   r$   r   rG   rp   rq   rr   rs   rt   r   rK   rL   ru   rR   rb   r[   rc   r%   r%   rT   r&   rn      s$   
   rn   c                   @  s&   e Zd ZU dZdZded< ded< dS )DatasetVersionz%Class representing a dataset version.NOptional[List[str]]tagsr   Zas_of)r    r!   r"   r#   ry   r$   r%   r%   r%   r&   rw      s   
rw   c                   C  s   di iS )Nr1   r%   r%   r%   r%   r&   _default_extra   s    rz   c                   @  s   e Zd ZU dZded< ded< ded< ded< d	Zd
ed< eedZded< d	Z	ded< d	Z
ded< d	Zded< eedZded< d	Zded< d	Zded< d	Zded< d	Zded< eedZded< eddd d!Zeddd"d#Zd$d% Zd	S )&RunBasea3  Base Run schema.

    A Run is a span representing a single unit of work or operation within your LLM app.
    This could be a single call to an LLM or chain, to a prompt formatting call,
    to a runnable lambda invocation. If you are familiar with OpenTelemetry,
    you can think of a run as a span.
    r   r9   r   rk   r   
start_timerun_typeNrF   end_timer)   Optional[dict]extrarJ   error
serializedzOptional[List[Dict]]eventsr6   r,   r0   r8   reference_example_idparent_run_idrx   ry   Attachmentsattachmentsdict[str, Any]rV   c                 C  s   | j dkri | _ | j di S zRetrieve the metadata (if any).Nr1   )r   
setdefaultr_   r%   r%   r&   r1      s    
zRunBase.metadatac                 C  s   | j dS )z"Retrieve the revision ID (if any).revision_id)r1   getr_   r%   r%   r&   r   '  s    zRunBase.revision_idc                 C  s$   | j  d| j d| j d| j dS )r\   r]   z, name='z', run_type='r^   )rU   r9   rk   r}   r_   r%   r%   r&   r`   ,  s    zRunBase.__repr__)r    r!   r"   r#   r$   r~   r   rz   r   r   r   r   r6   r,   r0   r   r   ry   r   rb   r1   r   r`   r%   r%   r%   r&   r{      s*   
r{   c                      s,  e Zd ZU dZdZded< dZded< dZded< dZd	ed
< dZ	ded< dZ
ded< dZded< dZded< dZded< dZded< dZded< dZded< dZded< dZded< dZded< ded< eddZded< dZd ed!< eddZded"< d+dd#d$d% fd&d'Zedd(d)d*Z  ZS ),Runz$Run schema when loading from the DB.Nr8   
session_idOptional[List[UUID]]child_run_idszOptional[List[Run]]
child_runsr/   feedback_statsrJ   app_pathmanifest_idstatusro   prompt_tokenscompletion_tokenstotal_tokensrF   first_token_timeOptional[Decimal]
total_costprompt_costcompletion_costparent_run_idsr   trace_id r-   r   dotted_orderOptional[bool]
in_datasetrK   r   rM   rK   rN   rO   c                   sr   | dsd| di|}|ddp*i }t jf |d|i || _| j sn| jsn| j	  | j
 | _dS )Initialize a Run object.r   r9   r,   N)r   rv   rQ   rR   rK   r   stripr   r|   	isoformatr9   )rS   rK   rN   r,   rT   r%   r&   rR   f  s    
zRun.__init__rV   c                 C  s    | j r| jr| j  | j S dS )rW   N)rK   r   r_   r%   r%   r&   r[   p  s    zRun.url)N)r    r!   r"   r#   r   r$   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rK   rR   rb   r[   rc   r%   r%   rT   r&   r   1  s.   

r   c                   @  s,   e Zd ZdZdZdZdZdZdZdZ	dZ
d	S )
RunTypeEnumz5(Deprecated) Enum for run types. Use string directly.toolchainrh   	retriever	embeddingpromptparserN)r    r!   r"   r#   r   r   rh   r   r   r   r   r%   r%   r%   r&   r   x  s   r   c                   @  s   e Zd ZU dZded< ded< ded< ded	< ded
< ded< ded< ded< ded< ded< ded< ded< ded< ded< ded< ded< ded< ded< ded< ded< ded< d ed!< ded"< d#ed$< d%S )&RunLikeDictz&Run-like dictionary, for type-hinting.r   rk   r   r}   r   r|   r   r,   r0   rF   r~   r   rJ   r   r   r8   r   r   Optional[List[dict]]r   rx   ry   Zinputs_s3_urlsZoutputs_s3_urlsr9   r   Zsession_namer   Zinput_attachmentsZoutput_attachmentsr   r   r   r   r   Nr   r%   r%   r%   r&   r     s2   
r   F)totalc                   @  s*   e Zd ZU dZdZded< dZded< dS )RunWithAnnotationQueueInfoz&Run schema with annotation queue info.NrF   last_reviewed_timeadded_at)r    r!   r"   r#   r   r$   r   r%   r%   r%   r&   r     s   
r   c                   @  s,   e Zd ZU dZded< eedZded< dS )FeedbackSourceBasezBase class for feedback sources.

    This represents whether feedback is submitted from the API, model, human labeler,
        etc.
    r   typer)   r/   r1   N)r    r!   r"   r#   r$   r   r6   r1   r%   r%   r%   r&   r     s   
r   c                   @  s   e Zd ZU dZdZded< dS )APIFeedbackSourcezAPI feedback source.apizLiteral['api']r   Nr    r!   r"   r#   r   r$   r%   r%   r%   r&   r     s   
r   c                   @  s   e Zd ZU dZdZded< dS )ModelFeedbackSourcezModel feedback source.modelzLiteral['model']r   Nr   r%   r%   r%   r&   r     s   
r   c                   @  s   e Zd ZdZdZdZdS )FeedbackSourceTypezFeedback source type.r   r   N)r    r!   r"   r#   ZAPIZMODELr%   r%   r%   r&   r     s   r   c                   @  s   e Zd ZU dZded< dZded< dZded< ded	< ded
< ded< dZded< dZded< dZ	ded< dZ
ded< dZded< dZded< dZded< dZded< dZded< G dd dZdS )FeedbackBasezFeedback schema.r   r9   NrF   r@   rG   r8   Zrun_idr   r   key
SCORE_TYPEscore
VALUE_TYPEvaluerJ   commentzUnion[str, dict, None]
correctionOptional[FeedbackSourceBase]feedback_sourcer   comparative_experiment_idfeedback_group_idzOptional[Dict]r   c                   @  s   e Zd ZdZdZdS )zFeedbackBase.Configr2   TNr3   r%   r%   r%   r&   r5     s   r5   )r    r!   r"   r#   r$   r@   rG   r   r   r   r   r   r   r   r   r   r5   r%   r%   r%   r&   r     s"   
r   c                   @  s"   e Zd ZU dZded< ded< dS )FeedbackCategoryz+Specific value and label pair for feedback.floatr   rJ   labelNr   r%   r%   r%   r&   r     s   
r   c                   @  s2   e Zd ZU dZded< ded< ded< ded< d	S )
FeedbackConfigz:Represents _how_ a feedback value ought to be interpreted.z2Literal[('continuous', 'categorical', 'freeform')]r   Optional[float]minmaxz Optional[List[FeedbackCategory]]
categoriesNr   r%   r%   r%   r&   r     s   
r   c                   @  s&   e Zd ZU dZded< dZded< dS )FeedbackCreatez"Schema used for creating feedback.r   r   NzOptional[FeedbackConfig]feedback_config)r    r!   r"   r#   r$   r   r%   r%   r%   r&   r     s   
r   c                   @  s6   e Zd ZU dZded< ded< ded< dZded	< dS )
FeedbackzSchema for getting feedback.r   r9   r   r@   rG   Nr   r   )r    r!   r"   r#   r$   r   r%   r%   r%   r&   r     s   
r   c                      s   e Zd ZU dZded< edd dZded< d	Zd
ed< d	Zded< d	Z	ded< d	Z
ded< ded< ded< ed	dZded< d$dddd fddZeddddZedddd Zed!dd"d#Z  ZS )%TracerSessionzbTracerSession schema for the API.

    Sessions are also referred to as "Projects" in the UI.
    r   r9   c                   C  s   t tjS r:   r;   r%   r%   r%   r&   r>   )  r?   zTracerSession.<lambda>r)   r   r|   NrF   r~   rJ   rl   rk   r/   r   	tenant_idr8   reference_dataset_idr-   rK   r   rM   r   c                   s6   t  jf | || _| jjdkr2| jjtjd| _dS )r   N)tzinfo)rQ   rR   rK   r|   r   replacer   r=   )rS   rK   rN   rT   r%   r&   rR   :  s    zTracerSession.__init__rV   c                 C  s$   | j r | j  d| j d| j S dS )rW   rY   z/projects/p/N)rK   r   r9   r_   r%   r%   r&   r[   A  s    zTracerSession.urlr   c                 C  s"   | j dksd| j kri S | j d S r   r   r_   r%   r%   r&   r1   H  s    zTracerSession.metadata	List[str]c                 C  s"   | j dksd| j krg S | j d S )zRetrieve the tags (if any).Nry   r   r_   r%   r%   r&   ry   O  s    zTracerSession.tags)N)r    r!   r"   r#   r$   r   r|   r~   rl   rk   r   r   rK   rR   rb   r[   r1   ry   rc   r%   r%   rT   r&   r   !  s"   
r   c                   @  s   e Zd ZU dZded< ded< ded< ded< ded< ded	< d
ed< ded< ded< ded< ded< ded< ded< ded< ded< dS )TracerSessionResultzqA project, hydrated with additional information.

    Sessions are also referred to as "Projects" in the UI.
    ro   Z	run_countzOptional[timedelta]Zlatency_p50Zlatency_p99r   r   r   rF   Zlast_run_start_timer/   r   zOptional[List[Dict[str, Any]]]Z
run_facetsr   r   r   r   Zfirst_token_p50Zfirst_token_p99r   Z
error_rateNr   r%   r%   r%   r&   r   W  s"   
r   c                   @  s4   e Zd ZU dZded< ded< eddddZd	S )
BaseMessageLikez7A protocol representing objects similar to BaseMessage.r   contentzDict[Any, Any]Zadditional_kwargsrV   c                 C  s   dS )z,Type of the Message, used for serialization.Nr%   r_   r%   r%   r&   r     s    zBaseMessageLike.typeN)r    r!   r"   r#   r$   rb   r   r%   r%   r%   r&   r   }  s
   
r   c                   @  s*   e Zd ZU dZded< ded< ded< dS )DatasetShareSchemaz*Represents the schema for a dataset share.r   r(   Zshare_tokenr   r[   Nr   r%   r%   r%   r&   r     s
   
r   c                   @  sb   e Zd ZU dZded< ded< dZded< ed	d
 dZded< edd
 dZded< ded< dS )AnnotationQueuezRepresents an annotation queue.r   r9   r   rk   NrJ   rl   c                   C  s   t tjS r:   r;   r%   r%   r%   r&   r>     r?   zAnnotationQueue.<lambda>r)   r   r@   c                   C  s   t tjS r:   r;   r%   r%   r%   r&   r>     r?   
updated_atr   )	r    r!   r"   r#   r$   rl   r   r@   r   r%   r%   r%   r&   r     s   
r   c                   @  sB   e Zd ZU dZded< ded< ded< ded< ded< d	ed
< dS )BatchIngestConfigz"Configuration for batch ingestion.boolZuse_multipart_endpointintZscale_up_qsize_triggerZscale_up_nthreads_limitZscale_down_nempty_triggerZ
size_limitro   Zsize_limit_bytesNr   r%   r%   r%   r&   r     s   
r   c                   @  s6   e Zd ZU dZdZded< dZded< dZded	< dS )
LangSmithInfoz'Information about the LangSmith server.r   r   versionNrF   license_expiration_timezOptional[BatchIngestConfig]batch_ingest_config)r    r!   r"   r#   r   r$   r   r   r%   r%   r%   r&   r     s   
r   c                   @  s6   e Zd ZU dZded< ded< ded< dZded	< dS )
LangSmithSettingsz"Settings for the LangSmith tenant.r   r9   Zdisplay_namer   r@   NrJ   tenant_handle)r    r!   r"   r#   r$   r   r%   r%   r%   r&   r     s
   
r   c                   @  s*   e Zd ZU dZded< ded< ded< dS )	FeedbackIngestTokenz2Represents the schema for a feedback ingest token.r   r9   r   r[   r   Z
expires_atNr   r%   r%   r%   r&   r     s
   
r   c                   @  s*   e Zd ZU dZded< ded< ded< dS )	RunEventzRun event schema.r   rk   zUnion[datetime, str]timer/   rN   Nr   r%   r%   r%   r&   r     s
   
r   c                   @  s*   e Zd ZU dZded< ded< ded< dS )TimeDeltaInputzTimedelta input schema.r   dayshoursminutesNr   r%   r%   r%   r&   r     s
   
r   c                   @  s*   e Zd ZU dZded< ded< ded< dS )DatasetDiffInfoz;Represents the difference information between two datasets.z
List[UUID]Zexamples_modifiedZexamples_addedZexamples_removedNr   r%   r%   r%   r&   r     s
   
r   c                   @  s   e Zd ZU dZded< dZded< dZded< ded< d	ed
< d	ed< ded< dZded< dZded< dZ	ded< e
ddddZdS )ComparativeExperimentzRepresents a comparative experiment.

    This information summarizes evaluation results comparing
    two or more models on a given dataset.
    r   r9   NrJ   rk   rl   r   r   r@   rG   r   r/   r   r   experiments_infor   r   rV   c                 C  s"   | j dksd| j kri S | j d S r   r   r_   r%   r%   r&   r1     s    zComparativeExperiment.metadata)r    r!   r"   r#   r$   rk   rl   r   r   r   rb   r1   r%   r%   r%   r&   r     s   
r   c                   @  s:   e Zd ZU dZded< ded< ded< ded< ded	< d
S )PromptCommitz$Represents a Prompt with a manifest.r   ownerrepocommit_hashr+   manifestz
List[dict]ZexamplesNr   r%   r%   r%   r&   r   !  s   
r   c                   @  s   e Zd ZU dZded< ded< ded< dZded	< dZded
< dZded< dZded< dZ	ded< dZ
ded< eedZded< dZded< dZded< dZded< dS )ListedPromptCommitz;Represents a listed prompt commit with associated metadata.r   r9   r   r   r   Nr8   r   repo_id	parent_idrJ   r   rF   r@   r   r)   r   example_run_idsr   ro   num_downloads	num_viewsparent_commit_hash)r    r!   r"   r#   r$   r   r   r   r   r@   r   r   ra   r   r   r   r   r%   r%   r%   r&   r   0  s   
r   c                   @  s   e Zd ZU dZded< dZded< dZded< ded< ded	< d
ed< d
ed< ded< ded< ded< dZded< dZded< ded< ded< ded< ded< ded< dZ	ded< dZ
ded< ded< dZded< dZded< dS ) Promptz"Represents a Prompt with metadata.r   Zrepo_handleNrJ   rl   readmer9   r   r   r@   r   r   Z	is_publicZis_archivedr   ry   original_repo_idupstream_repo_idr   Z	full_namer   	num_likesr   r   r   liked_by_auth_userlast_commit_hashZnum_commitsoriginal_repo_full_nameupstream_repo_full_name)r    r!   r"   r#   r$   rl   r  r  r  r  r  r  r  r%   r%   r%   r&   r   [  s0   
r   c                   @  s"   e Zd ZU dZded< ded< dS )ListPromptsResponsez A list of prompts with metadata.zList[Prompt]Zreposr   r   Nr   r%   r%   r%   r&   r	    s   
r	  c                   @  s    e Zd ZdZdZdZdZdZdS )PromptSortFieldz$Enum for sorting fields for prompts.r   r   r   r  N)r    r!   r"   r#   r   r   r   r  r%   r%   r%   r&   r
    s   r
  c                   @  s*   e Zd ZU dZded< ded< ded< dS )InputTokenDetailsz~Breakdown of input token counts.

    Does *not* need to sum to full input token count. Does *not* need to have all keys.
    r   audioZcache_creationZ
cache_readNr   r%   r%   r%   r&   r    s
   
r  c                   @  s"   e Zd ZU dZded< ded< dS )OutputTokenDetailszBreakdown of output token counts.

    Does *not* need to sum to full output token count. Does *not* need to have all keys.
    r   r  Z	reasoningNr   r%   r%   r%   r&   r    s   
r  c                   @  s:   e Zd ZU dZded< ded< ded< ded< ded	< d
S )UsageMetadatazUsage metadata for a message, such as token counts.

    This is a standard representation of token usage that is consistent across models.
    r   Zinput_tokensZoutput_tokensr   zNotRequired[InputTokenDetails]Zinput_token_detailszNotRequired[OutputTokenDetails]Zoutput_token_detailsNr   r%   r%   r%   r&   r    s   
r  )Wr#   
__future__r   r   r   r   decimalr   enumr   typingr   r	   r
   r   r   r   r   r   r   uuidr   Ztyping_extensionsr   r   Zpydantic.v1r   r   r   r   r   r   ImportErrorZpydanticr   r   r   r   r   r   r   r'   r7   rC   rd   re   rf   rj   rn   rw   rz   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zupdate_forward_refsr   r   r   r   r   r   r   r   r   r	  r
  r  r  r  r%   r%   r%   r&   <module>   s~   ,$&	(.JG		*	6&
$+1	