VariantAnnotation/build/0000755000175100017510000000000014614361054016334 5ustar00biocbuildbiocbuildVariantAnnotation/build/vignette.rds0000644000175100017510000000051314614361054020672 0ustar00biocbuildbiocbuildR=O0uPhT|sFXD&qFUm!1{{)oBHz=Z4 I[L,Ϣ8E)ϐ(NkUDBHȥ|GX\|L#Xr"Fl}h@ SN. U29g7w*i,ӸuGEm9晳cx ߼nSխiH hiH ;H\*,܃u6d"qT:Vra]}PϮ8SNB:DVariantAnnotation/DESCRIPTION0000644000175100017510000000415314614361055016747 0ustar00biocbuildbiocbuildPackage: VariantAnnotation Type: Package Title: Annotation of Genetic Variants Description: Annotate variants, compute amino acid coding changes, predict coding outcomes. Version: 1.50.0 Authors@R: c( person("Valerie", "Oberchain", role="aut"), person("Martin", "Morgan", role="aut"), person("Michael", "Lawrence", role="aut"), person("Stephanie", "Gogarten", role="ctb"), person("Bioconductor Package Maintainer", role="cre", email="maintainer@bioconductor.org")) License: Artistic-2.0 Depends: R (>= 4.0.0), methods, BiocGenerics (>= 0.37.0), MatrixGenerics, GenomeInfoDb (>= 1.15.2), GenomicRanges (>= 1.41.5), SummarizedExperiment (>= 1.19.5), Rsamtools (>= 2.19.1) Imports: utils, DBI, zlibbioc, Biobase, S4Vectors (>= 0.27.12), IRanges (>= 2.23.9), XVector (>= 0.29.2), Biostrings (>= 2.57.2), AnnotationDbi (>= 1.27.9), rtracklayer (>= 1.39.7), BSgenome (>= 1.47.3), GenomicFeatures (>= 1.31.3) Suggests: RUnit, AnnotationHub, BSgenome.Hsapiens.UCSC.hg19, TxDb.Hsapiens.UCSC.hg19.knownGene, SNPlocs.Hsapiens.dbSNP144.GRCh37, SIFT.Hsapiens.dbSNP132, SIFT.Hsapiens.dbSNP137, PolyPhen.Hsapiens.dbSNP131, snpStats, ggplot2, BiocStyle, knitr, magick, jsonlite, httr, rjsoncons LinkingTo: S4Vectors, IRanges, XVector, Biostrings, Rhtslib (>= 2.99.0) SystemRequirements: GNU make LazyLoad: yes biocViews: DataImport, Sequencing, SNP, Annotation, Genetics, VariantAnnotation Video: https://www.youtube.com/watch?v=Ro0lHQ_J--I&list=UUqaMSQd_h-2EDGsU6WDiX0Q RoxygenNote: 7.3.1 VignetteBuilder: knitr git_url: https://git.bioconductor.org/packages/VariantAnnotation git_branch: RELEASE_3_19 git_last_commit: 7805cec git_last_commit_date: 2024-04-30 Repository: Bioconductor 3.19 Date/Publication: 2024-04-30 NeedsCompilation: yes Packaged: 2024-05-01 06:33:17 UTC; biocbuild Author: Valerie Oberchain [aut], Martin Morgan [aut], Michael Lawrence [aut], Stephanie Gogarten [ctb], Bioconductor Package Maintainer [cre] Maintainer: Bioconductor Package Maintainer VariantAnnotation/inst/0000755000175100017510000000000014614361054016212 5ustar00biocbuildbiocbuildVariantAnnotation/inst/CITATION0000644000175100017510000000335014614305321017343 0ustar00biocbuildbiocbuildbibentry(bibtype = "Article", key = "Obenchain15072014", author = c(person(given = "Valerie", family = "Obenchain"), person(given = "Michael", family = "Lawrence"), person(given = "Vincent", family = "Carey"), person(given = "Stephanie", family = "Gogarten"), person(given = "Paul", family = "Shannon"), person(given = "Martin", family = "Morgan")), title = "VariantAnnotation: a Bioconductor package for exploration and annotation of genetic variants", volume = "30", number = "14", pages = "2076-2078", year = "2014", doi = "10.1093/bioinformatics/btu168", abstract = "Summary: VariantAnnotation is an R / Bioconductor package for the exploration and annotation of genetic variants. Capabilities exist for reading, writing and filtering variant call format (VCF) files. VariantAnnotation allows ready access to additional R / Bioconductor facilities for advanced statistical analysis, data transformation, visualization and integration with diverse genomic resources. Availability and implementation: This package is implemented in R and available for download at the Bioconductor Web site (http://bioconductor.org/packages/2.13/bioc/html/VariantAnnotation.html). The package contains extensive help pages for individual functions and a 'vignette' outlining typical work flows; it is made available under the open source 'Artistic-2.0' license. Version 1.9.38 was used in this article. Contact: valerie.obenchain@roswellpark.org", journal = "Bioinformatics") VariantAnnotation/inst/doc/0000755000175100017510000000000014614361054016757 5ustar00biocbuildbiocbuildVariantAnnotation/inst/doc/ensemblVEP.html0000644000175100017510000246235314614360751021667 0ustar00biocbuildbiocbuild ensemblVEP: using the REST API with Bioconductor

Contents

1 Introduction

Ensembl’s Variant Effect Predictor is described in McLaren et al. (2016).

Prior to Bioconductor 3.19, the ensemblVEP package provided access to Ensembl’s predictions through an interface between Perl and MySQL.

In 3.19 VariantAnnotation supports the use of the VEP component of the REST API at https://rest.ensembl.org.

2 Acquire annotation on variants from a VCF file

The function vep_by_region will accept a VCF object as defined in VariantAnnotation.

library(VariantAnnotation)
fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation")
r22 = readVcf(fl)
r22
## class: CollapsedVCF 
## dim: 10376 5 
## rowRanges(vcf):
##   GRanges with 5 metadata columns: paramRangeID, REF, ALT, QUAL, FILTER
## info(vcf):
##   DataFrame with 22 columns: LDAF, AVGPOST, RSQ, ERATE, THETA, CIEND, CIPOS,...
## info(header(vcf)):
##              Number Type    Description                                        
##    LDAF      1      Float   MLE Allele Frequency Accounting for LD             
##    AVGPOST   1      Float   Average posterior probability from MaCH/Thunder    
##    RSQ       1      Float   Genotype imputation quality from MaCH/Thunder      
##    ERATE     1      Float   Per-marker Mutation rate from MaCH/Thunder         
##    THETA     1      Float   Per-marker Transition rate from MaCH/Thunder       
##    CIEND     2      Integer Confidence interval around END for imprecise var...
##    CIPOS     2      Integer Confidence interval around POS for imprecise var...
##    END       1      Integer End position of the variant described in this re...
##    HOMLEN    .      Integer Length of base pair identical micro-homology at ...
##    HOMSEQ    .      String  Sequence of base pair identical micro-homology a...
##    SVLEN     1      Integer Difference in length between REF and ALT alleles   
##    SVTYPE    1      String  Type of structural variant                         
##    AC        .      Integer Alternate Allele Count                             
##    AN        1      Integer Total Allele Count                                 
##    AA        1      String  Ancestral Allele, ftp://ftp.1000genomes.ebi.ac.u...
##    AF        1      Float   Global Allele Frequency based on AC/AN             
##    AMR_AF    1      Float   Allele Frequency for samples from AMR based on A...
##    ASN_AF    1      Float   Allele Frequency for samples from ASN based on A...
##    AFR_AF    1      Float   Allele Frequency for samples from AFR based on A...
##    EUR_AF    1      Float   Allele Frequency for samples from EUR based on A...
##    VT        1      String  indicates what type of variant the line represents 
##    SNPSOURCE .      String  indicates if a snp was called when analysing the...
## geno(vcf):
##   List of length 3: GT, DS, GL
## geno(header(vcf)):
##       Number Type   Description                      
##    GT 1      String Genotype                         
##    DS 1      Float  Genotype dosage from MaCH/Thunder
##    GL G      Float  Genotype Likelihoods

In this example we confine attention to single nucleotide variants.

There is a limit of 200 locations in a request, and 55000 requests per hour. We’ll base our query on 100 positions in the chr22 VCF.

dr = which(width(rowRanges(r22))!=1)
r22s = r22[-dr]
res = vep_by_region(r22[1:100], snv_only=FALSE, chk_max=FALSE)
jans = toJSON(content(res))

There are various ways to work with the result of this query to the API. We’ll use the rjsoncons JSON processing infrastructure to dig in and understand aspects of the API behavior.

First, the top-level concepts produced for each variant can be retrieved using

library(rjsoncons)
names(jsonlite::fromJSON(jmespath(jans, "[*]")))
##  [1] "strand"                          "end"                            
##  [3] "regulatory_feature_consequences" "id"                             
##  [5] "seq_region_name"                 "start"                          
##  [7] "most_severe_consequence"         "transcript_consequences"        
##  [9] "assembly_name"                   "input"                          
## [11] "allele_string"                   "motif_feature_consequences"     
## [13] "colocated_variants"

Annotation of the most severe consequence known will typically be of interest:

table(jsonlite::fromJSON(jmespath(jans, "[*].most_severe_consequence")))
## 
##   5_prime_UTR_variant        intron_variant splice_region_variant 
##                     1                    98                     1

There is variability in the structure of data returned for each query.

head(fromJSON(jmespath(jans, "[*].regulatory_feature_consequences")))
## [[1]]
##   regulatory_feature_id variant_allele consequence_terms   impact  biotype
## 1          ENSR0000....              G      regulato.... MODIFIER promoter
## 
## [[2]]
##   consequence_terms  biotype   impact regulatory_feature_id variant_allele
## 1      regulato.... promoter MODIFIER          ENSR0000....              T
## 
## [[3]]
##     impact consequence_terms  biotype variant_allele regulatory_feature_id
## 1 MODIFIER      regulato.... promoter              A          ENSR0000....
## 
## [[4]]
##     impact consequence_terms  biotype variant_allele regulatory_feature_id
## 1 MODIFIER      regulato.... promoter              T          ENSR0000....
## 
## [[5]]
##   variant_allele regulatory_feature_id consequence_terms   impact  biotype
## 1              T          ENSR0000....      regulato.... MODIFIER promoter
## 
## [[6]]
##   consequence_terms  biotype   impact regulatory_feature_id variant_allele
## 1      regulato.... promoter MODIFIER          ENSR0000....              A

Furthermore, the content of the motif feature consequences field seems very peculiar.

table(unlist(fromJSON(jmespath(jans, "[*].motif_feature_consequences"))))
## 
##                  -0.003                  -0.022                  -0.087 
##                       1                       1                       1 
##                       1                       2                       6 
##                       3                       1                       1 
##                       9                       A         ENSM00205804739 
##                       1                       1                       1 
##         ENSM00494167763         ENSM00522532781              ENSPFM0238 
##                       1                       1                       1 
##              ENSPFM0506              ENSPFM0597               GCM1::MAX 
##                       1                       1                       1 
##                MODIFIER                       N                       T 
##                       3                       2                       2 
##             TEAD4::ELF1             TEAD4::ELK1             TEAD4::SPIB 
##                       1                       1                       1 
## TF_binding_site_variant             TFAP2C::MAX                       Y 
##                       3                       1                       1

3 Transforming the API response to GRanges

We’ll consider the following approach to converting the API response to a GenomicRanges GRanges instance. Eventually this may become part of the package.

library(GenomicRanges)
.make_GRanges = function( vep_response ) {
  stopifnot(inherits(vep_response, "response"))  # httr
  nested = fromJSON(toJSON(content(vep_response)))
  ini = GRanges(seqnames = unlist(nested$seq_region_name),
    IRanges(start=unlist(nested$start), end=unlist(nested$end)))
  dr = match(c("seq_region_name", "start", "end"), names(nested))
  mcols(ini) = DataFrame(nested[,-dr])
  ini
}
tstg = .make_GRanges( res )
tstg[,1]  # full print is unwieldy
## GRanges object with 100 ranges and 1 metadata column:
##         seqnames    ranges strand | strand
##            <Rle> <IRanges>  <Rle> | <list>
##     [1]       22  50300078      * |      1
##     [2]       22  50300086      * |      1
##     [3]       22  50300101      * |      1
##     [4]       22  50300113      * |      1
##     [5]       22  50300166      * |      1
##     ...      ...       ...    ... .    ...
##    [96]       22  50304748      * |      1
##    [97]       22  50304805      * |      1
##    [98]       22  50304935      * |      1
##    [99]       22  50304943      * |      1
##   [100]       22  50305084      * |      1
##   -------
##   seqinfo: 1 sequence from an unspecified genome; no seqlengths
names(mcols(tstg))
##  [1] "strand"                          "regulatory_feature_consequences"
##  [3] "id"                              "most_severe_consequence"        
##  [5] "transcript_consequences"         "assembly_name"                  
##  [7] "input"                           "allele_string"                  
##  [9] "motif_feature_consequences"      "colocated_variants"

Now information about variants can be retrieved with range operations. Deep annotation requires nested structure of the metadata columns.

mcols(tstg)[1, "transcript_consequences"]
## [[1]]
##     impact transcript_id gene_symbol      gene_id consequence_terms
## 1 MODIFIER  ENST0000....      PLXNB2 ENSG0000....      intron_v....
## 2 MODIFIER  ENST0000....      PLXNB2 ENSG0000....      intron_v....
## 3 MODIFIER  ENST0000....      PLXNB2 ENSG0000....      intron_v....
## 4 MODIFIER  ENST0000....      PLXNB2 ENSG0000....      intron_v....
##        biotype gene_symbol_source   hgnc_id strand variant_allele      flags
## 1 protein_....               HGNC HGNC:9104     -1              G           
## 2 protein_....               HGNC HGNC:9104     -1              G cds_end_NF
## 3 protein_....               HGNC HGNC:9104     -1              G cds_end_NF
## 4 protein_....               HGNC HGNC:9104     -1              G

4 Further work

An important element of prior work in ensemblVEP supports feeding annotation back into the VCF used to generate the effect prediction query. This seems feasible but concrete use cases are of interest.

References

McLaren, William, Laurent Gil, Sarah E. Hunt, Harpreet Singh Riat, Graham R. S. Ritchie, Anja Thormann, Paul Flicek, and Fiona Cunningham. 2016. “The Ensembl Variant Effect Predictor.” Genome Biology 17 (1): 122. https://doi.org/10.1186/s13059-016-0974-4.

VariantAnnotation/inst/doc/ensemblVEP.R0000644000175100017510000000355614614360750021115 0ustar00biocbuildbiocbuild## ----setup,echo=FALSE,results="hide",message=FALSE---------------------------- library(BiocStyle) library(VariantAnnotation) library(jsonlite) library(httr) ## ----dodemo,message=FALSE----------------------------------------------------- library(VariantAnnotation) fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") r22 = readVcf(fl) r22 ## ----lksnv-------------------------------------------------------------------- dr = which(width(rowRanges(r22))!=1) r22s = r22[-dr] res = vep_by_region(r22[1:100], snv_only=FALSE, chk_max=FALSE) jans = toJSON(content(res)) ## ----doj1, message=FALSE------------------------------------------------------ library(rjsoncons) names(jsonlite::fromJSON(jmespath(jans, "[*]"))) ## ----doj2--------------------------------------------------------------------- table(jsonlite::fromJSON(jmespath(jans, "[*].most_severe_consequence"))) ## ----doj3--------------------------------------------------------------------- head(fromJSON(jmespath(jans, "[*].regulatory_feature_consequences"))) ## ----lktaaaa------------------------------------------------------------------ table(unlist(fromJSON(jmespath(jans, "[*].motif_feature_consequences")))) ## ----lkmakeg, message=FALSE--------------------------------------------------- library(GenomicRanges) .make_GRanges = function( vep_response ) { stopifnot(inherits(vep_response, "response")) # httr nested = fromJSON(toJSON(content(vep_response))) ini = GRanges(seqnames = unlist(nested$seq_region_name), IRanges(start=unlist(nested$start), end=unlist(nested$end))) dr = match(c("seq_region_name", "start", "end"), names(nested)) mcols(ini) = DataFrame(nested[,-dr]) ini } tstg = .make_GRanges( res ) tstg[,1] # full print is unwieldy names(mcols(tstg)) ## ----lkmc--------------------------------------------------------------------- mcols(tstg)[1, "transcript_consequences"] VariantAnnotation/inst/doc/ensemblVEP.Rmd0000644000175100017510000000712514614305321021423 0ustar00biocbuildbiocbuild--- title: "ensemblVEP: using the REST API with Bioconductor" author: "Vincent J. Carey, stvjc at channing.harvard.edu" date: "`r format(Sys.time(), '%B %d, %Y')`" vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{ensemblVEP: using the REST API with Bioconductor} %\VignetteEncoding{UTF-8} output: BiocStyle::html_document: highlight: pygments number_sections: yes theme: united toc: yes bibliography: ens.bib --- ```{r setup,echo=FALSE,results="hide",message=FALSE} library(BiocStyle) library(VariantAnnotation) library(jsonlite) library(httr) ``` # Introduction Ensembl's Variant Effect Predictor is described in @McLaren2016. Prior to Bioconductor 3.19, the ensemblVEP package provided access to Ensembl's predictions through an interface between Perl and MySQL. In 3.19 VariantAnnotation supports the use of the VEP component of the REST API at [https://rest.ensembl.org](https://rest.ensembl.org/). # Acquire annotation on variants from a VCF file The function `vep_by_region` will accept a VCF object as defined in `r Biocpkg("VariantAnnotation")`. ```{r dodemo,message=FALSE} library(VariantAnnotation) fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") r22 = readVcf(fl) r22 ``` In this example we confine attention to single nucleotide variants. There is a limit of 200 locations in a request, and 55000 requests per hour. We'll base our query on 100 positions in the chr22 VCF. ```{r lksnv} dr = which(width(rowRanges(r22))!=1) r22s = r22[-dr] res = vep_by_region(r22[1:100], snv_only=FALSE, chk_max=FALSE) jans = toJSON(content(res)) ``` There are various ways to work with the result of this query to the API. We'll use the `r CRANpkg('rjsoncons')` JSON processing infrastructure to dig in and understand aspects of the API behavior. First, the top-level concepts produced for each variant can be retrieved using ```{r doj1, message=FALSE} library(rjsoncons) names(jsonlite::fromJSON(jmespath(jans, "[*]"))) ``` Annotation of the most severe consequence known will typically be of interest: ```{r doj2} table(jsonlite::fromJSON(jmespath(jans, "[*].most_severe_consequence"))) ``` There is variability in the structure of data returned for each query. ```{r doj3} head(fromJSON(jmespath(jans, "[*].regulatory_feature_consequences"))) ``` Furthermore, the content of the motif feature consequences field seems very peculiar. ```{r lktaaaa} table(unlist(fromJSON(jmespath(jans, "[*].motif_feature_consequences")))) ``` # Transforming the API response to GRanges We'll consider the following approach to converting the API response to a GenomicRanges GRanges instance. Eventually this may become part of the package. ```{r lkmakeg, message=FALSE} library(GenomicRanges) .make_GRanges = function( vep_response ) { stopifnot(inherits(vep_response, "response")) # httr nested = fromJSON(toJSON(content(vep_response))) ini = GRanges(seqnames = unlist(nested$seq_region_name), IRanges(start=unlist(nested$start), end=unlist(nested$end))) dr = match(c("seq_region_name", "start", "end"), names(nested)) mcols(ini) = DataFrame(nested[,-dr]) ini } tstg = .make_GRanges( res ) tstg[,1] # full print is unwieldy names(mcols(tstg)) ``` Now information about variants can be retrieved with range operations. Deep annotation requires nested structure of the metadata columns. ```{r lkmc} mcols(tstg)[1, "transcript_consequences"] ``` # Further work An important element of prior work in ensemblVEP supports feeding annotation back into the VCF used to generate the effect prediction query. This seems feasible but concrete use cases are of interest. # References VariantAnnotation/inst/doc/filterVcf.html0000644000175100017510000236446614614361005021612 0ustar00biocbuildbiocbuild 2. Using filterVcf() to Select Variants from VCF Files

Contents

1 Introduction

Whole genome Variant Call Format (VCF) files are very large, typically containing millions of called variants, one call per line of text. The actual number of variants relevant to a particular study (of a disease such as breast cancer, for instance) will often be far fewer. Thus the first task one faces when analyzing a whole genome VCF file is to identify and extract the relatively few variants which may be of interest, excluding all others. This vignette illustrates several techniques for doing this.

We demonstrate three methods: filtering by genomic region, filtering on attributes of each specific variant call, and intersecting with known regions of interest (exons, splice sites, regulatory regions, etc.). We are primarily concerned with the latter two. However, in order to create the small VCF data file we use here for demonstration purposes, we employed genomic region filtering, reducing a very large whole genome two-sample breast cancer VCF file of fourteen million calls, to a file containing fewer than ten thousand calls in a one million base pair region of chromosome 7. For the sake of reproducibility, and for completeness of exposition, we will illustrate this first step also.

2 The Data: Paired Tumor/Normal Breast Cancer Variants

Complete Genomics Inc. states:

To provide the scientific community with public access to data generated from two paired tumor/normal cancer samples, Complete Genomics sequenced and analyzed cell-line samples of patients with breast cancer (invasive ductal carcinomas). The cell line-derived DNA are housed at ATCC. Samples have been sequenced to an average genome-wide coverage of 123X for three of the samples, and 92X for for the fourth sample.1 Data generated withversion 2.0.0.32 of the Complete Genomics assembly software, on high molecular weight genomic DNA isolated from the HCC1187 breast carcinoma cell line ATCC CRL 2322. Sequencing methods documented in (Drmanac et al., 2010)

A small (1M base) subset of this data is included in the current package, and used in the code presented below.

3 Filter by Genomic Region

We identified this subset in a prior exploration of the full data set (work not shown), learning that variants of biological interest suitable for our purpose are found in a 1M base pair region of chromosome seven. The appendix to this document (see below) shows the few lines of code required to extract variant calls in that small region, from the very large file obtained from Complete Genomics (somaticVcfBeta-HCC1187-H-200-37-ASM-T1-N1.vcf.gz) and write them to a new, small VCF file.

4 Introducing the filterVcf Method

The filterVcf method reads (by chunks, about which more below) through a possibly very large VCF file to write a new, smaller VCF file which includes only those variant calling rows which meet the criteria specified in prefilters and filters.

Reading “by chunks” is accomplished using a tabix (Li, 2011) file. The a yieldSize argument specifies how many variant lines are read into memory at each iteration.

tabix.file <- TabixFile(file.gz, yieldSize=10000)
filterVcf(tabix.file, genome, destination.file,
              prefilters=prefilters, filters=filters)

in which

  1. file.gz: a gzipped vcf file with an accompanying Tabix index file.
  2. yieldSize: the number of text (call variant) lines to read at a time.
  3. genome: a string indicating the genome assembly, e.g., “hg19”.
  4. prefilters: one or more simple string-based filtering functions, each of which returns a logical vector corresponding to the vcf rows it will be passed (as simple character strings).
  5. filters: one or more filtering function, each of which returns a logical vector, corresponding to the list of parsed vcf structures it will be passed.

4.1 Prefilters

Prefilters are conceptually very simple. They are functions which will be called with a single argument, a vector of character strings, each of which is an unparsed variant call line, as read from the input VCF file. We use grepl to return a logical vector equal in length to the incoming vector of unparsed VCF lines. Each prefilter and filter is called repeatedly, with lines supplied on each invocation. filterVcf calls these functions repeatedly until the input file is exhausted.

Notice how the logic of these prefilters is very simple, using grepl to do fast, simple, fixed pattern matching:

isGermlinePrefilter <- function(x) {
    grepl("Germline", x, fixed=TRUE)
}

notInDbsnpPrefilter <- function(x) {
    !(grepl("dbsnp", x, fixed=TRUE))
}

4.2 Filters

Filters are more sophisticated than prefilters in that they assess parsed variant call lines for possible inclusion. Such parsing is intrinsically expensive but will be performed only on those lines which passed the prefilters. Therefore it pays to eliminate as many lines as possible using prefilters. Filters are useful when there exists detailed criteria for inclusion and exclusion. This can be seen below, especially in the allelicDepth function. Each filter must be written to return a logical vector as long as the number of rows in the input VCF argument; be sure your filter works with 0-row VCF instances.

## We will use isSNV() to filter only SNVs

allelicDepth <- function(x) {
    ##  ratio of AD of the "alternate allele" for the tumor sample
    ##  OR "reference allele" for normal samples to total reads for
    ##  the sample should be greater than some threshold (say 0.1,
    ##  that is: at least 10% of the sample should have the allele
    ##  of interest)
    ad <- geno(x)$AD
    tumorPct <- ad[,1,2,drop=FALSE] / rowSums(ad[,1,,drop=FALSE])
    normPct <- ad[,2,1, drop=FALSE] / rowSums(ad[,2,,drop=FALSE])
    test <- (tumorPct > 0.1) | (normPct > 0.1)
    as.vector(!is.na(test) & test)
}

4.3 FilterRules

FilterRules allow you to combine a list of filters, or of prefilters so that they may be passed as parameters to filterVcf. We use them here to combine the isGermlinePrefilter with the notInDbsnpPrefilter, and the isSNV with the AD filter.

library(VariantAnnotation)
prefilters <- FilterRules(list(germline=isGermlinePrefilter,
                               dbsnp=notInDbsnpPrefilter))
filters <- FilterRules(list(isSNV=isSNV, AD=allelicDepth))

4.4 Create the Filtered file

file.gz     <- system.file("extdata", "chr7-sub.vcf.gz",
                           package="VariantAnnotation")
file.gz.tbi <- system.file("extdata", "chr7-sub.vcf.gz.tbi",
                           package="VariantAnnotation")
destination.file <- tempfile()
tabix.file <- TabixFile(file.gz, yieldSize=10000)
filterVcf(tabix.file,  "hg19", destination.file,
          prefilters=prefilters, filters=filters, verbose=TRUE)

5 Look for SNPs in Regulatory Regions

We have now created a file containing 29 novel, Germline, SNP variant calls, each with a reasonable allelic depth, extracted from the 3808 calls in chr7-sub.vcf. We examine those variants for overlap with regulatory regions, turning to the ENCODE project and using Bioconductor’s AnnotationHub.

The ENCODE project is a large, long-term effort to build a “parts list” of all the functional elements in the human genome. They have recently focused on regulatory elements. We use the Bioconductor AnnotationHub to download regulatory regions reported for a breast cancer cell line, with which to identify possibly functional, and possibly clinically relevant SNVs in the breast cancer tumor/normal genome we have been examining.

The AnnotationHub is a recent addition to Bioconductor that facilitates access to genome-scale resources like ENCODE.

5.1 Load CTCF Transcription Factor Binding Regions Identified in MCF-7 Breast Cancer Cell Line

The MCF-7 Breast Cancer Cell line was established forty years ago, and has since played a dominant role in breast cancer cell line studies. The University of Washington reports transcription factor binding sites (TFBS) for the CTCF protein, which often acts as a negative regulator of transcription via chromatin structure modifications Though the MCF-7 cell line is an imperfect match to the HCC1187 cell line sequenced by Complete Genomics, we combine these two breast-cancer related data sets here, didactically, in this exercise, to highlight the importance of cell-type-specific regulatory regions, and of the availability of such data from ENCODE. We shall see a SNP in the intronic binding region of the cancer-related gene, EGFR.

library(AnnotationHub)
hub <- AnnotationHub()
id <- names(query(hub, "wgEncodeUwTfbsMcf7CtcfStdPkRep1.narrowPeak"))
mcf7.gr <- hub[[tail(id, 1)]]

5.2 Find SNPs in CTCF Binding Regions

vcf <- readVcf(destination.file, "hg19")
seqlevels(vcf) <- paste("chr", seqlevels(vcf), sep="")
ov.mcf7 <- findOverlaps(vcf, mcf7.gr)

There is just one SNV which overlaps with the MCF-7 regulatory regions. Find out where, if anywhere, it fits within a gene model.

library(TxDb.Hsapiens.UCSC.hg19.knownGene)
txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene
locateVariants(vcf[6,], txdb, AllVariants())
## GRanges object with 10 ranges and 9 metadata columns:
##                  seqnames    ranges strand | LOCATION  LOCSTART    LOCEND
##                     <Rle> <IRanges>  <Rle> | <factor> <integer> <integer>
##   7:55212133_C/T     chr7  55212133      + |   intron    168915    168915
##   7:55212133_C/T     chr7  55212133      + |   intron    162109    162109
##   7:55212133_C/T     chr7  55212133      + |   intron    136465    136465
##   7:55212133_C/T     chr7  55212133      + |   intron    124739    124739
##   7:55212133_C/T     chr7  55212133      + |   intron    124739    124739
##   7:55212133_C/T     chr7  55212133      + |   intron    124739    124739
##   7:55212133_C/T     chr7  55212133      + |   intron    124739    124739
##   7:55212133_C/T     chr7  55212133      + |   intron    124739    124739
##   7:55212133_C/T     chr7  55212133      + |   intron    124739    124739
##   7:55212133_C/T     chr7  55212133      + |   intron     34146     34146
##                    QUERYID        TXID         CDSID      GENEID
##                  <integer> <character> <IntegerList> <character>
##   7:55212133_C/T         1       25129                      2898
##   7:55212133_C/T         1       25130                      2898
##   7:55212133_C/T         1       25131                      2898
##   7:55212133_C/T         1       25132                    389421
##   7:55212133_C/T         1       25133                    389421
##   7:55212133_C/T         1       25134                    154442
##   7:55212133_C/T         1       25135                       639
##   7:55212133_C/T         1       25136                       639
##   7:55212133_C/T         1       25138                       202
##   7:55212133_C/T         1       25139                       202
##                        PRECEDEID        FOLLOWID
##                  <CharacterList> <CharacterList>
##   7:55212133_C/T                                
##   7:55212133_C/T                                
##   7:55212133_C/T                                
##   7:55212133_C/T                                
##   7:55212133_C/T                                
##   7:55212133_C/T                                
##   7:55212133_C/T                                
##   7:55212133_C/T                                
##   7:55212133_C/T                                
##   7:55212133_C/T                                
##   -------
##   seqinfo: 1 sequence from an unspecified genome; no seqlengths

6 Conclusion

This case study begins, somewhat artificially, with a very short region of chromosome seven, a section which we knew, from previous exploration, held an intronic regulatory SNV for EGFR, a receptor tryosine kinase implicated in some cancers. Though artificial, the case study illustrates all of the steps needed for broader, realistic surveys of whole genome variation data:

  1. Filter by genomic coordinates.
  2. Filter to extract only those variant calls which meet these criteria: Germline, novel (not in dbSnp), consisting of a single nucleotide, of sufficient allelic depth.
  3. Intersect these variants with recognized DNA elements. In our case, we used short TFBS regulatory regions, but the same method can be used with exons, splice sites, DNaseI footprints, methylation sites, etc.

7 Appendix: Filter by Genomic Region

The most basic form of VCF file filtering is by genomic region. We demonstrate that here, extracting variant calls in a 1M base region of chromosome 7, writing them to a new file, compressing and then indexing that file. These steps created the small VCF file which accompanies this vignette, and is used in the code shown above.

Note that this code is NOT executed during the creation of this vignette: we do not supply the very large VCF file that it operates on. This code is here for tutorial purposes only, showing how you can filter by genomic region with a possibly large VCF file of your own.

library(VariantAnnotation)
file.gz <- "somaticVcfBeta-HCC1187-H-200-37-ASM-T1-N1.vcf.gz"
stopifnot(file.exists(file.gz))
file.gz.tbi <- paste(file.gz, ".tbi", sep="")
if(!(file.exists(file.gz.tbi)))
    indexTabix(file.gz, format="vcf")
start.loc <- 55000000
end.loc   <- 56000000
chr7.gr <- GRanges("7", IRanges(start.loc, end.loc))
params <- ScanVcfParam(which=chr7.gr)
vcf <- readVcf(TabixFile(file.gz), "hg19", params)
writeVcf(vcf, "chr7-sub.vcf")
bgzip("chr7-sub.vcf", overwrite=TRUE)
indexTabix("chr7-sub.vcf.gz", format="vcf")

This code creates the small gzipped vcf and index files used in the examples above.

Bibliography

Drmanac,R. et al. (2010) Human genome sequencing using unchained base reads on self-assembling dna nanoarrays. Science, 327, 78–81.

Li,H. (2011) Tabix: Fast retrieval of sequence features from generic tab-delimited files. Bioinformatics, 27, 718–719.

VariantAnnotation/inst/doc/filterVcf.R0000644000175100017510000000630614614361004021026 0ustar00biocbuildbiocbuild## ----eval=FALSE--------------------------------------------------------------- # tabix.file <- TabixFile(file.gz, yieldSize=10000) # filterVcf(tabix.file, genome, destination.file, # prefilters=prefilters, filters=filters) ## ----prefilters--------------------------------------------------------------- isGermlinePrefilter <- function(x) { grepl("Germline", x, fixed=TRUE) } notInDbsnpPrefilter <- function(x) { !(grepl("dbsnp", x, fixed=TRUE)) } ## ----filters------------------------------------------------------------------ ## We will use isSNV() to filter only SNVs allelicDepth <- function(x) { ## ratio of AD of the "alternate allele" for the tumor sample ## OR "reference allele" for normal samples to total reads for ## the sample should be greater than some threshold (say 0.1, ## that is: at least 10% of the sample should have the allele ## of interest) ad <- geno(x)$AD tumorPct <- ad[,1,2,drop=FALSE] / rowSums(ad[,1,,drop=FALSE]) normPct <- ad[,2,1, drop=FALSE] / rowSums(ad[,2,,drop=FALSE]) test <- (tumorPct > 0.1) | (normPct > 0.1) as.vector(!is.na(test) & test) } ## ----createFilterRules, message=FALSE, warning=FALSE-------------------------- library(VariantAnnotation) prefilters <- FilterRules(list(germline=isGermlinePrefilter, dbsnp=notInDbsnpPrefilter)) filters <- FilterRules(list(isSNV=isSNV, AD=allelicDepth)) ## ----createFilteredFile, message=FALSE, warning=FALSE------------------------- file.gz <- system.file("extdata", "chr7-sub.vcf.gz", package="VariantAnnotation") file.gz.tbi <- system.file("extdata", "chr7-sub.vcf.gz.tbi", package="VariantAnnotation") destination.file <- tempfile() tabix.file <- TabixFile(file.gz, yieldSize=10000) filterVcf(tabix.file, "hg19", destination.file, prefilters=prefilters, filters=filters, verbose=TRUE) ## ----mcf7regulatoryRegions, message=FALSE, warning=FALSE---------------------- library(AnnotationHub) hub <- AnnotationHub() id <- names(query(hub, "wgEncodeUwTfbsMcf7CtcfStdPkRep1.narrowPeak")) mcf7.gr <- hub[[tail(id, 1)]] ## ----findOverlaps------------------------------------------------------------- vcf <- readVcf(destination.file, "hg19") seqlevels(vcf) <- paste("chr", seqlevels(vcf), sep="") ov.mcf7 <- findOverlaps(vcf, mcf7.gr) ## ----locateVariant, message=FALSE, warning=FALSE------------------------------ library(TxDb.Hsapiens.UCSC.hg19.knownGene) txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene locateVariants(vcf[6,], txdb, AllVariants()) ## ----eval=FALSE--------------------------------------------------------------- # library(VariantAnnotation) # file.gz <- "somaticVcfBeta-HCC1187-H-200-37-ASM-T1-N1.vcf.gz" # stopifnot(file.exists(file.gz)) # file.gz.tbi <- paste(file.gz, ".tbi", sep="") # if(!(file.exists(file.gz.tbi))) # indexTabix(file.gz, format="vcf") # start.loc <- 55000000 # end.loc <- 56000000 # chr7.gr <- GRanges("7", IRanges(start.loc, end.loc)) # params <- ScanVcfParam(which=chr7.gr) # vcf <- readVcf(TabixFile(file.gz), "hg19", params) # writeVcf(vcf, "chr7-sub.vcf") # bgzip("chr7-sub.vcf", overwrite=TRUE) # indexTabix("chr7-sub.vcf.gz", format="vcf") VariantAnnotation/inst/doc/filterVcf.Rmd0000644000175100017510000002756714614305321021363 0ustar00biocbuildbiocbuild--- title: "2. Using filterVcf() to Select Variants from VCF Files" author: "Paul Shannon" date: |+ Created: 20 February, 2013 Last Modified: `r format(Sys.Date(), "%B %d, %Y")` vignette: > %\VignetteIndexEntry{2. Using filterVcf to Select Variants from VCF Files} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} output: BiocStyle::html_document: number_sections: yes toc: yes toc_depth: 4 bibliography: filterVcf.bib csl: bioinformatics.csl link-citations: true --- # Introduction Whole genome Variant Call Format (VCF) files are very large, typically containing millions of called variants, one call per line of text. The actual number of variants relevant to a particular study (of a disease such as breast cancer, for instance) will often be far fewer. Thus the first task one faces when analyzing a whole genome VCF file is to identify and extract the relatively few variants which may be of interest, excluding all others. This vignette illustrates several techniques for doing this. We demonstrate three methods: filtering by genomic region, filtering on attributes of each specific variant call, and intersecting with known regions of interest (exons, splice sites, regulatory regions, etc.). We are primarily concerned with the latter two. However, in order to create the small VCF data file we use here for demonstration purposes, we employed genomic region filtering, reducing a very large whole genome two-sample breast cancer VCF file of fourteen million calls, to a file containing fewer than ten thousand calls in a one million base pair region of chromosome 7. For the sake of reproducibility, and for completeness of exposition, we will illustrate this first step also. # The Data: Paired Tumor/Normal Breast Cancer Variants [Complete Genomics Inc.](http://www.completegenomics.com/public-data/cancer-data) states: > To provide the scientific community with public access to data > generated from two paired tumor/normal cancer samples, Complete > Genomics sequenced and analyzed cell-line samples of patients with > breast cancer (invasive ductal carcinomas). The cell line-derived DNA > are housed at ATCC. Samples have been sequenced to an average > genome-wide coverage of 123X for three of the samples, and 92X for for > the fourth sample.^[Data generated withversion 2.0.0.32 of the Complete Genomics assembly software, on high molecular weight genomic DNA isolated from the HCC1187 breast carcinoma cell line ATCC CRL 2322. Sequencing methods documented in [@drmanac2010human]] A small (1M base) subset of this data is included in the current package, and used in the code presented below. # Filter by Genomic Region We identified this subset in a prior exploration of the full data set (work not shown), learning that variants of biological interest suitable for our purpose are found in a 1M base pair region of chromosome seven. The appendix to this document (see below) shows the few lines of code required to extract variant calls in that small region, from the very large file obtained from Complete Genomics (*somaticVcfBeta-HCC1187-H-200-37-ASM-T1-N1.vcf.gz*) and write them to a new, small VCF file. # Introducing the `filterVcf` Method The `filterVcf ` method reads (by chunks, about which more below) through a possibly very large VCF file to write a new, smaller VCF file which includes only those variant calling rows which meet the criteria specified in `prefilters` and `filters`. Reading "by chunks" is accomplished using a tabix [@li2011tabix] file. The a `yieldSize` argument specifies how many variant lines are read into memory at each iteration. ```{r eval=FALSE} tabix.file <- TabixFile(file.gz, yieldSize=10000) filterVcf(tabix.file, genome, destination.file, prefilters=prefilters, filters=filters) ``` in which 1. *file.gz*: a gzipped vcf file with an accompanying Tabix index file. 2. *yieldSize*: the number of text (call variant) lines to read at a time. 3. *genome*: a string indicating the genome assembly, e.g., "hg19". 4. *prefilters*: one or more simple string-based filtering functions, each of which returns a logical vector corresponding to the vcf rows it will be passed (as simple character strings). 5. *filters*: one or more filtering function, each of which returns a logical vector, corresponding to the list of parsed vcf structures it will be passed. ## Prefilters Prefilters are conceptually very simple. They are functions which will be called with a single argument, a vector of character strings, each of which is an *unparsed* variant call line, as read from the input VCF file. We use `grepl` to return a logical vector equal in length to the incoming vector of unparsed VCF lines. Each prefilter and filter is called repeatedly, with lines supplied on each invocation. `filterVcf` calls these functions repeatedly until the input file is exhausted. Notice how the logic of these prefilters is very simple, using `grepl` to do fast, simple, fixed pattern matching: ```{r prefilters} isGermlinePrefilter <- function(x) { grepl("Germline", x, fixed=TRUE) } notInDbsnpPrefilter <- function(x) { !(grepl("dbsnp", x, fixed=TRUE)) } ``` ## Filters Filters are more sophisticated than prefilters in that they assess *parsed* variant call lines for possible inclusion. Such parsing is intrinsically expensive but will be performed only on those lines which passed the prefilters. Therefore it pays to eliminate as many lines as possible using prefilters. Filters are useful when there exists detailed criteria for inclusion and exclusion. This can be seen below, especially in the `allelicDepth` function. Each filter must be written to return a logical vector as long as the number of rows in the input VCF argument; be sure your filter works with 0-row VCF instances. ```{r filters} ## We will use isSNV() to filter only SNVs allelicDepth <- function(x) { ## ratio of AD of the "alternate allele" for the tumor sample ## OR "reference allele" for normal samples to total reads for ## the sample should be greater than some threshold (say 0.1, ## that is: at least 10% of the sample should have the allele ## of interest) ad <- geno(x)$AD tumorPct <- ad[,1,2,drop=FALSE] / rowSums(ad[,1,,drop=FALSE]) normPct <- ad[,2,1, drop=FALSE] / rowSums(ad[,2,,drop=FALSE]) test <- (tumorPct > 0.1) | (normPct > 0.1) as.vector(!is.na(test) & test) } ``` ## FilterRules `FilterRules` allow you to combine a list of filters, or of prefilters so that they may be passed as parameters to *filterVcf*. We use them here to combine the *isGermlinePrefilter* with the *notInDbsnpPrefilter*, and the *isSNV* with the *AD* filter. ```{r createFilterRules, message=FALSE, warning=FALSE} library(VariantAnnotation) prefilters <- FilterRules(list(germline=isGermlinePrefilter, dbsnp=notInDbsnpPrefilter)) filters <- FilterRules(list(isSNV=isSNV, AD=allelicDepth)) ``` ## Create the Filtered file ```{r createFilteredFile, message=FALSE, warning=FALSE} file.gz <- system.file("extdata", "chr7-sub.vcf.gz", package="VariantAnnotation") file.gz.tbi <- system.file("extdata", "chr7-sub.vcf.gz.tbi", package="VariantAnnotation") destination.file <- tempfile() tabix.file <- TabixFile(file.gz, yieldSize=10000) filterVcf(tabix.file, "hg19", destination.file, prefilters=prefilters, filters=filters, verbose=TRUE) ``` # Look for SNPs in Regulatory Regions We have now created a file containing 29 novel, Germline, SNP variant calls, each with a reasonable allelic depth, extracted from the 3808 calls in *chr7-sub.vcf*. We examine those variants for overlap with regulatory regions, turning to the ENCODE project and using Bioconductor's `r Biocpkg("AnnotationHub")`. The ENCODE project is a large, long-term effort to build a "parts list" of all the functional elements in the human genome. They have recently focused on regulatory elements. We use the Bioconductor `r Biocpkg("AnnotationHub")` to download regulatory regions reported for a breast cancer cell line, with which to identify possibly functional, and possibly clinically relevant SNVs in the breast cancer tumor/normal genome we have been examining. The `r Biocpkg("AnnotationHub")` is a recent addition to Bioconductor that facilitates access to genome-scale resources like ENCODE. ## Load CTCF Transcription Factor Binding Regions Identified in MCF-7 Breast Cancer Cell Line The [MCF-7](http://en.wikipedia.org/wiki/MCF-7) Breast Cancer Cell line was established forty years ago, and has since played a dominant role in breast cancer cell line studies. The University of Washington reports transcription factor binding sites (TFBS) for the CTCF protein, which often acts as a negative regulator of transcription via chromatin structure modifications Though the MCF-7 cell line is an imperfect match to the HCC1187 cell line sequenced by Complete Genomics, we combine these two breast-cancer related data sets here, didactically, in this exercise, to highlight the importance of cell-type-specific regulatory regions, and of the availability of such data from ENCODE. We shall see a SNP in the intronic binding region of the cancer-related gene, EGFR. ```{r mcf7regulatoryRegions, message=FALSE, warning=FALSE} library(AnnotationHub) hub <- AnnotationHub() id <- names(query(hub, "wgEncodeUwTfbsMcf7CtcfStdPkRep1.narrowPeak")) mcf7.gr <- hub[[tail(id, 1)]] ``` ## Find SNPs in CTCF Binding Regions ```{r findOverlaps} vcf <- readVcf(destination.file, "hg19") seqlevels(vcf) <- paste("chr", seqlevels(vcf), sep="") ov.mcf7 <- findOverlaps(vcf, mcf7.gr) ``` There is just one SNV which overlaps with the MCF-7 regulatory regions. Find out where, if anywhere, it fits within a gene model. ```{r locateVariant, message=FALSE, warning=FALSE} library(TxDb.Hsapiens.UCSC.hg19.knownGene) txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene locateVariants(vcf[6,], txdb, AllVariants()) ``` # Conclusion This case study begins, somewhat artificially, with a very short region of chromosome seven, a section which we knew, from previous exploration, held an intronic regulatory SNV for EGFR, a receptor tryosine kinase implicated in some cancers. Though artificial, the case study illustrates all of the steps needed for broader, realistic surveys of whole genome variation data: 1. Filter by genomic coordinates. 2. Filter to extract only those variant calls which meet these criteria: Germline, novel (not in dbSnp), consisting of a single nucleotide, of sufficient allelic depth. 3. Intersect these variants with recognized DNA elements. In our case, we used short TFBS regulatory regions, but the same method can be used with exons, splice sites, DNaseI footprints, methylation sites, etc. # Appendix: Filter by Genomic Region The most basic form of VCF file filtering is by genomic region. We demonstrate that here, extracting variant calls in a 1M base region of chromosome 7, writing them to a new file, compressing and then indexing that file. These steps created the small VCF file which accompanies this vignette, and is used in the code shown above. Note that this code is *NOT* executed during the creation of this vignette: we do not supply the very large VCF file that it operates on. This code is here for tutorial purposes only, showing how you can filter by genomic region with a possibly large VCF file of your own. ```{r eval=FALSE} library(VariantAnnotation) file.gz <- "somaticVcfBeta-HCC1187-H-200-37-ASM-T1-N1.vcf.gz" stopifnot(file.exists(file.gz)) file.gz.tbi <- paste(file.gz, ".tbi", sep="") if(!(file.exists(file.gz.tbi))) indexTabix(file.gz, format="vcf") start.loc <- 55000000 end.loc <- 56000000 chr7.gr <- GRanges("7", IRanges(start.loc, end.loc)) params <- ScanVcfParam(which=chr7.gr) vcf <- readVcf(TabixFile(file.gz), "hg19", params) writeVcf(vcf, "chr7-sub.vcf") bgzip("chr7-sub.vcf", overwrite=TRUE) indexTabix("chr7-sub.vcf.gz", format="vcf") ``` This code creates the small gzipped vcf and index files used in the examples above. # Bibliography {-}VariantAnnotation/inst/doc/VariantAnnotation.html0000644000175100017510000301340214614361054023307 0ustar00biocbuildbiocbuild 1. Introduction to VariantAnnotation

Contents

1 Introduction

This vignette outlines a work flow for annotating and filtering genetic variants using the VariantAnnotation package. Sample data are in VariantCall Format (VCF) and are a subset of chromosome 22 from 1000 Genomes. VCF text files contain meta-information lines, a header line with column names, data lines with information about a position in the genome, and optional genotype information on samples for each position. Samtools organisation and repositories describes the VCF format in detail.

Data are read in from a VCF file and variants identified according to region such as coding, intron, intergenic, spliceSite etc. Amino acid coding changes are computed for the non-synonymous variants and SIFT and PolyPhen databases provide predictions of how severly the coding changes affect protein function.

2 Variant Call Format (VCF) files

2.1 Data import and exploration

Data are parsed into a VCF object with readVcf.

library(VariantAnnotation)
fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation")
vcf <- readVcf(fl, "hg19")
vcf
## class: CollapsedVCF 
## dim: 10376 5 
## rowRanges(vcf):
##   GRanges with 5 metadata columns: paramRangeID, REF, ALT, QUAL, FILTER
## info(vcf):
##   DataFrame with 22 columns: LDAF, AVGPOST, RSQ, ERATE, THETA, CIEND, CIPOS,...
## info(header(vcf)):
##              Number Type    Description                                        
##    LDAF      1      Float   MLE Allele Frequency Accounting for LD             
##    AVGPOST   1      Float   Average posterior probability from MaCH/Thunder    
##    RSQ       1      Float   Genotype imputation quality from MaCH/Thunder      
##    ERATE     1      Float   Per-marker Mutation rate from MaCH/Thunder         
##    THETA     1      Float   Per-marker Transition rate from MaCH/Thunder       
##    CIEND     2      Integer Confidence interval around END for imprecise var...
##    CIPOS     2      Integer Confidence interval around POS for imprecise var...
##    END       1      Integer End position of the variant described in this re...
##    HOMLEN    .      Integer Length of base pair identical micro-homology at ...
##    HOMSEQ    .      String  Sequence of base pair identical micro-homology a...
##    SVLEN     1      Integer Difference in length between REF and ALT alleles   
##    SVTYPE    1      String  Type of structural variant                         
##    AC        .      Integer Alternate Allele Count                             
##    AN        1      Integer Total Allele Count                                 
##    AA        1      String  Ancestral Allele, ftp://ftp.1000genomes.ebi.ac.u...
##    AF        1      Float   Global Allele Frequency based on AC/AN             
##    AMR_AF    1      Float   Allele Frequency for samples from AMR based on A...
##    ASN_AF    1      Float   Allele Frequency for samples from ASN based on A...
##    AFR_AF    1      Float   Allele Frequency for samples from AFR based on A...
##    EUR_AF    1      Float   Allele Frequency for samples from EUR based on A...
##    VT        1      String  indicates what type of variant the line represents 
##    SNPSOURCE .      String  indicates if a snp was called when analysing the...
## geno(vcf):
##   List of length 3: GT, DS, GL
## geno(header(vcf)):
##       Number Type   Description                      
##    GT 1      String Genotype                         
##    DS 1      Float  Genotype dosage from MaCH/Thunder
##    GL G      Float  Genotype Likelihoods

2.1.1 Header information

Header information can be extracted from the VCF with header(). We see there are 5 samples, 1 piece of meta information, 22 info fields and 3 geno fields.

header(vcf)
## class: VCFHeader 
## samples(5): HG00096 HG00097 HG00099 HG00100 HG00101
## meta(1): fileformat
## fixed(2): FILTER ALT
## info(22): LDAF AVGPOST ... VT SNPSOURCE
## geno(3): GT DS GL

Data can be further extracted using the named accessors.

samples(header(vcf))
## [1] "HG00096" "HG00097" "HG00099" "HG00100" "HG00101"
geno(header(vcf))
## DataFrame with 3 rows and 3 columns
##         Number        Type            Description
##    <character> <character>            <character>
## GT           1      String               Genotype
## DS           1       Float Genotype dosage from..
## GL           G       Float   Genotype Likelihoods

2.1.2 Genomic positions

rowRanges contains information from the CHROM, POS, and ID fields of the VCF file, represented as a GRanges. The paramRangeID column is meaningful when reading subsets of data and is discussed further below.

head(rowRanges(vcf), 3)
## GRanges object with 3 ranges and 5 metadata columns:
##               seqnames    ranges strand | paramRangeID            REF
##                  <Rle> <IRanges>  <Rle> |     <factor> <DNAStringSet>
##     rs7410291       22  50300078      * |           NA              A
##   rs147922003       22  50300086      * |           NA              C
##   rs114143073       22  50300101      * |           NA              G
##                              ALT      QUAL      FILTER
##               <DNAStringSetList> <numeric> <character>
##     rs7410291                  G       100        PASS
##   rs147922003                  T       100        PASS
##   rs114143073                  A       100        PASS
##   -------
##   seqinfo: 1 sequence from hg19 genome; no seqlengths

Individual fields can be pulled out with named accessors. Here we see REF is stored as a DNAStringSet and qual is a numeric vector.

ref(vcf)[1:5]
## DNAStringSet object of length 5:
##     width seq
## [1]     1 A
## [2]     1 C
## [3]     1 G
## [4]     1 C
## [5]     1 C
qual(vcf)[1:5]
## [1] 100 100 100 100 100

ALT is a DNAStringSetList (allows for multiple alternate alleles per variant) or a DNAStringSet. When structural variants are present it will be a CharacterList.

alt(vcf)[1:5]
## DNAStringSetList of length 5
## [[1]] G
## [[2]] T
## [[3]] A
## [[4]] T
## [[5]] T

2.1.3 Genotype data

Genotype data described in the FORMAT fields are parsed into the geno slot. The data are unique to each sample and each sample may have multiple values variable. Because of this, the data are parsed into matrices or arrays where the rows represent the variants and the columns the samples. Multidimentional arrays indicate multiple values per sample. In this file all variables are matrices.

geno(vcf)
## List of length 3
## names(3): GT DS GL
sapply(geno(vcf), class)
##      GT       DS       GL      
## [1,] "matrix" "matrix" "matrix"
## [2,] "array"  "array"  "array"

Let’s take a closer look at the genotype dosage (DS) variable. The header provides the variable definition and type.

geno(header(vcf))["DS",]
## DataFrame with 1 row and 3 columns
##         Number        Type            Description
##    <character> <character>            <character>
## DS           1       Float Genotype dosage from..

These data are stored as a 10376 x 5 matrix. Each of the five samples (columns) has a single value per variant location (row).

DS <-geno(vcf)$DS
dim(DS)
## [1] 10376     5
DS[1:3,]
##             HG00096 HG00097 HG00099 HG00100 HG00101
## rs7410291         0       0       1       0       0
## rs147922003       0       0       0       0       0
## rs114143073       0       0       0       0       0

DS is also known as ‘posterior mean genotypes’ and range in value from [0, 2]. To get a sense of variable distribution, we compute a five number summary of the minimum, lower-hinge (first quartile), median, upper-hinge (third quartile) and maximum.

fivenum(DS)
## [1] 0 0 0 0 2

The majority of these values (86%) are zero.

length(which(DS==0))/length(DS)
## [1] 0.8621627

View the distribution of the non-zero values.

hist(DS[DS != 0], breaks=seq(0, 2, by=0.05),
    main="DS non-zero values", xlab="DS")

2.1.4 Info data

In contrast to the genotype data, the info data are unique to the variant and the same across samples. All info variables are represented in a single DataFrame.

info(vcf)[1:4, 1:5]
## DataFrame with 4 rows and 5 columns
##                  LDAF   AVGPOST       RSQ     ERATE     THETA
##             <numeric> <numeric> <numeric> <numeric> <numeric>
## rs7410291      0.3431    0.9890    0.9856     2e-03    0.0005
## rs147922003    0.0091    0.9963    0.8398     5e-04    0.0011
## rs114143073    0.0098    0.9891    0.5919     7e-04    0.0008
## rs141778433    0.0062    0.9950    0.6756     9e-04    0.0003

We will use the info data to compare quality measures between novel (i.e., not in dbSNP) and known (i.e., in dbSNP) variants and the variant type present in the file. Variants with membership in dbSNP can be identified by using the appropriate SNPlocs package for the hg19 genome (GRCh37).

library(SNPlocs.Hsapiens.dbSNP144.GRCh37)
vcf_rsids <- names(rowRanges(vcf))
chr22snps <- snpsBySeqname(SNPlocs.Hsapiens.dbSNP144.GRCh37, "22")
chr22_rsids <- mcols(chr22snps)$RefSNP_id
in_dbSNP <- vcf_rsids %in% chr22_rsids
table(in_dbSNP) 
## in_dbSNP
## FALSE  TRUE 
##  1114  9262

Info variables of interest are ‘VT’, ‘LDAF’ and ‘RSQ’. The header offers more details on these variables.

info(header(vcf))[c("VT", "LDAF", "RSQ"),]
## DataFrame with 3 rows and 3 columns
##           Number        Type            Description
##      <character> <character>            <character>
## VT             1      String indicates what type ..
## LDAF           1       Float MLE Allele Frequency..
## RSQ            1       Float Genotype imputation ..

Create a data frame of quality measures of interest …

metrics <- data.frame(QUAL=qual(vcf), in_dbSNP=in_dbSNP,
    VT=info(vcf)$VT, LDAF=info(vcf)$LDAF, RSQ=info(vcf)$RSQ)

and visualize the distribution of qualities using ggplot2. For instance, genotype imputation quality is higher for the known variants in dbSNP.

library(ggplot2)
ggplot(metrics, aes(x=RSQ, fill=in_dbSNP)) +
    geom_density(alpha=0.5) +
    scale_x_continuous(name="MaCH / Thunder Imputation Quality") +
    scale_y_continuous(name="Density") +
    theme(legend.position="top")

2.2 Import data subsets

When working with large VCF files it may be more efficient to read in subsets of the data. This can be accomplished by selecting genomic coordinates (ranges) or by specific fields from the VCF file.

2.2.1 Select genomic coordinates

To read in a portion of chromosome 22, create a GRanges with the regions of interest.

rng <- GRanges(seqnames="22", ranges=IRanges(
           start=c(50301422, 50989541), 
           end=c(50312106, 51001328),
           names=c("gene_79087", "gene_644186")))

When ranges are specified, the VCF file must have an accompanying Tabix index file. See indexTabix for help creating an index.

tab <- TabixFile(fl)
vcf_rng <- readVcf(tab, "hg19", param=rng)

The paramRangesID column distinguishes which records came from which param range.

head(rowRanges(vcf_rng), 3)
## GRanges object with 3 ranges and 5 metadata columns:
##                   seqnames    ranges strand | paramRangeID            REF
##                      <Rle> <IRanges>  <Rle> |     <factor> <DNAStringSet>
##       rs114335781       22  50301422      * |   gene_79087              G
##         rs8135963       22  50301476      * |   gene_79087              T
##   22:50301488_C/T       22  50301488      * |   gene_79087              C
##                                  ALT      QUAL      FILTER
##                   <DNAStringSetList> <numeric> <character>
##       rs114335781                  A       100        PASS
##         rs8135963                  C       100        PASS
##   22:50301488_C/T                  T       100        PASS
##   -------
##   seqinfo: 1 sequence from hg19 genome; no seqlengths

2.2.2 Select VCF fields

Data import can also be defined by the fixed, info and geno fields. Fields available for import are described in the header information. To view the header before reading in the data, use ScanVcfHeader.

hdr <- scanVcfHeader(fl)
## e.g., INFO and GENO fields
head(info(hdr), 3)
## DataFrame with 3 rows and 3 columns
##              Number        Type            Description
##         <character> <character>            <character>
## LDAF              1       Float MLE Allele Frequency..
## AVGPOST           1       Float Average posterior pr..
## RSQ               1       Float Genotype imputation ..
head(geno(hdr), 3)
## DataFrame with 3 rows and 3 columns
##         Number        Type            Description
##    <character> <character>            <character>
## GT           1      String               Genotype
## DS           1       Float Genotype dosage from..
## GL           G       Float   Genotype Likelihoods

To subset on “LDAF” and “GT” we specify them as character vectors in the info and geno arguments to ScanVcfParam. This creates a ScanVcfParam object which is used as the param argument to readVcf.

## Return all 'fixed' fields, "LAF" from 'info' and "GT" from 'geno'
svp <- ScanVcfParam(info="LDAF", geno="GT")
vcf1 <- readVcf(fl, "hg19", svp)
names(geno(vcf1))
## [1] "GT"

To subset on both genomic coordinates and fields the ScanVcfParam object must contain both.

svp_all <- ScanVcfParam(info="LDAF", geno="GT", which=rng)
svp_all
## class: ScanVcfParam 
## vcfWhich: 1 elements
## vcfFixed: character() [All] 
## vcfInfo: LDAF 
## vcfGeno: GT 
## vcfSamples:

3 Locating variants in and around genes

Variant location with respect to genes can be identified with the locateVariants function. Regions are specified in the region argument and can be one of the following constructors: CodingVariants, IntronVariants, FiveUTRVariants, ThreeUTRVariants, IntergenicVariants, SpliceSiteVariants or PromoterVariants. Location definitions are shown in Table 1.


Table 1: Variant locations
Location Details
coding falls within a coding region
fiveUTR falls within a 5’ untranslated region
threeUTR falls within a 3’ untranslated region
intron falls within an intron region
intergenic does not fall within a transcript associated with a gene
spliceSite overlaps any portion of the first 2 or last 2
promoter falls within a promoter region of a transcript

For overlap methods to work properly the chromosome names (seqlevels) must be compatible in the objects being compared. The VCF data chromosome names are represented by number, i.e., ‘22’, but the TxDb chromosome names are preceded with ‘chr’. Seqlevels in the VCF can be modified with the seqlevels function.

library(TxDb.Hsapiens.UCSC.hg19.knownGene)
txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene
seqlevels(vcf) <- "chr22"
rd <- rowRanges(vcf)
loc <- locateVariants(rd, txdb, CodingVariants())
head(loc, 3)
## GRanges object with 3 ranges and 9 metadata columns:
##                   seqnames    ranges strand | LOCATION  LOCSTART    LOCEND
##                      <Rle> <IRanges>  <Rle> | <factor> <integer> <integer>
##       rs114335781    chr22  50301422      - |   coding       939       939
##         rs8135963    chr22  50301476      - |   coding       885       885
##   22:50301488_C/T    chr22  50301488      - |   coding       873       873
##                     QUERYID        TXID         CDSID      GENEID
##                   <integer> <character> <IntegerList> <character>
##       rs114335781        24       75253        218562       79087
##         rs8135963        25       75253        218562       79087
##   22:50301488_C/T        26       75253        218562       79087
##                         PRECEDEID        FOLLOWID
##                   <CharacterList> <CharacterList>
##       rs114335781                                
##         rs8135963                                
##   22:50301488_C/T                                
##   -------
##   seqinfo: 1 sequence from an unspecified genome; no seqlengths

Locate variants in all regions with the AllVariants() constructor,

allvar <- locateVariants(rd, txdb, AllVariants())

To answer gene-centric questions data can be summarized by gene reguardless of transcript.

## Did any coding variants match more than one gene?
splt <- split(mcols(loc)$GENEID, mcols(loc)$QUERYID) 
table(sapply(splt, function(x) length(unique(x)) > 1))
## 
## FALSE  TRUE 
##   965    15
## Summarize the number of coding variants by gene ID.
splt <- split(mcols(loc)$QUERYID, mcols(loc)$GENEID)
head(sapply(splt, function(x) length(unique(x))), 3)
## 113730   1890  23209 
##     22     15     30

4 Amino acid coding changes

predictCoding computes amino acid coding changes for non-synonymous variants. Only ranges in query that overlap with a coding region in the subject are considered. Reference sequences are retrieved from either a BSgenome or fasta file specified in seqSource. Variant sequences are constructed by substituting, inserting or deleting values in the varAllele column into the reference sequence. Amino acid codes are computed for the variant codon sequence when the length is a multiple of 3.

The query argument to predictCoding can be a GRanges or VCF. When a GRanges is supplied the varAllele argument must be specified. In the case of a VCF, the alternate alleles are taken from alt(<VCF>) and the varAllele argument is not specified.

The result is a modified query containing only variants that fall within coding regions. Each row represents a variant-transcript match so more than one row per original variant is possible.

library(BSgenome.Hsapiens.UCSC.hg19)
coding <- predictCoding(vcf, txdb, seqSource=Hsapiens)
coding[5:7]
## GRanges object with 3 ranges and 17 metadata columns:
##                   seqnames    ranges strand | paramRangeID            REF
##                      <Rle> <IRanges>  <Rle> |     <factor> <DNAStringSet>
##   22:50301584_C/T    chr22  50301584      - |           NA              C
##       rs114264124    chr22  50302962      - |           NA              C
##       rs149209714    chr22  50302995      - |           NA              C
##                                  ALT      QUAL      FILTER      varAllele
##                   <DNAStringSetList> <numeric> <character> <DNAStringSet>
##   22:50301584_C/T                  T       100        PASS              A
##       rs114264124                  T       100        PASS              A
##       rs149209714                  G       100        PASS              C
##                      CDSLOC    PROTEINLOC   QUERYID        TXID         CDSID
##                   <IRanges> <IntegerList> <integer> <character> <IntegerList>
##   22:50301584_C/T       777           259        28       75253        218562
##       rs114264124       698           233        57       75253        218563
##       rs149209714       665           222        58       75253        218563
##                        GENEID   CONSEQUENCE       REFCODON       VARCODON
##                   <character>      <factor> <DNAStringSet> <DNAStringSet>
##   22:50301584_C/T       79087 synonymous               CCG            CCA
##       rs114264124       79087 nonsynonymous            CGG            CAG
##       rs149209714       79087 nonsynonymous            GGA            GCA
##                           REFAA         VARAA
##                   <AAStringSet> <AAStringSet>
##   22:50301584_C/T             P             P
##       rs114264124             R             Q
##       rs149209714             G             A
##   -------
##   seqinfo: 1 sequence from hg19 genome; no seqlengths

Using variant rs114264124 as an example, we see varAllele A has been substituted into the refCodon CGG to produce varCodon CAG. The refCodon is the sequence of codons necessary to make the variant allele substitution and therefore often includes more nucleotides than indicated in the range (i.e. the range is 50302962, 50302962, width of 1). Notice it is the second position in the refCodon that has been substituted. This position in the codon, the position of substitution, corresponds to genomic position 50302962. This genomic position maps to position 698 in coding region-based coordinates and to triplet 233 in the protein. This is a non-synonymous coding variant where the amino acid has changed from R (Arg) to Q (Gln).

When the resulting varCodon is not a multiple of 3 it cannot be translated. The consequence is considered a frameshift and varAA will be missing.

## CONSEQUENCE is 'frameshift' where translation is not possible
coding[mcols(coding)$CONSEQUENCE == "frameshift"]
## GRanges object with 2 ranges and 17 metadata columns:
##                       seqnames    ranges strand | paramRangeID            REF
##                          <Rle> <IRanges>  <Rle> |     <factor> <DNAStringSet>
##   22:50317001_G/GCACT    chr22  50317001      + |           NA              G
##   22:50317001_G/GCACT    chr22  50317001      + |           NA              G
##                                      ALT      QUAL      FILTER      varAllele
##                       <DNAStringSetList> <numeric> <character> <DNAStringSet>
##   22:50317001_G/GCACT              GCACT       233        PASS          GCACT
##   22:50317001_G/GCACT              GCACT       233        PASS          GCACT
##                          CDSLOC    PROTEINLOC   QUERYID        TXID
##                       <IRanges> <IntegerList> <integer> <character>
##   22:50317001_G/GCACT       808           270       359       74357
##   22:50317001_G/GCACT       628           210       359       74358
##                               CDSID      GENEID CONSEQUENCE       REFCODON
##                       <IntegerList> <character>    <factor> <DNAStringSet>
##   22:50317001_G/GCACT        216303       79174  frameshift            GCC
##   22:50317001_G/GCACT        216303       79174  frameshift            GCC
##                             VARCODON         REFAA         VARAA
##                       <DNAStringSet> <AAStringSet> <AAStringSet>
##   22:50317001_G/GCACT        GCACTCC                            
##   22:50317001_G/GCACT        GCACTCC                            
##   -------
##   seqinfo: 1 sequence from hg19 genome; no seqlengths

5 SIFT and PolyPhen Databases

From predictCoding we identified the amino acid coding changes for the non-synonymous variants. For this subset we can retrieve predictions of how damaging these coding changes may be. SIFT (Sorting Intolerant From Tolerant) and PolyPhen (Polymorphism Phenotyping) are methods that predict the impact of amino acid substitution on a human protein. The SIFT method uses sequence homology and the physical properties of amino acids to make predictions about protein function. PolyPhen uses sequence-based features and structural information characterizing the substitution to make predictions about the structure and function of the protein.

Collated predictions for specific dbSNP builds are available as downloads from the SIFT and PolyPhen web sites. These results have been packaged into SIFT.Hsapiens.dbSNP132 and PolyPhen.Hsapiens.dbSNP131 and are designed to be searched by rsid. Variants that are in dbSNP can be searched with these database packages. When working with novel variants, SIFT and PolyPhen must be called directly. See references for home pages.

Identify the non-synonymous variants and obtain the rsids.

nms <- names(coding) 
idx <- mcols(coding)$CONSEQUENCE == "nonsynonymous"
nonsyn <- coding[idx]
names(nonsyn) <- nms[idx]
rsids <- unique(names(nonsyn)[grep("rs", names(nonsyn), fixed=TRUE)])

Detailed descriptions of the database columns can be found with ?SIFTDbColumns and ?PolyPhenDbColumns. Variants in these databases often contain more than one row per variant. The variant may have been reported by multiple sources and therefore the source will differ as well as some of the other variables.

It is important to keep in mind the pre-computed predictions in the SIFT and PolyPhen packages are based on specific gene models. SIFT is based on Ensembl and PolyPhen on UCSC Known Gene. The TxDb we used to identify the coding snps was based on UCSC Known Gene so we will use PolyPhen for predictions. PolyPhen provides predictions using two different training datasets and has considerable information about 3D protein structure. See ?PolyPhenDbColumns or the PolyPhen web site listed in the references for more details.

Query the PolyPhen database,

library(PolyPhen.Hsapiens.dbSNP131)
pp <- select(PolyPhen.Hsapiens.dbSNP131, keys=rsids,
          cols=c("TRAININGSET", "PREDICTION", "PPH2PROB"))
head(pp[!is.na(pp$PREDICTION), ]) 
##          RSID TRAININGSET     OSNPID     OACC OPOS OAA1 OAA2      SNPID
## 13  rs8139422      humdiv  rs8139422 Q6UXH1-5  182    D    E  rs8139422
## 14  rs8139422      humvar  rs8139422     <NA> <NA> <NA> <NA>  rs8139422
## 15 rs74510325      humdiv rs74510325 Q6UXH1-5  189    R    G rs74510325
## 16 rs74510325      humvar rs74510325     <NA> <NA> <NA> <NA> rs74510325
## 21 rs73891177      humdiv rs73891177 Q6UXH1-5  207    P    A rs73891177
## 22 rs73891177      humvar rs73891177     <NA> <NA> <NA> <NA> rs73891177
##         ACC POS AA1 AA2  NT1  NT2        PREDICTION   BASEDON EFFECT PPH2CLASS
## 13 Q6UXH1-5 182   D   E    T    A possibly damaging alignment   <NA>   neutral
## 14 Q6UXH1-5 182   D   E <NA> <NA> possibly damaging      <NA>   <NA>      <NA>
## 15 Q6UXH1-5 189   R   G    C    G possibly damaging alignment   <NA>   neutral
## 16 Q6UXH1-5 189   R   G <NA> <NA> possibly damaging      <NA>   <NA>      <NA>
## 21 Q6UXH1-5 207   P   A    C    G            benign alignment   <NA>   neutral
## 22 Q6UXH1-5 207   P   A <NA> <NA>            benign      <NA>   <NA>      <NA>
##    PPH2PROB PPH2FPR PPH2TPR PPH2FDR SITE REGION PHAT DSCORE SCORE1 SCORE2 NOBS
## 13    0.228   0.156   0.892   0.258 <NA>   <NA> <NA>  0.951  1.382  0.431   37
## 14    0.249   0.341   0.874    <NA> <NA>   <NA> <NA>   <NA>   <NA>   <NA> <NA>
## 15    0.475   0.131   0.858   0.233 <NA>   <NA> <NA>  1.198  1.338   0.14   36
## 16    0.335   0.311   0.851    <NA> <NA>   <NA> <NA>   <NA>   <NA>   <NA> <NA>
## 21    0.001    0.86   0.994    0.61 <NA>   <NA> <NA> -0.225  -0.45 -0.225    1
## 22    0.005   0.701   0.981    <NA> <NA>   <NA> <NA>   <NA>   <NA>   <NA> <NA>
##    NSTRUCT NFILT PDBID PDBPOS PDBCH IDENT LENGTH NORMACC SECSTR MAPREG DVOL
## 13       0  <NA>  <NA>   <NA>  <NA>  <NA>   <NA>    <NA>   <NA>   <NA> <NA>
## 14    <NA>  <NA>  <NA>   <NA>  <NA>  <NA>   <NA>    <NA>   <NA>   <NA> <NA>
## 15       0  <NA>  <NA>   <NA>  <NA>  <NA>   <NA>    <NA>   <NA>   <NA> <NA>
## 16    <NA>  <NA>  <NA>   <NA>  <NA>  <NA>   <NA>    <NA>   <NA>   <NA> <NA>
## 21       0  <NA>  <NA>   <NA>  <NA>  <NA>   <NA>    <NA>   <NA>   <NA> <NA>
## 22    <NA>  <NA>  <NA>   <NA>  <NA>  <NA>   <NA>    <NA>   <NA>   <NA> <NA>
##    DPROP BFACT HBONDS AVENHET MINDHET AVENINT MINDINT AVENSIT MINDSIT TRANSV
## 13  <NA>  <NA>   <NA>    <NA>    <NA>    <NA>    <NA>    <NA>    <NA>      1
## 14  <NA>  <NA>   <NA>    <NA>    <NA>    <NA>    <NA>    <NA>    <NA>   <NA>
## 15  <NA>  <NA>   <NA>    <NA>    <NA>    <NA>    <NA>    <NA>    <NA>      1
## 16  <NA>  <NA>   <NA>    <NA>    <NA>    <NA>    <NA>    <NA>    <NA>   <NA>
## 21  <NA>  <NA>   <NA>    <NA>    <NA>    <NA>    <NA>    <NA>    <NA>      1
## 22  <NA>  <NA>   <NA>    <NA>    <NA>    <NA>    <NA>    <NA>    <NA>   <NA>
##    CODPOS  CPG MINDJNC PFAMHIT IDPMAX IDPSNP IDQMIN          COMMENTS
## 13      2    0    <NA>    <NA> 18.261 18.261 48.507 chr22:50315363_CA
## 14   <NA> <NA>    <NA>    <NA>   <NA>   <NA>   <NA> chr22:50315363_CA
## 15      0    1    <NA>    <NA> 19.252 19.252 63.682 chr22:50315382_CG
## 16   <NA> <NA>    <NA>    <NA>   <NA>   <NA>   <NA> chr22:50315382_CG
## 21      0    0    <NA>    <NA>  1.919   <NA> 60.697 chr22:50315971_CG
## 22   <NA> <NA>    <NA>    <NA>   <NA>   <NA>   <NA> chr22:50315971_CG

6 Other operations

6.1 Create a SnpMatrix

The ‘GT’ element in the FORMAT field of the VCF represents the genotype. These data can be converted into a SnpMatrix object which can then be used with the functions offered in snpStats and other packages making use of the SnpMatrix class.

The genotypeToSnpMatrix function converts the genotype calls in geno to a SnpMatrix. No dbSNP package is used in this computation. The return value is a named list where ‘genotypes’ is a SnpMatrix and ‘map’ is a DataFrame with SNP names and alleles at each loci. The ignore column in ‘map’ indicates which variants were set to NA (missing) because they met one or more of the following criteria,

  • variants with >1 ALT allele are set to NA
  • only single nucleotide variants are included; others are set to NA
  • only diploid calls are included; others are set to NA

See ?genotypeToSnpMatrix for more details.

res <- genotypeToSnpMatrix(vcf) 
res
## $genotypes
## A SnpMatrix with  5 rows and  10376 columns
## Row names:  HG00096 ... HG00101 
## Col names:  rs7410291 ... rs114526001 
## 
## $map
## DataFrame with 10376 rows and 4 columns
##         snp.names       allele.1           allele.2    ignore
##       <character> <DNAStringSet> <DNAStringSetList> <logical>
## 1       rs7410291              A                  G     FALSE
## 2     rs147922003              C                  T     FALSE
## 3     rs114143073              G                  A     FALSE
## 4     rs141778433              C                  T     FALSE
## 5     rs182170314              C                  T     FALSE
## ...           ...            ...                ...       ...
## 10372 rs187302552              A                  G     FALSE
## 10373   rs9628178              A                  G     FALSE
## 10374   rs5770892              A                  G     FALSE
## 10375 rs144055359              G                  A     FALSE
## 10376 rs114526001              G                  C     FALSE

In the map DataFrame, allele.1 represents the reference allele and allele.2 is the alternate allele.

allele2 <- res$map[["allele.2"]]
## number of alternate alleles per variant
unique(elementNROWS(allele2))
## [1] 1

In addition to the called genotypes, genotype likelihoods or probabilities can also be converted to a SnpMatrix, using the snpStats encoding of posterior probabilities as byte values. To use the values in the ‘GL’ or ‘GP’ FORMAT field instead of the called genotypes, use the uncertain=TRUE option in genotypeToSnpMatrix.

fl.gl <- system.file("extdata", "gl_chr1.vcf", package="VariantAnnotation")
vcf.gl <- readVcf(fl.gl, "hg19")
geno(vcf.gl)
## List of length 3
## names(3): GT DS GL
## Convert the "GL" FORMAT field to a SnpMatrix
res <- genotypeToSnpMatrix(vcf.gl, uncertain=TRUE)
res
## $genotypes
## A SnpMatrix with  85 rows and  9 columns
## Row names:  NA06984 ... NA12890 
## Col names:  rs58108140 ... rs200430748 
## 
## $map
## DataFrame with 9 rows and 4 columns
##     snp.names       allele.1           allele.2    ignore
##   <character> <DNAStringSet> <DNAStringSetList> <logical>
## 1  rs58108140              G                  A     FALSE
## 2 rs189107123              C                         TRUE
## 3 rs180734498              C                  T     FALSE
## 4 rs144762171              G                         TRUE
## 5 rs201747181             TC                         TRUE
## 6 rs151276478              T                         TRUE
## 7 rs140337953              G                  T     FALSE
## 8 rs199681827              C                         TRUE
## 9 rs200430748              G                         TRUE
t(as(res$genotype, "character"))[c(1,3,7), 1:5]
##             NA06984     NA06986     NA06989     NA06994     NA07000    
## rs58108140  "Uncertain" "Uncertain" "A/B"       "Uncertain" "Uncertain"
## rs180734498 "Uncertain" "Uncertain" "Uncertain" "Uncertain" "Uncertain"
## rs140337953 "Uncertain" "Uncertain" "Uncertain" "Uncertain" "Uncertain"
## Compare to a SnpMatrix created from the "GT" field
res.gt <- genotypeToSnpMatrix(vcf.gl, uncertain=FALSE)
t(as(res.gt$genotype, "character"))[c(1,3,7), 1:5]
##             NA06984 NA06986 NA06989 NA06994 NA07000
## rs58108140  "A/B"   "A/B"   "A/B"   "A/A"   "A/A"  
## rs180734498 "A/B"   "A/A"   "A/A"   "A/A"   "A/B"  
## rs140337953 "B/B"   "B/B"   "A/B"   "B/B"   "A/B"
## What are the original likelihoods for rs58108140?
geno(vcf.gl)$GL["rs58108140", 1:5]
## $NA06984
## [1] -4.70 -0.58 -0.13
## 
## $NA06986
## [1] -1.15 -0.10 -0.84
## 
## $NA06989
## [1] -2.05  0.00 -3.27
## 
## $NA06994
## [1] -0.48 -0.48 -0.48
## 
## $NA07000
## [1] -0.28 -0.44 -0.96

For variant rs58108140 in sample NA06989, the "A/B" genotype is much more likely than the others, so the SnpMatrix object displays the called genotype.

6.2 Write out VCF files

A VCF file can be written out from data stored in a VCF class.

fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation")
out1.vcf <- tempfile()
out2.vcf <- tempfile()
in1 <- readVcf(fl, "hg19")
writeVcf(in1, out1.vcf)
in2 <- readVcf(out1.vcf, "hg19")
writeVcf(in2, out2.vcf)
in3 <- readVcf(out2.vcf, "hg19")
identical(rowRanges(in1), rowRanges(in3))
## [1] TRUE
identical(geno(in1), geno(in2))
## [1] TRUE

7 Performance

Targeted queries can greatly improve the speed of data input. When all data from the file are needed define a yieldSize in the TabixFile to iterate through the file in chunks.

readVcf(TabixFile(fl, yieldSize=10000))

readVcf can be used with a to select any combination of INFO and GENO fields, samples or genomic positions.

readVcf(TabixFile(fl), param=ScanVcfParam(info='DP', geno='GT'))

While readvcf offers the flexibility to define combinations of INFO, GENO and samples in the ScanVcfParam, sometimes only a single field is needed. In this case the lightweight read functions (readGT, readInfo and readGeno) can be used. These functions return the single field as a matrix instead of a VCF object.

readGT(fl)

The table below highlights the speed differences of targeted queries vs reading in all data. The test file is from 1000 Genomes and has 494328 variants, 1092 samples, 22 INFO, and 3 GENO fields and is located at http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/release/20101123/. yieldSize is used to define chunks of 100, 1000, 10000 and 100000 variants. For each chunk size three function calls are compared: readGT reading only GT, readVcf reading both GT and ALT and finally readVcf reading in all the data.

library(microbenchmark)
fl <- "ALL.chr22.phase1_release_v3.20101123.snps_indels_svs.genotypes.vcf.gz"
ys <- c(100, 1000, 10000, 100000)

## readGT() input only 'GT':
fun <- function(fl, yieldSize) readGT(TabixFile(fl, yieldSize))
lapply(ys, function(i) microbenchmark(fun(fl, i), times=5)

## readVcf() input only 'GT' and 'ALT':
fun <- function(fl, yieldSize, param) 
           readVcf(TabixFile(fl, yieldSize), "hg19", param=param)
param <- ScanVcfParam(info=NA, geno="GT", fixed="ALT")
lapply(ys, function(i) microbenchmark(fun(fl, i, param), times=5)

## readVcf() input all variables:
fun <- function(fl, yieldSize) readVcf(TabixFile(fl, yieldSize), "hg19")
lapply(ys, function(i) microbenchmark(fun(fl, i), times=5))

Table 2: Targeted queries (time in seconds)
n records readGT readVcf (GT and ALT) readVcf (all)
100 0.082 0.128 0.501
1000 0.609 0.508 5.878
10000 5.972 6.164 68.378
100000 78.593 81.156 693.654

8 References

Appendix

Wang K, Li M, Hakonarson H, (2010), ANNOVAR: functional annotation of genetic variants from high-throughput sequencing data. Nucleic Acids Research, Vol 38, No. 16, e164.

McLaren W, Pritchard B, RiosD, et. al., (2010), Deriving the consequences of genomic variants with the Ensembl API and SNP Effect Predictor. Bioinformatics, Vol. 26, No. 16, 2069-2070.

SIFT home page: http://sift.bii.a-star.edu.sg/

PolyPhen home page: http://genetics.bwh.harvard.edu/pph2/

A Session Information

## 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] stats4    stats     graphics  grDevices utils     datasets  methods  
## [8] base     
## 
## other attached packages:
##  [1] snpStats_1.54.0                         
##  [2] Matrix_1.7-0                            
##  [3] survival_3.6-4                          
##  [4] PolyPhen.Hsapiens.dbSNP131_1.0.2        
##  [5] RSQLite_2.3.6                           
##  [6] ggplot2_3.5.1                           
##  [7] SNPlocs.Hsapiens.dbSNP144.GRCh37_0.99.20
##  [8] TxDb.Hsapiens.UCSC.hg19.knownGene_3.2.2 
##  [9] GenomicFeatures_1.56.0                  
## [10] AnnotationDbi_1.66.0                    
## [11] BSgenome.Hsapiens.UCSC.hg19_1.4.3       
## [12] BSgenome_1.72.0                         
## [13] BiocIO_1.14.0                           
## [14] rtracklayer_1.64.0                      
## [15] AnnotationHub_3.12.0                    
## [16] BiocFileCache_2.12.0                    
## [17] dbplyr_2.5.0                            
## [18] rjsoncons_1.3.0                         
## [19] httr_1.4.7                              
## [20] jsonlite_1.8.8                          
## [21] VariantAnnotation_1.50.0                
## [22] Rsamtools_2.20.0                        
## [23] Biostrings_2.72.0                       
## [24] XVector_0.44.0                          
## [25] SummarizedExperiment_1.34.0             
## [26] Biobase_2.64.0                          
## [27] GenomicRanges_1.56.0                    
## [28] GenomeInfoDb_1.40.0                     
## [29] IRanges_2.38.0                          
## [30] S4Vectors_0.42.0                        
## [31] MatrixGenerics_1.16.0                   
## [32] matrixStats_1.3.0                       
## [33] BiocGenerics_0.50.0                     
## [34] BiocStyle_2.32.0                        
## 
## loaded via a namespace (and not attached):
##  [1] DBI_1.2.2                bitops_1.0-7             rlang_1.1.3             
##  [4] magrittr_2.0.3           compiler_4.4.0           png_0.1-8               
##  [7] vctrs_0.6.5              pkgconfig_2.0.3          crayon_1.5.2            
## [10] fastmap_1.1.1            magick_2.8.3             labeling_0.4.3          
## [13] utf8_1.2.4               rmarkdown_2.26           UCSC.utils_1.0.0        
## [16] tinytex_0.50             purrr_1.0.2              bit_4.0.5               
## [19] xfun_0.43                zlibbioc_1.50.0          cachem_1.0.8            
## [22] blob_1.2.4               highr_0.10               DelayedArray_0.30.0     
## [25] BiocParallel_1.38.0      parallel_4.4.0           R6_2.5.1                
## [28] bslib_0.7.0              jquerylib_0.1.4          Rcpp_1.0.12             
## [31] bookdown_0.39            knitr_1.46               splines_4.4.0           
## [34] tidyselect_1.2.1         abind_1.4-5              yaml_2.3.8              
## [37] codetools_0.2-20         curl_5.2.1               lattice_0.22-6          
## [40] tibble_3.2.1             withr_3.0.0              KEGGREST_1.44.0         
## [43] evaluate_0.23            pillar_1.9.0             BiocManager_1.30.22     
## [46] filelock_1.0.3           generics_0.1.3           RCurl_1.98-1.14         
## [49] BiocVersion_3.19.1       munsell_0.5.1            scales_1.3.0            
## [52] glue_1.7.0               tools_4.4.0              GenomicAlignments_1.40.0
## [55] XML_3.99-0.16.1          grid_4.4.0               colorspace_2.1-0        
## [58] GenomeInfoDbData_1.2.12  restfulr_0.0.15          cli_3.6.2               
## [61] rappdirs_0.3.3           fansi_1.0.6              S4Arrays_1.4.0          
## [64] dplyr_1.1.4              gtable_0.3.5             sass_0.4.9              
## [67] digest_0.6.35            SparseArray_1.4.0        rjson_0.2.21            
## [70] farver_2.1.1             memoise_2.0.1            htmltools_0.5.8.1       
## [73] lifecycle_1.0.4          mime_0.12                bit64_4.0.5
VariantAnnotation/inst/doc/VariantAnnotation.R0000644000175100017510000001747514614361053022556 0ustar00biocbuildbiocbuild## ----readVcF,message=FALSE---------------------------------------------------- library(VariantAnnotation) fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") vcf ## ----readVcf_showheader------------------------------------------------------- header(vcf) ## ----headeraccessors---------------------------------------------------------- samples(header(vcf)) geno(header(vcf)) ## ----readVcf_rowRanges-------------------------------------------------------- head(rowRanges(vcf), 3) ## ----readVcf_fixed------------------------------------------------------------ ref(vcf)[1:5] qual(vcf)[1:5] ## ----readVcf_ALT-------------------------------------------------------------- alt(vcf)[1:5] ## ----geno_hdr----------------------------------------------------------------- geno(vcf) sapply(geno(vcf), class) ## ----explore_geno------------------------------------------------------------- geno(header(vcf))["DS",] ## ----dim_geno----------------------------------------------------------------- DS <-geno(vcf)$DS dim(DS) DS[1:3,] ## ----fivenum------------------------------------------------------------------ fivenum(DS) ## ----DS_zero------------------------------------------------------------------ length(which(DS==0))/length(DS) ## ----DS_hist, fig=TRUE-------------------------------------------------------- hist(DS[DS != 0], breaks=seq(0, 2, by=0.05), main="DS non-zero values", xlab="DS") ## ----info--------------------------------------------------------------------- info(vcf)[1:4, 1:5] ## ----examine_dbSNP, message=FALSE, warning=FALSE------------------------------ library(SNPlocs.Hsapiens.dbSNP144.GRCh37) vcf_rsids <- names(rowRanges(vcf)) chr22snps <- snpsBySeqname(SNPlocs.Hsapiens.dbSNP144.GRCh37, "22") chr22_rsids <- mcols(chr22snps)$RefSNP_id in_dbSNP <- vcf_rsids %in% chr22_rsids table(in_dbSNP) ## ----header_info-------------------------------------------------------------- info(header(vcf))[c("VT", "LDAF", "RSQ"),] ## ----examine_quality---------------------------------------------------------- metrics <- data.frame(QUAL=qual(vcf), in_dbSNP=in_dbSNP, VT=info(vcf)$VT, LDAF=info(vcf)$LDAF, RSQ=info(vcf)$RSQ) ## ----examine_ggplot2, message=FALSE, warning=FALSE, fig=TRUE------------------ library(ggplot2) ggplot(metrics, aes(x=RSQ, fill=in_dbSNP)) + geom_density(alpha=0.5) + scale_x_continuous(name="MaCH / Thunder Imputation Quality") + scale_y_continuous(name="Density") + theme(legend.position="top") ## ----subset_ranges------------------------------------------------------------ rng <- GRanges(seqnames="22", ranges=IRanges( start=c(50301422, 50989541), end=c(50312106, 51001328), names=c("gene_79087", "gene_644186"))) ## ----subset_TabixFile--------------------------------------------------------- tab <- TabixFile(fl) vcf_rng <- readVcf(tab, "hg19", param=rng) ## ----------------------------------------------------------------------------- head(rowRanges(vcf_rng), 3) ## ----subset_scanVcfHeader----------------------------------------------------- hdr <- scanVcfHeader(fl) ## e.g., INFO and GENO fields head(info(hdr), 3) head(geno(hdr), 3) ## ----subset_ScanVcfParam------------------------------------------------------ ## Return all 'fixed' fields, "LAF" from 'info' and "GT" from 'geno' svp <- ScanVcfParam(info="LDAF", geno="GT") vcf1 <- readVcf(fl, "hg19", svp) names(geno(vcf1)) ## ----subset_ScanVcfParam_new-------------------------------------------------- svp_all <- ScanVcfParam(info="LDAF", geno="GT", which=rng) svp_all ## ----locate_rename_seqlevels, message=FALSE, warning=FALSE-------------------- library(TxDb.Hsapiens.UCSC.hg19.knownGene) txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene seqlevels(vcf) <- "chr22" rd <- rowRanges(vcf) loc <- locateVariants(rd, txdb, CodingVariants()) head(loc, 3) ## ----AllVariants, eval=FALSE-------------------------------------------------- # allvar <- locateVariants(rd, txdb, AllVariants()) ## ----locate_gene_centric------------------------------------------------------ ## Did any coding variants match more than one gene? splt <- split(mcols(loc)$GENEID, mcols(loc)$QUERYID) table(sapply(splt, function(x) length(unique(x)) > 1)) ## Summarize the number of coding variants by gene ID. splt <- split(mcols(loc)$QUERYID, mcols(loc)$GENEID) head(sapply(splt, function(x) length(unique(x))), 3) ## ----predictCoding, warning=FALSE--------------------------------------------- library(BSgenome.Hsapiens.UCSC.hg19) coding <- predictCoding(vcf, txdb, seqSource=Hsapiens) coding[5:7] ## ----predictCoding_frameshift------------------------------------------------- ## CONSEQUENCE is 'frameshift' where translation is not possible coding[mcols(coding)$CONSEQUENCE == "frameshift"] ## ----nonsynonymous------------------------------------------------------------ nms <- names(coding) idx <- mcols(coding)$CONSEQUENCE == "nonsynonymous" nonsyn <- coding[idx] names(nonsyn) <- nms[idx] rsids <- unique(names(nonsyn)[grep("rs", names(nonsyn), fixed=TRUE)]) ## ----polyphen, message=FALSE, warning=FALSE----------------------------------- library(PolyPhen.Hsapiens.dbSNP131) pp <- select(PolyPhen.Hsapiens.dbSNP131, keys=rsids, cols=c("TRAININGSET", "PREDICTION", "PPH2PROB")) head(pp[!is.na(pp$PREDICTION), ]) ## ----snpMatrix, message=FALSE------------------------------------------------- res <- genotypeToSnpMatrix(vcf) res ## ----snpMatrix_ALT------------------------------------------------------------ allele2 <- res$map[["allele.2"]] ## number of alternate alleles per variant unique(elementNROWS(allele2)) ## ----message=FALSE------------------------------------------------------------ fl.gl <- system.file("extdata", "gl_chr1.vcf", package="VariantAnnotation") vcf.gl <- readVcf(fl.gl, "hg19") geno(vcf.gl) ## Convert the "GL" FORMAT field to a SnpMatrix res <- genotypeToSnpMatrix(vcf.gl, uncertain=TRUE) res t(as(res$genotype, "character"))[c(1,3,7), 1:5] ## Compare to a SnpMatrix created from the "GT" field res.gt <- genotypeToSnpMatrix(vcf.gl, uncertain=FALSE) t(as(res.gt$genotype, "character"))[c(1,3,7), 1:5] ## What are the original likelihoods for rs58108140? geno(vcf.gl)$GL["rs58108140", 1:5] ## ----writeVcf, message=FALSE, warning=FALSE----------------------------------- fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") out1.vcf <- tempfile() out2.vcf <- tempfile() in1 <- readVcf(fl, "hg19") writeVcf(in1, out1.vcf) in2 <- readVcf(out1.vcf, "hg19") writeVcf(in2, out2.vcf) in3 <- readVcf(out2.vcf, "hg19") identical(rowRanges(in1), rowRanges(in3)) identical(geno(in1), geno(in2)) ## ----eval=FALSE--------------------------------------------------------------- # readVcf(TabixFile(fl, yieldSize=10000)) ## ----eval=FALSE--------------------------------------------------------------- # readVcf(TabixFile(fl), param=ScanVcfParam(info='DP', geno='GT')) ## ----eval=FALSE--------------------------------------------------------------- # readGT(fl) ## ----eval=FALSE--------------------------------------------------------------- # library(microbenchmark) # fl <- "ALL.chr22.phase1_release_v3.20101123.snps_indels_svs.genotypes.vcf.gz" # ys <- c(100, 1000, 10000, 100000) # # ## readGT() input only 'GT': # fun <- function(fl, yieldSize) readGT(TabixFile(fl, yieldSize)) # lapply(ys, function(i) microbenchmark(fun(fl, i), times=5) # # ## readVcf() input only 'GT' and 'ALT': # fun <- function(fl, yieldSize, param) # readVcf(TabixFile(fl, yieldSize), "hg19", param=param) # param <- ScanVcfParam(info=NA, geno="GT", fixed="ALT") # lapply(ys, function(i) microbenchmark(fun(fl, i, param), times=5) # # ## readVcf() input all variables: # fun <- function(fl, yieldSize) readVcf(TabixFile(fl, yieldSize), "hg19") # lapply(ys, function(i) microbenchmark(fun(fl, i), times=5)) ## ----sessionInfo, echo=FALSE-------------------------------------------------- sessionInfo() VariantAnnotation/inst/doc/VariantAnnotation.Rmd0000644000175100017510000004753314614305321023071 0ustar00biocbuildbiocbuild--- title: "1. Introduction to VariantAnnotation" author: "Valerie Obenchain" date: "`r format(Sys.time(), '%B %d, %Y')`" vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{1. Introduction to VariantAnnotation} %\VignetteEncoding{UTF-8} output: BiocStyle::html_document: number_sections: yes toc: yes toc_depth: 4 --- # Introduction This vignette outlines a work flow for annotating and filtering genetic variants using the `r Biocpkg("VariantAnnotation")` package. Sample data are in VariantCall Format (VCF) and are a subset of chromosome 22 from [1000 Genomes](http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/release/20110521/). VCF text files contain meta-information lines, a header line with column names, data lines with information about a position in the genome, and optional genotype information on samples for each position. Samtools organisation and repositories describes the [VCF format](http://samtools.github.io/hts-specs/VCFv4.4.pdf) in detail. Data are read in from a VCF file and variants identified according to region such as `coding`, `intron`, `intergenic`, `spliceSite` etc. Amino acid coding changes are computed for the non-synonymous variants and SIFT and PolyPhen databases provide predictions of how severly the coding changes affect protein function. # Variant Call Format (VCF) files ## Data import and exploration Data are parsed into a `VCF` object with `readVcf`. ```{r readVcF,message=FALSE} library(VariantAnnotation) fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") vcf ``` ### Header information Header information can be extracted from the VCF with `header()`. We see there are 5 samples, 1 piece of meta information, 22 info fields and 3 geno fields. ```{r readVcf_showheader} header(vcf) ``` Data can be further extracted using the named accessors. ```{r headeraccessors} samples(header(vcf)) geno(header(vcf)) ``` ### Genomic positions `rowRanges` contains information from the CHROM, POS, and ID fields of the VCF file, represented as a `GRanges`. The `paramRangeID` column is meaningful when reading subsets of data and is discussed further below. ```{r readVcf_rowRanges} head(rowRanges(vcf), 3) ``` Individual fields can be pulled out with named accessors. Here we see `REF` is stored as a `DNAStringSet` and `qual` is a numeric vector. ```{r readVcf_fixed} ref(vcf)[1:5] qual(vcf)[1:5] ``` `ALT` is a `DNAStringSetList` (allows for multiple alternate alleles per variant) or a `DNAStringSet`. When structural variants are present it will be a `CharacterList`. ```{r readVcf_ALT} alt(vcf)[1:5] ``` ### Genotype data Genotype data described in the `FORMAT` fields are parsed into the geno slot. The data are unique to each sample and each sample may have multiple values variable. Because of this, the data are parsed into matrices or arrays where the rows represent the variants and the columns the samples. Multidimentional arrays indicate multiple values per sample. In this file all variables are matrices. ```{r geno_hdr} geno(vcf) sapply(geno(vcf), class) ``` Let's take a closer look at the genotype dosage (DS) variable. The header provides the variable definition and type. ```{r explore_geno} geno(header(vcf))["DS",] ``` These data are stored as a 10376 x 5 matrix. Each of the five samples (columns) has a single value per variant location (row). ```{r dim_geno} DS <-geno(vcf)$DS dim(DS) DS[1:3,] ``` DS is also known as 'posterior mean genotypes' and range in value from [0, 2]. To get a sense of variable distribution, we compute a five number summary of the minimum, lower-hinge (first quartile), median, upper-hinge (third quartile) and maximum. ```{r fivenum} fivenum(DS) ``` The majority of these values (86%) are zero. ```{r DS_zero} length(which(DS==0))/length(DS) ``` View the distribution of the non-zero values. ```{r DS_hist, fig=TRUE} hist(DS[DS != 0], breaks=seq(0, 2, by=0.05), main="DS non-zero values", xlab="DS") ``` ### Info data In contrast to the genotype data, the info data are unique to the variant and the same across samples. All info variables are represented in a single `DataFrame`. ```{r info} info(vcf)[1:4, 1:5] ``` We will use the info data to compare quality measures between novel (i.e., not in dbSNP) and known (i.e., in dbSNP) variants and the variant type present in the file. Variants with membership in dbSNP can be identified by using the appropriate SNPlocs package for the hg19 genome (GRCh37). ```{r examine_dbSNP, message=FALSE, warning=FALSE} library(SNPlocs.Hsapiens.dbSNP144.GRCh37) vcf_rsids <- names(rowRanges(vcf)) chr22snps <- snpsBySeqname(SNPlocs.Hsapiens.dbSNP144.GRCh37, "22") chr22_rsids <- mcols(chr22snps)$RefSNP_id in_dbSNP <- vcf_rsids %in% chr22_rsids table(in_dbSNP) ``` Info variables of interest are 'VT', 'LDAF' and 'RSQ'. The header offers more details on these variables. ```{r header_info} info(header(vcf))[c("VT", "LDAF", "RSQ"),] ``` Create a data frame of quality measures of interest ... ```{r examine_quality} metrics <- data.frame(QUAL=qual(vcf), in_dbSNP=in_dbSNP, VT=info(vcf)$VT, LDAF=info(vcf)$LDAF, RSQ=info(vcf)$RSQ) ``` and visualize the distribution of qualities using `r CRANpkg("ggplot2")`. For instance, genotype imputation quality is higher for the known variants in dbSNP. ```{r examine_ggplot2, message=FALSE, warning=FALSE, fig=TRUE} library(ggplot2) ggplot(metrics, aes(x=RSQ, fill=in_dbSNP)) + geom_density(alpha=0.5) + scale_x_continuous(name="MaCH / Thunder Imputation Quality") + scale_y_continuous(name="Density") + theme(legend.position="top") ``` ## Import data subsets When working with large VCF files it may be more efficient to read in subsets of the data. This can be accomplished by selecting genomic coordinates (ranges) or by specific fields from the VCF file. ### Select genomic coordinates To read in a portion of chromosome 22, create a `GRanges` with the regions of interest. ```{r subset_ranges} rng <- GRanges(seqnames="22", ranges=IRanges( start=c(50301422, 50989541), end=c(50312106, 51001328), names=c("gene_79087", "gene_644186"))) ``` When ranges are specified, the VCF file must have an accompanying Tabix index file. See `indexTabix` for help creating an index. ```{r subset_TabixFile} tab <- TabixFile(fl) vcf_rng <- readVcf(tab, "hg19", param=rng) ``` The `paramRangesID` column distinguishes which records came from which param range. ```{r} head(rowRanges(vcf_rng), 3) ``` ### Select VCF fields Data import can also be defined by the `fixed`, `info` and `geno` fields. Fields available for import are described in the header information. To view the header before reading in the data, use `ScanVcfHeader`. ```{r subset_scanVcfHeader} hdr <- scanVcfHeader(fl) ## e.g., INFO and GENO fields head(info(hdr), 3) head(geno(hdr), 3) ``` To subset on "LDAF" and "GT" we specify them as `character` vectors in the `info` and `geno` arguments to `ScanVcfParam`. This creates a `ScanVcfParam` object which is used as the `param` argument to `readVcf`. ```{r subset_ScanVcfParam} ## Return all 'fixed' fields, "LAF" from 'info' and "GT" from 'geno' svp <- ScanVcfParam(info="LDAF", geno="GT") vcf1 <- readVcf(fl, "hg19", svp) names(geno(vcf1)) ``` To subset on both genomic coordinates and fields the `ScanVcfParam` object must contain both. ```{r subset_ScanVcfParam_new} svp_all <- ScanVcfParam(info="LDAF", geno="GT", which=rng) svp_all ``` # Locating variants in and around genes Variant location with respect to genes can be identified with the `locateVariants` function. Regions are specified in the `region` argument and can be one of the following constructors: CodingVariants, IntronVariants, FiveUTRVariants, ThreeUTRVariants, IntergenicVariants, SpliceSiteVariants or PromoterVariants. Location definitions are shown in Table \@ref(tab:table). | Location | Details | |------------|------------------------------------------------------------| | coding | falls *within* a coding region | | fiveUTR | falls *within* a 5' untranslated region | | threeUTR | falls *within* a 3' untranslated region | | intron | falls *within* an intron region | | intergenic | does not fall *within* a transcript associated with a gene | | spliceSite | overlaps any portion of the first 2 or last 2 | | promoter | falls *within* a promoter region of a transcript | : (\#tab:table) Variant locations For overlap methods to work properly the chromosome names (seqlevels) must be compatible in the objects being compared. The VCF data chromosome names are represented by number, i.e., '22', but the TxDb chromosome names are preceded with 'chr'. Seqlevels in the VCF can be modified with the `seqlevels` function. ```{r locate_rename_seqlevels, message=FALSE, warning=FALSE} library(TxDb.Hsapiens.UCSC.hg19.knownGene) txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene seqlevels(vcf) <- "chr22" rd <- rowRanges(vcf) loc <- locateVariants(rd, txdb, CodingVariants()) head(loc, 3) ``` Locate variants in all regions with the `AllVariants()` constructor, ```{r AllVariants, eval=FALSE} allvar <- locateVariants(rd, txdb, AllVariants()) ``` To answer gene-centric questions data can be summarized by gene reguardless of transcript. ```{r locate_gene_centric} ## Did any coding variants match more than one gene? splt <- split(mcols(loc)$GENEID, mcols(loc)$QUERYID) table(sapply(splt, function(x) length(unique(x)) > 1)) ## Summarize the number of coding variants by gene ID. splt <- split(mcols(loc)$QUERYID, mcols(loc)$GENEID) head(sapply(splt, function(x) length(unique(x))), 3) ``` # Amino acid coding changes `predictCoding` computes amino acid coding changes for non-synonymous variants. Only ranges in query that overlap with a coding region in the `subject` are considered. Reference sequences are retrieved from either a `BSgenome` or fasta file specified in `seqSource`. Variant sequences are constructed by substituting, inserting or deleting values in the `varAllele` column into the reference sequence. Amino acid codes are computed for the variant codon sequence when the length is a multiple of 3. The query argument to `predictCoding` can be a `GRanges` or `VCF`. When a `GRanges` is supplied the `varAllele` argument must be specified. In the case of a `VCF`, the alternate alleles are taken from `alt()` and the `varAllele` argument is not specified. The result is a modified `query` containing only variants that fall within coding regions. Each row represents a variant-transcript match so more than one row per original variant is possible. ```{r predictCoding, warning=FALSE} library(BSgenome.Hsapiens.UCSC.hg19) coding <- predictCoding(vcf, txdb, seqSource=Hsapiens) coding[5:7] ``` Using variant rs114264124 as an example, we see varAllele `A` has been substituted into the `refCodon` `CGG` to produce `varCodon` `CAG.` The `refCodon` is the sequence of codons necessary to make the variant allele substitution and therefore often includes more nucleotides than indicated in the range (i.e. the range is 50302962, 50302962, width of 1). Notice it is the second position in the `refCodon` that has been substituted. This position in the codon, the position of substitution, corresponds to genomic position 50302962. This genomic position maps to position 698 in coding region-based coordinates and to triplet 233 in the protein. This is a non-synonymous coding variant where the amino acid has changed from `R` (Arg) to `Q` (Gln). When the resulting `varCodon` is not a multiple of 3 it cannot be translated. The consequence is considered a `frameshift` and `varAA` will be missing. ```{r predictCoding_frameshift} ## CONSEQUENCE is 'frameshift' where translation is not possible coding[mcols(coding)$CONSEQUENCE == "frameshift"] ``` # SIFT and PolyPhen Databases From `predictCoding` we identified the amino acid coding changes for the non-synonymous variants. For this subset we can retrieve predictions of how damaging these coding changes may be. SIFT (Sorting Intolerant From Tolerant) and PolyPhen (Polymorphism Phenotyping) are methods that predict the impact of amino acid substitution on a human protein. The SIFT method uses sequence homology and the physical properties of amino acids to make predictions about protein function. PolyPhen uses sequence-based features and structural information characterizing the substitution to make predictions about the structure and function of the protein. Collated predictions for specific dbSNP builds are available as downloads from the SIFT and PolyPhen web sites. These results have been packaged into `r Biocpkg("SIFT.Hsapiens.dbSNP132")` and `r Biocpkg("PolyPhen.Hsapiens.dbSNP131")` and are designed to be searched by rsid. Variants that are in dbSNP can be searched with these database packages. When working with novel variants, SIFT and PolyPhen must be called directly. See references for home pages. Identify the non-synonymous variants and obtain the rsids. ```{r nonsynonymous} nms <- names(coding) idx <- mcols(coding)$CONSEQUENCE == "nonsynonymous" nonsyn <- coding[idx] names(nonsyn) <- nms[idx] rsids <- unique(names(nonsyn)[grep("rs", names(nonsyn), fixed=TRUE)]) ``` Detailed descriptions of the database columns can be found with `?SIFTDbColumns` and `?PolyPhenDbColumns`. Variants in these databases often contain more than one row per variant. The variant may have been reported by multiple sources and therefore the source will differ as well as some of the other variables. It is important to keep in mind the pre-computed predictions in the SIFT and PolyPhen packages are based on specific gene models. SIFT is based on Ensembl and PolyPhen on UCSC Known Gene. The `TxDb` we used to identify the coding snps was based on UCSC Known Gene so we will use PolyPhen for predictions. PolyPhen provides predictions using two different training datasets and has considerable information about 3D protein structure. See `?PolyPhenDbColumns` or the PolyPhen web site listed in the references for more details. Query the PolyPhen database, ```{r polyphen, message=FALSE, warning=FALSE} library(PolyPhen.Hsapiens.dbSNP131) pp <- select(PolyPhen.Hsapiens.dbSNP131, keys=rsids, cols=c("TRAININGSET", "PREDICTION", "PPH2PROB")) head(pp[!is.na(pp$PREDICTION), ]) ``` # Other operations ## Create a SnpMatrix The 'GT' element in the `FORMAT` field of the VCF represents the genotype. These data can be converted into a `SnpMatrix` object which can then be used with the functions offered in `r Biocpkg("snpStats")` and other packages making use of the `SnpMatrix` class. The `genotypeToSnpMatrix` function converts the genotype calls in `geno` to a `SnpMatrix`. No dbSNP package is used in this computation. The return value is a named list where 'genotypes' is a `SnpMatrix` and 'map' is a `DataFrame` with SNP names and alleles at each loci. The `ignore` column in 'map' indicates which variants were set to NA (missing) because they met one or more of the following criteria, - variants with >1 ALT allele are set to NA - only single nucleotide variants are included; others are set to NA - only diploid calls are included; others are set to NA See ?`genotypeToSnpMatrix` for more details. ```{r snpMatrix, message=FALSE} res <- genotypeToSnpMatrix(vcf) res ``` In the map DataFrame, allele.1 represents the reference allele and allele.2 is the alternate allele. ```{r snpMatrix_ALT} allele2 <- res$map[["allele.2"]] ## number of alternate alleles per variant unique(elementNROWS(allele2)) ``` In addition to the called genotypes, genotype likelihoods or probabilities can also be converted to a `SnpMatrix`, using the `r Biocpkg("snpStats")` encoding of posterior probabilities as byte values. To use the values in the 'GL' or 'GP' `FORMAT` field instead of the called genotypes, use the `uncertain=TRUE` option in `genotypeToSnpMatrix`. ```{r message=FALSE} fl.gl <- system.file("extdata", "gl_chr1.vcf", package="VariantAnnotation") vcf.gl <- readVcf(fl.gl, "hg19") geno(vcf.gl) ## Convert the "GL" FORMAT field to a SnpMatrix res <- genotypeToSnpMatrix(vcf.gl, uncertain=TRUE) res t(as(res$genotype, "character"))[c(1,3,7), 1:5] ## Compare to a SnpMatrix created from the "GT" field res.gt <- genotypeToSnpMatrix(vcf.gl, uncertain=FALSE) t(as(res.gt$genotype, "character"))[c(1,3,7), 1:5] ## What are the original likelihoods for rs58108140? geno(vcf.gl)$GL["rs58108140", 1:5] ``` For variant rs58108140 in sample NA06989, the \"A/B\" genotype is much more likely than the others, so the `SnpMatrix` object displays the called genotype. ## Write out VCF files A VCF file can be written out from data stored in a `VCF` class. ```{r writeVcf, message=FALSE, warning=FALSE} fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") out1.vcf <- tempfile() out2.vcf <- tempfile() in1 <- readVcf(fl, "hg19") writeVcf(in1, out1.vcf) in2 <- readVcf(out1.vcf, "hg19") writeVcf(in2, out2.vcf) in3 <- readVcf(out2.vcf, "hg19") identical(rowRanges(in1), rowRanges(in3)) identical(geno(in1), geno(in2)) ``` # Performance Targeted queries can greatly improve the speed of data input. When all data from the file are needed define a `yieldSize` in the `TabixFile` to iterate through the file in chunks. ```{r eval=FALSE} readVcf(TabixFile(fl, yieldSize=10000)) ``` `readVcf` can be used with a to select any combination of INFO and GENO fields, samples or genomic positions. ```{r eval=FALSE} readVcf(TabixFile(fl), param=ScanVcfParam(info='DP', geno='GT')) ``` While `readvcf` offers the flexibility to define combinations of INFO, GENO and samples in the `ScanVcfParam`, sometimes only a single field is needed. In this case the lightweight `read` functions (`readGT`, `readInfo` and `readGeno`) can be used. These functions return the single field as a matrix instead of a `VCF` object. ```{r eval=FALSE} readGT(fl) ``` The table below highlights the speed differences of targeted queries vs reading in all data. The test file is from 1000 Genomes and has 494328 variants, 1092 samples, 22 INFO, and 3 GENO fields and is located at http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/release/20101123/. `yieldSize` is used to define chunks of 100, 1000, 10000 and 100000 variants. For each chunk size three function calls are compared: `readGT` reading only GT, `readVcf` reading both `GT` and `ALT` and finally `readVcf` reading in all the data. ```{r eval=FALSE} library(microbenchmark) fl <- "ALL.chr22.phase1_release_v3.20101123.snps_indels_svs.genotypes.vcf.gz" ys <- c(100, 1000, 10000, 100000) ## readGT() input only 'GT': fun <- function(fl, yieldSize) readGT(TabixFile(fl, yieldSize)) lapply(ys, function(i) microbenchmark(fun(fl, i), times=5) ## readVcf() input only 'GT' and 'ALT': fun <- function(fl, yieldSize, param) readVcf(TabixFile(fl, yieldSize), "hg19", param=param) param <- ScanVcfParam(info=NA, geno="GT", fixed="ALT") lapply(ys, function(i) microbenchmark(fun(fl, i, param), times=5) ## readVcf() input all variables: fun <- function(fl, yieldSize) readVcf(TabixFile(fl, yieldSize), "hg19") lapply(ys, function(i) microbenchmark(fun(fl, i), times=5)) ``` n records readGT readVcf (GT and ALT) readVcf (all) ----------- -------- ---------------------- --------------- 100 0.082 0.128 0.501 1000 0.609 0.508 5.878 10000 5.972 6.164 68.378 100000 78.593 81.156 693.654 : (\#tab:performance) Targeted queries (time in seconds) # References Wang K, Li M, Hakonarson H, (2010), ANNOVAR: functional annotation of genetic variants from high-throughput sequencing data. Nucleic Acids Research, Vol 38, No. 16, e164. McLaren W, Pritchard B, RiosD, et. al., (2010), Deriving the consequences of genomic variants with the Ensembl API and SNP Effect Predictor. Bioinformatics, Vol. 26, No. 16, 2069-2070. SIFT home page: http://sift.bii.a-star.edu.sg/ PolyPhen home page: http://genetics.bwh.harvard.edu/pph2/ # Session Information ```{r sessionInfo, echo=FALSE} sessionInfo() ``` VariantAnnotation/inst/extdata/0000755000175100017510000000000014614305321017637 5ustar00biocbuildbiocbuildVariantAnnotation/inst/extdata/chr22.vcf.gz0000644000175100017510000211040014614305321021674 0ustar00biocbuildbiocbuildBC)]n\G}fEUr_E%gAK%0Ej(='{sGFڗRN_]\n]߼?}ɓ!_'/={|O<~}77n/ryrO۫7o߼tu{qƽ?{?>9ypv{s^O?]\^yws~仇g|z뿎=\:_N7no6w9ݎ^ӳ^78 X|n?oo8zw}%n+oءw}sqc^ {WX^ŧ;tv~%mo_=qx}~^:1!^϶W?sp~>o{___^v=t=7~}_޸Vx ί,>1w7?۫ͫ'sy;os_?g poo>t>67ɚYܕ?:ӍvoV}[WYE>kr?~WϏ>m/IkM O//o/٠u} w}B~vo~pO>?\\^_?N&|~忻?>|uzi\^:ttݸu^?L+};=Lwrӏk[g_5Bo;iv&ޱ\^\mqvy˿:9]qx9|un?+?6o8}3IfguN{?>p􁻫gOvvuEpSwow2?1v wϴ9%҃ョ~8~#F8bGKB]ytTG! 9J=z?N^xt|#-鑏brx&ܟ='ٽP`gÏ}O%߆ӷ=j\?b'9 g{W_6|C)5aKN2'cU(!} ;[!}z}f@g@ ˀ* (U OP Jh0GO S5"6[i-,]Z\L/] /Wk_^ʃR:D)v@. ^jxv"(,^Vk$ b8"X;ب6wfҼl{ 0 1$hܢ4^Sd Lj-6{Ϝb>\jY̶^Ә)ZҢht8 )OzuuVw@@)3 XnQnO4+SAη4)O_)LSi]3̓By[JM@i[?[10H y0H]t=S.WֻGOHB3)300 {NNd`eH[5>jI1C  3hVƐŝ+bNfS[Ҧ9*)>π&pipGcS|FARp?z\5#+k)q.|8 t Ye^ć1=G$D_6Lbx.H:TqBu2/stL'3}'Z{XRx-G7ݪz?8kTm^L Ɯsqȥ;k5VCmƗW4baW!AꨙNmPnz>0TZ,a"JbPLZJLuY%D<$V^d$'n8!'X, TY(6UxO,dVӐYfh鰊!e F] W,rL& VdD[E(Z_6u[0 sq3,GP JHWlQ4/9_XgpFKHoɂdgF~Ӽf"C3z5fM{QPR)%*`Eע&DW! v%E"iX_R̫grdoxE*A8:ԞeIӐc5)0 PސB%sF.x٬HFl4 "c,Pr(#|YLM'0#dd11V]ol7A1깵I<ŚSJ{:4 +p JS] %Wܢltl'iDeVGlˠUi(T\Aj$x)h݉4C.gic~^+3\DV'4K(3EF+ [/Oq}75?7NAz˫ 5ԏ.mܥ2:H.]دڈ!SIkm9Hj6ދ̤VֱBqbVMNךּgE =WB tCǗ2buPxޭ [zƹPG_a3Ud )l!%*]R(]ɞ]CqT:*fΡ_Ѵ^1|ekVA ٶM̸4., 5_Nd5bZY1qI=eܽ#NtLI$.,𲁁  "=c TiIڋ sNbzz3npfS16R)Ud:gr H.N.7S9pYq顔3]ڶYQ0Dqg,F*v)?6\m&wlz}=P DE3JFږYdN4#hM$M8 {", X-phD1 KSu܋sZ#<*ʉ,'Qiרx8W`[8`3-OH [|l-H@`r- s+ee֑c5vH ]N;F@LZ1kFFzwn`.{2vmUT#0Ts8eYY|f9eX}Ю:`l3ltkus Krh\FɣKG8,$&"py\SWv'R'WqL,+*l k&Z wR-'`Tzz5HsdbkƘ{92R*];/T;}!{r 2 /5&4:tg[`v(?c@`LDX²!s`Q4 N%42E`Y%״xh<ӯe2p? Vs6o>idø1{Զ BOYg0w]eKݢP6LHJMB,9Y{9 :0": G(¨mcJϖUqk]=%CG:mމLLVL, fpw^"L0P6ߑV'Q|rAx\ս+,mVEq܉uRcAWB̈́[誚xLT^mGAXH~CFO kD`BΜGIDu '\D+d}1LË]^ݍ5h6ܙߖ&mܚ۾ZFГ.:BFb0͝K>s)B T$aѢ YKΩϔ~;ymEwADR7TNILRńB7<]f3aIUgw#ZzO,pPZn2npW:fSmd,wq CVDW&Ubͩ O#n1n5"¿1w!dK)E9N_ϳċd (AVcyt3CY.s$#Jpk!Xɖ.h T˰bOaSRD?vM7t<;B.v A1鼊CN19fLNROtMv E-;'ԘWZu| -Z2t5_.f6+$8غ}kfH+7gI x)i B:95XZA\iXqlS!n5dMC*_)]*dӌ8Jvk &, k {>ӁӠ4Ju411ZLji-۞=isCA7 =2n(a'^G2Sc%\-DZ 0!qt_lb+#anS}):/'ġJ`JHUH'zBxgq|պn\teIA8tXٱKδBw(ЩLםKr$:`a^O p>4#%uq!hp6MnW!śk6N+T&Y؅1i#Fh%r7~?lSg}oa6Fs?/lUh)O(jG)wA9mKjծVyA hRrE9(gr{eRX]ő^cݷ[ T9(`Z__r( s-#yoҶ%]%p}xSܻ~Tܠ{c'SRJ r̲Vi.rs-\ews\=)+5~y;@ť@Rs!mahKLs%مMTb@&XJJȍ8eM5fRunzJ^9krVw8IY9/ɏ(@BSaNu)+!#1fp j&8U3=N^ܚ} 5;wՁ A/Jrv%Z-ih&AKnja+AGLwJYIBUGվjMlv.kᒢ[) ݃j.ZwYJ)G߇x*i2ut^Ne[YA8s6Ȝh'iF>axv2D@7]USdȔM,Ӝa<9RZ(zτYD ֑ Bg6+=$+,ދ~ HB6 h_vd%Z%4k>j@uf յ\l/i"J{VtV+ujmł+.+38t ~Lfi͌12r-[Vwibſx}1R?Fs7Թfx*GUkwlqď43(P]Y^ZHSh%!ƁQrzu|Sm4}_JO-̓z5~\7?D;W^@X1Y+V.uޮՏ r_>F-#KI´QvB={;nbJQ .:VmkKY5),H&vJqui*nٕ\ӸMDzw8q SzUk:ĭ<#pm[4S>e.Ffuɂa;DP=/YAn+I閳/F C].I;28hAab' :>0=b'1f~AH6g,3N}us&ʺ[E PlްGg$UdH%:ѓF!* {q| ;]cFnHWkڴ*jS?af}.*re' Yeˎaq7Dv3"55lf'lmbyl#ux8G}5t"XGf-Y؁J0X{̬}F2aб ŁKRd$T'xXFfV_~O;5Fkͻ (%lt:DQ]7pD ^$u,0k= `q/J w2XQl 8dȐ!C`)[Ikk5ꢬ{eMF$oDP L/BjDۆU:W=Jvؒ=1ǎd0JzqYt/_{=7rq_DҴ$rh[l*.fee4d}bY`e؈5 v\$nQr5sy+EoߗT-^\g~nUGe?NzEM]Zj VW,dș5b9[N9LX`J(,}'!*V>'ze)rT:M'Vse\s-"6:+UEmϝИGFn?,DJPD$1hm;B `4@0.D/[rkgT Z@ڠ .O]XieL ɡEʗd;eTQNiOx>y,ZA(e,CTL HZ!P:CHs`!*LG;Ѥ|P.AT_dXtF:-K &?Rz@sݹbnjU\%wcvYᘔA\s"J[3d#h4'w5Ep~ߗ5|xf8_[N +ݸd5箔9o Υ@qWMN /B=P'xMX]y#f7y1|m‡hI*efX▧=#mm+D&4LLފYyM:܉J5Gx5[hvRf!a!' r9-Dž%!-]4VK/ ѐ+yP)7M0Z#qbW.BA#Zд-b)F _"vX삾#/6;1C4kVSpZ7Pv%MNtq=mlr|9C8do TJ$唋E iz>EAʂeQ^FߎBC8)]˒\q]YtP#3YӒs8H࢚MbjN%'}I(G~]Ϥ-Ϥ~ZQ'Ȳ'~O)L3y3yOJ=YEV?c4BO/O2ߞ^^~ ??=?U"_?^ӯ1zoϟ~_ӯ}/?5(_>~?G'")Bzʧ6. m " 2" ,?\u }B2:7 OG-MZ u+F1(@u`QW˅yJRya-Qg#*w_8R]M􃿰M86zeM|z^(]㗀2A` 7d 3*nhn:[p n=Cf#-LnT Mzt2^ogt7@;Mf,ֵ+@<¬0tD~!3>Z.\MФ!aI 2I"D _Df |ʹӟ P ?IJbe e}ak N~GM$ޢaޡ¯@Zqp3|cT돁bd3F lukx.ϔئ;"'^[a 雙κlw| I Z ]ޚ_t-֛gUr⃖ǐ+>Ѹ a.:( "0߀pz!M1p}V"h6\P%L_'>M19kK))r |[j{vcý.*]P_.U\éC9Icle)RO0lu5& ^Fǃ00Y]9B^b̈́b{8{^{ [w"<*!Úr>_Tb|gƿ7nQip3`+ Fnu‹%̯+]Ze&l}x0I [A.+_~_B(uShyP\ax̟UB)8 hwZH1LATd|KrÜ'_I>SA1MŊrz3Q$$6rЕ,V&c{Y3YJ3VD"c3ɟ4ė[>S0C Vd\&(}ڽ[[Daehj '/[[}O2dg/a \ESDnFnl̋@PĀOriw rvA` 4ANJiKNb| dsO|ćXģ"d lD+p8ښbM`ٲ] W#0,Gyh.P~+Zoz 26*珖4\H,`g; Xl,D.x^$#تQ3~HB0P{c Qn''bźƎ1)s1V % YŰ?Zز1E^oY1(H ~V6ҍQIFBQzAw-6(_jәF갨F((i\VLJڵxNMfHDU=F~1lΎC5>d)V\E&we:\|v=/!oTQ pFE@TWX6_&PZzzF''L5!=C`r)hG,yxw LuUlsw(Y_k]ʧߏ \w1aJk 8 "-ul輵,X\Vbd!e񉕬nAa|G>@ѿ,0u:-;j),O;ۧ!I'PhTa z˞HQRkd{ܓjjj)"eT%BQMؚӦj,"Iu׀+芞xM8( BګvZHL^5OXi~liHgPU*%%  ;wuھ'pɓ?wDG7.'Ze꣒t=;24G0[ Ur*GUpbt4l{O)!뷶q\0Wg8H.[.tNzB7桷>,_J*K LM]kuv!iD +4,ǶeZԛ^4i ToNoNja|[\`) 90jJ'nK/ ./{`W5ƄR_Dd sO5Y(hٓքޚ/m#WT,ȅZ*QGqX Q4Ra%YW˖ +R2? ]`oFV(4Vo'Z,q 7:Mzax+%]3hb\l]0F{s7LqMy@#lo$ܕ ޱեW]2|]<2Alp9 Z%a ϸ;!a;Z={cб5%2JoᵉSL_3 sB؂z#>/cg}MZOFGI'pZ}]| GTs5 ;0!}ӷ@Z~R:%TtAb60k𐊵# \51CZ9jabaoܑӒxE!\W'["x]ud:\dDXҔzdben1 |dG<0]ϟ^O iLږa~*jJ{NPZ!FW.7l-*tՕRd?:p<5̦3-?_^g 1]wS*[]rUOn.qsϣud&>F0K &!\ LPR+lէ :..-A)ة!2<@+ J`&0k!7yFi. :LZ~u流&@f"&p0y ؤG^zg~S`koS [㜖`\㋱: |G6WS!A-ׄ=~wp`XY)R밴qE2aHpэ_'QR('keeX8=<Wr*5);_tt5 QkpݳZ2uk~=XAlL.X4ʳ@w(CX3 򙞚Vڑrμ!a#WZe(u onFՌ6Vhz~uIkՄ RlckϢukh?ǫxŭRO/(Yr1òt _#-." v(Tʆ(urf{4fjRb49; \hsA~ֳAg >'9Dn#;9w(d+0ϸc>ڀkir%卨JiOVUjRbFƏC6s"TڟXz'/ ?aX;ZG))vl#ssŗ>`~HڜōXVY5'pZnйPSYx%]皋kd:j)򕢊/"Uoյ4UM{Ib2\e lqNN v5!!k_XF'f}AXXJ-3E"4M V pziaIނUK+0?7. 0fm"h#dC{ۮNu3kNNArkIxT>4<ra%l#sgmAFA&ع['gj䞮| LnCK:r 8))7]ie8 A'軀Օf2"cm&SM^6}(ky!IQrP!]r" 'Lݹj qO̽MyUzFZzt| YC-[9\yn @$}%cVN.?Lly]%:gY]\yDŽ8;}@N`Rʃ9"25zg9G:S3{4НDم:T۬˯}sku7 2ו ͑rtP AGԕ-Mssa.Z(OM>D;I5xPDîJVy3Z/d9˳ȑX7hUQ}_pRK+^)߫Wo~3)uI ddOCIc^հxB1H&;s,$./dֵVQ4̝k/ViB335P,ۏ>p8X-,o3\9F|/cՔwT}8BVRT6,$|%SVJReU i 36w"€l%kq9_"0HM2g3p&"2% &jFQyfw9Իm*nA紀w^^Zg-=%<^>X5M2 ş\MJV#~TY6yrrG͂!:PXxX|5[(۶yGjWg(@`u@ ;vQntA .ꓓ5{`p* pENW:U U3U%t7!dplx׬̴8Jl ?]|cB[z8ܒ>9:ߋ?SC[x覐ѐKdm0FjP/ =\;*Cb!7wArޒ>ih ~^Y1/P58: Фـ8{5Xh"-qZ4/é&AF-,~ V*> P..k"`ZVwDnw]'SJw8G֥(TA/matw{sFܩr;fmf骄GmfmzUFS[g9DgtUO)cD@73v*9k4O;bS~ϐlx $rk.)cV\koFin&!gH0Ah &N?q.p n'<2c5a-;`lMO遹#H-A\(za~b# {YlҴg jhx S2%Z+Aru+ZLB}4)^T|֦KA% 4pU[629B|]{7ar..KY;M\\5tE'XzZ`bΡ5Rm_vSV̀M;q5'Nf#MW̋kΦCs;l@+$A& [{pI (<;E,My֫u\rZwt+SHq]બW-^| m61 @WlGs*р:qPv=YD sN,pMhejs|^iUq܏pq/?Z|t'+r\(ʉkyt\&;UcO,"|c6V֪$ -ͬܙ YW'Xt\1|.gHr|{6 ^om<;zBe0j]kNmVIao}M^*CgȂEad{ G֪n$msfܕZjt}4o_B ( JIFEW*"u١1iR/b*_3 4!PTVp9 LjA0|MB3%b+F{ W=ҞjΗ$+| )AX`5kO9Y'^WvRFMXOܕj \8ݲ:P=f ך/V/3 j |_U(2o7Y׎B3fgf]N].F@@}"ߜZqcD׸隺;=b2jnU_Q28z'\LjJ8.V>Z`)nx E)l m7ެNp{d, 7skJ:-U^49px޿vJy=绌#h9g@=$/%pz&+rPp?궮_j\Rpig<33>_gGYhr6ÅD G Uۋh{V{Gxi s C.OWYǶ.>hVTt`,>hfh#RyL&22F=஬pR .B%Yw@  zRN,y1VIey^z V}r_^VhE?i6SP*Bw"lFkSѵO]͊vL .e"NR è`uܿ>OÅlEvק C ]j qg{ѵ:߿YFdunN\(8-C Gm;6 #.snwPS5ICoLg1T[ݘzE7zY1Ig=+p a;c](:*[%ytqM~fmGwXPo뗿*ƅJ)*O/^CMRd׊Ko:fJf092$2pPp e9z,#Cd'eSƳ +K7B9F%BjpsGEiz#\ hS [#~a[XBC7K Pp|S⺈&%\w22PM:䖮Ć!|*V*$57Ưw=4 uS-m&Kى;q*9-L3yQpI!PV W.~8lp(K0%靠TIV>ۏ[yo+\<]W4oMv~ѳe7{LYzm+\4HR0ۭ" k|^b,6HmP9sB7Ms񪻻dEab];RfPTY_򮇎&A IrO'ު~LfxXx-mR!ALŅmVx8oma͖ω&͍ 9[* _Ut`[gˡRMJz]LRtU0*x~l*Vo\V,JjEkA4x; A BcNDy>'_|܍bYuf>.͖EJ7js1}tYRU#}=v!vWltdJ"{:Ej^S*>?o֠5)$s ú8Lh7>*-Zo8nZ[x KVy " 0Mꁝ42sek=Ӎ`}²[z% n7?mI4g(!Xş|>76ބpLϘ&UÛ`-"5nh\4uPilA,zGRYjH S9`X[oAb7/|k.827ZB1KNC,=aH #斐Ip-h4ԃUG3D\1rjҍ R Poܧg 9 8ZH-e* ocaWo]i}`kY4 ,EOMM>~;t2!I]=6kVn# fo1Cw~>. ^uL%2EQBC)]Ksfq]3E!,X#e*r4]*}q88EOF?O?B '>~×?$[|_wBM>׳h>(L^_OJ=Ye1>R:2ӓL_/_^>}ϯKO?\?//?=<}|wN?Ǐ?~󏿼XQ?~_^פ4Jא,n)[t}O6Eed=}~zA\?w.:='-\E 8OsߥF8gNeN~Ҁ4{y[TSh:z:q1u|]*nҍgi^?I}3>3;u}7PE}QȄKS?gbǯy#o"=b 3tǭʊoNFeQ)g|f\Ql=.8^X-7FZKv[5޼qe-UF*ԅHcLP`4Rm'#`I3fpA'#O=~-چk=hE@76t3RiN\g1H=s2C$ͲjKX#g+ZQVK!"#Jlm.5K jK Lڮ^bdg!G_lֹN)4@Bm ݫG!)Y[Or(.^]<.k$;E["{qDw\?`p kl6dF=2x {߱Ie+nw?Ͽq >:rUW׿M遟?Е&S:hnB;p8}'WT+qSC}Ek_ xeS74%t{{e0j0hޥB'~#tee~J/LYKkM/ G9пw-kgJecH%ME|Sct: Kyf1GhQ=8;bt& jK vG}gj{D ~{dor/35&햹{E8z4=Ո߈.̡gz j?OlջtCNmrMwbyϠDQ4R RY4΂m3m FUx& " ,}"9gV}r~VW 4Rx$W.q" dGe:A$vQŒ՛&wb&$5wzb-s2qFV'r촏*dȒyrͷ+dÎq16yOݍ=l,tqAxOwe5Tס)vǮ}9x]Kcm}n -dT0gs i,o|N偪 8@pH?}h3kd1j|1' ;%GĆ]+HC2w $cֆn{(p]UgFj}L$:ٗ=Rf\JCU^ !@ƕf*¨r"Rajd~c*!TGz«I@Z)g&2D~t<_ٌE%X2*UN Һ Ks;6:9 ;{;֑ 03F6%0I ʪ庈sBl{ZEXԅDh|%di7P츩EM[^O~&C^.^5R@=i%&k$``7 0 M=-|Z?*H'Kc>ivj~}2x̄}P_Qo(Fc Щb"$#,& +tr|lz@] /H}o%owh()jZIvHІ֑8iTߖRXa,֬;BYmMuuL}9%nziϜcv,?eV}cZjV8QܶՐ^ vF A=RY|MiS]ےdµcN"Vy 0>ޘ|R_$)R[|e59:mHJf;4>EI`'{3V~uXf7`f\А8D޿>SR*3 U1u gqobzإ%"&8#F0 )%71P`XjҋZE/Mi4eYC,gџ9;oEm;@@Ӂbs:o~ 7JI-ޓ:|y/E-;v< 1gUu9_&L6Xj?޳*.;y0;㶝Y2ܼޚ9r-{P,MBkSf?̶>K}k.vnDz6"kQ8|Wr[_&Ǵ bڟ7_inuqSsc6!&Ԭ^q8ķطY^?XIp^Zvoj@OBqbzm>[0sr[g),d%S*y:^{K#/.#{MNȢJhl09;_H_C(ᏆPz^г,bXGZ;O1QnCZؙz'r_Ï? R"g)G}>P]{l `Sbme`$]?b Ԍ[?ϘFAxw^Ȓ|w /+Pe(_&8Ɩ7LPHjc4nbZknۂvXS9 ܌(wEW<B}QjkSCv`GJl?A7:IT9\$7zSt$}fG/(\r>2˾_.Yo Kdp1Mt#{[;qg/cB=ChLz#ꥈQ7kW\S&vx2[G 16`.YQn@J UTN3QȰp|ruovLP'(H)Q e`v ~KPYyɟB[)pQB/eNpy X95x^iG_t*ςZ2alR۫*A\4j|^GGpcm0{pq3,@'zEX/t|˙?߬,'H}-h*oB2BoZpZ.;WdCH Yl#:x`(:c9^LlgcTMsjN^_+dI*K(ͺىXo=¶t)*nٙzuSUX+ˑMpXae 95N6r`P?3dde$ă_2{XT$-˭ U9;i2|$ѩ?%mF`}=(AّE)O.XPTO%>+U s}ϭ{IgS(†%%Flw{E2C?P{Wi60l1Pґ5zO+OlN3 2trr9)fɝ9021eVS԰ww߯].FhCμb: %qLǤ'.]yh!B{lz+t@]88'B`QJqX$F\&í jX3zB>2y 7;b| Ttr*MJY|L/$Uo@.Pk^?mhYWԞ'9 .ŘsmȡΚ]fi .®LW>X(Z~e̱8zCxk):VAhFBf~1M. Tou oܧLBW)!&HM1d&[49%0K^=;"z2GIK88 b=jjt40Ϯvpĸ{-:\Rf,6834nJn6[9ŕ'\_;vs0Nu`({FȐC۪ipmz)6rbZ\mr\P 5+iLhSPo< BT0FvE8 ft1#p43"*-VScnPaXBՔJR HsANcnޗԏnNUۢq%MUVq. :15N!pϸtDGj+\*,Tu1ƉL[-ƇY{4aVMNHɒ&joRi9AoӗȷG 8U{-ٵjkp=Ҿ";GAN-W;epZW*(cv_oz  R*27] sa͚uJ E &'V;seZϬiGnP-\3i+2!;:h#YP r 2Dy#G/;&B^Y &<~H.uaiJ/{ ̋9Cn.s!sg7g&b[D*W86+׷\<?d*L.C/}.>w!MSkm޴J{ne2:} i#ڰ?;"(ۃ-' 2W =>r]wJ=prre`+IG|TLkjmo /#5-7-)1M9H.+Ypp9iq|tXC,; REtie8n@z`H?3dbn\juS''#( Phr\ DN.݉AIӍ .^Xn ], bw>Y*\tZY=p['V/C.V]gGOϞUL(Y&8 (́hY W3e6p-SXb>zlJD'ġ6\+@DNlUa?".*K8nϝkŤn]Iuyr> oD}A={P+r~u˛°gFL@f}+nnTuE0 ;) @Nyh]nPn^ )@ pr4mulGY,v%Gu&434~ܔsW&RCAE%NJO ޹L$/ust^e%{p:S.ERktiP]%Pf#& L$/l0*f+.[{=caǻ愬ڋ|> s$yļF{jIz H$1 eK)fe)C.UZY %n[n-B˃;lIK uYJlO?!7ECMp2f|ri̓*a%B(L8(4/4˲հUUŸ-pRrBaJ(̱,nZ5ʈ5̡%l7ń}H4;w+.7 I-zH>FTPz"Ha>EkҬn6[a] G ҫb pvRI»N,ܹ1j? F~Q-mp*N6`v!Z%F'7&:70B8۠󽶊1%kA~unzj>ω{I+f7 W_0ᙲZ,ak*BitA-I}{{M~MyPIgU[1_N:k(!G†%Gm6& H eӸ Y'ORLLH1.1V=:΄mn"fRT ?}++3o /7m4!E1zEvXWkgJ[%mzwM p'pZE`49N9YEI"O=Y^"ZNuesK0Sxl'Ȣ?~Ae$q7rc|AhY͚Pz!ĻWArUVGE7m.Ek%̡GO^mJz fͤaY8k8kͧY24  h3)[0l< g!കAFHP>|4汅sDH܆?aJH p2 HXCc8.Id^6~{)0gSXX4WYLrxFCr`Kg/!Ŕ骏JLh)`GpnF9RF4vCS>Zڰj5Hqu3 H+^UtC+z4~- z6/ r[Z܏ }⭁f͹4S)"сUulqJRey9UGYN'o`N&sԕQ+!gAExhH~˗?߾o_o_7NG\ss'gZ??n3?M{>k8 G fcɚ[Fr~TGo ǯ_0JG(o%EP F@ Ͽʕ0eCquS_a-\TP>i[`~6-6$#(lCwZOJ^ 75__@]@1@\?6'*R4-&F_6NŚTӐ13 F[l&08\e+fku`.TYXO=Yy ȟ#+E&熄pڮx/'vD\la[$rWvaTR%`W:ԬH;s4J-ead;2BI-b`1CK e4\U$5';L cMf+R3A|[~pyz\YR_u2"vgy>F/l&h5XM(~B)>0v/srs\gimuܘ'Z.H RYwƹAM@WGPm <1\ngPd?f+@iv\k^f MHDw;U#cPa_d0YV +uWh0f1kƋ^]r ?LP_I нUZF1C`5ωQmb1AK=#EF+(0Y9dL͞:1$E†>Tz sMccF 8۽)LEr}W|{vZs"Q  bL3&׎۰奷K`[vڎBze&](PTCUʚbZԡ믾[@ØLx¤+4gZ 0f,@lo(׺f&ǜz1Vh^{[5sTx#d~tiL>l-><^l)L{Dۈdkϛhen(f1_ֶXDݰRxS.[lLJ`\`hrhkyuԕCevx[*rd\k'p6S^<ę*d6GQR#ŀ+Jah*5o Ώ:Dn,ike0pLrObLu/&VFTboS'oۣ *? E[;ǔp/{ԗ-Ţ>F[#iLnjZ >k!g_P5f7%-UY9rdQ Z~\ řUPN4_Z)8=xQ,: wyqyR9xЮ%ܰţhڴۣk%v\{f})ͬH= IԽh9#L{⅂힝_uзI@+z "yÒybj:ٶcWF2o嗬uDnc0f h^HDMk=-Wjm7$W96-E?J2f7ּ\-4xSh9ua4i=Zf3r:>u| ө?dE:5-]ў eqV󕫴595%lȢqD5@C=8Knq9vN\n-gK7צ?dYkR smX2.3nP-{Bvsux}yȂd٠mƜw['xGP/hN{vCG|m;§T QiO7 7b]/_ aצ>\p fpOf촡9ڟX)/ﯟtOd6l'/[;v5BF{nv%Fĸ0aߺ|O~|n5}TSǯdȑSh̡om'Ɩ" WgmM]+{ȇьu틋?stm*|v-LFћA:1Q"kK1 ri5 F  @3`;y>^=)z-l=V.i,;E!Yh!B)K mqg~iL%SM>~&8, ,img4Gw٠:qo~nr D7Hm |6-؉>i>]y. o!qzs=H:œyA^zt5l&,_G=4&BGK]GMR}x^#Ͳ_ֽ0 ۧ҉Mkf`ZboDzǢiPM~&75A8^y-R@gi_ޖRZ: Ԛ!e\tEM.r 7b12/G {xA[!ub)kʏM ?X.ӏ0@i;\ѲF&#FüL ؠbyDDmdb˷ƖAMΌI34xR^!pGb!U;^Inb}OsrU)oɘ묤.?HK+ V9< er 6x'p9ok .O:{{I7q5(FW߅uqV*fh/ŋkנ>.ItW0Z]BL8Q-/smd 5V?~z-xԁ::Pv甌YO]4iYӸ3 ;/i=^<, S!:Fv0cTt)*19WFƗ?(KEUg,8X]cݢJVw?jt[b?h)ma^؁M&4%2HD,Ax ^uXxEw><$вMe6v?] 4bDa.O3ddgI B4H(P|itI(ᷱKVKo s8Yb|`֊NreOJ&6u}>7h (I`>܃&fʧ]izyH\6SrJh~-@OwT|Pa9PYBY(l;њ\);3em"ڒY| 5(X%Hu' ľnJSAaT0{ޅcNt*?夞EUN&c th?t՞bښMj㵧:)G"b kCN>H{DݳضPJ\ x.= :.) ኀӧoG^>*T#W+F{ @"#}킡](ƥsg6R-4X%Vm 5 L+)IT΍ .||K)co|OL/K)0ꎘRpYN϶|<- Ht4$5ny ~V{I2N4ebDrih;p _*]`{ <OG7`jS]ɼ}O-n3A[%<¬x)"#H 8;9G`4XAT:ʙ {1&aq^o>^S8?ir)}IN{잮,Ca6 ]XX{Oe3]a^=$T`eiec* qN vۂQ4~ K@I;=@ȥ-o ʑ V*ÝHIIFQ",؉~YD-47f#~CUlD )P \S9ѡh: jW[wl`>[c\R5}B~Æf;,3@^[x40ׁ55! zL8K=C&{HJOf H4iҀojwS?*YmG}f_>d= Ne(*5Slɜ*ˣ__\zN; 00eN'bkFBnd\l4tbӮbQDS s(IsW`J7ǩZpW(n,=y*ʁA& ` I܏}H7V>JUș//Cbo}]`PNcFچkN銁4WΝ5+=0@Z)5Z}眀mZj[3dmEsovIHal:E w.lP\y,rv%M²4h?eCm ȔƽӠ"ٴݠS~Ԭ1%w3`ؐTYez*зk-2mI s+;ֽܛS~]uwA@WjF m"^]zZKs)dnCЋγ]6}NČGWERmX=v# l0"~$6^oG_ 0~b9r>2M^gv 7`%>=Eq|wۀEx.+aC]&&udg9ƒ$lIUzLF6#eߡ F3.oX)$8_th1mJԠ+ԙX89+H㱨 cA{)b9*%Aonhv?;Uh|i8iVK6z90G7,i4#SJ]O|kImf Xs X(a҄'qу8! O]c}0IA1ֵXKJ[=%^).ʶU:htqg \S OnHUНE pv/q?C|KIG[(v@1g ]rkm\!s^̈́>;Pk>X|f~|GW9~wa3`4"s*qHP˛.hˋ:Q-A1uڝ'Gt/yBVa?<'5[ے BbNxPJ۽S.>Sl{RdYX2ʺ^ԅx3-caooDm1U<,ޔWp;ÙIOHhw5Hq|@?ۇ@M8_S(|Y&CS:{NGsw>;ѥV`sֽmaJgb[A=C=āgx>Q{<ߟf\q,F"B ![a[ 3M.Q;^Hzt4Ov6tQFM3Äs`Ǽh\2bepaR:!zsIL6I(=C1prSԧK4CR4-8򸧳G|` O? !LMbZeENA(Ӧ)Pi)0v:yF$ )Q|P(!d^Q՗,@D t cs] їj\MҷʵFG_i냕Ԧ[9wQ[R"[GH#iܷv-o`SK|=7}X A76; CYOQ8֝*`ݯ4_ {^i<~8p+DԂH0fvMA{Z?kO޹p64N̦ߪKq̇̀BP.[jٰ@8)N[cՉ"BƊж3 eut7 ~w=LkW!WIFG}(a8EMsjJ^ro8GafVo@|DT|4SXZ 6v9p_J(q%\ߗ2W9>LM`<;lisZ]H/׫~C"qe^P>&8''铒At'IA¡Y6Nٴ)-2:2Dj|E# ^" XI?\ZMZ9my)듿84YaJؕy0J,E@\Vfi[ а#XQOBS k-"sɪ\[^gA^D 0&qUhk6uz.+:~zeƒkLV}ھɭYZWK|k:W2jR5wC) )"CkI+Auz+c6r&e8%ɳqa&ׂ˵F >f #Ѡ8Ǿh 2eE51bL9|lc8NHԌr|U FJWjbݫXa6*lڌYog 9ơ%`7 [ɣӛhоeQb[׻f{g>hOJ=+ o*<&iÐ= Qgb,?7xөE9 #51_kkFb'ZP#_C/_Fcup]d'aVfZ%S]Ї%z$?΅zQ̉^{b$g{ i@O"|0uU?:uJ4p"㞴cs>EEf>1*{YO4],rqzˏsm ٜND.o S ɂa2$5ŀ(^B"l:\s&i_-{2~ vAD4n,u`E$|bBzՠ/գ-$-SBhP$AU8ӂBCo-}˲\9nX[߬(NWވ~K:xn{菿|w,LuBgٺ~֟}R~QRBB}f3מA?9eRQ} WO@Oo_R>mqo_/c_ho۟ς~߾知[3˟[o_˿_O߾~'!3|]-egץ,t,T=_Y_p{}ᆠ}u+ giX݀6op~ yoc܋: &ӂt"3YO x˳7U&]Pwtz.@N/0-W8n>''T.%0vP3۩զ/֖')=m3߉TN#P֧KbMJ Pj ㅾ ?6a5(vϩlyV+jmT=fԿ/)eT!oo ;J5X߄_C`4; sBXtlhduۉU yӮC}B~ ~Ys0|_l]r#7ٍ |c5[Xt|7MXW\hz܊ B:2;ؿ o>@uyuRpQգs -c[܄QWwmo+b\ql|\Ȓ m] |pb<'\k԰g5vcR;/AGAC(bkB l )^@11 Xʿ wѶC[`r>Lļ1^v@"# h\UKց@cl=.@4sqأ pqҊ5k_ \o*+ 5ٷłvs4[P[Բ f޿qzp "suBX{T]shD-$c5>@Mፉr<4dFF7>͌':N ޘR؝lo6c>Qicm $&! #{6Ɓϱ,G3S3g+ؙe)=:8pϹ)'~f#l@"#bWs9\b>eۢo8s=`{٬$xǤ$GjeG_ƃpg{; A;l*(xYq71wT .3h\#wMнtO*csuA4B$jDװNї$5M]Ϧ5r1ϳeI͈'ALK1/pԖԘ6|mhTtd;MV;0&"*@kgZt~]Zfh&)rܒ6t{_{ p8m^]ۡeΥÝt rlmR:#Ȍ26ʽr{idXWkm wf\Cbg@6ϫ]2A̠?ȧOD ^g:njSnRg!W(/Ù/Rb|PÎW])lg9<`ZzyPRm~u=V嫎`+u#^rrJ[ e*`̼'3b9̀4 2=oEj WU%Xoȹ֤!߻S.QItOKM0-viuܑzDr9ѱ!U#Moa0=`I&_]DpK~0_tֻpXknrtku)qéb=>tҶgw|;#n:eA 9*XJ A֥/s~5H!6K'h<4J?釾hpnuxPq/g^ozՄٶ&#:5s ({,Zo\͂W!ڷ' ag<4pK ӓ=VH_$W*N&:/UoOѯ"i)}ߤjO%ΉY<9 Z'c7Ӡ`L-zGY% 4k "^!'dI眝Z~&KtrǪj滙dL6{,t*GL\'|G0Bd`uk kE.>*nl0cppj1v]/iYNrIs'@Ӵ#sN4> P.ߖRBΥSnPQI3`O$5l!}{Mt=ǑnUcnR}yjH}1Qd gi@2rl[,oځ\hV~83n'@dP&Ө%W8C}֕itq9޺HsWtgz3^̡no)k"OpT)kJذjb: ]c r:1PH?ᾄ14xEī%ۖDgCNr7=P^ ]+A#nC)] |Gz+lLbn4Rv0h@+bZu 5)I3 }y.yai? kTc ̓CZt5|3%5‘BĢ .TͯtH6#RysT`6 7ḱ2-3(*jg|!41 )KB Gdpkp8_Tx$RE4zˣ9CI-hmN o1T~Xk[Y[h5D1f2Nl[3^cSi(P5I1Jm>.fw\vԤ΃7t0X)Õ^ts69{<:Y2347_3b.&w7c>eb@K6om PBPBOInYX&liІxvP=.R\ǔn0Nw`ЈB 8-6[}WH)g?A53:8Oj(KR_N!h3t/CcoPN57'oCTftOY?ym}M'tTV$IF mSӰk* mz\(:9,I v/sfM2)ܢ6 =Br$%2Bԭᓪd~mDqV1`1,>\횦UvrbH451yTp{TR XW><0cS[ Qn*!>yƍςa*u($Heáho1bqw#&pZAR+FgQNQZ|AC;>`Uyk@Gd)C*R:ٻ hUӪGL+A1GA_U;+w+r^=K.mmg?X| nчDZ\TM%9/(Ii~_ UqB]i8Bo[q9a vLNqܬmldτ"N8*5a>N_ :tMj,VO8BD1_fqRbV_ 1lҸ8kܽS!!tatc1+jwWl60 XFn3qEKE9c gmBUu.LmΏ!>ݗq%bq(WbZ_}n|֊سnwNa}$lBA9 yN_^]5u6p)`Ճ#Lw=@ e9!qsG|Tx5Ϝ)SZKW4> I+Ҧhe8!&_y>%lmoΠZrhTJe@>JǬTP7%m;WP P1|ƺ,4۹ } P4&F55go@Þg0 Ğ=mzP]80sccWR=Kù0׷u}/3+P [j܊D!(iT4 71foWHg[t3Gk-N&|z)XTeO( 1iMɺZUk _,A$6ҥGv黛Mc4&}?PXũmb۩3uTK뼐?4_xpC;=잙܄l7S7gRjFS;&Tr(}4cT͡{$Tp$M'Q>N;p>x4 &lV\evf5{ltk{~BD0$͵]_.5&M>|.WgዃLKAu|Ԑ&"1o]WbβexkdIb?b\DlOi<#& TB1 ka%$ebҟPCDo[W aopRo뻵ƞ޳,qR8s/m6f. O #1dٰ"H;.$#)cKaWNu)_@g k@$%n֎!M 6o3pJwsdj.ei魹Сu4IFf*Ə#5=ګB\(#Ur^a TѮ&77kܶ08r5d܏d$ɯ#QE55΋|%IRRf"_O9MH0|Ag+g>}^/3on.M|6_*K=*g G/3ؼis~ߛ뵪rFJхM-cG }̆+W+ɬU£YTaćUoTNj06m0IW*$|޷%I25yied.יB7](tkQ".*#T rψh/&O?T >2@=%vOGIKX|^7\H~{F:q",pbf6z0mb|9EZwTfLII*=ʹ6M)՝:OE[UIO::m.ʲSJEvdc-aAbT#uшX %X\`8K>3/?Vܑ.Ðh!|7/IQ}YvܴjMJ^2,|h7jk$20z B+\m/H,.ɭeępNC+r! _fhYQ|][21DG(W^u4#.ipt9jv1v#FLRߓ^5,pcg}Nou}]W0Pr6uF#a\Ng5J@WyNڜвHfp\ W5BN:kCӭ )Ys%M99{hByu#)y}nK@;)2IPI[{)݋*GI `i^X][r `a*,:6/fCwm Kn&\GfW{لz_X/e/3ƓthSprܦ@~#pwnz: 1}y'{t&D8%j>eO&?`bcGWS4Ra91bͺQECZzw<_JVbj8J*;5=gm39^kLlL 39.rOEN¬ET0]ZsˉR Yl= 6Y,ŁyZڣki7М&ZK>W1RQe3hچ[ƮTTX(2E-;AʴkGP2֏PobgGKWJ"h]+CY콹-Ǩ\ SEk]4,aȊFZ׫|rbzU6etRd|>}o|J{>B'U(RS80nLEI%!X( ѝAf[iN[$zgz 0 OJx1au$eP&Ρ>{Mi~5Wm.pF7K7KI:f,{'Xc)AJ8/(:idyI|H%3/. ^B,K%OGzHJ,ySŹ2NAĠ?2@/x Koji ]/Pv3xgX/ TVPPHQL<]Z>՝/ *m 6ܝ=jb8S:tI"z(ɎE&QLgpwb&Ua0oD͍#ⅩՏΎ[X(T]w~sY Fu@d#xHt"n[ĵ摕!+ KjOz7 raEZGQP04;ϥ$(fyϪra;is5. }~! \<8qzIRuBDMeQK"VG ^G0MjD~ N4Bl;X#nK`Qy?)f/;H z9m,khvx܏8 ]i L8~3~@Ltck \\$EÀ]3VJZQcm 8 rγbՀQRHqT i<+8moq"/H{ú!e f>5=NZHtx(tfoM ;ߧt.\:yG8VlhX-36wG߇Wh<o%!Gk3VUmG⽤%ؘ|N_n$^dI_9MۂkjM|@Ftu DHxEM 3 $pEˢp* $m"w;u~g=%M"C&;V/}[y|8().3IIBޅ{Jc>Z?S1DB94q#jMi\?yu =" dηJ^rP2`~@%UxME GH –UR]ZъqGvF(=2b^rnE^N(Q"¾&+L0$ ]f/~`Ʋ)V(a|+ ُV_'E&MtwD\}#G|@bKH?6Tov#2zh8@u%%ݮ q Pp= /F ]vM1[vi܈ j[kDLl }sӾoԤ;;T-&SY(b(⵩q45'+{:4ƷcˣBdp}g(b_JTā*E_+v<>crbXޭ#ljEO;5*r #GZ+~{6kg{]ȫyK%m$5g^Vo] QuRJsgv1IF{FT%wB0Є L9fDZVtY{Xu#D̀? z?ax!:qmګ`|6VYHyҀx wGUzͨ2~o\۰;mmU^!j-T-5':씱5cX6 +V*ͽmޜ4w=plm(6Qfs?q]uu%B:xzZS ƞq*"`!'^YϟcW[M?mb`wZzzO:u/8OߓQF?BC+]˒\q]2bH<1툑FRwKZ2qyo{dEeUɓRIO_>}J}ׯ^h_Czy˗?۫/~K˷[R:W|Ͽ/_^~ۿѦ~}S*?~ym~mZ|:|ϟԿԏOwӧ~g?uLGgf'ç#*M4wklΟH;U񗓿す`H Fu .iD~]~Al=:S_gڿ7`Lh6@, o܁oFj`}Cқi.LL0ԥѴO[>aPŀ2G|zAЖשÀ4'|c;5*،:dpLxvc+; _6xc?2~cW\)0O\fA%EM׿QSi/6ؿo `4:(;cP3Wb?suꄝB ߎܒH8`_/짾`v456i Jn{]\A4PA4]1C5 F.`whJ7Ϸ9d xciY {8=k*g;OHo(QC͈lzg\\6 'vIgkYȆ:ʳW)0F cTbGf8> fF9v|F=Vx⟵gtNT- S AhTuIPV?R4}k.< Zb,UhX9Ցdzkq/ [ p&r†j}A¯ \w'ɳo฿gWK g/ƍ#L4+1kr%ڕ3ZVdn~Ez^Y&y %נytMOR4q`#(YXvqyV}&EX3ʡ pC,cJ渚ދ\;#O.gaW _ѩGQ%/A}`1dzYyTC^oq9}:Če>6A?q;s0rzXQlDaAP= /ȩ#|"M,p9ɶE_Z`T@39b#ۛ)'کD \t s,(ŞM[uΕ]͹UmF <*Rq vӛ@A\^f u(dBaw#* e䦗09?Z؟a}b-YѸt%τC0Ջ@H&;}̰ N:u-g,ȕIv)*p5VJlWXcI8*1)#9伏y0Q2,\kFϷN8&yW!!HK {$=3X wB,gpp':ڄ|#eԻF:ܖ7þMm}!R ]RNw4۰çMW6񹸹{ܧQשx%xޅZmL{͚}ԚyT|%שX9ӹYFf9G_:bfؽ'һyIeY=BF&nY@V7bm6 rd]3ïʭԸ~b'ͭSPӜ1} g3^t?F\7T4]_g=lF]_ 4I9>iS< \9Yci>Nݘ'͍S7;J7-I7zCq).>sq%7Nr0T/)ρhDFhf VʪmR9tuŝrOyXsxsTbKl3u" G'kkZT0duS,Xpy9pWs[9:jGF( Zn[E.u$<ƥ?W|;Q.ՁEl}@=zq޿G&z&HzM2|6O9ώFib!tagӬY 4\@x@mv5Voc8uҐcfӆe:@$Uˑ9jd`K3ֺ˸ `u%A^#ժLFJN9k!|LSZ6'VErXRǁB2hQH '-a'&)#.p<7tmݯXCs&(1`]4Z}=M<99xa`G+Ŕ[B9;Ҩl䁺6Z¼ηbɬ#HO?T ן*V HĉW=z9ܘT?C~}νՀD:< 9)'"iP %x Y Gj\{7Rr}4H&z@֠7YoeR :{ |] &;#.QW uֶ$bifk1mB }H9h)0=7D =|mY0[LJx꠶"k7!t"kn},!a0*vyjI7:l{PAkOl[ ;z@\>ys)cqM:9 9P*^nkKL |nAdkK,:6 UޑKi3`1|'6@?$8CzfyT)15=_ ]۠~3)2Co KC:X]v3YZ;sՀ:KL?Xz/lzoW[`]QFx˴TvM @`:ݩ3m;+IVSժ]?_QSW-i5bI$XS#cw^,#e \Q,Pa-ұcݣwqz-)RPA&gyglT :oZj Kx#1^&eʜjمF{^lT)JknfQ|~l"}KcUX[T[L<6qL ן!-0xQeZ}ϡH1ZúKp0s=Vdx%P lElS5 4-W*is>i9?H$@qZ!jriOGagWj\:(b qjGTͻc,wU+{]/@~ѭHK!*Rgr6tX} "s0 mG:ҔP3>adK09PD]~dDsfy(ũc t!ڷs(ŹȲ`qďFn%Vv) ()Mav$O]ow3j]ơ}-ʊ܈qčV7k|wߒk75Xu6q 63w&O̝P@Pf  AӧɌ&LLQב=҉j6 K@vp7-[j9#㩞{PJɡzaH#hSlBѺ?,wbmKI`klHtIf!mx?>ĝp\B1(,u*֭h߽>BD+yUbQS{5|dJ;]h'vmE%;pw 4tMۘV'pAHw7?nu޴&fa/'+Ug5 h\1&x"fC^/܍ϐju³U0"x4I+w 0h`}Y̩g|V8\X䯵 Taw܅cGU51Q/dM%jjGZ@m"',E!:6hsT'nd.ce׾[u,Ւu@6OZ"Z+PB tEv+el^Oۂ;S.*W )>,w/];6 ]{=wLWNFHw aQ:LFk5M&y?!׶:NDY^D5xmQ y]ztS49лclEZUiX_|˸/!dm $1Ť JD&=<r.Ba%itdPEx^iηtB;ͯ!ns ֮﯀BH!)g#f}W~cY[ 5kCrޚU_ᅵi :n;+#%s Wp|ʊ|;l; hFmO3؂tR`[9 K˷o<%<|?󕌟l<]HZ}UZhI{S4eޮT).;[ $mi[X,܇+{c򉮕+*F8ljYVZQR:Q2\nXk(CK}n5 R {]M3z!ڥ0H/4!򱽧m:3uh6abT T2*/5gr.1kcj[Mt`Ͼ5]PU_[gMsǀWsБS9yZ`1cժu Ǝ_af*0#1?✷8G7-X]`V?/,wHf|cD IG6F`R܂e_ njFQV]o8J'QGϘИm+Ad/7+m\ezMaOR_jRZIy6+>CcU^Hs7' wL̲ۿ߲()ȡ/.BY?V%WrX0VrySkFM;ܔc.*ƾ:yIv@SSeT4u7729;íۑih6X(~AJL<U~a$ Zq- i?926O+̆n}SYi^!`wFA+tFCd+\g +ܯ6Qƶ9B`[w|ъ` KdF͆/S? -A; cVV㖋DI쁩h#ˌv+>Uij2m<2UG9Bɦ k\5p6'K'FjiejV؟e_]ha ڃgґut/Imz-L',M45^y>mB~Y 9;*>E$yѬ)J!u'bem;!`3[*٠8ICr'Z.cO-Ge/>d̺ySs[UP:|$?Rg*8tuߩG+"\b4V꧃nk S(i X Ji%wBqL@nv¥nzj*%^H3@q!C~-rMؗC?/3AkZ?H;`;jaA5BL&}T0⚁9ERK#-xҝGh> :vozihgP1Uy~T7ümbD"؅sհRz6h(۵òb'%EC,^QΞUHrdd3x[Ԫ&rPű- wlc/^;J@\lzciF7PAD/+$/&C۽y ;dvևdJKK.ߠm./sEZD$;Ppbsحk |2.ԍ$vWTq3KPq\ j)pۓ8, Eka\!9P3pĬ5-1oqx6}Z2"J&5DO%4yW][?`J9 1J%1] 6F@pHIM9?F N۴(ϙEbd-TԨclj7ҞbK,ou?d3 OnE D[GKriu\nFJ6VP0ޙh/BC/!9nr,rDzmA2M@\>l睭-z&W}v;:aed(s2۱k#%5>8l6-O_ :@/) j)m}hX:\@#Cԋj{p.{:9a.Ywlkjt$)7ͫ"@_wkiNgq{h>o!orQX2Z-Wfȹ.$llAͬTtPlP$pThfx&K(U&)K>Vʁ(7f4I ǣrw 6R#."T:W!ngEtn+96Ism`6ܙD/bԗ˺2e!MQth?ǩz.+^j5)=A#t&YɆp*%}|- J:9IEPHKr-bά~CBI{ "qy~wQgf!f4cnFÃ#˚#X'X<4b)ruY[\@L.[׃^Q3m }'|:lBE3 @|jo/M'T!MX>X[V$03Ay:;I%[n?v ZmjNg'r7Dqkő N5O}i zJZoΜȃY0٦[ kV*ڤC 9V1ݐ|jNt@4 >@IuaL/3E)Bmbƺ=(`FXLq5xv#{yЂmIWX\ːwY;n|ܕ EuY|4H!'T۷a<>)ltl6 8xP];ѪHPn"݉|1$ӱH>ൺqKB'T {Lb 3ܮw6 ^Xm:[!wr:n::ْ5%1ev=x8cv4"@PEcu޵ i`x8(~=H]2io,'dπtfLʡ|q*^zӄ];ɮ3 lU]ᭁV.5oe6z$VyvJ̳U}EM2~0M]T7D^Qj,!x]W"<,,ULGZs!:3o c"ǥLl'NMZ=4?F2oyC*}u.yJ]N.MG igxv OoPU6Pm^R&yo?S=3;)dD|/0['C|l^ ? rmr*LYnCyEChB"Ѧm@({xht`o;{5zֈ)tTh* C.]LnkeLF1?&/{F~.Ta ,ͧTuA!J+iN}h˦&!꾂/[ UzYJͪ J@ǞI=b՞ﮗY;Hw|V⩲Ǔd7w5R"z;xyx,܃F>:]1i_faD6S/)a﮾ ]1u@=UZ'8޹٢;c4yHA)eu %i>l.\9kִ!HBk1r6 6Ict8PZeTHD쨋5GRhy [ߔƀg*xxy.T[W }w-ٜ=%7L|4U ?D UwzJ*<(,kv3V]~s@u!HI{W~ҍ]1້ۭN bnL xJ9ݘe5ʱٻc "̂#&28EO-w%)H 1Tæ N4&wIݲ؟,yԹBF],UZX[wt 2)x&^/IHI;NrZjZXtuY<7uQD7h,)7L?.jͱc|_Б#S"](ĉ&'RqSǸvɫmצ&\~CmM(^7쉮 >S,&RߒUP Syg=HI/#)0P -zEE!3EmxU!%+~ @jwYViMtRBz_qCclކ).*ELHѬfG;|J3~%nxzbǫf..L/3vѢ0xWoXa0cҥ! %)=}:h;BC*]ˎq]ld;ыFkLÖ4-;_ψ"UFfN|:O,)`3|UOFh0o߿?*_ϯك5/x_//o{?/o߾:/?sc2>o'_޾_k6/?xӟ'HO$CA>?`O_ڏC/㛨g',jx聒Ay 6 /pO}9\_9[s脬90B_?K}$tt**8~jf3++Sسɾ׹̛򺎜u 9|BE>^߳A g51hb! P:' hM《,0J>4=2_GT U[se5˄u1p J_{*UYhuWv; GxHak Lw2^!ckӫvlcBC}{ةd 9t8bE%p gu3lt=(-&W0bVi;;̣ik.]<;CEJDiyAjz}V`4+ڕmDqˁ` W󃎷^6YJ@;=Ixl;mv^M LOx do`8Z1Q7b3ᮺ`-[c-3^dG.7F_On|v; WY#;r|҃|jK?@_#~mtsZ(l)dx/~Dp깅hj@\.ۃ*^ǺGfb}V;JUTU% ~i@`a7#EE-ِNLnX\ gj-̊9͛^,pν7>\7G0xO;l[iZuY-Cj+1=Gy t9'Ÿ;xg𺸐gˀ۰S{ r;`? "w(MsX"BjF,E1[2pޚsB)ffZ;Uk^{jnY{ɇD^'ō O/Qz +^UqB \n(#`:<=zh!0>Q 7>u4s,)WšłDP=2alp>j$O!u4{c-/1142)oDs!]K+W$SrpWX|@OB}±d}N:op\Вx8:CoKRd-LWR[6ԵC.NMɎ{"<-`#cgLVaO Ҁbg$˃ZD  ~ hQX2k;p)`۔)Rv}:$g4?+}\FkH07I/NehQ]pbXp |RT`ڊkM͛ؕz)>gv*JZ>1ZJmXԜiy&ilEK׀almeT_ya A^rr9gK_N}!4QXp {_volA|j>PZ%3vBIb薿ş%YC `%ӁyC6Fd[Wѥg@:Eey|.yl^ΣNUm;9YDdT$2.uكUzvZ&&#A~hڏ!>NC|6+"U72kc $M|Dp9En3#sy %dxdH(Rd] )'!'kRDF'@Bdָ"V* &:Ѩ!(z38iw 1 KhgȗN5!^r6]t96sq^a4#誇A y:zg;SꇙA5[ʱVccܢAѕ^7ʯf٩o}EX(ӷdH)Q~[9Y؈D×-銢 fGØ+%]6.CNy]X+*ڈ`GaFڃ@^F4c0>Pb4v=/:cS0^j7zPmV l*y4]\\:HS@&%{=z6|%~h]/nRǔ2 gzK#v+ 39~?5GBhN"Zv[I]r-YIWgs>zpIL$/LtW7mHt=Z /P\ ˌ1R? kPr>@ਨH!! ʧiY{pr fT0BA RIIds\x!8'\>‹<%*kVbRT ş27L]5 v˼r̋5"(ibxabDt->#7<!CB#cgCȢՇ[WOhVc|pg\L}P\k)08Ӎ> rwW,I"\r(TUpօ(JaU*қjg{ܕIٶ~hUR%fȡV|)nBA:, ᄠZTGi5S)p4 "L#ꭺ+n'd8}upcF%&Y`{$S̺0AZ&z'*Z|4 .i{?mI5)ɀUd^Lu.s#dE!2BDh$N4FICh4sqEPt:R-Gfͦ20M;-GyjZΰh_֎I,V;\=Y6e9^F{(Z[xN M8T71jTHe|XZ ]o<ґAO";!Y[kc9dhuGLXdr/"6\{${G ܅HŮ+v܊" +b'c77jIk-8zYP1y&/N 8%q%ͅLMY(m4*Et>̰S^͕9>x0Tj4m:cAY|@iƄt!plpWF rf#Y`)P4{v}t즠2.2CQmTI;|OjR:jY_~ Cl#Un5f0WNe#CLN)keݻVzz(u KJȢ\w[c\91!t8d5Zɘ"ڮι4@-akU)ġ̅W鲌 y̕EKf8* E=z-PI{pi#Ybuvw$rVm^2?@xtR @tu[x"AEi Cp'ok φui ã 2҃8P0":?aiBFb4-:Sj@XE5 {xA4%Ɋ@ύn qUwq376 q榺@:S !nc49odzgnG{8smtqi@:Vxf\ x4PtƀToVfZ(aң$ ;\1ݐ+)6)"X-j-9]APsq(jMꤞи]i@J7n]Le/܅hXeJ:0إc<%{i dY3g-*ar[iuq!_66<=?}|K>3XwY =/Pf#JC.ԢM]} 2 v/ F AUN*0\v϶5~$Ad0%>>[}v|zQoZͥTsWYttFKq#|V1pe\>SۤL=mfL/HvьLm_ЕyC6;ݤxhk8yyS \(J >mSUbI y/@&^.ٲ/op n+>Z;sƪluH [m 8z`8c)mV|Q.9jYn={\,:${ " uyxq%{b=hS=r6Bܞ+/vqnIrR:CA֏۸gX-a?4a7sUBq7 Pii1JVB[)Ia-&uPmqUWjCA\E*2c2*^DeL*>}Dz ԓ?H)_PۿY!"(Pb;fQx 'GP旵"^uU gs`@n;.$>8C2w{@~iz֐Up(0*@eVDRIhdIݟx-bhr9RZYmp۵0o~E)E3WHJy+nX:ˇE9ut**D)ʬ@l&%=sOՂaR MFzb) RNm}N@ )fN c/șFNa>͙QO0>Z&b|"*=})5KPGw2j " @)33:g?TK\-7߈PG2SDv`:%?AQz`9ԙKS~5 FSpA)F*E=E||KF)ũOBN 'Tzqȴ6pM>fzu#ܬ@V`(*RÕFb#veπ6(W]Л[jVq=i|@Lx9u:4<\4OO<8ۘ!\D_,d!c(s!O/r=ܦFW>iup ?RM%\:.=l`3sYYy׸rju+ާnGJ(l9Iǐ tX?}⤟[Y4d2aT,4n74œ)V7ڕڰL{/ ;~t٪8e+bw avm_"IO0m"ᴕxh/]g:ul+oˠ6._EVr{F7TTeFyã=fX.fW:>?!\PobZʋ6DG퇓OcCE~&!Ù+h>f"8{_ZhTpno0crq<xMz4a@YoBK8Ǥv Yԡ'n`V@ f]J|69\]uZ5gx}moU&ܓoD}*Qan:7H1ݴ/RaμIu&эTw7*|2HVcd E^љOl=U꣱OilqGu7 [XNb;YԲA * .,j[UFӋz 꼝c&b}ZYGF O#$ŗ\@4LF8Q͍N^9]vmeMQamX9%OArɀn??}'QW=%zKe7<8=g> dz>PԃS ~8zQnFl<ʣ ;Ե6*R]bhzRPiK{<5 Q9u<&psi1>Lmh̓'TO'4wFiA E>l]ή` LY;5hTA+2Vd|\ b,8H ; O饧2^}O=NRL,kG$c,0ړ^WL܁+Ӳo^JQ%-3-VTajc%[|`s0tauj: D_Id<؃zJ^lqQ ia-x0-lcsd&XL5_t)`aڏp݌%uE: 74PVLvjګ`,맥WΥ]vC:N)[i"^(n(nLZ#d' .}F5O6PJٺJx$]$NG"$Mʧ:G^L  DaYlèP(ќdM{cB&Pa*[oJ;tz v.6ɵ}q'ڽc_:q`'"vǍi-Q|z)2᭸ɏvS̊ N2%@aR|c ?2R #KQޘ+Ws8 lbBٸd0_vas{:}`u#֫mo!7?ƒEi1Lo0L]G'Xy}6: _ rDnF7n93ge]ZȫOJ ΰ)VP}83W^IIƗVs)&$Dyx6ev1ӫA~xlށ]\yt!QNB {bVѶ^Xc9~%I+#Ș_g3>DwU F}G #4I+A,){J1f= )#m c?gu6Ue7Z+7 `PmC#^6y/433=qhX@L5.S Dv<~^w,UQӚe܈kNNxmVу!VΞfK=/6A0z5F/eu Aq3s\Wp]ANZTO#~2%xqغA$ ^Lr5<+K^x-K y,߷: I ,=qxEavZSGp4HR/Gvĺr`aϡ:l6 Ks+ٷ|Bzt9AUVbԊ]^gTNq`Y]&GrO*;\k3/f >+.9ŤO,O*r L ]Z&zVKL'2z5"b oESmM+Z\1jup`<ޗ\;„e^d =i[^Nh˶u铞Ûi{.16+1Skau'|VJc\"V*:ggi99X6=ЭbLqz"/ 䢣kC08 =ahi~J/ݸ<,n|`eGλRˇm^>U+-*2۵0j̀@'гN`h%Uq>H=]kן?_>}? !ܧ?/ru#˯Շoo?}_~AÏ˳iÏ1JLj{p陇~4?ϴa?`x_`c?|o}Qӗ/} W^/h?.d8ia?]/q܈"P(O%#^(Rن\zo& }k֩>|cرzO_- Je=~5 B!b @&}0`g2!ќѯӡ%|o>eo0?qb" v2dONUEO?gu{DBX/3;R*C땰G[7~\l@Ѵn4|\7&alv0UЪ*TBGWS2~b]}my]}ώ6X-zTMD/ l]vؒS̀vv>2Ρ{,g vAlu.}/U[8c{v3cp{=K!c @>`Wc,XY?]t |s**c#2:dVfc` ;_Ͻ~i䌈@g?~7$gly8Fx "yojH*/+gz@.z-~9@ml*)q{NV| έ![XCL.$=cOxR>> *+`^@ zf,MjDPրYl v jF #/bXjI3 )i&4z}ё91N/H~xv|kl<Xe7o-iŻS\dU4Ȃnx5;&,v`%70G;iʵ573wݣHwGܘ5a{x5D6j@rJ:F)kL~X7|8g PgVAlgOCjLus"tH\Sx%hsއ:149F;bIc.psEMx4-!{-dбbR 6} 9WHqz! b O?¿ \i0Zc1v2RT5F'#1Cj֫@iـZH?!nފϱ [$R^ @3zej\xj1N@}#_،,_&,%ra"te3j9NA{GNݒ6ߒh̹c(Ac⡄egaN+dN FN:WʁV$W9 G#}|1L3ỊUhaV,(g:Nk_3_##mbJh4^GZ]KeG Od4 "BA"9\Nlԝ@1~IC4r)JĞ8t&@>qUl58ǕO F\$Z·yru]HhQQ-fIiS9Is!9)],Yca|UR ۘڤov Nj (,Mf1B8ϢLpw]KY@M{$44A[yaƜ˸Dx`(6ʲm}\|1615.^ƨƠɹ |Q #eB7XYu(YYvI r0:oQIҰZm5:%MPdV'Y kGP9zMZi1| wV~4sŇn{ܬZQR!ǡ}Q㭍Hiʑ4V;(qA`,e:>“QzI&fRUZC8Ӳ* QvnJow9Du}1$-~wwBz_hhaK6l禲3X Ibgp#(3Z4aJ5F^ u6 &z/&5fH䃢_dBu J)FHw.s;7H\7d_?/l5Ǯ(4UXCgZ[z;+;GmKʹH |]7@u;4Y'Uy6)c9LR $=v( ]q,f]q<(?F H&C|$2($M{"L"T4x3C5'd umon@Tq5/vݘ}t kq˝Is`x S8L.IZ҂,2?' L(_88r+n,`V1Zŋ̴χ*P{$X*% A,oN35xRb]9kJߩ{/q+w5*y5TD!x=~湉ނ\1JxǣkOo58~z9o\GcYk,#iSA.O~P2] SMfnt:5p)>b.5?ʟ,jU:^3dQCIjU{p3fṊ; w1Osr3)1}_<>xӰS}GQ VD[ &[9ӀK41ъA-TCqkJdAU8p@ VpJɸTG-&Ƙ& "WT\Bb'NK!yzﻇ6 …rEr9gEfL&9A I]W~j@\ ;nE$nD 1' NČ jlb|w"m>Rƥ24:%hJ<41z)5 4B[cڔ:N>Z?ZH#b>JfMI^6$sˑWEMgƥ\A9뒢ێ29$fKBHCIn?OJ7uIm*r9*x%H=Ч>.#fTUa[[+W+ikN^8VAW0c*k uyxS / v֦i&zfdEZb\9j[k;Ά@w5~' +}ޠĽήb" #tPl-8͏ex1:,S^(8:oE.-Z}nv^Я1A%AePe:{.>$A iNDd]XElyp3W5APD@: `.+NKI=O1OzR/;] J$T#Wl-R 3?p|PZ==!0Dk1Su#W`xkFJemL CYejNY=Fn@5`]jv"z؉-6 \9c/r'$;ws++>\c0[Dax3e#Ĥ ۣWۑOn@ί,}Jn9\VrP[-/s8r1Å*3c,SR䁇<5bܺN0g4kܣ,@Bx;xmϽ1hڿ/y\Kt(߷ "]yP1A~$Vd,7.6M3%߇ ܫgV.l:Odi"ڒ)ؗ|+(++]eED#RPMLx #홿ݺ\qEMՓ5s8b wDrmo=F͔i]WELbleЄx.Q;qw!6\;tkԜ`F|c .=~/G$HPeL4Q{GB_rBn`v!n8?]41c*h Eyаjx#.z҈~q;6|SI!ǔRHcC !~G\u$)q~XhY'U>7lZcodVi, N0!h[) cWʻbebkxҘLT6pY?k δ~NQX]@eĢY;Rg5em  za)0/:xm0XX.52eFAJTíB?RF-AÊ2q4mMqwzRgܭ-zj@VbdUxݧi,.ֻ4e N͈)U( /l|Wat 0űG[*O!g*e="h):?kX"рY׏I}!TEnw#a1txt44cu.0N\uj3]Dj5=7b88֒͙hs6rX/vE2U䀲ՇSLRӆ6[#܅^1pSDԢ8dNXk4%HBbM8Jc֬rr21\sr=dnL)bWMJ,`u^ 3[菒фKjV 2șh[v(͓"4TY{˅!W5Vѵ5e_oOd(\8<*`vkV=$D;-s鉎'j0ܖć#FtqsS4?9~1'{##lepk=(cW=Hu2NeϡS7#y%t&Y !9bC^njrɹ/$}Xr녹jp1V%xC@Ii,'Μ~ZH.*V:7"lkJ&KG/ pklwXϷf\0vY `L_ vz G NW0ƈv"Zd}-qٛZ14G8ou \ hESVF%hъZEͶz0FQadg(TNi^>6p/ފZ!LsƷ+.ۮ-˃kv_ZzWmyydwg!aMy3z8UxsP43[>_ile'ʆƩm@KlWo |oFxd738gK).Ol8[EA_@+>k+#YRE Y? |^_q7O&턎̸ 6G00 SXsU@'5_:%lɓj-D'fOddΖ ]ੵӓ!Fd; i\-ۙ?+EYhb".ubɔU/Qri"PDkIyYv,w-ǀ]CvE3+iTmauVXk` D3zaXV9Xˎu []|8.A0  wq<ե7 n+,iX1!KאlkRi}1%[/#TϛoThzU]cp't°P G%v^@6܀ L+jVԫͻKPMSq%^q7]  VjNq_G+]z5]+ [_k,*C}N4B̅b5aItV+jͣh/`x6E4leQ DR6Cȳhj٭ۦZ5Zjq?1%~GحyEn2-&GQ0XE"X\vxf^86Jf=Z= 8ޫa~rvcWlwD"ly͑+­Q׌`gJYk֐^_jz869Yٳl'xv77FMx={ɘ`VWG.St6I;7h%42hM.zjژ|yxG #u&һ]Ѹa{9tIV=xMV9rSo]Z-LvҠAI22B3kn6 A:V΂$KJQZIΙ%Ջ!fCmd9׷^=MpXJo#Rn, n%7+T|RXc אHN1H]r>MU)k[&ih)SmGzY &o/!%Y0 nsND's,Yci q/W&xOu+EOKɉ`Hb1ݖs Ei^<5PaAJ{4i<(t4Ug)󐠵_ H'EaPKѾ3gVtȹ"{]'nmlu]%6_'1xJRԽIF bDרMBUZP :< 5 %T8YKA<1*DpLJ7+>rؽG^Gw$9/C2:fr&Gh |ͬ8$9؊`ԟ:_V =+mzseU Q9#yKTه7:-)jއ$Du7ZeEu]`)5q m"tMs3󬌝<ۄѝj˭ 2;!$m|مc뾋sfV8lESpt!`;1̗e3_SŠm_p9X_́= ۸c@m/sbpz瓍/]h.KץTd/?)Soz>q^|?w_#z^Ǒ_o>GH_G*x;>? oz|Q9W~!y#]z8­?x/G"#=%n.}W< zg Io仇w"+ᗾ-^`?? 7q_ dxʘwwa9xԧ~>/Gv acz'$ ?ƻ)5*~'*"P›y,sW98WxT!CoxT>1S6<*qM>8v醧@CVh4k`:TxwTQ 92˩tzWpRPA(r7g?&ѕwڻ=<>|/ڸB(G Gs}xJן謢8GCYW`a[A}zЏ~\n7J~~Hڙ׳:A,@'VR>BsV]5 >h<< ~6*E?E ~3QMQ B?቞zr&o (k~ˏx~B!_/g:8e]KRXZSR|ņ/?qϿ}?w>˜QHd]*U9/{/w*TC JsۙM!"%"}zݺb=)y'R+Cr49d۫B-:`$Hg[]i,^,K$sY<ɢQ@PCNAD}v"p@ȏ@@g5BS6+^I҅MJÁhVS*+y!TKpϕ' q^"y'ڇc~~(%[:&单\CJVYі!໓i$|HD.#sIY*Iլ' Y(WcJ;\-U֘}kZ6ysd$)> LA0z~&)%#QJ-qMt+egFfw vmKRvf.GptK,M-*$;. W>3K*\pUjgO 1sl!17lÿE=vuy7c̯oEI6 M-xz}M梈!*ڏ_{ ~n`O)5q~x v ݨH )B5o; _,/؃4Bo[t '*Yp@LX=)m h&v27\|oH &1eζ`f8ݵcXH)3{Zv4}^^_%G"tJ&DǎO1?%wsBatN;V0 8rf-1(;C|@뉟·4n!U>AȲ b}r_\֎BY!SN>z]xΎa&JHk 1uxF  zdK"]c߰`k> H tr?ДE9\d$C9$sOāb39ߔiiHAyIurҧ:gږ~2$-;?8TWz\ svtRIl=!Q4#-ȩ54 E#X AgDVEK(azMbq>Sfh!Zh| ̆+yv31Nݺ=CHUΎ vԔtmɘY<ҫCt !:z)nJ=z5UN[V.B}v2,]Ml\xqni,1p fd!/m|~#fS`e^m6fEW:=}=~Ub=֞TpA'pNMG}E5Z"(IKJoB8ΙE1gtdo}^|{N=I(ԘFsc8#֓=SeS紺BA~ykAQg˚OIU}aܷkeF:4Ú_Μc߀kg5a7|fc>ά&g juQ̱I'sqێĵL(k ΕH^ߡ-ڸ:~<89>\x֡FAq\&ޕeO[Y v|f9Qe܏T6cuR-g)`F&4O?_ͣ!ZSK`Ƿ(hS*!ؙ،P?1pOnH V6oP'*l&-\f|B}1~ر>@72hHvM<@K%~01(T}+xC"OpyWnѺrG5فDe'[;a^XeףwmU9?vk(gM|z@rM!;9˞Zm!@]h[Gt[J]3 -$,,x*T!+v@KouH} T&9YkVps?h~ mqW!α>_Ks-@_כehO!%gKh<@H"6`V<[lF9Uݯן[BuBCk+܈8mAZc' 2c}\[o:ƋyO byȢWHs9QK)2" / h6vۛ9Zז\˙\^wHX~r.ҷV3TXF!3z|D,3N~Y*eM}K`u*9Uy F§u{:ՅA0[R ЪZOlϙA^r4RYB)YTD;wqcM,lRJ;wY"7%:vDQL*{J}o{H}5\ e⋞.- g$ |zaj^{2Lbk~'Ez+N2?*3@Aґ8:5:.HoVNǵvLmVWKB>)Q#3tP |^,}K( D!%C$B-efqU Gnr`1q fxwgqն8)4)ޏ&Hm5b4&v\Mn.MupHѺjżð3AS;h b$ho^{2~/Y'kʵ\7˜Cݭw5w]l6 -譕\D2aj}HKze*G_[緲g?{[ |ٿD}:a>4%'h,qWa k1J|4ޭHՆ^CR)Fi^iI,$hh[SPz +TZ[&/WR#JyNbdb 3p,hlMU$FM5 ImULv(ò,p;K%ՅmRŃ[<$N#k f|i.*F>Gze]4İ* *Ջ 2<4$$y)nc43^Q˱6p̴){rJnf:F)uғvYg+`uOZ@dhi d#%3,L룯6EF0GOJZJj3}9 -t饻 RUݏ ]S:bgK'U~_E29X>5Bh˒^X4 F&.o "6JbsMV<.ڮ!zLH΂Gw˧S1F10fѯy/۵٦s+䦩 oE`me IMoд70үqeyH)j{S\APPy ѽx%,%IxKfe)001 qC!!CX9HN{iV?aPFsgj)V^:5ѶdSy C? + J* 'ezS!_6qZM#"r Ҧ%h1$Cd|ypVz' M"Q^m43uu 6MF]K̔GMw>+:{m5!ko~Qi$%g ]ṗ~vF~ Zq| F(ܛdb +2;R<)jxs&˄RC(*D'>^C̢@NM؆&AinCޟ_Hrm&üBRDz=3z-slvq凗y:Rn+e=\GͽFjywsav}8ҋ[8ߧ'pBʙy ?Xͦ %kz0AWazr0Mw0)@!h+v`]'^ȫQg۪%:9 M*ߒ6n8h|r0j1vl t G=0,霰eyiF6WkcB3F:=i4):d,|ψSXb M Ib(MUjMy~i5RqM3ɭ 6XF7+a͸!&<&Sfd(4QhNsN{ 3Ǟ FU&`&Ǚl~ z+gj(>ryB )|iHݐ]fdH\dr(`TkM x+=0vZ;lfvݠYRD5z_*oۓAǥ,;iĤچŢi K6WN\^Aӛ[.9WriZܠבr[B'jo KPtL!O4arGڰl[/L˨cȩP]-w߻h7~9d;0)Ggv6&d8e3 4RT- ~![YfH3' ,ضmy$ tUI緖Čgp[ 2nISyn;awWzd_XP;sY xucLID6^,Y=Za>>}n9iU6cH]:PB/:s#α+8Qj -v=m͙UbM)bl+ڑ:h6[c&܇Ӝ{kи#U W)˫: NM|d/T?wa`L޴Exj&i%&A%+4j,N8ٴNx5k:&7/znB[)o>K'hqr3Ҟ4tr"I!$?psun=<.DŽm :4vmmsLS&_o\)r\^r֋4ù&ʌεR1vR|.=*~H5԰o];-4Ԫٲ'7rHl`5aC$uc*]1\ OO^T>Dr{R_ɞc+WK2%P\((VD41tT-p+#0'HPh*QoE7h>[͸91Li}?'(ǟ<ʢԮr0-M|}SgH#bz{=R2ei/FF+Giy/#_{DY(ͩ]_>7_b?ܥ $H5\S +Ґ=f,<}Q~Ж!>V(~R4!nr3sA] D긭j=>bcVkZnxe@p/t:H2UZ4IN˜ x A kzVy=%[C&"*0ʇ`NYcvxtg1B_(ukdqc$MzNx,޳?_=1D:ZڈY3U_y]fTF p .X!kf5 CQΝi.y9ZI_Brh?.;^kFZ+#k}4!^pu4)%4\0=4aFWooKC>>mnPum`nYԞ%ӗFcklϿS\(}Y)kz7Xc洷@X\Y9 ۹:0<&j}Sը>R`Fjf Es"߈w j‰]1:у_e߳bka`1cm!dF9 <2q3u<)d0VXQ@ŶPʹJ`Voԡc[U<ǶڇS[؂;96zYcCͳRxIiy`dfqDJ\LtbPi;9ʏ8:-堎-:YNI/~zXKs1"n(jdovBwg.yyh%ʥq*o;ґ3NgG۷ vj"_t?!Q!ˬO 뇹LؙN|)⤳9Q|qN'۷z9ɴ:;Ğ H=ey3ɲ;btrM-ateAp=>Q-g:Hf3p#6396Bn\*K0KD0{G'H2F s]DfZ~i`mذ  imX3u/bN|_ΐ]ԝMDi*:` e@C[`fht_M[ 펅t#w֚V{\>JlUE^ڼ{(WHgRFV$wYbɗXR."kl}3oQNr,k|t|fhhӯ@;aadj d\w?(K]rlza}<>kQ(GL1-^<[󛝔D/.")>0RpR]d]NQ.MZY ˲]ӆFMQ$6M*?̰mFjsyY֊{ R,)ޗ'k P; FO9(JTro p:*u1ӗW`8Zn;`3-nL9hD={sj"6vTl^̫܆40s,xdџЯluKu'ؕ'̵ۊ;BnѶk nj,vv΢1pdx4-Zq.,]/AAxfn e0:if#Nkޘre牴Vwݧ2=;O/Ig9z1ylb+^OMiCV;*y.Ș.e?MѾmZ$5}e_z}ޟ`K%TOL e+| * V[6,gޠR}mwu{.or޹lbT k鴣Ra$Eun}p.CEupm5T#vQM }?^bn&|j3ō:@)޴@ʥ-uo4*p<UύJuջқL^M<poo(jH 9 [sVDe_aԧMJCX# C1x"E9LcdljL_!JBuR[j 1xQ|ց%f^na mFؐi]%n!"z)t9qT^l#% Ա'=Q\ܹG4Y҂ -ؘ)+>Ôs5&o4|Y@9HX%N箼'vҕ^c8_(S,O)" pJDSSV`39Q-O#ϺXɫ<9U'CUe1njqzZΗ0އ!:D"ѿ:ڋ1_J~:6v"Km*|;'H玵$O>rqAWD7LI&nYCp^1F"Fm*ZrM e8Qk a).9q٥+am򘻘|OƲVl;Lrg^ڍ`1%t>J7:==?1+T?N.|{$Ͱ{rx}$Ή2Y8jjbYL^QJf6);6vKT ƙizc/b2e&pFrvZMʆh1)>akI:;e0vOxz1| Zs" $U*Q>Qtl.Bǽ"6<_ڭ < gyHXMuXFԍm _W2NK`=QDH-UoF06ù9A,T 7}Tbgvdgqs2m|8̩rXl -8 [r/z7lOXo3}݂m]a;OB]ێ$q7ʤηMH~8űԦ2TNQY"F9ڥi/+д`;P.t<)wDenQIz>I;oty/F'߾>?~{oϬK߾9~/?~?ϔۏ~._wO~o?&[fILW| Яѯt=[e[^yq >c>L8pb6q3S WpkHς}ӊ5iWy\?sd΅O?}zGVDrHbq78ՕF}_w~I$cgGrBrC2`bP j,dV" `gAصg>t_v켮&1V0)֧?1)0 h>Vhtu\[?s37aw>UZE M 3|ݖ'B W2l$+ﮓpVxFkǎ~]cLurim ~q=>!w iz>Vv Wl/ίIfnYmm? Ԇڢ6VoL߁%Ki = -ާg˾*AL%lI ,'H'A61| ažewz(Cϼarhؕ/S fsx+ H^EG"F:M'vުhe6];% .}  gcC.G':lv^pqL,Kg=eI*L{ucVɇ,=1?`'zs|_$tدhSRJ;~)a@.?15XBO,Rքy؅N MֽX5)O_بزKAhg9GdžW \| ?/>,|[]+qÐP_/)K\\&k[`U1KÝM"Ϩ{z)s]ix,of6S^ZׄRބ}휻Bz?#dgRi|=ZD9'p71/:H tpt$`7zF'\,Ir1 KFw5q]E9a%xJ j2ڹ䠢ulZm1Ʒ@yxlJ;PMW|wᝎקk' 0iiOFDxD3ڒu3ycCq pya%&J7Lhi(uL{$uoiW #]5BEu-Z0|NEI~W*_KwCV!L!+!* 9tFf_$* N{'f)T'xէ;wp tȞs.8F7gͳSV+ Wpxq:nSh `\}[]#5,;:8 qTw-"*nutZS) ھ0kotZaߌ`w]EkB6dpWM| ٭ηKhuhjZl[ $ ͝k4S |f^n-XY.2ŲG\X֍vn4w۱x o2&0ؑC2ظ'n>”ЭFQ=ImgYs^@=ۛ494._8 o<͙QqmᨲN+Xga*.L=~!D cƙWwEVRz-f?v1-&(N>7IζH%O(>IU j啤V}-L9nҪtC{ 5j/D_5JQ2FG'e*quC)g_.un-UKNdYi6笔,+2Fǚ`OJFW;'usVQ3uk,"ԘvGAYQ&"g.ho_iG!tCN=J^BJ:ә+1x[e)FwE"ң \?X{/禵}ڱkm*fom#cH.5.F#§LF{eL. 7A.Җ벞n",č<$Y4d4v]_+(TqGet6,*Rep4:qAZ:z^t&/clkrn7ܸO8anꆙMdR$4`BӃˤSH7>9߫͛]P!Pc{L؜5šz1짗W)MCUW]^Z_  -^=n vM|;NKc8@6y*/onCiA7uAJ,mݍs7GlәP'~sxȅ'[zՍ  hPUJXL[-,䤲]ur2HH@ h ivKՊg]J9nH>{'j4 -\[͠Gʌg5u7t颾x<9m3d0r/)ʛԣEq4 %zrAhMs-j= !v:tUWb®Q++w[I"W@(h:$x|㊁.[Jzqn*.Q.[4k#U!+Ld{ ٦iGL<>+c,EoHٸXK$A+,e[ls`Mz"OW&7B *=u$wn.s}bB[{o[[ yFo vyH*yo=sb I]XMSt7'[I5: 1YÖ"L^îkБэND)Cd4-e}fCεY sT5K^>HR'zBT U%]_|UVJLtfjVqUZG}u=U+&`e#0Q TQb6W߻v!.$l b LB0%[co.VV 3ž]cq F B3LE}r'P&;ї^}DBoƒ3w长~)fIał6`r:7$QR$K tF}Unsז-5YuގJJaL(rYխ"5{安 [*Na1h`:!~3:< !x?$6r3La3+^ 7]߹k95q(-ey rDE7 ʣlCAG̩nhw^;YrQ-zz!@CnrC/8~ ʼnn|uiEJjo g8L]-GF3ݽTw #3:0 m8987[!ˣt fq41 l
ODR~|}'$iFڱL.9^ˌv(+xO[_DjK"zvU IgyعL_dg,ۺwW_Fލ Yx^M:*#PнB ܸ4`'$-y3j։]uIdUʴޫH#1uXM͒Dqb3g@7X(m)uY}#g,aǶ\AC@1? 895r۫G#lVaQP2J!a;j>4uo#kf ;NN 5kܻluy#>eQaPۇh;6QF(O̓\6^K'>x⏓wzu:Q -)ixf4z]\ئKԩtDޜj5< . 6RjNkTF)L.y/dNyǭ=t>eTJH&**5vYR@ ;"-LHzݨ6LZly< m EZUcJr"}#ԏP OН)aE^xqMdI-?[)m ,؊Sj q2R_G@kx2_H]a6,;oumapC8ҏJ?(ÄZ] xi_B}dwps-ڼݘFH5;Vʷ95b_Q`bWjӰzN98WSSGZ쩸^f JT !t50MnJ\(.>tؠ{|i}ݻaj%1 ts#[OZ%%Cء29c`g΂J&77FGsS,0 {mZ*S,ivSMf֗3n0&r5 g܅Wo%MjPvR5AJFA4)|dN~ͨ|T>$tRB".<1J/gC$YM/+܀zi\V>@UXmTv]IEXP9Jb9,HKsn{QzmsJ}eKIh>/ϳAJOsF\6ҾYhA0prQs05'_$JJ6P`lj8x)^\ӧy2כ\qJ@ "̺ٞ8\8k>JI&}ᆎÑ)ad_& VZp6KWӘ_FwO&18h<4%e: hEv]ȓ(*W)smº.IA47N 1M|_Ya3̦fՙV?Cܻq%np=lltCªP-%kOnX%~JT1;MGI{cu!iOqm.[[#0݅0GLiˑBpxj2f${@V؜ 4ez/k`]%get"$<@`Me?k"DEw-gVFq%  ΅mk'ȃu/4r41M'vʶDq;_T2HR ?:cOvJsPmۓdc#t-ڹ B/q`k9 {cǂf XMҐ/ig`kA{lӺ]R8b$-d֐g}D~Muyfֻ#ˑs7*23cnb~FJyXS5b6t4 JJ)\\991TQ /Բő"tuTV/ uxAvje/ \m%83n$'I1iEYes[T<$ PM546-OZiCjsdlݚn==.]3h򞨢@UpȀbvgzK%۷R%H׳3-W_dݔR2U!fuxmwkfaXϢ=z]^q ٩7z(\ ŗ9]^?K*$ÒĂ5 d>(96Wf9Y}ﻯqZ]Jܦ~W"<u"F3rQP [9HIݪhBZE- ލyϬqj)̐tɖS1ȴ2{I@0Z[$0 _a3)?*{_-iu.^] ^̐$Hv`ˇ(`:{mJ;Nh~Z+byTm[4ĝ O}|!bj>ڀ Ehxx!=6evĆpQ, lƕZpE+֛?fSFgAe\$'7%vUڑLnU(XL)jMڧ4`w_~J&q%g@@Q/1KdL@~ǝ/!I2:qDIKe %I"hqoFX Km/uM XYey l .b>RK:޶] 頣`ϪI%iK^ [ط 7G˟~ /TH*Py&7M'fi߲vߡT7Jr'V y_fײm &鴕YC ǘ9 *t ٌs9o?:9h96t=A:@ |ISXdp *1+A (- d>IDvnh)UI A*ɝG;שuC1 -1P!4:~/5l/4:}!?.S13W`K ԺX Q`7x\OhNvY$FK˳v~vi= TݏYQX ˢKv|0qWɏ26c$okn,N=RmIl)N4 Cd-[絑 ^ /baoRvti`ٳ }tFW-6[mf۶$A9c(+aVUCb`,yT WiA ipʉU;DmoRvo[INlQ78Mj*KPO-eSqrcZG;ak .m_E_ϡ4ІmHaNx{IသmimSjm jjrV3h;AQ\$b-a@PjBl8"hDUۻ}O Q jo_Ꚃ)3ז4k6tdYKytI/W<g~IU',AAbc_q;sE⢯"ëպx;e+Thvj][v o. |.ҦI*͞s^")9c(a@{8TENNA! $njYݓ#0ݱlV_͵mi6F`{#tۏp׽O$%,bTH'Vb<$iUyE/!Gʔ;34]C&*ZxȟZSYk|8| sή>eBZw!V5Ku>Vۖg6RHu f2j7T-vKw|[lKfy<@MFl2oLQ*uyOj0 OQW` MAt/ O^ٗil)|f` $ d:5ƺ͇.]>e~)9r`]3H'X/˟,-j&1mVD~ kz}G XuĔ<9:%!F4I6#/."H r _q+zg\_H+>H𾔏~ʝ }ԹE͛Խ+ȇyj)l)&sUڜIݗ; ,8Q'yw%a!>_#{Zm(6iGxTR{s#ag ==ř%cq^w4~_ˏ:V|cϸps& 6Թ?hBdnobvB'P$ѵ!UQDݻ>v87@a6B 63)-3AKf6BאP"ڝI>RE>F-:\0yT# f2>0ő<=}Ufwv=1ayWrm{X'Ȱ@KZ$i4x+0rtc6Mīl}|#Q?3M7(E =uf055ȱ@H\ױDK З~ ҘoB aagL۞|ӚoI'^דշv`g[g|F%ϫo+)Fjqj6-Sm (w'R ga!汝5*S0CT ԘBB%|]bDdBȚO~qҗVD܏Dwi6+|ޑC꩜վh%7(I36iOOfW(i|URTEM1 MmzB8K-ߐKz6U̯_G4& ST,lPsya7KQՀi-Dc)r.݆*j'"fnbfVJ5 rQ绊֣0zOQ~BB Wuc- |ɋOrԝq/ },#vS;75)Gm$YP깊7`i&յMM:Ȳӯ[g} wXމy*d_1C?3`Vu^]x΅:w #ᤪJ&"o>YZDHSW/%GoY I hiH1 +.INyNm,R z^ :2&H.>wImRˇؤSzM?[z騷}W~Jv?셟-Q& !Bj#D#z},%^J㼪^ If*| ~|lnTy-[o e5øEuį|6x؃02~@u3aPQ_9PǔDdK[1MԙPAe{7gbv4!q@$D! Kt6]AnP@W AVNpHe nG~Wz1TS ] KkI^?MH_EK"{[,KcOPpD!e>-sC]D˞)1ʸ=猢uQVY 4">5< ~AO%jb=AyHh +亳ھ5գOG:ȓ>%];D.1([&fESG_ǶԥHs/. dnڛݓ}}6"(A6XlIؠRQ@y/dyZqyKSf a&@&BvF" v}|JRnXJ;27?DBC)]˒7r]E-Yv,E;c^ Q@U͑5Tޞ{n:y/?}^?wR:'×o~|Qշ7?Qϒ"oʯ}33c^rQ;g^뿣3://?y/-%g_?~ǟ+/,/?_ڳ`^_>/˗>Z?O翼G?#Cḧ́Ӹ"V֏M̷ m_tyfg)3U^}/5mn:ڴC*&cL`q[/fKC9Æ"{ *Td h`zmH^יj.=V]D?ξ.rv4ճybV'Mk-Nk\;Zcc5bC5ڳu@v7`TA'6/?t5VWk* Kލk@9{q5:;(';\RĨyB=Į|݂n5|?n[ؔr3Տ`|JMk_}|@VMϬϬ_3E?Şق-+ŵ>p,a71BkiFyؼ┖.9[u+8J[:-}B>kpc] y6;^5݅;|ʠJox%aI#W:o:( \w \䢍OƔ[iޣ,B.L䴩_Ʒ"|ό<:34K6zh]l^pLk$EJ :#ñ*)txk,q6&r76l]>];͋Dr_Ѫ#h,7c өExX˰'='NآNtbJwŅ߉Lb[¼bf=;8)~)7MXvGu#el3\[?& WjfxLYzZbG`VpkZu ˟JâKzQө6|;!쎏c`CՖ#o=icQeI ;,C_=a& .B財?(\U>Dwa+k[<՚LB`*@z Vg@It]ֲ8\Y[IlVg UgÞZM[oV&r%]?RoQ8X%Bqv#,a%[,q{V-T:lNgϬόBN%LU14'*2&£{egHi 3ҭ2r$e;Ld..%/ SnHz~ӥ~M{,?0̫S,r-*fU(5%Yyx딷S|wM,vq 8̎]\m5%'8Vyjֲ5D?ʂM5]9OH%<[CL wҝ"|dLao?lձ69ͼuVp veKdƃ.Qs9ۀ܆B`*~4=ް g4rNR_ :Qd#8I#R 'x[4f_[4oVj]SܩnƖjMVĮL 4FE[&7#{Ejz<ĕt,D?N&Gv;Ltk,}/m$ؠ- yKuPNے Λo;PU\y[(趘֩rur,׬s$sՓP[n ٩'#)L衃U5"kO2`p'Mm =p\_.Őү[Hup*W"ђn-3ipnmZGo> aY^)/OuvbN LuƩE $Ac\뒅 R*9G,&Z)AڱZ_!хL]1SQ \>Ү p0`\5C$Yfka5HÜIo3eq1KH;ձHJy<4P>h3j3'Ć ϨYıhƓ~ǡƒ6#b#jSAԿљ2&87l?+en4`ޓGtޭrѥd{0 ]iw`RxQgl+;S.C(.L2 rv=Q({<³];tއ9]][˒23Y:jt Rvݔp΃@L1*]K0zm-##)~B]GnHR(H+N)HdF: z+c^3J89^zm–*:ә-eKyq+q4z_rga:@X²:?vcyf L)Nx_k ^G[Ԇ|,MIzVޅ]S8yAwUjC.7-b#3zX5$JFH5tT,8}`#-J1y{ͥzSj9\ډ~GGr-`wNܱ{n29 c<ƽ|{:X*<6 l ep|ȷ'Y{JQCߨ jbzdd\(G3a@FzUz۸R.z3F\̻ %_JH`Q|+pB*⅙AV@;Z8k+$X8g%/>.ȵ:`dlD2JHhR%_z>uc5ΖqYNפ*qCMLfe蒼*=u|LاQiѐ\{Ar 3eqVy!?bn}6.vKkW[5 kH/ #9pobES B߬JGX-͇vdugX3˱zF"poSܦBaٸ$œr<[t%Ԏ}t\U׍ >I:%7B65qJrm5C#9W\)q36*#=L}2g̠JU)/uGLdzP3=cKR =.a@4A+c-m]FtM\&=2Uyϵ-*#eZtr;j-,urMd$PW**oz=+ P~HQ$9pFvR4&؉cm7ƆxWr̚iIW2#^wdPҔz.T~(K1"mIjuNIz=2ӕhM6T4&gDvF_#iG̓z$zn|`F8y|bK+eBHap[,LYI {kNy.RZMA8P̊D9(mPyWBӖ ړ!e֫rb/^lxմxy3l?AʫS48Jd֤XyFr+nYOH b/D͉ B\![$د=wHʤ\W&QR4G`&WٱCVdFaMȀsv!3](| ʃd7Y4מwK4B{P\>~R=HgYPp$&-4^NVUlD-xMyuMig:慐)ݻCLک'#p+m+1ĆśoZGՄ9HqPڨP X==+ -]d_܅1tI ՓiC$B \ݝAtjcΠzݐW.:oN"j,qX!JT(I7:ƿ "STi-FmQwcrt>C8Q)5?DQX2uψͿF*gZ[U93^b :w:vdanu*]B1Fx qY/=n9fɔ#X(ly0Ѯ\@ ;=vQ{q>/;k:NIY EA6@eku&:0%_&*nYAT8LTrˤD1.=HвrbۼH H(p%յ(3&)rQТd<:n1B b>ca"B:Y2W/G+"n!|Ņ=$:b]``l,ބt΃>\<3TPU65We>}H p8w|^һ&vpfݙ[[E|Ӟޕ"avHwŰ ,T`0mLI$nƴqPl8i0:m.WQ-[؂HK'._`Bkg)j&{m<@ih6ݒk>̾>KնJ6OZncڞ[KQLs5(%+Gai_/ߡt 25h8DE)Qq+m:ܑ iurCʨ&i+XlZɱ4>|Utʳ$eP@w p KFgT*w*f*)cenh1x{zEk{Mig/90j86CtGC/:LZD;͍ tY-ݾ/%3De%%Ğf黬%b,kѹIZv}YS9$8kZ7d0qVNѧC#UK((s- ii- r ].Z *5"}DVB$*bUNUZXOb@2y,t1pSVҒ/FXKFZHҤ&GY]"&[\oAawNWR[ d7kI5i6|2֊;3(`)K^)yM+S+"+CF~)'pѪz"E)]hɔѭ 쯽n,.2$zcF+˩dNʭcqMwN0Í̘n;67{\S~7< .$OW O+^ſk1UTSW)'}fx?r+6]%.|%:R~zO~gsh)TAUѶq*; YrC$[s"ӘY5& HLOdYreaL*l*?f "43RQHD3kwdH :2)NC^s Ǜ؉%i~<=#{RTמeD>S iUw0CyEIGRob:q7Hg )R(f4㋯Gjx$om^k¶@H{=Gө&KM}zŴ[9ڜy=7,&wj- <"e3L0u*fiGo&7꾄$I-S:J yF}ʧH C=OJ6 ^쒗 ۺ DqC.,ksk8bO;~AX2 Lp.Nָsl; Wi O>mVrw5I%C &(׆\^j, Lk^= Yye %L"x3uH95@Jx$U%NaX搃f9:kNFߗz88_®щ^Soc$ JzO< ]@)Rb=|߱~1qгY+5QA Ue@[8C:,Ukx:3cӌ}W.K]Q9sfxݳNfxRkl΢ƠڏC7 Nbm' }/ xQ\UwxYw<8@eʗ9)xΔXi_p5/Ic9z:x\wzFNP*{[2BͩLwSC5k^B@4 = Q)hk:9i2WiX".㋢V% aIA0 (GG)2_qQV4Ӄ@B\b.L a&Z%(&Kc\n %Q<%֟Q.kZn!{s^ѤwnjG"\p1mFJ>RaxDE8ta4s-#-?fڰ}Yfљ-e>Z|hzy7E$Zm^^7 :!F~cZw72Y Y2C~$\u9|R;ko_+ƵhxYٰ֗(vӸn 4wŊ- J#geX.1J -w¸whOJ"('C9Ы͟w]./Q%ć`0`ce:VE UvFD_:j_k$id%v]pNϓNM86kE7y0pF[m醴.A햦~f{gj҇Nd!-`[p&0weK?B"g)1J["3Ղ!Z>sĭf(D}`)DX/),I.\!i~x1ibLAC^He=7$IZ6थ{,Cqw~ߛr"N\4o q_IvתV(B`)dvkHNSAĽ=[Q̶+/5Y-W`C#dm)SRN~%42"~F}7gNssQq zT0oـy(0 ܁mD\>g2͇T(][ %)qaֲ,WyV M3D-Z^_LOf=ev*FGQ`lmk8Xc 08`UQ!zB TgÝH5Gn7fXrKFɘqZoҩk#Ⱦܚ^RtC{릆(˔ i2 s{ +HvKAAwVF#p)̜IԽ1~i5 s`H~CN:3D۪d;vdN喘5vFJ TMu(4x^g} %8[ EÀuDDb h(-(͹[yb[aA'STD(w @m=H6/#f%Iv<&(o6lp(kİk}&tmth NѬu΋'؛}`7MHiP߶ P.TPObwv;^;`:l_'g%$o~t^4U*u5i[JꅫY0r7ųQ ywu/JEZ}qiN[\hCs$RX2~6#"8),9({RB8 @ؔW33!3fg/#7O@[Ƈk2eu5Gމ5iBC+}M\Ǎ[dF"S/`jvGؖb{f711woO~'2/{Q'f<*N!>*e>*yC~>~o?9}??}P~̿Q?7!pW㙫@g>?3u_@ &⇯>ڿ~?>շo?/4D_{}p.ۧ_׷?}^[_~׿}ӟ~_~/۷W@}׿˷)'tlD"p>eG r@N,,i  ՁWP '÷@ ADUnojYF\S>,]i$[_J5Y6Qo`k*fkeA :!> 7}+;q8hlEelQ[P Ҁ LBhS=:YRحt3̋*_,v0ʦ J[հ,P>O4Zj+x]GŅӊ8.|},].2&|| 2SE87.0*5LC1q!vY~𬿟6-'g-f[-[SytG#GHܳ"znbcPm9g2BͶ ~bq&(ڔw0jnѸ-a-l!pv\N*vY93Fib8n`݂V*t[t]~ }mBp ~2Iӷ\13Ȁ[;K8w nJ8!Yb\@b[Si@ֻ3Wr4R oD1+?}|_j%q{0O\#0k1L6POBy E:6ֺQLl\93* $;]0Jr䪞B|R%l?dCWmR ǘ=wڜD]V4%H5"]NKI@ΉyЇxƓDvP@.@jw'rl$&_)'X{F,aО{Y਋54Yo>՞ l+8큣g9#Jq\hilKgNÞY2gE/2ϟYRs1Dfp:߂^+wgktL#l"k;vdZ0' &嘛9FSKS_|s)g(OTr㺏4a)I_#+jQtaJ ,ARBru> #=!gSw#zbQ4.7R %!>?hBףg#K:mTo GXG\k'rKW~6|$ &HL׊Yma?5Tf'aՒА|D94:\lNN(#s:] V^ nJ :Q(c8@ );p}4+Tk@+O_^1@do=4kԱ;o\1~ 'j{/l>9p Aճxe}z ZrWRy"2h&ɰt@Q2{6zusjZjo%o™="&lfa>v?Q@Cgcq!QWϱcxoJ'*J5cgbL;wdK_s#NMU]xT74Ӣ:[.Ŧ aG),:jyHVT8 }]<,tV%*k0jzǿTC`}]0δfI2 "*!2 &JWD=٬f rgAF׼ؘKፑ@,?"t?:آ{rUFkmJВeho5>3&6їr9<a=OOvI_-Q=)NfAx,5xq IBέ̤ dISdسGM|l{RbӜ?s1tt`J.[Iu)wtSC _- eŨS]FMF21W۠nT"3;eL"nY ;}XmG6cS! SiBB/+( <*`:P!77AÛk+h6CD6q]6 Un`x}^nn]: ^#d,U@!vi¥x˗+~+lX>㚔 ^i+D{|QpT9k02U*`q MBd_u7'vC!$X,xHd*iN,xQ+ RcJRт-VH);VGdu_/;yC6 j^4Yy]8ꋬ28έ/mAouG,!4ڹE9ȁ6I*كbN> @q`JgHg%g(!PוC&vɎUɭUGf|5E  LP/A*@z5j`^-_.TPrH2Mv0]Ɲ9#?+{׫!,H:☣(®^9kĬ <"GOx,kw0OG(K$އs Vn:e'GK|#4=إT[TP˭s#^ nyPטY-5Y߭W"H@J[<iJt ?mtm!0#983rSI6*9 gh۔<#p<1s=[OI}q Kae6KGYŽ6< S[ NsA׉|뾷wn81R8|ak[tÿ '  ?T!]jO}Ax\jB.h8eg 8L%TBsJ^jm;em*ĺiͪ91FyRϑRMD?yéHd[: ]}hxIF#PXJtt\XGAm+sBE߉Rݸx]+&I1)&C[2_AD~{(}OURuNuV1rVR[Ab2}ZȒV@д S@XO_Yڹ]6>8bH͙eVpR}sM{AO6M[;q.|mv2aV\Mt7Y<+`G,k$1D<s/W)[&ǨQg~Q3+m[HyxSwm<މM߬va읨W׳RN"{u'e$n#s 6MoމNv2ς>kiU5 W?3}MmV6Ta,v{+*LP VY 9Mˇ͋ \!i$h9'v>:.%#>:_%0P)Q̨>WJ%t.2k[±2-莰sg!e/K&q}R߯HV־,}hQp#օT]}-\~{@ ßTu|a#=,EZSWjN;rLn{Gزڽ[lƽM}3U+V+1f[K$i^? %KL^DQ#Am/%}}mk4G- u~xө%0Rm~r-04X2 *4W>.mEK^v#ٽŧ#erUIvfOtIF( "GĦZ_4/鄓6Ǧ!cZg[i ?k6$1bd z>:}~:< T)o 4ϱ:KHU.{~#y;d?^?:'uN9>,.H8*T*ѦӞoUtMdj}[;R;ŝh;i{eMs}}h!g͛{^L7+(GD;SgO)^TO 3Qul}k{GS&ppsC&gDcx*PE5vRQxwzK8=#[3VclYI{ bڡhI~uzGHB0R8$1i'VxFJAҾ6!(`ʲ@%e;<"=v2/m`zA12%1/kHN:ib Cu'^yl'ك"y~9ߊ͢,RjdJ֞g=' FJ?AVjt/p&)TۧJg4}s/KL0{twt/* TjyzH7=K)xbGmJ^_+{@qkag-vʠB"Ot#7vv[aZAꊎΙZj?C؜>)4Msvx4"Xq^,0 `19:%7խ|3cޙ<̞mrvcClGs嗆K1Cި1@~!}R} ܪ́KƳHϢ-Ɇ` Hp GKB(eh_$ &ejlm;=>x6$H@E Ҕ6lN`J-08ϳibB)CNSS|8rNvr3NSLKILj"8 ~NMs=ۦnkb"#Un>D^ TRor!ca83ގRl›x7<$ FP̪NM vڷWR[o u vI!T8`G7LgqBNM뫟ص?3qsp/JגES V8Zl["tZn Zu+5Gwҵ. ;8>1CRsw$P9蚅.gF<.=)P\EA!Dom"}CA)dD;'E2#ty %϶ >`((cպpB\^ICYT-Q1Qufη ܾ62`l߄ ?nADY۩?ljobٱs5HH;gZlk:^{޳0D{4 l9->z0jZEx 6##sĆ};Z]QxηyevXx\F|]ng Ǿݎp:v:ct>\&tO{ίFlԎ4 K - qs˷/o_Z- ٘5SsSua.,e8W[6{Q־>\^6evrxg?Mh֭ 5P quyڭ=>S7W^yHXAjhS̬-!%yo*`=mF>}iV%u(b%\6muu#QY#KIeLQm$Vcg,Q. nk}^E:2rJ\lY4eUQsfI !˰UOٺys\*tK#7aT NhO\k[(dNSg@Ctz~3r;ީWȑR9cڵ^3NK7$,f>>_Cf5ZjSLrYvH귡ҿ*zl,{ln2ٙ8眯iLGQcA-I?ȳc ]+/ғQ- h0ql]LΛ|YF/,49Q9DmeA֖HЊs0BGxnCcy1 4 8$fcN}$7SbaJWPZtiRTiRnhږDI $GTc>J[RCII)MB6(t3b^ f!poB.rkk f2qv/%[4WӶ& *J&}/5cm NAiPZ"3&ɩ2!+fMœ8auh.Ӧ]fFͤ6>=`D'^o7GIz>/.-b+7#uG?k>]G^| U$M Ҁչv~[(Hq ^] `R[ՆG>܏SKa&;X= rҬ}ʦ9xmUmYE53삪vjL,*h=&yu7Մy1]#3̙Jbx[{ 0T2O6fbmm.&pɔ2ӗf䂪rh}:px#L90c 뜴Np`OYB΅-sW,5#zW4A-p{8F.`5kM1a92}/V 洁̒>,6l_5'4y.`N*mqv(%6KnNzg̝ء ?hgP򊴪0rMgcZ5k @beeao=_$3ҡ̖ )3>23pvis97}།*5A"&}yxzYax稭+ݍH;tcS,|Ͼ۞='1RW[ľֺl;1l tӒ>:(؞k:9]4RtsEFSZ]JfΫb5 iܶ>3:)fhyK9v$X2=eP]Ub@!(~h: aO_tZ6܅\leVLas}dҸ s֏53w b>'r+qYjhk5});1ᆠ@s3.S0|\z ܜOoRD߲(fCsVKyu+|:}{|+"s s\ýBZH=\qebI#~|He`7/cƭ&$Đ_gN}RNfūV92=A˻,4h|ZdY.q66[b[ K/Ifi] 2p$ϊ`s'6-,Fs Y&2i_x9@TxMnw?ҕ}_=?V=.QJϵ́/ܘ`oF( n/xH #LW賀Xu.*PP&׻_is\QՂIKHhJݦ+v˦tۚ?S$UȺmYGhBLp=Un+eh'u.s['v6奀]n;ܓؑitAOn=r>Tә I'/p^Vl-^ FHg3m$Z#ś5DTG8nԆ 4:^)~S"n`Kaʨ=SgXtnCװЎ)fNwE~Lעǐ8J[)yrP NBƨCmvNs{f1׽cX07 s[b\@sW/%ʓA 6-<8S,L;J'1,e BHbGwnszAQT6Dw?r=Vd n 3iDTJ@ *L~~ӽs趟iFxl2=kA3иgNTu{.lMo .:u3epT&H5u4h)7yEˈ|]qG wG:=\8SZ'k?8an: ^t+n]Ri-OHʡ#AE{@%hgZRK?3qOՌ, nR*5XbBTwDr$7e ei\ݩw5r^G5f9V}:pԨI@r* &3+jL8\ys:ЄHg.*u((Q<`TzfPWap  K]-ZX;7%ulr? EЦh9}|g.lSi5:Ґ/ZEJvjHM]qrQv_E!yKނJvHaE6`7uy=>fι󑆂 LnC">Ș`g 7O4p9TeA9*CsbZvD"J\\bA DՌ\}(mFꂥ;/|RW /Q^>!=~~Gl{? #Q_~*=c3c?_)lw`A+[}xL˷o毗f֠ˆ3헁Pj'QP  !FN 1Z"c_-UN?a97?|3볉d ImN6h/bwkJwuhXtJM+UJ &:X5AoL~& R}fg;%,\+#^} hDօp fiJLӿ爤ͦx0zљ'>g+$Hj%>~r܎ATп/?C&*a|w71V(#OcGe>p\>nWd?:a!T4:tx/] 7щ8VF[YyfsW)}Q,r^:'V+WcB#0'/ s򗞤^Y~z04ޙ>VlYM%yIͱC ~\z_z'ʕd }hgR@}zWl.d_1+qLwԫ30ٖ"Ɗlu.GND6]9bedQtDXxiޥxpAfl~v@. J%Nyg8\tPZ#tVRLagzN ݽ;NE0_?>if#֑S V!lplBa/} =[5sIƞD#tI盶R\#oe9 oGaOk\)lI/3>p: -_ƒ8&EQ5tFX"&Oi)f֧e}4s {:5ɆQ %[]%̡;Bʝz;;0kjs`17o?$*Y֘ A\MJ#u&!O'ZA#bX%[)L:=8 g/6smT 76"Amm ;etࣥg(.|W Jp[!YBptO$c(HF T,NJlHW~}o<pe13ElIle%S!N+*t׻>4"8swS aNPAkfj[C@qe؛0Ӏ ӱ Rڱ^L$݅'Oaހ[eтKs+XNO@!t1 w 0=xcK(~Ò~U:}b2ac:{R hĄ .,nT m 1zՊ-  93JsqM '-Ua,kfnȤ/_*$0VXp5A:0HGHf;.@|g4>S?l+KۘbCWiZ ÄsqC\5/tH5Tψ1_>Y?_K Ipvpƌ1 *0":ʉ˿/koB#BoƔG|5,<tqQ6B+ݢ1ښ!|5f Ş3T,50 f;C/u% )ƙcbR̤Dה}"GD{䇾 3Hdrrn̑iw~f%>zQ(4BA-ٌp8TgB6fQ1P* u& WX.ÿVʕӚנrgsNJՙWR%Ctĵ5-NZJـ79Lޤ\"&sCI13 smBa&eR0oo*NiV䴷ݜg'O)78KtbXiWlqPTr{4rATsJ'Kx_ӕrTHa@yA9@*Ո:IK!VT ynj:I)5BEAёA F@GCUpeFڐzE#R&&.o=Fqm I)CtNkjkSDm Q۵@߬UҝȾ ߷KH95@(K&ZfCfzvސbɧ'n3JJŰ NbfjyӸSQަ M5O?dghVRθuH%6F|qVV-B; 3FJ`ZۥFAv= >SIo w^ R50j(HgB8Ue8 VGA8\:tr~V? O jI5BJ#Adf6r}Het ]Q.P/YOtų.ƁwHZ=qKI sMP]S:dĮė^'3.#|fWo}1̅{NB %rM Il0`w"%2Z2BT{!={0TrF@d[ȼb` 9JrZnAK)r+MtpFDޙ#,ATU\ Ƒ'cq.5}^t4=q+6N>q0R$1<@eOrJX' ¥XX?w],GBVXfOwV"~/{4kij/oC ڜ %5wq!RÜ_atÇSby$0ƖqLإ_8`љ8K_􁝦[t0wzNrbDHwc !4jy`6;J s<]cij&M wY)S!"ȵtqj̢J)绰ɘ۸`kJ62WpKCztg@$HqaQ:AIXT^nevݼM|Dm==^mlje_[шJ2+ZKL؎7MG b7tLViSU0Y~jgcg߾IEHp˷+y>ZA%7tdV2;3 o@/aRs bw'W%]!vzq鳐ո(!&I] WppqV"J r` {u6jk҅sH_vIFZ)Z.ˍ `NT9T6DdatNqܹkv}w,cGI` źY|=C J" ysLC쭮v۞ReT9Kﴢ;=5]pPrbkl;)g][P X)`I0%pzXUB6!,U -,*|d#C[ * ]2C4&1*ՀUթR3O20UCF{OpC7!m#B@-O0LhE( 9Q  {?$EYU˜@gu O=K(n>qUZ*#0^6{rGNעSZ$&^ juRrP1J4{©r*c:= XzV3z5q3<K lk.9͍\n0]g:y%b+TPZgcrLX5]FyqX~!@q&R[5# Zyi]qiv+q̅Qb[_>'^v1}wEɒwcV~ނܞM nB􉪥8$1&VM\GKiN o2|^\2 0{CشhrBc4WqY9^x*|̇Up#3aW,)m=4W⎴j4a(7K6±5ST#^VV}!ofXE8kr:$u "&WpKy]楹hǻYy<5 "{טRGL&8MY%{;Rqy0+nQ*:{SRr yRmEJ,"0kpέ'ȝG@.aL%eMm(j'WUYZHyP7sxU䬶yt}4ObZ4eLǶ{>Ԗ[rbI T*>7(@S}WUXespn(r=:oRF["Ҝ[,v>" {zȾ,1IРԏxMtg0v15>pT ɨ$eM?mΓ>زGmkíGpW@yNFKQ0s=w*e7߷{Oe@RWiٝxv.!}:m.Y`#ŒrF!rdOZ'NA?.JT6Biynm;ʒ^i]acփ_;('=6iAk=ROM9gq붯^4kjO֓tmUЎԋJ1-Xllu>5y.ua!4zB[^4ڙx؄KNB>γ(ײ`7ZѠ4鐔Bs\db%RneJ<Z/qeFKHU d«q}hAR` k{ؐJKzR*2;K?x e P9ʒ.A fH9Q&^: OVN{6.l2=ˢY Z^eƳ)*E0%g[M vpd#ƩfN>o2؂m^8U>Y0;vȞb 8{*E+P7r7ijk_#gntplMXͪ,[b/R gWδZQ9:N U8;n:&`7A\zCBW_VئVB 5B*k(ePWTAڃgC!$Z  l\XL~ȓ|7_'@#0N<$C'0CUgE b$U.[H}6RB(\)0 vQU ݞ$^D6St/v ж_,Vr)=Ruɖ,*ձp .ad鮰{&A24˙@rl~),ˊd o:VM튳(x֬Y@aCkUqysi}#fxv:wҚinFf)~=dv=N@"Qك sPBw%gp(@^W vq`r;gsS=݅H**9xr("|;򁲦*kW$=|տ:u SmP"YGGVַҦD{vc.5NZEZf&dI q1`(O;8¢fz;]cxd0zϨap+'IM38rM3WiVs1@}Yj`LNbGߥ(z0 λq*]0HN0wHpЎ檾ZN;luI TduSD 5h+r-ODs8sB>TaUх-6=mzIöVJeԔ_ب%: =z+{ he,c Iוm$"q}v3(lۊ`[hZ[dS7V1v$Wv n()ggN.Pj/Z :t*;HYJ(8@[Q3Mzo `SY䟼iEh~ZBjuZ\٧buڧz*otӉX{_sl;ymC-Xr=lF2"/ ny2X fYѯcB,gC1&-6Dn - C/D)i9Z+d=ѕ ڠc=@q H2a6=Ί&hɲ^KvVl+41d_^mrX;1 Tc'=t#z)s{%46j/]M=cvr{^XbjV԰,/}wdp@ZrQ>J]]v&\^?E. B "%Bھv~1'nEf_Jkz">&4StgVMEga(hQII/:fSO=Jx Mt oִCU70t\$ukg$3Xcll)-ZC 9}k\EEQjXM/t\O j-ʘ]A̹a-E/vm1?|%h@H.!:tiqS#;w?z7^w Xo6Qak,Z^fW7nzǤu]>*O/-AbD{J*nKcqH ]W& %qhvWHIMW$;p; סJ*2FNSf9΍p#@Y:q-<8p^ko3$hscyY#[%QF;nKOBC:)]Mm]3Eb_qVTْ#NvT'Yǧ03OrM=oG?US~󭟿 ^yUv뿵'/>z?~Rvӗ>O/ݗO~˗O?׿|R~sN/G?>?O_kQ姟E2ן?4~{^s/Ͽ<ѷ1|X>zٷPُ*~%: m :B-Ul?, q @x|+J XvYbV3*RU5g*#uC19ۿ7э63oKiřtP'Ci8@ӧ=[fIU%l8TG#Ma;M[@1ꫬ.\ w_p My  jWɼF2G_2M- [=%\W|+Lpqs6z~ n|V^01@n@i6~V_X^P+8' Q~m,u)s@h|$ZH^CS9: 3@]3D\4)9dWwCԁyْ ~,Ĵom6_g>ab8G{o*eʆRp~ޒ& ^K!nv<P=V}b[=O>ۨ#)/{zP)eÖj{򪅢2vll@Gц[׳%ee:["'m0U&Q>6tRr#Ώ4#7]<?zr#:w|dscBJOȈ;0 0nL{drng t"1Lh]9a)^A/Cr i/bBkOi~2UG\H>R=rN*X0 (٤t>^l6f;tXDr&kZYP%Ajvt+2%&XDr2*>ZnHd$?S 9Nts»P߽CKӥ.w[s7HbK=:cdmr|p{(MÞ>E[s|c(޴\y<ԉ3ibk<}O1aXy+n҄n-5Dxgim+X~ 5I7 G[ ad/$]V #<Pb]>NBc: ˑ 5vt;Α< 'M'\2PR2r:&HgXQMl,|G"HQCW/e=gu KvMl g%lYʔ#S#RҼpJ<{LdB]~EGNGiZ`S fMҥ|AF߮L@a諁֫VLjAn`Wdy7SN;;eNц 1i)ip )>A\WRY<yJDWYcT [@{7' [ RSjWS\i j. ۚXR-6 @Y:H!tQVЮ(ܹܵYtSwݥ| t)$r,R6ST>އY6S]'HuwRV$yL$P$G \j+賮1cr|c.ZST:ֱȳg+eS -sA[NTVKO79收:CXRIekr 4TϘ A>GȴLQ%"[=B} PPP~1"p$"ۭvb:5F`0t)K4':I,rct/~Cz+'mͅ)Vv `_3XC#/?t %^G"Ҁ/W)iTG ?Jn%t3otqV?u~֛gjs~SR1$(W3fc]E {e"8_r_ ye#VIreP6dhIVE߄t>: A7EpSIvM"=+N#>HUX32@Le+K-ti.k$)9HSR`V3mR5[e3m3j):c:۪2WGU]T'5Pѵˮ6c[lJdYF1U x ZP)7cErPj$ysy-ԋP_Q@e ¤wyͯ&maӿ^O̤1#E1z eFb`}&YNOG;6ɲ->0PB&+ud#ksu2{ `35/uE]S /r?@ihu2hWh=P?XjՅ)e7d m )wW5U9?G6#l#u wVUȗ8%ELQй]fj %8?* ʹb[#gE=1eyqFWVǀCY!ĕ.0BZ  hRSQ_E{/p3-ׁ fSB"ö6"']1\)#;XۡW RwHgÙN(K%5մS~%=iJ#ĊBM'J3Ff5:d:jz$Gnl qI&.Q5.Ok0hǔ%QExTޝy"wFwn)%}s^EɀM%ZG640l-ѴAPEI<֤> ٦3\lOc*휧hkDAG3W 3h$)|8[_]af`/"cPu?b &KX@ l; []*%H vi26ib/*AlVQԮd;l=d;&CIxno@G2h}ʿY0\xq,ߜM:R[ʭo߬6Ѥr4Q!QxH4csְDMl:&k'lA|n)˜u8 ,",n٠7\9^,1jk+4<tv1bxzDΒo #4rݵqޘGS-mBUZ8g A^ju+@\ ݵ]O\ /|fHk׻-n/cd;}9nt IE\ +I׾< -<찆B懮WHYy=KA3Y\>EIy&Pډ'H)zCFV_~tG3)$H\EA]ͤ%Ir)KZ K"`zӮ1q]aqD̆HdZ@X0a(ҩ$^.{F:c}HCLY[Yn`>%GNKLqԼ|Q]4ׅ[0ȺfzW"͕3ݘH*# #hZI.w Κ>32(S̰QoS۔ RۼRC`tV uj7ч"yNH M"-.=넒p߅tOF(d\إFxfnd^n^#sʚUj@A15WRc{H:ܧ2vu:4Z|ki\_q"]Qn}sfXGH#tD@èAP쳷xD `FܢBO *ޔݵA;jcoR.5tzM{h_`q'[J`x[̴@r^Kc2*эZNz&z )N.nj6OQ]D i/nr8% R{? EzC;eiL4b6@TB-lEe>ڂĒ tiL 0$x߽.g'ȗ7 "WB\۠n@ҿXϧZzᕞXY3 tA3Lq0ʑekO&]9 J)IY+4 S@|[ʪ>zLdSXhQxa)u|?Kp`S l dv&t(ok㽷`Gx =oy;M5}ëMIsGN䤿H+8 ۮ-\@<5)!\<5r* |\~T#w؇PHq!벰 nU]o@`?O`æ-x=)txj?*zZFz(nܘk@S5SQGRd"&[(m㨯GZǜ:ja8UR!+6Ae5bZ){V={`lt[߲8"ն Jp2=(MhBmiɘ m1fK=HM֛Tl.U/kϔ?RW$5`b/nuc \x_s:,jr`d14戼QK}qυ’=ZQsVvr~]fg1W8u[14CK5XºBh֨m3CӶAZ*V$1^;o42 D)h^;;)<( {nFCMu{^mxLNBg1]zT!K`);f9#HlcLə}mSȍQpTg:a4v=cB4RQ2źwlR UڸY;}cdљߵw㩰e+h'FN"8?qh:Gcgxj sf՗H;x+(jđN'rwlWnTXlኑ.=+ζ_>Jڧ?`Bjl;®f0ֆI%~+i?}PZЮXmDccSUvX,c 9f$fqw =`^˞-5,ZJIE9ĊM0OX ;e6?tb.[CN'$:ߓoomT ́dPu?!ڨh|I mnˇlT[eIA)>j ND8&mP`ju ُ鵻cކdu]=9`ҋ/DX]"x a9JnLXedU}=( RuS; B+gX2 &A^_‘K@.-NRL:v+ݔ.N.C@C:dMN ;1N+cI]9m]zP9/RwUN#&V3; ak13|ek5JUȱ_a2i7$M(кh -rMG#)T6ũa'SͼྙUƍgaWSuE,fqi5_fWHIN1 $~SjZ<1\SL)4q=zv[3XIo8K}8gs:F=x09H) ɲ'ЫyT_.ȱdo1%C06>Cnh~t`b l&w &@3sYwvzv6jx)hGnʕ&Υm6KrTb5+Zh?NTƋICGcn~(F5J:Gݜ(b zĶkT_Ϲ<8aq\OX3|w{vUI.$(/uNwȇsޖM)e@mS)!b=K6]kq£ލ, Kazhg|ɟd0lBHޤ~:8i*3X&_G:m ‹.G`QX{Mڃ4ɍ1p],&0ܡg!1A:6Fؔu%m1ΏklHB&R` 7'r]XN%PT*G'Mऺ|=9oZ-4&Q;CQʂ!oI],kգQ?!D;m~.dU U}ϢvM5̶3O9d :ԑ5)kǜfԡ O|ȓ׭ B-QSrGczlVY%KVVWy,NP,Kx6F9"b-BvR~ SɱbRpu. 3o^u\ ut& \"WbKOxF{;Ol!HHθ]g[diszbEcXOZ6 ]fثwNg}:@x۞0M&\U[ Qh7dmn4Akv;D3 Ȉ-NI=P[ǫ]nowڹW%&̖5v仦 3\47mhr09[gnZսs l2igYi|g tm)fDKo%=9xz&ŰXe=*Un;q7 d:79gu3um7g +5q5nNmӄ$uB ]zc͞%rj ,Lxccu nNgSu:Wo-;8u1i؛ݩw qhנST0ylzP9V<âפu4VF/>َgk+Fuabq)zk "r2S.|'܂TJQt^=J$Z,șpgzFY,)kUuTUC`BGi32cZxrZ:i\; B(0Ya-JVhtb!01KRyHqy9.y&cam76Lc+>\ )uCncG7&3X ?%.h1׽rŒcTZZ3pAeNϨ(|%I7} C:% gT7t&T+Onyv5r?; ZD(?ZNĬvBW/QvS2ݽ3bX=W1 D0rIw?tM&cs[iu,aKM;f ,ܱ 7ۨ._ Jn[]rOd{Y\)2<Œyw}!!rl^I9oj4?č^M 1@ Bl ˟>^/?%~??ח>ϿG9|z;{ˏ}w_~/}?]U!~WrY2|m{ 3:־렼.SxT ݗwA~?wsP|_??h_~VP]v1ױ3!;!*r g)mFNxf|}ϊ_ty1rλ\NᄒD"hu ЁjXnB 1iu:`gՕ_% ٞ[3եbu[O2vCȖq:;>6` VV8C;^& d&1㊬`촙US-Ltml;hlůH`˓'Z֖glئ-$"rFHo%:taFVW[. QtiHߋ7QtmtK;p4.ǂbSxT}J,7)7kV>`4_2^_x9U24@ǀx8_( `|D^7AG4o\$ SO2_{>|4 {!mфꠗ#hJ^{*'OuzcH S5)]ʙh[8v:T1rQ΄k3&? ^FMúT">*px&ĕU.* #?i(ӌ6TBi38%LѺU9\E/<.?e6l ɉ})8.Pe[hF < =I ;GƜEǦnKqw< eb =},emѥ1_{*6HlX*Dtu %g+̲\YR@eKbJ2 (:N?}(N+.R-weVюeH3\ c,;"Yk;{+yp1DI:fUBKy[hjaRH%K!LZ &00HKF& aR::!]I9,\ MQ*?aG7B@ j~A6V]^[qp)yw p1-G8BNLHf9rJ"7Mx&A:jIv{&_"0BK 0!0mN=vշ?W+܈+Xv'p&̭{?CtWO!^ `q'`sS*t- P^{Eut_= g9'\ -~Jn?Ԉhf$l[/D:*n'dWZܿknLkrb2ZbMɒ~WF diQ,ܫKOQ>G`#g59 žkMgR6MZ9D| { 2])wΆԖ' c Kkd@?/p)HG]o7{^uG8F{8$kSJ9eY|jTjQP Zĕ(rZ SZqvUHz Y1he=e:CqƩa!?#f_ UlOޯUC7D{ٰec.D*A? xR+d _9$v@MGڦ/KF(1ɖr`bNi)p|_B9%:5iRڊtZ2fo?F q$/)jyKqg{k] w}\-RD~'dz-#3xԎ [`K'쭸239Ff`{pjM%6q lT(K.a:QR*`D yXI^޾)kL,:tTK}9UL\JL$-חtB9Ҙj ӳȹltiC nlp2 O+XRꇱ;YA[Wyq956Im㕞~o<iA7_i1C.ەg(LҔ:lYե#2]&2٤}x06AtE8vbV:Jv#F_uN.-{QۡST3; "ٜ/W]Tm"cOwzHakG~"np@rHإN-&e![)tC@v܌ \ԺY^~$*H5xJra=OC*v=ޓ| ozA%X6xurϧ}+~\ċp762IHt(^厜n:U EyoEbO_-w&T:Bh=9!7M:2LZ@{Ԕ5$u$GZB5l.PtH}HS*z;KۘLeL폚sXBEeNэ ɦ%tj euA0W|#8半IKPةҴ^0qثRD/ϖJm4ZSK'*mn=|J>}9c Y4yCo0هSE9w]ie`xjT 6$$1zThp{Rsa%떅G5n@b6d-ILj l!LC[-udי)6'=~&b+?IOWP6|V 32*SSʷS(:87krQϜ?Y z؇ki-aku+Vi8A<6\$Apmqnl_{fWzoؔkJÏj1-n63#|@lQ B>w)0]LJ딐H*"9eE*l8A0F6kO3t k@z\DJ(Љ݂ݐ16~sadgYCBTF"nsV^;6w!I#ĦͰN@pј`Q 7^=?uбuԡ#cE8рaIv[a |-piHm ? SybGΞ$+߯?6)2rvPW/z kA7ZҘlnF!]i'n '3˅^e/ۮx|H^]NWz}<#-T"2ɊjV3V10I~. =:]&aKBf36j,[pû^ jGIȾꉜIc1JС9:,z/Ua/#<0/+Y|(/~Qle`E{+EQ vR%M;Tg0he[ \֕WWCӰ |ܖ+xM5:TOv \i7U!HU(ͼܛ\hc܅^lyBIp!Oal-%a]t겴h=,e[֬,Qƣ^=, rަ-&nBAx b$Dkl84ku m_ߓ[(R*pd2.Zҽ5  xf9mەY?uCm9kdGf@%Gac\u1D[~9h9iA-FHFkFmӏm*r;cZI#p-r1 T3ދHX mK@KҐƒ5:`AgTheX)“֠mx.>Mc adD]EgB7Ѧ,Hok[@N,k$<ֲ9]&rg^x֭6 C-1&^01_hkTU`aPnF.,mxx;NA`_Վs*Cڻߨ+RA"-x::jkۙ+eb͡W+7 3.3ENԥХ`N-tu%r7 Y>b#@v||\Ks@dQbb k28mE֝LuطpmaSNYt*K .I8- 8C1wW@?2kD.$H|;nۀD&GV!nC$*^RMZ>t#as I/mT'N.lJn{S'EɭM*ږv}!i%S`Fłxy'|VfdUDm{dptܳ˱t?TЪZ[s(҅ݛ(~K]8+rS+J]n,:@l\Zb{Q8jhV*STKjQ2!wCBE3:vcameXشv=φWv)27vw2BBܒe7uluwgR=.&#䂫i0GuvZLE>.$s}g]S(kYUIYdbzVFMŬ`5pj(i7h1mFYz2g꓅wT+LF *uV 8qK;Qo3%ZǵxUqʙ*q%0( $.vY]D ~+ݣns^"vc2#SN8r qq p;<`xϋ|!r-%R(͚aN/ʺ}Һ%wht 0p `3mKߜ m 6!8-aҢo"𢽱DWcsu7JH(+bnR3:__j|:K;,YީuDrt+N7 nWlPk F$@Zx=ۈiwn˻F" /أ6,` +DT.4T G=ͥ3 (E.D蹠c`,ʬ&]JOޛf{Ҹq=e}kj1ˆо&/j$%iךZĴE$}qS" sFIxF'Ӳ: uK*i3k7;lY!YFJ׳C ilqIF^`A2fxY(2X9RA=&A~mZFKeZ+MRp !̊-WBՄyEB }Lڶ&^$)Y,U6ѩ~H&JjY*毚 6x8(#˦lWKo ׎#GSoF:4 s3O|qlgӚF;*0{s*Y `u08%f9zdY"%P:lPƱvR0n ήDN=DEʈ+h܄JMj6Iʭ.1).Tu6%jMЙ=0X 9Ku']<͖ JdsP'.y/ʦM}@Tm%3()>҃ua0qp+{9:hdMڱcBy;UYm9P&oEw'5چ9Z\ed3(H=x[&0?9p,{lzO(CV [&MPw]L}tayڀcQ5pt ԷK6Yv'jT'p0wXjS&5~bO6 9N{YJlk=)O&7BޑJAW#:&{GXZhC .|3ZP4vrO C.CsnD~n4P~Xxf@+;Y]?#Zjm qgQhi~~Ke'ɽBmQ.p#|BɏɜS},3Xu(]|Z%&nm~BI_mۃhvaAlL_uAY%V h@e܀396v+yمjr}rNʺ_a'P#j;ZO'p:>uޝ 4:Q;,nl7>&Dt2#i1@hmK7~=oٶzCe˂M z7xU^cj>/nE1p,e0q U{S<){˾ [ \B!R P]}-\Yq&]Z[PQK2t66k-:5$ڙ9R&FˍyI|!p|'kJѻVv=Cu E}@"N`8Fȕd-QLT"Xi#1s` f<&1 ?ICQbiAcaF0:|{jbny%zD:aLN0WC'(б%2kl3oO_bP;D:a]Æ2]?~r]1V郣*zvqoNMَ+1?2;^Z HE16{tRޖ1jJyaZRQ%TvhcTD/Ft혝O奆9I'LqoW麟6Qed<0?KRuvH@&~plK^Fii^+W#F(%ZSZ KP BC']˒q]@ࢃhGfaKN -*Ka)C^@N?pOJ}P~T?>@g:_``ȯ˷o~?y~//7oʿ)痗O__~!痿|/^Rxo?9/O?__^R[׿?ۏ_B 䧬Ϝp|S!g)%٘2rr `;@g`e|`F*TGNo?u19M M[) INU˿Viny pJ3 cy:lw2OƵaNVN߇~ ag/EM,4pU(_;<[n vGÁ]k6"`Gc`2jJG;=vA.hSqf7l"d(6,P)_1(G604i&Pg v)ХX_s>n>*uv0Yy;d9CGVY_/Ǝ,dhlF0ۀ6b`R!\گԑ/:Aׁ}2_ gϼ}ڇt-ϔx K{\2F9!|ܻdי`%[ZeF.}P.F:x}aGU(V \2Gnz:{3NQ 9Dόࠟ-cS)roCf>p#CDaȤDh Ҍ}? ֹ|g;F0f昳)q67+y8㧫&p { 1|p (:GYTxJ?csocxp"p):'hm>%/Nw! 9ܑ4e<2;d!Bug% 1|!Tܟ@G`r=,<ρXlI,u'jRVq~D-"#uqnS^RyU/RO I{]&ܝ޽HEj*uA L*j6Q` Oӗ E@ɮÿ/?W鞬!VÑ`r6Iޢ{^Jl?gCw/OW; :ZtJ2dL#k8ytJڻN停]aG6bLCz.m7{[Dp:JjQl΁ϙxkhB:բ/ ;!M3͍50vbg1Ew59vCG- |%3vPXܮXD]U4@P(6VհCkOGzR3q#}ok$pnBuƖv`l[Fcl꨽B۞B0b uȸW+Ecsپӿ2l);`kт> Rg|کPRUc *l2p% o@f"z[{{rPp舴?P8k"Dڿ"N|'<@ "#QPGjMlԒ8lW5!x+nz/G774β{[#Ax{f1^; 6߱Kp6WI%?p}|}zvQu~)(\UzZ{+:W]j1GE/ۈH$C`/!_r079Ƿ=s/3:ܸ#[J%svm-L}M}=G@%"[-06p1-#׌.kYTF-PM[Kj e]:5JxIyfӾe@K3Uue}ZZZ6;ꅵUGsꤘZVb{g 9_0r!UU1\@N\}D6/"`F5XT 0ri9vdUYU#} :rt?jVE[OdbM_` u`P3;\q\kטiSZKXG04ϛ>m>t"FDnzceZ26?@GͲ;5Pa,u )Lb3SfQue!=O{I|mϲukuVyqjF )g9\zoxǺHMHaI\ǛZk]{5!;3L,lARH7zz׫ aTMhCE59Cc ]WQWfm2&λnZH~`q[tBzz7:sgt@zeԑ.tOCj5'B'iuB&QFӆ9LH2qFU)/:*+A|\zfJBtoZUH>@I&'=yʇG}•3a5z\)nY b팙3U}Eo qu7H&s gӱU6u^ NXOy0;S:\6^݁S^g|29&\5/$0bq%gfr:, ńd4E!f=lr+@ipZ:{B4;r$-WBm\$phaQ+3\)h,U1!z`{|y2CĊDIY4w-U(#Bp \T;qB?F|dTNNj׀o'YD=t/L#])W'簵UH&񅩄 ZxS,<={gr:5Иb5 z^ */$jԋdk7/TzUtyȨ>}P#鍳[j>_"|4fe]y֗ 9Sdqp<G棞[rh7,u ƐV2iD^$0 y!>XO4ܒk8 !05r5*. E1F6'n后fyO&=:qm[\%ǽvՙ.^zKL3V7s>D}dR~j 7=;=u:fX 6HDwZ:t*Df +tY#f77$4'lyصIuLtbSrr4.JSL Eњ,-6THr>;{2zv+/FtXC^ R D,8?dP܂x\^__^JE+f<1whߌ5;']nb;`hrs8YnGJytoIO\\Sp9y@e.?kLh $4ԪamJYW{bT u0ؿ}tLQu'z|W!C2C+h2-}`Щ4Tݔ0yl7`ofʨ*ϯ;h7 ڧ$Z ΢Ԕ>_YgT?^~DD}x ?| in$)5dSٲٲeb SW|OOϔ\^rı#b).*Z?MA-VY8ulwln't.`<;'v6Gh`R0d 6 }!yW v1 l\-ʴa_&hر9U}҂ͧVOxFϨRTo)0׻#q"V9UxkPPe@zjFJ фB0T>&M̅Rz6m`qLY%1 gޫV!'(1کՀvr Jb=9#:ymK=LqmhE-Ui$#tG&\YeՄ}~ߝ aSiU;&Wn:\k!l[񢎄ډdt>:uz}o\iKA$ҠUۛ$#!p51Q;iL\S#vWes(Q88Ve$j&XJ $L`ZN!FVtsrw9; Yd ߀ocYi*EK i;|I{oh8Y;Ri{KYzo'~2@Z .U:VVCԤνvH g[jpOcZ |7-khoRi.)A4y[u۳5h|L&nKtX=ԣzvۡ"|+DW ob:67xGq)`\[)xyiKrq,Z 9`R<Ϛ)ox֓&KO^f㌒vu RC75[it|rH䆝?2ls5]hT=|dNbr㭷쭩[t̓~0nBɺ<ߴ\Nc4&Zf/ݸ%e= #I.Pk:Yxˣ3w9Zd]A_%5 bq Ĝ JC Nb;aw+1̱-YZX[*A)>DPmwIk$\&D lNv:n1JۤB$?~×N<`Em>wbZ§'X ,)!/z^"(t8tQ,r(_(d8Aݠ*XmXJ[YXOr]ȆU0ӑ)zmtd󃿌ot+0x#rZ+uL򔊍^y71vm[q9c0IXMK^#Z@Ҩ1˥I"z$l[UYNo沞>qh[I"D8VZrPӜZSf~|< 66;%}%ZB*%4ĩShr6 !%"q]oBGG T`I S3"f`M#9a:2| }g6 W0'/`73]>py#-1a06mNv5| 1xQyqM0So9;\q.cِe?qi6߷W|Ac#Eо0'W}"H8.zCB*1jiNP_y2@A2Jda__e">w^ 6 %A탤eޏ;6 \j֛ܞػ_o~ȅ715K߰C-= c{/^)ݪ'{;:]kԹgf[gvMU[5jzLt[R$Wz g`sЂm;-5 R:ӸbRr '3M]} bt c6GyDJCxܵS귣͛m&6@tfJ6ܶBN &)5 L)@"H4K2An#F]NaF]Jt?f1R?csv,ID(\-Jb i+ ڣ(hڐ\}ײx]z"H)NgҊVfO֎-3aӍlV"He7wx *iUMAW5ti2ɡ)VeaxBv@8 6S97:a;=hDnsDE%C~-(GvR^Z;hI]/e_NL|N\{ ^E9+Y[4X̅~w4fueHv)o樍\/{kC@Zy,Z d_ 8ky>Rِf\VIKK)Q^ȡWYKb4+l7li'+rj]垒 @W:IJԅnwȬJ_fHW3R)Z̔3C25N[`L}47DG];Ήmm=>0g@#6Mv̩vU ):׍!Q)e,/]:3v@D(֕='ƿWERn"t7l⡽޶8\xn9VB&yM"R9١`lKmА\7[?R@/bS5P"íc0rTs!\]TulH-h 5R G`;TSEL@tǣM :m=刋CN,; ߋ| ƇBJ!4T.[(WJr>cgV0jE!P'Ff5rX.3W4c. ]jnNkIлNų9'nAPj 9đI2.; `fMQUWʸmm@2._jcxSZ7lӚa. H:ەgeF Khq_LC@&Y]YdVS%Y(T@K{ɋDPDjbAԢꅲ1(x& _uイA/BL ]ژ607>1~c=kRC!>-Бw' ="cKz&95kڻzgZ-H5}zmRDck 8BtH)!c 'M;mF !Z>g8]5)f؎sg WH욀QrzEmN>tKrz%I[Au>IzhcK&U$K_S=?EΌyikP^Jl"9 Nv\WܮP1ͻe%ä 6ggLeVBXgF4nd!M=v[*tS_^MmU 5M㾟^pVXd~Gg S0?>V$Ax#%86Y\%%m-|[.8v7Wytz%EEnİ6MvBK2vMт["rX2={9G7=CWT"FNN StSAKW(f@T{V'}sPR7`](MX[3B0e[e稺a)臗*Z/S^\O죕+֝sKŗ34vUހw휭qmS'!se٘o4 Uۙsa掌0[qeKNmccGkGuldY'^G.^p OOkpofۄ)uY;(ԩY F~ل=&lMYh^،Yƪ mՕ9?]FڃͣAPQ!wgT6Sg3i+Qf`gF`-i?iwl>xir1Q}L3]uo>n˷@K zGG=3-?Ћ({ ݛ ieI4aKb%o^|سdH} U!Wpᄹ- jzME6Eh h&iĊe1%_4. bf'".a:\KD&FtBs):}Oh0;Y^n wj`R0kk%-)ǣZKXZ0r)v7;fJPdD\3 &!Q"Z]z3WRX=㉵y=m)E+['T֦1oˤk0ǡuCI7_ e6+gV@:Շ(W;W͞F~xnM3| 8:͎s2Ed+Bm9פ=T? dCVkI~61flQ-L%SWNÝpjIݶZ})b٩eq۾iS?gݘϮ{ ޑ= BC2']Ks7r]+EV0 GcO,]*,@ó$RsEO;/}}]w`?S}8Sǚis){~=_>L? ((SO?)˧8I*N??ǟ_;Lp]1qÑSg&}8 Z?Wq,^IwO(:b{ &70gX}o´ $o`qA4 f(g(0|JEG?_&@4 DVA ǟI\! @i*\eC'P1 a6<؈*P)q: sоGX^DA _xgg,1 il/ZeN˄FiU|(>u Bv;#vZlC ?k^?6w=RF4t6dC]j7Wr6w=>zx @j"'odJHa}j=rţ-}7Y , rF88Fr/<>nK+2<|ٲҝ3P6Bcັl h{C}MMFje4Xi0!0E+H uE'ÛLuU1Q+J-=-DD8wagvm׵X? *}z|3”sr>!"9]hOt@Su{vOWKO>zU~彍6P}xl2j~j%tk6?l76ߊj޿' l,(kmT?GlSLeQF`%hw"&M,q-Q˚/)o!$ahtwj e [p)e&Pi,SŧqjQXv,:J$,ғ}EWn2!]>g͘7k޶`P{M89g9<}~etrIkg Y/t“H6Q pA'x&T(~#3 Ub҇Ȼd҅hC`-m[%nNޯZŃ{^ bۼL:=`hIixEGv{;}}}Ϗ;8[nkjDžK›`Ig::rB2;UC˗E Deaym!3.8K4Rޤ:khZ"T绪Al^ADO:hZ`EsuHc͵*KIy9fp oZc5Sx Kn@i̧Tӆ'i~nwpXcڱ `fMlEv|`u;{{ vXp}A#mlջԒ4*'O&uq}=sANEe]Zɯ!cz8t#ڴKiJQݔvvΨ69jG:7鏗fz"E#tvRf28-sMh  #]:$rgZ[f QS dF_1!ZceUfW q>↓ |xZII`;,WQ-oSm aNrDSC' $W놏 V +<Zq>;F0ys7i5)!]ȉV9omj!}F :kyl-e8=GZqb`=@] h |%d^'ߙҝW:)XevzT3ZbC/YQ,vlK;Cfy_)1cVm/!zA"e /P׻ߤGQʌoeӐ#,R|TIyD@iJy&4Iypoծ';2nuqY9̇y- ͋n|9d^ Ym}Kd=c١#۰XoYDV:x4impfLCSMs9N (Xf8IJz!kpWrtbsy13:L WO98Slm‡/^O4-YcCIA$ |y|_QS ~TVz͜#>Vk ЂP5_vkQ=C+-8,qS?E|bnɮ_4[׍Ly2hȴ&r"8FyV{ L;XK/nB1R5/[lbEtDWr@(V)>x-Ժ`'D%W:.+|b^o#}d:؀ۮoqQ8B[-S 8Nak>nc}hTT}b) B5AOɣs$se$먹a;-H* la!uUԮڥm^jеMKٞE._nl0޺0HZkoabHv݈9hNSg *|ڴ- Q\ iZ-ZBw*eZ+H,A.XKzu N eb[WL6"VњݧDIvŽ roU7ovKdd?D*Yh`!G2q8Tި;߁oك|ҁ[c=SR86ag- =៶e4t#Wú85N#q1YR% QcNv6) x)uRrreBiaI$Pg{s()Vbh &IR*/zM:d!yǾix?*Vc{ٸ [ٓ4[z)ۚ|+;slne4rIdrR\A, +f\tFm(>UM18P;6_hOhF6<,J94i1 SYlMW\68WtQ{ŗ:ܖ?lk!jk#[坮+CӒx1NsL˵o5&%ilM_,螬fjJrM@7YI7l= #K> 4ԉxD)\a?>lf4kA08"wyTuWi.m h.pb4xmgW#7@䱏8|V`1S'^qH"v`Uc76+/ mn_%RB' )5';zRmJSd0>W_}.=NzJYuW/a*"x̵ u.?%hkQ|,t]W:~9X~\3uUDÎBލOYt+#]Ad`k0`7P]@@Hqg5g  n܁&jӄAj7j2+t.6NZb.뿇QI\șnƭ?.-)fxt낷L&<DjO(ynuzmY{&2 ?}yiKd#R@\BLC*@eB*L.~r(){_b(gm(QajQW4)(omVcN6Vnvn|vʌ8 9 ",}[> L{9Ewqh7&il( ȞoY")k7z;ܨ;)@E u + aQ"!^dޔQ}D(u0M.CX!7[%oHJ MW:\W.@UO,t}z;p\Yl5\8ȥ4jc( \` Z֠µRGLqv4B>u\ZX7K?+ԾΖ-(E#~+W}^{R괖;~:T(z0t!AZiS]/7 1̧|۱SDi<ݯ|in:Pz`i7Jpi>^Bn ګQΝg=9-LZcNTc7eO!I;>88>S'.g4Xf)L]<{TWÜsni(EguzZj޾LykUC _=iAUME]ntVwT7y`TF/s_riL*FQG~evt]gM\|e WW#:y@'G\2!#)Jdb0]ٺ"5b'@~ d8!p$w >Q4ghӭ?U8>jApmh}?CM3Y;x\[ \y΅)gD[,f~' |=#|+yr=r~ w F Ary5~S~Fܱm71ux]Drte|x]'zF3¸t19I㣑*`B' M:ȕ4#F$@|vҠD];:֠ qy*6 ^w@=YyIm t_-mP'^Di`^r-3Dmb?49XDJ، 43/T r2`ȭ}w, l(p 'Բ GĜx%|O;m g-w;;ܦ>N/q[s!ܝ*Hab[W!M*Qn׼.;zv4$:Tɰ9US?]tֈ퐨t7tj'fogjx&Q+TĔz>loq4.awwu6&|}.tɫl'A'e1yn99:|Xڍ9 Цh8@H1%; ZhV"e/nG S+;Π5uLQWrNQ1>ТUFʲՀ}U\U%#^BoBP˞昁:rN05GHiDqtJaskTv!p^<;[Mb'&`xc6q@|Q2ᇐuv T{k[7a!i=ƹw-GN\?: c`sq"+H… |CltiE<7ܸ&md˿T5->۞2Ţ5g*b2LB'_!alq/p4s5;ZXܩ6tTb:͓eݚULs|AN>~~CGauX+6`SbW ۺUc -M\Qz^A!ÇHtrʆPI KpI>TuMj( :Q(:r>>{-esCTM5ۣe>SR2͡kPEleDo&Dγ~]ZDSl 13>yF[/^+cwEoYumbFFP_: XHt,9jo1Uu0Ɣ$L v?ki mCv}ݒ܈[0P+.+H1KevVzύGDΠjic 4 A\(ٿ̦)"##5rӆkꡔ.L5Qky֣XtR>[8 ^&Dh Ckqut-IOu&R^QD=y.Pn@41QG bvK~n%o{tKϺes~Q n׿G+}j5[VUA<*&+6YcS>Y!r|Nufp-fs:yی3O(DZ V<+w#3G׎E2eQb2Ŋ:\7ί; e$[]eP?Z{U{XQ,q -ČmtqNNu/r*^t&yD)au{FN#B(1ըc<Z/uS'5AtV~,un LrDXs#G.Jÿf#.jϫon;X?l8f4U*x+\d'le,\pf/)l8 b-E(t9ǶC ia]ԆțvM3h#n|XJx*9eD֝wI3؝+z*.؜u$4D,ڨB1nfJaDidW QZl,59 e13%fBێblODvOXPi tɻMWU(q|As3o̜ h_&{S\ׇO یpMh:^ȰNyZpy-2|j;6Kw<ۋTm?roߪí)"n1e' 0vLg\NׅY՝tvr<̮߯@7ƫo=5]E{wp$,` *+>u;Hs;V:0/tVGgY *\3\4ɗxVc.6 eklپvݾZe渎x A-}BI Jt5d]\H %͔`h,l02N~07r)7"/؝sCV7-r9y봌5nR@%A0,#218`./VnlcRU:b={r&jDa :I$x@ane{QMaU@}%djJ%h=;k8KOtboG+b0Yg՜z<ł5a@K'P77+jRZ%vUnPa\S|$P .#r y yd> IHT#-Ecޭ5H!}'p#`O462aܪ2kl)*vwVv٥*#$qܬ>_pyBdU0¥o8 $m,"²cjbUdqD,/:Bzҩ̛֮F N,V)qArwyEΌy03J-Q/FC` ~ܷ?|xB`Y3 ;*9 zzm|$ЭuHS{X8Lyѭi<^c@e&|Pͧg~w\^y~ jqcEFB.E]$2 +cU}T9ykd0>դf pK1*Fܤ#((bJyJ6!✩o, oW5NuG]G(@͈5 F/Im : (/EoIt҂`?cbBC']ɲ\q]B"*k."xQ#(Q&d-xtk[xpq_7Ч*'|x{~{ŻOw~|')K&6?MՇo5g|Ku=M||o,gڦg`% /xἓ¾^/?}~$o>|/^^>~Ï{^ O|o^ח?C>\uI$(S 8(pbO 8#Y! UH"p?u0W iYQuY&Dft8 I` K)53_WeQ e-Rd`CɈkGrI'?_~Xn Ů8X-D^/QɄ(:= 'kzyH 07 %(!DDa7e[?p6c} Q+4RU `>ISLo_1tzvBH)/_0|}o=6,k0XXUiNnt :Fu+f8ONj2oˏ [FԣA|ho{ Je ܛ݌Mi>0ۂh=zؤzQw\ЪNwayߡSrEeV3r~RQgq9r;xH7 κg#U8@7l7!mxs_oƈ 8>ße5ܴ >A!&w՝`*qScI'}- =Kr3+2܉MFgV@>sD$P 35<VVKxA0y6c2=R"=kx>׏^Sd#4{MN?xYszb";/jph.rlE?9}om?+YBg}.Z"sZ7?O!dk.%@]lu;bo% KЋ&g+-Bo*t.8c‘ߧ͂'ږBV3V(A.m9'"A^CYC7 3 -so0dEnM-9Um ƛj ^e} Ȱ_\ 2 bڇ/Vhm)⵩L=Y[o&Xݵ$,weg`Q}CaWl9xf젺' sagM8pp4㴉x'&sy6WGsYM+#O;XRyH&M|iVL˅h_-йx?3$G};Ƭ3<%3R=ގC#f:CE:f#гݼ+v'ӬAz+7q  Ey.s&ٮCkR@H ?~|y}oFOr5Z5q\l`ۨ.gƘ A5PZpG2AT~x?I1@c#u8Ὗ^4rm"N(V9:U=Qkf/vt#Sk>P_+kK-:p "ؠ_>8De6p8P f1oS ؝C$ =7729bTL$~"C,T3xnѴ:cUw]גQ%&r:R1t*~%OG5@Gusy0f5N!O*rj$d32E-.kWa'm@+w3hڒK6j}O+z(溏tR )Fn} >EUӘ\ft8w&?p+A;ϙe"fY| 26CY̼vaBӑK+s{ccUQ{e(rOWWm3> 3uZ4?L߮N_ 6;vaj6ld5FrH1⋕+[2("{"i 6ŗ~uJMW.{ꥁk_oYFX7&ו(1Q+vV|̻nWS y~ <F0ydu;j =zz]nH%*A`.Y9⒨x}q+h=f%w'|7vdjQaq%a5GYz]}LJr^)҇b6*ޚY:\!s0hN؇ HoZ&nGSS|}M6.:_g/ 9ǾFkެL:U@N< S@*,^e%]ltnbLgm ȕ3HWhp>='v*-1 yı+9y{cK%BiʚY],}V`ZA80SJBęq2uD"8XF##l!ݚ+o"@qr^{Xc'ݕ#@6.{5tRNFvL(ˎ9S1V SOUzuk%> +"[E jO*a+;Vô^@^_EBrU_4$ݤ;>+@MEE"Sw]r bvxߺ0IINZ1)N fr@*Q6m6X."ɭTN~PL8y5зwXW-ˑuBŌ*iOWiYJpOܩplo(q≧]nwCJ.|M_ԥGSJnz<ta="+qp3m1b:\t>#ɑi\8&\+ c=r=?e?U^ucp0+j͏ d,bWfSҀn^-o. v#&܍%.f z?y-rkɄZfph/A.8e >QC0űYITraE8ɴMөWaDE*u v2 rLJT<~+c9Y,77Ry hCxA c:̼ 1QSBk w A;0~#熙/W#`vm$ar*[TMj|mn `:`ȍC`vj\Xpe!+0DpFqNhʣ.v%`0Gk$̞7M'3 'raM"`b@ďO(578EI.D{6S]R p<26U[ϫb8~b%7k݀ɫAs5 bSCxU|!B"\[2u|tZ ;TDi S/fqN^)])遴r&lxX<>-r5춥V18SRAYtc4/IK3Տ4%\ӎ_ \eGGEe#'HA U ey̚ϒQ8tΆǠeܘa0y,fsXXU9Ctg !RQ(s^WδFl몐M F2`,T᪘Xuw X}h9|XBAUa8qǾuY& J=/s>àI̴F>ShN +с-MŎfN=9Պ{0}o)-?=SH] `-.†ykUO;mNJ*?OkUܘtִyTC!B cLz:lMkJp]r5)=-D `Ci|؃[xK^퐵GO%2e9%f/v|Մ_ZrC` s`:jAAUvwjv\gXRWfr+X'D$b%*l'Vr)oV(m C$#@a?(M:J7)n&eǢڕ18c"޵cJ"UKd ^LhHzj)GW-␪*iVg2]װb.9 ,kFR:Kv-橬NfO1-ayb4N\W-4.Gp؇]h-+@ ruMɕ4^㮃kJJ/F1e/n8 0$5>` 10 3 3u=z1ձB|c^RUܯ†70fRhY Hd& u+T>JE څz9ե>uS|Y֩N^ vBmabnN$fq~W't9*+5)0L@G%ojulwkM< Gtou1bڴ>[ B.4 2FۿǤRަ,H')Jk5F3R`)6l@۞$&ךj`{,:zp'pq\yovUŵ%"P(-0.Uz%HԟlkÙ-Oj}8ΫqqŐl,IІ=@uN&~B?g vȒZ{%bp4C|hH囋7jd /|~~R WtB(N N/;cգΔB\>M̄RZKXggVdD MjӬČD>ލ {fs"mNRC]sԷ~E2oMd!_9 U'B# Ðzb}$Ҏ 94QRuÕ* ;}k~Pes7-R&Wfgl*<-wK7lGӆ WEr:fHkA.[.7.E H[ʑXZuugط\vt6԰ h%yuq<%?H\p3x& 4hc'IcL(-ףt⤋5*amn$~nHB_lfi HtZ!T?5mSG`G Ak5#7a JA u`bo3A_؆tHc>ӁKU-X_B gr.F:Cœ%5Trɡ#n϶ pF^nf(*t pUmdJJ]ijpzTA{9-2*5hѼCJ'rIg̶5UWvڂZWJo;Hg^Hz;9!v%хcJ{[5Kt(Qh'LC8K`=LJFg/5O+(㧣e.װr'u<ƈuw3ӳdYi@i*ߊ3rԌn-]6Jh|UIbQNgĺjjF>%WRjt2XJFԊx$탎oN,eZ( 4Hru5Kv[ /qiJ 'RKJ'Z\mE\f(swàJ$G#KUwB^WL1ۅp?ҫBg{4TzF|5lR=^U-6'ꖒ$Gѝ#VQav2 ڦ_XZsx=j?Dȑ-;]W< b 6~YF) 3ҍWdwN N^tL<0orsNM޲V̾؇C-#Ii34}Q_FyzA5f8XU՛KlUU.jvщp&aC#wkT 7e1%31նdi^z3Z丼Ffh԰/f:s*<4mVl2SI++!y]Q;GtkT=rz(fEI#ꮠueJr|LVl3#4 ̚[RY*&Inj{%p8s݊˳iZ]=陪mA| 3 a S*eK"ؤyU1'ufUwL5|M:Ӧocsw(i8ɔ;M#V|C9Eg;ǏU;zo߃(2տ#pYH:* d0`ѓїITl  6,KẆ6^/ga!csB&usVcFEcZ.ԍOntNvc;b+ E;(vV7UY¡ J3OߤV[b D'k2ժ MnLZ xv;VvZr;6O&WurO , X Qa f :1Nil .pu={>BLNGiC\6扮 I7qz75SºY؂[1O!Mum~:hwQܢ3f0RL#Ku,U9jFqz? 5l޴.w^^9o_"ifUJ}啘ݡ+0L9wQbZ5k Xڰ[j8qF& +sMCY"A}7]N(u5'OwST)aR<gɋu=Cbxo5UWS@6nc#wSSi| JJNn3I(7Mnx&s?#/m@z[v2t]ݘvmȅ2ZPΕzo0R TC0^b5I_OSi. tR~NزzG²|lMohЙE'bT0LT9)`ҿ6b{_E >( ԇ5V׹Z툪J 0B+k>ݥZk8 ;O({OL{;h8u04PO'ͧYo'1SV3cj:oi T%}Oc- 5j@[1[u0u=4Sf) v8>Ǘ^oF'9_Tm6}*ȨN3 gRUf'('V6lR1yhY_o`4UK唻) Nv/M8A[N䛠r?CY&4<"J'H,J%G F%^@EjIYoft3 3VlU1E}⟬}'P&Y)]#u-$v B=\e1KIEEV$2>@:i6l*qlpJ.h3zA+6)GewɎ#sxiPSA[$$+_)Txg;)[Srqerq'fMQbTۢwm'Ұ S\QS2ªu z]L9CKfimzKİi~fhG8uCyk R4k_5a%i25 ZΐS>yTࠅVҭV֡cz;brQ:L72c-D@̑:[L8(e4W7f3rr@{ z.'IJHv^y$I햙}W[9b?I$c\Jq,>-& DyYwtLYj-Z@#Jt?A\\ lNg|4S6W!"+xZ!Q׻Nm7U|/6m^BC(]rq]ATֻiGH3s(Rzu:39d潜{nV7xBx)Q陈QO?G3^=L|A>*WFk? :0ė۷/<~A?˗=s2Oϟ>=YOǟg!xxz~lO|?˷yIǯ>dC ~3K?)d33p6 `zx}xA.P \aϠED@Nzy '̀DN$|95+;be.Xpр"r_;r5 09`%*6!h@v r*Z*JwDZ=lo,LF4l#lg`+EHvqOL*;a>ϡGweYJ80Lf%Nv4==3i]ζP*Od/ o\!;TP5_"7edЮ,U7K]a')LFͦj>_ t]Oh]Zͯ \|BppI_V(t򬘠G@~'p0/h+ea>} u5; vd촰Bjf,pbyl#NF|b'NT-et@P0MW}CNǨ'E@g$VguqNZ{8Zte,4wRςbW(j&7Eؘ`D> 3PJ<G,ւNK4*A@@ (DP/5s@A(.|!7]PxR8. #lmOJ`{b5{Zetl|VI#Lλx-~/L&#zw(FDp rߍ2]04J0NN5Z֞??כDa^Npoz|s:{ 9i16å{US~|>їV/R_GGD,Hu3COhpJb(_II75d#-~C _,I.RϽʃF֣27"=0*(S"iΉqot~*̥NF+"3wPH$ǥx3@P=s M ٍvǙ\إ؂!06>QKDX3hP>c@wfJ }I)36]Dg/_V?`ۍ_ݗ7={5a.l0 6SpH'wݫǣn>aeÞ0y Z/nW3?~Ɨ+uZ_Y+S &7ȟgq:1|xd B:^糎fv`|gwrEΟ@Zs"Рf)e+m5(X}XveE  m!Ƒz:ƥ,۹?ew;؂-PAok׺ "9rܰ{CxR dB oKE \wuKI뫛&cU0\xOsiLfs*,@N6 P-C3 Y`fǂ;S 9k:$nHՂ#Aul`ahy~H 5>ӹUn YiG2R_[S:`F}Z_^ӱ)ﻀYw,StQ xdO""Fd:y j6R5^5K@=MmjL1ndbf1-?usƏ//1Hw#U.ѤǾV Sj$ :O' }3…:ǀk03דkSCNuf_L7:t RO#Xn1͹qE{~bV2GW4pDBP{$f9b81ogޓ Lj˃튛9`2 x}$QT:`~<!v \ KA ?!z\N}nRn9}1{ɍڻH|*+^$0;5S;\=~JґqHݿ\PcȜj%/S/2Squ&( ( pfx"I3#NN b5AoqAsyǴgV2_Ŝn~ͺȆ `@&U,CS\W\ I!b _Ρ^LSARŬ6gdd0drм\ S֧y<9dk㭇:sGT/{WםWv&ѹ V.4ఫްA `yr7(wKNj_HCQpxԻP1"N0dCʕkTꜥ/-i5fA)[8}HBMX{Ɣ@̴GVl8*)΂QfhJޗ,U:YXsUϗU7R~* LyЯ2JeL];^j`"Ht-7bs 0Xܮ{yO+W2Q]U48 N[,5(Z{~Hc-Mv4z^ښe$kE!Mz}'3Yci#Aٿ$ nxSܜAm]|5U *ag[Gçڄu.5csO V z,-S?Ia->k Of"vv3_dsUpʣ.K>n7#ZҒs1N)Qjn {AM ooAks ƍ#mXl-[-$,,ɷUH380N!7no:֮"q[eC($*PO eL*;`U^W%\,U֐,JwC(D:D;=+H0 /A._Jd5=15#BC3ajS>3b'SC0cbgi0ㅽlNgS*ѱe0Ӏ'Zmm~`?սzނD_.6;0m_>|5kl]fn`)k\ˀe<@yb(9hqC>ެJh=Ob8EhRRV*cr9\7R&l$^m <"OXo>1X*`,{UM>ʵbe% +EL7N& FDS+sc ROS*,30AE';(bS $fD+`%Bse$8̗SA 4@s-{]CN }hUXJjWˣjjv/`oo]|hhpM9.u-y1z#ן_}Z.8j]zk6N9˱݋ k:EVj5okQumuH!$W},Nmfj#aCF!"'VyVsh1R0owilngr40(p(_sZF!Vg)W >GGdMXr[JעW,/գҋ\͗V'Gp!}v`;Np_CMXj}^@Md3}JDƙr>PcB ?{&pgi>.F#[r{t aʼnp+ѨN`&|%1;Ekt%1Wu{<*|řQ |ceؾZO  ư* =3p 36?BFI0 'WZ,xäP4p) m = F*p^*t'QeJ*nf` 6Xh.32 Ih%[;- XSjv^KLKS;rK ~".Bj9۸k_Ǚ1 7}rȢ6†l`_֞عM(ت5߫07l_P.Q1܏EBaa" 8&XPw4@>W׳tG;`rގpzy\+A7vޭ98"i6:uΔKFA^n膏]`i݊C aKb E$AFvwb*o d`_ ;-J;&i/vW2L5+ YU|d)|wmP;E|t_=ނrNfe8q5ua%~; #˵Īfu pުg׳hF^ t:GJQnuBQAsƎgL/F{z!۰}%m1w"wpٰ ˊm")U7gq,I&)B2IGBCb摝&ZxDkiFٙƓ8Vͼ!hVWKoK-vt4,ьw6mA%qby$3@^H35[&پ JmڜHrjᆞκ&)\O[,ֶ܀`k C*#ehz,Jy|O׉r2ݵ}(L$d9rp۱'u4^0#;7ߴҋq|fnEN \)wөT{zDJ-02S2%zs'8u}7n \3􆌝Wh̍ӰUE U B WMNVܾV L/ADg7cJx=;>EJo ͞i{bނYoϭ5 Yk\+1`=tTJwx{YA9FygTf:uaR;PUjy 2LMXG}Νbdjuw>(f2mbmHZu&" ZVp5yliq)`r_ rB#fHU fR5ihf[p+W!e"qLH%ƨ&L2& 1ÆVb q\֓Tiű4IvNM d84HZT/h0:vX>J$#,%W" 74i7ޟfA~٢6nZ|X؜=KTJȔ*J=d=6j.Sk)'+5玻2y *J)" l=cT*.ϜdŻT*vPdR 8]s؆=[+IX5ϯl7 ) >J>t;/7"HSԿ [>&9B{w@g R+LsE?w$,\:iy+M1s X]s|d3B2lRfYL{=.!KUK %ⴗ>Դ8!7_@- ᄛdAJ aZ;M-byI5]77=qܾ]٤Ak?B>'fgOawAŷƯIOC2Ȭ !;E/ G@ ۙ>LV&{7CR桌sQut)7oS5ǥqR\-RX!g& P1RJ*93v`2v(bn^ЭEd{ u9DdʊY/BАMqG6-ؼg`h(Հ!NVqvC/*d" o\z{{qv}Dׅ ?jm՜ԯc\V:HQ@(dի13@-eN!q. ZaMUTҘ~D>Oݺ|U*pډclZ*ưD0k3a +ۤe;-ɸhb:0+N/ -#v :`;ھNᝰ5b`)UW2õwװ NhVbК%F/z1"7XECc1 +-?`duegiFPz!ẳWN$0~=Nm 8f&NQ&J1`j:T#Sά\5~=z7yMY ;Y" gA$|/5JC3u!l tჵo.GOXjڂ*> oa;zsZG]T];JaTcߠB`(a"͋j>vG%^Zc*/z/L94_˔w#;0 " @DELnrMZz&7 ѧ8*:Eo@bݰebq!< f7ЇEUup-D -+P70cى̑Mo2H_PX䊕'ph5Z8z[9օ dk[nR-oǞOgEkR(cQp43_Yqzmշ0sen)oE7X,**Y @n qo3DnCyλ ?sS-eBX:h::TTIR v9 ?Ov) t n\%D;1.m W;H = ʩvNF 1AG&&yFLL%a7Z~\Vǫ+gNZN;0ʉjңа][B XdV= bxC\qNޘ;@I+ V) fMJdݼǜOt矚Na&"ԨI:W|kݦgeww{fQ[Ę)Ll6ah(ՠ!bkzXZBy޷AeS%axA.;/NDJHYpDZ4pʆŕ- 1P=xyx*Mi=>#$6~Q+ѳ6QZ[߰겓hnGdHz)[1SKȶ@o F- ldbRs~@5 R${5$I~vk|{\B\;a;m1{g@"ZC'GG2dYkA1| S;é,sT.etqk@V[LaLvB.Z,ˊNxA86=;#)zg8Ns 5v2i6].w 8Jlſ4B_ b]|HǮ^H1y__ݣ Rr_MɫB#n{zAXSݱӕ䬬n+uND`n7;T(>vL B/09yF-~g7"<f|&-km}GSI_QJ ?뤬EgQb^e9ohNeR+zl=\{\D{;H|7_v*i«A7eC1uцh9D(?{y:BC)}˲7[$2 Ne-oqG@%CvtdvZ'I)ӏ ?_U?gÏWӳX^?l|d^y_냏O_^@S>|g`_||{~׿1B|_^s 9=?+*C8+=B[ ^5A^ N_>8F8f𝤷:cbElG7-g鳗3"ak9~'8|^|}]ֻb{~/!Sz|Za2Ok|p9lE@հ{bsUkGTKw`u9$V1<2v[%j*Ol!Y%gm¯p7~'0c0[I>(&9x*Bnr2;K&g[JO{cxsȣZM=dή>]k'6|O Χ8,ן"X"1QZTT*wH` ;9]/i2h3#p586"y*bsu5q9F`Tځq8x ĸځn؁77/ 4kLloA KSRY6R$QMeJLI^ 3Ս\i{(tHܥ^c y򭹆- apZQ2XzOGm3|<^9#)cJZH62A6֧$(i/Y;̠i*Ӧp=2hZreaCZ>?yr.K3QT(Mu;61w+Ҧx1 :t0Rj۬dS))e;S(*:@j5Nn ؑeRxV/C UW?lkS'q{#d6Gϕ#;x5Lo܆MȅǛ:3r!& .tb- C,n)6Chi= a vP/3;I {|-htxc!8SBwJfNV$ p7B}|$XN ~VAMtaTieP뗡Q?̍RuOuJ"Gsa):%.ϗE!i38N FB\|yKt/)f#byXE)Zڢ霎1{vjM@3iY޻;(PȰR-P`-P s *GI6*)q(R\0A p5>.Cq]2)3^cH7VAɑrrX^w:1(`QqdSŃiJ-Ld&+sS'f)3W2ʣG' z|.+s6Ȑa(Χ9=ϜA>׎aL3Z4!$@/ !}ĎEte,ZڊSR4洲]_@]G+wE]tRxp'CYw"d?!prX4:E3Jjz?d51m舛ӕ" %F g;erQer歇Ґx&(vX}ƧP[,&t#;0s2oҒLd?•0hUq憬E4ވc^v3vP: ڹ)ۙz=Gv0~cCE_oZ{k-uRʗ0.fF:#9xj1$h$I,L*IoHyHbQH`lk@TOR}?=^R>RŨ~bg xQc &5J9E7iEbh_B)L.b@>;&A;w]>C *tpf/sF +,{|ur pI53).}܉3b?r8!67)q|fU9c&EUa:%$&歙ŻL `ƃijvyuRȲ2_ rh Su; k,!W-nvn2y)ya4c,-0 \eŧgH E2D*gq"dEinP!Df$'B:KG zt DI:| IJ>0̐5ENi$.ujn+X~xUޫqlOV%9<# &T_h]bTfPq.Ee̹9 H9"zb׏HB߾w/mT'rgkmP`8" AD-jDBk-0@kıRˆ|G$JCOjމ>94WM^ys7t Q oX6U^Iժ?*cMeUx_ZzZE3n )"]˻ocԾ Cs2rʪ{IG7kh])9(2MѝXYܒw{V L0ZK:J̣Lf uA۲@Nf[J 8+C.6:cx~d bVs\KTadˊ}4Бڢz,-5b-uB)$-)iZ81x9T`M+hأ!P"/(,Y 3Ge=keg~X|5 :|>5ئ]p .w*vc i9DHaQ"4{eрzU` g8A6kbDL./7<8Vk ,x.@]NU8h4X#m{r{cZ Urˣ,/M\srӪ; Dm|c`]/Aϵ把NLRfUd$zt8%Չ2WS@ZN}~֨KAPMy'juIU&&,M7C9X^sLP-&.r3"Zc?〜ȹ[¬LН3ms3ʆkM="zs^S9y!klWoDc% yѴB[q,9;*YZEbΆwRxgMOݣ:5 U=yu:oܬSR{bDLL}tlJ#OT3!.ķO 5gd!*H`W/0z# !W{{)$D-\e+>ASeǸ 㭊KvNh;PPg @\f\[w̯zlͧs!vPw\Ho9X-}s^uܺU%yC9џm**gY2c1!)>ʿqEڴ`yDmv*Όd[apSy64e{ʔV\%$"A5] g.7@ ؕ3Y?bժqm>~*"] 6>70U+uXm-'ͪh46*%D~×= ^Eױ?(vd r8L=Us wf@; Tzݸj:=p]L!`ķk̕^ =2оGg_ZV\O`lI%v}5\_hut^[2SaR2bT̳fPGrk!#*)]X(C1C.BQ9, `'9;d (ȳڸ]XDc:VPк5 {$jU"lkb KUU\gpGݖLYij8GѰbe?jlٱ)fl$vYOtBSkg^2/׼MLHseoɅGkt58MUy>9 [[$_btF<# $/۰ i(T :ILVdV38ڋjsRt[͸y!><])ZkeOe7aWUSqSks҉%߆z!fʯYܥu>qBS%vU?[e<覛'Lc FI(l#RnT'p6BRnU]_W2.٭Or:qy*Gvpcl. NJ*EE3uCfNx] \1OA3]Lإdʎù/(lF]FF&˔U *!.L [Q6?@mpr9xi|a1)g3[he$uʐxX8E[42)!un|Hv*ئ96܀q#{_i ڟ;H )4RU2xx FaEh\< tMS#QTXRNu Gl8t$(&y=3Ү&Z6Q)y aƔgn93 <.4z-/Ńԇ[E]4LvQb` 7sȵ6~(tyLN" =KKq&ԍ0Ӷ5yw3O ؁`/J4ڐ*#BQF2ҤK3^@GkBƋMiͬigh{o!W;: O"3 tԠu YYdn; MJW޺YZ[1%g i ܀I(DkJ慥dw})Sb7)~o+vmݪ:9lTyLK461u6٤şӣO0+!{ձeU0 QH$L [*ʍX|a- $*렏u_%Uv{ ,08L`Vs4׀ 8["zz-M4atIUp3+%N6͹F٥j+Q<\v] /0Ce RU:Frh݀@˫q@FYj6x"YPpb`95NtcE T-I6P//1cP{%I@ڜՀ2;r [N6 T&81#PȘ݂V棬lu Ix$R?* ?%yo k4a :3/S&m 6Hs⌼ggV2.Uf-2/a9pG`cÒ<]NsיG8Ӂr;'ȰN]O[ 7V#+g uחtPSsO:X/h̜q7sbcJk̟zY1$/ KhD{ZOXq8h3Rp/98 0*\7 QN(3ܠ6VS"G4E=/Z_ƂGn"aՈ%$-:| yEH[6—A0pWu|Cf]<ͷhVp h {Tѳ09 r>] ǽƛ pz$qcbrj9yeUhARx2tpHbX=fA-˳Póx.sغ2b zvSbqmS@Uz$,4[eѴbH7 J %ZӺANW%)$jm%q,ſrXGovsqar1p-#cO*MU4*8)b&,h``!82ڥ -hwe)$Al ,DXxinO{{͆a0߭}8ezG4pAP$Ȁs$x払-'Qwfw@%F0:6кֹ}G ķ__@B|l#ɣ%񿚺tF3/q9 5{ FS\"yǂ鰈Eߌ~\kstP5 2]U߈q4Jr 7kzT^`jхlzc X/_'¥b !vlkLGCV"^$>HBc [ y4$laI.@..[67Ps\[>>`^Z)wڷ+ Dl=O ~I,{w'D@OU}I誾'YRt?aLگ[NHh"ӊ sI PZf鄒gp.nCr1ƨ,t‰喝fOd!Ng,W򀠐5_z\kh0 2EZG=47__FJxwt= bk]2¨@lIMrc[4w{-b0cZu(f,ssm]|ErAP`H?Ob,Z(k U8wb TLNQJ~uK Ѧ :rY|]7@r#+|OW^*5Q*&Gޔu,1lOp֓={ʵ02٭sE>\(..ip_CBiooMl}וB)_imGϷ7i?s͍Ĺ6Uk2}GLMAfCЩVnyәv6w)v9^;4ƚhjUSMaK0!PhVW^,5^I}tMܴ=' 7첎wa#b$WND[4]1u%%-\!pybl-ܺtnXtPUcM:ݭaizd%0?N@)BBxZF!Z"6vSNŪܽY5pGw7ggɕ*(dVݎ9"$rTԬ> *Oz5<8rCQ4)TxԬ=d ?l! ^BLs $z|a2!-ڡ m{c=Z^'ez_BogU>'=0.}k6qhOUZ: bP䢛Ip2CK:kxhZV2)2wQ\n;n'[E tm{hǭ^ᛛ '=+\HkEڔ|[|q Y}g<dU5S)EY""z,fNcb$*鉻 ˋ yXb/W]a#ZŸkhʘR-G q̯ qT]gDZ{R;4c&yzяϪXjpdl~H}7kN/ˎG^9n!#{6<1mZy1FgEb^jc,Z#Z$ロbmFKp6s=yTyN\7ic$E}Do,;ipTO\|[!*̪gqdhβ+{_H#(BC']r]9n}Vŭ"{TeLH^ܼ RTyZ>>??}B>|{o1?|A>:kx&>QQ왌ģ~Џz|OoFﭰR[w˃~#8i痧_?,`o a_~?|O_~Zzz/+~ 'XhWg86>b [\Iu[ӇH֣@W;0O-)ˁR^I5<3h~axm30bhʅ˅nh<-heRRvYQBfFB>}]glnKp ;T2eݗ3 dI f] pb\7n9VA>= [oCm(2 ם˨S<=XF|E.eu~nTIlg"3=}~~~ѻ1?t6ؙ736?WHe=B"QN]I/ߜ4>#zx&lDM5;8ޑ"i佘 II,Q~*dAEM Lo"*Ru L|߿5p hFg-@_Z({g-^^BX (5v|{_ux.M L͏*D~MǗ]9b9 ȅahoM{n< 6bcI8e{D σT&`e:m0V4iQ r0DeLb9$\a[j#VFaOn|tgRg}/IpW@rhdxI$|P<)앰g~Fb12:{Ϧ^u^g4cX FD I/#qu vmqr:kp]A m'Qwwש5M0ap]s'2rg49!N\MJW@j;&zB_$#󒈜l?GJ5zss{ \tcQW(._Sc UFhęzgUg{F5~.ИֹQ[ZxU߮I؜d%gvx?V )yrATr< YO[Hau\M ~Y"W&"|g[J˱o>|a$d:[ԅ:#D1A-]"z*oE*'$)z )F$vOd˷\[8hvѽt4\k$8 +{nl{- ("(..,EL4V)jC_ٜNwN+Nv;~m0K_o:G \VElAizѠ{N1D3ՊaD_jr0 ĉ[ ID1bԈRk;ѠYF߻ qLL{ o\3%NXQ-S(t=1EC 'T3]p1(Eٝ# +Б>6"11 oH^O[U0 ײU.B|DВHOm<*!;Z U(g"P<8 gs>Et(䬫ur..94/ 9y & m+"5VI6/2~*;qvVYu9}&&2BfYI>,X(u|9}0D#%ft.djo^6z_;V-reN薊vƨ]:Nyn:˻85b\ ܨUBL5+g Tn6qaD s-Ac/yj$ CZKx&ڶ+?L>uՙ8_mƘiM;FJ"Zozx~ W\kQquy%F&2_W|D_E=GqG*5Y3]J6t۹C;!Y<Z+C<""Q),*]cMumD:ݐ)abq;Ś3!Oz g%ddNVO@"*W硕mA"))yJ>rF 8n\@t #MЫpRg.rhʍ0fs9zI`)Tφ(50(ۨW@dRX@:ȊcZb*bItK&mxV7ۀ+)Iv(fq炨pB cF}~I wt'u>^:\ʚђX嬮8#Fn7n\b`<hVW4Ei!-GD2A7_,PhTCqJ TvV[٪$H"&[ȥ̌} L: ch[C|L6E!Iآ1@t3UQesnQ1a_v㊣y7[\ßJl%ic7a!:!ޭc;Vux\m:S qՖx fqqhHaٸɫ~/%L8yh_i)ԮG].hgCLoIKװF9#[mYd,2ҤCjk8_3 \d1oDE ~fl)h/),tb[R}{/˥nqdM}{ip fk@HTbbQ-~'k-_4)CHN]=@~ܨ~L1uBD.{)MMљQD{x.mْH+Uƽэ鹰;8kїP[9IgwS#Z8Z<Q ZJihC;F>'x9=ﶚlS9nL޶L6qZF-%Lr!MDN؄, iF6E j;K0t5tGLdR?3frA|I:LN|1/*spц$N&O&\JWɵ&oLgo1t{ic6VܗB>u 1$7ǵY{K1A3`8r VWws`Ӹ"wc&ډlMuI". ;sԲQ kC^B9D@SRI#7m˂4;ޏɰ#2M-8U悮%l<Q3"} jΚ~YŕܕCag{vތLS|/z^w⨄NDg47xGn[ !9my6Ϙ1Q'Vx= NԙKlvsfT.0;& WF(6uzm8cY>C]#-/>f_8#Ո9]FHx vl[l8?joChP3dG8Z>L)dEmǡKAAp~bSevQ9},$t 1vDFň{J!^x:n9qoz P*2Ҭ UGɫ*:>41oq0 B#uk %눎Dx*>1Bi޻Ii C3:6Ac[7b8VM?`v8(za([6ӯe3Gbcy1bFDKU70Hj rYa\w'vkaj{fZcz/ "iCqLxYӲBxn w˝)75^}1\b39L'(u5w%s͟x4i{Z{CQn縻J1Z9ɇY-jcu'o5~AX9ACr S X_bOt! ʌQ}v)Ҁ{4Ӑ&`,f9";z0 K#q {L6%ҭ>y$(JFotdj)Zw"XTD_Dvh-ӤaНFP^`.(_M0z(b#\KؐS(j)^j%#5ZT2q\2{ѐ3'ŀ1 6MOwұsCɊm<;wIK~)bώm~AJDԥyq\襊ګk0YVpv)2HxΓrL4i{kdݨ/dȷHyʢ[?,r !`^р5T`)V-73<äP:B FzGɈ|{6ͼͻnsԦ|jdVq҄bC32c")H2vw;;kX#kq֡2aG~ J\b{)'L$b"3:tKvF֬Z{}vDX. "]v8FUځO^sȜ1s~Yo/XkN)m@4*ԪΡ+`e\āe{Sq#<¿sB=Z_=2Mh$qXpQOLuŊ-ض?tJVמ[61U( k[F}GjU /*eA%.׬rr_0qQ .A+FnKZZHѾ1ŽJQGϰ[IK4 [s%F#ݸjn7|Pn3cWAphځFܓKxwn{Y:?Umtx2#19LƢM mmq/ ̅c&j8NIq1`; bDW̽GMR#&v+%< By8Rjqjη aܒGNc^Ԓ\<θ͋#]P3ջY]5_DҫusX j'Y^r4(c1meóZ,˷jG#.R5jsjwvnzb+eU9)(ZKgwmctWg -W-Yg4)F0yl(ϻ3 ZVC(u;Rjx2I]^&r)}E{u)@whr N|٥3Sסhw C:7u&EPuWv=VǯcAtwSzNBv+;θW"MmI PpwkΗ]:YԚchrIaX]s7ntJVN77+=l[i F'W0qs@ k 9Vem%v]Ծ:FB5 J[*c Rɛcd%M#`3*ޗ{Uɧ Sf܉x*:μd.(#A-7ebV a_G7;a::qa&mʼYaL_>k7F^MժV h165zd(cDZ_Dë7:-kګ8~YyUQq+T$7ug25k,aߠ`_tl*%ϹbqV̳e( EWuv%rd m|iBCWI qS1]WrZ=?ZaҢ(m=v()PP`pB\o?QsQ ~5ⲳH*;SV 9Di`e]:,_z 1Ρ $U7Lܟ8G*;YeyeBP0<q ﴣɦL=Hck^'O!h:KiLޕdor/F{L>,lwϰu~~$/e],LS%>)*66x.l[FWX#6tl+ְӛ^>|㍹:33r!!3]wb7Brke)k%}kZ!{LHvা=q ^U3ʫ7o3KܢqpXϾOVˉ;~e32&bX.݁i<9 "@+g=X-iest h#t~7ŌxͬcP+Xz!S/MS}AJ]ڦJL|ۭ;Yg<0=Z_|jng7~ScyyTwv%SY7j\6غ&QK|ٺfJ_c?3&4#N5a[0hKւ I5z7}/ӏχi;Do("~d{}c*L5 Of̮- MS`1zC&ڴmQ)aPI`֜wz>h>cpa3<lMlEv9gx-!`9&3%39P%.򼬲͊Q)Bi ة 1i}hN5c7aՒ4ek$?M!PɝyϠ l.Vy2FB2㔱E͎j2.r`Eմ$I-z!fܸ%TBLRa="N;| 3܈9"ڞ&8]JOvU(f@F#wuݚ;~5KWG `B;t9`ɁNљ ~[>g3Eמ7ONy]NG03p0O&1й,$T?ޑSV3sf?g1Lb߰ J?o;bg x嗱&w } W`&tc53 q7䟷g>f?=myOviy)?Ty݅ñim ~zVMjwκƉmR8|0j뱧xf?#cؗCX78-?;Vn:?YO Ccwb,{N+Uc6м/30wgOa?-Wj_bɶ_ Ž])_1LQ&tٞuɀU xC 'nb0v:ȁ&ngމׅ˧˟?Fe޽ϯ+@JVo\+'H'f~\y/[7{-{j7jq&[Om[ գ̃]>g>(hWSp=.B1)*DڌkMZGB[WgS7} me!R.#%Miy^;5j g 0a3ra3PAQsN*r=#3Jk;g0XCIvV/?j;c8_`RraQv%l>|,SzGdZ J&XN9q&1@ S3j 7It>??l {AnUpOYYKm^n3ްɶ YgA`6-g=4村U>wYrk mm`:'# 4n;O*sDT{ć56yWRF #$NFv')BH`$I7N \ͥ=:T5p 9Cby@P?@WƊN>W' ^*jM`> )mY>)ۉ и]&([49zղlmVw-%B>W GR1%cf |JfAqwHǮ,G1KA]t3mpAmr |;x"Y܋2!:58pKQ3nU_蓟Y10jĵh=h˜ c9\p{t<8hm[iU?E&<nȥ|w{Q%MO Ne.T[Ǫ;ȕb >ޏH`?󃸇oeM,dZL\f\:-Tܟ:^x@p@1qZ9j{y( @zyW?ڻ4-Iv{_ owPP;p~t.?ǁڭ(ewBG<{I2A9PG !y54*6XNފ4r6inE}ܞ57cuջ$Nr=XG L>\=2,0t1q,"ώngxjS[)wLsO۟IsIJ2m`xspԃ߀iò a>Mr6B& Q څyH›K>=`bmv7G(X_7owk1[aXp1{ (*=ݻHPOۋ6WkX 2zOK[Tt}a*Ggcv|K. Qxlɉ'#}ɗږ6PPzܰ܅ (* CVA *.Tʂ󕹕cZpZP9JvI 0>-\ Mj3%Qhκ t9dzڟ"|K2f9sֻ #b7agnO'~ +"^:{SEP[Uclz\W:T4tP5{~eZM49౗*}<ݻz݋Z Jûj\N X;V?T`͐VF۠[QES{_hv&Ӵ:ٸ/w_{oxYl̔QmB|BxRILހ%l'] |7_b$KEb82RyG8F8 +뾽0#)NheF]!ş#M+<#&pz 'd^ՑwF9>tlyQiy/]|: W.kRyѢQCj}ivԀ_h(Kԇ6+vЍ*ds1a<ό^H/ǫ*i(F@fO@Mkv93@~Ad$ +)x_4{=_JH|ePKs>%ZE gp B.~!U>a/O-C4ӎkᚑbZFR)Ո9QA"F r{LҔqmq7AcғiH:rϑ[ me&s5WƥAPYR|5sȅފ~e ©5BVV} urc'``$1%i~ԠՖ՛s5ѫxbƀ 4O* V͢ ?\qE , (@KtECOofW̺w Ic_.I|`^HgiU5abmKZ(PczP8^} QC1K:5u5Fwj'BvWRlfvc)%&m mF}dOVL1Vğn~V&vW:kT@$hleHkkU j[Me].o{0B i -E*{T_ŷT /?Z/' dL_40u|umz&m-JJ&k2fOgwq'S8掇7]g"fؑa\*KPk\RCߓw@x O)2o=Ogfr`yS`i&e rs(nP-gȃXs}M#G2|&)!-ȍϓ@'?X5Qֻ3vP۵ļ|C}T% Iby <#DDaݩ^m~+[ 2dt{B1b2!eL/G%VSӘHKҟt?}gL/͂=R4 Cc ΟX E."/C~}Z@y[{@izڕьċnp]MޚgJQES)Fk0@M:T2WEdšk`7 8 "1]gkK3MvlNx*r-0-ؼw#p7!u`p9o~swy!a BewJCBw5vN}3ޜ}|i; AN?Rltpycueyuc7 <8$>lBGRwT1eJO҃*CEl#Q6LLaqmsayގI0Ю|S02O[x.#$-rr;vup*f4ktsy!q)1RLeEZÉ?&Zhqg[jTl⟣74`&&H2zޙu*]s7aĜE!r͓B/p = ౥O\+Ӽڅ\ԱmbRߨUȫ `Tua1$O&?M!%'~*EeN]P9+/k^N˸6̌zB\hszE)CI8Dv͐D]rS9:m ^{ ._SxLs(: b⶘GJ EKIm\EU{UUEJ 7qYs~ίGv*aE$$۞iv?wlfޙ';Z>d\z$xY NBy \Jr7> c5K2X65m-,*G<:m7 |$9^Iɖ%HR|WC \TFCz SAfy>μ/b9bKO4iq bw&יRA/WJWB]l,M6t6碪S~yՏ?.K:IbˇBcSegmxI]R|g1!o:b۬ O%ۡfhӊUV$Jc:Y#L%1tYTl{/7>‚7E2n;̯[8!49vłW/M:˽OHb@=u>_ M@|A z/$e2U(4cUj8&o< ;gq톾 B<6] Bpr-6\_=q\E|˟Cz7+ `c@NKf+3͉p[qQɀgo۞ZYh&ZpǍO\vj$HmE*n0 X6]BmVq*.< ^0P %$Hv5sIq*`3r )V/|pڋTF|Ű ݩ)Wyƀ$b~ 6t݉ĬhÎ"~_Inӵ+)1 K 1]%/ ǒ}k]( ]eq [&|CW^I8zuz9#~CmDTZ@+w Ҫ-b%Lu[/'Ʋ679'2Xoi@ex\yD>'"pCp^K1+&reʦ^'JZ>T;HeyAAեW62ȶg%I k|q%2BLak_Fx觃k& DnV[!۴;iǼkؒt/e"nb33+ SiP{ϭl+@e7nA [zc; ڬV@3ӯ}~57"HC4h=m48H2́$Ecn.#E7VW*&Iw&/m`R^je\`%7٨T'9=1t\V%~#\{}]C)p$|IaO~J-.Q9#.2eWQ\)aX# ]`cv[ ~v*px`p{߄06d-lKs٪.|DT(.䪰geC-|g]K*ePL[n$9*QׇfѮsXZ]w\;ļs2Qr\^R}&_|.7r*nu*[[ 90bw `XM?5x0F|ɾԷqt5*k kdpd1=y-9Sԅg"g0g[˷qhnVɕ;`&$\XڅW)Hb鲙^}]@.ɲۀ i,͆f*ebW;ҠZ71PEW.}!rcqŮ'};"!YDfbiQC;1} f h꘼ e~ ) rEF٠֥wF }}Kb+Q&#;#? ezF-(;eI>w$f!r!Q ¿"iJ 2jm|$%GYֲiZJa6%i_ mSzO-XUTz#0?,YmV}lwZ u;!}1|Kx}0M,@%@0x1Xbu&5}NSOI,NjO``-2ug"5Ѷ;tu r)͡fipVɒ!yE(c#yGc`ڒ8o쪏f0sv^xFNEȹ^bgxC(ր4&i(sO߃˪նf*HE}:KmM q=`T!<-@|+^x}{L7w|8V65'z%&Խz-r TvړTBHWҡ)BQeR,t ($,tn u~X^k瞯3=gn qBi. %s6xBlr`W* 79#80 ,4z!jn^Wm?'w/oE==slE'uzLj}وJ)pN3\7Sbg1m5gBssHl-UuK>ESH*H>$Aé =VxjbAW+ϨVLW/Eޱ]/oav_ΩGX̆9ZXA'=W"^ :8eqiH=y֦ €U[ G;Yl-Ltu3ϖÏRDRd0Xy STvztn,,%cVT4qa#Nиn5H֤'cj4WvmvIYB3S7LJwld ЮM\&GOđBF'*hjG7w>lҴ aęF|^ q:mP@!KO|Pȕ.hqhNZ0HyHv<Ok-]?2jn_'Ck6YݴMM2ޒ&ZFQY+ҕ[ 7nQ yӎ5` mZ;?<2U~ZطTwcd (T(M-7tʣ͵cvK{TCQ27:IPaѠ G)nĄusԿ˩b.1/[rKs}7ɇ B.sog$efGCAhmxU2jM S `iՍ^1Ms̹e#'c&r: Y8dUti]c> ttgvzfNBC,,}˲]7ݘ5@`ɴ#JRu]Aϻ=7HN*::X2|/o㟿*߿E_ۏW ܧo?'o_'7E=3-x}1S^{cK&ot~o ?}1:?{ǷcJ)Vo}2oKGDa;|WV}Jgϒ1Pz_1&e((>׆W tln vn71niϥٟ, N3k_l);GWHۅZo.c ȝip`z_>u'̘ 3iuœ<3Oe(ae#u1b7}h oŦgCbp+OO'Vs%.(9BEМ>9uޕKLIٌׅbG*$ C QCC4ir W4g6?:gq3?S?}»A_7!@B&;s>gɗBؘtA5!>6.]X; BGnV3?Y8Wktsc6)6X]!CUNۭ,6Tc3j5UTzSjFQt߳}Q L[n#Q ӈn FuYNtŕ9>2덺P3qF3hr1-7P/;@}NvOlD-o[<D'kN>LӰ B%sYc64GmK.8#d3Hi]/%$o`RF"awz}rpE.zUžל-B]=o` ayl >[:OKj ciTFg '޳gc^-i _jڂbkו^רlás'q3BVL8-`.%vHgAkыNnA/VPI.>!m +ݞM9mp[z;H3lQwdW&`Av%p[.,3Uʦ7\raÂIg*>B~ذS6b3^9$ v' J)Ɠh>>&w)¹X.RxC%q;00Ӄy5v a g[}CBٞF԰zW@ǔ0/zAv%x~oXWzx3[~-_}G ٝw1+Xf(ZBZP UD]0v}b{-+\H#jN %9Alc sW]k9Ɖ٣1KsWK=A'0'FJ_81+qp&fr:O@ *.YY3{^r60|m$!7PRnYwDhR1Ù $ C!n(o.RGRɳ@KP8Ё |{] 7cFy8w)+}-/ %O\LY3xZxI1Xw3Gʿ=̎1b+bHg:"3iPe < >5fCnKkPxFKkGn!XɸlRM7nb4l3 NA$,1kVvB{l=8ζR=XLӒRײ`kv*4Vw3J+)qf dU8G:ͺg^q$g;P)1^7L'\>L}g=~2>璪iT{TڥO{Tʾˁ%B=r:pc [ZZ0kҷ*^>)PjwWKC:+өw+8l骷;<0b'`uC9A(˝rQ34u2v'[WSWPя9stf=57SϜvf'um+"J`ݛTM: 6H3VׅKN aSH4rϩ[wLGz-9%Z$dqq$t6;pܧTREZXB E+ qϕ`A !B0 .l?5ȹE6i.ƑN3hiDD J9(-De"򯒓dAT# 6zt$ɱwUHC~,M*A I0?d)s(Օp3F, sTAЕ"~>V,|koÁyb&lM槏mq1REBĆ'>]79f/;8ƃuK(GJ&Ԟ4ۅf53DQ !gI#:WD#kQ.(xK6QmICO5fװA:wDZf5SgJJ@Mp45 !^< =v[,BiWPlK*1ko0䥽'ab1$wЬ4,%yko &MXJbnZ\5gsd|"|TtgGo+Tޮ,X]^|G4:ޗUNl2;Zh41y@D}fg"˻Umc1* PPڝ7_P >i7u@E=<8))Յgxӽr @ŦCMW⹺vG?O\[MQTkr^'WkdS"D0gOu6lڳǡᵍ "%7COrYCxl`N zWEݎ^zh=[rPG7"9v\JͶu7AL*h$u̦EUI) $3&BGT[\쵳'E΁3'eNϽ;0ingVƏ1I =1hu}w.ֻcfEua|cS^Z R${yzybmc}mgXD;'!UŒEFXl(;NԸQ2 13.Uav iHiiAΜSg ){+"{:8 l׎'ry)BC3) >>\/t35%k, 1cIn%iI9'f]pBqqY\՚wZD.voE=(XNґO B->!J'ܺөV ۠s`s)X/ EXoIE2  [O8((|޸\Βe' B5VGAx!uX_mtXeuv # tN/p# C_6:t&G:mF$V;$zXrA_w,G25w3梡mN>-"D}S8){XXB$\>1B-) m%qbNPYp3:qb]lyƅZZ.2z_Da(3KGȴo؉$4E2:G){ Ŗg!Hi7aƒtISB H3.e!gM^jA}YAc7uAǖCEaS.__jq6z@_S 8 _ǿMhf ki} \ M2YNm$GNjiw^|`9_vn^^GL Jd#ϩ# ueQsn 瞯u@:BrLGt[+(5e*`fIoeo9=ס0E؀3k;$}Qhh 3ݿ Dp:ׇk}R{  u}RViO6X\Si\,9:K n1TSU_쪇M|&;b/-&)$,jEݚQ|Ntf6ބK*ܼ@ːgM<)©V3ƪu !m! n"32[52ǂK}jN^.t&TY[?Ϗ<)'`CZHˉkM_? 1ȫWM-2X|i0JhZP ۹n5 ݝo<^;e8ݽvh}"tn zrak8At)nƌ[3OT[(L:1s`/0 | QO4e(Q24JjDR[*)$8G!5sr5]tJ ldW+G؄!Lc9˒==LXcYI F5"WcCzsJ {T_6I^XlYB2F:O q^w rPuSvy Xs'qi{F,rz~]y/5}ALXi[>&6b3@=Xγ&8y(Xt6VJ[s7H“F`vqXpye)=IT ,8NPB9y0MI#E( B\E])1 ׺_u5t$.]6K҃߱ 3U6X%*n˄< hӦF47֭2+űkǦiA3G.p,ИS%]> B\_:ȃYAR]DyZHXn$ YY;smI E=d`j&PcD/ [:tqRЦ`xzӌdKƧ"'8N њl%$<+K9f8fڒl1咽>.VϸCݕpMe `kr7:4mNȅ4ަ 6s >aA2^Pl(}Sna(Zh>)/L(pQ)n8|@%(3pp^54n<'O&aڎŘ~dN͞h]h3ᚾ;;aQ@Hw,ZsJ=H+Nsu7ݏ 7<(L4ָ.}v% zlڠN"!܉ֆfF2 mX=~m2I*&wwb9PsܜNBGUu*@ŭx2unRjAwA<@9*2jɉ!.G &Jdq',f2.RJf;-&7t,o `!͚oSY@=_ zm.ut/Y0~gUl>_gz34G|+'!A9-BGcV<OzkV@tiՋ4'ٱF옝cqc41/[:_BQů`ji4:o;'j_soΞNsD(DQ@d:(.[IsX|,j?%wt>JV(;0X5:3dG|ފ̟ҭݞ?PkxƎj>m~`KZ%XC\c㌇XŤ1= c(/p27a%8 GwD!4e"s[2!n ;2T5 dWx+d)M-h>(UA҄wn+eMK7i_Q-=F 5;RQB< ufI_H]o}[sVmfj)?,m.Kk@}c# "(=YG8f43 {[&x7G${7xLZl^n8u9ϧ޶6娡LGҡ{pw} K\)fQ\c:FE'&]JKhڱ< S.)R(}F[$pBIJu{¬yƞW+0qqf{]yoːf2JiG{ҧs(e6M(zV4ћt '{upd1ʭ(G݆5W6.?w&9#я) NxiPbGGAOqEFi`\-&iA1.d:l <c>iK3t^m̶< !O@Khj$iI ;7>X$lnM~*l) 6Ѽۙ 永+9̓H}Yh[Yx4 /1f=Bi4ţM\Jɰ>5Tp>+[Y-xn˦{u rkvHgiN!#5T ;mt$>p*r.}:߳s,ԑ?+ 56\c㱍I%bc%|:o"4XMŷ[f~xh3-mbڵ٦kNeȤRu_9m |D,Kϸ&.3iFKǃAHE!?2k1[o'Z?[nEim(Q3sxߘr#ث^/u̵|8iahkvPmgV[³\~f-7zx4)knFyRk%i*!/c=uKgզ V.%.e:Vr/ZG鴴(Ȏ_/Rտ'vASdv1q<{eH:Z!-3{eF[ԑ>q)3b׮o$uPN{WDW$PwgB~KnW: X۶"β~Djkqm1ִ+;0>15 ֌>[G4wat Z@{mA!15h#D+ۨIޮxo0lʔL=黶cl1"W !u27Z'$Tc1[8XqY-VYa(>K e畵r>zܱ7cՆCY QiZy6ն^^Fz-* 0Ge{?d:gS}cБTۅ 7σI8|\l$hXxӻВ1Uy^Euf5pTڐQqr :; Wl]7K.:k$dAImeGas 0H6'K8RH I#e#7^N=EB(ެjJHq,'HMJQ=1w=iR ^-*U-rR.Mu;{y38G3̓D !2AQ>rMW%!DLCyX儩5SgL|f_NNd&[8FZ;Lu [f3n#l s" +ͦ䜗@5A3nl~W'-cF ҆v]A莋4TַfR{YZ Ɔ}^!F/zYEFlG4LU26E4S-L7c+"߭Џ]_y%gN>8VW9d(]c'S .[Rڕ*xpo[e-qlt/~˵g. Bt L 9M厌:ZD\f/ch|zKn) _\Q +%T+OwBM2p59x9WtT(:H.n(80;s{pI:ȅRt(2 ]f7> dsԾm}Y r},pD+7*yY|6.fo:#~N};gerH~Q!$-1YSff7sNSA._6pN؅|NeeC%6 V50l'Ml5(uQVԶHB a sΌCd`z$8_HV0][;[T#y$:o$%MqF֯YAmơ/ܤ/sfgltDYtZ"/4Q (V.(_Cf&F+G,Kܡ G)\Œ5"%*: Rs7RAB/c~Egߍ!M!w\SDc^ ,YTr^7/3*15^0{wuY+Ibc#8ʚɹ+T+?l䅹ҘolP 9aݡQ~W{'G4}Z3bcas5 qLt#y۶ov'&Ϲ4.!R|}qq%޻NARDIn+ecP$pa**O q/on吘 1!V2W)ZTخ v箮4WXJVԪ35Œڡ@#vxЎNaM`xtBC)]K\q^4޺ŭkI-9dJeὝe~|:@ )GvʶLj?;Aݷ7~O/FX%/J |zy{B_[׷?}Ï? ׷^~ן~ڪ?}x}{~R^Z~wwO{?[E/ǧ g"= nzt&BCz!Va*y:kG\q`Ƈ oT=iad&SHOI=LR!Q+DQF?!H?JhA Ƿ0&Ρ!bVYz̵,Cyg\z5|şPmYsN(;wᡍ5ٺ&PEC6a,jZG(XBH؄KLg>"|p):H_&!嫨lj,JtwР&ﯓc4([M: A^W.;C2k`B$$aB$?6=zJMR :$ 9 k)ˤp\HOH,:AK$}]њpB&{8!`RTJeF,"W> iGi9V dG󨝏xQg ||+R{8x>V8PGa1 _W*f*RC+q%p DA#mAWn1;Y>R9eA2`N /VulCV uڻ6n+(e\p)wP kcɨrs C9$&`ꪽށp!娝AQB\SXް U+",ZQaclmx9:Mx]e*cلO4u*dB2525,r4CNgB9.[Hz*r;NLX-y!ӒT:v`gX}F2fDR;[.b5i̐GYDEY%, HLgKW#RWarlgP"COt%i+k5RHg)`@kcFܕ=sƷ*ep餝78B+\L L\8c3+ȿ.ޥ>AXiU!W*}Q{;1A+{[]|BU OW3󝧃hI[xyFg%%HJ(;SVpYd)a>_qyn&{TcD ;Q韊(W/eɼœ?8]D"$k䌟s 0݅4R C =b$Mc^sKcnM;2밓x"Fz:Tr(HLh\E9Kc:"N߫d)3^ZOZ՘O@0ݤ慜( u<*PTD"F3MeAaGA Ml2R^E1J 鶝êu'6QHlyоdgE; ISnjEʏ`ѣ(}*\axf+ļG5q(VNC["E 9E BiΜW{@Dצf^xptp(8)?StM;"Q:W{G)PjAAvw"V\pkӤ@즴x7wkJ;淏f%꿎J L[{fcJ#iLe[̤p 1IwLrm"',X_\YtJSZw#%9% S$D 'qt㛢˫FGu(z0$v7ᭆYy%'׀_jvʉT behqʈjO6: aDSi 1-?6y'ѻ nh)P7xl&A;0{5:]#W)%?C5 F#$*9% _ R)*DWXCEPR:3:Z8wl`D}J(85D[[ %`:d~)#r( edDv(ꨳd_D$U|ȓS֓#[ C CJ tf!۵XfJ|Vҳp@eJo*P!V!<5] ֕>[K$JY̷QD&䜓sԂjïVE"U icCKg=RcY§eѻڀMA\K/DC w%~ /%T)k tes9ALMR?ә d˽:QQ`w ey_'12> VEyZ+wm u^*";N ݃(C?G..92qګ۴' 农I췒4xqH0 ,k:$bUn\~l g,Ʊt?rӌ۔020k#XǢșغ=) aM*oǰB2& dߞDXEZ=(CZFܢFP?yl .^#tH87Oq>'1!B+Xc}ZO,_J)"F5] ӱ}nkٻ<Z6{@ΪXp'Q^`)3Gx-5']|Aӣ/!ƺJp@Y< ɰqVtLVpov-R/g7U)R4eZDT)z B:~4ĉp/Sx}u7sCK+[|w"ӣѻ voDmrWFݵ '$ MDn>3VuxR`ɱ n`hbNXe}P:q f q>@F˨喾benB *)̙I}ʬtT))/.5!̀29nfWt7$}sj12fm$I .DWM[cB)ͽZ_͖˒O05/a\Վ*VosLG@;h }t`\yG}jvP|A.v&YZq{l] qul.zER!\ oˣ8~jD@&6·WJKVJ@Q !N2퐰 gtAdJbJn<` iu>#fMHKR=g] e_-@W ^a3_m?#j42 kJcJn+ ajԚxUDs5ds I3P6"v+-o Ҝ72&,_b;!K-ƐCD)zPHQ բTBbx"P] ̚~4t6L3MY}h(?|Vk_.U}12AQl= DZ |\Aj\Z51Y-oH|a4uw_W3+.E8oj 7[0 OSCVtx>z|@UAƆ|qT! <&p#)AUηr5EJfFB=4J1U=|8J3NoP#K]acALأo{}kOJwdž4&|f7oucqvpCR)Kd--dz'λCfgǦ-H/.imHBrN}(}:@Nmt9.PrBINJ[\oF6uDW-s_pJc:VQ/JW@J_nuPI$7fS 91w(t~,Ƚm3P-g/]ڵP1dp&8 4卞g{؝DP~=_(|$T?~>Oܲ_*0eRڂs["nq#ݯ[.[Xm|ܧnJ=Vfpm8*Y8`0I STGLf%sR6NHj:,w-}]_ɜ-<'r0f=ucE}+ }}XeXA)4 d=>N 3YY>/ ;v srkF9}ԄipJ-ARF֡؛u鑷%yFnzElLg9 6 ngi5֚% G45jihEN"^IilIЊlC~KfprmqtK/k)*ؠ+lIKjħ ⇱a0i AGydo;E ,[d."P{C2N3P6✎ETqs c_, Tyna.bVJ9䎅Oad0dw1EA½F* 7(eܠv {^&|'>#IY☳R#V@>EKh)qm3c!p04q&e]>:QG?t:v1lU8A6Si3'[9 w̬SdJ%3AK z#[$D+f^a)Le "~bed MnX5s>w?squ<yM~h=WdEzV'hw_̥/2eLuiPy”2m\^t5z#/NC̻sA] G{OT1FFeZFSKV&P4l}M e"\8;˺NeA\y >{Nk#}=j;x)wA͕@SB`n}EpV[gL\~15KL T uEgtɔ~354vJZmƤn-%ʂʂ$I@Tzң$%NTH1u~??o]/ldRM5F7h#,ebڪ#- n&93g`1- CÔL 1Es_zpl%4֯ :i5mTe2$b-VhO\4}Kw0%YϡLUS1IUmlvyi]PW|9p?A.2#@.[:A.LMR&ZJLF@+!rDgmqe)L\pWZy4a(7PsEO!t5Oٍ@/L|SC:x+ʙikơK8$BT"ϭCoA f1 @~8i%NN"lUv7iUm'K7b6'B,|leuUIZ pTp᱑VnDG=:9+3~02 ni^{%L[M\ *:]Ue9),FB4KgܰO+PDzoД4c͢{%[xssgqfe*L&*ZuuzhYEM`[-A[k*w6?=)G|0F]O %AzbW9>Q\T ¤$MGK<,;qKMmY4.S =S$I,I~XLE>Ղr|FE T'\Q./uR*YMS'\۷ ʞ86 \NGaT.>'yW E^#E /dgV%/Fýv-Ib`sۋv.Կt|՗aڪiծ*Qtn֞W9Rz&w؀U_,xNeV-~ E0;gҨhʆ@Vr>Q[f8Hv&$͟9)ʺZޫsJSIy8bDߢ}~{{{./cY- y:3WB%I!ʐlYAJsw|N5f5J97KaIpr(sNhF &kO .MEԎoIP.`tƓ.Id~Cwy&$~66B-tb3 _A΃ QJ1NrqWܑ b%dxdœEZ41ܴȟa0X@[ÜfuRա|A'E(ǥMڞ7i|hi:F' =G[VH̘u1H[[FpWcC}$⸢I}c 借™d٘pA% ڒn&kh#Բ NrvƜ+D1i2^snᇁsA1.\kˎYXuft!Hǫ/xJM:uH @_+V6>s&fFl(?ʶBDɖؕa{(F=3j-5Wv y~ O/˩X?Ï3݊Z_ `կJCzfJ{)OGڱӢp9M~ץlG:NawW>ڏNtR)z-Fu%t_rW=t8%6R͉_Ё( *(:t7ޏvO*[.Mckz7xg:Kݶ(KsU+A bz15H>nDkVOTAbeSq 6dG.(pFm/Ymu?hu{p89K/X j8~ 6` _yj|8%jɦrP9fIXi]yvA+Y}Q05Hv%h5o>SNUd똮X(5a(EOSN^@j  =-kZɃuW 9(JfF/z73㣈#!~)pjxHt8"6&{6`]<.56BCk)]M\m]3bu7SxEJ˱R,ȌO]g޳#e 5g $W|/!N|sњ/NRZ9e|0ӷOoϟ^}u/_^o_󛚗}z^ ˟Soy|xo?|O׷[K{J?|*>'h=L)LϜUKP3HLH(*5^ ZO?~z(LrjPm^`au~F6#PR8f/7+n Te7 ӽ'ٕ77n'0 @*Qע)`[*1L@q/\ '7E=btSP3oMLAM?װ:?+f~J([Ww< ;wKEDOyp'"IqLW(Y⎜YA+|˷Z,q]H"މ߾*r@``N v) ;9i`= ,Md},97k1E1WXA,@F-`nǟ+lt1^.=xcSТPT7Rh(l&}(,WSP`Aghm-|NEͩ>:Pn_z~N&DŁ\,Sl%xr(8ffOiѢnO"E݅9+Řx'=+ZCvD\P]L6bbI0 E%OZ 7GG'hD%Gxel T"bcQ|ꉜ=Mi'#X,9JQUč+rZxiմ1L]' wUDk-̎]0-XƇ v4\Y8"dfSJ?dwGj&Fa\7we;g7AÙC_b!x~1Hf ƽo-1L^/p9|1^:o}t?lV?bDv)[xw!Uf}`KUƟNrǏcnKcBxb¨ q7 y9=K@64)NRiԙa\NƶM k@;~de䲍g lp)W3*LsW[]rWdvxk)V:%z[e6Қ(Gʢ % X֭$U\h5 rRw?KKhe0rKieFkrOr8wO6eΆRrV hnˑ cx[8FɓtZk֤J[]0%4O jq$_Rk ytU/!SV\+}1 PWNIcCX#ɆOWE6;Hw\0${6?ΒV'`ޒT pyP*4/zZ၏VRKm|X9qbeU65 W|\Q^0bp򮆼H*ö\: u`eshcDЧ*jqޡ9qhVE<:`sa7<٫XwRAb+2KN9.H~vv5`Cӽߜ+M[$w9.N H! XO0/7rz(L( zsstRfk@ `C &yCN4JxBnqv5~~W a{oMЙO(JV4^NodzȐ*-'ל~k!s]#,C:RI-gnzOE'1)>{DU7hT.~u2gI0҃aV"ISo7hSPٗbm䩹f%,>l?+]$ 7uM \J\yJ-qI!KתbuNft%b`ɮFSɧK(&q͉ QlUl!㷳u/Wb lM>CVp(iMTdJ=~o- ʆ_YS)@*'NXĎ28/ڭ5wf jP8sK\n#5b9=*SEL=?e6XKݏԹUVښ[܏IϤ]]&vd[7!b > Ժ-cp-KAG8a*,Im;rNdSLcyar3뒰KCMO8ӕyRr fRWVzXL\#q&=|M/Aq"^k]m;tϞ:1Рػrn+`~Nm+q2Mk ipb]}7e a;aD"d(z:`ou0;1\#.Z1+Gz{:.Fu`4N&d 1_V 0ht\v"\D/ah ȉvT 㒩Psr78Xe{ a).5ԏ09I2-c,.f)Z%J2ϤkXE jW2|gËAjJt`DQWAX WH$ݾL" )24C "X"hÑĆ1rF͉ 7r^ZԔ'okOItG)A+;H+ꃔCqS_u#hpnB)i{ӅKoﹴg49uAceɥIr=UOT >DLJbq0*LhцR`zKTyZ{Cq 9+F&Jy= ~h]3 ۘ:$ť@rȗ*!N5O tn7e1>6ޚ%ˎi"Hɥ'KELT|4jO8E_h̽,Jhp\ꅑƐm cV$r^@ ⠚y 5{]%F0Il{}p05~Céo%NtnNjڟ./_ hWh|u @c圔]ՠ\ocբ=-b;FNDޓ .!MU6L'6BvIf}e!zS{jWKd_h}}Ǹ|rl؜nd.Qgť2YXDj-xiƆ5QxB&N!六iCtN+|MEݒ5ly0s lgU:"\ȉNKNYC VTrpDAȦ?(Md(e*3ͯl2CqT"r$JXt7oR:/9v}$ hٺf^Dp3.GR\dldB=: J|03$ᄋjar~|ӳVƅG4E6{s= ~뗦͌_<-gLS)7ڊg}0+}^F b~`cLQ (= Bbcv7nyw;B+ xK'6fS:`kcO >@tnxckkq@w3n_oq z k/vMF'ؿnΠQ*#m]tP>!}Gz(]،,M &5`z+;|G,X$TxH#eCjHY] X4 Ŗuuc0*|8]>yNicئESf+=|7l:L0bN.qtԩ;xge|}y;uQ1TJ5<84BW}Dhς ްKA;yĭѳho[v6k$xIY`QVÎ[ |g%\VƠBW&Y8nDU\lAj#; Ɩ? Ofl +n^Y3ʗCenj׵3^)# ,Pvu+Oz>34nmqmOR nMT<6iq-&m)r|̠Z{tiԃR P૜zusR*y޻*%e#8Vݷ8E efR?mpS[11g?+2Gn6$Cʉm(6]CAd OX(?1\A%rX&FڒT^@0Yfn1Ab 5%L<9&Ջ+RsW ⱒ 1Bj=A3ki!W3ȬA Lcs֜lgUST%' u=] ppS Nlnae-|!8ܠtܝo6m2BVĠ& aH`_(ƉC{vj1~]t47$S}jo9Z&N<r0Kt*,/QLd _>ZB>|=ȩEs]82Kϲvt8ȝ9׵8c1ԝP-yleJu72Vj`w7v[ 1p2y\'CdeLZ`xv_ߖBl'j<(c^QwZ]U{)ݕ%"L+Koz2=#=t _(PWgfV ũP*:mZ*:j(fdj)! }sO\Jt bv_kcʮN}YOGZoĺJVv \P42td 7 $Uc3 j y+gRckthfn~n%V*Lů]څQXVYRKuե!'( f{gy. ̀n:H%1s;]JktRCSSNi\P@2S%F5omFyE_07vcW 1ic^OooNM#.o=ˀ;5+7Ժ̒ ۘ?I4;lC׭󰌎p7nfi@`,>)=э`GIVADט3(( =@J☣۝dw;vu%}Lbq:ag,%}lY9<;%#D\wp"sgir\ioAl κMu& >)s؍T*vx@3~`gk3US7]s'ٛhgUd}W>ZBg. KtXm %:rjY竺nիirRhxfAIW ^t!%8.uiey> pyGQGѕ6ljs%Y[sQ.xupĘ; Hf{C*k+iruUcg 2{X3-@]x3KbFz}FGz7*9DѴ. N.'68]%v YD22V h1^JǖR/iw 9&bP0kUȱp2 VS%6 >a'8F=<\u2HoVϭu[~ryFdIWY2 3 }bHBx-KJv{ 9 >(isTF9)3hlT19gw_6w^6G%I{Y_'FE% i#}pr\$BŁLÈN:x*ܹOz@A[?--nw#ƙWe4*tSNk=E8sT/^8S į$Nϝ5vSKȀTuh@PSdL}f3a;51FXĉ.tϫOK DH}߭wt郯}A#-4SDJ'eo Irkۨ҆ww[ mMKzL7`a}PruBp-Qd  lN)jꭃhBVFu#T[pcrdnm{t;pîl<{ vW@i+> ^ٶk*@nnGGYiŁ3(TmG1 j-b[Z4 f{АUA)@F"V]$90\$[| {69Sҡ%e}Yd#($cT73nv²q5zT\oO{嘥y@cKe @Wۂ8ryLQ)`/ߕ(ϴTéWlW-7j;S 15$/ꍶ{VW V$VݯQVUSg(Fݯr|(Kd4`!Fg }#]_b"Ft_p<ǫy5wS&7̋Ո 5tDH fmqnVS: ~1^ŗC@w0RxoL&wo{ Xy,)DdSe0>b0Ebi2.)XoLd~i4;MN?K,d\ +B#j;Ng(qnrfLhpoo Bf;@,V#- TO$1m%fMv̀T gIi&/٣[u~*XRmI1mJtD=w/r\6ߡ ha8Sʴ~Wv,NO̷;LEw3DϖB,A:1„*R4W¹eE#N1̨g+Yր3P˘yY4j-J \F x_6Q祫{o=culO=CW! I9 3E3mҰNm9wenio֧m):pΧQA[%Ԥ1}=, `c~7 fxA>cپ%Ő,G.(9޴A-vtx>KdMCstGMgvB~NYZb:m߱3db{` K ]Ϝ8jn{6'FۉRn9ܠNcmpg$iC{s˨;wz3sykb=)]M^y']{J;?=7V}d,lV(!KGƖEdNklՐmy/- %W0IJڤ]me =TNWXG1nFǝE(I/'abRN&w: NK1.n{BCj!]r%r]"1Y^0&d/o U)B d/B`w=L '#c#WA dJ 0ׯ|O &^OF<߁|_z~_Oo__k5O?>?~ӗ?_Oϟ?/۸^~~mw[>JH)S#}$aܲ UTr7o)beJ0})PPۿ0, KsҠJrqA2?Yoq?%V4"Ft[zb[ oqFV+*-Ik85>*?Z7}"\M+FH+-+;vXbafVltG=aecbřtR+.řXjYTXc)2 6ό >>5xqڤ#-5ːB.?u> }^K~hV  쨂QY(kΣ(VCuںZJwpxU+v-G}x9?Vw;2SPz;d˹t!s l6dÊTQ\qQCUe XMRik* ,GaESڟNudP"yr:d?6Qς7)6 ] U2<SiZf)q]H;EQif$̟zz59 pp30eEUPɭt=W6h OYمIZ wLtwKZ/7j:>[L(:v>o̓[ڟcj =eQ7|$ioJ$;jT{ A}*[bz㍊=7]pٙfHHo1[էS p|F=-j$bèWK̡Wev _.66p9@zOeN+$hh˛3c{7"):(j}I|L vcubL%$P<x#[fNu S) CBD"I:gk$QҘD⋥ )R7294 ]%v"@i;2BtcE1.5E0N=D)} +cQNAݠlT0`(#V6˄Χj\Znqbbugv c;nP.;D%{m124A^\&tB:O]kol+3M1X@x5cfsD}@ LdI*H6"EILPŗ*J>fd&$ uXhC]:{.;l-5Wv”ӭ7'vKќ]>QDU7DGSu[,Ny{+ZP` J1=GxI\qPsAYig KQٰmXqUpf~0o0&n*퓵315L2n{EqhLʙQK~M\@+~sfq]7ٟ-G[piQZL͢9Y+;[K) f4nޞTr&鐮x|ͬ(fX-S-6*|7RJ=I|='g} e#T9KWGZy0ME!'V:O'ip Hryi]8!7Nӱsx3R~S7UdC@cף0iEǰJh[X?rE6+qS*p#,% 4seI`P"V\mpN<A׉cm.5,$(ax9Y{!udz_{fXT]vyTfϼeXƞ`_V,T2;EڝPR &!X^d;bp.Kgwb-4CP df@5ּp?& tTf%T;`P]]4ś!#Fbǜ΢Ho6pmn{LX#O.EX6`K*`>q^yW@OKA5BA_P=;?qUsG=NdH `Rf !2ITkd .B,˛<%^D%nJ%`L2":F{yWm0312=2 ɑv<`iQ̘VDіvK7,zm9>ttLG_ZX}_VW ,g$sSfğ+jfWJ#;/r9[Gzݩ)-Tk˄SgݥF~·eR(*hD0Vh2kn @&b!:I''Z܋T-*25`n(yοʦѡL쎻/b28#w,9Jd YmJk&:#0WgiZI`4SE԰Ьp51"fN ]JS\58eɄnzv%k>jZ_eThO{KJr_ҪxthsWS؅ˉ@?1$SRǓ؝;TJE$E|Ssr HwTiZ ,>uV~hR Zb5h5EC '82׿b8$??Vs44c;%)ۓҦmmĽ)KvuPX@ioWVU6C3^LPO=]/M,Z4MǔÕp!XuF`@KCg9uU`Or"# Gi[%js3}z]1sFGL~A 0:j7e"8mҾ kƄdl`uFjl1ź6W|CT^wZpZUo5)nϮd}'yUnBj͉ DiI2^㮛\;v5X({6l3<5"/CʌL˯ZٰR^L*Nf}e\T4\/D6,EM}S2Hϟ+l0wGtLFa_\@ 8-:<̡:$iz'\n%}{ AwaN^6RvN'HGGqNֲPəx'*7x_t4J>@2}b׋NzY^\NyamXh1 5Kfϟ~ gxr9u#8Wnt mX0ADE+@Lhߔl}+E87Op1R,Nl.1)@ڠhua-1r?^n?uPRa{s5+fuEef^~zjѿ[3*&Z<͉mѸymƈHy3tژpH@֠;}%*ź:H` 0C8eUYsF*-tTqvq0LN 'QWtj:<Y_j 10( SF`-5̛f}{`q\RzꛏKM&d/p_4 Ϻ/5:+>,Yw3`y5 H+?Ðo<YBlhJ#E"G^Wg-xBC&]ɒǑ=ch}am 3f\$M&ӁwR-3<"=:@@'z=xB_>96P_V$|ޥoӯѼ}gӏg;L:'߾r~&3yPjz3#=9|(W͇7_o7OKO }hx|?KcL}|>_>||>~ӏpBArI̠Z dP/#@:cR*; >6 @y{-(#]K;)Xmyf[ى]L R/t2O =O'\b`A y4ϲeblKa3&agC.}zD@Nqv<3w ;β) 9+̛|>̔3o Vb)=su=JT .&X1B@j4j{CJ-\ j}'E.߳#'}9Rhdo8Z;`0k}zʓރXozozZ*fu~;:hńG0arN'*<*Ő"O[{~5@ר[*gM~`$pM6>=u٪ɷ{8>l,ĵ]%|HAD't~{fl"iW꒨Ř1Qa6k}\k.\`z#>#x{:_MgA_S-i0m(`zH痳A&q)PkrLEIQk  Nq  "]/<:rZW?xh\}kCXEt9:Fzq_X:J COi ^j5jY*&  ڦMt}Z_)[B Z ^/ ]T ]#ҥMn@@ I,ګ꣍%-A xOBx|:rS[cS>aq< %*>3n#йbwz܏jo9^aznx S!e,V|vhp}AN褕:{~k)At"MXYx!-ڽPrgy@9jMkH)W^dZWM tA\?a>K䦁Tk)ejYZNI'3`dp'G6g(e z͸[k.3-pnGVJ:jȭV)=ݢ|=71md/wpHw!]]9.tdp4U:3nM ?zɡ6"{9rD,7C96C.č#pq'_ɣ?A0}}qH[muڤn6ӾSzFW^IQ(qܶ3Q)3-uEոbqR|8㭑π{k%FTd.TPPhꨆ#%&xg\=j)gt|,sh"˙-kB6g+z) v.#f*ɣot ^I@UabeiXuR*]X]b$p pf2"A5+c*3ysxyϯ~ac޹niQ{':v肣&dr79}(DleL!с\4 ӎVwJ܆eP=sAA~@P~)CrGp' + uo)c3[aKP_ɩ5,neRզHXc)!WnNF ^&ae3FĨ2 Z~XkKbVu݇͵ c1s@z%'G 8h=J%f ){Z^eĥA!{kK܃ܷ8`'8|AU\QTOq IewmtJJ|Bhvh Vj+}&4wjo, V#ZVxOZI8]4=+0 oW"YI/d}G nOKKMvʜXx.÷ NcA{&ayOi,7>Vpg hPbO_*rV&_!|in0cT `Vǐb9PQbܰёfBse?ۢ>.]@\:0!/w1726Z|vqua$hٔ=YsQ_쪠C8zyF9 71 =sdk WBKl7pj>;:2[Г6_,J ڣ $kXGyߚpApBFr}Lx3Sm(v[1@%F+rLRK;QXJ_H(pЋ{1 9ldܧrh\@7Tn|o |G׿/w.'YIPzFz J8SVP:L}XIs=*`0Wr"R0ξ;mM1Lcu鄇SA si9]d$i.2hѻըW@4 sԉ3>ZYMrRĴA@*=쪀JJ +œ KZ{^W0z,]+^A{aMz'ݔȫ} G/riw|Ӵ9;'XdȯVgTxroe61m񜃩wyz?44@#eطo2_tzgm?|@?9.%HA$fz!(Cޚc L>qu)@xrl, LMšޜ5}%=R+Dc\%hVfEZܟԄzbG}urC8paRMXyRVryoxC3X+m^6ߝ`0Ǯ O(0'V, ܣtq6U*J\V#Vr W.ϪIs764G9fcb5{r wJ>"*/(tut1U%VrQiKpyJȈtzYO v,yDv49*N.^ShrYϠB!գ!xZySC1|b8tѿzaIcNz-8Afm oR'&rʎ.Ʊz!,Q^h$}ZTD~*<%a<WqF1y:^0fPsC|&'ʏ Q-Y&ڳx>kN<dE)+(ȈYb4]҅zVgWBqe2U?Px%" *Y Inw)Y$Z5F'8ȝXuo`߫ai8̈́zɂ:s(U@1?X4 ҼUa~D^xA|ɇZaN?)+nNc'(fIm/ l"<k /43AL*e!==nM! ߼23HA`ZNrTj,CV$T׹s2x$zSً>kGQ]Z9th9W[QWf:ݘw|_!,w.t`ʠ2A|sɕ?#TMJ's+M!66頇΂%1lp21q0N=n)'YԺ]]v<2 h9\.6S]%j)M KQ\Jt89 aN-d} c oˋZ GGr$Bw0uxȑٗ.{~ NY]dM ˾:G&4PignAE. Y $+?DyCMPՎ L+9i/<UjF,yvES|\O3v )e0H+J5*/^|Ea[{7+$bݻ(7{IQwJm玹#s9ϊ4 ;Z᪨~B: ìf(L^w^{(g8;gK9ojIQP?t?gc3 (r4(NTCdWg}Y.!0,jjEj |]Q=h3ZPY Iq5vm, ,I>AZ[Ƨ(;9X4jU^BՍc 40](ǜ%d!">\sTuN3eoIX Q>ɼAq|='qUٱNfc _hDNySck--(quu%5co+bN ,+1pVjӍ",~ 4f[_ A?$|#rWڨ|p2EU_{6Uc17Qk5i-w} *R0tމa])5 ~1t}relL׷5-ÇܶH'dÍ: /,Bmcąs܃04{0]6e܌s4BcԈ4͍ u>Wܐ=Quf']o\ldvI2?quk,ˌpIIm!a~dҥ&GY\M]| C~i Ug1 i=.k"NF/+IX[ B:Pu xS]~:į;޶Ac|'*QΑ!6 }zR OZm9z Lx1X\?n-hIzvwGE'6 p{P:x=>D]2#~?sCկYH#/hDg:r'+$/˷PzdF5D 6(`m;b$eF[EݾD{` r3йRJyyyb'U8Ln,Ա,3ΊSX[ SiEfEKG/҈t Q@pQm݆bP /sz1jX8󣎖l4j2TyŔ]eDFKQ"㵰JZ- pEd%ic7OtpRuF;k˧= c1UOiɲ߭]P:?}DD|J9)EJv%'3pnOix[=RQB8cWM/}bYV1|NzG6q]P48ؔ| 6T<ڝ$LSezA 0x5jZaAHGhL1:2_)0 喙0ya*5sdyQ#|w\ 76 )ƳMXH֪̚*$kfD/ |/HuY{PReg1 6:?Do`.s U>|(47H\CBqcaJ΋G%J9y~ RIwf\2Q;?[d!Z]88V]&Ѡ]rc|flqOqe'5FKELc[zw;!2 mY n3xeԉj 71/6ds=+:d ]y\@&R3vRd)8Lqs cJfr1vs;P2EZ#U9CK7V k$ bJ EKѡqt5B "S` +RCGY%Y X:U9)O|G7T ,)"(Am-{Io}aŚϭNK(Ô|rNGf!c!S1[zWPLlӻU%UwV Bs#vLK;a݌Pcua6hAjLFGs;݇ӜRJi]Ylmc(hl'wK{."O(>0΀syiq,9b\g 8쥚bx@H@$qW{qՕCwʯ(++~\Y}u'Tƀ6\傊7ksvyף\"Ƣq;x}뙶X\?jZ0(INIWBs^pc0qu*( fRX[ŠwVg^ $vԜiHa\k*>Ǚ"d Zk \eS =Ҫ ]0Ib#'X47C:fLSKMd1+v,=Xen.۰G3*s`Q4t\٨aN{>&g%HHt0 -Ym)X4 UCIbݎA$鄘{zWtaQRO]$.gKFuY2h'4BVR3%˪uV@=EV36=X+^ur7~C+ `Q9O722﫢@ BSEz#3'/ʗ׏@?>g//#Ɣ{y?sF_~o?}_^wkkx/Og';3~)Xz&ó3I@Ax?_8RL,<N>}~z}?~o  /_׈S?xH}"A B&W_X@?$j@Z8E< p`RAuy#|⛁Z 䆏 L39=ftvN2evjOvV@@A+`n4GJ SG;y=vġ8[\ ̣͟9s\Dv'GBΫtt gw`vROd93Ϭ|6EE/Ba^uzϊ(kv7cbP(^lsjvq.b\ĕCن  c|@Bo\Mxfѳ "M)ZcJƌU^bF: [h L1:H>1΍w$gk(v`0 XXl_Kdi;()qD VLUF|q\)-;sɚ".G \ܰr[8SOcT" B?\18ɻEo[(/cu#X->oqjsQKJg?v)G|JdLz.. elЙu)w 'robzO1k{zD2CA^x0,cԒ oɀr\<0zj -,w3.QXMȹ?"'K1dζ  C?<Pr^Dީ0w]8"mo }nD4\oMD(5)λ4DIh2ݶ kc}_5)>ofԿS9:K,\g=*Mi&?g@.3 xJ'V7 Y~'T; `ƧM]WUV(ȥ_H*!xߙqE$*R_Q8`teȮj+k^h3?۾ڕYsq(%J⏖{{{56cNJ"F'p$<-6cRޥ3;i )$J̭q TuuJ/z(TA(?|臹)jo:ۥǖ<^4C4,pKCbdX>N|`UXkY6w^P~ | 7=;hS.XZ yM(7d* 9jѕ֭`7\@P0D-Qm^d{6=J8 [Q.qeHdΡzBp/J-}O&.u _̂>ςM=.GpÜtA_6d) $,%bxd`]jo+排7ãm DZ!< W\=2#-SԮ܂3!G?E; R zi~xk !s.9FPsއvt(5 nMѪZ&_r]j(m>ZX9: B\2E O!D恠{NeF~n O͡#9˓8*Vr-i*(X 9s tdt^%%40+YLd aMĚ]sW~8uqtLZb;QLD;FD|S1m=ư`1Us}xf[R<N %\]N@pv=ѣ:(nHSؐ)c imh*bWm)4DU1xC|៥C@9޲ ^O~/kc>{&:OpItm{ 6-x596!uݎxyOY*;r5(("san{3}Ժ(([|dǷ݉pݿ 8]=@4J{˒:Uv񈩫o0YS.lQr"HinPYw!&.5C UEwe3V)c!)O@Ң+[>yiGAj2;WɽOou* m\yVCɅCGr񣯒L,e?2U!LZ&L lyv1nJqFNQ4E3[be6]"T"璶Vj,XN%MX 7-"ě^txϸ}9Bj ~Z bMrSLEJn3#%I*JބR!BJA瞻JZVTp XC_Ci 6&v <7BkeP(V.cPaiVZ$z,Ig 'Ŏ vXxQWHT7]ʗ}D~O[D`-T2D '#r~ԠqeI#0dI?ϼ2vVY=x԰x88ƥ܍ؕ34 U Iꒆo?Ϗ*2`E0E'DhhS-#vxd+UuZC d:v"U/j.|ZIJFB6~Z8K)(O _i5hvD{K.Ckt' $LD-7I浗6`W?HqPq{&l9Zצ`oNNJSC+or=Ԯٞ賆I~HcK(> OwCz\tCn\i-"_H ;A~ kB#l.̂=_9\Pi!ۉiT@y45yfn +mW?`M=NY-A2j?b/TܤZ{h#3adz|OfkT;##($aޚ\F-Z[XHɺ 'dC߿!Sg\NC2Յ*YlՊF#9L][*H1BNDg҂ǥJ sjRNV|JXgӪ!JhМ,Ybs :awZCRb]3I41=N1[5 9EDֶ-$'D ‘#L2H1_YK,45s%Gc勅pX/C51^jEuv)x9{[9+FLZ [ӎqNV.Ӗq;dj.w6?&3F1!ď8~T4]=Ip"'0 ߏ*v%i")ܾp0#蹥DMnt`=#tcA{3R.4fhU}h ڍ^5eD +xgGXewìyYzPDA!iuHn%t20w;כ1E… ŜgE9F@aR-vEf?MѤ: [nAnѐtv;ZJ9hFwC${ۇֹ[\!}ݳ2yo6C cG9?&p\W9J|T~ãD$SJ#1V֌!&Ά\߫0U Reۺ"Gg $+poEUnڕFY .'x389p!&;0?ppbUIhu12G?t\qA{=fZ{J:)"ȶSEq˞ Yku@ф/5a'.Šl81YV.30XS]֭+PuD~& *!b .\}TlQM+efC1>QӚ1_7xI8-f)4>t#x=:]YѦ ;:7uS(B/o-w(<~Qf7Dw+!^q-:X-0D&C{;] ʰAu&(o%x|׾_`@$`yV]v>rSxNr!&*mtJ3ƄGt eUMJ=͵%ǦVWv/4E%)|G?r<Xh=r%(7bEe ##Ua{1F+6vٯUw̒ZMZ"z8-e #C*|Ղb [ЪA+k:ڇݫ9NR;>l#f5dE(A!cEYu?9AX\3n|JwݾA1pR2;OiV8!m Hz{Ѳ;tpF!g Fhh򇻵V,тd?+aBJ[Ah5UԽJR+515S^PPlҿvP ٥ϲb~`ֽ4IX.bS{ʡCXP]'{@鍽΃;)D7 lmmt׺v*^+ }/jXqEV;66 FtT&تF6X ʒ&cNYToE*F+c wp;[5ϒj롤$vB71^/vMjK^rb<9mT XMOÜN˞A1^uEڏ}PNvf;|4]lm gd9-pﻃi;+W ;*&kUo=6S]s)sj]P) Aڻ>['NCG0WUe FjtU&^-PF|e|X2*zǺ쥠ȷeUO0C- ㎢o3]0aBrz֬3t{F߶^>%zN%zC;"VuQ :mIFz”qo'#Й(Z Zs r<>gBC,$]M]k~WZ^4r⌥df"d;?~W$U*>$?g/1|ӧHVǿ?q?>~'{~ዹѿLOŵ0Rwq?}Cx_?O~o>O^?=p# R<@׿|~>=! =??S(f<̰/Ġ/ٻ$k*:SI;b =&o C}lx66[65PȨ$`b#6<  ׽1.YHιilMz5y0+H9`&`&]b 6F,lU3nTw g[Q~VA͈308 5=#'9yƛd9aj? F3 YuoZUqsة8"Y^:)`bq Fp!^>3Wʡ^<"*qQ`w ;k# tb}|݆rI>CfsL*9هZ`L}i_xGΣ 0Lr4ʳB:ܤP>S+Fb-jzR9DAPEMN{LKF#(c'`tky.I\]BT#.C.DZ]DWR kuWlzxYi :guXWq͎jCj@^pZdBQڷ*ENzƥ4jgg5P,dy^T)U5 "=jjɤ1 /I66x3ޤ)~$ ) !jm+)hMW *JVSÆ8.9hѺ+=2CE`f'' ˰>M@i{𝉼|Z+ nhWg:Eu.+m"wGӃhzw:18 b\V\_qO7)#+KVk1gyaxx (3hnug8!n3TuxKK:[UςNkqQNd]> iC0ꇛ:5"ol&ig23}&J0HZ 6UwV!,LSlIV6 PܮE&g񮐝Uy̫*ĹBϲ>ghpnz]7D+CxUmtd+r+:쪆i>-4ڤ}:K7 (K*Q?Vi˅:rd+/gk 'q8o;:n>Wcc9k%^LEeѽ\khRIuSrW L@40 1u;VPg$^1NY_Xa=REw߬(_z ޥ~xeNpb=UEk% O9fMNjK#9қ_ m$Xk)Ԃ/'eO'/ПO)>hDU C6{<m|n0}.-eq!C^÷.D@[Fq$N\x-i~"\d2:q8O\pM~hE,{-h Y)G xNB9{t&[!op_Ӭ)VVJ)HhWԧN\!4<PA%{w E8$! P*-IRVL@yQ{~s, Lj&ƾfU)_̆ ] #E4!u'~ݠf,Xkd ٝO]\Y.`jh 9l'z=*E{=aFc#`Tg:,"@Y5nJl*_=@EF (OŦpql8*ny;1IgPqs2(go!YWڀE6iG,Zڶnz}`ӣ}6\bH , SUJ:0qڌגa5._Fz$2댰kɚrA k:a2+U;:Vou967‘ 6}~Lw,2PjF6=5+aqs 6lqL W)8[E7Cjgмdc1_z=@@E5kt(e@+~&% rgҴUhqG+"mS~Et7gSZ:i6saąrLGlP6;Q )6{n0Ɨb+6͇Túy.VlZ?h))bv GI;@d-ΞA( iL֪Oq{,}Wf Ӹ߭Y5Ⱥ ] {.p]h .|,$@ĽT^c[]"4A81=8Ȇfɀ^jŠHw%Li-ÐY%=O}z3d"do`|h(' o\"f@إ^ Κ^kS_N교BWUY6Sx2*'j2 _q2bVLm[Xb#UUb_ #(ɑq6B8Zi 8 Aft)?8눱+2a rxUҹ z]6D䂜PEls.;cI:Eܨ-nNuUx^b hg avr'醮CD-{(жR_qa+os{|`388QK7>̊h hުURv/5,Z_åCh7bduUY䑡Fyyb1ks^f[?nޝ8l@Qzj<-x_6FZcߨR"`<JHn'WѕkLfcZy\.AH;M-yms+_|ggc1_tat ~6[0䷱SJQD6uCbkLh4/#Qu1MTGNB:ysx˶vϼHŏ%BbAcUHA.B b#(Y (hQtkR$d& { IJPfT{ A]je).#7`F`y8 -٧Z5.5aIޤmَ86N6c-#O;} ^R(eH!f=b+4Y*jkt$9ԭw%qJɁOzMnƖ"}XkW ip\>wQ1#@V#6H "1-ӻPYn϶pmPFwE \d<,^t6P=ԀDzդ@q\WC@"KiI>ÎKcqET-@"YjLAmge?nԁ,/|`H}֭fjVM[T|d3 B&l97/ es$fT[RmԫESA8b/k* 0ɛp|^\q5Y|ԇޜYUUO`T}EG"z/^ݖϵYsoy|"FYezuISbA T!iKS3/_ 9MY-Dn !&Q*rԭ39psllųeJueuH!}>g߸*dl!B7tvmZjFk%Revr>mYՑ1#jJp,/ditFs 6ѸMT9d݉9RgKIV,JT%0+hrv. N-R۪`&^]MDZLɊ bԆ$DkS*Q;~Q&/a CKM?&A/'#HH&s䚙yѸDYX:~,n^d{\gx4=!Q95@Ը6ZH]eԺ6M *Zgjİ cvnXlGq7%eS?C“~fWYt]5ծX划P=cB Pz%[ͤWc| 2ZYc%sяu?$z}kˡ/ZhJTiyugrIƝ)_lH9lFɄZ׮E|L+nnbl9_%%Sڐ\7Z =y.j-|z"7fl:.6 9*X[GKFҸ"w c DV؈!ά\ t28HD^B$4V}% N]Ti=rXi5? ru:1\>]YH#[C.ÛYҳjW,R$[o{jApSgu) ќXҠQ9U94h}zL`kܲxIǹt.-FpzBz&n /%3)8] 5iC_KU ο EZ@BOR+m8%3%Kދ"1 K,i/kjr0;&֡bOld-FYQ;_bT#VCf12R_Vһw}VAZ7EMong[*8·^`}H vlUmoYWJ[TU>s+κֿԢoWmmؕ1aSJk6onBͣe`DAj;mଲuBQǷ8Mc۔nq wHJ6.Hέ7m+H'%C#\bxOJ,=mwieͮ_bq#^Ž!X^ "@z>wGrй\r)j~E\DZtnݧԥtXe,\8ۭJ_|ix]!?t3<0d~t' fāf1sA'V=6p?*>!}bkgo,kJ:߀t֙Ʉ<CnJc.vÚQEvlfkTӵϢ)i{&%A h]D=k>[eGY(UhFGU(PGBV5aČ}v0"]5Z(d;0-՗5"߱NDPs8>ZCDNEo94=˧Pq :Tu֕q6j=:[Z2} Ax ܢWwUNe9,؇Cjx,r9SٜhZ(XB0%s {.-`@_vK5϶Wy>sIg mN~Up41? 3臷=T7dQS>ɺzF^yaމAEjf*j$cHOف2ƫzNxm4v`'$ ɝ (,܁d"ɓn6_g{fdQ6\8`e"/7z ?: *;\ +5>&-7|V" vH~^QGЌRk.ahBCx-]M$m= @~sb#jCﶏΏL UC)(9aM_#~>SߩJ??U.Zg`1?} KO/O?xo뗯/?|A{Kݗ?1X|^_~}~y~=^K-?xOG`>ӟ ~:@,Fq(  d$eq O_ q;^^h ]@z]?(QƄW>td_^0% SA lj}t:!)~&|K*hL<>+PƗbW1d/ H'aK@3fF2+GY/Ωw~}7Lje 'C`Nr~(^G.|6=KVsF6u_g;יXq*$ݾR{$O|P h8{Ӿ:T +1H=4aKg#Lz,+Ϭ:՟U' ֞>8\pa'd+L!Kw^v<-pmpuY[VڗbppsdS:sg'%5͟tfvmNwg/ 7רS,T*Mُ:B] b>h wH\pQ~++\kt+EtApsz噫:vM@`MZF`g27> 4n )sQx7uY 8 f#P;듣>ArzADbθY?C? :,N ~B4JyࠩO""ρnE0?X阰uJG6~TB+!eTσ)7M^ }lr6%pp5°yuI8RLl%0ڥzt6yU/(!Q'၊ȩrdkL$'~Cb6hfC1%|Xǹi@w(y{e{nSd~ȖT-PFpfƗoJGK M&n\E;$J=(nc5AnOmɕvԖ:,6go(@,e'*wFČ ;ZRA$ qj9М_覑sXרwUݻZk{*ZU%>"sMyT9q^d H'VUh%ǞQXw=#Il`xL5ciF⤕&8lPG ; 6\x]4Kd X=H{,ZTaJcΒ.DT\tr}YC[#2k9M9EEXKNfK38%}H _Ɖ5ݹ⭊5!ͭ:v=ɤoUt FA O1,/]5A@ds "ankN:s ?mcӒ6 mD?b4X!&v5dҵ@"2+K* c̐%@e)H~MM"r*zWX[6睱<܂8oGKaTz.v3*H걕zn7e K!*VM>[V*HqLiW@n))dx43rkM!.+s.'¯@TpqO'  붦Iy Z_*Ǡy䶞?rXOG)Nac2WИEPHmC{ŠojSk&6U #4BOP )vEפ|g?r#g_*_#>տ[Ճ9KK>g1*,!F]zE(62i'Xǘ 9pEk#I5Q16gc#wR+>ئٱ ٯźf )M)MlP +mґh1YCX]K$CZM\n5$S|YheaemmSk.&~ޣjAҪx\L|zOv 6X%l6,T%mB"MPN {rQ76 .W<ɾҿFK@Vw:oڭq4)N`Xu]ߝyK7 MZm.P ~P,l3/ܼgfb7,Ӡ@bF2Ýtz4}.VG)\؅X |@2_T~Ts>7yw MǜoĨkUgQ-N_OGrpm6[@q:hE57W*Xq4ca[M Η2b>%Ċ=p8.|fե]G@ nU镦RRIDWWLUJzR,wfTFl&u/%er버Hs$nVYz,16N!eJ1sBZ+Mo'&Gb#?7#ߗ $Y!Yv ]J0gb5ݢ5jCKyRLFǑJZ+`3qQq>gW@pyC GpQ84 Ϯ

_F3N=ʄ$egUŅ(bBQZzWvsCMbּw&85cvrwv&ͅ6uBڴ:0֙)4k,S?}>59|ko}^3Z+" \m`%CU#n!F%Q60B+Hh4GDM}pxr/ IAܺ[wqwY p7ynk`QW ܂3AhEc3ƖԓP(IBE̍JNm6+]uGBڀ|Fe"v{4Λxlq4>np(Ǖg^hG5#\ S@s (d{4=|4!FxAJt(wC\B?"CĻ9',!:h2w[Ƀ %*oafgP]og>J^9̧`>su$Ty3k[vf4^}sqmQdPG*®Q`.UÔ;,$}aq1G()lNzk;vgV 4O[+ `-Id$~qnќzX3=JjPSef7uJy]ոPhv.Izz'z21lڔ>xҕ~dhMͿSh?Plcqbp37ilHG<[DA<95U/>qM6'enǍs5`qE2|-ԩOvoY{nVCpޚAȧ E\x#ܪ<XǒoFdnLa_y^{1]2TlGx~1\ucmY>D l\&SamXq="Eܭ+^"q7lç|s%q]I/sV9zZp/@Ӂvdr8T4"VɕB[s.:(k`골on_>=;56LG.0az>Ȅ-X!v٨qcbSED-Ρ%r)(ItC o)}._W>g y&Fފnf$Մ'XRlfdX;!N>mpٞqɮ套Ymٮ'ZGa2)g~͕HE|ma PH@hpjv8|]9䟽._m8!a\'*kǔ Θl0զٛ3>%` mrzqslG1̳E[w[q(Uӽ˙pD\,TsPWWasmn&Vt[J_jvftEsMR/bo%gQZSt b˖ڼ1=KNtt4c 8+0L>cYcS]@hPjex8QյviBeI8[Pnק bOX apvQnЗ^^JV6>R_`΋mV(q 3~tOeO% ZX+~!@ڀ XU)?0/j xvAy3th5fǷyh0r#x}  Z%:r NuNݯN9H{*Eh}2!Yi=J=]uebKP"tMƶQZĵxO\jؒ0vpnK8(\t> ۠HaVԇhT3pCEB@d ~9W*[LZ~l8&$>va0-%z4:%%iƍFn]␇7 H>~\\ ^M6xZR?h ߜB0?KI& W`߾8fc]5DSYa_;ir? t -!$9Ɠ"cw D=Dw\ xX|WVCPRp[2ʩ ۘ/i=UlٿIjlWU*HQI?;9Ò9gtzTUS ^@14XRoƺ>>j ioJ4yް4PomDZ<ֶD0>HMnMXIZ"T{"Z0|bںD:LHWgYE'^PF(/CJG?HT6u[}'<^ d v(ߊz 扃h*L_BIfeRsS<)"֕Ղ{U!l1]EO/ٖM6=Lj$Wv'qNPŷ8ή,Wm4ޫsl^:PziGiC-~lum2ѽ8Zj.hYe@jh!q4!!蟙l͵g8¹xeD7zeL$spn-D~*B| }MږYElh"eYB&uaX46Lن Srf`b;cuOuL/qpe.c0M Sy`ʷ9 Ty9e^VM2 f${s8)}GVif7~Uy1nS (MA}̵ nh̪v kd6w[S=.2 ƥ~йS70V{tp0EG^Nʵl|$[DBDseTsPe*MLeW:+O\A5?Jcud$_#M8W}}}_B(`^i#bLE՝s}"9=SqhF18e/e;:;c}|+#y>o|,t'\̫ byO5ƍ@xݖ SlحѥIl֧fU#!;Ɉ*t|UdU~zvc|b75>i؀s[ّBp[i='ZCw\E-,_7J\Xp6[\T{6=Fd1J'6Eʏ$\ >ѝz8ۛ1NRBhQbl)ljIVShHx-e`Y'eoqẲwI fiɴg\֚v9 `M TCOQ÷ ^d'S?nTE˥$2tU )]D^vT|F?Y)Wѹ+^0c-;doV۞2?2)Iӵ=viqA['6mYunfj2Ci΅:b7w-{FbCÍv#%rRG砧F |#7.k=A>Ryp̛4uPMu.bξjDYnʜX9ul? Y9!nVkJt x8F[D5M1&%fmk$- iRzL!"QEV Msa)c )湱f˩]b1T}> ɷİTt$RP:acwBk!0*9 9֞%j!hTq$a/" yhjCXj%[_6w}9йU|' 65Iv fA12ݻ}3Wb>-c?*1[n|:ai_ym% nhJH ~"ƽuCT%[/Kݮ;5+}؄1u P/;WZp!TjB @CwtRc}ýXv1Q%W xf.6 H=7F'AA^1%s] v|6=x]1@P8a1vZk$Σ? ҳƽ{B#+VCQ<#X"Jӡ|q딬8'ߖ|c[vD6[v^%N 8ݴu0p,ț9iVD6 y2VR\i%"KYH'/}찳7u!{ \xi(iPZ&3tBTHEG굋;3׺Ĭ-\E'MT]̠v jZM M؂*fC5H'1S!uݒ}hw d5Ā ,1_D̈-nkn'fڈ="' oHw#{NXpi[F)X^j'c^vXEbyuPk~4ϰi)Zz ܵQ{uiQAf;nm;IJS([6=o_B\{Jȅ^z^wI\3Z::)i GtMm8GrY a'<r xSVxډ`bJ& M{ z?/PkBkj!hٟ\hx[Cc^MUL8|1k5%>HHAչo!osb opL=g V1[D&#Keq7`dS7hܹyË0KdG=kZfzguEd' jq&6Ծ5-/qK54>S!8UdbšU,'r'(1SYִCs9wW8D5RĠLD8 R<:ќ:2n.0tqgf>w@, zӻtlb8\Kx{:*֮Fu~%LDV,>B;鍡\dp! p^^8BtG IIX^&mjN`~_wj@( XcHW a֙k5GՏ׌>uO ?~Hlsڜ;Ԣ e$%fttH7q $}CR^t3hEXrZh;:zz= wڵvB(m![t/Q(JO1F rE8P]OFWݮ$u@Yc_{;3lЏH:S1r[T8Ԣuԛk_'=a[tq&囫>WV&ZC ν 0oV~۔^>;$vVZ|>ۢ6uvWsu>`mA 3*&Jzd>h7%0cZܠC [ 4+&sƧP.yCRqMך6OgUE8ͨ~ٓT8RmA7N 1ܨ@ כdq7@ 7"'og%,:E9֔2>CQR9Mol\(k9|#4BgYF( q+=MCô0~7L 8M8`t&y-~- &˲/jڞ峺y).WW w"cligHToO\kOo㐵Mk@~T2>zbϣlIZ*ƇLf T7R#}!'I#0/MZ8N0 LKWeUrn$]vݰY8EzC!n7ȓh85Șkk^L>5d?Ѻ,,G+vR]]67Xb7CEOSlE6A|mОj!wVB[tTC1{F=TT,QzBZo7KA2X4Y唬-y|d^tw1-r)_@/ѵQͽ]G[y3΢k#ͼ. ۿ~oϟ~)?vs}Iû_ӗ?N9?I> 'AɄ?Lz :iY&p 3A{wA|߿|.~B_dˇ/~uCK "`_ח म~B/|@ v( Mˠ9(kg!}+d7LSW8+ AM ~'x6yN-pRTk#T? 8=j/p Dθc0^}1"N]DaUc4V'C~Yϻ!O%?,SSNM8x:q, ,a+`7 rGl6"'3^V=0NyE>Z~;lҁAYax7@ r tvwj}5A2WC Y>.M;>caG،εaT ]&/ Ey" /&Ilgװh*hAED#Z'0_>=!oŇhp#B1pۜ@x"?"¶}Va|_4m6O:mJT11}q‚\?b*!$AqHO-ik*|Vϥ6*!MRǣU|4rKm NQ5Fr8͗,~KFQ{KNp荨K^Z٤0t$[e tz(5ftvSeT2SverҪ2֙嫑@-*\r[p[T$yF +ETRm\(о NsK%ca] J@>m:U] ݒ5O%4.@Ԭ?5P-ՑJ^t%]P %voS0U9vE}Jtz^Le'P7,5gj]\1rݰAI.k(Tz:{tow6uvc͔ O3{_a}5PKGw W+C/C7_vOЍЍژfH,{d[;Q."Uoz*d<& pfi7"{ޓ<3X͐̈́xnmb, hpz3<84jE5ht✡2/:7pbxHnpQbLr73&;d?rT "myu")' ohòmHH9Մ9F_g?=Fsc"ܸ6aepzk"@yWbFj`wh}2Uy<U.g:V>Z@̂D.3􃑠ړ`\Q{EՙSU;X+O|{63dޖ)Y(\= Q"ĺmU%aB' T ,M=Ia g0:8pqlzR @5\6!2l<p9:b̛,|H֎Ē\ِ)9Nóz 9|ȡLLwEfnjJN;6vV26/$klz;HR\찢;P?YV9v]v*s^(3-Su˅}~).X3ΊX;kv1?߂s3ve2Q h&#5QGH']sϬӾ5]Bpf;,li^PH',4Oc\p#-{ `#=>n ]]>)E=+TX֯ 31-ͳ24` |v>r]b]ri@[\]ly|IhznuWcsGDM1%IJ8뾡;Mswѣ^VXJqW-$gud^7<+K/;i$rܽ=gzmLSɲw -æ/Y$յҖ ”"Qc|I >qtζ+F2/d$5-J(tE"2/2T\k&+#QKJgЄ:r!!g A78krB / #Qܤ9x ue"&rRHN cCݠ5C*-_;T۾j"|7pE!ZtW!aFu|gE?P&-0r3& i?ST-PYZ/bX&K54W@Pcnz1كLX'e oppiC/*T*B0 lj[2ԧa[;ٸux2.=LB!nTTK|V6@,fyKRSS׊p?w_ 3)7l*PW!Sth3uwe{ i6]*+}Ϭ ȱ)e o*ز']jQ)X6[H6¨Mj.:b&y ֍ouP_cS.cڬ>1oGEߞdrTӹi'd,+%X%XvARf];d2F]#A scjèHr?J, ް~FSӦ{-\>0j4+ծtbϪէ`\+ ig6me2ok Gҳ`.]5 nM 9bWsx+Ej2%%K{[b_ UĚN$٥7YX4I[F;Tdž5"WQËLwRSmɮ:Ҝwuh,y!۽Nz,[H^eHz[Zfo y_@=GƲ-,6҅-Z&W 㓊O9CGKw\Axb#=q,:r~̀Rs)vč߼Gqteӛy]2V״ F_xnT{k9ne&N[.$H^Xz뵕wJ}jϡ}/]^n C<;ālJ}r9d:ZZs״I[n紳e0$#6a/u~Tif9Δp!g#4Pq0yp`(ѓ?݋PZDGYTF!3Xmy743 bvL(.S[l-}~yzCG@!c&NdPp2.pL/dW`pE=?!绸0[Cԍ, %ZLF UB~pg1+1:mvmєc3)3>ѱ*)Gڝy' ƒp5:+]Nefͧ#c!U$'8-͏'}Wm,/ Xүq}!(Zԣm.K̼$g Y +;k#e){ 6@+e8.H Rs ,96$. T\ں%EqM2-N=XbX/;m!jvYIk%+]\ؐA*25+rqM[zXgx҈&?.0E$J뤩. QBlM&!{}Rڹf"_ I,|HԂ؞mD\KGPCQO,J #r:О_2sʀ1!=Np͉ Я2ޥXKo $nfxR]h}V؞Lj{ԗa:hE x'<vdz!ihyb59V.^$|S1LEZN_٩qG׎%)4ީ;i<itiANʢ{G514E(7'O?dUp%idbu]U>qoZӕFqo_5ȺNc* mlc5ވa\7+dyZ3=Ǽ`D>*#pؾ&nԧ¨qE7bei)CoX1".+g`pv*W*iD޻%C`pVnXo8|"i"et lrAJ3`f`g2 4֡l=1)Vj?O52u<\t'2ݨf)=7*brVq %'gsyU۫(%ܢ2Gl.+:&WN"5BBjt2'íWv4jdwy+3Kn":U.w,_ ^ٲ1{YF}FRy额 Pw6)բEaŠtԪAffRLyXԅ0jLLםە2HY?nR|2mr .~ ղ_X!zcІmUzA{6,wHtvqk{ A=dUx(h["n~AYlnT^0D1%[e26"gig[I.2x(#dߤ3\BczwM|MN`wi4UC=Q]}简/ ^E{y(e1/\=9$:V]kKXN ;>M̑=|H=]hiMϙ@N{.F#HK]4=KZ?3S"-lhǕj "icRӏ[I2mI&-PLEE;|煺??d hMdP Z y 9éBNZQ\&s0kUeE%ɱ5ꂺjDZȦV;] M:𺸾Im\n;*\֟uAz`m!<|yJ[M`f?Q#.i4$''/AXCvϯm~h2~2r-*(gM+jQN ̮ {RΌ`,xV[n1t/[M8F =PyIIĥnjR @IPwdY?Q% moXGw5?gnknX\ jMoxjCO _TǟL3m&tG_{"-=O*?'Һd-{FopGCX`01\ /׿}D3)fԗt5 ?řݪW6SEi++qHR3S旸MM(L?ns(B7kIibuggtg`8DVbLVX(4KUݮF~ޅZ[d3HQSQPAxĆT)"ᕇgXILM-#IlkZ!]CTd٭ rl%wu:C'5YW dcG u=kDom ژ rf:6KqA/ 8G4PBlyoҍQ+#"%n}jaLonR|R n ZSwmQ ̩sOfëePV nkbMҭclƙ!o5Я>*wRR׀nuZހR49n ?"6Q\?eVH뫬8Iѵ^sz؁\vHiN'Z(N &A^rkHS^)*O%ͱ)*{ a|2)gt;:qvb DAXwÆR1bq.N$OؚrNW/|:gI! ]<펊 ;ͅtS~9:<&|nS(eTcxؙXeT'/)oGOxin?Qf@ϓ=Uc<-g}Fi l~3Ea1qS$KS v'Vrk<# NZ٫J0E?Fu 9ݱyt$su2Z[dPD9Inܘ+6;Sfb`ޛ-do1\]G2 NŒXҋ5wGxٺ|;LXw"2GISlzqdh{mؘ!z2qon#ǯ 3XͨCK;9|5ŔT,?.8&=bgFη=s:`q1C_vFb5%$̼}_sNĜΘipAf~.WnWXhVm*L׸MuEukϊi&xzOCTA莽~ʅI.ke356[nyU, a-Õb),$n[=1 _<q^L 0 USV|*#BvWR/lBlLlgjB70ׅ4ᛟA g{_C0בg"'^iw+/}]˃<,tݓĪJ'~֖@Ne;L~H y.P??l7,wu>u@Ϟtdg&'G '3 z1/cd 1uez˘ /4u`ʝfsu-ek|(0Adma%j_,a6wsO֛Xި'x@,ڐ 5lV.F{ŘJ2I 0#-RH`:譵i 7yq){N~Ft`nK 莥i[Ck1jѸ ƎMpV񼸾xW+]&u>@{mwC;M5yqZEmz-9$g- #]Y"_[N6&i麬:' ʉAc(aJ&/L`W JHѻD=gh=|i_;-#^,w!;NT{kj&#LvYЌ6p|v}'d!n>RA?Ho艅tY t (z.%W.=NI{5^zZ'&9l<]cm{* a~}VSO_uL 4(_wWCp:c M_Nn:Qo-zS “dzb *_6#i BCP*]˒\Gn]B1PM;B{xwn&2*R0uZSpp|yN O_{}/~T2oGA#^~ּҗ[oOxy˗?[z/?o|~w~q/_/޾g|?~_c? >H>lO3!><33) 0yU_OJ+e\x׿Ii2w_6LdAIϿsL4\G eTRA܃ ZE@^>:}Qރ?gnf5`UVg`r3.? qj '$YKW`v nj*c/d1Rg`/ Uz[lo&UAP</[lGԚU(3nk3tJl gkQ]M9 0͕gfVsZQ&>NdLއد׏a2~q CWt㗞f#pmN'|Ipq4}C `50 /_aAΡRS!~DDm7VgfhK;m <ct< ƯTu\Ŕ$j`ͮE)n*o+bNe&~D%0!xnI~XPYP sWla1]^?Sqs:N._K7c$aap1ɹ_·OLeO?>Ӿ7b^e>ϯ_ d;ŸU4MfGɬ.o̊Ԏ.lt`vG"ſOSe&&MBMj}X&K.AG+Ը Zy7pz|_=x֭= cksLA&ԾPaOha.43TE v3ͧXL\Mbq¢)Sy4 z@4;r}茜- D;C"&FbKPU~α.<>We}RC۳bFâ#ҋc{+~uM՟Z+d`S=Yuă49 yLۈKB:x8,!@w5JwHl#\$9"a [@-|쁝B#,>prW2V ɧM>e s9M9E4+C5%%e*S͚{޽Ojb+CX9nqu^KY ^MF6L-h_vanbi5-3tT{=Vr%]qyV9{t5v&k+ōF-0эY S?`,)jL e 2漚%4>9#^Fs7抸\,U}ya r?_59%&W[S(B5by]-wɱe#=1R  tRt[#($$3;mO~[y"Y>YxF|({vkdPUp6pSN#T0`;JKץsreV!LP~l[{{p;U% 1*W S_Zo-Y/~c+Lz'He쐼*UbLU>9чV`ք16]sda s6jՖ̟Y"ok|R˧P %4,vap/X~uqqedV`8w(g1?`5FK̖2cpsrA Jn &Ky,݃*.gDbJ732EM'xzvjtna' <)T,ם^|Уp9Ccs?(v I|-Ē13{r.g%GJgE9H҇uzqӥH^0Y,ObTXa&n Jg"-j_ظ7vm܄ʬrg=9,$3 ~d[{"*#LX*'[\pnv[U6W+W~ 7~b|ep{P*X"c Wk<OXwĪRaA7J`kƻ[[3zmOVd)-7G2; kȫi>XQ\C\  U@ˉ+ ^{fw=l$fO8IlJve3eH'wq%]D[K1/<P2x="Z'RU׊) Yx} *%Vsm{2_(Yg t8!E4ֲ!3;vVsR)\vG h!HDi츶P^~`Wd28Y!U)S7Zk #g=+,Sɖhj{}v%r Di!wsS`5n̝bE7=Ⱥ\tFW:7FYjRˠX޽bl휍RT'jg e$,^ 2IzK⎘ +(2P[jPꠎups4{R"*p$*f#69 cZ7eʹ^Ueӿ@ HBQC^y?LZvŧB.6NK*v`H!"lE#TDoL^gP > zE'7ku4e,8Ʌ;diDB4aYdX.1pY0nb&Ap!p I fbgȔ6 5#@㏤mYdՇ).b-0iu-K QrNAH#j 7Aŭ] ޑ+qș?I3^b''j-.Yzɦt1ETwO2O [aTzȒI?@[,ZQu$c Jf+TQ!s>el NoQwtr8Fzqz/]΃|'Sx3\:ʥMϏ%ݵ1ǜă*_N|wƦf>OF u%PCkk1aBO*rE2Gje:wPFB G/Ÿ{sAo7*k@;7&rA ֕)C>p0B/sHb\z¬Bʔ`K ɡ!%8▎] Q [h܁DkBkJOQڠd0\d("V}D,w1Xө^ͲN\8U 0a- [ZH4Mԏ35XÉw z i&lD羻p!]28aqŖmҥA/bo+f6ˌMG/T79rv^ףUjM azNNϔ^;%Bxh~ޔ;Eԃg u-iu.%Υ0ETteUdM+Z eWcpOm]LtTPR# %$a"z~1Yp8\39/V47/0y~Wa{P`cz , m3@~u(ui=FYi}(gEw 2TRyw׵,}i*_[sg? È"9Qvo3w;)(VCێ1lt;==vó6v+^V\~8,!z,YghGo9[ Z=y}sh5G)t.SXS` [O%47 !z}!3%9,Nvi|>\L%=nPUAR хu&^%%||FcsYMSzյj֔d7uzKF]r+%AƳrL*=)W+U*\v5R[re CR(\j]ǿUfq9.\wڃ ^*qWP>` dddّrgWZ36tdQBUk?hEHE8Aab|;—TE"jK4_L'7[ث4;N*yWmZmӺ`+>s+2EvDc7[ysHrqyQb8?_wRFGh o&_W pCT*"jݿ9Xy*ѫ,V S+'H:a-iBeā8nd[SKůPd)]cgrdM@)(k6nvp25{ʇlԪ#BfTmOY|:V?2w-G{x| %쨃~ mփ4GLWHУ#Ψ1(BފuDay"9. HWwCw*'PH5Z.N=ݙ0'800;Ywe֓Az|4)%z7P5,&|"Cf bp܎|_80:7IJ3#kؕ@ U7oT`ik3ashYG; hg`A=|ST4֟|*MGt 7yԱJ= feȃ]TGk IK o%7:뼔ʀeگKnIXcݼлtW=G]=Y#7ݑy^5bmM8rp ZקH^-QG&E{znnL63v8wVHB!vs vf2l؇P2Θdћ(geF]5B-ZfMc#8u+ڴR+S9<vuk2<iim[-CbP(lTF1EAW F *p1:HE-Оvm 6  TA.aRIkKaRڍۼr1½EfYA݌P6}!af9ȕtEfXR;˽%g iJ]/LeӾ50M0{x5Tʹ`6bmpmer 9eHbuN<;c 5tɘ1<9]Vxm8&R[ A!m*V\bEܻSq"Z'Ѡ>  HYLa_K{uV) DfDNvй_#-+vs_hkȲI{jt2tsY w) :xwpW(W V\RTZkl`;5ILB-*Qu!zC}V(r\j$H9K#qjr_Qof,m{"Ɣk#V9d7f1/`=.uY^'wvT5fx_5y`Dv95*C,@z_LQ3-;sq?`ćw-=9&LdWS̿Y d@~:zAekTOxzUgdYe{"iQrSΈghEt4Le/.-*N(UE *3¨uN[HNXfeɟwogvMY'<}xQBK0ynڙn܁Zk.n)"Ȧ;LIW$FEfY#72[ǪXd^8+ % r8>"@rvzJ.mafM=>CjZڥoIkˠƉlPRѕ1FJ*ϚWB޴&Mn :c4l|X**{"{ d7z`%FGyK.}=Mժڻ?rd/݅0B;`(TkF&^A]Mϯ;2>偵n EC2nL --Xp4%as \Pjࡖ+n;|$)eyD=q2XYW몮 `BZ^+< :]TvS~pz`~;޹7_ii[1 !0;ĸ!ٸ-1€a(h1iL{5-W6u((]zgKq%7R(NT|sqeUf6 wp~.&~`sVhz] .^t.yD){ ,#{зaD\ymbE}066@%a8M;UH]y_%5w*5z4 ^gdݎjR5y2 UU7ks=fT[AYr wV ,Ǽt!TP_|ANlƃ2{=3nsvT Qs-vkݬK=Z6UHg"'m>JrY#,jfɉ VNAآu 5Y36q`Dۀ)#N-טPi-T5Xƻ*͵_KRn8i^ͱA t㔫W!X[?d> !CK,j[Zr78Om5υhn4G!gZAWWxC8XI잝,v᝭VK`X& RB)R A6 ŀv}cg%:tl.o {,n8BYC)+Rq}ybn2汚71sgYhm2+tM҇(M|5U beD7đ_82Dn18ekQ M"GXخh/eYG:fZf40"ՑSeVfC\sA 膅L( a(%"y =eX$L c-^H p ^P glnL23]LFi6#"߉AZަį+QV|;pq.nE\t2\k15gvLSKoa:"C35#"u5?=&e##*Ws58fst X k3yDLbR_gWEnEh㒑k*UXfH+O@0DI 6;爂 8!9񰶉ֹpaŴ'K{ 1P{ߺ4|Ӱ]'J3B^VNmtܦ!X40sBPvfq{e ”9I0."u,Melv<~OzeH+ƽ{ͷ9WTQrڔ8A{o_RlbǾ4Y(a-6㰃?cҁڟK>ݸy#o.!+]7N݅>#j' N">5 F>CbF(/,+ފ}9zͨDZ!nșU]LtR^ oy{ 7OGJJ=2j5\8,ҵu&kPy?ƀ3X*iPkN~@̣ms?}BC2-}neq[ZDf U6 e5{g涇;2>J tbdkvyo36ZZj?uǿ q?P(hU) _Ch~Nmx|F[0. -"^o;lz뿚.Td>~cՅA@8liu:g-J5Qkڦ0ĚA:%5"&J(>s@˖Nuõ) eplqg V n;ٿSg܁cPF=笲">w]y=ut{|؂1g|?eHAt=Pٟ{$>ǮpO&i4CO`HӬuwKMˁ}]. 燕Q/ZS}QYpau5!Wo('9$7ZgI>3+c'BHR5ׯH|m԰[Rࢭ߸qN<ǻgZw ԳIp놸˔Pp=Q l.Mrayk5z! 8u7Q:|2;`wV=>[o?W THNh.jK̳aGǘ_G_g>[wtc+_=.XG\?. cP%hl5Ȏ^ΚEI2X=`^v4RvEୡ]N9SN8]v&|j5 0|JܵN"/|HO#@ Yd4dFSvv>li|`cM\˵Hga' " ~hNךl^d3F UQ6I8#S\Dc]by 6! L@< n)$.RүzWZ2::96BY)M[_ֺoϖʶb;"\H-H 緗-]S#I&``f?@~{ej]Ot"b[a\)QA>{9_1;;p:ExH_.xnqvcR "L!puRLZ]FÜ>N')6-BsfZ]תgk K{CIysFLlzmO5jhyD~Lۍc?2-IMS+\S4"m娷Fus>VvdVgB D[ۄ7@yk[6k5>N]ͅ Mg/~\Gx]OGwu D*SιαT|x֜"fe=)Z ;\g-ϓ<@0^D Cmv{K(S PO \V I.v6c4)\k]/Xe٧8kk01\V@z!1`P5IEųQ].,sⴖyYwB[us$_9vk/%9'$j4esLOpd!&EOZv4gLL$0Lwi%)&CP:Mާ뽏e'_MJ6ZC)XӺ ( #Rr(&KrXmduj<-< ߤWݚ a.Ōk%op"Jn8!ƍ`&EmR 1RJx!D.iai9cIRePiƼcJ(V]oB?a!.2A8Q=I.C$*>,(y~ǘ\_ ph|j ]#3vL\/rN :iʆ&3@L-_R&u zi9ps59oNt6|x:zŮv&mT0/2T={pv4P a5\'1#ݨ.S]։ *Ks U%t-?CGḬ3^ַL^;.;ҋ:GR.4w`#4m@y Sf7HY#gve7;{m]ldBl(IK4;"yi n5욱l !*cJ[ZbKb2^J gBkxg"¤ѼG WCΤQc{N$ p;i6|.r0/+ߑ i?h1iΊ˱wP?yr* }h{)薡&v5,?1a=tEwXo妡ώ-o]݆2O'5\Pmrn,m(/>&qƴ XO5KP7*3h?~֗}.^z )eu8.'/1szyHLbI>W[4,u͕i='[ƶBn/4!ȡ"&wY 84y H%>M7&MLza1q{.N̈X3܇Luc Fp+vM8 hݧk?cmI˛c}5! "oOJ}qcEc$FZ=/w>PL*|˅`=/N7c( VGIՉyRӒ剃p=NZPU;znB%o xQh81<1֕4\YY 6 16D$ |!qB~pl ȴphI591% F7Y7j=;H2¸p( jM7(iYa:RSM98f?J t q-KxiCgx~??y}XaQ'í9^S_# zrDz{I݉D&uU(,ϓݨK]i; p9g.N ujȕtv"v#((ªi *w]CM[xRMTu ?2EtK WQ 1x>m׈-Y9?07rRR|U$Yh[3A0%Df r=$d ꪅ-,/xЄzfMjLκ' !S1~7"ǎCT]nJG"`hs$# H$u6GUY@hyw(F}-GL s Hr^!u06WϾdre(%XT1=b#2-{܏u>W:Zm}XQHlXa[/9DfсQ*4_Rh}YHR %'v<-) Ϛ%[^Υi^dL;h0cHOS4sv >nw^t{ujFM@~A^\V"εv|F7QↂxKYCE] vNYUxbMlBQٚТ`IJH~ AӋV[ͳkh.&2lKœ 0VBNN]h}"~0&VS}U/5 ?HCl"M{nRwL-my0Sh7~#!%Us,v$ӑ(UUŐK`.nWE,흲S>`IOzŮ֩␐4f4d8U62;Lr̉.DB?4 g3zFv. 2#T߻nIC6&ȬbJKXKvGbIe}K&êaK#mxni[z̕,ρ;?\ D4,]9 mcI|4dnNBY9f\; ۴,2qmb_IWZeQ"/rPBnŖ0Ȫ'odʱ}d%k=-!]9]9rP/<ˏ:C%p@iemZ:vR?1ï˧kʬOLpm:HnFF퓧1baR2/ K±,s,+zYٰ=>;O}b$)ZN aT(>5RB)Wp3mH#~Mq h7)`򝴕*M-pKR-`î=qa[s:& %㷺/ğ)d\V_["(BbfXY֥Z74M hH >ڧRI915@MplO0Ρ<PiŔt >M6 >R$_]x=jIZbBE70zڜ0Qm32,՚F*gm ;>+2)wIe6%vTX #u4Ôa7n4Y}Ւ 5у ] M6n-oyx {H.EJ򡕘)(A+X1 ݗ'2W;$kiK8\>։a[5ފ&nljz^=@Po4 3g8BK9#d|T;!y.*h]lVՔr5d|"tw%Ή\[1in|6Zq3ئ6$[=8)@#dAd_ O *6*@6H]MO3 M_m8C|f7 7hrq;ZO<(ַ[]g=`|jj`6~C'q4c7;^)vyT D;kvr_9 ' =hP .,/>נ8ģ'$(CD^Qʿ1^(8C"NbhkVa)S|d9.W0<"mnK˪[T3N; 8,0Xkko?%[Npléf䯾<_huFuwsKE2nw:sܚEXYD%D'şvtTcٺiQ<(otzf_|nnDI2$|q\%1-3eޞeyk2݆ySȠ^tɇ]”X3+B_оڅ#hL,q/~F!}CF;;/A*L!e/sE5t:frbzg)oƤpiwH쐐Tr>q(DnQ_UE\X̞oCȐ״&<ߋrB p|]qcxЮbNu]BXEo$"ff4rHZovs q5,o;8ƨ718kqﭝVx"0 N `IM#&ԿzH}6&wB%}OUf@Vf.L$z"|?aSz+K*&|Nwi\NE ҳpQhPo>N=5 $3ٝxس vԯ %&QhjubtV8|2f49|Ko|{C:f"![´Y_rqd}% /ir~ m?Ѵk~9b4(N;/b6-8wBG Kj+: зݷV ezk%k4N]d!踟=W ss;b:A9wt-D ba[N<_I#twj\lF&96M+j)̺U:ޞ\INRT Tc 2k\*wҢ N=b{ X嗺to/MjA3Y%. ?M;,F5cj㌾'\,;+l&,Hs Y7XR-SB֤ᵹz+"/=ֶqHY=i#6K.rMb 0n{:׈w%XA;?}NCxϗ*{Bpxnnҭi›`b!ՆVU1aۑŲ2(۴לX}YmYu6ydְ[t.M8.{{vaESntƱ%.L?oݘpda%lJKx,|`guw! _DkOǨG_vWe K\sIv?yjvp|stBi!vaUCP1δͪWww75Ua-˛L -̌UVI.ד3VCA]m]=r`M$֠B%'vm4Zs(V*v|.YekDpw&iI8>L-),gr{/ UfW/:uB\H2IW.D3RqQ̤.g}|_oI!ýæOk\^LV{Dcz go~Ii~fHV / Ў*Hkt3o N,;b <:HQ}݉~gے0ITJ`ө"#SV颃ⴅӧUz+O)ޏ:[|۞Dq䏩S 9}dFqkUQX6\->YRNA˜rq&v!܁DDBt ~(RpmKs!8$'DNq*l'3`ɾg$$ag-'}]Z1c?7yf[\rCsV6"N*-"GI:G'L Wd| BdZ/x`VlǁMGU6zX n=*6cl$bv ζݰZΙr\?Y:f4#ͻf%~[qtyY[-v|6vSNV[h8S/P[.)z2 ܨ 0旮 n|׳THU F~NY.Ϟݞ6*oNj4K=p,_xZa"d#O|Fjq%H~G*Js剠uvSS7ma  ?^c-(`4J|OR?Lp+x=\\ OrEzCcL-*Z3&??Ls#V7ʭ5R`ZpOu +tM*p /hZ^Ia6ߏ1wQíH PcvQc3g%]u,}AXgՆEH}hmyGsn3f6%vDS OzX(&Lb9VF*Yjgk8p0qyiS·>@ƭL6()rGzܵB45c TNPk5@aBϪTge %:Ĵu͛y9ng}Fleu QD0}CKٜd}j?2ϓ:&M 7"\b<%˹~;!7MgkkdڥK:.(L\!5@{i:b1ߋLfQ5IgYg: NHX`DLY)=η*M.]! h#{' u2`^Hpx[eNNn^q<+3K Y]4t9|F-qy)WyÚ<|GclN%]ZC^ F.nNsTA=/%#:h.E"R$dv|" .rDfܸcFi| -Cbff-[kQmD:ݑT X(.y.$-7ǹԪ9uiB`?wH61cg1ݬ|S 8m~ވg`nov3 1w&eVju\`W(6NȹCZd/IJ\4R6ׂtq.q'7R+'uK6JѢsI\#3g\CtehnC0gOo_9NW6:p3Gw bTrKԏ4l\Xۭ{*!F>0)v١/;1LCt&--?;v?nBC)}˒9r:[X48(ijJfU.L6 gf9/<"*;~}TiTpZ (~{O?}{o9? /5D>_?~~ۗ>O_>ç/56(o_^TOO;+_wo?Ə?bY{{;‡ࣳ/h/փJ/_3rn`.?o_~_; b~lt203_/ϟucf{c &&d2~ꄨ_,qBA逰O?s~cj/{ƠNfS;C& hVK=g gC3B1(kgZg֗/!9Vk"SAN@ ٰ>FiF` UЮB"2>9|/zf!db'*,A{ XƇ1Tt ٣z~!6sw-\k9"tY ʳˉW!L6Šn4U6Nc݌t/ӉNȪ->NϷe}5;A"śEX 瀜ˆM [C0z{IC45O3lOj]3- _-,U/^\s%Kd!\nʜtoBυkUjC0%BǛ]:6i5[#+DAcah).fjVf^+$#&: ĵUnrg V.P&^5# ^Gu0XXn_|ؓj:Z&/ɌfvL-P%(yϠAFhPbf0H0#\Ax@F}?jherΞU?ߌ恡ߐ>-2]oᲡ^֗ iG\t18;̇\8RATFR"_FH/n] rfm6/ ن9K3n@{/=F%S|qI,Pdhg\ҭLRAK !|\Qj&lR6/*0j"r_ WyN24r^uuxzntqlnХuEs1kCa.wR4L%pcHVTg/x~VUox|T.JBpP/̘|n|',mrD?}mছΦ]t-Zayf9GD_ 5= 4/ѺP)9@Z`U/{CӕE֡hTe5w+۠Y2ST1IrS~S g!Bs\H{yu6UB6ӆ!gsD/ߔ_! euWVa~Sm!MZP?B m&.\^;^:>yIvb VkȮfc$^EEfjU@DʷqЉz"}o)kd]J䣜L>f QyD5&Lc|*r0?u*?M@0ʪ,6@Ewi{6)aZA.sΦsV,e&w-͡yPz* mllx7[D{k.lHYӯ=a>| [8w;QxM lgR~Z ЛsŪ؋Y'd YA\f0w 4&?c j+L`r嗠z٩=Nhu%[cvY6YVR QD^Q=s%A7FڇpG@k &h1hS/ŝB}ҭ]̮\A2j_ZvqD9)EN"34icV5S;.ԵN^K$-xNɏ$@cڡbF~Fg֊Lʿbnz|#,W4S/o2vSU橃HMz 29JR].McʥQp$t؁$?@!Ngg5]`=Թ)eqLG^t0=pGc[lA9>߉9^oJ-VvMm2$) PN]<^l%;QH#ˎjua"E SD2Їx'9>뭉3oΗeBУ:-uqf} 4 621aJOs-SR¥*aؐ6O*;ڦ5vأc %;\FL[ʻ1X*5t<+f2(7G2gD;1ao(0rTcXG'n l :Q#FύUrC)m0UC;~R\ưoILd@lSV*Py\mi""'rUpiB݌*,)ΒQ&o2;vܩ:TM1q?)K4tj6Y0Hܜ:vmLQjD5aM3N=@UBO] 5A!bb),1Rx-Cr& Mf NH7 5(yI,NRMxk$xh3{Fi*z нW4{E=6_ZFT ňQ!<19ђALcBbp&d#^`=Mg>IT("sjE__#:Cg~XسP[!! 6M 2:XKa{tx]'ue@7 $lcjd≑]8pJVu8U!څDiS~m/u/GSīO+ToT),eS*iB|(M9X ᖥӅnxF+* 2ٴ:aJK8c\R/z&Y}8-{w^r6eX6F{B>{r:]JJא;q@n+[䡌p zPbVdz$%T=ƛƃ$I|ޣ`R-EuE()p|<`UOBw-.\S7zjQ!Z+P#up*_:/K5f҂A#vSM n ,0뺺1Ee~P*I 0B-Fv)m/mqzB99Ӧ9]G>m$C=:j cw5vOg+Ui(ۨیMT>5SCEb;H 78 CiPJP1v7:ms9ǐnghIxen|W.eGH*آۋQLgjJt(a[o@%kgJy#߅F{ggY#ti_[vC}LtTvu@}یAso~_8sV nu]SPsnf+avE>~%Kq>NTQeC<&^Cc*&G\\TF:{!ˡ2/ ҳsIJ|R*LӅebHpF썆d9K<=g\DR߆/ /Y]DPIbi]?f\ /I_| Wpm7GuZB6\:S U U I^!ƕ'S{בHIDa- TpVR=H%>jowzD/G_0!^D+6x!:v58G$!1! |nhJ4Q pڀkй3a`Kl_Z;R<дu nCSLjwRL($aq ,)AVE8)2}ĽbxKӾ#tFN˸l`PtfebjY@Z}KUjdpN΢ӣ—rtztsFL5Li9|W%pi?WۣٱWz:h9nlbO%3RRQ2z@Dᴾ\JQNdpmХ=4bd^wLTHђV޾ntm"Ш;9[.ij*{6k@hzpb >ҷemE;{FoOWap^֬ʹTZnȣNwbю[Ҳ2/$"]lDgk']$n5v5nߥiT2AKUy)$G:/jCBG`#oqxy:tz xo嘋+.hH$PEI-zʳ~+G߽I{>!(' njBÈw^ #q- ϸ+cPneRd4aFoZtvwnuH.WMr|й:pctM`i= 8E b鴿y9NjQ[EۤU>/ 1˗վ6f|mƍU"$!5%Uz$qgx1ym:ROTg5tԵRt^mY9ANAwU(z$q1\ULهv}Ŗdb!)jYY 6?h7.kN}i7^HXb}MG?[5 kE A;զuJUq:!}3%jۢF"ɴ$sص: lfNi'CʠC=tޘp$ x/HT,Ps){OJ# BMu.G6Gڢm%O} K|'J5G` +Mu4T m0\o>)sN~6ȱW +Y̛X//ѻ-I8iX{1eN-dQxu4dG ZT]7X[5ˀ$mADhht* 6`8 nEߎ5_q*uF3k\68hes:#k2-lQbN>|&\f5bЙTglSIU P_;±l&x¦8j{p;&@{ώ >@}Ũb>nn..!u!,ތD}G@[+9sը*ؾd2c$ ]acPi3 RۣpG(/EW"!K.TԪ=zc7X7ɤ$h/+=l֢"ﴹoh2TRpx:s1v :y鄜qj[x$H#¦v52M"`rW@FN#I_|o'-R9]hRίho1C7taXF:;6!J~"#_ιzGfM+X`|s.bQCz6E Bf i1ҝ/QQtƙ駄rNÊ&EJ'Q/ NW5I:L$)5V>&CйIJS IڛyUM.&]vk%T=ǵ}!&+3T^&FMb`mHjrƘB}N*t߶/\x \wԋ`zĒCwpd ="cQ4PGŇ;ߎn_\,o*{V YƳyn(w&FH*K3QLBQ+F98&BƮcI$w&'_λ*e Άq@kB{"8ܫPK6,ٝźI2#`}.3N׺m8&-!;&Ғ-/}pVƠO^Ri6Qr(R&Y bI^=)ͺ$um0I GZgPKb(xZv\C{ +cy`/}*Kk 'e|Ba4j9}Lϖuv;5]]uQ'OYQ"VL,Y7- 9swe>>(vSncdD]L.Zc B:cWQ"NzcçuQ\%*+v])C 4ʩS= [EotAg^eJwCN+J'Y"8V8 9]c;Gd8XTrBag?I'|2Kjz]3KJ\O或T;ڵ莾s2hsW.ime0$\r:\qQbʡAucCﰞXmSoj*Ջwcuiюxvjave&,6FJ*Gv한&G<\;1%Z" ;Df%;5ZZvџ-_벚p-\7Ryc9e5CvN "<[)9V(zE2)Z|bm?E\y*p/lYbX]|9IvШBOiVh=>pOpb`eJ_/.}f^֤E({ZZi c'I?YƝe4->>fف1 #҉:},qw&FEjWC?+x} o9E_$l2-6-Ԇ.'|G׻CewӦT ؞a")?7*;fz+ek^Ep H{o%fF)yv[)L:#%f/Vn_-$v\!]|21]Yh͹ {puQb`3#11<f!Mk4&2HYDNG*%tC 5B{2"C \L%LjVWk̩ӞuV6qk Vi ?wѥK#eSlDZ‹JJk ?[EDRҤ˜ s =Z^`fбmQ5VZ J"엘q2IVi wN"Ls2EAfdZ$\kLTG}xҭsfnzڍ`mp9:ZHX0p.$2{hmVucXYKgm8 ABE9>7,4b(E^:vNtA$#+I?Ů͍j[UV?c^>./gI/?.nCf<|tX7ԇ]CB _H˺S׺et!aFB-3eQ 2ԞAlI1Zull=ozLi))U7"ۻBC-}˲ɍ-U4wEU5g%YiL/_x Q$f$:8/l?_}2E~g71hݧ3mۧoly_~ӯ{o_&߿_}}oˏ?_ڏC)?_o~__o[~?}O')mJp 93i҂\r YDϑ;aXeaX+n|-/"+YF'gK,g*6- =:~"b\~Sm͝Ċt#&MTEc|9iv|;_ :30r9fs M0l;t=Lݩ+#U?4Uklq#PNŢ*"?PHA0ߘ@ۿ%;*\oEWoŸZvؾ|bM;.ʽNn&D8@"pVW1ڏ엷Сָlg ڳm;8؎/XQ/+|v1A1;\F5:z|wص‹p)XW_Do{C]11s`_-JU:/kv\<xވyT @a(k7ayfgj~g{u!A4߇}lXrg(C{6cL3@tW#uA[[p1UC~co1p ,`._EF ;K+Am~1c>~1m7~E`C__dT;xmlliŔ`cs׸ܮ@|+34y1G34#$7 xv/ZH|Ѧj2rAe9qkR.Z7γd(}pO4BxX| yDI.8ve2l#ߒs*% DDd~_u-ZD15qaG) ߼D~ &㣵zIWŮ|b[KVKT1j}4˖o_Kbŭ rSV#A:, %Oa痂-'Bf]]3й-!@yN "^UR> >[rpFK*q:)^NSz[_8JwybW]t՛jr]'B(M^MZHr?Z("njv)ra4cp!]jxgՁ"WA{f! (<oun.f?l'*mch6~zΊ VOo za/^ˣ_1 __[>e̽'S>a9XpdL̼,k鵤RcIz~Od6E!倵<^&V}^!َc1ⶏvJ?݁;/ n!v>D=!r\ tLke2B^`uYdˬD˂QI:~Լ Z߉ׅ쒴Elbkd\NXv1=^}G%Een`Q\!t4귫t\ݞqֹ xCJ!ĥC0Ng^ O|-cؘN I_@96ZpS2_]ݵ̀N{VZ Y[ث]FjEo Y)X*^_7Hףjfz3[?۲&R聼g=]L! ދjk$sl$Dj#֦9|y"-vI% 2Qr! ~2/ cr nr#^-ןҬp3EŸg:v(o޿ȅA^>!T0Fzyxʄֵ{[J vxrX#VyKCc IL1"xdA&̍êȖngMEJ$ENǾdjg-u:N;ף^ Ôi~#'޿ 'x [@Wܸ;g TFN^seqJR5 OKHŇh1>3 d'=ϐAtZi Q~vE{;J,Nbhlf=/βD,C[DpG}b8'X՛9;P.'ۀcɜNdK\dl1 Ƨ60QuG3qǞHuXOL> I9Ojʕlq[8A{yۧ6㡫:r)dR^8q9?ݫ2 .T^3AN]R3sw"K4_l+6E{Đ%tY>:d}R{l[f[Q+vc=Enß,HhZf`2rӦdAf?jv{¢yd t]挴Zxh8-}Gv/<H*oI}&w6 2;^#ґg-pʼnO-XYɇҗ:BN8tF1kqy;iDts Mn#wB ԏS{($e߸'Pbd^YfKT484篐x]AI5@!93/U- Jt vL ? :՟J'6MvQ,k@SCۑU.mmgua$ˡP= j/ g7 K~ܶLOb(m.ăm6i.S WڳwfƃbT FN}#L8ʩ67F}ĂcA9֓^٤G&^tٍ$JhLIkoj7cpOWD{=0zjbg8_sp8D9k<$$8|@dgj=}W'v)Yу$5T0 }?G'4K{4oIX#U<*_Ɲ,;fj!?+UN-:t=O:c5Qtl2@g`d,Xsui -v=6%6D`UuPlbeLp#eFCXY,de x\ lpϪ` }`HfcC|I/> gh|kUKFv gZnʛl6<>ZYFg#`V!bF!209zt.kI9ws‹]Hk$eCD`LIb.ݰw(_ ΐ!:-aAWâI嬥x^#N ΛaұA0xf摒Xvώ 5Tyw+jJ4ufK\/E<'S:جgYkO+q_LܑޑC(ƻ$VY:Ɩ2vÜ n{a8AmMi 9ryR؄IM-PaShOt9b_0VNH黝A{5N<բW!oz܋$$LvWo.0C2DѼI/A#u$Ơm.& \`Tc1n} ^꠷sNTp:hI(E'.d>jVG?k2cgHdDtCWp[eO9)7~J?G` Z}cM3e" 3:@D0~f*"MshX 0bNnNGJƽ"m=thIDI`kR i cK Q/0"/O(A L:p uX)PfoK O"njH_Myt!kDQcæ ccD*` ˊ^·&Gs *v*!ec+o+$=W<˃29V%oZtIKR^ EC M롫csniDқ>*&V!'SrkD> k!.j:HS7P 5N @4*tK1W!BkJ!fvDnܫnJhIijQSgCFir^V[c[mm [goFZ_[@&bʱ2 b6(AIZlfu"TS*_tO6b7f6YL2I5:@(`ϲ$9:MZ. (/t'%FAܩ[2F{pІ8O'=lnj26c_ 8uCysHɰ X׍?ڜ&VViZIr7LRȥ\l΁e.(GWmovY[dz=]Z5AG:c/9Ez,NƧ:\eiiuμRx*@!_j\sgzm͛ZFk\HIt_Iz~ {|86AёY]e4v6ɾ93ġLJ֮d/aq<*52Z1n8AFߥ [%/U%D pC̭v좵Qԇ~ XMٌ.#'Nr!gȭY1OW}@gCXݢ*D/\WM& S.HW!̓KָÚ:Ue7"̧a{j8*m uw[R>Kod73uaieW4VD6Nd4I<8C3IfV[3|w?I;=2Ij-/Rk촋4KOhɤ8+1}KJ =HK AL.wWr®XyKcW vøbZu4j }wCDRǒ>}PF 9SR(uўTGn}K[O0&F5CzD~1^oI%7*~*+֓q<[(:Cs>Xイk@8ri;rq_&[1KA95xZ.zoGڜ]yF=+]EN6dƛa3.y:T 㮛4?$M(س}DwюdSd:Q;q%}qk35gUe8)G5|zXp)_N+YਯozCtߔ/s.:S3 JLIo/;G0T̥KIsyVD<Md̥2/~fl`7 Z{P-J/0nqFhegDfKkcJ#uu2l:Vg?!=u҅fT^>=Zl7qN) v l/*WpS^5z*qBSM`8FS}>]q۰Q~]w/QVVp`'w0H'UĮxDx%.Y—щ\λ\ "Hi4Rs|a E՝hxQݙ'x<~ʞILvcu %!iF^s?@Dа'Z''4+U=\{QF1p"N!7d eS(,oME zU:SͽG2-L _f'a(7eR*092m*OzSrSWv<3f<>مz[%]B2N{M{\FփvU滤M+n{? 34#mE5b w\]Q*;=nJ.{@Y[oŖSm% v"ry">,UpܹVgig*F9Md#vTwKQ-y(7ɚorS#CH]rnVG˜sD+"UF^ \YM.O.PR7CK1}^_ ݖA~峀<޸g5oEkr]Z[OP Lȱ'\%αf{Zt[w~`_ ,̧竉U o,>'I|pjW\&JMП.{ois IZ cS)>jV(Z(g!~͒X8.=AjMR.;2,DqV[ ; 0 $7#08 ̻j'B,Oq-in7Ei%kAgkՉ]W%CmDb5a%N $zJU=MZ"P ılÖ-up nIȆCĉʵѹ @p,$sIfF"&W˙Q\n̜ݷ9R|*]6CȡeQ6 ~S3c9}%f٤Ua)|{pSDu+[KٮZ7b5vaXTm`n`g˒HsElEOknE"dB'A;L,#s$7 r5ݵڳ<2eNp}|*~Ũڌ+e_AQ1 dtҮtK*8aP^j53(BN}hWJ,H֐|0#IiIun'4=]Wn ng9`d{[@NŕݢB,eIO|=e*V7pitMooo޿+V WieMB@ʹ _T(G 2Eުe[Lp2!i{0`dRF|Sڨ,w2tmE:Fl O7[vjygH<s5Ljlo$'l=mp8RVi}/:I1@s Ȉܨ,{_x^`dĘA0ǘyMtju7h~[BarD:fyv ?65(wgAs@{൰_"b"5,D8e 5дQMCIpԚfi2oP5;4BNtRN 1̜2mG+nPtC McgQu].6CUU qŅJT9U0?C|?zN.lrL!T_X¶\zVO7Y0%Z6],bܫ f{ Ikb!U$9(S 6/Wӯ=DAה7gZLW5s` @U!9rc3sɫ2қa!.~3<sCIAPС:0;9Alvi$C^oetZ֛ TvȲmq\UEM*1эb]H-41Y璷2<~C֚?3.e#}4O\m:d!~R~ b. ~RZMT!\dVK= xVjVڐpUپq#e?LZ+w:Mfꊜ6.M$oۤNĒ㺗݌F:y'䑄rsP=9yL{ܮMu_Y&K@T);%6[rZEZ_rX#F2a{ze o3e 3:MNg} 4./l6;)#d,rNփZ1mB oÅ5;֞D`0rIT [6 ? u9+]ώ[.sm1#b&:sF͒@igKYT7lVc jqMW Sfa5Yٻ*t.YH5MmnFIx9( r~'r8(]`Ȝ̜YLp.W$ڰیmXw<5'H6JR XL=ћӵX%K۶qA.a'KUE twORMQGY9,u4Zb.nB.(eI Og g4}4ʺGbI'›,97$+y9eԆkI~"1הc%es+ʲ l^f.?F pطꮊx0M+KPL[z!fw0bnqYun}67nIaKrvl)9ʳ?ߏ5{ZvTM3խ;U<{6;mqRA'F&s}h7`zEZu+&(zf6y[^tBNަȂr8̀yel`BPGQy|b5 1T FXrՕXXh%D9Aw&?ՕhS=rWbvvoQMu CDBB 5l[տNu0uO% |v%tm+d6#mX~:JTBmRq -%+zm ˈ駅.jp[Z+$®ʸe_BCa+}˲]ݘ*xT$nCwo̍sIEwP$7ϹuI _+W_~'/Rꗟ~֟gj}7?l>C^ʳh׵$T^gO?g'B *Oj0&iۧO:oo?ky'_޾}_{/忉]}/:_~oǗ_+>5_C~Oo@ΗOG)?| f姖g9CF.*Hɨ{Mͮ`نR M j]VLo06ώۗ_=0jU0 W=̆יcls͜1WԱl. ސSe~NKb+$>3Ww.igX򹝰+4pَ[+O" pb#DuP 0b2:Sgw6ՅVapYo /[)4lPϤ|l!|r oCQgZ} `>B to]untuڶ\ v^j ) ;C\r߾.188 6ur!G ԰֓|3r&'$r"g:rug[rD5a\;fl}%,:9zS S S켿9 1j\8+}m7n"si\1ǛqA.X{hQ+GȰ)7yXӎt5u@$m.t6K}tX_(7\~8&4Ûz!Y[˽6}obsH+}PKu*z8]*=6ob9.qK}XNՌBL` 1^Nr$smfڢ3aS֑T==nղ >Ƶ5vQ6PWΗ\Ɨ~k0z2|xT6[%+W= S/蒙^6Cۍcfq[+.~ҵȇ-DŮ4§5,,5L_-K{oAx6bn'CnM:$!Z-$}Q*/lY{~7 h34bցahfzUbx\/+ rayf0K=Ώ%,sRg*`.ab?ک5a+1\|ϥ-3iF 0ozXIxm>'_U[¶0~Ti=/V9ky6m􈶷(erM\F=(W^L+9GgܑVމ- slmDX=d9~- bH#4:,ޱKݐ.1-v\j5F[cRĖ;\' /ą,Gbs!ԥ%ĄH5DCX@=C%؁i #+VO6ݠ |sU'xYu=3]R0tݻ$51!o<]G:Ʉrq|91am:Aꃄo9KdK[(@ɴ.hyWY} \cRUZby;5:_{'577pI @1Q2B7Nag8vf6kכaCp: oofn nl{Ӧ+,^lP=s^qg=c  IF)P\c պvMt.8gvt抁jGj8RUt^nMت=CV(@ {z+E [u[Fi :Fכ.:1*/5<Д}us3Hɝm{˄ѪӟV~M Db9ݒ5bb) H0ٞYL("\<׉? bV{WPDВ Vʙ1ܳiT+ oR>{;{56˳1 Khvv:: .b'=yw M"CTR'+>2uUTffzåZ52G4|#e6όQM8Ux Ase1Hvgxpj|j G՛Sݎպ[yl$םbFT>ۙ XzOm꣦v Zl!S+LwUse9ԒG%oSx*M웾[m.d !9_!sa ) %i;)s%âu);3.v5{O;I`<1#b9WunRjNLOe%c?ܳP/[Z-ѣ-=6I'VA$ehD/΅p1C ;aN}D2װKeAd"'b?4>KGF`{\uĂCn PhYWRk~L\Mԏ@o4fh|.6`g|Z)u}ku\ID*>tP ]ibɦh4FZA>yiL{'}o)dD[z2_IL&G|d6(rޤ bZ|7'i?.ن|4x%yp=52^ױs!O h Id}vC݆s%LhX&SQ}yEnϕռm2Ƣd n3)!$*:r3:n(v Zea'kLS&ps℃ztX^CXbl<_p?}_Ƶ5_Iǔӷ^*S^ϑ3Fk4&І_5ebloID:k  ldif>c%xfkT::u~"'Rftrщj/;&m+?k|h.Fm?J D7>lzx8a1mExU A&H'ƏLbv#E(%`} ڎVxWNvxY;tR%ѱ6=&&;ͥNgjT> (tau]|p ؙGfF依NJ ҜFDx'`DȻV4&jn|":riFrC92gƅCYWen6vr-^TrYe*:5 Q*~ MQF/ux{*L8 d6|pdB}  yJ@yDq<ʔ[tQ V.惘Si?yh-2H'mb7Q'({l] a{#SEvbC֟0Xis%f3l&)a2.Rbdxv5LCm?IVSse?P-t "V9K¦e"WB1h@UJH|.S.R 9u4Kh"*8(qZfLzW15.)(q+'~R %ᶃd磔?0 Umݐ>ldlK&}R^+l-L)HJcHSIR?JC(JL+ATӋ|f/sr34!Li0;1\n Pk@B +Ƙ"UH'i`ҭIaL2.D}Կ^n!BrR9;-b]dqgf\A?I^T+(Im`LT앲 fHh;suA8MHд+Ǖ&9ѭXZ Ș[ -OLm@&\H"+ϮCbC>}>$͂_+C5׸{砼+`ZiAΠ qgS*k8nhq-WUZy9s39PDTP0l_Sü9C#ۜh/׿<j2 QMʥ"OzSwmx"y]k,X98ZvA$lJX!z4O+Y ZmO\գl'ؤq^jNUz{Xe~OeP5xbNv+hͤ PS>Ej|o|lY#2n/ $/﶐o(~Uwt gpqγI3m3 2ĮYV4iX|]\7 -/Y$H24ST)t 5'`aKDrh o\֒dq>E\6e?X^',%&ݗKHRAMq _:#4@qbblv2PmW/lJmx,$ vAl͐ȷ6GEJ1{3gyY=ow&Q N1q;/6)]lYm6H`3hv(=@?n4oSN;vӆ{gLϕ#A>O-?=3˳'s2kFwA8kY+$'v҅[0ޗDqGFR[U* sޗM!y#[l䓃'(E1\82CniSbN4N5.(0>5_vrIK# 7'6w¬)D;}:awwWewٖvl]BLN?7JBLg.u[?N1FwAn}\g;d5ufOT5)r:X{Τ zql=$]-+s y&`A>RQj76^>bԏ탑|8mV[#y737k IJBO@sͱiت֤| 61z0`ދ{~E-G:vMJZuv{l\ j"a8Ij Qo$h،6jFcVJ(ӨVtaW| sBRx,|lu8f1@!~/?( ~ vh )^T"5gUa(ӶHhYtfר&47bL98Iӻ[@P(l/;LE\$`d ^{O{gcΤ7w Ũs>-f#h$^y8ޜl&f9h*[;1Z7^n"]ӊ#.` #mK#Z>E -e=]94S 'bp3GM=٭4yvESL飏f4[`q?[gEhu=YnS2GoikM <OSlwcjŗ3}##GoKų%_d{-F^7`W'W; V Kz=?lݭk`fݻLJ|@Y>bdA_L҃a˜פ A?3z׀.?;ī9j l81LBHKW"ْ͐Ǝ̅1׉'hE3^^4'nKר:%rhF;ckHYnv<*h髖iGxD)x#A"wLS)v4k>xrdݙF.;G=O>,˝a~oUE6stJZ NW%3#Tyj’ šf:rYEej{/1pmHYa"=ce2I|,smPӪXj]1GO]宍 hMݍ/KT. MY 6vO勇6Q4 u&4mΎxHIMy yd,zȡ+39`ۼRav=&p1}׍5Pc(VZi7Lw+:Z#Cؚ(Nhi?R)nZ*]#mr863'c {52͟{MWxSqJMs{062Ug4QwN쾊; I} }SHmo.q`;0K KK )NԕVUx''Ujm؈RӤjb >3ͩ:o-{tn},=O"Q}e>G~) y`on@~n#m͓uןSè n󂊪ɣ[j-3/.n[޳cg}~d ¥\ cƥ{x .xa\%YYtYP׀@}k0z_7sѵ=U;tIrfRcΈHu i|[Q[/#(*l1(XhT'dSˋ)H.B#S ,>™/AwTƂ%ُwۤY> Z5fmT qd(,q0Q|Ksݾ tWG^.FB߭P5hCm|o-  QAR6s^\Ou;ʿ0>xPn=vJA1CcXej,M0MThuBljqgGjσRʁ]lIʧMcI@C_ehs R6z^8T10!~ ',rҞiE:{/D"_$-I;0T,a;#dMNO/ݿj;>6Zp3ڃYعkK8[>o;r̠HB 91~BN+RP NhMGlX9f:Ο:4svWPL> MrmyF!ч)1( A*흱#zM<&>zTدuKAz|2b3v \' .agƇcB.hc YB8pԶA'n=Ж-Mʔx ^S2&g8cq/F+룿ijXa&\@8`)]aX.HcQ^b?)~/ECMP"aO:D]cuHh a9D7 +$U-Xv}zLc7O=f|׆7ʪt'#&z p+:M{>m`d*K| }W3g^еi˛{~=0>߅.}.j1c.8*&lX[큝RbЉŷ¾e'G[ G?|mCذue)Z'x  =h$"D QHkJ1 <3F@\ >{6\s#`On' ҷergcGHcLt?Jsq㯣톅-WQ3'@яHc> n=^E`~6@#H9%Q ~du.}IÕ^Ә;θ4q!FOeaYv*jc` Hqgd=I7* Ms< {`_%V)aβ}9 ؽE (2&uH٘Oֈ@wRD> q,s g sDU J);݉yKp>z9igY.~z܎G7yvFR[FE#)=U1Ab{)/ysăG[#GZ,4j):-[Pɸ k\C"7nW"-j|Ȩ9 n&3ƆB뚠>;m|HVCm㎴ƠZAu#Ib3 pZ ʋqk%쉏LQ`e޴\֍9ޠv {}saQSd`$;TY(Lq8ƕ\ч,mj8]Rn8nKTKD%%%c<(юf4삁3XoT4'?\q'*"id:12a-h bSvAAC*cg| 8: v1F^ dZS(HR:7o[tQQ(\ Yڜ6p(在QМ.&تBxz Nk TN /&dM %k.(%\Ҹ'h5*lrL1-.Xz'%Cu mWHCRv^;#G:jJ8]05ZWr.Y坸ff_?SBT{Fpw(IᅣN 5lbX9( ^M0d~Fzmp-^r*VH9¥)U  ѴzGCnO<76)<_S2~TWiJD{JdJ;D\,;=ơ +RBW)Ƕg`DT#8S 7ʕ(IyK&iܬR9'Uq ,ymghAnnUhC_ &^VfHэN!,_̜:3ӼIsxns^F+ eZ!N^j@#.Y!q~H#:R \ʗoe WT#kTd>c.qk5w<~)^Bߓr~z Jʤk(\Bf2TS#ʆY=!ܮRl(t0CvVR=+G& ݪ.*}kpJCMXF=P5 E:I}ܬUnCщ-R!'TjՙQyPSKu _OaP5+<|‘0^k3ЭMO? ``e#I9˷-@x^ϧg(0+q,Ȋ.i d%$U@͐.GdJ"<Y%k~dz/aw4R;+!›=Ճf%wak:U☟MOGvhu:sA܏:c i3vQUv\͖mMFE!6r3 PBvI\U]<Ά/L YA40/[!:DA5 .@_bLdWlО̩gÔ@IJkN6EI IJ8 Rw%wtʭf 4D3JhمNpIopvh[n~G4mCL3Ռ\&1f pa=^A˭t1M}4as<8kx+AᢝzCx͊esΧ8E:h|Zh94Ҡ6zVWTfSQ0Fε)!qa7ϘG?lJSCUE.|wfW>. ̾:*f2R-IBФ5 \S##Oϱyi2H-jw;"yuibo4y LUr0옸Lߥf ڽhTC'28(y}H9*kMex/kt/CNT;TBi¶ѓZ f: >:%ry5Gh*$Kc&F &f[_ tuVfKgC4j`r.19#:-U\iӄޠ{yы~Sm ]Vr*Kh\ZIe؊j ÚH]7q)=kΊFwv{-bh2:P3/O<#vcFRCMhtU)5B:RE VK*P38Lt7” g]!p4<&F!#nܙHjyo qo}n05~`ۄ6:~gv7Y;ԇ:]a60ayBϩ9JqR=4씩;pyUF.mY݃ɼϬȇxY82A4esx%0O! c8YJ~t 'uPbdvJk]fԖ  't'Lxt\+O*K;^NAYPQ"FC&tQ۔e'jr/7փ>k#մd lG<}4QB'v/mM80`n{ 5e 5a.݇y+rs@ʨʈ]Qa6(k- ]y&fg-9 K+ T'j1ȂTQgUlc6LSaurI(wqɄM_\y a>n={~?~~~o3=p_X nR-_t{׸??oHO-?|Q~zJN?m~M2Ɵ"}-)mW?S?~^{KH>{-ʏyԟu@66lr{GG{6{}?s?5ޣ(n5hk l*giWs+?S o~o W/߰`T5 k>kO^L5fo,@`0|U'F<V>

G}KGK!VV(_R |hgUP.[6|+ VRg_Q>[yg38x|.?t_')%X䢾,IP㪘kJfz߾i~so),)?L~r+Jҷ=_S?['jOZet@W" F7:QӼ.P7ɰMÑo}de#BHYF砋6=hK0t`Va"3uNq1; +SiOȉq$9K=6X>.S.--}9A!AM-#|as7 ;(OSM)-9Ԏ;]9#Ӈ2tr:QGe!7Sx+Ul>ū1r*gTZf3s8:| #JdG }nӶ# 06+qfS%*J^ʉcҦh#X 2l!_~9Y: 94Qk=kOJNו# @>V&Q[Y΅h5 Uǔ}X.pE/%}O+s(489%X l.;6FoŨ"zTc0H#s8K6 ۑJiCf;)j*.%Ѽa2c9 [c.f̶g4No0L?EÆGt99 ᩐ}jdߦ`x_0nGꮰC4f=4l]iGJ)3B]8Ðhs?n_o6.Eo4"f"mc5\=4Xa5 bq4P7]9it1׳sNtdc{/zp}<+1!M۫;yH e󞜙 `@Of'ZSfϚ q!AF2[>>g8-ztU8c̻;K) 9^ƎVe/HF *##_ǝ T6jB$B&a"SS2gv%3>x~+rWNDқ49_P('Bq rzq==nxBCF SHK&,I1icݫ:$G0 g#^ܒQ-k*u\Uۗd qFSC*9A&w-(!^;fz"*4+>8dt +5C 9`uYFcs f;B%6,{K%VaVg#En1[4O)ktW$+ )"װ[?%RH:Rעjr1C-Q$CHȺ@hZU=:c'$MLjT(\ԅH15jnj"lM(.9xBٞ 0;;h3 @Lf u~QUz I׵լjLnP:ccPL0xެ!hR8 8x!43jOBTNRB- 2az=!|Pjj+ %5e@cYj$_ lb*Y7$)gՏQfCn3*o\O "@Ұ;Rb \ 6bp=r\{UX]sma9υ(Hf_-4C' ]t|`TXr=B´8Bcz@he! -8#3k1ݿVw< ^$ !cS;Hmh ]WSuHa8o-i8u-mRZJ`H/7$I[+.!ZCR\"\|gFl:^Uٖ<_3A &AB@9bcړSQ- B=(ja!}b򖜐6OdΘL btxjJi?1ȿ{PQAOSMt,W̼L}V tD-,y%=}U68vqoC^51_Adh q PZkTWH84Wj)57x0xS)gZʼ̹dυ^PJItG;]b]{n}>~Ņu Mց+AhX^7&Lƛe yFP}GuikOeg'0&FI6yE.N+KVePj_zj*xƔ<q4rLos*_ ;5/u0&6-=my}P( h+y\q1L`wcEp;DRM˫Xh?Ym[ *z9HJ+2W;(FF_4ǍWK!FpvBrjrT?ay뻌B9Lg(dMVO>in.(1[E K;cdE2ܞ RF#fز F՘$vw?3C,Zc[dО0gw¹ R #hXwzhlFẘ]{KS^T/1+ߦM2Ņt 5e+pME·RN/,@rdfV꼐l Ɔ>tdMKlkz ƍg$"VCdS>כlw6@1q(~c@CDIDNd^ՇT&Mhn 6ri١ 07´PrrP8@6jyFo1hђÏs )+!Hk,L%Ux\vh,# . ЄaRʩ ]7,codiT2ld,TҌBC+}˒%:-eNEZUERj)gfp =f7d";'_zSO(~O?/B=/~f~YD>Y3ͩ!yک`o޾ڿ}ǷKrN||FGo?ʳ?~|/{>M?__>U׿Nj21~??SxCpVq̿1Ƥ⏅"vcI o_80ݐ+'{o_nF/D ,<-/VguFo:〟5+D|2gB5 ZmO!fm=j'6W3I &e6<0ug՘?&SВY֓ήvh9 bq+reG9$]ԖԶ<:[1(lϴ.WtA˳^= |zq'@*xئ+㝿(~p2Ft4_q=M+yuiV0;J] b +S֧w-041vy`GqKٞ%m];R\o vq4?~n0H}tu;R: y;e2j$evERJl{&|e6>1`lɷf /$ޱӇ*al|iݷz{Vq/Lh}RhU#˽DFd\M?3V73#R/P>&Ίa=|0Ojlu ;]>3 0ۀK5twAc_ O"J#]: >{WgyJJ|n;1 vOiHђFOGb+R:92gwGhg]n.Cr;rDHv*r890:,BIݦP4{}Ny"߳o_i(!&؏3Rt={آ:/{'&*~ 4>bGWlAL6~`紪A M{ cl/z=2n CĴe(T"i-Rٳ)F75-|G IرW 3OT ֱ4\{MRxk|d[$$jB %5&Xl!3wo{4n띰Bç2SdL5Fk;?C. i@[m+'h 8_"P&QX%#ie$u˥GBuZicK[+3{,]J8X*?=>L."`̳bcʒk ~g?wdO^WY~F=894ŜgUؚ">j4 εp;FP969N NR"{hSj*h&"z4 #]\>4T3)d9 *6e >HΛx^fCH.~yZ"'*R4s'r>'vv*{]0McIN`hn;ϐk6MMMXe׆@jxbD<81Uc[GxyeHRڞ}̻咂V *HGr}e1 U"lDHQ6ƽ'4_bرȑ`9*~_t7hԓt9ӏ|Pog)2:pڪOŏ#iG)Hg,]\V {Ws+}o6|4k)T)Xlq3~fo]jax4~|yKq#V.+1%8 }zfؗTTd4.J߯.ը5O3iS+a TsIJS%__ OM1+S8+\ъIOk`Id3r.WS{[4Фk}LAWsCx?ሪ ) [dD4IHT꣮ Pllv.Ėsuyt{w5f#ZǶJwq)ME tpdAaҤeܚ~;sRNI[t(V742J48wh \RE[u"n$yFx!9L5|i::0[A*>- )݇(ӯȨk e I}:CRzi? /]ãTR*#?BqdChhuoql3ܨT]X+,E^-&U[Ґa+sϣMn>A[ܛnb'~#7ZeޙOca )dm Y%Mz5U;Q#Fm`I'Ja| ;R3)ҖZR$y0 ;o3o[>| ?vEp l"eΆVV[>9L #/ŗGѪiTቭ&"SýA*^=_~6]Tj~ľc)X0޵wXy~ rpidTˠ0<1ekȅ\LM %UBNּ L5]! nP􌞁ԣu-Ї7VB:_gUPg9Wن;GK ԡٳ~rKarn?|IT>|RΗ<wo+c?(iQSLEIoD`)u#QY'bkݐܯ7eZ)]vML|چ!_e43.XhibKMk8e)'g1#d$WJ74K㾻/nټ:7Atk/~6 ʄBL8w Gz45C3dY~<1rɮn kƂzOAΩFʿFF`f|^ vOD[v\y/ DCk,h]N^і2Sro q`o灞e)bӎE}9[$e21"XL=WŠ[>[`9-fs{Va9_] F*1ps$$Y&x 9N)0/UzuKe< 5 GƠ{*WfсQp8D)NR@ 3V ljvp-Ƒ]d[wbu6ֺN.\X> qC/ֿ<9e`6̭҆$JbCn6E%6)v^'Y{]pyv0Ys)} ZKqUrPAM\Xpq_q.nJ-Ux|E\8g(0)zW27#J8Mx/Gj~.:Ǖk Md6&LR2'P\ںkAI8H.ݩRS W'Tl4 !ncN\cʷТMw|LaLq =l x!Izdls_׳8\m͚pt8tq専mR;t3bvT@RZÔVV&`&MRA 8yRjSS i[k(Ay¢j7C(`BW gE"'ngDF݅ :׋l<[ ($J1az  $ țV@i3HΈB 5Cnȡc[gc {B#U _8%)o0֬5۠WdѸ6V[2To@ζ)ݎ6&]]x"sDu]%ZVe %8r1'"7F)λк}1:ܢ:Q_BO@eBnu-נ*6]B7iLYpZWg+mZ?bɒU]tyn8<v"DQeUF2}w8Mҹ%<6+֎){G(R`1و @~'u n8 FFɜJ5@VYM['[puגV3SO$ޮRݏ} XtPsDdiO?F1W)_֘378tB`0og/Q'uػmG]ڼiS@3K/I=r6$/ ٷtRSY"K{9ς6&}?%cK,&8Ɖ={a~"CE!'*dX|F4OjIxOgmd-`_x|\`}b$xp{Mj!~Z]Ω΄K^kVSP$#"s'SJ'IDٱ;% <ԋfeDٝDgFɤ0\avnLL*[.X~7)U˸̞ is@zO aBB(,h"I1]o>D6*}wٝlMO:%LG"?7P<ؠF Xi7=Q(aˍ('mzb$,(/-$? vc.1HIMiKX]m•Ԗn;(}E`].Kvj)G:JZiML>mRS:~DPHkzMz@8M T#ϭMuyXG盿x 4E!mg0PնG}܉ #e e:MtկXOlX-U}7^?Q}vYE`Nx'޳ݮޜMuv+]P\MlA!ǚP{p&k~׌t?wfb ҹnc%4=Ec^mwsll7QG%6v#ؘH:=0:Γ+΅ -UB] (2emyud 3&JB{^WY!ig!ˍ,ak;E=xǫlRPTvfWNa0~b%!}!%KUkbٽGe De,J  *Ǒ|gV3doK" m!|CꍋE0_7r=>4nݐ* vOiPݓm<˄BN.p Ut^\'_}+SZd{ȃU l|? q'O 6QzяyDTc)g~%IJe*T@v"SZɊ0e+ducM6x83FavYH >a~h®FUzbv(pd cT[ib6f(A{, A bR4;a5/.bF >m<{" -)'[8ʘ+Qt g`WR)79fq42 &AMl}xo[o cځ9˥yXdIT쬃g T" A)֜Ų6d߱U]6Lmf l̨6|b쉳D=ݒ^݊(lG=J[K})A pMbL]}L-c Qkk8s3Ό}UtHCHGyLR d-29cFސHӉ2G6b|.xvfl|9Ts9Mp_p #4'>]mu̎R9YȋBcգ)Vwq85 s.C0ni%z{kp&p*rȚL鶢Ie߬v>nbC)F(jtxne_X[!* 0jo)9d^ =хZ4ZQJ]78I]S)<+Diy.t:ە7v|nE>UH>Y`N%zPlHF9q$>*7pV"cʫgC^xyr9 dS3W;րYO^K+tjxNa61H܊/\ˋޓԁ^Z/ѷ~of|M{Xh(4&Z͋V%\EqbikEhl;ꮥv? 6hעӣ@1@_fb@W@{»[3 KdyA_s eN$8j`¥ !'JSʌ.ZZ!/OOƪЅvKz۬J J:%K#7=K*zC)~; O/iS;aS,h\{}r(6|jbb^N@sU %Ŭbh6ZA $p/5Ο^CZc/cQ`y]9D1iI+PŸ86| >,R ~Q N`JM^n7p==YP VE*F>n94$;]$m@!.ּf-#Vr9lG&]$kA5]-Z#{v ,OͳW[Q(Wi5( (nT:c}HT»ScJT&[|RBX]vmLQۧނ?X_T|I^ƎI&W)46Gm:_~ /mNg٨F%9F1E /M Z"&Q8 VG(ܪƜl%i ci!TSb(nV/@\:qnx7}{'Ҥ|8: ak+0Ob 78:%JAbzٻTgVX'-9-I,:2n!ބeEu1qI 7LG/$7 cQ )Q/DΙ˖5c;1~P(TW:#-gӷ Te7PnJA7F=I3F&(ێd\)UⲈ%6{DIp]J!cǾ쟝 Ee,v1Hshf|}/R9<M)%6gr4ó] /,nJj@Ȁ\~ژ&!PB ^\}4uwQ@iq:"J1 ]b/}|Nq ΨNe!k?4'Swft&Zp4([37Og~RgUo)eRo_cdc{w-Nxט'Eveީ@9e&gRK-J%"lm\twK9>朦.#4Uys\>&KR2S/b3r< {m/sʆ5{'P%@T,hn]Įs̒熿p+R1[bN^+3PgV[uCQ,3;I:kQ5}Ft8CF$!raNr-=fN;T}G}"tL<(XL5rPNk D&a$ Qni.iЬ*]o7 /ߏֺM8aL0! ?uB1@F ٮ t_=,U4`>,d"0хTt?C,lK;K! rF:.p廵e$\urG7|Sz|c_d6ZDR%p9}F#!(~Bc{!OX|iV/>4!BB^]h8[vXambc233Xn0 -hmlE^!¨TⰔf}ssfبI||* ;$7Wf!6pJӓ`*濔̼N|0妃 tJP+Gg4;&Aw0ib pCۄ24ͯxQ~QgqS\S& E~sn|jy.-|04g,0um<+C(:mzDNL鳺(<RG13G%g}Cc'x ruaL!h![? [`ve<~dm[؏Tg7K=TtGq}|Kw|9oJŽk#cfY9ơJ`o{MϲG:Abܰx7 0 ̘m نhm]FmwsfޮPŢ=$kaÑ<ԛ90zKh\$j7Iڻ]Kf'%fٜfM[(V@TX9lvqtug,hd~'Ѷmchb}>J87 i J\6u?Igk3[^>֟VSO_>ڿ}O?-ۗ/}gѾ=Ro_~~RVǷھϟ߾{\|ßo_~ן~y'=b)gZ}h3Ryf}[S [@tJ A*2 (yHE CN@ oFP"+r YAEպJ9oRA.Z\p{n 7]{Q]$!Y<ݠo g^ֱiqBG2)W41nph$"l$)ɰHBGR%b~`+13f>|yWXSL*d~as *c|Yn q*c.(;=s9a'aj?/a'̏vRt.]T-y"ظPKpS# ݕ';!i@| \[cA[t}]r{nŷwu m_701瘌.3Pof.uL3җ[M|#h|hXȾ:3hOPEFc7[F{ (VkHNc`Qa`Y<^wnF*tIoq{y:Ԧ ^ޓ9x}v5Տ+@F|f}L >հ;j]($[|\-G!3%(wǷE(Pi.FP1َ*}tjU P~l.uLF4 RO/ !J:݇Opr ya/ErLM3Zer\ M[خx\ 55Qp U5`0CEM |;pQ)<8kV;6 !Vg&$R dƆ8hϠjP'߹|g֞AԼ; 5 =v횇/e\D9MF qnBxw'վz_Wm(`>c'`%p 1g߱e_9@w+^m8-xT>hw4 u2/6nAK =@§Zaŕ|ۣBR~x9A T]C%QE4o`ZwϢ AӾ9~ AjRC:g7炅YxOab)9 w R f:*6_?+2=Nv1.)f*U"@h&[ hq^M3| ~) FBPo 2|{"Iz[/VjZBح0bhĸfb-*Őr/HZω CWxgqOK5TFCyujS%7cZ"α#^bZDg֬^$~&6 5^Y Llq#jqd1k7SŨnϥ1_=3L[T5L/6טEm^BƖ\}LVUΫyR6;6ZXH̭q9X q\ŋOfؔ L)֣G-k<|%Vk_n3- :⎉s7P[Jk1c"BC%rPr+'E |u4PfTː,Q/kCpw؂VC. efs_zd hHLV}*G4:f-vQn^f/alLF-5كO q5̸Qa{`6:ПzhS҂s9\vlzLP~RR(٬jV6 j>E(Gu{-~AwrbmNm}Ox"pS]ϭ3HgOBh1ᰥ%4ps !aˍ1-~m-7+-B2H 3(\O|o;>j6ms2I]K(A"vcc4t埝ꓪV-SFyO).ZH^@^rIJ.m,ޓKr{=Y~9/SJ#.Nt)n;kN3dV(:USl;i.k>Xwu3{m?6[/` mcb5ۤe袖Zl臞BۊάcqqLbJ=׊wN<}f:'(n&b (+tXr3ޚN@dpZH\]}({bUJښ=?Nvܴf$$ck©򤍵ۅJ -ѓ'Q-wցCRRoTkCeGJC m1izw.A<44kWYkWkyXS!!f>lV| 2qy˺p]cjudةdS4BaU8uH#G #% ;IPÅO?KC>4M(s LQN}!޽PNDS@4;^ Yd+h:m!rcK`DRBa%۴4p%S9&z]ye7hDx]%$)T6L!`4ζvs"8v,yA@q45:{N:Slit[72U =cOI;|u;[ZhR$W6/iƅӭF!0X83uuﲵaB(= ^fT|b>}J*Ђ㲙> `k=/KƬLc'z3>NC1s v0=s'aՌ`9jqLf=Va9cdZZs@}`doH2@%J*X=旦>8I-9yȒǨp5w o5?>n2m3oN)y!`9'pizayl߿3jn1f8zջ>LO=-| pr+":k&fy0m`N{K(t_rۮJL3_fJu&e;J۳z&ٴ}*,DC,ʣ"Cn }h2n|҇ItPꍝ\1y-ܽ_`*p$7`:u^և>W>)  -z1p-Plʞu%wXJӱCn]xUg$Л9&eD}ӄyF2K3.ܼbIxBCV}Q<Zkx r]µ,d6ǶZ!дdĹr_ٖSZG՗_:=w n Z{o_ش E}O0!Ax Vu=u*ah{_ki^DeIwR|p6 9NVhq<Ž9<YQb 67\S|OH5En'\{E&U]yA˚RK+I*dâZ²:c3{JPŒ1bl<:es$b/ѫaDJQe'&_Gc 6"ahpM Y[jڵhvFWԟMii],Teu&u3p':8Vcڗ1yS9TjFmyF:oMy }蟳֔Yg]g<ʲcU6,tf< Olv (*$gNzP-S''6[/P4ְH7h]𤼕_1ֻMMuJS0SBĹKUf|/%MUr#еpqQm:ֻ ҹ~d+Kx417J||M7Q)BqojGⳢ^Lr.{!վp=5:A F򇮋~m8ۉ,嚕2{ʙΓX#1i* aTSW=lz8,BӴoɜ|٣6&4* 2?ה22NMzӡSj {$ng Ci':֎O./gqw~浿Fߦy"ց6%_k v{:zS9vJeZyc43nM%s"DAE$׼Epy)U,mZv09`ںT.oΉFk )l)'FGKh_Mܦa7^51~_˗CǃMNgȳESfPSMŤvjTes6¥O)o)T6&u֥y*Op-u1SmՋu' U|SSsZ{A6hQ>;5Fg.d!\hD$*{撈 Kd`j 9ذNsAeol\~ MFע5ڷ1@ -lޙu%W.ݚKk\lr'QD5?}&JuH4"Q6f@N-YiP:7`VG;- ւF~/(RVw&r$p.pRٳ ?ʝmwa~uˠUdJ0 ߹2H] TV7KNH3 DOp`,\7 sw:[iҐ~Ë#&#qπ(>F Ҕ6FLi1֩ ^5f*!ǧ{|yDv]T"aTXfhb} ]9){`]gO7~8&4@ %ěWYDLYz;h c?r\]V:f& )R99ֹ{ipO&'llluJإ ~hDlTGGlw'uE9y%PR&-Q*T>uJk9t~[Z}Q3ۅ^Vl߁a낓` o?WvMK.ep/ ޙ2빎)ó>}UJW,30L>;Nac8u3ۖ(mmwkuڛOMϮ3B^ 4!6qҖ$ ;~tX>!e֠?fdT˄;U{V89ɞjaD+G[d34f!{v rЂܱHm],e4k,{^WkwD|"63uq}ԗu3dzs@;Z8[r 8eriņm +:i~픨QNKpժJyPJ] m47`.6:!묍T&Ct >հ9o[6J̰ r,5A=6۝RL9<@#/{\Lӂxr1E`2o[:Zb_j69.zUaE)NQtv@o`16+M1hBƥZKӬ' FGRZi}RW[xQ8M6Pw]/56Mg<_E:G*At3EMZsJblNnۦmp{.Gu*9ׄ겒능{Yy3 l yLU ㌳y@^Ac'N rtoDNK6ʡ^ՕS/P۬v{TKw_ 0q@*s#lNC7b%G8JcM'&Bsk\ק<&owFhoF2$#^H6a#gL~̓u `ܙIZEFaջTvBgj`i,&s!{WS`iZ9ѐ2WZ@pFjűġNå<l70,J3Z.ȾIT1' H t3lǿn)bFb,6VS_^Akeե8 ¹)2r:EtnMkn:>~Ep+?AL$'UsG#Dw&qELPVޟ'{1W nepvpO2X󊭰Zo8*0j@^#ԲZ S* ֫?+16k#]+9bs>|3|c{atjG lCw-g@Kuy%"5SrrZF{6eݷW[4H>S~6(\8rId7x݀bg$13we:!)̿YPtgb +IBCz(]ɲ\q]B"f"x°#$R&d-ǻ[̪n\ǯC_ۧO^>}~???\g>|oY%ջ/?`?!Ȅ %e|TzfaNg.'}x`Jykᄐ{؍p-H|bt/CؽaJ;nؕG^qsU iשVf'`CSnjV8@13>rNoq t?@䀮ȀJ;QKa#ZPtnvIgw+o_WoBDNsc:{ dA:G%H{`Uh38Ggy;9٣q?NGjވ\O_oů$d ?OƸnx ߰ ` VHյD_M:a- q;RYRVG]`UM֔enzz(qDDq:a@jBqD<U<]ULglct~3gvpΗπGƀvp\VE=՝yQ\ 0ća^ao":~~kOܮ~]3Ed]ꘄ]V]LGhphJ|'a똷P3ʙJ]/9(!4Py/[W -UPG{G +˵vrwqujG}(gUL76c(w.סFo@CQKj/` B+8cJ1x;T6 pFZ>Qk>0zbkuvstN]Hނg".֔BS"~/tu9NL [fbfy cx!cd3}@uJd-ڋd2,ȫn%-S? X5SF,5)͍ inb+F5[=`Z54OfMTKi[9$\Tձ6KBjf{~U:b̈mKaV؎v+w6wJo1˻[+s6p] R ˗/^ށ~lzawٵ,!OLgbR)ਇ~ȊzwlTfN /eziHR6`Z[Ç5EٴFEynN>ڠ+G 3v u]ƜX`Sm=)МgU-gCktmkGPJFMMs>\4艦Ґd Kv-rTHW :[hlU:*-x&%?9EA yfD~Bn9)^u#SCS-Iae2)-cp<^#wr# ey)AJܔ֭عR"DHt03``$-hU<,}\.K^ӤqRWX445}S tf./>Zh{SrPc2#j$'Αh9aΩ\|L%̌ 'KS ]a 1<_!qFŸ X87,.&ڛI91&PcLX]vj o (63\ k+j81hd֝i⛇>kZE.a^Ohv8lXj86[-'.]׹c ;_oFlhı[LӹMID3}㧑tXΪPB':}ǾQX.hȑՕOJQR\O~bԬJ.ҏDlVg.vV?@[U*"&OO6\Dߊ{֪Y&1Ӊ6`yC*G * -i-z!J#Zn4l==wrRJeb>BJe4>[K[=oT eB.Bjl4I&;l%aK9*@XuF1IE(%ZKy"+mb0^.MtJ?a2Qf~Jp3} KרCcȅ%6@0\O+U?!Ք0>ɅLe/JѢb-S#0l7-Zg#qͣAKch h=2l^9WL.pɖ顥ne?iaL(Uƌ% 4A&=a8>EFWs|s,a 4cLvRQ uPRF',?Kd[K[Ho:SKCjkwF97 RrLGQ\nƽ2Ȗ-Jf Je}Pk5ܥY9D9NսR֪QE e)Y?\jݩÌKdQ5"Ϥ^5Crp +a?O3d!':]mLL1ڵƴ{>*@g?g H!GNnH/rO9&"sdd.nHN3s'c Exg9VX2. 8>% IUViq$!O\ 79JL/Wޠ|7 DqˠÕ?&ɀ\uʋ;$.v܏Qrߺa>0 u[>d1,q$%7Y{P$'-4!2Ij6M$i-&Wji^*rUuGK;J;B:uZ-$=3NJ8Pj\W`$A\ 4][ė]l /~Fy'ۡ%f!qJn1MH =gf B(G1u 'Ϧ|sr\p=fT.*\,ڰzޚc#:xdAt׷Mskg 8FT+GWM$uЫ`oȦ* ԇ\>.j8V\=7Ue8E{YW,2 4W+z8je ~ 7Ír(⯛.b%A@ 5MvԨP Pɮ9=!=VMwsC1c}|HEC@\s齏q'ގʫV{Q6Į aX6gk6Spr@*+ZE94HZa$iHCuJ!lNؘ)mgT ۑ\N"Є;$Bwꯧ Wbܹ%OCU9Hkhgt5_+yXFTepVibX*eF[+tZ %vm/Mg,t} =~d)FAr E[U,zᩂ0,íp)U3hࣅd>X(䱣r m)%#l䵛0׿t#1-Cx>FE.Big_E+: jJЭ[V=ZǫZR5 A3)zRG3|ҔgYq)GW9~Z7Y_ӠRқZGFƕ왖]>/Dj[^7,׫#(Z 8MR7D>/f&| uYZ3 \>Ҽua2tH!xwhmp'<Q:'Q$Q$ 7BVl7Q %G)wR/(Jq^\ $aǵKڞ&heQ(n@m3kRcbbKj,ԷkҢ'L-sx$GCM4 fY:dHg,ၴ(Z7GBXqR;oRE3.V!̕Պb0%V 1g];Egd9BZ2Ii8agC]hSTa6t྽OEbݍ/JcKM1|dQKFY*Ym#ÂUdhA`zJۃjh^̃V*=bL9xxC%8o| Ȑ&9|ɬQ:lnq ;v;e<{э,WT"V&Kڇ]0lThR ii4ww3t~8!p|Xm=h$I/LP$_h*}tN! ҹyJ sˤЁs(;e 敾VԃPJQåD))!J^3uQPV|e*ӗjNq*ފJ JPw]u@D2@qVzبfq^_1{~ͱt2YJ Y j,hㅍN8j/yA0-Z$VՕ[af״_Ht) Ef֎;{]qp|+u`ϸ(#2gքGw uZ&JN2x7IVkҿa*sjU( C pn`Y9VPMr. ; ?9+MGk8\4r4c -Sr߰DK+Pğiqa<X%n]ȔC/3W ({.nc D=ذyZ#f9A31{S=jdu?wu0լD56A>:2=)14LVJ嫴*"x˰157a1q# DW kL2!&J2Gdw\pI;s'ZS=@ndPuǼm勐@9|ąElȇ-52nPƉ9XzC2yv2_,rҷ]F,bH/m\RA1]`"9Q゛`d{PրvQ/[Uo\vƩ $'NR 8I[G|)vY^t`q Zlݖ@항 !Zyb 5،(ɠ&I;;k ^f}><[09@S~m˅%S&rx}ށKo6`BaڡD\2sNڅ:j+_\)(qjsw$nމz#Dc^L1զe/ܰj)4H3e}9fkOLCFJIbgZpMe13>rDсVdF]O-L4OP\ "5VEu0Ǧ.ma-\~rfIᐰ1vs@rhS{(L/l Ǿf0ބ]ǼagD!'1J"D 򜿗 '=Qy~aw_ftc]Zk#§7e}%YtT3M`NՆuE?Q$8%σL\#o${g_hz3 Z܆E\[aPUvҁ@wm n[aqy7}:_L(uW,jnWi}js/18N\č2Cɲ)Lǰ2c^wTDZXRgO|:6{||9 DV+.|,5,咞).@w*/Io@V[,=; ̳5F-R>sJ^bb{r+odP-S: H3J|Rl[ì292Nf$xryRMK'IcheC ^~)eT LDYJ;ҴU*; "fFT/ BkCύ2W쉎CU\ߍȪՉq^qe03] G[B&W>Y*1%K-Чhf)OP6; ։i,:"IFߎUoq3k3v0$<.C| ۂ)eǥV[{߾T(JKRKpU.  ZM;Ӱ ]ѥNix #/M=* Fju?U#'d/1bO{ko)u"U1 [Xw>bK)M)alL^WvT,omYN "(iu!b\29wezh ݰe iz7n*!XbLWSZVԞ^^FyVAbp.T4xBM+ޫ,yQG㽔b$7hC\ ?Q.y}RHFLVQ_-a`:o@FӾM"։"$ԋrs! ?sE{ɩ#Y03u u"vꛆSm-VapyOXJ,^U+:кL=e7On9W=ooiπd6BZ4 Xс7_B& z.Nԫ6 $0no4աC怉T?';}=We 5qN <{Gf.ojm^vGOT!'I/U¸I:^8ӋB2 '9:)PȒ'US=ڪ$&\Vrmu)x43D.w#z׊"vU{TH4]< $&E&M;8eڋ#,񶽋j Bb"yU5\+9>geoŗ޲`gvF{(*!:1hM䎨&Fs˱ۊ!m&~U}H[$'ȩiQ-hiXa` Hm9Ї3Z-CU+Q DWpl t4 ,̜U[^AH'Gf@@w'}fWo3zH_ rՍih$v"\G:{6osr*-l8i>6>wW#sm7 @De8UwxPlo ӈ\؛}AEyNBC6)}remVEͨ*ZVd<ޏwv&-VY%B⹰?[?Gk:~ǿ?/?}^W?wKN?Η_?3_#?+3WO?U)fO޿|y{//w_/S~_To?_ro߿?OTA/?/߾PW@Jo=S&p5 gP`go%m viTzE >t4sNU\.@u|/Űѹe.x-k ȂkQ|_tY0HpwL7T[x{ +߰3|E\{ܖ.0LGm Qf'vOl)(wh:zM6Qu<ȾgCkjTsdUNM˼ʳoix;J=̿ ?s; '#+Zs؆f7:> ʋO5\}uYnz zzH2 2T,(x,%=1g/4ʮNn9.'_!Dc;<):YN1WGIh  &{- Ic8p?ZQZQX#HʰTqtmU2a1%]/}q 9/ 1_mh \ߕV;sGfB5/@eT v gt=D^r6\B$W9U^^wtIT5+l)O:cn J7PDH:O4[D@_SعX؅V fcJ)у-W*7P/<͊$( Gaњ;q]Fu⸇% iOCp/Uhӥ kqR!ִLV'V̽tH&q!xy ]wCH6?2.(z;lm*ܮqmc=#_A7QΊ4"?%$urc ksY9=kvUQyDu#05V7X zi,$clpp>h0,O /*hf 0Ch֔q';`G c?s-6ؘrlƄ7E׎4מ[ i;5VY@s;>H~$ux@eq̋Zncڥj}CsL Y֓- m^E|8Gh @%6j!1_G ~ r}OJd"(mu#{uO5' o6Dksb\B  rr-Fy;hW 6OfANO0 FQf0<<*H!;ȒiJZ?seJgG7 /.1C4,mذuO&@[Wd/T}ܴ@ 0y6qݗ]N(!<&?Q{Ky[J5M%\8 29C ] TD3Ad] ֟ލ c6OFNR'E8oE˞%iFֵx#![(i![#,0S['"En0]p0+9˗&Aju,̾c0d(Mz?9&VI;X E{c gQo|*_3h"_"#K_m :M`[6nk%E2}م5z$Ja:\Ѕՠk$ʍƤ{<{M_zӻ !<w̶1jWs˴Dݞ0#*Iv=1ӪEmmSI|9䰑tp?z@67 #Xq3{1sb"6 V1rȅ\q%Ucd9 sXm!mfs=F6hֱ4m[\)/_1nXT*Ty{!gz^'ֶ.Yd$R1t]::0%of9Crx4=Y&2g)҆TBw7wt&qr~ڼAW B}GҦqc \Iahu_u +tP@r&ʝ I#٩14}8m-Y QtInN)qu[8"}_15.Yy=@dh?#d-yO[(Ѡ:a2ܘY6%,5U"u'mܰs r"9~Y L[ugAƘps{k^Z:wAR ܨz9cKafjhr%'Avc9f!hhay!+@ .Lr.C*lF0֯%s6Z5.EK\{ǩOsluhGD_?c~710q9Ђ=ˡg6)a{˫{j͍wEfz'IRL?nȂȋݭ.% C Zp\f6ꀺ#gU̲ƪ#!y3 &2% *f R!h< ?4smӠ;:%PXfm:umkl9mu6;8mke:Qj~VҎTS(j29_2)51̴VV(ᩅycؠ| MaK} Ec 9| 6k-9iZzjn ܺo'\/̴2Ygά:96^L:k)2PRV?{c qW=S(%>ׅixA^%oMq5<646+^̝{c' V^ =#$h=D1wA*Qʘ谴‘G:ORbKAijBr/mM<%DI):lEdn/%y4"rꖇ1tj)}ٚ[c7b}b:{1_,;v b'liof.mBT!-Cgm4qb=/"zzS_/:3D[gkQ;!~ENsZۀ2iu:K`q9s)R{{aG~TWfDNr$BA.N&+'}ZY ʌ2zVG&>͢m:3Kpg}BRZK.;L tl/l~snۑ箘˩2rU.9X{56T2Ͽ¦"=h-E<[:pC, "]qzO*ԶS ^4ȭ"|q|\eAd?F<944\:N}'璉iW8.[S޸d-QJDACfRb_.QG 1aD&E\%ޓw$22mqs%ԜnX [cIF‘{0$SHԬA%ϐ$*RC抈޶[rĝRgWR9eT`)T+ӣS&?82S/$)0$%jZ(ocM %?g}ڊbMԧ[=P !Dqlm}C.p{?7 ֋dpsA-O?rî~z"VzoI澾`Se;H ,AãۙO.$m1P4']B\~̯$Q(jA1A$ K S‘)JrCb+mR9y"SZV;-OHxW$ќp߿vɘ* *h*%љ'[:;Z zCζ=rg9/%J3ɼ9~m^EOn5_6(Ne+BWD -41N%r\G\VnA~b۟)ј ,?l0c,W[F4=UnRs|)MD_)S#:3Ɔ6mh|Nu@tJGdܦ?n>/_kk4=Ev&w) 1}V]cw=oh\3-uc;3Uٽwz#~ F8ułNoL8 9{UXp[&TZcCY,T+|-Y;MGx?rIVx*BmN-׻0&{1sz`.bq'16,qvcO@h,r#p}Pb/TJܨ2!M b4F(&N: 4tUXM]W6M\x}X MYuHN\c92g|dH:)W Qe4O*h)PmUŊ=}TV6?CG*7 ;M \gI^aDeyDH)ŘmgyKN|qǶwrV{z4 80̥"7Gnh4tϱp \$*}j+hf{6^NAG-[N =sh,i䚩$hå}])2<2X9kMP ssoHsuOd=dh.%myeGUg6}Js1 AAšycZnI>YbHtzIWLj6X( ǻLNify*!༰{N~PtK'G-M 8{MfYn8٭Ţ Ǡ̦xF$O|<]?ӬzTLߢ)YP\/aQchb|}1vϬV#[ҵ0G ̩/R" R v!l9`"Lbc bg)K<{F- 8|Z.X:IlI4cѰ{O 5 /x( [_!J[5hoof:g0ќC]C wN"|9%zRDpR֍R絠IsymiO+kԫ02ƈXm}-<C1֛tb_KŤ`.)svE&Bݦgѥ{I^)gZWlqrZG7e805:ujve/|9ڤ1}IJ ®?d(Ct-dJ#`I; :SeĶ4?u,SR%'۠nPmT^.hKyߍ4Le V04K5[mc&DJ,ER)C+ZnaAIAhbsnu5v7MV(Ęl:#mE/mmfJUR,1-q`.190NZMv|eLKb2$G,bk-uwXP} kۼݻN]@4噴q}ƵZS "GP9P],Gԟ;Lb[qC}ehWv SZ9TҼðza:+Ipg{XJM.FE1yE4w[ߑŽE@%sf.ZirC?gr , a"2I7D[!m3'gz7{wXP,$ZsRZFŃu]r$Hg:!UyJ|K5kot[NL-Tƶ3:}W`5&U9ƒ-œn4? k>B?52cI#@<5\l-)s{kxҸMQ9=P\{y _ZcEQˎR? ۈ@qߞɟ 2FZx3)'tz6|̔g[#RG`t]6Zc m#n ,Cv);eqg1޵{HϤl4Hpҹ+Q|8FTzM˟!Ba"YvL!1 ֡(IHOFxu?IaD12HQj5Ba#=<_Y#~GkbeiGa%3Vig+)gƚ>v<2tF=F 9H!aa׃h%jUF5htm):t:ސ(rFd5imwKI% eIkiU ]V{5tlZEFF:(i;ȩ\<93"7.Ra HP8Z +F@GpHBt X=H!7g,259R$}Z;wNσy{v xǘ`$3=#v)%+15IPQ3,A1h;EZK"@9-[*AJ2YΑ)Q:EmqrFT*Lm :TLռu̡FT\oa@eS#[dmߛvM„!bgވ1CWlƳiU 4?[DIFi4eJ/ldlEKd|JrM\\B#s]<Xo:6cMbMgQˠoJ{͗|lNGjr#vLZܲrGj/d'*p@.tĄ95tԘl zjĄW{l*r3/&>M?y]zNPPևi T7 .aRdO,!FU-jԥoH\T;USN,h<sm%섵"`j9o"B4*qIcpO &dCIu.ga`AO3}JI s/`&,; lyT5.^6lc9 'TrCEM)(Hc^RBBC4"ZYz^ +, cنTזT,泎Awɂ 8=%Zz['pVnNT+rt54-=g VrRvt >6Jj$p-TӝpT VŤwp G`KP1 ~@-#hж&Huu:Ű%x}[}6Bwx**8M![ wV10 2WST#bLBlkO% n^76Ru>Տ.6(Gؑ@ *qUUȵ 1OF- Qj9c'Ч9Ԝ9u 3sB%|Yo[B,9)a\ C'7{xfj-'uG~#MM%j.mrNF ^ *"t_ (dEL IYܓ!MQy3KB4$WTp;!N6o/z,6Д:ȴ9H=B͠NxzHQ)W_V{ڎt> IAlFkilPD0+oOוQ&A.`J/\J]B_Ԝ|anr2Ƶ62>J$;ԦCk8dۘHn 7|qvɠ6c }V]+D:E0>ō)'2k{^lR5`\[oK%W11ݡky6`y_q'2]-)`-_W)vuT8Q+ x8:4gie9 Rn]D[23}b=j5BAYl-'"Wg`3BSM4uH߈A Krt+#uw l"`֔j306j=ƼD0HDL6zT[Sx\ʮ]=j-2ĢKz$tZ/A~)-׶هa$qdY dAn ^FS-Ĥ'qn!7W=emM_Psh. nߡB*?)|83=$::TAZ; m +\ŠV)H}0tXNfew!m7*uLR0~53n!OggXcq@v$tkuM( 'ɢ5w¶ı:?+M좷IY)peNNRp]-قUM jS\u{3k:NզS+pR.;y!u/ş+tg5ghOw&@F@]+ϵc' AkuJzz1psa+#B4ZR~?qbo/YMH`b)r@j|?g,7WMCR Цr_ͣg:X_q`6>cq!Ћ4&=nPUaaZ#뇌kOea_&ፏ@d]7n 5Mhĭb4 ${G!Jv[߆ s\!ǁY =1&vƔk{rgWݣ|R[i25=]CH/ c)-S +k{}]j.1Y-$϶%ށ1<S:iٟM- K3k(f3BZ\)E'uV;]S<05xn#&[92olPJُc%oq2V&VZѷ*I5ӎ G1R6+}_QtHYJR<._T&G'nm}U߁RZ;ňQ=%69 ju9Wic읣zhE^Jl ? F&]qd",n`x(y0]ꯌgK[HpnM#iJG&JDŽN!NJGQil\fOI:15v_,Zѽz]S5nX}G n^ܱ'Zs7le\PhM}ݥԉ3%m.[v5GxjV8g)qd]Y"_X9ܶC &2;ʅ ^,IYwOGÐ#Ux~Η ʮf-v*rvBڻcQLXtU@xC~|bUf貰ظj! x||qX6. 1ߔѲNg_,{}B4&^[59|^~ 3ofEZmh0U vii;`ve{*mHx4,MMuqI.mƼ񱝀H(3shqrI-pN0K*i4׷ooOhf_jJ\ Ӿ"_/wkQ~P;;Θc9(cr(jZv\mvGsLE4cE\^ƒdaA%2.G\c~֫!j:nO-e^i{bj&7dtAkP/<8 )չg<,qEQ.յt`KK{ӆX糭ʼnrL|t^ZϮģb0c5y:Ҟ'v)^X^j Bj{{9ЩuQ-)e^[Er>O(R>b:-ӻ=/LS`Gؠ FV91Lߟ]PdΧ{'7!.$X}Mf1 ѰtvAY$3[OoE]~{Dܔ>:[P%RzbU=Yن' ^Z}j2[ KY[ &u,F4r mW}}uezZ[J;z؅߰+ 9sEQ8z}9p}BIsc,;ĸ;@Мh˷%֍o⸐eaҖMI4AYw=2TIlֹM܊ƽR8tBkhn6}/WM!k|篟S咦qmTmJOu>L2?bV.?/I(h?l+0T٤ @%q* a G~TXUF͘Kep5YKPVʥ ʛIQh-ij2VI\–J`<ڒ|[pp li6ìÔCȃ8 F4#*#*ZXPC,r} k] r3 7i.Xi;cu6[mWF_3}בtML0e|,zw3^ xehm]ώSo~!*U90)R*@Y1nBq+z͋;$P~⭍4KB.o[e_MK] g&?8n,K:d2ܟ] ڝ#7EXG}6*;gg$^]ľE-,3`^ fli0Nנ߃[Jڨù(`G{Ag= 6_]agyR`Iؒ*f}~<"Ԛ1xznM 3#[www0cn,J+^?}{Κ";x%(;aWf3l⼵hax_r7|AT!Ƅ7`yyYbɃh(n.9.ʕC$"P1}Jr3 bVlpٕy0t|aSnM lmR!N2xss%q; z [C+Dg$?(u< cFSR@?vyo:*| 둟J?^%D|L{Ln "7zFޠp&cg<'ߌ|sJ}鼞2,:|O?cyX>&͇q d'uMf9-jbWML:jTjw+ZI_*QLͳqA[{)ʓDK(7ZFPn]bm\1Z\ rNr`Y{_4 [%t qt=]i=Azs;g % w= 1ް""> ^`}zt- qU[L.SHWǭ ;Ft+zd=}2&:{Ȏ(EYD%rdm%l53;[WaGyXgZ29 CV93pTD|S#I洡:\3ي^2ttl9dEdcn(NSq \SW3;g\Z&! r|]d C:ekn'̩jagEet4L8vx@mW t㞅 qjQJ*sǼR=(qd#VޞTMKJ9O4EϬX2AAۦϽfѼj!4u@x;0Pp6Y]\#**>+vPiVXLߐ~22`Kõ !=$FW Apc= vi4jYsY>&QE A1% _^PwRa ܑHWgQlgl85S`ی [/CY)EcoR)&nnflb/lϩ :(sgҘXtmۋż KPOXPCm^Qu\ϱk ) IԹPTSQk " aPWŽ?^CddIRαu(d$H(iV78Yb  )IJ!1w\ 6v ]ӒiPG[*Ǡ9p'/ rܙig'o8+NQR[I㌀QZR @į8t φN5u'mXS;s :`ϳ>eoV몶:#ڬ AXG' AuFt7O)"vFa`R6EvnNT$ L9pKEۈ7nXɬ>k8zW8cm3ݯܑw8PBd.*޴eSO^h&Ѽ]MXrZ#\#fJȎ?JZ∇r`J dm\ ^P+{(ȑE3#g\YK jc hi.W!%Wqqa1r #c.O.+` ltԄ!^2˃$rƉ29:IH$@9ѥŊ&8(E*H26 9ꂤ6$$mp g<3NT2=KJ4"p q%i~#yn+AY!vŭm[1{vVĭ[#K2J޼*TBC +]˒%m]eؑ;fѢڎC&[wK^㝯DfCLpkpp(|gx+7ҿk@IL=+^^߾Jo˯{~yLǗW~Ͽ_헿|-x)/Gӯ.O>~dU@@?p(,yu- yDzC)&p xZxVsH[!ݱ_/EC> YgYf\_TRfqd=kP+YرRvH!f~1O!Xa{&'+F#T̐ɠp.%0_7pp3൳%0.zRlVlgгYbsK+}=Ah8Yԇ8`5ZV:Hu0Karf4{0ISXwޮ܄pDK AҔ_X?bz^-wڦӉa sKvzj#zowz=.WoxdpSV;*_I#}a^xI {Kz)O3rŸ@8&CGJ. TL:4a FD nֳU,5&,9FEP 8M!PuUFO|v/U1˺0N0uʓ)*٪9R֗dhP8-;'bg PvqIR8xXOwH_Йtf'1Iݸ%e9n"^~'"gip2F'J bx2qǪ:v5[± 7f dSl2x."JpfW6P F88<>#' ã̊#^dcb7D-xѹ6]{qqOjF#Ŋ\DNc;qRFyrQM.O_ H׊3+]Y2 {9oнîL9k%׬ĊXOlw_Rdxhv`HVAmk;iD̝KNSB-E*oNf>PԞ!f83ܸ2m0(kHbW$clPǢXm TL.aIz7HȲ|j<6;kg'[3'!dZ.tBQ>,+bTt^ÛhYp{TMS^Qh"`@Rd]iå-sڀVR9VaehĴt!On6Kg%uquQÛeɅ4- 6Yk$q)@@ly)Wphy=+I[vNr8&t jsg F hfg4Y77r^gb.m2F.8=a1(vK,M.H0W.55V4 D r.ZEZjOY1;zJ3LKZh; pG J;v 6fsC8|5LgINJ-VS .U䜧pG4Uid]4Sp{W(ʫZ0akQ%q֥k8|;HS`M}zʄBHHMNq!!q|"^ d h|6q_2wK)vl(ʉU`^&Vŝ*0 XǡL!L#XA;.1BunuP$;{psI[w)5NB)୪u_5ȣЁx[=kd-G!aR6>"8[ j{\unFh~4`9Oϖx>(>hKSv<}cv* ?EآK2dk.a4,&[[R_'uu/S.<_fMJM̆$>>\U4n 5XY=Y NO< Xa vT4@I1]|!~^%֏Eķ82$p=52f!MlS)Ĥį*(㢶j)j?e <ǝi!,LkQ\׬:G2]oƳ0Lm:D4&=Qh3;SɧƓHySB YGڱxZIÈrSV"jq1db()ءe% Ԣy``e2q ;ʔ2b6();S[܉,K=xb /ICT"^ȣYKzăU^T>k0]5&v-~(BZy] 2~ܡ0c$FW9$cXE&>W/n͆ T-R6ڑ Fʳlcd53xoKЦ CoH7\I Wu#©DvLO$7R|YWQL%QDz' 5CuZ@{6 >#@6j~8^0#_\z}zÑU*R {J˔h_"Iċ; _ f?Ż+I!5/)qIERPEڿxzoԖ9>S9+ C(5Ʃ* _P  >tFǾ8%*O,[7slp$-7r? <M`5% ^zqA?dm(#w u @/Ry<)ZoٯP4SvrXW.Ӆ,Y 30]ATk"@[~WO-;Nq?Zfij'^|VX1't嫌viOQsSf5_?6z3N\ |XFX`+~N`NUO )u @ZӀ"|]AcS(*DP'rJ }zjfA\Et$ʄiiR+^̞)U6g7WtEwPvz=X0 Wy3_ 9tUעU?`66z&lJM)42ǧ-WHKC l߀b\8qeȅq5ڛlSٿ6!?`iwekYՅm [yOѺӾtX᭖,%`/Cr,q@, F~v[! L\|g|-ap!̻M"A i9ZRi*O7-2Ae.I1&zVl@Q*bwHOSͪM2+ڏU5ّ9$e\<2dmxG@Tg>cӘ:1OL_2#7@>ZUBw #[<-v%݊ltdK0-~:eFZg\odZMo}f @üKYs?!Wu(+|kA]xwif4uҨ9p9n ے (ߠyW @䑥|Bu{ *گLgKkC+\b [=_?mVn Mlէþv1mka.+'#M62d~Kq]=_Zy̲߫% bI![&m<1NLEtOvdᑽr[^a *2:١w }v¸8DNU1]wKk̲ܔGḿw:$H G-N#g(Ze"_/\JGh\!-错z(G;y2 UF;srفZi?vPV8z"43S 袏1H];Ȫ񌼊jg`jx|: j]UJEmupvjV&AAI xI31V3·A+ޔ*/;kFז'.6d6S.ZZ}/^Jy w"@W}`ggi=44{,qk<#hStWPUw1yclU|3ڕ^}|R0#ؙ46cA)G)cgMk([ӳj,?PGSk)jaϸ;zƅRC E⥉Uryq*?txK0m9V[.ar|\嬩$g>/s1YEq6k:I';0Rץ9L7dz*!k9zsVh[.`><}e=8.T uU Pt};q:2سw }}T Fr=a R 47jLw`ǺMHa`ɠוf4sG0% 8p/$*QmLXXk8㭦SNJɍ'k{jupAX\dsZTrB]_0UK|x>͓'i-ijVT1(* <ڑ|J [yVnEKSm9_@N0brɢruNv0)J>ΰo+/Nџ2)>p1q;o=;vNZbuB5#}ܽ$*1{Bg[d=+fI{3`o(|E-Rjnڤ 7xDj0ӱHP`((Ʌɤt O6}AuSHb6}ٵ+DF0\qᯫf\~C2&: DO[ړ,$d!b0Ѳ/MɾN;jUOyNu*;sAV`v./"--^̍&lSm:nRܛ^DEߗ,mL+p"! T8_ u}脝jV;{EwSKԃ[Z, CTCl10Hk/;ڬ=O+e['@,Z!yy5P"O1s J-mMDGXQˁ{RxY?ǀ2&S}FeIFlKRٙw@SjaJ*8C/efgh.7QDƧNC܅QEwcz\#0Zv(]-d>$~cEv+.c6ve"T暟&Nql6j+ʼOJ> Y`Ɖ* T[E :)rk&,랐Psh-'cqA 9 D&)cgd{D"sgfVFs2ʱ6iP]wThqK9D}O1kC$j1o~2//eoK<hpmZGmw˘3lьw΅%+?;me%[0R΍KV&]/4efUt\ミpG ["$ ,BBOIhk:>%Z@s/Ȑ0ӹXO Yr&vy>.eA˒h$<_jLp<}+Wy@+T# t3z)t>P]Y XKm%R ppaі荟|-Ԁ~ V)gt1#&ADw0 ;FoYfЃ4MDi@@u)dǕMCHkسPub8%ȈT؄)Y-0`@Z:~2[#}yIxt(Z|λ OŝZ_MsG_k0ykb+ny P!oV 2ĖTq6.{ Ys(nTw;&" :@} ^*\>IMqpj|n֓]fRK\Iv;C@mVp̑V4l3!8bf}u^";ʑ# ;  x N>8>{)J* z$0LR>M L Vmm9XԃB]z {R[&̴8Oh[-6vebӡ.{)QϤ+#Z00]#]+O?̀gSm&C6#UBɹJHIz_A>ԩa-E`h@luDW 4 ᢓo̮Rd e7RuL`jB$#287>7a} RJi7=SmӬ1 #:pSktt:؂͉6seInIMbC [.s:'0XFds@ut~B%eSt1xMF"t?z;fd,?ى鎣Mlf' m.b6 H>LQSm鑠OLj㖄,|*<>O<[a(C:g:}6d0z/qWVVȵiZ8c5APnE+0tjl0HkXڄׁOY/<#4>U;w&$2gj;ܨ5n̳\j8Dr;M5VZ B1DYt Fc<  ΐncLz9ΊMq#y 8j#fp'ʉ=egxtg. H!^6wGv %uHd>qԦXBCG']ɒ$q=hmsh LƃxŒ[{FfF9Uz=~O߿xBʷO׏?|oo?ȷ~}C-޶,?ˏw?"W|wߦ|-G|QPYo¿}0ۏ{{*־o+?\PS6ӎkJC*Vxx7oj{^*"(}c=s;?ԃg9Y P'T ߻Hŗa*t4T&& xSVw Hٍ6DafˈGogŧ9ۜ3F}xTzmz2Tw;F(4EǗ ΈNJS Վx:Suׅ|v f}V^=a'OiA4e7v 6Ynf,a+~' -;${HF$/;G*#,Q(j_{";ߎɶPH nG*F mE;^5pmwuxLUf -p>f#._"L R_)n+'Z"IY صUc 7:ߌ"]\(רg@E>gj|CJ- i R#x*AA^FoE! ;IGShѓ,ԫ_ rBQM(F_>cq%19>"FDb~@Ȅd  5%Do_>Y^9W G#eBdv3[=q$AӘ[ Kwcђ;}<7A|jј GSޏ_Fxm%ς:.CLnu 3YcB[ M thw GͧEF9.&7lφ(b|=RÈ91.Er ZW:t vJ(hxL ?~{vrN-.䗏᭟NcβU9ƧUVt1u]XX(sJ BuHiRXyc75~n,v;3K Ol5>:6g;3vu+lR:ST<*p5H"^ vd+Ad4Рdޚpܺgl A11]Fp[^g4."E$)G קY\Iru|Sfԯ~Q_RɚR{,Dŋ:x{lAb:;l;5)ZnG.FICQLg۬iʨzթW5,Jxgw}JP"LƥN±Fn"ϴlĬ1@a} Z Xn@`˰}mJ_tW*``2,߄ a~6K T٨G3;ЦVr CLf*0}1H0WrhBDSF0A{05S0z0ÈFC ŭ>:mcv꼍CtGvv[ŶdTID;͎*"Rb֘0V$4>~ܾ=o3VBIӁk+g[Jiʮ z_>5+l K%^.O>87` x3D-r< UdI9bٟIr7f=E +j}G<V]Xm*CC3velbM6G*3L؉mLة ]RƦӮZpaePCkH |gÚ5 @I34|]bʔ1Qa:ݬ8lEF6G [Wj#k$]'vߴYQce ݲp'VjZ3۝r,ܹV4jQ7'?͐RhJ+˼S%NM:'296Č- 헥T.!b1Q7:ՀL*!)Jf.vcDC mM}K`*\ǾF;f~ȔٽN&DleCNe< x-r5I1|qEcV,wtn l(v5d2t1y;t@.W;<4g2 qbz9nqBg7;Y] u0IY|-2e V4I "yvc@'ǛB 1fW\ gk5;9c[)Q.hfTha>-Ɇ?Nyi 3Q7>s@&Q1%.|u_mLЦ`|< k/䂘V6e2^; M,هC34ynSPg30y#:g&Al`n&LVr_N2 JiT3*#]\zyѨ+/!7g^]TbC!M]b3A6q!70J֧c֧A b.))?%s~ֶ0zRh߼ܗV2@눥c"O!iHf3H27}l?ضwG<{&!wԡsq S# 34 7de/ݙ 'ialDypi8% ^O,*?uiy|i;ź2@L$H|]}=?I F]*G*Z糧2Up<5A% 4:9 icH~ti=М ސ.ϪgCAy3g.{SHM~ ? bm{Mcm(c8wf>~ڼ%]uGtf:o-*9 Rer~Ԁ VXgL}p䥓 "X"eEjm%ڹ4&KSS0h4MNJ7NCA6 j,i/4 1ݹiMcpƞzRdv,?&;}ҷ*b+eim1sȧC9.n@@?u:Gc dד%i|5Dq2(Ԏ'N7jEoCifir2( VHHj9o$" BRqcrDϺq=_씫?3ɢŒ%#~KWIxHS]Gg \ t!hxqi͉7FC M?RœX4᳘96u0/ MִZyFnj|Dxa,VڋM$4Pz AZf霳]r۹ [Ϟlr2yL«٧BMk N9[pZ)T OmgeseA`p͵H/6GM 6]w@3S[ar 8T`T- @ǔ{j NqTY'CË|RPע 0(+Pު<:"ʋͺ`Sru9ap+p)i [:4AJtp) 瓓˟$v:C?rs{6TBwn碕-8ve?RQ-1ۂ`jvuaxOGƚV{\H`$16he֏0QA%bu ^Oc/sL&ҪճЎҼkZ7vA8t(L]f{"+w _9.nQG}}لX嶾Lׄ]Yz@u ̗yr-:՜;6`㦺a exߙFx^(l2~üb^I *bDl$8uL8$[zh=-M ҄<,Lj$ãg"72TUAY4 61<7 v+@I Sūɞ't"h}<$'f.jY2c͒ˋm]n–S+Fj-[B1g:b_߁C|"k@͂\E̜ oꃱ `iR`LY31˜׉؈m!Z(m+kMϔMs!uȹ(mrHw`Esx{A/x:ب% ںQpF JYZٽԵ$l+'{IbE.Ex]W}-8D*]$%=v+[ׯWOxHT+rJ6 װ->6ނ]Ѵxߦ`+wV',1갮E|]rFMp9eduI baʖ^q.wKq8Phќ<ӽ>SM+Z{_ b>7v$td(9ɴ̞yaͰFM+cTnhFLp1nA}p;l[61*v./A d|$%s ڟpڳQ#@ud)9z3(mbuϾs~-Ȉ6l B;Hƥ]_/InF! * 0nɎ$r Sk.X)\m~ib8| KmH k.ljBKqgub~zqP`UqFҸcf2Fa%0 r-u4ͨ;MJb 8>4F9fE+.^n%Ys{/g$Yiv΋5 ]N3a}jj7.+c9Uf:Q LN}I`o@jkќDPt #DP7iƸ˷S>NK"Q.&SD`ߎ[ZwkCͰѺWSrdPq.m)=5tKIˈU]c7lZ;]NJlWrDFttN\`,aVAs0t@ɺޢ4:s)=87mF#vZ 9䪂p_j+o*w䛶"ϡ2a{EeowkFe6Kg+y{ʴzL~9rKV{C2=萢V6Az$Lfyi^awA$y.)$#hp@Dw 4wY0|O,fo]ci`TL}l]‰t+&1(弍4f;O2UYa#kEV5QVt7^*I3u/: JN}ŸY/ʬ'_ʾ)J8?#l@UQꅷWW(uVM7V(F9B'֡ƃ CEV9xg"Ǵdِm@lun##2 8f91DW`dI7 k:_`_Jm»'۶?YGOoLDc(6ʶ&iL)Pܜ2ȌNcrnAʭMe X˯ic 'M=/_c>%1I~[3F%\;HT4ͣ0Q"rp<1ڣԁzð&עu d-J{lBQ4{H;R*We"[Zk)315Rd ^IJՆ\7/3g j][6l› ` EюQEإt :^!8KTǔnlTDdvG0ҧ -w8M j,U)]ȠK8/x_( ޱ7~Xrp^pV2~YAo}-7E'2! )톲(Zry}oQ4vnL텒1'/5CKF82 ae68)jf}[R5=NŮ'G<#+Rou.}\Z:daVF.I ?r{@xem2|$YéwPQlFr)*nPBބdIH=MlQo|9KNo?~pҺ=2r$^Mh=dǒYV|#kV`XxhUPigZnFukbi\Qpmqe M:uԫ/߰Ӵi]a̜%pUݕx A<1ڲxX^[GT)L_Rf vy?I:`HQ⭒^93 "òO.vN5'ET/=+h?B;+˱}Z@cV?61RBC*}K^ݚ--ޏfAImGh$Y͑^xxH\ 7 ۲|S|<ۧQRׯ_1:/O{cY}_~߿_߾_~Eo=B|')'??CO0m/xSg?~6u~OY?O|*RN1rO|߿'IΡB Csං?(;9N5~G n1~Ű-':g¯"'Yw481_O'>xf]07>^8!9 "<Zw_64~"UO Yx|Կj~ex[u5TMϡ+vtVнil b䄱sscu1:ļ b9RLʭ2_0^$rS0EUoN`'iII}wi#ӶvoUyw{:JZ㐲%Ж .݉]~1DQM(pCE315",Go\j/9Jqi"jZfJ6gDZQ= 2ռ9ϛPфvW^&+g !8]ЭVn̈́JxA0 Ҩ)99l]MX9n] $kƴ~fg:8O+hrFk|a>aJ](bXvBN 9IN/g=:@R|cʹ[DE9߶KM&OByxF/:c=HiZu @0vE7xuW׿o[q>,zK1ѧ3~ntkg4|+h-fd E`j@-6>KB-ϯ8/e 7>+Dpa;Ӽa9g{>)ֶ  {;Z8(sх(e;g8ZpLمbT$ ô7@º,ȒXC^1m-L H<|\Q|$K}dzf1Y'\GhXS rtȊŋq9ESڝNR0# C0dS",DdgԨZ\3JVAmK?ѣf1Aj{'AZ$e]e뽰VWPgb3ːL05"&jT'xOPR` `uʹWG}=4U3.sů*lwqE산iLMeHz 7{5IxO3 5vPQ1yk &3qAb<:p%j9wI%gc{cw՝qaF~JhR *Q@{\SMzӯ .mj? vKhIHᑈ(aauYJ$g#XԘ`3dOӶg)PCL[~$!x83ue b3AL9 ds3Wt.-˨F{Εv`N9ƛ"쬎`z>g A?7AC *}; 7_wϗCu Kq4-وzP?,um&O}da,֦lЮ8 ;yJyD}d‚.J]j!xQ0{X>! Fʔ\IɦyL7?@챡>[>i*mbl[0YimHO}vϗ2Ha ꠥ1D͘+2 rLҤԊo, 1IL^$l91I-U=ke ͌/ܚqnKt8 ]7T(JPgxq'p?2q|GUl#lz& dMPt Ω`{ڴyObNk|!wܕ7}&a^.بM:-##O~I:K`dobnjHt}`~#{AĒkowܝ'ȏ`' &6 o%f*xc & (͒6|7CAݗECnl"h㡀,,rޒk\܄X%DR 9&ђsmxUȧeAĜZ#Wo)b0$0;a9 o#f¾|Maо-f KC'ՄwjPJZqxNMgbg@ٔc u;2:7%r1wꐧt(ؘTHQi8 %xfq1$'O]V@iK?])?Iʲ#;ajZÊ{1I;Ft(״$ܺԃSWl56sC%OhQP$$J[%^L 0vUh}bp{R+(D:#/QAf`%!4nkSǷh>y~U֋y'fz1Ir\y;{ vzԑS#d[;>IN]ZKqKZ .vf#jmc*fH>/+;s&SY蟨ЮM M 4Ht TF ;4`UT ttF[ZvS_'ۭ1w %L#73o%Dit@>QvF_zڒ$>YN5-#X5+3Q yCTQ4mDRNog$M5aDV^]AwˏP#G,3Uz,LMЈ~`coUl*`jv|$J96(/\b$A">fJ]f!El>VjO.S2؊^Z'/*NPu3 3'oFbkq$M_맏+/[ ׎B&er/UzESVXL`'萲r1qȯnttKF?6QZ\san;Z8TP/cb؞^\Ii8̅!tF@%cǥtM3G; :"]Z̐~˺NujJFxYϐD?rl[& ՝T)F{#f))sdJɼ*k2e\X1Z$6-rpUw[JZ4*_穻k2-'X6Oy48L[-4Hy_DqfQtLje=5G>a'_7,=88W\+3{^= 10] -Y)06 =SwZѶ& ]Sl[[FpGFVl㮓݋E9ond`m}d /BCkg.98‘$O[hH6S}KUua/K& Luү黵 _+_F_E~wRә(w#VaaϡoMFo:mn, , b{HO,0;w*4eQ>pzAʴi8^xBKz SOeX\nT^-X_:3]8 G\ñ ][e>$o՛h}]ʰco[un">ɧF CLdzm3?y"|>0IG yK%]L짌jyU*"*;=B|65 οPv3ETk=_)%=z եK%Y.!.ʲj06uQ5'>}ρï.g)f` bI/{qT3K~eujM ߵ4I.6 ɬ]H|O[LB)LMdo7b5;Vm#GX3nA̢=J/%摁LubPVQ98ogy``A䷾dDƫ/<_#"c3c'Wdtl<qJo|I>UNx*2+aYYcxxuWcmPqOJ.a BN]Kg$'Aݞɱ'Q CȏU 6]VMsł Y5h]ǧkT6p0wwESOb*߄8Yu#1g.؄אw8L~yU[RMqljT&}d/ngI" -uy%mO>2)~hg\y\Ms54/$} I#ML+nr!yn %Y91^8~1\^%)k]P.w|/x] Ӓѳ =;e-[ WJbRuVUܹO lxI"Qrq/Eۀ_tp*CB"Bj6pI%V\ H"='%|/OFSNrt衯ƅ+iS "IL 55HWzG)'Kފn^qU((p.4bk2E|U\Ilp/Ot®U=}ܠчs2c߾@}a*X VЅ,,υ7fOh Zsy67܎pކ˫{}XQX-l*}IP$ z sI-+' |isR}7Avװc{YAl_<Ó1UMʼnմt9αaK\+*+a%mmUF_w ˰N~_ɟٺsЖK !mKn@!ԦR){m2W5#FBslCk}[NJ?S_3XFjpVEq|1TM9|o* 3HzJ3stIr:LN/`lc 4b)GY0'-o_]|F5v +9MvHBٸ/Ԗ͟9s~s^ңB8 6⥀hNl9⽭p[ݾYV{aCmM(Xhˊ]o7iguXoÕ֍=nشk7lWb=Aw~m>e?; M|`[i׃W'kRweD6I\ثYe^ #ĦxQD}Xg]u@{c"g7M񸘗B Įa@notHa1LlMtl?eɦH3u7%WnSr1Sd/2غ3,,`ȵ+YV[ÕC;ii nD8bD؍+6'v&B.:Kw&'$\@"̇9%6Z#Px %$+ *n5*>ݼCʹ-xzT]CMqwo5GGgu)MS7%LA=Y(9Hty A'KR^A4Ȇ)Q1ڴtpHS49q_I tDlJ2a@*:bg.%y>约W#͂y?s2 މ CHgf`ZacӼZ~nBu;'&m*ݒ`'w4ym$'Uh0*ϫݶxldAjR b \Ա8]wIAӮ ^ONjѮPmH<!I)p,irN~߳'9H%㖘$5 gFa3/(q9'tdrlWgB=/m|4'ڝtYIcl޻%չ>;>Űy$™ Y )B d !D3YŞ>޷CouXa86LTq#tDh8k8is$U8{F`~1q k0B 9M:W) OBC*]KfQ]7CR9(7 cfʆAx=ǣוRyU{l03u*ϓ'|Q//?ׯ_~ӿ/_o闷J)/X_q?~P~,YCɘ?t>cu0?~fGt޵|p*d@YL^?|_~痷 ̗/Sw_?}E_Ƿ/$ QC?Ov /uQ ?/?/ ) F2/D7 :D'L&>߂>]64#M]NC0Kee@_h4!hN[4qڈWye6 2 p bі|x33?3tgjZbQW˴Q{ ?ǞJ Mgd&07_Q*.#aW\񦚥y g|Ҋ&ՐV۳ "s<Å~La?в"vPqBγ٤3P;v9rmn50_v(jb$Qp~=,cW|O/F=LSs )˾; QM۷oYpXxĜii︅\ou~#rgQÉjZ7#.}Bss "d`l,O}0 0u{39%<;8d>jp$*~4JP=.y&J{ְKV(&+ 6Jlg82%?|uSѠ U+lb^0hMaSB l_}K!_Zx~L+39PDf8z״ODiMdriGݐp7uP 覂1KA/6=:c%0\J_60ۜ&l-–Mz|{o=~wDW˭>|]}= L2lQ e3SSu#ͽ"[JuYn7@j :9PlȺ3rnQ3:0 n6(.֠Plpe%O-"~ {?1\W uł7/\A8g8fM TLhӰmEٔӡVі5bdIUmSl͆muw:A9DRg$Ƃllsoq5֬J/}m4UBah,}qt΅ d#fZ8|ܛ~g=b?:\ dV<ܤF r{j[cNOx1.ɭ*׻?ݍnkJj[@G=l`ZK;x Ur̠LJdѿAvFR({Cg _dt(.j['.G۽ N Ǥ Ύ֭MCNx8m7;7-߯U6 1]RT'J7-*>~ۧ9 Ж׋y:3?[98xAG_4^{炞w\rLcs7t:KT׿n Zr8c^qC%!, bXCp (p.9,]iy󶲄v2>؍ 9zCad{Ay;G]D(fQ { w=6vA*Ò3l{E,%6_|$,HBLlb8;ZʹDΈT⍰wV:k8*DI_ 1J8%g_&|SG.-D\Mm :ڊycCzp7+klFB$S ekc֊M,St ܹM{,d`(7ɠwn+e6ÊDKzae+"a:rMWuH]oHhpٓb1/ y0GPaLV=gBfZlhcƥ ;a 7Bv R\Rr$jRt Nݟ:mqi*ɾj(Ě6`+U!m%^:WдQ5ctd-Rugl(ڜ}ǜ#lOO7#j[7.%xCr.4cIKLOω66O(e&y:}AӟH-S\ۉaR8_[2FƘbkO(kL6,/\2Fhp L^?°V78EfȯqXq9 lJ:g)v$zGtxx3oG{EQoďN;Q!cY/c0:EA/}:UMD;Z7h.[rafBpѵVA<_ C飜*lɎL줎HG?q4-j#,S\od;~i\y;i/b'$4uT%#MԙrЈO5+/x4o9|p#ZCCe79| a8hCS2"3O#Oqh zuromoCSmk̐C.u; Kj4Ėb[L푝`"0Y2S Ǩ>J5p>db$t9XꟸC$sB:  G S6[_Ӊ[j?Ǎr=0>66EEQ3z&t!nM &1ik,x6"m :a"+p:S#f@h4%AЕT1xr1u^fv:Z0Ie@BviD>Ws($Tx"n%NZH8Y$-uvTh9|0˂o飅.ex dXHyGG1cqH7$ <~ܨLm<`/8adF`IcMCQ!Em5ɇop:ջ_OJzc:7oek:O&Vgzl9r5DR g當f{FF}uFzaMBnj ,1pQ}| GV[vn7yhu76$6?m3hh.a][6y|x_9!z87Dc[:tLYYc4Xs<8VބJɻґ3T٢p RZس59m IS:A.bm3pj>,m9:# wu=_W eI,>`wWDvm,Hr +ʪ:|週5 *ȗUs;цE؛ (IUxL$N_B1m#r8G:B|3!$1њjH\jrpyhtdڋb׶꓆Ȍt` :l맨.cW>dk%NTUU6&Wͥ]RɬPHz]ȷ\+@!g҉ )RKQBZY*q ?~/xY?cf0wQrf6vu/HM%@ ;Q3g_y&;%FX?vaEoՒWlHh iϡoiOe-w뺀Qjܶ_hx| 3|)/z|uBC`["@CN"^h;`k Z&ƺ4a$6 `>?db'41jhKYIߓ(0lbJkH;TroWt)d$2xIZXZvGf In%[//{뗖%%ٕ6Meɔ p"0 !iRIT/Y%0}@Zĩ'8a;3l{JynIGV #<"zշҕV}֦CZiEY+x!p4Iьi_Q>Jdg7EZ#i ht̤nI!zKa f7tE+h1&S#͔"@\toAxn"*8zGtvFc9 3SHn&\6RˏG6r/`-Fu 0B֍+ӿw A2:a o`]bU:\2@8L zY3ZmL*V(%d'Ėk0SCdAҡγٲHP83ݑs49&ӂ%,|ci+ӧ3*aN .ޥnluy~>e4 A}(6OSC=iYa6TVesXVJtD`f:eg59t9)`Z%6z>`͌sWCB]92a_* hY$xԹ~saMUHbJ.i /&yk EJuFP2|3NBRϖlٱ'qhB'd#oӜn-Aȣ O(UȓOJwt\QMkbf}\ŚV4z]Ҋ[\vSwAz8Uò 9/P1?UqW 70QRVLV$&+v+I/ab[zPdmE߹,""+2ĘHf4w/sg9AXNVfGSTGi̩ ФߍRPMmލ.ݒO]&/lJ8@׹zŵyGE8o  Eg2''6ٳT]tmsxOƙjqHҗtM˿nh3LI}c\^@=t\dUy% q od=B1g2t>p뀽]gA0zǂ- tpʚ4+T{&z~7da})Iѥ'W\s̈́LO4h)f!5 Y4Ek/s&B1rϮY"TOϏ u)c}r >uP14N.j>k¢$ XTiHJFw*<_~΂b LٷzKߋFz,hgo:@-, }ҒW|Nm.=-/L͗ vIW+&(Gڢ*C)l[fib!(]NƱKiQ(~3KS'2"w2QYʾeX|y_bl}3H3;"VFQ[]5tкn{ݘ_ѡ\&pc)f?U#ֻh(BgQ)j*N8W5vc! Kl#SqT--\L;\d]1VE]wnQ*v9ĭHu`TxD)Y9%/GѼ {2tg->)1,Ųbx#wieQnkxƒfzpd52~-.Д?^7X/R[%CnCkNKR>-7ӏ{h4fxr}h ١O r\r-ZxZ$"IgAcV`jy ]k?m5~![U\xϠ$8].gFO.)vy͠=+4K&xB|FrX톸)\E,O%^'!Z>|<g{?D^4#xDu3BRpl|@t7Icq[-üГ~c;!OACp,@|Ꞔ:8"5.nlh<FwB^yxXq9ί.72l!ũ|x(AW?\Iyߞ,b8b2 T(,g0?/gp=E Ю|k'%@i1@nt#{`+}x]Z<LEW^gz2 c>э7h6u`]jt/N'y|Vv.L"[a[ \uEͱ P"29:"A >ɮ(CSijQޖC%Jƛ"lE>}),y= bb:|> P:74PUt@Tgtݺi"[49ydaBrVQOv ,_gٗ]zpkb 9-P0 Gobw)aMrp)l͕\Ė^pת4F Zz!? 5ʷ x{-(g%>k5#.D~BL^+Lŧdž Qk: GN0UcɻK.'QCXדnB\xVA5`;VK*w*|pb|JpD?{t67£ WX`S9&-ā:c<'4 {r(+=#F|3w?&Z\!,i):mԢȄ5ؗd_ {+wlٖԹǟ aͰbPUv?2j٨jPסrw :@]퇵B~۬@I_4K2pu>om:]U…;`NQ}͎v7|jU=Nn`but6gO٪K؇zm\ɕ&&*ݙxInE V2' 悎d1ޤ(, )撌M>ti1"Cu!݁) I,<ǿÊNRUx~I ֙?}F8IGp r3K^zf+ 7̟Z?TSBouoz8Qcg%] a-?1yd:'~^T,P̨-8CD[c jHʤxʸ2q*UbXfݓ3>8!c NuPkc9 %~2b_žz]hwJc˖4MuZn"[#wVњ3io_9/tH9ML^X+8nIˌ*;)]x -][k@鴠 |,~PDg^ԚcozCKO`Z7kHKS'&ȴh'gnk;g yp~uڕάLa*dt8rHBn{ )0~&0f |u9|Clلp5*%Mn_[Վ9*pQB ֢Pg\1~tZ$)E-,GX)Q/g;zuw#̃Q1nb_ٗ-N1Դ4o<<[{iz9S}[3ڙN _&[hZ'TGkWsY=y6zCLeKg-XNnC \}\]+Gŭ>C*| umNs 't#wl5lЋ$W%֝Mf;MJGg1zcRn!֯=svoqCbir~/8)yiGmz.Zm6/.l 6śnP'4Igs57G`RDc͛331Ǵכ@Z{ɨǶ>T ٧\0ih` ,֡OI\qeRb]ۯc=][sXr  A䬚9Q^+If׶Bk]wCK`vcC5sꌞ;3{NlKt e};r :0)S}g~`j톞JnYD[X>+H&K{FqҺ[~C59t)H}^EFjagEbcv$ȉK:R]ƕ˔[;cVbQޙ!Һ>UW[ ~-u8PJjWw蝣~6Pc>fJ >R|$C_ƲHnjhXu)Kˆ8|ŎD"bҦO;ibހd0l "F: ^mxٌ:c3F.l>^-|- cAS Z!d;ߋc u6۠k:gcndЁn0VkȽmpkXm53O]B_sa`_涏YLUI:j\WG.+zt`d{V;Yt lIǼE{HV0X3btStOhNnmRЦ:J4՘{L%)3L  8I'Ըcjmk3*)j!89w~U~gI vNk #-ݕ3'R߄LRz"i@ X5]ff2&ܸH{tkSJqf"`- ZfӨv*A/L,b­T6BS5}a]!DG"h.[7^ A/KC;ըzAo gc;,@fсnH-4\ {P԰C|֤Fv;v5v V|e ^=?x#BCF-}˒d:-4Z-5j)q4xp<78UW͈bp_ǏzW?Os~]w=~m{ g=:YS<}} ͩ8:x}xM>t_o뗏_>_RJ9_ۿFK?~߿||ԟVB~۟W/NU|T:cW#n̆Mb y}F_:LV:vp;@8 3S^y\ݹ;`J#cCLQ+f<HvڜX;[)Y,T4W_^];j޾oV@Z5Wi3 no_Θ_q|1KKȉ5uML6,ZfIS{vuڔgLoںl}VlUS`Us;+c߰% "pO4"gdOmC5D\7_AX,Wa?_^Seko ǻ_|+^3%]a~Tӗ%ЄaT 4lxqڠ,~|t5'!e@Ɛ͸W`]Ǎ*nFyʳrsB>۳z;PY=>MoKq5 &CKKVrц/& ʯ=+mM(Vcrd|M 5->ڤ#N65H'_Y ROXX[?]4X ,˳&?N'}ւ AB+|IKdm7}=\jؓ9!pAzщn3gnnTzPj2v5z^[#c vCMOlP$|, 1a~BHcQG/ؠ%bw.ͮ6eNGW#! "8Z9)mzlN["'פ>]{uF2&N1f$qxgW3PNaqM|^50`t9-s?.(Ncz7E4Ҍ` k0gcS LSn"c}.+(/]s?gbs$\3Iۤ1d[.n%=ע%{~|5Pk! kak fk/^;09H=5XG5ٲkz)F1˅ >kGPEK%]ˀTM3]c|q*1Yl T匓c[0qjFt|frlsK`ӗZl@XC&W^&X>뻒0 b"&Grc?~Xc]%TR)Crb~h̀ަh:[,xqZqb4Q-N$5 |\N$9a~Ȕj!Oל3SM9·k?5OZfkZmu"0HbG% rֽ!c y i[$>Ye1kzҮ9_ Shtd~k_G"IPzE4R>ɿ!Z_Dø IYr[! -$G>6=48RY=f s-`̿$GhW=h& c!@PYehZzg̷Is[B-/8l&#Dmءm=8RP=(xx.Q;OcOksqS ٮ~\ڵ8C)U>Ҋ{jOJ 9\b޺EQY6m]LFfqi 19i֍'tXp,O0U;Wc"DYv 3kaXTy!9-Nt+1/BKT7kX)Sl%|,g힄&x9{ә˥F4cʨ`V gWNdLFzh6R:[ZbyR˰]4!|!HV1GQpY>;u="v|)X|g1~yćJF$M~{16d3q艙 ('_r9ؠ񘥁 d` ۶q p6M:0{{ɗ}0*8n0]k`xp=?쬱 T83-GrC&]RuI"Hr ]`E&w'fur@։=ldh3X]VJWֺFK1 ƍ9s~*6\-鐭s5A9ttx>~}^VլRf(<"X1m$FHmǶiyO{ujL+ n'9$`Ce4'\=i4gnES~gvb[@uQQJ_{P'jY̎g %T{ZihJLse4?*b'%|!E-|϶x/CIX" _EM,Zaw8eWT]6ܠ[5Y0 ;CeEk|1uAtf:X3͐=0`Gp~2!3\%̤^=L)9zAwT侮([uFmLc+Uwߧ⡉B;/u)EH xLNWߧr39NU]LP"K8biNrt5FC@£M=Ia zU[_S8б2tnd#Q],r6ɼCű6 ;im]Nov]#F{zÅ?+CCQ?;󢷪ו_xibITvciTe@,^Ly9êY\y+vM[Y rȓob6(+V7`9eC.Z]i`Oz1xFO>LޱmS11Q]jv};[eB;G-4" wއq9$٨I|%>dG6!+tsSۓtIasTJ5<vvPt2Qva+2Cg1Tu7e@)D-$HwJl"gө?Bk2?CRQ$:@ęcփ_dy%QH9?p e{1~]$5(ǗW4E1MF]@PL̹P5&120*AVqʎ̈́ѣ*1Z;/HeͺKa&/o.{N3v& ܬ&J΁ ,dUGyd<)b"+5_X$kQ[*lLiv!N{L$}ܸ4s5sղQ3jJ9٩lV4DOL+[yLFB/&Zrq r΋q H݅ҁ,v@ rEc??3LqF'ӐRmnڦ[T7y/`TawNڍU yɂ}oH)0MKJʣxFƄ XGfF(c5e.լ|N[vZs\}0-^)DA4 %j~m'ɞTmQ,b>8ܕ}NuCǵ9DyF>y]}9ymON;Qj;Q%{ז>=l %QLg?=T9xW}:dA-~躲~E+q,"GKBeL n cV*RH ױFm=%Sx@s4@ zF5z3$HR; |#TXxmRlS+6Mpj`RHF`zCZʆTleY"k Mr?-LE L jSg:oĒf"iVU/86:9(7Nَ2EPL[*\^knere%:]B"PO lw{e+G\ڤ1݆h(u jĸTrft&c|voTIMX~ϕ7i1mַQJs?=U%ݖb˩bo%d;1fc±egJ|@8RRN-m8=9m6 Jh+euoC(:E o>l /j],޻1ͤ3!#ϸ3VGi7†mw/ ޾,8[)$g@~\e c[9v6Zc|as3הHt+ >t,ܰ4ġ`BCsՅ^UyP9n8ۭVfR-u BQ] uPMf>X$IvW!8`4^'mTum6m4Kk4BzG[hgbT}TAg-,ms;u- {~̠]el]8i8 @7hK2!SZFESسL9y7rD{]ʈF5[lG˧ή?+n2!` KWvO@B&]Lbz2Ra0|;n9xR'z&Ϧ)[qiBuE 7yw@R_S=_myHU)Cit?bzd%J/ln߹inh{'ܑ="ݞa>e'إ]>κXS>ͱ":M % ԡXzk]=!BM f{iDxOhƤzpR4uwlSΎVuv9庸AՇ[;]:Rҧp~/Qb\k?Sw3b\hzgq dz|Rk9uG:l50[`k\}hK6o۵9 [5}M"\U͟h(pfnQv 8TĢ&x>&=]\G~"}Ǩv%Dx'O/,9o5(X29Y- Rfcԟ-&]}]!r#WcwJ%t> Mh6 W4[uoK"){{KyREL [ {-o[ꝰ)jOO껆k'*m֠kݧFLEўry-|JKEu" mrdk~8J-q]4j&tfZC'-BSL0K^ 즃d>l1q<<CA+~M:;+|}u}kfmֻh;G匥$\aH~rWJ Sb>[JpF2ȯ8U(k0rd@2|xOx1E. AǁaƮOɈF+Vi_[Q7Dis5j+ WV$]>u^4 m/Q%z$=%yTÄM}~0vFKi WxKSM>NT}o\V DRu"O,0fOe[A_9CZp<4dBӬav~| ޚtD(Zs0 %$pR+ӕفH@HUIŶ}%j۠bҭ"1Nj྘9LI<+6lpւUҜ'v"2`38) >:ReLF9}mvԾJK?]]z^W*c=f:y6 1+CImJ: 5ƆnY([՘T{)z3`BM?{IJ֯Ⱥnbƈ)_IR pntgbw 5# ֌Ws͌Ǭ~458(tp˰+Fik`aa׋;B3xLv޻܆`?Ǝemr,gJ1|_K$%Xޢбe.5#V=}L}n ]!)gKzñkNnCR \&w': e @9&^<Ǘ:Ъ㷯PhDB1ueyyk5f$d"m@Ž8}mn Qj1w] dAduR;Dn,;ݰnrEn1Zz\qrt  {b9(^j)jSc ϫa1ΊIgb,n#DV%=DSGgͼ۝@t%!N"E[Bg`u;ds\ a4)ʗIrb1'!gm_hB5zd\SCi#@@Z(^ .]ǸYKcj uEMm=GYIҗ@F}M}$uJ3h`a `ےն,\KQWGm瑢b7̥zkn3ؾl]oۍG_|)ܮ`lShŭW-W@ /3z gDy 'wܩ(~מcڮm:~1jxo)TD*(~vg;~{ڌqd/{C'4f0Vxg g@DmQޣK縪e#gV dib=y>ڠ 2gZS|Ц:5]^ݝFG:O:?$BXs3NH̗г_4PX@Уe",+mD=kX}B^DĈ\bj(4Rݮ kgmFW^Dom|i`rS9 N*F"B9.jG .j$pր뮆S] fZvWT)OɷTdsTRɹpb ߳}dϜ${3a0IU:a=QՅWQY؂bpuƣ(.61hQ3,V#a4bÁp;IhJh4LK9wVE{߭cK/7]ց Y/7k^iTHN$Rb1N{Y#86BlB9CaUn_\r$s ba 4=5aʏUchGVo zq cS.R[@jM'jǻ Mdk|,G9F}З8%P -/NC1P.Rƻ}AS_:{ wV%"qBv,OZ"ҵ1 c)֚P=ѫc79) 9|\Z0k!8]S D)dm;^0{ w}֛4I&ztMҴt*O-h |RNecsR.HҊה҉eybEX9ХqsN&pϱJ$dLvq.5q>Җ׆EHu |f\]H\|zjx KIݑӈp֙L6\k>ʩwn6&<͖.ʼbx_&tnaIϪZ'")OsםR6Q;ޘ{ $öiL73!Ę :VztUl<hF2M}3хaz3 S\ ;v KΖL!O]uSPK}4}8MX[LJm5A+6LoO7J,j䬾?ĊfXH L7›0Lݳmctmf/a:H `گ8L<VҴ:%߳cUt]@'boeӦ.(b k$))נ0J55NkW*̂M]Agדϑ_>p3!9 L產::֍};.:9x8I 'wVBzU Hz#'$%vb=D_:y&qGֽAyte F03p迂JծG֨׳NLXٓ%vQLzL1acu'u﫴˪ ,ڶ'"g.KJ81Ϻ:LeNBRXqvȰ$i;g"ܑ 2J2HjŶ_i]E4PfF C+F i~{R\;pN7OC&2'.J%ԽM'oUw#̨ e9dA2χb'?~[gS@=24QB0?lr6F<9vIFgsFR'vLev;BeR%:q|JC}Oes|!("#9?'5ע6 $ \iDzQؓ =6cB}k64|Hr*&RQf3+þk= }A8[Z:pwc|: љBAζ 1/ge=QUHc1D[ࢆ.a[q:hs&W)`d/Wq ga׀zmVx AU*:"&uƷO' vby碏ojI"Fd9oCᤳ۠2(:l޾}|dk(,:MlJ 3%@Y$wKgeװq-QJ r@BYyBx/s˶^)maU ir>]tG\n*2L_(-c.&Qd^f:^؝Z5Va󿣪t. Mאּ;c_؟ABC)]˒\7r]"2[\tpdi,Yho{7^H&fSCEUɓ!މ?7{ߟ!u7gҦg&>s=3=<wF-w?R['Axӻw2_|y/Az飴O{嗿<=_~Q|!߾G1)>_ǟO~zyz痟?5٧;ջ/?ˏ)ES9ҟ@N..!GHNiiD(.h;^LB[{g6O?B..v~~6`x:vJe삋v1INj*=↡5Q]INHet5qh u$mFPRK9"y# Ae.('p1u~<_ގX\%3d|&l0TMcm=Eo ^;ג7aU}PJJpm7dە.^2Dh x0~i6%(W߁vixn2Uuq=Q]~߳i l ϣO~K1 ?gao,۰maȟ''\"vA`DDyah1 ۑf23CZZ}F~#ҲUFRݐVEsO9d`ܙ-tDX9HԤYg@> bRmR^V?eeq1F6px79gT ]|70ފ49v·A.7\11rP= r63NiT ]\t5SeirD|M=^.Y_rmj\z6j P@_X7ӫɠ;O}?S/82PU[M3ڹ[Lwus;>TBC GCvDYL(04%2M[B ԋ) 8A$tD ҫO9$=,*3dr4 hesgt4_I R%}¾$NVg,{)@ۓ4JGFڢN1ù$;0n͚CkHw$yf-Q H꿅>0',gg&= EhkJq"Z륳Șwy2OtxdQt[L)ip<ȜcE6E 觉<6H&R%`e\Xx齷>s/@> qt=}'!W|ѹMpY&8 ftã5ALΫMi0WB1r;cg}6:af4ly&A$.!eH!AGp\FXeˠO+Ӫ闅Ŝ]{18SMOo3:p@TfFh7!9\Zڈ\Dh-D Tq7]|됚#[PȐfjJL*D4+^œ˃ۯ)2-gxyq73{Rk0 5ɑPC15qRj v%;ҙ.&сj%qPEVIJʽ9J%=ý^C=rLr _0i MfƁT18y8V@mdH8cBdGR"fV5TLg?s RV9 p]ҭqft;5;$% 1q̓.96d+4o PE#ӌ.S'VsPg0WdwN|߅AQHMk)ƗᲞ!lwnS`k 7?U:Ubo?۵oEUQֿż TXg/'x#)YvT`*k ι~zԡ @-ҋg Y}]ʡ4`MJ6W`np5 v9usmܭp(#\jB( !5*!ei%uhA/zϪRy\E`2>q,jӺk {)3HsmcV 6>IdrA= LT l %ڢR$&|7`K^>zA9t?OzrFvb (7#ܖJ7R7!RDRvPJ40 X&k p"Uc}AhPo5abig4PDΪ|p(3mb@5Yꃁ^xFěܰ4^rgYjNUʭ蝀lJXܼE"aOˀ!Л:3*5Jg4MtE+p2[QZ9۩s3R+~Bjwѩ5JhԦj\n`nz*^ryK`U\lRy#uft`LXFtoWwsp^bh55T" TXp;%mm,Uj e1D`]0rE"s2(<'Е2ޛ碑Y3A[Δ70r1juR緦ǒ]Ͳ=Krp: P 6EZ_E gnJ)$N De0N\;M|JїnzeSDm3T&qs\7 e";h3K5RGzfˊ[L?'좥ޫ86G+;9=I<o ~G,;k|uz.?_hD3K75xzڵE9J7_d99T6@>R@ߎl &w vd͎׍Y}dizXm;D6d$eKvY!S-}'ʅ&PfAtA.:bGﵙYcW%LCIasBiPtuCO`~0/_UTV:F YdčIЂC׬C1jASGM%Qc8Jd(+9sAީ>>R2އ7* :Gb !5/#=/pY$Ô(Lga6*Nnkp5"y ;f p$2\^yL[5W&G?x4v=d;$[wY6Cj,~烤 -Ӕ1Lq|-\ǖV:EFX\l^rT!x{ &BY 1IRi ]Zxq ߩNė۰l; s&~; *9V*YԎJI?c1B\I3ShW]B!RHq6MO gk`U\㴦gg=hl/IgL)qa=z\•,q8Τq+@*#̂nVW B[ D(5k+l9X,wxMyg㩚BsH&T_h*EI0&ةO?P[UBc.G+{y X`6B߹QC`kB zqvF22n$ش~ʼnRbN8y$s}G:.ph{³*_}pJ$goɇwS&')DN2HDsIݮ|~8fbQX,lVv|?NYƏ) XuΘE4cK`cNߤղg-%֛a-r8Nq5KJ\1["CᵁRQ7I*17ʄ\^)Umxѫ,Jb55lZ& TUb1 %cNCsmB7J` JD͡;4?L>V0JA8mBp s-ǒBDr*ؘ$XV;hY4C\pvZF7lY'F'2EVq; q!TYEiKQUqEҜ(9ܘ`еû];ߜrGOYU.3~tc yX^/2Fk˝3; )`|Y th{$X+;AKeGAکn[:7i[89 qm'.^,ASm`#,==0e)oTE ;Ih.xC76ł#P&`-"sw]k%WN&u W/KjN;~)C?Kv3K'Z2G !ᏞZU/A%k:,}{%NNy!*ntKMtNۇ9.A!JQa~{)}\7m֌ C̵m.y >s\fbIjnM__\+/B:eCD&sZVN]ED/flMf',eD,&TepEWG#r>hBXb 5{mQ y5Uqp[DiʧKiYv%dd*\5SҦ +ӡE QVmhSɉQ>IC>hn(浼5O[й]瓈A0 D.~HRcmXLDk^R7D/"/^lgJ4kF%6Sz:h랼53n[]JFOp"LW>TVԳ%t}0uJ'խk=Q[/wҫuѧ*rk|Qɺ?TB}ue3nTqڞPe:``Uycy8J׆BP[p4-\~trIes`KGoUoǑҷMM쮂PO̷ë*J⧟iB8QxmPf!bp)7=!v)սo6D30-r@ mwimN4\isgmރsZ WI.E_>2`Ht遾@Gי X,h!% P_ѿ[ RIj'g+oeޫ;Z;7ONzK&ƍ2zpy$iWWG8)ݔܑ*ٸ6,H=ѵ Zo,/>D 8~\z)]:Y& 74 1k徒R(-z *PWq*:i<jnpB_Aֽ8Bk:H ^Fl ۵:_zEE<(&v:8/akr) ݘQ>r:Ltbb.EFqNBt䊭r{tڏ|Qe"D)\͟) GC=7ƩQI@H6ij>mgu|rHT?xi; iڋHfFR=ՎIդLJh4Dip2{!pY9ͮ[zfS@|<}2 oya2vB94}/^{>/ɽ9STSmSVՌIL5I0Y҂1ū mU`oݍsIApZCч6y vYKDd.- ? d1cowv0Bqp`,W4JbzP^wFlYmMAB]imy>xeEUN"̘xFoƈڏ&E70n dY`|OA\|[phIn+*>T0&NG5j6N^8Yr!4 ߭9Mʱ|\9cN6>SUak$u"bL vVeËC1;½A o"-4ʲܴZgYjmx98LPt`cڋrz";v9)3~Wb%.u 1 />X;tܢpː;mUgC1EOۑk'ydUʂU0^HF{Z(8gC UbTv3WH8}*$mdgZQ̦naA`0{[z)J@1%FN+TDzf`Y}*k֪uJg uuVK<.,&\lY"t.0I >z^ PBxbSKy{)+jn0 5ND虘XXZfb2Y3(tex5eNUXx2,2S΋ʘZ sBG.uռ|v :m9!1xi Ĝt{% O?cuÖ-Fp4`'ۺ|P&c񵮅`3B:vѠj(rT>~fB![1Ľel[768Č+.H3x.rZ'Fے ,ςߩV͒g$}Z; 2GX]P ǙްGUW&KǬY=U Dk4ckUM^_l3YaFZ, P|amgІ é&Ңŗ -;q>2?3YPg"CjWVP(*~"HZ\+&#.zc5E[U *u``UqTinU4t^gϛמ/lP(QBYn{U6υ* ,SlXa҃AC!'A<0Fk v܅ߍ6)A|eGmy9yf;bl.#Y2[ *=+UuM~ Vullyt9WnʰXޢ1뵺=ÇmM P@goeQu硋싰sOD~eUluN i~m BYX97,m1șe!jОTC -vU[a ; uaV8BC#]Ms$=kˌGEݻcwZm>G& 2A&TKh]ժ'OQ__~÷ O'~1GxDG>!iŸ(|=suGhΠ/߾=|KB=?:?!8_^s%~}˧o?_Ͽ_߾o/;__w0Cܿ:~,/9##43,@B+¨ V^+E/i!"Z_ m`8 C~ bQW  )@_Sppa{f#. :EpN"vN J6 ڷR(Qq|qPD|SLG8dcQ8`;|Ѻ١ 8dVDM cRr5#PR۰].`(L5GYD3j< ?_' K'ZfU=.YGU8F$bkkUAo@XZEh"j'=}8RR܆7󧗩Mn7jߑ=Z}v›U G% ux<;+>t $>;^?M2PYES}7=B;fs>{:[7ٓx ȑ7贓2?Ƌ^iy(GcS> v.[Ēez ʞX_|/]TcC^8t>g?>ùgzb _< GGH3l>^q nM"pN G[i9NX#&"(C3 &^k܁5Jƨ+y5; ?ZU=t.AwJi1w; $Azc-clI0=<ް2|"r<1H2 M :̧ y+ P\f hN9$ Cg)& , z A''w7۰$c.Չk‗OB-=6 \ =qGi.bW..ݡIҟ#9!:dmQ QA1.BNh[/KK>_݉L&KbJ8|pwvGQ"D*fhtTon',8ŮT4Ƅk>E<[_\fmXt>M5<ΙC";2.X9?p|؁`k2APXz&;`fbi32v},җnF6×\ZWXkpث0 V8Hٴj?.xXu^sj~0 ^]obf!jxwmαtΥ;~%&;:er_J{n&x |>+(Çvv$fG`x+䲡{]z3UI2\4Z ߹SlMs, ;Q.ޛ%M;9gnuV!v3UNJq"1(ajQSzI!,R:+]TuWC *sR`.CʘU|GBI&எ[:W%s,-o \[H+ed'wףTȄ NDA#wE1(o֨bcLt"Mh%*봇4e#Q*X M:1y]IY4G-Mכy hvsQ8N9P7(4.mZA#5ezgj-xv,x4aFf?䘅p\(̅u'Q Ɲp^v H/U4M<:Fפw{*c'0];#FBRoV\J<n .g' b*NN7 GJ/{.(vA| %>&55v09RXB[Z[`Z.Ր.CBA ɟg#L%fHDX#scTW); p3,**;5.zu]jtv hhJv-W@bhï{V9Wƨp>' 0Lϋ5f po!<@K$_~f %j2:|z.0!rޣsԐk԰ًgYۆݰ֮Rۮxag.=}MI V^;gY3~jǬ 5|;?P'%QUd]jr(']{ΚȺ2)`T 3<݇j !"m$t÷ XlH=,d{0"-L$0&K>q$nRg3-VLꎸ7G`Y_w>ga(O+Gi1c8ʖ )GY?-n8Ud.C64|tԲdh4VI1#ֹ`r$_#8k/F C=$y;#_ /@-y>iu<YvP)agTOJhMq>~wOϬkGa ;jnz5덜q!!qFhqmz_,gi (#:ZNh#/E\RuSIc{]6vΕx^iW3~H'O3643BQz[)4JJv3ތ3U)vF]r z)c!I#O e9rٵϷ~iӚOW"W"t;3oۓ}\m У~%lfa 5!PÚz1jRd뛓E-BL|Tjy3$oǿL]MR7 bpoC4t6M]ldpxn;~{<4!0 }"n*A5cJ^Sm@PRsPԢڼ{Va[)}L5|l/q: & 9=fuԾG,$V"6Ĵ{7U5!x1øJՏxTD|6< HP1E4^{aRV@#BK{AT]Ip;+<ez9? pj۲50:tL77*TZV&aCevn3 *XIB`E'mɴ‚!lN67-|)+i;؊E{}$7Ň*ͻ(}Օ[n$/ܵ5i{ 5 t jnMΏD2iF%2 "ǍdXBI)sDjCC4s9n){<3?QgϚ8#yּ>2$D[պ@1譺At}wJnd+4CLf2"q=buS\#P C<N`KlCmM"_@4thUʪQYY9G(/gLUj" h]exޑ)$%]NDjNdƓU`XGAɕyv$meF4X2 7 VmIZr/uKliؒ0V 38M4u 6qث/p&m m W@it!'cD#Q]!UmG ̈6#dE#,BҪ- *M\5j%VZL>-Z,y ˩l֟atN>5;ƃ->\љ#={f,D#jx$k6ʎ 2k׾+/bέ2tݫMuCmP ffV .X۹o*eHL/Z¾&jpkb!j9I.l*{fu8s|mA ҡDʰ~VͧhBn\Qb-u3'uc&o4t}t1/K)B-{ԭoFErzX)t{zB-9ƭ[l,}[?X9292n4GHfS:ovP!aM3Il5<"@YFw dDžk'(s=Y5$>I>ɻ_fS5-8Z|YF]p;bW6T{H7+O\,8>Fy†;E;-[6\Qg}Fۖd3qԞwl3oof(I_2U;7-kۋGnVx,K |mpfU"]UȾhl%5 ԫpNs9|DQ7^dDL%c;Б .|f7/\SQ R&fo=Q! ɞқNƍg,hO, :rr,n_J3TeΖ?vXa>~'P|HndVid0w1-j>Ӡil0Jؐuz~q-S>E%1;||Ado3Х}RKt\K,H8ja ݧŖ0m4#1P|%{miK@2  ЋnϢT5G=/ ))/!nXS_b!xJ}- Hren>l*V2KVr -Yv8LEUNlmpzھDm ciݡN4V>T -)~f H(QLk ƱQg7ǖѹ`f VEZb6-]wlj0eB5 IX!SBn?Sٰr8]$¾vF^,Y,Yu8th{@Ef]%8Z8xBV]NIw pnbZg^y%^gӛخZO! gjμ˶ sW yoqI8տ(vK$M8q=ÑO]p3V\t2؍q ۧu~4ffmdq\]qٱ1Yֺ}ѩl=P./o _ GbtO]-u)/}p{xhؐw啊4Al "TA̲r.xo4\Kt|K[Xȶ[KhÛXTRÃs [h۱B0NwCLd%9{ND"K}@e&ʪ9q0!-Cކ}Ptgw3E95f:-zjS?=$"frl0pwUՐ\aT 2w=k$NeDwV.<>"o.A!fmp*3Q]'^i?Q<>|+Rq*-76}A1mj8cWʽ;W6nJ~ مN1R9pu%#ppؠg1gmc}U:j`5gb!k,,wp'=r0э$`b76T+oA`"e϶ʜ4s//̔JgKlDV!&iLa@qD Pmt>^O,\y+WR3 jn/Qz̭\0h= fҀX:TȊ^ygtO4wVV\=ews*]J.,"gi<xu8Y̤t0%na]%I;$g[ˑb\h:Yyt8j?6 cT?)_i|ĘUi}n(^kv}f۾7ٶzZT5}VT}ܸ0[#8obT}9VȦMgFaP-e m5ͥW(XfCU8/$NfK^lĄ]:zZ_P :mjU(g󊱱iS(poS{kPk$m#H5|Oewr!%e'M (J̱^4;GWMyam+g.m A/ZփqBta0rq4\bHe\:8-m#hF(m/O1k;iZnbCՈph.9%Vۀl:<B|Pۦu5F;f5B <`5C_NIG뱺MMoq1e%nC nӳe]V'M>7V$ޮv~˻{؄6ݫmykV^sU9QH58m~e![8اsaA `NN.1BbeQV5x#N׀/9r{2IH$+tSK W(;a,8fL'Nփ/`$'>WA |Se)!θkqPHC1a3|^?uk-S>+ܓTы T=ǩ5dlԀdʙ!iTJ93,<Ԅ8ɞ̑ >{{]Dft!VނMG  -4Bߺң%u‹>&f7Ў]WJm}]֣/ φ_\p`H9E[-81,d9: n{p/`ೠm%pr 4Np߻UWHDLkE)Odzg$>fr@Lѥg0Y3Ы"gWZ6 cL)-;p(8Ra'*y~jS g0%;, |׵U?XZחWL)C0y~]Tcq) NkCyL?J5juF:{]-YKs*tXכ5Cv695>]h "Vo.OqɈ+ke n.3z>a+Ӧ E+r7h_̯XV|:Ie}CVb!Pjn)hFrɷ}vvPlk5(g6ӎT3]◕%w|C/T7}c/s U@<.$R[_M;;l.6h5,n _MϲvN~ 2ډn24~WP;ڪeBCV+}Is$qoi = XM?f%JDtՏoUeC _yB_"_B}}۟~?7~g-/}{v? ~>q_?Oן{#'#RO_>>?A|Ÿ_3ןwrJE_Oۿ~ l55!X1wxi`e§oP!~^Iƭۿ~[\G,"!#Y_gAkA 7ap\@· 9-$U1PkB(&hgQ5XNcw~"MT-u:>~筱>ٓ)~?.xVLdC$fhoO^li;d.;1ib&!"A\_G?#?F+Y2hiDDm8n+d׊`V K M%tʆh8ksd BqʹhUZm;!:j\:v&S &Y oTGewf'M&䡍z-+πog6ȠvJEqK,32: `ʐ쟒!W\C3>CDڠoԊ;tf7!fO~^lc*mL$:.s?s~n<\S4Z&x>D nAěONNdu">Z %TC֤җ_~-?XT<]T("Dn-}KJ :&@m iI9[d1vҦ,kEe,Jӿ\$eR~ 7;3.=wL,o*Z~\lck0![ c/76 V6魑Y[fJ Gp0tq]P|%nP3DNNK 6Z4u.63%)֯:A1chckGܨI@$r{PB"TD$!@jCMfwaLN)OQ](sS>$4nET>ȡ ɾ)(Оa!iS*V8[#S SAڦ 뒤$ټjr8q*6a,ai'~=2%NX49h( t(I@$hL44.5piԮi,gnvҽ#sZn0YMß?7Yc=- :jS ېSA8a%wBM [ V<96N5*=x"dƬ׀"E8Kf](ܤ-];l8M\89ŎF)DsdXF3xb| (n֟_pdf.h#)FYM5:cVTd;}j̡EaѴzHTưiL)*b)zjnpfuG2$Ҿkfy$aJ'^c-(s&Q0dպrxBu*f4|?A|kҭ:?ʷeG#cIܬ\όdz [:5TT{ڗ?%L"-QH*ؔGoY`PS4BS< Bx9sVxDw!5%L$uRVKcN"N+3p!DRfh2?T=:y_\P=Qa1_ƳIMQtG׬R)9\8&} -z^քhD2K>jXKYDcw.`~|sfJ/R` R}-8b.fU 7o Nm^u"u9Ť#M. 5]$12tY?=iT!~R9I2[b "aJ39C$5lV>3sQ$S"ZQ8vo cLs%U|t/uԻ]mĨ=;HY7))rF{]2y>RehEҞQ?V^XK,u&djŒ~|?0V02E#N`h!neNUmt>O9Ê{^тS'FVg #гJ^ ڨ)y5AwTAT_IFIϠ,t0*y Ibu=;N9 ?3SXR# 1.WD6;I 0,-2X S!%+Fٰ J ѳM kGu:4\,R3I҂Ĥ"ShMl(.FJq q1XK#RHI [`+KڒRϰFwEp)A:I3;1T#xaxx.uM0j?%eڐxPx%!7 /LǪݥiMjsA_a3e-Cu#w&4`m9).r$Lz$}W38EX9Tĸ%[kl"2ȥmjdXئ肵VϵH*$4WOa[MSS9|y%`d\p}Pg?<| Ưq%2KC!jR.km6H.Wv&Y+)SO8{5|`;>^M/4.#A31&\"F 9 846:&r1؏s_l<#`S+f;Wl* RZz+/Vd.5W"FMzFL *w6Q9P02MnݥD e 5/D?_vΗSoz Hf)dL tiJb6Ќl9ʅkk\[ܛVdg>"h^hv5,Sף)>Z+=q6q U(0bNzFdϣ5;ksY4abXN:ʹKLs6\'w?2{5G2av?G%p6)Kçqb3ƦA*<`r#xE&L(%5$|cnsera+tG#%B'R=bZBc}nZnx/n'Vjb#rTJ>2h-.q-dXu[ ũ*gF "Ƞ@,-%(m& =h1kQtr/kҫSS`l BZE϶]Z^w<=AXb]Nޕ2++FFEa5"Dxt,5;W63+%=L>*MU8ښ i< 2xmZj$f%q R+·ITRQ(td=!`$tUB"amHrt>exbM:9G7X”O ̦Jpҳ ]Mz҅.dk}]>L/=NYLYӸ"ۉNkV*B ^JoVv'!j{c'¾M= T}=]+4;1Js[FIW mGODaaM F2ۄDt1We󂾜:Qjk?-T1L}'>ڲA290{($CGԋK.p0i38&p(J;=`9-%7K.]Lh)ت ^P_T3INqi6< U~Χfc2\j}r+ANJXG@ :5q=HGMVœ ae M/ nVrh+mJQ(9Q(cVll/˚CQT f8)em7;QqGt JZUCA]?<̟mϬsWkW}-WՊíBK)<&߫,P*lw>lء*SVחS3a[+24#,Α'!06.KnQakhӁM.,a68&7N|%0H &l}H간E.7GN)uvf4l h)~ H(,פOm?ȎBulm8MEeM ۾?T郎H o,s)>r9P-yķM P-n!D(Jjb)VRSF DH%SLrxwF򼁝/ i^^;CYBQ30mQ`h%mLގ+5js{n9L=17蠁7 iA%Ү@Lt ;r .p1lX(" Kte-L}CI=O9!Y-焳x`98(bZїw)0dվpL 572E+ܩK{y{̌Lf.R.^50rTpgF,ޖeZGϐaӥ*:29Y9]xD1=Op>4|0ɜý;ƻ-jL !Bג!9h$Obd$b!0,$ Jr$ӹ~;g&;벝 F9m3cj]z)^'iO=VC۱C/^s˺M1^lx{˘K% AtӸu!7#<JjK;߁2 UeS`LBPuƎ; AY|iW0Io'DOIy@ ^h&Pd~@#O7mTo9K fiU":~&Yz?YƦg "fL=Q~/Kn'?&4ujq0"u2 s܇.X6 p;|Тm޿Sg`[zI9pFك u[|   `yFTJ'ebKT-[Q)hO\  (Jnc܅?o)kw/[I!

џ´Ee;vf<["íFl҅FbFL+=6}Ȱa uՠhyxV&`'/wh.r2aӿ f:3|+RYyoCO|,hM,7c g )\HGqeuH.{l i#r{D=YޗF 2+i`V]L ~t'}sj;'=q临,6IVUqx@غRUCIse`f$d*ENg©*AO>-" ql(yzOH:"rE" eps(.ٽ ye.+jkAYz); [p0y9Y'MCȳkj{> '^f087nlyjj 79Lysҷld.Ib3{K{s!qS+- nӹtgJ7Pxu.}U ׮_,@*C(ni 4|ygf3zGՔs_۶XhR?E\٩ҫ__y4[g<]M\Rت/HQś}QZJ-FA>tVZ4e9tR:fvưؖ"5ס2QtY1GBq4W1Q !HE;âv6’[v[ iawMC%N UsUrQŹ3-}_>ţ'YT9<Ιr;Ywa0 JZL{\u:Xvͯvw|ԓ_'>8RܮYz^\ڴrpk10UB7QUGx8$߱CM ӤL"r),)07UlJtleir=4ӔX%Y&0L>X#YLAk 'A[jx>Mi̼9{RY||a> KWf&oўu#}фT JH$騎Fǟ񴕁 T!.)Y6EZfXY[ f~;=7)a:vdkh&FsVWN9=]Ɗֻ6}MPksm$ c ͈T_epMN(lEԺ$g:Vf]UI&5xnNs# Zyi\]:efUD?51T&jk:Kuh<+MK:bL1낉rl;8Yf.H}u͍i?!Jˎ=ad xB2]\r bQ5GiE)Go{Pyi8wB񘓍>N 桗SdP;Q8?o?-׷[r{{7vK?o#1[g4B-^I{}}şK/{u}!{|Z9^[~jۻ~Oqoo#MnKoBʽ|o4hezNVw/-{~/!voG'$=䇤M/|~/L*0j7PL|>3o㍿ȿ,Koݧ9]Ix/wVbVPϏ';I Jo5^~gWK_3ފ@W)o2?.@>$-EgZD! iܭ OzQ|M,o@~!:K헟2gR<)S<nSVI&jW9^ķ{7xX}g7K]9_3y|DH-خu+#>c ]G^>-chU !Rइ me`t@thX,d#yqޛz4H\Vĩo׮GF=t4YR&djxۄϱ<ԫ|[ ?hɩӿ;DMJ*~'}O_勆h޿~o?QF׷o/bzKL|^ۯ{ko/?__[/_ȭϕ?8 3o>t{f>#:-TlNU}H>ƱQooL+2ĈA4ɕGUz{ݍ~%" ʳ<@A.iLA}@8Ȍ 4:@Ӳ:a1>xW;?&\ ȅ rۀ tj+Jnz/ӁP@BGV+u_fyeovX?`?8EǞr >WtӡځX~\C.PNCxuǞUӣzL;^3(0tP_g{nc>_jcE-GoN[먦l hM4> ?UW|}.4a-*b Yb T;7Bp~# fG2n-rA&Eq̺ѯuz]O_FjLcT6sҏMWg6clGLD<;ۼ3\8='rzG:C0&Fcpg|7L;! b{䰫mC/YO=F793%Pnك#ed.D8{Lp}0s9|q.Z`E!LXyIU:w#k1%+u06)0K#Az π G&+ nz &E'$#r9P^(B Oav_:{1F,Նܒy}dUm uU=D-nr"9v4~-UHoFտ0553t(r<7êUAaHhod]Op40nhw5)r~foׂ=j lD2̦{aqv+G 貁Hy ?V1 IuTFh a4f Ƚ!,A:U33{;]1.ҀHI%nPлaiSQ38 e 3aж>% éhwҍ7:+Q M=Ojֆ5 MZQJ~D5ji(4J:V}kW]1jq#]Nom \Ӏv#5mK1 7.ga R8U m͘U5nr*AKYV%hIö;ޣQ-A!>TtXa|6 !;}S6g[9+9i-6:pFT)qSSgڢ3:e8P2z7@V(0$bʭLs?cTͭsF*ew|DL1R14)Pȍ^x`9&1*D۽ EXA JXF8ۑ~FNGM 7G<\9<_C.v`ow:蜴db2и4Z÷eu=1Z9{eKZڠƬi'T܊-<)A23K^ărk'3z ־8jiV+{:Wo,؅VB[`A>}0u{"7^vPsGGV}z5o +]ZUZ]oˎ2/̏9l:0p?܉ z? K)B2i* QRK˞ e\T{ j!bHApωq$;D%x$х#/Ӝ0iR]Q\uqJZASýl@25R7tG)CخcR+NHsNæ>vG23nLaaȊ$]!^p 3EvB26oIt̖Sv=Z8$6~Խ(@9uQ\D'{iU&FMuCN[H ȑs*"wNDH{Oxa͗2#anB: ;0:Oj)"bN_K+lc3TܪjVqN󙮯vK`Qx6HUo&@)`|xF/7Yc6F-4ô#pa}6jю+}5("Q?umlriQ DDņ>)!-GHwgNW;J 8:ªH@=F?``*j윍JlnIaNjE4XM)a!Zgr,׃ںǀ#Ļ{ԣ*n]aLI##6kJ;tKE1bNhjZCl0Zcd;E/:rƽ2`F_Nws)n_;p+U+vL )Ac~ϠjzvsvE:46]ص2l5[v^vHv-upSQ;Mt$r탟r+]s }G5`7 S/0Bm@e>+?D¸Y% bשhz7MB4>f3!uy\>F"Ŭ&"68)cP~vuݽPo 0%7K,fZtD q(|j{ %ao #9JfnuFh'_ ')41۝iJR٥7~~Lp*5}8!VWHLm6܄ʫqlVbC5)2]pä<2~$U9؜l ؚ!.b:^fp d[߹{u!6X[QnXBN{2 " Td`{}ܰ7c@A>l˖JRjֺHTqD(D?jKvqnve r./H'MQ9î)9Lف_qT[xmAl9nӂ╄-"tQh|>yH\<)4ҭQqoq(Bali,ZZ]ŭcߋG=;wu.YPa'D$-5)(:{ "wPoN'xOOD#vJҬooRZCd4p@:-Z91{icFpiB!==r3 E˽­ǸLQWIZfӄ$#6w7 'eG פ\2YGi[ z&3\O.)IX(J:Wդ/ٴF~zs^D@A;dlE0%ob' w[+9ɉKs ϦMk{o m?AmgR;vK?$VW$zql6&!ެ: ܒ^GjD>:6XP5$GS+7p[P4Q~zOk:YxX.smnڔbzk*x_iuOJ_cD!:vaSy :,:jXUc$UWr1Mitos#%hDtK){D}/ߨh͓MFU8 &-JڔD4K{w9#-vkds/c37}QWʣI >󛹑G9]!n_z.lʇ[SL~lDXU2TFzQ~53m~ lrlmn e|" k%dZ`3h4UH ht:m,1q d#i* ,lo!9!`M"Zg8>iD&/_{:Z'NeLLP]=ִk x\9 @KWrsΰo]%}YȨsKloiF(%ũ S*u;dڅ{.D\spmi?4pjtaH(L0Hƪ4<-ם52iưۛGj 0(? {?JZ]IL J4}ӜkNG(@#]r-G !Lm!Mci/cWى`QY2^/06gݡzc2mz[.GAsJܗЛYz]%ze5zY$-ntf`?.s1wbp+Vë<*i`P,ֺ Cr_=p,Mh56+DiD(@&0فg;Q?\duSn>['Yn2Ɏc"GPs[qn ٍȯd&vօj^4B&EZz wV>6ṭi-vAA;$4+0`9T6* yx] 쉊LVb C4Ժg4IQtxOd 경o%ECMfHmJYo5=s})is G5/S;>&Xg'ׄSBlD]qdGQ6&S>̎tPLle3UqN9xm߆N!(N( `]x@ljoW پnV~ƮEuHF+7lEb3̜i_"o'(S ĆMS/dEHLŒi<OeP~z 8*}a̡tseNWETIL+0RNOE*\G%.]Z##)^xqHٽTG hviJGQB"I@Z\G-lUƞDԏn:IAIi:]6Ge]š' r,ЩM?k^@N<;ʖ=J 5]fg 6E$lN'Am1{r6 s<SLrz v5/rYY_4G%B_*509v}aL?j)}w9 mhQYg1O$5kr<ԛ"]rom&Hɜ⯻a'U; -a%p.%J$RamۿS]))!kuolRQ/Ez|)dBZUu fp/* ]94g@,l]m8rJt72o/M5fmh.Y EZۜ vNH#d-zbםwanmtU<weV\a6L IЖk&6b Orzhzz ]4h,"(uYe 5>DС1}AR]WX0xFq#tIȂݮI* v5+t.5UM:0.Ǖo3rROXZ7M_өN=閸ɄPH6K]F.JoG?-\]xUI+暊q;=i֢RZ\Z?d}YvbRhYfSLwV$3XbaG9< Vsk8`R%Ĝ(,OFxr&2`D?l}uy9"xr/q9mIVó845jgY ß퓦;b;P_0j:>U6>I Q #vU7,%#?+(Cc@VPPX38Dߓd.ks^ɒifǽ~1ǗEzM$^1F"bod>Uv!H1Sfmѹ~!Enº|Z|i 4~x'7\ݟa#FftLHxAlڒ^[Ǧ8H5zFktl@H {+ QK< IݞK#ّi.aqrT,"VZ)$Gcy걢-~pn\%{ 5cv@S 7Usڏlt؃ު{{`\+[+gCӴ;m49c>#ѩQBH2{ӻ?cmc)?F9iԚDHs=N?VƾX-ܬ#FqH{~]9 NKvXv(Yw ^%\Le4 /;J*HKZ-zl;9^&y.#.Rloc@)X#xKl?FzIB$}n6i gzvl4CфjB}MJjv+.yM3N[|)[Ϫ6iyU>c<`3W{&Roi_Dn# קER:q$j7uBKϽ\Nz!^0ϸ%n1M,z*&A"4xScE*ޡWA] g{O{E$WL֛i%hJ7.kpNա6rwE4 '5gڳC%&tiE:7.DvSj>&p^Mq::(m2\+PErr`d9x& 6&3hȝϐڴo g2XGm1mr4J|ꮲ2=^6KݭSxgQɄghP_=+w!^ˡ܇Q_fۃ;>8V2?2Ÿ́b+9j T죴e9Eo`76wJ#"M+A{o\vyl,LZX.rz}b7 H#qhx8Z3DZifjSl3MV߁-iHO 25\OٲUG@M݊؉?'zӺ(-c}IS|p4)'O̝0%}.6M@*^^XV'61g(`y%u]ݍ QW&r>xgk> $)~/ߧ^>ˀ~fg"M'+b*ë(Oޞd?~/'c4/o맷ן?)_>}O/?Im_~_K}_}I_?//?c~^^?zuk%_~s?}y_CDq} _=>S-jZz^hTKǴ}Cъ[ lZ1?lcp,CgvH毳[u.,瞞>}IF݁+C&uTH3~i-Ji֩Eʁ"DmL?M?]|]oueTP"7e23Gj݌^3ܨW!rmXM}I(/gͯk*=k324 lDNy݆%J9Cߗ&}^g*qlNi3RiuwM>~B,&\Gφ{C  08A)@SxᎮtau.ŕ ~8G.8poyug.s>Ͻ2zWUb ৶{ &%Q[h g9Ǒ6#W_Z ʴ SD #疘sSvJ4pÚ`knC[óy \LzYaCW J2p(#( VTdzg lL@)\ԱcM^ 0F`&$ U$Q0U^n,ɘCHUsp4^A2)_?'tH"AK19(}+lC( P4dm H+2c<IdtSǀJ5Oa/BZcJyhUXq>3Ńi 4m6s˓E^\'smohx9<:mx)ޖ)i\;E@k%$RƮ4l3 leK%y8qnG.L>Y_ϷYdyxHTyv'0 D\"93v'ׯa'mp^kJuPsK5!h ы;\3a tO {jpF%Ҵ߉LiacԥLo ,֌H_nQA5ұr'wLx=~.9y͸GH<\9}@YlrD ]qJJXRX6Dܜ:GTⲌho;9"]MEy"p\_Ӣ>*ɥ̸aYz{)f6"^H) 7_@nl+-=޼q*)hX6bn0J%hjo+8Ƶ.F6GmćLk2Ltfk+xQ)#k'[ 5nxnACpءrZK449ꗕ7kI3 ])}6G͉Z ,&R:s^b}LR;BxҟZ,µ}ml.2N,O"W.4K#b)״۱u8ќ\n3M@cYwuTZ1=iӣI2ޓ0:i $טDRc)i@3h؈^e0VTSҳÍD<)]RrqXCɤ:vbG>3qA"*{zh~lm_F""~>Ĕˀ>zgUHʺ(it*ʕb%q8Y&\9;Dh5` @=*Y}4)i ΎU|_TBaipC@u }HE[jkfD0\ak-9c:zCd_떅WZߍc:ZQFwVC%[À{- +(ͨ ez/NJZmwLw eᅤWӬK׬p)zx0%:೚Tp3h\,E{Թ|mrn0[BW՚Oa t ,MI,ta*}/_? ~ ~C}2^^?QfW<е)e^F1KQnM&a]X[VLlDF85JAK{R[Tӕ#>&8&h`"i۽+ökϯxɯjEvϻcqE$usD5+ eDS` ^\~C3oqfF*)!gUSsc^VaڎBPY] o뢾&8u -b}QPN J>Z7&%l(e@HE闀Ɩ VZAp荹Ȗh09(RKZc_Wc>\uVh2X-(4>͇Lη^^m\9~ɥ'd!y^B):Mb)~M@c 4c D]yDjAHPYz:@ *So VCCOf+,0e}+^_is|= M;{r%{ֹ }"* 'w= 4V?RfSvύ5RbFt_8NOdphe߄(ޫiO* ɧT Q7âPT|%8a>׹02Wy|Nej٦rFCJBej"c0sUKLq\9w+9 gtgOg2R>TM:o9zJNf7ƉQޞ}8GhCs6 O 0N*N5#ԇ-`y l<~5>ЃR~Z#JI<ꧼ"_lٷ+pYub&JQqnrx`~3z:CԾ-si?)su1hmk K[YY61mN[c-˹V M[O{#d5:'ZkJ̆Ŧ)J!))9yJzM*F '\T$8bY$HSI(`S@b!R>J{0]s+L{Dwi%nLiH/DV،#n}| o8O.x\L9c޸bUחdLHIl|[w R6`5YTgd%dNA$H7Lϣ <vtG}Ny)$dA|ol瀒ƃn: u`HHE_.r]78?}=s-oʸj&{k1[.16\$ô7BiQNoZ?n`_B''ċop,Y;u r $YAjƯ_8-@J'IQf5TFO5]z14F<}vM2PVB4DT6__msbO v=+|0)OV;wh v4ڳiTɪsȲ~$z@O؄X\ɴ.0#thm=C;1/߻eNRu{K-q>S5 ȡXkTs>J뙱WC+_J {hd{¬VrJe'M2펶bθr"-⧜iYG3S$I֬8M2_b"%{?1׹g*jOƞ? :;IӰ44[5cOVh2x0In7xݷI5(<Ƚ(Nt)L1~Ky.b` ET-Se {D{7!#np[2;椫KFι}I~puYˢ!wCRl] ~X-@9BK=T v3ܷQU.UF5{KC<&B.}s0)+SP`eM^0I:(:]3Jթz\t]ںwΕ/rT:FsrIZf:#zCi]}R^soYѺ5ޛs%:NYUs']:^fCmA(*хJgCMлl%y1%AwKX##9k@&j#c2N]4m%:*˓Gd߸C,iLU֍5lbH-qtT) \F3i[8|#/ ؗ"^$T^%&wGվ''%=[󆓛ԯKc٢ɏR3(gИW CA&Э7"'crxI) 0kE(o:|گ")H\k+M4eZY_#˱>'1<,w̩QBM e&U̠ u#m|:}\e 8bĠ9Hued(oe$,tRÌyq A pt*rlwXqɖ=]fٍr ^A8ҽ9sO3W{́]c-%xy-]5([q'Jy{Li\~}\Vh}xޣ ѭ0<@]Sf:f@؇2!9,}O`uC;Aː W̒SV\nvXp^wA$:XTAM'x D7T~nW'vk?tq"iw֛7 /b Wl  *ߖBKM`o8163~Lp3k4w^OU`J@zgŸzZ%! ('XI81bx1PgĖ?"U?b7{ sMu)bcRbM\pJ{V`e*7;hɦ NͿﳾwZJi؃N6,3UNkT+Wj평 RP\4 ׫iH; puB*a-t}ج7Hc'ܭXaRJPgtI,?$J9ɮTzrfcA(ZbPq@!gJ"yX ؊ZENsX8B|h!`iQL̐.u;+ ̬*<FkEeܞG7["nP[l^̭/-Ua,"&-R ;d^μl:9M42{bW?BU"%*8-2!f氻#[Q&sm.}\PfPr xP9$ O!\ P_E ւC2:6@wytQyTž2+W 5G`m&opk)ÅL'M̌0-m==3U.{JR6wPKx#Yl+-,z-B S3¸0Q׫:=Kr{F516(>̂orp %{fb4h"Se7Ń}#1_FzWczYdz.c4546ۤeg%BҤDk$z5^"c )\ [[دn݃ O_סo-ľV*R}]#BY!`H:[PfKhϲ#ňBN؅_Ƙ|:l]|52hc]R!*jJMr[;M@%0r(d c>B9DLWq_j>4 jNc]BV+'p|gs-=E_{!*v\g}.XDwU/S؟R6'Py8|gMi!a_U 3\Ӝ 4:o`]BCVariantAnnotation/inst/extdata/chr22.vcf.gz.tbi0000644000175100017510000000117514614305321022457 0ustar00biocbuildbiocbuildBC`OHqǦ 4` VPӠCVnj-`DȪCBTk,"NY"!4=Dx/K^|>۞gmj)+=EŔRp濃Q{{=px㏈l <:ۦnbYnRnBn2 3 eBCVariantAnnotation/inst/extdata/chr7-sub.vcf.gz0000644000175100017510000033502014614305321022413 0ustar00biocbuildbiocbuildBC+}koǒg Ac^m{mّYf!@?~=}}~8\~&~o?,U{rz1u8΀7_y~V7Ž~:9\y~xoWϪ3jmdysv}~u{|Ϯnrѓylʝ^ý۽-O/V?al˛ڎ\/O^^߫qg n~::=^nOZ˗O<}{5{.oonƿ4~jopVocr| Tg?]ޭnV-_OW=~6}YD8~(zy<}yzzey}qzTkqprOPK\Bg-L9o|pf|ms۟o7;ӣ'%7ʤx^] hb'pj Oj<{u/o޾<~_O0~fIj^ͦ/^tfng_,3&_ϾZDl]_mxX:WǝXr|}x3YGY]=V kt{:N"113mHY )L#pX"W?݌?l( .O՛5<b6iw"Ҫ[].&KR7ﯮV etw ^߼?8?4&^]ܼwm'MQÂfu9 fife@vlbN> t8C<]\A=wOɫmtANgb~\]2z鸼˟NNj;,:?;xgwyGg%.yh?_vdMɣ4ˇ1 #TF|׳?'/ o~dr4MGֆ.LFk1Bcc5bٯfi5K*u!󇓚o8VxK΄]#11Ԫ~\v >~$ Wr"XXj?/l=Jg/dDÜ/'#hܻmRlRv;l&.n>X.r "-kX02haRNtyu.7]Գ%4w | YBrwP\Bl0XK_B(B A߱i"d|,dcon.&RCT<9y-U:iu$oY歓Xgz xx(k*kj|%Uu0U01 ~[/JNiW5bYH[j@aRA:)3ee#Pi[i&>Js$[PPod7/^V' ^"'kckv/%` "c+%[.l4d[T>OI#]iXrE} Jd!lUÌϲw7ܽm`YG=Rz`jNQ- ĊY[ ygDq `+jWI^K¸J[SM,Ix|/>'^ JBWp "fPnĤAJ 8\7eD3Ch&#o(*/g" !w6!]4YV o$axK1TYs{eeleH6aIgvI*OEs1ĄC)JN1 E([Hj-|UjzS0R{1}˚JU!U]:6g9vJJ .'Y|19:}Ϯԍtm&j\h,JZ ,< LE6D]rc!մ 0%Mj^COIJcm҆hFS3c9`$OQP6,o, 1zJPpUpU υAK ~gt +-B]l߰S,PbO* #{߾GDy"367q#NbvxBEoݾhY3 )4 h#a.I$la ㋺Td~w+] !}FPEP"h]_v+A5Cv: 99t%,'Xv)f_b۾*w*tMޥʹ(HcPߌz  R^l(4>*CGoK8Ϩt[b3uѶiL!S5d.cW`Ь;۰Ts3d0S+Ϟm?|N*$59Zn.DD0lӻNIN NL:wI841_YR<=LN?xS<>o6{JF fXb(at f~͇0 $?ڇw=4ƠVӸP9@ЩdTu z9TØĈd J5/ض#cJlK vU/^PԆZU=E/`N?cybj :BsxslMDG7DrOۘRJWJaKu{ K;AF̭޾Lc?ݍ@tLom!6ж"zn!5rl")xaEL4Drr(dESҚy'1ЛH'-nLd[oFbmUBo[:Wjvtv7:Ch X޳:̈h l,nu|\GҬ&1s%Ŵ{!5̀oj[9dC$>v;f4YL0g$au>7@oo>&^T7F4}+uu9֏;=T+b &r _:* ^) BeZH*SFڭ)D7O 5}Uz6v}l((rZ CNc4Z}ʉ:+'oʘp(r $F &5&C}84fFvk2rM)rD8Cvo$+UY@ .F-b"h 7 L9I0d2Ksѡ9rZ.R UfW ɽͩc4r ï(++T:؆sŁ`,4G:Bm`&ieĨv:)q=Ŝ!HVv¼!p93h ' q`/#@uelS4G(+`SX,9]XVZGΚٍ~9 -c/^ᲁE SEx_G63kv1K쳓`g$@c:unmۃsp3&_7j"uhAcmDoLЋ{v{?=h{(OZIԞnXr` }xܿ{> U 450;B&,Y@B>pg(S4c(ĕګ†p-kJںO/Sf*JngQ*|\&'KG9' pM]Z (#vc;z${:v|89y˻oѫ=z~4,+nrorb( %Zga]J 85P$^ 6Tڷ( 'S3P~H,=!nHʹͽu Ȯm^&a8QVJZ1G_%Q_DIX6}M2=V,V#7O"eki9TLdڧ(B;!*k"gԀ,^ʳ5aڰɽ55֮kGL2 #kh{T8H5FAQ"h LRM '"X^ԩdmp mb :N+nh/2s4W9cԏ*&Bk#'tK"!Y. ?`tMtc_H6Js0YgX/mChKw $1I;Fk;L3M^(KHmm{Iv#_a88دuIJгţ^~+;e84lsq :e:|-! U5kܑ 3wl'(|vp*e#AB{|QZz;oH&rrE^s X+.vx;&3e JGz]@ [`uN&Ivp*Jvj? G; v>ڔwwAXJK A Ifms\^wtW=A@CA|rNQCڋRỷiazP깘Q!SbyzT&%觢Grχ3Ǒ5hUUʨ0e,%?u3 <Мgx9* +=-i`>70S~b40ӢL%=c$§DE:yǃv}X1PP\ kZdx~8~uT KvFpr;{p+hNsy'uxC0ɻ@mfyg9K< 2AQSC-M`\Ϡ]2}3B2uꁭs7)2NeqA.aד(Wi_!+x#j*>̓ ?#j UТN KlAl7 wd7yQdJ?L-TVMR5tuُ,}sU^Mڅ%2-J-Mj?%HฝyݗCJ q`c%qH(JS kL-s_3;m4i0~bq,wȚr5\B6H,Zr#np 2:_^0\Ƕ3\&R+cLJqZ_ʣ!0u~eqĨN",9@0DTHp^Hly _DIkk:a ¯PXzXpZ:g3eP鮚NKlfJ`XaW5nuThd$+U50h8;8JN b Q!Â*ba5)b3D$sM[rxdϱX̾D?՝SSP^RXAAi"Hp2J@~E6.*T T} DEF;ydKxy`NZ8T(sṃzgs&%$Cc<Ty_)̜]9bJ YI3@jHƒawmnl9+ #:hEAGRxmg3ZëQ +Ku;dܨ^虅- Dsm BI}7;wS!ӹڻeXS5hTXVP E26M֐q2j*9ʳU(1Uk'5A:cl"f.X9}%,tnrw K0R 3pW-Ss(MyLzƼֺ,`W[c+xQPG)9ijʔ ]s' I/,e\~4d \}Z*-mbN{φZm020s$R,{ň _s' }j< a!ߋ^$5vڶ(f'F֗yȱ/]j+LEbzp M!r%nc̀UQIK[sWAm2ry׽SrA<)tgVvW]XtCnnw kR􇽤wFȒO ^d.to`-;р5࣭44B!u*ZjmA ϹuB*U)r6iڮRr_o/=mV&?hPMe1ZY=Pӥ~nZ:4{+hLpa<2z-1 *qRW4$i)CɈe{eP/Z4J2TǴUX<@oXB)=3./ v”G4JR ;w4{8;FOayGxxIG>W'ٜ7aѧ1L*zT8G;kP}`㊰DPH3GAMڰd1d6>CX147cR*5b$dd&m1cUdcTE&Cso\TE&wTJ$ƊWV~nb$f>AJUN)I\*33٪ 6]MFaޜHꈌnyi1T 2JT I]""h6nV]LSԗ "%R=N` v2P Ct}7g(<>Rr TFKa)!s?@F@w F./raL gb\+Dqx!A$EQkK1d@zqT 7uL2՟fLOoK!_RH㞳MG-mx<`<2:~Z~*!x $SZ#%?b0Bt>rxs8~cYYsNt4XdTB+eg*)0t>Dd]_TEAv%UAĉ?xDF p(q9JJpX9[s?5Tsm ڠǚw;3;iGD0fI ԥe%f$]UZS$l^*Dq@MBC3'}m#qgaaU{xCrrI’1lQ<e|2`E,tV-PYO~v۷O~~R~zy?}ջOx}_~闿] 7oNy~O?_o[/wq?2ww Kc+C+ci,m{\g@vJGCu'ȣuX:SQv)Ha_ſ/_sF|aFǃ~<=oo{yN^ԏki|Wu㿞fj58kL'&ۨKIrKD. MC7͒0%\ )6Ba}@q| aǜňylZ]/x\2TF '6E'l,/Zrqk>1BS!ƌuG]tSp,d9٣sPFK^(XDisi~i.q$QqwnX>NvJY3dYtANG1 =$ivtXO!J[ETcCl`9yFvJCm$2)$;SM|JU99uZRAncCPA,`;), K=|]vWUV\Khe\Uklǚk=PIu v" :ecaY?Մ;tRcUJa(c1E\iߍyn؍TPC*lǐv,HjH7*qsHkmělG%=;7T\:pxyMN4X-i*16qr["b{w!nNvF\!+m&~)[;xhQL+0'AlcXHCJ*7Xe0?x[)cCyi d$0aNdELI튏w?oZϡdK,b|@Uh,/R`ȆPb ^L%`w9qhlDQM %;FEP<:А)L99eg[>Y3?YBO%VK"$f0&DbY:+t@ ~(,4u2Gd)a/xէLatOC3>)}69}Lsѝl&^3.qf,X̮τљΞLK$*߼/ͧ|SAglJlg!Ux;%8ړx.έv@jFvF(C3d*N`Fj EpmL<§+~8X#%F6ҧGK 1buվjees_ѝMt{K?b=_Z*Ixf+UƇ S+&Egt6k#^Z2Y(p>3?=̇Y{>Ps;"<85 y^O~ yRDƙ ád<(Glay1s FIo.&OE\+BJw%GU}3SC^gQL% Bnz}y1re{+jD5$|C/|6FF,ɾ=v*S:rqf,YSOk龚3QM\)TEz]"\T6Eyp͝VDV佥9$dpY%WqŨ&4 ]BrQtP6??_~S<}Bm~g5#?*bn0["F laB'ǚh`w`g;ł?Q?S>XtSߙ1HM lK4Nt}mmp&:tYLwnެچd9:jlC8N95򛟡AJcRJ_G͞GX&F7qP$VyeQӉ E r*K~-{k&ߟ Y_aaf' ׿3A󫣤&4r0ZѧNwؙ:UT١nXgXH}cGM 0871(6~䷧,ǃSVW>= Y2i\Ⱥ+_bY Y1܅s4V?D$5HNثUukJj|A@Ґik^3[ηעUl̕1$cn 5 o4&}0D⟃R{mFˆ4dvdjZzp(9 aָJxgxQ)p'~|U0&B%Ff';oA/U픐e22&{g FBUW_܄m>XV.Z8Q:VGaBtk$j]HHpG(ucF5 tnWм:O:d{H1\pFZ<^CfpfY9k&E2msNYi`>:M:I;>vGk-@\ZPrnP0(巀+)͗Z7p/Hp 7H5;Պ"Apj ٚ022>`ٴK7`Mxƪu@^*S+P`+t&F(i೔ W#/nz&Λյ!.)/[7qfY$Ҷ=6V6mSn\jC&9X=2BmŤ|ba9~Iga5ھ#GNNWh#<2~ǟ7u4H+ͷ{<쟃6Zk7`? w]̵J2cЂqb:9Io혔LQD!K&dAJ#l+0EJB\\r44s;)ڏW-=C;dVuם?ݣnE|@TڀФ-t&-UlЋnB,S E4^ ֶi/O O;_O֌~VQ3?t}_q`~+GګL@I9yK_iM@vw8+32H(6I1tACϠS$듑wU_$B˖GKZ@7L[~UT[E)VkDX\Iuac(S_3S@jJ_Z nusXXSKe}a_e e)X3uXgV7 <:D]gN"^W1ERcl4WV+qҖOڮZ8CLб bM[ WLF\ȳ^ֽY٦/!+_d;ta).6+}miDUfU΋0T[4]HNXf*\NuL"6Sd_Qw`]  M}ͥ}SM?g3B))ւ4Jr+j%BɌ7u^`iRTqP;kAV罻 r7]= hmTo7־k}6! I#݀g׾} WxdgyP2˄䚔!HC@K-O@t7)(ۏkJ+Kt+<$-:p2Pi!o96b&+kZt_!q;%Ŀa1ky6j$ > UJY|*> sZ:;xmW `f۾I.Z?4nz ﹖ #-1zm#lkEI噹vT,%i0j$RwN[@S4'R -~u(.SxԚV8l_N8CETPD x Sg0kS]{x,QNLK Zo_n'prd-!암KqSfWtvYgZݖТn|my2GՏ~osuwT/( ]>uiuBԯ{'>0fNw#v7Pt;GIh%z(Z4r ì9ޟNc[IY:n;rvjKĞnҞMnΝDW};~PX+1Br%E4ЩxA~Q8Q:%佟U$ivDZ&f Q4##PZt nv/׈nTcx CoNhTnt.ݴvui!|e%dQ`=^;^RRƲZ]ar;cO!QgT3P0Qi-l}bJ k`N+Mrw*S:Drw˭c[5.fw:nMR$]$O-Wzgxx7Dq\ pe?g7O~򮸺}'5V%!]GvȆh= M5%+pAwB] zMI.v 6 ȳQv~Swj#r>%,W 9p0%K]( ٬JIT3\20^@>Dsh;"'y֕sHy]XJrK( ʣso pZ l-٫\ aB-:`ߒc&dۊ~u@|zC膖;RB2C’ Ի,p@5Qa/,yvOdequ~c=HM9h4soQ(8z+UƆٝ픎\Ke Ws Mw0(?sO#ڰUHjVv>G(^!6a_:n1ndēdԧ)FC%02sKFJRX)`8x u;˨WioP:M=T-MັTnt1k>UgL!#R7(JęG5}~lXBmNq}ڵMVb.!ngGTg #Ia' 뒝T qq;xZ4bMp?(\d(`Or رtR!)SՀE2Z^^6ؑz{(QH+ e8lᬀ2T>i8,LTQd: 8DE~V.+p$bqM$t~^"Jx-JԟlD$0EfdZOzI0F/Zvze [;qODXDC4 թkYONWxβF 7zN6F.7ĝUvL'Ir^cJc % ()|c 5YO'i9;l\i@Dc4`iHp6m:B ӒF%3qJۉzE<կp^M@)w]ob"fs3'ۑhzKi f 11Yߎ+_`A}x;W }7Qt8+/8 XX׀.f6 ɘto55tSֺyEl/oq=yEaRX:^e7 +"4 ͕-Y^L5,K2\h@J!)a ;#*/@ҝI:z %DifaZr+!Hu}ɱ8*~^!WWr|\{ֱya10:Ahw?{Uv:v@K NԘJkhN;_ڊt LϚggqC/hbϮhNtN;qmrga*}1_u;mR" 30|Rl x-dq:MA6ERk Dl^LZR叟 6OzB ˆ 44*mQ\gjL&n6"%lN.~@5t 2 [cbYO!Y]"}!u C= ?FK SwAf#BB; |W$2''I*vıp i$()|D03Y3@h.f~v2M,P-nV2I$'ђ%(Y?/++@7 j X?>DZ6㚦q(]ƿ܃Rq5ET_OW)6֒˱PU41kګPXRJ_XꢵMaRJN:-;+xgE`1BM!XH)p״Gҩ-%V?KNSe͠u͛-eu=&#BFiQO1J's9ń: By(`Td!NWam]OH܃Χ7t>9 j=Ϲ̵ɓa&ֆ%~$<^?y3+q)d{gݧ4f.JJGl]k(m i@,NqAVB`b`R:{io4lʏg<஠RRtOwPGb_J7e:.oqtBCW6}{$Ǒ"QE@ޗv dB",u_DdVuul[#xg;22232q:ϛi|ws71: CЧ7wlm~i.Z{O0 #p<̾p7S_~:P~ z˯~=~yݠp;ǝə.l0<4mOwy"{DQh$oCvmR}bE@g7BINZrw^|fNg-6=boןÛ+ݗ~sz7o盷}7_4@g+n ?w+}/^ه`o ?_~k{.zc?QRwr}7,_/VݴӘ4Zgq$x>\QsQGccK|V vA.:2T,QY[hk qY[M;<ں2GWn?Ү_?wM> ,UG&3d1ZgN66r(ȳS'w[ w]M,5(NsH:l&o~ۯ菗oYGOQfx˝\=_^'|Ӎn|4fLH;m_nom%*6[gF D*Fd7ݎ̗DTo$yX@cB _Z?̍9@S;J/q)r3}x͜8Ety6,P[qS77z]  deLt+Xg(:8Rxz2u7nu̞Ќ ֱ,|O|Jƴ7-avh)]rގ]%s5Q:!hz,@3oͦFݑkK+G8QG&{XJ`,&.5B܍L >` VOs[7F+P DxJ\cVk*  :L>krBP_'$6mnllL'pD'Q"9lʃ%4JVٶ+˱נF'OX:f,LOH@tw$|oDqHXuGoD1ȐKCv%i/\kՇ2JgԈ^nм % R7{^~)灩1E-~ 1.E)YL`u}ǔ6tGU{RH-R&]O% PRJQF7xAK4ou@O'--Ri]y57 C/j?rk| ʹ`M oCZ 4L$ӄB#%Gz(0gn$e~{.!*prZFчX G!Jҏ"Gl8bi;b &$g$@DHv_DG!z F]Eb@fJG%+E#m5 WxՐB_ jb5pGrgWC:sC͞ ͙XDJfRȧO2 '$&^F'v>@#]~?!ҙ /(4>I}<)Xc+:h2| lԒ &;Y셐}zĒc$G. آt#[%VŊId]eA5Iȃ@\Ȱ-'֢e,n.cF [Wx(c`dNpXv癉aN˅m^̃WH4:E퀄 & (]489:XGPpA-f\O4z24&Gc:T?^=N|szj-N ^w?|p6^'0 bLpgh( L_AΦ"^7Q˚ewa7ћLHKre$VzɈ%LOk(r30n~yNXn}kސ_~ LtV@8  +Jwb da®4fܨÐ#5][`ls_?/45 )E~1Eub1u>.ce>޸[T[m~;Y|uLJ^nmvdGTN9Vm8.,6~F& 4k|!u_nݐ^ك* [9vv %q~9Y&?FϏ!͚ ] S(tTBV'u >bQ!F4l=?NZ6/p| %KUt|*m@S߼?yxqĿ?~sk]a~q5gH %ś%Te?KıݲE$]&:!(v854ްab(`EcI/%mB̖@O0\z^FKXLf$]"h3VUB n^M8HZV `FsN]qnѰnf?@ӧ׿Н9 /_#bx/ͽjYβK.j\ ga(,K͍@l@'+@xI QZr*Tl 5U{} ܇M5D%Ҝc,$l&pJ/ =JĹpẐKnfP&")a~q-V$Ǒcy 3J7NڃDᮭn5 S\Õ8\@+GE|t)p]~IїTFuHz; QNxK-YF3?a@d> NO[Dd)g'"HoXYO ) ^Q;Zߡז-6m%Ub[@|ܔ#} xv<,nf’-rsGrg7/Lȩ 8êzfJY L6 +JsU +|ڹm aHܘB+\cFn:揮͍@LZO;jϋtpph.|?4DWz$bqa? A޾>~S.NC!ǝՄGSD 7zvشxug2#}a{ f𵇰B[-{H)Rfn0U7( >^*ck^ۮ+*ۼWyѻůUgh.HWEvDu^\V%iS q#A2 {hΉxÏ>h/Q0_^#Qlsu'WeuJ[5.L4u](\'$ɊCR!,yÛw_^w_mxxwqj!&տBl01q BtILfS@=+Z9/n/Xv[\3{@\u:3=9{]jKM 0Ѫ~zT6m5g1 //u u&D|Tfawp<LQv  Pgnӱ2 =HC '4H TFqχӋ㟿/?|҃oFlDRMݝ%^qaM̀z7 Xsu&CS]V;Xl-l9"N oΟ^mnC$N涸E yx͏?)cY3eLG-PA$̝POg[o3cN)BPl% J6XaȜI1򸻸icbKBճ;tF_mQ'$K{֟+G"#wR8,1Ƒsy-rS ;!.$u[ 5G1msUi c~#tTn5 %vn^h,Xsźk~g4T&9fQmrLt2eA%%0^qgY{3f\|1/,j&՞vLsiͩeofdw3tJZ}I}+'v9N*95cЛ+G ym3*#<)kOmAyfLRMhzpX 7vڤ<ϛȖXI,LǍT6[IV| 8@Hm\mZf?;H4xg߂-C-΍ en.G `Fw9  -bԧ~cyK[s11,3e-MWL"rQ|~@Nm\Sw FlAگQ;kN9dZ#Nb EqkA @AOc܉գū$#:ddIJJރ4vnT4ߓKSҺ#M?>z}* L؀hO$ S$Q&;!M୩5Iҙg)'O*h(}|}fvW?TH.CDjwQYI6H#FÿLznCqY0iƭ[%K)Oăbk3V,0Vjl`F3 %B3+T]212$V w>f| '`SEv> BKY̪v*Rœ*l̵.zk%<p3W﫮}>-}NiJvɎCpoUm!'ㆀrCNhcUcocG#tOvo& Vuu\{b1SPl0 W/dGuMu,> bnI:"y/NP}Ay\R&b4g!!#A$Qwzf!OXZb w+C\ܺc#/V=EX2+{I)DW.Z0J_~)2pҪ1|Xk|w CqL!B545n#C02 \B AF}KG*Y/$a.ceOpET4J+f6Qr!]_lJhXDt Y,3!.}Tn@!(wĔa%N5?0+uH0n-7ʖ#*-,j0K.$^W u'w@0#7X9sNhޠ"Mc\"!KRsJ/=B\GH˘Ј(z:#21O:ݳQKD3 q"3Tn^fQD`2m9X:i5ݷXd;+VϡlO#3;쁍|\Ua-qetN49Z]dۨI*7ǥLO: -y.+[LEArFzYZ'8kZL@`hv%46_\ju`u[e\ 9!&Pz֏4D*Ŋ8f*VmrD_s !n8#($MM0Ԣp$2nUȔœHQJ\=@rVZGM\G8\`̵,8lF*e(X#}2i0ߎ-S- <|l[ zk@ey2alɃҌp=r .. '9eAƽd}tdA\3Q1d;W |h`H._?]T}'Dc)^T``ET#oNe 2(|RKn`uGIX<Θ9NѺ%>&K=EWȺvԾzb"`%Ny#Q|R C65sž'\So]Vq^MҌCyg"G#i<k.&襲;a--MЭZ;^5442jLB/BUNw~9ޝӧ<}a0DzHȥ -[~ڨϢ[1m5$̴AVH;+tfH(ed^deͅSߟ}MbpL̍&D:Nki(m V_ pLeuL%ڕGkK~ _p-,~ 6Mjr>'shg_9w^~7_Ho⥬?}nlMП@yF A 'HVgVwGjfzGw['Gq`_wdX?ɐmGt^,ٗnw<B ҃G0wBrsڄ 8ٸ}m:]lemnPMv9 FqIKƕ#x'8EWq¶< OF!r0E.8zŻM)SCܒ)]@ WbO$ ̦!%3agIHR]#F 0p/=õ$I$k7m^Bq.$Eof+ڣNl{s%Laѫq/48i4yX;Pw,,̀iiYB_|?r#B( FS*D0աe'7vqVAj6}vm۷c\G 3KhzKCFgm{%M LHj(nݴ $йweğ@VC2R 5GoKm`i%2#@;R֧eJ :Is{Svp3 B ZI: Ec\z>ı%⚞ow@0nFۧ2V[!l EAM9-\d-vR^&ߎogwh%o!9@0%1! C҈v27g]yŽ@86ZpEq$}$Mh8PĞ(lT2/IwLq*Djp刦Egl^lԕߚ'W=rkk@BGL|s–]j'LHApa-5 #pN9[Ɣ`IȠ&; 1 r.r'-N]cX"hS 13qNHMݝ j-\F; 劙܁zI &6:xcQVmdnr]Wk&aKu|[xlU2qX\h󈒴3V!g[ϻR: I`<(6V;9ING" '# rCq +;Xu'!GB)FVVZ\ 48[}q"A8]WRcm~80{900"i"#b)'=?68j 5?fJGVJ9bf_DH,v s%!V]fl@C.Tt (rw)#v:ۤR"FᐠmoJ,hZ%T_>-#6RM_31\ 9ږ(KwJ(3PehD*H{P UϨig&]M\|boy3ѹZH>ex-dƛ%ӊJ|qQL8mp<ǡDCmh#]DxǃH_(:J7$]VXH,ul!yqdvH džԃ+>(:3x,^T6kFqې]x$ O#쟂%p5T]U6RS Q e"'ȅSY۵!F"{ t1ބK@IݵȩR%1%m$*'3`'(KZzp/އ#%ZA5*gE{vl5/-%N?8v71sv61j3V_Ti;8PYnp517ϑ&U+]pUƫTO+Muharj!fMȅ!o{lЎ FK0)|~_E>rkjGS])M[8FKw! n/X(n/_ /J ڎ.ڗjZ59 v%O VL!LW G8'LtZ!LECç`;~=*pQ;FNSF".S= 4 2g\n)\m{lV A8ܠ0lF,s8KĝUC'j !u{}N?Ov|!X)hƖrInin5|z/7Ng Ѹ1/7ϒz' (!z{S=d8F¯/NscE%HQ&[D$תLa.spA %òc G8T(q@W'RqԆ:81-cӷHߥ|/ 04gY?E>c9,XUhen(evѡ: [f (wErW[XP t8enΙҮj"TGAMky86IXv#nc*4w.'W3(NG=)vy5H񒽿sqg$<,g^]_sř UmI9Ugeq0 X֬(j]yfnbʝTh9b`fvωTldM=ɱ "ףtCL< {5d6sfv;sL2uhc 4KW9kyG8WubMOOyY6e",'eehPX5h ƺSUc;&*sAenNRxC6?yox:֜8䑐9O<7.e16YCx@ cDBJtBY)U)ߥ*>:z>js]$Vƀ8aְ?tfʬǃK?K#ǡ5Gqm{, b e088Cuu-1n2 ь{]MC5:a|5DAcK-MmAQ.]TpWKẆ g)=r|[q.pFMQ*<)7e3XruR#cF~lQvR**v5@Y@i.XnNT-[U46|oR_"P>)<h ij[SzoUlxGcP6Sx(a)~ۇ?N/HpW)FWA<ڠ@g8X5/G[˦v-7VJapgx]pT[/#G1)4;GQ*5MPȷ>kѪ<ྏ50nFʽenߌ6 uа",.ZױTDrX)s6fd`ٞ_KqVⲉ#k`7F6=XCzi᥷Ktern5wڳ$z ˢVn(Wf <]6iz-)P Z;/x[68sJA]q+l׭JX5+F"ٻ=CpOa»iab?>̂Nc;,G Q FrBxG%4kmc-m.NZH߉pdD!xKN 'uuU8sp.U*]4#Q;h /Ǽ"XyAU ALb*j *<³Jw} B u;GVޝyF4ddZ=Zٱ%r k QQ4xm`p t L7@hDAbMXD~rZoI떾=*njfwF!J@Z9ssD3*mA~sEFʙUSMa|!b[5fvzp?G*`u,耫*"DB(?6jBpUIVGB% ]VԯXg8u՝ٗla/q\kpЬ?]D0?SK0\9O܅ ȭl`f9` .] *$$6a-=!ݳX˔z ڶJ-1vaEiGhC&'dڨ}\Ek֫V‹GpqB&j8qGƦ͝WslLt18(pϝЇ\ b@-eժyw" gROc޲X {~.ho`QxP!]U늈jekSlfY^qo땰1Z,k}wMH*,pB3y'W>mɖF&Ie;+Ah룡^Y$Y]$RblKݏ4e=% \G4@92,Ӕ/Ѹe(ܸ7&"8swqK~'9pflsvCҹhvXɻ si.[oJ\>y$5y]lۆV$2 ^)spZ5zŜwFѠ^KljoG/^-$qkhF"E/ io JI7Kb5"΄ˡgzuB;M~)\z՘v?*Ҵ!MQ!?ımlK3I :.J<r .Dz ģ  )b S\_}I@aZ̅[5dh˩&(5|NTdS 6C@f`Z5GB%&Tr/K)uQ\@Ō\\7v`9p1 .qݡlWT㹹Ʀ@,w3BCf8}ikǑg(etj0r<0 4a?y2b@och ezgo/翑:Lyf~L6ӳl]v~{y6x&8蝫?J$5B܍:[KC=NHO;|g'k&c-C)>}~))EmBc2dxDLѥȳPMOs1~l\t4Zef_WFsGR numeHd>ΐ!29KϴȖd16lg"KCJa.~l wo.<SԟA/ԟfb'DCtӃO|Ӂ-C{~h`pmҮ>yラ4;nk9:ܔLO~mtf'~f酨(( Ү xϘxcn?^>&_z CE&&N3k'%fK~'n X:w_>p嗿3&ç82Éۻ?s~#O{}$OU0>E6X(xKSo\ _gzxN|Cr%לjB{L1; gzx*)["Gg7,4hHi/}ITS}y\X4@4>;ӽR]/f'z{󠔦 Cx.V z1o}*\"-MLKY@ޯzyA $,`YA碃n}F>W˯B:<?9}>?OJ|)W&~F&aC]YZ5}LN3K/DmQ9+y}B 㥳K",}XBGL t28,5nID;z7~a6Il~Y\>)5cGz^ d+++zyzntEδ9c/t:kK T#GweKZIۜ:yLB31sNzCg!k#1Z0B|>I+z~d"SCh98oUic`8/3;ts,5nЮѵc@ )xI2~&6pu|[MLfvB3 j鄨 zzϒ:~.T5:(ܗF¿kU5]~g(&_)ߪp!49UJpTE)/rv|I~F;6nt}"I3=<[y*$B<&'A6K.8 =.L!6w#q5n{>!1_cR(9rEM'l"B.Gz;6$C OЇX씾"<nL=Yk ;8lL\"o>!n1XGyBOJ 4!5B܍[ Yru NHn~iӹ{1P]KBM[ҒZiSqgL,5$ͅ~j&_GZ,j~iٍ 7SJ&5YfS8JXbo7`H&}-H_q,2QԄn&zv}@V/fe둻6[! yD6@1Nޫ"}\[jg+(9װQCȤf(ۧm;̈́İiqN,H{iDod}ܹZY?Qt e~?E?yqqil<_;i%M$fH\ǢSmʒlFu,5FJ'De#[Ӈ {sߘ_Xa K1ZqnȦT2xxJHq"dUa[WV@MOӁH&6ě* 'OtpU7Ui3a'J'DǰLS3pӑs5uⲙn\gXz섰7e Ke"{F֧#ye8'>??O?~7$d,d=q~a ^ǣYIq_w<쇼9z~[J~{`~w&skb= w0 5lX*YvXG퓩gN$b}듍zw!xa{xܓv8ݰtʜ\-0Ԑk)*A$\9`*=95vί* c0e'L4h<ÀCӢ C;2;X]~*c9ͅW0hp+j"V׫6gB4 N7H3:@?jܼ]OI Y D1m \}CBM,Ϻ i>CRp*Aܒ@xH0+,1xB̋gKފyt"\pcxʻa-R6ؓy[LVQJgvBYI f@hؐž3ۉS5>aNe>.- h^}If*⾨BoHg&kpJ̃9(H3-#ZrȪbXO2uE{־ QnDˡIb~vL\B1Vp' /w$T gby835!dj;oVo9Zc -$l,}l7>!ZY^]E"aY{]Hʑ@>gܺu%S =Ԉ(dzr`ڦKcuh."{!j%h=Ox5v98E'htE~k#A:AK6<(H!r{:aPs1˿ONsh#VCEN҂VZڊxXbYy -ȎLY*&θaGq/}FңV"m6&p%$y[扦5:kQOH{CE q>b.$1.R "wB 28J" !]K(ktZ+z>ӯt}Ջ ;_䋯}};Q$6!'+8!BfPX|Stf'nٳ[@ο2zʙFh_;P¹d. w[ϖy3 `ۂ5 /њ5-t2n48~Ni-vZ1 [;BJ G*^^4j1eLk$) K| @mltm})e,:)N2r{q¸i"rɸ2rP)vì]Qm4n}If?(.2{z)~E Mpp-oM<7q/ [Xڸ + .?n)_pbp+OHh2 BgvJ霛0K? ~.J k}39KR^8J͕s4-]cGބt2 9T"cIB%냭7h+Nn.Z2!((Yb GE֤5$0 妹O(";fPoկ>ӕw>/mAKtUHp i6E&% ifhIF|/4.(rmźξnov27N`գCo9z$u%Ԏ%1zp `i;l=f,Xj&ś$RaÁV+45|Wm#Dw=音tn܁9ke.:@gݟ+ʭRoeIۢ±"\[M!x`d8:0[gpXY'Ş) ڛYެge kF3|ST'p2uav02t#bG=ق!m.)|4O$l-}yBZyas 3,ҁyx lz,i/1hHazG ݑ<۶*Z^jBB'NsiJ:$ҁZşB&-O9sGG8Z @-' TR(!B+gKڐGc.A! ܊A\Ab| Yn}ma~8ypv*0W4";^lUa3saדZx,/\_@ĸrPqʑă۞9fY jjDAGFZ(AҔDψ-^cJEmx]FKդJGo5k`D_(7(@wtڤBgv2Guq?+ vqh}){VA9\+2bXޢ̌IDf~D#Gm 9~|2g`\ow>l$..78\rhׯ`Q$*6G&+.-c%y:Gljq?~r:g %F^+ OΈ=b߼g w/gr:wh/&ٔw3Hi+@1i} A)]e t`ˡ;c )Ȯ7@Rto,~5>b#1JG"5 YR 1).0w]PiOwe6Ը}]x滟kt<\M{^`@8,}Q#/Ui{9CZgěW84{xr5hq\8s+\/瑜 H?.דaBDP-0F}xl5e曽D+3em1].V1tvH$E!C#FJņqfM,(ar9}~V,W}@9ùp[3*n4=OٺeVSII_03sp;#0ͬd)6"Vqf1\ )/޺\6&]X/b k/H#UkPgloEյ!ˑB&$Sa3Vqy@ Tf'tȟ{A5AϩOQfd<m &skU>n3J޼ C5p޽ lWSZ';vuÕ"$Jvđą-iH+^rYF-~iS2V"WJ9kӟk59ev:O'D=82(G| !rmd58[GȌWTbgy[PQ-d(l\x0t,s `X^ $x/r8G8c_C\%6Ρh]e>}^ ^cX*f9C$0:fFbN\#Y5Pl0m\im_)m 1FtLת Ѳ9)#~;Ax u>j(?J{ TEf6\VG}6Z!C.&o~{E}XeM=NթN.BbBVfj󅐂O{s| _/y;&f߁\n^Nr[4vd g1bqq(R?EA(vaڣhM"j6Lջ)3ZSz8l.P$ ? X YYDMۘLbu;H4Ƞ'| T}}˚\ (['K2J=LXI$o)+ quE6B`  f@$T4D<+տhEɇGR6/^bV [x}MdT#ůʩSFR %J.x-Mիҫ:]-ZoO}-Aܸrs-y@gCW|Dy5(^@suHL A xT3q*!$ᙋ[ ro,f3ofS+55Hš? T9tDlj͍-+U}%oec8pt> 5ba},.RO:1c0fthcuZŽ+e3(7 }+~@: A.ٺr*c#x:8~eqX9oP΃s͓]FVnbw?/g /oAc5C{U{~(P]hjG hk=;~VnOߋH`[2K(H]MȽ}9oHF <=a"U 5N; x"tI2`#Ԯ~PbEoNw{a n&^vT5"t#z@@p \l2#̄v ٕrRA!&x t[-}ʨr+!C{9bj nC?w x\jw\$z3` Ka#2~B,V]IiY,]e3^uU;ữ>P M1[ `8wEZR?]6!F ۢ\+7-WH+yB@#,\~UcB]@h r +jaJH"؉c3zxHzl 9tF2Bm1\Sqė<7Q^Jє2 Vd>N zi 81/H:Ew/q$8;N;qo:}~C&?m#x <=IFMvԄ)ur"g|=Kqo5kH:"VO玃Ldbc7:Sf*zI8\Wd~_f0Yc:f a'mt$0OzWȀ3^ʀ;̨|X!s_N̺ xd;ͳ2ֳ):r&5f7MvI_?aXk\bi5\gO8 rM>%x0Hws3{s;,\)J`[9\_F_o:DC\tAPlQzlS]|l;cx)u}hZn1I0Hl.#m͘dQT.j6d8M,Hɤn@h"ΝfE JZ%wKpJK&`ds kY&Jg#HJKP6nЭ\x Q/Q\uHJ+Kگ{!'KI2/Ղ\7+!z$g Nkx^KtĞN2vm@6"!PP+x"E)I+pRÖpɵ*V|6>T P@(ߚ1WK4h#j! R-W8Ĺxw/Nr~"ɷ2p W6 s{NTDB"#2REm7AKkZFӣǍyaNtVQo8SW/)^$kcQzn]u49?.Bx'$  O_/F޾͟= ?#Ye].Nflwd՞) }(N8Vot(l޳ψ]yc_HqX_BP4}2C_RHIi1Xbԉ1P/3Q ,n˿Ơ=Irq {ma-3!CƬ%>:_O>Xz 8/Crs|[& | KҦ[z8郵CקUXO=m.u[; Ap )a!,ح>Ţpی8 K. $DF~X/Jm?uٜ* 1h"+ʴ.g0 T&J*qwmreض|>mnf1-1txz٢+2:'c}IED]v^F\u.c%F[ 66͓>tVa/w|ѣ. Taǖ8r ,aד@226< }ÔI IGoAX'>CWz^0-^JJ@@2ccu;7JI"S vckvE'Q/j%=Ci9\>A'M t5D;⍍$u&RT:dk\?d5rE.v!i4QL @COˏ=`s/5PhBUpmmw$^B G6J2|"CNÆ1X`Jc)9 -X [AzT0h)f=;*b A4TT0?;5Zj%ڳ,c_֓#Zǯ2򕞣y/7>71CFTRUMEKi,/p^ נ js)8o~ hN b`d1IYԎS=||M?.ZYn l(Tq~#5d3(uX K?^Vi Cj_gY4~uyo> u6~iTH 4,ih]v9y`3;?/?\mCIw>s-\]  4[L+o#]tJ ]BҋĚb9K:plݜ>ƙQJ[dc2Fݝ%H&+a- \mf8aM@Z[PDixԅ bB'x 8[߂A$iϢ5D9zg$T51 CZI-ikykYJFS.(YZ9?'#(Q.[PRM)^v(M+ QQ9&jӪ>Ti$}>jsq?px 2.2kYwCwg$Ȃ?ؐ^ZjRR~^R8赩;fev7լV y(*B'&v,Jr6 E߫ƿq&}Pe>pw0i!9%+$ErfA0:ZxQ㣜jQ5QX| 4Ej".?MͱvUͲg` i *v=k_NBC4}ks$Ǖa"GtDEdRл#Z.w7bÁʪj8 AT3+}{\߽?<|p4?C?__f0ˬ10ϗ_}wG_o?jz_͹o޿}8~wDWx<|v*6sr=sGs;;/B́A|K-]P?>Zjï83Yc1)c <U FQ8[d+G sWdA9/GA &L >1i('@ TTYJW:o7ޔHV+P,"C~Jg2+鵰`l#PQeW-^-~'"֝D10jǟnC$] FR祠`Ifc2]˒jhn&P\tSHpX_>=`ml/e=2%M j#z|Љs90 H[0IڼeV~nXIvXEp& (ݏgTI(maO&V*<OEͣ w6R˞ qj{‹Ť(sq'h]T5t{὆~;ur-uV肟6,.?@8Fx!Lx5_2EQ'MD1n bVC %?ToG'88QmXJwzJ AGU;!`0y*6#kePFjZ,@ >XbG;;*J#?cTZP84 je΃jS$ހNd(Xn`p^݉Uh鐫=:dpjSmdA+Г*DO9&@2C}K*WSbֆ "N!w{K.>1%v0W%˺V L شЭD0z,'1 ol^i-ԻA刱cPrT[ģyPAMn J)n{ k)Q $^x @6#7@OAWQ<n+h7)gc[zcQ`IrnR-s;XOeX |1݇?x;A"1rT)D±8 G i{g6t7~CZYJ՞+)^FBN0Aށs{xq~Uŋ'yWRo Wbp 0U7 ۽HbԷ<2\6x$Wj  hIh AljM?3 Q3W7ٟ/q??O_b4<(8(yq/8|s 7}eUBfG8b4kmPB [tYgT| PĤ`z;٣LI1{2"e< $'nh;$ƕam'& IKO {W4OF,{K؛5N`NǙI-9A\0AనbP`}ۧ}LuCU8tCWPMG3<^*=X ;IJ~~1X3g%\~~~15'5x"$"y)|yύ6uDp  RV\; RBYX [1.#zr2zsbg,6V:y(j|g ,~.ŀVO^N3oH{8l>ɋ?9|OgsZr.r:\a+hQ_ˋDU?|O_+mwŔyGi\ E5EHDEsJ|p YT˰Ou)@NÛo|C(jb[fBgC .z _PS/jB/=x7U6$-)7˄NB)t앵90DlػbBn Nu3ƠM> 7xd9j}xc6zᗚ  8Bdz$(YC6$;~]8Y G[׆oW;|o8/yʨ̳w QHHs%̟7@ɑvrj$~;ɏp( . ge!x]Y\!6 բx=<6<`ku% vc.֠eUHCvAŠV9 0 R֠`3- E3ZZEDP, 5^aDbw7UL1SnJOR& ÄqוN9M8i$6-<#Nn`k= 0u;@,$hkV}O`:;!ybHkŽBO;nƷN/x){s O `ƀ,*v?Q,a_8>=E;/+S k{rŮ|xɫW%0 q"9S+bBa*"jQ!*Ս&+ORC K*a<԰t7=R12 (L896EPZݺr @vE0`L^.?:Ug%Fc_8uM5u8צ:&[Y!gBJ|lhx4$l|#be8RR.d^`$ch_J:Y;*R3U)U)S\Ey0TU_ؤ\`ưT3ki$ 7[>%VȮ W#GQ-Vʮw9Z2L=^oơ>S|= d }7ˆHȢ4mdW/զ 7t9যIH%9mսT\iT>/; TCW@C8FGVÓ@Rc;an)r) .h][YW D$x%ภŠLXÉs"šte$hDѳ"i'XΦwzճq"UtР `DZҺ(Pȭf-;;tX;"1$ _\ViK DH֏w [ 226J-/XRN*d0;g @kwo^{hY+*f>_'jZxt&tn'}}>$aKĥ9͝k ţ0Gs׭Hºh/RVxXړIb/@,~|]px<%+ };4'Zw|CiJ}_?1fJ6N.9on/y=̎ +S)F3%T #FE yU+g1 ? 1j_ FN)'׸$Z yhZy3n%Uj|`}w,`uK@N s)eN_؈S@<} JA%p0R5Bv' %)_U[$0:OruIé}gC_UqS^J2vJޑnq;S>t +iY{5)oJ0>O9@zljTg CK*Z7vb8|D d hU7:-!m+T3d~D澸tԄi# D}k3v Hv_F[mW{ߒVLܴtb&L_}R %}m9V j%VXD ! =U9 JXQcQ @4_ yF'lόfb Hw ^ *YԢ勺Ib jqj;>}IJ&vy?fdzS-UyK.ZSHjuyXPuzJZ6THfs3V"i<pN&jXhJ ;Eվ);u*M#+{uIOξ@[sEpo '3B=xW_2W*!*HAv1Np$j-ocmOc\YwH1R RICv%?}72A=0.;G5q\ ҳKV C.c[;\'b m(Btm >J'Ԓ/aϛK{)\da~56,P L T)U3oUG_PlY/6}}\cCv!Qd[;21[Nᝓ;o?]oO M4MmoӊyuoMuRÏB! 8%gǖ m)m_O- 9b1'Z uCL;T(1J  Q:bM=v-,fsSq &OLZrbsǪeYAmL~ở?ㇿ|OO b̒],t ueI ϏT"@7Dx#rqx^^;}Es1"9|N͔þyX1r`7Շxjt`A}<9#l' yg":_nvIX9ʠ!y>}~{>yç;@_<^+U3M?'-z?.q*.<AF; [oU*#{`lXZB3AP~+k*w'bXg>%~{}'dyOyk 4JAi<$e0wX6j kɲ)`]|lC )NO}ɪZ5 @ 35Yյp:eaM қ`I,=xS^&ǖE.-fUo N3NR͠f~STӺ:6VQ":4H;ZuO1" @%-ĭq83۴6S u{WqHZ%q)`m]#f)`dl*yP2esy ƒ(-' Tsg vk3xҍ 0*-r(˛\Pm~@I?PGgo0m|)?Մ9g ws2 ߹n{ybW?v\Lڣ3x6߈睜gfJ㥦rn%`NI*$^; &CޏCuC r)JW7y͔is3㏏ЉVjKJ[ ×[ؒvh?׏h6;1܇xǹRAHp-zJIb]u@;HO,u6{ѭi^n:k|a-#Hue'8{Sڬ%bx&ޥp'[pOM؛g^1?~ǧLv\Ч2 X;D,, (Ył2Y $ZQ$נ+eK7|-3QsPkv[.t˷ӏ>|oޔzFKp6mie'DuE M.m$B즜d7uAOj:Ձ-kyAu3V3y[-d-g kmj#l ',ۊ!ZAs?LIcRݯII/ܴ=|, ZTfekDLAyS:P!24|I{\Dx얆[)Ʈ g3,au4tR6XZ=^12)W}CmSTMHt`r' mG[}cEDV?iXm;h!41aDPT6x#5,.af#)Ց l$8P0C@6c'8kkD`,μZ0ʩ8+PkXjJlK;S U[j0 j.W ``""۞d ɕbsu<#4sa(?u=7af(آSkN'5X`? j!JNnj$s"Fh.g{z:p6b\qڂsz5$Md鄌T(cQhOMr.%21pKƂi>ܭ@7(hDGXJL`ylХq:%t3 =Ex7bS*o;r-;E m{mkv⌞s;kO=ަ >4[/6BC1}Y#Ǒs&hfXQ;O.DizfP?~<TGGw{W|/^g_:x:|燿}/yשּׂs.w?wû姟;|G/z}-?~}#+?a:dd֦N׽} ovAe&˞Gzx Qb 9_vw#|}1V^ؒ8ḫ9@s ݝUBUw΁Q فG=CO?"'۲oZ sRkA#f;^N44ԚAv cĒ/((3g!i,֌LYV[O6Q|ajP7ą]N Q'fRo# QD]6|\mVȔ{<ǞmK’-I/-.dZnIޒ YZ3÷;{{NOؖJ%Uaip{ @+m5] 9~,L÷vEӼD哰YSފ5%T`pg3π~YgŦ&}!i̪;xe-*x@h %Ylu딧*//'CDd jWi{=2`B40aYkqvc5N`E[Qf Xl[B""+š.wyo&$ʪ(y|BnِoCDYq> R+0$^EKBG1* Dp *JW8{QQyAMZݙRZ_hct0=۟K'VŎU㐌V4~7" i({63gn%o+  {c3O23txgS<h\Grz.8y#ۏCd@\yF\uJKgi*H1L /ާ<;Ƴ(mW9YX?x޿S.A3kpx%"*VI!18&rǸ3by IcX*scKVl~'ٛ!YfbjE-,>oRXGNIaV+nRC,%7^R" GrikVHYQv2ُ81$58-n!/gL}秇G o Y%)cZWs|xY&ӛxR%SG/39塇i[j~4EX! 羆Ie`71bj1\X[J k~wo}?> 5Zp(sQXhEW9+sꪕFXXĖt,d+hJnKX3f؁l3eln+ h*쨄¤Ι:b 8sRldЙ>}Fٕ0X맗w%oK} !-~0# o)} ^@9^ x6F51iZFX-ɁCLΫE4FVOvzwR<f"LF4E+&=Yr`6BdRWvPȫ= [MJ֘8>%DޟslQksL^Ǡ % Z}9](+5bՊmaN5w(=Q͌sAF- xlM0lDk~r1SQB\]LMrٚN1qP x.UT鸞z rWjKJ0-OW0gPp@"Hlofu:RRO,?N#͂-}SDœTW[*, z82sZ*QV5Eq6[Laj+.P8 tn|a,]³ʡ@LQ]w6׊)Uo ) .zR Xss/u#y 2,I7/<2-gG=9O΍p9K5h2 rrDARWvݖfp: .0oxVDvz~j:m,;i+Óo}?K~}{a"1Uʳx<7" 䠞Dnq ԐFx>u__@ߘJ Pa$KZz< WG) x³U%^>. #̨sdK٨?m]Fk*|]7I!E &ǾCF}ik]G8QE+2a.-_#nͦp.k %N!1sL0<}{yCK㑪˧ӕgsc 2! 1Na!l9i]<;w|b}9wz}:FQRPŧӢ>hAG^$yh6]-I8 C3!W=GZ<|[đS'qkP8ƚqp>!sϼLrjr1\LCCu+'iקʁj0DlO5#>Mߞϱryƒ>O aOę#E=&v}59[|I"oOz_/,(e1d4fox*49.4X6/E48 8 ;&"  "UgXdjq] L|[kߊTFdgeM[&"HڞR5pWaӄ)x@_<ΔJƥjQ5<< |yO3ҧQ5;a r_LT y51BLD`%Sհ1gy^k9rKYc}H0̘t' Y>3j7 /{FLjC)Z6[mqd'b3p@ Q/|+Ė/$ O҄))Fk$iv3o [C~#&50d w#JAcnl'G+q0`tl(nǯLއYyxE#Q3ӏ3K񻛊SI3"50 ZC cT8%yG)ΚS@D2M./ke ZBjtӋQqXPz<\u\'qq5dteivmV+S z̖א\y&!MQYO}s̚ïp\]>Yۜ5DFo7_BD>^YIG2FMv ^k/iʈAd18g(n;gSBvfR8'G +&+ɹd)1W,`hbCf5&81.pئO !P0dԆ$F{mUt&k4L ṡUo p@]ma*V/d Б.DK lǝOO%N t]*"CeZ,[bl&bY!<|%u72+ MOΙfN*9nO,vS.j`~)QfIKGUM 2/=}LhܓkZEF( l%;I%d¦bzesdwWG0[mSL2yd\d8dRW$ (T\!$tJE$RP d|"-oo诡W2Eu(œ&߂UI%J)(PoKPpp.nrV}~ Q#fht>FO3Gf3~p0DWIVK -Bn)Ucz]cx050%RMʹ&z@ay<1t+(sjfN^0g|=&{IyJeZ'{,~Fj4W׭uhp£Ϯ 78$˲D{HDFⰅh캉Qa1AMS ?^B}ll1AʜQW!1O;Zz(Tei` tFfT5R密7bR<32-+#mDWBt2!nߞ)S,~0;RE*oׇo T~(*_HNd,^:S̆ +8tptvxyC4C7ܳ zY6=T4Y3hGPxQR)7YAs”lk" AHF5jz*JLdK&F ^~cǕ5A(1Fl[|D)r$JסD.j]i3X%jLFx#5 }g -A6/G2-1HJU8I-g7X?}`"\O2{:ZOjb>JZ}04GuJɎ <h44C9M'{UŖNe<;>`[ );52hJe ȏˣ$Vԩz{JF܀.ׂ4p2Y =Y 40Ӷ,)0 gokLSƢ.3ӨZU{(E֢3o|yp~me<> Z/yȦ*:&T3ϰm|Yxf)P50 wK?D<CUOiJ~e YV:lX\[۴ HpƂQ.K O^#Z p AV̙InG}ZjPyוIETEbI5kdK=UC[C[o=3%Xvxf0ht(+\K.jkes@HeX SG +LP ɉ%դwMv{ljj*9Ü7\yizB"[Ibu<nκUϯR)g:byoG .71?R1od)z'0@u4G/gQnQ{Ш`6Jˣ$v`[Jмw o#zflDurX^d !z'0^SBb !~?px0,E8NVOvRP6Ƥ M^f=E3.7ÏM;ee5oZO-}iXM֚Vwlu\ZuH8Z /;)I >3ǭí2-X s3ç_#c&9*[|zTM9.2]Cƺ>U-MMūtyYzYc%\yL0Nk%45վĂLOs?AevN5IF8x1 [_x):od?%)L $an0i8ny.qkQ lnQ#ac_S^ElZ+ef9"l1TOmRVF#*~ޗ>8f;Kw M# eQ㯵M{Pղ[8[gOd(g@.uslG( Sd$96{3JI5KXM5CVY{J">=x{n#:|??׿%v }cMoĈ .Z " X jrRZ4EOt=('eAco jˆ<3(®~bhd!Ŧh\+`Gw S^ߤ7Q708LH;^"Dz}!23)C|pn""&j $#.}gXjD~ Gz#.n/ApV 39UD/YXGׄɃ}?E囥޻wᨧ|Dΰx! 39e{-? i L>[qu.稷*K¬eXF x3UMh_sod_x̆s ;`|=YJBF3‰ʨdϨj1I8+\Lg³𨅘;j@}%4;/~}˷/)'NaOÅ/źDzʗLhuI@}U별$ .Z' l&fFmeUK0ygQffLaOhYezMi)MpaBK[PzN3@7SRTmoE4le֖8ucp1pQ+aAzxIj@s!!;1ۣ}쇒sO"uhn0C=LHKe:Qud+υwy{9ݨ5B[]zn5ck L=<9`ٳLǧFRY!SrOami:Je6}ƾG3Km4KK,?hYmz+=ɽISһFkG/KѾ[sG6:ؙ$ Kjq u}jE㻾*+dclӚIT .KmHf'gVN1HDYrZjYm-O?;pwOؚlBx:”b0Y0^._UdʪEr-1%{uL0HÙqHL؄RT鰁3FΰUoVAg*agQ0þy fv/S-rB,#L';%O~e$eBd DlpnmʒT{zᵫs=`WP6Ћ,󃷫Wo x' ;h ۮTyD2ʣ{@u_GJS\85` ނ0S)GIYkC!jGTWT0A\#=j AA|}16s;aͅz(y{ٺ꺁L9CdIU?~ СF:W :`gLƫ処!M2&hpd5vMό{y8}"guޒ:o=ZCov-oF{@Ou4ɛz QI/opjfmk}5/ϴ]`i>SIw.tz'ɭ^;{wKqDK'Z4x:'j:#t ~e6z\6gr~Sdv,}s̝ph^щ~`ew=Κ號tՕwyi'EtG؆ V]Wn%4Gtd"iSwu!t$npbUNN?ua.OSؒ[_P#GЁ:vNΤONGu>̧Eׅ$5G 2T vyݮ$89֐}KQ+_z̓9q";|t71vV'RԔ}7HIŔz`gxy, 1 qZ;Ps!TI ݕr!(2vs>׿jF5OyÓJF jڈ!zXw Zj/f:KYRN>R4:ܵNRR+v +DѮ])—s/jItIjw&,ꡀ_t Ƣ rPuUg-B~o*X]~B4ϙ[CYHj@ SZl+3L_+ܱ\sVGƌ#[D07k(DKo+-9B`e[[tB[\E|(vbW-,,:=@{Ys@x.Rk]u̕9zӻ_4/9o_Vȕr;7]Rq} |%,?PB"`E S 3~"F e~ exï5-8r Wwت%y8/ K#L'ڋ#׺I 2HzIN],NoRoҲ.E\5'VF̢,…>Im"LfP2!)Z~1Ҟ[ NL ž*h)#dʐ`,]mpn^WCǗ6l .!Qa.)XD6]iI}J,vy!%k Hۇ󣵠t+WؚjrtF0Beæl%2v72RfJs_NiEi]χv"F,LO_/8MS٧jyǞsZU" D `,ID5\4afv[L&!X. /VW2BLU9 sGa0c.Zf:ZC'ĶlLl6$ n37L1X.Ǖ y7>SbR,<,3Qb{)aR0.懬dw{2OF">gN&8nrWn2$?\0!>AUFx1U_BPxI]Eq($'%kBNHw"es_OV\dN4kDa/Bd<HբBDg W>?:57Sz Oje|KEG vv|cc-uZCل p%GDZZ-XyYcnV@mKx=|O SZb,̺E% .~yo7]݄8C7BAv3g`R{ BxF,= 1 qe;O,?5+66k=Md#xc&6uTkqk޲T?f`p<@)@A/2F;3 AqE"dRc_EP6e mɾ@iX76W`PW9C/e޿ܟQ:.ߢp%+Wb0@j# ;bok҅KMB } rEto^.9 ⦂7%5k\؛1Г ^aOY [`zey#S΁:9_1BCe0}k#qg1|Ro7;3'AV,xfUEvv3͞fT2*2ޏ|'k_f.Gt?ӷw/E~_? ~qޟ~?.)Myѹ5evާx ;PJRp] Е^˻ciwo_Yl73䚞o>|h~~'T iԽuf/|߬XXPb{^ ] oӕ L䌱__ aK ;͑7u<ˉ ~m?|Y,>˯tޙZ'g /O;TMڇ`;O!7GpI,O\섞=9#LmR0 %1ʂ$GirJ$NEz4QY6}㵔80'W}_WVT**b) ꃟ<<=/Z*D-%&:vD%O`byJ0 9s9aeZ%Fv5IJ:7_3o[F*"nc;335 w7_6S-==Ε#os-_}BvwBel[94 G 9.2ek@وYhw'|VnR^_ $}F&-cxpќmdz5(dpaK!"[ߑik4=U_qe)X[ \RG.'='XbڑS*V$^)'RJH5$q&Aq!ĆOVo>קxL2<, + XUer4Tyh/$4F-!NƟSWz6!n.&76*xyH„7xa#WM=8!u){+ąj 6'Z95OgQ^6F! e\%aÙ˕_tcOvpƹ1`SRorQ}r,s^%e-WB5(%=F硫Փ-* ~poǶ=F bfFqV}-$1O5LW"GͨѐHj:EvUWd͘J|R_kZEMmoe{cՕ^0@ן ߞFC8k$ 90kfHZsL:=5[^ S/Y;=I7,s6ͪT~YhxM񧞘ޘ¦mC!.Qa_mNW1"@rpupsĐ'۶෫uU;i k?)1:pGrk,SsY@W%Pfp'g|ȁV9PJ';فzƻKn1u9Xq_)8Z_GmA_QPec-A) \:]}]XvbSnBRuuL+#0[LbQOBt }DTez d':e[(,@уVMzpő3|'S|_<}3]A r6bF): )!>5M\H҂_M2B(Dezt5ř x}d\dɑ&OxV,ӤD)P-_"-΋)MH-G9Knq|_X_j 瘡;SAJz_VgP +ߨUQR0Rgj2/Wg6:k߼oY"%st<z|q^(st/ rn%fgK!睎},K1\CL n ~ӫ!‘~~(je h%L[29i?H=E;8Ur ,e>oGR5m3c:eo]M^@~j4ą'w k n"tAdb 5[mC"\҅6 y6Y"y6kPFFh^ AzZ48\;ch4:l';~ĠrV.9Y]|g+o`&G%LnkC՚ Z{ %-1Q#= X. \0y=-b*)|kk4دlJZza봰RTZWB-15K 0RFeCב%1+MVo݄EX`ݧT2eWPh&nL\RjH.݇\=c=Kll\M߬;+`$k vE& 8'Y N%=(ETPCE_2A 'ւlA̎?ӹga<5Z^jw,9;ppmbz)؀2fpSrF%PF1 ʫ$ Ԇ5@)59Gv<߮_#p.$3S"]r K,"Y-M5ՠ6, DO9U0jT7&pWLqԛr3"*K 8[\N=}@ʫ qjɅq3Qaۆli_SH\{p׵TxL E9-vչR@̎V6qpA_%^N/"f8-֩Q~^K%RǟBߖ ɏ6 C)ڢwԖ5Vn&bχ?/}~og4L|?R:9&G|{rߠ $؃om@ [;g> #)!Y]w&GT{jn\7(C&%yȾ](%x +'9!BVsER0=%ۑCOg$*p@93#WGH%Ѕ 3)AI ֐Tq4AR;Ł\0v$\)$u.Y@LTb3?3mQp?~*SP( K%머Η .fה['J=a;T=)`(R  Q, D=_,"٩lc:p_ 9tzkrT輭tHOOu5|#jE)TG4{f:N` eOќ87Ve Az(H# pW0% pnfiϱ\=Ԉ% FL,&Z"2Jѧ-]52Z sd9nFy|Xu£Z(=6kcLdX'ڋ.Vp2)tp岱u|(O<#iZ`FI.B GJ31cfϥ f婎G{"Xi̅M\E8KKO qÆ`&_*=v;oMxD<-Fyq9ڸ-(߭4k49sxN ÂNNkk:e# h-o#F%%)F"T^ny_ XA5bYwX-P 9\eY7 7%_tIke${pm&yǓ@x91.\G@RBT _czE!8fu3}$i5p<{Z`;*~utƄC6gHct͎q_ ϟ돟ϟ:|s `97`T\{ojd7L(SBD@zD?1K`5{a)_&C`Fb$=G= c1<{4-tVN!P A1vv؜p]37ǓYX2uwKi6&ߤW}Y|f|:k7Uj[4Z4FT&]XR0EI{6\H;%z=Ht{?I&cw^ٱEN`p\ŢOlff֥)_1X$`UGjx9]ѱAӑaYy ſXn#+Ǚ9%-c@XoTZVu LQK=P;e\hB&wz!mzbqDMA0|#_@!8']8@T">kl(jG2\R[O LA<3Ă J ؚAN0ZumP`xDt=ELcZLr k E'c.W?B_oӬccW‚мn6L#=| `H/j D-)eq“|,p޵rAR՝S==` <_:/TBOFE .%Dݾ=*MDygOÒ.FX%%9" KȄG(?56`لGzSߞxRdB=+ :00gh8H>:~P׆w zHLg)9 2 >J&.>g#,}K뼡,~IywxU΢4&;yָ'Z <ȮgGf|<<2/'DžƱL9,~ܯDwĻH R恟N횈zO]4s̮نZ$ ґyWvS2~38X k;M6 +gDܛv߽UBtFH:o9(L ]}<;o#}C ᤟ͯ:pa{Gdi/},dX !MvWvHYљV]rbAJYhpGt׈TN*pWH.IwzdUX?d2">~$ T߸Ib)s&:?|Y;BzfbRgJw(W'%=rc3& J /֮-{GQVeI}8JRHi;?JO.IVrar_|SXG#[EK&x|>Ig=xbȦ];57Mb&61ɓhW[Bгp8#g>֓='[G Yڱ-’nڱM}| 2:<{>_|3M}dD+n $TS`e&p1mm7خg\+m+`n$mR,ROtquvj͉Lbu8@0'rkя ^4ypVinK-3| )񽼇.`jH ȼ[4Yc&WD)I*N ' ˔m,3۴} m9Xx{]j$.*(we-6 ~NL'*I.LmZ}H8c= 3:QLV_ .RbNrQZD)Z(<-CԖA&uQQa IYm=| v:ub)?B*DkS䋥)NTޝt]]`tzνdll_CL=w/E3g4{2OF]g!T0^'Jg҇; {Nh#Wt{J;.~o̒lh0O躋d]-|kV^'_/)4Qb{K- `\p:R`mvs`ӟ(𣏬6kl$FJ'C,=j j${Frt5뎪zmĻC.`ҳQnJI6?(Gn>֝HA9떫`3+#ǬO*P;tCٸJ3FNUT.F$ck WVvn[]^7J5#e3}Fd]%;2]-}zzSmgqO>#cHI(Yg,qSU.^z=A)2>% t!t^zQQx Xtl{apz|]'8й{Y%:`j6gWKM=p+fͽ LQ;='>920[bM7KXqw\ 7=\_ *6hZDRĖ~? ZyqT=P%Wz&7+\t9!{Ah) >p~IwÏ:n]rٻAj\Xhn^]tB5$ ²NQy؟s@e,A G4ªkt l83U>| ۙeU$8Ac[@cXdD GkP- n?Ac{^ 8D+W = c[ŚZW88|efVy(M]c3XP||]ܤShzƈ dxNWuC98~pcHz=3633~tJ̆Fq &om>Q'*xfy@=de!)jv|bb'J~Ə'82v؃΂l+wf'w 0@Z/xbVw3E珛];3|8TADR ^#`+C5o4;$l:/fEŃq#lp2gaz2QW כbb&Qz=:h[AL+vݷ[ r1@E6H$zP[LrݼF7$UTKËq-}'=v Gugze}ܼܕ_7,ւ;/# XV˽WNZmkGcrJ@jE~oql{E`ME݅uzhvi`71ßw= hzzak.6ൺ߲&2?o`4i- Xx4As"\<$n@[pH`flM{6铣 -hy"x _V(:EQ:уƈ{O@DU%(%ȜIX~y)Yj$&ܲ c' ^3 ҠeGG>YBOWDBpUlMI#0̳/qG&Yݚc),#ZyqW4z^jh~|ct~؟. ۟n[\Q#G"Rw9"`dG=5@DX4R" 6 [sKuxq;0!"gI~8 e;:`{Y_: OK3bt;`AXxT1CZ1RZusFT !5)HZtRCLgECo!a=<חsHm +'n'aa^0Ah}v骉x4A]C t:2z&)~<ٙI(\۞AĖ,!rԨUP`BC/}[q3Ce5~vA#ZrO'alIPl߼ V49ݪ.MqnyefJ!|z: 3<>Oᄑ|~;}S _d}? 'or?y~/ÿH[~~'/ҟ՟/=|JKb\zKOs3K35'vEՠ Oo~7; 7? 1OW#wnәz9?O/[~z~GR ɷp)uΧ>eڼô;9يΙUxE6>r39=c3 Rޙ,M7ʗWl252 &EC}CllpY!%m͉)+|G;|= O w0/zhȖ'>&;uk'v7XYK.H6\ʝK1~ABWy^k/7jͷW&t>9قLk,'X&Dffkn}// ,,0y4 <ɗ2ҵ)5҄bk1n< 3;Gj9g pG7+ѽͽP9 ؒ ߳Wl- .$ht6y|bbJEs|1shIPTNkS śU:Cb;HB[@,Ɨ.X#9*Z1fFr&i;E"rNE9@ :F{!c >hR s&&H# 291ap*ށS PZ b]EO[UaBy.9W M fmuOa>4 .@?,B]H3w&S:| ˄c]cjTuul V/_ćeBV "~ъ*JnʋmQFyևV)oHWkA).㗍퀃WomEn/sms+E]#j7[aXf_Ѱ"$cCH1A X*n;^F`añ_jWyYEjTQp[hL(bx-6u9!4(8J K1)PNF!jF)ԇɭSwvq4% yT\?iujxnFzLK-bK.$1 s{&3N)!F g`_I*q5 !>OslLBϻMncˁl8s B։lRa1Q 5#qpwQt{Pٗ3Q;191M*wvqc2 m:p&`?l̠zWx,dtgYpw o-6}j{{/~_%ђq`hfWL$Bsj΅΂6 #M_vj6/n3'=~vB ^+kqd$lA{)*9Nv41Uj9m`nF"؏.{jjA+ALԥ /"sb2g_G l *D5Cldw,w[!/!88A/m&`@ WVK/{Ys@S>.ζhO½LLlTl]*P*t,D#A[|,+bcÌ] t8yNuBK^W#X{Dap.zZ|GXnnmv/wуe-Ȣ U5H%Hgzɒr20`zOEcЌ.fibpi~߹,] U܇V ް""WGYc֯ _/ܹ6xC0Ur`tH̉\N('? 4@ї:zx9>[k#kwXN4Of^T1ks7\c`iR <|tխcDdh{`x] ,u #y+٤9Ւ̈́W!iw ss ܂1CY2N6O;9ֈ̉,1?DRŎڨD'Q @*4Gv:(٘Cv:׸Q^+ݦ<$( ;8.q+9L8|m tEBPD`]nϤz۹{Te%?ATF66]߁Vb;Da;BR#347eLJNAR%?XLdZ_}D41#+K{dZ7C*&^wp;h@, C \mŤ4I]*OmDo&65pV1hL_8|'똓PYVMxlb7UcOh..P޵xxKW#&xp3Y I(#ـ`c NjݷFLWI綟17-uoa#$_ߢ%騨bdkTS?샵w0ldջtwA b9ǨbkVίF8;*iK9J&0Ti@8]i )+< 1.?payl[keؖWP:յ= -}y\& fvo9HH{Х̑.uw t򮫻``5zwDPV@u-Rh\EHT -'΄jTA}#bJDhsg7,@ZQ*}-'}mDQ v ˆdDz!sbH ?ڛȦgv鎗Yp4mD7U1@^=[{r|H6 X!JL0ȗ%t^&,.~A4;>0.ຈךSY=Ԇ)QQM-jC,95bdHZYF\EKf漡|;oA'$َ p)(?;5f(ÂNY1 [Xc#k|ge?I|k%}9zw8x..bAlFXCӷz2"u*3rPke4ųPtco?A fCA1LZDKT !2Z&u5*ej,uFvrl xV1CLVW4FP抧x". N`l冶\yZ^btWdL)]IA,7B# zDZ2Y Dԃ.;L" MȦINi _F An -XD8M9| _ǍТɁ&py"X4h␿a"a qؤ(eȼ5ab4Z3>TJ`&(5Bޙ^:;/}"Fs?h9ɱl trǦZ܃^M`lAOzDֆ®t)% 4:%-nm1lݽYqL(0x4,#h-]J4\K;%1n{A ; vgrM86XP nrՆ3^ƽ89e^>; ^Z7ҟ""bΏWL$*OJLZN&xqD' l+L' 9D;l-AJjLȣh1\=rG"Q핥jJX{C _%mBjbF8Tx RNýA+ JTk-+46' MP{u9¬)5/obFbgE>>'Nyr=`QAsaIDa55OuG.рxH个]`"`[D 91hs-UQMO^L.;(h, k0e~)}24BF%14 `VQ"Y'i(8:#z0oB$k xXJ"dBB9Y+ReDO+b6Bʬ=¯% JKFX\/9V}xB2!-GFL6n溥XmTӴ[swXф⃂?%v֮q#O/_FLE)Ѫ2o3Քڣ>_WVVDjMʈUS!UtUEϸ9yURqFXJyv>fh+S D5:+QDLZ_3;ŦZ`?Qnk-(`vs\6P62E3Q6?f5a)CbWVds4)Yv8ظQEs$/--i`JyZ\J3,z2`39<$V+o:\P:ȞU 11J.{YBFWT{qB70& k\GqT- LHLs|%eಸ #pB1Cd/(c^ԛ#jcᑋZ7'9S&Ld8$J%\#RTfˤpr2skۻ-V3Ru=_4kѸ>2GmCb@f }XHS< w>{jCCy0_ma7;<%[A {C6 unCUJL@^- ;NnHFFe&Hf½`=p玄gIp ۊAÖMRaMQ&YyeڴQl*Q&\L>*nDk c5~\suv<_k-KJsw^Xc'`av1*RdOӪTI#d3M-[hR)}XͿDY|M1+kuW+KU3s"x2 *-$7V dsVCU_,s(y_bř,VU9<[;R] :>g(Zע!>ݭɳ Lj 5bӝL= ZEx`jaЁ"rh vrqsͯc٤) p ? Q/@xaj I+ {k|A9!աFBSb%k/c}/!uAmX*Fg;%v! s)0cʕJ( +@prig k*y.C,eV>a7A/ȥBuY4mz=FVo a}ҝN:hK.Ee4߹#f)L+Al,[QB@Ehnnweqi>+xyuOiD+Fuzd®&6Q Mv{43%_ ]8hK:MEHV[.$`!(x >%wL2nӭ&E- a?K K NZRn6VKQ3kf@,,M-7ɚǛIrq]O o0Rf)qb-< yi1ЂTYj5hgZ)XVfs+ *צݖ68RLNvV6 !jP3;CE ͺ tQEc52jCaC4k8'e#'B݀0qL6U&Hy?_߼\%gSD̀'"S֕gv0 Ǎ{ SrTkp} -|LCr1b 14y1[Fea2%d ][AOM4vRÐ"$1)#ᅊ.'f}wˋ$oOBgOۙ5N26US˝y1'cI]ŢydL4T?W>ao18 O~oͫ_!1#oW5dfl/޵*8OX717i1 b&VW 66y,SoJ),Sh s;B(9,+sXy)hnr%e1Fc.T>rօFgNL #1_}=|&&s')tX@PiUaNymI! g8(mō**4*!7kqL1V/fZE8[uEsHuŌsMud:DaPHBƊY&-^Fj6v|l9(3t@c&L ¹\_ȎBu!B8~ͻmO8 Y͗O'l*@`騶{VڳZE R璍. D(}r  Tqj;K3W%=5_5:StA0e>/W8QqXt.Z#{'IqŻ$h=Z{>-Tź$q;,`кl,Emq-vzB,aZ$6/-X&V tiwfMRML\=.])[׮C}{vڅ|}-e:XM[z#nGHnL`u^P Rl(FfYNVpZ^8GL>iH3A'i.3ɉ 3\QW+7UO;fR06w3w!pSD GpX f#ehuJx` -ͶƠKQZ],GV/FsF] pAA]7;fE"~;c|f"5WQrѠeaԲ,pPWs EPM Ի5G'fX/+ A[ݪpUq*:h+ Y`!\EzҴE!wYX-脐:e5\t X{T>>XjJMK%>Qi^2 ֤|\iUNkNɹj5̹TVݮkhn'g++ KEv$-etJou0iSm֣Z~}Qxר˪U^XC-Zbuc|@1$ m~{Lb"{Xq6yKiis(o lb-xS.s]ԇM5-$ae4NyH98u; f*nTmRXdtCk.QvӾG [Z02U;h)ay3F}P ,`~@}ϑ=d1+?&Ӿ K{f `="ڄM4'K3'Ɯ ܦși~WF@q3-^ ZQcqgQIXBt/ӽ::퓵3:!tۚbSp0@!40:nNpщ(?#P̄7<_uom*Zlc t|x\'wn/}pM_=kzo^kC{~>>OCo92xp]%]b7FyvlgSt` >6<34 Do=ұjvQQ=a]iw^AJ18Wݻ(-FS8AWGwBGr9n|]>i&,*"]ټ6-p,tJ>ۖV!fb?aƼX_U+e=1GӫY*R <QH~v'IY9u@go )Aʖ3Hԗ,Nh|zW/(#9VaYX㚴t+sg˚=wBU <x^>tC䐪'M `ɔE ,Ag4 NPJ,'Wo]'s4:GFBdy6G9_ջzbgH||bHo%8]6t*$p #hy4X&z#ԍT A4j951eԢt9|H{}H.XWd1̪&%p-qoXeˏ{-EgXuEe)*:(!9" FuoZ* Li5UN?RPqgx`O@7ARQJM*jVr?xb&!xW)C;HT;~?l"ᡆG$1/X#4 x1#UXEӞtXp {zhV0L|-mNI9y6QĹ8%RW՝Ko..djK+-ZCh[u^J.b5Eb,5pA썅P<5J%߾dryA~qO嗴ttm^pNKTN o"pŘ.сמbb)gi\̩ѡW4Xb]QL#!]~`mwJ A/MʆqK4۶e#(Q< D\JV`"kVHm[dG2i5T mlړdBWv{`FnQ.im'ص7r!2}:2̙ 2sg9'D1"lJ|]Q̒P 7Ք U,"XYR|qκs]8G2w2;޺yGgrjSS.2*s7Ws;VXJexj3筻:#8 )MQYVa>,ٗX{uvﺴT*2ZȟK^L{p=Mȵcd>t zJ!E{ir j|㵁[ ;vX4[]U{CZ_1cL')z:F =kh1J9ؒD_fJV ]tȕ1b[aXj%nnJ]#B-ʚ[ϖi.% 8RE["~//OOBnr#GG49}nxY蠚s0Ksëpv1D(Ϗd??;[X M54˴7ix{90J_K>|*yEttL1PEKS~ks %fi #*X;T&ic$VB!FŽ1kO_7cb}ѕӕ+fW*-+Qz ʬ*Rl咃nR@n!+plbm]wε@IópIg"}>(NDoKrv"e"T!xN^4%(QtItAIt,5QШڽΧzyL4xtßMv~~e.VKz޾ _?o=P1{J):g֍g0.`4O] Xn`sx `g# 6 R-,]"Y$az H~C\uG [Ͳ=Xpl#Vc4n O&OY@:4 3(gPrc~}Ӗb$p)T7rc$Ma>e,mڸ[T!*5J $ ufIBc!;S3Bezu*$rt@kֺ&3)UPٶط_(!cV! 0cZLbVHEYQ5g1qR$ cF#08웩C6&7Q`Ϥ!ͬ{JK'@#)Nd5sp$d(Pu32It+ihuKN4}AJJvqV(X5Q,D񰒊9Q0XYT+!{sV\RK:^{HȨjMyܤ#oy1mOO̴Tf-J!<9- s$o$fpPzүIn+Xh&zSZ8dNuB$t)0@R߅r'.T&/%9Eqm[Ǥg)G^;Ag(Et#"SE2iT$ʁ|O^a*T =)LEzM{8(0l'^ЋDD'\a"j IRuUZP61gpR""rZ~/ulk51H.eHnAH73[#[/XE m\ Zr(B\D!>B҄l&58}ŀQ`wRFS0)>Kܔ(ӕk!L^?^4%|۔JŶ]b &ٮPQf^Φo*u0rejka]Q3F讜>θPzMK$fO9L.ޖz(9 @ᖉh5"[.\B6u9L2X$ RJK,GDI lj`N"`iqH8rmΑnFi.NJ٫\Y ?,N X&"tjMFvz'onU{ΐ HTU=eIv4ӕq2LSCèFL&IQY UrnӥzN:U.+8̶Jd i\h:řdsL89qˮv21WfY6Zi2/Ιj%Ch8Y 2uBJƓX6=pT43̀E37uaKrLυEU-\U" ̭F!$gUL J 7 tQ6J%&Iq~h >ͣJ҃lGh͑F@~c\ ;_XlaBL .~~v5Y9drElȯcAϰ6ٌj염]*CK\X"LcbܠVvaި*DM,A' Op {,G'zm1>eG.,՗^ n öΣCۮ_w&8qLVq S)tȫK49p"!_" _&,epe䯘4p|~+Zc1{Hמ̒âr E*t JrHwa]حL<2'=ƠSu($! Vuw __hG0ğ ˃:9rQsMU3'43_R4:&>b̚6%\DV>^:oro۽m 9(\u:/=.Rk]*/Ȟ+G,3*S .ov<[=uuȆGh,{r ]ǝ%AoWF_}_A:ڝy5l;H V /?lIk]"篖W9sgx ȇ9{A(&Kɪ14x5QhXM ZRxR Elte-SQmb}_"c:G^tקO0뚠"} "TwgG*kv>.(/PMK 67fWPYО_P')c+p  !S ޛ+[l,_"b 1lm,!pb8R稖jG̃isY?IZlh_@Xa\#ՂtRhѼwX*yLJA_+2ՔKb_LXILvqoЙcKvCcf"Rsh20 jb䠽#/ D`rȶUW_/A֫/C>+$sN6jh 7R#`Qx E3aPQI.f\b DSl؎鿘EMwW;b"PG@|w !xfנ̉(d yX1xsFQgu̒д4!22޷dz|.Q(MYJ(Q2Ƈ2A9e=3`L!{X] nwa6ޒ z`E!ޝ,t[EXsNw4Ko\˛I.:L'=;P|yGa "2z_>+ԚO g֪>6-VVt{]D>:nugZ^fgzfsrNh0B*p퉑DNg[WuF\+9ʄQd2UͷWX v3B@қ!K9{fmMyUtwXxA\Zuѫ^ [=%W_kNN1B-*+9SG'[GVV__yD=svJG3vPXWQyIŤj5z +cТ3<^] t*/ 'QG mlyyHQ񝞫b8Wn\DkQ9+RIWUC]*@kI1͌T{ k`={T U`ZcaAޥǢAw`ij­=S7KYt%Uu|dbLFxU.@Nl[@ج%ĉ=IƟ,W0ftDP;8k@K.|hQfN lPoLW22\CENRd<5k:YP mg߁ J=vFcA 91-ؚ:3_ԢDM5BS__sqS׀?tW8[#.DĢFڊېcSE5q9͟&SA@ІUmLM}HLMnsZ]4˷y^)YŲDRےӵ1j^e8>8YYK26D@g@ I#ֲjЪ/eky(GUO6kވӳJQN7TݱbJ/ضF}K;]% KC#6>$*HԆMq69ZαUiuNڗFfGt:r*38 Ye\CNZt;LNi0au6;rM9 vN`3I2orahQ5 HZưڔp=++"#{*(C@лb-җvH_t X. PˀT-EǟZA {xNk$yLYfģc [t(Q .^~aaknլ-9E)>UBf |tN}`}ḲDI"(wZĀ+ +TBEV̉nx*eh&` 9L, 7mYNt2XҔ,5vE5R6E-֫NMXX}@c5XÊҫM")x}H`of-Tg MQ4Cй%&a-.{W֝EؠwdvP .E^ 9T?Wϐ9PX#t:YiN;Y鴺'" U?E+&v+Aʦ_9L܅JX5T=qjt?ƷP2ePZ*ݚ>LiTi0K덲$rmtPu+D(,bkx|Og u;'ф~6Tj,kmg$ &~NB>tI$'xvѮ袭Hvx;㸁4ZWnFDp8|[Auk[ևAs\|7 _WzK7(]:_3fREX̜0$Y.V>"%RrzE햃Tx.\&UB >s=CF2xtE;B=\Gl8f󰯨(,'] ԛzT o_;/ܲèkL֚~,鞅毂Uiq\hx}y*'oa5fS%t&/we}Lչq\CO'̖*$uYbKbt]:|Ԗ/s9ˠv޿6g޳tz`K?eK01'@"2p,g%tjתkV9 9RkO5>z dCUuaYȽϨ8ES];ێ1XU"u(;`JֆLfݪ CWsHnGmJІ= hUy<>||#U>O 7 +ڀyt5uoe]<gEPɠ xH;bp;"!{'U*ʖ{?Ue|~Ӹ3W^G ]P]^*EPa9i3b U?AkP[@-%# Z&ŒF/ r1Mm.^ΛRaBLݝg ȍY<ԙwqcN CǚgN`dsCy}L'KsٳVQZ8 QsivŧQmZC4z${[t_󾷶X"wR9 $z[*]gKa GN QVL釹jut<&5xŞ68K4m#^yjaxb"5^iVu&]W>4Mն.zMM"_W9M+!@iIǪR?P( Q"DU`Dª]cz_^)>&Қ);zheihŮ@ópvyG^CN8~uW_W(euBG>mC'sjv8:|:Ʒiksd,Lpbi$B%»SaFv {H3Dͺ9r {u!2'V cÐ9(p^Յ[]:8>M VrzaLtfnILKFK'<`-$$G/DҿP:gvKT7Ԯnݶw/כ_77o7Ϯ6QE2?Eȫ^M$ʖ*%QeZ 2"4Rcn-(S A~tMq+8q*3MBx$`hŎ}{DB4#BKO=:;PM%^Lv1Jz˅fDZO؁Ԟ\^y AfqܐU dU=04\9aX s14UG{b?mJh<6RÊr~_:q^υOw89TcF3B!{yհ XDsI5s%Fe_7H.j(2Kt&ǹEBRGA?- \J g썄Tv2 :Cj&pJX iь)Nj3(-у4 6hsxR xoVP"kN=AoO P )1r`]{ҏ/JG9.?hP+`!nH0R"!3SE4%r$3):V\j~cާl2rj,Zarҥ4}RRZ%>^BGUӷmjkQ߇f#)BCVariantAnnotation/inst/extdata/chr7-sub.vcf.gz.tbi0000644000175100017510000000135014614305321023164 0ustar00biocbuildbiocbuildBC흻Kůj.BAVn94EڐDB%RK{hڻaZfjr-M 9FEKHҒ?9˷|@?| zwV]Jҧ<:U5s͟?$?y3QU n䮞.~qW-ٚ8w v$wu+wX滑ħ4}&YK~>]_: 7sWg}/rWgHw%p wu]=nwcy+۲۶$]]Y wqW?ik{kտ׹7opWgN7$^W rWYSKz\]]]]]ޣ vVx/wh=^..YzjM!pw>+祌1c1c1c1c1c1c1c1c1c1c1c1c1c#ފ⭧x)j⭥x3/ċ7Mx.ޤ7Mx3.ބ7MxM xc-P7 x,7 xcL72&9pBCVariantAnnotation/inst/extdata/ex2.vcf0000644000175100017510000000354414614305321021043 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##fileDate=20090805 ##source=myImputationProgramV3.1 ##reference=file:///seq/references/1000GenomesPilot-NCBI36.fasta ##contig= ##phasing=partial ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##FILTER= ##FILTER= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= ##SAMPLE= ##SAMPLE= ##PEDIGREE= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT NA00001 NA00002 NA00003 20 14370 rs6054257 G A 29 PASS NS=3;DP=14;AF=0.5;DB;H2 GT:GQ:DP:HQ 0|0:48:1:51,51 1|0:48:8:51,51 1/1:43:5:.,. 20 17330 . T A 3 q10 NS=3;DP=11;AF=0.017 GT:GQ:DP:HQ 0|0:49:3:58,50 0|1:3:5:65,3 0/0:41:3 20 1110696 rs6040355 A G,T 67 PASS NS=2;DP=10;AF=0.333,0.667;AA=T;DB GT:GQ:DP:HQ 1|2:21:6:23,27 2|1:2:0:18,2 2/2:35:4 20 1230237 . T . 47 PASS NS=3;DP=13;AA=T GT:GQ:DP:HQ 0|0:54:7:56,60 0|0:48:4:51,51 0/0:61:2 20 1234567 microsat1 GTC G,GTCT 50 PASS NS=3;DP=9;AA=G GT:GQ:DP 0/1:35:4 0/2:17:2 1/1:40:3 VariantAnnotation/inst/extdata/gl_chr1.vcf0000644000175100017510000006036314614305321021666 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##ALT= ##FORMAT= ##FORMAT= ##FORMAT= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##reference=GRCh37 ##source_20120923.1=/nfs/public/rw/ensembl/vcftools/bin/vcf-subset -c NA06984,NA06986,NA06989,NA06994,NA07000,NA07037,NA07048,NA07051,NA07056,NA07347,NA07357,NA10847,NA10851,NA11829,NA11830,NA11831,NA11843,NA11892,NA11893,NA11894,NA11919,NA11920,NA11930,NA11931,NA11932,NA11933,NA11992,NA11993,NA11994,NA11995,NA12003,NA12004,NA12006,NA12043,NA12044,NA12045,NA12046,NA12058,NA12144,NA12154,NA12155,NA12249,NA12272,NA12273,NA12275,NA12282,NA12283,NA12286,NA12287,NA12340,NA12341,NA12342,NA12347,NA12348,NA12383,NA12399,NA12400,NA12413,NA12489,NA12546,NA12716,NA12717,NA12718,NA12748,NA12749,NA12750,NA12751,NA12761,NA12763,NA12775,NA12777,NA12778,NA12812,NA12814,NA12815,NA12827,NA12829,NA12830,NA12842,NA12843,NA12872,NA12873,NA12874,NA12889,NA12890 /net/isilonP/public/rw/ensembl/1000genomes/release-12/tmp/slicer/1.1-50000.ALL.chr1.phase1_release_v3.20101123.snps_indels_svs.genotypes.vcf.gz #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT NA06984 NA06986 NA06989 NA06994 NA07000 NA07037 NA07048 NA07051 NA07056 NA07347 NA07357 NA10847 NA10851 NA11829 NA11830 NA11831 NA11843 NA11892 NA11893 NA11894 NA11919 NA11920 NA11930 NA11931 NA11932 NA11933 NA11992 NA11993 NA11994 NA11995 NA12003 NA12004 NA12006 NA12043 NA12044 NA12045 NA12046 NA12058 NA12144 NA12154 NA12155 NA12249 NA12272 NA12273 NA12275 NA12282 NA12283 NA12286 NA12287 NA12340 NA12341 NA12342 NA12347 NA12348 NA12383 NA12399 NA12400 NA12413 NA12489 NA12546 NA12716 NA12717 NA12718 NA12748 NA12749 NA12750 NA12751 NA12761 NA12763 NA12775 NA12777 NA12778 NA12812 NA12814 NA12815 NA12827 NA12829 NA12830 NA12842 NA12843 NA12872 NA12873 NA12874 NA12889 NA12890 1 10583 rs58108140 G A 100 PASS AA=.;AC=37;AF=0.14;AFR_AF=0.04;AMR_AF=0.17;AN=170;ASN_AF=0.13;AVGPOST=0.7707;ERATE=0.0161;EUR_AF=0.21;LDAF=0.2327;RSQ=0.4319;SNPSOURCE=LOWCOV;THETA=0.0046;VT=SNP GT:DS:GL 0|1:1.250:-4.70,-0.58,-0.13 0|1:0.750:-1.15,-0.10,-0.84 0|1:1.000:-2.05,-0.00,-3.27 0|0:0.450:-0.48,-0.48,-0.48 0|0:0.400:-0.28,-0.44,-0.96 0|0:0.550:-0.48,-0.48,-0.48 0|1:1.000:-1.93,-0.02,-1.45 0|0:0.100:-0.02,-1.44,-5.00 0|1:1.150:-2.72,-0.46,-0.19 0|0:0.400:-0.48,-0.48,-0.48 0|0:0.000:-0.05,-0.96,-5.00 0|1:0.550:-0.48,-0.18,-2.28 0|0:0.050:-0.01,-1.50,-5.00 0|0:0.200:-0.05,-0.94,-4.70 0|1:1.000:-0.90,-0.06,-5.00 0|0:0.350:-0.48,-0.17,-4.40 0|0:0.400:-0.48,-0.48,-0.48 0|0:0.150:-0.11,-0.64,-4.10 0|0:0.100:-0.04,-1.08,-5.00 0|0:0.250:-0.48,-0.48,-0.48 0|1:1.050:-0.93,-0.39,-0.32 0|0:0.150:-0.48,-0.48,-0.48 0|1:0.850:-0.76,-0.08,-5.00 0|1:0.550:-0.48,-0.48,-0.48 0|0:0.100:-0.11,-0.64,-3.40 0|1:0.850:-0.62,-0.12,-5.00 0|0:0.550:-0.48,-0.48,-0.48 0|0:0.150:-0.13,-0.58,-2.73 0|0:0.000:-0.07,-0.85,-5.00 0|1:0.850:-1.34,-0.08,-0.92 0|0:0.500:-0.29,-0.43,-0.95 0|0:0.550:-0.48,-0.48,-0.48 0|1:1.000:-3.15,-0.01,-1.70 0|0:0.350:-0.48,-0.48,-0.48 0|1:0.900:-1.16,-0.10,-0.89 0|0:0.350:-0.18,-0.48,-1.76 0|0:0.550:-0.477139,-0.477113,-0.477113 0|1:1.000:-4.70,-0.00,-5.00 0|0:0.100:-0.04,-1.04,-5.00 0|1:1.000:-2.80,-0.00,-2.27 0|0:0.150:-0.08,-0.78,-5.00 0|0:0.450:-0.48,-0.48,-0.48 0|1:0.750:-0.48,-0.48,-0.48 0|0:0.400:-0.18,-0.48,-2.05 0|0:0.200:-0.19,-0.47,-2.13 0|0:0.050:-0.0744919,-0.802609,-4.09691 0|1:0.800:-1.34,-0.02,-3.52 0|1:0.550:-0.46,-0.19,-5.00 0|1:0.800:-0.48,-0.48,-0.48 0|0:0.700:-0.48,-0.48,-0.48 0|0:0.250:-0.11,-0.65,-3.92 0|1:1.000:-5.00,-0.00,-3.05 0|1:1.000:-3.09,-0.00,-5.00 0|1:1.000:-5.00,0.00,-5.00 0|0:0.250:-0.12,-0.63,-3.74 0|0:0.350:-0.19,-0.46,-2.34 0|1:0.750:-0.477139,-0.477113,-0.477113 0|1:0.800:-1.38,-0.02,-4.70 0|0:0.200:-0.11,-0.65,-3.36 0|1:1.000:-5.00,-0.00,-3.80 0|1:0.650:-0.48,-0.48,-0.48 0|0:0.550:-0.48,-0.48,-0.48 0|1:1.000:-5.00,-0.00,-2.37 0|0:0.150:-0.06,-0.92,-5.00 0|0:0.000:-0.01,-1.54,-5.00 0|1:1.100:-1.78,-0.40,-0.23 0|0:0.500:-0.48,-0.48,-0.48 0|0:0.500:-0.48,-0.48,-0.48 0|0:0.700:-0.48,-0.48,-0.48 0|1:1.150:-4.70,-0.07,-0.85 0|0:0.100:-0.06,-0.87,-5.00 0|1:1.100:-4.70,-0.14,-0.55 0|0:0.350:-0.14,-0.56,-2.82 0|0:0.050:-0.05,-0.97,-5.00 0|0:0.000:-0.11,-0.65,-3.40 0|1:0.800:-0.70,-0.10,-5.00 0|1:1.000:-3.22181,-0.00425079,-2.03905 0|1:1.000:-5.00,0.00,-5.00 0|0:0.150:-0.14,-0.55,-3.52 0|1:1.000:-1.62,-0.01,-2.66 0|1:1.200:-2.36,-0.21,-0.42 0|0:0.100:-0.08,-0.77,-4.70 0|0:0.100:-0.02,-1.27,-5.00 0|1:1.000:-4.10,-0.00,-4.40 0|0:0.150:-0.05,-0.99,-5.00 1 10611 rs189107123 C . 100 PASS AA=.;AC=0;AF=0.02;AFR_AF=0.01;AMR_AF=0.03;AN=170;ASN_AF=0.01;AVGPOST=0.9330;ERATE=0.0048;EUR_AF=0.02;LDAF=0.0479;RSQ=0.3475;SNPSOURCE=LOWCOV;THETA=0.0077;VT=SNP GT:DS:GL 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.000:-0.24,-0.41,-1.44 0|0:0.050:-0.19,-0.45,-2.25 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.000:-0.12,-0.63,-3.10 0|0:0.000:-0.19,-0.45,-2.23 0|0:0.000:-0.19,-0.45,-2.04 0|0:0.000:-0.12,-0.62,-4.40 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.41,-0.45,-0.59 0|0:0.000:-0.19,-0.46,-2.27 0|0:0.000:-0.04,-1.06,-5.00 0|0:0.000:-0.19,-0.48,-1.56 0|0:0.000:-0.11,-0.65,-4.10 0|0:0.000:-0.20,-0.45,-1.96 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.000:-0.07,-0.85,-5.00 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.000:-0.24,-0.41,-1.44 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.000:-0.11,-0.66,-4.40 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.050:-0.40,-0.42,-0.66 0|0:0.000:-0.01,-1.59,-5.00 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.000:-0.19,-0.47,-1.81 0|0:0.000:-0.04,-1.08,-5.00 0|0:0.000:-0.19,-0.47,-1.69 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.000:-0.19,-0.46,-1.80 0|0:0.000:-0.16,-0.52,-2.28 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.050:-0.22,-0.44,-1.41 0|0:0.200:-0.48,-0.48,-0.48 0|0:0.000:-0.165516,-0.505484,-2.33348 0|0:0.000:-0.07,-0.81,-5.00 0|0:0.050:-0.13,-0.58,-2.79 0|0:0.000:-0.13,-0.60,-2.98 0|0:0.050:-0.14,-0.56,-3.05 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.050:-0.18,-0.48,-2.04 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.000:-0.0666747,-0.846856,-4.39794 0|0:0.000:-0.12,-0.63,-3.59 0|0:0.000:-0.01,-1.48,-5.00 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.000:-0.20,-0.45,-2.01 0|0:0.000:-0.19,-0.46,-2.39 0|0:0.000:-0.11,-0.66,-4.00 0|0:0.000:-0.01,-1.70,-5.00 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.000:-0.477139,-0.477113,-0.477113 0|0:0.000:-0.03,-1.12,-5.00 0|0:0.050:-0.18,-0.48,-1.99 0|0:0.050:-0.07,-0.85,-5.00 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.000:-0.01,-1.71,-5.00 0|0:0.000:-0.09,-0.73,-4.22 0|0:0.050:-0.20,-0.47,-1.57 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.000:-0.12,-0.63,-3.66 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.000:-0.07,-0.82,-5.00 0|0:0.000:-0.18,-0.48,-2.27 0|0:0.000:-0.14,-0.56,-2.82 0|0:0.000:-0.13,-0.58,-2.97 0|0:0.000:-0.03,-1.13,-5.00 0|0:0.000:-0.0503466,-0.960745,-5 0|0:0.000:-0.00,-4.40,-5.00 0|0:0.050:-0.20,-0.45,-2.25 0|0:0.150:-0.20,-0.45,-1.94 0|0:0.050:-0.13,-0.58,-2.84 0|0:0.150:-0.18,-0.48,-2.21 0|0:0.000:-0.05,-0.97,-5.00 0|0:0.050:-0.19,-0.46,-2.12 0|0:0.000:-0.05,-1.00,-5.00 1 13302 rs180734498 C T 100 PASS AA=.;AC=20;AF=0.11;AFR_AF=0.21;AMR_AF=0.08;AN=170;ASN_AF=0.02;AVGPOST=0.8895;ERATE=0.0058;EUR_AF=0.14;LDAF=0.1573;RSQ=0.6281;SNPSOURCE=LOWCOV;THETA=0.0048;VT=SNP GT:DS:GL 0|1:1.000:-2.01,-0.40,-0.23 0|0:0.000:-0.04,-1.08,-5.00 0|0:0.000:-0.08,-0.77,-5.00 0|0:0.100:-0.20,-0.45,-1.73 0|1:0.950:-1.68,-0.40,-0.24 0|1:0.850:-0.42,-0.21,-5.00 0|0:0.200:-0.48,-0.48,-0.48 0|0:0.100:-0.13,-0.60,-4.10 1|0:0.850:-1.15,-0.03,-5.00 0|0:0.100:-0.26,-0.41,-1.17 0|0:0.100:-0.08,-0.79,-4.70 0|0:0.200:-0.20,-0.45,-2.12 0|1:0.950:-2.54,-0.00,-5.00 0|1:1.000:-5.00,0.00,-5.00 0|0:0.000:-0.00,-2.09,-5.00 0|1:0.750:-0.63,-0.12,-5.00 0|0:0.000:-0.07,-0.84,-5.00 0|0:0.350:-0.26,-0.34,-5.00 0|1:1.000:-4.22,-0.00,-5.00 0|0:0.150:-0.31,-0.41,-0.92 0|0:0.200:-0.20,-0.45,-2.02 0|0:0.150:-0.12,-0.61,-3.27 0|0:0.000:-0.01,-1.49,-5.00 0|0:0.400:-0.48,-0.48,-0.48 0|0:0.250:-0.48,-0.48,-0.48 0|1:1.000:-1.93,-0.03,-1.29 0|0:0.050:-0.11,-0.65,-3.80 0|0:0.300:-0.16,-0.52,-5.00 0|0:0.000:-0.05,-1.01,-5.00 0|0:0.500:-0.48,-0.48,-0.48 0|0:0.450:-0.22,-0.40,-3.92 0|0:0.050:-0.04,-1.03,-4.40 1|0:1.000:-3.55,-0.00,-5.00 0|0:0.250:-0.21,-0.46,-1.39 0|0:0.250:-0.22,-0.46,-1.31 0|0:0.200:-0.19,-0.45,-2.11 0|0:0.050:-0.130463,-0.587405,-3.04576 0|0:0.150:-0.20,-0.44,-2.36 0|0:0.300:-0.20,-0.46,-1.76 0|0:0.100:-0.03,-1.18,-5.00 1|0:1.000:-4.40,-0.00,-2.95 0|0:0.300:-0.48,-0.48,-0.48 0|0:0.300:-0.48,-0.48,-0.48 0|0:0.400:-0.48,-0.48,-0.48 0|1:1.250:-4.70,-0.62,-0.12 0|0:0.000:-0.0146544,-1.47912,-5 0|0:0.100:-0.11,-0.66,-3.85 0|0:0.100:-0.05,-0.95,-5.00 0|0:0.200:-0.38,-0.43,-0.67 0|0:0.300:-0.48,-0.48,-0.48 0|0:0.350:-0.20,-0.45,-2.02 1|0:1.000:-4.00,-0.02,-1.37 1|0:0.650:-0.86,-0.06,-5.00 0|0:0.000:-0.00,-2.05,-5.00 0|0:0.000:-0.02,-1.46,-5.00 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.000:-0.00528701,-1.91721,-5 0|0:0.100:-0.09,-0.74,-5.00 0|1:0.700:-0.80,-0.07,-4.70 0|1:0.850:-1.28,-0.02,-2.69 0|0:0.300:-0.48,-0.48,-0.48 0|0:0.300:-0.48,-0.48,-0.48 0|0:0.050:-0.03,-1.24,-5.00 0|0:0.300:-0.21,-0.44,-1.66 0|0:0.150:-0.21,-0.46,-1.51 1|0:0.900:-1.40,-0.38,-0.26 0|0:0.700:-0.48,-0.48,-0.48 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.100:-0.15,-0.54,-2.92 0|0:0.150:-0.23,-0.42,-1.56 0|0:0.000:-0.01,-1.61,-5.00 1|0:0.750:-1.07,-0.04,-4.10 0|0:0.350:-0.67,-0.10,-5.00 0|1:1.000:-2.36,-0.00,-4.70 0|1:1.000:-3.52,-0.00,-3.10 0|0:0.100:-0.08,-0.78,-5.00 0|0:0.000:-0.00338326,-2.11014,-5 0|0:0.100:-0.18,-0.48,-2.37 0|0:0.000:-0.04,-1.01,-5.00 0|0:0.100:-0.05,-0.94,-5.00 0|0:0.050:-0.06,-0.90,-3.74 0|0:0.250:-0.32,-0.28,-5.00 0|0:0.250:-0.10,-0.70,-2.78 0|0:0.550:-0.48,-0.48,-0.48 0|0:0.050:-0.13,-0.59,-2.97 1 13327 rs144762171 G . 100 PASS AA=.;AC=0;AF=0.03;AFR_AF=0.02;AMR_AF=0.03;AN=170;ASN_AF=0.02;AVGPOST=0.9698;ERATE=0.0012;EUR_AF=0.04;LDAF=0.0359;RSQ=0.6482;SNPSOURCE=LOWCOV;THETA=0.0204;VT=SNP GT:DS:GL 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.000:-0.00,-3.07,-5.00 0|0:0.000:-0.10,-0.68,-4.70 0|0:0.050:-0.21,-0.45,-1.67 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.000:-0.00,-3.36,-5.00 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.000:-0.07,-0.82,-5.00 0|0:0.000:-0.00,-4.70,-5.00 0|0:0.000:-0.26,-0.41,-1.19 0|0:0.000:-0.02,-1.29,-5.00 0|0:0.000:-0.03,-1.24,-5.00 0|0:0.000:-0.00,-2.01,-5.00 0|0:0.000:0.00,-5.00,-5.00 0|0:0.000:-0.00,-4.70,-5.00 0|0:0.000:-0.01,-1.90,-5.00 0|0:0.000:-0.02,-1.36,-5.00 0|0:0.000:-0.00,-2.97,-5.00 0|0:0.000:-0.00,-2.54,-5.00 0|0:0.050:-0.30,-0.41,-0.92 0|0:0.000:-0.20,-0.45,-1.99 0|0:0.000:-0.12,-0.63,-3.44 0|0:0.000:-0.00,-2.02,-5.00 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.32,-0.41,-0.88 0|0:0.250:-0.52,-0.16,-5.00 0|0:0.000:-0.12,-0.62,-4.70 0|0:0.000:-0.00,-3.25,-5.00 0|0:0.000:-0.02,-1.27,-5.00 0|0:0.050:-0.40,-0.45,-0.60 0|0:0.000:-0.00,-2.15,-5.00 0|0:0.000:-0.01,-1.55,-5.00 0|0:0.100:-0.18,-0.48,-5.00 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.000:-0.30,-0.41,-0.97 0|0:0.000:-0.0397766,-1.05789,-5 0|0:0.000:-0.19,-0.45,-2.53 0|0:0.000:-0.00,-2.48,-5.00 0|0:0.000:-0.00,-4.40,-5.00 0|0:0.000:-0.01,-1.56,-5.00 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.200:-0.48,-0.48,-0.48 0|0:0.000:-0.00919955,-1.67861,-5 0|0:0.000:-0.01,-1.73,-5.00 0|0:0.000:-0.00,-2.82,-5.00 0|0:0.000:-0.38,-0.43,-0.68 0|0:0.200:-0.48,-0.48,-0.48 0|0:0.050:-0.19,-0.45,-2.03 0|0:0.000:-0.07,-0.82,-5.00 0|0:0.000:-0.00,-2.34,-5.00 0|0:0.000:-0.00,-3.52,-5.00 0|0:0.000:-0.00,-2.08,-5.00 0|0:0.000:-0.12,-0.61,-3.92 0|0:0.000:-0.00418936,-2.01773,-5 0|0:0.000:-0.00,-4.40,-5.00 0|0:0.000:-0.00,-2.11,-5.00 0|0:0.000:-0.06,-0.86,-5.00 0|0:0.000:-0.00,-2.01,-5.00 0|0:0.050:-0.12,-0.63,-3.74 0|0:0.000:-0.00,-2.29,-5.00 0|0:0.000:-0.13,-0.60,-3.19 0|0:0.000:-0.20,-0.47,-1.57 0|0:0.050:-0.07,-0.84,-5.00 0|0:0.150:-0.22,-0.43,-1.69 0|0:0.000:-0.08,-0.80,-5.00 0|0:0.000:-0.04,-1.02,-5.00 0|0:0.050:-0.20,-0.45,-1.99 0|0:0.000:-0.00,-2.98,-5.00 0|0:0.000:-0.01,-1.57,-5.00 0|0:0.000:-0.02,-1.31,-5.00 0|0:0.000:-0.00,-2.63,-5.00 0|0:0.100:-0.11,-0.65,-5.00 0|0:0.000:-0.00,-3.08,-5.00 0|0:0.000:0,-5,-5 0|0:0.000:-0.02,-1.26,-5.00 0|0:0.000:-0.00,-2.69,-5.00 0|0:0.000:-0.02,-1.46,-5.00 0|0:0.050:-0.02,-1.29,-5.00 0|0:0.000:-0.00,-2.25,-5.00 0|0:0.000:-0.03,-1.20,-5.00 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.000:-0.02,-1.28,-5.00 1 13957 rs201747181 TC . 28 PASS AA=TC;AC=0;AF=0.02;AFR_AF=0.02;AMR_AF=0.02;AN=170;ASN_AF=0.01;AVGPOST=0.8711;ERATE=0.0065;EUR_AF=0.02;LDAF=0.0788;RSQ=0.2501;THETA=0.0100;VT=INDEL GT:DS:GL 0|0:0.200:0,0,0 0|0:0.150:0,0,0 0|0:0.100:0,0,0 0|0:0.200:0,0,0 0|0:0.150:0,0,0 0|0:0.200:0,0,0 0|0:0.100:0,0,0 0|0:0.200:0,0,0 0|0:0.250:0,0,0 0|0:0.050:0,0,0 0|0:0.250:0,0,0 0|0:0.250:0,0,0 0|0:0.250:0,0,0 0|0:0.300:0,0,0 0|0:0.250:0.00,-0.30,-4.10 0|0:0.300:0,0,0 0|0:0.250:0,0,0 0|0:0.050:0.00,-0.60,-8.20 0|0:0.250:0,0,0 0|0:0.100:0,0,0 0|0:0.000:0,0,0 0|0:0.200:0,0,0 0|0:0.200:0,0,0 0|0:0.250:0,0,0 0|0:0.300:0,0,0 0|0:0.250:0,0,0 0|0:0.050:0,0,0 0|0:0.150:0,0,0 0|0:0.200:0,0,0 0|0:0.250:0,0,0 0|0:0.350:0,0,0 0|0:0.450:0,0,0 0|0:0.150:0,0,0 0|0:0.000:0,0,0 0|0:0.150:0,0,0 0|0:0.050:0,0,0 0|0:0.050:0,0,0 0|0:0.250:0,0,0 0|0:0.150:0,0,0 0|0:0.050:0.00,-0.60,-6.20 0|0:0.150:0,0,0 0|0:0.150:0,0,0 0|0:0.150:0,0,0 0|0:0.150:0,0,0 0|0:0.300:0,0,0 0|0:0.050:0.00,-0.90,-11.90 0|0:0.100:0.00,-0.30,-3.90 0|0:0.200:0,0,0 0|0:0.350:0,0,0 0|0:0.250:0,0,0 0|0:0.100:0,0,0 0|0:0.050:0,0,0 0|0:0.250:0.00,-0.30,-4.10 0|0:0.050:0,0,0 0|0:0.150:0,0,0 0|0:0.150:0,0,0 0|0:0.300:0,0,0 0|0:0.200:0,0,0 0|0:0.100:0,0,0 0|0:0.150:0,0,0 0|0:0.150:0.00,-0.30,-4.10 0|0:0.200:0,0,0 0|0:0.100:0,0,0 0|0:0.150:0,0,0 0|0:0.300:0,0,0 0|0:0.350:0,0,0 0|0:0.450:0,0,0 0|0:0.200:0,0,0 0|0:0.300:0,0,0 0|0:0.300:0,0,0 0|0:0.200:0,0,0 0|0:0.100:0,0,0 0|0:0.200:0,0,0 0|0:0.150:0,0,0 0|0:0.250:0,0,0 0|0:0.350:0,0,0 0|0:0.000:0.00,-0.90,-12.20 0|0:0.200:0,0,0 0|0:0.100:0,0,0 0|0:0.200:0,0,0 0|0:0.200:0,0,0 0|0:0.200:0,0,0 0|0:0.050:0,0,0 0|0:0.100:0,0,0 0|0:0.150:0,0,0 1 13980 rs151276478 T . 100 PASS AA=.;AC=0;AF=0.02;AFR_AF=0.01;AMR_AF=0.02;AN=170;ASN_AF=0.02;AVGPOST=0.9221;ERATE=0.0034;EUR_AF=0.02;LDAF=0.0525;RSQ=0.3603;SNPSOURCE=LOWCOV;THETA=0.0139;VT=SNP GT:DS:GL 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.200:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.000:-0.45,-0.46,-0.52 0|0:0.050:-0.25,-0.43,-1.13 0|0:0.000:-0.07,-0.81,-5.00 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.000:-0.03,-1.12,-5.00 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.200:-0.48,-0.48,-0.48 0|0:0.000:-0.11,-0.67,-2.93 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.250:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.100:-0.477139,-0.477113,-0.477113 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.000:-0.19,-0.47,-1.85 0|0:0.000:-0.04,-1.06,-5.00 0|0:0.200:-0.24,-0.45,-1.18 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.250:-0.48,-0.48,-0.48 0|0:0.200:-0.48,-0.48,-0.48 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.000:-0.0404435,-1.051,-5 0|0:0.000:-0.34,-0.41,-0.81 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.200:-0.48,-0.48,-0.48 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.000:-0.19,-0.45,-2.25 0|0:0.000:-0.04,-1.06,-5.00 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.250:-0.477139,-0.477113,-0.477113 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.000:-0.08,-0.78,-5.00 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.100:-0.48,-0.48,-0.48 0|0:0.250:-0.48,-0.48,-0.48 0|0:0.300:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.050:-0.11,-0.66,-2.80 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.25,-0.44,-1.12 0|0:0.000:-0.48,-0.48,-0.48 0|0:0.000:-0.00278841,-2.19382,-5 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.150:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 0|0:0.050:-0.48,-0.48,-0.48 1 30923 rs140337953 G T 100 PASS AA=T;AC=122;AF=0.73;AFR_AF=0.48;AMR_AF=0.80;AN=170;ASN_AF=0.89;AVGPOST=0.7335;ERATE=0.0183;EUR_AF=0.73;LDAF=0.6576;RSQ=0.5481;SNPSOURCE=LOWCOV;THETA=0.0162;VT=SNP GT:DS:GL 1|1:1.500:-5.00,-0.67,-0.10 1|1:1.800:-5.00,-0.66,-0.11 0|1:0.800:-0.19,-0.45,-2.24 1|1:1.550:-0.48,-0.48,-0.48 1|0:0.650:-0.13,-0.61,-2.25 1|1:1.550:-0.48,-0.48,-0.48 1|1:1.550:-0.48,-0.48,-0.48 1|0:1.050:-0.48,-0.48,-0.48 0|1:1.100:-0.20,-0.47,-1.42 1|1:1.400:-0.48,-0.48,-0.48 0|0:0.500:-0.17,-0.51,-1.66 1|1:1.500:-0.48,-0.48,-0.48 1|0:0.800:-0.23,-0.44,-1.26 1|0:1.000:-1.14,-0.03,-4.22 0|0:0.200:-0.02,-1.35,-5.00 1|0:0.800:-0.54,-0.15,-5.00 1|1:1.400:-0.48,-0.48,-0.48 0|1:1.000:-1.63,-0.01,-4.40 1|1:1.350:-0.48,-0.48,-0.48 1|1:1.550:-0.48,-0.48,-0.48 1|1:1.450:-0.48,-0.48,-0.48 1|1:1.450:-0.48,-0.48,-0.48 1|1:1.350:-0.48,-0.48,-0.48 1|1:1.700:-0.48,-0.48,-0.48 1|1:1.500:-0.48,-0.48,-0.48 1|1:1.350:-0.48,-0.48,-0.48 0|1:0.850:-0.19,-0.49,-1.59 0|0:0.450:-0.07,-0.81,-3.66 1|1:1.750:-5.00,-0.58,-0.13 0|0:0.650:-0.13,-0.59,-2.08 0|0:0.000:-0.00,-2.30,-5.00 1|0:0.700:-0.21,-0.47,-1.41 0|0:0.350:-0.11,-0.64,-2.72 1|1:1.350:-0.48,-0.48,-0.48 1|1:1.500:-0.40,-0.45,-0.61 1|1:1.200:-0.48,-0.48,-0.48 1|1:1.200:-0.374811,-0.424928,-0.694176 0|1:1.000:-1.81,-0.01,-5.00 0|1:0.900:-0.20,-0.48,-1.47 1|1:1.450:-0.48,-0.48,-0.48 0|1:1.000:-5.00,-0.00,-2.84 1|1:1.250:-0.48,-0.48,-0.48 1|1:1.350:-0.48,-0.48,-0.48 1|1:1.800:-5.00,-0.86,-0.06 1|1:1.900:-4.70,-0.66,-0.11 1|1:1.600:-0.477139,-0.477113,-0.477113 1|1:1.500:-0.48,-0.48,-0.48 0|1:1.200:-0.48,-0.48,-0.48 1|1:1.750:-0.48,-0.48,-0.48 1|1:1.750:-2.81,-0.45,-0.19 1|1:1.150:-0.48,-0.48,-0.48 1|1:1.800:-3.18,-0.47,-0.18 1|1:1.550:-2.59,-0.46,-0.19 1|1:1.550:-0.48,-0.48,-0.48 0|0:0.650:-0.06,-0.86,-5.00 1|1:1.600:-0.48,-0.48,-0.48 1|1:1.700:-2.45593,-0.438493,-0.199173 1|1:1.600:-0.48,-0.48,-0.48 0|0:0.300:-0.07,-0.82,-3.80 1|1:1.600:-2.35,-0.44,-0.20 0|0:0.100:-0.02,-1.29,-5.00 0|1:1.100:-0.34,-0.41,-0.82 1|1:1.850:-5.00,-0.89,-0.06 1|1:1.650:-2.41,-0.46,-0.19 1|1:1.300:-0.48,-0.48,-0.48 1|1:1.300:-0.48,-0.48,-0.48 0|1:1.350:-0.48,-0.48,-0.48 1|1:1.600:-0.48,-0.48,-0.48 0|0:0.700:-0.17,-0.50,-2.56 1|1:1.350:-0.48,-0.48,-0.48 1|1:1.850:-2.58,-0.46,-0.19 0|0:0.950:-0.29,-0.40,-1.01 1|0:1.200:-0.28,-0.43,-0.99 1|0:0.950:-0.33,-0.43,-0.80 1|0:0.850:-0.24,-0.44,-1.18 1|1:1.500:-0.48,-0.48,-0.48 0|1:0.650:-0.0794071,-0.777024,-5 1|1:1.500:-0.48,-0.48,-0.48 0|1:1.250:-0.48,-0.48,-0.48 0|1:1.150:-0.48,-0.48,-0.48 1|0:0.750:-0.27,-0.44,-1.01 0|1:0.750:-0.12,-0.62,-2.49 0|0:0.500:-0.17,-0.51,-1.69 1|1:1.450:-0.48,-0.48,-0.48 1|1:1.600:-0.48,-0.48,-0.48 1 46402 rs199681827 C . 31 PASS AA=.;AC=0;AF=0.0037;AFR_AF=0.01;AN=170;ASN_AF=0.0017;AVGPOST=0.8325;ERATE=0.0072;LDAF=0.0903;RSQ=0.0960;THETA=0.0121;VT=INDEL GT:DS:GL 0|0:0.150:0,0,0 0|0:0.050:0,0,0 0|0:0.050:0.00,-0.60,-8.30 0|0:0.100:0,0,0 0|0:0.250:0,0,0 0|0:0.150:0,0,0 0|0:0.500:-0.80,-0.20,0.00 0|0:0.200:0,0,0 0|0:0.250:0,0,0 0|0:0.200:0,0,0 0|0:0.150:0,0,0 0|0:0.050:0,0,0 0|0:0.300:0,0,0 0|0:0.200:0,0,0 0|0:0.450:0,0,0 0|0:0.400:0,0,0 0|0:0.150:0,0,0 0|0:0.150:0,0,0 0|0:0.200:0,0,0 0|0:0.250:0,0,0 0|0:0.200:0,0,0 0|0:0.300:0,0,0 0|0:0.300:0,0,0 0|0:0.150:0,0,0 0|0:0.250:0,0,0 0|0:0.200:0,0,0 0|0:0.300:0,0,0 0|0:0.150:0,0,0 0|0:0.200:0,0,0 0|0:0.100:0,0,0 0|0:0.300:0,0,0 0|0:0.550:0,0,0 0|0:0.250:0,0,0 0|0:0.300:0,0,0 0|0:0.250:0,0,0 0|0:0.400:0,0,0 0|0:0.250:0,0,0 0|0:0.250:0,0,0 0|0:0.350:0,0,0 0|0:0.050:0,0,0 0|0:0.150:0.00,-0.30,-5.20 0|0:0.300:0,0,0 0|0:0.200:0,0,0 0|0:0.050:0,0,0 0|0:0.150:0,0,0 0|0:0.050:0,0,0 0|0:0.050:0,0,0 0|0:0.050:0,0,0 0|0:0.250:0,0,0 0|0:0.250:0,0,0 0|0:0.100:0,0,0 0|0:0.150:0,0,0 0|0:0.000:0,0,0 0|0:0.250:0,0,0 0|0:0.150:0,0,0 0|0:0.250:0,0,0 0|0:0.000:0.00,-0.30,-5.20 0|0:0.150:0,0,0 0|0:0.400:0,0,0 0|0:0.200:0,0,0 0|0:0.100:0,0,0 0|0:0.150:0,0,0 0|0:0.250:0,0,0 0|0:0.100:0,0,0 0|0:0.150:0,0,0 0|0:0.050:0,0,0 0|0:0.300:0,0,0 0|0:0.100:0,0,0 0|0:0.150:0,0,0 0|0:0.150:0,0,0 0|0:0.100:0,0,0 0|0:0.150:0,0,0 0|0:0.300:0,0,0 0|0:0.100:0,0,0 0|0:0.550:0,0,0 0|0:0.200:0,0,0 0|0:0.400:0,0,0 0|0:0.100:0,0,0 0|0:0.200:0,0,0 0|0:0.100:0,0,0 0|0:0.150:0,0,0 0|0:0.100:0,0,0 0|0:0.150:0,0,0 0|0:0.200:0,0,0 0|0:0.100:0,0,0 1 47190 rs200430748 G . 192 PASS AA=G;AC=0;AF=0.01;AFR_AF=0.06;AMR_AF=0.0028;AN=170;AVGPOST=0.9041;ERATE=0.0041;LDAF=0.0628;RSQ=0.2883;THETA=0.0153;VT=INDEL GT:DS:GL 0|0:0.300:0,0,0 0|0:0.000:0,0,0 0|0:0.000:0,0,0 0|0:0.050:0,0,0 0|0:0.150:0,0,0 0|0:0.000:0,0,0 0|0:0.100:0,0,0 0|0:0.100:0.00,-0.30,-3.60 0|0:0.150:0,0,0 0|0:0.100:0,0,0 0|0:0.100:0,0,0 0|0:0.000:0,0,0 0|0:0.150:0.00,-0.30,-3.60 0|0:0.050:0.00,-0.30,-3.60 0|0:0.100:0,0,0 0|0:0.100:0,0,0 0|0:0.050:0,0,0 0|0:0.050:0,0,0 0|0:0.000:0,0,0 0|0:0.000:0.00,-0.30,-3.60 0|0:0.100:0,0,0 0|0:0.050:0.00,-0.60,-7.20 0|0:0.200:0,0,0 0|0:0.200:0,0,0 0|0:0.000:0,0,0 0|0:0.200:0,0,0 0|0:0.200:0,0,0 0|0:0.300:0,0,0 0|0:0.000:0.00,-0.30,-3.60 0|0:0.050:0.00,-0.30,-3.60 0|0:0.200:0,0,0 0|0:0.100:0,0,0 0|0:0.100:0.00,-0.30,-3.60 0|0:0.000:0,0,0 0|0:0.050:0.00,-0.30,-3.60 0|0:0.000:0,0,0 0|0:0.050:0,0,0 0|0:0.250:0,0,0 0|0:0.150:0,0,0 0|0:0.000:0,0,0 0|0:0.150:0.00,-0.30,-3.60 0|0:0.150:0,0,0 0|0:0.000:0,0,0 0|0:0.100:0.00,-0.30,-3.60 0|0:0.100:0,0,0 0|0:0.050:0,0,0 0|0:0.100:0,0,0 0|0:0.200:0,0,0 0|0:0.100:0,0,0 0|0:0.100:0,0,0 0|0:0.100:0,0,0 0|0:0.150:0,0,0 0|0:0.050:0.00,-0.30,-3.60 0|0:0.100:0,0,0 0|0:0.100:0.00,-0.30,-3.60 0|0:0.050:0,0,0 0|0:0.050:0,0,0 0|0:0.050:0,0,0 0|0:0.000:0.00,-0.30,-3.60 0|0:0.150:0,0,0 0|0:0.550:0,0,0 0|0:0.000:0,0,0 0|0:0.150:0,0,0 0|0:0.150:0,0,0 0|0:0.000:0,0,0 0|0:0.000:0,0,0 0|0:0.150:0,0,0 0|0:0.000:0,0,0 0|0:0.050:0,0,0 0|0:0.050:0,0,0 0|0:0.050:0,0,0 0|0:0.000:0.00,-0.30,-2.80 0|0:0.050:0,0,0 0|0:0.200:0,0,0 0|0:0.000:0,0,0 0|0:0.050:0,0,0 0|0:0.050:0,0,0 0|0:0.000:0,0,0 0|0:0.050:0,0,0 0|0:0.050:0,0,0 0|0:0.050:0,0,0 0|0:0.100:0,0,0 0|0:0.050:0,0,0 0|0:0.050:0,0,0 0|0:0.050:0.00,-0.30,-3.60 VariantAnnotation/inst/extdata/h1187-10k.vcf.gz0000644000175100017510000036355214614305321022135 0ustar00biocbuildbiocbuildBC5}ks7g蘉1AхWDuWd~r46% ʓnU?$R D[<<~?ؽ=QGyu+Vyx=|xz^ÇSOYׇWwI~=OŻ?]:<.o_Ϯ?-gpq.N6z|gwn6]}ݝ쯶x/(g㷯/ W}vutp?SWO/C<̞oWOG둌j[Hj٦.U\-%6417_xWLIiij{ڪ57K7zzQ5K0z$վIbTUݴ>5/L R7sΕl$7TrNfy,um^77F6-^6R=Uz;(bi!̵m{ݮV6Ǒ\LS;(VU̲/W{Љ"q$[&oJݦZԵSu믗k竅lv=$Rɬ7JV<M:-ީ'UCvFMͪUc^:MzZ RCUհ0Z\/otVzy4m-J24*}|Qn|6YybNU4Wb+!5;ob2:D^/SZsJ;3<=}k6ZkOuK)pdmenY*Mܸ溪֭T1F2jnϳ7].]gL=^JodOn{kߵ^4Ϊ]U,ղыE+jdmvӾSS6M5I *NLx|)jh]# ۶$rW71Qjpuu#idQyxuy]5fX/ujVN#p*i$^5Eĵnyc_öV+rWnjW.iI`$ WF-MKG5A$h+U:Biެꛪ'V7WPmy;Rv{E$E{sm|\$4/>owѨVW>\'B>^=̟_}Wf뤆uyW/Y@gWϏi{{sv?,ٰͫ4q5uu=޻ [k>/f>ivo_ɽvOOr J:ɇ6{N/~yL!;h'Gg LlCZ>.GAӯCUx޹W/M(`=~1 +LK|oyX˴On48/Oŧdsbu*o=R@{W/›8[@|8\L,y3tdoFz-j8~=k{~Itt^\}F_Ki,LywWvMa*OO~a3ٛwg'?p'K}c&קǴaRMfxy"3$/u͛=X~no%v}mn}>&Hzu𷙪^}re:{]fz>^]\` 'H,q4&崃!燴\Ocb? 7,ϻDOIY 1qtD>>4HOÁYViaV:E>I$Q7NJtw>}`>1_)Nt,kWwݛFtpxp|!_Ww;;'}N`?3R vuwn:}i~wfDԫ٫9nxze+c_3ɘL\kwL'w?i9MoVI~6ɯJ uߪ~dA7$>NhYH&)qTN%I8jDv_搤dsﶘƁyŇAmLs4NO~.d?ϡ:l0AZm{Q0IBדή!..(z UY3yMXݾ ܸM 44#~_TU;niS[yaq0Ly h LwXѰkHc{1iݰcMRÒGll:VKVNCerH Oݦ~c[zU5|VXZ~jZRj?2, 1HFMm9 zihiH&h a`X+$" !U놓56(;ťA{WhD b8Oz BKo4wIuKoCjWa8XPmh'͆H!_|}E+ëEV>/F\^~+ڰ'FvzǞITcԆC0=20њ6/=05//][&w 8- Ф8ZNNh.퍀[G*C ب`T?0|6yK h~kh~%OxgPӕ2}lfqcto#! : Mt,x}a`t;Զ$"=CA%ǁ*z:6 <:H#Ao ia0@&ECҴwiWD[akׇ%cPHo فʠMEjG|9"-M+ u8`>n 6%iR/t4tU&# \UZFP)_CH̴ر`dJIt% Zvy0o q$-fHC0'2tt)%xAj8-ט:paCFKߩOke)&0ATʋj`Icx6$:Qa5[``Yv ӁE^dᠮ3SY(mس?[dhHB@rd5aqI&/uw=+!D~DA5vGpd r=;:AfkAݍ.@ D>b/<|P;S4u9TuȂiȾ~`A/썏0"95{zhbde|G+~6J⼵H#"JpPkP,v1>aAчXz`,RrpՐu^m^r DgP!$kX~! {$ԎXL!(DrqNA 7Ga:$4 Jt ް&OH5? @EGLJ2w[c79v z8r4$gΐtB=@$xgÓt H`;X?ACHvyiᠱќBhC&ʫ8'X<ݑ@w [Y"Cpn"+r,P6Elqa@[Âs\U -PH~l>T~_LgMǁS{]!m=%p:[kr ^{8c Gy Vr[8K ]HmEQ'MDTziwl> ׬Exzx:oX*f=xpĭc -]m.ԘuMl "=6AkR/XNm 9[ ^<-ܻtt2eGb[ymfa6]} cL4J/4ƚ"n2*D)}+C8o%@W(Fq.ZF5%F 2ʥvCyz8/&N'i`aFq(bz6K=CX|b:XIE9_-6f=fi87SB @aQ \b@{50eIYJ**$RӴq5ez otj8%E8@Ep9`e զC.r~*dn 4ARB;2^~{ 8L="hˬDhPH!B+JGGCNjʻu-laC[5#̭`COsjɕ2usjZ] TV Ipbw+P[3k9__0ٛȡOAhUvEhy4e|_G*{u"z2Ӊ_T!,lN[8{gfHlC8FR7D<]_FYzh(\ӈ) BY뷯MEE̅3+W2E!~9Mx#j&:2ko9-tY%W)'ʕ˼T]=_,[W"ca"=,䄉Ҷ-al}jO"e]W.78%NRQ+``8nJ &LUi(?KihȈm4{ۉGF:iNeXj8Q D] pZu('pُE+N5G>œIr+bȦAΆ \|&>pX+?Ss"8?GEuou^U\3jUqj2zQZ.g,w̫xU"GId(i `ݔ.*>cmI|A3}(70?IeVZss@nF8nA /o Wia(!#壮l[FZ7g/*⥼sF-s.{Bs} mQ^Goлd}]e}BjMJjƼViƼ%UqNd51ƞS/; "t=5c-O2t2g;V!: iudhpX8'hqZ *ķ /TuŁ M9,ɨD(9h^rh"y}DNU@xTe-S:l7't6'Q ۔Geg ;J gg\(ʼndKĺwB)N*;@RK0j\rKyQ"Isq<+Н$u>"vMwkɿtkC \:^HXs"D}pnGdE0|W%D6+bݛ={Zd'R!m//jj;26zBTT_FUusP'EF!%*0t%a’$~#xAM9<.mʎtw[%1q][jcG(K '` 1L 7e 8l5w憯_ђbd8dhG ]&kD oRw|,ʥ8^ɹtn X❨!o4J:PSlӠ%R4 9 W̚7 *ʣ!3t (sTdڜEXx}r* P$=(R[z$VWpۉ Y֏Lly -#œ~ː"ThF.Wnj1 ꈢ@pugxF_^7C#`~6Tl9Kғڳ'HAvN|:z="Jh)9k1k#z]I5cctkb`oH@3 ;26dGN=P FY@ 1\$12=rpz[SPw"HIrx@׃`V@Ø$^Rz!F#9!"sv92-YXs̠]ոCL -HdN) 菜' 8<4fq- *gT^ Pω u!R^9ClGGT`=mPm$kGIP͢g_`HʁwE9㻜V^9.\r^͝ 'Gl_ǪG#S4UƮYޮlvDT fB_V EGH಑c> dky$sESN|UWjO1d]SCtC^ƲFfdUs`lAs㻐8(Tvy4tj.֐: :%:]/Xv7veb6=U%ٟCHxC.lB8 J,%+S3FT#! ^bN ƊKI.Xf{3z bd(j27g/Xn'x4PդPz@iJ$5?\'|h]K Ie9s(r6q;InE{7ĝl am\_\(`a8UcH,%L!5.Lz1{l$Fր!*9;ǩbAvaz֚/Q[SWcJmʟ_]gd]ot%Xm.$7@g\i.'"WDY7h>gQ~j.¬I =ю /G( r#J 尢 Fs%așp(FB2;D|> j0AAz# jzn{-G"٣,h=EXr,c`yRN*ˎJh)x:q`n > Uʧ_I2P!KNE ɰ{;TNg崃o0$(^ƌHTV35I0jh*c6p2G 5@Z-'FV3o7j e/O[ wR|L߂уDZL+ŷ  AkJ901h=_=e1pEjW\?u kbSzAЋI .A;CWn* &hN5 I@d0uR9"#ňo.p$3:4ciNK%@͗ ̩Ԅ.X׸.Fpn"?e>½qkMRrnTgSk>i- PaCky˸CλO/_wzݧ$ZloRmdߝ|ao G(L*d&"N.\ Eyh; NLtPR_^trk!!rS|\Ȝ"S1ώ8d"  TՉ+Ry=C7?I!+Pl4w*(.c=s*o'Km0q_䫀ՉBFBDjhhm vc1ғ6l?+=Wy/K1Fc/O Cq]W0tyӑI,ԵiEieWf 9`OȮ* 3iB­G\P+e`ͼ5ZUnQ-f'`Ŭc׈JNjx<P ҺѨ>p͂s`UzVbU &YIր)i>Az- D4DuFA $ fLzlq/1PD-5 n `H@5ed.BL[Ȍ̀* ].[d֠%`48/2M( I Ŧ\_r@Y¡R 3 IBFs@ dpFqCIŝ r|`>5DF7Ӝ2=>އMwT^Fb!d|j+*-M "!r.7c ڔ TpWx2!t3fehL}QˇZ\kkbu/@M[rYXjrhJ TIKpy ܊oc?`!EpДo} gșS^=FxLp A9Tr*4+P(cZ iAغ|%2A2JKC(vY09tm#Kr8BL1 9'Z;DwY._ך\Y#zs5!bJB F{ LRe7k2ny[q(a)WP*5%' ͚W|r'j*|\6۲HVpAyW_e4|(aR!pxN@?ʍ!}IR^|\3]2DCCk54L"v zF١8C'vM g_PSA(#<0#5q^[Q1]4Z)a42 :Tߌ2+p, 5C /o/nѦm$ (m:eC,=/bSQ."CЌuDjw!"0A% 7tQLoohnTԖ/&3M^eA"-Dxɭƻ zYxUh$ʜs xL_]PɸK1 ?yN$|O3>_Q'$MEh*$p*p,}tP"y (\6&*Ͱnq~yuB\R-]$պMf͜lՎl᫮Pڋ6唯Ѩ e _=~_2lyt1ZU6u^gtJ׍jN[e{zxy^ŋ=zYy}O[p~|^ҿ._bsG6}:UU5|+ƟiuNͩ>֧C3u1f1XH6(*5\c3c Xo |=@D46W!i]= \.k GN Wd *놞Sd!X(X)_s)ɘ*_DVN-ihθ:H&}6#2PM;mݞ|49^IbXd2aV[l}<{&s^?~~oo.7͉pױjӟcsjO[Ycwv%n->V lTo¡OedQv= +>kV`2]FnDLb)XV1Hu(A  lQ>J<\w }2,'C JWR7ʆsqpˍ 'K9ݹ e*DA5Fqܐٲ N sH>N^@tQBF^ir%rIwxfӶ9,:V W*췾|U& i Q!B`iB_.N|5Fu2= )p0Wpy-J3J5k@ h=:)9_Yeͩ5,Iԅ-c^&pI m$$ШqԹ0BqTeeФЈ `<. Di-JIq\$Ԟ@=M*AˑG%KYL=Z Rʂ<r$aӐ#:Qt=P-_Vw܀>}ٖ80woغVa1W+m*UT|; *iR{., Si!|ܓZWq _U~@}MI .,J#dB>2Qsd E6emk!d4&|9jP7I $% pc9 M 'DGc@SV5cpV.gxdV GrvZYjǏ$, -Sۛ́v8zΪ'`%yіIP ;> ^xɇHY5 ylk&. *k.$ U d| OR߅/ ̟\6JtD'ՃBkPFh-.(z]+ڷlhڷ1H حe E,3J F,P,0SsJ rJ>$uyM=&O d|ǁlۀ _O+oS:w/NfꪚX`0xBh_I#a}'f&NCE4!kŠi3 z'lVn0?.K/ǡnO1X#ױmgcuJ7i:Zz=f1ZD\D9)R>AI"WH'`kBFF%5OCթ uǛ?Y~p]Hx(jQ^Uڻ5nO>NQOZ곇vc <9N߫};iŒ}dz&}|6_* dt[!ox_,+P5Q\&pa: SJ< bP!q6bWJޖR'5O%밍ڟ7FM١otUNgZgJwٚcx=iq?§BCq1}ƕ#VG" CI'VfcbmG~W(tU+ə.d ϗt~_< v?w=[ݼœ1T5qBuU.0<-:5d~7io׿/dyo.zB?}shٺ'O/KN- )4~Vᅣ?lwyYWǏ'"% T);V-ûZ3,\^ -zKH9F0q` ^wB&@qyo&$~o/ԋE|YD*^n4 6/$7ﮭ\oAKo14b=_O?}tPy1M\o9OǏg\o~߼u%Cd"ucᷰLrzvy?φ2.okmj +ޔES >oft{6&:i X5p!Horp)ZmO9a١SHt#SH' 3.fX$esL0@]`_˻۲矟O۫#k9W)a"-VXH5NuHwz,ٻ_uN7:W! ~ݹ =BәȋDEY]E\X~R%śpfXd`ϩj$6niPA"Y:;$c`+W:,}~Yfu}h$d_u &7_?owɾy섟ź; Gnj7,H,2JJ{ Lv{&y6oDzn:)z! >^hC߸w]ѫhU<u9):w!75#?|pT}"F5[Re8L(uI .m\2JĖ>F"%UL$ZњĞJ[QQ{wi+1酇r䱘 _HcEj$%4>ⲯNPii}dN36yq\ZVAw989 /4=D08 8] h3 DJHpp%&TڪnU{U7?L'L/f:PO| ;e2=Md[lqj|wC=ǡMe+WUìQ\t +ŽC&-X,aLᳯ AdC'1pTV/ [8 _3]KOM)"MOAlv-Pf{@.< oLou T5| 5: ieeTRZ@DF-iVdձue-ek @5 FWE"'2ь ƉvIl`T4h .8䒃6>?sdݑ]pG3`j8| v"r MC.(QF 2q›qkW4J_p6LLv51suxȰTs^A4!%BTl^?)72i_}XZdc")|MMΆdAa>%;TKoHMFhͶ5m윈ʹ d6rAptRZ!u=b}6#rR}%ttto_T H>3#kL'n hLGf͕ܶxB([`|^oW`cuwi_iY9!egIq- *5p8]σMw# \k.`+| -S0ʀΐj& / py0c]ݰhS=^t=Rrغ*ۀ VpvN쀑?:ӻ|T9]]ȿyLps >\+oMVRQECEm"{u$*yȠt<\ 7a V 1di|pi0+2WBK]qtʑ] iUnxfSOd9Ho )!Ϻ}̷HeLxؾ'$ܞRQnD)`D6Ly]!5XCG6zT>l+4 !947Mһ*$Xjt1ۚO]@n'hxd}ۈfb)@\ WQ㍵]""^?8y^:ԞIѶByGhVm 0""oYt \G*$*=Mz#rP7HV6'EJԄ3WSaUxIF,UuoB`9r;>B+G(x ӕȖͨ(~g3ؐ{1\g:2ɫu2QD * ^xX (u 8!7oq݉( ψD]N>'^:Zr:}p[cxXfY9^oZ$[Hi5HC)xkE<>9YvuW]зȀcZA~d'^)jl؊UFX޼}q΢hǘOϹM{Kz332Xt@XF IGbF߮^7ä#:)pc'+\eKμa 彁r٬mƈwY Q}Ծ86S g̚jh*i[JGsoKoÀs~ t!f KB//'I&1ɀh;I !^á/$l8W|?_T2لIW_g<? Npn`ṳBUFw¯Hʰ/"\M{Ff}(MjhӢo)Wta 0lQ53xX꒫Qo_NdwH!AۘiRI`_!c)đ̦E{;(QoKI$צ -Go8vCV'>|WHܰ/j~?(;.DCm?&'L̻B>AkD]+N8{ӈ0+ɱDk,iZwNfpYqj B<R ,C~~20f 褃dWU> [ AE\I*\8_TIW]|<?N<)myDXwF+Vtl^hD)0lYG*LmCX 7ގ-̎$]*A?4'T͆A 4)f[JoT "Ua+9iˑIP3*~A15p~۳ۀV)h0,u `l+N[j4d|OQp_7'Pr%vBrZN80JxQ6y9?Mf~CUn9Lϊs^ZS:G tB ;0 +e!(b_@T=㌓A: E+z F |Q"9e)6ibK{" K&D[v?r,} hB^4!la?C YNXCc{yG#'#FS#t#Ax&((<ʉ;& ʩ 9(VfuRx 9R8MO"<_FxѰ>xryO<\|Q0 :)7q6l\jbD^z`:q%0P>%yozwB![ 3!`3w;7bU H޺sCt(-=Ѷ E?0>]}v)7z6*r'C`LۆѻbÉ[RA`nz4© cKm@zQJiQı2M$r"12y:j9Jx?c\hoxEh'A%,%9Ew[:=DOOP2"+]nI2>0Xx58)q`M]rlBܽio [컂 a#f TFc\r== T !a^Β]Tm60Zb"}8iƴ7-r[8+z2A}ƗcSSпʡp p\8~E)gn{++VL7今0GIǥx8OCF739SF[ǵla]O]XRϗû)-,CЇlT͢aĦP"3|ީgWӵh=و󨿋eԹug'MBwНδl,R`Ml?B5Nj'E8soMԮ崑.Q d6J|bC&v (kd譬>P#r%(ͣ'ojCzqӾx'4MdR7*Dvd 0}뿓[pUd(HfY#J9FI}Rh$GZh#f7H4SGtp(I$ئd$[ `d6 70!1.?ueN ^F#`$JIzYt,P&LΘCȩn&:y̸<*dF)=3/.z`4"M}Y$,$aVu[73O)G59+kв$b{%C*YgڜqdP:L&(+N~NcEIZ;Ѯȹ45e" HXłY劔lbx=[B:Y1LG0]3`%Y`>1$78jh#Eqr,*Iܤ ,1"  >-t D3!Dtu,.|[%B ,]5+F,xGW9XA4:r#?h1߷&$([CR\߸-:n(sg>ZtSҙʿm|DХZ`1J(*Q9c66~>kK&ls9U  }:-#e=Շx1g"bHq9(VӤ P5\9OSKs-_>x_3n.^XX!xEGaCEȈRJc_L]u>vn{5rPFg'CmtbWR WE7BZIQX76O=YRM,=ADbUzHLG`%y͵@x #E;3.0X-|.^$3(4!YC *w1-ˮ(lAQvxg()&:%R+fD6nF1}VDj5`WCo+X8Zfb-k`֌o5)|Ods|n<(0 %FNx]%ۨVnƣ$8%O L" }qԃwTb Q`MxagJc~2T"uәelM{di(dۭt97e"%u++-p"ϑ Jn2#D;il\[i;ݏXf["P0v,4,UaV8RۨɚcߩJ`9s g`Z?H;°Ʀp[MF#EKv-ϔ'V׊ƘoϠkU=}:^PcZ̃`ʗrfRqN(oHýC])C[]h'| WGM+/[Xs;oae^M~}Q#YwI~@&="8gp(IhτW(9/1Ԓ9{/pO8BIUgy4P4už`'^V(;}#T|44;N=tҷ%o.ѝ0g՗oiw"u%b=]s)-7 $ݖ =9}t#c$nwd M @y?9u\+pܙUh!*UkK-.kYz^cvV&gˋt̂?(B| &@~R87=|f Hk'Okz)QaFޕ/ͅ3@t lӏ7B5vLz|6'zmL2v/Io؂wI|ٝP7bg*' L^x ;j{L²EO$``JI&l8܀d#x4䢥l?GVFԮYA?Dfɮb;i(@ZJgFEPZ0|A﷖q:w؈}6r y?z8+nE]bZЙ`Ba+Z0CX9T}HٟFvz5Tt*L>WJ [1 b[7؜h {,ijW!X07m`r0K :cgM}]U))bVۂYJ/9~aEG*D#S(j`ZYZJ]XKF4╻&h 5Tw-'kW`錻徶&Lȭ^+yfoik9:bWԼʱ2bqE?"C<"='+ınqrP"gq hCѳixl ,޶5q306ظS7^ h(AYY4aP!yXCJcԾ4<,zZ:t $fPbPр^1 #oiQ#f$","NKu86^F] .]֎hx'E*2+cb)]FDx6,{VZ8|I0ejaPHgcCY7(.Vɕ=*]^2dP#NbxQ \v0akb_K~=_Fl,戺9c`:,#coq0:nAu W iK2:R/+eeHqi4l Ϛ$C5VzE1{yZb0?wGAE%9OՎCKFD7Є㓑fZs?RRW$e=c*-PP|wRpRIr.dU< x*|[ _2O*3hd5^j)N{na晜ELj3dĔY\aZ1RNzü.ȃhd QUT0$U5k>7Kyשׂ 6ZRN͸Jo%Eu,)45/CT&՚Zk-L CT7}7zmCVN63Uh(-$k$4mj [jOѝŢ3OΒP6wL Ùh}3vIє2&慔> t'+1!B1pFS c+NĦ3kܤtPl9y܆>d>L)'a&3ƄxU(L^<.јL:WiL^_cH?3lBf}#^R_4*TtbH&S^\tOB}gf]YNrZEΊ(ѾSJzKq ۵ c@Aw e&5-eM6'L%[kZP7rJeX[pfR챯HT[+G*ņ) {} ?3-ENb=%m!!!d^o 䆘zgLt[p+`bx Ƶ>PH2 qT`Y[:{ثoK*cg0j |Owau݊ZBC1}ێ%9vsC H QF{ff Ȃ1&Zy"ΉU#u*+OUe_^Ѝc7i폿?|󿔯ѽ/ۚ?~?~W>[_O?Ǜx}?ws|ۗuwhO;??Gϻ/-}+0Lg6f`(_77w1܆30vKw۾ħn*#eg`]?}hDZ|ݜ|[}c`ٿ÷ÅuY=Ncfz~}[ѓ.g)ʾ ӭ}+b[貸}s}?a}W4 GoGˊm{ۿ|VoeYLT6X>V0|ud ˇ[}tRȍʴglTchŨ0.tMQ~Tw.Ⱦ`ՂRSx cW7s(ʢmG }(_77ulKlXF -a._rooa1i-ˡKk.O[$U^F*,ۡ[t],OǩMu'~U"tdvvbf[AWgcOɭijN4dvR碀.Q8/~Bȸ0Q>?;>9|]G;:Q$سuvsƢ4Abĺgc=/ ]*F\QYBY c&D+A{]Jvaez沫sz ُ#Qn{m?‘UOzVG݁@,0sUhpc'֝|{|vŨ^KuVݙ~?GA~/ek%g+vuG9_}owl//oEy,^>{|~[EcqC_įֽP'z5lS냹<16C?o!n=1uNz)Vo>}~ie(nƃznt܎P;y[O`nvjj}c횘z= rNRx6i,&y'uEsgcu:ChY=&_"y2˪]vW;" S旽w*yI>TA-v|ּ-U{ani]-Lb pd,0u <:=mncٶ䄾lߟ_ iXꫬeYW>wu]j4UvA%vHT%wBKCOpV\٫S[&"j&ظp5 T=o6N&3Hͬ';ٕF9p+C֕GjOٲUkyfUߤ):\%Q )b)\>J-G}e ^$jϺX`f&__npi,:E,pC^vIEHT%;;ֿ4Yc6vd]cf"JCfYse[%~Um7uo)@H] jr,-uv#GSw" ֲ?w$$PœøLASYSii0k)2&CG[ ׍~es}p .5 ͎U\OIH]x,44CN|8s%4l|ArKu<´}c߲vx xV߶>~c6qrz}rlƴn1~~lUWF{]uw0v_a?3Y3 VU?܄i9$zE/CÕY%5IA$% XUۼ6/~̨o H$hUl^Nu7g[1Cӱ&gEH!rXdL.7=.^-w_̼mSP ض*%(\xi 첩y*b󪈃A0n* MCuRBc`3}^{:]o k>Wb&OL ^8$8rJxn:T>P˫ \e°х隣w.?w8rs/ƱusnjwJktQ/|7]x r}s tʹ_-mΈ* 'NxXks̡t=O .56\71fstKASa,Uq,|-LrKQ`#A g(=]({܅;v-Rt5:7sT]Kgqjkj "wur]|NU* U?BNcf;C PW+q#u:ifL@3!qM!O-[8тknuMzO7"(6a41 &a~`.Jxhr9[0btݝFyt4W…3*`eZi-S+4]~c0`6i @2sׄScfGuf~%s^*a6|kQsHzj|[tN\i : @j4 FzP8\NRY#v.z :#1C"T?? qdm =xvyQq31y=c^{:#`|+UIkNm^1Ќ#lөM#Lf|z?qCbD bxr۪qcg[;G\ a;[IGM"84FXRig'EN҉.+a7 ^< +pډ[zH _8 ˵TԥEqAT&*NwXMĥB<6P/_XVW8\j]xrf~0G 0f8ga׏ }ז٨B͸itCD\o6|0|ۘc7maL0w@sĆ. @iG<Byi+3\3f фZƞVR؞f8fus^7me8Fs؁Lskq,~ [~\vA|\mn֎W2@7ґ;Σ;V/co{[XGE1I48ŭuk,& X% ޠ'څ?b6NQa&ӟ$-ĄqV^UQk-z-8b&IG^xa_No{^Ue4p\aBt*Sʆou 7q[ "b36:0=/&{YZq'5ۻ\n'Qx7Z3z^g+kp\ōc; vUqs,t,/,%7?N^O9)2HOZkGܼ/'G/Cf1w92_c!I0+Y +l[nM_g9lM ۑY1ynιq'+2BOeu~oD7|7wtwfg A2`6 L=.Ƿ0vŧv y$6O_`43e vAj{Yu!Ew۷CE!ݪfȈ3Z"}&-` # K! O)nb lTXkc pu?FDy\ӵ(ҟ =Jҿb)Pv4Ar*Ă<&MN-@)jbɖ! EdƮ(aKqp Cܢ~l-=WȺ,nVaMp=/lKv-+6kCpL|moy XFaOj'ιBk|_$XX/^4Ǯ>6kql< cݝytF#m}ýHDH}n "gƆcqlBv9pQ$vH>4ZQf+4|@١nqHzq:<Rt۷ HHLfV_ZTo&G Y{D)k|690 w𾹜zd,1aJUGwбpZH$*D*HTCˑ?}ςcXn(;$8BNy8DA<]__}UL+ 39N97ipаBls}O* klI!ϛ zYU>g_'js:oFm6aj#➰ K1ZfrѬ{)$Hyr^:_csN[Ar,גc`ti*G` ̀Q Ka|@B?z6 'l]<8X Fqeͤxk7h;2{p$$6Bwxw> :>5a%F!ziDJ hWlRscA,<<Ҕ[| (I>= تh}xP7}X[/->MzAD!]ئ4:X~VŜ&ڳJspu^m:HbSSƣRwD܉y;>.GY7LEi:܋̢H̓&L {sBC#0+U Kڮ"Z-A2Etѱ{BXI%ZA B`}}z1 X8^ ׇqɳC :e@ ),wV\4@/[qcnb=P3Q;aJdZZ7(L"!Qρn=WTg&;P#B2qmlLϡ&_D ^O\ޜL[<}bgwĽ\F@|[y e:F}F}c]#y_;- "3 q|c.!^6`B tn2򎡊D9fNcgrtGXrA]GܕZ|ҽAR|?r(JD 4F8%Щ>DP}Y߆8c^('4DgȦЂRVc3"nk@j_7PO(JDhtWibR% bCMݙۺLp+SM|,rtj.읏~(_77c>Fg2^*0>~@.Ζ 3&WBD B3 fsn,F&橖E֜/[bn^=}/-V'RGz$CQv.m G8+ǿOLKڊR$#ZaR\&64)(25d?V%xOFZDz{9jd A#F4$,MVVE(A@pG<R҇]\F ;pWweVJO"38"[H 0~_}O8 4ƤzjRڧR(Smǖ7ZVE Տ$6Wwb]HN`UgwZ-|fƚuӠ_Rnj{ f)jP@ 2̮{ajM$u)?G*'JBiM,9"ET S-E` [O*dzJ "+OΤ2I5S4S:*_*s9m%tsދ At˄Y7-<9( GzΩx-i)qp8)JȀ|XEd c-p:r~)O;&b #@+9?ܝڽ7\wG" t &AYPȹ.WlHak-cpu 4n[M:EEvL ; !OeU\-wFRqEsGE2+eU.A"YDij 6=!0 g"Rd] ")4o %D.=J1FLLLLϤ0AEQ:m$^YYIza`IFF0@ !3^9b 0#:xi "`TE_zw1@Èp&z.ShiԜTxNpcPa%$]Y6/͝=qG8s9ei6`ty=@33.:$37x"0*@dezٍ\}d7=9CCK0BXP`əB3l=gEhUBZ 4`D]I{O6Tki56RR'7>PĄsFrQ  (ATR?fqn&J(`y+1] _hkKe4Wfic%mLNU=ae<+$=26ďK-3|Gԓ,IRyڥҵolf8tLh[j~/w .$Ja$VsOC O/MXT yhiʍphdBiH=F~:4aA׆#% tB;XdtwK7o񜨹8 E; p>ԓZXɊX4w P"]`](JA^k&\inZڂcJO"u+Da7&ysH 9  =wn4u"NBm*Nu(J+f)M6=6g&29GYq`ʄ{>n ޾wEm n)N4s<8Sȋ S) adZ^/IK!p Lފ/ q؞_vw- Jˆ$S}=)9J.)h}z Fnbpq4[?ݼeP_׭|0+::c+Sֿ $8h!8Ri0O7v&o &gW1m o#ҷǖ+J|H&I]eH"0yb|~hE doF) &?0$cI2\7tJ"Np𵹡,Oy&ԙ! , >E\vKH.!}>i԰{#*Q@@\3=zsal7:D5Ďq?B=((FrE) HmM)&y#c -&SF7hRDi(Dh##p.#kp/z*6Hw#{zTh"lAJ@E(E{.8mynXrRt6E(Ե0F&(]CR1Bf$,+BzF A̎- 4 #4ADHm֡@?o o X8ie>G ,=$HJ̐Ol V$ 1+DRu|G/އpE\R _ow`ZCr5 sFfOB H#or|䧒 劚<0U,_@)߹jlO;*bt}hb;Z@; /4䟩oAF5@JFUJiI[_sqHf \?6r)d9J؊n;3I -ݥ28"q-e m`RE;C'"+#s$QCٰ Nj-^犼8 ]<< |- 7&$z` 2Fen\'c]u%vMV&_"5_72໾y:/[7f.aށSq*pjS=HFMDz ޿DIgQFtq$P~aS+aT#cr|j2]AxP*G$b$+A76͐O^LTP%fN?OJ6%22=E641+X!{\YGe<6WdVp=e}7 9-V-S% 6g!AhyC -/@^XrsXFW8쒱%i+~~Q~fiHt[L8|scG {bv^f1ޭD-Xa_T~B;)V Z5Iy1ț\yeoAp) gPlܮUKi(R Thd*-eL(OyE-Ek 8"˩|XkOY6*VˇA2tnRޑgxD Vc|7*7jZ(ir3-=lm8w)$&&`.E'v$' }Nv$1 }FlYy}̈BCV1}ۮvsC:%JN:c3 VINboSK{k]F9N9]k_伌9/_a/\[~}C/ï㑔z֔۰Rrn{55גKh՜7oySs㴿% N؜\s'[GiޞoMI),{Q^S=ueY7̏=w([iwo^`Um(s{{%I [^V5b`oV^0۰WG?\[y߸={8pvW,VǾ 5XK&l/=hZu Ør؇vЬg[@);>3Uj_~}Ô1 ӷ_0}׿{Ͽпݿֿew۷ym?6qx_ޖo=nơ}7b) lHXnqVIUN\aɽwipQv6ڲuexWS+҅#cAZpJ2NJ,S$!?`"X- /FO?9_~ |Ӥ&OP~wWR׈wj~7-,AVe@}Q)z]#+<,6J+wMٕq ف] ?hގY w],E}0Nť:; ȶQh>5f3d&BOΕ":qY4KG: `uu@1~(}*I`hM7kB! vӰB+,Wymr fR..w=`l~6Fsd 3!ƱR16~_dZ3NBlM]FcvYyZx[x [fruN,te^,nJ.u+7a.ŷFI$`+$v0\KȊ+Ou@ iYL*P6;Z 5nӈm}?rm(ﲽ"?-˥ғhFm]2ςw nfE[@->%Y`̀hFlG^`) f~ f_`Lm0iފ׃WP] =~tEX,f!TU *d&'~V!0`i,x^t } &N*m.g?;m4 Ky.^n'iHa(;*l&eDۤvM4WgڞڲN%ͽ&aAfv{U+4(h Ms8v>.^6:NKȊU~"\wOUGLXǿ?q 8Mcݺ8q;//c:գyŜZ֯EkҚ)Q!W0{_uL(XAI7-rz~;~2ѾvKfqس ?_apVϖ)?;W 9ҊӃy/ƎÛַ^I)~eΠzVhCo<ʫ9Y֥'Tjl;S{uԽJ6Y@ hA Į1/``*eL=2@bqifВ(CS:O.Y۸L+}o{']e>lme=8 ,2ԃ=x@4L@vTAob>w])3ᙔr~bR".NJoIp_BuM[6;⃴? l_':,9-kx g3?um/p<굦KRfR8r]{`v~9\5bgf@,0;ABQUԏicג N2! hv!(ëAQLe oev&XH7\Axyf^ڻ 7pMGnci"aTzY "YWk̉\nǯ9'diH#q إȱB:<ЈPօޤ FJٌ]b9_вUY -ޠgu+^B0@ۺN>hxCp F0zJM n&?Mݺ)uMO2Z)Zq՛h/2^* xG+𮰘3>&QCQfa}\jR/]x#@aCT`Q@cS\t<*%o`8Xs &њyDXX:2¾p|zߌ!Z$P *P#14bXvQba[RĬ1 Dsu~^1W\6 U Omɂ] hcBb06%T@M,s:zZRXf*X ,); D m5BJV) @q,F^YmcɬʶM X+(I}sӵQXJsB5+Vlσ2ggZP"+VBycX2h!|^70|dF^MƯa"Mmmע2(AÝlNd"685Taߘ-@%@ j/̮כ41, 9¾S67^;Z2Ycrha@#oݦ8! GFK' מ{yKY!mUZzJv̡ ҧ0t)\]a[-RMS7GָX$ 9LUpLo;#E. x94W`C/>El{3XmQ*Eh)@4H ?N$& AetYp`IRU^4JΐjUd U` Q3Bv(2g,4H%-*{܀Maw4JYp G@: SD掟Je2ҥeH~_(oPG;]_"J7DȵɝJL'{V aD4D$ta=v,@DdZypr\^VL&r3Z/hvgi$~" f@8 +bm*\%춹Iw?* ^<,drbRv?f-'QLW=a#( ,aE߬`<þ+OvS*! 3at`ˌ8h.d~=ᕍ$ӤȦC#sJo)Tz-koA QQ#>i*u/?. F cyiQ *n/ u!# ilB "7IJ4B222̲P%~]0!+ vz2bЊ,{b]fZՀ.K(Xܜ(SV m=tjߣd)c"do2:i$]$.6M ID -79C?z i}_7~{m|ko5 b?L;3.oe}~6{/GK}+%"E_çnn~ַۗ/fg4EDIԉwNoSm ^<=;֩ˤN;WZA%Pr0#7&+ Dg*:Ͼ$:#X$,P`e0Fכ.(5nW;P-Z" xKMB|*|'abD)_Gj o]')Zg>Zf]Y.˼*Ih-uSEGTG}oҦp]3 Z5_;op¯V ]gƣc2xfo1n~}=i(.%ͯWPW޾fN40gͺki%6h_¶E7><ٌ͓B&s#%t&1nW(3X #12q1R$j#o5X%1ҫ=Eg${hZAr̵SbV:nvҝa$=v D7]䎰]p}Kq)1 A~WF^Õ&/$jעRr u$n1؊'9=H>U$-m'/VeTg"JL0" i)({r#yÅKYV;ayyiQBsi~Nl 9} Ł7`#\<4;rJ$U5ȓYf{);5Rn ֌|ZyT1(.kE^t# Cpo[LRl) 慍$#Q7ن9\J͛UĸyCKPvve5Չ จn_|ԆL.V0DABI?~َחQ#ޤZ!rY)QTB]1f 7Ė?PVz$jFȠ>% ˋ (baaɐ&^0hXBZ# FѠCD^E?#If# (? LD5C<5U[BW}Yw$3K-h=-L&HYa,̪4(i I\)-v2utczD"bS9c7g@n*nw\j](.2PA% @&a(7I TN$4,9"9*HI!UK?06^|yxqI_*W,u"*)>p^]K> Op[qP) (]YLfGX'*ϮwdvQ8boC1ggM gTK3NhJuyɟk#MR٧ԇ΃l[B3q)]* :B<ѿ#<o[4/ Y9h? {X*c #a\y982Cm3\P:Ox@3ʹNGz/ BNmחe(k`}~(s?yDr'Hڕ!(J$zScd|~g4Ry4'Rm839,Ao"ԺRRucv?R2p e:ɽz<՗gizLq6WP~eGǮGrI o=UE`n^]*}:m ,02to!B)xñ d|C6_ōoʃT#+"# dp 9g5xDۋ&R43IՊa6WՏY`3O|ۤ7MQN Esc XfSPsf#M.랹= 8k/ɱ¬qH`WRR ڪ3qR-qփ {X .c!wF8  3/6b SenRN.OR3OJnCig:ԱP>j($;=W<?\@>.&$^2>.$\!$ȸ9yRtΞ0K_hDq%B>AsMh${Iݓka B5D"Pܚ&%V_hv"aC= ׶tԥ -3KrCd2._Lo3 xTfA.>?V#J$ 3uawhy{d޽fu4X[Xa3|duTXƠ[%b9R*r2ȴ̕D Y}>dWT6ʍaelfzgdb zapX a>nµ".p0'RQ.ehsefF D vw̡>O|\GpxB!H^q̈́ sHu!#be0+2T܅',K="I\g6mbW', ʋhasM<ɗ7Ubo:~@#ST#S{kπ$G> -W+ľ8^x<($Da7aZKL57߿}T[u`f0}B„-f7R\}t1#8.0X)pWN,̜--c=Nh4MhD>eΚ i͎PL]>}u)#¹jәŅ{ٚD0xZ2${^U+L5a]EK/I|>0-{M@kbro4d+q,_СDDmZԎl0_t,(R:p[w{%OL_ȹH`ܒJLT_JWf|#KU$ơw$̐p";}ƅX,7hp8?P%a &zc0n˄a6׋҅fî+-m$?ĐGI.f+lT@m|nnt_fc-tӈH4Z~lFqS9Z;%[熺)*YYt I%{\620m2"51ZT0l+{܏Pԭ/7sO=ɉiRi6Ɩw nFK SIO`$Ǟ:n~&:=@$T!\BL!" [q,|ܑF۰8~b[6x]{OVj/5D v_ ցc^aS9]3)}~j??yu3s;y?O<:9Crqndȏ Fzp"  7nݪW/\t|8G.DE HSXc}K ma[o!_`yj:?e1-#L$=ar[eS,+wkg@;SN8848iݽ|Rr%.P"?y^_H0KmBџz4 $ UYe&fBP4 sԵFC.K' (@|g_LVZLK"ۗ7: BUL#shPǯnBĜ[{ɨXK< ,RylPv\9c.7n8\ъ㰒,sA]Ѷ< 43`ϴBI{yrQ)W3ё&"@FiG9٘dp?Su}{`^Cq'cU[(Qö2-L4 #bSi% }ʳ)^t`|sȗј 7Ո0AO9N92qJƒIBNFT~2 QQƽ0,X=fj&[ h{/B;SW_33Ksp m',jim[_J'7-֡B;H'ԋ,rʂE9C`+BiV>=CBh BKz(r5tm>prv讝RSr.g 2InG5F'Yi\o$jʩFhqe2(GW)z~b*P kydJ>\L 'FNrQ@6K#iIS WJ0 %-^8`]Fv 3letĤ10&R~!!ΧH{yT@TD2r”ݡ)*fRP,aC)n*Ǘn-ptL-stdMꛆ69uk4+?}n484J#I‘X|m.y* $ˌFCKi =ag ] ލ])':h Ϭ>DL>e22B< =Ig!Z-d]2QjtFKZן ѓbKz%߼`V@4>8΄fr?FN-&? LDvX g3F,j7 OUƑI晝j|F8IZ<6 %@OAhbƙt$ ?C5fЈ/tgTyWRC}")թ6-/̟ÛFFZ{n (̨>C}r&א#)3M) EX5h8xLƥ3WqFvXrcPY@LY?BBREɤmLњͽ!\#>O Md( : ~ܞ *e&(:B#.Vf.N`SgX ¹џ0BN$`,R"GxܦKU)JTRނd&p+Oc8r X@JL,w/ , %ᨠux{iQe(BD Mo1׺ f?H3SCIS޼D E0WdtfW⥈ɔąF;l[8+%HcB8x= e;\7]hfJTr0ax6&U:񈟩%wB`4|]Nu1{CdRKK)%#/iFL|))P\ [M0*cRrP|KP€k b "Ъ%%HvhlJU Ǔx{d4d2)KvCl T\6v!+jO Sכ6F5L{8/ۑI,qYx');ya ےS@yt9r4S41i3qL+O 4+0 m7$|bV`}I|hZE%{/ uѕJ;h+J:")1x^:]I\-BBid Wh)U8mLt,Ox\@(#̜]lu&<AʣZt6.5ܢӅm~eW|])`+Vp:%++?w7_A(dvF7Ld~ d`Z OY})9 87)z]9AgQ8&D3·?~FO"0)TrD$MIB\vi^ i=̍]8$xcll̏N Z*Q^FK) DCw7fd >^'?ڗKS"V.-ǘYЕ, sD%4{fW (9(voBC*0}ێ8s·̋٢$Re`UUt ~7ע"tҍ_6up__0%~o_۷/on%r-G~Y>YedSIJRKXbYwDck%R[#:z1T[P4uj3W)ҬsQJa=<6BR'a vxG ۰ZSܜZґgT%NC] a. Bj NFms[۶r1c_l=Ķ guO1ԖVˏ6((LwmRM;su͕4`C*-mѮhزiw\g#J::-='E7kSxlof1ay*t`3F@ laHO0)?8,~c,n΀_UQHA%hsJie<7mH&.CҾ/F1>¤; CNoǯش3RTl]Xd ؖ卶ܯ2 3R=?ǽҿoXO?pkcž%|7 Wۏoo__ x69iMo~|w}mm?<OqO98X):ZJ5"iﳝ({ ҶB)5ڬ4* 5Am48+5>h6u|}m$r{+R۾B' 0}bbPΌd;mE2~1>\d=J?14&=)e?7&ެdR`~FTp%2dz سVE]կ4gk8B̕˱3qTfrSe 6̶~ Ԇ&ܹ؍,)7,$޸ C/,ҵ骟:vir9cqun\Xan6f#ڹR* X-q |YIm)FL:V&%-e_0w\0~KlZ7axvŃExCk",Sˠ*;;Nz m8]O|1RWzZ Ư(^b(/.}5? \! T-jmmعyL^^NqA3x*;MyFmFpIOxm2oܶkܶq!P&KG{f=]I1&e^ vʲ1j" ewV e'$0m.)xnͤeqG?RQ2.!D̊ bՅ.taXfW}+}aH0iŤ?  ƅphr !Mǒٳhl!K8aX8a♑ )c;z{p r'kaf7ߌv=ƿ! zIEx Ѻt:xlǺn+:{,9<8*wmݼ6Mg|62T.E: *U؆qpGi}Źy? cؒӞFNjLi;Xeb\4@b65#8;n#DX$YAj x8QX#Еi\aRi\4VTFϒY&ZmфNQZr1t ύY~gW!$5$4fmfd2-T:òUН@i)c- ~#\Ƈ>1J*޴c Q#2eN- -L, 5 #3M+Y;:?[XԢ*ӡ*oo&~/o_s __W%4_C6~eN|'8: J]83« A؛cߦIY;sS +mT ܮY;+w,N+Zi;mjU^yP4MOR$ 1Ca^2i6zbg?*g,Upo8ʙ*gU9uBۈ=v$ߓyi8G&3U U赤,6f:NDuRz\,V&_ [IBVP`B6׭Cdngı2}pp+okFp˺Ac$ `߾skB;s;ifߡ{$\#4aVP 6nNj#7`Jpl#7/ qwҜqܣbހ;$Ii@V?4CL*=*8kFmwGkCUe ";O կ]XSN"(x+5aQ{w! 亊*(hsBd{NLfݘzZK͛΄9\k0ܣkCjuY,?}Ng4e q Bܿ  mCo>lƠS0 N^_6 =f=Zvum o?s>_Q)ot߹κ0|?l:[jBF+iU\Lߧ^Vi<8rW&n G`6n7(]*WUǧtcLu *pݺ.pJWt !O bW{\rd$0f |iII)[d?PxWnkxMU*z<.)=8/HѷoukZ-]p=sMԟ)rP;d78u I1UE-CJbh T»oўׯn6wޕ m'K‚pf.8b_7 K(Kw _,b:"q;DOYh8D JѪ(D 0X]VՍ( |Wդ94uQM?ah0^մ 2_MNE*aM<OmXCD2ͽF9rQ6yk?xp̸ۚy_!D"f*VPuY/!C4x MPV_8X0Oq02%ؾ,`^ kZQxkn;'yt:\`+ N6q.pEДB&5o-ɠMJ+ؒҤk'5n f5FڔieGlW] Ua3z QS\ \)agatz- i N0$z !aR^)šC\ض0~[SYL 'abMi)bd(1xEZ '&I\A֒ jZ8!!"?E=A.>OhΖrZ7 v7zs 0ҕ0I!KpNa][ʚ>gY[lY3@A [棂ǒwEp[vctXkS7=Y&bByڠ{`<Л $4+剟$j9}~N޹{Ԋx`)- K-1JS@wr#x82@Wv٢mZ4϶?vǮ@(s"qsW_JQ=:_9Mo?p{*&y4+k-$y,)h%5a8#Ŋ_ԓw؍"恭@N @ ]:ևڲ$4RJcvɹuw#/Q A@09 W8fh% s? I5-eI5FSؿV*O ۠[T4&JE2 ò:ni[ REI=Tǝ2ai.&@v7 Vckb5Zw!HUS+t r7mDtK{(g̝ҋ'MO`5Āݡ􀠧Hnx:ST}'A0vW>quTY1vvpq=Ddl#ԹX:O.\⯰uG$§$Nô«P-ZCZz#Z=:XOÌ֦rޑx}]x[iWcRD^Z|j8wb̤T_Yt/rv~} ,3_L1r RQuuUkǜ )&X}- xyʢF犫sgY0\S{iAj?tgz.`|(šYBZ!0zư.# ]o#\L$F(@^Ef!`zrp+~Vv9]A@W\9=%. \b ȭ4B,mNy[}InWσv_B=WAJZ+-i %t̝_Uc3hs p0~/+Y_j〈xh̙gtJ~~ԶU9Kq{4r+yow?/ OU!|ϵ}I"H$!V<|^J09 s""V/}ih_z@0 j.B谓EY,+FZ˃jy)D6{ ݧFq#ލU{d{DQ&?!pp=ƯM]kIXĐ )¡H@,ИJ`&Y m둍=1Jp5M|cR1R+͜$uK '{{2,(!b7)+ 'j'MΔi.$c'}O'l~,#Z 'L<x{WhF"8. >m%} Zᵖ=}5G_.FINӲVTX@L^d_zfPM[ݕwvGBD !ɵ/F g4bL"D7mzw(rfW- c nG:[` i"x.טxz>AKrpH^v >BOd=YQ{~$s3֥;eܱ>'|IxO F|}[9 QGquSʾBF~l: k9Mo 4}u/o2tJ[EdU ǭR)2U3I-oS͖Ftu+ 8!)0mD@FL<{2L9u1@SH!M+(2!ԅ};8+<@Cb1`L»!cºuZ-@0t%3[Jrmc uGX9ᅱ?>Uoi[qWߨ{[oӇuܶ8m߼3wNBRSڍZE2@l= Y)yyq2}{;OvU{Z;:ձ[(/V^{'jI˹kNW~n>{Y 8!+,vm$tׅӡS3z>$vV|JZ~#W{a":k9kIgakȷ[zDLaĠ&WRGE:h2[{b%8p!:yD:0p{ϣN'gݘ=)6]_Zp ]Nm32Rj0DHۢ,"s2 ™<~;I)+3qǎ}7;2:8ĎMGӕ3w ھVXܷ)1VC_d ?7hDZc끊2lBX\zC.TN OMJ(Z0%ݯ.ʎAj?ae%݊y&kc0+fFC@Tg$OEҏYçgD ǖB c0AՅnsqX{s |`&TC sUzS)2 4WdGL=IΝ C`$Z8c؊I4{Gb)exH]25੝4mp;d*"b1oKRV+j$Q%$W}%ƿ&7#=t/rmɉU$Gےʏ@/;NS i6EP`TLPMv zkG),!!"&^)ԉtF靦#= |PHG?V93ViÿRZqEXv@!@.=DMY[^և6F e2}- 6V˲k/S3p&HRm60YV?ɗnv)|bC י -xQ~3S<2t is"@SU<ˌ酇i3 ʴx3j}=z^aA ,(V&I=4VNH@xKrs,#J/P'S̗c편cx{+@B2K9QEO##LH0ÙOasm()ij-$,wK4,OHΜFO]bҴ_:ξpïxL&!"0ӎRxu|Z0Xvp5*9ta+V&//ʟZft0UijeD53ת#OI]\Q^ޯ ҏg(T{k!jmJx2VdCZiIɻUn$&z5+$a%Pu.+ID0V ue>9glRhz50G?¹n 3Г]Yo6jbȧh7i"~4=ed >-!|hxـQrg2%;NOAKr7 DGs Qݯ-̡S.EuSd:!>w:&H Hڔ0̵an3] k2dJUs-E@ 6EĠ(cYq  㩒ػmz׍1˜ܴEG "itƼ19 ?ɩut~\w~i\*rOK})[1C~gYH+ZkC ]+m=A4hp-`%$m*Z 8=])Ώ~#pu6: ,fnϾ{ &(3]e~C9Dxb.pD%Z:F(Lj.N'bնJx7oZ3aJ<]ab"j65K:1Yhwu4Zjfv0Nh{ sNa&{w,ic$Ts8E˩ubS_^eZ^Dwf݋v~54xLJ :=1+C,m{)e?ɝ7+05wyk,r uszs$@C<م I~Le}~7je(3 Gxz-gRBCD1}ٮ%9կL);v@9 dVWr46gAмNjt3yDܕI_Ϳ<׷O S6La^Oo1J_^_eS?p9SWtuj\RJVX:ޔ'|]USudҷCkhֽT?ׯ뗯[=`R[k%ȶ:hEi0ƷQͬ0vSZ+'%|fN- cx3>͝6[@~˹u ͸}Y ͜jnjKUڛ'Onvu=ƒ :ۖVQ6mVu}IoKǿ/'~g׵״S§߿;o+goO:znZ0n{}oӰX?L`˧^Asn6m ]wcط׹*}T6;#Nsy:6 z emYv+j{6l]$sNސéydYy{zm[Gs-:ڈv^BgmJ;hz{.60Z*yczTCzs.6; |Ė)FH6aƩ5ް]g y?5 T.Sl4q6&S ;R^̶~gib-Kv@ʼn{ҍr`.ha]K;гy{>>ۗoA}6=u`+kGu\pA"}zs[4C<*&7Gy& 3mïb6ǶQeڨYLz̼웄o2X;$I I( P~$wKIh* MCEb;q}].۴ ? kc&lH{:u!~\ `(ٯU)Lm!UuvcɌ}Ddd`pޯJGdj}un .S2.B6s HmTo8T4A.A_ذ|dԱN"SE{9i~b*vGZ:M~IVVm';Ml*ev++z .r3uCמpLٴ-u<%hQpim(ODۇ J2[H"]jAyry1xfimYCnkvV˛y1HʹmіkYfOr%nd*锭Re$;{ǯг>@jGI;cr~n[=5Cn)晛-Sq!Q[MȧP,r'dbJ[yzqI%a4lҜquy\8) XM1dvv+ 6.Ιo̮a]ITa:uiI* !?,D}A aYnQxq9lT3k 1-B]s64A3ydd" #s2i)vX 4+Ҭy4 qax5ʂm~L.39.O8\p )]j'%${zcM;" +48 mo^i^k{ܵ=]:@zԢfՕ]UP^삐\+ U *aq]{Piϻa\`[`Y8볁2v?Њn|*}L!ڬ LpxfS;Ǚ~d2b3?VhЬfgVdCX.`Eh#F@>]‚KY53lJddo;{ ~#7*if֮{|@O S f-3Ty#s ejQ0t[o |:/1ITi&jQ.W⽙+tf[n5CWHX\1`Ja .׭;z oDm'eX픀E=]Buǖ!n. l.(q~|l I{GMsIj3׀9G 9W4=wqPKv9cm(p]0]0f­zhj'aWjIî4|8ȿy"`>ƁEcTFKQ{zm`Us2:rṾi/Ӆ2=\o>WЗK ݕ>Hݓ_#>(Fw8T+]tQXГݏ{aTʒ_7MKnNX*$\P;uޏ&[w8hR9q"v;٦l7 m3MXPN4[t8"~W)ŸxMiPV.>JS :W6m_/\Y=/|^8T6U DdtA(,a\N#5ޮT0-9hDmyЋrL- p6&(GG<- Ewq{L3nfON-,PpMfkuso8G6̉hDž 6\I_``9z4_4L;[_0za% 2l ,3pQ7%O9W:l= o^{Fl$ KNڲ 14w0 T.S24? R%߶c_ƮcC/n[ϡ;1}[ >2coa} ml]SKj#<x8x}OET[Ph8$ B02a|˵$|Hr~@@lVq3N;59mz?~1%c"Q2F`VFLfm`tq#1: AZSNnQmy!=hGRD&H( MD^Zrw4De.F\oCꄚ7)*oAn:J Qډmf^ 8}ݢvYKL33t lw[ :ڭ"2DZ|"7sIb\UO1B&lm_>&S͝"; COosEZ6PnHz٪2t\% 1(_R`502 V7`ikw=)YWSF#6x 0n:>ŕZ6:{e&$)-C- JA pkB;&f JÑ/wIcωT.0@Ўk4aBC[ 3hu)!&w(Gn\.Dx )[pgw 5,DK+!@P ȕ'0.]ZI414IB +OlFQK:+JL-ao e#Jij=eծf U:RF,t lh#=Z]{}X#Acچ؆]Inmhv5ƭ{*1`aUDIppcsb:kyxېcy '@ Ի] t+Իob9.D=|ӓzWy/iԿOJ?/ww^~__s F_#>׿ǯ_\~:OUzއGiaDy,AiXW.b>-Q;GծnC(*% FGheBFMm%73N\ (Zt)([rJJir4Ak\Xhj_ЅyNsJ{avo5bh Q9Lvj',-Tv &|OН eX<\SA#gxHZm]e+Vm#,Uok)6# 4e`FFzZ8 .S-/K3 7pA$sLyIM 4r oId_$yPH3: pfr7*` IڨC8Ëwc6zI-b[C# [v{gn~_sڑr W'IZVfܒ9BkҌ2#\;E=/Dq \:8NM#kP zHxy҂`TaaOv$.SIe 20),ÈM r/dZ .b2,$׺pQ ٧.{ Ȑ>I }#ǵ*/&nd@a .:\#ϯ6Om75^x*o]xXi 3GvhX ۓ\,]=ۼvƊ;]Qimg`wNLUE&Wn$PKrAId1?;ga@0Jv]t|0Z]0aa#8QdnOeA,٩ň^;AOBSwj<c9A.8N ^~iGBmM=:-DOU$lJJGQ< ?Gзsn+3uPjJޚ0vY ` @R߷ ĵ\%0 c3ͽDO== %dOΧ%dnVR[)#.;"(¬7oM8SހM, cEV W _ALih`cu>5j^37 ujIOsȁvs auD J'_0('hC 23$1(EO" [~dX}W5pG~z40&2(;`;Q8@Rf9WJ%AAĄ;"l#q#^I4V|[CY`FϏ#=r:QOb΀|{_/RqQCt -dbS%DfJaR}NIm^'`ZeH\N_#2c A;gĩImԚ C vSY} ƍs[50-Jq~;(Ӱtĥ"LE邳΅j*N{5H yb4[a|6 :32{/^d?:U yNaТ̈́Aࢽ ڧzЙD1.+&ZfdX[OCS?xK>B!t?\ΗS=-#Vzc-CR&5޽(pF4ڥ+,+[vzCuR\ WV`(qKv<gXa ,n5Sb)Rz6e"s4nlFBאʄԡTI Tпgۑbk$>HuОG::I͍!-S@6&e l?9e9\{[w8M&PzrݙhD{ruIيў瀚Me IAj3 4rC6xB:8Oe$nAG᪖tg& G*aU 8i˹piwq28 RӥPʻJVk 91\"/D&Ij bLR$v+o,/L%h {ƙ{h< YI0J͙TZH~.}W|jipZZV+,m5==JJZI,?ToJ#5ss5 }߸υ!'{Tp(AESkwYΑ,Q?9G҄im1ģP$8R`.8:Rj[o%9"mPuNK^BZz hY&nRl={$6`SRǵY j`UBcmJ{ݰ&3r)W,6I-#f 2I7+2=*zikYc y(׋Ԫ*S/*L<*ihH-2B~`D^1|8Wbz%X,:.ߝTP D퍉 W`ɍب.QDsҀ!x8On/iO2D"%qZ6@%z>=E<1*8Ԍ, {4qyC*m $& :3Ds4i#P)Ob[PZU R'W>h Ro6Nڏ] "@l 4O>@=eل_^s2OJC7y3 :Q˯UϩQvUS$$sR޺\)݁4~42o~1bܒ|Ou/=pߏnICvDe+. 'I'^q p?%Kʓr"Yח5=W<²a]⓻RgW5_+B'7fxZ{O›Xh09}yFdAwDF_K"^f۔AX{? p+oA7*:޼Hwu|y@ʹZrBI>  -ʕb)M&1",pyN`z~rcIC~BpTvfnU8Li '-s#o_p%eHBvk슽gBf $XCZ "eKy^&?g-ĩ%.edAEFX cxq)ka^5.V9]q*i_:]ȧaOI|("٧]dž- aI,\ztG -[Cf e>WD'損ts@}G I1Ӛ/ eW{x-Qys1.Nf O䩙} ۟/sSuYIz3 -޺+oǷ֒(!ȵJ"ExͳsRg8!"ws({rma&q{ P*X*#tm?@BYXS`DecvH0\SsSvt*S?DٝLrYi'"%#Qb_$ (' 0k4&L8\|%Hȏ,w0jಅBf0ZgS(bvhFY'kG&jvQh-ذ)L8œ!"5E#}Kn W_ɇm"t&nrI df[+\%4'tqg^vao1>S﹞Um*;w}ji"DcLyؽׇS}B*lDžpgg$A$QLcz7S'd.imuJ a3'b±n9KGh4O DCRHa@ND:#,7J&0$ ΰ^l`n&PMڷ_s]1U˞ӿկ4ۗ>?|?_du~__~wsϿ_i_ם?==So!i3Gu-5^Zrzzy F-ѓ2v#yޓ5D> qQK#z(@b <5CI3P/c1M]0<J C@->8^ c#hB3Ccmq~9sa55_Ei;0M~]=s *$;.EP${dz*-wO{Qp{GODqM !S.ZYƣ)}$Iȡ*P<8tq m$Ⱥ-f9Q,چ wA!дn&JȮR+D b[}ѨZI#! 3N̷yR}pPHC#a%x}ѕuH rye<҅In(U[a*]"?@-%D/G΅b$"M 'J Bk(c`zzd(;.ui1$͍Q#d[OmN:ٗx[ @(m KwԞ޾0<&c%("iaQdsGɑ~"Fd"|FHރ.nн5 $\qX#.&fWvڔʝg̃%ᄈ:++ԁ#'vK # ԕ;,h@J s!_$5Gʶ{F+;2&sNIj0>)iG4HӒ#׌*F 0J;Ԥ݁]Ɔafs d%0Q*)E=ڃnX.-42& ^!m >e袑Bݲ& 5.; *GgusA> ^T&bɣCB@$k2Vq.7F)IY- >DDN7n P gS1_S#TdLqʘ"3t**[zF`GFB'+} eP,a HZz'i$t.>b̘IhJ <eO"/r(I0nL S'MጦYD7fUbƩU$^& ELc.\>ϕNēRع=KK}Ζc3u7)y]`\SCM= ƌ.I&H^4T .` @%?ϯ~jyP|EhRr:pe{N-9G+IMZ-L‑Wki&S 1ͤb[ δîSQHɖ )8DH y !x<#hnJ\)X!(;H2TFUsF:x_,0Y~yDW!DStsj$df^~ D?jQ 7ntMJhIJp)rĤ] °V07 \ nBHI4a6JՑLo xV`zp3BC00}˲%WS7Wj@ j32p/ #OV9y7*^ $@<<<>||R?|~8|~O/}amNoʴ]迌_y/ʡΫM-m߫mO6,{+d/\rl)]飶9G+q,3Si)^ YGMfV~腑MY:8'_RlfjWGprr$ڭώui5U?C{J4GEUm6qkNol}gOmsuv.]X93vT=ֶPoGqq¥ }uj{&ַ,]"`#V_@>YExiem_Vxk/mKg4agi]}- 6l1|' =֣e{mnVtƃ,i"Ɇ=i݇GJarPl{ͧ}~ŝ{_JkUO&&! xpe)wlC`bsO=0x&\ڋ|LϚMmce&Tcy|qsVƿMOwGBپ\0Uv{J SHX1A,:\y{Ґ0d+9vqNPIJFϟZ dl۽2q\.ę җEm8/x ҍsn7}^ VEyÈQQ?LۋkNSSJʂ e*.IF;Fy.+\&z^UHxR6uV+AѲǝR'Ye/CZF<*Bnkƞav鵒g=zPx,8 SȰK_8..++o]X1uUiRo4#Z5KY8ⴙSX2d&NB<4*_GzZiT2/y7Mۋ͂wi>\rdQBw&|TRo)4Lz]ԤXjw7_ 'Tn UɤKoN?r^]> 2a7S 0XAa]7ddt3lRSFL /Ko k㚋L0@Cn%36rTkO=TytrK[#={?8BG|ЇqR >~HIxL niHޢ v aQג9KdXfE'61FJ_i>Dӈn=nvw[i׽=&٦b?]:=F.̈́90a"j:ݔ1>ܛ=cX챍k7{ 1hf>|8GmՊlvzIwMxP`G ط0!TpJszNq1*ȓ Zii@s '~ p]LcB?ᅋ҅XD99 i4eXLRƻDn]:=GO\lU+N 6BGey׆Rڗݻ7Etg::n< Z> e_<'XmmoZzϐ Z[ew$ϵprqFY=CW&oyp)9bPlQX۪$5S۵a&a@M PvuS䘟XìP$-#H.6veXąw=-[[*ݵbe{)!Mfw)8&")hlnL!W`7~*oE:䫇?VEBaV3iLF ~+|n.Ok]3oI^ʑHyAN\ʃ:n DuN47 (TRF혿 SsoإaX JpChGg4O/# sCХNc_)@MپU]CS)@MjC C0JpSco%?~l0?$2/mWwb &F% ސhVҒ:"uKP ~ZtZ5v= ʼC6 }LV2]rQr9 ,E1ڷAωwok ei%'|_+̷$$I'sۊ3laӴwG s/o~ 4UHH.if}b̕;ةMD}"tq]+8 5-YzT4<~ftzBL9|QoK> gbura)FA&'(`Ve_Pə|+aSW/~^H\Z_=5=x `F>&s r-cDdoJ*hD;6lߖnYfM4m6,'=]qX*惱Fn1X8MطN(c$&MlX;/ђv}nڭBa;"^g R$9=s!jHWz"FBTr!)!Dhn z)n&\݌X_47&䯜{goQ!>}eqFhW7@R"+bq=N[C#UmjEj4Sq Aovdj]#يm4P\YI@~a3/B ,q? fHpT%{z{. +3x`J/ y 6W%aK;A!AUI>FkIlG@*p"HW1>x-8ʱLW>`H ;d^=豭g)28kهgPX[eYLIتq;B WZb&Rp-[Y0VNkՉ 2W3S!2FD,h =ǸeB;\vP0/}_c~O\grl \0Ċd@Jr:ibp7Z4Dix(8_aaN#H s!vSQ]g' 9ETڑ>! j0@A 2HJkJEJ"! ` 4J &RVs)ZIإ:_R60^\@Ԇ?RwʾWmsq??Kc*vkft`q6:&?OY[xz[ p /k Aڹ?{LԄEg%sq#U@q;)w N$o̠t#T"%,u"_(5=HLUO vy;G6W[ R+e#6vn58rHݰC޷3LSV oWyc!2!2[ҁˊ% J=GFLxδ4xVZX[¯\0>_ٷ.\*hV&;B#' 9L0\wiY:InV~:a<+MH' B8ћ/!F1leH9K_drs^kHI'"Sz ă in7i%>7ЀR/Fd/w*"NĄ^]lNKKzźe&"|bu .Kǃ&>\Ibo.>wӤ&Hc/, 9 axCNxp~,2z\'ǫ$nB7=\[䴄@huq95O2Nff-~ɭYʠUtdGwv?O%wNzt=syzt_GhMu@qvMPC| V1uP4'QwH01jG$.d̏T5@ŭ(Ve3>[@thd6í; snΌA"Zq{+.x4Y=DfVz7K~堌R^V.V뫣D=sg;WrDkZu٩x-I-o'q3{qaB\ {:OJd`s:ـwNw 6"D]rXYU]L MUX[}Y,ځ}-YO:'vM0 BKH ~:yV{&WA3Vhpi ϩ1iKMJH6b/_ٍDtZpHc FY w"dkS0y^"Q`H`IW%Q9g//fU,b.^l@td^asR ̧-xZձd7ίB R a9< RRV"Jpu+ofG[B[oanu73#720ro84RZKcsB8#a^Oڃr̼<謄慄Iʠu.9H!0{$J*d^^\5GK| Kͮe2hY$ma+!m&HhI9e:~3҃%@v $. BˑIBsl3| ,@[w߾ >[Qlޚ((&fj@X!'R.3&SbZ݅sT#t]x`iÁ*[{eHM_#30yf+()'rvk)u#ɟpP90&R{w[Ì%p:T>>ZJC~>${rxqخ*YMz0}K/E϶! 6ޓa=Owm9.?1Ʀ&maúӿ{Q~o__~sl?_gv#_>ӟoڟw?`Ki\_g!v?2V8gΆ"ݲԟ&sb(e+웓`K hM"'4FdpgV}+ #poab;G0C)9-bta XI>ɼt@3POgx{]{¸-WWQ6&eR(l3(s/dfL 駐 QiDpQ{ +53\ DkBTGQg/&fc|(4; Eakb+) VդI a'8DJݕq\"0CA-]r>:#0{v8(/ ;|Jmm'=|/ 27O7E4oNPCzZ\eWq ^EH PH!zyOumn* [I&f>YxBW:4VV)jƜ_Dyp3mWˬf0>ţex+ s]^Ϣu%_i00Az Q fTNElɤ~Iiĝ11dKVia h+`UW¢aFz%*JZo>/W6o2ѣHF/F a š6vZNLeHe#s* 0t;!p|L JpHvVLԈ03b qYY)0Cu0tm0΃G7C19B `K2+ح<ҊgCnPG$#wsȵN-̕#{J VԤUWܘQd:9=o/c D)k`A$F4 R |f:^DazǴNa ~mM?w (;Hv -g>*TNtyN~>I²M&玃(N5eXbx=@ܒs1LqwsgKɝ(`T *x2Loei +A(2m *L@vҍ8M+_%\T6rdtGL[P_vyzP(K7i73B]乩i1q  ۪BQɇ4Fl%~=LmT&B"=*3ZܸXHl": qڙYGϜ&hbt<V\W Z6.# ZBX2F mQ<x](юe$.eb7FQbϕv*L12iGٰ{/s"7Ap#R TLj -WRJpA Wfv5#9qZpi*AP[]h), |0  ϹؿW)>#tnU4#ЩAV%J$߬t9w!8/iʉײ{ Ͽ N?f>BC0}I%99CȎ=O*{P]E&@ Э~H7x޳3oewsyO_>Jmڗ~iT/~~7|Ǘ7~yXVs%>֔k{E-w_cYYeC l~shk5sI5۷_pj8ҺԞiJeJqq{ڏ M8a%J6Rnզv=j}U{6d#?ޭ?>Om?{a{MuoPƛ$auCkFYi>}eԊV3 ޶6flI^&Z]ee=%؞ jkUʩJ}lu;w5fV,$umx[˅^CQckO[}LR_hVv~[e+*>~巿?_| _qheXǩǿ(3l8|?_yxj2Vvul/8*W&ڤ48 gM]Å" n~ay Y希^)L&4;)#҆t9.McX d,+!<[Ff O\%6zvgohI_0ӋIJ|f7" RJ}Qڻ}j`ugJK&I,\VN[ܸ:zr_7}H EB6;IĕVr?fAمR]}S9Sn:pR#J8mɘC%ݽڮ] n,jE/ a(`W 6e\ErkXL)>twM4a4Zy tHEra9;R}lٱ(ft5iN -1PS2$ghstA!]jh&wi[x?N=6afSؾ𮯈vr)}6y{]5 0qa-;VC=}&ÌdJD]@!4| L0բPжu üP2#AFz,dj]ɉƐ&&Jj{(8 O˩ɟL0$ bmnl5fllb/Ύss VMg]9袲! ᒀir'lHᦔu]|-/fъFFW4UPQh}ĥ' f7 lf)Finvtf pQĕuCmrG*]hOlj{~"GaפN0"o)sʴE f0lzW?NmӠ̄?q`bMr釁ո<6xD &1M,4fibM0Nfo&; p,-O6,űJIK|6wMQo.Wf2 -EΐL/  ɼqDEo/'dʰOt_D.m2{mYaO }٦P` AQޔį;0nm)eE:fvgWqag6d GF)oF.@[:G\~~[|B>F,Pr>tklWV/* Nk؄.F/ ˽Qa )dtҡou`dط2͐6QV޺S.K@ULDlvn?+ضϘ,m؛hjn E'ySXM{hRh6s0b=ơKi^1ə䭾=#g؂.3`NV>)ʴgp9֧t7B}}LA}VlB)!]].b[UrQsϔ.UdQy+">PR6.@ n}oe^.k=sq(֘dQHRCȃ{[y2 e2Kyiq6)v+ 3->Sx &G-l[٪o2cP8"[Bg*aQ޿~֘l7ԭfV6pOTŜЪ~3)=,u!>eOOҹeM+ulZi/P'nBD_ a4\K\(vCR4F[$u+L8G}!򂌀[S`a  "eL|a{WI8VؼJBCd[Da=d0V(;a ݽNoL9oA}B֥vYNMOKՌ#0W tu6^gv5{VS+p!ז3ڶdTiB}|~)6 JL'#(ID=C{x8 nkX iqt/.@T8sjr dvԊ`cQyIK81NZayD4J8 *bz<$ge b1Y' $Z!Mg(BmL׍> gc@;N} 7tfnse{ r SN*vxi4^z<Ƣy=/lB^0 %ds*F'` _^3=3D(T3GPQcݳC#4I[- V,eA^ĥ+/SW^&My]`Bޯ4(8 ʵ_?ߦK?Q?Տ'lG}ch?_q#>7Ic]?.?iHW_+m?:^S6=rn]0`τHt0ᾩ}7/]n[:?`jç3l/ 쉧Ҥi24#EZ0ǼYG':*+D`U yz{ɉsFQ /TJ/ABWIYMu} c$l+O*4tZ@1ܯ/U „PIZEW:=LQm#+ҿNXʐBX ]kMMl Ic2dJ'·i=FyI׋(,86՜ʲ}8,(.$&93$0H]m_࿳V3g]t5Ǒ`2Ĉ8Q%z*m,%6aKу`鄲tnG- ;f]!)y9ibc0ө ./~ӫS iM's2XF3#B]US.qWTfTran6̤vøL/H#A-Pa:ϔn'CR\Myψx4bFVbN'ŀ4E S!jĎyf)؈ tVҔ)`RqF5o/irЀ[7A[/]ոtm} *z}Ctѱ괷KX`pFV+0HX(BQ)sY0-/M&U`aIoGC8aNqL PDK&&-dlW GTL#<8V,le AC JGhN3nHP*Yp9`waw㒰7- ;vt̍R#0KGЉ08+r|`ϸzۼp{8Ijڻ6X!ˡ !hTz?᰺( nv[TƠ+jfSgEߚb'q3Д`RX1XAҥz{]iH~0s!+37Z4kR+O]YhL0%<@Hd-U2IؘH'p-#4Dft9۔0F3tTzN9p(:<;:*#DQ.yCB` a[RU+oy!!4X }j+0hbLB_}pq}dݟ杲zxkZ;o8GiZ*T V'FR Oc+42`q ;F2YbN&^K7GDqqyk4`꜅Yغj0vv`q[d4:(Yw uO8I%4C O)n$UlA!pJ4=c8z'Lܝ:9_..9-Q7WPʨ[i&:Ng `Y㟜5{tY.{UXɩ,^ZI'.KYEB-XD/Sͥ0>.#qXBѰT{=:|BE!-^9(0(zQDYn5o'3 _I$/3k.4g'!Q53(p LWk~)>8GlG\#a{@|՗>~R$e)l#yY[v𯃿.'n-ZОţ0Bl\qZ0qZ 1Ip@{e׈G8JBOʼn6Hf10$΃+T>j|R)O8ҪnE&xwסQY% atl00dyTK!'?İ(gi[?aMRgGt&R z 6{;;<Kx#!n&!]B5 !<[V+Oid?> ?fɠ6V8CZsiGil GFPМ e%r%((eG%hK88z]U0UIp2 a)`Cheڠ'BC㉇* DHNnK;@,v0:548OǤaw1yxklanQz,ZTHp.H!\4Mş݀nfbAoa7u<(Hq%c(s{h )DAi^(ۇ -'@&$B3F2I/ 9OZ ihooo҈rG40+d_8,שtZH [hW4|Ȣ(02e&e=<ɲyƍL< +ϿP@ * L凳mi',Id<; ܄ur(O/%r,=5]`<6Hl o ko أ\ C=䉕foυ3C)qHp:5o_z~*"'g8W5^PG*gUxZT|/=i7*Il5Ty}O}!%Cm$$7{c|~ӄ!YfD+%ikP+; c#W'o Q|fQl%#tL^,UѹmL (h~vLtLG.J> LrOT95D y ~қaJ!6KD9֖ ǯ,@&8 @߃/[8rYJsLyPhq%y)=IE#,%vkM Z?5Iܭ<+vB W6s$# Wn E@n)x$2O/MA01BF ՗lNK&M:3ofjw5 QuA yg88e٣o'PK}eX9W(閖K񲬠 AР Vbe[|i1`ǮGLe;m j{}@G|2C= g3+dJJ+^^8zhF*NtUׂ^4529IE~ ޾qx˳-oL[{5%^ )31F1qR]0^$:8d}ٽ^-$lݍz_os|k%~~$(~b>FY_#0{t+6Fo\z]<=EN_z&0;{#nQ’OLLfWBhɺBZٗ 5m).qF|L. b2?}vK#†)?>0E I項9Bx)r_6ȼ}pQ'}o0̄qUʳAsOnzK7b$Gfg;Dlc8Z0E ⃄Ay) ~=Vz:31:;1KDWIXoBLhMB8DK޹+BLH  ҥy+uWs=sBZЙ G2j F$tSh!e–mkPL&-JJ. }Zaq gvP#;w{uL#~{nLt"8U>6Ἇ<: ;Mc ~HP-jrMxV^K\_<I Rv%!ⵦnq #vR)QJ G+%p6=j#6ajw1lM^\e9!=aYs: =y s78Z@R/㵒u, :+]sZfk2G0\ Z9 ]NoA1Kl3ܽYA҄jn+hﳂcϏOܾ;_|= >_Rs l>ͼWnӪev2exy]*:uGkI8K8M# zk]LӔ~<,eNwuP 3e]zK.ܼL'ܡ8} WiRy,^ oLvV!xR>ˉ ei ZBѲ*p+o^īK@%|Mpg(?˘sd!*M^}e NPɈ|s==u+D+K$tWLu|A.p*"#5)H< zPHsEĔk%%Z+ Zˆ'yo Η2/W%I.iw.U6-NF|AI.2;,lYÈCU"r@|/$  ?㋯~7 rzar*&#2_V 9&XF/$Y?~cAmƗs< yOaσOpi#L~#i,S:f&ܟ"?>WRg'gM.C逘?z}$2 o Woi-;/>~|jBAw Y )4iC~-=oulD̐`U[@9O?,8ơWEQq^֩&rOD_Y2O*GkI<{=;1\a{#>5g"ũ^UKr\5-.VWbhj՝I^DjU,||pn%J=46n@xyexEꞇ~rС> 5OЬNbCg*1!wba&&Q_ Mӓ ]HAp9T̲jDؗ!۩g!D,d7Q$' qY^SN8oRDu p9@Z0e/U `v@zPOa!v샯TM$5hKbFy +Hj8'+'tdoNOs }|yN0HƔ AˠBiS"\9wױH0Oܮ yơ R~)l#Ve|z/L*  (,,R4dPn `;W׮x…RHtl#FgTNu=,,u'T ח +0Jpo&3s(fVk +SǞ:5t3A0je&A: AV]@Tp;Ȋ4ҿ&ʯˑ/Z|VJtSېBY*k** e{H9,n3Aڢy#C ]"Ц^sg>e`7e dP#Um^lS$0)2RɆsµ.e5\WP3@da±̓ʆQ*ؙAũ?C>GEp>,jo#îa4gJE' 5t!me c A?m"؄{KqWFnL Wb 0dTm}o'xWgiAl48bZZi%9Kw+M2K ZELXA3vO 䗞S;(ی$XvБyadj↓פUz @r$Y&'gXKD'x AJɈ(6hZiX5c&~,uЄ/fRfbDOwNs {P&=v5 `KI.%dwɯO31r+z{JxGٚ亚nH%&ARa\^MAއ:s|<,McG<|B «7OWG%g`G|aq!UJ |{48D1}4tĂ\g`_DPB8MK\_i9mm>Ǚ׏zBϝ}g~ UGT%hy]2G2hD̾N= #tfpPF[U{i M+U}=25*K܊ȗ#\Α>0ʽ|qY[EyfQgmp}#e.w&T`EVFrB(CM=Л9-r~U \Ӹ؅m2K2Κ<=0ҭ;G1NVt=&mB*gAy__yxr>NaŌx%g NED :_V=A6a!BfS Dstvu$lhĶ a30UaX8km QR'6Tja(-2:#ѰSWpH63%1;03J% %N";9Ja[FMn,n/LdRTm ~3UNʓ__7fRZxoqC{ B10e .gƳM[_:ާgǯڏiNYa:z'8ZEkJ=,5C(o>A0 ;2{Rq>aVx҄pJdP#.?¿@x,0ZK7\+wH .ǁ9^=534EƢNh:AB20<̙EVWq$X!b{&_[r1qcZs, =Qi.sdƋĔ|.ng3C+QF)UIB1(iHZp*O! *ŕI Gx ́cm!G3`6:Ƅ19Fz=% :ԛfdD%nkt8=7OwR#x  Դ}(x.:EHFn>evf0^[p)?6ySMDd)=0ᑈy(Ki=y @hwM"`|HiXIT:"3`Q8Υb4*w@D$ /ج"[4GB㢬z'ϙ-K㸌? L{a^WHW&c({y^)TK"-Ug=;2J8 N >d{\/沮(5E?L<_$,0 #6tvs1T H!PDIU,:™K?~D ٱ#Ll!ҍɂBs=>'׆2t%kr.RIB #YҒøMP!S9%ءZyu%U}75':$uvp`?a^{ӀS|gz "ejiQ^2?_?5BC60}]8s)#KRzۀ̞ c~1ǛP E$\HQ8ܗV?g%~;ReƗ0aq/[Jr"EqŶ˭ܻpk=ՑJ־>ƶWXv:f?ؔ!dw:N>VQx?{ԷP[5ksRMlo^]76gP}z}>͗^piަ}=y߇1CC^yh²:q=h[\lyO/t fm(` vM{l~WZї7'|n0&Nm/S?_^ol_2g/o?^އ9,߆X?]&w߿k[s5 GDɗ?di[.}M[&nl { ћ+2 ^oQ sʸw<.M^m1\#*j= ~EngqZK;xNO,mOfFhO'l]{ɶ ;N{s=$ϝ&j+%*A8?lIoxŭ׶dVTnw,MV{GaD\-| B&$.30))E \svδ% oY ﮭj'yx8ܯ(lbʹmz,3Vѽ1_w׎"k/\YDaڛnRV6)m/߫]h}Ⱦ{ iv޲dJ?L1Q%ʦT((zˢ=-b6l2zlw&%WlU~SbQ6h}8۶].8l̚Ayn2)va;ѷA-1{ :=`vp$Ֆ3I{|Ξ6竴xer57NSFhl&8MI+De_pxyʽjv FekÙg$0c4Su5cX4c4V\xWn$%̛]k]+q`nBq0mJS]dz&s;-qȴa SMlޚ#ڤd٬~]m s}I^_aNV^n Bs")Aemv hY3[X+Ŵ&hTIv1ݶQYmensdޔ쐴<FO`U||{|-k߾0SWZCae(o櫝;w_ױ3+f*jrfO)|ڄ-,u?ZlJ=:178cLlۭz%^8{ݫB t^7;ʔmLTDM}R!*:Y߇ngTf!`ep.2vʱ pF>l ƴ\:If0;Wg` [#]<+(y! ejp<2,&Y4LLaf\dmq^x)jfW@s39l6Iw3dGY $~'<? nch5b_߄ ap]f"l Uwm?4:?S/?~_G6ƀ~v{//7?w|US?ԯ~zGUx^TX˻kl-ZvEUc䄇jքUwWmCؕya/z+UF7!pw-[ϰio2\iA R66#!#l7102a]ymb{n+OBg#O؁sT2x2}NՔ_7ۆ;QiS @|:Й'mdxā /tgUɧ$侓0\«Pq0v& q~y0@b~vfu2*A)Ax*YL8$q^}2ґHŴL T"fWM ]nH .eoJ?#{$<y$H(2q~{@G ñWB`GSZl?k:sG}a7)"Dfeb87&\&[(J` hIpwP6woTwU01-/ݽֵڕA_kġ!if?Ǐo >r)PJUG~z.m@Ԙ|E LopEA3B!fl,EIrT;aiAUi1[= p\ZK/t[qS63ELJPbjF{5Ë}x1Qxdc<j4Z$rKXh,P rɍ';htǫ7#(PJir-=?<0Af x ύq}XiE &fۇ3}VE ?u0h:RK`b[Hr4&?8< C{Šk6"4p c'xM<%-gxᔥ`-߽*?C/.Ig^5 SgI,$,}\% .'&'+0hw ;G'Jt9:\VAFÕ(ҳU .+>?O0yʺ6O-,Bt #qs7ܺ,KA\pn2 *-Mi,+-G|__ta?$j3y9uſqH5}J׿_٬_'w8Ѓ)+6ag|/*pU55c4&n|:E~D+\8-\Dp0".dq(XmoNXz,n1oCx##ȾD 'Qz!gwdq@Ri Zffl\(Q^5DFP ug(dzL>;ŇP/BB X}0)O3WTF E=^aaYlh]Fg "p Aav#FC=TKC){2!¨eZmǘ sZwda Y ',CJIX0[cԟjѣ0Z/`iV 6V;Pۚ({'Jz3!R|iy Vf6a3 h|i4Lc"4W9 ;Dr(x]|gWr.M]D% EͶ$c%"0I&,|]n]X_iR|zz=!yVRC#DI`c]}f ~f=+@ӼB辍uhx{_Jp J0QM\\\F9NΝ=g/ ,#7vx-aWfGgK@.)t*R3)Lv۽p#/]w7(kpGk~ܿ}f))fXGxqgmSNSrB4> <]=8SP߀| FrIȌBçHpA ՖFڪ pfVdϓxD\q KϪ~Pmcz/<]t$`~3;,\D*s8+\&/qkrW|ҽgHE. ] 2b+.q^ы :'ec-sx 2ǪQԉ|e,4#f'Bp*ٙ.9dR5ǮԱV)\כ4zcL:߹vH#lL$0Yk k`:AġSADY@. o◢A|R)FBEcSJDf8_,?6˃ $9)2yB.ܠY JvXҘUc#1@ҐL/#I N$^8}?#->κ_vbi'0؍ݐB9'G1}С]j D\)Rl( 2) ⲟH<& )lˁTOqBb}j ba䉵61Q/_z^&>aa 9A7M}Yf"j2!̰#0uWV R /Y=P `bbDnbGґ;?o%D $aZtB`wnkKo5С‡*l6 KsLhVsa 'H΂ 6a3ӥTm0%#cL2#ʅHa! b+-}_6gLs!,쓥$h2t ,C"kvp1+ORk+;܎[Bxb$iiux=}wJ,bL1O_kg{70i緇\Z/= ^ZX Z?oSx[{X%)hfYqLyHrċᶒv1 0 kIPja jbQ"5t Bd gYn'b1I\R:Fu/r2VWeF(<~zοzȹggPܘ?#]BO&׬e!G&qDKgRִ Haz-8p }E.Gr{ j0XףCR7R|d2tB)ҩ-At@<^t)D7 t2sg.VvtLM0}mP[&kޑƠ*ͯۀ%L F. [R7T6QLHZ*>&zB~ #Tu3N߀2/Lƒ= =͎|#yZ@)û[Gio(y=>+ aeJ`a/[ϸoyxO|o#ǎ+ 2̨f,;cޮfjg{y*](bqasfm*%^uǎT"ރGܙJD2co{O3I7Nאtq|0ri4%$1 &?jh*`s9#;i`oP~47@̣Pia1&)S=]CHgЛ70 U; !YJQzibM-Y]@,W`!{DU~2t}r%d|koOea,1 ='ѮrV^j#SFHA iFpOzCf~#(Ip>&%-wE S2+D>:50qbZ`~bzaqX ٪d GqW4п(pRU#d:%gpBE0:訄+PBkmZ]+Ki􄅭 TK ,ֻ>\NI;b Gk4Jߠ_`siIϒ  U}AuikjC8c \[qŘ/tPm` (D2gW%4֊̑I ɴW{7%-wlOyzlu:gAQUQ>zCUqjĶ7ʋjU}Tx9xƃF1*0tbY1$\Q;pc;>[_A~n' "<'a8-ḒZZ{d\JQh\e|GHRyEx8AM CZB΄^j~ƃ|{;X 6}NvԐ9qn2wY8m+WF: )oTʈ!˥/?8fID!pwJ#QAT󫀾%{%wK%* ɽK\CGW3=q* nIz#Aa׶ C2]O~"Ry߄<%ZimWZ/- RbpJ=TGpkPUa(z8妐;,R SNBR4Z`*%yʨØ ԄN(Hq0^j◀a\YT%'dLf  HLt}d^ *=&(?B JiZbamzzptn+PR&/f[$; 2>\zG7;l:u$}ITkK`̙SNti?qLն8d3\=ںJBr7{(Cw[0%6@cj &tm䬮{UI8NX>>,3z0BF{$u&FCJ}fxJ_X"s<-_@&t mRyH*= S<U Њ ~|8BG6>*vZ5? $[M{}zuqXZK.C+wteF瑕gOO3KIm^WxdNѢg?@3|[v'v)5&@0)R1MҁX/Zr(a9 ǎְ^p-nc}2tMDOe SfKrW UtBb5F帟Pi+W1yWң#g[Hp*%׋·bd;|>`2N#N B!5{OoAv(Yƥ1D c$ߙS'CK+ y3\QE8ş|B 4z qfA4m'XqjKXkR#"qd}T$z r5E!5\m%ZvNjm~.?szcZXE<(`%6{$Ǽ4{5Z]ۭ83am VȮ^7$ ?RKz -^t f骰ar$p4 gi%i!ᇖ]Kkhd8,vյF'+G\NjL_0OFBȝAR!'"ˌXpq;{.%')` Wed@&Zu;>am餌ƘYau'HiR[KwX١C/yƯWkTvl[C7`P+.U\p4gޱX,%6}/HuԦ_K\}Ha{^{XpezFL#)UnHGRW{D>{ZR9?~h+=/czm}8nz܇YulG`>>Ұ'ԓ3Q4OsW7 "\ou6>+Y-G^hq>ݼ`A@v|K$|¾PU\~N0]뵶|Վ,BBīRzai:w Ik(Zmz/ (:<Smva4̖3ރC{X*53m#b{w~ 뽁cu)L&,ͳ0(G8^&q-;!q1M $'|d++ޝwU,3} I 4xfun N'k;!YA='l(K9fW[*O,˲K d٘xz{]qalw~e|>K&Ѕ+uD3S4 axAj H=z委) ,Z\dܪԢ7 grUM|p3jXD#*GC~SyvPa{%tbΦ J~j=.sx|oraV8M~aA ږBW$.馔i\&PuFH@:#}nIf k>?41{fLH2Rz1D2³8cG~mYV¿>IK ޖI o+^f)'}uṥէV3z-q _|wӘچ^2I`xt>ݚRoTҽ6V5>t3*FgctSjokN5z&F9jͭe魷*ϭw;ϹHW-IKd"Nuz'{ڇ~wA_hv8k>ڷȺj*˘-q-lj0|[r_GZ(c3d2cÊne8Lzc Y'dz01tz)#yvj$/4I?S֘.W:X~ Ra]y6iO_.1<^Xȣ`&~nك.&9m]99rRoց;iBReH8!sVia?.9Y  eЩ~>D^kFol?*]մz>GNq_<liÔZ}pޮ7r(Dk~j6i"s&W{e$v#StD$DQPu^q8%X9}i]+V; MeE/WOyq}^e>-c$v"缿uY~Z܂-Viần8s c!qK44J*,Un0S?#J| : -\\nO,T ϙR'{d,̰uܵ I";wإj0e[9DB[ydJpYPy.F^L"TA@LtنٶeVw؆-AIzUaG#dO唅悳 ꍜxcq<7!g&e}&9ˎ'CHlkx"Z1}̼$f]:BJ<w5C-)⪔ɇu<6tk zGB ( sEel!^ m|q2}0 v# ]uHt Yߤ~-7=,*념5h T*$)M4Q/s[#}I~l&LϪ)T==+P畻Daj`ja?>9C IcmUvtYF|NjFgl{.z;O/~뵩uRv⩔57,\O+/nem>?<  bp9'`6LXԷ 1 Mep!LX7;sTXPFn-Kx[҈'8g0پF)zSkQi 0 A³0nj9LQNUR)0i[u"<,[{pدdcM;[؂c=NԭyjE¤Ya͙ÉXj7UA+:"{pKX~;E3Mc^ 2 łŘӺ 4^Pɥlmdc1 8fuinpgU`(3T+>zv*UMN:3=0b4;37DcI=6M/͸RIqƪg]p GP.phOA\&"ѷ7*Ց\Zf1a>shes^.>!DjC@m& A:b!2tY2wvl RdW]g S">BJ(:WcgMi/+~^AĤuQlDXw20[uhT XiVBݛ^9Njy*-7L#<~3"s@~was-l[3uAuvg/[/=+.$z@P/vb<@?/Zx  ©uuG5c22,'VНVvy(ShA*:o" 0"Y yxioRڬ~9 H{Ra?LLnUbA ; #"8w aSy +1Zx4~rd,of$h P\{\R4Xw-^uɩLTtt [(zŊ"A,˅!Wʛsd7s b2U1 RjcP_~pVmA!xۍm$ Nc]n- Z8.O= `Do,]2 f6<&,9|SGdm7yͷC1[CYEcV=kj!w3w/cpnl0xꬋM6|zUomMǸj1+bX.~'H\Q( qg>Ag1œ;W0{*PJ$BNNWɨg(cw€!"[yx8GoѴ*Dv#'Fj(P*$ݿ0E ~B寐" 蹗xs0x[ڥCAn &WF8OLGÀ,됋&"j$2+@HyB=;X٦ #X68^rE+hfEQytzYaϏc vkvVګ j%Z @9uk5a +YaB}-Gͽ# '@>b{;QV>x1<:-%U!A RHUR=%*)9P%)5&ca]yC D (S~˪*u@V9QR5^ 0PwYӇTlĉ3~֡z~ bJk#L~0A MTOi7ߟe)ǂ"$z֛YHgoLa` 2w{-Y]A#4rAiMf~~>kk|vC{f8<<ފ~Z?}_~),sr9O?W6ӪKju{ċm뢌elU9cG0_%K?iۉhݯʐ |luP5qo@"OZUMp!c!zR@AuĨ<]⽼&Kfad%eK:74WF6dceJ܁z_ e>7C;iܜ37ၠ Bن O ׅa*lϛȰ글 /ۡxܛ+I3l 2c/a R> 'RE;Vٺ[8w}z'W7#VPSQl -;n0Le)S"ZLȥRm$_f6adMSIEb8zEns *o"Sa{TVw($abZ E^a6yepA?:ߓ.Ͷ:aMxcyI''7,+Dږy;a w FNpYDY#98qOp^ө+J n.Sr 墂hoQJůY,%%j#ϱ}mGXBW`jL#OU"{ K@#X}o*nTGqTa΅(4eIYbAE}ɰ|rv*HV=qT:Dv E; I\)z-G^>*d>woi7 MՑqI|" i\$]Ƥ d@kL!Z+_0^4plaV}U8^!`૒zWE[ [&xٝt7 m9PQv|KLdDB>WFo IO"gv+lHy[tZ(ܫ)\G/ ,Pggf2XwzҸd $<8#PfmCt 3]xce'LHhS*_,eDeEŏj## .p'oØW$&L8򋺧u@Y #B]a*&WdA\r 2 >;x@"Qsdzu pbW9R<#hN%:`+u VP( 4"p@Xs;[?:b_]#V7%O6T@-2B7ۜ8q5GNèHzj3运DB.UU bVT/FNY`+ށ>cyljOt\4f)Isٗ52pi!zl7hxF bBsZU 'Vl$b$5_wyCF0S`;q Cu&V s𑫃k4 {5.!p; 6{٘=x̌@Dڨ.5w#B2Ō6L_5*gx"Cǀ}OjmGx ˴L)UR .n}p`+ RIK 0,O1'Ǩ֋~*z;̻T_ɦG.n4~b|$j5U/Xq .& B ޲2=7*սh P< MJ[F GC̃7 \H޿AwG0PaJeMO,ToEjdNuҞ3d, er+C_Zy.WQH_Zy/Ww' }GprW[S9s?u0Op7KV-Ͷrfjkǎ;z ܥ/=K{Gezs{K8턥@R2f76{βb@uBCVariantAnnotation/inst/extdata/hapmap_exome_chr22.vcf.gz0000644000175100017510000126631614614305321024440 0ustar00biocbuildbiocbuildBCE[[S9~_ZjH{v--Tq1 %w˶6ݒ# _n[n KsMXN'BD<].eoftTfm@*ʵ/\(9$Tr|ΩzEJ oeoft1߈燒o3^eWa8I;IZ$IM%#YP+ق%5tAs0T*@!2Cp#O`~G~\rAI7\jj\pX.~{ĆWs?K7b9pk.rcZ\ 5.A%H.,.},Z.55.Q%H.~1j\K\B~å%Z {QlIP/J|j7㳅b{qb>#[< }[I|{}[YQXQY*Wg`[D߉`T,%9ψb| fd~3^_# @JBr .,gcʢca`MmLpe9OBa?Ѡ&Pt*-k>fOLv[o 5*JWM"[aFEyFyI3@q}F5/sjxno.܆-y -[)ؿ8hqĚ ՘Ӕ*E$˗d%qzv1lpƋzUpp<Ρܒjn\&-%}+hS)̥ҿrlWXQ>rGd5 ;ONjT*fZ@;C4eMi48{^.vQ]Dܒ`UZPxĸUͳ ډ}ӽ_Pi (c\ HS@`_s&ӿrY6WțdrQv? BX&&h3?Ib.@̈́ԛ繩axsz7b qBSshYJUw+ Jn)̥J1A^t)i U+4tgsUYͦδiD4ss#j\? ٧̳s[PO}I?]d}}.i2D *4["g3NT2sʧzv0(Eq<{QGJ/I{kic߃ۤVQM:hc[ut `m A^[i?BbM:iFm7[#dC(*[q/P[D 8 #OnZqxKVH~x[#JSi4aa͑ qoe =oec  zi< W['ۡv0&zu!0굞FEX$AnZ8 AІ/Eb;@ Zx!"G660 NJl+_<'.$FIlH/Vb% IcoCPaކs)Jl%DХ^|xa% r A`Ň6$\| 7!.G,F.<lC&.b ޾1 /A &F*1+cvaCp'VD0]2GǞKWƱI1ȷ0^!g^p01 r'Dw&vhy6Ǟ 7dcK*.g<0] 60R ?c;I˸&L\>Ap>?1 ۘ0\`BmL=6bDNʎu|:V0B(X1뻳'ۇLyQțk]{'ReB=?r/SO}69钙YY4Eߞ^T,{4eoOU/+'g$O˜oٙF[_KSg$ \.7ЭQ4wa@6 ^9'~kPd|񷟧ny>~_~o ?n?|{~ouiynt8GR j_I_Y ,6l+_`pq_ I|}Pm|xQGB+UVգJ# YaMHWk-Zz4>1 W>j)dwD74T7/Knnoʒ|=ڻߵ:aswwhݷ߿g|ޣoݧ]7wRqsz@[=8?=&OOwcd{|{ҍ*A)z7a.?wPʾӟ}o?ԠۧoO~ +$Ts,AՒr[ *Xj%M&M/\"VTT8Z:^V `/*JRKIHٌ>4s.gl3vX3>v?f1fSpR!=k;8ψ0 #n?CvavE·6ݐ~ppNxöC;7u3l.'Hvĭ7)9R;Vgq]a| K~u\!yNZ!甋*U5SB !CC |VV ?$gl!Y*fmфH[IiVVI_wmD2L^f;XK nWZjq$"JB%amT,橽ucvfkcr+%f)5kVarh2'g-h`*1mFM=ɘJ+<j5JmBI4֊dOkdmjg69!Uٱy*k+Zlo#4KP+.Eb}xC2}+71&Au"VqU%F+nxAp+1GZSZ%mLUV|* WUҎ حH9:A$)VKtY *CT+ SZ2ԄS̫j6[ӄqو촴N>4CĶH)7:n$3GV,U4"vƪ eeF \S̓V{sS(9j\ߔY O=,oJ8).X0Kf$p0/[E9:̍z-ۅΛ7>N|V#&tZ.y®ayF:˖t^j߫E =zA;&R)J40P.QķK4'R4GxL!1FB6<8Oj J]ڐTwkgb~M+3hHτRQzª$RUicʁ,.C]Tޡil&;\glϴa`2}|Y:x{Ny<"H`txJ(KErL /cSbc3` b Y'ɓS?NW5?j5-xVsOVrNOQCJ*=A,sG,A K4hWm H2C)p\6] ^[*] r cۈ/re^)j*| U >66^d1yys*LAq7ejcj%<<%#Ȩ&,"ɼjq5 'ZB h8j^g7j)jmXXgkVФ,I哯 \$wE\-`W3&9i,{y_Z}9- (ȓ3TNVKik|[i xJ#&j|g#yg¤km#“Gs|> ^9{+Cs)%nJx?5?<[3!1z)fa=J8_ܳȓM[I~)?ǫMQ(* FPGj_>k)dTB&4,[ٹ~7WP\ne-Y9άy@<2\*|&.FNk5qI]q%aRZ*y5(QZuGBu6Em*!Jg_ ØUeѢ 1* yD/a^ YNpzCnKNC3BPZPܜ*r(/?Yt=XRx4D|'⒫C.w%FI(QlU`G3T2lh6iW`%}9|؂ / 4́} <(|'BѨ2 \c*t]N x!IhMJ޼`yl#ѩT P*%sY"Isu(Ġ:%'5tNӀ5@cĀhsX$uPTd{0'@ zt{..Fi}+7'pވplD8TwPx>6~ |  &IiS@K^n_ rp]Ra?T\Y+K!HLB=? ʾsb:/>] %gf Ysq'|o[sq]}䢎P8??FB#5]^=ǦCz2OXW%l\BP =q ir4^M& AIWȜЕgeOGNKf}D gV[Oи*Y W[*yBꞞ{x` (A/2ee-5W=$9^SO\/ʜ, uGNGpq@^RN%H٨2@^޲2`<%HJ$s[w}:"<CQ9 neFz]̃QΝGR&%:ԗ*W7c.kJ?ލ gDPyu S[;.EL~麡AJ(p9` C6~AR)dS+H S s|Tj>0t~͝r >kgNr. %¡@7LJmr/Jyʝc0"^]/qfv~֖P+z@rC"̧393 Ӂ|4u CT-=nv/z1*nݳ{Y#  ^R%4R4ٓ .Âvj{f) jZSHԨpw3؎fLc%5@H"h |t_Z.}D D( 1xXi4ugj\փ8\jBA2aD]ձi{VrBr8,Q[9QEjSo,⎸\j$d 8Dx3@a/(D4cB,ieڍe!4]ha)!`s IPG0) TD8BJ=ؐ%W;V@-k,_BI} W$ۯCЊyK/!+Pb(1 )~s{H:R:]k\:O?A,_fh gƬz0_YNd& U%}龾՚'zS+;_X$'Iv dٷSd:7*,dJGer4!Kxnr!.)Xف)`OFb 3#ARMM < 3,Ir4/h[r239njI*"Tshh:.=Yb?™qޓqӻ5!CկAVZ6{PA+y*{oP9偕Xa*YހWN*;ttȗO"%"IʽO<%I[;TRVsd_wɖsy)&mC zܵB%H׾\Ǿ1F)RȺrzIWAPjH_*F^|%IEjJV3,-m1*`R)qqNΞvvrsn@DKg5["Hg4 \jJ R9xf꒽ɌcKsUz@Kp-{LH:RmAᑄm0nfrq/:&h)-,hsC|SxWU|6}vG'sG75d8 -`V*ޝ̮y2H-IPުa͇l~a\'<{~b˳4`4~E2Kݠ\'"8|+Pgz|kJ\>%Op bDTC\{tKڧsGfh0?G}h"X;ֿW󲪭*sBKɘB'[G TIW8kRmcj.(&Y[/Ca[B5u' <`:y`::0А/ANh0MAG`6t3 "2RXmS6:6}EE_n8YtWEmEߝeȨr m*p`1 l!>:|4G͓0! ,vxC+ =7Č'%P7ڣesλ‡,\}9BsC@7!bhdIJ).W u>[՜S`zPH|^{;J@r#Azb\zcUvuGeTJT[7#Lk,IĬETL^t(X:!%Aw11G N Dέ0,p'^CC•v:/z峡 b[7aD#&!:x+]D[3ViȊC9RE6s[Gk*O^NQ9x$%]f3W̟cQ-,3y?ٙѲAcf;9%'x)&-Z(ݘiavN5ɬ\{CR->j\[KB ޾<=GxP>mRyzXK'O;7Oډl.wĎyL~ Vz 2؝<_f3AO/roFV" /ج,[K6@"pȃ.׻C('& ; j |}54|8K\z%~dWSk= .o`֍# @Tۙg5Ϯv<rft(>%/(ϰ;6/'Qv臅" ~OlOGUw JY.߭Xߞ)֗ັQ3he Ko\x orFެ+ãrL6z|~Ŕ}4`.cޛc%Hznj{z{BzO{8۵g0EjyXvh#vdN,w"XiC^'Jxܾ94DZT8؀Q\fPE($6-3h5Xhfl4"M9%:6Ƶ{:V981(0LdWq4ڊz>9Ǣ@.5{_*80U3ҟu̎Uȟ6tDsX Y{Y 8q8J`.$P۲/ u4cDI| g[\@|E9{ $Fqò=7WJ4D6Ϛ&i] DuZT=Osz'V8UDu^ vn$6w0Í$#3W``0gooÅZ>Yr2x6#3{<+X3IR9ƶjJ,)+ R {ף ba_0E#x-~2C&, ʲ9%Zy+Gl,蝓yQ^t P1 G\L85D'P qלR3gG+F4Wabyޡegr 2|+p5nZz"1#'q! ܙTa7|}UIHEY&ly}ZLd^3"a;G>tV׊!H[!=|.v&A9X 5'ߕ܍ dCH%H+idH.P=©wcH{Xw ~ˢc7ҼrDAORiDɡt\'rlAK-re枓PXf`|F`umE8 i*eibg$J ]8#rIf z ݓCRaȖ#ZǛ np `4 m}V renYw1AFR/EB`C$DN̉8Wz Ֆ^Z;)o:3^,SO7tSCl#b;'ǒ2''M+]jIVWR9eHH*O\kAS^–ꛞAP!a^"zp ̎cJR%z ~V1Ea'W&z]Y\HI)LJed}Hȫ{B>B(JTSc`\]skCI(s xI(>Ι` +9Ӓ|;9\}?qiBB߸&m~dJ*k9?]b>?JPH C` {5P7f~"p98|S_9*y+3<$a gaA`ވhʉ W@Ϛl<] *]lo؟=&/^|)P*F&z„uB4,ƞN=j϶uMU]7[]ׄ [=b|AlyVtx%#?g {xc0%$]v>=c2F(5D1'? U0Mݫ3 SO 5TnKH{VJ!e^Z8WO4jŒ} iic9ڹ k(  :?oly#uFxJöCB稸NRI+ A!{rM .]߃cDTg*S)Gd:2?$ԆR,Nwf0 ĆHD}ts>gD7e}.RIFGQOV>zWJ%eOztXsniY]K>MW 2b|Hx( Cd)sK>܇go#q-ȩ?c0qFsR呒rZJi#~8u'⒘sR+"\1!WÕ C>[BW=F>=,yscЊS n|67R!;Q)|5DfrG:ap69_ꐗu#\ۡ5sn!J4Q2/ݓtև)ۺQ v%۟>&~ ʯtdBkS_:C:0'qȤe K(6C[L8YJ ~>$} ;aۧݑ 6b`V Q,硩PJyVݽJծ^/XhTz\0O~T%\Hm8"1]y 8$uL ]c+x]P}+9' Vրa tj hj # 8@9BQ| A+gR`Ujoz8He+%$bb\{".808M8]`wx #H,^cC Ex  %Qy %}9!FnƾX%| #kԝdó5[jP%Tyr)5w/H`T=9t c;.1xB;g=)d^ &8FG0Lt'+^sdAx."D E񘌈11vK 2@-B'g< N-s%&1d pOb\s\(dzcRTYrX#=dER?Dj#z",',{-9sz#@!g*\(!s3@`/u\dBLh4hS1Ȅ=mA >x `ѭZ#,bތ_/U/KX^ŕTirrq%֩S#*dn%_!/ ڠ 8~Pi=C+4['u1as*_QjdOZ1ϩ++Z)@vI$`B =5uLYDBX wӘSۀYA8K{T2I3ߓNj$^eϗ#=$-ßxrIwھ>EcMBT,ZN^cN9/f^67R*؊L",x$`y4"//UWa# 2h`bT irA)e)wW,IXM2L,NBƄKYNgIezdv'#biWS*zCtO!d2X}Ĩzw,<x|aJ!@a1lڱ֓*CO~\ٓ5:єIg7Nξ'߆93Q َ(:8O>.2K5f6ҠxDD""C0ŀDs#s!tE7̀%bW>hrF9xy 5EBu] 9^C_(٦sw__?O?Z K mQ ӽ^Qz[_ # ]dK6LBp/ݭ~O ا{i&g }C;{7(tgɴݝ9 oYTxyRr܍#l,Nf@p=^ +'ߏ^ BWD@VJp?b"_>gpJyQ|Lfɳ6O2H)J=p}adzZc$<^ˉm8y(|Z6L*SDED4~uX\,7i]uHrPRzVO&pJT#4V!Mk_泵D*tgQ%NT|MaS}qe<_G)\Z q9UD[YҞptT9QY-E*#C%QpǍ " `GZY9a+Tn^3Ym&cJn 3Bh$o=rwX/-81c= ü;:$\8<;RhT:&sɸ% 8 x]C\MwC@W"KyH88J޾@?m̓BCH[7%_9t6%=eM >Ӛnc傭j+d2oXL&_/ˇOoޮy}[~ٯՕZRpkV_);+zZwBa LɯT5T3`$a ВDDzʚJ>Wke'.kί!V]&km]; rYc8{4}Z\uxWC/Y$G3u嬯EehYBX33^rYs(hI_#V鱺+ B+5K a)kKr%BDWb_&`!w*8q )k GѩI#mDψsQ_@_Rd (.Ի`>׈GqrR7F|>Ļň"4^,Wl#E{eiq!OkDQ''\ =GzzӫR~ūyū_?xIK/^׿ǯh^B/痲x__yeIśW߿,ۯ//)-!~ŷ߿_?+xOş~||K?/_/KzÛy_矿}_yW~o~ǯ_%?_|~z/?ݟۖ1Lz|o{׏w|?|‚_>o޽z׏/ؑ.(qΏXaKo #rEZ68gM蒰Xҏ ԴN? u9ҠZ%bڣ(:䧦Mݛ#Rhl-{pĔVOl-_>r<%dY Z%{ ţ8bNS.LՉn굗ְᵣ_K$ڭu|~j^NSӗ/;"SP9\ҙWd\q7OoHrYJy&x}%φSGKWJlUp#bg |_G󋯢F Iw? ,ӏ3I]˪DqYdcŘN,Dp IJ7w9 Y睸z'a\]bjpTJ2!g W N}Oq$%gWX#J:.[)DLNj6%"4k\C ;iX:2.J DZ2`^ʄo iViwg?ylql{*F hܥh65!/$^XU}êc *1S U aU*ׂ T:J_gEp(eFxyR9ݣWp3TURTk@PH5#4K*н@t+Vcrɮuhu 2tP̑YVn[jYvjw}#i@MWIL`+bb$6KBdVUГQMM 3rh ݯKRTR@I'KZ C ШwɉK.CQkd_eFXީ`}J:­ޜBTlm]ܙ, cȸuvOיz)?GH맷O)*/D⩾n[5y-Zq+,5l U@3*.Ȼna/a+6/Y[L_~eaWIh+.>pt&!L~Ԅ>.~"dtrNpؤI}OG^{U9΃$*xp~(_ |[HܻRhѨwˎܲ4p$=E'M<,Z Z𠛑@+!DQ\zߪ ,˚]j̰+V֖_NIZhkH{'G@3ILMB& >s쟯=E;6IYb- SMR˕(֊֮F]6˗/j'&S߶)L ^+ĭ<:[s&V.x2Pfv=$xg=Bf|` ^^CMv/ AC4anq]xќos/ͅQ܂w#EIqّԀvv3H`޺.ȡBb+IUdIcWbu` G$攭I b2_yh8n[D< c92`G]GMڷx_1Gm>_(eBڹfv¸o:@MXDf/}f_KinޭS10y5Ey@`2$Nג%/u1C@UKSYJ5׺z'Ň($=@ K[]e`/P܉Zse'x=Z9ɯ؎+50!W j mVtW4u!bi]A.r33Ԟ"qe+w̬aShGGNkpՓ0yU[V‘$i!pq.< |z*dF _aX& jKpM7ZEȎf("n%j_e*.&fOT!ىyKWɜ R]Ks20Rp5n413s.S 2yT*ZP|)x&>~PILk\i--tmZK"/BZ(QC(E3JL5!\ЏҚcqjr~cF?qH ^|jm,Z͟͵:ژRNj@R3bNX6;@=[NJigk *N> l%մ( يO֚+X }(EEWZ[\V?VU5]#!r(2llm05yk,D\W/\ЈHC(_B#Bzdqeh =9Fޕo$](i j %MMb765;=[`Ok5h$&&D]ϲkIYWXDx™%jd)ӫO) Ml0ƸBkRwmfY{lR d [A|0,ِ&D媲TyXL,_h1a>NMb]Xe8iUG[]\6~!-*w O?-p6Bqewj00MI. eJ8kxxVA$N|my%}!*Cˋ~++~25pR\OƻtD`mCRvzktP`[U sdt֨셳f9b~!? Rd6q3@ FTHM*dǹI[*TqULuTG!NZC[ԜuQ?8>}},, jcT/^Nva8dU^ʌqh^!=TOI)f (t'+_-sFOMtut$>pr"Ɉr-{l?=YSZ֥zP*m-= iUa(K=ֲ>x{v.TZo9lQ/ Cm >+[ƪƞ `穩:mͫ&ij^u[ٚ:q{4MJqn1lu\u1MMìb s JR4WO}]b| Ks <[|b5^=":dIX$̐!塹(Up #M->^KĘ>>[j0E{In @]x6;+j5(ƒbr[~GNE5sJuqD qLWbnIѥf6#%ӽmuiBd]kLd,̛3WJbct4n+5Յ' x/ xU1mV=K\zLT\NxPwrSpS\i{Mzr앳z$.qՕ+a'z""CiS7PZ 5)쁇Q Z”EjYy#]ۘ6RtcqWBQ5 &Z4"尃̄% M^v6wzu5yco?P54UQz,>!fw:Neuϑ׫l:tjxY\f{>?}LჸT>cuwbqmf~ƳS.U]rfd =m B?8=^_Mʘ~hT)jkQei4śOr9y9J]h (Knfp G>߬s(->^$ E/~N΢jޅGÛ4 =KMMVqTKpA6 X M;ׂ"#e#<*6SClWm;X tIq*=>Tҕ4zIuKel=Bzg_ S\Ϲ4^6Ȩ: e۞")YV#]QC6svuDHUAW5k^M$&[UJmj%9lc)Kϖ|1.Vq@Eq,/̛Xѝ*KxcREtgr\o,#lξYY KHU 9, Q/G).mEɬLD_;5V']Dv-wwA6{N,d? !Ͳ~N5N0 fޜkn,rCw@G`B#FU䪥0$1j&Bwzg:hIJI(E{r&4r[reͧlK6쉢:H/xZdyMBDjhM %.< byr2S8-\7Sxl0?!p!LᏃ̕C9HLeZ XzRWrPe}m![enQl GCyȡ?/3SA}۩e̟&&56~z̙7A")&n`JHO4\r##wktM{Lo~ ["0SXygf肃l}=wOeU8h!Yr}.BXˍ~۫m b4DK ocH{Xv&] ˃N9i&?p-/%~\]rZHè2ى5|Jף9;FmJP'˜T`>BU!$=o=cNݾ{ C5)80F"_#:I}7O@ N4'! T' Ϟ/hl˵ %6¼ sO\Ftuӵwj*9ژ}ÞǗᠯ `c` ,ŃH1XDЅ}6K94` pϏr]%N+=@\O%_bg;mnrâц_614z!>dMQ-7Ɓk iGKZ4@{'Lꡟ ({+Mxa?Oɏř:x\GX0N]G7C"/٢ė0;U^!ecWcuRx E#xQ_3)O3'+I9$$S.% U ;{HxK+paJ#"*LJ< r̾r&%LVwɟƀ.Rwog ~J|wG4Q N!;G5@4KPIܷiȥa09YNVOn:# !ff:D|qߖպnOkWT<耻%4-d1l*d}T,EE[bF*hIefEs Ru~qn=5+4Ƣ8vBU%0xT= )IYՓPx)[gq-⛐~-Fd /ټ 끩ȔB{֟wo}w|w`oޮ?|\EvI?M鄪#FқtMi&1 AY:*BK}"&wiw1<[q GB?"u+U_B=d4A)biRհUjZ?X~%;?I^Wj0VszcSVq s9;0m3 lpRK4˓4`~;@fLMj2m)Jc?ms#$,F馬iDDDžA: Khj 0woע!0#DkkZXu]eF4GB_]צhQp!'[9ĜBiy;1-ۦĖPw(*N ]ٲaLF"=Dod%\q1;x]'k7_*2&mvJ^LقƾSTDͷ5nF&$PY3A]^cRHv1)cDeCT7mF/#I;ĸ=K3px_Km>ӓ \^VAߺ;l Kv|h}`UB޽ íDHW⠽9+} F{إ|t^VneVwq0 v!mҵKu+Vtbtuis Q~]2rQ]A8, ~'tyZ^Lȝgj[N9հ=PmFTXLaFjz~ңޥku6t֛_iXǛ1,]-Webg:^#$t)hƲP߻iw޽~st b"˾*7+Pl G8<&M*' R8.8-l̬,'u(V*$"1nDTXGSZgsA@3df?u_Cci:b <]yNItNپZf6 ؜kcUbZK!^:a)qF"j,l(0cht^[ᐿ3OHmrl7U}9U fd/?ޤ/aOq\;%#;p,yw/4.Y.:Ņk:4قOz.ASSlijQhqZA^똻۾aM^sB":1ފx) Όr&4t 5eZ*䧷 ?.¿eJciv.3ۆi˜O]|5t٩@%'͎P-GsQl}͛WG2B|"\Ub!3/^q'GGv6q3ԵURt24}oO'hӑS௺<+jX%WHܞwz &kYw[m_bؗg#A=K̶)-չ_}ݒj99wdxpxto IfsZij01V6.WX_^0\X[BboNdWH+A<vqxP \<2T*">W#yX2+S ;1 ])ʼnO>I@dˠ~s.z]R) PraAdҀ)Y"K_Qz<fU1&(emSˊ]Y[[=^*zmvy ('M/ ~\U`͹`BTb=g)&<~=h]tU Zpjn%)h ,? %paHY_)Y}AԔ[HEV_hg7SAjH򜐥sM5/!|BT c!I5==%[a"!p"u[I8GʞeO~;'Ďϔ7va80]aJ=ީ(+wtTu\ph+D2+iAOv4jO8&YJlg- NJZW߼ZRhЙmQj884BRHw7YdߔԃxyU@=6)|Z!\Q=8=璫_tXYBJ5c0% :,lD鋯϶@wr2 lsjC*YM"`| \y`ٹH1EQqח-;{*{ nC*dW`T⎫4(%$  ~*bEյ (ݾYHg:3&'(_J9 A$h怣Y@|w-)Gvs^E:]1!jc+.hZ9x YBZLYj&KZ 2D,sUrf`[ T:e$nX2Mu5:,wy84leaH|[.>Uo'8Lo\-os7g7gEs5꤈C6 QRR/&~,wK)_]=rHǢsi,-2`Ӻ S_{WŻ8V/:eӸ(}Y zB-Yh%QD~J`"Cx*;ӇWP4[KGz5 ЯνqKvyi_mag!!pq:g2u#5rdb1!ƵkAUY):B +1UiF)%d@!<U>`H B$ IyliL{uf,`$*},*XYoGn^hUYL4OoŴbDMb)v1s/V؛.%)>^8A#Y= Y-8b"bхlNFB=RKDҋϫ(t0"Ť؅׬0VdywO\5ֶ7Ҁ#dǻJ=C\WҲ!Fm¶М x&ĝa=wMhnvj:T2gK~}?hLlWtoIE҄Kr `lRRղo$-K@-V%#͈sqan4ij yZeB/ jJݬXÃ4xMpxY-4 US"MvvLC @QsWlj}& jA׭<{BsZ *JE԰le%+qc*-T Sk`6Zfެ  AJ1ӛ7@r\VU5 Ɲ(>UąҦpzg{T,^ë‹ kaIA^D;Oh?т_>o޽~u>xݛJܮ7O*HW? [9FAY 7h?'OZb H̵7ҋ?0Zu*8#OQ]kej|~kM_V@Ks<7NdSVtjzbDBhAA|}h "AyhV_ET.]K{2nazNG!I8O K ^J]2Me)_-|"ma8ѥ7v`HX#c-kɕtw٧ zoU(;'H8WRNQUl}R߄s6[W6rL{g!2Rc#DTr+`~-yu?/B)ICw(+͆XGǀ.k]u%5`FD߻բ;VQT48z} *Lo"nŲrD95~%TNbbnPI%òpQ1yTJ "GZI-&%YWQl32[0i醎<{ z4D\t_qP+WU GA{Wb428tLtG8HXcpI\fէJ|SZ.?BG^jzH6Q.(vʑb_ViF'ga3$T+hؓTO)Z0q @ l׻7 ufJǰs+ZSǿ^ϩ#{Mh];G)P2&ke pK: uUgJ5ꥶ*.qQ{m6gxσ aĬIM!@7:F># c+fsј߄Ij0Sbw72"_Z1WEnS+آ7ąLȚ-(^h1=o- g ^Yfפ$c U4j ma~h 9DmwSn?Jؘaвa`OŰ@ڋ<~/M:ɭh~zhmk`F2kț=|K:<\=2^Z[+7 :gmnAᬜ|'~ >⇤9HnB XiK Ĝhmy*PG4pADE>3[865l;w9$ȟ3Ys_rltI2Fb.z2"Emos/S6u#1JXsb~zo\>((opH1L: 9d6lVJ .el3~ dԔ$#+9u:%mL;nMSY`P<&iaK ]Shv9IuGx: ǵŸf7n |:Xjl3NUp.BV $׌JH>1±{̫]VNz 7So7}ճGP%bƵKKUu,*ޠXaX =.ߨBYC҃48`{G zXsEzeKtr7{uѭ u֫1e#lt-;f| /6_sR\oސ'B ri!%g"ʅ@1u)*:RN`O/4? ,Vt5̛W;_Y8D _kq`.f{}L%a)uiGu`nix5K \l t=cs9]q^jۺ6-0wg޻8҄(b̖Pf"72ԸŭE, p7o'biPlpqV;{ B`^*+b;P. ;8.؃$O ǯiX|X_n8SJu>6|)>|:SJoggE܂%"7VNAڱǟn@4fRu2c Jzí%Zqw`°ufshg;tm>=f;&h7ZC8r2}2p l)2hW72\YhF_k>UxJe@X>t<>ROxk-qܙAIvWmEjQCRG1i[9rڣ].SׁH;;`t |J[L0kwo1^ 3*qQmXx\0VM. b72!-?9"htb XP|iS-܉98|/ɘ8KF i/Fcbz_|@ wo, b4* g-o]Ρ6ޔ 6Yy/N] 4#zÎN!#@)D +LEaTJzEpr*G*`;^ mp w-HPFhe+f൵=kgHr! TS.k54M%7 &XB@B4˔ZFFrF$ ovze321*ʡn^ȽEGq $wBTcTUI($h541g@:DAxn -x&πDzRF{kHS7SUIMqtYlsET;uKثFf-,{nه#[f1VowKէ-_2v*"`H-\&,XeMMwsW#z$ Sk 㸆ݴʫX,MފTb٢^nI әI[bAP;NP}}[-fFBĕxb+:mtM(E6ޘ`#|\n,'pmB5ޮo)TeBZz]4`J9yEq D^#O^Sr*PM*\U 3-P*iKymm-6F;\ݪ:޽z9SXk+aǝo*]``%s"Qk{8p=|hzIʅ|PȑFoCU7&Jғ1l5wK#ɰi MQlE`#h+ν(ΙT!+ })|ݫUTU(5xg+p)qBBmT5˰38\3X@FK={ck&c=5U sϤa6HDKwiOWCƤTk:Es𵣨+Y~W,xژv<0㩸@v?hQ/)5 kJv-N.zޒ 4:flZTYoHp4W1VQ*\ Zr7τX YE;I[j;FU "tQ^G֢=T6&*V'7M <}lښ6]#4wEl飊8<[(Z U Ff)y^<7 GW`'{K9!QiYZkJٹ` aIAqB;ޔhM6){U\5ޫ3_83epǠ~kh渲0Wm4;l-{B :뛩jMǝ1t_'Y˺t e4E2d2ZFi9j şG:4S`LKxx'MŴo-2 WȖjLwXJJA|~-82Ayx&k39"`6G(vc`bf惈]~O'I>JM@$eTLp UNWPI_QwoA ^ Y:&|? Hlw+N FάF׿w;%nѵ_DAT Ks_IӯBH#$.<{9|_Mܖ#r3Zs,F 5GoYa/6Y`(,5Tҧe<-oOKj\\VWiTe%1|E{Hi.ɏ%dXW/u>ͣxZn::* *mfMYgoѯ,k!FȱEꉧ盦)I:i[}LZO&"?;N}:z:2:>JQAP|:mEYJS]4η*]@S͇Cz6+-@1{A⡂4򰚴6}Ͻ zRbmni.l5`˃aҍY/<8S[̭xRȞ͆Z|ib*M2ۥ[]iя`JžR* )kFی]%+)*Jkʢuξڜs\v8a-5eg+xt.Jt2U >~آCByaEivb=60{ ӛ7^yWWoQ>$eaYSO/5UHeZ Z+/̳'ggZODz/"jeP0gy?r?~L{[v L='^yk8X ݨ- ݠSFfi)nd*eeÜm4D.U"u4L^Ll.eMJ&sCchSŇ`7ʆִq,8$FК~GE\Epo^ EPԇz󞵅Ƨ}[sZ$)5lP0)yM?72p# H#+j5ySyX)G]\? jS=lHd HY7 Dyc#yF&DB81o#L6NS+tξ;HYʴ&^VH̢{8YoJ48GEOtC[5F T[bTV_6ޘCW?Ո<~uj 4HG̖RYSQX{&4]{̟oll}_n9_T71'(W=)B{L.ƞ꒕3 `4pCȪH; a E6Kc]g!#CE#T'S+5S爴P+j51pWvD @P4ZZlj=AeDVcO9#{o),(HTq@Q6RT6F+Ue6SH( UL(knwNHYӏT+Rix5I_,QQQ#eVg[|P:j y$fӱZ#JpM,9^Y[LnJw;QN~BMB jǂI)=5sX#PO e3|& h1$5`r("{ O%޷BHǿCKzT.QPY4Nj,:ZPrwDB~0aJVUR+9 mt_HFqnNrfwmL^1G nB#gǺ8Lѵ{}s .`ӗ4$U0Eo4K$GlQM6~{^>h4O;i"l}$Siu'WnSByu f[J{ }oU)[L`Ŧ N8R`-ŅtǞ%>I$!QSo{?u=-YvƝ{ZQj]Ǝ{< ᡒ(Xy05+}$či3¿.&]aFSc'.푧z6ܳqXh˺ZZC9T{<Vau0|ewm@ژ>10QST"둎GUQ<:.Jg y`"&I8O Z5ɪ%ZzZNJ)tV&x[RxccgNpcrMhyqÝ..|{?|˟W;XXo~yo2.ocۿK}pxt7?~'l^~OwPRngLJo~}of2Kq}n݂󇇻xܾxzC/~xy7~r;˷?ůvW?tӏ?wۇwOwQ/` qŸڊ\FBVg eMX.C*2aVEW!HzsRѯbc zXXАboX+% o#֎O!WAfK9(5dC*eŘC .J7''L*պK|hz6kK&>SX[D]UJ(Jʡ|k{-bV__⚂آ]_`p٨ U1.Bu` Z%*!HDI͇RRd|R,B_Iq v 4iE&5d0dy4#,!"5d)x 0.o_/JEm(^H%6?g?<__w\{o?=__߿y=/fxCǷnO_/=@ 30e[3W;{%~Rm8i bI[5lj*e+j*˸xrT+A;!2OVbh' 8mZ^ÑV:6e-j^0xh]iyxa՜ 0Tth1=1Ob/QJNߑ2hOS4k_rjO:.#dWt+էL\\6ui*dKɴ Lۤ Gr G1)h!вdIF@{H74W(<( x)C& +m2Bp1w1 bڄ)d*@2Q )^Ƹ֚U6%* uIWN%͚jIZ.W2V~ՆlwȦUV5-1N $P *=a6]x3 ϙj"'O&%I}2g( <]%j$.܇ lMJ+GRWpbʽ)6G[r0I(Sp'xw*+$z4VAz\t$\kszדPPM6MEKb/ڜT\#KC|R`4bD*R^"nczK*kq 3t5U]ME99pBeWO4ZT.\ p=…Jҡjb-YPI:c$1!i .RYvMj5"o eMNM]4Qp+].AeT ^`//?ZGػ#VљKݦHN(+mJEx*jP6%*y֋ 7I a/r^<@x\-ٸi*jz"xDTd+]6D.V*{tiNvW,Z㌘cnFH mdbQXXLԈXi!BqtIpI2 Tq{d/ju.-ʼnW6im2]"j7LȂq:z+bƤSHq4fo7dHMՓ~b]~1銚J6]ϾB-. T66=%1g\7:B@Ctꄬ&;o@ (|]~x+y֚%U7&Cylv WX%)ЦKWæ2Tr_d7Ca!٬m AK*/Jq ڭI3h&Mrt@)fK+ ̧*hJi$44axR:jŒ\ 5;g:-s V_adQ0SfS4$u( 6Y9Vt05 o2anE.8oa> ө*""-fXɒ!~r1W(,,n6˲h&6\,įT}ɳ<1ǔP+9D|\8\G2PJ1`h+6$4lEONوh .'V+: DQo:^e!ٻfP۪;^Flt&Bs*j] m7!2kW3jT s;i#W1GX{]I,Sr|]98)&V*ZUn i! u7S [q3hm\SΧ~}jwԍ }oU6@f\ jkP jBJ4(_f}TE$2Q^ I!C_/5G!ARU .%y,akTSh51؊"yxwÒ7.M7Kӂ!=+f:1Y\ڏPE-0G@F8?s(/9nglܾwlϱ5P( U{l~`CBn*I⃻W ۝wcd4n>x~_{|W[O@-7- yx-n%}dw7op`b{$VB+ڰ|q֭j(/OScvF G'pq5) *"l7Z37iQUnSE~w~ǫNUDڶ987Vƌ{"E D-z3x݅-%}-YhmDΉm..aLN;@%n'Oϵ_H=^, wRwwY=ڜL9"65@ 1ڪ2ֈ?xR-0|mj]oiKиw(AD|az$ )SZ4;)qy#^dͥ`?bikjz߇w5k`Z<\0b/mNPn5&t%v>]_hb%S =ZTK`ȧ+qNYSy,j#R_ᢙ$|y)a=BFc]H4K_sM v,{&u2^p=fI0-p]P* y P\Zx<9aJ^q'q($;нƫg845뗬YUDmR ~IiC1Mm/}J޽wuV^IWN 9 [cD:ĥt%;z!C"A QHFs*5wفڰȖI-*l(&b`>eX[Lwye͆!#O9Y;LliKc-,E~׺rM+0FBgux!YYpy$d֒mRռ 4MgM['nP`oMޠ@Xb#/xUc^xU[5Bf5¨O%O`KB_^A)O%RSbRxp!Lsـ; -gAFi9hz L#– i#4KRKcwX_@9an$0CC5= _b-Wk&_uM.8Oy]åfӍ1{7B&[ER1uˈ,|=pԱgjpR L!eoJjF,#JeHdX\ƑU^CTTT-Us@Fsv(v⩠爫,ϐL1bٶD'е.y[V|Ai+4SXV*EJ#ؓq02Eu(`-~=M} ,mh2[ET! NICКgʱ-WMK:Y饐279H${';e/{)m bCv+-X>9@0ɕ!0(tR❛ba teGQl1& [@c,Y0 .Gz=3TiڜHy7q񟲸aj/zf`:izPs CsY{lM~,e-PW^yĹ*1qM~׆h !Z9p׏quDw>N#+ jϠ HVbwG)N<=a˝ "]pKHhܤqwWW$9et,HK,4'tK)߿_~啜E{By>/=ZS0{D}# ﷌nK3$qV-/ -(jԡ6Vy?'EH~!ZadfҴzL7hhf0{Gj'#fctbz09t0wFdYa2nS3)p?"/ukM 3bQ1!-IfPWqM~S|j5ʰDVz-ul5 0yh婱[wŒg35}tKE,!#}i2ةdi+jrP樒fZT"O-u7zxM*ysy{v =%y)*U\xK|޲W#0JT)]Ĝ"8qb"쏴zvnjEEEA 5D/C#ydk̚P+..dUɵz 11/ 5E:o^W\TֿPv.9A=m$߉|_sQ2ىs\Mrt~̥ʎvE&bդ촱WM"bJ_SWLF -|Y2hKDzQCvrOWzCC8ٵ.lDZ_TmHXP\1ϭԩX"Oώjn*>ESMCe`'%p6LXi6 ?2t\'-4{SM jQ+YUXA29^{ӵֽ+sty.k},n`ؒvH}:JÊoAm RZҖ jV:͟)cEe5}R^3LL }&{cpqx:ovD7R~RYwF! CޅDrF[`f@iH|Ƥ!'_ֈՐǕ;3/ UkagjAr;aK+Y Cg Ϋ@u:%-\gJbBǻѡxAYkԳgs!J,y\ѯ#@P!la*Ct ֣#xv4^Q&:~k;P,W!qR$eq]["A-]Ԁ/eֺyZ}G2ԓg6E ^r渂M\Z-ffyvcI &_T Í%.%cOa7a%eb1R9wh᷊2b.[ARUgɎkt6,<[Ci2`%ϖO%3wVnZޥf4Z5hAm Xne]ƭk؏հ@*\iiC:hVo=whI̮kq$yGi\ɏ6Hc GqM`_弬i%7?vgD`KJw`>Qe[% "d5\"Y>~Q8_~}TR=bOic^#!WjZl>-˅_p]GƷseGCBx8UFxIiIk~E _jW?h#XPi*r ; Ch=Oc.ŊYNMsn=s?Ǚ]ߔ<ƒHVM$'0Y~,п97UBөe G^}"C'|z 48$|-R_vkjXOWɶ$x3{C$45-W>t`]R) ?~[BA :tC <:n:|] ]z/Z>]3\oT%9o/5IͧsILdpS$UEH|_!O:b$͔McG**q`fzvo?>nJYj>7ގ4n ϝw*RGdfPrb$/7%#$ ;[k234t !4FN;Ao ӋjŤXr!Ul\Jio*S]ZkȢ{@e>PLNA=9eE3NJ 3ǽ7;R)pgWzaaTC]<E$Ej( ɯ`mՐVP83́6Tz}eO,ۗYZIh)`>QL*$)h+ ph3u ZLk-RlR$Tu?J@l lyZdϖ'Lgb?RX]yKNiw`61I DDM[z[\oŒ}X _kn]Ns7!H(`)5X`jJPi( J .!7i67 P)- j<84f֕!\k~A';Qȓ :ڍsB_')|v]*v ?dFui~m#н-HVu:J wranRjw4L܄Vy4z7CpC}B+歮GXM@z>+@*M{<[WL-؟p| iXV~q]> Y/9_oX 0oHqL}ҽ@yxǹҸчW|1N0WBF<*Y\l s>Ou[bN2P ]wwo }\׃g<2nms|:?ňiU$Š.4WόLdJ??~}dlBUSCe,7Dne+k#n-+ 1g` Z.kwlC6Xyԇbu[9ٱϪ v ,[Q*Y ~g`{^8dOvę>;֮`?Mg!wvu=x^D{Se$=w*^b(S4CenmzM.}f$xέ_Z#X )n #dw3]1Rh:j| ( ς7 X:/֋=hK!F; z,h({ [˒3D:"lJ\dP0Xƀq&GK-pp3#=fHYntCc;@Ew@+Nr)r۱& k%K+QR$|5ƀ4a)]b7GIhMq/џL1],-Ar] !֤^7 99ZGn`Н8 D^#.EEEqa]h=]W8<.;fazIz1zXzp PC$@Mz^` [r!al^6|J ̴bzaIkvvV&^`V]NڢLDŽMj qCxG%XcwZ]7:g/4s#27ٽz sOqxno! DWoޅAF؏{9<~*e:uݚtT<6ֻB!=&􆽮Zݕ7`bؖk+>07ͅa}2"˜OZ[wo^S]p6궆Ӑع>av;1ic:73ǖgFՄripH [% ˛wRVߵnKضb}jGtBžA 3xg(Z?5 +X=?+%QpwŒ:\=}} No^v=_{G)cY~}Kt~КnҌ+(5̳_7Ҝ720ͼ7+՝4#mu"}' 9{!e^ޙ}UԱ҅8I^#iixZn={봺/RO̅p{ͽ2j%o5Yz 5}#Y4c?lW `zґªxXXW]d Lyrq yPb Ȋbf+OųU fIUak"^KQH4BT}Ziz$qw:C|0[-9|Ȟ|7&I:n0ܿg= 08gȪlbG=be@(BEV[bbx\s^AX)cEwzn* 9rXEʅZI2@_Bitpx:'L@)ѣ= տY!diTˊT''N#cb}zUty߬ljtq\iQL̯:IhL=>M=NɏGh?t &ZkQټObQo 6J:Ƭ/jWE{)|wgG߁4@BΛU-˛L/3P.я^gfYO0?P Q|l-3PY]L0klT$(ϹPDۭH~{Ҩ٬qj [Źev]J0S+Zb &5k1@>^;@NXi+v* (]=rG9%h[pK2uE7#z/aO((G{a^7l!'_XL-ɖB@S־Vws!k@X; l?M=, x<|]=ut{d׬`׳U$0f| y/hi{]aBڻz&zW[r#7 7~ˤ*,&M^*0mڅ)lADf^A߾۷/m(rx2-ٹZo˜C]9x1:/9сz>fP4SkGjA8 g799P O:w&y_N+FfUk/1tqcGWwfg;8[NcaŘk3n9;wsr}no|b?P﨎ЫR}kqzt_wP1͌sJ3N㞊M.s#ṕ:_{ZCXa`_m> Dʲx,L^I1 J&)i-X<8 <檓p a6okY"I" ̎I˩[ (=)yr Ra~$c hť5/@r լ𠌾iZ.0TQAXO)qdzg۫kn B$Su4ب+1F9y} 0e*`H́NX<\cp\JI!a&/+6-ֱ56xVBeGzoA! \r떟2>S* %qHIdu>9*bg uvE B R*#Aq&D!t!TF%% 2i~\+ ~‡a# fxFy( łm0?LEy0LmU;VC)vKw+z?_ȆvsYx~IQ6qI㥭6mhO.rh{4q3UhCNϺPiQˑᮡ"~^)2_NEvO!#GD&}khBsvg^8$_i$=;ȼ=ZȐ B!#7^gһZ$y%l3b 00?Ъwyw8v#ͭM7THnQyTI&#˗}ָח6T ' yD8^4\kr@d*pr1klncrL3t>+XgDg|$bDkE R?@̅?||M? _o@zn-ȑzz燜 CrNQ~s/ kBMR"nP9;agߟ_矿o=dfh{)@$4NRĥ$x$KȐ3%.)aFB73;ʳNh:<j&\UH si{"E P7o9߁$$+]GE3ٵbH*.yb;E(D <[.ceQZUP7i`=N5h*2i*tj4,I%MiyWzXa8͟]ZW&ښc%p&J9KbWT 5EsI\/.Hd}$$Vr<:ZjL9-Ln(őP,dp`3`D&LE$2$[_uNlK-1B̥&Y41[R둆Q+ u\7%tT͒_0Y7Y]#{- [~x9a |1G{* /!&F5JWgJs^&C2^Gi?3 fzjkZO#?fNk3GeX5"XǞ@Ǹj 9R]ɗgx|yhgٰLa" \+} DG=!`㽐~\Xyx'.B`d}?>띀VXEAWā6-j^n:|2$ (WMneu`* Q7:ɖum8]fY k4sz[0i+MÐy@6HD|#";'ӋEHV+BĿyY/*8B^o|bN\BOzctEXn%!Ѫ/xZqS<>EYAcNj##W8ܖA4c&6BXqapq$9_M UY7jbJe.cPA_'˻1{ ?'~nUkQ~d:u%Ϙ{ѱYCL-Psvߥ),&=u'cŖ5فm 6({c[9Di ;- 5'5EH?Q4P@! RL@҅H]X}Sr E^r$81JVĚU,VD1Ij+PfTrܷ[eE[Z"b*z(0;?BiuQ,0 0i}&-%\wX3"EFTytnGin=-j pMnx|6m$9To*fƭU}*K(N<NM+g39`edagLshX7nn67i8w +6jBCG}[]7rsXEr7G(lY_NFqdC es<`S67uYEC\9e],n W^Ls0+SPj^Fgd5OPЋIqڋH.zSS F}hRMWB`@LI`BOm5@NGE:F@qgII0mhRȦS5<֎ǐ7iԇd>m5Mnh 8P^2/,$%>x_-g;q4&1?NHo>~"R-z8-n~|ǟ>뿿uKu..Qoӧo??µ1>~OqJ|r˻;JF}.E7?uWu)=<{ǻXpG/?=ݓHv;%o]~kRY(O"ݾzzvGxLJ/_={ͳ;Y޾}__iTFKw?xw /Ŋǟ>Ӈw^ϟs绿_~yy>{xn}h`\Q5K Y&8sc'`_p3jmA,$r/Il QjWi ŷhId;P$(G1vS `oX fB *HP,AΈ6ZMa~yE-Jo$ 9*0?$3M9J|bDF%G-2'uC+Қfi޻P֤޻ [I]d =s"rG2%r`f$y}P: I< Cq P9yI2x E! (;x@%G;8`x $3x[\-(g.o3MGY'/wr j(E0Y|18n~Hd䤠(F _] tی9R~al~X'5)PR@uW@0F|ۑX\-LT%LD*s*NݪIpkϼv$vSRR8ptLK)8S(ep݁#*6@-}hi)X<%P,]ܿ`Ԋ6_``*K1UB DB8lhfttP Zi~/gHVZHeDK<+yMQXKZ8o>b=R#貦⺒R#GdU[--VW֦gJdX[9BAtĨP\-I5ɝΈV eZa;l9X־h(X΍ ǃuQłAj9r K;A8hXQ)r =V7-%C"8,i4)hhZ9/v'0y-&J>+=x2]i'8yFfFL'FBz$41cRʡbN%)) $ThvR?!XyyS r,UρWQO%w楖9Px,Vp^47saOfvIx9XAԼ<"񒛰.n߾o!2o=@}~={?Z^?߾?O<>>#->|O'^kdGK:#%VM'yxE+S9'oy 3)Hd\߾8 BdiYëg'%߻MB`~H÷S&ྦ](QE Vgω6w.e]Mj`Ι+/7=>}_mFŨ `@1N q6^q8Yem!ͫTu m0ؘ0yoV0fQ&fR sbMeQc.FQnnoJJ"e Jì9+.$r,+1K҉Y ]j5*W#Nrk}?@Kxt TBqnP/U{2 K b>Mcn`hH:w {k",jyD`6C& nٙPhIJ-Dn 4ŴYv4 eJlhpFe4,}t_hIG\)u W&4/\6b5gS-8`jor0dnr OiFx%OӹnW+^'c<dž\,Ug]S,E`>LbJ5,47Jհna9Zv[^TWdIyzɒuH _`õCWu0q="@ >]Ar8i㗈~ < j*ZMEmv2N(dZLIc]=&SB e8pJkt7… aٲ|aԳ P>G]ٹ)eX+ZkdA5..NrB9M-RP"8ΟCw+&O8-Sj cRntU|ISt&lȕӢ_Ot-׈3B JE5NxF4HS[q3#b4_&ȁ;6ԓK(3k='sȎnHu~R3w{L=hըY:cu市|gQGXGMzr]{ P{@ wc*{ jVhPs)dW IQvH|)w`_O"`4NErY=^Z ~b)dT:t;"TF"Y2Ŏ3 EVfFzs&ǒ k)kv)X;3Ot.H4=sם#ElW3RQ•f2Lfi&ۄ*r$FԽY@UJ?٥y{>4n0 ԏ ;|G ҉`j F1Ó_0uh?Rd!adDLd;$#}ZB#|~U/vit^Cې^NuC F(\<=)L);;ß(C!!k$ `mjD soN"jxad4:JV/1|36FF=5hԵnt}KۆhQdvjYV8zY;v7y$xI(]ُGńj۬fk"IIqS7!AHTwd+VqF$edD.IVr9͉19K];;C|G I*t&9أ4Bاk<CIp\CMۨ?t"_^B?='Xny6_1nƶ.8!FEqTX[Y3 \¢m2xě}@ūe=kb*\زC\|,Zk;do,BrCfО\0Sx,= XSA'j͕6y;꼾ȵ)TKfHյb x0l´^5wKȷ]a& >j42dim{Y]BҢ/%WB.Msz> Ewx896'נ)8%lmdb4 AuO(aw~hB6@e/5Zq)Ji>2L% 5y]ة᪽jj0Ct8 )8׈Ou/Ӹ\#<QaK'DLcKQ9p-:Tx?:΄9pA5BLa1MP:h)/e.uP%t)b}&BN- j#WOd[m*#\ X &2݂"iJUֵSqEtmh.ySFYOi9^v0R{B :p Fo!6,2Ed\ b£P$FR'iyVֆ;Q*}E l6oh*Vji8ļ߬M~k!uzqu^ٚ\wN}xai-sb YSsP8<$si&W=,!R]z\st>.Zz~DulK;.!s]})t_Ś)*ΩԈt{$Qɼn܉yI!\Vgچ N郶ļN4L;)6H9Ug*nMzga3\.]q!G<ľK>k(tY1]G"'YV-vvLq#}$.]^i5O: m=ԟG'h3PQ,uG=3g!s@, L8I2W!gx/7bƣXܑj@*ثcPż^ *JO\e){Pt}&ȱ4[IѸ?SX[N̏ӻib x=x|bj)H/qڪ-!J|vuM~iScCTF|~ "s< !S8hse@fO|c=祒\FH'nD;kmW#2PmӆI6)̗/Dl2v_BGv_Uh~j&_(~@v[σ]9/N5oSmrq,;m<爨'W其;Bgej9spt-7֖xUEHn|N# r%1V0AC+i@&г.Z֥Vl]<:pܨH1uvW*1y9د@Ȭ+u2l!, X3ڭjXF٪*k!p榖=2\-=^]vh/t18Zoq{=N}:vQ,BGEZ(yj VOVeҪE[֖MkrbյR ;/9OL y'/'&\ۮ/`+:OݚܲnyUǡ-W{Qbڷ,Yn#ѭ_` Ы+k>3p T!um@"(G/]w7H(aR;?ƨitD2`%ha$Ć L=hJ8zX>~Gxm*KnLPҹZ'[xo=L@p{t9(<bUw`i{H]ĨjۣQPZ[@I2!˾ /!fFm<:t~8r?*\N=®Qik$-ޭHCgMFD6r{.8OzGo@H͏BK(ihҬŚ/αU|fԊ[+ 䦳R5%__-(2l"+WhK {jat޴|N58BoQf~p_{Y_KfFЭV3av&cfe:+g˜Xڵ .㴖Pha\ƚ1??MS &svFX0U:xkCJ-IbHycX QxR>a/Ƞ9cZzZ jvu,v ,s,|Pq:q' n-!u^Ik`B=]Հ 3PB(RV_[sEOrFQD^=Qn?)P#Wgy uyl]7`oKI>+u- <ԋֺ1;&j9_D n&;^TP(,놰4m0V$G@FU}]rK[`!HtN. z\W91 Vk iꌸzYXLq9Itt˕wi:ٺeOU> nx(;Ԅ,uSmF, =͋[$}cz\1*MrŪ<7^*?N^O.cFfFȭ+_]gIWOW[B[uapA q^ZZ"n qyiFiR/-;`^![GEٚIѵv Xt ޡRK_D,Bbf˦O x#r}FԑBߚ6pŷsU<vŷ::=ӭ` z:S/p=m =#峵*R~7@\zBJnQ5CN9YSiJNCvA.)jf_9Vպ~Pv9~vmeSIʉ~>X#ǻ(?Q2|gpX^$c9h l)pfA4wӛ M֣O1=`=`^\Òhڕ',YKk%rPPS]{\S='* o$4g0]S 0mcGj :$ˮwu"o?1gDS5LHnӆ&.(lwdD`%d/{QQr)^nЩ؊ݾo2,@HM  )dnz8-ouq 7=L.{r/krbM?p~dԏg𮝵'g`fȿUtӦI^hY]ZR9Z3vogKr>p` >܇eǧIpw#R9I j^{]J7]9b WdsSE |už7C7m+J{OL ygaPّCj܄wKeXKƠtIRB`[rX=Cy}!b2IeRA؟-+p(Vׄ^o N*r H>у4DH(`ŤG~'d2_xQJX DjEKҙvfڙ)Lf/X䴱GTYsSW$A9kA3Rpx#0r/d-B jl>o7mz9\PfHLKL{?Q I2iM4DR`ƍ6;3C$KmZ]$QN=:Id$OS:y$_2r$ mD%2Usώ\YUn1 i@+^&ƞ~ͮN 8vހ9ꩮ!&/ݓ^(͉>2-`ջSeu) 3+6i0Vw\tV2|\'s-Wh@. T%l0J!5g 6-OvzR X}o]mͺg lG4AӪ;(m[`ؐ'o:#2p2򣽺VB4MPuis.cxǁT;6=6ТFv[zW;G!o9Rqy|bi\ (z9ܻ2Srpիa<"RMG97,f6ܛ{{Qu1bz]W Y׹-"vV+?F T_^KպR} W6Dgޱ⩺s<,|S/Y[&|r-Va#ުᒐIbtC cc\N&$r$|~FUfaP@G=+_I>H9԰sW>njST:z>%b(N#%C|{}cC{PM7xfV|n 0}hzk8;׏<^u',IMMUW؈ó + K,)׿٠2+Vb7:H}V < 9|UkRUN_ 3x/ؕ+'IC*4z)W+_v8saaJuG)M1xRZs%~ڇ[z+O}Ez" ys\s,ҀA͑+IY/~Y#M[ruI6&&׊Q:ANPU_6'9s9a-2킌:n$-:&Ѕg$Q$\‘,5$}O5?dN|C. W؋" V7+J}n:N8H`2l mut 3}q_`ˀI1e\% 2 մe8Mf( Bٛ2[Y[YIyySpś*[74Jq3` )#У;mS{Ѫ<1/-d@FnyNxkZ&k81q&\͹=pU=KM̆,S"O WYэ 7}-#Jxۊgd;2C~f_^r'ecnmdi0,,w]j/)&ko4k&p*+1$?Ǥ*%ӂ@a2jgTד#JlE*ATڋܯ^8pݞ<9-嫅'ڂ>'p^3J)U_tsu\\Kߧ^0|aNiSm{-nT!'ҵF$jys9̝%g E'!7AwC) c<=ã2^+]8% 6 :d%dwOԢD%_%tI Ϊ#I #n\vn]ǍDMk'%!*3sdzb!;TvAB .Qwa&G8 H:^Q?A ,? {{+MRk e?itP(dFÆ];2ܳDyT:A1IcMu ]+I{YwyXMf1zy8_ڝ\*Vp>jzyf{UZKz<)+GJ9ќH -;*%lnI3ج'zSsH6n6ʞKuUhhES`:j)g(K%o-CIV,tΖ8NN̪ϕG[]QΪiPJ rF[;`B[vA,օ\rIT8o@en*й6Ε]4HZTV: mN7e2 lXd$h@7CVٛ5 CCl~^:d5(R)~=4خ+71ܝ<<ɝ5@?_}}a)X$?~I,Djj~f/_Rk{ݹ=bt|tbN}|':ܘq1Lj+$٥xUM%[ )Pn_rp߽9@Bt%p0>|z.74Hyr)@oߡG8`Ǻ%4@Ȏ8A;Bu}Ig|u T?>N$BYG$Y.WO߀;pn:MGמYSsc`~ |;ϏZG;;=;SgGhg48t۷]5?!JJ﷿?xGD"_b>(1/<~\.As iiNX!!;ahg5^Sgfa-a__EJ(/3 {,Ck PECTL5X e+e Y̏ o 4l,t'g'q4?A $WILxHٌ2u;GPBknP-[-!79jZo@k@y^TJOF(ÁQqwp@3F͹bp=#_[gQ\zV2^$iVL@ΰ߀/.a&j象x Xx}AoV4!ϰ:qNa16^qL<1Ppy KkcTrrI;dHp"4nNm>b;0WK*!ͺgB1MjabBƲ4Xh%17^>Ji%q[7^ʆ=ŏ%Y.g`И&$ b9txUvjCYbd}t؁g_1%4E=BUwܘh0Jˍ ', ..g,K|L.A-1i`Q&q' .;()(MGVun=t H&\QBVvp/ *َgyLJW߼<.,O~j߿=%I/߿<@^x=߯Ovom=֛޽UK U5*$N` b/)d3w jE)hX0dIU|@hŠ3lᚒEC)RJ"^^cP*V0+@"OiX%Xmzj6 *xkesMr&bjk 2h@֠Tr mRB2L33{ZibD :MLxT*|E[,Cba˔KAyኦ=/4/HsKm Nd&H < J`6W"T('bPLʻ㎳*,93W@)ƎIX:&'&qY"b3SI b@FF)u4E(Xs%8`IV,B}1fSA}G^fd%g}$xakĎ)ƚ#ՏLDa56|W>(V6BǫNR1hNnTyClGM/8X@3ۓlgq bƩNNrۙY6b>fL iMB> P3`~OeSeӌ>3L-,=&bpxe]J_W+ pER\Dv?aLrv{aQNi#+ I/ ̤!P(vJ DX"B"f 8uE#CK?@c[Ҷmщ6*#d;&1@=5@Gp;l~#/>MVR*Q(U"OKC7ˤwJ mgXpnfNrTd%`0EI(rM1ه84TE2hnKu ϝ9hH|sl;Bf̊tZQVbVZ2bձVHR@M(0WJF2VXFg/[w#xue[ zP$C KeRF!CXհP5,, UcWHn‰mqVqf2T3z=ǭejd\ 'V9XK8 JU\#עfUOf ?YƐ#(u^$SLL5`o3֜P`/;k8g[am!Qo@atyQִ*H'Q-L1cm'wA`h?Q*A,b}+R3bK4{苵FS즀C%Q@9G3 K1H)'9"02<1kZdBA1˝3$UGIX%$' Bmr L&:[cfii̹DPP fw#o>~|%~)źt,Bv,/n`I =YR|H\R^ ?G.>,G HR.(AӝŁG/p&PϿ=}|Շ~\Zi‰3bͽXA{)ԸQ҅(p=FN%YMZ_óO>`GԮ5pϤ d'[0D6I[Sv>Z#H@r02"8BWkFi6. `)Q:%M[1TH+9/2$ "e#dq 1ALq1[RhD|'../ZGL*/ ʥMuN8Xd޼BKNO}h߉p*S$vjS}Pi@MTӭRo QLt (; Bڏ"F tYyw?EUMjtIؤ]=B>%σ;KA&:[&>uj.钍8҈apȚ YwU\! O F79 rD<FRjZ sǕ\-AC<x ;&^sGk4]!Ǣ u:+CDnnv(KN |2T O%%"0%v v H4%ƫݔ,6؋^f?C&K Pav:(5DtlؓYݬd ‚[߇/_ i%4#(1nU"_#;qv}  v}YcObCE.C93HȚW8|qmk*v|W8[ңMgʉbwKmӜs T v9J0aedJ!m'&qN`6Vdcy غlztfYj`[c(ΞHR=nw)AI-Q6p :|ʓX#Ț'-tp YY(f2 TpJ,1Nۯ 8ȿ-}Ǚj7[ 2QV.c/H 4`Y:>)o:s[g%3w?7iR ZSL%qiL`ia*L 7,Bi?JznBleD+8W)V%SN<9f'蛷s1 aa!c0M@&J)xN^tʷ$/kEB%2Ⱥ7|ɥ̇ dzU\*r)RMMW!޿zyJM#.I;GLLnݴ)h8f[ @w?THgX*@Q8ƉuDX&dVb O~/vMx®,ɭwL~5z?Lq77~.Rtɫ=.,o}96s:j;kJO>#\J+lE0ӈɞ=f]6Y/mJ:GcT!yvMXbc5BBz8uQrS:[]dԔsJ%7`DLiɌ/|a7sא "kE,K)!3g/2{.+2I,=֫%V7JtGk [ڋ#V8oNUJLJc.?vYnf_\MgCCi܌EfGͨ~ΌX$a1P4f LOwnT'GZ:(TB:ZAscXWJ2Vb@q!ݠl`^25RBB|l7`eJZiHۇpBqvOoRMTF`j'gPF Rni<._Wl6<ðvD,9rjR&':aRn9.RzwC=X;s]r+eR䮢#Fw01DOL$d'wl PN9?+Ci=1I-12׍\1Y:zAwK~s&KjhGZ~/8zs>"}1inptk?>x*(ZVS))2meԛĥ)Ǭ MP)]AYYRo uFtn[]bk(h]P^dӼj.fOmbcXԈd%.!=$$Aޏ}KvTIhb+\]u#wk͂~ɒ9Eg3_p6)f]*u?7!z.96QnZ.U,:vULZ`.VLQ̦X"Kd)[?<||,9ʼnoSqYD)$wdn79-^R e}Y `cSs6N6)qÖIA/Ǘ~3}󏿿~?wo}x>o}wݛ)>Y.ZUΩU.r-U4lu[$U5fh:s-m=q\a)*]~-X{=ԝ’Z'OSqU<.gjp+;ފKL-^twR4 qnatVI" g7:X{"[z^ X%)'rYdq|mS;>$4u*tջ4;7^[D< =xeQϐ2=)ܵP⌮T[O8q##b1pęzIzM.m7:'eNN5 efXL^:wsב]Kt׹:]89X-OS5,GZ.nYI u\-gѿ KJ&ōMMJ_<'l: y %C q.A8ĥJ3DP<~1J96An<*I]| J`.,OYfrC|S9Q +Ks8#΂sDB a\3\h% *Q_%p^W dDar3J4c 1(Hxib@hגrAgI%mT0=KΨE(mR`sCeL63E&|j7;ΐd+dHKd NLw+Ҿ=z8"GGXv<GqPw?*sx8K1y k]v-[i&I*תv(k;G=ڛV؛9YגZ^bxW+a zn? ?u_bᎹ{R!G}݈ŒXtR*F"K=F2j:_Zr_?}AC,Y`Sv~M=A "_R0[s]K.NUV?"kl$..5t8MAQ@[H8+1ll^|t?Wl>Gn12&MsyO5xx O1Y.ZL9At֦6'屻 {3H9ߟP ȋǃ w7 Yh;" c8\t=s dž䧍ByurTj^=s;:`&9]GV+Y@Τ?g/Vd#+_^3Z:SV*agPv/nh> 4nbk'ɭ Gu"S[GȍS'}PcCKXmMˎ73T__@rǦy|4x\e"HF P\~/ۣ{tռ]aEfmg*7xzy/Ô0A :)0TnU_U<v‘YOxj9i9\<9 Ji*{U tOiܥy(:ROQx#-XU]] 9 ɗ;ѵF k*[[Kܤ{xP-JvghblH^<^SBF)<Ղx=qZcy8XeGIYA=Z(m V)tD?xzLhӓzގkM"wVtk> AW< ֹۧtae4K9;@wvPne<ԾBxKr$hD0fHo:}9T F`7^5^ cur: W A׍(c [9o"/K* Oxi1f+UZI{1oSpI72:p1g#ȟYyWs60L_C*wҫ9l` c{3Q0G-,„?ZmW6_?u8ȐS٠",/ɠ٠w-O Zrnsᜁך9 ƣ5Vՠ=PAg:=c=0F3ѺxªۏggwzD#K9<"[{ŽDp ը>mw_5YgeUis]iLǣgO$MaHtxQe8|aczwM{E;.^V˧[aYX5%d ᰉk+ڡ5'l>S G;c"䔍MEZr3G@{ɆwzjV;^N/ѣ)g2 9B, rlJӽMMޮFAv.ѡS7$yZę^(z`8ߨ6޵Iz)zIY|P8mLOn5ɷV31#f:@>a~MYOu _2v|Y-~B_ܒ_vȯLٯlxX)+kn@GC ldlyyB$>Ɲ+_Txn,b~P޳AAT'G &d <ƹi!G'm &Vwq%L9Qt_5̻UNADVy7NLR5UL㷡փ|JcF lz[|]*(c谉?aH%-+BiB<\,THnkkOn ړO1h=:~sG6pKpYd)BY;k㷷z@MPdMR+POjTI=ȬSDs@JdCFgr $Gܴ'1LfYI/r^ W}FĬh9-U?Z,{L6o=6`'>k%zo%?EϢbYR/Y3ё6~ tv'jl^|XvGm)F-8HSk"J $Xhcb^B=G +U)`ZY6!o2s*uwy9\w:vհ`~"B}z?&-xj([Ҭ@H6dY-*I{S@+$`?\6f=k A/87%)>-.OJ'ӝZhldq>CGm?Jfop4SHm3IJWdaRWi808  ]0_[jZ=!1K٣pQ!IoMo# "eڔ~Qzl7 tJ, \3hi.U`;! X %`&M]/sb!X:_9}ÅyXs\k*RQZ T˪ž䝁9E_xå[]8%'Kɏ*dKOYܿL1Y95&9ii9/蚓$ w N\I^hd_a ۥ:ۭ)36'` )BT,vAaY<Yׯ=s=2@CiH9'汭Vbujsv[ZSH۵9LуuZڋ;*cA'﹍v`wqHaG`8?K2МlGnVqZ%  .$P[&Xu lzgCQJ6xf*Y\~R-`3egd\D[^y>lbKXȮVLV+& ױy4}ЏbO[ܓI.է/z9}g/T P_=9/Gbࡒ&g*B%ի?&6@jE"Έp72)\̭ji<.-^B"wn@=RY)^wTHmƷ .{3vz58'jz " !u;gڵ&Yo׵štX֜ßU(G6gvJ`Bfd*f Š ^])5M]{YQ^S@fp}КH#ZJ3ݓJve @L\ܰwQAh npe"kJv}R9b_ gH.G͕|"O{#i !h7=Ƈlff_cc;avwsvbMj/"yF8ˈZ<;Wτ|~w}L׌J_VU̮xeco:G/ K=}P-[/Н4:-(_T6_~',@e+ {A{KIީ̼; u42/)'a:K[ґtLFM\. Q_][}vc84Sz<^o1.dOdz sg[ȝb0+wڢ֥}{UUzs.mJBTRiJfVOP,:NV[EbHԼ~lq߁!a{Oj9š1l!φJsukވS׿>.Zsv{w c'Ok]ЊaC{Z2/o]XSq83Yݿ?q ҧS TEBBKTgPAX-Gi;JiiCpD*4CQQ& _VM1gکՑ\dߴz&?FEN*z[rU:<dڽd|hUgP$8% ‡@~,25x\C*Sp wq-&2lPg0J>uQOk.8>h͕Dvf! z#rxbnutOQbél%vIet)/i7#+D?~9}(lє+L 妉+[^IN ߟ* լ!'&>pP h^ G4 xB}ċ"!U(X ܿ?ʋg|q5:{;{$rM,5QTug4ľ_C0 _I8^ZdMLY[IIuˈ2M0pb1߁h( Pں  Z`0DĦ]P]X-Nz_W@HS taʝ'D<%PC's ѢzL.vMLG"jҚ$鴑C }``pҠhHP߸P _3B/)6_g>~[  X{-H39B "L1qzVNVؿR C`6YTcw+i3 -TR'X$Қ$35UNUTTOwǘdP/eUmͅ0w?~ȉQ +ݱV*›.Ԭ"`M2Ej*5톞Lp[x=InĆFUٕ =>PYd$\[|U , 섎*6Y9fA*:PH|{p5I bٽ~V1t?=,`ֺsQW {Ռ;қ3<"ڙo9":WT.DEýŒ9MY;8c/ CwmjJ,eU̚+2M"=M&SІ Y @ MY'ڨ}:\7^ijۿ7NMY"aǑ_ C#?ÛZQ .uU#1 9/.Rl(1Hhw:VyTs902iٝqXO,bMk#aJڅWΣY'J88✒XG>F C- ާWp;c )w Hk8b;^wݤ%@et#$ܸͱ)% o`3<3X0ةMN'Q, VLvyg[QU((/-Y=wH;3>7#KW5ȩ˱T#GNNnI:6yf{ss;'!fSCHSws|K9ɠT~0N(wRS ~Qt%N;;DqO7E9Yε,GIˎH|voIxFɕ %gJ­ r=|zk1i+an& '!%E-Wx(ROmdzXQchr"~BS(i"!!9HR] ł]:Cgdܨ%: T' mnT78q0=x A(1=}">8B qsڏPw1]R!Ips16SR Ւʕ4šTR$U9X\|4t㙢tcg*xfJ^IBH LDžOt$Mg^ԄP:ury Ug&H%KE*93e/ʦjn*նY$6_ȑ$EGT#^#X"''I _lz]9= 4S *k%f@yw F(Q#L8oT&9W)﬉\.aЊ }AA,5|G]3v،58 ٩H^$)!â:!ذUwӚ{̄XwD~̰l$G\V|"y* ťIiKɻ*&kLR1ݐ3Xu!*d8' B^~: i. -~H1c?з tϋ$ >$S|4%F'&w lF!>{䟝j9y NJs}ԥAtN>߽L/>}()/~iTq{Ԝj|⭺~ͨxk>g0yCj3Zي})Sך/7Bܓg"=kˋC4;z#j'wuCVNU5X,TB$8J1\?6nk d7F Atpf{ŕ#32J"_jxclrx͑5"39LoOe˸jH -/S,z.$eӝɲHkɆiF;דǹ{Ě Uzc +ڦ!SI xe[QrN&27"-芍\7*{Jm(mv2ț?&8橛_qt*yub| ;"ZK8gk@)Axj I+BrHhHG5:ʚp_ձZ;[g?fm̗4咷}]dmrs܂wO%ͯUpYDYP]ҢJ\~d%4hى)v.|㙃=|&< >ĥo[{+jog|˔@p@3pT|;pq\#c5fLrŎf^`@ԏ߿Z7k4{,aP-{wcbΎF:-nvSz4QݨAA\3Z<6LuZOu[~bogX.q Uwi(^+!kyEҌP^2l`N: V̱ KPEޛB;y]YjCoԥlޏLപGH L"KI} 9 m'Bt!dR[F\WCCR4&n=}kSgl1e#Wlw@4ӝ@dA^!6AQ3([UⰁ9֠=[sM٩c5Ocv[Yh%rח([Ap` V~0jżj&wL)X eޤ|Ջ m8LLs7ՍɁ<@݅dٔ(Gi8tun5pvFΜG#gUI*yE:'= %m:-J5xՕB wrg@Y˒gg׼)1=yf *9yna~T*#cSjlh o8F~\.s>~Y1fUrsIeBCIA[mo9r<+G/[-7]8Bӭ閴inmUjHY|ȹ_>}slOڞ^Pnrd'SڞybS'߮OO_Qq~׿|_1ݾ}܁ ja{qr񎷗g; p{7WׯOw$O\~/ƐW>젋ۏ޼;q'qO_\oysv]*ǧ/g\)x:PY\r.]JZVb* KT$RS q1M 4`nJ41\tP0`n+(]arL! Pb=S Ğ? \}^]\e qus|!u{|GI5@z|h8EEY#8:^KR<#ImA{;PrƎZ?0;6uO`U?q{w/_l J L.2LSrS icv˘>2AI9$:4Άdll0ĂEB7g7'ő&(\$V)L<FV&Qt˘2bhO1NId n^7Bo9 b&0xchtifSZz؀0M4% 9Pq\QGU qZ EӓKu5㘃{A.”`˥T6#p}h%o6'C1 6WWXSCVc[BVr'(kfT`4Dp,`x}v|>J˲@5 `@[W?;+@Hvs9ѴJsfԆRrފ+h1V[I]#P cd( gx~ՠb_NN7Lo2{͵Q{I0hE<%P%4,C#SesސܥgmsnqюRkeH5;)Nc|a :[@DV}"Bv44Ii5 ȫ3ZlDZ\G/w´/l\ZPMa 8n~_P_% [0jLϧ]M(OK;\TpZi ÈDU:Xj*NDH5nZ2,Of_7ae5dXd!*q֥CL{`/UTQk<6mi=yӈ١{h3MȰ4 عb@Zհ@ ;MSPyjб6PjG ¡v{&՞l˃XlsZwhoshk;uS*9 ({kJlsK̴3B[J١"T]0up$R6zR*O]f!C`@eCA_#md\YYzLL5JJ\JO\q&m~:)|vK 6ysɥ;XϾ5tG͞6&,>cy*>C B.&ɠv-璴_bL Rm&Աʱ S[@P$_JuG4y~^5' X18FY<\)mP$B 7mw|QE& PȄ˜r< ivIq KA)rr3{0'<28ϣSf`JnD4qKE7i(_2uҧ,L)OH$\O *j@崜s.ViM,<o'^;@zEb^5o޾C4I=s^Xa"ͫ4c~%LA^eja!:e!eo7ߜܼ=ק#"_0dZZq⧦TK5if%SKkl`q:LcIQ\:|[֬kyFhꝔi[`́3ąP5{?gH(9ߖ5Z"}la=mYŔ^޻Iqk=۲f]_79G؏\\۲f]j/_C݉ ό<긣OZu*.P揩11smYEa=quEZ*qCyQ[FɟsmYԗn^b]$oK g-챭Yf{۲f]^!y( Yz9DLCǶxbc䘬 wju`~E}$zb]ⅳcͱ&mzJ?ӊfy2ʫ]H׼ Qi_>iĜ*J=IjzI&MpqZW!z Xz Fp:T:xޚ ګ[9zY0zO7_LVWǣa(YU胆tT<,pzҋdGfKj2IK-[pаr{=B*iԍ*[!ϜpFoTIR" 8PNI"/$^g,ǜ B2^P ˢ&ßޙP,3Ϋu= w 2A47Yb[w@ay A>>R/ LQrx١ŒW#(H0HAq$d!3s4N Aq9APmmA-{5jEn3L0 w̧Ov[ʮ bp:n`F$;^t2z3 N@QC@14F+ťly];ptsvi@y=c&R'*reZ0ۏoBh;TVƋ_>0]=>^XrʄF`݃K}E__Ce |E6l`#Rg5vRb!*(^CL0<0\ LJ`Nabtzxq92j* Au:*ӝkV}$m5FWOi"9t E1{%'Pnօ GC%aXX8/K4)~qYgxDբ`d9NCĦW܆ j̐#6- zNα yE>~ '.:E35cq&zσB-q;hx`(bO5x>OLVfrؓr>2uXƯ_ܰ?O: ~˰';ÞAd՜Յ~}F$QvNӵD+>M,z2̏z,O\JL׸lgS v D ".3ޝ[qG/*| `\7a->ŏ7[d,b~OhJˢ|p0}XNED5D, ݎ.;}VZ'򍧱@Ϛt, \[OVUFq-{둉p00}oU Dw㒇נеa>@MÌPC)PMxj/mi wpyǁZnX9 {tW UyFYb6+^ik0p_v:QۃZ^$\>ij( uÇ[tD> !´`6,ǜ $שƶ6m+Hh.QFA^HUXþ(YN$$˾ilyYݪUlɳl>jY9GGy^&w6wCG q9G \h6`nmZ T%KVO|RC}$[?P&OuBDHkΤ3#"ɖŘAhw,┫:H&/:bp><ߙWw e-,bԖ=eU猆^Ku@ y|l%Ky8ү ㆐3l@ę|8>iR\]ߡb׻샘,qBKeϦ^D2'E5G'MVўj}JEVi.e 7O펮AΌ,Ggθ0(*czNEb7^8uhvJ)}\Qph?58O+K⾎hĿYj=haJEpN]}$2RˋJɓFH)vƑTSz_WŒ$HIU$l샲hJQJE~a5$?quTK-Q۔-L$y|su&)rI, ӵ1fsC Or}1ZXe㒚圴յ~c+7<5Mx˖jӋK}ZVF`$ju?c?溮7-~&F[R.ӵ>}q^V|#DŽwyIniK^^[1{w7]5V=$ ënϨOxª[ \22PJ5~eEDZV޹Z>3ŸNlK.w\+qz+eD  $9B[P, #ySIn念}ۮȑ,*#"#2C,7hƭ_ ][BU?`D޸9ޕd2k9{5;* pqWZ-"r CF=Ja9|;{r^^@OLT"9.^CΩ=.yyL ݎ *&7xiHp1t7Фrt̓tܗձ6{G^AY9T}Jx,a`o-C$P]{V%rڅ ԒI.^BvHcEhtw?|ÎɃ˽i ԷٵItl6kp\3v.qFeY&j'x>%&lMc܆}g~kr(ҒW︷QO1 Ѝ C4O`3{Mݽx;}Q':\8DI_Wݗ65&O[-WXM^;Q.SȏϏ"~K+5z'wOXȤ.Ɏ} x朮epQ2VeDT2ʯ,o#z4FPU;DORC׋w$V;*,9S}S-b=Y4&C$4VEfyGA {~N 8I=@ 0!-P1壋%CA0[݋ٵZkڷ::'jԉj # ͽ0v6+ vݙi(߼+ӵiCeE$rnxĠl"2Ӗ;m^˿ogt>k=Wo<2|s9d'K)͙H5X} 0gPNј]{t+EcWV>޺Qlx#JO+!;[㨓 Zѹ[_eS/6ee:F C_e;3ch:r0*-a[xQ[^h;,ab<ز')KЯ7^-m>\+k ͻA:)YtL)dddۺbM[rm,2xXmw(-ta\onƅ7f:ټ}QCC .CuSJ_8IavNJ:6ISaQuC7w]ƾC&i}6Azv}t`NaEF]:5ypoLب&Dztő<įz{׍;BdQ~ܛlRڦbyinl!)0Wī^m3FܰQ)eTU3JЁ>h ùe4J1XtMГ{OM _DLR#K0GvuiiXhYSwPᎳ-T#Ph\j#);1}TbLnX.j/^]ukCҢNRd;eZCWG#q# rYG^I;BܩxgRjii[XN,JF'1,o!#CȪxwS5ԘV_=|soKs3vRs| ܵf{ rgrL֛Y 1w5eiH0 TM\s, ]d`/(c>dn;Cњq+6aj_^0E<,R1as7kVk'3Ȣfc9:(黦3=8ūUoFE8GL5iԹ"(38=&*c#|}wxq! _Uc:}l5{g9ZNo]ltNTF79޻YZ F4J ɘzj䏪(qoZWJ0)uldd%*ʖ pW{L6Jxzvk6[啢|eiEN,@ro>q ^KzN.XoR'A}ta z"ZBnũ Onp&5u18fZ3vLLch#Y!uݿ0b*F)@\X;5@$*3GKqh?sX Jy'sPVs99yK[EY+pA.(D1v%G*5&̯r$;y}WUMh|KnD [wFh#Xkeg͕Ymry6o )q(np9{Es_"1y >Vo2pZ>ʁ" ]m.=ȭ?}go8#x"= /C:AĞ:R]]?z!cb7O c2q̂w6C{ybTtˆ0oۡvcv1v1VO"-;=([(u 9nIaëJ&qlMG:5yF,%p뱡Y3ecrCr/@50!+2Xձ*huj]aR+StZyBt[dt: N ?I e^Gx,=X4|a%*b1iS}JTb) 5s2$.p5t!0_ uΤ8ؒq,qm-a&ұggQӂNnZ`1#u70XrYc4:i Oa|SIV.sځE%_12!_B m8ߐ-Uٙf~{M!uD6 E'&*>T|8C?`" #/(vgUtKV`bjR="k,K{!/ A=8`:JW& ".d=0GbKq_GmJE8diGqWé=EA:Og#rc#:gtXn P <)Rͤ , ٺ3(b<"4+'s_+O썵m Qj$I cr7p1^/1bB,83ቤ'1Vo!f% I GKNpW@,Z% *E .}sVXQQ. 2RC*QmJ;gK\S6 4ޥbkN *O%(:9-@_nK3eÍ /=_RCʑЯ \ @(>ts&Gq+T,X{dJu ;5RLht#XqR%E=} N Fܖ)x}IN9 RʜO)l.8K@I99VLO/Nԑjcmr|Q\Y9,,Y0Tj1F(IZZ?R͜(O$?֧-_A$5-F!_liV ]ZQC|Ǔϖ+z(Sj?"Z\En49So$Xy8^ڧci\B|NnZSv\s<uTg,\a鴅Sq[G+T,bƕ# N&;L04!y%F2<$"k|wy9sל`t =|LkJk?CS2_/:ڢc*Q# Ne2j2_kk}/HZdQRH/*6:6yJWX?3M&hl8W/md7)߹i 3f`'eC:ה,Zq`魚oոM 69CG_ ~1K,~&]iJTU"aP.w.+gW>˗?s;^7 #Fc\!Hzky +5N+juDSt~|)K\g`xu#}cyM<31_n:aJF/tRvA_QO?Zg< Ь QR.Ϗ$wLufeW}"HtHbIEI)"=>}~دGi֏PU%WkU5 uEq H^̵!Tm4H{/3p٘@4'ֽ6DFǮ/Kv>EjLɏ0+2QJo1>n>)%oÇ3ѾPֶ>jqFf_Q@}ԦLf"!槭oN cg3M"֟ǭoL%3$Ҥo#ut ) K/ֵZOQ09*g!> !~iĻVD=GoޟFw kdZ+? A ʅhY=m^|\|ev'sΓYl`q)o3t>ΟڏPW 5y~eGPnP|"ȅDc~g&RAtX# IvX ww=jB;UX׍gRwuyL"(m WhL498X}y ~mq=ɩ_݈Lϛzt;3i?O[O߀^fA`L??oQӗ% 8:b:n_}^}Sx\B5 => W;{=& ȓlF^sWxK[!/B`.a-a@wIm`пZ3kL:`A\jRCFPﲊ VeVdS[gVy_^QD* AUڲN'k* ]؀eHVvigM0TC{T7is)GgzOuAqPD'=w滧O0K㣭I7m3؄}IE  &vxE0C2:;U/āޤi K/ !{N TCp}l~H(uxRG' K4ffNATO8<_^--!|=J0s4,zסZJNbH0@.Jc c0hgЬaQ߾G qD7 ~:PFind sV7C܈0DNxC>[x0-X#%Z=9k-j-[ץԜ"NEg nr,y d6Z=+pSh=H4Ek,x1Ejν򰯘aTѿ}~3g`5ܸ~oGOw1Gh7я|hI&CyzNTs?T,̽C5UhV[$QсQ(9kJ} P΂5胪f+Hۏx)xN[|wLJQTHe ]@Ӝ>e&nJiyxqJ G%a v`J%Ru>71@/$}O%˧/2*碋]* sA䰯)VFL9̡)V[,*`@^wgQKX(~ 8)QE^U-m=}yKv演^+%J*$H$A( a} BfD";lҔTh) PQP%)N ;nX})ɥ$$0QbўDߨd^Gpj C^߮77Pb1MF/c%(Tt*>ȏoArh$"iܼ$DNO? (uyM.& ^5`&qԱs[,a ;U@}q #ώg0r'Pj k"R1+;dZs^^Ow`#rh9𖸱g"`tq4? JrηҦQTJ5Ngto;iY1.EURT'wy4;!#j#n9)n!ŕ 擹VCkZku_BoZ`Z+nH|Ke%\g0:n.!=:=lXt zto-h|n{8\͜;aJ壤lfȮwЁxH]l60z&ֽ̀PQy`fc8PNsTn]}n`5B jxXs\iٴ_k#ki]3=[wpasZaWzk87:*2j֐լq|?/߿7ߡ7LxCu3Б䍈̀Ǚhoyy*:q2fasI[ RMb3ןϛvA6~,.]Yׯ߾_Ɂ&b'eL  :Q.uє[Lr, AVhOl8)c9X1;0Mu@@/{DX0vyxdE?Pgk&rS6m˧/k+r:ͅO?5$\fIM#ZtTM9qJ46`Kz(F~Yj{H'ECQ t(g,K$ӡtUG ZF0zqzw ՕOo/"[I Kz޻^Ndo;܇5 B6¥o'hF.Hg"!CNIEJ0|s^ҀDfY|IϏiI&NsX.t Ok3M:2{ MD^%%ƧT1v_wb- xA?vPtZ4ѿ,9>Z@e[}m<ʝ5` 8ee]OnS֫BwrЗT+tO=%D 4O:;%әTʠG2,պ&CUeRA>:&j>8ɹXC-0hRG.HoJ5I\I*K )\|UŃKbE]З!Xr(ԓV~me"V]8/J$adNyoqIVc(~GrpY@tǾXO Fn*O,1zO>=~zd~fx]:c]kF 4qXdva?_<"ͷa#|;~_˗O?;HyՠZӦR(7䀪nmڠwNh4eCw4mڠc> Gcg4_]51}v 6)*~')F -CI!I&/nNO4moGu/V:eCMFoљoznTVph<G-NݾYQ y%z|>u<釁'T?4,'~x~Nt]}ةsP[(q@=?x(S"ӒVK˛-X;rgs-'8kP[4CMEOEF/}i{.!JfMT:a iC]ԣo9sF%@فtwi# k (kA=d*AduSC쳷"e;|]w,3ի&[o1z TLgH6t(Y)e5yXn 8UM%6J`a r̃[ 7ddmpl.½KE/1tϠ4Sz5"-a S>N(&4: .όXjx /:~LFjo䱰ag'8ghQz]5zԎ3 6W.hɚbJ僋:J$\,ɧ EBXκ6:Gkŭ}XhYK*=f+"m{p= 4VΓUcSJɧOO|Ro`tRҋ@ mְ8`GkmBCJ?}[7ٿT#KZR ղTׂwZcG6$uc5O&O ;mQ.׏q"_/ׇ $_Xv )ӇϿ|O_o?}woϿ~/#ti{za}dŮꂱ kJ5)pWkPkԢ^ 9Z\R{-\k1ZK-kI- R+Z`祈`L{ZԢR Jѱ68Lm9WcמAѦ9fÑ=&H+yPfOnj{Ϩl`vLjIKV#G6DgsjnX+R{ހ.`\\0j\}Z ֵv%4kfChTCMOnpε!0lH32=O\\}p{y 7wEwsO|S\|yۯ맿iwO7Fo Ǜ|}6ëW\l޼??_?o_Z7?tˏ?[{Ot[{-ܼ{ӫ[A,JƯx_o~x_.oay?>x?Zis6Tpkv{j@eY-]LKZdAs5=z1WEbl/j}68,Mkga(~0v#d{)V,5BAp{imGK`?k:wl{٠[)LJLJ5$=١HtqiSmjNB/j׆B*J1 N]9yZA}#p{)F/AA󠂊 {hiФW|5$rb0V!R Ap\N&IOD̍e}?7 Qk^yͣUkMDm}GPX\,JgPA )_㬫([iͽ\R$ZEZAӭ!]!A64aBkibwA> _&x>B BNEBCڐo%.[@j^ڡ ۀ[Q䒨iuAKuJP@^U.uSD=љsAKU꒲aΰ|J;&J;R@e!ZpBfQ#%pEsƒBW:8}{JdMA A }0giXcI=,58ԫ$o.l1Vmk^7v]kM ;7rݜ3jbJ Zuk rI|=F EAkT`-1b@(Ƌ@]MikH3u.Ú]=7.M-.thD#/Ym=(IQ Znj-"|bCJ-F:<稻[`0lyQ:1!{6EZ"gxM} /&0\mM>&i ,ٸŤ#-h` m[qtVWdʐq8L5^/ΌEFq|/Q fKkNtLƅV\Po ^rrQ\ g*/|ztlO^"]lHv ϡPn25rCwf2@aA]XхPE<1X7j1 ^GҢ~vw W-%}9I7Qr一;f6\MrGFy!rFXqZ͘vk@v! 񾊊6bM "d3*e bܡ!0Zq7]RS8r` 06HkXmͭo fb^|`zu>\E6Hnhm Nn`=->6p"[ĦXW)"!Fui6o""t#.Y݀ҀjnCK7o0KēDph^:?_ӗǰO_o_/__?~?=>l8t@* r'2VH}T[Su[˅MJ.(گK)w\( f\ mgr_?CQ!xC+55 VȭT#J.rsƋZ2C/ =&U/sOT13r3 Ci3'*&W {CSy~%TS^)mpbt2N[YtH2J#bE)-^\yX V!Nۅ:V[tBJae) v7A,NN=JA  k-EZpd0۪32A  ol,ʨK)g7QV91QeDv[f+ns@F\Txk99z8<O[ VSppkwU=8wB@dx;J^uu8SB6*rZ2:چM.xep+yVslXVn,@*-#[RlM҃ϔMtʓWwUϢFu$.1<%R[n:\}B/\|TI ͚ v%?VtJE<,zǒR9 At$9 WL||x|){u6NHQ Q#pq@LDѪ"`W7W݌mcF~ZO(uB5!k)MfY΁U}bV[UG*7\d&,HU! Ḉ _ϿԪb(:(8Ņ Bn16v~M\k="M΂ռEmrvqJpd4: BRfm\Tcf5;Ղ&la;jHGh3E?3xx%qpS-D )Biʆ'[3u6iI5aFCFSypD 5)Z˙M;b> NRfdIQN*D#N!VG$2PD (@^oLhZۘi VjrEDic Pף"w΂msԪz d q;R/ ct݉C\R8Ӈow)-lv[4q^TBBi{y@V+$m ]RpD9=&U.ʞbvV{Q }_|1Q/Lj]2.GҰu#Xdn1d{KXC J1x_k}lW-M;6–I9q{ZYf;u oNhGJq]{RGM˴PWyc1mLQ(-Qn~ 1NmP rP7)i,B(i㥅dWA7 }HiE5aHK%t(|)vaG92v)3vB![D^Ʈi Bd)$7h/PH'Hr"*-x8~S-Hd1WsR=Y2goɾGpd{һ@*ӀݬSTNv5THBA|5VLз86.ժ((wL9b[*E)h!> e!W hJ;ltj2!MUd EL$^9)EAk"YFnۚy#;9*ĥ#kJgޫb;WQHg0Ei2Q{jTM*iڸMa6lHE 0ɥ^+J Ȁ(@X+a\!ƣVJh+..ka+pA+v|bͪ|TT RmUSdjb+x AhV,qjOV bIe( :VR O$tRz  ^ R-rIg@=s@2[aP䂃|~hjͮ 'oNx-6OT7J+yܔaZ_eh=X+}tdr,8% OHTύ!&nvFls_ Y-7Wn^홱u.j_Y|`F-$jӓĴaV%Z,li-;XL_鸏̘@ Xf4"fr<t%=㑄#q!XPZ)-nmq/\mDvAlXaOA׋kAO*6*i1qRE#iZJJ? ٲz9v$$C:"#LCJ:fAMp6k>TE;x M FjH2D~$L*BJn::ixU\'<$RsLj6'u`pv"fT%Mb)6Ysۓb@ 6K1=B3#kd=Xq';Z݁0vlK֠|(L󏨁GNobyO߶KQ\%bXV#7u֮>.w{Ӑm+^M vpl]+(UKf_pIH=m#F9XٔIU$PZ֘l A$Z%Jir8HrFx̹9z*LNCR11< IA 24-,4tkzDe⍋rtZGa,΁}΢j;a%jǼr&{z0m htۚnnJ!&6j`Ӧ6{hCh2ڎ9fr8m <|^fMd^l* 9P2X)eGVи--lGqTVDν9N3&t܊Gl/`szqtw?JL3,E:'h8a\sx!*E4uRh_4a]NI{i+#8XϹBY Gb}\ФGJ5I\&(  +0sj$^^= xz[J#(~u9f0A MU@M/9EA2JLȞ%GdK8=AE1 \Y\$>,1YtTfϦ&6h# 'ps爮Ί==)])/T&?]kыcYLyU"YdQPCu ?iuL`P9} })M`mh)qpv-i)pRXc\%M.7ەw?_+Dc.vpurX0EtFAĜ!@WZ!,B d4d T~o/KhCçLk$K zA>7/p|'8&9[$MT ,X\!X'GՍ)[ުݼ6Q)^9ܳ,2<5$~:ȡoVyM)ĭS mM$5~k[_NOZ/7-|MyqjSRN",8T~ Q{q nIl3wG#y,x<{nn! i"?bQ{ZE85BPWuN,#Q) #ʈ5!7k(iHj k|_bmŊ$'6 H>I;{3k z_w'«(1P*j1ZۢJ\ֻTy'ўJ9gQY<$Z:3k59;Zs$m|`T,Z@IQЅe}t\ z A"($"}m ֜vK,PJ2a=_w/z2>rщ|.AԤ%EjT7u]\75u12h~7sBžm![FPݵyAlLsDR}jI3wFM <.?jXl:;ݽr#FާW|%!{N#qXȑk]A)-iNF/ۜA/PNLׁؕތ?O-.J6j,1YL3A咰?Gis|Dɨ}HL( l'QX,We51dɪT&׉ B6glI%;e2|ʖ @ Aof'WI/G'ivyƮz' A0'8v0a3Ylp6\>rMU@{ZźY 3]2P[Яc0S(]$dpHie=NqH("goX^1[cSr⺒" gA s9Cɱ]^$37U@ΰ ꡪ1אQieErk4V0PVmKP/yǝxE+BY ѨE^oih\P iN6 QhhA/ t`ey:QUC q]=㉓ y((@w$4ৈL ¾Tɷ maD- Sc5WY޲q}{'5TRew|0/lCl[zͯHh#jԼn. 0{Rh&n%x$†`/‹t1ˍs+Cv@]G1qӹ^o?G 8*md"H4&M;0og(U4Rj JCrt@_J!RkxnU/rٵgy zrw`2SvTOٴ|ªU}[Ug* TJQkvK{x>5}T&.Ǘ+"h!uPS?՘ E PJV/2"KUv< t $bU)uA]Uy\^Ҵ Ƒt`yc^3 yykRUj{pk a=p|38JrddѐzsE5|7l㹇Շv Z8ok^Pb38f@yNʣJ qf\_xǝS3*0NL5V?R~~ᨏ8P!AS6Z #3rƭT-M 1M3EfPv!E_o e 7"YvF5EqLv:J$=iJ o{ΧCA0tPiL+lB;DKGH%΂ y]Ҭ`Gf؜ԖIk!]+o0pJ0Kx/mz+|wۦж&<-Ib.ɉ%m7¶Ҙ7г?7Ro5YG$ĖQK+#)ҾJ@dx)j3nRP-UշPPO].mu vP@P*Ҏ5[_M?Uy,Pl=c14ㄖ Bx)͒mdR}ڛ^p1$^^kr~.p#!JB;ݝ^$7j(D! BV/~ߐ}6h;|hnK8)5ck9 vo^ȎSLftRMbb>ڮ]ǒ]/:>DQ*8{rG/0C{Wz9m`VTEɍ\Sn@E{ȭ&8:6qڰC+!{9e0Gt[=>_{WKWJ}Ive.wQ##z!txo 퉤>~3 y'P8m銥%>hec<ԻxZ9m)sw"cϳ_^>쪰LM{Ĺi՞+yGKlu9SySz#MHv9wXںs`F68ܖں8wpgu ~rL4ZeF,:5!&zwor9M'.ڼ[gyֿ,bw[%Wb1YrN{1ґde!ݣ6ڳZYbh!YVUꍠKf3/{h]B(k &ʟnAyGRe )etf9tn e rEɪPni}} +#) [LnOv%]nPO;,R?y0iM'Z0?F3UX$9_왍}!+CG%+fRfZ ݣ^?haGv2c3Oqy(t[r9OR-{)O*RѢH/i7d_r8ˋ9G\u̍/JP * "wf޶UvhVH_? ퟆQ{FX:?Fа*2Ֆ Z*RXAyv;u`=oŪ1 ]YW%VB7МsVOw;}nO-ĆkXnVWt,Ֆ˹oEћI9+Pc; vGjjP~P;z>֣d_`2Ѭm)ګFS[ؖ?ځ^-Zp E*m[NYo,q h8hRʊ+pG^3:srA|m5IFwDtpwM7S!/jt@f{JI$>ŬLo*1<_wR/SE'3B"U.?5SVvUcbnv9BR)ʪduHJ1zuLy  T8sO5O[dz%F%Ry+:J f3ZtYIN[6,,K/WLlq;V$#jorsSܾh /xZ)}rbkd}cLRsZ|@Q{]n&́2 BK Gin 8};ۺ{v̲=E/..fE+πG&֨oݨlR2$D }fCw ĸ{~'EI0}qM7ɍ4X=awDl_)~"ERU'[=a+T4:㎲{Ģy{8|qq?&9m٭.s#'Z {߾ bt_ hs rlJJ #{X זJ>rSް:N,Ow8<4 X.-nP쫂vrfbVP'`&}%DӝZF_ݘ7M|E+'_9&Uș}O|9>lOeMb#؈O&rZ!q[3tS $ bi8R4߲pK+2d+Y&GEbL(;%}e,zhZx5J`V'ZM_ur% xfy5L'S&cLIJL'ӉKV )ND')^,]ʼՑEu2i,e*7.QebO5..;i󼰺AwboWDt$;(O$Q .XZs'=Ph*9(N{ʥӷw]ϊb" \lP!ɵbu&4\f7敊CG4I߇RP8GH S .&7U-%|WN9AQ!a NS9q/BNwgJ2.0~N>dWLduiil M74;W!7ǒ&jo.j:H?}5q~{B)ֺ/~bCvN3b m؀-n=KFX):nmV<"22FDD{#/x_Wh7Kz̖]s-$,|ݲAG6%h7a3Mj#IިkůsMC-+1ѶqںvVWP_~std6pc+b\":_acJZ9_8 KΑ )e\Fko %ЦF 5aGݖD6H<`~qcL GȾTog&$hKb',ۨtnI&6Ħ}o0p=%Pf))$7]BpҐIUзz7kT-uZ"u9&l> [Mʍ@t(ܓ6Ώ->пWT [e 5 !8o8S2B-WkZh^!`4/}.WHd4]`o&sQB09quCOg(9v5S݀_F,6[`UIwۈ|षv6=Ǐ?_ENHzWswxrp4l¬_DG 6 Gއ?CYRPc;$(??WU=W:B=i^,Fa%6zӺ)OH `cmwat=ԩ Ժ⃌֦ hmP>1uL`8P v勣R5 K.͛1_kw qr˾~v2U9,~kSTbUfOcjT;r_KJ5iԋٹi(K^Np\ m 7kІz^sq\ܺ|u\嫣C-iJzQg;TxmØ\NeRsq_ T!2#uTh.#펪UCj}h.|teub"Ih5HO>Re#nr43x`d@?"U!ҬA t\%=w(ȍ %0eFZ.eWSDJ]qy4YۇXjlF"lJVk0`'n25n-i]J4/d]R-[VT JtlF rc7q!_D]],AIշD}b!![WXNpFYq%OTRyZ*C??bķ%o ]Ajh^o3|ăun-']G$GoTpv8\;Tϲ/דZx})t3>UTh<{(v滃]JϹy 8q5T_z-dþvOvE&v0e"Cg0&<3JsFw!-+b=+~;yaHZ,!x6>g*Tz/ DGaUGDz B(EQ zGι5cD |nR=j8zj0-ymM4[yR4&1R2ZBLu%DgVg+>^JG>T."*p:05 ֔[g4HD<{KxBk>:I}nj5nF%~!$+uIui#M㝵j(wf2$Y| kQeoO7R=!s*[5~PŚݱ)ؐAHt%s5XE+bSLCŇ,UUr |"j(Χq?vq-݂c:D(0Vc?0"B1b㖹;bff:wIn!i6|Г d~ֆ$6$r|aި4OP]찻#(B,ݪvsi~^ܵiբ%??OT+oWU<`# BiʼQd<Έɞ0T$Uh<+EGY*A!Ls )m'14rucoqTpT Ws"VYòv"-w)26/C 9-*rZaj,p*h8<:; qL;Zؔ @O'Cj66FJ ]~铅_ Ar%Zu4E[ά}0;]< >GɵT> j~45+hLmAm5Dc-{חnEvI5n|ImnC(i|і[dZu`\Q}'ym|ԒM3=D랆P IǏ_ޫCGVW˖pTEO;߱5i‚xV&K>!1Hz=] aL4oIN4Yc،@3Ε'4PH OJSr`Gož=R6Hټax}hY [0xX]V[{3ް庘|< 7`b傞7R 5MENoZ27$2;RЗዬJͤqhxJona&=+,{vQ88XI'.BC,F[mo<䲽~OS# ;o\] Jۛo_]e0W?^|>/`٥m߾ ]t˸}wuuwחI?ܽ㫇=ܽ}}A'Ŕkq5"XĚdޕ4es0R lX|3Ն>H$]IT&m-NRgrX+k*#MKG}ԈeO1hWMdQi1Jũh_3b׊]:HStNRCU:Zfpl=g<43C5 y(Q=!f#Y3 D7 |&G[@er QIj-!a61<\==XUG$;73O% dI"uoce:[mRG6!`̴[4My(7]zdP0TMtꔓЈ͢S!4:euS3dVSnwN>oR]dr5JZsybĨ]kY 礎$և J2ll$۸4YwFOydť"_x<}+P|*ϝwOa@ <9+2d0yod%UtEs(ј%PA9aQr,9T 9,YCcL9!A0IdE0 `bh]I?k;'9N Ga&8} M$xLzlBXġ]i\c YH $T R4a&]V9ڤGĹ.N!y8U9Zv+z0!V\FS̈́I,VV uQΎJ|wcRqj-A&b O8cW-fd_$]ţ#z(ge_OnTʁ`a ˈΝ#1qΝwI2+![*zňŚ2|āh>b^VL=a72xG DDyѥK\b3ƎS乩i"]_}϶␧#2(AWQ(z8iTDŽyty;=cgjEvl`'-!㮈Q|2CE-{,M&OIt$'H7=Uȣ=U+pbZl➣i^:k\{(d%y5dޓOnk-hP6/ kbܤtoL7H`hC5y70Ak " P_][Mr:m,`$#vDW.: 3zxt.)gZEo(/Gq@VHpo7o^y}%r}i)O?$9'eYGO4iVg#/MzbWΩeORS; /X1^wm0cBYɃc EQ{<0r4!yʊooxI4ԕЦl(˚/ >j{W mGε+sխ99/゗ç-[kέT$tDd%Ep,q Dәfb}~+1;w|YɃc QvKQW/@aL%x+~'m:gcOwÕ 05NamZ7m:l\Lw2)K$T=_ΑĩJY~M~L?[G(R^>3iwڽ{=K'4s{!6i=͡r(3[3Ϲn-Fk͙qB=?V!1Q:;jkL7+MJ}̣Fu7@T]ym%EBt,VXybsZ4PVtFY=-4hy]V0wLT: Vt_=rF/<$&hfl VjC= (YN1ʵc/ $iC&6|'ێG_R,a~<DU4Љv+!:dxNZ==7i)4!:P[@".;gf t!F#X? h;"X!J)m7 fG5a=ھ5eiO`/Dm#{4p/{b+2MLKT Kmo>]{aMَtH[˛i8Rj6Yّ ͟ѕ8^{m]='ShtX7@l,!-oMaP[~{Lu/xz o=MK>UĽOd-_gg׶^j)4b*ZzLdLdh3\K.LdݘWGg'~m2=D(W%zPZ|q|nᵫ_S˰b S)cTav`޵[icqt\>*צfr./9¦LcfQWGWWd |hOyHF7샮R5J~{ˬj@T;F 0T6Mզ@D#27zkj`/!aW9m;޳skhmyEܬڢYԹS3>ƹlThzUGQ$n WBO2Zr`!)Odž{jbv4vZd#y"<$Uޢ8sS6QuB@^ e6N sii),%4n3N)V?՗1(h&\G* 9$~ iΥv݉hg2+TWsgԆD$gКMe)r0mH 8p- Y4$;3-UHkN[1䡱oMϖi|x-2Xa$@lfYmPjWy)v $\0Ӵ׶+M]Ch;Ʋ9جl+߾@_ Y52.{5s)nXㅚ5En_Ӑ9 G;}]j$м6w 'myNRhQF"P4=3&7W1-xXrq.`4ԦlѢYXY o 5fD6&ߙNHO/sGJ;jeZ'TFC#3S}0ھ_Nv5X%ɜjnz q3:[__׬ʓHًZnԢ'R ktjaʩ4%m44{ANm8|P / zvK>=Q)ܳ5Dw%ExoҬZ }Rr4&6裐v/hƔ}j(يR>I5䣴bBmB1>Zci–"7eݹn z5J8Cc>N `9Zۆ~UXa8Z3f .m/rԢuȳҌ,P~|CKɬ!:I~{rwʹ_p5ѷ6@|`^eMGA~ٲZ]o!hH8zM4xɪKvj ][ ]q,q\l l$0.ik~;`wOLܿ,Zlޔaޛ#hGwÑ]P<%hb)m%Zc۵gwhz}7vN w8[ K--蝣A"/+.cflBSxNȀ '$;3f"ptzHjFOvqn4zYs|sÏtkq1Ҩwٶx1 jR p!} њK #|d9Nrb۠>\G{ IU<ΐt;caxp +dxJQș҈=trb)ܬ9J=&s Jxe6y/zF X~P;yӚ Glsӥ+>&ĸlwTmm2  OBXS`Cs% -ަqn8&Oۏ>闲4%c=[ g5 (U*rۿ'^MU*Mk(x %YͻYe~Щ(k뷟;35B<@W!2G8z! ^/ d^Bv3'=+DtV(#'.Ȣy~]0rɕ\%s*+I~[5!.wD]npd$;qFAPs#s'dÒ1TzI gM{98(d ݼO7D kyd[&]:+&`m%Ds%}:!@}꽻=ԼrA h|I ; | &X-a_Bz!B)9yB/gؔ)xPk5NMU5V+ߠ@-O,DJ R k;e`CLiB32nKT&H ǰ] ٚ5ie/Ÿ ,sS= 6&I^h|3 &PWQ sXB:GV^2">g; :ztG`ǐX|cYj5&q@7Ylގ4ߙyD$9vт Ndî^GE_ a\z5_+5A0ߕờ܉S(g:ϲ[.y&_Bv7~C-1ZFyJ\Woh^>S?NadD>̘H\O0cE9Z^ mYg@ɘ? L<!8s҉͸: =o&7t Y4I^ڋXjJ qR=ą寱=.ӄu68N_"\-]r\9,*~qGt8W ,Cơz7bedǧ6(SuM10i6a zƴB ^)ӳh@~$)R՞ToCеzˆ_E]24}S3 ' P\) df>1>wgdapTc,HoK9~f; wHױ8T N'wͷ˚EFٕ j_kza$ r.=͜qZWu5x1:8.ܱlQ0%Q4*/\vXld#hb륺42&j]׉@^UPapyV_44:[ț*anV'[A]?A'm5NFp *ޚqI(}K^-f:N' y^၊kp`;PJuH›Q=`=#"Ǩ$̲> ŸU{ar=VZhBVc!wmշ-U(U{ g>"p^ύkdMe֨ǸוWبSq XyadngԝtG; CuWh߅I!ŤH}" pA3R͜ (K5q, f#q3.DyzyO?[wߗp޾7%,o5q+x*^q`๝~MZvhrLY3@ECqjV."8[ Kx93;m9o+ȡ-G33/'0zQ;L:cݝzeO=9[:l߮=4 x)"Jy^$KN`vA9y9&ԑՃ;A@yW*9[XMo^(;CU<$w&ޑ׳9L/MC`Z񗟭ln2L!#Lld`oZjx7H"$7tBv<:AjYE -tRG. Jw58ATI{GJSIUI.^;}Z@@C$HݻzF=7 ø5^ ϩ1.6מeaWځC_!_tF#s}O??-\27s>1vvŻX4nO2V]{mz_ޓ Z}2&zNźٝP&}*W@2;'z:cdC9]v;E:A<\7?T'i vAXoӋk] n33ll!w37)4JAϕ1;~39;δDژF6Fݖ#R2Eҕm\br 7o?@R,OϜ <|wg_ǿJwIEjN"*~%NrWJR?BCkӄV i' (A:de $dș~?WL%y㐑RrlGc$9$#Aa*p3~ ˴{P|i&ANC=&`PP蜗p&ށt'G(S"I%~xIJNV:Sw05EJ#6U-@I^=~Wɻ8:n27KyqE<'乃$Z9̧HtҢN|{<T_C/]'{oD&yҝ=~ W~=!N`CխQGʮNo`LO=D5Fy5`+V{ٕ%؍x. eY=8gK6ADy D{ eX(,ltG7x VuJ*p$9";$%w:M7ᝂ6f;_S]Mιޚ^{IC ?Hz $]/˺52L}N۟g eqr-֢#xUq4I*/YݐD]:J:A@,:ʳEiQsM(]T ߠ4 |`)} ݦ" -L%QsHLyU}^~)fK>8vr$8<ܳ$ r5 +y@;9 ά?S8%@9(kܼ.bǰs팏 T3le$@%Ȑ hθ}y%/$NEekLOV*;O>})k,k-_'' 9YP.ir;$r#u,w"<ԚA9T@FiAv .,&ޗ!srY}X²I 9 >93ԑET3*G*baE4uD |Q5Jbw2V;Ns‚.rMXB"i [*x5502`tf%= }0wB(Bu{g^/Luw .vL>Z02vի9މb `ϕ7`n-9!w@r JB}cٮn/&;/j{ebxdü! Lpmͳoq5 sRͥDb[/wv-ɪ2\J$VO;mMo2%K3KUAH"}\N[C~ 뙫Z;D);A7Q (!Kl;,HϨk7f+W7WX(>{N H~2; G Ε387 ݔvލ)<%DJOSr]=GA/[?/zpd򊶐#q[N'FH}l׌Ǟ p&HZ_~,nvUQ })Q7I{S'fv&{32[Tx P.'IɆ7MgU( սE"%;%W=D)JvCZ˖JC_̗W@D0g7%'qJBY L{`rzq(;TBn۬iq-J,( Ȯ=+4әhsZ>hPa:e[B0-<21(3"{]`oB-@ܢA9t0^vh*t#Ȼ4ɮD9jNaV_e-&xvs(T;h8pXɔkQ7+APec5Ƽպ[m[8hoK <])ŧ<Ϲ9}X9_Prtl ]8:σϠ#x]QꊊO_1Uu hWM퓋mJpホryJ( tU^VU'(ZTm OwX ͠j;~F6K)Y"~E6u5#Hz'*l 6iP&Mg7o8%~;iM*i"P3"`S.mj{{zYr*'t17x|q2˗J3 {wV=L:AuNΰ!bxꃡ 僶Ee  {!?e&e̙e\?xd&!q S˻ڃӵw\G8` —Yi欆&*߹Skk=$o@r5˕;GU=j3~=5{/[9!`fb|qrE+}K8t+Q-B/!WO$.utGWm%!e=:KNۏ=. o D\p"ek$5Dղ4셒iA/ټyK:K4HT1]h?N 腆zW}8QwqXȝ$( q y~]= qrX\YF /0+jn_Ѕ0fF_M_gM;VfѥIW7٫gz@K*Ȥd3cgD&#>;RA#&&)(ódV}}MñA3_8 T&퉬mY#č.&#-zjA0DcIevݎwK =J?ߢx{\)UwJ.Q) Jd;߻?Ju:kiL=]__R[_NBD ɴ~|S3V!x(Iy52s. JZy[[~5.fu.Hoo r l]~UKN$`썝ӷ?|K0:/&rECqޣӁ@/Q"ƔTHfI3%II;h09B1I;?̵F!L*GyICz6/N4G;/0@vOa6k;:R![$J\[~ w sCI,Y"I>ƒX8iT8ڪs$٣%99' $˘,l,yH恓L+œKl]NJŘt67d`1K 턻ő3 Z?Ӵz@,$ߙk89IlĘ8$w )]ۉ'{f*$VN8vE_Y@?V&v_Z^T8Ts;T Lx_Plו8oȕEȪB@!76d4!t&p!\^1/dɼІv Ȉ, #Oju,p%J/'Eˬ0/ɡ.߱.~߬FLDwx!gjW")v.3r0pkޡ&x 2 ' 泡n$9sN|RKxSHZg檊 fDp9:Nc^Q8(.ׇn,'뾎Y#;PIEQy_7qW%֝=)iM1Uq_L4*|^=+ERM``$ >| .tt=^-A~b߈5C7\!FŎfZc-.WU?` !~=iJ/ϒʩ[vȠQ@3ʒ.vuciL ̾KY: Tpyqu+UrU-d2eJgA' u Yzqy dg;,\-uhj6AĪ$%%X<&UI&A_2e^jf-!Ѹv0 `6VOΩ=9'J|P:YcmX|l΄$WC9tiCCYVjjYZ&P_E'kQE(j*`hU`O'7N|T5Б|'ίG3.+QAȉK`? ˉTuљ F@s@@Aܩ*8&;(;9bJ c΃B;`޶;tu\eG u$vxM+nt1v ` Q0^BLN5\Pvu;AǞ\p-^@vivrnzQ 6M9Ű6fxEGH5y]C'cueD=/pث )wzVO 9YKA> moh+ti7T\nE8TA=Oryr/oI L6lg/_~?l?~?~N y&8pG[9¨@>(VgF8P:88{kwpuz$]AF3:uCo wpz˽znJU΢q*9ZVc]Qc: g>Wuk{&:V݇s nH(z@3oOHN8tB.ݻ꿺vx$͖rDn>hpˇ:֏<+5UIks3 U0qA߰:'W\~2=vrHJC5" AgA"u78UyN(4hɖqM/)=Yp~?4vyMNn`.ֻF@,o %BŐyMNLDIt#ОbY<?}/O~x\?y?}xwq_ϻwz{_Ûo¤ J"B RR=F;T9'R) %k p' rbFa*y #PI`!idc1CH$$l-HHl՘۰2I"xslLTj̉AXGPaٖR1@ cc U.Q73[ 2aW2AeMq90yN.Kw Y -!kCQ@N-OrǾhO ahCMBƑ Hzxa7^{0c=(28q:K愮$P(<#9y EvTT0>}v(h{0{2ovwo_D߾ MZp?㟏e`pwwzzwݏC}_}?~绿?O߿9X ߿C{_`LJ$"dp|JБ#?"_l^bb[G}$0h+.ǤΗ(/^ u/^_ؒ ;N{KiG=&iaS=`s9"])Lpd K@$I撴d$%6L, &ܐ$->/q?CZsr\RP5a[R*eK ;*Y 3]ʈÄk[=$M8LRSX_۳2̹!~4p!K;$Qr '#q0gĀ=,NE0 LexBL .K 'K" ȧlp &@˰tCSαEh94R&D8W!e5lHZtr'$< b;۸J@K\‰ ƄGX`X(Y~%n"FS$bԯ2_q % T(1iI$nG!%0K_,ݦ'ԖtY~5lHDdm6U*V*mtpaqzZJs2 4dYt/Q*QmU\cdW+cDT k=nw\dypbJT:& L҉A1b\'h+ ]JtGpD.LyqBt*5Rb2NJrv Z+:5XN^#d4Ε•/kR։P74dS/f)ø,LR(%QZh;)9,qtʡkRMOع9hO"2Vo(#el+8C#3c~)[(ĈH,LpAk W[)H|A &Dڊ^HM`(;*=@*d *)Qr@۽ۑM(J[DS38}&O3&e-3O­Ii`RK7yd79E$)$`t-(u'_B~i=:VM4ffϭvR6;cSJL)(̑+w:6k70UjnsQY[5}CgAbhiMCYlvԝB1f(14as0y衙<גNJ b~i HKg1.u'[pxs8kb@% nr2暭æhBlBS4@Pm].׎yt"%͈؊H[H>!~!Z5c39"PuwPe tp+Orvʼn<_ΉD)W!Ky ȟ=KqrOkhr hXfc9׿/ IݴoK7%8P-zj̼l ,cJYX+MEfRE)6C)zwPwSg xDne֔GGykȶR՜ζ]g ;䱔2%yu'˰z:s1beE\hA7!A7".^*%FtKey4UȭBl+cnnX$@,&n)5aĿ37Æp0ܠ%Ѧ(T0]gt/.k{t0O{Y6`fi,9IzdOKTF1hTTU.I/9</& ~^*/kxjOC4ȕ-/@X }JvbMP&/Է08cZ2 ;&o$pl%%׎pU&׫hej+)e% bNH+_<'tٮ0ۚ` Oé3yyM2|]%v7ހs"\W)+^Z`evl_\]\Ӈ21x<4<~f7OCKXfe95`\4і4m1m 01$eU#Vd`\X\|De ǐK>|zw[l]T7~zزzɳzԿ~o~/o?ݾ?/7?~/ӻ)ᏻFďjū1Q C JLU6$~JQ6c?uQǷp z Q[q99LĿ_'E49|nyjߣy4w4BT.hY 9*qMVf.: w߰)ɦB_@w\>/x&xa^~p }j) $3fRIv tHӁ0,tӲm?\Tg?|H?^JΙo /ǟook/l/!{w]WAJHndP1p&+޴^I"JOab& @ym4 L[2Do W>+x>~~|r_>~㻿KZ^j&DNT p&>|z ,8Nhmِ Elꢆ[ 2Oo}!W;V m-~5zF۟/b!lb@d]8,ňCGnas=A?'s>Q̝OTM$phQ[{zJ58-&ҖX7$1_];66@8` $JLl'~˸ŕmj|TeݷRBs(f~۸m.㓨R}[i4iͫܶN}e k{)$oc]j/E"nv5)&FmluH"CE*V|x>}hEzkq屵qҳ'mp>ǑP-FE;zO-T@Avkr#}}|wOJ,pR9Q^5UFr4>ߌSiFaSـ7oo6Ulљ "HXJ{K>e Tي Rehs2 d Tm6mA8[M?|neV{YR-x*ׂo5z`XGS]o /z*}CxI}4`I-5 gA.}R JPewX| 6x KzA>0hO% @(mjkUʒp & 3 6aJv5akMIUNeZ޼%kfgM- ToY4TbfNS t IGqݛ!$C˘HC{\CQTlT/#Evx*H_;8A HZѱJNYIE>Jn061Dl`>@}Au$Zо@=:~Vsѽ%%8Zf*U)^fwkzאu`>cb9ܺf[M1hFa1 @> d`*E%ix@oV3@C'cXx OBcԀ|QZnj*8ld(6NuLNj;$-i%B.XX_޽|x)\o\"2q3z/̵1"eT+rN1vJSexO3f5˨,]u)-,sNh P]E|zb+$B3Ug~~Sɔ]W8 MB"1M[i ?\@R\y]UIol{HDXy>cqŐ}#潸wnr,yW)Wzi)C_{1CC1eMChvA`i*p*•=Às$x 00t8cJEӼ,6SLw[6C18Ԅ'ؖO9޴pɣp%[x,*oLYj[ɺolU$lˢ7D=`X&8 փ_ 6eY^AT7!JZW+ xc +"SzMszehyr63?lI: u8d°W<cx g!;33F~ۦpzeHk~oFKQ{Mj^ $no,4-F 5L;ѐ-^"Gi@N%KSH%譚dW{f4ShA5W/Rg&R91,%v5o7ڨNI 7[qxAsuKΈt1[hw@j{\:0)2L#w;Θ^@NwsMo/r1| =P冨poִgA h!Fn wI !RF'.3H_g.|CwX/٢t :&lf ;$l-0h՟ѷvK?_,iLӮ@]+tz?gȆ3?͎~FpWJ< [6 }}@s=:ˮs:UK xY%ZTӾ.n'ʕ"ܖj44{ g89o^pDVF<@Oiϙpe5lTlUvTi=eqȹlmW䦭h!'ghӓl|0SXkjm7n?y9l5SM5m~.=jtybdC6?C<[UF3cZfNm[Me>@q+(w_Ai&eg2U/&J >v5D%ditwlz {璊vwwx8x{.15[Ff}ma~XB|HCN iYĝ Pڭ."׮r]$hOiulʉ 5'Xk֫Ox&IF|Gk0>մnBȽV}}lȉų9duMA [Ȝ PM-uM]4_Bj+_ftYf[Y(֧:ޒ3퀻V^l +C<9D"^jh! ds">wm1tx4;kܦX9`#!%Gr6U 0W7"?tE:8bj8K*]Πg 3ԜT^<+<5_sprlt*Y߄.ZBҚ.eG{>҇'ufpySz\"/Z>t}a.KVX0ǚĊ=>2$])b1&ƿN1 #:ٵ2tv6r=uSC$P(z_`ZȵZʖĭ+he"f~"`7k$ur\ VdI2]MD [{32դn <ٵ9ÍM>RwZQS`A-n4hJ'R+8)iqзMj#GlwC2r(fAO4 -Nd%< 1и)t6#KW\+}cӄ&%С{06w"B9sF9nEPݗe>ZO}BEn-B]0S: ޱi_fV;akB1#^se-GV̓v#x[cob-O2k AbPeV)Y,טƸ=I0:-m,a3+Dj --{-h`5ێ#Xm4HڠK&򍄎{8Ebpe_ҥUH)XiND $.}c# yjK5qҌ(CC7 QmvL"~^܎#= ,49] A>9{]tq ۣV|?R}0hζ)ޭ9H [zh"SV`aC;sUhכܕ"_tIhY8dp7LVfxMC0S3fah0P UW:}R& 7EfH'DB nT0S"p8kYf=ap„]xd'$ϫK[jPȤ|Rs+oB$ Uj&hA{@^'HRuT1@7+~:G5$Ԅ@n՘J}=6H2FfЅgře\囯#{$$$淣" s$=&*q?|(Acqj$v(N@r ! ?΅{yRr[7JN ⪮sqSDwѱC?'o-ץtA]Bw-v`CR4b)<' -R)6Q3qpJI`q7kͽSW9~*N*Mi`IP`YFM)EI .|S#|EvnR650T_z(~(ng^'=C)ngD<8\A jM Տgj"55zdhpzV@Оm4ieߝ"UP >}8)KR2{BU\iLZny@QMFkS]Bit뮯N7g9{U 4sM8˼\d%1 Jul*>GP_̲e;vƹcx[1|tTl(~64J^pTLȓ O}S@} `BثMp+bluSB>dZ?܆/ $z@!2X/2dZڳ Bt;.]V 8Z"Ժ؅Zż?ϛg;| xVQ0S)ՙ }#ZZq\w]ö63Fa-vhN'TX1x W5rպzwa$ZCin姟 ZK/?{Aڍ| jx᝟M nB]olOSTƇ=vë"yPᷯ7៿JZ'6QiOWԼoQ6f_NM/E3*m+%K$du] bt/E\QU\'^:ؕRԡ-!2U:䌬fXLWZ%s52i{NSvf/Eo՟:pus:Gx<21~ϘS\KQ>GrZV8 J%q `%ܗμ-S',.ώ|,r; } ,'9.%*I6?Hݽή?RI:$wC4M #vvM$9m$nIP/.sƱKnOpRE;ycTjT)RN cߧ k x~jav'[;=KRܖƀQFrR_wDKiI[K jΩǑRlx~w>8xc?:ģ(B_wEI-~$I I$Ե s1lקo-b\#Y!1 hVM4&6MDIkĚIJFӴyu"NC8 #OUYέ[؏dOf{Dw*{ ͕BM(c7kN(5 >p R/W0I$r iSoƑkiO'猎"#'l})dHєDImcc, 9N n wTJOOhTTR6UXmyj:5ʒ*9#Y*kWXBш qJMd|HM!ƩUMB ry< >y,J9UEɀ[$*5D'ﯪNa|[QR+9505*Hw%$o%M9`=ʃ]$M]--iRd?sR$>cwc''u^=5'ZztqK݂HYY4F#@f ,f<t(Qgo0\Hstp%XΩvK;Sίqhrˤ1^7Cاnz2צ;|Ek:0K]F)ɫ5 S%(^ЋH C1:jͩVl4Xu"x0klMkW E;Rz]4(nYSd:\OJ0LK}ös"QLj:f-rAApL&]6LLSm՝qԬ1' {qj]nɬ4Ur1Vח׷fO%Wzw+\>h|U+{xOl_u?Ω{2d#rrieڹfM&Kh'# n>-7nf?spkHL̓D0cs9c_)1ٓ*-Ӧi° i:.zq-k$% /UXv[uϋN̒ -AuVNO!YgoU퉍`Sbd y ̛SrԦʾ@LA}K}NVI/aY>/Fڥ$2ɚ!Pr4 ݔrPrAq;Q /r,pP, 8gyЭu~lF;MU'n !# 2BR܀y[Hl'h-E v}n rmQ?Y];t{ssm"E q@];Wc;u!]'҅Q Z_>i}Q}b cv{XOP >ww͙䮤rH~ c*AY*7`ȟ܈d{Hyc8T:?4b3@*֊,M}aXʤj%o ї4{om@ ˘(k$iu[qʺoPN/mHƩa[0cݪ2 SCI'DV7a]DX!X3|;.Gտ𡃩5+lcǀM"E0U/b#4>NUjұU~l3 HD =dc]:-iuUͥG5oF{-N`)JXu'ϩ0*8 @CfvBp~0 a.*.t8Nj̑ U xJRU?|YgZCbl5eRɏ^p KG(h|@ٗ^-|OsQZ3LdI?#Z=UN ;QE y 5k ]V3XԞ+e[; -ԾC0. TU+̢g>fRm#z`ޖꑖR[HzN 'aZVH1Ny:C?ovKuN͇sP!8#yA\܉n%fxB(L/S͜hʥT(I$I6׆'ȟQGjk؋j6j!Tma;CFkTԼnpqSXWjxQl5ꆘu5b*Jg423OD@{e`O,%G;r)IuvkV5ӇΪ6Str[6dʲ#K0o]5ޟZ,X_|DN'' RdvRǙT0u"9J3tb4Z S[!BjW>i5F4]:Vd8C)Wzە§k'^bm{UpE%'W$OR~tEήơYzДbRT?`#\V#l}ߧkۻܳ㶀:lYX[+E>hEWu$1K{YOJEYm3p'k2ܗG)o?Z.Z8a0CgY͎YZ@vuoȾ杷5C9MxгVފV)Yy0|tx?ޥ覹Ra!5n#<=q]=׋6\b#[~ywa6Au*#38H^yL!d;ud=Ծpyr/fijWagsM4O"%.>)cU.C}2sܕ{$}̺TSC%8|̶XwDB!YhbI euw8hk?EQ.쇢!v2]|YY|T, \ɩ(^;RE}+ODy5XJ^Δ.;sݤ')3cB)ɒ"OiץئLrmmoyj]OV~.0|k~}خsIlޢ2}+bbk!'QהMWȂ–3,&9s @o7H{CvJ@+ei&L2]nhYr8)|\3,ۅS|. O\}ҧMqύ|A l]RH2.n$QCKiJK[AB/:d QWZ( br[K$?(( *eY]ݳLGSrI|hU_)SwW+V1"X aۉ0GaBiB;(-6+,hVi"fX!L#{Ěi Rʷo_TT;3uLIUS%7,i Î0h0w~ve֦E0|(2 /fgx-5+~`'0 Lj/ƚCaRm,Ňn Hy"1iá S~wf^]FXTf;gE}\7W;TbB6p.PVOK}ach3TLX{Ycܥag[syj~ c][[BxI,MnF6hJcFĞpY }(ntxYlE[՚BVt)a_¨F; Xp8,zI A%FݱG Fr?QjdVxmKKnaEFp9=GSYӳejhf/Jd_ I 2TvvT.D=.BCJE %E<sR tY(֓&5p6POdb xKfe|1mD uv;.91I/%}K(ί~na9]G,K#4x^.ʳC?#Yu)Ok>I~ [dc/_ۯ{.zPbruu.d{_HPaTShv]|ȽS~zގ5 RfbLGipԱg[R{ Եke;BFT:UkrL^~=dǑI|Y>ߓU]Q8h5LΉ2W]({$yqrQ&+kq?xMB: 'Yv\4$Ij}1+^%jN>),}L 1~Zļ|Qr2|QmpUE郅"D 'ڏȁ,KEe(jB4q~ {ՎKo_L4iw|!0?۔8feChJj(RLS"GdItԷŽsbw!=wAחoooo/h'Q*P%DhsBz\e.=;**U*&|[Cd},..6.æ'wwN!b |?ՓK(D .56C:B߇%؟KYkDKd7|ͣ* ( N\&8g ABBqzUnXab! }RKC}Xgݡj} o"@qxL>GLHeMָr{'x+^g`4[=zN쯃􀨡6ҘH&d%B)`(! UCz[#9n+:[ߦ7,YYBOЂ3e: T3/Kucۦ$LJ_X?kCv?~Sxn;[_y\i$q"T M8Q>G M]CF]7duAg=?{iBpy`* cг°Xʹ4dĩ$gh88YhO]=]Z14:fP3ٵ5ρt]L,Wt,K7P 6d{FQ?}G5L9_h<[z tyW6o%ޝ\ ؆O^#ieK( ضEa KIvׅSfđĿA4@Oc,Sڋ1URƝM.x;Jsw^DKJ'O!Ou.{myN^=ϵG;=e+ㅚ};)Wt9(N|A:#+c ϙ2mK'dd8oA&\&K_ƣi8M÷\E/sd0=fqtᦿD.jtL90:N gNm:q?];)BCAk&&,; ^,K=~kxh Ig0̏D7/Ulb1I&d\ Ǹ2SX"WԀiZKY jZ rzee qeN1@X79+ndh0nu&Md4 LwcƵ[)8cE9ĕr l d_ 6XD;,Bc\1k*!՚`M#'k_F @u@h{h K6ZmmJqW@͂ !>aQxW(ӻ'bΈ6o7̯ ,1~ۿן_&.+Zb?}o *Ïoc| ǯ~Eۏ뿼 ~/o^&Y?k޽{_7o_7?~?&.oЅ>o_oo{ۯ֯_yoZv{?s1cYR !T$;u#ڡ Ɛh-~{/N+1d GC4u+Q%۝4)>}BćKl|Qh%k&ۃiEZK9BH%5J ƣ x!7m=X(02(R0 cĈ3m@Uq H)%kbYLh&I?Y$l46V~`ww߮6e>O 㕶BDGhPp[c0l~|oó h<-7QlIU< "ƕ!>)P;T>b Sj]G#& hhȔ s6}w޽}ݻw?QpȈq,ȊGd\p E A1.@c!O?~᛿|o|`G| %TTP go͟[O鷿GX?۷?׏OT x܊9 Bֆw"k靊 X~~,gmnC<SA+։R`x삯wTh9pub Ie4&X'bZ_$X)0hԱ8 6xk\{Yc j C6Q$mO6V !~'JQBao hx';'y~LFFWb l #3z&Hoa#>h"f^"(X _%a3@lZ"":<#".цr1xHv A\NFXHбaQ_'ضl$#AzGNeNyeEdh)NԵWB ꇳBlbx+u}CL2$z6MW w@kj˽/ԾiMbXl}\=>&0 0]#(.ަػ'LWmšb&qp~ gH ]#T8(Zv3*Gkףuӻnc%j&SB *Wbm8*q(66GD49&oпɿ 躲:y4`^aRWg5D`ovF[ HkF&P_1l&q} P @‚ 0 lS>?\( , P>YIy/";SBC>Y=* J؇#cИ󗄾>z#=؄ ^W^6/1]ZRGLF׏ b)Nz QR$j(LF~DCItĐܯ\de9[K{h@mZ^NP_v;%_2%6٥G-dOO0ٌoeGꑗNfǴ\P~I8>z%*tx.Ņ87TCCdNjX 4N 鰆xkhZOm e(Z5;jya?pguuYݞk*McjCZi Ms%[4BX] "ʻ E‘b샛AF3?.vӐ6ma{w3=Pmm5f3oƠ֧+knj) ]4lsS9o3? ^8k}+PGb ƶ7;¼[/m>ʶoC OC1l: &i>n܄b㇏V2,L+\&r4"kg$ߟ**CCdޜ1䱭H dXxv^pJͻJXRһI~Uj~J4SBp~*y*(uDӻOb>~g0SQv>Sˬ<㨁Coq GS|D>(i>a鋋/>jԤ1u;[nC`'rÔ flNR7bV]lz $Eiʘ^}gL9XtPWԛL9coF! ӥ8߶Օ^2C3OЬ&y&)yFFsA#Ѽ#"ҬSF8sFkko7':]h#j4aq{+i~+&J{RE;tFYM3Mz$֗oEzyNisD~Yjrdap_ný= ,$Q2`C(g\ɯ?KՃruTmu{'|Fgx.;kIAN hx0hMnO 2{8,nFۜ0|/`e]IÌھ ~ZCǩT"uU\D;JGM`;/[&X+ wP uƀ`\fnͣ"fB A\_(Km\ZdFK*qM.H@M xȖt!i`Q![w Ҭ d<MrTv\#&C\y?&cbYNl5ijX>$K͢q(;Ԑ^z;J[hV g"d2<QsV. .lqQQa!yjh|!_M|42% n,bN&Y/6+ 3\G^FUI#ͮMg*Ts6߫ FgSЖxBTXɻ7&M |G)WŴܸa!&"||; 5;1`GYs'E>U3Sm4.+0KOw!#Y:eHkCkkvrc?:va6kMr)`mQ֤X{rDLdEWvǚ}rZN(mBv[5?١ `fsSh6 ތsk˺9uvGV~QE]%Mn@93O.]qhc]@PiٮwwV07!AI 5% - .CJț`b~:܏8H@1L TBb4p aW8S)(]U{Ps[ZBݾ"9q.׋ޟMfs@E5?tڢMd^ u7.K`V 2ݷJ꣤P-Pݐ&[,i~ڌM?uX[b}Hf$~(K+NchH.g 4"5ϣV}qҥ#F5?d%zz,RrK\ĊK 5G,l`Z69Q)] VpߦDǷԤRYP<5;l/[ؾ[fD{fy m,ƚ{N}U[9SFR@/YkSi yvdV䫠9HNP3MY w9iT&mcxJ7aV\`4k%j_ s|,lP<)|t^y{ |A*#2M8x(9<߬85,sX@Erg qPv8KT%-eeEMHp<* h"QUaO)OF%La|[ȼNt~Tmc2n& dNLj~UO 5"z¦m u?҈vh+i j|E@݀la<[V-a]Iަ\Au_^q' )^wԓOEE`k,8;g\rJd^U> ezn*:-&kG=Xٍ`-Mo ˩W ӻO9 >Atn'%F^bQ~m_`TQL=_> svbn->* }9 6,3w^Oe[8Q {~BpӾ<1< <2Zd~Y˚m %osz',rڽpMM5?b,LJ1eD\ed!;~\X#]O?:x7 <^d~L5?!$ W(g%_~w5XVó&WʕqKP݇vh%/${ōi'kS:6 iPk,] =x闟훟﷾=ٛoqUbg1:[gb3Jpq5E'$_ljUa޻x X=S}M[8v>7HCmO)>;`مGni͐pMhB,ZxIBmsG19*8dR䤼f& 8-x&Bb`L{&XhŰ %-O P cLaP) Y[UDȰ6zg; #vWn>|LFkT'TYyOP/,{lu^.p4-f WB=ukRN|@cj`scӚHT<^@5-Щ'<(OS-yfOEt.S"Fe׉ ;v}xOT^*]4=iz4<.>.g2C2߿}_FȗLԛ)%?~pƲo oD1ϛZ;jڡ IU\3[NۦSAUL=̦g^-,m^GTOM=v[bi,V͹s(Qg[&.Xu [bG)H[5͊qmɻxoM}0Z|Y/|xk]lG V0!ϼU#>}xі/E0XTFDGaOl&ɿ0,wtBĿƚ٬8dQ'2aCd}:_?gOc箑nܑn0'Wi;PwN):qj?4|ӃoG4{ʇ LXG6<_S|k.l^8pNNl6>%۷Fm qjldNS/q5l;Uϴ3 }tuK6QGl'2k:g?+%1+4jSGt/'˗S5 !@)[2S6ҵTJR]g1ucĞ͋l]L p L Z( )OyΔQ=R_s<N0JAQ樰|LHZ.||dhXvO2uˤ6nz獭uhTN/8ygUMxK{HiݟFu@PC.ke\!"ڜ6oQgg؋g[^ 4jkvu֋ABi|*DR(-~Խ QLԍ|Ⱦu~VW(lTjz*]n=#և]4xl*0Q"HT-FM&W-du.QN !&5N/b lY s,rkgZa %9D.+%-eẎCYXb cGiL0}pH9ͭLۛLa m‹0[ \NoK|PIm6+.bY, ZU67eHyKJ\cgd AMk^ gY`5OFyx VBڑLř,ah8ZvI.yƌڹ󆚷X7}xCl%Us1t'i Rx Tt&Ů+Y{7LX ~:1`Oo޾O%_id;_"mo4$^Q^vj%j;qV5;bJ@# _|d:J靎!sstȼEZˑ"o.S.#̯ ֪.2k:Mu%&`tYɳSP-~k~-jr#ޑU|N^`sl<9WKւٯ(p:Uv 'ZuC':rrn]G^sT\,eJc6\y{+"y5}dwd9~  y?уp͍"Uro!e+W?ZdZezj|?رR$3 [wh;nrGZ%i 4`4F>G t2Ց!`NPTcQTj+~ %Z)8wkz ,⁀-g*q mVhTD{U<;suJ-1 [4A4J~KRSe{hpVM`ANa0殩i 6>LkmNbZs 雸=[ׁan)Q!ZԌ$rӖjI:vu"RSG3wb'[" 5/9L؜yl%dP&bkupv=PU:TBJ~/@Qi`; TQ$tk6Ok:A@TEw2;#9Ց摺`ce:œ#LX^;#a+wa'l SV=5yg'@F'B<=lfwkmq , ^%ѱNTt<<.r_gq=wRèxܯ.O)/}pq0=ns|8uOnOkt0vTYc0D7*\^S\raHi&/bTHW ^3#y t! 2cv*o"rT23}_'@wPCc68}, `]j$==jy5[j]I5{̉!\& 2"zj4 =bz-uV'X!p dd^9!LE9u>ߝʰbsi!3Gī87f88E4^%C~?kH~uo/uo>sy\SR>; \v]oו9Ш%h7~9hKwE%.-x <:aQh͵s^i1.nXdA ޴?e}my|iVR«Y&/o Oy4=-Am83r7m 9D#⚶Dˌn7.]uVߵGVpɆ[@ W*,"-J;"OM*]2֬~ xpwVK#K&_ʤ0[s!1!2Js#¶n@^|RLjFd0kꄫT=6gsg$ź0X鱾-0yrFRPP.CZ8זJX, AiŒmTbEgZl9HrS[=ZAl٣'U/1Mdc~'9/ "8ZO]\{||êg0&rWL1ͽէjOeu /Yҙ8yA*NE'Sn(%I[P_s$Y4DA@de]\it-堚wiſ\ג6G_rk SuDy(]uODoI4S}"4̴#%7:t- [pӅQ(+`JI)gm'wOteK̹.aN)<'AfM%^8E@.TcA o.o) Wʒ ܢ< |X\LfBK_1v8HBP~) Th >OOV8U.V>+S6m4gWj猵-7xw$Q\#zЋֲ=%V:X'@h:,#Iv≋u?9VUW,X,B0S@uxɕԚA2E=-0uʩs1b (i|Bh%̼!ĕ3"7ZԬy@e;m+`¬|`$G4b TCMX*=17x<6J1B? (ɳmܐ@r'C~K5`91zK3yȉʒ*ޑWh@ $=E`\ƲԀR^\ ^:xV(iHx[BĢ!.sj\\0Fg^`]$&).kr߀詽N/L dR3-Sj%d1v+R0ܗ˛{7;AFqW1pͥ>®Ͻ07n7 -/bxAr6ܼ5o):CQUܟ,vK( {oI. ,O*UUġLĔFBRBa*{0{tfفMkʉP[œw*4 BT HuJNK)lRX3ګ:r\yUˆ5;M5y-!899<ٟuph|1TY- >}ndg3Y.ĄʘWm_z@hAHƘB`~`:O~#F)-UdD8;WxúYv{mN4ّ0\Gr3WvNr<!\{<*X=u=@=6.^:JD<;-$AѺCȋVJ4-fvz.0;sWцJBKG.$ 9+\r# |Χ؜ˏG4{z R kJK2yb{oJa܉dMnpr|ɟB5_NC9m~U-3w3< ]R7+ =lj wB~N<(Md֪ON@Qhk4YJlZ[췾{\UykzN >bkyT%\a fԬVŭFPk#e֬4+Ia<곮l滁)QEj>؟/| yCxc0Ƨ ,<0u+ wӞC^\eIyEOOS9[rxz,) 6w;gx @4n+U.QWR7"JؖNvOEx/w&R=Mg/ܺF/g"^EE@9@,nT_ mCi[d/\E=dR|,Tk(h%ZW[6AjpJ6F#U 'y%+.iJ)Tu&T܄yJ_&-~cZdFΰ~:huQYq:Ct}:ՋRtNb Ml5Ht=OܞM'-Kl8[Kgx)n' [VoApX{JB+bF楏!E ~кzҼe)i{7 PxcU4'qk&XgǁT ٥U^*#*/j,ҨH\2<ԫg]dëL wD 7yUmYȫt5``gSey>%D[bCjTU9љPLGLwk w^KKe/pyA(A"owY/c%}{ʠ[ZE. |An4)֙Aqf1Joڻn_Tl5WN]i }1PNjvG]>FVE79oc#.Ԫ0 KuŌk^6B0ODQ'-x-0,_nq.R,w{ZH7RJmYRY+5TK8P-/1NT;;L^.ѲJnhYb!Jk_\)9E #]H[P֚nCG|*^ٓ '-^lEVYAXz"DL匫xJg.tF:&ЅGZ%EN>-[ vwKyt_r+85Wρ>#=YnZM5~3'roBl7a7,Mv:p`K]*&Xc%辎 j<=O riX3N|wu3~MvP>E~0tnk a .ف snr4"j:zxFBs^w&Bs:)~vf J@́ny̫Bz_x Sۈr+m.}eD&7zTvI({"?G;hL+]3HnÅ,eY7 y~uYY>$4PVe&їi7,ɾe쳡?Wg]տyC`$#O찳ܘYNNVOu^eHi8Nii" 0q+qVMq)Mqڭm+jv976~]y;v# =wvLΛr^Ѓͬ*yڋIFUî]J9-yL g@CǺha˰?'DIHq@NNI99âR'.9ǫ;.^Ϲ,tב^Wde&2ԣGwSĿu(NcH2ԢޱxGLTyfD F OONcĵE*=!y:&q4Z7mˌQzS I-?|^bUlYD=/b,!Dnm0$zB"Pr7p.׻wFס-E@wOoR\rEooy-0>+Ts3{]wg.i5Wܸp9D/%(KJ'xGU-NۯyLyy7?p! ^)šHw߮BCӡc˕B7n] h᪍:VIxXM]FĐZiPQzn*>%Gz u`0F}x-bȣD}7(85}2Cl{5MT'#_"jxHF]N5 B`7iz+6P{gg7Q:!kJOo>A^Ü33~Qx$xEh^R]7!nx^>szbyLӉnrȋk2մ.R4]/?+tE6z3@ȐWSQsHŋoՆ9E\븹2Lbq֊*.4:" ސCNrZ:GЉ2گꊺl4dp2*ݎ_ yJ#@j(5C'qUiSsJ@u1JPzWU/^ieQilF"&/珪u#x+W6QJG^S ;}lDYWyv>! @uC횙*jeZ5Luzwu7i \a?1wU7.BC|C}[%_ U3-MGG֥ǯ 'L8ѭ$@~|k}!%P<,.Z+ L7;~#!e_4:PC7-{!s xu9$fWv+:+kf(ˡhyLoȘ"2~|)c(L3&o-l*OCQy>Pox&}>iϷO?ݞ޽7Oowoß>ÏoWa?ͻ?׿뿎~|[Ux?[ 7O<}6-J>|7| |~_›oϟ~_~__~7}xO?|O?ẩև[滯›߿đ?}?~ÏO~o?|懯l|-Dz~,-oOoA7oO>_oo7ןo?O_篿>-c9sz4л%/G3흨t0{'E;>K2N9@q e  Qۄ{XĜ/ Iiy҂P/wվ@f~̵SY3[@ 򥗿~-YBy+_$9T0K2{!ٓKl/0ǖ.u^^r\nG紀۴J׭J/ߧLsH_tcEc ZgbV 7ĉZ P)l&B?G7O#X{C,[+b bͫXx,\aYbW[ Wʽ 3A5Qz+J'Emqs"OB5'r}NW6|JpSCNe2C 1jo%\_.eL#ќV_$LR" c~D|(pe꽃"D2͑Vs$|F(=LMFk|w5I`/Zw[+uh2i}݊Bmq-+Hw]}l (J/78 %+`Yr%QY*yX:֫u}m^O/t9P 7 ]p.t- 7o􊛤 ^Bܒk[Br 6.hr=EE ȼ.d?mK)%~|S ̓4&.UP"y}HcO%KξD2usO};VXw(UD!&vL/ @& E4I>iOWZ&"_(q MVЪ)c arx(K;S[T@ V > d6b9%pyt\q#AX }"< Vz^*] ^?nAѩ/G)˵K\!'bL'S9q3WovA҈.HR90,Nsr}_+ҋwbfL ŜO:Ք[vL~(m2B#cbVFfVP '3*!:II&%.w(]xiYT~2HN^EX>YxPN.p5Lm.C?,B[ͻ6104V @悔D A[6\T&M) c qHMh-Հ X7ցK(E[*G$Pyo$ag"GאD[:ҐFDCۯwTNM(V2(b!ʹIEoؑ) |Z.  J?n|D-gI]0\}rm)YZt; &:J'hC:!@K2d 8))Z;#8˷SV]F)U P곁JaG9XO@*R h}+!N߰U:5{2TAw?d .REc-6 L%gYط7RD6+yEe(&_j*_7R] |BVVT*hљ 1>EMXE^ĭPBMC\mX!Rބ&JYK IOj/&^QӬLEC ÏCF\w?}oݿϿ/Gؾ?7/㇁ӊhy- ;l뢩dii7^ѽfvҍij2Yo:of>3 a5i%Lm * 3Nk]/eknҺ9A"+Za84bҼΠB&,BlmaX+*K]`(=\̪K`g3D8+QIM>K5Uѐ㻏>dE3xVlu8%PxR "MmCNLgE JuE<>ϼ'@2H3ЍlHLњN1åŀBqG0Lt6@,_f#uMYl_(zT3w?Ȥ#} )OL1$.J'>p(jQ5%b R$"́>tP.-z gD\[Dꋃ馜ehCݓ"#sȲ͈1qt~]:"Y9m>xmW# ;Ss@)ڌ<]U0ǬŰ\2+"G1M1 v g`j:*7p!A}!eñ-rQEZXzq2񡴩ӲǜX4^T`0Yb"jAEoOooUt!φMH͋ZWb(`q\&ab@N8%9p| LM-NȶZFӥVߚIEtu]LO](²P|nV+m[!l =8|jN+K'e, `S̅S5 K7|i4tTHwb*F,uLS z9 ֦xׅk>%(HN(Y~oD{#5)\:E3k]BaQGJQjX&XދУ n[G;eۧ)Nʻ[9n:D|)b;%uo0h#ݻx%R3-MTS-BS b582]Y7gw׊YxYDO,ݿaEa%IzD f݉♤aZ5.棃f ٟ#g! f^}#Jx:X5U1كe:jSɹ C͏G/[hqDpxkR@0f0PY2xӧa("*`B W<ܜ;ub@&_ ƺicw;w[}y8_4IJ%er)۱W6ĦJ!x=А6?bW̧V*(RK;£x(wZT`kY쇳X`","KdPt9Ǣh=p{9S aur$OW*$wS8Xq1RFC4O1ġOk7l?  NGc_",DX;UE}CD2}*e0ȹS+qd\t o:fh0&+Eo=[[OCy+咘S6b%[0:#5c-hp'Lo(UĠ4Rw &d)g!G^wL9bK] Z8ʀ> f8gWlDϹG*C2=ٕ"%{XV4>rV'}*D E5kb M-SuH D/; jE3 b{w;F8ϧDvڷ_,m'ʦ-4{E#*̂Fz ݸ3%\G%8{4/e/~,~ dN}h=+A/i.EåP/3 )(ϏGf2Pn.K|}菋.u4-ĩQhy5X%FѦWY4D9a 3c;Y9y `AGii1sHKfi& ^Ľ޵S(q¦kl)DTx#yS=Q!mc$55kS • `,>ՕOIXEe ;[-)blStbaSA9֔19tZ1SQ:˘"1Gϥ5Q׾|nsΚ[t\1)kM4ޛ<aK\YfNv_'팦2@Z3tglå NNiXK,c CޝoI49cvnKKg7Z`s w8Iv~SS+>xuդ_,_>Ap7+"@pJ>˧p%+qs= 8틧wkF1Z|Fjr/$E =ǡW5<9trah[j#ZhF,7& =;V'N48hI-!ngGCh1*ѥdzj{( vz j2͏@maG|  vi=S3O7cili"R4"7x)4rRGؐL<jǕAC$ 8ٞ1' Ft0wOS͘cFs5m1!M}diVZg 2XHL;H'* ]M#P-ATSlR'옇[&}MPlM9$4!=R /}0%07@4h Ѣ*yK^pFUt~upGJF+yѨG/:0q=ϩ3pd !ۻۻ7I6JGn(^.We*y#2ÜrcU 5b2PN~w.͏H4ҁ-d~w*/h/&۱Arg5Ej3 .Gy~.wִN=լ3yPk59 7/Bm6UbLk<> eTj_ia&d!~iցUㄳub:Kl-emi-j{̺w<㫙@T]$J)H H(LG.nfhl_yh'5= DP `Ok!{ π>mIzFmSԢ {Ʒ5Of{NLgVkG5of\ܨ$W?PC s=ng)t| FFV7/Q|F-A8CK7'[w֣#>"PB!tsQUIĹlOKK0#< 9$'tFOݏF Ec?vW$slu6*j5W'`XDNToAco0=o)eT'Xh`4 1Ѿu 1p.nFp.B@/h뙘uGR@LU4㪑EїW)](Az :?6z VL7 6*t lr)!ɂll ȦxkηȚXyC6u-%wS@6٢85KdUmɏVЩ.`:&ZCV;^ʥ rc(,"AI (7c9h÷z\b_=z%oqĉ\X=2\dzk/vdLތJI ^q(y< p: F%`w6-33 c]xs'8aq0L]1êq v#7cctMځw@C[:%]qC)zv̄`+S$f55fPFk?zlG+|~`#:^rvZN:3˺ĺ^c݃$u -<$|; L!:źB ni<1ڥډq-iESn !<4wd';_ԭ~#LrLx%}pĴG!z B ٺO4N>CZ _N90s#\Jѕ73nsɷ(CWjU]1n?ӏ>~Sڒ/)?546=:JMWMJc]GGARX7K}ЃĄGLo*N 0DaJ7_ϟ~o}ѰҨmlX @qISSRCx !gھ$ߜmf1&][u Fa v`VƏz^ɉϡr0j;2Tv@4ҟ/6O}p2w29 ˧dI-O9pyZ@xIeY(LL >Q.ЗäW+FqE'|ɱoYSs Z hOJ_uh}@C*C"P2/>CAb܀GV%@n$‹-xKJ_˛G>4.J aa P0hX5&4["ׁs[T^$":۫4Z3/ TܤV:-{ea0\IHKz|yU1/>aa/b&0A50АPTK1RԣP\iƯ9,\ t}‘XЇ͑[ItHU;(^ ;t{4cg7E^MKr*DQU#8;=( #<9G1N_qp7-.ū q E"ab jL +16ЪV>)?;Y@upL )wD!Gٮjv%gz&Yɍ$kaZ08ziaT3.9$d%gZD!YȆTp f_Q48edD8Nw&N˚lCcb^X ؃-+exd(`IϴUogkYUr&plAx䘫 =;:$>,. 2A+9nz&3 i[imk4Zď*̽A(/:Jv 6 HTNހ9@%WB0Yl)jj?==}|L!!BX o>WIgV n R6r}):(  5J|3|{X3Tغo"tM47eQaT{AZ݇eۣV,pEKͦYy笊wfm1/Y?=\t+05khmwdE`YE"f@k-=(EvMlx!o>G`>ܞnC(|AnF}mR㦰:vtxC)~Q(ٯygiLCHYED卽d|H"]`4Z8Z 'kEV;`ieU&u#Ҟ}^B1/XUR]gb+p]ad':ZR;vOMǽ3WG1kV0TV}j7w{t:,;i|e{\ue[Yé`Zzv@*]0M! at!3*K9RRD7Nw_6 $lۣl k.m [ܙ҆ x-mKE'i %iDGIaFRX3~B<8E/s4s4/t|ǜڳVvj?tmM|6 V6Av5h=fRX {k]g˺̳Æ^k\2da~>>bORٲQ[[1U֪s؜#1V]q>ȸZ?pZvzJ>+s_]_m^< aܖKIM$١Le )yk? _c_x3&jNuf/SM921#úkbu~ ʑZ_VlY5iQN@l ̺Wgh§dh5 Y/9m7ZF]6Iew,W8ba 6莦8<X |*tΨ3(` 5rAY\r)-^ cfx֕n^1^Aulca~с,^~Ǵn>FM &I[Y-9}YH҂i$=[ZI|@n񜀗>`pA > 7`XR%ݬ{qXE}Кd!L X }}6 N2G;֎z<VL#H Rr0<z9W,HK2Y$Z,CF۽ 9/:oEulwmT.HMݧ>em0 )c1f".+@tF6iڭt;Ǯtf7nH0-\V H[Y1ECʚ3瞲ȥz@lK&,5)[* ؅}wJ;m qL"Ⱦ 5TP+&΅O_r}Lx:smmꅸ'!m"a0=܂7x5":W]Ɖ9;GˢIG3VoJ)B1ԙ4B?|V%Ѱ mKljU_J}ebN5$&:>cBVF[:GR@fܠ(wr o ;hvEb) 4ֺ'-.J :&3r4 Wg6:K]bCK dXM?w @1D fUW+쫠{UkbǾL?ѩwP&VVPFZr [HgP;~q6: th'ͺWVW TR: UCWAaDp([KUXFMX.X/piBc:Όm0#'gF6^<:?3{OKa]g޷Ҽ5er(hͿ3r#ۉϘLڨYx25<Z9y62}tj_l86q:T $=hiU`/S83:̢ΙA3%OYB"oD:"6ZF gYCK7zHD8Wxd5 2CU,{ &]pj# 8;jW#U4cnOZ}9hiM2&XzDP=^YZhJ%P\xt(:k+l;u'N,!ǁt{᱅}cxZ/x_5䌿i*T;%aKkGej1D,:^'̰{֯G/O, >}V F=Yd:."3z(B?I?CɝeNy;8K+VE~K|~<-}FkNWγŝ.VaX4kí glޒ,'L` &>:sY U M[sG$u6e+Kjy.,luduChT`P' c <F6 څwvQhCzw)?Mp>- PXOUV>SƑWKجḁj9Y21z]Oi-uW PYFr^F|߂>'p3`ZNCf;FVt` ݲ/H{Wݎ2Vϼp5{r=;`˩aZQ(8Lqlϖ}Ƭ^V Zs\9Ib YvN$C%gD +[;PMq1@ s n /-lpŻ!}HloX?@|\z gOP M^ -eh` ZSĐL’-&\DDhՉ 1꽟.d-R8zb~xTiT[BՆ+T'-d}jd ۂO,a\Mp-]pl%h"ǨCw@%c+DfC.Yiw-ppVQnwNx0P2 fCVT}7bz e1gb=`$3 T}y7}NG3Q{DB9rF&Qz&W7h%vzBOB+i||iִejvC#lŖyNdmdxv ܃Љ;4hg 6ۿ_jڏp2LKF.֔@SVBd NsB5jRRLcPyWr:^ի&.\q>؟'jQ"﷗wEx1чHTЖ P,JZ`łTC.kъ$h6q#l12N֩{")afi2QraߦNUzժW:@ V[t~ ջ8 @(&g}ۤZbAbRkdj!alL[q=BP8N7e\./^0Ct3b;8B 9>;:SvF Y춊.pShlj֤3񪖉T}֞$FdQY( dSxӇMűP*'< hi(ID&Y]:YMfX@gi.k6%9Fq8 cڤ_hJkUhl9˺]2Hth{hA[ΥC Ru^Eq.|NVZΤsCM8[[[A+|L"7F/F[:jo4/&٪]~Q-iSFuȽ6d5 Ζ Fg.Laj;f ˼[J #2L l^NkXPݘZ=+ "5{=7 Hb P1XQ#$H֧&Z6|3Z=%8n2[t 6A [ RxRFb#X +$BC=H[7r. TFM9V%q=:v|b&b~ $.Z")юMl @%d)d{){N$`='Ȓ@2^r\[=o yGI;C \qgڲ9|}ի^1Dѭne41^w6(ލ9坹ws f7dt+[]n$NjxQxocjpn8X6ϔ15<Oo@ ͇͐@PirWuBžw,`\,F)"OTX&'&crR9 Gl=69O@0&ǹ.N\8:/3Q&} eU| "i^{/o޾&y^͊zkW_~pϜ_?9UW_㫯{ (~x7ջ7WOxb[)o?׼_W?u2k~ּȯi+߾}:7w^k)?|7?~o͏x_#o^}_e7?_WAտ?ӫ뇿_OyO__o޿w/o{N DmCrmZkήj,0,֚.ǨΚ@bTlq)H RSm.x scଭ9R邭YA`f \xBeӓ;:`됫X\%m-|c"i! * 4/X) c Tx.Uhc,?S!>2q6gV\l:X"vlfXos Kug]T[JKۻ[f߄zMS?0a5ttw]^1/צv/vZL65gW˻c'%'g65UᗢZwU* fy [n6!|MC&:ūy`G:cyPekN<U W$UኰVBo>Sف&8ʾrm tu֬`>R "P.u$T kS)aWTWxR"vݔ!FIcA 1/:_L;p-Y=T/Ԩx5ǼB}.s*s[މB宱K_]tijˢal:sϵLv̓LJ ̛#y@sB!yN&5yXhɴ#̹K*&z!TsM RTy- P*XcYU|+Ȫ=Q詤"T%!?TK*aj "~z`O/#Y8 vG6@T2'lUKȢYؔA燮[5+ѼvVq|5}`-%PiM?гd2I +ES+ V ,W;h3 VX ˻wo޼ylP6)07)"R.ӽYkе2!u3:2݌IyCy&؞XbaVoސ_}ݛא.ȭ 6:6 mM?~?lYNbo?~oo~o?=l_?~ùwPњo]ƛjܖf{85iTYxnPJrp­&;*25{Kxjf >,sm<רB{Js%)%>17o'^Յx8z3琋q HLGǟ?|8rB6 KUACȣ/px Ak1=r"/VBhGKǑx3Hj y}wRՔS[ 5BVfXmiLfYݻp #ɥ =mfiI!Rۂ&{? 4^d拘& oE )=ec,,bztgA1\Z[R[64R++48z.צMׇ\^޼{E>р 6q&Ť@@Z٫O72X)i@(fl.ȌȆE']? cO͜QH&A2o('SbhpٴZ ÆZZÖT(^51㡘Cz7ojən=_S>wl ([]ìw*BlW C/vs`lYr!H\7ſLMJq_KNUĖWTZ7[N+E5jtM5_CKz:xsc㡓n{|M%cѽ3x7S+u4T!ۗ_OdR&ɳ{ML+ZT) އlEV)mdy&˽) >el -g_D/ҎɁqm}l3SX=fk RDmymu-?VdP=^j'<׶t 4 FrighC r 힥 .~ULo(wBwn9@WWuMH^ꤞMmu -hOZ#{Sc:Ꮝ L4wF^O<[`bכ^5pMnHgonHK<ܰ@UN^o>ѦWk#zyx@xcK^.}pև;Ś]_8pyl|cF8B *[?nq7'ڝs2]=AUQ{_[ WU} _P#7{i+ ^iPg \bpx@V+b`R'y FܭUr]IXrmyb[0dƐvU1)8Z!MyrϡrP[m<^]v}]"zv _zpD׏+ĪxC\,{X.W:rޱom!uP֮TEݟMl  h{Y޶ v̮q3B{S̩B|yZĻ@Ogl"*eC+d} ހ&"d.aar?%%z&lKmpkAʉ]GJS M GGo %Bhå2 Omrȷ;'H& !gXm/ۅPmRL]qv?rF*ތ 6y[TaFx6fW"Y ; spXh9ΠfcPk3p^{5c# P 8qKEsqb$'|`W;O( o+J6ɏ`cN0c d/B& BLxFzŊ~no?^j$g\=`ai0,͝CX!U8h1M vkRF|LD v #7XOMтA"g7´0 'P ኖlZn]%Crjb%B"W|L틲b +]Ȗpb۠ *%§r;bF72lzq,K p\tbs8BKJś+ gMdhYҴ\u=s8yYŶ_T}tȖT:L(WEp'Z#ffvMkp@,7clߪ~T3pyQGӌ:JQgY<%ܘgLZ7ƀxb3HBYS۬ǥY~+dee`wp7oQ={2u#5-ր^%$-r=gPzťuCdqu7`G+@[\ G!GT;d cQ B-w.TKoDSb R7q4 \) ~"7RM8"h3~xk$I.Js8$ϬijD{dtaR?6HSpӠo,1\<6Btr.틠jrLA6ꕌK{d?" ɗajhڊjH@P:<0& œd)0)Xهcdc]KO3wHi<,V?]<>g[;..RT yըz%"XmTS9t (tLjTΩN%5PUfi C m3}B_ZפjvOÎaCM[MTpD$2;H0)j@x}TDT Շ Zծnꁗ)> HS:H)%x yjPBLF~`TYX,ok el^ͬ}*L!*/ n|Z*"=Y^wRwZ SFqKB#wefCWR,S[@] v9#Wx d1BN ;_@O]mÅ!↥Xʹo5߷m8 cG/~f~=v&=8 ` '#cNj vo%// Ka -aSh^ń7(12x퐃/qVPr3[91?M#"^a|uMժ/0Kb㷙\C!wٱG/"c|@^GZ?tN'l$UiJIzȼWdfC+Ϲ,0PsGZ#Q f Al-# 2;HBlٕxg9v*,c)29 ' e{rBȲ otOY69=^WSB=-Oh:0?c& LPNm+N! O{87y60Zj+SK^ s4]|y }h.*GոC3- n-jF@$O/= q 6%@=}$Ӆp]V-ʈ KR-Uw Ck;K3ۼv wGlͅn2&l: Oya(&@vkr⫗Jء2{w@$>s1(qr]λxC wPiW!%z%F! %%qJ3xFuSX,t* C{D'kkL% O8g ~c璨~<["Z/l)FA6Hobˇ_ġ8 AՏF( (Yj=萙7Y# [x;ƧB7p;/WB-ypVeYaXRI^$w%k>sr>{ w6l>Ml)lIMȉ̯zy̓s??/W[SJcP̖/sjFz5I `obfyRBT8Z?\޼čSoxW?nb{ò]lP 6t@ yak2Hy޲|獏kxgI+ϋq /-NAq:2J 4K( QD}^,\w[OJP4x5R| ;xĹ%!{]P|P4xKw7͑w Ao۲N[<JlgGE`A0ŘX;lĔ犾sxR U ޡX1f ]U>m7xٝG9/woC\89q9dAg ww`1"/S˻wo_G-˥cUHxى7z槑tp򫏖(ݛטEP\Ba}<_osŀNT@=ܑv`ZJhΫ7.6si1F;׾ mbe"dΕ l8vx:?C*|@sͲ9gxagVݳ_E˙"Lhx W߆nOtJl(SzT\)e)D2K} P,Phآ<# *e2DU󎞐BB$ӨLdc-ȔtAy-QIx,&*jbt9-_Z <*5֪P1MS9M8 !BfEuje4K%xa<>L/`0@C:-h7h#A:zR2G>$V{l9䉨S]6ICjTUM-Z*KLG[;ޡ׃;َf#Gw3c F:RstCj yHؗR=aotք@u®kRM?Fa4*PBbw2+07{&dS!["ʓ+1+e&2vKļ>߹%&)c٣%j5v$LߕwSC8=K `Ǐ&82vԂdy;K97T5ӗ=6eSËo\4*6|(I}ޫ%{ς'?ZuEXmn@]q2P2E V,@uµ#0Dqy+7NHg9?%PfOmp'bM)w@5bd|'쩥$)yч  KC#tQ[ rW |LKQ>^5Gc3YU'Ң!wε!<#+Tyj>%|M4yJ5_/TA#g;/#+F/Ǻc,| H;ױ̰/'X2֕#Y/2#81NkD-{&=.-zQFhԖ/nPy]˿UJv B"Q>$w{!tqKӞ%dYVacdyv.O6@8 4ƛE6)|Smrlɪ+Q]c84ABfTND>piJZR? imEPZCm c :dG|l˔VK>L3)Xu_9H: CT+. PW2lVW6#\ZهxC|4I+ &O; 3  S.2XKMw8̻^/o@`WnF[bG9 ""R %``pSuyr^P JZFmg03@T Pl+>`+v-0#Y6@ ar/P4,Qڀy[).%)ׯw.p8h˖ɿE#i}(};{!);Sw*,SOGez<'r;LONRuKI ^'k^&Ò$N[)'FVk,2ޤxRSOʟ246UNjnY%t[C|U!j:ƺEbJB*6!=yՈr D*ݓ c3mztdy]p3|V?{%Y+οִҏd\}E)]7ɫYyJ Y<~xhETi/h4R; 9{$($<mW:fϑw::Y%.(eS@R$NiQ|@TEVUx s.uwIhh@2a6A(EȢtB V2 *ߑ0'(pGFc Δ`tF^0k,zDn.qBݜKu͜V8!(hWpzJ/ q0a>u(&)ŵVx/uj Z`~6O5g} GMu\Smb 0ˇ_ Qf ML|6YOn['84HS+S+ 86ӕf͋_0IN+JsABQ<Vx=8G|_3{ЉscN y-#%1n"r{|*gMwztTJ"'f;h7^|ȡrlɐXC%3M>~2Mǚ@=H -E&ȸ@JffP,41("ltK6e`HnY/7v)]G<B>ydಖvb * h2M#;#$$ zݴ[0 WF̱,D [vcVn$߃HD]kTBr^Jک<t7R'l Hb 8FTJ `]'VLKc.:#;q#82 嘕gBO1 Y^HiADm)%0o?r+F!< ndOnþ $zkl> C ʧpҎQDLk0]נ,m"#|k%FSZ҃[yOdˇ_@`A`yY!] s0@|㉥ǼP-m,YOB~ @%JdixbmjJ^OO_qV}SR^pT?6 S3`)F+r5:yb..8Ȣp=Zs5A N!3f8cT6m4Nʵ?zGZIDުI;ZУbח] Le`'ީp 3$u$.0jxe `2:d6_)+1:dhYwhH0牕DĎ\@8;03TZ5^V^ Kv1v -YD$J @ {jdL%͞d7εO@KJ%D~:6>}=*zґ;Iwʀ(-*[%ZŅmUoy^(|yy޼;_7_Ņ7?oKJ?!-^&A+s՛o_%jrǕ^%jP΀(eO94٘blR6yGkׯu+WÔ,qZ_M%{=,o6ן>?c%lC+ dm;FQHpZY:mEsԘsoW><= Pr00B/?l] X5jc_F Ծ;_|;%7{Yxo=[5(eZj CG JIԾ;Zyʲ"Ms3O7NB{9N8ۛm$%ڼ+z4-i ZsH6/ KAinZ^%E퓣yW(~iq㚗O~gx~4x.=!c\%ʿL,v%57$Һo$ÈBk~k1q.&|D$[ZIlʮNG5ǩjkPr{+w0wK[\.@/9!|{,YPZs9NQ0'=';aE4JjűzQNjsk8-d"GUh"t> y5V\9sr[ȑdH>HPZ8]Vᨓa%c!P`onDѴ2'x[tH;Bk9kCHeԇv^\Kt}n7޽%nd7dҚSYe칑+_>W~ X`mYRYG $StdzU{J<6#c«2yl<0$>,6cE0\k*JwYVB`VHYg8VӇvƔl( yԖbGVg"BKDm1N >cA~65 ܦ-/B)7->JVB-is'ȍ_( Z,-LF 7J _JH_eC=irLӸ|(\cztSM#DEvu: 97s3˷s (20IK,zr`C/ UJWv@ԫwdVUwT=˥RifXd 287Op9#˻/X6(CCT̹8sBX! MU\E$'mB0# Lt{H Ğ4 yBDn 6`(&F&%9Ny [nnoũ(CфwTHjC,5ʧsNZGJan❂YVYr/AC ]w%@7AJlIt&N̾s60̼789Dm v.j<ёiq݀[2謲c&N3k"E _~|y޼+Ĺnl6V~p#l4`;y[yjӠy3*G)Sw.?Ȉwy ͠r "JsDas{՘Q8 x׺syT,j JfI5L% hCǖD!Fm_(Ej%М z̖N?TL" fڜ.i6L{ .8b(gIq _EKcMJjLyШ!sI%;'춐ˇ_5"~ qɛ'2ƗUVlm\{bmtL@Vyq',Q[@9vQ,E9"%FQ/_s3=7 L-ti=3#jBĞPZx惂uB%(8,/I9V S7hό7ϼ_D3ʤ=b'I :r *0z5 ['9:y3<eGx4Q"{zDl(>}޾{C㛸d~?O_׏7pAƟk_u).1^|q|х?߾iP?||#K퇿^O//?˿0׿M}|S;Kӫ}M|Wo޿4p|~7~zd~OyB?&.HKӧ˯_z߽_?O(o*_}W_wOw,-ĂV  H![(X(K 1{{\f\qks6V) k+,J  ڞ`JFJhtřnʽ1k_d8B ӇO@2qE2iPYΠ,.btX;%e}ybR!nb䅡Y<٫D"fͰXix2e)2 ſF(%q1(b!qb, (PO[& koK=7`-@J+R\ߊ$-14t9\1v "Iggz~D١s1FWa:\JzQf d$9י& %!oqL nѺu4CnJ iLH o$A9D4k5['U-mp yamB׸@= hҀL -E;Vv3}{ۿ?_#._OO?GX(a ?%՛+Ő@Ckg6CkWJG7Oޤn\rNۃo*EZXnׇQ>xPp#PHA`w~j3NOY\`>NVI@$󡯆7TTkt}j]t9W^TLl><c\OrY]Yw|ͣq uĐ>} !r~z,+<O@BdS5/=PI[p+BJ8jQoIl`%Zɂt8J&%,(/LeeV'RmF $h$6ILUꠚvRe|Q,ms=XKv$oZU!g(T&*I>nZzw+xXNȗ,n5$7_Ybj]^P'~w/p蚡OUz*I\d [Lok\/ y#RY9kiƔYMG\VъbQ|u"]f_SYr/;{B<[ vː>}V4K$Oo=q$y]$s},g4Щ-:ޕ";H'S=e8)OKH7>M綳\+ >;VY0T%~İmIg>8BzAFR*YRP&puI+ AضCq"Q&6Eu ꒎#U㘢`D)>] Tu:̣U*4Ets|/'C~U :+ /f`IEе'zUaԏhSV= wWhcu-=MLS<$ߏ Gͷ[ 8JI2ےľQȠg yg{:^Q?Z}r4!]l.q4y! "8\p26\ӈ',[ U‚ pT_zrɫ7^X{|W;An,*C ڕG㇂-т̦Nc M; (Vj0 %ST49"(7[ #E<-"Ay6s|zR[3T?1x^QzUiv 6^9ty־D> pkk bEOW\,R$Lq EPni~, R 84R48\p0M_OޝA#snsQƸyPiwpmݱpr}cPyp6~X1.g6՟R,yø{¨F`)VEcSʺ.nC:sB=yIZ0)4ae Stc{9D x aI`,/Yos`|{<4o`i^wQoO!!N bu)Vß;ZEVtFcPAN7I6uLnŃ r;liwh 2WL3c\7L8tѲ)G#3@ZԊui.(=4&5_dҒwN%5.7m /Ւ1/ӧϐ>I@D.MQhѽb{åJaCG͋w|aA|GIxb{C7^@(‹")hdhby'rSn~/ eNO`6_l?lB LPe%j:f K^k/nJե=p ahJjl8s׭P Jw1+_55&:N׎|9tL"mm B!ꢲ1|97{2w[v4i@}=aÆ~wZulJZuOIi~T7 0Qm&0Q7x7 632=d⪜)* d82g-a-.Oyo9oRIݝ^5-[Q &Sy[=q16D[GMMmCW!)ӤS-R?S[T9Yy}jp_Z}EGۅST]|d}~_T5~]teLIWІo65ek-l4+۱4|1*_ƤLMH}A- 6ذ&-i>rT HEᮾwb|j#(rO*| _ݝ\-aVm Ӻ w.4ò'D+Ln6k떥 8wsisH7& -жxTӰK6%\F g(3 ZR[;_yyXwMLr;䩇l{:+8]!"S;tQ;#Vڵ,rX~7 i"w@?a6t:>Nj:jJ~hNɪt $$NDN&='c1/'U!M1Ϥ|/^ҎcQX$Rǝxم"`Ug|AǠK樨׏byqӊ]}k?~Vr>qzG3n8~;i9'n]8W ڦ_KlnǶ3ijgϙљFw0v RΠw?^9ov(wmìˊq шAq@w U9P?DDcXzmwon}WOI7uf^,&I 3;ad><GIUmc@2͋ܠ,T(SXp4Wie@%paQzIP1u $o\z/8]gv:9eG[kQp+8bCæv){}i)dt)½{ 8CI5NcpU:UiG1n~#4TzFhg u 9cz+}YsǣGHX޾N=XVSht G&{k"caXpEu˭G~Bٳ~RӬ ܭZb~('t0r&mo'o2=\c?ycnU7 $9Ig'?[ODja2b=e3zdg{jM39F4EO~+n+iUӑzO 5jjMF[] qؑL S:b 6Zr YAPCd7hfU WYAX'^=bIxMSZtꓪ\꙼I4XRI}̍jƽQ<.[Qhu Es<|ݕ[W~q3uh2_'b]XC<te'Gl j$Lja 5=e2Ii8<)3Y ֿdk`fu=QRL]bRހřjqE&rG"ƆD,j} qѓv ۀ(3me] n!{A;E. =yFj8ȁBA>*G ,i_7Kt۴rvo{[@G_閫aLjiC\@hػh4;[Aƙvfn:#!dZe|3ͺНi6B'M[ `~¶ J궭@;P㻒%KrS@R'-.Q(m|ƕ4OCVU1 DeuFzK1v[H7 m1S.Sm#S1jTlI\ָڕS<\H[8 %yL)gjXc;q;!򌪆/!b'FXR)P{\;Y[ M%i] X'kPw idا.Lik`lA%bޅp3Afh* wտ*PƘ%Ybm:Kr5 VjͶp#vҝovnP zZ榶gQ.hѲ|_=3F~U03B𠝟;#=X\){ ɒV1yGhf'z#;F1;),0lbg TI{H L=kn*g6Y3׾Zw^1<VZoN6WNmS["<2㬯\!RvTg|pv3s͜1=;]-HS2By=L X`+8ht͙:x|}Bӱ}c=k7sZK#7g %?~ow2Q4?}h&7Ƽ>h,='NE9-<]ESĻKWf8c[xaߞx$Cctlotm_:9wo@Y36]Z:+W;j޹Km5]ۮ%i뿆}o$0Q]}KƲ$ %'b)=G`T"{ A I{\u`ƧO8--p,Ү%@:%Hw!q'ñp; O֍c3-9%u;+Q `g3ϡs^ήI~ɳxKw=vo}g,f8̜!XԂm83QAq+B%ܹb:Qw; ;v[fDx]^bO>Ӭ$+y$ǕW x]InKZ5- B>]s_ OHaJrk^ ƍqvwӄ4"=S%P=);5"ldi:=“[H^c6]M%h"!1zg5t,ix"]NL$Uly ׋"$9"P\a֚=.m.MC1d$ kX<"2NP'1ϼo-݁)dr֜,eK9+ڹ}{[$x- X]̠\c{"1D\[MܭZ EA1䞅DIǃ+DŽJ7Ƙ7N$F#!ft,_8t2ٸ%% sfr"&rGq> qwEҙ$XܯFDh6ʝ7;@-Ml&\V:0'=4զkڗwU.G)x0,Q/d(V k?+vZgmH??kk[W6cM}b۵E:\GtKlC+hq%w+ft ÜiI%C@~\ڊv%mqa0 yadK(w,|i 6^$RVj.jZ"{y랿Ҝv}M\=H` ?{%֜C+_X `͑uv_þDH{C r}&d7e@ K[ȖtB:&ly2bA 4BuK; dfzND-he{)mRop]@Lpqba=cC\ّ 9 =Px<^B+u\\)mzFz- Z4%i"4{=OZR' qÖ `R`*J]B8Y4&ijb q `W;:}UےSn! j }Y iyZ 3%Cxz-y=hdǧC6 ?b3DxJnp$$1̺~$m7|ỷo E6@#'m}1oβᥳ=4/?18e  *RR,NG,^ }6湖O?l^õn ë~ 7XZ}~FC`=?^Ĝ9 R?ǿ@?5lV ]m M2f?o&Epq~yhղj0Oo޾„jIPsOeΪW,1ݚ|ܴ0# {q"sg"6T{Bϟn~s>jX]}FrKQ^J?F$]g_q4!^?a.o!Ӏ8iΤ Ƿ X4g JrRDZ^ՠGRGpx3Y{> 3t$ 1]ȹz/|yNi qv/ 1B zxS4ĵ!J,y. 1JQ'׿⅕!&6wnFNhlFEܿabZ&۬_UpXfRk6u),n2@ՒS˰3]ʠM(1k`dsR U6Z-baCPn 䢬F sh49ހmAbRY~€KZ꘤Hna1 j'D%n%ɊdK$L æ@U sඐ 8𢽐l6keɑ6{`Zx+}; ``,rِ|-X6w)[ V鍨m+IW2t?gT,[BcV{eG݇qxBJq9LF%bmv)vq(D| )kiGYeBxb}ƋI l peJw.n}Z\p5ZKW1)L@Ss!`^쑣A32Zи&{C Q\,%/lLQ̿rrRww[ Z 0 XOES1m2YbcR7{ߓ+"Xֲ-1+F',0nnsĜU6}9[ygmd|?8pjwq״䍼er`pub-2ïSXqػawwz!TpO{0S,$+yȘjNְ_[Cvqbѿr\Źr6"|z )]Ywh=BЈ$c+X].v&ip#KP]I,^>֊#zq:{#7]޼؊VeϔYCo(L.nb_)XÝ yR$BxDz|6+8_J;1Zˁ2XF_\=x+O*)yp,c9ȋP ;-1UE0|QzT3 ͖vZ+:GŽzDo~VߝԖC@+X8o~+XYM܋nl 1u!)) ao;K#5tBULp47Xt ;`1 kMYy. fUx}ќ`]ۣҔ'Vz^mrsPawdp_ r7)\ tb`6CxR A\6I "ͽ{|*)S%i"R|Y4i]l<OoyI׿h|&ydqft/w)L 3)ܟ0F(?F#n,)M4̋t3r?_??н[` `M؃ 6)9:݀$^hJ,,Gt ߀]sfO͢v #݀^ ݬS{|,2Oέgǐo?/F.l&:&<}v#r2 x6=˥bERP*ӞnjP$rL16~B&I~+.b9B̗ ߎt!n9 2#2d8"ÈGdzaDN#>qDև9=qDGd|"n)" "SCd*#W{qDG6 L "-"Klp'L)~倗FW@{ƅ)=ºwg,Iؔ@}Bdz$zV}l{ O{ӳ {^ Y U!MY=/ϦKT? XGX}Ex "ϋ3 BuuYq'H}|_Jbٟ:6K vD=DmcHR,] G z Yw$/b0› d8gN|tf|à>>o=PUuI'LI򈸀 .&BqKC\"|oN0]Ưn5mtQk\%97~hn'g -3[əmjJudQGsJ80zZ#z< #c~͋tlLcqU1*UɑuoM<|㽜q t".ܺ*b;΀ Wldi}ɹPwE[`5@.H:{y7%-j=. Չn:S6eRj#RE[}R5-VL D[5 |$а gjSF}17?Fxk%ԫh ڒ`%S/E|]g 'XVo^%H>V نVCpRrZ6ӹi{5st1/@?>Z.Xݎұmx"]XIg}3'Øb>"zBfνuMo\K!x*+_p][l1k5&V=g${[Wրˋ>Ly4`wL <$sU^Hb`hŘG!x#(9 KX95EVX_"a܁sx kZ]s(nNhxĝ?Ehc䎗ni$VnۖS7|@9t?f,9!ul~ q3j5[- S P6\W].[8tHgȮotB: ngB}gWH{:=5RҨz2=ҋY0ك5]n^E˺Xn "Kь 2b\KU?[6Q6nTD$QqMUg2 frgkevٌ0|;ĆnZv"'d|F~ZNgqm!}+cw!gzG ^oD3ݦH`RM|y~;b á׸ `:mּ'cbq!Qjm/QYӧϊ[FsK ^i`ImQ(([/aw%yO> lr zlrȆ/ N.تd7i3#[>˿1<9_wER"fǻ2wjm폖BM<,Їߒ4dd5έ|u=mԡ$hqdM9Y:8zF4EڗhD6v Ε';WK7GĈoGuo*ܪJ5/FןD|Ҽ>PB1s{SqPR%@袮E8&&pdWn'-6ݻ$v"L"X L))FVG|SdaMҜӚvGύ'0ƺI@S>ל ,uQ]ymSi={Wz*ֳzQv_g9ûJSPN<޸O6{]Q/˴Jp3f 'HX`)X$b!Rile%7+wp|k^rN"4ví5u^i L1vCo`hؼM/Dj @׭xȗdT ;[&2<}QSdnrĻ ,]z,f_, yޔ}Zޱց/g81b38T:% #ܶ v/EN>v^ 1kck)V,u#V7&p,`d(ǤOfOovlhsWV"ܾB@wbN0ƽ܎1 0k楡Ӭ~KNN7.fj+zץ,zza.$B+9;N9 ҹ-jQ#9&+W\Rl.N,>E~D(p7kO(]57phkvVӕ @w`nQ@rD#H\y|YżX)ޛ1%6݉Z%5j),5"z_\1.1Y}іؑ#H{ХH;3|JּK_iU S l+Mwaqn)# jHB9pt44`[ z8-LF*U`츗ch޼9 I^TZK su2%ws)=08Ь8␦ 2%5ŕcָ)Һh#]wVl^fq6ș/ d !'ޠqnx >?K$taw;@!jͦ"-%fTsC#",-iu8+- WD]K|\E_v%㋈SJFt`UUǙd7u?xb nid'cIo4:xwm8qMnic@9NnojDy!ưM1b- nhF bӰa+b$!m!1M؂/vLlKOBL22Fd${Ց24Waz6uHPi*,Э ,8S[ $S`^KkY$MsZCvS4`[!<"$a[xuR^~(^Iv\WuNrKV4]p몆0C<ɤ\zV,0 c^Fna٥س8ca8i4|f"Noܥ%p H 45Zv]uݴ8ΩGSܰZ=Ɲzt J]-L%J6S zzߖݜEU{WDV 3]2$,BaZҍ@Hl!a8ƃ:#7g~6] -”zv#ɖ֊!WuͣEk8[g9&.[!>N|i(>ጉ!zKgKw|9i,TL8N4MI_+4E^FXi=.iDDfngٯ,(ɾN*:}L0@ R5G&V7YTƓi}HP bInܹ=qw-‹Wf9,ЭXޮOB.:u!WxQA{CrO' v+}έ;6&~-;[VUCD! L(Jqo.Qiku4g{IfsN1+O2%£W^9g٧Z^.:Y;.P.Ћ>7_px`4:0j e?ʹBP BppʫqXQVDءjFd9K(})#ID]@ jjcېli Nq<'#ubl="ѐz%e-) z4]yN0N]mL R36UGhD' 񨍛5)sԂeV60(gnșP&*QR/qAJ!;#W$_&BlٍDB(ͪ@W,\  _ 3s+. 9yKiD%sJ PMg@ʍ4E% y=|YΙtZi7Y5]dPl|:H#ykǏ(7k<\\(befBwhBtI=u^Hx7'S1L[KJ˃ "?X pV< + ,\8{U} ZbqnQZ;6w. .pH2׸]$i5/f֊aRvorz ٿ BCFm%&_Y* Y%u-K~Ӛc=!A_y2+]>=}|d#y?x_V/[w׷|"n1'k{qł_~x>(7o_}W{ ݷ?߿/@XwIw~_ݢ???|_|ˏ?/~~M7gDHk)5Rpn),jR %Pޅ]+kQG c ߋߋ}e3*Ry_'AUF'N_$QyxM6RȦD FBUnl|c7͝Jcb@Ȼ!. \ ~E!;Hpll+`NJM8X@sS-"Jn;F+Pk&~-?ٳʾhVa)Wwj?$W]4C=& i*,_>H`%6 ,n)IxD6eb&ؒ1N.bK7gRrZ ]H-RKb+*or! y w_}aoۏן~?w??f_O?j*Y .Xj/lCBmO7&#h*hjIA,j߸p5kZbc[k qy:y;kC?}Kͳ~=l&"Xy>?k_暓)SlV5IX!^k&R م!{_>|Jg}%ntVU`KTk΋*QYUUUM੪"^U7WD읶q+x! D0Д0(ϡ^ b69Ek eopE?X DSSX[vqW}TjNXs3+JFcJK'6A(~Y1ʚTHyn}jHsS`'Z9'2v lZl/k.-g rإnqrL64WVho` 1n[L {LN},z5?asOWŽ^$+&M"BU4,ဂl!G%s-ԚXN7y !nv鰸eZz-:G{nJtd@`O753r60DۡBAtƵBi{@C)ywgj-vT}rJR%mb@ǣb+H4F%O"3Ȧd.+%P2lg6Ǿ )Se_Tbg%Gh@51Z`1mc.͈I3R؅ْ4maLA8# )ʆ8i]HËgQu&EW.MϚ] k8hSp@fsԻhP]zhp#TO.dRTw|m/%TZLllɼH`"ɻ{Asx\OɮU6âxnKS6>-c|%%}}S2o 4~(sqr0C1S0RE;zoNBi YQ"&HMx*C3+Muy/7p|/^5noVyNb6%(67^yiYXY2T؍+@8çē?_ C9uOQkxaC~WRz˻L;v1yYhHL&60 i`h#tw֓o;[cupi i&6bM4yYfLE[,6F~|ECҎ.rRu ɡ5dS6%,ZKWĤ\%R: dgRă@JQ>'Vgz簎k@Nī'|=%M݌w a.1T%2]gy`8k]8;Z|׮/3&TЏK';Z P[ԜOP*y0utI螷m Q_*A.HGh'9EUцDgvo\9yk:dHpC2u!SDKd_T%foE2D, ϝ<`DH]SѰ]q,?!k5IᒣT۞W.sI~jlÇ$I$cUbs ,~,vc~, r/&n~K{lpښɥ]\Y3+91SCc֘_~)*17.l<&ڮLz!pShD`ygټ蝂e5.OtŲyO5CʻW?G<ˡ`d3BBÌs$ ˓ uAšT̀|y,*!C(g4t^$epףFl}.L6e Qd̪4D@Zin鯍Uܧ/{[ꋤ"-q{.mYxp!)Wj'G@l=y5{tG-*q7eMq͆O#s)wѥ)0x1g9'Sj`pl1zκ7ڬzp/?€ZJӒ&o3^Ⱦ-j2TmY7_RL9)ջjY_ữGR? VK|Oc;[1:P8yyX$F%Kyq!:dl\i2O$0.y<{kQwMe~ޡTTAdžyX.T7pblbɡ`rm!7/X-ƛ/:EDpC.S͈mF02u7  MʉX7x3AnEhhD"0e?MbᕵQRΟ(Q«T.X?-0ND׺`| aWY \59яzEC2O<;#̏>W'6?kvXK5uNX z>$ AlZh$t#nm|Gϭl*,]' > &{MzuNV3+垘M܌Nlr'wa/6s*܍N r0LYswۏDgW+OUPvl[y 1'WElKwxP֓=~1gg_d+9%mQ!W^kNn閔 Ӿu#kݸpӧ}GɆwYG|6f܂ JT| sbrb$8d>Qd?€{6@a yu~3wVhy%HnPL<ud[(K;1 pxtt>_Z쎮#0sgJx@9 7'}ߐϖ f挈# N[kK:_98&>5}Z|B=1DK-EzPgCtMdq<4~@q(-ˀB]m/3W8ֹ'f٭jo ~MZ12EKjeZCLyK +}̏}t(vX$T vb%oJGÌ=㭠v%9>6yDp 3Ul.4Xңkѕu-4B]Ϯ}s*/ˇ_D; afD41^2Vy{s@pu8vgi= p y%4KPR I@ :] 8k$l SlNIVf ZʜD,odz#! c&'"F$r=u~'/\ =sg綒KdOX2jk8P2v -G)xfwPZlw{tʼG|oLbcK(>ž,s l@v,3E\^HnǭfV#E-IUSi,Kkِz{nu.7/9i41B#A{v)X/xt>BUߺOwqIAM6ފUS0݊5)ϙ*lLG/Z;wFbfmwYXz3i9bfP.&:j#@-e"tH_3*n'<) &af||(oP\raDg.A.6G66p$-9T"5 (J2eP&| /ig(Wtd*#JMl_nRgcu`|莛 J_uFN0sTGk iږm =$xo7.C@sWT]9 ܏t܏Y"ikXrPXCB5gkҲ4ا ic֫[m}e\Wi$˔8[YwUNw%#G$hvy?~?ߔB&DzteKcYݿ64Yh}&n=Bq'as¾"4 ]orzLE) w'): _O򗷰77j:x=k`tlO4I+;?/`TՎGMta5 :;+6_fVVJٙLr3f ER&.i\QcPi"jql ,#@okSg|a Q5/y"ud+;kM^v‘'<фc#N5Jeoa?܍7VGJn'm-s7\du(Dw,P_<%vO.)A ,_Jz.Ȋ\@/!Hω Ș t<[,y@Zxt~çl`_7[S||-=k6VhYҵ68e'T(At-[đXrvCN oD\r.e%&;\lqFmA 5H%ZT{Ϣ|@5 ӭn/ӯ9՗5ss(ghcTr̒y XI9qac06CUm4j oRl)(N{)u[*!c+L|w^ג/{5UȔG]lU}ռd pJYX { [-!W R_>Έ+S{݃ҼutFDy xir09أ`w)jו[k7.Y 2{fq+Sh:6XWd>f $}kHuie $ :Z>(u =q4ʆ:v,҉,%q^c25UߵL̕<ݥ-I$mZ(k;4c߽'ޓC]>=qF2kN(d>G 4j`;l@%]'S̩鄿$]E`.Ns:Ͼ쳿gT$'+(۝=Yp* 0<kłKx{ekeXPQddZ|6j\)u|j2'x,`JXp n ԃGH JoA٪X4A&k(`s*JLqb9y1cb60̊{N^U6c%&1Jx{rc<ᯗa7D‘/PeѪanG @4a߻A{cӸv~V CiEbi'ɪj\YmMfCD3j΂uV=M֞p55ߞn1-p fN6g]$_d ^cXms]v']en8KX!M7!Pf/th#ypA`qvrIНecdk.5l'ڞ Agݾɴc踯"05#̀+'v\e廍vV:I>Du pP܋)縱ߠܖ.=~jiP{ XEfEJ&ދd>!h|cz:+8!sφ8s\dSJ&OFq%UT,"U[% MZRiN@ Jjr .αK޹>AOr0p<x-N~);F63ȩANX힜;r;$J^}SK!yOt^ 4n;sGêĘ֠ChWmt(9.m=[seu;G9X76`Vҭ/=kpZ.Ѽ"i޾iLrHV a?^I7Q :\ܫmEX H*P<ȶ)$]?э8 b i bڲ5֝/ҌvY~J p;lqg($bOmԴt(M, Dӻ05קhYr^3iov@ 3Ks+5%oi Bttp#&Z#)^p܄Ky:/0=k>='ayrZ^נ%(C]ߎG7 GpPG!Y6rJO=)O<)7iäyR>dN\ԭ?7TʴTj{68V=0:++=Kܮ.=@_>|l$opժyKҠI+'MAT~&x!y4*tb.fhquM3/C-?k& it5s AwEG=$䮸Nb C0Nˆ!_ْb'6͂>nT 1*`֘ˤ"[V.Yʁ1&ڸqc|.H`<1Ʌ_)QB#d+vfIVјޤ&/rֈS}b{Ǜ$'c=9;KNY%idk yw N/9,{KJ;3W)rZ9, P% \qFi4) 4;3bs=δ? xi[X-ўd(y.Hvq0<|(yw!Z.\O[oS˞1Mྻc,tprBMwuj ! TM|#i>OUPt!p27˶,5ACD{ +:G$LT:j9~>bx x24zXzՈ"W| XJ|ؠ:9UC hlecOVJ++XҐ@#wz`3};"{1!ѐgma.+;u[\lF"IcsxyuBvWASp2),\[Jhvs:ehz4UriycsˍP"wwJ-gv s:RĤp^"Ev TL@_wr#%P6ɻfKчePg<)桘)r8~}SiG㡾Ǭw-\]07 %F>D^Q Z+Uѻ` ;)s:; W?/>)+%~{*\1G.sB8|w5zP̘щ՛l{ywCÖیV6vyQ )so@>!TS~J0\Th`† %%#H!yɐ`I&{DȨ; J`d +T^ ƅ3zf6\LMAgDmudD hq6CpeD &\$%yZmxtn< snhvN(M[2ջ)9wy)䩽&PɘF۾,,Ug, OIx^'\U'ZfW΅$='O2Ϯ\+R+K51@%dGN"K;mSTT@Odf\EY!>p qk"0?g(r! 㮾BC#!W|N-i%̔㙹Vg#I2uS=4%pu#tytKIv ;kqci8e;hhtwy}jK93G4HjDXk##Mj~O$X`n':K,{{izݶ7NiM·7d%QFgE8mo辀- FiS{ݞB 4wLzcr1#uVZ2{;Iv#| be.9 vDT&<*^5a=_R󒣳` -6 s!*^;r-#:gH?u'fOWX\'YyaC8Mw\RtO3v?I#TI8m XB8}zۥhcs};_#a6!S@ᗟaM"7Zs]Q;BdH$\Vv$,=c< o) 3+* r~Axk:e#WzV(|HJ]S WrZw3JeM ̓t ub 8LjḅpQxil^& IY9jS7D@8)¤\*ہ4ρv#"diESU\iCL!_5 iG{]9 ҝ=JdܭC Ufww" \\< CBˈ`˕6]:Aבebv#"%R/*t]8nJ?C3 W܎(ՅM^a/@;yzۮ*` gm4w"uʲu1նՎhL;A{=wWoݽ@$uyָXF@Ì^4Mka.eo ז YS쮭z6gw~@b43ﭷgA)n Gu?Kۂd$In+ݣ]Z]qN`Ä@z* 'R,q9 .T0 ,`H>$ZjȂ;HO =#RfgvΝpc(C%/sth\i Ypʵ4.swA#P|o>8Xuq~u-wp>zM>Txڋ\澕-DC' -Kb2N>}|e2՜3}6U=VRC7*L%~gy#iT1]>ԯul')[gn,}6B; l5wFg?|8mTO#!>Osi?$CUSD(Ɯ6~O:xS7nP«|:e:G6~O*㣇7 tin9e`m_y_e~ǿ-OCy|սUhj{ld%PQ[/c(\6n=5Lշb(4&ǿR{VUrWiHo-+;Xmȝ5RG)oQr9l@׸XC'͟IA'2ºAyss,,=SV΀;<[ O nBnutNpõ'gpw~E!z5Y=+*@{ tV\%Sh3uY;7U6!hc h)loe HdqX}q~ K^ⴒJ8 c=|VJ>xn+DG&X[`N睌v {,۪^4u!J^*\X| R kukU;3?R9-ҘTqoǬSXSwc7.DTe`@Bɥf?JRR)[ł4Cqڕ˥\7=u~U?oUA RT Ua |]=9VD,ZO4RÂMKY2c+%-ؒS-hkK=4Աi퓸< K=4Hѡ&;w:$(;d9Bw񻙌m*T566AG˴L[ˌ Hy|HY[J?~($Sn!,VocFED>&DItw[=?4v*NJStnv:A6{ (5\%o >⺭֑hB8:e×O/_I/p&J:U~?SIHFYedȷUF-"SF.(;ɴ7!BrN22~JG HM:&|ͿO?w?O^%R.%!/]qKJ7RnӸ2 g`UElmfbh$zYG3_SCA΋80?`[n2M֮RU4X%x0cYsQ2:+zN9\SWcY,$̩*<6*ũRM7c:]0^Wm)kkUWs,5W}E*ҳA/Xƴ%0㼚ӚR͐{!UViӧ>V9eWeE1 <.i0A-yPvMb7}+))>u=)/L/,f ˔ڄ!0LK*|!9.p`)!"A[^WD]Ŵ>b&"'PQr! OWD G8*=p[ѵVu5'Pr:3<7"+Vv^p$Mr $ ݭ;)^h in5drZfm9;|u( 9`85MK^o&p WLvr^zU[[r^<}9c/ꕮʠi:ud'(4?9MhQ!y^oYJX1yIR-kx|$WlG;__ӎQYMʧZ}.M2OG_N,K%Be)Z5m:]ihS0 7M`Ex &UE^0jңtzEQ6Q.]6M5 ˢ-dZ6^ V쾹׋N ոɦL/8FjݲӋX+8)% (5ku]ּ JC6.sCY* vYeu\0h74.wEn+V9ObꤺjE~u;[=L*k}ߌ(TZf~bEi4j^ edB `b+ݍbRYe+Oux%pR)P՜qF(Zm.5Ӹ˯n< U2ք2*բ0(&R풊J~U›9)k+x%p1RBZ)ZWL`meMbYwb,H) U3ߋ(_’ꓬRiO@D5 ׏u|M9X.xb\.5BrҶoY| C~|93}Bʇ1U/c>j2ԎX㫹mI{x-(P~-vAܼf50$ۤ.LU:)Odô|9\?mnfz]:`bE uqUvVəcfU袛2p=0ur(wr"1ZTQ)U,*MҵԼ'? LGUHwpYM)\H tA2&]/{񲂋]r1|$tvq̄S4YR_,wF﫚\eeӚ}x3W6 %I;.TKw^'%}R\&]WNX4w8]դM+o,tڠ>Tc[fCRs_J8zc-mNɾwN 6e,e9$@gJ2)7 K\^BϪ *SBX%ji e^.7[N(njX,SxK/9i=i/`"꘴a@?y.*?o ȷ7';U4vί~O!JWm8-[ˁyzXPQ)5Qx5rn[]`WcyoP8[y <Ʒ*1N<-yMԲ>&G4b$tsz›.۰ $Yuˮp5ocLdeZ/O9$iU"W4~N,`җ}=plM ɿ*N ݲ& i*X`ljQϼ@L;&ݲr5e Jׂ>bkv5ϫ: X3z8V 1RKŧuL4 MI KXMҊSEgD^/^ & 1[odv-Wnl/1}\6{ETCE.}|ndiKĀs񙋍V̾%8(ڢz_mfl1 ; Q='F__ h sT7H6a ،G3^LHU/t z7 Wk3n74P'0g]AVTɀF$+{}nOGKg<@tlH m |}Ku%)|3˧/U|V t%0mxrz4NhKBSy"t| ȟxGۃY[Yón JQ$\dBcLF(0(^_qy056"wIֆ7g-4y٭a$fH )C7Q6E%H9^niF Ԕ2exR%XjZY9|Lހ#L=_)[kW 7;E\ٛ6Mۃj-Vw=Čx.CnbޔAvi/_n^RQYvrCQvlo+;BpUs'U"z\ ::1|ΥT ˃,U g?U^({PvhT]_`g ? AJ>= 7"醜@#XTFT}M4 od e?/BS%Qň=]t6VzHS%fE+p`fxCa)[>"7Z)Qa. aD;!aZ_iR=4v(szp =Y{3"#obJU=ް[L* %3Sv0UŶRk.0Ei bjL?=*r~ƥT>R=f)MN6< I_*&.7c4Wa4uDi.9hFSձp."N"siԌ /j&.JLd~gbyxHiItP43}HjBX.ƍ[s 0@Ig8s$oiUuǟWw%nݭ2[YՀN$nB*x 4e4e^4-F`X2YF6_.669-O81G% L)XG:FQT)n΂@+}?=35]8w/۪aN_e oQRh=w1-ML-f#:LcI,_[Ky-WCoT)G',U'b:>1CF@=+ll,A6cs؇9)hrIy,O7 I`v9V}qUq𷱼g>ijF~ISX=p <+ 5aM|hyL0 4NF^? .\vRC  *0pLI$VҴ'OW)DY3h/%.{g0- ӥZI<23ӏy%E/JIN ;O87)EoͣIbHsywkTDOZ96|MX<#Ω2hmFbؙ$ 8CU`]%lS[.4lw5޿;A.zIԲ)e9[_Io>LHfLj tD!DFs͋A {v1d1ŝ#MoWD,AbJb}Ѕ/4B%ܡ1ۑd9tZ^Rzכ.>YWPlzހ5t3 *.+g(89{We}Z%P-G{ -I=! лg7p|9LJr!ɯ4IJiQuR@% htډK@fnVpCJ>GŢ$'(r„)~0WcD6J|;N#(V۲EJpfІJкV AvAc%F,z{~̿'AWG&yy㥖1p5谿e^( 2-jKz 0~|Njj/R h#Fh&~;9Q=<ŗ#؋,o32-9>Xr >а8F#zVk)tYӊ921{`@;}?t(=>41sttG?V(0: K{B֘y߈#K x:0Nn-:k` {,/\{$DbP~X [v>h^>r'8 /!QU@ʃS>; |Ԁ H:d2 OI1jCb!0-% A[t@\Nٝ${F!>$c0EXr>d[ d,&n*n1G}  C2O , $u-u\(cȍwI0bU ¥&%Rv)x/q71vk81xY<]n.stjt˩S[C>PHC2Ѧ:0PE$K4?AԿ4=s ISR vVsC)3.zM˜bET@Hx0;b2:HRB-.s Z1ǧ#ݪЉC$YZqdN*8h.@ n>`Zݟ ;rfX ȣЛt= nכt;)&ְ.b]}Gfe`׏c[c݃; #vrbE 4mYE<-+o3c!,cG3.M6?$&<3[=b<`CL7LQSJ AwC<)I9A+v+Ije?]-; cT$^b(RTd0[PwQ$"_>1"! .eC{8;"R* MtzJl| %%_M^)p? (NWH'(8cӨA`X?7-!a5qȣKQAz4d{bib1i-*v*r~?DK i<3X%5o@U+4Ao; k&RC|Oe7 j ^nvؿ)]tVcDo4SV'ך/=U]: wZxjK0R=aRDo$;gM͝'Y{%Oc T42!jR!KcEI'2`Ӎ dO7B ޕ7܏sLhwP.3R:ƾ4+uO|HyT .Ƚޏo,`hq|0N+P2\8i1R%L,`ݠ*Y=|4tEK*B+C9/rU$r*2DyȦRyACNɒJ< ܮT*Ol%co:?-*=Q 9Y뚼dvPkKf@“K&([h`0[/"A?3y:hTAX|u"_UF-2XkDa, af7y 8z8Q/Y0M {3?la[` rγYՎ(pL{& NzI@PJG(+6w04XrUA.qG9߼Ә %$L/r"u}EDmZM&=j>INY8wʾ*HZLfB3U\IW.(hhT%t% m>jz zZ TS SخgEIƔ s9>d_} )%)fa<0=n1_}8FP.4ۨ$%`mL%)0ڡ|up؄&6 9}aɐ:]_FӠC2J:QΨTqHPuV*FƯ.^~@T2J,7dx;L^lo>ܓ'f%Td^҃, 2*xǼ\d-,*UG'Pj%v)jD܊e%ݩw =OoXF@QxjiTUB[3~0j, ~ڨuP PrJړFe) !wQZь1+qX̴(p Ag$Q@6a# o^0>Iam^G-aΌ@=s[֛s \HĈ ?*>BCLFyPE (>lx+YnK*w@7njf.xz0ϱߎ-4dž46cF&9g?w5D w$_\)VؒolI7E},G)缐`jd3T."A$u.dT,[ܕ.[}X6pb4Of3ʈ 46Zpw5,Ihz{XcEj.`G&X*MՃ#ZزjڌƢ4Mz$M'Ȍo/x]00iWv~>!=@jēb 5ܥ)kqcb#n.v^)YS)``޻+dܣvYN\FLjT-갱::#nHIvWk,ӥMm=4BM޻ 1|D_>|xA洈<Ƙzvv"<`#y- B{]uz~*225ЪoXl'H5v zt<ܐ*&/ ?1r[eʭvsMRpDZ#MD}#v\oﲫފl#;n50PHSE*Uvj\s fU^jC!g\2\[Ů/p/Ds` JaEm\Pl#[5Di8ӑB *as~2W˳|: GUih$'O&vvжd}G8BF_pl=UL97׊}U 0w_#3|\yHR)(I/F/ gϘJςKgeE.N<ǟ.ivT:gEŢw"R}}`+!E8(-@M)v´a >-b3(`|M)/@5cŀ|ͺAJr]=sl$xQy+qz&WD%5L1.@)yKUlir}xt3 Obc^Z)xT 6_نwƖ9V8#v䎔CVLy/aGT(S#B2w .ZSaUIԋNYl:$oyu/d,O cb-o҅4Cڝc &mږ534tK{آ<#>$čMįf;p#}s(m-j/}c.΀Fsg{f0- 0Ps)ME*9[_S̊+H왵JЄa( zJ̚ YЭ"Rw & )R#?aBQRXRZ@3|= Oyef=6NfGp,]Dd/p4JeJE'-j%fMQjN^x͔N.Om3{i.M9&'I2Ē.&9nKߡ ЙtqRXƶW?ZLVM gjfFkJ6na]jqdр\m&ANY.Bn*$AF<^"/Yܕû}~ SK}nr[|GJgp>5WvY 3?4  t~r\΃MZ%9yaU# ѫ%ɶR\dcFʩTl 2\/ L?ŽRvuȓatbw[q<}3d9nT,תmc5k$n!=,jF#{KQАntajgIJPšc2;o1[d@Ϸ3#y#BCEߡ?}cmϘrPtoZoL){κx(<I,hH'#a-鑓u+yHg@^r4H4%,PJ' |S:f3nD Yj>(1_'`iˁgv]Bw+ªت{bPzK#Ega\6NpCI_j9?(f\srӧ >0[MO{})&O5Y7j"V>IbTA GҙL$LT*3~]ҦP"mzvf =E!FIm$$uۃ]ddĘ"T,}/KY4ϥ,^\ْ>}vFOY KK9؅ݩDL]ݯ??ezc6 ؒo_Cϟ?U#< f^2ض B׽s/Ϛ e"]2pL郓hp" P+{nWL+Wjf(,9UHH[IQdoQeB㫃X94lBe) yG!&lnk [-,jVVvF{yCvq&YUBܳLBy׮称C b*D[;CQ$aH.¥ LE;NQ2P%:DiQDZx(U]b 9P~[na[VY{\0QRʕ+լP UwI)N`(-_1L)L[tC-+re;ULՃ)a9DmPV[M\c3\\m -@H#N,Om+D&c# Hr"޾H ^da| 5 yŞa0:f\[J.vŦKB&*of|n39]R?#w57"x t`6d` r8eCXG=v07遲uCV Hw.)_ÚOV ؄1 ; rz zc!Ȃnav x3߫DM-hڰ[D΀O;rIHvЃdԻQa[qR"U{ VFs (܄,s.PL)_r2,I_RB!Hg}V/yR)OWd+,zaIӾ7lж}=#@dgF jZ&W㽘G!! 9EF[Z_>ہQ/U^VWueH2v PRs 9cW2sHڕl4@NkCզcI cm)uMU1fզ"vUGwզRdAQv/CsmRscRz+T6LayfI2'7m77 bP24uW˒|a}=$j C9H֙r7;ҞgN=?cs눱lSĥ17"^Lln  IxwBVZ{STY ""pS4[ZCDaE3>2Aނ>sKZV8FܕgqT5If3Kvt*w4SL8lv~JA̝W8/9FXf>,ۉas?[i7,TJl$& ]}'bF(1R¶$w#-qyEK7lë%|Nq eҬ+Yv<7A1 $qc"it[riʣ-;|2^3*ƌӌNh55 W݁qDFDiRZdeje4kZe-:>;DU:{RZ"kiLf[5ʶ^  N Pj0Pc>V̌pR':q`8qcr> iQH ʍu 1[ne㗏_>_2,lTBKʁ³tݱN UKiIx,/\Q槎;GLP~ΗāȀ-"G!߼o|o/y549=&v#QW :݈Fl' GvuBjRiߵ(ۍ*ㇴߵK{)@#a 珩l~wj j_iV7E Vx(-FAt!ؼ=GJv@RZ/p@릊.-0#;Շ3XDQ&L#p~kzοCOސ_b@1 TTUgzl^=F#J@R/G5PXJgJKēW6 6e =kհe -hu怲e=s=!9 >rE'lb(R}3"iY03H+᜹,X}(=䲽>T[5gYD9yNm9 S1?ްP>$G(.\oQ~r}mh3`y_{dgϖރQ|+}Ep.s:i980O!𔶌 l@ld4W9Հ("&97j:VߊAO)iE_#\2ܴ:wFts;_/[|939~Qm;Ood`{&C2%FcIY8X)-Z Y2_E:C$j2L5 3ԣˣbVo.3 7 b K\SIV-mF6o9P-- F2뾶X4=:GaD kDlnCtjsjR\Be& O^QrC<`_"GͪD=%>[01lTכ|z#Pv1{sspŷD@K}guݪ &/ŤHfSpS"]d+4m5_L BbM 4N'{ tN?(D1iT*%qJR&LZ%sn<*@ժ`HDf`a*2GpH'|^pfV2Uš-l ɀk^jss^ cݥA3L^vA"&ޙRyZ" ]EV]+S.C>\sE MG˜HlzF9REq5mlQ"{=EmJ4ӛI'=&tvyT=~?& ts13pO/^Ş$;vJiL;)-\Q+"I"+t)18=EtuRVۓE| jӱ"m&[v$m l䯤O1v8x+HĽ0$!vn5dO"W 6,kd0pD%QE;k>L(MROVvs?))Z; a|3dׯ/" ZŇo],X-E75\9k ^ ;IK$ME|| WI/ jHM>q-e ۱27/IѺ,h]ZӝߍЁ@ow9v/c:h1~]R!5c<#"Oh Jo9 mlе*3]]K[`'ҥhh0dɈzhq0,B(E4 c_4Ĭ_Cim]n@^=.^9}!678.zR']Dns *ҴB]1 ٫bd)YENH0@]b(Sns(v|.$/Нa]D_)΅Og}NZ-;'b*Y~H#ȈA@er>&_oEz/&3Ǐ{w›ŷSzL>owӷO|>߼y[Loy__;~o߼{[?o~wo??w_O?{׿|TkyMOo)|KXb)VKnVdtC "TbwC LƐc,1d I7ܺMk7-9nbA c@:=.' IOT*v#9H֛`lK c`yt#À)%G#bRBQc Yٚ^0gm/X̽@}u qBHVכ9d[<`_p~MFTs36DnKy#X^[}_)c}PR,dA cQ-Px?*90Uoӳh RT姟YR|M1ɖ,/s@r Lm L|(p]T** enSVjDYycz&+Yp|Gi㳬V) &46GM"f)fHq(y`%"P8!Ϗ1 ±'F4z7 [!Z:hRS9ձЂ823*0Pbݽ'ܿMbДX[9XRH 9$t*gt/EKL%GcnX4"C a<IK}#J̫G+Xi]Eqiũ];0S䱬Lו5υPp0/Jm$~K1!T]RL_>||y%#A'-x$Ԫ|Uw7|.-|4'7QJ⦹ *$V!؅\$niJ*<R?J 5 aČ30珟&[S833rt PpPP7C^vLr|8~R#K# C M#YRaTChOG$%)pAޙ,T [rж(dڰ%%VaJ6 󲤀49Lja fT,=*"-R=GͪܵMc4č ,Y,PY=X@SmΝТ%]lł!]hvlA \8?WӿUHezLftQ*95Y:&:d{vs;]~;,|^pn_23JƄ^>|z!Ų5#?Tn\ eD6>ldn9W7q5o S.g*uO.iJ.s)&~=~e5l6>6+Zdkq IPՈ| nn~u0U%j$Xy7 S nGWfB5߮z#1GG.*NVSkVCwR=Hg7;GFx`:(6πes21`զk_1`1L/J⳩*H\satQg8: -Is@Zy@_۱s=nBuSՄ W/ S:mMM:^^Nmi]թ)v/!3g]AdѼE|?|ٕ6ӻgiF:lܟɸ̼q^\5DvxF0N?:0ݙ.r@~ݿԫ>%])@7J_roϯ2ث[$DnyX~֋0t"Eݗ$kCru:}U]4v*c1]_qN2fzb=g{o[ ܡGEſwx"t/+- i 2KNzxVWZE.ծpߊz?V [ϔSa/e|R``~WG+d]C ӳQg_KQY љ)UI@_>|xhHSr4iFAz84KM"jjE[mVCBЌ٫w*;PJ')<&Bqkfn WCo&U~TFOb'PܴT"C LM)~I 6D=r&E,ctyUs/MQѩvg<fi 4U"ʩ8k^?sN 5[[: 5kDyB)t1EkDi0j S2IXϚcɁ7%R/hU L]B]?Tgq u++M >jd{j+~96&ƾq.эn]~Ee?~;):#~4uՄ0ާ->WCwlvfrtoi,97k07O*1s=})Ve5YqiPvdJEY[k_ŵeh/zخ T'IosPoĒs.MEH[MnZh*ꮂRJ[]j>u'2_UL'Fئ Θegu۽9$ݠ>z0`yW7Ͱ |{ -^gם:\Hn{>#u>7;+JcTMqA6C6jiC^k^=<Jެl.͟f8Pvq~s~ۥ;s0Ntzwg  f]6tQ&b5} i#xӐ6?&>F05#( ƙ,UK ʞ܋2qk{O`C:![\<`;G] 6wׇ bF8|{ꘞ7dpD>J9*t9IMjg]Z,mPf5TP1\mpL5iG߾_,m|p{^. y\8Jlw>3LՁ[/`<._OYj2M<*RC!ʴE~mg l4n2mwMVxT! S<5@Vca.b̾Ts(#_pH~p BP9 ~4Fq11վ➣\\Jf'*ՏbQ $s=HꝪ4rdqM-Q 9~9ql@}:<ٚA|3^1HHfQ:P,`p?FIeAi )>N'ֽ`Hƴns^]6*KI3YgvZHh0uAG;<3v>WL7Ē꜃JySW*FUa #r {05oOǃI{v7 p o_8ݳg(c; ? <7+RˇČQ$Wxm-yB!oB-YuZ-nT+%KTGƛ ]uZhS-}_]-c),ou;O2n<_1!(HwP!9$uCN8[p5`ƲBϚ.qǥ ԩmzS3h׹SKil75HB֒  q='@߸H{?Г*>fO[eѵR;=ܴ\Z2pޛ5[\{g׉' ] 0^<KGXA=茮U~]MH{ú/\VGdAS=4dIb~=@@bR;150r4T9=5p:ږ]r[rCy Vft!e%O) E_Aw>jQ~PՊjmz9JlZ? v5QղFxfkxؒK$鋄]0W M͚[5-T|[tZA7p!ȉ v_MsB:u f*I`Sp]̍rtM!䭼\h|<‚OL&M#\,~45P/z SvӼ*pge;iJϓR/ @hK?eyWs*`(ID4K'ONrO}p<;#ܟ\p9qJ")iiYəkD`5{m=filpM*dKOUbT܎ -pSZU WDL'xr1J"~-ﶊfzBшE5qR`uJ;H !{K R0tw ?gOQ10Y!2n1`)$SHy7 厯< 2Kx02,ڰ|D`*;O B|<;K\[7P>_Ը'DqsT,dn{sL0' ~w@,9sȇ:r 44LSIԦ1H%^1ش+7Oi.iАў53|&iKO1z,1*h!Cg| :$%d|"Aƍ>L>S]c, gIjKR4S:s؂FdM. ba %TCgTo7u!LZ~%YO)X0UiM*ھ螭t oxLj)Al֍PmxR) zkH]x8 $F `G{+7?XT՛v=r)A1cc %gY%=~a;tR-i ^q#q"DНV9\}u, #Gca:YdzIK_!0G?LKt<{.ZIڥ Go13inAȸ]B$(zˈ!|e$ |FFʠ9(a0y >(4ɸ2$~!2-BYA$f-@3w T3)9a%O\e|Wt 4p)O2= ճnvLM̐FtR%hݥ ip׋hXwk~ /wNNGa4\̄ft'i iGX$OAwЃbC*i''Oi%1 nAtqJ( Q5=xGӫp XͲs|6Nm.Ѓkw7$ϗppK(عG%6u4<~z.wOұịѭN=9 PM@vb:Y,e9SP^}Kp^G (l_|v SŒ08_B,#OYf g~goyZ vے0&qqgqlIbzT%N.o%'H#T^ d:TV(At2iǼZ-w[­2 e@G (፯V C=#bj1+e@z ˲$GOu#hߍ3"^Ax,D,] &("t$ݙ&`/ӓnH 5~/({v|-xI1])SWcԽ-XhӐ֨8zYwm,FXޚEܟ2zY faW=P1 + 񕾶/h-K԰!bm=&C,)]$+1yE)t';h[_rf9j HU>\,_ނҪ%++s~v[UK,>P\vTؽXs >9К֯oz+$`( $0Y5LR PA噁BQėhS^aNH~Ǟ|v'N)"iՓ\kbM&ڊPӜfv9<)05 SfX{*֩bI]L*F[W_ } p[5͑Q H_AliSia 2qk8C:O:#Kң`Օӹr_Ϥ g n~ヘ-ne(hYZ3 Y.U K6xYBօ~cDhy7L,K5Yј7]1*:;wcv\L>qG-5~k~̲+AlYU0fPRBJ`cyMA @=O#96zCsPzx]^5sI1K2 ّ!S+S['P M%L,Y-c%O5xV&%6NNK$| 7Yr|$eŞg,Rb,(޳QsIJ"B_9T׫B n.틣lhHX/keyCVقs<;;[Mh{`eOi6_%&c:'(e}ᗽ6igT3[&b얙uyP$nh'>x %WE0opL[`A{D*@@OݥNKP!{$elJg=W~R\ oQA,x[zSCWbhWuL/aWq2?Ǯ=ydIWv׎=K oG9D:9x9Ub}vc?Ѩ -Ȏ> N H˫p2"qxMpZ-?j{B Z&|% { 4nR7)4`Prȣ%6+*^Lw?, N-< C R[K(24@^í9p% 4oIPi-%r..mԴlI+3iZ\wL|\O}FTPTFbE n2p)e +2pwSODײi {6Rw>Iu3S ]dÂüжQˡPz(B~@8v Z,ى(q}BSG>N8@S%HAEb]L wD_~*b@ =Sd5Q6yN< zﭢ-^yyWϷ|J'D}r5R:/ LtwkuPIѰ_ҕb>Tڼѻ:<^n>Exīhv#ѩǛ䱦EJ\!߽Jv@r25؛\)m<\LN5;^3!zA~2Y8eWZ7;$3ږF=esU.Y8,ȝ6< 7)~*"ݹ$ӜΧgߏgh< NU<:?'^Ϋ)ŭ؃{jQoux&$녂sfH(J%1uyxu=|!n?Rř=6]^?p)>/C4t4ո$lLؘI0$W+ Bک?g.NrZ`4'pt1ÈM&,AWAn@Ekf!k ~*x0Z\rg /@^?k$mSK (. dFY]}~kW2s,4 <^ nsd0ӹT2Z^f.id>fathj%tmx˘gVR%J/rqwc #+a.<$㯩M 8H>z'>^ǘ YA${R W)Sv<|-* :Gt|)"Z|q!uXqs蕡4 aTiHi=fe|<F{IHq$ dO\b.N;8E*RF՞sƿ0xWOPkq@&}JGvu3ׁ_4p4KY}gq|9ծ!q.Y݋>z=e.ryn守# ӭz?81%s K sV XKjxy#\yx;)u'h `g^5|z);=Pϼ%4R'Q{ObkhS4Běמ%BOT+@Hi{¯D;0`8' 2'h(gNr9$χ?!I秬!tߒ?ܩqHlCF9|bcx f 0}QL ZP@N\$5f~ jRͿeD ]Q˅C -h541P .R/[h[-32 pQegj6# #JNNFAC WwAoʧsTY]8ik X.QrfH40x-pNLci~Vϰ B18α W{q T1_"pHq0KjlZ8eRD#ew*7{5zN-W蜞9Z/Y \K!BgZTdB9d!As琦6f Cw &|)N irP?VAaP ғ/Eڿ?_g$ ̿I!'&AL/І sq&(@\hQ_BM ,#5in6Pz;R_j3F-n"W^ "XLX(t O۟*Cȓ",}4?'|D ^(4Ӽ7vE] i6S)}頭z2_p4f=324j+XF-%{ފnq6!d72d>Es,В@cJq3]79]*sP!Ƒ6[ :-is/B<45d9*oޏ /nj)ZDę"kp90",O'VV=ۏ\j0ꯘ,5a%o7gx[ba bb ?489\ &[0B Ĕ[{uBkʭN:薹P <%l1&^"YU"GK d(oP/n ;CC'%ǢhV8rCyh悭he6 kPZ{ڗΒ50"J9w{z&@xB#ĥWȩ(FO,{4 0 YZ]r㵔A!374ѩs3%Hs^ fj&L0 P.)H)8}-p%3XΙZQR^C7lPQtwJգ<-t[Dciϋ˜6ki -ؚIYlFca't0VHCZfhT,t25{ʁZ ,8 1(4XQ-{1ₓht~V pW[yc-r7ZV&ڊU:g' ۂd=uF9!*/T?SMuJ]&'ȥ/SU0'*kkĘl"U*xEr5jABX8%{h FY@[^rj ")zT1UqK,NxV<]IrBȋptl)  z;CPWle<x4\!T)chD6UjDo*$ʻ~o @chа ho~lWrn+Dmf/ٯUc^&ޯ kq$YoaBdmIMjE([ZIn#r|R(+||dPYLA4`/MfFpam1ډq-/2!rp9^-z!q88ya$VtH^>VO۹&z{ 1Ao ,KuE*+%ouZBfN%G#T`Z{מŹT-ֳl݋kT֎;T0]HJ5ɢsHs 8yts(-!WofUח&7݉2؇A}ٌar찶{1rzw-yZtC&"]qxU-S)/g[&|˹y%[ɆW,TdV dw$_񙸬UryCU#̈́"Zń8JޓmVѲ*fx͒Q㴺*jS@lX] ֌%il` Mj6yU19q I_ ۹ӢcZJ2KV3YrxᣙGe*o -oa`[]n*ÐPJIj1{fwNM$5c$ Ҟ^;(8.O]j Ф*ŧ?ُ:n>Uq*MڗbS/3O/߾"KΚ)OJ]hwTY.FtR9^xVGN.+aK[\UTa(=Z`OzQpp寚J38Ay8摛0{*D;SIǡjkVe.L\n,y"M0X\b}rU=iNS5LaYGh ʥZѤkW-sW=z(}\5邩d]1CJw^lv'4ɄYdR"܏1I_6Vh, HʠT!#%{aiYl_!> yYa *v|ڹx]hljBh}ļ=EADY2pSt+Cz3FY~ 9^U\cY?qzz,5 ](4G>xu/av*qJ6&EI}`Affd}@Nf|Z󨊆s=)Pnk$K^3b<gͦE،*^Q5Je 49퓜>7v:ļ*Q[X\G# XlqU7S"&(C) r"c_jAʒZ Sw 4/d d-ލH6"A, ?b?v7RlB |^s\#Mg+{5Wq|*\]-&k%T|U!8AU.hd٫M^xt1U+8;`ȷ"ƭ_S{rRȀhEo[#EX9u hme!߻&9^bmDfbuvky/Z=MFKzmL3T+yhkRu~Ps6_ \C&H]1eB UUya|[,gsjp1iLɳ Y,̿^rĜXxx' t 5k,tC(Ѻj5~pf9N-p2CTwMGu"/dp~,/gأ]i=c `!ZXݬI(AK0rДJJ|;6j|oB\(l?T5W[d&Q:\Q1eI99Je'Bw"WJ|MxmN\!_-pf,/ bnN., o!L>.`. az-L-)>/ wx OO~aS9_A QxVs͇hIIg44U0E$߼`SݭqĕTKI YM$Ϗ lwiIG{ic9 ߚ*+SgyΥ:')]Á'Hx#a7(,T0S(Ṃ0|=)'7!;:f'Bӆ>MD\ R 0;.WffHJItXT%3s6]ga-$nFAvQe$/(iҭI, ]bTx!&"`oM"\§NanB&/aB6 +GS?EPxY8r e[lhfMY#G~gP^Q=Z mkt3}g 2HCt,3C|$*1VP8TgT\ i՘Rڿc-FsJZPY/&':U7F,''ļM7m _!g$YWٲ|L"d|?ߗxۿӇ7N4ɷaGfna<\h%1f'jg '^ _G٠|h;4q]}R)WPFC& 񅠲ϸ"T|+`Kѯ NLO[$wuˌ(-.e M Y ~hN!:8|&~&ؿˎOfr^ѡMO@D/9W@! LѲRJhOy^!(Er}&OeN+&s6%ȴ@&6 Tpv0T׻%fs :.M,YQRa֖ 0@z"tk:}H [ښ6%oLQ7ҠDž730-|gކE_`i?dtUpVؙ͟ÃX4AVM[1NAlo]B7XO3l{ T^qAvTx8ɍX:AiRK lBɏ6<sr1?-QHfZO%WĕJ3EHaB$ҽF|aJZ[D 1oC>=#5QDgISPb82wkxt&px:O2ESH軁 !ZFE5Bb];-iDg8jpظy?0h{B\ penʔjd !pt""mVm4T,_$ T$M=V oU USaj`iqґI#@o`+I`%{؊1fqJIeFYgH={Ȑtphx&q6'y@!s`:B.1pW(ê K՜X63[hkҍyHG BHE!E1X^sH:%@1mP[ B74Dg#VL#eqۡ\j ]@wd1J6\r7Yr~Ǖ b[HiFt]gB0G M UuF*4RIu< [XtpI811UF%9>S!FKa5!lTODbۡr*a:5l=^NOHz] H1Ƀ {`N11Iy73mN7KfzH3Ф2au%=-6J7 ۼ=Hg9=bK_,Tr+T_0(L)gU r^r,dƱ72>8ֈGr~}-GNd"^ !"|ɋW6@ d$?|,ri._Xe'?@A:YVͦlfd9a@iB 1Nıi* DtM]B4.V$CM㽍s+L:xW͆rm8;У?p2&h'C ZMSQjTDQ/)*+@oeL%' IiK nE<;XӓA}٫tZImJ 9i'MMZ_㊹z'mYzd ^R)ƌ+fNv*CJ E?Ȅ:c'jyvȟ;,p"#c XMrx,ҍ6;is$$[Ԑ/,.9˳d(Z"8[,&_I|5?:22i`zs%5&,t6jN$5>k[h&S]NzPEPvJ  hER؏<1lc1vg4%Д#JBxL:3ʩ1%)sw4Pd5oxTb?,ȣ٨] d_0sZ׌k 69/$>I{OZ#ό=TY[B ^r/Y}΂$ lS$WwzFD 6\{Jsǿo+Iu;miT)W`i喹cOak/6`И[b S8U7u'eH)sU*ZNC+&It柠bV!0l .TSxu ;7mxK{~v54h@W}Ιݲ7e(MǗO/7*J`cI؈a)\jlN^P>}NvjMIh_{xnLv+>2弿)\\b;ϽXb}*Lj3SRdޱ͓TߏkZXF &(XϏ 菏t3$Mc]XswI"ZcR6|r'%/3cyl=mRM\Nǹ3A9 `z*6q1WHj/__.ol@|52khx(fi)G|Yƣ^B ey)|\J(z!dsQ*e>01/_ޔa1&Nw'F‰Arx@2q\39IsTz s-*x9e=sRۭ0ӍeB`iֲuK' AE\CΊ GӗIXKHDۢx#t:C*Rx}օƇĕ[Ý' klK0HW fKOS&Qm_W+Cv?#CN@Xs!³YG0Xd,O򆑛syn#0xd]"#[OJVgώ!){=&Oc)gFe;AS YÃ)wym))lLSԼ8y]AkC@w&ߞ\=&Cͳ=<\rhҭ'gjD]Xnx#0x<{Ye|$N¡a.Mܸ~y)==ZZ&*g2cZG>;NO<&򣻘qP<8'{) R%Ardt"{hqљ%]&NO-4Y &qynYQ;tH5P@Ӆ$bꑳxBB(ONwǤl-a-֭WZ?%|"~^TYb KʨV1q2BIČb¯`ynЭ" Hi%l7n]߹E+= n %27哆!}%?BQ}\+'y;x"P} )ߣWrV\f+e^ \ZM"!FHAI^n @e˗M7EI4nڍ#hAq2'l0>g]ٻƉx[^k~=f-=ĘS/Q!!+/檂 H62C6=ڎP9gO#QJzF0v J ~Ijmk/nW_]ch lB kS8ؼځsSIAJ6&L~z(͵=pwWSHugsSLk(ܓ0 Uh6_%RslϮr@ۮJqEEaZ$Bcr,]=L9jl'$}אeRΚ!.{Ps#,T:ܾˢ.UC~"^U+n aټ5T(B h"&4%,N Kڕ;;-lEfRG 6уNpA? O ͦ#aKzPvlm2+=zNd[G[RBN. UO{<w8aXrH7T9E&FVOc0P2ymGu<;R!+P?ѣO;4RrFN{Vݎ(MMN)Ls_ nߔ.T&fK@ǓQM@?]8" IG%!yCl{bJML3C2N%'V_Q@HF05jd3E)Kg.irG{M%9lw<ˍu؄aUcOdrLy O|WBۗ5>8ܪD6wQ0n?QL^n;&-oh,IBFJR"Zj<<0Q#F0bx&O {f.n^w.wfP+tI'[mYvYG%'̴kz(i[= e|_q-s(e9H< 2 *|kX4/K0챤|'p. \=cqey o O|c ̀˵^3 u(ա yLe_@bRgE>v\#lYAI߸s\ UI+ҫDiC+W rXc po 媍~!;D_J-3r- "c<T ڢV%*"Cى|'%eB.xy.64'{fTZcE+,fU#AΖ}yc.1j&ĮN N;u f`˻OcpL,dn`dJJ$KKӜcz1IɝLh26MX vF?I6sYSھ%;`%irn 칎4D@0Q}P3WuDoChSYFәWVmV<GƝiEjqZqDf^%E ªu0V(eZg~2vlɬ&}@p4D7i]&XG DC6/{kAK«eֽ@+Z ,|^E'tnphO }.yǷv@-Q ZtNI܋^rUxwۼ[ϺLSi3el2M >˕ ۤ<;T^!Yf!k4qZBx in38<0A5RK1X1fDK wj5CJ>+fjࣕfy >tdF%8Rbr|i%SO˹D/JKE5B(A4sb=jsjpZ:LS?d;9Sо[uqmWf"ZgJq[n57[>~ H#w՞FVbֶ.:NKVYjx@_F̏ګ]Ē@)!.oM (ޖ#)/rb r»:A8 rS`*8[²Ӷ| 4Ǥ#w"hNQZ͕Nylj&=ɷQn-AF-&Ȳ^,bٝ j! waR}99RFd41@u dѷggr-oP:ˡGh\<C)]/Đ%a.RGN`Co,m&PJs31吵x{+=:Koh!H@P>I [G5 BzlyV48{YtJzTH;+7Vܱ /B ypsoІ9%BeBvژb=x#8||>~;/v0r]<)*\!z>f,.{!ԢrE$A̰w_ Ņy;n_黏o~ݧok&uaϨ0zBXU*5TabIz)E>FUnDʩp287z-sDusN(zM = ]IPd(n!PCϱy5\,_VswGҭcϿÇB/L_ 5f?CH?C) j%?B֟~wGd8~7& O&_FG(m،񇠒 u{?$1^AJhWI#zJLq1]c?4z?,er)%?H~xcc heY '7[pTdM"$="^P_>bC#ƶ1S8rHlaByBV]24hfJ#%azV5E/byﲷe,Sm4h,Ej`v^ĖZh"S4vRpLB &T#r%sG{B΅ȕ6bC`P&HBSR),AtGUbr(6f(t2*TPwՅÛʕR3. &IZ]/FmNJ=.8pN̶j%Ե LL!BҸ,R-vZ0KA ۩UAKQ]IHґ5 '[D_ErRs7O r;%CӠͼ b]j)˯Yrx oXPxАV-ߔF6בeR"-kT$HJga[*eyHa)q~ sf\U FJ80ɉ3|Z/1Ry%~K$L7x-=vOߋ%5(pm^0)aYounM`'BĖɷz#XA%VIb{їj%1X5D}懺'n49NnCv$qz'k=Vi%)̋ϺuF"*6F$KTLQz],4w1TJ EsǂEG;[|Cݹ'zSGk£}N@* JB_#tW' @9F0_ [ \e֚7ɡg$Ж]JlGQp|BƿuvK : R"2D2't:Ϝtͅ4!Fpk>peMг%"+j˫zuUzJQx9!U o^H nup,YQ@vgR̲'%8zx٩l"`8[<[/|I>HoVKį4 F!~"K\3-KTI;.{F8!Dhe0(;z&S R @(-ܪQU ЩWݱЅrƎb(3 IT2t7Ɓ2P R(L Ti@{;K^ }D(4# <,횣8>7i4x˝Fާ6\赅KgȤa%|UrG>܅e_-MyOg)fY*,-}Lƒ K,vLJݓ},CU5ty4-Ixr}4Or}*ˌ͂氷RɳG#IXFoY`;& g]h/LhA5KL!D_եR7ym.6CoBIGPbElU3 rٻvki85qڑ|T 767X.U"6P.Ab%8T%la~1f9zE{띩pn(d̍\34.2RMHX.18U,88J |_1YTḱa^kw*8E(;?U&pzԱWuJV{_)4xb$lpX׸MGv:㯰jl!#ĎV8nN1P;}l$|UlY8q&|k:]1s)Caփ\"&迮2{r|%c\U х3p~ge!˰#.Xg>հD/Г0 /DK"9[\'^ib.$8^$e^؋&oΕO%|r|J% 0|2wGqG\֊Rf;Z oJaY OJ$< (TMqAp+b1<|. Ҋ^.f izi$Gz .y`wE'>v|k3V\xi@ޝ`F1e{3~,faڗ~Yh$@Kӧ.+ա\zy% /tuWhUgH9b׬2nAИ16: VXW^D8BACI:f||O{gWП{'MOO3_=įK (Gkpd. M7߬x*rx^ o:1+ʖf4イJyqO#s &XmLysNas޹8NG ́v r0T(,RdSo\1˵,}avȭ/<+N\]^vtdPۉ_%sa͑k ɷdY^0Y+1Kɶ62y+b'Cj9EbCa^R0Ay/=%أѨiwN'z{‘DG%'1яNrl XgÃJQ0nRʰѧpb@ZJ*õ2K?N գ!1_̽p>0mĎq.'[e[k*l% Vg)Pfe-XKr^'En3<7W@O b{;Жb\Y |P\<,%;o{܏spNhHQ8-A nʦ4YW`?]c($n1@KԨ UP,)cs92B^8ƹ)mBӇyB\ѓpul}  \AIqCv P5SơB9*]xM \n+b'HS!!f( ZY=*-3c-Acwb(wlERUrUf;c%P϶X2lL SRGY!9󡌽E:^)fTjqP i~ ?wGƷ~YxƷo!_~_~ǧ?__~ˏx?ۯ_>~*|]wЄ%ד1@Z(@6!\W{ψo~RXSEC BT>qaX}a1 9љ9r]TzKXR.!C=dȩ0!st Uc@ smIC PDmjA-%YGb0w& Y ,=AKfw "XLAqМ0f꿑&1Ä4g2Im fOnPX sI% B0dcA lqj茸cvvYXuXѷOF(?jH?dh^19qJO6[e[R: 1bue"q5P (w l7: K28P,w(#GPbħXF`O`V/ˇp= 8KH_/Eo|q\XwB1QȂe>%?C)WM6 9{ /սN\I-[=l&~jQ;Ҏ)Y0֞b!C3$>_f $@(GR ϱ sP8 k+Mhˤ<,YWAL}0nw\P 'N۵T:l۰ԥ)%>)>Ѭz Co PLp;9SBréL /?9 $:P!]<8ʏ{2jB#)S*I㒺ґUu"UgH%9#a0pTbea_v\8^Z]"zuIWvף44L4_*d7)ㄘ|+7/摽yhZPCQаGgu$iz5T[d2:bCz$L?y4l h-Rw_2_zR2X_#C6;\Vι@LU˦b?@ۑa`Ò$aU~VdGׂBbbN#!z0ŭQsőB€uG9-qM!+#%*6P 瘚xvdm%kPr[-c7k‘Yql[E;wm ߥ 8haoJ1Ò0o$@UZmSJA.at=Rh7}{CS10R|y&8rW\68mzt˖#Sj_v-\ dQ. HS>v`#3#=`z,iApLJnW'i@'SVؠ  E:7q7и 4X,8@?G~ u&G!?8sVmbe%SE4dKgFz5w ݰI 'O9]>( rquK,yP juA+YwY > 2B'Gy`l,O5C+<}(Ϛ]*x<1՞ cOUi]@ "͗nmn5@D ^ 痞O8@A idwD5r5%}AN]BUPK5Ю-TbTB͝TtP1Б ]+=D*'T֕w,J9}[7eBjp\oLIQS_^7g8jLyf M/+:{ь$3/y +VvYX2_Mw6}"x dLmE~`5f4RWȭA:H+t#V $ibV"­d_֨#uJMU{s ۡ>o5gUWH#M!n KWï;[!Ua( _{ [b$*׬&i”Jrh+j M%1VM3徎U+4Ԙ74EhZwunQ(5Z|' UNBPEqt'2%8p8{0ZNˁ֖se+)* KݟUFJŦScO3nI(Hā`/|I>=!j('}eB 4- ԧLof 5Jӑa466q1R0NE%V[(- 5@90.Ti+thݓ)!A&m3aa}`=B(HUNk<\} Ntg"̲8F.T U_`Vz l+1m!v<;J|*QzGpMXӧ(|XsCL̇+#ݐ0Udbb:2|L;1TZFgCg%zUɠPs%Sm~@3 ,a\DjCMR =PTzS =ovNjC@6As`h`LxY4he߉S{*u+-+>M'^qMlw7P|mڴԍoIT{|GTOkXR<q4.β:3 %ױǢUZյsQl߄DbCNn&Xuk/|J^5`'\OyrINDDЄ[k >#jOwy0EVµk/ 5ux2Jw֣YoQvt7Oru=Ԣ|XmR濦٪@ :y:iPu㟵Qz\`Jwh$2~4HRjty-@5oOMmP1mH]ߪ B c$$NSPcٖ̫4 8Y$\Wh7L30ݲ_#c C6{5[$0 R5WjJ *V^?Rm|3}qsbR~Iw~-m :ys=OuP3Qc~4;1SeV\^p FlbՍ1 ∿YIL Otgoy'_4EW`ZwI`NO ^%.jeӽ#ٷ~5V-w"8 g,|@i;:;g_g^ԻBٮfmģÀA/vUr4c ~FwG K*?LTxuSdEǔOY`èUhӠndڕs7X%y +E:6zfob8G|ċ+}ctyn/{ ƕW(|_BDtnOB9}ZiвWR8Yjze)ULV>^ ܊.SWt6vW2@byލ>eh٫R`5߉^7h}7 dHgRjW5f:d13<Dj^ `=)wӍOr˜v!sv{f !tS$ 0~>˃cRM4 'x.=yLQ|@(ȿ:)|,鑮dbڡ(~ ictD8O!16RXrȝ5D`Mͧ zwsxsaHwy(fkǂW0̜gO`=w*&F̹pNɱG {҅ۘ–ODD&#seDһ)ܧot4AsirW,d6֝%X噕S491ɠof2:R<1 Dǜ5 e:BXlc(m&<=sSV]J8yQ):Y6R3iθ1bq?֨6'^:Pwzފ3OQW.a{f@w&lyC0>\Qʷw'W4.S?4w*s0$\*AE%fhrf<̕QD>- ( Nhec77!"TLs#`OÓ= zW۞\>7N C^)lp$oi($ܭ0Uҹŕ.RYy6ʲp,g=H_`[`P`[x2>fxŁxWqsӺנ$&zcNݾ%nLA"L6u*VqGe7.-]N}I=>h8/ J1&s`"#Fts{goL'p ʎHxAHH52%\yj+) M-o,Z"-@{ }ò얰nm-([/R'7(|8%zNaIM}ǂ T^q3QTSuof+ #aE}H=Nחyߺ@bQzD3QkN6K(ҳ翈;FQ d5h\O=!x{xh0zb)p mO55qz]8 :2?:E)ꐍcAFI@sbLzh28+ᱸ={q @r݋"IKU_+!zW~o?eZi I7CC6Zb55𠻄 pQ-*8J5*Rq=\=I|WޖT[-}6.#Z:> ule\dMS]"k9+v`^]LRK42W`6~1!&f ++s6VO\2Щ[.jJWkx=ܸihy+w"V:ZVLB%C蕌(8@Jݤ-ĹFG0ټ!s Ά H;v20[HҬ@}[ jۯ);vpaN#~6s1$Kn&O]m#-rlnG8imE+mCѫlS4FZVB-$^>㇏>~zǏ?}Ǐ>}|㧗/egT=wC-])*3/Kf 5øKfhSʂ3aO5sDǬį7tpnnq7>Oǿp?O3Ŀǿㄸ?C:\M5Vq7h:r$bo(t i]yodr\On x|hCӸt^S{h ^'䉑y>0)Hi)cSp=]"|_oJk:[fwüéAK>ZƓAwa~p5DdAf*kg[ObBvNq=Uám ZQ0c,Jzy3)Τbǡʇ)5a{a9 b#ǵN0\ʜ=y3A:I >-~lB2qfuEf >Dp<wN^*f.q_ܞ©wL77f}\'ƭpBk d,Gc`~8AVE-NWLtCP@|,Ւzd,`dR܃ {'u5ɣ0{U=hǢɍfa+~8#Tn@l TnO]ƻ⑭\{qq>,܊A60ÄKgz=LĀ_~4j̒_>^PL>3=gdy Wu#9g96ov'bOC *=sBc -9d 8G0+ 3e& qO:84(HH9(Jiwϓ('-cqoRcn7I+^ZDJ 0]>~؇?+0%]Y;D,K_>|zA`C;#ٮ 0'%?9{T#tOw^~YI/NK_${gyx;9zR'P $ت6JGNs_2S0=q[!4qzЮKϑӊ yn)@X8P .spBGWG#g 拇i:IsY*6؃-4^C2'Ґ1b!ϭ[ no| FCclc Zu4=߶m%ɡF{HK2BjnLB05:Nܘ[räO>;-'Ka1{!z4Dk9p `lܑ Q\.ѯMXy頻b%o"կ6,Tg1 i.W!ج&Ę[<83ľ&nRM:Xktr}4a C^#ũy_<-Dת+rruiN%^PȻ;\JD H @0{-~"1=ɖ_ݼ{_A[tN8e)l əy'خsF!jjY;#a{ w;]Wr == IbbxxI|ֺB+|`ĚX~Ce9`j.8n-FsM)=;ʔB4F髟XEz2*lu1.JC!̟@c&IlmvwәYTsa:G]P]X!wZi A3#arW/h+tn{sR't_,bLTPm(غ(O O94U7_Rf'D~:oح) 7a8M< !`~ d%9P*_ݪd#ћϧ[U#YRbOҜ~w`I >}?.W>|~+h?ǿw/O[~x cv+澱Bé)ops{̇P1ݍu .t`$ݞ.0k߁4cH{lՕAm2}{xݷ|=g{xܼ"!·zhcNx0N5fΆ֞2S'CTqV܅Rō6[4F1ԟں ;|vGjO X^~0 lD}J >} 43ɹܹO?YSW=kUkEp|!($6#W*h jJY=;)x|uL{!9tE xxlg\Elts}@^լn@҈Ҧjn2XwDI=[wʇod `@'#14}EZ%d%r@גDY[M"zAeyY 3ZUG9>q&+⌆e>bX6W~ãH7SO)z5NEP3wز"N.ZOkj/`*F9CiS] y)g<3'=n$= " x]_%aT jN5B&V6awM'tӁwBDSg k; (dR̓sf(l[蚇vHB3O<͟m>u/]דQ3.>ڂ}d^<\t˻.X,bA yM= ʹ3OКVh-١m\%BU"<}#Rwߞh4~ۦ@)~W+2Xn.ɞ+3~u/erGPQWg\YK\l@ʏ$.&<Y@mUGz^O5An|Y<|<"oqH+w0[y;.NCE3E 6l@J4)wQ'f[*&"$I #bZ9N,]/+ sQhH7,7*jPg}hQŹG`Z\Ya qh-ֻ(sP]Q.lfpsMoa5-=ۏ?\4RAҌTp΃KA`+BK *#s:$ J-e:(6҂5 ϲi/6=c:!5K2SCx  ,$j}=Ž\½J^p^CQ[$+Ъݭ267N[ddT6=7dsn005SgMdZJGfy:5C_j 2|fn5LF6CDbuOaB+=|$ Vǀ*9>_dg74ƒ=i-c9V/7r\y%tVHtv̶t11%9WXs[/8򫴯@%Fu/,v),<1jy 5+ĉnU^@ӌ$d/{G3jX_+تa8e<#X<7s0~e`K9S+]zF3Haz[v`!ރ'agt>#s4x->VyĬ . qXq#L(nbB%,Jb&UR.S6F:=hc20PkQLMn *}|g25"{0y*I3,gH4@AJ@tĴDԨ #8V:E&8 M q`ЋcN"F H3f Tܮf49Kvy<6g_g0wg 2 g2wgm@t@aP,A[Y63v>݈oF<҅b>Dv$}鄁Spol~Tސc.+zys28b`< }|efY #d{5iC  \ӊ& tkKYy`%Wn(y֓-hg>jC*p5H$K0_'n+ X0_StQ3'ti%/%8NFJjMzE8 GQ b+ì^']vp*J|{Z7qʁ[;Я2~t*4 Q$tjx7 1l-O;4ʠz٩Hܳ4x6]'!Q@ދdld_ =3UV&1 W3h;c4ɣ@(Ӄ^ep;a|W'MSО:CԃP,zA; utcWMtI=˞ sr`,Ydi,Jnэ1vs Hx Nbc%yOGp㰰حq3=C,9;ӳJVA# 'Ga}reD)P<5D_~9Y༑W+xj5@ K4rcl{Bz#ڵ <BLd"C3x|ʼϳ'vhuWGX?Y@D؟gՋnU`L5z`|wk2  CHOK֢gj+J(Zip##Hrpr湯w,HϚ.MjxBLW&tfn zٝ113]v9a$]MWƀuJc;`誓KK$!=Ėc 1ʗZQ3(D80ȇɫ(I9CHOoA!Ϛ)[65#i{4 ^=ȚB!Wn'wthS7}8(m<;L=;alѽ0|y(QG"aXyRo\Ũ4fOlB`s\N2 &VrA߶f$*gq|uݴ!K]CWQ91ch3mLܷX&_=Fq]wB_|W'iٰ jV>J iKr*Kܧt. erړyƃ+e4?}$Iy;_yۃ7|HC)4^ԏ62,xoQHc b8@7~,ڨFmT D$,pB^5q=fö*Xluzc6Đ}?Os0 a_Ua,&՟N)v1Vstl^ 蹄dk#f,ܒ].k^&BS B!CjRԽb:66fZ}ƮZdI2PGzuxNز܊3qz}ȯ^th@*i=(g(_$vE7;VkCBC9H[ɑWN&㞙8l IRJǂmI 5 ̏7*RYkZ="{[E/@(KT 2גkY٩7ʐjL5 XMd7@TQjV4x&7*c, s,M T;1L{Ty.d`c *F/UyeP-},[ϲ?dspI^̭beW&R>W'X u75_PHr@NSQ@&OD/b2|(LU^>|zˏw?K["~wD?p{ӟu7$|?w?7R{;Ӎ]d>ïÿ]z?_~/?MR"z߿o;^w>KowǏbs~!n%/?1x6"~/7;-?~_o~_ۻS}S氻n^(&7񚭝8٤MJRȘڎyzf/q38v2r7g0puȪ/2_^|zi/2ϱxqAd~79b<>?ZI #>Ҿrጯ8WYFI7q OXnfNV>iSw.rJ$M,Qi ѹ||q2EOi^E%dEO.z6)zJ2gH-ǂ nK;铁ӯ?_~w_@-ѭ@JiID"ܐ8I&wcG;V%'4xUhI1a@-{.hGKB-h9-ܒgKGǔS4@=$i,SBt@hJ p0.l|yPihBCj+wSBy+yV/]BƊDϢ*گ!i>a{K[x,x!H) cUɕFqt@MU ٕR,M^U=T9dA&Mx:=8b{J]*%/_]rB!nFSRR)[Mx݊8]aS59*MF)]*rLK)$$&I1<Il(wS}rS@ZkV- dXVGgY[0b2S09RoT6JSp7)҅!.jy55qӆۼ<5&DCQɷl9OF)/;ț!cTlc40\ i o߻aovgu{NBڌiniL>chuD |kVXrH+䓇 PJ+ߊ+FYhژimv -vvBy 8l`p ,@_؆0~``ji^rRϳwq`NO gΡ\8U+?8,ӱ<kEB ScCSL9oS&0ӵ- O1 >)V<&CJΡXod`ŶQYܧ2UvOMv%ˆOj3=zBVl~ӣwռ+&}dMuۻUl?~PC-}{&OJKQ>TUP7cR4 c+Ur38^p68\.r'!ghL@U@Q܇WJV//90=f1%a}bhGoaSo'COF΢U.a\ V\ˣVo):-,Ӆc`?#ԇ| + bm{"I ^E(v ֚#=ܧRNдX ,b`\Y@X?9UhSI:/xxai]/^([=Yx )x ޴{l3IM&G/-ӍNeOt$]/OXzb~,C;7Pd\%%ս]E&pbh=UfO{asA&PT@`йXtnldTr|09Gh"Ŀ뺝$8PqXwiᛖ1 *u@!cuH@2[*zc:R8z(9LL Ȏ`1 URyA28@*"cJWLqbBK#]ܠhqIfI&f嫺e9@"JVˬ.-x%xzIv!Y7 o9/K6g?'3[Gt 0t7臟~\Oq@%[,V5I*tx>dK}x{x c"-CђR:%EVN gAy=>$ lbl$w*su1`xHOWb΀Hp, &U$J =rǜysKŤ 5+f{N8֨ CH{JlgjPCR15#WW , ]D5usU\\h922Rt-8Uԥqk9z->\LCf 23? mB1-[ڭG**T\%CQ,X.nBYDSb/_>p\sT?mdW)iLK36CҖ- SpFz&jqWK*q8J  XKaOP 0zUS|O*j!-8gMx|ϚJaצaօ-:`ʰѧ8.K˗)5]y **֥9Gጪ-ԁoGzRx8FUe?~|G1|:kN1Jli jX!=]"&7RE"ZX MRWr4rGH on!e*re/GkV+jv9ch{7Pshd굊 <7ˎ! @P>-A [0osObQȱX+EޒW.-:pnj.)J) *6ImXabi!DU"E>K U񛖑9lbhR*Yɐ*ג/`QnW\2HgH2mon3V _NU#ܲХ.(J#'^aNG#'`kB 0V$kةHCGd ,Mn[ʵ7etgl CRƸ737֭rqDF,ot+R! #_dvX 4\m@hxD{j`**x 5p;Ɛ.fPOW0>b 'cvZ0x3IWHP=ܙN)8,fDXK 'Rݤ`;`Y{97kv?PL@4|j\Lˇ4abدjke;ku:@xhua~յ01?\$cyK)[.ֱ!8Q& Z ]Yoyd5Qõ>` xH4iF1xم#RZ{ (f$/tь ߧp)< i7A(ZGfd0 :p\z$`íZ{KBA$%Gy&j5q搧S0)2aZ&>dߢъ(eZִ9k#*MaLD^W W!uͮ4LZ6'nݍHuT.WJR)͏y&%)ς+RfX"0SWί:Js/tſWW|J5,Tɪa D4wIɵgHtGc Mj~,G ݑnقZ$]4 ;9* Vn2ɉDOq !MP TNYqES!5DA'BGr'XpnB@k}8ӍoRG9$ P!,= _% A CiћӧZdZ {!E 7|V6 ."5iJ7ʛҭlFυS*"lVY ;ދ<[Ii ZdjY`TG#ms@jҨL`Yn Q Ҋ뿣c^q@N ~,&f#;jOF0 v$sS !Fi{#׾fE-^2f5Bo ",3g9e 2me3؃ Ub*X6!( U+ G}2!npqv`bN/RZK62u|\g͙R7:֭$%&OHs6$u$pTY t%Mmg`\*eĦrS.`>qb~3I>'e=F?# }wXLV)\  A}pZ@q&9P,(i 0 %HPy(<4q.vq X54C Ȕ/xP# d:bZR_1~.<0qoS[;g*ez-7'Ml״钰[YȷObPoY3[hɦvI,#1.nCywH0_ >p^$Z9gpTs.MZz!kdL5b5'E>j@Y`ԫK]2TlO P=0b<È'9v).%_D(X&NJ5C3a{tkx8&L$%wnX [h\EZ24Gs3AYIt/F$/wzEhX~u&WN`oUF~pnJE`k)w ")qǸ֎5ǘdiˍ0 UA2sBf[-SBtj_ƱecK<_,WK椔S)CsʵTr~kv8Yf:mgK_7`23+8B`Oīg !rE !b@H0qXa:r⣦C/t1,>,6ΜB]<U`t V#!ήST+5s+| uU:K)EpJ*5մhy$,%N5ܚja;qa0L?tz"|)W0F9,L0% PC IW*k]j8GfK%VuH,m^#-֖o bMzT3}e%=5AՔpҷr$,&+Pr1H*6W{op3ŇH!hAx`aTbUwh%xҏ?^d OVPf@8!j 1uM_["$0`3Zv""|4\UK0xP=hG<ζi+^F zxe^O:wYX XFʗj%4ԆA crBD( URE]%6p 3_icg ('\hb -r-ƅɡ"I_|լ.1ĐeWд kR4D3|X^3+oB'MṆF/r^`5MΟT7ULi0z{V&^&qA"lv^'r|!~*r]31#r%8fp0 ϳć>[87;)`,P\ىc##/0"5ڵXɻv-z\E8|U`nb$.'ON\'IӇ PԄ6;Uad]IBk1tI >J7جr4 u%ly%b95ش2]@,^94B _@rxy71A8g5B]/gcSe$/ 4)#,sT p[F~|jqR[O[{vo"H9n(<̥bo`sm"b|XJ5\ Aݒu[jc  xROKJmi09~}t`Yͷb}(`U$>@imwDcRӷD1o l]{:y*7iq3X*Mp0buh(FK mW93.b 2֛D^mcC皏 Rq塙&Mu )҆Gl:7#D!,?"!HM$IKz<% ˖B" qe=a&.R ^"4#PHq?WL! &Vucx#V s%QP*'9hAs(=7V̓GA0]q7UЩJ5̝03z~jU)=r+<k*զʸE6`~P{?G?'9Zj>^1px(]<'t[tHD&Bd:QREꕬbbJl/ ;2U*^ign3]b%R[yF Jԥz zpUZ@_?$ R)cbы9Y dsnXXk6"&RmY,AWZQ`6)jlR%\˪{ɮQԅ~I;\*)S:h~y"\$2EF|ԚG.c9[(U i=?{ɫ#qn Jm||Iq)vZVJV,F~\GTC.SK?~|b,k#]Uͣ $Aid'<`婣qˑ A~|?kb,rC.?7?O_3m_?o٦VOqܻ"'tjJ G- 309͇sC,EZt"-,/  4 EW5vAw 29ga ]I<օne{㡽ef{{XL.*4Rj S{fIMSe=Y8=pѹ N=\mP0DZ5tu'z?a8Rj`[ '}&g&N{ŐKⴣZ'ZӾg[&Oʁxa|5?لn[q%fmW4g!~ y4r9GT j2LuotvanGK+T7&yWzmAʶK^Nv,W?^&gG+)n_Knz* F,Ռk2 l:;nϛޥPZ@+6 ZWA8r.gGgL&*֗/_ [dҼG0^6o$TE=k8ܫ@sF6yR =[RՀcˀl3|yhʀ͛A,~Z/e+LG\C2 GتģOzy[1a~Nx*.>b+ff)Di7E^Q1=KY,rI8U#ÑR1w4`z# jֲ# MrBK+8Q 7LG4%t:=C7c=]f0+\pTls3V7p>1dʓw;A` 3ULf/'s#euI{</Cu0[4r.iYY3YxzcY6[si-4u;#-~%<54aZmC8B]M/U 콙PK%}4ǯb{c=yщ H?KOrJib̭z14BS̛,>=+M .`s3'7e#pjw/U'Ics7QA![.Bh8\r2AbG#>- fbx@]TtePECP'\{p+=pΩ2hm%|?|?} :F 7?~Llأ˹ºv TSXwy.>C~SJ%z-';|_::t@w5gGqc5!e^< =FGto4%i3,Iͭс$ _Q>!]!@{<޺,y:Ùߘz(W<Gv_D{hgvo4ܡ,ؘu> bev8xq+Mۜ¼5peC>o[<*Ѓy5A^~A({ZjX[ ؑ @*V(y]C56/Bf B<Me, |4x ( hx { 4a3 BEcCVX%< :uS=Xf 1jh هp~ff.6^堰kj|Elo;u:VtG-GI@ύ&Ԑͤ[& u:zj@z9`S)tLY8hһ9|6p]a6`pc/~LU+s5mk_ux_,꣯&ĞmkzC7(mR%43Va^ !!;LL`F3Ayos5 \ӔsƗmڸ?Jٸ0ō,˵FOrD7Or/{|*%akLYpqh<<_"s.X( =>B I9h>N.6U36SG%=0MFNmB'VqϹ AhnqiF=yfm];Uӹ[%PYAP<ܬ:H,_ Zo{HF#|rQGe8R牐Ѭ R!8mirp ax.P-r菱$nL6>\p$e!mW"%.8ÄHvfe`~B]A[FY{gsQ/hvVdɅנ"f >L✵&.ZE$@&mh򦢈 w@*< m.Zns^iy"6t1)5l0 VkumF>rTfB5+ۃ5 HkT€VA'Qc4~bb 4ۼranL(SYp&'e`4sdgњ9fnk;P@J9~%K^:)J^q?.(K֗/_&l+uf] Nz\ =Nop▟v?+&on)R@|E/dY5Ai#2IvZN`} b`y{lr ya U x]PaVdKoN0M,yRb7jy9pjBPSGg' h-Hϖ\1'5#}jVl X% nj5n$vCo1fb4@3_{GF/W K~~xJu9j^|uK.ˇΦ&+ip&*.SXmOd^A@}rNi .Ye}U^Ul%VrVZx:n8%P[qTR)FdW8o[L(rFggn$dnzF:؜:Pj"LJn+)ͨ#V H<f@4<(~u7q͸1%VU縖R3Kݵ 2 0`K*Qҧ|oz]u|hkn4MLQQfĥ;$\ n#er9*4l>VD;+Jėp! *b|MD Qj IqW-#TW S 4ҡ;uQ@±|nbsJuuOC|7cFjgW(:aM%@nb js`z 2 œ|~~0{߅e;2m:yjO<1HuGax,&C)\Ha""bV$Mb+“Aһ7:,Ftۋ=ASkApz%-Vҳ#]`[ (s' a jur+&t0)ҪXBm)xË8zVѧP{ԠQ(X`y݇Lh+ LNYCTWꄑ[ۉGW)d;gg<u`E-[>{x.v6̊mb z@Oz3w_ui=[$!.s{eaFb38Pݧ@AjkM>R $`Tuk1ԪOSw~X7.@~ =sTvqӋ$PFFE/z᯽ {'㺣om+X33*%{;ukq<9~=)cer<IGzsE`=}ipLTHe_7HK'晻ʍmzdGg);:o\Y)gReW.t8R_!%}i2p|&cghxzBCYN$N=&)﷥J ݞ ۨDѶ4ytmfcn\JjYe([R䑊-/[O\GO'p;ځ'a KDT ήq,"V'Nq U$jT .aPD!GHS@3&ACW _sVN k^uMIy˲J:QۢqõN *_$;v⩾Ku<}:5A>Y h"{?e0O?|`ҾVLjiR9P!x71K%9$"Cؤ&K/\%})X ɩ\jp F޸,ō7LWP%N:DLxD@K>K'(3DzK{ ڊHܝ)p)$`#uعƸJ\zm ﺡ>J=KBz+gXr!˗@`;8m.|εȞ 7c^'0`xP^# a Jxjb[F%.,NA|N+aܹxQX.u#^4V"Rf1nza_Zfm#A*PB-ERȇVj "R9FFNXVMKn9,r no#za[=hTo.x-ԢmP* -벣)rM:̥A~d(+NDA}^Cb<÷E֫]E.Fwl>Mxsi{}RKʡeDO/ËI\:tAȆ+~Сao#+D>c|rFO U4wqhpՋx!oͧ_o~_CMV NDspx0%Ԛ-TPrTW@4uAj--#pP$W57^1v(%ԱP/9jlRU qJGY>#Oh .(+^µ48ZSԡ@Qu Br7G8gE3v/W.J.9^ "c6φIW6j^rA h~"Aұ$4D#oWmL,'uPfa<}XMͲ6C Ct8dMؒusJ`P!KURr̀fu%(= PCejaQJS ˇ/IS3\fm72jq?!$yS<(&aY֍38Ktř7iV|a?a};P$@K@Ad1Q7&TBZ%qi׋L%j*XEzJ50g9l| hcۀr P|txcsHD0("6ʉ|;AN59:t&V%z\ 1w "!p!h5ru\Ѳjf l+͹ͦfJpb=Ksdlk@5ϕ%ColYuZ361".ʜ"Eq-!C+%@Iצ'6X@X̱ [{nl.@nAq`HA<˪+. XfG/s\l5 OW9;5h&nO}9CySMLL.[ّSm9%"gLcB.#,f|j !FL"[:b6"o&XvIg3zQvigcXgO2z CS̭lI3S ;X7.0G#&SzN|$?ק"Ւdzo<|g%Bq2 HX\׭ם+mxq0Er z"ɣT-Zk„p@ H~@4e=]ꂝ{ MEúSnb\0%vY[RcT I}&^T=b,.u,;Jɒm %jK~#、U,H_.lM.Rw \9<71dAQ7/WdR:񖚮z[0;4vG_Da鑔b=]Ԣ$ݣy/rz(0 !wO?j-ĉjݙxA:x5ˇmDO~OWV?^1|<.\"fŖ!J\@j\@#]3|ubp°=>lƘ!TSIrN O1r]t"mWɆ.F=ogg'1=`f4B$@[+4Jb2sce,@[ls#͍ :QKce+ЪxfbJ PZeտYYr+D@!U8͆rM-&QAH/`\4ꯡr~X&ښL'u#/,~@9:^%LLX3 6b>c4 :+UM5f@bc_FF,v$k;[-SܢOQR Qa-^SJHT}z;>B1oKݠoOdlMHBC@|[Ǒٿr\32<Ф`˔+xR`񃈼Tuw1=C0Cdv/n|'xՋ'z| bOo}}Ӈ_?od0AR\K'KWt&&$SToR[.R&&%eل 7sR%bbk.*Eٝ wB,f+2I争O7TG4KUj][Qʳ xxU1^7D ~уB*>g@ Pʦ۷/^>1? 6Sx|ÓX ~/___՛7OV7_o߽zퟟHʏ맿}|?O>/+r 0! P`Q#` v6[! ;vn%WaW ~% CCH~jm4_79AB@8dž~o q^ +A^P?wGzBы?pSfKFv:<)|׀ z; j*5Sڧ)IW fi9v{25^1PBiOפ}!}MXOEɖזJUJtإ}4i,wF>DlwXng%;8ƶԘ]Ar푴>KjLY2rHmT[ۑS~;4BŀgO ]-q2<>T|PKSҏK~D|UU CyjV^>{" ܈T-z(cW+\7]9&+DPN%Ēªb%KE+\6ѝBǥ\ QTѐ.jBZ6eG#o`D{`0QMLy+z[P H/p(yܛi"fR$Юy 4$BKeZɪ]2K& 4FgJIVC7:x9cs&,qQJ`cXu@o>0r#eڷ<}oU+H|5Ccv~V\fBա&|Rof'|r$|EEk"3t6Oz8C'5)4wIt$r?pyNCV9U3ākOaf$ZjchT}Ջk])(;%A挧WĐTi~=HlW2EЇ%Vŭ+\:B\,'wS&'"Uge X1PH:MٹY (P@0pId`.c` 41G dH32xa파N;uߢ k(Xd -wyZ4 3K; ]ӹu.:U+*-.X:< @I_m-4."(9Wg$q ^MfBCIDu\KGuAn?45L0FYB_5s%#I`ɝn8ޢ7$J[F2k|_̠>:?AL8S> K 1C$-;j;Sm԰R(Wg@1ıLi\GI?8: 扙+ )4q5JYBu b3J\\6/QЅ/ݢtΰL]L6;b? 7VndRoAdR--@ƶU驮4[k5-#n8&!yxn{yAo_5HCq*ŋ޺`:Ap=itׁ'хjէD|%a&FP]  ޠRH./5_V-Jٽ3IB m|~VgնzҢz0XMTץZD@ Y9ks820=1)doN`RHvA)É\g%'J%1&IA&mGԩP r2'hR8h`:b>E"LO2UhKRaXmR|7a&vgYxv›)WV]q0M\غpH#+}ɮ=9pLe!<$G\h.nzH7g:g3U I10/tN=EN3ЎT>~7aD漱L78խF$s*'V$$poŠ1^SkR) yЦr4" M Vl{늅p_9H2w* s>oPŘPCHO,!n*@²L7!]Cc_Wcs^r B#J0,B +Ҩ {zXtEK`Hu{܏XB~?8]+p, Bm{6ƍG ˢ3I*4 bШ$ah) RQlCMS80*qG+ Fd)(@w#ehC`7-i@h+9TzpmTIhUb>jZu3*0 $.'$k-=~CD({[Gl *0E( WF;<ܱX^(XqD%l)nQ>raAg H2 A"uES%EK+HtD /I4\<$9֯& xD4/^ԔΙ:Lr6F”$|3FI {rT҈CZ=ˠ(x%$YwGV& 5^?4̑+T4Ab;F&XkNR&*+'F ϒ & .AHViv&%7^%BOsA+l =VeҬotc0\H.G/s6g|P@_mHv7}\NPN_;F|rьIWb CQ˖IԕHHe>BCNX/?6ckFZL!#]Si V[ pĉa N(HuDDd6])8+Y(r`2o"}1lLvZ.T­&WC}կ|5m)ckyF-k\5쿕`ߴՆSgfX<ʍ7$HmOhkǡ^RG'zJҡn0t-iw"3H$O𿅰b=YxAPe[*uڅa":'nV2&&+Nab!4MԬeOg¬CKszΆlx0a,&ĉJQڢ"CaQaAtNhInHF)K]҂"U_~xV0#g Iokn79iYsX+)yӛOhhY &Ww퇿O~/׏}>|o=/( v)y ` S 0gœBo000̤ Չוy&\f˗3c *i,@;z|a+v j0 dys~]TZi$s` >)iVQ0e4^X]iO*AG[EDca&`paSG2EûRDUC6_IraJ[~.3fK0D~|DI΄ WtmS^ٮePҚ4쌒ty2Ɠ$Qx-jWOwacƚ?&v1GOI!BTZ'{?u.8 d1`D>"+z6^V@Pb nR;&Ix{F4.)GA<:1YqDu#)6y;Wxz^C-#ǎUe)ĸ v6"^[mQ9'zϜʅb!YXe>ֶV5J6d3><_z.8Yn&K@piR>}R2`9kiK )߽}初1Wq |>#T|V]IF cOQ98E̳ZbuhUR1]Ȱz ?z%_{^#ϬFJd_V9tIL?x5+m"i&Juwzt/YM&k9[Ia0Owi2%e,Jyfɖ8^zl-=NǙGã׽tmvM a՞Eޫ_]2!s,fq\ґϼS"jU&:ksv=#g\&ezҾ߉ʡB2J4-H>J/Q[T\(RO|o^eptVN vg/&{Vn+ 93 ZWGLK5qUL'=y..ul'/_H"s>PnLG+q -\RǑ^׳8sx"ώVqDUH#z{.dل?K.S?]ۍ$x%g`  -{za@ z`D7s{Lf Y\7x{XW hֻI ^ws\q|X=çW#f}Ăj6@7.%VrXP*g [E AЩx]aBU\ osr٩8pT|V&t7k5B.4h!D|'[r p=*<#79$p2XQL9d7 | qCA GDJFv1맸PW֍@rbO{8ּxXE ~KBˠD4mP\?&|`o]E>-MeeE#vr{ ƛg gV n/Ʌjr {ݺ)'xseօknB߹D> i]өMQ{AtdX^gaF 3?I%+q(zyۊy0Ix48otQ!6 ||2R;|_}9P8Ң0 4ف>I#L|«vھ:yq,~y*S- ڧ5~;f>GAXHciո8dkwRLy9hQx }`:L|E$5}o$ɏIJmeXP_=r9C b3gidޤfM7 3 BhJSE`!w w_7ix9Ṇ+$[O`#ywu$焙F'-z<O$ C?_I%jO2֑~I}:hl4$LPz+8u^39eUJW_n7:K%jIEEq̌-" YSc/3ef=G~[eq|z@Y7 I;a=J QCNY P5_W_{}OC9x-=,u<}='%xf1u)ew ps? K%M<Yê.Y Z:(fM9s{+#" \x.4*Z0 rPE"d)Kk H(X򭊱 Dw05u}tx=\jxk8z\__,c+]ChwXyZQP3Q/F2vVF<$cǕ8W!iإ: {]8Y N@RYW+mv_p\\ΗÑ,7B{ O 5뤚 x=>0oPf@hA=YIKߨteNlZ;,F~+̰QP-fV? Iu1^-'IJ٘N֬DZJkl:2"삢 x|DƋё5a0s*a`;!UN83Enh3nȒ˛G+?z]*DA.^佔}L״^|lZ(a'LqDG0BR.w ژ*eZN;xyYMt y (.\]uz5Y:gMarοejHOiI\>a7}G\fGf8|ctRsi|n[$I@PVwb $0 ֪T|d6n?'ɍ*2W!Pi7 A֪>R7LH1=U iӯ>ytEtq˽WL %¬X*xEr+.G;Ag\vGFvh9ek+Ʌ`G|un8у8:Zi:M3},c痤MNX.SӼ1TNk+_}rtCnY[O*X6R)Ndkp bhrM`=c8ʹQ-d[=!^eg',M%|жh/08 O[ .t"z-گ_+b'BdZ zͨ_aХWM0JFy-h 7b18%u-y}V; <Yĝ<+u]dW$}`):E *0lj"6? BC;Q?w ٹwRO Qo5`hY( 9[ͫaC;~OeXO%yNgOIpzs['2m:K>N8f3ijM: S9D8v0E%4[/$MB~b$K:Β`-. ̎G%X)05W>å+i6Hʇ&X<]yvOs%ͻĩ9mqX7gn?eF5c5LUXl:DC n%%n*Gi"7(*f;I7'z:lQi` )>! $=@ʕ\ڠMxK3a9.v/:lh9"B`vAH 9I7P~v 6l@[uB[AKJ~R.a_b;Y.i*6T be3M$y5L·Yq4*4/T/9$K<-I8N`dc!tySv \9^E)5HUl}e1ێ@M3OJ=(Û&nTbќ_FyE|1im|&lhYpfջgPyq.f/0F('f={EWM$3&wJm6/gSbm,XM}//kRbO֗= ]nU4C)!N%lJ ,etbCmJSѹ=VT4ϻߕP`ρψ7;IbvRi!@7;`ˏo~ɧsp/ zӠ;JFK ݬi7WAB%ªaiJC25D*-%-yEJ ;|fҎ$8&5aMy\rU#\GzuANnI87̐@1 ;{q e9$fFesHj*&cqf]"/T"ET\Ǜz+-, kk{!68>N<\f%S/ &^b$Ra=5lTf+whm=`BݫOSYMgLLzn6왹Z] +jl -k}PeyqMF]j`}iOeXeDmVzUlPKt&,)O[A4=8Wa{tT@ T(C*ura 豓}f!lxXŶ#f*{nw.{N[ s$uG?58غ֬xTg"K^΂o0JesֆoQ_xbp%;VGf(>@=Nlhj/$U2+"ga_/p8Qz|-֤"+LVo+eɲbԒY#(h]-(A8=ˈ3nL/R eH2[Hx Ѯx1?uVuG>]n)>) g m&۬E̓!St ܢzHMQ_C&h}rqIOpos<Ρd\xxԏ^c3:Yφ9,t2C߾!V&? [MN;2z!` mj!,c cp 92(lKEܫ)P#e_Jqk/s,*kBWy  aIrB$Ɩ3:x[gI0UflR[U5uؙw{q=fsz?KĚr6 =,ͨ1f&MQc\`ވg\78hf5NZr#DOV^AONWx1/>t YTS{gsN ĒC[WSG",'KB5e%Ղ:[G-3PǺ[:(sׅϺ]tdY[Euxj٧Cߙuujɩ3`a`_xdi/*(6V ݣ'ȣ]Ex;U؜UazY(ʼ2f-Sy@LJC`;\EQ/=KSuE h^M~t^<wCd o!'bw1e.W6`ܛ;dS/c{me. #!2,l:pKrq$vzBtSo9߀c0;f zPr 0Q[|~X0r$vy|葄m>JIzŒ}d(A@G=-0n Xt9eT "ӏ{- ${W=^r;qLa14 @4ˋ^8'w9SRlMK+Xi'O<2tѠ5pu}6wVgO[ZB;9ŧG19if@k RPEV*\.q6#کE:fp6ks _5{l[V/()uF[kԻ-%"wR|K"o`S*t:wЍʢR)Xtm<-iud Q/tBۿ޷_ W*7GE,f'-w҈ i.W9kộ? eGy3E`oUC}mZ\{OBwFNѴV^<AzM=<23Peᬨ8ӮarFwgy)P)ҷ!@(~[[R8t).Ѻe`p˼Ƞ@qK[ Jk7QڈnTdS|ɮT$ &Շ$ݕBj7"Eo/|=z%1iI^f}hUw* !R@0i?N -2w}kO WD52DE \HZ9* ȟF d3Ox0& %ɟZg8~ha/ /rH{j)L1Cvl/ܱr$#Z5ΏYw(ꚻg5̩mis2TRUM`Sf-i(R~ R;nm; PR" X2oU燸3Xo2ƕ__`c`r-Cb90Qrro dYaɫ@yzWEn/pX۞9ZU8S;? sI]~b 4{vkMFɅ_.d:,:@QLy Wu89[ |uE ֲ~99䝸En,-NCQwU'$wkUCq95Wگ& >TBlWe\J ' nE Hq5\سQM S0<̞ pqlɝ—l.-7qBhAd8!>~F0k-ԧ2ۅQGkK" :]y„.NWv]0^PJ: ̓KӼW퓚ЖOz Մ;n9VRՓ6[#a)ڭUP]OU^aC7 h(6y'1S \ש7 ZMG?SŸ%[Vf R]SNK;#Paɮ $@T1}P ˻fUsm:WRS7p38(I\Lԕiظ/0QCsSd} >&񒿕o͕ێ$&5>m.Nw?D_ IAjstdN&c9#1RYBib{/o= U-}hktu*0X[Β g#]/J;} ,Æᴚl R!3!cxHv"EI1;iÃ&R`fy{XT&*Pk Z7lF/@;H zN `T㭾E-{ M{MQX;Y$+OEwTWYZgOY0w|ux>jsS-;%6 ڰbة}_5 6`iϹ5\:xI/ZREkeD/a JO?AAW@~ UifH\cK;jayԸФvK/vVbo-31 Y q˪AP);Vv  ψAY2oPO?/ZOV򫫥LËl}6]),u+O Ct3"EX+HRStM0[?ةlR'6AP׷P;MAT:"iXNyEIB枯'A|ēXA"_PHxF!N߿%lc_&{+QS#|ei7`*;a0&͖Y#jT znE2~zӁǐ4.n]pIy22 wN_5XEGV6~ R48A@{Yr>c 7^znJ[ŻɹnX6+PO-ŇP\5BCjض([jw!Z{t=.w>w4KrhvG=-yt'<퐃kJw/k > A&VH"61P13QT\.@ViOu];q&;br R~N]LWhAx40c gNL5ݫ 6a?]p/H ${#bBCVariantAnnotation/inst/extdata/hapmap_exome_chr22.vcf.gz.tbi0000644000175100017510000001123214614305321025175 0ustar00biocbuildbiocbuildBC}U (Az@hFADrDT$,mI* * (JP " Jaإ}gTuuC3^ާf״V\tQQQ]&)lOrQǒ~[%KQbWʖ 7(f'ם$fr/bf{rWh{ry|oYY͖+֊wٓ|"'!':)'/?''/h:7]gO1GoOb!bQSw6Q|ڔ/)'?-p^,'X*'_)'@:*V'XўeϾgc{ EzWaO~~qXͿdOni+*6',-ƻ_ٓgw.'+<Ξܻds\O]l kS[dOP>?^ZnO#sB đ݇[/-ǸtǺqqq[8,A>_CzLW ڻgړYlb={"} .v K]\bOO|˞<=9mMf'qbK]OgfMXz>-'{M>\/.q3/l9ŭ=|OW'-''l$'GNj?',ޖG!QdOH>/w=u,n1+}W'-f'/Ls\*{rrֿ1U,nO^7W,eOXڞ|aXƞ-=2=J1g߅?oOX|XўbO.UPmO.]McOo.8.ֳ'&ַ'//ٓ~'(>fO]e$6'AldO0^|ܞ|"=y: /E[&t_|߾ 6'Nw9ۓg?$'ok+':TleO 'o[->I[6䨯Ŷߊ-Oٓ+v'">q6AhO=SdO޵QlO|ZbO՞\؍ϧs.bw{ω=M=3,'G{s3'>,'ǜړ\ٓO1ؓsړwVٓ'ljŋړOuؓNJC/ٓ,ۓRמ쑤>"t=u֊U\F@ayeUMbg;٧ۮϟgs{+9#v'~]b~p^؅7cZړ;'?} 5T8Ȟʊmm>ǫ@=b7ӽOwKןn\g{?w)'Ĺ*gy}ΙTO׋oړ? .'-.'7ۓkf}}~ }\f~q7gnq멫Ezۓ'--'WOؓ+3kg5z>*'l,=NKnRo=U=p{o⯮(1}/Y'Ϙ(eON-mOn۞\~x=g/kN~ۓ_8#'ǝ ۟+]O]ԏ_@EĊ,^ƞ=޿#&Ʌq?` ^otWoןK*'-6'oOޘ(6'XlfO=y =:_?B7*f5ݿ3=mVxAlcz~~qߕ̘QǔVħYٳ;:N1}w=x]7ؓ;??ZeO0VmOn;Y|ƞȞB!ġ7a^眇'*p=uE}=-ro)rb멻_|ŞYq=q=y1ў\e=ߧ m_q?{rYb{ 5o~r7d?u=u}qn}Xqvq=9Oq=yO>q=BN{2.}/r=uY+]O]q=S_/_ۓ߽${{gA5#{ϏSwwC=yⷾ.k>ߌ'ɹ2ؓړ/x?%{_݇ KQʓ۔o_ɽG݇k]O]b&SǪnLv{;܇,ZC,o9܇:9e}'^\pO''$>>]XžtXڞ|.=y>1ƞX<=b%}%V' rO+?}kϗX'n{1[2]zJUˈ|:ؓW\9~??& ܇6+|K>%ƻM3vɣ[ؓ |-uOw?#>iO8Blnߣ2Swb;_Il>StR'ߕ_`OA{_7z_S7=2YjO>2]s紽=g}D=yb=y q=y*ӯ\U1|nx>zš7?\oV-qoGړW7w!s=u' [ ?ړ 'ؓ7 'z?=${rCa}~ݮnSWu}Bz.gۓkLϜ﴾9O䑗ŹQzjӷ4Ϯg\g6S\dO^1_\>\\Fm{lٓ?}'-s]\݇%'[&s7*"s=u׉ۓOm׻V7ٓNJ?HϿs{'O O[E/{/ݞK{a},zs=ys6q=vq7#ϋ9U_~TkOn& l}=Tzq=e9oɫb#ģQ%}J>kyZɳ3JimV϶ϴ_+ggggyF<9ϊ&z|tl'GN-yzgClp5C]aβgX3[:dtJ gP,23:$c8#:%29dt8fYLgf-ZU pvsj^NDUԒ!Z2#9aBfDDfC37"3oUlpvs89Vg'lpvq88=gٿlpvo87 g熳qٷlpvm86=Ζ gdžaٯlpvk85di8٤)٠i%3CC234d83!  g@C23ȌpiHfdi8,pV)3GSKf3IYɑYi%I#3JY!٤WKf3KI٤ gF:2fY7nG#3#EfZ(2Y!i%3(C2jΪQddrd"(Ùp$Ùi%3Y7̀L̂L̄ Lp6d82ɬp]Hf0 g0x gdvaHfنpard`8k09230 ظa `Yj? L۫L裯oo>^]xk}gnϸnׯg7[Snke߽,5w˖^-szjit˖1̈́^-ր ?tgjY-y[&sd2W[빖3y*e*<2[f\s\Ce( ղϖܲ2k32k1ne@ݲ[tM|2kK-]c!]Khko<[˸Dk5Ik| 9[eM2=.켺o߳,21]++e0=[jkIm 5HFkYjٚ56khd]ּdVֶdT5*Y5'[wBCVariantAnnotation/inst/extdata/structural.vcf0000644000175100017510000000576414614305321022563 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##fileDate=20100501 ##reference=1000GenomesPilot-NCBI36 ##assembly=ftp://ftp-trace.ncbi.nih.gov/1000genomes/ftp/release/sv/breakpoint_assemblies.fasta ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##ALT= ##ALT= ##ALT= ##ALT= ##ALT= ##ALT= ##ALT= ##ALT= ##ALT= ##ALT= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT NA00001 1 13220 . T 6 PASS IMPRECISE;SVTYPE=DEL;END=13221;SVLEN=-105;CIPOS=-56,20;CIEND=-10,62 GT:GQ 0/1:12 1 2827693 . CCGTGGATGCGGGGACCCGCATCCCCTCTCCCTTCACAGCTGAGTGACCCACATCCCCTCTCCCCTCGCA C . PASS SVTYPE=DEL;END=2827680;BKPTID=Pindel_LCS_D1099159;HOMLEN=1;HOMSEQ=C;SVLEN=-66 GT:GQ 1/1:13.9 2 321682 . T 6 PASS IMPRECISE;SVTYPE=DEL;END=321887;SVLEN=-105;CIPOS=-56,20;CIEND=-10,62 GT:GQ 0/1:12 2 14477084 . C 12 PASS IMPRECISE;SVTYPE=DEL;END=14477381;SVLEN=-297;MEINFO=AluYa5,5,307,+;CIPOS=-22,18;CIEND=-12,32 GT:GQ 0/1:12 3 9425916 . C 23 PASS IMPRECISE;SVTYPE=INS;END=9425916;SVLEN=6027;CIPOS=-16,22;MEINFO=L1HS,1,6025,- GT:GQ 1/1:15 3 12665100 . A 14 PASS IMPRECISE;SVTYPE=DUP;END=12686200;SVLEN=21100;CIPOS=-500,500;CIEND=-500,500 GT:GQ:CN:CNQ ./.:0:3:16.2 4 18665128 . T 11 PASS IMPRECISE;SVTYPE=DUP;END=18665204;SVLEN=76;CIPOS=-10,10;CIEND=-10,10 GT:GQ:CN:CNQ ./.:0:5:8.3 VariantAnnotation/inst/scripts/0000755000175100017510000000000014614305321017674 5ustar00biocbuildbiocbuildVariantAnnotation/inst/scripts/test_Rplinkseq.R0000644000175100017510000002524214614305321023033 0ustar00biocbuildbiocbuild### ====================================================================== ### Testing Rplinkseq and VariantAnnotation ### ====================================================================== ### ### February 2014 ### 'rhino03' Ubuntu server, 387 Gb RAM ### 16 processors with the following configuration: ### ### vendor_id : GenuineIntel ### cpu family : 6 ### model : 45 ### model name : Intel(R) Xeon(R) CPU E5-2690 0 @ 2.90GHz ### stepping : 7 ### microcode : 0x70d ### cpu MHz : 2900.142 ### cache size : 20480 KB ### physical id : 1 ### siblings : 8 ### core id : 0 ### cpu cores : 8 ### apicid : 32 ### initial apicid : 32 ### fpu : yes ### fpu_exception : yes ### cpuid level : 13 ### wp : yes ### flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov ### pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb ### rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc ### aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr ### pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx ### lahf_lm ida arat xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid ### bogomips : 5799.87 ### clflush size : 64 ### cache_alignment : 64 ### address sizes : 46 bits physical, 48 bits virtual ### power management: ### -------------------------------------------------------------------------- ### Objectives ### -------------------------------------------------------------------------- ### Compare runtimes between Rplinkseq and VariantAnnotation packages. ### ### ### Test functions: ### ### load.vcf: Data are loaded from a vcf file into a list of lists ### and accessed with x.consensus* functions. (Rplinkseq) ### ### var.fetch: Data are loaded from a PLINK/Seq 'project' into a list of ### lists and accessed with x.consensus* functions. (Rplinkseq) ### ### meta.fetch: Data are loaded from a PLINK/Seq 'project' and parsed into ### a data.frame. (Rplinkseq) ### ### var.iterate: Applies a function to data from a PLINK/Seq 'project' ### while iterating. Result of function is returned. ### (Rplinkseq) ### ### scanVcf: Data are loaded from a vcf file. Info and geno fields are ### parsed into a list of lists; other 'core' fields are ### returned as a GRAnges object. (VariantAnnotation) ### ### ### Test cases: ### ### Test I: Query by range. ### Import data by randomly chosen genomic range. ### (Functions: load.vcf, var.fetch, scanVcf) ### ### Test II: Query by range and fields. ### Import data by genomic range and 4 randomly ### chosen info (2) and geno (2) fields. ### (Functions: meta.fetch, scanVcf) ### ### Test III. Iterate through file. ### A simple function is applied to all records in the ### file in an iterative fashion. ### (Functions: var.iterate, scanVcf) ### ### -------------------------------------------------------------------------- ### Data ### -------------------------------------------------------------------------- ### Test file: ### Size on disk: 1.8G compressed ### Contents: 494328 variants, 1092 samples, 22 INFO, and 3 GENO fields ### Download location: ### ftp://ftp-trace.ncbi.nih.gov/1000genomes/ftp/release/20110521/ALL.chr22.phase1_release_v3.20101123.snps_indels_svs.genotypes.vcf.gz ### ### Test subset: ### An arbitrary subset of data was chosen for testing because the full file ### requires >250G in memory. The subset range is 2e7 to 2.5e7 and contains ### 63088 records. This subset is the 'range' in the mask and param objects. ### ### PLINK/Seq 'project': ### From the raw vcf on disk we creted a PLINK/Seq 'project' so we could use ### the var.iterate function. A 'project' creates compressed, indexed, SQLite ### database from input files. This one took ~30 minutes to create. ### pseq proj new-project ### pseq proj load-vcf --vcf 'ALL.chr22.phase1_release_v3.20101123.snps_indels_svs.genotypes.vcf.gz' ### -------------------------------------------------------------------------- ### Set up ### -------------------------------------------------------------------------- library(microbenchmark) library(VariantAnnotation) library(Rplinkseq) ## version 0.08 fl <- "/loc/no-backup/vobencha/ALL.chr22.phase1_release_v3.20101123.snps_indels_svs.genotypes.vcf.gz" ### Attach the 'project' to the R session: pseq.project("proj") ### -------------------------------------------------------------------------- ### Test I. Query by range ### -------------------------------------------------------------------------- ### load.vcf: mask <- "reg=22:20000000..25000000" loadvcf_1 <- function() load.vcf(fl, mask=mask, limit=200000) ### var.fetch: varfetch_1 <- function() var.fetch(mask=mask, limit=200000) ### scanVcf: tfile <- TabixFile(fl) which <- GRanges("22", IRanges(2e7, 2.5e7)) param <- ScanVcfParam(which=which) scanvcf_1 <- function() scanVcf(tfile, param=param) micro <- microbenchmark(loadvcf_1(), varfetch_1(), scanvcf_1(), times=5) micro ###Unit: seconds ### expr min lq median uq max neval ### loadvcf_1() 313.1729 335.5738 359.7979 368.4054 369.9397 5 ### varfetch_1() 264.4101 283.2388 291.7533 305.7028 318.7879 5 ### scanvcf_1() 300.5585 308.5507 359.0814 400.2049 678.2296 5 ### -------------------------------------------------------------------------- ### Test II. Query by range and fields ### -------------------------------------------------------------------------- ### Randomly select 2 INFO and 2 GENO fields: info_var <- c("RSQ", "THETA") geno_var <- c("GT", "DS") ### Other fields parsed by scanVcf: other_var <- c("CHROM", "POS", "ID", "REF", "ALT", "QUAL", "FILTER") ### load.vcf: To the best of our knowledge, this function can import ### by range but not by select fields. To isolate a field, ### all fields are read in and parsed with the x.consensus ### functions. There is no equivalent comparision for ### load.vcf in this test case. ### meta.fetch: mask <- "reg=22:20000000..25000000" metafetch_2 <- function() meta.fetch(c(info_var, geno_var, other_var), mask=mask) ### scanVcf: NOTE: Fields in 'other_var' are imported and parsed by ### scanVcf() under names of 'rowRanges' and 'fixed'. tfile <- TabixFile(fl) which <- GRanges("22", IRanges(2e7, 2.5e7)) param <- ScanVcfParam(which=which, info=info_var, geno=geno_var) scanvcf_2 <- function() scanVcf(tfile, param=param) micro <- microbenchmark(metafetch_2(), scanvcf_2(), times=5) micro ###Unit: seconds ### expr min lq median uq max neval ### metafetch_2() 118.14090 120.65009 120.87346 120.88615 121.13340 5 ### scanvcf_2() 35.45512 35.46179 35.51305 35.59804 37.41809 5 ### -------------------------------------------------------------------------- ### Test III. Iterate through file ### -------------------------------------------------------------------------- ### load.vcf: To the best of our knowledge Rplinkseq cannot iterate on ### raw vcf files. Iteration must be done on a 'project' with ### var.iterate. There is no equivalent comparision for load.vcf ### in this test case. ### var.iterate: simple_ct <- function(v) ct <<- ct + length(v$ID) variterate_3 <- function() { ct <<- 0 var.iterate(simple_ct) } ### scanVcf: tfile <- TabixFile(fl, yieldSize=10000) param <- ScanVcfParam(fixed=c("ALT"), info=NA, geno=NA) scanvcf_3 <- function() { ct2 <<- 0 open(tfile) while((len <- length(scanVcf(tfile, param=param)[[1]]$rowRanges)) > 0) ct2 <<- ct2 + len close(tfile) } micro <- microbenchmark(variterate_3(), scanvcf_3(), times=5) micro ##Unit: seconds ## expr min lq median uq max neval ## variterate_3() 1552.88520 1576.55856 1583.13120 1585.65281 1591.96375 5 ## scanvcf_3() 50.04566 50.06945 50.27194 50.56145 50.70112 5 ### -------------------------------------------------------------------------- ### Scaling with number of variants and samples (scanVcf only) ### -------------------------------------------------------------------------- ### Linear scaling by variants: tfile <- TabixFile(fl) yieldSize <- c(100000, 200000, 300000, 400000, 500000) param <- ScanVcfParam(info=NA, geno=NA) fun0 <- function(tfile, param) scanVcf(tfile, param=param) res <- lapply(yieldSize, function(i) { tf <- TabixFile(fl, yieldSize=i) microbenchmark(fun0(tf, param), times=5)}) res ### [[1]] ### Unit: seconds ### expr min lq median uq max neval ### fun0(tf, param) 9.883719 10.13574 10.15165 10.17318 10.70124 5 ### ### [[2]] ### Unit: seconds ### expr min lq median uq max neval ### fun0(tf, param) 19.385 19.6715 19.71968 19.72206 20.23362 5 ### ### [[3]] ### Unit: seconds ### expr min lq median uq max neval ### fun0(tf, param) 29.24268 29.33945 29.36927 29.38207 30.01012 5 ### ### [[4]] ### Unit: seconds ### expr min lq median uq max neval ### fun0(tf, param) 38.71675 38.73608 38.77965 38.8696 39.27382 5 ### ### [[5]] ### Unit: seconds ### expr min lq median uq max neval ### fun0(tf, param) 47.94605 48.76884 49.03272 49.03859 49.08618 5 ### Linear scaling by sample: tf <- TabixFile(fl) ids <- samples(scanVcfHeader(fl)) sampleSize <- c(200, 400, 600, 800, 1000) which <- GRanges("22", IRanges(2e7, 2.5e7)) ## 63088 records fun0 <- function(tf, param) scanVcf(tf, param=param) res <- lapply(sampleSize, function(i) { param <- ScanVcfParam(which=which, samples=ids[1:i]) microbenchmark(fun0(tf, param), times=5)}) res ### [[1]] ### Unit: seconds ### expr min lq median uq max neval ### fun0(tf, param) 61.80377 61.91141 69.62993 70.10218 103.1949 5 ### ### [[2]] ### Unit: seconds ### expr min lq median uq max neval ### fun0(tf, param) 128.3595 132.1819 135.7386 135.966 150.7588 5 ### ### [[3]] ### Unit: seconds ### expr min lq median uq max neval ### fun0(tf, param) 204.0067 211.0546 219.2069 232.3388 249.188 5 ### ### [[4]] ### Unit: seconds ### expr min lq median uq max neval ### fun0(tf, param) 266.7383 269.8461 273.7986 299.7805 330.6505 5 ### ### [[5]] ### Unit: seconds ### expr min lq median uq max neval ### fun0(tf, param) 329.6348 337.1841 348.7968 359.5972 364.2781 5 VariantAnnotation/inst/unitTests/0000755000175100017510000000000014614305321020207 5ustar00biocbuildbiocbuildVariantAnnotation/inst/unitTests/cases/0000755000175100017510000000000014614305321021305 5ustar00biocbuildbiocbuildVariantAnnotation/inst/unitTests/cases/banded_gvcf.vcf0000644000175100017510000000716414614305321024237 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##ALT= ##FILTER= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= ##GVCFBlock=minGQ=0(inclusive),maxGQ=5(exclusive) ##GVCFBlock=minGQ=20(inclusive),maxGQ=60(exclusive) ##GVCFBlock=minGQ=5(inclusive),maxGQ=20(exclusive) ##GVCFBlock=minGQ=60(inclusive),maxGQ=2147483647(exclusive) ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##contig= ##reference=file:///humgen/1kg/reference/human_g1k_v37.fasta #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT NA12878 20 10000000 . T . . END=10000116 GT:DP:GQ:MIN_DP:PL 0/0:44:99:38:0,89,1385 20 10000117 . C T, 612.77 . BaseQRankSum=0.000;ClippingRankSum=-0.411;DP=38;MLEAC=1,0;MLEAF=0.500,0.00;MQ=221.39;MQ0=0;MQRankSum=-2.172;ReadPosRankSum=-0.235 GT:AD:DP:GQ:PL:SB 0/1:17,21,0:38:99:641,0,456,691,519,1210:6,11,11,10 20 10000118 . T . . END=10000210 GT:DP:GQ:MIN_DP:PL 0/0:42:99:38:0,80,1314 20 10000211 . C T, 638.77 . BaseQRankSum=0.894;ClippingRankSum=-1.927;DP=42;MLEAC=1,0;MLEAF=0.500,0.00;MQ=221.89;MQ0=0;MQRankSum=-1.750;ReadPosRankSum=1.549 GT:AD:DP:GQ:PL:SB 0/1:20,22,0:42:99:667,0,566,728,632,1360:9,11,12,10 20 10000212 . A . . END=10000438 GT:DP:GQ:MIN_DP:PL 0/0:52:99:42:0,99,1403 VariantAnnotation/inst/unitTests/cases/buffer_realloc.vcf0000644000175100017510000001340614614305321024763 0ustar00biocbuildbiocbuild##fileformat=VCFv4.2 ##ALT= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= ##contig= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT CPCT02080261R.bam CPCT02080261T.bam 2 33141297 gridss9_272646b G .GGGGGGGGG 9740.19 PASS AS=0;ASQ=0.00;ASRP=0;ASSR=0;BA=176;BANRP=0;BANRPQ=0.00;BANSR=0;BANSRQ=0.00;BAQ=9740.19;BASRP=135;BASSR=247;BEID=asm0-129103,asm0-136881,asm0-145686,asm0-208575,asm0-30737,asm0-313482,asm0-61232,asm0-76515,asm1-145029,asm1-325449,asm1-423983,asm1-83584,asm101-68144,asm101-71616,asm11-81358,asm12-108625,asm12-152126,asm12-296167,asm16-133782,asm16-321806,asm16-321815,asm16-427257,asm16-94950,asm2-111121,asm20-143189,asm20-151129,asm20-170890,asm23-24876,asm23-291820,asm23-306094,asm25-114379,asm28-403417,asm29-121241,asm29-372733,asm3-150990,asm35-275592,asm35-282174,asm35-299968,asm35-359080,asm35-413690,asm36-391459,asm36-500121,asm39-267753,asm4-55688,asm40-181037,asm40-274527,asm41-436861,asm41-50053,asm41-73629,asm41-86602,asm44-284475,asm44-56449,asm46-101600,asm47-58479,asm5-123015,asm50-275561,asm50-797397,asm50-808980,asm51-106547,asm51-331358,asm51-339689,asm51-352967,asm52-126646,asm52-127230,asm54-102131,asm54-141975,asm54-319668,asm55-101690,asm55-207917,asm55-404060,asm55-443020,asm55-448683,asm56-292029,asm56-33816,asm56-35611,asm56-95061,asm57-108850,asm59-111905,asm59-213002,asm60-123692,asm60-161463,asm60-177300,asm60-402772,asm60-407224,asm60-412267,asm60-431644,asm61-263435,asm62-116054,asm62-467095,asm63-11233,asm65-254540,asm65-82577,asm68-269027,asm69-172288,asm69-182239,asm69-322025,asm69-379517,asm69-379530,asm7-340503,asm7-520912,asm72-362566,asm73-193036,asm73-96390,asm76-236578,asm76-254532,asm76-436369,asm76-481923,asm76-489947,asm77-116984,asm78-10896,asm79-174885,asm8-104372,asm8-104377,asm8-169742,asm80-135541,asm80-452317,asm80-452541,asm81-352996,asm82-83936,asm83-114358,asm83-384537,asm83-397466,asm83-433389,asm83-89759,asm85-393026,asm85-428243,asm85-609807,asm86-189185,asm86-202204,asm86-367634,asm86-367881,asm86-38643,asm88-154549,asm88-208277,asm88-408031,asm88-423280,asm88-429860,asm88-450503,asm88-469478,asm88-511793,asm89-167354,asm89-308060,asm89-372580,asm89-506657,asm89-573829,asm9-155250,asm9-247549,asm90-251538,asm90-409044,asm90-424975,asm90-45985,asm90-501874,asm90-599687,asm91-129940,asm91-359139,asm92-2480,asm92-396478,asm92-436104,asm92-5583,asm92-589941,asm92-627762,asm92-628827,asm92-632577,asm93-192515,asm94-103200,asm94-159474,asm94-241619,asm94-32204,asm96-279498,asm96-315198,asm96-358909,asm96-57650,asm97-476801,asm98-170886,asm98-394768,asm99-399940;BEIDH=-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1;BEIDL=72,135,138,178,251,61,163,176,253,10,48,113,258,124,168,143,300,59,176,146,99,44,187,223,70,197,146,93,103,11,139,79,112,16,145,14,75,40,15,24,66,18,39,159,175,38,73,133,163,176,28,78,93,178,299,289,54,22,172,5,11,21,124,180,239,203,8,182,161,29,11,20,43,233,317,94,205,88,144,143,219,175,73,31,72,57,56,159,20,167,19,290,88,189,214,26,5,7,63,44,36,31,27,79,39,39,28,31,19,131,131,49,211,136,244,19,45,20,140,9,26,12,38,205,32,39,86,49,148,59,26,123,155,12,6,7,64,26,25,23,300,170,88,19,38,149,104,220,16,46,182,15,77,226,68,86,19,36,269,259,5,28,58,13,74,18,21,153,7,6,19,299,40,173,30,45;BQ=9740.19;BSC=0;BSCQ=0.00;BUM=0;BUMQ=0.00;BVF=382;CAS=0;CASQ=0.00;CQ=7802.12;EVENT=gridss9_272646;IC=0;IQ=0.00;RAS=0;RASQ=0.00;REF=8898;REFPAIR=3;RP=0;RPQ=0.00;SB=0.4408397;SC=1X;SR=0;SRQ=0.00;SVTYPE=BND;VF=0 GT:ASQ:ASRP:ASSR:BANRP:BANRPQ:BANSR:BANSRQ:BAQ:BASRP:BASSR:BQ:BSC:BSCQ:BUM:BUMQ:BVF:CASQ:IC:IQ:QUAL:RASQ:REF:REFPAIR:RP:RPQ:SR:SRQ:VF .:0.00:0:0:0:0.00:0:0.00:2332.26:20:72:2332.26:0:0.00:0:0.00:92:0.00:0:0.00:0.00:0.00:2579:2:0:0.00:0:0.00:0 .:0.00:0:0:0:0.00:0:0.00:7407.93:115:175:7407.93:0:0.00:0:0.00:290:0.00:0:0.00:0.00:0.00:6319:1:0:0.00:0:0.00:0 2 33141297 gridss9_31852o G ]3:196361427]CCGGGGGGGCCAGGGGCCGGGGGGGCGGGGGAAGGGGGGGGGAGGGGACG 551.28 SINGLE_ASSEMBLY AS=0;ASQ=0.00;ASRP=19;ASSR=1;BA=0;BANRP=0;BANRPQ=0.00;BANSR=0;BANSRQ=0.00;BAQ=0.00;BASRP=0;BASSR=0;BEID=asm22-211186;BEIDH=0;BEIDL=349;BQ=0.00;BSC=0;BSCQ=0.00;BUM=0;BUMQ=0.00;BVF=0;CAS=0;CASQ=0.00;CQ=551.28;EVENT=gridss9_31852;IC=0;IHOMPOS=0,0;IQ=0.00;PARID=gridss9_31852h;RAS=1;RASQ=551.28;REF=8898;REFPAIR=3;RP=0;RPQ=0.00;SB=1.0;SC=1X69M;SR=0;SRQ=0.00;SVTYPE=BND;VF=20 GT:ASQ:ASRP:ASSR:BANRP:BANRPQ:BANSR:BANSRQ:BAQ:BASRP:BASSR:BQ:BSC:BSCQ:BUM:BUMQ:BVF:CASQ:IC:IQ:QUAL:RASQ:REF:REFPAIR:RP:RPQ:SR:SRQ:VF .:0.00:7:1:0:0.00:0:0.00:0.00:0:0:0.00:0:0.00:0:0.00:0:0.00:0:0.00:213.52:213.52:2579:2:0:0.00:0:0.00:8 .:0.00:12:0:0:0.00:0:0.00:0.00:0:0:0.00:0:0.00:0:0.00:0:0.00:0:0.00:337.76:337.76:6319:1:0:0.00:0:0.00:12 VariantAnnotation/inst/unitTests/cases/ex1-seq1-90.vcf0000644000175100017510000000453014614305321023601 0ustar00biocbuildbiocbuild##fileformat=VCFv4.2 ##FILTER= ##bcftoolsVersion=1.9+htslib-1.9 ##bcftoolsCommand=mpileup -Q 0 -d 1000000 --annotate FORMAT/AD,FORMAT/ADF,FORMAT/ADR --no-reference -r seq1:90 --output-type v --output ex1-seq1:90.vcf ex1.bam ##contig= ##contig= ##ALT= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT ex1.bam seq1 90 . N G,A,C,<*> 0 . DP=13;I16=0,0,13,0,0,0,260,6110,0,0,714,41636,0,0,114,1218;QS=0,0.946502,0.0288066,0.0246914,0;VDB=0.314346;SGB=-0.683931;MQ0F=0 PL:ADF:ADR:AD 105,33,0,107,25,104,108,25,107,105,105,33,107,108,105:0,11,1,1,0:0,0,0,0,0:0,11,1,1,0 VariantAnnotation/inst/unitTests/cases/expand.vcf0000644000175100017510000000345414614305321023272 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##source=VariantTools 1.1.0 ##phasing=unphased ##project=example ##fileDate=20121029 ##INFO= ##INFO= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT H1993 TP53 1000311 . T A . . DP=14;AF=0.5 AR:RR:DP:AAP:RAP 2:29:31:1:1 TP53 1011392 . C G . . . AR:RR:DP:AAP:RAP 540:41:582:1:1 TP53 1012027 . T C . . . AR:RR:DP:AAP:RAP 2:0:2:1:0 TP53 1012219 . G A . . . AR:RR:DP:AAP:RAP 2:0:2:1:0 TP53 1012654 . A G,T . . DP=10;AF=0.333,0.667 AR:RR:DP:AAP:RAP 585,4:1:590:2,2:1 TP53 1013309 . C G . . . AR:RR:DP:AAP:RAP 934:0:936:1:0 TP53 1017504 . A G . . . AR:RR:DP:AAP:RAP 2:3:5:1:1 TP53 1017549 . A G . . . AR:RR:DP:AAP:RAP 2:3:5:1:1 TP53 1019784 . T C . . . AR:RR:DP:AAP:RAP 5:0:5:1:0 TP53 1019934 . T C,A . . . AR:RR:DP:AAP:RAP 3,1:0:4:3,3:0 TP53 1019935 . G A . . . AR:RR:DP:AAP:RAP 3:0:3:1:0 TP53 1019986 . C T . . . AR:RR:DP:AAP:RAP 3:0:3:1:0 TP53 1020710 . A G . . . AR:RR:DP:AAP:RAP 3:1:4:1:1 TP53 1020776 . A G . . . AR:RR:DP:AAP:RAP 4:2:6:1:1 TP53 1020811 . A G . . . AR:RR:DP:AAP:RAP 2:4:6:1:1 TP53 1020837 . A G . . . AR:RR:DP:AAP:RAP 3:3:6:1:1 TP53 1020838 . A G . . . AR:RR:DP:AAP:RAP 2:4:6:1:1 TP53 1021339 . A G . . . AR:RR:DP:AAP:RAP 3:4:7:1:1 TP53 1021340 . A G . . . AR:RR:DP:AAP:RAP 3:4:7:1:1 TP53 1021638 . A G . . . AR:RR:DP:AAP:RAP 2:21:23:1:1 VariantAnnotation/inst/unitTests/cases/fewer-FORMAT-than-GENO.vcf0000644000175100017510000000114714614305321025564 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##source=VariantTools 1.3.2 ##phasing=unphased ##project=example ##fileDate=20130419 ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT H1993 TP53 1011392 . C G . . . AD:DP:AP 41,540:582:1,1 TP53 1012027 . T C . . . AD:DP:AP 0,2:2:0:1 TP53 1011392 . C G . . . AD:DP:AP 41,540:582:1,1 VariantAnnotation/inst/unitTests/cases/FORMAT_header_no_SAMPLEs.vcf0000644000175100017510000000113214614305321026222 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##INFO= ##ALT= ##FORMAT= ##FORMAT= ##FORMAT= ##reference=GRCh37 #CHROM POS ID REF ALT QUAL FILTER INFO 1 10523 . TCCG T 62 PASS AN=2184 1 10583 rs58108140 G A 100 PASS AN=2184 1 10611 rs189107123 C G 100 PASS AN=2184 1 10616 . CCGCCGTTGCAAAGGCGCGCCG C 172 PASS AN=2184 1 11540 . T TA 30 PASS AN=2184 VariantAnnotation/inst/unitTests/cases/meta_header.vcf0000644000175100017510000000250014614305321024240 0ustar00biocbuildbiocbuild##fileformat=VCFv4.3 ##Tassel= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= ##INFO= ##INFO= ##INFO= ##META= ##META= ##SAMPLE= ##SAMPLE= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT Sam1 Sam2 Chr01 1000 S01_1000 G A 100 PASS DP=20 GT:AD 0/0:10,0 0/1:5,5 VariantAnnotation/inst/unitTests/cases/missing-FORMAT-metadata-elt.vcf0000644000175100017510000000105214614305321027002 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##source=VariantTools 1.3.2 ##phasing=unphased ##project=example ##fileDate=20130419 ##FORMAT= ##FORMAT= ##FORMAT= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT H1993 TP53 1011392 . C G . . . AD:DP:AP 41,540:582:1,1 TP53 1012027 . T C . . . AD:DP:XP 0,2:2:1,1 TP53 1011392 . C G . . . AD:DP:AP 41,540:582:1,1 VariantAnnotation/inst/unitTests/cases/mixedStructural.vcf0000644000175100017510000000563214614305321025212 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##fileDate=20100501 ##reference=1000GenomesPilot-NCBI36 ##assembly=ftp://ftp-trace.ncbi.nih.gov/1000genomes/ftp/release/sv/breakpoint_assemblies.fasta ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##ALT= ##ALT= ##ALT= ##ALT= ##ALT= ##ALT= ##ALT= ##ALT= ##ALT= ##ALT= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT NA00001 1 13220 . T 6 PASS IMPRECISE;SVTYPE=DEL;END=13221;SVLEN=-105;CIPOS=-56,20;CIEND=-10,62 GT:GQ 0/1:12 1 2827693 . C G,T . PASS BKPTID=Pindel_LCS_D1099159;HOMLEN=1;HOMSEQ=C;SVLEN=-66 GT:GQ 1/1:13.9 2 321682 . T 6 PASS IMPRECISE;SVTYPE=DEL;END=321887;SVLEN=-105;CIPOS=-56,20;CIEND=-10,62 GT:GQ 0/1:12 2 14477084 . C 12 PASS IMPRECISE;SVTYPE=DEL;END=14477381;SVLEN=-297;MEINFO=AluYa5,5,307,+;CIPOS=-22,18;CIEND=-12,32 GT:GQ 0/1:12 3 9425916 . C 23 PASS IMPRECISE;SVTYPE=INS;END=9425916;SVLEN=6027;CIPOS=-16,22;MEINFO=L1HS,1,6025,- GT:GQ 1/1:15 3 12665100 . A 14 PASS IMPRECISE;SVTYPE=DUP;END=12686200;SVLEN=21100;CIPOS=-500,500;CIEND=-500,500 GT:GQ:CN:CNQ ./.:0:3:16.2 4 18665128 . T 11 PASS IMPRECISE;SVTYPE=DUP;END=18665204;SVLEN=76;CIPOS=-10,10;CIEND=-10,10 GT:GQ:CN:CNQ ./.:0:5:8.3 VariantAnnotation/inst/unitTests/cases/multiple_INFO_fields.vcf0000644000175100017510000000066714614305321026012 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##fileDate=20141205 ##INFO= ##INFO= ##contig= #CHROM POS ID REF ALT QUAL FILTER INFO 17 10001541 rs12451372 C G,T 100 PASS AF=0.139776,0.0595048;NS=2504 17 10001547 17:10001547_G/A G A 100 PASS AF=0.000199681;NS=2504 VariantAnnotation/inst/unitTests/cases/negative_FORMAT_Number.vcf0000644000175100017510000000574414614305321026201 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##samtoolsVersion=0.1.17 (r973:277) ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT test chr1 32386425 . T C 24 . DP=3;AF1=1;AC1=2;DP4=0,0,0,3;MQ=50;FQ=-36 GT:PL:GQ 1/1:56,9,0:15 chr1 32507666 . G T 6.2 . DP=5;AF1=0.4999;AC1=1;DP4=3,0,2,0;MQ=50;FQ=8.65;PV4=1,0.062,1,0.36 GT:PL:GQ 0/1:35,0,78:36 chr1 32524459 . A C 3.54 . DP=5;AF1=0.4998;AC1=1;DP4=1,2,0,2;MQ=50;FQ=5.47;PV4=1,0.0021,1,1 GT:PL:GQ 0/1:31,0,98:30 chr1 32622505 . G A 101 . DP=18;AF1=0.5;AC1=1;DP4=10,0,5,2;MQ=50;FQ=104;PV4=0.15,0.0055,1,0.0075 GT:PL:GQ 0/1:131,0,162:99 chr12 25357574 . CAA C 109 . INDEL;DP=5;AF1=1;AC1=2;DP4=0,0,4,0;MQ=50;FQ=-46.5 GT:PL:GQ 1/1:149,12,0:21 VariantAnnotation/inst/unitTests/cases/no_FORMAT_column.vcf0000644000175100017510000000043714614305321025052 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##fileDate=20111001 ##INFO= #CHROM POS ID REF ALT QUAL FILTER INFO 1 2020003 . G A . . DP=10 1 2158344 . C T . . DP=10 1 2179799 . C T . . DP=20 1 2229439 . C G . . DP=20 1 2229827 . G A . . DP=10 VariantAnnotation/inst/unitTests/cases/no_GENO_row.vcf0000644000175100017510000000107614614305321024124 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##source=VariantTools 1.3.2 ##phasing=unphased ##project=example ##fileDate=20130419 ##FORMAT= ##FORMAT= ##FORMAT= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT H1993 H1994 TP53 1011392 . C G . . . AD:DP:AP 41,540:582:1,1 41,540:583:1,1 TP53 1012027 . T C . . . TP53 1011392 . C G . . . AD:DP:AP 41,540:584:1,1 41,540:585:1,1 VariantAnnotation/inst/unitTests/cases/no_INFO_header.vcf0000644000175100017510000000045414614305321024547 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##fileDate=20111001 ##FORMAT= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT 587338 1 2020003 . G A . . . GT ./. 1 2158344 . C T . . . GT ./. 1 2179799 . C T . . . GT ./. 1 2229439 . C G . . . GT ./. 1 2229827 . G A . . . GT ./. VariantAnnotation/inst/unitTests/cases/unspecified_INFO_FORMAT_fields.vcf0000644000175100017510000000321714614305321027517 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##fileDate=20090805 ##source=myImputationProgramV3.1 ##reference=file:///seq/references/1000GenomesPilot-NCBI36.fasta ##contig= ##phasing=partial ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##FILTER= ##FILTER= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT NA00001 NA00002 NA00003 20 14370 rs6054257 G A 29 PASS NS=3;DP=14;AF=0.5;DB;H2 GT:GQ:DP:HQ 0|0:48:1:51,51 1|0:48:8:51,51 1/1:43:5:.,. 20 17330 . T A 3 q10 NS=3;XX;DP=11;AF=0.017 GT:GQ:DP:HQ 0|0:49:3:58,50 0|1:3:5:65,3 0/0:41:3 20 1110696 rs6040355 A G,T 67 PASS NS=2;DP=10;XX=1,2;AF=0.333,0.667;AA=T;DB GT:GQ:DP:HQ 1|2:21:6:23,27 2|1:2:0:18,2 2/2:35:4 20 1230237 . T . 47 PASS NS=3;DP=13;AA=T GT:GQ:DP:YY:HQ 0|0:54:7:0:56,60 0|0:48:4:0:51,51 0/0:61:2:0 20 1234567 microsat1 GTC G,GTCT 50 PASS NS=3;DP=9;AA=G YY:GT:GQ:DP 0/0:0/1:35:4 0/0:0/2:17:2 0/0:1/1:40:3 VariantAnnotation/inst/unitTests/cases/VarScan_header.vcf0000644000175100017510000000600214614305321024650 0ustar00biocbuildbiocbuild##fileformat=VCFv4.1 ##source=VarScan2 ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##INFO= ##FILTER= ##FILTER= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= ##FORMAT= ##SnpEffVersion="2.0.5 (build 2011-12-24), by Pablo Cingolani" ##SnpEffCmd="SnpEff eff GRCh37.64 -c /home/adminrig/src/snpeff/snpEff_2_0_5/snpEff.config -i vcf -o vcf -v 48vcf.snp.somatic.vcf " ##INFO= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT NORMAL TUMOR chr1 1574019 . A G 0.0 PASS DP=27;SOMATIC;SS=2;SSC=14;GPV=1E0;SPV=3.7681E-2;EFF=DOWNSTREAM(MODIFIER||||MMP23B|protein_coding|CODING|ENST00000356026|),TRANSCRIPT(MODIFIER||||AL691432.2|unprocessed_pseudogene|NON_CODING|ENST00000317673|),SPLICE_SITE_ACCEPTOR(HIGH||||WASH2P|unprocessed_pseudogene|NON_CODING|ENST00000542901|),UTR_5_PRIME(MODIFIER||||ARHGEF16|protein_coding|CODING|ENST00000378371|exon_1_3383535_3383901),NON_SYNONYMOUS_CODING(MODERATE|MISSENSE|Cgg/Tgg|R10W|CYP4B1|processed_transcript|CODING|ENST00000468637|exon_1_47279154_47279278) GT:GQ:DP:RD:AD:FREQ 0/0:.:12:11:1:8.33% 0/1:.:15:8:7:46.67% chr1 1580738 . T A 0.0 PASS DP=76;SOMATIC;SS=2;SSC=14;GPV=1E0;SPV=3.1816E-2;EFF=TRANSCRIPT(MODIFIER||||AL691432.2|unprocessed_pseudogene|NON_CODING|ENST00000317673|),TRANSCRIPT(MODIFIER||||AL691432.2|unprocessed_pseudogene|NON_CODING|ENST00000340677|),TRANSCRIPT(MODIFIER||||AL691432.2|unprocessed_pseudogene|NON_CODING|ENST00000341832|),TRANSCRIPT(MODIFIER||||AL691432.2|unprocessed_pseudogene|NON_CODING|ENST00000407249|),TRANSCRIPT(MODIFIER||||AL691432.2|unprocessed_pseudogene|NON_CODING|ENST00000513088|) GT:GQ:DP:RD:AD:FREQ 1/1:.:25:15:4:21.05% 0/1:.:51:25:24:48.98% VariantAnnotation/inst/unitTests/test_expand-methods.R0000644000175100017510000000552314614305321024316 0ustar00biocbuildbiocbuildexpand <- VariantAnnotation::expand test_expand_info_geno <- function() { fl <- system.file("unitTests", "cases", "expand.vcf", package="VariantAnnotation") vcf <- suppressWarnings(readVcf(fl, "hg19")) exp <- expand(vcf) names(mcols(rowRanges(exp))) cnms <- c("paramRangeID", "REF", "ALT", "QUAL", "FILTER") checkIdentical(cnms, names(mcols(rowRanges(exp)))) checkTrue(nrow(exp) == 22L) checkIdentical(info(exp)$DP[5:6], c(10L, 10L)) checkIdentical(info(exp)$AF[5:6], c(0.333, 0.667)) checkIdentical(geno(exp)$AAP[6:11], c(2L, rep(1L, 4L), 3L)) } test_expand_structural <- function() { fl <- system.file("extdata", "structural.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") exp <- expand(vcf) checkTrue(nrow(vcf) == nrow(exp)) checkTrue(ncol(vcf) == ncol(exp)) checkTrue(is.character(alt(exp))) } test_expand_structural <- function() { fl <- system.file("unitTests", "cases", "mixedStructural.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") exp <- expand(vcf) checkTrue(nrow(exp) == 8L) } test_expand_multiple_info <- function() { fl <- system.file("unitTests", "cases", "multiple_INFO_fields.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "GRCh37") exp <- expand(vcf) checkTrue(nrow(exp) == 3L) ## single row, subset of INFO fields selected exp <- expand(vcf[1,]) checkTrue(nrow(exp) == 2L) ## single row, single (only) INFO field selected vcf <- readVcf(fl, "GRCh37", param=ScanVcfParam(info="AF")) exp <- expand(vcf[1,]) checkTrue(nrow(exp) == 2L) } test_expand_gvcf <- function() { fl <- system.file("unitTests", "cases", "banded_gvcf.vcf", package="VariantAnnotation") vcf <- suppressWarnings(readVcf(fl, "")) exp <- expand(vcf) checkIdentical(dim(exp), c(7L, 1L)) checkIdentical(dim(geno(exp)$AD), c(7L, 1L, 2L)) checkIdentical(geno(exp)$AD[,,1], as.integer(c(NA, 17, 17, NA, 20, 20, NA))) } test_expand_adr_adf <- function() { fl <- system.file("unitTests", "cases", "ex1-seq1-90.vcf", package = "VariantAnnotation") vcf <- readVcf(fl, genome = "") exp <- expand(vcf) seqName <- "seq1:90_N/G";sampleName <- colnames(vcf)[1] # for all/forward/revert strands tmp <- sapply(c("AD", "ADF", "ADR"), function(var){ # original counts countsVcf <- geno(vcf)[[var]][seqName, sampleName][[1]] # in VCF: counts reported first for reference, then alternative alleles # check counts for reference allele checkTrue(all(geno(exp)[[var]][, sampleName, 1] == countsVcf[1])) # check if counts for alternative alleles idxMatch <- match(alt(vcf)[[1]], alt(exp)) countsExpand <- geno(exp)[[var]][idxMatch, sampleName, 2] checkIdentical(countsExpand, countsVcf[-1]) }) } VariantAnnotation/inst/unitTests/test_filterVcf.R0000644000175100017510000001263514614305321023324 0ustar00biocbuildbiocbuildquiet <- suppressMessages test_filterVcf_TabixFile <- function() { fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") tbx <- TabixFile(fl, yieldSize=5000) dest <- tempfile() filt <- FilterRules(list(fun=function(...) TRUE)) ans <- quiet(filterVcf(tbx, "hg19", dest, filters=filt)) checkIdentical(dest, ans) vcf0 <- readVcf(fl, "hg19") vcf1 <- readVcf(dest, "hg19") checkIdentical(dim(vcf0), dim(vcf1)) ## with ranges param <- ScanVcfParam(which=GRanges("22", IRanges(50301340, width=10000))) ans1 <- quiet(filterVcf(tbx, "", tempfile(), filters=filt, param=param)) ans2 <- quiet(filterVcf(fl, "", tempfile(), filters=filt, param=param)) vcf1 <- readVcf(ans1, "") vcf2 <- readVcf(ans2, "") checkIdentical(rowRanges(vcf1), rowRanges(vcf2)) } test_filterVcf_filter <- function() { fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") tbx <- TabixFile(fl, yieldSize=5000) filt <- FilterRules(list(filt1=function(x) { rowSums(geno(x)$DS > 0.5) > 0 })) dest <- tempfile() ans <- filterVcf(tbx, "hg19", dest, filters=filt, verbose=FALSE) vcf0 <- subsetByFilter(readVcf(fl, "hg19"), filt) vcf1 <- readVcf(ans, "hg19") checkIdentical(dim(vcf0), dim(vcf1)) } test_filterVcf_prefilter_only <- function() { fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") tbx <- TabixFile(fl, yieldSize=5000) prefilt <- FilterRules(list(filt1=function(x) { grepl("LOWCOV", x, fixed=TRUE) })) dest <- tempfile() ans <- filterVcf(tbx, "hg19", dest, prefilters=prefilt, verbose=FALSE) vcf <- readVcf(fl, "hg19") idx <- any(info(vcf)$SNPSOURCE == "LOWCOV") vcf0 <- vcf[!is.na(idx) & idx,] vcf1 <- readVcf(ans, "hg19") checkIdentical(dim(vcf0), dim(vcf1)) } test_filterOnSomaticStatus <- function() { f <- system.file("extdata", "h1187-10k.vcf.gz", package="VariantAnnotation") vcf <- readVcf(f, "hg19") somaticStatus <- as.list(table(info(vcf)$SS)) checkEquals(somaticStatus, list(Germline=103, LOH=1, Somatic=4)) somaticStatusGermlineFilter <- function(x){ !is.na(info(x)$SS) & info(x)$SS=="Germline" } # filter the in-memory data structure filters <- FilterRules(list(filter.1=somaticStatusGermlineFilter)) checkEquals(dim(subsetByFilter(vcf, filters)), c(103, 2)) } test_prefilterOnSomaticStatus <- function() { f <- system.file("extdata", "h1187-10k.vcf.gz", package="VariantAnnotation") tabix.file <- TabixFile(f, yieldSize=1000) isGermline=function(x) { grepl("Germline", x, fixed=TRUE) } prefilteringFunctions <- FilterRules(list(isGermline=isGermline)) filtered.filename <- filterVcf(tabix.file, "hg19", tempfile(), prefilters=prefilteringFunctions, verbose=FALSE) checkEquals(nrow(readVcf(filtered.filename, "hg19")), 103) } test_filterOnSnps <- function() { f <- system.file("extdata", "h1187-10k.vcf.gz", package="VariantAnnotation") tabix.file <- TabixFile(f, yieldSize=1000) # filter only on snp isSnp=function(x) { refSnp <- nchar(ref(x)) == 1L a <- alt(x) altSnp <- elementNROWS(a) == 1L ai <- unlist(a[altSnp]) # all length 1, so unlisting is 1:1 map altSnp[altSnp] <- nchar(ai) == 1L & (ai %in% c("A", "C", "G", "T")) refSnp & altSnp } filteringFunctions <- FilterRules(list(isSnp=isSnp)) filtered.filename <- filterVcf(tabix.file, "hg19", tempfile(), filters=filteringFunctions, verbose=FALSE) # now check the results vcf.germline <- readVcf(filtered.filename, "hg19") # checkEquals(nrow(vcf.germline), 186) } test_prefilterOnSomaticStatusThenFilterOnSnps <- function() { f <- system.file("extdata", "h1187-10k.vcf.gz", package="VariantAnnotation") tabix.file <- TabixFile(f, yieldSize=1000) isGermline=function(x) { grepl("Germline", x, fixed=TRUE) } prefilteringFunctions <- FilterRules(list(isGermline=isGermline)) isSnp=function(x) { refSnp <- nchar(ref(x)) == 1L a <- alt(x) altSnp <- elementNROWS(a) == 1L ai <- unlist(a[altSnp]) # all length 1, so unlisting is 1:1 map altSnp[altSnp] <- nchar(ai) == 1L & (ai %in% c("A", "C", "G", "T")) refSnp & altSnp } filteringFunctions <- FilterRules(list(isSnp=isSnp)) # now filter on both. should be 98 rows filtered.filename <- filterVcf(tabix.file, "hg19", tempfile(), prefilters=prefilteringFunctions, filters=filteringFunctions, verbose=FALSE) # now check the results vcf.germline.snp <- readVcf(filtered.filename, "hg19") # checkEquals(nrow(vcf.germline.snp), 98) } test_index <- function() { vcf <- VcfFile(system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation")) prefilter = FilterRules(function(x) TRUE) ans <- filterVcf(vcf, destination=tempfile(), index=TRUE, prefilters=prefilter) checkTrue(file.exists(ans)) filter <- FilterRules(function(x) TRUE) ans <- filterVcf(vcf, destination=tempfile(), index=TRUE, filters=filter) checkTrue(file.exists(ans)) } VariantAnnotation/inst/unitTests/test_genotypeToSnpMatrix.R0000644000175100017510000001707414614305321025405 0ustar00biocbuildbiocbuildlibrary(snpStats) ## SnpMatrix class quiet <- suppressWarnings test_gSM_array_GT <- function() { mat <- matrix(c(".|.", "0|0", "0|1", "1|0", "1|1", "./.", "0/0", "0/1", "1/0", "1/1"), ncol=2, dimnames=list(1:5,1:2)) sm <- new("SnpMatrix", matrix(as.raw(c(0, 1, 2, 2, 3, 0, 1, 2, 2, 3)), nrow=2, byrow=TRUE, dimnames=list(1:2,1:5))) ref <- DNAStringSet(rep("A",5)) alt <- DNAStringSetList("C", "G", "T", "C", "G") map <- DataFrame(snp.names=rownames(mat), allele.1=ref, allele.2=alt, ignore=rep(FALSE,5)) gtsm <- genotypeToSnpMatrix(mat, ref, alt) checkIdentical(sm, gtsm$genotypes) checkIdentical(map, gtsm$map) } test_gSM_array_GT_2alt <- function() { mat <- matrix(c("0|1", "1|0", "1|1", "1/2", "2/1", "2/2"), ncol=2, dimnames=list(1:3,1:2)) sm <- new("SnpMatrix", matrix(as.raw(rep(0,6)), nrow=2, byrow=TRUE, dimnames=list(1:2,1:3))) ref <- DNAStringSet(rep("A",3)) alt <- DNAStringSetList(c("C","G"), c("G","T"), c("T","C")) map <- DataFrame(snp.names=rownames(mat), allele.1=ref, allele.2=alt, ignore=rep(TRUE,3)) gtsm <- quiet(genotypeToSnpMatrix(mat, ref, alt)) checkIdentical(sm, gtsm$genotypes) checkIdentical(map, gtsm$map) } test_gSM_array_GT_nonsnv <- function() { mat <- matrix(c("0|0", "0|1", "1|0", "0/0", "0/1", "1/0"), ncol=2, dimnames=list(1:3,1:2)) sm <- new("SnpMatrix", matrix(as.raw(rep(0,6)), nrow=2, byrow=TRUE, dimnames=list(1:2,1:3))) ref <- DNAStringSet(c("A","ACG","ACG")) alt <- DNAStringSetList("CGT", "G", "GAC") map <- DataFrame(snp.names=rownames(mat), allele.1=ref, allele.2=alt, ignore=rep(TRUE,3)) gtsm <- quiet(genotypeToSnpMatrix(mat, ref, alt)) checkIdentical(sm, gtsm$genotypes) checkIdentical(map, gtsm$map) } test_gSM_VCF_GL <- function() { fl <- system.file("extdata", "gl_chr1.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") gtsm <- quiet(genotypeToSnpMatrix(vcf, uncertain=TRUE)) checkIdentical(colnames(vcf), rownames(gtsm$genotypes)) checkIdentical(rownames(vcf), colnames(gtsm$genotypes)) checkIdentical(rownames(vcf), gtsm$map$snp.names) checkIdentical(ref(vcf), gtsm$map$allele.1) checkIdentical(alt(vcf), gtsm$map$allele.2) checkEquals(unlist(GLtoGP(geno(vcf)$GL)[1,4]), as.vector(g2post(gtsm$genotypes[4,1]))) } test_gSM_VCF_PL <- function() { fl <- system.file("extdata", "hapmap_exome_chr22.vcf.gz", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") gtsm <- quiet(genotypeToSnpMatrix(vcf, uncertain=TRUE)) checkIdentical(colnames(vcf), rownames(gtsm$genotypes)) checkIdentical(rownames(vcf), colnames(gtsm$genotypes)) checkIdentical(rownames(vcf), gtsm$map$snp.names) checkIdentical(ref(vcf), gtsm$map$allele.1) checkIdentical(alt(vcf), gtsm$map$allele.2) checkEquals(unlist(PLtoGP(geno(vcf)$PL)[1,4]), as.vector(g2post(gtsm$genotypes[4,1])), tolerance=0.01) } test_gSM_VCF_structural <- function() { fl <- system.file("extdata", "structural.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") gtsn <- quiet(genotypeToSnpMatrix(vcf)) checkTrue(nrow(gtsn$genotype) == 1L) checkTrue(rownames(gtsn$genotype) == "NA00001") } test_gSM_VCF_noSamples <- function() { fl <- system.file("unitTests", "cases", "FORMAT_header_no_SAMPLEs.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") gtsm <- quiet(genotypeToSnpMatrix(vcf)) checkEquals(0, nrow(gtsm$genotypes)) } test_pSM_valid <- function() { probs <- matrix(c(1,0,0, 0,1,0, 0,0,1, NA,NA,NA), ncol=3, byrow=TRUE, dimnames=list(1:4,c("RR","RA","AA"))) sm <- new("SnpMatrix", matrix(as.raw(c(1,2,3,0)), nrow=1, dimnames=list(NULL,1:4))) checkIdentical(sm, probabilityToSnpMatrix(probs)) } test_pSM_invalid <- function() { # invalid matrix - probs do not sum to 1 probs <- matrix(c(1,1,0, 0,1,0, 0,0,1, NA,NA,NA), ncol=3, byrow=TRUE) checkException(probabilityToSnpMatrix(probs)) } test_pSM_onerow <- function() { probs <- matrix(c(1,0,0, NA,NA,NA), ncol=3, byrow=TRUE, dimnames=list(1:2,c("RR","RA","AA"))) sm <- new("SnpMatrix", matrix(as.raw(c(1,0)), nrow=1, dimnames=list(NULL,1:2))) checkIdentical(sm, probabilityToSnpMatrix(probs)) } test_GLtoGP_array <- function() { probs <- aperm(array(c(0.4,0.3,0.3, 0.5,0.1,0.4, 0.9,0.05,0.05, 0,1,0, 0,0,1, 1,NA,NA), dim=c(3,3,2)), c(2,3,1)) gl <- probs for (i in 1:nrow(probs)) { for (j in 1:ncol(probs)) { gl[i,j,] <- log10(probs[i,j,]) } } gp <- GLtoGP(gl) checkEquals(probs, gp) } test_PLtoGP_array <- function() { probs <- aperm(array(c(0.4,0.3,0.3, 0.5,0.1,0.4, 0.9,0.05,0.05, 0,1,0, 0,0,1, 1,NA,NA), dim=c(3,3,2)), c(2,3,1)) pl <- probs for (i in 1:nrow(probs)) { for (j in 1:ncol(probs)) { pl[i,j,] <- -10*log10(probs[i,j,]) } } gp <- PLtoGP(pl) checkEquals(probs, gp) } test_GLtoGP_matrix <- function() { probs <- matrix(c(list(c(0.4,0.3,0.3)), list(c(0.5,0.1,0.4)), list(c(0.9,0.05,0.05)), list(c(0,1,0)), list(c(0,0,1)), list(c(1))), ncol=2) gl <- probs for (i in 1:nrow(probs)) { for (j in 1:ncol(probs)) { gl[i,j] <- list(log10(unlist(probs[i,j]))) } } gp <- GLtoGP(gl) checkEquals(probs, gp) } test_PLtoGP_matrix <- function() { probs <- matrix(c(list(c(0.4,0.3,0.3)), list(c(0.5,0.1,0.4)), list(c(0.9,0.05,0.05)), list(c(0,1,0)), list(c(0,0,1)), list(c(1))), ncol=2) pl <- probs for (i in 1:nrow(probs)) { for (j in 1:ncol(probs)) { pl[i,j] <- list(-10*log10(unlist(probs[i,j]))) } } gp <- PLtoGP(pl) checkEquals(probs, gp) } test_matrixToArray <- function() { mat <- matrix(c(list(c(1,2,3)), list(c(4,5,6)), list(c(7,8,9)), list(c(10,11,12)), list(c(13,14)), list(c(15))), ncol=2) arr <- VariantAnnotation:::.matrixOfListsToArray(mat) for (i in 1:nrow(mat)) { for (j in 1:ncol(mat)) { n <- elementNROWS(mat[i,j]) checkEquals(unlist(mat[i,j]), arr[i,j,1:n]) } } TRUE } VariantAnnotation/inst/unitTests/test_isSNV.R0000644000175100017510000000737714614305321022411 0ustar00biocbuildbiocbuildvcf0 <- VCF(rowRanges=GRanges("chr1", IRanges(1:9, width=c(rep(1, 6), 2, 2, 3))), fixed=DataFrame( REF=DNAStringSet(c("A", "G", "C", "T", "T", "G", "GG", "TCT", "AC")), ALT=DNAStringSetList("G", "A", "T", "C", c("C", "TT"), "GG", "G", "GCG", "ACC"))) str <- system.file("extdata", "structural.vcf", package="VariantAnnotation") vcf <- readVcf(str, "") test_isSNV_CollapsedVCF <- function() { checkIdentical(isSNV(vcf), logical(nrow(vcf))) checkIdentical(isInsertion(vcf), logical(nrow(vcf))) target <- c(FALSE, TRUE, rep(FALSE, 5)) checkIdentical(isDeletion(vcf), target) checkIdentical(isIndel(vcf), target) checkIdentical(isDelins(vcf), logical(nrow(vcf))) checkIdentical(isTransition(vcf), logical(nrow(vcf))) checkIdentical(isSubstitution(vcf), logical(nrow(vcf))) res1 <- isSNV(vcf0, singleAltOnly=TRUE) checkIdentical(res1, c(rep(TRUE, 4), rep(FALSE, 5))) res2 <- isSNV(vcf0, singleAltOnly=FALSE) checkIdentical(res2, c(rep(TRUE, 5), rep(FALSE, 4))) res1 <- isInsertion(vcf0) checkIdentical(res1, c(rep(FALSE, 5), TRUE, FALSE, FALSE, FALSE)) res2 <- isDeletion(vcf0) checkIdentical(res2, c(rep(FALSE, 6), TRUE, FALSE, FALSE)) res3 <- isIndel(vcf0) checkIdentical(res3, res1 | res2) res4 <- isDelins(vcf0) checkIdentical(res4, c(rep(FALSE, 8), TRUE)) res1 <- isSubstitution(vcf0, singleAltOnly=TRUE) checkIdentical(res1, c(rep(TRUE, 4), rep(FALSE, 3), TRUE, FALSE)) res2 <- isSubstitution(vcf0, singleAltOnly=FALSE) checkIdentical(res2, c(rep(TRUE, 5), rep(FALSE, 2), TRUE, FALSE)) res1 <- isTransition(vcf0, singleAltOnly=TRUE) checkIdentical(res1, c(rep(TRUE, 4), rep(FALSE, 5))) res2 <- isTransition(vcf0, singleAltOnly=FALSE) checkIdentical(res2, c(rep(TRUE, 5), rep(FALSE, 4))) } expand <- VariantAnnotation::expand test_isSNV_ExpandedVCF <- function() { evcf <- expand(vcf) checkIdentical(isSNV(evcf), logical(nrow(evcf))) checkIdentical(isInsertion(evcf), logical(nrow(evcf))) target <- c(FALSE, TRUE, rep(FALSE, 5)) checkIdentical(isDeletion(evcf), target) checkIdentical(isIndel(evcf), target) checkIdentical(isDelins(evcf), logical(nrow(evcf))) checkIdentical(isTransition(evcf), logical(nrow(evcf))) checkIdentical(isSubstitution(evcf), logical(nrow(evcf))) evcf0 <- expand(vcf0) res <- isSNV(evcf0) checkIdentical(sum(res), 5L) res1 <- isInsertion(evcf0) checkIdentical(sum(res1), 2L) res2 <- isDeletion(evcf0) checkIdentical(sum(res2), 1L) res3 <- isIndel(evcf0) checkIdentical(sum(res3), sum(res1 + res2)) res4 <- isDelins(evcf0) checkIdentical(sum(res4), 1L) res <- isSubstitution(evcf0) checkIdentical(sum(res), 6L) res <- isTransition(evcf0) checkIdentical(sum(res), 5L) } test_isSNV_VRanges <- function() { vr <- as(vcf0, "VRanges") res <- isSNV(vr) checkIdentical(sum(res), 5L) res1 <- isInsertion(vr) checkIdentical(sum(res1), 2L) res2 <- isDeletion(vr) checkIdentical(sum(res2), 1L) res3 <- isIndel(vr) checkIdentical(sum(res3), sum(res1 + res2)) res4 <- isDelins(vr) checkIdentical(sum(res4), 1L) res <- isSubstitution(vr) checkIdentical(sum(res), 6L) res <- isTransition(vr) checkIdentical(sum(res), 5L) } test_isSNV_gvcf_format <- function() { ## ignore fl <- system.file("unitTests", "cases", "banded_gvcf.vcf", package="VariantAnnotation") vcf <- suppressWarnings(readVcf(fl, "")) checkIdentical(isSNV(vcf), c(TRUE, FALSE, TRUE, FALSE, TRUE)) checkIdentical(isSNV(vcf, singleAltOnly=FALSE), rep(TRUE, nrow(vcf))) vr <- as(vcf, "VRanges") checkIdentical(isSNV(expand(vcf)), isSNV(vr)) } VariantAnnotation/inst/unitTests/test_locateVariants-methods.R0000644000175100017510000001331714614305321026016 0ustar00biocbuildbiocbuildlibrary(TxDb.Hsapiens.UCSC.hg19.knownGene) txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene cdsbytx <- cdsBy(txdb, use.names=TRUE) intbytx <- intronsByTranscript(txdb) txbygene <- transcriptsBy(txdb, "gene") gr <- GRanges("chr22", IRanges(c(16268137, 16287254, 16190792, 16164570, 18209442, 18121652, 24314750, 25508661), width=c(1,1,1,1,3,3,2,2)), strand=c("-", "-", "-", "+", "+", "+", "+", "+")) test_locateVariants_upstream_downstream <- function() { loc <- locateVariants(gr, txdb, IntergenicVariants(1, 1)) target <- CharacterList(character(), character()) checkIdentical(loc$FOLLOWID, target) loc <- locateVariants(gr, txbygene, IntergenicVariants(2, 2)) target <- CharacterList(character(), "100037417") checkIdentical(loc$FOLLOWID, target) loc <- locateVariants(gr, txbygene, IntergenicVariants(100000, 100000)) target <- CharacterList("23784", c("100037417","4282", "66035")) checkIdentical(loc$FOLLOWID, target) target <- CharacterList(character(), c("23523", "2953", "391322")) checkIdentical(loc$PRECEDEID, target) } test_locateVariants_queryAsVCF <- function() { fl <- system.file("extdata", "gl_chr1.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") vcf <- renameSeqlevels(vcf, c("1" = "chr1")) loc1 <- locateVariants(vcf, txdb, IntergenicVariants()) loc2 <- locateVariants(rowRanges(vcf), txdb, IntergenicVariants()) checkIdentical(loc1, loc2) } test_locateVariants_ignore.strand <- function() { cdsbytx <- cdsbytx[1:5] gr <- GRanges("chr1", IRanges(c(12190, 12595, 13403), width=1), "-") loc1 <- locateVariants(gr, cdsbytx, CodingVariants(), ignore.strand=TRUE) checkIdentical(c(1L, 2L, 3L), mcols(loc1)$QUERYID) loc2 <- locateVariants(gr, cdsbytx, CodingVariants(), ignore.strand=FALSE) checkIdentical(integer(), mcols(loc2)$QUERYID) loc1 <- locateVariants(gr, cdsbytx, SpliceSiteVariants(), ignore.strand=TRUE) checkIdentical(c(1L, 2L, 3L), mcols(loc1)$QUERYID) loc2 <- locateVariants(gr, cdsbytx, SpliceSiteVariants(), ignore.strand=FALSE) checkIdentical(integer(), mcols(loc2)$QUERYID) } test_locateVariants_asHits <- function() { gr <- GRanges("chr1", IRanges(c(12190, 69091, 13403), width=1)) loc <- locateVariants(gr, cdsbytx, CodingVariants()) hit <- locateVariants(gr, cdsbytx, CodingVariants(), asHits=TRUE) ## annotation element loc_nms <- as.character(mcols(loc)$TXID) hit_nms <- names(cdsbytx[subjectHits(hit)]) checkIdentical(loc_nms, hit_nms) ## Hits lengths checkIdentical(length(gr), queryLength(hit)) checkIdentical(length(cdsbytx), subjectLength(hit)) } .extract <- function(x, col) as.vector(mcols(x)[[col]]) test_locateVariants_PromoterVariants <- function() { s <- GRangesList(GRanges("chr1", IRanges(10, width=11), "+"), GRanges("chr1", IRanges(30, width=11) , "+")) ## empty q <- GRanges("chr1", IRanges(15, width=1), "+") current <- locateVariants(q, s, PromoterVariants(5, 5)) checkTrue(length(current) == 0) ## endpoint q <- GRanges("chr1", IRanges(20, width=1), "+") current <- locateVariants(q, s, PromoterVariants(5, 5)) checkTrue(length(current) == 0) ## strand q <- GRanges(c("chr1", "chr1"), IRanges(c(8, 12), width=1), "+") current <- locateVariants(q, s, PromoterVariants(5, 5)) checkEquals(c(1L, 2L), .extract(current, "QUERYID")) strand(s) <- RleList(Rle(factor("*")), Rle(factor("*"))) strand(q) <- "*" current <- suppressWarnings(locateVariants(q, s, PromoterVariants(5, 5))) checkEquals(c(1L, 2L), .extract(current, "QUERYID")) q <- GRanges(c("chr1", "chr1"), IRanges(c(21, 41), width=1), "-") strand(s) <- RleList(Rle(factor("-")), Rle(factor("-"))) current <- locateVariants(q, s, PromoterVariants(5, 5)) checkEquals(c(1L, 2L), .extract(current, "QUERYID")) q <- GRanges(c("chr2", "chr2"), IRanges(c(9, 10), width=1), "+") s <- GRangesList(GRanges("chr2", IRanges(10, width=11), "+")) current <- locateVariants(q, s, PromoterVariants(5, 0)) checkEquals(1L, .extract(current, "QUERYID")) current <- locateVariants(q, s, PromoterVariants(5, 1)) checkEquals(c(1L, 2L), .extract(current, "QUERYID")) current <- locateVariants(q, s, PromoterVariants(0, 0)) checkTrue(length(current) == 0L) q <- GRanges("chr22", IRanges(50310410, 50310420)) current <- locateVariants(q, txdb, PromoterVariants()) checkIdentical(unique(current$GENEID), "79174") } test_locateVariants_match_predictCoding <- function() { library(BSgenome.Hsapiens.UCSC.hg19) gr <- GRanges("chr20", IRanges( start=c(77055, 77054, 77054, 77058, 77057, 77057, 77055), end=c(77055, 77055, 77055, 77058, 77058, 77058, 77054)), paramRangeID=rep(NA, 7)) fixed <- DataFrame( REF=DNAStringSet(c('T', 'AT', 'AT', 'A', 'AA', 'AA', 'T')), ALT=DNAStringSetList('G', 'A', 'ATT', 'G', 'A', 'AAT', 'G'), QUAL=70, FILTER="PASS") vcf <- VCF(rowRanges=gr, fixed=fixed) ## coding regions match, zero-width loc <- locateVariants(vcf, txdb, CodingVariants()) coding <- predictCoding(vcf, txdb, Hsapiens) checkIdentical(loc$QUERYID, as.integer(1:7)) checkIdentical(length(coding) , 6L) checkIdentical(unname(loc$CDSID[1:6]), unname(coding$CDSID)) checkIdentical(unname(as.character(coding$VARCODON[c(1,4)])), as.character(DNAStringSet(c("AAG", "TAG")))) } gr2 <- GRanges("chr20", IRanges( start=c(5, 77054, 77054, 77058, 77057, 77057, 77055), end=c(55, 77055, 77055, 77058, 77058, 77058, 77054)), paramRangeID=rep(NA, 7)) VariantAnnotation/inst/unitTests/test_predictCoding-methods.R0000644000175100017510000001045514614305321025615 0ustar00biocbuildbiocbuildquiet <- suppressWarnings library(BSgenome.Hsapiens.UCSC.hg19) fun <- VariantAnnotation:::.predictCodingGRangesList cdsbytx <- GRangesList(tx1=GRanges(seqnames="chr1", IRanges(c(10001, 10010), width=5), strand="+"), tx2=GRanges(seqnames="chr1", IRanges(c(10100, 10001), width=5), strand="-"), tx3=GRanges(seqnames="chr1", IRanges(c(10010, 10001), width=5), strand="-")) test_predictCoding_empty <- function() { query <- GRanges("chr1", IRanges(start=c(1, 10, 20), width=1)) current <- fun(query, cdsbytx, Hsapiens, DNAStringSet(c("G", "T", "A"))) checkIdentical(dim(mcols(current)), c(0L, 8L)) } test_predictCoding_varAllele <- function() { variant=DNAStringSet(c("G", "", "C", "AA", "GGA")) query <- GRanges(seqnames="chr1", ranges=IRanges(c(rep(10003, 3), 10011, 10101), width=c(1, 1, 1, 2, 3)), strand=c("+", "-", "*", "*", "*"), variant=variant) names(query) <- LETTERS[1:5] current <- quiet(fun(query, cdsbytx[1:2], Hsapiens, variant)) current_varaa <- values(current[names(current) == "B"])[["VARAA"]] checkTrue(as.character(current_varaa) == "") current_consequence <- values(current[names(current) == "B"])[["CONSEQUENCE"]] checkTrue(current_consequence == "not translated") variant=DNAStringSet(c("GGA", "GGA")) query <- GRanges("chr1", IRanges(rep(10101, 2), width=c(2,3)), variant=variant) current <- quiet(fun(query, cdsbytx[1:2], Hsapiens, variant)) checkIdentical(unname(as.character(mcols(current)$VARCODON)), c("TATCCGG", "TTCCGG")) } test_mapToTranscripts <- function() { ## both in 'first' cds query <- GRanges(seqnames="chr1", ranges=IRanges(rep(c(10002, 10005), 2), width=1), strand=c("+", "+", "-", "-")) current <- mapToTranscripts(query, cdsbytx[c(1,3)], ignore.strand=FALSE) expected <- IRanges(c(2, 5, 9, 6), width=1) checkIdentical(ranges(current), expected) ## one in each cds query <- GRanges(seqnames="chr1", ranges=IRanges(rep(c(10002, 10011), 2), width=1), strand=c("+", "+", "-", "-")) current <- mapToTranscripts(query, cdsbytx[c(1,3)], ignore.strand=FALSE) expected <- IRanges(c(2, 7, 9, 4), width=1) checkIdentical(ranges(current), expected) ## both in 'last' cds query <- GRanges(seqnames="chr1", ranges=IRanges(rep(c(10010, 10013), 2), width=1), strand=c("+", "+", "-", "-")) current <- mapToTranscripts(query, cdsbytx[c(1,3)], ignore.strand=FALSE) expected <- IRanges(c(6, 9, 5, 2), width=1) checkIdentical(ranges(current), expected) } test_predictCoding_strand <- function() { variant=DNAStringSet(c("G", "G", "C", "T", "G")) query <- GRanges(seqnames="chr1", ranges=IRanges(c(rep(10003, 3), 10011, 10101), width=1), strand=c("+", "-", "*", "*", "*"), variant=variant) names(query) <- LETTERS[1:5] current <- quiet(fun(query, cdsbytx, Hsapiens, variant)) expected <- c("G", "C", "C", "C", "G", "G", "T", "A", "C") checkIdentical(as.character(mcols(current)$varAllele), expected) ## query "+", subject "-" v <- variant[2] q <- query[2] strand(q) <- "+" s <- cdsbytx[3] current <- quiet(fun(q, s, Hsapiens, v, ignore.strand=FALSE)) checkIdentical(length(current), 0L) current <- quiet(fun(q, s, Hsapiens, v, ignore.strand=TRUE)) checkIdentical(as.character(mcols(current)$REFAA), "V") checkIdentical(as.character(mcols(current)$VARAA), "A") checkIdentical(mcols(current)$CDSLOC, IRanges(8, 8)) ## query "-", subject "+" strand(q) <- "-" s <- cdsbytx[1] current <- quiet(fun(q, s, Hsapiens, v, ignore.strand=FALSE)) checkIdentical(length(current), 0L) current <- quiet(fun(q, s, Hsapiens, v, ignore.strand=TRUE)) checkIdentical(as.character(mcols(current)$REFAA), "*") checkIdentical(as.character(mcols(current)$VARAA), "*") checkIdentical(mcols(current)$CDSLOC, IRanges(3, 3)) } VariantAnnotation/inst/unitTests/test_readVcf-methods.R0000644000175100017510000002245114614305321024410 0ustar00biocbuildbiocbuildtest_readVcf_format <- function() { ## arrays in geno fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") checkTrue(class(geno(vcf)$HQ) == "array") ## missing QUAL, FILTER, INFO fl <- system.file(package="VariantAnnotation", "unitTests", "cases", "no_INFO_header.vcf") vcf <- suppressWarnings(readVcf(fl, "hg19")) checkTrue("DNAStringSetList" == class(alt(vcf))) checkTrue("numeric" == class(qual(vcf))) checkTrue("character" == class(filt(vcf))) ## structural fl <- system.file("extdata", "structural.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") checkTrue(class(alt(vcf)) == "CompressedCharacterList") checkIdentical(qual(vcf), c(6, NA, 6, 12, 23, 14, 11)) } test_readVcf_unspecified_INFO_FORMAT <- function() { ## As of 1.7.32, warnings are no longer thrown for 'INFO' ## and 'FORMAT' fields in the data but with no header entry. ## Fields are silently skipped. fl <- system.file(package="VariantAnnotation", "unitTests", "cases", "unspecified_INFO_FORMAT_fields.vcf") vcf <- readVcf(fl, "hg19") ## columns immediately after XX entries exp <- c(14L, 11L, 10L, 13L, 9L) checkIdentical(exp, info(vcf)$DP) exp <- NumericList(0.5, 0.017, c(0.333, 0.667), NA, c(NA, NA)) checkIdentical(exp, info(vcf)$AF) ## columns immediately after FORMAT entries exp <- c("0|0", "0/1", "0|0", "0/2", "0/0", "1/1") checkIdentical(exp, as.vector(geno(vcf)$GT[4:5,])) exp <- c(56L, NA, 51L, NA, NA, NA, 60L, NA, 51L, NA, NA, NA) checkIdentical(exp, as.vector(geno(vcf)$HQ[4:5,,])) } test_readVcf_fewer_FORMAT_than_GENO <- function() { fl <- system.file(package="VariantAnnotation", "unitTests", "cases", "fewer-FORMAT-than-GENO.vcf") exp <- "record 2 sample H1993: fewer FORMAT fields than GENO fields" obs <- tryCatch(readVcf(fl, "hg19"), warning=conditionMessage) checkIdentical(exp, obs) } test_readVcf_missing_FORMAT_metadata_elt <- function() { fl <- system.file(package="VariantAnnotation", "unitTests", "cases", "missing-FORMAT-metadata-elt.vcf") vcf <- readVcf(fl, "hg19") exp <- c(1L, NA_integer_, 1L) obs <- unlist(geno(vcf)$AP, use.names=FALSE) checkIdentical(exp, obs) } test_readVcf_no_GENO_row <- function() { fl <- system.file(package="VariantAnnotation", "unitTests", "cases", "no_GENO_row.vcf") exp <- c(582L, NA, 584L, 583L, NA, 585L) vcf <- readVcf(fl, "hg19") checkIdentical(exp, as.vector(geno(vcf)[["DP"]])) } test_readVcf_ranges <- function() { fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") checkEquals(width(rowRanges(vcf)), width(ref(vcf))) compressVcf <- bgzip(fl, tempfile()) idx <- indexTabix(compressVcf, "vcf") tab <- TabixFile(compressVcf, idx) rd <- rowRanges(vcf) param <- ScanVcfParam(which=rd) vcf_rd <- readVcf(tab, "hg19", param) checkIdentical(values(info(vcf))[c("AA", "AF", "DB", "DP", "H2")], values(info(vcf_rd))[c("AA", "AF", "DB", "DP", "H2")]) param <- ScanVcfParam(which=rd[c(3,5)]) vcf_rd <- readVcf(tab, "hg19", param) checkEquals(2L, dim(vcf_rd)[1]) } test_readVcf_param <- function() { fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") gnms <- c("GT", "GQ", "DP", "HQ") inms <- c("NS", "DP", "AF", "DB") snms <- c("NA00001", "NA00002", "NA00003") ## samples samp <- snms[3:2] vcf <- readVcf(fl, "hg19", param=ScanVcfParam(samples=samp)) checkTrue(ncol(vcf) == 2L) checkIdentical(colnames(vcf), snms[3:2]) param <- ScanVcfParam(geno=c("GT", "HQ"), samples=snms) vcf1 <- readVcf(fl, "hg19") vcf2 <- readVcf(fl, "hg19", param=param) checkIdentical(geno(vcf1)$GT, geno(vcf2)$GT) checkIdentical(geno(vcf1)$HQ, geno(vcf2)$HQ) samp <- snms[3] param <- ScanVcfParam(geno=c("GT", "HQ"), samples=samp) vcf3 <- readVcf(fl, "hg19", param=param) current <- c(geno(vcf3)$GT) checkIdentical(unname(geno(vcf1)$GT[,samp]), current) current <- c(geno(vcf3)$HQ) checkIdentical(c(geno(vcf1)$HQ[,samp,]), current) ## geno g <- gnms[3:2] param <- ScanVcfParam(geno=g) vcf <- readVcf(fl, "hg19", param) checkTrue(length(names(geno(vcf))) == length(g)) checkIdentical(names(geno(vcf)), gnms[3:2]) fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") param1 <- ScanVcfParam(which=GRanges("22", IRanges(5e7, 50302629))) vcf1 <- readVcf(fl, "hg19", param=param1) param2 <- ScanVcfParam(which=rowRanges(vcf1)[1:10]) vcf2 <- readVcf(fl, "hg19", param=param2) checkIdentical(geno(vcf1)$GT[1:10, ], geno(vcf2)$GT) ## info fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") i <- inms[c(4,1)] param <- ScanVcfParam(info=i) vcf <- readVcf(fl, "hg19", param) checkTrue(ncol(info(vcf)) == length(i)) checkIdentical(colnames(info(vcf)), inms[c(4,1)]) ## geno, info param <- ScanVcfParam() vcf1 <- readVcf(fl, "hg19", param) vcf2 <- readVcf(fl, "hg19") checkIdentical(names(geno(vcf1)), names(geno(vcf2))) checkIdentical(rowRanges(vcf1), rowRanges(vcf2)) ## info, geno, ranges, samples g <- gnms[1] i <- inms[2:3] s <- snms[3] rngs <- GRanges("20", IRanges(1110000, 1234600)) param <- ScanVcfParam(geno=g, info=i, which=rngs, samples=s) compressVcf <- bgzip(fl, tempfile()) idx <- indexTabix(compressVcf, "vcf") tab <- TabixFile(compressVcf, idx) vcf <- readVcf(tab, "hg19", param) checkTrue(all(i %in% colnames(info(vcf)))) checkTrue(all(names(geno(vcf)) %in% g)) checkTrue(length(rowRanges(vcf)) == 3) checkTrue(ncol(vcf) == 1L) checkTrue(colnames(vcf) == s) ## no info, geno, samples checkTrue(validObject(readVcf(fl, "hg19", ScanVcfParam(geno=NA)))) checkTrue(validObject(readVcf(fl, "hg19", ScanVcfParam(info=NA)))) obs <- # no warnings on samples=NA tryCatch(readVcf(fl, "hg19", ScanVcfParam(samples=NA)), warning=conditionMessage) checkTrue(is(obs, "VCF") && validObject(obs)) } test_readVcf_genome <- function() { fl <- system.file("extdata", "structural.vcf", package="VariantAnnotation") checkException(readVcf(fl, genome=2), silent=TRUE) vcf0 <- readVcf(fl, "test") si0 <- seqinfo(vcf0) ## no param si1 <- si0 isCircular(si1) <- rep(TRUE, 4) vcf1 <- readVcf(fl, si1) checkIdentical(si1, seqinfo(vcf1)) si2 <- si0[c("1", "2")] vcf2 <- readVcf(fl, si2) checkIdentical(unname(genome(vcf2)), c("test", "test", NA, NA)) si3 <- Seqinfo(as.character(1:5), NA, NA, "test") vcf3 <- readVcf(fl, si3) checkIdentical(merge(si3, si0), seqinfo(vcf3)) ## param bgz <- bgzip(fl, tempfile()) idx <- indexTabix(bgz, "vcf") tab <- TabixFile(bgz, idx) param <- GRanges(c("2", "3"), IRanges(c(321682, 12665100), width=1)) si4 <- Seqinfo(c("2", "3"), NA, NA) vcf4 <- readVcf(tab, si4, param=param) checkIdentical(si4, seqinfo(rowRanges(vcf4))) si5 <- Seqinfo("2", NA, NA) checkException(readVcf(tab, si5, param=param), silent=TRUE) si6 <- Seqinfo(c("1", "2", "3"), NA, NA) vcf6 <- readVcf(tab, si6, param=param) checkIdentical(merge(si6, si4), seqinfo(vcf6)) } test_readVcf_tabix <- function() { fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") param1 <- GRanges(seqnames="20", ranges=IRanges(start=17320, end=17330)) param2 <- GRanges(seqnames="20", ranges=IRanges(start=17330, end=17330)) param3 <- GRanges(seqnames="20", ranges=IRanges(start=17330, end=17340)) cmp <- bgzip(fl, tempfile()) idx <- indexTabix(cmp, "vcf") tbx <- TabixFile(cmp, idx) scn1 <- scanTabix(tbx, param=param1) scn2 <- scanTabix(tbx, param=param2) scn3 <- scanTabix(tbx, param=param3) names(scn1) <- names(scn2) <- names(scn3) <- NULL checkIdentical(scn1, scn2) checkIdentical(scn2, scn3) checkIdentical(scn1, scn3) } test_readGT <- function() { fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") GT <- readGT(fl, nucleotides=TRUE) checkIdentical(colnames(GT), c("NA00001", "NA00002", "NA00003")) checkIdentical(unname(GT[1,]), c("G|G", "A|G", "A/A")) checkIdentical(unname(GT[2,]), c("T|T", "T|A", "T/T")) checkIdentical(unname(GT[5,]), c("GTC/G", "GTC/GTCT", "G/G")) ## genotypeCodesToNucleotides vcf0 <- readVcf(fl, "") vcf1 <- genotypeCodesToNucleotides(vcf0) checkIdentical(GT, geno(vcf1)$GT) fl <- system.file("unitTests", "cases", "no_INFO_header.vcf", package="VariantAnnotation") GT <- readGT(fl, nucleotides=TRUE) checkIdentical(unname(GT[,1]), rep("./.", 5)) ## genotypeCodesToNucleotides vcf0 <- readVcf(fl, "") vcf1 <- genotypeCodesToNucleotides(vcf0) checkIdentical(GT, geno(vcf1)$GT) } test_buffer_realloc <- function() { fl <- system.file("unitTests", "cases", "buffer_realloc.vcf", package="VariantAnnotation") vcf <- readVcf(fl) target <- c("gridss9_272646b", "gridss9_31852o") checkIdentical(target, names(vcf)) target <- ".GGGGGGGGG" checkIdentical(target, alt(vcf)[[1]]) } VariantAnnotation/inst/unitTests/test_scanVcf.R0000644000175100017510000001246514614305321022764 0ustar00biocbuildbiocbuildfl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") scn <- scanVcf(fl) test_FixedTypes <- function() { .vcf_map_fixed <- VariantAnnotation:::.vcf_map_fixed exp <- exp0 <- list(rowRanges=NULL, REF=NULL, ALT=list("A", character()), QUAL=list("1", numeric()), FILTER=list("1", character())) named <- names(exp)[-(1:2)] checkIdentical(exp, .vcf_map_fixed(character(), FALSE)) checkIdentical(exp[1:2], .vcf_map_fixed(NA, FALSE)) exp <- exp0 exp[1] <- list(NULL) checkIdentical(exp, .vcf_map_fixed(named, FALSE)) warn <- FALSE obs <- withCallingHandlers({ .vcf_map_fixed("FOO", FALSE) }, warning=function(w) { warn <<- TRUE invokeRestart("muffleWarning") }) checkTrue(warn) checkIdentical(exp[1:2], obs) } test_InfoTypes <- function() { fmt <- info(scanVcfHeader(fl)) info <- scn[[1]]$INFO checkIdentical(as.integer(c(3, 3, 2, 3, 3)), info$NS) checkIdentical(as.integer(c(14, 11, 10, 13, 9)), info$DP) checkTrue(is(info$AF,"matrix")) checkIdentical(c(TRUE, FALSE, TRUE, FALSE, FALSE), info$DB) checkIdentical(c(TRUE, rep(FALSE, 4)), info$H2) } test_GenoTypes <- function() { fmt <- geno(scanVcfHeader(fl)) geno <- scn[[1]]$GENO checkEquals(typeof(unlist(geno$GT)), "character") checkIdentical(lapply(geno, function(x) class(x)[1]), list(GT="matrix", GQ="matrix", DP="matrix", HQ="array")) mat <- matrix(c(1, 3, 6, 7, 4, 8, 5, 0, 4, 2, 5, 3, 4, 2, 3), nrow=5, dimnames=list(NULL, c("NA00001", "NA00002", "NA00003"))) checkEquals(mat, geno$DP) } test_scanVcf_no_FORMAT_column <- function() { ## no FORMAT -- don't parse GENO fl <- system.file(package="VariantAnnotation", "unitTests", "cases", "no_FORMAT_column.vcf") geno <- scanVcf(fl)[[1]]$GENO checkIdentical(setNames(list(), character()), geno) } test_scanVcf_FORMAT_header_no_SAMPLEs <- function() { ## GENO tags, but no SAMPLE or actual samples fl <- system.file(package="VariantAnnotation", "unitTests", "cases", "FORMAT_header_no_SAMPLEs.vcf") geno <- scanVcf(fl)[[1]]$GENO checkIdentical(c("GT", "DS", "GL"), names(geno)) checkTrue(all(sapply(geno, nrow) == 5L)) checkTrue(all(sapply(geno, ncol) == 0L)) } test_scanVcf_no_INFO_header <- function() { fl <- system.file(package="VariantAnnotation", "unitTests", "cases", "no_INFO_header.vcf") info <- suppressWarnings(scanVcf(fl)[[1]]$INFO$INFO) checkIdentical(rep(".", 5L), info) } test_scanVcf_negative_Number <- function() { fl <- system.file(package="VariantAnnotation", "unitTests", "cases", "negative_FORMAT_Number.vcf") pl <- scanVcf(fl)[[1]]$GENO$PL checkIdentical(3L, unique(sapply(pl, length))) checkIdentical(761L, sum(sapply(pl, sum))) } test_scanVcf_crlf <- function() { writeLines(readLines(fl), xx <- tempfile(), sep="\r\n") checkIdentical(scanVcfHeader(fl), scanVcfHeader(xx)) } test_scanVcf_connection_n <- function() { fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") res <- scanVcf(file(fl)) checkIdentical(5L, length(res[[1]]$REF)) res <- scanVcf(file(fl), n = 1000) checkIdentical(5L, length(res[[1]]$REF)) res <- scanVcf(file(fl), n = 1) checkIdentical(1L, length(res[[1]]$REF)) vcf <- file(fl) open(vcf) for (i in 1:10) { res <- scanVcf(vcf, n = 1) if (!length(res[[1]]$REF)) break } close(vcf) checkIdentical(6L, i) } test_scanVcfHeader <- function() { checkIdentical(VCFHeader(), scanVcfHeader()) checkIdentical(VCFHeader(), scanVcfHeader(character())) } test_scanVcfHeader_VarScan <- function() { fl <- system.file("unitTests", "cases", "VarScan_header.vcf", package="VariantAnnotation") hd <- scanVcfHeader(fl) checkIdentical(dim(info(hd)), c(7L, 3L)) checkIdentical(names(info(hd)), c("Number", "Type", "Description")) expected <- paste0("Somatic status of variant ", "(0=Reference,1=Germline,2=Somatic,3=LOH, or 5=Unknown)") checkIdentical(info(hd)["SS", "Description"], expected) fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") hd <- scanVcfHeader(fl) checkIdentical(length(names(header(hd))), 11L) nms <- c("fileDate", "fileformat", "phasing", "reference", "source", "contig", "SAMPLE", "PEDIGREE") checkIdentical(names(meta(hd)), nms) checkIdentical(header(hd)$contig[["assembly"]], "B36") } test_scanVcfHeader_META <- function() { fl <- system.file("unitTests", "cases", "meta_header.vcf", package="VariantAnnotation") hd <- scanVcfHeader(fl) nms <- c("fileformat", "Tassel", "META", "SAMPLE") checkIdentical(names(meta(hd)), nms) } test_scan_row.names <- function() { fl <- system.file("extdata", "chr7-sub.vcf.gz", package="VariantAnnotation") scn <- scanVcf(fl)[[1]] checkTrue(!is.null(names(scn$rowRanges))) scn <- scanVcf(fl, row.names=FALSE) checkTrue(is.null(names(scn$rowRanges))) param <- ScanVcfParam(which=GRanges("7", IRanges(55000723, 55000789))) scn <- scanVcf(fl, param=param, row.names=FALSE) checkTrue(is.null(names(scn$rowRanges))) } VariantAnnotation/inst/unitTests/test_ScanVcfParam-class.R0000644000175100017510000000550014614305321025000 0ustar00biocbuildbiocbuildtest_ScanVcfParam_which <- function() { which <- IRangesList(seq1=IRanges(1000, 2000), seq2=IRanges(c(100, 1000), c(1000, 2000))) svp <- ScanVcfParam(which=which) checkIdentical(which, vcfWhich(svp)) checkException(vcfWhich(svp) <- DataFrame(), silent=TRUE) checkException(vcfWhich(svp) <- SimpleList(), silent=TRUE) } test_ScanVcfParam_fixed <- function() { fx <- c("GT", "ALT") svp <- ScanVcfParam(fixed=fx) checkIdentical(fx, vcfFixed(svp)) checkException(vcfFixed(svp) <- DataFrame(), silent=TRUE) checkException(vcfFixed(svp) <- 1:5, silent=TRUE) fx <- NA_character_ svp <- ScanVcfParam(fixed=fx) checkIdentical(fx, vcfFixed(svp)) } test_ScanVcfParam_info <- function() { info <- c("NS", "DP") svp <- ScanVcfParam(info=info) checkIdentical(info, vcfInfo(svp)) checkException(vcfInfo(svp) <- DataFrame(), silent=TRUE) checkException(vcfInfo(svp) <- 1:5, silent=TRUE) info <- NA_character_ svp <- ScanVcfParam(info=info) checkIdentical(info, vcfInfo(svp)) } test_ScanVcfParam_geno <- function() { geno <- c("GT", "GQ") svp <- ScanVcfParam(geno=geno) checkIdentical(geno, vcfGeno(svp)) checkException(vcfGeno(svp) <- DataFrame(), silent=TRUE) checkException(vcfGeno(svp) <- 1:5, silent=TRUE) geno <- NA_character_ svp <- ScanVcfParam(geno=geno) checkIdentical(geno, vcfGeno(svp)) } test_ScanVcfParam_samples <- function() { samp <- c("GT", "GQ") svp <- ScanVcfParam(samples=samp) checkIdentical(samp, vcfSamples(svp)) checkException(vcfSamples(svp) <- DataFrame(), silent=TRUE) checkException(vcfSamples(svp) <- 1:5, silent=TRUE) checkException(ScanVcfParam(geno="DP", samples=NA), silent=TRUE) checkException(ScanVcfParam(geno=NA, samples="foo"), silent=TRUE) } test_ScanVcfParam_trimEmpty <- function() { svp <- ScanVcfParam() checkIdentical(TRUE, vcfTrimEmpty(svp)) vcfTrimEmpty(svp) <- FALSE checkIdentical(FALSE, vcfTrimEmpty(svp)) checkException(vcfTrimEmpty(svp) <- "a", silent=TRUE) checkException(vcfTrimEmpty(svp) <- 1:5, silent=TRUE) ## FIXME : should this work? #checkException(vcfTrimEmpty(svp) <- NA, silent=TRUE) } test_ScanVcfParam_GRangesList <- function() { fl <- system.file("extdata", "structural.vcf", package="VariantAnnotation") compressVcf <- bgzip(fl, tempfile()) idx <- indexTabix(compressVcf, "vcf") tab <- TabixFile(compressVcf, idx) gr1 <- GRanges("1", IRanges(13219, 2827695, name="regionA")) gr2 <- GRanges(rep("2", 2), IRanges(c(321680, 14477080), c(321689, 14477090), name=c("regionB", "regionC"))) grl <- GRangesList("1"=gr1, "2"=gr2) vcf_grl <- readVcf(tab, "hg19", grl) gr <- unlist(grl, use.names=FALSE) vcf_gr <- readVcf(tab, "hg19", gr) checkIdentical(rowRanges(vcf_grl), rowRanges(vcf_gr)) } VariantAnnotation/inst/unitTests/test_SIFTandPolyPhen.R0000644000175100017510000000201714614305321024300 0ustar00biocbuildbiocbuildlibrary(SIFT.Hsapiens.dbSNP132) library(PolyPhen.Hsapiens.dbSNP131) quiet <- suppressWarnings test_SIFT_132 <- function() { db <- SIFT.Hsapiens.dbSNP132 scol <- columns(db) checkIdentical(length(scol), 10L) res <- select(db, "rs2142947") checkIdentical(nrow(res), 4L) res <- select(db, "rs2142947", columns="AACHANGE") checkIdentical(nrow(res), 1L) res <- quiet(select(db, keys=c("rs17970171", "INVALID", "rs17970171"))) checkIdentical(nrow(res), 9L) checkTrue(all(res$RSID %in% c("rs17970171", "INVALID"))) } test_PolyPhen <- function() { db <- PolyPhen.Hsapiens.dbSNP131 pcol <- columns(db) checkIdentical(length(pcol), 58L) res <- select(db, "rs3026284") checkIdentical(nrow(res), 2L) res <- select(db, "rs3026284", columns="POS") checkIdentical(nrow(res), 1L) res <- suppressWarnings(select(db, keys=c("rs3026284", "INVALID", "rs3026284"))) checkIdentical(nrow(res), 5L) checkTrue(all(res$RSID %in% c("rs3026284", "INVALID"))) } VariantAnnotation/inst/unitTests/test_snpSummary.R0000644000175100017510000000251314614305321023550 0ustar00biocbuildbiocbuildtest_snpSummary_empty <- function() { cnames <- c("g00", "g01", "g11", "a0Freq", "a1Freq", "HWEzscore", "HWEpvalue") ## no genotype fl <- system.file("unitTests", "cases", "FORMAT_header_no_SAMPLEs.vcf", package="VariantAnnotation") res <- suppressWarnings(snpSummary(readVcf(fl, "hg19"))) checkTrue(all(dim(res) == c(0L, 7L))) checkEquals(names(res), cnames) ## structural fl <- system.file("extdata", "structural.vcf", package="VariantAnnotation") res <- suppressWarnings(snpSummary(readVcf(fl, "hg19"))) checkTrue(all(dim(res) == c(0L, 7L))) checkEquals(names(res), cnames) } test_snpSummary_output <- function() { fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") res <- snpSummary(vcf) checkTrue(is.integer(res$g00)) checkTrue(is.integer(res$g01)) checkTrue(is.integer(res$g11)) checkEquals(nrow(res), nrow(vcf)) checkEquals(rownames(res), rownames(vcf)) checkEquals(as.integer(res[1,c("g00", "g01", "g11")]), c(1L, 1L, 1L)) checkEquals(as.integer(res[2,c("g00", "g01", "g11")]), c(2L, 1L, 0L)) checkEquals(round(res[["a0Freq"]], 2), c(0.50, 0.83, NA, NA, NA)) checkEquals(round(res[["a1Freq"]], 2), c(0.50, 0.17, NA, NA, NA)) } VariantAnnotation/inst/unitTests/test_summarizeVariants-methods.R0000644000175100017510000000117314614305321026560 0ustar00biocbuildbiocbuildgrl <- GRangesList( A=GRanges("20", IRanges(14370, 17331)), B=GRanges("20", IRanges(17330, width=1)), C=GRanges("20", IRanges(1110696, width=1)), D=GRanges("20", IRanges(1110696, width=2))) test_summarizeVariants <- function() { fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") sv <- summarizeVariants(grl, vcf, findOverlaps) checkIdentical(ncol(vcf), ncol(sv)) checkIdentical(length(grl), nrow(sv)) target <- matrix(c(0, 0, 1, 1, 2, 1, 1, 1, 1, 0, 1, 1), ncol=3) current <- unname(assays(sv)$counts) checkIdentical(current, target) } VariantAnnotation/inst/unitTests/test_VCF-class.R0000644000175100017510000002333414614305321023117 0ustar00biocbuildbiocbuild test_VCF_construction <- function() { ## empty m1 <- matrix(0, 0, 0) checkTrue(validObject(VCF())) checkTrue(validObject(VCF(collapsed=TRUE))) checkTrue(validObject(VCF(collapsed=FALSE))) checkTrue(validObject(VCF(geno=SimpleList(m1)))) ## substance fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") target <- readVcf(fl, genome="hg19") current <- VCF(rowRanges=rowRanges(target), colData=colData(target), geno=geno(target), info=info(target), fixed=fixed(target)) checkTrue(validObject(current)) checkIdentical("hg19", unique(genome(rowRanges(target)))) } test_VCF_fixed <- function() { fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf <- readVcf(fl, genome="hg19") vcf1 <- vcf ## ref checkTrue(class(ref(vcf)) == "DNAStringSet") checkException(ref(vcf) <- NULL, silent=TRUE) checkException(ref(vcf) <- as.character(ref(vcf)), silent=TRUE) ref(vcf1) <- ref(vcf)[1] checkIdentical(rep(ref(vcf)[1], nrow(vcf)), ref(vcf1)) ## alt checkTrue(class(alt(vcf)) == "DNAStringSetList") checkException(alt(vcf) <- NULL, silent=TRUE) v1 <- vcf alt(v1) <- CharacterList(list("A", "A", c("G", "T"), "", c("G", "GTCT"))) checkTrue(validObject(v1)) alt(vcf1) <- alt(vcf)[1] checkIdentical(rep(alt(vcf)[1], nrow(vcf)), alt(vcf1)) ## qual checkTrue(class(qual(vcf)) == "numeric") checkException(qual(vcf) <- NULL, silent=TRUE) checkException(qual(vcf) <- as.character(qual(vcf)), silent=TRUE) qual(vcf1) <- qual(vcf)[1] # recylcing checkIdentical(rep(qual(vcf)[1], nrow(vcf)), qual(vcf1)) ## filt checkTrue(class(filt(vcf)) == "character") checkException(filt(vcf) <- NULL, silent=TRUE) checkException(filt(vcf) <- as.list(filt(vcf)), silent=TRUE) filt(vcf1) <- filt(vcf)[1] # recylcing checkIdentical(rep(filt(vcf)[1], nrow(vcf)), filt(vcf1)) ## fixed checkTrue(is(fixed(vcf), "DataFrame")) checkException(fixed(vcf) <- NULL, silent=TRUE) checkException(fixed(vcf) <- as.matrix(fixed(vcf)), silent=TRUE) DF <- DataFrame(REF=DNAStringSet(c("A", "C", "T", "T", "C")), ALT=CharacterList(list("C", "G", "A", "G", "G")), QUAL=c(10, 20, NA, 10, 10), FILTER=c("pass", "pass", "q10", "q10", "pass")) df <- DF names(df) <- c("reference", "ALT", "QUAL", "FILTER") checkException(fixed(vcf) <- df, silent=TRUE) df <- DF names(df) <- c("REF", "ALT", "qual", "FILTER") checkException(fixed(vcf) <- df, silent=TRUE) df <- DF df$QUAL <- as.character(df$QUAL) checkException(fixed(vcf) <- df, silent=TRUE) df <- DF df$ALT <- unlist(df$ALT, use.names=FALSE) checkException(fixed(vcf) <- df, silent=TRUE) df <- DF df$REF <- as.character(df$REF) checkException(fixed(vcf) <- df, silent=TRUE) } test_VCF_rowRanges_info_geno <- function() { fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf <- readVcf(fl, genome="hg19") ## rowRanges v1 <- vcf rowRanges(v1) <- rowRanges(v1, fixed=FALSE)[5:1] checkIdentical(rownames(vcf), rev(rownames(v1))) ## info checkTrue(is(info(vcf), "DataFrame")) checkException(info(vcf) <- NULL, silent=TRUE) v1 <- vcf checkException(info(v1) <- DataFrame(), silent=TRUE) checkTrue(class(info(vcf)$AF) == "CompressedNumericList") AF <- NumericList(0.5, 0.017, c(0.333,0.667), NA, c(NA, NA)) checkIdentical(info(vcf)$AF, AF) ## geno checkTrue(class(geno(vcf)) == "SimpleList") checkException(geno(vcf) <- NULL, silent=TRUE) checkIdentical(geno(vcf)$CNQ, geno(vcf)[["CNQ"]]) checkIdentical(geno(vcf)[["CN"]], assays(vcf)[["CN"]]) checkTrue(is(geno(vcf, "GT"), "matrix")) v1 <- vcf geno(v1, "GT") <- matrix(NA, nrow=5, ncol=3) checkIdentical(unique(as.vector(geno(v1, "GT"))), NA) } test_VCF_subset <- function() { fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf <- readVcf(fl, genome="hg19") ## numeric ss1 <- vcf[2:3,] checkIdentical(c(2L, ncol(vcf)), dim(ss1)) ss1 <- vcf[,2] checkIdentical(c(nrow(vcf), 1L), dim(ss1)) checkIdentical(rownames(ss1), rownames(info(ss1))) ss1 <- vcf[2:3, 2] checkIdentical(c(2L, 1L), dim(ss1)) checkIdentical(rownames(ss1), rownames(info(ss1))) ## character ss1 <- vcf dimnames(ss1) <- list(LETTERS[seq_len(nrow(ss1))], letters[seq_len(ncol(ss1))]) ridx <- c("B", "C") checkIdentical(rowRanges(ss1[ridx,]), rowRanges(ss1)[ridx,]) checkIdentical(rowRanges(ss1["C",]), rowRanges(ss1)["C",,drop=FALSE]) checkException(ss1[LETTERS,], "i-index out of bounds", TRUE) cidx <- "b" checkIdentical(colData(ss1[,cidx]), colData(ss1)[cidx,,drop=FALSE]) checkException(ss1[,letters], "j-index out of bounds", TRUE) ## logical ss1 <- vcf dimnames(ss1) <- list(LETTERS[seq_len(nrow(ss1))], letters[seq_len(ncol(ss1))]) checkIdentical(fixed(ss1), fixed(ss1[TRUE,])) checkIdentical(info(ss1), info(ss1[TRUE,])) checkIdentical(c(0L, ncol(ss1)), dim(ss1[FALSE,])) checkIdentical(fixed(ss1), fixed(ss1[,TRUE])) checkIdentical(info(ss1), info(ss1[,TRUE])) checkIdentical(c(nrow(ss1), 0L), dim(ss1[,FALSE])) idx <- c(TRUE, FALSE) # recycling ss2 <- ss1[idx,] checkIdentical(rowRanges(ss1)[idx,,drop=FALSE], rowRanges(ss2)) ss2 <- ss1[,idx] checkIdentical(colData(ss1)[idx,,drop=FALSE], colData(ss2)) ## 0 columns vcf <- VCF(rowRanges=GRanges("chr1", IRanges(1:10, width=1))) checkIdentical(dim(vcf[1:5, ]), c(5L, 0L)) ## 0 rows vcf <- VCF(colData=DataFrame(samples=1:10)) checkIdentical(dim(vcf[ ,1:5]), c(0L, 5L)) } test_VCF_subset_empty_slots <- function() { fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19", param=ScanVcfParam(info=NA, fixed=NA)) checkTrue(all(names(mcols(vcf)) %in% c("paramRangeID", "REF"))) checkTrue(nrow(vcf[2:4]) == 3L) checkTrue(ncol(vcf[,1:2]) == 2L) vcf <- readVcf(fl, "hg19", param=ScanVcfParam(geno=NA)) checkTrue(length(names(geno(vcf))) == 0L) checkTrue(ncol(vcf) == 0L) checkException(vcf[,1:5], silent=TRUE) checkTrue(nrow(vcf[2:4]) == 3L) } test_VCF_subsetassign <- function() { fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf <- readVcf(fl, genome="hg19") ss1 <- vcf ss1[1:2,] <- ss1[2:1,] checkIdentical(rowRanges(vcf)[2:1,], rowRanges(ss1)[1:2,]) checkIdentical(rowRanges(vcf[-(1:2),]), rowRanges(ss1)[-(1:2),]) checkIdentical(colData(vcf), colData(ss1)) checkIdentical(metadata(vcf), metadata(ss1)) ss1 <- vcf ss1[,1:2] <- ss1[,2:1,drop=FALSE] checkIdentical(colData(vcf)[2:1,,drop=FALSE], colData(ss1)[1:2,,drop=FALSE]) checkIdentical(colData(vcf)[-(1:2),,drop=FALSE], colData(ss1)[-(1:2),,drop=FALSE]) checkIdentical(rowRanges(vcf), rowRanges(ss1)) checkIdentical(metadata(vcf), metadata(ss1)) } test_VCF_seqlevels <- function() { fl <- system.file("extdata", "structural.vcf", package="VariantAnnotation") vcf <- readVcf(fl, genome="hg19") seqlev <- seqlevels(vcf) checkIdentical(seqlev, c("1", "2", "3", "4")) seqlevels(vcf)[seqlevels(vcf) == "1"] <- "chr1" checkIdentical(seqlevels(vcf), c("chr1", "2", "3", "4")) seqlevels(vcf, pruning.mode="coarse") <- "3" checkIdentical(seqlevels(vcf), "3") } quiet <- suppressWarnings test_VCF_cbind <- function() ## requires matching ranges { ## empty vcf <- VCF() empty <- cbind(vcf, vcf) checkEquals(dim(empty), c(0, 0)) ## different ranges fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf1 <- readVcf(fl, genome="hg19") vcf2 <- vcf1[2:4] rownames(vcf2) <- month.name[seq_len(nrow(vcf2))] checkException(quiet(cbind(vcf1, vcf2)), silent=TRUE) ## same ranges vcf2 <- vcf1[,1] #colnames(vcf2) <- month.name[seq_len(ncol(vcf2))] res <- cbind(vcf1, vcf2) checkTrue(nrow(res) == 5) checkTrue(ncol(res) == 4) ## info checkTrue(ncol(info(res)) == 6) info2 <- info(vcf2) info2$H2 <- !info2$H2 info(vcf2) <- info2 checkException(cbind(vcf1, vcf2), silent=TRUE) info(vcf2) <- info(vcf2)[,1:2] res <- cbind(vcf1, vcf2) checkTrue(ncol(info(res)) == 6) info(vcf2) <- DataFrame("noMatch"=1:5) res <- cbind(vcf1, vcf2) checkTrue(ncol(info(res)) == 7) ## fixed vcf2 <- vcf1[,1] res <- cbind(vcf1, vcf2) checkTrue(ncol(fixed(res)) == 4) fixed2 <- fixed(vcf2) fixed2$QUAL <- c(rep(1, 5)) fixed(vcf2) <- fixed2 checkException(cbind(vcf1, vcf2), silent=TRUE) } test_VCF_rbind <- function() ## requires matching samples { ## empty vcf0 <- VCF() empty <- rbind(vcf0, vcf0) checkEquals(dim(empty), c(0, 0)) ## different sample fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf1 <- readVcf(fl, genome="hg19") vcf2 <- vcf1[,2] colnames(vcf2) <- month.name[seq_len(ncol(vcf2))] checkException(quiet(rbind(vcf1, vcf2)), silent=TRUE) ## same samples vcf2 <- vcf1[1:3,] res <- rbind(vcf1, vcf2) checkTrue(nrow(res) == 8) checkTrue(ncol(res) == 3) ## info checkTrue(ncol(info(res)) == 6) info2 <- info(vcf2) info2$H2 <- !info2$H2 info(vcf2) <- info2 res <- rbind(vcf1, vcf2) checkTrue(ncol(info(res)) == 6) ## fixed vcf2 <- vcf1[1:3,] res <- rbind(vcf1, vcf2) checkTrue(ncol(fixed(res)) == 4) fixed2 <- fixed(vcf2) fixed2$QUAL <- c(rep(1, nrow(vcf2))) fixed(vcf2) <- fixed2 res <- rbind(vcf1, vcf2) checkTrue(ncol(fixed(res)) == 4) } VariantAnnotation/inst/unitTests/test_vcfFields.R0000644000175100017510000000206014614305321023274 0ustar00biocbuildbiocbuildtest_vcfFields <- function(){ ## invalid checkException(vcfFields(NA_character_), silent = TRUE) checkException(vcfFields(tempfile()), silent = TRUE) ## empty target <- CharacterList( fixed = character(), info = character(), geno = character(), samples = character() ) checkIdentical(target, vcfFields()) ## structure fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") flds <- vcfFields(fl) checkTrue(validObject(flds)) checkTrue(is(flds, "CharacterList")) target <- c(fixed = 4L, info = 6L, geno = 4L, samples = 3L) checkIdentical(target, lengths(flds)) ## signatures hdr <- scanVcfHeader(fl) flds.hdr <- vcfFields(hdr) vf <- VcfFile(fl) flds.vf <- vcfFields(vf) vcf <- readVcf(fl, genome = "hg19") flds.vcf <- vcfFields(vcf) checkIdentical(flds, flds.hdr) checkIdentical(flds, flds.vf) checkIdentical(flds, flds.vcf) ## VCFFileList vfl <- VcfFileList(c(fl, fl)) checkIdentical(vcfFields(vfl[[1]]), vcfFields(vfl)) } VariantAnnotation/inst/unitTests/test_VRanges-class.R0000644000175100017510000002531714614305321024051 0ustar00biocbuildbiocbuild.TARGET_seqnames <- Rle(factor(c("chr1", "chr2"))) .TARGET_ranges <- IRanges(c(1, 10), c(5, 20)) .TARGET_strand <- Rle(strand("*"), 2) .TARGET_gr <- GRanges(.TARGET_seqnames, .TARGET_ranges, .TARGET_strand) .TARGET_ref <- c("T", "A") .TARGET_alt <- c("C", "T") .TARGET_refDepth <- as.integer(c(5, 10)) .TARGET_altDepth <- as.integer(c(7, 6)) .TARGET_totalDepth <- as.integer(c(12, 17)) .TARGET_sampleNames <- factor(letters[1:2]) .TARGET_hardFilters <- FilterRules(list(a = function(x) softFilterMatrix(x)[,1])) .TARGET_softFilterMatrix <- FilterMatrix(matrix = cbind(a = c(TRUE, FALSE)), filterRules = .TARGET_hardFilters) .TARGET_tumorSpecific <- c(FALSE, TRUE) integerRle <- function(...) as(Rle(...), "integerRle") characterRle <- function(...) as(Rle(...), "characterRle") factorRle <- function(...) as(Rle(...), "factorRle") make_TARGET_VRanges_simple <- function() { new("VRanges", .TARGET_gr, ref = .TARGET_ref, alt = .TARGET_alt, totalDepth = integerRle(NA_integer_, 2), refDepth = integerRle(NA_integer_, 2), altDepth = integerRle(NA_integer_, 2), sampleNames = factorRle(NA_character_, 2), softFilterMatrix = FilterMatrix(matrix(nrow = length(.TARGET_gr), ncol = 0L), filterRules = FilterRules()), hardFilters = FilterRules()) } make_TARGET_VRanges <- function(i = seq_len(length(.TARGET_seqnames))) { new("VRanges", GRanges(.TARGET_seqnames, .TARGET_ranges, .TARGET_strand, tumorSpecific = .TARGET_tumorSpecific)[i], ref = .TARGET_ref[i], alt = .TARGET_alt[i], totalDepth = .TARGET_totalDepth[i], refDepth = .TARGET_refDepth[i], altDepth = .TARGET_altDepth[i], sampleNames = .TARGET_sampleNames[i], softFilterMatrix = .TARGET_softFilterMatrix[i,,drop=FALSE], hardFilters = .TARGET_hardFilters) } make_TARGET_VRanges_empty <- function() { new("VRanges", GRanges(), ref = character(), alt = characterRle(character()), totalDepth = integerRle(integer()), refDepth = integerRle(integer()), altDepth = integerRle(integer()), sampleNames = factorRle(factor()), softFilterMatrix = FilterMatrix(matrix(nrow = 0L, ncol = 0L), filterRules = FilterRules()), hardFilters = FilterRules()) } test_VRanges_constructor <- function() { vr <- make_TARGET_VRanges_simple() ## CHECK: 'ref' NA ranges <- IRanges(c(1, 5), c(10, 20)) checkException(VRanges(.TARGET_seqnames, .TARGET_ranges, NA_character_)) ## CHECK: depth < 0 checkException(VRanges(.TARGET_seqnames, .TARGET_ranges, .TARGET_ref, refDepth = -1)) checkException(VRanges(.TARGET_seqnames, .TARGET_ranges, .TARGET_ref, altDepth = -1)) ## CHECK: invalid totalDepth sum options(warn=2) checkException(VRanges(.TARGET_seqnames, .TARGET_ranges, .TARGET_ref, .TARGET_alt, 0, 1)) options(warn=0) ## CHECK: DNAStringSet handling (ref and alt); also, coercion depth=>integer test.vr <- VRanges(.TARGET_seqnames, .TARGET_ranges, DNAStringSet(.TARGET_ref), DNAStringSet(.TARGET_alt), totalDepth = .TARGET_totalDepth) vr@totalDepth <- .TARGET_totalDepth checkIdentical(test.vr, vr) ## CHECK: recycling (every column) test.vr <- VRanges(.TARGET_seqnames[1], .TARGET_ranges, DNAStringSet(.TARGET_ref[1]), .TARGET_alt[1], tumorSpecific = .TARGET_tumorSpecific, totalDepth = .TARGET_totalDepth) seqnames(vr) <- .TARGET_seqnames[1] vr$tumorSpecific <- .TARGET_tumorSpecific vr@ref <- rep(.TARGET_ref[1], 2) alt(vr) <- .TARGET_alt[1] checkIdentical(test.vr, vr) ## CHECK: coercion of 0/1 matrix to logical test.vr <- VRanges(.TARGET_seqnames, .TARGET_ranges, .TARGET_ref, .TARGET_alt, softFilterMatrix = cbind(a = c(1, 0))) vr <- make_TARGET_VRanges_simple() vr@softFilterMatrix <- as(.TARGET_softFilterMatrix, "matrix") checkIdentical(test.vr, vr) ## CHECK: all arguments, with unnamed metadata test.vr <- VRanges(.TARGET_seqnames, .TARGET_ranges, .TARGET_ref, .TARGET_alt, .TARGET_totalDepth, .TARGET_refDepth, .TARGET_altDepth, tumorSpecific = .TARGET_tumorSpecific, sampleNames = .TARGET_sampleNames, softFilterMatrix = .TARGET_softFilterMatrix, hardFilters = .TARGET_hardFilters) vr <- make_TARGET_VRanges() checkIdentical(test.vr, vr) ## CHECK: zero-length input test.vr <- VRanges() empty.vr <- make_TARGET_VRanges_empty() checkIdentical(test.vr, empty.vr) } test_VRanges_extract <- function() { vr <- make_TARGET_VRanges() checkIdentical(vr[1], make_TARGET_VRanges(1)) checkIdentical(vr[0], make_TARGET_VRanges(0)) checkIdentical(vr[rep(1, 3)], make_TARGET_VRanges(rep(1, 3))) checkIdentical(vr[c(2, 1)], make_TARGET_VRanges(c(2, 1))) checkIdentical(vr[c(TRUE,FALSE)], make_TARGET_VRanges(c(TRUE,FALSE))) checkIdentical(vr[TRUE], make_TARGET_VRanges(TRUE)) checkIdentical(vr[], make_TARGET_VRanges()) checkIdentical(vr[logical()], make_TARGET_VRanges(logical())) vr$tumorSpecific <- NULL checkIdentical(vr, make_TARGET_VRanges()[,integer()]) } test_VRanges_accessors <- function() { vr <- make_TARGET_VRanges() checkIdentical(seqnames(vr), .TARGET_seqnames) checkIdentical(ranges(vr), .TARGET_ranges) checkIdentical(strand(vr), .TARGET_strand) checkIdentical(ref(vr), .TARGET_ref) checkIdentical(alt(vr), .TARGET_alt) checkIdentical(refDepth(vr), .TARGET_refDepth) checkIdentical(altDepth(vr), .TARGET_altDepth) checkIdentical(totalDepth(vr), .TARGET_totalDepth) checkIdentical(Biobase::sampleNames(vr), .TARGET_sampleNames) checkIdentical(softFilterMatrix(vr), .TARGET_softFilterMatrix) checkIdentical(hardFilters(vr), .TARGET_hardFilters) checkIdentical(vr$tumorSpecific, .TARGET_tumorSpecific) alt(vr) <- NA checkIdentical(alt(vr), characterRle(NA, 2)) twoFilters <- rep(.TARGET_hardFilters, 2) hardFilters(vr) <- twoFilters checkIdentical(hardFilters(vr), twoFilters) twoFilters <- .TARGET_softFilterMatrix[,c(1,1)] softFilterMatrix(vr) <- twoFilters checkIdentical(softFilterMatrix(vr), twoFilters) } test_VRanges_subassign <- function() { vr <- make_TARGET_VRanges() vr[2:1] <- vr checkIdentical(vr, make_TARGET_VRanges(2:1)) vr <- make_TARGET_VRanges() sampleNames(vr) <- Rle(sampleNames(vr)) vr2 <- vr vr2[2:1] <- vr checkIdentical(vr2, vr[2:1]) } test_VRanges_combine <- function() { vr <- make_TARGET_VRanges() vr.rep <- vr[rep(seq_len(length(vr)), 2)] vr.combined <- c(vr, vr) checkIdentical(vr.combined, vr.rep) } test_VRanges_coerce <- function() { df <- data.frame(as.data.frame(.TARGET_gr), ref = as.vector(.TARGET_ref), alt = as.vector(.TARGET_alt), totalDepth = as.vector(.TARGET_totalDepth), refDepth = as.vector(.TARGET_refDepth), altDepth = as.vector(.TARGET_altDepth), sampleNames = as.factor(.TARGET_sampleNames), softFilterMatrix = .TARGET_softFilterMatrix, tumorSpecific = .TARGET_tumorSpecific, stringsAsFactors = FALSE) vr <- make_TARGET_VRanges() checkIdentical(as.data.frame(vr), df) } make_TARGET_VRanges_vcf <- function() { gr <- GRanges(c("1", "1", "3", "2", "1", "2"), IRanges(c(1, 20, 15, 5, 20, 5), width = 1L), "*", TS = c(TRUE, FALSE, FALSE, TRUE, TRUE, NA)) seqinfo(gr) <- Seqinfo(c("1", "3", "2"), c(NA, 22, 25), genome = c(NA, "foo", NA)) new("VRanges", gr, ref = c("A", "C", "G", "T", "C", "T"), alt = c("T", "G", NA, "A", "G", "C"), totalDepth = c(NA, 10L, 15L, 10L, 5L, 3L), refDepth = c(0L, 5L, 15L, 10L, NA, 2L), altDepth = c(5L, NA, NA, 0L, 3L, 1L), sampleNames = factorRle(factor(c("A", "B", "B", "A", "A", "B"))), softFilterMatrix = FilterMatrix(matrix = cbind(a = c(FALSE, TRUE, FALSE, TRUE, FALSE, TRUE), b = c(FALSE, FALSE, TRUE, TRUE, NA, NA)), filterRules = FilterRules(a = x > 1, b = c != "foo")), hardFilters = FilterRules()) } checkIdenticalVCF <- function(orig, vcf) { vcf$QUAL <- NULL if (!is.null(orig$TS)) orig$TS <- as.integer(orig$TS) softFilterMatrix(orig) <- as(softFilterMatrix(orig), "matrix") softFilterMatrix(vcf) <- as(softFilterMatrix(vcf), "matrix") names(orig) <- names(vcf) ## Information loss due to binary nature of VCF filters if (!identical(softFilterMatrix(orig), softFilterMatrix(vcf))) { origFilt <- softFilterMatrix(orig) origFilt[is.na(origFilt)] <- TRUE origFilt[rowSums(origFilt) == 2 & rowSums(softFilterMatrix(orig),na.rm=TRUE) != 2,] <- NA softFilterMatrix(orig) <- origFilt } checkIdentical(orig, vcf) } test_VRanges_vcf <- function() { dest <- tempfile() vr <- make_TARGET_VRanges_vcf() writeVcf(vr, dest) vcf <- readVcf(dest, genome = "hg19") perm <- c(1, 7, 8, 4, 2, 10) vcf.vr <- as(vcf, "VRanges")[perm] genome(vr) <- "hg19" checkIdenticalVCF(vr, vcf.vr) test.vcf <- asVCF(vr, info = "TS", filter = "a") writeVcf(test.vcf, dest) vcf <- readVcf(dest, genome = "hg19") vcf.vr <- as(vcf, "VRanges")[perm] ## adjustments necessary, due to folding at INFO and FILTER vcf.vr$TS[5:6] <- c(1L, NA) softFilterMatrix(vcf.vr)[5,] <- cbind(FALSE, NA) checkIdenticalVCF(vr, vcf.vr) vrA <- vr[sampleNames(vr) == "A"] runValue(sampleNames(vrA)) <- factor(runValue(sampleNames(vrA))) vrA <- keepSeqlevels(vrA, unique(as.character(seqnames(vrA)))) writeVcf(vrA, dest) vcfA <- readVcf(dest, genome = "hg19") vcfA.vr <- as(vcfA, "VRanges") checkIdenticalVCF(vrA, vcfA.vr) geno(vcfA) <- SimpleList() vrA.vcf <- as(vcfA, "VRanges") vrA.stripped <- VRanges(seqnames(vrA), ranges(vrA), ref(vrA), alt(vrA), sampleNames = sampleNames(vrA)) seqinfo(vrA.stripped) <- seqinfo(vrA) checkIdenticalVCF(vrA.stripped, vrA.vcf) vr <- VRanges(seqnames = c("chr1", "chr2"), ranges = IRanges(c(1, 10), c(5, 20)), ref = c("T", "A"), alt = c("C", "T"), refDepth = c(5, 10), altDepth = c(7, 6), totalDepth = c(12, 17), sampleNames = Rle(letters[1:2]), softFilterMatrix = cbind(depth = c(TRUE, FALSE)), tumorSpecific = c(FALSE, TRUE)) vr_small <- vr width(vr_small) <- 1 vcf_small <- as(vr_small, "VCF") vr_back <- as(vcf_small, "VRanges") vr_back$QUAL <- NULL vr_back$tumorSpecific <- as.logical(vr_back$tumorSpecific) checkIdentical(vr_small, vr_back[-(2:3)]) } ### GOT TIRED OF TESTING. I mean, seriously, that VCF stuff was insane. VariantAnnotation/inst/unitTests/test_writeVcf-methods.R0000644000175100017510000001117314614305321024626 0ustar00biocbuildbiocbuildtest_writeVcf_connection_increment <- function() { fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf1 <- readVcf(fl, "hg19") outfl <- tempfile() con <- file(outfl, open="a") writeVcf(vcf1[1:2,], con) writeVcf(vcf1[-(1:2),], con) close(con) vcf2 <- readVcf(outfl, "hg19") checkIdentical(dim(vcf1), dim(vcf2)) } test_writeVcf_tags <- function() { fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") dest <- tempfile() vcf1 <- readVcf(fl, "hg19") hd1 <- metadata(vcf1)$header writeVcf(vcf1, dest) vcf2 <- readVcf(dest, "hg19") hd2 <- metadata(vcf2)$header checkTrue(names(meta(hd1)) %in% names(meta(hd2))) checkIdentical(names(geno(vcf1)), names(geno(vcf2))) checkIdentical(colnames(mcols(info(vcf1))), colnames(mcols(info(vcf2)))) } test_writeVcf_flatgeno <- function() { fl <- system.file("extdata", "structural.vcf", package="VariantAnnotation") dest <- tempfile() vcf1 <- readVcf(fl, "hg19") writeVcf(vcf1, dest) vcf2 <- readVcf(dest, "hg19") } test_writeVcf_geno <- function() { fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") dest <- tempfile() ## empty vcf1 <- readVcf(fl, "hg19", param=ScanVcfParam(geno=NA)) writeVcf(vcf1, dest) vcf2 <- readVcf(dest, "hg19") checkTrue(length(geno(vcf2)$GT) == 0L) ## Rle vcf1 <- readVcf(fl, "hg19", param=ScanVcfParam(geno="GT")) writeVcf(vcf1, dest) vcf2 <- readVcf(dest, "hg19") checkIdentical(geno(vcf1)$GT, geno(vcf2)$GT) checkIdentical(geno(header(vcf1)), geno(header(vcf2))) ## matrix vcf1 <- readVcf(fl, "hg19", param=ScanVcfParam(geno="GT")) writeVcf(vcf1, dest) vcf2 <- readVcf(dest, "hg19") checkIdentical(geno(vcf1)$GT, geno(vcf2)$GT) checkIdentical(geno(header(vcf1)), geno(header(vcf2))) param=ScanVcfParam(geno="GT", samples="NA00003") vcf1 <- readVcf(fl, "hg19", param=param) writeVcf(vcf1, dest) vcf2 <- readVcf(dest, "hg19") checkIdentical(geno(vcf1)$GT, geno(vcf2)$GT) checkIdentical(geno(header(vcf1)), geno(header(vcf2))) checkTrue(samples(header(vcf2)) == "NA00003") ## array vcf1 <- readVcf(fl, "hg19", param=ScanVcfParam(geno="HQ")) writeVcf(vcf1, dest) vcf2 <- # FORMAT descriptors for GENO fields tryCatch(readVcf(dest, "hg19"), error=conditionMessage, warning=conditionMessage) checkIdentical(geno(vcf1)$HQ, geno(vcf2)$HQ) checkIdentical(geno(header(vcf1)), geno(header(vcf2))) param=ScanVcfParam(geno="HQ", sample="NA00003") vcf1 <- readVcf(fl, "hg19", param=param) suppressWarnings(writeVcf(vcf1, dest)) vcf2 <- readVcf(dest, "hg19") checkIdentical(geno(vcf1)$HQ, geno(vcf2)$HQ) checkIdentical(geno(header(vcf1)), geno(header(vcf2))) checkTrue(samples(header(vcf2)) == "NA00003") ## matrix and array param=ScanVcfParam(geno=c("GT", "HQ"), samples="NA00002") vcf1 <- readVcf(fl, "hg19", param=param) writeVcf(vcf1, dest) vcf2 <- readVcf(dest, "hg19") checkIdentical(geno(vcf1)$GT, geno(vcf2)$GT) checkIdentical(geno(vcf1)$HQ, geno(vcf2)$HQ) checkTrue(samples(header(vcf2)) == "NA00002") vcf3 <- vcf1 geno(vcf3) <- geno(vcf3)[c("HQ", "GT")] writeVcf(vcf3, dest) vcf2 <- readVcf(dest, "hg19", param=param) checkIdentical(geno(vcf1), geno(vcf2)) ## list fl <- system.file("extdata", "gl_chr1.vcf", package="VariantAnnotation") hdr <- scanVcfHeader(fl) param <- ScanVcfParam(samples=samples(hdr)[1:2]) vcf1 <- readVcf(fl, "", param=param) writeVcf(vcf1, dest) vcf2 <- readVcf(dest, "") checkIdentical(geno(vcf1)$GL, geno(vcf2)$GL) } test_alt_description_quoting = function() # https://github.com/Bioconductor/VariantAnnotation/issues/52 { fl <- system.file("extdata", "structural.vcf", package="VariantAnnotation") vcf <- readVcf(fl, genome="hg19") tmp <- tempfile() writeVcf(vcf, filename=tmp) #lines = readLines(tmp) # missing from chunk above #lines[grepl("ALT=", lines)] require("S4Vectors") good = new("DFrame", rownames = c("DEL", "DEL:ME:ALU", "DEL:ME:L1", "DUP", "DUP:TANDEM", "INS", "INS:ME:ALU", "INS:ME:L1", "INV", "CNV"), nrows = 10L, elementType = "ANY", elementMetadata = NULL, metadata = list(), listData = list(Description = c("Deletion", "Deletion of ALU element", "Deletion of L1 element", "Duplication", "Tandem Duplication", "Insertion of novel sequence", "Insertion of ALU element", "Insertion of L1 element", "Inversion", "Copy number variable region" ))) chkr = readVcf(tmp) chk = fixed(header(readVcf(tmp)))$ALT checkIdentical(chk, good) } VariantAnnotation/man/0000755000175100017510000000000014614305321016003 5ustar00biocbuildbiocbuildVariantAnnotation/man/defunct.Rd0000644000175100017510000000461314614305321017726 0ustar00biocbuildbiocbuild\name{VariantAnnotation-defunct} \alias{VariantAnnotation-defunct} \alias{refLocsToLocalLocs} \alias{refLocsToLocalLocs,GRanges,TxDb,missing-method} \alias{refLocsToLocalLocs,GRanges,missing,GRangesList-method} \alias{readVcfLongForm} \alias{readVcfLongForm,TabixFile,character,GRanges-method} \alias{readVcfLongForm,TabixFile,character,missing-method} \alias{readVcfLongForm,TabixFile,character,IntegerRangesList-method} \alias{readVcfLongForm,TabixFile,character,ScanVcfParam-method} \alias{readVcfLongForm,character,character,ScanVcfParam-method} \alias{readVcfLongForm,character,character,missing-method} \alias{readVcfLongForm,character,missing,missing-method} \alias{dbSNPFilter} \alias{regionFilter} \alias{MatrixToSnpMatrix} \alias{VRangesScanVcfParam} \alias{restrictToSNV} \title{Defunct Functions in Package \code{VariantAnnotation}} \description{ The functions or variables listed here are no longer part of \code{VariantAnnotation}. } \section{usage}{ ## Removed \itemize{ \item refLocsToLocalLocs() \item readVcfLongForm() \item dbSNPFilter() \item regionFilter() \item MatrixToSnpMatrix() \item getTranscriptSeqs() \item VRangesScanVcfParam() \item restrictToSNV() } } \details{ ## Removed \itemize{ \item{ \code{refLocsToLocalLocs} has been replaced by \code{mapToTranscripts} and \code{pmapToTranscripts}. } \item{ \code{readVcfLongForm} has been replaced by \code{expand}. } \item{ \code{dbSNPFilter} and \code{regionFilter} have been replaced by \code{filterVcf}. } \item{ \code{regionFilter} has been replaced by \code{filterVcf}. } \item{ \code{MatrixToSnpMatrix} has been replaced by \code{genotypeToSnpMatrix}. } \item{ \code{getTranscriptSeqs} has been replaced by \code{extractTranscriptSeqs} in the GenomicFeatures package. } \item{ \code{VRangesScanVcfParam} has been replaced by \code{ScanVcfParam}. } \item{ \code{restrictToSVN} has been replaced by \code{isSNV}. } } } \author{ Valerie Obenchain } \seealso{ \itemize{ \item \code{\link{expand}} \item \code{\link{filterVcf}} \item \code{\link{genotypeToSnpMatrix}} \item \code{\link[GenomicFeatures]{mapToTranscripts}} \item \code{\link[GenomicFeatures]{extractTranscriptSeqs}} \item \code{\link{isSNV}} \item \code{\link{ScanVcfParam}} } } VariantAnnotation/man/filterVcf-methods.Rd0000644000175100017510000001135614614305321021665 0ustar00biocbuildbiocbuild\name{filterVcf} \alias{filterVcf} \alias{filterVcf,character-method} \alias{filterVcf,TabixFile-method} \title{Filter VCF files} \description{ Filter Variant Call Format (VCF) files from one file to another } \usage{ \S4method{filterVcf}{character}(file, genome, destination, ..., verbose = TRUE, index = FALSE, prefilters = FilterRules(), filters = FilterRules(), param = ScanVcfParam()) \S4method{filterVcf}{TabixFile}(file, genome, destination, ..., verbose = TRUE, index = FALSE, prefilters = FilterRules(), filters = FilterRules(), param = ScanVcfParam()) } \arguments{ \item{file}{A \code{character(1)} file path or \code{\link{TabixFile}} specifying the VCF file to be filtered.} \item{genome}{A \code{character(1)} identifier} \item{destination}{A \code{character(1)} path to the location where the filtered VCF file will be written.} \item{...}{Additional arguments, possibly used by future methods.} \item{verbose}{A \code{logical(1)} indicating whether progress messages should be printed.} \item{index}{A \code{logical(1)} indicating whether the filtered file should be compressed and indexed (using \code{\link{bgzip}} and \code{indexTabix}).} \item{prefilters}{A \code{\link{FilterRules}} instance contains rules for filtering un-parsed lines of the VCF file.} \item{filters}{A \code{\link{FilterRules}} instance contains rules for filtering fully parsed VCF objects.} \item{param}{A \code{\link{ScanVcfParam}} instance restricting input of particular \code{info} or \code{geno} fields, or genomic locations. Applicable when applying a \code{filter} only. Prefiltering involves a grep of unparsed lines in the file; indexing is not used.} } \details{ This function transfers content of one VCF file to another, removing records that fail to satisfy \code{prefilters} and \code{filters}. Filtering is done in a memory efficient manner, iterating over the input VCF file in chunks of default size 100,000 (when invoked with \code{character(1)} for \code{file}) or as specified by the \code{yieldSize} argument of \code{TabixFile} (when invoked with \code{TabixFile}). There are up to two passes. In the first pass, unparsed lines are passed to \code{prefilters} for filtering, e.g., searching for a fixed character string. In the second pass lines successfully passing \code{prefilters} are parsed into \code{VCF} instances and made available for further filtering. One or both of \code{prefilter} and \code{filter} can be present. Filtering works by removing the rows (variants) that do not meet a criteria. Because this is a row-based approach and samples are column-based most genotype filters are only meaningful for single-sample files. If a single samples fails the criteria the entire row (all samples) are removed. The case where genotype filtering is effective for multiple samples is when the criteria is applied across samples and not to the individual (e.g., keep rows where all samples have DP > 10). } \value{The destination file path as a \code{character(1)}.} \author{ Martin Morgan and Paul Shannon } \seealso{ \code{\link{readVcf}}, \code{\link{writeVcf}}. } \examples{ fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") ## ----------------------------------------------------------------------- ## Filter for SNVs in a defined set of ranges: ## ----------------------------------------------------------------------- if (require(TxDb.Hsapiens.UCSC.hg19.knownGene)) { txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene exons <- exons(txdb) exons22 <- exons[seqnames(exons) == "chr22"] seqlevelsStyle(exons22) <- "NCBI" ## match chrom names in VCF file ## Range-based filter: withinRange <- function(rng) function(x) x %within% rng ## The first filter identifies SNVs and the second applies the ## range restriction. filters <- FilterRules(list( isSNV = isSNV, withinRange = withinRange(exons22))) ## Apply \dontrun{ filt1 <- filterVcf(fl, "hg19", tempfile(), filters=filters, verbose=TRUE) } } ## ----------------------------------------------------------------------- ## Using a pre-filter and filter: ## ----------------------------------------------------------------------- ## Low coverage exome snp filter: lowCoverageExomeSNP = function(x) grepl("LOWCOV,EXOME", x, fixed=TRUE) ## The pre-filter identifies low coverage exome snps and the filter ## identifies variants with INFO variable VT = SNP. pre <- FilterRules(list(lowCoverageExomeSNP = lowCoverageExomeSNP)) filt <- FilterRules(list(VTisSNP = function(x) info(x)$VT == "SNP")) ## Apply filt2 <- filterVcf(fl, "hg19", tempfile(), prefilters=pre, filters=filt) ## Filtered results vcf <- readVcf(filt2, "hg19") } \keyword{manip} VariantAnnotation/man/genotypeToSnpMatrix-methods.Rd0000644000175100017510000001544114614305321023743 0ustar00biocbuildbiocbuild\name{genotypeToSnpMatrix} \alias{genotypeToSnpMatrix} \alias{genotypeToSnpMatrix,CollapsedVCF-method} \alias{genotypeToSnpMatrix,array-method} \title{Convert genotype calls from a VCF file to a SnpMatrix object} \description{ Convert an array of genotype calls from the "GT", "GP", "GL" or "PL" FORMAT field of a VCF file to a \link[snpStats:SnpMatrix-class]{SnpMatrix}. } \usage{ \S4method{genotypeToSnpMatrix}{CollapsedVCF}(x, uncertain=FALSE, ...) \S4method{genotypeToSnpMatrix}{array}(x, ref, alt, ...) } \arguments{ \item{x}{ A \code{CollapsedVCF} object or a \code{array} of genotype data from the "GT", "GP", "GL" or "PL" FORMAT field of a VCF file. This \code{array} is created with a call to \code{readVcf} and can be accessed with \code{geno()}. } \item{uncertain}{ A logical indicating whether the genotypes to convert should come from the "GT" field (\code{uncertain=FALSE}) or the "GP", "GL" or "PL" field (\code{uncertain=TRUE}). } \item{ref}{ A \code{DNAStringSet} of reference alleles. } \item{alt}{ A \code{DNAStringSetList} of alternate alleles. } \item{\dots}{ Additional arguments, passed to methods. } } \details{ \code{genotypeToSnpMatrix} converts an array of genotype calls from the "GT", "GP", "GL" or "PL" FORMAT field of a VCF file into a \link[snpStats:SnpMatrix-class]{SnpMatrix}. The following caveats apply, \itemize{ \item{no distinction is made between phased and unphased genotypes} \item{variants with >1 ALT allele are set to NA} \item{only single nucleotide variants are included; others are set to NA} \item{only diploid calls are included; others are set to NA} } In VCF files, 0 represents the reference allele and integers greater than 0 represent the alternate alleles (i.e., 2, 3, 4 would indicate the 2nd, 3rd or 4th allele in the ALT field for a particular variant). This function only supports variants with a single alternate allele and therefore the alternate values will always be 1. Genotypes are stored in the SnpMatrix as 0, 1, 2 or 3 where 0 = missing, 1 = "0/0", 2 = "0/1" or "1/0" and 3 = "1/1". In SnpMatrix terminology, "A" is the reference allele and "B" is the risk allele. Equivalent statements to those made with 0 and 1 allele values would be 0 = missing, 1 = "A/A", 2 = "A/B" or "B/A" and 3 = "B/B". The genotype fields are defined as follows: \itemize{ \item{GT : genotype, encoded as allele values separated by either of "/" or "|". The allele values are 0 for the reference allele and 1 for the alternate allele.} \item{GL : genotype likelihoods comprised of comma separated floating point log10-scaled likelihoods for all possible genotypes. In the case of a reference allele A and a single alternate allele B, the likelihoods will be ordered "A/A", "A/B", "B/B".} \item{PL : the phred-scaled genotype likelihoods rounded to the closest integer. The ordering of values is the same as for the GL field.} \item{GP : the phred-scaled genotype posterior probabilities for all possible genotypes; intended to store imputed genotype probabilities. The ordering of values is the same as for the GL field.} } If \code{uncertain=TRUE}, the posterior probabilities of the three genotypes ("A/A", "A/B", "B/B") are encoded (approximately) as byte values. This encoding allows uncertain genotypes to be used in \link[snpStats]{snpStats} functions, which in some cases may be more appropriate than using only the called genotypes. The byte encoding conserves memory by allowing the uncertain genotypes to be stored in a two-dimensional raw matrix. See the \link[snpStats]{snpStats} documentation for more details. } \value{ A list with the following elements, \item{genotypes}{ The output genotype data as an object of class \code{"SnpMatrix"}. The columns are snps and the rows are the samples. See ?\code{SnpMatrix} details of the class structure. } \item{map}{ A \code{DataFrame} giving the snp names and alleles at each locus. The \code{ignore} column indicates which variants were set to \code{NA} (see \code{NA} criteria in 'details' section). } } \references{ \url{http://www.1000genomes.org/wiki/Analysis/Variant\%20Call\%20Format/vcf-variant-call-format-version-41} } \author{ Stephanie Gogarten and Valerie Obenchain } \seealso{ \link{readVcf}, \linkS4class{VCF}, \link[snpStats:SnpMatrix-class]{SnpMatrix} } \examples{ ## ---------------------------------------------------------------- ## Non-probability based snp encoding using "GT" ## ---------------------------------------------------------------- fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") ## This file has no "GL" or "GP" field so we use "GT". geno(vcf) ## Convert the "GT" FORMAT field to a SnpMatrix. mat <- genotypeToSnpMatrix(vcf) ## The result is a list of length 2. names(mat) ## Compare coding in the VCF file to the SnpMatrix. geno(vcf)$GT t(as(mat$genotype, "character")) ## The 'ignore' column in 'map' indicates which variants ## were set to NA. Variant rs6040355 was ignored because ## it has multiple alternate alleles, microsat1 is not a ## snp, and chr20:1230237 has no alternate allele. mat$map ## ---------------------------------------------------------------- ## Probability-based encoding using "GL", "PL" or "GP" ## ---------------------------------------------------------------- ## Read a vcf file with a "GL" field. fl <- system.file("extdata", "gl_chr1.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") geno(vcf) ## Convert the "GL" FORMAT field to a SnpMatrix mat <- genotypeToSnpMatrix(vcf, uncertain=TRUE) ## Only 3 of the 9 variants passed the filters. The ## other 6 variants had no alternate alleles. mat$map ## Compare genotype representations for a subset of ## samples in variant rs180734498. ## Original called genotype geno(vcf)$GT["rs180734498", 14:16] ## Original genotype likelihoods geno(vcf)$GL["rs180734498", 14:16] ## Posterior probability (computed inside genotypeToSnpMatrix) GLtoGP(geno(vcf)$GL["rs180734498", 14:16, drop=FALSE])[1,] ## SnpMatrix coding. t(as(mat$genotype, "character"))["rs180734498", 14:16] t(as(mat$genotype, "numeric"))["rs180734498", 14:16] ## For samples NA11829 and NA11830, one probability is significantly ## higher than the others, so SnpMatrix calls the genotype. These ## calls match the original coding: "0|1" -> "A/B", "0|0" -> "A/A". ## Sample NA11831 was originally called as "0|1" but the probability ## of "0|0" is only a factor of 3 lower, so SnpMatrix calls it as ## "Uncertain" with an appropriate byte-level encoding. } \keyword{manip} \keyword{methods} VariantAnnotation/man/getTranscriptSeqs-methods.Rd0000644000175100017510000000337014614305321023423 0ustar00biocbuildbiocbuild\name{getTranscriptSeqs} \alias{getTranscriptSeqs} \alias{getTranscriptSeqs,GRangesList,ANY-method} \alias{getTranscriptSeqs,GRangesList,BSgenome-method} \alias{getTranscriptSeqs,GRangesList,FaFile-method} \alias{getTranscriptSeqs,GRanges,FaFile-method} \title{Get transcript sequences} \description{ This function is defunct. Use GenomicFeatures::extractTranscriptSeqs() instead. Extract transcript sequences from a \link[BSgenome]{BSgenome} object or an \link[Rsamtools]{FaFile}. } \usage{ \S4method{getTranscriptSeqs}{GRangesList,BSgenome}(query, subject, ...) \S4method{getTranscriptSeqs}{GRangesList,FaFile}(query, subject, ...) \S4method{getTranscriptSeqs}{GRanges,FaFile}(query, subject, ...) } \arguments{ \item{query}{A \link[GenomicRanges]{GRangesList} object containing exons or cds grouped by transcript. } \item{subject}{A \link[BSgenome]{BSgenome} object or a \link[Rsamtools]{FaFile} from which the sequences will be taken. } \item{\dots}{Additional arguments } } \details{ \code{getTranscriptSeqs} is a wrapper for the \code{extractTranscriptSeqs} and \code{getSeq} functions. The purpose is to allow sequence extraction from either a \link[BSgenome]{BSgenome} or \link[Rsamtools]{FaFile}. Transcript sequences are extracted based on the boundaries of the feature provided in the \code{query} (i.e., either exons or cds regions). } \value{ A \link[Biostrings]{DNAStringSet} instance containing the sequences for all transcripts specified in \code{query}. } \author{Valerie Obenchain} \seealso{ \link{predictCoding} \link[GenomicFeatures]{extractTranscriptSeqs} \link[Biostrings]{getSeq} } \examples{ ## See ?extractTranscriptSeqs in the GenomicFeatures package. } \keyword{methods} \keyword{manip} VariantAnnotation/man/GLtoGP.Rd0000644000175100017510000000354114614305321017371 0ustar00biocbuildbiocbuild\name{GLtoGP} \alias{GLtoGP} \alias{PLtoGP} \title{Convert genotype likelihoods to genotype probabilities} \description{ Convert an array of genotype likelihoods to posterior genotype probabilities. } \usage{ GLtoGP(gl) PLtoGP(pl) } \arguments{ \item{gl}{Array of genotype likelihoods (log10-scaled). The format can be a matrix of lists, or a three-dimensional array in which the third dimension corresponds to the probabilities for each genotype.} \item{pl}{Array of genotype likelihoods (phred-scaled, i.e. -10*log10). The format can be a matrix of lists, or a three-dimensional array in which the third dimension corresponds to the probabilities for each genotype.} } \details{ \code{GLtoGP} computes the probability of each genotype as \code{10^x / sum(10^x)}. \code{PLtoGP} first divides by -10 and then proceeds as in \code{GLtoGP}. } \value{ An array of posterior genotype probabilities, in the same format as the input (matrix of lists or 3D array). } \author{ Stephanie Gogarten } \seealso{ \link{readVcf}, \link{genotypeToSnpMatrix} } \examples{ ## Read a vcf file with a "GL" field. vcfFile <- system.file("extdata", "gl_chr1.vcf", package="VariantAnnotation") vcf <- readVcf(vcfFile, "hg19") ## extract genotype likelihoods as a matrix of lists gl <- geno(vcf)$GL class(gl) mode(gl) # convert to posterior probabilities gp <- GLtoGP(gl) ## Read a vcf file with a "PL" field. vcfFile <- system.file("extdata", "hapmap_exome_chr22.vcf.gz", package="VariantAnnotation") vcf <- readVcf(vcfFile, "hg19") ## extract genotype likelihoods as a matrix of lists pl <- geno(vcf)$PL class(pl) mode(pl) # convert to posterior probabilities gp <- PLtoGP(pl) } \keyword{manip} VariantAnnotation/man/indexVcf-method.Rd0000644000175100017510000000266514614305321021327 0ustar00biocbuildbiocbuild\name{indexVcf} \alias{indexVcf} \alias{indexVcf,character-method} \alias{indexVcf,VcfFile-method} \alias{indexVcf,VcfFileList-method} \title{Create index files for VCF files} \description{ \code{indexVcf()} creates an index file for compressed VCF files, if the index file does not exist. } \usage{ \S4method{indexVcf}{character}(x, ...) \S4method{indexVcf}{VcfFile}(x, ...) \S4method{indexVcf}{VcfFileList}(x, ...) } \arguments{ \item{x}{ \code{character()}, \code{VcfFile}, or \code{VcfFileList} pointing to bgzf-compressed VCF files. } \item{...}{ Additional arguments to \code{\link[Rsamtools]{indexTabix}} } } \details{ If \code{x} is a character vector, assumes they are the path(s) to bgzf-compressed VCF file(s). If an index does not exist, one is created. VCF files can be compreseed using \code{\link{bgzip}}. A \code{VcfFile} or \code{VcfFileList} is returned. If a \code{VcfFile} or \code{VcfFileList} is given, the index file is checked, if it does not exist it will crete one. If the index file was NA or missing, the path of the associated VCF file is used as the index file path. An updated \code{VcfFile} or \code{VcfFileList} is returned. } \value{VcfFile or VcfFileList} \author{Lori Shepherd} \seealso{ \code{\link{VcfFile}} } \examples{ fl <- system.file( "extdata", "chr7-sub.vcf.gz", package="VariantAnnotation", mustWork=TRUE ) vcf1 <- indexVcf(fl) vcf1 } \keyword{manip} VariantAnnotation/man/isSNV-methods.Rd0000644000175100017510000001341014614305321020734 0ustar00biocbuildbiocbuild\name{isSNV} \alias{isSNV} \alias{isInsertion} \alias{isDeletion} \alias{isIndel} \alias{isDelins} \alias{isTransition} \alias{isSubstitution} % VCF \alias{isSNV,ExpandedVCF-method} \alias{isSNV,CollapsedVCF-method} \alias{isInsertion,ExpandedVCF-method} \alias{isInsertion,CollapsedVCF-method} \alias{isDeletion,ExpandedVCF-method} \alias{isDeletion,CollapsedVCF-method} \alias{isIndel,ExpandedVCF-method} \alias{isIndel,CollapsedVCF-method} \alias{isDelins,ExpandedVCF-method} \alias{isDelins,CollapsedVCF-method} \alias{isSubstitution,ExpandedVCF-method} \alias{isSubstitution,CollapsedVCF-method} \alias{isTransition,ExpandedVCF-method} \alias{isTransition,CollapsedVCF-method} % VRanges \alias{isSNV,VRanges-method} \alias{isInsertion,VRanges-method} \alias{isDeletion,VRanges-method} \alias{isIndel,VRanges-method} \alias{isDelins,VRanges-method} \alias{isSubstitution,VRanges-method} \alias{isTransition,VRanges-method} \title{ Identification of genomic variant types. } \description{ Functions for identifying variant types such as SNVs, insertions, deletions, transitions, and structural rearrangements. } \usage{ \S4method{isSNV}{VRanges}(x, ...) \S4method{isSNV}{ExpandedVCF}(x, ...) \S4method{isSNV}{CollapsedVCF}(x, ..., singleAltOnly = TRUE) \S4method{isInsertion}{VRanges}(x, ...) \S4method{isInsertion}{ExpandedVCF}(x, ...) \S4method{isInsertion}{CollapsedVCF}(x, ..., singleAltOnly = TRUE) \S4method{isDeletion}{VRanges}(x, ...) \S4method{isDeletion}{ExpandedVCF}(x, ...) \S4method{isDeletion}{CollapsedVCF}(x, ..., singleAltOnly = TRUE) \S4method{isIndel}{VRanges}(x, ...) \S4method{isIndel}{ExpandedVCF}(x, ...) \S4method{isIndel}{CollapsedVCF}(x, ..., singleAltOnly = TRUE) \S4method{isDelins}{VRanges}(x, ...) \S4method{isDelins}{ExpandedVCF}(x, ...) \S4method{isDelins}{CollapsedVCF}(x, ..., singleAltOnly = TRUE) \S4method{isTransition}{VRanges}(x, ...) \S4method{isTransition}{ExpandedVCF}(x, ...) \S4method{isTransition}{CollapsedVCF}(x, ..., singleAltOnly = TRUE) \S4method{isSubstitution}{VRanges}(x, ...) \S4method{isSubstitution}{ExpandedVCF}(x, ...) \S4method{isSubstitution}{CollapsedVCF}(x, ..., singleAltOnly = TRUE) } \arguments{ \item{x}{A \linkS4class{VCF} or \linkS4class{VRanges} object. } \item{singleAltOnly}{A \code{logical} only applicable when \code{x} is a \link{CollapsedVCF} class. When \code{TRUE} (default) only variants with a single alternate allele are evaluated; all multi-alt variants evaluate to \code{FALSE}. When \code{singleAltOnly=FALSE} all ref / alt pairs for each variant are evaluated. If any ref / alt pairs meet the test criteria a value of TRUE is returned for the variant; this may result in a value of TRUE for a variant with a mixture of alternate alleles, some that pass the criteria and some that do not. To retain single ref / alt pairs that pass the critera use \code{expand} on the \code{CollapsedVCF} and then apply the test. } \item{\dots}{Arguments passed to other methods. } } \details{ All functions return a logical vector the length of \code{x}. Variants in gvcf files with NON_REF alt alleles return TRUE; structural variants return FALSE. \itemize{ \item{isSNV: }{ Reference and alternate alleles are both a single nucleotide long. } \item{isInsertion: }{ Reference allele is a single nucleotide and the alternate allele is greater (longer) than a single nucleotide and the first nucleotide of the alternate allele matches the reference. } \item{isDeletion: }{ Alternate allele is a single nucleotide and the reference allele is greater (longer) than a single nucleotide and the first nucleotide of the reference allele matches the alternate. } \item{isIndel: }{ The variant is either a deletion or insertion as determined by \code{isDeletion} and \code{isInsertion}. } \item{isDelins: }{ The variant is a deletion followed by an insertion, either of them involving two or more nucleotides. } \item{isSubstition: }{ Reference and alternate alleles are the same length (1 or more nucleotides long). } \item{isTransition: }{ Reference and alternate alleles are both a single nucleotide long. The reference-alternate pair interchange is of either two-ring purines (A <-> G) or one-ring pyrimidines (C <-> T). } } } \value{ A \code{logical} vector the same length as \code{x}. } \author{Michael Lawrence, Valerie Obenchain and Robert Castelo} \examples{ fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") ## --------------------------------------------------------------------- ## VCF objects ## --------------------------------------------------------------------- vcf <- readVcf(fl, "hg19") DataFrame(ref(vcf), alt(vcf)) ## This vcf has transitions in row 2 and 3. When 'singleAltOnly=TRUE' ## only the row 2 variant is identified: isTransition(vcf) ## Both row 2 and 3 are identified when 'singleAltOnly=FALSE': isTransition(vcf, singleAltOnly=FALSE) ## Expand the CollapsedVCF to ExpandedVCF evcf <- expand(vcf) ## All ref / alt pairs are now expanded and there is no need to ## use 'singleAltOnly'. The return length is now 7 instead of 5: transition <- isTransition(evcf) transition DataFrame(ref(evcf)[transition], alt(evcf)[transition]) ## --------------------------------------------------------------------- ## VRanges objects ## --------------------------------------------------------------------- ## A VRanges object holds data from a VCF class in a completely ## 'flat' fashion. INFO and FORMAT variables for all subjects are ## 'repped' out such that each row is a unique combination of data. vr <- as(vcf, "VRanges") isSNV(vr, singleAltOnly=FALSE) } \keyword{methods} VariantAnnotation/man/locateVariants-methods.Rd0000644000175100017510000004152314614305321022717 0ustar00biocbuildbiocbuild\name{locateVariants} \alias{locateVariants} \alias{locateVariants,IntegerRanges,TxDb,VariantType-method} \alias{locateVariants,IntegerRanges,GRangesList,VariantType-method} \alias{locateVariants,GRanges,TxDb,VariantType-method} \alias{locateVariants,GRanges,GRangesList,VariantType-method} \alias{locateVariants,VCF,TxDb,VariantType-method} \alias{locateVariants,VCF,GRangesList,VariantType-method} \alias{locateVariants,GRanges,TxDb,CodingVariants-method} \alias{locateVariants,GRanges,GRangesList,CodingVariants-method} \alias{locateVariants,GRanges,TxDb,IntronVariants-method} \alias{locateVariants,GRanges,GRangesList,IntronVariants-method} \alias{locateVariants,GRanges,TxDb,FiveUTRVariants-method} \alias{locateVariants,GRanges,GRangesList,FiveUTRVariants-method} \alias{locateVariants,GRanges,TxDb,ThreeUTRVariants-method} \alias{locateVariants,GRanges,GRangesList,ThreeUTRVariants-method} \alias{locateVariants,GRanges,TxDb,IntergenicVariants-method} \alias{locateVariants,GRanges,GRangesList,IntergenicVariants-method} \alias{locateVariants,GRanges,TxDb,SpliceSiteVariants-method} \alias{locateVariants,GRanges,GRangesList,SpliceSiteVariants-method} \alias{locateVariants,GRanges,TxDb,PromoterVariants-method} \alias{locateVariants,GRanges,GRangesList,PromoterVariants-method} \alias{locateVariants,GRanges,TxDb,AllVariants-method} \alias{locateVariants,GRanges,GRangesList,AllVariants-method} \title{Locate variants} \description{Variant location with respect to gene function} \usage{ locateVariants(query, subject, region, ...) \S4method{locateVariants}{VCF,TxDb,VariantType}(query, subject, region, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE, asHits=FALSE) \S4method{locateVariants}{GRanges,TxDb,VariantType}(query, subject, region, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE, asHits=FALSE) } \arguments{ \item{query}{A \link[IRanges]{IntegerRanges}, \link[GenomicRanges]{GRanges} or \linkS4class{VCF} object containing the variants. Metadata columns are allowed but ignored. NOTE: Zero-width ranges are treated as width-1 ranges; start values are decremented to equal the end value. } \item{subject}{A \link[GenomicFeatures]{TxDb} or \code{GRangesList} object that serves as the annotation. GFF files can be converted to \link[GenomicFeatures]{TxDb} objects with \code{makeTxDbFromGFF()} in the \code{txdbmaker} package. } \item{region}{An instance of one of the 8 VariantType classes: \code{CodingVariants}, \code{IntronVariants}, \code{FiveUTRVariants}, \code{ThreeUTRVariants}, \code{IntergenicVariants}, \code{SpliceSiteVariants}, \code{PromoterVariants}, \code{AllVariants}. All objects can be instantiated with no arguments, e.g., CodingVariants() will create an object of \code{CodingVariants}. \code{AllVariants}, \code{PromoterVariants} and \code{IntergenicVariants} have \code{upstream} and \code{downstream} arguments. For \code{PromoterVariants} and \code{IntergenicVariants} these are single integer values >= 0. For \code{AllVariants} these are integer vectors of length 2 named \sQuote{promoter} and \sQuote{intergenic}. See ?\code{upstream} for more details. When using \code{AllVariants}, a range in \code{query} may fall in multiple regions (e.g., 'intergenic' and 'promoter'). In this case the result will have a row for each match. All data in the row will be equivalent except the LOCATION column. } \item{\dots}{Additional arguments passed to methods } \item{cache}{An \code{environment} into which required components of \code{subject} are loaded. Provide, and re-use, a cache to speed repeated queries to the same \code{subject} across different \code{query} instances. } \item{ignore.strand}{A \code{logical} indicating if strand should be ignored when performing overlaps. } \item{asHits}{A \code{logical} indicating if the results should be returned as a \link[S4Vectors]{Hits} object. Not applicable when \code{region} is AllVariants or IntergenicVariants. } } \details{ \describe{ \item{Range representation:}{ The ranges in \code{query} should reflect the position(s) of the reference allele. For snps the range will be of width 1. For range insertions or deletions the reference allele could be a sequence such as GGTG in which case the width of the range should be 4. } \item{Location:}{ Possible locations are \sQuote{coding}, \sQuote{intron}, \sQuote{threeUTR}, \sQuote{fiveUTR}, \sQuote{intergenic}, \sQuote{spliceSite}, or \sQuote{promoter}. Overlap operations for \sQuote{coding}, \sQuote{intron}, \sQuote{threeUTR}, and \sQuote{fiveUTR} require variants to fall completely within the defined region to be classified as such. To be classified as a \sQuote{spliceSite} the variant must overlap with any portion of the first 2 or last 2 nucleotides in an intron. \sQuote{intergenic} variants are ranges that do not fall within a defined gene region. \sQuote{transcripts by gene} are extracted from the annotation and overlapped with the variant positions. Variants with no overlaps are classified as \code{intergenic}. When available, gene IDs for the flanking genes are provided as \code{PRECEDEID} and \code{FOLLOWID}. \code{upstream} and \code{downstream} arguments define the acceptable distance from the query for the flanking genes. \code{PRECEDEID} and \code{FOLLOWID} results are lists and contain all genes that fall within the defined distance. See the examples for how to compute the distance from ranges to PRECEDEID and FOLLOWID. \sQuote{promoter} variants fall within a specified range upstream and downstream of the transcription start site. Ranges values can be set with the \code{upstream} and \code{downstream} arguments when creating the \code{PromoterVariants()} or \code{AllVariants()} classes. } \item{Subject as GRangesList:}{ The \code{subject} can be a \code{TxDb} or \code{GRangesList} object. When using a \code{GRangesList} the type of data required is driven by the \code{VariantType} class. Below is a description of the appropriate \code{GRangesList} for each \code{VariantType}. \describe{ \item{CodingVariants:}{coding (CDS) by transcript} \item{IntronVariants:}{introns by transcript} \item{FiveUTRVariants:}{five prime UTR by transcript} \item{ThreeUTRVariants:}{three prime UTR by transcript} \item{IntergenicVariants:}{transcripts by gene} \item{SpliceSiteVariants:}{introns by transcript} \item{PromoterVariants:}{list of transcripts} \item{AllVariants:}{no GRangeList method available} } } \item{Using the cache:}{ When processing multiple VCF files performance is enhanced by specifying an environment as the \code{cache} argument. This cache is used to store and reuse extracted components of the subject (TxDb) required by the function. The first call to the function (i.e., processing the first VCF file in a list of many) populates the cache; repeated calls to \code{locateVariants} will access these objects from the cache vs re-extracting the same information. } } } \value{ A \code{GRanges} object with a row for each variant-transcript match. Strand of the output is from the \code{subject} hit except in the case of IntergenicVariants. For intergenic, multiple precede and follow gene ids are returned for each variant. When \code{ignore.strand=TRUE} the return strand is \code{*} because genes on both strands are considered and it is possible to have a mixture. When \code{ignore.strand=FALSE} the strand will match the \code{query} because only genes on the same strand are considered. Metadata columns are \code{LOCATION}, \code{QUERYID}, \code{TXID}, \code{GENEID}, \code{PRECEDEID}, \code{FOLLOWID} and \code{CDSID}. Results are ordered by \code{QUERYID}, \code{TXID} and \code{GENEID}. Columns are described in detail below. \describe{ \item{\code{LOCATION}}{ Possible locations are \sQuote{coding}, \sQuote{intron}, \sQuote{threeUTR}, \sQuote{fiveUTR}, \sQuote{intergenic}, \sQuote{spliceSite} and \sQuote{promoter}. To be classified as \sQuote{coding}, \sQuote{intron}, \sQuote{threeUTR} or \sQuote{fiveUTR} the variant must fall completely within the region. \sQuote{intergenic} variants do not fall within a transcript. The \sQuote{GENEID} for these positions are \code{NA}. Lists of flanking genes that fall within the distance defined by \code{upstream} and \code{downstream} are given as \sQuote{PRECEDEID} and \sQuote{FOLLOWID}. By default, the gene ID is returned in the \sQuote{PRECEDEID} and \sQuote{FOLLOWID} columns. To return the transcript ids instead set \code{idType = "tx"} in the \code{IntergenicVariants()} constructor. A \sQuote{spliceSite} variant overlaps any portion of the first 2 or last 2 nucleotides of an intron. } \item{\code{LOCSTART, LOCEND}}{ Genomic position in LOCATION-centric coordinates. If LOCATION is `intron`, these are intron-centric coordinates, if LOCATION is `coding` then cds-centric. All coordinates are relative to the start of the transcript. SpliceSiteVariants, IntergenicVariants and PromoterVariants have no formal extraction `by transcript` so for these variants LOCSTART and LOCEND are NA. Coordinates are computed with \code{mapToTranscripts}; see ?\code{mapToTranscripts} in the GenomicFeatures package for details. } \item{\code{QUERYID}}{ The \code{QUERYID} column provides a map back to the row in the original \code{query}. If the \code{query} was a \code{VCF} object this index corresponds to the row in the \code{GRanges} object returned by the \code{rowRanges} accessor. } \item{\code{TXID}}{ The transcript id taken from the \code{TxDb} object. } \item{\code{CDSID}}{ The coding sequence id(s) taken from the \code{TxDb} object. } \item{\code{GENEID}}{ The gene id taken from the \code{TxDb} object. } \item{\code{PRECEDEID}}{ IDs for all genes the query precedes within the defined \code{upstream} and \code{downstream} distance. Only applicable for \sQuote{intergenic} variants. By default this column contains gene ids; to return transcript ids set \code{idType = "tx"} in the \code{IntergenicVariants} constructor. } \item{\code{FOLLOWID}}{ IDs for all genes the query follows within the defined \code{upstream} and \code{downstream} distance. Only applicable for \sQuote{intergenic} variants. By default this column contains gene ids; to return transcript ids set \code{idType = "tx"} in the \code{IntergenicVariants} constructor. } All ID values will be \sQuote{NA} for variants with a location of \code{transcript_region} or \code{NA}. } } \author{Valerie Obenchain} \seealso{ \itemize{ \item The \link{readVcf} function. \item The \link{predictCoding} function. \item The promoters function on the \link[GenomicRanges]{intra-range-methods} man page in the \pkg{GenomicRanges} package. } } \examples{ library(TxDb.Hsapiens.UCSC.hg19.knownGene) txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene ## --------------------------------------------------------------------- ## Variants in all gene regions ## --------------------------------------------------------------------- ## Read variants from a VCF file. fl <- system.file("extdata", "gl_chr1.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") ## Often the seqlevels in the VCF file do not match those in the TxDb. head(seqlevels(vcf)) head(seqlevels(txdb)) intersect(seqlevels(vcf), seqlevels(txdb)) ## Rename seqlevels with renameSeqlevesl(). vcf <- renameSeqlevels(vcf, paste0("chr", seqlevels(vcf))) ## Confirm. intersect(seqlevels(vcf), seqlevels(txdb)) ## Overlaps for all possible variant locations. loc_all <- locateVariants(vcf, txdb, AllVariants()) table(loc_all$LOCATION) ## --------------------------------------------------------------------- ## Variants in intergenic regions ## --------------------------------------------------------------------- ## Intergenic variants do not overlap a gene range in the ## annotation and therefore 'GENEID' is always NA. Flanking genes ## that fall within the 'upstream' and 'downstream' distances are ## reported as PRECEDEID and FOLLOWID. region <- IntergenicVariants(upstream=70000, downstream=70000) loc_int <- locateVariants(vcf, txdb, region) mcols(loc_int)[c("LOCATION", "PRECEDEID", "FOLLOWID")] ## Distance to the flanking genes can be computed for variants that ## have PRECEDEID(s) or FOLLOWID(s). Each variant can have multiple ## flanking id's so we first expand PRECEDEID and the corresponding ## variant ranges. p_ids <- unlist(loc_int$PRECEDEID, use.names=FALSE) exp_ranges <- rep(loc_int, elementNROWS(loc_int$PRECEDEID)) ## Compute distances with the distance method defined in GenomicFeatures. ## Help page can be found at ?`distance,GenomicRanges,TxDb-method`. ## The method returns NA for ids that cannot be collapsed into a single ## range (e.g., genes with ranges on multiple chromosomes). distance(exp_ranges, txdb, id=p_ids, type="gene") ## To search for distance by transcript id set idType='tx' in the ## IntergenicVariants() constructor, e.g., ## locateVariants(vcf, txdb, region=IntergenicVariants(idType="tx")) ## Unlist ids and expand ranges as before to get p_ids and exp_ranges. ## Then call distance() with type = "tx": ## distance(exp_ranges, txdb, id=p_ids, type="tx") ## --------------------------------------------------------------------- ## GRangesList as subject ## --------------------------------------------------------------------- ## When 'subject' is a GRangesList the GENEID is unavailable and ## will always be reported as NA. This is because the GRangesList ## objects are extractions of region-by-transcript, not region-by-gene. \dontrun{ cdsbytx <- cdsBy(txdb) locateVariants(vcf, cdsbytx, CodingVariants()) intbytx <- intronsByTranscript(txdb) locateVariants(vcf, intbytx, IntronVariants()) } ## --------------------------------------------------------------------- ## Using the cache ## --------------------------------------------------------------------- ## When processing multiple VCF files, the 'cache' can be used ## to store the extracted components of the TxDb ## (i.e., cds by tx, introns by tx etc.). This avoids having to ## re-extract these GRangesLists during each loop. \dontrun{ myenv <- new.env() files <- list(vcf1, vcf2, vcf3) lapply(files, function(fl) { vcf <- readVcf(fl, "hg19") ## modify seqlevels to match TxDb seqlevels(vcf_mod) <- paste0("chr", seqlevels(vcf)) locateVariants(vcf_mod, txdb, AllVariants(), cache=myenv) }) } ## --------------------------------------------------------------------- ## Parallel implmentation ## --------------------------------------------------------------------- \dontrun{ library(BiocParallel) ## A connection to a TxDb object is established when ## the package is loaded. Because each process reading from an ## sqlite db must have a unique connection the TxDb ## object cannot be passed as an argument when running in ## parallel. Instead the package must be loaded on each worker. ## The overhead of the multiple loading may defeat the ## purpose of running the job in parallel. An alternative is ## to instead pass the appropriate GRangesList as an argument. ## The details section on this man page under the heading ## 'Subject as GRangesList' explains what GRangesList is ## appropriate for each variant type. ## A. Passing a GRangesList: fun <- function(x, subject, ...) locateVariants(x, subject, IntronVariants()) library(TxDb.Hsapiens.UCSC.hg19.knownGene) grl <- intronsByTranscript(TxDb.Hsapiens.UCSC.hg19.knownGene) mclapply(c(vcf, vcf), fun, subject=grl) ## B. Passing a TxDb: ## Forking: ## In the case of forking, the TxDb cannot be loaded ## in the current workspace. ## To detach the NAMESPACE: ## unloadNamespace("TxDb.Hsapiens.UCSC.hg19.knownGene") fun <- function(x) { library(TxDb.Hsapiens.UCSC.hg19.knownGene) locateVariants(x, TxDb.Hsapiens.UCSC.hg19.knownGene, IntronVariants()) } mclapply(c(vcf, vcf), fun) ## Clusters: cl <- makeCluster(2, type = "SOCK") fun <- function(query, subject, region) { library(VariantAnnotation) library(TxDb.Hsapiens.UCSC.hg19.knownGene) locateVariants(query, TxDb.Hsapiens.UCSC.hg19.knownGene, region) } parLapply(cl, c(vcf, vcf), fun, region=IntronVariants()) stopCluster(cl) } } \keyword{methods} VariantAnnotation/man/PolyPhenDb-class.Rd0000644000175100017510000001065114614305321021404 0ustar00biocbuildbiocbuild\name{PolyPhenDb-class} \docType{class} \alias{PolyPhen} \alias{PolyPhenDb} \alias{class:PolyPhenDb} \alias{PolyPhenDb-class} \alias{duplicateRSID} \alias{metadata,PolyPhenDb-method} \alias{columns,PolyPhenDb-method} \alias{keys,PolyPhenDb-method} \alias{select,PolyPhenDb-method} \title{PolyPhenDb objects} \description{ The PolyPhenDb class is a container for storing a connection to a PolyPhen sqlite database. } \section{Methods}{ In the code below, \code{x} is a \code{PolyPhenDb} object. \describe{ \item{}{ \code{metadata(x)}: Returns \code{x}'s metadata in a data frame. } \item{}{ \code{columns(x)}: Returns the names of the \code{columns} that can be used to subset the data columns. For column descriptions see \code{?PolyPhenDbColumns}. } \item{}{ \code{keys(x)}: Returns the names of the \code{keys} that can be used to subset the data rows. The \code{keys} values are the rsid's. } \item{}{ \code{select(x, keys = NULL, columns = NULL, ...)}: Returns a subset of data defined by the character vectors \code{keys} and \code{columns}. If no \code{keys} are supplied, all rows are returned. If no \code{columns} are supplied, all columns are returned. See \code{?PolyPhenDbColumns} for column descriptions. } \item{}{ \code{duplicateRSID(x)}: Returns a named list of duplicate rsid groups. The names are the \code{keys}, the list elements are the rsid's that have been reported as having identical chromosome position and alleles and therefore translating into the same amino acid residue substitution. } } } \details{ PolyPhen (Polymorphism Phenotyping) is a tool which predicts the possible impact of an amino acid substitution on the structure and function of a human protein by applying empirical rules to the sequence, phylogenetic and structural information characterizing the substitution. PolyPhen makes its predictions using UniProt features, PSIC profiles scores derived from multiple alignment and matches to PDP or PQS structural databases. The procedure can be roughly outlined in the following steps, see the references for complete details, \itemize{ \item sequence-based characterization of substitution site \item calculation of PSIC profile scores for two amino acid variants \item calculation of structural parameters and contacts \item prediction } PolyPhen uses empirically derived rules to predict that a non-synonymous SNP is \itemize{ \item probably damaging : it is with high confidence supposed to affect protein function or structure \item possibly damaging : it is supposed to affect protein function or structure \item benign : most likely lacking any phenotypic effect \item unknown : when in some rare cases, the lack of data do not allow PolyPhen to make a prediction } } \seealso{ \code{?PolyPhenDbColumns} } \references{ PolyPhen Home: \url{http://genetics.bwh.harvard.edu/pph2/dokuwiki/} Adzhubei IA, Schmidt S, Peshkin L, Ramensky VE, Gerasimova A, Bork P, Kondrashov AS, Sunyaev SR. Nat Methods 7(4):248-249 (2010). Ramensky V, Bork P, Sunyaev S. Human non-synonymous SNPs: server and survey. Nucleic Acids Res 30(17):3894-3900 (2002). Sunyaev SR, Eisenhaber F, Rodchenkov IV, Eisenhaber B, Tumanyan VG, Kuznetsov EN. PSIC: profile extraction from sequence alignments with position-specific counts of independent observations. Protein Eng 12(5):387-394 (1999). } \author{Valerie Obenchain} \examples{ library(PolyPhen.Hsapiens.dbSNP131) ## metadata metadata(PolyPhen.Hsapiens.dbSNP131) ## available rsid's head(keys(PolyPhen.Hsapiens.dbSNP131)) ## column descriptions found at ?PolyPhenDbColumns columns(PolyPhen.Hsapiens.dbSNP131) ## subset on keys and columns subst <- c("AA1", "AA2", "PREDICTION") rsids <- c("rs2142947", "rs4995127", "rs3026284") select(PolyPhen.Hsapiens.dbSNP131, keys=rsids, columns=subst) ## retrieve substitution scores subst <- c("IDPMAX", "IDPSNP", "IDQMIN") select(PolyPhen.Hsapiens.dbSNP131, keys=rsids, columns=subst) ## retrieve the PolyPhen-2 classifiers subst <- c("PPH2CLASS", "PPH2PROB", "PPH2FPR", "PPH2TPR", "PPH2FDR") select(PolyPhen.Hsapiens.dbSNP131, keys=rsids, columns=subst) ## duplicate groups of rsid's duplicateRSID(PolyPhen.Hsapiens.dbSNP131, c("rs71225486", "rs1063796")) } \keyword{classes} \keyword{methods} VariantAnnotation/man/PolyPhenDbColumns.Rd0000644000175100017510000001263214614305321021643 0ustar00biocbuildbiocbuild\name{PolyPhenDbColumns} \alias{PolyPhenDbColumns} \title{PolyPhenDb Columns} \description{ Description of the PolyPhen Sqlite Database Columns } \section{Column descriptions}{ These column names are displayed when \code{columns} is called on a \code{PolyPhenDb} object. \itemize{ \item rsid : rsid } Original query : \itemize{ \item OSNPID : original SNP identifier from user input \item OSNPACC : original protein identifier from user input \item OPOS : original substitution position in the protein sequence from user input \item OAA1 : original wild type (reference) aa residue from user input \item OAA2 : original mutant (reference) aa residue from user input } Mapped query : \itemize{ \item SNPID : SNP identifier mapped to dbSNP rsID if available, otherwise same as o_snp_id. This value was used as the rsid column \item ACC : protein UniProtKB accession if known protein, otherwise same as o_acc \item POS : substitution position mapped to UniProtKB protein sequence if known, otherwise same as o_pos \item AA1 : wild type aa residue \item AA2 : mutant aa residue \item NT1 : wild type allele nucleotide \item NT2 : mutant allele nucleotide } PolyPhen-2 prediction : \itemize{ \item PREDICTION : qualitative ternary classification FPR thresholds } PolyPhen-1 prediction : \itemize{ \item BASEDON : prediction basis \item EFFECT : predicted substitution effect on the protein structure or function } PolyPhen-2 classifiers : \itemize{ \item PPH2CLASS : binary classifier outcome ("damaging" or "neutral") \item PPH2PROB : probability of the variation being dammaging \item PPH2FPR : false positive rate at the pph2_prob level \item PPH2TPR : true positive rate at the pph2_prob level \item PPH2FDR : false discovery rate at the pph2_prob level } UniProtKB-SwissProt derived protein sequence annotations : \itemize{ \item SITE : substitution SITE annotation \item REGION : substitution REGION annotation \item PHAT : PHAT matrix element for substitution in the TRANSMEM region } Multiple sequence alignment scores : \itemize{ \item DSCORE : difference of PSIC scores for two aa variants (Score1 - Score2) \item SCORE1 : PSIC score for wild type aa residue (aa1) \item SCORE2 : PSIC score for mutant aa residue (aa2) \item NOBS : number of residues observed at the substitution position in the multiple alignment (sans gaps) } Protein 3D structure features : \itemize{ \item NSTRUCT : initial number of BLAST hits to similar proteins with 3D structures in PDB \item NFILT : number of 3D BLAST hits after identity threshold filtering \item PDBID : protein structure identifier from PDB \item PDBPOS : position of substitution in PDB protein sequence \item PDBCH : PDB polypeptide chain identifier \item IDENT : sequence identity between query and aligned PDB sequences \item LENGTH : PDB sequence alignment length \item NORMACC : normalized accessible surface \item SECSTR : DSSP secondary structure assignment \item MAPREG : region of the phi-psi (Ramachandran) map derived from the residue dihedral angles \item DVOL : change in residue side chain volume \item DPROP : change in solvent accessible surface propensity resulting from the substitution \item BFACT : normalized B-factor (temperature factor) for the residue \item HBONDS : number of hydrogen sidechain-sidechain and sidechain-mainchain bonds formed by the residue \item AVENHET : average number of contacts with heteroatoms per residue \item MINDHET : closest contact with heteroatom \item AVENINT : average number of contacts with other chains per residue \item MINDINT : closest contact with other chain \item AVENSIT : average number of contacts with critical sites per residue \item MINDSIT : closest contact with a critical site } Nucleotide sequence features (CpG/codon/exon junction) : \itemize{ \item TRANSV : whether substitution is a transversion \item CODPOS : position of the substitution within the codon \item CPG : whether or not the substitution changes CpG context \item MINDJNC : substitution distance from exon/intron junction } Pfam protein family : \itemize{ \item PFAMHIT : Pfam identifier of the query protein } Substitution scores : \itemize{ \item IDPMAX : maximum congruency of the mutant aa residue to all sequences in multiple alignment \item IDPSNP : maximum congruency of the mutant aa residue to the sequence in alignment with the mutant residue \item IDQMIN : query sequence identity with the closest homologue deviating from the wild type aa residue } Comments : \itemize{ \item COMMENTS : Optional user comments } } \seealso{ \code{?PolyPhenDb} } \author{Valerie Obenchain} \keyword{classes} \keyword{methods} VariantAnnotation/man/post_Hs_region.Rd0000644000175100017510000000160314614305321021254 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/use_vep_api.R \name{post_Hs_region} \alias{post_Hs_region} \title{elementary vep/homo_sapiens/region call to ensembl VEP REST API} \usage{ post_Hs_region(chr, pos, id, ref, alt) } \arguments{ \item{chr}{character(1) ensembl chromosome identifier (e.g., "7")} \item{pos}{numeric(1) 1-based chromosome position} \item{id}{character(1) arbitrary identifier} \item{ref}{character(1) reference allele} \item{alt}{character(1) alternative allele} } \value{ Instance of 'response' defined in httr package. } \description{ elementary vep/homo_sapiens/region call to ensembl VEP REST API } \note{ This function prepares a POST to rest.ensembl.org/vep/homo_sapiens/region endpoint. } \examples{ chk = post_Hs_region("7", 155800001, "chk", "A", "T") chk res = jsonlite::fromJSON(jsonlite::toJSON(httr::content(chk))) dim(chk) } VariantAnnotation/man/predictCoding-methods.Rd0000644000175100017510000002344014614305321022514 0ustar00biocbuildbiocbuild\name{predictCoding} \alias{predictCoding} \alias{predictCoding,IntegerRanges,TxDb,ANY,DNAStringSet-method} \alias{predictCoding,GRanges,TxDb,ANY,DNAStringSet-method} \alias{predictCoding,CollapsedVCF,TxDb,ANY,missing-method} \alias{predictCoding,ExpandedVCF,TxDb,ANY,missing-method} \alias{predictCoding,VRanges,TxDb,ANY,missing-method} \title{Predict amino acid coding changes for variants} \description{ Predict amino acid coding changes for variants a coding regions } \usage{ \S4method{predictCoding}{CollapsedVCF,TxDb,ANY,missing}(query, subject, seqSource, varAllele, ..., ignore.strand=FALSE) \S4method{predictCoding}{ExpandedVCF,TxDb,ANY,missing}(query, subject, seqSource, varAllele, ..., ignore.strand=FALSE) \S4method{predictCoding}{IntegerRanges,TxDb,ANY,DNAStringSet}(query, subject, seqSource, varAllele, ..., ignore.strand=FALSE) \S4method{predictCoding}{GRanges,TxDb,ANY,DNAStringSet}(query, subject, seqSource, varAllele, ..., ignore.strand=FALSE) \S4method{predictCoding}{VRanges,TxDb,ANY,missing}(query, subject, seqSource, varAllele, ..., ignore.strand=FALSE) } \arguments{ \item{query}{A \linkS4class{VCF}, \link{IntegerRanges}, \link{GRanges} or \code{VRanges} instance containing the variants to be annotated. If \code{query} is a \link[IRanges]{IntegerRanges} or \code{VRanges} it is coerced to a \link{GRanges}. If a \linkS4class{VCF} is provided the \code{GRanges} returned by the \code{rowRanges()} accessor will be used. All metadata columns are ignored. When \code{query} is not a \code{VCF} object a \code{varAllele} must be provided. The \code{varAllele} must be a \code{DNAStringSet} the same length as the \code{query}. If there are multiple alternate alleles per variant the \code{query} must be expanded to one row per each alternate allele. See examples. NOTE: Variants are expected to conform to the VCF specs as described on the 1000 Genomes page (see references). Indels must include the reference allele; zero-width ranges are not valid and return no matches. } \item{subject}{A \link[GenomicFeatures]{TxDb} object that serves as the annotation. GFF files can be converted to \link[GenomicFeatures]{TxDb} objects with \code{makeTxDbFromGFF()} in the \code{txdbmaker} package. } \item{seqSource}{A \code{\link[BSgenome]{BSgenome}} instance or an \link{FaFile} to be used for sequence extraction. } \item{varAllele}{A \link[Biostrings]{DNAStringSet} containing the variant (alternate) alleles. The length of \code{varAllele} must equal the length of \code{query}. Missing values are represented by a zero width empty element. Ranges with missing \code{varAllele} values are ignored; those with an \sQuote{N} character are not translated. When the \code{query} is a \code{VCF} object the \code{varAllele} argument will be missing. This value is taken internally from the \code{VCF} with \code{alt()}. } \item{\dots}{Additional arguments passed to methods. Arguments \code{genetic.code} and \code{if.fuzzy.codon} are supported for the \code{translate} function. } \item{ignore.strand}{A \code{logical} indicating if strand should be ignored when performing overlaps. When \code{ignore.strand == TRUE} the \code{query} strand is set to '*' and can overlap with any strand of the \code{subject}. The return \code{GRanges} reflects the strand of the \code{subject} hit, however, the positions and alleles reported are computed as if both were from the '+' strand. \code{ignore.strand == FALSE} requires the \code{query} and \code{subject} to have compatible strand. Again the return \code{GRanges} reports the strand of the \code{subject} hit but in this case positions and alleles are computed according to the strand of the \code{subject}. } } \details{ This function returns the amino acid coding for variants that fall completely `within' a coding region. The reference sequences are taken from a fasta file or \link[BSgenome]{BSgenome}. The width of the reference is determined from the start position and width of the range in the \code{query}. For guidance on how to represent an insertion, deletion or substitution see the 1000 Genomes VCF format (references). Variant alleles are taken from the \code{varAllele} when supplied. When the \code{query} is a \code{VCF} object the \code{varAllele} will be missing. This value is taken internally from the \code{VCF} with \code{alt()}. The variant allele is substituted into the reference sequences and transcribed. Transcription only occurs if the substitution, insertion or deletion results in a new sequence length divisible by 3. When the \code{query} is an unstranded (*) \code{GRanges} \code{predictCoding} will attempt to find overlaps on both the positive and negative strands of the \code{subject}. When the subject hit is on the negative strand the return \code{varAllele} is reverse complemented. The strand of the returned \code{GRanges} represents the strand of the subject hit. } \value{ A \link[GenomicRanges]{GRanges} with a row for each variant-transcript match. The result includes only variants that fell within coding regions. The strand of the output \code{GRanges} represents the strand of the \code{subject} hit. At a minimum, the metadata columns (accessible with \code{mcols}) include, \describe{ \item{\code{varAllele}}{ Variant allele. This value is reverse complemented for an unstranded \code{query} that overlaps a \code{subject} on the negative strand. } \item{\code{QUERYID}}{ Map back to the row in the original query } \item{\code{TXID}}{ Internal transcript id from the annotation } \item{\code{CDSID}}{ Internal coding region id from the annotation } \item{\code{GENEID}}{ Internal gene id from the annotation } \item{\code{CDSLOC}}{ Variant location in coding region-based coordinates. This position is relative to the start of the coding (cds) region defined in the \code{subject} annotation. } \item{\code{PROTEINLOC}}{ Variant codon triplet location in coding region-based coordinates. This position is relative to the start of the coding (cds) region defined in the \code{subject} annotation. } \item{\code{CONSEQUENCE}}{ Possible values are `synonymous', `nonsynonymous', `frameshift', `nonsense' and `not translated'. Variant sequences are translated only when the codon sequence is a multiple of 3. The value will be `frameshift' when a sequence is of incompatible length. `not translated' is used when \code{varAllele} is missing or there is an \sQuote{N} in the sequence. `nonsense' is used for premature stop codons. } \item{\code{REFCODON}}{ The reference codon sequence. This range is typically greater than the width of the range in the \code{GRanges} because it includes all codons involved in the sequence modification. If the reference sequence is of width 2 but the alternate allele is of width 4 then at least two codons must be included in the \code{REFSEQ}. } \item{\code{VARCODON}}{ This sequence is the result of inserting, deleting or replacing the position(s) in the reference sequence alternate allele. If the result of this substitution is not a multiple of 3 it will not be translated. } \item{\code{REFAA}}{ The reference amino acid column contains the translated \code{REFSEQ}. When translation is not possible this value is missing. } \item{\code{VARAA}}{ The variant amino acid column contains the translated \code{VARSEQ}. When translation is not possible this value is missing. } } } \references{ \url{http://www.1000genomes.org/wiki/analysis/variant-call-format/} \url{http://vcftools.sourceforge.net/specs.html} } \author{Michael Lawrence and Valerie Obenchain} \seealso{ \link{readVcf}, \link{locateVariants}, \link{refLocsToLocalLocs} \link{getTranscriptSeqs} } \examples{ library(BSgenome.Hsapiens.UCSC.hg19) library(TxDb.Hsapiens.UCSC.hg19.knownGene) txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene ## ---------------------------- ## VCF object as query ## ---------------------------- ## Read variants from a VCF file fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") ## Rename seqlevels in the VCF object to match those in the TxDb. vcf <- renameSeqlevels(vcf, "chr22") ## Confirm common seqlevels intersect(seqlevels(vcf), seqlevels(txdb)) ## When 'query' is a VCF object the varAllele argument is missing. coding1 <- predictCoding(vcf, txdb, Hsapiens) head(coding1, 3) ## Exon-centric or cDNA locations: exonsbytx <- exonsBy(txdb, "tx") cDNA <- mapToTranscripts(coding1, exonsbytx) mcols(cDNA)$TXID <- names(exonsbytx)[mcols(cDNA)$transcriptsHits] cDNA <- cDNA[mcols(cDNA)$TXID == mcols(coding1)$TXID[mcols(cDNA)$xHits]] ## Make sure cDNA is parallel to coding1 stopifnot(identical(mcols(cDNA)$xHits, seq_along(coding1))) coding1$cDNA <- ranges(cDNA) ## ---------------------------- ## GRanges object as query ## ---------------------------- ## A GRanges can also be used as the 'query'. The seqlevels in the VCF ## were adjusted in previous example so the GRanges extracted with ## has the correct seqlevels. rd <- rowRanges(vcf) ## The GRanges must be expanded to have one row per alternate allele. ## Variants 1, 2 and 10 have two alternate alleles. altallele <- alt(vcf) eltROWS <- elementNROWS(altallele) rd_exp <- rep(rd, eltROWS) ## Call predictCoding() with the expanded GRanges and the unlisted ## alternate allele as the 'varAllele'. coding2 <- predictCoding(rd_exp, txdb, Hsapiens, unlist(altallele)) } \keyword{methods} VariantAnnotation/man/probabilityToSnpMatrix.Rd0000644000175100017510000000253414614305321022767 0ustar00biocbuildbiocbuild\name{probabilityToSnpMatrix} \alias{probabilityToSnpMatrix} \title{Convert posterior genotype probability to a SnpMatrix object} \description{ Convert a matrix of posterior genotype probabilites P(AA), P(AB), P(BB) to a \link[snpStats:SnpMatrix-class]{SnpMatrix}. } \usage{ probabilityToSnpMatrix(probs) } \arguments{ \item{probs}{Matrix with three columns for the posterior probabilities of the three genotypes: "P(A/A)", "P(A/B)", "P(B/B)". Each row must sum to 1.} } \details{ \code{probabilityToSnpMatrix} converts a matrix of posterior probabilites of genotype calls into a \link[snpStats:SnpMatrix-class]{SnpMatrix}. } \value{ An object of class \code{"SnpMatrix"} with one row (one sample). Posterior probabilities are encoded (approximately) as byte values, one per SNP. See the help page for \link[snpStats:SnpMatrix-class]{SnpMatrix} for complete details of the class structure. } \author{ Stephanie Gogarten } \seealso{ \link{genotypeToSnpMatrix}, \link[snpStats:SnpMatrix-class]{SnpMatrix} } \examples{ probs <- matrix(c(1,0,0, 0,1,0, 0,0,1, NA,NA,NA), ncol=3, byrow=TRUE, dimnames=list(1:4,c("A/A","A/B","B/B"))) sm <- probabilityToSnpMatrix(probs) as(sm, "character") } \keyword{manip} VariantAnnotation/man/PROVEANDb-class.Rd0000644000175100017510000001006214614305321020754 0ustar00biocbuildbiocbuild\name{PROVEANDb-class} \docType{class} \alias{PROVEAN} \alias{PROVEANDb} \alias{class:PROVEANDb} \alias{PROVEANDb-class} \alias{columns,PROVEANDb-method} \alias{keys,PROVEANDb-method} \alias{keytypes,PROVEANDb-method} \alias{select,PROVEANDb-method} \title{PROVEANDb objects} \description{ The PROVEANDb class is a container for storing a connection to a PROVEAN sqlite database. } \section{Methods}{ In the code below, \code{x} is a \code{PROVEANDb} object. \describe{ \item{}{ \code{metadata(x)}: Returns \code{x}'s metadata in a data frame. } \item{}{ \code{columns(x)}: Returns the names of the \code{columns} that can be used to subset the data columns. } \item{}{ \code{keys(x, keytype="DBSNPID", ...)}: Returns the names of the \code{keys} that can be used to subset the data rows. For SIFT.Hsapiens.dbSNP137 the \code{keys} are NCBI dbSNP ids. } \item{}{ \code{keytypes(x)}: Returns the names of the \code{columns} that can be used as \code{keys}. For SIFT.Hsapiens.dbSNP137 the NCBI dbSNP ids are the only keytype. } \item{}{ \code{select(x, keys = NULL, columns = NULL, keytype = "DBSNPID", ...)}: Returns a subset of data defined by the character vectors \code{keys} and \code{columns}. If no \code{keys} are supplied, all rows are returned. If no \code{columns} are supplied, all columns are returned. } } } \details{ The SIFT tool is no longer actively maintained. A few of the orginal authors have started the PROVEAN (Protein Variation Effect Analyzer) project. PROVEAN is a software tool which predicts whether an amino acid substitution or indel has an impact on the biological function of a protein. PROVEAN is useful for filtering sequence variants to identify nonsynonymous or indel variants that are predicted to be functionally important. See the web pages for a complete description of the methods. \itemize{ \item PROVEAN Home: \url{http://provean.jcvi.org/index.php/} \item SIFT Home: \url{http://sift.jcvi.org/} } Though SIFT is not under active development, the PROVEAN team still provids the SIFT scores in the pre-computed downloads. This package, \code{SIFT.Hsapiens.dbSNP137}, contains both SIFT and PROVEAN scores. One notable difference between this and the previous SIFT database package is that \code{keys} in \code{SIFT.Hsapiens.dbSNP132} are rs IDs whereas in \code{SIFT.Hsapiens.dbSNP137} they are NCBI dbSNP IDs. } \references{ The PROVEAN tool has replaced SIFT: \url{http://provean.jcvi.org/about.php} Choi Y, Sims GE, Murphy S, Miller JR, Chan AP (2012) Predicting the Functional Effect of Amino Acid Substitutions and Indels. PLoS ONE 7(10): e46688. Choi Y (2012) A Fast Computation of Pairwise Sequence Alignment Scores Between a Protein and a Set of Single-Locus Variants of Another Protein. In Proceedings of the ACM Conference on Bioinformatics, Computational Biology and Biomedicine (BCB '12). ACM, New York, NY, USA, 414-417. Kumar P, Henikoff S, Ng PC. Predicting the effects of coding non-synonymous variants on protein function using the SIFT algorithm. Nat Protoc. 2009;4(7):1073-81 Ng PC, Henikoff S. Predicting the Effects of Amino Acid Substitutions on Protein Function Annu Rev Genomics Hum Genet. 2006;7:61-80. Ng PC, Henikoff S. SIFT: predicting amino acid changes that affect protein function. Nucleic Acids Res. 2003 Jul 1;31(13):3812-4. } \author{Valerie Obenchain} \examples{ if (require(SIFT.Hsapiens.dbSNP137)) { ## metadata metadata(SIFT.Hsapiens.dbSNP137) ## keys are the DBSNPID (NCBI dbSNP ID) dbsnp <- keys(SIFT.Hsapiens.dbSNP137) head(dbsnp) columns(SIFT.Hsapiens.dbSNP137) ## Return all columns. Note that the key, DBSNPID, ## is always returned. select(SIFT.Hsapiens.dbSNP137, dbsnp[10]) ## subset on keys and cols cols <- c("VARIANT", "PROVEANPRED", "SIFTPRED") select(SIFT.Hsapiens.dbSNP137, dbsnp[20:23], cols) } } \keyword{classes} \keyword{methods} VariantAnnotation/man/readVcf-methods.Rd0000644000175100017510000003760614614305321021321 0ustar00biocbuildbiocbuild\name{readVcf} \alias{readVcf} \alias{readVcf,character,ANY-method} \alias{readVcf,character,missing-method} \alias{readVcf,character,missing-method} \alias{readVcf,TabixFile,ScanVcfParam-method} \alias{readVcf,TabixFile,IntegerRangesList-method} \alias{readVcf,TabixFile,GRanges-method} \alias{readVcf,TabixFile,GRangesList-method} \alias{readVcf,TabixFile,missing-method} %% lightweight read* functions \alias{readInfo} \alias{readGeno} \alias{readGT} %% import wrapper \alias{import,VcfFile,ANY,ANY-method} \title{Read VCF files} \description{Read Variant Call Format (VCF) files} \usage{ \S4method{readVcf}{TabixFile,ScanVcfParam}(file, genome, param, ..., row.names=TRUE) \S4method{readVcf}{TabixFile,IntegerRangesList}(file, genome, param, ..., row.names=TRUE) \S4method{readVcf}{TabixFile,GRanges}(file, genome, param, ..., row.names=TRUE) \S4method{readVcf}{TabixFile,GRangesList}(file, genome, param, ..., row.names=TRUE) \S4method{readVcf}{TabixFile,missing}(file, genome, param, ..., row.names=TRUE) \S4method{readVcf}{character,ANY}(file, genome, param, ..., row.names=TRUE) \S4method{readVcf}{character,missing}(file, genome, param, ..., row.names=TRUE) \S4method{readVcf}{character,missing}(file, genome, param, ..., row.names=TRUE) ## Lightweight functions to read a single variable readInfo(file, x, param=ScanVcfParam(), ..., row.names=TRUE) readGeno(file, x, param=ScanVcfParam(), ..., row.names=TRUE) readGT(file, nucleotides=FALSE, param=ScanVcfParam(), ..., row.names=TRUE) ## Import wrapper \S4method{import}{VcfFile,ANY,ANY}(con, format, text, ...) } \arguments{ \item{file}{A \code{\link{VcfFile}} (synonymous with \code{\link{TabixFile}}) instance or character() name of the VCF file to be processed. When ranges are specified in \code{param}, \code{file} must be a \code{\link{VcfFile}}. Use of the \code{\link{VcfFile}} methods are encouraged as they are more efficient than the character() methods. See ?\code{VcfFile}, and ?\code{indexVcf} for help creating a \code{\link{VcfFile}}. } \item{genome}{A \code{character} or \code{Seqinfo} object. \itemize{ \item{\code{character}:}{ Genome identifier as a single string or named character vector. Names of the character vector correspond to chromosome names in the file. This identifier replaces the genome information in the VCF \code{Seqinfo} (i.e., \code{seqinfo(vcf)}). When not provided, \code{genome} is taken from the VCF file header. } \item{\code{Seqinfo}:}{ When \code{genome} is provided as a \code{Seqinfo} it is propagated to the VCF output. If seqinfo information can be obtained from the file, (i.e., seqinfo(scanVcfHeader(fl)) is not empty), the output \code{Seqinfo} is a product of merging the two. If a param (i.e., ScanVcfParam) is used in the call to \code{readVcf}, the seqlevels of the param ranges must be present in \code{genome}. } } } \item{param}{An instance of \code{\linkS4class{ScanVcfParam}}, \code{GRanges}, \code{GRangesList} or \code{IntegerRangesList}. VCF files can be subset on genomic coordinates (ranges) or elements in the VCF fields. Both genomic coordinates and VCF elements can be specified in a \code{\linkS4class{ScanVcfParam}}. See ?\code{ScanVcfParam} for details. } \item{x}{\code{character} name of single \code{info} or \code{geno} field to import. Applicable to \code{readInfo} and \code{readGeno} only. } \item{row.names}{A \code{logical} specifying if rownames should be returned. In the case of \code{readVcf}, rownames appear on the \code{GRanges} returned by the \code{rowRanges} accessor. } \item{nucleotides}{A \code{logical} indicating if genotypes should be returned as nucleotides instead of the numeric representation. Applicable to \code{readGT} only. } \item{con}{The \code{VcfFile} object to import.} \item{format, text}{Ignored.} \item{\dots}{Additional arguments, passed to methods. For \code{import}, the arguments are passed to \code{readVcf}. } } \details{ \describe{ \item{Data Import: }{ \describe{ \item{VCF object: }{ \code{readVcf} imports records from bzip compressed or uncompressed VCF files. Data are parsed into a \code{\linkS4class{VCF}} object using the file header information if available. To import a subset of ranges the VCF must have an index file. An index file can be created with \code{bzip} and \code{indexVcf} functions. The \code{readInfo}, \code{readGeno} and \code{readGT} functions are lightweight versions of \code{readVcf} and import a single variable. The return object is a vector, matrix or CompressedList instead of a VCF class. } } \code{readVcf} calls \code{\link{scanVcf}}, the details of which can be found with \code{?scanVcf}. } \item{Header lines (aka Meta-information): }{ readVcf() reads and parses fields according to the multiplicity and data type specified in the header lines. Fields without header lines are skipped (not read or parsed). To see what fields are present in the header use \code{scanVcfHeader()}. See ?\code{VCFHeader} for more details. Passing \code{verbose = TRUE} to \code{readVcf()} prints the fields with header lines that will be parsed by \code{readVcf}. } \item{Data type: }{ CHROM, POS, ID and REF fields are used to create the \code{GRanges} stored in the \code{VCF} object and accessible with the \code{rowRanges} accessor. REF, ALT, QUAL and FILTER are parsed into the \code{DataFrame} in the \code{fixed} slot. Because ALT can have more than one value per variant it is represented as a \code{DNAStringSetList}. REF is a \code{DNAStringSet}, QUAL is \code{numeric} and FILTER is a \code{character}. Accessors include \code{fixed}, \code{ref}, \code{alt}, \code{qual}, and \code{filt}. Data from the INFO field can be accessed with the \code{info} accessor. Genotype data (i.e., data immediately following the FORMAT field in the VCF) can be accessed with the \code{geno} accessor. INFO and genotype data types are determined according to the \sQuote{Number} and \sQuote{Type} information in the file header as follows: \sQuote{Number} should only be 0 when \sQuote{Type} is 'flag'. These fields are parsed as logical vectors. If \sQuote{Number} is 1, \sQuote{info} data are parsed into a \code{vector} and \sQuote{geno} into a \code{matrix}. If \sQuote{Number} is >1, \sQuote{info} data are parsed into a \code{DataFrame} with the same number of columns. \sQuote{geno} are parsed into an \code{array} with the same dimensions as \sQuote{Number}. Columns of the \sQuote{geno} matrices are the samples. If \sQuote{Number} is \sQuote{.}, \sQuote{A} or \sQuote{G}, both \sQuote{info} and \sQuote{geno} data are parsed into a \code{matrix}. When the header does not contain any \sQuote{INFO} lines, the data are returned as a single, unparsed column. } \item{Missing data: }{ Missing data in VCF files on disk are represented by a dot ("."). \code{readVcf} retains the dot as a character string for data type character and converts it to \code{NA} for data types numeric or double. Because the data are stored in rectangular data structures there is a value for each \code{info} and \code{geno} field element in the \code{VCF} class. If the element was missing or was not collected for a particular variant the value will be \code{NA}. In the case of the ALT field we have the following treatment of special characters / missing values: \itemize{ \item '.' true missings become empty characters \item '*' are treated as missing and become empty characters \item 'I' are treated as undefined and become '.' } } \item{Efficient Usage: }{ Subsets of data (i.e., specific variables, positions or samples) can be read from a VCF file by providing a \code{ScanVcfParam} object in the call to \code{readVcf}. Other lightweight options are the \code{readGT}, \code{readInfo} and \code{readGeno} functions which return data as a matrix instead of the \code{VCF} class. Another option for handling large files is to iterate through the data in chunks by setting the \code{yieldSize} parameter in a \code{VcfFile} object. Iteration can be through all data fields or a subset defined by a \code{ScanVcfParam}. See example below, `Iterating through VCF with yieldSize`. } } } \value{ \code{readVcf} returns a \code{\linkS4class{VCF}} object. See ?\code{VCF} for complete details of the class structure. \code{readGT}, \code{readInfo} and \code{readGeno} return a \code{matrix}. \describe{ \item{rowRanges: }{ The CHROM, POS, ID and REF fields are used to create a \code{GRanges} object. Ranges are created using POS as the start value and width of the reference allele (REF). By default, the IDs become the rownames ('row.names = FALSE' to turn this off). If IDs are missing (i.e., \sQuote{.}) a string of CHROM:POS_REF/ALT is used instead. The \code{genome} argument is stored in the seqinfo of the \code{GRanges} and can be accessed with \code{genome()}. One metadata column, \code{paramRangeID}, is included with the \code{rowRanges}. This ID is meaningful when multiple ranges are specified in the \code{ScanVcfParam} and distinguishes which records match each range. } \item{fixed: }{ REF, ALT, QUAL and FILTER fields of the VCF are parsed into a \code{DataFrame}. REF is returned as a DNAStringSet. ALT is a CharacterList when it contains structural variants and a DNAStringSetList otherwise. See also the 'Details' section for 'Missing data'. } \item{info: }{ Data from the INFO field of the VCF is parsed into a \code{DataFrame}. } \item{geno: }{ If present, the genotype data are parsed into a list of \code{matrices} or \code{arrays}. Each list element represents a field in the FORMAT column of the VCF file. Rows are the variants, columns are the samples. } \item{colData: }{ This slot contains a \code{DataFrame} describing the samples. If present, the sample names following FORMAT in the VCF file become the row names. } \item{metadata: }{ Header information present in the file is put into a \code{list} in \code{metadata}. } } See references for complete details of the VCF file format. } \references{ \url{http://vcftools.sourceforge.net/specs.html} outlines the VCF specification. \url{http://samtools.sourceforge.net/mpileup.shtml} contains information on the portion of the specification implemented by \code{bcftools}. \url{http://samtools.sourceforge.net/} provides information on \code{samtools}. } \author{ Valerie Obenchain> } \seealso{ \code{\link{indexVcf}}, \code{\link{VcfFile}}, \code{\link{indexTabix}}, \code{\link{TabixFile}}, \code{\link{scanTabix}}, \code{\link{scanBcf}}, \code{\link{expand,CollapsedVCF-method}} } \examples{ fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") ## vcf <- readVcf(fl, c("20"="hg19")) ## 'genome' as named vector ## --------------------------------------------------------------------- ## Header and genome information ## --------------------------------------------------------------------- vcf ## all header information hdr <- header(vcf) ## header information for 'info' and 'fixed' fields info(hdr) fixed(hdr) ## --------------------------------------------------------------------- ## Accessors ## --------------------------------------------------------------------- ## fixed fields together head(fixed(vcf), 5) ## fixed fields separately filt(vcf) ref(vcf) ## info data info(hdr) info(vcf) info(vcf)$DP ## geno data geno(hdr) geno(vcf) head(geno(vcf)$GT) ## genome unique(genome(rowRanges(vcf))) ## --------------------------------------------------------------------- ## Data subsets with lightweight read* functions ## --------------------------------------------------------------------- ## Import a single 'info' or 'geno' variable DP <- readInfo(fl, "DP") HQ <- readGeno(fl, "HQ") ## Import GT as numeric representation GT <- readGT(fl) ## Import GT as nucleotides GT <- readGT(fl, nucleotides=TRUE) ## --------------------------------------------------------------------- ## Data subsets with ScanVcfParam ## --------------------------------------------------------------------- ## Subset on genome coordinates: ## 'file' must have an index rngs <- GRanges("20", IRanges(c(14370, 1110000), c(17330, 1234600))) names(rngs) <- c("geneA", "geneB") param <- ScanVcfParam(which=rngs) compressVcf <- bgzip(fl, tempfile()) tab <- indexVcf(compressVcf) vcf <- readVcf(tab, "hg19", param) ## When data are subset by range ('which' argument in ScanVcfParam), ## the 'paramRangeID' column provides a map back to the original ## range in 'param'. rowRanges(vcf)[,"paramRangeID"] vcfWhich(param) ## Subset on samples: ## Consult the header for the sample names. samples(hdr) ## Specify one or more names in 'samples' in a ScanVcfParam. param <- ScanVcfParam(samples="NA00002") vcf <- readVcf(tab, "hg19", param) geno(vcf)$GT ## Subset on 'fixed', 'info' or 'geno' fields: param <- ScanVcfParam(fixed="ALT", geno=c("GT", "HQ"), info=c("NS", "AF")) vcf_tab <- readVcf(tab, "hg19", param) info(vcf_tab) geno(vcf_tab) ## No ranges are specified in the 'param' so tabix file is not ## required. Instead, the uncompressed VCF can be used as 'file'. vcf_fname <- readVcf(fl, "hg19", param) ## The header will always contain information for all variables ## in the original file reguardless of how the data were subset. ## For example, all 'geno' fields are listed in the header geno(header(vcf_fname)) ## but only 'GT' and 'HQ' are present in the VCF object. geno(vcf_fname) ## Subset on both genome coordinates and 'info', 'geno' fields: param <- ScanVcfParam(geno="HQ", info="AF", which=rngs) vcf <- readVcf(tab, "hg19", param) ## When any of 'fixed', 'info' or 'geno' are omitted (i.e., no ## elements specified) all records are retrieved. Use NA to indicate ## that no records should be retrieved. This param specifies ## all 'fixed fields, the "GT" 'geno' field and none of 'info'. ScanVcfParam(geno="GT", info=NA) ## --------------------------------------------------------------------- ## Iterate through VCF with 'yieldSize' ## --------------------------------------------------------------------- fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") param <- ScanVcfParam(fixed="ALT", geno=c("GT", "GL"), info=c("LDAF")) tab <- VcfFile(fl, yieldSize=4000) open(tab) while (nrow(vcf_yield <- readVcf(tab, "hg19", param=param))) cat("vcf dim:", dim(vcf_yield), "\n") close(tab) ## --------------------------------------------------------------------- ## Debugging with 'verbose' ## --------------------------------------------------------------------- ## readVcf() uses information in the header lines to parse the data to ## the correct number and type. Fields without header lines are skipped. ## If a call to readVcf() results in no info(VCF) or geno(VCF) data the ## file may be missing header lines. Set 'verbose = TRUE' to get ## a listing of fields found in the header. ## readVcf(myfile, "mygenome", verbose=TRUE) ## Header fields can also be discovered with scanVcfHeader(). hdr <- scanVcfHeader(fl) geno(hdr) } \keyword{manip} VariantAnnotation/man/scanVcf-methods.Rd0000644000175100017510000001214714614305321021323 0ustar00biocbuildbiocbuild\name{scanVcf} \Rdversion{1.1} \alias{scanVcfHeader} \alias{scanVcfHeader,missing-method} \alias{scanVcfHeader,character-method} \alias{scanVcf} \alias{scanVcf,character,ScanVcfParam-method} \alias{scanVcf,character,missing-method} \alias{scanVcf,connection,missing-method} \alias{scanVcfHeader,TabixFile-method} \alias{scanVcf,TabixFile,GRanges-method} \alias{scanVcf,TabixFile,IntegerRangesList-method} \alias{scanVcf,TabixFile,ScanVcfParam-method} \alias{scanVcf,TabixFile,missing-method} \title{ Import VCF files } \description{ Import Variant Call Format (VCF) files in text or binary format } \usage{ scanVcfHeader(file, ...) \S4method{scanVcfHeader}{character}(file, ...) scanVcf(file, ..., param) \S4method{scanVcf}{character,ScanVcfParam}(file, ..., param) \S4method{scanVcf}{character,missing}(file, ..., param) \S4method{scanVcf}{connection,missing}(file, ..., param) \S4method{scanVcfHeader}{TabixFile}(file, ...) \S4method{scanVcf}{TabixFile,missing}(file, ..., param) \S4method{scanVcf}{TabixFile,ScanVcfParam}(file, ..., param) \S4method{scanVcf}{TabixFile,GRanges}(file, ..., param) \S4method{scanVcf}{TabixFile,IntegerRangesList}(file, ..., param) } \arguments{ \item{file}{For \code{scanVcf} and \code{scanVcfHeader}, the character() file name, \code{\link{TabixFile}}, or class \code{connection} (\code{file()} or \code{bgzip()}) of the \sQuote{VCF} file to be processed. } \item{param}{A instance of \code{\linkS4class{ScanVcfParam}} influencing which records are parsed and the \sQuote{INFO} and \sQuote{GENO} information returned. } \item{...}{Additional arguments for methods } } \details{ The argument \code{param} allows portions of the file to be input, but requires that the file be bgzip'd and indexed as a \code{\linkS4class{TabixFile}}. \code{scanVcf} with \code{param="missing"} and \code{file="character"} or \code{file="connection"} scan the entire file. With \code{file="connection"}, an argument \code{n} indicates the number of lines of the VCF file to input; a connection open at the beginning of the call is open and incremented by \code{n} lines at the end of the call, providing a convenient way to stream through large VCF files. The INFO field of the scanned VCF file is returned as a single \sQuote{packed} vector, as in the VCF file. The GENO field is a list of matrices, each matrix corresponds to a field as defined in the FORMAT field of the VCF header. Each matrix has as many rows as scanned in the VCF file, and as many columns as there are samples. As with the INFO field, the elements of the matrix are \sQuote{packed}. The reason that INFO and GENO are returned packed is to facilitate manipulation, e.g., selecting particular rows or samples in a consistent manner across elements. } \value{ \code{scanVcfHeader} returns a \code{VCFHeader} object with header information parsed into five categories, \code{samples}, \code{meta}, \code{fixed}, \code{info} and \code{geno}. Each can be accessed with a `getter' of the same name (e.g., info()). If the file header has multiple rows with the same name (e.g., 'source') the row names of the DataFrame are made unique in the usual way, 'source', 'source.1' etc. \code{scanVcf} returns a list, with one element per range. Each list has 7 elements, obtained from the columns of the VCF specification: \describe{ \item{rowRanges}{ \code{GRanges} instance derived from \code{CHROM}, \code{POS}, \code{ID}, and the width of \code{REF} } \item{REF}{ reference allele } \item{ALT}{ alternate allele } \item{QUAL}{ phred-scaled quality score for the assertion made in ALT } \item{FILTER}{ indicator of whether or not the position passed all filters applied } \item{INFO}{ additional information } \item{GENO}{ genotype information immediately following the FORMAT field in the VCF } } The \code{GENO} element is itself a list, with elements corresponding to those defined in the VCF file header. For \code{scanVcf}, elements of GENO are returned as a matrix of records x samples; if the description of the element in the file header indicated multiplicity other than 1 (e.g., variable number for \dQuote{A}, \dQuote{G}, or \dQuote{.}), then each entry in the matrix is a character string with sub-entries comma-delimited. } \references{ \url{http://vcftools.sourceforge.net/specs.html} outlines the VCF specification. \url{http://samtools.sourceforge.net/mpileup.shtml} contains information on the portion of the specification implemented by \code{bcftools}. \url{http://samtools.sourceforge.net/} provides information on \code{samtools}. } \seealso{ \code{\link{readVcf}} \code{\link{BcfFile}} \code{\link{TabixFile}} } \author{ Martin Morgan and Valerie Obenchain> } \examples{ fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") scanVcfHeader(fl) vcf <- scanVcf(fl) ## value: list-of-lists str(vcf) names(vcf[[1]][["GENO"]]) vcf[[1]][["GENO"]][["GT"]] } \keyword{ manip } VariantAnnotation/man/ScanVcfParam-class.Rd0000644000175100017510000001511114614305321021700 0ustar00biocbuildbiocbuild\name{ScanVcfParam-class} \docType{class} \alias{ScanVcfParam} \alias{ScanVcfParam-class} \alias{ScanVcfParam,missing-method} \alias{ScanVcfParam,ANY-method} \alias{vcfFixed} \alias{vcfFixed<-} \alias{vcfInfo} \alias{vcfInfo<-} \alias{vcfGeno} \alias{vcfGeno<-} \alias{vcfSamples} \alias{vcfSamples<-} \alias{vcfTrimEmpty} \alias{vcfTrimEmpty<-} \alias{vcfWhich} \alias{vcfWhich<-} \title{Parameters for scanning VCF files} \description{ Use \code{ScanVcfParam()} to create a parameter object influencing which records and fields are imported from a VCF file. Record parsing is based on genomic coordinates and requires a Tabix index file. Individual VCF elements can be specified in the \sQuote{fixed}, \sQuote{info}, \sQuote{geno} and \sQuote{samples} arguments. } \usage{ ScanVcfParam(fixed=character(), info=character(), geno=character(), samples=character(), trimEmpty=TRUE, which, ...) ## Getters and Setters vcfFixed(object) vcfFixed(object) <- value vcfInfo(object) vcfInfo(object) <- value vcfGeno(object) vcfGeno(object) <- value vcfSamples(object) vcfSamples(object) <- value vcfTrimEmpty(object) vcfTrimEmpty(object) <- value vcfWhich(object) vcfWhich(object) <- value } \arguments{ \item{fixed}{A character() vector of fixed fields to be returned. Possible values are ALT, QUAL and FILTER. The CHROM, POS, ID and REF fields are needed to create the \code{GRanges} of variant locations. Because these are essential fields there is no option to request or omit them. If not specified, all fields are returned; if \code{fixed=NA} only REF is returned. } \item{info}{A character() vector naming the \sQuote{INFO} fields to return. \code{scanVcfHeader()} returns a vector of available fields. If not specified, all fields are returned; if \code{info=NA} no fields are returned. } \item{geno}{A character() vector naming the \sQuote{GENO} fields to return. \code{scanVcfHeader()} returns a vector of available fields. If not specified, all fields are returned; if \code{geno=NA} no fields are returned and requests for specific samples are ignored. } \item{samples}{A character() vector of sample names to return. \code{samples(scanVcfHeader())} returns all possible names. If not specified, data for all samples are returned; if either \code{samples=NA} or \code{geno=NA} no fields are returned. Requests for specific samples when \code{geno=NA} are ignored. } \item{trimEmpty}{A logical(1) indicating whether \sQuote{GENO} fields with no values should be returned. } \item{which}{A \code{\linkS4class{GRanges}} describing the sequences and ranges to be queried. Variants whose \code{POS} lies in the interval(s) \code{[start, end]} are returned. If \code{which} is not specified all ranges are returned. } \item{object}{An instance of class \code{ScanVcfParam}. } \item{value}{An instance of the corresponding slot, to be assigned to \code{object}. } \item{\dots}{Arguments passed to methods. } } \section{Objects from the Class}{ Objects can be created by calls of the form \code{ScanVcfParam()}. } \section{Slots}{ \describe{ \item{\code{which}:}{Object of class \code{"IntegerRangesList"} indicating which reference sequence and coordinate variants must overlap. } \item{\code{fixed}:}{Object of class \code{"character"} indicating fixed fields to be returned. } \item{\code{info}:}{Object of class \code{"character"} indicating portions of \sQuote{INFO} to be returned. } \item{\code{geno}:}{Object of class \code{"character"} indicating portions of \sQuote{GENO} to be returned. } \item{\code{samples}:}{Object of class \code{"character"} indicating the samples to be returned. } \item{\code{trimEmpty}:}{Object of class \code{"logical"} indicating whether empty \sQuote{GENO} fields are to be returned. } } } \section{Functions and methods}{ See 'Usage' for details on invocation. Constructor: \describe{ \item{ScanVcfParam:}{Returns a \code{ScanVcfParam} object. The \code{which} argument to the constructor can be one of several types, as documented above.} } Accessors: \describe{ \item{vcfFixed, vcfInfo, vcfGeno, vcfSamples, vcfTrimEmpty, vcfWhich:}{ Return the corresponding field from \code{object}. } } Methods: \describe{ \item{show}{Compactly display the object. } } } \author{ Martin Morgan and Valerie Obenchain } \seealso{ \code{\link{readVcf}} } \examples{ ScanVcfParam() fl <- system.file("extdata", "structural.vcf", package="VariantAnnotation") compressVcf <- bgzip(fl, tempfile()) idx <- indexTabix(compressVcf, "vcf") tab <- TabixFile(compressVcf, idx) ## --------------------------------------------------------------------- ## 'which' argument ## --------------------------------------------------------------------- ## To subset on genomic coordinates, supply an object ## containing the ranges of interest. These ranges can ## be given directly to the 'param' argument or wrapped ## inside ScanVcfParam() as the 'which' argument. ## When using a list, the outer list names must correspond to valid ## chromosome names in the vcf file. In this example they are "1" ## and "2". gr1 <- GRanges("1", IRanges(13219, 2827695, name="regionA")) gr2 <- GRanges(rep("2", 2), IRanges(c(321680, 14477080), c(321689, 14477090), name=c("regionB", "regionC"))) grl <- GRangesList("1"=gr1, "2"=gr2) vcf <- readVcf(tab, "hg19", grl) ## Names of the ranges are in the 'paramRangeID' metadata column of the ## GRanges object returned by the rowRanges() accessor. rowRanges(vcf) ## which can be used for subsetting the VCF object vcf[rowRanges(vcf)$paramRangeID == "regionA"] ## When using ranges, the seqnames must correspond to valid ## chromosome names in the vcf file. gr <- unlist(grl, use.names=FALSE) vcf <- readVcf(tab, "hg19", gr) ## --------------------------------------------------------------------- ## 'fixed', 'info', 'geno' and 'samples' arguments ## --------------------------------------------------------------------- ## This param specifies the "GT" 'geno' field for a single sample ## and the subset of ranges in 'which'. All 'fixed' and 'info' fields ## will be returned. ScanVcfParam(geno="GT", samples="NA00002", which=gr) ## Here two 'fixed' and one 'geno' field are specified ScanVcfParam(fixed=c("ALT", "QUAL"), geno="GT", info=NA) ## Return only the 'fixed' fields ScanVcfParam(geno=NA, info=NA) } \keyword{classes} VariantAnnotation/man/seqinfo-method.Rd0000644000175100017510000000152014614305321021212 0ustar00biocbuildbiocbuild\name{seqinfo} \alias{seqinfo} \alias{seqinfo,VcfFile-method} \alias{seqinfo,VcfFileList-method} \title{Get seqinfo for VCF file} \description{Get seqinfo for VCF file} \usage{ \S4method{seqinfo}{VcfFile}(x) \S4method{seqinfo}{VcfFileList}(x) } \arguments{ \item{x}{Either character(), \code{VcfFile}, or \code{VcfFileList}} } \details{ If a \code{VcfFile}The file header is scanned an appropriate seqinfo object in given. If a \code{VcfFileList} is given, all file headers are scanned, and appropriate combined seqinfo object is given. } \value{Seqinfo object} \author{Lori Shepherd} \seealso{ \code{\link{VcfFile}}, \code{\link[GenomeInfoDb]{Seqinfo}} } \examples{ fl <- system.file("extdata", "chr7-sub.vcf.gz", package="VariantAnnotation", mustWork=TRUE) vcf <- VcfFile(fl) seqinfo(vcf) } \keyword{manip} VariantAnnotation/man/SIFTDb-class.Rd0000644000175100017510000000665114614305321020420 0ustar00biocbuildbiocbuild\name{SIFTDb-class} \docType{class} \alias{SIFT} \alias{SIFTDb} \alias{class:SIFTDb} \alias{SIFTDb-class} \alias{metadata,SIFTDb-method} \alias{columns,SIFTDb-method} \alias{keys,SIFTDb-method} \alias{select,SIFTDb-method} \title{SIFTDb objects} \description{ The SIFTDb class is a container for storing a connection to a SIFT sqlite database. } \section{Methods}{ In the code below, \code{x} is a \code{SIFTDb} object. \describe{ \item{}{ \code{metadata(x)}: Returns \code{x}'s metadata in a data frame. } \item{}{ \code{columns(x)}: Returns the names of the \code{columns} that can be used to subset the data columns. } \item{}{ \code{keys(x)}: Returns the names of the \code{keys} that can be used to subset the data rows. The \code{keys} values are the rsid's. } \item{}{ \code{select(x, keys = NULL, columns = NULL, ...)}: Returns a subset of data defined by the character vectors \code{keys} and \code{columns}. If no \code{keys} are supplied, all rows are returned. If no \code{columns} are supplied, all columns are returned. For column descriptions see \code{?SIFTDbColumns}. } } } \details{ SIFT is a sequence homology-based tool that sorts intolerant from tolerant amino acid substitutions and predicts whether an amino acid substitution in a protein will have a phenotypic effect. SIFT is based on the premise that protein evolution is correlated with protein function. Positions important for function should be conserved in an alignment of the protein family, whereas unimportant positions should appear diverse in an alignment. SIFT uses multiple alignment information to predict tolerated and deleterious substitutions for every position of the query sequence. The procedure can be outlined in the following steps, \itemize{ \item search for similar sequences \item choose closely related sequences that may share similar function to the query sequence \item obtain the alignment of the chosen sequences \item calculate normalized probabilities for all possible substitutions from the alignment. } Positions with normalized probabilities less than 0.05 are predicted to be deleterious, those greater than or equal to 0.05 are predicted to be tolerated. } \references{ SIFT Home: \url{http://sift.jcvi.org/} Kumar P, Henikoff S, Ng PC. Predicting the effects of coding non-synonymous variants on protein function using the SIFT algorithm. Nat Protoc. 2009;4(7):1073-81 Ng PC, Henikoff S. Predicting the Effects of Amino Acid Substitutions on Protein Function Annu Rev Genomics Hum Genet. 2006;7:61-80. Ng PC, Henikoff S. SIFT: predicting amino acid changes that affect protein function. Nucleic Acids Res. 2003 Jul 1;31(13):3812-4. } \author{Valerie Obenchain} \examples{ if (interactive()) { library(SIFT.Hsapiens.dbSNP132) ## metadata metadata(SIFT.Hsapiens.dbSNP132) ## available rsid's head(keys(SIFT.Hsapiens.dbSNP132)) ## for column descriptions see ?SIFTDbColumns columns(SIFT.Hsapiens.dbSNP132) ## subset on keys and columns rsids <- c("rs2142947", "rs17970171", "rs8692231", "rs3026284") subst <- c("RSID", "PREDICTION", "SCORE") select(SIFT.Hsapiens.dbSNP132, keys=rsids, columns=subst) select(SIFT.Hsapiens.dbSNP132, keys=rsids[1:2]) } } \keyword{classes} \keyword{methods} VariantAnnotation/man/SIFTDbColumns.Rd0000644000175100017510000000303614614305321020650 0ustar00biocbuildbiocbuild\name{SIFTDbColumns} \alias{SIFTDbColumns} \title{SIFTDb Columns} \description{ Description of the SIFT Sqlite Database Columns } \section{Column descriptions}{ These column names are displayed when \code{columns} is called on a \code{SIFTDb} object. \itemize{ \item RSID : rsid \item PROTEINID : NCBI RefSeq protein ID \item AACHANGE : amino acid substitution; reference aa is preceeding, followed by the position and finally the snp aa \item METHOD : method of obtaining related sequences using PSI-BLAST \item AA : either the reference or snp residue amino acid \item PREDICTION : SIFT prediction \item SCORE : SIFT score (range 0 to 1) \itemize{ \item TOLERATED : score is greater than 0.05 \item DAMAGING : score is less than or equal to 0.05 \item NOT SCORED : no prediction is made if there are less than 2 homologous sequences that have an amino acid at the position of the given SNP or if the SIFT prediction is not available } \item MEDIAN : diversity measurement of the sequences used for prediction (range 0 to 4.32) \item POSITIONSEQS : number of sequences with an amino acide at the position of prediction \item TOTALSEQS : total number of sequences in alignment } } \seealso{ \code{?SIFTDb} } \author{Valerie Obenchain} \keyword{classes} \keyword{methods} VariantAnnotation/man/snpSummary.Rd0000644000175100017510000000475114614305321020457 0ustar00biocbuildbiocbuild\name{snpSummary} \alias{snpSummary} \alias{snpSummary,CollapsedVCF-method} \title{Counts and distribution statistics for SNPs in a VCF object} \description{ Counts and distribution statistics for SNPs in a VCF object } \usage{ \S4method{snpSummary}{CollapsedVCF}(x, ...) } \arguments{ \item{x}{ A \link{CollapsedVCF} object. } \item{\dots}{ Additional arguments to methods. } } \details{ Genotype counts, allele counts and Hardy Weinberg equilibrium (HWE) statistics are calculated for single nucleotide variants in a \link{CollapsedVCF} object. HWE has been established as a useful quality filter on genotype data. This equilibrium should be attained in a single generation of random mating. Departures from HWE are indicated by small p values and are almost invariably indicative of a problem with genotype calls. The following caveats apply: \itemize{ \item No distinction is made between phased and unphased genotypes. \item Only diploid calls are included. \item Only `valid' SNPs are included. A `valid' SNP is defined as having a reference allele of length 1 and a single alternate allele of length 1. } Variants that do not meet these criteria are set to NA. } \value{ The object returned is a \code{data.frame} with seven columns. \describe{ \item{g00}{ Counts for genotype 00 (homozygous reference). } \item{g01}{ Counts for genotype 01 or 10 (heterozygous). } \item{g11}{ Counts for genotype 11 (homozygous alternate). } \item{a0Freq}{ Frequency of the reference allele. } \item{a1Freq}{ Frequency of the alternate allele. } \item{HWEzscore}{ Z-score for departure from a null hypothesis of Hardy Weinberg equilibrium. } \item{HWEpvalue}{ p-value for departure from a null hypothesis of Hardy Weinberg equilibrium. } } } \author{ Chris Wallace } \seealso{ \link{genotypeToSnpMatrix}, \link{probabilityToSnpMatrix} } \examples{ fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") ## The return value is a data.frame with genotype counts ## and allele frequencies. df <- snpSummary(vcf) df ## Compare to ranges in the VCF object: rowRanges(vcf) ## No statistics were computed for the variants in rows 3, 4 ## and 5. They were omitted because row 3 has two alternate ## alleles, row 4 has none and row 5 is not a SNP. } \keyword{manip} VariantAnnotation/man/summarizeVariants-methods.Rd0000644000175100017510000001430614614305321023463 0ustar00biocbuildbiocbuild\name{summarizeVariants} \alias{summarizeVariants} \alias{summarizeVariants,TxDb,VCF,CodingVariants-method} \alias{summarizeVariants,TxDb,VCF,FiveUTRVariants-method} \alias{summarizeVariants,TxDb,VCF,ThreeUTRVariants-method} \alias{summarizeVariants,TxDb,VCF,SpliceSiteVariants-method} \alias{summarizeVariants,TxDb,VCF,IntronVariants-method} \alias{summarizeVariants,TxDb,VCF,PromoterVariants-method} \alias{summarizeVariants,GRangesList,VCF,VariantType-method} \alias{summarizeVariants,GRangesList,VCF,function-method} \title{Summarize variants by sample} \description{ Variants in a VCF file are overlapped with an annotation region and summarized by sample. Genotype information in the VCF is used to determine which samples express each variant. } \usage{ \S4method{summarizeVariants}{TxDb,VCF,CodingVariants}(query, subject, mode, ...) \S4method{summarizeVariants}{TxDb,VCF,FiveUTRVariants}(query, subject, mode, ...) \S4method{summarizeVariants}{TxDb,VCF,ThreeUTRVariants}(query, subject, mode, ...) \S4method{summarizeVariants}{TxDb,VCF,SpliceSiteVariants}(query, subject, mode, ...) \S4method{summarizeVariants}{TxDb,VCF,IntronVariants}(query, subject, mode, ...) \S4method{summarizeVariants}{TxDb,VCF,PromoterVariants}(query, subject, mode, ...) \S4method{summarizeVariants}{GRangesList,VCF,VariantType}(query, subject, mode, ...) \S4method{summarizeVariants}{GRangesList,VCF,function}(query, subject, mode, ...) } \arguments{ \item{query}{A \link[GenomicFeatures]{TxDb} or \code{GRangesList} object that serves as the annotation. GFF files can be converted to \link[GenomicFeatures]{TxDb} objects with \code{makeTxDbFromGFF()} in the \code{txdbmaker} package. } \item{subject}{A \linkS4class{VCF} object containing the variants. } \item{mode}{\code{mode} can be a \code{VariantType} class or the name of a function. When \code{mode} is a \code{VariantType} class, counting is done with \code{locateVariants} and counts are summarized transcript-by-sample. Supported \code{VariantType} classes include \code{CodingVariants}, \code{IntronVariants}, \code{FiveUTRVariants}, \code{ThreeUTRVariants}, \code{SpliceSiteVariants} or \code{PromoterVariants}. \code{AllVariants()} and \code{IntergenicVariants} are not supported. See ?\code{locateVariants} for more detail on the variant classes. \code{mode} can also be the name of any counting function that outputs a \code{Hits} object. Variants will be summarized by the length of the \code{GRangesList} annotation (i.e., 'length-of-GRangesList'-by-sample). } \item{\dots}{Additional arguments passed to methods such as \describe{ \item{ignore.strand}{A \code{logical} indicating if strand should be igored when performing overlaps. } } } } \details{ \code{summarizeVariants} uses the genotype information in a VCF file to determine which samples are positive for each variant. Variants are overlapped with the annotation and the counts are summarized annotation-by-sample. If the annotation is a \code{GRangesList} of transcripts, the count matrix will be transcripts-by-sample. If the \code{GRangesList} is genes, the count matrix will be gene-by-sample. \itemize{ \item{Counting with locateVariants() :}{ Variant counts are always summarized transcript-by-sample. When \code{query} is a \code{GRangesList}, it must be compatible with the \code{VariantType}-class given as the \code{mode} argument. The list below specifies the appropriate \code{GRangesList} for each \code{mode}. \describe{ \item{CodingVariants :}{coding (CDS) by transcript} \item{IntronVariants :}{introns by transcript} \item{FiveUTRVariants :}{five prime UTR by transcript} \item{ThreeUTRVariants :}{three prime UTR by transcript} \item{SpliceSiteVariants :}{introns by transcript} \item{PromoterVariants :}{list of transcripts} } When \code{query} is a \code{TxDb}, the appropriate region-by-transcript \code{GRangesList} listed above is extracted internally and used as the annotation. } \item{Counting with a user-supplied function :}{ \code{subject} must be a \code{GRangesList} and \code{mode} must be the name of a function. The count function must take 'query' and 'subject' arguments and return a \code{Hits} object. Counts are summarized by the outer list elements of the \code{GRangesList}. } } } \value{ A \code{RangedSummarizedExperiment} object with count summaries in the \code{assays} slot. The \code{rowRanges} contains the annotation used for counting. Information in \code{colData} and \code{metadata} are taken from the VCF file. } \author{Valerie Obenchain} \seealso{ \code{\link{readVcf}}, \code{\link{predictCoding}}, \code{\link{locateVariants}} } \examples{ library(TxDb.Hsapiens.UCSC.hg19.knownGene) txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene ## Read variants from VCF. fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") ## Rename seqlevels to match TxDb; confirm the match. seqlevels(vcf) <- paste0("chr", seqlevels(vcf)) intersect(seqlevels(vcf), seqlevels(txdb)) ## ---------------------------------------- ## Counting with locateVariants() ## ---------------------------------------- ## TxDb as the 'query' coding1 <- summarizeVariants(txdb, vcf, CodingVariants()) colSums(assays(coding1)$counts) ## GRangesList as the 'query' cdsbytx <- cdsBy(txdb, "tx") coding2 <- summarizeVariants(cdsbytx, vcf, CodingVariants()) stopifnot(identical(assays(coding1)$counts, assays(coding2)$counts)) ## Promoter region variants summarized by transcript tx <- transcripts(txdb) txlst <- splitAsList(tx, seq_len(length(tx))) promoter <- summarizeVariants(txlst, vcf, PromoterVariants(upstream=100, downstream=10)) colSums(assays(promoter)$counts) ## ---------------------------------------- ## Counting with findOverlaps() ## ---------------------------------------- ## Summarize all variants by transcript allvariants <- summarizeVariants(txlst, vcf, findOverlaps) colSums(assays(allvariants)$counts) } \keyword{methods} VariantAnnotation/man/variant_body.Rd0000644000175100017510000000101214614305321020745 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/use_vep_api.R \name{variant_body} \alias{variant_body} \title{helper function to construct inputs for VEP REST API} \usage{ variant_body(chr, pos, id, ref, alt) } \arguments{ \item{chr}{character(1)} \item{pos}{numeric(1)} \item{id}{character(1)} \item{ref}{character(1)} \item{alt}{character(1)} } \description{ helper function to construct inputs for VEP REST API } \note{ Produces a string used as an example in VEP API documentation. } VariantAnnotation/man/VariantType-class.Rd0000644000175100017510000001357214614305321021653 0ustar00biocbuildbiocbuild\name{VariantType-class} \docType{class} % Class \alias{VariantType-class} % Subclasses \alias{CodingVariants-class} \alias{IntronVariants-class} \alias{FiveUTRVariants-class} \alias{ThreeUTRVariants-class} \alias{SpliceSiteVariants-class} \alias{IntergenicVariants-class} \alias{PromoterVariants-class} \alias{AllVariants-class} % Constructors for subclasses : \alias{CodingVariants} \alias{IntronVariants} \alias{FiveUTRVariants} \alias{ThreeUTRVariants} \alias{SpliceSiteVariants} \alias{IntergenicVariants} \alias{PromoterVariants} \alias{AllVariants} % accessors : \alias{upstream} \alias{upstream,AllVariants-method} \alias{upstream,PromoterVariants-method} \alias{upstream,IntergenicVariants-method} \alias{upstream<-} \alias{upstream<-,AllVariants-method} \alias{upstream<-,PromoterVariants-method} \alias{upstream<-,IntergenicVariants-method} \alias{idType} \alias{idType<-} \alias{idType,IntergenicVariants-method} \alias{idType<-,IntergenicVariants-method} \alias{downstream} \alias{downstream,AllVariants-method} \alias{downstream,PromoterVariants-method} \alias{downstream,IntergenicVariants-method} \alias{downstream<-} \alias{downstream<-,AllVariants-method} \alias{downstream<-,PromoterVariants-method} \alias{downstream<-,IntergenicVariants-method} \alias{promoter} \alias{promoter,AllVariants-method} \alias{promoter<-} \alias{promoter<-,AllVariants-method} \alias{intergenic} \alias{intergenic,AllVariants-method} \alias{intergenic<-} \alias{intergenic<-,AllVariants-method} % show method: \alias{show,VariantType-method} \alias{show,AllVariants-method} \alias{show,PromoterVariants-method} \title{VariantType subclasses} \description{ \code{VariantType} subclasses specify the type of variant to be located with \code{locateVariants}. } \usage{ CodingVariants() IntronVariants() FiveUTRVariants() ThreeUTRVariants() SpliceSiteVariants() IntergenicVariants(upstream = 1e+06L, downstream = 1e+06L, idType=c("gene", "tx")) PromoterVariants(upstream = 2000L, downstream = 200L) AllVariants(promoter = PromoterVariants(), intergenic = IntergenicVariants()) } \details{ \code{VariantType} is a virtual class inherited by the \code{CodingVariants}, \code{IntronVariants}, \code{FiveUTRVariants}, \code{ThreeUTRVariants}, \code{SpliceSiteVariants}, \code{IntergenicVariants} and \code{AllVariants} subclasses. The subclasses are used as the \code{region} argument to \code{locateVariants}. They designate the type of variant (i.e., region of the annotation to match) when calling \code{locateVariants}. The majority of subclasses have no slots and require no arguments for an instance to be created. \code{PromoterVariants} and \code{IntergenicVariants} and accept \code{upstream} and \code{downstream} arguments that define the number of base pairs upstream from the 5'-end and downstream from the 3'-end of the transcript region. See the ?\code{locateVariants} man page for details. \code{IntergenicVariants} also accepts a \code{idType} that controls what IDs are returned in the PRECEDEID and FOLLOWID metadata columns. \code{AllVariants} accepts \code{promoter} and \code{intergenic} arguments which are \code{PromoterVariants()} and \code{IntergenicVariants()} objects with the appropriate \code{upstream} and \code{downstream} values. } \arguments{ \item{upstream, downstream}{ Single \code{integer} values representing the number of base pairs upstream of the 5'-end and downstream of the 3'-end. Used in contructing \code{PromoterVariants()} and \code{IntergenicVariants()} objects only. } \item{idType}{ \code{character} indicating if the ids in the PRECEDEID and FOLLOWID metadata columns should be gene ids ("gene") or transcript ids ("tx"). Applicable to \code{IntergenicVariants()} objects only. } \item{promoter}{ \code{PromoterVariants} object with appropriate \code{upstream} and \code{downstream} values. Used when constructing \code{AllVariants} objects only. } \item{intergenic}{ \code{IntergenicVariants} object with appropriate \code{upstream} and \code{downstream} values. Used when constructing \code{AllVariants} objects only. } } \section{Accessors}{ In the following code, \code{x} is a \code{PromoterVariants} or a \code{AllVariants} object. \describe{ \item{}{ \code{upstream(x)}, \code{upstream(x) <- value}: Gets or sets the number of base pairs defining a range upstream of the 5' end (excludes 5' start value). } \item{}{ \code{downstream(x)}, \code{downstream(x) <- value}: Gets or sets the number of base pairs defining a range downstream of the 3' end (excludes 3' end value). } \item{}{ \code{idType(x)}, \code{idType(x) <- value}: Gets or sets the \code{character()} which controls the id returned in the PRECEDEID and FOLLOWID output columns. Possible values are "gene" and "tx". } \item{}{ \code{promoters(x)}, \code{promoters(x) <- value}: Gets or sets the \code{PromoterVariants} in the \code{AllVariants} object. } \item{}{ \code{intergenic(x)}, \code{intergenic(x) <- value}: Gets or sets the \code{IntergenicVariants} in the \code{AllVariants} object. } } } \author{Valerie Obenchain} \seealso{ \itemize{ \item The promoters function on the \link[GenomicRanges]{intra-range-methods} man page in the GenomicRanges package. } } \examples{ CodingVariants() SpliceSiteVariants() PromoterVariants(upstream=1000, downstream=10000) ## Default values for PromoterVariants and IntergenicVariants AllVariants() ## Modify 'upstream' and 'downstream' for IntergenicVariants AllVariants(intergenic=IntergenicVariants(500, 100)) ## Reset PromoterVariants on existing AllVariants object av <- AllVariants() av promoter(av) <- PromoterVariants(100, 50) av } VariantAnnotation/man/VCF-class.Rd0000644000175100017510000004661114614305321020023 0ustar00biocbuildbiocbuild\name{VCF-class} \docType{class} % Class \alias{class:VCF} \alias{VCF-class} \alias{CollapsedVCF} \alias{class:CollapsedVCF} \alias{CollapsedVCF-class} \alias{ExpandedVCF} \alias{class:ExpandedVCF} \alias{ExpandedVCF-class} % Constructors: \alias{VCF} % Coercion methods: \alias{SnpMatrixToVCF} % Accessor methods: \alias{updateObject,VCF-method} \alias{fixed} \alias{fixed,VCF-method} \alias{fixed<-} \alias{fixed<-,VCF,DataFrame-method} \alias{ref} \alias{ref,VCF-method} \alias{ref<-} \alias{ref<-,VCF,DNAStringSet-method} \alias{alt} \alias{alt,VCF-method} \alias{alt<-} \alias{alt<-,CollapsedVCF,CharacterList-method} \alias{alt<-,ExpandedVCF,character-method} \alias{alt<-,CollapsedVCF,DNAStringSetList-method} \alias{alt<-,ExpandedVCF,DNAStringSet-method} \alias{qual} \alias{qual,VCF-method} \alias{qual<-} \alias{qual<-,VCF,numeric-method} \alias{filt} \alias{filt,VCF-method} \alias{filt<-} \alias{filt<-,VCF,character-method} \alias{info} \alias{info,VCF-method} \alias{info<-} \alias{info<-,VCF,DataFrame-method} \alias{rowRanges,VCF-method} \alias{rowRanges<-,VCF,GRanges-method} \alias{mcols<-,VCF-method} \alias{mcols<-,VCF,ANY-method} \alias{dimnames<-,VCF,list-method} \alias{geno} \alias{geno,VCF-method} \alias{geno,VCF,ANY-method} \alias{geno,VCF,character-method} \alias{geno,VCF,numeric-method} \alias{geno,VCFHeader,ANY-method} \alias{geno<-} \alias{geno<-,VCF,character,matrix-method} \alias{geno<-,VCF,numeric,matrix-method} \alias{geno<-,VCF,missing,matrix-method} \alias{geno<-,VCF,missing,SimpleList-method} \alias{strand,VCF-method} \alias{strand<-,VCF,ANY-method} \alias{header,VCF-method} \alias{header<-} \alias{header<-,VCF,VCFHeader-method} \alias{vcfFields,VCF-method} % Subset methods \alias{[,VCF-method} \alias{[,VCF,ANY,ANY-method} \alias{[,VCF,ANY,ANY,ANY-method} \alias{subset,VCF-method} \alias{[<-,VCF,ANY,ANY,VCF-method} % Combine methods \alias{cbind,VCF-method} \alias{rbind,VCF-method} % Other methods / functions \alias{genome,VCF-method} \alias{seqlevels,VCF-method} \alias{expand,CollapsedVCF-method} \alias{expand,ExpandedVCF-method} \alias{genotypeCodesToNucleotides} % show method: \alias{show,VCF-method} \alias{show,CollapsedVCF-method} \alias{show,ExpandedVCF-method} \title{VCF class objects} \description{ The VCF class is a virtual class extended from \code{RangedSummarizedExperiment}. The subclasses, \code{CompressedVCF} and \code{ExtendedVCF}, are containers for holding data from Variant Call Format files. } \section{Constructors}{ \describe{ \item{}{ \code{readVcf(file, genome, param, ..., row.names=TRUE)} } \item{}{ \code{VCF(rowRanges = GRanges(), colData = DataFrame(), exptData = list(header = VCFHeader()), fixed = DataFrame(), info = DataFrame(), geno = SimpleList(), ..., collapsed=TRUE, verbose = FALSE)} Creates CollapsedVCF when \code{collapsed = TRUE} and an ExpandedVCF when \code{collapsed = FALSE}. This is a low-level constructor used internally. Most instances of the \code{VCF} class are created with \code{readVCF}. } } } \section{Accessors}{ In the following code snippets \code{x} is a CollapsedVCF or ExpandedVCF object. \describe{ \item{}{ \code{rowRanges(x, ..., fixed = TRUE)}, \code{rowRanges(x) <- value}: Gets or sets the rowRanges. The CHROM, POS, ID, POS and REF fields are used to create a \code{GRanges} object. The start of the ranges are defined by POS and the width is equal to the width of the reference allele REF. The IDs become the rownames. If they are missing (i.e., \sQuote{.}) a string of CHROM:POS_REF/ALT is used instead. The \code{genome} argument is stored in the seqinfo of the \code{GRanges} and can be accessed with \code{genome()}. When \code{fixed = TRUE}, REF, ALT, QUAL and FILTER metadata columns are displayed as metadata columns. To modify the \code{fixed} fields, use the \code{fixed<-} setter. One metadata column, \code{paramRangeID}, is included with the \code{rowRanges}. This ID is meaningful when multiple ranges are specified in the \code{ScanVcfParam} and distinguishes which records match each range. The metadata columns of a VCF object are accessed with the following: \itemize{ \item{\code{ref(x)}, \code{ref(x) <- value}: Gets or sets the reference allele (REF). \code{value} must be a \code{DNAStringSet}. } \item{\code{alt(x)}, \code{alt(x) <- value}: Gets or sets the alternate allele data (ALT). When \code{x} is a CollapsedVCF, \code{value} must be a \code{DNAStringSetList} or \code{CompressedCharacterList}. For ExpandedVCF, \code{value} must be a \code{DNAStringSet} or \code{character}. } \item{\code{qual(x)}, \code{qual(x) <- value}: Returns or sets the quality scores (QUAL). \code{value} must be an \code{numeric(1L)}. } \item{\code{filt(x)}, \code{filt(x) <- value}: Returns or sets the filter data. \code{value} must be a \code{character(1L)}. Names must be one of 'REF', 'ALT', 'QUAL' or 'FILTER'. } } } \item{}{ \code{mcols(x)}, \code{mcols(x) <- value}: These methods behave the same as \code{mcols(rowRanges(x))} and \code{mcols(rowRanges(x)) <- value}. This method does not manage the fixed fields, 'REF', 'ALT', 'QUAL' or 'FILTER'. To modify those columns use \code{fixed<-}. } \item{}{ \code{fixed(x)}, \code{fixed(x) <- value}: Gets or sets a DataFrame of REF, ALT, QUAL and FILTER only. Note these fields are displayed as metadata columns with the rowRanges() data (set to fixed = FALSE to suppress). } \item{}{ \code{info(x, ..., row.names = TRUE)}, \code{info(x) <- value}: Gets or sets a DataFrame of INFO variables. Row names are added if unique and \code{row.names=TRUE}. } \item{}{ \code{geno(x, withDimnames=TRUE)}, \code{geno(x) <- value}: oets a SimpleList of genotype data. \code{value} is a SimpleList. To replace a single variable in the SimpleList use \code{geno(x)$variable <- value}; in this case \code{value} must be a matrix or array. By default row names are returned; to override specify \code{geno(vcf, withDimnames=FALSE)}. } \item{}{ \code{metadata(x)}: Gets a \code{list} of experiment-related data. By default this list includes the \sQuote{header} information from the VCF file. See the use of \code{header()} for details in extracting header information. } \item{}{ \code{colData(x)}, \code{colData(x) <- value}: Gets or sets a \code{DataFrame} of sample-specific information. Each row represents a sample in the VCF file. \code{value} must be a \code{DataFrame} with rownames representing the samples in the VCF file. } \item{}{ \code{genome(x)}: Extract the \code{genome} information from the \code{GRanges} object returned by the \code{rowRanges} accessor. } \item{}{ \code{seqlevels(x)}: Extract the \code{seqlevels} from the \code{GRanges} object returned by the \code{rowRanges} accessor. } \item{}{ \code{strand(x)}: Extract the \code{strand} from the \code{GRanges} object returned by the \code{rowRanges} accessor. } \item{}{ \code{header(x)}, \code{header(x)<- value}: Get or set the VCF header information. Replacement value must be a \code{VCFHeader} object. To modify individual elements use \code{info<-}, \code{geno<-} or \code{meta<-} on a \sQuote{VCFHeader} object. See ?\code{VCFHeader} man page for details. \itemize{ \item{\code{info(header(x))}} \item{\code{geno(header(x))}} \item{\code{meta(header(x))}} \item{\code{samples(header(x))}} } } \item{}{\code{vcfFields(x)} Returns a \code{\link[IRanges]{CharacterList}} of all available VCF fields, with names of \code{fixed}, \code{info}, \code{geno} and \code{samples} indicating the four categories. Each element is a character() vector of available VCF field names within each category. } } } \section{Subsetting and combining}{ In the following code \code{x} is a VCF object, and \dots is a list of VCF objects. \describe{ \item{}{ \code{x[i, j]}, \code{x[i, j] <- value}: Gets or sets rows and columns. \code{i} and \code{j} can be integer or logical vectors. \code{value} is a replacement \code{VCF} object. } \item{}{ \code{subset(x, subset, select, ...)}: Restricts \code{x} by evaluating the \code{subset} argument in the scope of \code{rowData(x)} and \code{info(x)}, and \code{select} in the context of \code{colData(x)}. The \code{subset} argument restricts by rows, while the \code{select} argument restricts by column. The \code{\dots} are passed to the underlying \code{subset()} calls. } \item{}{ \code{cbind(...)}, \code{rbind(...)}: \code{cbind} combines objects with identical ranges (\code{rowRanges}) but different samples (columns in \code{assays}). The colnames in \code{colData} must match or an error is thrown. Columns with duplicate names in \code{fixed}, \code{info} and \code{mcols(rowRanges(VCF))} must contain the same data. \code{rbind} combines objects with different ranges (\code{rowRanges}) and the same subjects (columns in \code{assays}). Columns with duplicate names in \code{colData} must contain the same data. The \sQuote{Samples} columns in \code{colData} (created by \code{readVcf}) are renamed with a numeric extension ordered as they were input to \code{rbind} e.g., \dQuote{Samples.1, Samples.2, ...} etc. \code{metadata} from all objects are combined into a \code{list} with no name checking. } } } \section{expand}{ In the following code snippets \code{x} is a CollapsedVCF object. \describe{ \item{}{ \code{expand(x, ..., row.names = FALSE)}: Expand (unlist) the ALT column of a CollapsedVCF object to one row per ALT value. Variables with Number='A' have one value per alternate allele and are expanded accordingly. The 'AD' genotype field (and any variables with 'Number' set to 'R') is expanded into REF/ALT pairs. For all other fields, the rows are replicated to match the elementNROWS of ALT. The output is an ExpandedVCF with ALT as a \code{DNAStringSet} or \code{character} (structural variants). By default rownames are NULL. When \code{row.names=TRUE} the expanded output has duplicated rownames corresponding to the original \code{x}. } } } \section{genotypeCodesToNucleotides(vcf, ...)}{ This function converts the `GT` genotype codes in a \code{VCF} object to nucleotides. See also ?\code{readGT} to read in only `GT` data as codes or nucleotides. } \section{SnpMatrixToVCF(from, seqSource)}{ This function converts the output from the \link[snpStats]{read.plink} function to a \code{VCF} class. \code{from} must be a list of length 3 with named elements "map", "fam" and "genotypes". \code{seqSource} can be a \code{\link[BSgenome]{BSgenome}} or an \link{FaFile} used for reference sequence extraction. } \section{Variant Type}{ Functions to identify variant type include \link{isSNV}, \link{isInsertion}, \link{isDeletion}, \link{isIndel}, \link{isSubstitution} and \link{isTransition}. See the ?\code{isSNV} man page for details. } \section{Arguments}{ \describe{ \item{geno}{A \code{list} or \code{SimpleList} of matrix elements, or a \code{matrix} containing the genotype information from a VCF file. If present, these data immediately follow the FORMAT field in the VCF. Each element of the list must have the same dimensions, and dimension names (if present) must be consistent across elements and with the row names of \code{rowRanges}, \code{colData}. } \item{info}{A \code{DataFrame} of data from the INFO field of a VCF file. The number of rows must match that in the \code{rowRanges} object. } \item{fixed}{A \code{DataFrame} of REF, ALT, QUAL and FILTER fields from a VCF file. The number of rows must match that of the \code{rowRanges} object. } \item{rowRanges}{A \code{GRanges} instance describing the ranges of interest. Row names, if present, become the row names of the \code{VCF}. The length of the \code{GRanges} must equal the number of rows of the matrices in \code{geno}. } \item{colData}{A \code{DataFrame} describing the samples. Row names, if present, become the column names of the \code{VCF}. } \item{metadata}{A \code{list} describing the header of the VCF file or additional information for the overall experiment. } \item{...}{For \code{cbind} and \code{rbind} a list of VCF objects. For all other methods \dots are additional arguments passed to methods. } \item{collapsed}{A \code{logical(1)} indicating whether a CollapsedVCF or ExpandedVCF should be created. The ALT in a CollapsedVCF is a \code{DNAStringSetList} while in a ExpandedVCF it is a \code{DNAStringSet}. } \item{verbose}{A \code{logical(1)} indicating whether messages about data coercion during construction should be printed. } } } \details{ The \code{VCF} class is a virtual class with two concrete subclasses, \code{CollapsedVCF} and \code{ExtendedVCF}. Slots unique to \code{VCF} and subclasses, \itemize{ \item \code{fixed}: A \link{DataFrame} containing the REF, ALT, QUAL and FILTER fields from a VCF file. \item \code{info}: A \link{DataFrame} containing the INFO fields from a VCF file. } Slots inherited from \code{RangedSummarizedExperiment}, \itemize{ \item \code{metadata}: A \code{list} containing the file header or other information about the overall experiment. \item \code{rowRanges}: A \link{GRanges}-class instance defining the variant ranges and associated metadata columns of REF, ALT, QUAL and FILTER. While the REF, ALT, QUAL and FILTER fields can be displayed as metadata columns they cannot be modified with \code{rowRanges<-}. To modify these fields use \code{fixed<-}. \item \code{colData}: A \link{DataFrame}-class instance describing the samples and associated metadata. \item \code{geno}: The \code{assays} slot from \code{RangedSummarizedExperiment} has been renamed as \code{geno} for the VCF class. This slot contains the genotype information immediately following the FORMAT field in a VCF file. Each element of the \code{list} or \code{SimpleList} is a matrix or array. } It is expected that users will not create instances of the VCF class but instead one of the concrete subclasses, CollapsedVCF or ExpandVCF. CollapsedVCF contains the ALT data as a \code{DNAStringSetList} allowing for multiple alleles per variant. The ExpandedVCF ALT data is a \code{DNAStringSet} where the ALT column has been expanded to create a flat form of the data with one row per variant-allele combination. In the case of strucutral variants, ALT will be a \code{CompressedCharacterList} or \code{character} in the collapsed or expanded forms. } \author{Valerie Obenchain} \seealso{ \link{GRanges}, \link[S4Vectors]{DataFrame}, \link[S4Vectors]{SimpleList}, \link[SummarizedExperiment]{RangedSummarizedExperiment}, \code{\link{readVcf}}, \code{\link{writeVcf}} \code{\link{isSNV}} } \examples{ ## readVcf() parses data into a VCF object: fl <- system.file("extdata", "structural.vcf", package="VariantAnnotation") vcf <- readVcf(fl, genome="hg19") ## ---------------------------------------------------------------- ## Accessors ## ---------------------------------------------------------------- ## Variant locations are stored in the GRanges object returned by ## the rowRanges() accessor. rowRanges(vcf) ## Suppress fixed fields: rowRanges(vcf, fixed=FALSE) ## Individual fields can be extracted with ref(), alt(), qual(), filt() etc. qual(vcf) ref(vcf) head(info(vcf)) ## All available VCF field names can be contracted with vcfFields(). vcfFields(vcf) ## Extract genotype fields with geno(). Access specific fields with ## '$' or '[['. geno(vcf) identical(geno(vcf)$GQ, geno(vcf)[[2]]) ## ---------------------------------------------------------------- ## Renaming seqlevels and subsetting ## ---------------------------------------------------------------- ## Overlap and matching operations require that the objects ## being compared have the same seqlevels (chromosome names). ## It is often the case that the seqlevesls in on of the objects ## needs to be modified to match the other. In this VCF, the ## seqlevels are numbers instead of preceded by "chr" or "ch". seqlevels(vcf) ## Rename the seqlevels to start with 'chr'. vcf2 <- renameSeqlevels(vcf, paste0("chr", seqlevels(vcf))) seqlevels(vcf2) ## The VCF can also be subset by seqlevel using 'keepSeqlevels' ## or 'dropSeqlevels'. See ?keepSeqlevels for details. vcf3 <- keepSeqlevels(vcf2, "chr2", pruning.mode="coarse") seqlevels(vcf3) ## ---------------------------------------------------------------- ## Header information ## ---------------------------------------------------------------- ## Header data can be modified in the 'meta', 'info' and 'geno' ## slots of the VCFHeader object. See ?VCFHeader for details. ## Current 'info' fields. rownames(info(header(vcf))) ## Add a new field to the header. newInfo <- DataFrame(Number=1, Type="Integer", Description="Number of Samples With Data", row.names="NS") info(header(vcf)) <- rbind(info(header(vcf)), newInfo) rownames(info(header(vcf))) ## ---------------------------------------------------------------- ## Collapsed and Expanded VCF ## ---------------------------------------------------------------- ## readVCF() produces a CollapsedVCF object. fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") vcf <- readVcf(fl, genome="hg19") vcf ## The ALT column is a DNAStringSetList to allow for more ## than one alternate allele per variant. alt(vcf) ## For structural variants ALT is a CharacterList. fl <- system.file("extdata", "structural.vcf", package="VariantAnnotation") vcf <- readVcf(fl, genome="hg19") alt(vcf) ## ExpandedVCF is the 'flattened' counterpart of CollapsedVCF. ## The ALT and all variables with Number='A' in the header are ## expanded to one row per alternate allele. vcfLong <- expand(vcf) alt(vcfLong) ## Also see the ?VRanges class for an alternative form of ## 'flattened' VCF data. ## ---------------------------------------------------------------- ## isSNV() ## ---------------------------------------------------------------- ## isSNV() returns a subset VCF containing SNVs only. vcf <- VCF(rowRanges = GRanges("chr1", IRanges(1:4*3, width=c(1, 2, 1, 1)))) alt(vcf) <- DNAStringSetList("A", c("TT"), c("G", "A"), c("TT", "C")) ref(vcf) <- DNAStringSet(c("G", c("AA"), "T", "G")) fixed(vcf)[c("REF", "ALT")] ## SNVs are present in rows 1 (single ALT value), 3 (both ALT values) ## and 4 (1 of the 2 ALT values). vcf[isSNV(vcf, singleAltOnly=TRUE)] vcf[isSNV(vcf, singleAltOnly=FALSE)] ## all 3 SNVs } VariantAnnotation/man/VcfFile-class.Rd0000644000175100017510000001022614614305321020714 0ustar00biocbuildbiocbuild\name{VcfFile} \Rdversion{1.1} \docType{class} \alias{VcfFile-class} \alias{VcfFileList-class} % con/destructors \alias{VcfFile} \alias{VcfFileList} \alias{vcfFields,missing-method} \alias{vcfFields,character-method} \alias{vcfFields,VcfFile-method} \alias{vcfFields,VcfFileList-method} \title{Manipulate Variant Call Format (Vcf) files.} \description{ Use \code{VcfFile()} to create a reference to a Vcf file (and its index). Once opened, the reference remains open across calls to methods, avoiding costly index re-loading. \code{VcfFileList()} provides a convenient way of managing a list of \code{VcfFile} instances. } \section{usage}{ ## Constructors \describe{ \item{}{ VcfFile(file, index = paste(file, "tbi", sep="."), ..., yieldSize=NA_integer_) } \item{}{ VcfFileList(..., yieldSize=NA_integer_) } } ## Accessors \describe{ \item{}{ index(object)} \item{}{ path(object, ...)} \item{}{ isOpen(con, rw="")} \item{}{ yieldSize(object, ...)} \item{}{ yieldSize(object, ...) <- value} \item{}{ show(object) } } ## Opening / closing \describe{ \item{}{ open(con, ...)} \item{}{ close(con, ...)} } ## method \describe{ \item{}{ vcfFields(object) } } } \section{arguments}{ \itemize{ \item{con}{An instance of \code{VcfFile}.} \item{file}{A character(1) vector to the Vcf file path; can be remote (http://, ftp://).} \item{index}{A character(1) vector of the Vcf file index (.tbi file).} \item{yieldSize}{Number of records to yield each time the file is read from using \code{scanVcf} or \code{readVcf}.} \item{...}{Additional arguments. For \code{VcfFileList}, this can either be a single character vector of paths to Vcf files, or several instances of \code{VcfFile} objects.} \item{rw}{character() indicating mode of file.} } } \section{Objects from the Class}{ Objects are created by calls of the form \code{VcfFile()}. } \section{Fields}{ \code{VcfFile} and \code{VcfFileList} classes inherit fields from the \code{\linkS4class{TabixFile}} and \code{\linkS4class{TabixFileList}} classes. } \section{Functions and methods}{ \code{VcfFile} and \code{VcfFileList} classes inherit methods from the \code{\linkS4class{TabixFile}} and \code{\linkS4class{TabixFileList}} classes. ## Opening / closing: \describe{ \item{open}{Opens the (local or remote) \code{path} and \code{index}. Returns a \code{VcfFile} instance. \code{yieldSize} determines the number of records parsed during each call to \code{scanVcf} or \code{readVcf}; \code{NA} indicates that all records are to be parsed.} \item{close}{Closes the \code{VcfFile} \code{con}; returning (invisibly) the updated \code{VcfFile}. The instance may be re-opened with \code{open.VcfFile}.} } ## Accessors: \describe{ \item{path}{Returns a character(1) vector of the Vcf path name.} \item{index}{Returns a character(1) vector of Vcf index (tabix file) name.} \item{yieldSize, yieldSize<-}{Return or set an integer(1) vector indicating yield size.} } ## Methods: \describe{ \item{vcfFields}{ Returns a \code{\link[IRanges]{CharacterList}} of all available VCF fields, with names of \code{fixed}, \code{info}, \code{geno} and \code{samples} indicating the four categories. Each element is a character() vector of available VCF field names within each category. It works for both local and remote vcf file. } } } \author{Valerie Obenchain} \examples{ fl <- system.file("extdata", "chr7-sub.vcf.gz", package="VariantAnnotation", mustWork=TRUE) vcffile <- VcfFile(fl) vcffile vcfFields(fl) vcfFields(vcffile) param <- GRanges("7", IRanges(c(55000000, 55900000), width=10000)) vcf <- readVcf(vcffile, "hg19", param=param) dim(vcf) ## `vcfFields` also works for remote vcf filepath. \dontrun{ chr22url <- "ftp://ftp.1000genomes.ebi.ac.uk/vol1/ftp/release/20130502/ALL.chr22.phase3_shapeit2_mvncall_integrated_v5a.20130502.genotypes.vcf.gz" vcfFields(chr22url) } } \keyword{classes} VariantAnnotation/man/VCFHeader-class.Rd0000644000175100017510000001153614614305321021132 0ustar00biocbuildbiocbuild\name{VCFHeader-class} \docType{class} % Class \alias{VCFHeader-class} % Constructor-like function: \alias{VCFHeader} % Accessor methods: \alias{reference} \alias{reference,VCFHeader-method} \alias{samples} \alias{samples,VCFHeader-method} \alias{header} \alias{header,VCFHeader-method} \alias{contig} \alias{contig,VCFHeader-method} \alias{meta} \alias{meta,VCFHeader-method} \alias{meta<-} \alias{meta<-,VCFHeader,DataFrame-method} \alias{meta<-,VCFHeader,DataFrameList-method} \alias{fixed,VCFHeader-method} \alias{fixed<-,VCFHeader,DataFrameList-method} \alias{info,VCFHeader-method} \alias{info<-,VCFHeader,DataFrame-method} \alias{geno,VCFHeader-method} \alias{geno<-,VCFHeader,missing,DataFrame-method} \alias{seqinfo,VCFHeader-method} \alias{vcfFields} \alias{vcfFields,VCFHeader-method} % show method: \alias{show,VCFHeader-method} \title{VCFHeader instances} \description{ The \code{VCFHeader} class holds Variant Call Format (VCF) file header information and is produced from a call to \code{scanVcfHeader}. } \section{Constructor}{ \describe{ \item{}{ \code{VCFHeader(reference = character(), samples = character(), header = DataFrameList(), ...) } } } } \section{Accessors}{ In the following code snippets \code{x} is a VCFHeader object. \describe{ \item{}{ \code{samples(x)}: Returns a character() vector of names of samples. } \item{}{ \code{header(x)}: Returns all information in the header slot which includes \code{meta}, \code{info} and \code{geno} if present. } \item{}{ \code{meta(x)}, \code{meta(x)<- value}: The getter returns a \code{DataFrameList}. Each \code{DataFrame} represents a unique "key" name in the header file. Multiple header lines with the same "key" are parsed into the same \code{DataFrame} with the "ID" field as the row names. Simple header lines have no "ID" field in which case the "key" is used as the row name. NOTE: In VariantAnnotation <= 1.27.5, the \code{meta()} extractor returned a \code{DataFrame} called "META" which held all simple key-value header lines. The VCF 4.3 specs allowed headers lines with key name "META" which caused a name clash with the pre-existing "META" \code{DataFrame}. In \code{VariantAnnotation} >=1.27.6 the "META" \code{DataFrame} was split and each row became its own separate \code{DataFrame}. Calling \code{meta()} on a \code{VCFHeader} object now returns a list of \code{DataFrames}, one for each unique key name in the header. } \item{}{ \code{fixed(x), fixed(x)<- value}: Returns a \code{DataFrameList} of information pertaining to any of \sQuote{REF}, \sQuote{ALT}, \sQuote{FILTER} and \sQuote{QUAL}. Replacement value must be a \code{DataFrameList} with one or more of the following names, \sQuote{QUAL}, \sQuote{FILTER}, \sQuote{REF} and \sQuote{ALT}. } \item{}{ \code{info(x)}, \code{info(x)<- value}: Gets or sets a \code{DataFrame} of \sQuote{INFO} information. Replacement value must be a \code{DataFrame} with 3 columns named \sQuote{Number}, \sQuote{Type} and \sQuote{Description}. } \item{}{ \code{geno(x)}, \code{geno(x)<- value}: Returns a \code{DataFrame} of \sQuote{FORMAT} information. Replacement value must be a \code{DataFrame} with 3 columns named \sQuote{Number}, \sQuote{Type} and \sQuote{Description}. } \item{}{ \code{reference(x)}: Returns a character() vector with names of reference sequences. Not relevant for \code{scanVcfHeader}. } \item{}{ \code{vcfFields(x)}: Returns a \code{\link[IRanges]{CharacterList}} of all available VCF fields, with names of \code{fixed}, \code{info}, \code{geno} and \code{samples} indicating the four categories. Each element is a character() vector of available VCF field names within each category. } } } \section{Arguments}{ \describe{ \item{reference}{A character() vector of sequences. } \item{sample}{A character() vector of sample names. } \item{header}{A \code{DataFrameList} of parsed header lines (preceeded by \dQuote{##}) present in the VCF file. } \item{...}{Additional arguments passed to methods. } } } \details{ The \code{VCFHeader} class holds header information from a VCF file. Slots : \describe{ \item{\code{reference}}{character() vector } \item{\code{sample}}{character() vector } \item{\code{header}}{\link{DataFrameList}-class } } } \author{Valerie Obenchain} \seealso{ \code{\link{scanVcfHeader}}, \code{\link{DataFrameList}} } \examples{ fl <- system.file("extdata", "structural.vcf", package="VariantAnnotation") hdr <- scanVcfHeader(fl) fixed(hdr) info(hdr) geno(hdr) vcfFields(hdr) } VariantAnnotation/man/vep_by_region.Rd0000644000175100017510000000220314614305321021116 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/use_vep_api.R \name{vep_by_region} \alias{vep_by_region} \title{Use the VEP region API on variant information in a VCF object as defined in VariantAnnotation.} \usage{ vep_by_region(vcfobj, snv_only = TRUE, chk_max = TRUE) } \arguments{ \item{vcfobj}{instance of VCF class; note the difference between the CollapsedVCF and ExpandedVCF instances.} \item{snv_only}{logical(1) if TRUE filter the VCF to information about single nucleotide addresses} \item{chk_max}{logical(1) requests to ensembl VEP API are limited to 200 positions; if TRUE and the request involves more than 200 positions, an error is thrown by this function.} } \value{ instance of 'response' from httr package } \description{ Use the VEP region API on variant information in a VCF object as defined in VariantAnnotation. } \examples{ fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") r22 = readVcf(fl) dr = which(width(rowRanges(r22))!=1) r22s = r22[-dr] res = vep_by_region(r22[1:100], snv_only=FALSE, chk_max=FALSE) ans = jsonlite::fromJSON(jsonlite::toJSON(httr::content(res))) } VariantAnnotation/man/VRanges-class.Rd0000644000175100017510000003673214614305321020755 0ustar00biocbuildbiocbuild\name{VRanges-class} \docType{class} % Class: \alias{class:VRanges} \alias{VRanges-class} \alias{VRanges} % Constructors: \alias{VRanges} \alias{makeVRangesFromGRanges} % Coercion: \alias{asVCF} \alias{asVCF,VRanges-method} \alias{coerce,VRanges,VCF-method} \alias{coerce,VCF,VRanges-method} \alias{coerce,GRanges,VRanges-method} % Accessors: \alias{alt,VRanges-method} \alias{alt<-,VRanges,ANY-method} \alias{ref,VRanges-method} \alias{ref<-,VRanges,ANY-method} \alias{altDepth} \alias{altDepth,VRanges-method} \alias{altDepth<-} \alias{altDepth<-,VRanges-method} \alias{refDepth} \alias{refDepth,VRanges-method} \alias{refDepth<-} \alias{refDepth<-,VRanges-method} \alias{totalDepth} \alias{totalDepth,VRanges-method} \alias{totalDepth<-} \alias{totalDepth<-,VRanges-method} \alias{altFraction} \alias{altFraction,VRanges-method} \alias{called} \alias{called,VRanges-method} \alias{hardFilters<-} \alias{hardFilters<-,VRanges-method} \alias{hardFilters} \alias{hardFilters,VRanges-method} \alias{sampleNames,VRanges-method} \alias{sampleNames<-,VRanges,ANY-method} \alias{softFilterMatrix} \alias{softFilterMatrix,VRanges-method} \alias{softFilterMatrix<-} \alias{softFilterMatrix<-,VRanges-method} \alias{resetFilter} % Aggregation: \alias{tabulate} \alias{tabulate,VRanges-method} % VCF reading/writing: \alias{writeVcf,VRanges,ANY-method} \alias{readVcfAsVRanges} % Utilities: \alias{match,VRanges,VRanges-method} \alias{softFilter} % Typed Rle classes (at least for now) \alias{characterRle-class} \alias{characterOrRle-class} \alias{complexRle-class} \alias{factorRle-class} \alias{factorOrRle-class} \alias{integerRle-class} \alias{integerOrRle-class} \alias{logicalRle-class} \alias{numericRle-class} \alias{rawRle-class} \title{VRanges objects} \description{ The VRanges class is a container for variant calls, including SNVs and indels. It extends \code{\link[GenomicRanges]{GRanges}} to provide special semantics on top of a simple vector of genomic locations. While it is not as expressive as the \code{\linkS4class{VCF}} object, it is a simpler alternative that may be convenient for variant calling/filtering and similar exercises. } \details{ VRanges extends GRanges to store the following components. Except where noted, the components are considered columns in the dataset, i.e., their lengths match the number of variants. Many columns can be stored as either an atomic vector or an Rle. \describe{ \item{\code{ref}}{(\code{character}), the reference allele. The range (start/end/width) should always correspond to this sequence.} \item{\code{alt}}{(\code{character/Rle}), the alternative allele (NA allowed). By convention there is only a single alt allele per element (row) of the VRanges. Many methods, like \code{match}, make this assumption. } \item{\code{refCount}}{(\code{integer/Rle}), read count for the reference allele (NA allowed)} \item{\code{altCount}}{(\code{integer/Rle}), read count for the alternative allele (NA allowed)} \item{\code{totalCount}}{(\code{integer/Rle}), total read count at the position, must be at least \code{refCount+altCount} (NA allowed)} \item{\code{sampleNames}}{(\code{factor/Rle}), name of the sample - results from multiple samplse can be combined into the same object (NA allowed)} \item{\code{softFilterMatrix}}{(\code{matrix/FilterMatrix}), variant by filter matrix, \code{TRUE} where variant passed the filter; use a \code{\link[S4Vectors]{FilterMatrix}} to store the actual \code{FilterRules} object that was applied} \item{\code{hardFilters}}{(\code{FilterRules}) record of hard filters applied, i.e., only the variants that passed the filters are present in this object; this is the only component that is not a column, i.e., its length does not match the number of variants} } Except in the special circumstances described here, a \code{VRanges} may be treated like a \code{GRanges}. The range should span the sequence in \code{ref}. Indels are typically represented by the VCF convention, i.e., the start position is one upstream of the event. The strand is always constrained to be positive (+). Indels, by convention, should be encoded VCF-style, with the upstream reference base prepended to the indel sequence. The ref/alt for a deletion of GCGT before A might be AGCGT/A and for an insertion might be A/AGCGT. Since the range always matches the \code{ref} sequence, this means a deletion will be the width of the deletion + 1, and an insertion is always of width 1. VRanges and the VCF class: The VRanges and VCF classes encode different types of information and are semantically incompatible. While methods exist for converting a VCF object to a VRanges and vice versa, information is lost in the transformation. There is no way to collapse multiple rows of a VRanges at the same genomic position and accurately represent missing data. For this reason, it is not reasonable to assume that an object resulting from multiple conversions (VRanges -> VCF -> VRanges) will be equivalent to the original. } \section{Constructors}{ \describe{ \item{}{ \code{VRanges(seqnames = Rle(), ranges = IRanges(), ref = character(), alt = NA_character_, totalDepth = NA_integer_, refDepth = NA_integer_, altDepth = NA_integer_, ..., sampleNames = NA_character_, softFilterMatrix = FilterMatrix(matrix(nrow = length(gr), ncol = 0L), FilterRules()), hardFilters = FilterRules())}: Creates a VRanges object. \describe{ \item{\code{seqnames}}{Rle object, character vector, or factor containing the sequence names.} \item{\code{ranges}}{IRanges object containing the ranges.} \item{\code{ref}}{character vector, containing the reference allele.} \item{\code{alt}}{character vector/Rle, containing the alternative allele (NA allowed).} \item{\code{totalDepth}}{integer vector/Rle, containing the total read depth (NA allowed).} \item{\code{refDepth}}{integer vector/Rle, containing the reference read depth (NA allowed).} \item{\code{altDepth}}{integer vector/Rle, containing the reference read depth (NA allowed).} \item{\code{\ldots}}{Arguments passed to the \code{GRanges} constructor.} \item{\code{sampleNames}}{character/factor vector/Rle, containing the sample names (NA allowed).} \item{\code{softFilterMatrix}}{a matrix (typically a \code{\link[S4Vectors]{FilterMatrix}}) of dimension variant by filter, with logical values indicating whether a variant passed the filter.} \item{\code{hardFilters}}{a \code{\link[S4Vectors]{FilterRules}}, containing the filters that have already been applied to subset the object to its current state.} } } \item{}{ \code{makeVRangesFromGRanges(gr, ref.field="ref", alt.field="alt", totalDepth.field="totalDepth", refDepth.field="refDepth", altDepth.field="altDepth", sampleNames.field="sampleNames", keep.extra.columns=TRUE)}: Creates a VRanges object from a GRanges. \describe{ \item{\code{gr}}{ A \link[GenomicRanges]{GenomicRanges} object. } \item{\code{ref.field}}{ The \code{character(1)} name of the GRanges metadata column to be used as the VRanges \code{ref} field. } \item{\code{alt.field}}{ The \code{character(1)} name of the GRanges metadata column to be used as the VRanges \code{alt} field. } \item{\code{totalDepth.field}}{ The \code{character(1)} name of the GRanges metadata column to be used as the VRanges \code{totalDepth} field. } \item{\code{refDepth.field}}{ The \code{character(1)} name of the GRanges metadata column to be used as the VRanges \code{refDepth} field. } \item{\code{altDepth.field}}{ The \code{character(1)} name of the GRanges metadata column to be used as the VRanges \code{altDepth} field. } \item{\code{sampleNames.field}}{ The \code{character(1)} name of the GRanges metadata column to be used as the VRanges \code{sampleNames} field. } \item{\code{keep.extra.columns}}{ \code{TRUE} (the default) or \code{FALSE}. If \code{TRUE}, then the columns in \code{gr} that are not used to form the VRanges are retained as metadata columns. Otherwise, they will be ignored. } } } } } \section{Coercion}{ These functions/methods coerce objects to and from \code{VRanges}: \describe{ \item{}{ \code{asVCF(x, info = character(), filter = character(), meta = character())}: Creates a VCF object from a VRanges object. The following gives the mapping from VRanges components to VCF: \describe{ \item{seqnames(x)}{CHROM column} \item{start(x)}{POS column} \item{names(x)}{ID column} \item{ref(x)}{REF column} \item{alt(x)}{ALT column} \item{totalDepth(x)}{DP in FORMAT column} \item{altDepth(x), refDepth(x)}{AD in FORMAT column} \item{sampleNames(x)}{Names the sample columns} \item{softFilterMatrix(x)}{FT in FORMAT column, except filters named in \code{filter} argument, which are considered per-position and placed in the FILTER column} \item{hardFilters(x)}{Not yet exported} \item{mcols(x)}{Become fields in the FORMAT column; unless they are named in the \code{info} argument, in which case they are considered per-position and placed in the INFO column} \item{metadata(x)}{If named in the \code{meta} argument, output in the VCF header; a component is required to be coercible to a character vector of length one.} } Note that \code{identical(x, as(as(x, "VCF"), "VRanges"))} generally return \code{FALSE}. During coercion to VCF, the "geno" components are reshaped into matrix form, with NAs filling the empty cells. The reverse coercion will not drop the NA values, so rows are added to the new VRanges. All logical values will become integers in VCF, and there is no automatic way of regenerating the logical column with the reverse coercion. There are many other cases of irreversibility. } \item{}{ \code{as(from, "VCF")}: Like calling \code{asVCF(from)}. } \item{}{ \code{as(from, "VRanges")}: When \code{from} is a \code{VCF} this coercion is essentially the inverse of \code{asVCF}. Information missing in the VCF is imputed as NA. When \code{from} is a \code{GRanges}, metadata columns of \code{ref}, \code{alt}, \code{refDepth}, \code{altDepth}, \code{totalDepth} and \code{sampleNames} are transfered to the \code{VRanges} object. Additional metadata columns in the \code{GRanges} can be retained or dropped with \code{keep.extra.columns}. See also \code{makeVRangesFromGRanges}. } } } \section{Accessors}{ In addition to all of the \code{GRanges} accessors, \code{VRanges} provides the following, where \code{x} is a VRanges object. \describe{ \item{}{ \code{alt(x), alt(x) <- value}: Get or set the alt allele (character). } \item{}{ \code{ref(x), ref(x) <- value}: Get or set the ref allele (character). } \item{}{ \code{altDepth(x), altDepth(x) <- value}: Get or set the alt allele read depth (integer). } \item{}{ \code{refDepth(x), refDepth(x) <- value}: Get or set the ref allele read depth (integer). } \item{}{ \code{totalDepth(x), totalDepth(x) <- value}: Get or set the total read depth (integer). } \item{}{ \code{altFraction(x)}: Returns \code{altDepth(x)/totalDepth(x)} (numeric). } \item{}{ \code{sampleNames(x), sampleNames(x) <- value}: Get or set the sample names (character/factor). } \item{}{ \code{softFilterMatrix(x), softFilterMatrix(x) <- value}: Gets or sets the soft filter matrix (any matrix, but ideally a \code{FilterMatrix}). } \item{}{ \code{resetFilter(x)}: Removes all columns from \code{softFilterMatrix}. } \item{}{ \code{called(x)}: Returns whether all filter results in \code{softFilterMatrix(x)} are \code{TRUE} for each variant. } \item{}{ \code{hardFilters(x), hardFilters(x) <- value}: Gets or sets the hard filters (those applied to yield the current subset). } } } \section{Utilities and Conveniences}{ \describe{ \item{}{ \code{match(x)}: Like GRanges \code{match}, except matches on the combination of chromosome, start, width, and \strong{alt}. } \item{}{ \code{tabulate(bin)}: Finds \code{unique(bin)} and counts how many times each unique element occurs in \code{bin}. The result is stored in \code{mcols(bin)$sample.count}. } \item{}{ \code{softFilter(x, filters, ...)}: applies the \code{FilterRules} in \code{filters} to \code{x}, storing the results in \code{softFilterMatrix}. } } } \section{Input/Output to/from VCF}{ \describe{ \item{}{ \code{writeVcf(obj, filename, ...)}: coerces to a VCF object and writes it to a file; see \code{\link{writeVcf}}. } \item{}{ \code{readVcfAsVRanges(x, genome, param = ScanVcfParam(), ...)}: Reads a VCF \code{x} directly into a \code{VRanges}; see \code{\link{readVcf}} for details on the arguments. \code{readVcfAsVRanges} is an alternative syntax to \preformatted{ as(readVcf(), "VRanges") } NOTE: By default all INFO and FORMAT fields are read in with \code{ScanVcfParam()}. The minimal information needed to create the \code{VRanges} can be specified as follows: \preformatted{ ScanVcfParam(fixed = "ALT", info = NA, geno = "AD")) } } } } \section{Variant Type}{ Functions to identify variant type include \link{isSNV}, \link{isInsertion}, \link{isDeletion}, \link{isIndel}, \link{isSubstitution} and \link{isTransition}. See the ?\code{isSNV} man page for details. } \author{Michael Lawrence. \code{makeVRangesFromGRanges} was contributed by Thomas Sandmann.} \seealso{ \link{VRangesList}, a list of \code{VRanges}; \code{bam_tally} in the gmapR package, which generates a \code{VRanges}. } \examples{ ## construction vr <- VRanges(seqnames = c("chr1", "chr2"), ranges = IRanges(c(1, 10), c(5, 20)), ref = c("T", "A"), alt = c("C", "T"), refDepth = c(5, 10), altDepth = c(7, 6), totalDepth = c(12, 17), sampleNames = letters[1:2], hardFilters = FilterRules(list(coverage = function(x) totalDepth > 10)), softFilterMatrix = FilterMatrix(matrix = cbind(depth = c(TRUE, FALSE)), FilterRules(depth = function(x) altDepth(x) > 6)), tumorSpecific = c(FALSE, TRUE)) ## simple accessors ref(vr) alt(vr) altDepth(vr) vr$tumorSpecific called(vr) ## coerce to VCF and write vcf <- as(vr, "VCF") ## writeVcf(vcf, "example.vcf") ## or just ## writeVcf(vr, "example.vcf") ## other utilities match(vr, vr[2:1]) } VariantAnnotation/man/VRangesList-class.Rd0000644000175100017510000000315314614305321021600 0ustar00biocbuildbiocbuild\name{VRangesList-class} \docType{class} % Class: \alias{class:VRangesList} \alias{VRangesList-class} \alias{CompressedVRangesList-class} \alias{class:CompressedVRangesList} \alias{SimpleVRangesList-class} \alias{class:SimpleVRangesList} % Constructors: \alias{VRangesList} % Accessors: \alias{alt,VRangesList-method} \alias{ref,VRangesList-method} % Aggregation: \alias{stackSamples} \alias{stackSamples,VRangesList-method} \title{VRangesList objects} \description{ VRangesList is a virtual class representing a list of \code{\linkS4class{VRanges}} objects and should behave much like any other derivative of \code{List}. It has both a simple and compressed implementation. VRangesList provides conveniences for manipulating sets of \code{VRanges} objects. } \section{Constructor}{ \describe{ \item{}{ \code{VRangesList(...)}: Creates a VRangesList object from \code{VRanges} objects in \dots. } } } \section{Accessors}{ \describe{ \item{}{ \code{alt(x)}: Returns a CharacterList or RleList, effectively by calling \code{alt(x[[i]])} on each element of \code{x}. } \item{}{ \code{ref(x)}: Returns a CharacterList, effectively by calling \code{ref(x[[i]])} on each element of \code{x}. } } } \section{Utilities}{ \describe{ \item{}{ \code{stackSamples(x)}: Concentrates the elements in \code{x}, using \code{names(x)} to appropriately fill \code{sampleNames} in the result. } } } \author{Michael Lawrence} \examples{ ## construction example(VRanges) vrl <- VRangesList(sampleA = vr, sampleB = vr) stackSamples(vrl) } VariantAnnotation/man/writeVcf-methods.Rd0000644000175100017510000000762214614305321021533 0ustar00biocbuildbiocbuild\name{writeVcf} \alias{writeVcf} \alias{writeVcf,VCF,character-method} \alias{writeVcf,VCF,connection-method} \title{Write VCF files} \description{Write Variant Call Format (VCF) files to disk} \usage{ \S4method{writeVcf}{VCF,character}(obj, filename, index = FALSE, ...) \S4method{writeVcf}{VCF,connection}(obj, filename, index = FALSE, ...) } \arguments{ \item{obj}{Object containing data to be written out. At present only accepts \linkS4class{VCF}. } \item{filename}{The character() name of the VCF file, or a connection (e.g., \code{\link{file}()}), to be written out. A connection opened with \code{open = "a"} will have header information written only if the file does not already exist.} \item{index}{Whether to bgzip the output file and generate a tabix index. } \item{\dots}{Additional arguments, passed to methods. \itemize{ \item{nchunk:} Integer or NA. When provided this argument overrides the default chunking behavior of \code{writeVcf}, see Details section. An integer value specifies the number of records in each chunk; NA disables chunking. } } } \note{ NOTE: \code{VariantAnnotation} >= 1.27.6 supports VCFv4.3. See the NOTE on the \code{?VCFHeader} man page under the \code{meta()} extractor for a description of how header parsing has changed to accommodate the new header lines with key name of 'META'. } \details{ A VCF file can be written out from data in a \code{VCF} object. More general methods to write out from other objects may be added in the future. \code{writeVcf} writes out the header fields in a \code{VCF} object 'as-is' with the exception of these key-value pairs: \itemize{ \item fileformat: When missing, a line is added at the top of the file with the current supported version. \code{VariantAnnotation} >=1.27.6 supports VCFv4.3. \item fileDate: When missing, a line is added with today's date. If the key-value pair exists, the date is overwritten with today's date. \item contig: When missing, \code{VariantAnnotation} attempts to use the \code{Seqinfo} of the \code{VCF} object to determine the contig information. } Large VCF files (i.e., > 1e5 records) are written out in chunks; VCF files with < 1e5 records are not chunked. The optimal number of records per chunk depends on both the number of records and complexity of the data. Currently \code{writeVcf} determines records per chunk based on the total number of records only. To override this behavior or experiment with other values use \code{nchunk} as an integer or NA. An integer value represents the number of records per chunk regardless of the size of the VCF; NA disables all chunking. \itemize{ \item writeVcf(vcf, tempfile()) ## default chunking \item writeVcf(vcf, tempfile(), nchunk = 1e6) ## chunk by 1e6 \item writeVcf(vcf, tempfile(), nchunk = NA) ## no chunking } } \value{VCF file } \references{ \url{http://vcftools.sourceforge.net/specs.html} outlines the VCF specification. \url{http://samtools.sourceforge.net/mpileup.shtml} contains information on the portion of the specification implemented by \code{bcftools}. \url{http://samtools.sourceforge.net/} provides information on \code{samtools}. } \author{Valerie Obenchain and Michael Lawrence} \seealso{ \code{\link{readVcf}} } \examples{ fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") out1.vcf <- tempfile() out2.vcf <- tempfile() in1 <- readVcf(fl, "hg19") writeVcf(in1, out1.vcf) in2 <- readVcf(out1.vcf, "hg19") writeVcf(in2, out2.vcf) in3 <- readVcf(out2.vcf, "hg19") stopifnot(all(in2 == in3)) ## write incrementally out3.vcf <- tempfile() con <- file(out3.vcf, open="a") writeVcf(in1[1:2,], con) writeVcf(in1[-(1:2),], con) close(con) readVcf(out3.vcf, "hg19") } \keyword{manip} VariantAnnotation/NAMESPACE0000644000175100017510000000653314614305321016456 0ustar00biocbuildbiocbuilduseDynLib(VariantAnnotation, .registration=TRUE) import(methods) importFrom(utils, packageVersion) importFrom(stats, pchisq, setNames) import(BiocGenerics) importFrom(MatrixGenerics, rowRanges) import(S4Vectors) import(IRanges) import(GenomeInfoDb) import(GenomicRanges) import(SummarizedExperiment) import(Rsamtools) import(zlibbioc) importClassesFrom(Biobase, AssayData ) importFrom(Biobase, sampleNames, "sampleNames<-", samples ) importClassesFrom(AnnotationDbi, AnnotationDb ) importMethodsFrom(AnnotationDbi, colnames, exists, ncol, nrow, columns, keys, keytypes, select ) importFrom(GenomicFeatures, extractTranscriptSeqs, mapToTranscripts, transcriptsBy, intronsByTranscript ) importClassesFrom(GenomicFeatures, TxDb ) importMethodsFrom(GenomicFeatures, cdsBy, exons, transcripts, fiveUTRsByTranscript, threeUTRsByTranscript, distance, mapToTranscripts ) importFrom(XVector, "subseq", "subseq<-") importFrom(Biostrings, AAStringSet, DNAStringSet, DNAStringSetList, DNA_BASES, getSeq, GENETIC_CODE ) importMethodsFrom(Biostrings, nchar, reverseComplement, substr, translate ) importClassesFrom(Biostrings, DNAStringSet, DNAStringSetList ) importMethodsFrom(DBI, dbCommit, dbConnect, dbDisconnect, dbExistsTable, dbGetQuery, dbReadTable, dbWriteTable, dbListTables, dbListFields ) importClassesFrom(BSgenome, BSgenome ) importFrom(rtracklayer, liftOver, import ) importFrom(utils, txtProgressBar, setTxtProgressBar ) exportClassPattern("^.*$") export( VCF, VCFHeader, reference, header, "header<-", meta, "meta<-", vcfWhich, "vcfWhich<-", vcfFixed, "vcfFixed<-", vcfInfo, "vcfInfo<-", vcfGeno, "vcfGeno<-", vcfSamples, "vcfSamples<-", vcfTrimEmpty, "vcfTrimEmpty<-", duplicateRSID, CodingVariants, IntronVariants, FiveUTRVariants, ThreeUTRVariants, IntergenicVariants, SpliceSiteVariants, PromoterVariants, AllVariants, upstream, "upstream<-", downstream, "downstream<-", idType, "idType<-", promoter, "promoter<-", intergenic, "intergenic<-", probabilityToSnpMatrix, GLtoGP, PLtoGP, VRanges, VRangesList, asVCF, softFilter, resetFilter, totalDepth, altDepth, refDepth, sampleNames, "sampleNames<-", altFraction, softFilterMatrix, "softFilterMatrix<-", hardFilters, "hardFilters<-", called, stackSamples, "altDepth<-", "refDepth<-", "totalDepth<-", probabilityToSnpMatrix, GLtoGP, readInfo, readGeno, readGT, genotypeCodesToNucleotides, tabulate, VRangesScanVcfParam, readVcfAsVRanges, isSNV, isInsertion, isDeletion, isIndel, isDelins, isTransition, isSubstitution, VcfFile, VcfFileList, makeVRangesFromGRanges, post_Hs_region, vep_by_region ) exportMethods( filterVcf, scanVcf, scanVcfHeader, ScanVcfParam, readVcf, writeVcf, expand, predictCoding, getTranscriptSeqs, getSeq, genotypeToSnpMatrix, snpSummary, locateVariants, summarizeVariants, isSNV, isInsertion, isDeletion, isIndel, isDelins, isTransition, isSubstitution, updateObject, fixed, "fixed<-", ref, "ref<-", alt, "alt<-", qual, "qual<-", filt, "filt<-", info, "info<-", geno, "geno<-", strand, "strand<-", "[", "[<-", cbind, rbind, "mcols<-", indexVcf, vcfFields, subset, genome, seqlevels, seqinfo, reference, samples, header, meta, keys, keytypes, columns, select, import ) VariantAnnotation/NEWS0000644000175100017510000004501414614305321015733 0ustar00biocbuildbiocbuildCHANGES IN VERSION 1.36.0 ------------------------- NEW FEATURES o ref<-, alt<-, qual<- and filt<- allow replacement value length recycling CHANGES IN VERSION 1.28.0 ------------------------ NEW FEATURES o Update package to support VCF format version 4.3 - SAMPLE field lines can now have key 'SAMPLE' or 'META'. To avoid a name clash, the existing 'META' DataFrame has been split by row into separate DataFrames. The 'meta(VCFHeader)' getter now returns one DataFrame per unique key in the header. - PEDIGREE header line now begins with 'ID' o Add vcfFields method for character, VCFHeader, VcfFile and VCF to return all available vcf fields in CharacterList(). o Add support for single breakend notation (thanks d-cameron) BUG FIXES o .formatInfo() now return a column with all 'NA' for a missing value instead of dropping the column. CHANGES IN VERSION 1.26.0 ------------------------ MODIFICATIONS o Clarify fixed fields must be o Following renaming of RangesList class -> IntegerRangesList o Updates to accommodate change to '[<-' method for SummarizedExperiment o DP4 assumed to come from INFO field o Extract altDepth and totalDepth from DP4 GENO field when present o predictCoding() now respects 'alt_init_codons' at the start of CDS region only o Remove error message in 'rowRanges<-' and 'mcol<-' methods that check for fixed column name. CHANGES IN VERSION 1.24.0 ------------------------ NEW FEATURES o Add subset,VCF-method that knows about info() o Add alt,ref accessors for VRangesList o More efficient show,VCF-method o 'rowRanges<-' and 'mcols<-' on VCF class behave as they do on RangedSummarizedExperiment o info,VCFHeader() and geno,VCFHeader() return a DataFrame with the correct columns in the case of empty BUG FIXES o Fix "ref<-" recycling on VRanges o Fix bug in locateVariants(); code to fetch IntronVariants() was incorrectly fetching IntergenicVariants() o Fix bug in rbind,VCF,VCF-method CHANGES IN VERSION 1.22.0 ------------------------ NEW FEATURES o add import() wrapper for VCF files o add support for Number='R' in vcf parsing o add indexVcf() and methods for character,VcfFile,VcfFileList MODIFICATIONS o throw message() instead of warning() when non-nucleotide variations are set to NA o replace 'force=TRUE' with 'pruning.mode="coarse"' in seqlevels() setter o add 'pruning.mode' argument to keepSeqlevels() in man page example o idempotent VcfFile() o add 'idType' arg to IntergenicVariants() constructor o modify locateVariants man page example to work around issue that distance,GRanges,TxDb does not support gene ranges on multiple chromosomes o modify VcfFile() constructor to detect index file if not specified o order vignettes from intro to advanced; use BiocStyle::latex2() o remove unused SNPlocs.Hsapiens.dbSNP.20110815 from the Suggests field o follow rename change in S4Vectors from vector_OR_factor to vector_or_factor o pass classDef to .RsamtoolsFileList; VariantAnnotation may not be on the search path BUG FIXES o fix expansion of 'A' fields when there are multiple columns CHANGES IN VERSION 1.20.0 ------------------------ NEW FEATURES o add import() wrapper for VCF files MODIFICATIONS o use now-public R_GetConnection o remove defunct readVcfLongForm() generic o remove 'genome' argument from readVcf() o improvements to VCF to VRanges coercion o support Varscan2 AD/RD convention when coercing VCF to VRanges o use [["FT"]] to avoid picking up FTZ field o summarizeVariants() recognize '.' as missing GT field o document scanVcfheader() behavior for duplicate row names BUG FIXES o ensure only 1 matching hub resource selected in filterVcf vignette o fix check for FILT == "PASS" o correct column alignment in makeVRangesFromGRanges() o fix check for AD conformance CHANGES IN VERSION 1.19.0 ------------------------ NEW FEATURES o add SnpMatrixToVCF() o add patch from Stephanie Gogarten to support 'PL' in genotypeToSnpMatrix() MODIFICATIONS o move getSeq,XStringSet-method from VariantAnnotation to BSgenome o update filterVcf vignette o remove 'pivot' export o work on readVcf(): - 5X speedup for readVcf (at least in one case) by not using "==" to compare a list to a character (the list gets coerced to character, which is expensive for huge VCFs) - avoiding relist.list() o update summarizeVariants() to comply with new SummarizedExperiment rownames requirement o defunct VRangesScanVcfParam() and restrictToSNV() o use elementNROWS() instead of elementLengths() o togroup(x) now only works on a ManyToOneGrouping object so replace togroup(x, ...) calls with togroup(PartitioningByWidth(x), ...) when 'x' is a list-like object that is not a ManyToOneGrouping object. o drop validity assertion that altDepth must be NA when alt is NA there are VCFs in the wild that use e.g. "*" for alt, but include depth o export PLtoGP() o VariantAnnotation 100% RangedData-free BUG FIXES o use short path names in src/Makevars.win CHANGES IN VERSION 1.18.0 ------------------------ MODIFICATIONS o defunct VRangesScanVcfParam() o defunct restrictToSNV() BUG FIXES o scanVcf,character,missing-method ignores blank data lines. o Build path for C code made robust on Windows. CHANGES IN VERSION 1.16.0 ------------------------ NEW FEATURES o support REF and ALT values ".", "+" and "-" in predictCoding() o return non-translated characters in VARCODON in predictCoding() output o add 'verbose' option to readVcf() and friends o writeVcf() writes 'fileformat' header line always o readVcf() converts REF and ALT values "*" and "I" to '' and '.' MODIFICATIONS o VRanges uses '*' strand by default o coerce 'alt' to DNStringSet for predictCoding,VRanges-method o add detail to documentation for 'ignore.strand' in predictCoding() o be robust to single requrested INFO column not present in vcf file o replace old SummarizedExperiment class from GenomicRanges with the new new RangedSummarizedExperiment from SummarizedExperiment package o return strand of 'subject' for intronic variants in locateVariants() BUG FIXES o writeVcf() does not duplicate header lines when chunking o remove extra tab after INFO when no FORMAT data are present o filteVcf() supports 'param' with ranges CHANGES IN VERSION 1.14.0 ------------------------ NEW FEATURES o gVCF support: - missing END header written out with writeVcf() - expand() handles 'REF' value o support 'Type=Character' in INFO header fields o add 'row.names' argument to expand() o add 'Efficient Usage' section to readVcf() man page o efficiency improvements to info(..., row.names=) - anyDuplicated() less expensive than any(duplicated()) - use row.names=FALSE when not needed, e.g., show() o add genotypeCodesToNucleotides() o add support for gvcf in isSNP family of functions o add VcfFile and VcfFileList classes o support 'Type=Character' of unspecified length (.) o add isDelins() from Robert Castelo o add makeVRangesFromGRanges() from Thomas Sandmann MODIFICATIONS o VCFHeader support: - SAMPLE and PEDIGREE header fields are now parsed - meta(VCFHeader) returns DataFrameList instead of DataFrame - show(VCFHeader) displays the outer list names in meta - fixed(VCFHeader) returns 'ALT' and 'REF' if present o 'ALT' in expandedVCF output is DNAStringSet, not *List o remove .listCumsum() and .listCumsumShifted() helpers o add multiple INFO field unit test from Julian Gehring o add additional expand() unit tests o modify readVccfAsVRanges() to use ScanVcfParam() as the 'param'; deprecate VRangesScanVcfParam o replace mapCoords() with mapToTranscripts() o change 'CDSID' output from integer to IntegerList in locateVariants() and predictCoding() o add readVcf,character,ANY,ANY; remove readVcf,character,ANY,ScanVcfParam o replace rowData() accessor with rowRanges() o replace 'rowData' argument with 'rowRanges' (construct SE, VCF classes) o replace getTranscriptSeqs() with extractTranscripts() BUG FIXES o readVcf() properly handles Seqinfo class as 'genome' o allow 'ignore.strand' to pass through mapCoords() o writeVcf() no longer ignores rows with no genotype field o expand() properly handles - less than all INFO fields are selected - VCF has only one row - only one INFO column o don't call path() on non-*File objects o split (relist) of VRanges now yields a CompressedVRangesList o predictCoding() now ignores zero-width ranges CHANGES IN VERSION 1.12.0 ------------------------ NEW FEATURES o allow GRanges in 'rowData' to hold user-defined metadata cols (i.e., cols other than paramRangeID, REF, ALT, etc.) o add isSNV() family of functions o add faster method for converting a list matrix to an array o add 'c' method for typed Rle classes so class is preserved o add CITATION file o rework writeVCF(): - FORMAT and genotype fields are parsed in C - output file is written from C - chunking added for large VCFs MODIFICATIONS o add 'row.names' to readVcf() o deprecate restrictToSNV(); replaced by isSNV() family o remove use of seqapply() o show info / geno headers without splitting across blocks o use mapCoords() in predictCoding() and locateVariants() o deprecate refLocsToLocalLocs() o propagate strand in predictCoding() o replace deprecated seqsplit() with splitAsList() o ensure GT field, if present, comes first in VCF output o modify DESCRIPTION Author and Maintainer fileds with @R o add 'row.names' to info,VCF-method BUG FIXES o modify expand() to work with no 'info' fields are imported o remove duplicate rows from .splicesites() o fix handling of real-valued NAs in geno omatrix construction in writeVcf() CHANGES IN VERSION 1.10.0 ------------------------ NEW FEATURES o add support for ##contig in VCF header o add 'meta<-', 'info<-', 'geno<-' replacement methods for VCFHeader o add 'header<-' replacement method for VCF o add strand to output from locationVariants() o add support for writeVcf() to process Rle data in geno matrix o readVcf() now parses 'geno' fields with Number=G as ((#alleles + 1) * (#alleles + 2)) / 2 o writeVcf() now sorts the VCF when 'index=TRUE' o add 'fixed<-,VCFHeader,DataFrameList' method o add convenience functions for reading VCF into VRanges o add Rplinkseq test script o add 'isSNV', 'isInsertion', 'isDeletion', 'isIndel', 'isTransition', 'isPrecise', 'isSV' and 'isSubstitution' generics o add 'isSNV', 'isInsertion', 'isDeletion', 'isIndel' methods for VRanges and VCF classes o add match methods between ExpandedVCF and VRanges o add support for VRanges %in% TabixFile MODIFICATIONS o expand,VCF-method ignores 'AD' header of 'AD' geno is NULL o add support for SIFT.Hsapiens.dbSNP137 o remove locateVariants() dependence on chr7-sub.vcf.gz o modify expand() to handle 'AD' field where 'Number' is integer o rename readVRangesFromVCF() to readVcfAsVRanges() o remove check for circular chromosomes in locateVariants() and predictCoding() and refLocsToLocalLocs() o modify filterVcf() to handle ranges in ScanVcfParam o pass 'genetic.code' through predictCoding() o change default to 'row.names=TRUE' for readGT(), readGeno(), and readInfo() o fixed() on empty VCF now returns DataFrame with column names and data types vs an empty DataFrame o update biocViews o modify 'show,VCF' to represent empty values in XStringSet with '.' o replace rtracklayer:::pasteCollapse with unstrsplit() DEPRECATED and DEFUNCT o remove defunct dbSNPFilter(), regionfilter() and MatrixToSnpMatrix() o defunct readVcfLongForm() BUG FIXES o modify expand.geno() to handle case where header and geno don't match o modify writeVcf() to write out rownames with ":" character instead of treating as missing o fix how sample names were passed from 'ScanVcfParam' to scanVcf() o fix bug in 'show,VCF' method o fix bugs in VRanges -> VCF coercion methods o fix bug in lightweight read* functions that were ignoring samples in ScanVcfParam o fix bug in writeVcf() when no 'ALT' is present CHANGES IN VERSION 1.8.0 ------------------------ NEW FEATURES o Add 'upstream' and 'downstream' arguments to IntergenicVariants() constructor. o Add 'samples' argument to ScanVcfParam(). o Add readGT(), readGeno() and readInfo(). o Add VRanges, VRangesList, SimpleVRangesList, and CompressedVRangesList classes. o Add coercion VRanges -> VCF and VCF -> VRanges. o Add methods for VRanges family: altDepth(), refDepth(), totalDepth(), altFraction() called(), hardFilters(), sampleNames(), softFilterMatrix() isIndel(), resetFilter(). o Add stackedSamples,VRangesList method. MODIFICATIONS o VCF validity method now requires the number of rows in info() to match the length of rowData(). o PRECEDEID and FOLLOWID from locateVariants() are now CharacterLists with all genes in 'upstream' and 'downstream' range. o Modify rownames on rowData() GRanges to CHRAM:POS_REF/ALT for variants with no ID. o readVcf() returns info() and geno() in the order specified in the ScanVcfParam. o Work on scanVcf(): - free parse memory at first opportunity - define it_next in .c rather than .h - parse ALT "." in C - hash incoming strings - parse only param-requested 'fixed', 'info', 'geno' fields o Add dimnames<-,VCF method to prevent 'fixed' fields from being copied into 'rowData' when new rownames or colnames were assigned. o Support read/write for an emtpy VCF. o readVcf(file=character, ...) method attempts coercion to TabixFile. o Support for read/write an emtpy VCF. o Add performance section to vignette; convert to BiocStyle. o expand,CompressedVcf method expands geno() field 'AD' to length ALT + 1. The expanded field is a (n x y x 2) array. o 'genome' argument to readVcf() can be a character(1) or Seqinfo object. DEPRECATED and DEFUNCT o Defunct dbSNPFilter(), regionFilter() and MatrixToSnpMatrix(). o Deprecate readVcfLongForm(). BUG FIXES o Fix bug in compatibility of read/writeVcf() when no INFO are columns present. o Fix bug in locateVariants() when 'features' has no txid and cdsid. o Fix bug in asVCF() when writing header lines. o Fix bug in "expand" methods for VCF to handle multiple 'A' columns in info(). CHANGES IN VERSION 1.6.0 ------------------------ NEW FEATURES o VCF is now VIRTUAL. Concrete subclasses are CollapsedVCF and ExpandedVCF. o Add filterVcf() generic and methods for character and TabixFile. This method creates one VCF file from another, using FilterRules. o Enhance show,VCF method with header information. o Stephanie Gogarten added genotypeToSnpMatrix() generic and CollapsedVCF and matrix methods. o Chris Wallace added snpSummary() generic and CollapsedVCF method. o Add cbind and rbind for VCF objects. MODIFICATIONS o writeVcf,connection-method allows writing to console and appending. o writeVcf,connection-method accepts connections with open="a", only adding a header if the file does not already exist. o predictCoding and genotypeToSnpMatrix can now handle ALT as CharacterList. Structural variants are set to empty character (""). o When no INFO data are present in a vcf file, the info() slot is now an empty DataFrame. Previously an empty column named 'INFO' was returned. o Empty VCF class now has an empty VCFHeader o expand,CollapsedVCF-method expands 'geno' data with Number=A. o VCF class accessors "fixed", "info" now return DataFrame instead of GRanges. "rowData" returns fixed fileds as the mcols. o Updates to the vignette. DEPRECATED and DEFUNCT o Deprecate dbSNPFilter() and regionFilter(). o Deprecate MatrixToSnpMatrix(). BUG FIXES o Multiple bugs fixed in "locateVariants". o Multiple bugs fixed in "writeVcf". o Bug fixed in subsetting of VCF objects. o Bug fixed in "predictCoding" related to QUERYID column not mapping back to original indices (rows). CHANGES IN VERSION 1.4.0 ------------------------ NEW FEATURES o "summarizeVariants" for summarizing counts by sample o new VariantType 'PromoterVariants()' added to "locateVariants" MODIFICATIONS o "ref", "alt", "filt" and "qual" accessors for VCF-class now return a single variable instead of GRanges with variable as metadata CHANGES IN VERSION 1.2.0 ------------------------ NEW FEATURES o "readVcf" has genome argument, can be subset on ranges or VCF elements with "ScanVcfParam" o "scanVcfHeader" returns VCFHeader class with accessors fixed, info, geno, etc. o "writeVcf" writes out a VCF file from a VCF class o "locateVariants" methods - returns GRanges instead of DataFrame - 'region' argument allows specification of variants by region - output includes txID, geneID and cdsID - has cache argument for repeated calls over multiple vcf files o "predictCoding" methods - returns GRanges instead of DataFrame - output includes txID, geneID, cdsID, cds-based and protein-based coordinates CHANGES IN VERSION 1.0.0 ------------------------ NEW FEATURES o "readVcf" methods for reading and parsing VCF files into a SummarizedExperiment o "locateVariants" and "predictCoding" for identifying amino acid coding changes in nonsynonymous variants o "dbSNPFilter" and "regionFilter" for filtering variants on membership in dbSNP or on a particular location in the genome o access to PolyPhen and SIFT predictions through "keys" , "cols" and "select" methods. See ?SIFT or ?PolyPhen. BUG FIXES o No changes classified as 'bug fixes' (package under active development) VariantAnnotation/R/0000755000175100017510000000000014614305321015431 5ustar00biocbuildbiocbuildVariantAnnotation/R/AllClasses.R0000644000175100017510000003011214614305321017577 0ustar00biocbuildbiocbuild### ========================================================================= ### All classes ### ========================================================================= ### ------------------------------------------------------------------------- ### VCF (VIRTUAL) ### setClass("VCF", contains=c("VIRTUAL", "RangedSummarizedExperiment"), representation( fixed="DataFrame", info="DataFrame") ) .valid.VCF.fixed <- function(object) { xlen <- dim(object)[1] ffld <- fixed(object) nms <- colnames(ffld) if (nrow(ffld) != 0) { if (nrow(ffld) != xlen) return(paste0("'fixed(object)' and 'rowRanges(object) ", "must have the same number of rows", sep="")) if (!all(nms %in% c("REF", "ALT", "QUAL", "FILTER"))) return(paste("'fixed(object)' colnames must be ", "'REF', 'ALT', 'QUAL' and 'FILTER'", sep="")) if ("REF" %in% nms) if (!is(ffld$REF, "DNAStringSet")) return("'ref(object)' must be a DNAStringSet") if ("QUAL" %in% nms) if (!is(ffld$QUAL, "numeric")) return("'qual(object)' must be numeric") if ("FILTER" %in% nms) if (!is(ffld$FILTER, "character")) return("'filt(object)' must be a character") } NULL } .valid.VCF.info <- function(object) { xlen <- nrow(object) i <- info(object) if (nrow(i) != xlen) return("'info' must have the same number of rows as 'rowRanges'") NULL } .valid.VCF.alt <- function(object) { if (length(alt <- alt(object))) { if (is(object, "ExpandedVCF")) { if (!is(alt, "DNAStringSet") && !is.character(alt)) return(paste("'alt(object)' must be a DNAStringSet or a ", "character", sep="")) } else if (is(object, "CollapsedVCF")) { if (!is(alt, "DNAStringSetList") && !is(alt, "CharacterList")) return(paste("'alt(object)' must be a DNAStringSetList or a ", "CharacterList", sep="")) } } NULL } .valid.VCF <- function(object) { c(.valid.VCF.fixed(object), .valid.VCF.info(object), .valid.VCF.alt(object)) } ### ------------------------------------------------------------------------- ### CollapsedVCF ### setClass("CollapsedVCF", contains="VCF", prototype=prototype( fixed=DataFrame(REF=DNAStringSet(), ALT=DNAStringSetList(), QUAL=numeric(), FILTER=character())), validity=.valid.VCF) ### Automatically generated "coerce<-" method is broken so we fix it. ### See S4Vectors/R/S4-utils.R in the S4Vectors package for more information. S4Vectors:::setReplaceAs("CollapsedVCF", "RangedSummarizedExperiment", S4Vectors:::canonical_replace_as_2 ) ### ------------------------------------------------------------------------- ### ExpandedVCF ### setClass("ExpandedVCF", contains="VCF", prototype=prototype( fixed=DataFrame(REF=DNAStringSet(), ALT=DNAStringSet(), QUAL=numeric(), FILTER=character())), validity=.valid.VCF) ### Automatically generated "coerce<-" method is broken so we fix it. ### See S4Vectors/R/S4-utils.R in the S4Vectors package for more information. S4Vectors:::setReplaceAs("ExpandedVCF", "RangedSummarizedExperiment", S4Vectors:::canonical_replace_as_2 ) ### ------------------------------------------------------------------------- ### VCFHeader ### setClass("VCFHeader", representation( reference="character", samples="character", header="SimpleDataFrameList" ) ) .valid.VCFHeader.colnames <- function(value, slotname) { if (length(value)) { col <- c("Number", "Type", "Description") if (ncol(value) != 3 || !all(names(value) %in% col)) return(paste0("'", slotname, "(VCFHeader)' must be a ", "3 column DataFrame with names ", paste(col, collapse=", "))) else return(NULL) } NULL } .valid.VCFHeader.info <- function(object) .valid.VCFHeader.colnames(info(object), "info") .valid.VCFHeader.geno <- function(object) .valid.VCFHeader.colnames(geno(object), "geno") .valid.VCFHeader.meta <- function(object) { msg <- NULL len <- sapply(names(meta(object)), nchar) if (any(len == 0)) msg <- "all elements of 'meta(VCFHeader)' must be named" msg } ## Test VCFHeader only .valid.VCFHeader <- function(object) { return(c(.valid.VCFHeader.info(object), .valid.VCFHeader.geno(object), .valid.VCFHeader.meta(object))) } setValidity("VCFHeader", .valid.VCFHeader, where=asNamespace("VariantAnnotation")) ## These validity checks test the fields in the VCF against ## the VCFHeader. Called from header<-,VCF-method. .valid.VCFHeadervsVCF.fields <- function(object, slotname) { diff <- setdiff(names(slotname(object)), rownames(slotname(header(object)))) if (length(diff)) { warning(paste0(attributes(slotname)$generic[1], " fields with no header: ", paste(diff, collapse=",")), call.=FALSE) } NULL } .valid.VCFHeadervsVCF <- function(object) { validObject(header(object)) c(.valid.VCFHeadervsVCF.fields(object, info), .valid.VCFHeadervsVCF.fields(object, geno)) } ### ------------------------------------------------------------------------- ### VcfFile, VcfFileList ### .VcfFile = setRefClass("VcfFile", contains="TabixFile") setClass("VcfFileList", contains="TabixFileList", prototype=prototype(elementType="VcfFile")) ### ------------------------------------------------------------------------- ### ScanVcfParam ### setClass("ScanVcfParam", contains="ScanBVcfParam") ### ------------------------------------------------------------------------- ### SIFT, PROVEAN and PolyPhen ### .SIFTDb <- setRefClass("SIFTDb", contains = "AnnotationDb") .PROVEANDb <- setRefClass("PROVEANDb", contains = "AnnotationDb") .PolyPhenDb <- setRefClass("PolyPhenDb", contains = "AnnotationDb") ### ------------------------------------------------------------------------- ### VariantType class hierarchy ### setClass("VariantType", representation( "VIRTUAL" ) ) setMethod("show", "VariantType", function(object) { cat("class:", classNameForDisplay(object), "\n") } ) setClass("CodingVariants", contains="VariantType") setClass("IntronVariants", contains="VariantType") setClass("ThreeUTRVariants", contains="VariantType") setClass("FiveUTRVariants", contains="VariantType") setClass("SpliceSiteVariants", contains="VariantType") setClass("IntergenicVariants", contains="VariantType", representation(upstream="integer", downstream="integer", idType="character") ) setClass("PromoterVariants", contains="VariantType", representation(upstream="integer", downstream="integer") ) setClass("AllVariants", contains="VariantType", representation(promoter="PromoterVariants", intergenic="IntergenicVariants") ) ### ------------------------------------------------------------------------- ### VRanges ### ### This is useful when variants are the unit of analysis, especially ### when diagnosis the effects of filters. Thus, this corresponds to ### an expansion of VCF, where each variant only has one alt ### allele. If the alt is NA, it describes a reference/WT call. ### .valid.VRanges.ref <- function(object) { c(if (any(is.na(object@ref))) "'ref' must not contain 'NA' values", if (length(which(object@ref == object@alt)) > 0L) "'ref' must not match 'alt'") } .valid.VRanges.strand <- function(object) { if (any(object@strand == "-")) paste("'strand' must always be '+' or '*'") } naToZero <- function(x) { x[is.na(x)] <- 0L x } .valid.VRanges.depth <- function(object) { checkDepth <- function(name) { if (any(slot(object, name) < 0, na.rm = TRUE)) paste0("'", name, "' must be non-negative") } depth.slots <- c("refDepth", "altDepth", "totalDepth") do.call(c, lapply(depth.slots, checkDepth)) } ### FIXME: we are not yet checking for redundant observations, i.e., ### rows with the same seqname, start, end, alt, and sample. .valid.VRanges <- function(object) { c(.valid.VRanges.ref(object), .valid.VRanges.strand(object), .valid.VRanges.depth(object)) } setTypedRle <- function(type) { cname <- paste0(type, "Rle") setClass(cname, representation(values = type), contains = "Rle") setValidity(cname, function(object) { if (!is(runValue(object), type)) paste("run values in Rle must be", type) }) coercer <- get(paste0("as.", type)) # as(from, type) is NOT the same setAs("Rle", cname, function(from) { if (!is(runValue(from), type)) slot(from, "values", check = FALSE) <- coercer(runValue(from)) new(cname, from) }) setAs("vector_OR_factor", cname, function(from) { new(cname, Rle(coercer(from))) }) setMethod("[", cname, function(x, i, j, ..., drop = getOption("dropRle", FALSE)) { as(callNextMethod(), cname) }) setReplaceMethod("[", cname, function(x, i, j, ..., value) { if (missing(i)) ans <- callGeneric(x = as(x, "Rle"), value = value) else ans <- callGeneric(x = as(x, "Rle"), i = i, value = value) as(ans, paste0(class(runValue(ans)), "Rle")) }) setMethod("replaceROWS", cname, function(x, i, value) { x <- as(x, "Rle") ans <- callNextMethod() as(ans, paste0(class(runValue(ans)), "Rle")) }) setMethod("window", cname, function(x, ...) { as(callNextMethod(), cname) }) setMethod("c", cname, function(x, ...) { ### FIXME: cannot use callNextMethod, because broken for ### primitive generics where the actual primitive object ### is part of the call, e.g., do.call(generic, args) as(do.call(c, lapply(list(x, ...), as, "Rle")), cname) }) cname } ### TODO: These could land in IRanges at some point. They are useful ### for constraining class representations, and are convenient ### coercion targets. In theory, we could also use them more broadly, ### i.e., for Rle method dispatch, but that would require work in ### Rle() and runValue<- first, and would break serialized objects. setTypedRle("raw") setTypedRle("logical") setTypedRle("integer") setTypedRle("numeric") setTypedRle("complex") setTypedRle("character") setTypedRle("factor") setAtomicRleUnion <- function(type) { cname <- paste0(type, "OrRle") rlename <- paste0(type, "Rle") setClassUnion(cname, c(type, rlename)) coercer <- get(paste0("as.", type)) # as(from, type) is NOT the same setAs("ANY", cname, function(from) { coercer(from) }) setAs("Rle", cname, function(from) { as(from, rlename) }) cname } .integerOrRle <- setAtomicRleUnion("integer") .characterOrRle <- setAtomicRleUnion("character") .factorOrRle <- setAtomicRleUnion("factor") setClass("VRanges", representation(ref = "character", # or XStringSet? alt = .characterOrRle, totalDepth = .integerOrRle, refDepth = .integerOrRle, altDepth = .integerOrRle, sampleNames = .factorOrRle, softFilterMatrix = "matrix", hardFilters = "FilterRules"), contains = "GRanges", validity = .valid.VRanges) ### ------------------------------------------------------------------------- ### VRangesList ### setClass("VRangesList", representation("VIRTUAL"), prototype = prototype(elementType = "VRanges"), contains = "GRangesList") setClass("SimpleVRangesList", contains = c("VRangesList", "SimpleGRangesList")) setClass("CompressedVRangesList", representation(unlistData = "VRanges"), contains = c("VRangesList", "CompressedGRangesList")) VariantAnnotation/R/AllGenerics.R0000644000175100017510000001755314614305321017757 0ustar00biocbuildbiocbuild### ------------------------------------------------------------------------- ### predictCoding ### setGeneric("predictCoding", signature=c("query", "subject", "seqSource", "varAllele"), function(query, subject, seqSource, varAllele, ...) standardGeneric("predictCoding") ) setGeneric("getTranscriptSeqs", signature=c("query", "subject"), function(query, subject, ...) standardGeneric("getTranscriptSeqs") ) ### ------------------------------------------------------------------------- ### locateVariants ### setGeneric("locateVariants", signature=c("query", "subject", "region"), function(query, subject, region, ...) standardGeneric("locateVariants") ) ### ------------------------------------------------------------------------- ### summarizeVariants ### setGeneric("summarizeVariants", signature=c("query", "subject", "mode"), function(query, subject, mode, ...) standardGeneric("summarizeVariants") ) ### ------------------------------------------------------------------------- ### VariantRegion classes ### setGeneric("upstream", signature="x", function(x) standardGeneric("upstream") ) setGeneric("upstream<-", signature="x", function(x, value) standardGeneric("upstream<-") ) setGeneric("downstream", signature="x", function(x) standardGeneric("downstream") ) setGeneric("downstream<-", signature="x", function(x, value) standardGeneric("downstream<-") ) setGeneric("promoter", signature="x", function(x) standardGeneric("promoter") ) setGeneric("promoter<-", signature="x", function(x, value) standardGeneric("promoter<-") ) setGeneric("intergenic", signature="x", function(x) standardGeneric("intergenic") ) setGeneric("intergenic<-", signature="x", function(x, value) standardGeneric("intergenic<-") ) setGeneric("idType", signature="x", function(x) standardGeneric("idType") ) setGeneric("idType<-", signature="x", function(x, value) standardGeneric("idType<-") ) ### ------------------------------------------------------------------------- ### read/write Vcf ### setGeneric("readVcf", signature=c("file", "param"), function(file, genome, param, ...) standardGeneric("readVcf") ) setGeneric("writeVcf", signature=c("obj", "filename"), function(obj, filename, ...) standardGeneric("writeVcf") ) ### ------------------------------------------------------------------------- ### scanVcf ### setGeneric("ScanVcfParam", signature="which", function(fixed=character(), info=character(), geno=character(), samples=character(), trimEmpty=TRUE, which, ...) standardGeneric("ScanVcfParam") ) setGeneric("scanVcfHeader", signature="file", function(file, ...) standardGeneric("scanVcfHeader") ) setGeneric("scanVcf", signature=c("file", "param"), function(file, ..., param) standardGeneric("scanVcf") ) ### ------------------------------------------------------------------------- ### filterVcf ### setGeneric("filterVcf", signature="file", function(file, genome, destination, ..., verbose=FALSE, index=FALSE, prefilters=FilterRules(), filters=FilterRules(), param=ScanVcfParam()) standardGeneric("filterVcf") ) ### ------------------------------------------------------------------------- ### VCF class ### setGeneric("fixed", signature="x", function(x) standardGeneric("fixed") ) setGeneric("fixed<-", signature=c("x", "value"), function(x, value) standardGeneric("fixed<-") ) setGeneric("ref", signature="x", function(x) standardGeneric("ref") ) setGeneric("ref<-", signature=c("x", "value"), function(x, value) standardGeneric("ref<-") ) setGeneric("alt", signature="x", function(x) standardGeneric("alt") ) setGeneric("alt<-", signature=c("x", "value"), function(x, value) standardGeneric("alt<-") ) setGeneric("qual", signature="x", function(x) standardGeneric("qual") ) setGeneric("qual<-", signature=c("x", "value"), function(x, value) standardGeneric("qual<-") ) setGeneric("filt", signature="x", function(x) standardGeneric("filt") ) setGeneric("filt<-", signature=c("x", "value"), function(x, value) standardGeneric("filt<-") ) setGeneric("info", signature="x", function(x, ..., row.names = TRUE) standardGeneric("info") ) setGeneric("info<-", signature=c("x", "value"), function(x, value) standardGeneric("info<-") ) setGeneric("geno", signature=c("x", "i"), function(x, i, ..., withDimnames=TRUE) standardGeneric("geno"), ) setGeneric("geno<-", signature=c("x", "i", "value"), function(x, i, ..., value) standardGeneric("geno<-") ) ### ------------------------------------------------------------------------- ### VCFHeader class ### setGeneric("reference", signature="x", function(x) standardGeneric("reference"), ) setGeneric("header", signature="x", function(x) standardGeneric("header"), ) setGeneric("header<-", signature=c("x", "value"), function(x, value) standardGeneric("header<-"), ) setGeneric("contig", signature="x", function(x) standardGeneric("contig"), ) setGeneric("meta", signature="x", function(x) standardGeneric("meta"), ) setGeneric("meta<-", signature=c("x", "value"), function(x, value) standardGeneric("meta<-"), ) setGeneric("vcfFields", signature = "x", function(x, ...) standardGeneric("vcfFields")) ### ------------------------------------------------------------------------- ### snp encoding methods ### setGeneric("genotypeToSnpMatrix", signature="x", function(x, ...) standardGeneric("genotypeToSnpMatrix") ) setGeneric("snpSummary", function(x, ...) standardGeneric("snpSummary") ) ### ------------------------------------------------------------------------- ### isSNV helpers ### setGeneric("isSNV", signature="x", function(x, ...) standardGeneric("isSNV") ) setGeneric("isInsertion", signature="x", function(x, ...) standardGeneric("isInsertion") ) setGeneric("isDeletion", signature="x", function(x, ...) standardGeneric("isDeletion") ) setGeneric("isIndel", signature="x", function(x, ...) standardGeneric("isIndel") ) setGeneric("isDelins", signature="x", function(x, ...) standardGeneric("isDelins") ) setGeneric("isTransition", signature="x", function(x, ...) standardGeneric("isTransition") ) setGeneric("isSV", signature="x", function(x, ...) standardGeneric("isSV") ) setGeneric("isSVPrecise", signature="x", function(x, ...) standardGeneric("isSVPrecise") ) setGeneric("isSubstitution", signature="x", function(x, ...) standardGeneric("isSubstitution") ) ### ------------------------------------------------------------------------- ### VRanges class ### setGeneric("totalDepth", function(x, ...) standardGeneric("totalDepth")) setGeneric("altDepth", function(x, ...) standardGeneric("altDepth")) setGeneric("refDepth", function(x, ...) standardGeneric("refDepth")) setGeneric("softFilterMatrix", function(x, value) standardGeneric("softFilterMatrix")) setGeneric("softFilterMatrix<-", function(x, value) standardGeneric("softFilterMatrix<-")) setGeneric("hardFilters", function(x, value) standardGeneric("hardFilters")) setGeneric("hardFilters<-", function(x, value) standardGeneric("hardFilters<-")) setGeneric("called", function(x, ...) standardGeneric("called")) setGeneric("altFraction", function(x, ...) standardGeneric("altFraction")) setGeneric("refFraction", function(x, ...) standardGeneric("refFraction")) setGeneric("asVCF", function(x, ...) standardGeneric("asVCF")) setGeneric("tabulate", signature = "bin", # BiocGenerics? function(bin, nbins = max(1L, bin, na.rm = TRUE)) standardGeneric("tabulate")) ### ------------------------------------------------------------------------- ### VRangesList class ### setGeneric("stackSamples", function(x, ...) standardGeneric("stackSamples")) VariantAnnotation/R/AllUtilities.R0000644000175100017510000002435214614305321020166 0ustar00biocbuildbiocbuild### ========================================================================= ### Helper functions not exported ### ========================================================================= ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### readVcf() ### .collapseLists <- function(vcf, param) { idx <- sapply(vcf, function(elt) length(elt$rowRanges) > 0L) if (!sum(idx)) return(vcf[[1]]) if (length(vcf) > 1L) vcf <- vcf[idx] if (is(param, "ScanVcfParam")) paramRangeID <- names(unlist(vcfWhich(param), use.names=FALSE))[idx] else paramRangeID <- names(param)[idx] if (is.null(paramRangeID)) paramRangeID <- rep(NA_character_, length(vcf)) ## single range in 'which' if (1L == length(vcf)) { lst <- vcf[[1]] lst$paramRangeID <- as.factor(rep(paramRangeID, length(lst$rowRanges))) } else { ## multiple ranges in 'which' lst <- lapply(names(vcf[[1]]), function(elt) { suppressWarnings(do.call(c, unname(lapply(vcf, "[[", elt)))) }) names(lst) <- names(vcf[[1]]) len <- unlist(lapply(vcf, function(elt) length(elt$rowRanges)), use.names=FALSE) paramRangeID <- as.factor(rep(paramRangeID, len)) ## collapse info and geno info <- lst$INFO sp <- split(unname(info), unique(names(info))) sp <- sp[unique(names(info))] lst$INFO <- lapply(sp, function(elt) { d <- dim(elt[[1]]) if (is(elt[[1]], "list")) { as.matrix(elt) } else if (is(elt[[1]], "array") && !is.na(d[3])) { pc <- lapply(seq_len(d[2]), function(i) { do.call(rbind, lapply(elt, "[", ,i,)) }) array(do.call(c, pc), c(length(lst$rowRanges), d[2], d[3])) } else { do.call(c, elt) } }) geno <- lst$GENO sp <- split(geno, unique(names(geno))) lst$GENO <- lapply(sp, function(elt) { d <- dim(elt[[1]]) if (!is.na(d[3])) { pc <- lapply(seq_len(d[3]), function(i) { do.call(rbind, lapply(elt, "[", ,,i)) }) cmb <- array(do.call(c, pc), c(length(lst$rowRanges), d[2], d[3])) cmb } else { trans <- lapply(elt, t) cmb <- matrix(do.call(c, trans), length(lst$rowRanges), d[2], byrow=TRUE) cmb } }) lst$paramRangeID <- paramRangeID } lst } .formatList <- function(data, type) { switch(type, Integer = IntegerList(data), Float = NumericList(data), String = CharacterList(data), Character = CharacterList(data), Logical = LogicalList(data)) } ## Converts structural variants in a CharacterList to a '.' ## DNAStringSetList. Used in predictCoding(), genotypeToSnpMatrix() ## and snpSummary(). .toDNAStringSetList <- function(x) { pbw <- PartitioningByWidth(elementNROWS(x)) x <- unlist(x, use.names=FALSE) x[.isStructural(x)] <- "" xx <- sub(".", "", x, fixed=TRUE) relist(DNAStringSet(xx), pbw) } ## Returns structural variants in a CharacterList and all others in ## a DNAStringSetList. Used in .scanVcfToVCF(). .formatALT <- function(x) { if (is.null(x)) return(NULL) flat <- unlist(x, use.names=FALSE) if (any(.isStructural(flat))) { CharacterList(x) } else { flat[grepl("I", flat, fixed=TRUE)] <- "." flat[grepl("*", flat, fixed=TRUE)] <- "" relist(DNAStringSet(flat), x) } } ## The grep for '.' here is looking for '.' as *part* of the ALT field. ## If the ALT were '.' only, with no other characters, it would have been ## converted to an empty string in the C code before it reached this point. .isStructural <- function(x) { grepl("<", x, fixed=TRUE) | grepl("[", x, fixed=TRUE) | grepl("]", x, fixed=TRUE) | grepl(".", x, fixed=TRUE) } .formatInfo <- function(x, hdr, nrecords) { ## no data allNA <- 1L == length(x) && all(is.na(unlist(x[[1]]))) allMissing <- 1L == length(x) && all(unlist(x[[1]]) == ".", na.rm=TRUE) if (length(x) == 0L || (allMissing && !allNA)) return(DataFrame(row.names=seq_len(nrecords))) ## data in file but not in header if (!length(hdr) && length(x[[1]])) { DF <- DataFrame(x) names(DF) <- names(x) return(DF) } ## matrices and arrays type <- hdr$Type[match(names(x), rownames(hdr))] idx <- which(lapply(x, is.array) == TRUE) if (0L != length(idx)) { for (i in idx) { dat <- x[[i]] d <- dim(dat) ncol <- ifelse(!is.na(d[3]), d[3], d[2]) if (ncol > 1) dat <- split(unlist(dat, use.names=FALSE), rep(seq_len(d[1]), ncol)) x[[i]] <- .formatList(dat, type[i]) } } ## ragged lists lx <- which(lapply(x, is.list) == TRUE) if (0L != length(lx)) { for (i in lx) { x[[i]] <- .formatList(x[[i]], type[i]) } } DF <- DataFrame(x) names(DF) <- names(x) DF } .rleRecycleVector <- function(x, len) { if (is(x, "Rle")) rep(x, length.out = len) else if (length(x) == 1L) Rle(x, len) else S4Vectors:::recycleVector(x, len) } .pasteCollapseRows <- function(x, sep = ",") { if (!is.matrix(x) || storage.mode(x) != "character") { stop("'x' must be a matrix of mode character") } if (!isSingleString(sep) || nchar(sep) == 0L) { stop("'sep' must be a single, non-NA, non-empty string") } .Call(matrix_pasteCollapseRows, x, sep) } ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### PolyPhen, SIFT and PROVEAN ### .getKcol <- function(conn) { sql <- "SELECT value FROM metadata WHERE name='Key column'" as.character(dbGetQuery(conn, sql)) } .sqlIn <- function(vals) { if (0L == length(vals)) return("") sql <- lapply(seq_len(length(vals)), function(i) { v <- vals[[i]] if (!is.numeric(v)) v <- paste("'", v, "'", sep="") v }) paste(unlist(sql), collapse = ",") } .missingKeys <- function(x, keys, db) { if (missing(keys)) return(FALSE) if (any(mkeys <- !keys %in% keys(x))) { msg <- paste(S4Vectors:::selectSome(keys[mkeys]), collapse=" ") warning(sum(mkeys), " keys not found in ", db, " database: ", msg, call.=FALSE) } all(mkeys) } .missingCols <- function(x, cols, db) { if (missing(cols)) return(FALSE) if (any(mcols <- !cols %in% columns(x))) { msg <- paste(S4Vectors:::selectSome(cols[mcols], 5), collapse=" ") warning(sum(mcols), " columns not found in ", db, " database: ", msg, call.=FALSE) return(TRUE) } else { return(FALSE) } } ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### isSNV helpers ### .isSNV <- function(ref, alt) { nchar(ref) == 1L & nchar(alt) == 1L } .isDeletion <- function(ref, alt) { nchar(alt) == 1L & nchar(ref) > 1L & substring(ref, 1, 1) == alt } .isInsertion <- function(ref, alt) { nchar(ref) == 1L & nchar(alt) > 1L & substring(alt, 1, 1) == as.character(ref) } .isIndel <- function(ref, alt) { .isDeletion(ref, alt) | .isInsertion(ref, alt) } .isDelins <- function(ref, alt) { !.isIndel(ref, alt) & !.isSubstitution(ref, alt) } .isTransition <- function(ref, alt) { m1 <- match(as.character(ref), c("A", "G", "T", "C")) m2 <- match(as.character(alt), c("G", "A", "C", "T")) res <- (m1 - m2) == 0 res[is.na(res)] <- FALSE res } .isSubstitution <- function(ref, alt) { nchar(ref) == nchar(alt) } ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### predictCoding() ### .localCoordinates <- function(from, to, ignore.strand, ...) { ## 'to' is a GRangesList of cds by transcript map <- mapToTranscripts(unname(from), to, ignore.strand=ignore.strand, ...) if (length(map) == 0) { res <- GRanges() mcols(res) <- DataFrame(REF=DNAStringSet(), ALT=DNAStringSetList(), varAllele=DNAStringSet(), CDSLOC=IRanges(), PROTEINLOC=IntegerList(), QUERYID=integer(), TXID=character(), CDSID=IntegerList()) return(res) } xHits <- map$xHits txHits <- map$transcriptsHits flat_to <- unlist(to) ## names needed for mapping ## FIXME: cdsid is expensive cdsid <- IntegerList(integer(0)) map2 <- mapToTranscripts(unname(from)[xHits], flat_to, ignore.strand=ignore.strand) cds <- mcols(flat_to)$cds_id[map2$transcriptsHits] ## CodingVariants() must fall within a coding region. ## mapToTranscripts() will map ranges that span intron ## junctions and overlap multiple exons/cds regions. Because ## of this, it's possible for 'map' to return a hit for a ## query that 'map2' will not. (The subject in ## 'map' is a GRangesList and in 'map2' it's unlisted.) ## Only ranges identified by 'map' and 'map2' are kept. ## Ranges identified by 'map' only are discarded. if (length(cds)) { cdsid <- unique(splitAsList(cds, map2$xHits)) keep <- logical(length(xHits)) keep[unique(map2$xHits)] <- TRUE if (any(!keep)) { map <- map[keep] txHits <- map$transcriptsHits xHits <- map$xHits } } if (is.null(txid <- names(to)[txHits])) txid <- NA_integer_ ## protein coordinates pends <- c(ceiling(start(map)/3), ceiling(end(map)/3)) plocs <- unique(IntegerList(split(pends, rep(seq_len(length(pends)/2)), 2))) res <- from[xHits] strand(res) <- strand(map) mcols(res) <- append(values(res), DataFrame(CDSLOC=ranges(map), PROTEINLOC=plocs, QUERYID=xHits, TXID=txid, CDSID=cdsid)) res } VariantAnnotation/R/makeVRangesFromGRanges.R0000644000175100017510000000457314614305321022063 0ustar00biocbuildbiocbuild### ========================================================================= ### makeVRangesFromGRanges() ### ------------------------------------------------------------------------- makeVRangesFromGRanges <- function(gr, ref.field="ref", alt.field="alt", totalDepth.field="totalDepth", altDepth.field="altDepth", refDepth.field="refDepth", sampleNames.field="sampleNames", keep.extra.columns=TRUE) { ## check args if (!is(gr, "GenomicRanges")) stop("'gr' must be a GenomicRanges object") args <- list(ref.field=ref.field, alt.field=alt.field, totalDepth.field=totalDepth.field, altDepth.field=altDepth.field, refDepth.field=refDepth.field, sampleNames.field=sampleNames.field) if (!all(strings <- sapply(args, isSingleString))) stop(paste0("'",names(args[!strings]), "'", collapse=","), " must be character(1)") ## match fields matched.fields <- match(tolower(args), tolower(names(mcols(gr))), 0) found.fields <- matched.fields != 0L matched <- matched.fields[found.fields] ## error for 'ref' (required) if (!"ref.field" %in% names(args)[found.fields]) stop("No 'ref' column could be identified.") ## extract fields, coerce to type lst <- as.list(c(rep(NA_character_, 2), rep(NA_integer_, 3), NA_character_)) names(lst) <- names(args) type <- vapply(lst, class, character(1)) lst[found.fields] <- Map(as, mcols(gr)[matched], type[found.fields]) if (keep.extra.columns) extra <- mcols(gr)[, -matched, drop=FALSE] else extra <- DataFrame() ## construct VRanges VRanges(seqnames=seqnames(gr), seqinfo=seqinfo(gr), ranges=ranges(gr), ref=lst[["ref.field"]], alt=lst[["alt.field"]], totalDepth=lst[["totalDepth.field"]], altDepth=lst[["altDepth.field"]], refDepth=lst[["refDepth.field"]], sampleNames=lst[["sampleNames.field"]], extra) } setAs("GRanges", "VRanges", function(from) makeVRangesFromGRanges(from, keep.extra.columns=TRUE) ) VariantAnnotation/R/methods-CollapsedVCF-class.R0000644000175100017510000000503014614305321022563 0ustar00biocbuildbiocbuild### ========================================================================= ### CollapsedVCF class methods ### ========================================================================= ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Constructor ### ### See VCF(..., collapsed=TRUE) in methods-VCF-class.R ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Getters and Setters ### alt() setter setReplaceMethod("alt", c("CollapsedVCF", "DNAStringSetList"), function(x, value) { value <- .recycleVector(alt(x), value) slot(x, "fixed")$ALT <- value x }) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### isSNV family ### .dispatchSNV_CollapsedVCF <- function(FUN, x, singleAltOnly) { alt <- alt(x) flat <- unlist(alt, use.names=FALSE) gvcf <- structural <- NULL if (is(flat, "character")) { gvcf <- grepl("NON_REF", flat, fixed=TRUE) structural <- .isStructural(flat) } res <- FUN(rep(ref(x), elementNROWS(alt(x))), flat) if (!is.null(structural)) res[structural | is.na(structural)] <- FALSE if (any(gvcf)) res[gvcf] <- TRUE ## relist lst <- relist(res, alt) if (singleAltOnly) all(lst) & elementNROWS(lst) == 1 else any(lst) } setMethod("isSNV", "CollapsedVCF", function(x, ..., singleAltOnly=TRUE) .dispatchSNV_CollapsedVCF(.isSNV, x, singleAltOnly) ) setMethod("isInsertion", "CollapsedVCF", function(x, ..., singleAltOnly=TRUE) .dispatchSNV_CollapsedVCF(.isInsertion, x, singleAltOnly) ) setMethod("isDeletion", "CollapsedVCF", function(x, ..., singleAltOnly=TRUE) .dispatchSNV_CollapsedVCF(.isDeletion, x, singleAltOnly) ) setMethod("isIndel", "CollapsedVCF", function(x, ..., singleAltOnly=TRUE) .dispatchSNV_CollapsedVCF(.isIndel, x, singleAltOnly) ) setMethod("isDelins", "CollapsedVCF", function(x, ..., singleAltOnly=TRUE) .dispatchSNV_CollapsedVCF(.isDelins, x, singleAltOnly) ) setMethod("isTransition", "CollapsedVCF", function(x, ..., singleAltOnly=TRUE) .dispatchSNV_CollapsedVCF(.isTransition, x, singleAltOnly) ) setMethod("isSubstitution", "CollapsedVCF", function(x, ..., singleAltOnly=TRUE) .dispatchSNV_CollapsedVCF(.isSubstitution, x, singleAltOnly) ) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### show ### setMethod(show, "CollapsedVCF", function(object) { .showVCFSubclass(object) }) VariantAnnotation/R/methods-expand.R0000644000175100017510000001430414614305321020476 0ustar00biocbuildbiocbuild### ========================================================================= ### expand methods ### ========================================================================= setMethod("expand", "CollapsedVCF", function(x, ..., row.names = FALSE) { rd <- rowRanges(x, fixed=FALSE) if (!row.names) names(rd) <- NULL elt <- elementNROWS(alt(x)) if (all(elt == 1L)) { fxd <- fixed(x) fxd$ALT <- unlist(alt(x), use.names=FALSE) ghdr <- geno(header(x)) varsR <- rownames(ghdr)[rownames(ghdr) == "AD" | ghdr$Number == "R"] varsR <- varsR[varsR %in% names(geno(x))] if (length(varsR) > 0){ geno(x)[varsR] <- endoapply( geno(x)[varsR], function(i) .expandAD(i, nrow(x), ncol(x)) ) } return(VCF(rd, colData(x), metadata(x), fxd, .unlistAltInfo(x), geno(x), ..., collapsed=FALSE)) } ## info, fixed, geno hdr <- metadata(x)$header idx <- rep.int(seq_len(nrow(x)), elt) iexp <- .expandInfo(x, hdr, elt, idx) fexp <- fixed(x)[idx, ] fexp$ALT <- unlist(alt(x), use.names=FALSE) gexp <- .expandGeno(x, hdr, elt, idx) ## rowRanges if (is.null(rd$paramRangeID)) { rdexp <- rd[idx, ] mcols(rdexp) <- NULL } else rdexp <- rd[idx, "paramRangeID"] tmp = VCF(rdexp, colData(x), metadata(x), fexp, iexp, gexp, ..., collapsed=FALSE) # https://github.com/Bioconductor/VariantAnnotation/issues/79 says 'A' should not occur in info(header())$Number nhi = info(header(tmp)) num = nhi$Number inda = grep("A", num) if (length(inda)>0) num[inda] = "1" info(header(tmp))$Number = num tmp } ) .expandGeno <- function(x, hdr, elt, idx) { gvar <- geno(x) if (length(gvar) == 0L) return(gvar) ghdr <- geno(hdr)[rownames(geno(hdr)) %in% names(gvar),] ## 'Number=A': one value per ALT isA <- ghdr$Number == "A" if (any(isA)) { gnms <- rownames(ghdr)[isA] gelt <- do.call(cbind, lapply(gnms, function(i) elt - elementNROWS(gvar[[i]]))) ## elementNROWS same as ALT csums <- colSums(gelt) == 0L if (any(csums)) gvar[gnms[csums]] <- endoapply(gvar[gnms[csums]], function(i) matrix(unlist(i, use.names=FALSE), sum(elt), ncol(i))) ## elementNROWS shorter than ALT if (any(!csums)) { nms <- names(gvar) %in% names(csums)[!csums] reps <- lapply(list(gelt[!csums] + 1L), rep.int, x=seq_len(nrow(x))) gvar[nms] <- mendoapply(gvar[nms], function(d, r) unlist(d[r], use.names=FALSE), r=reps) } gvar } ## AD field: one value for REF and each ALT ## AD (for back-compatibility) and 'Number=A' (ADF/ADR): one value for REF and each ALT isR <- names(gvar) %in% c("AD", rownames(ghdr)[ghdr$Number == "R"]) for(i in which(isR)){ varR <- names(gvar)[i] gvarR <- gvar[[varR]] if (!is.list(gvarR)) { ## 'Number' is integer if (is(gvarR, "array") && length(dim(gvarR)) == 3L) { if ((length(unique(elt)) != 1L) || (dim(gvarR)[3] != unique(elt))) { warning("'", varR, "' was ignored: number of '", varR, "' values ", "do not match REF + ALT") isR[i] <- FALSE } } else { isR[i] <- FALSE } } else { ## 'Number' is '.' gvar[[varR]] <- .expandAD(gvarR, length(idx), ncol(x)) } } isA <- names(gvar) %in% rownames(ghdr)[isA] gvar[!isA & !isR] <- endoapply(gvar[!isA & !isR], function(i) { if (is(i, "matrix")) { matrix(i[idx, ], nrow=length(idx), ncol=ncol(x)) } else { idim <- c(length(idx), dim(i)[2], dim(i)[3]) array(i[idx, , ], dim=idim) }}) gvar } ## returns an array of REF,ALT and REF, pairs ## 'z' dimension of result is always 2 .expandAD <- function(AD, idxlen, xcols) { if (is.list(AD)) { adpart <- PartitioningByWidth(AD) if (any(zeros <- width(adpart) == 0L)) { AD[zeros] <- list(rep(NA_integer_, 2L)) adpart <- PartitioningByWidth(AD) } nalt <- width(adpart) - 1L AD <- unlist(AD, use.names=FALSE) ref <- logical(length(AD)) ref[start(adpart)] <- TRUE vec <- c(rep(AD[ref], nalt), AD[!ref]) array(vec, c(idxlen, xcols, 2L)) } else { AD } } .expandInfo <- function(x, hdr, elt, idx) { ivar <- info(x) ## no data if (ncol(ivar) == 0L) return(DataFrame(row.names=seq_along(idx))) hnms <- intersect(names(ivar), rownames(info(hdr))) inms <- hnms[info(hdr)[hnms, "Number"] == "A"] if (length(inms) > 0L) { ielt <- do.call(cbind, lapply(inms, function(i) elt - elementNROWS(ivar[[i]]))) ## elementNROWS same as ALT csums <- colSums(ielt) == 0L if (any(csums)) res <- S4Vectors:::expandByColumnSet(ivar, inms[csums], TRUE) else res <- ivar[idx, , drop=FALSE] ## elementNROWS shorter than ALT if (any(!csums)) { nms <- colnames(ivar) %in% names(csums)[!csums] reps <- lapply(list(ielt[!csums] + 1L), rep.int, x=seq_len(nrow(x))) res[nms] <- Map(function(d, r) unlist(d[r], use.names=FALSE), ivar[nms], reps) } res } else { ivar[idx, , drop=FALSE] } } .unlistAltInfo <- function(x) { ivar <- info(x) if (ncol(ivar) == 0L) return(ivar) hdr <- header(x) inms <- rownames(info(hdr))[info(hdr)$Number == "A"] inms <- inms[inms %in% names(ivar)] if (length(inms)) return(ivar) ivar[inms] <- lapply(ivar[inms], drop) ivar } setMethod("expand", "ExpandedVCF", function(x, ...) x ) VariantAnnotation/R/methods-ExpandedVCF-class.R0000644000175100017510000000611614614305321022413 0ustar00biocbuildbiocbuild### ========================================================================= ### ExpandedVCF class methods ### ========================================================================= ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Constructor ### ### See VCF(..., collapsed=FALSE) in methods-VCF-class.R ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Getters and Setters ### ### alt() setter setReplaceMethod("alt", c("ExpandedVCF", "DNAStringSet"), function(x, value) { if (length(value) != length(rowRanges(x))) stop("length(value) must equal length(rowRanges(x))") slot(x, "fixed")$ALT <- value x }) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Utilities ### VRangesForMatching <- function(x) { with(rowRanges(x), VRanges(seqnames, IRanges(start, end), ref=REF, alt=ALT)) } setMethod("match", c("ExpandedVCF", "ExpandedVCF"), function(x, table, nomatch = NA_integer_, incomparables = NULL, method = c("auto", "quick", "hash")) { x <- VRangesForMatching(x) table <- VRangesForMatching(table) callGeneric() }) setMethod("match", c("ExpandedVCF", "VRanges"), function(x, table, nomatch = NA_integer_, incomparables = NULL, method = c("auto", "quick", "hash")) { x <- VRangesForMatching(x) callGeneric() }) setMethod("match", c("VRanges", "ExpandedVCF"), function(x, table, nomatch = NA_integer_, incomparables = NULL, method = c("auto", "quick", "hash")) { table <- VRangesForMatching(table) callGeneric() }) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### isSNV family ### .dispatchSNV_ExpandedVCF <- function(FUN, x) { alt <- alt(x) flat <- unlist(alt, use.names=FALSE) gvcf <- structural <- NULL if (is(flat, "character")) { gvcf <- grepl("NON_REF", flat, fixed=TRUE) structural <- .isStructural(flat) } res <- FUN(ref(x), alt) if (!is.null(structural)) res[structural | is.na(structural)] <- FALSE if (any(gvcf)) res[gvcf] <- TRUE res } setMethod("isSNV", "ExpandedVCF", function(x, ...) .dispatchSNV_ExpandedVCF(.isSNV, x) ) setMethod("isInsertion", "ExpandedVCF", function(x, ...) .dispatchSNV_ExpandedVCF(.isInsertion, x) ) setMethod("isDeletion", "ExpandedVCF", function(x, ...) .dispatchSNV_ExpandedVCF(.isDeletion, x) ) setMethod("isIndel", "ExpandedVCF", function(x, ...) .dispatchSNV_ExpandedVCF(.isIndel, x) ) setMethod("isDelins", "ExpandedVCF", function(x, ...) .dispatchSNV_ExpandedVCF(.isDelins, x) ) setMethod("isTransition", "ExpandedVCF", function(x, ...) .dispatchSNV_ExpandedVCF(.isTransition, x) ) setMethod("isSubstitution", "ExpandedVCF", function(x, ...) .dispatchSNV_ExpandedVCF(.isSubstitution, x) ) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### show ### setMethod(show, "ExpandedVCF", function(object) { .showVCFSubclass(object) }) VariantAnnotation/R/methods-filterVcf.R0000644000175100017510000001132714614305321021145 0ustar00biocbuildbiocbuildsetMethod("filterVcf", "character", function(file, genome, destination, ..., verbose=TRUE, index=FALSE, prefilters=FilterRules(), filters=FilterRules(), param=ScanVcfParam()) { if (file.exists(destination)) stop(sprintf("file '%s' exists and will not be over-written", destination)) tbx <- open(TabixFile(file, yieldSize=100000)) on.exit(close(tbx)) filterVcf(tbx, genome=genome, destination=destination, ..., verbose=verbose, index=index, prefilters=prefilters, filters=filters, param=param) }) .unlistScan <- function(...) unlist(scanTabix(...), use.names=FALSE) .prefilter <- function(tbxFile, verbose, prefilters, param, ...) { if (verbose) message("starting prefilter") if (length(vcfWhich(param))) { warning("vcfWhich(param) ignored when using prefilter") vcfWhich(param) <- GRanges() } if (!isOpen(tbxFile)) { open(tbxFile) on.exit(close(tbxFile), add=TRUE) } prefilteredFilename <- tempfile() prefiltered <- file(prefilteredFilename, "w") needsClosing <- TRUE on.exit(if (needsClosing) close(prefiltered), add=TRUE) ## copy header writeLines(headerTabix(tbxFile)$header, prefiltered) ## prefilter param <- vcfWhich(param) nTotal <- 0L while (length(tbxChunk <- .unlistScan(tbxFile, ..., param=param))) { if (verbose) message("prefiltering ", nTotal <- nTotal + length(tbxChunk), " records") tbxChunk <- subsetByFilter(tbxChunk, prefilters) writeLines(tbxChunk, prefiltered) } close(prefiltered) needsClosing <- FALSE prefilteredFilename } .filter <- function(tbxFile, genome, destination, verbose, filters, param, ...) { if (verbose) message("starting filter") destfile <- file(destination, open="w") on.exit(close(destfile), add=TRUE) ## param with defined ranges -> read all if (length(vcfWhich(param))) { yieldSize(tbxFile) <- NA_integer_ vcfChunk <- readVcf(tbxFile, genome, ..., param=param) if (verbose) message("filtering ", nrow(vcfChunk), " records") vcfChunk <- subsetByFilter(vcfChunk, filters) writeVcf(vcfChunk, destfile) ## param with all ranges -> iterate by yieldSize } else { if (!isOpen(tbxFile)) { open(tbxFile) on.exit(close(tbxFile), add=TRUE) } nTotal <- 0L while (nrow(vcfChunk <- readVcf(tbxFile, genome, ..., param=param))) { if (verbose) message("filtering ", nTotal <- nTotal + nrow(vcfChunk), " records") vcfChunk <- subsetByFilter(vcfChunk, filters) writeVcf(vcfChunk, destfile) } } if (verbose) message("completed filtering") destination } setMethod("filterVcf", "TabixFile", function(file, genome, destination, ..., verbose = TRUE, index = FALSE, prefilters = FilterRules(), filters = FilterRules(), param = ScanVcfParam()) { if (!isSingleString(destination)) stop("'destination' must be character(1)") if (!isTRUEorFALSE(verbose)) stop("'verbose' must be TRUE or FALSE") if (!isTRUEorFALSE(index)) stop("'index' must be TRUE or FALSE") if (!length(prefilters) && !length(filters)) stop("no 'prefilters' or 'filters' specified") if (length(prefilters)) { yieldSize <- yieldSize(file) file <- .prefilter(file, verbose, prefilters, param, ...) if(verbose){ message(sprintf("prefiltered to %s", file)) } if (length(filters)) { ## TabixFile needs to be bgzipped and indexed ## FIXME: all records are read at next stage, so no need to index? if (verbose) message("prefilter compressing and indexing ", sQuote(file)) gzFilename <- bgzip(file, overwrite = TRUE) indexTabix(gzFilename, format = "vcf4") file <- TabixFile(gzFilename, yieldSize=yieldSize) } else { ## file.rename does not work across file systems, so be expensive file.copy(file, destination) } } if (length(filters)) { file <- .filter(file, genome, destination, verbose, filters, param, ...) } # if filters if (index) { if (verbose) message("compressing and indexing ", sQuote(file)) gzFilename <- sprintf("%s.bgz", destination) gzFilename <- bgzip(file, gzFilename, overwrite = TRUE) destination <- indexTabix(gzFilename, format = "vcf") unlink(file) } invisible(destination) }) VariantAnnotation/R/methods-genotypeToSnpMatrix.R0000644000175100017510000001632114614305321023223 0ustar00biocbuildbiocbuild### ========================================================================= ### genotypeToSnpMatrix methods ### ========================================================================= ## Coding for snpMatrix : ## 0 = missing OR multiallelic OR multi-ALT values ## 1 = homozygous reference (0|0 or 0/0) ## 2 = heterozygous (0|1 or 0/1 or 1|0 or 1/0) ## 3 = homozygous alternate (risk) allele (1|1 or 1/1) ## empty matrix to return if conditions not met .emptySnpMatrix <- function() { list(genotype=new("SnpMatrix"), map=DataFrame(snp.names=character(), allele.1=DNAStringSet(), allele.2=DNAStringSetList(), ignore=character())) } setMethod("genotypeToSnpMatrix", "CollapsedVCF", function(x, uncertain=FALSE, ...) { ok <- suppressWarnings(require("snpStats", quietly=TRUE, character.only=TRUE)) ok || stop("'snpStats' required; try BiocManager::install('snpStats')", call.=FALSE) alt <- alt(x) if (is(alt, "CompressedCharacterList")) { alt <- .toDNAStringSetList(alt) if (all(elementNROWS(alt) == 0L)) { warning("No nucleotide ALT values were detected.") return(.emptySnpMatrix()) } } ref <- ref(x) if (ncol(x) == 0) { warning("no samples in VCF") } if (!uncertain) { gt <- geno(x)$GT } else { geno.cols <- row.names(geno(metadata(x)[["header"]])) if ("GP" %in% geno.cols) { gt <- geno(x)$GP if (storage.mode(gt) == "list") { gt <- .matrixOfListsToArray(gt) } } else if ("GL" %in% geno.cols) { gt <- geno(x)$GL if (storage.mode(gt) == "list") { gt <- .matrixOfListsToArray(gt) } gt <- GLtoGP(gt) } else if ("PL" %in% geno.cols) { gt <- geno(x)$PL if (mode(gt) == "list") { gt <- .matrixOfListsToArray(gt) } gt <- PLtoGP(gt) } else { warning("uncertain=TRUE requires GP, GL or PL; returning NULL") return(.emptySnpMatrix()) } } callGeneric(gt, ref, alt) }) setMethod("genotypeToSnpMatrix", "array", function(x, ref, alt, ...) { if (!is(ref, "DNAStringSet")) stop("'ref' must be a DNAStringSet") if (!is(alt, "DNAStringSetList")) stop("'alt' must be a DNAStringSetList") # query ref and alt alleles for valid SNPs altelt <- elementNROWS(alt) == 1L snv <- .testForSNV(ref, alt) # if x is a matrix, we have GT with a single value for each snp if (is.matrix(x)) { if (!all(altelt)) { warning("variants with >1 ALT allele are set to NA") x[!altelt,] <- ".|." } if (!all(snv)) { message("non-single nucleotide variations are set to NA") x[!snv,] <- ".|." } map <- .genotypeToIntegerSNV(TRUE) diploid <- x %in% names(map) if (!all(diploid)) { warning("non-diploid variants are set to NA") x[!diploid] <- ".|." } mat <- matrix(map[x], nrow=ncol(x), ncol=nrow(x), byrow=TRUE, dimnames=rev(dimnames(x))) genotypes <- new("SnpMatrix", mat) } else { # if x is a 3D array, we have GP with multiple values for each snp if (!all(altelt)) { warning("variants with >1 ALT allele are set to NA") x[!altelt,,] <- NA } if (!all(snv)) { message("non-single nucleotide variations are set to NA") x[!snv,,] <- NA } # if there is more than one ALT allele for any variant, # the 3rd dimension of the array will be too big # any values here should already have been set to NA above if (dim(x)[3] > 3) { x <- x[,,1:3] } # for each sample, call probabilityToSnpMatrix smlist <- list() for (s in 1:ncol(x)) { sm <- probabilityToSnpMatrix(x[,s,]) rownames(sm) <- colnames(x)[s] smlist[[s]] <- sm } genotypes <- do.call(rbind, smlist) } flt <- !(snv & altelt) map <- .createMap(rownames(x), ref, alt, flt) list(genotypes = genotypes, map = map) }) .createMap <- function(nms, ref, alt, flt) { if (is.null(ref)) DataFrame(snp.names=character(0), allele.1=DNAStringSet(), allele.2=DNAStringSetList(), ignore=logical()) else DataFrame(snp.names=nms, allele.1=ref, allele.2=alt, ignore=flt) } probabilityToSnpMatrix <- function(probs) { requireNamespace("snpStats", quietly = TRUE) || stop("'snpStats' required; try BiocManager::install('snpStats')") if (ncol(probs) != 3) stop("input matrix should have 3 columns: P(A/A), P(A/B), P(B/B)") # skip missing values when checking for validity of probabilities missing <- rowSums(is.na(probs)) > 0 if (!isTRUE(all.equal(rowSums(probs[!missing,,drop=FALSE]), rep(1,sum(!missing)), check.attributes=FALSE, check.names=FALSE))) stop("sum of probabilities in each row of input matrix should = 1") # post2g can't handle missing data if (sum(missing) > 0) { probs[missing,] <- 0 g <- snpStats::post2g(probs) g[missing] <- as.raw(0) } else { g <- snpStats::post2g(probs) } g <- matrix(g, nrow=1, dimnames=list(NULL, rownames(probs))) new("SnpMatrix", g) } GLtoGP <- function(gl) { if (is.matrix(gl) && storage.mode(gl) == "list") { gp <- gl for (i in 1:length(gp)) { gp[[i]] <- 10^gl[[i]] / sum(10^gl[[i]], na.rm=TRUE) } gp } else if (is.array(gl) & length(dim(gl)) == 3) { aperm(apply(gl, c(1,2), function(x) 10^x / sum(10^x, na.rm=TRUE)), c(2,3,1)) } else { stop("gl must be a matrix of lists or a 3D array") } } ## PL is same as GL except for a factor of -10 ## GL = log10(L), PL = -10*log10(L) (phred-scaled) PLtoGP <- function(pl) { if (is.matrix(pl) && storage.mode(pl) == "list") { gl <- pl for (i in 1:length(gl)) { gl[[i]] <- pl[[i]]/(-10) } } else { gl <- pl/(-10) } GLtoGP(gl) } .listMatrixToArray <- function(x) { n <- elementNROWS(x) maxn <- max(n) v <- unlist(x, use.names=FALSE) a <- array(as(NA, class(v)), dim=c(maxn, nrow(x), ncol(x)), dimnames=list(NULL, rownames(x), colnames(x))) a[as.integer(IRanges(seq(1L, length(a), maxn), width=n))] <- v aperm(a, c(2,3,1)) } .matrixOfListsToArray <- function(x) { # find number of elements of each cell of x n <- elementNROWS(x) maxn <- max(n) # for cells with less than the max number of elements, add NAs idx <- n < maxn x[idx] <- lapply(x[idx], function(a){c(a, rep(NA, maxn-length(a)))}) # unlist and convert to array x <- array(unlist(x), dim=c(maxn, nrow(x), ncol(x)), dimnames=list(NULL, rownames(x), colnames(x))) x <- aperm(x, c(2,3,1)) x } VariantAnnotation/R/methods-import.R0000644000175100017510000000053014614305321020525 0ustar00biocbuildbiocbuild### ========================================================================= ### import methods ### ========================================================================= setMethod("import", "VcfFile", function(con, format, text, ...) { if (!missing(format)) rtracklayer:::checkArgFormat(con, format) readVcf(con, ...) }) VariantAnnotation/R/methods-locateVariants.R0000644000175100017510000006027614614305321022207 0ustar00biocbuildbiocbuild### ========================================================================= ### locateVariants methods ### ========================================================================= ### The 8 defined variant regions : ### CodingVariants, IntronVariants, ThreeUTRVariants, FiveUTRVariants, ### IntergenicVariants, SpliceSiteVariants, PromoterVariants, AllVariants ### ### Each region has the following methods : ### query %in% IntegerRanges, VCF, GRanges ### subject %in% TxDb, GRangesList ### ------------------------------------------------------------------------- ### methods applicable to all variant regions ### setMethod("locateVariants", c("IntegerRanges", "TxDb", "VariantType"), function(query, subject, region, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE, asHits=FALSE) { callGeneric(as(query, "GRanges"), subject, region, ..., cache=cache, ignore.strand=ignore.strand, asHits=asHits) }) setMethod("locateVariants", c("IntegerRanges", "GRangesList", "VariantType"), function(query, subject, region, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE, asHits=FALSE) { callGeneric(as(query, "GRanges"), subject, region, ..., cache=cache, ignore.strand=ignore.strand, asHits=asHits) }) setMethod("locateVariants", c("VCF", "TxDb", "VariantType"), function(query, subject, region, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE, asHits=FALSE) { callGeneric(rowRanges(query), subject, region, ..., cache=cache, ignore.strand=ignore.strand, asHits=asHits) }) setMethod("locateVariants", c("VCF", "GRangesList", "VariantType"), function(query, subject, region, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE, asHits=FALSE) { callGeneric(rowRanges(query), subject, region, ..., cache=cache, ignore.strand=ignore.strand, asHits=asHits) }) ### ------------------------------------------------------------------------- ### region = CodingVariants ### setMethod("locateVariants", c("GRanges", "TxDb", "CodingVariants"), function(query, subject, region, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE, asHits=FALSE) { if (!any(seqlevels(query) %in% seqlevels(subject))) return(.returnEmpty()) ## for width(ranges) == 0 : decrement start to equal end value if (any(insertion <- width(query) == 0)) start(query)[insertion] <- start(query)[insertion] - 1 if (!exists("cdsbytx", cache, inherits=FALSE)) cache[["cdsbytx"]] <- cdsBy(subject) res <- callGeneric(query, cache[["cdsbytx"]], region, ..., ignore.strand=ignore.strand, asHits=asHits) if (is(res, "GenomicRanges") & length(res) > 0L) { res$GENEID <- select(subject, as.character(res$TXID), "GENEID", "TXID")$GENEID } res } ) setMethod("locateVariants", c("GRanges", "GRangesList", "CodingVariants"), function(query, subject, region, ..., ignore.strand=FALSE, asHits=FALSE) { .makeResult(query, subject, "coding", ignore.strand=ignore.strand, asHits=asHits) } ) ### ------------------------------------------------------------------------- ### region = IntronVariants ### setMethod("locateVariants", c("GRanges", "TxDb", "IntronVariants"), function(query, subject, region, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE, asHits=FALSE) { if (!any(seqlevels(query) %in% seqlevels(subject))) return(.returnEmpty()) ## for width(ranges) == 0 : decrement start to equal end value if (any(insertion <- width(query) == 0)) start(query)[insertion] <- start(query)[insertion] - 1 if (!exists("intbytx", cache, inherits=FALSE)) cache[["intbytx"]] <- intronsByTranscript(subject) res <- callGeneric(query, cache[["intbytx"]], region, ..., ignore.strand=ignore.strand, asHits=asHits) if (is(res, "GenomicRanges") & length(res) > 0L) { res$GENEID <- select(subject, as.character(res$TXID), "GENEID", "TXID")$GENEID } res } ) setMethod("locateVariants", c("GRanges", "GRangesList", "IntronVariants"), function(query, subject, region, ..., ignore.strand=FALSE, asHits=FALSE) { .makeResult(query, subject, "intron", ignore.strand=ignore.strand, asHits=asHits) } ) ### ------------------------------------------------------------------------- ### region = ThreeUTRVariants ### setMethod("locateVariants", c("GRanges", "TxDb", "ThreeUTRVariants"), function(query, subject, region, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE, asHits=FALSE) { if (!any(seqlevels(query) %in% seqlevels(subject))) return(.returnEmpty()) ## for width(ranges) == 0 : decrement start to equal end value if (any(insertion <- width(query) == 0)) start(query)[insertion] <- start(query)[insertion] - 1 if (!exists("threeUTRbytx", cache, inherits=FALSE)) cache[["threeUTRbytx"]] <- threeUTRsByTranscript(subject) res <- callGeneric(query, cache[["threeUTRbytx"]], region, ..., ignore.strand=ignore.strand, asHits=asHits) if (is(res, "GenomicRanges") & length(res) > 0L) { res$GENEID <- select(subject, as.character(res$TXID), "GENEID", "TXID")$GENEID } res } ) setMethod("locateVariants", c("GRanges", "GRangesList", "ThreeUTRVariants"), function(query, subject, region, ..., ignore.strand=FALSE, asHits=FALSE) { .makeResult(query, subject, "threeUTR", ignore.strand=ignore.strand, asHits=asHits) } ) ### ------------------------------------------------------------------------- ### region = FiveUTRVariants ### setMethod("locateVariants", c("GRanges", "TxDb", "FiveUTRVariants"), function(query, subject, region, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE, asHits=FALSE) { if (!any(seqlevels(query) %in% seqlevels(subject))) return(.returnEmpty()) ## for width(ranges) == 0 : decrement start to equal end value if (any(insertion <- width(query) == 0)) start(query)[insertion] <- start(query)[insertion] - 1 if (!exists("fiveUTRbytx", cache, inherits=FALSE)) cache[["fiveUTRbytx"]] <- fiveUTRsByTranscript(subject) res <- callGeneric(query, cache[["fiveUTRbytx"]], region, ..., ignore.strand=ignore.strand, asHits=asHits) if (is(res, "GenomicRanges") & length(res) > 0L) { res$GENEID <- select(subject, as.character(res$TXID), "GENEID", "TXID")$GENEID } res } ) setMethod("locateVariants", c("GRanges", "GRangesList", "FiveUTRVariants"), function(query, subject, region, ..., ignore.strand=FALSE, asHits=FALSE) { .makeResult(query, subject, "fiveUTR", ignore.strand=ignore.strand, asHits=asHits) } ) ### ------------------------------------------------------------------------- ### region = IntergenicVariants ### setMethod("locateVariants", c("GRanges", "TxDb", "IntergenicVariants"), function(query, subject, region, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE) { if (!any(seqlevels(query) %in% seqlevels(subject))) return(.returnEmpty()) ## for width(ranges) == 0 : decrement start to equal end value if (any(insertion <- width(query) == 0)) start(query)[insertion] <- start(query)[insertion] - 1 ## PRECEDEID and FOLLOWID as gene or transcript ids if (idType(region) == "gene") { if (!exists("txbygene", cache, inherits=FALSE)) cache[["txbygene"]] <- transcriptsBy(subject, "gene") callGeneric(query, cache[["txbygene"]], region, ..., ignore.strand=ignore.strand) } else if (idType(region) == "tx") { tx <- transcripts(subject) names(tx) <- mcols(tx)$tx_id callGeneric(query, as(tx, "GRangesList"), region, ..., ignore.strand=ignore.strand) } else { stop("'idType' must be one of 'gene' or 'tx'") } } ) setMethod("locateVariants", c("GRanges", "GRangesList", "IntergenicVariants"), function(query, subject, region, ..., ignore.strand=FALSE) { .intergenic(query, subject, region, ignore.strand=ignore.strand) } ) ### ------------------------------------------------------------------------- ## region = SpliceSiteVariants ## setMethod("locateVariants", c("GRanges", "TxDb", "SpliceSiteVariants"), function(query, subject, region, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE, asHits=FALSE) { if (!any(seqlevels(query) %in% seqlevels(subject))) return(.returnEmpty()) ## for width(ranges) == 0 : decrement start to equal end value if (any(insertion <- width(query) == 0)) start(query)[insertion] <- start(query)[insertion] - 1 if (!exists("intbytx", cache, inherits=FALSE)) cache[["intbytx"]] <- intronsByTranscript(subject) res <- callGeneric(query, cache[["intbytx"]], region, ..., ignore.strand=ignore.strand, asHits=asHits) if (is(res, "GenomicRanges") & length(res) > 0L) { res$GENEID <- select(subject, as.character(res$TXID), "GENEID", "TXID")$GENEID } res } ) setMethod("locateVariants", c("GRanges", "GRangesList", "SpliceSiteVariants"), function(query, subject, region, ..., ignore.strand=FALSE, asHits=FALSE) { .spliceSites(query, subject, ignore.strand=ignore.strand, asHits=asHits) } ) ### ------------------------------------------------------------------------- ### region = PromoterVariants ### setMethod("locateVariants", c("GRanges", "TxDb", "PromoterVariants"), function(query, subject, region, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE, asHits=FALSE) { if (!any(seqlevels(query) %in% seqlevels(subject))) return(.returnEmpty()) ## for width(ranges) == 0 : decrement start to equal end value if (any(insertion <- width(query) == 0)) start(query)[insertion] <- start(query)[insertion] - 1 if (!exists("tx", cache, inherits=FALSE)) { tx <- transcripts(subject) cache[["tx"]] <- splitAsList(tx, seq_len(length(tx))) names(cache[["tx"]]) <- tx$tx_id } res <- callGeneric(query, cache[["tx"]], region, ..., ignore.strand=ignore.strand, asHits=asHits) if (is(res, "GenomicRanges") & length(res) > 0L) { if (!is.null(res$TXID)) res$GENEID <- select(subject, as.character(res$TXID), "GENEID", "TXID")$GENEID } res } ) setMethod("locateVariants", c("GRanges", "GRangesList", "PromoterVariants"), function(query, subject, region, ..., ignore.strand=FALSE, asHits=FALSE) { if (is.null(txid <- names(subject))) txid <- NA_integer_ usub <- unlist(subject, use.names=FALSE) pm <- promoters(usub, upstream(region), downstream(region)) fo <- findOverlaps(query, pm, type="within", ignore.strand=ignore.strand) if (asHits) return(.consolidateHits(fo, length(query), length(subject), elementNROWS(subject))) if (length(fo) > 0) { queryid <- queryHits(fo) GRanges(seqnames=seqnames(query)[queryid], ranges=IRanges(ranges(query)[queryid]), strand=strand(pm)[subjectHits(fo)], LOCATION=.location(length(queryid), "promoter"), LOCSTART=NA_integer_, LOCEND=NA_integer_, QUERYID=queryid, TXID=as.integer(txid[subjectHits(fo)]), CDSID=IntegerList(integer(0)), GENEID=NA_character_, PRECEDEID=CharacterList(character(0)), FOLLOWID=CharacterList(character(0))) } else { res <- GRanges() values(res) <- DataFrame(LOCATION=.location(), LOCSTART=integer(), LOCEND=integer(), QUERYID=integer(), TXID=integer(), CDSID=IntegerList(), GENEID=character(), PRECEDEID=CharacterList(), FOLLOWID=CharacterList()) res } } ) ### ------------------------------------------------------------------------- ### region = AllVariants ### setMethod("locateVariants", c("GRanges", "TxDb", "AllVariants"), function(query, subject, region, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE) { if (!any(seqlevels(query) %in% seqlevels(subject))) return(.returnEmpty()) cache[["mask"]] <- TRUE coding <- locateVariants(query, subject, CodingVariants(), cache=cache, ignore.strand=ignore.strand) intron <- locateVariants(query, subject, IntronVariants(), cache=cache, ignore.strand=ignore.strand) splice <- locateVariants(query, subject, SpliceSiteVariants(), cache=cache, ignore.strand=ignore.strand) promoter <- locateVariants(query, subject, PromoterVariants(upstream(promoter(region)), downstream(promoter(region))), cache=cache, ignore.strand=ignore.strand) ## Consolidate calls for UTR data: if (!exists("fiveUTRbytx", cache, inherits=FALSE)) { splicings <- GenomicFeatures:::.getSplicingsForTranscriptsWithCDSs(subject) cache[["fiveUTRbytx"]] <- GenomicFeatures:::.make5UTRsByTranscript(subject, splicings) } if (!exists("threeUTRbytx", cache, inherits=FALSE)) cache[["threeUTRbytx"]] <- GenomicFeatures:::.make3UTRsByTranscript(subject, splicings) fiveUTR <- locateVariants(query, subject, FiveUTRVariants(), cache=cache, ignore.strand=ignore.strand) threeUTR <- locateVariants(query, subject, ThreeUTRVariants(), cache=cache, ignore.strand=ignore.strand) intergenic <- locateVariants(query, subject, IntergenicVariants(upstream(intergenic(region)), downstream(intergenic(region)), idType(intergenic(region))), cache=cache, ignore.strand=ignore.strand) ans <- c(coding, intron, fiveUTR, threeUTR, splice, promoter, intergenic) meta <- values(ans) ans[order(meta$QUERYID, meta$TXID, meta$GENEID), ] } ) ### ------------------------------------------------------------------------- ### helpers ### .returnEmpty <- function() { warning("none of seqlevels(query) match seqlevels(subject)") res <- GRanges() values(res) <- DataFrame(LOCATION=.location(), LOCSTART=integer(), LOCEND=integer(), QUERYID=integer(), TXID=integer(), CDSID=IntegerList(), GENEID=character(), PRECEDEID=CharacterList(), FOLLOWID=CharacterList()) res } .location <- function(length=0, value=NA) { levels <- c("spliceSite", "intron", "fiveUTR", "threeUTR", "coding", "intergenic", "promoter") factor(rep(value, length), levels=levels) } .spliceSites <- function(query, subject, ignore.strand, asHits, ...) { ## Overlap any portion of first 2 and last 2 nucleotides of introns. usub <- unlist(subject, use.names=FALSE) int_start <- GRanges(seqnames(usub), IRanges(start(usub), start(usub) + 1), strand=strand(usub)) int_end <- GRanges(seqnames(usub), IRanges(end(usub) - 1, end(usub)), strand=strand(usub)) fo_start <- findOverlaps(query, int_start, type="any", ignore.strand=ignore.strand) fo_end <- findOverlaps(query, int_end, type="any", ignore.strand=ignore.strand) fo <- union(fo_start, fo_end) if (asHits) return(.consolidateHits(fo, length(query), length(subject), elementNROWS(subject))) if (length(fo) > 0) { df <- unique(data.frame( queryid=queryHits(fo), subjectid=togroup(PartitioningByWidth(subject))[subjectHits(fo)] )) GRanges(seqnames=seqnames(query)[df$queryid], ranges=IRanges(ranges(query)[df$queryid]), strand=unlist(strand(subject), use.names=FALSE)[df$subjectid], LOCATION=.location(length(df$queryid), "spliceSite"), LOCSTART=NA_integer_, LOCEND=NA_integer_, QUERYID=df$queryid, TXID=as.integer(names(subject)[df$subjectid]), CDSID=IntegerList(integer(0)), GENEID=NA_character_, PRECEDEID=CharacterList(character(0)), FOLLOWID=CharacterList(character(0))) } else { res <- GRanges() values(res) <- DataFrame(LOCATION=.location(), LOCSTART=integer(), LOCEND=integer(), QUERYID=integer(), TXID=integer(), CDSID=IntegerList(), GENEID=character(), PRECEDEID=CharacterList(), FOLLOWID=CharacterList()) res } } .consolidateHits <- function(hits, qlen, slen, elen, ...) { txid <- rep(seq_len(slen), elen) dat <- cbind(queryHits(hits), as.integer(txid[subjectHits(hits)])) unq <- dat[!duplicated(dat),] return(Hits(unq[,1], unq[,2], qlen, slen, sort.by.query=TRUE)) } .intergenic <- function(query, subject, region, ignore.strand, ...) { s_range <- range(subject) ## avoid duplicates co <- unname(countOverlaps(query, s_range, type="any", ignore.strand=ignore.strand)) ## variants that don't hit a gene feature AND ## zero-width ranges return '0' has_width <- width(query) != 0L intergenic <- co == 0 & has_width if (all(!intergenic | (length(subject) == 0L))) { res <- GRanges() values(res) <- DataFrame(LOCATION=.location(), LOCSTART=integer(), LOCEND=integer(), QUERYID=integer(), TXID=integer(), CDSID=IntegerList(), GENEID=character(), PRECEDEID=CharacterList(), FOLLOWID=CharacterList()) res } else { q_range <- query[intergenic] s_genes <- rep(names(subject), elementNROWS(s_range)) s_unlist <- unlist(s_range, use.names=FALSE) ## ID all genes that fall in upstream / downstream range. ## upstream == follow: f_range <- .shiftRangeUpDown(q_range, upstream(region), TRUE) f_fo <- findOverlaps(f_range, s_unlist, ignore.strand=ignore.strand) f_factor <- factor(queryHits(f_fo), seq_len(queryLength(f_fo))) f_genes <- unname(splitAsList(s_genes[subjectHits(f_fo)], f_factor)) ## downstream == precede: p_range <- .shiftRangeUpDown(q_range, downstream(region), FALSE) p_fo <- findOverlaps(p_range, s_unlist, ignore.strand=ignore.strand) p_factor <- factor(queryHits(p_fo), seq_len(queryLength(p_fo))) p_genes <- unname(splitAsList(s_genes[subjectHits(p_fo)], p_factor)) if (ignore.strand) strand(q_range) <- "*" values(q_range) <- DataFrame(LOCATION=.location(length(q_range), "intergenic"), LOCSTART=NA_integer_, LOCEND=NA_integer_, QUERYID=which(intergenic), TXID=NA_integer_, CDSID=IntegerList(integer(0)), GENEID=NA_character_, PRECEDEID=p_genes, FOLLOWID=f_genes) q_range } } ## Behaves like flank(); ranges do not include start/end values. .shiftRangeUpDown <- function(x, distance, upstream=TRUE) { on_plus <- which(strand(x) == "+" | strand(x) == "*") on_minus <- which(strand(x) == "-") if (upstream) { ## '+' strand on_plus_end <- start(x)[on_plus] - 1L on_plus_start <- start(x)[on_plus] - distance ## '-' strand on_minus_start <- end(x)[on_minus] + 1L on_minus_end <- end(x)[on_minus] + distance } else { ## '+' strand on_plus_start <- end(x)[on_plus] + 1L on_plus_end <- end(x)[on_plus] + distance ## '-' strand on_minus_start <- start(x)[on_minus] - distance on_minus_end <- start(x)[on_minus] - 1L } start(x)[on_plus] <- on_plus_start end(x)[on_plus] <- on_plus_end start(x)[on_minus] <- on_minus_start end(x)[on_minus] <- on_minus_end x } .makeResult <- function(query, subject, vtype, ignore.strand, asHits) { if (asHits) return(findOverlaps(query, subject, type="within", ignore.strand=ignore.strand)) map <- mapToTranscripts(unname(query), subject, ignore.strand=ignore.strand) if (length(map) > 0) { xHits <- map$xHits txHits <- map$transcriptsHits tx <- names(subject)[txHits] if (!is.null(tx)) txid <- tx else txid <- NA_integer_ ## FIXME: cdsid is expensive cdsid <- IntegerList(integer(0)) ## CodingVariants() must fall within a coding region. ## mapToTranscripts() will map ranges that span intron ## junctions and overlap multiple exons/cds regions. Because ## of this, it's possible for 'map' to return a hit for a ## query that 'map2' will not. (The subject in ## 'map' is a GRangesList and in 'map2' it's unlisted.) ## Only ranges identified by 'map' and 'map2' are kept. ## Ranges identified by 'map' only are discarded. if (vtype == "coding") { usub <- unlist(subject) ## names needed for mapping map2 <- mapToTranscripts(unname(query)[xHits], usub, ignore.strand=ignore.strand) cds <- mcols(usub)$cds_id[map2$transcriptsHits] if (length(cds)) { cdsid <- unique(splitAsList(cds, map2$xHits)) keep <- logical(length(xHits)) keep[unique(map2$xHits)] <- TRUE if (any(!keep)) { map <- map[keep] txHits <- map$transcriptsHits xHits <- map$xHits txid <- txid[keep] } } } ss <- runValue(strand(subject)[txHits]) if (any(elementNROWS(ss) > 1L)) { warning("'subject' has multiple strands per list element; ", "setting strand to '*'") sstrand <- Rle("*", length(txHits)) } sstrand <- unlist(ss, use.names=FALSE) GRanges(seqnames=seqnames(query)[xHits], ranges=IRanges(ranges(query)[xHits]), strand=sstrand, LOCATION=.location(length(xHits), vtype), LOCSTART=start(map), LOCEND=end(map), QUERYID=xHits, TXID=txid, CDSID=cdsid, GENEID=NA_character_, PRECEDEID=CharacterList(character(0)), FOLLOWID=CharacterList(character(0))) } else { res <- GRanges() mcols(res) <- DataFrame(LOCATION=.location(), LOCSTART=integer(), LOCEND=integer(), QUERYID=integer(), TXID=integer(), CDSID=IntegerList(), GENEID=character(), PRECEDEID=CharacterList(), FOLLOWID=CharacterList()) res } } VariantAnnotation/R/methods-PolyPhenDb-class.R0000644000175100017510000000653514614305321022335 0ustar00biocbuildbiocbuild### ========================================================================= ### PolyPhenDb methods ### ========================================================================= setMethod("keys", "PolyPhenDb", function(x) { sql <- paste("SELECT RSID FROM ppdata ", sep="") unique(dbGetQuery(x$conn, sql))[,1] } ) setMethod("columns", "PolyPhenDb", function(x) { dbListFields(conn=x$conn, "ppdata") } ) setMethod("select", "PolyPhenDb", function(x, keys, columns, keytype, ...) { sql <- .createPPDbQuery(x, keys, columns) if (length(sql)) { raw <- dbGetQuery(x$conn, sql) .formatPPDbSelect(raw, keys) } else { data.frame() } } ) .createPPDbQuery <- function(x, keys, cols) { if (missing(keys) && missing(cols)) { sql <- "SELECT * FROM ppdata" } if (!missing(keys)) { if(.missingKeys(x, keys, "PolyPhen")) return(character()) if (!missing(cols)) { if (.missingCols(x, cols, "PolyPhen")) return(character()) if (!"RSID" %in% cols) cols <- c("RSID", cols) fmtcols <- paste(cols, collapse=",") fmtkeys <- .sqlIn(keys) sql <- paste("SELECT ", fmtcols, " FROM ppdata WHERE RSID IN (", fmtkeys, ")", sep="") } else { fmtkeys <- .sqlIn(keys) sql <- paste("SELECT * FROM ppdata WHERE RSID IN (", fmtkeys, ")", sep="") } } else { if (.missingCols(x, cols, "PolyPhen")) return(character()) if (!"RSID" %in% cols) cols <- c("RSID", cols) fmtcols <- paste(cols, collapse=",") sql <- paste("SELECT ", fmtcols, " FROM ppdata", sep="") } sql } .formatPPDbSelect <- function(raw, keys) { ## no data if (!nrow(raw)) return(data.frame()) if (missing(keys)) { df <- data.frame(raw) rownames(df) <- NULL df } else { ## restore key order missing <- (!keys %in% as.character(raw$RSID)) lst <- as.list(rep(NA_character_, length(keys))) raw <- raw[!duplicated(raw), ] for (i in which(missing == FALSE)) lst[[i]] <- raw[raw$RSID %in% keys[i], ] df <- do.call(rbind, lst) df$RSID[is.na(df$RSID)] <- keys[missing] rownames(df) <- NULL df } } duplicateRSID <- function(db, keys, ...) { fmtrsid <- .sqlIn(keys) sql <- paste("SELECT * FROM duplicates WHERE RSID IN (", fmtrsid, ")", sep="") q1 <- dbGetQuery(db$conn, sql) fmtgp <- .sqlIn(unique(q1$DUPLICATEGROUP)) gpsql <- paste("SELECT * FROM duplicates WHERE DUPLICATEGROUP IN (", fmtgp, ")", sep="") q2 <- dbGetQuery(db$conn, gpsql) matched <- q2[!q2$RSID %in% keys, ] matchedlst <- split(matched$RSID, matched$DUPLICATEGROUP) names(matchedlst) <- q1$RSID[match(names(matchedlst), q1$DUPLICATEGROUP)] missing <- !keys %in% q2$RSID if (any(missing)) { warning(paste("keys not found in database : ", keys[missing], sep="")) missinglst <- list(rep(NA, sum(missing))) names(missinglst) <- keys[missing] matchedlst <- c(matchedlst, missinglst) } matchedlst[order(match(names(matchedlst), keys))] } VariantAnnotation/R/methods-predictCoding.R0000644000175100017510000001766014614305321022005 0ustar00biocbuildbiocbuild### ========================================================================= ### predictCoding methods ### ========================================================================= setMethod("predictCoding", c("IntegerRanges", "TxDb", "ANY", "DNAStringSet"), function(query, subject, seqSource, varAllele, ..., ignore.strand=FALSE) { callGeneric(as(query, "GRanges"), subject, seqSource, varAllele, ..., ignore.strand=ignore.strand) }) setMethod("predictCoding", c("CollapsedVCF", "TxDb", "ANY", "missing"), function(query, subject, seqSource, varAllele, ..., ignore.strand=FALSE) { rd <- rowRanges(query) alt <- alt(query) if (is(alt, "CharacterList")) { alt <- .toDNAStringSetList(alt) if (sum(elementNROWS(alt)) == 0L) { stop("No nucleotide ALT values were detected.") } } rd <- rep(rowRanges(query), elementNROWS(alt)) res <- callGeneric(rd, subject, seqSource, unlist(alt, use.names=FALSE), ..., ignore.strand=ignore.strand) ## adjust QUERYID for expansion of rowRanges res$QUERYID <- rep(seq_len(length(alt)), elementNROWS(alt))[res$QUERYID] res }) setMethod("predictCoding", c("ExpandedVCF", "TxDb", "ANY", "missing"), function(query, subject, seqSource, varAllele, ..., ignore.strand=FALSE) { if (is(alt(query), "CharacterList")) { stop("alt(query) must be a DNAStringSet (not a CharacterList)") } callGeneric(rowRanges(query), subject, seqSource, alt(query), ..., ignore.strand=ignore.strand) }) setMethod("predictCoding", c("GRanges", "TxDb", "ANY", "DNAStringSet"), function(query, subject, seqSource, varAllele, ..., ignore.strand=FALSE) { .predictCoding(query, subject, seqSource, varAllele, ..., ignore.strand=ignore.strand) }) setMethod("predictCoding", c("VRanges", "TxDb", "ANY", "missing"), function(query, subject, seqSource, varAllele, ..., ignore.strand=FALSE) { varAllele <- alt(query) query <- as(query, "GRanges") if (!is(varAllele, "DNAStringSet")) { tryCatch({ varAllele <- DNAStringSet(varAllele) }, error=function(e) { stop(paste0("attempt to coerce 'alt' to DNAStringSet failed with ", "error: ", conditionMessage(e))) }) } .predictCoding(query, subject, seqSource, varAllele, ..., ignore.strand=ignore.strand) }) .predictCoding <- function(query, subject, seqSource, varAllele, ..., cache=new.env(parent=emptyenv()), ignore.strand=FALSE) { stopifnot(length(varAllele) == length(query)) if (!any(seqlevels(query) %in% seqlevels(subject))) warning("none of seqlevels(query) match seqlevels(subject)") if (!exists(".__init__", cache, inherits=FALSE)) { cache[["cdsbytx"]] <- cdsBy(subject) cache[["txbygene"]] <- transcriptsBy(subject, "gene") cache[[".__init__"]] <- TRUE } map <- data.frame(geneid=rep(names(cache[["txbygene"]]), elementNROWS(cache[["txbygene"]])), txid=mcols(unlist(cache[["txbygene"]], use.names=FALSE))[["tx_id"]], stringsAsFactors=FALSE) txlocal <- .predictCodingGRangesList(query, cache[["cdsbytx"]], seqSource, varAllele, ..., ignore.strand=ignore.strand) txid <- mcols(txlocal)$TXID mcols(txlocal)$GENEID <- map$geneid[match(txid, map$txid)] txlocal } .predictCodingGRangesList <- function(query, cdsbytx, seqSource, varAllele, ..., genetic.code=GENETIC_CODE, if.fuzzy.codon="error", ignore.strand=FALSE) { if (ignore.strand) strand(query) <- "*" ## variant location in cds region mcols(query) <- append(mcols(query), DataFrame(varAllele=varAllele)) txlocal <- .localCoordinates(query, cdsbytx, ignore.strand=FALSE, ...) if (length(txlocal) == 0) return(txlocal) ## reverse complement "-" strand valid <- rep(TRUE, length(txlocal)) nstrand <- as.vector(strand(txlocal) == "-") if (any(nstrand)) { va <- mcols(txlocal)$varAllele va[nstrand] <- reverseComplement(va[valid & nstrand]) mcols(txlocal)$varAllele <- va } ## frameshift refwidth <- width(txlocal) altallele <- mcols(txlocal)$varAllele fmshift <- abs(width(altallele) - refwidth) %% 3 != 0 if (any(fmshift)) valid[fmshift] <- FALSE ## zero-width zwidth <- width(altallele) == 0 if (any(zwidth)) { warning("records with missing 'varAllele' were ignored") valid[zwidth] <- FALSE fmshift[zwidth] <- FALSE } ## reference codon sequences altpos <- (start(mcols(txlocal)$CDSLOC) - 1L) %% 3L + 1L refCodon <- varCodon <- .getRefCodons(txlocal, altpos, seqSource, cdsbytx) ## allowed characters that can't be translated ## "N", ".", "+" and "-" pattern <- "N|\\.|\\+|\\-" altCheck <- grepl(pattern, as.character(altallele, use.names=FALSE)) refCheck <- grepl(pattern, as.character(refCodon, use.names=FALSE)) noTrans <- rep(FALSE, length(txlocal)) noTrans[altCheck | refCheck] <- TRUE valid[noTrans] <- FALSE if (any(altCheck)) warning("'varAllele' values with 'N', '.', '+' or '-'", " were not translated") if (any(refCheck)) warning("reference codons with 'N', '.', '+' or '-'", " were not translated") ## substitute and translate refAA <- varAA <- AAStringSet(rep("", length(txlocal))) if (any(valid)) { ## 2 genetic.code versions alt.init.codons <- attr(genetic.code, "alt_init_codons") gc <- genetic.code gc.no.alt.init.codons <- genetic.code attr(gc.no.alt.init.codons, "alt_init_codons") <- character() ## ignore alt_init_codons subseq(varCodon, altpos, width=refwidth) <- altallele refAA[valid] <- translate(refCodon[valid], genetic.code=gc.no.alt.init.codons, if.fuzzy.codon=if.fuzzy.codon) varAA <- AAStringSet(rep("", length(txlocal))) varAA[valid] <- translate(varCodon[valid], genetic.code=gc.no.alt.init.codons, if.fuzzy.codon=if.fuzzy.codon) ## respect alt_init_codons at the start of the CDS cds.start <- start(txlocal$CDSLOC) == 1L varAA.to.modify <- varCodon %in% alt.init.codons & cds.start refAA.to.modify <- refCodon %in% alt.init.codons & cds.start if (any(cds.start)) { varAA[varCodon %in% alt.init.codons & cds.start] <- "M" refAA[refCodon %in% alt.init.codons & cds.start] <- "M" } } ## results nonsynonymous <- as.character(refAA) != as.character(varAA) consequence <- rep("synonymous", length(txlocal)) consequence[nonsynonymous] <- "nonsynonymous" consequence[fmshift] <- "frameshift" consequence[nonsynonymous & (as.character(varAA) %in% "*")] <- "nonsense" consequence[zwidth | noTrans] <- "not translated" consequence <- factor(consequence) mcols(txlocal) <- append(mcols(txlocal), DataFrame(GENEID=NA_character_, CONSEQUENCE=consequence, REFCODON=refCodon, VARCODON=varCodon, REFAA=refAA, VARAA=varAA)) txlocal } .getRefCodons <- function(txlocal, altpos, seqSource, cdsbytx) { ## adjust codon end for ## - width of the reference sequence ## - position of alt allele substitution in the codon cstart <- ((start(mcols(txlocal)$CDSLOC) - 1L) %/% 3L) * 3L + 1L cend <- cstart + (((altpos + width(txlocal) - 2L) %/% 3L) * 3L + 2L) txord <- match(mcols(txlocal)$TXID, names(cdsbytx)) txseqs <- extractTranscriptSeqs(seqSource, cdsbytx[txord]) DNAStringSet(substring(txseqs, cstart, cend)) } VariantAnnotation/R/methods-PROVEANDb.class.R0000644000175100017510000000576414614305321021715 0ustar00biocbuildbiocbuild### ======================================================================== ### PROVEANDb methods ### ========================================================================= setMethod("keys", "PROVEANDb", function(x, keytype, ...) { if (missing(keytype)) keytype <- "DBSNPID" sql <- paste("SELECT DISTINCT ", keytype, " FROM proveandata ", sep="") dbGetQuery(x$conn, sql)[,1] } ) setMethod("columns", "PROVEANDb", function(x) dbListFields(x$conn, "proveandata") ) setMethod("keytypes", "PROVEANDb", function(x) "DBSNPID" ) setMethod("select", "PROVEANDb", function(x, keys, columns, keytype, ...) { if (missing(keytype)) keytype <- "DBSNPID" sql <- .createPROVEANDbQuery(x, keys, columns, keytype) if (length(sql)) { raw <- dbGetQuery(x$conn, sql) .formatPROVEANDbSelect(raw, keys, columns, keytype) } else { data.frame() } } ) .createPROVEANDbQuery <- function(x, keys, columns, keytype) { if (missing(keys) && missing(columns)) { sql <- "SELECT * FROM proveandata" } if (!missing(keys)) { if(.missingKeys(x, keys, "PROVEAN")) return(character()) if (!missing(columns)) { if (.missingCols(x, columns, "PROVEAN")) return(character()) columns <- union(keytype, columns) fmtcols <- paste(columns, collapse=",") fmtkeys <- .sqlIn(keys) sql <- paste("SELECT ", fmtcols, " FROM proveandata WHERE ", keytype, " IN (", fmtkeys, ")", sep="") } else { fmtkeys <- .sqlIn(keys) sql <- paste("SELECT * FROM proveandata WHERE ", keytype, " IN (", fmtkeys, ")", sep="") } } else { if (.missingCols(x, columns, db="PROVEAN")) return(character()) columns <- union(keytype, columns) fmtcols <- paste(columns, collapse=",") sql <- paste("SELECT ", fmtcols, " FROM proveandata", sep="") } sql } .formatPROVEANDbSelect <- function(raw, keys, columns, keytype) { ## no data if (!nrow(raw)) return(data.frame()) ## remove duplicate rows if (any(dup <- duplicated(raw))) raw <- raw[!dup, ] ## reorder columns if (!missing(columns)) { if (!keytype %in% columns) columns <- c(keytype, columns) raw <- raw[,colnames(raw) %in% columns] } ## return keys not found index <- unique(raw[[keytype]]) missing <- rep(FALSE, length(index)) if (!missing(keys)) { missing <- (!keys %in% as.character(index)) lst <- as.list(rep(NA_character_, length(keys))) for (i in which(missing == FALSE)) lst[[i]] <- raw[raw[[keytype]] %in% keys[i], ] df <- do.call(rbind, lst) df[[keytype]][is.na(df[[keytype]])] <- keys[missing] rownames(df) <- NULL df } else { rownames(raw) <- NULL raw } } VariantAnnotation/R/methods-readVcf.R0000644000175100017510000001661414614305321020577 0ustar00biocbuildbiocbuild### ========================================================================= ### readVcf methods ### ========================================================================= ## TabixFile setMethod(readVcf, c(file="TabixFile", param="ScanVcfParam"), function(file, genome, param, ..., row.names=TRUE) { .readVcf(file, genome, param, row.names=row.names, ...) }) setMethod(readVcf, c(file="TabixFile", param="GRanges"), function(file, genome, param, ..., row.names=TRUE) { .readVcf(file, genome, param=ScanVcfParam(which=param), row.names=row.names, ...) }) setMethod(readVcf, c(file="TabixFile", param="GRangesList"), function(file, genome, param, ..., row.names=TRUE) { .readVcf(file, genome, param=ScanVcfParam(which=param), row.names=row.names, ...) }) setMethod(readVcf, c(file="TabixFile", param="IntegerRangesList"), function(file, genome, param, ..., row.names=TRUE) { .readVcf(file, genome, param=ScanVcfParam(which=param), row.names=row.names, ...) }) setMethod(readVcf, c(file="TabixFile", param="missing"), function(file, genome, param, ..., row.names=TRUE) { .readVcf(file, genome, param=ScanVcfParam(), row.names=row.names, ...) }) ## character setMethod(readVcf, c(file="character", param="ANY"), function(file, genome, param, ..., row.names=TRUE) { file <- .checkFile(file) .readVcf(file, genome, param, row.names=row.names, ...) }) setMethod(readVcf, c(file="character", param="missing"), function(file, genome, param, ..., row.names=TRUE) { file <- .checkFile(file) .readVcf(file, genome, param=ScanVcfParam(), row.names=row.names, ...) }) .checkFile <- function(x) { if (1L != length(x)) stop("'x' must be character(1)") ## Tabix index supplied as 'file' if (grepl("\\.tbi$", x)) return(TabixFile(sub("\\.tbi", "", x))) ## Attempt to create TabixFile tryCatch(x <- TabixFile(x), error=function(e) return(x)) x } .readVcf <- function(file, genome, param, row.names, ...) { if (missing(genome)) genome <- seqinfo(scanVcfHeader(file)) if (!is(genome, "character") & !is(genome, "Seqinfo")) stop("'genome' must be a 'character(1)' or 'Seqinfo' object") if (is(genome, "Seqinfo")) { if (is(param, "ScanVcfParam")) chr <- names(vcfWhich(param)) else chr <- seqlevels(param) ## confirm param seqlevels are in supplied Seqinfo if (any(!chr %in% seqnames(genome))) stop("'seqnames' in 'vcfWhich(param)' must be present in 'genome'") } .scanVcfToVCF(scanVcf(file, param=param, row.names=row.names, ...), file, genome, param) } .scanVcfToVCF <- function(vcf, file, genome, param, ...) { hdr <- scanVcfHeader(file) if (length(vcf[[1]]$GENO) > 0L) colnms <- colnames(vcf[[1]]$GENO[[1]]) else colnms <- NULL vcf <- .collapseLists(vcf, param) ## rowRanges rowRanges <- vcf$rowRanges if (length(rowRanges)) { if (is(genome, "character")) { if (length(seqinfo(hdr))) { merged <- merge(seqinfo(hdr), seqinfo(rowRanges)) map <- match(names(merged), names(seqinfo(rowRanges))) seqinfo(rowRanges, map) <- merged } genome(rowRanges) <- genome } else if (is(genome, "Seqinfo")) { if (length(seqinfo(hdr))) reference <- merge(seqinfo(hdr), genome) else reference <- genome merged <- merge(reference, seqinfo(rowRanges)) map <- match(names(merged), names(seqinfo(rowRanges))) seqinfo(rowRanges, map) <- merged } } values(rowRanges) <- DataFrame(vcf["paramRangeID"]) ## fixed fields fx <- vcf[c("REF", "ALT", "QUAL", "FILTER")] fx$ALT <- .formatALT(fx$ALT) fixed <- DataFrame(fx[!sapply(fx, is.null)]) ## info info <- .formatInfo(vcf$INFO, info(hdr), length(rowRanges)) ## colData colData <- DataFrame(Samples=seq_along(colnms), row.names=colnms) ## geno geno <- SimpleList(lapply(vcf$GENO, `dimnames<-`, NULL)) vcf <- NULL VCF(rowRanges=rowRanges, colData=colData, exptData=list(header=hdr), fixed=fixed, info=info, geno=geno) } ## lightweight read functions retrieve a single variable .geno2geno <- function(lst, ALT=NULL, REF=NULL, GT=NULL) { if (is.null(ALT) && is.null(REF) && is.null(GT)) { ALT <- lst$ALT REF <- as.character(lst$REF, use.names=FALSE) GT <- lst$GENO$GT } res <- GT ## ignore records with GT ".|." if (any(missing <- grepl(".", GT, fixed=TRUE))) GT[missing] <- ".|." phasing <- rep("|", length(GT)) phasing[grepl("/", GT, fixed=TRUE)] <- "/" ## replace GTstr <- strsplit(as.vector(GT), "[|,/]") if (any(elementNROWS(GTstr) !=2)) stop("only diploid variants are supported") GTmat <- matrix(unlist(GTstr), ncol=2, byrow=TRUE) GTA <- suppressWarnings(as.numeric(GTmat[,1])) GTB <- suppressWarnings(as.numeric(GTmat[,2])) REFcs <- cumsum(elementNROWS(REF)) ALTcs <- cumsum(elementNROWS(ALT)) cs <- REFcs + c(0, head(ALTcs, -1)) offset <- rep(cs, ncol(res)) alleles <- unlist(rbind(REF,ALT), use.names=FALSE) alleleA <- alleles[offset + GTA] alleleB <- alleles[offset + GTB] if (any(missing)) { res[!missing] <- paste0(alleleA[!missing], phasing[!missing], alleleB[!missing]) } else { res[] <- paste0(alleleA, phasing, alleleB) } res } .readLite <- function(file, var, param, type, ..., row.names) { msg <- NULL if (!is.character(var)) msg <- c(msg, paste0("'", var, "'", " must be a character string")) if (length(var) > 1L) msg <- c(msg, paste0("'", var, "'", " must be of length 1")) if (!is.null(msg)) stop(msg) if (is(param, "ScanVcfParam")) { which <- vcfWhich(param) samples <- vcfSamples(param) } else { which <- param samples <- character() } if (type == "info") param=ScanVcfParam(NA, var, NA, which=which) else if (type == "geno") param=ScanVcfParam(NA, NA, var, samples, which=which) else if (type == "GT") param=ScanVcfParam("ALT", NA, var, samples, which=which) scn <- scanVcf(file, param=param, row.names=row.names) .collapseLists(scn, param) } readInfo <- function(file, x, param=ScanVcfParam(), ..., row.names=TRUE) { lst <- .readLite(file, x, param, "info", row.names=row.names) rowRanges <- lst$rowRanges res <- .formatInfo(lst$INFO, info(scanVcfHeader(file)), length(rowRanges))[[1]] if (row.names) names(res) <- names(rowRanges) res } readGeno <- function(file, x, param=ScanVcfParam(), ..., row.names=TRUE) { lst <- .readLite(file, x, param, "geno", row.names=row.names) rowRanges <- lst$rowRanges res <- lst$GENO[[1]] if (row.names) dimnames(res)[[1]] <- names(rowRanges) res } readGT <- function(file, nucleotides=FALSE, param=ScanVcfParam(), ..., row.names=TRUE) { lst <- .readLite(file, "GT", param, "GT", row.names=row.names) if (nucleotides) res <- .geno2geno(lst) else res <- lst$GENO$GT rowRanges <- lst$rowRanges if (row.names) dimnames(res)[[1]] <- names(rowRanges) res } VariantAnnotation/R/methods-scanVcf.R0000644000175100017510000001727514614305321020614 0ustar00biocbuildbiocbuild### ========================================================================= ### scanVcf methods ### ========================================================================= selectSome <- S4Vectors:::selectSome .vcf_usertag <- function(map, tag, nm, verbose) { if (!identical(character(), tag)) { if (1L == length(tag) && is.na(tag)) { map[] <- NULL } else { ok <- tag %in% names(map) if (!all(ok)) { warning("ScanVcfParam ", sQuote(nm), " fields not found in ", " header: ", paste(sQuote(tag[!ok]), collapse=" ")) tag <- tag[ok] } map <- map[tag] # user-requested order } } if (verbose) { msg <- paste0("found header lines for ", length(map), " ", sQuote(nm), " fields: ", paste(selectSome(names(map)), collapse=", ")) cat(msg, "\n") } if (!length(map) && nm == "info" && !length(tag)) map <- list(list("1", character())) map } .vcf_map_fixed <- function(tag, verbose) { map <- list(ALT=list("A", character()), QUAL=list("1", numeric()), FILTER=list("1", character())) c(list(rowRanges=NULL, REF=NULL), .vcf_usertag(map, tag, "fixed", verbose)) } .vcf_map_samples <- function(fmt, tag, ...) { map <- setNames(seq_along(fmt), fmt) if (identical(character(), tag)) { map # keep everyone } else if (isTRUE(is.na(tag))) { map[0] # drop everyone } else { if (any(nx <- !tag %in% fmt)) { warning("samples not in file: ", paste(sQuote(tag[nx]), collapse=" ")) tag <- tag[!nx] } map[] <- 0L # drop everyone, except... map[match(tag, fmt)] <- seq_along(tag) # these guys, and... map[rev(cumsum(rev(map)) > 0)] # drop trailing unwanted samples } } ## used for both INFO and GENO .vcf_map <- function(fmt, tag, nm, verbose) { numberOk <- grepl("^[AGR\\.[:digit:]+]$", fmt$Number) fmt$Number[!numberOk] <- "." mapType <- function(n, t) { if (t == "Flag") n <- "1" t <- switch(t, String=character(), Character=character(), Integer=integer(), Float=numeric(), Flag=logical()) list(n, t) } map <- Map(mapType, fmt$Number, fmt$Type) names(map) <- rownames(fmt) ## user selected .vcf_usertag(map, tag, nm, verbose) } .vcf_scan_header_maps <- function(file, fixed, info, geno, samples, verbose=FALSE) { if (isTRUE(is.na(samples))) geno <- NA hdr <- suppressWarnings(scanVcfHeader(file)) fmap <- .vcf_map_fixed(fixed, verbose=verbose) imap <- .vcf_map(info(hdr), info, "info", verbose=verbose) if (!is.null(names(imap))) { mapply(function(field, fname) { if (field[[1]] == 0L && !is.logical(field[[2]])) stop(paste0('only "flag" INFO fields should ', 'have Number = 0 in the header; ', fname, ' is "', classNameForDisplay(field[[2]]), '"')) else field }, imap, names(imap) ) } gmap <- .vcf_map(geno(hdr), geno, "geno", verbose) smap <- .vcf_map_samples(samples(hdr), samples) list(hdr=hdr, samples=smap, fmap=fmap, imap=imap, gmap=gmap) } .vcf_scan <- function(file, ..., fixed=character(), info=character(), geno=character(), samples=character(), param, row.names=TRUE) { tryCatch({ if (!isOpen(file)) { open(file) on.exit(close(file)) } maps <- .vcf_scan_header_maps(file, fixed, info, geno, samples, ...) tbxstate <- maps[c("samples", "fmap", "imap", "gmap")] tbxsym <- getNativeSymbolInfo(".tabix_as_vcf", "VariantAnnotation") scanTabix(file, ..., param=param, tbxsym=tbxsym, tbxstate=tbxstate, row.names=row.names) }, scanTabix_io = function(err) { stop("scanVcf: ", conditionMessage(err), call. = FALSE) }, error = function(err) { stop("scanVcf: ", conditionMessage(err), "\n path: ", path(file), call. = FALSE) }) } .vcf_scan_character <- function(file, ..., fixed=character(), info=character(), geno=character(), samples=character(), yieldSize=100000L, row.names=TRUE) { tryCatch({ file <- normalizePath(path.expand(file)) if (!file.exists(file)) stop("file does not exist") maps <- .vcf_scan_header_maps(file, fixed, info, geno, samples, ...) result <- .Call(.scan_vcf_character, file, as.integer(yieldSize), maps$samples, maps$fmap, maps$imap, maps$gmap, row.names) setNames(result, "*:*-*") }, scanTabix_io = function(err) { stop("scanVcf: ", conditionMessage(err), call. = FALSE) }, error = function(err) { stop("scanVcf: ", conditionMessage(err), "\n path: ", file, call. = FALSE) }) } .vcf_scan_connection <- function(file, ..., n = -1, fixed=character(), info=character(), geno=character(), samples=character(), row.names=TRUE) { if (!isOpen(file)) { open(file, "r") on.exit(close(file)) } tryCatch({ path <- summary(file)$description maps <- .vcf_scan_header_maps(path, fixed, info, geno, samples) txt <- character(0) repeat { input <- readLines(file, n) if (length(input) == 0L) break input <- input[!grepl("^#", input)] n <- n - length(input) txt <- c(txt, input) } result <- .Call(.scan_vcf_connection, txt, maps$samples, maps$fmap, maps$imap, maps$gmap, row.names) setNames(result, "*:*-*") }, scanTabix_io = function(err) { stop("scanVcf: ", conditionMessage(err), call. = FALSE) }, error = function(err) { stop("scanVcf: ", conditionMessage(err), "\n path: ", summary(file)$description, call. = FALSE) }) } setMethod(scanVcf, c("TabixFile", "IntegerRangesList"), function(file, ..., param) { .vcf_scan(file, ..., param=param) }) setMethod(scanVcf, c("TabixFile", "GRanges"), function(file, ..., param) { .vcf_scan(file, ..., param=param) }) setMethod(scanVcf, c("TabixFile", "ScanVcfParam"), function(file, ..., param) { result <- scanVcf(file, ..., fixed=vcfFixed(param), info=vcfInfo(param), geno=vcfGeno(param), samples=vcfSamples(param), param=vcfWhich(param)) if (vcfTrimEmpty(param)) lapply(result, function(rng) { rng[["GENO"]] <- Filter(Negate(is.null), rng[["GENO"]]) rng }) else result }) setMethod(scanVcf, c("TabixFile", "missing"), function(file, ..., param) { callGeneric(file, ..., param=ScanVcfParam()) }) setMethod(scanVcf, c("character", "ScanVcfParam"), function(file, ..., param) { ## no ranges if (0L == length(vcfWhich(param))) { .vcf_scan_character(file, ..., fixed=vcfFixed(param), info=vcfInfo(param), geno=vcfGeno(param), samples=vcfSamples(param)) } else { ## ranges callGeneric(TabixFile(file), ..., param=param) } }) setMethod(scanVcf, c("character", "missing"), function(file, ..., param) { callGeneric(file, ..., param=ScanVcfParam()) }) setMethod(scanVcf, c("connection", "missing"), function(file, ..., param) { .vcf_scan_connection(file, ...) }) VariantAnnotation/R/methods-scanVcfHeader.R0000644000175100017510000000064714614305321021720 0ustar00biocbuildbiocbuildsetMethod(scanVcfHeader, "missing", function(file, ...) { VCFHeader() }) setMethod(scanVcfHeader, "character", function(file, ...) { if (length(file)) { hdr <- scanBcfHeader(file[[1]], ...)[[1]] VCFHeader(hdr$Reference, hdr$Sample, hdr$Header) } else { VCFHeader() } }) setMethod(scanVcfHeader, "TabixFile", function(file, ...) { scanVcfHeader(path(file), ...) }) VariantAnnotation/R/methods-ScanVcfParam-class.R0000644000175100017510000000457314614305321022635 0ustar00biocbuildbiocbuild### ========================================================================= ### ScanVcfParam class methods ### ========================================================================= ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## Constructor ## setMethod(ScanVcfParam, "ANY", function(fixed=character(), info=character(), geno=character(), samples=character(), trimEmpty=TRUE, which, ...) { ScanBcfParam(fixed, info, geno, samples, trimEmpty=trimEmpty, which=which, class="ScanVcfParam") }) setMethod(ScanVcfParam, "missing", function(fixed=character(), info=character(), geno=character(), samples=character(), trimEmpty=TRUE, which, ...) { ScanBcfParam(fixed, info, geno, samples, trimEmpty=trimEmpty, class="ScanVcfParam") }) ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## Validity ## .valid.ScanVcfParam <- function(object) { samples <- vcfSamples(object) geno <- vcfGeno(object) if (any(is.na(samples)) && length(geno) > 0L) return("ScanVcfParam: 'geno' cannot be specified if 'samples' is 'NA'") if (any(is.na(geno)) && length(samples) > 0L) return("ScanVcfParam: 'samples' cannot be specified if 'geno' is 'NA'") NULL } setValidity("ScanVcfParam", .valid.ScanVcfParam, where=asNamespace("VariantAnnotation")) ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## Getters and Setters ## vcfFixed <- function(object) slot(object, "fixed") "vcfFixed<-" <- function(object, value) { slot(object, "fixed") <- value object } vcfInfo <- function(object) slot(object, "info") "vcfInfo<-" <- function(object, value) { slot(object, "info") <- value object } vcfGeno <- function(object) slot(object, "geno") "vcfGeno<-" <- function(object, value) { slot(object, "geno") <- value object } vcfSamples <- function(object) slot(object, "samples") "vcfSamples<-" <- function(object, value) { slot(object, "samples") <- value object } vcfTrimEmpty <- function(object) slot(object, "trimEmpty") "vcfTrimEmpty<-" <- function(object, value) { slot(object, "trimEmpty") <- value object } vcfWhich <- function(object) { slot(object, "which") } "vcfWhich<-" <- function(object, value) { slot(object, "which") <- as(value, "IntegerRangesList") object } VariantAnnotation/R/methods-SIFTDb-class.R0000644000175100017510000000752514614305321021344 0ustar00biocbuildbiocbuild### ========================================================================= ### SIFTDb methods ### ========================================================================= setMethod("keys", "SIFTDb", function(x) { sql <- paste("SELECT rsid FROM siftdata ", sep="") unqsnp <- unique(dbGetQuery(x$conn, sql))[,1] paste("rs", unqsnp, sep="") } ) ## NOTE: The database table has 23 columns. There are two ## 'METHODS' (BEST HITS and ALL HITS) of obtaining related ## sequences using PSI-BLAST. Each variable outcome was listed ## once for each method which created a very wide non-coehesive ## table. We decided to consolidate the data by these methods ## to return a more compact result. (Not sure if this was wise ## or not.) This 'consolidating' of the data could have been ## done before creating the database or here before returning ## results to the user. We decided to keep the database table ## table as close to original as possible so curating is done here. setMethod("columns", "SIFTDb", function(x) { c("RSID", "PROTEINID", "AACHANGE", "METHOD", "AA", "PREDICTION", "SCORE", "MEDIAN", "POSTIONSEQS", "TOTALSEQS") } ) setMethod("select", "SIFTDb", function(x, keys, columns, ...) { sql <- .createSIFTDbQuery(x, keys, columns) if (length(sql)) { raw <- dbGetQuery(x$conn, sql) .formatSIFTDbSelect(raw, keys, columns) } else { data.frame() } } ) .createSIFTDbQuery <- function(x, keys, cols) { if (.missingKeys(x, keys, "SIFT")) return(character()) if (.missingCols(x, cols, "SIFT")) return(character()) if (missing(keys)) { sql <- paste("SELECT * FROM siftdata", sep="") } else { fmtkeys <- .sqlIn(.formatRSID(keys)) sql <- paste("SELECT * FROM siftdata WHERE RSID IN (", fmtkeys, ")", sep="") } } .formatRSID <- function(rsid) { gsub("rs", "", rsid, fixed=TRUE) } .formatSIFTDbSelect <- function(raw, keys, cols) { missing <- rep(FALSE, length(unique(raw$RSID))) if (!missing(keys)) { fmtkeys <- .formatRSID(keys) missing <- (!fmtkeys %in% as.character(raw$RSID)) } ## no data if (!nrow(raw)) return(data.frame()) ## create variable columns dat <- raw[,-c(1:3)] res <- matrix(t(dat), ncol=5, byrow=TRUE) colnames(res) <- c("PREDICTION", "SCORE", "MEDIAN", "POSITIONSEQS", "TOTALSEQS") ## create common columns id <- lapply(as.list(raw$RSID), function(x) rep(x, 4L)) rsid <- paste("rs", unlist(id, use.names=FALSE), sep="") protein_id <- lapply(as.list(raw$PROTEINID), function(x) rep(x, 4L)) aachange <- lapply(as.list(raw$AACHANGE), function(x) rep(x, 4L)) aa <- .createAAColumn(raw$AACHANGE) method <- rep(c("BEST HITS", "BEST HITS", "ALL HITS", "ALL HITS"), length(raw$RSID)) dd <- data.frame(RSID=unlist(rsid), PROTEINID=unlist(protein_id), AACHANGE=unlist(aachange), METHOD=method, AA=unlist(aa), res, row.names=NULL, stringsAsFactors=FALSE) ## reorder columns if (!missing(cols)) { if (!"RSID" %in% cols) cols <- c("RSID", cols) dd <- dd[,colnames(dd) %in% cols] } ## return keys not found df <- dd[!duplicated(dd), ] lst <- as.list(rep(NA_character_, length(keys))) for (i in which(missing == FALSE)) lst[[i]] <- df[df$RSID %in% keys[i], ] df <- do.call(rbind, lst) df$RSID[is.na(df$RSID)] <- keys[missing] rownames(df) <- NULL df } .createAAColumn <- function(x) { ## create single aa column, snp followed by ref lapply(x, function(elt) { ref_aa <- substr(as.character(elt), 1, 1) snp_aa <- substr(as.character(elt), nchar(as.character(elt)), nchar(as.character(elt))) c(snp_aa, ref_aa, snp_aa, ref_aa) }) } VariantAnnotation/R/methods-snpSummary.R0000644000175100017510000000570614614305321021403 0ustar00biocbuildbiocbuild### ========================================================================= ### snpSummary methods ### ========================================================================= setMethod("snpSummary", "CollapsedVCF", function(x, ...) { alt <- alt(x) if (is(alt, "CompressedCharacterList")) { alt <- .toDNAStringSetList(alt) if (all(elementNROWS(alt) == 0L)) { warning("No nucleotide ALT values were detected.") return(.emptySnpSummary()) } } gt <- geno(x)$GT if (is.null(gt)) { warning("No genotype data found in VCF.") return(.emptySnpSummary()) } if (ncol(gt) == 0L) { warning("No genotype data found in VCF.") return(.emptySnpSummary()) } ## Genotype count snv <- .testForSNV(ref(x), alt) if (sum(snv) == 0L) { warning("No valid SNPs found in VCF.") return(.emptySnpSummary()) } gmap <- .genotypeToIntegerSNV(FALSE) gmat <- matrix(gmap[gt], nrow=nrow(gt)) gcts <- matrix(NA_integer_, nrow(gmat), 3) if (ncol(gmat) == 1L) fun <- I else fun <- rowSums gcts[snv,] <- sapply(1:3, function(i) fun(gmat[snv,] == i)) gcts <- matrix(as.integer(gcts), nrow=nrow(gmat), dimnames=list(NULL, c("g00", "g01", "g11"))) ## Allele frequency acts <- gcts %*% matrix(c(2,1,0,0,1,2), nrow=3) afrq <- acts/rowSums(acts) colnames(afrq) <- c("a0Freq", "a1Freq") ## HWE HWEzscore <- .HWEzscore(gcts, acts, afrq) HWEpvalue <- pchisq(HWEzscore^2, 1, lower.tail=FALSE) data.frame(gcts, afrq, HWEzscore, HWEpvalue, row.names=rownames(x)) }) .HWEzscore <- function(genoCounts, alleleCounts, alleleFrequency) { a0 <- alleleFrequency[,"a0Freq"] a1 <- alleleFrequency[,"a1Freq"] expt <- rowSums(alleleCounts) * cbind(a0^2/2, a0*a1, a1^2/2) chisq <- rowSums((genoCounts - expt)^2 / expt) z <- rep(NA, nrow(genoCounts)) zsign <- sign(genoCounts[,"g01"] - expt[,2] * rowSums(genoCounts)) zsign * sqrt(chisq) } ## Maps diploid genotypes, phased or unphased. .genotypeToIntegerSNV <- function(raw=TRUE) { name <- c(".|.", "0|0", "0|1", "1|0", "1|1", "./.", "0/0", "0/1", "1/0", "1/1") value <- rep(c(0, 1, 2, 2, 3), 2) if (raw) setNames(sapply(value, as.raw), name) else setNames(value, name) } ## Expects 'ref' as DNAStringSet and 'alt' as ## DNAStringSetList. Returns a logical vector ## the same length as 'ref'. .testForSNV <- function(ref, alt) { altelt <- elementNROWS(alt) == 1L altseq <- logical(length(alt)) idx <- rep(altelt, elementNROWS(alt)) altseq[altelt] = width(unlist(alt, use.names=FALSE)[idx]) == 1L altseq & (width(ref) == 1L) } .emptySnpSummary <- function() { data.frame(g00=integer(), g01=integer(), g11=integer(), a0Freq=numeric(), a1Freq=numeric(), HWEzscore=numeric(), HWEpvalue=numeric()) } VariantAnnotation/R/methods-summarizeVariants.R0000644000175100017510000000563714614305321022754 0ustar00biocbuildbiocbuild### ========================================================================= ### summarizeVariants methods ### ========================================================================= setMethod("summarizeVariants", c("TxDb", "VCF", "CodingVariants"), function(query, subject, mode, ...) { grl <- cdsBy(query, "tx") callGeneric(grl, subject, mode, ...) }) setMethod("summarizeVariants", c("TxDb", "VCF", "FiveUTRVariants"), function(query, subject, mode, ...) { grl <- fiveUTRsByTranscript(query) callGeneric(grl, subject, mode, ...) }) setMethod("summarizeVariants", c("TxDb", "VCF", "ThreeUTRVariants"), function(query, subject, mode, ...) { grl <- threeUTRsByTranscript(query) callGeneric(grl, subject, mode, ...) }) setMethod("summarizeVariants", c("TxDb", "VCF", "SpliceSiteVariants"), function(query, subject, mode, ...) { grl <- intronsByTranscript(query) callGeneric(grl, subject, mode, ...) }) setMethod("summarizeVariants", c("TxDb", "VCF", "IntronVariants"), function(query, subject, mode, ...) { grl <- intronsByTranscript(query) callGeneric(grl, subject, mode, ...) }) setMethod("summarizeVariants", c("TxDb", "VCF", "PromoterVariants"), function(query, subject, mode, ...) { gr <- transcripts(query, columns="tx_id") grl <- splitAsList(gr, seq_len(length(gr))) names(grl) <- mcols(gr)$tx_id callGeneric(grl, subject, mode, ...) }) setMethod("summarizeVariants", c("GRangesList", "VCF", "VariantType"), function(query, subject, mode, ...) { callGeneric(query, subject, mode=locateVariants, ..., region=mode, asHits=TRUE) }) setMethod("summarizeVariants", c("GRangesList", "VCF", "function"), function(query, subject, mode, ...) { if (length(geno(subject)) == 0L) { warning("No genotypes found in 'query'.") return(.baseSE(query, subject)) } ## count hits <- mode(rowRanges(subject), query, ...) if (length(hits) == 0L) return(.baseSE(query, subject)) ## genotypes na <- c("0|0", "0/0", "./.", ".|.", ".") vcf_geno <- geno(subject)$GT[unique(queryHits(hits)), ] gtype <- as.numeric(!vcf_geno %in% na) ## summarize counts factor-by-sample fac_x_var <- table(subjectHits(hits), queryHits(hits)) var_x_smp <- matrix(gtype, ncol=ncol(subject)) fac_x_smp <- fac_x_var %*% var_x_smp rownames(fac_x_smp) <- NULL SummarizedExperiment(rowRanges=query[unique(subjectHits(hits))], colData=colData(subject), metadata=metadata(subject), assays=SimpleList(counts=fac_x_smp)) }) .baseSE <- function(query, subject, ...) { SummarizedExperiment(rowRanges=query, colData=colData(subject), metadata=metadata(subject), assays=SimpleList(counts=matrix(NA_integer_, nrow=length(query), ncol=ncol(subject)))) } VariantAnnotation/R/methods-VariantType-class.R0000644000175100017510000001177214614305321022576 0ustar00biocbuildbiocbuild### ========================================================================= ### VariantType class methods ### ========================================================================= ### 'show' methods setMethod("show", "VariantType", function(object) { cat("class:", classNameForDisplay(object), "\n") } ) setMethod("show", "AllVariants", function(object) { cat("class:", classNameForDisplay(object), "\n") cat("promoter: \n") cat(" upstream:", upstream(promoter(object)), "\n") cat(" downstream:", downstream(promoter(object)), "\n") cat("intergenic: \n") cat(" upstream:", upstream(intergenic(object)), "\n") cat(" downstream:", downstream(intergenic(object)), "\n") cat(" idType:", idType(intergenic(object)), "\n") } ) setMethod("show", "PromoterVariants", function(object) { cat("class:", classNameForDisplay(object), "\n") cat("upstream:", upstream(object), "\n") cat("downstream:", downstream(object), "\n") } ) setMethod("show", "IntergenicVariants", function(object) { cat("class:", classNameForDisplay(object), "\n") cat("upstream:", upstream(object), "\n") cat("downstream:", downstream(object), "\n") cat("idType:", idType(object), "\n") } ) ### constructors CodingVariants <- function() new("CodingVariants") IntronVariants <- function() new("IntronVariants") UTRVariants <- function() new("UTRVariants") ThreeUTRVariants <- function() new("ThreeUTRVariants") FiveUTRVariants <- function() new("FiveUTRVariants") SpliceSiteVariants <- function() new("SpliceSiteVariants") ### .checkArgs() takes the place of a validity method. ### 'upstream' and 'downstream' are forced to integers ### which changes the object and can't be done a validity ### method. .checkArgs <- function(x, argName) { if (!isSingleNumber(x) | x < 0) stop(paste0("'", argName, "'", " must be a single integer >= 0")) if (!is.integer(x)) as.integer(x) else x } IntergenicVariants <- function(upstream=1e+06L, downstream=1e+06L, idType=c("gene", "tx")) { upstream <- .checkArgs(upstream, "upstream") downstream <- .checkArgs(downstream, "downstream") if (missing(idType)) { idType <- match.arg(idType) } else { idType <- tolower(idType) if (!idType %in% c("gene", "tx")) stop("'idType' must be one of 'gene' or 'tx'") } new("IntergenicVariants", upstream=upstream, downstream=downstream, idType=idType) } PromoterVariants <- function(upstream=2000L, downstream=200L) { upstream <- .checkArgs(upstream, "upstream") downstream <- .checkArgs(downstream, "downstream") new("PromoterVariants", upstream=upstream, downstream=downstream) } AllVariants <- function(promoter=PromoterVariants(), intergenic=IntergenicVariants()) { new("AllVariants", promoter=promoter, intergenic=intergenic) } ### getters and setters setMethod("upstream", "PromoterVariants", function(x) slot(x, "upstream")) setReplaceMethod("upstream", "PromoterVariants", function(x, value) { slot(x, "upstream") <- .checkArgs(value, "upstream") x }) setMethod("downstream", "PromoterVariants", function(x) slot(x, "downstream")) setReplaceMethod("downstream", "PromoterVariants", function(x, value) { slot(x, "downstream") <- .checkArgs(value, "downstream") x }) setMethod("upstream", "IntergenicVariants", function(x) slot(x, "upstream")) setReplaceMethod("upstream", "IntergenicVariants", function(x, value) { slot(x, "upstream") <- .checkArgs(value, "upstream") x }) setMethod("downstream", "IntergenicVariants", function(x) slot(x, "downstream")) setReplaceMethod("downstream", "IntergenicVariants", function(x, value) { slot(x, "downstream") <- .checkArgs(value, "downstream") x }) setMethod("idType", "IntergenicVariants", function(x) slot(x, "idType")) setReplaceMethod("idType", "IntergenicVariants", function(x, value) { if (!value %in% c("gene", "tx")) stop("'idType' must be one of 'gene' or 'tx'") slot(x, "idType") <- value x }) setMethod("downstream", "IntergenicVariants", function(x) slot(x, "downstream")) setReplaceMethod("downstream", "IntergenicVariants", function(x, value) { slot(x, "downstream") <- .checkArgs(value, "downstream") x }) setMethod("promoter", "AllVariants", function(x) slot(x, "promoter")) setReplaceMethod("promoter", "AllVariants", function(x, value) { if (!is(value, "PromoterVariants")) stop("'value' must be a 'PromoterVariants' object") slot(x, "promoter") <- value x }) setMethod("intergenic", "AllVariants", function(x) slot(x, "intergenic")) setReplaceMethod("intergenic", "AllVariants", function(x, value) { if (!is(value, "IntergenicVariants")) stop("'value' must be a 'IntergenicVariants' object") slot(x, "intergenic") <- value x }) VariantAnnotation/R/methods-VCF-class.R0000644000175100017510000004221414614305321020741 0ustar00biocbuildbiocbuild### ========================================================================= ### VCF class methods ### ========================================================================= ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Constructor ### VCF <- function(rowRanges=GRanges(), colData=DataFrame(), exptData=list(header=VCFHeader()), fixed=DataFrame(), info=DataFrame(row.names=seq_along(rowRanges)), geno=SimpleList(), ..., collapsed=TRUE, verbose=FALSE) { rownames(info) <- rownames(fixed) <- NULL if (collapsed) { class <- "CollapsedVCF" if (!length(fixed)) { fixed=DataFrame( REF=DNAStringSet(rep(".", length(rowRanges))), ALT=DNAStringSetList(as.list(rep(".", length(rowRanges)))), QUAL=rep(NA_real_, length(rowRanges)), FILTER=rep(NA_character_, length(rowRanges))) } } else { class <- "ExpandedVCF" if (!length(fixed)) { fixed=DataFrame( REF=DNAStringSet(rep("", length(rowRanges))), ALT=DNAStringSet(rep("", length(rowRanges))), QUAL=rep(NA_real_, length(rowRanges)), FILTER=rep(NA_character_, length(rowRanges))) } } new(class, SummarizedExperiment(assays=geno, rowRanges=rowRanges, colData=colData, metadata=as.list(exptData)), fixed=fixed, info=info, ...) } ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### updateObject() ### setMethod("updateObject", "VCF", function(object, ..., verbose=FALSE) { # Fix VCF-specific slots. object@fixed <- updateObject(object@fixed, ..., verbose=verbose) object@info <- updateObject(object@info, ..., verbose=verbose) # Call method for RangedSummarizedExperiment objects. callNextMethod() } ) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Getters and Setters ### .recycleVector <- function(x, value) { ## warns when number of values not a sub-multiple of length of x x[] <- value x } ### fixed setMethod("fixed", "VCF", function(x) { ## Fix old DataFrame instance on-the-fly. updateObject(slot(x, "fixed"), check=FALSE) }) setReplaceMethod("fixed", c("VCF", "DataFrame"), function(x, value) { slot(x, "fixed") <- value validObject(x) x }) ### ref setMethod("ref", "VCF", function(x) { fixed(x)$REF }) setReplaceMethod("ref", c("VCF", "DNAStringSet"), function(x, value) { value <- .recycleVector(ref(x), value) slot(x, "fixed")$REF <- value x }) ### alt setMethod("alt", "VCF", function(x) { fixed(x)$ALT }) setReplaceMethod("alt", c("CollapsedVCF", "CharacterList"), function(x, value) { value <- .recycleVector(as(alt(x), "CharacterList"), value) slot(x, "fixed")$ALT <- value x }) setReplaceMethod("alt", c("ExpandedVCF", "character"), function(x, value) { value <- .recycleVector(as.character(alt(x)), value) slot(x, "fixed")$ALT <- value x }) ### qual setMethod("qual", "VCF", function(x) { fixed(x)$QUAL }) setReplaceMethod("qual", c("VCF", "numeric"), function(x, value) { value <- .recycleVector(qual(x), value) slot(x, "fixed")$QUAL <- value x }) ### filt setMethod("filt", "VCF", function(x) { fixed(x)$FILTER }) setReplaceMethod("filt", c("VCF", "character"), function(x, value) { value <- .recycleVector(filt(x), value) slot(x, "fixed")$FILTER <- value x }) ### rowRanges setMethod("rowRanges", "VCF", function(x, ..., fixed = TRUE) { gr <- slot(x, "rowRanges") if (fixed) { x_fixed <- fixed(x) if (length(x_fixed) != 0L) mcols(gr) <- append(mcols(gr), x_fixed) } gr }) setReplaceMethod("rowRanges", c("VCF", "GRanges"), function(x, value) { ## This method does not manage the 'fixed' fields REF, ALT, QUAL, FILTER ## Use "fixed<-" instead. sub <- value[,!names(mcols(value)) %in% c("REF", "ALT", "QUAL", "FILTER")] slot(x, "rowRanges") <- sub x }) setReplaceMethod("mcols", c("VCF", "ANY"), function(x, ..., value) { ## This method does not manage the 'fixed' fields REF, ALT, QUAL, FILTER ## Use "fixed<-" instead. sub <- value[,!names(value) %in% c("REF", "ALT", "QUAL", "FILTER")] mcols(slot(x, "rowRanges")) <- sub validObject(x) x }) setReplaceMethod("dimnames", c("VCF", "list"), function(x, value) { rowRanges <- slot(x, "rowRanges") names(rowRanges) <- value[[1]] colData <- colData(x) rownames(colData) <- value[[2]] BiocGenerics:::replaceSlots(x, rowRanges=rowRanges, colData=colData) }) ### info setMethod("info", "VCF", function(x, ..., row.names = TRUE) { ## Fix old DataFrame instance on-the-fly. info <- updateObject(slot(x, "info"), check=FALSE) if (row.names && !anyDuplicated(rownames(x))) rownames(info) <- rownames(x) info }) setReplaceMethod("info", c("VCF", "DataFrame"), function(x, value) { slot(x, "info") <- value .valid.VCFHeadervsVCF.fields(x, info) validObject(x) x }) ### geno ### 'assays' extracts full list ### 'assay' extracts individual list elements setMethod("geno", "VCF", function(x, ..., withDimnames = TRUE) { assays(x, ..., withDimnames=withDimnames) }) setMethod("geno", c("VCF", "numeric"), function(x, i, ..., withDimnames = TRUE) { assay(x, i, ...) }) setMethod("geno", c("VCF", "character"), function(x, i, ..., withDimnames = TRUE) { assay(x, i, ...) }) setReplaceMethod("geno", c("VCF", "missing", "SimpleList"), function(x, i, ..., value) { assays(x, withDimnames=FALSE) <- value .valid.VCFHeadervsVCF.fields(x, geno) x }) setReplaceMethod("geno", c("VCF", "character", "matrix"), function(x, i, ..., value) { assay(x, i, withDimnames=FALSE) <- value .valid.VCFHeadervsVCF.fields(x, geno) x }) setReplaceMethod("geno", c("VCF", "numeric", "matrix"), function(x, i, ..., value) { assay(x, i, withDimnames=FALSE) <- value .valid.VCFHeadervsVCF.fields(x, geno) x }) setReplaceMethod("geno", c("VCF", "missing", "matrix"), function(x, i, ..., value) { assay(x, withDimnames=FALSE) <- value .valid.VCFHeadervsVCF.fields(x, geno) x }) ### strand setMethod("strand", "VCF", function(x, ...) { strand(rowRanges(x)) }) setReplaceMethod("strand", "VCF", function(x, ..., value) { strand(rowRanges(x)) <- value x }) ### header setMethod("header", "VCF", function(x) { metadata(x)$header }) setReplaceMethod("header", c("VCF", "VCFHeader"), function(x, value) { slot(x, "metadata")$header <- value .valid.VCFHeadervsVCF(x) x }) ## vcfFields setMethod("vcfFields", "missing", function(x, ...) { vcfFields(VCFHeader()) }) setMethod("vcfFields", "VCF", function(x, ...) { vcfFields(header(x)) }) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Subsetting and combining ### setMethod(parallel_slot_names, "VCF", function(x) { c("fixed", "info", callNextMethod()) }) setMethod("[", c("VCF", "ANY", "ANY"), function(x, i, j, ..., drop=TRUE) { if (1L != length(drop) || (!missing(drop) && drop)) warning("'drop' ignored '[,VCF,ANY,ANY-method'") if (!missing(i) && is.character(i)) { msg <- "[i,] index out of bounds: %s" i <- SummarizedExperiment:::.SummarizedExperiment.charbound(i, rownames(x), msg) } if (missing(i) && missing(j)) { x } else if (missing(i)) { callNextMethod(x, , j, ...) } else if (missing(j)) { callNextMethod(x, i, , info=info(x)[i,,drop=FALSE], fixed=fixed(x)[i,,drop=FALSE], ...) } else { callNextMethod(x, i, j, info=info(x)[i,,drop=FALSE], fixed=fixed(x)[i,,drop=FALSE], ...) } }) setMethod("subset", "VCF", function(x, subset, select, ...) { rowData <- rowRanges(x) mcols(rowData) <- cbind(mcols(rowRanges(x)), info(x)) i <- S4Vectors:::evalqForSubset(subset, rowData, ...) j <- S4Vectors:::evalqForSubset(select, colData(x), ...) x[i, j] }) setReplaceMethod("[", c("VCF", "ANY", "ANY", "VCF"), function(x, i, j, ..., value) { if (!missing(i) && is.character(i)) { msg <- "[i,]<- index out of bounds: %s" i <- SummarizedExperiment:::.SummarizedExperiment.charbound(i, rownames(x), msg) } if (missing(i) && missing(j)) { x } else if (missing(i)) { callNextMethod(x, , j, ..., value=value) } else if (missing(j)) { callNextMethod(x, i, , info=local({ ii <- info(x) ii[i,] <- info(value) ii }), fixed=local({ ff <- fixed(x) ff[i,] <- fixed(value) ff }), ..., value=value) } else { callNextMethod(x, i, j, info=local({ ii <- info(x) ii[i,] <- info(value) ii }), fixed=local({ ff <- fixed(x) ff[i,] <- fixed(value) ff }), ..., value=value) } }) .compare <- SummarizedExperiment:::.compare ## Appropriate for objects with different ranges and same samples. setMethod("rbind", "VCF", function(..., deparse.level=1) { args <- unname(list(...)) if (!.compare(lapply(args, class))) stop("'...' objects must be of the same VCF class") args <- .renameSamples(args) if (!.compare(lapply(args, colnames))) stop("'...' objects must have the same colnames") if (!.compare(lapply(args, ncol))) stop("'...' objects must have the same number of samples") fixed <- do.call(rbind, lapply(args, fixed)) info <- do.call(rbind, lapply(args, info)) ## rowRanges should not contain REF, ALT, QUAL or FILTER rowRanges <- do.call(c, lapply(args, slot, "rowRanges")) colData <- SummarizedExperiment:::.cbind.DataFrame(args, colData, "colData") assays <- do.call(rbind, lapply(args, slot, "assays")) elementMetadata <- do.call(rbind, lapply(args, slot, "elementMetadata")) metadata <- do.call(c, lapply(args, metadata)) BiocGenerics:::replaceSlots(args[[1L]], fixed=fixed, info=info, rowRanges=rowRanges, colData=colData, assays=assays, elementMetadata=elementMetadata, metadata=metadata) }) .renameSamples <- function(args) { Map(function(x, i) { idx <- names(colData(x)) == "Samples" names(colData(x))[idx] <- paste0("Samples.", i) x }, x=args, i=seq_along(args)) } ## FIXME: combine header info ## Appropriate for objects with same ranges and different samples. setMethod("cbind", "VCF", function(..., deparse.level=1) { args <- unname(list(...)) if (!.compare(lapply(args, class))) stop("'...' objects must be of the same VCF class") if (!.compare(lapply(args, rowRanges), TRUE)) stop("'...' object ranges (rows) are not compatible") if (!.compare(lapply(args, "fixed"))) stop("data in 'fixed(VCF)' must match.") fixed <- fixed(args[[1L]]) info <- SummarizedExperiment:::.cbind.DataFrame(args, info, "info") rowRanges <- rowRanges(args[[1L]]) mcols(rowRanges) <- SummarizedExperiment:::.cbind.DataFrame(args, mcols, "mcols") colData <- do.call(rbind, lapply(args, colData)) assays <- do.call(cbind, lapply(args, slot, "assays")) metadata <- do.call(c, lapply(args, metadata)) BiocGenerics:::replaceSlots(args[[1L]], fixed=fixed, info=info, rowRanges=rowRanges, colData=colData, assays=assays, metadata=metadata) }) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Coercion ### SnpMatrixToVCF <- function(from, seqSource) { if (!all(names(from) %in% c("genotypes", "fam", "map"))) stop("'from' must be a list with named elements 'genotypes', ", "'fam' and 'map'") ## match seqlevels style to seqSource map <- from$map chr <- as.character(map$chromosome) seqlevelsStyle(chr) <- seqlevelsStyle(seqSource) uniqueChr <- unique(chr) if (any(invalid <- !uniqueChr %in% seqlevels(seqSource))) stop("seqlevels not found in 'seqSource': ", paste(uniqueChr[invalid], collapse=", ")) ## ref gr <- GRanges(chr, IRanges(map$position, width=1)) ref <- getSeq(seqSource, gr) ## alt refIsAlt1 <- ref == map$allele.1 refIsAlt2 <- ref == map$allele.2 alt <- DNAStringSetList(as.list(map$allele.1)) alt[refIsAlt1] <- DNAStringSetList(as.list(map$allele.2[refIsAlt1])) if (any(refNotFound <- refIsAlt1 & refIsAlt2)) { df <- data.frame(rbind(map$allele.1[refNotFound], map$allele.2[refNotFound])) alt[refNotFound] <- DNAStringSetList(as.list(df)) } ## genotypes GT <- as.raw(from$genotypes) nrowGT <- nrow(from$genotypes) newGT <- c("./.", "0/0", "0/1", "1/1") GT <- newGT[as.integer(GT) + 1L] GT <- matrix(GT, byrow=TRUE, ncol=nrowGT) vcf <- VCF(rowRanges=gr, fixed=DataFrame(REF=ref, ALT=alt), colData=DataFrame(Samples=seq_len(nrowGT)), geno=SimpleList(GT=GT)) dimnames(vcf) <- list(colnames(from$genotypes), rownames(from$genotypes)) vcf } ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Show methods ### setMethod(show, "VCF", function(object) { paste0("This object is no longer valid. Please use updateObject() to ", "create a CollapsedVCF instance.") }) ### methods for CollapsedVCF and ExapandedVCF .showVCFSubclass <- function(object) { prettydescr <- function(desc, wd0=30L) { desc <- as.character(desc) wd <- options()[["width"]] - wd0 dwd <- nchar(desc) desc <- substr(desc, 1, wd) idx <- dwd > wd substr(desc[idx], wd - 2, dwd[idx]) <- "..." desc } headerrec <- function(df, margin=" ") { wd <- max(nchar(rownames(df))) + nchar("Number") + max(nchar(df$Type)) + 7L df$Description <- prettydescr(df$Description, wd) rownames(df) <- paste0(margin, rownames(df)) print(df, right=FALSE) } printSmallGRanges <- function(x, margin) { lx <- length(x) nc <- ncol(mcols(x)) nms <- names(mcols(x)) cat(margin, classNameForDisplay(x), " with ", nc, " metadata ", ifelse(nc == 1L, "column", "columns"), ": ", paste0(nms, collapse=", "), "\n", sep="") } printSmallDataTable <- function(x, margin) { nc <- ncol(x) nms <- names(x) cat(margin, classNameForDisplay(x), " with ", nc, ifelse(nc == 1, " column", " columns"), ": ", prettydescr(paste0(nms, collapse=", ")), "\n", sep="") } printSimpleList <- function(x, margin) { lo <- length(x) nms <- names(x) cat(margin, classNameForDisplay(x), " of length ", lo, ": ", prettydescr(paste0(nms, collapse=", ")), "\n", sep="") } margin <- " " cat("class:", classNameForDisplay(object), "\n") cat("dim:", dim(object), "\n") cat("rowRanges(vcf):\n") printSmallGRanges(rowRanges(object), margin=margin) cat("info(vcf):\n") printSmallDataTable(info(object, row.names=FALSE), margin=margin) if (length(header(object))) { if (length(hdr <- info(header(object)))) { nms <- intersect(colnames(info(object, row.names=FALSE)), rownames(hdr)) diff <- setdiff(colnames(info(object, row.names=FALSE)), rownames(hdr)) if (length(nms)) { cat("info(header(vcf)):\n") headerrec(as.data.frame(hdr[nms,])) } if (length(diff)) cat(" Fields with no header:", paste(diff, collapse=","), "\n") } } cat("geno(vcf):\n") geno <- geno(object, withDimnames=FALSE) printSimpleList(geno, margin=margin) if (length(header(object))) { if (length(hdr <- geno(header(object)))) { gnames <- names(geno(object, withDimnames = FALSE)) nms <- intersect(gnames, rownames(hdr)) diff <- setdiff(gnames, rownames(hdr)) if (length(nms)) { cat("geno(header(vcf)):\n") headerrec(as.data.frame(hdr[nms,])) } if (length(diff)) cat(" Fields with no header:", paste(diff, collapse=","), "\n") } } } ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### genotypeCodesToNucleotides() ### genotypeCodesToNucleotides <- function(vcf, ...) { GT <- geno(vcf, withDimnames=FALSE)$GT if (is.null(GT <- geno(vcf, withDimnames=FALSE)$GT)) stop("no 'GT' data found in geno(vcf)") if (is(alt(vcf), "CharacterList")) stop("'ALT' must be a DNAStringSetList") ALT <- as.list(splitAsList(as.character(alt(vcf)@unlistData), togroup(PartitioningByWidth(alt(vcf))))) REF <- as.character(ref(vcf)) geno(vcf)$GT <- .geno2geno(NULL, ALT, REF, GT) vcf } VariantAnnotation/R/methods-VcfFile.R0000644000175100017510000000542014614305321020534 0ustar00biocbuildbiocbuild### ========================================================================= ### VcfFile, VcfFileList class methods ### ========================================================================= ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Constructors ### VcfFile <- function(file, index, ..., yieldSize=NA_integer_) { if (is(file, "VcfFile")) return(file) tryCatch({ Rsamtools:::.io_check_exists(file) }, error=function(err) { stop(sprintf("VcfFile: %s", conditionMessage(err)), call.=FALSE) }) if (missing(index)){ index=paste(file, "tbi", sep=".") if (!file.exists(index)) index = NA } Rsamtools:::.RsamtoolsFile(.VcfFile, file, index, yieldSize=yieldSize, ...) } VcfFileList <- function(..., yieldSize=NA_integer_) { Rsamtools:::.RsamtoolsFileList( ..., yieldSize=yieldSize, class="VcfFile", classDef = VariantAnnotation::VcfFile ) } ### Methods ### setGeneric("indexVcf", function(x, ...) standardGeneric("indexVcf"), signature="x") setMethod("indexVcf", "character", function(x, ...) { stopifnot(!is.na(x), length(x) > 0) if(length(x) == 1L){ index <- Rsamtools::indexTabix(x, format="vcf4", ...) VcfFile(x, index) }else{ index <- sapply(x, FUN=Rsamtools::indexTabix, format="vcf4", ...) VcfFileList(x, index) } }) setMethod("indexVcf", "VcfFile", function(x, ...) { index <- index(x) newDx = NA if (is.na(index) || length(index) == 0L){ index <- paste(path(x), "tbi", sep=".") newDx <- index } if (!file.exists(index)) newDx <- Rsamtools::indexTabix(path(x), format="vcf4", ...) if (!is.na(newDx)) index(x) <- newDx x }) setMethod("indexVcf", "VcfFileList", function(x, ... ) { ind = index(x) dontExist = which(!file.exists(ind)) if (length(dontExist) != 0L){ fn <- function(dx, obj){ Rsamtools::indexTabix(path(obj)[dx], format="vcf4", ...) } newDx = sapply(dontExist, FUN=fn, obj=x) ind[dontExist] <- newDx index(x) <- ind } x }) setMethod("seqinfo", "VcfFile", function(x) { seqinfo(scanVcfHeader(path(x))) }) setMethod("seqinfo", "VcfFileList", function(x) { si = lapply(x, function(elt) as(seqinfo(elt), "GRanges")) grl <- as(si, "GRangesList") seqinfo(grl) }) setMethod("vcfFields", "character", function(x, ...) { stopifnot(!is.na(x)) hdr <- scanVcfHeader(x) vcfFields(hdr) }) setMethod("vcfFields", "VcfFile", function(x, ...) { vcfFields(path(x)) }) setMethod("vcfFields", "VcfFileList", function(x, ...) { vcfFields(path(x)) }) VariantAnnotation/R/methods-VCFHeader-class.R0000644000175100017510000001024614614305321022052 0ustar00biocbuildbiocbuild### ========================================================================= ### VCFHeader class methods ### ========================================================================= ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Constructor ### VCFHeader <- function(reference=character(), samples=character(), header=DataFrameList(), ...) { new("VCFHeader", reference=reference, samples=samples, header=header, ...) } ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Getters and Setters ### setMethod("reference", "VCFHeader", function(x) { slot(x, "reference") }) setMethod("samples", "VCFHeader", function(object) { slot(object, "samples") }) setMethod("header", "VCFHeader", function(x) { slot(x, "header") }) ## meta setMethod("meta", "VCFHeader", function(x) { dat <- slot(x, "header") nms <- c("INFO", "FORMAT", "QUAL", "FILTER", "ALT", "REF") dat[!names(dat) %in% nms] }) setReplaceMethod("meta", c("VCFHeader", "DataFrame"), function(x, value) meta(x) <- as(value, "DataFrameList") ) setReplaceMethod("meta", c("VCFHeader", "DataFrameList"), function(x, value) { dat <- slot(x, "header") slot(x, "header") <- c(dat[!names(dat) %in% names(value)], value) validObject(x) x }) ## fixed (QUAL, FILTER, ALT, REF) setMethod("fixed", "VCFHeader", function(x) { fixed <- c("QUAL", "FILTER", "ALT", "REF") lst <- slot(x, "header") lst[names(lst) %in% fixed] }) setReplaceMethod("fixed", c("VCFHeader", "DataFrameList"), function(x, value) { if (!all(names(value) %in% c("QUAL", "FILTER", "ALT", "REF"))) stop("names for 'fixed' can be 'QUAL', 'FILTER', 'ALT' or 'REF'") dat <- slot(x, "header") slot(x, "header") <- c(dat[!names(dat) %in% names(value)], value) x }) ## info setMethod("info", "VCFHeader", function(x) { info <- slot(x, "header")$INFO if (is.null(info)) info <- DataFrame(Number=integer(), Type=character(), Description=character()) info }) setReplaceMethod("info", c("VCFHeader", "DataFrame"), function(x, value) { slot(x, "header")$INFO <- value validObject(x) x }) ## geno setMethod("geno", "VCFHeader", function(x) { geno <- slot(x, "header")$FORMAT if (is.null(geno)) geno <- DataFrame(Number=integer(), Type=character(), Description=character()) geno }) setReplaceMethod("geno", c("VCFHeader", "missing", "DataFrame"), function(x, i, ..., value) { slot(x, "header")$FORMAT <- value validObject(x) x }) setMethod("seqinfo", "VCFHeader", function(x) { contig <- slot(x, "header")$contig if (is.null(contig)) Seqinfo() else Seqinfo(rownames(contig), seqlengths = if (is.null(contig$length)) NA else as.integer(contig$length), genome = if (is.null(contig$assembly)) NA else contig$assembly) }) ## vcfFields setMethod("vcfFields", "VCFHeader", function(x, ...) { fixed <- names(fixed(x)) if (!is.null(fixed)) fixed <- c("REF", "ALT", "QUAL", "FILTER") CharacterList(fixed = fixed, info = rownames(info(x)), geno = rownames(geno(x)), samples = samples(x) ) }) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Show ### setMethod(show, "VCFHeader", function(object) { selectSome <- S4Vectors:::selectSome scat <- function(fmt, vals=character(), exdent=2, ...) { vals <- ifelse(nzchar(vals), vals, "''") lbls <- paste(selectSome(vals), collapse=" ") txt <- sprintf(fmt, length(vals), lbls) cat(strwrap(txt, exdent=exdent, ...), sep="\n") } cat("class:", classNameForDisplay(object), "\n") samples <- samples(object) scat("samples(%d): %s\n", samples) meta <- names(meta(object)) scat("meta(%d): %s\n", meta) fixed <- names(fixed(object)) scat("fixed(%d): %s\n", fixed) info <- rownames(info(object)) scat("info(%d): %s\n", info) geno <- rownames(geno(object)) scat("geno(%d): %s\n", geno) }) VariantAnnotation/R/methods-VRanges-class.R0000644000175100017510000005530514614305321021675 0ustar00biocbuildbiocbuild### ========================================================================= ### VRanges: Variants in a GRanges ### ------------------------------------------------------------------------- ### ### Thoughts on the gVCF format. ## The gVCF format is essentially a run-length encoding of wildtype ## calls. We could represent the run as a range, but we would need ## somewhat to indicate "WT". Probably best to go the VCF route: have ## the first ref base, and an NA alt. We can distinguish this from an ## SNV or indel, because the width of the range is > 1, but there is ## only a single ref base. This will break the assertion that the ref ## length always equal the range width, but that is not a big deal. ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Accessors ### setMethod("ref", "VRanges", function(x) x@ref) setReplaceMethod("ref", "VRanges", function(x, value) { x@ref <- S4Vectors:::recycleVector(value, length(x)) x }) setMethod("alt", "VRanges", function(x) x@alt) setReplaceMethod("alt", "VRanges", function(x, value) { x@alt <- as(.rleRecycleVector(value, length(x)), "characterOrRle") x }) setMethod("sampleNames", "VRanges", function(object) object@sampleNames) setReplaceMethod("sampleNames", "VRanges", function(object, value) { object@sampleNames <- as(.rleRecycleVector(value, length(object)), "factorOrRle") object }) setMethod("totalDepth", "VRanges", function(x) x@totalDepth) `totalDepth<-` <- function(x, value) { x@totalDepth <- as(.rleRecycleVector(value, length(x)), "integerOrRle") x } setMethod("altDepth", "VRanges", function(x) x@altDepth) `altDepth<-` <- function(x, value) { x@altDepth <- as(.rleRecycleVector(value, length(x)), "integerOrRle") x } setMethod("refDepth", "VRanges", function(x) x@refDepth) `refDepth<-` <- function(x, value) { x@refDepth <- as(.rleRecycleVector(value, length(x)), "integerOrRle") x } setMethod("softFilterMatrix", "VRanges", function(x) x@softFilterMatrix) setReplaceMethod("softFilterMatrix", "VRanges", function(x, value) { x@softFilterMatrix <- value x }) setMethod("hardFilters", "VRanges", function(x) x@hardFilters) setReplaceMethod("hardFilters", "VRanges", function(x, value) { x@hardFilters <- value x }) setMethod("called", "VRanges", function(x) { rowSums(softFilterMatrix(x)) == ncol(softFilterMatrix(x)) }) setMethod("altFraction", "VRanges", function(x) { altDepth(x) / totalDepth(x) }) setMethod("refFraction", "VRanges", function(x) { refDepth(x) / totalDepth(x) }) setMethod("isDeletion", "VRanges", function(x, ...) .dispatchSNV_ExpandedVCF(.isDeletion, x) ) setMethod("isInsertion", "VRanges", function(x, ...) .dispatchSNV_ExpandedVCF(.isInsertion, x) ) setMethod("isIndel", "VRanges", function(x, ...) .dispatchSNV_ExpandedVCF(.isIndel, x) ) setMethod("isDelins", "VRanges", function(x, ...) .dispatchSNV_ExpandedVCF(.isDelins, x) ) setMethod("isSNV", "VRanges", function(x, ...) .dispatchSNV_ExpandedVCF(.isSNV, x) ) setMethod("isSubstitution", "VRanges", function(x, ...) .dispatchSNV_ExpandedVCF(.isSubstitution, x) ) setMethod("isTransition", "VRanges", function(x, ...) .dispatchSNV_ExpandedVCF(.isTransition, x) ) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Constructor ### VRanges <- function(seqnames = Rle(), ranges = IRanges(), ref = character(), alt = NA_character_, totalDepth = NA_integer_, refDepth = NA_integer_, altDepth = NA_integer_, ..., sampleNames = NA_character_, softFilterMatrix = FilterMatrix(matrix(nrow = length(gr), ncol = 0L), FilterRules()), hardFilters = FilterRules()) { gr <- GRanges(seqnames, ranges, strand = .rleRecycleVector("*", length(ranges)), ...) if (length(gr) == 0L && length(ref) == 0L) { maxLen <- 0L } else { maxLen <- max(length(gr), length(ref), length(alt), length(totalDepth), length(refDepth), length(altDepth), length(sampleNames), nrow(softFilterMatrix)) } if (length(gr) != maxLen) gr <- rep(gr, length.out = maxLen) ref <- as.character(ref) ref <- S4Vectors:::recycleVector(ref, maxLen) alt <- .rleRecycleVector(alt, maxLen) alt <- as(alt, "characterOrRle") refDepth <- .rleRecycleVector(refDepth, maxLen) altDepth <- .rleRecycleVector(altDepth, maxLen) totalDepth <- .rleRecycleVector(totalDepth, maxLen) softFilterMatrix <- as.matrix(softFilterMatrix) storage.mode(softFilterMatrix) <- "logical" softFilterMatrix.ind <- S4Vectors:::recycleVector(seq_len(nrow(softFilterMatrix)), maxLen) softFilterMatrix <- softFilterMatrix[softFilterMatrix.ind,,drop=FALSE] sampleNames <- .rleRecycleVector(sampleNames, maxLen) totalDepth <- as(totalDepth, "integerOrRle") refDepth <- as(refDepth, "integerOrRle") altDepth <- as(altDepth, "integerOrRle") if (any(naToZero(refDepth) + naToZero(altDepth) > totalDepth, na.rm = TRUE)) warning("'refDepth' + 'altDepth' exceeds 'totalDepth'; using GATK?") new("VRanges", gr, ref = ref, alt = alt, totalDepth = totalDepth, refDepth = refDepth, altDepth = altDepth, softFilterMatrix = softFilterMatrix, sampleNames = as(sampleNames, "factorOrRle"), hardFilters = hardFilters) } ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Coercion ### setMethod("relistToClass", "VRanges", function(x) "CompressedVRangesList") parseFilterStrings <- function(x) { x[x == "."] <- NA if (all(x == "PASS", na.rm=TRUE)) return(FilterMatrix(matrix(nrow = length(x), ncol = 0L), FilterRules())) filterSplit <- strsplit(x, ";", fixed=TRUE) filters <- unlist(filterSplit) filterNames <- setdiff(unique(filters[!is.na(filters)]), "PASS") filterMat <- matrix(TRUE, length(x), length(filterNames), dimnames = list(NULL, filterNames)) filterMat[cbind(togroup(PartitioningByWidth(filterSplit)), match(filters, filterNames))] <- FALSE filterMat[is.na(x),] <- NA filterMat } genoToMCol <- function(x) { if (length(dim(x)) == 3) { I(matrix(x, nrow(x) * max(ncol(x), 1L), dim(x)[3])) } else { if (ncol(x) == 0L) { if (is.list(x)) { x <- as.logical(x) } x <- Rle(x[NA], nrow(x)) } else { dim(x) <- NULL if (is.list(x)) x <- as(x, "List") x } } } setAs("VCF", "VRanges", function(from) { from <- expand(from) rd <- rowRanges(from) seqnames <- seqnames(rd) ranges <- ranges(rd) ref <- rd$REF alt <- rd$ALT if (is(alt, "DNAStringSetList") || is(alt, "CharacterList")) alt <- unlist(alt) alt <- as.character(alt) alt[!nzchar(alt)] <- NA alt[alt == "."] <- NA ad <- geno(from)$AD dp4 <- info(from)$DP4 refDepth <- NA_integer_ altDepth <- NA_integer_ if (is.array(ad) && ncol(from) > 0L) { if (length(dim(ad)) == 3L) { refDepth <- ad[,,1,drop=FALSE] altDepth <- ad[,,2,drop=FALSE] } else if (length(dim(ad)) == 2L) { RD <- geno(from)$RD if (is.matrix(RD)) { refDepth <- RD } altDepth <- ad } } else { if (is(dp4, "List") && info(header(from))["DP4","Number"] == "4") { dp4 <- as.matrix(dp4) } if (is.matrix(dp4) && ncol(dp4) == 4L) { refDepth <- dp4[,1,drop=FALSE] + dp4[,2,drop=FALSE] altDepth <- dp4[,3,drop=FALSE] + dp4[,4,drop=FALSE] } } totalDepth <- geno(from)$DP if (is.null(totalDepth) || ncol(from) == 0L) totalDepth <- NA_integer_ nsamp <- ncol(from) if (ncol(from) > 0L) { if (!is.null(colnames(from))) { sampleNames <- Rle(colnames(from), rep(nrow(from), nsamp)) } else { sampleNames <- as.character(seq_len(ncol(from))) } } else sampleNames <- NA_character_ meta <- info(from) if (!is.null(mcols(rd)$QUAL)) { meta <- cbind(mcols(rd)["QUAL"], meta) } if (is.integer(meta$END)) { end(ranges)[!is.na(meta$END)] <- pmax(start(ranges)[!is.na(meta$END)], meta$END[!is.na(meta$END)]) meta$END <- NULL } rownames(meta) <- NULL if (!is.null(rd$FILTER)) filter <- parseFilterStrings(rd$FILTER) else filter <- FilterMatrix(matrix(nrow = nrow(from), ncol = 0L), FilterRules()) if (nsamp > 1L) { meta <- meta[rep(seq_len(nrow(meta)), nsamp),,drop=FALSE] filter <- filter[rep(seq_len(nrow(filter)), nsamp),,drop=FALSE] seqnames <- rep(seqnames, nsamp) ranges <- rep(ranges, nsamp) alt <- rep(alt, nsamp) ref <- rep(ref, nsamp) } else if (nsamp == 0L && !is.null(meta$DP)) { totalDepth <- meta$DP meta$DP <- NULL } if (!is.null(geno(from)[["FT"]])) filter <- cbind(filter, parseFilterStrings(as.vector(geno(from)[["FT"]]))) otherGeno <- geno(from)[setdiff(names(geno(from)), c("AD", "DP", "FT"))] if (length(otherGeno) > 0L) meta <- DataFrame(meta, lapply(otherGeno, genoToMCol)) vr <- VRanges(seqnames, ranges, ref, alt, totalDepth, refDepth, altDepth, hardFilters = FilterRules(), sampleNames = sampleNames, softFilterMatrix = filter, meta) seqinfo(vr) <- seqinfo(from) vr }) setAs("VRanges", "VCF", function(from) { asVCF(from) }) optionalDescriptions <- c( GT = "Genotype", GQ = "Genotype quality", PL = "Normalized, Phred-scaled likelihoods for genotypes", MIN_DP = "Minimum DP observed within the gVCF block", END = "End position of the gVCF WT run" ) makeFORMATheader <- function(x) { fixed <- DataFrame(row.names = c("AD", "DP", "FT"), Number = c(2L, 1L, 1L), Type = c("Integer", "Integer", "String"), Description = c("Allelic depths (number of reads in each observed allele)", "Total read depth", "Variant filters")) df <- rbind(fixed, makeINFOheader(x)) df$Type[df$Type == "Flag"] <- "Integer" # Flags not allowed in FORMAT df } makeINFOheader <- function(x) { df <- mcols(x) if (is.null(df)) df <- make_zero_col_DFrame(length(x)) rownames(df) <- names(x) numberForColumn <- function(xi) { if (length(dim(xi)) == 2) ncol(xi) else if (is.list(xi) || is(xi, "List")) "." else 1L } typeForColumn <- function(xi) { if (is.integer(xi)) "Integer" else if (is.numeric(xi)) "Float" else if (is.logical(xi)) "Flag" else if (is.character(xi) || is.factor(xi)) { if (all(nchar(as.character(xi)) == 1L, na.rm=TRUE)) "Character" else "String" } } df$Number <- as.character(lapply(x, numberForColumn)) df$Type <- as.character(lapply(x, typeForColumn)) if (is.null(df$Description)) df$Description <- optionalDescriptions[rownames(df)] df[c("Number", "Type", "Description")] } makeFILTERheader <- function(x) { mat <- softFilterMatrix(x) if (is(mat, "FilterMatrix")) rules <- filterRules(mat) else rules <- FilterRules() df <- mcols(rules) if (is.null(df)) { df <- make_zero_col_DFrame(length(rules)) } if (is.null(df$Description)) { exprs <- as.logical(lapply(rules, is.expression)) df <- df[exprs,] df$Description <- as.character(lapply(rules[exprs], function(expr) { gsub("\"", "\\\"", gsub("\\", "\\\\", deparse(expr[[1]]), fixed=TRUE), fixed=TRUE) })) } rownames(df) <- names(rules[exprs]) df } ## If a row contains a FALSE, all FALSE filters are listed; ## otherwise, if a row contains an NA or it is empty, the result is ## NA (.), otherwise PASS. makeFILTERstrings <- function(x) { failed <- which(!x) ftNames <- as.character(colnames(x)[col(x)][failed]) ftStrings <- rep(NA_character_, nrow(x)) passedRows <- rowSums(x) > 0L failedRows <- rowSums(!x, na.rm=TRUE) > 0L ftStrings[passedRows & !failedRows] <- "PASS" ftStrings[failedRows] <- unstrsplit(splitAsList(ftNames, row(x)[failed]), ";") ftStrings } isGVCFRun <- function(x) { nchar(ref(x)) == 1L & width(x) > 1L } gVCFRunEnds <- function(x) { ifelse(isGVCFRun(x), end(x), NA_integer_) } vranges2Vcf <- function(x, info = character(), filter = character(), meta = character()) { if (!is.character(info) || any(is.na(info)) || any(!info %in% colnames(mcols(x)))) stop("'info' must be a character vector naming the mcols to include", " in the INFO column of the VCF file; the rest become FORMAT fields.") if (!is.character(filter) || any(is.na(filter)) || any(!filter %in% colnames(softFilterMatrix(x)))) stop("'filter' must be a character vector naming the filters to include", " in the FILTER column of the VCF file; the rest are encoded as the FT", " FORMAT field.") if (!is.character(meta) || any(is.na(meta)) || any(!meta %in% names(metadata(x)))) stop("'meta' must be a character vector naming metadata(x) elements", " to include as metadata in the VCF header.") metaStrings <- as.character(sapply(metadata(x)[meta], as.character)) if (any(elementNROWS(metaStrings) != 1L)) stop("The elements named in 'meta' must be of length 1") if (any(is.na(sampleNames(x)))) { stop("sampleNames(x) must not contain missing values (for VCF export)") } sampleLevels <- levels(sampleNames(x)) if (length(sampleLevels) > 1) { xUniq <- unique(x) } else { xUniq <- x } END <- gVCFRunEnds(xUniq) if (!all(is.na(END))) { if (!is.null(xUniq$END)) { warning("Replacing 'END' metadata/info column with computed gVCF END") } xUniq$END <- END info <- union(info, "END") } rowRanges <- xUniq mcols(rowRanges) <- NULL rowRanges <- as(rowRanges, "GRanges", strict=TRUE) colData <- DataFrame(Samples = seq_along(sampleLevels), row.names = sampleLevels) meta_vector <- c(fileformat = "VCFv4.1", source = paste("VariantAnnotation", packageVersion("VariantAnnotation")), phasing = "unphased", metaStrings) nms <- names(meta_vector) meta_df <- DataFrame(Value = meta_vector, row.names = nms) meta_header <- as(splitAsList(meta_df, nms), "SimpleDataFrameList") genoMCols <- setdiff(names(mcols(x)), info) header <- VCFHeader(reference = seqlevels(x), samples = sampleLevels, header = c(meta_header, DataFrameList( FORMAT = makeFORMATheader(mcols(x)[genoMCols]), INFO = makeINFOheader(mcols(xUniq)[info]), FILTER = makeFILTERheader(x)) )) metadata <- list(header = header) alt <- as.character(alt(xUniq)) qual <- xUniq$QUAL if (is.null(qual) || !is.numeric(qual)) qual <- rep.int(NA_real_, length(xUniq)) filtMat <- softFilterMatrix(xUniq) if (ncol(filtMat) > 0L) filtMat <- filtMat[,filter,drop=FALSE] filterStrings <- makeFILTERstrings(filtMat) fixed <- DataFrame(REF = DNAStringSet(ref(xUniq)), ALT = alt, QUAL = qual, FILTER = filterStrings) if (length(sampleLevels) > 1) { samplesToUniq <- tapply(x, sampleNames(x), function(xi) { match(xi, xUniq) }, simplify=FALSE) } genoArray <- function(v) { v <- as.vector(v) # handles e.g. Rle if (is.logical(v)) { v <- as.integer(v) } width <- length(v)/length(x) if (width > 1L) { v <- matrix(v, nrow=length(x), ncol=width) } if (length(sampleLevels) > 1L) { sample.ord <- order(sampleNames(x)) if (is.matrix(v)) { v <- v[sample.ord,,drop=FALSE] } else { v <- v[sample.ord] } ind <- unlist(samplesToUniq, use.names=FALSE) + (togroup(PartitioningByWidth(samplesToUniq))-1L)*length(xUniq) a <- matrix(NA_integer_, nrow=length(xUniq)*length(sampleLevels), ncol=width) a[ind,] <- v } else { a <- v } if (width > 1L) { array(a, c(length(xUniq), length(sampleLevels), ncol(a))) } else { matrix(a, length(xUniq), length(sampleLevels)) } } alleleDepth <- c(refDepth(x), altDepth(x)) filtMat <- softFilterMatrix(x) if (ncol(filtMat) > 0L) filtMat <- filtMat[,setdiff(colnames(filtMat), filter), drop=FALSE] ftStrings <- makeFILTERstrings(filtMat) geno <- SimpleList(AD = genoArray(alleleDepth), DP = genoArray(totalDepth(x)), FT = genoArray(ftStrings)) if (length(genoMCols) > 0L) geno <- c(geno, SimpleList(lapply(mcols(x)[genoMCols], genoArray))) info <- mcols(xUniq)[info] VCF(rowRanges = rowRanges, colData = colData, metadata = metadata, fixed = fixed, geno = geno, info = info, collapsed = FALSE) } setMethod("asVCF", "VRanges", vranges2Vcf) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Reading from VCF ### VRangesScanVcfParam <- function(fixed="ALT", info=NA, geno="AD", ...) { .Defunct("ScanVcfParam") } readVcfAsVRanges <- function(x, genome, param=ScanVcfParam(), use.names=FALSE, ...) { if (!isTRUEorFALSE(use.names)) { stop("'use.names' must be TRUE or FALSE") } as(readVcf(x, genome, param=param, row.names=use.names, ...), "VRanges") } ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Writing to VCF (see methods-writeVcf.R) ### ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### gVCF support ### addTotalDepthRuns <- function(x, runs, genome) { mins <- viewMins(runs) gr <- as(ranges(runs), "GRanges") ref <- getSeq(genome, resize(gr, 1L)) vr <- VRanges(seqnames(gr), ranges, ref, alt, totalDepth=mins) } ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Filtering ### softFilter <- function(x, filters, ...) { softFilterMatrix(x) <- cbind(softFilterMatrix(x), FilterMatrix(matrix = evalSeparately(filters, x, ...), filterRules = filters)) x } resetFilter <- function(x) { softFilterMatrix(x) <- FilterMatrix(matrix(nrow = length(x), ncol = 0L), filterRules = FilterRules()) x } setMethod("subsetByFilter", c("VRanges", "FilterRules"), function(x, filter) { ans <- callNextMethod(x, filter) hardFilters(ans) <- c(hardFilters(ans), filter) ans }) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Utilities ### setMethod("duplicated", "VRanges", function (x, incomparables = FALSE, fromLast = FALSE, method = c("auto", "quick", "hash")) { if (!identical(incomparables, FALSE)) stop("\"duplicated\" method for VRanges objects ", "only accepts 'incomparables=FALSE'") duplicatedIntegerQuads(as.factor(seqnames(x)), as.factor(alt(x)), start(x), width(x), fromLast = fromLast, method = method) }) setMethod("match", c("VRanges", "VRanges"), function(x, table, nomatch = NA_integer_, incomparables = NULL, method = c("auto", "quick", "hash")) { if (!isSingleNumberOrNA(nomatch)) stop("'nomatch' must be a single number or NA") if (!is.integer(nomatch)) nomatch <- as.integer(nomatch) if (!is.null(incomparables)) stop("\"match\" method for VRanges objects ", "only accepts 'incomparables=NULL'") merge(seqinfo(x), seqinfo(table)) altLevels <- as.character(union(alt(x), alt(table))) x_seqnames <- GenomicRanges:::relevelSeqnamesForMatch(x, table) matchIntegerQuads(x_seqnames, factor(as.character(alt(x)), altLevels), start(x), width(x), as.factor(seqnames(table)), factor(as.character(alt(table)), altLevels), start(table), width(table), nomatch = nomatch, method = method) }) setMethod("%in%", c("VRanges", "TabixFile"), function(x, table) { table <- readVcfAsVRanges(table, genome=genome(x), param=x) x %in% table }) setMethod("tabulate", "VRanges", function(bin, nbins) { if (!missing(nbins)) stop("'nbins' argument not relevant") m <- match(bin, bin) ## for dupes, 'm' always points to the subject with the lowest index tab <- tabulate(m, length(bin)) ans <- bin[tab > 0] ans$sample.count <- tab[tab > 0] ans }) setMethod("merge", c("VRanges", "VRanges"), function(x, y, ...) { ### FIXME: support softFilterMatrix xdf <- as.data.frame(x) ydf <- as.data.frame(y) bothAllNA <- function(nm) all(is.na(slot(x, nm))) && all(is.na(slot(y, nm))) ignore.cols <- Filter(bothAllNA, c("refDepth", "altDepth", "totalDepth")) ignore.cols <- c(ignore.cols, c("width", "strand")) xdf <- xdf[setdiff(colnames(xdf), ignore.cols)] ydf <- ydf[setdiff(colnames(ydf), ignore.cols)] by <- c("seqnames", "start", "end", "ref", "alt", "sampleNames") merged <- merge(xdf, ydf, by = by, ...) with(merged, VRanges(seqnames, IRanges(start, end), ref, alt, NA, NA, NA, sampleNames = sampleNames, merged[setdiff(colnames(merged), by)])) }) setMethod("liftOver", c("VRanges", "Chain"), function(x, chain, ...) { grl <- liftOver(GRanges(seqnames(x), ranges(x)), chain, ...) gr <- unlist(grl, use.names=FALSE) ans <- x[togroup(PartitioningByWidth(grl))] ans <- update(ans, seqinfo = seqinfo(gr), seqnames = seqnames(gr), ranges = ranges(gr)) relist(ans, grl) }) pileupGRanges <- function(x) { x <- x[!isIndel(x)] gr <- GRanges(seqnames(x), ranges(x), strand(x)) sm <- selfmatch(gr) uniq <- sm == seq_len(length(gr)) map <- integer() map[sm[uniq]] <- seq_len(sum(uniq)) pos <- map[sm] base <- match(c(alt(x), ref(x)), DNA_BASES) depth <- c(altDepth(x), refDepth(x)) samp <- as.factor(sampleNames(x)) pileup <- array(0L, c(sum(uniq), length(levels(samp)), length(DNA_BASES)), dimnames=list(NULL, levels(samp), base=DNA_BASES)) pileup[cbind(pos, samp, base)[!is.na(base),]] <- depth[!is.na(base)] ugr <- gr[uniq] ugr$ref[pos] <- ref(x) ugr$pileup <- pileup ugr } ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### Show ### .showHardFilters <- function(object) { cat(S4Vectors:::labeledLine(" hardFilters", names(hardFilters(object)))) } setMethod("show", "VRanges", function(object) { callNextMethod() .showHardFilters(object) }) setMethod(GenomicRanges:::extraColumnSlotNames, "VRanges", function(x) { c("ref", "alt", "totalDepth", "refDepth", "altDepth", "sampleNames", "softFilterMatrix") }) VariantAnnotation/R/methods-VRangesList-class.R0000644000175100017510000000127714614305321022530 0ustar00biocbuildbiocbuild### ========================================================================= ### VRangesList: Where there is an IntegerRanges, there must be a List ### ------------------------------------------------------------------------- ### VRangesList <- function(...) { new("SimpleVRangesList", GRangesList(..., compress=FALSE), elementType="VRanges") } setMethod("stackSamples", "VRangesList", function(x) { stacked <- unlist(x, use.names=FALSE) if (!is.null(names(x))) sampleNames(stacked) <- Rle(names(x), elementNROWS(x)) stacked }) setMethod("ref", "VRangesList", function(x) List(lapply(x, ref))) setMethod("alt", "VRangesList", function(x) List(lapply(x, alt))) VariantAnnotation/R/methods-writeVcf.R0000644000175100017510000002132514614305321021011 0ustar00biocbuildbiocbuild### ========================================================================= ### writeVcf methods ### ========================================================================= .chunkIndex <- function(rows, nchunk, ...) { if (missing("nchunk")) { if (rows > 1e8) n <- ceiling(rows / 3) else if (rows > 1e6) n <- ceiling(rows / 2) else if (rows > 1e5) n <- 1e5 else return(NA_integer_) } else { if (is.na(nchunk)) return(NA_integer_) else n <- nchunk } split(seq_len(rows), ceiling(seq_len(rows)/n)) } .makeVcfMatrix <- function(filename, obj) { ## empty if (length(rd <- rowRanges(obj)) == 0) return(character()) CHROM <- as.vector(seqnames(rd)) POS <- start(rd) if (is.null(ID <- names(rd))) ID <- "." REF <- as.character(ref(obj)) if (is.null(ALT <- alt(obj))) ALT <- rep(".", length(REF)) if (is(ALT, "XStringSetList")) { ALT <- as(ALT, "CharacterList") } ALT <- as.character(unstrsplit(ALT, ",")) ALT[nchar(ALT) == 0L | is.na(ALT)] <- "." if (is.null(QUAL <- qual(obj))) QUAL <- "." else QUAL[is.na(QUAL)] <- "." if (is.null(FILTER <- filt(obj))) FILTER <- "." else FILTER[is.na(FILTER)] <- "." INFO <- .makeVcfInfo(info(obj), length(rd)) FIXED <- paste(CHROM, POS, ID, REF, ALT, QUAL, FILTER, INFO, sep="\t") .makeVcfGeno(filename, FIXED, geno(obj, withDimnames=FALSE), dim(obj)) } .makeVcfGeno <- function(filename, fixed, geno, dvcf, ...) { if ("GT" %in% names(geno)) { geno <- geno[c("GT", setdiff(names(geno), "GT"))] } .Call(.make_vcf_geno, filename, fixed, names(geno), as.list(geno), c(":", ","), dvcf, sapply(geno, function(x) dim(x)[3])) } .makeVcfInfo <- function(info, nrecords, ...) { if (ncol(info) == 0) { return(rep.int(".", nrecords)) } ## Replace NA with '.' in columns with data. ## Columns with no data are set to NA. lists <- sapply(info, function(elt) is.list(elt) || is(elt, "List")) info[lists] <- lapply(info[lists], function(l) { charList <- as(l, "CharacterList") charList@unlistData[is.na(charList@unlistData)] <- "." collapsed <- unstrsplit(charList, ",") ifelse(sum(!is.na(l)) > 0L, collapsed, NA_character_) }) ## Add names to non-NA data. infoMat <- matrix(".", nrow(info), ncol(info)) logicals <- sapply(info, is.logical) infoMat[,logicals] <- unlist(Map(function(l, nm) { ifelse(l, nm, NA_character_) }, info[logicals], as(names(info)[logicals], "List"))) infoMat[,!logicals] <- unlist(Map(function(i, nm) { ifelse(!is.na(i), paste0(nm, "=", i), NA_character_) }, info[!logicals], as(names(info)[!logicals], "List"))) infoVector <- .pasteCollapseRows(infoMat, ";") infoVector[!nzchar(infoVector)] <- "." infoVector } .contigsFromSeqinfo <- function(si) { contig <- paste0("##contig=") } .pasteMultiFieldDF <- function(df, nms) { if (nrow(df) == 0L) return(character(0L)) prs <- paste(rep(colnames(df), each=nrow(df)), "=", unlist(lapply(df, as.character), use.names=FALSE), sep="") lst <- split(prs, row(df)) lns <- unstrsplit(lst, ",") paste("##", nms, "=<", lns, ">", sep="") } .makeVcfHeader <- function(obj, ...) { hdr <- header(obj) ## If fileformat is >=v4.2 or does not exist --> set GENO 'AD' field ## to Number 'G'. The Number field indicates the number of values ## contained in the INFO field. 'G' is a special character and means ## the field has one value for each possible genotype. fileformat <- "fileformat" %in% rownames(meta(hdr)$META) if (!fileformat) fileformat <- "fileformat" %in% names(meta(hdr)) if (fileformat && grepl(fileformat, "v4.2", fixed=TRUE) || !fileformat) { if (any(idx <- rownames(geno(hdr)) == "AD")) geno(hdr)[idx,]$Number <- "G" } ## Format all header lines dflist <- header(hdr) header <- Map(.formatHeader, as.list(dflist), as.list(names(dflist))) ## If fileformat, fileDate or contig do not exist --> add them fileDate <- any(grepl("fileDate", names(header), fixed=TRUE)) if (!fileDate) { fileDate <- paste("##fileDate=", format(Sys.time(), "%Y%m%d"), sep="") header <- c(fileDate, header) } idx <- which(names(header) == "fileformat") if (length(idx) && idx != 1) { fileformat <- header[idx] header[idx] <- NULL header <- c(fileformat, header) } contig <- any(grepl("contig", names(header), fixed=TRUE)) if (!contig) header <- c(header, .contigsFromSeqinfo(seqinfo(obj))) ## Last line before data colnms <- c("#CHROM", "POS", "ID", "REF", "ALT", "QUAL", "FILTER", "INFO") if (length(geno(obj, withDimnames=FALSE)) > 0L) { samples <- colnames(obj) colnms <- c(colnms, "FORMAT", samples[!is.null(samples)]) } colnms <- paste(colnms, collapse="\t") unlist(c(header, colnms), use.names=FALSE) } .formatHeader <- function(df, nms) { ## Support serialized VCF objects with old "META" DataFrame. if (nms == "META" && ncol(df) == 1L) { if (!"fileformat" %in% rownames(df)) df <- rbind(DataFrame(Value="VCFv4.3", row.names="fileformat"), df) fd <- format(Sys.time(), "%Y%m%d") if ("fileDate" %in% rownames(df)) df[rownames(df) == "fileDate", ] <- fd else df <- rbind(df, DataFrame(Value=fd, row.names="fileDate")) paste("##", rownames(df), "=", df[,1], sep="") ## Support VCF v4.2 and v4.3 PEDIGREE field } else if(nms == "PEDIGREE" || nms == "ALT") { if (!is.null(rownames(df))) df <- DataFrame(ID = rownames(df), df) if ("Description" %in% colnames(df)) { # VJC respond LTLA 20 Nov 2021 if (nrow(df) == 0L) return(character()) df$Description <- ifelse(is.na(df$Description), "\".\"", paste("\"", df$Description, "\"", sep="")) } # end response .pasteMultiFieldDF(df, nms) ## 'simple' key-value pairs ## (Rsamtools reports unstructured headers as one column named "Value") } else if(ncol(df) == 1L && names(df)[1] == "Value" && nrow(df) == 1L) { if (nms == "fileDate") { fd <- format(Sys.time(), "%Y%m%d") paste("##fileDate=", fd, sep="") } else paste("##", nms, "=", df[,1], sep="") ## 'non-simple' key-value pairs } else { if ("Description" %in% colnames(df)) { if (nrow(df) == 0L) return(character()) df$Description <- ifelse(is.na(df$Description), "\".\"", paste("\"", df$Description, "\"", sep="")) } df <- DataFrame(ID = rownames(df), df) .pasteMultiFieldDF(df, nms) } } ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### VCF methods ### setMethod(writeVcf, c("VCF", "character"), function(obj, filename, index = FALSE, ...) { con <- file(filename, open="w") on.exit(close(con)) writeVcf(obj, con, index=index, ...) }) setMethod(writeVcf, c("VCF", "connection"), function(obj, filename, index = FALSE, ...) { if (!isTRUEorFALSE(index)) stop("'index' must be TRUE or FALSE") if (!isOpen(filename)) { open(filename) on.exit(close(filename)) } scon <- summary(filename) headerNeeded <- !(file.exists(scon$description) && file.info(scon$description)$size !=0) if (headerNeeded) { hdr <- .makeVcfHeader(obj) writeLines(hdr, filename) } if (index) obj <- sort(obj) if (all(is.na(idx <- .chunkIndex(dim(obj)[1L], ...)))) .makeVcfMatrix(filename, obj) else for (i in idx) .makeVcfMatrix(filename, obj[i]) flush(filename) if (index) { filenameGZ <- bgzip(scon$description, overwrite = TRUE) indexTabix(filenameGZ, format = "vcf") unlink(scon$description) invisible(filenameGZ) } else { invisible(scon$description) } }) ### - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ### VRanges methods ### setMethod(writeVcf, "VRanges", function(obj, filename, ...) { writeVcf(as(obj, "VCF"), filename, ...) }) VariantAnnotation/R/test_VariantAnnotation_package.R0000644000175100017510000000010414614305321023720 0ustar00biocbuildbiocbuild.test <- function() BiocGenerics:::testPackage("VariantAnnotation") VariantAnnotation/R/use_vep_api.R0000644000175100017510000000555114614305321020061 0ustar00biocbuildbiocbuild#' helper function to construct inputs for VEP REST API #' @import httr #' @import jsonlite #' @param chr character(1) #' @param pos numeric(1) #' @param id character(1) #' @param ref character(1) #' @param alt character(1) #' @note Produces a string used as an example in VEP API documentation. variant_body = function(chr, pos, id, ref, alt) { sprintf("%s %d %s %s %s . . .", chr, pos, id, ref, alt) } #' elementary vep/homo_sapiens/region call to ensembl VEP REST API #' @importFrom curl has_internet #' @param chr character(1) ensembl chromosome identifier (e.g., "7") #' @param pos numeric(1) 1-based chromosome position #' @param id character(1) arbitrary identifier #' @param ref character(1) reference allele #' @param alt character(1) alternative allele #' @note This function prepares a POST to rest.ensembl.org/vep/homo_sapiens/region endpoint. #' @return Instance of 'response' defined in httr package. #' @examples #' chk = post_Hs_region("7", 155800001, "chk", "A", "T") #' chk #' res = jsonlite::fromJSON(jsonlite::toJSON(httr::content(chk))) #' dim(chk) #' @export post_Hs_region = function(chr, pos, id, ref, alt) { stopifnot(curl::has_internet()) server <- "https://rest.ensembl.org" ext <- "/vep/homo_sapiens/region" tj = jsonlite::toJSON(list(variants=variant_body(chr, pos, id, ref, alt))) ans = httr::POST(paste(server, ext, sep = ""), httr::content_type("application/json"), httr::accept("application/json"), body = as.character(tj) ) httr::stop_for_status(ans) ans } #' Use the VEP region API on variant information in a VCF object as defined in VariantAnnotation. #' @param vcfobj instance of VCF class; note the difference between the CollapsedVCF and #' ExpandedVCF instances. #' @param snv_only logical(1) if TRUE filter the VCF to information about single nucleotide addresses #' @param chk_max logical(1) requests to ensembl VEP API are limited to 200 positions; if #' TRUE and the request involves more than 200 positions, an error is thrown by this function. #' @return instance of 'response' from httr package #' @examples #' fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") #' r22 = readVcf(fl) #' dr = which(width(rowRanges(r22))!=1) #' r22s = r22[-dr] #' res = vep_by_region(r22[1:100], snv_only=FALSE, chk_max=FALSE) #' ans = jsonlite::fromJSON(jsonlite::toJSON(httr::content(res))) #' @export vep_by_region = function(vcfobj, snv_only=TRUE, chk_max=TRUE) { stopifnot(inherits(vcfobj, "VCF")) if (snv_only) { dr = which(width(rowRanges(vcfobj))!=1) if (length(dr)>0) vcfobj = vcfobj[-dr] } if (chk_max) { if (nrow(vcfobj) > 200) stop("VEP API is limited to 200 positions") } rr = rowRanges(vcfobj) post_Hs_region( chr = as.character(seqnames(rr)), pos = start(rr), id = names(rr), ref = as.character(rr$REF), alt = as.character(unlist(rr$ALT)) ) } VariantAnnotation/src/0000755000175100017510000000000014614361054016024 5ustar00biocbuildbiocbuildVariantAnnotation/src/Biostrings_stubs.c0000644000175100017510000000003714614305321021526 0ustar00biocbuildbiocbuild#include "_Biostrings_stubs.c" VariantAnnotation/src/dna_hash.c0000644000175100017510000000626214614305321017736 0ustar00biocbuildbiocbuild#include "dna_hash.h" /* DNAStringSet -- hash */ #include "IRanges_interface.h" #include "XVector_interface.h" #include "Biostrings_interface.h" #include KHASH_MAP_INIT_STR(ref, int) struct dna_hash_t { khash_t(ref) *hash; int len, size, hash_idx, *offset; }; static const double DNA_GROW = 1.6; struct dna_hash_t *dna_hash_new(const int size) { struct dna_hash_t *dna = Calloc(1, struct dna_hash_t); dna->hash = kh_init(ref); dna->offset = Calloc(size, int); dna->size = size; dna->len = dna->hash_idx = 0; return dna; } void dna_hash_free(struct dna_hash_t *dna) { khiter_t key; for (key = kh_begin(dna->hash); key != kh_end(dna->hash); ++key) { if (kh_exist(dna->hash, key)) Free(kh_key(dna->hash, key)); } kh_destroy(ref, dna->hash); Free(dna->offset); Free(dna); } void dna_hash_grow(struct dna_hash_t *dna, int size) { dna->offset = Realloc(dna->offset, size, int); dna->size = size; } void dna_hash_append(struct dna_hash_t *dna, const char *value) { khiter_t key; key = kh_get(ref, dna->hash, value); if (key == kh_end(dna->hash)) { int ret; char *buf = Calloc(strlen(value) + 1, char); strcpy(buf, value); key = kh_put(ref, dna->hash, buf, &ret); kh_value(dna->hash, key) = dna->hash_idx++; } if (dna->len == dna->size) dna_hash_grow(dna, DNA_GROW * dna->size); dna->offset[dna->len] = kh_value(dna->hash, key); dna->len++; } SEXP dna_hash_as_DNAStringSet(struct dna_hash_t *dna) { int *iwidth, *istart, twidth, i; SEXP tag, start, width, ranges, xstringset; Rbyte *tagp; khiter_t key; istart = Calloc(dna->hash_idx, int); iwidth = Calloc(dna->hash_idx, int); twidth = 0; for (key = kh_begin(dna->hash); key != kh_end(dna->hash); ++key) { if (!kh_exist(dna->hash, key)) continue; kh_cstr_t cstr = kh_key(dna->hash, key); int idx = kh_value(dna->hash, key); istart[idx] = twidth + 1; iwidth[idx] = '.' == *cstr ? 0 : strlen(cstr); twidth += iwidth[idx]; } /* RAW */ PROTECT(tag = NEW_RAW(twidth)); tagp = RAW(tag); for (key = kh_begin(dna->hash); key != kh_end(dna->hash); ++key) { if (!kh_exist(dna->hash, key)) continue; kh_cstr_t cstr = kh_key(dna->hash, key); int idx = kh_value(dna->hash, key); if ('.' == *cstr) continue; for (int j = 0; j < iwidth[idx]; ++j) { if ('I' == cstr[j]) *tagp++ = DNAencode('.'); else *tagp++ = DNAencode(cstr[j]); } } /* ranges */ PROTECT(start = NEW_INTEGER(dna->len)); PROTECT(width = NEW_INTEGER(dna->len)); for (i = 0; i < dna->len; ++i) { int idx = dna->offset[i]; INTEGER(start)[i] = istart[idx]; INTEGER(width)[i] = iwidth[idx]; } PROTECT(ranges = new_IRanges("IRanges", start, width, R_NilValue)); /* DNAStringSet */ PROTECT(xstringset = new_XRawList_from_tag( "DNAStringSet", "DNAString", tag, ranges)); Free(iwidth); Free(istart); UNPROTECT(5); return xstringset; } VariantAnnotation/src/dna_hash.h0000644000175100017510000000052314614305321017735 0ustar00biocbuildbiocbuild#ifndef _DNA_HASH_H #define _DNA_HASH_H #include struct dna_hash_t *dna_hash_new(const int size); void dna_hash_free(struct dna_hash_t *dna); void dna_hash_grow(struct dna_hash_t *dna, int size); void dna_hash_append(struct dna_hash_t *dna, const char *value); SEXP dna_hash_as_DNAStringSet(struct dna_hash_t *dna); #endif VariantAnnotation/src/IRanges_stubs.c0000644000175100017510000000003414614305321020730 0ustar00biocbuildbiocbuild#include "_IRanges_stubs.c" VariantAnnotation/src/Makevars0000644000175100017510000000066314614305321017520 0ustar00biocbuildbiocbuild## This file uses GNU make syntax $(shell ...) so we need to ## have "SystemRequirements: GNU make" in the DESCRIPTION file. ## See Rhtslib's vignette for details. RHTSLIB_LIBS=$(shell "${R_HOME}/bin${R_ARCH_BIN}/Rscript" -e \ 'Rhtslib::pkgconfig("PKG_LIBS")') RHTSLIB_CPPFLAGS=$(shell "${R_HOME}/bin${R_ARCH_BIN}/Rscript" -e \ 'Rhtslib::pkgconfig("PKG_CPPFLAGS")') PKG_LIBS=$(RHTSLIB_LIBS) PKG_CPPFLAGS=$(RHTSLIB_CPPFLAGS) VariantAnnotation/src/R_init_VariantAnnotation.c0000644000175100017510000000114014614305321023122 0ustar00biocbuildbiocbuild#include #include "vcffile.h" #include "writevcf.h" #include "utilities.h" static const R_CallMethodDef callMethods[] = { /* vcffile.c */ {".scan_vcf_character", (DL_FUNC) & scan_vcf_character, 7}, {".scan_vcf_connection", (DL_FUNC) & scan_vcf_connection, 6}, {".tabix_as_vcf", (DL_FUNC) & tabix_as_vcf, 6}, {"matrix_pasteCollapseRows", (DL_FUNC) & matrix_pasteCollapseRows, 2}, {".make_vcf_geno", (DL_FUNC) & make_vcf_geno, 7}, {NULL, NULL, 0} }; void R_init_VariantAnnotation(DllInfo * info) { R_registerRoutines(info, NULL, callMethods, NULL, NULL); } VariantAnnotation/src/rle.c0000644000175100017510000000311514614305321016745 0ustar00biocbuildbiocbuild#include "rle.h" #include "utilities.h" /* rle representation */ static const double RLE_GROW = 1.6; struct rle_t *rle_new(const int size) { struct rle_t *rle = Calloc(1, struct rle_t); rle->size = size; rle->len = 0; rle->value = Calloc(size, char *); rle->length = Calloc(size, int); return rle; } void rle_free(struct rle_t *rle) { for (int i = 0; i < rle->len; ++i) Free(rle->value[i]); Free(rle->value); Free(rle->length); Free(rle); } void rle_grow(struct rle_t *rle, int size) { rle->value = Realloc(rle->value, size, char *); rle->length = Realloc(rle->length, size, int); rle->size = size; } void rle_append(struct rle_t *rle, const char *value) { if (0 == rle->len || 0 != strcmp(value, rle->value[rle->len - 1])) { if (rle->len == rle->size) rle_grow(rle, RLE_GROW * rle->size); rle->value[rle->len] = Strdup(value); rle->length[rle->len] = 1; rle->len += 1; } else rle->length[rle->len - 1] += 1; } SEXP rle_as_Rle(struct rle_t *rle) { SEXP value, length, nmspc, fun, expr, result; PROTECT(value = Rf_allocVector(STRSXP, rle->len)); PROTECT(length = Rf_allocVector(INTSXP, rle->len)); for (int i = 0; i < rle->len; ++i) { SET_STRING_ELT(value, i, mkChar(rle->value[i])); INTEGER(length)[i] = rle->length[i]; } PROTECT(nmspc = get_namespace("IRanges")); PROTECT(fun = findFun(install("Rle"), nmspc)); PROTECT(expr = lang3(fun, value, length)); result = eval(expr, R_GlobalEnv); UNPROTECT(5); return result; } VariantAnnotation/src/rle.h0000644000175100017510000000051714614305321016755 0ustar00biocbuildbiocbuild#ifndef _RLE_H #define _RLE_H #include struct rle_t { int len, size, *length; char **value; }; struct rle_t *rle_new(const int size); void rle_free(struct rle_t *rle); void rle_grow(struct rle_t *rle, int size); void rle_append(struct rle_t *rle, const char *value); SEXP rle_as_Rle(struct rle_t *rle); #endif VariantAnnotation/src/strhash.c0000644000175100017510000000114114614305321017634 0ustar00biocbuildbiocbuild#include #include "strhash.h" #include "utilities.h" khash_t(strhash) *_strhash_new() { return kh_init(strhash); } void _strhash_free(khash_t(strhash) *str) { khiter_t key; for (key = kh_begin(str); key != kh_end(str); ++key) { if (kh_exist(str, key)) Free(kh_key(str, key)); } kh_destroy(strhash, str); } const char *_strhash_put(khash_t(strhash) *str, const char *value) { int ret; khiter_t key = kh_get(strhash, str, value); if (key == kh_end(str)) key = kh_put(strhash, str, Strdup(value), &ret); return kh_key(str, key); } VariantAnnotation/src/strhash.h0000644000175100017510000000037214614305321017646 0ustar00biocbuildbiocbuild#ifndef _STRHASH_H_ #define _STRHASH_H_ #include KHASH_SET_INIT_STR(strhash) khash_t(strhash) *_strhash_new(); void _strhash_free(khash_t(strhash) *str); const char *_strhash_put(khash_t(strhash) *str, const char *value); #endif VariantAnnotation/src/utilities.c0000644000175100017510000000164214614305321020201 0ustar00biocbuildbiocbuild#include "utilities.h" /* get_namespace */ SEXP get_namespace(const char *pkg) { SEXP fun = PROTECT(findFun(install("getNamespace"), R_GlobalEnv)); SEXP nmspc = PROTECT(mkString(pkg)); nmspc = eval(lang2(fun, nmspc), R_GlobalEnv); UNPROTECT(2); return nmspc; } /* iterator to return null-terminated delimited fields */ char *it_init(struct it_t *it, char *str, char delim) { it->str = str; it->delim = delim; it->n_fld = (*str == '\0') ? 0 : 1; while (*str != '\0') if (*str++ == delim) it->n_fld += 1; return it_next(it); } inline char *it_next(struct it_t *it) { const char delim = it->delim, *curr = it->str; char *start = it->str; while ('\0' != *curr && delim != *curr) ++curr; it->str += curr - it->str; if ('\0' != *it->str) *it->str++ = '\0'; return start; } inline int it_nfld(const struct it_t *it) { return it->n_fld; } VariantAnnotation/src/utilities.h0000644000175100017510000000054514614305321020207 0ustar00biocbuildbiocbuild#ifndef _UTILITIES_H #define _UTILITIES_H #include #define Strdup(x) strcpy(Calloc(strlen(x) + 1, char), x) SEXP get_namespace(const char *pkg); struct it_t { char *str; char delim; int n_fld; }; char *it_init(struct it_t *it, char *str, char delim); char *it_next(struct it_t *it); int it_nfld(const struct it_t *it); #endif VariantAnnotation/src/vcffile.c0000644000175100017510000004647714614305321017623 0ustar00biocbuildbiocbuild#include #include #include "vcffile.h" #include "vcftype.h" #include "rle.h" #include "dna_hash.h" #include "utilities.h" #include "IRanges_interface.h" #include "XVector_interface.h" #include #include "strhash.h" enum { ROWRANGES_IDX = 0, REF_IDX, ALT_IDX, QUAL_IDX, FILTER_IDX, INFO_IDX, GENO_IDX }; enum { POS_IDX = 0, ID_IDX }; static const int N_FLDS = 7; static const int TBX_INIT_SIZE = 512; KHASH_SET_INIT_STR(WARNINGS) static khash_t(WARNINGS) *vcfwarn_new() { return kh_init(WARNINGS); } static void vcfwarn(khash_t(WARNINGS) *warnings, const char *fmt, ...) { static const int bufsize = 2048; char *buf = Calloc(strlen(fmt), char); int ret; memcpy(buf, fmt, strlen(fmt) + 1); if (kh_get(WARNINGS, warnings, buf) != kh_end(warnings)) { Free(buf); return; } kh_put(WARNINGS, warnings, buf, &ret); buf = Calloc(bufsize, char); va_list argp; va_start(argp, fmt); (void) vsnprintf(buf, bufsize, fmt, argp); va_end(argp); Rf_warning("%s", buf); Free(buf); return; } static void vcfwarn_free(khash_t(WARNINGS) *warnings) { khiter_t key; for (key = kh_begin(warnings); key != kh_end(warnings); ++key) if (kh_exist(warnings, key)) Free(kh_key(warnings, key)); kh_destroy(WARNINGS, warnings); } struct parse_t { struct vcftype_t *vcf; struct rle_t *chrom; struct dna_hash_t *ref; khash_t(strhash) *str; /* general purpose hash of strings */ int vcf_n, imap_n, gmap_n, smap_n, *smapidx; const char **inms, **gnms, **snms; khash_t(WARNINGS) *warnings; }; static struct vcftype_t *_types_alloc(const int x_n, const int y_n, Rboolean isInfo, SEXP map, khash_t(strhash) *str) { SEXP elt; const char *n; SEXPTYPE type; struct vcftype_t *types; const int map_n = Rf_length(map); const char *dot = _strhash_put(str, "."); if (map_n == 0) /* no INFO or GENO in header */ return _vcftype_new(VECSXP, NILSXP, '\0', NULL, 0, 0, 0, 0); types = _vcftype_new(VECSXP, NILSXP, '\0', NULL, map_n, 1, 1, 0); for (int j = 0; j < map_n; ++j) { elt = VECTOR_ELT(map, j); n = CHAR(STRING_ELT(VECTOR_ELT(elt, 0), 0)); type = TYPEOF(VECTOR_ELT(elt, 1)); if (type == NILSXP) { /* skip */ types->u.list[j] = _vcftype_new(NILSXP, NILSXP, *n, NULL, 0, 0, 0, 0); } else if (*n == '.' || *n == 'A' || *n == 'G' || *n == 'R') { types->u.list[j] = _vcftype_new(VECSXP, type, *n, dot, x_n, y_n, 1, 2); } else { /* array */ int z_n = atoi(n); int dim = (z_n == 1) ? (isInfo ? 1 : 2) : 3; types->u.list[j] = _vcftype_new(type, NILSXP, *n, dot, x_n, y_n, z_n, dim); } } return types; } static void _types_grow(struct vcftype_t *types, int vcf_n) { for (int j = 0; j < types->nrow; ++j) types->u.list[j] = _vcftype_grow(types->u.list[j], vcf_n); } static SEXP _trim_null(SEXP data, const char **cnms) { SEXP nms = PROTECT(NEW_CHARACTER(Rf_length(data))); int j = 0; for (int i = 0; i < Rf_length(data); ++i) { if (R_NilValue != VECTOR_ELT(data, i)) { SET_VECTOR_ELT(data, j, VECTOR_ELT(data, i)); SET_STRING_ELT(nms, j, mkChar(cnms[i])); j++; } } PROTECT(nms = Rf_lengthgets(nms, j)); PROTECT(data = Rf_lengthgets(data, j)); data = Rf_namesgets(data, nms); UNPROTECT(3); return data; } static struct vcftype_t *_vcf_alloc(const int vcf_n, SEXP smap, SEXP fmap, SEXP imap, SEXP gmap, khash_t(strhash) *str) { SEXP elt; SEXPTYPE type; const char *n; struct vcftype_t *vcf, *rowRanges; vcf = _vcftype_new(VECSXP, NILSXP, '\0', NULL, N_FLDS, 1, 1, 0); /* FIXED fields */ rowRanges = _vcftype_new(VECSXP, VECSXP, '\0', NULL, 2, 1, 1, 0); rowRanges->u.list[POS_IDX] = _vcftype_new(INTSXP, NILSXP, '\0', NULL, vcf_n, 1, 1, 0); rowRanges->u.list[ID_IDX] = _vcftype_new(STRSXP, NILSXP, '\0', NULL, vcf_n, 1, 1, 0); vcf->u.list[ROWRANGES_IDX] = rowRanges; const char *blank = _strhash_put(str, ""), *dot = _strhash_put(str, "."); for (int i = 2; i < Rf_length(fmap); ++i) { const char *nm = CHAR(STRING_ELT(GET_NAMES(fmap), i)); elt = VECTOR_ELT(fmap, i); n = CHAR(STRING_ELT(VECTOR_ELT(elt, 0), 0)); type = TYPEOF(VECTOR_ELT(elt, 1)); if (0 == strcmp(nm, "ALT")) { vcf->u.list[ALT_IDX] = _vcftype_new(VECSXP, type, *n, blank, vcf_n, 1, 1, 0); } else if (0 == strcmp(nm, "QUAL")) { vcf->u.list[QUAL_IDX] = _vcftype_new(type, NILSXP, *n, dot, vcf_n, 1, 1, 0); } else if (0 == strcmp(nm, "FILTER")) { vcf->u.list[FILTER_IDX] = _vcftype_new(type, NILSXP, *n, dot, vcf_n, 1, 1, 0); } else Rf_error("[internal] unknown 'fixed' field '%s'", nm); } /* INFO, FORMAT fields */ int nonzero = 0; for (int i = 0; i < Rf_length(smap); ++i) if (INTEGER(smap)[i] != 0) nonzero += 1; vcf->u.list[INFO_IDX] = _types_alloc(vcf_n, 1, TRUE, imap, str); vcf->u.list[GENO_IDX] = _types_alloc(vcf_n, nonzero, FALSE, gmap, str); return vcf; } static void _vcf_grow(struct vcftype_t * vcf, int vcf_n) { struct vcftype_t *elt; elt = vcf->u.list[ROWRANGES_IDX]; for (int i = POS_IDX; i <= ID_IDX; ++i) elt->u.list[i] = _vcftype_grow(elt->u.list[i], vcf_n); for (int i = ALT_IDX; i <= FILTER_IDX; ++i) vcf->u.list[i] = _vcftype_grow(vcf->u.list[i], vcf_n); _types_grow(vcf->u.list[INFO_IDX], vcf_n); _types_grow(vcf->u.list[GENO_IDX], vcf_n); } static void _parse(char *line, const int irec, const struct parse_t *parse, Rboolean row_names) { khash_t(strhash) *str = parse->str; struct vcftype_t *vcf = parse->vcf, *rowRanges, *elt, *info; const int imap_n = parse->imap_n, gmap_n = parse->gmap_n; const int smap_n = parse->smap_n; const char **inms = parse->inms, **gnms = parse->gnms; const char **snms = parse->snms; const int *smapidx = parse->smapidx; int fmtidx, imapidx; int j; struct it_t it0, it1, it2; char *sample, *ifld, *ikey; /* FIXED fields */ char *chrom, *pos, *id, *ref, *alt, *field; int alt_n; chrom = it_init(&it0, line, '\t'); /* CHROM */ rle_append(parse->chrom, chrom); rowRanges = vcf->u.list[ROWRANGES_IDX]; pos = it_next(&it0); /* POS */ rowRanges->u.list[POS_IDX]->u.integer[irec] = atoi(pos); id = it_next(&it0); /* ID */ ref = it_next(&it0); /* REF */ dna_hash_append(parse->ref, ref); alt = it_next(&it0); /* ALT */ alt_n = _vcftype_ragged_n(alt); _vcftype_setarray(vcf->u.list[ALT_IDX], irec, 0, alt, alt_n, str); _vcftype_set(vcf->u.list[QUAL_IDX], irec, _strhash_put(str, it_next(&it0))); /* QUAL */ _vcftype_set(vcf->u.list[FILTER_IDX], irec, _strhash_put(str, it_next(&it0))); /* FILTER */ if (row_names) { if ('.' == *id && '\0' == *(id + 1)) { /* construct ID if missing: chrom\0pos\0ID\0ref\0alt\0 ==> chrom:pos_ref/alt\0 */ *(pos - 1) = ':'; *(id - 1) = '_'; *(alt - 1) = '/'; while (*ref != '\0') *id++ = *ref++; *id = '\0'; id = chrom; } rowRanges->u.list[ID_IDX]->u.character[irec] = _strhash_put(str, id); } /* INFO */ field = it_next(&it0); info = vcf->u.list[INFO_IDX]; if (1 == imap_n && NULL == inms) { /* no header; parse as char */ elt = info->u.list[0]; elt->u.character[irec] = _strhash_put(str, field); } else if (0 != imap_n) { for (ifld = it_init(&it1, field, ';'); '\0' != *ifld; ifld = it_next(&it1)) { ikey = it_init(&it2, ifld, '='); for (imapidx = 0; imapidx < imap_n; ++imapidx) if (0L == strcmp(ikey, inms[imapidx])) { elt = info->u.list[imapidx]; _vcftype_setarray(elt, irec, 0, it_next(&it2), alt_n, str); break; } } /* missing data for type 'A', 'G' and 'R' need to be padded w/ NA's */ for (imapidx = 0; imapidx < imap_n; ++imapidx) { elt = info->u.list[imapidx]; if (elt->number == 'A' || elt->number == 'G' || elt->number == 'R') _vcftype_padarray(elt, irec, 0, str, alt_n); } } /* FORMAT */ if (0 == gmap_n) return; /* early exit */ field = it_init(&it2, it_next(&it0), ':'); int n_fld = it_nfld(&it2); int *gmapidx = Calloc(n_fld, int); for (fmtidx = 0; '\0' != *field; field = it_next(&it2), fmtidx++) { for (j = 0; j < gmap_n; ++j) if (0L == strcmp(field, gnms[j])) break; gmapidx[fmtidx] = j; /* gmap_n to ignore */ } /* SAMPLE */ struct vcftype_t *geno = vcf->u.list[GENO_IDX]; const int max_fmtidx = fmtidx; for (int j = 0; j < smap_n; ++j) { sample = it_next(&it0); if (0 == smapidx[j]) continue; for (field = it_init(&it2, sample, ':'), fmtidx = 0; '\0' != *field; field = it_next(&it2), fmtidx++) { if (fmtidx >= max_fmtidx) { vcfwarn(parse->warnings, "record %d sample %s: fewer FORMAT fields than GENO fields", irec + 1, snms[j]); continue; } if (gmap_n == gmapidx[fmtidx]) continue; /* unknown FORMAT */ elt = geno->u.list[ gmapidx[fmtidx] ]; _vcftype_setarray(elt, irec, smapidx[j] - 1, field, alt_n, str); } /* missing data for type 'A', 'G' and 'R' need to be padded w/ NA's */ for (fmtidx = 0; fmtidx < gmap_n; ++fmtidx) { elt = geno->u.list[fmtidx]; if (elt->number == 'A' || elt->number == 'G' || elt->number == 'R') _vcftype_padarray(elt, irec, smapidx[j] - 1, str, alt_n); } } Free(gmapidx); } static SEXP _vcf_as_SEXP(struct parse_t *parse, SEXP fmap, SEXP smap, Rboolean row_names) { SEXP result = PROTECT(_vcftype_as_SEXP(parse->vcf)); /* ref: DNAStringSet */ SEXP dna = dna_hash_as_DNAStringSet(parse->ref); SET_VECTOR_ELT(result, REF_IDX, dna); /* rowRanges: GRanges */ SEXP rowRanges, seqnames, start, width, names; PROTECT(seqnames = rle_as_Rle(parse->chrom)); rowRanges = VECTOR_ELT(result, ROWRANGES_IDX); start = VECTOR_ELT(rowRanges, POS_IDX); if (!row_names) names = R_NilValue; else names = VECTOR_ELT(rowRanges, ID_IDX); width = get_XVectorList_width(dna); SEXP ranges, nmspc, fun, expr; PROTECT(ranges = new_IRanges("IRanges", start, width, names)); PROTECT(nmspc = get_namespace("GenomicRanges")); PROTECT(fun = findFun(install("GRanges"), nmspc)); PROTECT(expr = lang3(fun, seqnames, ranges)); SET_VECTOR_ELT(result, ROWRANGES_IDX, eval(expr, R_GlobalEnv)); UNPROTECT(5); /* names */ SEXP nms, sxp = Rf_getAttrib(fmap, R_NamesSymbol), elt; PROTECT(nms = Rf_allocVector(STRSXP, Rf_length(result))); SET_STRING_ELT(nms, ROWRANGES_IDX, mkChar("rowRanges")); SET_STRING_ELT(nms, REF_IDX, mkChar("REF")); SET_STRING_ELT(nms, ALT_IDX, mkChar("ALT")); SET_STRING_ELT(nms, QUAL_IDX, mkChar("QUAL")); SET_STRING_ELT(nms, FILTER_IDX, mkChar("FILTER")); SET_STRING_ELT(nms, INFO_IDX, mkChar("INFO")); SET_STRING_ELT(nms, GENO_IDX, mkChar("GENO")); Rf_namesgets(result, nms); UNPROTECT(1); PROTECT(nms = Rf_allocVector(STRSXP, parse->imap_n)); if (1 == parse->imap_n && NULL == parse->inms) SET_STRING_ELT(nms, 0, R_NaString); else for (int i = 0; i < parse->imap_n; ++i) SET_STRING_ELT(nms, i, mkChar(parse->inms[i])); Rf_namesgets(VECTOR_ELT(result, INFO_IDX), nms); UNPROTECT(1); PROTECT(nms = Rf_allocVector(STRSXP, parse->gmap_n)); for (int i = 0; i < parse->gmap_n; ++i) SET_STRING_ELT(nms, i, mkChar(parse->gnms[i])); Rf_namesgets(VECTOR_ELT(result, GENO_IDX), nms); UNPROTECT(1); SEXP samplenms; int nonzero = 0; for (int i = 0; i < Rf_length(smap); ++i) if (INTEGER(smap)[i] != 0) nonzero += 1; PROTECT(samplenms = Rf_allocVector(STRSXP, nonzero)); for (int i = 0; i < parse->smap_n; ++i) if (INTEGER(smap)[i] != 0) SET_STRING_ELT(samplenms, INTEGER(smap)[i] - 1, mkChar(parse->snms[i])); PROTECT(nms = Rf_allocVector(VECSXP, 2)); SET_VECTOR_ELT(nms, 0, R_NilValue); SET_VECTOR_ELT(nms, 1, samplenms); sxp = VECTOR_ELT(result, GENO_IDX); for (int i = 0; i < Rf_length(sxp); ++i) { elt = VECTOR_ELT(sxp, i); if (R_NilValue != elt) Rf_dimnamesgets(elt, nms); } UNPROTECT(2); UNPROTECT(1); return result; } static void _vcf_types_tidy(struct parse_t *parse, SEXP result) { SEXP elt; if (NULL == parse->inms) { parse->inms = (const char **) R_alloc(sizeof(const char *), 1); parse->inms[0] = "INFO"; } elt = VECTOR_ELT(result, INFO_IDX); SET_VECTOR_ELT(result, INFO_IDX, _trim_null(elt, parse->inms)); elt = VECTOR_ELT(result, GENO_IDX); SET_VECTOR_ELT(result, GENO_IDX, _trim_null(elt, parse->gnms)); } static struct parse_t *_parse_new(int vcf_n, SEXP smap, SEXP fmap, SEXP imap, SEXP gmap) { struct parse_t *parse = Calloc(1, struct parse_t); parse->vcf_n = vcf_n; parse->str = _strhash_new(); parse->vcf = _vcf_alloc(parse->vcf_n, smap, fmap, imap, gmap, parse->str); /* FIXED */ parse->chrom = rle_new(parse->vcf_n); parse->ref = dna_hash_new(parse->vcf_n); /* INFO */ parse->imap_n = Rf_length(imap); if (1 == parse->imap_n && R_NilValue == GET_NAMES(imap)) parse->inms = NULL; else { parse->inms = (const char **) R_alloc(sizeof(const char *), parse->imap_n); for (int j = 0; j < parse->imap_n; ++j) parse->inms[j] = CHAR(STRING_ELT(GET_NAMES(imap), j)); } /* FORMAT */ parse->gmap_n = Rf_length(gmap); parse->gnms = (const char **) R_alloc(sizeof(const char *), parse->gmap_n); for (int j = 0; j < parse->gmap_n; ++j) parse->gnms[j] = CHAR(STRING_ELT(GET_NAMES(gmap), j)); /* SAMPLES */ parse->smap_n = Rf_length(smap); parse->snms = (const char **) R_alloc(sizeof(const char *), parse->smap_n); for (int j = 0; j < parse->smap_n; ++j) parse->snms[j] = CHAR(STRING_ELT(GET_NAMES(smap), j)); parse->smapidx = INTEGER(smap); parse->warnings = vcfwarn_new(); return parse; } static void _parse_free(struct parse_t *parse) { rle_free(parse->chrom); dna_hash_free(parse->ref); vcfwarn_free(parse->warnings); _strhash_free(parse->str); Free(parse); } static void _parse_grow(struct parse_t *parse, int size) { static const double SCALE = 1.6; if (0 == size) size = parse->vcf_n < 2 ? 2 : parse->vcf_n * SCALE; _vcf_grow(parse->vcf, size); parse->vcf_n = size; } /* --- .Call ENTRY POINT --- */ SEXP scan_vcf_connection(SEXP txt, SEXP smap, SEXP fmap, SEXP imap, SEXP gmap, SEXP rownames) { struct parse_t *parse; Rboolean row_names = LOGICAL(rownames)[0]; parse = _parse_new(Rf_length(txt), smap, fmap, imap, gmap); /* parse each line */ for (int irec = 0; irec < parse->vcf_n; irec++) { char *line = Strdup(CHAR(STRING_ELT(txt, irec))); _parse(line, irec, parse, row_names); Free(line); } SEXP result = PROTECT(Rf_allocVector(VECSXP, 1)); SET_VECTOR_ELT(result, 0, _vcf_as_SEXP(parse, fmap, smap, row_names)); _vcf_types_tidy(parse, VECTOR_ELT(result, 0)); _parse_free(parse); UNPROTECT(1); return result; } /* --- .Call ENTRY POINT --- */ SEXP scan_vcf_character(SEXP file, SEXP yield, SEXP smap, SEXP fmap, SEXP imap, SEXP gmap, SEXP rownames) { struct parse_t *parse; Rboolean row_names = LOGICAL(rownames)[0]; if (!IS_INTEGER(yield) || Rf_length(yield) != 1) Rf_error("'yield' must be integer(1)"); if (!IS_CHARACTER(file) || Rf_length(file) != 1) Rf_error("'file' must be character(1) or as on ?scanVcf"); if (!IS_LOGICAL(rownames)) Rf_error("'row.names' must be TRUE or FALSE"); parse = _parse_new(INTEGER(yield)[0], smap, fmap, imap, gmap); const int BUFLEN = 4096; char *buf0 = Calloc(BUFLEN, char); char *buf = buf0, *end = buf0 + BUFLEN; gzFile gz = gzopen(CHAR(STRING_ELT(file, 0)), "rb"); int irec = 0; if (Z_NULL == gz) { Free(parse); Rf_error("failed to open file"); } while (Z_NULL != gzgets(gz, buf, end - buf)) { int n = strlen(buf); if (n == end - buf - 1 && (*(end - 2) != '\n' && *(end - 2) != '\r')) { const int len0 = end - buf0, len1 = len0 * 1.6; buf0 = Realloc(buf0, len1, char); buf = buf0 + len0 - 1; end = buf0 + len1; continue; } if ('#' == *buf0 || '\0' == *buf0 || '\n' == *buf0) { buf = buf0; continue; } if (irec == parse->vcf_n) _parse_grow(parse, 0); /* trim trailing newlines */ int last = strlen(buf) - 1; while (last >= 0) { if (buf[last] == '\n' || buf[last] == '\r') buf[last--] = '\0'; else break; } _parse(buf0, irec, parse, row_names); irec += 1; buf = buf0; } gzclose(gz); Free(buf0); _vcf_grow(parse->vcf, irec); SEXP result = PROTECT(Rf_allocVector(VECSXP, 1)); SET_VECTOR_ELT(result, 0, _vcf_as_SEXP(parse, fmap, smap, row_names)); _vcf_types_tidy(parse, VECTOR_ELT(result, 0)); _parse_free(parse); UNPROTECT(1); return result; } /* --- .Call CALLBACK FUNCTION --- */ SEXP tabix_as_vcf(htsFile *file, tbx_t *index, hts_itr_t *iter, const int yield, SEXP state, SEXP rownames) { int irec = 0; kstring_t ksbuf = {0, 0, NULL}; Rboolean row_names = LOGICAL(rownames)[0]; SEXP sample = VECTOR_ELT(state, 0); SEXP fmap = VECTOR_ELT(state, 1); const int nrec = yield == NA_INTEGER ? TBX_INIT_SIZE : yield; struct parse_t *parse = _parse_new(nrec, sample, fmap, VECTOR_ELT(state, 2), VECTOR_ELT(state, 3)); const tbx_conf_t conf = index->conf; while (tbx_itr_next(file, index, iter, &ksbuf) >= 0) { if (ksbuf.s[0] == conf.meta_char) continue; if (irec == parse->vcf_n) _parse_grow(parse, 0); _parse(ksbuf.s, irec, parse, row_names); irec++; if (yield != NA_INTEGER && irec == parse->vcf_n) break; } free(ksbuf.s); _vcf_grow(parse->vcf, irec); SEXP result = PROTECT(_vcf_as_SEXP(parse, fmap, sample, row_names)); _vcf_types_tidy(parse, result); _parse_free(parse); UNPROTECT(1); return result; } VariantAnnotation/src/vcffile.h0000644000175100017510000000101114614305321017577 0ustar00biocbuildbiocbuild#ifndef _VCFFILE_H_ #define _VCFFILE_H_ #include #include "htslib/tbx.h" SEXP scan_vcf_character(SEXP file, SEXP yield, SEXP sample, SEXP fmap, SEXP imap, SEXP gmap, SEXP rownames); SEXP scan_vcf_connection(SEXP txt, SEXP sample, SEXP fmap, SEXP imap, SEXP gmap, SEXP rownames); SEXP tabix_as_vcf(htsFile *file, tbx_t *index, hts_itr_t *iter, const int yield, SEXP state, SEXP rownames); #endif /* _VCFFILE_H_ */ VariantAnnotation/src/vcftype.c0000644000175100017510000002166514614305321017655 0ustar00biocbuildbiocbuild#include "vcftype.h" struct vcftype_t *_vcftype_new(SEXPTYPE type, SEXPTYPE listtype, char number, const char *charDotAs, int nrow, int ncol, int ndim, int arrayDim) { struct vcftype_t *vcftype = Calloc(1, struct vcftype_t); vcftype->type = type; vcftype->listtype = listtype; /* VECSXP: ragged array */ vcftype->number = number; /* 'A' or '.' for ragged array only */ vcftype->charDotAs = charDotAs; vcftype->ncol = ncol; vcftype->ndim = ndim; vcftype->arrayDim = arrayDim; return _vcftype_grow(vcftype, nrow); } void _vcftype_free(struct vcftype_t *vcftype) { if (NULL == vcftype) return; int sz = vcftype->nrow * vcftype->ncol * vcftype->ndim; switch (vcftype->type) { case NILSXP: break; case LGLSXP: Free(vcftype->u.logical); break; case INTSXP: Free(vcftype->u.integer); break; case REALSXP: Free(vcftype->u.numeric); break; case STRSXP: if (NULL != vcftype->u.character) Free(vcftype->u.character); break; case VECSXP: if (NULL != vcftype->u.list) { for (int i = 0; i < sz; ++i) if (NULL != vcftype->u.list[i]) _vcftype_free(vcftype->u.list[i]); Free(vcftype->u.list); } break; default: Rf_error("(internal) unhandled type '%s'", type2char(vcftype->type)); } Free(vcftype); } void *vcf_Realloc(void * p, size_t n) { /* Realloc(p, 0, *) fails inappropriately */ if (n == 0) { Free(p); p = NULL; } else { p = R_chk_realloc(p, n); } return p; } struct vcftype_t *_vcftype_grow(struct vcftype_t * vcftype, int nrow) { if (NULL == vcftype) return vcftype; int ncol = vcftype->ncol, ndim = vcftype->ndim, o_nrow = vcftype->nrow, osz = o_nrow * ncol * ndim, sz = nrow * ncol * ndim; if (nrow < 0) Rf_error("(internal) _vcftype_grow 'nrow' < 0"); if (sz < 0) Rf_error("(internal) _vcftype_grow 'sz' < 0; cannot allocate memory?"); switch (vcftype->type) { case NILSXP: break; case LGLSXP: vcftype->u.logical = (int *) vcf_Realloc(vcftype->u.logical, sz * sizeof(int)); for (int i = osz; i < sz; ++i) vcftype->u.logical[i] = FALSE; break; case INTSXP: vcftype->u.integer = (int *) vcf_Realloc(vcftype->u.integer, sz * sizeof(int)); for (int i = osz; i < sz; ++i) vcftype->u.integer[i] = R_NaInt; break; case REALSXP: vcftype->u.numeric = (double *) vcf_Realloc(vcftype->u.numeric, sz * sizeof(double)); for (int i = osz; i < sz; ++i) vcftype->u.numeric[i] = R_NaReal; break; case STRSXP: vcftype->u.character = (const char **) vcf_Realloc(vcftype->u.character, sz * sizeof(const char *)); for (int i = osz; i < sz; ++i) vcftype->u.character[i] = NULL; break; case VECSXP: vcftype->u.list = (struct vcftype_t **) vcf_Realloc(vcftype->u.list, sz * sizeof(struct vcftype_t *)); for (int i = osz; i < sz; ++i) vcftype->u.list[i] = NULL; break; default: Rf_error("(internal) unhandled type '%s'", type2char(vcftype->type)); } vcftype->nrow = nrow; return vcftype; } #define TPOSE(to, from, nrow, ncol, ndim) \ for (int k = 0; k < (ndim); ++k) \ for (int j = 0; j < (ncol); ++j) \ for (int i = 0; i < (nrow); ++i) \ *(to)++ = (from)[i * (ncol) * (ndim) + j * (ndim) + k] SEXP _vcftype_as_SEXP(struct vcftype_t *vcftype) { if (NULL == vcftype || NILSXP == vcftype->type) return R_NilValue; const int ncol = vcftype->ncol, ndim = vcftype->ndim, nrow = vcftype->nrow, sz = nrow * ncol * ndim; SEXP ans = PROTECT(Rf_allocVector(vcftype->type, sz)); int *ival, idx; double *dval; switch (vcftype->type) { case LGLSXP: ival = LOGICAL(ans); TPOSE(ival, (const int *) vcftype->u.logical, nrow, ncol, ndim); Free(vcftype->u.logical); break; case INTSXP: ival = INTEGER(ans); TPOSE(ival, (const int *) vcftype->u.integer, nrow, ncol, ndim); Free(vcftype->u.integer); break; case REALSXP: dval = REAL(ans); TPOSE(dval, (const double *) vcftype->u.numeric, nrow, ncol, ndim); Free(vcftype->u.numeric); break; case STRSXP: idx = 0; for (int k = 0; k < ndim; ++k) for (int j = 0; j < ncol; ++j) for (int i = 0; i < nrow; ++i) { const int idx0 = i * ncol * ndim + j * ndim + k; const char * const s = vcftype->u.character[idx0]; const SEXP elt = (NULL == s) ? R_NaString : mkChar(s); SET_STRING_ELT(ans, idx++, elt); } Free(vcftype->u.character); break; case VECSXP: idx = 0; for (int k = 0; k < ndim; ++k) for (int j = 0; j < ncol; ++j) for (int i = 0; i < nrow; ++i) { const int idx0 = i * ncol * ndim + j * ndim + k; struct vcftype_t *t = vcftype->u.list[idx0]; const SEXP elt = (NULL == t) ? Rf_allocVector(vcftype->listtype, 0) : _vcftype_as_SEXP(t); SET_VECTOR_ELT(ans, idx++, elt); } Free(vcftype->u.list); break; default: Rf_error("(internal) unhandled type '%s'", type2char(vcftype->type)); } if (vcftype->arrayDim > 1) { SEXP dim = PROTECT(Rf_allocVector(INTSXP, vcftype->arrayDim)); INTEGER(dim)[0] = nrow; if (vcftype->arrayDim == 2) { INTEGER(dim)[1] = ncol * ndim; } else { INTEGER(dim)[1] = ncol; INTEGER(dim)[2] = ndim; } Rf_setAttrib(ans, R_DimSymbol, dim); UNPROTECT(1); } _vcftype_free(vcftype); UNPROTECT(1); return ans; } void _vcftype_set(struct vcftype_t *vcftype, const int idx, const char *field) { if (NULL == vcftype) return; switch (vcftype->type) { case NILSXP: break; case LGLSXP: vcftype->u.logical[idx] = TRUE; break; case INTSXP: vcftype->u.integer[idx] = ('.' == *field) ? R_NaInt : atoi(field); break; case REALSXP: vcftype->u.numeric[idx] = ('.' == *field) ? R_NaReal : atof(field); break; case STRSXP: vcftype->u.character[idx] = (strcmp(".", field) == 0) ? vcftype->charDotAs : field; break; default: Rf_error("(internal) unhandled field type '%s'", type2char(vcftype->type)); } } void _vcftype_padarray(struct vcftype_t *vcftype, const int irow, const int icol, khash_t(strhash) *str, const int ragged_n) { if (NULL == vcftype) return; const int offset = irow * vcftype->ncol + icol; if (vcftype->u.list[offset] != NULL) return; _vcftype_setarray(vcftype, irow, icol, "", ragged_n, str); } void _vcftype_setarray(struct vcftype_t *vcftype, const int irow, const int icol, char *field, int ragged_n, khash_t(strhash) *str) { struct it_t it; char *ifld; if (NULL == vcftype) return; if (VECSXP == vcftype->type) { /* ragged array */ /* 'G': one value per genotype */ if (vcftype->number == 'G') ragged_n = ((ragged_n + 1) * (ragged_n + 2))/2; /* 'R': one value per alternate allele + ref*/ else if (vcftype->number == 'R') ragged_n = ragged_n + 1; /* 'A': one value per alternate allele */ else if (vcftype->number != 'A') ragged_n = _vcftype_ragged_n(field); /* allocate and fill */ const int offset = irow * vcftype->ncol + icol; vcftype->u.list[offset] = _vcftype_new(vcftype->listtype, NILSXP, '\0', vcftype->charDotAs, ragged_n, 1, 1, 0); ifld = it_init(&it, field, ','); for (int k = 0; k < ragged_n; ++k) { if ('\0' == *ifld) ifld = "."; _vcftype_set(vcftype->u.list[offset], k, _strhash_put(str, ifld)); ifld = it_next(&it); } } else { /* array */ const int offset = (irow * vcftype->ncol + icol) * vcftype->ndim; ifld = it_init(&it, field, ','); for (int k = 0; k < vcftype->ndim; ++k) { _vcftype_set(vcftype, offset + k, _strhash_put(str, ifld)); ifld = it_next(&it); } } } VariantAnnotation/src/vcftype.h0000644000175100017510000000311514614305321017650 0ustar00biocbuildbiocbuild#ifndef _VCFTYPE_H_ #define _VCFTYPE_H_ #include #include #include #include "utilities.h" #include "strhash.h" struct vcftype_t { SEXPTYPE type, listtype; /* listtype for ragged arrays */ char number; /* 'A' or '.' for ragged array only */ const char *charDotAs; /* '.' enocding when in character vectors */ int nrow, ncol, ndim, arrayDim; union { int *logical; int *integer; double *numeric; const char **character; struct vcftype_t **list; } u; }; struct vcftype_t *_vcftype_new(SEXPTYPE type, SEXPTYPE listtype, char number, const char *charDotAs, int nrow, int ncol, int ndim, int arrayDim); void _vcftype_free(struct vcftype_t *vcftype); struct vcftype_t *_vcftype_grow(struct vcftype_t *vcftype, int nrow); SEXP _vcftype_as_SEXP(struct vcftype_t *vcftype); void _vcftype_set(struct vcftype_t *vcftype, const int idx, const char *field); void _vcftype_setarray(struct vcftype_t *vcftype, const int irow, const int icol, char *field, int ragged_n, khash_t(strhash) *str); void _vcftype_padarray(struct vcftype_t *vcftype, const int irow, const int icol, khash_t(strhash) *str, const int ragged_n); static inline int _vcftype_ragged_n(const char *a) { int n = (*a == '\0') ? 0 : 1; while (*a != '\0') if (*a++ == ',') ++n; return n; } #endif VariantAnnotation/src/writevcf.c0000644000175100017510000002300214614305321020011 0ustar00biocbuildbiocbuild#include "writevcf.h" #include #include /* write all elements of 'list' genotype field */ static void write_list_elt(SEXP v_elt, const char mv_sep, kstring_t *bufp) { SEXPTYPE v_type; int v, v_len; v_type = TYPEOF(v_elt); v_len = length(v_elt); switch (v_type) { case NILSXP: break; case LGLSXP: Rf_warning("'logical' is not a valid FORMAT data type"); break; case INTSXP: for (v = 0; v < v_len; v++) { if (NA_INTEGER != INTEGER(v_elt)[v]) kputw(INTEGER(v_elt)[v], bufp); else kputc('.', bufp); if (v < v_len - 1) kputc(mv_sep, bufp); } break; case REALSXP: for (v = 0; v < v_len; v++) { if (!ISNAN(REAL(v_elt)[v])) ksprintf(bufp, "%g", REAL(v_elt)[v]); else kputc('.', bufp); if (v < v_len - 1) kputc(mv_sep, bufp); } break; case STRSXP: for (v = 0; v < v_len; v++) { if (NA_STRING != STRING_ELT(v_elt, v)) kputs(CHAR(STRING_ELT(v_elt, v)), bufp); else kputc('.', bufp); if (v < v_len - 1) kputc(mv_sep, bufp); } break; default: Rf_error("unsupported 'geno' type: %s", type2char(v_type)); break; } } /* write all genotype fields for a single sample */ static void write_geno_sample(int i, int j, int k_last, Rboolean *k_valid, SEXP geno_zdim, int n_rows, int n_samples, int n_fields, SEXP geno, const char f_sep, const char mv_sep, kstring_t *bufp) { SEXP field, c_elt, v_elt; SEXPTYPE type; double d_elt; int k, z, z_dim, z_max, index, i_elt; for (k = 0; k < n_fields; ++k) { if (!k_valid[k]) continue; field = VECTOR_ELT(geno, k); type = TYPEOF(field); z_dim = INTEGER(geno_zdim)[k]; z_max = (NA_INTEGER != z_dim) ? z_dim : 1; for (z = 0; z < z_max; ++z) { index = i + j*n_rows + z*n_rows*n_samples; switch (type) { case NILSXP: break; case LGLSXP: Rf_warning("'logical' is not a valid FORMAT data type"); break; case INTSXP: i_elt = INTEGER(field)[index]; if (NA_INTEGER != i_elt) kputw(i_elt, bufp); else kputc('.', bufp); break; case REALSXP: d_elt = REAL(field)[index]; if (!ISNAN(d_elt)) ksprintf(bufp, "%g", d_elt); else kputc('.', bufp); break; case STRSXP: c_elt = STRING_ELT(field, index); if (NA_STRING != c_elt) kputs(CHAR(c_elt), bufp); else kputc('.', bufp); break; case VECSXP: v_elt = VECTOR_ELT(field, index); write_list_elt(v_elt, mv_sep, bufp); break; default: Rf_error("unsupported 'geno' type: %s", type2char(type)); break; } /* multi-value separator */ if (z < z_max - 1 && k_valid[k]) kputc(mv_sep, bufp); } /* field separator */ if (k < n_fields - 1 && k < k_last) kputc(f_sep, bufp); } } /* return TRUE if genotype element is NA */ static Rboolean valid_geno_elt(SEXP field, int index) { Rboolean valid = FALSE; Rboolean v_valid = FALSE; const SEXPTYPE type = TYPEOF(field); SEXP elt; int v; switch (type) { case NILSXP: break; case LGLSXP: valid = NA_INTEGER != LOGICAL(field)[index]; break; case INTSXP: valid = NA_INTEGER != INTEGER(field)[index]; break; case REALSXP: valid = !ISNAN(REAL(field)[index]); break; case STRSXP: valid = NA_STRING != STRING_ELT(field, index); break; case VECSXP: elt = VECTOR_ELT(field, index); for (v = 0; v < length(elt); v++) { if (valid_geno_elt(elt, v)) { v_valid = TRUE; break; } } valid = v_valid; break; default: Rf_error("unsupported 'geno' type: %s", type2char(type)); break; } return valid; } /* --- .Call ENTRY POINT --- * 'conn' : connection * 'fixed' : character vector of FIXED fields * 'format' : character vector of FORMAT names * 'geno' : list of genotype data * 'separators' : character vector of length 2 consisting of a field * separator (first) and multi-value per field * separator (second) * 'vcf_dim' : integer vector of length 2 (n rows, n cols) * 'geno_zdim' : integer vector of z dimension of genotype data */ SEXP make_vcf_geno(SEXP conn, SEXP fixed, SEXP format, SEXP geno, SEXP separators, SEXP vcf_dim, SEXP geno_zdim) { const char f_sep = *CHAR(STRING_ELT(separators, 0)); const char mv_sep = *CHAR(STRING_ELT(separators, 1)); int n_rows = INTEGER(vcf_dim)[0]; int n_samples = INTEGER(vcf_dim)[1]; int n_fields = length(format); int i, j, k, k_last, z, z_dim, z_max; int index; Rboolean fmt_search, fmt_found, *k_valid; Rconnection con = R_GetConnection(conn); kstring_t buf; buf.l = buf.m = 0; buf.s = NULL; SEXP field; if (n_fields != length(geno)) Rf_error("length(format) must equal length(geno)"); if (length(geno_zdim) != length(geno)) Rf_error("length(geno_zdim) must equal length(geno)"); k_valid = (Rboolean *) R_alloc(sizeof(Rboolean), n_fields); for (i = 0; i < n_rows; ++i) { /* reset buffer */ buf.l = 0; if (NULL != buf.s) *buf.s = '\0'; kputs(CHAR(STRING_ELT(fixed, i)), &buf); if (n_fields > 0) kputc('\t', &buf); fmt_found = FALSE; k_last = 0; /* write format names */ for (k = 0; k < n_fields; ++k) { fmt_search = TRUE; field = VECTOR_ELT(geno, k); z_dim = INTEGER(geno_zdim)[k]; z_max = (NA_INTEGER != z_dim) ? z_dim : 1; for (j = 0; j < n_samples && fmt_search; ++j) { for (z = 0; z < z_max; ++z) { index = i + j*n_rows + z*n_rows*n_samples; if (valid_geno_elt(field, index)) { /* avoid trailing f_sep */ if (fmt_found) kputc(f_sep, &buf); kputs(CHAR(STRING_ELT(format, k)), &buf); if (k == n_fields - 1) kputc('\t', &buf); k_valid[k] = TRUE; k_last = k; fmt_search = FALSE; fmt_found = TRUE; break; } else if (k == n_fields - 1 && z == z_max - 1 && j == n_samples - 1) { kputc('\t', &buf); k_valid[k] = FALSE; } else k_valid[k] = FALSE; } } } /* write genotype fields if present */ if (n_samples > 0) { for (j = 0; j < n_samples; ++j) { write_geno_sample(i, j, k_last, k_valid, geno_zdim, n_rows, n_samples, n_fields, geno, f_sep, mv_sep, &buf); if (j < n_samples - 1) { if (0 != buf.l) /* sample separator */ kputc('\t', &buf); } else { kputc('\n', &buf); if (R_WriteConnection(con, buf.s, buf.l) != buf.l) Rf_error("error writing to connection"); } } } else { kputc('\n', &buf); if (R_WriteConnection(con, buf.s, buf.l) != buf.l) Rf_error("error writing to connection"); } } free(buf.s); return R_NilValue; } /* paste-collapse character matrix by row, ignoring NAs */ SEXP matrix_pasteCollapseRows(SEXP x, SEXP sep) { /* VO: looks like 'nc' is not used? * int nc = ncols(x), nr = nrows(x); */ int nr = nrows(x); char c_sep = CHAR(STRING_ELT(sep, 0))[0]; SEXP ans = allocVector(STRSXP, nr); PROTECT(ans); for (int r = 0; r < nr; r++) { int len = 0; for (int i = r; i < length(x); i += nr) { SEXP str = STRING_ELT(x, i); if (str != NA_STRING) len += length(str) + 1; } char *collapsed = R_alloc(sizeof(char), len); char *dest = collapsed; for (int i = r; i < length(x); i += nr) { SEXP str = STRING_ELT(x, i); if (str != NA_STRING) { strcpy(dest, CHAR(str)); dest[length(str)] = c_sep; dest += length(str) + 1; } } SET_STRING_ELT(ans, r, mkCharLen(collapsed, len - 1 * (len > 0))); } UNPROTECT(1); return ans; } VariantAnnotation/src/writevcf.h0000644000175100017510000000040614614305321020021 0ustar00biocbuildbiocbuild#ifndef _WRITEVCF_H #define _WRITEVCF_H #include "vcftype.h" #include SEXP matrix_pasteCollapseRows(SEXP x, SEXP sep); SEXP make_vcf_geno(SEXP conn, SEXP fixed, SEXP format, SEXP geno, SEXP separators, SEXP vcf_dim, SEXP geno_zdim); #endif VariantAnnotation/src/XVector_stubs.c0000644000175100017510000000003414614305321020772 0ustar00biocbuildbiocbuild#include "_XVector_stubs.c" VariantAnnotation/tests/0000755000175100017510000000000014614305321016372 5ustar00biocbuildbiocbuildVariantAnnotation/tests/VariantAnnotation_unit_tests.R0000644000175100017510000000015514614305321024436 0ustar00biocbuildbiocbuildrequire("VariantAnnotation") || stop("unable to load VariantAnnotation package") VariantAnnotation:::.test() VariantAnnotation/vignettes/0000755000175100017510000000000014614361054017245 5ustar00biocbuildbiocbuildVariantAnnotation/vignettes/bioinformatics.csl0000644000175100017510000001135314614305321022756 0ustar00biocbuildbiocbuild VariantAnnotation/vignettes/ens.bib0000644000175100017510000000176114614305321020510 0ustar00biocbuildbiocbuild@Article{McLaren2016, author={McLaren, William and Gil, Laurent and Hunt, Sarah E. and Riat, Harpreet Singh and Ritchie, Graham R. S. and Thormann, Anja and Flicek, Paul and Cunningham, Fiona}, title={The Ensembl Variant Effect Predictor}, journal={Genome Biology}, year={2016}, month={Jun}, day={06}, volume={17}, number={1}, pages={122}, abstract={The Ensembl Variant Effect Predictor is a powerful toolset for the analysis, annotation, and prioritization of genomic variants in coding and non-coding regions. It provides access to an extensive collection of genomic annotation, with a variety of interfaces to suit different requirements, and simple options for configuring and extending analysis. It is open source, free to use, and supports full reproducibility of results. The Ensembl Variant Effect Predictor can simplify and accelerate variant interpretation in a wide range of study designs.}, issn={1474-760X}, doi={10.1186/s13059-016-0974-4}, url={https://doi.org/10.1186/s13059-016-0974-4} } VariantAnnotation/vignettes/ensemblVEP.Rmd0000644000175100017510000000712514614305321021711 0ustar00biocbuildbiocbuild--- title: "ensemblVEP: using the REST API with Bioconductor" author: "Vincent J. Carey, stvjc at channing.harvard.edu" date: "`r format(Sys.time(), '%B %d, %Y')`" vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{ensemblVEP: using the REST API with Bioconductor} %\VignetteEncoding{UTF-8} output: BiocStyle::html_document: highlight: pygments number_sections: yes theme: united toc: yes bibliography: ens.bib --- ```{r setup,echo=FALSE,results="hide",message=FALSE} library(BiocStyle) library(VariantAnnotation) library(jsonlite) library(httr) ``` # Introduction Ensembl's Variant Effect Predictor is described in @McLaren2016. Prior to Bioconductor 3.19, the ensemblVEP package provided access to Ensembl's predictions through an interface between Perl and MySQL. In 3.19 VariantAnnotation supports the use of the VEP component of the REST API at [https://rest.ensembl.org](https://rest.ensembl.org/). # Acquire annotation on variants from a VCF file The function `vep_by_region` will accept a VCF object as defined in `r Biocpkg("VariantAnnotation")`. ```{r dodemo,message=FALSE} library(VariantAnnotation) fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") r22 = readVcf(fl) r22 ``` In this example we confine attention to single nucleotide variants. There is a limit of 200 locations in a request, and 55000 requests per hour. We'll base our query on 100 positions in the chr22 VCF. ```{r lksnv} dr = which(width(rowRanges(r22))!=1) r22s = r22[-dr] res = vep_by_region(r22[1:100], snv_only=FALSE, chk_max=FALSE) jans = toJSON(content(res)) ``` There are various ways to work with the result of this query to the API. We'll use the `r CRANpkg('rjsoncons')` JSON processing infrastructure to dig in and understand aspects of the API behavior. First, the top-level concepts produced for each variant can be retrieved using ```{r doj1, message=FALSE} library(rjsoncons) names(jsonlite::fromJSON(jmespath(jans, "[*]"))) ``` Annotation of the most severe consequence known will typically be of interest: ```{r doj2} table(jsonlite::fromJSON(jmespath(jans, "[*].most_severe_consequence"))) ``` There is variability in the structure of data returned for each query. ```{r doj3} head(fromJSON(jmespath(jans, "[*].regulatory_feature_consequences"))) ``` Furthermore, the content of the motif feature consequences field seems very peculiar. ```{r lktaaaa} table(unlist(fromJSON(jmespath(jans, "[*].motif_feature_consequences")))) ``` # Transforming the API response to GRanges We'll consider the following approach to converting the API response to a GenomicRanges GRanges instance. Eventually this may become part of the package. ```{r lkmakeg, message=FALSE} library(GenomicRanges) .make_GRanges = function( vep_response ) { stopifnot(inherits(vep_response, "response")) # httr nested = fromJSON(toJSON(content(vep_response))) ini = GRanges(seqnames = unlist(nested$seq_region_name), IRanges(start=unlist(nested$start), end=unlist(nested$end))) dr = match(c("seq_region_name", "start", "end"), names(nested)) mcols(ini) = DataFrame(nested[,-dr]) ini } tstg = .make_GRanges( res ) tstg[,1] # full print is unwieldy names(mcols(tstg)) ``` Now information about variants can be retrieved with range operations. Deep annotation requires nested structure of the metadata columns. ```{r lkmc} mcols(tstg)[1, "transcript_consequences"] ``` # Further work An important element of prior work in ensemblVEP supports feeding annotation back into the VCF used to generate the effect prediction query. This seems feasible but concrete use cases are of interest. # References VariantAnnotation/vignettes/filterVcf.bib0000644000175100017510000000137414614305321021647 0ustar00biocbuildbiocbuild@article{drmanac2010human, title={Human genome sequencing using unchained base reads on self-assembling DNA nanoarrays}, author={Drmanac, Radoje and Sparks, Andrew B and Callow, Matthew J and Halpern, Aaron L and Burns, Norman L and Kermani, Bahram G and Carnevali, Paolo and Nazarenko, Igor and Nilsen, Geoffrey B and Yeung, George and others}, journal={Science}, volume={327}, number={5961}, pages={78--81}, year={2010}, publisher={American Association for the Advancement of Science} } @article{li2011tabix, title={Tabix: fast retrieval of sequence features from generic TAB-delimited files}, author={Li, Heng}, journal={Bioinformatics}, volume={27}, number={5}, pages={718--719}, year={2011}, publisher={Oxford Univ Press} } VariantAnnotation/vignettes/filterVcf.Rmd0000644000175100017510000002756714614305321021651 0ustar00biocbuildbiocbuild--- title: "2. Using filterVcf() to Select Variants from VCF Files" author: "Paul Shannon" date: |+ Created: 20 February, 2013 Last Modified: `r format(Sys.Date(), "%B %d, %Y")` vignette: > %\VignetteIndexEntry{2. Using filterVcf to Select Variants from VCF Files} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} output: BiocStyle::html_document: number_sections: yes toc: yes toc_depth: 4 bibliography: filterVcf.bib csl: bioinformatics.csl link-citations: true --- # Introduction Whole genome Variant Call Format (VCF) files are very large, typically containing millions of called variants, one call per line of text. The actual number of variants relevant to a particular study (of a disease such as breast cancer, for instance) will often be far fewer. Thus the first task one faces when analyzing a whole genome VCF file is to identify and extract the relatively few variants which may be of interest, excluding all others. This vignette illustrates several techniques for doing this. We demonstrate three methods: filtering by genomic region, filtering on attributes of each specific variant call, and intersecting with known regions of interest (exons, splice sites, regulatory regions, etc.). We are primarily concerned with the latter two. However, in order to create the small VCF data file we use here for demonstration purposes, we employed genomic region filtering, reducing a very large whole genome two-sample breast cancer VCF file of fourteen million calls, to a file containing fewer than ten thousand calls in a one million base pair region of chromosome 7. For the sake of reproducibility, and for completeness of exposition, we will illustrate this first step also. # The Data: Paired Tumor/Normal Breast Cancer Variants [Complete Genomics Inc.](http://www.completegenomics.com/public-data/cancer-data) states: > To provide the scientific community with public access to data > generated from two paired tumor/normal cancer samples, Complete > Genomics sequenced and analyzed cell-line samples of patients with > breast cancer (invasive ductal carcinomas). The cell line-derived DNA > are housed at ATCC. Samples have been sequenced to an average > genome-wide coverage of 123X for three of the samples, and 92X for for > the fourth sample.^[Data generated withversion 2.0.0.32 of the Complete Genomics assembly software, on high molecular weight genomic DNA isolated from the HCC1187 breast carcinoma cell line ATCC CRL 2322. Sequencing methods documented in [@drmanac2010human]] A small (1M base) subset of this data is included in the current package, and used in the code presented below. # Filter by Genomic Region We identified this subset in a prior exploration of the full data set (work not shown), learning that variants of biological interest suitable for our purpose are found in a 1M base pair region of chromosome seven. The appendix to this document (see below) shows the few lines of code required to extract variant calls in that small region, from the very large file obtained from Complete Genomics (*somaticVcfBeta-HCC1187-H-200-37-ASM-T1-N1.vcf.gz*) and write them to a new, small VCF file. # Introducing the `filterVcf` Method The `filterVcf ` method reads (by chunks, about which more below) through a possibly very large VCF file to write a new, smaller VCF file which includes only those variant calling rows which meet the criteria specified in `prefilters` and `filters`. Reading "by chunks" is accomplished using a tabix [@li2011tabix] file. The a `yieldSize` argument specifies how many variant lines are read into memory at each iteration. ```{r eval=FALSE} tabix.file <- TabixFile(file.gz, yieldSize=10000) filterVcf(tabix.file, genome, destination.file, prefilters=prefilters, filters=filters) ``` in which 1. *file.gz*: a gzipped vcf file with an accompanying Tabix index file. 2. *yieldSize*: the number of text (call variant) lines to read at a time. 3. *genome*: a string indicating the genome assembly, e.g., "hg19". 4. *prefilters*: one or more simple string-based filtering functions, each of which returns a logical vector corresponding to the vcf rows it will be passed (as simple character strings). 5. *filters*: one or more filtering function, each of which returns a logical vector, corresponding to the list of parsed vcf structures it will be passed. ## Prefilters Prefilters are conceptually very simple. They are functions which will be called with a single argument, a vector of character strings, each of which is an *unparsed* variant call line, as read from the input VCF file. We use `grepl` to return a logical vector equal in length to the incoming vector of unparsed VCF lines. Each prefilter and filter is called repeatedly, with lines supplied on each invocation. `filterVcf` calls these functions repeatedly until the input file is exhausted. Notice how the logic of these prefilters is very simple, using `grepl` to do fast, simple, fixed pattern matching: ```{r prefilters} isGermlinePrefilter <- function(x) { grepl("Germline", x, fixed=TRUE) } notInDbsnpPrefilter <- function(x) { !(grepl("dbsnp", x, fixed=TRUE)) } ``` ## Filters Filters are more sophisticated than prefilters in that they assess *parsed* variant call lines for possible inclusion. Such parsing is intrinsically expensive but will be performed only on those lines which passed the prefilters. Therefore it pays to eliminate as many lines as possible using prefilters. Filters are useful when there exists detailed criteria for inclusion and exclusion. This can be seen below, especially in the `allelicDepth` function. Each filter must be written to return a logical vector as long as the number of rows in the input VCF argument; be sure your filter works with 0-row VCF instances. ```{r filters} ## We will use isSNV() to filter only SNVs allelicDepth <- function(x) { ## ratio of AD of the "alternate allele" for the tumor sample ## OR "reference allele" for normal samples to total reads for ## the sample should be greater than some threshold (say 0.1, ## that is: at least 10% of the sample should have the allele ## of interest) ad <- geno(x)$AD tumorPct <- ad[,1,2,drop=FALSE] / rowSums(ad[,1,,drop=FALSE]) normPct <- ad[,2,1, drop=FALSE] / rowSums(ad[,2,,drop=FALSE]) test <- (tumorPct > 0.1) | (normPct > 0.1) as.vector(!is.na(test) & test) } ``` ## FilterRules `FilterRules` allow you to combine a list of filters, or of prefilters so that they may be passed as parameters to *filterVcf*. We use them here to combine the *isGermlinePrefilter* with the *notInDbsnpPrefilter*, and the *isSNV* with the *AD* filter. ```{r createFilterRules, message=FALSE, warning=FALSE} library(VariantAnnotation) prefilters <- FilterRules(list(germline=isGermlinePrefilter, dbsnp=notInDbsnpPrefilter)) filters <- FilterRules(list(isSNV=isSNV, AD=allelicDepth)) ``` ## Create the Filtered file ```{r createFilteredFile, message=FALSE, warning=FALSE} file.gz <- system.file("extdata", "chr7-sub.vcf.gz", package="VariantAnnotation") file.gz.tbi <- system.file("extdata", "chr7-sub.vcf.gz.tbi", package="VariantAnnotation") destination.file <- tempfile() tabix.file <- TabixFile(file.gz, yieldSize=10000) filterVcf(tabix.file, "hg19", destination.file, prefilters=prefilters, filters=filters, verbose=TRUE) ``` # Look for SNPs in Regulatory Regions We have now created a file containing 29 novel, Germline, SNP variant calls, each with a reasonable allelic depth, extracted from the 3808 calls in *chr7-sub.vcf*. We examine those variants for overlap with regulatory regions, turning to the ENCODE project and using Bioconductor's `r Biocpkg("AnnotationHub")`. The ENCODE project is a large, long-term effort to build a "parts list" of all the functional elements in the human genome. They have recently focused on regulatory elements. We use the Bioconductor `r Biocpkg("AnnotationHub")` to download regulatory regions reported for a breast cancer cell line, with which to identify possibly functional, and possibly clinically relevant SNVs in the breast cancer tumor/normal genome we have been examining. The `r Biocpkg("AnnotationHub")` is a recent addition to Bioconductor that facilitates access to genome-scale resources like ENCODE. ## Load CTCF Transcription Factor Binding Regions Identified in MCF-7 Breast Cancer Cell Line The [MCF-7](http://en.wikipedia.org/wiki/MCF-7) Breast Cancer Cell line was established forty years ago, and has since played a dominant role in breast cancer cell line studies. The University of Washington reports transcription factor binding sites (TFBS) for the CTCF protein, which often acts as a negative regulator of transcription via chromatin structure modifications Though the MCF-7 cell line is an imperfect match to the HCC1187 cell line sequenced by Complete Genomics, we combine these two breast-cancer related data sets here, didactically, in this exercise, to highlight the importance of cell-type-specific regulatory regions, and of the availability of such data from ENCODE. We shall see a SNP in the intronic binding region of the cancer-related gene, EGFR. ```{r mcf7regulatoryRegions, message=FALSE, warning=FALSE} library(AnnotationHub) hub <- AnnotationHub() id <- names(query(hub, "wgEncodeUwTfbsMcf7CtcfStdPkRep1.narrowPeak")) mcf7.gr <- hub[[tail(id, 1)]] ``` ## Find SNPs in CTCF Binding Regions ```{r findOverlaps} vcf <- readVcf(destination.file, "hg19") seqlevels(vcf) <- paste("chr", seqlevels(vcf), sep="") ov.mcf7 <- findOverlaps(vcf, mcf7.gr) ``` There is just one SNV which overlaps with the MCF-7 regulatory regions. Find out where, if anywhere, it fits within a gene model. ```{r locateVariant, message=FALSE, warning=FALSE} library(TxDb.Hsapiens.UCSC.hg19.knownGene) txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene locateVariants(vcf[6,], txdb, AllVariants()) ``` # Conclusion This case study begins, somewhat artificially, with a very short region of chromosome seven, a section which we knew, from previous exploration, held an intronic regulatory SNV for EGFR, a receptor tryosine kinase implicated in some cancers. Though artificial, the case study illustrates all of the steps needed for broader, realistic surveys of whole genome variation data: 1. Filter by genomic coordinates. 2. Filter to extract only those variant calls which meet these criteria: Germline, novel (not in dbSnp), consisting of a single nucleotide, of sufficient allelic depth. 3. Intersect these variants with recognized DNA elements. In our case, we used short TFBS regulatory regions, but the same method can be used with exons, splice sites, DNaseI footprints, methylation sites, etc. # Appendix: Filter by Genomic Region The most basic form of VCF file filtering is by genomic region. We demonstrate that here, extracting variant calls in a 1M base region of chromosome 7, writing them to a new file, compressing and then indexing that file. These steps created the small VCF file which accompanies this vignette, and is used in the code shown above. Note that this code is *NOT* executed during the creation of this vignette: we do not supply the very large VCF file that it operates on. This code is here for tutorial purposes only, showing how you can filter by genomic region with a possibly large VCF file of your own. ```{r eval=FALSE} library(VariantAnnotation) file.gz <- "somaticVcfBeta-HCC1187-H-200-37-ASM-T1-N1.vcf.gz" stopifnot(file.exists(file.gz)) file.gz.tbi <- paste(file.gz, ".tbi", sep="") if(!(file.exists(file.gz.tbi))) indexTabix(file.gz, format="vcf") start.loc <- 55000000 end.loc <- 56000000 chr7.gr <- GRanges("7", IRanges(start.loc, end.loc)) params <- ScanVcfParam(which=chr7.gr) vcf <- readVcf(TabixFile(file.gz), "hg19", params) writeVcf(vcf, "chr7-sub.vcf") bgzip("chr7-sub.vcf", overwrite=TRUE) indexTabix("chr7-sub.vcf.gz", format="vcf") ``` This code creates the small gzipped vcf and index files used in the examples above. # Bibliography {-}VariantAnnotation/vignettes/VariantAnnotation.Rmd0000644000175100017510000004753314614305321023357 0ustar00biocbuildbiocbuild--- title: "1. Introduction to VariantAnnotation" author: "Valerie Obenchain" date: "`r format(Sys.time(), '%B %d, %Y')`" vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{1. Introduction to VariantAnnotation} %\VignetteEncoding{UTF-8} output: BiocStyle::html_document: number_sections: yes toc: yes toc_depth: 4 --- # Introduction This vignette outlines a work flow for annotating and filtering genetic variants using the `r Biocpkg("VariantAnnotation")` package. Sample data are in VariantCall Format (VCF) and are a subset of chromosome 22 from [1000 Genomes](http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/release/20110521/). VCF text files contain meta-information lines, a header line with column names, data lines with information about a position in the genome, and optional genotype information on samples for each position. Samtools organisation and repositories describes the [VCF format](http://samtools.github.io/hts-specs/VCFv4.4.pdf) in detail. Data are read in from a VCF file and variants identified according to region such as `coding`, `intron`, `intergenic`, `spliceSite` etc. Amino acid coding changes are computed for the non-synonymous variants and SIFT and PolyPhen databases provide predictions of how severly the coding changes affect protein function. # Variant Call Format (VCF) files ## Data import and exploration Data are parsed into a `VCF` object with `readVcf`. ```{r readVcF,message=FALSE} library(VariantAnnotation) fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation") vcf <- readVcf(fl, "hg19") vcf ``` ### Header information Header information can be extracted from the VCF with `header()`. We see there are 5 samples, 1 piece of meta information, 22 info fields and 3 geno fields. ```{r readVcf_showheader} header(vcf) ``` Data can be further extracted using the named accessors. ```{r headeraccessors} samples(header(vcf)) geno(header(vcf)) ``` ### Genomic positions `rowRanges` contains information from the CHROM, POS, and ID fields of the VCF file, represented as a `GRanges`. The `paramRangeID` column is meaningful when reading subsets of data and is discussed further below. ```{r readVcf_rowRanges} head(rowRanges(vcf), 3) ``` Individual fields can be pulled out with named accessors. Here we see `REF` is stored as a `DNAStringSet` and `qual` is a numeric vector. ```{r readVcf_fixed} ref(vcf)[1:5] qual(vcf)[1:5] ``` `ALT` is a `DNAStringSetList` (allows for multiple alternate alleles per variant) or a `DNAStringSet`. When structural variants are present it will be a `CharacterList`. ```{r readVcf_ALT} alt(vcf)[1:5] ``` ### Genotype data Genotype data described in the `FORMAT` fields are parsed into the geno slot. The data are unique to each sample and each sample may have multiple values variable. Because of this, the data are parsed into matrices or arrays where the rows represent the variants and the columns the samples. Multidimentional arrays indicate multiple values per sample. In this file all variables are matrices. ```{r geno_hdr} geno(vcf) sapply(geno(vcf), class) ``` Let's take a closer look at the genotype dosage (DS) variable. The header provides the variable definition and type. ```{r explore_geno} geno(header(vcf))["DS",] ``` These data are stored as a 10376 x 5 matrix. Each of the five samples (columns) has a single value per variant location (row). ```{r dim_geno} DS <-geno(vcf)$DS dim(DS) DS[1:3,] ``` DS is also known as 'posterior mean genotypes' and range in value from [0, 2]. To get a sense of variable distribution, we compute a five number summary of the minimum, lower-hinge (first quartile), median, upper-hinge (third quartile) and maximum. ```{r fivenum} fivenum(DS) ``` The majority of these values (86%) are zero. ```{r DS_zero} length(which(DS==0))/length(DS) ``` View the distribution of the non-zero values. ```{r DS_hist, fig=TRUE} hist(DS[DS != 0], breaks=seq(0, 2, by=0.05), main="DS non-zero values", xlab="DS") ``` ### Info data In contrast to the genotype data, the info data are unique to the variant and the same across samples. All info variables are represented in a single `DataFrame`. ```{r info} info(vcf)[1:4, 1:5] ``` We will use the info data to compare quality measures between novel (i.e., not in dbSNP) and known (i.e., in dbSNP) variants and the variant type present in the file. Variants with membership in dbSNP can be identified by using the appropriate SNPlocs package for the hg19 genome (GRCh37). ```{r examine_dbSNP, message=FALSE, warning=FALSE} library(SNPlocs.Hsapiens.dbSNP144.GRCh37) vcf_rsids <- names(rowRanges(vcf)) chr22snps <- snpsBySeqname(SNPlocs.Hsapiens.dbSNP144.GRCh37, "22") chr22_rsids <- mcols(chr22snps)$RefSNP_id in_dbSNP <- vcf_rsids %in% chr22_rsids table(in_dbSNP) ``` Info variables of interest are 'VT', 'LDAF' and 'RSQ'. The header offers more details on these variables. ```{r header_info} info(header(vcf))[c("VT", "LDAF", "RSQ"),] ``` Create a data frame of quality measures of interest ... ```{r examine_quality} metrics <- data.frame(QUAL=qual(vcf), in_dbSNP=in_dbSNP, VT=info(vcf)$VT, LDAF=info(vcf)$LDAF, RSQ=info(vcf)$RSQ) ``` and visualize the distribution of qualities using `r CRANpkg("ggplot2")`. For instance, genotype imputation quality is higher for the known variants in dbSNP. ```{r examine_ggplot2, message=FALSE, warning=FALSE, fig=TRUE} library(ggplot2) ggplot(metrics, aes(x=RSQ, fill=in_dbSNP)) + geom_density(alpha=0.5) + scale_x_continuous(name="MaCH / Thunder Imputation Quality") + scale_y_continuous(name="Density") + theme(legend.position="top") ``` ## Import data subsets When working with large VCF files it may be more efficient to read in subsets of the data. This can be accomplished by selecting genomic coordinates (ranges) or by specific fields from the VCF file. ### Select genomic coordinates To read in a portion of chromosome 22, create a `GRanges` with the regions of interest. ```{r subset_ranges} rng <- GRanges(seqnames="22", ranges=IRanges( start=c(50301422, 50989541), end=c(50312106, 51001328), names=c("gene_79087", "gene_644186"))) ``` When ranges are specified, the VCF file must have an accompanying Tabix index file. See `indexTabix` for help creating an index. ```{r subset_TabixFile} tab <- TabixFile(fl) vcf_rng <- readVcf(tab, "hg19", param=rng) ``` The `paramRangesID` column distinguishes which records came from which param range. ```{r} head(rowRanges(vcf_rng), 3) ``` ### Select VCF fields Data import can also be defined by the `fixed`, `info` and `geno` fields. Fields available for import are described in the header information. To view the header before reading in the data, use `ScanVcfHeader`. ```{r subset_scanVcfHeader} hdr <- scanVcfHeader(fl) ## e.g., INFO and GENO fields head(info(hdr), 3) head(geno(hdr), 3) ``` To subset on "LDAF" and "GT" we specify them as `character` vectors in the `info` and `geno` arguments to `ScanVcfParam`. This creates a `ScanVcfParam` object which is used as the `param` argument to `readVcf`. ```{r subset_ScanVcfParam} ## Return all 'fixed' fields, "LAF" from 'info' and "GT" from 'geno' svp <- ScanVcfParam(info="LDAF", geno="GT") vcf1 <- readVcf(fl, "hg19", svp) names(geno(vcf1)) ``` To subset on both genomic coordinates and fields the `ScanVcfParam` object must contain both. ```{r subset_ScanVcfParam_new} svp_all <- ScanVcfParam(info="LDAF", geno="GT", which=rng) svp_all ``` # Locating variants in and around genes Variant location with respect to genes can be identified with the `locateVariants` function. Regions are specified in the `region` argument and can be one of the following constructors: CodingVariants, IntronVariants, FiveUTRVariants, ThreeUTRVariants, IntergenicVariants, SpliceSiteVariants or PromoterVariants. Location definitions are shown in Table \@ref(tab:table). | Location | Details | |------------|------------------------------------------------------------| | coding | falls *within* a coding region | | fiveUTR | falls *within* a 5' untranslated region | | threeUTR | falls *within* a 3' untranslated region | | intron | falls *within* an intron region | | intergenic | does not fall *within* a transcript associated with a gene | | spliceSite | overlaps any portion of the first 2 or last 2 | | promoter | falls *within* a promoter region of a transcript | : (\#tab:table) Variant locations For overlap methods to work properly the chromosome names (seqlevels) must be compatible in the objects being compared. The VCF data chromosome names are represented by number, i.e., '22', but the TxDb chromosome names are preceded with 'chr'. Seqlevels in the VCF can be modified with the `seqlevels` function. ```{r locate_rename_seqlevels, message=FALSE, warning=FALSE} library(TxDb.Hsapiens.UCSC.hg19.knownGene) txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene seqlevels(vcf) <- "chr22" rd <- rowRanges(vcf) loc <- locateVariants(rd, txdb, CodingVariants()) head(loc, 3) ``` Locate variants in all regions with the `AllVariants()` constructor, ```{r AllVariants, eval=FALSE} allvar <- locateVariants(rd, txdb, AllVariants()) ``` To answer gene-centric questions data can be summarized by gene reguardless of transcript. ```{r locate_gene_centric} ## Did any coding variants match more than one gene? splt <- split(mcols(loc)$GENEID, mcols(loc)$QUERYID) table(sapply(splt, function(x) length(unique(x)) > 1)) ## Summarize the number of coding variants by gene ID. splt <- split(mcols(loc)$QUERYID, mcols(loc)$GENEID) head(sapply(splt, function(x) length(unique(x))), 3) ``` # Amino acid coding changes `predictCoding` computes amino acid coding changes for non-synonymous variants. Only ranges in query that overlap with a coding region in the `subject` are considered. Reference sequences are retrieved from either a `BSgenome` or fasta file specified in `seqSource`. Variant sequences are constructed by substituting, inserting or deleting values in the `varAllele` column into the reference sequence. Amino acid codes are computed for the variant codon sequence when the length is a multiple of 3. The query argument to `predictCoding` can be a `GRanges` or `VCF`. When a `GRanges` is supplied the `varAllele` argument must be specified. In the case of a `VCF`, the alternate alleles are taken from `alt()` and the `varAllele` argument is not specified. The result is a modified `query` containing only variants that fall within coding regions. Each row represents a variant-transcript match so more than one row per original variant is possible. ```{r predictCoding, warning=FALSE} library(BSgenome.Hsapiens.UCSC.hg19) coding <- predictCoding(vcf, txdb, seqSource=Hsapiens) coding[5:7] ``` Using variant rs114264124 as an example, we see varAllele `A` has been substituted into the `refCodon` `CGG` to produce `varCodon` `CAG.` The `refCodon` is the sequence of codons necessary to make the variant allele substitution and therefore often includes more nucleotides than indicated in the range (i.e. the range is 50302962, 50302962, width of 1). Notice it is the second position in the `refCodon` that has been substituted. This position in the codon, the position of substitution, corresponds to genomic position 50302962. This genomic position maps to position 698 in coding region-based coordinates and to triplet 233 in the protein. This is a non-synonymous coding variant where the amino acid has changed from `R` (Arg) to `Q` (Gln). When the resulting `varCodon` is not a multiple of 3 it cannot be translated. The consequence is considered a `frameshift` and `varAA` will be missing. ```{r predictCoding_frameshift} ## CONSEQUENCE is 'frameshift' where translation is not possible coding[mcols(coding)$CONSEQUENCE == "frameshift"] ``` # SIFT and PolyPhen Databases From `predictCoding` we identified the amino acid coding changes for the non-synonymous variants. For this subset we can retrieve predictions of how damaging these coding changes may be. SIFT (Sorting Intolerant From Tolerant) and PolyPhen (Polymorphism Phenotyping) are methods that predict the impact of amino acid substitution on a human protein. The SIFT method uses sequence homology and the physical properties of amino acids to make predictions about protein function. PolyPhen uses sequence-based features and structural information characterizing the substitution to make predictions about the structure and function of the protein. Collated predictions for specific dbSNP builds are available as downloads from the SIFT and PolyPhen web sites. These results have been packaged into `r Biocpkg("SIFT.Hsapiens.dbSNP132")` and `r Biocpkg("PolyPhen.Hsapiens.dbSNP131")` and are designed to be searched by rsid. Variants that are in dbSNP can be searched with these database packages. When working with novel variants, SIFT and PolyPhen must be called directly. See references for home pages. Identify the non-synonymous variants and obtain the rsids. ```{r nonsynonymous} nms <- names(coding) idx <- mcols(coding)$CONSEQUENCE == "nonsynonymous" nonsyn <- coding[idx] names(nonsyn) <- nms[idx] rsids <- unique(names(nonsyn)[grep("rs", names(nonsyn), fixed=TRUE)]) ``` Detailed descriptions of the database columns can be found with `?SIFTDbColumns` and `?PolyPhenDbColumns`. Variants in these databases often contain more than one row per variant. The variant may have been reported by multiple sources and therefore the source will differ as well as some of the other variables. It is important to keep in mind the pre-computed predictions in the SIFT and PolyPhen packages are based on specific gene models. SIFT is based on Ensembl and PolyPhen on UCSC Known Gene. The `TxDb` we used to identify the coding snps was based on UCSC Known Gene so we will use PolyPhen for predictions. PolyPhen provides predictions using two different training datasets and has considerable information about 3D protein structure. See `?PolyPhenDbColumns` or the PolyPhen web site listed in the references for more details. Query the PolyPhen database, ```{r polyphen, message=FALSE, warning=FALSE} library(PolyPhen.Hsapiens.dbSNP131) pp <- select(PolyPhen.Hsapiens.dbSNP131, keys=rsids, cols=c("TRAININGSET", "PREDICTION", "PPH2PROB")) head(pp[!is.na(pp$PREDICTION), ]) ``` # Other operations ## Create a SnpMatrix The 'GT' element in the `FORMAT` field of the VCF represents the genotype. These data can be converted into a `SnpMatrix` object which can then be used with the functions offered in `r Biocpkg("snpStats")` and other packages making use of the `SnpMatrix` class. The `genotypeToSnpMatrix` function converts the genotype calls in `geno` to a `SnpMatrix`. No dbSNP package is used in this computation. The return value is a named list where 'genotypes' is a `SnpMatrix` and 'map' is a `DataFrame` with SNP names and alleles at each loci. The `ignore` column in 'map' indicates which variants were set to NA (missing) because they met one or more of the following criteria, - variants with >1 ALT allele are set to NA - only single nucleotide variants are included; others are set to NA - only diploid calls are included; others are set to NA See ?`genotypeToSnpMatrix` for more details. ```{r snpMatrix, message=FALSE} res <- genotypeToSnpMatrix(vcf) res ``` In the map DataFrame, allele.1 represents the reference allele and allele.2 is the alternate allele. ```{r snpMatrix_ALT} allele2 <- res$map[["allele.2"]] ## number of alternate alleles per variant unique(elementNROWS(allele2)) ``` In addition to the called genotypes, genotype likelihoods or probabilities can also be converted to a `SnpMatrix`, using the `r Biocpkg("snpStats")` encoding of posterior probabilities as byte values. To use the values in the 'GL' or 'GP' `FORMAT` field instead of the called genotypes, use the `uncertain=TRUE` option in `genotypeToSnpMatrix`. ```{r message=FALSE} fl.gl <- system.file("extdata", "gl_chr1.vcf", package="VariantAnnotation") vcf.gl <- readVcf(fl.gl, "hg19") geno(vcf.gl) ## Convert the "GL" FORMAT field to a SnpMatrix res <- genotypeToSnpMatrix(vcf.gl, uncertain=TRUE) res t(as(res$genotype, "character"))[c(1,3,7), 1:5] ## Compare to a SnpMatrix created from the "GT" field res.gt <- genotypeToSnpMatrix(vcf.gl, uncertain=FALSE) t(as(res.gt$genotype, "character"))[c(1,3,7), 1:5] ## What are the original likelihoods for rs58108140? geno(vcf.gl)$GL["rs58108140", 1:5] ``` For variant rs58108140 in sample NA06989, the \"A/B\" genotype is much more likely than the others, so the `SnpMatrix` object displays the called genotype. ## Write out VCF files A VCF file can be written out from data stored in a `VCF` class. ```{r writeVcf, message=FALSE, warning=FALSE} fl <- system.file("extdata", "ex2.vcf", package="VariantAnnotation") out1.vcf <- tempfile() out2.vcf <- tempfile() in1 <- readVcf(fl, "hg19") writeVcf(in1, out1.vcf) in2 <- readVcf(out1.vcf, "hg19") writeVcf(in2, out2.vcf) in3 <- readVcf(out2.vcf, "hg19") identical(rowRanges(in1), rowRanges(in3)) identical(geno(in1), geno(in2)) ``` # Performance Targeted queries can greatly improve the speed of data input. When all data from the file are needed define a `yieldSize` in the `TabixFile` to iterate through the file in chunks. ```{r eval=FALSE} readVcf(TabixFile(fl, yieldSize=10000)) ``` `readVcf` can be used with a to select any combination of INFO and GENO fields, samples or genomic positions. ```{r eval=FALSE} readVcf(TabixFile(fl), param=ScanVcfParam(info='DP', geno='GT')) ``` While `readvcf` offers the flexibility to define combinations of INFO, GENO and samples in the `ScanVcfParam`, sometimes only a single field is needed. In this case the lightweight `read` functions (`readGT`, `readInfo` and `readGeno`) can be used. These functions return the single field as a matrix instead of a `VCF` object. ```{r eval=FALSE} readGT(fl) ``` The table below highlights the speed differences of targeted queries vs reading in all data. The test file is from 1000 Genomes and has 494328 variants, 1092 samples, 22 INFO, and 3 GENO fields and is located at http://ftp.1000genomes.ebi.ac.uk/vol1/ftp/release/20101123/. `yieldSize` is used to define chunks of 100, 1000, 10000 and 100000 variants. For each chunk size three function calls are compared: `readGT` reading only GT, `readVcf` reading both `GT` and `ALT` and finally `readVcf` reading in all the data. ```{r eval=FALSE} library(microbenchmark) fl <- "ALL.chr22.phase1_release_v3.20101123.snps_indels_svs.genotypes.vcf.gz" ys <- c(100, 1000, 10000, 100000) ## readGT() input only 'GT': fun <- function(fl, yieldSize) readGT(TabixFile(fl, yieldSize)) lapply(ys, function(i) microbenchmark(fun(fl, i), times=5) ## readVcf() input only 'GT' and 'ALT': fun <- function(fl, yieldSize, param) readVcf(TabixFile(fl, yieldSize), "hg19", param=param) param <- ScanVcfParam(info=NA, geno="GT", fixed="ALT") lapply(ys, function(i) microbenchmark(fun(fl, i, param), times=5) ## readVcf() input all variables: fun <- function(fl, yieldSize) readVcf(TabixFile(fl, yieldSize), "hg19") lapply(ys, function(i) microbenchmark(fun(fl, i), times=5)) ``` n records readGT readVcf (GT and ALT) readVcf (all) ----------- -------- ---------------------- --------------- 100 0.082 0.128 0.501 1000 0.609 0.508 5.878 10000 5.972 6.164 68.378 100000 78.593 81.156 693.654 : (\#tab:performance) Targeted queries (time in seconds) # References Wang K, Li M, Hakonarson H, (2010), ANNOVAR: functional annotation of genetic variants from high-throughput sequencing data. Nucleic Acids Research, Vol 38, No. 16, e164. McLaren W, Pritchard B, RiosD, et. al., (2010), Deriving the consequences of genomic variants with the Ensembl API and SNP Effect Predictor. Bioinformatics, Vol. 26, No. 16, 2069-2070. SIFT home page: http://sift.bii.a-star.edu.sg/ PolyPhen home page: http://genetics.bwh.harvard.edu/pph2/ # Session Information ```{r sessionInfo, echo=FALSE} sessionInfo() ```