
    -jX                       d dl mZ d dlZd dlZd dlmZ d dlmZm	Z	 d dl
Zd dlmZ d dlmZ 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 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' d dl(m)Z)  ej*        e+          Z,e G d d                      Z-ej.        e/e-e/f         Z0 G d de          Z1e G d d                      Z2e G d de2                      Z3e G d de2                      Z4e G d de4                      Z5e G d de4                      Z6e G d de4                      Z7 e3            Z8 e5            Z9 e6            Z: e7            Z;dS )    )annotationsN)abstractmethod)	dataclassfield)	BaseModel)MaxRetriesExceeded)BaseRagasLLM)json_loader)Prompt)	RunConfig)DocumentStoreNode)EvolutionFilter
NodeFilterQuestionFilter)compress_question_promptconditional_question_promptfind_relevant_context_promptmulti_context_question_promptquestion_answer_promptquestion_rewrite_promptreasoning_question_promptseed_question_prompt)rngc                  <    e Zd ZU ded<    ee          Zded<   dS )CurrentNodesr   	root_nodedefault_factoryzt.List[Node]nodesN)__name__
__module____qualname____annotations__r   listr         b/lsinfo/ai/hellotax_ai/base_platform/venv/lib/python3.11/site-packages/ragas/testset/evolutions.pyr   r   !   s9         OOO%555E555555r'   r   c                  P    e Zd ZU ded<   ded<   ej        Zded<   ded<   ded	<   d
S )DataRowstrquestionzt.List[str]contextszt.Union[str, float]ground_truthevolution_typezt.List[dict]metadataN)r!   r"   r#   r$   npnanr.   r&   r'   r(   r*   r*   +   sR         MMM(*L....r'   r*   c                  |   e Zd ZU  ej        ed          Zded<   dZded<   dZ	ded<   dZ
ded	<    ed
           Zded<    ed           Zded<    ed           Zded<   dZded<   dZded<   ed:d            Zd;d<dZd=d!Z	 d>d?d&Zd@d*Zd+ ZdAd-ZdBd/ZedCd0            Zd1 ZdDd3ZdEdFd8ZdEdGd9ZdS )H	EvolutionNr	   generator_llmzt.Optional[DocumentStore]docstorezt.Optional[NodeFilter]node_filterzt.Optional[QuestionFilter]question_filterc                     t           S N)r   r&   r'   r(   <lambda>zEvolution.<lambda>:   s     6 r'   r   r   r   c                     t           S r:   )r   r&   r'   r(   r;   zEvolution.<lambda>=   s     < r'   r   c                     t           S r:   )r   r&   r'   r(   r;   zEvolution.<lambda>@   s     7 r'   rewrite_invalid_question_prompt   int	max_triesTboolis_asyncr    r   returnr   c                   t          dd                    d | j        D                       d | j        D                       }| j        d         j        t	          | j        d         j                  nd }|rRt          j        d | j        D                                           d|          }t          j        |d	          |_        |S )
