
    /iipO              	          d Z ddlZddlZddlmZ ddlmZ ddlm	Z	 ddl
mZmZ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 ddlmZ ddlmZ ddlmZm Z  ddl!m"Z"m#Z#  edd          \  Z$Z% ee$e%d          \  Z$Z% e            &                    e$          Z$g dZ'dhd  ej(                    D             z  Z)dSdZ*ej+        ,                    de          d             Z-d Z.ej+        ,                    dg e#e"          d             Z/d Z0ej+        ,                    d e'          ej+        ,                    d!e          d"                         Z1d# Z2ej+        ,                    d$d%          d&             Z3d' Z4d( Z5d) Z6d* Z7ej+        ,                    d+d,d-g          d.             Z8ej+        ,                    d/e#          d0             Z9ej+        ,                    d1e'          d2             Z:d3 Z;d4 Z<ej+        ,                    d5d!d6i ej=        d7ej>        gej>        d7gg          fd!d6id7d8gd8d7ggfi d7d8gd9d:ggfg          d;             Z?ej+        ,                    d/e#          d<             Z@ej+        ,                    d/e#          d=             ZAd> ZBd? ZCd@ ZDej+        ,                    dAdBdCg          ej+        ,                    dDddEg          dF                         ZEdG ZFej+        ,                    dHdIdJg          dK             ZGej+        ,                    dLdMdNg          dO             ZHej+        ,                    dPd,d-g          dQ             ZIdR ZJdS )TzF
Tests for HDBSCAN clustering algorithm
Based on the DBSCAN test code
    N)stats)distance)HDBSCAN)CONDENSED_dtype_condense_tree_do_labelling)_OUTLIER_ENCODING)
make_blobs)fowlkes_mallows_score)_VALID_METRICSeuclidean_distances)BallTreeKDTree)StandardScaler)shuffle)assert_allcloseassert_array_equal)CSC_CONTAINERSCSR_CONTAINERS   
   )	n_samplesrandom_state   )r   )kd_tree	ball_treebruteautoc                 $    h | ]\  }}|d          S )label ).0_outs      h/var/www/html/bet.cuttalo.com/ml/venv/lib/python3.11/site-packages/sklearn/cluster/tests/test_hdbscan.py	<setcomp>r'   &   s     KKKvq#c'lKKK    Gz?c                     t          t          |           t          z
            }|dk    sJ t          | t                    |k    sJ d S )N   )lensetOUTLIER_SETr   y)labels	threshold
n_clusterss      r&   check_label_qualityr3   )   sH    S[[;.//J???? ++i777777r(   outlier_typec                    t           j        t           j        d|          }d d d|          }t          |          d         }t          |          d         }t                                          }|dg|d<   ||g|d<   t          d	
                              |          }|j        |k    	                                \  }t          |ddg            ||j        |          	                                \  }t          |ddg           t          t          dd                    t          t          dd                    z   }	t          d	
                              ||	                   }
t          |
j        |j        |	                    dS )O
    Tests if np.inf and np.nan data are each treated as special outliers.
    )infinitemissingc                     | |k    S Nr"   xr/   s     r&   <lambda>z#test_outlier_data.<locals>.<lambda>9   s
    a r(   c                 *    t          j        |           S r:   )npisnanr;   s     r&   r=   z#test_outlier_data.<locals>.<lambda>:   s     r(   r!   prob   r      Fcopy   r   N)r?   infnanr	   XrE   r   fitlabels_nonzeror   probabilities_listrange)r4   outlier
