
    h+b                        S r SSKrSSKrSSKrSSKrSSKJr  SSKJr  SSK	J
r
JrJr  SSKrSSKJr  SSKJr  SSKJr  SS	KJrJr  SS
KJrJrJrJr  SSKJr  SSKJ r!  \
(       a  SSK"J#r#  SSK$J%r%J&r&  \RN                  " \(5      r)Sr*\RV                  " S\SS  S3\RX                  5      r-\RV                  " S5      r. " S S\/5      r0 " S S\/5      r1\" SS9 " S S5      5       r2  S4S\3S\4S   S\\3S 4   S!\\3   S"\\3   S#\24S$ jjr5 " S% S&5      r6 " S' S(\65      r7 " S) S*\65      r8\" SS9 " S+ S,5      5       r9\" SS9 " S- S.5      5       r:S/ r;S0 r<S1 r=S2 r> " S3 S 5      r?g)5zArrow ArrowReader.    N)	dataclass)partial)TYPE_CHECKINGOptionalUnion)
thread_map   )DownloadConfig)	_split_refilenames_for_dataset_split)InMemoryTableMemoryMappedTableTableconcat_tables)logging)tqdm)DatasetInfo)Split	SplitInfoz=https://storage.googleapis.com/huggingface-nlp/cache/datasetsz
^
 (?P<split>z)
 (\[
    ((?P<from>-?[\d_]+)
     (?P<from_pct>%)?)?
    :
    ((?P<to>-?[\d_]+)
     (?P<to_pct>%)?)?
 \])?(\((?P<rounding>[^\)]*)\))?
$
z\s*\+\s*c                       \ rS rSrSrSrg)DatasetNotOnHfGcsErrorA   z?When you can't get the dataset from the Hf google cloud storage N__name__
__module____qualname____firstlineno____doc____static_attributes__r       O/home/james-whalen/.local/lib/python3.13/site-packages/datasets/arrow_reader.pyr   r   A   s    Ir"   r   c                       \ rS rSrSrSrg)MissingFilesOnHfGcsErrorG   z9When some files are missing on the Hf oogle cloud storager   Nr   r   r"   r#   r%   r%   G   s    Cr"   r%   T)frozenc                   4    \ rS rSr% Sr\\S'   \\   \S'   Sr	g)FileInstructionsM   ae  The file instructions associated with a split ReadInstruction.

Attributes:
    num_examples: `int`, The total number of examples
    file_instructions: List[dict(filename, skip, take)], the files information.
        The filenames contains the relative path, not absolute.
        skip/take indicates which example read in the file: `ds.slice(skip, take)`
