Ë
    CØïiã…  ã                   ó  — d dl Z d dlZd dlmZmZmZmZ d dlmZ d dlm	Z
  G d„ de«      Zd„ Zd„ Zd	d
gfd„Zd"d„Zd	d
gfd„Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd	d
gfd„Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z d„ Z!d#d„Z"d „ Z#d!„ Z$y)$é    N)ÚAnyÚCallableÚ
NamedTupleÚOptional)Úassert_has_pandas)Úpandasc                   ó¨   — e Zd ZU eed<   dZee   ed<   dZee   ed<   dZee	e
ge
f      ed<   dZee   ed<   dZee	e
ge
f      ed<   dZee   ed<   y)	ÚRemediationÚnameNÚimmediate_msgÚnecessary_msgÚnecessary_fnÚoptional_msgÚoptional_fnÚ	error_msg)Ú__name__Ú
__module__Ú__qualname__ÚstrÚ__annotations__r   r   r   r   r   r   r   r   r   © ó    úK/var/www/html/aiagents/fe/lib/python3.12/site-packages/openai/validators.pyr
   r
   	   ss   … Ø
ƒIØ#'€M�8˜C‘=Ó'Ø#'€M�8˜C‘=Ó'Ø37€L�(˜8 S E¨3 JÑ/Ñ0Ó7Ø"&€L�(˜3‘-Ó&Ø26€K�˜( C 5¨# :Ñ.Ñ/Ó6Ø#€Iˆx˜‰}Ô#r   r
   c                 óf   — d}t        | «      |k\  rdnd}dt        | «      › d|› �}t        d|¬«      S )z’
    This validator will only print out the number of examples and recommend to the user to increase the number of examples if less than 100.
    éd   Ú z§. In general, we recommend having at least a few hundred examples. We've found that performance tends to linearly increase for every doubling of the number of examplesz
- Your file contains z prompt-completion pairsÚnum_examples©r   r   )Úlenr
   )ÚdfÚMIN_EXAMPLESÚoptional_suggestionr   s       r   Únum_examples_validatorr#      sT   € ð €Lô ˆr‹7�lÒ"ñ 	ð wð ð "¤# b£' Ð*BÐCVÐBWÐXð ô ˜N¸-ÔHÐHr   c                 óþ   ‡‡— d„ Šd}d}d}d}‰| j                   vrN‰| j                   D �cg c]  }t        |«      j                  «       ‘Œ c}v rˆˆfd„}|}d‰› d�}d‰› d�}nd‰› d�}t        d	||||¬
«      S c c}w )z[
    This validator will ensure that the necessary column is present in the dataframe.
    c                 óÈ   — | j                   D �cg c]!  }t        |«      j                  «       |k(  sŒ |‘Œ# }}| j                  |d   |j                  «       id¬«       | S c c}w )Nr   T)ÚcolumnsÚinplace)r&   r   ÚlowerÚrename)r    ÚcolumnÚcÚcolss       r   Úlower_case_columnz5necessary_column_validator.<locals>.lower_case_column(   sT   € ØŸ:™:ÖB�a¬¨Q«¯©«¸6Ó)A’ÐBˆÐBØ
�	‰	˜4 ™7 F§L¡L£NÐ3¸Tˆ	ÔBØˆ	ùò Cs
   �!A±ANc                 ó   •—  ‰| ‰«      S ©Nr   )r    r-   Únecessary_columns    €€r   Úlower_case_column_creatorz=necessary_column_validator.<locals>.lower_case_column_creator5   s   ø€ Ù(¨Ð-=Ó>Ð>r   z
- The `z ` column/key should be lowercasezLower case column name to `ú`z^` column/key is missing. Please make sure you name your columns/keys appropriately, then retryr0   )r   r   r   r   r   )r&   r   r(   r
   )	r    r0   r   r   r   r   r+   r1   r-   s	    `      @r   Únecessary_column_validatorr3   #   s¶   ù€ ò
ð
 €MØ€LØ€MØ€Ià˜rŸz™zÑ)Ø¸¿
¹
ÖC°1¤ A£§¡¥ÒCÑCõ?ð 5ˆLàÐ,Ð-Ð-MÐNð ð :Ð:JÐ9KÈ1ÐM‰MàÐ,Ð-ð  .Lð  MˆIäØØ#Ø#Ø!Øôð ùò  Ds   « A:ÚpromptÚ
completionc                 óD  ‡— g }d}d}d}t        | j                  «      dkD  rg| j                  D �cg c]	  }|‰vsŒ|‘Œ }}d}|D ]1  }|D �cg c]	  }||v sŒ|‘Œ }	}t        |	«      dkD  sŒ&|d|› d|› d�z  }Œ3 d|› |› �}d	|› �}ˆfd
„}t        d|||¬«      S c c}w c c}w )zK
    This validator will remove additional columns from the dataframe.
    Né   r   r   z9
  WARNING: Some of the additional columns/keys contain `z<` in their name. These will be ignored, and the column/key `z`` will be used instead. This could also result from a duplicate column/key in the provided file.zh
- The input file should contain exactly two columns/keys per row. Additional columns/keys present are: z Remove additional columns/keys: c                 ó   •— | ‰   S r/   r   ©ÚxÚfieldss    €r   r   z1additional_column_validator.<locals>.necessary_fn[   s   ø€ Ø�V‘9Ðr   Úadditional_column©r   r   r   r   )r   r&   r
   )
r    r;   Úadditional_columnsr   r   r   r+   Úwarn_messageÚacÚdupss
    `        r   Úadditional_column_validatorrB   I   s  ø€ ð ÐØ€MØ€MØ€LÜ
ˆ2�:‰:ƒ˜ÒØ)+¯©ÖG A°qÀ²šaÐGÐÐGØˆØ$ò 	BˆBØ1Ö=˜!°R¸1²W’AÐ=ˆDÐ=Ü�4‹y˜1‹}ØÐ"\Ð]_Ð\`ð  a]ð  ^`ð  ]að  aAð  !Bñ  B‘ð	Bð Dð  EWð  DXð  Yeð  Xfð  gˆØ:Ð;MÐ:NÐOˆô	ô Ø Ø#Ø#Ø!ô	ð ùò Hùò >s   °	BºBÁ	BÁBc                 óˆ  ‡— d}d}d}| ‰   j                  d„ «      j                  «       s!| ‰   j                  «       j                  «       rf| ‰   dk(  | ‰   j                  «       z  }| j                  «       j                  |   j                  «       }d‰› d|› �}ˆfd„}dt        |«      › d‰› d	�}t        d
‰› �|||¬«      S )zA
    This validator will ensure that no completion is empty.
    Nc                 ó   — | dk(  S )Nr   r   ©r:   s    r   ú<lambda>z+non_empty_field_validator.<locals>.<lambda>n   s
   €   b¡€ r   r   z