Nmerged
c              3  $   K   | ]}|j         V  d S r:   page_content.0ns     r(   	<genexpr>z(Evolution.merge_nodes.<locals>.<genexpr>L   s$      "G"Ga1>"G"G"G"G"G"Gr'   c                &    g | ]}|j         D ]}|S r&   )
keyphrases)rL   rM   phrases      r(   
<listcomp>z)Evolution.merge_nodes.<locals>.<listcomp>M   s'    OOO1!,OOOOOOr'   )doc_idrJ   rP   r   c                    g | ]	}|j         
S r&   )	embeddingrK   s     r(   rR   z)Evolution.merge_nodes.<locals>.<listcomp>V   s    'I'I'I'I'I'Ir'   )axis)	r   joinr    rU   lenr1   arrayreshapeaverage)r    new_node	embed_dimnode_embeddingss       r(   merge_nodeszEvolution.merge_nodesE   s    
 "G"G5;"G"G"GGGOOOOO
 
 
 {1~'3 A())) 	
  	E h'I'IU['I'I'IJJRRI O "$O!!D!D!DHr'   
run_configt.Optional[RunConfig]c                ^    || _         |t                      }|                     |           d S r:   )rC   r   set_run_config)selfrC   ra   s      r(   initzEvolution.init\   s2     "JJ'''''r'   r   c                   | j         r| j                             |           | j        r| j                            |           | j        r| j                            |           | j        r| j                            |           d S d S r:   )r6   rd   r5   r7   r8   )re   ra   s     r(   rd   zEvolution.set_run_configb   s    = 	5M((444 	:--j999 	8++J777 	< //
;;;;;	< 	<r'   current_triescurrent_nodesupdate_countEvolutionOutputc                   K   |r|dz  }t                               d|           || j        k    rt          |           |                     ||           d {V S )N   zretrying evolution: %s times)loggerinforA   r   _aevolve)re   rh   ri   rj   s       r(   aretry_evolvezEvolution.aretry_evolvel   sp        	QM2MBBB4>))$T***]]=-@@@@@@@@@r'   promptr,   r+   c                   K   | j         
J d            | j                             |                    |          | j                   d {V }|j        d         d         j                                        S )Ngenerator_llm cannot be None)r,   rr   rC   r   )r5   generateformatrC   generationstextstrip)re   rr   r,   resultss       r(   _transform_questionzEvolution._transform_questionz   s      !--/M---*33==(=33dm 4 
 
 
 
 
 
 
 
 "1%a(-33555r'   c                    | j         
J d            | j                             d          d         }t          ||g          S )Ndocstore cannot be Nonerm   kr   r   r    )r6   get_random_nodesr   )re   r]   s     r(   _get_new_random_nodezEvolution._get_new_random_node   sK    }((*C(((=11A166q9hxjAAAAr'   r*   c                   K   d}|                      ||           d {V \  }}}|                     |||           d {V S )Nr   )r,   ri   r/   )rp   generate_datarow)re   ri   rh   evolved_questionr/   s        r(   evolvezEvolution.evolve   s      
 --}========		
 **%') + 
 
 
 
 
 
 
 
 	
r'   feedbackc                z  K   |j         j        }||j                            d|           ||_         | j                            ||                     |          j        |          }| j        	                    || j
                   d{V }|j        d         d         j                                        }||fS )zF
        if the question is invalid, get more nodes and retry
        Nr   )r,   contextr   ru   )r   prevr    insertr>   rw   r`   rJ   r5   rv   rC   rx   ry   rz   )re   r,   ri   r   	prev_noderr   r{   s          r(   fix_invalid_questionzEvolution.fix_invalid_question   s       "+0	 &&q)444&/M#9@@!((77D! A  F
 !.77 8        G *1-a05;;==H&&r'   c                
   K   d S r:   r&   )re   rh   ri   s      r(   rp   zEvolution._aevolve   s       	r'   c                
   K   d S r:   r&   )re   r,   s     r(   filter_and_retryzEvolution.filter_and_retry   s      r'   r/   c                  K   | j         
J d            d t          j                  D             }| j                             | j                            ||                     d {V }t          j        |j        d         d         j	        
                                | j                    d {V }t          |t                    r|                    dd           nd }|t          j        j                  }n)fd	|D             }	|	rt          |	d         |	          n}|                     |          }
| j                             | j                            ||
j        
                     d {V }t          j        |j        d         d         j	        
                                | j                    d {V }t          |t                    r|ni }t&                              d|           |                    d          dk    rt*          j        n|                    dt*          j                  }t/          |
                    d          d |j        D             ||d |j        D                       S )Nrt   c                2    g | ]\  }}|d z    d|j          S )rm   	rI   )rL   irM   s      r(   rR   z.Evolution.generate_datarow.<locals>.<listcomp>   s=     
 
 
+/1aqs&&an&&
 
 
r'   )r,   r-   rr   r   )llmrelevant_contextsr   c                f    g | ]-}|d z
  t          j                  k     j        |d z
           .S )rm   )rY   r    )rL   r   ri   s     r(   rR   z.Evolution.generate_datarow.<locals>.<listcomp>   sI       q53}23333 #AE*333r'   r,   r   zanswer generated: %sverdictz-1answer"c                    g | ]	}|j         
S r&   rI   rK   s     r(   rR   z.Evolution.generate_datarow.<locals>.<listcomp>   s    EEEanEEEr'   c                    g | ]	}|j         
S r&   )r0   rK   s     r(   rR   z.Evolution.generate_datarow.<locals>.<listcomp>   s    AAAQajAAAr'   )r,   r-   r.   r/   r0   )r5   	enumerater    rv   r   rw   r
   	safe_loadrx   ry   rz   
isinstancedictgetr   r   r`   r   rJ   rn   debugr1   r2   r*   )re   r,   ri   r/   node_contentr{   relevant_contexts_resultrelevant_context_indicesrelevant_contextselected_nodesmerged_nodesr   s     `         r(   r   zEvolution.generate_datarow   s8      !--/M---
 
3<]=P3Q3Q
 
 
 *334;;!L <   4 
 
 
 
 
 
 
 

 *5)>"1%*00228J*
 *
 *
 $
 $
 $
 $
 $
 $
 
 2D99$(()<dCCC 	!
 $++'19L        1  N "#~a'8OOOO"  ''(899*33.55!<+D 6   4 
 
 
 
 
 
 
 

 #,"1%*0022D4F
 
 
 
 
 
 
 
 &fd33;+V444jj++t33BFFHbf9U9U 	 ^^C((EE.>.DEEE)AA*:*@AAA
 
 
 	
r'   language	cache_dirt.Optional[str]Nonec                   | j         
J d            | j        
J d            | j                            || j        |          | _        | j                            || j        |          | _        | j                            || j        |          | _        | j                             ||           | j                            ||           dS )z;
        Adapt the filter to a different language.
        Nnode filter cannot be Nonequestion_filter cannot be None)r7   r8   r   adaptr5   r   r>   )re   r   r   s      r(   r   zEvolution.adapt   s     ++-I+++#//1Q///&*&A&G&Gd()'
 '
# -1,M,S,Sd()-
 -
) 066$,i  	,
 	x333""8Y77777r'   c                   | j         
J d            | j        
J d            | j                            |           | j                            |           | j                             |           | j                            |           dS )z4
        Save the filter prompts to a path.
        Nr   r   )r7   r8   r   saver   )re   r   s     r(   r   zEvolution.save	  s     ++-I+++#//1Q///#((333)..y999i(((!!),,,,,r'   )r    r   rD   r   TNrC   rB   ra   rb   )ra   r   )T)rh   r@   ri   r   rj   rB   rD   rk   )rr   r   r,   r+   rD   r+   )ri   r   rD   r*   )r,   r+   ri   r   r   r+   rh   r@   ri   r   rD   rk   )r,   r+   ri   r   r/   r+   r:   r   r+   r   r   rD   r   r   r   rD   r   ) r!   r"   r#   tcastr	   r5   r$   r6   r7   r8   r   r   r   r>   rA   rC   staticmethodr`   rf   rd   rq   r|   r   r   r   r   rp   r   r   r   r   r&   r'   r(   r4   r4   3   sU        "(!&t"<"<M<<<<*.H....*.K....26O6666%*U66& & &     ,15<<, , ,      /4e77/ / /#     IH   \,( ( ( ( (< < < < "	A A A A A6 6 6 6B B B

 
 
 
' ' ' ',    ^
  =
 =
 =
 =
~8 8 8 8 8*	- 	- 	- 	- 	- 	- 	-r'   r4   c                  d     e Zd ZU  ed           Zded<   ddZd Zdd fdZdd fdZ	 xZ
S )SimpleEvolutionc                     t           S r:   )r   r&   r'   r(   r;   zSimpleEvolution.<lambda>  s    AU r'   r   r   r   rh   r@   ri   r   rD   rk   c           
     h  K   | j         