prob_checkr!   rA   	X_outliermodelmissing_labels_idxmissing_probs_idxclean_indicesclean_models              r&   test_outlier_datarX   /   s    F6  G
 ('++  J l+G4E\*62DIQ<IaLW%IaL##I..E"]e3<<>>)Aq6222&Ju';TBBKKMM(1a&111q!%%U1c]](;(;;Mu%%%)))M*BCCK{*EM-,HIIIIIr(   c                  `   t          t                    } |                                 }t          dd                              |           }t          | |           t          |           d}t          j        t          |          5  t          dd                              t                     ddd           n# 1 swxY w Y   d}d| d	<   d
| d<   t          j        t          |          5  t          dd                              |            ddd           dS # 1 swxY w Y   dS )zy
    Tests that HDBSCAN works with precomputed distance matrices, and throws the
    appropriate errors when needed.
    precomputedTmetricrE   z*The precomputed distance matrix.*has shapematchNz'The precomputed distance matrix.*valuesr   )r   rB   rB   )rB   r   F)
r   rI   rE   r   fit_predictr   r3   pytestraises
ValueError)D
D_originalr0   msgs       r&   test_hdbscan_distance_matrixrf   O   s   
 	AAJM555AA!DDFAz"""
7C	z	-	-	- @ @}4000<<Q???@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 5CAdGAdG	z	-	-	- A A}5111==a@@@A A A A A A A A A A A A A A A A A As$   	*B??CC1%D##D'*D'sparse_constructorc                    t          j        t          j        t                              }|t	          j        |          z  }t          j        |                                d          }d|||k    <    | |          }|	                                 t          dd                              |          }t          |           dS )zA
    Tests that HDBSCAN works with sparse distance matrices.
    2           rZ   Fr[   N)r   
squareformpdistrI   r?   maxr   scoreatpercentileflatteneliminate_zerosr   r_   r3   )rg   rc   r1   r0   s       r&   #test_hdbscan_sparse_distance_matrixrq   g   s    
 	HN1--..ANA'		R88IAa9n1AM666BB1EEFr(   c                  t    t          d                              t                    } t          |            dS )z
    Tests that HDBSCAN works with feature array, including an arbitrary
    goodness of fit check. Note that the check is a simple heuristic.
    FrD   N)r   r_   rI   r3   r0   s    r&   test_hdbscan_feature_arrayrt   y   s8    
 %   ,,Q//F r(   algor\   c                 p   t          | d                              t                    }t          |           | dv rdS t          t
          d}dt          j        t          j        d                   idt          j	        t          j        d                   idd	id	t          j	        t          j        d                   d
d
                    |d          }t          | ||d          }|||          j        vrNt          j        t                    5  |                    t                     ddd           dS # 1 swxY w Y   dS |dk    rNt          j        t"                    5  |                    t                     ddd           dS # 1 swxY w Y   dS |                    t                     dS )z
    Tests that HDBSCAN works with the expected combinations of algorithms and
    metrics, or raises the expected errors.
    F)	algorithmrE   )r   r   N)r   r   VrB   p   )ry   w)mahalanobis
seuclidean	minkowski
wminkowski)rw   r\   metric_paramsrE   r   )r   r_   rI   r3   r   r   r?   eyeshapeonesgetvalid_metricsr`   ra   rb   rJ   warnsFutureWarning)ru   r\   r0   ALGOS_TREESr   hdbs         r&   test_hdbscan_algorithmsr      s*    t%000<<Q??F      K
 RVAGAJ//0BGAGAJ//01XBGAGAJ$7$788	 
 
c&$  #	  C [&444]:&& 	 	GGAJJJ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 		<		\-(( 	 	GGAJJJ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	




s$   D;;D?D?'FFFc                      t          d                              t                    } |                     d          }t	          |d           dS )z
    Tests that HDBSCAN can generate a sufficiently accurate dbscan clustering.
    This test is more of a sanity check than a rigorous evaluation.
    FrD   333333?gq=
ףp?)r1   N)r   rJ   rI   dbscan_clusteringr3   )	clustererr0   s     r&   test_dbscan_clusteringr      sP    
 U###''**I((--F $//////r(   cut_distance)皙?      ?rB   c                 8   t           d         d         }t           d         d         }t                                          }t          j        dg|d<   dt          j        g|d<   t          j        t          j        g|d<   t          d	                              |          }|                    | 
          }t          j	        ||k              }t          |ddg           t          j	        ||k              }t          |dg           t          t          t          d                    t          ||z             z
            }t          d	                              ||                   }	|	                    | 
          }