- `z?` column/key should not contain empty strings. These are rows: c                 ó<   •— | | ‰   dk7     j                  ‰g¬«      S )Nr   ©Úsubset)Údropna)r:   Úfields    €r   r   z/non_empty_field_validator.<locals>.necessary_fns   s&   ø€ Ø�Q�u‘X ‘^Ñ$×+Ñ+°E°7Ð+Ó;Ð;r   úRemove z rows with empty ÚsÚempty_r=   )ÚapplyÚanyÚisnullÚreset_indexÚindexÚtolistr   r
   )r    rK   r   r   r   Ú
empty_rowsÚempty_indexess    `     r   Únon_empty_field_validatorrW   f   sÜ   ø€ ð €MØ€LØ€Mà	ˆ%�y‡�Ñ(Ó)×-Ñ-Ô/°2°e±9×3CÑ3CÓ3E×3IÑ3IÔ3KØ˜‘i 2‘o¨"¨U©)×*:Ñ*:Ó*<Ñ=ˆ
ØŸ™Ó(×.Ñ.¨zÑ:×AÑAÓCˆØ ˜wÐ&eÐfsÐetÐuˆô	<ð "¤# mÓ"4Ð!5Ð5FÀuÀgÈQÐOˆÜØ�e�WÐØ#Ø#Ø!ô	ð r   c                 ó2  ‡— | j                  ‰¬«      }| j                  «       j                  |   j                  «       }d}d}d}t	        |«      dkD  r7dt	        |«      › ddj                  ‰«      › d|› �}dt	        |«      › d	�}ˆfd
„}t        d|||¬«      S )zY
    This validator will suggest to the user to remove duplicate rows if they exist.
    rH   Nr   ú
- There are z duplicated ú-z sets. These are rows: rL   z duplicate rowsc                 ó(   •— | j                  ‰¬«      S )NrH   )Údrop_duplicatesr9   s    €r   r   z.duplicated_rows_validator.<locals>.optional_fn�   s   ø€ Ø×$Ñ$¨FÐ$Ó3Ð3r   Úduplicated_rows©r   r   r   r   )Ú
duplicatedrR   rS   rT   r   Újoinr
   )r    r;   r]   Úduplicated_indexesr   r   r   s    `     r   Úduplicated_rows_validatorrb      sÀ   ø€ ð —m‘m¨6�mÓ2€OØŸ™Ó)×/Ñ/°Ñ@×GÑGÓIÐØ€MØ€LØ€Kä
ÐÓ Ò"Ø(¬Ð-?Ó)@Ð(AÀÈcÏhÉhÐW]ÓN^ÐM_Ð_vð  xJð  wKð  LˆØ ¤Ð%7Ó!8Ð 9¸ÐIˆô	4ô ØØ#Ø!Øô	ð r   c                 óÐ   ‡‡— d}d}d}t        | «      }|dk7  r@d„ Š ‰| «      Št        ‰«      dkD  r'dt        ‰«      › d‰› d�}dt        ‰«      › d	�}ˆˆfd
„}t        d|||¬«      S )zW
    This validator will suggest to the user to remove examples that are too long.
    Núopen-ended generationc                 ó€   — | j                  d„ d¬«      }| j                  «       j                  |   j                  «       S )Nc                 ó^   — t        | j                  «      t        | j                  «      z   dkD  S )Ni'  )r   r4   r5   rE   s    r   rF   zClong_examples_validator.<locals>.get_long_indexes.<locals>.<lambda>¥   s!   € œ#˜aŸh™h›-¬#¨a¯l©lÓ*;Ñ;¸eÑC€ r   é   )Úaxis)rO   rR   rS   rT   )ÚdÚlong_exampless     r   Úget_long_indexesz1long_examples_validator.<locals>.get_long_indexes£   s<   € ØŸG™GÙCÈ!ð $ó ˆMð —=‘=“?×(Ñ(¨Ñ7×>Ñ>Ó@Ð@r   r   rY   z. examples that are very long. These are rows: zf
For conditional generation, and for classification the examples shouldn't be longer than 2048 tokens.rL   z long examplesc                 óž   •—  ‰| «      }‰|k7  r/t         j                  j                  dt        |«      › d|› d�«       | j	                  |«      S )NzeThe indices of the long examples has changed as a result of a previously applied recommendation.
The z? long examples to be dropped are now at the following indices: ú
)ÚsysÚstdoutÚwriter   Údrop)r:   Úlong_indexes_to_droprk   Úlong_indexess     €€r   r   z,long_examples_validator.<locals>.optional_fn¯   s   ø€ á'7¸Ó':Ð$ØÐ#7Ò7Ü—J‘J×$Ñ$ð Aô  BEð  FZó  B[ð  A\ð  \[ð  \pð  [qð  qsð  tôð —v‘vÐ2Ó3Ð3r   rj   r^   )Úinfer_task_typer   r
   )r    r   r   r   Úft_typerk   rs   s        @@r   Úlong_examples_validatorrv   ˜   sŸ   ù€ ð €MØ€LØ€Kä˜bÓ!€GØÐ)Ò)ò	Añ (¨Ó+ˆäˆ|Ó˜qÒ Ø,¬S°Ó->Ð,?Ð?mÐnzÐm{ð  |cð  dˆMØ$¤S¨Ó%6Ð$7°~ÐFˆLõ4ô ØØ#Ø!Øô	ð r   c                 ó^  ‡‡— d}d}d}d}dŠg d¢}|D ]t  }|dk(  r4| j                   j                  j                  d«      j                  «       rŒ<| j                   j                  j                  |d¬«      j                  «       rŒr|Š n ‰j	                  dd«      }t        | «      }|d	k(  rt        d
¬«      S d„ Št        | j                   d¬«      }	| j                   |	k(  j                  «       rd|	› d�}t        d
|¬«      S |	dk7  r…|	j	                  dd«      }
d|
› d�}t        |	«      dkD  r	|d|› d�z  }| j                   j                  dt        |	«        j                  j                  |	d¬«      j                  «       r|d|	› d�z  }nd}|	dk(  rd|› d�}ˆˆfd„}t        d||||¬«      S )zœ
    This validator will suggest to add a common suffix to the prompt if one doesn't already exist in case of classification or conditional generation.
    Nz


