
    jT                        d 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m	Z	m
Z
mZmZm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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& ddl'm(Z( ddl)m*Z*m+Z+ ddl,m-Z-m.Z.m/Z/m0Z0m1Z1  e       Z2 e       Z3 ed      Z4 e       Z5	 d6de(de	e6ef   de6de7de7f
dZ8e.	 	 	 	 d7de
d   de
d   de6de
d   dee	e6e6f      d ee	e6e6f      d!ee	e6e6f      de*fd"       Z9e.	 	 	 	 d7de
d   de
d   de6de
d   dee	e6e6f      d ee	e6e6f      d!ee	e6e6f      dee*eeee*f   f   fd#       Z:e.	 	 	 	 d7d$e6de
d   dee	e6e6f      d ee	e6e6f      d!ee	e6e6f      de*fd%       Z;	 d8d$e6de(d&ee7ejx                  f   d'e=d(e&d)e>de
d   fd*Z?e.	 	 	 	 d7d$e6de
d   dee	e6e6f      d ee	e6e6f      d!ee	e6e6f      dee*eeee*f   f   fd+       Z@e.	 	 	 	 	 	 d9d,ee6   d-eeA   de
d.   dee	e6e6f      d ee	e6e6f      d!ee	e6e6f      fd/       ZBe.	 	 	 	 	 d:d,ee6   d-eeA   de
d.   d ee	e6e6f      d!ee	e6e6f      f
d0       ZC	 	 	 	 d7d$e6de
d.   dee	e6e6f      d ee	e6e6f      d!ee	e6e6f      de#fd1ZD	 	 	 	 d7d$e6de
d.   dee	e6e6f      d ee	e6e6f      d!ee	e6e6f      dee#eeee#f   f   fd2ZE	 d;d$e6d3e6dd4fd5ZFy)<z
Main File for Batches API implementation

https://platform.openai.com/docs/api-reference/batch

- create_batch()
- retrieve_batch()
- cancel_batch()
- list_batch()

    N)partial)Any	CoroutineDictLiteralOptionalUnioncast)verbose_logger)Logging)AzureBatchesAPI)AsyncHTTPHandlerHTTPHandler)BaseLLMHTTPHandler)OpenAIBatchesAPI)VertexAIBatchPrediction)get_secret_str)BatchCancelBatchRequestCreateBatchRequestRetrieveBatchRequest)GenericLiteLLMParams)LiteLLMBatchLlmProviders)ProviderConfigManagerclientget_litellm_paramsget_llm_providersupports_httpx_timeout )gcs_bucket_nameoptional_paramskwargscustom_llm_providerdefault_timeoutreturnc                 0   | j                   xs |j                  d|      xs |}t        |t        j                        rAt        |      du r|j                  xs |}t        |      S t        |j                  xs |      S |t        |      S t        |      S )a  
    Resolve timeout value from various sources and handle httpx.Timeout objects.

    Args:
        optional_params: GenericLiteLLMParams object containing timeout
        kwargs: Additional kwargs that may contain request_timeout
        custom_llm_provider: Provider name for httpx timeout support check
        default_timeout: Default timeout value to use

    Returns:
        Resolved timeout as float
    request_timeoutF)timeoutget
isinstancehttpxTimeoutr   readfloat)r"   r#   r$   r%   r)   read_timeouts         m/Users/manta/Documents/Projects/TheRoad-I1/backend/.venv/lib/python3.12/site-packages/litellm/batches/main.py_resolve_timeoutr2   6   s    & 	 	::'9	  '5==)!"56%?"<<:?L&& 899 _%% >    completion_window24hendpoint)z/v1/chat/completionsz/v1/embeddingsz/v1/completionsinput_file_id)openaiazure	vertex_aibedrockmetadataextra_headers
extra_bodyc           
      l  K   	 t        j                         }d|d<   t        t        | ||||||fi |}	t	        j
                         }
t        |
j                  |	      }|j                  d|       d{   }t        j                  |      r| d{   }|S |}|S 7 )7 # t        $ r}|d}~ww xY ww)z
    Async: Creates and executes a batch from an uploaded file of request

    LiteLLM Equivalent of POST: https://api.openai.com/v1/batches
    Tacreate_batchN)