J d            | j        
J d            | j        
J d            | j        
J d            |                     |          }| j                            |           d {V }|d         s2|                                 }|                     ||d           d {V S t          	                    d|j
                   | j                            | j                            |j        t          j        t#          j        |j
                  d	
          d                              d {V }|j        d         d         j        }t                              d|           | j                            |           d {V \  }}|s|                     |||           d {V \  }}t                              d|           | j                            |           d {V \  }}	|s0|                                 }|                     ||           d {V S ||dfS )Nr~   r   rt   r   scoreF)rj   zkeyphrases in merged node: %srm   )sizer   )r   	keyphraser   zseed question generated: %srewritten question: %ssimple)r6   r7   r5   r8   r`   filterr   rq   rn   r   rP   rv   r   rw   rJ   r   choicer1   rZ   rx   ry   ro   r   )
re   rh   ri   merged_nodepassedr{   seed_questionis_valid_questionr   _s
             r(   rp   zSimpleEvolution._aevolve  s      }((*C(((++-I+++!--/M---#//1Q///&&}55'..{;;;;;;;;g 	 5577M++}5 ,          	4k6LMMM*33,33#0*RXk.D%E%EANNNqQ 4   4 
 
 
 
 
 
 
 
  +A.q161=AAA,0,@,G,G,V,V&V&V&V&V&V&V#8  
	N151J1J}h2 2 , , , , , ,(M= KK0-@@@)-)=)D)D])S)S#S#S#S#S#S#S q$ N $ 9 9 ; ;!//}MMMMMMMMMmX55r'   c                4    t          | j        j                  S r:   hash	__class__r!   re   s    r(   __hash__zSimpleEvolution.__hash__B      DN+,,,r'   Nr   r+   r   r   r   c                    t                                          ||           | j                            || j        |          | _        d S r:   )superr   r   r5   re   r   r   r   s      r(   r   zSimpleEvolution.adaptE  sF    h	***$($=$C$Cd()%
 %
!!!r'   c                ~    t                                          |           | j                            |           d S r:   )r   r   r   re   r   r   s     r(   r   zSimpleEvolution.saveK  s6    Y!&&y11111r'   r   r:   r   r   )r!   r"   r#   r   r   r$   rp   r   r   r   __classcell__r   s   @r(   r   r     s         #(59U9U#V#V#VVVVV'6 '6 '6 '6R- - -
 
 
 
 
 
 
2 2 2 2 2 2 2 2 2 2 2r'   r   c                       e Zd ZU  edd          Zded<    edd          Zded<    ed 	          Zd
ed<   d d! fdZd"dZ	d#d$ fdZ
d#d% fdZ xZS )&ComplexEvolutionNF)defaultreprzt.Optional[SimpleEvolution]sezt.Optional[EvolutionFilter]evolution_filterc                     t           S r:   )r   r&   r'   r(   r;   zComplexEvolution.<lambda>U  s     8 r'   r   r   r   TrC   rB   ra   rb   c                   |t                      }t                                          ||           | j        ,t	          | j        | j        | j        | j                  | _        | j        
J d            | j	        t          | j        j                  | _	        | j                            |           | j	                            |           d S )N)rC   ra   )r5   r6   r7   r8   r   )r   r   rf   r   r   r5   r6   r7   r8   r   r   r   rd   )re   rC   ra   r   s      r(   rf   zComplexEvolution.initX  s    "Jh:>>>7?%"0 , $ 4	  DG ++-I+++ ($3D4D4H$I$ID! 	z***,,Z88888r'   rh   r@   ri   r   question_promptc                *  K   | j         
J d            | j        
J d            | j        
J d            | j                            ||           d {V \  }}}t                              d| j        j        |           |                     |          }| j         	                    |
                    ||j                             d {V }|j        d         d         j                                        }| j                            |           d {V \  }	}
|	s|                     |||
           d {V \  }}t                              d|           | j                            |           d {V \  }	}|	s5| j                                        }|                     ||           d {V S |                     | j        |	           d {V }t                              d
| j        j        |           | j        
J d            | j                            ||           d {V rb| j                                        }t                              dt/          |j                             |                     ||           d {V S ||fS )Nrt   r   simple evolution cannot be Nonez"[%s] simple question generated: %sr   r   r   r   rr   r,   z[%s] question compressed: %sevolution filter cannot be Nonez)evolution_filter failed, retrying with %s)r5   r8   r   rp   rn   r   r   r!   r`   rv   rw   rJ   rx   ry   rz   r   r   ro   r   rq   r|   r   r   rY   r    )re   rh   ri   r   simple_questionr   r   resultreasoning_questionr   r   compressed_questions               r(   _acomplex_evolutionz$ComplexEvolution._acomplex_evolutionn  s      !--/M---#//1Q///w""$E"""26'2B2B=3
 3
 -
 -
 -
 -
 -
 -
) 	0N#	
 	
 	
 &&}55)22"))(+2J *   3 
 
 
 
 
 
 
 

 $/215:@@BB,0,@,G,G-
 -
 '
 '
 '
 '
 '
 '
