
    2iw                    t   d dl m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mZ d dlmZmZmZ d dlmZ ddlmZmZmZ dd	lmZmZmZ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(m)Z) ddl*m+Z+m,Z,m-Z- ddl.m/Z/ ddl0m1Z1m2Z2 ddl3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9 ddl:m;Z;m<Z< ddl=m>Z>m?Z?m@Z@ ddlAmBZBmCZC ddlDmEZE ddlFmGZH ddlImJZK  G d dee4                   ZL G d dee4                   ZM G d dee4                   ZN G d d ee4                   ZO G d! d"ee4                   ZP G d# d$          ZQd-d)ZRd.d,ZSdS )/    )annotationsN)TracebackType)TYPE_CHECKINGAnyGenericCallableIterable	AwaitableAsyncIteratorcast)SelfIteratorassert_never)	from_json   )ParsedChoiceSnapshotParsedChatCompletionSnapshot#ParsedChatCompletionMessageSnapshot)
ChunkEventContentDoneEventRefusalDoneEventContentDeltaEventRefusalDeltaEventLogprobsContentDoneEventLogprobsRefusalDoneEventChatCompletionStreamEventLogprobsContentDeltaEventLogprobsRefusalDeltaEvent"FunctionToolCallArgumentsDoneEvent#FunctionToolCallArgumentsDeltaEvent   )accumulate_delta   )OmitIncExomit)is_givenconsume_sync_iteratorconsume_async_iterator)
model_dump)buildconstruct_type   )ResponseFormatThas_parseable_inputmaybe_parse_contentparse_chat_completionget_input_tool_by_nameparse_function_tool_arguments)StreamAsyncStream)ChatCompletionChunkParsedChatCompletionChatCompletionToolUnionParam)LengthFinishReasonErrorContentFilterFinishReasonError)ChoiceLogprobs)Choice)ResponseFormatc                  r    e 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ed'd            Zd"dZdS )(ChatCompletionStream+  Wrapper over the Chat Completions streaming API that adds helpful
    events such as `content.done`, supports automatically parsing
    responses & tool calls and accumulates a `ChatCompletion` object
    from each individual chunk.

    https://platform.openai.com/docs/api-reference/streaming
    
raw_streamStream[ChatCompletionChunk]response_format2type[ResponseFormatT] | ResponseFormatParam | Omitinput_tools-Iterable[ChatCompletionToolUnionParam] | OmitreturnNonec                   || _         |j        | _        |                                 | _        t          ||          | _        d S NrC   rE   _raw_streamresponse	_response
__stream__	_iteratorChatCompletionStreamState_stateselfrA   rC   rE   s       m/root/.openclaw/workspace/.venv-openai/lib/python3.11/site-packages/openai/lib/streaming/chat/_completions.py__init__zChatCompletionStream.__init__7   @     &#,**/]hiii    *ChatCompletionStreamEvent[ResponseFormatT]c                4    | j                                         S N)rQ   __next__rU   s    rV   r]   zChatCompletionStream.__next__C   s    ~&&(((rY   4Iterator[ChatCompletionStreamEvent[ResponseFormatT]]c              #  &   K   | j         D ]}|V  d S r\   rQ   rU   items     rV   __iter__zChatCompletionStream.__iter__F   s,      N 	 	DJJJJ	 	rY   r   c                    | S r\    r^   s    rV   	__enter__zChatCompletionStream.__enter__J   s    rY   exc_typetype[BaseException] | NoneexcBaseException | Noneexc_tbTracebackType | Nonec                .    |                                   d S r\   closerU   rh   rj   rl   s       rV   __exit__zChatCompletionStream.__exit__M   s     	

rY   c                8    | j                                          dS z
        Close the response and release the connection.

        Automatically called if the response body is read to completion.
        N)rO   rp   r^   s    rV   rp   zChatCompletionStream.closeU   s     	rY   %ParsedChatCompletion[ResponseFormatT]c                \    |                                   | j                                        S )V  Waits until the stream has been read to completion and returns
        the accumulated `ParsedChatCompletion` object.

        If you passed a class type to `.stream()`, the `completion.choices[0].message.parsed`
        property will be the content deserialised into that class, if there was any content returned
        by the API.
        