num_examplesfile_instructionsr   N)
r   r   r   r   r    int__annotations__listdictr!   r   r"   r#   r)   r)   M   s     Dz!r"   r)   namesplit_infosr   instructionReadInstructionfiletype_suffixprefix_pathreturnc                    [        U [        5      (       d!  [        S[        U 5      R                   35      eU (       d  [        S5      eU Vs0 s H  oUR                  UR                  _M     nnU Vs0 s H  oUR                  UR                  _M     nnU Vs0 s H1  nUR                  [        UU UR                  UXuR                     S9_M3     nn[        U[        5      (       d  [        R                  U5      nUR                  U5      n	/ n
SnU	 GH  nXlR                     nXR                     nX|R                     nUR                  c  SOUR                  nUR                  c  UOUR                  nUc2  U H*  nUU-
  nUS:X  a  M  UU-  nU
R!                  UUUS.5        M,     M  SnSn[#        X5       Hf  u  nnUU-  nUU:  aP  UU:  aJ  UU:  a  UU-
  OSnUU:  a  UU-
  U-
  OSnUS:X  a  M<  U
R!                  UUUS.5        UUS:X  a  UU-
  OU-  nUU-  nMh     GM     [%        UU
S9$ s  snf s  snf s  snf )a  Returns instructions of the split dict.

Args:
    name (`str`): Name of the dataset.
    split_infos (`list` of `[SplitInfo]`): Dataset splits information.
    instruction ([`ReadInstruction`] or `str`): Reading instruction for a dataset.
    filetype_suffix (`str`, *optional*): Suffix of dataset files, e.g. 'arrow' or 'parquet'.
    prefix_path (`str`, *optional*): Prefix of dataset files, e.g. directory name.

Returns:
    [`FileInstructions`]
zExpected str 'name', but got: zExpected non-empty str 'name')pathdataset_namesplitr5   shard_lengthsr   )filenameskiptaker   )r+   r,   )
isinstancestr	TypeErrortyper   
ValueErrorr1   r+   r<   r   r4   	from_specto_absolute	splitnamefrom_toappendzipr)   )r1   r2   r3   r5   r6   infoname2lenname2shard_lengthsname2filenamesabsolute_instructionsr,   r+   	abs_instrsplit_length	filenamesr<   rH   rI   r=   r?   index_start	index_endshard_lengthr>   s                           r#   make_file_instructionsrW   \   sw   & dC  8d9L9L8MNOO8999DE		4,,,HEDOPKD))T%7%77KP  	  D 			.))+,YY7
 	
    	 k?33%//<'33H= L*	 3 34"#6#67	*+>+>?__,)//&\\1\y|| %Ez19$!((hW[)\] & KI*-i*G&,\)	9$k)927+2E5;.1D689n2+d2"Dqy %,,(DZ^-_` 42:L4$74OL|+ +H! +4 !+ ] FP	s    H53 H:8H?c                       \ rS rSrSrS\S\S   4S jrSS\4S jjr	SS\4S	 jjr
S
 r SS jr  SS\\   S\S   4S jjrSrg)
BaseReader   z8
Build a Dataset object out of Instruction instance(s).
r9   rL   r   c                 *    Xl         X l        SU l        g)zInitializes ArrowReader.

Args:
    path (str): path where tfrecords are stored.
    info (DatasetInfo): info about the dataset.
N)_path_info_filetype_suffix)selfr9   rL   s      r#   __init__BaseReader.__init__   s     
.2
/3r"   r7   c                     [         e)=Returns a Dataset instance from given (filename, skip, take).)NotImplementedError)r_   filename_skip_take	in_memorys      r#   _get_table_from_filename#BaseReader._get_table_from_filename   s    !!r"   c           	         [        U5      S:X  d  [        S U 5       5      (       d  [        S5      e[        R                  " U5      nU H3  n[
        R                  R                  U R                  US   5      US'   M5     [        [        U R                  US9U[        S[        U5      S:*  =(       d    SS	9nU Vs/ s H  n[        U5      S:  d  M  UPM     nnU(       d/  U R                  b  U R                  R                  c  [        S
5      eU=(       dH    [        R                   " / ["        R$                  " U R                  R                  R&                  5      S9/n[        U5      S:w  a  [)        U5      nU$ US   nU$ s  snf )aS  Returns Dataset for given file instructions.

Args:
    files: List[dict(filename, skip, take)], the files information.
        The filenames contain the absolute path, not relative.
        skip/take indicates which example read in the file: `ds.slice(skip, take)`
    in_memory (bool, default False): Whether to copy the data in-memory.
r   c              3   B   #    U  H  n[        U[        5      v   M     g 7fN)r@   r0   ).0fs     r#   	<genexpr>)BaseReader._read_files.<locals>.<genexpr>   s     %I5ajD&9&95s   z&please provide valid file informationsr=   rf   zLoading dataset shards   N)
tqdm_classdescdisablezqTried to read an empty table. Please specify at least info.features to create an empty table with the right type.)schemar	   )lenallrD   copydeepcopyosr9   joinr\   r   r   rg   hf_tqdmr]   featuresr   from_batchesparu   rC   r   )r_   filesrf   rm   	pa_tablestpa_tables          r#   _read_filesBaseReader._read_files   sQ    u:?#%I5%I"I"IEFFe$AGGLLQz]CAjM  D11YG)J"$,
	 !*8	1SVaZQ		8djj0DJJ4G4G4O D  m-"<"<R		RVR\R\ReReRjRjHk"l!m	/29~/B=+ IRRS 9s   =FFc                 \    [        XX R                  U R                  S9nUR                  nU$ )z?Return list of dict {'filename': str, 'skip': int, 'take': int})r5   r6   )rW   r^   r\   r,   )r_   r1   r3   r2   r,   r   s         r#   get_file_instructions BaseReader.get_file_instructions   s3    2{<Q<Q_c_i_i
 "33r"   c                 v    U R                  XU5      nU(       d  SU S3n[        U5      eU R                  XRUS9$ )a  Returns Dataset instance(s).

Args:
    name (str): name of the dataset.
    instructions (ReadInstruction): instructions to read.
        Instruction can be string and will then be passed to the Instruction
        constructor as it.
    split_infos (list of SplitInfo proto): the available splits for dataset.
    in_memory (bool, default False): Whether to copy the data in-memory.

Returns:
     kwargs to build a single Dataset instance.
zInstruction "z" corresponds to no data!)r   original_instructionsrf   )r   rD   
read_files)r_   r1   instructionsr2   rf   r   msgs          r#   readBaseReader.read   sF    * **4{K!,/HICS/!UZcddr"   Nr   r   )Nr4   r   c                 |    U R                  XS9nUb  SSKJn  U" [        U5      5      nOSnX@R                  US.nU$ )a  Returns single Dataset instance for the set of file instructions.

Args:
    files: List[dict(filename, skip, take)], the files information.
        The filenames contains the relative path, not absolute.
        skip/take indicates which example read in the file: `ds.skip().take()`
    original_instructions: store the original instructions used to build the dataset split in the dataset.
    in_memory (bool, default False): Whether to copy the data in-memory.

Returns:
    kwargs to build a Dataset instance.
rp   Nr	   )r   )arrow_tablerL   r;   )r   splitsr   rA   r]   )r_   r   r   rf   r   r   r;   dataset_kwargss           r#   r   BaseReader.read_files   sJ    & ##E#? ,%#345EE)1::PUVr"   )r^   r]   r\   F)NF)r   r   r   r   r    rA   r   r`   r   rg   r   r   r   r/   r0   r   r   r!   r   r"   r#   rY   rY      sx    	4S 	4(? 	4"u "U @ e< JN	Dz  %%EF r"   rY   c                   l   ^  \ rS rSrSrS\S\S   4U 4S jjrSS\4S jjr	\
SS\4S	 jj5       rS
rU =r$ )ArrowReaderi  z
Build a Dataset object out of Instruction instance(s).
This Reader uses either memory mapping or file descriptors (in-memory) on arrow files.
r9   rL   r   c                 2   > [         TU ]  X5        SU l        g)zInitializes ArrowReader.