asyncioget_event_loopr   create_batchcontextvarscopy_contextrunrun_in_executoriscoroutine	Exception)r4   r6   r7   r$   r<   r=   r>   r#   loopfuncctxfunc_with_contextinit_responseresponsees                  r1   r@   r@   a   s      %%'"& 

 

 &&(#CGGT2"2249JKK}-**H  %H L +
  sY   B4A/B! 3B4B! BB! B4B! B4B! B! !	B1*B,,B11B4c                 	   	 t        d1i |}|j                  dd      }	|j                  dd      }
|j                  dd      }|j                  dd      }	 |t        |d      \  }}}}|j                  dd	      d
u }t        t        d1i |      }t        t        |j                  dd            }t        |||      }|j                  |d|j                         |	|
||di d|j                  d
      |       t        | |||||      }|!t        j                   |t#        |            }nd}|`t$        j'                  ||||xs i |j(                  |j*                  ||t,         t/        t,        t0        t2        f      rt,        nd||      }|S d}|dk(  r|j(                  xsB t4        j(                  xs0 t7        j8                  d      xs t7        j8                  d      xs d}|j:                  xs, t4        j:                  xs t7        j8                  dd      xs d}|j*                  xs9 t4        j*                  xs' t4        j<                  xs t7        j8                  d      }t>        j'                  ||||||j@                  |      }|S |dk(  r|j(                  xs t4        j(                  xs tC        d      }|jD                  xs t4        jD                  xs tC        d      }|j*                  xs< t4        j*                  xs* t4        jF                  xs tC        d      xs tC        d      }|j                  di       }||j                  dd       ntC        d        tH        j'                  ||||||j@                  ||!      }|S |d"k(  r|j(                  xs d#}|jJ                  xs t4        jJ                  xs tC        d$      }|jL                  xs t4        jL                  xs tC        d%      }|jN                  xs tC        d&      }tP        j'                  |||||||j@                  |'      }|S t4        jR                  jU                  d(jW                  |      d)|tY        jZ                  d*d+tY        j\                  d,d-.      /      0      # t        $ r,}t	        j
                  dt        |              Y d}~dd}~ww xY w# t        $ r}|d}~ww xY w)2z
    Creates and executes a batch from an uploaded file of request

    LiteLLM Equivalent of POST: https://api.openai.com/v1/batches
    litellm_call_idNproxy_server_request
model_infomodel)rU   r$   zPlitellm.batches.main.py::create_batch() - Error inferring custom_llm_provider - r@   FTlitellm_logging_obj)rR   rS   rT   r<   preset_cache_keystream_response)exclude_unsetrU   userr"   litellm_paramsr$   )r4   r6   r7   r<   r=   r>   rU   provider)provider_configr\   create_batch_dataheadersapi_baseapi_keylogging_obj	_is_asyncr   r)   rU   r8   OPENAI_BASE_URLOPENAI_API_BASEhttps://api.openai.com/v1OPENAI_ORGANIZATIONOPENAI_API_KEY)rb   rc   organizationr`   r)   max_retriesre   r9   AZURE_API_BASEAZURE_API_VERSIONAZURE_OPENAI_API_KEYAZURE_API_KEYr>   azure_ad_tokenAZURE_AD_TOKEN)re   rb   rc   api_versionr)   rl   r`   r\   r:   r    VERTEXAI_PROJECTVERTEXAI_LOCATIONVERTEXAI_CREDENTIALS)re   rb   vertex_projectvertex_locationvertex_credentialsr)   rl   r`   zALiteLLM doesn't support custom_llm_provider={} for 'create_batch'n/a  Unsupported providerrC   "https://github.com/BerriAI/litellmmethodurlstatus_codecontentrequestmessagerU   llm_providerrO    )/r   r*   r   rI   r   	exceptionstrpopdictr
   LiteLLMLoggingObjr2   update_environment_variables