until_donerS   get_final_completionr^   s    rV   rz   z)ChatCompletionStream.get_final_completion]   s(     	{//111rY   c                $    t          |            | S )*Blocks until the stream has been consumed.)r(   r^   s    rV   ry   zChatCompletionStream.until_doneh   s    d###rY   r   c                    | j         j        S r\   rS   current_completion_snapshotr^   s    rV   r   z0ChatCompletionStream.current_completion_snapshotm       {66rY   c              #     K   | j         D ]5}t          |          s| j                            |          }|D ]}|V  6d S r\   rM   $_is_valid_chat_completion_chunk_weakrS   handle_chunkrU   	sse_eventevents_to_fireevents       rV   rP   zChatCompletionStream.__stream__q   si      ) 	 	I7	BB ![55i@@N'  		 	rY   N)rA   rB   rC   rD   rE   rF   rG   rH   rG   rZ   )rG   r_   rG   r   rh   ri   rj   rk   rl   rm   rG   rH   rG   rH   rG   ru   rG   r   )__name__
__module____qualname____doc__rW   r]   rd   rg   rr   rp   rz   ry   propertyr   rP   rf   rY   rV   r?   r?   .   s         
j 
j 
j 
j) ) ) )            	2 	2 	2 	2   
 7 7 7 X7     rY   r?   c                  *    e Zd ZdZdd
ZddZddZdS )ChatCompletionStreamManageraF  Context manager over a `ChatCompletionStream` that is returned by `.stream()`.

    This context manager ensures the response cannot be leaked if you don't read
    the stream to completion.

    Usage:
    ```py
    with client.chat.completions.stream(...) as stream:
        for event in stream:
            ...
    ```
    api_request)Callable[[], Stream[ChatCompletionChunk]]rC   rD   rE   rF   rG   rH   c               >    d | _         || _        || _        || _        d S r\   )$_ChatCompletionStreamManager__stream)_ChatCompletionStreamManager__api_request-_ChatCompletionStreamManager__response_format)_ChatCompletionStreamManager__input_toolsrU   r   rC   rE   s       rV   rW   z$ChatCompletionStreamManager.__init__   s+     GK(!0(rY   %ChatCompletionStream[ResponseFormatT]c                z    |                                  }t          || j        | j                  | _        | j        S N)rA   rC   rE   )r   r?   r   r   r   rU   rA   s     rV   rg   z%ChatCompletionStreamManager.__enter__   sB    ''))
,! 2*
 
 
 }rY   rh   ri   rj   rk   rl   rm   c                J    | j         | j                                          d S d S r\   )r   rp   rq   s       rV   rr   z$ChatCompletionStreamManager.__exit__   s.     =$M!!!!! %$rY   N)r   r   rC   rD   rE   rF   rG   rH   )rG   r   r   )r   r   r   r   rW   rg   rr   rf   rY   rV   r   r   z   sZ         
) 
) 
) 
)	 	 	 	" " " " " "rY   r   c                  r    e 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ed'd            Zd"dZdS )(AsyncChatCompletionStreamr@   rA    AsyncStream[ChatCompletionChunk]rC   rD   rE   rF   rG   rH   c                   || _         |j        | _        |                                 | _        t          ||          | _        d S rJ   rL   rT   s       rV   rW   z"AsyncChatCompletionStream.__init__   rX   rY   rZ   c                D   K   | j                                          d {V S r\   )rQ   	__anext__r^   s    rV   r   z#AsyncChatCompletionStream.__anext__   s,      ^--/////////rY   9AsyncIterator[ChatCompletionStreamEvent[ResponseFormatT]]c               4   K   | j         2 3 d {V }|W V  6 d S r\   ra   rb   s     rV   	__aiter__z#AsyncChatCompletionStream.__aiter__   sF      . 	 	 	 	 	 	 	$JJJJJ )..s   r   c                
   K   | S r\   rf   r^   s    rV   