t          |
||                    dS )r6   r8   r!   r7   rB   r   rz   rC   FrD   )r   r   N)r	   rI   rE   r?   rG   rH   r   rJ   r   flatnonzeror   rN   r-   rO   )r   missing_labelinfinite_labelrR   rS   r0   rT   infinite_labels_idx	clean_idxrW   clean_labelss              r&   #test_dbscan_clustering_outlier_datar      sf   
 &i09M&z27;NIFA;IaLrv;IaLFBF#IaL##I..E$$,$??F-(?@@)Aq6222.>)ABB*QC000Ss__s+=@S+S'T'TTUUIu%%%)))I*>??K00l0KKL|VI%677777r(   c                      t          ddt          j        t          j        d                   id                              t                    } t          |            dS )z4
    Tests that HDBSCAN using `BallTree` works.
    r}   rx   rB   F)r\   r   rE   N)r   r?   r   rI   r   r_   r3   rs   s    r&   !test_hdbscan_best_balltree_metricr      sX     C1D1D+EE  k!nn  r(   c                      t          t          t                    dz
  d                              t                    } t	          |                               t                    sJ dS )z
    Tests that HDBSCAN correctly does not generate a valid cluster when the
    `min_cluster_size` is too large for the data.
    rB   Fmin_cluster_sizerE   N)r   r,   rI   r_   r-   issubsetr.   rs   s    r&   test_hdbscan_no_clustersr      sT    
 c!ffqju===II!LLFv;;,,,,,,,r(   c                  :   t          dt          t                    d          D ]v} t          | d                              t                    }d |D             }t          |          dk    r,t          j        t          j        |                    | k    sJ wdS )zb
    Test that the smallest non-noise cluster has at least `min_cluster_size`
    many points
    rz   rB   Fr   c                     g | ]
}|d k    |S )r   r"   )r#   r!   s     r&   
<listcomp>z1test_hdbscan_min_cluster_size.<locals>.<listcomp>   s    @@@ERKKuKKKr(   r   N)rO   r,   rI   r   r_   r?   minbincount)r   r0   true_labelss      r&   test_hdbscan_min_cluster_sizer      s    
 "!SVVQ// H H*:GGGSSTUVV@@&@@@{q  6"+k22337GGGGG	H Hr(   c                      t           j        } t          | d                              t                    }t          |           dS )zA
    Tests that HDBSCAN works when passed a callable metric.
    Fr[   N)r   	euclideanr   r_   rI   r3   )r\   r0   s     r&   test_hdbscan_callable_metricr      s@     FF///;;A>>Fr(   treer   r   c                     t          d| d          }d}t          j        t          |          5  |                    t
                     ddd           dS # 1 swxY w Y   dS )z
    Tests that HDBSCAN correctly raises an error when passing precomputed data
    while requesting a tree-based algorithm.
    rZ   Fr\   rw   rE   z%precomputed is not a valid metric forr]   N)r   r`   ra   rb   rJ   rI   )r   r   re   s      r&   "test_hdbscan_precomputed_non_bruter      s     $U
C
C
CC
1C	z	-	-	-  


                 s   AAAcsr_containerc                    t          d                              t                    j        }t	          |            | t                    }|                                }t          d                              |          j        }t          ||           t          j        dft          j	        dffD ]\  }}t                                          }||d<   t          d                              |          j        }t	          |           |d         t          |         d         k    sJ |                                }||d<   t          d                              |          j        }t          ||           d}t          j        t          |	          5  t          d
dd                              |           ddd           dS # 1 swxY w Y   dS )z
    Tests that HDBSCAN works correctly when passing sparse feature data.
    Evaluates correctness by comparing against the same data passed as a dense
    array.
    FrD   r7   r8   r   r   r   r!   z4Sparse data matrices only support algorithm `brute`.r]   r   r   r   N)r   rJ   rI   rK   r3   rE   r   r?   rG   rH   r	   r`   ra   rb   )	r   dense_labels	_X_sparseX_sparsesparse_labelsoutlier_valr4   X_densere   s	            r&   test_hdbscan_sparser     s    &&&**1--5L%%%a  I~~H'''++H55=M|]333 (*vz&:RVY<O%P 
8 
8!\&&((#E***..w77?L)))A"3L"A'"JJJJJ>>##$U+++//99A<7777
@C	z	-	-	- U U{kFFFJJ8TTTU U U U U U U U U U U U U U U U U Us   &GGGrw   c                    ddg}t          dd|d          \  }}t          dd	                              |          }t          ||j        |j                  D ],\  }}}t          ||d
d           t          ||d
d           -t          | dt          j        d         d                              t                    }|j        j        d         dk    sJ |j        j        d         dk    sJ dS )zj
    Tests that HDBSCAN centers are calculated and stored properly, and are
    accurate to the data.
    )rj   rj   )      @r   i  r   r   )r   r   centerscluster_stdbothF)store_centersrE   rB   g?)rtolatol)rw   r   r   rE   N)	r
   r   rJ   zip
centroids_medoids_r   rI   r   )rw   r   Hr$   r   centercentroidmedoids           r&   test_hdbscan_centersr   .  s    :&G1gSVWWWDAq
U
3
3
3
7
7
:
:C$'$N$N ; ; &qt<<<<QT::::: 	  
 
c!ff  >"a''''<a A%%%%%%r(   c                     t           j                            d          } |                     dd          }t	          ddddd	                              |          }t          j        |d
          \  }}t          |          dk    sJ ||dk             dk    sJ t	          dddddd                              |          }t          j        |d
          \  }}t          |          dk    sJ ||dk             dk    sJ dS )zS
    Tests that HDBSCAN single-cluster selection with epsilon works correctly.
    r      rz   rC   rj   eomTF)r   cluster_selection_epsiloncluster_selection_methodallow_single_clusterrE   )return_countsr      g