### =>

)ú ->z

###

z

===

z

---

z

===>

z

--->

rx   rm   F©Úregexú\nrd   Úcommon_suffix©r   c                 ó    — | dxx   |z  cc<   | S ©Nr4   r   ©r:   Úsuffixs     r   Ú
add_suffixz2common_prompt_suffix_validator.<locals>.add_suffixá   s   € Ø	ˆ(‹�vÑ‹Øˆr   r�   ©ÚxfixzAll prompts are identical: `zt`
Consider leaving the prompts blank if you want to do open-ended generation, otherwise ensure prompts are different©r   r   r   z 
- All prompts end with suffix `r2   é
   úR. This suffix seems very long. Consider replacing with a shorter suffix, such as `z5
  WARNING: Some of your prompts contain the suffix `zZ` more than once. We strongly suggest that you review your prompts and add a unique suffixa”  
- Your data does not contain a common separator at the end of your prompts. Having a separator string appended to the end of the prompt makes it clearer to the fine-tuned model where the completion should begin. See https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset for more detail and examples. If you intend to do open-ended generation, then you should leave the prompts emptyzAdd a suffix separator `z` to all promptsc                 ó   •—  ‰| ‰«      S r/   r   ©r:   r‚   Úsuggested_suffixs    €€r   r   z3common_prompt_suffix_validator.<locals>.optional_fn   ó   ø€ Ù˜aÐ!1Ó2Ð2r   Úcommon_completion_suffix©r   r   r   r   r   )
r4   r   ÚcontainsrP   Úreplacert   r
   Úget_common_xfixÚallr   )r    r   r   r   r   Úsuffix_optionsÚsuffix_optionÚdisplay_suggested_suffixru   r|   Úcommon_suffix_new_line_handledr‚   rŠ   s              @@r   Úcommon_prompt_suffix_validatorr–   À   s  ù€ ð €IØ€MØ€LØ€Kð (Ðò€Nð (ò ˆØ˜EÒ!Ø�y‰y�}‰}×%Ñ% dÓ+×/Ñ/Ô1ØØ�9‰9�=‰=×!Ñ! -°uÐ!Ó=×AÑAÔCØØ(ÐÙðð  0×7Ñ7¸¸eÓDÐä˜bÓ!€GØÐ)Ò)Ü Ô0Ð0òô $ B§I¡I°HÔ=€MØ
�	‰	�]Ñ"×'Ñ'Ô)Ø2°=°/ð  Bwð  xˆ	Ü ¸9ÔEÐEà˜ÒØ)6×)>Ñ)>¸tÀUÓ)KÐ&à/Ð0NÐ/OÈqÐQð 	ô ˆ}Ó Ò"ØÐqð  sKð  rLð  LMð  Nñ  NˆMà�I‰I�M‰MÐ/œS Ó/Ð/Ð0ß‰S—‘˜-¨u�Ó5ß‰S‹Uðð ÐUÐVcÐUdð  eð  @ñ  @‰Mð pˆà˜Òà&Ð'?Ð&@Ð@PÐQð 	õ	3ô Ø'Ø#Ø!ØØôð r   c                 ó0  ‡‡— d}d}d}d}t        | j                  d¬«      Š‰dk(  rt        d¬«      S d„ Š| j                  ‰k(  j                  «       rt        d¬«      S ‰dk7  r%d	‰› d
�}|t	        ‰«      k  r|dz  }d‰› d�}ˆˆfd„}t        d|||¬«      S )zd
    This validator will suggest to remove a common prefix from the prompt if a long one exist.
    é   NÚprefixrƒ   r   Úcommon_prefixr}   c                 óB   — | d   j                   t        |«      d  | d<   | S r   ©r   r   )r:   r™   s     r   Úremove_common_prefixz<common_prompt_prefix_validator.<locals>.remove_common_prefix  s#   € Ø˜‘k—o‘o¤c¨&£k mÐ4ˆˆ(‰Øˆr   z"
- All prompts start with prefix `r2   zÒ. Fine-tuning doesn't require the instruction specifying the task, or a few-shot example scenario. Most of the time you should only add the input data into the prompt, and the desired output into the completionúRemove prefix `z` from all promptsc                 ó   •—  ‰| ‰«      S r/   r   )r:   rš   r�   s    €€r   r   z3common_prompt_prefix_validator.<locals>.optional_fn(  s   ø€ Ù+¨A¨}Ó=Ð=r   Úcommon_prompt_prefixr^   )r�   r4   r
   r‘   r   )r    ÚMAX_PREFIX_LENr   r   r   rš   r�   s        @@r   Úcommon_prompt_prefix_validatorr¢     sÆ   ù€ ð €Nà€MØ€LØ€Kä# B§I¡I°HÔ=€MØ˜ÒÜ Ô0Ð0òð 	�	‰	�]Ñ"×'Ñ'Ô)ä Ô0Ð0à˜ÒØ=¸m¸_ÈAÐNˆØœC Ó.Ò.Øð  rñ  rˆMØ,¨]¨OÐ;MÐNˆLõ>ô Ø#Ø#Ø!Øô	ð r   c                 ó:  ‡‡‡— d}t        | j                  d¬«      Št        ‰«      dkD  xr ‰d   dk(  Št        ‰«      |k  rt        d¬«      S d„ Š| j                  ‰k(  j	                  «       rt        d¬«      S d	‰› d
�}d‰› d�}ˆˆˆfd„}t        d|||¬«      S )zh
    This validator will suggest to remove a common prefix from the completion if a long one exist.
    é   r™   rƒ   r   ú rš   r}   c                 ó\   — | d   j                   t        |«      d  | d<   |rd| d   z   | d<   | S )Nr5   r¥   rœ   )r:   r™   Ú	ws_prefixs      r   r�   z@common_completion_prefix_validator.<locals>.remove_common_prefix>  s:   € Ø˜L™/×-Ñ-¬c°&«k¨mÐ<ˆˆ,‰Ùà! A l¡OÑ3ˆAˆl‰OØˆr   z&
- All completions start with prefix `z_`. Most of the time you should only add the output data into the completion, without any prefixrž   z` from all completionsc                 ó   •—  ‰| ‰‰«      S r/   r   )r:   rš   r�   r§   s    €€€r   r   z7common_completion_prefix_validator.<locals>.optional_fnL  s   ø€ Ù# A }°iÓ@Ð@r   Úcommon_completion_prefixr^   )r�   r5   r   r
   r‘   )r    r¡   r   r   r   rš   r�   r§   s        @@@r   Ú"common_completion_prefix_validatorrª   3  s½   ú€ ð €Nä# B§M¡M¸ÔA€MÜ�MÓ" QÑ&ÒB¨=¸Ñ+;¸sÑ+B€IÜ