#8 ! 
	N6:6O6O"M87 7 1 1 1 1 1 1- KK02DEEE)-)=)D)DEW)X)X#X#X#X#X#X#X q$ N $ < < > >!//}MMMMMMMMM %)$<$<0;M %= %
 %
 
 
 
 
 
 
 	*N#	
 	
 	
 $002S000&--o?RSSSSSSSS 	J G88::MLL;SAT=U=U   ++M=IIIIIIIII"M11r'   r   r+   r   r   rD   r   c                H   | j         
J d            | j        
J d            t                                          ||           | j                            ||           | j                            || j        |          | _        | j                             ||           d S Nr   r   )r   r   r   r   r   r5   r   s      r(   r   zComplexEvolution.adapt  s    $002S000w""$E"""h	***h	***(,(E(K(Kd())
 )
% 	##Hi88888r'   c                *   | j         
J d            | j        
J d            t                                          |           | j                            |           | j                             |           | j                            |           d S r   )r   r   r   r   r   r   s     r(   r   zComplexEvolution.save  s    $002S000w""$E"""YY""9---%**955555r'   r   r   )rh   r@   ri   r   r   r   r:   r   r   )r!   r"   r#   r   r   r$   r   r   rf   r   r   r   r   r   s   @r(   r   r   P  s        &+eDu&E&E&EBEEEE49E$U4S4S4SSSSS',u88( ( (    9 9 9 9 9 9 9,92 92 92 92v	9 	9 	9 	9 	9 	9 	96 6 6 6 6 6 6 6 6 6 6r'   r   c                  d     e Zd ZU  ed           Zded<   ddZd Zdd fdZdd fdZ	 xZ
S )MultiContextEvolutionc                     t           S r:   )r   r&   r'   r(   r;   zMultiContextEvolution.<lambda>  s     = r'   r   r   r   rh   r@   ri   r   rD   rk   c                  K   | j         
J d            | j        
J d            | j        
J d            | j        
J d            | j                            ||           d {V \  }}}t
                              d|           |                     |          }| j                             |d          }|sN| j         	                    d          }t          |d	         |
          }|                     ||           d {V S t          |d	         t                    s
J d            |j                            |d	                    | j                            ||j        |d	         j                  }| j                            |           d {V }	|	j        d	         d	         j                                        }
t
                              d|
           | j                            |
           d {V \  }}|s|                     |