Args:
    path (str): path where Arrow files are stored.
    info (DatasetInfo): info about the dataset.
arrowNsuperr`   r^   r_   r9   rL   	__class__s      r#   r`   ArrowReader.__init__#  s     	$ 'r"   r7   c                     US   SU;   a  US   OSSU;   a  US   OSpTn[         R                  X2S9nUS:X  a  [        U5      U-
  nUb)  Ub&  US:X  a  U[        U5      :X  d  UR                  XE5      nU$ )rc   r=   r>   Nr?   rp   r   r   )r   
read_tablerv   slice)r_   re   rf   r=   r>   r?   tables          r#   rg   $ArrowReader._get_table_from_filename-  s     z**04F*Fv&D*04F*Fv&D 
 &&x&E2:u:$D 0$!)PSTYPZHZKK+Er"   c                 J    U(       a  [         O[        nUR                  U 5      $ )z
Read table from file.

Args:
    filename (str): File name of the table.
    in_memory (bool, default=False): Whether to copy the data in-memory.

Returns:
    pyarrow.Table
)r   r   	from_file)r=   rf   	table_clss      r#   r   ArrowReader.read_table<  s     &/M4E	""8,,r"   r^   r   )r   r   r   r   r    rA   r   r`   r   rg   staticmethodr   r!   __classcell__r   s   @r#   r   r     sG    
(S ((? (u  - - -r"   r   c                   D   ^  \ rS rSrSrS\S\S   4U 4S jjrS rSr	U =r
$ )	ParquetReaderiL  zj
Build a Dataset object out of Instruction instance(s).
This Reader uses memory mapping on parquet files.
r9   rL   r   c                 2   > [         TU ]  X5        SU l        g)zInitializes ParquetReader.

Args:
    path (str): path where tfrecords are stored.
    info (DatasetInfo): info about the dataset.
parquetNr   r   s      r#   r`   ParquetReader.__init__R  s     	$ )r"   c                     US   SU;   a  US   OSSU;   a  US   OSpTn[         R                  " USS9nUb)  Ub&  US:X  a  U[        U5      :X  d  UR                  XE5      nU$ )rc   r=   r>   Nr?   T)
memory_mapr   )pqr   rv   r   )r_   re   kwargsr=   r>   r?   r   s          r#   rg   &ParquetReader._get_table_from_filename\  s}     z**04F*Fv&D*04F*Fv&D  ==d; 0$!)PST\P]H]~~d1Hr"   r   )r   r   r   r   r    rA   r   r`   rg   r!   r   r   s   @r#   r   r   L  s*    
*S *(? * r"   r   c                   8    \ rS rSr% Sr\\S'   \\S'   \\S'   Srg)_AbsoluteInstructionik  z?A machine friendly slice: defined absolute positive boundaries.rG   rH   rI   r   N)	r   r   r   r   r    rA   r.   r-   r!   r   r"   r#   r   r   k  s    INJGr"   r   c                   z    \ rS rSr% Sr\\S'   Sr\\	   \S'   Sr
\\	   \S'   Sr\\   \S'   Sr\\   \S'   S	 rS
rg)_RelativeInstructionit  zHRepresents a single parsed slicing instruction, can use % and negatives.rG   NrH   rI   unitroundingc                 h   U R                   b  U R                   S;  a  [        S5      eU R                  b  U R                  S;  a  [        S5      eU R                   S:w  a  U R                  b  [        S5      eU R                   S:X  a1  U R                  b$  [	        U R                  5      S:  a  [        S5      eU R                   S:X  a1  U R
                  b$  [	        U R
                  5      S:  a  [        S5      eU R                  c  U R                   S:X  a  S	OU R                  U R                  S
'   g )N)%abszunit must be either % or abs)closestpct1_dropremainderz5rounding must be either closest or pct1_dropremainderr   zAIt is forbidden to specify rounding if not using percent slicing.d   z2Percent slice boundaries must be > -100 and < 100.r   r   )r   rD   r   rH   r   rI   __dict__r_   s    r#   __post_init__"_RelativeInstruction.__post_init__~  s    99 TYYl%B;<<==$>_)_TUU99 9`aa99

 63tzz?S;PQRR99 3DGGs8JQRR151F499X[K[Iaeananj!r"   r   )r   r   r   r   r    rA   r.   rH   r   r-   rI   r   r   r   r!   r   r"   r#   r   r   t  sH    RNE8C=BD(3-"Hhsm"or"   r   c           
         [         R                  U 5      nU(       d  [        SU  35      eUR                  S5      (       d  UR                  S5      (       a  SOSn[	        UR                  S5      UR                  S5      UR                  S5      (       a  [        UR                  S5      5      OS	UR                  S
5      (       a  [        UR                  S
5      5      US9$ S	US9$ )z)Returns ReadInstruction for given string.z!Unrecognized instruction format: from_pctto_pctr   r   r;   r   fromNrI   )
split_namer   rH   rI   r   )_SUB_SPEC_REmatchrD   groupr4   r-   )specresr   s      r#   _str_to_read_instructionr     s    


T
"C<TFCDD))J''399X+>+>3ED99W%:&(+		&(9(9c#))F#$t#&99T??3syy  9= r"   c                 `    US:  a  Sn[        U5      eU [        R                  " US-  5      -  $ )Nr   zUsing "pct1_dropremainder" rounding on a split with less than 100 elements is forbidden: it always results in an empty dataset.      Y@)rD   mathtrunc)boundaryr+   r   s      r#   _pct_to_abs_pct1r     s:    cL 	 odjj!5666r"   c                 4    [        [        X-  S-  5      5      $ )Nr   )r-   round)r   r+   s     r#   _pct_to_abs_closestr     s    uX,u4566r"   c                    U R                   S:X  a  [        O[        nU R                  nX1;  a  [	        SU S[        U5       S35      eX   nU R                  nU R                  nU R                  S:X  a  Uc  SOU" XT5      nUc  UOU" Xd5      nOUc  SOUnUc  UOUnUS:  a  [        XE-   S5      nUS:  a  [        XF-   S5      n[        XT5      n[        Xd5      n[        X5U5      $ )zReturns _AbsoluteInstruction instance for given RelativeInstruction.

Args:
    rel_instr: RelativeInstruction instance.
    name2len: dict {split_name: num_examples}.
r   zUnknown split "z". Should be one of .r   r   )r   r   r   rG   rD   r/   rH   rI   r   maxminr   )	rel_instrrM   
pct_to_absr;   r+   rH   rI   s          r#   _rel_to_abs_instrr     s     )2(:(:i(G$M]JE?5'1Ed8nEUUVWXX?LOOE	B~~]
5(GZ\Z-I]Z\RqyL(!,	Av"A&$E	R	Bb11r"   c                   f    \ rS rSrSrS r\S 5       rSS jr\S 5       r	S r
S	 rS
 rS rS rSrg)r4   i  aC  Reading instruction for a dataset.

Examples::

  # The following lines are equivalent:
  ds = datasets.load_dataset('mnist', split='test[:33%]')
  ds = datasets.load_dataset('mnist', split=datasets.ReadInstruction.from_spec('test[:33%]'))
  ds = datasets.load_dataset('mnist', split=datasets.ReadInstruction('test', to=33, unit='%'))
  ds = datasets.load_dataset('mnist', split=datasets.ReadInstruction(
      'test', from_=0, to=33, unit='%'))

  # The following lines are equivalent:
  ds = datasets.load_dataset('mnist', split='test[:33%]+train[1:-1]')
  ds = datasets.load_dataset('mnist', split=datasets.ReadInstruction.from_spec(
      'test[:33%]+train[1:-1]'))
  ds = datasets.load_dataset('mnist', split=(
      datasets.ReadInstruction('test', to=33, unit='%') +
      datasets.ReadInstruction('train', from_=1, to=-1, unit='abs')))

  # The following lines are equivalent:
  ds = datasets.load_dataset('mnist', split='test[:33%](pct1_dropremainder)')
  ds = datasets.load_dataset('mnist', split=datasets.ReadInstruction.from_spec(
      'test[:33%](pct1_dropremainder)'))
  ds = datasets.load_dataset('mnist', split=datasets.ReadInstruction(
      'test', from_=0, to=33, unit='%', rounding="pct1_dropremainder"))

  # 10-fold validation:
  tests = datasets.load_dataset(
      'mnist',
      [datasets.ReadInstruction('train', from_=k, to=k+10, unit='%')
      for k in range(0, 100, 10)])
  trains = datasets.load_dataset(
      'mnist',
      [datasets.ReadInstruction('train', to=k, unit='%') + datasets.ReadInstruction('train', from_=k+10, unit='%')
      for k in range(0, 100, 10)])

c                     Xl         g rk   _relative_instructions)r_   relative_instructionss     r#   _initReadInstruction._init  s    &;#r"   c                 J    U R                  U 5      nUR                  U5        U$ )zCReturns ReadInstruction obj initialized with relative_instructions.)__new__r   )clsr   results      r#   ,_read_instruction_from_relative_instructions<ReadInstruction._read_instruction_from_relative_instructions  s$     S!*+r"   Nc           	      >    U R                  [        XXEU5      /5        g)aq  Initialize ReadInstruction.

Args:
    split_name (str): name of the split to read. Eg: 'train'.
    rounding (str, optional): The rounding behaviour to use when percent slicing is
        used. Ignored when slicing with absolute indices.
        Possible values:
         - 'closest' (default): The specified percentages are rounded to the
             closest value. Use this if you want specified percents to be as
             much exact as possible.
         - 'pct1_dropremainder': the specified percentages are treated as
             multiple of 1%. Use this option if you want consistency. Eg:
                 len(5%) == 5 * len(1%).
             Using this option, one might not be able to use the full set of
             examples, if the number of those is not a multiple of 100.
    from_ (int):
    to (int): alternative way of specifying slicing boundaries. If any of
        {from_, to, unit} argument is used, slicing cannot be specified as
        string.
    unit (str): optional, one of:
        '%': to set the slicing unit as percents of the split size.
        'abs': to set the slicing unit as absolute numbers.
N)r   r   )r_   r   r   rH   rI   r   s         r#   r`   ReadInstruction.__init__  s    6 	

(BhOPQr"   c                     [        U5      n[        R                  U5      nU(       d  [        SU 35      e[	        US   5      n[        S USS  5       U5      $ )a  Creates a `ReadInstruction` instance out of a string spec.

Args:
    spec (`str`):
        Split(s) + optional slice(s) to read + optional rounding
        if percents are used as the slicing unit. A slice can be specified,
        using absolute numbers (`int`) or percentages (`int`).

Examples:

    ```
    test: test split.
    test + validation: test split + validation split.
    test[10:]: test split, minus its first 10 records.
    test[:10%]: first 10% records of test split.
    test[:20%](pct1_dropremainder): first 10% records, rounded with the pct1_dropremainder rounding.
    test[:-5%]+train[40%:60%]: first 95% of test + middle 20% of train.
    ```

Returns:
    ReadInstruction instance.
z&No instructions could be built out of r   c              3   8   #    U  H  n[        U5      v   M     g 7frk   )r   )rl   subs     r#   rn   ,ReadInstruction.from_spec.<locals>.<genexpr>5  s     FXc,S11Xs   r	   N)rA   _ADDITION_SEP_REr;   rD   r   sum)r   r   subsr3   s       r#   rE   ReadInstruction.from_spec  sZ    0 4y%%d+EdVLMM.tAw7FT!"XFTTr"   c                    / nU R                    H  nUR                  nUR                  c  UR                  b  UR                  nUR                  nUR                  nUR
                  nUS:X  a  UOSnUb  [        U5      U-   OSnUb  [        U5      U-   OSnSU SU S3nUS:X  a  Ub  US:w  a  SU S3OSn	X8U	-   -  nUR                  U5        M     S	R                  U5      $ )
Nr    [:]r   ()+)	r   rG   rH   rI   r   r   rA   rJ   r{   )
r_   rel_instr_specsr   rel_instr_specrH   rI   r   r   	slice_strrounding_strs
             r#   to_specReadInstruction.to_spec7  s    44I&00N*ill.F!\\ ~~$--#s{t-2->E
T)B')~SWt^2wat1-	'+s{x7KPX\ePeazOkm  l"::"">2 5  xx((r"   c                 R   [        U[        5      (       d  Sn[        U5      eU R                  nUR                  nUS   R                  S:w  aH  US   R                  S:w  a5  U R                  S   R
                  US   R
                  :w  a  [        S5      eU R                  X4-   5      $ )zEReturns a new ReadInstruction obj, result of appending other to self.zAReadInstruction can only be added to another ReadInstruction obj.r   r   zPIt is forbidden to sum ReadInstruction instances with different rounding values.)r@   r4   rB   r   r   r   rD   r   )r_   otherr   self_ris	other_riss        r#   __add__ReadInstruction.__add__K  s    %11UCC. ..00	QK%!!!U*++A.779Q<;P;PPopp@@AUVVr"   c                 "    U R                  5       $ rk   )r  r   s    r#   __str__ReadInstruction.__str__Z  s    ||~r"   c                 "    SU R                    S3$ )NzReadInstruction(r   r   r   s    r#   __repr__ReadInstruction.__repr__]  s    !$"="=!>a@@r"   c                 X    U R                    Vs/ s H  n[        X!5      PM     sn$ s  snf )a"  Translate instruction into a list of absolute instructions.

Those absolute instructions are then to be added together.

Args:
    name2len (`dict`):
        Associating split names to number of examples.

Returns:
    list of _AbsoluteInstruction instances (corresponds to the + in spec).
)r   r   )r_   rM   r   s      r#   rF   ReadInstruction.to_absolute`  s,     IMHcHcdHc9!)6Hcddds   'r   )NNNN)r   r   r   r   r    r   classmethodr   r`   rE   r  r
  r  r  rF   r!   r   r"   r#   r4   r4     sY    $L<  R: U U<)(WAer"   )NN)@r    rx   r   rz   redataclassesr   	functoolsr   typingr   r   r   pyarrowr   pyarrow.parquetr   r   tqdm.contrib.concurrentr   download.download_configr
   namingr   r   r   r   r   r   r   utilsr   r   r|   rL   r   r   r   r   
get_loggerr   loggerHF_GCP_BASE_URLcompileXr   r   ConnectionErrorr   r%   r)   rA   r/   rW   rY   r   r   r   r   r   r   r   r   r4   r   r"   r#   <module>r%     s       	 	 !  1 1   . 4 : I I  " !( 
		H	%Qzz
aO 	 DD  ::k* 	_ 		 	 $" " "$ &*!%H
Hk"H s--.H c]	H
 #H HVs sl,-* ,-^J > $   $o o o0772:de der"   