ˆ=Ó˜NÒ*Ü Ô0Ð0òð 	�‰˜Ñ&×+Ñ+Ô-ä Ô0Ð0à=¸m¸_ð  Mlð  m€MØ$ ] OÐ3IÐJ€LöAô Ø'Ø#Ø!Øô	ð r   c                 óü  ‡‡— d}d}d}d}t        | «      }|dk(  s|dk(  rt        d¬«      S t        | j                  d¬«      }| j                  |k(  j	                  «       rd|› d	|› d
�}t        d|¬«      S dŠg d¢}|D ];  }| j                  j
                  j                  |d¬«      j                  «       rŒ9|Š n ‰j                  dd«      }	d„ Š|dk7  r…|j                  dd«      }
d|
› d
�}t        |«      dkD  r	|d|	› d
�z  }| j                  j
                  dt        |«        j
                  j                  |d¬«      j                  «       r|d|› d�z  }nd}|dk(  rd|	› d�}ˆˆfd„}t        d||||¬«      S )z 
    This validator will suggest to add a common suffix to the completion if one doesn't already exist in case of classification or conditional generation.
    Nrd   Úclassificationr|   r}   r�   rƒ   z All completions are identical: `zJ`
Ensure completions are different, otherwise the model will just repeat `r2   r…   z [END])	rm   ú.z ENDz***z+++z&&&z$$$z@@@z%%%Fry   rm   r{   c                 ó    — | dxx   |z  cc<   | S ©Nr5   r   r€   s     r   r‚   z6common_completion_suffix_validator.<locals>.add_suffix}  s   € Ø	ˆ,‹˜6Ñ!‹Øˆr   r   z$
- All completions end with suffix `r†   r‡   z9
  WARNING: Some of your completions contain the suffix `zU` more than once. We suggest that you review your completions and add a unique endingaH  
- Your data does not contain a common ending at the end of your completions. Having a common ending string appended to the end of the completion makes it clearer to the fine-tuned model where the completion should end. See https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset for more detail and examples.zAdd a suffix ending `z` to all completionsc                 ó   •—  ‰| ‰«      S r/   r   r‰   s    €€r   r   z7common_completion_suffix_validator.<locals>.optional_fn—  r‹   r   rŒ   r�   )
rt   r
   r�   r5   r‘   r   rŽ   rP   r�   r   )r    r   r   r   r   ru   r|   r’   r“   r”   r•   r‚   rŠ   s              @@r   Ú"common_completion_suffix_validatorr±   W  s  ù€ ð €IØ€MØ€LØ€Kä˜bÓ!€GØÐ)Ò)¨WÐ8HÒ-HÜ Ô0Ð0ä# B§M¡M¸ÔA€MØ
�‰˜Ñ&×+Ñ+Ô-Ø6°}°oð  FQð  R_ð  Q`ð  `að  bˆ	Ü ¸9ÔEÐEð  Ðò
€Nð (ò ˆØ�=‰=×Ñ×%Ñ% m¸5Ð%ÓA×EÑEÔGØØ(ÐÙð	ð
  0×7Ñ7¸¸eÓDÐòð ˜ÒØ)6×)>Ñ)>¸tÀUÓ)KÐ&à3Ð4RÐ3SÐSTÐUð 	ô ˆ}Ó Ò"ØÐqð  sKð  rLð  LMð  Nñ  NˆMà�M‰M×ÑÐ3¤ ]Ó!3Ð 3Ð4ß‰S—‘˜-¨u�Ó5ß‰S‹Uðð ÐYÐZgÐYhð  i~ð  ñ  ‰Mð dˆà˜Òà#Ð$<Ð#=Ð=QÐRð 	õ	3ô Ø'Ø#Ø!ØØôð r   c                 óÐ   — d„ }d}d}d}| j                   j                  dd j                  «       dk7  s| j                   j                  d   d   dk7  rd}d}|}t	        d|||¬	«      S )
zŽ
    This validator will suggest to add a space at the start of the completion if it doesn't already exist. This helps with tokenization.
    c                 ó6   — | d   j                  d„ «      | d<   | S )Nr5   c                 ó&   — | d   dk(  rd| z   S d| z   S )Nr   r¥   r   r   rE   s    r   rF   zLcompletions_space_start_validator.<locals>.add_space_start.<locals>.<lambda>ª  s   € ˜Q˜q™T Sš[�r°QÑ6€ ¨c°QÑ6€ r   )rO   rE   s    r   Úadd_space_startz:completions_space_start_validator.<locals>.add_space_start¨  s$   € Ø˜L™/×/Ñ/Ù6ó
ˆˆ,‰ð ˆr   Nrg   r   r¥   zæ
- The completion should start with a whitespace character (` `). This tends to produce better results due to the tokenization we use. See https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset for more detailsz=Add a whitespace character to the beginning of the completionÚcompletion_space_startr^   )r5   r   ÚnuniqueÚvaluesr
   )r    rµ   r   r   r   s        r   Ú!completions_space_start_validatorr¹   £  s€   € ò
ð €LØ€KØ€Mà	‡}�}×Ñ˜˜!Ð×$Ñ$Ó&¨!Ò+¨r¯}©}×/CÑ/CÀAÑ/FÀqÑ/IÈSÒ/Pð BˆØVˆØ%ˆÜØ%Ø#Ø!Øô	ð r   c                 óà   ‡— ˆfd„}| ‰   j                  d„ «      j                  «       }| ‰   j                  d„ «      j                  «       }|dz  |kD  rt        dd‰› d‰› d�d	‰› d
�|¬«      S y)zt
    This validator will suggest to lowercase the column values, if more than a third of letters are uppercase.
    c                 óH   •— | ‰   j                   j                  «       | ‰<   | S r/   )r   r(   )r:   r*   s    €r   Ú