||           d {V \  }
}t
                              d|
           | j                            |
           d {V \  }}|s5| j                                        }|                     ||           d {V S |                     | j        |
           d {V }t
                              d|           | j        
J d            | j                            ||           d {V r5| j                                        }|                     ||           d {V S ||dfS )Nr~   rt   r   r   z5[MultiContextEvolution] simple question generated: %srm   )top_kr   r   r   zsimilar_node must be a Node)r,   context1context2r   z;[MultiContextEvolution] multicontext question generated: %sr   r   z<[MultiContextEvolution] multicontext question compressed: %sr   multi_context)r6   r5   r8   r   rp   rn   r   r`   get_similarr   r   rq   r   r   r    appendr   rw   rJ   rv   rx   ry   rz   r   r   ro   r   r|   r   r   )re   rh   ri   r   r   r   similar_nodenew_random_nodesrr   r{   r,   r   r   r   s                 r(   rp   zMultiContextEvolution._aevolve  s)      }((*C(((!--/M---#//1Q///w""$E"""26'2B2B=3
 3
 -
 -
 -
 -
 -
 -
) 	C_	
 	
 	
 &&}55}00A0FF 		8#}===BB(*1-5E  M ++M=IIIIIIIIIl1ot44SS6SSS4&&|A7773::$ -!!_1 ; 
 

 *3363BBBBBBBB&q)!,17799I8	
 	
 	
 -1,@,G,G,Q,Q&Q&Q&Q&Q&Q&Q#8  	N -1,E,E-- - ' ' ' ' ' '#Hm KK0(;;;)-)=)D)DX)N)N#N#N#N#N#N#N q$ N $ < < > >!//}MMMMMMMMM %)$<$<08 %= %
 %
 
 
 
 
 
 
 	J	
 	
 	

 $002S000&--o?RSSSSSSSS 	J G88::M++M=IIIIIIIII"M?BBr'   c                4    t          | j        j                  S r:   r   r   s    r(   r   zMultiContextEvolution.__hash__
  r   r'   Nr   r+   r   r   r   c                    t                                          ||           | j                            || j        |          | _        d S r:   )r   r   r   r5   r   s      r(   r   zMultiContextEvolution.adapt  sF    h	***-1-O-U-Ud().
 .
***r'   c                ~    t                                          |           | j                            |           d S r:   )r   r   r   r   s     r(   r   zMultiContextEvolution.save  s6    Y*//	:::::r'   r   r:   r   r   )r!   r"   r#   r   r   r$   rp   r   r   r   r   r   s   @r(   r   r     s         ,1E==- - -!    DC DC DC DCL- - -
 
 
 
 
 
 
; ; ; ; ; ; ; ; ; ; ;r'   r   c                  d     e Zd ZU  ed           Zded<   ddZd Zdd fdZdd fdZ	 xZ
S )ReasoningEvolutionc                     t           S r:   )r   r&   r'   r(   r;   zReasoningEvolution.<lambda>  s     9 r'   r   r   r   rh   r@   ri   r   rD   rk   c                l   K   |                      ||| j                   d {V }|d         |d         dfS )Nr   rm   	reasoning)r   r   re   rh   ri   r   s       r(   rp   zReasoningEvolution._aevolve  s\       //=$*H
 
 
 
 
 
 
 
 ay&)[00r'   c                4    t          | j        j                  S r:   r   r   s    r(   r   zReasoningEvolution.__hash__&  r   r'   Nr   r+   r   r   r   c                    t                                          ||           | j                            || j        |          | _        d S r:   )r   r   r   r5   r   s      r(   r   zReasoningEvolution.adapt)  sF    h	***)-)G)M)Md()*
 *
&&&r'   c                ~    t                                          |           | j                            |           d S r:   )r   r   r   r   s     r(   r   zReasoningEvolution.save/  s6    Y&++I66666r'   r   r:   r   r   )r!   r"   r#   r   r   r$   rp   r   r   r   r   r   s   @r(   r  r    s         (-99) ) )    1 1 1 1- - -
 
 
 
 
 
 
7 7 7 7 7 7 7 7 7 7 7r'   r  c                  d     e Zd ZU  ed           Zded<   ddZd Zdd fdZdd fdZ	 xZ
S )ConditionalEvolutionc                     t           S r:   )r   r&   r'   r(   r;   zConditionalEvolution.<lambda>7  s     ; r'   r   r   r   rh   r@   ri   r   rD   rk   c                l   K   |                      ||| j                   d {V }|d         |d         dfS )Nr   rm   conditional)r   r   r  s       r(   rp   zConditionalEvolution._aevolve:  s\       //=$*J
 
 
 
 
 
 
 
 ay&)]22r'   c                4    t          | j        j                  S r:   r   r   s    r(   r   zConditionalEvolution.__hash__B  r   r'   Nr   r+   r   r   r   c                    t                                          ||           | j                            || j        |          | _        d S r:   )r   r   r   r5   r   s      r(   r   zConditionalEvolution.adaptE  sF    h	***+/+K+Q+Qd(),
 ,
(((r'   c                ~    t                                          |           | j                            |           d S r:   )r   r   r   r   s     r(   r   zConditionalEvolution.saveK  s6    Y(--i88888r'   r   r:   r   r   )r!   r"   r#   r   r   r$   rp   r   r   r   r   r   s   @r(   r
  r
  4  s         */%;;+ + +    3 3 3 3- - -
 
 
 
 
 
 
9 9 9 9 9 9 9 9 9 9 9r'   r
  )<
__future__r   loggingtypingr   abcr   dataclassesr   r   numpyr1   langchain_core.pydantic_v1r   ragas.exceptionsr   
ragas.llmsr	   ragas.llms.json_loadr
   ragas.llms.promptr   ragas.run_configr   ragas.testset.docstorer   r   ragas.testset.filtersr   r   r   ragas.testset.promptsr   r   r   r   r   r   r   r   ragas.testset.utilsr   	getLoggerr!   rn   r   Tupler+   rk   r*   r4   r   r   r   r  r
  r   r   r  r  r&   r'   r(   <module>r#     s   " " " " " "            ( ( ( ( ( ( ( (     0 0 0 0 0 0 / / / / / / # # # # # # , , , , , , $ $ $ $ $ $ & & & & & & 6 6 6 6 6 6 6 6 M M M M M M M M M M	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 $ # # # # #		8	$	$ 6 6 6 6 6 6 6 6 '#|S01    i    ^- ^- ^- ^- ^- ^- ^- ^-B 72 72 72 72 72i 72 72 72t j6 j6 j6 j6 j6y j6 j6 j6Z V; V; V; V; V;, V; V; V;r 7 7 7 7 7) 7 7 76 9 9 9 9 9+ 9 9 96 
		%%''  	""$$r'   