model_dumpr   r   get_provider_batches_configr   base_llm_http_handlerrC   rb   rc   r   r+   r   r   litellmosgetenvrk   
openai_keyopenai_batches_instancerl   r   rs   	azure_keyazure_batches_instancerw   rx   ry   vertex_ai_batches_instance
exceptionsBadRequestErrorformatr,   ResponseRequest)r4   r6   r7   r$   r<   r=   r>   r#   r"   rR   rS   rT   rU   _rP   re   r\   rV   r)   _create_batch_requestr_   rO   rb   rk   rc   rs   vertex_ai_projectvertex_ai_locationry   s                                r1   rC   rC      s    w.88 **%6=%zz*@$GZZd3
%zz'48		 !1(,"q!Q JJ6$>	2<V<=15vzz*?F2
 #?F<OP88+668#2(<($$(#% ",,4,@ !4 	9 	
  !3/''!!
 3OO%&9:O
 #O&,99 /-"7%+(11'///#%v5E'FG   : H  O"&(*  (( /##/99.// 99.// /   ,, ''992D9 	   '' /??/%%/ 99-.	  /;;!)"7+77# < Hh W !G+(( 4##4!"23   ++ 7&&7!"56   '' 3??3$$3 ""893 "/2  ),,\2>J%/6/0-::#!'+77"7- ; 	Hb O !K/&//52H.. 6))6!"45   // 7**7!"56 
 "1!C!C "~&H 2>>#!0 2#5+77"7 ? 	H.  $$44[bb' 0 #2!MMEij 5  {  	$$bcfghcibjk 	T  s_   AS R *D)S C?S C?S B,S AS 	S'!SS SS 	S&S!!S&batch_idc                 h  K   	 t        j                         }d|d<   t        t        | ||||fi |}t	        j
                         }t        |j                  |      }	|j                  d|	       d{   }
t        j                  |
      r|
 d{   }|S |
}|S 7 )7 # t        $ r}|d}~ww xY ww)zo
    Async: Retrieves a batch.

    LiteLLM Equivalent of GET https://api.openai.com/v1/batches/{batch_id}
    Taretrieve_batchN)
rA   rB   r   retrieve_batchrD   rE   rF   rG   rH   rI   r   r$   r<   r=   r>   r#   rJ   rK   rL   rM   rN   rO   rP   s                r1   r   r   [  s     %%'$( ! 
 
 &&(#CGGT2"2249JKK}-**H  %H L*
  Y   B2A-B 1B2B BB B2B B2B B 	B/(B**B//B2r)   r\   _retrieve_batch_requestre   c                    d }|dk(  r|j                   xsB t        j                   xs0 t        j                  d      xs t        j                  d      xs d}|j                  xs, t        j                  xs t        j                  dd       xs d }|j
                  xs9 t        j
                  xs' t        j                  xs t        j                  d      }	t        j                  ||||	|||j                        }
|
S |dk(  r|j                   xs t        j                   xs t        d	      }|j                  xs t        j                  xs t        d
      }|j
                  xs< t        j
                  xs* t        j                  xs t        d      xs t        d      }	|j                  di       }||j                  dd        nt        d       t        j                  |||	|||j                  ||      }
|
S |dk(  r|j                   xs d}|j                   xs t        j                   xs t        d      }|j"                  xs t        j"                  xs t        d      }|j$                  xs t        d      }t&        j                  || ||||||j                        }
|
S t        j(                  j+                  dj-                  |      d|t/        j0                  ddt/        j2                  dd                  ) Nr8   rf   rg   rh   ri   rj   )re   retrieve_batch_datarb   rc   rk   r)   rl   r9   rm   rn   ro   rp   r>   rq   rr   )re   rb   rc   rs   r)   rl   r   r\   r:   r    rt   ru   rv   )re   r   rb   rw   rx   ry   r)   rl   zJLiteLLM doesn't support {} for 'create_batch'. Only 'openai' is supported.rz   r{   r|   create_threadr}   r~   r   r   )rb   r   r   r   rk   rc   r   r   r   rl   r   rs   r   r*   r   r   rw   rx   ry   r   r   r   r   r,   r   r   )r   r"   r)   r\   r   re   r$   rb   rk   rc   rO   rs   r>   r   r   ry   s                   r1   8_handle_retrieve_batch_providers_without_provider_configr     sO    #Hh& $$ ++yy*++ yy*++ + 	 (( ##yy.5 	 	 ## ++!!+ yy)*	 	 +99 7%'33 : 
h OW 
	'$$ 00./ 	 '' 3""312 	 ## //  / 45/ o. 	 %((r:
!NN+T2+,)88#'33 7) 9 	
b OO 
	+"++1r** 2%%201 	 ++ 3&&312 	
 -?? 
>"D
 .<<,.1'33 = 	