lower_casez(lower_case_validator.<locals>.lower_caseÃ  s"   ø€ Ø�f‘I—M‘M×'Ñ'Ó)ˆˆ&‰	Øˆr   c                 ó&   — t        d„ | D «       «      S )Nc              3   ód   K  — | ](  }|j                  «       sŒ|j                  «       sŒ%d –— Œ* y­w©rg   N)ÚisalphaÚisupper©Ú.0r+   s     r   ú	<genexpr>z9lower_case_validator.<locals>.<lambda>.<locals>.<genexpr>É  ó    è ø€ ÒI 1¨Q¯Y©Y­[¸Q¿Y¹Y½[œQÑIùó   ‚0˜0©0©ÚsumrE   s    r   rF   z&lower_case_validator.<locals>.<lambda>É  ó   € œÑI¨ÔIÓI€ r   c                 ó&   — t        d„ | D «       «      S )Nc              3   ód   K  — | ](  }|j                  «       sŒ|j                  «       sŒ%d –— Œ* y­wr¿   )rÀ   ÚislowerrÂ   s     r   rÄ   z9lower_case_validator.<locals>.<lambda>.<locals>.<genexpr>Î  rÅ   rÆ   rÇ   rE   s    r   rF   z&lower_case_validator.<locals>.<lambda>Î  rÉ   r   r7   r¼   z
- More than a third of your `z%` column/key is uppercase. Uppercase z÷s tends to perform worse than a mixture of case encountered in normal language. We recommend to lower case the data if that makes sense in your domain. See https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset for more detailsz'Lowercase all your data in column/key `r2   r^   N)rO   rÈ   r
   )r    r*   r¼   Úcount_upperÚcount_lowers    `   r   Úlower_case_validatorrÏ   ¾  s—   ø€ ô
ð
 	ˆ6‰
ß	‰ÑIÓ	Jß	‰‹ð ð 	ˆ6‰
ß	‰ÑIÓ	Jß	‰‹ð ð �Q�˜Ò$ÜØØ;¸F¸8ÐChÐioÐhpð  qhð  iØBÀ6À(È!ÐLØ"ô	
ð 	
ð %r   c                 ó   — t        «        d}d}d}d}d}t        j                  j                  | «      �rõ	 | j	                  «       j                  d«      s| j	                  «       j                  d«      r_| j	                  «       j                  d«      rdnd\  }}d|› d�}d|› d	�}t        j                  | |t        ¬
«      j                  d«      }�nV| j	                  «       j                  d«      rdd}d}t        j                  | «      }	|	j                  }
t        |
«      dkD  r|dz  }t        j                  | t        ¬«      j                  d«      }�nÓ| j	                  «       j                  d«      rud}d}t        | d«      5 }|j                  «       }t        j                   |j#                  d«      D �cg c]  }d|g‘Œ c}|t        ¬«      j                  d«      }ddd«       �n?| j	                  «       j                  d«      rit        j$                  | dt        ¬«      j                  d«      }t        |«      dk(  r/d}d}t        j$                  | t        ¬«      j                  d«      }n¸n·| j	                  «       j                  d«      rj	 t        j$                  | dt        ¬«      j                  d«      }t        |«      dk(  r+t        j$                  | t        ¬«      j                  d«      }nd}d}n.d}d | v r|d!| › d"| j#                  d «      d#   › d$�z  }n	|d!| › d%�z  }nd*| › d+�}t-        d,|||¬-«      }||fS c c}w # 1 sw Y   Œ(xY w# t&        $ r- t        j$                  | t        ¬«      j                  d«      }Y Œ`w xY w# t&        t(        f$ r1 | j#                  d «      d#   j+                  «       }d&| › d'|› d(|› d)�}Y Œœw xY w).zÕ
    This function will read a file saved in .csv, .json, .txt, .xlsx or .tsv format using pandas.
     - for .xlsx it will read the first sheet
     - for .txt it will assume completions and split on newline
    Nz.csvz.tsv)ÚCSVú,)ÚTSVú	z=
- Based on your file extension, your file is formatted as a z filezYour format `z` will be converted to `JSONL`)ÚsepÚdtyper   z.xlsxzH
- Based on your file extension, your file is formatted as an Excel filez/Your format `XLSX` will be converted to `JSONL`rg   z¥
- Your Excel file contains more than one sheet. Please either save as csv or ensure all data is present in the first sheet. WARNING: Reading only the first sheet...)rÖ   z.txtz9
- Based on your file extension, you provided a text filez.Your format `TXT` will be converted to `JSONL`Úrrm   )r&   rÖ   ú.jsonlT)ÚlinesrÖ   z^
- Your JSONL file appears to be in a JSON format. Your file will be converted to JSONL formatz/Your format `JSON` will be converted to `JSONL`z.jsonz^
- Your JSON file appears to be in a JSONL format. Your file will be converted to JSONL formatz]Your file must have one of the following extensions: .CSV, .TSV, .XLSX, .TXT, .JSON or .JSONLr­   z Your file `z` ends with the extension `.éÿÿÿÿz` which is not supported.z` is missing a file extension.zYour file `z!` does not appear to be in valid z9 format. Please ensure your file is formatted as a valid z file.zFile z does not exist.Úread_any_format)r   r   r   r   )r   ÚosÚpathÚisfiler(   ÚendswithÚpdÚread_csvr   ÚfillnaÚ	ExcelFileÚsheet_namesr   Ú
read_excelÚopenÚreadÚ	DataFrameÚsplitÚ	read_jsonÚ
ValueErrorÚ	TypeErrorÚupperr
   )Úfnamer;   Úremediationr   r   r   r    Úfile_extension_strÚ	separatorÚxlsÚsheetsÚfÚcontentÚlines                 r   rÛ   rÛ   Û  sË  € ô ÔØ€KØ€MØ€MØ€IØ	€Bä	‡w�w‡~�~�eÕð@	vØ�{‰{‹}×%Ñ% fÔ-°·±³×1GÑ1GÈÔ1Oà$)§K¡K£M×$:Ñ$:¸6Ô$B‘LÈñ .Ð" Ið #aÐasÐ`tÐtyÐ z�à#Ð$6Ð#7Ð7UÐVð ô —[‘[ ¨I¼SÔA×HÑHÈÓL’Ø—‘“×'Ñ'¨Ô0Ø k�Ø Q�Ü—l‘l 5Ó)�ØŸ™�Ü�v“; ’?Ø!ð  &Nñ  N�MÜ—]‘] 5´Ô4×;Ñ;¸BÓ?’Ø—‘“×'Ñ'¨Ô/àPð ð !Q�Ü˜% Ó%ð !¨ØŸf™f›h�GÜŸ™Ø07·±¸dÓ0CÖD¨˜"˜dšÒDØ &Ü!ô÷ ‘f˜R“jð	 ÷!ñ !ð —‘“×'Ñ'¨Ô1Ü—\‘\ %¨t¼3Ô?×FÑFÀrÓJ�Ü�r“7˜a’<ð %F�MØ$U�MÜŸ™ e´3Ô7×>Ñ>¸rÓB‘BàØ—‘“×'Ñ'¨Ô0ðCäŸ™ e°4¼sÔC×JÑJÈ2ÓN�BÜ˜2“w !’|äŸ\™\¨%´sÔ;×BÑBÀ2ÓF™ð )J˜àMð &øð |�	Ø˜%‘<Ø <°¨wÐ6RÐSX×S^ÑS^Ð_bÓScÐdfÑSgÐRhð  iBð  "Cñ  C‘Ià <°¨wÐ6TÐ!UÑU�Iøð ˜E˜7Ð"2Ð3ˆ	äØØ#Ø#Øô	€Kð ˆ{ˆ?Ðùòc E÷!ð !ûô: "ò CäŸ™ e´3Ô7×>Ñ>¸rÓB’BðCûô œIÐ&ò 	vØ!&§¡¨SÓ!1°"Ñ!5×!;Ñ!;Ó!=ÐØ% e WÐ,MÐN`ÐMað  b[ð  \nð  [oð  ouð  vŠIð	vúsb   ¶EN Æ3MÆ8M