ףp=
?r   )r   r   r   r   rw   rE   N)r?   randomRandomStaterandr   r_   uniquer,   )rngno_structurer0   unique_labelscountss        r&   .test_hdbscan_allow_single_cluster_with_epsilonr   G  sA    )


"
"C88C##L"%!&!   k,  IfDAAAM6}"""" -2%&++++ "&!&!   k,  IfDAAAM6}""""-2%&!++++++r(   c                  6   ddgddgddgddgg} t          d| g dd          \  }}t          d	
                              |          j        }t	          t          |                    t          d|v           z
  }|dk    sJ t          ||          dk     dS )z
    Validate that HDBSCAN can properly cluster this difficult synthetic
    dataset. Note that DBSCAN fails on this (see HDBSCAN plotting
    example)
    g333333g333333?r+   i  )皙?gffffff?皙?r   r   )r   r   r   r   FrD   r      r)   N)r
   r   rJ   rK   r,   r-   intr   )r   rI   r/   r0   r2   s        r&   test_hdbscan_better_than_dbscanr   j  s     u~t}q!fq"g>G+++	  DAq %   $$Q''/FS[[!!Cf$5$55J????&!$$t++++r(   z	kwargs, XrZ   rB   rz   r+   r   c                 J    t          dddd|                    |            dS )zo
    Tests that HDBSCAN works correctly for array-likes and precomputed inputs
    with non-finite points.
    rB   Fmin_samplesrE   Nr"   )r   rJ   )rI   kwargss     r&   test_hdbscan_usable_inputsr   ~  s3     0000044Q77777r(   c                      | t          j        d                    }d}t          j        t          |          5  t          dd                              |           ddd           dS # 1 swxY w Y   dS )zd
    Tests that HDBSCAN raises the correct error when there are too few
    non-zero distances.
    )r   r   z#There exists points with fewer thanr]   rZ   Fr[   N)r?   zerosr`   ra   rb   r   rJ   r   rI   re   s      r&   -test_hdbscan_sparse_distances_too_few_nonzeror     s     	bhx(())A
/C	z	-	-	- 9 9}511155a8889 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9s   %A--A14A1c                 8   t          j        d          }d|ddddf<   d|ddddf<   ||j        z   } | |          }d}t          j        t
          |          5  t          dd	
                              |           ddd           dS # 1 swxY w Y   dS )zu
    Tests that HDBSCAN raises the correct error when the distance matrix
    has multiple connected components.
    )   r   rB   NrC      z3HDBSCAN cannot be performed on a disconnected graphr]   rZ   Fr[   )r?   r   Tr`   ra   rb   r   rJ   r   s      r&   0test_hdbscan_sparse_distances_disconnected_graphr     s     	AAbqb"1"fIAabb"##gJ	ACAaA
?C	z	-	-	- 9 9}511155a8889 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9s   %BBBc                     d } d}t          j        t          |          5  t          d| d                              t
                     ddd           n# 1 swxY w Y   t          j        t          |          5  t          d| d                              t
                     ddd           n# 1 swxY w Y   t          t          t          j	                  t          t          j	                  z
            }t          |          d	k    rft          j        t          |          5  t          d|d	         d                              t
                     ddd           dS # 1 swxY w Y   dS dS )
zR
    Tests that HDBSCAN correctly raises an error for invalid metric choices.
    c                     | S r:   r"   )r<   s    r&   r=   z2test_hdbscan_tree_invalid_metric.<locals>.<lambda>  s     r(   zV.* is not a valid metric for a .*-based algorithm\. Please select a different metric\.r]   r   F)rw   r\   rE   Nr   r   )r`   ra   rb   r   rJ   rI   rN   r-   r   r   r   r,   )metric_callablere   metrics_not_kds      r&    test_hdbscan_tree_invalid_metricr     sN    "kO	  
