genefilter/.Rinstignore0000644000175100017510000000002714614230661016224 0ustar00biocbuildbiocbuilddoc/whbiocvignette.sty genefilter/build/0000755000175100017510000000000014614336167015030 5ustar00biocbuildbiocbuildgenefilter/build/vignette.rds0000644000175100017510000000057014614336167017371 0ustar00biocbuildbiocbuildRQK0:@Px L}E&c MҤ$uo>u^tsu̇ommAswf*j$Ln$݀βDH;) N 2ܽ r%*p 5iZµ%)Y9B-= 1.11.1), AnnotationDbi, annotate, Biobase, graphics, methods, stats, survival, grDevices License: Artistic-2.0 LazyLoad: yes LazyData: yes Collate: AllClasses.R AllGenerics.R all.R dist2.R eSetFilter.R fastT.R filter_volcano.R filtered_p.R genefinder.R half.range.mode.R kappa_p.R nsFilter.R rejection_plot.R rowROC-accessors.R rowSds.R rowpAUCs-methods.R rowttests-methods.R shorth.R zzz.R biocViews: Microarray VignetteBuilder: knitr git_url: https://git.bioconductor.org/packages/genefilter git_branch: RELEASE_3_19 git_last_commit: 43d41cb git_last_commit_date: 2024-04-30 Repository: Bioconductor 3.19 Date/Publication: 2024-04-30 NeedsCompilation: yes Packaged: 2024-05-01 03:52:23 UTC; biocbuild Author: Robert Gentleman [aut], Vincent J. Carey [aut], Wolfgang Huber [aut], Florian Hahne [aut], Emmanuel Taiwo [ctb] ('howtogenefinder' vignette translation from Sweave to RMarkdown / HTML.), Khadijah Amusat [ctb] (Converted genefilter vignette from Sweave to RMarkdown / HTML.), Bioconductor Package Maintainer [cre] Maintainer: Bioconductor Package Maintainer genefilter/docs/0000755000175100017510000000000014614230661014651 5ustar00biocbuildbiocbuildgenefilter/docs/Cluster.pdf0000644000175100017510000000056214614230661016770 0ustar00biocbuildbiocbuild%PDF-1.2 % 2 0 obj << /Length 6114 /Filter /FlateDecode >> stream HrίA. HYJ[Yt|s#1>, BKJ̠wnZ"Y:,grS._~{tv؎.7wNm@zXBSM4Wm~ ;g]ȭUx~/7H"$rzS]>FV ޼ZXJwy^mF].rC;!/V1 fzo;[Rũ[Cedy/ԉVWuoyݶy]]xcUvzW5q4Xs\XX,Fs' ,1genefilter/docs/gcluster.tex0000644000175100017510000000322314614230661017223 0ustar00biocbuildbiocbuildNotes from Cheng Li, on what he does for clustering: I basically followed the methods in the attached paper (page 2, upper-right corner). it's not the standard avarage linkage, instead, after two genes (or nodes) are merged, the resultant node has expression profile as the avereage the the two merged ones (after standardization). A description for anther project using dchip is as follows: Hierarchical clustering analysis (3) is used to group genes with same expression pattern. A genes is selected for clustering if (1) its expression values in the 20 samples has coefficient of variation (standard deviation / mean) between 0.5 to 10 (2) it is called Present by GeneChip? in more than 5 samples. Then the expression values for a gene across the 20 samples are standardized to have mean 0 and standard deviation 1 by linear transformation, and the distance between two genes is defined as 1 - r where r is the standard correlation coefficient between the 20 standardize values of two genes. Two genes with the closest distance are first merged into a super-gene and connected by branches with length representing their distance, and are deleted for future merging. The expression level of the newly formed super-gene is the average of standardized expression levels of the two genes (average-linkage) for each sample. Then the next pair of genes (super-genes) with the smallest distance are chosen to merge and the process is repeated until all genes are merged into one cluster. The dendrogram in Figure ? illustrates the final clustering tree, where genes close to each other have high similarity in their standardized expression values across the 20 samples. genefilter/docs/gfilter.tex0000644000175100017510000002166014614230661017034 0ustar00biocbuildbiocbuild\documentclass{article} \begin{document} \title{Using Genefilter} \author{Robert Gentleman \thanks{rgentlem@hsph.harvard.edu} } \date{} \maketitle \section{An extended example} Consider an experiment to explore genes that are induced by cellular contact with a ligand (we will call the ligand F). The receptors are known to transduce intracellular signals when the cell is placed in contact with F. We want to determine which genes are involved in the process. The experiment was designed to use two substrates, F and an inert substance that will be referred to as P. A large number of cells were cultured and then separated and one batch was applied to F while the other was applied to P. For both conditions cells were harvested at the times, 0, 1 hour, 3 hours and 8 hours. Those cells were processed and applied to Affymetrix U95Av2 chips. This process yielded expression level estimates for the 12,600 genes or ESTs measured by that chip. The goal of the analysis is to produce a list of genes (possibly in some rank order) that have patterns of expression that are different in the two subsets (those cells applied to F versus those cells applied to P). If there were just a few genes then we might try to select the interesting ones by using a linear model (or some other model that was more appropriate). In the subsequent discussion the form of the model is irrelevant and the linear model will be used purely for pedagogical reasons. Let $y_{ij}$ denote the expression level of a particular gene in contact with substrate $i$, ($i$ will be either F or P) at time $j$, ($j$ is one of 0,1,3,8). Suppose that in consultation with the biologists we determine that a gene is interesting if the coeffecient for time, in a linear model, is different in the two subsets. This can easily be done (for a small handful of genes) using a linear model. Let $a$ denote the substrate and $b$ denote the times. Further we assume that the expression data is presented in a matrix with 12,600 rows and 8 columns. Further assume that the columns contain the data in the order F0, F1, F3, F8, P0, P1, P3, P8. Then we can fit the model using the following R code. \begin{verbatim} a <- as.factor(c(rep("F",4), rep("P",4))) b <- c(0,1,3,8,0,1,3,8) data1 <- data.frame(a,b) f1 <- y~a/b-1 f2 <- y~a+b \end{verbatim} The model \verb+f1+ fits separate regressions on \verb+b+ within levels of \verb+b+. The model \verb+f2+ fits a parallel lines regression model. So comparing these two models via: \begin{verbatim} fit1 <- lm(f1, data1) fit2 <- lm(f2, data1) an1 <- anova(fit1, fit2) an1 \end{verbatim} From \verb+an1+ we can obtain the F--test statistic for comparing the two models. We would reject the hypothesis that the slopes of the two lines were the same if this $p$--value were sufficiently small (and all of our diagnostic tests confirmed that the model was appropriate). In the current setting with 12,600 genes it is not feasible to consider carrying out this process by hand and thus we need some automatic procedure for carrying it out. To do that we rely on some special functionality in R that is being used more and more to provide easy to use programs for complex problems (such as the current one). See the {\em Environments} section to get a better understanding of the use of environments in R. First we provide the code that will create an environment, associate it with both \verb+f1+ and \verb+f2+ and populate it with the variables \verb+a+ and \verb+b+. \begin{verbatim} e1 <- new.env() assign("a", a, env=e1) assign("b", b, env=e1) environment(f1) <- e1 environment(f2) <- e1 \end{verbatim} Now the two formulas share the environment \verb+e1+ and all the variable bindings in it. We have not assigned any value to \verb+y+ for our formulas though. The reason for that is that \verb+a+ and \verb+b+ are the same for each gene we want to test but \verb+y+ will change. We now consider an abstract (or algorithmic) version of what we need to do for each gene. Our ultimate goal is to produce a function that takes a single argument, \verb+x+, the expression levels for a gene and returns either \verb+TRUE+ indicating that the gene is interesting or \verb+FALSE+ indicating that the gene is uninteresting. \begin{itemize} \item For each gene we need to assign the expression levels for that gene to the variable \verb+y+ in the environment \verb+e1+. \item We fit both models \verb+f1+ and \verb+f2+. \item We compute the anova comparing these two models. \item We determine whether according to some criteria the large model is needed (and hence in this case that the slopes for the expression are different in the two substrates). If so we output \verb+TRUE+ otherwise we output \verb+FALSE+. \end{itemize} To operationalize this (and to make it easier to extend the ideas to more complex settings) we construct a closure to carry out this task. \begin{verbatim} make3fun <- function(form1, form2, p) { e1 <- environment(form1) #if( !identical(e1, environment(form2)) ) # stop("form1 and form2 must share the same environment") function(x) { assign("y", x, env=e1) fit1 <- lm(form1) fit2 <- lm(form2) an1 <- anova(fit1, fit2) if( an1$"Pr(>F)"[2] < p ) return(TRUE) else return(FALSE) } } \end{verbatim} %$ The function, \verb+make3fun+ is quite simple. It takes two formulas and a $p$--value as arguments. It checks to see that the formulas share an environment and then creates and returns a function of one argument. That function carries out all the fitting and testing for us. It is worth pointing out that the returned function is called a {\em closure} and that it makes use of some of the special properties of environments that are discussed below. Now we can create the function that we will use to call apply. We do this quite simply with: \begin{verbatim} myappfun <- make3fun(f1, f2, 0.01) myappfun function(x) { assign("y", x, env=e1) fit1 <- lm(form1) fit2 <- lm(form2) an1 <- anova(fit1, fit2) if( an1$"Pr(>F)"[2] < p ) return(TRUE) else return(FALSE) } \end{verbatim} %$ Thus, \verb+myappfun+ is indeed a function of one argument. It carries out the three steps we outlined above and will return \verb+TRUE+ if the $p$--value for comparing the model in \verb+f1+ to that in \verb+f2+ is less than $0.01$. If we assume that the data are stored in a data frame called \verb+gene.exprs+ then we can find the interesting ones using the following line of code. \begin{verbatim} interesting.ones <- apply(gene.exprs, 1, myappfun) \end{verbatim} The real advantage of this approach is that it extends simply (or trivially) to virtually any model comparison that can be represented or carried out in R. \section{Environments} In R an environment can be thought of as a table. The table contains a list of symbols that are linked to a list of values. There are only a couple of operations that you need to carry out on environments. One is to give the name of a symbol and get the associated value. The other is to set the value for a symbol to some supplied value. The following code shows some simple manipulations that you can do. \begin{verbatim} > e1 <- new.env() > ls(env=e1) character(0) > ls() [1] "a" "an1" "b" "data1" "e1" "f1" "f2" "fit1" "fit2" [10] "y" > #this ls() lists the objects in my workspace (which is itself > # an environment; it gets searched by default > assign("a", 4, env=e1) > #this assigns the value 4 to the symbol a in e1 > #it has no effect on a in my workspace > a [1] F F F F P P P P Levels: F P > get("a",env=e1) [1] 4 > #so the a in env1 is separate and protected from the a in my > # workspace \end{verbatim} In R every formula has an associated environment. This environment is used to provide bindings (or values) for the symbols in the formula. When we write \verb=y~a+x= we have in mind some values to associate with \verb+y+, \verb+a+ and \verb+x+. We can use an environment to specify these. \begin{verbatim} substrate <- c(1,1,1,1,2,2,2,2) time <- c(0,1,3,8,0,1,3,8) response <- rnorm(8) assign("a", substrate, env=e1) assign("b", time, env=e1) assign("y", response, env=e1) environment(f1) <- e1 environment(f2) <- e1 \end{verbatim} Now, both of our formulas (from section 1) share the environment \verb+e1+ and both can be used in any modeling context without specifying the data; it will be obtained automatically from the environment. \section{A weighted analysis} The Li and Wong (2000) algorithm for estimating expression levels for gene chip samples also provides an estimate of the standard error of the expression level. These estimated standard errors can potentially be used in the analysis of the data. For example, since we have observations of the form $Y_i, \hat{\sigma}_i$ we could consider taking weighted averages, within groups. The weights would be determined by the estimated standard errors. \end{document} genefilter/inst/0000755000175100017510000000000014614336167014706 5ustar00biocbuildbiocbuildgenefilter/inst/doc/0000755000175100017510000000000014614336167015453 5ustar00biocbuildbiocbuildgenefilter/inst/doc/howtogenefilter.html0000644000175100017510000234252014614336155021553 0ustar00biocbuildbiocbuild Using the genefilter function to filter genes from a microarray dataset

Contents

1 Introduction

The genefilter package can be used to filter (select) genes from a microarray dataset according to a variety of different filtering mechanisms. Here, we will consider the example dataset in the sample.ExpressionSet example from the Biobase package. This experiment has 26 samples, and there are 500 genes and 3 covariates. The covariates are named sex, type and score. The first two have two levels and the last one is continuous.

library("Biobase") 
library("genefilter")
data(sample.ExpressionSet)
varLabels(sample.ExpressionSet)
## [1] "sex"   "type"  "score"
table(sample.ExpressionSet$sex)
## 
## Female   Male 
##     11     15
table(sample.ExpressionSet$type)
## 
##    Case Control 
##      15      11

One dichotomy that can be of interest for subsequent analyses is whether the filter is specific or non-specific. Here, specific means that we are filtering with reference to sample metadata, for example, type. For example, if we want to select genes that are differentially expressed in the two groups defined by type, that is a specific filter. If on the other hand we want to select genes that are expressed in more than 5 samples, that is an example of a non–specific filter.

First, let us see how to perform a non–specific filter. Suppose we want to select genes that have an expression measure above 200 in at least 5 samples. To do that we use the function kOverA.

There are three steps that must be performed.

  1. Create function(s) implementing the filtering criteria.

  2. Assemble it (them) into a (combined) filtering function.

  3. Apply the filtering function to the expression matrix.

f1 <- kOverA(5, 200)
ffun <- filterfun(f1)
wh1 <- genefilter(exprs(sample.ExpressionSet), ffun)
sum(wh1)
## [1] 159

Here f1 is a function that implies our “expression measure above 200 in at least 5 samples” criterion, the function ffun is the filtering function (which in this case consists of only one criterion), and we apply it using r Biocpkg("genefilter"). There were 159 genes that satisfied the criterion and passed the filter. As an example for a specific filter, let us select genes that are differentially expressed in the groups defined by type.

f2 <- ttest(sample.ExpressionSet$type, p=0.1)
wh2 <- genefilter(exprs(sample.ExpressionSet), filterfun(f2))
sum(wh2)
## [1] 88

Here, ttest is a function from the genefilter package which provides a suitable wrapper around t.test from package stats. Now we see that there are 88 genes that satisfy the selection criterion. Suppose that we want to combine the two filters. We want those genes for which at least 5 have an expression measure over 200 and which also are differentially expressed between the groups defined by type

ffun_combined <- filterfun(f1, f2)
wh3 <- genefilter(exprs(sample.ExpressionSet), ffun_combined)
sum(wh3)
## [1] 35

Now we see that there are only 35 genes that satisfy both conditions.

1.1 Selecting genes that appear useful for prediction

The function knnCV defined below performs \(k\)–nearest neighbour classification using leave–one–out cross–validation. At the same time it aggregates the genes that were selected. The function returns the predicted classifications as its returned value. However, there is an additional side effect. The number of times that each gene was used (provided it was at least one) are recorded and stored in the environment of the aggregator Agg. These can subsequently be retrieved and used for other purposes.

knnCV <- function(x, selectfun, cov, Agg, pselect = 0.01, scale=FALSE) {
   nc <- ncol(x)
   outvals <- rep(NA, nc)
   for(i in seq_len(nc)) {
      v1 <- x[,i]
      expr <- x[,-i]
      glist <- selectfun(expr, cov[-i], p=pselect)
      expr <- expr[glist,]
      if( scale ) {
        expr <- scale(expr)
        v1 <- as.vector(scale(v1[glist]))
      }
      else
         v1 <- v1[glist]
      out <- paste("iter ",i, " num genes= ", sum(glist), sep="")
      print(out)
      Aggregate(row.names(expr), Agg)
      if( length(v1) == 1)
         outvals[i] <- knn(expr, v1, cov[-i], k=5)
      else
          outvals[i] <- knn(t(expr), v1, cov[-i], k=5)
    }
    return(outvals)
}
gfun <- function(expr, cov, p=0.05) {
   f2 <- ttest(cov, p=p)
   ffun <- filterfun(f2)
   which <- genefilter(expr, ffun)
  }

Next we show how to use this function on the dataset geneData

library("class")
##scale the genes
##genescale is a slightly more flexible "scale"
##work on a subset -- for speed only
geneData <- genescale(exprs(sample.ExpressionSet)[1:75,], 1) 
Agg <- new("aggregator") 
testcase <- knnCV(geneData, gfun, sample.ExpressionSet$type, 
       Agg,pselect=0.05)  
sort(sapply(aggenv(Agg), c), decreasing=TRUE)
##          AFFX-MurIL4_at         AFFX-TrpnX-M_at         AFFX-hum_alu_at 
##                      26                      26                      26 
##        AFFX-YEL018w/_at                31308_at          AFFX-PheX-M_at 
##                      20                      15                      15 
##                31312_at          AFFX-BioC-3_st AFFX-HUMRGE/M10098_M_at 
##                       3                       3                       1 
##          AFFX-DapX-5_at         AFFX-TrpnX-5_at         AFFX-BioDn-5_at 
##                       1                       1                       1 
##          AFFX-PheX-5_at 
##                       1

The environment Agg contains, for each gene, the number of times it was selected in the cross-validation.

2 Session Information

The version number of R and packages loaded for generating the vignette were:

## R version 4.4.0 beta (2024-04-15 r86425)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 22.04.4 LTS
## 
## Matrix products: default
## BLAS:   /home/biocbuild/bbs-3.19-bioc/R/lib/libRblas.so 
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## time zone: America/New_York
## tzcode source: system (glibc)
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] class_7.3-22        genefilter_1.86.0   Biobase_2.64.0     
## [4] BiocGenerics_0.50.0 BiocStyle_2.32.0   
## 
## loaded via a namespace (and not attached):
##  [1] sass_0.4.9              lattice_0.22-6          RSQLite_2.3.6          
##  [4] digest_0.6.35           evaluate_0.23           grid_4.4.0             
##  [7] bookdown_0.39           fastmap_1.1.1           blob_1.2.4             
## [10] jsonlite_1.8.8          Matrix_1.7-0            AnnotationDbi_1.66.0   
## [13] GenomeInfoDb_1.40.0     DBI_1.2.2               survival_3.6-4         
## [16] BiocManager_1.30.22     httr_1.4.7              UCSC.utils_1.0.0       
## [19] XML_3.99-0.16.1         Biostrings_2.72.0       jquerylib_0.1.4        
## [22] cli_3.6.2               rlang_1.1.3             crayon_1.5.2           
## [25] XVector_0.44.0          bit64_4.0.5             splines_4.4.0          
## [28] cachem_1.0.8            yaml_2.3.8              tools_4.4.0            
## [31] memoise_2.0.1           annotate_1.82.0         GenomeInfoDbData_1.2.12
## [34] vctrs_0.6.5             R6_2.5.1                png_0.1-8              
## [37] matrixStats_1.3.0       stats4_4.4.0            lifecycle_1.0.4        
## [40] zlibbioc_1.50.0         KEGGREST_1.44.0         S4Vectors_0.42.0       
## [43] IRanges_2.38.0          bit_4.0.5               bslib_0.7.0            
## [46] xfun_0.43               MatrixGenerics_1.16.0   knitr_1.46             
## [49] xtable_1.8-4            htmltools_0.5.8.1       rmarkdown_2.26         
## [52] compiler_4.4.0
genefilter/inst/doc/howtogenefilter.R0000644000175100017510000000454314614336155021006 0ustar00biocbuildbiocbuild## ----closeg, message = FALSE-------------------------------------------------- library("Biobase") library("genefilter") data(sample.ExpressionSet) varLabels(sample.ExpressionSet) table(sample.ExpressionSet$sex) table(sample.ExpressionSet$type) ## ----message=FALSE------------------------------------------------------------ f1 <- kOverA(5, 200) ffun <- filterfun(f1) wh1 <- genefilter(exprs(sample.ExpressionSet), ffun) sum(wh1) ## ----------------------------------------------------------------------------- f2 <- ttest(sample.ExpressionSet$type, p=0.1) wh2 <- genefilter(exprs(sample.ExpressionSet), filterfun(f2)) sum(wh2) ## ----gene-indexing------------------------------------------------------------ ffun_combined <- filterfun(f1, f2) wh3 <- genefilter(exprs(sample.ExpressionSet), ffun_combined) sum(wh3) ## ----knnCV-------------------------------------------------------------------- knnCV <- function(x, selectfun, cov, Agg, pselect = 0.01, scale=FALSE) { nc <- ncol(x) outvals <- rep(NA, nc) for(i in seq_len(nc)) { v1 <- x[,i] expr <- x[,-i] glist <- selectfun(expr, cov[-i], p=pselect) expr <- expr[glist,] if( scale ) { expr <- scale(expr) v1 <- as.vector(scale(v1[glist])) } else v1 <- v1[glist] out <- paste("iter ",i, " num genes= ", sum(glist), sep="") print(out) Aggregate(row.names(expr), Agg) if( length(v1) == 1) outvals[i] <- knn(expr, v1, cov[-i], k=5) else outvals[i] <- knn(t(expr), v1, cov[-i], k=5) } return(outvals) } ## ----aggregate1--------------------------------------------------------------- gfun <- function(expr, cov, p=0.05) { f2 <- ttest(cov, p=p) ffun <- filterfun(f2) which <- genefilter(expr, ffun) } ## ----aggregate2, results="hide"----------------------------------------------- library("class") ##scale the genes ##genescale is a slightly more flexible "scale" ##work on a subset -- for speed only geneData <- genescale(exprs(sample.ExpressionSet)[1:75,], 1) Agg <- new("aggregator") testcase <- knnCV(geneData, gfun, sample.ExpressionSet$type, Agg,pselect=0.05) ## ----aggregate3--------------------------------------------------------------- sort(sapply(aggenv(Agg), c), decreasing=TRUE) ## ----echo=FALSE--------------------------------------------------------------- sessionInfo() genefilter/inst/doc/howtogenefilter.Rmd0000644000175100017510000001301414614230661021313 0ustar00biocbuildbiocbuild--- title: "Using the genefilter function to filter genes from a microarray dataset" author: - name: "Khadijah Amusat" affiliation: "Vignette translation from Sweave to R Markdown / HTML" date: "`r format(Sys.time(), '%B %d , %Y')`" output: BiocStyle::html_document: number_sections: true toc: true toc_depth: 4 package: genefilter vignette: > %\VignetteIndexEntry{Using the genefilter function to filter genes from a microarray} %\VignetteEncoding{UTF-8} %\VignetteEngine{knitr::rmarkdown} --- # Introduction The `r Biocpkg("genefilter")` package can be used to filter (select) genes from a microarray dataset according to a variety of different filtering mechanisms. Here, we will consider the example dataset in the `sample.ExpressionSet` example from the `r Biocpkg("Biobase")` package. This experiment has 26 samples, and there are 500 genes and 3 covariates. The covariates are named `sex`, `type` and `score`. The first two have two levels and the last one is continuous. ```{r closeg, message = FALSE} library("Biobase") library("genefilter") data(sample.ExpressionSet) varLabels(sample.ExpressionSet) table(sample.ExpressionSet$sex) table(sample.ExpressionSet$type) ``` One dichotomy that can be of interest for subsequent analyses is whether the filter is *specific* or *non-specific*. Here, specific means that we are filtering with reference to sample metadata, for example, `type`. For example, if we want to select genes that are differentially expressed in the two groups defined by `type`, that is a specific filter. If on the other hand we want to select genes that are expressed in more than 5 samples, that is an example of a non--specific filter. First, let us see how to perform a non--specific filter. Suppose we want to select genes that have an expression measure above 200 in at least 5 samples. To do that we use the function `kOverA`. There are three steps that must be performed. 1. Create function(s) implementing the filtering criteria. 2. Assemble it (them) into a (combined) filtering function. 3. Apply the filtering function to the expression matrix. ```{r message=FALSE} f1 <- kOverA(5, 200) ffun <- filterfun(f1) wh1 <- genefilter(exprs(sample.ExpressionSet), ffun) sum(wh1) ``` Here `f1` is a function that implies our "expression measure above 200 in at least 5 samples" criterion, the function `ffun` is the filtering function (which in this case consists of only one criterion), and we apply it using `r Biocpkg("genefilter")`. There were `r sum(wh1)` genes that satisfied the criterion and passed the filter. As an example for a specific filter, let us select genes that are differentially expressed in the groups defined by `type`. ```{r} f2 <- ttest(sample.ExpressionSet$type, p=0.1) wh2 <- genefilter(exprs(sample.ExpressionSet), filterfun(f2)) sum(wh2) ``` Here, `ttest` is a function from the `r Biocpkg("genefilter")` package which provides a suitable wrapper around `t.test` from package `r Rpackage("stats")`. Now we see that there are `r sum(wh2)` genes that satisfy the selection criterion. Suppose that we want to combine the two filters. We want those genes for which at least 5 have an expression measure over 200 *and* which also are differentially expressed between the groups defined by `type` ```{r gene-indexing} ffun_combined <- filterfun(f1, f2) wh3 <- genefilter(exprs(sample.ExpressionSet), ffun_combined) sum(wh3) ``` Now we see that there are only `r sum(wh3)` genes that satisfy both conditions. ## Selecting genes that appear useful for prediction The function `knnCV` defined below performs $k$--nearest neighbour classification using leave--one--out cross--validation. At the same time it aggregates the genes that were selected. The function returns the predicted classifications as its returned value. However, there is an additional side effect. The number of times that each gene was used (provided it was at least one) are recorded and stored in the environment of the aggregator `Agg`. These can subsequently be retrieved and used for other purposes. ```{r knnCV} knnCV <- function(x, selectfun, cov, Agg, pselect = 0.01, scale=FALSE) { nc <- ncol(x) outvals <- rep(NA, nc) for(i in seq_len(nc)) { v1 <- x[,i] expr <- x[,-i] glist <- selectfun(expr, cov[-i], p=pselect) expr <- expr[glist,] if( scale ) { expr <- scale(expr) v1 <- as.vector(scale(v1[glist])) } else v1 <- v1[glist] out <- paste("iter ",i, " num genes= ", sum(glist), sep="") print(out) Aggregate(row.names(expr), Agg) if( length(v1) == 1) outvals[i] <- knn(expr, v1, cov[-i], k=5) else outvals[i] <- knn(t(expr), v1, cov[-i], k=5) } return(outvals) } ``` ```{r aggregate1} gfun <- function(expr, cov, p=0.05) { f2 <- ttest(cov, p=p) ffun <- filterfun(f2) which <- genefilter(expr, ffun) } ``` Next we show how to use this function on the dataset `geneData` ```{r aggregate2, results="hide"} library("class") ##scale the genes ##genescale is a slightly more flexible "scale" ##work on a subset -- for speed only geneData <- genescale(exprs(sample.ExpressionSet)[1:75,], 1) Agg <- new("aggregator") testcase <- knnCV(geneData, gfun, sample.ExpressionSet$type, Agg,pselect=0.05) ``` ```{r aggregate3} sort(sapply(aggenv(Agg), c), decreasing=TRUE) ``` The environment `Agg` contains, for each gene, the number of times it was selected in the cross-validation. # Session Information The version number of R and packages loaded for generating the vignette were: ```{r echo=FALSE} sessionInfo() ``` genefilter/inst/doc/howtogenefinder.html0000644000175100017510000233447414614336156021547 0ustar00biocbuildbiocbuild howtogenefinder.knit

Contents

1 Introduction

In some cases you have certain genes of interest and you would like to find other genes that are close to the genes of interest. This can be done using the genefinder function.

You need to specify either the index position of the genes you want (which row of the expression array the gene is in) or the name (consistent with the featureNames of the ExpressionSet).

A vector of names can be specified and matches for all will be computed. The number of matches and the distance measure used can all be specified. The examples will be carried out using the artificial data set, sample.ExpressionSet.

Two other options for genefinder are scale and method. The scale option controls the scaling of the rows (this is often desirable), while the method option controls the distance measure used between genes. The possible values and their meanings are listed at the end of this document.

library("Biobase")
library("genefilter")
data(sample.ExpressionSet)
igenes <- c(300,333,355,419) ##the interesting genes
closeg <- genefinder(sample.ExpressionSet, igenes, 10, method="euc", scale="none")
names(closeg)
## [1] "31539_r_at" "31572_at"   "31594_at"   "31658_at"

The Affymetrix identifiers (since these were originally Affymetrix data) are 31539_r_at, 31572_at, 31594_at and 31658_at. We can find the nearest genes (by index) for any of these by simply accessing the relevant component of closeg.

closeg$"31539_r_at"
## $indices
##  [1] 220 425 457 131 372 137 380 231 161  38
## 
## $dists
##  [1] 70.30643 70.94069 71.66043 71.66962 73.55186 73.66967 74.77823 77.42745
##  [9] 77.86960 83.57073
Nms1 <- featureNames(sample.ExpressionSet)[closeg$"31539_r_at"$indices]
Nms1
##  [1] "31459_i_at"      "31664_at"        "31696_at"        "31370_at"       
##  [5] "31611_s_at"      "31376_at"        "31619_at"        "31470_at"       
##  [9] "31400_at"        "AFFX-TrpnX-3_at"

You could then take these names (from Nms1) and the annotate package and explore them further. See the various HOWTO’s in annotate to see how to further explore your data. Examples include finding and searching all PubMed abstracts associated with these data. Finding and downloading associated sequence information. The data can also be visualized using the geneplotter package (again there are a number of HOWTO documents there).

2 Parameter Settings

The scale parameter can take the following values:

none No scaling is done.

range Scaling is done by \((x_{i} − x_{(1)})/(x_{(n)} − x_{(1)})\).

zscore Scaling is done by \((x_{i} − \bar{x})/s_{x}\). Where sx is the standard deviation.

The method parameter can take the following values:

euclidean Euclidean distance is used.

maximum Maximum distance between any two elements of x and y (supremum norm).

manhattan Absolute distance between the two vectors (1 norm).

canberra The \(\sum(|x_{i} − y_{i}|/|x_{i} + y_{i}|)\). Terms with zero numerator and denominator are omitted from the sum and treated as if the values were missing.

binary (aka asymmetric binary): The vectors are regarded as binary bits, so non-zero elements are on and zero elements are off. The distance is the proportion of bits in which only one is on amongst those in which at least one is on.

3 Session Information

The version number of R and packages loaded for generating the vignette were:

## R version 4.4.0 beta (2024-04-15 r86425)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 22.04.4 LTS
## 
## Matrix products: default
## BLAS:   /home/biocbuild/bbs-3.19-bioc/R/lib/libRblas.so 
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## time zone: America/New_York
## tzcode source: system (glibc)
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] class_7.3-22        genefilter_1.86.0   Biobase_2.64.0     
## [4] BiocGenerics_0.50.0 BiocStyle_2.32.0   
## 
## loaded via a namespace (and not attached):
##  [1] sass_0.4.9              lattice_0.22-6          RSQLite_2.3.6          
##  [4] digest_0.6.35           evaluate_0.23           grid_4.4.0             
##  [7] bookdown_0.39           fastmap_1.1.1           blob_1.2.4             
## [10] jsonlite_1.8.8          Matrix_1.7-0            AnnotationDbi_1.66.0   
## [13] GenomeInfoDb_1.40.0     DBI_1.2.2               survival_3.6-4         
## [16] BiocManager_1.30.22     httr_1.4.7              UCSC.utils_1.0.0       
## [19] XML_3.99-0.16.1         Biostrings_2.72.0       jquerylib_0.1.4        
## [22] cli_3.6.2               rlang_1.1.3             crayon_1.5.2           
## [25] XVector_0.44.0          bit64_4.0.5             splines_4.4.0          
## [28] cachem_1.0.8            yaml_2.3.8              tools_4.4.0            
## [31] memoise_2.0.1           annotate_1.82.0         GenomeInfoDbData_1.2.12
## [34] vctrs_0.6.5             R6_2.5.1                png_0.1-8              
## [37] matrixStats_1.3.0       stats4_4.4.0            lifecycle_1.0.4        
## [40] zlibbioc_1.50.0         KEGGREST_1.44.0         S4Vectors_0.42.0       
## [43] IRanges_2.38.0          bit_4.0.5               bslib_0.7.0            
## [46] xfun_0.43               MatrixGenerics_1.16.0   knitr_1.46             
## [49] xtable_1.8-4            htmltools_0.5.8.1       rmarkdown_2.26         
## [52] compiler_4.4.0
genefilter/inst/doc/howtogenefinder.R0000644000175100017510000000107714614336155020767 0ustar00biocbuildbiocbuild## ----closeg, message = FALSE-------------------------------------------------- library("Biobase") library("genefilter") data(sample.ExpressionSet) igenes <- c(300,333,355,419) ##the interesting genes closeg <- genefinder(sample.ExpressionSet, igenes, 10, method="euc", scale="none") names(closeg) ## ----gene-indexing------------------------------------------------------------ closeg$"31539_r_at" Nms1 <- featureNames(sample.ExpressionSet)[closeg$"31539_r_at"$indices] Nms1 ## ----echo=FALSE--------------------------------------------------------------- sessionInfo() genefilter/inst/doc/howtogenefinder.Rmd0000644000175100017510000000710214614230661021276 0ustar00biocbuildbiocbuild--- title: "How to find genes whose expression profile is similar to that of specified genes" author: - name: "Emmanuel Taiwo" affiliation: "Vignette translation from Sweave to R Markdown / HTML" date: "`r format(Sys.time(), '%B %d, %Y')`" vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{How to find genes whose expression profile is similar to that of specified genes} %\VignettePackage{genefilter} %\VignetteEncoding{UTF-8} output: BiocStyle::html_document: number_sections: yes toc: yes toc_depth: 4 --- # Introduction In some cases you have certain genes of interest and you would like to find other genes that are close to the genes of interest. This can be done using the `genefinder` function. You need to specify either the index position of the genes you want (which row of the expression array the gene is in) or the name (consistent with the `featureNames` of the ExpressionSet). A vector of names can be specified and matches for all will be computed. The number of matches and the distance measure used can all be specified. The examples will be carried out using the artificial data set, `sample.ExpressionSet`. Two other options for `genefinder` are `scale` and `method`. The `scale` option controls the scaling of the rows (this is often desirable), while the `method` option controls the distance measure used between genes. The possible values and their meanings are listed at the end of this document. ```{r closeg, message = FALSE} library("Biobase") library("genefilter") data(sample.ExpressionSet) igenes <- c(300,333,355,419) ##the interesting genes closeg <- genefinder(sample.ExpressionSet, igenes, 10, method="euc", scale="none") names(closeg) ``` The Affymetrix identifiers (since these were originally Affymetrix data) are `31539_r_at`, `31572_at`, `31594_at` and `31658_at`. We can find the nearest genes (by index) for any of these by simply accessing the relevant component of `closeg`. ```{r gene-indexing} closeg$"31539_r_at" Nms1 <- featureNames(sample.ExpressionSet)[closeg$"31539_r_at"$indices] Nms1 ``` You could then take these names (from `Nms1`) and the `r Biocpkg("annotate")` package and explore them further. See the various HOWTO's in annotate to see how to further explore your data. Examples include finding and searching all PubMed abstracts associated with these data. Finding and downloading associated sequence information. The data can also be visualized using the `r Biocpkg("geneplotter")` package (again there are a number of HOWTO documents there). # Parameter Settings The scale parameter can take the following values: **none** No scaling is done. **range** Scaling is done by $(x_{i} − x_{(1)})/(x_{(n)} − x_{(1)})$. **zscore** Scaling is done by $(x_{i} − \bar{x})/s_{x}$. Where s~x~ is the standard deviation. The `method` parameter can take the following values: **euclidean** Euclidean distance is used. **maximum** Maximum distance between any two elements of x and y (supremum norm). **manhattan** Absolute distance between the two vectors (1 norm). **canberra** The $\sum(|x_{i} − y_{i}|/|x_{i} + y_{i}|)$. Terms with zero numerator and denominator are omitted from the sum and treated as if the values were missing. **binary** (aka asymmetric binary): The vectors are regarded as binary bits, so non-zero elements are on and zero elements are off. The distance is the proportion of bits in which only one is on amongst those in which at least one is on. # Session Information The version number of R and packages loaded for generating the vignette were: ```{r, echo=FALSE} sessionInfo() ```genefilter/inst/doc/independent_filtering_plots.pdf0000644000175100017510000153310014614336166023731 0ustar00biocbuildbiocbuild%PDF-1.5 % 42 0 obj << /Length 1749 /Filter /FlateDecode >> stream x[Ks6Wprf"o9m&鴎gz3Fl&2ʖ:^kw]F~>wBDDMjJ龽_8I)њl)J呶(+,:qVEUX*gUӸ_:29\W_Pgm^`w%I&Hy5b*kgyOZet5* {~F#ǚu4y6scy _U]VoHhۯ|USFΐ:8:b9NDh,I崘\#88Ž(e(Teą_E@F U'Z; w5~ӟ'FΔD&A\AU4d faj0g-#t#@.!*8;=2{}Db[:\`Jg; e %H cRA8 MqYmb6[4m.CEhBM5%Ew-ʽ+$ t.2B:*˒ KعVSzwçBʀʎ98@ϒʊ_P,#b]Nt\36 ޿> stream x[moF_A-N5 K}WW'w)JbJH7$EJɮi[ oyٝyvi0I=w=Tw'޻˓ z! S̓> iACr]O'I(?ZORjJDzڣLN/Hc5)$}ȶ7CthD%:d=!~x !W?>x; }5 (,OM$2dv꿎Y0JX 5д6y\E^ٺXgBmא'y"sGNflUXF񘎊jS9M̲-(F8vOefFWӸ43 {84B8БE -ŖbҺ5ǷU)do4K}dIT%ӆG¸8*Mx/%DSmx2uqqZq&iHZ/MP3UWs*Yɪ*)6idGs5=$퉜XSNÛΥo{RӭMm̿Idϯ5O /2ھ9 &7m#МעmkӐEjq4'L1"#aUxE+ ʸ{S aݚy^}ḎAgxL](sZhGP*ng T5Q\-ڔ2 -BiIt~ =rA=`z!M3Ʈm7H4>Yxs̩ GQf_Hʍ[B5)1Kڷ i冂lLy,NsAZ)KkzWk A(x[G6-}]V¼M}秔Jl06$xbR3]K)40K?" ~ ֓ErBH`)⎢7W)0ݪ>+'8Q^iϕ%&-7Q'q͋ԝ>O9hۦ $ŦZm*[NraɤmwdXEy9B3;"קNHv4R*c`HA4Y\ \hm.fV ԝdGj4KV)„~6;?`6'%53ki>ZFu6s&srk:2\PۇN!6YԜCݜmk vnya  (x/ׁzjm TMVe@kaKGZI6#T eQ H"maбQ4łCsakiO(lŭV/e{Srl<sXQA<ΐAJ} FN~hsmZ[sV+J;|*`6qxD{_Hᗽ8w /NΪgEY\اo{aؖz2+ ^Qtte^K ttl.R -@w c`OܲNkO5(5юa|g)W.P!4jC endstream endobj 57 0 obj << /Type /XObject /Subtype /Image /Width 1816 /Height 943 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 63398 /Filter /FlateDecode >> stream xg`UۆHǂ`{A`A?}^yU7ХHtAiH$MLۙg̵gLZz0B!$hִ̪MB "hۋ B &iދ !p xD!"!B/B!"!B/B!"!B/B!"!B/ҋBEzBH/BEB!"H!^ !Ћ"!z1^3|X$38K3!Ћ>x_3fB}b,̈́B/H6G{zBEz^$z^3.֛_]PB/ҋmo..BEz IϽP!"{/nں.BE{#ɋJ̿ D ЋŻyf$B?Ћ;PFAB z#3G ^TH^WTЋt ZjEoU}-FJJ` /2^t|,|>M4I/ϋo./8Q{7@Ew^,!zQ}^4nh97?UЋ^t-w_O?EUEԏޟ/AxA /n7h ȢbEB/z"?'0^ zH/ҋ̙ zQًO|I #ӋJρxś ]xr/~l"a4 ܋o1^T_?,h1 ҋJi/6"Rp^lqD/ҋ*>g$ZK- 3s@VEҘ^t; z^T?cEB/ҋ"2-.@Ez^3Ac^`H/L#3/EpB/FY)E/ O/ՋAEm{8/N.0 "+H|p( 9/k+_/Ћ M`3$B/j̋5ôx^Ԕh-ʺu Xq#/*-b:I]zQ+0!FЋbM ={q<12U6xbE/~b55-Rsc_ zQ;^J28"-bE_/~lVEv/6F~[k[{s/^m& "i&vEC'/X+أSz mSR,ROhH/ҋڤd/*x1Ǔы 0ˮŵ&71//ЋLe$@Ex1IK'- 6W ^?a"Kl'Ӌ, HW 5 ^<d/3O!mav/NOS^ϥ HDkЋ~/El4OZ/-ls݋BmPys%Vwt9xA7 5/ً ]GiJQy6d 5Aa/j1d/Ns`sʋ4CEp.ω3^ԌMi.^g'Áv/ 2iX_|^ b0 ^Ԏ✴b ')q{Qy~Q` @Ex9MB)^4'mwEEf{Tr>^bDA5ESƘ\f +Es֮]kt"lfDl/ 5ES>15jO'?]5O7:l^1qfJ`@EMyd*9+6aoNm_KEp"qi E/0"PFЋ;m 48EE&97: yA^$"h:
ttCysdʋ-/6~oC-Ex H46!8)eu Ѳ)RiEp1z1"pFЋɔҪ3+/~j1aaEV1"B/F} uwׯg4;(/-\JqåxA)%&^zQ}t3 V3Q "H/xA9z^xA) H/ҋ H0Q "H/+ RcH/ҋz gDB/ҋRB/ҋ2"yEzQ\EzQ\ H.@Ez^Է B/ҋ1"GIEzQ܈όEzQ܄C8ۄЋ"S~A 0Q "H/ꙛ H60Q "H/nA{q@Ez^3 `^pӋz6 d3B/ҋw3"i,FЋ"g\F"EzQ܉ >`6@EylY5!b`]A (zQ[^< ÖC > H*0Q X(FdNzN 3 ^Ԑ˧YK=غݝEvS5oYeӿyk#{эA c/g8[/&Vd}azۤv7杛h l#p (zQ;^ŘxEYM7׶@?Hy-ň~ $ B/jƋ9{1f^ 2|yjRԥfI6|}ZœӺ:yqyZ!q^ЋA,d/h1fP^lִJg='fJNLr≳L -Fz12ndDŌ5Ů^I?/7W?Oű)s?#q ,a/Nu71YӁas'٧z9x&b_\ 5q ?GN6/44:#x" Ԟb2";5{/NwyR%^\j NH/F,Ad;'@ExW/nދxqaM7zqyV8u <mJFЋ&/x.^{(61'/g5#q% X(zQ3^sX^LunB:x iKz1byW0"B/݋.^ Ћ&Ӟaw5S܋-#'q9 X(zQ;^,G#&fRM^4S7],b|Q)_ z1byEӞőŦ`x_g(yg߉!b :1"5ES`bҪUi*bŹыsA ey"^ԄMı4,-^4%–KbukjafV43"뀍5EF 5}smy"r{L3ayy?QRSSsHy\ J=!Vi6)jO:~\ZO%xoz1x`zQ^4=eْԴu{''.?G1^HzAd5Q ~xdz^L?ryc Hb[$/>G/ҋIDm|N/GF%hXS;Kb?>zQ^,^>qČMU^l2L#/0 "0 8(|ϗ^ԩ>z 뱛UM+|2z5 1 #[->dzG/ӋeV8mMza@wz80NkoB0T[{o#<{.xTy\\\W7oq͐hG/ @> 0(.W 'O/<߻Q8L9a0_ft#M4u6Ӌ: )r@EmyqPq̋P#gZdы:D{B6iES9^QveZ\Rn^˔J4E}Y |/zQ^\E4r>e;OՋ'γU\mY^ZY)tha-F/݋/z1ؾX7+zqyE=‘xha{˿Ow/ަ!Fqzt5@abazQL2~h] }}X^IRSE2Q/19==t߀E{qwy {^䐻BπR Q% l;9ŗ^ԻS\xO;Cs܋oH $khע؆G l˿Ӌ#oVMxq-U,^޼ʛr/y35/ >eD;hMb;dzҋ#\ŽMxU\3')by/|C4^야XvV C^^MEZE2R_55crbYY?.'zђA7V0,C{F B/ulgX)/Vr$m7wŜ]h2G/&'.?Gs,3HO 4pŊ En/r7k izH;v_H^4g^O 3#8 t+p1~{ol0NNjTAXh2-PfųG =$/_ԷͽV؇uzFAY\ zQdixQ;;?^QK.n|V_,-BWzQ}l2 O2Ћʔg/ LT_quzQ} (<+B/KOJ8櫯V< 2^Kv/Ҟj71_F/d` p1^/D7Ƒ}+BUeڡB/܋ڷo^CE(܅ z^T)i/A "H/ ` pz0^E] Lcn} EzQ&3 ]@Ez^5G NLH/ҋ*(# p-z2^E]*<]/٣EzB` p~/ .xb;O H/ҋ$`xZ{m|Ŗʱ<"H/@)F2 Y wB<"H/)1 V8ҋ"H(tċPqxEz^$Q b?dcfҋ"H kU2/ҋ"H$_3g t~=Qҋ"Hd- ӢGҋ"H1>cZ] BsJBz^If@}(֨"H/iMGWOXG/ҋ" |t"PЋ"{$DEzQhkB`B/ы7\ӋC]CzQ}^< oCBzQ^0:xRfACD0Q ʼHHs1z1v8EB:N4^ $`(z^$J< )&0 ^=;GB/ҋD܀;IEo~`*@Ez[уA`H/}sb~aH/}s7`sB/ҋD܋n d`@EzЕA,dH/}gKB/ҋDXDz^$ tQZjnS,+Y"H/}4.SjעXa "HM/\: RXl6Dz^$tt.yb%Ћ"7/|׉{$/f(-,^y\'J^Q,;X"H/}gN̒X,X"H/}ZN,WX,X"H/}+LXf "H'8]a񀭶XDz^$ 4R^w`Ab1Hg "Hר ؙ d3 ^ÌEoEo@@EzQqFЋ"7cBFA;bH/}=(T0 ^Ȳ)aH/}38(`_NB/ҋ2!^~`NP \Ћ"CB}űE:fϼײ@X1EFЋb} 4 Qg3^LR xɫ ``gH/`͌ёA "^E-6F#,lfldl4 EwZFc| z^$z, بT728'sTUbNEz,iؖul3sT>S6pnkj) ﰸzQ Wol~'\њgQzQ9S6Zo.PR)>bq%o_ښܼg=*XdcH|ErD_-w8bo+WB/*$pwg9[Y8'Js5$AGrykSf3TW1 GHŊTgi%ₛe27@7aiN Gd}Û!8n)IqƀtIJJ4*bw6 @j)ύ"Q/-~Ŵ6`i ZbV6|+=n%?_v$99[3~F/ᕎs-U/>c1a&T0yҌw{vzq?7֪@TYY7md/K.s^EEq<.>Ľ*`KѠ ۠ ݒ-5Ҩ?W>1k^^$.f̬뱗M`)Ф/8}BSd#_-u{cO-z `㧤뷨,ыDC}t SGŧX49QE^U#Bb7 z#Zvy ^$_F%4 8#Q,RƔ}CSz3 &BG>^,Zir}4~5G򫍁QӋDL0 &׈=CbT-zqAס нuT_ |O/+7l 3^bI/Ћ Q0Fkh,"H8*Wl,bgw0A[{iĭ^Gt<[7 ;ٷ,H/ҋIu6Ɖ^4qK\Wم9bl߷Ktnz^$j_S;\.ip%I4 Wt@H}׈_gIwzƮcEB>Ӭ=c_[0P[ɋZBo[&m,^ xW[\srO d8(Sb{^l:A4I OV]cɐKN!@9k%q,\D/a̋%~[o'Y x?xDB YE/~'v"Ҥkן|) \ ’>ƪ C7+z}4ELzDwOb;pN`& $|TO "̋-Gՠ]ݯjЋ-@[/JX*iuߌw/\m3ftq4/r^n"^ޙ*>y4<^궨z.wtm`U`~pi(j~raSuS_/,Q̋/M%-?}}ͯay%ϑ"n36i 8Δn9-.\|$ݥ=f3bpo@7">T9o cj0%d}.S7R dYIa_]W5G5~PAtrP`0:)@OXv)~I>Z^:X\~eU5WV9lrk=#r]|#GX؋[[[9ònzHΧ>nȌX3ѪXe1/N,:)#sݝЋj&exvR;ä_'z/w Y eqhRbg/Loh8Q#&^Trb%/Fw3: $?82uII{ԍ^$$6 Oy^ZҢ!?Bʋy8PnEֽҋDg#hŲ]_H ^X--CARz%/# %3[Z{}_KڼXK/0CrKEv{ @>KC/_ HxpȮݾ_(8tPz n{ePK6ҋ@7Ymd\cݳIp,cK%z16'է*|rUݽVa~B5,z-ɋ7ЋO5[] R"S{SqAa/?N|oW%/^7YF/=PuYjn30_)䷇K cȝyŨ/srn7+bZ0sIXI/FV5UG+> }B˕v1}c=|0G)gkw) ? =4t8}T#zD0W{Q} 5Ufd>Iq9_ݰyڞlodBhxiFNۀGEɈò?Kˆ 8k.Q&ϓ1T_I F% Wq2/6Aζ_tI$S'|]{Yo_Qmƭ芻tyiql=ɅŸy\ߖy`TK[>s2/6&M%A/&ad/P:~U} ϸX4]lK6fȫE=${722/^ |4w$pxwbzSE/*5|D/%{M^%Eluo[Z#ӵiN}Y#?Z9CmO8>Fы(2^bA3bi| IyΟOvn{9Z:#ˋi7o)Ћ z7H2l&TIR͕@xjX,/ښ!wP`4%x~&ӪWT{" ;{L6 N염Ws3F[ƓY@^+.Pg!l/F-k^NEjVkwXd"Nbl"÷V.O՗bɷrr៽~ 8zʚ释<+dO;\`RQʋ/x^"Q5)`Lux-&Z[se^\#T]7YvX#/?zrD9;=^\5gJ^ QxT`nLelMnykRzR`#pCw8}_V;w0\TuwkO+b]zыk-}x&~ҋD4x9}/@Tk :oeDžd7UQH/g_LzQ/sqzPk!|v~=rRL[Bu`{e{x,8((8R7zK%)H\Zo6jŠl@* na2cKB_r/.duwo4,$믣 @D7n3Mnx˧o)qH'/ Ttbdث|X-EV#J/ ^,`GDqVr/ߝT?HHxwsDٟ^>պzXȡyv|Ϛ c>{}֪h{-6wSc5FsƿooOK=D}It{'j^$uǩ wfħdjJs/y{ulsSCC\vv-_Tߩ $ՍXrțT$x~˼x1y@'z2|3gh#Ϗ%g^N8 H}:TW6;IacM{Z mp,-{{-_YZ-wn= aM^x4w&N/b}>uh=S тv[UH{<*07oXrl$ʣͅ-MK|-Y~l\tYZ=bߐ> XbcgHpH_V%lP*abm' MzL&#mꡲ 3ŋXtU~O;+. p4Fr/Y}U2 LT~-dû~,_bUIl2Vt4|ivZ* K)Q﷾v9?"!nTj)yLwyl(5a-0JدDѕ^,ك̙֡I}qNṯ ii'–*S;Zջ}j)IqR|oQ%{4S5p"qRqj&_ޙ咲.a ԤFjF[:!>5,޻h辯{KP{wZFk:s5h&hHjZqzkc4ǵ:{=<1Y0ҥS<{ƛ<_w|K`k톂P[Ҡ50E3GQ̘ZL/)=8zxd (!;%4x]ò\>MYmg*/漨5EvhutJ$%m@?y )O>7^c(zvXJwMza K119ER)e+ >urcT NXŇްج8XћOq@_I,rXOȼKz^$C}M]P.ZZsy+>&(+d h&cϠu&kb*{rR^,pH4úo· Sol-A-6nKNÑ*Y*9SOHZ76VE"Ez zRZ\1T%e%3d) *9S],≷'ІW^$$0y.ӕzCɗUATJUou^_ދ[g b qK*XnuEmH ݿ( ז iO9T*q2QyܯvRQv}ڑgfyEBܳ/3Be0f$)b5JuX޵)5<*3sӋ"!clgh\I= +ć;~Qzwr=?N/zqܹ:z&‹psݢs꼌=ieu]*Hqidoc蠁V"K> zWt8X ORV]V*fVKN9e@Z^6ؽk {Ojqw2:mOw}"HH$ykW , G'X}YK ؞-ԁi![/jL{'z=H/R+I^5{L?l y öR\d#sV-?Z7yО^ qW_us /MyFG_Vi-a&ջݜ iL?.1S EBX[)MPUҐMRێja8ҊN8q {Ԓ=),sEἀ Џ=u(ltICɴlyW'}>~ڕ?fdsیɥf+Қf&S8dFn*ⵡ{/VY_t~F5[ HɿD@=Ze5;bl}^Zbi~rИ3ֶ[(qcɔ=Phߙ#Gۣ[Ӭ_gꎖ{Urv[>pJ;>M?ы9~wz^$ȼ1NK"r,#`_XgMRf'dO~ $ywpdb6S' o2,:nR ą~ySW2oVʭVŎ cthZ{M'{GӋD5{ >^Mv*`)س!LO%"GܿA}J+>wkk$l5I rHizJ~gٮEKGL6/L޸k "Q3|W;{Zt0 oVEBoҜ*3̛Wa]1{TXK0*piDS̒sdbx+KUj=yQ7I_N/01vMnx;wRk{M_^4dtlc,;ҫ3mMvIM,*o#R/'L2/5D봁Ҭ, ЋZ^$cܳpҏ+)?xnb,r&UJ: %F {MubbpKMR9uCE esms0oV%-9ULiQ yR5\v2xm(=*, xRvbb ^׶1ɼCЋDyF~V^Fһ-Z,^pmÙhVʥbJ"ɠH'X%HqZZ^ d&k>Gx`:ba1 $L~MiOZھ1ΩHay;&Is;V׾5.tٛhZ Ed_ʱ+m&q[5,[Sf_\NH m1E=6#sB?K/+yX'l\{3 4f;ҍͶ}sZh>Vrc޾]{su4{+|[u13saibܼtU_QWIL/ [7t i{dEzD8R]nwM?p3 RGY=rWXa胨-*{φZn2u@xy.zLrL'?%KymJJ-] v8HI[7ǰBHvCG6jҋD?,n5\oc*F G84;^g]7kޙ2/*=k0bw-{Omt?`_fwUe[F8LL{s4P,L8n^˓qLV80f`l|4^F% M!ʾs-Yz臭=)d q0[6(i'LusX-7* بS<6&e&jB'c /BBGuCy.GaKMux*rCLGA|;HÉn:˙ɲ6x/rK|=qW*l Gd,K}4@dw*85-)Zl mͰ^CjыD?kY4[il,~W纂-uMVIyk6tUsS$jͫ_>iŇ12>'H[[+8ʱ6H/ձ:D>I5.:'=\`\ϸ,k&vQ:~?mYa ˶Budɤ?'N^$- Qw(=;[brx?V<@Fxƌ' b( yoI^$= '*{}JajQ[KdpCvy;eے{h>ӗtR')=Cނd eR6uqx`v."!Uzgtv#C!% 4s5!t SR2K /5ȯFR}1f0jS7p ~ n8. ]"!qʏZtٯJdS[^ ͲJC&b)Lo^}B~jRӬ.5;ɹQRѱqS훟`ᓲ]+H_?]tӋҭvU6MUe+r@:޻S(KIW]rΡ>{jrT>9 _y֨qsvYǷ/[)/3IS3PeSkMKlt =v˴u .V'D36 :nHuX7-fK.ޱUqM"܋^7>5} e%Y$.k|llɣ{󂐋h4ȅAOdL?^!C/3K~^MrTǗ ͫ%8; wR aq4b+(Ch\17R!^DiǻaEB% "!na簖b{O >O.!ɨ[*-b~лk&*n(eUm;,T=Cng oI\dG }X-rE&Lcg\c[uZڬԯyӖWʦ哰؅}dA^4J=Kn }Dse1=ME)V޷ -+F)6c [ 6x4ZZ',l4O'uILsg!#yn66x1flxa0,]s%]c ~p꠬Q0ьŒf4HQ͌Rw+sꮺ]TթjMkt?oT]ԩw{p"y2Rt%n ;[O+2ŭv]zMtP'E%.FN 9]b}ϴ+|55\klQ~aHw)\SĎW;vJY=}h]\?yM>WWb\ĸD'#E=۶Peٓt@U[7iW0lbGޣS8>D67C-m)o/"ݨ x$F'j7>WW4k 'kCnrG-[7k"r$itʯ'e [)ڥ?g\^ѯwSø<_j<9FiÊ)36 1Z|khq#E,+z_W-3"UGLa!^'zZx*9BC슢xNSԁ5u> }⑉Ivd<x?fsQ7ysx?w_5ӱ%'T=抰{f ɥrwޣ+v!GEF=,'.P:d!]ȣ=soX۱M!Xiڇ /^ljI %bHvz,s$niӴ 2N׆Zt\<2\X`\W5!3xJɘ,6޺EYJN>EK` pF~<(H+RAD;DP˘sHmx2YxM:oKvJ\Ip=D2fňWMVo(1bW<9C,`X뛗/(qKewO 7eW";ؖ^$r\.*Wl vQM 9!78<&d:BJ1csSogr)EHvʕ|*ox9!mDM)瓊 ~ۛ1.b1R΄2騺=`s,IcsHU4rzRn$t4d!E>Yq E= rJ=Ƹxmyф‡ AF:$ㅷTCn=g].T! Ŋ62Q9-!/p1(fl]qU3QMY#B4,GPcaϷ+iA ^UyI>hntύ!bYϞ0U a6qYmΛd3skI꺗s."n~q#>Ƌ l|胋;O&ܗJia\f!j^ ȻGtf_c笊*n!q@F*O""ݦs˩64b-rjb>DNg"%E mhsF-̻k¶[P$~|s!rtkZ‰q"$+ !e%z۬F ꅄDf(p0,zebc{tlLM3%#\rl8e2i&]xYTIN`I遛w ae]XWOu|N "|n/^;җq"$P NȕޗHn5 u6kjgwmHNN%1^DҥgǗUnŻA}W(؃""D鸩4avШkoQyYB"zJ0.b\b- HVc{LR/RhBeCڐ89#L瓝{}V_EdONe#E86S9:Il(ЂCj] A꧂Z{B:c/p-)>EX1^\1 wx֖n!ʖ4S-j^p^m$4.ΰ7=s{ Uhݵ49:/&"g%!ࢰB<-I0 RSzV v  k7i!rŽt=eAv2lٲ7gfE̷;ͭ%.¸%uny/ ;\"bOte _|:W/)ʋ7|_R}_vH"9jSLH=(jRʐ|bO`J!TUD`.]ζzY({OH6/9kk|#n-ݸd "$Pʅ98[$#VB]o\KT).σT闸&G!&3ĵ6HJ#M+O, ()9kfqE6 )BFbֽ).߁σ+hdX])G9xV'ժF(0e_?ef]4ht67}$Hu~a7q̚ 沜|&8؁D6Ăqc[@)t'A+47O&sOfD]ݚQOΏ Ooʣ~{Tj:-Aw$"V<$+E YNEs0)K5}ld-qᕣ\/]۳\(i NHf俯cki:`ߤe[{v 6 7Hnܽ(NVxavd)֐ 2{nK=ҊOԜ6Eޕwn]1I>'6h)hю v:cVct" %^ i5db?bRuٝf"pۧhP HH2<\@%bifvXJF]m*nH1 #gA6 {LΥ݌Z# r#mBep,)ϡ͝DcaI?|m 486\0.M}[ܷ*/9ONznayv5bdB%G@5rSz_i)dG_P,SV6$P 8"I5O8%v ja3D :e Z< ôL=`:X.Ѧ8eɬkZqTeXK k#ೂWa @RJrj:R rtQL[0ۣ/W`aZN7ޮ|ϚiLBOs {5'q<:[7AX:JZ =1E,ONG$xU4Y+3pAjrnrkՒe96=g׎w&s0ݍ)ۃ BUD$(+vO|u-< e:f/̅x"X2d\x " v ] NDϖOn7¿3-a\ĸXI/hP{3 s#tjWBjv_!;UJ~8o}(ʦa*92!-KׄRTf5pB싧 CLkLA̧í*eЈnGg{"FgWΑ$(eqCE7ýss"(y{B caU⎸yaj+!kҌRqCT$ʘvDƯ[^2{D=2J90o?P1"V~1F3Yp5ͻ¸ѴsZ{FhrX"%2ue=x J{1iҕ9 ߉ۼ#uD9 |J .Id]]C'2@X)ܸ?p̚bG 2 $BgI*c GGelE,.'U:RgJ:5bC;V? YHp~`l>W S^5EGpFfj凗עǴDzj,}+>='o*>z.cp ÍgaǐwXC|[/2f#,Fgb\rN??ٕe3$a.˨S hHH4ʁ$u{o5KmnSԁ9gIŝ'r% p RyxYm=Se+=ֈ3yS-W-^}qRAgݯìIxn89JZXlz"n+P(IoOG.ƒEcI+۷k8mF/H+N|VӦ'N%{c dPx{Lۋ;(v͢%,|CZd?j ;ȗû)5邶@h;J5-0HhQ YEJI`0 'n #@N!#ƒAս%N+Ly&Ԁs+ݜ?4Q })L'{q؂q"hKb; Ui# 5q1O>(ϳJVLX1g#;E,̇jV4 _wNvm 42K 2~ ,TY(fG y`op>0R,[}*OVB9ve4# $߸DjTF%8ȧ 虋r=[MRX0.Fieho r+xkHSlܪTkz>%hfA ZDB6m`.3ieq4 Ipg2ȶ P*\F:gLJ~I څL).P*dl#52N5rlU'X¦g"7Qko..Տ ][Q7Yk?fyU褙x":WH m(lG%%K؞'rKJOÌ?׉F57/#;;u#3j Ztn+\\[`SC ,huЂL:n) i3ȡPkEKvL)-‚q&7~jn4Jb8BY2Bz +EPWU>+^`vi}Y_:}bF9M|ng{}觰 G3.9r<0]g PT.~ {h\L&.Cjk֫ SuȋMdH.epÞw>g] |Um/"3M$%g-d.7hȟ"`uu@hn/F&=:;+ v,lvER<(4zW^rwZǔ)G'eݨvUR!WGGI-xbhA8[ˮzƯGl;0.b\ I7VXWHP Bao/iPQzsEron| 9>b<?9 wa#%^~)JdY0b/0ݥM޶輦u5\4q1cН |he%xĿx(fL.k?*7S9\MU 't,$fIc!0>ۏ1.&",@F$sފE9}T뉢׃g wn!6c9} 2VPިb(P7 Lp[Տߡjhu^h"lo [Rь]317^XæY3 Qt/"@j;tJF)*9Y,Nx$vQoܱyJu< []9Z}&TC*vd=NkctWrW$5R MFӉ SLԥS /K唭YN}FAqɏ&KlEZ"$$bxWu,,' Kx;ex0Z5Ϋ؋tNF]uqfi=%, |vG3a7f*9* L)XR616iPw_vZ QfD=v8utga|jvHi~w_V( GyqiP$lސbs`rpAuJލ'i ѽ4vW*PGV1.^g,{s9e? 9Ok{?yο|jWFS\GÎKw#>[|NLm"s[b.lcaK')l9"TKsK?ٮQu'}n;GFo+FJIX[`\ĸx9dZ^d {-H.ϴFRd}ծ ,'tLP''G9*0*zD_!9m9 }43.kܹcC\#>Fd's;pU򎅆BX/xq1.^i H\' @ 㘅D н3]jLq⛕<57/!F$lـL*vh0كf=5c\ĸYU\<k+.K NbzXk+$tHpRщc=jсIFT \- >c2 W۾]'bg\3xZS%`1ˑš]fTFbxK FLj}w"E,YJ&y٭!Ҹn$-g|$#۳Ha ҲĞYfHsdAVHq.`.CIw3g9y$኱RVE1 6AQrl E}e([IxMK^«X5[Ɠ ] /?U6"E,ɓD.ZyEZuޢ v^ɫ |H8醶f(24d?{ 0r镶Dmi< uxFyY:5a,ߓ* %֙Nff8 ޾3y6fJ刢hNt7B+JxMEQcT0fP1.b1Fe >ʉjE,S~9ȥV4!)!?>j>ǦYt"Lhؠ\+ ģKo=S2baW#"$BU—rߐ_1.b\r+C9vZ""Tr Y_#\3sbz|QpZ.?>r[&?62ˆeGt~>yhwj 7C$ݢrH<>-ΠZ}SẄSİ:|VT\-h޽(P4&rLwͭj:o%ww%E>.H3D6-J F%J1KApԘp[ci$TR-/h+\.{]e4;4Ƀv 65`SwS++Fhj(JhcŕL"89ѣU>$e~Z粤YYoqexFr<9Ǡ.Xz葕올JKBۓk~یLOrtGpȻ `Q%r'\Pnׁt({7x "˨V_onE )'MwOרu6};1L rQQi?"tzQa{3m= ߭ƻz‹L_o\,x"d=+Kej>)!zIȂو+vh1=1-jNY@0iF.ƔԋW&#^BE`oC}69_b KIJh,t M+rE2ü"9.QVO;f:ȍnc>vgquE/^3 Wꋪ%<S>"$EJ ߺbZSgɨej,نM lsDN"Cɦc$drFo*F9KcR6(BIR=&sC!2|VbVN;62oZV5:=+$, GquciW#b5wNlFΚlq56抌L.^?T!ir0jf=mcbxZB4yQf^CqKr|}/qyYQOeJ] Ӧe|XKnF:Sr$ FKEX0.^(\$^|rhէic*HfZ8=P-)S\qqpt{=z1c e7RF `"x%'Ch=oCcl! 1̓o;kAlժj/BpMS_c\8-GxF"YBDV,๣nT.@fJA U#˚güp8DTts<;"{vh(E1`\heǯr!2tWg Mzi}?^ZA_)pMS(D݌?Z3.c~W/P*#w.)jGL_;V7=Xoф^|]ʻ8=39>>&Fٹ2ƀ?00TË nfPd6W a) - EX6K" {򣉄yZKo&|ԎsqB8ŷxqᢰ =U ^SwQ.}LVU J{˨3yΖ勁G1V$vv$7>]f&i>&fD+~HWI^z‹_DDTq{uY+_cW۩|e@i-jkw@lBL}ڹRߢsm?'bc1.b\6l)²?B($/sBq\K%Ia-y 79 E R+#zB> rm@wL3zl/WЫKz{6]=B`z zHcd|2=Dlq!t>X;iY?!hmYҨV9J`\rieLl.zq;M `=Fu8V,xJn0M#{IinWb\VzX01m>$iEPs!]F&X龷?W"),`Sc[bY%5(lzSyLu,3 Ȩ6ҭcrBfR \b`)E y'L|)z4rU-' MMȓuou2;l |kQ,+1jxR]I`3p\T9< G3\򹊽ytvcq#-4T9Z/,PVߗ2<`↫DKme~JheQ,3-`\ĸ%rx~M~:u$i Ā=$qLEGuy(@io= ܮR݀x+LG킟#%NeQ U1A4fmQ_3rOB*|eK au4%WWBKmY4-eNBCu=P];c|&q ,ǡuc TޠjDd1}B.13teUvl>[ymq^;Br^M\`?xr('AksZ˅9]z!X" y@(>\[]" Dp >|~y\{>iN ܡ;<5`1{Xsn2qzH>½*m|z*FWuG<ὐi! |ڒ}'(ϔ.q5h֟^`>o*f"E,a7?h&yUh1K/Bnذ mIjEν<=mؘEnN.quyHL<R3'ɨǻF?7#mP|®ڙ^Q]!><="M% LNmrqͽkV=2'(bn-]K0mȇ99Vszط*Z|t#~u E,\FcaW\Ju=n@&ohͪ4c>>L_, B:ɍ/{pY?4j s]Sy|S%+{Y0ny-֚(QZnwqn/"J-8AٔY^Ffg!-\t&*\hG% ;zBaDH<gL}O@j|0cm|'OTQ-Ԣ Q^BmX9`tC8YYN3"ttHT|JuaqEIm|T|@ :|v-.F;:)o\֯y}V}Ȩ46eLs+D> >qL]7"~~Z)#IkKyuB[=Q\.|e*/X"W6$Hwb8U- "wCE]\)N1H d_ab}ϣ 6&%P? &0vL>oM 9_gL*:3 㗋 E,X`^ohZ,]&mnVK.$xhbwF=UZ2`0.~CVsK*&Tٹ"k[rkDTC%=HMJ]L. M:{'JYt5pbL՗I!2" ĬcSPT*>Y(M&GKRtGt@!8owM?i0.~| I#YmGEYk$(L~/aI>&g _%[ -C4HMwy;HY`B݉R71H_I 9o\i<y {!eRbُ{D1TT6Љ8ߍ,f890,{6~)wѕ؂&:eaŚD˦cػ;j V#dz#BOԵ>h7QFNv1$[!% 2Ŀ!!~n)G/%!j9m%\\pY]V/cJsAZ!Fo ~#dT βpm|^_/XC3WU^SKQD"cZ܆ALlzpr:t} ) ҏzWK~<"C-/&Ѫśԁ9+_l11$ ai>qZt6~x'QbïY{kbJ|.*%3i/f?faHyzq}ھQoa=GP%Ej4h\T`nTf.H޽73ŘB?@4*#<@SEj (ꏃA'IR' 4j2UuVl2B]/Ǩ2y,. ye}HDz嶘cّ_0kˆԧ"m&Xt>+r]@ץK~)R7{ۧϮoSS]AY7/mJB`\RݿHnN 8Au&N [ 7")ji™+.{Wc U\ܗqݡU4i+D` r ~?Ɲ{lqyFK^Y=,kADԙS'`eUI5JzS"FMV;|K#v젯iޥQg珋ő5R^| c2$]GS|ۻ34 $u$=%{VMObB Bx:LU2DMݘBx`VzQQUqOE*ǭEW2Ge<<;ES3T[Paϙ 珋|F"bd[k:hFX2 FFsbhƒFǪY- onbݰ'atZ!ۚ!U23v*s]b:dE Q;>{#l~b"FK['wC0~})E;존6ڙuIS)ahf[F ̕r!AJuM: ʐv^ID_q Y'Vk;v_T> s&&إ^U؆(LiL;r3ΠG8OhfP]`HL/F]-_q=b(g|LnU*x~gYأh]G70(f32O8> sO0.b\/AiBFQy זm%RPetU\;Ag~9vEAΫj.Q3Ms3˄ ogtW 0Cbr], WEȦ$= +}`ªNp@_`yfPv?5-O]!Nu>Do%{f tR,1.tIV %2Rc-fJ)_&jm˥d֓=㚮 "Y\cPR c¹wfF&1ۍ}=[5/Vw'ǶPԉ\qoG<,㺪D?2dg sڪđZBܵY6\Q-"HjS"aHs{1sj<@u~|IEFԷ0]bNS|sYBB!}B`llC%"3?XPq/mL)2: oW1o8 VaAkdeoS&i.Lh<e >6EEBA9{S(RA ?(}:8j+Qխgu>PZ`Mliɑ/uI⹈+ZṂDHP/s^+5KP2\<k{{װ!?>]a͌FCzE 9` ȃ7 L*]|J\sH# pjE5F>bk4gOg.gtD.:_RX0.FcýlQg1cϠwϣ Y]]۹z1#v.Q{ }>dh4 o24/? ?4L#gŦO79Ą&NbdІS<3c =|J- I U1`iaA- {z,X:gȇX,Qeg\x[_&[{ya_=#-HR]rp8/Q{eiR"UWqCjBL/>dvhu cA0Ԕhskr$̻z c/ .g\|KTVB{Շrwhl?ygYm;⾌uMsyV-K^'>|!H7{bŏŋQ6jg2|YR%NՊup [$ I~U.wQk2>\6K0.^\rN0^4:zDE (XR}|VXyB񤙐wĞH5}|W=bŮiVlLiσBty+n:"]7TсA 4IfANZd}9 N@Ti*W$|LYm$]WH>墆U?a!j}-_Pn 0>C; PS tx,dn.0^d??%u[NIR+דZ/.8GAzqgf,ġˢ'PX0.^\ܷ2EC^=Opg e&&i϶kLugvW'ȷA\tfP5ύE}d.znSP?@}d-1Ȍ\@dF^n1A'B\9d-oW\rt0a\%eӵXkyg:DnOm =ЖT&y]<`k4g4.UO𿙴xT^7 OB^&minj!’XɽӞ'O"O;z['=:mef{o6Illk^q5EgL8mtUg}ᛏ jV(yD9D#tW'#~<*^lY oIDod .tJWBp)G'%x=eg])~M dSN4N;r 5J =i2Sos.@tEK}S~Y WYע8ORdZ"m;{P i_t(I_3,]Kh{c|N2y%7s3pP0~?7?SyI?[wa_>B:٣4*r:[Фs&t׍aՙOIW(} :KИZ(Zqs7+OD3M_ƦaIg]z &:ZZRN{"Ѹ{\ BXcJ##vvo^Y-"7i:r"Z!jtJ=e~W2Zib&k.ni:pk;C|ybHCWCQdN&ܠou&dXSԎ{kk-P‚q14'W݆.'P +kU]IYwբ VLX@-4tXH2A6nvQy4 nQҷnqD3d$MS Hb>>ó-`'t}ٽgךMkv"mW-T%SRQVZDuaJ`59`0@ct д+5e~\ݪybLJcYhíS,#ŋwuhϵ@dn mHGK}0'\`n|LЬTt8TwܸF]_L |ТG*;3} r.O45YD=쪹8+H E,Enx7)@be?m4&F &fTmm1NQ(p~k4#2 od IYTRگq/! ?]>e Dk­fcqbd[TkKiǂ3^熸l6ֳŊ7m=Y^h\bNG)Ƌw CQr#,P' P A\- d Zq*̒P fptYĝZ"ňlyU R$s>pu׫DlZk;8ڄ6S$@RH^KʹJ$W 芑x|FG&]ۓH 70ƹW`.ۚ;t&DlJ\.@\!!VD%~O+AzX焵k#[DKJIG0$4cYk}2[sz])V %SwP]ظI3 zDV!d0Zra iyLiŢ7'F#'%3RRZ`zn_ԣ斡c5 YPIpSٿkfC >3 Y!~k])xE.b`;*z+dTo=\ZRCrBȥU7$i%wJE*Z/eQMJ 3tI6`jr3vD\mIi4>OQ'5>lP4,",Yv'Tw0.b\/PSn}3 NQX#2e-QsԴr]OPqM`߀nM?Ih tvTD& ͳLrtDsu<>eg,xy9sot˯(q"Ż>{QzaBaJ۴\JD]ZOX&3$b ۥ(-|OY֣ o憧8\`K9>MDEfH`1l:jh 7!Am1m/ |hO)zhqm0.b\ Vim{!n6D~4Y+P͜(8-8|]wfwH8n4Aa6 |+U)OW{y|AlBn#JpEȂ%(3OwGlP <D KnJcC<%a{{VFJeH4j |Λ)f=Ӛb\ĸrr*pۃ;LSoW~4z_Ns$i%(m% ) rXL=aOG]p5g]e.|8N NDl b [Y_.bDA&֙# d$Mĸq1XXn]b5EgrsN(Y%%k%ƿ0m@4vvޝDa\4ċz#*ԦiX|Wjqq j_}Kj{Z6UyA Z(bݻhKaq1H3\_Sxy+ QzPOW\UA9fB˔N4Ӌ*l [ (o4g\2R0Cx9X5zip* f 7`Q{PQCd0.b\ @y݄2M=1@L°ӔwCf{U?TJ떨 ~7'$x׷|&'hg E?08(b{X>*4*PQĚE7)ٻoHZfa֭aq1)K5Mɒz)#h}/&`JΚGZ+Jl(m>,WE~ -M!y7?]|E>d;٣ ( [|Ejף>J5 p/WIWpR%z`bq1o p]&VcM/EE%t 5$Y]%r+_"JNriC>C_f)wWj&+6ȼ3E&O51MNÚ-ir9M]\ uxKΚzm݀ō/{U2_БxJJ*Whdv weZ øqr )_ƽ@.FWO>W\ۖI_>~p$ᣰa '75R|T6\V,r9i(spybBXk XM=uFÜpK}Z W+8<-䘜ۓˡ /TIHbD, ~#K5)7V'խGYa[B ŸKs6d8O z/ij %I=8g+jsQ~Ljƌ>ϕ 0 7:5"<*BUŏ+omlb]că<2̺!Pۤa# WDXj[uz{4v|HCL! K͝s4 -[øqr|},oQҷ̚GhFҙ~,+mлLg>!hhFWq$pz,Mh,p4[ƎĎbޜiV؄İH XoƼqN:*8D`umI3U2 D̳K.o~E^uP2v)y_A- ܎Q_'s">HF-Yb҃ p߀H2Q'[WL!͊f/{*\>@1:/b\tȴHyx&./ăPaY?ŕd}p ɽ|GDrq7>qĜK2hԣcan*X0.b\|z.C'啸H:T񀙈<ďNRuJ%k |3>ITҒcTU|o8Vq3p)j4\Oy0O=aZ7} "zh(pkιrj0.b\ 5s4ܐ;K۹7-Th+s~abH(8~7C Wp.$cCMe'fmX_:WHK攡yKG| EHfs_LCTo*oAtނH]a=-Jhx`_cXخ؋*z^3OU \66zcRud7W6ӬKys0*E#SӇ"??Ak[qWKk\UFkpmL +!tx=KKXa$P+O˵p&U5G3&¸q E ưM%ƬjNX2UO$Hv1ANS]NxoC݉Pp[=%,'8au]RPrS Η5P3e7Y.u3ۮ>wcuq"ZjJiSP#1gd;CWtfdZZg 6drH IQX*Cl-8Qo=RJ^Z>;''(2IlhjiW}x͢ Le> ;0q8qb~fC1^yhbPG eV+}X0.b\dkpj4^lt)Ȑcn>)rB?,ҙY=>U$TOgڠJKDhĸq+I-$̗$V&+ DgC!n )//kʪek. ¸Eg`չ_ 1`0=$|@hIHR@nB !Vr/r+.Ľ "7ƸȖ{\&K;NʶFC93;gg<{Μ'Xo%iqJO?k޽4葵sn6/-"۫{OjE齖&/Z,;TzgW05f,MJHeªFUE~zàn1'fg}9~Asg^Z 6wϱS[<3{nE UZӎroBhެjtB b 2q->YqͲ5{,ۊ ٦}$@<ݐM'7Ο) z<3( RZ*x/¹r P/ڶ%(Ψv-8!_He!_wyZ\rh8hlKȥr2˶=btHOŧ,w/oxLz0tҴܝx/¹`yx19˿%tPER%dMëp㧗I/U7fiz^h娧Y}\i?4[_wG|\.a1gܞx/9S@yFJ%XY* '<?"7e[C kqliOZ :˓E/T}is %?C^UsYeg }Vڮ}"^73Jiup;jK&<bK.I[i{Z$yq=agr MJv`JeF2?]~P2msVX0׈AfrEgJr߮ huc~|Y0c* L4 "<[kZ-ҏ qeZ[+Ƅ|Rc:PsOsߊ=3=rrYf. 2Җ/E8)w+{83V\sӈgG> scuye1'u>Q\77>Sr4BɜSq``7Tç650u^6^{[)\w{1Jy/E8lLQ;^W.z'ؗAntW/b{{]W.D-gTG1v#,O͸k/Cm#}Ӷ8_ 73IPiϮm,P'ݩ;t!|Ci@; nN!!U9#75D@j5fVZþm w>[Qm|JDl}fF3i4qYnKM7i']zF;?ڀ;[سn{נ)^ry["^DX7Ӳ$ضRemN *3Nښ%uٓ#[x';">p1ᶅ iq"is~QYUHzWN7YFP֤ lyDZihcih7[z%{poE œ4C,t(#+s+Z7HOpn7y:0aR}T; ã_([Nz,Wq jpyЌGFGR̭c3"^s9GbԩbOl;tvc3NԧXvR_˽jy Aq "3[fR qir}YxHϰW[tDNN36}q|dTq^#bW5dE砺htv6kV`eM<䈕6GVE$iU?J%(SCZyVoE9Np=UjG+PΑ[m߀/NlZ[BC\g,(w6/vY&X^)[1NzEqb8Y^d6](ef3[ZX$ٲ]sғ33:˒!)LsMo4kgf<X$h>ܘx/9cKH ;̧BCq]xqjY2f^Il JwFU5yfqY gIo(hMӷA M79`Ks?sJ 7ċxQd%K#:_QiyUŗ$_kb ov>W3ͦ^k=hpyXLՈfvf{Ǩ!fkM eA{D{8eSx7>m< -[k?$3 iIUUajxꋓ.w2SVj=CvfLIk S,#c0ni.~i "-?.*|GR4h=Q[o+*}ZT6HnI9ͨYJ[iڹܚBi~-5 קKoemXqۺ='ŦO#VpzVrE˩^=!lsW`HSHM!|}ki},vttŰ˞ySIU|nQtKK9cNzΈ(*O0SFBrǿxKNacuC-"^jDq͆ۏs xۓg iVܧ*T*Tڽ!Ze/UJU45X9ɔ̩2rkˌ=Z]4};qOEyj]ci!{h#Ni7思`= k훝W5IHO*0;1:C3l +͏UF5Pi`G_%pN_H}'F!E"5*EjohYMofXR ÷qMV%LEcU[3 T]^tRwc z?6heF* i eLFwe{n b/E8? ҈{V#L'2:U==/!#ϗ,_U'X2UybuOjץ0<`/f{ZCËxcV_ӻΖor'Ob0@3`I'y'zY=ۥyY_W/%5ɡ3,:|j͑vx/y̎7,o7uIN}a>C) Rq)rчK ͎B@ȕ L,g.[^1k?njCmcE3ËxgBற_d~  _(O0jzAO}M;2E_*} 3VLxog 2hfi$Fbq^R kOկ/E8YZ@rPk(]Z†(exemcT'R!˟}҄i cnW͖㙈K,1qv2~_R'daas{LeE uZ>gVF)|})oW=˧iWMv", kk͹ ,}hzZVK~L,vġm='wl3_PLʃBg?{fzZn3c_zL^}#{Z =#G'}k:V=Y+E5#*Nhn7VZm hCkM'_,}UmĒIEq،:Ki uّ2in=Ƴ4ڃUћ"^XiAshA~t4눷CE5"ĐJEYˈ'`e"?=;,X2;t9qK\"䚙S &Qae|f[`!̓y_DKOJHjbVlG][D~#%!ZlP_iV'yǣ7Β5vwx1R}M 9t {Hv'_!39F]n KCg!O=(AjO }8i4XXRwY!죍h[ڸSc>AS٣GjG+}Ta(i#mޤ(e-[]{úd/$mVgDQqj/E>;A'kq9EXtLް?}<1 h..QeeE-,־9'-=TXj-ػ]i!G,m*p6"^j4m5TJžM%ޠ]D:?b3-U#okE OΎueBBK<.$VSǤمi8WO9m6 8}S4(6 oI5ȻBlyCUwE3#0p]XcT3'07m󢱶aK,EՊ9s|q;MMUw+gjCR/*/D#5|_$8)Fȇ OpJ٥6Ӝ%'0,Wz[h­^XxyQ}G6 'Ijg*,1XN:Us}+9/a,Ԅo1˧;ijrZή]3Ó3ѽ4,& +LA٪մ7*J-NVdY~ײ<.WYp) O6ʼnmkv"^sFh#Ibo[4Ujϵ "Ǹ'G_!-wuq}֐ x/BM[' 3U$Ou3V}Vl_QR5#xزr2^\_9g E5 Kи}saЬgv=jعZtO-ø9?^'s w#d7xƌ񞰨{x/B͠aLE ~WS_R>S=1̨,;N /E)X}(ލmԡg&+ g4߭#u3V>MDK8>'αpS/EQ 3_R9,Ym?e" s$95"ۺ,Of5[8aҒxF}\b"(V=m?C Hʛrڑ>"r専^jcheբ ^ċP3KaL XAo]}-q):3lL׺v/Ei Dt^GZ2i$rǧY8v6&|GfIzh\^"IMx~-80y Ӂ;6yeiA=QJ/E,:&Vu05^_~]KZǴⲷS$CuMñq ^ċ oCm5ÓhTY -yTau!?fT9/E866YDQnj6f"Ώ׋\yêX3stx/$&teT;~MEn`i};yȭy̾*]mK2`wIEkb-WQL:pߦ<3fINcu$:?]aKD-E]Vѯ`wD.SZ!}VAK?o~ƪG2LIyxj:,34ӄmguo|A勺Ճ{S8ױE*ި:|}ҧm=|l=޿Gƛ\K^&QgF|ٱ| 2 *~sR^W䪷=H:*]{8w%?}vVcċP8e[a>*gƦ&wVON.z߷N\==WE͜VAwXx1y,n-%W7,Ƌx*Yenj yb;tx^Xc4GG6n_5m2jOLIt48^l"~Ke}$ƋחHET[UԨp6n mAsH)[06oԒ|gً#z{4Q(9PkMny*nΕme]1^˖DrrlF4sq^Ԃeʌ4h Hym:y?%xvxj;lg6̾Żez/{ɛRWpXDv5u<v͝:w;V]#M 8{˃m6x/$zL`K~K'37_jmqZ//Lӧn7d̘yŕ;K"@طcN}2&SӋʡg{"X/*[U8 ^EEٞҝt%6U:^E3kϚp[E^L"x"^/Ex"^/Ex"^/Ex"^/E5K2[j$9l.T%n"@^d2f{bPMcr^?D>Dz"^ċx/E"^ċx/E"^ċx/E"^ċx/E"^ċx/E"^ċx/E"^ċx/Ex/E/E"^"^ċx"^ċx/Ex/E/E"^"^ċx"^ċx/Ex/E/E"^"^ċx"^ċx/Ex/E|>|Y~Li\L.bg@=뵹t15>e^ܟyܟɊ!জP ] 2Y8\~U!^gĸWޕ?*[䝻\r;!w#*T#^#X\NAϤx{pgW)CFU.:\nL ;|BKԒSxO9n\ju5`Nђ~?P.(pe&g^>+tiC-Z>zXn'{kX+U1E;3'YW5gVߤ.wv|D\ZNW3amGb9n\jC<|6G\{}en-tV }4\D.yLr7RBȏLk7f 74;T[]_y[$e9n\ꠁ wa&$r_XFk'^n\HP~6ƅp/Tx2xeK"Mq`E^V8܍P 0`nn8UO}sm˙=/LS)s {!w#*T;?iNeeel}^)Skgꋼm!9n\j?K4ԝe 1W+9܍P.'ݝOl~5Y WPWs)W~]rV7gsCZs2ufs8܍6Йx^f->,Sn|_k0#rŬ5f?I8[39Jmn?,S %krvzD fdoN#&YnSs\i^t?Wk3v>5g OՂs2Ȼ"Vr)W=dTvSmՊS2_kψ|sH +"M,mʥ~[K"1ڸ͵˃bOs)W!y|m 5E׵%KTy[D ^ wc(W˗ dU!r sHZOڥe c)vr7RBup׺g/fV-+Si~ĿXz3CFUW&"u7/ژ;2ER/; X;Pר'6__W ᧽$ bk<^Tۯz+ ~9)Wzٍ~;3װxro5^>x>WtkrxߺfC?Ѹ]o(Wj0SE`rY[/aNoȏ@}N/@=Njr4/*dm~Cb{kxCb"Ebigo[7uO~pI{%#a[w^gG^WS b_fsM_t]?`S!u<s4./,*I'{thOP]d~̣鈖77콘8Cߎ^P ,}C+兣C[(OGn^T~iM7}y])ӽzOCGw,ɲb9*rV\ދ5! LB+z[byqSOjSO-tD +Z_wfYSuƋ.tіٞқz9s^zƷ{Y_ofZ arANGKNDсjMGORЖ^%r}/ql&h>_?]Յ }[ݡ:ԋ[U^ѿZ\_G5b=_bgt/6߲Iu%QrIboїrin/RZ멚%: sE#oXB-m.,OR;^H\.-u/Rר="[u9ԕ4jo䘞ZM}Q[һhD g_0^?^݋F/Ջ4o{1BnMPpmf/W6۩Ŋ2QḦˋG4xq׆yQISkV [^e}ۘN^m6Gn2^\[5Ò(^?񆪾ü'FG9Ѻ^E;|ڏk6{1M%B5yo_}8)q~;E#oL5^"zqZ;~ӋBhqF[ 4$oU(["WK"v]6hcD/xËEe^y֋;ýxN|oCh~^^(i`&XjysYpu^?;̋?סO<싨ssi2x>GZG b@mbGzыG4G}QM[Xj5-Z}q6#%#hQuEej^"R?1GMt[CE4P/XZE#oKxo4.ioqwEmӪU{lq7sD߿ƫD^~ͣ.]xEnyoAfVSsE2#ygӋnݔߒU.51tnz@~qY;fD&G1Mx5$W8sXyᰫr>XyIbrWEї4-ݕ#G 3޿xIƾz!G8=D/&<ߺ!G=U[h#l~E~MOrO>O# endstream endobj 58 0 obj << /Type /XObject /Subtype /Image /Width 1807 /Height 952 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 19792 /Filter /FlateDecode >> stream xyfÌ}ɖ6EQ(IBB+ۢ"-(BQ6n%{v" wc,3fq̌sf9㏟sη{>9wq:PCO}9_kw#vq9cr9@ C!r9@ C!r9@ C! pm !( yrY@Uտf+;֓C@9~yoj TxZt;㾝{L_|طH[Xkr}_}CLy(ǿcտHWΏ띯rW5s|ړnXjr翞z/~^=&W(rȅ{ܢ~TwG~9gyC7k) ӥE QA{1iƊmG%5ez{UQ m3>C@o> uSU }pnػ-ws$D-3)uoؒC@ܱt'ڢn Y;?t8CEX?w_|Ά SZ=^>qF_4{مwęk V_k~S].L_d;hY_n |aO4a sz>ʇ\p}+nhpqӦB7̟γݚ*hqC sgo?j5Q6iCL@}kR%<7ǔ!S~9ٮMkj`7u~F@ڿ xu"XF.O3 Ǚ9uf<ٱqt侾o6C\'7Ι0I{`e 5pu|J +a=[.0M%{2"r^{Mb.[ïq] "@߻x>w7(7>) Cr cory ^>"@ ܳhԎL{D=^0l6n7^梂!WN Cr _ulxY7EK%0rH6HsE|tq<9$ܩ?}וJh[|e0H!c4JhX%@;|ͫ>^"Z?_!@;yϴJ+k-ڗt!9:y÷^/)dfow|{oERrf>ÿ!@O`./e/ì8Ac#r /O~edWiop 9ӧS~ʹ%nr:jaQw=-vfl^OW>u ;~~wF1(9Ac9I[ڿ`LvCS]d' 9y+syu+h9sN+_S8🱿Ar.n^]ߔjēC>#a#z5jm5g!#cǿ6|M+&ء^ʁ}qLz%6$ԞYjV6 a]_kГCo0!}jRMr oݮH`VOIa.uk{ HE!vbgiW=8n^a|t:ՆMR9{,W8·\^fOkJR%r 7?wr)V +2MKDt39w+'oS9؉mOXɮ2ț>r~c%!]񓷥4ZAr4Rzsn6CwjՄnO9@vN2 _aO|TպPvp+~W~a_= ᳮoVOxʾeBvzC%ҭQT9lcp[Hqv݄mJ}&}!^FK5{\>T&|Cx'~"'~Cg`*9L7K]ҝ/|_0GܺIV|A S9`VhW[89H``s'1nGZ;Ҷqr]_>iFOOD`j;[_v/C ]M@}Ör1 %ֿ_ֆeP?cxs>&Uq!ԃh'L|xSrhF߲BCrfћwLE'&Bdj[BT!͓>-ԸL001\ O{us)5L0(#[J!wGr9ttCnJ!׾weI6YLuֆ[ kmt&;-8D@3R4n`_]vy+~;w=FW ;XOm8u1on]PT 91;KNL0kr {e)!7V*"k]?@@/̆ư!◅ 0Q}` 0ϡ/(Jax0Cr'n83?2CrpJrh>|'9$yW lxmaa9se])h7z7!` sss2_9NaX\ MyRݦc9 }x`;A p_&JX|ma>39L;sVyzn!`:D;+L 6u}x@Rm’~si0P\-g0љ.t\3OCDӺq]xCDG>;nah1]CHǷu]G@%=!` m\-,m0}63s9 Ϩf\xCD1nol_@k?}BCn3RC)~a®+ @! 0Gqױ]a9$0Қg˻._xXCr#\naH@!th:7|aHup-j6Cr#%,:*Cr3ev 39$0iCr#NJAM?90rHa}Jo +,rHa-,mV"!9NL5ja_b9$0"7YLF>$-s%!9okI|8Cr3mP~cX}PS`ORCkɿ Y-t8!9bFԶ?$-ffCrC-z {xfCr3]~cx= Zٳ=Crsr~fCrC-f0ov%fCrCe;<PgΝ|TZ| P:bX6fCrC37|vYPZ7FCrC%|wưƻG@! 3 {9 4FFCrC%jcdXu8!9Ftd8OIrHa-Oاb+VFCrS-;>G@! 5V wħ9̒ 6$L//XmamkCX˺d} Z- J>[ca=^G{GMr?wz + CKZ˸Y9$0֮I_0 /aw/H I7!nJjBaDng=v[:K7$% gnQ𒬫k}h{":&FKuiTz:9;>tQ0;f`pwȡ/"$,רS΍cuu&[!$r|u5$,5!0bRTWarn!CA 9RѴwfxﵣ[26rrb9.n^{cVvՙ^>{1VۺL2s!r۪ '9,$mLuT sKַwCFHsm+k]iӱS&\{>~a9D^9>$>v& ]c^1r -yRQk9"½]<Q([VHu!B”npAaEvE%09DYZ5a.0;Hq&+"׭oe~#.}&z5oY+"e/E:$RDoF/ʣnC3 KAݢ2iW^c}]>~a!9D.JtAӜ+x᥏ؿ*[MJ[sCd֢? ޡ^zu\;1N4ޭK!59r8LW9)9$D1äGsx^lxa C\#KAa2ˡsW=}Tpr Ck3GOGq)f԰+,"GxB7q;-3{r~Ur|}9o9J?;z)| 'ȪBN3 YaJ"qRr<8{Yϡt ork#k_A 0_=KJw!RHcL%ЯCdfVMIm1ҊaY 9N<"~CRGaC),gC@ &! 6 $4AdϽֺAAO8}j} 'Й"\@rOU|9ߘ]t?:Wuz9D:;?'d'!˯ x%HU'y'瓮 CiopT·k/?0Ԍ— Nd3+n~~‡Z8%OLӴ&Y']d~mۭ[îBC%.$A `뮗=2^9ߌ2kRP9~OJ!Z} 9\\3qQ+!|K}} 7s8֑|C06+Vvohȡ \wsxտ.ߴuYrC9Ј9̪i6Lo m-ǖ;o簃4֦Rgr_0T9R2)Rurwb7 96ۺ"-~Vr'at[wJ!Xְ wrXI1Rer>JVo:zԊ"/OCh3k9PRK|o=2"-[Cť7tbhT09D޾5lA:h+o3=_Ծ~+͡3w;$ya,]J~㋦E᱾@28Aȃ:R| _89 p"ɡ̀a/wK'ˡ lFY9$= a~U+Թ鑱!js9._fRr\q_9*Ht9DnH }#ΔC)EaAiC!hW 9&-MuTV\)9> J =9w%nopz+/-M#[r>CgWTۢnoS0@|W\yhR7 M>y򶾅+} '}-n'_d/dQuWzdݮt#9l+9*#^3tnCclxA9wl#9NAi}9$!93 }Mh$~ãs% ~jɡb9\*]2)O>#ˉ8֖J%S+R94̈́|P .viKr5._&^cu2TTpR kKe3fpU>k#l[ΧS` a骤O_f0*wIȡ);89B|T2eRurhͤoss!|{t}ʖR1rhIWme a=R۔-J!íU$?9<'o>(-|{-ӤЄeA Mcp#}p:׭ەMZr6DI3~%,oP xN*݆eaTPj}9q1r(=nۅv^a9 pqKr"OVzuFTGHD' {{Sw~z%9{nJpn~ówǸrt*#U89~չSz>'9sJH w3~qV>vJʡss'^xwGNt0$~aX~3?n3MSvlw}h~?!9]ϘaiFΖkMu_6GÒC߷Z rXcpGprn9zr,<]arT"N=(}a{JNas9ĥsڐӲΑH{B69 -s0,thztn _n{ߚ+ݴ{;{fx񵳔Ѻ=Jc͡RR4p0}Ԟ!?ϡijx|-C_Tդ2ї5I}Ә769O&L[ȡ/R hCC@}q5Y+%3lKMf&1zE~ݰ7_JJ2~EXSzQHg5NDZ0s9t{{PcuH̎am)s9Ecں⮱00U*˱#5jTXz''1nGZs=89 Kw3C&R]rAm˗n{7~s"n_-Ja$s 9'S׆ѭ9إf_ֆe 'ǀD @rxߦC?֓~k<&Uq!ԃHe&I4sL_#J~ 9o4*NJmEjjL;)v%!Dɡ_XEjr9vۺG*c#5kD\4$lQ ) rMRay_#JR-rƅ at[ߖkt{*ĶRwrH1R]i6-!o<-__cF.|HWkBrN/9n *KmR֍o>/^~i@iv}Nrh\CӦ~Vj/838rp7:31N4ޭK!~j]%?@%Ф[ݭ2hYr[^P+BXYE0C2ijU=M+uvuf60Mg a, Ps<:*% u^iQZȜ%!.͡%zڛ}rG{v[6g?v0$Xv93]+Crh?/Za!94قR8 s|t!R:]J|hrT)rw<9yB?1av V9D~c<}6[/#ЍR]@f\ɕ5[be"a.t) sX\͌$0/O}Ca_"l s`Fի!_CxCa9Br s`L/)rD,9D?CB*7 QMj}90(*U䜥Hc]yYSx#99$.Ǜa9\94؄?10-~zp Crhgrh2f94әR?rh\5ɡN.Efȡ%[) u0f05*RRR rhե69oѢEδZPCbC=J=UЍ98E89H٧rt[WHyUv=ca:{sFt[_nQuܬRcEYP)bK;#="xܲ#&ԈkX%0T~qm+K;rUYq}a~!WKɡNaҹ_v x%>so9̥v>r|o VoZwy5?g̍aHx@sK̡ (5Goɤ45뉧\T sKΡsE0=K<ҦTߤo8M_Ǥ0FS޶sSQBZ i09z jD3^46G?ɡk[΄rI&!åkϒCzʪ! r85K ^Tuc_a}NR=zkIv3:gT6_e/ң9wr[X;w +|89O*199tD Yst.{R/_qr _W C7N/bOra3BU!SȏȡR4hQɌȡ~/&L+ݺ^`S9F2ffċ1+Zͧ᜜im-+ 9TF:]K__j{H$ r\<ŭ|XK UQo^b_+MZkIO3AGN ך{K b| 'iMdjnOmk rbJ]x s{l]TA}6]q<:CYs䰚8eҕ|ͫuޜGSt1a!ic[zQH>|#NDZ3K2P#9ΕyuHDbrä*<wxUbں?ƿk,9̩O*1rC ]fP^P=W"n9p_9\58Nsfj>_s9gTVYl=O?Cr#?(bcih,޲voUV-x9k9"j9)7Jh9Hwd`>߽9o'gws ;͆~dʯsȡH7'*T%]8i}gɡx@.3~o8zWw7/oI5asAjnkS39 9T~ +/m"U'>aN as!mLuT [r\a5֝RrQWVȍV~LuTIX Wrx)V0ϝAz %}f##a^;k5 ť7S>14X*qR8*Rcs7wim/jWpsrO+r-(|.} 7&JWg@.9h Z_)92HN WsgH12ȗߔe C_ {þ_9\[T?J r' r|"֭[OCtkr)fCcY(E,Z.$;')rbX@u."Cs ,g%94:{+w,D FX=iȡ9&g94:'X@d*"rhtz Cscu@ F0ԏZsCst5X94;?S=,? Fp] f94:UPWrhvcÄvC,= f9EKȡ9+Ռa94:VCs–ÃUȲrht" d94:ݤn: FptiCsuÚrht+,905Vʀ99|Yq`l(0zi a Йؙv9t&x]k:aJ_n:zstjlp'rC:7ÕTl ϡ:sg:18J:a}ғ,5 JohZƱzpT3.U-,4 FpG)c94:HR?VCstW ȡ9'9"r@ΡSV m>]٩ȡgrůǷG{49}se CT 0KÃU= :[ |ygֿP~h9<{4uK]w6, >"uHd]9cRe+o)eBQ([VHu*_* nDJoIQ@ [΢rNEs$CoY+ &%=ϒr^/ʣnN+gI9toF.|HWk€!r.V ]pMJ[s\WT,( ulEn5xĩS'ywRvr7rCܟc~JٛwXN@361l:;Oc9)uc59KZȝ9z:iV,۹nٜKؕ.e{YL@s/s9$HYJ@aRVCsfrh|l@*u\fóMu~r1K]YD@xICs$Twÿ)Csx:i4+ȡ9|Hrhvߑa94:~Csh_pȡ9/q9ȡ9LOrhvJqC f ]qn,u, FhM9b94: X8@aDCs8١:Y7@Ut ȡ9G0~d%9(i-+:yÄ, ~HiERy×F9h9>HՏƇ߲V9TXY@^ҕGݾ9l+u%TV\2Iv]ֆy{Y\9 }WaeӀkRx WrxlEn5xĩS'ywRb23j kK>)9@wW,@]if ctv09/Ǘ37/{Dl?rg.9L(gr7͙] 9~- ί`twTJF58fA)Lܺ5'9|Wj||/p}Ef`]̾`U=rEk} [_=r=ŭnRK|%d<4'9gr#@!C9$?abՋaoίhAQH>d0NDZ`XHbr0(1mݟWk,9C\񋸵'1nGZs=89V_v/C9\be>~a9Ǥ16ķzC9F߲BCF0RZ~KB C9hIF0JR-r0"+}sVNFpF.|HWkBr0".V ]MJ[sC`يkSNf֥\EŐC!9tjdho9t:g60Mg !rt>*85ۏܙ#̡-nesf/cWBvdFg; s54Tx3_0!QdM*2,&` YBBB$u~>7;-8JqEL!kNKB= !;;r%ֈf Y'N/)(\\ޞG)m8aZrK y\f0IBL(fB=:Fʽq̾f(*=֨`&PmEa&^1k/9SV'frqGٮ!+s?ha(M_{SJ:afIBEIS*g&D3,=r;{loJF]K3)fĉ ..DrTbC8qDC+f(YqTR26V*uf4#v)ַ͊)wZwٗz*Ɛ 24I3ZLs]/&)ad$I3}fu8D2ܚĔ㭻 9Y&gGSKwE^ YMsT㓿Icd"B=(qBqkUlYaN1,Χ|NsN3񶽠uj۷ۧiOZ6_Xw1r9nI6$2rP ]!$Ya Iˤ.ѤNƕzGsRxQd͟myUZYr%"qu]Jĥ$` SEzrcN%['0 $HS>" 9k5Ì" JM2RSjrTC7sz'NOu-kn3ri۬Y b i/NWx="#H޳ݮr,bWMhiT2bt@ 9R{OK)e(0羶G)w[I񔱦RnƔZ0rKH=C.M9cRգ31LyuQNz}~NT.1kX]m})LȡUp̟Uh(Őr.@@@@@@@@@@@@@ 9CPC9@9CPC9@9CPC9~X?\1. h /ԧ endstream endobj 72 0 obj << /Length 2497 /Filter /FlateDecode >> stream xkok 6~Ip/IPe1D.ɿ.$;Rj^l @Y:pci^աxu5U~sHFN ",sHo?=Y.@0?eO0&a.B9j$=Wh*삤%)9 ɚ-51z'@BLgHJāL1b]͒F]b/pijl&i>@ӤldouӋyXuUڡ .6pJpD ̀E(1[Ò,tNͺNCI&B-####\w]ycS,z^f 元2[Az_O>p؀22]\ mF2砇PF?ÃY"@\x\bC0Vը9j,6}?ll kQ# ̕5W퉫RFpd'p֠ݔa\ۍ{ DBIYIjc\т;td٫W6 8'!6jZcr^ 2&q"'WYi M! t~~N4qcDa7SFc0 X y]]B!FѶ!QDJ͐:vC,p:n*[P@(Njl7"qf|Z}6PZ6?.%봪0)D8}-B4BQ}L=1hr /gyӆP*g^-ݴo:F` I?F<'_>rX82jF݅2}*a&-G0&$Amǒ&rӿ輌YW]It%ٕCagB YnI쪚KlWRc ]4eQzNj[ *7;`@5RZU uƉ;!K~G᮵Uj:DFQ-UJi4MmjjM43.܆Ĭо(tM h/eGj)&L_ !1d c2A@$9`|8Ocg4e@䤵zeziF;iZ)="YW;R`=e#Lvϋt;pL*o1%Qƒ)k 0%|P){͏#iHiRj擱"<O?,Ȧid-B-o)hˆ8[7^i|\Uէ]MHc `>jiF8Ϫ:4xɆjg~BJٿsB{3_{Xn`[ʹ *O괡%@%!Ým8eyuB ]`IL$N&9qj0N5l:$LX onqOCF% .5VS\_%ŇWPw5 =ϘZs À-`{?[J!ߛ?Ra1z,%oJ7yaE`H=k}ʳÒioǏ;8Gb(X:$[=FmH tqס^=%??0p^ථ\7P_ʪi^溝fMJP (xdiN/TиDƳ4m^XV-]8 ρ45Lߏ;vrgW&[Ŷj,Z 8zH˽Mupzmb~b!A pnqSECFm:X۬o7l ډb"^ll'-2Yt_|"5fZvt-8bAhɆb_wV-[EQDE# | endstream endobj 67 0 obj << /Type /XObject /Subtype /Image /Width 1843 /Height 1066 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 145014 /Filter /FlateDecode >> stream x XTUq@AY\K-%̵SR˽l޴jfeYiYfȎ(# *° 3ha3瞹3g9oܼyӦ2lmm:v,ZO֧={V=aG}wԳw ?~޽[haoo߶mۡC.[,--FnN~z377ntzVީSxbz_g2TeY]޽4l f>c}wϯ#M0["Z4l f' pϞ=kD&f0[VVIח@, O^5 gÇǏ#M0[5`Dz8'N?а M6Y{֧`VxxxT:tGG0[ `#%?a3 fݳAfS0~8p;>CWWWW_yl-nz`P fSRR$4Mfff\\ܧ~کS' nV+=Xϟ?ߠv޽X_?AÇ[f ̢ fN~Hnj.]2aaaa޽3VB?ޠΛ7|Fc.X߾}-fQf ! r0+ nصkWs̙3k֬9r=ڤIv=#o \'O\dWOO8pmO>gϞ[vݻw'{djE~~.\3 5pe˖%''tΛ7O8Xao۶<;sB1f{ -&ƍgݨ`ٳ6l0aB޽[jeooߦM+W|衇Zli߹JJJv㏋g[nӦMOVM zϟ_|AQK8L *{q.-((B'I}Ν;wͦ,[0?~Pyyy 馷JIIyLLTۨQYf%&&q5 &衇ҌU[ U*ՓO>iggWe#G2%yB/ZT=%\I71P?+66V_ ::-Q'pcǎg o4.|M)oTTzn9UxUiuf'777c{㏧s5=v ~kbb .] oX_~BR^y=zZl)4m1!-{x|&M.**>) 888̜9Sv`LNN^_ {~U5,XK0{wtt4g1?k~>}*M6/^f0ԬY3WF>T0/Sz p}̙;}1cFMo f}||QPP z-idh/_.lBya+ӻ)|ͬw:V3 1œ:|Ms _m`"^CVѣlp {OYm!Ϛ5 =s̙¶!==]%M۴imٲefVmf0;l0|Fu9i%̮YƜgC_̩Dhl*?̔4Ko5W¿ fԏ`SzKRRl896olŚ_@#< Z˦J:w,d *SN[Y4{ FM65xYf54?gmKi|`l*NJ8B'<9lj*''NƮQF=BH{{T0kAOPVV& `矯ځ#^`0[_% '`lNNNbb_|!\kK?٭JKK+-ߣGO?ѣaaa}F͛7W\\k疬Z0+[aϟ^W^m"<٫=3d)̉„V\v.AyUf-5 VZeN_C2`dYk,kYFo׮]5Bddڭ[^|?pɒ%ƒxmxxxw}&_ f>9nܸSҥKd2q`䮻2M2eȑ?^`⃞O>1BxꩧƎbEիWe:ݻ{nu5W fXE0[SN5S~AZG-_L(]H9k-Zؾ}~?,{%?7gYjAmBkx{{KK]`vbO>ܡ?I5ͺud f5 ~i]y5)`V6qttܲeKbB }AZxu 3g\BJCĘ6iDb1ʖ YStRqbaѾ}Zj%YYYu5vnݺ 5+_~)}Ř]fWUf->&iwyghhX~~E%>Vj_{5imAAAn wiɒi):*J5,(9[b *~a錎Ғ[ׯ_7b]vkc{I5^z}';ujzz9.u-,;/hfP`^ٳgesH!C-If]ɓ'eKٳGvd#[[ O/,ƍ͹ U6mԨQxxNl{1?]zZd4Țjmnڴ|dy+yX();EuYz_}X˖-SRRuVΟ?_Zlo,\PZXZ6+'Po+Vx/J7Yh?9k&wΈ+8sLe/KKK76᧰F# לi]Ν;'3 @ZXv횙W/l0[f`XQNNNzY[eggj4+ f,Y"-6b;J7ywʗ3ge+,++ޱ6tPsYny뤧e˖Ōݻw+W6lX]1^pɊnվ}{ل<--M]Ġ7d6֯:u`vʔ)1.J>}:a~Xw=,%H0+\e[ڵKIHH]W+XvX3f0璹‹zV{M7z|63^z)\`J 4HpbbbMi f7ٳgX СCŗ͛Wݨ`vb&v~n#/ӽ{w餎{ CT`ĉ'-LX0k"qPt&ǹ.Ee*oԩS-Z|F i#4k]V/,{ի+\OӘUb]s`zFpe6b b6qK.H0kfO6M f'L [ٳggΜ)[X6l0kf`vϞ=MVFOk)رcfKeuڵMVa-}#GSRHܳ*=Bu떱:wW O-+%;u~Z7n0}&M$`މ,8e z=+ʶ 6g&~0[k_%]O0 @ ,̊uJcN:׬Y&hBIk+RlJJx㍑#Gmt+ e-Z-H|-L8l0oi+++3d f׮][fɓ'W&''K}zٲezԁJee5 f322d|9sk z-}⯳?ꫯ) fׯ_o沿I7fQԼyNjWvNisZ0;n8{믿JZjU-]}ZjeU.]LoҺuk{=i___oC)>>ҭ>CE]"GGGzmz.]X*'7!+3%$$Ɂqqq.iEu}Pj5tvڕ/ӧOقK 0?O~~~dL0[#G+{ǍWaJU;Z l;vtCl$ǎ`j6H{=]JB.t-wwwӃEYz6l0tݺYUVw}6 (zYJP`ŋm YkZWsZVwoh0{n;9sFpvvvΝM$Æ ~_`Put:cǎ[ X\t{ڵ ፪s L-СCD^^^]4VܹsY|Г]T Qvz[ NM`~0[?FyTdg`ֺ f(A5m۶I4hP2˖-Ngr.*ߴip/$`VvXx'''c>yd?e ϝD?SJ˭N0{ ikɖ :0ѣGC~:٦MuUb]NvZdd]\\d=zAD -i*,,LZp_;k^?fޗRt0{-ٞ˖ ?SЬY3ehvx٣_dݾ}l ]IJZx͚5< f|W_}Ktul;vH /X@)Ġ' iVZ~|NnՂYa?ek]%PV.ke esDJ2'?4]~Xw}j` $?m…7I(?ˤWu iGDDtMfk45dM*\%&&N2t޽{NNN5?e F!}7 M6ɦ|ҳY\\ܲeKiGy`S ٥UtW3/CCCNiI77B]z'O=vҗ͕8:lM z/_΋dN9/&KFqvv}}1,ݻWz_l' 뮻Ο?/۪V2ge=Cu}Wa*YB;::Z..\&6~m|||bbϳ>+믿^k a?챻{{{]V#FHwL fe'?߿Z(/ȑLj]bdM-Z$QF}򮮮?u-[6f2s̩rgT0+jٲ?>c OOOce'E cpvE9s棏>ڴiSP`&rW8S'N`ȑl׮C=ԯ_?cOvBFӪU+ُՔ)S6lذgϞرC%[gPZMZrӦM**55*J5,XE0kbcKThm0V7o^V3f lc Gaw߭a\RR//*T斑`B1)p234GՂٚW^mRܹRoԨQ ;T{Ge7UUb-jXPx0i&of̘QjG){Vm#n8p͛77X`m ThNvmmmWfʞ~*|g͚esεk׮cdk`gϞfwye]egg@.]:vh`&=o& H;[6]OnZb,ybW_-S<ٚfE_vԩeD'sO`V% ?&L7sO W^-;1c{֬YW\1QOmK[n51>kiK _C eYz%''?C&&bfo1'M^xA`Vӷo_sOkn~Mv >eV]_D>|74hPNÇ[՚J]ԟ>}_.-]]].]L0a۶meE7ŋdwq}V:꧟~\:srr~駹s۷}B;HPiӅ}{ضmہ.[-ٳ˗/D8,ycƌٹsx@U'A/.._M69?BvZ͍ᢀoo^zhBkkɒ% 6F4isڴi| Up~֦MƎ{1̤V'MdSmg.**=}D...#F^r͛o?޽{۶mŸ“/Ҙ1cZhaW~~> &̘1C:99-X 22N>|VZoVc?T ZzM*""Y/vEVWcNJ͛7Ybe˖%I,WWW1J~mZA͍Y... fu:P+m S|կ-11QW^-Ț?v-77:UtI&͝;Y63tPJUzrrrfϞȑ#-3k,}ڴi^{-66Vәyrr+ڴi'U7ozzzѣϟz꯿z׮]{ ]W_0aB֭ 6Pմ*5~xj>ѣaaagΜr Sdddlٲewvv6W&M<==M7nP|mmmm*Idرǎ LjzҤI66{좢"L۷A2boo+Wn޼y?ݻm&)|xHHmUp7N2XسgO͛/]DEh4K.:u*"""444$$$<<ɓ*J᎕}wkmժUC >}&MxzzN6o6҃}IOO#U>ö ZdرǎC&@Ħ=I&UٳgYс)N+{c cͦdee buqq1bʕ+7o޼}q۶m|饗ƌӢE f`ti;Nq:|dx`}6  4c }`H:}[jUYk9vYXRuifHO.?ߡIr|6]m\ f@uРAU';;{ڴi""" f`]vo"w';!f,T/x^tVSUYYرc͛gO0 +rn}%G'-NJ<]N 2yxxe˖-կ-**J*`VA%g20}Ozbs6$U&WWWW6V fO0 ++()C䛿-2X0tNNNBmVqP^TGJTjsYeOe_VD^zY@ v@Le#Dh4`Vϟ/nݺV*N7i$sZ@g('?P 2EDDСCU*Uə={#GX@97ݗ"*֬YjӦM_{X=99yŊmڴWOZ˱@R7ٷaWSbݼyG=իW׻v^sڵ ZnmZc't$Q f,++k66ydD[с@9%اcT6}pn|n$UW->|xHH2,4T`E,R-|ƍLaooo,uttٳPl͗.]҃%^( ;KL0k4ͥKN:~IJjΩ#AT6x]΂BfPWtZ:R^ʞ}m߅` D0 ZV|c XW&ގ` D0 Z-fg&-N:yP“7o[BfPs /bw7c[ jtf@,M&}ozwBH0ַѡGϭzJͭ]"jRGO~萣%G'-NJɼXzG9ޢEl +<\]|+$~*:Z]TTVD0 "SV|_zIcXFaN \^|6w{9 Mb;w}+5…B]NgK0 "kQVXve畈vأC&OTmU#B:ٷ\/3#6nxPZ]ZF0 "ˉINw|=&H.TTwc1ur[&L#jbR֤v -4HN:=.NOYΞWZ3Bfz5@i49iw51*}OzMe={[ #Y77 RZۓ` D0 Ы Qp˱b7_#\biVrv5=dh&D^\؆%j@]ѕó/||!6AX!̲3g53Nw{ǎ-Hu O3,`WjSivug>sc~N~awS޴.Qb23o) f@PӊI?aþv06]PĨ5)YG <FaCjӦ~b$۾}oeXKBfz5&_-' j$Mb}w(+_)R쬢'<"F4Vt.f@`)b퍠IzwoZGU}T{ÎɲB0 "j?!5H?g9c[<ijNLN*)Ѯ_y?}3Zkܱa|)$;!}ozz12Rla{X}jD0 "JION.>*״9突ҥKgNޜMY(,@';5b\2^c/{jq9R֭VHvSO\XXN+,`W@\P2Z׮[+66^bY(,@I{K{i˥C6_+ M=9yp/f@]NX?g񑩟ͯǞHM͛/if@F=-K_xuMZߙ %}O=t~iy'zEFF.XW^nnn7W@tZ]aW1$uCjcgϜd7}ᅄs f@FYYYg϶1b֬YBxߒ=z4klҤIj|{HHG.y{'4ng$kgS14.@0 "ӧIS&FwyGiӦnnn^^^|Aaaao-B嶶jD;d[I)+*RDg&BfauƏ`ve˖?sرcGi+Tf}ju-;r|d#-E rt/F&Nmȝ` D0 R SUZ=p@}Cl. hpn9M^d33o-]W>V%DP YX4[[[-\Xe222ϯ]Vl3$l޼YZ3<#^Cˊѫ.E?d{lNdK/Nrv+7."2Hof@"7nO;cXDDؖ-[Ϗ=Z|Rv.X)St quѫ@i%s3u?livi?ys #Ï˦KHBfaEL";wwwNgYuqqKN>]|>}9d*))o6lKcƌСCqq1恛=oy*ZI?vvHve!ŠxxxnԨQK1B,ٿV⓲Ӟ8qB|'(|pp;W#ٰaɚ81J rlf@A}hZz5(T!_d%HC.-ٓ>`a}$Μ|9f@.]zjӅW\/_KVwA|rΜ9>RN*>߽{v)>@%v`.UtoAAن ;#Y OG0 "8u>kꫯL޼ysχx:tp]w.))ԩȑ#PsQƍ[+V$ld۴ nY,`ftlIZ^>2~6O\dd>Aݵk۷o/uv%Zx666^ u]Zp)gg?}$۵k Z:CBfk-rN\hh>Dݻw?ѣG ^?ٴif͚ժUEEZn޼YPnl@sh4EN7j䫿:oeh:zBuBfkTɵka={Tkoݪb~0{n}ᰰ*ݒ%Km/^H:;=V8xz|׮<]v81ȑ,e,`"<<\~ o۶M_fRT¶-2x}ѤI㏯Yիj[7n~z>wO(EWZ Ͼ`1:GO Y(,ɓ'Y_mpſΜ9S3g{Vi~jٲB^ դ%#(_{_}$v_+طnU98Sٳ E0 "PT,tڵ \R_J%'=qℝu?[oѫjN%-M jWk/cdaJa>/&lƾk֤jByfa-Zx^}UӅ_z%d&M +Fcƌ6رcq_ ׸qc{.**Jң͛'>٨QHz5jqC}cggn]]\4p1dz5` D0 +ҳgOM0tI1\xzzV- wQ!CYwƍK^^^jX'=jbo㿦, #?,fAb*22J5` D0 +2eܵitILӦM3~N׿a}VtyxxH0`Xŋj0ru';_ك|RހbI5)wBiRvbJ0 )WrrbO6v)nXCϟ?_v7|SvCz5 $zwh<6uЩN4L#FNN~۷CjZ\NΣǏtF0 t>q]bb˗/ښ߱KJJ:u$l5rH8 Vh"m?CN&GRulر}L5]G|b*ۭہ''5d^: ,`e rssju֭2cƌ1fadXRSS fst z5Negωk) <IuVm/&Dfg[jNR~X;__ `MӦPYXM>^!vݺu۷oжmɓ'ѫ4(W"@cfn3denvǢ4_>mڴXktqҤ$'?? ɑ-L0 "`Rui8]'?,y֎i'F98-uwx᥂fd4-N4Ɋf@̑!D [f`"-xVĉQc[ 3'ڭ[Z:LF[kLDDxvvBfz5-&-MsWT EDnU+yg&,+[j ld^nVP Y^ &;9nHmɦ^_Ofg;cGΡ'?#-kRRe3Fٿ1,`W,].eM~b*{tтsHKKu'NؑG o2PÊaÎ-_~666RtNSٶAA ڜ` D0 Ы@b᱇ocɺz;[wܯ!?:v y챨??_rwl>+CCTf@ Ho/a=rbݡg:8=wbÆnfg\AYٸ1uoL0 "Wr$(1g/;>`||q5gŋvrd^i)7*KviУG8ȑnUY(,@uATVttGdMekÆyW>²,`Wy;Yqz+~VsmР#m*pŊ7oqҕ/Bn(ʥII` D0 Ы4Di;ZylVU=8,O5k每dv KEEesug??۷KUK0 "Qecuúo%-.ٓ>qbTƾHoC;vi4:θ28}Ѓ܇ m.A_r[?w+R @Ӧm&=#RڴiJ4=4c/2~?O:Lo޼﷥\.*%%f@fЪ LןGEQã(gwbc[]d|~5.7/*9 !7K@fЪhi,'4?Po`4Ǐ籃G%̬ǵfA7ITtb @G艂00*LT X١ZLZ[s%/pY$7nT##**'_fUeMykÕX6Dǫͻzz *+u,͍XI*-ln)Y6"vly;b.YF,`Uky pHvV\\BQڳ!eM6899넃ƍO>]^ց̂ b̘157n\77Q[n޲e!tɓ'zTeX` n}|0:={X'-[##FחEd FE籣|ra~SSYD-p8ʕ+Ywfx_Zl|4#e,Z=}6˒%K2-2_U__?vXzRjyAA~vW*dݻwUC+DS0WL\v`(?Pnc/͍^m(Ar;,*K$Zvnn)!e$:ՙ7oBzjkk7nHW̊G0 3x`VRY]:+}v~Sٶ!ĉܶmݽ'Ck$u~\[ݿϯWB?*I11W5YYrIzEEZ]l Yfzש2~x̓FqʕTm +,΃G K$Ί%''ł˗/v8T*֮_ͪLj#GU}34'ޱIYܬ8rKJuv/.," 5 gJJ'%Y k>zLҢwhfӳ}rRSSڼXqfuΞ=f0~z;x&Ņ*i&z75B[t:;… ۬Zb|-=3Z5Ż;˯{9eIXffѯ_5+M&yȂ<^a+t:K2+u]222BK6Xqflڴ,A̲e˺.d܊Zങڵkך/j'(\r&P~~СQr8_]kn66 y]2΢E0LtAMʊG0 `>7!m߾:9辵| p۶m7:v3LJ\mo|UX-|RVTU&’D;vlt~?Q:XQѼ6nJ++ay`t_~זC6m4V>Y fc?1jZ2fƒZ5<,^!^&vbV>VʕT*eKD=ArT+[XNYƪj}۷oO:u+?pÇwܹzj6zzzj4;US-5MJZd21Onf/^H W{!/**V qG {uh$֯POHe{P^c㬸8zzO8Y&SիV֭[G^h8Y fb1}^p:Ϝ9C66J=;fUee姟~`~:00h}ސLFۓg{ud"6oNR%K--&4BܹsRt E\2_TT?~ŋYwft3ΦoSNu]_7n~~~T{7CB}w j?oA wG- PUR2Iw^{-Je΍oh0IrnUJ ZqdVS̲EIIѣGׯ_ikkYkoo?uT؉'Yzft3U*{aHHwYѣԪYfUXTRsXh$x͛é~~~Vjb:nϞ=VVV~7Ъb*8R0?!nV\_|*M<&ϨPR ,81<0 ! NDZ;7w@&a~~RmmɄ e_.Ǐh4Rh\r%U+ŠG0 }Yll /0uTWWiӦIIITIFF5B#GS1bݰa֭[' ѪSmiIލWSz5{6BBT˖9_X;5kR/_.kmET@VFmH t,3h~RSSڼXqfЪSωc2Td^WH:F6oNwt 7";wn_Դ<:eZq Җ`\]]뒑൙L&jJ77튊kz`CfЪ "G*W2d,H0ҋ|߿F^^#ǃ(ΪT#"X_*UH{ Yfrqqy,Adm='OPT>raZ5Pj}޾00*/ w '4,UӧK{Nf>/ukzTTDy]]7/ozl,緃8Tɫ!e&z(/kɡj6mZvuu-[=,Z5@_cj5)TdƵJ6HZK=ޖ_o_ެYqRYׯW6hQ6(~wv e۷Seĉ4m"A>`&.Lu)²vX5œ&Ŵ cmlSC Vp>Sb &rV2 V4fk˖-toJRg򀀀Cҕ<3l9vh}AOV2cǍj?@gg cW&'02VMMWɰݗ/_}?ԩSϟ .?>|xΝWhFa˱#@lݝ˵3||說"JR[`](7 <j~XLDݹUUZ'2RWZ[U @`/3|eRbaǘeoFGӧdž  VllCE qN,EEE=.^8::u`Rt44*Wii3|ǫ׬Ip~`+0UU5 "JeHE̲EIIѣGׯ_ikkYkoo?uT؉'YzfЪ,IgJ}:n*;;NɘL&<ʊfMjJ;T<'4t_^ 7;!e#P\\,ɒAttX,V*&,Z516'Sl Q:UHGa~~H'bgNQ!,\i) {!B0 V `aMF1&-Jyj'6,d WW 7kAodvC0 ` T6dÁi^z)1dǍ=ZԄN{ʭ)B!ΈUj8'lS0_? '' .\PTTA0 V `1}x*MYbja :etKcCBT9AQUULS}YZ}_`ѤRippCŵ/O lƌ?#,Z5eMe%J=[Җ!tkm^|~5&ikLf*<<|ԩ[ne?neeկs=UUX]N%RYF)>&Wo ґaQ)*}k3yL~H[9 eÇw:fϜ9ӯVXa2fЪNWMʦ?κTprTfŅz j~ ,խիRVQ}q0uΛ7ORS?ؼ/^dR4$$d֭?C;Y`)V?{=ggg77Yf:tww|s8TV MQ|*{pZ9&X[[ 7ڌSSs0?dWc>1lU*W$-0 Ey 3cvX`tVkۼy3U駟f#voə3g~W7o$z{{dժUt &KǏ?c:v_J(vfT\jx?TvCSY#}ŋlmy,=:oj2eeodsm\:_âTĒaQèkpJvCZD,ϟ@FFk;uUc#v={6}?l?ўT*0a]?oS **^;:fܹt6K#FIKKlC/**Bx QãVU^\5r$Mkc]010@"#A67TYY"]K ~A ׁ !@`ŵ3 &cSۇYFrrrD"@ss3áTVVv][JJ U8|"tqΊfǍfU_\\BGGG̢EW׏;Z^PPK-jZ\UUU׵kXqfE^{5:qF%_~eVT,vl۷Se{^~a:m A 'Nh_mU=1Z5bm3i Cv,"j6a{/TkqzjHdy;(2򯩩juKo\Z~u`@ꞛ73)fo@ff&kkOЃ L2gΜo^~Qzygknpp0|"J׷P9r>t[ w 7O!vt =~5w޻6^'yyҾR*sp,X78#3gΤz薖j{US# %$ v|W "YG'55|oSj ]e9T%ڒsvPeD ,3}ts…6kSSSvDXqfElmmkow]իmM/.[,YB[Q ;]vZ|>ZV pOZndeБp_͐}3,*80">^eDٙqqpN,XNCζm\[zȐ',wg[d4^p_~9""(66wߥP dGEqvvf#iEӾ{n.))&9ۻߟ/['P m~zcǎ m}||GF4BC E£"ppyʔaB V{ݼوKt&.?+KQd-W:~Mj0qĝW`D"Q.͜9֭[Wz+Wܸq#''o}農9̂婩3fˋ?҅4ѣ~~~]T*}YjIܹsjU/Mu5͟UV93΍yTq.L1$,X+՚5ɚ{ ,}ᇝC d'NE 8Y0/+WЫd2|PHME=z4UdkkFtcǎ%/];ڏ]PUŨ=ƌB"_ߴf#Z/RVs8' yґ}_ƛW!Yvڄ ڤ^^^g}f3l"YvqftR~|'GHIIW?Ξ=K0_~&N(KO{r9АJӪz .ԸGP9/g .\ojy*儆EG<]]eJ̲A/_. ۗ 7o^Lfʔ)~-ٞ]C?F, 唶2 4h}Kh4eA=i;t%pBBBrvv߿χ~Uz˖-ԪzBcwCv ^"FDFWVX ]E<`@:y=6 P#$Ν;t|j6B0ӏ©.JZjje5J7d֬YmC/^ wڳg}QQ%jPgPǩe73dED5pPʊKpWTT3Yt u ~5rUȉ|w7oM]&^6'~4Ѵ6\:v>Wz@p^o_X,.\ugΜ MJޞwiO?]`O?xmjx͊g $~\xz}h$oϡҢ"D\`0lIO5 1| k#_OI+É;*#B0 uOMM|vv6]ԩS]Wn>׍7u j| YoAKbj1i4Sʜ9O&xX1 "iqR޼R&lj2T`4r$?+w&Pe$/A*ߖ~kfEs5l`̸O$>#aܑ.2j!njSٳgvSR^TJ=Ԇ!!!w=z(=gZ5T*zl01\ۍ7 #J]TTERYrW #Y(rImGs4N}JeGGfg2m!vyTvÆ MS:H7n~A[M>ݼ-yQyzzKn5{l@QQZ5^ M&6hdD^^ŋ{ã̇pB?@KӊwdNt$;A R(F#N+Դ,L\H7^"/U;`,uQ5v+iڵ:N%wUnnn 3w9jH山۷w޽{;z$Jx^}X+d͙EFFKܣ222l\:R tQf?o:AY` "{EE}P\\L'{w2N;v,ҥK۬*|w:> \v XAWcɦJ*:A .^.mxq kcE[9RUUY%QjTټp =x5QmbzN B0 O/U@iV4n ֪VmLL =laQ֥}f\^f$jbL -jqrsV\+޲ڜTd#B0 lq~}n:zڵke2A&I"+3">&tPHGQQ89|!TGaam@f-8Yii^|̙3VTw1,e۶mt'O#bj`ywc5Nh9gEn8:)p |RV6M$#ّ|`+I9}3.!`, fzذL*nE|4zf\ ,(83U}2I*ykYfB_ /L:uڴi/rRR=UA{ȑ'Fagg7lذu Bj`[MWDPdkۗg27X3~~~͈~u6#e梩©T* aAMk ,0Yj@4'~c鹽Ww&UCP* $P oKqY{_Zdb"pFDn(3,jnN߬3XwfU@ߤ+*oFⓉX OL,W c"Tv̸[p}{YZ$x4ދ rH|G!x8fU@ah4v٢?Va,_IZt.0 ~Lvɨ̈ %M.MKb9E$Z9 9X5A0뒯{\fUkoTii{rcsv^(*:.iƌX*6rs]\kݛuu˓#7nԴ̰A G_wvūYQ`V,_vM"1PA0 V U200069\D,*P?277͝P4/#Ê˥ڔSxɲ0I$I1䱞"OrynC,cW 6kjj^x~fg!$fЪ´VBTkR b`D_F ˿V_z)ʏ u?np ]X.\ÙaWjR-vGΎa,'3?a*w f ΝK[oey:n:&ԳfЪ2hZE"qabc#GRy,g}zTj|SֿݎCFEEUAT*EEэkMj&̳\exu3n$4'~mzƒ/k_}QRjgi@ pqq6oѯsGE fЪo4Vܬ6F};W&LЛ4;at[[.'X\^_]%kN||ZFX\]\'oϺuޱ3X-ve/_VO7̚LiӦglMM-ܹs٧O>|8pȑ:tSfЪuMj~u޾ߙsUʪvav]g\-/{-O >SK:u fCBBHvٲeͿ}Iz-ϧ+ mpp0n `X04MO&rmmXH on5+O%++5))4Q⟕e _"" ZL&dlʬ#GZwڇONYMٛGW˛&Ƭ`vӦM̝;Zt)ۻͪ~Z /Zhdr*!mpɅ6-jVSHjT!6ۇeδ4r9=×-럕UՊpǩZT>fZ_yN_noޓʓbc f9.]988PkڬԪ?O,Z50 a $uO#rBV0^Uv`is74#Gi}0b/ _OkFVE=M4 vP䠹sOUMP'q0rd?FgggY%q bcc۬u=,@0 V Q#IY&! QRjKy{E' R45*zNukAP]}߅{tX[Crr]+İ#onGn_JӤiA177q"#YWWW]|aaaU> _7oޤZhe+:x,ךx<@^+%;R}aǎ;0:1#…RL=(x1N7o:%ev\H>cۿ pFCYcǶkVܬ}y|azOP!.^$Y5gjՒ%KoxUjqe-Yj` Ԕ^Y六 z?ЊQ~`qDD}^Yɭ[)Buk/11bAOK[J%un%}淟k`ܫٯPCg'\6oF>,.BC:rH G6m.@0 V ܯSx5/rUUϧGiiDvCùҿ-DFvp#RR^FBmi&V)'&TnȎFͧKK ـΫSV-:*o4֪4D5ÇS̀ :%i`~~~,Z5Q){=ggg77Yf:tw|S'JѪ2yn*;4!` T$;br4 !*2cڇIM\VnJTvX0IirfR7MXCAA Aڿg`0Kt&õ;իEEE,K/Dgw )))_Iǿ.Ӟ0aBpppzzT*=~c=FSkdd1cgdUtfT\j恛wSaQ feϙOENVCElDj p.Vt-~4zT*;1f⭦[8' C('ÝF$Y[YYQoҤIm  ;wIUWE?~]]o~j4Hm6'@1bMZZZggC =[2*wtRT' ¨Tv׿܆}yy7)fyH>LU_ȕNNWV0V["/n.J&e2uAY` "{G*l(jW:&oNNNk(,,ttt,Z|YرcqhKKKrjWT*wF裈;9oP`Yl2EHEw߽ә7i]]Xe噒nzS&$>8U(t0cx22& Y ٣Tv]:QsM懇;R7@06m!7ou.}'t֘U*5l׮]հ}vUy_>|NeM 'Nh_mU=1Z5F"oT',lQYM O=׬Yq}私 N)ss/(ylg/+.wX|Vj4`W]yTC%e"L8'DK{GɆ?pVoW ߭VMII9qD=B۰ fEk.]vf/^hѣF%%''ł˗/v8T*֮_ͪLj#GUAؖq7"lmQlk $\:ut }gѸ:%;1loPDbΜ*8gJrmɆl͵ ^c2gTgssFD f\ltr/^tuuw_Z,Y`zwQ266.yUׯ?d2P%7mD/@p+NGu]paU+V =! Dt*NZe9s9%'ko80cפI1,KpuqqTZ>N Zvv\kkF#n ,rȶlfpBzRVv95uMX]gIltԧo|JssOC#}Qfc[Ŝ\.3g:I-_lY%KP%}||V̤֮]|9ϧUՔL-͌kT%(H1}zy&Pz GfO8'=6);mbذ0/)A55B^/F%%%444ggɓ'O64ˀ`,ϟg:׿{ j]WOFGݶm[M;F/$!z{{L&j>EWK~*J'؝ڵ._.[&! ˖CBTMM};vHd$$-3SIجи*eծ lssZe~110c#"dgZZz! ӒQ]Hvҥ{y> ,X߽:[oE?>?q]8??^. i(G5jmZZ]XӍ; M;I6HMAA  ؁#d| +.vaaJK٫LWvژ1TMmx"Z㹘w< u Ft|җ!هϝ;,}y#Y+mN)))tw]ٳgx<oĉE"yIiO.p8RbZ5tAvɸV\*xTrh$nht7#1,{Yz}E޼<*WO7Bgai9_z~Oޞ=<̛F=L7`o,_W'aT0;h *.hn}SSӯ ℆WYcQ_jR4>l .JJj5=3Jڵk~sR7Ə_TTd^8::ŋB>mϞ=mvګϋ\N]\ȸNP+2 K ֬I %tzGHێ%o8N>sg˵;}[ƶ ?58uQ=㹶G fP;sm4 ,X<___`+**b^u…:s ]|nR*NU~) ,x9V kQzoUS%Wۇ xO>sgΩSʴ4M #2y/nu swi[,NZlfa;0bs>:Qjjy{pFcSe%7'ggLڄ\U\,_MMLQlcc#> /C0 筷ޢ3˳NɿnܸqGnVfNM^7|V 2ĝ.rw00.s&*/ם8QlƆf_̼rLݕxDEQyӶGATV].??};Ͼ׾{tYD}Z'V]ݞ 屓&"#ʎRC&]-A7L))X鱵.).vaw&z@n5B[ .`/>.%~ i&lǹsN@VPPs<w|[nn.j׹v"Q1gUYr\\ffDE f3qQ.wG|U4HW$"@0֗ W+ZUT Lc*.~ULXFsq`_ag5mڴz+!!N308`HKK?̙3D0+ ˖->S=W1+Wy2 |D6lfsBBB`T8,sYzZJG/͓7-\iiHOKŽhqN8ʏB!54@ ?YQGXWu]溓7Of(7%X&smK&raRi\kx=#G f! `\û;dgϞ%.V۷ MJ;vo(flUVgw{7Q huFQ1%Bm+ĬVWu7|/'n ecA f3xoO:401Լ%~+`;g2f/mMMDCdTU}b;Hh-700V`8~8q=o~bzb^ISC~0[W^h322rǣGv#jZ*|AH"k%!Cݻ iΜԈ~>eb1W  eܝ^^Y҆Up'ɓcWe:+=[R3tPԢR1~+Yc"`Cd:D$IDB ZRX`Wra ,gTY J9s&bAJKK\Klb[qĉ]g۶m6[nD(ZV>Of?z ˫ RvOF_++Nk׮~V,^:7*(QP3%+ l3+Sl %ˍH* >bZͭ9sH6-5B :B.O#(?ӗJ$zl,A0 Ft__?ݧ888vcOOO%k׮Z\C Y޽{{xx,]ߋaT 3X T"`bHJCX:{6Ϥ^`6CAcBDbEO^$gj 9T|jU`R~'`̶ cĝynl)lUU駟\`0n޼ٿւQY0`5kN6/ ZZ[=\K_f R=o49rǹmd,z4NJ qE4Y:,xɓix,-܃lTPȨ6ŒVc29x]iw V/qaa2 ¨$I;6aYŒm۶I&uQL0a˖-6ؖ0Ν `tA322^z饐Yfyzzb%K޽ʕ+^х_l@@_|>@ +Ğ9s7cggΜӱkozz:jcҊ%եλ]V$*P0ţiiMqR\\RNB ƎXd"JPtldY|?Z=6cG('4Yނ$VSPJ`ƒɾ<^xeʠ3p8˖-;<ҙ@0 j֘qOHv-)i8O_꽽Iƥ!_|!8^-D8--^&#/w%.b.c'&Zj6g c]22V1*jYns`ҥK^7@o: fQ 0[|Z%rEI:47G BR!lvBa#ҞT sIq!X7 [HB 5),J"% va zh.9Z0 ]{ ;.;;O>iߺ3LP,0[C-B< %KpWꋏRiF~kl"uEyg|CʊZ3ՙQ(?-8i\hͭ2Y|j\"PEhA3 f uEEE=l/m.]j:-NY`T8+wD%44Pѣb<0z|UUk{'P 3RD-q,,혔DT3>ui5{fjqC{e;"&^Nx]nh0Bny"QZ i03]`dqw q7l }4`Ci\6/oju&4M9T0͛7cYYc`` `N@_F m/њ^mܘ=au]h#0sg~s3|'WZ4=}ܝyl0uMAs34p2Luf8&b72F ZPwUc"[`9T0퍟T*ӎUUU>>>ЧNY`Tjzp_!3|*6 ZX駕{\@Kb,`nݚ+ =tP8͖KR%A4PԬR1^ӧ~4Ai6$Ο??2ܧT*… OBHߙzsҼ6 z]9.cXooҽ_|QVj֭d/i:+V!9ڎn7mCֆw%r5\ T4VQL),ONcĝ}sI 4*}'ٹsgv||IS',0FcQ#&yP C^{/ݽbLmޜ#曚MzEXb97%A㌈J}DɂII/ _{I3,v2Y Pc8P,hTB+  f?q{׍7Ο?} F5(!Ǔ<VTQQ`V.\Ȍ$$Ej5e9D@DD54Hk$֛䍏tOg(Z wi EGoǒH<^Bh6렕4|ܸɎj4I&o=<c񖶶6촱-]&O @0 jQC[$sG$?D+ b.//Rh(JXd"JQtld&Ԕ OJy~DZf$]uu[,Pch+*gd 6;F0x8AAAGMKKJFe;::***ӏ;6aۍKY,0\GS$VB 'ju:c$0v$Ƌff +4Ed2H-NK VhP1cY,ddNK[bR )V+(>ZSk}8,˵ǎua[8)%H6Ʉ~i)4=K֭y/VQ0 tHAL*I@C!"+$ d"%}( wH c Rq.b\bw7l/]L F5C1 ȧQoGP$a0T+Vܮ"n]&PgYvFsCLߕH^).~&/o-M䱮%/GTu{u0qŇD8ijDVkG]]f{lZ]RiK屬`lϿ`RTqqqwuWE>k',0FjB[Zjֈsø)4HGFz@~ ۸1x>wnjb%JklhhG~CJI"P6`iMq 5 Z4E qrÔ[pCZՙE]汭;l0K_;ofll,?SMM t`ɤ155-+_^&yRmk !%tuE&PF#8-rCⴴX$-z$;ZT]AR]?%DD`Wg*Ϗ@wE@Oc۫u-uf(:>cmrBCqqm], ƍsl+,_< 00\.F5 vX5ٚUmK]G$eA0 F}})S}饗zXVٳ-w64K.۲e j81ڤLQ]yCO2Mq㖼QHT46A¯ٌ&$ȧMyRZx_Qdz}3\_|g]^H =VVTޠhi)8'g3M\(Bh`ioW&' "#)C ^w@0 OlĪnjhsr~V8q"~G.j8ԌZ rA f DboXMMU=xh`޳]pOFF2gFq8b.Ꮈ/d. E UIuI| h4IlVzq1 ^RRabAgRpyylKK>R >~ N@$y{{2f6l)V]nAFFWWWb3gN:'vmG9r˫F5Ŝ5qCRz?S7ƕJa-jCBě: Ax̟BїLJj;:c5>EKXטeѨK"ԉv62ه Jt:>4Ԡ -"ƍO>)>t(gŋ77<6iR bG* +lqC9@0 FNc=6lb̊<ö͛GԡK-[˗.]rOx p(Z{ { a,c#G?2]5_nEx??[o5tk55XDx ^/L!Vx{9k9WÅft(jQ%% tusX%6ZGu:]~~]RR _x!{F)..ݕO^K*5g,x CCCC{f Mtttw^[C{sX F^9Z트|u|]>4`X.(CنCJ4.[gwtX*`Nd<Ljo9Fi *"dΘAWWC1Q4YܐE$Yj2,m8i\8/|uBRG;$ZTPVBQKKH.O"Y.e2bkm-o݂iF/>>K[Xo5r8S0;ay? . hد>her4f(w^ zf\.q{Y/_&6-Kr 7ߴ[p-[<O?t\\\mm-j d+2.qG rG8{aPNRRK( y/|RƎFQ(Uz'%~+R)g wĽs;>ukU+[1jm)'7I %sK"ys8S*SLPءAd$N @vH"1#̞={;'3s"**ri% 2cZ===,-;tiiiYŋ{quz툝Z{&M j 2$Vg?Jyg6Mv{P^}X,nrWBiw$U̒64&M6/.?y|r ab@<+.).җ |reId,٬ 9sKOZQ/&j; T*Gm{iu|csL|1EQtFӇ`-;_ cbaUU~\NdOǽ{5},^XXxNǎQ !^ޔ$R?3͂9/ԿfɆ Y{ҽXMM )xk%iezc}:ʉ'vZn"ub*yYiJ%+l?V++;A96#Akm3V&$ӳph;:&_|1G[|x̂b+~z ÇCOAA;~xqDN>>~hL_}U`` ڵk01XgY%"|Qf++XDp\:?WQKUU{ 33XQXUu5_1L6K[,~n\"G4`jyCNK[RWt B 6}eeՅ y  fnv<}4cHH`8^~+$e˖T,:221PFȑ#ķ...j[[jԼy+By,v8vkM*+NўNKYj \㓊Ol#ٻ(-,C"y1×Hm2ieB 'yy屴)SZCm-4Ԡs`vɤiǬ,|ɓ'C:fX/[? `/bvvv" gΜ}ٙ3gzzzbm۶: ]P+rloG9rddWvAUe˄Jv>βK^ŭ{)B~scmsVAc67d4$&GAsU2dg̰ cIُ<"knAP,>P(ᎉ+?ח Қ(e0JA`T`xX;DkB$/ RZ'\_o_B D--1b4:6`` `l? A"Z$J` Z2Y*"Y`q5[D$Il,/<>}]=  m:p`v֬Yb;Θ1Y{… ;w\fOw_v^r;.]2J,3e9' EXWTrMv/;:܍uFcLͶcǓ|>C[F])tIqIIq8(\?VQWW_R:gh3i4Mkג<=;'؃uk+*цC> ~2'Nӎ'Owܰazo% ͛9Ψ{`JDANǖ&<ۼQge&hؑP,vr|ߙz癀zoϞ=j<fQ AE"xV r͙eYY7(7/.ELml.tQBajQݝay`Q=RL)A06.).^-(jRi] ,V@)ūT[/33y)D͗;Ԡ Nh(:Zmiˈ#q`?ٳgVO@pB|//u藕Zj*GzΟ?ʕo/_-k=GÁfSUryB^6 %sKyB,*FQ X/$^=W״%K|Ѐ ʑ9T07l_k;4'5v"_yURR5Ȕ)Sl-Y`To[o3D"yi9I">nƺ"xYM͘e[^z <ޏFF _}|"kK;W'`זH3Uϧ-^L\@ɾ^p ptv`+t2ҥK7nܸf͚I&u`֭f'M<_͎;C䌊,0'x{-6!7s--f={ yys_IHBBQ=,Eb))U~fFo < 'Xm 5j,g̜I\Ci'Kbc;qF# f1O笠:|pGSgpBbX6oތC0 jêLV#$Oma斑ITk5+<@ִi΅I[%&*41:L HA"rmxRſZ_s$m'v'?Vz ՙN_XiƒH? n9T ;V%@bl2ϗ[s1_CdjPPPm۲_x…G[rP` QY`Trq6fM&b5]Tۥ> t3?? ֶ;ۣB;#Y DCLo ?pZzGsE\{={rhΚyy[SRl"KK[\\Ryln& ~q0*E͌U,`0XӧO۷o˖-7n|'vO?56:ԜxjzzzbG ?~,0p[Z,^*6RC5lwYPNKٌ~]m~hESۣE"/6-mk|]Gmx8`SWg#BSŬ7Cv"#HD񞮬LB .uf&/<׋LNMNjr`v`EQ ru:haHoJ?Vzl-{-1c;D}W_יL-u#u#ʠeZ꒒Jxٳ>F 򊾿Fh_}ٳg+W>tCx}5Ԗ-[۷oT<} 42$X$5`3cld*LNǖtPް7bn G=K{<ˇHvPU+ @J]K +P.ɶބsk˭p (~~U`̚%?;'V=zwb0|/>>))?ry?+t={OY`Tc:S1vY8Fl T*GGƏ'QۃZMM@0Nw,rr 4Ѡ@o&֡C,7m]溓7Of(|v0 "Q4(v› eI1(mee:>j 뒒/V;'#"Җ,A\]a7߱} Шcc}ĉ,:jK<<<.^|]{nYkOX"N683<3Z;,u(v$k$kҚ4u77 BC9Jp3.- a].]v8"ARV~vL Zi8D&2C`,z}yA֊̅ 'Sz % Z|/am  f?f|Mթ>mjjZr z:^xڵk?믿yÇ?SSN188XՎ,01HDK5Uw$ၫ+Á\^^ G]K&q2Y%$-Dk&B9cH^<~VzhPU,nx`Ω_u45Iy6yr?bXՕ9>o ӧ̙c0tnܸ155u=efQ wdE-F.!$O0Jhַ2Q4" Ĉh`BѲ6Jc㧕D<޲t/ l3}kkU6^Ĉcӧ汳EхPt Z! ,V0v5q8MM\fPxx#f"15Cc08R0{e"Q/vbʼϝ;}`X//e˖a?j>YfX+,_< 00\.F5dtgnG^ņjE䆧uu]Hv,ƙ318 墢sr2=|~TpV*67H\j/Y`z#d̫ZZJ/Dgg?BNn\S(΃ů_L^xx 19dh0P fn݊LDDD^{ _gϞkfJ$0T.[TT$˝.`ٶm[oe7v5Z]ĺkCq,]o˖-0!eҘ꾯(LJ$"$ORKEv:9!AlYmĐvbdC7hTݭ[ rBldBJNաxqݘrs 4Q6&\fnt3xp8FHli Zmõ<C\WT*Yb"uA:fjժ{yիW0v=?y$v__SN{1v⒟Ia\F "mmv2|.*JC&X D(sw~ ײٶAUfG1bq\P*z+dCƌj˼qENjV+P[mnnÒHlvPBe9:lA[uz&#WVVCdk{f+++񵁁ЧNY0 0oѢE.\(((,X@V6w? ;Tzzzgj'Nߑ DA~Ql>u"V5/9sUthMJ "dIZ\T1[,oQ JbKBՅg [D :Xt@+Z%FQA?XFSiӈH2EMM8`H9T0;ad8.=%%%̖_zSN%$$0;`tihh З_~?cX@Ӊ#lذAkVn:b ݱ%3gΜ:u*OwwNȑ#xyJY VC%CDX\F Jla;Cldʔ{!<C56oeK>@ rzbĈcB!va,fc :JPAAJŸu ni\5(e^|s`688?ߝ~7%K8_/… /^뮻:)7~{d=ef蒝MJe?a|w.^6?yuhkjjRt˖-KwqC\.'O|7`T_lT9:=22+=k֬j fFGGڵi&yP=jj=&U#y0$VГ\^˗^tӲpR5/2i>`^c(ӆOuh F?]I_w̰ZZX$akRSygɮZHFӦMĐ{ɡp ŋ=p|_z&M:tq{*XL?Kq&ÇGDDPsL<}0E^y!NT[n:rݺuF>VTTP{m湝Q0ΓH 0CpPjaiӰWNXwݵj`.f9C'Ğdž1ölIդ[Jâ)n;YYUNZfpT$;g=TsWЦ,xo fd2zo>_ꗧ~ r< u@hhT*~>12s̳a0\t_O=TӅ鹵{6رS>ޙu׬YC2 Jpgp=y=l y/ _~VZE /Ƽ;G0 cHOO}9>J-Եx'||ݻwutt̛7Gj4ͽKm_lYww7}?je#Cj GG`3eOf*3 fLIQ/^|^ Ҵ[Yn2O[[{]AiVT; t]E3=(N鎟?[ FN#ٛ=IHt8:2Kd.<:h*R^xso5~oþTW6qDir>UxO^`xfa du鮻7nܹE5z-O?>ޞK-E7oܹs m6R޾qFjg]Yñ'\[ c7F趢\QaEdVV{.5y2+Zvq{ᦦ]JCrSE|>`@IhՂ՞y xY< zB8#x:mG \gE>c…}H|G^ɛYh;z222$ç_S&LEPy@XXcǎQOHrP$*||"4+]v=ӕR\\L=|p%[&l67iҥ~SS`|gT UkmaJr.a22NuB[*khN<~+1Q1gsW>/}i,}߫b%ˆ_ s=gV>ۖ‚S#d =Y ryͦG C.Q\HL"eϛ駄/N1&Y?D28׌م RX[VVטxfGT[N[yΎ[@E;xk֬9xFZuuu?c=@ ϧw]}}pAAA?W^=a„'[7ްX,g눊rҨ蟥Rjx8kjֹE'EѢʧ*5k:;\ь~Xy/%h9y򳆆 ,ֹeξ1lommNWn2uwÁg] =fMMR&~I$Gdd6[3ZW 0 ˞?3 nPDŽ͆V/`;OzA={^{5:2O숲m+r}5-aO?dYfYk~K;G/SҨ8ZT%3y;%[KUAgVOzAVԪ^qqYȦhWͶ`ciNmEEOWVWW^J.ߘSMĞH4aaxu[>U*w;di="ٰӳdVy.1?_=3e ׯW&%x}rfɤ%$$$??ŋ{s60gΜ%rNa?#.Y._uϵX?4 $ً/kWKK;s]w]wu[nMNN>qF5i6M g1/pVSmm*&*Y0c37/۽Hs,ggs[[$!= oDDEb $Z[kj^|V"]fO RYڄ6ax---c_\._NuMTTO?yWR=$ό !t뭷/jj#]m߾}߃_UUU}qqq###F~ԩӺ/1`,D+EqG7K:-%En3<' ~Fv:2WJ$F3-%[185!Qht2b6׋D7 ~YYUb-Ǐ`4υt8<<3eoެٷώe`,`D"s:u>x2cBYYYHH\nVaV<رctr-9DẐO裏cZZQzaMM>"00}o_*ꫯbTbo+l:Eڼ(kk561n+:|bӕ ۗTEr80{pUtVJb+ OhFu93'q KJdJeZ>h7Q\s34f)+Wt fƏ7?ڿ]]ƍ[z}o޼y'W39"A̟}' #YTmӦMϟNyyA磏>ZRRG60]NUqf$]lSo3uV.`U$T1TZTdbTWOMOM!%xmz`E/*+2 xl:]#X3eOXv}Ӄ&_@*7z-PHWkv '̂_XxwTzA<L]pɺ|k͜ݧ"YN$d +0d{/[jSwg䱳g}kxʻ TgU*e/6X Yg|z[hQpV%g^I(3gNXQs(Z[9/-[i4V d('2fOhR&C`jU9˖yXNd,>ޘvwwSnΜ9>L&Suuuyyy~~>-..[% ,G?7oL9i$ $%%;wR a٨7n+''_|sC?cT7pKX cґlޕy'GB+%KB5kvRVVvt<-<<>ݐ8p@DDp1Y,(Z:8>CO:FyDb1H6"ޢPUI6X,|!UyEG"Y7 ۟ʌ`ȓd&uk5\!픢YF\\ F\@@ 9;;e,YIlLN`?2eJ+[yԖA,-uuuͻ|z~+W<><<<$$sUW]e tF,,eǎ/˗/3P1F5\:syllyܘonV+]6ϳUW SS5f?鶖\d+nA B>X/Ԍ5|g H'Tq:]:3|B1m2X"zmNI^ݻd`^ `^裏.cXIGG]wu{xW?8Y~l/r``13<ӃQ #^pW{ynjSRٓ2C籡X gێ+lo 6\̖n;>]t]Ԭ\@&@4(d;hA!VEb"#0tz ۂ/3Xpoq\+mnnӟ&,F5*ADፅylҜڽfKx {qGqf 7Xhw8_0 rĨ9<o.o.5 gMG!{c`%}mb2*+۱J`/:%J]@󯹦' f,F5gS>ca/z{Eig~W!hQF;:[7Gt%C!`}kzj,#lX)'gZB(8m~]0`v„ ԃQg'FDDO}Yj۟2Z؋5UhIbIdF < nRR\r'5KTJ55++YZfDESqc\2E,d*J :'4P.WO?qgΤٳ[k}e`6**z0"ǏG0K`TXd3SԢhQfoSdKd`iii+rH64'U*1BEMȞH ɕe2"I^QXx}yb0KKqgki骬4xM_}U_|QWi`Sy 'ш8 fW\I=| .C0L;s/,Ydl)iaMBrёlD;!AЏ~ZP}`I ZfZld@f@,jÆ ?I;8( ddF*};W]ś=[s8Mċx]f֨`ֽ{}O}YjvvK "g]WzW-ے:HX ;%EӃtn+-2 ri>2-k5*giA ˢgHqld+=I.OZh>ս >o̰ ~[el(@ 0$^K~O{`vY~- D1(Oz层esOWBBtvmMN'IxW\'z="tv+Vkt7j,-湪bMH=q[t.U5Y&;+yĽQ;c^^wU_ + fOz}uۺukmm-` ?((ڵtRݎ>f0_X^ D"Uʬ_^n޼l:1J"^fS]@\vj`Fr"770ji%%[̐3pF.ı'.Y:+*&ӦMِ{ɡp ŋ#8XW o`kiӴs8g[>k齷4RٳiSEESO.LT(u@f=#IE6Y,Cc<c9)Ri^A(}~^?SJE=`y[0&f̘q`۷3`T}B' |Eޕyg+`1KXxaI+)IK)S8))j@x#S};mrȻHvkTf3d'uJ(3Jeο24VkSAE*;{/$RArttT6kmmh;YJUU /lٲ>|͇F]Y߃`.W3(+r{ pн}sMU*t킫峥iY,//qank4Tx561%*$jQ[˝I]Qr*57]K]17:Q`xs0K3yyyG=p@ZZZFFD"q(B0 Q #SYFcW˛˓UKyy^z.:UBVӛ ɨ`$Th*0|\q,k˜aT*+4 nC| 7m2dYSR#T]^̎?.!;~ ,F5 MIl*Ezj{A킁s7JZ`PlLf jOe>c؀̀KRGYp-- 'Je oِ !;=q":n xU0rJ:-.W` ,F5 u|d_ى6@/c/˹웦oww"'1Nggi]DY6{N?ɅhF`{2CCAx fVUW]E=PROf0iӴ ,*-zbltw_1vA~infSF,~Q*]Ҁ{Jesr.꒣M.*9͞8AWn6lʕ+|>! r?PNE 2II ̴tiΝ3EVUR"_V`Ϟ_oG,V8ʖlu@ą\,yBrg0Mnv_ m_jڦ~C}Yj2S)gic?LMՄWLXϥnTTDMfmnF\]]T*;/{Q$T(HR*N_CS[{9SPl=U2`_M8C04T 3Img&36VBE1ME|>^F\Je*4ȱZODT*5`F Io*R7V- C}Yj,)R`c<,.XO gD~|ՆXT*{_YY˅6pսG[33 4H I`K;T*ŢA C_c7Qt.=Dio`Yj">fn&ILIQ3hav d#d1*)*ۚq8d(wfgϧX&=F(W28&D X-]x-\to@0 Q ET *(^fk;t!,iZ_P@EZӳ ɰ\y@f{NϚ.AiAy,&Ķr>Gl"{'*^Yj8/RFMe c6|0֟TNN<*`X I6T6QQQI=XkDg$֧ dߪ7nl>rt;,1 ,x!ۇnerpd2OtSfQIÚ5yUU(؟+j .@ O|Rb4Ȑ9 KLf}b0[4.`[[+z1nɲ&L'$tWUe|YBM ۶mC0 p!S% bęPfɖ]tBAɹc,LO^P7cs B 2d'N|͡/[99Լa`^Pv:%A]%Ҹ8|Lf a0{ȑK|qY8Exi"+\/T<ܶ HvԬ~@q{_e2*wUU.,3ƛPl8+\&@ MwB,H_D?hc@ѵ 11h`z~ŊHxv52 g,^]e/=MHLT|mTdEbS[<7ϰ:|4L͕3A2+ILf(5N)$醨kH6w }f&'!/,9J8#AolҶ6Y]W^&~Jj7Ł Ɏc0XRA UH#j_ ZRiކfjIl,f֤.xYf !b*7 V 5UA?ɔuh(& |1^&f{̛\)$Tͨ(;]g8+ʿr,SSTt;=T X4mmmDfH/+|Յ̂A0 ~$HuʤXZC Hv8FbLh,dj1Npe|3frg%w]S^ 8)]0dX !/`,ADepq EѬ2=]ɡRŋHar:Ӵ8# e2tTyn<oM: ܀@Yfgwf߾yEUYf !MӲ'$.wEnGiO>VmT/ASfaLk >mhhw8>xśHv^TM*S[\٣v"4`a;v'N#ټ5kZ8,x!l-һJ 62e2flv<*u5`ݬR9Ţ;i6AT5=1Id%hAqzwҵ i4P`z;ϧS+|͝۸?I1h999?Sfff?&5 ,Vv+R.qgq[Uͮy@/Cl͎wc,5ϼo0(Y02z\=ɪIITŷ`_*"1+kj dҦcb2%0CCKlѥ$F+7o/굝z0111`|yS/.8>ay@|*{|uzy8%6/z$ҴiY1y-3p$IEE3tk::J8mCIXSd׫SR0jlhh/ rY8`|N=gim#/> r[z<ut8RS5"-[Ju>jvȰTM겜etɉ|G{;g@+¦ӥ\1EClƎ"}FϕV3w-Y5ag Kii.6ZL& dC}Y::*L!p qqY!”5V]f׉ #ZstYg-iYv)w8^S< Hb I?iL\n휨>s~n˗cil`ロ:u*Y8YZk훵zL:Dr)ɱ?T.JLT̜L vo|䴵!+vHIʤHN$=Sz\[CV{6υԼn5y9::))˗rL\Yx< yUrС¦cb0b}7~E=%K1$P߀`Ju%[Jtdc45A~YWWUuGG<6(iSMf SqGӕX,jLfG 1IqA :Eg3|y/YP$,e2]yc#j?WݮKOxΉYTloCM Yf !ofXT*% pd2cpoQƤR ɪ&+zߓj[["70nX' }F(N[J~,$*)Y׍ oxjuʉ߶ E'Nys瞱bWL>#$XۂYi`>S/y&P>CUdi6"0/Əcvjj(BqGqqшvG{VbVv.}f߇&_z9s+rWБl3o>ޟ0''gg+puu65}e0*m_܌XƸqt$˝1ChGm,I?gVE;_zV+ fPYŪU]OL2$6sV$bAhCxj,]f(TŽ`Wc~s"8tbIVyl/c̪83ePI,U "w{uu; ¦ӥ1Sdsr.S|ur~]z4.sa/fX{KTQ̼NzI_.1#я>,x;Ne!ܙ\Sbg3!ADuee&Ljc8,RR AD>;t:7gtǞHT$TM7M#+(쪬3׵;ڭjZʤecKJ <)8/[K&5 W9}̊D+V\20+W,))AW%HYhd/Qsd2[ϦY*˯IZZ++ c2=.?zÁyu8:R)j|PxM <6ktc|, \2AAA| zg o@؈T("ת{x[\HUvuP\zsyWUUuw1$^ II-Ǻqn745}#>ZPXxߓȴeihPgӦI$Um,ᾈz7nt?^"9rwݼyg~;n8> f`9MN"*ɿ:nLOMEETN"kS꫄BxX߫r1˗/w+0`FMoRHͅ./=;ζ}{)`lRc1O;AdIș% MӉ@̪DE⴬it" <EPlV74|ZZ͞ƞc'nh>w:;PB,Xגq˗W&McW_}ݻwgٳ>C0, rR#jjz>, gQ̙t|%JT(geyaUf3^$Bpg {}f[3O.`)B^a&tr@vU?HC xyk(_{``666z07tӠNtOxO}Y-݊n\HwHI؞'=s4dlo<|IbqNS]ݻb-Lfh0˝%hjnoECt6<_}%KT=hoռ(]t)`ANW3@0*:J:eQFMDbڳ 9sxKEnntkF#2t"`l.. +Oha<[e99. dnnY ' '3e2C[T:;'Qa`HХ\vg YuJ aq`L`vҤIԃԉ555ԉS`.6$$ Sj=V{z.>^6{6Wƌ''$dd~X_SaaG뾭SWCӯ:s]:%F NϚ+Mդ@CգR%geM^NgL. >##oZz =Zh^̆QF;ᆆp@0 YO0f% sz+;sAS+r_x8j+f;*յgh|6\^n2a A?5YYf-[R%bI4#ahRK=Ǯ19vNGuȝ1CH|W . ԉ:qS`.&m1yI&3#a_7EGzQQ{|񅦱WXg6"QmTmV}$#ٹ]զ 3X/dNU&%9;;2*O.Տ?8~gO?}E@%dM(oz^3fpf;Ew+ >W&/5 6}2)IG S);j%0i4dn0ti*Z:LRg/gi^̶O:zUpm^P;;U?2_^Wc)F֒@23OVjz(HmOmaN,˜qqR~Kz}HD籁 Dj N$1,Zz^r45}uV$I:8]iNJ՚UJKj3,""IO&\`mΝ% 22>M`FHSxJS Yuv"=]#L,-INV~ "M]%Бl('Vuwc<ygDRE.Fh7$:]J,ŋ1|b#dyju AXq?׽^Ov[ҥ3XƸq%KW>TݻOIm/^̺:tl~DDD߿]KsY\D#D+^WTV3f<)NgZ=/;d' r y=MRBqҸ*4N/6h66gY}Ws8Qg0>ͮ l~Jή.SyݻWc7ߜ=o^f@@,3,LjU֭?1T54u3 ˖-']dɞ={ZZZЏ>, /c1wy/eDa#<ı0&f̜ݹb%)Qr[:0nf?R^}&w&EqvVl't3yykX dt+PQhm#.6 T^x o;cF,UVxUت]o_[nU=IV@߼6t~ߵk׋/ѣG} , )O3([.w]Z+ du|MNa|S̀%%HRoQ66{0r/;DNQ{' 2:b,~tʻ_7}MEkB,}[o+-MR*67יVE˻򙦦o,F\i:Mj$6=iR度Nuow4YBfH4ILoXfdVq;$͞xvX8FLjmr:N¯\fd?=e D5ww*f !sm/sgp{%0fѦ"0$O\͛6_JbEW]]N 6߫^>+]q~VWmhjJJ2aŚ ܣVd*#I,Ac˫_ؓ'c,~i2YBf<59V2Xb,^K9F3Qͯ\43:5g*E)YϮTϏuW3ץjRc%^aքqL:\v:dx('R"ur:Jg46s.ܠgޚbdZIjJ_Xfͯ~tJD3oэ`cc `` `c~/hy||>t~?/b\7%χ.,Cæ5wO c#|QUaiU))ܰH^28 ɪc v>^È<憞?]@SYE|p$|{+lĻс<6Q Hh Ы{.\&1է{q۶i~ ,C!sa9qw#d$S0Uv=]O%%1eZ=FM*wrL:=C,tv(YyeΑLMcQƥSs*;|">()bн)*uHNG07R?DQ4a2fR,;] ـwjuCC@ ())a0uuummmhP|6`e]. ,ofCOyJ/ _WgʒNN]s %#C\U$&SXy,1E ȡ?tJZgOLu~>ןxb >dr-aaaCΓ-~; &C0 }1GՂHD)AW-|Q-[*Ǝ-jw\sd z].WRnyxW]*MDxψUUb42II^φ.YA:MuuwC@Gl\\7Th40:Fq˖-C.ڞ={Vk5Y -nI clbSU ((dfJV|X6|8;~Q& Y(t0D%12n3[{I/9̙ߋz=[",*7J:uUW ҐHM6u$3"A@`6))ɛ%ED k׮MOO7>;uԉ'<P -{^Diݵ9Pc$Y-ZKHG_{R~M ); f}]oꫯڵqqqOz=9򜩴$!Pڔ9T ܿ*DQMA{r ⧦+*s DU0kٖ.]OLLT* q)--˗/cAOqiI#+ bؙӧ57&$֯/{u)3] h@4Y UmIvʭWÁ~r|7% |S(/j(2,V-,@덆7FGz#ٹ_(PtS-.^d) rye9G.yNuDo$[8v4+ 6" f~fv<~ǎ+++kllT*m q=r{[`A@4Y 8agyJr"u((?^lvȧL"!nkBQ4C,3JKn7'.;.dPf/Fcdl=sWZ-"d3fsrC]^!/hex EhF͇`2 uR(+H8:jYYD70yhtH7[,+,_0D*s&P&x#| ^px#Y29Q*rAU9NIuOŶmHT7e%'=?"o쐋4㒐p Y <{>|x@4Y x>m%KH6%j/dYE99r-f?R|26 &@܉ԉHzzۼ, d:#l?4>\Gu'bbN)k+۰AG%o)G^D"D!!DJfZ4q(Q!vu_զLiiHěZWB!Y/uyydrPhW1?BC0v T vJ ;ׯIҬ{wr=J!&ϑ/.ǒFiUwettM%&PL#]UU D HTƠP {,2sLqlvޑAbLTP(wFB Ĝ}Xݮ,MMbVNyb̙Y oZ16\`Oݑ#G_~߾}_|xɓ'=||M67IIIFcT`s⨢l}x$)Tz^\4+ӦѸ\ChH4 #DnG2cY ojEI}c))GZ8PGum1\hDJ<}!H:J./$dlmpᰵ+*4O?曢}87୷ꫯDZ7n8m۶3pf?䶸D10g>U+y<99rom*PL|9@G`L쨽\hy~;ǘ7<꼊NN<|سӠ׳ LBAW2y5*>?U,ΐJ\dl9=n8ͮVw $2/O{⧞ڽۘIIcs Y۷7zeKoY /̝;7,,wƘF-[,'''; bŊ doVOG\!bM7K%= tJ~{rr0ؙ3V+B񟺺|k8H/\Ud rNM G1}E51[vU: >N;'ZO*SUΒu==RT~][,RX8f D/)汖#nWaU8@?յw#^fޖ>3p8.s(2OM{#QQQ_|EЏTkkCޤ$OJbcbb͛y`UJ.M>HJfI& CN H뮹g0s2®'5;:>mn~n/ɌsZlm:5dMhw_8Sc@JX\{1űMAaQf o--GE}[KJV3ġ"Ѧx_V~i0[j$*ġC^[re֭'zˑ#~3Z[ZPX@`wd h`Ϣ!jiieeet:\.FPG'@0 \y3M'"OCI U*j.raYY? zz܁6wwVԴO$PVv- WBEEwlr"VNYU{uu G)_y5~:;E-6+t:Zk{)"Æ7%̚\n K"8bgWfTW?(NޟG(aaQ-۰A}^[êԳ= 0@0`믿N>駟bO0VpO8 $ae'"œxw?m,pի9x@曶j7ooTj?%qqDL斊gkk?kitt4Y,YpAt>_G)n|&0kbS,~j*a2skv>-TutŞ+:E5%7Ի+ofcy9r/ fNɓ_V. fq&L2e   Ԇs "ٰӬ:ӏ~$&g|X zNfR.Zf),*=qwc|7hhhş=|p(ajp@PRR`0***ڠ@?mNzC#|fVJt:XfM4 ,nwxT'pkr PV< W*=Vf4ǹ0W4ke%%33Q%.0±)ܔ$}MMw3} J*|H8RkNiٔߓg,*nyNu$#̴Gz`~nݺ?Ծz8pvϞ=:Rjȑ#;w\dСC`;v?~m,91e~-3\ԨźbE  Nv9vվظr.1@UpJr eU*AWWwڵz1l11wGw%j\!ꪪ=n%4*vFE9{ ЦM{z ¯ C&>;H0]o 1b2rKXXؐypb|UѬ"g#YE6ZQa|8 OzV(in jik{^"Y_V6v$M%%{kjp sd}&S'A۬YTs%Ͽ&}-[Z:jq,P#]\Cho$[xqɓXWa}$mnnƟ1bD0hܲeːg@ `d+MU$Vlٮ]UIIH;2,KWdtvUW/ebTf梁|łyʼ8b>Wo չZl2|I74Ao$]L>apȯQF$A fzE|"քkצW_}wߝ:uĉ?zܻw }ޘl6 vFS)^TW$;&ϑY'^xAaC񔁾?iH^j 4,4Ob2a#5Wz^ۃ씱 @$-ˆ˨]`j+l섿} |U0>;H0]w] ͮ]j\\Oh~j׬Rh =k'Sx*c{H3C76K8\IBpacj][Z l E.Ϳ~zqƝW|_Ӹ$$$\`ð8ކ~Y.1 #-QKN$,g ǮL&We@О8ۍw\3ocH@kuy)SGM\屨:?Ѡ^\mi>wipR5eĎru)rsC9s.N `Cڵ3f0 o)G^D"_#lvw@0 +,[QTV.?=~u0?>b/.'N64?}TF!"Pss5n̝% ;LϯLij>,+[O ,bZ?X ڵՎDDH23Q. fquuuO?ٳcno-uQWð-[{{p\]mx$K'~]wW]Is0VlIo4|iMyQ]E.XL=@=ONGP' Ysw]uCT$4y#+W* ۏdڳgwWl6; ,p.uf< .uL]W''RZr%N \̺\>hڴiwy'+kS(+V\X${뭷hk2@L|m ϖ[,v ;#&1̖-z}p B Blqb\ExxoYfN`s e7p46c2Uz ժk cqqܔYv?W pa0ԴhѢsy{7СC{oRRRTT@3o<>󖖖m,@_\!'LU>Nظcbb99``~Pb eNgIyPum9{9[ ,L/@m6*y9>agٰa-d>T\.OGⲲ2:NѸ\nMMB@Q4,;EfQ[Mh|dvND#ee`<A<]M lk XqK-nmZ2 HFTYs]<'2^ޭp;Z[+]n]u͚5OARo/~a@B6 >g@Y:jkQٲfo4gvJFP;Zp$ɉٲl;BKlmBa:D ~0<UVVy=P͖ @0 ?}t>QV8ֳI%7y'%%rSlYw媀/Qxxt)'z/U`3b幄b(ϖepS(QMMuP(["U?_+  f:`\yo={vp /۱c7|fʮ%hČ 2aYKYudtb8nG32ii5.UTDNjx*K$'CC7oDI>Zm*Z\HdyƢUa>qbSGguK˜?೒=g@`>7 & [NS+rL ?JfH}C±g=/]͖x3bx^o NI.L/Р*"v[u:Db%"H>M el*d{d'Y"gd >!6V%J~3n89r c\ `Յ:PsYhEO7]WD& y-FSJGȑ/Xd ޵ -A.Wzc yl2\n B"⋋J$/(Gu:ڂahPm|nJJA0СCIǏH +v ӅalӋ3%[N^k$yd8Cn9ʼgu[+ZZWbg'DD"?x;qq>j1;w*S][ w` dA0v3<7sO2f v6pL快TVf.£)J@\mXrT>?DIz<قRU,=㦏}ZQkvp-r::c_ŋ 聪0o.25tڴi>a,JNdfT:pV0;R&MF===_,p,2 c[[+yyʸ?pj\:\J}TO k8& 1wi9{*YXpqWև>"|T@Ms:U*}LM(%Y9 3P9c.Big-Ycӧݫ')ſzmۼ^[ZZ}Yae RrW?yoR<B_%arc0Vܜ%>VS⦒tz8d6Nju:Ds=|uEE":hGM$ٔ߉DOXK$,,H$ϵ}]5 P\W9}Z~h;(=w Co(sЭj@tx|"""^}UNqTR_CN3ws59޽5#Gt.*{n tDk(W-A&Qwxknn~_vQQg178|%64bgz&0͟VUѦ7za ƜjD=v d~eg }v-mT$<|511W*xyp%ld˗/ưuuuϗjif,%&Wm^EZ#BqLf V*)5=XVrڧI&wŋ䅣tڂbh@2Y6LNoѮH+Y,P]`b1+rsEqV"%$ z^Z}{8vzn r^{|z)fR_k(2Wm̋@))ܼ<:GvV頻I& ;>ki!hU&S K- eq>±W kI/nn>$>rFAd **d 4&s z6[#HKc&%- ȣFLEnJ45A ?#pf̘1n.?\ E16[.'2cV@IH],U(:`:1.s ]>6'ȋ@"YəL(a8-MjRiVEV:}@E&~i6LT^o_]ܔ1c _rM5=r䈁˅W-lJTTԐ @0 Nk/|wO}9+K:cݧdAzGF3_J}8"q3TvB]@1/սdEͤ|_ԿtEhP(D9I%d$_?o]ҳX'NԿJΝeȣF R6u*o_VCOCp`vƍC.B(w}wNS@Y_K}dJR_:4?/Y;O%QI hp`֗E!Ho$&V[@?,nK,Wx+KV&zÈ66n>m0ҬQ[ZH$WTd&[_hMjUmr\If&?5L>|ڰHd$3)I&صZ U0믿'N|`@.!̉X+v @}/[~z\Fli*Nnʯw:ooz2-,PHpl6[AKx*ØwNRRLI&]Gw~WEfsV埈DOo,*@h6g#˅ (kIFDgত<?-aN'*ݺu7ݾ}P(ty`%qsi+ԗݎr8>mR1vlaߐ)2֫74\0T͎X6NB$*tBH(X[h:Z"gS)c œW|qϋˌe=j ʯt.w-6 A`=`{{޳@HM gQ"0-ߴI|@CZ"G*E1? fٹs' M(`Ert8_/]MXKY6]].*U%MIU8T> %Sl "9PGJ5gl*41'=T˩wzT?44^FcN NѾRݚ5~k$$֯/{u)3/cy|6Y,T.WȔHR$&3O[$KQ2QQɬT~j$3Wg(?7*KJVxG]g6ufeQL;h.! f9u M(`PLSaH"Ht.jzŤҞd[N#ykKiڠf/eeH9%(ywžFQƍj įY4f 6TS H#HvÁ>eޚ+J pBر))瞓|M[MMNRv%e2w0&Z> /bفtRuSӇTUrSΉ *mm4TG?oSG5}-:FNĺ?\+͇ j ί٭[z#֥K#9g0Yd;8;"+V}45E|մiAJlʒh, =M ҆ T\*SAKx]PP|FF|"7nתտJ$ϕD DH ƜnS E{RU~~K/oDiZQ~GM=[l m}׏; v?fs]k9Db>䦊-55IY͟տ Tf~СW_~+Æ RlzϷ}mH\p*&A0 Aɮ+T>y$'wڪݻk~Zʼ2K(= U0+!04 Y83U5W\CɺфJeٲ.Aי?wP@fw﫬`#H L: '|U~0}uODʖeM|?֒۵z=D}+UUedrs!H$,go O=EƇWh0 f=9f,WKGI_/#%&^EDO49tK9LA0aWJ峵\J^}ieI55 E"\ź]kcN8%Xc5>֊0S[8v#OM47 [0ӃWݰaCkk+ Ph`Mik?.zRZB"enjzz M N^Ajjk7o cGFlؖmii#HF3ܔ2j]]`Я;DܵkMpS\z 6x)..nyyy48@0 scneR.d&134"Wy|Wj 4,4Ob2al@-y^@E\C!ΈD"/ Of%gJ2:u=R$R(AMZ-GrH1g*?N߂gMjڰ,6Nch4W?Ϭ35UZOVJN$Ji8s3G_S/<2uRkIW(@|ؙ3?^S\qbc55Z,nw4m kwI-!lӔJPb;.RX D[0˿80Y*I18PKAZ!͒Vt}/_F}ءC))lGNZ.ITj^ PgKzauR"8á3+|ä,Lcd{EI[᫪ n_AYZ{ӵ>,!Jf 6jF%jj~v [8-MQX:Jçf[VT䟛ŭq5>9M+z*U%8qs&S[|-_n8`BY2S7nmʭg*[b^UPhu"LQg2bN;cev~dOHhstBB0 p `f/쌠HRChIhl})[jr7k-2 S)1ዢȮUjuXE:\qr21aB % ,Ooq8/Z0{ )ͫTVUźajRSQQ@W$D3k{k>^[omuÚÎ4J\23dkkg <5r7-[FKѧ <`BYG:IM5HS$; ߊt)遐)1QPYi[36Z}5igRd#x,Zm@sq_]mHP;lXoQU=`Fʕ^h˟5KfZ7>ğᄎfNRe/d#5dcb~ɊDcIl#;I)Ҵ}!H-cxju"tvttiBy@Ν_?{餯1ujWqr<5Uw˅.jTz{{j5>t 7_ހYq:4k ɮNC3#ɓdl c/Pc^-PPm6+ۿnhGuoϟ\TW|oo ]EE?{9=֬aƞ2wGGs.+nٳG-1`dZ0{ _YqBo'v_m06ux^ۗmti@/,shr7V_ѝwrWEE<% .XaGUG"X,\s7փYD;뮻f|MvMF,fLaKgO7o]ScݵK2a~Q؋d;NVg*eɻ/ć"]}66d{ټEGh+f0( l,<>ZwXu82|f͜8"2 K oUw1*Ӊ"& yG?fv^/"&e_i-ñ>֏͛qL̞۟U(b wTV:B՗m.1d3S) (ZԠ7"Iͦ77/?U^~GQ2mX/(X,lJST7o{zC!{zi~ݻEII%^^t pb۶ڧnND`d`w}78`O, =/qj{Ø$k@vN$%C+=OAsR%%tlk!6-ۿ{(c{щII];SYUdXc<Oͦ4JtT_ ù "Nh ///]&{R~'ɳlqEO)F|2=fϞ[Kos%oŜ>_cGϷ~olg|>+pNpx* $^) ѝm ]u._^&M%Q*m6K}}&gﮨpNFĕ\ΪU*Vgaw~q@y`gu%f>I85gpӳglRf I?/s8Z [Z>R*_VZz#Gǜ *lqUw)vb4f:fm%^˽JN\sƌSz=EW_]~m?p`ѣfՅY#u8ᾣ9y"p.0"!@F#T/\[g秥)tQ.(6-`,I ظq#8`G,W$LWGK/Iqw8H W.>z>^:*UTA X\PN''hˋD773:;l675Bb^*^MoٳI)ID<@LXZ۞=$::'y6i{ɜqʬ }Oc^ŗR^~{eɆ[[?5抾{(4d""%) }1̺\.H?_=8Yf%/(}ֻtdV6VO%ٴIjw\VX  Lfp]%4lhxH"IX\9X]\],NS(k4]]Faceuҕ雄 UU*=]Cתj/5 mƚh q+jkJhd"Uf7$"bde-_m(_Ϟ/2O%{#}NߘnYO}MXӕKI.XNLOH৥)rs &}pH3T?Hɗ[kxkk,+Zzg֏nRy ?V`:Y*Uc +̙3hrr , `ƍNV'k.˟qWp2qpiiի ř C\=553Z5cO:~<[?LfF3VNmY30ӻ$z=܌$M5?pqp~dCz)vk9qqh"YC%cǎ^pVpB0(7en"P$vЍ5UzCiՃUm_u ]alt4}f[o5֐=jݞ(.Y,t)cu{kΏGw<$hA1^zi,YB$ 0B-}W.88YnQl}=>:)[ʤ6֨Re /Κo_-ptERTF3|;~8בH 'Iwn/r. j\ͦ&+wl\\ScRlkkkTTTp:y+bi kr^<'Y;%J2T:Eim*dDmm}? 2u]IRҞʼn̢+Oy,#6K5(V\8K4dIPVzu^XX -XXs0]ƴ fSSSƍe2%0(/e,0&DQ|UlhC8}Rdz4S2ܹ1 榨 j?8c4< xC *jC.^{$4#Y[CC1eJ EZ>;%,Ʈ fׯ_M7݄H|`";hGwO 6_dtZT*OY JNwu\bY Rrة#doJ'|1!]l2] HӣSAju&I:CjƼ6VqWxߏ|O*YR)--ũ9!!uxvV11XDV:Sm0S@Tג%ПכPD2Vq"ylM+4 Sū֌lF6[*}]sElI2by\$&&NDz''k&>(FC)5ko$aaav|`Ν5$$ch$&KZ0 /{9P `N塔J"Ge]V/*۰ARrnl>m FC--)4 <E4u-s{߭!lJ)&sI,5W(ܬP*ZkJT쳥_?h̙W_5x 0^`0s)SF5wgy&++b֟ N`NʻhQ4U"u*EZ-{ U~+RVB}UUוtg8ALƭD 挋 .^V,A!I,NNE=CA#I:jHEl()//,4{PL7rh)XP {q$=9|*0 `vɯbcc/8s8Y8&KC6*n\g4rrt))҅ ҲH"!-# ,o v)I"S}z&sf`&&QUlovwȑihl|  7?xt:t#ϞݯKWɺu֩8߄Z0{ 84?o#"EteCF]s o`eˊzJNwޑ9^PK*.$lA,p6 ԼR}K{zl^ȟ"Fv89L|4EZu E,с9c0b}X߮g͕Ŝ>_OHPgf"8!`1g2g:xTnaax8Nؾ]iiuJ-Mdg"IR *G[,`1͙K8' ]T$٧fՙ^my,c%%i\xs:> ~fwΪ@&%qNk5.Y eaay]W &gDzz(?:剗p8Tjz%Fq4%2֌֐lF"ɜBmXl4G~0U{;iQQy,cʔ{mOo/ndͿ<`u: 5ep{-))hz 0eɬ#8z3C iW@yB/ux~ϋ^"꣖z=4RW^(ث`qcNgȏѡLOgΜ2O''k `"MAry/w:ɜ 7=NlH&D `Hm{Wy!9\4EB{S<5[;sd.Cn.9`A0 !,JM7F,3*hKKS̚c'N%'l(x4xCll?$EroN"EE/7wZ*mb` 鵵lQ\};d!7  ! , -٭N"-X\1֗ٛrlcr8"^ZmNպW&e0yl'Dd6䏕^<&kT{JJDII"}qB0 !,yRrs~$<$ EjGW/.n았(;;҅[ݿ6 ^"ἡRu76eYe5$!t{t!7vm M(ٵZ[[YAf}}V̟6z ru8~ʺw4dOg>~ lvpcid5r]΍7/]V,S9zH-%7b(ki . LcTyjjVYAf+CJL4/q8!@ܕc͚5^W>F砍R&=OʮJSΟ+Y6 ;*`qpc/ Qˡ(Ϩ e4*g \a9s|q/C0 !,8C;}mz06V~ZO,{5]}fit:;U+*}c^.syyW_5!N0dD0 ,A:Iǚ+X"'6ͧS?]Xc/͖P`2G6FKKM:6-ϐ쉥KKmlVg֣RjmkJH X5'^/3ko7~Y;v֮eΘ׭}G$ngZf!!<*CŚ ^+Msg+ٝ^%$srtHKQC@^*1d{Q)Iu&&SzL?xkIlDn0ĩiVhnCY*CyM=6r'eOkaP3j'30e2"?RI^"SSv6ĉ8Ab4%E= ,9EKBD47NgmCŖwU{o~K'N=@UiHnRh:=8d\WRykk_T[iyyɉ UW1"#QP XkX2bsbonVReOIY{ !, cuܐk$ ~kND݂dv8ܸQ0e cWcbRksIۛT..(c٩ryuOϨOީ魫 p"|-o<odyf&Oci(8`ȥF~Q{D5BB0 (7rWrm"MK[{h}G+b`;>kv;#իh<6FKs hW#i;"1, #ۿn/<Nm_vSr88m/c#"ݻn{kh^kl\^TNg2JKM&j'~-eq1NѝIc]a642^>&#68m!nik;{ rr6;[&JJb͙7p/>^} cٱ(^ HJKK***qr,@(-Typ"eҮ3xNK8-1Q r,ﶶMBa8A( n//oT?<;tez 1>PeR.uv2TDD$<6xJz__p k,(PFΝ+$"#Or*KkkM cٱBGwߚ5kbbb.8UVرO?d,YQԧSe sLiTb:7ʺo4-_^37bIJ2i .7]lq8FeHqJѫD+V=]tfhW( 7KJ.~ ΐ%[lc<ë yaEtDO% ZOOҖ,jggfQ q82TK9q"L#?>TʸStY ĄJWARCU.Uh4TW?\XxX6{QyuuϷc))jS^@4%bŠI,s ~B<54XL:1`C0f֭[/8g>cV#ɡqȟ30:5?,[NV~wؕP(``P$e5P[pB$2OZ瞫Y;o^RkoOS(n XXj,K")0a(Y@RҦ랿EE' "'&]ûfwLuf浝lJ!W9T$=QQq7PXx>DbjDxkts<^7ջw-:y:h߮oT<\B0?/qqqf\vzlۣ>:&,#]6[[(&$$6Ŀ <9%Ezu%11 ܂O?m_vaQڒh:DY|V0M8ޮi"]r<[*OM'LaL9Q99|O[Nl9BSA[5]%ݩTd4rgz|%']pּyU[HzHMoF*#8fCӊ+壏>:D"VZ5&,X=L5{!;W)*8~p`K/儅 EF+Wrxm6::ɮ(*4$+ܝUUoTmkgٙ]]++‰&%ҕ鹆&{ӹ)ECnIɺGLEq8q|~H$(M&SDQCV8סhoΜ>2Lygki;ԩQ^/,s`64ϋD"9$9qDަM6&,pt%s:3qpԙjTT&MƸfO>D#[!$u j@0}|t&s}YY\ikbqNQȾ}f2ghAl,#&M{e{k"1$:ZZ>p. j5E.,ӒP:F6[Ƌs䩩'N'n%`64M:uY}{`YĖꇫiixuqWm7Vtia 2.s]/{Zmv\9:]TzQAe<^R)XT_]o]8DI|$QR"-[-IjaGd;?B2ke46p&ZTTf͙Ss/n"`64J>|&{[r8|gOt 6 :%o.we_nx9+|1U<#VL*M&&j6wHxR٣Պ;`T MB_xcX|JJJ#8{\lgǝEˊJ{ QNKSDEĉTad|Uqq`?W*xJYYX*(HHGM()//,p! %%Cn.Q`6dܹ3N}ӦM?'|ѣG}|ן|;cΜ9^b ^K33#R ٱ۾}+&Lp$vҤI˗/=СC-cf|ux . #ҢhdG9tvSo6HN#ዢF#["E/L8kW/ѝw&"Y5״5Vqf""˅B!)((555,f m֊~ dqvsꝌF/|1YH.m5PΒ@$c ۯNBb c셾m6~~QK/ Miƭ0V `n[%hicc}?zNsW˧o[EE`I"odf6gi ayar{zJezqUy,1E"SWW!E ۿQWn%xqc/X }p7-f!!q"8edJvI Lu#YM,\+[R^ZmG(ZTpFd݇-:s 3+4Od'iao#p`Vچ"HSR  cH~B*#"0T̎EEDRZZZTTTQQQWWֆR!}󒔑m'y,>m:|y)l?^ƶZL"S{eN3_z.w%ADKb¸U8Cyx[fMLL̉EEEZjǎ~%c`2T8q`qA_kM&]}aǘB0\.8Clٲ珹CF0 ㉹,[ YF,C\a>d/әk0) |DѼ 9I߻&'Ie8OdY<#ٔK-y$lkoxioj2LiJ 1GDD `T΋W^E\%l6oݺs:1tfa .GO~EW2TsX:=RTuOTU]\P07Y*=ն K<m6̆,tWXNaÆ:tȑ#_c>s}>c7o9sfcG0 cɮHSD!JЦi_C2fErPT Eh7i E5 85Ѷ{e{.:\NgN1~.xF#[La,1OP( \,#о..O{yiN_xaWܩLOoʜeOfCU[^^~jkk+ǎ`ƢA{i GY,u)n< jov2udikk\l:9hq VTSwwVYo~ L0É𥬹ws.yxU`@xbUU=AOOu^WgG".+3ٺG-}P8xiJJTl&HL^y%=:lX{Ѣ[n>Hkrr,  Meee@uݺujݽcǎB8|0 +,tQE?_whzpEKKSX,gVӵduvRˍ$ApX^TX`h)0߈E勛2L3hײ/zEڄc'huADxkd'ۏiv]\ww&M:2דoDd$K7魷 ?hɾ>prfCӞ={%..|n^-[{{G#"HSo2|Xkά/Je cլ\ 'giK˩WNyksuu Yet%%J47L=sߛH$mժU:lѸss6{lνC֬,ͮ]ŋ ƁĊ\O}=sFG--(wUT\U\Cd|V0M8ޮJ2TIC^?aNWr+6n?o xvH9|Xw/'sL Er]N6ZMMNcja`64ϋD"9$9qDަM6ʺ`HiZ\ R*s&^]lcN.;[{PKF~6%EzU[V$& dJn\g Ia) (Ξ߭_mu8LI 'h'2$A\z]buvv8y֯ھzB[qyyQߙLߩR7 N bJKFcs= ;^ܱh2""bKC^3.iԩCR[ll`0l۶-M6 +f! ؋9'ح{nOH; キwbm4)<^I3 $ )RiJӉ-{GgXx&{_uE fX^JiJ6[eWd&;2bsɉ\PpZqDxɞ`Ğ(e2gOm_:WWfO$؋qGrrlJ%Ez ! M?\ve===+n?<&,~D;87?͹g=,7wK$=MMgoޫ:WRVZccd8rȾ sǚ=y3ii'ʒnfӛee.uw'Pm /;-{^[RVj]qqTU8;.02U ֙ʽY!,!a^@h94&ͰwBW;;sVÌ.i6w~]cu2,RmwH&ܱ0 ̲Siiw.`0n{z*,,aN e7- @(4v|ѺNok7{c7lB3xwVLQ~q3Z,NVΙlqY$=zw1`*xҸ@loCq+|a|j445}P^~9rTMMb?t_RrUU3-}6Tv0!ֽ̲ O=ԡCieVrJ ~\p 7XqwEWKcbj1z# |@i8%E]Xhgc4-{[| x[uLGu|35\\xq2iϝpW*LEt:;'Κ8'V*ݩѤl:l]]W+Xz9W_^]pZBe[-^{^???p_|_|ɛn)**111}}}s# 4ZPWLR \r4n*IKVU bNnW׋uuWDp~o@Jq̰6XZU1I׉]_WNTO->C&p JH42f.WBMKR~W-V%'gg;OlCe3t7'lݞz}pY!Kc~UN9(o*YULMut—Sqm!ԙHe*ΝҿV;4+iZ?om} xk½sfl{Xj_ KK'*䒢KyuNsXWRy@b90Z##(Lwߕr oe /Vq!3Ԅ~"fO \r%KW]uH$safzP++buThXlޚ\R78^+{뭆&EL!I$O:7Z,<9G=?ҢKC9N?si'` ETz!hIyygWW?E\3Ҵ1tp75<#fIL '<|ݻ w{ESQ=ut|@#q111!!!+aaa{>i=CiԦi5EID\Bџ+ Jat89Y>00HӓP,`1˽䅺:nWLr"S35Ϝ!:cbG')>lP=9CC<#"p8S-,/C{v:;lߪ}?GGSn{!\׿nk{OaI 9t655RX,d2YUU`pݧDuٺ5ԈeEi뇇&,;c[o-eExwgfgրnccD7W w(o549fCvǪ[-X{TNΧOh?n v/(`KQ!yyg^_]xC[ߙ͵4=zl5j{N5uΛ'9no[ 46`  !vf6MHRE52YYub_ v*|ᅺB9S";˽OjiY,.Uh*LQqq5gDg5X.wDr~y5565ݝk`t@P~mTPEb3 ,OsٯojQ㊹I{RAY}~uxq/]mk￿zz쳻6Mtvd>ײY,NY9IR&-/ ATc;lnﮫ{_4pïHOB u~;}clq\\}}eeX`fo?Da[[[Qs"t.Ҿ-].{*/B[so@뇗.=d/(7D.fK֋D+ x,Ef{;;[>G4X.w7.@fF^&'<\4T8,gy睍7m}ӈBW͕O0a[(K,Q5+ݶ_etq~{ V{yLNiBeoT|O?>lddٝ;w:Z*ݼn!S]Tq8謬h7wnْ9r8ɚO0wyykh<;+T+U=69R5X5ӡ[hx jjZO(<} w6jKl750NJ[S7o,N+O:P.K{E3vg733 N̒lASSL쳄籄Rv_ܶ8)䟓Kuh(EӽYTt3ؘ -YYdIL c0N[xTH_Tp/1Iaܥ,;X]80YYY=Y1^(e#'KۖfsdW.]mT|_2xN8væm-NήƺhWqo *{dvfL?ǯJ$1M;4\}wY_ Ԍ̶Bɂ0N!!!j>K/9yӦM6Yq#Lw> jut&%)-fŠ *.8#Ci;iz_sF7wB]]lj;uEEW?^3X3od*PSD{l@aE:]Ngl(*$Kj}uv`YvZ|9TVV~ɇ dESjʮ1 4} X]`\ $$ȳZwMg͝W5fl>*4 S52FS)lics`ȔH(jin%++דּ[@bmnƭZt3˾}s?̜h|BS=DG&Ij:ޙV/[o,,;.}wŁkFossHfW!Ӑ Og[[?Rz˝cel}vQlQQ#^܇,0N{a~;wєz{{\tE,2ʁʎ|*$eGRӃ+X$9cǍ92ٹg-( ]I|+V/ƆP!W\r3~^TtswYՖFuJ w|5.!0N~:/Ͻ/;9aN$Uɀ(X%袺&`y%blYW N,wJ"77]5I;LE/ֽp6^cxU88U tBZ% dΜ#!yT*eRL-YY˅`Ae'պ~zoPݳgOmm{o<,Q؊!TU9άxY@Kf۽/^򮊀0 'ѢJVQAGl HT vӅdUD7}Hu]]yBg$OjSvrhҍXA{x:#V^[\q`kҪ}[.L~beR`UnB a}ݠ b㽤{֭q̕0r&h dnKƜݸqܒkSRJ hIWH7uo'n%[w~9vL~{x PMܺV?"1+99&y,P?`M0!̲H$ڹsì?00aN:kUq|=!;}NoM7{=|~E[i:}Z y?i}>[,ԿoJbO`WEay<{mq:'}r23V}oe(yɮb^o8L&܄9GٵkWTTTHHa~ٲepRغlT '|,ɒq "S$|uwoaa ޢex8];+/Ϸ.UBium99ԸPN7z/vwv] 90` iixNx+_03B=sB9L,adl~~Ϛ5B>}vR90.Wv{{Lc(s$.U9PnTܳA=ȀIC>k<[G08X'ojz?/LUpju\W駪&2 `boXwokkqC! !̞v2&Ur8 Ȅ}}矯 [` `utɔR-dADu-]ҾV/-c9W_?1:nmRIUSTIJKJJc K(*m=rsWh/=465~(v}!3᭷_}QQK,,U?mm`vffh=!S+;Ax!UD鑞?|I[38Ѭ }cwzp^GM\Vt%7uoXMjnEשaV_ X\x.,z/E"ٌN,vӺtD1RKv/Z}J5jdƋ }K<. ^w>6I;.*Q M[vt^^x{lI^^\/9n:UJʷ~MQTt IW4%_MW?/2ҷJbbJ Eb7~ Mj_gd23۳((+:E,Eu^WJ݅KrdflmBSb"8̨(AjrG,|Ȯ< ir2 qq=vw^"13EO?T\nwx/sd8 j0ś7X%dSa!`Y`!ٓi^^DLizeu 833 'RAu^ne;RKR*FZۖәH BRqqAݶl,wl^:];K-YYx2 18aal=0 ,0{dw8y y#AƜnysJC ry0Eyi Eg f% ܴ[j>R)ZkxW;<ܪզYE6P.O0##@FPč"+gdػq! !Κ{ݒRg))!5d,|teESd9'?#C7R~r;E6F"N:<=I;F#UKKzxWk nK Xզ MRq>*ɪyy~y%)۳\C~l]:]X/rexSm j !Ѥzulഄ0 ,0\k֦iśľżW }rf@y%Eokhd˭cWWFτ!GlM++zX-pLؙd* ;@*Q[|wWXʕ{o=Y`!YGÐi(+] dmλ!|hRqqቃbA$JQ{vHZ IE&r  |J &$ڳ%Kj}bo,O9.(4*y, CdQ df𥗴mmÓX~[SuPwv yBMkkR5í>4TѤK*Fp-YY۶N^x!354~f~a֬1SԹ+r}{ ѿ/۵^kl4+dFcBỊj UiZNu77ZWݞi(HYB6f|zMj*R;pF9! ,ۿi/wBoGzid$/9YUU588}G^I,fW\JčzՓnut"d wkjݸf~"anӾ[B6*}K|ȞsN~z18dj>m,fCT  ;9aE(4aW8tLQ(A:i7⒢KT|ѥ3|  G..W(= 05Y`&.3S/KVMڍv F=!A] =]GS ٹN(dF P9b]'\wSM>ݞҺ܎%~ sD*y]uu77b_tl!%K ~BGmUf^e7uqhX{--۸ql3dSVg6dި;{.aCmS5i{{eR+E__}i^D{w7nE,if]T^r5X,giz$#CB1t>rҴPIkQAL> ZBQL;;ɉn!3`dWw ~PBs= HFp?iv}]})d9)\/1I6Ro;x*Ւ5hҒ|lX<6R /xll@*990;0 ,4ì;3o4m_=+W0t˖V:R?+.pN8|PQ%޵ dxviáKO焅1UVyQ,ƽpj  0K;h52ֿVIiǖ/HJR &oUAVK =2ݞBx^ _&=vAdu-ǙR+I;ITp:%54Aa**~oib&.Xۿx#L\``*3@',3g#k`,E)Ny.UJ1U rr, wL^(uY͆\,'Q'}jo[?<~/(*gk']$7mb,'+$ aXhw*+!u %rܰAd29&}wѭ/-s;*Jf5RGW i:o(ˋlT0 ,4'¬ )X%nf96mBN¯qLMV>sj)SL px0s`r3UV":0T*L;Aw  ?Z,sIsJw.g1xmW1[}~, Vj&RTFvۧ/FD0UV~-~N,0 ,0pJΓV7T6qi٩rЎ{*{N9ãögK*+o2S\tjRS$KiF-ffi]vcl݋u*y\ ׯOjz/˚ O`y:lG_EŽL<$[Z2D‘)/m$Cf&'4ʤ$ՊffMR'C`|~aSeoaҲSodm:;lZ~q2/l&xZZ>z$YNXᣏpB, Zs\ 9^Yxu ڵBҲNNT(*<7W2~/YN)7kL-)jmzZTY}eemY`!YKEN8MCCs]Z6(9;blD` XWd|츋難`~oH^ud@.j5*[_ӞldK23qEB ~tվOT٫.q֖?TL^P`r8#Cf7XMK@:a'! ;k*0y 89Ĥ`*-Mv`^T(fpPhJcIvyt]5 e))7kxyx&}Fb0 ,tl_Y/G$BuQ]}7z~p,~d0ɬ+rseȽ"o],M6rYek*[,p¼I`۶, 0 ,tj``*D}鑌 }h( "7Slldb>o]_Mw{Gv8*+x/ &⸸Μw*Y`Sf V Fii4 r&P:qtv{NY Anbk$/2U8,Rzˍ`e = :gOE~_@ìh;3 o50KK6n[3D2YASәyyıAnf u/:z׺/㎝y|H7d0?- e0 ,Y8Iu/ԍ] $bݖW 0ddd7"UcaFn҅uzlAJ2]\?ٻ/Y`0#V0ОCeR&Ɇs^[}V&P~ '貍f2*|,~N"ȨѱLł_&BljZb-W0U6l=pIv? 2ygJz$!S"9oܪo/Fג儅)MEE` B?P5|l`2j|k=-M8|E+[ x넻G# `*8Ujs&|bl+0ͺtш,f{z8 sԙw.gl|xvR e$kT'{K۳eqSd?"_d$A۳i ?L,I5| S2U&GK<.ODgqVSl-z=~/)Y`fm6IT mdz֌UM$5~+Y<.@OQA$K}H& /%+=<_ faX$YUɫ kxᅺ J\+ÑyOVZ z5uc :; @pfNV]tLaU=zX]A|B~nk];Qv+dE^< gdaXd'ZvCgDEʦgd-/%{h;KKWjSe=w ,B'%6I%DFxLU({5I|I\^~(mZ={رcqoݺڷo%sYM A.@^fi'Hʀb>믿ꫯ>S|/]fy|vo.{B.p@eۛU͛㏗Mo~Ŋfgg"brH'Axk[ 8= ̲SII7^|z~vu]ޡJKKglʊ1e/ra& 8m ̲ӣ>.}}}'2z9oU7.J0{{qKabbb?>ggg][k8pט]jdVիW/CGc4f T-''砞ɓ ֑pqMMRؙgz+Ejꠞ޽{|ʬK. #HXx≞ HAATVS q|ـdJP\<@HO;1hРu9lRƏv=v>}o֭[M¡zdJ=ٳce%³ %Ȕx*S;a漼ݻwx&p0Cј(4f!"Y׫WZZw .,((ˇ^^ ^z L4f! YHc>}'tR[׬Y /4h=3~ɓ'GSL ;r_|u-c˖-7ol8!YBc"ҘzO7nڵk[=Lh8@,D1 `]>^:%۹s\8!iB,X׃u}Yz?|elٲbŊub+UԢE lرV2 И(4f!"YtgϞUV-Ywޙ9sfnny/^o8OcИ4f1 QhB,X׃u=&p0! YBc"Ҙz&p8D1 QhBD`]n(4f! YHc8M,D1 îu=Xc И(4f!"YzL`7C,D1 `] L&pBcИ4f1 QhB,X׃u=&p0! YBc"Ҙz&p8D1 QhBD`]n(4f! YHc8M,D1 îu=Xc И(4f!"YzRSO=&srrـ I,Ax6 n)ȔN:y* ?8G H ((AY Գwɓ'/\Si$K2 H`֭=X^^{GH,((AY!@z}oUV9995j;o޼Cj$$F@:dJC֯_OkH,?L>gϞmڴSNŊ֭dʐ!C-Z S`@:$ŋoﻲQ6mzWN<@Y!ƍ{]z ~!pңG ܹ5fJ!{c=68xƍٓ, i)Z,5·~ Sʒ)j i,۶m QvܹsVٴiS6mOr͛!pr'{Cgʾ^}ؑ#$KdQVHL3fLWfeRLQSHdپ}{~_ANYڵkxY6m:nܸ…+ 7u'" ' ,~w;|qƍפ Y"&BgJnna]v?|lٲg}vРA[e]dJ2EM!o߾ArrrnٳgXwߝ0aB'Y`J{ ڱc.~͛80`Μ9?I8IHdY~}0pg޽,.S O;u3JIYADLetȔN;-<wܑ_( X0桇RV)5tHVffflf͚}3xp]Z.eժUWZo+T9s~!p2wp~^nFJfJߟ2e:wS^d, ))N"ꪫ ?~i}sGYAD5tHCw*Xpa1;w<baYYY[lQV֚5k·o 4hP,&33sڵI" ' ,z*wHL]vq^dޘUVHL0`@K.Mٯ_0>RV)%54IСC{7̔YfY~8|%w_?7n\HIBj$K;m:]5R2SbkRV, ))ox≉#xpiӦ)+ȔeB$KJb;vm ^xpSZ.,vk֬YPPP\X~~~cW_}uHIBj$KWUlSp4W̔'o}kRV, ))uog?~L)Q)Clٲ%m͙3'?iZl\pA;/ٶm$Hg4tPW̔F"$KƬBgJŊc;|͉#p SJ)j ,X|yϖX>ٓ Jܿ :|$$FԫW/G ߰ajJ dJ{M DYeϔk׮đrK^zL)j ހrƎE|Z)+ieժUy=$1bDe" ' ,K3g۪U]n2334i2p{5fJ{M %zcVY!3o6SN9EYA(S$KhΝ7tSx{j%m-Y$?xcdž~i҆HIBj$K? ޽{VVVq+\Y]$פ Y7f9SڵsE PYAD5tNm۶SN}{}QGGޕ[w}7'ONHI8IHd L>Bd͛735]$פ Y7f9SB_ώ_D++Ȕ(k y=О={V̙3a־~0JI8IHd =:~oӦOK)xV?NkVVS~~~vvv <8q 7\rxPHIBj$KQ|ԨQ.1%SkRV,1P3eÆ ڵ _ƕ*Uwy3LQSl_} _6mRVS-b/NyE"O:$HVXݔK9ʔD5)+HޘUV(י}6mڄN;?. (S!Yf͚5G/~G?Ce%=]veX^đ_ꪫROe" ' ),&Mumǚ3gK9ʔD5)+H(ɢ&r_r%UPe_j i,7 ^vVZ^Ç_'y$$@L6-K 2???eA tֹs3[l7`u֍\tE|7#( e֭*Umj֬YL>= R2H%leɲdQVHLٹsgڵc^?IBjgB$?PFؾ5 [i3&|VJZ _ \sMAAA{୷v[ЧO1Dُ,C ^x۶m+N:u?ݸzjWr)e5)+Hɢ2o޼pSp#ꫯdJ2EM!Mހ 80ګW"۪?|NNN,&++k(+GK,Y\B/XK."w(({lg̘oرc_T3qDהr)e5)+Hɢ裏V(}W 2%q) 64h 5j/ty޽{K}ذaV+lݺe˖/Ufgg?Ү]>eQP! eŊs~#edd9fJYzM %z(+v՘UV)54y6{jժEɑkЧayBMx={ ^qQP! eݺu} w͛+.%=SkRV,ѓEY!31 SdB[lY۶mdGzq 3gί-ZT^=''UV;w!5DNR YBp=g?kԨQJjԨq '\s5>޽{]AR&S$,?9e S$Kt pꩧ}GqD{5q;v(+>w-Z\rÆ O^( 77?yFTҤI+WzJmƌ*Ug#Fߖ-[yRѣ;hСi;v{a533f͚'N /^dggרQckv {Mo}ǎFۚ5mڴ|HaIhN4)6Dʕl7py"@KBcvܸq!ׯ_dW_ ] i{>W\qEk֬٪Uoqܹk׮}> fgguQ۷O>}G7o7n\׮]4iRJ5j4o+hхs9'zYg}RZRn>᎟y?Ϝ9D1 ^5\.]Ă[nݻwr 'vc;mعsgⓙ;wn8Kt@(lou] >c"sα]/Jqz1;dȐئ5kdV\2q,*'fu n֬Ym۶m)N/bcv۶mk><]̂ Qy, Q>ںuXg/cԪU1_1׿5qŊOfڴia3Jt@(lwq VZIzkD_>?cFlΘ1tӧ;Ξ=;˖-ߤ1 D6fK,I9s0rԨQ|DOU^=|0lx֫W/cǎ-]cv͚5Ꮇ~{k׮ i 7i7f .#}݈_~}VVVq}x~I+VLp3$.tE5j1[8[n]5b/Ҿ1{ox-[ݻP,]ؘ {uԹϟϜ9s+V ے;w޷;_3|{o͚5oѣþhG1??vN:ر#شq jժ͚5k׮]q]zuȞ={¿/?~|8D<__jU <{n+6@tacvmڴPV֯__Qvխ[ s} effrkժ駟ݷ1;r}8e˖ :t5eʔ"AY 1;lذ 6$h^~|Mڽ{ߞ]322_jժ駟AU8B;j}Zj7o|#4fG^{޽{7iҤjժ999A@|2_|1bĈׯ_bŊjj۶7G%qڵC 9s6lXJf͚]zӧO߳gOq/^|feeT֭c4(dӦMcƌҥKƍQW~_uUSNݽ{W p@ۘҘH2Y$ӘH2Y$ӘH2Y$KN#<P> stream xy̅콎u_!G"+H%I_D7]o}C}UJ%WߤCUHM\}ewg~vgvg95~fk;bCrg*u*!kFO;)V.WZfOLذLv#3_Gf9hz?lsGqZ6rs 1wY_G99W9L>a#7rByDrCu(7١`^&`=)$9Ρ {ߔrhn} C>9E}l߽~n߅?G(rm~c;AGH߾idȿ+aG߲h?9C:}}Q۠mGq`{оM{or!M shq/9LU5Jj*re-Vll9LeO_:74O!OwҬ}ޮV+gu~qkQ5j/Υ:7;UyÍ^=j{@$簉9<ĭÙno1l9q?v,RnsϾ"2_>mAaFޝn3ޖEs>$9Lih)QEε-#9|rCrs:~?lǵ5*3SjX;K P9|^۱!DrW/t3/btga_usUZ6J|&GD[{vmCc}rQq;cU쥙crw,^\*Ͼlˣr$sh=WC,k?"8oY͡e[myn9|8[nu"kB bshj}-/qZkZe'÷U=lā->arbrzh tfGv?+2{-m\޵[XCK2{A 9'=/ .-vg[Mec4[={c5:h'|[]?^չan> mk~~{3 "{а}a]oR6vK}`a͔hGytOכPчmOTu!c'}<}!-k['OûgI|gg6 `}}C?_^9\fdΜˏt5V,>',?NA{Kz9DDw=Y!5$a8"a\shNT9DD< 5 aq/;J=! "r\R=9X""FpJNnB,NS>CO9sRѶ((9DH-{>?B-wsư|6HC1c%yn6GC/=>oB5~DB>>ڴ]i9ݗ~s~K4fC@$n7nyŝ)19_행zSrտfbzOd 29DF3ݻ{OHKVۗ/&%!$lYOKѹbqMrv:n>i5wIC@DBi#֌jgxԃ^)s1r]1iiw֚C|f@K~q%ZcX,/56֐L;9B#͵Fd$>hAiO1rmŔ_"nrGIq2 nj錂h4ۭq̈́mLhr 3)~]fAݥ_fDov-+.sxT 9FzIe[,Nj+ ,%uG|:9Sojo꡸̃f󲳆Zƺz}9>6ُ&[(a 09gL5^o:I3_˘9ӛϿW1#$ͷIR V3r4tV6AcrU?8C!G`\%T s!@$IKm'tCvd}@8|}9t|nuOCaaG=K*j7!nV eg5q1{k)94~(l9tvr9 r ǟT C,:^o1S爑շޝ@[;㊷f2_e=9'V!$r*9ڶE5GԝLSVa'YƝ)@h{\͹# :u9.Z(5J=!6vNz CZDR5K!6Z2u5Ԅ CR^eY*%B`i-3"N폤Yk6Kq@(<̈:T;oϑnZ3WFTxoTTDJO9oܸqO֚@0jROf2%rh_*ӊ(u![-y?SF0%rh$pQ~ B_/gNЮ=S#.=JoOMwy?b49C+$ے[&9pV~\L:zӔ-Sm5`כ$ο p֙]vGb:Y|} C *}2WO&E]?u{݃fecyuYP̊ 9p=?K}fE!puXQ]-9$ի‚;+?9$(ż{^9$λG_g1|!9[} 7wh@b9se{KWy>HxXaxCrHq kHOwzϥRN}\C!JfbŸH~.ښul-[I%wi%@#=^NYc'4<s=rKE_um)Lh77˷&Dn(\Ujv\/Lh]j?Kz8n[4O,9$ =irt}̗dA`B~V#6f.>]W̒Cr/kפ) ~nl ~aik +cnǨY>($e2J|s^} MZ Ys/gܒCrz{1~+&u: VZE-K!$y盒y^\ۤйD>C{qXOU].tgn}':A#|~!9P Ӥ7\J9qg~"2n+>(H3ꫲ? ]Q޹mΕ.*K@He[tT~Ys '싻C냛$ɧ8rnW~ xa !}8yInv\*q,>.4>!EכRrfJ#<,+Uî}n$ⰱeݟw? cR-|C7ˌ5p#]!\j|Ou氷TuIC~T_zOu0yVH !ZeeOv0IZyMFJCpD6N5D%C~lD|C&Ky^Aj@AK?hFK9#ԓBPwT#|C2%pfc+CA]|C2FB[W2wv@Gkn/'=sxlo3tԙ3-m>JrGGW9E|C0=^oȴ,\\e7ˡ]1l5߇ CnVވώ.)%<>rh>sr;riIGgTu2{ Z޸|"+SE/W\mh̡CMyrec?_OmR| j8qΐC~!J"EşU:9<5E_lߝ&M:+vgOl Dr8YGZD~(rfS]Z{/ṞrxbC79`^1#|?%`q=C+;z?ƺƑC>8ޖYV_gz&f9ܕ(tz'Vg}yj)o!,?.dwn5|qqko>&ů\1ԽCxk}u6ۥ-l+bBaGPwl =.Kf0,;uH%v|9,!}YZfT#wQ}rDb=1dsjmE,i&/܍[6Yo'+W",a-c%2ar֫ÚW.kC^,.!7G?7V=CpN!͎+.k^.rhGlcy\1r~#J}!ByԂ,4)UӍ2m7I8(+Iwa|ﭮkBPKѽ~/'b[QI$@U, ♬9L]ޣ&-45jx}JrDQ~1oIBpCU^U!J%`R1ʡ+aI>̝R_CL0 ˡݒVLaUO,JesH. Tnc ACc[V/7yKD֒rY{PBP!aL!03-^CaW}9rPFG)CP(åBp3WU{rArDG23yhEW]l eg51ϛ!9^9V V8'oG; -L-C +&$YxIL!hrԔ7s[N 򷾺tiPxiUt=S2wɫsOl%*=b]vT9ϼRRt2mg AéF g}Eɹbqg 9 2 f b $9"5rXZ(5J=!<K 0o]֒&:ow*dy_G%QGBp䰤yuY֚RYr Glc;YBw0ay#c֚R9HWdWqBP䰒y{\/72WFg)'יBP䰩T]T6\jBfV1os%!EKvxZq79Q~18p>s$]syJwI?CMJ~|7Wп35?rSj$wiuTq-c*`"'WrϓlKovw_O!=Mr8V yIrzK8[AmBPb:Y|DsӤ7KߘBpY=h_6F𖑬ʼ8>-a"@xDz)M"ϸ@02_'߼#}[v;9$Li8SctoVQ*"ac;x_[XN!"7[z)w⤗!9P䚨QoZZ'rHϥ!L^x}wCEJV_޲#!4)[[MNWwˉX'@ѺVIM>>>X(RALΖ޼ݭ*sbyN(J-USou4^[$}L!"4S_ Vז%9$ *7SFe.ݤiC5!9PtJO1xCos Fn@pIB@m=mGۍuһ(*ˤ~L!@J1-+̛\ `5W(*PŸL!@V^B{.<.CA ۤǘB/VĘk*V;nVl!`AqB@ץ-{8߃0"39DVԛ)\ʼ؊ft?}z؋ՖCE6hl:ZDxK;xCE`vB0Q>}):=M責;OC!@C;BQ2/U\׮f;g!9xtS(b>mdrCr *z+S(bG+vnwQt_OPJm~} ?i7WRKyx9$+e^k3wq^-5Ϥ|\-'!qڹ㼻S%LU,9$Ŷ&<7v'^2eh󱴘Cq^k k4ϹHGc7JGldATUU=uV[FjA!Hj7s6J2CbCrwIRC1_];4C>6IЪ(uqnt:^!9c&cNHĨo.jyT|.sR{K5Ҳ\Oa߶5?~׽'.JԽoq.Tˤ)'vE19$4:a9"]!xnjn^ZC,ޤlL햒C 'p9OFHP. ^;Q1+JwaZ,U/6C/{ ;ymYۢ'!>MC[8 !1KwK|gg6 `}}H0:J12Ҧ<R(&92#{v\~b99_z<'<ܫRi+|N5!$ !kX^A0oR.#Y!5$@[XOR/L;z_& !^Ir0#N!N޻j'E%5 t=9J\shNT9ocnND'aۢ>wz#Yz \nk? UG(1wAϥȡ7HuR+ۂ{T*A?6905sEbՇ>;;\TetAV &䰐v7oޜF~ xĹO%۾yگPVM2u#J{D>{)kQ<\6wkåa*+Y}jO;{wEIwzGK݈E?B͚oΩrHa.%{3ákZ+Ubzq.RI9՜%KgI/ؖ˜kucskZÚ 9 b6{^$t˞kؕ3S@HJRȢj;(SBg夲moZ_\bܜEQI1#1z*trh}y`[g4) D?yaL>mV5CDC`_u /IB'˜RB/-v=89D8;vȾj]dVKcC)K ǭ /攓Cs7?Ƶuh `4U*~9 a)Z}Lq.&}h !tJW70VĄ6/C9@nfHߑCrFj1C-{MͨXE,9":s%5yt!>Q{!L~8iV"d::s% ?./]ĩvuqk{]r Cݳ[.أ7V k5OlPr'9E(E:P% al4oXֺ;M32zRZ,'K廃Lҫ an۶Y#2I_T!߇ҧuTqt?#Cx{X E%5IݍFȡ9%I C*gQ86zR m64C˴Ը6mB/ғFbIGܩx=MR $f͚I=gy߶5?~׽yi]C}r=?Uڨ6QESNP=w]Q̹Մ]'#k5/+xzRJ\^~ˆJoT]oʾeSa]%sk_r f10Dk~PE9_R]2U?cju;CJS%JqeKX@06~N]]?=0`_nw^CNxıCn[ֶIr0u8A\?>μ(6I鼝v. esO|gg6 `}}HޔzZ?sx+y!2|!f^N;LZ"9\fd=t5Vx9DB2.%Qa3WKKc`r{gfKj{<*9DXZ' a @vT5y)js(s?'9vN+Zxr00 F7ݍ3^-Ky?y_>$i5q*ER˪Sr& y#mt/0[;pBc?G_2D>X7Gb=[zۯ9"ʚG}lתO_komc?vI RrpVe0 _t}ڪk.9ˍʹW{K!Ћt ͗ ){-:~aU[_f[W2wvA|d gCs=ڠ`H9G&_G:'ΐc?жcN ?ui?~KE^_"-d gg먂/W_9ٽ5O䰤=n| OxIr v2 3qt[ΥTr mn>a>l"x+nLMWI9~ua\rXS*o99Yvor5V)Z[~'/z۱.9Y9~[*m ~6&^MTKTy%} !}{1 aC `@ikVJm#Y};5*V*L1 /1޽`i~ʡeh KewO̟?Grpsnd @Lꩌw_7QZ9vt1vi}oԴmLcGK!Li*S7oˤsYA+Ie܎(5OenNa @>*& 9 rYm{CagWG}KcI#LϦݔʗU뫖tQӿf¿^}ԝzpO4n]F^V0 _Is=9w/v0:ڼdX_jڿA޸<9D2UCpY]|ӊmNurҞI >a6\}"l-^g @)+/筪C#WIf}a0KWn;m9~N<;:?Y& Qƣd /=}wIR_y`ZDIC N^"PU 8]zT,sЙQ|ZYu{y2sxvC Tumn2)m xl%M҅{ԟ=ۋ"lLF0b2,? >!^ aaτ%HHd6(c@aM4rw<m?Jgl @?# B3:4-n" s8A+'0O{dZ&"+H1.iZ{U||yAZrHUՕL/OXC'JS9<:m,MFso!Γx)a÷:*POwˤLy=ҿ3!છb2 s8/і}wFw'Cş)sդZCcˡKezx6eAY'/߷rв-AzR+9I],n9Sb|@0aCl9/5%@t9yK;pTN9,y&n";)dl9HK=1)a^9l 9D(d @pr8A9DK)LZ_ 9x=ZsvIc @p{yqwX(6E89DL1 rhYWQL{I r@ȡ]n5(xqrQ9X~}bG oz6qr";Z1 brh8&]䧢"(bOJI9 EtYf 9$> ߑf1CDYQ#Z\_ҙ 9kpon&+Xq}Lq.6TpPZ᯲XOFrݏCD]=̼ɶ/6/۫aD|`;9D@o(ec\x^sSGȡa9D8Fz*ީٽ۾K֕i3= ۫rdER'rp9mɺa-cElpaA""5Kɱ'VLrRJT+0Z,m$wK1ȷ|ybwvTT|C.1Ywhco2:{Cg41*9b~vyCW32Pw9DD0#u53XXO7rN뉌'CDAu sդXOOƺR`ݿŸ>.:rh5x1#m қoQmc 9Mbqˡt9D\F K@Jd|?ͼoۚ_^!udrY\ڙ-Rz}vsՄ]'# )ͥW@9,#-͖M~M/ej˯!$v~&KgGR]<ю/xO 9D:s$'1f気ty{H$/_Bu!c'}<}!Ir"yT8O?]z0+ pd.c;̦AÎeZG*{׳uf-9s,3lgG+C܎h+_rx7qwX(6E->iEz;!rJ_2-1 [8 uKZ$Kz^BjH8OR\ @9˭95dy} 9D~R5uL@arhŎ&0d94'*"0f԰~W#@sh8&]#< 5 6xaEeTmwoTvt:s,7~LoЮc+C[ڸRLL79[s'ndx_n d,6!ru9<1ڲ^9Xdw_{K5S>CO9sb?#(9mb=~E;8,XM.'v˳nXz $xU JZol"'꒩>&/թDerV+~99ֹvHrV0,c=l9qJec^b޳~~/= F͟ q!osI(ŭ^0;N7bKBF !2~C1ۮY;rXA鼿2$`f޷m͏߯u/,ߣ,`|a43l<Ӿw]Q̹+MBî|b90GiT31>n~q<ϢMُ0[JᵌUî~!E7<%Y Hv|=)8Q/|tqd^CNxıCn[ֶIrB2~E *P^MџݿsmT0NUT2!e6yHWcrrqj{rEz;!rH7[ ی8bw=Y!5$q]JZX3@0IZyMFJimqvޓ}i6 sX2\/}eap:Rã{l'Q ^%40a"a}:=8(r0ѫ8.0afZɹ=Ɗ%m&x69t5Jnl鿓$aaiYX۔ @QI5}+}SΜ9moh[|F]Iv3K"ap{n?&ah髢D8̡]Za0 zɁ8c:':K_XδECߦ]t1Z޸|}wAr]@$Џa{Fz) 0-gukÈvbo` ".Nb`孻T a{Xz)jo;VajKc7Iq5÷~ˡtJqM{å9O͞#FWzw9HwJˡ*{:gVR٪)o'ISa*ud "->EOWeܙB#޲1v9CZ(5J=a1,}D\kIKּ/#g Sy9,)t~]jfTF-Tcy9v:of)FfZD`+IHe+U#iS9l*=}r=YkKMad%VgHaO+_ &̥[Ddיs.O.rQJ2CK7#{Gnu]{J cޞě&Hg "4'W:)kI%ŷzMr]H͡dOSNw'4)Z,[4ϞRzArfIm͌@$ 4˧aW^ ~ECw:f0Fso`cqfȴ;Jwz4ȓj5QF7hCrU\qrH#Ѫ?S@ad[zd9$hEۻ8aGALQp547 _)n_5m⛚?> A )G" ) + Yg|Q{q_sg=gwr(V:8}ȡfي[=ca-zo re|%eȡfٓ"Ziam]C9̴! ~9L[sQDC9̲El=9,{ODC9̲="x9,{K9.R ȡf(l a .cC9̴QO2@0>Rl1r(Ѧȡfkm.S ȡf܉Q09lX6@0JDȡf۰kMC9 29l~r(J8Ї,9Ì;. 6@0Gc a3r(ws rmKN+C9̶9l{uj aE/ rmE\d a%6}9l!&SPmQu1r ^6iӳas7(ߦa-eR^F,f칢89G.O)8?rlg a462S~YNz;zЫ;bC}>hαc~NMjfr9ePS~Hk_: y`6? ; beu=Ȉs9+b)rXO=#n)ٙZM1GJc9lnV6 3sX.:a3䠈+zǺ6/z0b|qx|rجT)Y~ߠmSaÍ}3DSSE7m'Ǽ,pckQu #U?Xl?<3kofM^\0KsIb$bUîn^nt+V[aǷ"ܼ"Ϫvı ~w4*S0_4)fۗx b6O+|Y;9ؕ#6]Ƕ6m^0@귿3SDΚ jT7 tmU T6Cnp#W_+1@ޝ*>ϖ >lWÍkٶ c0JoP+b_Jpq)rgo[_ڠ/!Ǜ ͏nL7nnxȡf[c4LI&a =ؚJ}c029lbVü,޶'{͗æ a${ιu=wJæ1rNKӔ׉'?&dEh1r^6|r{ES^ua 9qڝ]#&9L!j}{T1rD#:d iuDg~;æᬈJ7xªVac'RcH%{D^D XEty5ﳾ{ľq)ñIy`tr9ll#N3rqmg8rzrB9La}lha+ue++|W܁rՏwԩAH/e+x]^u`Qgd9̯wFi>WL,1FaYzy}NfRM%uX䰫[vϘu*?䊤M;D+yN'iaD !D=@ÇvfZr|\]iavs]n\eavsoDE.f83{De Y]"r*,f:C ,f9El YGG8˂,p^cas6?\09|s%%V+f9[E*f9#:kasⴈ-R09\rPD-T9r_JāZrNq')f9wYU Y (f9k.d% YoiV(f9 Fkas8G[r>%;,O9rGG`@3!k@El YGG8,p^caas6?.09|s%%%f9[G%f9#:kMas8ĖO[r~r]Lj[a邗Myn, Zz2pQm#aYG'3~у S ,UĦCV[-<ˎ:j"kpɞt蠫#6+?ìyJh9<5yowS?3nׇ3l;:@HmK$Lp?6O,C,##lK(8M 9qKݏLN=0I @Vr9bZݏ&᫿=0bV @fr3sX.:g.++wն C9Ǻ{r8;d X};_#N<3Oy ~ƏII <01#9\<̊+l~(WbNO*ҩ_4xp~f÷޿0tE.U^7|رw v/?sYrNfosaR,l1u_ޝ?jx}u~c|ٹo+ @ͽĞJfA_yp^Bjߘ1O憿9dT3߱0OAne [gDlVrY~5ڰ5~t}G2O[~w+oz+N-6Hǽa}aM;E\[5OZ]+w6Nzg 5:;.r^sˆ-Fv]566O17mky9^D޷䰶Et*dR'W.I F% @?R;ʹMãG p]=#~X{e595q QZp;F1###zO/yN6=kY:DX6bzG^h?<8>KSo"~cUazV:>潎|=xg07q.;}唈s+7eG~{=au:1⃦7 "eQa]Q\yD:~bgì)9Ӛ]#6|s^߭:Ȉh̚dV3)9ag/t8tvJ5k6q% etCr #(U;&wχ豰pcŖ~Ƿ\æ_Eފɍ[#7M/l=W[QrL׶X}/{t͆|D4ҤI-$l߳siw5!ɑë#[Mr^҃{,޶Ƨ {o9<#Q @?W${ιu=wJnq9\'[Kr%iJăퟷm_s]6|r{ESZXoR7⢵;Fвrv~ncF% ӢrxUmVG/+ÊùO ys5vF\ׂrxJLp}Qs/ ΰpFĥ#]BrXo{:TʚF'N)i9qe qmg8rzrf9'o駵> xbleJ;Y+D] ]QE9WXԫ*&%#(?h ߷v˖]جr}`pL>86=(=n|+vՠfUC:G_ MMz9oEqZ+r>:9n^Q f6%E2pB8y@÷Lb(K@Ïh?+@31=" Nv&9p~-"L:09\|IQV !D}K@ÇzFa/Zrtl]eYavs,w.ׯ*09,ElXr.{u"0+9>c uŰ/>0C9,8fwͳ0[999999999999999999999999ùKjk49F^y ,X0m9yvplL7qѤst7){t61mmM~a'i17“C9D9C9D9C9D9C9D9C9D9C9D9C9D9C9D9C9D9C9D9C9D9C9D9C9D9C9D9C9D9C9D9C9D9C949CPPPC9C9C9D9C9DqQwTcYP0wNe[\L>h`e a L 쩋v=?i3T{{GKGλ_Y95#Oܾ}NUbVeeKΈJ/i enWuBؼR{"7쮕'~y6G:aƵ'kYCN /s}԰[&ܫr(>lKk4󿙟1v٩!8!'/Ji0{+r'&5l_|,ab2?v3Sn;<@5.Ar[K6 e}?iԝ,WV'[Gty|NYs/ݹ{?%=3>~+ujdmڙ>RYVTIɴlcfid߭95y6z ⒪ # 29k9tSKa.86-#YYh9=ΰL+gj"'kޭ7^a|At|6ɱsfRϓcW\yѥth{y{?+XM-[uĈ29Lo?h9>jBdWψêػ'z/cܫE/C) xeΏdz<Vh_Z˖/_^' u0ac"sj+xJɷ{ez^o$OU^. e-_q_8#7km%M,R6?yᓏ~R-dz^3zwhrN /se7ǚZ:s_ՈAerg'GFL߻('dj}>slװdwsVkz$);-TlrW_,l+VM}ˬ_ /;Lv'2j&b)?EQD:,"v/E\mj< T]Ȧ=dwBN /s_kj:3ҙ;DLg|PR1w̯cmq?*,}ܧ e_*7IkNX%)}Bk?i.rwAD*QsPCk] @^^~S ,-]9Lm_r>tR;Rx?Eey^o&Unwy{wnq7"7R7{>=9ҫzwD{0]Z{A;#*)z%;=nm~´R6[Ǿ0j]?lbo_v8zZߣ}˖n1wQ:w9l9yU^j%ܯNآzkFN+M*ݹa,TRuo75s]}jgfMX eF|ϥS{ J/Q/C99Q?= ڹ2@^~EDQhrƒU;"ںS s]3k0~bsY#*6͞={@~bsMֻ6حJ4gS,$r=&Dy~L~ OWg wR8Qƞoc"!Kew$[V/񁝐[3JK9*8lݧ:O s[:|#z{Ib\=nӢmKK6 ξ).IY=sch`]qOu@~~6zF51?(顮aw9l/8ꄮWjs_}e:]ڭSy'cf~Y9E7ݣ]ݼԬ6ȋzcG2 jeQSLX@&]dpQo}ԩ&4)`%囿N672萈vVnp9I yEG sqYk(Zb(dM{7&qPȘY;9=TȘ$z}Le{joѾXȖ$ll9<:dL:r2a> stream xYo8=B2P1"Elm]}N Zmh񒏸]:A,.J5\E>b. Cbæ~g+r#=Eeaw*aC×ȣ>\aA!?j㲨C$CvTaqy J# ΗSX#=ډjWIĵjsqaأDM]@xT7\''[, A"3³&B15*T+.>ۅBN#gveqG  B`b1АܝK@{XIj])-:7YZBJu ^ ! v{O6VFQL7 Tc 'i_2M XHnR55 \!CC٠ |dG?N>`Z>S+^B2-Xӓ v@0j@+7@0Moii< x#B\&!Jg;( d7EAWy0]iURB"it!c( + ')`0},Ve@gC-"1+s1YShB=i\s~p-T oa`Ykj[뿚ᛝF_PܰGH % ( \u9{љttt'%(z+FO/ך3dAH tm$@ԕ?WH0ESkĥn` 5 ۮbXK8xnxwO@PB-$M'%5;S^)^gW*a=O=xi9_.eIPz+RYsIinTj[:PZsu;ĝ0 ITKUFEk2 . S㙂2^:-~q 1N?( Dvq[kKYfRPRbVzL"\692K~?ҲerϪV¡ˬ:IYxb/ yX-3fWǤrrmG\\IU w3vSo!chS%[1Or~8NU>+[ΦDEduz-Om-zg;WݵyLgsȒIHgm"JK2JA0?/@pM|M$ͧ=ϵ ]RFE~q DQĔֶ nx&*@H'o^VX~L:!m]Qz!LQnC_Y5WSg;Y7,o6 | V:d+1Jslpm2ÈT* zݠwN#%= "`xy|hy@.WReG`U=|!/⅛`!ZE-7R]6q<d^2&y 7 Aعv?a7F? q1A j쌝}ך聚r=߼GF_);yy_<.߼V|dlDp?J:ot t")ӘNhz.XA `ſbM4G)!ȅh[\nWdKvAaʒ'Z~9sg%_xu{|IC~1]Un4:3ob)_]) ^aմŸepzyLr +5GrM-v!IGZb؆zy!z@ Ҡ-֤  ي(ؤ$I9_$R~H0+7<^<']yZ󆴼髡/Ʃo@Jl_4e*V-U-+#ҀrKPSSZΊ@ݩt\4(YR( F- ?Kd}ƙZ* q-@<=0UK>-8|Z\n˴ n3nXNjy:/zmrU t*unspPrY*d0MRi 6>VEW3l~A7eX@ԍ"9LO endstream endobj 83 0 obj << /Length 705 /Filter /FlateDecode >> stream xuTKs0+|g*EO?$ 4L0jb c뻲$zӷ"*!xt=]݉*p<-IpYJf9{ ,`D =x<29O)O(kMA31K]FG"jeWad?1@OD)|>-'#}33uHx=L}LONޘ^Gfض+*/  XNsר!`^gZeH&ceQ <~7VG;!өxtP]>g1OEzwݛyS?!+nM{zDF0D@qӜr⏛ Y~uSs,CrC}dXUu[5?ulz7^n,ΡMdp=H؟0l(+&Sy o"k4o}>J(?W-P@$i䞣> stream xڍT[54RE{(5@@HB:(#{"R)TJ&tz[Y+yffϜ9 'c%T  *zzZB $" praX8? )!PAC!k*{ C"p@H\ZHB@Rhi*h#P 僆99cm+E! u^#aPubQ@ #D;`XgE{B)!nп p0̟1AC8\x hc-] 9!A;w!d= ANG 0Pzco A^Cd92*M?MG$ѫr,USWLgG8JMJق[J<24hz_/t^eʝ)l+{DUNGE;|ɍ`kO:Ƙvg4ΗerՎ_塓e1ͯ(wYPr*jE.g313{6i&l! 1+hN%"B K0ᑟe~{2׌{e ":wv?ٮ}}Fuґn8ܷMGHiK͎8z(/=epJ_ ![qDHu]b`3t0LFpyzoLho| m2[_*y4u>W[|zESOoP'S,@Uԋ;Uyl:[Ї_ 脀vlLF2,|<骜w ߑJ7ߔ0ۓ& pE]#-ˎU+Skå'ǕtEhBӌ+%,[W5/ UևeNUp\1$NPCDOom9I5h@d6?\Wq ;Ns&VpU(=DT-+mQ\!ǐ ڤkM` yo &iUGYXb'jw ? abTZe16WpK֘2RJkUMxh (DCRP 5aU!D~tlܫϭq!_DUxj/.oƣ+(6'8_}nR;L `ȝYalHR3[DJ7k.\[4/apS)RQˇNj"~#(ۤ^y\g^^)l҅o2l+ KQ Gih?Wg_ssGSixvEH{Qm|ե N3qO kKI3 b9Px.偝}^0>X*2Hύ1Z >t5Fŷ):1amI1CjΓ\ C4 )9ˊR1HKE$8KMQyoױLհ$׹Ǝ_muE`Kʳ6}ɭ%(V$ [/k4ˠ3j'e*?|f!^oIic xӤHki.GvR$}߉w԰qa,lD=npwy_gGLӡ%NBzӇ51RtU?pEX[ƞzA+˦V'=`lxJ9popc<5O?܇],Ii}רCC-qPJ0Ԇ+%eȞָ/+ 4yêM_% 5UN.F}s*ҿc0m=vw۹TTpv$wxn {__;IHݥ&RYlh;[vϿg ݭ`'/ϸ J#Ji61 r]{vFR?z8#<Կdi[/gn},oЏL{JՌ{62XyMQ&Β݌d'skS2Ǽw=G~d"H@E>[>aP7HN#Ruh<[z*e*hX8Ws H7M->,1ZE9)fVnl6'm6ܽ[j#Cʐ eV(@  Ky6W,r:sW jk: YY\|QhKab@iH;ׇ&CyqmрJI&}g( )ZܵNaȷ?$cM f]g㓎)8佥t@N8=5iR^wYFTvds#čgx=b3ΥD-w7>?j.&[o *vǧ{3Ww.#*o,n'h@t ]ºx' y@E_TDza皂#q +\Aq6)Ձ%>!m򄧉,O`UQENʛIJcT]I8`u-%LI:QUc{>\,9͈3`P4%;r}$yƗ'O|%)%((Õae1ȷwhjv_3HɰՠH< c)XTɟ;naO\{Pi.Rw HM@P;byȵ` !ang*xGM7D+Ѱ9jsb({@/1lߨ:%`9K|ZjXu1g^&;1JPy>crTtzL73u)KKHfUB1'#^O\Cdbq|J^u I ąj+Lp3t,ހ=+pd鞕L >$.acEKOHu)CTy;QQf_1 ,.{9[ݱ)D5x-I3žx[I ,5mM/ ]Vy I ^qn#kS/4|%^n4/TO|b!g_:Q=I: DWRtDYPT7'0/bDageȎs|.-N' ~s/a kF)7.~^uibsaW.#Hop\!`-_;rF |b+jm`E SXqĝ~x!8=B;cuHgSmǡw`^cn܃gq ?NDx]HkD*2.|gFEF:0iPfRc/ā_!;'|D4KO6]ɭrzb:cc Q`L뗫 γaAj+퍨͇UFZ除%I:s+W:톑!!V^21?V/'(UkF<_Z{[t]9u0' GR?uAzl:K_ r+S/ =^?/9H꽜8NB=ot)fS.+UE  {]|Rg[,r@@O S3"H20{sO"'X÷DXln;Ow nB~wL<(Qhh2*䔸9*O7cZu]qd/EnH 4u9Ѱ6Jހ7a؂ c]o)bLN5>^~a7R370x֖ze{:z24P<&|+O~ ء?abUwO τ<N96$R(3_jhp,*__%w*h+KQVc OSs>4Ϭ6H؋s Ȇ P:GƋX0̭ϕnZʍ>;z=ZrXh5m6%V x]2U°yG^ߎ,6[IK츬7]DSLb6"jJ71E﷞hu}|PQ:@i^MMU+Y}\z$.gqEZA,9 2a;3­cm͏h>VWEL1Kjʧ^W:5iqWFKs#I{N3%,%^S8%nUlO'G䖔VF*&h41bgt"AT-ߌGËkxbr׏8uL endstream endobj 102 0 obj << /Length1 1394 /Length2 6064 /Length3 0 /Length 7012 /Filter /FlateDecode >> stream xڍuT6(SZa0$[c!lN ) QNnD?=9纾cg畷FZA /O@PSS$1пPDH/C,P9AB@$HLR@(( 7*]@M>E"Qp[G w0 ؎=P C1*! `%]]]h>$V zP4\vY4ѿH+bpƦ8#( ;P_UEkO?? p#l6p{(P[Y?`{4vVX@ey] C P 9"`ݝ>C ][6p5 p'g g EńEP' +t`׀zm'bPPoph#TǺ6mn@3,@@Mbw Q Rg !MI uB#HT]u`Jy:Wޥ>;?y- 1JOgO()[ڵh)8Ȝ=\az.IyՖwܯq,#oqr%P8: dDֶ^\.VS jjn,N׸K/xs^Som$rH}?k!:`yXV*t ֵl{?5]` T70A\"T O+ʇw5sswY `q jҦԕ7DH-@<)+KmoshH E8Y`e>?G%eCG(s>PpBn׫2;$ qRlUӭ.jvt_kj/ϺKrN}b T^uq0hbN.[ ++F6swnU{c7FmHo08XڟT0{"DPxol6ex)0{2Dޱ &֫<9F ܿX&dʏgOy.3[z΀<݄b+>=Qtdj,SχGe\KJz4fl t%PEH 7 }"+5o&+^ۡPMj6Kγ<}tSӾ^ T-l {.9I->BA56Hngzo.vEb3,%l\.AA>-ƱN[~t-Bnu-mPVZ |S&^ڰ(إ&ۈhqc+IK㣚Ty"&MTJ+:ԴqS]VwuV&:T) wq ſߤ`ix#Yo;t%,5xL0X@BI X!*x!d& ajgE- 9&c|\EwT~5+^g_Eź8-Y֨J>O($JqhvdWoO'XRjcXs`g*LnKOj:>wUP6x͍wîyL Mۈ5̯L;ivr!'36$sWi}fXVo7o[tQB/5dEm3K]p5CƆb?dhAK(}pUpL۾|܂Qn☲z){~!Y9cbvXW3|8!1FG;FAkrz흭pn=hH9x".QETC^ˈwyz*0-#l')m0%X[xy A6k1Uf&-Ǥ)XKMtre'Hщ+;=%{K{BXD@6Q|[qv-wτY|>xaօ#2^{guUH!⣻ 8f'Ibz~/ Ro?Q(kBy\v*MeNQJ^"K#sEADu}B#^V? tM*Z@3cj"u[x@4_-ePt4873x:T喇2h^@#[` X5|\Kqy{][7܆@Sm$LJI$wvB#P~zJ<Tz P2,C^ u|14Yb?Vx\>^jHE#2NސL¤,.o!v㽾`{'JO1F|$KZ}g_&_e\*A;9őĪdlZN!^^>შX6i䒩ͮ3Tgvyr"f/KЄh {)=jܛW~.ӻ^q 4M>hQ }3A9 P= +y.p3G)&;؞^mDiʣ_>euuO e#)P3: 7n?mLK0] >@= 3ŹEzZyqbgo_/9pզvm}h0+i epd87S^C{ވ7V'MĨ hiWu|' e.R5jE66R] JӉy̍r<m %/w gx[lIQcsKŠdDUfs^؝Nfn)s+O'A>ewH UӓtoLËѪu$Vi_ПbiJ}44 q0>`%.mpfhP{μ@ NwGf> %7(p§Yd)W-dd1 PzUWғ+ *EIm^NCP! >~E-5UߢUSwּO7Epamm3Z@c5u3B;M%ĭ[W2m7B6ƍxGC6X+ i*J]v <=8~#Ք zN|jؼ'}6ET+{ɓ_UD[A8,`G`YFQ0!A>EkN{O&DN;C#$tt*J/B ;L7~PGKfժ*.ߨ=L!ЛYnahrY5m+۲/;')/y˗B2܌:.{Xrk~Yp/a-1 ^jaEoC*01k@ +M>Y;%/_C(_pXM;o^!>]iZ1K ǹbȮ2 ד(hxfW w\Q]$qf&_ڊo.n+┯j-eW"{(ƍ,Ӡ ]q_AD*/%= NrL^2T0FՉnn+(1zӼh4/w0{61$n]{T~ࢎeUq@Ą9lk'485܇gd5[].kN)PQ&dZg`׬iҤy%u!ŝBD˫wL+UA?P5 yEwDڟ^i_힪V{ActE']3eE;\nU!aAU>O`Sjr$}! 4~BjQ)K$v߹\p1m^Wٵ$TKAk&:WNj;\gj_!gqW|b}M3ÃkGK5¬F<=[d:.[m83b~|y\j-!ݿ*VCH\N]xL"F9#s;Z'FkSr$$4zn:UtO(LY> *E[`߇Ț;wڻzdXSd_dre/39jۻ/qfNk?<(NZ$*ifS1RsmIX{.8 O\'͙Ipu\\%npШ.ei?/s<->Mt~R&.U;[d:/h}DЫvT+v{-CEoHcPTt͕K,TW'T4Pw  Vs1'!cC{Σ[$%=_ @ٛi6}T~Iםᚘ)@z824wQ5,mF>,X!7󠀈 Ii'k#^9~&U#9x㞭mH2^s7o&cV;I2 52SRC&JH,7l Du,5bs$%!%fJ&$}\Fy^(, endstream endobj 104 0 obj << /Length1 1379 /Length2 5903 /Length3 0 /Length 6850 /Filter /FlateDecode >> stream xڍxTSۺ5"wkҥޛH !@HRIo)Qt Ҥ+"Ͻ㽑1o~m9#FN(G e ňo;1 G!e c650 G!:^HI1 Po S;E:($M̭;`uA )ew'F;" p()`0>>>"`wY_ǸLh7 kdg4bn =@hl Vj =ȿz6+ݟ_`Fj`|1B0@`o0v~h( ̇x=0h4kF_i۬tREC4PvD {#`p5G{A`&ۜPFRR@}!. y@;3x<0 8 !@4(?\@'8p:ÑΎ5Ca >2 DEt,5T/  ,&@ $@JJ#V CdjO|g.P߿~(`@gWݑ?,s0X裰Z@7tNp/jcX5(#Gk}NFp /e77 5B0( |XAܰw4]PYW A9$ #ƞ5v%aUMf3`(O_ JD 7e^4 /̢ r#:딙}7G VVb%0{UnrVG]Pp+g(y\q:dcVr|TˇR=[>_u̘x=G\a{ T6^fW g*qm߿;XHV&_#$e69WGET"==gAjt@{WjMoP=G,9fDIZRb\sp:g~Gӱ~OϬp}`8wN٦#?Z~+A핲"ę7EVFzWbb7kZ+PZ z)F]/v酥;IzQAVk4wLO{z&.gl_Jkƃ綀Ғ>o *\6ΐwtPd,Gs~ 6h[A^[i84}3[ _M(c-岺|RUxSF=}In@ׯA`Mr^zױ/~53a&ERfMcbyj0Mw[~bOC\Zn;{Uߚӳ'M{ϗ3M+ ҍwQ;[Fv Y> ԥNCZn|3pIlCF ݱQ4COֵޯm [ϳq*eiGRY6My:<#4b^xҰ!0!M6G/dBk*Hǘm6H"L~ƥQᭆ@SdoDh_?>>DMQ;Q>;tr`!-U=[^|6L&Zdnm7CyUJ怔wF(Gpf IdzY ?x16=}f7'nȖRJ4im͎?l/LzZiaa.ӔP.q;4XY(KREreNTX?pV`T88( zr`H`:CK6U<ZZo0PIjPمr0:jPLYm16 ȶ=V"=8r"R3]($F{ؗiI2p{x|)yJnv<e]V: Օ;!{ha[>_SU;,ćc>cT2~hVٟo:oo8Vnv3 6epIZfGO>%S_˓xq8f:6GOm|̯ ~%9׈]9+5,yOr'N+0CNh­X6Y<ИԐְKbr83n'6MUwhlj#A_Wf4l(ˣLM\f, /M ^ޜh)+f!ޥ4;rHqdI>'‚|&P2}˸4:V/+0]%gwM#VRnόzFƨ]c-Lm~tXyp5(*|FZN ~L,=_(F ZX +q[b`;K'9'z?qY6VZ(»bK~eLJ6Y~|x썳0cqmdoE.a%gF^/C <~Tr5?=u-l!D0z.}W;.xY0uq{gºs*='+ P)K1*!#VR gh6뮱o ֠u}{ DfczI,byyNJrp:$W?3~g fxyڟ6LHN Oc}#KYNHȭM""f$ПR*{ KniVLE=m?`_S[16Yn K*Zpi )YL9 e޷ڵ0ؑ-+0 I жnO,*8 Z.Y4/=~̺tfÌYGeoVҒ ;5xM,N޻/4Q98IXD&cw]NƾHle%ml  :{( tT :C9< EȎF93P(c+%qab&3 yݘu8jT_i<,^fLӭfqPF.U"j;/z=Y'y*Y9UT\DU4 FЬizu'e6_y;| hO{9dw\$u更ƻ4F ua 5`F:+ED|bLeBZ:z x`=eXi AGfsBUk ]`\͢ᢵXraqqޫ?Z /j)U-3F>`G>I5ZN+q| Y.Ii|3ʔ)=j㷄?uxtތ5>+@wu*sy&HHB̝?dvZ{Vtwoց{1Ø-Wȃ^m=mT Vx>3lo< Ӈ\]'%q?x%S ~K/SNICu ׫ J&hC4+&@lM^F?~ )\{l"֋mM ykTW6 p|̌muFj* =j~nٮ;)X1eVVe^QYk '!}$0CQyHKٓUk-VGPjZ`@Od6#.Zj GLG~[i5zTNN 5u\4ڴkF/Onlݸ3wz6Z}dr ] ՟^WK?&k(GC͞"՚1eVԉ"Frf/txS'bܼJh|Q𓯍XuTz`GډgV/D6__wr6_0Ģ^h#zi:^iٲ-G&o`z"ɐDi4BĪHa|rC[cKV6D`jn8 sSu)Pe(fyVRTщ;bUk)].9msKz('%8EI-f/^t'ZAuC ,8~ۣ8<(ƛ_(hKYFXg`AyPdqdIi(\e֎j8s^9ō/}J8S3N4H-rS! َbE{lg![bL+aA2Ƣ}% А|WCSuM(]6lcKo\Vݙ<ħǰTٌG30T*O[!Ŕ6{Gcju\=ҷРJtQeUPL5c~VFr5~<4K\08dC;R`ME?r]z;P+PX {PGCr}#jKֻ q܅']L-R%0;/xcFTpJmDOĨc9tc&F86'9!ypADr43#{7 }s&*H hY)זWнRs!z7lwIU:LJYj,\!}0,OO}2K`9 ˩؜5~ /;#dLuϞ湙gjSGWZ>GVU)t _Er|laY#=6@vȕŽo xOղ4]&!4kY.qus&owng> %('陈>nmQ兗 bM^ęs:t#^&"ֲ3֙" \OILތ8!kEuFl]ѩ C-Ħ(Q4¡:AŲSL b- CשƖmO N&0&i9vUY\NߕߓJfj<=}+,^шMU|Jj F4l=7kkL$mV7cb`vij齁/oEHm9/Ǿgۛx j΂" I.K3O>*<^7oiᷓj:$T~IYD ^e~:;tLXqS:6@ \$1\{`a1zz N I]w5B|RIaJq4TC-vt4HpX.Z" V}K!^P0$6B6!;ED mi klE endstream endobj 106 0 obj << /Length1 1965 /Length2 7150 /Length3 0 /Length 8264 /Filter /FlateDecode >> stream xڍwuXm6H#R .tt7RRҡ JHtK >7\s3s];`3*0(O3zià0n'LJ̬ ;àJvp $D%||B@mo/;Gd ? r`Gg(.Vu / `_vvB . aΎNp  #qԡ@<00{=} Ψ ع!sOٹ9C"vg<mrRq@' {B`=g t"LWt= o~WGOKỲ_P u<=q3D"a@ ?)CVG`EL#-*"1-*D*zjH~|Zɧ}|:ɧC"$-B2"!-BVk|&`Gj "ع#rR syΞ@o[;2!ait!`]ߏR$LA?!?7[yg{KYyމ@&EFE*msV#H>wrqür C@N[;;w"6;DD6VbȟuGvȀ[*ad.(]I vHB=^حhdN؝SȢoHw;O0__*A@0N_6gM ;A.a;Gs ?sp/g[Z/ӝH%%h^뎜y҂ EinSD|Пx~Br(nD->k_jL΢s3<dtaxP L 3'0"Ɖ_z#m SyzقGX2>V\YQ:;__M1N=0h^FLWO.ڃ:%\&i G?g遯9WPTCXT JK{ it^Yn3V}`=Nx:x]_~cd,?) PЎyr|4uC%uⶠх](jXlch>QW}ɘ}3csWxBs2 i}ƓŽϫʎFĒe-J_č<tfLj\R2V\.dO4-Nzn"[5k !JV MŘگz~uB` @gI5ٰk)ݷx)<$[ &wъoS?-Lj|U@QЋc6T ΁Nk{ҷ>:8^Z|*Ve~#IwUWyH30٣*)(ZFj/˅{WhZW 6SZDqEQo#=Fj׌G:.sW~}SoQ,O :5'z~sDVD<1]nypuїh ƫ/22=>4x[7 *=(yz41yc`'ƎTdȺ t j73y\Bᥳ!YJɠ>¯$ԬU#gQ~/ge%-q~.N$u[4Ca߱nAg^T .f|7W=4&q'jpЂȮK92o]oFKIOτLa-)&Ne|@}` _f/:,^d1Zx_$KۻN]s?NU7 dҽjal"[U/EaNj%#vQh1OVdܝ-_6G<ط--+O=ի7C(=0}b.S+Qԣ<棼珳HÇcW.!: u]w-3λGE!vjҋXn L!7b}Kt&n*z# F O DDf=M0?F!m}#6+7d )3"u0g>ZOCLiUJGUk6GsgכB@c.P\q]q +S5_#cGw|߂ cfKXuzҚAu~bZ#\9bI\".(ޙ&p PVY' QִyZedc&KeD. rgZޠ&k+֤Y|,߽I9kg(CɊ1}7rgp8 |I977tp/N7VlŸaLM{߾.qvK =- ^Ȅ=P9ݵ$kH[{˷4$vW8YQz{Hek^i\,;w^*Yјo$<>JaS^ݣVN+gT$(Uĩq[M/#OZ^WiyrX@4pRZI)?oXiKvˤO6tXBr} %s䤂|@W8u Wd.)FX`ģ,&6YDۏ ΍Y7Κ%Ig2WSDa>9b}"ӊJbkmӟ{/=Mū8kعr9{EkG$S'L[oz(ӭeUJ˂e, Փ\EQI`0(kgsZ/ |s#K|YNyN_Elq~RwM!UbJNj'rc]:S)& _])z\'@ Sf ml!S4nKr ;xfu?U{D_ sX|9.$5։@82jPhx)+ߟhǚ!z/9X_5mgf\͗~N"- gg#(84D׹Q=. t}B%cT+z.£7Z:\&=/2{/9::D"i2oo{9M?(0^rpcK$]x c^;nv 1TJYi z>ǠRT wS? srMRs[up iPi#i'd#M:C뾺 q[Uݗ@a&JKoFF(nJ6}!6UwĦ_N_=h!Dgwԍzu1T% ,%U*'5E'4{''OѪͼ\{hoJIwTp!Ęby"䳮?ClzvS}&75)do I=׺R"h< -/ANmZx&*"w2͢;̶DcC7Vߴ>K)llHK6kdw2Wҽ->z<|j^h }Ad"8e 4E+f9`c ף},7'k`W/1*C ;QJ E( XjZEw TNV/l Չ}pm q$YPl ^D&Z+/t]J|ypλ7 NaӐw';+؇)r#]x=ie,~ No٧'EFK>%\H`d|AV;u{S}b)?׏ʬ{%S] &E ]t.;:^{'/Plotw#V4<'#9NOu&I3?EPpFcRtY8ލWwڙKxѳ Jia^%%v>kMAkm_,HLJ3L!߼KQi/ŪiSƖvН$1lb f-=9_ D33> r0㯘WWMF/KEQ:(C#Kz4oc?*/]v]MxMổ? A%3*kmnZ|ekH+fv?/d {SjL^{ѵ^+᪃>i (eK y {UK7) $l? J>"#Mu4V^p>~ܞxcͶ?ޓ6J [ sK"/AC#؛ӖC\r~OOsmOH-:-.Brl%ԽPW#Km-'޲fĘ-cW;7  w V7F6OΠ>mCC@ 84o@o4b~DP_ee<4jڟSnT0QkS&YhvWTȨb&›:fŷ7o*C:5ݎWꕕiN {Zu'A%k B'e܌r9vdM?çu (:X?ㅨһD8/\fIO>pGTۢ-'hl\%Rt^&v3oIyiAcS'0D0땥A/])g&Wz-'Oq r{畎q@0kb$Ψx{`IԀLF,Q7q0Ŭw)Yt]{zߗ.|xl8CQbr'0Qb);ه%9r=_7ؤ ٙ"짱|~J蠎͋E9<8yr(p/%wL, JKu+Ɨ%aWSJ`O`HruwEDHGdYJK7TmS"\gM Xۿ? oPfx6iZGg]O%B-1R~\~iWJ:-T.Mp"AL/πC%oO'@W4,6K"ҕ&Z*.j8OXz'^V Sܜ$h޳6ϦnސBQRҲ1))޿bڤ5j^d't&n{@B@CדNSlגh\d/Q }:uܙa,"?*~Tz# &M80w6 o]GˣjHK~&v&@~;Cq#DփP> &½1d`8*SJ*X>RepⶩѺeU2*䚳sf.n=vuj*WEW󑋇KR[b#൯|T ߝӲ'nydlBizxܟ4'g$ J/TD&hȔ؆"hv< VZ+G\lm>kUkjPh%bHe\}';նx/٤DVJ2voN6V0Dt haSa5_h4ShJ;rl{=B|V`ȫTLHrqvFLkKn 狚E,Yo)r-Fg^; iI#K&[08Yz?_L0seֵ9 |h<LG7ZeRqPmDr맯KYNjy>xX 12U#N"-E= .pAlTcxXeEDi:s]j(hz]&祅g nIҼ'4-ʱ= _ndeoP"[GBN@w]F}4>YjFp4کZ}`k, >5ƺuI,U"0.Lbp8%&or,s|/bo6NN endstream endobj 108 0 obj << /Length1 2833 /Length2 22972 /Length3 0 /Length 24542 /Filter /FlateDecode >> stream xڴuX=LtCw79t3twtHJK ]R҈!!=G^\0;^ϳRMU$ fq^+k;{9X5@6N6nZZ)w9Y m`H*$C rCV _2l j.`V slc bH؂be]w$@`lPdSfxCvgb 5e44rjlš.EJSK[ -%5~9C۰T } ӕe$d@v7:3jTkwl`WAvvooo6O0 ?l<.ȧ;0V9)v g$Y9 RB vAp_ml=}dn 9;[B`O?6/Ȋ_A)Ow=rOSt?w/m{ٖ.v`UA{3;l* 2Z!̪QǙ 'w= ׂ~^PRg+)''kIAt?sڭ휭+oʮl Rh p@n-vLo3"C+hg |{{`wOPߎF(@>%2ÂOugk&v0sP!`FaWqCs?d=U̝@ +ƙ;9WD~sePqqw2wJli/aeWCf_ٔLڿ#dn!ߏ.+|tpyx?! `QVWaf0gK+;g'/2<< d@>L  Iz.(w./ `R?]qe ]A\v?]tA+A*?AkA7]p \t ?E?HDAH?2 #˿@n:- +b4tq ٿ-ܿ-NNH9 ? wWNV%At9!, ; m}]mAE@lvAO Dg Dǿ 2$rC $ܐŸqCC^QB>+/%c7OJxw0x?v DֿDB45*HtV_TO1n%wPh $V嵼qPF;=<獎WVAA$2:laoC{ K+vv9^.3;{/p}1{Hgz/w +Lf%Q}8{ be<'I}ϴnjiїQGFm5ZZiP~8|Mu7\C+H ZIt.\gpʐWԻzͰ-O_Q[ 79xKwB)06Rۇ~}cz:tG@PLz+rX:Ep]I߄?\H-wdTGh¸lW̛;Qgv D'c}o,q$yPBEZJ_7[;^W3'J'55RIVk2ҝ23Ի-3ICw]Mޡ]ɓBX_Z 6&f`*65ƗMּT.ϱ4q\ZhQ6sʱMmzG$ Uk{횏ky4J('JZ%%Q;xӥ3f.4P.9Mw0C xuNPԊ>P*ǩt]MTTz Vx÷J~#,]*FGwJɜ"%7?wii>@|[k0Qm=ҍ B~EucSEZ`JnE6c[:yhh9hQ<:Ƕ&TͻqDKouvEk %NQmm{LL[+œ9E4{KC(f\s&H˜%CXEP훐~n+if}ǻ&NNoGi*;ӈf¦xm9Sn~E{5mxSnJ;nR(} _-erH%SQ@fU5Jj~ķXc*6sDlj^׺A$U{ @m%lr mVL殽O3RpG[ X9$omCܛHF}ۙq܀4GimqD*;rhf4" iTmŹ,*q| *h$ q.P#sI'Ǫ&qw_>0tcd2Gpe0EҚѝy3vMiUE3 |H^=80lT⦆[O|ԯi+4hl/@ይO!ثmFreDL4_Ӭ{;䀽j߸}=95t8v2 s>ȪX{}qI`o R>| gF+::Rq 췣^3BdDT@b3dYgRllģڎV8<#}fͨ0eoب!qyR3딺SϪdk!HHjdyQeUv-v&0(-AR;80U;XSj4IzݟXfBnhGPv&YZ+BޙԷjƕ=Шfa9Yg5RsŐO!R֑dϟbMʼnY~ogZQε݈|axXFxNowF$j͸M((,~U׾s+HJ|Q*0t"BLO5zTJE+VzЩzg <'6QUef'hs*p4 PN&@ |CY l_iPdP{f]{wTkPœhMIqV8|_q5ļq /8+UØ=<(S< SUY5oCՆ&UHê:<{`x7 Bdq&]snzOo;J_Wʅ9o-P+E҅MEo{%NˬN[rї06j']\ ?v\tyv[D"U`&@3@!Rlƌş9s, 8J#N!TwYv,owO?2ׁM oeBR#DՍ5ƣ9;Iˏ{ԏ)2J~ԙlڍ&zCZ~Nv&aMJ?>zFoTY9Qom ;/< /ze BPe-wckꆪS0R>?/kW1kBDݨh3 \>&&L&@kgw Hc&¦Z@T\ JU -cT6Zk)CKꪥg "VS2BXiDWaMmۋp ^$_K3Q,T +] D,/`u FTJu9Ha`S߰gx{=!]SkBU;3ɟ#Uk:}30>m{R 0IӯTu7gbMʛ(ڵ#Yҫ0׋6Ƃbp|dlvlw xMa_!*JTfF$+aLS&3j8AMS݌;b Qч|_gnUapi#$% xt!< Oy[j Og eRЂOؘ.?m&Dc$lИxW)#bB+ڛq.9EF8k^8\U2DLrϷʴk?L=cشj~%p}sXIc潈"2MǓx"7fpHiŜct2O|iGG.L#'A`v|dIڇi+I]F]G K3i\%"*tɉ1_=gѢiӣ愷Qn>mv/붾ۆ² 1,X/Dj օD ^ E0Z Fi7 /d}"B3e>uw\!6Y5$-F<l: Ml)2|­)'^~>@DxuV"L Iu%g#ѦcubG ·lܔ{1DI~0,o /S*Fw tx}l`԰.ԩWo`OJ}j$&4]w`0*Gtd^V+<"FynSXbFӽI\WVQdt)~K FHh뭒*kAW S!oD?eM9(ũdȰ^)bp!0|\g h)UucRan]"XvSuꔈҭg'vD-ݐX%cM@SLj́ C}]|Gq;O_EvEF]Q"\xpgBO\zMkO"Rc)`ĻiTnҎ)E}, ]ŝ@=. MmlⱭO|V:|hnfuysq'C%]dGI,dIWuaEm[, X>KwE箺P uu&}a41UCsWuh(kt 1oV*fj %[q*;^<7sfGͭ'8տ}z108@;oĜF_ +^b۰d8;PP~D\.4m#1Ȩ@Z>ߏoB@R ]΅Y"+9pR0|<&-CgY]3!V䵵[O7I#"MX,w[S->vf "OiξYLTk4VbXI煲 -\7ozSa9|1._lLvWk#G|.ID7+F N#[ƎJ Jt`n= cא~G>D6ٴu,)ϥG7cۏu6a !kz.?msRx牒9~Va;#FA\%]9z59Ejz(C^rIb R4ϫ&^xgH{a{悴!ʰ9@}w^6l۬p>$*|NN{02g}.7oI ` ;Fs=N]h' @9 &b/|}ءi: L}1z3H74rԏЀY0rdҾ.c9?KN1ĥCRy^,9>nzEtbkP-6͕c@aflL&ѳ}Zh<|_FTyV/Nwz+jA''Hye&h*9o x %ZNi^<_>f c|$ņk-)C夒4awrsүgٮʴ޳S'f `&ACiRԤbPʫcO[}Lnus-B 29 ~z@#99s% i3O{s:+{G-&єwQqoČS)D6ʊͨ7 _grtnyݘTnB(2Aլ9 ˀUS!yCeZX]5#&Ȝk'Iɵ[plr 3^g [%,Gs+覤i?PiEIlmpȈɨ(ɗ'ifldLJxvXqfbD0'ξ%"{=Hf(^?şґᒆVQ/q(& jGJCCx2~Xj,ثOT辭,Nی[Jn}t-"DZ<. ׸IBIhnߌ,.J_@-} 4W4޵bSNJ2x.aR7emK0#mD'BDX5Fk Eŋ2"ҋ5wܚ .X:@CŠ! ;`i*z&"dHxwB)Q5y/8@wP!+xITX =*.)ȵRX#v&I6Eq@o(Ε@KSr_ٻn`ng,!S?pbn>@ғ`rᘧo^˔q |gp5D7TjN8@/}8:U94eGO' V_И Ce+ ڴ ZJӪ[~}jRTV؝%4V{yA[K A#qrj覯dI)e,g65LWp=NJ^ 0jPƮ=Z_f>jҼH@9x7.0 uz[F;%xQ|۩fmZ\Ǻ јU7^PF%%]L(\A#3v1YRCtTk Fj ՞FȰKY|3;s1M2ӵo1V 3WϮ̫7YIyp#Z }VEBUZϮ&JgݟX}bp<]Tdw_"n/ң 4iFdJ_"=[)WPFxqB|J J'90,8HԴ|>zYWh-{?T;@:aZr$ZQ?UY'0ZfTO͊?MEJ'ưuj #7a>M.O;'ެ}]] JŠM%X&n?Z28&[CGlڕMs`.ZIж#maL.mgND1'*߀ ƊDrdZK mabܫ_XDp?{\I0Doa?EEU⨱G1\ngcb,(%<;ؗ$Fk%?9G7.f3=G-BaP Ӈa<B/eod yWHG7φYٳ=kT8&,pL\V]0>zS|]ȮnD?RK9葯5MevBճ= 9EBXn+DМޏ/,ʇmyxxGL(^M&[5^9(Ѕf2ͥEV0=ٱCn^T˕7;IqP1^x%Xټ "Z=aU(奌?4>kQF{\,8A 1-`U/jb_GsɆ1fOh hKh6,d4mQk.N6P[""fbkuBACI]χ?l,Jk ހ2MsLGLs^a!գ4rQ77KiL*GW~m̄jf)x.QsX:C^Ɯ-3WgJC;]ghvꃻ`t1TF}v(hд=--'Gt!S3R6THx8C$|V8JQD,nхYcsYOԸPLy1솘ۣ<`E c 5e/8Vӡv|x8UBŞN%=݁p\"Ks1B& GM销dK F-SGв]! 4j{-D*xi&k3dJ0LìK:Mpp &`&-)5[2X+DzlkpV yTڵܫ-&%|3zW.ݫ ahS uoLNdCP1}x:vl>x!Bn7ǸkjP\kFKP퉡Ko0*ư57QE1:7`!!6aKA)#$6E)qNG$FN@+ |Ȯ j Lesj,k9y1JzYO3Ke0DX5Hߚhc\n0^G1$qkqςwp)$ ÄKJ~}<ͷZny~Ui%0Tom╺BЇ̘yb:TvK3t ^WX3]NLTs?|NOd/$k𧛀l4\a^ 1(QEdZ)CW'Uӄ_48#?L1~Ǚ VP ɜ]z7z4xɷ_}֟6ɣ<7:>y;;K "j ]|+ؙWxL&n88óY`ܤG&g\'%q;eN _N;sfj'4tKMoHC0G>)̶-#^ xFk/:#^5b֔ldwD;7֚)d2RL?UѸ={"VhMqMSu,5Ί=r.Ab8Y9(UIMӊؽ~<0.//h-c~a'oq˾ u"}]H;EIo _$_7VDNa?Z.ܮ.w<Θ XCOS~xy(zKF #lzr7ǘI U<79!u^@~{(Vmb)K D1 } kn?}xc.VNpK*ۢSYEްD0d5~NekӲ"g{eGh}\H/nS{@s=yh13vb ϕYu8'շNZuKe2d~Cvwq֯(.Ē3Nqt(/2N ZQsE_rx#LrGz 4O*mn䊗tW@+;KaZă[rB2Y= e!%os}(B\MT"!MŕPsq)p|>kr$L%rkؘ4?4c%/rGt `KNKOvE4[#V-'\caфϜ ! `MYl{ݎ.L%Yl>U|Xw⓮bpxx Ko"!qh*4fg8DvJΨ*YJVxfYvJJπyڲ*@hCC@`)+I0$Mh/^t ?e"` 'e5엒灸r%9\G72B+ Vjqwr2d_bאMm:ʣ%S붬VVeL'XN݊VQ]c/٬ 8/z $ XSPֱM'2S <,.`@­Aϑ_-`WQ(Nf9Dz m~ڪ.FӀ_(hel; N&lE ,M;Y6O$n3X2SJEKW>0C{bG[Ҕ<,8k6&̐R熇 KyN8 ~~D((Tfa}wT>k%ܕp*!OeXYuTORP,RcN7$5#&mc}w6nmϗ;EuS9&'GvPrKPGBߧ8IȂVK%j /chupͱc9bk+zL|jm Nˑ۠L~k(>&#>O8jQ%.XRe-sx-^u-&`4uQIe_u쌏IG M:gPR+=tݝNBU`]@קIkF9AOrkSi"(R*N= aD4єTߎ[REN<#-IQc'ujnb /Ky60NH!VNQإl-(ʨ4F;R~<zbWHJrq$|ґ}}^ (WkXGp}aPOt2oz {VhF .btvM17VpCU{K|s )w&҃ܦՋMf2-g2ov,RX5mL^@~h(9jY'=ΩZ%G*5ĒCxbi uqDܪ7Dr!w<ʜh^9sUF?_r+ 2c)~\󆶒ƘɱXE\e~cXnkz䭄n Z2Lz_lh\ۣ5Ly?&LᗜUT D#?D Ӹ_p@9}cc{K(FN:^aw!;Ʌcݎ*Q<Û3DMו֋m9Q]pkjY=p:сQ,-mt9HFnh# 9'ykTQPM"޾Fe5g;SΔϺ;]cTmAwJ̲}$Gr!߶wMTۻgz:-pJ]vBW {dBTk|I_  5CkiSqWyC K\S|p nM3ydž:>ym<,GgM=CoRblJ׌lJON>F-SƤ|5wS@N#|C*y7ҢmғFWI{P= cZcZ_ 1EGˉI$G1d:L%!zڧ CeGyNC&j`;;Xt-[!rwkZ.T cY(EUPm\r^gb(6r+6S6GP .ew2`Ȣo? fAqI<E?Qq֙iTD-_TҺIRݵl'.UÆSw|k|!gWO>c܀_hێ.)$w 6Qs2%kXniBt6@hJ_i٬)KJ=a-~¸7qMEp[ƭq BY<&zq0i=9~Tl# < <},v̊8-{aB*9OsйFzm4?._jOX #+60#hk}/jMHy[À@][*hw{|VoYVmx||= GAKZ /7 &K }+:ׯ`F8rterH³8MNXF3S72B/R\l^2PփrN?yӤPfB $X <]owfZٶ8Z2UD.+# Fr?< 0͍"KAk3w@YmEJ{Iӛo㼗n|l{wdEb$M/XfJM_W>7`1[YAӢ86L+&7`m˨S-.nЃZm-l J5 `Öbg+MCe=ӐviCR+Zdl;#zW&rZV gL~}OSHμDD"(٪|&߽&1\-,lBU[VXxNLR..1DGA˨`M'D/e%83I)[>j7# ƃ?k-g/Qi ȹ^lY_X=y)NѤbní·fvW9'⺜)KCVJStQ9|ٌ3 J_G1)mj$@K'8笙-FLxaVΪϐW48P^NԐ`lgN"3TEM8  RP?n(feQiDxW$3M wz4A3k*a.m۝l5ɶm[m{r&d۽Z{u] b+5cύH@aR@MgMHgѱ{I1C K SC=mVX\b;Gb`R)!L8=~.ی5!f q%1(Z6mMdqGu& u?$ˏ:&@z|b +WSpk¾G0'k{B((~ҮNqW:==S-U(#٨|`T!Gw?݌&Wiڜܯ[7aäWٙ埌KEm΅Ndh:P|v|*gU4r=_읁 *6$ɡԥ%XT}/OGAN\kKD8fz[j2{6"cA~mڌ[\; vHç'goq#x)x?/ -H˭ٱy'-]}/p&U)Եt312H1y:{,t}J`BNMQ .9CAp$w;?/e&v苯>xwlE =9Dw%LXLTeA$gT2PʳՑe`/U UV{LijS \$o_l-wVL EjOt g1)T2K#GGXӋmEW;N0Rgkh}LmHh%gѸiDRJsQz^{JB(7qvUE.ޛ( `A' g+W>AL2ü!pXl,͇݃[׉U0Z^~vT~Y?D#0la(%azh14!Bm4y _$@p2g+nqfeZ-e.8_B<ߗQ*lwu[kXM|ec.RNd+gWĺQ8Aņg'u8ٱWI=wLY.OiǤ!#|P%#O;;_Av*~i#˲%uplfkAW,AX$o+e Xʎؗϐ]q|]1?P%P@t /g=9U+[MXn'd @t) eON.*$?ۆz/Ǫ;IGّ_F$fv#D P5M+3nBDW>0x>lwugzSHvՈO!zPΔ/!'`>a7s!&VC!QQ'*}%_~56)NIKyo$'t9DEh/n$6v#łhǕGpk A#c1ýVŀ~Ewm5`zF>"A_4׈!5rY3U%CJde~m{Q!fr7ˌ`b7nJR3orJ!Klp\Yk})n^]&ȯ,2 \ύTUwO ަW5*GR"95@|\:-y0WkL~ɒQ2&~ <vЗGCNc$CHm]"a3?+(V*Ue yXn3Gs'-ן _*+P6Eܤ׳-ӷ\wwv(12b`&RmDv,^{ F6}aN9^f!Lk"}gz?D^ɉ,}Irˆ<=Po;qP<zƯӪS.D蝽_SiC{ n7RD \Y 1%(Ie?unAl,>w=dk8QJ`6I݆}z8KVʋYmeL-Ol$Og3AyʛŅ.Ukdv]3QqB}F-{5XT;$:<@eZعЍBY7g't xBJe?^e7/2 hx")a)C̹H:u½7֩'*jF]O̷qui^ 9"9PAFF[ %gW89,Uu}WĻ0]Q'|BnivHU*v%@|;X,HI*P?+92D~=R,FP3KM\EFM;7tßtVDBon٩)^~qn\SsqQ*5k='x]|n9U+R|cC)wh-i۾ap|?Vئ+h Mήַ1YOPa<6Tത aM^*Y$ؠT#DVn" ԑ(B n˶ ZSb>aPT 0Sْ9-ى҄y2JnV<# $(c!"0/QL÷k!P;\N\hE(!i;T*A35b56sr15NHEKʆ3R8itA\tV!# G݅b˩@{Tuh^gYj*Ô[ūyX@xt)X׶ao+a3o}wdƛW!?a)~c Apnc4Qhm2o:dvȳasXQi(ֹ ?x;0O:B+=c9-&|?zqjCb-nn96lwȖ\aUQ =lňPE( KXՅ~nޛM \xQFy$<@k3H^&ՅI R2\{'yn/}kC-bf BFFI.zTiL&V&0=|Qg^?鋆4^~ c]T o&ZJ#irA ZwM 5Z-#B△/UWoxaktSrW`-ܟk S E*K]O$HlTܽI,S|TA`M\Vc:GHɻV1%=Gjkڒ-@-P1&`0VtŤ]nHMv#赌u ۈ:7 ~8MY VY7#!bM׏(HF D%#.& ,Tm͎TFaf{PԹyP=òzɽd}α @G zuXuWmzk/ 15@rF'ઽ{_SkPB[~XےQ^Ȥ*K˚&{Hň^?aWiRPgPM M$@sU9Tt}bţ]J(iܹw)%Vh-x塞*#iB5auCA0Յdf3.,4 %@Tqw SHyncFSLQ pOyռu߳yo~ v>"3D"J*98qK >^>|6HZ{EF%⠗ E.ع:fw> T+uyQ?&³I6'-unezc*}c ܻ4sIh\ ܎h?zY}FH灶ɍ52HRNM09x6/c>LS? -o|"g/S O)MwN쑦h򶫶tܢ@&\*M^rɴn띯4mkV' ;u;u[NE 3*_4X;و Ǵ<-mH%-_CA%Ƃ!8eaV%U{ C]& W!̼nu931?/1 Z{QP ?6PA[ɾ&V,gA GZޤȚA8OnN-+m!Σ~D[Nʧ\.G~v^\CN"{ }\&Ct /I0z++H8.iǞ6`GZ}!ٶ PN6[ }CjUzI đ=q(rE}ӿ}z."9TH/O2KJEC@Z8ݬTwlItۈ]K[ Òu &[5A{YfV;Uz6]J+O#+Ճ/4M4͛/5#g3e"RMfQ`>3?xtJ7V@,:դ, (a=b BCx7!>gk6Mx53f_uH0W c/2*s{8X+ ֮˟ctPy]ghh`wvD`WqciT\\حғ+jmWw1S3h4_ԦR2`7W%gEX yrByl?>^3 TȰ[llytܷR$"v%+(1xD*%%J!EHJq}-=#QS0 /eĊ1Pv'+y `P^9HuTWFdU)3`ɝVRԨ3e˿8gͫPi ZH}.s >ϩWRK%[KPթ鄉NIKr0Ia>zqEGל4 n\Nt-bLK~!_vY=Xx}fnC7kqb%(n~݋}?Mhx21+#hM?ƢWgߧfWo`h$ TIBȔV/dǷ"(*>Z!pg(&1 a3cM1]aS81*;5eK.[-ϸCae?K}x?>iKZmNuV 3of%"|7AjC t'G Pb'&[HV\ 9腂wt=ѴJa}Q>ꛀE5 /f.?$; q(ز.+岪X5.P%`q/|cO&dJ{Xc[͚+1!o#l\֕U x[ˎ%Bh_jӲryw??@R}{9s)p0hcTAR7821+jX4 \#J/N02`ڢ(P?">QXo{7ä 0,\4Ьv!n2)0~uq߹ &r|-U`$l.־R1q 1R;]e,?<~`_y =Ci+M {.k*Au_#`o(*źq7ؽR$nϰσE‘"r7x "d>wH endstream endobj 110 0 obj << /Length1 1932 /Length2 14486 /Length3 0 /Length 15699 /Filter /FlateDecode >> stream xڵzUT\۶-) ; B w .5CN -xp >ܳ~5,cGQ3Z̀R G03+@AQѕI hfo`gfeDwm@` l P6yY~@H.oJ @6rhM* W0he{s9yXY`b鏷3@jg0u1+2@oB-`6,@:@ZMYSE-jWДfH*iHZiMu?5o[14qWUdcsj'?j~ \-]@%ZN|,,Vn`f_iX۸<@.v 1not N 6@GW')пoT9[?1ep+_ ** SG0l vs%{Z@ @O\7ͿK7f7n GWW"6?ջ3ǿdJRL oȤzcǑ O/+7'I%-AoU"O'0ŋmmpĖ6xpsbtqvJ?2+  :,+lo$8@?K|o1ۨ ]/[%VO5to3jrX-Y@v3e%fod43u? *U8Cg*e P[eo}/he|DFg͟`bC K|#1Z?/+IGs`b\\vz&fGX\\%7E/`Q_b `1`1_3ٿ6VV 7ob7 ` %d{Klo@or b[elo\LoE ]S !._XjXfh vg} 7Ͽ3Ty<}8Nv 67.ظ8_}? zAiM% '+Q}`>ґ9A/M. j ̢.)9Pؿ&WO\[+Jj1kg).VtQrNg}j#h~eŸL0h[Q<֌b鹈NI8 ~}1]1);*kJ!٨+J,Qalxt1&wSi(@6c7UIi>'ֆQs3;4ۓ=\aM(d{0/>'„HE?v}a4Xֿ.*Ddgo#ūUi[u_i Nӫ`_4L|TӦ=:7!3*&ITXKH]캡1/ʲ;č?t6+0ޤѩsB,V'"~-'s8&I'86.=iZPI&WD[.V ؐT3gnft:~';_ꬱ70EJ(y(,/!!p:gb&<_8Y #!0C]RzRH X/%75{;T+J8qV ؅Zƫs@Y\+vL}%v(4=DP=d"@J N^փ1<VGAE7@;L'53./m "?q;j}N.K?M Y7R0}iI q&Tw?O c%ㄥ9փʪ.{PU|FPKvئ)Ip!(9&KНyGWX^N&p]ާPrhL_9UR_Y6`k|to|>9(lH]}$3W?^롙Iԟa$PCTl0ju~>،ȝdA=gzo-_ n6Հ4PWb!z;!*tdؖ[5 c~j2ė΢` @p]DY[ {8*Зȭ_vDžHKB$9]Rol3CJRpD+pX7;- 6Qcjb~GɦP6w-@-ʩytTPЛ dC2Xj`DҔFn[8mx=׍ժ 14ԓWQ*vFI׶Nĕ-OGM&5Q)l]\}3ywNX([)/;X%2p<7V*PN !ȝ JBR(3"<"g2.Oq:dYD΁F_mߒu%0N7*UśBMt٧=]6tqؔ9J:]\D!i ól,sshgd8P:s Vpd288r d%$yɗ}͖ CZUTL\.pd]!FСgJ4np}9Elsi^VH/T';GFeמkCI!x"P]m1h_Sctgö+SO3#lSR1&@@{Mzoޫ¶@}g}fÜ>~P%VKad䭴s3Yjioo%oa I;sU0%Ccع6%F|t䔱EFaRRpHĵ"3!͚nVX్p#W 'e_e='WU96=Am*ES 5שɺ"ܪTe 怸R XI'0e]LϡKűs]\4AřZv5b:[uM%^Ź1ѽ[QD@J::C)zy}KeR3ny`,&yTd$Dkv-$4z8+n1 }{H] z,k0Mэ_S!6Z\4ϐsqÌPuA#m%a 7Wʙ̸8yHyH 8 T-y (fEWQr"(S6J3QF,p9L' ~NN Y3x8ݶ>\sńK'7nmJ+H=juV-Xض&xd}+o(qt7k~>SgخE>8DA:']'8=%+aRӪl3ω'FGq+;Yߢ|S)~%v=ޞ_ɟAۺum\.*|^aBngJ-#8T"BLṶZXWKB3)<sJ˗9q*e$_zSE]. .]嘿(n2{C,yij+Eu=dDglMJhP*{n8CLMdalYxYUlxL+O 4lGۯh#[H`*ʸym@YbvzxN9c˓%ˤ"Ҹu |%~.dTΰn!:_xcwζ:ZOԳ>*U)ENLqյEm G]Ϻ.Gg${6d8nk¯JcpJcәqxn?'r[#F?Ob ~LEnٮiQJ3DFRo(ű`[X2A+0zQU'օtyC"wBBPh~.?du,O2^L*9G[c"{(<+Qq?%JjYZ)ecCͶx1l$2KRh@`L%CΩ)x;D{ ِ.)ŕ:,).܊t>a-4iyH4,[^rX.?3FIn9|AC' +m#/vFj^6nB&0{?8o|@ s!HŹXZtnDnbmc`ASt=w& %-T͔5IyRI_f~=RM{g-h6~^ oA|9V*(4HAWI) T{r16izo~qCIkǝ,ROd'AhEB R,b-@ơ.BeW ]]xVW5o,me*T\XGphJ6/vKΝ(Hpa~囄,d'})]"fg\V.LCh)I36̟U <yOLTT)z lۘ[HKXB ŊC%y|{2H֠|D`H$&[1(%ۊW,9b?Ϯ(uGpooIARB?ڨuag{cVG,,AL, MB4) yGyO( ? k}[SLi1 NskNUD(Y VMCNOD>Ri—C9S?B^^LiF~SpuzhL#vӏkY-"@V=r/2@xh\q KC>"N&QǥT3/1u]H-r39;os%]y{`A83r&ƌ¬I̒®'#iԗұ}sayl1HX[JIG|;b7* GÞHT̏4`[dDDYA"PY]p&idzE-h=oB~2bVyal~\i87n/GyH}ָGc<#rLn8Me=,O-9 <=9u?S>:@u}|fgn8,wX814LZL~Qq| 飶E|-GDSqBPK(_AK]ztX4σ'fRS&3N.~i|V3$% <^ۜK3mTK\',72)Z;_ ԅvG<ѕ*}Ә rˢBX 5]%)}ڞco' Ԟ3!Qqy̛nnvz%MZw7ðOKUݔkLپ_,$ם?w5].O&e2J%YĶ/WYXZyapDκ#<'EO]xjlxHR dE?QC(K&BAⶖ}ƚQ+M4 ?NN+%C ,lX[΄[Ńn{O_||inȝ&S 鰠 P; "lEYJ=3!> isb,) ۛ|¿*{*Fš5vki :v(] 4SيMb͡(c(A*N|xQx+\Vzgct:U KOBD`p?7s+ ۺU3 q^}yJ.XPhN`:P~4U1 "acf]k{6Էk߬.vvbi}i:Nc~sprל5_dϧP0uu7M WiLfs7Uzz|:\:}=T,)W&;b,={]:$ey z+WPKٍʞK~9 Ufl2Z4G q*w=C+FI=t8Czk^ F9ܪ|N,̈́oX|DjdrIsYbN[~aG+dD2շ)J夗&םG$R0(¥?TiMRH-Gq5jYBba[}r3fWٞjCt9p^ ,J5Q]rhXF%%}hB`WD6] %QY ,z4@A圁8U!?@7LrC~a>84TcSsy'vʬ(ϗ." qv’TX6ֻԭ?64#J>$۳s5?=i:䟕!e-tfq.B+7}27r 5CX&քT(@k\\X1^Vw%eֳrO~[^/ӗ4FUqq@oO|_e $]pI<,bKD H |<+햯n"*ri~YфZEuOыgD>m)$;MXNaU|.m+WhTuS(zVYۮ$a OFbgD #F $ýٜ3<0tܸ}WrR{cE:r ofHwRC^sb?7x:(vnh3e_~gQNNN[UuZW$W^',e>6Dn)ZD|$S҆odMq1>ÌջŁe؃Fwv Y Ę5VzKՄԪ eg=̋y~ WCAG]]HY?]ܿ7ߑn\''oďɘqMBѺU%eKat JGT[:.D'3[ R, ݼ&\/4L]%}'r6n"L7het}Щӈ|mXw^6vjYW)SpݞLD&l$k%,w\AnY:y/5Ͽ!KՒ7 EpmB_5/qa|$T4GJA >{mwl{OqFǝ'h($vypr_)]כq!D[$F_];c#4_ C_ӃN |.ѿ{ޤȃI (_h .Z`?yy\Sª>xC-H$Ssƨk>t eίy:-7HUx.F[9@6zP*Az0O[$[(JإR8uWCJ턴C-$Jl]c-'CWjƹO8j#H=g,rE]=`rt쌑W+J+ՂI*ڬ- isST}5luj$4=Cly\;/7xvJIfC 1<ͷGmOfritVzݴ)B-l&(u%`wt| 0WaKT3Fy:-m6ǫ*H\ 6rk% =})@RoSX|J:\<3^5x@E \LOT+Ui1Ë>`_#OjV%)Ը} %K􍩗Ak݈4“l i98I#M!s[[(d*]=;tNj#8, kh mS+U#E`FTᏃRVe"5J=nZwGuW['&C䗁`Bk|\;P%)w8BD[kC:Md씫4gh+@d*{:_r + Y/w~5W)B-~Wђ$ސ٭aQf¯Nگbcd8'[ruI%:=\ZD,sʁvs͐J^>3=Z*PLu5UO*vkbU2YMi@YVBP$:U . ߢ2Ҷ.v9"R4t'8]s\6b GHlcRmo y|&ԸspДpeSuPZuEHOHVwH9KQ: +qզ4Vtܟ"X%M$gYtC?}ʈn|_:w']Xu0ٽn.s)zqتlTFk?̱hxFheLbHD0T_2\YvEN&&/g[+<f *Ӂ.Dqd\?!AIaXo⾧%ڕ=>uQ| ~oڈ1~5<"lfIY;n@)c/сt4Ul;^0 uDyr ȩJ$j/i@;{+CO_~(β;`u88] x$)d1b, G͟'^k|w ;敍IC9ewSnq-K`cKU~ Д/›9M,gIp ǜ[So!ƫny)# \N$pK?̜RQ<+Ie3|mM[0n ضk+G3u{,ìD :NEu{Q֖dꠍ^gci_`r%1+ڵ{яG0AsX̟hɴX. W!]S"i )Wv\a9B!}֍x[7~;7EA(qK߱_EFrv9$ qaa^DeT__Ƣ^}|y?xZ ld)߱q lsB~t b/IJqObU;6c DCQ8PSU~zK~5+2.B yJYO|Iʙ.Y[L ./xoӗ#>s<;/x|}*9.w1߯E稰`.W=.ez*);`VŚchsLGr+E{}-g DYJkZ(wp.譒v ŜldJyfBzu#6VA= 4r\ ߀ZuQTh'7\(5`>GۊI.n!#{Re0Y*c5JZ( Ccz'B{:"5Z9@d;'@>aà77xVBD/(\\.c*UvĚFG\gEyȿ׀ J*#_-At'@ٓ;IKrh88_1#*>!hnl fv@TB&1%\5SeyL6S8:M   WkKNrZ(8x:[IYD50Uۚ¼:hSo%ג -Z 7f)qa%LT &Cs-u'M mIjD BVFYX `M*JHL@h@AV{QP?;T-߼>4b.Rږ^jJ_ ٪du}rX3c^0X͖'-+-y]9˧Zw&NEJvp H~c 6(A^3hGwO̧tù+ Wse7XwD#\M\߲9ŋ?$3-K]_/)Y$Y V#rs5BtyFeU<.g6Tg+GZI;F1cRƲ1Rj%:k#LP?h`h-6IcS쨞ݤ~wyZUmlcM՚1AŠGp]r4>~ư±w>1b2>j쇓&~ANmdcw4 endstream endobj 112 0 obj << /Length1 1904 /Length2 27158 /Length3 0 /Length 28286 /Filter /FlateDecode >> stream xڴzeTm6'H'; w5G}w=;sfz򮻪(D'd 2~813rdd lAV_ 휀fzFFV {9F p4|5r|W032r!Pā6@w1 t4Pv2(  G:Cw6H"u775sc?)#K9 E/K !2(*JbJqů*JTlmA8-@THNY T()TڼoJ S~.G]VLYHYC^9@{?n+Oڻ=/J3GG[nzS'Gz)_);\@= Wblh? 178(}iww{OV8/]yy#] 4'{?>dɲ. z?3m+/^1'?Od`@O/1%e:³gdž/?De&.V{ߣv@>Q<9gm[ڀ\l<7 ;2I; 4S#]ja X9Mg w"&{7 _%mL@#'J򯆥zVch r|/ ?_8YYX)WZ[?KB '^?&ch,ohd.hB6V@?*Z꽆1be/{yY,'\Dl@6f6v{A0A@5skDd ]ۂ7p@0Ճ=tLLL,^kQWK?9]Fs #bo܉h .2l~uXŔ6\Ѭߤ@<&Oy  n?u,׵_ [޲(bB#* %TR9S--C·H7DR풖lhFL{ h o=B9A#R0ݝSl,gyaXq)+D ;O")]^vaXjYI<}*<K1_ݍ 7k(Uփ`KBߊ+l=o>hiY5h0vx>K§['ۨQ'$l"0ry bHh0FtOe^G S屄>8Oܷ΀c+#l[Aaܳq!%P+LΧ$8OrJ[AAPRvs ilٯSz59-JPJ`2>qJ ?m+ {6R zhO-f ;\S_ʥٜ->xZ12H'Y0֐\ PrmEgfaD44- ŘX}E2"sQ/BP΢ҹpwuyKh_ yǔ)Zgy-ه&{rTyFt6sm͍{2==R4]f/wRo*"b7J@llN_[A3C *5x wK&y?mZC&#BƸK;\Naaxm"Ox+!6 \=OsIb8y{ iSp)҂$T WLꐱmg>1sr(jDB_x_YSNM_4ےwE%9h%UV$%6Kc$(z3(ŹFq)!j`QB1j 'W d?ـ9M5ф3<~].ke` %,0:E%^9 m)L b-wg"υqRɉk_| XV$bX5'Yr9M΃\v2yojZ,*`.\(ө<{d2' N=>Zڌ’F#"O~JHj@y&qTpg,Y9Ih^?ͼNo Ne" N¼giש 6V у4NLjdپ5 J}mҩz)GWPϾOI_ۭ}հavJTlh7TAyߣ-qgHDFߚ3. EqGo; nJ 7c;KJS#Y)ܨ4<]N|ؒ(O\=+r|S'Bf]!S֟uuh(;ʅ(Uݱ`ۗ[ݫiܰ|V&k5uj׫] Bd9ە~J>9\ )0D 1ea;#Wmpxӵp@q]Z`!U n{sF+gbM .P=n8C*]ZŻJ8d^^`biONE.>!|N8T*lƷlE*^/C#[syμ</0%<v ׉ 1]3K: LP|6p)A%޽F%<4:'UG`u?8]|5򙇫N]6,g$+L(Z^|mC0uG %E)Ip/XEmpR#nVvU4ttxˇ?w.LR,J,ך>mD+\?0EZ9%lnjdH(+>ukrOirsV/ u}nV- 3B H_4O$Du}+]Rt.,? ,nߨMW/X*vx|IdBW֑Tx/yAJCKR}hEemȯk*os+jf(?0nGoy-J&::¢^Xu'QM<]%$3˅YFĝ$1[ꭉXT 1uLOnڈWA}s>1Hy5G*8m[,IYS.x[ۜnT5`jU'!3K{ b r= 2V950I͈zv']_~O[ {* U$zf?þs'q+{?. -V)$Q׿]b2HVBȕԁQ\M;82i2UE&N olD[]n\66o&3OxHU+2\}2>%3AjB:Uiף~, uU~Gn[l7jGuD~cOP%%"'Ik*FWqX1-~w*ԕ8Zʸqklfk~##ԬK]2Rd"ތ&VG@|*[ z7c}Z]G IXyymvK~ 1/-;K%j5V߻'?Xkr(0],gdf &Ѭ@x]yQz${>zzjQ=Mh0ĊL?gt~d**vACudQhe\RйS'VUyCMDlIS=m$_I6|@j, qZ} K3 %;~E#U+QzVrv%m)]W&xSQӿV/2GkQEyҧ|陻GFsՇr]uEm\냥MYtlN9F=؃+ 83ˁMZ] ߼1+2i}\C%/YSqB9dwLo=9$۟(#$rC+)TrWåM ~wul RD}q*=6?`U[GUmHjO451mq X$)Eˉo 'ڀ3; AOx7u\"͋XInڝWWyt&L.?t%Y )nЛmXt3 C|f#B1,?uR1pWƠhLd.՚l -U #͒ NҶ>JK@7 fpis٬BDa9(sYnxDz.?S|lւ?% rxWʁv`EsUgLOye .D⣐l ٓ [ )H]L^9{ ʬ2R9*e`^*KNFs3tC541SE GyLwr=iImJJtEAiU"H QM=/IOj#bfGU zSjN-eEb 7౔ϱلw빫N訴YIa^)^;N`j0^LՌbg1Ȣ˹0J[GW]j<-;Mcbf~DAv{Y`{()AΓ7^;ٷ?)Q7,@n_xk XcirRAUA~DfjDO(0ImR;/=EȔl+kE'ZQ<,U(3@RGQ?`G d7oTO; ޥ>LҘ(2xV7vޔԎԯunjؙyNV}Ӂw<6Ths_@G cmvK"'x )9؇i!@{ejIM~a8?vbK*FUp3S8q%ЎwN>j{ C>S)Xe)f䃫3]^Ɛ{fx>7wrfA~鮹RNM 33'>Z ,?ֈNe(qsN8NXqwN ~l[kJxRQCiMa?e/}'`٤ثOjv9m1Btٌ- Zw˫Z|>Xgm]gl`Bʐ(^DoZ"߀m8o[w;1DΛgKq>c8׍ a-El} A`0X!F*4\ q>Iv(,ee+1.| -yf$o|R4zC|7;0ׁ?Z¸D% Mʼ̹{HDIVcịgpAȭA:EoQ&1<\ji݋Rů2Go]7KHpσ'3H60ڔ<<Q~BD0T^Lvlā\)}5W;y:~+ݡ}B\<^un\60.·W77)X$T/;1zS{aǿPwzf!oC~G:%ľ-E3[xp_h3?S ڋȍGa(P>yu3yM:V\mzhrLiR/x#¸OOCNR a{3{F*xU i=FO0ˢ(ƝLohh^˲뫴I>4bBNf}[."ETK%e1 },d̓%ݗ|I,ڗ!HFnuP{hka*[ ћd('h95yv夦<(]a Y>gzU(ؤ_>zylFjʶ\B A~;JC @~͒G[cn.*g2ØQ'$9;9f%/)}]kf̐RyΗml̇y[b"0r+ c(sd.n t ~$ mlYl[[R1dQZ Um^ktA2J>r. K5Ζ'MP}=[FmӍRo-:vp5 ܜjO*"?H=+{i[CM 7fUh8Ϫ= ZwBI~mPI I-UJUm\K[T/>={YdNz+L*\ћ0\Z&EcC1T6<| &=J:(Lr>4y~ w,Ebz,QƒEd 5u9QNvE]"`D&80sT(Kݛ #G-sZ|$`M0|M\ڷ~mU p/P+QYD8Cy|1|<ۧ0T D3gÍqIr Mi,5L+4/:?&ddV]cWN3pyS8 u ZJWV&.b3 KyFQ;z܉@YJ(5 ޟSfM`P)ӌ=l0 Ix 8L,d[^^]°ބaRV i_)vb juL\ܙ\Ԗ"K=z28i6FO|.JyT/IW!:HqS~:V}RA)ƻYY\߱D4ya (N6!ӄX2Ȥjࡧ]J}aRK!ظHLT M2P8l*lr#=qN)VH ОMYPc'G"`h*LyT/%ȁQ TYf>E*ylor}{;xExzYve>xya1X4T+bh5{ 'z5w<#D T/ >f!$=v";&׬6^#?Nut%V{\Vu4oை7GA};OL2O .jĀKf}s 1'[(p :ߨ(- n̑]X,xJ'j8F5mPǁ$zuMq)Bv@U~HA;:ח@3VOcB!̿d ysHy(9;Cz\Ծ8DÏ*?%-PI]׿<X N SRn|z,6P \VGT:}>E$l{u"f_k3RZ~]Vj;t3Laz2!Q̧dsJP)BJ0c}x(wiķz~wD1NɫsfHH7/r`q2~A|H[^B_i/Qo"<Ƚie] `oR3su){bHn:,/|h K"߶5}ߓq/,S7alζ{qү`V@[9/E^3+gӮ.c4u8ie7 Rn&Bgb;F{@\U6dES< /:#sɟ)=58{8Ժ1Uy@WT`26-ȜP0̓*NawM(ޘg1kZL~-GXDY1mXo?OqGڲVaQJQ`H5'!$ÎX~EC]o/< 1g]!=G~-0nӣga!e]zZB(T6X1; OiQ38K=GD HW qP;k(3j)um !}Hu)6+kMz%y h;N1%wZz~(;VNq@;,ZNh;3ׯî$o{;s .3zS;|ZԍתX񀌲ۇ.H#6!_=z[6gsE fNxI(8|Ԩ(IdH6K!q S0)ԉV&Lo*Pl 5Cƣ5uZ|+02%V|.pO9}!} &5*+4lܡB8ʽۏTgq&4J2Y>nޅڴ|;Tܢ4!/#,sH)(n',M\X0_Gg$liΈ YkQůh8' +kod8iZ=jq -/s4/B(3W(VJamLx#FXcdiAǺS0dS_D^G0X$ pWUb\AdJa`k7TࡖhKvf_wWĉҵ,,i2T IuT(~Iz<)J` nr<5U2ħ[IvK\N~kV=sUt%yr7̥}*̱i'33Hޑ pq檿A38[L#E׃ ޑRaxXb_UR>R.;GO,RӎZ  +P9VL'sK0F* \zXӔy$<dZM452Z;Ka#! 3J{5^39bELGs4˪o0 |%`|+(ͫS.8̗^6 biZ:gKsfRhOe?yT~,F)QNG( /5;1@փ,S7q&+,*n%¹*fj| -=; c \4 nj^pDA8[X(* JR}IQEͨrCP&*.ZK1##tOIGwȰ(J"qNl۶mc۶mvǶٱ:wz{T{Vn|="wp{-2z+׺Q!5v6YG U(ʩ^3^tEbJ>#n`T;EUHV#oh?6\~|~(V5WME<'[h v^kUSP^`Ͱ,V$nN`ǃuPz SR`qQ8"jWLhl+8~Wgfj5JUKjw |,poVX-M0ɨXCKz K(ՌB*nb}[׃Vx9q`SK?!U2esA7/yCUʋ4" ;y#zNeR9qk_[{30"aJb!6TЗQ/(jsK?9[o$+1:0dsSIqwAΞN"{rH2׳d4`**=rɊ'XQ 3JD脌ɀU_[#J6{tDFh9dyܴ%C;'ȇ!B]0RbegT*2n՜r^j9?K UaAQp+ kLj0Tf!7k}mbJ>,ئF08fzhm/|IW }89[E!bxl|%JLYK᭶/OxD2xamN [ -N}ɳRtvG rcxьf%}B;@({6\~|͍ՄnüR{r3 1H`ר BV%&D,YgڂYCcF5; !?Q l $qrLܦ# rR3`/=z[?_]$8KJ[YZS`Rk.F9LghD=JJ UX [ȃ}+M(#NHq(손;#8(p4u<19G/lһLLD~WD7SP^ߎye*I}HB֌br1nQ]/@)M`}S_%4 X1BURӲo/qX=@VhX y7h689]r^k@s9trgUri*ʥHg큛8CdN6"J\R< M4 یOC^iPW%J@g?1: }oa'KZI?䁮]@轩评G7%P%?/7s!片f~>Եôd99՚%h5L؋d c%qk7#k <4ӵ j&S.:Bm J5co9DY\1 ˶̢NJ_GN#X7:ϨF@TGg(97lY3 F!w8' G56{wn'_ikIw H6+٘Kƛ^PJD qdE6)XJab+Rg4FBY3wBHfL3doM2=(tsXi]WwŗcfI@v5: C&I\dgȦlH5Wp'w D~#co18Me Q,@yfK$0vDHQIS:0}`@3>P񷦲r^ҖYDq)J%ue'=Jbaj4@::4Eh25!ѐ?=-31F (-Y#0:"" C{v Tܮ8<-';iaZmYvϭ\L5~ Js]vG <)oS\ʘߟ|cR>6 Lng!]O]\ER[]"}T^.Tk%T/RWaʬ!:+[8 Js;[\{ng@K)#Frݘ÷jd/@8aE67xT"|ӻPYW>~%;Z}GIt7':5)kS EKk&ԸS10X@ע.z\<@E~mAݏYjۺO;a;}.Rb=!Ϡs >>M&a+Y|5`.K@dz&t;נXAm30Xߏ"գ20k=bUFocg$}c~)aSuL`[5!pL_[35Y~ fD4Yah (OF繧MMRiFQXs \{S:8`80on ~$~]{/ue M:|8th>}?Eƴ^p/j}>f.|ҹD| ˨pJ RSBR:Y3VrhZL owlޑr"쌵$$IB\9;RxSyEj.\KP;<;_̸>lX ϬL%bnbբ7 q`$^U#ãW\1mSfCWp)EGB>LFfO͌2O}ˏ/)cꥑ[SOޔBsϖZ?,nlfok(NrI@Ԃ2Ȣ>Q:/+1T)8Ο:XbrSAZI ̆ڠkׇ"I&ê쭠pmO/t Ǣ hz8ZY=$ .u .Ҏsqr0 ~>[ B\pC*7L -:YdmSp٦?]͑t֗k1h7<%6N:xM6LdX,m3.՛VZoTly"buۆk|N~ܮIAgDꀶ̫8hnqtV=LN#hlRpe}Pbt\i\ 3~Eku]!b~>U%S,9mvTޣ- B&uh P$&#x".`^.ZuNo#ZY&E?3U&vO00%iWmsXrO*eaEk^wآ8]8XR[4䛾xk/zXfK; vG1Ӕ%;2TGἠyךWUt |uz!JZcVl2>AmLӓĝ/+E{='!e͠$J97%/=:i DA7j#Gˤ6^nT0+GY{GSP&1o xk;S5}*6;6,f"DˇoTO*Gư{ӝQ9©rOk5e˨h|U<ƿ-ʂ)jKdcd}L5އrdӖuXޅ1-1vk:B_4FKTܽ .?[Y8(bNM2QwV^1CWLY=GgȪ%RZ %ZɁBL6hq.%429kغ|g7,$<F8>vVLuO|>՝zΑ GZW(/=i#~Ļ3fLB@{{ Jb i^COTZؼ/>DMF9DLiYQ&op# !TҵSQ:;?@`?Á77Ÿ́"a}y -t"78??rt2pjrͰB[s4r<-O@ ?pVqKI[+F7sG;F4OEFWJU%#XO!lo>pc21nT4fJ>HTddl@﮳^?潿|C*S~Dzf!rtHws7èTo?a߾BN|B-tdБ[,i ڪܖi|iMU49q'ʿq>E 2\B7 $zaV׍ESQW6{\vi! u1l#&\֊gpwc 9yaTaKH] e8;ҧjETxW'[ECu܏{I;5vc@bAEPPymBbn|̽m6K_ 5,ܽN˿f҇V9`(&fT4bt܃JwFۓP4`8liC t~'"QzgwipɶɧzotBmI6*f͇*$NFkx-@2Iي̙_ Aڔa_δ|YjxDG'?=q0V'LȂ, t+ٙ3#ǻF4۟ >3o`ƎA!74_ǿ˕SeW{'iCg z)LA=лTcă[yCȌЖY+x,yOU(׆2o#r.j; ,ks2ݯI"YkMqo)Ysz՟W?*53CX<; ū.p³bVjt]+`-Xag1 zU_xȺgH|i3vPZhY6j,Om_!Uz?,Cg˳Rqy|Qc, OcQہ+l@EMi :%aaIH0#?{x@΍?_w4Ҵa֠'Nӑ 1,'#<{%~f3Wstdڵ*C|cZf6QTXTɴoo;w]ǜ 9 5۷X:|Y(Im*`~7W? q@+ AlDJvqƍ,!-[k.wNϳ e=wGz%Û7qZ,yOZ gCQ1YKǔN]7JډylD#22/}xF 5cb}@t=~Q   bVZJ-QuBQ%"SEW`?:#`lfqZHMյL$@StZ,*Y! $$۱IaYen!$c+sBCU#V Q%.~KgN^5 "4| Zj[(:?lI O<'ǘFyV#֩Mvu*x~Zf~KxcmQģ#JΣִ a;HV 5pnF~tkE~ļ=Fc2h_%yY sQ )ީ@I&߫l`"8\H8OIL '2=^LgD|'zR{ !^8!6[HkP08*IӨq݇$! O_-.n=7wa[g1>u(ᯭ 1xIsS7HAc]:*Wo`2DJ/7V4{&l&Tcyg\vTW='ϭFxS-J/pe$ޛ*|45،\g27N@tXb.WxW}uXV%ʡI4ݼ6ztesB#5A( {ff>ovd%2®ߋ]!V+ؔ{ҘA7k1÷Fpn{ jǭcA%"ak|Ӂ s]~N?7},\SK4VU7r~}0~n~ ة%\9BGgk$;@ψ,R.w-P&xe,1_lOo;(c7$ ˕5(CŰ%qrɆG:^`Sh0BBj^ ꅆq_\TĔ'|cu'ZA(Vy/ nڰ=~!+YX`,pCPt~͝"K,..﬌-Grsk+Li-wf{1ހf}^QyvKDcG\! LiaKI,256|п@HW¿p_q[GU`zd.5G sƌь낕)md?L6}8ʎwk^r )N%b}T}+tL.Pz+fDGX jt1 T.@AL UO.w͡nQɕv9U?&mUӡF#Ph9SRq/ v7t2g׮ LrIzF᛭hĜTgpJtS i%B{y2."2Gڧysߑs(ĬrRyWIUHGuSоRKiKJێ0Y*Vl_Mō>oZϱ+[Z1u+mefw։G * oA \!e`qLx񅣫kYRp^V*UvE e#;ъf@8)]IoLhP vlwHۥ!YK/VbԲ,?{v*eR*DzmcEN9}247s-'OS<|ZQ}iV/5FyHDvJAvd n)&p0W`تYDLl bk0eZXםT7ze(OH1zR,#!ti130,ƃ91!b_0[aɁA2`7qɇT[Y^ /ص)˔_J aI_f#߀/z;Uhw"`ed!~<[Ku9y(ReK(򦡎F^=IUK6FЀ|@:J1XuX'е}e6~/r I'tvDL?o:ÌXd]8EM)9c)?Wj RsyI>ZdC9cT18Ť]belJPk Ltҕ\,T )6I^tDn`vMW#1S>TQHWEOSh;T tt ؇{-x>_=|̲ ctDdr\ʱwhqEeqb,Kkz!cDzYbc?( dD%JR}1%P;KŠKֻ"IoS_z-I:)MX%*Ђj8]cOW#|ejqh;Ve[|m/T(O2Җ_Ur96gmmʡ#;v pxdݡcr>?7 !mFnŢ2۩2µYJCx_ |,9^C>xSZ( 4yTQ ^Aػ˫x0hΗ֔I(RdaĠ8+yQ7X0bzYK}5Q98tK#PL*vu4ٕFX1d# y(_<}yxD?Eϣu I) PJdGVd2[U̍cd{ 3 hB1<\kW@Co0 ̔4Gi(i[uN g@4^gGcNf"8LMg87l'/MqDaZ_nOnx' o)8+1e?_H25XUE<6P{_״YZo e%u.379U;/0ґc J#\ -At;nY\;%0åո f6/{^H;6O\Ak9^$"YJUf8{B]%k`-- 8{#}Ghn}afז]9y'&!!3^^(I(=>3=0^<-+է#n,Xc713Շi8w8j/歫w\@qUzPՋ EX3f xd'+J nRL^Ej 7UZPFŌ 8X=]"& e|APFs#w?G"m[H{۾v~ ]h٣VvrZS77ySc-ʙs'D/nGX6U +}0%H_kG*Uf|gA*bv_&W4.0p.ד t@߶[_O;knEbi"$.K߲`/";_xoKISXuL8&Wrt) N`ZNlJsrNL@ ?5ͣ:lm;كR(L:T8Qk',GY4vy64S5ۭeO0S> stream xڴstdݺ=cc۶*ѱ1;ضmc{U|3ڣ(rbE:!;#3=#7@VN։NL GN.4t5tr8 ΟqfFF.8ri4yΆ@&? E;'g:#CO3H"bghaf7 L҆VvnNVC[4=@P֦;S*P"PVPSTLboo_IDU@uZOUgfyO:TTŘ tt[F߭}:S@elFoLohFooON7;G+h [O:́Jw"Y coݿ6T~}'sZGsCbee6@[C[OGgCg'?hBGǿ5?eua;ӵ6t3uq_m:Y89;+#`ja ۽ߙY K~ ϖN[zgwp2X"5 /}<99z0llhjakbs{5[ ~Bp̀Ft76g[Ÿx{L  +߆\1qL,?%M.ekjkTlQibgk019JjX[dhcanCQG;D_ r65s@jX?>uhle trpc~2o9ye!Y!?>bv&ff6v^L*6g`jwl?+VVv ac0ڹ8a񿖜/>3c٘ @O |f: O2HZ aaX_.rΎ:d?_M? {khaa;w/:VvF3XX#_?{s{D@w11OeJcHXT)$9i9&trT;h@_:E$Om&yFKb䭉h:Z@ܒ_i' tVVLzk\+!@mX)y:Du-ҭ` } oi =&ҰWhAn4}O.hd3yF 9`K(#!XL,XJ1RQس$(*7}(:V"/44k؃^KH5;zM/B/%-._u}/l+F("j6/6D8Y`w"/&6ڼp:;}C;d[Q1.%a)RA;G#5G!z (#UkL5/44'f_ֽmËwu>,jjUz2LA@y} Lt^߯P4GmF4adS9k W"tD_7QV~\v>, K?+@[D͛oM% uk2©cj7GXacDxƃ=}!)Y)ɘpREѡܤՑ/ʮ8A!OA35pU]u_xV>193t\ʪz~l@_ѻٸMl* Yn]_k֢!o0c%WAgzf$ܽSJk.c!qU]h#͌! s_j5\hυEJq-ntFĄdDmӻ{йF0zT0n! 'cӊ oӧl 0) APbKUP{Zh%#;LA!֡rߠAldQ;~^&7E>,/Zp Q/ѝ0)-*cE$a+Hq6/=o$>0A\tqs6H- amGIϯ Պ>J fMl&&!}nM{gA,L-g.;HNnH> 3Q ئ/,;ZPTפΚoμXJ(+ӄV r] :1y~%+u\wM "<}PxgUdľ&ܖ_;@AH~7G)}6=}%q~.\׋zzOH^Ik{(lrdDC7cCȝ,{{N7tb4Ttn'LNhe Hb.o68{UQo?(Mq 21n&eqk$@^ &2qq" 9bhqNc'AU)lj, i}>FXW~zrqgFCKt6xVȡd,ҺY>#w[|qSэ^bsL G|JإPE(kK{(piX%a-.@j]48\8gȭUb\{fޒc<{_u2a!7ɧmjSr"1(>̣w`F?P=,&h9JN5wScx 4wqLD}>u,ְَ">7h7 Oԭ}m`XU_ob `k:+AǸ'tTdZ5&3m)Ў|]u%^NT䔽?!E6iy,@k@8Fc-qm)Ei0QƘzz7*G?̚{$US(o@T=~ ZbG˔ :P@.SSwSQCMQ%bUxc/0Ħ47ġN:WO;*/BИ~8ifoɟt):#GQIq-,s5OlV>a"{V)i>+?f?.nP}E(8KLfiNE~08Sl/*Z 'G?)BZk0ڗJ஭1^lpCEx== +6c P-r Wķ"FgIHv.dts; !M@oWPk**7 ŏm)OG"cY,xcZ$9!zU,{se3e0.h&pmB9<}6CD߇~I`(H:kI؝+/|yM:oaɬT˲΃a8(xI}7m*XoL?Y}M ~x{F᧺^қHMfdg֏[͒W2tICL[>7.j=Qmjd-1&З~}Pm2-J!Llt l! V#+ ltˆ_3eiZ VڅV36 a=lpǖz H&hX ӧ_y豇3ުټHP/Ѡlo /ڐDԫh5;Im/DNoم Uڵ٬dDw2"֭0?L^}G.sv}WjBD=ޛ0h|mZK;q9AGɨ5S(>(Ÿ&@sL4>`d*JMGW؃ҽL?JUѯAafL3w(LMÈV'ʷ a!oL,HHeKߎ_U'>O(@÷#*-!F8枆;U8;]¬@ū^~ c 60G[F7e}_I:ebyܕ9v)f˦\gdVԞ`-_z~V zB֏k푷g-]#]/z( 2x8C0AVڦGΣ^8I;G 06\)%&0,q;31je.rְ39Ӄp&3 ȭ2*NBQ_igkd`/<1U+[o5bzuܡbpMj iV|X@"D^uL̿0=u jkoB(E DN?CdUI0Kry'Ư13}K$eaOzJ{+<O\2Nu^ˮSNWn)|D,-L ^B0?b#}#'VAπj|,Q}^{okz"@vA]blN*m]VkĞpS 6b=~۟ 58Cf?)zÇ\Z`3K%;ުURޭjFX.*[3/'6粗N^+dUA Mxz~CwgCɰV[KP%:bVk{,>voEqHPo%REڨc~+sr$Ǥ|yWK/^d{Qekm "w4h&(Az>"eп[pYcT#=yAb-_&⛾ON۶G̋Rx:_d!@ɌRr yݬnDSŬ=ˇ䃡uhYaBbr"(Ww.WTxÊ.!3#ڦؠOaU=o}ӥolOLCWɖ~^8giCN؊wךpթby 'x4[V1gw' NT3[L98JKPK/$ $S>3~t˯(]*;uN**Է/[Ƚ' %lilYcdhԌaU]vadKI*"tWq;8&'˃XB[9/߱3x'ı*S9[éj±M j [=UQ䨙X*n8KT+BmtG7_(`OĦ"].f l;lbѓ^ 8SjA^AIˣq<<sEy| #Ŏ]E o1]6kk> ~ZdA-TL`5g+Bei(="}w+$7WR҄Unޤ~쀊<(`]2iWs]ze~Uz^6ln!MTpx숳\mKGV /σ~MLI#_( +iA諁 KO+_2e]^v%2~ /b5_DQ?rk=s6"լŅ_:IȦͶfTx)Tl -;OЙܤ'3/8җET-.J3m)T@;,][varq VQh9Ӻ i]uLYPZCYt |; 9{NJiv\) gz#qN`ӢjʩCl-Sm+Ԉfy1zwP[i %%a4V/I-/K+r)47"TU@Q7)k J07UxHw#^UÓ{n4/I B8zIL}ue 2+ԋ _~?X%%x&Ap!rCX(jNf:#ת~#O1{Zǃm^l3nTmA nb l .هٺ0K29R$9*$L˘orV&y$ }Yl߈D |NQgl"Wc{#HAxQPDMBBf_}Mz{"-#K-oDڐfMA:CHRI(CA Xdl(pԂ2Л ;DG@]]}*$ύkjV6֌#He6\\/E/"_pB2gIݲwAbm| h746|]w6W$zmW hr96_c%W{%y*֏D)Z*-֖ r8& "o+9V^a&3'阂mg 6WsW+z.MINr$.كBY_Mk(  [G,s[zʠXm;~ѐRV1?aϳL $hu "-~{1 t k;sTdtC;,-FU2 y 2%^| . pDA0k B1,(t|ٯCpI7:jktA:l#$e_rD$4cRLAM0Tԉ;ÎAhR1a을wdCc IRz7e [iCrEfmp;!BHGH%"A~h RS`E=hyI}8R.'qj}{2؉G;G,2B9?6K'C]_e˱ û&.*u "fr(|x#U+@^_/\墯hw38WxDWb.%u*Q+]k)jM3u6m X@*|&|=v#M3 $>-rBR| ]|rBd 7: Z7Y_'l6Wz#}-FۦRѕ]S pQkRQciOD=T.!RSˆpz?mS 1vje Otj9%}FT5ylmxaRJnʷlS*\mк_'-ek.]ObIFrS_qUD Rչ1R5LDH!Nbb$MK&8zew@)ˊr.0J=LۻD8U` ueysF-9Owwѩ7z~P:ՠL̝tj ˖6II)jiFF*h/y:/qRŋy K'/;0c] ~#b)1!pJdZz߆G_b$5ә$$gzpiɨk~}S,`j-ˍ;1\K\tDC;0>+\&')m-[YSfN>(AÀyh?5ޔrm2{tLSW*vI$]2ULz,`|>E~R6|Y,SC"]Lsam7[Ck.y]\aGllv܄'ix.ih /Zua:$qƫ6*\O;Cx]O{^Gv2m[KG&+Y^zz Pqxm.%^yo,ҡ]DY3z"&UWq/Xqv&__Ɨ[SzrN]n3˃8[t%RhّC+;8AV%a Z r bW,)iʹr'`#n@ZWXs0]~`2dz+Qb)۫2am5]IJ[WQ_ѝ=*rR aw$Z>)sr~E]&|{%9tC!SAFjݺbC%ޢHNв"~H̄f4!?(K Է ^TߠFAMJ~˫ l;Dc i_e8`(A%  .ra_W_Wةs5+0tG^Lwx،*7ABE&%c%۾$l%i>g8$ℰa wlj3yн|A?U #ZBNJt5_y58p7\۬ NKmh`-|wPE)gдq߾00o 81(˕e,C/iUc%nV,%Vd.sd `TG횁Lj.fYnGU*mR²J8z^T`&]*gob~Zz}b TEϥD۲|)cC=\^Mn<$pс}0V"E6%|mgIOM4;i@9bjY_Mx\# }Xw) C,ƪCPY9eyqf'Z{(%е{d''lSrيw1$ي#XZh c`Ehpzlx~ڣÓ!(|8r^ɍ$61gf)%q1d{w/\mMZxGrqDKk}owwvDϣj(l7["2^G#¬|$T95aje3y(>h#~/ -m *p6/=A?^_[uCAcC`x"qNXtOi `'Ȍ8'@~) kN;똠ޱx_|N$r˨$.?#IlxKeub1u⧮$ }O/}uc)lfEF0J ic5ˤ$YAzz}t~Q.G/Uաk›W!IYc:$g}xko.jnb /*z_[dT:ꗢ(^50*O)&Y&XCCc85Q;!W2W,8 Ss n7M//Z0u[ SNIs߹Mƽ{Rxʬ:Ö6?oH-Jbe+xϧ$Wv-q8*TenmuFcS3**E-A&Yz+qL!3-217l9-B Aʾң5l~I2YdU猔X NnאY*E8L&*Ek4KsҢU.A 7+ނ:"늒2SW6@C@0[z Lp+dl" z(U&*9ƶ4O1({{j3o.4Yzsj,,LiN9|;?kXr\S]@aY㪱) 8oA {-$4Z?iU9|510nd*t2*OFu9H $^1M ;ףYMDyA فRϾ}AGmIHl:{y"P90P,ZS/>ؓ =3& 㿻^Odw632ǤH:k&̗'W88|7$tpsI  T( E5GYp#ġ&?k4q^1Z5[~(ߟ6YxEB=NrPóE| 1rR^A}I2^e A1>G}B^~ JG3/БdjkwIה@? txz$Fm7q'}'N`D$ ,ܻܮK&7Qn!#vIvrK3A0W7#[ctھ_S6_}EgښFhKviC>+8lЇ%_7VBNs_^fnͦkG\aYt}g,B6KӀH_%͝ I*=s-snT(eY>]d AAn໫辇W43w~QZПዱOSӔԦd0! Gȴ0CW3#yfpdU2Y7Tٰ  yR`%-E"Nb ko3+0K{f@+*?8}(/1XD2;ՑFQXgַ`#G:#P9^S=@'ocD;8;ayAkF:'dn_>Dum[fd+V̊m#9_V6B-R9ȷV^ʢ*ޏD&M5^9ʍæ9\~PTygQW8_3Ƶo۲A98C>#]5o@=eX'g^[DxHN5ƔYZy5;T1i+l)" eo*Xr |+)Ze#8ђ rk$R Q▂m̳9j(2*0:cpfm:QNWgDpv,/ԮC(L1 IG* y&o+E8A#U]11Xzڞ3\WlXl xW,h[wCI䒪 poXع6u 7v%᳔g Mn.n2$x40qBFjFါ/-"u{obXnd.*A. sS1:$/+ʸ"]p_S^ !wD Ҙ?-\/Vz٬IʯcP]^h]"wMS%PF,#b0).#>j?;d^:ԒO<-_ ԉHm5o)iL@g ȯ? %'y𼸤VkڇK_/gEf Ȗ g$CJxC[lVʾQN _;| ޸ArSezF^i&??5U"i~9VјI6i{Gi'c|lW;>'EIeC.jiR+zEg415{fDH U%FֵEJ|cHɲ8Ld HJx:av9?UDRR pgT-֣k%n#C=r`mώB%V=d51?|Z:+OVV.LHR#btт]"kvʤts xc?(e>[^syo߄((﹉] _hգJ7,DQY]`!,qaB'P>aK|/:3 K GQ]~P^m?a\lAR4>0GKMhDڸ5n~'_r>2#rh7߇I4=='`11C=mN @Uݦ1rk]O6myFzD>k.ϸ@o?pTUW`~_Bh`JJmLlFT9bv+d2-n:h %Ц~i@h'(It돭ϻ¸| FV~#iʍ@cT+B ㈜#ԩo>]N nBp$bl= ((>;Vڽ7y\ S?Ah' :r_M ޢԦ>37A+8 |ŨTU.U0?3F3H5?;V \ s"JeԼ뻪`G]0?K-3 (-au8 `5 UcN@|zSNR0aC#aW#Y3+8+dt\Dd!1{d:n!,@5o\T2۩׹)S?\]puX^2Җ0U'?qߪ?:h2~ٶ9r$KZ0ǥ]yY0: 4@ פ#=Q!K 4MDشk\ͬn~L/Lm+D؁mS/K|Ki;~F3^* %'$)w]HkᏙ0HY Vp8q t \Eh[jSLLڙMG%͎Hnn_" =%i-.CHI@ 1ubDl@+6ش>U{'tdrAo 520?‚!a^Aƕ/<`^}јRv;vRrRR|SԦA>xWgdnmWGC_zW3J&*TW" P u"BNb_%TΪWZGaxYαWv[2I'M3A@ygPB,S+!-<(Z2(x ]6"4GIYvW(08G;&ģCl4(CWm*F}.+\z+ '( lOdVkxRp2(y8V+"V_w;4,Y學pO(fبR"eRۦNhCy?C>1eӷdY},l qn uz qAJ\9F }h2Ctro26]Ț:k >=8XmHeRGwWƑ*7& iZ3FvpK7A^3Ll3#0%tb_+}Wfh@`hYyBGg|[T"L3PDf$FVՆ_y@SfBZs37͍xQ@/UÎ nAM$ jp]{MQҬ5'&X%鬮睁cڌZ2&n'eID- [53q-nam%1=9qZsө xcKIW`t.H |JSQ'Ԣ""$8" mn=#_ 5d& P XcóXS}M:9f6.0l*+T?\~o\@js$hɦ|{$ 9*/q!\L )m԰99Q2oX1Ӓ5liWy1ދeQMXhC N۽ lm}C\|/?kC߰SKGsU?w'ʵ"?߱eK![PwmP8mx=4YKeoiُfII&x~])v~bHEJ7.L!`lrù9 (80?_VSq nd C8vi^ܢ 7/v^76|@s\GS_x+ǡ$fSz&=ن\[T @+aggH!z<H.; 2ny B4;!L E3ޟB.In`bGaDr]h$֕OWe=a.q %R#DY !#i#V>f3)'&G'2ʼ?P[XJIm4w!&˴zXO$(@؏CUO4-2xdVf #6S[XOw8I9(!kBjcqDC+߄*Bx#w$N .q/,ѠL7_tj㳊--[9$v*Uk1Wf=_D`pa9hj{Yȝ#9bZ^+86&:T /O#LD [ ffnL !}@ !L9c`/nvlxV԰̒ǟOfG*h]/lwsXi<wc֢:B4~rV BÎ2]y#q>iR0r_6%/5P7 Ъ\XirN?)ig"`u@Vr^ZV>;%H]и/El-pˢĕ&'-C--mtѱ3'o=!_l [-R+d6w2܇5*ULcQ~0mu8i@j{ɫOzuKQ'rԗcy/p= A B6Ԥ 9 fMIG0#"T?}4?x96KB0-iB(&WA8ѸbM5p\'+l1yDJ_:\X|m=]50H NMy/hS^EMKP4"B޹ 0 $2ǿ;d}$ **FA;Q]4jEyWJ {N 6,rr\ H餉j\JMcʳΝz{=S*"uXj|矆ߺ54$x([uHl+LGՠn c>Cb5W^ ?T;brS נ4L1Ti74̩ڃR>-l3M ?,6-@mn*T|^D 붶> stream xڴuX[߶.KqP)KR\Zݵxos9'Ox11\EI $fbM\YYl@6  l a es  r+-f^ET 5GPqt3AV6 wqG'/+kLL#Lm=\mm9"hf kS;K%@TTSH)k999W-Ҍ Q% IH rxߊ𯻢$+5X Wi6.Zk0؉h :XOb x@4⽝`kп9I_JV;S{#c 4֦*(Mm SwC)`Y@@oV4] ||M=sL\Go\m\X؁VwlEd$5މ x |.+/坤U"m{.^m=|oo-ܜ5be!,3in7?l 4sXoH> ?[BbXؘ߉>,HDut ~UE}J- K$f%G;!h%fgdjϖ mZi]MCg*e P[euXj(w澟>6wIinrup7?J~߂* k1t0wqqrL]\LXީ a}gw`w?YYX̠ؿD6^ͿevyvYYC0 G+S;ЖKCYh Ҷx?)Ss?T-&`bg_X99|Ο'-~ 2GZYt4V'Y4]K < #5N/K.lȦ.vT3K tCkْR5BUdOяMRtP3([q9DKn)lvkb+)@sT1m & u֣d shyc+B?gRaLΩ {2DiC\W.+]RMMO $[cۡuӜN|ITHU,7T•~-Kul?B_ב}by -  0Fĸ= hۢO`9%k" ֛#{7|3A%Bظ<ڑxW `Za\~ 50q aCp4dO *ѯ=}soR!aa.JZA3Y]JA82" oÌ9v횟gJHH"syhÃ| s>ivhDhJBF!i:#5rQ7vP7p?A~Lq,[|d/cBDz`"ޓİr9@^FSL`.\4eD;iق `k_C`Rc}5ns,0A"GOǧt(X;/!{i%+uR_ݕ0[TCKLj~YUl?K!Qȡe8>ڵOZqg0pBC7bM1 <>u_R3 *33GfIvx_lpZU^R=K/.qiWG .ʻcZۈ?ߕ3PҪYg?IRd.m4JL;&brI1* 8&njfn)851aPl鼫U.2*9wL.@,A<!i7Jʹ,IHEV8Fv6 ``uϞϦ>h"'BI6O<^z0T9f5VW%ݔ 3 秔gsSQN`z"'/$A;&߭Hj47hnH4.eM삟Maa5n`$X>3|0TxU"w.*.H=)=d$@o-Ym7j}&ʂ9Z(]ߎ{XMULEoV6 ' ve 7~b<+i)7e8zhQ<*BN0;oy|*vsU?> fh n>at[S8sX>•x _3'?N.BO&ynnbfmeUIzJSea!EVVID7K|MoPE7Csu#3` (dbY/$ /ٕdΌ ^uF?>Sa7su !';5+FŏUTPɟ,tonv ɉT; !dcڔ6H¼_VX(Uqn)V;>W!8/)cc)::N`}aLxZ/8U/X}fk}5쌎(#u>"߯O<*"Lt7B{+*^bH:h\MwQJZArM0/1sVOj߭3X5Tuh(َCxm g,Q,aMKNڼU< SnztKZ#2<( %=?+Sxk"ڪLBg2WD=,%|j.dg[`ΥyMuIkJc BR|NtOֻ򧆒'A=OKla`0 >BT&=%,4$}[9fnOj91T,AfvV>t5~_,uJZ6Jj :#a ~3p-WV?3噜t;qxNSw+m*U[PٺV({ạו$uu_݉,)$+(e+ղ:W#+B۵ 2=m_cf1O894y!~ j"qx-B);^Hhv8xIkfJqШ{߭MiĬȬn~*J]ǣ}=v[W,%i0G6 !l[#|x\2iţsY!76}檁rp/KO;R;@㈏34Mqy=o(1e"j9c CW;pMl5eI5@("CocՕ`X/dM`⮟/&x@f[,%Ʒ?=a..81]fgHpeZ-lP}h^V!uI +(#o@y}n~|"rR 5t +zi<-I'`_v 5#Ц7\`+L_kVaIOh9mb[E'X(RO Aɞ%oI=f^aU_<@S!wۀ/qWyqMi/OV5s}%C۹P\{bAX0YbxJ;H {20eAŽ%0YEr۲t̓1AO0Lu}jI "4ft8Xe0.&_kdp2MPV3 w2sbWYT.zRίLe]1t!{EpNPz7H \.oK!$%̪y*U)$PӸڱ;}-F|/As|˯;\r"X蒩φ.HV J{̀(/t,G귎vfJۭ *J궽&39d q;b@oBٝwaMOqd<j|B щ]R~[|xE fHnMٍM\ΖG"bҳ m z #Gi i 6Dg,ei =cbZkeVPӞR=2v \1ظdS+hZ8|*:2\(JlLFG8:Ӯv#n"o?oP\SY)}}"u_u ܐHE'ϩKB} do5rWS1a9 \eܼ%N~R)kj2A@^x29,O݆G2gIDŽo7)c*{IJ[`\AG ܠ1Q|( 9Kj&Tñ"+ڒ8t XRp%$t24}|V09A8ϔX'xHi= raG(E#ٟ#1fDb=ϰcRsDPyNy*ڸsL#+o Ze4%L* g*`Wcs<%* r'<_a=1Q]&5u z^.a2l}v*l3.jfUIPVonkIQ2c5Ddz€@*v;E*?:"nɔs[eӅ[$˷ǣ~;:C-8&QEo=jKuEc\H%SUnBwӏS%CnvMg'/e֚jX XӦƇǖ܈ϔ•G9PrJ,xebTϧƧ xt^@q(d&#M[\˨~d='څgA1aqČ7<P3H2~[nf;D|8/\|A DΖ4y21$2f#9Vl)VoaJm:֫c&N< eqyz]wth6CsldpCW:)r.A05x{q]/ԕdO?dXinwkM 6Ç+&Ē4V%~r*|Gt'p2p$Gq0.So:!~RAb{)st ojHR໬۾Y &T: ~Z cyj = l~;C,iKȇ}PVXY~w  [Jnmq[_>nq.BC."dgn{MdFmeV{̃nYF|Ơ^ `Ivo)[gg dqe ECu[_ԕ~m m^9@<+]VG#o'ZPXRg!mj {H"u{B4Qi=sS!0U?_*RCc$ix|LwmFnOχuK}A$}ubc9,ۦp)عEf3/7M-z rt^(Zn_FhJygq넲$܆I~5WcYj {mpCL/7/C걭0O<5%Ȃ((p+GO$l%C1h6<2 ?h2%PRuAVC2`+!Һ/ /~/'_/>1KY[lW9tHTZ:;܈=ֱ-U8.MӀQb$ꍒ?(SE?Z.97ۍU=^rUi奧];hmw*BU[0DuzB;SDmF#Nɪ'^Ivړ})-/('̓T\&΄l`CKbQkUt3ćsy]Dњ L*I \|Dy "9S(  Ԗ XC}PZf|SEaUloJ3|=[3.l)]Ţ#1<2"1ȷ/d԰/?M O5~ Gr,yz!gnŝaQ<3! r8e>%eG%z.o;H}g^zGW 5/T0y~;<(^0QXI-wij\wB,ZiFNQ~Z*R}fEu>&m$RsVgŒDbmEU7ɗ5ؔb :6o)'Y2 *M#C_JG-*Emee1IqwӲ]ҊOwI-yewUp:O&w:hK^,m*ˎ!}ō)|0>eSG+xΝRrl? zH>ѽ+D',n׋O7}!Vڡ*7䧮Sa û Fʤ?K`y@|#7B276]󽫠d[ܬ-׽ Y 꽋E;zGh0c&~Kg5ssF,o$o8DzuyƋ;d⯛ijEg:s3!AY| 4@bg2ݾ\r1]j~tR4ݤZJ'(9*/YuٖJi eaq;ۃSV{"%Ұwddc804~.`tPUt|(LB*ԷƑ":]Kw8J$" HC' %<9!r]pmec(o)"c7 Z:FlXBgҨ1@=f.hX5$r٨lF,51U ZyLL=tӟIӉ.Qmn$'L('Rk`Fx%E*L2_5dhtÃgϐu|Nw\r[N XZULsH#hOalA+L  Ulާk*}5aY_9>XX5j'Q1r]G7jAZh]L/˷dl};; ǗMG+"z\Ώ~kշ:neJNwe6'w kMPɉq7RVPs0_nؾm{UkV tlgGUnoo6|cۛjCQ:BlX:ҾduhZŷTιJgdE9 \7]C#yT :n~5.u(h4 e:an&Dϡ"ۙЏoqire`)ahY[MwU/ui} rQR:du&4}: )u5ɂrkZ~fpOxlQ?,bY ;h0,Π;:$gHwɠP`X+>3 Lg_TA;#5|QSƦ:Hv2q_dVUk;u b4Z1?CIg}[ɭ]!qBBxr9ZЩU/ Zrcw Aˍ,:#4oj{izd`xCYjկ='+7Nbfّ@fT/듪͆ʍiQie ·M9ZsgDq$YS5ɘ G;}&b 7l <1LL1;a0jRۿOGM5QwKxޯvYkVgg,YO_X11az0Z Ndt ~~-4˥v;%/+ :s͊ō5za\ZC.*k"(|i7o ,O 43$ )ѧ̱a1o&E^=J$jJ^ebh.ݴBj6r8B}8]q+Vӏa-ۻZR{Έ^$j[&t8^/dCXx3n.q;wcb6` >&#J4y:b\Ȗe6Jyrjڐy `r2W .n E^+A)WPa`]N|s1(`"e[x õVv Lю9-RczBaĈ$ҷ1 ?^ u}~[thQvk,֔=\ MPu֧ xXIo5o}7_- lQ'ԟ'Ӻ֯HW2fP OTSƄw.9huO%U?>śf;*[շiU0WL9w^JB*on\(u^z/c03q9Yir2**ѽ\ΝN+aGg~ZYo;S\c%zIK97 bP!qguP-E:nM|MY,PgRa89_:ؗ$e?{9cdC3قi,Fyac)3]f( jvТhC_2Y(;|>/Pwn:1o(*D83zpNbI!9[LAvqa;Ta;軙R`N{xe [XE,&s=ڵt.QxR#a7-/8J^8HZK|GZTtlIWq7Tc*!9gORfH;lG(0$ѡrh7d?/b㭚 <=\ATF%Jך@tʹxFq/Va3ʐO/[i,ik4:dOm;2絽$V] R%Y m '{ykL1NXx_( KqZC6P$ $dXU^I[ä6JPάyҘ\ 2;< @h]b":4#:8r$@d^uMx͋[|`Ϣ/8jԤ=Mj]ڎ9|;.א*DF('Tbyb$T~(;;ơ Km6{?bf6 O|}·4)^ P2nVUQUm UDZ8Ympp/KE2m=* ' ّM  @=ČuZ8᳠ը|y=} UvC#y>PC×U9[˥ QO`;bk\dR|ݛħ[p\4jA SBu*\pfwaqE=kw/Pgkݵ, .hhHo#`%p9jNJO-G.I8r&S朩0 hؚL?i {d>!#Gޗ2r>nCۀLYT*(}zDMݾ}{bO=܅+?Hhai,Kҁ GVgQ4\)%>X5٥w{!uaOѓ ]\]E7Oú~7~=2 mny֫ye܉@Q2 @RL0}gsSr>^ YU:'Pr\D o7ߪ6^ g%8:B-ʁc#_ 𣍮(ōI]}|#NNe[Wٔ$nιneb't5W§LD)/#֗Թl*.We޴m4Ό{6ӛ(a&Ҿ23u%l5A‹]'hNhD\q^zʂWAR%i18\SKa#XZ}^£ ͺ q7e0gEn[TZy!Ϥ :ޣ|VWXbc }{šq9{j粗ZAMʮ]PwDD;'KpvGW)dC6į )ψ(~i?uƏF{zGKmξj2_^9P1b&D1ObX| m90*څ A#MZMEAOkl6r3TI)FT!kv, /v, +0OWsEɊ}<{ j$bs^kTHC2.>:bQ\ArA_:63Sי׭þY]nB@L}ƹR ;_Y}!@sj*vаivCBetj(%LGbѺ9Ahj+@cD/<,1=dWp2#d7h !BÌ+kpUέUc7EiMq Dជ"|㷓됯P 5^|[=@/l͖ S)QEe-?vnv6}B3rˑ".3V`f@AK{3d^Mj|{iփ N%ɄLYL)o Gi.m[t0q:"qT685 j )6 pr:+ g]nLS}U#wy:w!P.1b/c< M{bETDjʼn8 ad0s5HԳúgkPWIS2xp6D΃W (*a3J͎†+ˈZoeSD>ֈoJD=Qh6߼W5eY ٍJGY[B.%rYp>sbI"̢P^7e?zNW6m 9lMǡhHN[M;>mߏv[O$vv# È)Eeڇ/ ݣ ރ1WqKH~ׄ&-5EG :IQz隷&^C=b/T#ךh2%w/׫z饬!hQ8 NBGw[)H/9My53]R,޶}-q==Liܯu,|jE0*/%|KJzq%C-x}O{m8g Jedf_ ohS_Р(IL<Νϊ#ukq# gd9QqAzO#pЩ-l~œ.SxkBxew-K!Pn]È vW^^t@+O,啯)pP І(S( o2Vo %ړjbl 3`)]JV|O i V;+g阿~nqR@z( F OPFs.{ ;|h Geнк`D#L8|ط6*駜t ӵ$xs]eK[!00x\.}hPyy6oO I fV5Dya\/5:TdD@\v v9@PgtfQp:#PEe&B?l*H~<6GP=ELqO)߇i.* =i*48\TUkh@W;p z?oJA$Hx/A]7YV 0L굉D;~E>ڊY J!vi T;Y ) if<{Z71YYل-Q9t+@j¼bo;oux=(b*lY˺Qju2zHyt(fр*ucY";ö$N\ȓRu!xjX=d&Ƀ7V:\jW hGbdw1_)j{'0o%jEWCxBvҶGQb+iUԴWp;䙆#CF]uK[uw"6o:omB5%m,뵄8Xtj3S2*ɀN`RlQU" Z cziYW ff0\wuaD%y76о{_`J]πO ?iI8c DbB'K<2Ċ#Z+TЏs'>~q:@!%Y!\wM#ZTtw1?fs`Hg<}:U>#AT&Elwv1'rYݒ%L5@9H4~[ KOp{wb<buyEx@[pkzv;,"=|;OG ިzlZR/J.Fsş[p,}ba ]ófaGT<{JZLOMW]f P!AOv_)K] yj}AW6'@- B޿:y\^{t!HB\ #3h1QfvdD6~i@C([d=tIdPBv#b^s;py>ّaBa›8`p[ z؝CS[5*G;( fpl<*sJIbC 1[ pSb i&偟sdfI!wi* Z5b@%t !Kux+45YǍJ=ToJoK{_!"rEcVk7H Wj̚6M @͍g-@a7ߝ-M+М=ƢYvi9 4Jv9$ue\EoſwmFhYEr<{Gabt>h,[\:#&^?Ȗs<$bl"^Y=O&Z6sjtH3n/~Y; 4Ë"=1s_7%ØI(d4c]Q"/w-f3|h˟M6Fé u2"E{ؤPrPK >@CDа6T+q &LXNX!UӂLuBx$Ń|MHNhd_(?#6[2nrn-og#RX&faGfg,J[QxNYjH$NeN=F!.ҁ6pVFa"N$}xuw%O4p`"xFgH8$vs~QEWVA_Aԃ" Ťӫй?M\eLNԢk`Yu8p|Fq'Bi0Gvy7:Be8Ъ.,D6yQ\;mv/2T8a15UwR[H=Β{Z>k-}M) pyG09RQlnɼlJ&߂-Q{U)Vma6]JANQ~Sa*ؗi~t܀uX0,V|DɈEl|؆cE|Mϗ$ҹyqf[hCO':j<ݑRtbȲ`u^RaX'-ۢ iC17܀#;e/7Rw+"c]}#΂@9w6 j/{ 3jFW堈]st{6"3]ؔ xwpTEȨ^jWn]"x MKL7)V[)M*?=<5Sɦ @+.TG>6 endstream endobj 118 0 obj << /Length1 1608 /Length2 8278 /Length3 0 /Length 9098 /Filter /FlateDecode >> stream xڭteTђ- 4n݂{7X#K @ Xw'>;3w}kJή]:*u-6I $qqs TnZNlR ɇFG' !N2P@Ȁ.AAA4:4lc 0h1'`n`'ˏr@j@-` v U:yn(@Nn &5`q%9/@^V ?!V3l\-/3B`'+w/~k_Bή Ǘ : f v^'% Xd!VZ{yB-Nn( %9;Xx~svv'V+rs{y3 o[8;;x= _P75;KM+KmǟEQt8;gw@v酄 8T!З> [_5ozZAe^^72Z8Mx͋p^ :je px_vhw6.>iۂ _oW/!#'#,ա/?RR//SqyziX@]^9?-u Zrwu}Qmi?Ky!Vav3ӡՄ2F=]\Οk *!Vƅ72o u80ti ^o` 0~{2`ϩ6iZD>rrDQO{`V }C@b&)KN<*a@>U2ѓR(;)|ʪgaKT(JUR[q&x aìuÀ O-)BKd: Lj::R>$>khݯ x8Wi^>tt2TJyt_'S>ޤ8:Lի +OmW8:Dm$Uo+!Ab8`.MМU6s68}lzM6orDtjO(CG(UЫg&y/ʹ':`6'gHBψιd /\SDIx7fI YGpDXElB` <4wm"O1Uàe vGke5|ܯbKazE5 #ƅ37եR#e:k=lFNg<ǃ)%dWdRr$R9ܰ6w 84W#yFJyZȻ;[=K?Ez.-$ w# n$x]*T=5G9tW x"X?x(Nb&2M!?-jT̛>d+գH$´4D#gi'yn̻4+JQz>|P1.{n~{X;u?$ }<^-K "SDt=blo܉.{YsYm_W(6u%R[H?ȗ/0Vt\~4^>;o_H<γDIqzAtVpWMvmIW}L1y~p5 WGZS7y tOws,T.&s %҉5=㭈_M_VU7l3Ա<4놴bSR}n/kj*%<~4|6<=JؚJ&C6{ҾJz%@ D@IU#fSN_>[MN I&igTn5 I=$JO+l@(#DƯ1#F 9:)Ц [V)P?e$9?EEJl#y>W%)e_RFk~ ]4Mǵq2ixE{QnQxoY:f7VȇVMĵVG3PI sstxar2$nQ/BŎLF.%x{W{wH@شolngW&ΗGր EI>iأUwK<0Vk}~Ev M HVmaKM YP@ EtǤ,pI'CB=yAZ.UX 2/2!6 ?A" Wqu7L-*Ve^7y!QU(Q!<?q[݄&z(S1ȭL_G=8ڏEI8PNQrʗ[6Arpɽ[oL[I">9nn|HnCIK"G瓞\G|^8/(MJ@Ç:p@EH`}$z#""3禤'%aqWf K˒'DKANV_YdmpLa'ڄoϛ:\e^|Jj;8Olc5#ʄي|t2eGsghwY˘wf}^zQ|k"tch,gIyp*` D|28n+;l~x#r&TGn]t+Q03̋碷A͐#i@!:Z8O_MjYڪǤfQdL7FdHz*pBgJwʆI#%}Eec ':x Zaci8.fUhߦ}^A>>`\ ̶9]B?xT'3ӱxaLU!B;.<)D8J x5Q:'`[3"!YB9}a7ۂSV/Sh̪e4zv$P874&И9M#Ry2e"jAڹ6φro2+g%>×>h{50z}CF@a v.5k\ oHkbBD×*aQʭ V}ɛY\ gT`&4EL7B~})^e }FJ4\'n6eBnOfٓs+F 0PُIOhFyEi7\won>ɽ:<pT䯩pLAb}o_.&9b0LcV9o9a%Jl6{2[X{KV3A]&@+7ZΚFo;Wաk>E^ =.zԼl!fۏ ?[)&g[^P}ͺU66\@ŇtPf, @`\-^G<OU`L{?!iGڹ=~Xiԫ "%j5nh7sA (i.&qW\SiV~xBBr):Pcu%~i:$Q% FZF`e_1[y]Omu=~w.Wz^`ms&Kd^e' F`y)2_ .͆Xh7Zˍh)R$C&a>++T U vd+ E&h eA~$@2_)ϓ%? -nQp hKSO g\2R3?ϼp1c)J禘:Kzs.3;bɾMe笹^‰Ϫ-Ln95-gmܶpp\ĂQ9gKߕ]FW3& Ⱦ'oQwI-hR -B65<"]fa.pV?IoHE>i^bv5<'ƅ ^=Y^U7b\*i$߄-yc͝&P~67_%w߈dq 4wsn{Ȉ/֓8?ܗ:-&h$E9l>u4I5{@o Efχ0z4-*r^D(6v_-~'Yc!ZZTW,3N3}۽^I~`5?3z3CEӷPN 3y*NaX,Ƹua-+'3My)Lo^=5gaKɿϬ{?,cuG6)18<-05s>u}/RIk)hY ͆\>۸X !̥@Z0 Jβ˫*Q O<#c\R:ݙ LOੌ Rx־kzrXzژniVm`/c_I{R!q2*κ+va#t'@͜@ُqcw'G5 WS`.-wFXWAm&`M̴ȢEʪfp3BXtq`ʬZh%Ѷ߰E0""L 0tcZ9IyEFw_|4;jDZH.tY?Dː8}1^m/q41,r8\vK*hXTpUuOlpn3`aCLf>=E0%1N738Z18NW.R BS^ -v Ʈ CϾۭ;'mї(t|L\*uG ~=~AJD/dIȴπGh5I#nyN>$x`h1*C*tP('8gWuK Mt |AIUAA6S ͜.ÅPIܦY{g0Ykx7 #2E28oتQF5w  &!i[syb Uϱ4Kt՘Sլ#d(U4qyTy ZÒH3*Mh'-yAzJ<#GzQznK\s )YmoF ե[T^ӣPѨ8o Zoyz0\;$l]dLYLtצ6B!EY.2Ah%ًQ_4>K3]*rZ?SYï i?)Q3+T154.dW?K֛+MV/ĔK12"(ʣ.eM =hX [r?^/`L`m?Oen2pTBiW\%ox*\WP ŶR׋,nl:}:^YÀk*%p$n,JsDk|j W"VHĦ~YҴ(V)xw#P21+nD|ٓt@%~ ⾶q+jh#Z:&1@^dӎ o&h":gp^waOTܓM",u0G) 2n[[a3Q= xlX44Μf%Fy̱HeVMoUGU5Q*xщwڔNwNF.Srn$R@ jW|͝٦8b1pٛG aSy5ͨ\Z t簜%GeTZ\E@B*NýGZĹ[&a}8g/v |L8Xbu9t-m+:WK*og2׺jפ:ώH a1;aa*-Zj OBK!徟߾38UJbr@,z7wpUQ[j[(hku6D4S!i믏R? Q1dNy͑!6РHT?ɳfpwD 7xicZHWvlndoZ&33NG0@}L dg7ud+!K GD-l^іV4uWuLrjJʴ6b`Ch>dAFh9GҾkd3glLUwdѿ~<2 .׾ n8M|U"Ch-{enP3QjϵO7JT+*_p> ]2iI Mi)glx8L-Ꞽɢ 4ea΋2j`*<k@ǧ}nf!IGE8q~[ojj[D>gy|_>毐gSYaUܛ"Cn?lI+9`nV\%ǡZ .FcX2m4Uq ?NT |Hs;q_h7@+&z~^w}褯Q,D-}iT.|ds-i ;df*;yE*Ç,%U4(q j}n۷f(r8TsLٔkƤ(a>bיCrS.7I5Sz굼N|'8c*f}a)& +K)T(7b !W&D,mh]bIyďꊒgY<6sJyc5Hָ$p'bJ!_ j]~&$4oB4; *X+y7YJQ+Ziu$-ܱ!azSL*$|XO 8XaB88,OŝtL\N%߻qus89t>>% sQn&m]0]f tLM88!ss OXH#ed!#S$f# 7hCu4_l-wUsY(UdU&awT;8xZ 4NGv@ &f%BHX"e ">T3<5PlJ6QPt}6"VG.X埚wg=<*tT E׹Z<$i$ߖb\J^t;E>JCdyHwPSz^h+e!0;iVU hVK}!L!f奪6>.o}mLлZQP'dNj d<1H{֣΀Oz /ߏ~mIG%( Ϡ#,`@stDp|GbrY>l6Ԯ9&g(q2@,vl?}δ5?d=qiͻ>7t2-E&*p5ީxsx!"u+րJ\r2< ~r6O X__H&ц 38Ͻpmj,9?IR@{'nG.MZ>9jf VP&JL__}|ϦB4»@0=%$I,pp^2ѭHD8S+@k'O6i,(#m C\G> stream xuSu\ۺAJ fR)`pfI)ADB@:[.AZBw}>?]Y\l`D eP7 -hq@q{r..# {@p5{+бGDP(%#ZE Dd(`PpĸA$ hA*ϬUuv >15 p_-ڻA:zF_Q**+IA@PDJ)WTԷoE߇;!~5W.aX>+"<&qW_-ylp9 ;nP9@Sȟ>t{àpgؿEk@!`}˟7xq}ApF.Pp}?(pG wz\vĠPWギw^xCg&aUa^kâ]GbaB^JRpQ($!gV.XZE&ӛZQL߄te(xG^0Rg+92RPid=t#aS$4iȞ#V5kHD*Ńu~іܴ<٭B%8IQul^$):&rP] ?:g r߽ J Ԍ#n3ds[x(v;^ыE9mR啹Aig똰^ I[ 랪UZ{(O Gm7x.(*'_cG l-J ͺ1boshM,_r7ŴzV*!k^}}9 y mWOa00/RR5z9n/§/qaVtǝm[NF"xn!`0oh1/"sRt[|-m5Uxdip>MvEuh!1A45/W.pe+a"#A?@=zP1W,T2NTF*-:QW:cM;e\ݐ4yXO|t3k5\/wǖO 55IU)d֧r*!n\qK=dKޮ,}`mEUtp{eBJ ]$X\ZEu7]ȺAwܳ;ə UtO 6!9MtJE<%g=DoXe}66b2挰f1JK3ֿ%U1E6>_[*ܯ5A"txY }SQS#'!@Xaw<ӊ,@~j.i~O>Hc lbWOQdžs>vx Rߔy_RBsݩM L$岖z!{-xst!904䭠oo4ҋFsybŒu5U>Vl\b.{)䘐KVsnjTPCD~Z<3J*\IR-98pk×뭙Bs2x-vzG7a@Ay `/g"4Q!#*1&+%}E@4ˢߑk{}Vo_SI6l"kEu>[px}OֺolI}Z,򅱁.ǖM;3D^O>q+H~"/dʪ x?0NGG*Sn!>;h fB)'0 ㄕ,cLM&@ Tµf1)Tq4ƫR̉E9KPV/k]Fr7lt.WsXlj3~=MDl{`:wu4d=RsJT0ET?< k% 8q,M6 8!iT^іx&L@BS ߐ}^Q;X5,KO?-'U{+\5CYr}cx|fy?ciMtDFČ3LƾSvQ4KtaIN~=! %`ۣcE0wf52 sۓ2lvG:ì`!4Q*oUo9aҸܩXdًHQK2,ֆ|F=)x.v:En!mlbj$Q%tJ=!lRz*V_awa 2%b!lݒ;GHkNWld1Mf{~|!Pwg eɗ/z}$OOщ(x~IS)2–"cHO~ɴ5yA¹YS><`&_C oZNhա.sxd&}Aw?iD[qԴBvdɔh\ܽO 4ާoƒ}vw.T '߳Vl/-x[פkj YitҭMo"!cgvTpm$R/Vc9 .ȓ‹Zsy5rn ^/JP*r4-;{2 t46l@W]xiu!AѾ {׫PݶL޼$.֙|SCѵ2}ʰ)u$i/|<>i4e]HrVzdCnayffAI%mR0-d^c *;{]}SɨsP Bg=?4:y=@< :k:('D-Yj10D<&pHP%C'>*XD)FҢJ9 !'鸔%Ѻbm6OӦ{9 q0Dtc /N =ou#–d?>!b[b26Ǩv=Y=zpJ1BIɪd4J ]`ق "?-c粦0{V^Ֆf&$mKYO}Xێ:nbk=Ԇ~ӓ'ƱRnDyXzQK ~7FŽ'@|rwp-dKtra& LaTjBD?G%MRؤX)Ck9 ئ% $7/BW?ajy<쵅);O'mAN+V8?"ya:si pm2in%e~6z`i鯹|qdbV'M7Dt۶O֥j#UgiHUYlGf[a*"uL blF\0ź-E[?Q;+tMͦhZgNfga, {S[lYfkLRKփ_hf_z*JN QǜVQ=Z[VkNZG<>O揶r\|?:|٧o9ͮkq |N^QGb֏6:w6Q0i"S11Rw: ;M^YթO[6?*̡ou"zIqqCrޚFoYuZeL2nd Z4SBcMs~a/aN c*,'lc` @;LJYpp=ahv5 zʍw5 NF(vںHr"S^* Ӝ5+D*=_On8<Y%gO<C|yRQĜyZ!]LS0{CfΑZboEMg_ ?%=H1 pVhv׿~J/ғI}2=gq5+`h +\IBM  pQaJȣ,D 5ŭMP`r|IevCev\c߫Gs<ױM^RJO>lv㇞VwxkO{K(S5Ak̞MWTNƍ1ėu|} t :Ԝ5!‰-̌zRYL2.p[k8 vv6g{0N6kg 噂h}ynQNᘓ]g3ym/]-ASVUp@iC wx,ۦgjAO،t@cXOj@6J-n/%Vj.CG~xwB~el֮HK$3{*ț4QbdV$hD0&ԍjVKF #l7SKnWѻ_ ŀD s뇏 tLhii@zIy HQ@vyq˕{7N6^: ;>7~t# |;NCU~@+1Wp@Ŋq<DN rҔfG"1ZUvN*sٍ2 ̅GJz見XNdvb!Cŭ7%_O>B}ulr}(PM=YjXP3_A:Vrh@7.s~,jE*%dMqpA$]pmk|7qHg}&YU endstream endobj 122 0 obj << /Length 696 /Filter /FlateDecode >> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS >_P{=s@dkx;`VY`s4JaQܡn.Uu9\Y6><ٴ.Z.4>Dӗ}~r:-d0VWk,8yLһʮӮђ[*mLr?q 5F8@=@)& 8Rx uD\j2HV0CzL] bctI g$`htы0\F0s jd< I6zg W qȐ+#k .bsrbmXK7ǵH7Gnb>&jؐu1VljOu$՟qWS/%1{\xB!K(hHTЖ枃Jρϯv=k2UKς_:~$/ ~E+7ˢ/ l(/} -+ZXukoԝE?ZKq endstream endobj 123 0 obj << /Length 696 /Filter /FlateDecode >> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS 9_P{=s@dkx;`VY`s4JaQܡn.Uu9\Y6><ٴ.Z.4>Dӗ}~r:-d0VWk,8yLһʮӮђ[*mLr?q 5F8@=@)& 8Rx uD\j2HV0CzL] bctI g$`htы0\F0s jd< I6zg W qȐ+#k .bsrbmXK7ǵH7Gnb>&jؐu1VljOu$՟qWS/%1{\xB!K(hHTЖ枃Jρϯv=k2UKς_:~$/ ~E+7ˢ/ l(/} -+ZXukoԝE?ZK endstream endobj 124 0 obj << /Length 900 /Filter /FlateDecode >> stream xmUMo:W5?$R. d9M eCkmCp;;w~>|3E_?O]5߶w]Occ]=~?}Oyh9%?۹׬B|Ɯ>);vw%g43>\ 6 EJ78 1{~`W(-;]%=xe_,b+-O;q\L}UI--=BKE1p[! Mߊyu>.N5K)Wb٬8i[_uʕMzQ)V(Txޢjy!Z2P="Zd0\ÃGR\).2*Шa!U,H`+j.5Nα@VK-x%3%AYӀzΚ>kP#5m0Woþj.ZT$X/)n)#Wo(oRZ $Kp4Z-b\1ܰJ P"GXQi/8k^Zq:Zs9dB )sL-7xJ`aɽ)f$1 dъcCZC<73JgznHȰYɚTa,_-O87}KԴܗLloK+gJ.GZyVc48Wt]:P~`rZq.n1] S/Pu7Ue:?&?!d&1yHn5)yғBx#1ޞ]Go׏M?X endstream endobj 125 0 obj << /Length 843 /Filter /FlateDecode >> stream xmUMo0+J! ᫊"RVmk N7R$ݪ70W?g_,ɍehܬ=WWU\;;׺v7MOtҺ=po>fv8 | G՗_n}w̭][GL2sQ擾ݾk^!00jYV%H~~v}\; C}h{ϗC`Rރѩc~^ON6[7ݛ ZԲW/{FR^ww?U4H6!L@@B@q\s *G|F/+>㹴3Z~Z83f3[:٭ ߬Lg3t33 ~!>CO!>S 33>IY ?BXIAup*Çq G潪N$p|eO_:q;:'dE_kCvW endstream endobj 126 0 obj << /Length 842 /Filter /FlateDecode >> stream xmUn0CƆ"RVmk N7R$L̛O3 /~\k4~VzhO{|wޝn8O.oN?'uRG]>3dX;ҷ*נ_~vC̵:}W {1Esgq]ߍG@]dbڣH~z~ohTǰ9wxΏU]~NÛ Ju~*6{y~?xڰvtش~>ZjR˦YE3=sׁpuRA)`*R2$!`8li9UEХGSj043`4`4Ý(?Q  rt\e #q5p眛[q>x \iEܰpNMk l4\? 皞c:gN5^ ELOup3%M6`^ۘ1ل150ym 1F}3&ԗ0 bKl+֌>oRa Oѷ`)w`)?\֟agYg ֙P.L(ulgYˉx/N|N|&ٝ N|N'>cv'>7'>S} ~)>_Sϔ+>cR|&L|'a9i0K)cR{XTG5;)NͽRPs> stream xuUMo@Wla_BZXʡIW ld!fm웙7շĶM[؟McpuUӃsk/zfN꺼Ɠfn݅R^w}9qdMoXj_v}EQ>>pø;en>ڲ?`1&5vaj UkNAm<}\MxHM0}Z7WuI]ǽBnz/_ N{y;:ڰox\7nXw.kP^k3^Kյ u/A )`JbD>`2$`TY'``9&Dkx+0*NXXQQ3c w"]j~1F60aG+gıcW c rn q9Qܗ8% DMq.5Sh]`4$a]~9Vk ]8 IncT5obY:socsOPcYB?9Os֙3\Q.4ٰX3Z9#>^Z} ?L[ V|V|oV|3[: } B|)W|L| ,Y a!SMV,鸞:?8C8G潪N$ĸ<ޏ< Nuν_B,u7zl endstream endobj 128 0 obj << /Length 846 /Filter /FlateDecode >> stream xuUMo@Wla_BZXʡMW ldiof<ۻW_W7nzrc7)U7Nߜk]{7+wR}uN7|5s. )裮ݏk&8n~iyQqE0N[,g IM/*D@f`B9xczOpm`>W'9WRzL E]PwWqD`PދoSφ}= imX]ӷn<7̵^y]/׵Il/ܥ: ل0%1 " 0Z{q́0R0r0QK5<T`,if,1L.S5?׃[#M cL#F3X1+N978Nsk`q KpN8q )q4ϮEp O.5Ypc.Y7ь1O*ezl,d mY%0ymȋ,aYʘ8 xA} 3/Y1<*T71މf 97g19w(g1?\֟`g Yg 9LsQ.(ulgYˊx/V|V|&٭ V|N+>cv+>7+>S} ~!>_Sϔ+>cB|&LOr`B,&+jwRP{xᇣI^U E'b\o|s C:].cDܛX=oNܙ endstream endobj 129 0 obj << /Length 845 /Filter /FlateDecode >> stream xuUMo@+H.ȲrhQիԒ ؇6jo73o{q3mfѭVOn/Cf)rtskzf꺼Ɠpi?p>fv8coJ?< a9(})suזÌ\$qATh L}s6G 7o],jotuþ{UןtptZ|MÏѩNN6[7ݫ ZԲWO&suB`ilB =@ )U 9yI(ѥ S*043``MSiv|kiCXc, pDˆzA:x0)ljsn l9u}SrI4"nXCA8%&ٵ6AI cMϱXS_S/w"': fyRy(#c^g!ch"ƨ-kC^d cRx~h K^| МQV14Nd5cY9Y?C9돡'g ?%>O:ShYggΈrYgDg>[bghX|&^V|{ig33qgng3tZ[Yog,g-g B|B|\3gg3?f)O5[TT+&GUP#a#7a/c?w:'dEgtdbP2ڂ endstream endobj 130 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTMk0WhFG*! miʲV6vFrBbތf}\xM}qV'7t羋<]swrո:܉Ǿ-w$mm o\1A+Z7!؛~B?Fߗb n;nX7U{[LG5 @@N,Gw͡ 1}ԿhWWq}QEݹ-r*FNL7uY~~l+l+7tE )b,#TTHy9)9>*QKr7P:MȡQ^s$LD6aȑ*s.$S56`>ƄmÁ#TL 5kd}WXssc*{Rh/#? bE$L|ږ8^y>eSQc̯bV̯cNa'O;Q~{5pX2]$\^snaK??q FqMyc0=) &l(mi,s|d &\cV ]͸&ӈ9w{d :mB Ƈ\..Ա g~n59&\pe[N 8\4<[n6|kq_]~&)a endstream endobj 131 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTMk0WhFG*! miʲVZCcYy#9톅ļ{3񼛤es^7箰 nn8l=hzI-._뫦~^JIu]f `tTsr*o8{&X,dew+mWos~X(2X.EiTz}ܟ^7uY~lVNMєo R.bY.֔O9؄b%9vsr(MXa#D$ar bqMDs!FKRLDP0.BEHQ#͸FuŎ577v}QȕanOd$g;A,əCR;6+ѧx**Ę$90q'oקfQ%n;5pX2]$^q~+s"F!CyhIh~CMnOf1$#h)r~hмj5F̹k#ni<7>Tsa>s\8s&wsaY1:+r1\ut[ZM,k4w6_%aJ endstream endobj 132 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTMk0WhFG*! miʲVZCcYy#9햅ļ{3񸟤e&Oo]&C]]Mq>zwt߉Ǯ)n.pCx?nڽVgx=itO"i [\l\WM}'ԭ̚t4pXeȉeU oq yM\-CnCW_Ey}wP dZz891euB)] W-\v\]~[S!8&+Zce"'2Ɍ5I@|"B2AQhSlLء28a}ɑFq5ҍnnbfǮCG= Wܢe$g;A,:sx l=NOTƘ$0_س/vЧQ%~Zx pX2]$^qnaK??q FqMyc0=) &l(mi,3|d &\c ]͹&ӈ9w{d-tx\ \cΜekqLJs?<@>qhx .׷8wl~1V<*m"mmDa endstream endobj 133 0 obj << /Length 701 /Filter /FlateDecode >> stream xuTn0+Cl m8(zu$:`K$Q4pufn}f)ɻ|tùA<]u6m;O޴\+$ޚv}qff0(h$iƃ}E>.>ttPRJ(:X/rߴu&^!3PZM5^F$o߇7 V+1ؿһ`׮o7qIݞO!Znz/~N̿Z䄦buUWᴫ\k\r-Ve\[3sB A `ehHiJ }*>`!â)dHUA^UwEZK5h"uS/g bρ#)p̹18yi r<ܗ8-pN(T1 PUF9a*~0'ujE5z4jgǺ4QSkj sE8-_ZQY\2=<"NNL>9fѓ@D9{&&gnI0䑱Ӊ3 hxRE"7Yp/hJXCKH eR3ə$Sޛ{cYrwDz~ !G9Kûq_nY3/Bu{XcD~ӺԝE?zO,Fez~ endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 827 /Length 4268 /Filter /FlateDecode >> stream x[[s6~ׯc3L3v\7Ij'MRL;je%$Efu2 ߹Lxf3!t2u&x&ȄʤMgZ2M>3fhRt̜bIbFAn6'd&!cgyfIћG\<~Y\wιw9ݟS1bJŘWT̨սwdryE\n=gwWc(ݺ D5;gbZ07Al5hA<]T/#͙NkhԵZiͳbƹʜ"|ɰk sE ^-n iV3gV#^}&rw1)U23p <;QzACrWdu谧N'Dad4 ŨrR\sQB ~fwYqw8뎋aKƞg kXSrwqp)L%MIĂJ$ELf?Fba =gOsjoX{krp>W^ё Ev6#_ʒrˈnFE̞rx͑lDѹC#mC;AH}q6ؼP -< s%EՑA8XA$6_zi܌χW]b8=Ÿ?ik8~Ck$ֈi8 .QDencoALȑnC*˭lSFV>jS:_$c,eStNe U=PhDUw2c5eTu<qtI.x|-v$y{.=N?28H4rJKE}.=)-vSO|΃LъmB2`6>74[:Xt>?H[r|V{I4͠ICW_6nei+MzvT-";As. BVIaBJE<"j"#gBXр_ 1Dԡ$ 瑹W3CC*ɠɐrVBw  U<Ě15L`EΐBt)N' !oؒIJʳZ(`ZBIXqn; Rm*@NW_tأT5=Ȣ[$8wSdcT&+i0894xHdrisi^LI4ʹR]w<7hMC#DZ)Jq.#E눥QWDbd㌩Ņ9u*Uv_+PC9xϪ)s8r*LJB؞e4gr!D[Bb)G2AcCmt(@21 XCz?++bKwi&P4a;ZmKs+4)Rêa.ߓ $"{BcHԊB1:L .㴓RObS:!zMI@$.}'*LGlq)SM#kT*@)ۂp-c1p T\0*S퟿tHy-Sr:N)0Zu>vfP gWޗcwL'c {wewlʦiIs$ÕͿ~ؓk{>{֬e͌܅zw̜}X+`,A`̀1Zf.6;zv^>Ÿ{NNF;\͚v G'}1'9!^[9_F&_=e'v~T {^װ3X[+{{W'Nz~?n%w{Aq=cZXo4 Qv 1+XŠO]]fcv>_>Cg?ـ Ʉݲ!n/3d#6BO*ڱVP +}倍لMXaMǸE Do4.goSGm]/T/iq3 V^Kѣ8mQa\-s5zwaZoVi{~7(r6}{EbIٛ]> &J^kz.oo~+uQP.ۖ1\j{V)i:ӆ:tfKK bXFWYF/ ,= ~IB7a|S0Swɲ0lutx=k#ʮe{ܝqwz',Y)̽xûs7֞Άe v|nzr˝G߿^&xzSdDŽF0x ̅[] J.z#g0e+{ےm{5Q1ON_9kJ:ij[4E[-Ma6W#U[ I0,%WԟUx [Lseqr'2T̫ӐήT(6Fi%%I BGv#i 1TGCXbdsym>dA4S,v:I+|;)[KGWɔv2҉;V?>"oFo}&ox^YO΋"n\F/#һ#ZYɹBQe`V;ֵTdi U̥趀jucwm /hxxċ@쓲P=`@gX"Vݨ-ݱnz*d_D*]9/ vuHHu]VTH)THHT\ N*Eѻ5?{(/߰-_Lo.fқI 6+=AʳZdgY̫Ql!N#E5<,|I.8YyXG*X|PrTBH,,ɅU==0o\8iB50nN"'+VO<.`z{gx>f'oI/{O#sK$JoU7vܿOUTczBgOo$%ooT [0m&TKoŒ#]jK.I1"up͢OwI&k-}N^v endstream endobj 142 0 obj << /Producer (pdfTeX-1.40.22) /Author()/Title(\376\377\0002)/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20240430235221-04'00') /ModDate (D:20240430235221-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2022/dev/Debian) kpathsea version 6.3.4/dev) >> endobj 141 0 obj << /Type /ObjStm /N 1 /First 6 /Length 97 /Filter /FlateDecode >> stream x341P0ಱ,HUwN,IOHLO-V05Q0P/- CEs\K7?%U?8 51$3?O Ύ (% ` endstream endobj 143 0 obj << /Type /XRef /Index [0 144] /Size 144 /W [1 3 1] /Root 140 0 R /Info 142 0 R /ID [<5D0F548F434041C550A530AC41030AF9> <5D0F548F434041C550A530AC41030AF9>] /Length 388 /Filter /FlateDecode >> stream xNTQmlmED&EFV&evDװqcqa @ .ܐȎk(cCT[JjJNX5x%$*Rߑ x0 9xOa9Z*U>;CP#9Ѽi?KP:i!W !k&܂~hGpZ]@ӐK54yuhyuj0j8t/xuk|ƫGȫW|>>kzk|[1~d{'Wn/ߍ)_=Lhڽcc%G=q endstream endobj startxref 439228 %%EOF genefilter/inst/doc/independent_filtering_plots.R0000644000175100017510000000543714614336164023365 0ustar00biocbuildbiocbuild## ----knitr, echo=FALSE, results="hide"---------------------------------------- library("knitr") opts_chunk$set(tidy=FALSE,dev="png",fig.show="hide", fig.width=4,fig.height=4.5,dpi=240, message=FALSE,error=FALSE,warning=FALSE) ## ----style, eval=TRUE, echo=FALSE, results="asis"-------------------------- BiocStyle:::latex() ## ----setup, echo=FALSE-------------------------------------------------------- options( width = 80 ) ## ----libraries---------------------------------------------------------------- library("genefilter") library("ALL") data("ALL") ## ----sample_data, cache=TRUE-------------------------------------------------- bcell <- grep("^B", as.character(ALL$BT)) moltyp <- which(as.character(ALL$mol.biol) %in% c("NEG", "BCR/ABL")) ALL_bcrneg <- ALL[, intersect(bcell, moltyp)] ALL_bcrneg$mol.biol <- factor(ALL_bcrneg$mol.biol) n1 <- n2 <- 3 set.seed(1969) use <- unlist(tapply(1:ncol(ALL_bcrneg), ALL_bcrneg$mol.biol, sample, n1)) subsample <- ALL_bcrneg[,use] ## ----stats, cache=TRUE-------------------------------------------------------- S <- rowSds( exprs( subsample ) ) temp <- rowttests( subsample, subsample$mol.biol ) d <- temp$dm p <- temp$p.value t <- temp$statistic ## ----filter_volcano, include=FALSE-------------------------------------------- S_cutoff <- quantile(S, .50) filter_volcano(d, p, S, n1, n2, alpha=.01, S_cutoff) ## ----kappa, include=FALSE----------------------------------------------------- t <- seq(0, 5, length=100) plot(t, kappa_t(t, n1, n2) * S_cutoff, xlab="|T|", ylab="Fold change bound", type="l") ## ----table-------------------------------------------------------------------- table(ALL_bcrneg$mol.biol) ## ----filtered_p--------------------------------------------------------------- S2 <- rowVars(exprs(ALL_bcrneg)) p2 <- rowttests(ALL_bcrneg, "mol.biol")$p.value theta <- seq(0, .5, .1) p_bh <- filtered_p(S2, p2, theta, method="BH") ## ----p_bh--------------------------------------------------------------------- head(p_bh) ## ----rejection_plot----------------------------------------------------------- rejection_plot(p_bh, at="sample", xlim=c(0,.3), ylim=c(0,1000), main="Benjamini & Hochberg adjustment") ## ----filtered_R--------------------------------------------------------------- theta <- seq(0, .80, .01) R_BH <- filtered_R(alpha=.10, S2, p2, theta, method="BH") ## ----R_BH--------------------------------------------------------------------- head(R_BH) ## ----filtered_R_plot---------------------------------------------------------- plot(theta, R_BH, type="l", xlab=expression(theta), ylab="Rejections", main="BH cutoff = 0.1") ## ----sessionInfo, results='asis', echo=FALSE---------------------------------- sessionInfo() |> toLatex() genefilter/inst/doc/independent_filtering_plots.Rnw0000644000175100017510000001521614614230661023721 0ustar00biocbuildbiocbuild%\VignetteIndexEntry{03 - Additional plots for: Independent filtering increases power for detecting differentially expressed genes, Bourgon et al., PNAS (2010)} %\VignettePackage{genefilter} %\VignetteEngine{knitr::knitr} % To compile this document % library('knitr'); rm(list=ls()); knit('independent_filtering_plots.Rnw') \documentclass[10pt]{article} <>= library("knitr") opts_chunk$set(tidy=FALSE,dev="png",fig.show="hide", fig.width=4,fig.height=4.5,dpi=240, message=FALSE,error=FALSE,warning=FALSE) @ <>= BiocStyle:::latex() @ \usepackage{xstring} \newcommand{\thetitle}{Additional plots for: Independent filtering increases power for detecting differentially expressed genes, Bourgon et al., PNAS (2010)} \title{\thetitle} \author{Richard Bourgon and Wolfgang Huber} \begin{document} <>= options( width = 80 ) @ % Make title \maketitle \tableofcontents \vspace{.25in} %%%%%%%% Main text \section{Introduction} This vignette illustrates use of some functions in the \emph{genefilter} package that provide useful diagnostics for independent filtering~\cite{BourgonIndependentFiltering}: \begin{itemize} \item \texttt{kappa\_p} and \texttt{kappa\_t} \item \texttt{filtered\_p} and \texttt{filtered\_R} \item \texttt{filter\_volcano} \item \texttt{rejection\_plot} \end{itemize} \section{Data preparation} Load the ALL data set and the \emph{genefilter} package: <>= library("genefilter") library("ALL") data("ALL") @ Reduce to just two conditions, then take a small subset of arrays from these, with 3 arrays per condition: <>= bcell <- grep("^B", as.character(ALL$BT)) moltyp <- which(as.character(ALL$mol.biol) %in% c("NEG", "BCR/ABL")) ALL_bcrneg <- ALL[, intersect(bcell, moltyp)] ALL_bcrneg$mol.biol <- factor(ALL_bcrneg$mol.biol) n1 <- n2 <- 3 set.seed(1969) use <- unlist(tapply(1:ncol(ALL_bcrneg), ALL_bcrneg$mol.biol, sample, n1)) subsample <- ALL_bcrneg[,use] @ We now use functions from \emph{genefilter} to compute overall standard devation filter statistics as well as standard two-sample $t$ and releated statistics. <>= S <- rowSds( exprs( subsample ) ) temp <- rowttests( subsample, subsample$mol.biol ) d <- temp$dm p <- temp$p.value t <- temp$statistic @ \section{Filtering volcano plot} Filtering on overall standard deviation and then using a standard $t$-statistic induces a lower bound of fold change, albeit one which varies somewhat with the significance of the $t$-statistic. The \texttt{filter\_volcano} function allows you to visualize this effect. <>= S_cutoff <- quantile(S, .50) filter_volcano(d, p, S, n1, n2, alpha=.01, S_cutoff) @ The output is shown in the left panel of Fig.~\ref{fig:volcano}. \begin{figure}[tb] \begin{center} \includegraphics[width=0.49\textwidth]{figure/filter_volcano-1} \includegraphics[width=0.49\textwidth]{figure/kappa-1} \caption{Left panel: plot produced by the \texttt{filter\_volcano} function. Right panel: graph of the \texttt{kappa\_t} function.} \label{fig:volcano} \end{center} \end{figure} The \texttt{kappa\_p} and \texttt{kappa\_t} functions, used to make the volcano plot, compute the fold change bound multiplier as a function of either a $t$-test $p$-value or the $t$-statistic itself. The actual induced bound on the fold change is $\kappa$ times the filter's cutoff on the overall standard deviation. Note that fold change bounds for values of $|T|$ which are close to 0 are not of practical interest because we will not reject the null hypothesis with test statistics in this range. <>= t <- seq(0, 5, length=100) plot(t, kappa_t(t, n1, n2) * S_cutoff, xlab="|T|", ylab="Fold change bound", type="l") @ The plot is shown in the right panel of Fig.~\ref{fig:volcano}. \section{Rejection count plots} \subsection{Across $p$-value cutoffs} The \texttt{filtered\_p} function permits easy simultaneous calculation of unadjusted or adjusted $p$-values over a range of filtering thresholds ($\theta$). Here, we return to the full ``BCR/ABL'' versus ``NEG'' data set, and compute adjusted $p$-values using the method of Benjamini and Hochberg, for a range of different filter stringencies. \begin{figure}[tb] \begin{center} \includegraphics[width=0.49\textwidth]{figure/rejection_plot-1} \includegraphics[width=0.49\textwidth]{figure/filtered_R_plot-1} \caption{Left panel: plot produced by the \texttt{rejection\_plot} function. Right panel: graph of \texttt{theta}.} \label{fig:rej} \end{center} \end{figure} <>= table(ALL_bcrneg$mol.biol) @ <>= S2 <- rowVars(exprs(ALL_bcrneg)) p2 <- rowttests(ALL_bcrneg, "mol.biol")$p.value theta <- seq(0, .5, .1) p_bh <- filtered_p(S2, p2, theta, method="BH") @ <>= head(p_bh) @ The \texttt{rejection\_plot} function takes sets of $p$-values corresponding to different filtering choices --- in the columns of a matrix or in a list --- and shows how rejection count ($R$) relates to the choice of cutoff for the $p$-values. For these data, over a reasonable range of FDR cutoffs, increased filtering corresponds to increased rejections. <>= rejection_plot(p_bh, at="sample", xlim=c(0,.3), ylim=c(0,1000), main="Benjamini & Hochberg adjustment") @ The plot is shown in the left panel of Fig.~\ref{fig:rej}. \subsection{Across filtering fractions} If we select a fixed cutoff for the adjusted $p$-values, we can also look more closely at the relationship between the fraction of null hypotheses filtered and the total number of discoveries. The \texttt{filtered\_R} function wraps \texttt{filtered\_p} and just returns rejection counts. It requires a $p$-value cutoff. <>= theta <- seq(0, .80, .01) R_BH <- filtered_R(alpha=.10, S2, p2, theta, method="BH") @ <>= head(R_BH) @ Because overfiltering (or use of a filter which is inappropriate for the application domain) discards both false and true null hypotheses, very large values of $\theta$ reduce power in this example: <>= plot(theta, R_BH, type="l", xlab=expression(theta), ylab="Rejections", main="BH cutoff = 0.1") @ The plot is shown in the right panel of Fig.~\ref{fig:rej}. %%%%%%%% Session info \section*{Session information} <>= sessionInfo() |> toLatex() @ \begin{thebibliography}{10} \bibitem{BourgonIndependentFiltering} Richard Bourgon, Robert Gentleman and Wolfgang Huber. \newblock Independent filtering increases power for detecting differentially expressed genes. \end{thebibliography} \end{document} genefilter/inst/wFun/0000755000175100017510000000000014614230661015615 5ustar00biocbuildbiocbuildgenefilter/inst/wFun/Anova.xml0000644000175100017510000000144514614230661017407 0ustar00biocbuildbiocbuild Anova cov numeric main TypeIn TRUE p 0.05 numeric main TypeIn FALSE na.rm TRUE logical main Radio FALSE genefilter/inst/wFun/coxfilter.xml0000644000175100017510000000144014614230661020335 0ustar00biocbuildbiocbuild coxfilter surt numeric main TypeIn TRUE cens numeric main TypeIn TRUE p numeric main TypeIn TRUE genefilter/inst/wFun/cv.xml0000644000175100017510000000144114614230661016747 0ustar00biocbuildbiocbuild cv a 1 numeric main TypeIn FALSE b Inf numeric main TypeIn FALSE na.rm TRUE logical main Radio FALSE genefilter/inst/wFun/gapFilter.xml0000644000175100017510000000234414614230661020257 0ustar00biocbuildbiocbuild gapFilter Gap numeric main TypeIn TRUE IQR numeric main TypeIn TRUE Prop nemeric main TypeIn TRUE na.rm TRUE logical main Radio FALSE neg.rm TRUE logical main Radio FALSE genefilter/inst/wFun/kOverA.xml0000644000175100017510000000144314614230661017530 0ustar00biocbuildbiocbuild kOverA k numeric main TypeIn TRUE A 100 numeric main TypeIn FALSE na.rm TRUE logical main Radio FALSE genefilter/inst/wFun/maxA.xml0000644000175100017510000000110714614230661017224 0ustar00biocbuildbiocbuild maxA A 75 numeric main TypeIn FALSE na.rm TRUE logical main Radio FALSE genefilter/inst/wFun/pOverA.xml0000644000175100017510000000145014614230661017533 0ustar00biocbuildbiocbuild pOverA p 0.05 numeric main TypeIn FALSE A 100 numeric main TypeIn FALSE na.rm TRUE logical main Radio FALSE genefilter/inst/wFun/ttest.xml0000644000175100017510000000144314614230661017504 0ustar00biocbuildbiocbuild ttest m numeric main TypeIn TRUE p 0.05 numeric main TypeIn FALSE na.rm TRUE logical main Radio FALSE genefilter/man/0000755000175100017510000000000014614230661014474 5ustar00biocbuildbiocbuildgenefilter/man/Anova.Rd0000644000175100017510000000263314614230661016033 0ustar00biocbuildbiocbuild\name{Anova} \alias{Anova} \title{A filter function for Analysis of Variance } \description{ \code{Anova} returns a function of one argument with bindings for \code{cov} and \code{p}. The function, when evaluated, performs an ANOVA using \code{cov} as the covariate. It returns \code{TRUE} if the p value for a difference in means is less than \code{p}. } \usage{ Anova(cov, p=0.05, na.rm=TRUE) } \arguments{ \item{cov}{The covariate. It must have length equal to the number of columns of the array that \code{Anova} will be applied to. } \item{p}{ The p-value for the test. } \item{na.rm}{If set to \code{TRUE} any \code{NA}'s will be removed. } } \details{ The function returned by \code{Anova} uses \code{lm} to fit a linear model of the form \code{lm(x ~ cov)}, where \code{x} is the set of gene expressions. The F statistic for an overall effect is computed and if it has a \emph{p}-value less than \code{p} the function returns \code{TRUE}, otherwise it returns \code{FALSE} for that gene. } \value{ \code{Anova} returns a function with bindings for \code{cov} and \code{p} that will perform a one-way ANOVA. The covariate can be continuous, in which case the test is for a linear effect for the covariate. } \author{R. Gentleman } \seealso{\code{\link{kOverA}}, \code{\link{lm}} } \examples{ set.seed(123) af <- Anova(c(rep(1,5),rep(2,5)), .01) af(rnorm(10)) } \keyword{manip} genefilter/man/coxfilter.Rd0000644000175100017510000000206614614230661016766 0ustar00biocbuildbiocbuild\name{coxfilter} \alias{coxfilter} \title{A filter function for univariate Cox regression. } \description{ A function that performs Cox regression with bindings for \code{surt}, \code{cens}, and \code{p} is returned. This function filters genes according to the attained p-value from a Cox regression using \code{surt} as the survival times, and \code{cens} as the censoring indicator. It requires \code{survival}. } \usage{ coxfilter(surt, cens, p) } \arguments{ \item{surt}{Survival times.} \item{cens}{Censoring indicator. } \item{p}{The p-value to use in filtering. } } \value{ Calls to the \code{\link[survival]{coxph}} function in the \code{survival} library are used to fit a Cox model. The filter function returns \code{TRUE} if the p-value in the fit is less than \code{p}. } \author{R. Gentleman } \seealso{\code{\link{Anova}}} \examples{ set.seed(-5) sfun <- coxfilter(rexp(10), ifelse(runif(10) < .7, 1, 0), .05) ffun <- filterfun(sfun) dat <- matrix(rnorm(1000), ncol=10) out <- genefilter(dat, ffun) } \keyword{manip} genefilter/man/cv.Rd0000644000175100017510000000201214614230661015366 0ustar00biocbuildbiocbuild\name{cv} \alias{cv} \title{A filter function for the coefficient of variation.} \description{ \code{cv} returns a function with values for \code{a} and \code{b} bound. This function takes a single argument. It computes the coefficient of variation for the input vector and returns \code{TRUE} if the coefficient of variation is between \code{a} and \code{b}. Otherwise it returns \code{FALSE} } \usage{ cv(a=1, b=Inf, na.rm=TRUE) } \arguments{ \item{a}{The lower bound for the cv. } \item{b}{The upper bound for the cv. } \item{na.rm}{If set to \code{TRUE} any \code{NA}'s will be removed. } } \details{ The coefficient of variation is the standard deviation divided by the absolute value of the mean. } \value{ It returns a function of one argument. The function has an environment with bindings for \code{a} and \code{b}. } \author{R. Gentleman } \seealso{\code{\link{pOverA}}, \code{\link{kOverA}} } \examples{ set.seed(-3) cvfun <- cv(1,10) cvfun(rnorm(10,10)) cvfun(rnorm(10)) } \keyword{manip} genefilter/man/deprecated.Rd0000644000175100017510000000114114614230661017060 0ustar00biocbuildbiocbuild\name{genefilter-deprecated} \alias{genefilter-deprecated} \title{Deprecated functions in package \sQuote{genefilter}} \description{ These functions are provided for compatibility with older versions of \sQuote{genefilter} only, and will be defunct at the next release. } \details{ The following functions are deprecated and will be made defunct; use the replacement indicated below: \itemize{ \item{eSetFilter} \item{getFilterNames} \item{getFuncDesc} \item{getRdAsText} \item{parseDesc} \item{parseArgs} \item{showESet} \item{setESetArgs} \item{isESet} } } genefilter/man/dist2.Rd0000644000175100017510000000321214614230661016006 0ustar00biocbuildbiocbuild\name{dist2} \alias{dist2} \title{ Calculate an n-by-n matrix by applying a function to all pairs of columns of an m-by-n matrix. } \description{ Calculate an n-by-n matrix by applying a function to all pairs of columns of an m-by-n matrix. } \usage{ dist2(x, fun, diagonal=0) } \arguments{ \item{x}{A matrix.} \item{fun}{A symmetric function of two arguments that may be columns of \code{x}.} \item{diagonal}{The value to be used for the diagonal elements of the resulting matrix.} } \details{ With the default value of \code{fun}, this function calculates for each pair of columns of \code{x} the mean of the absolute values of their differences (which is proportional to the L1-norm of their difference). This is a distance metric. The implementation assumes that \code{fun(x[,i], x[,j])} can be evaluated for all pairs of \code{i} and \code{j} (see examples), and that \code{fun} is symmetric, i.e. \code{fun(a, b) = fun(b, a)}. \code{fun(a, a)} is not actually evaluated, instead the value of \code{diagonal} is used to fill the diagonal elements of the returned matrix. Note that \code{\link[stats:dist]{dist}} computes distances between rows of \code{x}, while this function computes relations between columns of \code{x} (see examples). } \value{ A symmetric matrix of size \code{n x n}. } \author{ Wolfgang Huber, James Reid } \examples{ # example matrix z = matrix(1:15693, ncol=3) matL1 = dist2(z) matL2 = dist2(z, fun=function(a,b) sqrt(sum((a-b)^2, na.rm=TRUE))) euc = as.matrix(dist(t(z))) stopifnot(identical(dim(matL2), dim(euc)), all(euc==matL2)) } \keyword{manip} genefilter/man/eSetFilter.Rd0000644000175100017510000000320514614230661017031 0ustar00biocbuildbiocbuild\name{eSetFilter} \alias{eSetFilter} \alias{getFilterNames} \alias{getFuncDesc} \alias{getRdAsText} \alias{parseDesc} \alias{parseArgs} \alias{setESetArgs} \alias{isESet} \alias{showESet} \title{A function to filter an eSet object} \description{ Given a Bioconductor's ExpressionSet object, this function filters genes using a set of selected filters. } \usage{ eSetFilter(eSet) getFilterNames() getFuncDesc(lib = "genefilter", funcs = getFilterNames()) getRdAsText(lib) parseDesc(text) parseArgs(text) showESet(eSet) setESetArgs(filter) isESet(eSet) } \arguments{ \item{eSet}{\code{eSet} an ExpressionSet object} \item{lib}{\code{lib} a character string for the name of an R library where functions of interests reside} \item{funcs}{\code{funcs} a vector of character strings for names of functions of interest} \item{text}{\code{text} a character of string from a filed (e. g. description, argument, ..) filed of an Rd file for a fucntion} \item{filter}{\code{filter} a character string for the name of a filter function} } \details{ These functions are deprecated. Please use the \sQuote{iSee} package instead. A set of filters may be selected to filter genes in through each of the filters in the order the filters have been selected } \value{ A logical vector of length equal to the number of rows of 'expr'. The values in that vector indicate whether the corresponding row of 'expr' passed the set of filter functions. } \author{Jianhua Zhang} \seealso{\code{\link{genefilter}}} \examples{ if( interactive() ) { data(sample.ExpressionSet) res <- eSetFilter(sample.ExpressionSet) } } \keyword{manip} genefilter/man/filter_volcano.Rd0000644000175100017510000000407314614230661017775 0ustar00biocbuildbiocbuild\name{filter_volcano} \Rdversion{1.1} \alias{filter_volcano} \title{Volcano plot for overall variance filtering} \description{ Generate a volcano plot contrasting p-value with fold change (on the log scale), in order to visualize the effect of filtering on overall variance and also assign significance via p-value. } \usage{ filter_volcano( d, p, S, n1, n2, alpha, S_cutoff, cex = 0.5, pch = 19, xlab = expression(paste(log[2], " fold change")), ylab = expression(paste("-", log[10], " p")), cols = c("grey80", "grey50", "black"), ltys = c(1, 3), use_legend = TRUE, ... ) } \arguments{ \item{d}{Fold changes, typically on the log scale, base 2.} \item{p}{The p-values} \item{S}{ The overall standard deviation filter statistics, i.e., the square roots of the overall variance filter statistics. } \item{n1}{Sample size for group 1.} \item{n2}{Sample size for group 2.} \item{alpha}{Significance cutoff used for p-values.} \item{S_cutoff}{ Filter cutoff used for the overall standard deviation in \code{S}. } \item{cex}{Point size for plotting.} \item{pch}{Point character for plotting.} \item{xlab}{Label for x-axis.} \item{ylab}{Label for y-axis.} \item{cols}{ A vector of three colors used for plotting. These correspond to filtered data, data which pass the filter but are insignificant, and data pass the filter and are also statistically significant. } \item{ltys}{ The induced bound on log-scale fold change is plotted, as is the significance cutoff for data passing the filter. The \code{ltys} argument gives line styles for these drawing these two thresholds on the plot. } \item{use_legend}{Should a legend for point color be produced?} \item{\dots}{Other arguments for \code{plot}.} } \author{Richard Bourgon } \examples{ # See the vignette: Diagnostic plots for independent filtering } genefilter/man/filtered_p.Rd0000644000175100017510000000505714614230661017107 0ustar00biocbuildbiocbuild\name{filtered_p} \Rdversion{1.1} \alias{filtered_p} \alias{filtered_R} \title{ Compute and adjust p-values, with filtering } \description{ Given filter and test statistics in the form of unadjusted p-values, or functions able to compute these statistics from the data, filter and then correct the p-values across a range of filtering stringencies. } \usage{ filtered_p(filter, test, theta, data, method = "none") filtered_R(alpha, filter, test, theta, data, method = "none") } \arguments{ \item{alpha}{ A cutoff to which p-values, possibly adjusted for multiple testing, will be compared. } \item{filter}{ A vector of stage-one filter statistics, or a function which is able to compute this vector from \code{data}, if \code{data} is supplied. } \item{test}{ A vector of unadjusted p-values, or a function which is able to compute this vector from the filtered portion of \code{data}, if \code{data} is supplied. The option to supply a function is useful when the value of the test statistic depends on which hypotheses are filtered out at stage one. (The \pkg{limma} t-statistic is an example.) } \item{theta}{ A vector with one or more filtering fractions to consider. Actual cutoffs are then computed internally by applying \code{\link{quantile}} to the filter statistics contained in (or produced by) the \code{filter} argument. } \item{data}{ If \code{filter} and/or \code{test} are functions rather than vectors of statistics, they will be applied to \code{data}. The functions will be passed the whole \code{data} object, and must work over rows, etc. themselves as appropriate. } \item{method}{ The unadjusted p-values contained in (or produced by) \code{test} will be adjusted for multiple testing after filtering, using the \code{\link{p.adjust}} function in the \pkg{stats} package. See the \code{method} argument there for options. }p } \value{ For \code{filtered_p}, a matrix of p-values, possible adjusted for multiple testing, with one row per null hypothesis and one column per filtering fraction given in \code{theta}. For a given column, entries which have been filtered out are \code{NA}. For \code{filtered_R}, a count of the entries in the \code{filtered_p} result which are less than \code{alpha}. } \author{Richard Bourgon } \examples{ # See the vignette: Diagnostic plots for independent filtering } \seealso{ See \code{\link{rejection_plot}} for visualization of \code{filtered_p} results. } genefilter/man/filterfun.Rd0000644000175100017510000000223514614230661016763 0ustar00biocbuildbiocbuild\name{filterfun} \alias{filterfun} \title{Creates a first FALSE exiting function from the list of filter functions it is given. } \description{ This function creates a function that takes a single argument. The filtering functions are bound in the environment of the returned function and are applied sequentially to the argument of the returned function. When the first filter function evaluates to \code{FALSE} the function returns \code{FALSE} otherwise it returns \code{TRUE}. } \usage{ filterfun(...) } \arguments{ \item{...}{Filtering functions. } } \value{ \code{filterfun} returns a function that takes a single argument. It binds the filter functions given to it in the environment of the returned function. These functions are applied sequentially (in the order they were given to \code{filterfun}). The function returns \code{FALSE} (and exits) when the first filter function returns \code{FALSE} otherwise it returns \code{TRUE}. } \author{R. Gentleman } \seealso{\code{\link{genefilter}} } \examples{ set.seed(333) x <- matrix(rnorm(100,2,1),nc=10) cvfun <- cv(.5,2.5) ffun <- filterfun(cvfun) which <- genefilter(x, ffun) } \keyword{manip} genefilter/man/findLargest.Rd0000644000175100017510000000261214614230661017226 0ustar00biocbuildbiocbuild\name{findLargest} \alias{findLargest} \title{Find the Entrez Gene ID corresponding to the largest statistic} \description{ Most microarrays have multiple probes per gene (Entrez). This function finds all replicates, and then selects the one with the largest value of the test statistic. } \usage{ findLargest(gN, testStat, data = "hgu133plus2") } \arguments{ \item{gN}{A vector of probe identifiers for the chip.} \item{testStat}{A vector of test statistics, of the same length as \code{gN} with the per probe test statistics.} \item{data}{The character string identifying the chip.} } \details{ All the probe identifiers, \code{gN}, are mapped to Entrez Gene IDs and the duplicates determined. For any set of probes that map to the same Gene ID, the one with the largest test statistic is found. The return vector is the named vector of selected probe identifiers. The names are the Entrez Gene IDs. This could be extended in different ways, such as allowing the user to use a different selection criterion. Also, matching on different identifiers seems like another alternative. } \value{ A named vector of probe IDs. The names are Entrez Gene IDs. } \author{R. Gentleman} \seealso{\code{\link{sapply}}} \examples{ library("hgu95av2.db") set.seed(124) gN <- sample(ls(hgu95av2ENTREZID), 200) stats <- rnorm(200) findLargest(gN, stats, "hgu95av2") } \keyword{manip} genefilter/man/gapFilter.Rd0000644000175100017510000000346714614230661016712 0ustar00biocbuildbiocbuild\name{gapFilter} \alias{gapFilter} \title{ A filter to select genes based on there being a gap. } \description{ The \code{gapFilter} looks for genes that might usefully discriminate between two groups (possibly unknown at the time of filtering). To do this we look for a gap in the ordered expression values. The gap must come in the central portion (we exclude jumps in the initial \code{Prop} values or the final \code{Prop} values). Alternatively, if the IQR for the gene is large that will also pass our test and the gene will be selected. } \usage{ gapFilter(Gap, IQR, Prop, na.rm=TRUE, neg.rm=TRUE) } \arguments{ \item{Gap}{The size of the gap required to pass the test. } \item{IQR}{The size of the IQR required to pass the test. } \item{Prop}{The proportion (or number) of samples to exclude at either end.} \item{na.rm}{If \code{TRUE} then \code{NA}'s will be removed before processing. } \item{neg.rm}{ If \code{TRUE} then negative values in \code{x} will be removed before processing.} } \details{ As stated above we are interested in } \value{ A function that returns either \code{TRUE} or \code{FALSE} depending on whether the vector supplied has a gap larger than \code{Gap} or an IQR (inter quartile range) larger than \code{IQR}. For computing the gap we want to exclude a proportion, \code{Prop} from either end of the sorted values. The reason for this requirement is that genes which differ in expression levels only for a few samples are not likely to be interesting. } \author{R. Gentleman } \seealso{\code{\link{ttest}}, \code{\link{genefilter}} } \examples{ set.seed(256) x <- c(rnorm(10,100,3), rnorm(10, 100, 10)) y <- x + c(rep(0,10), rep(100,10)) tmp <- rbind(x,y) Gfilter <- gapFilter(200, 100, 5) ffun <- filterfun(Gfilter) genefilter(tmp, ffun) } \keyword{manip} genefilter/man/genefilter.Rd0000644000175100017510000000427514614230661017117 0ustar00biocbuildbiocbuild\name{genefilter} \alias{genefilter} \title{A function to filter genes.} \description{ \code{genefilter} filters genes in the array \code{expr} using the filter functions in \code{flist}. It returns an array of logical values (suitable for subscripting) of the same length as there are rows in \code{expr}. For each row of \code{expr} the returned value is \code{TRUE} if the row passed all the filter functions. Otherwise it is set to \code{FALSE}. } \usage{ genefilter(expr, flist) } \arguments{ \item{expr}{A \code{matrix} or \code{ExpressionSet} that the filter functions will be applied to.} \item{flist}{A \code{list} of filter functions to apply to the array.} } \details{ This package uses a very simple but powerful protocol for \emph{filtering} genes. The user simply constructs any number of tests that they want to apply. A test is simply a function (as constructed using one of the many helper functions in this package) that returns \code{TRUE} if the gene of interest passes the test (or filter) and \code{FALSE} if the gene of interest fails. The benefit of this approach is that each test is constructed individually (and can be tested individually). The tests are then applied sequentially to each gene. The function returns a logical vector indicating whether the gene passed all tests functions or failed at least one of them. Users can construct their own filters. These filters should accept a vector of values, corresponding to a row of the \code{expr} object. The user defined function should return a length 1 logical vector, with value \code{TRUE} or \code{FALSE}. User-defined functions can be combined with \code{\link{filterfun}}, just as built-in filters. } \value{ A logical \code{vector} of length equal to the number of rows of \code{expr}. The values in that \code{vector} indicate whether the corresponding row of \code{expr} passed the set of filter functions. } \author{R. Gentleman} \seealso{\code{\link{genefilter}}, \code{\link{kOverA}}} \examples{ set.seed(-1) f1 <- kOverA(5, 10) flist <- filterfun(f1) exprA <- matrix(rnorm(1000, 10), ncol = 10) ans <- genefilter(exprA, flist) } \keyword{manip} genefilter/man/genefinder.Rd0000644000175100017510000000647614614230661017106 0ustar00biocbuildbiocbuild\name{genefinder} \alias{genefinder} \alias{genefinder,ExpressionSet,vector-method} \alias{genefinder,matrix,vector-method} \title{Finds genes that have similar patterns of expression.} \description{ Given an \code{ExpressionSet} or a \code{matrix} of gene expressions, and the indices of the genes of interest, \code{genefinder} returns a \code{list} of the \code{numResults} closest genes. The user can specify one of the standard distance measures listed below. The number of values to return can be specified. The return value is a \code{list} with two components: genes (measured through the desired distance method) to the genes of interest (where X is the number of desired results returned) and their distances. } \usage{ genefinder(X, ilist, numResults=25, scale="none", weights, method="euclidean") } \arguments{ \item{X}{A numeric \code{matrix} where columns represent patients and rows represent genes.} \item{ilist}{A \code{vector} of genes of interest. Contains indices of genes in matrix X.} \item{numResults}{Number of results to display, starting from the least distance to the greatest.} \item{scale}{One of "none", "range", or "zscore". Scaling is carried out separately on each row.} \item{weights}{A vector of weights applied across the columns of \code{X}. If no weights are supplied, no weights are applied.} \item{method}{One of "euclidean", "maximum", "manhattan", "canberra", "correlation", "binary".} } \details{ If the \code{scale} option is "range", then the input matrix is scaled using \code{genescale()}. If it is "zscore", then the input matrix is scaled using the \code{scale} builtin with no arguments. The method option specifies the metric used for gene comparisons. The metric is applied, row by row, for each gene specified in \code{ilist}. The "correlation" option for the distance method will return a value equal to 1-correlation(x). See \code{\link{dist}} for a more detailed description of the distances. } \value{ The returned value is a \code{list} containing an entry for each gene specified in \code{ilist}. Each \code{list} entry contains an array of distances for that gene of interest. } \author{J. Gentry and M. Kajen} \seealso{\code{\link{genescale}}} \examples{ set.seed(12345) #create some fake expression profiles m1 <- matrix (1:12, 4, 3) v1 <- 1 nr <- 2 #find the 2 rows of m1 that are closest to row 1 genefinder (m1, v1, nr, method="euc") v2 <- c(1,3) genefinder (m1, v2, nr) genefinder (m1, v2, nr, scale="range") genefinder (m1, v2, nr, method="manhattan") m2 <- matrix (rnorm(100), 10, 10) v3 <- c(2, 5, 6, 8) nr2 <- 6 genefinder (m2, v3, nr2, scale="zscore") \testonly{ m1 <- matrix(rnorm(1000),100,10) v1 <- c(3,5,8,42) nr2 <- 35 genefinder(m1,v1,nr2,method="euclidean") genefinder(m1,v1,nr2,method="maximum") genefinder(m1,v1,nr2,method="canberra") genefinder(m1,v1,nr2,method="binary") genefinder(m1,v1,nr2,method="correlation") m2 <- matrix(rnorm(10000),1000,10) v1 <- c(1,100,563,872,921,3,52,95,235,333) nr <- 100 genefinder(m2,v1,nr2,scale="zscore",method="euclidean") genefinder(m2,v1,nr2,scale="range",method="maximum") genefinder(m2,v1,nr2,scale="zscore",method="canberra") genefinder(m2,v1,nr2,scale="range",method="binary") genefinder(m2,v1,nr2,scale="zscore",method="correlation") } } \keyword{manip} genefilter/man/genescale.Rd0000644000175100017510000000237414614230661016717 0ustar00biocbuildbiocbuild\name{genescale} \alias{genescale} \title{Scales a matrix or vector.} \description{ \code{genescale} returns a scaled version of the input matrix m by applying the following formula to each column of the matrix: \deqn{y[i] = ( x[i] - min(x) ) / ( max(x) - min(x) )} } \usage{ genescale(m, axis=2, method=c("Z", "R"), na.rm=TRUE) } \arguments{ \item{m}{Input a matrix or a vector with numeric elements. } \item{axis}{An integer indicating which axis of \code{m} to scale.} \item{method}{Either "Z" or "R", indicating whether a Z scaling or a range scaling should be performed.} \item{na.rm}{A boolean indicating whether \code{NA}'s should be removed.} } \details{ Either the rows or columns of \code{m} are scaled. This is done either by subtracting the mean and dividing by the standard deviation ("Z") or by subtracing the minimum and dividing by the range. } \value{ A scaled version of the input. If \code{m} is a \code{matrix} or a \code{dataframe} then the dimensions of the returned value agree with that of \code{m}, in both cases the returned value is a \code{matrix}. } \author{ R. Gentleman } \seealso{ \code{\link{genefinder}},\code{\link{scale}} } \examples{ m <- matrix(1:12, 4, 3) genescale(m) } \keyword{ manip } genefilter/man/half.range.mode.Rd0000755000175100017510000000636014614230661017723 0ustar00biocbuildbiocbuild\name{half.range.mode} \alias{half.range.mode} \title{Mode estimation for continuous data} \description{ For data assumed to be drawn from a unimodal, continuous distribution, the mode is estimated by the \dQuote{half-range} method. Bootstrap resampling for variance reduction may optionally be used. } \usage{ half.range.mode(data, B, B.sample, beta = 0.5, diag = FALSE) } \arguments{ \item{data}{A numeric vector of data from which to estimate the mode.} \item{B}{ Optionally, the number of bootstrap resampling rounds to use. Note that \code{B = 1} resamples 1 time, whereas omitting \code{B} uses \code{data} as is, without resampling. } \item{B.sample}{ If bootstrap resampling is requested, the size of the bootstrap samples drawn from \code{data}. Default is to use a sample which is the same size as \code{data}. For large data sets, this may be slow and unnecessary. } \item{beta}{ The fraction of the remaining range to use at each iteration. } \item{diag}{ Print extensive diagnostics. For internal testing only... best left \code{FALSE}. } } \details{ Briefly, the mode estimator is computed by iteratively identifying densest half ranges. (Other fractions of the current range can be requested by setting \code{beta} to something other than 0.5.) A densest half range is an interval whose width equals half the current range, and which contains the maximal number of observations. The subset of observations falling in the selected densest half range is then used to compute a new range, and the procedure is iterated. See the references for details. If bootstrapping is requested, \code{B} half-range mode estimates are computed for \code{B} bootstrap samples, and their average is returned as the final estimate. } \value{ The mode estimate. } \references{ \itemize{ \item DR Bickel, \dQuote{Robust estimators of the mode and skewness of continuous data.} \emph{Computational Statistics & Data Analysis} 39:153-163 (2002). \item SB Hedges and P Shah, \dQuote{Comparison of mode estimation methods and application in molecular clock analysis.} \emph{BMC Bioinformatics} 4:31-41 (2003). } } \author{Richard Bourgon } \seealso{\code{\link{shorth}}} \keyword{univar} \keyword{robust} \examples{ ## A single normal-mixture data set x <- c( rnorm(10000), rnorm(2000, mean = 3) ) M <- half.range.mode( x ) M.bs <- half.range.mode( x, B = 100 ) if(interactive()){ hist( x, breaks = 40 ) abline( v = c( M, M.bs ), col = "red", lty = 1:2 ) legend( 1.5, par("usr")[4], c( "Half-range mode", "With bootstrapping (B = 100)" ), lwd = 1, lty = 1:2, cex = .8, col = "red" ) } # Sampling distribution, with and without bootstrapping X <- rbind( matrix( rnorm(1000 * 100), ncol = 100 ), matrix( rnorm(200 * 100, mean = 3), ncol = 100 ) ) M.list <- list( Simple = apply( X, 2, half.range.mode ), BS = apply( X, 2, half.range.mode, B = 100 ) ) if(interactive()){ boxplot( M.list, main = "Effect of bootstrapping" ) abline( h = 0, col = "red" ) } } genefilter/man/kappa_p.Rd0000644000175100017510000000200214614230661016370 0ustar00biocbuildbiocbuild\name{kappa_p} \Rdversion{1.1} \alias{kappa_p} \alias{kappa_t} \title{ Compute proportionality constant for fold change bound. } \description{ Filtering on overall variance induces a lower bound on fold change. This bound depends on the significance of the evidence against the null hypothesis, an is a multiple of the cutoff used for an overall variance filter. It also depends on sample size in both of the groups being compared. These functions compute the multiplier for the supplied p-values or t-statistics. } \usage{ kappa_p(p, n1, n2 = n1) kappa_t(t, n1, n2 = n1) } \arguments{ \item{p}{The p-values at which to compute the multiplier.} \item{t}{The t-statistics at which to compute the multiplier.} \item{n1}{Sample size for class 1.} \item{n2}{Sample size for class 2.} } \value{ A vector of multipliers: one per p-value or t-static in \code{p} or \code{t}. } \author{Richard Bourgon } \examples{ # See the vignette: Diagnostic plots for independent filtering } genefilter/man/kOverA.Rd0000644000175100017510000000133014614230661016147 0ustar00biocbuildbiocbuild\name{kOverA} \alias{kOverA} \title{A filter function for k elements larger than A. } \description{ \code{kOverA} returns a filter function with bindings for \code{k} and \code{A}. This function evaluates to \code{TRUE} if at least \code{k} of the arguments elements are larger than \code{A}. } \usage{ kOverA(k, A=100, na.rm=TRUE) } \arguments{ \item{A}{The value you want to exceed. } \item{k}{The number of elements that have to exceed A.} \item{na.rm}{If set to \code{TRUE} any \code{NA}'s will be removed. } } \value{ A function with bindings for \code{A} and \code{k}. } \author{R. Gentleman} \seealso{\code{\link{pOverA}}} \examples{ fg <- kOverA(5, 100) fg(90:100) fg(98:110) } \keyword{manip} genefilter/man/maxA.Rd0000644000175100017510000000125314614230661015652 0ustar00biocbuildbiocbuild\name{maxA} \alias{maxA} \title{ A filter function to filter according to the maximum. } \description{ \code{maxA} returns a function with the parameter \code{A} bound. The returned function evaluates to \code{TRUE} if any element of its argument is larger than \code{A}. } \usage{ maxA(A=75, na.rm=TRUE) } \arguments{ \item{A}{The value that at least one element must exceed. } \item{na.rm}{If \code{TRUE} then \code{NA}'s are removed. } } \value{ \code{maxA} returns a function with an environment containing a binding for \code{A}. } \author{R. Gentleman } \seealso{\code{\link{pOverA}} } \examples{ ff <- maxA(30) ff(1:10) ff(28:31) } \keyword{manip} genefilter/man/nsFilter.Rd0000644000175100017510000002137714614230661016563 0ustar00biocbuildbiocbuild\name{nsFilter} \alias{nsFilter} \alias{varFilter} \alias{featureFilter} \alias{nsFilter,ExpressionSet-method} \title{Filtering of Features in an ExpressionSet} \description{The function \code{nsFilter} tries to provide a one-stop shop for different options of filtering (removing) features from an ExpressionSet. Filtering features exhibiting little variation, or a consistently low signal, across samples can be advantageous for the subsequent data analysis (Bourgon et al.). Furthermore, one may decide that there is little value in considering features with insufficient annotation. } \usage{ nsFilter(eset, require.entrez=TRUE, require.GOBP=FALSE, require.GOCC=FALSE, require.GOMF=FALSE, require.CytoBand=FALSE, remove.dupEntrez=TRUE, var.func=IQR, var.cutoff=0.5, var.filter=TRUE, filterByQuantile=TRUE, feature.exclude="^AFFX", ...) varFilter(eset, var.func=IQR, var.cutoff=0.5, filterByQuantile=TRUE) featureFilter(eset, require.entrez=TRUE, require.GOBP=FALSE, require.GOCC=FALSE, require.GOMF=FALSE, require.CytoBand=FALSE, remove.dupEntrez=TRUE, feature.exclude="^AFFX") } \arguments{ \item{eset}{an \code{ExpressionSet} object} \item{var.func}{The function used as the per-feature filtering statistic. This function should return a numeric vector of length one when given a numeric vector as input.} \item{var.filter}{A logical indicating whether to perform filtering based on \code{var.func}.} \item{filterByQuantile}{A logical indicating whether \code{var.cutoff} is to be interprested as a quantile of all \code{var.func} values (the default), or as an absolute value.} \item{var.cutoff}{A numeric value. If \code{var.filter} is TRUE, features whose value of \code{var.func} is less than either: the \code{var.cutoff}-quantile of all \code{var.func} values (if \code{filterByQuantile} is TRUE), or \code{var.cutoff} (if \code{filterByQuantile} is FALSE) will be removed.} \item{require.entrez}{If \code{TRUE}, filter out features without an Entrez Gene ID annotation. If using an annotation package where an identifier system other than Entrez Gene IDs is used as the central ID, then that ID will be required instead.} \item{require.GOBP, require.GOCC, require.GOMF}{If \code{TRUE}, filter out features whose target genes are not annotated to at least one GO term in the BP, CC or MF ontology, respectively.} \item{require.CytoBand}{If \code{TRUE}, filter out features whose target genes have no mapping to cytoband locations.} \item{remove.dupEntrez}{If \code{TRUE} and there are features mapping to the same Entrez Gene ID (or equivalent), then the feature with the largest value of \code{var.func} will be retained and the other(s) removed.} \item{feature.exclude}{A character vector of regular expressions. Feature identifiers (i.e. value of \code{featureNames(eset)}) that match one of the specified patterns will be filtered out. The default value is intended to filter out Affymetrix quality control probe sets.} \item{...}{Unused, but available for specializing methods.} } \details{ In this Section, the effect of filtering on the type I error rate estimation / control of subsequent hypothesis testing is explained. See also the paper by Bourgon et al. \emph{Marginal type I errors}: Filtering on the basis of a statistic which is independent of the test statistic used for detecting differential gene expression can increase the detection rate at the same marginal type I error. This is clearly the case for filter criteria that do not depend on the data, such as the annotation based criteria provided by the \code{nsFilter} and \code{featureFilter} functions. However, marginal type I error can also be controlled for certain types of data-dependent criteria. Call \eqn{U^I}{U^1} the stage 1 filter statistic, which is a function that is applied feature by feature, based on whose value the feature is or is not accepted to pass to stage 2, and which depends only on the data for that feature and not any other feature, and call \eqn{U^{II}}{U^2} the stage 2 test statistic for differential expression. Sufficient conditions for marginal type-I error control are: \itemize{ \item \eqn{U^I}{U^1} the overall (across all samples) variance or mean, \eqn{U^{II}}{U^2} the t-statistic (or any other scale and location invariant statistic), data normal distributed and exchangeable across samples. \item \eqn{U^I}{U^1} the overall mean, \eqn{U^{II}}{U^2} the moderated t-statistic (as in limma's \code{\link[limma:ebayes]{eBayes}} function), data normal distributed and exchangeable. \item \eqn{U^I}{U^1} a sample-class label independent function (e.g. overall mean, median, variance, IQR), \eqn{U^{II}}{U^2} the Wilcoxon rank sum statistic, data exchangeable. } \emph{Experiment-wide type I error}: Marginal type-I error control provided by the conditions above is sufficient for control of the family wise error rate (FWER). Note, however, that common false discovery rate (FDR) methods depend not only on the marginal behaviour of the test statistics under the null hypothesis, but also on their joint distribution. The joint distribution can be affected by filtering, even when this filtering leaves the marginal distributions of true-null test statistics unchanged. Filtering might, for example, change correlation structure. The effect of this is negligible in many cases in practice, but this depends on the dataset and the filter used, and the assessment is in the responsibility of the data analyst. \emph{Annotation Based Filtering} Arguments \code{require.entrez}, \code{require.GOBP}, \code{require.GOCC}, \code{require.GOMF} and \code{require.CytoBand} filter based on available annotation data. The annotation package is determined by calling \code{annotation(eset)}. \emph{Variance Based Filtering} The \code{var.filter}, \code{var.func}, \code{var.cutoff} and \code{varByQuantile} arguments control numerical cutoff-based filtering. Probes for which \code{var.func} returns \code{NA} are removed. The default \code{var.func} is \code{IQR}, which we here define as \code{rowQ(eset, ceiling(0.75 * ncol(eset))) - rowQ(eset, floor(0.25 * ncol(eset)))}; this choice is motivated by the observation that unexpressed genes are detected most reliably through low variability of their features across samples. Additionally, \code{IQR} is robust to outliers (see note below). The default \code{var.cutoff} is \code{0.5} and is motivated by a rule of thumb that in many tissues only 40\% of genes are expressed. Please adapt this value to your data and question. By default the numerical-filter cutoff is interpreted as a quantile, so with the default settings, 50\% of the genes are filtered. Variance filtering is performed last, so that (if \code{varByQuantile=TRUE} and \code{remove.dupEntrez=TRUE}) the final number of genes does indeed exclude precisely the \code{var.cutoff} fraction of unique genes remaining after all other filters were passed. The stand-alone function \code{varFilter} does only \code{var.func}-based filtering (and no annotation based filtering). \code{featureFilter} does only annotation based filtering and duplicate removal; it always performs duplicate removal to retain the highest-IQR probe for each gene. } \value{ For \code{nsFilter} a list consisting of: \item{eset}{the filtered \code{ExpressionSet}} \item{filter.log}{a list giving details of how many probe sets where removed for each filtering step performed.} For both \code{varFilter} and \code{featureFilter} the filtered \code{ExpressionSet}. } \author{Seth Falcon (somewhat revised by Assaf Oron)} \note{\code{IQR} is a reasonable variance-filter choice when the dataset is split into two roughly equal and relatively homogeneous phenotype groups. If your dataset has important groups smaller than 25\% of the overall sample size, or if you are interested in unusual individual-level patterns, then \code{IQR} may not be sensitive enough for your needs. In such cases, you should consider using less robust and more sensitive measures of variance (the simplest of which would be \code{sd}).} \references{ R. Bourgon, R. Gentleman, W. Huber, Independent filtering increases power for detecting differentially expressed genes, Technical Report. } \examples{ library("hgu95av2.db") library("Biobase") data(sample.ExpressionSet) ans <- nsFilter(sample.ExpressionSet) ans$eset ans$filter.log ## skip variance-based filtering ans <- nsFilter(sample.ExpressionSet, var.filter=FALSE) a1 <- varFilter(sample.ExpressionSet) a2 <- featureFilter(sample.ExpressionSet) } \keyword{manip} genefilter/man/pOverA.Rd0000644000175100017510000000211614614230661016157 0ustar00biocbuildbiocbuild\name{pOverA} \alias{pOverA} \title{A filter function to filter according to the proportion of elements larger than A. } \description{ A function that returns a function with values for \code{A}, \code{p} and \code{na.rm} bound to the specified values. The function takes a single vector, \code{x}, as an argument. When the returned function is evaluated it returns \code{TRUE} if the proportion of values in \code{x} that are larger than \code{A} is at least \code{p}. } \usage{ pOverA(p=0.05, A=100, na.rm=TRUE) } \arguments{ \item{A}{The value to be exceeded. } \item{p}{The proportion that need to exceed \code{A} for \code{TRUE} to be returned. } \item{na.rm}{ If \code{TRUE} then \code{NA}'s are removed. } } \value{ \code{pOverA} returns a function with bindings for \code{A}, \code{p} and \code{na.rm}. This function evaluates to \code{TRUE} if the proportion of values in \code{x} that are larger than \code{A} exceeds \code{p}. } \author{R. Gentleman} \seealso{ \code{\link{cv}} } \examples{ ff<- pOverA(p=.1, 10) ff(1:20) ff(1:5) } \keyword{manip} genefilter/man/rejection_plot.Rd0000644000175100017510000000530314614230661020004 0ustar00biocbuildbiocbuild\name{rejection_plot} \Rdversion{1.1} \alias{rejection_plot} \title{ Plot rejections vs. p-value cutoff } \description{ Plot the number, or fraction, of null hypotheses rejected as a function of the p-value cutoff. Multiple sets of p-values are accepted, in a list or in the columns of a matrix, in order to permit comparisons. } \usage{ rejection_plot(p, col, lty = 1, lwd = 1, xlab = "p cutoff", ylab = "number of rejections", xlim = c(0, 1), ylim, legend = names(p), at = c("all", "sample"), n_at = 100, probability = FALSE, ... ) } \arguments{ \item{p}{ The p-values to be used for plotting. These may be in the columns of a matrix, or in the elements of a list. One curve will be generated for each column/element, and all \code{NA} entries will be dropped. If column or element names are supplied, they are used by default for a plot legend. } \item{col}{ Colors to be used for each curve plotted. Recycled if necessary. If \code{col} is omitted, \code{\link{rainbow}} is used to generate a set of colors. } \item{lty}{ Line styles to be used for each curve plotted. Recycled if necessary. } \item{lwd}{ Line widths to be used for each curve plotted. Recycled if necessary. } \item{xlab}{ X-axis text label. } \item{ylab}{ Y-axis text label. } \item{xlim}{ X-axis limits. } \item{ylim}{ Y-axis limits. } \item{legend}{ Text for legend. Matrix column names or list element names (see \code{p} above) are used by default. If \code{NULL}, no legend is plotted. } \item{at}{ Should step functions be plotted with a step at every value in \code{p}, or should linear interpolation be used at a sample of points spanning \code{xlim}? The latter looks when there are many p-values. } \item{n_at}{ When \code{at = "sample"} is given, how many sample points should be used for interpolation and plotting? } \item{probability}{ Should the fraction of null hypotheses rejected be reported instead of the count? See the \code{probability} argument to \code{\link{hist}}. } \item{\dots}{ Other arguments to pass to the \code{\link{plot}} call which sets up the axes. Note that the \code{...} argument will not be passed to the \code{\link{lines}} calls which actually generate the curves. } } \value{ A list of the step functions used for plotting is returned invisibly. } \author{Richard Bourgon } \examples{ # See the vignette: Diagnostic plots for independent filtering } genefilter/man/rowFtests.Rd0000644000175100017510000001514514614230661016771 0ustar00biocbuildbiocbuild\name{rowFtests} \alias{rowFtests} \alias{rowFtests,matrix,factor-method} \alias{rowFtests,ExpressionSet,factor-method} \alias{rowFtests,ExpressionSet,character-method} \alias{colFtests} \alias{colFtests,matrix,factor-method} \alias{colFtests,ExpressionSet,factor-method} \alias{colFtests,ExpressionSet,character-method} \alias{rowttests} \alias{rowttests,matrix,factor-method} \alias{rowttests,matrix,missing-method} \alias{rowttests,ExpressionSet,factor-method} \alias{rowttests,ExpressionSet,character-method} \alias{rowttests,ExpressionSet,missing-method} \alias{colttests} \alias{colttests,matrix,factor-method} \alias{colttests,matrix,missing-method} \alias{colttests,ExpressionSet,factor-method} \alias{colttests,ExpressionSet,character-method} \alias{colttests,ExpressionSet,missing-method} \alias{fastT} \title{t-tests and F-tests for rows or columns of a matrix} \description{t-tests and F-tests for rows or columns of a matrix, intended to be speed efficient.} \usage{ rowttests(x, fac, tstatOnly = FALSE, na.rm = FALSE) colttests(x, fac, tstatOnly = FALSE, na.rm = FALSE) fastT(x, ig1, ig2, var.equal = TRUE) rowFtests(x, fac, var.equal = TRUE) colFtests(x, fac, var.equal = TRUE) } \arguments{ \item{x}{Numeric matrix. The matrix must not contain \code{NA} values. For \code{rowttests} and \code{colttests}, \code{x} can also be an \code{\link[Biobase:class.ExpressionSet]{ExpressionSet}}.} \item{fac}{Factor which codes the grouping to be tested. There must be 1 or 2 groups for the t-tests (corresponding to one- and two-sample t-test), and 2 or more for the F-tests. If \code{fac} is missing, this is taken as a one-group test (i.e. is only allowed for the t-tests). The length of the factor needs to correspond to the sample size: for the \code{row*} functions, the length of the factor must be the same as the number of columns of \code{x}, for the \code{col*} functions, it must be the same as the number of rows of \code{x}. If \code{x} is an \code{\link[Biobase:class.ExpressionSet]{ExpressionSet}}, then \code{fac} may also be a character vector of length 1 with the name of a covariate in \code{x}.} \item{tstatOnly}{A logical variable indicating whether to calculate p-values from the t-distribution with appropriate degrees of freedom. If \code{TRUE}, just the t-statistics are returned. This can be considerably faster.} \item{na.rm}{A logical variable indicating whether to remove NA values prior to calculation test statistics.} \item{ig1}{The indices of the columns of \code{x} that correspond to group 1.} \item{ig2}{The indices of the columns of \code{x} that correspond to group 2.} \item{var.equal}{A logical variable indicating whether to treat the variances in the samples as equal. If 'TRUE', a simple F test for the equality of means in a one-way analysis of variance is performed. If 'FALSE', an approximate method of Welch (1951) is used, which generalizes the commonly known 2-sample Welch test to the case of arbitrarily many samples.} } \details{ If \code{fac} is specified, \code{rowttests} performs for each row of \code{x} a two-sided, two-class t-test with equal variances. \code{fac} must be a factor of length \code{ncol(x)} with two levels, corresponding to the two groups. The sign of the resulting t-statistic corresponds to "group 1 minus group 2". If \code{fac} is missing, \code{rowttests} performs for each row of \code{x} a two-sided one-class t-test against the null hypothesis 'mean=0'. \code{rowttests} and \code{colttests} are implemented in C and should be reasonably fast and memory-efficient. \code{fastT} is an alternative implementation, in Fortran, possibly useful for certain legacy code. \code{rowFtests} and \code{colFtests} are currently implemented using matrix algebra in R. Compared to the \code{rowttests} and \code{colttests} functions, they are slower and use more memory. } \value{ A \code{data.frame} with columns \code{statistic}, \code{p.value} (optional in the case of the t-test functions) and \code{dm}, the difference of the group means (only in the case of the t-test functions). The \code{row.names} of the data.frame are taken from the corresponding dimension names of \code{x}. The degrees of freedom are provided in the attribute \code{df}. For the F-tests, if \code{var.equal} is 'FALSE', \code{nrow(x)+1} degree of freedoms are given, the first one is the first degree of freedom (it is the same for each row) and the other ones are the second degree of freedom (one for each row). } \references{B. L. Welch (1951), On the comparison of several mean values: an alternative approach. Biometrika, *38*, 330-336} \author{Wolfgang Huber } \seealso{\code{\link[multtest:mt.teststat]{mt.teststat}}} \examples{ ## ## example data ## x = matrix(runif(40), nrow=4, ncol=10) f2 = factor(floor(runif(ncol(x))*2)) f4 = factor(floor(runif(ncol(x))*4)) ## ## one- and two group row t-test; 4-group F-test ## r1 = rowttests(x) r2 = rowttests(x, f2) r4 = rowFtests(x, f4) ## approximate equality about.equal = function(x,y,tol=1e-10) stopifnot(is.numeric(x), is.numeric(y), length(x)==length(y), all(abs(x-y) < tol)) ## ## compare with the implementation in t.test ## for (j in 1:nrow(x)) { s1 = t.test(x[j,]) about.equal(s1$statistic, r1$statistic[j]) about.equal(s1$p.value, r1$p.value[j]) s2 = t.test(x[j,] ~ f2, var.equal=TRUE) about.equal(s2$statistic, r2$statistic[j]) about.equal(s2$p.value, r2$p.value[j]) dm = -diff(tapply(x[j,], f2, mean)) about.equal(dm, r2$dm[j]) s4 = summary(lm(x[j,] ~ f4)) about.equal(s4$fstatistic["value"], r4$statistic[j]) } ## ## colttests ## c2 = colttests(t(x), f2) stopifnot(identical(r2, c2)) ## ## missing values ## f2n = f2 f2n[sample(length(f2n), 3)] = NA r2n = rowttests(x, f2n) for(j in 1:nrow(x)) { s2n = t.test(x[j,] ~ f2n, var.equal=TRUE) about.equal(s2n$statistic, r2n$statistic[j]) about.equal(s2n$p.value, r2n$p.value[j]) } ## ## larger sample size ## x = matrix(runif(1000000), nrow=4, ncol=250000) f2 = factor(floor(runif(ncol(x))*2)) r2 = rowttests(x, f2) for (j in 1:nrow(x)) { s2 = t.test(x[j,] ~ f2, var.equal=TRUE) about.equal(s2$statistic, r2$statistic[j]) about.equal(s2$p.value, r2$p.value[j]) } ## single row matrix rowFtests(matrix(runif(10),1,10),as.factor(c(rep(1,5),rep(2,5)))) rowttests(matrix(runif(10),1,10),as.factor(c(rep(1,5),rep(2,5)))) } \keyword{math} genefilter/man/rowpAUCs.Rd0000644000175100017510000001305214614230661016467 0ustar00biocbuildbiocbuild\name{rowpAUCs-methods} \docType{methods} \alias{rowpAUCs-methods} \alias{rowpAUCs} \alias{rowpAUCs,matrix,factor-method} \alias{rowpAUCs,matrix,numeric-method} \alias{rowpAUCs,ExpressionSet,ANY-method} \alias{rowpAUCs,ExpressionSet,character-method} \title{Rowwise ROC and pAUC computation} \description{Methods for fast rowwise computation of ROC curves and (partial) area under the curve (pAUC) using the simple classification rule \code{x > theta}, where \code{theta} is a value in the range of \code{x} } \usage{ rowpAUCs(x, fac, p=0.1, flip=TRUE, caseNames=c("1", "2")) } \arguments{ \item{x}{\code{ExpressionSet} or numeric \code{matrix}. The \code{matrix} must not contain \code{NA} values.} \item{fac}{A \code{factor} or \code{numeric} or \code{character} that can be coerced to a \code{factor}. If \code{x} is an \code{ExpressionSet}, this may also be a character \code{vector} of length 1 with the name of a covariate variable in \code{x}. \code{fac} must have exactly 2 levels. For better control over the classification, use integer values in 0 and 1, where 1 indicates the "Disease" class in the sense of the Pepe et al paper (see below).} \item{p}{Numeric \code{vector} of length 1. Limit in (0,1) to integrate pAUC to.} \item{flip}{Logical. If \code{TRUE}, both classification rules \code{x > theta} and \code{x < theta} are tested and the (partial) area under the curve of the better one of the two is returned. This is appropriate for the cases in which the classification is not necessarily linked to higher expression values, but instead it is symmetric and one would assume both over- and under-expressed genes for both classes. You can set \code{flip} to \code{FALSE} if you only want to screen for genes which discriminate Disease from Control with the \code{x > theta} rule.} \item{caseNames}{The class names that are used when plotting the data. If \code{fac} is the name of the covariate variable in the \code{ExpressionSet} the function will use its levels as \code{caseNames}.} } \details{ Rowwise calculation of Receiver Operating Characteristic (ROC) curves and the corresponding partial area under the curve (pAUC) for a given data matrix or \code{ExpressionSet}. The function is implemented in C and thus reasonably fast and memory efficient. Cutpoints (\code{theta} are calculated before the first, in between and after the last data value. By default, both classification rules \code{x > theta} and \code{x < theta} are tested and the (partial) area under the curve of the better one of the two is returned. This is only valid for symmetric cases, where the classification is independent of the magnitude of \code{x} (e.g., both over- and under-expression of different genes in the same class). For unsymmetric cases in which you expect x to be consistently higher/lower in of of the two classes (e.g. presence or absence of a single biomarker) set \code{flip=FALSE} or use the functionality provided in the \code{ROC} package. For better control over the classification (i.e., the choice of "Disease" and "Control" class in the sense of the Pepe et al paper), argument \code{fac} can be an integer in \code{[0,1]} where 1 indicates "Disease" and 0 indicates "Control". } \section{Methods}{ \describe{ Methods exist for \code{rowPAUCs}: \item{rowPAUCs}{\code{signature(x="matrix", fac="factor")}} \item{rowPAUCs}{\code{signature(x="matrix", fac="numeric")}} \item{rowPAUCs}{\code{signature(x="ExpressionSet")}} \item{rowPAUCs}{\code{signature(x="ExpressionSet", fac="character")}} } } \value{ An object of class \code{\link[genefilter:rowROC-class]{rowROC}} with the calculated specificities and sensitivities for each row and the corresponding pAUCs and AUCs values. See \code{\link[genefilter:rowROC-class]{rowROC}} for details. } \references{Pepe MS, Longton G, Anderson GL, Schummer M.: Selecting differentially expressed genes from microarray experiments. \emph{Biometrics. 2003 Mar;59(1):133-42.}} \author{Florian Hahne } \seealso{\code{\link[ROC:rocdemo.sca]{rocdemo.sca}, \link[ROC:AUC]{pAUC}, \link[genefilter:rowROC-class]{rowROC}}} \examples{ library(Biobase) data(sample.ExpressionSet) r1 = rowttests(sample.ExpressionSet, "sex") r2 = rowpAUCs(sample.ExpressionSet, "sex", p=0.1) plot(area(r2, total=TRUE), r1$statistic, pch=16) sel <- which(area(r2, total=TRUE) > 0.7) plot(r2[sel]) ## this compares performance and output of rowpAUCs to function pAUC in ## package ROC if(require(ROC)){ ## performance myRule = function(x) pAUC(rocdemo.sca(truth = as.integer(sample.ExpressionSet$sex)-1 , data = x, rule = dxrule.sca), t0 = 0.1) nGenes = 200 cat("computation time for ", nGenes, "genes:\n") cat("function pAUC: ") print(system.time(r3 <- esApply(sample.ExpressionSet[1:nGenes, ], 1, myRule))) cat("function rowpAUCs: ") print(system.time(r2 <- rowpAUCs(sample.ExpressionSet[1:nGenes, ], "sex", p=1))) ## compare output myRule2 = function(x) pAUC(rocdemo.sca(truth = as.integer(sample.ExpressionSet$sex)-1 , data = x, rule = dxrule.sca), t0 = 1) r4 <- esApply(sample.ExpressionSet[1:nGenes, ], 1, myRule2) plot(r4,area(r2), xlab="function pAUC", ylab="function rowpAUCs", main="pAUCs") plot(r4, area(rowpAUCs(sample.ExpressionSet[1:nGenes, ], "sex", p=1, flip=FALSE)), xlab="function pAUC", ylab="function rowpAUCs", main="pAUCs") r4[r4<0.5] <- 1-r4[r4<0.5] plot(r4, area(r2), xlab="function pAUC", ylab="function rowpAUCs", main="pAUCs") } } \keyword{math} genefilter/man/rowROC-class.Rd0000644000175100017510000000672414614230661017252 0ustar00biocbuildbiocbuild\name{rowROC-class} \docType{class} \alias{rowROC} \alias{rowROC-class} \alias{pAUC} \alias{AUC} \alias{sens} \alias{spec} \alias{area} \alias{pAUC,rowROC,numeric-method} \alias{plot,rowROC,missing-method} \alias{AUC,rowROC-method} \alias{spec,rowROC-method} \alias{sens,rowROC-method} \alias{area,rowROC-method} \alias{show,rowROC-method} \alias{[,rowROC,ANY,ANY,ANY-method} \title{Class "rowROC"} \description{A class to model ROC curves and corresponding area under the curve as produced by rowpAUCs.} \section{Objects from the Class}{ Objects can be created by calls of the form \code{new("rowROC", ...)}. } \section{Slots}{ \describe{ \item{\code{data}:}{Object of class \code{"matrix"} The input data.} \item{\code{ranks}:}{Object of class \code{"matrix"} The ranked input data. } \item{\code{sens}:}{Object of class \code{"matrix"} Matrix of senitivity values for each gene at each cutpoint. } \item{\code{spec}:}{Object of class \code{"matrix"} Matrix of specificity values for each gene at each cutpoint.} \item{\code{pAUC}:}{Object of class \code{"numeric"} The partial area under the curve (integrated from 0 to \code{p}. } \item{\code{AUC}:}{Object of class \code{"numeric"} The total area under the curve. } \item{\code{factor}:}{Object of class \code{"factor"} The factor used for classification.} \item{\code{cutpoints}:}{Object of class \code{"matrix"} The values of the cutpoints at which specificity ans sensitivity was calculated. (Note: the data is ranked prior to computation of ROC curves, the cutpoints map to the ranked data.} \item{\code{caseNames}:}{Object of class \code{"character"} The names of the two classification cases.} \item{\code{p}:}{Object of class \code{"numeric"} The limit to which \code{pAUC} is integrated. } } } \section{Methods}{ \describe{ \item{show \code{signature(object="rowROC")}}{Print nice info about the object.} \item{[ \code{signature(x="rowROC", j="missing")}}{Subset the object according to rows/genes.} \item{plot \code{signature(x="rowROC", y="missing")}}{Plot the ROC curve of the first row of the object along with the \code{pAUC}. To plot the curve for a specific row/gene subsetting should be done first (i.e. \code{plot(rowROC[1])}.} \item{pAUC \code{signature(object="rowROC", p="numeric", flip="logical")}}{Integrate area under the curve from \code{0} to \code{p}. This method returns a new \code{rowROC} object.} \item{AUC \code{signature(object="rowROC")}}{Integrate total area under the curve. This method returns a new \code{rowROC} object.} \item{sens \code{signature(object="rowROC")}}{Accessor method for sensitivity slot.} \item{spec \code{signature(object="rowROC")}}{Accessor method for specificity slot.} \item{area \code{signature(object="rowROC", total="logical")}}{Accessor method for pAUC slot.} } } \references{Pepe MS, Longton G, Anderson GL, Schummer M.: Selecting differentially expressed genes from microarray experiments. \emph{Biometrics. 2003 Mar;59(1):133-42.}} \author{Florian Hahne } \seealso{ \code{\link[genefilter:rowpAUCs]{rowpAUCs}} } \examples{ library("Biobase") data("sample.ExpressionSet") roc <- rowpAUCs(sample.ExpressionSet, "sex", p=0.5) roc area(roc[1:3]) if(interactive()) { par(ask=TRUE) plot(roc) plot(1-spec(roc[1]), sens(roc[2])) par(ask=FALSE) } pAUC(roc, 0.1) roc } \keyword{classes} genefilter/man/rowSds.Rd0000644000175100017510000000210014614230661016235 0ustar00biocbuildbiocbuild\name{rowSds} \alias{rowSds} \alias{rowVars} \title{Row variance and standard deviation of a numeric array} \description{ Row variance and standard deviation of a numeric array } \usage{ rowVars(x, ...) rowSds(x, ...) } \arguments{ \item{x}{An array of two or more dimensions, containing numeric, complex, integer or logical values, or a numeric data frame.} \item{...}{Further arguments that get passed on to \code{\link{rowMeans}} and \code{\link{rowSums}}.} } \value{ A numeric or complex array of suitable size, or a vector if the result is one-dimensional. The `dimnames' (or `names' for a vector result) are taken from the original array. } \details{These are very simple convenience functions, the main work is done in \code{\link{rowMeans}} and \code{\link{rowSums}}. See the function definition of \code{rowVars}, it is very simple. } \author{Wolfgang Huber \url{http://www.ebi.ac.uk/huber}} \seealso{\code{\link{rowMeans}} and \code{\link{rowSums}}} \examples{ a = matrix(rnorm(1e4), nrow=10) rowSds(a) } \keyword{array} \keyword{manip} genefilter/man/shorth.Rd0000644000175100017510000000541414614230661016276 0ustar00biocbuildbiocbuild\name{shorth} \alias{shorth} \title{A location estimator based on the shorth} \description{A location estimator based on the shorth} \usage{shorth(x, na.rm=FALSE, tie.action="mean", tie.limit=0.05)} \arguments{ \item{x}{Numeric} \item{na.rm}{Logical. If \code{TRUE}, then non-finite (according to \code{\link{is.finite}}) values in \code{x} are ignored. Otherwise, presence of non-finite or \code{NA} values will lead to an error message.} \item{tie.action}{Character scalar. See details.} \item{tie.limit}{Numeric scalar. See details.} } \details{The shorth is the shortest interval that covers half of the values in \code{x}. This function calculates the mean of the \code{x} values that lie in the shorth. This was proposed by Andrews (1972) as a robust estimator of location. Ties: if there are multiple shortest intervals, the action specified in \code{ties.action} is applied. Allowed values are \code{mean} (the default), \code{max} and \code{min}. For \code{mean}, the average value is considered; however, an error is generated if the start indices of the different shortest intervals differ by more than the fraction \code{tie.limit} of \code{length(x)}. For \code{min} and \code{max}, the left-most or right-most, respectively, of the multiple shortest intervals is considered. Rate of convergence: as an estimator of location of a unimodal distribution, under regularity conditions, the quantity computed here has an asymptotic rate of only \eqn{n^{-1/3}} and a complicated limiting distribution. See \code{\link{half.range.mode}} for an iterative version that refines the estimate iteratively and has a builtin bootstrapping option. } \value{The mean of the \code{x} values that lie in the shorth.} \references{ \itemize{ \item G Sawitzki, \dQuote{The Shorth Plot.} Available at http://lshorth.r-forge.r-project.org/TheShorthPlot.pdf \item DF Andrews, \dQuote{Robust Estimates of Location.} Princeton University Press (1972). \item R Grueble, \dQuote{The Length of the Shorth.} Annals of Statistics 16, 2:619-628 (1988). \item DR Bickel and R Fruehwirth, \dQuote{On a fast, robust estimator of the mode: Comparisons to other robust estimators with applications.} Computational Statistics & Data Analysis 50, 3500-3530 (2006). } } \author{Wolfgang Huber \url{http://www.ebi.ac.uk/huber}, Ligia Pedroso Bras} \seealso{\code{\link{half.range.mode}}} \examples{ x = c(rnorm(500), runif(500) * 10) methods = c("mean", "median", "shorth", "half.range.mode") ests = sapply(methods, function(m) get(m)(x)) if(interactive()) { colors = 1:4 hist(x, 40, col="orange") abline(v=ests, col=colors, lwd=3, lty=1:2) legend(5, 100, names(ests), col=colors, lwd=3, lty=1:2) } } \keyword{arith} genefilter/man/tdata.Rd0000644000175100017510000000067414614230661016067 0ustar00biocbuildbiocbuild\name{tdata} \alias{tdata} \non_function{} \title{A small test dataset of Affymetrix Expression data. } \usage{data(tdata)} \description{ The \code{tdata} data frame has 500 rows and 26 columns. The columns correspond to samples while the rows correspond to genes. The row names are Affymetrix accession numbers. } \format{ This data frame contains 26 columns. } \source{ An unknown data set. } \examples{ data(tdata) } \keyword{datasets} genefilter/man/ttest.Rd0000644000175100017510000000314014614230661016124 0ustar00biocbuildbiocbuild\name{ttest} \alias{ttest} \title{A filter function for a t.test } \description{ \code{ttest} returns a function of one argument with bindings for \code{cov} and \code{p}. The function, when evaluated, performs a t-test using \code{cov} as the covariate. It returns \code{TRUE} if the p value for a difference in means is less than \code{p}. } \usage{ ttest(m, p=0.05, na.rm=TRUE) } \arguments{ \item{m}{If \code{m} is of length one then it is assumed that elements one through \code{m} of \code{x} will be one group. Otherwise \code{m} is presumed to be the same length as \code{x} and constitutes the groups.} \item{p}{ The p-value for the test. } \item{na.rm}{If set to \code{TRUE} any \code{NA}'s will be removed. } } \details{ When the data can be split into two groups (diseased and normal for example) then we often want to select genes on their ability to distinguish those two groups. The t-test is well suited to this and can be used as a filter function. This helper function creates a t-test (function) for the specified covariate and considers a gene to have passed the filter if the p-value for the gene is less than the prespecified \code{p}. } \value{ \code{ttest} returns a function with bindings for \code{m} and \code{p} that will perform a t-test. } \author{R. Gentleman } \seealso{\code{\link{kOverA}}, \code{\link{Anova}}, \code{\link{t.test}} } \examples{ dat <- c(rep(1,5),rep(2,5)) set.seed(5) y <- rnorm(10) af <- ttest(dat, .01) af(y) af2 <- ttest(5, .01) af2(y) y[8] <- NA af(y) af2(y) y[1:5] <- y[1:5]+10 af(y) } \keyword{manip} genefilter/NAMESPACE0000644000175100017510000000501114614230661015135 0ustar00biocbuildbiocbuilduseDynLib(genefilter) importClassesFrom(Biobase, ExpressionSet) importClassesFrom(methods, ANY, character, factor, matrix, missing, numeric, vector) importMethodsFrom(AnnotationDbi, as.list, colnames, get, mget, ncol, nrow, sample, dbmeta) importMethodsFrom(Biobase, annotation, exprs, featureNames, pData, rowQ, varLabels) importMethodsFrom(methods, "body<-", show) importFrom(MatrixGenerics, rowSums, colSums, rowMeans, colMeans) importFrom(Biobase, addVigs2WinMenu, subListExtract) importFrom(annotate, getAnnMap) importFrom(graphics, abline, lines, par, plot, points, polygon, rect, strheight, strwidth, text, legend, segments) importFrom(grDevices, rainbow) importFrom(methods, is, new) importFrom(stats, IQR, anova, lm, pchisq, pf, pt, quantile, sd, t.test, na.omit, p.adjust, qt, stepfun) importFrom(survival, coxph) export(Anova, coxfilter, cv, eSetFilter, varFilter, featureFilter, fastT, ttest, shorth, half.range.mode, rowttests, colttests, rowFtests, colFtests, rowSds, rowVars, dist2, filterfun, findLargest, gapFilter, genefilter, genescale, getFilterNames, getFuncDesc, getRdAsText, isESet, kOverA, maxA, pOverA, parseArgs, parseDesc, setESetArgs, showESet, kappa_t, kappa_p, filtered_p, filtered_R, rejection_plot, filter_volcano) exportClasses(rowROC) exportMethods(genefinder, show, plot, "[", sens, spec, area, pAUC, AUC, rowpAUCs, nsFilter) genefilter/NEWS0000644000175100017510000000053014614230661014416 0ustar00biocbuildbiocbuildCHANGES IN VERSION 1.64.0 ------------------------- NEW FEATURES o Add `na.rm =` to row/colttests, requested by https://github.com/Bioconductor/genefilter/issues/1 CHANGES IN VERSION 1.54.0 ------------------------- DEPRECATED AND DEFUNCT o remove deprecated anyNA(); contradicted base::anyNA o remove deprecated allNA() genefilter/R/0000755000175100017510000000000014614230661014122 5ustar00biocbuildbiocbuildgenefilter/R/all.R0000644000175100017510000001031714614230661015017 0ustar00biocbuildbiocbuild#copyright 2001 R. Gentleman #FILTER FUNCTIONS -- some trivial changes kOverA <- function(k, A=100, na.rm = TRUE) { function(x) { if(na.rm) x <- x[!is.na(x)] sum( x > A ) >= k } } maxA <- function(A=75, na.rm=TRUE) { function(x) {max(x, na.rm=na.rm) >= A } } pOverA <- function(p=0.05, A=100, na.rm = TRUE) { function(x) { if(na.rm) x<-x[!is.na(x)] sum( x > A )/length(x) >= p } } cv <- function(a=1, b=Inf, na.rm=TRUE) { function(x) { sdx <- sd(x, na.rm=na.rm) if(is.na(sdx) || sdx == 0 ) return(FALSE) val <- sdx/abs(mean(x, na.rm=na.rm)) if(val < a ) return(FALSE) if(val > b ) return(FALSE) return(TRUE) } } Anova <- function(cov, p=0.05, na.rm=TRUE) { function(x) { if( na.rm ) { drop <- is.na(x) x <- x[!drop] cov <- cov[!drop] } m1 <- lm(x~cov) m2 <- lm(x~1) av <- anova(m2,m1) fstat <- av[["Pr(>F)"]][2] if( fstat < p ) return(TRUE) return(FALSE) } } coxfilter <- function(surt, cens, p) { autoload("coxph", "survival") function(x) { srvd <- try(coxph(Surv(surt,cens)~x)) if( inherits(srvd, "try-error") ) return(FALSE) ltest <- -2*(srvd$loglik[1] - srvd$loglik[2]) pv <- 1 - pchisq(ltest, 1) if( pv < p ) return(TRUE) return(FALSE) } } ttest <- function(m, p=0.05, na.rm=TRUE) { if( length(m) == 1) function(x) { n <- length(x) if( m>n ) stop("m is larger than the number of samples") sub1 <- x[1:m] sub2 <- x[(m+1):n] if(na.rm) { drop <- is.na(x) sub1 <- sub1[!drop[1:m]] sub2 <- sub2[!drop[(m+1):n]] } t.test(sub1, sub2 )$p.value < p } else function(x) { if(na.rm) { drop <- is.na(x) | is.na(m) x<- x[!drop] m<- m[!drop] } t.test(x~m)$p.value < p } } ##a filter based on gaps gapFilter <- function(Gap, IQR, Prop, na.rm=TRUE, neg.rm=TRUE) { function(x) { if(na.rm) x <- x[!is.na(x)] if(neg.rm) x <- x[x>0] lenx <- length(x) if( lenx < 4 || lenx < Prop+1 ) return(FALSE) srtd <- sort(x) lq <- lenx*.25 uq <- lenx*.75 if( (srtd[uq] - srtd[lq]) > IQR ) return(TRUE) if(Prop < 1) bot <- lenx*Prop else bot <- Prop top <- lenx - bot lag1 <- srtd[2:lenx]-srtd[1:(lenx-1)] if( max(lag1[bot:top]) > Gap ) return(TRUE) return(FALSE) } } # Apply type functions genefilter <- function(expr, flist) { if(is(expr, "ExpressionSet")) expr <- exprs(expr) apply(expr, 1, flist) } filterfun <- function(...) { flist <- list(...) #let the user supply a list if( length(flist) == 1 && is.list(flist[[1]]) ) flist <- flist[[1]] f <- function( x ) { for( fun in flist ) { fval <- fun(x) if( is.na(fval) || ! fval ) return(FALSE) } return(TRUE) } class(f) <- "filterfun" return(f) } .findDBMeta <- function(chip, item) { connfunc <- getAnnMap("_dbconn", chip) dbmeta(connfunc(), item) } .isOrgSchema <- function(chip){ schema <- .findDBMeta(chip, "DBSCHEMA") length(grep("CHIP", schema)) == 0 } .findCentralMap<- function(chip){ centID <- .findDBMeta(chip, "CENTRALID") if(!.isOrgSchema(chip) && centID == "TAIR") { "ACCNUM" ## a peculiar exception with historical causes } else { centID ## should cover EVERYTHING else } } findLargest = function(gN, testStat, data="hgu133plus2") { lls = if(.isOrgSchema(data)){ gN ##not a chip package so try the IDs presented. } else { map = .findCentralMap(data) unlist(mget(gN, getAnnMap(map, data)), use.names=FALSE) } if(length(testStat) != length(gN) ) stop("testStat and gN must be the same length") if( is.null(names(testStat)) ) names(testStat) = gN tSsp = split.default(testStat, lls) sapply(tSsp, function(x) names(which.max(x))) } genefilter/R/AllClasses.R0000644000175100017510000000332714614230661016300 0ustar00biocbuildbiocbuild## Classes for package genefilter ## ========================================================================== ## class rowROC: objects model result of call to function rowpAUCs, ## pAUC or AUC ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setClass("rowROC", representation(data = "matrix", ranks = "matrix", sens = "matrix", spec = "matrix", pAUC = "numeric", AUC = "numeric", factor = "factor", cutpoints = "matrix", caseNames = "character", p = "numeric"), validity=function(object){ if(any(dim(object@sens) != dim(object@spec))) return("\n'sens' and 'spec' must be matrices with equal dimensions") if(length(object@pAUC) != nrow(object@sens)) return("\n'pAUC' must be numeric of length equal to nrow(sens)") if(length(object@factor)!=ncol(object@data) || length(levels(object@factor))!=2) return("'factor' must be factor object with two levels and length = ncol(data)") if(length(object@pAUC) != length(object@AUC)) return("'pAUC' and 'AUC' must be numeric vectors of equal length") if(nrow(object@cutpoints) != length(object@pAUC)) return("'cutpoints' must be matrix with nrow=length(pAUC)") if(length(object@caseNames)!=2) return("'caseNames' must be character vector of length 2") return(TRUE) } ) ## ========================================================================== genefilter/R/AllGenerics.R0000644000175100017510000000306414614230661016440 0ustar00biocbuildbiocbuild## Generic functions for package genefilter setGeneric("rowFtests", function(x, fac, var.equal=TRUE) standardGeneric("rowFtests")) setGeneric("colFtests", function(x, fac, var.equal=TRUE) standardGeneric("colFtests")) setGeneric("rowttests", function(x, fac, tstatOnly=FALSE, na.rm = FALSE) standardGeneric("rowttests")) setGeneric("colttests", function(x, fac, tstatOnly=FALSE, na.rm = FALSE) standardGeneric("colttests")) setGeneric("genefinder", function(X, ilist, numResults=25, scale="none", weights, method="euclidean" ) standardGeneric("genefinder")) setGeneric("pAUC", function(object, p, flip=TRUE) standardGeneric("pAUC")) setGeneric("AUC", function(object) standardGeneric("AUC")) setGeneric("sens", function(object) standardGeneric("sens")) setGeneric("spec", function(object) standardGeneric("spec")) setGeneric("area", function(object, total=FALSE) standardGeneric("area")) setGeneric("rowpAUCs", function(x, fac, p=0.1, flip=TRUE, caseNames=c("1", "2")) standardGeneric("rowpAUCs")) setGeneric("nsFilter", signature="eset", function(eset, require.entrez=TRUE, require.GOBP=FALSE, require.GOCC=FALSE, require.GOMF=FALSE, require.CytoBand=FALSE, remove.dupEntrez=TRUE, var.func=IQR, var.cutoff=0.5, var.filter=TRUE, filterByQuantile=TRUE, feature.exclude="^AFFX", ...) standardGeneric("nsFilter")) genefilter/R/dist2.R0000644000175100017510000000114414614230661015272 0ustar00biocbuildbiocbuilddist2 = function (x, fun = function(a, b) mean(abs(a - b), na.rm = TRUE), diagonal = 0) { if (!(is.numeric(diagonal) && (length(diagonal) == 1))) stop("'diagonal' must be a numeric scalar.") if (missing(fun)) { res = apply(x, 2, function(w) colMeans(abs(x-w), na.rm=TRUE)) } else { res = matrix(diagonal, ncol = ncol(x), nrow = ncol(x)) if (ncol(x) >= 2) { for (j in 2:ncol(x)) for (i in 1:(j - 1)) res[i, j] = res[j, i] = fun(x[, i], x[, j]) } # if } # else colnames(res) = rownames(res) = colnames(x) return(res) } genefilter/R/eSetFilter.R0000644000175100017510000003034314614230661016316 0ustar00biocbuildbiocbuild# This widget allows users to pick filters in the order they are going # to be used to filer genes and set the parameters for # each filter. # # Copyright 2003, J. Zhang. All rights reserved. # eSetFilter <- function(eSet){ # # 2020-12-31 Wolfgang Huber: marking this as deprecated due to dubious coding style # (leading to many notes in R CMD check), lack of maintenance, apparently minuscule # update (e.g. I did not find a single mention of this function with # https://support.bioconductor.org/post/search/?query=esetfilter today) and # availability of better alternatives. # .Deprecated(new = "iSEE", old = "eSetFilter") require("tkWidgets", character.only = TRUE) || stop("eSetFilter requires the tkWidgets ", "package. Please have it installed") descList <- getFuncDesc() buildGUI <- function(){ END <<- FALSE selectedNames <- NULL filterWithArgs <- list() setFilter <- function(){ currentFilter <- as.character(tkget(filters, (tkcurselection(filters)))) args <- setESetArgs(currentFilter) if(!is.null(args)){ expression <- paste(currentFilter, "(", paste(names(args), args, sep = "=", collapse = ","), ")", sep = "") filterWithArgs[[currentFilter]] <<- eval(parse(text = expression)) selectedNames <<- unique(c(selectedNames, currentFilter)) writeList(pickedF, selectedNames) tkconfigure(selectBut, state = "disabled") } } cancel <- function(){ tkdestroy(base) } finish <- function(){ END <<- TRUE tkdestroy(base) } viewFilter <- function(){ currentFilter <- as.character(tkget(filters, (tkcurselection(filters)))) tkconfigure(description, state = "normal") writeText(description, descList[[currentFilter]]) tkconfigure(description, state = "disabled") tkconfigure(selectBut, state = "normal") } pickedSel <- function(){ tkconfigure(remBut, state = "normal") } remove <- function(){ filter <- as.character(tkget(pickedF, (tkcurselection(pickedF)))) selectedNames <<- setdiff(selectedNames, filter) writeList(pickedF, selectedNames) tkconfigure(remBut, state = "disabled") } base <- tktoplevel() tktitle(base) <- "BioC Filter Master" # Pack the top frame with a brief description introText <- tktext(base, width = 30, height = 4, wrap = "word") text <- paste("Bioconductor's gene filtering functons are", "listed below. Select one from the list to view the", "description and formal arguments for each filter.", "A filter can be selected to the set of filters", "for filtering genes using the select button.") writeText(introText, text) tkconfigure(introText, state = "disabled") tkpack(introText, expand = FALSE, fill = "both", padx = 5) # Pack a frame with a list box for selected filters and # buttons manipulate the selected filters infoFrame <- tkframe(base) filterFrame <- tkframe(infoFrame) tkpack(tklabel(filterFrame, text = "Filters"), expand = FALSE, fill = "x") listFrame <- tkframe(filterFrame) filters <- makeViewer(listFrame, vHeight = 10, vWidth = 12, vScroll = TRUE, hScroll = TRUE, what = "list") tkbind(filters, "", viewFilter) tkbind(filters, "", setFilter) writeList(filters, getFilterNames()) tkpack(listFrame, expand = TRUE, fill = "both") selectBut <- tkbutton(filterFrame, text = "Select", command = setFilter, state = "disabled") tkpack(selectBut, expand = FALSE, fill = "x") tkpack(filterFrame, side = "left", expand = FALSE, fill = "both") descFrame <- tkframe(infoFrame) tkpack(tklabel(descFrame, text = "Description"), expand = FALSE, fill = "x") dListFrame <- tkframe(descFrame) description <- makeViewer(dListFrame, vHeight = 10, vWidth = 30, vScroll = TRUE, hScroll = TRUE, what = "text") tkconfigure(description, wrap = "word", state = "disabled") tkpack(dListFrame, expand = TRUE, fill = "both") tkpack(descFrame, side = "left", expand = TRUE, fill = "both") selFrame <- tkframe(infoFrame) tkpack(tklabel(selFrame, text = "Selected"), expand = FALSE, fill = "x") selFFrame <- tkframe(selFrame) pickedF <- makeViewer(selFFrame, vHeight = 10, vWidth = 12, vScroll = TRUE, hScroll = TRUE, what = "list") tkbind(pickedF, "", pickedSel) tkbind(pickedF, "", remove) tkpack(selFFrame, expand = TRUE, fill = "both") remBut <- tkbutton(selFrame, text = "Remove", command = remove, state = "disabled") tkpack(remBut, expand = FALSE, fill = "x") tkpack(selFrame, expand = FALSE, fill = "both") tkpack(infoFrame, expand = TRUE, fill = "both", padx = 5) # Pack the bottom frame with cancel and finish buttons endFrame <- tkframe(base) cancelBut <- tkbutton(endFrame, width = 8, text = "Cancel", command = cancel) tkpack(cancelBut, side = "left", expand = TRUE, fill = "x", padx = 10) finishBut <- tkbutton(endFrame, width = 8, text = "finish", command = finish) tkpack(finishBut, side = "left", expand = TRUE, fill = "x", padx = 10) tkpack(endFrame, expand = FALSE, fill = "x", pady = 5) showESet(eSet) tkwait.window(base) if(END){ tempList <- list() for(i in selectedNames){ tempList[[i]] <- filterWithArgs[[i]] } return(tempList) }else{ return(NULL) } } filters <- buildGUI() if(!is.null(filters)){ filters <- filterfun(unlist(filters)) return(genefilter(exprs(eSet), filters)) }else{ return(NULL) } } getFilterNames <- function(){ .Deprecated() return(sort(c("Anova", "coxfilter", "cv", "gapFilter", "kOverA", "maxA", "pOverA", "ttest"))) } getFuncDesc <- function(lib = "genefilter", funcs = getFilterNames()){ .Deprecated() descList <- list() lines <- getRdAsText(lib) for(i in funcs){ rd <- lines[grep(paste("\\\\name\\{", i, "\\}", sep = ""), lines)] desc <- parseDesc(rd) args <- parseArgs(rd) if(length(args) > 0){ temp <- "\n\nArguments:" for(j in names(args)){ temp <- c(temp, paste(j, "-", args[[j]])) } args <- paste(temp, sep = "", collapse = "\n") } descList[[i]] <- paste(desc, args, sep = "", collapse = "") } return(descList) } getRdAsText <- function(lib){ .Deprecated() fileName <- gzfile(file.path(.path.package(lib), "man", paste(lib, ".Rd.gz", sep = "")), open = "r") lines <- readLines(fileName) lines <- paste(lines, sep = "", collapse = " ") lines <- unlist(strsplit(lines, "\\\\eof")) return(lines) } parseDesc <- function(text){ .Deprecated() descRExp <- ".*\\\\description\\{(.*)\\}.*\\\\usage\\{.*" text <- gsub(descRExp, "\\1", text) text <- gsub("(\\\\[a-zA-Z]*\\{|\\})", "", text) return(text) } parseArgs <- function(text){ .Deprecated() argsList <- list() text <- gsub(".*\\\\arguments\\{(.*)\\}.*\\\\details\\{.*", "\\1", text) text <- gsub(".*\\\\arguments\\{(.*)\\}.*\\\\value\\{.*", "\\1", text) text <- unlist(strsplit(text, "\\\\item\\{")) text <- gsub("(\\\\[a-zA-Z]*\\{|\\})", "", text) for(i in text){ i <- unlist(strsplit(i, "\\{")) if(length(i) > 1){ argsList[[i[1]]] <- i[2] } } return(argsList) } showESet <- function(eSet){ .Deprecated() end <- function(){ tkdestroy(base) } if(!is(eSet, "eSet")){ stop() } colNRow <- dim(exprs(eSet)) vl <- varLabels(eSet) text <- c(paste("Genes: ", colNRow[1]), paste("Samples: ", colNRow[2], sep = ""), "Variable labels:", paste(names(vl), ": ", vl[1:length(vl)], sep = "")) base <- tktoplevel() tktitle(base) <- "BioC ExpressionSet viewer" dataDescFrame <- tkframe(base) data <- makeViewer(dataDescFrame, vHeight = 10, vWidth = 25, vScroll = TRUE, hScroll = TRUE, what = "list") writeList(data, text) tkpack(dataDescFrame, expand = TRUE, fill = "both") endBut <- tkbutton(base, text = "Finish", command = end) tkpack(endBut, expand = FALSE, fill = "x", pady = 5) } setESetArgs <- function(filter){ .Deprecated() on.exit(tkdestroy(base)) cancel <- function(){ tkdestroy(base) } end <- function(){ END <<- TRUE tkdestroy(base) } END <- FALSE argsVar <- list() desc <- list() entries <- list() ftFun <- list() args <- getRdAsText("genefilter") args <- args[grep(paste("\\\\name\\{", filter, "\\}", sep = ""), args)] args <- parseArgs(args) argValues <- formals(filter) base <- tktoplevel() tktitle(base) <- "BioC Filter Argument input" tkgrid(tklabel(base, text = "Arguments"), tklabel(base, text = "Descriptions"), tklabel(base, text = "Values")) for(i in names(args)){ argsVar[[i]] <- tclVar(as.character(argValues[[i]])) tempFrame <- tkframe(base) desc[[i]] <- makeViewer(tempFrame, vHeight = 3, vWidth = 55, vScroll = FALSE, hScroll = FALSE, what = "text") writeText(desc[[i]], args[[i]]) tkconfigure(desc[[i]], wrap = "word", state = "disabled") entries[[i]] <- tkentry(base, textvariable = argsVar[[i]], width = 10) tkgrid(tklabel(base, text = i), tempFrame, entries[[i]]) if(any(as.character(argValues[[i]]) == c("FALSE", "TRUE"))){ ftFun[[i]] <- function(){} body <- list(as.name("{"), substitute(eval(if(tclvalue(argsVar[[j]]) == "TRUE"){ writeList(entries[[j]], "FALSE")}else{ writeList(entries[[j]], "TRUE")}), list(j = i))) body(ftFun[[i]]) <- as.call(body) tkbind(entries[[i]],"", ftFun[[i]]) } tkgrid.configure(tempFrame, sticky = "eswn") } butFrame <- tkframe(base) canBut <- tkbutton(butFrame, text = "cancel", width = 8, command = cancel) endBut <- tkbutton(butFrame, text = "Finish", width = 8, comman = end) tkpack(canBut, side = "left", expand = FALSE, fill = "x") tkpack(endBut, side = "left", expand = FALSE, fill = "x") tkgrid(butFrame, columnspan = 3) tkwait.window(base) if(END){ for(i in names(argValues)){ argValues[[i]] <- tkWidgets:::formatArg(tclvalue(argsVar[[i]])) } return(argValues) }else{ return(NULL) } } isESet <- function(eSet){ .Deprecated() if(missing(eSet) || (!is(eSet, "ExpressionSet"))) { tkmessageBox(title = "Input Error", message = paste("filterMaster has to take", "an object of class ExpressionSet"), icon = "warning", type = "ok") return(FALSE) }else{ return(TRUE) } } genefilter/R/fastT.R0000644000175100017510000000200414614230661015322 0ustar00biocbuildbiocbuild ##FIXME: this could replace the code further below at some point, ## but only when it has the var.equal option ##-------------------------------------------------- ## fastT ##-------------------------------------------------- #fastT = function(x, ig1, ig2, var.equal=TRUE) { # fac = rep(NA, ncol(x)) # fac[ig1] = 0 # fac[ig2] = 1 # .Call("rowcolttests", x, as.integer(fac), as.integer(2), # as.integer(0), PACKAGE="genefilter") #} fastT = function(x, ig1, ig2, var.equal=TRUE) { ng1=length(ig1) ng2 = length(ig2) if( ncol(x) != ng1+ng2) stop("wrong sets of columns") outd = x[,c(ig1, ig2),drop=FALSE] nr = nrow(outd) z = rep(0, nr) dm = rep(0, nr) Z = .Fortran("fastt", d=as.single(outd), as.integer(nr), as.integer(ng1+ng2), as.integer(ng1), z = as.single(z), dm = as.single(dm), var.equal=as.integer(var.equal), ratio = as.integer(as.integer(0)), PACKAGE="genefilter") return(list(z = Z$z, dm=Z$dm, var.equal=Z$var.equal)) } genefilter/R/filter_volcano.R0000644000175100017510000000300714614230661017253 0ustar00biocbuildbiocbuildfilter_volcano <- function( d, p, S, n1, n2, alpha, S_cutoff, cex = .5, pch = 19, xlab = expression( paste( log[2], " fold change" ) ), ylab = expression( paste( "-", log[10], " p" ) ), cols = c( "grey80", "grey50", "black" ), ltys = c( 1, 3 ), use_legend = TRUE, ... ) { f <- S < S_cutoff col <- rep( cols[1], length(d) ) col[ !f & p >= alpha ] <- cols[2] col[ !f & p < alpha ] <- cols[3] plot( d, -log10( p ), cex = cex, pch = pch, xlab = xlab, ylab = ylab, col = col, ... ) k_grid <- seq( 0, max( -log10( p ) ), length = 100 ) p_grid <- 10^( -k_grid ) lines( kappa_p( p_grid, n1, n2 ) * S_cutoff, k_grid, lty = ltys[1] ) lines( -1 * kappa_p( p_grid, n1, n2 ) * S_cutoff, k_grid, lty = ltys[1] ) segments( c( par("usr")[1], kappa_p( alpha, n1, n2 ) * S_cutoff ), -log10( alpha ), c( -kappa_p( alpha, n1, n2 ) * S_cutoff, par("usr")[2] ), -log10( alpha ), lty = ltys[2] ) if ( use_legend ) legend( "topleft", c( "Filtered", "Insig.", "Sig." ), pch = pch, col = cols, inset = .025, bg = "white" ) } genefilter/R/filtered_p.R0000644000175100017510000000141614614230661016364 0ustar00biocbuildbiocbuildfiltered_p <- function( filter, test, theta, data, method = "none" ) { if ( is.function( filter ) ) U1 <- filter( data ) else U1 <- filter cutoffs <- quantile( U1, theta ) result <- matrix( NA_real_, length( U1 ), length( cutoffs ) ) colnames( result ) <- names( cutoffs ) for ( i in 1:length( cutoffs ) ) { use <- U1 >= cutoffs[i] if( any( use ) ) { if( is.function( test ) ) U2 <- test( data[use,] ) else U2 <- test[use] result[use,i] <- p.adjust( U2, method ) } } return( result ) } filtered_R <- function( alpha, filter, test, theta, data, method = "none" ) { p <- filtered_p( filter, test, theta, data, method ) return( apply( p, 2, function(x) sum( x < alpha, na.rm = TRUE ) ) ) } genefilter/R/genefinder.R0000644000175100017510000001016614614230661016357 0ustar00biocbuildbiocbuild# genefinder.R # # genefinder functions. genescale <- function (m, axis=2, method=c("Z", "R"), na.rm=TRUE) { ##scale by the range RscaleVector <- function(v, na.rm) { mm <- range(v, na.rm=na.rm) (v - mm[1]) / (mm[2] - mm[1]) } ##scale using Zscore ZscaleVector <- function(v, na.rm) (v - mean(v, na.rm=na.rm))/sd(v, na.rm=na.rm) # # scales a matrix using the scaleVector function. # which <- match.arg(method) method <- switch(which, Z = ZscaleVector, R = RscaleVector) if( is.matrix(m) || is.data.frame(m) ) { rval <- apply (m, axis, method, na.rm=na.rm) if( axis==1 ) return(t(rval)) return(rval) } else method(m, na.rm=na.rm) } setMethod("genefinder", c("ExpressionSet", "vector", "ANY", "ANY", "ANY", "ANY"), function(X, ilist, numResults, scale, weights, method) { gN <- featureNames(X) if (is.character(ilist)) ilist <- match(ilist,gN) ans <- genefinder(exprs(X), ilist, numResults, scale, weights, method=method) names(ans) <- gN[ilist] ans }) setMethod("genefinder", c("matrix", "vector", "ANY", "ANY", "ANY", "ANY"), function (X, ilist, numResults, scale, weights, method) { X <- as.matrix(X) METHOD <- c("euclidean", "maximum", "manhattan", "canberra", "correlation", "binary") method<-pmatch(method, METHOD) if (is.na(method)) stop ("The distance method is invalid.") SCALE <- c("none", "range", "zscore") scale <- SCALE[pmatch(scale, SCALE)] # perform scaling if requested. # X <- switch(scale, none=X, range=genescale(X), zscore=scale(X), stop("The scaling method is invalid") ) N <- nrow(X) C <- ncol(X) if( !is.vector(ilist) ) stop("the genes to be compared to must be in a vector") ninterest <- length(ilist); if( is.character(ilist) ) { iRows <- match(ilist, row.names(X)) names(iRows) <- ilist } else if ( is.numeric(ilist) ) { iRows <- ilist names(iRows) <- row.names(X)[ilist] } else stop("invalid genes selected") if( any(is.na(iRows)) ) stop("invalid genes selected") if (missing(weights)) weights <- rep(1,C) else if (length(weights) != C) stop("Supplied weights do not match number of columns") ## Do a sanity check on the requested genes in ilist -> if the ## gene exceeds the # of rows in the matrix, can not be processed. if (max(iRows) > N) stop("Requested genes exceed the dimensions of the supplied matrix.") Genes <- array(as.integer(NA), dim=c(ninterest, numResults)) Dists <- array(as.integer(NA), dim=c(ninterest, numResults)) extCall <- .C("gf_distance", X = as.double(X), nr= as.integer(N), nc= ncol(X), g = as.integer(Genes), d = as.double(Dists), iRow = as.integer(iRows), nInterest = as.integer(ninterest), nResults = as.integer(numResults), method= as.integer(method), weights = as.double(weights), NAOK=TRUE, PACKAGE="genefilter") Genes <- extCall$g+1 Dists <- extCall$d Which <- vector() ## Get the number of genes/dists per selection. There should ## always be a number of total genes such that they are a multiple ## of ninterest numPerList <- length(Genes) / ninterest Which <- rep(iRows, rep(numPerList, ninterest)) byGene <- split(Genes, Which) names(byGene) <- rep("indices", length(byGene)) byDists <- split(Dists, Which) names(byDists) <- rep("dists", length(byDists)) ## Need a better way to stuff these together retList <- list() for (i in 1:ninterest) { retList[[i]] <- list(indices=byGene[[i]], dists=byDists[[i]]) } return(retList) }) genefilter/R/half.range.mode.R0000755000175100017510000000216314614230661017202 0ustar00biocbuildbiocbuildhalf.range.mode <- function( data, B, B.sample, beta = .5, diag = FALSE ) { if ( length( data ) == 0 ) return( NA_real_ ) if (missing( B ) ) { # Just one run on the full set... if ( is.unsorted( data ) ) data <- sort( data ) .C( "half_range_mode", data = as.double( data ), n = as.integer( length( data ) ), beta = as.double( beta ), diag = as.integer( diag ), M = double(1), PACKAGE = "genefilter" )$M } else { # Bootstrapped if ( missing( B.sample ) ) B.sample <- length( data ) M <- sapply(seq_len(B), function (x) { d <- sort( sample( data, B.sample, replace = TRUE ) ) .C( "half_range_mode", data = as.double( d ), n = as.integer( B.sample ), beta = as.double( beta ), diag = as.integer( diag ), M = double(1), PACKAGE = "genefilter" )$M } ) mean( M ) } } genefilter/R/kappa_p.R0000644000175100017510000000034514614230661015662 0ustar00biocbuildbiocbuildkappa_p <- function( p, n1, n2 = n1 ) { n <- n1 + n2 t <- qt( 1 - p/2, df = n - 2 ) kappa_t( t, n1, n2 ) } kappa_t <- function( t, n1, n2 = n1 ) { n <- n1 + n2 sqrt( n * (n-1) * t^2 / ( n1 * n2 * ( n - 2 + t^2 ) ) ) } genefilter/R/nsFilter.R0000644000175100017510000002250214614230661016034 0ustar00biocbuildbiocbuild##RG introduces two new functions, varFilter that does what nsFilter ##was supposed to, but never did, and featureFilter that does the only ##useful stuff that nsFilter does rowIQRs <- function(eSet) { numSamp <- ncol(eSet) lowQ <- rowQ(eSet, floor(0.25 * numSamp)) upQ <- rowQ(eSet, ceiling(0.75 * numSamp)) upQ - lowQ } ##For NOW, we will need to check the schema from within nsFilter and ##featureFilter to decide what the internal ID is that needs to be used. ##LATER, when we haev annotation packages that will make this sort of access ##easier, it will make more sense to just access the central ID for those ##packages. ## It looks like I can take care of both nsFilter and featureFilter in this ## way by just altering what the helper function findLargest() does varFilter <- function(eset, var.func=IQR, var.cutoff=0.5,filterByQuantile=TRUE ) { if (deparse(substitute(var.func)) == "IQR") { vars <- rowIQRs(eset) } else { vars <- apply(exprs(eset), 1, var.func) } if (filterByQuantile) { if ( 0 < var.cutoff && var.cutoff < 1 ) { quant = quantile(vars, probs = var.cutoff) selected = !is.na(vars) & vars > quant } else stop("Cutoff Quantile has to be between 0 and 1.") } else { selected <- !is.na(vars) & vars > var.cutoff } eset <- eset[selected, ] } .getRequiredIDs <- function(eset, map){ annChip <- annotation(eset) if(.isOrgSchema(annChip)){ IDs <- featureNames(eset) names(IDs) <- featureNames(eset) }else{ IDs <- mget(featureNames(eset), envir=getAnnMap(map, annChip), ifnotfound=NA) } IDs } featureFilter <- function(eset, require.entrez=TRUE, require.GOBP=FALSE, require.GOCC=FALSE, require.GOMF=FALSE, require.CytoBand=FALSE, remove.dupEntrez=TRUE, feature.exclude="^AFFX") { annChip <- annotation(eset) if (nchar(annChip) == 0) stop("'eset' must have a valid annotation slot") nfeat <- function(eset) length(featureNames(eset)) requireID <- function(eset, map) { IDs <- .getRequiredIDs(eset, map) haveID <- names(IDs)[sapply(IDs, function(x) !is.na(x))] eset[haveID, ] } if (require.entrez) { map <- .findCentralMap(annChip) eset <- requireID(eset, map) } filterGO <- function(eset, ontology) { haveGo <- sapply(mget(featureNames(eset), getAnnMap("GO", annChip), ifnotfound=NA), function(x) { if (length(x) == 1 && is.na(x)) FALSE else { onts <- subListExtract(x, "Ontology", simplify=TRUE) ontology %in% onts } }) eset[haveGo, ] } if (require.GOBP) eset <- filterGO(eset, "BP") if (require.GOCC) eset <- filterGO(eset, "CC") if (require.GOMF) eset <- filterGO(eset, "MF") if (length(feature.exclude)) { fnms <- featureNames(eset) badIdx <- integer(0) for (pat in feature.exclude) { if (nchar(pat) == 0) next badIdx <- c(grep(pat, fnms), badIdx) } if (length(badIdx)) { badIdx <- unique(badIdx) eset <- eset[-badIdx, ] } } if (remove.dupEntrez ) { ## Reduce to unique probe <--> gene mapping here by keeping largest IQR ## We will want "unique genes" in the non-specific filtered gene ## set. uniqGenes <- findLargest(featureNames(eset), rowIQRs(eset), annotation(eset)) eset <- eset[uniqGenes, ] } requireCytoBand <- function(eset) { MAPs <- mget(featureNames(eset), envir=getAnnMap("MAP", annChip), ifnotfound=NA) haveMAP <- names(MAPs)[sapply(MAPs, function(x) !is.na(x[1]))] eset[haveMAP, ] } if (require.CytoBand) eset <- requireCytoBand(eset) eset } setMethod("nsFilter", "ExpressionSet", function(eset, require.entrez=TRUE, require.GOBP=FALSE, require.GOCC=FALSE, require.GOMF=FALSE, require.CytoBand=FALSE, remove.dupEntrez=TRUE, var.func=IQR, var.cutoff=0.5, var.filter=TRUE, filterByQuantile=TRUE, feature.exclude="^AFFX", ...) { if (!is.function(var.func)) stop("'var.func' must be a function") annChip <- annotation(eset) if (nchar(annChip) == 0) stop("'eset' must have a valid annotation slot") nfeat <- function(eset) length(featureNames(eset)) filter.log <- new.env(parent=emptyenv()) requireID <- function(eset, map) { IDs <- .getRequiredIDs(eset, map) haveID <- names(IDs)[sapply(IDs, function(x) !is.na(x))] logvar <- paste("numRemoved", map, sep=".") assign(logvar, nfeat(eset) - length(haveID), envir=filter.log) eset[haveID, ] } if (require.entrez) { map <- .findCentralMap(annChip) eset <- requireID(eset, map) } filterGO <- function(eset, ontology) { haveGo <- sapply(mget(featureNames(eset), getAnnMap("GO", annChip), ifnotfound=NA), function(x) { if (length(x) == 1 && is.na(x)) FALSE else { onts <- subListExtract(x, "Ontology", simplify=TRUE) ontology %in% onts } }) logvar <- paste("numNoGO", ontology, sep=".") assign(logvar, sum(!haveGo), envir=filter.log) eset[haveGo, ] } if (require.GOBP) { eset <- filterGO(eset, "BP") } if (require.GOCC) { eset <- filterGO(eset, "CC") } if (require.GOMF) { eset <- filterGO(eset, "MF") } if (length(feature.exclude)) { fnms <- featureNames(eset) badIdx <- integer(0) for (pat in feature.exclude) { if (nchar(pat) == 0) next badIdx <- c(grep(pat, fnms), badIdx) } if (length(badIdx)) { badIdx <- unique(badIdx) eset <- eset[-badIdx, ] logvar <- "feature.exclude" assign(logvar, length(badIdx), filter.log) } } if (remove.dupEntrez) { ## Reduce to unique probe <--> gene mapping here by keeping largest IQR ## We will want "unique genes" in the non-specific filtered gene ## set. if (deparse(substitute(var.func)) == "IQR") { esetIqr <- rowIQRs(exprs(eset)) } else { esetIqr <- apply(exprs(eset), 1, var.func) } numNsWithDups <- nfeat(eset) uniqGenes <- findLargest(featureNames(eset), esetIqr, annotation(eset)) eset <- eset[uniqGenes, ] logvar <- "numDupsRemoved" assign(logvar, numNsWithDups - nfeat(eset), envir=filter.log) } if (var.filter) { if (deparse(substitute(var.func)) == "IQR") { esetIqr <- rowIQRs(exprs(eset)) } else { esetIqr <- apply(exprs(eset), 1, var.func) } ##note this was not happening in the first ##version - despite the documentation if (filterByQuantile) { if ( 0 < var.cutoff && var.cutoff < 1 ) { var.cutoff = quantile(esetIqr, var.cutoff) } else stop("Cutoff Quantile has to be between 0 and 1.") } selected <- esetIqr > var.cutoff eset <- eset[selected, ] logvar <- "numLowVar" assign(logvar, sum(!selected), filter.log) } requireCytoBand <- function(eset) { MAPs <- mget(featureNames(eset), envir=getAnnMap("MAP", annChip), ifnotfound=NA) haveMAP <- names(MAPs)[sapply(MAPs, function(x) !is.na(x[1]))] logvar <- paste("numRemoved", "MAP", sep=".") assign(logvar, nfeat(eset) - length(haveMAP), envir=filter.log) eset[haveMAP, ] } if (require.CytoBand) eset <- requireCytoBand(eset) numSelected <- length(featureNames(eset)) list(eset=eset, filter.log=as.list(filter.log)) }) genefilter/R/rejection_plot.R0000644000175100017510000000374114614230661017272 0ustar00biocbuildbiocbuildrejection_plot <- function(p, col, lty = 1, lwd = 1, xlab = "p cutoff", ylab = "number of rejections", xlim = c( 0, 1 ), ylim, legend = names(p), at = c( "all", "sample" ), n_at = 100, probability = FALSE, ... ) { if ( is.matrix( p ) ) { legend <- colnames( p ) p <- lapply( 1:ncol(p), function(i) p[,i] ) } if ( missing( col ) ) col <- rainbow( length( p ), v = .7 ) col <- rep( col, length.out = length( p ) ) lty <- rep( lty, length.out = length( p ) ) lwd <- rep( lwd, length.out = length( p ) ) if ( missing( ylim ) ) ylim <- c( 0, ifelse( probability, 1, max( sapply( p, length ) ) ) ) at <- match.arg( at ) steps <- lapply( p, function(x) { x <- na.omit(x) stepfun( sort( x ), ( 0:length(x) ) / ifelse( probability, length(x), 1 ) ) } ) plot( 0, type = "n", xaxs = "i", yaxs = "i", xlim = xlim, ylim = ylim, xlab = xlab, ylab = ylab, ... ) if ( at == "all" ) { for ( i in 1:length( steps ) ) lines( steps[[i]], xlim = xlim, col = col[i], lty = lty[i], lwd = lwd[i], do.points = FALSE ) } else { x <- seq( xlim[1], xlim[2], length = n_at ) for ( i in 1:length( steps ) ) lines( x, steps[[i]](x), col = col[i], lty = lty[i], lwd = lwd[i] ) } if ( !is.null( legend ) ) legend( "topleft", legend, col = col, lty = lty, lwd = lwd, inset = .05 ) invisible( steps ) } genefilter/R/rowpAUCs-methods.R0000644000175100017510000001025614614230661017415 0ustar00biocbuildbiocbuild## ========================================================================== ## core rowpAUCs method for objects of class matrix ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setMethod("rowpAUCs", signature(x="matrix", fac="factor"), function(x, fac, p=0.1, flip=TRUE, caseNames=c("1", "2")){ ##check argument 'p' if(!is.numeric(p) || length(p)>1) stop("'p' must be numeric of length 1") ## check argument 'fac' f <- checkfac(fac) if(f$nrgrp != 2 || length(f$fac) != ncol(x) || length(unique(f$fac)) !=2 ) stop("'fac' must be factor with 2 levels and length 'ncol(x)'") ## check argument 'flip' if(length(flip)!=1 || !(is.logical(flip))) stop("'flip' must be logical scalar") flip <- as.integer(flip) ## compute cutpoints cutpts <- matrix((0:ncol(x))+0.5, ncol=ncol(x)+1, nrow=nrow(x), byrow=TRUE, dimnames=list(rownames(x), NULL)) ## rank data xr <- t(apply(x, 1, rank)) mode(xr) <- "numeric" ## call C function and return object of class 'rowROC' res <- .Call("ROCpAUC", xr, cutpts, as.integer(f$fac), p, PACKAGE="genefilter", flip) sens <- res$sens spec <- res$spec rownames(sens) <- rownames(spec) <- rownames(x) pAUC <- res$pAUC AUC <- res$AUC names(AUC) <- names(pAUC) <- rownames(x) object <- new("rowROC", data=x, sens=sens, spec=spec, pAUC=pAUC, AUC=AUC, factor=factor(f$fac), p=p, ranks=xr, caseNames=as.character(caseNames), cutpoints=cutpts) return(object) }) ## ========================================================================== ## ========================================================================== ## rowpAUCs method with signature x=matrix, fac=numeric ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setMethod("rowpAUCs", signature(x="matrix", fac="numeric"), function(x, fac, p=0.1, flip=TRUE, caseNames=c("1", "2")){ cutpts <- matrix((0:ncol(x))+0.5, ncol=ncol(x)+1, nrow=nrow(x), byrow=TRUE) rowpAUCs(x=x, fac=factor(fac), p=p, flip=flip, caseNames=caseNames) }) ## ========================================================================== ## ========================================================================== ## rowpAUCs method with signature x=ExpressionSet ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setMethod("rowpAUCs", signature(x="ExpressionSet"), function(x, fac, p=0.1, flip=TRUE, caseNames=c("1", "2")){ rowpAUCs(x=exprs(x), fac=fac, p=p, flip=flip, caseNames=caseNames) }) ## ========================================================================== ## ========================================================================== ## rowpAUCs method with signature x=ExpressionSet fac=character ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setMethod("rowpAUCs", signature(x="ExpressionSet", fac="character"), function(x, fac, p=0.1, flip=TRUE, caseNames=c("1", "2")){ if (length(fac) == 1){ if(!fac %in% colnames(pData(x))) stop("fac must be length 1 character indicating a ", "covariate in the phenoData slot of the expressionSet") cn <- as.character(levels(pData(x)[[fac]])) fac = factor(as.integer(factor(pData(x)[[fac]]))-1) rowpAUCs(x=exprs(x), fac=fac, p=p, flip=flip, caseNames=cn) }else{ rowpAUCs(x=x, fac=as.factor(fac), p=p, flip=flip, caseNames=caseNames) } }) ## ========================================================================== genefilter/R/rowROC-accessors.R0000644000175100017510000001532714614230661017413 0ustar00biocbuildbiocbuild## ========================================================================== ## show method for objects of class rowROC ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setMethod("show", signature(object="rowROC"), function(object){ cat("matrix of ROC curves for", nrow(object@data), "genes/rows", "with", max(0,ncol(object@cutpoints)), "cutpoints\n") cat(" size of class ", object@caseNames[1] ,": ", sum(object@factor==levels(object@factor)[1]), "\n", sep="") cat(" size of class ", object@caseNames[2] ,": ", sum(object@factor==levels(object@factor)[2]), "\n", sep="") cat("partial areas under curve calculated for p=", object@p, "\n", sep="") }) ## ========================================================================== ## ========================================================================== ## subsetting method for objects of class rowROC ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setMethod("[", signature="rowROC", definition=function(x, i, j="missing", drop="missing") { x@sens <- x@sens[i,,drop=FALSE] x@spec <- x@spec[i,,drop=FALSE] x@pAUC <- x@pAUC[i] x@AUC <- x@AUC[i] x@data <- x@data[i,,drop=FALSE] x@cutpoints <- x@cutpoints[i,,drop=FALSE] x@ranks <- x@ranks[i,,drop=FALSE] return(x) }, valueClass="rowROC") ## ========================================================================== ## ========================================================================== ## plot method for objects of class rowROC ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setMethod("plot", signature(x="rowROC", y="missing"), function(x, pch=20, cex=0.7, xlab="1 - specificity", ylab="sensitivity", main=NULL, sub=paste("class ", x@caseNames[1], " (", sum(x@factor==levels(x@factor)[1]), " cases) | class ", x@caseNames[2], " (", sum(x@factor==levels(x@factor)[2]), " cases)", sep=""), ...){ sx <- sort(1-x@spec[1,]) sy <- sort(x@sens[1,]) spx <- c(sx[sx<=x@p & sy>0],x@p) spy <- sy[sx<=x@p & sy>0] if(!length(spy)){ spy <- 0 spx <- c(0,spx) } spy <- c(spy, max(spy)) len <- length(sx) nn <- names(area(x)[1]) if(is.null(main)) main <- paste("ROC-Curve", ifelse(length(nn), paste("(", nn, ")", sep=""), "")) plot(sx, sy, pch=pch, cex=cex, xlab=xlab, ylab=ylab, main=main, sub=sub, ...) if(mean(x@data)==1 || all(sx==sy)) polygon(c(0,1,1), c(0,0,1), col="#ececec", lty=0) else{ rect(spx[-1], 0, spx[-1] - diff(spx),spy[-1], col="#ececec", lty=0) lines(sx, sy, type="s") } points(sx, sy, pch=pch, cex=cex, ...) lines(0:1, 0:1, lty=3, col="darkgray") atext <- paste("AUC: ", signif(x@AUC[1],3)) tw <- strwidth(atext) w <- diff(par("usr")[1:2]) cex <- min(1, (w/2+w/10)/tw) th <- strheight(atext, cex=cex)*1.1 if(x@p<1){ ptext <- paste("pAUC: ", signif(x@pAUC[1],3), " (p=", x@p, ")", sep="") tw <- max(tw, strwidth(ptext)) cex <- min(1, (w/2+w/10)/tw) abline(v=x@p, col="darkblue", lty=2) text(x=1-tw*cex*1.1, y=0.02+th*cex, atext, pos=4, cex=cex) text(x=1-tw*cex*1.1, y=0.02, ptext, pos=4, cex=cex) }else{ text(x=1-tw*cex*1.1, y=0.02, atext, pos=4, cex=cex) } }) ## ========================================================================== ## ========================================================================== ## pAUC method for objects of class rowROC ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setMethod("pAUC", signature(object="rowROC", p="numeric"), function(object, p, flip=TRUE){ if(length(flip)!=1 || !(is.logical(flip))) stop("'flip' must be logical scalar") flip <- as.integer(flip) res <- .Call("pAUC", object@spec, object@sens, p, flip) names(res$pAUC) <- names(res$AUC) <- names(object@AUC) object@pAUC <- res$pAUC object@AUC <- res$AUC object@p <- p return(object) }) ## ========================================================================== ## ========================================================================== ## AUC method for objects of class rowROC ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setMethod("AUC", signature(object="rowROC"), function(object){ object@pAUC <- object@AUC object@p <- 1 return(object) }) ## ========================================================================== ## ========================================================================== ## accessor method to slot 'sens' for objects of class rowROC ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setMethod("sens", signature(object="rowROC"), function(object) return(object@sens) ) ## ========================================================================== ## ========================================================================== ## accessor method to slot 'spec' for objects of class rowROC ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setMethod("spec", signature(object="rowROC"), function(object) return(object@spec) ) ## ========================================================================== ## ========================================================================== ## accessor method to slots 'AUC' or 'pAUC' for objects of class rowROC ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - setMethod("area", signature(object="rowROC"), function(object, total=FALSE){ if(total) return(object@AUC) else return(object@pAUC) }) ## ========================================================================== genefilter/R/rowSds.R0000644000175100017510000000032314614230661015524 0ustar00biocbuildbiocbuildrowVars = function(x, ...) { sqr = function(x) x*x n = rowSums(!is.na(x)) n[n<=1] = NA return(rowSums(sqr(x-rowMeans(x, ...)), ...)/(n-1)) } rowSds = function(x, ...) sqrt(rowVars(x, ...)) genefilter/R/rowttests-methods.R0000644000175100017510000001566014614230661017774 0ustar00biocbuildbiocbuild##--------------------------------------------------------------------------------------## ## This file contains methods definitions for rowttests, colttest, rowFtests, colFtests ## ##--------------------------------------------------------------------------------------## ##----------------------------------------------------------------------- ## The core function for row- and column-wise t-tests - it uses C code ##------------------------------------------------------------------------ rowcoltt = function(x, fac, tstatOnly, which, na.rm) { if (!missing(tstatOnly) && (!is.logical(tstatOnly) || is.na(tstatOnly))) stop(sQuote("tstatOnly"), " must be TRUE or FALSE.") f = checkfac(fac) if ((f$nrgrp > 2) || (f$nrgrp <= 0)) stop("Number of groups is ", f$nrgrp, ", but must be >0 and <=2 for 'rowttests'.") if (typeof(x) == "integer") x[] <- as.numeric(x) cc = .Call("rowcolttests", x, f$fac, f$nrgrp, which-1L, na.rm, PACKAGE="genefilter") res = data.frame(statistic = cc$statistic, dm = cc$dm, row.names = dimnames(x)[[which]]) if (!tstatOnly) res = cbind(res, p.value = 2*pt(abs(res$statistic), cc$df, lower.tail=FALSE)) attr(res, "df") = cc$df return(res) } ##------------------------------------------------------------ ## The core function for F-tests - it uses R matrix algebra ##------------------------------------------------------------ rowcolFt = function(x, fac, var.equal, which) { if(!(which %in% c(1L, 2L))) stop(sQuote("which"), " must be 1L or 2L.") if(which==2L) x = t(x) if (typeof(x) == "integer") x[] <- as.numeric(x) sqr = function(x) x*x stopifnot(length(fac)==ncol(x), is.factor(fac), is.matrix(x)) x <- x[,!is.na(fac), drop=FALSE] fac <- fac[!is.na(fac)] ## Number of levels (groups) k <- nlevels(fac) ## xm: a nrow(x) x nlevels(fac) matrix with the means of each factor ## level xm <- matrix( sapply(levels(fac), function(fl) rowMeans(x[,which(fac==fl), drop=FALSE])), nrow = nrow(x), ncol = nlevels(fac)) ## x1: a matrix of group means, with as many rows as x, columns correspond to groups x1 <- xm[,fac, drop=FALSE] ## degree of freedom 1 dff <- k - 1 if(var.equal){ ## x0: a matrix of same size as x with overall means x0 <- matrix(rowMeans(x), ncol=ncol(x), nrow=nrow(x)) ## degree of freedom 2 dfr <- ncol(x) - dff - 1 ## mean sum of squares mssf <- rowSums(sqr(x1 - x0)) / dff mssr <- rowSums(sqr( x - x1)) / dfr ## F statistic fstat <- mssf/mssr } else{ ## a nrow(x) x nlevels(fac) matrix with the group size of each factor ## level ni <- t(matrix(tapply(fac,fac,length),ncol=nrow(x),nrow=k)) ## wi: a nrow(x) x nlevels(fac) matrix with the variance * group size of each factor ## level sss <- sqr(x-x1) x5 <- matrix( sapply(levels(fac), function(fl) rowSums(sss[,which(fac==fl), drop=FALSE])), nrow = nrow(sss), ncol = nlevels(fac)) wi <- ni*(ni-1) /x5 ## u : Sum of wi u <- rowSums(wi) ## F statistic MR <- rowSums(sqr((1 - wi/u)) * 1/(ni-1))*1/(sqr(k)-1) fsno <- 1/dff * rowSums(sqr(xm - rowSums(wi*xm)/u) * wi) fsdeno <- 1+ 2* (k-2)*MR fstat <- fsno/fsdeno ## degree of freedom 2: Vector with length nrow(x) dfr <- 1/(3 * MR) } res = data.frame(statistic = fstat, p.value = pf(fstat, dff, dfr, lower.tail=FALSE), row.names = rownames(x)) attr(res, "df") = c(dff=dff, dfr=dfr) return(res) } ## ========================================================================== ## rowttests and colttests methods for 'matrix' ## ========================================================================== setMethod("rowttests", signature(x="matrix", fac="factor"), function(x, fac, tstatOnly=FALSE, na.rm = FALSE) rowcoltt(x, fac, tstatOnly, 1L, na.rm)) setMethod("rowttests", signature(x="matrix", fac="missing"), function(x, fac, tstatOnly=FALSE, na.rm = FALSE) rowcoltt(x, factor(integer(ncol(x))), tstatOnly, 1L, na.rm)) setMethod("colttests", signature(x="matrix", fac="factor"), function(x, fac, tstatOnly=FALSE, na.rm = FALSE) rowcoltt(x, fac, tstatOnly, 2L, na.rm)) setMethod("colttests", signature(x="matrix", fac="missing"), function(x, fac, tstatOnly=FALSE, na.rm = FALSE) rowcoltt(x, factor(integer(ncol(x))), tstatOnly, 2L, na.rm)) ## ========================================================================== ## rowFtests and colFtests methods for 'matrix' ## ========================================================================== setMethod("rowFtests", signature(x="matrix", fac="factor"), function(x, fac, var.equal=TRUE) rowcolFt(x, fac, var.equal, 1L)) setMethod("colFtests", signature(x="matrix", fac="factor"), function(x, fac, var.equal=TRUE) rowcolFt(x, fac, var.equal, 2L)) ## =========================================================================== ## Methods for 'ExpressionSet': only for rowttests and rowFtests ## -========================================================================== setMethod("rowttests", signature(x="ExpressionSet", fac="factor"), function(x, fac, tstatOnly=FALSE, na.rm = FALSE) rowcoltt(exprs(x), fac, tstatOnly=tstatOnly, 1L, na.rm)) setMethod("rowttests", signature(x="ExpressionSet", fac="missing"), function(x, fac, tstatOnly=FALSE, na.rm = FALSE) { x = exprs(x) fac = integer(ncol(x)) rowcoltt(x, fac, tstatOnly, 1L, na.rm) }) setMethod("rowttests", signature(x="ExpressionSet", fac="character"), function(x, fac, tstatOnly=FALSE, na.rm = FALSE) { if (length(fac) != 1) stop("fac must be length 1 character or a factor") fac = factor(pData(x)[[fac]]) rowcoltt(exprs(x), fac, tstatOnly, 1L, na.rm) }) setMethod("rowFtests", signature(x="ExpressionSet", fac="factor"), function(x, fac, var.equal=TRUE) rowcolFt(exprs(x), fac, var.equal, 1L)) setMethod("rowFtests", signature(x="ExpressionSet", fac="character"), function(x, fac, var.equal=TRUE) { fac = factor(as.integer(factor(pData(x)[[fac]]))-1L) rowcolFt(exprs(x), fac, var.equal, 1L) }) ## ------------------------------------------------------------ ## convert fac from factor or numeric to integer and then ## make sure it is an integer ## ------------------------------------------------------------ checkfac = function(fac) { if(is.numeric(fac)) { nrgrp = as.integer(max(fac, na.rm=TRUE)+1) fac = as.integer(fac) } ## this must precede the factor test if(is.character(fac)) fac = factor(fac) if (is.factor(fac)) { nrgrp = nlevels(fac) fac = as.integer(as.integer(fac)-1) } if(!is.integer(fac)) stop("'fac' must be factor, character, numeric, or integer.") if(any(fac<0, na.rm=TRUE)) stop("'fac' must not be negative.") return(list(fac=fac, nrgrp=nrgrp)) } genefilter/R/shorth.R0000644000175100017510000000320414614230661015553 0ustar00biocbuildbiocbuildshorth <- function(x, na.rm=FALSE, tie.action="mean", tie.limit=0.05) { stopifnot(is.numeric(x)) if (na.rm) { x <- x[is.finite(x)] } else { if(any(!is.finite(x))) stop("'x' contains NA or NaN, and 'na.rm' is FALSE.") } if(length(x)==0L) { NA_real_ } else { sx <- sort(x) width <- round(0.5*length(x)) diffs <- sx[(width+1):length(x)] - sx[seq_len(length(x)-width)] ## cannot use which.min since we want all minimising points not just one: q <- which(diffs==min(diffs)) if(length(q)>1) { ## deal with ties: maxq = max(q) minq = min(q) ## take the action specified in "tie.action" q <- switch(tie.action, mean = { if (maxq-minq <= tie.limit * length(x)) { mean(q) } else { stop(paste("Encountered tie(s), and the difference between minimal and maximal value is larger than 'length(x)*tie.limit'.", "This could mean that the distribution does not have a single well-defined mode.", paste("q=", minq, "...", maxq, ", values=", signif(sx[minq],4), "...", signif(sx[minq+width],4), sep=""), sep="\n")) }}, max = maxq, ## largest midpoint (maxq) min = minq, ## smallest midpoint (minq) stop(sprintf("Invalid value '%s' for argument 'tie.action'", tie.action)) ) } ## if mean(sx[q:(q+width-1)]) } ## if } genefilter/R/zzz.R0000644000175100017510000000037314614230661015105 0ustar00biocbuildbiocbuild.onLoad <- function(lib, pkgname) { if(.Platform$OS.type == "windows" && interactive() && .Platform$GUI == "Rgui"){ addVigs2WinMenu("genefilter") } } .onUnload <- function( libpath ) { library.dynam.unload( "genefilter", libpath ) } genefilter/src/0000755000175100017510000000000014614336167014520 5ustar00biocbuildbiocbuildgenefilter/src/genefilter.h0000644000175100017510000000043714614230661017011 0ustar00biocbuildbiocbuild/* Copyright Bioconductor Foundation NA, 2007, all rights reserved */ #include #include typedef int RSInt; void gf_distance(double *x, RSInt *nr, RSInt *nc, RSInt *g, double *d, RSInt *iRow, RSInt *nInterest, RSInt *nResults, RSInt *method, double *wval); genefilter/src/half_range_mode.cpp0000644000175100017510000000632714614230661020316 0ustar00biocbuildbiocbuild#include #include #include using namespace std; double half_range_mode( double *start, double *end, double beta, int diag ) { // The end pointer is one step beyond the data... double w, w_prime; double *last, *new_start, *new_end; vector counts, J; vector w_range; int i, s, e; int N, N_prime, N_double_prime; double lo, hi; last = end - 1; N = end - start; // How many elements are in the set? Terminate recursion appropriately... switch ( N ) { case 1: return *start; case 2: return .5 * ( *start + *last ); // Main recursive code begins here default: w = beta * ( *last - *start ); // If all values are identical, return immediately... if ( w == 0 ) return *start; // If we're at the end of the data, counts can only get worse, so there's no point in continuing... e = 0; for( s = 0; s < N && e < N; s++ ) { while ( e < N && start[ e ] <= start[ s ] + w ) { e++; } counts.push_back( e - s ); } // Maximum count, and its multiplicity N_prime = *( max_element( counts.begin(), counts.end() ) ); for ( i = 0; i < (int) counts.size(); i++ ) if ( counts[i] == N_prime ) J.push_back( i ); // Do we have more than one maximal interval? if ( J.size() == 1 ) { // No... the interval's unique. new_start = start + J[0]; new_end = start + J[0] + N_prime; } else { // Yes.. What's the smallest range? for ( i = 0; i < (int) J.size(); i++ ) w_range.push_back( start[ J[i] + N_prime - 1 ] - start[ J[i] ] ); w_prime = *( min_element( w_range.begin(), w_range.end() ) ); // Set new start and end. We skip the more cumbersome V.min and V.max of the Bickel algorithm i = 0; while( w_range[ i ] > w_prime ) i++; new_start = start + J[i]; new_end = start + J[i] + N_prime; // If there are any more maximal-count, minimal-range intervals, adjust // new_end accordingly. for ( i++; i < (int) J.size(); i++ ) if ( w_range[ i ] == w_prime ) new_end = start + J[i] + N_prime; } // Adjustments in rare cases where the interval hasn't shrunk. Trim one end, // the other, or both if lo == hi. Originally, this was inside the else // block above. With discrete data with a small number of levels, it is // possible, however for |J| = 1 AND N_double_prime = N, leading to an // infinite recursion. N_double_prime = new_end - new_start; if (N_double_prime == N ) { lo = new_start[1] - new_start[0]; hi = new_start[ N - 1 ] - new_start[ N - 2 ]; if ( lo <= hi ) { new_end--; } if ( lo >= hi ) { new_start++; } } // Diagnostic output if requested if (diag) Rprintf( "N = %i, N'' = %i, w = %.4f, |J| = %i\n", N, N_double_prime, w, J.size() ); // Clean up and then go in recursively counts.clear(); J.clear(); w_range.clear(); return half_range_mode( new_start, new_end, beta, diag ); } } extern "C" { void half_range_mode( double *data, int *n, double *beta, int *diag, double *M ) { // We assume that that data is already sorted for us... *M = half_range_mode( data, data + *n, *beta, *diag ); } } genefilter/src/init.c0000644000175100017510000000054214614230661015620 0ustar00biocbuildbiocbuild/* Copyright Bioconductor Foundation of NA, 2007, all rights reserved */ #include "R.h" #include "genefilter.h" #include "R_ext/Rdynload.h" static const R_CMethodDef CEntries[] = { {"gf_distance", (DL_FUNC) &gf_distance, 10}, {NULL, NULL, 0} }; void R_init_genefilter(DllInfo *dll) { R_registerRoutines(dll, CEntries, NULL, NULL, NULL); } genefilter/src/nd.c0000644000175100017510000002067514614230661015267 0ustar00biocbuildbiocbuild/* Copyright The Bioconductor Foundation 2007, all rights reserved */ /* this is patterned on the R code in library/stats/src/distance.c as we want to have similar values, but does not handle NA/Inf identically, allows weights and solves the problem of finding distances to a particular value, not necessarily all pairwise distances */ /* Modified in April 2007 for use with S-PLUS ArrayAnalyzer by Insightful Corp. Replaced all int declarations with RSInt declarations. RSInt is defined in S-PLUS's R.h as: typedef long RSInt; Other changes are if-def-ed with if defined(_R_) around the original code. */ /* and further modified since S.h in R defines USING_R - not _R_ !! */ /* Modified in March 2022 so use R.h instead of S.h (S.h is going away in R 4.2). Probably breaks compatibility with S-PLUS ArrayAnalyzer by Insightful Corp (see above). Also, since USING_R now will **always** be defined, all the Splus-specific stuff becomes dead code :-( */ #include #if defined(USING_R) /*( R-specific stuff */ #define S_CDECL #ifdef HAVE_CONFIG_H # include #endif /* we need this first to get the right options for math.h */ #include #include "genefilter.h" #include #include "R_ext/Error.h" #include "R_ext/Applic.h" #else /*) Splus-specific stuff */ #define S_COMPATIBILITY 1 #include "rsplus.h" #endif typedef struct { RSInt geneNum; double geneDist; } gene_t; static void detectTies(RSInt geneNum, RSInt nResults, RSInt nRows, gene_t *data) { char msg_buf[100]; /* Will scan through the first nResults+1 distances in the */ /* data array, and if it detects any ties, will flag a R */ /* warning */ RSInt i; /* Loop indices */ /* If nResults == nRows, do not exceed nResults - otherwise exceed it */ /* by 1 in order to see if there were trailing ties */ if (nResults == nRows) { nResults = nRows-1; } for (i = 1; i < nResults; i++) { if (data[i].geneDist == data[i+1].geneDist) { sprintf(msg_buf, "There are distance ties in the data " "for gene %d\n", geneNum); warning("%s", msg_buf); break; } } } static int S_CDECL distCompare(const void *p1, const void *p2) { const gene_t *i = p1; const gene_t *j = p2; if (!R_FINITE(i->geneDist )) return(1); if (!R_FINITE(j->geneDist)) return(-1); if (i->geneDist > j->geneDist) return (1); if (i->geneDist < j->geneDist) return (-1); return (0); } static double gf_correlation(double *x, double *wval, RSInt nr, RSInt nc, RSInt i1, RSInt i2) { RSInt i; /* Loop index */ RSInt a,b; /* Used as array indices for i1 and i2 */ double xAvg, yAvg; /* Averages of the i1 and i2 rows */ double wA, wB; /* Weighted x[a] and x[b] */ double upTot = 0; /* Upper summation */ double botTotL, botTotR; /* The lower two summations */ double botVal; /* Bottom value for Rho */ double Rho, ans; botTotL = botTotR = 0; xAvg = yAvg = 0; a = i1; b = i2; /* Calculate the averages for the i1 and i2 rows */ for (i = 0; i < nc; i++) { if (R_FINITE(x[a])) { xAvg += (wval[i] * x[a]); } if (R_FINITE(x[b])) { yAvg += (wval[i] * x[b]); } a += nr; b += nr; } xAvg /= (double)nc; yAvg /= (double)nc; /* Reset a & b */ a = i1; b = i2; /* Build up the three summations in the equation */ for (i = 0; i < nc; i++) { if (R_FINITE(x[a]) && R_FINITE(x[b])) { wA = (x[a] - xAvg); wB = (x[b] - yAvg); upTot += wval[i]*wA*wB; botTotL += wval[i]*pow(wA,2); botTotR += wval[i]*pow(wB,2); } a += nr; b += nr; } /* Compute Rho & Distance (1 - R) */ botVal = sqrt((botTotL * botTotR)); Rho = upTot / botVal; ans = 1 - Rho; return(ans); } static double gf_euclidean(double *x, double *wval, RSInt nr, RSInt nc, RSInt i1, RSInt i2) { double dev, ans; RSInt ct, j; ct = 0; ans = 0; for(j = 0 ; j < nc ; j++) { if(R_FINITE(x[i1]) && R_FINITE(x[i2])) { dev = (x[i1] - x[i2]); dev = dev * dev; /* Apply weight and add the total */ ans += (wval[j] * dev); ct++; } i1 += nr; i2 += nr; } if(ct == 0) return NA_REAL; if(ct != nc) ans /= ((double)ct/nc); return sqrt(ans); } static double gf_maximum(double *x, double *wval, RSInt nr, RSInt nc, RSInt i1, RSInt i2) { double dev, ans; RSInt ct, j; ct = 0; ans = -DBL_MAX; for(j = 0 ; j < nc ; j++) { if(R_FINITE(x[i1]) && R_FINITE(x[i2])) { dev = fabs(x[i1] - x[i2]); /* apply the weight */ dev *= wval[j]; if(dev > ans) ans = dev; ct++; } i1 += nr; i2 += nr; } if(ct == 0) return NA_REAL; return ans; } static double gf_manhattan(double *x, double *wval, RSInt nr, RSInt nc, RSInt i1, RSInt i2) { double ans; RSInt ct, j; ct = 0; ans = 0; for(j = 0 ; j < nc ; j++) { if(R_FINITE(x[i1]) && R_FINITE(x[i2])) { ans += (wval[j] * fabs(x[i1] - x[i2])); ct++; } i1 += nr; i2 += nr; } if(ct == 0) return NA_REAL; if(ct != nc) ans /= ((double)ct/nc); return ans; } static double gf_canberra(double *x, double *wval, RSInt nr, RSInt nc, RSInt i1, RSInt i2) { double ans, sum, diff; RSInt ct, j; ct = 0; ans = 0; for(j = 0 ; j < nc ; j++) { if(R_FINITE(x[i1]) && R_FINITE(x[i2])) { sum = fabs(x[i1] + x[i2]); diff = fabs(x[i1] - x[i2]); if (sum > DBL_MIN || diff > DBL_MIN) { ans += wval[j]*(diff/sum); ct++; } } i1 += nr; i2 += nr; } if(ct == 0) return NA_REAL; if(ct != nc) ans /= ((double)ct/nc); return ans; } static double gf_dist_binary(double *x, double *wval, RSInt nr, RSInt nc, RSInt i1, RSInt i2) { RSInt total, ct, ans; RSInt j; total = 0; ct = 0; ans = 0; for(j = 0 ; j < nc ; j++) { if(R_FINITE(x[i1]) && R_FINITE(x[i2])) { if(x[i1] || x[i2]){ ct += wval[j]; if( !(x[i1] && x[i2]) ) ans += wval[j]; } total++; } i1 += nr; i2 += nr; } if(total == 0) return NA_REAL; if(ct == 0) return 0; return (double) ans / ct; } enum { EUCLIDEAN=1, MAXIMUM, MANHATTAN, CANBERRA, CORRELATION, BINARY}; /* == 1,2,..., defined by order in the R function dist */ void gf_distance(double *x, RSInt *nr, RSInt *nc, RSInt *g, double *d, RSInt *iRow, RSInt *nInterest, RSInt *nResults, RSInt *method, double *wval) { /* x -> Data Array nr -> Number of rows in X nc -> number of columns in X g -> The nResults closest genes to the genes of interest d -> The distances of the genes from g, 1 to 1 mapping iRow -> rows of X that we are interested in nInterest -> Number of elements in iRow nResults -> The top X results to pass back method -> which distance method to use */ RSInt i,j, k; /* Loop indices */ RSInt baseIndex; /* Used to index data arrays */ gene_t *tmp; /* Temporary array to hold the distance data */ double (*distfun)(double*, double*, RSInt, RSInt, RSInt, RSInt) = NULL; /* Sanity check the nResults vs. number of rows in the data */ if (*nResults > *nr) { warning("Number of results selected is greater than number of rows, using the number of rows instead\n"); *nResults = *nr-1; } /* Size of tmp == *nr, as each gene we're interested in will generate *nr distance points */ tmp = (gene_t *)R_alloc(*nr, sizeof(gene_t)); /* Determine which distance function to use */ switch(*method) { case EUCLIDEAN: distfun = gf_euclidean; break; case MAXIMUM: distfun = gf_maximum; break; case MANHATTAN: distfun = gf_manhattan; break; case CANBERRA: distfun = gf_canberra; break; case CORRELATION: distfun = gf_correlation; break; case BINARY: distfun = gf_dist_binary; break; default: error("invalid distance"); } for (j = 0; j < *nInterest; j++) { /* Get the distances for this gene, store in tmp array */ for(i = 0 ; i < (*nr) ; i++) { tmp[i].geneNum = i; tmp[i].geneDist = distfun(x, wval, *nr, *nc, iRow[j]-1, i); } /* Run a sort on the temp array */ qsort(tmp, *nr, sizeof(gene_t), distCompare); /* Detect any ties */ detectTies(iRow[j], *nResults, *nr, tmp); /* Copy the 1<->nResults data points into the final array */ baseIndex = *nResults * j; for (k = 1; k <= *nResults; k++) { g[baseIndex + (k-1)] = tmp[k].geneNum; d[baseIndex + (k-1)] = tmp[k].geneDist; } } } genefilter/src/pAUC.c0000644000175100017510000001152014614230661015443 0ustar00biocbuildbiocbuild/* * F. Hahne 10/24/2006 */ #include #include #include #include #include #include /*----------------------------------------------------------------- internal c function for calculation of pAUCs -----------------------------------------------------------------*/ void pAUC_c(double *spec, double *sens, double *area, double *auc, double *p, int columns, int rows, int flip) { int i, j, k, d; double *x, *y; double a, ta, tmp, lim, xsum ,ysum; x = (double *) R_alloc(columns+1, sizeof(double)); y = (double *) R_alloc(columns+1, sizeof(double)); /* this computes pAUC for roc curve in row k*/ for(k=0; k ysum){ for(i=k*columns,d=0; i x[d]){ for(i=0, j=d; i<=d/2; i++, j--){ tmp=x[i]; x[i]=x[j]; x[j]=tmp; tmp=y[i]; y[i]=y[j]; y[j]=tmp; } } x[columns]=1; y[columns]=y[columns-1]; /* compute area by trapezoidal rule*/ lim = x[0] < (*p) ? x[0] : *p; /*right border of first segment*/ a = (lim*y[0])/2; /*area of 1. segement (from x1=0 to x2=lim)*/ i=1; while(x[i] < (*p)){ a += ((x[i]-x[i-1])*(y[i]-y[i-1])/2) + ((x[i]-x[i-1])*y[i-1]); i++; } if(i > 2) /*last segment (from xn to p)*/ a += (((*p)-x[i-1])*(y[i]-y[i-1])/2) + (((*p)-x[i-1])*y[i-1]); ta = a; /*compute full AUC and flip curve if necessary*/ if((*p) < 1){ ta += ((x[i]-(*p))*(y[i]-y[i-1])/2) + ((x[i]-(*p))*y[i-1]); i++; while(i < columns+1 && x[i] < 1){ ta += ((x[i]-x[i-1])*(y[i]-y[i-1])/2) + ((x[i]-x[i-1])*y[i-1]); i++; } ta += ((1-x[i-1])*(1-y[i-1])/2) + ((1-x[i-1])*y[i-1]); }else{ d=1; } if(flip && (*p)==1 && ta < 0.5){ /*rotate 180° if area < 0.5*/ a = (*p) - a; ta = 1-ta; } if(a>1){ error("Internal error"); } area[k] = a; auc[k] = ta; } } /*----------------------------------------------------------------- interface to R with arguments: spec : matrix of numerics (specificity) sens: matrix of numerics (sensitivity) p: numeric in 01)) error("'p' must be between 0 and 1."); /* done with p */ /* check input argument flip */ if(!isInteger(_flip)) error("'flip' must be an integer."); flip = (int)INTEGER(_flip)[0]; /* done with flip */ /* allocate memory for return values */ PROTECT(area = allocVector(REALSXP, columns)); PROTECT(auc = allocVector(REALSXP, columns)); /* Do it! */ pAUC_c(spec, sens, REAL(area), REAL(auc), p, rows, columns, flip); /* return value: a list with elements spec sens and area */ PROTECT(res = allocVector(VECSXP, 2)); SET_VECTOR_ELT(res, 0, area); SET_VECTOR_ELT(res, 1, auc); PROTECT(namesres = allocVector(STRSXP, 2)); SET_STRING_ELT(namesres, 0, mkChar("pAUC")); SET_STRING_ELT(namesres, 1, mkChar("AUC")); setAttrib(res, R_NamesSymbol, namesres); UNPROTECT(4); /* done with res, namesres, pAUC, auc */ return(res); } genefilter/src/rowPAUCs.c0000644000175100017510000001475614614230661016334 0ustar00biocbuildbiocbuild/* * F. Hahne 10/26/2005 */ #include #include #include #include #include #include /*----------------------------------------------------------------- internal c function for calculation of ROC curves and pAUCs -----------------------------------------------------------------*/ void ROCpAUC_c(double *data, int nrd, int ncd, double *cutp, int ncc, int *truth, double *spec, double *sens, double *area, double *auc, double *p, int flip) { int i, j, k, pred, d, rsum, csum, rcount, ccount; double *x, *y; double a, ta, tmp, lim, xsum, ysum; x = (double *) R_alloc(ncc+1, sizeof(double)); y = (double *) R_alloc(ncc+1, sizeof(double)); /* this code computes roc for a given n * n matrix at given cut points */ //printf("Computing ROC curves for %d rows at %d cutpoints ...\n", nrd, ncc); for(k=0; k cutp[i]) ? 1 : 0; if(truth[d] == 1){ rsum += pred; rcount++; } else{ csum+=(1-pred); ccount++; } } /* for j (columns)*/ sens[i] = (double)rsum/rcount; spec[i] = (double)csum/ccount; } /* for i (cutpoints)*/ /* this computes pAUC for roc curve in row k*/ xsum = ysum = 0; for(i=k,d=0; i ysum){ for(i=k,d=0; i x[d]){ for(i=0, j=d; i<=(d+1)/2; i++, j--){ tmp=x[i]; x[i]=x[j]; x[j]=tmp; tmp=y[i]; y[i]=y[j]; y[j]=tmp; } } x[ncc] = 1; y[ncc] = y[ncc-1]; /* compute area by trapezoidal rule*/ lim = x[0] < (*p) ? x[0] : *p; /*right border of first segment*/ a = (lim*y[0])/2; /*area of 1. segement (from x1=0 to x2=lim)*/ i=1; while(x[i] < (*p)){ a += ((x[i]-x[i-1])*(y[i]-y[i-1])/2) + ((x[i]-x[i-1])*y[i-1]); i++; } if(i > 2){ /*last segment (from xn to p)*/ a += (((*p)-x[i-1])*(y[i]-y[i-1])/2) + (((*p)-x[i-1])*y[i-1]); } ta = a; /*compute full AUC and flip curve if necessary*/ if((*p) < 1){ ta += ((x[i]-(*p))*(y[i]-y[i-1])/2) + ((x[i]-(*p))*y[i-1]); i++; while(i < ncc+1 && x[i] < 1){ ta += ((x[i]-x[i-1])*(y[i]-y[i-1])/2) + ((x[i]-x[i-1])*y[i-1]); i++; } ta += ((1-x[i-1])*(1-y[i-1])/2) + ((1-x[i-1])*y[i-1]); } if(flip && (*p)==1 && ta < 0.5){ /*rotate 180° if area < 0.5*/ a = (*p) - a; ta = 1-ta; } if(a>1) error("Internal error"); area[k] = a; auc[k] = ta; } } /*----------------------------------------------------------------- interface to R with arguments: data : matrix of numerics cutpts: matrix with treshholds for ROC curve calculation truth: int with values 0 and 1, defining the real classification p: numeric in 0=0)&&(truth[i]<=1))) ) error("Elements of 'truth' must be 0 or 1."); /* done with truth */ /* check input argument p */ if(!isReal(_p) || length(_p)!=1) error("'p' must be numeric."); p = REAL(_p); if(((*p)<0)||((*p)>1)) error("'p' must be between 0 and 1."); /* done with p */ /* check input argument flip */ if(!isInteger(_flip)) error("'flip' must be an integer."); flip = (int)INTEGER(_flip)[0]; /* done with flip */ /* allocate memory for return values */ PROTECT(spec = allocVector(REALSXP, nrd*ncc)); PROTECT(sens = allocVector(REALSXP, nrd*ncc)); PROTECT(dim = allocVector(INTSXP, 2)); INTEGER(dim)[0] = nrd; INTEGER(dim)[1] = ncc; SET_DIM(spec, dim); SET_DIM(sens, dim); PROTECT(area = allocVector(REALSXP, nrd)); PROTECT(auc = allocVector(REALSXP, nrd)); /* Do it! */ /* note nrc is the same as nrd */ ROCpAUC_c(data, nrd, ncd, cutp, ncc, truth, REAL(spec), REAL(sens), REAL(area), REAL(auc), p, flip); /* return value: a list with elements spec sens and pAUC */ PROTECT(res = allocVector(VECSXP, 4)); SET_VECTOR_ELT(res, 0, spec); SET_VECTOR_ELT(res, 1, sens); SET_VECTOR_ELT(res, 2, area); SET_VECTOR_ELT(res, 3, auc); PROTECT(namesres = allocVector(STRSXP, 4)); SET_STRING_ELT(namesres, 0, mkChar("spec")); SET_STRING_ELT(namesres, 1, mkChar("sens")); SET_STRING_ELT(namesres, 2, mkChar("pAUC")); SET_STRING_ELT(namesres, 3, mkChar("AUC")); setAttrib(res, R_NamesSymbol, namesres); UNPROTECT(7); /* done with res, namesres, spec, sens, dim, pAUC */ return(res); } genefilter/src/rowttests.c0000644000175100017510000001503114614230661016732 0ustar00biocbuildbiocbuild/* * Copyright W. Huber 2005 */ #include #include #include #include #include /* #define DEBUG */ char errmsg[256]; /*----------------------------------------------------------------- which=0: t-test by row which=1: t-test by column -----------------------------------------------------------------*/ void rowcolttests_c(double *x, int *fac, int nr, int nc, int no, int nt, int which, int nrgrp, int na_rm, double *statistic, double *dm, double *df) { int i, j, grp; double z, delta, newmean, factor; /* Currently the following provides for one- and two-sample t-tests (nrgrp=1 or 2), but it should be possible to generalize this code to more samples (F-test) without too many changes */ int *n[2]; double* s[2]; double* ss[2]; if(nrgrp>2) error("Please do not use 'nrgrp' >2 with 'rowcolttests'"); /* allocate and initialize storage for intermediate quantities (namely first and second moments for each group) */ for(grp=0; grp=0)&&(fac[i]=0 and < 'nrgrp'."); /* check input argument na_rm */ if (!isLogical(_na_rm) || length(_na_rm) != 1 || LOGICAL(_na_rm)[0] == R_NaInt) error("'na.rm' must be TRUE or FALSE"); na_rm = LOGICAL(_na_rm)[0]; PROTECT(statistic = allocVector(REALSXP, nt)); PROTECT(dm = allocVector(REALSXP, nt)); PROTECT(df = allocVector(REALSXP, nt)); /* Do it */ rowcolttests_c( x, fac, nr, nc, no, nt, which, nrgrp, na_rm, REAL(statistic), REAL(dm), REAL(df)); /* return value: a list with two elements, statistic and df */ PROTECT(res = allocVector(VECSXP, 3)); SET_VECTOR_ELT(res, 0, statistic); SET_VECTOR_ELT(res, 1, dm); SET_VECTOR_ELT(res, 2, df); PROTECT(namesres = allocVector(STRSXP, 3)); SET_STRING_ELT(namesres, 0, mkChar("statistic")); SET_STRING_ELT(namesres, 1, mkChar("dm")); SET_STRING_ELT(namesres, 2, mkChar("df")); setAttrib(res, R_NamesSymbol, namesres); UNPROTECT(5); /* done with res, namesres, statistic, dm, df */ return(res); } genefilter/src/ttest.f0000644000175100017510000000330014614230661016016 0ustar00biocbuildbiocbuildc By R Gray, March 19, 2000, DFCI c Copyright (C) 2000 Robert Gray c Distributed under the GNU public license c c t-statistics c first ng1 columns of d assumed to be group 1, other ng-ng1 assumed to be c group2. Note: single precision stats c c Modified by R. Gentleman, 2004, just extracted the ttest stats and c computed a ratio on demand - or fold-change subroutine fastt(d,n,ng,ng1,z,dm,eqv,ratio) real d(n,ng),z(n),dm(n) integer n,ng,ng1,ng2,eqv,ratio c initialize ng2=ng-ng1 do 61 i=1,n call tst2GM(d(i,1),ng1,ng2,n,z(i),dm(i), eqv, ratio) 61 continue return end subroutine tst2GM(d,ng1,ng2,n,tst,dm,eqv, ratio) c columns 1 to ng1 in group 1, ng1+1 to ng1+ng2 in group 2 real d(n,ng1+ng2),tst,dm double precision dm1,dm2,dss1,dss2 integer ng1,ng2,n,i,eqv, ratio dm1=0 dm2=0 dss1=0 dss2=0 do 10 i=1,ng1 dm1=dm1+d(1,i) 10 continue dm1=dm1/ng1 do 11 i=1,ng1 dss1=dss1+(d(1,i)-dm1)**2 11 continue do 12 i=1,ng2 dm2=dm2+d(1,ng1+i) 12 continue dm2=dm2/ng2 do 13 i=1,ng2 dss2=dss2+(d(1,ng1+i)-dm2)**2 13 continue if( ratio.eq.0) then dm=dm1-dm2 endif if( ratio.eq.1) then dm=dm1/dm2 endif if (dss1.eq.0.and.dss2.eq.0) then tst=0 return endif c intermediate calculations in dp, so stats with many ties give same sp result c regardless of order of calculations if( eqv .eq. 1 ) then tst=(dm1-dm2)/sqrt((1.d0/ng1+1.d0/ng2)*(dss1+dss2)/(ng1+ng2-2)) return endif tst=(dm1-dm2)/sqrt(dss1/((ng1-1)*ng1)+dss2/((ng2-1)*ng2)) end genefilter/vignettes/0000755000175100017510000000000014614336167015741 5ustar00biocbuildbiocbuildgenefilter/vignettes/howtogenefilter.Rmd0000644000175100017510000001301414614230661021601 0ustar00biocbuildbiocbuild--- title: "Using the genefilter function to filter genes from a microarray dataset" author: - name: "Khadijah Amusat" affiliation: "Vignette translation from Sweave to R Markdown / HTML" date: "`r format(Sys.time(), '%B %d , %Y')`" output: BiocStyle::html_document: number_sections: true toc: true toc_depth: 4 package: genefilter vignette: > %\VignetteIndexEntry{Using the genefilter function to filter genes from a microarray} %\VignetteEncoding{UTF-8} %\VignetteEngine{knitr::rmarkdown} --- # Introduction The `r Biocpkg("genefilter")` package can be used to filter (select) genes from a microarray dataset according to a variety of different filtering mechanisms. Here, we will consider the example dataset in the `sample.ExpressionSet` example from the `r Biocpkg("Biobase")` package. This experiment has 26 samples, and there are 500 genes and 3 covariates. The covariates are named `sex`, `type` and `score`. The first two have two levels and the last one is continuous. ```{r closeg, message = FALSE} library("Biobase") library("genefilter") data(sample.ExpressionSet) varLabels(sample.ExpressionSet) table(sample.ExpressionSet$sex) table(sample.ExpressionSet$type) ``` One dichotomy that can be of interest for subsequent analyses is whether the filter is *specific* or *non-specific*. Here, specific means that we are filtering with reference to sample metadata, for example, `type`. For example, if we want to select genes that are differentially expressed in the two groups defined by `type`, that is a specific filter. If on the other hand we want to select genes that are expressed in more than 5 samples, that is an example of a non--specific filter. First, let us see how to perform a non--specific filter. Suppose we want to select genes that have an expression measure above 200 in at least 5 samples. To do that we use the function `kOverA`. There are three steps that must be performed. 1. Create function(s) implementing the filtering criteria. 2. Assemble it (them) into a (combined) filtering function. 3. Apply the filtering function to the expression matrix. ```{r message=FALSE} f1 <- kOverA(5, 200) ffun <- filterfun(f1) wh1 <- genefilter(exprs(sample.ExpressionSet), ffun) sum(wh1) ``` Here `f1` is a function that implies our "expression measure above 200 in at least 5 samples" criterion, the function `ffun` is the filtering function (which in this case consists of only one criterion), and we apply it using `r Biocpkg("genefilter")`. There were `r sum(wh1)` genes that satisfied the criterion and passed the filter. As an example for a specific filter, let us select genes that are differentially expressed in the groups defined by `type`. ```{r} f2 <- ttest(sample.ExpressionSet$type, p=0.1) wh2 <- genefilter(exprs(sample.ExpressionSet), filterfun(f2)) sum(wh2) ``` Here, `ttest` is a function from the `r Biocpkg("genefilter")` package which provides a suitable wrapper around `t.test` from package `r Rpackage("stats")`. Now we see that there are `r sum(wh2)` genes that satisfy the selection criterion. Suppose that we want to combine the two filters. We want those genes for which at least 5 have an expression measure over 200 *and* which also are differentially expressed between the groups defined by `type` ```{r gene-indexing} ffun_combined <- filterfun(f1, f2) wh3 <- genefilter(exprs(sample.ExpressionSet), ffun_combined) sum(wh3) ``` Now we see that there are only `r sum(wh3)` genes that satisfy both conditions. ## Selecting genes that appear useful for prediction The function `knnCV` defined below performs $k$--nearest neighbour classification using leave--one--out cross--validation. At the same time it aggregates the genes that were selected. The function returns the predicted classifications as its returned value. However, there is an additional side effect. The number of times that each gene was used (provided it was at least one) are recorded and stored in the environment of the aggregator `Agg`. These can subsequently be retrieved and used for other purposes. ```{r knnCV} knnCV <- function(x, selectfun, cov, Agg, pselect = 0.01, scale=FALSE) { nc <- ncol(x) outvals <- rep(NA, nc) for(i in seq_len(nc)) { v1 <- x[,i] expr <- x[,-i] glist <- selectfun(expr, cov[-i], p=pselect) expr <- expr[glist,] if( scale ) { expr <- scale(expr) v1 <- as.vector(scale(v1[glist])) } else v1 <- v1[glist] out <- paste("iter ",i, " num genes= ", sum(glist), sep="") print(out) Aggregate(row.names(expr), Agg) if( length(v1) == 1) outvals[i] <- knn(expr, v1, cov[-i], k=5) else outvals[i] <- knn(t(expr), v1, cov[-i], k=5) } return(outvals) } ``` ```{r aggregate1} gfun <- function(expr, cov, p=0.05) { f2 <- ttest(cov, p=p) ffun <- filterfun(f2) which <- genefilter(expr, ffun) } ``` Next we show how to use this function on the dataset `geneData` ```{r aggregate2, results="hide"} library("class") ##scale the genes ##genescale is a slightly more flexible "scale" ##work on a subset -- for speed only geneData <- genescale(exprs(sample.ExpressionSet)[1:75,], 1) Agg <- new("aggregator") testcase <- knnCV(geneData, gfun, sample.ExpressionSet$type, Agg,pselect=0.05) ``` ```{r aggregate3} sort(sapply(aggenv(Agg), c), decreasing=TRUE) ``` The environment `Agg` contains, for each gene, the number of times it was selected in the cross-validation. # Session Information The version number of R and packages loaded for generating the vignette were: ```{r echo=FALSE} sessionInfo() ``` genefilter/vignettes/howtogenefinder.Rmd0000644000175100017510000000710214614230661021564 0ustar00biocbuildbiocbuild--- title: "How to find genes whose expression profile is similar to that of specified genes" author: - name: "Emmanuel Taiwo" affiliation: "Vignette translation from Sweave to R Markdown / HTML" date: "`r format(Sys.time(), '%B %d, %Y')`" vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{How to find genes whose expression profile is similar to that of specified genes} %\VignettePackage{genefilter} %\VignetteEncoding{UTF-8} output: BiocStyle::html_document: number_sections: yes toc: yes toc_depth: 4 --- # Introduction In some cases you have certain genes of interest and you would like to find other genes that are close to the genes of interest. This can be done using the `genefinder` function. You need to specify either the index position of the genes you want (which row of the expression array the gene is in) or the name (consistent with the `featureNames` of the ExpressionSet). A vector of names can be specified and matches for all will be computed. The number of matches and the distance measure used can all be specified. The examples will be carried out using the artificial data set, `sample.ExpressionSet`. Two other options for `genefinder` are `scale` and `method`. The `scale` option controls the scaling of the rows (this is often desirable), while the `method` option controls the distance measure used between genes. The possible values and their meanings are listed at the end of this document. ```{r closeg, message = FALSE} library("Biobase") library("genefilter") data(sample.ExpressionSet) igenes <- c(300,333,355,419) ##the interesting genes closeg <- genefinder(sample.ExpressionSet, igenes, 10, method="euc", scale="none") names(closeg) ``` The Affymetrix identifiers (since these were originally Affymetrix data) are `31539_r_at`, `31572_at`, `31594_at` and `31658_at`. We can find the nearest genes (by index) for any of these by simply accessing the relevant component of `closeg`. ```{r gene-indexing} closeg$"31539_r_at" Nms1 <- featureNames(sample.ExpressionSet)[closeg$"31539_r_at"$indices] Nms1 ``` You could then take these names (from `Nms1`) and the `r Biocpkg("annotate")` package and explore them further. See the various HOWTO's in annotate to see how to further explore your data. Examples include finding and searching all PubMed abstracts associated with these data. Finding and downloading associated sequence information. The data can also be visualized using the `r Biocpkg("geneplotter")` package (again there are a number of HOWTO documents there). # Parameter Settings The scale parameter can take the following values: **none** No scaling is done. **range** Scaling is done by $(x_{i} − x_{(1)})/(x_{(n)} − x_{(1)})$. **zscore** Scaling is done by $(x_{i} − \bar{x})/s_{x}$. Where s~x~ is the standard deviation. The `method` parameter can take the following values: **euclidean** Euclidean distance is used. **maximum** Maximum distance between any two elements of x and y (supremum norm). **manhattan** Absolute distance between the two vectors (1 norm). **canberra** The $\sum(|x_{i} − y_{i}|/|x_{i} + y_{i}|)$. Terms with zero numerator and denominator are omitted from the sum and treated as if the values were missing. **binary** (aka asymmetric binary): The vectors are regarded as binary bits, so non-zero elements are on and zero elements are off. The distance is the proportion of bits in which only one is on amongst those in which at least one is on. # Session Information The version number of R and packages loaded for generating the vignette were: ```{r, echo=FALSE} sessionInfo() ```genefilter/vignettes/independent_filtering_plots.Rnw0000644000175100017510000001521614614230661024207 0ustar00biocbuildbiocbuild%\VignetteIndexEntry{03 - Additional plots for: Independent filtering increases power for detecting differentially expressed genes, Bourgon et al., PNAS (2010)} %\VignettePackage{genefilter} %\VignetteEngine{knitr::knitr} % To compile this document % library('knitr'); rm(list=ls()); knit('independent_filtering_plots.Rnw') \documentclass[10pt]{article} <>= library("knitr") opts_chunk$set(tidy=FALSE,dev="png",fig.show="hide", fig.width=4,fig.height=4.5,dpi=240, message=FALSE,error=FALSE,warning=FALSE) @ <>= BiocStyle:::latex() @ \usepackage{xstring} \newcommand{\thetitle}{Additional plots for: Independent filtering increases power for detecting differentially expressed genes, Bourgon et al., PNAS (2010)} \title{\thetitle} \author{Richard Bourgon and Wolfgang Huber} \begin{document} <>= options( width = 80 ) @ % Make title \maketitle \tableofcontents \vspace{.25in} %%%%%%%% Main text \section{Introduction} This vignette illustrates use of some functions in the \emph{genefilter} package that provide useful diagnostics for independent filtering~\cite{BourgonIndependentFiltering}: \begin{itemize} \item \texttt{kappa\_p} and \texttt{kappa\_t} \item \texttt{filtered\_p} and \texttt{filtered\_R} \item \texttt{filter\_volcano} \item \texttt{rejection\_plot} \end{itemize} \section{Data preparation} Load the ALL data set and the \emph{genefilter} package: <>= library("genefilter") library("ALL") data("ALL") @ Reduce to just two conditions, then take a small subset of arrays from these, with 3 arrays per condition: <>= bcell <- grep("^B", as.character(ALL$BT)) moltyp <- which(as.character(ALL$mol.biol) %in% c("NEG", "BCR/ABL")) ALL_bcrneg <- ALL[, intersect(bcell, moltyp)] ALL_bcrneg$mol.biol <- factor(ALL_bcrneg$mol.biol) n1 <- n2 <- 3 set.seed(1969) use <- unlist(tapply(1:ncol(ALL_bcrneg), ALL_bcrneg$mol.biol, sample, n1)) subsample <- ALL_bcrneg[,use] @ We now use functions from \emph{genefilter} to compute overall standard devation filter statistics as well as standard two-sample $t$ and releated statistics. <>= S <- rowSds( exprs( subsample ) ) temp <- rowttests( subsample, subsample$mol.biol ) d <- temp$dm p <- temp$p.value t <- temp$statistic @ \section{Filtering volcano plot} Filtering on overall standard deviation and then using a standard $t$-statistic induces a lower bound of fold change, albeit one which varies somewhat with the significance of the $t$-statistic. The \texttt{filter\_volcano} function allows you to visualize this effect. <>= S_cutoff <- quantile(S, .50) filter_volcano(d, p, S, n1, n2, alpha=.01, S_cutoff) @ The output is shown in the left panel of Fig.~\ref{fig:volcano}. \begin{figure}[tb] \begin{center} \includegraphics[width=0.49\textwidth]{figure/filter_volcano-1} \includegraphics[width=0.49\textwidth]{figure/kappa-1} \caption{Left panel: plot produced by the \texttt{filter\_volcano} function. Right panel: graph of the \texttt{kappa\_t} function.} \label{fig:volcano} \end{center} \end{figure} The \texttt{kappa\_p} and \texttt{kappa\_t} functions, used to make the volcano plot, compute the fold change bound multiplier as a function of either a $t$-test $p$-value or the $t$-statistic itself. The actual induced bound on the fold change is $\kappa$ times the filter's cutoff on the overall standard deviation. Note that fold change bounds for values of $|T|$ which are close to 0 are not of practical interest because we will not reject the null hypothesis with test statistics in this range. <>= t <- seq(0, 5, length=100) plot(t, kappa_t(t, n1, n2) * S_cutoff, xlab="|T|", ylab="Fold change bound", type="l") @ The plot is shown in the right panel of Fig.~\ref{fig:volcano}. \section{Rejection count plots} \subsection{Across $p$-value cutoffs} The \texttt{filtered\_p} function permits easy simultaneous calculation of unadjusted or adjusted $p$-values over a range of filtering thresholds ($\theta$). Here, we return to the full ``BCR/ABL'' versus ``NEG'' data set, and compute adjusted $p$-values using the method of Benjamini and Hochberg, for a range of different filter stringencies. \begin{figure}[tb] \begin{center} \includegraphics[width=0.49\textwidth]{figure/rejection_plot-1} \includegraphics[width=0.49\textwidth]{figure/filtered_R_plot-1} \caption{Left panel: plot produced by the \texttt{rejection\_plot} function. Right panel: graph of \texttt{theta}.} \label{fig:rej} \end{center} \end{figure} <
>= table(ALL_bcrneg$mol.biol) @ <>= S2 <- rowVars(exprs(ALL_bcrneg)) p2 <- rowttests(ALL_bcrneg, "mol.biol")$p.value theta <- seq(0, .5, .1) p_bh <- filtered_p(S2, p2, theta, method="BH") @ <>= head(p_bh) @ The \texttt{rejection\_plot} function takes sets of $p$-values corresponding to different filtering choices --- in the columns of a matrix or in a list --- and shows how rejection count ($R$) relates to the choice of cutoff for the $p$-values. For these data, over a reasonable range of FDR cutoffs, increased filtering corresponds to increased rejections. <>= rejection_plot(p_bh, at="sample", xlim=c(0,.3), ylim=c(0,1000), main="Benjamini & Hochberg adjustment") @ The plot is shown in the left panel of Fig.~\ref{fig:rej}. \subsection{Across filtering fractions} If we select a fixed cutoff for the adjusted $p$-values, we can also look more closely at the relationship between the fraction of null hypotheses filtered and the total number of discoveries. The \texttt{filtered\_R} function wraps \texttt{filtered\_p} and just returns rejection counts. It requires a $p$-value cutoff. <>= theta <- seq(0, .80, .01) R_BH <- filtered_R(alpha=.10, S2, p2, theta, method="BH") @ <>= head(R_BH) @ Because overfiltering (or use of a filter which is inappropriate for the application domain) discards both false and true null hypotheses, very large values of $\theta$ reduce power in this example: <>= plot(theta, R_BH, type="l", xlab=expression(theta), ylab="Rejections", main="BH cutoff = 0.1") @ The plot is shown in the right panel of Fig.~\ref{fig:rej}. %%%%%%%% Session info \section*{Session information} <>= sessionInfo() |> toLatex() @ \begin{thebibliography}{10} \bibitem{BourgonIndependentFiltering} Richard Bourgon, Robert Gentleman and Wolfgang Huber. \newblock Independent filtering increases power for detecting differentially expressed genes. \end{thebibliography} \end{document} genefilter/vignettes/library.bib0000644000175100017510000001305714614230661020061 0ustar00biocbuildbiocbuild@Article{Anders:2010:GB, url = {http://genomebiology.com/2010/11/10/R106}, author = {Simon Anders and Wolfgang Huber}, Title = {{D}ifferential expression analysis for sequence count data}, Journal = {Genome Biology}, Year = 2010, Volume = 11, Pages = {R106}, } @article{BH:1995, author = {Y. Benjamini and Y. Hochberg}, title = {Controlling the false discovery rate: a practical and powerful approach to multiple testing}, journal = "Journal of the Royal Statistical Society B", year = 1995, volume = 57, pages = "289--300" } @Article{Bourgon:2010:PNAS, ISI = {ISI:000278054700015}, URL = {http://www.pnas.org/content/107/21/9546.long}, PDF = {PNAS-2010-Bourgon-9546-51.pdf}, author = {Richard Bourgon and Robert Gentleman and Wolfgang Huber}, Title = {Independent filtering increases detection power for high-throughput experiments}, journal = {PNAS}, Year = 2010, volume = 107, number = 21, pages = {9546--9551}, } @article{Brooks2010, author = {Brooks, A. N. and Yang, L. and Duff, M. O. and Hansen, K. D. and Park, J. W. and Dudoit, S. and Brenner, S. E. and Graveley, B. R.}, doi = {10.1101/gr.108662.110}, issn = {1088-9051}, journal = {Genome Research}, pages = {193--202}, title = {{Conservation of an RNA regulatory map between Drosophila and mammals}}, url = {http://genome.cshlp.org/cgi/doi/10.1101/gr.108662.110}, year = 2011 } @Article{Tibshirani1988, author = {Robert Tibshirani}, title = {Estimating transformations for regression via additivity and variance stabilization}, journal = {Journal of the American Statistical Association}, year = 1988, volume = 83, pages = {394--405} } @misc{htseq, author = {Simon Anders}, title = {{HTSeq: Analysing high-throughput sequencing data with Python}}, year = 2011, howpublished = {\url{http://www-huber.embl.de/users/anders/HTSeq/}} } @article{sagmb2003, title = {Parameter estimation for the calibration and variance stabilization of microarray data}, author = {Wolfgang Huber and Anja von Heydebreck and Holger {S\"ultmann} and Annemarie Poustka and Martin Vingron}, journal = {Statistical Applications in Genetics and Molecular Biology}, year = 2003, volume = 2, number = 1, pages = {Article 3} } @misc{summarizeOverlaps, author = {Valerie Obenchain}, title = {Counting with \texttt{summarizeOverlaps}}, year = 2011, howpublished = {Vignette, distributed as part of the Bioconductor package \emph{GenomicRanges}, as file \emph{summarizeOverlaps.pdf}} } @article{Anders:2012:GR, author = {Simon Anders and Alejandro Reyes and Wolfgang Huber}, title = {Detecting differential usage of exons from {RNA-seq} data }, year = {2012}, journal = {Genome Research}, doi = {10.1101/gr.133744.111}, } @article{CR, author = {Cox, D. R. and Reid, N.}, journal = {Journal of the Royal Statistical Society, Series B}, keywords = {CML,Cox-Reid,ML,dispersion}, mendeley-tags = {CML,Cox-Reid,ML,dispersion}, number = {1}, pages = {1--39}, title = {{Parameter orthogonality and approximate conditional inference}}, url = {http://www.jstor.org/stable/2345476}, volume = {49}, year = {1987} } @article{edgeR_GLM, author = {McCarthy, Davis J and Chen, Yunshun and Smyth, Gordon K}, doi = {10.1093/nar/gks042}, issn = {1362-4962}, journal = {Nucleic Acids Research}, keywords = {edgeR}, mendeley-tags = {edgeR}, month = jan, pmid = {22287627}, title = {{Differential expression analysis of multifactor RNA-Seq experiments with respect to biological variation}}, url = {http://www.ncbi.nlm.nih.gov/pubmed/22287627}, year = {2012}, volume={40}, pages={4288-4297} } @article{SchwederSpjotvoll1982, author={Schweder, T. and Spj\/{o}tvoll, E.}, title={Plots of {P-values} to evaluate many tests simultaneously}, journal={Biometrika}, year={1982}, volume=69, pages={493-502}, doi={10.1093/biomet/69.3.493} } @article{Haglund2012Evidence, abstract = {{Context: Primary hyperparathyroidism (PHPT) is most frequently present in postmenopausal women. Although the involvement of estrogen has been suggested, current literature indicates that parathyroid tumors are estrogen receptor (ER) alpha negative.}}, author = {Haglund, Felix and Ma, Ran and Huss, Mikael and Sulaiman, Luqman and Lu, Ming and Nilsson, Inga-Lena and H\"{o}\"{o}g, Anders and Juhlin, Christofer C. and Hartman, Johan and Larsson, Catharina}, day = {28}, doi = {10.1210/jc.2012-2484}, issn = {1945-7197}, journal = {Journal of Clinical Endocrinology \& Metabolism}, month = sep, pmid = {23024189}, posted-at = {2012-11-23 08:40:12}, priority = {2}, publisher = {Endocrine Society}, title = {{Evidence of a Functional Estrogen Receptor in Parathyroid Adenomas}}, url = {https://doi.org/10.1210/jc.2012-2484}, year = {2012} } @article{Wu2012New, author = {Wu, Hao and Wang, Chi and Wu, Zhijin}, day = {22}, doi = {10.1093/biostatistics/kxs033}, issn = {1468-4357}, journal = {Biostatistics}, month = sep, pmid = {23001152}, posted-at = {2013-02-26 17:09:19}, priority = {2}, publisher = {Oxford University Press}, title = {{A new shrinkage estimator for dispersion improves differential expression detection in RNA-seq data}}, url = {https://doi.org/10.1093/biostatistics/kxs033}, year = {2012} }