ÇMÇ B1N ÊA(M Ë:/N ÍMÍMÍN Í3N
ÎN Î	N
Î
N Î=OÏOc                 óL   — t        | «      }d}|dk(  rd|› d�}t        d|¬«      S )zÓ
    This validator will infer the likely fine-tuning format of the data, and display it to the user if it is classification.
    It will also suggest to use ada and explain train/validation split benefits.
    Nr¬   zK
- Based on your data it seems like you're trying to fine-tune a model for zã
- For classification, we recommend you try one of the faster and cheaper models, such as `ada`
- For classification, you can estimate the expected model performance by keeping a held out dataset, which is not used for trainingr   r   )rt   r
   )r    ru   r   s      r   Úformat_inferrer_validatorrø   7  sA   € ô
 ˜bÓ!€GØ€MØÐ"Ò"ØfÐgnÐfoð  pUð  VˆÜ˜N¸-ÔHÐHr   c                 ó`  — |j                   �Ot        j                  j                  d|j                  › d|j                   › d�«       t        j
                  d«       |j                  �)t        j                  j                  |j                  «       |j                  �|j                  | «      } | S )zs
    This function will apply a necessary remediation to a dataframe, or print an error message if one exists.
    z

ERROR in z validator: z

Aborting...rg   )	r   rn   Ústderrrp   r   Úexitr   ro   r   )r    rï   s     r   Úapply_necessary_remediationrü   C  s•   € ð ×ÑÐ(Ü�
‰
×ÑØ˜K×,Ñ,Ð-¨\¸+×:OÑ:OÐ9PÐP_Ð`ô	
ô 	�‰�ŒØ× Ñ Ð,Ü�
‰
×Ñ˜×2Ñ2Ô3Ø×ÑÐ+Ø×%Ñ% bÓ)ˆØ€Ir   c                 óº   — t         j                  j                  | «       |r t         j                  j                  d«       yt        «       j	                  «       dk7  S )NzY
TÚn)rn   ro   rp   Úinputr(   )Ú
input_textÚauto_accepts     r   Úaccept_suggestionr  S  s?   € Ü‡J�J×Ñ�ZÔ ÙÜ�
‰
×Ñ˜ÔØÜ‹7�=‰=‹?˜cÑ!Ð!r   c                 óö   — d}d|j                   › d�}|j                   �t        ||«      r|j                  | «      } d}|j                  �-t        j
                  j                  d|j                  › d�«       | |fS )zc
    This function will apply an optional remediation to a dataframe, based on the user input.
    Fz- [Recommended] z [Y/n]: Tz- [Necessary] rm   )r   r  r   r   rn   ro   rp   )r    rï   r  Úoptional_appliedr   s        r   Úapply_optional_remediationr  [  s…   € ð ÐØ# K×$<Ñ$<Ð#=¸XÐF€JØ×ÑÐ+Ü˜Z¨Ô5Ø×(Ñ(¨Ó,ˆBØ#ÐØ× Ñ Ð,Ü�
‰
×Ñ˜>¨+×*CÑ*CÐ)DÀBÐGÔHØÐÐÐr   c                 óö   — t        | «      }d}|dk(  rt        | «      }|dz  }n%| j                  d¬«      j                  «       }|dz  }d„ } ||dz   «      }t        j
                  j                  d	|› d
�«       y)z?
    Estimate the time it'll take to fine-tune the dataset
    g      ð?r¬   g