z	-	-	- P P)O%HHHLLQOOOP P P P P P P P P P P P P P P	z	-	-	- R R+oEJJJNNqQQQR R R R R R R R R R R R R R R
 #h455F<P8Q8QQRRN
>Q]:S111 	V 	Viq0ANNNRRSTUUU	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V s5   +AAA>+B55B9<B9.1E,,E03E0c                      t          t          t                    dz   d          } d}t          j        t
          |          5  |                     t                     ddd           dS # 1 swxY w Y   dS )zx
    Tests that HDBSCAN correctly raises an error when setting `min_samples`
    larger than the number of samples.
    rB   Fr   z min_samples (.*) must be at mostr]   N)r   r,   rI   r`   ra   rb   rJ   )r   re   s     r&   !test_hdbscan_too_many_min_samplesr     s    
 c!ffqju
5
5
5C
-C	z	-	-	-  


                 s   A,,A03A0c                     t                                           } t          j        | d<   d}t	          dd          }t          j        t          |          5  |                    |            ddd           dS # 1 swxY w Y   dS )zu
    Tests that HDBSCAN correctly raises an error when providing precomputed
    distances with `np.nan` values.
    r   z(np.nan values found in precomputed-denserZ   Fr[   r]   N)	rI   rE   r?   rH   r   r`   ra   rb   rJ   )X_nanre   r   s      r&   "test_hdbscan_precomputed_dense_nanr     s    
 FFHHE&E$K
4C
U
3
3
3C	z	-	-	-                   s   A::A>A>r   TFepsilonr   c                 4   d}t          || ddgddgddgg          \  }t          d                              |          }t          |j        |j                  }|dz   |d	z   |d
z   h}|dz   d|d	z   d|d
z   di}t          |||||          fdt          t                              D             fdt          t                              D             }	 t          j
        |	j                            }
t          |
           dS )zR
    Tests that the `_do_labelling` helper function correctly assigns labels.
    0   r   r   )r   r   FrD   r   rz   r+   r   rB   condensed_treeclusterscluster_label_mapr   r   c                 Z    i | ]'}|t          j        |k              d          d          (S )r   )r?   where)r#   _yr/   s     r&   
<dictcomp>z+test_labelling_distinct.<locals>.<dictcomp>  s3    KKKBHQ"W--a03KKKr(   c                 .    i | ]}||                  S r"   r"   )r#   r  first_with_labelr0   s     r&   r  z+test_labelling_distinct.<locals>.<dictcomp>  s&    KKK2v.r23KKKr(   N)r
   r   rJ   r   _single_linkage_tree_r   r   rN   r-   r?   	vectorizer   r   )global_random_seedr   r   r   rI   estr   r   r  y_to_labelsaligned_targetr  r0   r/   s              @@@r&   test_labelling_distinctr    sc    I' FGG
		 	 	DAq u



!
!!
$
$C#!C4H  N Ay1}i!m<H"Q9q=!Y]AN%+1")  F LKKKd3q66llKKKKKKKKd3q66llKKKK2R\+/22155Nv~.....r(   c                     d} d}t          j        dd|dfddd|dfddgt          	          }t          || h| d| dz   did
d          }|d         dk     }t	          |          t	          |dk              k    sJ t          || h| d| dz   did
d          }|d         |k     }t	          |          t	          |dk              k    sJ dS )z
    Tests that the `_do_labelling` helper function correctly thresholds the
    incoming lambda values given various `cluster_selection_epsilon` values.
    rC   g      ?rz   rB   )rC   rB   r   rB   r   )rC   r+   r   rB   )rC   r   r   rB   )dtypeTr   valuer   N)r?   arrayr   r   sum)r   