__aenter__z$AsyncChatCompletionStream.__aenter__   s      rY   rh   ri   rj   rk   rl   rm   c                >   K   |                                   d {V  d S r\   ro   rq   s       rV   	__aexit__z#AsyncChatCompletionStream.__aexit__   s.       jjllrY   c                H   K   | j                                          d{V  dS rt   )rO   acloser^   s    rV   rp   zAsyncChatCompletionStream.close   s4       n##%%%%%%%%%%%rY   ru   c                l   K   |                                   d{V  | j                                        S )rw   Nrx   r^   s    rV   rz   z.AsyncChatCompletionStream.get_final_completion   s>       oo{//111rY   c                4   K   t          |            d{V  | S )r|   N)r)   r^   s    rV   ry   z$AsyncChatCompletionStream.until_done   s+      $T*********rY   r   c                    | j         j        S r\   r~   r^   s    rV   r   z5AsyncChatCompletionStream.current_completion_snapshot   r   rY   c                  K   | j         2 3 d {V }t          |          s| j                            |          }|D ]}|W V  <6 d S r\   r   r   s       rV   rP   z$AsyncChatCompletionStream.__stream__   s      #/ 	 	 	 	 	 	 	)7	BB ![55i@@N'  	  0//s   AN)rA   r   rC   rD   rE   rF   rG   rH   r   )rG   r   r   r   r   r   r   )r   r   r   r   rW   r   r   r   r   rp   rz   ry   r   r   rP   rf   rY   rV   r   r      s         
j 
j 
j 
j0 0 0 0         & & & &	2 	2 	2 	2   
 7 7 7 X7     rY   r   c                  *    e Zd ZdZdd
ZddZddZdS ) AsyncChatCompletionStreamManageraQ  Context manager over a `AsyncChatCompletionStream` that is returned by `.stream()`.

    This context manager ensures the response cannot be leaked if you don't read
    the stream to completion.

    Usage:
    ```py
    async with client.chat.completions.stream(...) as stream:
        for event in stream:
            ...
    ```
    r   +Awaitable[AsyncStream[ChatCompletionChunk]]rC   rD   rE   rF   rG   rH   c               >    d | _         || _        || _        || _        d S r\   ))_AsyncChatCompletionStreamManager__stream._AsyncChatCompletionStreamManager__api_request2_AsyncChatCompletionStreamManager__response_format._AsyncChatCompletionStreamManager__input_toolsr   s       rV   rW   z)AsyncChatCompletionStreamManager.__init__  s+     LP(!0(rY   *AsyncChatCompletionStream[ResponseFormatT]c                p   K   | j          d {V }t          || j        | j                  | _        | j        S r   )r   r   r   r   r   r   s     rV   r   z+AsyncChatCompletionStreamManager.__aenter__  sO      -------
1! 2*
 
 
 }rY   rh   ri   rj   rk   rl   rm   c                Z   K   | j         !| j                                          d {V  d S d S r\   )r   rp   rq   s       rV   r   z*AsyncChatCompletionStreamManager.__aexit__  sD       =$-%%''''''''''' %$rY   N)r   r   rC   rD   rE   rF   rG   rH   )rG   r   r   )r   r   r   r   rW   r   r   rf   rY   rV   r   r      sZ         
) 
) 
) 
)	 	 	 	( ( ( ( ( (rY   r   c                  b    e Zd ZdZeeddd	ZddZedd            ZddZ	ddZ
d dZd!dZdS )"rR   aS  Helper class for manually accumulating `ChatCompletionChunk`s into a final `ChatCompletion` object.

    This is useful in cases where you can't always use the `.stream()` method, e.g.

    ```py
    from openai.lib.streaming.chat import ChatCompletionStreamState

    state = ChatCompletionStreamState()

    stream = client.chat.completions.create(..., stream=True)
    for chunk in response:
        state.handle_chunk(chunk)

        # can also access the accumulated `ChatCompletion` mid-stream
        state.current_completion_snapshot

    print(state.get_final_completion())
    ```
    )rE   rC   rE   rF   rC   rD   rG   rH   c                   d | _         g | _        t          |          rd |D             ng | _        || _        t          j        |          r|nt          | _        d S )Nc                    g | ]}|S rf   rf   ).0tools     rV   
<listcomp>z6ChatCompletionStreamState.__init__.<locals>.<listcomp>B  s    :::dT:::rY   )	7_ChatCompletionStreamState__current_completion_snapshot/_ChatCompletionStreamState__choice_event_statesr'   _input_tools_response_formatinspectisclassr&   _rich_response_format)rU   rE   rC   s      rV   rW   z"ChatCompletionStreamState.__init__9  sk     SW*=?">F{>S>S[::k::::Y[ /EL_UdEeEe2o//ko"""rY   ru   c                D    t          | j        | j        | j                  S )zParse the final completion object.

        Note this does not provide any guarantees that the stream has actually finished, you must
        only call this method when the stream is finished.
        )chat_completionrC   rE   )r1   r   r   r   r^   s    rV   rz   z.ChatCompletionStreamState.get_final_completionF  s-     % < 6)
 
 
 	
rY   r   c                "    | j         J | j         S r\   )r   r^   s    rV   r   z5ChatCompletionStreamState.current_completion_snapshotR  s    1===11rY   chunkr6   4Iterable[ChatCompletionStreamEvent[ResponseFormatT]]c                n    |                      |          | _        |                     || j                  S )zTAccumulate a new chunk into the snapshot and returns an iterable of events to yield.)r   completion_snapshot)_accumulate_chunkr   _build_events)rU   r   s     rV   r   z&ChatCompletionStreamState.handle_chunkW  s>    -1-C-CE-J-J*!! $ B " 
 
 	
rY   choiceChoiceChunkChoiceEventStatec                    	 | j         |j                 S # t          $ r4 t          | j                  }| j                             |           |cY S w xY w)N)rE   )r   index
IndexErrorr   r   append)rU   r   choice_states      rV   _get_choice_statez+ChatCompletionStreamState._get_choice_state`  sh    	 -fl;; 	  	  	 +8IJJJL&--l;;;	 s    ;AAc                @	   | j         }|t          |          S |j        D ]d}	 |j        |j                 }|j        j        pg }t          t          t          t          t          t          dt          |j        t          t          dd t          |j        j        pg           D             d                              t          d|j                                                                                |_        t          |          D ]^\  }}|j        j        pg |         }|j        dk    r$|j        dk    sJ |j        j        |j        _        Ht$          rt'          |           _n# t(          $ ry t          t*          t          t*          i |
                    ddh	          d
|j                                        i                    }|j                            |           Y nw xY w|j        r[|j        |_        t1          | j        | j                  r4|j        dk    rt7          |          |j        dk    rt9                      |j        j        rq|j        j        set?          | j                   rQ|j        j        !                                r3tE          tG          |j        j        d          d          |j        _$        |j        j        pg D ]}	|j        j        pg |	j                 }
|
j        dk    rtK          | j        |
j        j&                  }|rh|'                    di           '                    d          r?|
j        j(        r3tE          tG          |
j        j(        d          d          |
j        _        t$          rt'          |
           |j)        |j)        2tU          tV          |j)        j        |j)        j                  |_)        |j)        j        rA|j)        j        g |j)        _        |j)        j        ,                    |j)        j                   |j)        j        rA|j)        j        g |j)        _        |j)        j        ,                    |j)        j                   f|j-        |_-        |j.        |_.        |S )Nzdict[object, object]Tc                "    i | ]\  }}|d ddiiS )functionparsed_argumentsTrf   )r   idx_s      rV   
<dictcomp>z?ChatCompletionStreamState._accumulate_chunk.<locals>.<dictcomp>  s:     ;. ;. ;.4:C 14jCUW[B\5];. ;. ;.rY   )parsed
tool_calls)excludetype_valuer   deltaexclude_unsetr   messagerK   length)
completioncontent_filterzutf-8)partial_mode)rE   namestrict)contentrefusal)/r   $_convert_initial_chunk_into_snapshotchoicesr   r   r   r   r   r,   r"   r*   r%   	enumerater   to_dicttyper   r   r   r   r   r   r   finish_reasonr/   r   r   r9   r:   r   r   r'   r   lstripr   bytesr   r2   r   get	argumentslogprobsr+   r;   extendusagesystem_fingerprint)rU   r   r   r   choice_snapshotprevious_tool_calls
tool_index	prev_toolnew_tooltool_call_chunktool_call_snapshot
input_tools               rV   r   z+ChatCompletionStreamState._accumulate_chunkh  s!   "@&7>>>m x	Y x	YF7D"5"=fl"K&5&=&H&NB#*.7"A.  6 *$3$; -1(-6:;. ;.>GH_HjHpnp>q>q;. ;. ;.)* )*
-& 
-&!" !" !" ( !!79M9M9O9OPP+   + +'@ .77J-K-K 0 0)J	 / 7 B Hb*UH ~33'}
::::=F=O=`)::& 0$Y///0  D D D"&("2$//dWI/VV%v|';';'='=   	# 	# $+22?CCCCCD # 
?060D-&t7LZ^Zklll ?+x77 6ATUUUU+/???<>>>  '/
'/7
 T788

 $+3::<<
 2;/197CC!%2 2 2'.
 $*<#:#@b 5 5&5&=&H&NBP_Pe%f"%*j88!7$($5<N<W<\" " "J
 #&NN:r::>>xHH /7A
 HQ!"4"="GQQ)-H H H*3D # 5 !3444*"+3/4& & 7 & 70 0 0O,, . Y*3;C?AO4<'08??@WXXX. Y*3;C?AO4<'08??@WXXX$)K!161I.""s   E
E//B G21G2r   0list[ChatCompletionStreamEvent[ResponseFormatT]]c                  g }|                     t          t          d||                     |j        D ]}|                     |          }|j        |j                 }|j        j        V|j        j        J|                     t          t          d|j        j        |j        j        |j        j
                             |j        j        K|j        j        ?|                     t          t          d|j        j        |j        j                             |j        j        r|j        j        }|J |j        j        D ]}||j                 }	|	j        dk    rg|j        J |                     t          t           d|	j        j        |j        |	j        j        |	j        j        |j        j        pd	
                     t(          rt+          |	           |j        |j        |j        j        rK|j        j        r?|                     t          t.          d|j        j        |j        j                             |j        j        rK|j        j        r?|                     t          t0          d|j        j        |j        j                             |                    |                    ||| j                             |S )Nr   )r   r   snapshotzcontent.delta)r   r   r  r   zrefusal.delta)r   r   r  r   z#tool_calls.function.arguments.delta )r   r   r   r  r   arguments_deltazlogprobs.content.delta)r   r   r  zlogprobs.refusal.delta)r   r   r  )choice_chunkr  rC   )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  get_done_eventsr   )
rU   r   r   r   r   r   r  r   tool_call_delta	tool_calls
             rV   r   z'ChatCompletionStreamState._build_events  s    LN*7%BUVVV	
 	
 	
 m K	 K	F11&99L19&,GO|#/O4K4S4_%%),$l2!0!8!@.6=     |#/O4K4S4_%%),$l2!0!8!@	     |& 0,4?
!---'-|'> 0 0O *?+@ AI ~33.7CCC&--! C%J%.%7%<&5&;*3*<*F1:1C1T0?0H0R0XVX  
 
 
 
 ' 0$Y///*/G/S?* /G/O "))5!9$*O$;%4%=%E	     ?* /G/O "))5!9$*O$;%4%=%E	     !!,,!'$3$($9 -      rY   N)rE   rF   rC   rD   rG   rH   r   r   )r   r6   rG   r   )r   r   rG   r   r   r6   rG   r   )r   r6   r   r   rG   r  )r   r   r   r   r&   rW   rz   r   r   r   r   r   r   rf   rY   rV   rR   rR   $  s         . FJNR	p p p p p p

 

 

 

 2 2 2 X2
 
 
 
       C# C# C# C#JY Y Y Y Y YrY   rR   c                  .    e Zd ZddZddZddZddZdS )r   rE   "list[ChatCompletionToolUnionParam]rG   rH   c                   || _         d| _        d| _        d| _        d| _        t                      | _        d | _        d S )NF)r   _content_done_refusal_done_logprobs_content_done_logprobs_refusal_doneset_done_tool_calls*_ChoiceEventState__current_tool_call_index)rU   rE   s     rV   rW   zChoiceEventState.__init__J  sD    '""&+#&+#*-%%59&&&rY   r  r   r  r   rC   rD   r  c                  g }|j         r\|                    |                     ||                     | j        +| j        | j        vr|                     ||| j                   |j        j        pg D ]l}| j        |j        k    rN|                    |                     ||                     | j        |                     ||| j                   |j        | _        m|S )N)r  rC   )r   r  r	  )	r   r  _content_done_eventsr"  r!  _add_tool_done_eventr   r   r   )rU   r  r  rC   r   r  s         rV   r  z ChoiceEventState.get_done_eventsT  s.    LN( 	!!))/[j)kk  
 .:2$:OOO))#1$3#= *    &+6<" 	= 	=I-@@%%--o_n-oo   1=--'5(7#'#A .    .7_D**rY   c                  g }|j         j        r| j        sd| _        t          ||j                   }||j         _        |                    t          t          dt          t          t                              d|j         j        |                     |j         j
        B| j        s;d| _        |                    t          t          d|j         j
                             |j        N|j        j        B| j        s;d| _        |                    t          t          d|j        j        	                     |j        N|j        j
        B| j        s;d| _        |                    t          t"          d
|j        j
                             |S )NT)rC   r   z'type[ContentDoneEvent[ResponseFormatT]]zcontent.done)r   r   r   zrefusal.done)r   r   zlogprobs.content.done)r   r   zlogprobs.refusal.done)r   r   r  r0   r   r   r+   r   r   r   r   r  r   r  r  r   r  r   )rU   r  rC   r   r   s        rV   r$  z%ChoiceEventState._content_done_events}  s    LN"* 	43E 	!%D( /'/  F .4O#*!! AS"233  (+3;!     "*6t?Q6!%D!!&^_E\Edeee  
 $0(0</ = +/D'!!.5LVeVnVvwww  
 $0(0</ = +/D'!!.5LVeVnVvwww   rY   r   r	  intc          
        || j         v rd S | j                             |           |j        j        J |j        j        |         }|j        dk    rjt          | j        |j                  }||j        _        |	                    t          t          d||j        j        |j        j        |                     d S t          rt          |           d S d S )Nr   )rE   r   z"tool_calls.function.arguments.done)r   r   r   r  r   )r!  addr   r   r   r3   r   r   r   r   r+   r   r   r  r   r   )rU   r   r  r	  r  r   s         rV   r%  z%ChoiceEventState._add_tool_done_event  s
    ...F!!*---&1===,4?
K"j00< -8J8S      <L'8!!6=$+4909C%5  	 	 	 	 	  	-+,,,,,	- 	-rY   N)rE   r  rG   rH   )r  r   r  r   rC   rD   rG   r  )r  r   rC   rD   rG   r  )r   r  r  r   r	  r'  rG   rH   )r   r   r   rW   r  r$  r%  rf   rY   rV   r   r   I  sf        : : : :' ' ' 'R> > > >@$- $- $- $- $- $-rY   r   r   r6   rG   r   c           	     F   |                                  }t          d|d                   }| j        D ]?}i |                    ddh          d|j                                         i||j        <   @t          t          t          t          dd i|dd	i
                    S )Nzlist[object]r   Tr   r   r   r  objectzchat.completionr   )r   r   r   r*   r   r   r   r,   )r   datar   r   s       rV   r   r     s    ==??D>4	?33G- 
 
!
dWIFF!
v|++--!
 !

 $.$d + 	
 	
 	

 
 
rY   r   boolc                    | j         dk    S )Nzchat.completion.chunk)r+  )r   s    rV   r   r     s     666rY   r  )r   r6   rG   r-  )T
__future__r   r   typesr   typingr   r   r   r   r	   r
   r   r   typing_extensionsr   r   r   jiterr   _typesr   r   r   _eventsr   r   r   r   r   r   r   r   r   r   r   r    _deltasr"   r$   r%   r&   _utilsr'   r(   r)   _compatr*   _modelsr+   r,   _parsingr.   r/   r0   r1   r2   r3   
_streamingr4   r5   
types.chatr6   r7   r8   _exceptionsr9   r:   types.chat.chat_completionr;    types.chat.chat_completion_chunkr<   r   #types.chat.completion_create_paramsr=   ResponseFormatParamr?   r   r   r   rR   r   r   r   rf   rY   rV   <module>rB     s   " " " " " "        b b b b b b b b b b b b b b b b b b b b : : : : : : : : : :       k k k k k k k k k k                            ' & & & & & ( ( ( ( ( ( ( ( ( ( N N N N N N N N N N " " " " " " - - - - - - - -                / . . . . . . . b b b b b b b b b b S S S S S S S S 9 9 9 9 9 9 F F F F F F Y Y Y Y Y YI I I I I7?3 I I IX," ," ," ," ,"'/": ," ," ,"^I I I I I 8 I I IX,( ,( ,( ,( ,(w'? ,( ,( ,(^b b b b b 8 b b bJ	X- X- X- X- X- X- X- X-v   .7 7 7 7 7 7rY   