×£p=
÷?T)rS   g‘í|?5^ª?c                 óª   — | dk  rt        | d«      › d�S | dk  rt        | dz  d«      › d�S | dk  rt        | dz  d«      › d�S t        | dz  d«      › d�S )	Né<   r7   z secondsi  z minutesi€Q z hoursz days)Úround)Útimes    r   Úformat_timez.estimate_fine_tuning_time.<locals>.format_timew  sv   € Ø�"Š9Ü˜D !“nÐ% XÐ.Ð.Ø�DŠ[Ü˜D 2™I qÓ)Ð*¨(Ð3Ð3Ø�EŠ\Ü˜D 4™K¨Ó+Ð,¨FÐ3Ð3ä˜D 5™L¨!Ó,Ð-¨UÐ3Ð3r   éŒ   z:Once your model starts training, it'll approximately take z~ to train a `curie` model, and less for `ada` and `babbage`. Queue will approximately take half an hour per job ahead of you.
N)rt   r   Úmemory_usagerÈ   rn   ro   rp   )r    Ú	ft_formatÚexpected_timer   Úsizer  Útime_strings          r   Úestimate_fine_tuning_timer  j  s�   € ô   Ó#€IØ€MØÐ$Ò$Ü˜2“wˆØ$ tÑ+‰à�‰ TˆÓ*×.Ñ.Ó0ˆØ˜v™ˆò4ñ ˜m¨cÑ1Ó2€KÜ‡J�J×ÑØ
DÀ[ÀMð  RQð  	Rõr   c                 óè   — |rddgndg}d}	 |dkD  rd|› d�nd}|D �cg c]0  }t         j                  j                  | «      d   dz   |z   |z   dz   ‘Œ2 }}t        d	„ |D «       «      s|S |d
z  }Œbc c}w )NÚ_trainÚ_validr   r   z (ú)Ú	_preparedrØ   c              3   óZ   K  — | ]#  }t         j                  j                  |«      –— Œ% y ­wr/   )rÜ   rÝ   rÞ   )rÃ   rô   s     r   rÄ   z get_outfnames.<locals>.<genexpr>�  s   è ø€ Ò?¨”2—7‘7—>‘> !×$Ñ?ùs   ‚)+rg   )rÜ   rÝ   ÚsplitextrP   )rî   ré   ÚsuffixesÚiÚindex_suffixr�   Úcandidate_fnamess          r   Úget_outfnamesr  ‡  s¡   € Ù',�˜(Ñ#°2°$€HØ	€AØ
Ø$%¨¢E˜˜A˜3˜a‘y¨rˆð #ö
àô �G‰G×Ñ˜UÓ# AÑ&¨Ñ4°vÑ=ÀÑLÈxÓWð
Ðð 
ô Ñ?Ð.>Ô?Ô?Ø#Ð#Ø	ˆQ‰ˆð ùò
s   ž5A/c                 óš   — | j                   j                  «       }d }|dk(  r'| j                   j                  «       j                  d   }||fS )Nr7   r   )r5   r·   Úvalue_countsrS   )r    Ú	n_classesÚ	pos_classs      r   Úget_classification_hyperparamsr#  •  sH   € Ø—‘×%Ñ%Ó'€IØ€IØ�A‚~Ø—M‘M×.Ñ.Ó0×6Ñ6°qÑ9ˆ	Ø�iÐÐr   c                 ó   — t        | «      }t        | j                  d¬«      }t        | j                  d¬«      }d}d}|dk(  rt	        ||«      rd}d}	|j                  dd	«      }
|j                  dd	«      }t        |«      d
kD  rd|› d�nd}d}|s:|s8t        j                  j                  d|› d|	› d|
› d|› d�	«       t        | «       y*t	        ||«      �r˜t        ||«      }|ràt        |«      dk(  rd|d
   v rd|d   v sJ ‚d}t        t        | «      |z
  t        t        | «      dz  «      «      }| j                  |d¬«      }| j                  |j                   «      }|ddg   j#                  |d
   ddd¬«       |ddg   j#                  |d   ddd¬«       t%        | «      \  }}|	dz  }	|dk(  r
|	d|› d�z  }	n6|	d |› �z  }	n-t        |«      dk(  sJ ‚| ddg   j#                  |d
   ddd¬«       |rd!ndd"z   d#j'                  |«      z   }|r	d$|d   › d�nd}t        |
«      d
k(  rdnd%|
› d�}t        j                  j                  d&|› d'|d
   › d|› |	› d(|› |› d�«       t        | «       y*t        j                  j                  d)«       y*)+aQ  
    This function will write out a dataframe to a file, if the user would like to proceed, and also offer a fine-tuning command with the newly created file.
    For classification it will optionally ask the user if they would like to split the data into train/valid files, and modify the suggested command to include the valid set.
    r�   rƒ   FzQ- [Recommended] Would you like to split into training and validation set? [Y/n]: r¬   Tr   rm   r{   r   z Make sure to include `stop=["z;"]` so that the generated texts ends at the expected place.z@

Your data will be written to a new JSONL file. Proceed [Y/n]: zK
You can use your file for fine-tuning:
> openai api fine_tunes.create -t "ú"ue   

After youâ€™ve fine-tuned a model, remember that your prompt has to end with the indicator string `zX` for the model to start generating completions, rather than continuing with the prompt.r7   ÚtrainÚvalidrg   iè  gš™™™™™é?é*   )rþ   Úrandom_stater4   r5   Úrecords)rÙ   ÚorientÚforce_asciiz! --compute_classification_metricsz" --classification_positive_class "z --classification_n_classes rM   z to `z` and `z -v "uc   After youâ€™ve fine-tuned a model, remember that your prompt has to end with the indicator string `z
Wrote modified filezd`
Feel free to take a look!

Now use that file when fine-tuning:
> openai api fine_tunes.create -t "z

z#Aborting... did not write the file
N)rt   r�   r4   r5   r  r�   r   rn   ro   rp   r  r  ÚmaxÚintÚsamplerq   rS   Úto_jsonr#  r`   )r    rî   Úany_remediationsr  r  Úcommon_prompt_suffixrŒ   ré   r   Úadditional_paramsÚ%common_prompt_suffix_new_line_handledÚ)common_completion_suffix_new_line_handledÚoptional_ending_stringÚfnamesÚMAX_VALID_EXAMPLESÚn_trainÚdf_trainÚdf_validr!  r"  Úfiles_stringÚvalid_stringÚseparator_reminders                          r   Úwrite_out_filer?  �  s«  € ô
   Ó#€IÜ*¨2¯9©9¸8ÔDÐÜ.¨r¯}©}À8ÔLÐà€EØd€JØÐ$Ò$Ü˜Z¨Ô5ØˆEàÐØ,@×,HÑ,HÈÈuÓ,UÐ)Ø0H×0PÑ0PØˆeó1Ð-ô
 Ð8Ó9¸AÒ=ð )Ð)RÐ(Sð  TOñ  	Pàð ð V€Já¡EÜ�
‰
×ÑØ[Ð\aÐ[bÐbcÐduÐcvð  w^ð  _Dð  ^Eð  E]ð  ^tð  ]uð  uwð  xô	
ô 	" "Õ%ä	˜: {Õ	3Ü˜u eÓ,ˆÙÜ�v“; !Ò#¨°6¸!±9Ñ(<ÀÈFÐSTÉIÑAUÐUÐUØ!%ÐÜœ#˜b›'Ð$6Ñ6¼¼CÀ»GÀc¹MÓ8JÓKˆGØ—y‘y 7¸�yÓ<ˆHØ—w‘w˜xŸ~™~Ó.ˆHØ�h Ð-Ñ.×6Ñ6Ø�q‘	 ¨iÀUð 7ô ð �h Ð-Ñ.×6Ñ6Ø�q‘	 ¨iÀUð 7ô ô $BÀ"Ó#EÑ ˆI�yØÐ!DÑDÐØ˜AŠ~Ø!Ð'IÈ)ÈÐTUÐ%VÑVÑ!à!Ð'CÀIÀ;Ð%OÑOÑ!ä�v“; !Ò#Ð#Ð#Ø�˜,Ð'Ñ(×0Ñ0Ø�q‘	 ¨iÀUð 1ô ñ
  %™¨"°Ñ7¸9¿>¹>È&Ó;QÑRˆÙ/4˜˜v a™y˜k¨Ñ+¸"ˆô Ð8Ó9¸QÒ>ñ àvð  x]ð  w^ð  ^vð  wð 	ô
 	�
‰
×ÑØ# L >ð  2Zð  [að  bcñ  [dð  Zeð  efð  gsð  ftð  uFð  tGð  GKð  L^ð  K_ð  `vð  _wð  wyð  zô	
ô 	" "Õ%ä�
‰
×ÑÐ?Õ@r   c                 óÐ   — d}t        | j                  j                  j                  «       «      dk(  ryt        | j                  j                  «       «      t        | «      |z  k  ryy)z>
    Infer the likely fine-tuning task type from the data
    é   r   rd   r¬   zconditional generation)rÈ   r4   r   r   r5   Úunique)r    ÚCLASSIFICATION_THRESHOLDs     r   rt   rt   ê  sU   € ð  !ÐÜ