MAX_LAMBDAr   r0   	num_noises        r&   test_labelling_thresholdingr    s#   
 IJX:q!:q!	
 	 	 	N %$aQ:!"#  F w'!+Iy>>S2......%$aQ:!"#  F w'*4Iy>>S2........r(   r   r   r   c                 B   t           j                            d          }|                    d          }t          |          }d}t	          j        t          |          5  t          d| d                              |           ddd           dS # 1 swxY w Y   dS )	zCheck that we raise an error if the centers are requested together with
    a precomputed input matrix.

    Non-regression test for:
    https://github.com/scikit-learn/scikit-learn/issues/27893
    r   d   rz   z>Cannot store centers when using a precomputed distance matrix.r]   rZ   F)r\   r   rE   N)	r?   r   r   r   r`   ra   rb   r   rJ   )r   r   rI   X_disterr_msgs        r&   0test_hdbscan_error_precomputed_and_store_centersr  +  s     )


"
"C

8A ##FNG	z	1	1	1   '	
 	
 	
 #f+++                 s   !&BBB
valid_algor   r   c                 Z    t          d| d                              t                     dS )zTest that HDBSCAN works with the "cosine" metric when the algorithm is set
    to "brute" or "auto".

    Non-regression test for issue #28631
    cosineFr   N)r   r_   rI   )r  s    r&   *test_hdbscan_cosine_metric_valid_algorithmr   ?  s-     8z>>>JJ1MMMMMr(   invalid_algoc                     t          d| d          }t          j        t          d          5  |                    t
                     ddd           dS # 1 swxY w Y   dS )zTest that HDBSCAN raises an informative error is raised when an unsupported
    algorithm is used with the "cosine" metric.
    r  Fr   zcosine is not a valid metricr]   N)r   r`   ra   rb   r_   rI   )r!  hdbscans     r&   ,test_hdbscan_cosine_metric_invalid_algorithmr$  I  s    
 XEJJJG	z)G	H	H	H  A                 s   AAAc                      t           j                            d                              d          } d}t          j        t
          |          5  t          d          }|                    |            ddd           dS # 1 swxY w Y   dS )z\
    Test that HDBSCAN raises a FutureWarning when the `copy`
    parameter is not set.
    r   r  zCThe default value of `copy` will change from False to True in 1.10.r]   r   r   N)r?   r   r   r`   r   r   r   rJ   )rI   re   r   s      r&   !test_hdbscan_default_copy_warningr&  T  s    
 		a  ''11A
PC	m3	/	/	/  r***


                 s   &BB
B)r)   )K__doc__numpyr?   r`   scipyr   scipy.spatialr   sklearn.clusterr   sklearn.cluster._hdbscan._treer   r   r    sklearn.cluster._hdbscan.hdbscanr	   sklearn.datasetsr
   sklearn.metricsr   sklearn.metrics.pairwiser   r   sklearn.neighborsr   r   sklearn.preprocessingr   sklearn.utilsr   sklearn.utils._testingr   r   sklearn.utils.fixesr   r   rI   r/   fit_transform
ALGORITHMSitemsr.   r3   markparametrizerX   rf   rq   rt   r   r   r   r   r   r   r   r   r   r   r   r   r  rG   r   r   r   r   r   r   r  r  r  r   r$  r&  r"   r(   r&   <module>r;     s(   
            " " " " " " # # # # # #         
 ? > > > > > ' ' ' ' ' ' 1 1 1 1 1 1 H H H H H H H H . . . . . . . . 0 0 0 0 0 0 ! ! ! ! ! ! F F F F F F F F > > > > > > > >zCb1111wq!!$$$1N""1%%  
 dKK1H1B1H1J1JKKKK8 8 8 8 ):;;J J <;J>A A A0 -/Q/Q./QRR    SR "	  	  	  ,,>22% % 32 -,%P
0 
0 
0 778 8 8784     - - -	H 	H 	H      )[!9::  ;: .99U U :9UD j11& & 21&0 ,  ,  ,F, , ,( 
M	"HBHq"&kBFA;-G$H$HI
M	"aVaV$45	q!fq!f 8 8 8 .99	9 	9 :9	9 .999 9 :99 V V V0  
 
 
 /$??QH--!/ !/ .- @?!/H&/ &/ &/R :x*@AA  BA& '899N N :9N )[)ABB  CB	 	 	 	 	r(   