. O   00`gg# ,^^._Bfg 1 
 	
r3   c                 r   	 t        di |}|j                  dd      }|j                  xs |j                  dd      xs d}t        dd|i|}	|$|j	                  dd|j                         |	|       |:t        |t        j                        r t        |      du r|j                  xs d}
|
}n,|&t        |t        j                        st        |      }n|d}t        | ||	      }|j                  d
d      du }|j                  dd      }| j                  d      rId| v rEd| v rA|j                         }|j                  dd       t!        d| |j                  dd      |d|S |j                  dd      }|!t#        j$                  |t'        |            }nd}|ot(        j+                  | ||	|xs i |j,                  |j.                  |xs t1        |xs dg dddd| z   d      ||t        |t2        t4        f      r|nd||      }|S t7        | |||	|||      S # t8        $ r}|d}~ww xY w)zh
    Retrieves a batch.

    LiteLLM Equivalent of GET https://api.openai.com/v1/batches/{batch_id}
    rV   Nr(   X  r$   rZ   F     @r   r=   r>   r   Tr   zarn:awsz	:bedrock:z:async-invoke/aws_region_namez	us-east-1)r   r   rd   rU   r]   zbedrock/unknownbatch_retrievebatch_retrieve_)rU   messagesstream	call_type
start_timerR   function_id)r   r_   r\   ra   rb   rc   rd   re   r   r)   rU   )r   r$   r"   r\   r   re   r)   r   )r   r*   r)   r   r   r   r+   r,   r-   r   r.   r/   r   r   
startswithcopy_handle_async_invoke_statusr   r   r   r   r   rb   rc   r   r   r   r   rI   )r   r$   r<   r=   r>   r#   r"   rV   r)   r\   r0   r   re   r   async_kwargsrU   r_   rO   rP   s                      r1   r   r     s   p.88;A::!4<
 "))VVZZ8I3-OVSV+ 
 3

 *<< / : : <-$7 =  7EMM2&':;uD"<<.3L"G GU]])KGnG_G"6'!#
 JJ0%8D@	Hd+
 	*x' H, ";;=L.5. ! &

+<k J/ 	   &zz'483OO%&9:O
 #O&,;;! /-%+(11'/// 	$4#4 .#$5$@ 0 $%v5E'FG  / < H2 O
 H 3+)$;
 	
  s%   E)H& ,B'H& H& &	H6/H11H6afterlimit)r8   r9   c                 h  K   	 t        j                         }d|d<   t        t        | ||||fi |}t	        j
                         }	t        |	j                  |      }
|j                  d|
       d{   }t        j                  |      r| d{   }|S |}|S 7 )7 # t        $ r}|d}~ww xY ww)z2
    Async: List your organization's batches.
    Talist_batchesN)
rA   rB   r   list_batchesrD   rE   rF   rG   rH   rI   )r   r   r$   r<   r=   r>   r#   rJ   rK   rL   rM   rN   rO   rP   s                 r1   r   r   ~  s     %%'"& 
 
 &&(#CGGT2"2249JKK}-**H  %H L*
  r   c                 P   	 t        d"i |}t        d"d|i|}|j                  xs9 t        j                  xs' t        j                  xs t        j                  d      }|j                  xs |j                  dd      xs d}	|	:t        |	t        j                        r t        |      du r|	j                  xs d}
|
}	n,|	&t        |	t        j                        st        |	      }	n|	d}	|j                  dd      d	u }|d
k(  r|j                   xsB t        j                   xs0 t        j                  d      xs t        j                  d      xs d}|j"                  xs, t        j"                  xs t        j                  dd      xs d}t$        j'                  || |||||	|j(                        }|S |dk(  r|j                   xs t        j                   xs t+        d      }|j,                  xs t        j,                  xs t+        d      }|j                  xs< t        j                  xs* t        j.                  xs t+        d      xs t+        d      }|j                  di       }||j                  dd       nt+        d       t0        j'                  |||||	|j(                  |      }|S t        j2                  j5                  dj7                  |      d|t        j8                  ddt        j:                  dd             !      # t<        $ r}|d}~ww xY w)#z>
    Lists batches

    List your organization's batches.
    r$   rj   r(   r   NFr   r   Tr8   rf   rg   rh   ri   )re   r   r   rb   rc   rk   r)   rl   r9   rm   rn   ro   rp   r>   rq   rr   )re   rb   rc   rs   r)   rl   r\   zHLiteLLM doesn't support {} for 'list_batch'. Only 'openai' is supported.rz   r{   r|   r   r}   r~   r   r   r   )r   r   rc   r   r   r   r   r)   r*   r+   r,   r-   r   r.   r/   r   rb   rk   r   r   rl   r   rs   r   r   r   r   r   r   r   rI   )r   r   r$   r=   r>   r#   r"   r\   rc   r)   r0   re   rb   rk   rO   rs   rP   s                    r1   r   r     sK   f.88+ 
 3


 ## ++!!+ yy)*	 	 "))VVZZ8I3-OVSV 7EMM2&':;uD"<<.3L"G GU]])KGnG_GJJ6$>	(*  (( /##/99.// 99.// /   ,, ''992D9 	  /;;#!)+77 < 	Hl Y !G+&//g73C3Cg~VfGgH++ 7&&7!"56   '' 3??3$$3 ""893 "/2  ),,\2>J%/6/0-::#!'+77- ; H,  $$44bii' 0 #2!MMFjk 5    s&   F6L 9C>L 8AL 	L%L  L%c                 h  K   	 t        j                         }d|d<   t        t        | ||||fi |}t	        j
                         }t        |j                  |      }	|j                  d|	       d{   }
t        j                  |
      r|
 d{   }|S |
}|S 7 )7 # t        $ r}|d}~ww xY ww)zu
    Async: Cancels a batch.

    LiteLLM Equivalent of POST https://api.openai.com/v1/batches/{batch_id}/cancel
    Tacancel_batchN)
rA   rB   r   cancel_batchrD   rE   rF   rG   rH   rI   r   s                r1   r   r      s     %%'"& 
 
 &&(#CGGT2"2249JKK}-**H  %H L*
  r   c                 p   	 t        d#i |}t        d#d|i|}|j                  xs |j                  dd      xs d}|:t	        |t
        j                        r t        |      du r|j                  xs d}	|	}n,|&t	        |t
        j                        st        |      }n|d}t        | ||      }
|j                  dd      d	u }d}|d
k(  r|j                  xsB t        j                  xs0 t        j                  d      xs t        j                  d      xs d}|j                   xs, t        j                   xs t        j                  dd      xs d}|j"                  xs9 t        j"                  xs' t        j$                  xs t        j                  d      }t&        j)                  ||
|||||j*                        }|S |dk(  r|j                  xs t        j                  xs t-        d      }|j.                  xs t        j.                  xs t-        d      }|j"                  xs< t        j"                  xs* t        j0                  xs t-        d      xs t-        d      }|j                  di       }||j                  dd       nt-        d       t2        j)                  ||||||j*                  |
|      }|S t        j4                  j7                  dj9                  |      d|t        j:                  ddt        j<                  dd       !      "      # t>        $ r}|d}~ww xY w)$zn
    Cancels a batch.

    LiteLLM Equivalent of POST https://api.openai.com/v1/batches/{batch_id}/cancel
    r$   r(   r   NFr   r   r   Tr8   rf   rg   rh   ri   rj   )re   cancel_batch_datarb   rc   rk   r)   rl   r9   rm   rn   ro   rp   r>   rq   rr   )re   rb   rc   rs   r)   rl   r   r\   zWLiteLLM doesn't support {} for 'cancel_batch'. Only 'openai' and 'azure' are supported.rz   r{   r|   r   r}   r~   r   r   r   ) r   r   r)   r*   r+   r,   r-   r   r.   r/   r   r   rb   r   r   r   rk   rc   r   r   r   rl   r   rs   r   r   r   r   r   r   r   rI   )r   r$   r<   r=   r>   r#   r"   r\   r)   r0   _cancel_batch_requestre   rb   rk   rc   rO   rs   rP   s                     r1   r   r   I  so   o.88+ 
 3


 "))VVZZ8I3-OVSV 7EMM2&':;uD"<<.3L"G GU]])KGnG_G 2'!!
 JJ6$>	"&(*(( /##/99.// 99.// /   ,, ''992D9 	   '' /??/%%/ 99-.	  /;;#"7!)+77 < Ht c !G+(( 4##4!"23   ++ 7&&7!"56   '' 3??3$$3 ""893 "/2  ),,\2>J%/6/0-::#!'+77"7- ; 	H.  $$44qxx' 0 #2!MMEij 5    s&   GL% C?L% AL% %	L5.L00L5r   r   c                     	
 ddl 
ddlm  fd	ddl}	
fd}|j                  j                         5 }|j                  |      }|j                         cddd       S # 1 sw Y   yxY w)a  
    Handle async invoke status check for AWS Bedrock.

    Args:
        batch_id: The async invoke ARN
        aws_region_name: AWS region name
        **kwargs: Additional parameters

    Returns:
        dict: Status information including status, output_file_id (S3 URL), etc.
    r   N)BedrockEmbeddingc                  b  K           }  | j                   dd d {   }ddlm}  ||d   d|d   |d   |d   |j                  d	      |d   d
k(  r|j                  d	      nd d|d   dk(  rdnd|d   d
k(  rdndd|d   d   d   |j                  d      |d   d	      }|S 7 w)N)invocation_arnr   rd   r   )r   invocationArnbatchstatus
submitTimelastModifiedTimeendTimefailed   	completed)totalr   r   outputDataConfigs3OutputDataConfigs3UrifailureMessagemodelArn)output_file_idfailure_message	model_arn)	idobjectr   
created_atin_progress_atcompleted_at	failed_atrequest_countsr<   r   )_get_async_invoke_statuslitellm.types.utilsr   r*   )	embedding_handlerstatus_responser   resultr   r   r   r#   rd   s	       r1   _async_get_statusz6_handle_async_invoke_status.<locals>._async_get_status  s    ,. !K 1 J J !
#+#!
 	!
 
 	5/"8,&|4*+=>(,,Y7x(H4 &)))4"1(";{"JQPQ.x8HD!! #22D"E(## $3#6#67G#H,Z8
0 E
s   !B/B-B	B/c                       j                          }  j                  |        	 | j                                | j                          S # | j                          w xY wN)new_event_loopset_event_looprun_until_completeclose)new_loopr   rA   s    r1   run_in_threadz2_handle_async_invoke_status.<locals>.run_in_thread  sO    )7))+x(	../@/BCNNHNNs   A A)rA   $litellm.llms.bedrock.embed.embeddingr   concurrent.futuresfuturesThreadPoolExecutorsubmitr   )r   r   rd   r#   
concurrentr   executorfuturer   r   rA   s   ````    @@@r1   r   r     sY     E' 'V  
			.	.	0H/}} 
1	0	0s   !A**A3)r   )r8   NNN)r8   )NNr8   NNN)NNr8   NNr   )G__doc__rA   rD   r   	functoolsr   typingr   r   r   r   r   r	   r
   r,   r   litellm._loggingr   *litellm.litellm_core_utils.litellm_loggingr   r   "litellm.llms.azure.batches.handlerr   &litellm.llms.custom_httpx.http_handlerr   r   *litellm.llms.custom_httpx.llm_http_handlerr   litellm.llms.openai.openair   &litellm.llms.vertex_ai.batches.handlerr   litellm.secret_managers.mainr   litellm.types.llms.openair   r   r   r   litellm.types.routerr   r   r   r   litellm.utilsr   r   r   r   r   r   r   r   r   r   r/   r2   r@   rC   r   r-   r   boolr   r   intr   r   r   r   r   r   r3   r1   <module>r     s  
   	  G G G   + S > P I 7 J 7  6 :  +, (* 4RH *,  #	()(cN( ( 	(
 (V 
 OW)-.2+/,u~,QR, , !!JK	,
 tCH~&, DcN+, c3h(, , ,^ 
 OW)-.2+/Fu~FQRF F !!JK	F
 tCH~&F DcN+F c3h(F <3\#9::;F FR  OW)-.2+/&& !JK& tCH~&& DcN+	&
 c3h(& & &` OWuu)u 5%--'(u 	u
 2u u !!JKup  OW)-.2+/}} !JK} tCH~&} DcN+	}
 c3h(} <3\#9::;} }@ 6>)-.2+/'C='C=' !!23' tCH~&	'
 DcN+' c3h(' 'T 6>.2+/sC=sC=s !!23s DcN+	s
 c3h(s sp 7?)-.2+/&& !23& tCH~&& DcN+	&
 c3h(& &V 7?)-.2+/|| !23| tCH~&| DcN+	|
 c3h(| 5)CeO,,-|@ 6:II$'IIr3   