ˆ2�9‰9�=‰=×ÑÓÓ 1Ò$Ø&ä
ˆ2�=‰=×ÑÓ!Ó"¤S¨£WÐ/GÑ%GÒGØà#r   c                 óö   — d}	 |dk(  r| j                   t        |«      dz    d n| j                   dt        |«      dz    }|j                  «       dk7  r	 |S ||j                  d   k(  r	 |S |j                  d   }Œw)zQ
    Finds the longest common suffix or prefix of all the values in a series
    r   r�   rg   Nr   )r   r   r·   r¸   )Úseriesr„   Úcommon_xfixÚcommon_xfixess       r   r�   r�   ø  s§   € ð €KØ
ð �xÒð �J‰Jœ˜[Ó)¨AÑ-Ð.Ð0Ñ1à—‘Ð2œc +Ó.°Ñ2Ð3ð 	ð ×!Ñ!Ó# qÒ(àð Ðð ˜=×/Ñ/°Ñ2Ò2àð Ðð (×.Ñ.¨qÑ1ˆKð r   c                  ó„   — t         d„ d„ t        t        t        t        t
        d„ d„ t        t        t        t        t        gS )Nc                 ó   — t        | d«      S r   ©r3   rE   s    r   rF   z get_validators.<locals>.<lambda>  s   € Ô,¨Q°Ó9€ r   c                 ó   — t        | d«      S r¯   rJ  rE   s    r   rF   z get_validators.<locals>.<lambda>  s   € Ô,¨Q°Ó=€ r   c                 ó   — t        | d«      S r   ©rÏ   rE   s    r   rF   z get_validators.<locals>.<lambda>  s   € Ô& q¨(Ó3€ r   c                 ó   — t        | d«      S r¯   rM  rE   s    r   rF   z get_validators.<locals>.<lambda>  s   € Ô& q¨,Ó7€ r   )r#   rB   rW   rø   rb   rv   r–   r¢   rª   r±   r¹   r   r   r   Úget_validatorsrO    s9   € äÙ9Ù=Ü#Ü!Ü!Ü!ÜÙ3Ù7Ü&Ü&Ü*Ü*Ü)ðð r   c                 ó.  — g }|�|j                  |«       |D ]*  } || «      }|€Œ|j                  |«       t        | |«      } Œ, t        |D �cg c]  }|j                  €|j                  �|‘Œ c}«      }t        |D �cg c]  }|j                  �|‘Œ c}«      }	d}
|r=t
        j                  j                  d«       |D ]  }t        | ||«      \  } }|
xs |}
Œ nt
        j                  j                  d«       |
xs |	} || |||«       y c c}w c c}w )NFz?

Based on the analysis we will perform the following actions:
z

No remediations found.
)	Úappendrü   rP   r   r   rn   ro   rp   r  )r    rî   rï   Ú
validatorsr  Úwrite_out_file_funcÚoptional_remediationsÚ	validatorÚ&any_optional_or_necessary_remediationsÚany_necessary_appliedÚany_optional_appliedr  Ú!any_optional_or_necessary_applieds                r   Úapply_validatorsrZ  $  sV  € ð ÐØÐØ×$Ñ$ [Ô1Øò >ˆ	Ù “mˆØÑ"Ø!×(Ñ(¨Ô5Ü,¨R°Ó=‰Bð	>ô .1ð  5ö	
àØ×'Ñ'Ð3Ø×(Ñ(Ð4ò ò	
ó.Ð*ô  ð  5ö	
àØ×(Ñ(Ð4ò ò	
óÐð !Ðá-Ü�
‰
×ÑØPô	
ð 1ò 	LˆKÜ#=Ø�K ó$Ñ ˆBÐ ð $8Ò#KÐ;KÑ ñ		Lô 	�
‰
×ÑÐ7Ô8à(<Ò(UÐ@UÐ%á˜˜EÐ#DÀkÕRùò=	
ùò	
s   Á!DÁ?D)r5   )r�   )%rÜ   rn   Útypingr   r   r   r   Úopenai.datalib.pandas_helperr   r   rà   r
   r#   r3   rB   rW   rb   rv   r–   r¢   rª   r±   r¹   rÏ   rÛ   rø   rü   r  r  r  r  r#  r?  rt   r�   rO  rZ  r   r   r   ú<module>r]     sÎ   ðÛ 	Û 
ß 6Ó 6å :Ý 5ô$�*ô $òIò #ðL -5°lÐ+Có ó:ð2 +3°LÐ)Aó ò2%òPIòX$òN!òHIòXò6
ð: $,¨\Ð":ó Yòx	Iòò "ò òò:ò òJAòZ$óò0ó(0Sr   