shazam/0000755000176200001440000000000013616730026011541 5ustar liggesusersshazam/NAMESPACE0000644000176200001440000001140113616633004012753 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(calcBaseline) export(calcExpectedMutations) export(calcObservedMutations) export(calcTargetingDistance) export(calculateMutability) export(collapseClones) export(consensusSequence) export(createBaseline) export(createMutabilityMatrix) export(createMutationDefinition) export(createRegionDefinition) export(createSubstitutionMatrix) export(createTargetingMatrix) export(createTargetingModel) export(distToNearest) export(editBaseline) export(expectedMutations) export(extendMutabilityMatrix) export(extendSubstitutionMatrix) export(findThreshold) export(groupBaseline) export(makeAverage1merMut) export(makeAverage1merSub) export(makeDegenerate5merMut) export(makeDegenerate5merSub) export(minNumMutationsTune) export(minNumSeqMutationsTune) export(observedMutations) export(plotBaselineDensity) export(plotBaselineSummary) export(plotDensityThreshold) export(plotGmmThreshold) export(plotMutability) export(plotTune) export(shmulateSeq) export(shmulateTree) export(slideWindowDb) export(slideWindowSeq) export(slideWindowTune) export(slideWindowTunePlot) export(summarizeBaseline) export(testBaseline) export(writeTargetingDistance) exportClasses(Baseline) exportClasses(DensityThreshold) exportClasses(GmmThreshold) exportClasses(MutationDefinition) exportClasses(RegionDefinition) exportClasses(TargetingModel) exportMethods(plot) exportMethods(print) exportMethods(summary) import(ggplot2) import(graphics) import(methods) import(utils) importFrom(KernSmooth,bkde) importFrom(MASS,fitdistr) importFrom(alakazam,IUPAC_DNA) importFrom(alakazam,baseTheme) importFrom(alakazam,checkColumns) importFrom(alakazam,cpuCount) importFrom(alakazam,getAAMatrix) importFrom(alakazam,getAllele) importFrom(alakazam,getDNAMatrix) importFrom(alakazam,getFamily) importFrom(alakazam,getGene) importFrom(alakazam,getMRCA) importFrom(alakazam,getPathLengths) importFrom(alakazam,getSegment) importFrom(alakazam,gridPlot) importFrom(alakazam,groupGenes) importFrom(alakazam,isValidAASeq) importFrom(alakazam,nonsquareDist) importFrom(alakazam,pairwiseDist) importFrom(alakazam,pairwiseEqual) importFrom(alakazam,progressBar) importFrom(alakazam,seqDist) importFrom(alakazam,seqEqual) importFrom(alakazam,tableEdges) importFrom(alakazam,translateStrings) importFrom(ape,mst) importFrom(diptest,dip.test) importFrom(doParallel,registerDoParallel) importFrom(dplyr,"%>%") importFrom(dplyr,arrange) importFrom(dplyr,bind_cols) importFrom(dplyr,bind_rows) importFrom(dplyr,combine) importFrom(dplyr,desc) importFrom(dplyr,do) importFrom(dplyr,filter) importFrom(dplyr,group_by) importFrom(dplyr,group_indices) importFrom(dplyr,mutate) importFrom(dplyr,mutate_at) importFrom(dplyr,n) importFrom(dplyr,rename) importFrom(dplyr,select) importFrom(dplyr,summarize) importFrom(dplyr,summarize_at) importFrom(dplyr,transmute) importFrom(dplyr,ungroup) importFrom(foreach,"%dopar%") importFrom(foreach,foreach) importFrom(foreach,registerDoSEQ) importFrom(igraph,E) importFrom(igraph,V) importFrom(igraph,as_adjacency_matrix) importFrom(igraph,graph_from_data_frame) importFrom(igraph,set_vertex_attr) importFrom(igraph,vertex_attr) importFrom(iterators,icount) importFrom(kedd,h.ucv) importFrom(lazyeval,interp) importFrom(progress,progress_bar) importFrom(rlang,sym) importFrom(rlang,syms) importFrom(scales,log10_trans) importFrom(scales,log2_trans) importFrom(scales,math_format) importFrom(scales,percent) importFrom(scales,pretty_breaks) importFrom(scales,scientific) importFrom(scales,trans_breaks) importFrom(scales,trans_format) importFrom(seqinr,c2s) importFrom(seqinr,s2c) importFrom(seqinr,translate) importFrom(seqinr,words) importFrom(stats,approx) importFrom(stats,as.dist) importFrom(stats,convolve) importFrom(stats,cor) importFrom(stats,cov) importFrom(stats,cutree) importFrom(stats,dbeta) importFrom(stats,dgamma) importFrom(stats,dnorm) importFrom(stats,ecdf) importFrom(stats,mad) importFrom(stats,median) importFrom(stats,na.exclude) importFrom(stats,na.omit) importFrom(stats,optim) importFrom(stats,optimize) importFrom(stats,p.adjust) importFrom(stats,pbeta) importFrom(stats,pgamma) importFrom(stats,pnorm) importFrom(stats,qbeta) importFrom(stats,rbeta) importFrom(stats,runif) importFrom(stats,sd) importFrom(stats,setNames) importFrom(stats,uniroot) importFrom(stats,weighted.mean) importFrom(stringi,"stri_sub<-") importFrom(stringi,stri_count_boundaries) importFrom(stringi,stri_count_regex) importFrom(stringi,stri_detect_regex) importFrom(stringi,stri_dup) importFrom(stringi,stri_extract_all_regex) importFrom(stringi,stri_extract_first_regex) importFrom(stringi,stri_flatten) importFrom(stringi,stri_join) importFrom(stringi,stri_length) importFrom(stringi,stri_replace_all_regex) importFrom(stringi,stri_replace_first_regex) importFrom(stringi,stri_sub) importFrom(tidyr,gather) importFrom(tidyr,spread) shazam/README.md0000644000176200001440000000432713402556553013032 0ustar liggesusersSHazaM ------------------------------------------------------------------------------- SHazaM is part of the [Immcantation](http://immcantation.readthedocs.io) analysis framework for Adaptive Immune Receptor Repertoire sequencing (AIRR-seq) and provides tools for advanced analysis of somatic hypermutation (SHM) in immunoglobulin (Ig) sequences. Shazam focuses on the following analysis topics: 1. **Quantification of mutational load** SHazaM includes methods for determine the rate of observed and expected mutations under various criteria. Mutational profiling criteria include rates under SHM targeting models, mutations specific to CDR and FWR regions, and physicochemical property dependent substitution rates. 2. **Statistical models of SHM targeting patterns** Models of SHM may be divided into two independent components: (a) a mutability model that defines where mutations occur and (b) a nucleotide substitution model that defines the resulting mutation. Collectively these two components define an SHM targeting model. SHazaM provides empirically derived SHM 5-mer context mutation models for both humans and mice, as well tools to build SHM targeting models from data. 3. **Analysis of selection pressure using BASELINe** The Bayesian Estimation of Antigen-driven Selection in Ig Sequences (BASELINe) method is a novel method for quantifying antigen-driven selection in high-throughput Ig sequence data. BASELINe uses SHM targeting models can be used to estimate the null distribution of expected mutation frequencies, and provide measures of selection pressure informed by known AID targeting biases. 4. **Model-dependent distance calculations** SHazaM provides methods to compute evolutionary distances between sequences or set of sequences based on SHM targeting models. This information is particularly useful in understanding and defining clonal relationships. Contact ------------------------------------------------------------------------------- For help and questions please contact the [Immcantation Group](mailto:immcantation@googlegroups.com) or use the [issue tracker](https://bitbucket.org/kleinstein/shazam/issues?status=new&status=open). shazam/data/0000755000176200001440000000000013402556553012456 5ustar liggesusersshazam/data/MK_RS5NF.rda0000644000176200001440000054756713402556553014422 0ustar liggesusersBZh91AY&SYzuP~@ aVc"A@ @ A  ` `Al  `Al  60@AA@  A A@   A  A @@A zOԍGoT24 zJꪪb`@CM hhhhGRڀd#~~ڧꪪ~UU*0!L)ꪨOUU?`z lnmf~3 cofc^/߻ׯ^oac>ߙ>}/_?<?{l`` XX,`` XX,,`` I$I$,_y<؊_U636ٱmL1 l}ׯ^z{ 9s~ $Hך $H$I <$I ysUkZ$}UZ֪H{UVo|UkZ{UVo|UkZ{UVo|UkZ{UVo|UkZ?UU]$K$I <sUkZo|UkZ{UVo|UkZ{UVo|UkZ{UVo|UkZ{UVo|UkZ{ $H$I <UUUUj7UZ֪}{Uj7UZ֪}{Uj7UZ֪}{Uj7UZ֪}{Uj7UZ֪}{I$ $HUUUUkZ{UVo|UkZ{UVo|UkZ{UVo|UkZ{UVo|UkZ{UVo|I$I$UUUUZ֪}{Uj7UZ֪}{Uj7UZ֪}{Uj7UZ֪}{Uj7UZ֪}{Uj7$I I$UUUUVo|UkZ{UVo|UkZ{UVo|UkZ{UVo|UkZ{UVo|UkZ{ $H$I <UUUUj7UZ֪}{Uj7UZ֪}{Uj7UZ֪}{Uj7UZ֪}{Uj7UZ֪}{I$ $HUUUUkZ{UVo|UkZ{UVo|UkZ{UVo|UkZ{UVo|UkZ{UVo|I$I$UUUUZ֪}{Uj7UZ֪}{Uj7UZ֪}{Uj7UZ֪}{Uj7UZ֪}{Uj7$I I$UUUUVo|UkZ{UVo|UkZ{UVo|UkZ{UVo|UkZ{UVo|UkZ{I$Owwwwi$H9s $HI$@$I |g}}I$I$wwwvI$3;?33rvE\ݮQn(k[-rfd{ILrvE\ݮQn(k[-rvC32}߇$&vE\ݮQn(k[-rvE\>n;\ݮQn(k[-rvE\ݮP̟}zI7wvIQn(k[-rvE\ݮQn(ffO$$(k[-rvE\ݮQn(k33'}{ޒMݒgk[-rvE\ݮQn(k[=I&3-rvE\ݮQn(k[- ~wwdrvE\ݮQn(k[-rfd{ILrvE\ݮQn(k[-rv]yII2I$Nz?]ܒI$$I W3>=I'߿I'k[-rvE\ݮQn(k[?wvǽm﾿??C???ݾ߇$$rvE\ݮQn(k[-rvC32}߇$$rvE\ݮQn(k[-rvC32}߇$$rvE\ݮQn(k[-rvC32}߇$$rvE\ݮQn(k[-rvC32}߇$$rvE\ݮQn(k[-rvC32}߇$$rvE\ݮQn(k[-rvC32}߇$$rvE\ݮQn(k[-rvC32}߇$$rvE\ݮQn(k[-rvC32I?I$`$I$I fwϾ{ILrvE\ݮQn(k[-rvC32}߇$&vE\ݮQn(k[-rvE\>n;\ݮQn(k[-rvE\ݮP̟}zI7wvIQn(k[-rvE\ݮQn(ffO$$(k[-rvE\ݮQn(k{>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC32}{ޒMݒgk[-rvE\ݮQn(k[]n;\ݮQn(k[-rvE?~?{fI$L$I 3݀I$ jZ9fgy-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC32}{ޒMݒgk[-rvE\ݮQn(k[]n;\ݮQn(k[-rvE\ݮP̟}wwdrvE\ݮQn(k[-rfd~$$(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffI'߿~ $H wwww`$I3{ڬֹzI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC32}{ޒMݒgk[-rvE\ݮQn(k[]n;\ݮQn(k[-rvE\ݮP̟}wwdrvE\ݮQn(k[-rfd~$$(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC3̒I$I$@g뻻 $HnəwwdrvE\ݮQn(k[-rfd~$$(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC32}{ޒMݒgk[-`3'~$&y]n߮zI7wvI^fd~߿~I$~I$Vk\9 >߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̒O߿~I$@g뻻 $H{f{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&}{$I0I$wwwvI$wvLϾ~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`$~ߦ $H wwww`$I3{ڬֹs30^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$ʯ$I.$I s8$I $I $H?fffI$L$I ?wwwv&ffgK{ޒMݒg߿~}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfI'߿~黻I$@g뻻3;k33fOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL  ̒O߿~$$I $I I$I$$I 3{ڬn߮zI7wvI_3'~邏߿fOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 {$II$~n왙}.zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32I?~߿MI$wwwvfw{U9ff$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`O$I3I$]݀39sWwwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL]{$I0I$wwww`{}.zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32I?~߿M$I e39Vk\9 ߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~L$I e39V]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvIks3$I&I$27wvO{w{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&3$~ߦ $I9sI$ $H}I$O $Hۻg9sֹrI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/3332I$`$I.={߽I&0 ̟}wwdfOw{ILwwwwwwk̾fewu[̶+wvn{32{|ff[oww_}mwom`VI$I$]݀39sWm`V33- ݾfewu[̶+wvn{32{|ff[oww_}mwom`V33-5^3I$I$I$ I$I$H0VI#V33- ݾfewu{~O]|ff[oww_}mwom`V33- ݾfewu[̶5kZֵkZֳ]{$I0I$wwww` sYsf`3n{32{|ff[oww_}mwom`V33- ݾfewu[̶+wvn{32{mリI$@˻g9sֳ3- ݾfewu[̶+wvn{32{|ff[oww_}mwom`V33- ݾfewu]{$I0I$wwww`I*$n{32{|ff[oww_}mwom`V33- ݾfewu[̶+wvn{32{5kZֵkZwfdI$I$]݀$I$I$P$f}mwom`V33- ݾfewu[̶+wvn{32{|ff[oww_}mwmI$@˻g9sֹmwom`V33- ݾfewu[̶+wvn{32{|ff[oww_}mwom`V{$I0I$wwww`@ۮ`G񙙙[̶+wvn{32{|ff[oww_}mwom`V33- ݾfewu[̶ZֵkZgfI$LwwwwvI$s9?~I$@`I$}}I$I$s5swom`V33- ݾfewu[̶+wvn{32{|ff[oww_}mwom`V$L$I e3gzn{32{|ff[oww_}mwom`V33- ݾfewu[̶+wvn{32{5kZwfdI$I$]݀$I$P$fffff}mwom`V33- ݾfewu[̶+wvn{32{|ff[oww_}mwmI$@˻g9sֹs30wom`V33- ݾfewu[̶+wvn{32{|ff[oww_}mwom`?}$I0$II$@˻I$$I!sަfewu[̶+wvn{32{??Ϗ{}<om`V33- ݾfewu[̶+wvks3$I&I$2I"\Y$3333330 ݾfewu[̶+wvn{32{|ff[oww_}mwom`V33- ݾfewukZֵkZֵ{$II$ fs>k33+wvn{32{|ff[oww_}mwom`V33- ݾfewu[̶+wvno}I0I$wwww` sXff[oww_}mwom`V33- ݾfewu[̶+wvn{32{|ff[oww_}m5I$ $HwwwwvI*$[̶+wvn{32{|ff[oww_}mwom`V33- ݾfewu[̶5kZֵkZֳ]{$I0I$wwww` sYsf`3n{32{|ff[oww_}mwom`V33- ݾfewu[̶+wvn{32{3}`].I$9s$II'I$|I$@݀2fgzn{32{|ff[oww_}mwom`V33- ݾfewu[̶+wvn{32{ZֵkZwfdI$I$]݀I$I$P$fff[̶+wvn{32{|ff[oww_}mwom`V33- ݾfewu[̶+wv~ᄑI$@˻g9sֹs2+wvn{32{|ff[oww_}mwom`V33- ݾfewu[̶+wvnۙ$I0I$wwww` ff~m`V33- ݾfewu[̶+wvn{32{|ff[oww_}mwom`V33- kZֵ{fI$L$I eI$I$P$ffffn{32{|ff[oww_}mwom`V33- ݾfewu[̶+wvn{32{?[o}}׻I$I$ $HfUU}Vk\9+wvn{32{|ff[oww_}m>=[o}~fefewu[̶+wvn{32{m$`$I.933- ݾfewu[̶?I$_wvI$I$33-$I$I%|ff[oww_I$I$K̶I$I$wwomI$I$I.{32{I$I$]ݾfewu$I$I$m}}PI$]݀39sUff[oww_I$I$K̶I$I$wwomI$I$I.{32{I$I$]ݾfewu$I$I$}mI$I$IwwvI$I$33-$I$I%|ff[oww_I$I$K̶I$I$w{$II$ s33LmI$I$IwwvI$I$33-$I$I%|ff[oww_I$I$K̶I$I$wwomI$I$I.{32{I$I$]ݾfewu$I$I$}mI$I$IwwvI?~߿~;I$ $Hwwwwv9}U9ff>I$I%|ff[oww_I$I$K̶I$I$wwomI$I$I.{32{I$I$]ݾfewu$I$I$}mI$I$IwwvI$I$33-$I$I%|ff[oww_I$I$]ݿWI$@sI$?}}I$O $Hۻg933-$I$I%|ff[oww_I$I$K̶I$I$wwomI$I$I.{32{I$I$]ݾfewu$I$I$}mI$I$IwwvI$I$33-$I$I%|ff[oww_I$I?~{fI$L$I enff~mI$I$I.{32{I$I$]ݾfewu$I$I$}mI$I$IwwvI$I$33-$I$I%|ff[oww_I$I$K̶I$I$wwomI$I$I.{32{I$I$]ݶ߾wwwp$I.9ϪZ9û$I$I%|ff[oww_I$I$K̶I$I$wwomI$I$I.{32{I$I$}mI$I$32{32{$I$I%̷̶I$I$Is3-33-I$I$\}mI$I$32o}I0I$wwww` sXff[owu$I$I$I$I$I.fefew_I$I$KomI$I$f[|ff[owu$I$I$I$I$I.fefew_I$I$KomI$I$f[|ff[owu$I$I$I$I$I.fe$II$ fsS32{$I$I%̷̶I$I$Is3-33-I$I$\}mI$I$32{32{$I$I%̷̶I$I$Is3-33-I$I$\}mI$I$32{32{$I$I%̷̶I$I$Is3$I0I$wwww`nff~mI$I$f[|ff[owu$I$I$I$I$I.fefew_I$I$KomI$I$f[|ff[owu$I$I$I$I$I.fefew_I$I$KomI$I$f[|ff[owu$I$I?_dI$wz2I$wwwuަfew_I$I$KomI$I$f[|ff[owu$I$I$I$I$I.fefew_I$I$KomI$I$.?Ϗ{}$I$I$3?_{32{$I$I%̷̶I$I$Is3-33-I$~߿g9ffdI$I$]݀wwwwww[ff[owu$I$I$I$I$I.fefew_I$I$KomI$I$f[|ff[owu$I$I$I$I$I.fefew_I$I$KomI$I$f[|ff[owu$I$I$I$߿~߳332I$`$I.9ϪZ9Ͽ~I$I$32{32{$I$I%̷̶I$I$Is3-33-I$I$\}mI$I$32{32{$I$I%̷̶I$I$Is3-30UG]]*'@w IPW{II$ fs>k33OUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.us &g{L$I.9pI$X$Iz39Vk\*'@w IP`zw{$]*'@w IP`zw{$]*'@w IPW{{wwwwv9}U9fc$]*'@w IP`zw{$]*'@w IP`zw{$]*'@^{޲I${wwwwv9}U9ff@w IP`zw{$]*'@w IP`zw{$]*'@w9=3332I$`{wwwwv $I$I$P$]*'@w IP`zw{$]*'@w IP`zw{$].`_s$I0z $I$H0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJU/|9̒I${]݀I$@ۮ`zw{$]*'@w IP`zw{$]*'@w IP`zw{$s$I{eI$P$]*'@w IP`zw{$]*'@w IP`zw{$]*'d̒I${]݀I$ ~sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=W]_ݙ 쫯߀?~`zw{$U$I{e3~sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](I0z fs>sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$]|}ǽ{`˻9sI$@@I$|{uUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt {${˻g9s0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ*{{˻g9sָzw{$]*'@w IP`zw{$]*'@w IP`zw{$U{z{]݀39sUfs$]*'@w IP`zw{$]*'@w IP`zw{$]*'@^{޲I${e39Vk\9'@w IP`zw{$]*'@w IP`zw{$]*'@w IPW{I$@{]݀39sUfs~{.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.s 39s33$I&;@wwww` $I$E?n IP`zw{$]*'@w IP`zw{$]*'@w IP`9I${˻$I$qVI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$dI${2I$8n$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=W_/}w3wU{Uϳ7wdt {Yw{ހ.95ŒOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛfs$K;@$I メI$;@fs7֪33 =WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfnfsffI$Lw{ހ.I$I"㙻z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfI$Lw{ހ.8n$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ*{`{2sZdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9ff`_s$I0z $I$I"㙻z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WKs$I0z H8n$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ*{0z fs7ַuUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀVI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=fsffI$Lw{ހ.I$sfIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$]߿=I%I$.$I s8n$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$=w{ׯ{?_/?7[fl'7?|_ٛ3}M7fߛ7l;3mflfe2LS)e3LS)e2LS)e2LS;e2LS)e2LS)e3LS)e2LS)e2LS;e2LS)e2LS)e3LS)e2LY|e2LS)e3LS)e2LS)e2LS;e2LS)e2LS)e3LS)e2LS)e2LS;e2LS)e2LS)e3LS)e2L|{>lfFն֡]cm-l[25IZFؖFY Mk 4hжZʴ4km@FcPf;jUiQMieQkMY[3EЖ)<݀epH  @@@{V;ݫ{TP -s.P} t$ۭ(p@nTdUm mٯ@[t :VSweQQVƩFّj[-j#[U-R8:@ t鹝a̰b,PGU]sǥ*m^YV;UN26LUmjj7rm2Ҩa{-ڦ2͔ZXfŵ*صlMvl.*[AjFf͕Ʊsus(h[[ٶҴm2 4+!wj*ͶwAfl2S`́Z7V w,ҊlʣFRElFe26i6["͌Z 3ٳU,+%a[i٦bEFm4͛cUUY2d6f![iU\ λR[R f4[`ڱ6mmY0f՛[2ٖ[M,aWw]-0lf֚JV46JBdYj%*W;8LřU*3[ke8YVm+K[Z4V1زE56ɫU)ݻiV챕JY%Tk4͓p;`[Smj,UUR6jli+Qm ) 3IDֱ6ƨML&CM44044L4iM 414&&`B)0&L4d FLɠ hh4 4E4 &@M4dC&&0 iSCL24ii#@!#UOoI5 zM4ѧlz4& 2=FQ 4̣OP=#i<ꁐOPa114hzhz@!oUOQ=S'LzCdh2FЀ 4 2hI 4h 4hhI&&h L2h L44 'jd 42b`jj}@\k=y'Y.Q=yKڒ7w޽.`3KuRr{y߲`.K ! $1X-4 , $ Y! $ʴ$No/%˗[iCw\H)z@z;Yn8q${_mὯ^L5oyR E c./S ^JRK%ɝfdI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$ΒLI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I&I&I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$'3$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$qOQI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$IydI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$III$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I8O"dI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I;t;7O{bCxݹjy'r􀰼(. wKnٯW-@|FЁ8=iB)-$i$3QP ș+Ő15vK8ULv"@Qwj0L!GR c8A3 e9hpqeJ*  b@GW E'wg^k9u^MwW7=~页QFt uqة9]M.XcW2U]YhF4SGFI]Y\5L̙8AӚ;5Otŵx ekoikx)l8zY.w?tn]ِ~ڎ͍o-*P1pK70[䈾)MphIi76"X:Y)vc֯_`7]ͨdbԠ@@YH?Uz̽r2rw{Eԣ'/ ]0Y ӿ&ѧfRu*`@-UF?vߖC iu|Z}==?J'5p+r8a\Nh0\;\eq" -vąN5կ"0 Oq;Sb4OGne 6s{ ]24ςH/юo7kֿlel>lф$fbvmeεv|ҕ鉊yK߾̎uJJ%BcO*0d krV aG=QzXfJ$i];<ͱwuHibb  Fxau BsԮ+_b BSzFg!BOl/ѝ|nfZWӠu}o:? މnzz­9!A. @/v^?;w?ذT9_.OHNP\M镲@:'VbTA+mcb:dC!&sl.MxEsHv3=#w] 4H U#>C-GSq:hw[ ¿f"Cj1 ؘkr,ӺEF|*[lc0ʋ `ے\נּL(b|K`N'sBAehFdd{{gt4w^9a!n7΅>)m$4w$gDq=jJ?wytc@}eqU|!zdK@RvvC?BRY?f&D@6|Uf/l+nixr˫_ѲeNc=~`6s@ɰ2taiiqPl= ]\]ͅ^!{&'VfySZۉmJ}h=RyT@%;D'wYhޑ7#@w(3@8?^7wk\t ;T׮.)/3 z[pRE| ^gROX$}͊ѢB6dJΟ7y0-m +xa GMvs:o)0;R1 2'c:G!]/4@AAJuÂS#'vŭMtI/Df}E]Օ0م5*yMS\f/b)zU d<hߑ !)sQ^{"ÑґFa$+Wk0>9'j S*5ys1K6- MNq7gO Ϳ>|y{EɗV mL7_ǴX#2C06]awY駐kTd1~Q2򺿆 u{5LBU9QWl!_U(ujƟT8rÌ8,A RUz_ }248$g*|jg1QC{O#KIw=/kMWL]FfNOТx&Kiڎ xbw#C%?@ޙyPG Û\QG U5EIkJ*}@t!"-0Gsq̑]PabM\ )cjSΧ{v^ ӳe)ǩgm8*܄jj?Z[Sr{etD4Lg!XȯxYlu_کOim([OSX1(ZGr%zwJSTϰ=7~COY zmu!#YY+^!F 4T !{5^2-$p@_ >9F#"O3̎pZ;Vc盶_4vqWsܧe9BƿSg,}}%`ʩphA2& #h|J vU!4c)"m0UlDOA'ɮr],fqd)[M lcɛx0ˢ*IϨ'y癘4Nʋ+C+k6n!8/Қ&hUҖp00p ?"ΩD2%׆i""xDD5Ⱦ$`Q3x \j+.)P-5A%:xqnx`2S =A欙N/jdw=xPIckIN):@s V; X@]ڔoZS v-PZ0t3InЈՉș&z*@kT"/}ybd\ZQwY|2S gCG{/v8 #fV8+$a ;|?';FAcKHu`3ܱ6YLpF϶Tk2!>ţ8#e4Oz@%Oc̠Gx8P_g1 Q͸<ӻV(nTL&]ƺ,@L $-нTl qÖ+$ 8=0@2%_GwVHH3J x `#?C.p %Ʊ+W,ծYV)yu9lIZ% A`p.sإ3PJM'!KnV*3;%g~*I@֘Xb/xƫ֞(1ưjIOamJ*FtlNH]!˻7FNC-rp QXgv ژ5k7E|"Hun R?DUD@HpfibevYd$U?/Pd?\Y2聞eTأ.DU+Ti =6|j`yAxݗ~E~/ .?b:eYHH8[Va!BS 0`@-: .: zL8HA%vąplm=}LΐҋOLTr βN| d<oа˳Pd%XJ L`d;-ވm1π<|w5r VOj?z"1gS@1FWd[nD%'o7sWmEA]ҨC2#> H3=a*rzn{E0c xu# =!jtF;@2![ƉTv@zQ\^9ô|{ЊD#8>M's1O1QG| 9M]5F$,T:זv,{=cM} [fNY F"8kF-Rm ^/9Y 0H67wT >f})rؼ4D[Z/ !TAޔI;1XHU?3ڇ CT hLxq(J2}sw:_k22J\ۖ t) wFW[PαAVϿGSuý4t/ Z0cW½|Û'Ɛ⍌}6Z_TW A u=6,=GOɒ&ש#9T˩YMFa1 xSA.'1CWHpӺz|Ή(2=[ۂOo{7Q^{b{’4Aۦ(J*5 h˺2X!݊-|c`q#H D^Zf>`s](\*YUn[^epN{lX 5ʌh^!.$3@`-<5uQT}o٩п =b_PZ\ߒ8=UhLqSX42 nX\+g#X$ΨU'M a93(cߎ ʹהOi~ȟEX>|Hs| πHrDU4tNZ):sqB<+(I;]ޛ=z ĀheMwW\4#S HeH,òbCL0 |pv>4 T\sTgM7iٕpp_pL>b'AK^s$ ^䑉g-ڨM!cxQQ!ޱGM@$%:em-1F\O *%&7]~0XUɝ~#BDӿ aUFPHQdD{h&[F\ 6Yzn[jT[ (U; ^ҡ0BhN͗(c&X5B4ys7J:L,̱Fk]|fFoa[2;NU&9)=iy#s߰uHab/=D ߭H_Q  " ~ظ? Beތ(n{<_ rB YLÄIonT ePƒxMY-h %WL: g3]FQ],l;`* fKc5bǩq+VJ'<{7#@Ñg-Q)ݢ|mw TDbB5Oz@J3[ǒ@{CЂH$(`,17AQ;Zpȵ >q=Q:}-{;?l?pGPbK~dL >i&$A%t&Q`Bq,û6骍@ J BVZosϵJD3/7UnFu7:Ӣ0[G|0 ǽMH8`'呤(A۽g3Pٿtgk{iQ0UEg x @ip `tZ 42~5 "M|1]~dvHYhxP1v4݊i=1(=q}mĀ8 M5ޗy[Ol~i=+UqD`)E@k=ӄNRVO|M=FrlcvhIH [Q tAfY1 k8GM rS)ag{qfm4&.RY~e^ $v().0 0G yB]Ss1.xd'F=Ѡ.eELskår1 hjyեHbgxM^L: d-(;' hg8e2JR*%eAc]⯍%〠Eඊ6%UZdp.*^̱<VG/Ȧ65"Kbx+ǧy>~^rЦg`pmP\4͓:?~ _Gd +W.B!5*Nvd krHE(qk+GF! }:t-ߠܟnnG&;0} >nS )ȫ*P$f=k`z*#OOE"PʷfS&lOXݓaŶNNJtR(oy uGxр 5O iY__Dfd@#&TD$ r)$2{B> k 3"%"v@Yd/ " w?n?nKQjH@ 2Oxuj?xf{8[wƌ 8| 'x|v*"bX&B!|A/֜{HJ(~6b uу$S:ڷ^z0Y@(t _Nm2crIWɉQ,\>hd+V> {HHNuTagz7GϜU+i$˳(`rcY7~ >mSJN{b>ʆ./Hᥪ廅VyB-zf0zicFU8UA*0BމۥK`jHBr7ڡ Dbr yƺdM4L{SPs|2q\J6P@oF,TZV=C ktOG'`&H)>Ζw GF1tP4-8Sn6B9 0@<}ʱ"-%ݠQ&*uX?Eqf}1%ywbbۜ5k/I{bsbw G{ndqtS_)[f+0o2f$`!$ 􄙗aá{iB~@ Y;: Zs6_ꎙQ.cvڢ&^v6 2tKzzCv$ c߯Xw ajP-]t *uGEw)jo eBk G"ű&|$4:RN?7l-67O9- nlmJXw\ !Nis]ζPfO#˙HH$m0I hscy {%Tv< D0W%7ctMl+~ƍFR3f$(ϼL}'?*-HsldΊH[{,k  x\CX+ 4KN߾258,c8:b6u(c>+# >+rXg^MVikAfn h%Ҽ7;nx=#q_7I4@8= ș,˓5 quk}L`f\M"#8Α䑡԰y#PS$Z~z-W_A:םYY_=) @P#iRDP&듺 #zcfM0alC , AI yPXg' K*>wB)^+4Ϯ+9Si_=d,H,- ޖX!i29]S2 ̾>V(u#$DڎQlÈՔD)^I/ om(2 ˌJ? ÷?9*cb ωq'R|ҡ0j 9aкg 0 5B?:BLO {܈Db &Q v d9XlBә`+1E+XşLg+PV&40Qr5'mu~d:(y "ڢgn8|//= {0u(Fx}:SpA+,+QDK$)}u/ElV}lmq!{z [U72+=33Q8Y# lO.!|&LWøJjph2D) m^ |AV6)j,u>,!rw0"~ AB5Eyr r0"@T}CS5/[Ҭj4S6ڷOFuC?D^ ݩc!M DA6`>[.L S69.TLV7UrH0mjN/{=%&8~*OY?"Gӽb?SH( AV*+G[:3/"غX yb{$J $T|H*eT'pBl`f+ Nm.LK0|>سGS#AXT$TAE0u: 7Hl@z|I aWo, Ei%)oAljP'˰!V劫; ;Ł3Oğ;e 6;440 _%" 66kF`;0 ?s{r"* =fZ$827b oyiY+#4nHTJXOYt+dGުa7̧'-[9WZj\pv}[P*.8c @1Paw/>\Nѡ9'jHCMw$g8lݹ9dLtjI4p]#$ y~? IIDr&ٗrP&z/&ZIó!Zϼ5 ?͐ծ1v~X&dq ɼ@@Vb+t^\Pz)?H"-Q[%D$J䃸Ձ:npi"L}8UF!*Û>HG y'F< Á#O7mĔB=FBBcܭ0ٹ3Q܅7BB0]AzFF &Da(&ia=,kIQ%w31e$ȇ E9oN@.Д mn!Ä@ !Q*mD>dґ>MP!(,ΓoglOoH0G[-L't(sEݘosu2U8(@ʠ98çּ|🥋8s68[n^ő 3*dW4T"Vuڣ26ĵFHn4B t{I._LkոۑXxm2y;OW9G$A`|GC>:NLqJDJvxf\ȕs3 pIq8C3ΎEX0d !)J(,:=~U&3T!xNK6b|Tô6S^?N'Vv-ޑ+708 2(6^dDx8Cv`ޛr:8@gPC~@MQ.D$^,#yZdݢt)V6?IP=~2T)) wԌu rPD;8ĀO$ZڠAt;篸PS\G֫āz߈Wa?#HnwQ tzQQW+S~")+yRAW8"hzߺ.@S72%&YњGFw`׊hQQCn1YZ,ZO6b?-TQ:}6M ~eJMدcRO;aِ8ۆzӌؼ3FlvrѦ`Kvϴi}dj CJw+GQb"=HBC%@ސ_aPh"9p/XFkr^; !fK6e&ZxpDzC4R;<Ya2L[$+ Xpg``No mjn Yu(Ub@z!%Ƒx hktD![k폼szea".xGүGǙtWU3d,[dmf1602S)9ž 䱌|P?{֮!A7JA> DԹm~nzѰo_BKXg3Ț'OfJ,K!\0f҅.{ mzU47Բ9FGC #Md$ c9aᲠzZ>Z, Q<hG`S aʆ韬Jr8K sfSPqTMsCLTryTL2Tf(Cf4H&GהZ]MaTK9D8cvDާҢA$w]y ӷ@Gz _>ugpVB\ ۭTJkn0dB\> c@gii72 Q~g9;WB&(=İ=Ɉ"D΁>G)&[W}-[!FG]*N̠bx%lrQ E䏙(K~=OIgf"AL"-~MJ|#.bC{C<0ny"vͳ}ᩑzs(rB0f #KgLAV%'GAR&b܎^N3a4aB=է?OAN;P*m;]s |CXS.OQ \ on,s (q{bF~(É\.J e @'$L 6CVybG'ȀHSWϾ.v˭F;K Pbh*4i}9S%RLqՎf%ɁFp7)Vgb Fa !HCB'fq9i,{H(Aa*"P P*WXפ1(._uL,] =&%z~beW8[J͏zC0T ;Lwjc˷%R?5ta5o.tley:.߿RYඳr u&8o5oF ccLA;/cr w#y2hFD: Gz u~+OJ\ZuUdoiL)Ώc Vuس|pja {MױNJ4IO,tY'^t}R]}XХ4cROF2_yAJ7 2b>Xx 1:AN%O|̗?5 E(Z(YK.q`8!"5!̓@EAS>޹]?2}/7j,ӴLXIM4NXZH%YyrFuLL/!6ϥص;kf@h#!•6 "颥0I'ˈPkAQTπŸ&j=^լ5R Mƒ9Ƹ8"\k Cn0~|!5qTT]`ͲQW`O﫿\ k'?@2DȆi4odBmW~E]iR rhGW>BWŻ*y#i[JK jѥqC-2՜MqE] 4}sͤwMTav@aس$j뫍_4dn\m7?uhؔ/0s]8&ۅܧ#b5 u5"2$B=)&%x֣*ZQ|~S$OKN)vc@*Å n`jGiKٟ 2PzW uzX9{ëa1d'p)`_!k08~8RZā|{ ? 5cvA0$&3Ŗ*ov#G/y&,GZ 0A*&QWp>.W2 ĩic:f۶f!6|ZZ6sgRosb)=?H] =OOH;hx R BZϨvm.zg$W KfzDvxFSܝ EG>t uFek*ϠGG(tӞDCo>|Ye2/HX9"8 lsxoCE>ܸX%O5FGد{c<@\|H\@TK/YNJS.ΓJy=^$|GZkC~~xDA&q_VRԂh4=L2M&jxӲӿ"M9~î9*%8BfpB9WQ;-2[)P 0}#^6>fIw/=Dk=B;GSɼzKި"oM/S>P)M\ 9"7楡/ b0p"vaj/?/;#Cż138G0Ę)# 8|&EBoE7@+IɧxZe&*dx@-/Ӣ$ +m8>>ÜN6ZM׉(DTZ_T!CqQEgPW"(~htm :Yj CqK5q*1\> uS*:0zU /$ljV)h3ܓ@{zǕV6l]1YFmcE>0B w!},μ`vcS$yÍf lTb=}Gm~Fhn- Q?FW#*QJ$A/j3;)FF!ndeNz/hPrEc闐.\4ĿDQϱ\B+ك0e8eb yk SZUU}8)PL>gC5Sެ3~vBVjbLbk3w@=) k@cw@_Ee$,-/>fy|?b[ћ:3)%"5IeΚ:g&DMeyKFQeERY:@sJB~ ^cP_w {!:{׾Gnf݅un3􆼙3|UmV2j9[U̪ڭeVns*sU[ʭUm.H V$4p:\ņqnL C]JΛH17`ҨCW4P?4Ȣo$ z8#:k Kv-ΔA-ӔxP0o0 58ޒL R@jF9 LגګH9,.">uw(w2H 3)@< CS}0My'LBlB5GKeV$Y*ޞTAPB>  "x'8n ,zgn9A ~Tl}=!oҦE*H:fO)*U^ #H!tITOc0çrULve_jW 6GP67+e-V)nsno%oT0` 0`*VXPvb'- [~x; ?}#MZ]4pUaIQUh‘EKZ~H--_eL/Nl=^O}Og`UP|ϛz[R AH) Rkrm R AH)!Zַ+ZڐR AH) Rkrm R AH)!Zַ+ZڐR AH) Rkrm R AH)!Zַ+ZڐR AH) Rkrm R AH)!Zַ+ZڐR AH) Rkrm R AH)!o6o7uzVUT|}o\zzg3 R AH) ֵkZ@kZֵ R AH)!ZֵkZR AH) RkZֵ R AH)!ZֵkZR AH) RkZֵ R AH)!ZֵkZR AH) RkZֵ R AH)!ZֵkZR AH)!OLzzg39u뮺`UP+ZֵkZֵm R AH) +ZkZR AH) R BnV R AH) +ZkZR AH) R BnV R AH) +ZkZR AH) R BnV R AH) +ZkZR AH) R BnV R AH) +ZkZR AH) R Bz뮻 ?e}}bR AH) k[kmH) R AH) ֵZֶԂR AH) k[kmH) R AH) ֵZֶԂR AH) k[kmH) R AH) ֵZֶԂR AH) k[kmH) R AH) ֵZֶԂR AH) k[kmH) OLzzg39گ_>@*+ZֵkZֵήR AH) Rkrm R AH)!Zַ+ZڐR AH) Rkrm R AH)!Zַ+ZڐR AH) Rkrm R AH)!Zַ+ZڐR AH) Rkrm R AH)!Zַ+ZڐR AH) Rkrm R AH)OLu׷}UU@{Ekm DR AH)!wwwwrڐR AH) Rkrm R AHgt!wwwwrڐR AH) Rkrm R AH)!Zַ+ZڐR AH) R g39Np479[U̪ڭg> گϐ ?}̪ڭeVns*sU[! eVns*sU[ʭ}Nu׷׾*ns*sU[ʭUmV2j9[U̪ڭeVns*sOkjUUsU[ʭUmV2j9[U̪ڭeVns*sU[ϯ=}}@*ns*sU[ʭUmV2j9[U̪گ eVns?]3w+ܤyحNJ**seR.]7YIϮQYh@R?>і%;`8[h r{ԒT/<v6"RPAo1"`,mRnu@4>]L,% v9<J7f;0D@l@j)^@ڮCϨ~9 u/ԒL-3]G AҰ1meyA#@;| ؈ WKC$*5XP/`R+=dr; gG[^ =h=+[K= =ߖ]'(s(.X1R`[$;١qߊw͖9數W0` 0Հ;  0`l:1ɴVؐ VNrH ck|^" < -FxY-LHJOW# ` }ċH4V+Ql/~KK/̪ڭNw}}2j9[U̪ڭeVns*sU[ʭxǏ eVns*sU[ʭUmV2j9[U̪ڭeVns>3ϐUUʭmWns:뮶sU[ʭUmVUU̪ڭeVns>󮽽u] eVns*sU[ʭUmV2j9[U̪ڭeVns>']{z뮻ʭUmV2j9[U̪ڭeVns*sU[ʭQ>Opu*eVns*sU[ʭUmV2j9[U̪ڭeVns)svs ̫s%xWv~=6f=9|'5l4k=| O~cƾd;4522O4qDdCk:E\aƉEw(uu%O~A0G_# AhjU1QlVm֔r~wnn?öYSe?Vr zDB +?̭ʰG ӎ-f[e gCZ'df_лq E3$7d% o!u e`P#T6xg*5f`,\CDr\e8 ՗@rZ!;357Z8,Ͼ~qnLE@ +EO΀;UPZֵkZֵkZ%jNoɢvgi39\A @DFZq.3uL}8*YY6_ED sU[ʭUmV2j9[U̪ڭeVns*sU[]u}UmV2j9[U̪ڭeVns*sU[ʭUmV3Ǐg<UU[ʭUmV2j9[U̪ڭeVns*sU[ʭ}}߿̪̪ڭeVns=^s3s>9}~?aܳ;ù̪ڭeVns*sU[ʭ}u_7`9[U̪ڭeVns*sU[ʭUmV2j9[U]w`9[U̪ڭeVns*sU[ʭs8Әʭ}{ʭUmV2j9[U̪ڭeVns*sU[ʭxǎUU[ʭUmV2j9[U̪ڭeVns*sU[ʭ~/u]*eVns*sU[ʭUmV2j9[U̪ڭeVns>jPhi.37jt`zQS[HMn '.!&&0lo~-i#r!8-$y8"3g6 !m`N@J ňTpS ҹ$=|vGyugŷP&v] 2  4,JvYv'|#C-iwޔ[r` 0ր;* 0`tg!.%hB}ann hݜ=*D>!.¼X2 5q>.000` 0`?G}}s*sU[ʭUmV32j9[U̪ڭeVns@iϟ>|sU[ʭVUUUUUUU쪯UUUU_]u]uUUUUUUUUUUU^ʪUUUUUUUUU_UW>@ UW ~~uB=@r!~l4ꯜ| m~=1s߅߈?EC_?O~r'cG2VLQLgһ.=mD-dYk=Ϟ~Oߏ~/~H*Q@GzUUUUUUUUUeUW]u]u]u]u]u]u]u]u/?C;?&|aoB,d_SLagyDqEl AEtJhJ.AOv#-?#/_~W>׀;O0Sw; zrn\\X0ξE*/; UٜMUY`ԌrAh;;`ŵ&%F&&#f͛6lٳf͛UU|UUY̪UUg2eUUʪ9UVs*UUY뮺뮝sUUg2eUUʪ9UVs*UUY̪UUg3UUyUWUUY̪UUg2eUUʪ9UVs*UUY>^eUUʪ9UVs*UUY̪UUg2eUU~ߜʪ9UVs*UUY̪UUg2eUUʪ9~dU^̪UUg2eUUʪ9UVs*UUY̪ \UUY̪UUg2gg2eUUʪ9UVs?b֪UyeUUʪ9UVs*UUY̪UUՙ` 9UVs>{Ϸϟ>~UUg2eUUʪ9UVs*UUY̪UUg2g_P*sUUg2eUUʪ9UVs*UUY̪UUg3cߒO5'JiTS֛Vkg}Of~g_ZlP4]!pEEj~S  `f[D_tQh5Ou#ra6PX5j i'?lsEl@=kK\Q{c?]6~Sͣrv1 0WCqYo5yϻ$JhXl`©ə1en1{CwXλr tGH 6hT7@"%q1uޚo./y^EJ%]ǿh\[#zKZ^ ]!"F05H!s\"ޟ_o~}~_:`>7w3?>_O?fPHn0WzlSϪ9 PS,@9 cYO߿5|_?A= UUg2eUUʪ9UVs*UUY̪UUg3? \UUY̪UUg2eUUʪ9UVs*UUY]Y}}UU{UUg2eUUʪ9UVs*UUY̪UUg3>;}}UU{UUg2eUUʪ9UVs*UUY̪UUg3U]UWUUY̪UUg2eUUʪ9UVs*UUY뮺뮝sUUg2eUUʪ9UVs*UUY̪UUg3w}~UW9UVs*UUY̪UUg2eUUʪ9UVs?{}}@g` 3g0`9s {쪯>|UP9s 3g0g@ Ps:뮺y3g0`9s 3?t(}K^'i*̱ u;}0ȱCAB;ڒKRm DRz;{j30/W]⏸"%%_ YxmS $e|EE$VYez&4]ioۤ6arȃf]/g\g~8??a%EB|9RPF̬|C-l㷻akJ@he@? ܦ<煥ٲ KMG,"&qiWs҃T} 8)I|{]s !rzt80w&F9bo¿0te&<#"I 8{?7}ϵ~3+?[_|#'i>ϷPJ1)O.f]Cs`dε F(Mf xHjf5En2 'g3?og>G? 9s 3g0`9u]u}3g0`9s w=}}@{0`9s 3g0g*3g0`9s n>|9s 3g0`9ϟ>||g}}`9s 3g0`\H\3g0`9s Gz\3g0`9s Uy93g0`9s 3^W <0`9s 3g3f͛6lٰ (IcR=82_\3_KON m!$Mg]㈰ON4nT:.!q嗯-G^j!&LATp <@w>W,2Dwu5h/ȧ젧:iwQpP/54̍x~vT- X{ӿxݧd]^{D`*3Ua#opӊ3eB`6q!iPz ڝ 9Rp{}9m~$_ʡ| pG3ңp)HGiAz8R{Jd$!q1?(xr9e|Ɲ:2wɛ7jQF`-[;kFf IkwOH" BHPR1n R׆XriWMAj[e}>sdAW6*/ -ƍwaToi~zTG;N/Nx_~@Fnavf4R8/.$v< eR]Ur|z◩(ǺY=K?[rx12f Y \(5i2 E/1:fN̴ؙ$[:T?R"3OlZoD BY P+%2.b\:Ht]$'ON]sl9QdcUo-F)L/Bq/ U-ݿϰ>jQ" 05KGfNZ.? /eb;p&,Hnna6 s@4ɏ'5r5 \CHP)j> ]?$v/޹pݙh)>qQ_ j >8awbSVo%t~o.C/Ȅ oрDf%"5 8cPjts̵Z \ J.#i̬>YU a3%`2̂]owtoUm!ZAq>~O;ZѰtaS1ԀֿΟn' I^Ԅ\pCJ QdգXXX dCP _~>[o6RP=daOѡppu9̥(ey-#g ?s}TQo)ΰZ9Lv}"&wͧ ZAUW֧(1{M.p>7E[s E+Q i~ܟ3e?L0,[kKkWv W:Z DFU/7+mF6BN]4rzAmID~T5t~{"|IK!S\K+4bپ%|&"(Xe9 Gks6h$O؛nru/fgT8Z8pMeְHiPwtOZ-NvbŒX"H~S=͏' H*,#K&쟖QMSFl~ک5;w2)4{d0dc!__߲f7,lT/~8EeW STœ>=6Ǝp^SV{O'v:tDU97ӓoƷ0 rh *0բ 8әc<+×<"Fp8XKoW܏2qp2KyIv/M l ̆p%жn~d >?Gmԩ}ge̜_ư nμa>0:|V.<BlszM1 ?̆WNWxG'8P9Jo֏ eaM<aG;C1zR&ͱc~\գQn*K#mc ˞H.$LB 5Oo5";z1Nm뿟_R'&KGߪ5_/QfZy ':[2ҟ@T/EٴE F*r\,2yj"ZZ~9s&GWϚ$u>Fd,{FSM=E̓dx[ UMSF~xP6i}>z1/-vw6=+듨@eys甄*Fф/>n%NJ%`S~Ft˴㗲xKJn٘_i# 7 <a6K;+(vvxZ),Afـ1HA70| zCa$1m& Hu; lڤ>*YY[ճ756vn擔Cpv}m^;w{|5 '(GڴQ7.xtߍtC[924ޡے}ZYo~U>]:y;gI6NMWCVMgb2Vx̜GfbXtzGzK?#CtXks?.M?ǧ~vL'0 'r wmU s1 Vk\&U~$q1&hH\zJr f:qA BCP2]."*zhN5O4VnPx %ԟSN~aȧv!'GjoٟVF2Qt5! d YcS|_c$ a&~f?M _F-.v"`Mu$^91B3~nƦK[>Lxd^.2PPlAYrHA'^10)<}<.k\OQ|=psP~X*r|>ZDVYθfNi쾊w 9}rMLO2LƦSO!u] {qϓϡ{Ors*;5uağmzyd|Qz~i,߯;N 4֤3OΑnMu+ l9fM5<-k֛@6aNiOi=OM+3]/&t=o+k5uT⬙ӛthx{m6+1jM5:I8Pឹ~dgCO)3DgDrx=;d^nW ՜_}SxOKARk1/vc8_okogJݪP/n{w 8'oI4 =ݽzt 9_٨&KSi9Z)ڳf{{':CS(sۥ>|؇IM6W7PYᏀj@l#0au`\2<$Xg򠈇Czk[ܹ!!j Ln} 띑2 !B<} &D2^s.hU:Do4'G9#Jji8d3_N嬆4 Hx;%>kHXM_x鷺koLO)Cp~A* D8 4@;kYi;eԓfTBl)>`~5w^nf}r P.ϸmf%@`u(9q<9q|FS4c eTWB!>>p wŚ8Kup`,=&mH[cRtC1=AE,9SEj ݉N=8oO~u|Tt7.@:q 3HރLNCg{ e~~R]/4<g@W WrF}oy0k,#Gl {/8Q@*#qB^ +jMHEbu=_g$.C=_{CO-nh>>:`*vLc>٥|t96| gr_5pNɶy*0YE̔? H Kkx,D z3,:<{{w1$bQvR 2ʣ Jj|֧pm5CrPKCF}oi40e%eM!CD{+$VLdT~%+$_D %,f,wCFj"2ؼI.P(CM:P8!/d#nD Ao`n}}i7fz~_8fqRq;4+kXKΑ(oX n^| AA+RAAT:i0ڔ#^2o =֑;T[HBuF o"͚ǫb7d3JY)B  )^տ7aLŢN^@R/1G%!Qhwa2p5`8,a|Ł>^L_ݱ: 1A&z!TD_|Ad@?S, *u/ڠ'*hрvuCZzWLX@'zDL>hvO /p u?HЩQ'Ǿ(\Dw _|gEЧ'vY⍂xxu:D/,o m.ĖawI?w,&žd=pVjiNZVq3k%b!19dlǁ*M΃ \&'QwkMzXǫ7,?bJ6͸NIzqƊ['XuV-4awY^XpC8d ]\p*|WC8CvFmlz8$|<>fj%ɨjŽqͅowtC9m "6daEZ;xZH)A3'uUQZd=NxÝ)i`GyqᑐG&zZ'084HdAຢ"OvUРnfuN+ 'HOUý]MY z3 rɌ(K!#)vL@-}dZYojbrX)#ޱ>.($)Q2PLxkt8HdD+8W FKp,N>rdiI)'3֤wUbҚ>1T* "-,ֳKiEk6LE|;9@z+23>gk(Oxm%ʌAgQgwW̒<Ȼ& ("R9_ ·Qv=F+a%Z\ΔZz)m1^h擼A;#E7 B.we{mm"#L-~I?7En9>7Sk8OD4!:ox8d=Gh{{3H3,-PFsÛ f[,48 _/D@9A0أλsg|MejCi+$@=XLs]X4z )yq9;ȱzR {bуp=6lv_RtX0 a(1Aw$=;=`KF.OX_ KDl1J)RRU5g_ J&=`-k " c"M0E8aG=o:\;/ߑ29zM3pb35?Kթ~Vi\*1nce)@ϓJ0ʕ5Z%Љ:T zE'/=Ry ~ u@q<RoI~z2qE 'y*HTd|/g4XAnQlG[`t1Jk@,Wa ?Ffj YO"]H%fcLuV"4JQ3e &A_-\%U9X xϭ4_v0r3L o#=_'O0uܽֈ84jGmƴְ7c[h]~6hxy8}+yT&y73;Bf!1q%Sj(+V+8WϦ*KrxBm#4޳Qq{ QΛ#@SNrF@2CRY 2t#I2} 'و]ěRǛ 4{d֢lWbGXS2 k{BZ4K+ARrl qinӬ]Tom"4qrG[h&p(JgaCJ6޵s]eM~^Vk|͞TrE܅iw8gL zFFOTX}oǼPoRWFs( 6+݄ }yban7`'# 9,@Z?ݒpP@ʿm4b*@~#Qr4NfHُ(DUIiCn8~/#ypf " ʒrsnM˘~w I)aL@8?5̉mWyT{>|w¿otUs">&Vâ"/wt`@l $÷`iX xi-:̮OŇ'ZIrH:4XP3 y 2M!@5\']v31{ 9$7Uzt)ק `h*un۞O[pl05O[b2Z H_?:k_PP/02\aUze; |f;[O:[pm߷h˳xOsہf}$@O2njKƳs 5'Cf_}m 5·}M~-09AnwLe8&; ߡg y@ƾBiikc}Zǫ|)@ð[kyƇ$:F@cH,'^?V]?OΒaV`X6aaDљ &8y :d/ q'd=) ^8ː8/ ɻwa3=mCa'_iqP 'FgM M7%#$i&Qd6}Ɠ6J`L@|@(Nj'E;yN+-9jҷF#&||rWD|'쁆XL0ZO@a츒 1+l.{)'a4frvxNI=7szj,z5 CÌN]N%l]Уlz~}ν->b ES8 DF|3{M1!^1iŐs$q# spU€G_zнpĉ2=*@y ^ςT@ BoCq.ĮROX8]𥛐jEK,+FKFeOX' a; Wj1pSCU XMDi:JXjIOXgH @ W-?c'H_PPYLC# Wa(ޅqqb"-"Ubw8T?jMfrH$FC }@" A.u(!2 KՌ w:@58 $a4OtW H4mX7+ 6>9W37~f)ԆCp'MmtJIQ6 Y4!2QzD0i$k0=wį6d.Ȃ/xUؿgĝ 0D/-_oaLD " I\GX at.(Bw^I6Ye:H~#0.XȏX`]^_ L@h(-ϸi 7X Hg^-a)0P.bt3Ӂyvm?֙O)4Y;uM [MgR)`ivC0s]:I泙(l) wt C&I&lNs^*b@Tށm\QA`, v$qQ ^昋Tl39Dw,{݉9d)wNj\m;{fA=K㛦nO+?i7*|Fm뤼L=M!@|T2?gͥPSg}L50ݐ8n"o'8s5Lfi b)=W߲ %U G?X㙋8a ,x!@Z# ]''̱G)f@z FpΑEv  kݎ5!#YHAW m!%~q󵹥=Z a! 7'0.M!M,yT0_kavёj2gR&o @z~m-CM[?{j괟Hbro&CfLxnӭt(W\\8!p fmo{o,`>ZG?ٕߋIm:7)ٷyx:ݣV9zx{֐4/7=462KСܗ9RI2|]dyv_nXgF-5AhA氏 ooSϢ;bQku>5,8u֨ ƭ~$ٜKgj g"qlOeBV\Nf=8 1Ć9'z*hbo~M*F+ pCd^4sPV}:״㲵?IZ5$)ٶ` #y^a 8rxpx~ GC&uX;зw98V}#)Kp6S+mզp;Y 1 ?'WGkZ:r>sTn-8\[UE8C㪘Zq]{]6u\9E<'FƁy;6 [˱Ǵ.&->$k-+7ݾvrHND g.XO4E)Tim{.9O+I18cK×8c u^cu;1z֔~;rrHi6&qhgOM6gEyW%G$]gҮWb*Q}~FyYK~&=4c\(G,ȤG߮,$"X@Е1tKSS;eSYGuM'zi[IF}YnV{A 'g6rXK䎯,B/qVl$S mgNPh|s܏Խͬ ht-PMߺ:L:j(ᮥqm2BdJ*HQ~lxW!C&jfSZEH/b:y>"PЌr8_3%X-WSS5)`8SEe֢ l6-DX ZD3쐹89 D8f#fL/+7)&J8-[0:9´*mN&Pp&AWY9OЛne&8^[AaiՂI7YI kPe9z nC!̀-&*{;cr3Q pg=dpAv-̀{s$pِ 8ijZSԮz_mxhf=HT.p`(#h?H,CqO֜9#fqVM>gލq4Ӷ}d_uٲ~wRv})Գ|ge~=;3؟o{wdzWųbI3Ffhki1n͛⧯r5اa3azWg,)8Dƌӕf ?oJy2oS{)`)!$ٜvBu&m u;!8͚!?0hfz)Dt!$D.Dag)r$(#_eC.*1)ADAmƎ)dEsCJ( q<D3L&U9MH Ѕ5uJF26r ENG̔YQ+(5u%Z.ݕI7%5>`4.Հ_;҄l{ N-p22 ί1!w5 RG#͏Ĉ9 ) =! ?NL@ѓ>,%g¬U/z`PϡQ z%~KpafKTpl_Tvu@ޤYP,oi@0\÷Zlr %1>hQwP0E\Y [ HตJ:`t l1o9;[V%w|^_fPv% 'ֈZ!, 'oJ!֦(]|R`0^^4f]iiSvkMg7Ops2{uRl[-I$I$I$I$I$I$I$I$I$I$I$I$I$I$Iq$I$I$I'II$I$I$I$I$I$I$I$I$I$I$qI$I$I$I$I$I$I$$$I$I$I$I$I$I$I'qĒI$I$I$I$I$I$I$I$I$I$I&I&I$I$I$Iq$I$I$I$I$I$I$I$I$I$I$I$I$I$el[-˒ОgCk׹t睢mqq}+|fm= b5`>C{qKD,~VWdUW">wY]cqZKb|Z''aB Fv5>Q[a|W'#`0g!KI$qI$I$I'qĒI$I$qI$I$I'qĒI$I$C 8888I'‰$BI!$LI$I$I$330333 I2I$I$I$ 330333 $$I$I$L333 330$$I$I$I0333 330^Wu$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$330333 33$I$I$I&ffafff$I$I$I0333 330$I$I$IffafffffI$I$I$L333 330<~w#<3ΒI$I$I$I$I$I$I$I$I$I$I$I$I$I$I'$I$I$I$O8333 330$I$I$IffafffffI$I$I$L333 330>+ʒI$I$I$QfffffaI$I$I$ 330333z=c=cҒI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$Iffafff$I$I$I0333 330$I$I$IffafffffI$I$I$L333 330332I$I$I$afffffauo?_~}'UWI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$330333 33$I$I$I&ffafff$I$I$I0333 330$I$I$IffafffffI$I$I$L333 2.KK.Kv?pXk<T: YpQ)p=P$&/8$(F!`Z{VMF%Յnt8ꃁTZ'L6FrŪ&O8h2z̸MiLPYoTO-ڦw8R}#&Yw`u(ߍ Z(a Ú̢/"Oh9%D MوkQ.0DF+h LRi]ʚuď>[UPvH,}u$Y0F !:7+e< *S.۬gИ}kzFzM\q8k6Qbh*Ԅt>LK[eKQ]5즭h?9,iPbϮ/'Ů8 ͏!^ތJ6?Hh[c ! $kc+?`O\&ru.J c FɰO3h+XEzhMm3QSB8Zv3ȔeĦ]KDxDX-R| LdeD&W<\N)4ak a vL$S6N(@1c%iTQphAhv8壥R8{I$I$I$qI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$qI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$qI$I$I$III$I$I$I$I$I$I$I$I$I$I$qI$I$I$I$I$I$I$$$I$I$I$I$I$I$I'qĒI$I$I$I$I$I$I$I$I$I$I!d(H|P!Bc H`55zT*hv]#D|GGhWy0GA< ܊bzDʩ(\"'m!؏GixsQpnq&/\h{G$I$I$I$8I$I$I$I$I$I$I$I$I$I$I$I$I$I$I'̌330333 ̒I$I$I$fffffaffdI$I$I$330333 33$I$I$I&ffafff$I$I$I0333 330|G<;yw8$I$I$8I$I$I8$I$I$8I$I$I8$I$N_FfN8$I$I'333 330<qqqqL$I $BffN8$I$I&ffafff8$I$I$fffffaffd8I$I$afffffaz?myz$I$I$I'qĒI$I$I$I$I$I$I$I$I$I$I$I$I$I$I=330333 33$I$I$I&ffafff$I$I$I0333 330$I$I$IffafffffI$I$I$L333 330#sc<4^&ISPa|r~W5oMw4e:wٓs=2or,Πt(6ޙVLp?b0($[gҮ1xnJ蕴Gc3px|j3(DǼ% -h$rj^#*t\}k1o2/ؔsGÆi-Ɖ='Fs 9VdS 86兯0Sî̂O윭Ź ZX0V:#' `"8M>αރc+q)~F PE[4f%Ds2*ɦx}"Tޘ(w Y1!tHXn/y~>F@\7d -L.jNq&[GbO~~{RŃG}=^x{=)$I$I$I$I$I$I$N8$I$I$I$I$I$I$I$I$I$I$III$I$I$8I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$8I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$8I$I$I$LLI$I$I$I$I$I$I$I$I$I$I$8I$I$I$I$I$I$I$#"\c{~˗qYqܣijzbk[LJT!c~cղ=cOf泘b#eEA}K(o񭊘?s>C 3ČHI$I$I$I$I$I$I$8I$I$I$I$I$I$I$$I$I$I>LfffffaffdI$I$I$330333 33$I$I$I&ffafff$I$I$I0333 330$I$I$Iffafff{>K|^/$I$I$I$I$I$I$I8$I$I$I$I$I$I$I$I$I$I$I>7R+id!oz^ HjPKAſO&cq!l ʒ$=p`PK®N@+{L;$iV>2ZԒq\KJ[^ھy2z5?@(CzlvQ#rӎK&[#2V IAuP9\bf.KZPeB]p# ?-p=. "v.rϿl_-Ls{< h.=:C!S?Ov9G6HpRJ Bw'gk&O̲ߌ#ڭ&"t M]MwL{MZ A `f4bu&0H?)HzZDRC\:%y +fE%܄fN/gj+\>n@!@%_9~OM8DO[6DžU):f]ίigظ"Eږ)^^IO A]{>)u" )`=~cc/>ڻ\6 4O.hrO5ctAw*S&r⸵D:~18B~fPQftȲXH1H O=K}21ݸVM-⁏RZunP;&[?d+ 4XolNvs>ejGVbʞ%'Cx ?[?X?Ll9F*]&x7*\lQT{^ #N=]MZf}nB$xR-'HԮ/~]}H *r.o5$E)-m|"&lowU1jM'=T*yp=\4r7*ƍ[Zlڌ4ћ*u)eU./5l3a(lʖ#.`@^.ZehvBng+HEH _&ȦGw,d~:ba=2c} weOt"&/2# 꿭m4oξuZ9L# 5qfщqu3}#]{PKZ|Y AlX(gb+re$8"w^&5;j[ls۰_M(Jli"Gc A L#`!SaϾtc h }tܑ^>>RF9:S}I m#~XMgp|,QY/_vA1 Z!f8%bmq CNofsYkRi۩^꿯߸vh9OC <%y$Vy;Ebˠ10uVNЈtD+,6WEXaG=}ı]AIW#Y>uw]p % RϝƲ\{=ߧ0 u24oDC5a)R֚*Я"Z'c.ƪ a<}Y٦ ]^!ki))BW=m9 tcRos^?;T~Е!|Wt8#)w4~t(ѲCY45АD(ga1_-/Jvh_9Me7+"c??LO^Ӻg$eAَEXږZmGț-{mА!NL{͹@ y"e[)7W0HNpM77Cm@׃cؓ=7-(Zk 9*6#xC55[TԿ9pǾbŋ %/Dxn^L}UCe'νҝ6mA0BQDK9>5w-o?]7X7r+fe; @p! gBMHw>yuVdOj H ji%|AZ c͆kUn|v{[gll,8iG| \#D}wi{P10{(B [SXcL\3j!}?kR,`m oau[5$M=dՎƇwpDj7ܦ?yvr]ut_4 rIq9 %0>uj~C߇9oU9׻ea)]|MęaΧZ6|HT[mئP.sx_z3*lo-#s-$7oҴ1J1rL`uxߪ0C߱gVؔ u*LmMYzgu&=/hҫg/_8!kv՚9oByQMϟc[.]ɴu05~߭o"w%|ɹsNj%7<~[-j\iKM6$6T٢3|ca5ģQ:VopW`IL '|SObY|G:X5$sFaކ˵8QΚo;~Pl@֘m5*pbxAJ$SWuAl $"KKhUl$;m~5}=GUt֩2HFjo 朓ϩӟyb6?[a8W=k;XfBvDKf-e$I$I$I$I$I$I$I$I$I$I$I$I$I$I8$I$I$I$$$I$I$I$I$I$I$I$I$I$I$N8$I$I$I$I$I$I$I&I&I$I$I$I$I$I$I$8I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$8I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$??I/qg~W|O;(5ww OC6 &Ʉu*{"Az:VuU漹Eg)P"0@ 3#1#1#I$I$I$I$I$I$I$I$I$I$I'qĒI$I$I$I$I$I$I$#330333 33$I$I$I&ffafff$I$I$(333 330$I$I$IffafffffI$I$I$L333 330>:뮺I$I$I$I$I$I$I$I$I$I$I$8I$I$I$I$I$I$I$ffafff$I$I$I0333 330$I$I$IffafffffI$I$I$L333 330332I$I$I$afffffa_s޿7z^xI$I$I$I$I$I$I$I$I$I$I8$I$I$I$I$I$I$I'fffffaffdI$I$I$330333 33$I$I$I&ffafff$I$I$I0333 330$I$I$Iffafffxx=CI$I$I'qĒI$I$qI$I$I'qĒI$I$qI$I$I$$$I$8I$fffffaI$I8$IffafffffI$I$8I&ffafffOd8888II!$ 8fI$I$8I&ffafffQzI$I$I$I$I$I$I$I$I$I$I$qI$I$I$I$I$I$I$O@333 330$I$I$IffafffffI$I$I$L333 330332I$I$I$afffffaI$I$I$ 330333o/'/C_5>| 콊Boxl&][A~r=y۴kH 9QEYMmNdYmHK@Ct陶4}*۷uuELd:n 3ߵmAsj2,V]Nv/m *Lh;.erO *އth7T9n-4=G=ޑ4Za%^ NC!Az}q#$cquy(k+RŦkXk^&⁄;Qu p@ 3m/gij(KS&_hI0cNM8kP8 ̂Vr~գ,5r,X*;B>ںG/c^ࣤH,YE~SFU.Qk78{a t[ʼn"OW9kj86;#@+F5eTSG;}9U0QwL+À oԹH(Nup0t;<)m1kN ]J>G9`U,t*d_ %\!^&L䆙#ai,uCMWrVt;Ы |TV ?8] xw(w`Zр@kP7Z@&4=+jK^r#ɬ>tq T { Ay@ -QBDdE0d F76yM _KP !{V+&?)iZK[əb{OhYTh__']x+ZҒM^X|,zsHQ@y({k)Fk˥-3m3f/)O6di,NOШ_$>YZY]tzoh.;d/f[`j\}W+(l-@#G쨜ћgZHjB/2X:pGq9Uࣗ5](:8}k"A&'UJGn'6$IZ!;jAH.W;ֵD1yy28_έ X6/ϭ8LW&`f27.Mj[-eԒI$I$I$I$I$I$I$I$I$I$I$I$I$I'qĒI$I$I$$$I$I$I$I$I$I$I$I$I$I$Iq$I$I$I$I$I$I$I&I&I$I$I$I$I$I$I$qI$I$I$I$I$I$I$I$I$I$I$LLI$I$I$qI$I$I$I$I$I$I$I$I$I$I$I$I$I$l[-eM3[ጧ>}sO?̧_Fߏ٬X5TwꛠAx\螽M_CPff+^-퍔/ |릨dn.MNIs)*Cp>G~'=?}{w{w$I$I$I$I$I$I$I$I$I$I$I$I$I$I$III$I$I$330333 33$I$I$I&ffafff$I$I$I0333 330$I$I$IffafffffI$I$I$L333 330>yg$I$I$I$I$I$I$I$I$I$I$I$I$I$I$N8$I$I$I<330333 33$I$I$I&ffafff$I$I$I0333 330$I$I$IffafffffI$I$I$L333 330=ս~kxRI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$dI$I$I$ 330333 ̒I$I$I$fffffaffdI$I$I$330333 33$I$I$I&ffafff$I$I$I0333 330os>/I$I$I$I$I$I$I$I$I$I$I$I$I$I$I'qĒI$I$I$#330333 33$I$I$I&ffafff+I$I$I'fffffaffdI$I$I$330333 33$I$I$I&ffafff/x=/KI$I$8I$I$I8$I$I$8I$I$I8$I$I$ ̒I$I$qOrffafff$I$I$8fffffaffdI$I$8afffffaI$I$N8㉆ffafff8888<<<$ $BI 1#1#0b5l?2Mg5l .̲Qu6t ,I\j(slsONo7_~7PY)~o%ɏFC͌=΢Gn yf=̴z@oU7e@Mz&v"G1fMe2hdng+LMLf$䄨?98lԒ>ojdy B)9# "FY 2`Ɨع@gu,Q8ys9t5?3B3FB L 3P`фݞP p:>C>jQ~]~1SzK Kߔ?I~O>l{0:OcuOuK}wY,u17!E҂9{+d!2S? Z.?_%hSKJ  ,ng񚶎G. oO !\xw:ozS(fQRE9& A;P[u%ț ?)ߣ_ªy#FD㿪,wU7+rF5ITܠХo|3݊&/A$IɹM)#uSQl7LY]Njߵ`~޵wh{̞("Xw-Ia2q|&gۮżڧdɃٯ6@`B0.4v*Y7};ZrFLk.#b qF=ڑ7Fa݊ȖWr0D \*[O7ቧSH <#T8&˘w8yx7IFcmf2YIo]V:Š;-\#/GOsƜiWoPdKWQrֲ9i8k)z+>}ќpm7}G֧00wOp^2ڰc i=!Α ~l죩Pmtf5P]`* sH p= ~P×]W~<ӹ"犟/jA! '?nwf[+knl&^#Gv1u;-W} 4B0ѮP^O.饍?$ :9)a)bg2s|) V;tļZ\}'%J~. aފ^T,QR͞E+43氣cS r`ЭWz_mv6K[LƠq\Z 5+3Z2p޿KB ̌G b-L+1؞+@T/),}Y3r Rc9Gr2Jk%~^Ov9w3#gnVžsVa!Rϼi*n6k?L(mB bk8s %ٮ^?Sʯ[4Әr믇>1P$NM>~&cy>P7.RlS lY>*^'+2'b}!BO V]H|Tcß{۝D@J˭g-4*P2k^*‡KE2ϱ筥+<uBO BݫggDx4k̹F%$o6>`R^h r=%hDY914bksjf)tz :|fxy3ԷWUchn{ɤN;QbFcuQ0=eP=zՋK|–-ڽq:Q[q{&wti54 ]=EܬSԑ=$3 w[5].mvӊL*yZ)۱yG,S'£ /J#4N,c%vFnߑ[N[=>__LDdpS 5Þp8V:WeM<^44KWAi?ٟ<%}1)8l|a\Go8uQ{[S>@RG9wK Z[[-r.!~w4\䌢;7t㤛Ib۪zZw.(/$L0ψCbkSϑ"7~*,+,#U!o|Ŋ^Կ&o @:wط(Hijm+:x0<%dB@pnݎRSW}-ޭzf|^,Ε=l"'QR!精Ub߭{ ],:J%SӶۋT ӄPl(h(ܘuH{Μ㚣?]X7%`^~-@{<:PiG3aAn9yT)Jc'q2e^wk&\aycnldmc;WۺE?qv=5)ˊ Z04`֢gxV*a2#rwǕҋuzO~|h YTuv~FiTŝgso/Α8DU>hy̡wtGQWi֪7DǬRf]k%"M60gj>NjA?Me95T5qG9;_yaW˺z9$ Y>V"(!@XRUχds4nY'X焏jaMOso:zӋZla*KjRdE4_1̬|T[hT*~I[6Liq/J3Ik\rO@H~vαJ@ϢDP@X[0"PWu[taNzuK6׍ྗ +)E eBk-E]=F7QDB}G?/|kC1O~B)ʑi34G6?:WI Zx+~_;:UZk<;ƾ)]_te ;O`B$?_H[l|bxC ޤf?KF7]uW$ᆍBB\U e7cx]@y( &2?zS9*fh:s*,Sf`]KWIOW4=1Sm_eұҾ[Y~yC3r.^^-ݹ? +9w0 HV?>drlŎ=tӳ ,ڐ˸̈́=~Bq3LvЕ^Γ6Dܴsm,3ߦB{eB;qP[fK6q⻄Nshb#tэyIU$˳D(bԎ@m1QR?y̝wm Η"aol־qhe`婔L#.b1&wrbޓYv9:Do#. yWlGo g)O#dJg?wocgyj~l| ^>}})Vv7/ʼnKw` EfrWr\4e^ B#jLruZH> N @Ppv?I(|y :?g_=Ko6?aS^MnB1vWI7Xcx_y9mDAUEXsG;L9P`/88iS 9XeO'Znwt oƓz=:Av9f*8PHPm9rrJ^dnQޝC1ꢫ bQE)R745(3bWy5K̄|zy])42j0ndcI~ɥRv/dVjT˨X.qyf_׵|B"-n9ۀ^FߺBMLp ~nwbE6>`UFa,. Zn"4lW/V*[|b 9a,psQJUQ#R8+/,Fq۳S(r6( r{_:/v=rMZ 78R btJX%j= ' |屩}lDW|=wu,>%-U=zQJF^-v3Dy!ՌڿSχ*\n?MžA?G*XҝtK,5'iךua~T\#L$~]Jy=@ DT>R>p/Zi/.Vo#|DjlV>NQ$l A9͹|wR;^12:)bK_?K^ fϮq:.2D)d8jm{8,~>0n;' VƬa{-΅o.+&T‚1o|Cbts@oEg'0 v)nƴz|ם'^ :"q},Q5in oBUw^WϐoBS%XAShP8aB,0LHHhoo*K\'bnP4BPʈ/d4;svSiH{1 y$#2;J%%ՠ*Wju#3XJr5*[ϧkUVz~L %oֺܑ?pZ#AQeQO'c--O1ncZNrč;ic't6Kd޾,0;Up4zH `[MsfKmN\ mEЭxR Ѐۉ8k#oT09Z68Lnl%Y'UEtu;'9Y-.;ERģ=>Yu\k|غwE1g%i$+3>Aܶ=ݱL6a y{Otn;^}6"L"d_O$.MhdK`cgigĕXYD :j[z3nf1/kۧٹn!+mEIij9\U;/){"Xj~/6r h7iHt;-_)sME:MkuyÊ㍑_4νkJ>&U0=,l#g)hY䢎J9bbZIZZK6GL>NmBUm];4Ui޳*iZVԀ bR^@ lpzUP] 7y{Sʮ۳ 7q fP" 6|X[2rM5ᷜдژDeG^fXV"V~ۙ!u4a&:|[|ڊh``98ä xѯDQӝXi$9n~? PVymħ d C\m_|{{ͥ|h[#ʂdp﯆r69?T@*5l9w\`E9Y dمT.Q\G>E =igS!Fo.逸^hU[11Ma8Jh3yj |?-Mڸr"tOqg$:V\)N5,:zS|c9\7D{'zJ_] [鼥+|N'7/fQX.!k[?2f6 76ޅIjB ӹT-*-Zvg~~jG ؉Âꅆ FX{*/ N/I*XOFEèHbC+/# ;8"%Z4%7_c"%l>?9j.FFv6K|#~SHI{({*7/qxwWUY=W_!j=K "nDž*b\MF}k|3}`  L@AIrQ G\{%XHL 9tp:Ԥ!a58GԒ#{$YcbH#,+շ~:$=ȧEbbRZ/J.#IA$<, ܈.5 >&ED`S6¾I>tk4 yoVUӵ]mDNvʚ?g]?7kU F h65.৒ 4}jhvzxL\oPz;YVu ]!+%O(8 ?B_+t*Jc])BEGSgHHð0N-T6|uRT1~{c]Ƈ89RIQ~sB{̢d\I*i?ÞEXw>'y#|*KZKtd}3p /^9 ԯ+VOyWe,E\O wB @wg2*O>;.=S)iy}F@TC3 KīSQɺQhU[Ή*w$?È2S:v"1<Ox? 5SR&A 1<or{+;v4}( ;zd 7Y^@)U`/'KĎ~_m=s( k"tmݖ@38 eԯTwa~Go.<ՙcS:*n袖I튖/Vފ 8Cfo2(d!ҡsb9'h=0 01rm'y[ $!$r\)qYvf~z;>,׳päw$,%+:^{:u}reLjwB4LyHLM7.Zݸ@@D"9`ςxdž)uo~Wⱕ2:m INtH]y^/4UgRN8[؎R h̅<a| +۵5jx~UHL[}V}vwm֝ǖh^r| \qkW̜Dd78);ct9Dv|*JXC-|ըmmK +uտ Ώ^Kz憯~>v9VUsmS}">0r>o6^N}&k$Βyo]̍cN՚ܾ03m\+eV⣘=YMZLz3tXmm~0n=fڣ]?y ,.c NޙrF8I eePZ`:)zK{SRSb$1M+0IT՟w֞ wSP}KZ {Rlfu˼IhIlA} Kxڳ_O}ӁS~M7-eO9AqsbEM3w <e\A beA[Q Yu[}%.HsmMHr/rn=0ss`^똧|u=\?'K3S3ӟI2){eMk{eH~{,~[OeqQ~\ S4u.]n}4 9oKسğ ~ynYw͜rNSy}כ۹a PHinPNi(M$AUGo}G8Kڦt)Z4q9.vnwW- bqslm]XA A/jk>IТ;&wŝ $,etAݷ#%wqiG I])~Ś.ϑ+|:yhvMz|,U[ ^ajSM>zԂAT,NNyg].(&L/zt>~)}(t\l*]*>* ;oAN\ $1S ?ml),"/cd]}"~G+֢{ⷧ(yY]`X=1|K5cn?p|z)Z&|%1[=y4Yuf;fӗG}<GZ&MQƥ #+˷%k ٫I^`)D2R$.pݒYɇoR44ЙFTOengbz"Lq'_0C)K@|dP:o!"}fgizD}}1!奍͂7?yj; MKgr9՛bW{S¶@Q0JjSz(D ZK-9ztu%)NN̞z!(VTo}Lrf'~Y`OUv VA._h*18SוM"1Q7kůNp[,R+}Kһ+7Uu<9.4R>V)  =K/0W_;aa)|9<Ҝg> gNkUt|(,R%hU&2jxu= Wu~:h1V/%0SS'+GV$?BZ sX5-h;R)3 "ëٕiؾKֿ'QO`fF/9ViHk/R9DZ {\>]*jq^JÃ[*ATy&*XAy _WLHe֪zM1QӋ~C'psҬ) (cE)l8 =a[x,]:6YE;}Ãv[=ܐi5=i(E*SIxy3׶&^eNϏI Ԁx(t(sm43v*:-:Zxܙ 룓̭㪬 sVj'>Y{kɩy}?mܿE^Vf8*κ2 O9-4+wf>͔g_4}wxKMoRнG`o6<$hN䔴Eη^Xx;1#&?ڮgb i4ڶ0gY\uc3_`746_wȳfO(YSaTu`T'5_C˯nFbj)+-&M?(qo~i]ʿtVWzWz ˗![%+EQ|'^C i0{-~X)3*j@yVW٩*=OBf{l{sqwHu*\13GnmS-lV wLƤxVfLWNM4A-YKXt[og_`dlߵ1X{ٮWJi7҄b!+$o태\蹲tW ӏDbxQ ":VxUaלVM\^<{fx0 ןp$'{C|lWGֺYTgsЂ& 0#DTǍȹ^:n_͐Ա]ND|ү޳Ǣ1LGiNHs4N/&ѫcp٪WUzLHp]gj7@Ő!!y^v/;VʷI<³9:/aZwi)փO Di)G9*2&=BA4\ki4*\)s 8]TS[M<ĵ`J}7kzD`uޖ+ FƬf!kjxU9߇Va|trm,W(^ i^τ1*0$g.:fPD*!*/1hۥm{D. ,Xgpu2 ,> h{ߪz%W~*v'<شzɰeDCGB̒ A-e,KPt> <[Ύ F8AE2VJj\6/}sCdRKn pxDW±5զLt̝6KLN4`1}0E5]MsuP*ea :z()ݛٛm i¨YQ$(I:oZN+?ig%LјU%3*Ζb}Js$!\ NНw9,&m] WË^e▿)#u9P%10@Qd1~:)b7\Wl1⹔}9\/Q1WGh~u}.g'~8Ibyr>R^KN;NORBg[Z(m7{w<F_`;XiIB_ O^ w^N>ptzkZGGaoN. Q&3v`r]~2/5]RFbW&շHخi}_IKOuBPLF9|MgrMx+/sotIU>G6šȝ訄+quo.|.13~c-mU:D?A!tMZՌiezX^n~'Ig qnd6av&B k}i.8){Dz{~ʟWLND\~˰@M$l}oSli ׅ3ɮYYlbAImqilOj( WMM&1>1Nofvw e!_oy|'4Bv,ƭ_#>!$I'Yp}ݧ+^N;SX {7z! :Fk.ss>G+# 򄡰BAlc!FJIRNsDх(*=jD?9Ӆ@_Jn7UXW;/2ur\%pŹrZs"H9FA@.#CrvCV"ĉeLBP@stU?oE2ZfVV<$BqtV)Şv&8}nK۩p H^nBGlh^bj S3:(6Y+l%A$@B7t?؛OqN~;a)18޴xbf3t?9C'~GԢi 06=W~r~wͣ K ~3_eoo쉃H}?˷B>U?A׷[Ѹ%&;fu0U+~cbjh&mQώnz0a_3gq6u2ѱ}+7I8ʥ1Ň z+%{uL}xQ;8{M͎_ڱ j\ΰ>D^9ћ8&ux:WvP(7'g{qs!kSnhٮ#,ːmOBS ֭L?q22u&#ȦoU'x xtvh 2'%{#1֭HqK_i-k8x'YN}sfdZD8ˮ9܇*v*oPbT(_4}oAߚC#Y5Lsk^QF}\H$Y~bgLwOnTo?ѧQ ?#qX/L+ .LhOAtL '? rBjZrT_Sul[Knjnx` lj#O 1\>u>:3 j`${ԲAഽ)eUU)xγcB(Oil}/~'?X|\ѩ-_gXclBYdfϼ-ޠySRAb%>=b+ SxUeK@섺7r}BS _fDUBsCw;9 ֋LO7b́i0c|>4m^S@g_c۟|+<ʼ .HꡎJ(kZ~!1cfw ޿_ cc/#l!_tLaa<kS2ˇˋWbt}1 A-;J'OeQ)End:L3~ޕ'CV\Da:30o}-˰d^҅+'Z1%t)?;ItMJVB+;G i?H]5ٙ"}m?:z/ğxw}#l3=l:jhk)Cދl,0bOVRȱg׳6"~ԭ0@pa `iA[OsG~B Dk[hx74)+@@NhN:N.3LlZU(< y-En?oz;?0JM&Qi3-tly|ؾr9oOn9ؼnK)[|L}ϛʀtD+\Pp~ ~o]h퓌\e&M\Py|`54kS{uX#HcB$.O_N/4dij|o+͔^>w.,b}Y/z ol͎ѯ#ղQogWn8}_[/ (t KK7fâMW3tΥ32Q:Ѳ uR{Ub ڼ5?Վ͟CHŮA=ȝ$UY^^ySȉs~.b[?۱Dy+K grUkX+tx]dnu:{α w =T s{,MzMZ\ `C ;ַʩZV~'-Li3 >qjߓ{ͫի[uSMc2ROUѬZ܁XObs0-%fLqjN]d֛E?rs>6ohV1~`T\>@`f'A8.,ޯ8[;͢#S#J>Թ?~j%SG ZX?=B?17mRo,( ڷʾ7xעT׷T 0s. ڄ|K3_$HR.j ʢ-38Ag^qyݷnDF|d7 2᥍$ljk ak< K&rz?dӷ۾ru/%<~]T<|d(fk":o?Kg O k=OeB8Q`ܗY^t)WXٓ&0.K|uq$l~;mOY{];n di j.f&I'U;VޙOş?Wno6v/Iw£n#et$8Eb% 8mN_>%߷QOv؉WLC&f(!un51l}W oinJTXiN',e=8:)_TW ӳ>'GlC/\Mf3~17%52Bzh9K, J6?-%wZ>f8AMɋ*3̛}u 4S;F4fWsOja7叓ھRp{H١>vb§,z!Ghg6=1=<{-hb8kN]?ך}_X^M3WCQ \\J-A>-<8ou.ݲ-R2?jSBx;S\˸˧CL5|/բg\1;YI^W9ZRrL`pG`b۷^jW %^E%nZRz#~Hn :ӌ_ݔ'OMMYJtf2N@KqePIՑaHfԷ:! !xBFr={z52V-0y11;@Cp|Vv KQ~dlR^qBzʳ\oSbxfۋ{D7qzf#^Womgg9O{x6uz'm1YJI~_c S;\PȿyO|4ADKY̞0 1.5Rolӷyp92s'qXoaP|wɋ.rԿÖ+q9ՁvujwlgKlOuz*< / 2&ŒNOU|WW7xwЏ\늯G?TO98q=u.aIqqń`ӿV"1Z_:[["qv_w׀mi=,"9Ll͚)[#wc][MUϾ(r^} b].PGtYʼQϧ+jJ<_+KtvЍ@<1[g<[gwmn-ޗpcbOgL~Zފ ) u( >?jGf0ʃFn |6*\v)26о3DWD$Nm%>5&g)kR#i&F F0DwwzT!g\oo4MnWd!H!;Qt;fBt|&kd;/C) oԙL N ?@[ ,d55hA6&^y9ѩ{@( vgyYOdI"IuXf4 cPjĥo#@ (@'z!w4ja:ii2zuKU8$E &q;|rLT<-^  @%+yN ˊ7~|.aKԒA>q0#clhbFq ef!4ivwԌ(~:DJLbrW(IC r|^)> ÀCS5bfor$46dkޕls, ~mt "~\@@5h<~Kt0Ⱦb1.t @Kоc¦{ft0!/I7#n6>5sKW0RÈɾ&"Ms oQ\>t~kMpziP4Z5L&wcTKHܔqZ}u3f` _-A:ڱ 2>B3H 0PcԌkyFcS8Ƞ`z@(h >$I0PӃ;].]Xu*" 5qD] ~k'V "̢fڻ~)8EHD%O佭A-a\ e2\/pbmM`$afqvL >A }BRh ȥ4FM֫VA8r5egT2 D2đ;VNE@]ѼgF/[mto6_KvͣPP&q E i.FsCY2ȑȈ0?u*"%#FFuP] hTZY35>LRyd|Wx0w%o[y,%2 {M4pF%(hl1oi僰dSI qNJ a$ I'M' sĝT*)TS[)aʾ'F h$#_ctV^~7v̉ PٻaRcSi5- gԠx@y%a6}xpxOAb~qs8>BlJ+5?ZA}~ͯu=dzIR*Djl,ZGpPvJ% Jl~KU- +F"WӢ0}P7.C>A!*B8Łf0i?~!vJvs(*B55"Qj. ҽ5YE/,gH1 H򮲚ha +%| 'UnQ! &Zw?Ci!ۏq'Zޮ8;fd5ݟ(}bߦZnY{ھ9tJfQnbgVa@I;  i S܇yyxLjUm}S sˋtmΛҧ(g,aOy̞~ˢ oC F/S‘1_ TBΑ4+|rނ Գ(B^f7l^puTuq1(\[EQZo.֪(>#2r8WT4+X7ͺfQX{R}I|T[aLk2)K$ *k]h)UBp%!Ebn/2]c'/X~6y{.r TٚC2erjdƢwT݅vKn , YO fZ]T1drxImYPx|B\- sɗ 7^Ow[ϱ[V^Ȝٰ>+?)̷&ǃll[ySnj]k`Jʺ~akn`9RSȹd!?axW$>}jnJm;"# ߹+gJ}酤[~_VHةnM#,ZK-Ʊ/ K-Q1A4\KwnA jŃ[1遌=!23(([e~5JUϽ"^SROppmA/BnN6aVyP47Qyj9Og[+: 1E2<-nw/ܜ6lLCӧ R%1'7v+m sTž՗zneŢ9JYDx.*js3L SC9Sܲ8>1kKPvVZ !Qu]x&;/חWKOm._R|993X5םOEa}/o"s?us4| -\ynmi<56_)px13ҧQ9ʺ~!>\zFfu?!vzBx!$XNjy:{}S&G?rgN6hX-Y(y߳*ߺGߥy8(zܭ;$ʘ!ANIC#e.;;5o(woeBqQ]GCu]nJual?%m:m?d7O*}l#]`f%&V`; •B-)9Mوw91\/J{|s>kڂM:@[q923US13-!  &ś=|BXaX0uT7݊CUNnE_9̇G{E `ͻm0۹x"6n&aC# x¨ _p\54yz(/D)*Wy.QGFƹA<Ʊǚ0ͯ%)|@a6At9&<YjOJZ X]p'nTѧ1A} Anc(1Iؐ ezȼĵsNMO 4Q~a׽?O!xB e8BcޝNQ!o5Ꞝ$4ZY ]%5ِ~'0Jew4B \kS`UzCW&2&ְ `y 9%b^nC A`A(ߞI"!)Gz7Osä9>EiX̊;P _a|z7_ =4Zl~[7p24: BD2?Oc?d:p8 n9=fU1zwuuLO^s>ጰhH ؃/`8$ ! (kȤОCZ6scҩx|v%3]'ړ`rh^⻆(L漕؞b/0t0@=`_KgW P^GNC긻&YZպ^Ca*?pM+C{$,'+$u3Gh_WwoVDj<( ^zq"Mu ҡf|Q4GǸy8 }9}u>Pa>[wzT)ؚ-Gdís{QW{]g֎օ|4>WՔ} < GI~y ٹ+Wu.O%Js8Ks|m*:0(.uL{l*(N~7A2-Iښu+q*1!j.5BلS|]9Tg=voqy9m3nmiɈq)$Lp֒|M S>ѷR[A*+z3|7n=E<+xKi\뉜(/#7vyq^vo umjV:Du֟ &9,(Zmcں*mq%d"ٲS5\(8_oo-qضR zܨz/㜀t*V&Pw*-ɔL0;zBrvLYflյ6QT쨟{fĩ.BoӺ F`z[+ BOluB6TZmq੊j. Lvm>ҕcYwe2tJ=@x[kgޯ9Ezu]?폛sWΰ6YVGj^ny2Ԧ N=ʨ}]%FBbk:kgk!YCf ]ZСuCEIԿ&nux$@Xo;F: VG$/_5Gasax|'&SPk,Jsut _? 3ղF26n|%pdevݱ`ilΓx닊^EeIX<dzQ\ELT&7ǐ^ZZSR6tJޓiL.Ȗ7']Re&r8-mmY:#Oզy#e|ƅ*v/}]*#"WzEQJ~f^B)SxݬOњ![wG λDGs4=jׁEہ}ZΫttk4ITWٕorkwFL-5Oe d}8Vy+5+S,oGۍr+}1+s~#%2y!aʴ)ѴDAڰ|4߮_S%|2x#fJ^sye:/y~R ?m5-!K.`*Eқv(s̪P2o&ShEWѾ s +St{àxHQp ,纠tZd'61flWv=O\EЙ2_~V󈌳Ghy`J~סw"qE( '6gzQRZxgTռb#w-WjXBΖ.nl\؟OB}eDO~ѨE/dzf>ث10J')Rj'c4+WjDXZPN3)ےe)!lK{䮟w;ԺezDkS;FW՟aKHxV{Ą'ٛ pA.n*w,8S+z\c.lhk6> \t9sh$uz;J 6Zyyrf=D+edb6lBv; 54a`aJEPV3Θ7FRY00 Zp>J^ITgt)}:#t&Sw-865bg>ZHh}R5V?I+M{4]p 4*}n|Tl$xex4χs/mC,`otVط^?V58i/~lU̪nfvf"ޡJvY@T4`׿gFAQIR:z-@o܃{lXNkdT245۳pLNyW`ϳ:3=oᆆ̺WxZae~GNUu%X~7ܘ -[쇐G1F?0wܜ>>Gs#&2\ֱf;ooy˾md^fҮ:u˿Aقw( Dg >w7^eMF?? ΛJ3tx@ $grJF֥%]Z@ tAZC )3*&5džfGMihW;\FnwGv|o% CrTej@mWZF 7Be89nAXt7^4ixУ)eUOy5t1^zW Tw&JvGi4*BnY~jMn'tH~~ww54}^Fe"H˯x5ab}so:]X/T')|SonV/ضJ% @Yr,o0Q|ܓ|,&Wةݾx}9 {i 430XL,gz*ҿqX KRģH0WErdx3 k>fpym+~-^Tt #'T'$;+}"0v )d.F~rZ߽rSqk}:}f9@{֒+k9P\e0U?&VocoWx @t2[Zz:gxxk[ܕe_jҋAwRfj?=X:pe"`ءe^UAD,mqMb×˒2EYo@VR-o)hx_/Ŵ˗^zj|HݰTMYYTOiBiq,Sy_2K4'g{ߗt?Z¤m 8+G15ο:%Z^S1v;>O tN>R区W~,Λw1mJ6v󞺖)<*/PoAٲL22bC"ha@MΤ2'Bgm:\9|-޿fU[u'نW]diн\<w69M8YrPؖViQqq97kJ^?LSqFqBӾrOotk\٠)mo:. 'Su3P=szK@[(Y[ٹ '!_ -^3m{!=Z/#^9EhhgBְ5~W2(bz, q)993?Udnb{NȰA-پRJ/y[O_0e,sj;?]&ɛEtWYc MjԶD3? 1o]"z .]DP_˅_Qּ~Lto5v! Q%z퓭ke nمN2d M-&fATY\:Y-w@*zϵi| h ĊxI4/:4w×<"BƮ"ds0=:;jKHxvؐwC1{㕎Cj&΀ڊ9Boj]֬۱o-=5F7CۉJ1~d^~}_ukWQ"t#?ԿF5@2>_4rU!Z76|R &?f{MfTMqem'>H)W'j({|o3f'S95[> wކ-mV"Ue֧۟7x 3v&[I}9H7`xQ`]z[CS ":HX}'>%ZO3;uJ;mUqDYBHR>1v,$_߶ðP-)R̾Yڌ>WNzq͠.] bsoQc/;+kqYDBf<"6gu,yɐ٫aG8VYHع~ds\n̗pp}cz<\zfx 3 w X"p% 1\[*?^e >C;.du*+{+]Mō2iN%NBL4EQBgQbU*}JbF] Z(`kT:=”]pd~k3uH=Q}y8jY Zne37#bG7VqIOAt(xхl6 ž|@_\صVL{zҭ nӀ0>!`#U6dVImY)XZZ[>\Z(DՙR#<*<4uzȸ@HG#Iz}*O֭A5 8+M6n^{7СuuPŸMxl/!#Pm/=:j>T&u]ipf}Ǥ-QQ.X{sl1$s31 O@X낞.bղ.+?z6fe[ۓEۿ{ߧ e}d輓~n?U?FY:]C_F:GwmO)#= ZZ]BYoCA"f;:k1kw\G:n<0&xxnl О.3'u{v`1SsMӺZ\kGsnA'"Qѹ0 y|s*W\kJ5\C}M1rYpMDq Bhc_uͿ} 4Ž.em[3{^v+׳40"n北ս<ƹo t3NmKtJ gYn]B ~p2&衉T" gw;lβoy,'03AW˺4(.IV(,upu wC ƙ,p@Ԅ;˦OiU7hzwͦדo[ iQˇi ?I@>2;lqv၅FQ9Dڲᵃٴg&JfXݝg9/9ᶃ/+%nQXvO?`u\;s{мFC!K7*oVg.y=x̽L3NFW3jjy?EA4ZFj-SW*/6 nQؼ|td݂;nB^ ˅ZS%W7kĶaADPC^)v $I\QћMC[qv0BqV{-9,}3Ũ y ݸP'9:q㬊cbuG0|-9+nWZ)0 ׌\k>jPW*8tB0O4xqĤqcwl7QS-ok4瘅p4‡!FRxJw+z٘9>m?U,(j3_,^c^3q/6gw~ϷB_ԉYHIr#uRYmw/1,?7+yz*7I6 5A e-cWQ(31cOaGfA GxP:1U~5%ݮ~W/omcegٟ0Z]⎡-"9 |t^ j}:gŕa"yk f!kO"̌9bl/:,ݎwS?goLN%..T,Opkhgi;ҁЌ4Lҍ&f\re\2῭f(R SC~.Sa==*[X[VR `dߣox'u~U%4#Fm79D{D]jynlpQsҤʙ׳M 7:*Ǯ @cOQ#ݭf LMfJ`.-},Qt7;̥2"͕P.tc1{ԛbR@l@iσ3r_ga diӚr LF% ⁷Ԃ㛯kb߭:܏%J~^h( ʏDžﲏʘ6>!-p:m}Bu߰> 颒a牮苍Ϛ[}Vw9y6@?9#V=mn!vUӎ]^lk,eh9ML8C0szl]xr{mhx*h#mγOZ; ?>-Y1JmenS# Xz0|H,''ݘE:Q-ww޳@-G̑P TL T`Quu#iMs~˗<;喺7OY]vhYq`0:4|xOGm'cobmM7N3gOw]ho3ol+;Z a0<\U"\zp42 [B0c>G[?sM7zZSi~ꝶ:JǷxji>̘ws@BmD蒽y{NS[F _aR^XNqcCS۷R,-Uzur {\^vp[o`]9_mo>֙el 1,JX^RϢH q\Ǡ$NoCo k  iV\;%\͗=X[\=S:W ӐKdJO#2N{)0aGFRzf/C5TFڙr"lS6>ЯLCՏAM<*+dd?kg?9/y&<-=ڋ裇>f峅:5.8ge|ҊN:OZحnb%9Ȼ·_:%VK{2Α9+ .[˚ȗhG!zw7w5?"a/wF9A~%egDKւ ŷ΅kE{:+:[Ng/zǯ+S)`Qf.E/kc_hIGW 7qI%ðIk WHמXvRf0r4CZ} ̬Ra^rygt}8T6vaυ~GONG}^.w\uǣy6 :2Òv0޴JeOqw;&zmΤbCm|l5D_=Œ{{.81<;D@ 06OjH6HtݲlkǑq{ނߢ}@b*FsRQxi%5ngrYǗ~憐6Xۮ3N5/N=؞Lf.Kmf^ƄC沼x{EC8G fGa\c'~#3vsuifϙm!`" V'ʩuqqo@Zar-6(`ˤq+S,֮uWf~:oI0YV!=WNo}+%[˴ݼN8ذ)sLɧ|jɤ<|FIk0s5:^ߚDTϠ̲ڷyۣ-d}39?"arg<{zˊaǃQXPmzɞc6zz¡O`4I"z+)MޙJví}߲Gx減}DjQ\\eq~&Psv(뿃٫Ep]>wŴx5;YWy82Jf_Mm5рMmdHz58%8? t-V͈5;xF̍Y­z5c +N 8޵ (6zĥ JW &^݉Cfi9)PhK? "XOwqNd^=tU#A+|<2/ҨSyt#F ItrH.Mw=iu#Òbs oSU3tfpq0 i@.v ;Q?b["ԛ]<\ 6(TS,B~Eq IFxJOlF*)7'E{alXmtvϞDUfed}9/uo TK{^uE.$OAw˷8e?E^7X˗IZhrv8gQ;Tt'h{)c:1޿q5JvfNSƀFmyk؁}@k_Iįy"މVsuR_/++b}V)?2#RNҚ)?>X y:^Kr74+j7k&_Ma@w[]&[Up5Zg>ߴ(V.;H^[ l6^ԞP9/p LHBC`Hq WII$HI$I@qL$C]`mH9$bI&ad/L2 I`H@Xp$ jtR8sLTZ:;| %Wt$3EJF{|{~$BZC 2m[:c O6"5@"PY0j~-iퟂ]|W@4&M+Ì M7;Tw]J 9?4lSȫ%X~rr>twɆkgUJm;(^H})zUE>fZ>frD[?z 7]u@}W3@m) ny.>]AZne{C'dڬrdb'eN>_&HWq%bX{b̵t%o& |W=ܺpn%HaOβHv-Xn#LJvySH%Knu{#qvsu~ӊpn?>(<ῧ\[^VRm1T*{-zrVv"oн+vX_dL|aZkJl^6m$>Ոixwטsp7L!W.~޹a8l΀F=nt4ޘV;(bl7^*4l14ԠAlAF\鉣V֛3kzMMz=ߟ9(^o:KT{-ʞ됽 ۢ} j?\ &\ %A-w#1Ku]d2rW_v09; u?wNP^~TZ7q:osm,ܯ|l^ŤI>zЮ<'v+qȏ=Xw%A LkM$bkt>1 lV?Yu;|וmUK;=}W1^if)PRq˺td״v h'&zgei;Rn21^y8puT}ԙ'߽P9&/ˎWU LY#xE}6fF˨5Xpnm~K4-)SBcR\`^w5 <-&bi"Is.bBy,=7vSt16<'/o)䄟GhhA/ xRv gգ{LV8I_B9Uُ4Ψh" N b*gsqou!:X%_]eq^'6￰7]&I?U`n-~sv}WO@#/ݺCV]ayPj|8:ޣTSyvѣOC,g:nk/*q(cr|7wVq?;h4p2uW@>M|JV/npvjn`&kg~~N,3lxV!lusk V)R>UH/ڋwZQp7;+dTaEL2J2qJjKz{ OOv;SaERPVP;?/ٷ,V57a{<ҤLTձ}EQji}E72RC,][ysoتj͚=k%!ۂQ&4%/i7Hsm!.yjܶX>YU(vC|Rz#*/]3P/eڷ{륨6~ɚg8e+;o7L̗3I4nR H|<0q%OxkwRN0}lsQ3-Rbʊ]KRPW={Dכ/M(s{E%qQJ&)2mˀm)iۏvO:\B aߩ۬B[qYxd>%U"K+7m=Z -Cu+5- T_g?8)xh7ͤ* eւJQߐ[BkqŞWtzl^)=^[u,u-Wbc9'~Ƥnvhdht; pAwdYF\ "j-?t@x5huYSÌ ).>QvxlM2zt7a0J2yg:w#y;~7AV䷖KУNePs3- ݫ9@9׹__)8r`HV}v]gooV_Ey4A,7•U92vׅ9`HO[G-=m-xUO"]pHkUs"^8LV;slOO>1cVMҦL !.{ :96[(dʌY#Z9G[y w-ͪmS)NM= Fz62SCBv8(=G`!q!Z";ZGW5㛪ojrd?p_yv7P<6-:uw1saPi:v5)^I℣LGyeRvlBª) ;Ϻwuy(؋ժ9堭r獵*k@ %u9:j T_ ԮKc%)sHel<۷QJ_%"pޭ4=ߚ4tG*%f`g,gvL,kXVt&ꋔl-S' Y2:fҵ6ZDn{ER:ʹ<ɴφTQ`=sKDCMt>Yv 8Cn Gٹ(mX??OIzhJ#$?&g{U.'. G ܻz{,:ɶ[9:e&y iyS|ʥKŮ>"W.!5^Һ '7žtIFg|g엍1=N.r\"U% 5Ȏ]n:y<ҲާRmNǚnEpR"3;+4ՉSB's3|B/u_\-`\(]%.aNM+aYDF:ajM!{~szV9u5I/n8r GeD1Sz} =gs^.|'杹=,}WD63mfG6CuEke뿏nɻ-G1Tv_|qMBRz0-w˼c\^ YsO:A탗vuPe2E]n+ 4=h"P7rElC4̻1I;F/iPW>A?6Vvii* 'ⵠ9Vy+>si rsy(6ar&Kb aRxMe9R|LZ/7@M*=v?_Jdêkm7o}ٗ'Ę6דtfV27~w?T {:ݗ򯣣8T4&ƙ؋Ρc%"q҉=i shLt4zfj{Ϫq6?ES)^1bIMaޱye7!mꏬ@A2r"Na 1ō60|t4qϐ3Yja7Θ Pâ2 ]F ^榆 :Eo9cGoWr Go")ßޟY~0 ՈqI<2L9" P39F y1$<m0to:Hfl:'Y[ Uf#XᏱOinbJd,[hWM⫞mⷑ<~̖u_ݿg\((o" "a7:0ԫ'ޯ``o@{{} 2xh滷].=fI\#I\wL?Dh:F]ATgX,a鸼R~ ,{q}1USlRR/ ]Z= %`>Qzznh z\0ջʯ7I sM.}ò/w% G~jH`\K")fѸNƻHt0uپ: KH, mY)#14{W1%h5em]SR`⒂ YN@XLIc'"z L #O>Rdrbk^K)68mIs8­ecv k7e"|KKOET^z/td H!‹>o뜮YJ\'>a"۴-]A_ ZBrLȎ6v˷{mz|f|mg10ǂϙߔ|hw4hg|b%%]qg~EgKleL[: uS#.d5{'=DwҜ6ى99bo6nw힇N:45>{ž:swO-fY/~x4 U')St^ /PR>n-Ae)rcA^vʹ)h% CP'0Ll~˫&2jwNr5ޛJ%a`ܗ c̊va d0apQ}V.)M!U6o.[HӇf9S(Zblӳ҇3uhy np6}ԋ__0xGySԃ_uUn-{m΋3Aa$=S9(KF iUa1Mt/ vذjs m_8ip$so'7HБ&%QI: [GM旲c-փb_ck~LkXFCP!v .g%<?bZ"CȝZ5pYEj%g+C w?;]L{W[A9S6Zdhp`D5< "ߞs>l4 97[獼MN04'ˀ)+f $Yp{CuM":>}G6nuBQ-⣍mE=1_`|W=K!.*y[s|k{N5/%]NXr;1VzyX 5M-$Iwl7/Vmnoq1wy&n%yr3P9Boe*|ɺ ZvwuԖwrY Y"1psv20Ax\FB<ӆP+QZǕV'Mu:䈑0OxvJQk啉sI6_B~ LGg ӱzw !Ϊ$b`!LSZY3bN!3{P0!J#x׮2}F Ѓ'HYWϮ4m\oS[q7gz9z< *c ˡD+f1Bv =xP}ER@x%*u^(VwE̎ gLt 00Wf(\pQaIx+l["@0/90(w5Kb/g<ͪғ%osf1[Dzs#;̴L^ 1?^p G,~ڌB E|+Eh fəlrƱƄ_n<;L_l ,$d2V,S[ť.2) E`88eH*i ʱ^\S>!L7 @yΒ1ç~TjnQ.2FY`<$|a}0ݦ؟3v&kc[/o4N3M >V+J'-Mg R8R;n%Z7b_ ;io~Yťܥ/]y/pהF~ K4ǡ%0 eq}2G3xnKl,i N ĎP╒sbFG{Wu-> U%<DTzt?08AlAƃQMp5Vzς_MoMic/ݏu?ay 9[MdSWtt["<.yߡy*jq9ھ,Q[['P*Y; i01E0Eei~[Um~s"8KcQj%k%gPF-u" A,hCi2P&|@à>S?HI HW NP'-)PS@[Ml1#H|X`8E9hDҏ:A;Axb=W!XL)4w߷BxUgµ6䑽V 8V,D8ȟk_nc~}.C)_Ԋm5.\+J4%lT%<`UH^`p@tǹ.PWz9vtRJ0B' :z'τ^[vXu넣, c|/` ;V/V(59)uYDbGW&h@vf˴am:'v{=\ɰ?n_C 3n;<D8|cA“J9gĆ-/P(]Mn9MWPn:6Oi *}=Qڒ'qć3nR|Wq<x(= =Vziuf{reLڠr|b, O>&@O=ds֮ +42X$BMf!/aM+kW"gQp=Oi^.31 Dy#'S*K8 룊=s=Y2NҜTw2 V|\a 3[dj-V&LLBs^Pfe R_e > H@(LVҷ"toD>5X =FF>GSu߬$: tB@ 0UF@7ц8o" <# clh1 Kzr]ۨ ƨ_UN(TV`i8iFy@)_|?zgL]l YAd /.$dw4|lyH8_xXG qA&TnPZ D>yˇ_50IKݠtQ+sGilb$QH.Lt7֑`y#A p'X{ aKao4ðj*.rEQO@t0"h@gp}\bHpO4GesDžլ*FQ::rawH0t6BRq_Y! ڜ/ 1RpOA/07H[3nbnq.cEӿ>d yJq#pB†(0ylJ]*0PqT@~9n)uP ah^NaJRd9_*PLrX0OOR6Zzt1BIuh8ţj?ӠPj6> l:1#EDNXH^]AP: !bM\8ǵ^51Hڛ,Ѣ0=8ԄzSq|W).|y 6yo>gc  ^oy/!Ii==By#K2}Z" o}Cyp(W"PfX& A^oЯHJ^GʦAX\w'P 82'"V!kGZ[ lIQJq^K ܟΑmW>VAxO[L}!\NE%~؈A5J%B4O1WiWp _;C 21%z#_>hu#+RDO&IοқLɘ|릥P^1-mz~ٿ&q+#ۭ\z-+pHA eA/r <@mRfOMTdH+ŵt{Ε~u$m8@sg{IMIh]l<ީG9.NϢHπhdFaG4VdP\b[Ǫ*w̦,K1j\k?8:|B ",5L x ۙBy|rp=6x>yOѦ,>A5ϵEH$5(/{LF^:JaԠfE4(,2 `VE_EnwgVgO,7jf0; A;5nʷбޖUTI,/@Dv-E1d'"ˬ^L.5K99 !\کpK>&t-li$^R+jSxi2a{s=Kv7d݅1ȡ:dsdHVlSؤװק6R{6*|>brt:73_PO#pKZϿS}{pkԡ8"bwpxi\i,ǗviĢzUz/|Dth l*inaA]8 I5kj%#E3PvJ#/ol) 'tF^X3bSHUhayt\!bL!kK/-F̋]5hSUf (Y!a )@Dā`b~o!5 +\m GvTJyÞ8 U% >wR!8 0a>Sg0VPDZU7Cn&o{WL%G ^[h8;o"9dxGL.(`A$ ` \wt/UJE__y@l@L]X1}̒5%gWA.(o/TrEp=|6&/Ǚ/v)z:IjQxꙀeh"݆b^:JۉIPk>aU}Q*y!;rl@P{F&$#^,f2"bPoZ5p%^FY5+$S 7TY-'cLj}WՇ;+fIBm*TL?]I$yTL QH鲌#7A& ^XoV>L+i؍U9A^&*aQu<r4d^A!lluq֖|>Y {!a?B{l\{h  1|dy z0liB汐̼ȸ3+)e ?ݭ( Xw !ZW?Qʜ]}e%E&Hj 2y6G^v Qn= *OCWO6⌎m#Qk{?$t~-?ڳ^Rb$ |V@ :-s4>|3 U&|UBgJMl!o3dܬ.ǬGG%VV On0N%v^Ug*-| i3yvL|o]-xn:7y&S|^${;KŪ8TB  M!m#U^G hRA}рqkc%bNɅVgq[V~vS BXP @ Iw/Yŗkjw+CіECQBzFnTW4'ʎ\ŵ'm ]r@r^GHd&uDjFIFep:e7_l݊jI%64i!Y>#P@R8I;o3-- ٩4\wjQ蟙 7K14He dQ뭺`ƥ&%-vQPnB)͈Tyu*]iњ!8l׽E+g``&t0KeaÒ@K&IyN1S~5cMv1iJ2H& ZmY27LMOߞgkzgU0#;⫰<~PlMwiN}" CN̑J{};[K"b7B0/K`eiˀ/srl=f;ޡ_`nǙ,Z]&l5Y @xB$.X|yn'WYGgw আPgF8Jƽ Jd[*--w3BsMrw`u6p@q$cdÌ 8}F& d|aHszRzXb WUZ;$^LVD}n@?|Nz 4"v:qٰQ΂h=.U9F1Y?R~OZ3C$D$}_BS$gDcK.e DGܒ$X8w뽯גQ}(\ iq3wUd'!kwC :GrLroQ~Uy8/*k!L y[يA>1 nymܹ[i`ja>pqk6yjz⟥n̪(r" Mb-n~f<>雗͐rH80X@dz'Np^_n:`2."}=iVk0d/åy[Kq' #Hmv4 h1`BFXuz|4tNY *o2x]Li v]]%. \@)MH G' @΂C ?8%&/l£7(SD(oJi );RIe $Aɠ:!Ē#¡R=5 -[QU Z{5//3lN+x,tÊI`l=t$fx@ $U[-oԠ!BJlF]Uj].)D$L e~i (/9РLRnfI0NWѐIRǿDk8ed÷5=Za ?I[( ይ>j}\{%孙 D5$FD/@/@B3n8/O}E|-gZ*4^,V[O1j@:WX1$h,ajlh:=YL=hm"xC]p!sK#,W殉p$ӥ"^ÇDPl_HieSLߌw^/Z ^O+~N##z3zfw%3J""{6S@HD}.C&CLeA݌9cBjy! %;"c`^(6r7 1s8{Ȅoz<jq& 4s*jc`oѼ(DH$'D@E!.Evc ratZsˇSLrVSDqufx/@tƇ{(;77 <\Ln22Ma]0[fh<{5Hbk3N~)ܚ!|:.h_h$'5$D F 20#v%qE-K=èT:&Ъ !'&Ǿ8 b xB'zH\A$j\eSPN *W$}ăk sJ>'tIczCB,r)\wAU73efc1Z!G""$5a5, YZTAРpӏlvV< O:гZ$1Xʐu8Uzj?iNrleVC ϠJ+0wb[ \WP]([D] -OqNT&I0p!u#6ABx(3a P2# \4jN 0wk=k2;OK>'ҪE !$8_rb`~ RC{>=N""dl%KbxoM5j]E @Q_"~jEP@ܜlF X`maZ莄|)"_3dWA{WhUA酀>)C-aKာA6ʵS˱'Zk1SNUL{efE'ڡYw a# Mz؂0od=ISvWBVBjHj"dW9y& V) niGxtXB\%¡ GlGď~` au,BzZjt1ׅee\x3?[7)n.0e%HWD`GU> P.Ğ.]h VGpLِ]TB0\x/%Py,(BѐߙY($H$ F5 a|ws[iCA،74㞩t~tBTw<A]j0'  ZHvߎwY1:e6/GَQM&MR(~qrQcOܻQ58p7L沩 ~OHQ;e (2)THDx QN5Gq`D!n'!ry>ŠZ}yV6fvkNsm%/ 󧻞EG6ѡAyc* Cm!y9҅Q5]!ۭF[vJe7E%g"~ۍ'G:ՉS]7`pfv'';uĎ f`ul >sB,d4fj/^e&#s3*I~ZYpd?ޙѐSܭZ)ǎ۟Awyaj^՝Ol&/0<&*YA-BH4# +F̬DtkN0L߈-$'k !.x&77.8S/1iwqd&at3Bt7:kf4SH!^w,LmQ粭30H~\5d|=cp^:n 9H2BTm?SfR.%aR7K0?BL{X3M:' |_[F9äǯ_E(|Vیk|/U{XWқ2TS*Or?`V8 )`ܡB|f#X1rLt8I>0d/>aM2*0IrM?} KXY[ɋO ߨA'`f>`MAu*yoo7ϳKeњy1?%M>Q_頂]sn7ߪMlf FH{l {uO!#<uV4(x99 # 8V|IK?F1bzd^ m"}+ls/ȝ%:(+x9TE?FsET2HMVP@{(!iˑGSy P#E#=9XZ>nEi֍%c>(^-{m?PҧHF{MNԹ1-V?o,A=+b)&g !ՇJ.|p#.svhаQWA"`2a#2; }?(=1f|J~29< 0 >8xOO}``o/z+u| eJZՐ3l?Z89#<~R V A.0yjyӻ6T:~CXu\AC>zwP&P~i;nqE>I`a3~ԸQݵaY*H:Ϳ !7?%[f%G#@@+v ^KWOq ?:9kŸ47ktq֩ߣFF{0 F\(*n> * 5 x/7, mm]"idG;K}&YbOf8($EB̮8)lwc޴9v0G[PK8O*?K!doyZM6shl%[AE53bw ($ƈb[&H N hjj#Z.V ~5j7qyJھNJK`{v˗,}@:ޝiS/Iz]Q9y1 LO+kɽL"2" 265[V\zYcH@ba7?z\ n2^#Q`F,cLixAh=̿]_(n7=KӝFd@j maLQ?|N%]dvh9n︅ ՚!p?n < U%({BF/LDÎ t#U%ۮ󙭈%fDBo9o2w/fB҄hMlDX 2i"}lz.mB& a>v,ee2rD}%9' YkCix)ńZ}˪ې MN?6VnO6vpiQє7x ˘ 쓥}^[[/iHoo&q?a8Өֶ5}8R+B3Pݘ 3}\|W%Rg)ps=͝xƴ3sA ̕Po Z|%v#Jٞ?ԅQV=w^2N4Yy%qτ{BN*OU /NM_ ؄2HrZţ$> ZjNIb}Id'釱,H΢xSgB\$yQo d PR\O7`P53k}Nn*0z'lI$ڽ"_ضKek HIړ/oY$E~?y+Wx%\YU͉X%$6c"@y ~a ޲8?8yI B< ;y 3. [*Uᑙ9ҽ2E;OIGtRb2-_m5dl2!6;W5,H)1O$1!vi0 vEtϹH6Z:[(^_\ :?td=Y=O!@HkjdDϽ #,v;{MQx؎v9t;Dj} 򁛩րa/Wcqt  IuK ;veg2(hhDXsxs8 7gq7WQZ$XVd;,Z?FяjADY,"1gpwSPkD0Aĭ0rbߥVg3*T}`wmU5YU0dX=Qaq8JH3~%+yݨLw`'`>-j wn&%hS)O+Y,ql_^p2Ĩv Gz:{eS{e9"͓Nr166*^ Ѷ(H4;+?_ZҸ"yæN#Գ`{U ~Z3 =_4AQ ZQj[7 [;@dg K*Es=AEn%ak?#w0A4ǣq Xt !("hǕ$0Xݳ:;Ҿ1 -u#qq?6v<(\˚؝(6)R!i03Ϛ~4EMiЁk0@;Aw@ymf. gA;`͞RߴFOk.FgIDVi*ޯaQv L *FK$!0d2&f_h_@ޝ)q%`/4$x9<e?GYenJtr$g'IV׼JReXka%JbT a_#AV ӂ&f@J~،Ӥy = t"䉪,+ nt6ՎT2#7V;'s]CWS t=`AwOb 0ojM'w/vWMf@2%&Yұrj4N~o5Zb8 xv>H{ Y*P[Un8:7g|^_u>QffZ{|pB] Οu|]z#G⺑g}}?sv&p+- gQ ;$JC?*zMAj\r "_whZx_/ sθ,{2xKm`ecѠ٤=\IcCyE`#[敩z|~q(;Yz6xo *pQ*J֑NYdMeM-:;{70aWGq 9(|=/^? W}.JxtaVk{Ѿ~UL3qG ȝ5 e5]#v^}`7}"KZ.U8rn/?c'C$=ΕDea oͮJG-Zso[x\y&6(#i;SԢv-P_M.#mm{B{X̂n$C,%Ok295CVݗ1-w~?hA4˜0Їprb͔$qk"ːis]J͂zqw ;L]#.Z՗ {RޟBjw89,4\/Gݢc`=o,7tH gO?wG* _ڶ[v-FikXu9yY҂N$f_ SeUyM\@|sd$Y<=f;d+Ԭ<A[Φ uq- ǭ=NIUAjw+ihv-Q&uή_Ջx tM [x 2)&C\Jl"-ܖ{&w:swSZ{BXbzJdpIxHwV;%1 iGwz1 rfզFK ]e85ԋFJ-C>lW`ʆu"AԷqhM+"}Ƹ7ʏG쟖Mܺ*çUywE@6sۍ]i_הO}"0T.qY(wg͵Xz1i/0t' ~Er滈F ~ݮNƽڃo.+, 8> kvNƉbZ$ vXhdܹ73B\_d[5=2ź6|"sKL"ոHS fE%KYO/_ ]sq-vI 5Jy= co msD͹c 0&QRE9s&PQ؋v[N bPm,UV 0ɹA:eo-/2y9VB=$Aml_Ff|^wm=[]L3hmѝO0GߑOWW)<;}Gz8?\Zs#s: U>{j`ٺ.vHFu/ɞ~jLyM>/jm_ȯp#LM}I'ͲF jϲJvfV+C"['nOk'8=iWޘA_ ZCrq^ (xN``(4CIȃEK;y|.{:kr+5;?lE5~AaO,MB9 %v2j*4f_~$ck/ə~A׼ŜN(v&'ɫ1٬^֗i^zWm#V2K~;/`AGj&%Y}1%w r_L^m/YӾd9aį82\Nwk(7˾ʡHr.댽TV%wgD(:hP>)\zR s041ӌ7Hv&6ֆەwQ-\- ۬`>zԆJ$ sE2!y3_`v6V=}Q4AqQ:b< A! nKIˏŻ\|Xqˆд^j5,O_iA'^Sn?B#Wwa|zTg/6@usEǭ˙>wFIicۥ[cǕ57^<ü])^ !:*YD6Eq?:`P:ǠpZhBHKȃ?'x_E̪Z#|qB'V,'MSC)Ya\ҿrvڽEb"  %ˑn_5$qtپ;u[-2/冻([wWtTipII,^ k k [O?hǎɆƱiq:0'9 dcJxdZgĥy\p@<_D"z3x[BT3&?&Myh6.Țj:L6jcO!9ԅWg~~ȟ^B-&ueHHmGj+[|V/6A^Ho`{HѕʟӘ, (*M{γA-I${QP `;v<@`0H4pW%5vulpUiLسe- P.ghLkM@Ȣ\OEWNGr{{݊p ~s.3\/!4flY_'s/ɈZЋޒZ{qyQSǺ_8N|/\yEH?Q5zagU2rG)eDh\^H HٓoJQ]d.}F`!􃚻y ,`:[zB8)B횵,q;NJ5gHbTeGpǒIKȶgyԷ[ؿ?:KdB-aĨB~xOdInԈ6Q"DPq (29iŶlߑ ~m! 7~ -@Me`c_x7f `a6ܘݷ |!?w%^XW&]U&o]jpKp|D\{sErOUqꑺ$"fKb)6FDh'~S֜~`z s CRW<3-JQ4fA} bZzJ9~yq}+4v.ۇ`D6PG/sQȧ9mWru@fJX`hA-~ 6aɏL(K'&"-\D  &3"^#PVk) 3 b{[ "^trյd. LYrLң8r|FPsEA~BV8Dtr}'[G-9cyvLf^!oQP ieHOݐ f90zojwjnyߍZ3PXA,0$j$ng&]W򨄱I5Sloԭ;W9xˀQ ڑ@A?sacqlΔgW`։`xE^_|LرJiN֜YxX-|2vfӾ}"|3n+b]=G ׺}ǝN~lQG#*+:9% Z2>2T$UkK5!c|q:?ynoC(s͡ :=DiC"^(ΩjFhPfd}&~Qa1tTlxfyr;$<זY# G,1}-_?3)AQ ٪iLGڧ[bGޔk>6VfVKqo4d;,x`78|˧?NXc+=[2coLEg4_!7iI4~|{'ȐZ\1([J 4z /CfXe㢡nX7^DP^}Q Qp«vU>2 B۠r>6n,+5xA ppntoT?+s W#pF- ~PAVE/\Y|&#e)=E\8O@w")=X2}d ;Liy1xUr'ѵ\vED e7nK0 LN޾ĶGD~\NYzc8VB H;gP![7 _M~:Nu܉LZ3Eo/A `YJ;S,(:yI-'|hgJ#x-Q\\Pg%t|l( 3d"vO cXGl[4 zy d^G !Iq }3E _,8ID%{6I.m| '=F6?Ճn8=+HI{anu ++A0F.o`6ajǰ}_ W\hr 62F_3-,re0$!hN|?w(eݶpKx rx恵[s~>K'$@#7C8,DydUo*K1ʈ&%ZEf0$c{D5K McndLZ7odl2Cp5w\Y<]􁎷}f72髻IL>bjHL`(#R%O-y{RjgjsPPTUC1sϫ́Y XvmD>ILX~I=cDry-A&(}ӍD8qᔋ-}+[==yc^/YYGv".E.kgK1g DkON'.0"8!d<뺛=|d88fx#-D6<}K"ΒS螄dfQ z?ty!u(Պ+iv'Qq+sIcTm7# 띿cEִy.?vQ@UH)~G_o_qS gzAaRu]TVPaJ(כThqOd $wT#Zt;+ґ»rj:20rҌ={1K &K5yt;[3vI73Ai"wjiR^&)Vj>@7Ό$/!=v9Ud#vS 5%DD p{0swm8IC LgԷEF]= lܐR,5ZUͤmӇ[a Dbϓ4ΨT L[V/MқI@&4{A^ḙyg&ѷAVj-f%zE7Q36fI[M XqI.u KSkeR-G wK};wXѭZ~xRF,=dqEB4%)H}kOv+iK} V-zOwcov1-\0]L 7K((tK# H \?ݡOu{ "a)7 H9k}9ydL@( FrFY )O~/(w@ќtr*hVÇUj0w/gta?]ָsH;(L;+T[^Vp|^zw,vfoisNΪf=.?  D5V'JpvuN<[mmJhc$[Fc 絧uDA-žsI}T@ב)jX0n__=n}o^+%u5@r%Izv^dΞ&O"pAT cx;6.=17\$T! 6f!?]mQS%??挠[t#ϖ05O |W6CK zwbSҹ3$Vmp⣚~Ӗ!'P%BZuE .}CEm2 xhE፿΅$?V~o8ӗ LjCY]$T\q>F?{Вl$jMsNQ^v8CSk{ʌ084Yڟ1;ՎY.^%*FKvS nln` H !u} NP¡j6GhLn?Bqw`:A k.fsyrGi"v;K01>d?(d_frv;½gJQ_"@aaL|ψ4HdWtcB҄a"a_?{l7pL@NAT-Va+nԛ|H< n|Q@o),#CiFD'/Z!!m5t9]VjM52YUaD&5$I,@@͒f O䁁zF @0g%yaAmeJS6xɓ^|teL %QHZz.!.j ' =l?G^{l,nnFHE]lz{q_v6 Ou. 7^ K?ه}^ 7^RujL1{QO~Ꞧfqm&ЙORpt;O>)4coL !Dy `Ov8KǸܫ\wrvbZ/8O5Cڹ0s&A-nj CH#y!d @偱x(;&S7 K;1 v/80:d̳CVpd/{Miz>d5ٹ 0yLJdPf8CN) q_qi/ LjXJo2pak(`tI}rMauO]a5;8v kx;'U}$~ۑ}Ϩ0k0g.#%mK.8{F(=X]E(qt8~B c5LQ 6%f%}ERaƁ%~괤WOR7'l #3mD &zAXLBA}=THJD H_j|@ǐ`ǝ=NM( ;A\ ]f/nQ zb&vč9ct$_^LZ^ha-p"[$@=聟:ODf=ݞpp@.Zm;ބ@T@02?͌a9{%4gN Ss mP\l5|ə^1ی4a햮rr=W^uͤHXzE3/Y -C- |b!7Ah$Sð2A6lUByZ ^:f"N;9+pY0ԗq N1+6 X.'Fӓp} ±Ò^FZ?`R%{z~(kRȻ&%:5_2G;EWwtY"o[b?InQuws'3e 4oRw[bly{ =>0ֶ]  e^ W#-EhIjg>}C^M«o] :/ ߈km;rR{R`t{ua {>NZg|^]//&;rh5Dp#-'\:Z-]oϋ;v ^77uTô6cW1ʨ"!*)p+$]{[\vdKrXX>v}V1[+ݪ[&垙ו Q3w>N6cg=+3uymdeb ZySicB1{g9vQ9p@zG4\K?|QVz:C&7tk\pJqMr4ɱ\z+F~{ȮWmDMgG*[N-|4wğ@UY۴JXSu  !jm{ŝɛ'I;6T1t,C%T]5#mcp`^Xs\ʈJ]\?CddV%/i?MC#w I׹rSʪpL-zY^Z̈́c?xʓmѫK#88#<ܔeyn9%Z46 qFGr^KbE5T|?yڪ~3M_ުVyE xx{mg=Q&-g6a{(rߗӧuvt[uA? }y)}/|׺.b^VRO5hzSmYS]{h;w#{,PvG6sAѐ_/jB;:E13q~6a)m3|SqvgGrۺNN~ 4A4'{:yz*֫EE04o7o?ǂE?h|ϳ_#V`1f8\*|;u`Ql_ڟyjӄ#9b; O)eQ V m@2;|&W#jHi._b.XzǾ DkEץRߧBFAiﺦokmrkH#BjHGMkg)l^9Q;*pq)Ns[CB`A$Ffj$If/zy#[Lj7>j}e{YnO&!k[(>gX3mAlǾWYj5+հ n8DO bcI}zOơ6ZLzӯF*r< >ݯ MA811\}Zg)>fg<PnvYs}vv{Y1ބMռL\gr gFު&|Z cE+0_*8^zyd_[ 'C[6pLqP4sϊ̬gz&BrhVtʰ#g?E^=FO"?7=wY gm޺a?O7}#u-(+q:{X.۝[ُWE5?]hO14Js?FX^waՄ?C\$%Sv\M{m%E"/c!Rxų3?ˉ4_AQ3P0K/d}k q7GѓH<:.ya5DÁ`j?Tnc^#cu"[_sJU}۴xP YۤHYPgZ#^Bm_5+R^3Sv; L g{TWiS6cˑ^~9KS-2kK'UKnX)YdXu9bNzGvPbs#@8e<ȡJ=9xub%B(BңKZ s ZʃKtb}r?/&LzFm;Үah}06F/mt"x98R]W*/Pv笱*Ih6-yҧbSsjz:iTBw}Y$+ 6%g<)fkFga`;=xԳ7r1:0'==3IEn;bkQ#1 6ōcfkf#b,Bұ>xo3XfOoL񳞲4)g覞DK%JdS| ~m NS;:^bN]:٣Uj9Imo3ŵ^-B޸l!·.ԕI)\(zG@#ϵ<}]-LĨw'nU·rGϟ5=0eGƣ[WN_|J}ַmF{x^䃢vTU2yFΨģѧU潴,GjBӈay!CS}Uo-mV&ڄEGGw1H]{X* Bzg]k-#wPR2_*wc}GxgmqwR& .7# pU?AUs><xcǓ1gwI(z7w5.`SA  U^1dEPy~Ǔ Nj(K=~):o |-D>9ôBhT\'Z@?ҚW(^ Z݄F|{ؕv\* qTQ_t{zFZ8սv_-bǓm*kDb7Ze[/ndq=DH K*JT}CCW.z[(y"w+ηc^LaoQN6v.dgQ`0LǞHˆYvSߊ/WwWnǚ bzzW"wWvyؿOۑ7kkGsҠ)" ))Ý\)Sp'"{#gv?gW)͡"4߶M;+EVHE6.`S!ciXl=gW[TfY6{k N\QTI<,f0k=55/E]RZޢqQK yŇ{oq DwM^,v.|̾y:ښ|m)G>Wk-W܃m~% H{oR8kRw#Gmm~!RpZ V +ڛ_íпS͕̻` 5iDVPړN {#./Aɤ$>Lҏ IEόs jeRc\$h)Z/w-Q?;j#%;cJwVP#|i `PHxB!eS5Cwz3g;:3?Xc k {i˭mΟzy|gʆIW-?&L% 鉥d$qsP !u&b# ֿh]?1kw/fa;c}z-<@^cuz9%{d(3ؼ]USꝲD=Fiϱb%2Xm>Offf .Sf xS0sg Anzkm%r3~%&~IDYe]J^956+K'ѼKX%nnBآ2 W6%X3ǪQo'Kjmjk{ֵU$wm'`ɍ=3I؟AZ;efv13#APGǦLF?ҶscX1$::uN,RMߦL*1 fE[NV<>QFr}6p> _4#4*Zzx؈ [hq.Sfl6.,41m/R(#vUZP"׺m~uTB)w,#[.Uc(=SE:ۖR a{?6&FTznp2g3s8h Il v|o {gT ?]*jv}0=/ Kc>VT]؟~^+1n7hp2PoG!Oyt޴#NX Ӵ׸\yQ&q53;Pkm5r:wKv(+ S`r(TiCB$I.ޘaIC]K7K:YɦpڂJѻQ 0w1`G{6|(u^Spt1<,oT=:ݔ"!oPkz6ֆ9zKo8HpR!٫z=+ivi\I򁐂%ՀTUӇ*}Hyq왐g6E W&EѓD0&2T=>}VnvYͶȭ1q+ASWʋwn>+/\VA`+8^Eo-NsJ!4>xKqVRgnb^Cr9{3r=<υL4;E<|dO@dhP|0'-AQ<ᜮ{ŷdd"ӸI)-:f,1yn/&{'saUop8* ǭvb.31i(G3]|ylB;Gaa旧pu*_$TO!PC i7KKwjMފ3N<,7maXվ]^j]7 oBSZ1LdCm|‚ja;Y2imݷyn|SѺkIY7=|f C{q@F &!|Cn/fNf׍pwIj58vltu0p:A/sqL6K`}Od^w 8:Az }Fw y[AWk(O~UFc4d] [DopvG=Dwi!P뉓G\h5:,myRJ08>-w4*̡SZgW'ۻ$g֒(W {B`N& ((VTH+`!uvUzmg15 }  ѦæƱUIL eWW6)S.̐g!63[<֗-/M3 VDxԾJXKcy;I;֒Naԩ<-|ܤѷ LmD?QmDSfX,_ $<+^5d,q =~D]M֣GT 7WSs ;ZjSDte&YQꑳ'n.E<:3#YP|p'[.htw-&yidk"e+a`G]oJH-apA9d_SUCBm?Q6#_JkI;'M??=3ۭyjC[M aK OkdT&-k8F0y>*7Yu:X<"cLp4 AfB93?0$'J̗fd+ޛ`8q2y?)„\%shazam/data/U5N.rda0000644000176200001440000014113413402556553013561 0ustar liggesusersBZh91AY&SYVdT~@> aVc"A@ @ A  ` `Al`   60@  AAA  @A@   AA A   @ ( RQ4bF ԧ1#LL 04i A'~T*Mh  "7ꪧ~URL#O*OUS~P jlUT"Y|v3mۏ˻ZַA;"(:P~yG?{,,`` XX|,,`UUT` XX,,`~I$]I- ?{{P"0t>*Q%vWJEso~u~8pkZֵ{πI$րI$@$I$Iss*ZU $>o{Ujo|UkZ{UVo|UkZ{UVo|UkZ{UVo|UkZ{UVo|ʪ$I`I$skUUwv kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾a$II$UP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{I$@$IkUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ I$I$@x*ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~I$I$ ֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾a$II$UP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{I$@$IkUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ I$I$@x*ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~I$I$ ֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾{_{I$?wwwwvI$s9I$>I$I$I$I$g{U33rvE\ݮQn(k[-rvC32}߇$&vE\ݮQn(k[-rvE\>n;\ݮQn(k[-rvE\ݮP̟}zI7wvIQn(k[-rvE\ݮQn(ffO$$(k[-rvE\ݮQn(k33'}{ޒMݒgk[-rvE\ݮQn(k[=I&3-rvE\ݮQn(k[- ~wwdrvE\ݮQn(k[-rfd{ILrvE\ݮQn(k[-rvC32}߇$&vE\ݮQn(k[-rvE\3$I&I$@ Pg˻I$I$ 2^ff}{ޒO߿~N(k[-rvE\ݮQn(T+33}ҧwUEjQZTV+UEjffO$~$Qn(k[-rvE\ݮQn(ffO$~$Qn(k[-rvE\ݮQn(ffO$~$Qn(k[-rvE\ݮQn(ffO$~$Qn(k[-rvE\ݮQn(ffO$~$Qn(k[-rvE\ݮQn(ffO$~$Qn(k[-rvE\ݮQn(ffO$~$Qn(k[-rvE\ݮQn(ffO$~$Qn(k[-rvE\ݮQn(ffL̒I$I$@g˻ $H333>=I&3-rvE\ݮQn(k[- ~wwdrvE\ݮQn(k[-rfd{ILrvE\ݮQn(k[-rvC32}߇$&vE\ݮQn(k[-rvE\>n;\ݮQn(k[-rvE\ݮQ^d~$$(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC32I?~߿MI$ϗwwwvI$3;k333-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC32}{ޒMݒgk[-rvE\ݮQn(k[]n;\ݮQn(k[-rvE\ݮP̟}wwdrvE\ݮQn(k[-rfd~$$(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffI'߿~L$I 3݀I$ jwwdrvE\ݮQn(k[-rfd~$$(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC32}{ޒMݒgk[-rvE\ݮQn(k[]n;\ݮQn(k[-rvE\ݮP̟}wwdrvE\ݮQn(k[-rfd~$$(k[-rvE\ݮQn(k{$II$|I$nəwwdrvE\ݮQn(k[-rfd~$$(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC32}{ޒMݒgk[-`3'~$&y]n߮zI7wvI^fd~߿~I$@g˻ $H{fs`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̒O߿~$I$@g˻ $H{wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL{$II$|I$&ffgK{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̒O߿~wwwww@I$@g˻ $H{fsL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&ᅬ߿OI$Lwwwwv$Is9$I> $HI$333$I&I$ϗwwwv7wwvLϾ~$$?~߽o0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̒O߿~wwwww@I$@g˻3;k33߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI_ᙒI$I0I$@I$A$I3݀ $HI$@g{>]n߮zI7wvI_3'~邏߿32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI32I$`$I.wwwwvLϾ~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`$~ߦ$I 3݀{fs&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n?߿~$I$$I.߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwd32I$`$I.'{w{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&yI߿~nI$wwww` sڬֹs31$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`$I0I$wwww` swwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL{fI$L$I e ={K{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0=$߿~7wwt2I$9s|I$@XI$߿~I$@ $Hwwww` sڬn߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvIks3$I&I$2{~$$/32}{ޒMݒ`>߽I&0ݜ[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9ݒI$ $Hwwwwv.wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jkU~w}fdI$$I $I.I$I$$I$~sd?UUUU33ﻻww{wwݻUUUUUUwfw|UUUUUU7ٝ|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfww}}}ۻI$wwww` sڬֹs30nUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{I$I$@˻g9swwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻j{fI$L$I eI$@ۮ`G񙙙wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUywwwwtI$ fs>fs֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33$I$]݀39sjnwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUU]f32I$`$I.H0VI#UUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪kZֵkZ$I0eI$s$I $I ??>߲I$$IsU9jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3I$ $Hwwwwv-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{ֵkZֳ]{$I0I$wwww` $I$E?n Iff*fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33I$2sU9gwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZwg$I0$II$@˻I$$I!˻-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jٙUUUUUUUwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUukZks3$I&I$2I$H0VI#UUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfww}}}ۻ$I e395snUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{I&I$2s廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUukY̒I$I$@˻I$(uUH333331UUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{}}nI$]݀39sjZ9߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪_ewI$L˿˻I$9s<I$@` $Ww߿dI'I$$@ۮ`G񙙙wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUU]kZֵkZֵ{$II$ fs>fsϼҪfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;I$]݀39sjZwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ932I$`$I.H0VI#UW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪kZֵk5I$ $HwwwwvI$I$E?n If*fwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU2I$$I.I$U_~fsۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUU?ϗww}򪪪ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;3$I&I$2ww[֪fg{-wvUUUUUUU33ﻻww{;33ﻻww{|w}ۻ߀{廻ffg{-wv;33;nwwٙwwݻ[vffww}}$I$@˻g9sW-wv;33;nwwٙwwݻ[vffwwn~33ﻻww{|w}ۻ߀{廻ffg{-wv;33;nww{fI$L$I e-wv;33;nwwٙwwݻ[vffwwn~33ﻻww{|w}ۻ߀{廻ffg{-wv;33;nwwٙ}}n$I e395s}33ﻻww{|w}ۻ߀{廻ffg{-wv;33;nwwٙwwݻ[vffwwn~33ﻻww{www?I' $H9s<I$}߿~$OI$ۻunwwٙwwݻ[vffwwn~33ﻻww{|w}ۻ߀{廻ffg{-wv;33;nwwٙwwݻϟ>|ϙ̒I$I$@˻g9sVk\9 ϟ>|w}ۻ߀{廻ffg{-wv;33;nwwٙwwݻ[vffwwn~33ﻻww{|w}ۻ߀tI$ fs>fsۻ߀{廻ffg{-wv;33;nwwٙwwݻ3/ﻻwww}wwݻ߀뻾{廻uwwn:nw{wwI$`$I.9[]{-wv~ﻻwww}wwݻ߀뻾{廻uwwn:nw{ww|w}ۻ[]{-wv~32I$`$I.ww廻uwwn:nw{ww|w}ۻ[]{-wv~ﻻwww}wwݻ߀뻾{廻uwwn9I$ $Hwwwwv7ww{wwݻ߀뻾{廻uwwn:nw{ww|w}ۻ[]{-wv~ﻻwww}wwݻ߀뻾{廻>|{fI$L'{.I$@-wv~ﻻwww}wwݻ߀뻾{廻uwwn:nw{{33}wwﻻwww}wwݻ߀뻾{廻ϟ>|ϟ3332I$`$I.9ϵYsf`gߟ>|ww|w}ۻ[]{-wv~ﻻwww}wwݻ߀뻾{廻uwwn:nw{ww|w}ۻwwwww@I$@˻g9sVk\9[]{-wv~ﻻwww}wwݻ߀뻾{廻uwwn:0VI?Uw{$]*'@^{$I.9ϵYpY$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=W]_{wwww`s8I$@X߿dI'I$39uUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt {Lw{ހ.9ϵYUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdu+{ޠ{e395szw{$]*'@w IP`zw{$]*'@w IP`zw{$U{z${e395s̒OUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt {Y$Iw{ހ.9ϵYsf`]](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](09=3332I$`{wwwwvI$I$@ۮ`zw{$]*'@w IP`zw{$]*'@w IP`zw{9I${˻$I$(uUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdə2I$`{wwwwvI$@I$~sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=W]_ݙ 쫯߀?~`zw{$9s33$I&;@wwww`E?n IP`zw{$]*'@w IP`zw{$]*'@w IP`z33$I&;@wwww` @ۮ`zw{$]*'@w IP`zw{$]*'@w IP`zw{$YI$]݀9s<I$`߿~I$@{ $~sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$]($I{e@ۮ`zw{$]*'@w IP`zw{$]*'@w IP`zw{$U$I{e3~sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](I0z fs>9 IP`zw{$]*'@w IP`zw{$]*'@w IP`zU{;@wwww` sڬֹUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt {Y${2sU9fc$]*'@w IP`zw{$]*'@w IP`zw{$]*'@^{޲I${wwwwv9}k33t Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Üf`_s$I0z I$I$(uUOUҀ<ٛ'/}w3wz$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=^I$Lw{ހ.$IIUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'yn{ʺ9fzUdI{e399'@sUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt ~{I {g˻ $H?u߿~$I>;@wwwwv9oyn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$yϵ=3332I$`{wwwwv9oyUVff(}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}{|9̒I${]݀$IUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIPWI${]݀39s㙻z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJ{I{2sZ$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}_s$I0z $I$sfIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$]($I0z f㙻z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJ{{˻g9s{jOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ~{g9ffdI${2I$I$sfIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$]9}I$^$I 2I$@qVI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WB` {*?ο}]])/ P^;W7ўOcJK֤rP[r" Woo313%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TT P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T ST P%@T P%@T QYP%@U$J*J*,J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J)UT7T<?f&J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*JҠJ*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*J*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J**J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*%@TYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T ST P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T ST P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%OP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@?@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TT P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T ST P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%OP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@?@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@ LLN2P]]\ɘJ*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*JҠJ*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*J*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J**J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*Jʁ*J*J*+*J*J*J*J*OӞ5J" VʨȂUJ U1AY&SY[)H@@⨃F?0@@ PPPp ȒII"I0@@$$$DDHII"I$$$$$$DIE$I@ $EI$I$$=ࠐPP @@JH  PH (!T A@JP   (VQ=STMMFC!hg4zbJzTHMѠh3HR~%Ojds`!&UM6hDU; UT>GRS99:(TEP_]~N9}'ﻑoi *h~z^VffI$?'?'}[z=G]E?Sr D"]x:u {I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$̙I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I3333333333&fd̒I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$ffLǔL̒I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$fq;I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I&fffffffffz33$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$fdyN$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$32fffdI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$'I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$IǔL$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$33&fffdI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$Lə2I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$III$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$Lɞ8I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$33333&fd̒I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I33&I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I'3?o߻~0~ꪯ_^z=z=6mmʈ"(?X@{ߑ>xz^Wxy`8xxyx)$ ( 떁@QD P@z0O[mUU@_`3>0k 0k W̪w;9^Uyʯ*eV t5`a 0ky瞀~}}|eWA] t5`A] t5^Uy0k 0k̪UyUs;ߝzyʯ*eWA] t5`A] t5מ|{C 0k 0kUW~ws*9^Uyʯ(A] t5j3UW̪n gϰ*mqBP% BP% Bm;m(J(Jnvی% BP% BP% J(J(Jmn0% BP% BP&sa(J(J(MmP% BP% BPmq(J(J6۝ BP% BP% Bm;m(J(Jۯnݻwww`UP~g09_Y(J(Ml&m(J(J6m(J(JmJ(J(Jma(J(J(Mm(J(J6m(J(JmJ(J(Jma(J(s9_Ygs7~w} 6mmP% BP% BPmq(J(J6۝ BP% BP% Bm;m(J(Jnvی% BP% BP% J(J(Jmn0% BP% BP&sa(J(J(MmP% BP% BPmq(J(J;v@*ys>(J(J6۝ BP% BP% Bm;m(J(Jnvی% BP% BP% J(J(Jmn0% BP% BP&sa(J(J(MmP% BP% BPmq(J(J6۝ BP% BP% Bv׷nݻml6mmq% BP% BP% J(J(Jmn0% BP% BP&sa(J(J(MmP% BP% BPmq(J(J6۝ BP% BP% Bm;m(J(Jnvی% BP% BP% J(J(J9{UT`J(J(Jmn0% BP% BP&sa(J(J(MmP% BP% BPmq(J(J6۝ BP% BP% Bm8xgs>\xg2ʯ3UW~wUT 0k 0k9^Uy{ހ g2ʯ3UW`A] t5`A] uO<UUUyF 0k 0kW~w{ 0k 0kʯ*eW^g3ʯʀ~UUk½w 0k *eW^g3}wwtUUs*`A] t5`A] t5UW~w@0k 0k UyUs*9eW^g2k 0k >wUUs( 0k 0kUW~wA] t5`A] t5`A]}C}}z*Pk 0k W^g2ʯ3{ UyUs*9 t5`A] t5`^y<UUs* 0k 0k}}UU@ 0k}ϟ7 0k*eW^g3UW̪UyUt5`A] t5`A]y<9^Q 0k 0kyUs;ߝzP0k 0k*9^Uy{ހUU^g2ʯ3UWA] t5`A] t5מ}<΀UU^g2k 0k *g{@( 0k 0keW^g2ʯ3`A] t5`A] tUyUs;ߝzA] t5`A] t5`A]y<}UUyʯ*A] t5`A] t5ay{ހUU5`A] t5`A] tUyʯ*gP}k aᮃ 0kyUW̪0k 0k W~wUF 0k 0kW̪w;}}}k 0k 0kyタ9^Uyt5`A] t5`A]Us;ߝzUC] t5`A] t5`EyUs*9џ?>sz=UY}}UA 0k 0k^Uyʯ*g{@*3UW̪5`A] t5`A]y<UW̪ 0k 0kʯ3{ k 0k ʯ3UW~wUUs*9^Uy t5`A] t5`_}|΀yʯ(A] t5aƺ 0kyUs;ߝzP0k y{{UUUUUUUUTW{~Wuus~_z{yUUU@UUUUUW{wwwwwwwwwwwwwwww*wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww????? wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww*wwwwwwwwwwwwwwwwwwwwwwwwwwwUVs*wz@@}@ t]Vs*YUS ?@@>|U_UU.@ t].{9t].@ Ug3www^T>@ t].̪}t].@ Ҫ9UVs7wwuUU{ʪ9UVs*t]9UVs*n@9UVs*.@ t]|ϟ=UW̪t].@ ЪU@9t].@ g3www^UOt].@ UUg3www^@>@ t].Ug2fUTUTg2@ t].,n@.@ t]UUY׾].@ tVs*n@}}.@ tg2eUU{U^2eUU.@ UUʪ9UVs7wwuUU{ʪ9t].@ ϟ>|}UP].@ t*eUU@3g0`9s nnUT=`9s 3g3@̠ n3g0`9s | ~g0`9s 3g3www}0`9s 3g0f=`9s 3g0`@{9s 3g0`9タ9s 3g0`9s7www}s 3g0`9s n3g0`9s }3g0`9s 3sg0`9s 3g3*sg0`9s 3Ѷ ?h *(B(@T!ps99}q3332I$I$I$I$I$I$I$I$I$I$I$I$I$I$32I$ffffffffg32fI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$Lə33333333333$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I&d̙$I33$I$I$I$I$I$I$I$I$I$I$I$I$I$I3332c̙I$ffI$I$I&fdI$I$ffI$I$I&fdI$I$GI$̄{I!$3 33&fffffffffffd$BI$$BI$33&fffffffffffd$BI$$BI$33&fffffffffffd$BI$$BI$33&fffffffffffd$BI$$BI$33&fffffffffffdI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$HI$HI$HI$I$HI$HI$I$HI$HI$I$HI$HI$I$HI$HffI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I $I $II $I $II $I $II $I $II $I $̙$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$33333333333!$I!$I!$333333333333!$I!$I!$333333333333!$I!$I!$333333333333!$I!$I!$333333333333!$I!$I!3$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$fffffffffffBI$$BI$$BI&ffffffffffffBI$$BI$$BI&ffffffffffffBI$$BI$$BI&ffffffffffffBI$$BI$$BI&ffffffffffffBI$$BI$$Cs^zGrI$I$I$ffI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$ffI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$ffI$I$I$32fffffffdI$I$I$I$I$I$I$I$I$̒I$I$I$I$I$I$ə33333$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I&ffffffd əI$I$I$̒I$I$I$I$I$I$I$I$I$I$I$I$3333333333=DHI$HI$L̄HI$HI$L̄HI$HI$L̄HI$HI$L̄HI$HI$IfdI$I$ffI$I$I&fdI$I$ffI$I$I&fdI$II&fffffffffffBI$$BI$$Cuӎ833333332fC33 330 q33$I$333!$I!$I!$:뮳333333332I!$I!$I̒I$I$BI$$BI$$BI&fffffffI$I33$I$I$I$I$I$I$I$I$I$I$I$I$I$L̄HI$HI$L̄HI$HI$L̄HI$HI$L̄HI$HI$L̄HI$HI$L$I33$I$I$I$I$I$I$I$I$I$I$I$I$I$I $I $I $ $I $I $ $I $I $ $I $I $ $I $I $$I33$I$I$I$I$I$I$I$I$I$I$I$I$I$I3332I!$I!$I3333333333332I!$I!$I3333333333332I!$I!$I3333333333332I!$I!$I3333333333332I!$I!$uӻk;]I$I$I$I$I$I$I&fdI$I$I$I$I$I$I$I$I$I33333&fd$I$L$I$I$I$I$I$I$I$I$I$I$I$I$I$I$L$I$I$I$I$I$I$I$I$I$I$I$I$I$I$L$fffffffffd̒I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$333333333332yY333333333$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I&ffgI $I $II $I $II $I $II $I $II $I $II$I$I$I$I&fdI$I$I$I$I$I$I$I$I$I$33!$I!$I!$333333333333!$I!$I!$I$I$I$BI$$BI$$BI&ffffffffffffBI$$BI$$BI&ffffffffffffBI$$BI$$CO)3333333$I$ffI$I$I&fdI$I$ffI$I$I&fdI'xII$L$I32I!$I!$I3333333333!$I!$I!q$u $fffadI$32I$I$$BI$$BI$$fffg]uffffffBI$$BI$$BI&ffdI$I$I$I$I$I$32I$I$I$I$I$I$I$I$I$̄HI$HI$L̄HI$HI$L̄HI$HI$L̄HI$HI$L̄HI$HI$L̒I$I$I$I$I$I$32I$I$I$I$I$I$I$I$I$ $I $I $ $I $I $ $I $I $ $I $I $ $I $Iۛ|^g=ٙ$I$I$I$I$I$I$I$I$I$I$I$I$I$I$̒I33333333332ffL̒I$I$I$I$I$I$I$I$̒I$I$I$I$I$I$I$32ffffffffdI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$q!&gI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$$BI$$BI$$ffffffffffffd$BI$$BI$$ffffffffffffd$BI$$BI$$ffffffffffffd$BI$$BI$$ffffffffffffd$BI$$BI$$ffffI$I$I$I$I$I$I$I$I$I$ffI$I$I$I$I$LI$HI$HI$I$HI$HI$I$HI$HI$I$HI$HI$I$HI$HI$$I$I$I$I$I$I$I$I$I$ffI$I$I$I$I$II $I $I$I$I$I!$I!$I!$333333333333!$I!$I!$333333333333!$I!$I!$333333333333!$I!$I!I3333$I$I$I$I$I$I$I$I$I$I$I$2I$I3:뮳332I!$I!$I3$I$I$I!$I!$I3333333333!$I!$I!I뮺3332dHI$$ 2BII3333:뮳332I!$I!$I33333333332I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$fd$BI$$BI$$ffffffffffffd$BI$$BI$$ffffffffffffd$BI$$BI$$ffffffffffffd$BI$$BI$$ffffffffffffd$BI$$BI$>889<ߞW=I$I$I$I$I$I$I$I$I$I$I$I$I$ffI$I$333332ffL̒I$I$I$I$I$I$I$I$I$I$̒I$I$I$I$I$33&dI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$̙33333333332I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I $I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$̒I$I$3333I$HI$HI$I$HI$HI$I$HI$HI$I$HI$HI$I$HI$HI$$I$I$I$I$I$I$I$I$I$I$I$I$32I$I$II $I $II $I $II $I $II $I $II $I $I$I$I$I$I$I$I$I$I$I$I$I$I$32I$I$I333!$I!$I!$333333333333!$I!$I!$333333333333!$I!$I!$333333333333!$I!$I!$333333333333!$I!$I!$333333333$I$I$I$I$I$I$I$I$I$I$I$I$32I$I$I&ffBI$$BI$$BI&ffffffffffffBI$$BI$$BI$I$I$I$HI$HI$L̄HI$HI$L̄HI$HI$q$33$I$I$32I$I$I33$I$I$32I$I$I!$I$I$IY $I $I $]uI $I $II$I$$I $I $]uI $I $$뮺̄pI$$ 330[8s"E ""( ~^p w_?_G?ww{(}  |~=TP<:t^^ײ<"8}W_P;Nowo'|"P۸@@~nK>cPT<(=Q !0 !( J H0 ?"x"EPw$S  shazam/data/CHARGE_MUTATIONS.rda0000644000176200001440000000170013402556553015540 0ustar liggesusersBZh91AY&SY"Xp@/ߐ@>+DSe3H M4ɵ44i )I#TH~4@"ߪFzO&L4`Ɂ &!L12`4a%)SКbdiTAxYo(a~7ᓐG-9Fbɺs-/$Дl$!sZb;_~7xǣ~Wû(*`{^vηtP @F@jÃ&3f><2fb`,1lOу׺Q[ZJ5V3ͬmcpED5Z @SAsM1v1"yֵr"3sBmZn\rƊ"]: )l[URMDAFI2DDn& ks@AP( P( P(. P(DeD]3lżV)-WD=V"KD>0DFR_%U5b33d'go 0`1q 8㈲UUe*+w뮺뮠UVRUɆ=eYdUe*)UY^ ofXLRU*)UY[c78pMiIJUVRUwwwrjT}JxUIQ",/3EUVPWEiĶc\n:.QMu +?I;ck,r{ ݙCi)1 ~"&r%WORCu(`TC2܆;w02^%BQ+XUazJ-18@C)]Lނ#mIYUqgT .p shazam/data/IMGT_V.rda0000644000176200001440000000210513402556553014171 0ustar liggesusersBZh91AY&SY?1@@@g]puU$?Qz?T@G =@4db0`!M0!FOU*5S!`CL4iɉii40LLLjhOLSj=&CLzsT +L֥:&t 'l-[;M<4-hZ]^ vbTB|[#  VCm!a*edOz?k[PTsWu?Owހ,,`` XUUP,,`` XX$Iv?$[ XX/|<}|}P"0άJJ$7I9EpֵkZ w{ހI$@|րI$@$I$Iss*ZU $ʪֵUR@7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7I$X$Is*ZU]݃~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{I$@$IkUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ I$I$@x*ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~I$I$ ֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾a$II$UP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{I$@$IkUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ I$I$@x*ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~I$I$ ֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾jֵU@ kUT߾a$II$UP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7o{ڪUP~ZU7;I$|?޻I$@9sI$@߀I$$I{?裸I'I$~I$Ug9 =k[-rvE\ݮQn(k33'}{ޒMݒgk[-rvE\ݮQn(k[=I&3-rvE\ݮQn(k[- ~wwdrvE\ݮQn(k[-rfd{ILrvE\ݮQn(k[-rvC32}߇$&vE\ݮQn(k[-rvE\>n;\ݮQn(k[-rvE\ݮP̟}zI7wvIQn(k[-rvE\ݮQn(ffO$$(k[-rvE\ݮQn(k33'}{ޒMݒgk[-rvE\ݮQn(k[ ̒OߤII$w{I $IwAzI?~I;\ݮQn(k[-rvE\ݮB3;>_{}*wuTV+UEjQZTV/fg{~ߤ-rvE\ݮQn(k[- ~ߤ-rvE\ݮQn(k[- ~ߤ-rvE\ݮQn(k[- ~ߤ-rvE\ݮQn(k[- ~ߤ-rvE\ݮQn(k[- ~ߤ-rvE\ݮQn(k[- ~ߤ-rvE\ݮQn(k[- ~ߤ-rvE\ݮQn(k[- $$II$~I$3>=I&3-rvE\ݮQn(k[- ~wwdrvE\ݮQn(k[-rfd{ILrvE\ݮQn(k[-rvC32}߇$&vE\ݮQn(k[-rvE\>n;\ݮQn(k[-rvE\ݮQ^d~$$(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-k|?{$I0I$wwwvI$3;k33(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC32}{ޒMݒgk[-rvE\ݮQn(k[]n;\ݮQn(k[-rvE\ݮP̟}wwdrvE\ݮQn(k[-rfd~$$(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\$~ߦ$I 3݀I$ jZ=$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC32}{ޒMݒgk[-rvE\ݮQn(k[]n;\ݮQn(k[-rvE\ݮP̟}wwdrvE\ݮQn(k[-rfd~$$(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- 32I$`$I$I &ffgK{ޒMݒgk[-rvE\ݮQn(k[]n;\ݮQn(k[-rvE\ݮP̟}wwdrvE\ݮQn(k[-rfd~$$(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k ̟}wwdfOw{IL3'~$&yI߿~nI$I$g{Ysf`33^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32I?~߿`$I$I fw{U׽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfdI$I$?]I$@ 333>]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~߿~$I 3݀I$ jZ9ffy]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n*3$߿I& I$9sI$߀I$,$I Woy$I0I$?]왙}.zI7wvI?~{]ݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`$~ߦ$I{5sf`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0232I?~`I$I$I$g뻻I$I$ jW{IL3'~$&U?̟メO߿~x >߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/s3$I&I$fff}$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n$߿~7wwwwww@I$?]Vk\9 ߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI?߿d߿I$ $Hwwwwv9}_K{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0?wfdI$I$]݀'{}$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n$߿~7wwwww@I$wwww` sYsf`2L3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&yI߿I0I$wwww` sYw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&̒I$I$@˻={߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdd~߿~2I$9s~I$@$I }}$I>$I n9ϪZ9$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n$II$ dO~$$/32}{ޒMݒ`>߽I&0ݯ33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fgww}L$I e39{ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUWU?{$I0 $HI$@˻$I $II$~sd?UUUy{廻jfwwn~UUUUUU}_/UUUUUU_g{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZkZֵkZks3$I&I$2s5s}UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9}} $Hwwwwv9}UwvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{I$ $Hwwwwv@ۮ`G񙙙fwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUֵkZֵk5I$ $HwwwwvI$I$@ۮ`G񘪪fwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;I$]݀39sUf]wn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9fdI$I$]݀E?n Ifffffffffb9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUWZֵkZgfI$LwwwwvI$s9?~I$@`I$}}I$I$s5sjfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;I&I$2rwwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jkZks3$I&I$2 $I"\Y$33331UUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfww}}}ۻI$ fs>k33 ֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUWwwI$LI$@I$2$I $Hfs>nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUW?ϗww}򪪪ﳽﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZY̒I$I$@˻I$~sd?UUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{kZֵkZֵ{$II$ fs>k33UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fgww}I0I$wwww` sXw}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪{$II$ $~sd?UU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZkZֵkZks3$I&I$2s5s}UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZٗ}`].I$9s$II'I$|I$@݀3wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jkZֵf32I$`$I. $I$(uUH333UUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fgww}}ݻI$ fs>k3;wwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW$II$ frwwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jֵkY̒I$I$@˻I$H0VI#UUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{_}}nI$@I$wwww`$I ʪk33UUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUU_}ww}~O*nnwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33裸II$ fs?{ܷw}ۻ߭UUUUUUW[֪fg{-wvUUUwfg{-wv;33;nwwٙwwݻ[vffwwn~33ﻻww{|w}ۻ߀ $Hwwwwv9}U9wݻ[vffwwn~33ﻻww{|w}ۻ߀{廻ffg{-wv;33;nwwٙwwݻ[vfwI$ $Hwwwwvww廻ffg{-wv;33;nwwٙwwݻ[vffwwn~33ﻻww{|w}ۻ߀{廻ffg{-wv?~߿~;I$ $Hwwwwv9}U9ff>ٙwwݻ[vffwwn~33ﻻww{|w}ۻ߀{廻ffg{-wv;33;nwwٙwwݻ?}}nI$s8$I I$|I$@݀39]nwwٙwwݻ[vffwwn~33ﻻww{|w}ۻ߀{廻ffg{-wv;33;nwwٙwwݻ߳{$I0I$wwww`nunwwٙwwݻ[vffwwn~33ﻻww{|w}ۻ߀{廻ffg{-wv;33;nwwٙwwݻwwwtI$wwww` sYsfa[vffwwn~33ﻻww{|w}ۻ߀{32nw{ww|w}ۻ[]{-wv~ﻻwww}}L$I e39V-wv~ﻻwww}wwݻ߀뻾{廻uwwn:nw{ww|w}ۻ[]{-wv~ﻻwww}$I0I$wwww` s[]{-wv~ﻻwww}wwݻ߀뻾{廻uwwn:nw{ww|w}ۻ[]{-wv~$I0I$wwww`ww[]{-wv~ﻻwww}wwݻ߀뻾{廻uwwn:nw{ww|w}ۻ[]{-wv~?_dI$wz2I$nunw{ww|w}ۻ[]{-wv~ﻻwww}wwݻ߀#ٙ/뻿|w}ۻ[]{-wv~߿~9s33$I&I$27wwwwww{ܷw}ۻ[]{-wv~ﻻwww}wwݻ߀뻾{廻uwwn:nw{ww|w}ۻ[~߿~s$I0I$wwww` sYsf`g߿~]{-wv~ﻻwww}wwݻ߀뻾{廻uwwn:nw{ww|v*#̀.sdt Y$]({I$I$]݀39sUfs'@w IP`zw{$]*'@w IP`zw{$]*'@w9ff3s&dI$wwww`s8I$@,}}I$I$fs>kY$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJ{@w{ހ.9ϪZ9dt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$]({I$w{ހ.9ϪZ9](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](09fsffI$Lw{ހ.$I$I$~sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt  39s33$I&;@wwww`I$I*'@w IP`zw{$]*'@w IP`zw{$]*'@w E9I${˻I$(uUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdus$I0z $~sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$]u~̙I${˻I$@ۮ`zw{$]*'@w IP`zw{$]*'|0^u۽UOUҀ.sdt $I0z fsۮ`zw{$]*'@w IP`zw{$]*'@w IP`zw{$U{I&;@wwww` sN`zw{$]*'@w IP`zw{$]*'@w IP`zw{$X{wwwwv9s $H?}}I$O{݀39?n IP`zw{$]*'@w IP`zw{$]*'@w IP`zU{$`{wwwwv9}Z*'@w IP`zw{$]*'@w IP`zw{$]*'@w IPW{`{wwwwv9}UUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt {Y {˻g9sֹs1dt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$]({I$z fs>k33](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJ{I$H{˻g9sֹs30/|P`zw{$]*'@w IP`zw{$]*'@w IP`~{g9ffdI${2$I$H0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJU=3332I$`{wwwwvI$@ۮ`z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=W_/}$I{e$I qVI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z_f쫯߀?sfn'@^{޲{]݀39skUU$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$yϳ7u 99}I$w{ހ?]I$@? u}}$I>w{ހwwwwv9oyUVffz>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>T/|9̒I${]݀I$E93wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z̒I${]݀3qVI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$U{z{e39UY'@sUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@s=3332I$`{wwwwvI$I$E93wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z332I$`{wwwwv@qVI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$U{`{wwwwv9oyn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$yϵ=3332I$`{wwwwv9oyUVff(}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}{|9̒I${]݀$IUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fI߿~{$KI$]݀I$@9qVI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WB?Oxk[|{>]/J %%%Jσ]OFy:]%%RR^%%EU'3 zIAjJ }<1313 P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%OP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@?@T P%@T P%@T ERJ*J*ʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*JUT[JKx" WO?TL̕T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%OP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@?@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TT P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T ST P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%OP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T ERJ*J*J*Jʁ*J*J*+*J*J*J*J**J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*JҠJ*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*J*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J**J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*JҠJ*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*J*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J* LT P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@?@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TT P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T ST P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%OP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@?@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T$J*J*Jʁ*J*J*+*J*J*cj),DȂU"2 rUDGPVImX2@_}G>5kQbv[MmfiZʅm S52,*3lji6Y%"klf &ɶjl٫ZسZZճV؉%mIeC٫i&iem2T @@@@:p $ww` Üls] mrsD`uBV-& Jm`l2L5ƭ6Mmm2imDI0l[[mI1 Q [ 5Zlг[-@P*J*@JJWe6U( *TRU-ejf **@URT&)m6*X<TU* RJUֲLbLSlgrU(J*TU)z[[%lmLU+j6B"fوFLҶ[)SKe%3CReiY-VbALkmjm&$Ti$YKmm+m[*&KS36իmf[YTVmJZlصI5fƵ[6mh5R0Uc,MmZDZ@+xwwtYkJE62[fCimQZօS5#֭V+-*͵3hY)e$-f-jc5mm5lFmً6%5iKmjjڶeZ$kTlMfͰVkcLmHm &VR MШhhVVͶlڪ4m6%Y-ALZFedͬD" 0d140 db44hF@ 4h0&L0#&4dɂ`L&ѡ h 21)L&ɦFFF idɈh 42OFFbdhF"TS~imyFMd24GAhщdhhiM4a@M 4b#M4wU)y@z@zimM44  i64 hoTꪪg5Hd42dbfL!h0F iɉd4Ѧ d&F6F`# m#Mm~s;K^|_/v{9Ns"X_ޟ_9hdHYfHi0aB@2R "ט@0$!a H0F6_O9Sڼ$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$$$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$III$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$󳙒I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I=g9$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$y$$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$Ig3$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$LLI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I&ILI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I'y̛[~K[;uIv9v,.צ'>8 ,FDX~~a=莉GD"hFhH"qJS.PZ'xz^#m;p?_)HMc.;NuV>XʗV. 139+2j)(BCjAP$(lC Ѩ.׮귝A$;\2N>*dt=}-~!P! eY?AJ b QJ[1,ov/Xx}]}sm]0_.R~ ۆ#tc݌y3 IjV^_|ͮ%tt=ٻ@4V<~_Nd/\[/ QC6cQQad́Kq(˽ۥ< "4`(_B\׹z+o/(I=f"O˘HENٚ+6 dO MO{&|~Uo[N1*~ȑM  r+YV C \q&Iʳπ5Wzp:`2}^EyO]J $-s.)-)y pg0N@OձNp ]S|>Ҹw# b r!ʴa;GK|5]U'ԍaU=n5*c R7> L^֭U(^l(V 2V^HJy֙Ĝ~Ie0FFg0X2to1Ŀ\mRa^>.z%bo}4rD m u@!p3V^v[$xUB[LøaG CLLu,gGnAUFA?{C4?R 'Ӄfjnft_f v$Ч~a{EU΀sj>`aI . Ƶй)m~|@B,TQ_fO 9Sh=NkHé>It-w>JV3b܀~)h!i&2yĽb bńL~bVa:ϘMt?[S~WM !O7`5eugن5]3."qۀ|wG)<6;e]:&CaG;e=S$ီ( vur*,Eg6'҉OOT]H?]UY9ѹ"ӷRh^͸L4Foz0H4i ;kпf2 /[ ,Pq0Q6hT]Ly7yrdwUVRMg2hcY3kgh.(tۛˤl*pBB* <{'5כt[+c7"B?YCJ>Z^m_sAۺMzW4;],R[Jq~[-綩c]HTeMőܵ0c<1SB(v?DJd4Luߞ{5EK~$F[u r 6.n(t]ZBw괣+ZEd3Ÿc0;ǗEo[i@lMl%P@ ɤo'-*c"ϴhyeΝ]+Evu=瓞Sz}J5:Z? CBP{i834 @!$b@!D_eG8iO]d Z>"qT8(L#gЁW;NohɏG%^p cN]$ BqL ʺDj+&+o; l|\>*ӝبH×|U;q~vK|8^/u τ^tF;&+&98֘CB-s^ڙxeiQ\m:!O8:VH2-6u\f?;ǵ|3&#mO7^c?eBwp"|)ssիwI{Jmzw.,3mҀn'Y̅|2ӕN 0pH\5#\S3̡*AR`xEޠz2\ORNY`!n߫4p :S!4! ̑ ce1 u$ܓW]fD0pa4g%y^?Jql E1 1S?}zIe!wrC޿{c[ڙ{ճB=.o_ߕe;&͆K] V~rX%[;abK~ku ̋Rzlsi}:sQ>Jg6ʣM n{my`jUq)oS_Ԁ-^P+>bb3Y# Vu\W@on^_8YfjiQKi#'!(ҳʏCCq'aN(?.Ho,]P 1 @^acGN)̬982{e;;8,s<ѩ?"6TI$Nʲv[m0` EMazO ϳ[#k6@"jhnfzC?/¼y4#ld%[~D_A4O SPh`ۏ=@ocM6ƃ`OZoR 8v }F'%\6|jQ Il.vi#K:0jh˲I|}k8/x'bjHr X>qVKCa6Yɜ,n|ϭ%ې˫a Bc8 K(B% 4֛ԟmYq) H;$QjW ?u-gMy:Tlk竺M$?}yuLr@ 4b\֮B@li ӐEz@ko.*MՐ4@TҠ֛K`6mj;-eU:k?uoO{ 'r^u=x +<_ie\2m;&>ma b/\^[>} @51Cj@'{Ǝ{}Rs/w -z3cOc,7gpʕpOȀm^j؝sl@ K.7|hē?6x|AI󋲻x8uŞ[/SW> o:&-~r8ZMK\O?yAט c͒NNE|1T`80I Zv4,lq,%ʴқ2ĕ@Boo8?$9uNE&r= 9 CqFvwl3i1Dj3g#RDr.rG6kwh(] ڷS{ vp^| ./@̈́G~`8]־ި_Cf.p#.<lVv{5]{fduT6 ^-]ΟVt.Tqln9C[fK?'Ɔ|uӰ<5]NyOuD6-y\LG'C:"*ߛȻjGW}3.qA/#^Lh3Nw榄7 m{L9\6xG5Bc0&Gl-uN]lfz&iZ:A41a}>^<<wwe!Z% 'W?dR+]B%خdထAI}Ҁ,):S>GLp RU0>@+8-J.6Ʈf22Qq,s ܏J2!:~ϯ)!\5"m()u>W;na9mX~ۢ8-JoEvrꪔcXN۱L䒭o.ļǻ`Ac##~{_R;+Ѫ\OM8&A^4)_dc3]GIUx@ aFZOMݮ~ݴ"9ΤvZd[]ROLeKKߊszC`=7Ej[T5=+j ȼp[`29I*y8z4Ύ݃T;MsbJ_}̨w)oLqoX /Jbm;E(RBbSrAYFP3?IeD'˹zBCQPr\K(R;+n,#v>~OS,tnvC8Ω;߸(K>lf?S.㬑}V_5G82?3; d[e?(Aeܱ$~O"CY" w'. _T=j崑` Y1QN^U;FPcʥi2{$]i_k~V?:>nL1FF}Q,5L?)s[ %SY slbaVQ'~}D:,=Pq[ÓzmwNGX:b~/3Şeyfsr^h`*@! fHWm"m|XGL||z7h8lUN+T7Ί"eX87`M|e]o}IKISJvfo _rc@GvtUyTLL-/=+51{ڥXV5q :;]>6ǰ]8/0ҋ~ O`B q9j 㠤>hum7X(Mӌ;鏶bpa{i2ޝոPV&=]F'%ݷ1=e}n<6. FoJ eY_\/Cȷ=vӠ² ,#.$@@Em'!%gP:֯.:5_l3R wKzp{f!kY<TT|o}8TX:|wn1wuj璝6[$,˦ݹl5Ut xs< ^JvPUpU=ƫ]\̮:z_YQF,}=+-Utws'w̚;^@u1~5说˘GO"sؖGl9%j.૾pk-7c>PɌjML|)3{^Bm0i˜I1ȭu\LVnk mCb^o`m]VjqDb57kܼs/AB{FVƌl ɭч-3ֶ@k&?ʵP9ZoR5`NLzFz@z\d>^S_Jx Ե?a¬2~2`62oݫzS@=z)Xy\^) ғjO;J|K`,/cdZw $xڷBu}y<!\RKʟP8|f" BFp]aPT3.NOMrK^S48[}kc4n^x -HX, eòp eTCQG{HO%+xTXzl>ô<69jәÔk`I@ኇMt) H{hrT,E>K^V𑃃'T^^*wH./$H4@H$OX,/}%aAN@>ARp[O3ҔPYkջ /czO&X4y-ߥ@*!aPl!LԫFE_|U&Ed_oNw}S6 7U6k T's\ļXliV*%9XAcS;~7ƽJ"lXc1g\j{Ogr+ZOkB- ;4q6'E6 `⼘O{&H+P/[78pƲJul+䒺*[oSQ6Nژ 02q wv+˵{${|,~ٷJVTBԲ9Aų7Vd RI$ Q}B2 P;;&AiNItr=zCb~k`#^2PUW*!CgSҨ tEfU5rejkH: sOuaQ*i]gjJ5q Аh|#5Il8%ji/)3ÞߒS+ӥ DŽM4889)]Fۄw* aeM[͒p%鈲GN"v݌ִ4S*"h00\O8lJ/kiG.L޽E2tIٺ<#^H g3i~ZYO/!F2NK+P9ߞp,XnxĶΙMᨷ7DL;U{ eL"|=TїǪ+h IN0ÚɂRvB vpR$ +gs%o!CXu4$smdD}Z@(hF*Ҵl(@#ߕL;y:MsFzfadNCm(%M TQS(`1]mHc<0(0G4V4z$pBJ&kҊ`5>=|RJ 'l߇UVћ8PH^H78;R&. 8e iEP0<ül˘lM2l JE)xmha>QrnK8zsGlLQWoX_9\} BY2ű(';\b}bQM? AϠLV 9'1\q>}T3ydo~o{ أQCX.agRM3)U3Vd^ƿc8|ZQ”;vD+䩡֒q ݙ܆},[O-!er+eoY7:`'l3Ց H{L2֔8 (Ѣ$~z)#<}QYd BZv֑[+޾|e4n@6ьPhՙ9 ̳JYqʆ䇢B>&l@'XՆ 09O`~_c!9+tJ+r{3h(y&p/Hû63:!DUu?%-M{~FDT*uRUPnƮPWXQRHc.98(7Nۘɲ]XG^F9!e:%Bb3MQB)k\Q쇽}̷oxCYͦчφbeǂgNP\ zTGD;o!K @IGPGP8$Q+Wq;La?mRQj?Xߢ}L:X8zmD_Ha۰ɐ֕~N"YCԽuv~P@0vB' s zgPQy7]:xCH"G;SW73CؼM ƾ)`"'bgY}J]IsDZ҈15IR{.&)r]{G `5#U z4RN5͈`$8vjҴcoX.v~/5^|=x[0O)g D*xzʢ5wKeRA\Ti2C{nxL=Ƨvt_`iؙl׫T|%Mdw- WP-\m0%KA3}CMTƛ]~aCVْP靥 )Uu`< Pd]>{h[Kp!fG2 p֦PuE-dQt2s/{L+K\SsK$dcٝNyKD`=wm:Oѐr9}DŞ1,l߯;<|Gǎh;! Բ!p6$VaƿPm^O01a$hWcRKFٶn( .p()do'M^1CIJ`B3J?(FÞM}:m!ܴN@!Aj9n `q?("ؖQ匂7[l,s(0%Bc]I@vmM!?Ԝn !xwIY!olmaBFNoxys]6ySK?UFRdJ ?CSiHdG>^X9eێj78W>Yqb5(:LQeF"18v=֌HģmNŨ7xfBg`4h=rP";U10IɶKL2ĺU "i?o:7'vP!Ur]u ǒԧ[ pu쭚h`R0j<q'{Nʖ%|?˟?28ʥQʭ;gvn3t%Ŧ`xBcRDi: kf07BSya<,^{G`eyމJSM dw+K+GI&~̎' ZVzf71+m3QLa@ /k0,ڄeѦ񩕫V}+8ƕ_H㤕]OHܯ$Jt?dy}mn&N 0% wܷ__r:U%_LJ# !';I[=$׈U2& O7_V새tT:cԬskzD3zd.GTd #cw#AsHv?f?F8kN$ f􊧑?qvsϨkG1݌[SPD Zz0N ^?_{n̂q'Ib1>r!y ՇsH^bDF}Zh"tJw{@829xh5$~[_m{iYlFd}0jJA@Uc5º;ߨ׊D|GRmć0p4Lz9059L_B>, @yXtq78-Y?ٿZѿ> èhp]N p\n2d$T3)8$wMYey@vN*aA9ۺVϗ{E)~LqJZT15S!. b䳭 3z a?TV`FCLdqeLk2%l}S#}l kX=iEԜu;8*e.ਇ( %I̤nyدz9R^+r2Ȍr)\_@Eb(0˸xn dH=ID6#sDbR@M8e;Yw=Y&dP#<>) m&[_IrMS͘qRbG.P47+,I@Dx}0'LpY9ӨR'tk,g䣽H$!q#|,ю"qsU?ɡ4ԩ?$IVx0H!oR1G## x:=0Vɿ0âN^RL6$'aJ_όQP@~Or31aqBB ޯ&ˇDU" 4-E4L[i`N~e+0Mv)k`]֑oMX2yF{=R[>5*5alz+!#w *R]?8@4- w^ُ Fc+ ^GF(>Wz5Q^HI8;{)?wӖq1GR-1cK1sD 17+LҷQ dWȂv0 AL7!F;<*-f@VdFt$vq7r~VHCɒy4$`b`rP;x}"G^8ePBHf~UfDW uw'땒SD qwǔp7 ubuU*~ U&Xz0]n `7#v%KAlA=3.P"BkNm]0*&tя.Lrь7iDp 6QCFJL,5YBfc0gó{}z/4a' ȁ-lUJz;_f6ԙl%$Y)gitK^ NqlK90;u 4wc&Ưm<]1 Q~zEuM W#.ەKѯ%h5twOy+IRxrp?([,!,}W9RyPAZ#ӆښsA %y8DM @NŠuH bìX䇕'hl=CXû,$ 7J=FZ)<5cukNx]"}F0ސM48zgƯ%Qjstw7jy"8I$|J#|}$ў/ͅ4uz+Bzeh@!XLV{Lca$0rtv-m2 -1F@ Z›:8f76;a1) FX6e F+ie9M|AA/,Dc$W^đxi uI3m(pKXCB:zte]gXQlLj"@nfO,%ʐehCplK JTIrŇNt+mk7H2^R6{':t# j'4s0OG>dy~אS. Jt-Ae)/pA),T[/Y#?*[U U!5QM%H飈6n}$IQqXú0wN?&ݮWd U# jz Ɍ(B8?KMUq[L`R 9_4}J82; #<+J ƳcxZ @Aq}VeoV◩(N0 ,N7L1< ~\J,% I'<6%\FI`hSUdǛ15ozLf=v7ŢO?,zdaFֵ{iquH阅t}<~{3?tR HY m*[C8G$)j)/=]= ̹A0D-I8t&~I]'rۃ^=3AbbSd3de06L_]:Khf&<ڿQpKD󑵽Ħ< mJUlBϜ\ HKwAOPa\'L-Y2.!Wo1ĵhq 4 Фj $fAAT>Ni% ZnO3ĒC@5ʈ"44 0f615|PB)+ixNXiesy. OmG}țT@WkCtU |aı߬Mw^?`MaڵaԜ [OӍNk-[ӯ!D0 wXqG@pn1SEҠ׫U«`.pӔ6dGLG ufMod w 0Pus_xJJ,#Pc)Tf0U- )[Kwf(p}gJ،5hPX``4ykRRt혆7D n_͟xsǠW+A@_ J{G1^a2*8. G%.y' =XN*;)щ(&CIqzf}OeJA[h25G]YцT@^DٿMzC|)r駩D,n9FCg NnR{~FCtb#pH_8X6@׽qeI}8{m.5"W|ꄃ.<4gIc3䳔,+ߘYLcCLF9}ёJl%l y0#bݻ,&yo}4r8.ҠomҼ#2{DY=k@ FBoV0;e-U&hQ[\<Ee9'H I͂*0a D ~N퓻6{p@ sj~.1ж;B:u3%V팄˞'\oڄ_DghFz*6"F-"qc-` @(F@)nNm"Eް#7b+AqYRRN*dM(ͷ3qGD_݇;_ h%iл5I[ )/7OO؜tnZ5EN@}v3\Eb+LIq'Hv`VX^(\k\_}Pm<հQ^M\ܵ23z_(㈨vp8je#"yFGNZ頊H6ΘKY0BrߜyJaƤEbKW1]\=48^"%PG5 L1:4BAa|!2V"ن?rXS`^߫rͽh7'z55quJXVfW{]Xqk0P["H@]"صLnRt.'wZ1a>ZvV h9潆\a2n-\Ti۬ j U%@//ۚpg08-쵟VzQIVV&@.24|Y`'P|'?eyEOZbquw\:_]u~`w4ˋ&79 W;G&5l)I aFM17ڬ9_44@]\=v ]&4K^9_Ah ~s61ёn^B9%PʐW9r5qL_\~`vnǙ)3z=yg+ݩu܀㲘XW Q2:Җ'X*o{l\PN0aG{,.PҴ󴓢0:>ΑCR\Uk)eͅ \}yp_Ҹ(;nSdo9,|8k/ %FQYLAnxÛZ̀ 1 =<ן$gr+B`I7h苆Aj# GirU&2~MC"P̊vs,pgUl]"@` 5cݙv_)Cuan1rܻ:gS(JΏx&?v6fRsG,6=%|:2ŲI!"Lǔ(3z"ƏLF)U0Ԇ3SiiH) o7D2EdZć!pErlgsܿĥ&7 5R]"ȸ{H0kcDcd6s^Wձ)O5#&!|@umy sBU~MfƗ-zc}O5v"bj}Eh" |E5A;wl*ZTY]UFmuGWMDz Ff`΁R+y{欵 4HN1(Vd3˰+ƴVsl='D*VaZj]!}7ddeO.zLQQ#N!ƼѣF4hѣ@p/&k[/h%RKDU'F%!*F.`\/JA9),9 ӺqҴ}#fFVUVVS8UUyy盜ns*sU[ʭUmV2j9[U̪ڭeVns=^79[U̪ڭeVns*sU_F2~u}ʭչ̪ڭeVns<{<2j9[U緷*sU[ʭUmV2j9[U̪ڭg>zׯ^ns*sU[ʭUmV2j9[U̪ڭeVns*s+j^ns*sU[ʭUmV2j9[U̪ڭeVns*sz<<$ᄉw}@ZM0Q^1g ~5HRzAaH#! X/Ku}0L(Qal3' k"T#8M)k{g?`*ۙ f}_/ϬU; Q uCT!a[,oZMǷD(#G31)_:X^_pH[[N8pÇ8p>>>>>>>>7Ygs=ٻwf{׽}ٻwfݛ7vnٽz{7vnٻwfݛ7^wfݛ7vnٻwfnٻwfݛ7vn{ݛ7vnٻwfݛ{ٻwfݛ7vnٻ{{{7vnٻwfݛ7vo{޽{fݛ7vnٻwf{׽}ٻwfݛ7vnolKUUU9{&nٻwfݛ7v{{g0g38g39ٻwfݛ7{7vnٻwfݛ7{7vnٻwfݛ7{7vnٻwfݛ7{7vnٻwfݛ7{7vnٻwfݛ7{7vnٻwfݛ7{7vnٻwfݛ7?*yyol{{fݛ7vnٻ{{{7vnٻwfݛ7vo{޽{fݛ7vnٻwf{׽}ٻwfݛ7vnٽz{7vnٻwfݛ7^wfݛ7vnٻwfnٻwfݛ7vn{ݛ7vnٻwfݛ{ٻwfݛ7vnٻ{{{7vnٻwfl{{g39/O}?UP{{{ɛ7vnٻwfݛ7^wfݛ7vnٻwfnٻwfݛ7vn{ݛ7vnٻwfݛ{ٻwfݛ7vnٻ{{{7vnٻwfݛ7vo{޽{fݛ7vnٻwf{׽}ٻwfݛ7vnٽz{7vnٻwfݛ7^wfݛ7vnٻwfϲ<ϧ@*oӍݛ7vnٻwfݛ{ٻwfݛ7vnٻ{{{7vnٻwfݛ7vo{޽{fݛ7vnٻwf{׽}ٻwfݛ7vnٽz{7vnٻwfݛ7^wfݛ7vnٻwfnٻwfݛ7vn{ݛ7vnٻwfݛ{ٻwfݜol{{g39gԭUTgs=߷9gnٻwf~__ٻwfݛ7vnٽz{7vnٻwfݛ7^wfݛ7vnٻwfnٻwfݛ7vn{ݛ7vnٻwfݛ{ٻwgʭUmV3}UmV2j9[U̪ڭeVns*sU[ʭUmV3*ns*sU[ʭUmV2j9[U̪ڭeVns*s >yy盜ʭUmV2j9[U̪ڭeVns*sU[ʭz~UP79[U̪ڭeVns*sA eVns*<ٳf6lٲAa=…$:M?Xx/Gi,{4P@ӫzܢm`wXM/$0r ”zb:(TcxbF>{uE'8T΢YBrKbi %kc23S5Jj!&Q ($ϒTA8F]G aO=``'ca\1ENhμ2?Rt5S@^%tJK}> -P* ܌^4U & &:EDo 9HDl:=9"jar@,(7l%CS@<~[[ʭUmV3sU[ʭUmV2j9[U̪ڭeVns*sU[]y eVns*sU[ʭUmV2j9[U̪ڭeVns<򶫾x sU[ʭUmV2j9[U̪ڭeVns*sU[;ߣ|UU[ʭUmV3j:9[U̪ڭeVns*sU[ʭy{UmV2j9[U̪ڭeVns*sU[ʭUmV3UUns*sU[ʭUmV2j9[U̪ڭeVns*s/_Y>>>UUns*sU[ʭUmV2j9[U̪ڭeVns*sό?;yoRslJW4GG;yA!x2W"ܞIX؞}A3=쐨9evP(_־( ؘV@kw%l+)чȡ<~Qzܜ[8oR/A衑aVRzu[ Ύֈ:z1HO$ޅ ^ARl&MHxͩo˔7מ!vXdn!j9z\wG[Y(P1T !=~&5 T0.J}ږP^jTi|RQ̰}aL/j/ ĎST1I'(lþhc37`=d ?:UTv㟢~߁WW_-/w`*jF*Q`00NlQ}o?g}}UV2j9[U̪ڭeVns*sU[ʭUmV2j9~UUns*sU[ʭUmV2j9[U̪ڭeVns*s^{<UV2j9[U̪ڭeVns*sU[ʭUmV2j9I󯝵נ*|U^̪ڭeVns>W73)g=z}=zUmV2j9[U̪ڭeVns> گ*eVns*sU[ʭUmV2j9[U̪ڭeVns=g{wx sU[ʭUmV2j9[U̪ڭ>ہϵ{sCsU[Ϗ}>UmV2j9[U̪ڭeVns*sU[ʭUmV3UUns*sU[ʭUmV2j9[U̪ڭeVns*s{<UV2j9[U̪ڭeVns*sU[ʭUmV2j9/p sU[ʭUmV2j9[U̪ڭeVns*sUŀA;Fծ;aIc_[U k6ネ|]f/]AZ>P%LfFqnȯo、p’N|'ʒh(Px*# Q_q蕞{_T5مX6={w[ $ 62 ?&̡cn?4ʻ(y`7S|sDR=#e6ca A`bU~V`D w› DLE*yuUwĒH`|0޵$E}?~=o?hs>u{UP7?߷>`x0獜qŐ8 `8!\A2=d`;1okg}_G~]p}UV2j9[U̪ڭeVns>0UmV2j9[U̪ڭgӟ>a|UmV2j9[U̪ڭeVns*sU[ʭUmV3>[UנUU[ʭUmV2j9[U̪ڭeVns*sU[ʭyO||| eVns*sU[ʭUmV2j9[U̪ڭeVns>^GUUS]yy2j9[U̪ڭgʫWќ9[U̪ڭeVns*s{wǞUmV2j9[U̪ڭeVns*sU[ʭUmV32j9[U̪ڭeVns*sU[ʭUmV2j9wG{UU[ʭUmV2j9[U̪ڭeVns*sU[ʭ{>sU[ʭUmV2j9[U̪ڭeVns*sU[wG{U[ʭUmV2j9[U̪ڭeVns*sU[ʍlٳeZzq>h3!z߉~#yk^v͗7+hm-jpF__kjd&G5|,I 7bu@d} q#Fȏz/#E$~꯳dl5i"ryA/熞̨(/;GjHEn4d-qS8mK۠P\a7ߘ˧  ~](lG77W|`zfEAS?헐ʯNaYtSC0Sɐ225,Wp*Ye 1=-qA5(Q+"U0k L~/t$l`^p})@>C{x#dd UU|g2eUUʪ9UVs*}ʪ9UVs*ٳ` Y>e| s n:Jo}u{_\߶?9X' G@yxK(լeOkdQ5K<Kes}kw۔&FE e}&  Xh"fHda┪(\@jB2@ /??5kŝHWʢw=oDõU~) ڰU !M+IICE1 A}+"(ż(1{VxsJTR͛CcLg0U*bjSlњ YGSh`GWX8pÇ8pUUʪ9UVs*UUY̪UUg2eUUʪ9WUWUU9UVs*UUY̪UUg2eUUʪ9UVs;9UVs*UUY̪UUg2eUUʪ9UVs? >Ӝʪ9UVs*UUY̪UUg2eUUʪ9{^^UUg2eUUʪ9UVs*UUY̪UUg3ʪ0s*UUY̪UUg2eUUʪ9UVs*2=zs*UUY̪UUg2eUUʪ9UVs*}V}^zׯ_MUT 9UVs*UUY̪UUg2eUUʪ9UVs>z9UVs*UUY̪UUg2eUUʪ9UVs? UWUU9UVs*UUY̪UUg2eUUf͛6lٳ` 6lٳf͛6,d}Oĩ`*l沒| r ƏO;Q#+5cQ,Q\CIwK&`̦}pk˳Ş-'4[lO8Ew䘋`@T ƭJL1-;nlɸ >|Վ[۷+փj@-pڈ]bc),$KbudT>ZOSЕ0 !BTE&4˫|+e_}kqtE+VQ_A{@ a [`Kq.y!L΅ofRKyAIiԑi<&n87gϱ~3g x~~{_ۿQj}h(.d5ٕ,[J?.~ݣ k ^1uVE!B@$R*KѣF4hѣF*ʪ9UVs*UUY̪UUg2eUUʪ9{UUyʪ9UVs*UUY̪UUg2eUUʪ9Oz9UVs*UUY̪UUg2eUUʪ9UVs>?_U_̪UUg2eUUʪ9UVs=3UUg2g{׀zʪ9UVs*UUY̪UUg2eUUʪ9UWs*UUY̪UUg2eUUʪ9UVs*w{מUUs*UUY̪UUg2eUUʪ9UVs*}uU^zUWx`9s 3g0geUz3g0`9s:eg3{<`9s 3g0`_a$Q lGR["؇]j%Jdy;cd`DkGDݬ啩e.OIBoc [ITO'7s`f ,ǷUנUU@g0`9s 3g^{|?=i/G̸/;^?.u2Ld4SQ@⽡(=RJk<~d{ip v&;n1dr70P6Z]I>ͽYlUd?he` C܉Od) ,^ hp [1U1d M; f]X˓.CS %ϖʼʘX.̔;}?_BT:c2$ 2j}MSۑö6FW-rnL]p2Pcؖ)#\6"z% d`$YI`(rHqe(!Q(ޮR y6YJ~ALOxg rL<wݨ:Hޣ}3>)h^jBb柨-PWts;#OqiFE\0_vCG<`7`xOpړ0kdJیbgL@ti,p0,b `R~IjD 5ӕ0ēiB +7c` _ v A X1fc$&m4P6"-,DdWU2WHly~UC:\m`1HڼF5Mޕcc-H;>^^1x2=CH|1ԩB:ф=>3en%JFY"D4&}]..KLE7ҙakJEK{\?ޕ5 ƒ]5EDӎlA q2{'(X : ߎd `am'&0_?x?-yhwVh@U0u$X +ba`l`[F٨JUBׂ)0F OXNEn׼J{q kǔ1T8eNJ QS]F;A=r~Maw$9V̓ݰjհ[A;;u/52x>6{Ԓf̌R(ZoyK&>aO>*>}y>/H`s ,i7r f\fIݟ*:2Ў0@pHф)`{Qr pByWJSmLA`0`ߩA(#}Pxk&>2j)/ aí-Tmiǘ%9r<Œ,Q)vF/! J+KXeG球6ɤ8P6IA쒶mV R41RIFzhڿǹ0 PIPtXX.&@Ae?ז FF=>.o#GjIi6@A7Oqf<ܔC o&eIJďCGPNDA!)Q l<@X@FF` A݌,9_[^`b=z߶DxN4_WNN| Cܘ(. 1KD[Lc2:00. ȃxAL,L1ab3#D+PC/!q 8 v@рeLsVX0Z31V Q0`0;HEsa-f:Ql3q]w$Cb0?fD11# `2 .Kr]*5&2{X_=,/206;ar^=XŴ `I$&'h|t3  "')ZX@>8VgH5X0]%v. *O\y,J) ztрX0O(G#jR($a`0όT%wh1 xx@1 f;|/Rx@`)=XAT:0PL&!bM{A < U C1!lK`0 #VP;,X.H2J g+W{8F7 jd֌G8Ɍ~ C,IHGaE^1al? @) ?ԍt<ݮ,%wz$)A6X%.GSn f+.SPÈ0G0ƼY̲aP1L4԰ vGfW @FՒ6$b ްxaBVzAAk.*tb aT 8a2AG=v@3*jˮf 8`&, 7!H[aJ.W84E~Qn⃞:2 rcHPˇF!p]T{()A]ҞjFH0oV#҉"tn&7fC0U:A♡"iލ^9/AV24qnא\˽]xafAA i!,Vw\%_&bYnLr׼0P qFD@ ;e2޶d=,/q8c h¼b@Cv!?Q l(-% 6He \0@xd/I1v諼QP~^ro McFLnH1 {>1bQATl9%$ubsG?P*|PTl Nݹ?GP 0X(nd !.\VpiH #TBBpdQv%fMHL| { Xpqd#P cZ1IEF1}R< <}h ?" K]et  B]~o=6bJx(?c !>7l.uϓ0ZJ\Hi,H<,Q &65܆H.(C̻# ,bd{A_E`ī[Co@caA7>, c0յ nj40D!q0nC"+ a,#Yh|/ @&P1AB82VWP.bJHoHGbn0'V`'KB[ Ak1a1^x A/V̊0^!`$`F'hc qdxO؂ۑiW[\POu6 ?j^b1 .H_, 䌑=% Ɵ$#?df+J6Qv1 !(lVDk&:XO eFTc>'ȶ+vAzqGf0ؠ_$;#XŃaeԚ\asHC, dNN{\'N7% iu < :C3a3 p*c P{pd PY`, ,?p8oq Bzz0,xեR?` $%J1|O\rCC%!4S| @p ͩB20_nWPg/eNd8(:Hk-f hBݔhao.Qbjr jK, *T {\<{>m pF(ad1Ls ]@C hbt H'O,~hb O3j_3;T/^(̑#Q$>C ԏYh:k 1 l䠧/&0[UѢr\'rӘ[r'Wpu!'jXhЍ?`ĂۖPy {\x}mI;mAh3x)cmK@sR%U!46PqG:&`;Ah_Qyre88M}Kw$[9&GI,0@}He/LKҤ@/] H/vccّzAe?4G;ZGʔ[$ S,5:@20+(r# 2D>o)bX & +)@auX;.SPf 4wQ֭]x`0L1Nbpa\`Aݏ6eދ Ra0H { sc|F l #O/^0yr0OsF1/V_ip ''zhֈ4qJ Bh+Y060+,]R?ĆBˢA:f4C:iTr:‚oTlomP 7~O\mdИM2,!ߟ:z_m#HnA0\ԒDs鏺0(<6"mm(a#bX@1k$ .PdCLL]P4_/(a^q>_PXuJ0ipJq_23ؐQ˃&t 6W$dF*Ɉ#A)F}# Q8x IrR|1׫AV)U1g qH:RlH 򩟌)G+d[(2a͆,[RT`XNnԒϳZs):̬j ۃ!׽bvIipJNBh̥O}p &Dw{av=tT+)t)h^HDY ;oF0c$n͏5AZ@ ̠t!)y=QVX O %ݠg3eGDH턜x +vmI8U\2Cʠ'T~&GKjcN&dyEj6E0Zi00'! Hʼn"xAOx6Q)DXqL/Q\8ZR|j0;2~F]8eА#x(zVdLy &"3~4Hk` 3 59ıNЋIu14KC z.Qj>i## pxbԌxa5'?2 Oz T'cSNEayH0 CIf }?LB2Ɲ&KɜqT%}Md Dv|2W'Wk2WQH (tvWdU Ryo @+1i0rqFCc}2zvmk@7m,Ia*(B5B>jj/TENO}΄pc(8q&2 Vzh0_ }nؚˊgԙO<] Ou&Wc~Zćc0*7H}&"4^Sa%Ŝfd; DOkݟfbB4Fis[Y8CMاϱkZjc1Jg0^~ivdO @0mLhzBLER0p1c쥑*wYz/A-پ!bvL2 WV0Q?P;: bW*-TS[",$9l|1yQ@9,y_y;Qg?K)5A*~{o,l,r# Ck+K1f'dIXI=?xeMml/CMԭߧٜ(3s2=(͸ c@I!&?A/v4__y\l =SOɛ5ݻ o+D P0%gRw؀YXF4&(>"-,"J_"w+wAZV:A`pn&a!mTđY,_/v/DDALC/hý/_zN@!*\WBW@[?zLXylEan* 0(Ȋgp=@1+07+S!*U4l T,,P0~Dy `;^/G A70뜆^>?連twƿ V3g[?чu4 aR~&]#ݎD@/j :ApH,I ICAiš  >c(f/^1uJxڒT,輑#`ʐ꼟2;zfe,[CٓYfMT6ٺP˦F!\32$qwX<4 W9:l_);A0_/1g'`;sWUgxgw~U[ȡ끘:%u7^ 1S*?rGE*GN!Xs OK.# Qt7.Uyvu"( .KfZXNDsgz=< +w##| U!(|H9427 m6i0 9{~qh !X 374Q.{{Ay! !/E9GJZ?Y1|[:QnѿmPK_sY-"7Io C;'0F#-9B;' Q! =^8.bU<)CP42b )لT 1`am%eېoCBRI$!6/]:/4^uFz46ΙN^֝Cv6];T(UگIg4s~< i>d366WeM)>Y)n˅U]~q:6Q1'J7A/iy#a;fҠ|r},[vI<3ix(k _\mJF0Gi_pA \mNY >R\/K;-pWim,#߾S:W+`v 1?:Xkyd %%,Th s MU,l#[Y&dlg^ߒ5x&?զam `Fw>SlǸgqغgUfmS};G'|q y]IlL7__孑?dѠc1TVh^^h%6HMB=2zdC@Jh6P-ٯ g[qɐ\gW[j~gFFe"FڜhCh"t$qnh*j;1liV 3&i5Z~R^"fs^ι+(GS>O\҅*]4_[R;߽:mtEzdč Gc9}A ~t (#n'Qt^` WHu'YX]m +{U7«Tli9 )dtYSZWP5=@γ)HA=֛#*0/A-Tk`~wnqӿ=گ!|p:!Z#/nԹP9{W$ܒ܇}AvA%6/ju㍦0pSLZ'c$=t+Gwv BΠ'!n+lKo_{hzlF?p=ȧejogڱ=smqϬ`h8,^~;Aԟ t=.nu:JiڙnK|MuSviޗoDk݁tLt:BqEWmQ#2A$~RO`F)C{C-*ho+u=僯>;Rpx^;;ú%#5iOnϻDV;8&uZzruNhN Je~Z}CqbL'OWeB]ZG#\cWI9d튎}uk\jkcFF@tCͺ"՛۵x8oNC? ^JCU=b,O1KZM@~czP,9]ڪU—4p2SQQsW#ie~! rm2G*{<X@PYXafzNe>FH{}2 %W/PV!{n$u҈'ĥ6j1We(REɐ"'r ?W #j ӑ|E3R3J0`wᅮQw{RGVŇA]sZn9du";i}_cy;-PJ*MD`b k:r Pb BPp klTÒFb)ue1I^豳{2g/ 00ZJS"J;$q (c Fc`b60E7 :ʱ {H0bK,q1!k'ˈ@ABh<rDŗ,.Z@(yA>04(!5Bt3yRbP40lkvoO~ 0u}Y0 b;c hc `b ﰅ, &#U^Q)kP~Y6\`RA${@i/ͤ . Bwr;~iFR `M4VX,1 T1x6Cg-+q!@ ыlgi>@FY҂x҃D0<rxEl7A$f_)M|uP bǦ[ Q $#?>z0!J]i }ڲ,p:!U)~ıbKى2kM0\e҂zĀ E.+&8@q t@a2s؝OkD7` /RO&Y`u@b Az!=amewx\A@Ev>9 A{ f*G/qP`  ?!qF#KyBj,n|c!}sDgpjjv,f@#L]Nr I(B⍘a1- MΤTfzBR `# a(XO`r:1,=!ǦN ' EQ|bt0t%Y_D#pv0 ` HoDLd2 d䮾0X!On/VK>@B,%R&mZ? :EItKB</3F <I` 8|t@3`~g:(B b`N0)JX{BcJUeZ{}ڵ9A:Q1zn5*Z,g8,NFnybὦ&߶÷E0jNnݫ/Cw2tWoipyC[MfeWxxWqѲ d6VEVy cůK%3AE"fcoO1˸/MLew_"c]i_RHo[| J |A^0Wez;_NXd!57S*])@ bm8E# W{d58x! ȏN?O'hftB ? o'ʔWy2-⋓ os<=kC<֞VG~v(%7Qe+QO0Dӄ%i 0M-P_9P7eqYdR3\zqFޖ4QXaCD++8rs]o.c 2sn0u!xA@~y\.Æ{OzRyXW[mNÏiL#-RXC\8.h 62Fb\;.0.y)oKfwsX{8Aq_~iH~?~bD`!'QvI~W Ɛ2pWX@EWA`ej# A@aLDKoCk{Ìa kn 0haR@z~pRC*38.a1OCՖi+Y \a5 F5o*Ŕ./fBMId(Qn79ǀ jHN- C"\ [Wȭ=Bչ/34Ǚ3itv2&b! qgMa/W?13>PK NGs<價DW?\)9Ye-#'z@-p QP3zbÁN@7LQnKT6P҂OGF(s|[S1)2x*6]1` ^iJ#|PeBܧk̈'C,oY0l| _>4n׋:Ϫ]\MQ/^n9 鎲kV<.o a W{zȁh`$ U,I.l\b{we1-JQ陵{&i@ LzbWWsį5#;5N4)0k6'ǻю&5.0*H#>-igƫ(-L03BQѥI}!ʾEc8]JԤ wGdel7u+ŀxpn?لAP,lե"mP731cI0 J7]`Ш@EZ^K</LJ=2I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$9$I$I$I'$$I$I$I$I$I$I$I$I$I$I$I9rI$I$I$I$I$I$I$ddI$I$I$I$I$I$I$9$I$I$I$I$I$I$I$I$I$I$LLI$I$I$$I$I$I$I$I$I$I$I$I$I$I$I$I$I$B,FX*!10/ʻP\9XE tV܁!,S0LjJҁvgG*~Q=SГ*W@[C ~dU94lDw;ۣy<p?xpI$I$I'9I$I$I'9I$I$I'9I$I$I'9I$I$I$>O^O's9s9 $$HI$$II$I$I$fffffaI&I$I$I$aI $I$$I$I$I$HI$ffa$$I$I$IffaI $/~O~S$I$I$I$I$I$I$I$I$I$I$I$I$I$I$L̒I$I$I$I $I $ffdI$I$>|I$HIfff$I$I$I0$BI$$BI$I$I$O!$I!$ffI$I$I$L333 $I}7?1=)$I$I$I$I$I$I$I$I$I$I$I$I$I$I$yffdI$I$I'$BI$$BffaI$I$I$ 33!$I!$ϟ$I$I$a$HI$HffdI$I$ϟ>|HI$3 33$I$I$I&HI$H[ o/KI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$FffafffffI$I$I$L333 $I $fI$I$I$I$HI$ffaI$I$I$ 32BI$$BI'ϟ$I$I$L2I!$I!$/yC>$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$>|ϟ<$BI$$BI$$|ϒI$I$L33$$BI$$BffI$I$I$I$HI$330$I$I$Iffa$HI$OI$I$I$I$HI$(J䀄 m +(=9EޑNX{C;j~ Q5)L{r KyfoYu!cs \7M7<DCͨBJh$:lӲ `1P EnY{喼M[CR/„`{oV:p wÂr9e39Ā ""q'q0sl!שUWBD1 ϕ-Lbiٹ0'DC]'}[Z\Yۃo/}uT"AݐWN[#HW{`^uX'jōy#Qsq[dcn{f|$I$I&I!$I!33$I$I$|$BI$$affdI$I$I$330̒BI$$Ckg9Oy'9I$I$I'9I$I$I'9I$I$I'9I$I$I'9I$I$?#vfNsI$I$zI$$BI$$0xffs9s9BI0HI$$I 9rI$I$IffafffffNsI$I$aBI$$BI$332sI$I>|I!$I0>y|ϒI$I$aI $I 32I$I$I$$BI$$C330׭7Uς/KI$I$I$9$I$I$I$I$I$I$I$I$I$I$I$I$I$I$zFffa$I!$II$I$I$!$I!$33 ̒I$I$I$fff $I $>|$I$I$ $$BI$$C33$I$I$>|$BI$$fffE_?hh$I$I$I9rI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$fI!$I!$$I$I$ϟ!$I!$330$I$I$Iffa$I!$II$I$I$!$I!$33 ̒I$I$I$fff $Ik og]W dTBÒ|ad0/El$.FBWVkΡVw2A)&ǹPSoaU8<̓oi-IqW) 6=#ds~SGHVΌ?Kev6Dt=`ì:ފqițb:Bbb30T(K6PRAUԾ_;e֘Ra$ew b ru&:M{/Q[lOɚ츱5VQ!e6Z8v!9eEXg:T@|~&Wbw(h/ d'{Ar4clXSqK8."XHݠ0Mbϥ&6}nudOC%DgBي&-G(`a$aj=-|?9=+sc.O@In4bJQ${ s;Qˢ#cRP߾PsYgwUZ ԵFaJp~fhmp,;nG. o=4BD5#)Fmf|_!7%䮤P@vZ1.oohO.m̦-aoBW |#`UQ:l0,,RPPy$GQo ] azKkQ$P0+ he!hʩ"hUQ0fY`: ZF`5@+GhQ  aN:_KX):<+m?P-}&M˴[/yn} =^*'yu`#lO 8TX1g[, yȰ~vE͟U֋+agT t7fL!9D迷MIm; #\}Եw]s1Ƨj?^IX[EMޚy~DݷW;|wBJ3q+'9ż½jAa"XD'hz8X|,u[#æ[,W.U}Ȇ9@ ɼkUp%pه69w}fjWE)q6&*U;E!tE9%bV~/cEMLj{Å>& = 2uK\|f- Vny}ulD3_|[ҏ@?xQ.e\|Ǩh,&~03IJ `1r%geq=ao jBhºZ^B =z* wF v@zyl[' 2'Khl&bo=# Zp֨8?_ڼV| #Tz ;G"6cmyY +l-劸5X8t4M YLu|m$ 8XVd[A $Z C,",E"$I$I$I$I$I$I$9$I$I$I$I$I$I$I$I$I$I$I2I2I$I$I$sI$I$I$I$I$I$I$I$I$I$I$I$I$I$I'9I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$sI$I$I$$$I$I$I$I$I$I$I$I$I$I$IsI$I$I$I$I$I$I$c5|ǣ/{I$I$I$I$I$I$I$9$I$I$I$I$I$I$I$I$I$I$Offafff$I$I$I0$BI$$BI$I$I$O!$I!$ffI$I$I$L333 $I $>|I$I$I0$HI$MǏy$I$I$I$I$I$I$I'9I$I$I$I$I$I$I$I$I$I$I$y 330333 ̒I$I$I$fffI!$I!$̒I$I$I'ϐI $I 33$I$I$I&fdHI$O>I$I$I$dBI$$BI&~wtI9rI$I$I9rI$I$I9rI$I$I9rI$I$I9rI$$I'9I$I$ffadBI$$|ϟ9rI$I&HI$H~39s9s!$I$$I $$NsI$ϐI $L330$sI$L333 $$BI$??#)$I$I$I$I$I$I$IsI$I$I$I$I$I$I$I$I$I$I'ϟI$HI$ffaI$I$I$ 32BI$$BI'ϟ$I$I$L2I!$I!$ ̒I$I$ϟ>| $I 33 33$I$I$I&HI$H~Wb?ާzI$I$I$I$I$I$I$9$I$I$I$I$I$I$I$I$I$I$OP333 330$I$I$Iffa$I!$L$I$I$| $I $332I$I$I$affHI$HI$I$I$II$$BI$$~kVqy dC4T+' |@dMHˑ"Ԡe @Ȯ R6/\D1 I}{?[ӵ8I-8B Q+]!%o9p*4yzIu܇/X[Pz}5✡{g,Xֿͷr+ [@?YLbA7g at{oW0X\@Q.Hv[ NVjጰW-A?6h 16bP 0y[M2ter/mv@kGFK]s ?0#{&&޿DOixXvs20ώ B u.Pt RErKɴYI +'7ǒ{:D >ښt\=* F3b@܆xVFo=j؀>@ mϡ9K"싍VR|7k&GZ0yeкfmS!0Z̔tN2A LqJHmrϞيSX 1ʣÖ’HkJxzlœE?V٤ -L D ,E^rO遯t@ז\mÃ>@?ĩHd+6+MZCKl~0 Z>%zs1ء'sCQY^y51N^Q^І1NЪS,1mWu8 i#G\ OQۭAbfd+H #AfU{9dF.d*ub lFzPCFH{M3QpAyDRtB&rkh%AyM&ۜ:yyy}ey 5ԥL"n|v'D^ vCiPQr.@c2~1 1y2{/mqL*a*WWl"~@9Eu _Mh薴ѮN6Uy]N6FB?UOl9z[*kֿK מ{xs6)ZR&0.%gVA߉54k(h,(}l^9W. ֋kۥ| $I $333 ̒I$I$I$fff$I $I$I$I$I!$I!$ff$I$I$I0333 $I?=<|I$HIfff$I$I$I0$BI$$BI$I$I$O!$I!$ffI$I$I$L333 $I_~'~'~'ϒI$I$I$I$I$I$I$I$I$I$I'9I$I$I$I$I$I$I$OXdBI$$BI&$I$I'ϟ>|I!$ffffI$I$I$L333 $I $fI$I$I$I$HI$ffaI$I$I$ 32BI$$CqaI$I$I'9I$I$I'9I$I$I'9I$I$I'9I$I$I$$$I$NsI'I$HI$3 ̒I$IsI$3302I!$I>|ϒI'9I$ I$$BI$?ɓ9s9s!'&I $L$I$9'ϟ>|HI$f)m_zzI$I$I$I$I$I$I$I$I$I$I$9$I$I$I$I$I$I$I=C32BI$$BI$&fdI$I$O>|HI$L333 ̒I$I$I$fffHI$HI$$I$I$IHI$HI30$I$I$Iffafff_1oן?޾?Xe+'^XP췲p)2}dnʢ7ci\! Bg9\iqn$ګ8k* k8H{+FEW3|A"V)oUd wrFw}{_Tf =s YWl[DzU>GGjϨ|2Cq=ڳ<_!rN8ѵF82Tcsp{$ظMPy㣵C7_$Q2$;>xgnj.^kk?$}W[ {h';碌5n?? 򡆭n857Jwks%?tjgIާӴbɪsK6kj\w "`:l]q {qh?a{ZnK傤ɳn ن:DaB#a~yLd4Gdlqƞ“zeB bYmg>> *ݬxXIw;߱;Ե7+ҟ\;W`$5-_P!tD(r|r` +U 9 [p|u_N{ ɘ(-} pSH`cCUI .bO+ϰ0@ <5 )mgG.̓'tRF $Psk'ZR*+w[yP3NpI ^\*K32  sMz@֖CϪ%J`:!zE:YD&뼧 ] 4@ /X0K7^I+^fle-JTn%-gDv^sMC-n9qe ŢⰊn(uN^\@Ia-~V6cynSq4ਊcԯ:I^A\WKk@F9~[ai)0'!ӛ$[v_,oVIng/s]yN7O#鐊= ,_U?~hԜuzh=N)Vi|íIS@\Y׻;/FӨӘS};`k T -b>D*qBna[-IXw+TR29/$2s:X?4< %26fOt2cE|pr_?=Szk9 X~ a| $I 33 33$I$I$I&HI$H_o=BI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$9$I$I$II!$I!ffdI$I$I$330̐I $I$I$I$ HI$HI$33$I$I$ϟ>BI$$BL330$I$I$Iffa$I!$s_{ $I$I$I$I$I$I$I$I$I$I$I$I$I$I$sI$I$Iϟ$BI$$affdI$I$I$330̒BI$$BI'$I$I$L$BI$$BIffI$I$I$L333 I$$BI'ϟ>|$I$I$32BI$$BI$?B'_^{/e$I$I$I$I$I$I$I$I$I$I$I$I$I$I$NsI$I$I$ffa$I!$ϟ>|I$I$a!$I!$32I$I$I'ϟ>BI$$BI&ffI$I$I$L333 $$BI$$|I$I$I$I$$BI$$z>/+|xz]tI$I$sI$I$sI$I$sI$I$sI$I$BI$I$I$'333 I$$BI'ϟ>|$I$& $I $3$I$I$? $BI$$C330$I$I'9L333 ̄HI$lO/9s9BI0HI$$I{T?'_%nǪvp\*;c39tJa}Sj˒`c?n6ק7ʏV-kJt(JcpQv[o00a |J[Y5 pc{>N΀> ;`s;IUOߺ"D_xV0$CLsg M%E3aaH4)g \Pp9:kʵzYg"䝿tGTc+[wNeeܨ 2 p.8{nkmRuv.60 w%ޚ44N􉥭23"gqb=3]SWL+w\wSU)& YK 鈰oA(`1(M?ETRp;xtnoAD\4X↣w8͘1osyɱ\xJ^MTGr8-ɐRkJiJk9>,!ѦK hֽ.#fps!HG+rkD.oer}jf$tGLɕ`Bxc6o6ḳqct-_=Ƚ U M:y2Dx!l+Ϧgb y8Q;CTwg@ xrm>qmSo$p-_4c߆@CuaVBɛZhw1H n[gmjl&S=ɽz¢CzgY]$$tr 1=Nf2?妿q0#,`);RQ?lMۻ} .}Uf>S}&іyM!τ_OսM Ol뼧 ;\ͱn1=c~kOƜ|) Z(MzM :ѕ Ӫg^\t^ו(^O:˿v`m OO?f}aL¯FWAD!=+clA[oWgQd$TyաqtBL|#a:1O̖:Aݙp^lq_MTk ﻢ}ժfFY^ ݿl#p~mY4r9-H\UJ\Q؏|c6l ̐})V%$`MN1=\ɫ/sQ&QP*}Nc"j;">ygDu9*' ȜBe)ƙ]o?K]]gY3}Js*]y/V+h6Q/]#6=\N㪞7)ӾVpiR')nEϾΦvr`'0XDI]1&v_>v^i},o7xbz6^ "c[@!CN])]#unR9Y{;@AeM/Nޜ)>$(gȄ%E_;d[ݾ8@f?Ea/]\ާ{I U+-UDžP mXo%O]'AAgYu:>c]I' QțG%8ӞpñJulp{6_:"< Y^h!/c1ƻV,Z]60cRܷ4aSTQr\5iz<ߜ.fɏ)c&ǷlKl,\4qiX (rHfz+iEP<?''t0qxA˕pϙ1[P=Rv ,N|O9 ApWȵQ.ȿ@s؂jq9#b~ذ` yi8r˝XL}:[0$П7&Ytxt:7f̨]Zs4t` `ÍԚs >UFZD<6U{M/u!erޏ"݀3h҇I\H~^u.X|ǃX oXk'{jڔD@ƃ6Sϐ wM j0KϵV7D6=ԉo lOiP2FDgaAwW=Xh;H=2pP1 V%dq4~ztenTœ>c@.*op}7" bwm-1A1\{Tg[⾪2P*te(HC 7{RUϐ=4p Y>evҥ`5C׬)+ը.zR ݩ25VOcd6*$WN^SLC*}s8WPָJmg - Z:*gOM4ܡplsNGXOoh!KCsn3Z@۸Hyrd6[To:O3\pϝOl4AAYN+NMZ3wc`\_x:2^x\`"fak~`6~Zt1s( jqvSѬ}.,߷G4܊t_9~^JĜ887)ݴ'z1-[G!s)-eۚ LLA|}5.To_jU,՜`Xx_ڮ2~K-H0`|JĜ)337cbҁHM}v"J V3UfcfCU,/I'~Q7%[R`u A ߿.!aca OR,V$0ӻKǶ|6.[#\ӹ!`0N%~?\#:htTCwv~Y~O!7h?vH0~d2зU|jz.ļ8gFz5þOn6aw~~;?{<~:e/*q\5ɛAkD R|q#hv44qɪHancɚ 5NsB3'픨6uV$CS)gzMnWn+_ˁ_vjׯI-WV;rK%qH NCU;͙,"Bt4aK;p5u*>n ѯ8FNi/昪eWP:Z;o(*'΋9۴-TDnE^Zv^T{]SzX륻fb+`G~WUuq2UfJzbg:UDQUg5zC~C75[h.RU)_Q$ jzzC.׋]juY`X~Wb yܻЬHmfm QH +%s/g7aI)H]kLgC1~^Xͼpq4hM]OEOw_L#pJ 7T5-#VW:;֔.{y8/Xw?<}B?{K, re=5#&:Qjm چ~*ЫNd^^FN~9E²) 8b3kF7wTg5Ar򙬁 |4%Tѱ۪:GBl 4><߽䑄:&4V? 7໷ʄDj0d3R'mNI[\f=mX♵bG̀nsC9S&k炶[Ӛt=Bo9NI .jgKaX*v"kAcϞ& kW#FDV6 ڕoްAL̒@iP5ca "{!d(ϡ\\=nG7RĊ_f\rŨGoI'fc &G3~m+En< 7c?`BGo7(yp8?/Q l'vd[,/8-J*~۲QNՆ nѹ ]zX^ :s;Sszt[J\++<̓{5Gs4C[$Vw.25H- /'ZxsN^_SdOO5)6;{he0*Gw=nt|tMR[m<5ޱ29z/g# 'zd6*nszN"]YN<ڨI6bÎ}I;;%_F#Pp&{pV-UuSծ ~`= Gq'Xs>LIGgA)S p=+M {j{V~O+nO5r Vwpwy]W/cǜv|M'T?jr˧v?`Fw3j.մK`9Tp3_~RG~Wzs _NH=zȭ? [P/D]F`4٘;Hz,QͧWQ׵@}C~yx,S9xcoݪ˒n|='s-VQxxsƽ@}>L̠..4! A$!Y@3: ʖA#gLKp|jf:i k!?)` UbFh5@A:Tz% 6q3tjXię̿u{(\%6ݟ#Yc[O|;vMi_ʎ]T'΍$pixo%Ԟ\MU a4cNJ|{D"%T{gzona;~MtZ;,M|}i:F_"w!PΎţr4N3IG8yo{4u_??!Q+|S8CEBd]fHVhx ItB{"<5<o2`q.A߷Y5Hd{[H> ;;"in.yI1wI4U?ǎ#nJRsxge17ns{%,ʻmnT.Yǒ5Ҋ'I6x*@vqQ&"*j2_\|-c-K[|BZ͖TI~zݣfy _'Rb?H?DMOZEeϏCQXGҼ!Pntf=Vͻǻ:vh);-ۮDpO-?gUvLOShD}kr׼rBw @Zx2T57g\_[GYa"|ZJ~4UG<@/S9KF6+/2_8 ]*1Q= 5X?{q>nÔ'L^޶Gy;0WNT u=(jOG'Vz-ݱL8 |iSW_2j&ÒNIMm7_\U8cQ M[lRf3t]}ZV{`D ܚ5/31A<YVm˲:ur5+TH_;7Sؼ{a|7L[''.yZɫ"pfb{14ϱ"^=c2 Uo;T s=~Qe:MB<,iHo4i?=m&c=bX޳w9ѣ1)a9q§캲' ! @!M@!WC!;ojڹiKW[I.)Qy_lG?+D#kr뽶On~IyKOU]* &%=q S!RߖJ|t LgXn }FsG%_Bx>X`H1t?UH{@bEU\B-.n1k3޷5h+VbN^(x^ OuJT-ӯͷIJQgDI8Váuwўot1qWN9>s|5ʺ2I=IYE>jώw餔GڨH4H_eg|yu6ֿ >^Yܬ#s_HL\f{ yhPTz('7Z+ͱOYkn9 u`ķO|PʳqT&hZXO[mqSZ|X=iׁjl IEFſFn|yGo9:1fx)4=I7uXcȫmR0cWm럛׺\HÃ㘍mf{,ES1kv+>^C_3Q|Ԁ:]Vcz۰a>`t <:/FfV ]hLtdr_{f_)TwoHHNDm~ \rK-5< Ѷ?*)KS6]C"N2|lBZ\QNL'hyQz#BG//eZϔ[<Ǿ]shD@ @a܀$mAҼɳ_<@VyZ)h{wV{$L/oo^DNZWy /rdE8+M?#2c oZ|zjjT@qyOү;3A~_de H"?)i>Eի,Jpy`Y|u]S2]ͮ)R~ap̳ryPך]uo %u'^Mgϯzl7M1>y+ .܊S>Gd+L^:v$>k[GǴ'P\e+zw1XC0wmڦ07==5|.+#Yu=;Ԡ!kr-x7sH }9hOF=ikWϝ/fq1RԼQBsPiz+.)CAO|_QROËW8Q < }-ĸ3٪zOx|>IY~dDnR@EhY[[ڼnW pNZ< =DZtNkexixPkq|GV $ǟ|oPsVשqݧ#v ~FHKm)`g~Π\[ة!_?L: aL83YAVj\P<Cngӂ['yv̵F:ZqX9]sn|ն{O5Ł=4+nTPͲBr@vp^ZƗtLA\i]󏬯;qڱNG)a(lRpA$vRGnB{Lݒt\R<8pR=ycLkmn0IjSS-lj!ѧ?ߡԺN֧+];D̤goi}}nUuB򟅩90[Hm? >KQPq9RzmR}w5uh!S@Bl$qo;kBr_lfoiimD"i$=u1O}ejYaejEbK,+s@az'u>>3RDL^x$3||gv }e1+:q gϷ8Wqq6@]\>:K@Af߈ߟD)EFcJU&e%bON.OSsp5r}Uw^BODT8󬒗6Ӈ'QWA/o0ž&WXQ{7kld':cY6H&C_ԗ cǬ5P_ E͂|)m lpaRչlz0ǤpD\e s`s|z6 υt4|7^\ " V#/b-mC?)@ -7-.4v2@WZmޮF"y`#\Ih6`$ʕc[n0A|Ƶ&^[!?y=6? "N0&Uc4 ~SQBNԛ[ vm}ΧWmRܥʿNyw2RsYg{}lV%4_ٵ>ٌωߚcv!0dgdո̔6Stw{?AEArjkL|ޕ=rd[}l6p֦N^߈ccMj'P W8}$[&^>®w$QkpywQ4P܎F7";ƫHZԲ2ʇ e+cGd TSY{ʂNFL/j?e^K־m 7jsQ7mL5O<}F_?Ӱ;FqB.bh:n2H3Mhc3}z!N:o|Ω ψ)Fxuh5r:Z#V9ͪíT.='ZwgZ=3|ȹ#fl383,^OUPz7/{ש!Uw_ ogLlOGVo7O!>tzoUv-'r ;]f޹yݎ^o{pP`egbn{FiN]3'^fzיG~` e]l^4:|'|m/d_ZԀL:l7"o^ ~N O? r{V vM p=Y_=헩5`&$ly8A>ocR?ȱx+3Fm׎:vvξmVf1fG>gA;V`;{ ˪+993S׾[TK`gSɍ?|;=ZOe{ 4:&=ɵ/Ou\X]wӟ ZR.bo=;F3* |Z*+'|4':};\ jD$g3-ʷ&E61c9ewvG]oꥠ.O\Z@#.}>*ձq-'2#c_=Y[b n,K{H_5xV<5CDg`}:Yca\v[5H1~_Vq.f1JemٿpZA&k}hi,q@ext6UEs|udL@!;o>ڄ#ϜjD&i*z@UjW6G}iL)҉8SU,AUn>f|ڶtQôѓeuVvM>kt[WTx2Oqoa8϶ԻNy8lv4r[(]: qTY{^k]>asxqRqZZ";7uh]YJd<7E׍n?{N OFRNIENX"x Ajk>v*3Gd ǔ3e#ol sUK+c*J@` 6H_fR-NfPM.W?_~m =dK*lyl:Rf÷ȟp$q7Kz- N (-vzmqX =߀JeFZ6@lH4ůt^˧BW!wL"˴HCYVT Sr]py}O _)GoSy;-ʪ"",! 0@y_P=zy6_F7?1h:c_`-cAtFNjt[ٙl:Fýp! [|sl7U@kMSn;Z{^uI5 K uZ6ca(K8/gW=חBy?_$n.T(a8օ~g6{)<7{#KOTDmnrW?䤋E潯Fq#n;üofNr ˿Lp#8K!a¨BkH;Fҷl9sm2Vm5\-t?~<眩]kk^^aZcH^BϿy)Vۃ7jy&5+~'dվU祅olOߧ;VNJoz/Y~'3?E1<@#_>?sߴP3o쿣 QB`5o:$bx J)xU+ޝ`,j?/nr}9=efo_kn jXr͞&z}UUqL飞ͭ,B4ջ9{+xn3M0-"ǟڟ'96pS?tLts[|#2B(|<Ӱj-3WTp>:Dg%sY FqkQgs*/E_cdY&|[^[OKn筤4vna?>AX|g+` ȶ sѿ>oۮQKԀ0m?M~Vc:*~t㬣s@]ʀbv{|Ά4O_y=/ wwHkVyץ {^9^3z>bÀYnּg^I"qBI%5[>(x4N>]KuLJ򊫻MݑJyC'=01Vt^ `9)몇:ҢGϽxM9 >Su{fv_ګ쬅VSr|?˴%$م ׌@wR^SF:Mt'J8ZF玸WƏ8Uv<);An&ߝ¯SsҘez "9uSx6RzlҖ,9yّCC{wcD#~x!=)KB+XҸKJ=! fg*xSOV]16O&'&[_G~H´yY*k cW_(b; lt"L&uk,V=+*lzo` .P~O}FUK:[cƔ$\ZggT`:eۻܰq?1sՠ &sX7prv?MG%~*kmJLXX"a5b@qHzdPpBq@ _t|oE%?S[QCr_ckA5txw{~w*)+kSA3>XS:T͵٦4SdΟ{t':{¸WbXۓy6+8>/!)7wEʘ @*x=v|^C=X%w2̅9~KE[èq$jlb`^v?0Mww.c!;;@8aMjߡv;PaEfC Wt,#ӷi"l6Y ?+^]sٴa^.<]Z͝[}+iK>cVBΡn)~ tzw_v떽 N[-eKpU{U B{x!ȷMʶ5FƃMapYa˓L駭mo]5J3w_֎)2S_kmKTquB^%,x]fk ytg@fF@:+xÑHf)wX|iT1 P8juS=@һx<{{Ŏ♂7 )؅34$7~5J\ʥl׼.;wcwk[6i~*%#1vmFڦ[Z ac5ӌ/j1澯8}\+=2`zfulc(x ߁ߍKz&:#0̘8Ik:ISJJF!7JN o\\G f#>lwKB@t笼ZFv2./|IBG"Yf՝lV}<z`lK;W:$@(M? ].V #;i1\l)cw<ͬbC 4nM{mjw4uǐ>rfj+ߠ>pPݍoUqu>uˋSDw,o]<.J}׿eyKį!bG|9[TOHcHwէH^}/\Gk̐i߲+h >BjQn9qJd{(9k|5y//T,ۈVT㋟6!Arq9 5nsKsL@9. ]#מ|o:3L/ONۣ'PwUZk<اn"\}zJ^ߒf~h@ M-@#PSVQ-(%se朎>wk0cţXUc$F^/ @DrĠ` BYq45 `5=Z@Pz[͆$=zYrPɗyq%1C){J˜z}B.Y9*>=rI z|*G w?F;_ߤ-]Xo'f1/OVAz6 8ƨ}^6;imFccx>: lؿX[O!%k~72Λ_w(K>Y8R]smПi=]KvׯEDCMˁš:Nx/eyF_R㱜<2'q{UWX(m6D26#RH3ӷ>bbiʺA#J>zwθ~+~O曚֙C*˩-tsҏE50t908UkVo,44w m럺@6! q'=ed&0x\&3[A@ ;J2D'uciGzvP .dav$6_3MRʕ6:|rJRdoB$xUâq.7׬.7@=o1d1)|kF>Jj3~}A>"Hc+I̋ÛjI.RUQ2W]~`=4s輌ʯA#;B)~ת;vI9Oh[\:O#ݰ{.6=R#Vϝ 6C0:sP3qy>E6P oq@rJqن ZH FKg5\>m,g'7lzą5eW~TСP Iu%^6=%I$ͅaiuE d;R#Z_oBA^7q"{ %:&@2bl@Ki"Q.☒ d A%-0 N})1kCVW(7#F0vKb SK}`+ Ea;%{baa,Dq8 iE%Y?u%Fc6?VP)*a?;4qRra+FJw{EǛӰ4 0V (aR;"m;%kC )=e&c ۭ!H0 :͉pꊓ21 oړWjJQ~1(8AKsP"8*6d : mxDbЬ7{o+x>p[&`  N9=qm#  ϳsf0Z;10vXć;hi#4`0zpCW' d,y5[C!sX6#mQ/I}1eb,TH/%ǧȥcf@7:EiJh/u_f "TBpN 2YIVh^ \]4$ =%3F5DWn %R1K!PP뿆*VϮZƷyl`ykI 6r+M0ļT`iG[yS`nT;9|ƿ[T]o+6 CuúI#QM HC ?^Sh/~N=1ʨk/{h#h}9TϙUoShB ooH+<|0Vu1n'OE}-m+3܏iXS--ڃ)N ƢU969V<Ԏu\0Ǔ$~v4 DH5, $ ȻB_6vm8% 4HF'>"nXe?h3 d`tqCw5oi0(~02M ,ae@+7 u_,^JRí >h:- X*J~!f[* g ?%.`vcbJ<IJ5v{.osv[4yTSŴPM=MTfh:JrǍ" c-?|Pe3"Vc `%r6C!>igINUO'ՇK!_Rri;2BaX}^Asqص/US^evFΞX"<_= dtoq3Dx\d^XØD$AU0@ )(I6M. `%%q &ZEqJB] - $3g9 [CA'фݿcy8H$x iO0 c›8J*(dl 3PEOːQ_Op;%}(^ґ;* sv$phI/T,!׍0b ރyT:)ME7QDZr(a@gθS#ڌ4zsF.Q4&X@$V}2Q88gZ*Pj1Q *g0@bsV ; AO( ^WLΌl?isζFb\ ؐT‘p -HԺ' h A?gTQa7\CW٫ӰMâ8"=:ց/df{&s;c#ϺХ1l M3l(#c njČXcތs(|RW":*oCԳۧlwF=N`8X˳2:9pzใGE9T'8 @Y NcK.L.0̣2vk&Ӷo,Zױ,09;ViJ m|G^(OԖQ@n:?ajJ Ge9ݒ~eZb`o[6[8LAwLlJ09qݴ{~L5ނr=#s8lbyWE)=N4G!shݥ k蕼]!<4z iMLh n9f:ݔOrRY2AvNGِ`zk-fF#2 5FWBv԰嚫 "sFRg}]=̹%YݦwermmȎbu3C,3EPM<Q@A/f6}Q. %:m,0gP =ܺJ# /vө&%:   aGfIX< f-Gȁ_;zd0-$ /  o%2#Z6]0sJw` 1LAސJ?Vp.` ffLf 2-ɫok=w|$پ`)p#=Y D^ B#j` yD^.-Zmy\k|u"Bc@#юpr u|V/OMCW^uL1 vL#+N3T_\r§ЄP=/rEF dVO,KAA@! ӣF|V5q5 8#aG@bR+vM@);m'~0i#Bź`#># P_< <A=pgȚ0Hrg4dJCoew*1Av w] XAZ1LOI&@~@0pe!b QU.-@ m*y@0y7?0bH`1F)B 2 u*g/&Q"ܥ!jHc9'P0Dzr# ~az!tlDjP^ĥ)`(Pl>;ϳ+GYsAQ*2*إգ)⻯h;4̢{4w6eۚq@b@bB`^u.a쫝 0et@A9(vApm%zMh)i7` (]_ˆe>xSWÙsbI!x8{kwOG%wҬъUTNu/n*gg q&a~n`żZwsڦ=k* UKod4<8jXº9,%aQ]_k1ٲbY2# /?yUUԅMk>n8B_9zgkT(0LYu?u!X^폧Z׹a ? Jݞzf屬4Ӭw72FٝυjLjn2)_#P z{l68s;%-Rk;MOdAH ?d>A֢\?wlT*,98T[F9w:K5KE,5H!4pIh/My3/QfM7Vr63:J?/Xq~0rO[.狾:9YcbI?-.¶ś+r~5~_Xl[K8=)L,ף1Ym>V5G67?]SrGNIa'vYhAD1biujdW"Y*{H.8m4a}4! Ӗr8&wiܚ yTN>%s3WOH;MQ^Ծ^<;  עOjJV__$3~[E&ȫ%/kKjP;N CuUQͅ!BVqw5GO/ }"ś 9˸|g`JL#08s W_z?r&5vVi2=m-~x@WƹHtp ln^TC#Aռ4.R~lV{&=CV/ixq2s0Hu-F$4#Fܵ1Fb*:0s0 ϞXo-`ZtmC Gp -o=ŇcI4b.?2u"T6\1 zR;UF$|n'"ZsC-[A%]q/軏V&}P”F6}㷣wYظ7Rg*nhrV TҦ%jV٨l`yH!B @ os bJ& ۉz [tF}k_> O c7_!}%]`Q?87',o{!GP?G|S)yS]X ''+V"@) M)Z|[xNcэ'38ZMJkGRwtOsNȒ]e Fm׆רPW!Ƚ\fX7IB}h6ogi =?FoTl6 o=B-U⒱9j& ~Tm҄^sg3^-`*ghnSg7'ԝgIL|C,: qD!rk+݊n)㡗yo)b¸G>٦WgkR'uZ p` 1~.Ei|S ~~ephr,k!F@y4ꐏ=~~<v0NHH`,ix.8L<{TRoG8:d쾖"MP:0א6`' i{ =p Ē%2evڰϭW@;4ȽN檈@|0]y|kH0rEͧz?Կn󞀀'@>//M| ~f+ec kZ'fO ~eӯ$5%y|::lsHyz \.ON:w;txtj3P';^zB ]OkmK5R$?9̐}IAc: ^OYy_NvǫO`饾> nӗgP!/r#r[~o8ڃ:?=  2X'P wMoMgVVp^ɩ G_ˇ7k4{na5bP'{˭I%̩`^I+Wї1Y%-pYU7 v% \TKc;?fݪgdiiWHҠ}t9&:9۾m iOPc{RmI*Jl# {SXOusBU_Թ [~.?˟YVZͺLcC~[ayϐרʾ.eSde#,^7W%AG+D=j!@KKelC/nV㳕ixLNuXY8b7zg'?&ǘ̘{VecޥvrJzD q8Xo (jKYj\<* 6ɻQۚm禎57>?tDZ?oQW#ca{x8/ҩ*衡W G}qT86X/9HUy6M;J^lz+GN\JLd@UݿbBf@eʎdw吸x>yE7:~/roӀ}?TS&(pw`̹bq /#[i !!tc/8}a.vw[m΄-,4KmH{l1#iG>%5+ٹ{ t<=jt 4^ V-?~fE%G ;Ӟb*<_@5cn8<7u:M)ſF qT?or{k+:W:'T_gCG6UvSpemY99.ρȆzbo:)T_[*tW"NjM`Dk6CҊtn5,o14>zUVN_? }أX{_8il+S)<_#h8;WUQ]'?R]qnX8keQ;Bzws )IRt,OxӶH!"<7]ܨ6"7&'+2QoMuդ{IU[iLJeqQ֐*NcR<|6,.;{iv+8wUwb}J:3HB}Tj|58 :]n)з4fY!U}Xe399[{s VJ0}ka~ry8TH??4ǀ #?NbƲYWiӾPߕf )9@{BU`|0x2%;YǮG?s{# wj24_[S4yz,\ 1?O:]4} עlY#7˳ObVNݚ ݵ9 LdW|DTܥg}#(EE~pe*%$ y6SzK&V0s ??sW9ϥ7L#'.<zk/9v~Cc^RS?Pj$1sxK//1tv.n;W#>y_uܟd-?eraZNh.O ##m'rG!jyP3 }I>~3ݍ(%R;up_PD5{x+C?ԗƷ3KCo Vi7}n7?|5 b+k̆Pݬ{['a}(r^aR&:!5:sW`m?*|9;o\r2Vs2DU騺bxW>KIlvҀyM99+_"+ =kPN}#ЕW{tg̶K3sՌ)oq2@j#*fgƝQAz)jmOF_Fp!ch* ?)PuGŻniV5_dqgT i] h {TK(0'%:R^'j0k[:_ںMg%sfVΌw:´(QRPԮ CwnGGt<4O^h!"on8wҥ?idzϙ M SNi=qno4+6=)̭lm*] 4%=: oM%pzSj?y죥>@6B([5[xENzC.d$r>DG֪L;p=eetqL]by["t=`! T7w4 /(G.n|>/͹M}ƟnOG'3w̼u:~I@5]o~ـ|Їm3εwAm Ol6d=Mu{>dIypkQ~\2CJsС}gRqήv²b KzzODUwb2Tz,ZNffi)/8؀ B;\َKrkSoHYeTs#ŹzGSU\coK> N)P < ) ,q}7 kvpZ- F*Zt?|]aG#뾬esE1\B'hcm32/e态Ywd=kͧc|DztW1 'u'6-XCSWqSxze9WidmdcjGS6ҼҞ?ME6!HK~o_zl vS. GeHVbm)ID42Gz7'Mw]u#yc;uu1eD}Ć& OL/FY/p4{UĢA}Ӣ%|.~7X換8*,)k-ݵ'~+D[O0j'Ϣ*΢0ZkVZ*ܳeSQg̾jևiN> ޸Vn#U9Z9b>qT0v x 걻eWAYQcj~]~JI|OM'a9F]s^>iU3Ϊ`4 Cnҕ-t^Zr+(4=N_7PUv~[Z8UV5Q[OJ U#[]_S,ڢ#[iF12x7Fc݇ 9+6PAS@5J϶ B⢉YyѮ\~"pxW83Bx8+0@N!rw&j[V?kIxl_<,6lzh[gK԰g ˀ?tz3W=*NTu;bvyjLS493?,lmz!ج#s&qҸOxDl}A &i$vJ:4rueCCL^o,M᱌~&:G$c1cm*"{ٶ0ڝ7/D}Yklǩ9]맛& V8[X.ZNοݭ9?_֛n)+Y=Ih(ͻX _6ăMQ,Zر&_ 7ce8B}T_ 0woxnZ>}ή.+Zvq`=))VNw8 ͧGkOakv퓸[['={F}w9Ԋ tPOyģwx-i/uVF.zҜq{ίYemHɕƟ_o%y]5~܊ ;D'yc4ͯZ'Er?,k &zVTd֤mN JEo=V_FWOŽ]ȴ.>~&ʫUYso}l/b9;޲42Q7iƸNXl9p*l 5 x|Muw8[<%%yJRm58,}k;5NM8*7w__(7-h_{ϋ?{9\ZwZ:3ߨ-V}~:llλ 7Mi:Rß <&C噉MQUIM~m8\;g5j*O臍`mvlVseA?A Wjt7 jý^3~ف<̽ d^b-.R_v;삹WqTٚvnMeoC̵v\JJ\iv0Eyɵkؿ*N35;'?}c܋mq !3եm?<7b~ҞcmHl,u(_|}Σ/xiN@NzDoNZ"7ǜqA^5}*(b0cxa:tpn̼o8{DCYmK$lmUyΝGAlȒ~4&w{%jc%wU"v?*tog!8nShc΄?~3ㅹnX,w3 6+$Z Vf_ mxZ۔f![9K Gbܟctk=$ aA6yb5^ .<D>J̕NtׯM5|_C+[.?DӾ'q}{Fm, Sό=1JRÌǧFC TVWϹ7DzpP~k>#O^Nv:YOlC׺FSTe٭jwMm?4z\k y&_wgJ2ծɗ.Hm+Zl{bg1`%Xw۬W>Wa5HWJ]f!g1|vY:5A*#ws ڦ!/8Ah]Wl֪2|oSͿ~JٓSg:s=([ *2w;4JkrvF tvSO}QDg^J >u[bQFobmHG ;}Mm?OeT ^|hHb I[\eֻmZvx>-HJHAr[QMgp xx}[UC3d?ذL,<_p' ˽lpnd\}cJ]<0yQyu<74.qW.;+lweFM1SPjd܌ѱ!rW7ʣՀ ^Xy{DN)MUZ=mםHg9\[⋪yw2?ɟs;Pvr2yUۇe&ȉXf[\%(nwX4l•b U20USUn^"ko1 UrJ'0C Phi{|oV9}ͧ^eij?[MӒGys;%@ZX&R1COs̷:Y0JƊ66+EFh|Fm-|@ Bfg잱ѬO L^Pr/^+:DI4H~ʼn&ʜCub>i?[qբ׻pV/"iIy>wf'&6j?ic{qKjrvl'`Tc2; %;8{x@ԍ{R\ڷ]/8 ;JO{ٻ`sYASA-" 0\Fa1Aͬ^6?fp7ܮa KQtaiWm73f-',ϑ-ssoP+pOv;댗,>6^ O"S7  % +˿s{ َn{j_~^5#8GV^&U7{ l>.AWsf^oC?K:μu>s)1~J  q9eUOf24摹*MJOeaF@ڞ)H|1F lz:VPPr<^23EqpF^fxib5HL/ɂ+Wg#a~K?p/*.)^k}5qRrB}iTeSI5\-<'*;8r\*;쏟ZZMjU0e)tw5;_}{̗?.S=A 1Q/HtcܩA)=VGԠ}(z[FL3zKfZggw>_kYnAn&N Broet<W3yA}оw<~cĻ X5&5{A72e[ -L:N 8.zicphҧ:k}q`^ٯb@H Vg 8.tI>E=M(;c37[ZGw1i;n|־7ϛ_~gf_(b`Op*vw}Tc9g۹0fBf@y8%a]j&tD1m+O:iR!R?(=YgJ%Z9(?qƠ^G)rll!ewYռ1]Uiu/v{kknO kj@f| ]x=>7~cݗ“{f}*Ngܙrxkuݳ Zx*]К4;98u!#je9Mat nQf7mڦ%wkrJ+k!fu< .oS#J='<43g53jc{& @Nsphu7]U*3ͳtec@!Z~βͻEVvڸ~mB}/>|a[5αõɊy*G&0Ƅ] щ&ij=*uOnwSʛ情-S ;>k*&aW>a|#[tEc`Er{<yxqY|9]qgNxu2 gk^wk3\еiBY{*9)f%i,4ж3~\?"mc3jl&"7gi?-P2 Ɩi5r0۳lV(xZ:15meB9ߥD-˷u0^>\ζōݜ)vYZ Rvq5QxSܸyAQ}kM>7^'&T,Xkڲ~ZLA&֝ђN:ݷ]'uo bw;v7lTXVܙqNo?m&D^TS3Qaj9/A|В5_/5>& ,'{g+Q oI ]>ڮ} ,e[!Jz=r3@]͋0:/!RyOH2xG|."Yy)M-YI6?Do-v8)P,uefl~83ijD_lXi2.{Qoy]\߾Sr<=>ƶY, 0o ߛ?oBhA۽ /2c Y1M*甡[e6y=,'"CҤRXivg7Rի{=pn*7Xo;>& v>/?j#_zM-)mE޳P;g EA(h=-RjKJEzqcOUX(-v cCsVn![طw[\uW~/aY/at̠REl㷑Of`bty+w[N3_i߫5 W|no)WqXYVx!\ycn ۔Uyfnbgd*CQ}s~oVn-Z<,MԷ\:IJ }#aoE\#3ّXO?ϙ|R>&u7k/ 2_٤aZ콯L| @z:w회/w^= `ȃnpNH$i!sh?Go%4og7͛o1ߪav; ߛ/ͳm0ߦqٿve~57l?HeSg7<͇.Ϳgߧsm!u@b`!b`$~I'ST~Dlm];N K8/=u չ~wN%oM3;hӥ_Z h9@ @lo~1ca]w?)(a0 0`! LscY ^1baE21Ԅp:]sE!*oveԢVW});kh/j.|ycF!!5va͵κfvUeR[Ȧp"0}_u!|WJ K۾WߦvP]s߫nIE3hh@) K>K8~ F[U;n;[4l<2gیգI05~G w}vyetro^5_ }9ek9ؑszFk#!@y了ӽNUmEhi&>RuGƷ94,'c3VC˂~S'leJe+ڲd~P}ERя(ds)?`@¢PB*WxrQ$W.z@!*Փ)_ SwU~t=DVޑikgIަ\jo6̜4{k \@0n{\Gd-9zEċt=;ׂYAUە8H\7CxNx\6 $>X O2ߙLβǦKWl j&'Coqi_QQf5^j4F<ҠߘV@!kP[GO,Lj31~]sђ)6I}c/Κ ٷny-ʠ׹!ʗJ'.̽)곾]x BҢǝh*V$S ص*?0 rX w2olusNj;p2]w.:r|r_E;c^ 5.<%bGpj<` kM"eUDžƣwjj$vw(P }$z>t_:jUFBbs>!!";"7 /TvG淋stkR^=e=BrkЄ){ΜV5:Gx`cq14K-ahEOwD[-h3ƫ`Szts=ET{L`8Эli5;ꇉLL&sq)[ΧVu{lP~|HŻCW7v:fh @Cw2f 7r/zۼ*zۧAN?~ I;^I縀ՈJ%az6PJ}̎BxG'?l W`FԐ DQޣz(ۈ+S&H{bqO2e˃OѰu^2eϷر^EMdn&9_uvE'/:س.O g,PQ $}) ̆v{F2 OqM\3nR^=WSL> 5޼睞ɿ} TU8*9X王Ŷ>Zs\d Tϩ,, ^ןpua '_t'n;[IhCSч|H >P R>ʧ5[ kǛɨj>U )IVB݂yuvRK.%1i*%h].@!R5ZE\UwuF<ժof(ttm)yr?OEeχz}ñvƮJnqktOV@6Dp [&:jU6ikxl^N]ꇥcoTQuܥE6r %WGόu~ru͖>vEgmRۨu_mZ+ Ubڽ 1oIh!gf<>%Vm^h=>71lzR`9:[,.ņʎ^¯]=-e&35$;~F9^ z{pWq[f5X\"ͫBڥp{1ƽQ*7vj )M<=3]a7 ʮg\-.4y[Z*i=ɲx ַw9 %Wqw׮kAjG|=!E[-:1Yslwqꐐ ]@i5t-w!q ߗZȲڲ3~Q gޭ[6٫1uDZMn 2QSik\#CwնY1e?ZރxD J^֙3na 4Z^$1orAY4Y}^xSRө.\0xG*cI0{:_yrԱ: Vnf Mp|ڮ-Ra<~wk`5?^o^~7g:sFk{|Ie@iut0XR.fλ j7Y_oT r3 +pSl{;,7|j $go1HYw@ B(԰J%p0΀1ȼ{-6ZSbm'^gXg|*;Lz?Z&!;h/#M)8OTÂd]gSH+uSvvqOW߿1HM0M_ 5;֛ 0Ѻh/6ovA'Ҷ2pܸAO_ OHAM h/.&0RiH6NS\7FuQkÂtěago\\ssWٺk߿Gp{+63 Hک?ĤM@AtFFG# T&%5 x;O?rДfs;pSTR<4>"OrЦ 3n8 o ?5מݚ%[g*ٷտ"OYӒ~Iai]B έƁд0W丶h'(Lץ/MNkfnIcHken>'ϔ^ҊSWcyK5ٹguSiAKZQMrN5T bp;UY'bǝW SfZ藲N4q(TiH'}Ŕ3X^j_?~+//Z-=Yw>6oI$9Oޭf;-H3]٪[eJ3\uvgq)~+ w݈w|=gv⮳6\){ tcG2?t^kBF.3Bfv_&+Yע{go/D&vgQ\O8|U;7Ky+n/q6yTqk(kP+AmyzrqN/(D_`q񪞮z/lMN݀2/W{=t7,kl|z tw,|B7O\FRAUCJ=BJYNag[hTb]BtMiE!|WgV\*2yxבxwF\[z7F̝ZN g^$.$=vdžws_R yo;5&IXHZiO|"_`ۭ6^epj{%Sw՞N|1RgR:#*iޘދseo@'.o0 GM8Up(rkټfs:f0#!mڗJӬg&듿kܫGksFO y@4aȵqʐwMrHW8@ 7#?h\q[-MĻo8n3ϭ[tHܥ& Q˜/݆=ZZBw}qûRz,e7D76U'_/o,JCrA//kڜwWoyw|a2w2G@mk/boUo'q Dqv2m4%*zg& k)we'ܗT?-ccruzǀ80w25 Cn˽-~`8o +YwplϨ܍Ϙg?;醣zwcWtP@q:> zYZ(&֠zSU仏wIc'q}E9AJ63MLDTtjp ߧoUŤIkk-EP3G-$z-|Z Gxvkz:BOϹ:Hum"* ԏZou-0>{`^9)s$,S.C9kWpeGf`C)%AY|9 .Oĵ  aD᮹/Ի^8H YQA&ND"珞 Ć:k1`ysc[i>KWiu].KW^~/ԈZ'ȟܦ͛4GrUB|u; =ëpZ?:eZ+C$l BCc>(1_:z59wE֢?vi԰xJt*&֗RjY/4n^TM=o-+xAm ySw1*p]a}Ngo`k\S8esp܏wqhd-z=Wv :_9TҖGyu_ཋern)-P >9C v_>3~[H= m;("~W3MM璧L(R|V2oM?멯8TW<vJXP{w~&rM{ߗb]+p϶AzskZN>rPS;*M~C[ uac9ث8w9cEyq@"gXHbjL輸F9$fzt k>/@*o9ʃ 9ߠd=Xwu@t,1忔^4 ӗGp.jw13·tT\KsJX/ƾen}1**XY'/}:fbț ܾ؀}7W*uul:&Q5&~BUsgVwU\=l5K+KD3 >ΪPSWטr7gCOn=;IQ ؀\:͌\wҝsJ{A׎ˍǟSGe`+i"P#:Ű.Gn&уns-x)d,r&# ъ\^rs-x[F ,+BpQRt| B>"'W_qHJpNc);VwX4.O bYe*Cʃ!+܃uycE-EWe'9b̸Zqx-hg!5q2=+sc m ]eUv$!ds1s֎=#+Z^L?>1f(޼Ru;rFn??]E19v:pςD`5>.I33c:,ݬ1|5^H xiבgH祘M/nd3.t=8n2._WA- .NM$#Q՗*wiX^!56̟=w֮^=5B{UREQ?*-Ų5_ސ[Ih9$7AtO\X dJ_ƾ<ƔN] 7C Cvlh7ZwNu= R vǕQYTU:_@-3`=vѾ ,^HztZ"Pb}tLolS;ӷiMi/^+9ߘH_:O!Cl USi՟Ge fo_FYˏ}F6бkk3e gLXud~DŽZwI繫2 ::bsqQD$N{bOLH3Y3T0F>fG%wcT絭OM ^~OVK]C.BJr^}|OUABH٦w[BNCrOP|1:[3<9o%h3`u?.jPZ;7uW_+g9Nd}x;ƈ޴i<"un[sK,2-z4HB o ECykh5.T2Ü@wj:(8I\R Okkm7Aݔ}>BYK#ψF DB`ߕ?h[I9Ⱥ+op`wIlW?ڻ]~/垔c1HǍ֩;jOhE%aUI]ЭC \9N`q`DS.3Wf@͓E7m~'}Xsg=/<-^C\FRid;^G}30\"#RД:yjm.7n sǟܓ͔hi28š2oiԃLq=!푭j|yH)4B 2K*1G{bG3*_gr\G5o13[Jɦ Dch>j/LQt߾<|zRuIb>Fݖc-ù>uFݭ>XйI+i<ul FAzs6co{!$0k (BEJѬmu!7JEcwȞU(Nѿmeف809 S$Ngs&0ϞWa#b:{H4[GW ?0øv+"gǦX6%2JjJL l97XпMWm* tPd>vݡs lQ)-bȄ_v7\=q+ E(:0_cp<0xd  ažesw6/w5-M׆& H (<^hqi)kBui*d3ЁEJ(?.;5ۑfwWY3G :ŷCǭs@.PK>_(XmR.MMj~3Ԑh!a0>*< [O4Jq7/N2dB7* ʻi*K~tWdW.; STgdSZ:PO&"M]PMS:#ػ~:IZ_ é;A~fgL}fK@ t;4ʽʾ^Gdl,6HqIK2DIx5s"8`WX#Mٍz͙wyث.z3{OHP74#%?A;lya7k|+̉|1$vl@(1(!Q Sy)`!\Rci@NՁ2{%v6L ͐]ҋ;1#*; .NٻXOy{vFu`bVu=ltXtzc}07EGF>m{,ViiZ [mjSyv%lkSmgNet,ԍp]O}a`b<[èn!h&Pko< @>ϳa;6,N9/#EKwziyk\'E%ubCN/V@pA:SVyp~a:f}{AB=#AP0] H(')Ue)NC܎~ت=}4ԊŠ 4]"E(Ĉӽdy'Ko3pFuڢfA}}G8]SԞnSƉP3(ڇNtaf|yuNfjWzLG7 T: kTs4T_GwW@14e/>m#w-3P_V)i $KQ)Hϵ/J ?pQ+H}uT7€=*C>o^&-u+{>`I޶>njMȡ:es;5}5q8*56OG_Kd@I̮6j'wOӰ3'a ٟVpRO2 Ĝ2H_hh@Syy#,[pGAl~h0s!({Pe|, (Om6*=@2&_|cb7P^e 0= nD8zPLj! k+Z:!BR^i*lm1" #0;,5.V7d@\ToЄ+ U7UDH1$Y7 fݜ֐u`7p^gqX;EHQFwE=GYfȚ:?7iPym_? X-igaJ@Wu?`%4@I%3]ʞltHdIBX {r `A,޴`@KzG/~8a:7y@ A"!3\r)>oNl8NUj&WH q)`i+4F\b~R}[f?u.꽠Ix{SyLO+Nhmj `ZǨ@Aw$4<@DFA*X.5T]{tʩ>j'%u>ޙDZ.Gn&6{ nn-˩$#|u@6CFM~>pǎjRER'h X TݐU}9AM^yhGC:7SBBnS)}~V ΪtHB y 1nԑ*fry /tjy!UJZV(lMR6wׇP,6%z[y5? y1tc ч,yOz^ ״쵼sIKz0gRfԛA ĭm:d?.(7CB#)A͍ E(A8Z攔3Ґ_j%%mi<.d܀DM~mG *Ә%2_"Ӵ1 j'HX"1^ %M@f !pR6ԕG/тw4=lq_AbYnd 1`/H#SSMd ma,. G{ rT qJavHXDc _lF/ jP ak.;Aůai%QQ V;qaE*!Kj !7v? `E˙8㾉u{c|a=.8hbm@aB3 &t q{)|hCRv^h1?stWhA~ 4.X*!]c߆-fWS(D'Fі W "Ic$\KliMwٿKJ6H`cRfVhS,DQzع3Jvyne\9Ux6a4v/,!ЈXmhe(;K7L3=k6R*AczOp܆iܕaN0 5V btH ?Ĺ Lm $Չ`!7꿗1"F h)|G TJ<+ssdtCi ay8^ 4? $^u̧GzPHr6 ^#,NMeHࡓU Nkd @ ^t59BC  G1!ˀOXN=o ɀؔ$ da+c9Ɋ0Wޚ|G#Wy}<+#fm \A<&_  Xl{m~FӰ8]oڞa^18I x%ɽ#8_g[Wj69~KȄ' 7pT$|V:Ay`Ry37a7P͟"?ävז>"<R=&CI%eFjM齥0 $ '] dc…Pm_4r+t5o ;G_( x37,F-܂A4!F*1TC d /`T w{1/ I"(0U@{-d@ς/4˴H g g6) !;v[i+3 ŤBLCA F>#q.Q،fVac6>z ;:BZW[xʌNMM0k*x@օTM+$2ne"J~H_ 2'-),JrВ\lUV=@ c vX N5 ZƨΔbе&,_,<" vcM,_\iΤd.h?Zl~agv@DNIpϒn^kD1})X mFA}! <YM;VKKjn騀[ $0..Tb*jJNJݧG>aschͅTlM{'-Ǡ-o GPyr͢7csMBSo7w%<9-[+&gq<͝3i\Na5%kjC!}+/~'%I` a!)= ~ӃA}jv3J\:UP8_ܣYʽ3;tss>׌I_AmͮOS*BJ:]vIwBX*{K x{0YbAs ^Т֖pG;q;k0鎪hq+ ţ^^O)vfq$~I>>lS{?cH1 Q ?A L3,?4\JK6.Q2ftؓ2n M}.p%1u _hߴꫩ2kF1!4#;T؞uRݿTj'A5 nbXUS@?zس 牼s9S?2 s=gy i EΰUolK<{"T_O_^1AM~ϾO`XbZ[RR8%HR}QHz.1_RUL9B Tbzc:&5Mu**4” C'U,{8_'/38t3ۉJ5^}WZ}_Ӓ~?q}<O]᭜StꊊPZ\fn s(b>r?h\Lm[JvO#C4 yA坬j&6‡?n?EK4f3H9jF(>=kh;(1\3 ۯbxʿ. ^Dٓu?ԿCwSH>G[O۷lׅr9ѷB ?pf0q:ᑤ{SmS\׌7~݋Js+'$3P8pF 1I&sW?5"B{۸K. soe! kкv$>3졈پONTC( ;ޚL,PL6!:I>k] pjc)x{GY C )Tcgtb)>z ~Q64P+&l Yo3'X҆w2Ky~P s%Lz>Deo/3XC~g̯k:*ȬÏ" te~o>]v,{2s(^bP&1=zf.Zk`%$LFh+(. 톅)= dFQvOL/m+d{ìYk@ "\fĥ!epg{٤|CP. {ė 3+C0]@91pO 834aT-A]y̘uڠ4^{Ȁ.q # Q;ar*vO5lg6~h >1uǕQZJR&HeA.6 JUT=QP(JO& I]Q+=r`[5C^``:ɸ  n boXx01}2ts s0 ʼ}Q`r30'Ff0!0,UkΒ(K}Bz%M눑bVјJ} ֍oPk$j7,6+?DCL{*"sXņprR6Ƞjɍ"b V΁h=8X D~.sqH:lv}PmJKU牿Nr:9'IaAx>쁣7"@ l]ZoL b6 1eagx4hD=;c)oOKE9[%. 4̔w'k;SBh7mc*:,B&d9:MtO3baKC?λq a0 QTLyu pA"htG4 'A Sw.~t B%]kTbMCvXM\A|Aʫ)vusmUEFc6P]}ob?|q_0ߜez+N#~bO#8ꆌ>h|a[Gc?d"zhM>LHOn #X!J3~>nƔj~&d%w; FIe|aSw DYי.XT+B )+ןBgZZΞrsA@3yo Fd6~T|a\7{rX~.i6'–|O( 7L>hZҙ 0QɆsQ* .-6@U)&/'h G%H3lNm^7G0Q3yfH@!D:wFhބy}ou^uf$DGe'dLLlC S s{W8l fg&*I߷oNvwV_$t)쌪\ }B׏lI_OaմKP4SdBzn ѱK˖?] A <`*W=_7k]r Ǫ ?wR/s:s8$g~ E+D?>J|38ċrYг!,[ږݿCogXHry, *^tL1֯ ˍ B%7 *07kQ_Ap`F;37ԅzaߺ]'𮓽tYݑW4kr!9eYޢJX[Bκ^ (غ}yvP&_Vջ0̭ |'(`3=@*lmWY\^lY{U`GwS|elѴtrMB)stgS1n7n:d%$DA\1#WSY/-\LO)栺_z 9Z,b1[ɃHE3t-@\0Ñ"H7CTh!qOgH=@ձ@fu+_'ӫX4Rh (B %1qZҷM ^:{]1p.y^^UR`Q^(G"0FR[fWwԥ@9a@baeN9үrWKHKgN`/]ff~oʪ] jGDLqxaF?V2\,[v*QqB2 \'ܑ^0Ɛ{0\T𧷥xչG{1Sh3_M91(>ctE tG@cR(RCboZBcN/'tSd xq7NNL&5uk?FӼT-./WL=ZʘUW-9d^`&d|!&h@*ZD lq0~V:Si0[Q@;JNυ*B`)jj[a wmDZ0]fEʢM|in6 ;r̈́Hإ5 ( M5x$`01ḥYp$Bo|i)k7P %YGG{yՉX2F֭+xpҠBX`0/P !w' <ߺ~ж`':ӁsQ0Ë<0^9CSCڌ z:M0(o2-m >#c4K{(R dЎ0p$10YUy7k<,2>{H,uŸL~5TQ"YjrPdhw]G,Q{dRrG2͑twޮo'P)Ȁ*:oS_z[@\Wpv6a ixSN] {q6mjq1]&?w'+8||-M&uɁk r sc'by9lK&P`:Oc#S,ző r WPo 5v)ä~`ђ}c)8?Zo 5'Q_ۯ\$`_\ڝ!A¡.Z>'qa JGDۑOEKR:Blp^aEpNZںtKs|TkMC\yv2 @`#rtŮ(_yd!I1cV9s67u"Sku5sJmݾBBܻNq@>7"e//at@@{X%n ?[-Vђ?BU3tX.2 #8YQHkJ)43.2?t2O:vyA3[_H]mh8K8zצ~:ڑd ͩ6l&D{:sNGjɣᄑYN%w'1s!ÅZp/^(L6,VT4ٵj"h[:zOB$ɟ+1q0jnkk{- D\Yѷ˱jvJWjb ]cGGϬdЦ =p@`_Sdb {8_Qs%YB,):~RApkF{"ִ[!N֎vZr;zc**_QgMs1)HG44JIidZI{&veB<9*P 3zu>}e:|ХБZܺ)uL>=hTbiHbYrSxQvVuu~[^֙14W5{c-U{Ht-t˚|~&uou2'^hia='w[+yYڤσ텕4 " dX:21RИel#E{6v(:s%1|%b*'v2c05EcCs oUxr#2-N 2cjPw!vr\뜐22(m [ fGN1vH(19}$fm.&X~ۨ v*hwGw,.,'_pN`kgvt. > FG򒿭Nn r 7)'8ڟ3K=Bap_̠7,2M6zig8ug @~|m]<ϻU߯UQLPq>jmI|GbH &2˦iWu(VEm9r=}[\ŒO׬G6O6w?m< @-g ={F!Jm9wYIX6BTsou+NՉ̷e 5L| !:'G:^; DB,>ɏ=͙#ߝKͺը$4V/pS_Ǻ~FJ7NJ%r7/bYĀ+$@yY}q&_牛BoQq&wNtGk:{cfj8i|Ig&*,iW\3=EK9Z9l~/Pb>f}G{CEñjdn 9Ŕz魗ɍM@BbpsEd9,5W٭.Q{Rc@ANWkdrj:K}Ɔ[񾹍·Z4n2I I&jfjFi[S!~9yVFgO/˟=ZLPj=3,. d"uiKP}N e27j ,H]gԮ! 0 V^̳j؞$wW]>C| ^JQb~7W#w`s⠁*mV}J6ޢ2)ulEOڬoJt%Aocp^ZݐUSGi0>5/FB2u5+Ps7Bs[y;PݷcęyC6Sh ʑh?⪃9G5RUkފ2dB~B e[lI_ć^FØRfzI-%POPXEiKwtAqq+ja:Ow:\H].gٔ3(ܿnVǟx6m #dZo*UvRa5yV=hL, v~t;?31/V(F9^N'MkW^ۜ}ӮpS.W^+dd[5wN\>7ۣw8*oS5JjvmLyӵrXL̎c0MhBN%T'oH-K'e~7ēt)*Uۆ.fj Gl/aq3܉ֻW 3'@\s<B 3XrxbgYKh1`Jxy͸0FllcE })QkS7\9,G>51Re@nPT0B_۳ıB@lãc5/SÝKV_Jxzl5nj9>{{?re)σar{#t|]{:\k*e]ړʱ;Au& I+~Wtm1C׊yR7j6 }_veP3,'_\T'CO{&.5ԎZym/RW!vę|V<:ӿV[\^I(gTSQڋfz t* n&odo@beZ4xeٲs'{a3]IIRKXMIiJ҈@  G}@> cZ@Lܘ.]'͵eZ?EvKvv`"SQEjcofEV ~&]X,RȾYex`ٖ1ƨʘhKMJgmO:ޜ$0/~7ƞޚ#uqt.FGoWXz/;u(yݭ綥(DUj& k%"W`~M뇒naP%rsc*H&$w&U:G H1~?ftϽq8@Kt䢬*  F 6B6@2fͰvX1N(xG? \3veާbKg&Yn<9kl6 6햬hZ83]6۸ٞ=0:&+vQ%&}==z]14;w] B\E&c_yQkB/P+~އQ!;,tK7.ktt[M1x$,mcjXh-ډP%uFһB?UɇknPo ogZ[/QdPǰɨi1dH835%euw(I[Db Tzzυ|mׄ=:xeBC`ʠ1>9vU:KWIt \G.unu +OCE8|I1`h#cF^w4VW+G6C3Krh6;;co_O ̽~Fi{+Hf>c;[LTʤZu2nI@DwZEۈ-U>4}FgK`hEX4Diغk_ۿDM!{3)fmyՌՙ?\}u$h렼yWPq |MJzaߩ'{O9]It]C)5fleޑZvpgVצM[X:e.CVkU]k6/+;뜪c;_۞Ƴd^7X)xb:ROěvWšmoT,{l Ja*8Է|&0᧑[Vn}>ۦ9F776߻N_{9)FkG7׋9JmWHޜzD{j-?EL~[={ͻzE9ꌟc\IE{ ߩīA4}l\(܃{gOܪRMy׽?WXlWo婽̳ ؗ;ۃml?xœ;_>Oˇ3*e=L2`)2Bi5t+N'rTvq w e}Dޏo~mg+[G Wiyz&~RLqټ6ߺ$e(׭aH!L4ۙa{zS'M9'ܴSڗ6ک\V󴫢Qj (n;}G sәl?wZP땋_`|qZeB#'{k7 LEĞ_BKVqY|x^kxxǡ⪒; K# i9^:ẉcZVoK<>7R&75tŅ6C:;Tw{~VY}yOL*V >L@wQ=J9Cc@/[UA1tJxd Bt_ ux BE"3.Ohoٳ9Ĵv #|Mwd'QOz]6̝҇ʴ/1q\糁|] 1ߴx9o;Z4Zc{"jխ:1rL}W PVǝ)G7px$:r4;Ss ƠIo3 @t blN=JY8}uR~`u|`jnZ?Ņ!J@Pe("q9 &{X,VCdtbIPӜv))$t3tyмN%KSXQ~u 'II3y{-\&H)>>'C1WNe=p;=DT'q66 Nصl{)) #Wz^^+e~.^*M'i_/{[ uT;84GUP_9,o\e3CcBg<Ծ̉9,?F$/;fPBazӧ;>[ޣٹN ^-AM8]wװj%){<d(yOip꼭\79uopïwҭT`i~u YԭKa=9oz$]-:UWczUfCX/I-J@r-H˝;Mx(p6,(Cdh ~@A/qȟӆQZ>>p)c0]sd]gj*v,7@!g.؏ՁJqU+(Hν_;Wwϟw2;EHtfՋJ7`C>i𻺥n6c8ނ3w.W6vɻSdU+/B%ZQ;o8P@){}ڇK`C ~]5kׇ{ !eev *| .\V8*Ÿ]Vc'ťƳPoL5W[i59q;y32羑B A)L㿷)NJ6z;_D,6(oEFY?ei( n~akMYxT0B~v*s3cq?ZxB%<~N(<ɥ`AJlsm\*'B ÈgN]& Ewi;ܥw,%>Sߪ;S)G {p_F;l߶=_l339ڦ-oik?4~'gAkq"h۽FAkQyˬ\;tZomBGJauu}ԭ(BDL' HƏ,j9܇ݺ~3Мp -_nɉGc~txoS!3_:| / obN#l2 x d٘.y `͡q6]־*9(ӓ:(v#O;rm7 bu<95}曑qv@qm {ͣ@p%ޙ^#y&vHV]A  MEKI'6}Iօ?bxQ9S^0y19pzdi+rQh mou\=) ly%1;nONZ  \V%ηwSFʻzLNE7c};sUƍ% p'F;MAާڕCS %m7UȐҙzk7ht יO83P{87>5Րj4]_:F4>\0sעzϊ5Gh{ίHOU4բSt?2:]P3kG/Rb:ytXҬ#-S 4 y^5ǽ=.@th~n pBMKߵjgP_J]R .`尪&GʱƇWvITOGg}CD46iA{ږ5Sy؎꿪oEyU3.ێT)i|7㾁ɉB Z4T"tDsۑBbq;ע&ɛU+՜IÄs *\܀(:ew[NQp.=L'LqomcM QL`JYvw%M/4">tAi࿼xo~<ݚJ[Z)Y{ Y-fڠloJ,>s(sVQ\Bȭпk#}ڻH2D@:>mu̓tPq֊ VJ=~_)Ŏ!b|e ^eSMՋWGr|ӡȶ]?ݏQL18kTST7ڞUZM7b"pRן=Rr<‡EO/]O)W(MCyU:%sv{F/™tzϺo4 ?vT^Jl]*u5AA@lL/f̆tR!eU"GkcYUcN7uA:0^3N{R)O>' PݙnyOc,>Oܺ}C'9G|:À kB4Hݶo6*̈́3bsl떗1lt B,#?d^15TXswMe"(Hshazam/data/VOLUME_MUTATIONS.rda0000644000176200001440000000175313402556553015626 0ustar liggesusersBZh91AY&SYo-#6Xp@/߰@^m54h4 = z)FʢD{J† 4hz OJ@ @IJyS0Ҟ=G q$ I23y @9xrd  ?$)Za F,eDJT9"$L1lEqeb"Ym2L{}~ڗNk$n7BA~א۹BH@Cr$''>5ʴd4$Aa"thFXڸ6eW& %h& *(\YFU,mmAIlYmKj +F(h (%-IQ%jVVQ-jfQ2XQ-х"PbƵQV-mҚdMqpx4tw@@P@P@MUP@ժ5F9eS)L,h.q3 u:i <B2@ 2uс$$7b0LW'w.v͛A1uT]bUUUV'sk)JP*ĪJ*UT[eYeYJ*ĪMywUEm[J*Īb";g.|vֽzbUUUV%URk뮤mm :H̒HF'N:oHVtUgFJ8u]u\J#R`0qu&2>Rc *TWZ??ܔN)y0`0N("HP ;n6Ϸ.xI9'wpA Kg M8yDf;ts^> :<>'CI?w$S Pshazam/data/HKL_S1F.rda0000644000176200001440000000037313402556553014240 0ustar liggesusersBZh91AY&SYGqaL@8t3׻llh4G|2|2\RAvrnsէZn..9ɺ\7MJdc1aqdɓ&L2d(pƗW2e2e2e2e"vha22,[,LK*"1X4"1X4"1X4"1X4"15=kZֵ !%2dɓ'.\sߚjݶl٪3+y fUUymHhѣ 4zJSoڔS=G4)ߩUF44@M44@ O)T&FLi`LDjLM4j142hji@TAn xHCpT=xPIQt[tjf.8*!n&HN((j);Be;P0ߎӀ.Ƃb1 9Ր?ׂ( ߎXW'G/G>-+i< Ub鋏␠f8 .FH PœBl&0&.dj(30˒,+8,1B0b3L VTҖ(3J! BB3ZֵkZf `0`0`Y ~'8S f"1@H]*N6%/'ѱ[Y{Zֵ330]\ĕrI$@ QO&Vu]u\` $U$bfffReuUUUTm$U$tq"뮺mm׫I%\I*A@ QV*l~m;mmJ$U$@ Qd̨ó P.l<V^3M&اCtM7vE332 Ht% 3ՒU0J\G5jF\ޛ K>h  Uf{ʵvB*˷N<ؖ&`Qs`XA c #je5n2cie<]bZdz.`?@*AU"(H:shazam/data/MK_RS1NF.rda0000644000176200001440000000037013402556553014366 0ustar liggesusersBZh91AY&SY{sL@8n;\ݮQn(k[-rvE\ݮP̟}zI7wvIQn(k[-rvE\ݮQn(ffO$$(k[-rvE\ݮQn(k33'}{ޒMݒgk[-rvE\ݮQn(k[=I&3-rvE\ݮQn(k[- ~wwdrvE\ݮQn(k[-r3$$dI${~$HI$@=3]f}{ޒO߿~N(k[-rvE\ݮQn(k?ϗww}JUEjQZTV+U߇$$rvE\ݮQn(k[-rvC32}߇$$rvE\ݮQn(k[-rvC32}߇$$rvE\ݮQn(k[-rvC32}߇$$rvE\ݮQn(k[-rvC32}߇$$rvE\ݮQn(k[-rvC32}߇$$rvE\ݮQn(k[-rvC32}߇$$rvE\ݮQn(k[-rvC32}߇$$rvE\ݮQn(k[-rvC32I?I$`$I$I fwϾ{ILrvE\ݮQn(k[-rvC32}߇$&vE\ݮQn(k[-rvE\>n;\ݮQn(k[-rvE\ݮP̟}zI7wvIQn(k[-rvE\ݮQn(ffO$$(k[-rvE\ݮQn(k{>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC32}{ޒMݒgk[-rvE\ݮQn(k[]n;\ݮQn(k[-rvE?~?{fI$L$I 3݀I$ jZ9fgy-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC32}{ޒMݒgk[-rvE\ݮQn(k[]n;\ݮQn(k[-rvE\ݮP̟}wwdrvE\ݮQn(k[-rfd~$$(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffI'߿~ $H wwww`$I3{ڬֹzI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC32}{ޒMݒgk[-rvE\ݮQn(k[]n;\ݮQn(k[-rvE\ݮP̟}wwdrvE\ݮQn(k[-rfd~$$(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC3̒I$I$@g뻻 $HnəwwdrvE\ݮQn(k[-rfd~$$(k[-rvE\ݮQn(k33'~$&vE\ݮQn(k[-rvE\>߽I&3-rvE\ݮQn(k[- ߮zI7wvIQn(k[-rvE\ݮQn(ffOw{ILrvE\ݮQn(k[-rvC32}{ޒMݒgk[-`3'~$&y]n߮zI7wvI^fd~߿~I$~I$Vk\9 >߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̒O߿~I$@g뻻 $H{f{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&}{$I0I$wwwvI$wvLϾ~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`$~ߦ $H wwww`$I3{ڬֹs30^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$ʯ$I.$I s8$I $I $H?fffI$L$I ?wwwv&ffgK{ޒMݒg߿~}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfI'߿~黻I$@g뻻3;k33fOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL  ̒O߿~$$I $I I$I$$I 3{ڬn߮zI7wvI_3'~邏߿fOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 {$II$~n왙}.zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32I?~߿MI$wwwvfw{U9ff$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`O$I3I$]݀39sWwwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL]{$I0I$wwww`{}.zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/32I?~߿M$I e39Vk\9 ߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~L$I e39V]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvIks3$I&I$27wvO{w{IL3'~$&y]n߮zI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&3$~ߦ $I9sI$ $H}I$O $Hۻg9sֹrI7wvI^fd~$$/32}{ޒMݒ`>߽I&0 ̟}wwdfOw{IL3'~$&y]n߮zI7wvI^fd~$$/3332I$`$I.={߽I&0 ̟}wwdfOw{ILwwwwwwk{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{}$ $Hwwwwv9}^廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU{wfI$LI$I$2 $HI$@I"\Y$3333333UU^s3;nwwZ9|w}ۻ߭UUUUUU_Wfg{yUUUUUUW}wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪kZֵkZֵ{$II$ fs>k33qUUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fgww}}I$]݀39sUfwwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfdI$I$]݀$P$fffffffff*9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUukZֵkZwfdI$I$]݀$I$I$P$f*9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUWI$wwww` sYs}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪g{$I0I$wwww`@ۮ`G񙙙fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUֵkZֵkI$]݀$I9p߀I$X$I?}}I$I$fs>k337wwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW$II$ fsrwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZZֵ{$II$ I$H0VI#UUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9}}v$I.9ϪZ9w{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUU+=I$I$I$ I$@I$9Ͻ[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUU+3}<{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪ks3$I&I$2I"\Y$3333331UUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jkZֵkZֵf32I$`$I.9ϪZ9gUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{}L$I e39V-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{32I$`$I.I"\Y$33333331UUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪kZֵkZֵ{$II$ fs>k33qUUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪_ew}}$;˻I$9s<I$@IメI$I$?wwww` 뻻rwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZZֵkY̒I$I$@˻I$I$~sd?UUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{}}n$I.9ϪZ9֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU332I$`$I.rwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jfwwn~UUUUUU^s3;nwwZkZks3$I&I$2$I$(uUH3333UUUUy{廻jfwwn~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy{廻jWfew}}}ۻI$$I eI$@2荒Z9~UUUUUU^s3;nwwZ9|w}ۻ߭UUUUUUW[֪fg{-wvUUUUUUW3;>_{}߿ʪ[֪fg{-wvUUUUUUU33ﻻww{wwݻUUUUUUy$`$I.9-wvUUUUUUU33ﻻww{wwݻUUbwwݻ[vffwwn~33ﻻww{|w}ۻ߀{廻ffg{-wv;33;I$]݀39sUf]wn~33ﻻww{|w}ۻ߀{廻ffg{-wv;33;nwwٙwwݻ[vffwwn~33ﻻww{fdI$I$]݀ounwwٙwwݻ[vffwwn~33ﻻww{|w}ۻ߀{廻ffg{-wv;33;nwwٙwwݻ߿~߿~fdI$I$]݀39sUfsϿ~vffwwn~33ﻻww{|w}ۻ߀{廻ffg{-wv;33;nwwٙwwݻ[vffwwn~}}ۻI$9 $H?メI$I$?wwww` s[vffwwn~33ﻻww{|w}ۻ߀{廻ffg{-wv;33;nwwٙwwݻ[vffwwn~?~{fI$L$I eww[vffwwn~33ﻻww{|w}ۻ߀{廻ffg{-wv;33;nwwٙwwݻ[vffwwn~33$I e39Vk\9n~33ﻻww{|w}ۻ߀{廻ffg{-wv^̾[]{-wv~ﻻwww}wwݻ߀뻾{廻uww}} $Hwwwwv9}Uwwݻ߀뻾{廻uwwn:nw{ww|w}ۻ[]{-wv~ﻻwww}wwݻ߀뻾{廻uwwI$L$I e3{ﻻwww}wwݻ߀뻾{廻uwwn:nw{ww|w}ۻ[]{-wv~ﻻwww}wwݻ߀ffI$L$I e]{ﻻwww}wwݻ߀뻾{廻uwwn:nw{ww|w}ۻ[]{-wv~ﻻwww}wwݻ߀泽s$I0{ޤ $Iww[]{-wv~ﻻwww}wwݻ߀뻾{廻uwwnHfg{{-wv~ﻻwww}wwݻ߀߿~s$II$ -wv~ﻻwww}wwݻ߀뻾{廻uwwn:nw{ww|w}ۻ[]{-wv~ﻻww~߿~sffI$L$I e39Vk\9߿w}wwݻ߀뻾{廻uwwn:nw{ww|w}ۻ[]{-݊H Y$](0VI=WJ{I I$wwww` sYsfbIP`zw{$]*'@w IP`zw{$]*'@w IPs~{?g{L$I.9pI$X$I$Iwwwwv9}UUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt {Y {˻g9sֹs1dt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$]({I$z fs>k33](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJ{I$H{˻g9sֹs30/|P`zw{$]*'@w IP`zw{$]*'@w IP`~{g9ffdI${2$I$H0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJU=3332I$`{wwwwvI$@ۮ`zw{$]*'@w IP`zw{$]*'@w IP`zw{$3332I$`{wwwwv$E?n IP`zw{$]*'@w IP`zw{$]*'@w IP`zw̙I${˻I$P$]*'@w IP`zw{$]*'@w I.We]~sdt Y$](I${˻g80VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ*dLw{ހ.9ϫ\Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=W_/}{`˻9sI$@@I$|{ۮ`zw{$]*'@w IP`zw{$]*'@w IP`zw{$U{$`{wwwwv9}*'@w IP`zw{$]*'@w IP`zw{$]*'@w IPW{ɀ{e39Vk@ IP`zw{$]*'@w IP`zw{$]*'@w IP`zU{ {e39Vk\9'@w IP`zw{$]*'@w IP`zw{$]*'@w IPW{I{e39Vk\9IP`zw{$]*'@w IP`zw{$]*'@w IP`zU{$I${]݀39sUfs~{JUOUҀ.sdt Y$](0VI=WJUOUҀ.sdt Y$](0VI=WJ 39s33$I&;@wwww`I$I$@ۮ`zw{$]*'@w IP`zw{$]*'@w IP`zw{9I${˻I$I"\Y$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z_dI${2I$93wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fI~s~}+$U{z{e39UY'@sUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@s=s}$Ix{3݀I$_}}I${?wwww` sUffbIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUp/|9̒I${]݀ $I$@qVI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$$I{es7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@^{ޠ{e39UX$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$yϳ7k33s$I{e39UYfp3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$]9s$I0z (9'@sUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUdt {I0z fs7n$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$yUU~{g9ffdI${2sZ @sUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@sUds$I{eI$Ps7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$yϳ7uUOUҀ<ٛ'@?~I$I$@eI$s8n$yϳ7uUOUҀ<ٛ'@sUdt9fIP3wUY$](}z>VI=WJfn$^^~;m۹yyxZַ|eII}1%_\oVy)/jzIAo"Jd%q1313 P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%OP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@?@T P%@T P%@T ERJ*J*ʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J҂UT[JKz=Gf&bfJ*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*JҠJ*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*J*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J**J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*J*J*Jʁ*J*J*+*J*J*J*J*J*J*Jʁ*%@TYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T ST P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T ST P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%OP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@?@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TT P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T ST P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%OP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@?@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@TLN(.dLT P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@?@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TT P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T ST P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%OP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@?@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T P%@T P%@T P%@TVT P%@T P%@T QYP%@T P%@T P%Ee@T P%@T$J*J*J*+*J*J*J*J*%^U"2 wIAv#PVIeIUT@fP2օ6ՅlikFYh[+CL1lڣ aʶfYM3*U&YMfUHƶ2mZVRiJMcY%QMMVMX63+k,vuS$$HH S[ XlC;S`)2`i2;`@I-DlX l5UE@D((!m)U KZJe %*VPDT (Qȑ5M}* UTP)UJ*gJJ8=U* TRTTԥjҪ UR@TR=ͣ5LlmVM'3`zURJP)T* UR^* f6g.TRTU*9k2lmYcjȥX6T `SlʁT4BfQ+@i2hCF4k@ e J҆V6֙H*PFЅ M[fڭ`@4[@l)M4YZh4kTҶ@4i)BT^ gwT $ %M)@[5 4֔j+MU H,-JkhmhdT5 L͍Vec Ŷ٦-[dJUkRRʈF֫$ZmTҊ1B"ֶ`jf45IR(P @mL5ցlPP(@  %؊@@ &ab4 #M2dM4 i4L M"M4ɦ!@hLM 2i &ɓ24L&`@ @&LL@M 2`M0&dh44hh&44fddF@4 A 4**Qꩿ~RJSE4iH$S~h ѐz@@i4 hdOHѠ iFUTJ)Uh'z @MzUIURTJi&LM22iL #LFz@M h#Fdhd S0m}{_;0mCo7vyoַ-oɳfl۶ߨf/o[~տP~[Ǐ|O_|;쯈g99r$d2FCBabI%9ZA'h00c1AZsL``#Wp `f"->>|ys<$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$II$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$$$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$dxzY$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$9$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$y$$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$Ig3$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$LLI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I&ILI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I'z<=,dI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$III$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$$$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$rI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I&OG̒I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I2I2I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$$$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$O&ۙ~Ծx؀<XUWox<x{{oUs3f6 0b{IYfc1``\X?{޹RP>:'/ci'FY _.Q;| n+[üe{?7Q(bBZh\xIW@]5f7gM~3FU8!!5@fP2o]4JeC%2䒎se(!a'?ׇ`0\ufՖz~ֻk@|' +iYz[#}*Ϥ5;CE2Z'YZVKE"?J8{4S'uA7矮S9\)"`FWk¡ >*2/daDo8IDa7jaTfظj|U.;z۫/Խ߿ތc<+n˨gsij" h6`3s%Ixzvڸo^^o׊I豠WG3ho>'.ށ+wt M)FLy{ߙU 5(M{ 1tO$cyWc@P5C 8:3o&|`:.pxB,VXzMp8p籼皝)L͘`PQgͶFHsAb/Ҕ1YF3},492\`dPVu]1wPMY?;4^lO!Lg6 tVıЂC5]Lb $+k ;(-A>UȕA0-Ý");ۦQRO'H *^̻ aL[j43aDN^&1ƆG2,<ԫ&瑝ee,\6ig)6^*H~>؁hb> _tWǘr|S2ָ۠je57C$?   >޼+R gFhlm$~Oܥzyi#}8Ow+cOrO~r/BL8foAA8EZO~Xؾmn- iEӖ\8|T/lm%T'ey#?^g\~any/+DcZ$+Ƭiyk7ISt %⼠*{&b{Ra9U ,=E2<=ˮY\V1C l^* *LBJ*F5/?v@r_wK<(Idl8u`ch)- 糳QC^6J-CŻaX3(ũ,ԟ6u-?EIW\aITE~K3vL19Q]fߛjn]˳Yr.|yE.ۼHCGK ădI>@rpa+9R)MoIPZ0ܾ]EB(ya$oԋ-P4Ѕ!Dُ!W6|MRFrqֵ-STyhH+0gQ7a_&39L !G9~M[jCm ԍJ c!`=A}fldY"lHt]t@>w7zu:%t?BL>fE@35UѹvzONMZ|־Qj`G}x?1F.|r MEy zGnF۞ua ZߢgrpZV/N|~j#JnaxP5ҍ6.Di7xW4֗J )=4tr>}KB+o ITC yn-Ȃ,EN.e~~*Dwppa($m{o*p Xuɞ2Ooʐ3W/xu@jV+XЄP, =pSjB%Ec oWY-CcEX{K۳[muLu<76:/f* bT$~61%_"эW~Y9 ar:h@ªO?jw8u'tճByQ&'emzDoP1001rۼXK1a@1Oo-(1001.L&/C,8zr|ݹ n 8s,`Lخ8 @ _N;Rk }~gc5 w @0cv+$ KL| /$e Gz7 S!=|s>BSQs^AU0+B|M< MZe-zV\B9Pv-ߑ2X`jrMJEtkKS<$ f6:,n`Ǟ,'ELՔ>\$:yK eW\ݝWO8ix?gx=_--AiJӜ@\]r\S?W;PKצETL}ꧧ5.P6"{~ \jW!Ǻ;O?T"8 }.YH,Sՙ~hfnT[*at_ZȡUE{7a)6rK-9xȧY]X&" ǗA5}?rLƈ%ɴ5Ary߳?qc߷? ;30?fDf"޼Q뵉>kl}~ТFXZAPΚ-ܝbv=r;!7UՃ[EIEȀ'(iyCR(ܻ>M2PpQ@ ɯ$Θ gx2OHIRJ^WSfa]|n'oZ{r"#Ocidg)O( Ghd>-UNK,y8o<(':~Edln[ .]lňy_G ؇և (63p$Pe _uf{șfDE6 2E/@eQvyJ䋆?&?c6TGR 4)!bv|ran; Q, cp/Y?{c]f6ۃbu߻ʥ]6}پ^fZ?\V>~;X9xj{ڀ*W~<^},ϮGj}6'),&d >pa;pf|՘8b"+R*\@`~Nܥd-X&߸~bZ^#'UU{:mBM{wX)!BǎgQBogI ö!2JrݾW : Q]JsdǨiTP?q7S}0Ta`ˌM6r<[TM0 ~}G? w9sŷ݆]"<51"KH~a}mt5C|^dm ` }2˒}7`*/#vQ+U!I*p>fdBK!1 Ԣ–ExjKiw[' ͞R hۇZ*Kיg4|ٞF꺕(`]iQmI>UCiH+bbc|_~w@xQbՎMaurHM9Dy u>فhfw*w=oE~pZő㪏K+GCzZE#Eϔ%kǘK?mh{}c~Klb,Ӟk~/4#y~N^ZXi֊, wR[ gqλAY$Q{94D'*G޸ a`goٔzP,[ÒT.g+KO'CC$E8of@*dfJՄW,FAwkSVh/$л|. 0E߬ok1y954sk-{(o笰R;F.F4;+ jV^k< [d0x(͹ʗJğ~Q6}Z%t)b{$(ZΒܵ'u?o\\Z^&`)Q7[{4D>( UH>ڱ6!)6/ɊXd hV: {W>`t|ɐ7q&{H&So?zv|S= {q?؛|oY)6<<ᵇx/6 $`0nrq-#/(&Mnhg]PzIH1/[X9 !oɰ/+ Zu~;(JۮEz:4vݨg$>.1gzpu] Ec'/tGwtb1& (ڃ `@=sPi.ހ%ɫI c"_NoRd. IH|#uOb F+A ? 3Ȇ~Ij}k-tǑ}:ŮtynO1VzX@U0sYz^N,R櫶 x Tp#wl,OInk #6D>}[m vu+H˭3g+|Vczhkx$ BatWXĔl۲{W2hm3LϭQtJl;Ig*DEHDt3O$=P"xvƃ2|ИQA ;ݢ&fEZ*|f]ґrPo^a,z*UaT zgζŝGw<զ=c/iLεX^8K1`auo7v[n]ho{f~ E1bՕ5/ɥ}hk!w_&AiJ6u@C<ٲsu=zΪs FK,AW[ /Ɋŧ19W/lqjDd0} q+#Y0ԁWR7jZZ@XlR$Ѝ$9]ÿg1 E6]&hT #9As\ۡ/aRgFT:r-nV:͊^okORC{%B!g"!gP0=jB[D`wG Gf9W#:c3'@ 1phwY$TAk~ I`[K֠KЧm4istwgY≩E+-u㌠PC5&g Y]8 J~u߶濉.eV&B.H~֍S/HAn  >*9b}L17mc\&\V6찯jV̥~N`F~>i`rKX,>8ȔqJňV#XG)OiLcCj4j)Gh}]a6Jn%Dg4oߜ/լ6{)9#+PV9h# jz/xn5cEz$njY5;ٶ܍栻>V}m~' r HP0Xv5hnxT*eDFŢoeT ; aY]bjcUl\rzf&z]$\\񜾥ɔdv2.ȸfݵaY3IFwp3>C:ZJ/bmy-%pӝhʱY-^Ol` `2놛`-(ŖhE&ۉ,~4 or;mNXP=qW=ԷcT획Sa^{9՝N;X8΃^sttKhp}ۅ\i+ZH4.|`GtN?moFĂ>H(NXF hIfX9'uKi=l}vgV9rnj@p rAQ[3h>Ѝ;bz G8ZsP&Nb(\DLqWLp`wn wC{/BRnWRf<\4oi"zhb|:9 ,P$F>C·:%[H0BϝrHn ㊮us!7Ũ6ќL\ IEyU9x~ΜuCފ2ɠkV2蠸#\׆ $3kwvsxN|r_]eD>Vr޿&Z\=}5.R{!uz߁foݹ,%bqEe|e]f^*mwniKê(\/ӹ})l[>$.w4&W'c_nL0Kq䢭ʷr5Xf['zIFB ¶U]&F28?d_럍4dzТq$LT?.f[pԥ%qPwmaֶis t$/YK,v-znmbIvwŒyA^ub6c+fD-+k_ITZ$+C؇A8x>ڑke2c6lyT Q@u4(1hlx+Ia6EN2(d0H9ֺTbMb8}>eGOb e:} 'TQaǛ]AaۉcG/eְzmEz\Casm5ZedE(c$Ӡ`sbA+r+1S8ۊ`xrc`8,㔀t)TayZ\s<+h~ȷc(!`ꗷ-[ٽf| <$]' 2yRnK̶n+ pWW):[-uʅMlU aOXAj?L]{MYfTuyW`7y!%EBZ0 pNBGדAa~f£-z)Nzitzw*1'=pQ/?n7D{{6W(93<&CTc%X_+0|^bUCy޿p;g=8gF4¢}i^B+w`Xfդ8aV~2Ge& \Z]䘡I kS$=.,"CbOmNsMAl3TN߾I=FKrkӾZ]jpdX]BYkјKж4"m"Ddu.h8r:~ڒPyrS $ݯ}CJڣ'=u(:aWOt;czX0xQwf1 3izh=}b^sY%${xsu 'MryV8ji8rw:ޢB8UmDA$voBhn=r%|RJ]U76Fޔd.UE?'st$u^{G~_u6* <ٹKߤqfLפTٺw0{ (*.ßjJcnWmg+<`5˦kcT+D/X\1DL~6 yr~|cCR :EtM1 ˁ7#!;drk8Ѓ^۸ _EE|Ƴ, @@%޳X K"1F~Ґ5ۘuV;AEi l'<Ѯ2g%PG:ТQX\! QSXTTdQUνuA͏!:g-Fw~neuGrS =]v6\ F?J Wv _WG(HƘcoa͈ץ)qz5ㅦ(s"p :ы.)T/r<'{}?ܻ(<#v Lsl f2R;!CK08G+V82%EtUuЦ^WM]!<1'fg-,MRл-FϢNuY~ \Y"Zm޼ Er*N0كaoRL)#.FJ݉]`G5@QQ^dIk>!B>BZWx;3s="[Eo~F!Y kHp%Umn&Fq`gf:㘎Ý"賬L'l4E(cu֡rܷ,~~_,BOjZZw=Ԥ&2 +:˅CC57!'je?+Wܭ6ń=Yx["Ry|=cviY˓!* `VH6i:&'Z 7$ݑNԲܣfh<'L\.)&́>ChQ!@5ô)XC@E9%3†B+Wz ͖g/KsG% ӌO*m(A0#>2,?#>#!FFHc V3MGb{cQe+I볞¸"ސpt*#m:ѪÐXD8 f'JdAWYbQd14^@RRSУY񝵋{ )3Tg1$ 6ONy$Lo2HlWɈ +^};@hM%|FyvP!oQ-_5 !)$\BQ漵u;iԟN޽+ -K*%W)?`Pij߯ J1CHq{֎Bp-Z~@a໠[Oy" So+aCzW/d)gK6BtD}g̒CQ4r2ԇijQ|a4PGǢ;ט e1VYp^I7Mc5)DBѣFZH(O$6e1`W'ks_)}Ώ{m|jƻc8uOTY*nJ;D*rN;߃=󕫻r"=Gו?9'"18^d9`KɷPE;(БV۩H *Qs!% vk}w@af8ak;{-LYv 臞ɽGi87V+mtB"։m%n?Z ƈ*Yi -ӬA\;ͻ+v% Mrw0/P,*NZWNڕ)7Xsiu!d$[ΦiA)T~!)C F_#!ȟ0LHh5dwd[G{rwj >fCo S1T /w(k%4+e 86܆]>ϨʕSI^}~3.kT]9?0'3nqjKtTDs] cG7y1i- rXѣe5)uIMPߴqxj}T+àD ,TwiAwBZֹd 5glI-hqFqAq>%}L S6Mݫq|%;Hm+Li/lj*u<ޏ z>a[i.s?ET%x]:BޔƟS0+DiscG,4J"Z#+SqCIp"F|E~㨭O+oS]B_ӳ߲wroWx}8Kh"mkeq3wD!I0)K&HC^:Qvgm2+WhNU=몫gM p# ~ţ-UU-ISC#+2y'A' Ԡo4r6Kh1TQ9shz~Yɚ ==5;c.+BΥAwڱ&b ,ަjHLU Bw2 +/I[!1pWBr#:q,~ Wy J]UW4DvbU缈,9C?HqF43qو@Ei4˼w 4. PF,OSz M.߾WF~m>zc8` UϪzjc&H !o^}XOq@N#CU#(IK/L,'!/!q_r=Rj{U4J]l.;,^ &q/Hgv\b2-HׂսJS{< !!kK1JXS.u v-鱖z+fL kFC|{KCG^L=]qEZ2=O1)R/fm#7I.RBsPoӮXVg3~X3= =Fw F0)z)ח=R>e /n@F&Hu3N07.zT } G^8(m1e+}_[BZix|g#跩ƅk]S 2hEvޭIsU6Ke~N$-X=z:2M7gkp޸&,dL!ˑNS]Kж[a#EIb`IbƎѥS&\! uW{[Ry <"V$;/gt4u-|no5l{( 확gӊNS}?9-PPm=C LI~e$1 ƱBƐtoG<ܴ˿PTGKyڵcqvYPG~i߃Z1~'KǿC4|C{;Ŗ2z-x|L!$4rƚb<MC!a:!95gc=_2\~N.y|02X烩p ٗA%/$Kόw\wp0 };Aʐ}J=i#`7[Oo;ob66#:>a1Hq/ ߡh/j}9|P%=^\+~)9G 돚Y#i#q(\ eh%a|H.{z>f`)b༬쏻 !f6U*H1zbP&B٩9'Bxe NE 6f1P>z "wu S$H2eJZI&E!X@iya.>UԾm~jGqB6/vr/{(><$Q@;z eϲ}:hS;K!^) y\E ѓ">iYҍ[G'WWz} f0 -HifN׽; DMnHެV,nc4m`ҮO")#JMv8[39Pl?w6 ܎Kť[0(f+d=I`jl_*y\~!9YLgYN Y x+'^Hl /k]L{UvTo|+#;%,VwtzbPd떯I7P~e+;=̠CAIjWJ[6@?s ̠ ?dZ1}k'BBug8_gB3@DU{+쮰i hti!D.#r^? fb[roO&u n F,p:czoO=ZRJ5ƒgz_TfFU^E"/c<ߓm5$a0˂I^M |ߩ=rŪx]B_9h6NYߢ{GV"} ɥޤY4=-D!) C]! ', w㏍D'UwLD\ CӷvT}>嚫`):*3s>2WV&&AAn0S0N洃c䰭kDFZ'P`;x bHl5^z<<79[U̪ڭeVns*sU[ʭUmV2j9[UV|zsU[ʭUmV2j9[U̪ڭeVns*sU[Ϗz2j9[U̪ڭeVns*sU[ʭUmV2j9gퟣ~kI󷖥bб$SNczؼVq1b/Z2$) ٌj~:}ZM|J@Qw,JdH"!*1k![,)ͭ:^2!VME;>ȃmQ Ζ̓CK8_\!~fPҢp_&.t\OSΟנ4_sN7gG}c8Lք^=gwWH@&Dl.]w6d9HˡȳSAË@!._{o3HWkHe&8l@Fv ;(@=V! Ds@ EC_Yr[7ᅦ'.)}K裙) t'#|~o??UP홟cOЄ!Ps3WlxmOhq RaG\UeJkX&4[Gڜ` S?ݐ$/E%A~ 4!gvnٻwfݛ7vo{޽{fݛ7vnٻwf{׽}ٻwfݛ7vnٽz{7vnٻwfݛ7^wfݛ7vnٻwfnٻwfݛ7vn{ݛ7vnٻwfݛ{ٻwfݛ7vnٻ{{{7vnٻwfݛ7vo{޽{fݛ7vgs=ol{{g3O|||UU@g<>>*{ߡ7vnٻwfݛ7^wfݛ7vnٻwfnٻwfݛ7vn{ݛ7vnٻwfݛ{ٻwfݛ7vnٻ{{{7vnٻwfݛ7vo{޽{fݛ7vnٻwf{׽}ٻwfݛ7vnٽz{7vnٻwfݛ7^wfݛ7vnٻwf~ߛUTgs=wfݛ7vnٽz{7vnٻwfݛ7^wfݛ7vnٻwfnٻwfݛ7vn{ݛ7vnٻwfݛ{ٻwfݛ7vnٻ{{{7vnٻwfݛ7vo{޽{fݛ7vnٻwf{׽}ٻwfݛ7vnٽz{7vnٻws=ol|Vz{{ߛ7vnٻwfݛ7vo{޽{fݛ7vnٻwf{׽}ٻwfݛ7vnٽz{7vnٻwfݛ7^wfݛ7vnٻwfnٻwfݛ7vn{ݛ7vnٻwfݛ{ٻwfݛ7vnٻ{{{7vnٻwfݛ7vo{޽{fݛ7vnٻwf|q~37vnٻwfݛ7^wfݛ7vnٻwfnٻwfݛ7vn{ݛ7vnٻwfݛ{ٻwfݛ7vnٻ{{{7vnٻwfݛ7vo{޽{Ygsۜ eVns*s{UU@UmV2j9[U̪ڭeVns*sU[ʭUmV3~~*ns*sU[ʭUmV2j9[U̪ڭeVns*s{xUUsU[ʭUmV2j9[U̪ڭeVns*sU[~ֶׯ@UP}ׯ^z̪ڭeVns*sU[ʭUmV2j9[U̪ڭg}k?'#ǝ_.qԞ6:LP. Ιe;uD1Ϟ~MԣϳFbz [$׿ILO{AnF14Hs%yBEEYclKHTCӢ 0Ee A:wtTc: 7=,Ձ' L(pʃ|FVGPF5G KoFِq*{ uG򷋍iR^/JHbI[GK,gϡT =E:#3 XHxR|j9[ˬThQwX3L.ըo摥E7{~m?ۀ}l/o{soHaɽ[v#D{l8u*Ʈa+l~{OJU݉da|ܿ {s_][~sU[l3<|79[U̪ڭeVns*sU[ʭUmV3߇=zO9̪ڭeVns*sU[ʭUmV2j9[UנUUʭmWʯ9{[ʭUmV2j9[U̪ڭeVns?G>>>ns*sU[ʭUmV2j9[U̪ڭeVns*s7 ̪ڭeVns*sU[ʭUmV2j9[U̪ڭg~SӀʭUmV2j9[U̪ڭeVns*sU[ʭ} >>UUns*sU[ʭUmV2j9[U̪ڭeVns*s{~`̪ڭeVns*sU[ʭUmV2j9[U̪ڭg~RנUU[ʭUmV2j9[U̪ڭeVns*sU[ʭ~ⶫׯ@9[U̪ڭeVns*sU[ʭUmV2ӧD'N:)ӧN0'bXeCKŀ>zo@qYջxk{!i0#[xK4be?~LPF<] CXD/Z.ʼG>h8]񹖫4[j2u#8#759kF>]/nvKB;gEk7E)H0:~:LsUG EP)-$ QZzZ[aIsvOVRC_葇/$څkBb|7rnIqӼo|B9j]{ :YD-)d*O]?p ,*uq+'f|Hf Ur=TctXAEHlKܲZ!!RpVO VZ`x*ZjիVZ>.# $ 5G1ogM2C?sV.U$%}āIl@ʞcH1Kgg>_WPUU[ʭUmV2j9[U̪ڭeVns*sU[ʭyy*eVns*sU[ʭUmV2j9[U̪ڭeVns?3{UmV2j9[U̪ڭeVns*sU[ʭUmV3}ʾVׯ^g*޷9[U̪ڭgUngzns*sU[ʭUmV2j9}O 9[U̪ڭeVns*sU[ʭUmV2j9[U=79[U̪ڭeVns*sU[ʭUmV3 eVns>jگנUU[ʭUmV2j9[U̪ڭeVns*sU[ϻ~^נUU[ʭUmV2j9[U̪ڭeVns*sU[ʭ{UV2j9[U̪ڭeVns*sU[ʭUmV2j9c{UmV2j9[U̪ڭeVns*sU[ʭUmVᇉJɽj[B*7|ijW S%E^*i1`(h3L")vT{Tq&<扼'g͈&6Ɩ:|9Rt1N`{;┝} Dq͝?Gyo{2GsIy8Y 1EfE^Ƕ~ _StV?(ߞabi&A!XI<5F??xڦBh%^ݦP^>\`W&kkkj eVns*sU[ʭUmV2j9[U̪ڭeVns?{UmV2j9[U̪ڭeVns*sU[ʭUmV3V|z2j9[U̪ڭeVns*sU[ʭUmV2j9{<UV2j9[U̪ڭeVns*sU[ʭUmV2j9}k_+ׯ@ UmV2j9[UU|{ksU[ʭUmV2j9~נUU[ʭUmV2j9[U̪ڭeVns*sU[ʭ~7<UU̪ڭeVns*sU[ʭUmV2j9[U̪ڭg UU̪ڭeVns*sU[ʭUmV2j9[U̪ڭgw?{9[U̪ڭeVns*sU[ʭUmV2j9[U<ns*sU[ʭUmV2j9[U̪ڭd:tSN`:tN: AyTt7Y+@0#sюtlF|: "{/q@4+^!849*A~hH҇Pxƣ4Yri!:%fҠHCv&tR#YP")޲{g8R}l{5F L[aaqۤ1}*?CNO{~%;19ADBq#S4V&LC#Nku#]՚FNԠ-o֕2 Dm2dK7 l*??YCt_0R\[1CٶtE! !ܗ"bVW NHW^ɲ}jj3^]FC}?y+Of~0<UW۟ퟯk~s>3}K`8ox& EÍ~Ogu1/v- _)$ɻq[=/}>U9[U̪ڭeVns*sU[ʭUmV2j9[U_>>>UUns*sU[ʭUmV2j9[U̪ڭeVns*s.{<UV2j9[U̪ڭeVns*sU[ʭUmV2j9~~UmV2j9[U̪ڭeVns*sU[ʭUmV3oz>A sU[ʭUmV2j9[U̪ڭeVns*sU[ϳ{{sU[ʭUmV2j9_*|w9[U̪ڭeVns?~~UUns*sU[UUUUUUUUUUUUUWU*UUUUUUUUUUUUUUUS{|UUUUUUUUUUUUUUUUUUUUUUWz<ϣ UUUUUUUUUUUUUUUUUUUD$% 0"f97ӓk:eVb90Nytьkl;݊|ͧTWR1 @8TYLRB$l/ #YQ;ہ#SW8h%40b/ #'?G Ix6:E(R L%C~۫)k٘e {9֟iVC:%J 4%CER }5/?PJ‰mMC2Jc5w㛰Ԇ1f1rK " UXV,ZQԐl._ ݆EfZ}k8"Ow(>`- 3b9ؑl d4\G,IMknWqHnnkVP?ZjիVZjի[ѕ.Z//jEA9Dyoݮtl!q0)}3g9ٜz' ֧?C>c~l,Ͽ+~_ *{{{{￞x {{{{{{{{{ߗ| {{{{{{{{{|*{{{{{{{{|y{{{{{{{{{={נUUw{{{{{{{{{_/UUw{{{{{{{3*UUY{נUUzeUUʪ9UVs*UUY̪UUg2eRtӧ ơX2>'>^gXe=& r!-Yy'X-`or jAG[ > իVZjիVZj~[VS{P2EaN9ԍZZkNS:\ǵ8Z%4*K=U+''ȹɓ~@UUfs*UUY̪UUg2eUUʪ9UVs*w{מUUs*UUY̪UUg2eUUʪ9UVs**UUs*UUY̪UUg2eUUʪ9UVs*~geׯ^z> UUY̪UUg2eUUʪ9UVs*UUY{<UUY̪UUg2eUUʪ9UVs*UUY<<Ϗ_yy}LUUY̪UUg2eUUʪ9UVs*UUY{<UUY̪UUg2eUUʪ9UVs*UUYK<<=|UU@eUUʪ9UVs*UUY̪UUg2eUUϩUWUU9UVs*UUY̪UUg2eUUʪ9UVs=UU@UUzeUUʪ9UVs*UUY̪UUg2eUUY?>>HB2f?{c֏QZCDq~vD%D);5@80Q:`l(Ϸ"X'm+ d$ KsWw!7NwbPD#|7$y^h=jիVZjիV[B𭠩eUUʪ9UVs*UUY̪UUg2eUU֪נ*g2eUUʪ9UVs*UUY̪UUg2gUWUU9UVs*UUY̪UUg2eUUʪ9UVs?^39s 3g0g`>3g0`9s tg><>g0`9s 3g0gꟷ_+쟁yOm83w?TyLX05Q">HTJw$w#ll =oK11RE8 0 ąj,);{p -xh%h)$)ݔrAё9&ˊu?ouԵjȹdqYd W^A%m~~.wRtvUr`mGwxe, 8Y;stLQEP/3H5XVI_߯ٷGb"VpTeRN97bY7@P}OyErEc~!^ޞ1fg9j%7<{.G]Qv%7B"zٱuk{bW =??}?@UU@>>>~[?߸~!M&Me :,y97n-ؠײmz"Քq/~~{?`9s 3g0`ϣl9s 3g0`9s;x3g0`9s Uz3g0`9s %U^z>yy|g0`9s 3g0gUY3g0`9s 3?9s 3g0`9s;x3g0`9s ׯ@=g0`9s 3g0g}y*3g0`9s 3g[pW_ڛ|ב'"^;QDչiSQ0%6){K<ތU'6ɻ'U& )މ gGju|Kv`Xl8d;Xr@Zm)Mko)!leG<9Zk(\dJƿAtѦd݃&s m !`YS)k(_'rgQڮ!\WA.OY̿ ^rԫTJL6\6?L.SNh3gJ!.t\ȃP3F]I@2QdV܇^@>\T^apTZ͖Ҩ:M _rkWShh|_ĐzN"#)INCYyy|NGYjp}ex7+ W&cy;)w*Hi Q²KC^e*,Sc{h5nPi𜼽j{ s" lx3Ye8}G~w19g1߬&et*MnOkـJeF? (f)B4$Ivdin)~KQ+Ȳm*y΃|?duf}D :S{!HLHbWɯ{he3#['{ J;}?+I|'j.ern: ^i+s݈&>hRιbp($%Y7ELiUr.1Ĉ}QA}c =py0fF(b ún<=$ 8E^Y0hA|G*1xW џU(hdnWIg'yPd@AE2]y[nr ?a\5kh*9}Hy4kqR6>':B姄x_}Z߽gwNw 8 &j *,\](z >devOٺK!{G{b9k C9'ptv*$q-Ү"6+}!ܒ'4.{kJGM5 }u\ ̀#o= q;]Hs/ _QV'n,^2hEͯ$!&?6tڔ4Q C lJ &`m:kb={TGH-%Suֺ֣>Ұ0I\+G w2RF`?ϣ@a*gFPzC;#-wvJ_xv9d5xnk=45S PZ_' BQ7'"o8Pjhas%ʧcAܠ}XJXͅ,mZ_BŢ.t*h,M?P8(^/:'k8X`pX6v29#E@ʭ7ԕqJ&0&h[,7]M~o~Tj&ো Q pt-jQ-exasr6ͿDxs-"RI#+!3CG:)˚manHu%8NHibxGGG(#%;Ro8{]LpG[iB%8 l[ ;^%y"r#Hk$fHCq:$-R#;i@nʣTR|!4 LuhY{e9TmNa#^Hn .qQvJ[9sH[@p(N3dЌêpCq?ܹZ^H8Yl]_#^0]K%3~)r&8U#sz4@~Joi& - 3b m~֥,\dg鐉'DFx:%F2sފ]H%Sz"C8J)J/1Շ?} *2B-+ AnFjQR`Hs7: e=2fQx )Ho%< 吿{ izH'~ 5dhn Bq8dz9c!"@i 24G9bƑU65Q8T124-l,fN; !7Rog7ݓBdCC?dwB$Yf~; ZӐ葆@Jϡ++"֠Hcq뉵/Z [8 ٢ަ0F/.5Z&Ҙ/}pFpD :|ˋPko1D6sz$e9$0F8g#ڽVdZYdsg6}1OhNAqaHJF!%af$lpߊfI'͗n_x*RTF7&K])xsLU4 CAv3Nj i UH.KEQ(vJqgNC([b t'JUGFフPv"\4v;2LvX(!\t~nq8l-Q0|͂\5"1|CL~'2†A/}t~&ĵfAN4wI{u{N}}Zb1E5:r鑸ܱE%PvFYD p T_/HuHZ"|v!=1(.K&X!-QyJHF /m(e'R_9`av h8d$&by"\O86Q v^kPY>qe1rJFd#{HYӷU:<sƄfpBsϏ%3eb)Ȱ@[]ESV@Ol33[PA oܶ[jP9AZFoM;IEi, B!H)ǜJqwf@@]{g7vhd65]ILƣLe=Gf6Qޤ|@'6p^F!NKdWz>TݠQ)rȃJNWp Eȍ+ŷ OJJN~3Tz1!'&fTzk <4p\ 1'Ah,MיSz;|xC{L5$n(tnH$kp!otҰ*N@2lfn>h?||=f(@H„6AY@ 9_ˤ!\X?kIv@WV !k)E5/vVF S0g)4Xoݜ9'Kx>@Egޒ9~C&T2:ԍ3[o/P2 li?P~^n#GuA}QӜjO*pŚTHE~_c)btl9ˊ.;9\s`W  /#-0؍#lmѹ @AY i)ù?"04J^ϱz6 80d/Y!;Ani؜N4Xt0vYO!sжOV]R zpb6dZAI9xNgX]nSΡA65!  S3(W<<9ͧߜDh[#5Dž5 uq2/iiRדN'w4s=Y A>c_2s/ (^ҥ?V\"єv۵MQ[ O;zcSG1SB"3hXse;4x-SI+("+6oi?zK{ֳ>^}+ t5 B 5S; rKZ]V̘b8m3\ g6`}So.Ej%5e583[*;KgH}p'*Z~wT}Z~JØ25[bx쾟V?drRY:DE|d RyA@ FȎ#< n ,+gd~3٦J/c\K_1!#|B:u/)9ñs%^&W9+9"͗BPFkDFEAF<=u3ckKL[;fTT+k M9?(%.zx~$$_0Ã`3TO Isa@y+FI$i!9FlaLg//2}E $bP`y(6Rq $Ye#Q>q GR۫O芷̊f\&QXp]ZNS@gz:aG0~XR.-`MyE82J?:X\(xɜe $>go?i zϵ١<[F^KTx@Tm:c^Ʉ2Zt(ѕ2wߜ9 Dw-oPZ_V $F{fr|f4x_(ʠwztOVF/ !LJ"{i5'aS|fF{йM^8FP)ѳ8/%~Px#bPR#B)rLßBif$[IFk`ɦfz2]XC{r7FY8.Π9Lu2Gp7$zo!E|!rR`NH=u(Fԩ^w=_Ϊ7 sAs˦F d>ꎱvSnց-l>T.!g\z*,uRCLHVE嵒T∬FAan[@f?;Eh+R Q-H- Ja3W9M$%mq]NUǬcrI u ;˒j |́Sœ})RhDK'8V P`F`[!<2RK<\ ZDsLU3=o5}[}dwL.¦m#jU+?VvVgj++9%oWJUr{వ$3VO=?<}ocԌ5(U G ߿?uC.,S.{>AjδS`Ȭ:i}T}ܒ@^`7n'w)6 \CƂœ4_/e ؿ(@&lgjz\1?2NmHln<^ط-"q8TUxTӑ=BQ, cgAnhBľg];o_JڄQ8Kt>ke_^g]-Zm{du KQG)̴͒"`ٕ!LM>xC'Ep>iaH.WRh2*.C]K3QNVRtwϮL+2]g"Ҏ!Mi7YW$!ZXqJi'/F3cb%2{x&f Ib`YOZq$I֠u4tmn~ĩov>{vj~ /2aBGN(xf ݢr#I#U\i! v}C6R[dzz5uS×}XwV.ruྫྷTBlZL>G^ j|1 K T?|pBbr==_v"1]CQ!Y +G ;@v'6Ʉ dR닊NR cmTM{IE:_ǝ:V\6+xoڿtw{ª1,\ߧ1{w b$,:SՁ䁻h91BI\ OƂ[Sb[)[G'7޻aV%'-[GL] n7ِ=cD~ēY0d ߈>>`a!4׍uށ+lUo|d}r K+LuP x1768n f3' M֫yF+/{8qSh\K|dt r-! :sD*vw>}1Jqi>8-ZotP5 AGL^Wͺi 4kQxfu Yż|%)>_?܍a\,ZS#KYMyUX D<ǗqV^\2:URLG:{ +uI%}'lnt ǯ̓.?{ ~/[W)%yvr`1by#b꠴c^nʍF52PW4'ѢO@%!xUKodْ#B$P@ "HHzR[LeL'Zu|?"vѮC c=1]]b ώ’!.kQ1F)yj@x@jˤpKM,Lyʤ?1#TwޗbD7bXV-gblk?!/^VT"+ אU&qXHrLw,<~N);nU'v댛y zz?)Zln?uؙ["-!9ByQ"ÈF8џQ`s]0|8B5 K ݯRiH ">T)B{B(]pWdc-Eogv;G KE/,ֱֺ?43NPK^5TLpx#uϒzěa:}4Ngg%ξjl0&)֡U7$;Nj+.eũ'MU3Uj1hY{*Hɛ:=!:<߆!9Ě^2Zj;ܯHt=rITz=?.'6whwOKbc^7mHU1D0X=͙G:nre㐺TUt&E7Mg:= "p^/*Vw륫\F7'&&,Yxvǯa5|a+_˹9'WfqKJ+gq| 3{!;E)%9W[Ж[ZQ[|"pLS֒NPNc}Q*]VNu~6x()Ǣp6YKj!̬ojTZ&kxLbYMM ͽG[^VOw="x0H9d@Y8qnŇeReUvCBu{Yգwfnlt> t?X:~}vֻ ;|߿kPI>*-ǞI3)hQa\Ԯ.s7kH~A,.<*N}E;R7ށR_OR8%qZy?eƖY]+RcdZqyH#AbFJ>$&p>v,k镰xRx*Pz.Efr&a$,N%RO> '4$5z^101*mɲr'Yp݌SWG\qWJ, ^YSvwI^ͺ:{0Y^};/%AE@X֮jk3NgjQ+ԈeP'ͲMAYd- 銕!7ҦI~c>0#{^6 .R$xS- #4^הjK;@.eL>Qr}]. Q1~R`Cea6 &d)v#f6>#gΜȸ»oۖD[ԉjuEMt!OӶc^sa12N\H<_j+d* T?R72̃!nReKariGufeGN''[D2Sy贃0deX$ݿ_wlAO 6ul5`%uMBNU{S.L. X ;4'&3)Wh*^e{oZ˿_VqE{ubTjڿn0jmxM:of;Յ69Lk+qxF/BxvaEEW R>aჀr 1Cnݞz]EKw#63z{!59-]eUx_E`"?t>l2yOPOj. 9ؐSsZ@'fg@-U N@ܔO~}f?ޚ9;f?hBB5g\p}O0 !19bw >mXs Cu8ӟd}֞zQ/S%q$ ZTyPxvT| uO#z MaƢS0X/ 9$`1E1L59Ns bZ3t 0!hCrR1 3:d/i,qڣU.s18I8Œ%!(]r"IL`J^ː1zsQk:Z h0 gr01$HA@lKȌ`c CS F QR闘00191r.O|Tm `F`I@PudaZB<1$cWt2r6|70Fh!6F{1D~I l뾑tI٨59 :M`r@Ɓ#y9pe"ǜhb b#= #}G%To!1a#Boh0# R\k8ܾk݀sO\1 X0g9F4 oHF> B@l #7> tݒBk#@r02^F1E. @M∌+bD7om y )%Yx:ٸ>uGgg2%b耪_>`=䌐0&`?|/|/fJG*10JCjA$}?;w?d"09N -dcyS?X6@s! h Y ]Jg "Ys IÏ4`Ǔ1J C8q@6, 5Da  F1r-̪O"# l!{8iˆ9D$ Ά$q>>$ =WSZ]"4KUn҅\ۮo;mP4ͺj6f~>;0 &v=@F17aK@o6"`a)|; v8J[]S0@70ZzDAʦjb InF! P-D,Xd/dǑo3A o&r2_6Sk!Q8X*Qpw1k d`F% w#89?ԜA#}DƲ#bs$3E{©,aNhY~"+XK9b  0j?uD0ǰn|Oڄp`pFp˨T'~! b0c#i R(|#F B[h ˉH.!~; Bt8cN01m3N li =c!@wގaͿҷO4f|uH7'3sö0 B6@{ ["qJs̍ǎ8 `'tp'5߁FЖ+q@.zpBoQDL%P):È]Rpa @:mo!C}&oF JC߮!v!I>d3w!Ͼ# 1I3Ad CO/0 a@^%JsTi!j;W0ѝd󗸌6U"9\`(Q01~v%CyYdVUfC4Adf- 0)/r-_ ҉d?ou<(*H Pcӊp`_ZsO7Ĺ88/9#w͖">`e"Sbd3P)ƊnެC3p r# 61kS܇s~K^՗4 x ar?;/s& =ۢ?]dc`Ws ]ՃcLqfA[spYcȌc%9}bC!X85i~F C5:sHŁ@tu Op1AaUF%-1U*:H 1L@8ЉG tHtJkHi8ޖFIuζc KĠ@nBї; 2MtN*G8}ih6hceAJ]|% ^ʄwa~K}lOy4 TbFXDEaW9fd:ԙoz 0?_8K*v_'vKy.>pI'+ 2W*99?].'@)4| qBhm`5m2XL\W[Ogzݠ*+slm,5C [$$A  ) /)$^.e#rkvWIĂ줫?%dd>Tw\dxYIb,2+2LgU` 0HQX W9L*b``|7 NOG+OHwo8\mYܡ:K~YKCdN"djN֓x/poay3Ҽ5HMIUgle!mHqp]gPă{ۆǬ_8@z 6`Jsx5ݣN;Olqt<.TW H&Y_ϡW$'R(?6Hb5?ԩw[&nC)30Aӄb11JF3Ag5z{rJ O<ń͗q%ވ$hj g A,#>"_? :uZ`#yݤ9 `(P;ч Wa7#Psdp`?0d 3 j t 7,HMxN $y q.Yhڦ҂ $F6<˶Aa"v"C_Y];SzK$A," ^wE' -L7d~0{=i^[;H{Mf۞ )^G Zy"f6Vh;?r)"qIbƩ&|9$eeC2^r[B$`(zt@ɒ&0޳Ao0R绶_ Xc<^BMH VyQĄOL ?XӳCء4,)O?̃x]R%!+*q#fJV _ۻ9߾o|Zbc)Q N> LNyzf%1S8]A{ȩRmf[u*vzSic״Oq&2flr -K`~zXv죚RZ|;,mϠ{[u*AԑtpSk>m< w8:S8dar?$$" pRBH;-j}-pǕqxfhBI$$BL330,$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$O!I$HI$dI$I$I'I$HI$33$I$I$I&ffBI$$BI'ϟ>I$I$I$2I $I $$I$I'ϟ>| $I &fKw޷{I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I=32BI$$BI$&fdI$I$O>|HI$L333 ̒I$I$I$fffHI$HI$$I$I$IHI$HI30$I$I$IffaI$HG_\~O?~_I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$T$I$I$OI!$I!330$I$I$IffaI $IϒI$I$I0̒BI$$BI$332I$I$Iϟ>BI$$BIffaI$I$I$ I$$BI$?OAcz?z޷I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$|$BI$$0332I$I$I$adBI$$BI$I$I$I$HI$HIffdI$I$I$330$BI$$|$I$I$3$HI$H2cFjA{N2vX ΏC2`ijU%w#ܺP@R!сw =QO Ͳlf0ߴ3𗬀/@/;ϮЖp,kr6Āz.-, ֵ xϐ.8d}64sevЭTκ[JcT2}:_$w}-4NXanjZC0?}sOyy;i vb^}>ͳ{DV/]^Ԗ~1H|k>03g TzZJ[BOF9.ʘ&܁Hu̦,Nyh7 mNy"K@%Ĩ[C>d;LF4v{S1SIssF ͵"L au@y1|DGĐpBssպ񞭜ibkj{M/qTv wZ(nV;I`e1PC%K0`m_1A5(^w|&rcyЏ!)n?ݮ4 -4q4'i459]cy!)t6LJFI Õd;nBMD y/G,"CGXL >wKBlC=SUn_x׏=/>gǤI$I$I'9I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$sI$I$I$I$I$I$I$I$I$I$I$I$I$I$I'9I$I$I$III$I$I$I$I$I$I$I$I$I$I$9$I$I$I$I$I$I$I2I2I$I$I$I$I$I$I$sI$I$I$I$I$I$I$I$I$I$I&{P"1f˨M3n"B\^}LSD}Gdn!Ëǘ7!1AʍCA*"S prj/ӿRphp;YWJeD>o3=}нߏzwI$I$I$9$I$I$I$I$I$I$I$I$I$I$I$I$I$I$}|I$I$L332I!$I!&fI$I$I$>|HI$Hfff$I$I$I032HI$H~?I$I$I'I $I &f/z9$I$I$9$I$I$9$I$I$9$I$I$9$I$$$I$I$fffffax9s9sa$HI$$32sI$I$ $$BI$$C33'9I$I$>|I!$Ifff9rI$I$Iffa$HI$~ $I$I$I9rI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$BI$$BI$$ffdI$I$I$330$BI$$|ϒI$I$L33$$BI$$BffI$I$I$I$HI$330$I$I$Iffa$HI$?~M7I$I$I$$I$I$I$I$I$I$I$I$I$I$I&$I$I$>|I$$BI&ffI$I$I$L333 $$BI$?M?I$I$I'I $I &f$I$I$I0333 $I $>|I$I$ $I $?yo4I$I$I$9$I$I$I$I$I$I$I$I$I$I$I$I$I$I$O1fffffaI$I$I$ I$$BI$$I$I$I$I!$I!ffdI$I$I$330̐I $I$I$I$ HI$HI$L3f9&_QI,'E(GӛC7G#2my=! Vq;s#vnpX&{w!rN4h",3U2Oah2HX"lY4v I$FH@ i W2nyoЖE! PB۬s\z94Y:yW+UJC;>[9Rytzv '>5y~ d?EE*o|HC"+n0V!a A=(d)K1j0'1؈vqOmqH>|eČWJ>qIF< }˛qČHCuBvzKEDW E,]eIaZX-a5ft/d';~S2i/m;Mឰ_or z+mGǓ@^-V._(`iяEU&dyÖh/*{h*0Ő^<7]-OyKOQO.ۅA!%ݛ6EX +L4U6gZRzlu@\1Q8 -B$S|||'ϝ"I$I$I$I$I$I$I$$I$I$I$I$I$I$I$I$I$I$I&I&I$I$I$NsI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$9$I$I$I$I$I$I$I$I$I$I$I$I$I$I$NsI$I$I$$$I$I$I$I$I$I$I$I$I$I$I9rI$I$I$I$I$I$I$2f +#nZI ËL+z֪ nv% K/@PX2u% -v5bht:C ÿ'̀ip+`bWz}lTM۽ v_4V0F1cI$I$I$I$I$I$I$IsI$I$I$I$I$I$I$I$I$I$I$I!$I!$33$I$I$I&ffa$I!$ϟ>|I$I$a!$I!$32I$I$I'ϟ>BI$$BI&ffI$I$I$L333 $$BI$?}~I$I$I$I$I$I$I$$I$I$I$I$I$I$I$ffI$I$I$OPI $I &f$I$I$I0333 $I $>|I$I$ $I $I$I$I>|I!$I0332I$I$I$afI!$I!+y=I9rI$I$I9rI$I$I9rI$I$I9rI$I$I9rI$=_~gI$$I$~a$I!$ff$NsI$Iffafffx9s9sa$HI$$fdI9rI$I&$I $IffI$$Iϟ>BI$$BIffalo7I$I$I$I$I$I$I$9$I$I$I$I$I$I$I'+y|I!$L333 ̒I$I$I$fffI!$I!$$I$I$II!$I!330$I$I$IffaI $v$I$I$I$I$I$I$IsI$I$I$I$I$I$I$I$I$I$O$BI$$BL33$I$I$I&ffa$I!$ϟ>I$I$I&$$BI$$C33$I$I$ϟ>BI$$BI3 33$I$I$I&I$$BI$??~lp0%ԖK3FE6WfhU{WSCPbb6؟\j3TvD1m=2Y={m\jƑw_[㐰8"ouwz5l׷RSL~}Ұ$⿞7%w")E1K6q-^P?;H {mG_ڡ>]ج?D/9Tφ08?3˪B_} Fx3 fH^w؂FZTWL8b;#YT ,h#*r{`4:|-wg#tymR9]?vkUwjoI z^)Qe:$ƟPPX{,z}x?1Vsm 35ҤBۙ7&|uRzJ1hϟQ}bkwb62d!g8s#QfEGЅys`T9)}:o+2~cOx.y 0SkB['Tb}Y/-4?iWɇ$u{YMXYȏzGæ@mvP>T8lQhN7*@cSb_vPJ0D%$E-%/1 ?r_=NK5\ kxHr? dWEJy\.zG>eUtG0ZhvyE dNRySM{_KȊ9HqyQٟ4^Bjj87ll5EIOȗq$кґ7\z8p("鲗|P so"$2~§%EɗK|K-Ï'ow04ǂ?ƽ5:wjjm|O85I鹟 ᬌ4ݨ9ל;$.z}ӹ?+"oJ ؕ_2A΢6qQ)15z6Na`LܢLۣW7#M@6ufu;5/l2?<GE}I9oK8RᨲJ;[E”iS;cgHp]9h7cnOb*a/dmìghAy߳zȄ*F?[5xh*e 'lC#JNꞰrŗ@>d%+\QȖydߠ 1C||XQ v?փH5s' 'onTFx糟_/MSf\L|# = 蛴dN9 r .!zM>T;If.ed,EԼV\?ސc/k7v0w!MzuvTH0)!Ӕԑ= 1ʥ]l'+#ȏ2btlV"5 Jgf@ϴءϘ83,`듲$4j!?G:;=p})g"4qZ[_h[.VKǷLM+Q=E7 :"VxcӘ;asCW8YB\2%f>F&fJ_)#@ y_0ex3y4h K\ʑbb:>PI[O.J 9ÐTq_+BU+_]0R-lS+g?Ν.{?;uAe}o>W5LO-Y}sx漄 P` 3(㱔8'z -E%|%ǃPח}߭!Qhaf(B g@57; FzF0L_&M) e #@Ē?[o7͙F6=#n73hvZApvxyl½$ů6+ crkެn{TE,!<-!H֬CK{TL A"g 5WdFy`Ź]?AӏF>#sB,qu1<-H&{±+>g'I4$Ŏ$`OAGNw_Zٕԑ^.HSNqk—3Yj U>VYE@{ U%1;8x۾EM5Y@O/8^OW^ًEP.F?XURdܹsuN7qF SP坙BCRbOMt~*X< -_D"~~{x}A>>$I$I$I$I$I$I$I$I$I$I$I$I$I$I$sI$I$I$$$I$I$I$I$I$I$I$I$I$I$IsI$I$I$I$I$I$I$LLI$I$I$I$I$I$I'9I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$sI$I$I$I$I$I$I$I$I$I$I$I$I$I$I0bX:TJt*؏36n~F:_O׉҉7ce[>?Wgiq~fu'oP8nZ 2Nٺvx ~{]iXlryKI1l9I$I$I$I$I$I$I$I$I$I$I$9$I$I$I$I$I$I$I?H$BI$$BIffI$I$I$L333 I$$BI'ϟ>|$I$I$32BI$$BI$&fdI$I$O>|HI$L333 ̒I$I$I$fffHI$Hs_$I$I$I$I$I$I$I$I$I$I$I9rI$I$I$I$I$I$I$~xI $I 33 ̒I$I$I$fffHI$O>|$I$I$fdI $I ̒I$I$O>| $I $333 ̒I$I$I$fff$I $~ֿOc$I$I$I$I$I$I$I$I$I$I$I9rI$I$I$I$I$I$I$I!$I!ffdI$I$I$330!$I!$$I$I$a$I!$IffdI$I$I$3302I!$I>|ϒI$I$aI $It^<|I$$BI3 33$I$sI03$I $II$I9rI$I$HI$f9s9s!'&I $L$I$9$L333 330? OyI$I$I$I$I$I$I$I$I$I$I9rI$I$I$I$I$I$I$y$I $fa'I$I$I$O!fffI!$I>|I$I$aBI$$BI$332I$I$I>|$BI$$0332I$I$I$adBI$$CK/Tlϋcks+rh)@zdn!%޹}U ĪӋ_ ?af|kJFzNE%^^%:3@o%&pkt]큌eÇm%+Xf>|3ލA55m;:^H`Z`UY>0-@T= E2UoQd%8|88E>8{ O0Ԣ n9G r)M=R RVS2vD"ßٺEČkidpfc`&Zg|`jO@RJeqk V^%o)Hou_UU=U1<9,A+8Ӯ%o{sB=-}xsg}(W|7&Q,\ Pj3IQZ&:Tlޙ@\O3Cl>\kU6T0-;VY_ ^_ֱ8XJ \k?R lgr)li+kޟȯrjHU)8pԩ[ Tֺ. %6wqa4K /;SU#XaɣM_ -皼srAbJy3< CpQ9ZXCx-[د+P,HEf&gH,Wx)yX> B)8eztf@|:je3OciRb!Vt53'<: 6U]Dq; sܭ_ʱU.I G?QC/}ʩ?K~'BȈ<3!y% ?Ա9C6ҙ.iJ !te-dvk-(K|=o 7}ivKŕad<7(.| avO9i&:VqۮivnuXi`2Z d׉n_fsdNz4wdS 4-]Y}O#&_sx2AZ}$@;)v ~Y5:Q`jy+8jw${YyQ<85' ՄdAI;$H>Vy?cWPQk8ԍ8W Oq'>%á^a cL.Xze 㽄lUWXI5a_>Gsd|-cbxΝzs?A&F:1׺ZJ .'N(ѓC+d 6@I$I$I$I$I$I$I$I$I$I$I$I$I$I$I'$I$I$I>H$BI$$BffaI$I$I$ 33!$I!$ϟ$I$I$a$HI$HffdI$I$ϟ>|HI$3 33$I$I$I&HI$H~O{ߞRI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$YI$I$I$|$I!$ffI$I$I$L333 $I $>|I$I$I0$HI$L332I$I$O>|$BI$$333 ̒I$I$I$fffI!$I!?o[֒I$I$I$I$I$I$I$I$I$I$I$I$I$I$I'9I$I$I$>|DHI$L333 ̒I$I$I$fffHI$HI$$I$I$IHI$HI30$I$I$IffaI$HI$ϟ$I$I$ffHI$HI$G}Ϝ{i$I$I$I$I$I$I$I$I$I$I$I$I$I$I$sI$I$I$333 $I $>|I$I$ $I $I$I$I>|I!$I0332I$I$I$afI!$I!$I$I$I&I!$I!$_7x{DZI$I$I'9I$I$I'9I$I$I'9I$I$I'9I$I$I$=σy+}4ǝo?_~-A%;uPo.Of a FcNø1/T@r>CUTYZ?ANpa_9\l}UzS넏y[+#ֿuaW>fL^}U9mTrpZg_oV\UJܴ]AIA._ Ơ z.^񬗤L]@~t5׶cjОRQ&u0C,AA"i$$ʠWy$i?z@ڧLk{x!Ho vPƎtj\rd,5p|Z#zħa8E]I1Xҭ]>uymAN مzWl$5hF7Cty,OYݾ$M22& Dov\Ƣ =Y4ubUoƀj͘b:g v_Ѫ{Z]S;+'a¬N0&t<.+6R}X6 (2t́xQ6\M; #X"0ES>LWiv{43g6=@*1Zò}E'" =;H4c:]sΔpNkf Z'| n{r?y*?>JՒi#kg:4$F̔Os&luB Ō#7npcVRQJdw2m9XSaAhE!\]2 &<Omdh7?.שcI! 9玩tqqy㞈ĀXA?`WZKmo+C_I`OsLg:-^P=+խsNp2rs-Dm.F9|W?8f7I1'4F{wk^We$||fMg\EaƩY Koޯ1G(Ԑ+ L{}:X|H QI^֓kqJ8ZRN6`k\:GYq2!yOm9i~*}~˞Vg-u)l6LJEAf۪R_OaKir=^Ub} 2>\IIg8K]m1Ho'&izr脞;W%ջ-ЁJ^#@Z:wbl}[e&ΪiuZj7g5*ܞq A([)̬tXs.q]TUzRuy1_|56GhʎfQ˿InFb)xhx0553M|_RЗ!2B+kJQf"$IIQk5пF}r-n%ծaIaT9\ͤ|pԣRYkNl+?zBn;CoreaLyl>sUȤ9 p.ynU-m!␦yqb|C NZ+LT3{w>IHD4FD(`TmKgi=bG$'%ڒN;FGgOcrC}I+nڎKI}Ѻ%yria| Vo俞K a]Z2 O('[/_w>?l姴r: >"S:-^`d>Kۅǭ O7>!AUY4TwoKBdϕ9,g߳4]F!4N`k? QNNDmC,dH֊lĵS<5pq3~ӭ.?>Ŧy4# FUfKT#xuJSaG?ŹzI9xf>\Vt(JƘ/c70ɾdm<X5AEXtԶ//Z\+.s<{JnOBbȜң>AtS:s⌸sQLһG)<簭fң3h}EU(f%WV-wYtinZ'x+FT@U5g>LϺ(adt͗޵VfEFw$ZlnWH%8g\RG\Xt05͵aEO"߫>t:rzɗIJU+ǽb֧x?%nI[R}+dO, 2@4,nLʈ~.wp2'&N"hFBwZ6b.GR>3I%)e*[HBP2@g/90MۚhҞ2N'`o"ๅj8Sh^fK-g9xIX*Vb 0۞jTlf=7و?~o_lT7椏4&퍀b9 01+3+ME<C/&<e,,w " \rEC` ?2XogP96Oƴ'`YK0PjôY  'j|+u{J*Uݛ~"@sA.ie:$`TٓG亷p|\Qj,VsGm],NAM5ʄ , tH{ބlrHY%wVwPSxxNľ-`P2j #t3EwFh3ܯٓ9h :iddrq~-AI/%)A/(gl"s8\qQߙ~(m)fnƿ{fZ|!BN/`7~[EgXRg6vHpjط󺶋hߞ`_.vЋ9oZmW2 J5ko 9[\%֫xy@m6}<Ӯr]o[t WWV9bxV#Y˳e6{85 o=钼#Sq,vjF)f m{6?h7g3>;3P>?TIO<~)@QYhR".^(]E`:)*vIH/FN$m|oE1is#$=һ Vkƪ4aB# 8ϻEFGճS-f,,\1n}|3mL}om;ka Z?iCY/Qj ivVZ_=c9[k2z#c]y=9MU]xYٯ[])o:‹6_t5%1ebk^O(2T t$f]vN+F[<|kW,Ҡ8,$p%Z|'pK%al!xՁaDH9NoǢJ]sWM[#)yJQ"e_Ʌu`+^0iߺO( !;v=*v1V"=|w}|}{big}Y;<~GASoaCR#HP==Ǵr0DP^If=/,uXc,s[6h))SIe[ov-)!Z }K>LD鷜󳋋9Br~-NOe5GtJHx=% b) LMRCT9Wr減cߚO'_H# Aj~[ú>MT&~*H$OTFeYU}\iч{,/ 4ˤXA{ o2]c&9~XGMRoM_>mQz^ljy4<¨G\.R.+kekբg#>[Ish,ݰ9.ޑ‹'U!r)$uT@!~Q}}Y7 aRXU<2q6KԟՅ?5Yx=_vØ(-M.<ؑlg }ERȑX-0: EŞ,3?餿&JG]v>cZeo}a§iacdJlN*"!w`5E| !gUDxw>%!f<)4e$v:,U~0nHPcRsQċϸ"ա%C~Y8̈*5(Om>DᄶOi$4{!H0Ϣ@۪ $^xje>0(U''oB..4V݂Hn02bҖכx@6J:*I.P_kJ2CnWʜY@u>-|]C, 6uc;6S5Lf; y_"!2+|k0':^3qC|*_x}k}`W2-$^Pm)@fQL3*/;4^{Xm<҃'-ge%u aGz߼T7w]oc_rٴ=,-Ҭ[~H0NWue[f9t5g``mpP]u#iWs?9g8A>cʉwxATey*9)&7/tGL`)L'|r`"j̄pK`lO]ː^T4=ʯ녊^eI3|8߭IOiR5vj/1ud`Rs"aR_ٴ^LJ'eF7Ca5cfN|<0gLڋ,VTz\<;4z.ʁ?}5etq8lg1bA㩔Suɭϣ;H*z>Yo5L,^gz!>rb+8xg~(jD=/*n)z2;f+U .]L|;ooHzaK =DS>x ~̟Qй/\kq{={Ye *>Cw[ܲkfA]]y:R ŗ xC76e SP_p$ߌtazC?ت.tv9Z[/֗FV2&0OB 8kpo]Fjbb^  )<(-#wBk)/H19njW1zps'WG3xr\b#U|hnl9kcr>A9z[DEYR4 LXRyΐ|*bdɼ 'n`ܢA$! i4& rŋvt^"Qχ2C 0cki/M7Srkƃ#SOSj|)i$ '"{;zf͇|6^νxorbdKίѓj:f+ hݿGiسm? _Fvk(,"2y֣ \z+(骅r3(yIaC!m/`uJOxP Ns&pJ;Z޿N}ql.OSSvs[z6D{ ;JKCgL7̭ڂ`á-x? 3.Gz7L}ՙ01cgPc]@cu˶_t8  μvd^Uyg$Vv&,wF>-; ] ґcY%"U[/E5S7AhٳN22;R]^/텋71zv}}*(Dr]kf+s"L:OVPK*j/<$ d橣bV@s5Eϩ@L%uP- !]}/6HY`Q\d k97ӳ}?>9lþ,'G R.蟡R*ZRDy >nRxQ'+;26-8C21DD-;PMNpĥczD"_+b( Ju>y#dß4#n1Ez*υ^/ јȅO% peY zl-p c o!ھػIBj;&j#Yp!uniK,̺7 p]sTNzm|оF:]GBMdKv v$p?}s0_ g8K݅3b%Rα L?GtWtJKܞbm,aQ/OuZZ?H)iS%mAM0/~RvYѩכsO Rۏ3݄;ggȎ #czϘ@֢́M3C^"{3={/3Q3oJ"AS$Jfh=s+ 4bm谺J zr&qʔcm MDBzv8ٵ\~nf[?"+?{ORJ]M]RÁHd#߲} ĩJƙ'IG''gѰ 9zU/°[ hWSr8V㱔S^8 gZZ4: Ѣ5|4OO7~쵝ʉ}wvSw%ЮZ]CUi7eoh9\ߡ/Ew_s$v~2t5 UͰTvR™k є>͇=Ƙ}`,mȟm]!Ū)>QNH5w󾐒BvR_?> #sEbC4X= ҌqGm +|Eu7M 0]T`rd%Dw??O+=~}Yx Uqpdq  Ouv]ocPw{9R K]U #z2lx`7,} 隆z{=d܄s=9 8 za+F(Z2g.PzuTMUzãk-1I3}%Y\z=8tW$5lݟ2)xnЬ+ tL+ơ}NH_&/mK\OTvuȃ` qRqTA(jUg=,dõfij2_O[s#wQRҜr]vm&\ :e{b2)G3L +S傼`qp  #@&΅qTc{Ey$+fȂ@IQ\ !MϏ%b9E!R1}e[e8 vZ\gf9>ȯZgw|;vX|)Pkcy*QRk+- -8U[;DXscj]G!A~R,5X#яc}ƻ/0u'nY`}KKt$fM>580MPT-ׇ3lVd垊u~f^p GՉ'*M-F y l9ѵ hh~2mdjzFWf)|^cxO|W"pgF]ugYKZGɐ==5$2c7$'ۄxff_EφW>,ky6cҘюeJ xP2f k|"|-$<Ɨ*W i1Tl?b]fsx`]j ַcKu#_$x,@?*MyKIh'Pƺ%x;ѭ#nn{]:V_+zr|;.S6$]xa0 &T}W?|Ƌ7~ d M28#(i᣻_xCKWi5?gd#s@!~vKoX4X@{SX8ۨG_C70wYuf\.jΉ5K?zCrV7?n{xx Vk-ی먈qt^5^u[\Fh_1Ηõ^T"eٮ^^ʺJ3͕1*j.FtvOov*ueOK߂^NR ¤:\;JŷZ~"0_j ?(D#?t-Gn9)_S/A$B1 Qg>r½W /=z,ĢM邴t^IK~,s1 ՃyhH p cIwZUν`kaS sŃV%٣MR~EO >ٿ?6o oIyAύkؑK77L٪(5z/l*g;}}NHٿ>E9mN)_ooGZ#7!PtؒJ$#*aBk0MkwWwuE%:cffs_И;m䬑h9"r>%GZ+o0013dN$8 zgegb^;uWQF޻+!Thď_ӾYO~귑EҀ%9Z|Ou v i4/_ Lcinfn|-?9(z_G={xYE5 p"ބ 5dAg^6@w 8潓u^ ~Y]7(E33-4t"XǦ) H#+4]L|wrAodXPmϓÁ+J_bZF( ,} ϣb./^^p OC)}nյBvv;dޣͫrdR6'*[=Rf ;w/r T{AAi!&6$b̖!|V<7 |4d-2_I'gd0 4V 0t(ꮷ>ɮ[Ȕ@g ͕ۙDt gS>dsӿH/ˈ{?5Z?w ߻ޚG5/?u<IUaHJ 6;K5a]r׊qXk˫8F;eAǪNuDn ;X}" j\!NBGi{x{TIBm 3}8YmPR˜-uɔHJڅOy.%]{Qle_6AEY-Ifypn}=zǮ8I, Wq cح7tgQT+jd3JAH-;ٲG]z$1*rG/IWKլ>ԭ+'!3׷.b|Rd{-VhZ[Ž@{ԿSH|Yz}nzցM5tp;}Ѵ9~ۤrctE~HᲩF ^\J~c:JXo+=lM_o^D3,ؾpr:FY;W70>>;^Iz%ܮ~wۭK>9S6񊚠+WIDsOeZ;'[ST4{@AnL@B%_Qג fI)$|w|0c/nL@H&S _<0UǵR?吅{oͨgϜٚ[4--@D"У6MS0 9 r2Gcybcy5cWѲNso/nX|;fi7. io^|`6oקc޹adevi~g8cXfs^ {ؔ}-qT n-&7msÊd!vTAS)0wذE2rNrwd(x*f;?oP9}{Ex:D/),gSYJv B#]DW/㽉}o]YtE -UW~:o^#&ZGID+G쐷EtYw߮_ZKh|gfL>LyT z 4tk^6?}sТk>|}Nڻ-͸3"*?w lz>p@D#5 5]VdNDvUSCgC ΋"d0؍ռeQU˘T6y$$V`hidP-0WU9Ҏf} B7q`KGyv껈VLem2hٟtR!{ᵞ .*7+E;,ZD |ѕdοS3{eD5}D;O>[>ZM!n(Û^!E*2(t,Y1o`w)e+oRu*8[=Ii'"(mgě&Nx·]uƎXV_/.cyk1Cw/чeQVo*69y H4FV? vm<8|B_#_CҪО>:vfLFj#Mr::3~t\/oչ{C1Ҵ j5w S]##Q )ѧ)B/'䫭*⌮޶Ns F+uɊM;?ڂ /orvg=[uL BxB6X9 /&VQ ƅl6ڿZ1eDmfSj(v,^d!$pT &)~޿ZFΑ{9 ;Ї h;_yYFQ.}Xn" ӱ=Z cl_B`]8WCd9tRSHBMWt>߱*Gj EZ-VkzJh 6H6XQC9ZD J*ρɌg!n@͐JD'fw] oEXz%b_K~f!`ws=\'2I~e[G/PЏ/'jA\rC)#o{OqWA.eF"*LrٴλvmD]Vv%gzT=Z||ϔc½zԾ]Jz:c/GCK6bwKAYV6B|' eGJqĻn3rkb3Ԥku搧EM8g8<ڹv^ R: {9u.0H oxj]'[-%ت}E^}cvwYee8`XPޚe9pVFCXD2/-j*|7zfIS|sᄱq.?ᓚ8Ũ{~ΰ[v j7pS|-=n#; = J;;ۂ ȿ'ΝѨ7cq0ϋ![[xa5ԡ5`8|յx!^oxb*'Zi9]u!'i9JOg@љHِ2s ؎vLy◦STi^#C=V;0[yph?K?|yEg/zLq8MAdHkIߨUQȫuBI͡˳Ӽeɸ| A5i^BʼغZ H0bYuZs582brn{T/9А>dp$q{2"`"`MDtÛr1C, KFCV9|D9>7H[I3r{l|0XXFnNZ8^+=#/&SGr dn}ɀgΡ\2pa0OS{D[Ɛ&&fП, *|=W:D ޼lְ6Ko߹MZ Orë|or'|t͟FXpfH;}mn:c ?>~lp{lR-hmxGE³l.A(xoW43)H'ZG Ss0)3E=`WbľzYHM|9?%cGφ?':z iOJAQX7\ngIyNO]VZ]dm%BTl}-aL?3cz__Хog- &.yc+% x=8f] Z{-? n r(K Fȸ9N5;̴3€7qRy[J0؉ wjNx7ZL 97LE/iOW?L"xTr|q,A5q_+m.K'2S ~vz|#=8_7v S$iC" ]p7?3BHF$ 3vz($E;\BeU))J]rN7+g} ;'J26MUdW;YcQp8JP4y&^"DZcL=1 '6S"H$ x4ruZDl蒕1/iBLEPRFieJ:.0/bPS)~(!"ə&'IkIp1 ;5\$kϧjHO#fM 0V2ũ^pհi@/t9^O+UWԑI]+F{R,z;{u* 2*S~6*8ej 9gEi iV z p!o!5EJj֢ھ ݒS?cBİ=vyZK??$mؔVRj?yB uLo d6GYPs.Z98;y*(K?ptHo _݋bA$CMd;qVs]8@KK)D"r^9[DLeb onoH?])ңS]yɅH,H:ybhRRKrab[jcA܀Z؇jwք@V)*a3%GwAM0[%wMXh qvt-p|Cލ)>֋:}- )Y O|Z9u*@F/r,Vb8%R[B7`<5E-)B3(uOXr5J౥vܪm#8^ Fs#Qssx) dZ%DXO 9tk;|(j='p-˦Uӆ ^B=;!F@u;yQ&M3*H kHs.*,E-t" CfCL#"jb6=H(6#?kO/5Rs?dsG3 WB eJ'86(eatUW- .xI2!|($!4F7 *F}!#W/3Pa=!dj85֛ZJ4)#}霌I#ZOۄ@PHFrtO*f!\$HxNC\\5Qa[!bPHnlz.[}ɌÛjPDUN&9 ӬNݭ8TK[[$̴%ƫ!@f;'\~4]=3S\di|.ԛgb64b' ~^^/ 4 T\o3Z8{#4Fx(k23TqWlP*|anr U7ĩV 8^T`F"y}ǩjiߢZm&7SoV~Q` Ys>xa pfҌp۝8 ⩎Qu|\( S=rt}.Q NKvΚ9|!}{)'oQQ3Rlھ^H]TO<(Ż ,kL9^$-r+`eaVNnc y/Ɔe޾vo-i2CfzL^Ͽ(_?T+v@u9 }"4'6$ TȀ:;#y JT ɿ  o סf"W3!%22sFHA2 XY""򿤕> A0<6cd^v1RsYCqbAh3hȎj<#|[Y,JŸŃ' iKY:>PH҂AP^N=?3ta]ơ'Pq+s3b";spӄ!|o`X#)01 ͺKGDᜇ>]cÅݢیG ".HacMV<ŧ㹘M<9SOt/j+]uc/W$t.+Cy\{64_dV_5 RAA&LBFXX$Z`XژLQvo&K!-L;8m?p5_rX ?Q.*K}[^>@u׉5ԓdiyn`f,_cό[ uU^'GX)5? %^aT U>v$ջUd= sM[^@4ܾ7 66lQR@ P~AC`U}? ׶kˤ(9'F43k IP84;u}7isaLVrhF*3vbSᗵ۪Fg _$@Ԑ0 H54_eaLGe.ꔟ4`{^?Gp 'De|#>"^ǜkݭHeɷo_Ѥ3k6^HDpa9`Ue\H]09$ߔQQEP!Qne"7~cI8t <$cqch@)%|& cS <X&垝bi+f)~d}$[CV_07Qz`:րR"Q%"d5nnF?J2de/B y%\ݚOZS?LzRЧ Ncy80R00( 9cH05I)Agp+˥ da#AFn87F| z9!xG4&T?'pr#*"ݓS$Ґ\Nq\Wi/ͪp,-vD@`3ާD|dhxlJLwgBZuNߩ@f,9J_<0&`i.Jz"p dv)ZTԑ먬j|hQUDp1vy =]0ZH0u LC2V9kmAgg!û *! i.U&fT+/E|L^ |Z9]K@OuY߻Ѽ5U@qa{ӾM=MᰗC|hBA4. ?ⅷҌ8%L}pu]?[V۰VTc@҆nf;u/)1`A H`r_)= 96OH݅h6IQA0"\j< @[%7-we=`>AJ6;r-j<^Qoinw틶iÏBbV!'vwMdK8f:VhE?R3bR1*]:M.|ś-ogg.@V}0' *h=T & L{#(!䄜(!aXB ?}(niC֡8thx0[gNN' ] Bs i}pJ/5@q`ƪ]2 WhC)8U' e\%]{ Ѯݗ"wCoVLo䤊.8)nxHϽ:geqQGǬ87yK:K:܋W'̱sHK1fN 1ck9xvT6>4dS$y2*(~kdD d'F!UovR麢=j)݈FC[ZUǜ#;NMr%KK\z=?w4I_b^ XRXCX[VsԂ`:[Otx'O!87dZsej l@|邘H8w"X/H4Թju@bsc (Etk.NO -;VF0q{Zc))*gJ ,YoV̫% ECLu2~ID3']mlK&0$W/:vzF֞\95WZ t)HjAq!ymЮK Vƀ1>NiJp#N^!Y0ke1@6q?]S6u[߆~C}|RYq(םqꃪR주\!PemR}wi=.7[0s?*~}\BPH*PO@Ҡ 2s ƏŖT"dYh\l[3N^ lY~Px}δ9l"ODO V|n~ zs}y_׷J6וdw=sa #H2M'EMŔߡaWPIsx v<CYO88>S F Umb)_|muwtV|\&2"$Owzg&Sg*׀n3'k.7+]vdi@4`;LZ|.P3\k_P*UX^ ʖ4oGnf;ovehZٌ` 7|!Ju&*C6RY 01`4ړ=0E_h1TZҭjw]v\o Dw sm KkP9% ׳j^.*zULj[{Ko _1#i`wov1"RY:b5x-v|3kH#\qAM@Z/|[%J^zZY?9k+}>O\Wpc2sN~U%\4fY| v!\(c=>wUp|Em_;8JOd ;ł{k%ש4~Mr PezUքj+6 i ֧ZEGBzwš7'81^Ӽ\h{G1 1_2aGPw[[cxeݥ KmurIbנ &On^Nm N/c.^[!E@L.B%܌62BfFUwnuޙoy 0+0G0h6reɭI<2:QAH%&%m&do]c~`ʣ09qd"eCi3q7+EұECk{n&0 z^]{E{ з'dffى?H,nK=N|`__mqynʣK7/{3!sp۔P{aRt7sJZշboRh9ܠ8է`OOKge'U5}6H\vA4v9%l]M+I'},-ش(N4"C =9KUem\^߬W_[C@hPy\|5بGaţXO~ݽSwvFi[J\ywl "/y}~TH}~T5/wwٔz5}a?`0/!.?(5ʚ:oW$QգI>\S+2=hN4J_ 0Xnk8bDgYä|2WK)4b2Av^>uyOc2C\3[H !ei SW 献j>JG$jy"jgoͧ=>v^&/u?mI4J|<j a9e߇ N}OovͽXq};>ӻD\$UnȻxbOO~xuݭrO0-9VWq`n2i5r$$("^:PɣWV*m@."wtM`2p_./ i=WL/Nw!GQ'YmkkK1QxR좐+FV艣nuኻRE78#9yE#FhaQN֓:Q)| 6z);?Ƹ?Ġw \i텷[,-M cTbzU;ZB ei*LZhj̔ ?(x%a͠\u"g 8B/#:zH FLD׀ YӞ,t䟡&LJfmY hZV)e}߭8>i:m t#2v.?Dws)me*Z6cG#p @",W!vR,#&Ղ#6{JWb'S2wQ-ߵYKPdu^j_w^ u^ 2 _na?">:IRk6 s)FYE"x~ryU3: iB%- . Ўyއ(WzNjNF p"qn4Rʬmg>V"*tή[hOn&G̾T| eԕr:ddS4}vMx}Ԉnq ; Uͧ:@4dJv&nboW/c`am@u n:o^H℥ on)+[ ?KjG9ͧ|R^";X>iW*3׷ŵ/(Lu7_ꎲdte{2ۅ7f8aw $eK&W=SB2ֿuKO?L1Ouꔁ|%"PAtLK={+jS>+>"WZ_O+~6xmpqq͚(} ڸq4W?aMP) m ԟ\pn~?Vȩcw# f3Z_+=O6$?g])1[YZv 83Tk)re\:jd~LUy!\^ a2na>`3iX5/`emeN +qbTy̎E8=nozhxY#F:0~+ ,w:'xH;lUѦO?yX6I}uۄ+yܱ3KWo :lKbS<<^+*3+"p 4`w=XL[ -duwf5v"Б9)o'5K!yMDO=S=2k24iݛ3q>[uMIݖ>29Sd/~xc r4À7tGs +8Ûߚ IA,:dS~U=>+{j^2kyӬ@|m]KLj8K/8~z|;pCXerwmM|Ӿo^>` xje)|8۽T6fL6J>9JY[7Z Y??gAk~{׈*P *gtHs♮φO)(V`xA>YTYUi2oR=pt\1Wpe-P4"W%x<937Y9P幐ݖ/->l=&)wu&񖆿{Η#kMi:?XE^Y2TΛcCCLaM=N ^h)KZD"MT+L ~LZ-N_n;s 99M ʟ<#Peޘx^ڝh6:__7AG1?|]Qk<1ǏMh/>cCu(H&Sub+ 2͂)q]`ƆeA9]u)gBB3Vye<kӲvxRv,9)}vֶp}dJ8|+z#"ߦ72"4Nw:);jVȓ㵿]l os*_f?3r@23|lT 6~h6KͭٸiMM6yEzp5#_H ~ )fc>B,+Q;k[I}a/\zp[t +h^͹x L+hPz+!v~UU;ZDp.cfMI>Aey@>\Q~XIFNz_s}f^<&)JPUa::E^@K*c^#t_λ;I>} lɱ][gQz=IӏP,?m[~5f!Ekl ֭雈 汑iC"޵Ȑ`VA:h˜9V~|gcH ,>ZƘI;9E[AtszzpWn\SQH l%o4DΆV*?YdjϾ~{%Flp-Ǝ u^q9JfU؋d(E3-ױ'BUUIDVP>6EVz.kS]򿗶6\݋INt^G!Y?A[u T%Qt*=\Xg2iZ>}/#4j}<Ջ< l;Î+b|h$z!`t߱@"loҙ.~t1{Wژha~`'R\l5]~y*m݁^ޭpbuӼT*yErGw$*EWz^f:«ü>xKE{!PAdkI8GE CbeCClp鉝JerҕGpzd (zG'f<<;uTըz2] rR =ͯ/+fP>=(AղfI~Ƃݑ)2 \@ez}pjL-uip6r/]=W} |WL>0wQ85ie`1A R`clQ0_X׬Ѯ_B,fA-(Y'-RQjW[.6 1%{Q_PJY咤=X8?GqPiԉ`&ޜ= E݉:5v< @I%"яk&  R[|F6et~X.5 $V7V%1MŶݕ+ 5e#a7iK^TTwc:>ṷ^։so၁f[Y8yy9ڊQ{3`I.x=[Rc֪7~E~Y(A[Y:7P4w;f-ypY k"X gp k=p:(K WR:1ŭ:QEht~ 7pf>xP:smnuYlp1 Φd/UF̟StIw)c܎G񗑼l(ɡEn-y\Fl^?)VZ]V8^d[ bZ:Y!jx5 p!0Y!Ύs3!Ζu7=nT̟;4sc~-ʴdk6 HApQ~K8o3xfG8S{L9ycAlSLm0#]o$odzl{[ϡv$Qk y,u OSޓ]6]HWDYxQIvݚ{8DO©Ȅ\_M* ]t9lP8Y,It9;SGհxZ!*tfn'NRB`s̀X{ӺL]lW5v07; Ş*OnhﱕRWppJS q7hR:t^0x̾a pw7o~@>Վ4SCC*ڀ4"zs`S9HhGQ WneH,a`bRf T"aNlU jʃzX9jKQP5ʃbD,F^.}ՁwBCk gcrNڙR"U@\Gd$Uy"Hj,U023^ܺA=#)8F7)y3S{cYG{:Zi+(i8v4/ܟxϐ^âٟ0tw)N<-BTg <uu_V{w ?ioYXFZ5hwdHs2.&qRHs{+-uy %ʤ$xXVI}i65{Uʚr]n6&K멐RoY'59sB%!<(,7^Qǖkr;gRBT >Z~,/oP 6| 4 r_qu$+,I&2X@O*ՂSa,v5y؛.̟ji'tEɿ R @9gM"/(f FIj lo<͢v[suqc;4wHG0Y(OzoplZ@%^"LٶӦi`ed0uP4d0x;QTkߴAx:ٗLVqƣW~TWͩKGO2^Q{pdgyiL{fcib[J61;[Ax/s#7j-@UayT[\+?n"r,r>~&-KhE[F*jt6XPg#e}XXe͜$ƶ^`n2|9O;ݶ,r>^Pc3Almjo+[Znߓ*U9[XfSbSf[$%-A'6yTd.^b&<,4xÕ-w7wu8u[и[s~svM[>GHL.:ePxz*W_Y?<4PxsπzD1M{ذ IyVNe`pk#:ކƢg.!)]WXu!chI ,pʾf\ov`Qzfˋ$Zb*~fQ,41f?Mzeq,rz=N\iWO&Ek{:DTA9$ bDDB {ySe}`~qu-hL7k+w"~]N;$͹PlᩱS^}LNњWeVw71'M!=9_E]mZz`N+[׵ivG3,t,9m  $t j??bG-eߜt?֓uB\%ѿVƯ:$6#&7w^N|Z-Uzﵬ$aZIV%.ɱ!}Igl9Ԭy #oS&3ڢbFpYA9Q5cgћ4?Luɯ!}Q}wq5$rK@m rF,#Jo^ɔTw1 %Ռv?m93EM&0/-֡(!F='[vx(asWh(/) nCl^,`niyAt7waES=}qL7' Q=#A|uR3)mZeT!g{cIn k_[&҆&%@MjvH!pL/lߟ֗s:޴׭>P:ϼY.yqgE&K%5 ʏb.CI&Iڬuk<@JU1c_q/ >u/76@ 2J*|}i+iz&8|RBZ/yQxhz'զ.]f nL_LNRCIo$xoKDh b,ܩ]Kͮ+9 c4u6,WUG?A7%Zp[h#[b}6H`ws?Mٍ5?Y} gEcg 3-'k9*}\z & d&.JG Vmzl좪T온zb0 9o?x '?tsTVHIR? &W U!aX(1gFoPz \@QJo?FQ3ELY;P>H,+Q`g{bh;KoP`i_ۘX\twڊo3ؠrn0\8:&T_MhÅo7qEdl}Yp$լCdӫVN %@+8 )t}ǷYXujt V FSX+<]p`۸EPdVXJqFۓPJ~4{sUe7+ʹ.Yer 9>Ojr!͚N̟'#gɺӶ? ~hȌwWMk[͑4TQNHz>fHڭxIz\{^ 8{߽ƓtOQ˃j\?/]Cf>%i?cɞtW=ךvz<[+᠘u8*gdvs-x:JXn5Lq/ϟ#*muuXc+sBĺVF_{ tN4~g v9׸92=z>oۑe@PuN t\~OM kRSٌ 5ld gZ0_YC^bsvh/Cn Zc՞?.lRJ6ko~w:BꥂgX  [G'|OlL7_@{.B}ytʼEIYZ,O҂1U_ӆŨ0A@ZUio$G{+cdݒbhP=0.p=Mފ_|1!Cs$dJx(Re,;FiEh8ݽ݈›tY5`&?O0ÊC*+P V !=2I-a#tBX}weg!/^.LfGK&4Ҡӡ߫'li{G$閭_29VMc(XoKL8F#y(IoGދki( eyUNtE?W{TwlsǪC A kx`ZYm,VmT&flmٶWBN}-1!z-܃D)8,ru-,\GgSe5|AN|ÂY烘3\Mm(;YIINm~J'bW]fw.I8[N}]6uS&c"?j5]w{h]#D럭ߩ[G0:Gt^ Jg,i =oB%h<Ҏ4Xi5\?N*FaE"k ?Mz i^#)oc LSsY'FӡSW)e'd2G߮}aHQxXZ0#{"TÐg&nO+!qkTm6묢+P^b̓>W0u41&s%\Ia *73/J_9|#7F`76J8ϥSTB;Jo2bN^}9yR,KUh̚,B!Z*1<ͯ6XD~oԕ3vQ!ҝw+$[cc,Q_sgDBU0ճqƂvWЧoT<9&\.t*w L7NDcd^Jݺ~3cK;EBtI 2:Ys[zRj9V69Zɧ/܏3j?tLsfK L|Wk,߯PGO/8:; hA$l8|>`MY`j]JI͊#9vI;}:㱎ҨT*_f? ,+"@8dn*+kȱbJ蔮>vȧ/"}Y@U[Pf ^4pW"k1Z(eq.8=JR鞿B^12C].5]'AeǘRFH8OziM1l~Y37 )i6ͩB%I@l9M︁as ;|~ `4ޏ5Dud߄@G6[Qq:u鈜.t7R&^>-_ ?]mokҕa1YsM'lݮֈhTҗ"^&[~ڏݮ.VwYIKrRZiC2<-N[ gON%-vyK!ɏ*,7:vˑV"՝E!Y,'V"O Ty/ϥ 8>’E}}?^*2O}#{Ss\ 9_:< ́zL3=W%}#k+&-: wwO?${|M| Ќ-kFL>EEŕϢ^Fǀ!{1%JG;MȾƟf*+c#_N+MC\Cr%l`07V%|kW^eh'N7)TEj׎7jbnqԛneoyX_76 cnvF;<G)b:.3}v5Vkk5OA@ tozΕ"Fx+TQy>dYέO7k4/Py+R<|%rejwUO!:(cfN`>r=Nl-~$9Y|K$ hX{lW:;K%h}g2c;46Ot橨[|W<` Ns}W#!s\ܞZtNrMþ/#?Owzl8ꥬF./a|w"mI&o;G+XGߏn斡+~;$aȡþ|+rQ~X9~g}XebO8v@;ڊST`A7霹s}Vd+Ū9xjNG~ϒejkM%Ǯ$KW”y<1jQWyY:2eingO0Y-i &Vϼl!˥q@){|%8c+̤:/aQg$K{n=b]UZ};?¸ A |0  N< NndB6sJqrGz zi?_7JSZߌqy^Dmw.t8"Z{f+}ST_?W-]Jv|}jlƺ*$V\=*}jP\X=lRfJ.[R`uUz4.Pw$H*<_"78ψ~R|MV_NnI˰X0M$?R@%1&b'P&Y!YE*kyw,9 _:ZKÎ5P[~XOd2lsXwASc-|`. $7wO %g='蛉g<1"y5$MRlFF~c|r%q.3֝+ZH7]k|G>kXG; Ǫ.|a3G8Y6I'ͦ Opvdhh))q ݻ☲k`)gDt1=<0Ⲣ: 07bu!`yGHњ' D~poW%y8lķ|Hc;Ԫab:L<cvi}MSJԅXS |'^1vgK)ͣixhRܿ}(;AԵX*yZi۳z2uaLvľ× 1bPRcQ&ldjET\ӹgJ(diRu1;C WscHU0=R2}Y㔊Igp1 cqWAElk)_Q6.lNW-]魗S7 Usޡ}7Z/cK}pG-)ؽK=i^:ÈP?؎p@5+d閯m+{k+՚FoDn|\7Bd9/F %Wz&A9}]7kh~kc3 /j.եiLgױQ*$徏t٦9/|KFKKL^(zh>b)M"]-g54?`ؚVM"u:NoǰOO\|_WD䮬 .YJbw=.c?I㈣/_aaP )Q=ٶ  &r98Q%d|#ɷEgeyɑ#nsIS;VKU̔v HTw%c {F)+kr"(x82,Gǵh"̝ H>zJh,a9O7,>oVho1HaO0qӭ'U%LZ:Of^}_k]nVzjK˾]Yd cGηuf= |uɣ/ho0XqX;q\rt4rmpVnbסu2co|W~Tؔ d bq=yga,< & U5+Ac%@ط 2>ٝe9+ՋT=:$򜑵eL eJ1~”Oq.=kCׂs4lD"32S~hsHvk?KQ\ <t P hXZrVޝt4{N׾.gU4e@5:^" ^YIAGǽz`xL>oS %TmۈL5~:kMfٵqSaYtyO(Ew0A1#&*y_U`r3I74UKd;v1:J&Cb /9X݀U&_s21R< ?(jmbLq둫1\W xbt;eS0(G~|Ak/3ibJ ck䀇~&I@er81=6&c~nj.:RӸkM:6u``Q &G0X&ss֝oikn%lW1zΚB"%16[t]b5|]/\KAStb㤨1h_hvY0@Z`̶`w\Pz{)r4dxGd'vG SBzhvx468k Q<&_b) Hyy!,ɘ%jT\m:#2b'M YBڵ,%9%`0#̀J+*|FFo;Tdbg9σm8;#XU$~'^8B3x?2WT^fOZF[j8C$T^dwQnM}@[!F[LǬ58G8^(9b3]]$;]-n0xއ>m lL|bLJ o7 jF}OV e@u1#CQy/# Jsxd?]Ox#_ՍoB -UUw1n60C[^ݗ+AjQQ:ntuSI;<./ćI궝CwnG0o2dOgA"s򻴄AU"[R,A bA[ _6eI _Fߕկ!)&f>=%U&:9]>O10*3tNq{^=tԛ+;d 8vU]^o= -_ks)EJ1Mek k}|e2=RXwu&=" Oj[FY*A4mMjn 5E)ESA2ɬQId ]bTgVR/h&[llc9w|dnw;-cA#CuٙJ(P!h`8OxS%w Cn#`Q7mصq5l[:, f7 cWx|] l{"n@[Ϳ r `\gp0u4r%ś3ڗ<mxZOup*!P"˞^s`*sW(|Xy['.:d p2BK?&' sD[&^Ĭ-}opSc,޲\ɁfwE?V78&b~wT ?V aRxulR5m}nSj~ZN;~(NRr dE~T.DCz TfMPߔXd6GH,T[xVV*IĤo`b{Ʉy\^zߙi$< q4WWO/.}?UPafw;nIYrAg9UQUyYxL+ y*llO|Y$@چLZaQ|R~HUP䜃_dO,e65׆شc`JHXcy#CGbW[65#D喂F%`+ S{+,bQ1[vR:(O'%_*bĤ7돿$vbz4s%UL S *HeAF]3hVBl]8sCJ"cDX=AG6-ZˠѳaWZbA%,K2kwWe(.7kKkGڝKYş`uԜf߯h:D~ f0T}t`x p (BOƧ_q-ETYv}Pp=ب.K06 [y"w w7q Ӱ0КG hCb^T&-/bU@57RhwW;C}rdyoSV_Ka_s3RsR|5f 9E^,=a'ڢixщ'OG?A[?6I"ʸϙ+gYD nTķf:{)'E+H;PQ*"^rh&[%G$?)s+8 W|dJ.*lfbx:ce]@ۈnT-er;`'q/,ΐvaMG%y(rUk?z"^9/(o~{ *@J:%QXD7PuM_wR M$ ]`d~G?!ٝ]`kڈCˡWy38O = )5{e+ tގrjR+!l~ GRCTS)Hu(+-9?k4Qba4U_! FmM5ྏU"Lw5HwYh5 ynJ'BHZvks:5b_M14HZ+u)ϫ>8ylݢ=ރKf0̐4t7~3m03FrE>ݨ]T[d:l~*._03M&ی|PsC%1o;Gj"zkZ.yI'ݛ}~3cxɕy E2Bw@bYYƢuLwRQsju !:elg/豕d1m NwX1xwQP=ё8 Zq|c,0<-Vr$}6h@.yfH>0\ ==>^4LG(}.éc9R MZqtkT[BS~U3-֐\,:4;b9Ճ/՘mCbzJİ]O`aHF94 z䏤$jyn379yh~v0nS(n2>~~iŊ';OxB'[C@VSRIxuƫtR](j!*yBZ՘Mu2#QGMv>R'tXoZю\v V,8%:`:3K:`_TR^e?jAVNܪJcppU;\tӸdtҫ~-|_%c6;\F7Odm(o;̂?w(S_Qu{#dtoPOwh)F)( ~ tYSi?["Ѷ[T eVQhqjUZ{H,^wha5sgr!Qt?.&yaCfjnΤa`!ɜL#+NF}O?IiD8щ#5D~Jc_soa 0B٠/ߔapYMdT`5 *^3k4s/fO%PdiD+O OAkC`h-15Z%8UoSwմOgjVc_ce{AYYc7gX05/`@}SZ8$?vP_d?v P^)s[)1Ӑkh`]}*mo|mS51HWm?h  ǚ xkq*qWȣ`;Xj[2"WY@`'WY"u셾PrWpEOZF'_qL~*+wg%IH"[dr4{S"_l4^eͭ)a?Hc\ZďR,wNqcFk$F%;;XMR9D >s},t \3 >09RUK[=%a()'yT%̶j)O hXi@nNz"ت S< `Y3* Ϲkh@%NEDAt~/)>.慦Z $·8Vr3]Ģ;loss7)YV-e!ʹ[|zPW ^k kosH_}NH'AAioT%$ra=\aZY8]x:+%'l>* 0-2{<ؚas{7(sׅhШ`b >,iX2}M+ ߖ`E@x`0xxGծٶcҿ\\BVY0ILB'~xuzaEmtшSM& 9g.U|k|fTMU*=w1.R߂7F-K]gFqw_L=" K!c{z4f-B7;ug\e_Evu21\Y )R<_*OeM Jwn 46J[LW#XgQ~߻MPxh;j+/H:3^Nŷ1O!0cN[L841)h#}$-pgoU.EgOވO`mkY̍H1un]Ə mRˊy~f߻N]Sɯ于7"T6♹U٨)^kdykyƟ<֖M7Ug1L!@\,~ߢ`S46|T{V@6#pos,i[}4'-XDfټyYW6k,&/q||>ªKŶPwPV>xÍMF.-wheV ad=HyKi쉇ҁ ;p 5QZܢ jĺcT8 2-;ޔ:\ff$R6P|f{#?%k,:V}EǔWg %gt1%bLc&YS_/Ɯ3VD3_qzIRa5ǃJX ZlM $4v SY02B}6e!#i\_}8HNd<~:ڦ5b,hIPu#XoUɦp ԩ#[#nj =gFp֫t=p{)DJ,n5ǁxªE@zVF3Iϒkn#9:€ y]q!M2T4 +W2*^ A3E@"DSM:) KQ5&'B?+/@=ڮwQe/MԺ=$?2o)*:LEfjsd.@C~+S4NBŗZe?XK {ƙ}sC43_RGd~kq`cpUX\BYPC8 &pqX^}6#dIMOG oϨHQ,&~T- a$Тo~^ꁯv)KwD9kߤjbz}Aw3>JYB .>_ ?a+(bZ:DP4|ƤHXD(NfktO^Mݪ PZPܽpOqe"#0H1%+  A2dƉj-c!45cvs1ܿa?`3t5%ͻϒEϾt ZǙA}d6ɾ:]K7H588Yo85!i6Hr A5``Ɖ/|^xE|@sZqX3FjaC?f7 L7g9[z^~p+]X^ Ořa}^\_>V6-K?s,YݲQ|X4څoO*.اh,][=fJ)R^]G2䓹kO#uW+_-5gԭ&s]hcREbL[Hp5-k= Vde#+a&3%'dtpQ@l)mzWb -o[)TOeYz%]ad֌DeQ]ޗ!,7{3CYQKW֠;}ٜi٭->VCq`\{qxT]%&RgIu 9os 7Ѿ*gMz)Y.oaˣVM"<Ӈ_YS~ \- QNiN$2#1W9H>s[GhrDhL`[ٞ5]h]K!7/ B [ ɲ3_kc}TCzxa2IlKe9To3D9cLr[wrē.}qlwj%)^YJ\WcBUYGcH;0\Q @5Yz}K-<@a2f\tnSnH ljyN˥h1}C02_ry4)Vz[~kF[+4EXT\"Xb* xr# cfuMGX](Bf*Дg1&;BNx"#/33ɥg w __9z7/!MeHWy^lXd#F?oO̖2C~ӟ < -'+)? zM!,T< =J)O.BRRHU3$ xҠ'(CqGuܦV{zQ&67v oQNϪA"qR~#r5ԎE ]X~KGT 5qHFqbi\DEG魡7D27Ą>("ݖםH @[)ޥBv_tnE?A|!# g%(°\ !1 FO*q#Fjջ677N!(&vm޾._|0\Q(FՔQ~VmÆv$g+QlTl %[/ʨ=˭8țP\Z9^cX[T{0\;+b7<B:$'Cގ7IG-E\7_IB` .96Wa.Zo2G" ΟOkIP5s͐?32Ux4qr'|ٵ-#WY6x_OBX27Rv rr\TX6eLׂӛ˞:ЦKWI,^*r*500$ӚA|wP^Q~5ok^mda,):0mGD|I44v5~ jۻ:["۹>gX8W#u e# YRg9 Yk{Bd]Aͨ.w=lyQ/ok]G pc&JE 3 ԀI!ǜ+ɖ;dHI/EEt8*ɅOÐ޳Ԗ&qz׿> k.֓ g2%h#+Y`,uxNBR룡Kjgv(O\5!&F(K.>gyb>n4Vm)s=ijtͫ.ǽ~)1F0 ?)kٵ䬶mG'o< &t$'rɑck*rFG%?FU1 (-Rj瞪FAgQ0Y`iLWAķephK,TޠM]N͉)܃ ASNvHcbSMV9CT5b2>Kb^Fc0(rvѱC-dvhN =#@?3?@܁P# ~ Ae8FClN6[w;?'艆pnPUVSizso?ogشQQC,encj,?'WW|Gwxnw?r_,yÝ*r")0@=pkh>P腠o-ը(ɦJC$%gY!)̉D?qF>u8pKZrTg? %DZm>whɐO6:[`@Et^kfn9bI}1 BYݐ``'I!D !s;+H*o)ݍ iTW#5 [U='gU7pƵi _ ;w<|NqBK찭|a{B)`MX ͸枇E D |fUi.ҷMZҕ_VF3dvo_ HٜõevI͓vqOdvC4|4 0Y Jn~t:D'M+-wPyM(;; }@FnyٟPU뭈p?})(2qGэH_%aѰ&3ޚ } HʳIҩ:/s~`eȶO]Fx< lIGos%œwE'M 8B1jd$+ԛRGD PL +њ2&\=EԷ_Q;{[آ md'I6v PŵgcVߦen92 9eg5N#s( )Jr=|Dkƶa}-{6H!&QaM5'홇zQ oW y7+Z:- %Jv5Lz"A򖧤i|,,lh06ӵ׃ń^ߖS˶Z< g*FSJ0%HX6ϵx%ѯ`h4Tm#¤6&8 ؕp)A#⽧R[2 ͇xJwkBX#՝LZ'95 '`" P j\.}e\ks3 n%,p 5L\{ʇuGw_jBS)-08Gb.) džr֟M.b"g)%Ql_ݺ# x22d=ib#Pv= oi?2sXeD":ՔDi;8>p,ձ"dm Rc¤m>sƌ™JE#f!`3dH`8vm>?Q;JgEP2jVIF=81!L|o 8X/S2 3ilkA=16VܧU`v=4L]ϲlz/\W5!~ ,c@iHÐB~rd>}Ayk, 7Lp=vJ'X)WpY>kWM#jDz \AdXnAQL/ ơsC_niZ藍G>Ve] VXG1Q*r5#p8䰜g3۴g!#^u&1<ߛR7z3s쎸F7bP]=QF0!r )}D /f><2Iv@(_XߙN9\Lc@_HÙ[GP\z f-؆~c-k2 8dm ;a&x?$3=SrFu9Q Kj9AMÅD& m!>L764q餜S.၊AÊ7೅#y~ޢ!(r(k+jj(+셅eΰV;[Q]H%D^n7U TqlϤ~;)X;ZмJ3)u*H\;I|_AX><:#A",k_qO#[aB +9/\*$9?ĸut+u;w1]D&OPTU;Uٜ pGu3f(`i7n{,5ԕwe"@@c4(, ۽s_o(1zL c{ ;@5Ѓ I*2 RDs!9%œmy/Ylڞq(]/Jy1_-_LwHy=腾,Q=hSH}U E l 3lF*S&-11t?#ѾB،FwHdXr\'uN7{CE0xWx JZ`L|`i ߮f"]WOIJ=w&'`:Zy}0[(~zAxdZ{վU%+%%ìMe#.u27#L o.jGi䉮}ⓖʃ6έ,jE3YZsrt} }a8ʎfӍ< gUe(v1٤R|+C%^jt`3 ĩaZ>3 2B⽈J03;BFO@f$p4#)RT?]P`S7"iYSm#" {?Sw 1"nE7B-Fk, LMO3G@OxA}(Rb$$B_䊪#9tc_ >!}+QB86:_H:& ?Zz&{0NR}M1~o Be〣HyuFo3x Vs0KKsE{dw+-d".py+Fһ`g27_㒣Rf< E@b'2*+҄?0!GcwH 'Os؞"Apj4-F}!kdY둃ᛁ)JިDm?(7к%Ɠ Ef©AAsIJS>q9o cFC$'oIY1LL׽?VAM8-^|>i٧Qkw#mapۤ3 ?10=4P &ʜQbn>A+&n`A~Qؾ'y$XfHy*;}PO1q%eG q?à$~vnŧjR,QL_wIn ``^ y2e'HCX6K?҇mȁĉ W/4lE O1\L(ySru;fLc~]JxlWoߛIJKC(eٷ )MJq|D, F e/1 ѓv{L'VW3A1pkx51D3tߩ tChPaBraMjuNCD={gF12ϡ`o]'2jwl+ w]',9^cуNB.5NǶ.)n0z ߴc֥GwՇ8 ;/f `'" ;OH3zI$t'/j*AoPL߲{`Qg Etn؉i?peԚ,|Ils#N"|g8ȩe`-f1ږoSNӜH5gs*ԸbC֐Ջ)Qv. UqA{.\!ͯJ?7f0)Nksua=c0ΙF;P`:Z*)QKv9ԑlѧn>)#idʙG^?c >)=HX3fmkOo>#R*V} Wp!G@6̨ >, _ n?la?<]Br[-AƁe:}[ FRܘk<ƷS{x}-^.@k-,*c+ _ |\I)?{M|N RBf؇&nj 581=KBOSO|[@0Nm~#7*$9dohcC}:>JK61'qDLH+6vVl*YyP!|;IDFn&5suk0*0M}M{z2 'x8kDz )ImHϕ1`1^NM"25X$NRI|1R%N -׀*MAfkdEuxBǬҁR3Ã^MI.d^@rh`7N]Fx[H$I| q)2_(Y<.yi̒G}셓ˮ80X%WI0f^P'H'~-Mlb@xoǝJOy@Y?V$4 QAC7-`e!cG^HɴZ[||s<އRO˽1@ lǭܳ*UH"Q,5=餁F_:#IMN1e/Iڬ-M4-\P[2 KU8#BI(K@sd'^%r`6/G56W+RzNT3PV[c}\:mw# оҤ j8S8,-{d@gn $cFMf!{&7μ[Wuұƒ#7 2玅Ԩ7e(칸X/q,|"ߊTVE9 - ptu|ɋ/k, h^ 1x;YpQ%KjM' d7 ƍ]pť!"Ds"xoT9Cc Hؘ("^Z#rEoAo% b0[m+jzc 8wU-uJ%x%3I?jR~[.E`݄ma#I+K$CR6pLyCD[npjǾzao$[O(dY^ehޔ7pj'Cl|]cӾwoX4y\9O%l ?[{VFjŔiPCVV[^j^r:)[rWܜF,D[Ϧ84kP{Z1zGDGvқmC0:q+TkEo%Ҽ>5 ]QCECJ$H rb 1(|? HmRRa3GT9=wJ4kT7V(K}ؐR\XRXN0ߏl43(ChB󮿙n,=rF/p@qA ]@EWP_(g&TՐh#ᵷttCTQd▁ʤ3EI<uA+CdCS,SgCgDH1wK,Fb 'svHA[{|oW6աked7׿{W)mW޹t#sQ8+- |13z5GRasc"px(^1#g{pwU*5b>Kk# 6e;B m{ C y#w!vcJRoHXXU=UBSf>_ibx,ɖ'e.Ic k*F1 ;_dЬ? <'q qj(Ҭ.~8$Om=4&5x'EF3!$p@.If:Z1_A[O@r!.QƝ@.bB%K> 6٫3Kp )jHҥCHމPnW]J6p25u%)Vj쏛WxR?6Ľm&!SGF~a6=yL#AL!*@ב e,aLKCAOEκƾd}>Z0ye?*ԧ'#TY[Al8t8rjXj3 ^Uk!AHȻ7'f-nQB ֔8^܏OXR<4f?q}LD!H.T`\S՟@X[oja+$m Fbݏ@8$C$_i8#ZpßE&#K_8H̑ ++4x_ԇT2ԫyɒq4Zw3|m>=F4 ;(E5mGQbIpuN/t5TNVP'I!]QSBC(]di8q)Twښ#Eri[lO*dcô"hM\h)syCbe}TQVУ=v w[ʓl16S4јPQOziRN&"ᛅj*ls77mvL޾8W8_ Oڀ#\weQpm|4id[l[j$7'/(1$ lz_ҾX}cN =t0pbOe;:llW6t@:*w(zܢnIRZC|B`g}=@ Hf,Ək Mr7.w*AEf1eHčȨ%ħ<3g7Dx֩5"a""-*M*ȅAFq{[W,2HϮztD.oW]5%v9PQqvnf`j$qdBT2jd|5!^R#q.^CLC3%]9G=Y"shGأB\DQa.Jʣ} )MھT  R'"B#EeseI=.z ]UB9_va<繕+dl;n^3_hTKyw*1Rl竆D%>=m;{{֗lQox{>S` ^pY8p< XOD-`DH2*i`c%XgI*CBJc.jݾ:*QI_sP^qjwi?RuGO̼OO{:85^rmf/:౨3ѶGFH!?f?=HF,ª I:)W 6̋H/j`6O;Ӗ%\z[Eg"j ̍MSSsK5sAm.Jt|.ծ(}z,V~3_aVgfs{e,Fh ._SK?f>i!Gqb8z}fkDĆm%R ;H%f! g~ɲsXA|G]mTLr.pl qCyk?>I 3R?P&+$ ^_ŊNi鷗O]E[GwZxwGɴ_u{pF\xYGw!9׿^1(*W[9ַDZ),ׄh;ob{]0 |)hߠ{7crO(Wo zF؉4 %KO8A0F#I&6Bbٖ7C8Ymӛ1'#4`=nckw۩Թ[gTL2%s >n2BlfN8Q|o'Ri1oi;O5ߛmڤsKeZȘ6uyFg8&-cyփ<O?AֺiFn1Y)~@o!=gZEZU  BEU~~4s%;|m̃8i5ҩ|sE/aT@-NO/=p 4\w=Y=veC}?#B kENj E`+M>ׁ\|j6,~ 5;D?kZ zp"VBZ.oԛOO 9.R޺B+l@8*% œ]mֺcf$1IqnM(nn:M2/\@!(GW$) ; N_ѣV1h#-aJe]K `}QCa}x3ĵB:zk~}zJ~HcgbVD=be,ei\9),1پ. Tau)}y~c Gncf~8zEZbFf`mh{rM]=QPA8@7,8=&"mҍAٯ,9#}[GaiCJo폜U(G̪=}dby,D)+'\Y R7' \}#} @9?XZ\ a.Eh`x⎈_#FyD\_E8<2S(~fidd4) .({CH81o%3ٲes׬oӱժGfQr}hWSalDJfX 0Jk1HQL̂V^; Mm*}R{Jߛ&s32J30xLylt{vYˍ6͟4x5|gzګְ<ֲK+GhYfƥ˜ƽRXG..B=N\h;C0O}$h*\$\HQfnyby|g]>qSj(2Hv3]ƢXtzc;]]?sXAQRd7?Sփ1S~Hhe[ƶL`c命K F )cׯk\@e2%:9?s*^k$l4-aKN<*?I$ﮨWnU$7<(֮82q]FX  7 <$7`8q1Y1WfMqvnNo!f53}тeXɫ`7+h"n* &҂$c7~px+_oz]j@kY h#.;數7[! >23 Хm~Uu3뜓F%#G .+tINilFA'.{=9=/}köoq6 9hw[&Qx\K!(oh?ၦq`ruT +'Lb,hym5i_$@mXz0Uf%&O5vRqib= ĊfWARQymT/fXrnE`Ώc*u=&w9+77mvJnjpvh\:хPLM teދ$v/г>ҏD$+04p A9a w:Zږ5$vgbץ򢠊7iLDq9.Y0nw` 1r{rՖNXs]b8s~ວ NMV#$.|8!a `"D@wo ^7WN[(T({;Wͬ?T% =?UϟaR7Eۯ\@}h!=՞+Z>Q?7N`[n[cU֌LUb{}G-zz|l=5G3)I c<ɦm%4lrxZ(<~ecW2p FNi Xch~/S=f D{ \!%> B_Ou|WڣOy:X^J K䋙 pRo\vGcdPu3Zߓރ4(ac?Q# t7s@CZ)-񎌊W*fca H`W[ڈ+"ҽ?O8_SǑh$P&Y 9!t3P% :08lkA12O=` L:O6]qt 2\~UOS=^ ;'9 K?@PͧVovWxIov?8Ynw߆U;DAZTx0Mv?ZJ/_]&YgT\Q+ [@ #OYwH4qmnhI^qg9Vv~&6q:Mþ^Zn `?}o+tq˒qz@A ?ב7ǎ*f&&^ۆ;~Q*9^hsͪW"{uCn [븠]<::|ԕJ-J>==壾".5 #Ol}ۡFQ3{a$*j|WbZXW/uMi8UJXPś㴪 8M 'X>kkPyys7ioJ}ɬ6|p0 S۔[U{ڝt4F2ѩ{yz+X^n-$&Pm Be{Js4x @ L\x/!~,)U&3즭[״ī2NL ZK{T}VUD-OtnS0$*SVvn_O%B,Hԅ9+$4=&001`;[OL0}ƒtFE]X>8>ƕF?]qjic=,q58S|Fo2P{qbx^fts_L;Bf0ڛ٧ut/{D[Meƭa˺SՖ3eU*_Sx|.Oͩ}od3 O%|R}q]!?ChULn$*CZ`)WD;kyOP05_5A „ղZRBĻUU*$ e|7' ̺+Uwt+3,;N(-bOGf|[Eǣn.5nɎ)h.XyIRsHDiqu> U;~מAn\[=tjB׭ N/2<9tb6L44zi ;CaZ=^Aݸh-wԶX}'_TSXP:*Ş? RGVf&RD`ͰL|0*M:0YDzt m?YXƏtWZ^%A>ՎLUV2[iO+q]+NX4 $L< V;|^~+QuhQmH< zWXf11e TC?:t,?Z&r7}EY;ԒNSo,/WE%ήF\"$; m6f#AsP9Oe77۪k$p5Ws/Rss6Gg^weh5D-2͎%Wrձu_OC, =?S0+ͷE#_~Ym+3BC1?NVw{]<3Dݷ?ex8<4sܬ PRlk!ʖ̀兵jK[a{[xyg/JGIvxRqtMjPL z{O%W7Ii8ul$^Q{F߾M8{m2%T3U0ejeiSS S6GkWٰt(k&GgC&b({n܄/Ǵ $gi {MWCS4۔䗺^2p|eY{G*b@4~o}Z]5f [ڜl'~ â|rS7Yb~7]Jg_7 U⡜J,:c;7GDwB_ťSxǮyrgyk8 w j wHճҘFIj$X\rŕmR{`br;,?Cr7f49eAG)ވRmsȃ^9Р<mCⷀe2]/N-ڭ%nf /L;_ P3۩1cmv8x0W6}kH 7n&$"&KQbyBG9sZLȗ>):7㽣#Jx_ ݦ4SsPK%siy#>0_E7qZFkEXDoe3^h Bfr˓Y8p,,vݾn}*9\ATd2x ibk6q/C4`TL_No>y@CkRM^+"Bm0I&a(dH.P|C}ƒg :w~Rݳ5C3xxy3%a*.\_I5 CuD/W-ic3)9n1ЯH,t^v:^<(17PXճ(xJQblwÎ %D;'I%1~A}p^H%16Oƥ۷~ť)5\Z<.m p~Lx=}ܵn6UC,ZC=hѧ;<8ۦP6Ք1؀"D(a3v.Z U['ai,t{̖i{oqBja{.rch}#^_ cRdz@My ;$&Hqk>8Uj2 .IaTA8I #T܁m/$x- ː :qn&(w$y!|7k˻p': {IvD T6U3iGӖzey>:`y~ǴWćp{eo?QMq$@`[&% AԔyeӛ\R6r Raɇ<;# ASlײַR3#U/+֤;_LX[Z#ܘ2l0afqiyπ!x)q堘vqJnGG.E'BTI:F[KӖʚ(+ ~/5AuGկ3˘yjШ>%6X*+}y * aH֥Ip `5,@=[%xl y\.c߱^?BCmhYO}rÛ=gKY|iuk| Aݛ{lN.T U橃-)AzF%y $j١R!ba'1ӵ o$)і7y`?u:NZr/9'wdA֨%x G$"X"\3h.p`EYO̮4Z}~ʿf{z6UyDDdbV# H[$%%)!V~!lAQ8jY\3ix`{S19+gy-˳&f:sl~>negE7k=m^fH7QC>GKɩmzgN:BQ.IbxA-֟s 9n6RƎ78ēEgnLk8x4D{!{ =|-o&f [(u;%emgTRر$`4lyxP Q>akVKv0Q쫡{+ uwݗ&rҔWSi2r{TFY1WNWa ~[3c :xDα5gK0k۷~W9jUX5Ĩ,s.n ŰP갑Uk0'^"5| P?je(dW}l9(AqCjvol :R"TجUYN,Y~qz@\,Җw`T`vzȂyY'/0di%Pshwu羟|`g /|6w:;*tJ$+KdsFCuP60ը?L+e+& s%: AqPç5GK wWI`_q`+U3ZxRL3m0}঴lF6eKEqM\/Wփ(C_/^pnMX>z_BV"~rMY GeqMfӴXMRY,gF}froiyvMfPojJkn{W#ajqغ²o/O 6%xmnZ/vp4Ҵr (k8'bʬ lR|3"6bJzH'^@MlKm/F<0q auH'Bp^/qE9~[Xz orW+9i{C=zϷ5U9Rh"ߦwy !avB'I'nkXS oc}u& bP \l_A'5Ƙ]7e[UkJ,-}_oV'tRN6zKFJihl4{p4 mQe^ָ 翞ˡ?򴬝!>+*(v2Mp$_s-5M1շ2l^q Į_l 6[1W|HAŠHנsW}Ѫtq a-@FT xI){Q0L0pY k/egL`8Ӓ=_*AdVi[qDW>ZQ(%&a#vV}t~D Q.pzC)H{>T?Y ?/Z Og$H$H$H$H$UP UBH* fo//n|PY{QGs{;Nm]1 j9oyxv냖\Vl8r܂}׶+iN}sL h9̲3J'罺8V34ZH\KSntK͟cr x4rﭺN&iݻ*sc5)TeR bBv>6VN_UmvQxjJAPˁ[_lD )rE8PS#EIshazam/data/HYDROPATHY_MUTATIONS.rda0000644000176200001440000000166313402556553016312 0ustar liggesusersBZh91AY&SY#\a@/ް@^yU[ouH! 4iQ#4`&&T)2ꦟiMCi2hb4%A), and NA distances to zero. } The 1-mer substitution matrix is transformed into a distance matrix by: \enumerate{ \item Symmetrize the 1-mer substitution matrix. \item Converting the rates to distance \eqn{d=-log10(p)}. \item Dividing this distance by the mean of the distances. \item Converting all infinite, no change (e.g., A -> A), and NA distances to zero. } } \examples{ # Calculate targeting distance of HH_S5F dist <- calcTargetingDistance(HH_S5F) # Calculate targeting distance of HH_S1F dist <- calcTargetingDistance(HH_S1F) } \seealso{ See \link{TargetingModel} for this class of objects and \link{createTargetingModel} for building one. } shazam/man/DensityThreshold-class.Rd0000644000176200001440000000223413445225760017207 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DistToNearest.R \docType{class} \name{DensityThreshold-class} \alias{DensityThreshold-class} \alias{DensityThreshold} \alias{print,DensityThreshold-method} \alias{DensityThreshold-method} \alias{plot,DensityThreshold,missing-method} \title{Output of the \code{dens} method of findThreshold} \usage{ \S4method{print}{DensityThreshold}(x) \S4method{plot}{DensityThreshold,missing}(x, y, ...) } \arguments{ \item{x}{DensityThreshold object} \item{y}{ignored.} \item{...}{arguments to pass to \link{plotDensityThreshold}.} } \description{ \code{DensityThreshold} contains output from the \code{dens} method \link{findThreshold}. } \section{Slots}{ \describe{ \item{\code{x}}{input distance vector with NA or infinite values removed.} \item{\code{bandwidth}}{bandwidth value fit during density estimation.} \item{\code{xdens}}{x-axis (distance value) vector for smoothed density estimate.} \item{\code{ydens}}{y-axis (density) vector for smoothed density estimate.} \item{\code{threshold}}{distance threshold that separates two modes of the input distribution.} }} \seealso{ \link{findThreshold} } shazam/man/plotTune.Rd0000644000176200001440000001071713575260615014431 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \name{plotTune} \alias{plotTune} \title{Visualize parameter tuning for minNumMutations and minNumSeqMutations} \usage{ plotTune( tuneMtx, thresh, criterion = c("5mer", "3mer", "1mer", "3mer+1mer", "measured", "inferred"), pchs = 1, ltys = 2, cols = 1, plotLegend = TRUE, legendPos = "topright", legendHoriz = FALSE, legendCex = 1 ) } \arguments{ \item{tuneMtx}{a \code{matrix} or a \code{list} of matrices produced by either \link{minNumMutationsTune} or \link{minNumSeqMutationsTune}. In the case of a list, it is assumed that each matrix corresponds to a sample and that all matrices in the list were produced using the same set of trial values of \code{minNumMutations} or \code{minNumSeqMutations}.} \item{thresh}{a number or a vector of indicating the value or the range of values of \code{minNumMutations} or \code{minNumSeqMutations} to plot. Should correspond to the columns of \code{tuneMtx}.} \item{criterion}{one of \code{"5mer"}, \code{"3mer"}, \code{"1mer"}, or \code{"3mer+1mer"} (for \code{tuneMtx} produced by \link{minNumMutationsTune}), or either \code{"measured"} or \code{"inferred"} (for \code{tuneMtx} produced by \link{minNumSeqMutationsTune}).} \item{pchs}{point types to pass on to \link{plot}.} \item{ltys}{line types to pass on to \link{plot}.} \item{cols}{colors to pass on to \link{plot}.} \item{plotLegend}{whether to plot legend. Default is \code{TRUE}. Only applicable if \code{tuneMtx} is a named list with names of the matrices corresponding to the names of the samples.} \item{legendPos}{position of legend to pass on to \link{legend}. Can be either a numeric vector specifying x-y coordinates, or one of \code{"topright"}, \code{"center"}, etc. Default is \code{"topright"}.} \item{legendHoriz}{whether to make legend horizontal. Default is \code{FALSE}.} \item{legendCex}{numeric values by which legend should be magnified relative to 1.} } \description{ Visualize results from \link{minNumMutationsTune} and \link{minNumSeqMutationsTune} } \details{ For \code{tuneMtx} produced by \link{minNumMutationsTune}, for each sample, depending on \code{criterion}, the numbers of 5-mers for which substitution rates are directly computed (\code{"5mer"}), inferred based on inner 3-mers (\code{"3mer"}), inferred based on central 1-mers (\code{"1mer"}), or inferred based on inner 3-mers and central 1-mers (\code{"3mer+1mer"}) are plotted on the y-axis against values of \code{minNumMutations} on the x-axis. For \code{tuneMtx} produced by \link{minNumSeqMutationsTune}, for each sample, depending on \code{criterion}, the numbers of 5-mers for which mutability rates are directly measured (\code{"measured"}) or inferred (\code{"inferred"}) are plotted on the y-axis against values of \code{minNumSeqMutations} on the x-axis. Note that legends will be plotted only if \code{tuneMtx} is a supplied as a named \code{list} of matrices, ideally with names of each \code{matrix} corresponding to those of the samples based on which the matrices were produced, even if \code{plotLegend=TRUE}. } \examples{ \donttest{ # Subset example data to one isotype and sample as demos data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE == "IgA") tuneMtx = list() for (i in 1:length(unique(db$SAMPLE))) { # Get data corresponding to current sample curDb = db[db$SAMPLE==unique(db$SAMPLE)[i], ] # Count the number of mutations per 5-mer subCount = createSubstitutionMatrix(db=curDb, model="S", multipleMutation="independent", returnModel="5mer", numMutationsOnly=TRUE) # Tune over minNumMutations = 5..50 subTune = minNumMutationsTune(subCount, seq(from=5, to=50, by=5)) tuneMtx = c(tuneMtx, list(subTune)) } # Name tuneMtx after sample names names(tuneMtx) = unique(db$SAMPLE) # plot with legend for both samples for a subset of minNumMutations values plotTune(tuneMtx, thresh=c(5, 15, 25, 40), criterion="3mer", pchs=16:17, ltys=1:2, cols=2:3, plotLegend=TRUE, legendPos=c(5, 100)) # plot for only 1 sample for all the minNumMutations values (no legend) plotTune(tuneMtx[[1]], thresh=seq(from=5, to=50, by=5), criterion="3mer") } } \seealso{ See \link{minNumMutationsTune} and \link{minNumSeqMutationsTune} for generating \code{tuneMtx}. } shazam/man/createBaseline.Rd0000644000176200001440000001031013575260615015512 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Baseline.R \name{createBaseline} \alias{createBaseline} \title{Creates a Baseline object} \usage{ createBaseline( description = "", db = data.frame(), regionDefinition = createRegionDefinition(), testStatistic = "", regions = NULL, numbOfSeqs = matrix(), binomK = matrix(), binomN = matrix(), binomP = matrix(), pdfs = list(), stats = data.frame() ) } \arguments{ \item{description}{\code{character} providing general information regarding the sequences, selection analysis and/or object.} \item{db}{\code{data.frame} containing annotation information about the sequences and selection results.} \item{regionDefinition}{\link{RegionDefinition} object defining the regions and boundaries of the Ig sequences.} \item{testStatistic}{\code{character} indicating the statistical framework used to test for selection. For example, \code{"local"} or \code{"focused"} or \code{"imbalanced"}.} \item{regions}{\code{character} vector defining the regions the BASELINe analysis was carried out on. For \code{"CDR"} and \code{"FWR"} or \code{"CDR1"}, \code{"CDR2"}, \code{"CDR3"}, etc. If \code{NULL} then regions will be determined automatically from \code{regionDefinition}.} \item{numbOfSeqs}{\code{matrix} of dimensions \code{r x c} containing the number of sequences or PDFs in each region, where:\cr \code{r} = number of rows = number of groups or sequences.\cr \code{c} = number of columns = number of regions.} \item{binomK}{\code{matrix} of dimensions \code{r x c} containing the number of successes in the binomial trials in each region, where:\cr \code{r} = number of rows = number of groups or sequences.\cr \code{c} = number of columns = number of regions.} \item{binomN}{\code{matrix} of dimensions \code{r x c} containing the total number of trials in the binomial in each region, where:\cr \code{r} = number of rows = number of groups or sequences.\cr \code{c} = number of columns = number of regions.} \item{binomP}{\code{matrix} of dimensions \code{r x c} containing the probability of success in one binomial trial in each region, where:\cr \code{r} = number of rows = number of groups or sequences.\cr \code{c} = number of columns = number of regions.} \item{pdfs}{\code{list} of matrices containing PDFs with one item for each defined region (e.g. "CDR" and "FWR"). Matrices have dimensions \code{r x c} dementions, where:\cr \code{r} = number of rows = number of sequences or groups. \cr \code{c} = number of columns = length of the PDF (default 4001).} \item{stats}{\code{data.frame} of BASELINe statistics, including: mean selection strength (mean Sigma), 95\% confidence intervals, and p-values with positive signs for the presence of positive selection and/or p-values with negative signs for the presence of negative selection.} } \value{ A \code{Baseline} object. } \description{ \code{createBaseline} creates and initialize a \code{Baseline} object. } \details{ Create and initialize a \code{Baseline} object. The \code{testStatistic} indicates the statistical framework used to test for selection. For example, \itemize{ \item \code{local} = CDR_R / (CDR_R + CDR_S). \item \code{focused} = CDR_R / (CDR_R + CDR_S + FWR_S). \item \code{immbalance} = CDR_R + CDR_s / (CDR_R + CDR_S + FWR_S + FWR_R) } For \code{focused} the \code{regionDefinition} must only contain two regions. If more than two regions are defined, then the \code{local} test statistic will be used. For further information on the frame of these tests see Uduman et al. (2011). } \examples{ # Creates an empty Baseline object createBaseline() } \references{ \enumerate{ \item Hershberg U, et al. Improved methods for detecting selection by mutation analysis of Ig V region sequences. Int Immunol. 2008 20(5):683-94. \item Uduman M, et al. Detecting selection in immunoglobulin sequences. Nucleic Acids Res. 2011 39(Web Server issue):W499-504. \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based on synonymous mutations from high-throughput immunoglobulin sequencing data. Front Immunol. 2013 4(November):358. } } \seealso{ See \link{Baseline} for the return object. } shazam/man/calcObservedMutations.Rd0000644000176200001440000002527113575260615017120 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MutationProfiling.R \name{calcObservedMutations} \alias{calcObservedMutations} \title{Count the number of observed mutations in a sequence.} \usage{ calcObservedMutations( inputSeq, germlineSeq, regionDefinition = NULL, mutationDefinition = NULL, ambiguousMode = c("eitherOr", "and"), returnRaw = FALSE, frequency = FALSE ) } \arguments{ \item{inputSeq}{input sequence. IUPAC ambiguous characters for DNA are supported.} \item{germlineSeq}{germline sequence. IUPAC ambiguous characters for DNA are supported.} \item{regionDefinition}{\link{RegionDefinition} object defining the regions and boundaries of the Ig sequences. Note, only the part of sequences defined in \code{regionDefinition} are analyzed. If NULL, mutations are counted for entire sequence.} \item{mutationDefinition}{\link{MutationDefinition} object defining replacement and silent mutation criteria. If \code{NULL} then replacement and silent are determined by exact amino acid identity.} \item{ambiguousMode}{whether to consider ambiguous characters as \code{"either or"} or \code{"and"} when determining and counting the type(s) of mutations. Applicable only if \code{inputSeq} and/or \code{germlineSeq} contain(s) ambiguous characters. One of \code{c("eitherOr", "and")}. Default is \code{"eitherOr"}.} \item{returnRaw}{return the positions of point mutations and their corresponding mutation types, as opposed to counts of mutations across positions. Also returns the number of bases used as the denominator when calculating frequency. Default is \code{FALSE}.} \item{frequency}{\code{logical} indicating whether or not to calculate mutation frequencies. The denominator used is the number of bases that are not one of "N", "-", or "." in either the input or the germline sequences. If set, this overwrites \code{returnRaw}. Default is \code{FALSE}.} } \value{ For \code{returnRaw=FALSE}, an \code{array} with the numbers of replacement (R) and silent (S) mutations. For \code{returnRaw=TRUE}, a list containing \itemize{ \item \code{$pos}: A data frame whose columns (\code{position}, \code{R}, \code{S}, and \code{region}) indicate, respecitively, the nucleotide position, the number of R mutations at that position, the number of S mutations at that position, and the region in which that nucleotide is in. \item \code{$nonN}: A vector indicating the number of bases in regions defined by \code{regionDefinition} (excluding non-triplet overhang, if any) that are not one of "N", "-", or "." in either the \code{inputSeq} or \code{germlineSeq}. } For \code{frequency=TRUE}, regardless of \code{returnRaw}, an \code{array} with the frequencies of replacement (R) and silent (S) mutations. } \description{ \code{calcObservedMutations} determines all the mutations in a given input sequence compared to its germline sequence. } \details{ \strong{Each mutation is considered independently in the germline context}. For illustration, consider the case where the germline is \code{TGG} and the observed is \code{TAC}. When determining the mutation type at position 2, which sees a change from \code{G} to \code{A}, we compare the codon \code{TGG} (germline) to \code{TAG} (mutation at position 2 independent of other mutations in the germline context). Similarly, when determining the mutation type at position 3, which sees a change from \code{G} to \code{C}, we compare the codon \code{TGG} (germline) to \code{TGC} (mutation at position 3 independent of other mutations in the germline context). If specified, only the part of \code{inputSeq} defined in \code{regionDefinition} is analyzed. For example, when using the default \link{IMGT_V} definition, then mutations in positions beyond 312 will be ignored. Additionally, non-triplet overhang at the sequence end is ignored. Only replacement (R) and silent (S) mutations are included in the results. \strong{Excluded} are: \itemize{ \item Stop mutations E.g.: the case where \code{TAGTGG} is observed for the germline \code{TGGTGG}. \item Mutations occurring in codons where one or both of the observed and the germline involve(s) one or more of "N", "-", or ".". E.g.: the case where \code{TTG} is observed for the germline being any one of \code{TNG}, \code{.TG}, or \code{-TG}. Similarly, the case where any one of \code{TTN}, \code{TT.}, or \code{TT-} is observed for the germline \code{TTG}. } In other words, a result that is \code{NA} or zero indicates absence of R and S mutations, not necessarily all types of mutations, such as the excluded ones mentioned above. \code{NA} is also returned if \code{inputSeq} or \code{germlineSeq} is shorter than 3 nucleotides. } \section{Ambiguous characters}{ When there are ambiguous characters present, the user could choose how mutations involving ambiguous characters are counted through \code{ambiguousMode}. The two available modes are \code{"eitherOr"} and \code{"and"}. \itemize{ \item With \code{"eitherOr"}, ambiguous characters are each expanded but only 1 mutation is recorded. When determining the type of mutation, the priority for different types of mutations, in decreasing order, is as follows: no mutation, replacement mutation, silent mutation, and stop mutation. When counting the number of non-N, non-dash, and non-dot positions, each position is counted only once, regardless of the presence of ambiguous characters. As an example, consider the case where \code{germlineSeq} is \code{"TST"} and \code{inputSeq} is \code{"THT"}. Expanding \code{"H"} at position 2 in \code{inputSeq} into \code{"A"}, \code{"C"}, and \code{"T"}, as well as expanding \code{"S"} at position 2 in \code{germlineSeq} into \code{"C"} and \code{"G"}, one gets: \itemize{ \item \code{"TCT"} (germline) to \code{"TAT"} (observed): replacement \item \code{"TCT"} (germline) to \code{"TCT"} (observed): no mutation \item \code{"TCT"} (germline) to \code{"TTT"} (observed): replacement \item \code{"TGT"} (germline) to \code{"TAT"} (observed): replacement \item \code{"TGT"} (germline) to \code{"TCT"} (observed): replacement \item \code{"TGT"} (germline) to \code{"TTT"} (observed): replacement } Because "no mutation" takes priority over replacement mutation, the final mutation count returned for this example is \code{NA} (recall that only R and S mutations are returned). The number of non-N, non-dash, and non-dot positions is 3. \item With \code{"and"}, ambiguous characters are each expanded and mutation(s) from all expansions are recorded. When counting the number of non-N, non-dash, and non-dot positions, if a position contains ambiguous character(s) in \code{inputSeq} and/or \code{germlineSeq}, the count at that position is taken to be the total number of combinations of germline and observed codons after expansion. Using the same example from above, the final result returned for this example is that there are 5 R mutations at position 2. The number of non-N, non-dash, and non-dot positions is 8, since there are 6 combinations stemming from position 2 after expanding the germline codon (\code{"TST"}) and the observed codon (\code{"THT"}). } } \examples{ # Use an entry in the example data for input and germline sequence data(ExampleDb, package="alakazam") in_seq <- ExampleDb[["SEQUENCE_IMGT"]][100] germ_seq <- ExampleDb[["GERMLINE_IMGT_D_MASK"]][100] # Identify all mutations in the sequence ex1_raw <- calcObservedMutations(in_seq, germ_seq, returnRaw=TRUE) # Count all mutations in the sequence ex1_count <- calcObservedMutations(in_seq, germ_seq, returnRaw=FALSE) ex1_freq <- calcObservedMutations(in_seq, germ_seq, returnRaw=FALSE, frequency=TRUE) # Compare this with ex1_count table(ex1_raw$pos$region, ex1_raw$pos$R)[, "1"] table(ex1_raw$pos$region, ex1_raw$pos$S)[, "1"] # Compare this with ex1_freq table(ex1_raw$pos$region, ex1_raw$pos$R)[, "1"]/ex1_raw$nonN table(ex1_raw$pos$region, ex1_raw$pos$S)[, "1"]/ex1_raw$nonN # Identify only mutations the V segment minus CDR3 ex2_raw <- calcObservedMutations(in_seq, germ_seq, regionDefinition=IMGT_V, returnRaw=TRUE) # Count only mutations the V segment minus CDR3 ex2_count <- calcObservedMutations(in_seq, germ_seq, regionDefinition=IMGT_V, returnRaw=FALSE) ex2_freq <- calcObservedMutations(in_seq, germ_seq, regionDefinition=IMGT_V, returnRaw=FALSE, frequency=TRUE) # Compare this with ex2_count table(ex2_raw$pos$region, ex2_raw$pos$R)[, "1"] table(ex2_raw$pos$region, ex2_raw$pos$S)[, "1"] # Compare this with ex2_freq table(ex2_raw$pos$region, ex2_raw$pos$R)[, "1"]/ex2_raw$nonN table(ex2_raw$pos$region, ex2_raw$pos$S)[, "1"]/ex2_raw$nonN # Identify mutations by change in hydropathy class ex3_raw <- calcObservedMutations(in_seq, germ_seq, regionDefinition=IMGT_V, mutationDefinition=HYDROPATHY_MUTATIONS, returnRaw=TRUE) # Count mutations by change in hydropathy class ex3_count <- calcObservedMutations(in_seq, germ_seq, regionDefinition=IMGT_V, mutationDefinition=HYDROPATHY_MUTATIONS, returnRaw=FALSE) ex3_freq <- calcObservedMutations(in_seq, germ_seq, regionDefinition=IMGT_V, mutationDefinition=HYDROPATHY_MUTATIONS, returnRaw=FALSE, frequency=TRUE) # Compre this with ex3_count table(ex3_raw$pos$region, ex3_raw$pos$R)[, "1"] table(ex3_raw$pos$region, ex3_raw$pos$S)[, "1"] # Compare this with ex3_freq table(ex3_raw$pos$region, ex3_raw$pos$R)[, "1"]/ex3_raw$nonN table(ex3_raw$pos$region, ex3_raw$pos$S)[, "1"]/ex3_raw$nonN } \seealso{ See \link{observedMutations} for counting the number of observed mutations in a \code{data.frame}. } shazam/man/GmmThreshold-class.Rd0000644000176200001440000000360313445225760016311 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DistToNearest.R \docType{class} \name{GmmThreshold-class} \alias{GmmThreshold-class} \alias{GmmThreshold} \alias{print,GmmThreshold-method} \alias{GmmThreshold-method} \alias{plot,GmmThreshold,missing-method} \title{Output of the \code{gmm} method of findThreshold} \usage{ \S4method{print}{GmmThreshold}(x) \S4method{plot}{GmmThreshold,missing}(x, y, ...) } \arguments{ \item{x}{GmmThreshold object} \item{y}{ignored.} \item{...}{arguments to pass to \link{plotGmmThreshold}.} } \description{ \code{GmmThreshold} contains output from the \code{gmm} method \link{findThreshold}. It includes parameters of two Gaussian fits and threshold cut. } \section{Slots}{ \describe{ \item{\code{x}}{input distance vector with NA or infinite values removed.} \item{\code{model}}{first-second fit functions.} \item{\code{cutoff}}{type of threshold cut.} \item{\code{a1}}{mixing weight of the first curve.} \item{\code{b1}}{second parameter of the first curve. Either the mean of a Normal distribution or shape of a Gamma distribution.} \item{\code{c1}}{third parameter of the first curve. Either the standard deviation of a Normal distribution or scale of a Gamma distribution.} \item{\code{a2}}{mixing weight of the second curve.} \item{\code{b2}}{second parameter of the second curve. Either the mean of a Normal distribution or shape of a Gamma distribution.} \item{\code{c2}}{third parameter of the second curve. Either the standard deviation of a Normal distribution or scale of a Gamma distribution.} \item{\code{loglk}}{log-likelihood of the fit.} \item{\code{threshold}}{threshold.} \item{\code{sensitivity}}{sensitivity.} \item{\code{specificity}}{specificity.} \item{\code{pvalue}}{p-value from Hartigans' dip statistic (HDS) test. Values less than 0.05 indicate significant bimodality.} }} \seealso{ \link{findThreshold} } shazam/man/distToNearest.Rd0000644000176200001440000002532513575260615015410 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DistToNearest.R \name{distToNearest} \alias{distToNearest} \title{Distance to nearest neighbor} \usage{ distToNearest( db, sequenceColumn = "JUNCTION", vCallColumn = "V_CALL", jCallColumn = "J_CALL", model = c("ham", "aa", "hh_s1f", "hh_s5f", "mk_rs1nf", "mk_rs5nf", "m1n_compat", "hs1f_compat"), normalize = c("len", "none"), symmetry = c("avg", "min"), first = TRUE, VJthenLen = TRUE, nproc = 1, fields = NULL, cross = NULL, mst = FALSE, subsample = NULL, progress = FALSE, cellIdColumn = NULL, locusColumn = NULL, groupUsingOnlyIGH = TRUE, keepVJLgroup = TRUE ) } \arguments{ \item{db}{data.frame containing sequence data.} \item{sequenceColumn}{name of the column containing the junction for grouping and for calculating nearest neighbot distances. Note that while both heavy and light chain junctions may be used for VJL grouping, only the heavy chain junction is used to calculate distances.} \item{vCallColumn}{name of the column containing the V-segment allele calls.} \item{jCallColumn}{name of the column containing the J-segment allele calls.} \item{model}{underlying SHM model, which must be one of \code{c("ham", "aa", "hh_s1f", "hh_s5f", "mk_rs1nf", "hs1f_compat", "m1n_compat")}. See Details for further information.} \item{normalize}{method of normalization. The default is \code{"len"}, which divides the distance by the length of the sequence group. If \code{"none"} then no normalization if performed.} \item{symmetry}{if model is hs5f, distance between seq1 and seq2 is either the average (avg) of seq1->seq2 and seq2->seq1 or the minimum (min).} \item{first}{if \code{TRUE} only the first call of the gene assignments is used. if \code{FALSE} the union of ambiguous gene assignments is used to group all sequences with any overlapping gene calls.} \item{VJthenLen}{a Boolean value specifying whether to perform partitioning as a 2-stage process. If \code{TRUE}, partitions are made first based on V and J annotations, and then further split based on junction lengths corresponding to \code{sequenceColumn}. If \code{FALSE}, perform partition as a 1-stage process during which V annotation, J annotation, and junction length are used to create partitions simultaneously. Defaults to \code{TRUE}.} \item{nproc}{number of cores to distribute the function over.} \item{fields}{additional fields to use for grouping.} \item{cross}{character vector of column names to use for grouping to calculate distances across groups. Meaning the columns that define self versus others.} \item{mst}{if \code{TRUE}, return comma-separated branch lengths from minimum spanning tree.} \item{subsample}{number of sequences to subsample for speeding up pairwise-distance-matrix calculation. Subsampling is performed without replacement in each VJL group of heavy chain sequences. If \code{subsample} is larger than the unique number of heavy chain sequences in each VJL group, then the subsampling process is ignored for that group. For each heavy chain sequence in \code{db}, the reported \code{DIST_NEAREST} is the distance to the closest heavy chain sequence in the subsampled set for the VJL group. If \code{NULL} no subsampling is performed.} \item{progress}{if \code{TRUE} print a progress bar.} \item{cellIdColumn}{name of the column containing cell IDs. Only applicable and required for single-cell mode.} \item{locusColumn}{name of the column containing locus information. Only applicable and required for single-cell mode.} \item{groupUsingOnlyIGH}{use only heavy chain (\code{IGH}) sequences for VJL grouping, disregarding light chains. Only applicable and required for single-cell mode. Default is \code{TRUE}. Also see \link[alakazam]{groupGenes}.} \item{keepVJLgroup}{a Boolean value specifying whether to keep in the output the the column column indicating grouping based on VJL combinations. Only applicable for 1-stage partitioning (i.e. \code{VJthenLen=FALSE}). Also see \link[alakazam]{groupGenes}.} } \value{ Returns a modified \code{db} data.frame with nearest neighbor distances between heavy chain sequences in the \code{DIST_NEAREST} column if \code{cross=NULL}. If \code{cross} was specified, distances will be added as the \code{CROSS_DIST_NEAREST} column. Note that distances between light chain sequences are not calculated, even if light chains were used for VJL grouping via \code{groupUsingOnlyIGH=FALSE}. Light chain sequences, if any, will have \code{NA} in the \code{DIST_NEAREST} field. } \description{ Get non-zero distance of every heavy chain (\code{IGH}) sequence (as defined by \code{sequenceColumn}) to its nearest sequence in a partition of heavy chains sharing the same V gene, J gene, and junction length (VJL), or in a partition of single cells with heavy chains sharing the same heavy chain VJL combination, or of single cells with heavy and light chains sharing the same heavy chain VJL and light chain VJL combinations. } \details{ To invoke single-cell mode, both \code{cellIdColumn} and \code{locusColumn} must be supplied. Otherwise, the function will run under non-single-cell mode. Under single-cell mode, only heavy chain sequences will be used for calculating nearest neighbor distances. Under non-single-cell mode, all input sequences will be used for calculating nearest neighbor distances, regardless of the values in the \code{locusColumn} field (if present). For single-cell mode, the input format is the same as that for \link[alakazam]{groupGenes}. Namely, each row represents a sequence/chain. Sequences/chains from the same cell are linked by a cell ID in the \code{cellIdColumn} field. Under this mode, there is a choice of whether grouping should be done using only heavy chain (\code{IGH}) sequences only, or using both heavy chain (\code{IGH}) and light chain (\code{IGK}, \code{IGL}) sequences. This is governed by \code{groupUsingOnlyIGH}. If used, values in the \code{locusColumn} column must be one of \code{"IGH"}, \code{"IGK"}, and \code{"IGL"}. Note that for \code{distToNearest}, a cell with multiple heavy chains is not allowed. The distance to nearest (heavy chain) neighbor can be used to estimate a threshold for assigning Ig sequences to clonal groups. A histogram of the resulting vector is often bimodal, with the ideal threshold being a value that separates the two modes. The following distance measures are accepted by the \code{model} parameter. \itemize{ \item \code{"ham"}: Single nucleotide Hamming distance matrix from \link[alakazam]{getDNAMatrix} with gaps assigned zero distance. \item \code{"aa"}: Single amino acid Hamming distance matrix from \link[alakazam]{getAAMatrix}. \item \code{"hh_s1f"}: Human single nucleotide distance matrix derived from \link{HH_S1F} with \link{calcTargetingDistance}. \item \code{"hh_s5f"}: Human 5-mer nucleotide context distance matix derived from \link{HH_S5F} with \link{calcTargetingDistance}. \item \code{"mk_rs1nf"}: Mouse single nucleotide distance matrix derived from \link{MK_RS1NF} with \link{calcTargetingDistance}. \item \code{"mk_rs5nf"}: Mouse 5-mer nucleotide context distance matrix derived from \link{MK_RS1NF} with \link{calcTargetingDistance}. \item \code{"hs1f_compat"}: Backwards compatible human single nucleotide distance matrix used in SHazaM v0.1.4 and Change-O v0.3.3. \item \code{"m1n_compat"}: Backwards compatibley mouse single nucleotide distance matrix used in SHazaM v0.1.4 and Change-O v0.3.3. } Note on \code{NA}s: if, for a given combination of V gene, J gene, and sequence length, there is only 1 heavy chain sequence (as defined by \code{sequenceColumn}), \code{NA} is returned instead of a distance (since it has no heavy chain neighbor). If for a given combination there are multiple heavy chain sequences but only 1 unique one, (in which case every heavy cahin sequence in this group is the de facto nearest neighbor to each other, thus giving rise to distances of 0), \code{NA}s are returned instead of zero-distances. Note on \code{subsample}: Subsampling is performed independently in each VJL group for heavy chain sequences. If \code{subsample} is larger than number of heavy chain sequences in the group, it is ignored. In other words, subsampling is performed only on groups in which the number of heavy chain sequences is equal to or greater than \code{subsample}. \code{DIST_NEAREST} has values calculated using all heavy chain sequences in the group for groups with fewer than \code{subsample} heavy chain sequences, and values calculated using a subset of heavy chain sequences for the larger groups. To select a value of \code{subsample}, it can be useful to explore the group sizes in \code{db} (and the number of heavy chain sequences in those groups). } \examples{ # Subset example data to one sample as a demo data(ExampleDb, package="alakazam") db <- subset(ExampleDb, SAMPLE == "-1h") # Use genotyped V assignments, Hamming distance, and normalize by junction length # First partition based on V and J assignments, then by junction length # Take into consideration ambiguous V and J annotations dist <- distToNearest(db, vCallColumn="V_CALL_GENOTYPED", model="ham", first=FALSE, VJthenLen=TRUE, normalize="len") # Plot histogram of non-NA distances p1 <- ggplot(data=subset(dist, !is.na(DIST_NEAREST))) + theme_bw() + ggtitle("Distance to nearest: Hamming") + xlab("distance") + geom_histogram(aes(x=DIST_NEAREST), binwidth=0.025, fill="steelblue", color="white") plot(p1) } \references{ \enumerate{ \item Smith DS, et al. Di- and trinucleotide target preferences of somatic mutagenesis in normal and autoreactive B cells. J Immunol. 1996 156:2642-52. \item Glanville J, Kuo TC, von Budingen H-C, et al. Naive antibody gene-segment frequencies are heritable and unaltered by chronic lymphocyte ablation. Proc Natl Acad Sci USA. 2011 108(50):20066-71. \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based on synonymous mutations from high-throughput immunoglobulin sequencing data. Front Immunol. 2013 4:358. } } \seealso{ See \link{calcTargetingDistance} for generating nucleotide distance matrices from a \link{TargetingModel} object. See \link{HH_S5F}, \link{HH_S1F}, \link{MK_RS1NF}, \link[alakazam]{getDNAMatrix}, and \link[alakazam]{getAAMatrix} for individual model details. } shazam/man/calcExpectedMutations.Rd0000644000176200001440000000647513575260615017115 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MutationProfiling.R \name{calcExpectedMutations} \alias{calcExpectedMutations} \title{Calculate expected mutation frequencies of a sequence} \usage{ calcExpectedMutations( germlineSeq, inputSeq = NULL, targetingModel = HH_S5F, regionDefinition = NULL, mutationDefinition = NULL ) } \arguments{ \item{germlineSeq}{germline (reference) sequence.} \item{inputSeq}{input (observed) sequence. If this is not \code{NULL}, then \code{germlineSeq} will be processed to be the same same length as \code{inputSeq} and positions in \code{germlineSeq} corresponding to positions with Ns in \code{inputSeq} will also be assigned an N.} \item{targetingModel}{\link{TargetingModel} object. Default is \link{HH_S5F}.} \item{regionDefinition}{\link{RegionDefinition} object defining the regions and boundaries of the Ig sequences.} \item{mutationDefinition}{\link{MutationDefinition} object defining replacement and silent mutation criteria. If \code{NULL} then replacement and silent are determined by exact amino acid identity.} } \value{ A \code{numeric} vector of the expected frequencies of mutations in the regions in the \code{regionDefinition}. For example, when using the default \link{IMGT_V} definition, which defines positions for CDR and FWR, the following columns are calculated: \itemize{ \item \code{MU_EXPECTED_CDR_R}: number of replacement mutations in CDR1 and CDR2 of the V-segment. \item \code{MU_EXPECTED_CDR_S}: number of silent mutations in CDR1 and CDR2 of the V-segment. \item \code{MU_EXPECTED_FWR_R}: number of replacement mutations in FWR1, FWR2 and FWR3 of the V-segment. \item \code{MU_EXPECTED_FWR_S}: number of silent mutations in FWR1, FWR2 and FWR3 of the V-segment. } } \description{ \code{calcExpectedMutations} calculates the expected mutation frequencies of a given sequence. This is primarily a helper function for \link{expectedMutations}. } \details{ \code{calcExpectedMutations} calculates the expected mutation frequencies of a given sequence and its germline. Note, only the part of the sequences defined in \code{regionDefinition} are analyzed. For example, when using the default \link{IMGT_V} definition, mutations in positions beyond 312 will be ignored. } \examples{ # Load example data data(ExampleDb, package="alakazam") # Use first entry in the exampled data for input and germline sequence in_seq <- ExampleDb[["SEQUENCE_IMGT"]][1] germ_seq <- ExampleDb[["GERMLINE_IMGT_D_MASK"]][1] # Identify all mutations in the sequence calcExpectedMutations(in_seq, germ_seq) # Identify only mutations the V segment minus CDR3 calcExpectedMutations(in_seq, germ_seq, regionDefinition=IMGT_V) # Define mutations based on hydropathy calcExpectedMutations(in_seq, germ_seq, regionDefinition=IMGT_V, mutationDefinition=HYDROPATHY_MUTATIONS) } \seealso{ \link{expectedMutations} calls this function. To create a custom \code{targetingModel} see \link{createTargetingModel}. See \link{calcObservedMutations} for getting observed mutation counts. } shazam/man/MK_RS5NF.Rd0000644000176200001440000000224613445225760014037 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \docType{data} \name{MK_RS5NF} \alias{MK_RS5NF} \title{Mouse kappa light chain, replacement and silent, 5-mer, non-functional targeting model.} \format{\link{TargetingModel} object.} \usage{ MK_RS5NF } \description{ 5-mer model of somatic hypermutation targeting based on analysis of replacement and silent mutations in non-functional kappa light chain Ig sequences from NP-immunized Mus musculus. } \references{ \enumerate{ \item Cui A, Di Niro R, Vander Heiden J, Briggs A, Adams K, Gilbert T, O'Connor K, Vigneault F, Shlomchik M and Kleinstein S (2016). A Model of Somatic Hypermutation Targeting in Mice Based on High-Throughput Ig Sequencing Data. The Journal of Immunology, 197(9), 3566-3574. } } \seealso{ See \link{MK_RS1NF} for the 1-mer substitution matrix from the same publication; \link{HH_S5F} for the human heavy chain silent 5-mer functional targeting model; \link{HKL_S5F} for the human light chain silent 5-mer functional targeting model; and \link{U5N} for the uniform 5-mer null targeting model. } \keyword{datasets} shazam/man/plotDensityThreshold.Rd0000644000176200001440000000451513575260615017011 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DistToNearest.R \name{plotDensityThreshold} \alias{plotDensityThreshold} \title{Plot findThreshold results for the density method} \usage{ plotDensityThreshold( data, cross = NULL, xmin = NULL, xmax = NULL, breaks = NULL, binwidth = NULL, title = NULL, size = 1, silent = FALSE, ... ) } \arguments{ \item{data}{\link{DensityThreshold} object output by the \code{"density"} method of \link{findThreshold}.} \item{cross}{numeric vector of distances from \link{distToNearest} to draw as a histogram below the \code{data} histogram for comparison purposes.} \item{xmin}{minimum limit for plotting the x-axis. If \code{NULL} the limit will be set automatically.} \item{xmax}{maximum limit for plotting the x-axis. If \code{NULL} the limit will be set automatically.} \item{breaks}{number of breaks to show on the x-axis. If \code{NULL} the breaks will be set automatically.} \item{binwidth}{binwidth for the histogram. If \code{NULL} the binwidth will be set automatically to the bandwidth parameter determined by \link{findThreshold}.} \item{title}{string defining the plot title.} \item{size}{numeric value for the plot line sizes.} \item{silent}{if \code{TRUE} do not draw the plot and just return the ggplot2 object; if \code{FALSE} draw the plot.} \item{...}{additional arguments to pass to ggplot2::theme.} } \value{ A ggplot object defining the plot. } \description{ \code{plotDensityThreshold} plots the results from \code{"density"} method of \link{findThreshold}, including the smoothed density estimate, input nearest neighbor distance histogram, and threshold selected. } \examples{ \donttest{ # Subset example data to one sample as a demo data(ExampleDb, package="alakazam") db <- subset(ExampleDb, SAMPLE == "-1h") # Use nucleotide Hamming distance and normalize by junction length db <- distToNearest(db, model="ham", normalize="len", nproc=1) # To find the threshold cut, call findThreshold function for "gmm" method. output <- findThreshold(db$DIST_NEAREST, method="density") print(output) # Plot plotDensityThreshold(output) } } \seealso{ See \link{DensityThreshold} for the the input object definition and \link{findThreshold} for generating the input object. See \link{distToNearest} calculating nearest neighbor distances. } shazam/man/extendSubstitutionMatrix.Rd0000644000176200001440000000226213575255270017725 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \name{extendSubstitutionMatrix} \alias{extendSubstitutionMatrix} \title{Extends a substitution model to include Ns.} \usage{ extendSubstitutionMatrix(substitutionModel) } \arguments{ \item{substitutionModel}{matrix of 5-mers substitution counts built by \link{createSubstitutionMatrix}.} } \value{ A 5x3125 matrix of normalized substitution rate for each 5-mer motif with rows names defining the center nucleotide, one of \code{c("A", "C", "G", "T", "N")}, and column names defining the 5-mer nucleotide sequence. } \description{ \code{extendSubstitutionMatrix} extends a 5-mer nucleotide substitution model with 5-mers that include Ns by averaging over all corresponding 5-mers without Ns. } \examples{ # Subset example data to one isotype and sample as a demo data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") # Create model using only silent mutations sub_model <- createSubstitutionMatrix(db, model="S") ext_model <- extendSubstitutionMatrix(sub_model) } \seealso{ \link{createSubstitutionMatrix}, \link{extendMutabilityMatrix} } shazam/man/slideWindowDb.Rd0000644000176200001440000000341413575260615015351 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MutationProfiling.R \name{slideWindowDb} \alias{slideWindowDb} \title{Sliding window approach towards filtering sequences in a \code{data.frame}} \usage{ slideWindowDb( db, sequenceColumn = "SEQUENCE_IMGT", germlineColumn = "GERMLINE_IMGT_D_MASK", mutThresh, windowSize ) } \arguments{ \item{db}{\code{data.frame} containing sequence data.} \item{sequenceColumn}{name of the column containing IMGT-gapped sample sequences.} \item{germlineColumn}{name of the column containing IMGT-gapped germline sequences.} \item{mutThresh}{threshold on the number of mutations in \code{windowSize} consecutive nucleotides. Must be between 1 and \code{windowSize} inclusive.} \item{windowSize}{length of consecutive nucleotides. Must be at least 2.} } \value{ a logical vector. The length of the vector matches the number of input sequences in \code{db}. Each entry in the vector indicates whether the corresponding input sequence should be filtered based on the given parameters. } \description{ \code{slideWindowDb} determines whether each input sequence in a \code{data.frame} contains equal to or more than a given number of mutations in a given length of consecutive nucleotides (a "window") when compared to their respective germline sequence. } \examples{ # Use an entry in the example data for input and germline sequence data(ExampleDb, package="alakazam") # Apply the sliding window approach on a subset of ExampleDb slideWindowDb(db = ExampleDb[1:10, ], mutThresh=6, windowSize=10) } \seealso{ See \link{slideWindowSeq} for applying the sliding window approach on a single sequence. See \link{slideWindowTune} for parameter tuning for \code{mutThresh} and \code{windowSize}. } shazam/man/U5N.Rd0000644000176200001440000000105713445225760013221 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \docType{data} \name{U5N} \alias{U5N} \title{Uniform 5-mer null targeting model.} \format{A \link{TargetingModel} object.} \usage{ U5N } \description{ A null 5-mer model of somatic hypermutation targeting where all substitution, mutability and targeting rates are uniformly distributed. } \seealso{ See \link{HH_S5F} and \link{HKL_S5F} for the human 5-mer targeting models; and \link{MK_RS5NF} for the mouse 5-mer targeting model. } \keyword{datasets} shazam/man/makeDegenerate5merSub.Rd0000644000176200001440000000406213445225760016755 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \name{makeDegenerate5merSub} \alias{makeDegenerate5merSub} \title{Make a degenerate 5-mer substitution model based on a 1-mer substitution model} \usage{ makeDegenerate5merSub(sub1mer, extended = FALSE) } \arguments{ \item{sub1mer}{a 4x4 matrix containing (normalized) substitution rates. Row names should correspond to nucleotides to mutate from. Column names should correspond to nucleotides to mutate into. Nucleotides should include "A", "T", "G", and "C" (case-insensitive).} \item{extended}{whether to return the unextended (\code{extended=FALSE}) or extended (\code{extended=TRUE}) 5-mer substitution model. Default is \code{FALSE}.} } \value{ For \code{extended=FALSE}, a 4x1024 matrix. For \code{extended=TRUE}, a 5x3125 matrix. } \description{ \code{makeDegenerate5merSub} populates substitution rates from a 1-mer substitution model into 5-mers with corresponding central 1-mers. } \details{ As a concrete example, consider a 1-mer substitution model in which substitution rates from "A" to "T", "G", and "C" are, respectively, 0.1, 0.6, and 0.3. In the resultant degenerate 5-mer substitution model, all the 5-mers (columns) that have an "A" as their central 1-mer would have substitution rates (rows) of 0.1, 0.6, and 0.3 to "T", "G", and "C" respectively. When \code{extended=TRUE}, \code{extendSubstitutionMatrix} is called to extend the 4x1024 substitution matrix. } \examples{ # Make a degenerate 5-mer model (4x1024) based on HKL_S1F (4x4) # Note: not to be confused with HKL_S5F@substitution, which is non-degenerate degenerate5merSub <- makeDegenerate5merSub(sub1mer = HKL_S1F) # Look at a few 5-mers degenerate5merSub[, c("AAAAT", "AACAT", "AAGAT", "AATAT")] } \seealso{ See \link{makeAverage1merSub} for making a 1-mer substitution model by taking the average of a 5-mer substitution model. See \link{extendSubstitutionMatrix} for extending the substitution matrix. } shazam/man/observedMutations.Rd0000644000176200001440000001424413575260615016333 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MutationProfiling.R \name{observedMutations} \alias{observedMutations} \title{Calculate observed numbers of mutations} \usage{ observedMutations( db, sequenceColumn = "SEQUENCE_IMGT", germlineColumn = "GERMLINE_IMGT_D_MASK", regionDefinition = NULL, mutationDefinition = NULL, ambiguousMode = c("eitherOr", "and"), frequency = FALSE, combine = FALSE, nproc = 1 ) } \arguments{ \item{db}{\code{data.frame} containing sequence data.} \item{sequenceColumn}{\code{character} name of the column containing input sequences. IUPAC ambiguous characters for DNA are supported.} \item{germlineColumn}{\code{character} name of the column containing the germline or reference sequence. IUPAC ambiguous characters for DNA are supported.} \item{regionDefinition}{\link{RegionDefinition} object defining the regions and boundaries of the Ig sequences. If NULL, mutations are counted for entire sequence.} \item{mutationDefinition}{\link{MutationDefinition} object defining replacement and silent mutation criteria. If \code{NULL} then replacement and silent are determined by exact amino acid identity.} \item{ambiguousMode}{whether to consider ambiguous characters as \code{"either or"} or \code{"and"} when determining and counting the type(s) of mutations. Applicable only if \code{sequenceColumn} and/or \code{germlineColumn} contain(s) ambiguous characters. One of \code{c("eitherOr", "and")}. Default is \code{"eitherOr"}.} \item{frequency}{\code{logical} indicating whether or not to calculate mutation frequencies. Default is \code{FALSE}.} \item{combine}{\code{logical} indicating whether for each sequence should the mutation counts for the different regions (CDR, FWR) and mutation types be combined and return one value of count/frequency per sequence instead of multiple values. Default is \code{FALSE}.} \item{nproc}{number of cores to distribute the operation over. If the cluster has already been set the call function with \code{nproc} = 0 to not reset or reinitialize. Default is \code{nproc} = 1.} } \value{ A modified \code{db} \code{data.frame} with observed mutation counts for each sequence listed. The columns names are dynamically created based on the regions in the \code{regionDefinition}. For example, when using the \link{IMGT_V} definition, which defines positions for CDR and FWR, the following columns are added: \itemize{ \item \code{MU_COUNT_CDR_R}: number of replacement mutations in CDR1 and CDR2 of the V-segment. \item \code{MU_COUNT_CDR_S}: number of silent mutations in CDR1 and CDR2 of the V-segment. \item \code{MU_COUNT_FWR_R}: number of replacement mutations in FWR1, FWR2 and FWR3 of the V-segment. \item \code{MU_COUNT_FWR_S}: number of silent mutations in FWR1, FWR2 and FWR3 of the V-segment. } If \code{frequency=TRUE}, R and S mutation frequencies are calculated over the number of non-N positions in the speficied regions. \itemize{ \item \code{MU_FREQ_CDR_R}: frequency of replacement mutations in CDR1 and CDR2 of the V-segment. \item \code{MU_FREQ_CDR_S}: frequency of silent mutations in CDR1 and CDR2 of the V-segment. \item \code{MU_FREQ_FWR_R}: frequency of replacement mutations in FWR1, FWR2 and FWR3 of the V-segment. \item \code{MU_FREQ_FWR_S}: frequency of silent mutations in FWR1, FWR2 and FWR3 of the V-segment. } If \code{frequency=TRUE} and \code{combine=TRUE}, the mutations and non-N positions are aggregated and a single \code{MU_FREQ} value is returned \itemize{ \item \code{MU_FREQ}: frequency of replacement and silent mutations in the specified region } } \description{ \code{observedMutations} calculates the observed number of mutations for each sequence in the input \code{data.frame}. } \details{ Mutation counts are determined by comparing the input sequences (in the column specified by \code{sequenceColumn}) to the germline sequence (in the column specified by \code{germlineColumn}). See \link{calcObservedMutations} for more technical details, \strong{including criteria for which sequence differences are included in the mutation counts and which are not}. The mutations are binned as either replacement (R) or silent (S) across the different regions of the sequences as defined by \code{regionDefinition}. Typically, this would be the framework (FWR) and complementarity determining (CDR) regions of IMGT-gapped nucleotide sequences. Mutation counts are appended to the input \code{db} as additional columns. } \examples{ # Subset example data data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE == "IgG" & SAMPLE == "+7d") # Calculate mutation frequency over the entire sequence db_obs <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", frequency=TRUE, nproc=1) # Count of V-region mutations split by FWR and CDR # With mutations only considered replacement if charge changes db_obs <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=IMGT_V, mutationDefinition=CHARGE_MUTATIONS, nproc=1) } \seealso{ \link{calcObservedMutations} is called by this function to get the number of mutations in each sequence grouped by the \link{RegionDefinition}. See \link{IMGT_SCHEMES} for a set of predefined \link{RegionDefinition} objects. See \link{expectedMutations} for calculating expected mutation frequencies. } shazam/man/HH_S5F.Rd0000644000176200001440000000175413445225760013572 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \docType{data} \name{HH_S5F} \alias{HH_S5F} \title{Human heavy chain, silent, 5-mer, functional targeting model.} \format{A \link{TargetingModel} object.} \usage{ HH_S5F } \description{ 5-mer model of somatic hypermutation targeting based on analysis of silent mutations in functional heavy chain Ig sequences from Homo sapiens. } \references{ \enumerate{ \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based on synonymous mutations from high-throughput immunoglobulin sequencing data. Front Immunol. 2013 4(November):358. } } \seealso{ See \link{HH_S1F} for the 1-mer substitution matrix from the same publication; \link{HKL_S5F} for the human light chain 5-mer targeting model; \link{MK_RS5NF} for the mouse 5-mer targeting model; and \link{U5N} for the uniform 5-mer null targeting model. } \keyword{datasets} shazam/man/MutationDefinition-class.Rd0000644000176200001440000000214113445225760017521 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MutationDefinitions.R \docType{class} \name{MutationDefinition-class} \alias{MutationDefinition-class} \alias{MutationDefinition} \title{S4 class defining replacement and silent mutation definitions} \description{ \code{MutationDefinition} defines a common data structure for defining the whether a mutation is annotated as a replacement or silent mutation. } \section{Slots}{ \describe{ \item{\code{name}}{name of the MutationDefinition.} \item{\code{description}}{description of the model and its source.} \item{\code{classes}}{named character vectors with single-letter amino acid codes as names and amino acid classes as values, with \code{NA} assigned to set of characters \code{c("X", "*", "-", ".")}. Replacement (R) is be defined as a change in amino acid class and silent (S) as no change in class.} \item{\code{codonTable}}{matrix of codons (columns) and substitutions (rows).} \item{\code{citation}}{publication source.} }} \seealso{ See \link{MUTATION_SCHEMES} for a set of predefined \code{MutationDefinition} objects. } shazam/man/MUTATION_SCHEMES.Rd0000644000176200001440000000230313445225760015214 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MutationDefinitions.R \name{MUTATION_SCHEMES} \alias{MUTATION_SCHEMES} \alias{CHARGE_MUTATIONS} \alias{HYDROPATHY_MUTATIONS} \alias{POLARITY_MUTATIONS} \alias{VOLUME_MUTATIONS} \title{Amino acid mutation definitions} \format{A \link{MutationDefinition} object defining: \itemize{ \item \code{CHARGE_MUTATIONS}: Amino acid mutations are defined by changes in side chain charge class. \item \code{HYDROPATHY_MUTATIONS}: Amino acid mutations are defined by changes in side chain hydrophobicitity class. \item \code{POLARITY_MUTATIONS}: Amino acid mutations are defined by changes in side chain polarity class. \item \code{VOLUME_MUTATIONS}: Amino acid mutations are defined by changes in side chain volume class. }} \description{ Definitions of replacement (R) and silent (S) mutations for different amino acid physicochemical classes. } \references{ \enumerate{ \item \url{http://www.imgt.org/IMGTeducation/Aide-memoire/_UK/aminoacids/IMGTclasses.html} } } shazam/man/expectedMutations.Rd0000644000176200001440000000730513575260615016323 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MutationProfiling.R \name{expectedMutations} \alias{expectedMutations} \title{Calculate expected mutation frequencies} \usage{ expectedMutations( db, sequenceColumn = "SEQUENCE_IMGT", germlineColumn = "GERMLINE_IMGT_D_MASK", targetingModel = HH_S5F, regionDefinition = NULL, mutationDefinition = NULL, nproc = 1 ) } \arguments{ \item{db}{\code{data.frame} containing sequence data.} \item{sequenceColumn}{\code{character} name of the column containing input sequences.} \item{germlineColumn}{\code{character} name of the column containing the germline or reference sequence.} \item{targetingModel}{\link{TargetingModel} object. Default is \link{HH_S5F}.} \item{regionDefinition}{\link{RegionDefinition} object defining the regions and boundaries of the Ig sequences.} \item{mutationDefinition}{\link{MutationDefinition} object defining replacement and silent mutation criteria. If \code{NULL} then replacement and silent are determined by exact amino acid identity.} \item{nproc}{\code{numeric} number of cores to distribute the operation over. If the cluster has already been set the call function with \code{nproc} = 0 to not reset or reinitialize. Default is \code{nproc} = 1.} } \value{ A modified \code{db} \code{data.frame} with expected mutation frequencies for each region defined in \code{regionDefinition}. The columns names are dynamically created based on the regions in \code{regionDefinition}. For example, when using the \link{IMGT_V} definition, which defines positions for CDR and FWR, the following columns are added: \itemize{ \item \code{MU_EXPECTED_CDR_R}: number of replacement mutations in CDR1 and CDR2 of the V-segment. \item \code{MU_EXPECTED_CDR_S}: number of silent mutations in CDR1 and CDR2 of the V-segment. \item \code{MU_EXPECTED_FWR_R}: number of replacement mutations in FWR1, FWR2 and FWR3 of the V-segment. \item \code{MU_EXPECTED_FWR_S}: number of silent mutations in FWR1, FWR2 and FWR3 of the V-segment. } } \description{ \code{expectedMutations} calculates the expected mutation frequencies for each sequence in the input \code{data.frame}. } \details{ Only the part of the sequences defined in \code{regionDefinition} are analyzed. For example, when using the \link{IMGT_V} definition, mutations in positions beyond 312 will be ignored. } \examples{ # Subset example data data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE \%in\% c("IgA", "IgG") & SAMPLE == "+7d") # Calculate expected mutations over V region db_exp <- expectedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=IMGT_V, nproc=1) # Calculate hydropathy expected mutations over V region db_exp <- expectedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=IMGT_V, mutationDefinition=HYDROPATHY_MUTATIONS, nproc=1) } \seealso{ \link{calcExpectedMutations} is called by this function to calculate the expected mutation frequencies. See \link{observedMutations} for getting observed mutation counts. See \link{IMGT_SCHEMES} for a set of predefined \link{RegionDefinition} objects. } shazam/man/testBaseline.Rd0000644000176200001440000000525713575255270015245 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Baseline.R \name{testBaseline} \alias{testBaseline} \title{Two-sided test of BASELINe PDFs} \usage{ testBaseline(baseline, groupBy) } \arguments{ \item{baseline}{\code{Baseline} object containing the \code{db} and grouped BASELINe PDFs returned by \link{groupBaseline}.} \item{groupBy}{string defining the column in the \code{db} slot of the \code{Baseline} containing sequence or group identifiers.} } \value{ A data.frame with test results containing the following columns: \itemize{ \item \code{REGION}: sequence region, such as "CDR" and "FWR". \item \code{TEST}: string defining the groups be compared. The string is formated as the conclusion associated with the p-value in the form \code{GROUP1 != GROUP2}. Meaning, the p-value for rejection of the null hypothesis that GROUP1 and GROUP2 have equivalent distributions. \item \code{PVALUE}: two-sided p-value for the comparison. \item \code{FDR}: FDR corrected \code{PVALUE}. } } \description{ \code{testBaseline} performs a two-sample signifance test of BASELINe posterior probability density functions (PDFs). } \examples{ \donttest{ # Subset example data data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE \%in\% c("IgM", "IgG", "IgA")) # Collapse clones db <- collapseClones(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", method="thresholdedFreq", minimumFrequency=0.6, includeAmbiguous=FALSE, breakTiesStochastic=FALSE) # Calculate BASELINe baseline <- calcBaseline(db, sequenceColumn="CLONAL_SEQUENCE", germlineColumn="CLONAL_GERMLINE", testStatistic="focused", regionDefinition=IMGT_V, targetingModel=HH_S5F, nproc=1) # Group PDFs by the isotype grouped <- groupBaseline(baseline, groupBy="ISOTYPE") # Visualize isotype PDFs plot(grouped, "ISOTYPE") # Perform test on isotype PDFs testBaseline(grouped, groupBy="ISOTYPE") } } \references{ \enumerate{ \item Yaari G, et al. Quantifying selection in high-throughput immunoglobulin sequencing data sets. Nucleic Acids Res. 2012 40(17):e134. (Corretions at http://selection.med.yale.edu/baseline/correction/) } } \seealso{ To generate the \link{Baseline} input object see \link{groupBaseline}. } shazam/man/slideWindowTune.Rd0000644000176200001440000000711113575260615015735 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MutationProfiling.R \name{slideWindowTune} \alias{slideWindowTune} \title{Parameter tuning for sliding window approach} \usage{ slideWindowTune( db, sequenceColumn = "SEQUENCE_IMGT", germlineColumn = "GERMLINE_IMGT_D_MASK", dbMutList = NULL, mutThreshRange, windowSizeRange, verbose = TRUE ) } \arguments{ \item{db}{\code{data.frame} containing sequence data.} \item{sequenceColumn}{name of the column containing IMGT-gapped sample sequences.} \item{germlineColumn}{name of the column containing IMGT-gapped germline sequences.} \item{dbMutList}{if supplied, this should be a list consisting of \code{data.frame}s returned as \code{$pos} in the nested list produced by \link{calcObservedMutations} with \code{returnRaw=TRUE}; otherwise, \link{calcObservedMutations} is called on columns \code{sequenceColumn} and \code{germlineColumn} of \code{db}. Default is \code{NULL}.} \item{mutThreshRange}{range of threshold on the number of mutations in \code{windowSize} consecutive nucleotides to try. Must be between 1 and maximum \code{windowSizeRange} inclusive.} \item{windowSizeRange}{range of length of consecutive nucleotides to try. The lower end must be at least 2.} \item{verbose}{whether to print out messages indicating current progress. Default is \code{TRUE}.} } \value{ a list of logical matrices. Each matrix corresponds to a \code{windowSize} in \code{windowSizeRange}. Each column in a matrix corresponds to a \code{mutThresh} in \code{mutThreshRange}. } \description{ Apply \link{slideWindowDb} over a search grid made of combinations of \code{mutThresh} and \code{windowSize} to help with picking a pair of values for these parameters. Parameter tuning can be performed by choosing a combination that gives a reasonable number of filtered/remaining sequences. } \details{ If, in a given combination of \code{mutThresh} and \code{windowSize}, \code{mutThresh} is greater than \code{windowSize}, \code{NA}s will be returned for that particular combination. A message indicating that the combination has been "skipped" will be printed if \code{verbose=TRUE}. If \link{calcObservedMutations} was previously run on \code{db} and saved, supplying \code{$pos} from the saved result as \code{dbMutList} could save time by skipping a second call of \link{calcObservedMutations}. This could be helpful especially when \code{db} is large. } \examples{ # Load and subset example data data(ExampleDb, package="alakazam") db <- ExampleDb[1:5, ] # Try out thresholds of 2-4 mutations in window sizes of 7-9 nucleotides. # In this case, all combinations are legal. slideWindowTune(db, mutThreshRange=2:4, windowSizeRange=7:9) # Illegal combinations are skipped, returning NAs. slideWindowTune(db, mutThreshRange=2:4, windowSizeRange=2:4, verbose=FALSE) # Run calcObservedMutations separately exDbMutList <- sapply(1:5, function(i) { calcObservedMutations(inputSeq=db[i, "SEQUENCE_IMGT"], germlineSeq=db[i, "GERMLINE_IMGT_D_MASK"], returnRaw=TRUE)$pos }) slideWindowTune(db, dbMutList=exDbMutList, mutThreshRange=2:4, windowSizeRange=2:4) } \seealso{ \link{slideWindowDb} is called on \code{db} for tuning. See \link{slideWindowTunePlot} for visualization. See \link{calcObservedMutations} for generating \code{dbMutList}. } shazam/man/createTargetingModel.Rd0000644000176200001440000000720413575260615016705 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \name{createTargetingModel} \alias{createTargetingModel} \title{Creates a TargetingModel} \usage{ createTargetingModel( db, model = c("S", "RS"), sequenceColumn = "SEQUENCE_IMGT", germlineColumn = "GERMLINE_IMGT_D_MASK", vCallColumn = "V_CALL", multipleMutation = c("independent", "ignore"), minNumMutations = 50, minNumSeqMutations = 500, modelName = "", modelDescription = "", modelSpecies = "", modelCitation = "", modelDate = NULL ) } \arguments{ \item{db}{data.frame containing sequence data.} \item{model}{type of model to create. The default model, "S", builds a model by counting only silent mutations. \code{model="S"} should be used for data that includes functional sequences. Setting \code{model="RS"} creates a model by counting both replacement and silent mutations and may be used on fully non-functional sequence data sets.} \item{sequenceColumn}{name of the column containing IMGT-gapped sample sequences.} \item{germlineColumn}{name of the column containing IMGT-gapped germline sequences.} \item{vCallColumn}{name of the column containing the V-segment allele calls.} \item{multipleMutation}{string specifying how to handle multiple mutations occuring within the same 5-mer. If \code{"independent"} then multiple mutations within the same 5-mer are counted indepedently. If \code{"ignore"} then 5-mers with multiple mutations are excluded from the otal mutation tally.} \item{minNumMutations}{minimum number of mutations required to compute the 5-mer substitution rates. If the number of mutations for a 5-mer is below this threshold, its substitution rates will be estimated from neighboring 5-mers. Default is 50.} \item{minNumSeqMutations}{minimum number of mutations in sequences containing each 5-mer to compute the mutability rates. If the number is smaller than this threshold, the mutability for the 5-mer will be inferred. Default is 500.} \item{modelName}{name of the model.} \item{modelDescription}{description of the model and its source data.} \item{modelSpecies}{genus and species of the source sequencing data.} \item{modelCitation}{publication source.} \item{modelDate}{date the model was built. If \code{NULL} the current date will be used.} } \value{ A \link{TargetingModel} object. } \description{ \code{createTargetingModel} creates a 5-mer \code{TargetingModel}. } \details{ \strong{Caution: The targeting model functions do NOT support ambiguous characters in their inputs. You MUST make sure that your input and germline sequences do NOT contain ambiguous characters (especially if they are clonal consensuses returned from \code{collapseClones}).} } \examples{ \donttest{ # Subset example data to one isotype and sample as a demo data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") # Create model using only silent mutations and ignore multiple mutations model <- createTargetingModel(db, model="S", multipleMutation="ignore") } } \references{ \enumerate{ \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based on synonymous mutations from high-throughput immunoglobulin sequencing data. Front Immunol. 2013 4(November):358. } } \seealso{ See \link{TargetingModel} for the return object. See \link{plotMutability} plotting a mutability model. See \link{createSubstitutionMatrix}, \link{extendSubstitutionMatrix}, \link{createMutabilityMatrix}, \link{extendMutabilityMatrix} and \link{createTargetingMatrix} for component steps in building a model. } shazam/man/HKL_S1F.Rd0000644000176200001440000000211213445225760013672 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \docType{data} \name{HKL_S1F} \alias{HKL_S1F} \title{Human kappa and lambda chain, silent, 1-mer, functional substitution model.} \format{A 4x4 matrix of nucleotide substitution rates. The rates are normalized, therefore each row sums up to 1.} \usage{ HKL_S1F } \description{ 1-mer substitution model of somatic hypermutation based on analysis of silent mutations in functional kappa and lambda light chain Ig sequences from Homo sapiens. } \note{ Reported in Table III in Cui et al, 2016. } \references{ \enumerate{ \item Cui A, Di Niro R, Vander Heiden J, Briggs A, Adams K, Gilbert T, O'Connor K, Vigneault F, Shlomchik M and Kleinstein S (2016). A Model of Somatic Hypermutation Targeting in Mice Based on High-Throughput Ig Sequencing Data. The Journal of Immunology, 197(9), 3566-3574. } } \seealso{ See \link{HH_S1F} for the human heavy chain 1-mer substitution model and \link{MK_RS1NF} for the mouse light chain 1-mer substitution model. } \keyword{datasets} shazam/man/RegionDefinition-class.Rd0000644000176200001440000000207513445225760017152 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/RegionDefinitions.R \docType{class} \name{RegionDefinition-class} \alias{RegionDefinition-class} \alias{RegionDefinition} \title{S4 class defining a region definition} \description{ \code{RegionDefinition} defines a common data structure for defining the region boundaries of an Ig sequence. } \section{Slots}{ \describe{ \item{\code{name}}{name of the RegionDefinition.} \item{\code{description}}{description of the model and its source.} \item{\code{boundaries}}{\code{factor} defining the region boundaries of the sequence. The levels and values of \code{boundaries} determine the number of regions.} \item{\code{seqLength}}{length of the sequence.} \item{\code{regions}}{levels of the boundaries; e.g, \code{c("CDR", "FWR")}.} \item{\code{labels}}{labels for the boundary and mutations combinations; e.g., \code{c("CDR_R", "CDR_S", "FWR_R", "FWR_S")}.} \item{\code{citation}}{publication source.} }} \seealso{ See \link{IMGT_SCHEMES} for a set of predefined \code{RegionDefinition} objects. } shazam/man/makeAverage1merMut.Rd0000644000176200001440000000276213445225760016301 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \name{makeAverage1merMut} \alias{makeAverage1merMut} \title{Make a 1-mer mutability model by averaging over a 5-mer mutability model} \usage{ makeAverage1merMut(mut5mer) } \arguments{ \item{mut5mer}{a named vector of length 1024 such as that returned by \code{createMutabilityMatrix} and that returned by \code{makeDegenerate5merMut} with \code{extended=FALSE}. Names should correspond to 5-mers made up of "A", "T", "G", and "C" (case-insensitive). \code{NA} values are allowed.} } \value{ A named vector of length 4 containing normalized mutability rates. } \description{ \code{makeAverage1merMut} averages mutability rates in a 5-mer mutability model to derive a 1-mer mutability model. } \details{ For example, the mutability rate of "A" in the resultant 1-mer model is derived by averaging the mutability rates of all the 5-mers that have an "A" as their central 1-mer, followed by normalization. } \examples{ # Make a degenerate 5-mer model (length of 1024) based on a 1-mer model example1merMut <- c(A=0.2, T=0.1, C=0.4, G=0.3) degenerate5merMut <- makeDegenerate5merMut(mut1mer = example1merMut) # Now make a 1-mer model by averaging over the degenerate 5-mer model # Expected to get back example1merMut makeAverage1merMut(mut5mer = degenerate5merMut) } \seealso{ See \link{makeDegenerate5merMut} for making a degenerate 5-mer mutability model based on a 1-mer mutability model. } shazam/man/extendMutabilityMatrix.Rd0000644000176200001440000000253013575255270017332 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \name{extendMutabilityMatrix} \alias{extendMutabilityMatrix} \title{Extends a mutability model to include Ns.} \usage{ extendMutabilityMatrix(mutabilityModel) } \arguments{ \item{mutabilityModel}{vector of 5-mer mutability rates built by \link{createMutabilityMatrix}.} } \value{ A 3125 vector of normalized mutability rates for each 5-mer motif with names defining the 5-mer nucleotide sequence. Note that "normalized" means that the mutability rates for the 1024 5-mers that contain no "N" at any position sums up to 1 (as opposed to the entire vector summing up to 1). } \description{ \code{extendMutabilityMatrix} extends a 5-mer nucleotide mutability model with 5-mers that include Ns by averaging over all corresponding 5-mers without Ns. } \examples{ \donttest{ # Subset example data to one isotype and sample as a demo data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") # Create model using only silent mutations and ignore multiple mutations sub_model <- createSubstitutionMatrix(db, model="S") mut_model <- createMutabilityMatrix(db, sub_model, model="S") ext_model <- extendMutabilityMatrix(mut_model) } } \seealso{ \link{createMutabilityMatrix}, \link{extendSubstitutionMatrix} } shazam/man/collapseClones.Rd0000644000176200001440000004705513575260615015572 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MutationProfiling.R \name{collapseClones} \alias{collapseClones} \title{Constructs effective clonal sequences for all clones} \usage{ collapseClones( db, cloneColumn = "CLONE", sequenceColumn = "SEQUENCE_IMGT", germlineColumn = "GERMLINE_IMGT_D_MASK", muFreqColumn = NULL, regionDefinition = NULL, method = c("mostCommon", "thresholdedFreq", "catchAll", "mostMutated", "leastMutated"), minimumFrequency = NULL, includeAmbiguous = FALSE, breakTiesStochastic = FALSE, breakTiesByColumns = NULL, expandedDb = FALSE, nproc = 1 ) } \arguments{ \item{db}{\code{data.frame} containing sequence data. Required.} \item{cloneColumn}{\code{character} name of the column containing clonal identifiers. Required.} \item{sequenceColumn}{\code{character} name of the column containing input sequences. Required. The length of each input sequence should match that of its corresponding germline sequence.} \item{germlineColumn}{\code{character} name of the column containing germline sequences. Required. The length of each germline sequence should match that of its corresponding input sequence.} \item{muFreqColumn}{\code{character} name of the column containing mutation frequency. Optional. Applicable to the \code{"mostMutated"} and \code{"leastMutated"} methods. If not supplied, mutation frequency is computed by calling \code{observedMutations}. Default is \code{NULL}. See Cautions for note on usage.} \item{regionDefinition}{\link{RegionDefinition} object defining the regions and boundaries of the Ig sequences. Optional. Default is \code{NULL}.} \item{method}{method for calculating input consensus sequence. Required. One of \code{"thresholdedFreq"}, \code{"mostCommon"}, \code{"catchAll"}, \code{"mostMutated"}, or \code{"leastMutated"}. See "Methods" for details.} \item{minimumFrequency}{frequency threshold for calculating input consensus sequence. Applicable to and required for the \code{"thresholdedFreq"} method. A canonical choice is 0.6. Default is \code{NULL}.} \item{includeAmbiguous}{whether to use ambiguous characters to represent positions at which there are multiple characters with frequencies that are at least \code{minimumFrequency} or that are maximal (i.e. ties). Applicable to and required for the \code{"thresholdedFreq"} and \code{"mostCommon"} methods. Default is \code{FALSE}. See "Choosing ambiguous characters" for rules on choosing ambiguous characters.} \item{breakTiesStochastic}{In case of ties, whether to randomly pick a sequence from sequences that fulfill the criteria as consensus. Applicable to and required for all methods except for \code{"catchAll"}. Default is \code{FALSE}. See "Methods" for details.} \item{breakTiesByColumns}{A list of the form \code{list(c(col_1, col_2, ...), c(fun_1, fun_2, ...))}, where \code{col_i} is a \code{character} name of a column in \code{db}, and \code{fun_i} is a function to be applied on that column. Currently, only \code{max} and \code{min} are supported. Note that the two \code{c()}'s in \code{list()} are essential (i.e. if there is only 1 column, the list should be of the form \code{list(c(col_1), c(func_1))}. Applicable to and optional for the \code{"mostMutated"} and \code{"leastMutated"} methods. If supplied, \code{fun_i}'s are applied on \code{col_i}'s to help break ties. Default is \code{NULL}. See "Methods" for details.} \item{expandedDb}{\code{logical} indicating whether or not to return the expanded \code{db}, containing all the sequences (as opposed to returning just one sequence per clone).} \item{nproc}{Number of cores to distribute the operation over. If the \code{cluster} has already been set earlier, then pass the \code{cluster}. This will ensure that it is not reset.} } \value{ A modified \code{db} with the following additional columns: \itemize{ \item \code{CLONAL_SEQUENCE}: effective sequence for the clone. \item \code{CLONAL_GERMLINE}: germline sequence for the clone. \item \code{CLONAL_SEQUENCE_MUFREQ}: mutation frequency of \code{CLONAL_SEQUENCE}; only added for the \code{"mostMutated"} and \code{"leastMutated"} methods. } \code{CLONAL_SEQUENCE} is generated with the method of choice indicated by \code{method}, and \code{CLONAL_GERMLINE} is generated with the \code{"mostCommon"} method, along with, where applicable, user-defined parameters such as \code{minimumFrequency}, \code{includeAmbiguous}, \code{breakTiesStochastic}, and \code{breakTiesByColumns}. } \description{ \code{collapseClones} creates effective input and germline sequences for each clonal group and appends columns containing the consensus sequences to the input \code{data.frame}. } \section{Consensus lengths}{ For each clone, \code{CLONAL_SEQUENCE} and \code{CLONAL_GERMLINE} have the same length. \itemize{ \item For the \code{"thresholdedFreq"}, \code{"mostCommon"}, and \code{"catchAll"} methods: The length of the consensus sequences is determined by the longest possible consensus sequence (baesd on \code{inputSeq} and \code{germlineSeq}) and \code{regionDefinition@seqLength} (if supplied), whichever is shorter. Given a set of sequences of potentially varying lengths, the longest possible length of their consensus sequence is taken to be the longest length along which there is information contained at every nucleotide position across majority of the sequences. Majority is defined to be greater than \code{floor(n/2)}, where \code{n} is the number of sequences. If the longest possible consensus length is 0, there will be a warning and an empty string (\code{""}) will be returned. If a length limit is defined by supplying a \code{regionDefinition} via \code{regionDefinition@seqLength}, the consensus length will be further restricted to the shorter of the longest possible length and \code{regionDefinition@seqLength}. \item For the \code{"mostMutated"} and \code{"leastMutated"} methods: The length of the consensus sequences depends on that of the most/least mutated input sequence, and, if supplied, the length limit defined by \code{regionDefinition@seqLength}, whichever is shorter. If the germline consensus computed using the \code{"mostCommon"} method is longer than the most/least mutated input sequence, the germline consensus is trimmed to be of the same length as the input consensus. } } \section{Methods}{ The descriptions below use "sequences" as a generalization of input sequences and germline sequences. \itemize{ \item \code{method="thresholdedFreq"} A threshold must be supplied to the argument \code{minimumFrequency}. At each position along the length of the consensus sequence, the frequency of each nucleotide/character across sequences is tabulated. The nucleotide/character whose frequency is at least (i.e. \code{>=}) \code{minimumFrequency} becomes the consensus; if there is none, the consensus nucleotide will be \code{"N"}. When there are ties (frequencies of multiple nucleotides/characters are at least \code{minimumFrequency}), this method can be deterministic or stochastic, depending on additional parameters. \itemize{ \item With \code{includeAmbiguous=TRUE}, ties are resolved deterministically by representing ties using ambiguous characters. See "Choosing ambiguous characters" for how ambiguous characters are chosen. \item With \code{breakTiesStochastic=TRUE}, ties are resolved stochastically by randomly picking a character amongst the ties. \item When both \code{TRUE}, \code{includeAmbiguous} takes precedence over \code{breakTiesStochastic}. \item When both \code{FALSE}, the first character from the ties is taken to be the consensus following the order of \code{"A"}, \code{"T"}, \code{"G"}, \code{"C"}, \code{"N"}, \code{"."}, and \code{"-"}. } Below are some examples looking at a single position based on 5 sequences with \code{minimumFrequency=0.6}, \code{includeAmbiguous=FALSE}, and \code{breakTiesStochastic=FALSE}: \itemize{ \item If the sequences have \code{"A"}, \code{"A"}, \code{"A"}, \code{"T"}, \code{"C"}, the consensus will be \code{"A"}, because \code{"A"} has frequency 0.6, which is at least \code{minimumFrequency}. \item If the sequences have \code{"A"}, \code{"A"}, \code{"T"}, \code{"T"}, \code{"C"}, the consensus will be \code{"N"}, because none of \code{"A"}, \code{"T"}, or \code{"C"} has frequency that is at least \code{minimumFrequency}. } \item \code{method="mostCommon"} The most frequent nucleotide/character across sequences at each position along the length of the consensus sequence makes up the consensus. When there are ties (multiple nucleotides/characters with equally maximal frequencies), this method can be deterministic or stochastic, depending on additional parameters. The same rules for breaking ties for \code{method="thresholdedFreq"} apply. Below are some examples looking at a single position based on 5 sequences with \code{includeAmbiguous=FALSE}, and \code{breakTiesStochastic=FALSE}: \itemize{ \item If the sequences have \code{"A"}, \code{"A"}, \code{"T"}, \code{"A"}, \code{"C"}, the consensus will be \code{"A"}. \item If the sequences have \code{"T"}, \code{"T"}, \code{"C"}, \code{"C"}, \code{"G"}, the consensus will be \code{"T"}, because \code{"T"} is before \code{"C"} in the order of \code{"A"}, \code{"T"}, \code{"G"}, \code{"C"}, \code{"N"}, \code{"."}, and \code{"-"}. } \item \code{method="catchAll"} This method returns a consensus sequence capturing most of the information contained in the sequences. Ambiguous characters are used where applicable. See "Choosing ambiguous characters" for how ambiguous characters are chosen. This method is deterministic and does not involve breaking ties. Below are some examples for \code{method="catchAll"} looking at a single position based on 5 sequences: \itemize{ \item If the sequences have \code{"N"}, \code{"N"}, \code{"N"}, \code{"N"}, \code{"N"}, the consensus will be \code{"N"}. \item If the sequences have \code{"N"}, \code{"A"}, \code{"A"}, \code{"A"}, \code{"A"}, the consensus will be \code{"A"}. \item If the sequences have \code{"N"}, \code{"A"}, \code{"G"}, \code{"A"}, \code{"A"}, the consensus will be \code{"R"}. \item If the sequences have \code{"-"}, \code{"-"}, \code{"."}, \code{"."}, \code{"."}, the consensus will be \code{"-"}. \item If the sequences have \code{"-"}, \code{"-"}, \code{"-"}, \code{"-"}, \code{"-"}, the consensus will be \code{"-"}. \item If the sequences have \code{"."}, \code{"."}, \code{"."}, \code{"."}, \code{"."}, the consensus will be \code{"."}. } \item \code{method="mostMutated"} and \code{method="leastMutated"} These methods return the most/least mutated sequence as the consensus sequence. When there are ties (multple sequences have the maximal/minimal mutation frequency), this method can be deterministic or stochastic, depending on additional parameters. \itemize{ \item With \code{breakTiesStochastic=TRUE}, ties are resolved stochastically by randomly picking a sequence out of sequences with the maximal/minimal mutation frequency. \item When \code{breakTiesByColumns} is supplied, ties are resolved deterministically. Column by column, a function is applied on the column and sequences with column value matching the functional value are retained, until ties are resolved or columns run out. In the latter case, the first remaining sequence is taken as the consensus. \item When \code{breakTiesStochastic=TRUE} and \code{breakTiesByColumns} is also supplied, \code{breakTiesStochastic} takes precedence over \code{breakTiesByColumns}. \item When \code{breakTiesStochastic=FALSE} and \code{breakTiesByColumns} is not supplied (i.e. \code{NULL}), the sequence that appears first amongst the ties is taken as the consensus. } } } \section{Choosing ambiguous characters}{ Ambiguous characters may be present in the returned consensuses when using the \code{"catchAll"} method and when using the \code{"thresholdedFreq"} or \code{"mostCommon"} methods with \code{includeAmbiguous=TRUE}. The rules on choosing ambiguous characters are as follows: \itemize{ \item If a position contains only \code{"N"} across sequences, the consensus at that position is \code{"N"}. \item If a position contains one or more of \code{"A"}, \code{"T"}, \code{"G"}, or \code{"C"}, the consensus will be an IUPAC character representing all of the characters present, regardless of whether \code{"N"}, \code{"-"}, or \code{"."} is present. \item If a position contains only \code{"-"} and \code{"."} across sequences, the consensus at thatp osition is taken to be \code{"-"}. \item If a position contains only one of \code{"-"} or \code{"."} across sequences, the consensus at that position is taken to be the character present. } } \section{Cautions}{ \itemize{ \item Note that this function does not perform multiple sequence alignment. As a prerequisite, it is assumed that the sequences in \code{sequenceColumn} and \code{germlineColumn} have been aligned somehow. In the case of immunoglobulin repertoire analysis, this usually means that the sequences are IMGT-gapped. \item When using the \code{"mostMutated"} and \code{"leastMutated"} methods, if you supply both \code{muFreqColumn} and \code{regionDefinition}, it is your responsibility to ensure that the mutation frequency in \code{muFreqColumn} was calculated with sequence lengths restricted to the \strong{same} \code{regionDefinition} you are supplying. Otherwise, the "most/least mutated" sequence you obtain might not be the most/least mutated given the \code{regionDefinition} supplied, because your mutation frequency was based on a \code{regionDefinition} different from the one supplied. \item If you intend to run \code{collapseClones} before building a 5-mer targeting model, you \strong{must} choose parameters such that your collapsed clonal consensuses do \strong{not} include ambiguous characters. This is because the targeting model functions do NOT support ambiguous characters in their inputs. } } \examples{ # Subset example data data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE \%in\% c("IgA", "IgG") & SAMPLE == "+7d" & CLONE \%in\% c("3100", "3141", "3184")) # thresholdedFreq method, resolving ties deterministically without using ambiguous characters clones <- collapseClones(db, method="thresholdedFreq", minimumFrequency=0.6, includeAmbiguous=FALSE, breakTiesStochastic=FALSE) # mostCommon method, resolving ties deterministically using ambiguous characters clones <- collapseClones(db, method="mostCommon", includeAmbiguous=TRUE, breakTiesStochastic=FALSE) # Make a copy of db that has a mutation frequency column db2 <- observedMutations(db, frequency=TRUE, combine=TRUE) # mostMutated method, resolving ties stochastically clones <- collapseClones(db2, method="mostMutated", muFreqColumn="MU_FREQ", breakTiesStochastic=TRUE, breakTiesByColumns=NULL) # mostMutated method, resolving ties deterministically using additional columns clones <- collapseClones(db2, method="mostMutated", muFreqColumn="MU_FREQ", breakTiesStochastic=FALSE, breakTiesByColumns=list(c("DUPCOUNT"), c(max))) # Build consensus for V segment only # Capture all nucleotide variations using ambiguous characters clones <- collapseClones(db, method="catchAll", regionDefinition=IMGT_V) # Return the same number of rows as the input clones <- collapseClones(db, method="mostCommon", expandedDb=TRUE) } \seealso{ See \link{IMGT_SCHEMES} for a set of predefined \link{RegionDefinition} objects. } shazam/man/slideWindowSeq.Rd0000644000176200001440000000340113575255270015551 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MutationProfiling.R \name{slideWindowSeq} \alias{slideWindowSeq} \title{Sliding window approach towards filtering a single sequence} \usage{ slideWindowSeq(inputSeq, germlineSeq, mutThresh, windowSize) } \arguments{ \item{inputSeq}{input sequence.} \item{germlineSeq}{germline sequence.} \item{mutThresh}{threshold on the number of mutations in \code{windowSize} consecutive nucleotides. Must be between 1 and \code{windowSize} inclusive.} \item{windowSize}{length of consecutive nucleotides. Must be at least 2.} } \value{ \code{TRUE} if there are equal to or more than \code{mutThresh} number of mutations in any window of \code{windowSize} consecutive nucleotides (i.e. the sequence should be filtered); \code{FALSE} if otherwise. } \description{ \code{slideWindowSeq} determines whether an input sequence contains equal to or more than a given number of mutations in a given length of consecutive nucleotides (a "window") when compared to a germline sequence. } \examples{ # Use an entry in the example data for input and germline sequence data(ExampleDb, package="alakazam") in_seq <- ExampleDb[100, "SEQUENCE_IMGT"] germ_seq <- ExampleDb[100, "GERMLINE_IMGT_D_MASK"] # Determine if in_seq has 6 or more mutations in 10 consecutive nucleotides slideWindowSeq(inputSeq=in_seq, germlineSeq=germ_seq, mutThresh=6, windowSize=10) } \seealso{ \link{calcObservedMutations} is called by \code{slideWindowSeq} to identify observed mutations. See \link{slideWindowDb} for applying the sliding window approach on a \code{data.frame}. See \link{slideWindowTune} for parameter tuning for \code{mutThresh} and \code{windowSize}. } shazam/man/plotGmmThreshold.Rd0000644000176200001440000000442613575260615016113 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DistToNearest.R \name{plotGmmThreshold} \alias{plotGmmThreshold} \title{Plot findThreshold results for the gmm method} \usage{ plotGmmThreshold( data, cross = NULL, xmin = NULL, xmax = NULL, breaks = NULL, binwidth = NULL, title = NULL, size = 1, silent = FALSE, ... ) } \arguments{ \item{data}{\link{GmmThreshold} object output by the \code{"gmm"} method of \link{findThreshold}.} \item{cross}{numeric vector of distances from \link{distToNearest} to draw as a histogram below the \code{data} histogram for comparison purposes.} \item{xmin}{minimum limit for plotting the x-axis. If \code{NULL} the limit will be set automatically.} \item{xmax}{maximum limit for plotting the x-axis. If \code{NULL} the limit will be set automatically.} \item{breaks}{number of breaks to show on the x-axis. If \code{NULL} the breaks will be set automatically.} \item{binwidth}{binwidth for the histogram. If \code{NULL} the binwidth will be set automatically.} \item{title}{string defining the plot title.} \item{size}{numeric value for lines in the plot.} \item{silent}{if \code{TRUE} do not draw the plot and just return the ggplot2 object; if \code{FALSE} draw the plot.} \item{...}{additional arguments to pass to ggplot2::theme.} } \value{ A ggplot object defining the plot. } \description{ \code{plotGmmThreshold} plots the results from \code{"gmm"} method of \link{findThreshold}, including the Guassian distributions, input nearest neighbor distance histogram, and threshold selected. } \examples{ \donttest{ # Subset example data to one sample as a demo data(ExampleDb, package="alakazam") db <- subset(ExampleDb, SAMPLE == "-1h") # Use nucleotide Hamming distance and normalize by junction length db <- distToNearest(db, model="ham", normalize="len", nproc=1) # To find the threshold cut, call findThreshold function for "gmm" method. output <- findThreshold(db$DIST_NEAREST, method="gmm", model="norm-norm", cutoff="opt") print(output) # Plot results plotGmmThreshold(output, binwidth=0.02) } } \seealso{ See \link{GmmThreshold} for the the input object definition and \link{findThreshold} for generating the input object. See \link{distToNearest} calculating nearest neighbor distances. } shazam/man/shazam.Rd0000644000176200001440000001261013575260615014074 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Shazam.R \docType{package} \name{shazam} \alias{shazam} \title{The shazam package} \description{ Dramatic improvements in high-throughput sequencing technologies now enable large-scale characterization of Ig repertoires, defined as the collection of transmembrane antigen-receptor proteins located on the surface of T and B lymphocytes. The \code{shazam} package provides tools for advanced analysis of somatic hypermutation (SHM) in immunoglobulin (Ig) sequences. The key functions in \code{shazam}, broken down topic, are described below. } \section{Mutational profiling}{ \code{shazam} provides tools to quantify the extent and nature of SHM within full length V(D)J sequences as well as sub-regions (eg, FWR and CDR). Quantification of expected mutational loaded, under specific SHM targeting models, can also be performed along with model driven simulations of SHM. \itemize{ \item \link{collapseClones}: Build clonal consensus sequences. \item \link{consensusSequence}: Build a single consensus sequence. \item \link{observedMutations}: Compute observed mutation counts and frequencies. \item \link{expectedMutations}: Compute expected mutation frequencies. \item \link{shmulateSeq}: Simulate mutations in a single sequence. \item \link{shmulateTree}: Simulate mutations over a lineage tree. } } \section{SHM targeting models}{ Computational models and analyses of SHM have separated the process into two independent components: \enumerate{ \item A mutability model that defines where mutations occur. \item A nucleotide substitution model that defines the resulting mutation. } Collectively these are what form the targeting model of SHM. \code{shazam} provides empirically derived targeting models for both humans and mice, along with tools to build these mutability and substitution models from data. \itemize{ \item \link{createTargetingModel}: Build a 5-mer targeting model. \item \link{plotMutability}: Plot 5-mer mutability rates. \item \link{HH_S5F}: Human 5-mer SHM targeting model. \item \link{MK_RS5NF}: Mouse 5-mer SHM targeting model. } } \section{Quantification of selection pressure}{ Bayesian Estimation of Antigen-driven Selection in Ig Sequences is a novel method for quantifying antigen-driven selection in high-throughput Ig sequence data. Targeting models created using \code{shazam} can be used to estimate the null distribution of expected mutation frequencies used by BASELINe, providing measures of selection pressure informed by known AID targeting biases. \itemize{ \item \link{calcBaseline}: Calculate the BASELINe probability density functions (PDFs). \item \link{groupBaseline}: Combine PDFs from sequences grouped by biological or experimental relevance. \item \link{summarizeBaseline}: Compute summary statistics from BASELINe PDFs. \item \link{testBaseline}: Perform significance testing for the difference between BASELINe PDFs. \item \link{plotBaselineDensity}: Plot the probability density functions resulting from selection analysis. \item \link{plotBaselineSummary}: Plot summary stastistics resulting from selection analysis. } } \section{Mutational distance calculation}{ \code{shazam} provides tools to compute evolutionary distances between sequences or groups of sequences, which can leverage SHM targeting models. This information is particularly useful in understanding and defining clonal relationships. \itemize{ \item \link{findThreshold}: Identify clonal assignment threshold based on distances to nearest neighbors. \item \link{distToNearest}: Tune clonal assignment thresholds by calculating distances to nearest neighbors. \item \link{calcTargetingDistance}: Construct a nucleotide distance matrix from a 5-mer targeting model. } } \references{ \enumerate{ \item Hershberg U, et al. Improved methods for detecting selection by mutation analysis of Ig V region sequences. Int Immunol. 2008 20(5):683-94. \item Uduman M, et al. Detecting selection in immunoglobulin sequences. Nucleic Acids Res. 2011 39(Web Server issue):W499-504. (Corrections at http://selection.med.yale.edu/baseline/correction/) \item Yaari G, et al. Quantifying selection in high-throughput immunoglobulin sequencing data sets. Nucleic Acids Res. 2012 40(17):e134. \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based on synonymous mutations from high-throughput immunoglobulin sequencing data. Front Immunol. 2013 4:358. \item Cui A, Di Niro R, Vander Heiden J, Briggs A, Adams K, Gilbert T, O'Connor K, Vigneault F, Shlomchik M and Kleinstein S (2016). A Model of Somatic Hypermutation Targeting in Mice Based on High-Throughput Ig Sequencing Data. The Journal of Immunology, 197(9), 3566-3574. } } shazam/man/minNumMutationsTune.Rd0000644000176200001440000000617313575255270016624 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \name{minNumMutationsTune} \alias{minNumMutationsTune} \title{Parameter tuning for minNumMutations} \usage{ minNumMutationsTune(subCount, minNumMutationsRange) } \arguments{ \item{subCount}{\code{data.frame} returned by \link{createSubstitutionMatrix} with \code{numMutationsOnly=TRUE}.} \item{minNumMutationsRange}{a number or a vector indicating the value or range of values of \code{minNumMutations} to try.} } \value{ A 3xn \code{matrix}, where n is the number of trial values of \code{minNumMutations} supplied in \code{minNumMutationsRange}. Each column corresponds to a value in \code{minNumMutationsRange}. The rows correspond to the number of 5-mers for which substitution rates would be computed directly using the 5-mer itself (\code{"5mer"}), using its inner 3-mer (\code{"3mer"}), and using the central 1-mer (\code{"1mer"}), respectively. } \description{ \code{minNumMutationsTune} helps with picking a threshold value for \code{minNumMutations} in \link{createSubstitutionMatrix} by tabulating the number of 5-mers for which substitution rates would be computed directly or inferred at various threshold values. } \details{ At a given threshold value of \code{minNumMutations}, for a given 5-mer, if the total number of mutations is greater than the threshold and there are mutations to every other base, substitution rates are computed directly for the 5-mer using its mutations. Otherwise, mutations from 5-mers with the same inner 3-mer as the 5-mer of interest are aggregated. If the number of such mutations is greater than the threshold and there are mutations to every other base, these mutations are used for inferring the substitution rates for the 5-mer of interest; if not, mutations from all 5-mers with the same center nucleotide are aggregated and used for inferring the substitution rates for the 5-mer of interest (i.e. the 1-mer model). } \examples{ # Subset example data to one isotype and sample as a demo data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") # Count the number of mutations per 5-mer subCount <- createSubstitutionMatrix(db, model="S", multipleMutation="independent", returnModel="5mer", numMutationsOnly=TRUE) # Tune minNumMutations minNumMutationsTune(subCount, seq(from=10, to=100, by=10)) } \references{ \enumerate{ \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based on synonymous mutations from high-throughput immunoglobulin sequencing data. Front Immunol. 2013 4(November):358. } } \seealso{ See argument \code{numMutationsOnly} in \link{createSubstitutionMatrix} for generating the required input \code{data.frame} \code{subCount}. See argument \code{minNumMutations} in \link{createSubstitutionMatrix} for what it does. } shazam/man/makeDegenerate5merMut.Rd0000644000176200001440000000405013445225760016766 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \name{makeDegenerate5merMut} \alias{makeDegenerate5merMut} \title{Make a degenerate 5-mer mutability model based on a 1-mer mutability model} \usage{ makeDegenerate5merMut(mut1mer, extended = FALSE) } \arguments{ \item{mut1mer}{a named vector of length 4 containing (normalized) mutability rates. Names should correspond to nucleotides, which should include "A", "T", "G", and "C" (case-insensitive).} \item{extended}{whether to return the unextended (\code{extended=FALSE}) or extended (\code{extended=TRUE}) 5-mer mutability model. Default is \code{FALSE}.} } \value{ For \code{extended=FALSE}, a vector of length 1024. The vector returned is normalized. For \code{extended=TRUE}, a vector of length 3125. } \description{ \code{makeDegenerate5merMut} populates mutability rates from a 1-mer mutability model into 5-mers with corresponding central 1-mers. } \details{ As a concrete example, consider a 1-mer mutability model in which mutability rates of "A", "T", "G", and "C" are, respectively, 0.14, 0.23, 0.31, and 0.32. In the resultant degenerate 5-mer mutability model, all the 5-mers that have an "A" as their central 1-mer would have mutability rate of 0.14/256, where 256 is the number of such 5-mers. When \code{extended=TRUE}, \code{extendMutabilityMatrix} is called to extend the mutability vector of length 1024 into a vector of length 3125. } \examples{ # Make a degenerate 5-mer model (length of 1024) based on a 1-mer model example1merMut <- c(A=0.2, T=0.1, C=0.4, G=0.3) degenerate5merMut <- makeDegenerate5merMut(mut1mer = example1merMut) # Look at a few 5-mers degenerate5merMut[c("AAAAT", "AACAT", "AAGAT", "AATAT")] # Normalized sum(degenerate5merMut) } \seealso{ See \link{makeAverage1merMut} for making a 1-mer mutability model by taking the average of a 5-mer mutability model. See \link{extendMutabilityMatrix} for extending the mutability vector. } shazam/man/calculateMutability.Rd0000644000176200001440000000200113575260615016603 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \name{calculateMutability} \alias{calculateMutability} \title{Calculate total mutability} \usage{ calculateMutability(sequences, model = HH_S5F, progress = FALSE) } \arguments{ \item{sequences}{character vector of sequences.} \item{model}{\link{TargetingModel} object with mutation likelihood information.} \item{progress}{if \code{TRUE} print a progress bar.} } \value{ Numeric vector with a total mutability score for each sequence. } \description{ \code{calculateMutability} calculates the total (summed) mutability for a set of sequences based on a 5-mer nucleotide mutability model. } \examples{ \donttest{ # Subset example data to one isotype and sample as a demo data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") # Calculate mutability of germline sequences using \link{HH_S5F} model mutability <- calculateMutability(sequences=db$GERMLINE_IMGT_D_MASK, model=HH_S5F) } } shazam/man/slideWindowTunePlot.Rd0000644000176200001440000001072113575260615016575 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MutationProfiling.R \name{slideWindowTunePlot} \alias{slideWindowTunePlot} \title{Visualize parameter tuning for sliding window approach} \usage{ slideWindowTunePlot( tuneList, plotFiltered = TRUE, percentage = FALSE, jitter.x = FALSE, jitter.x.amt = 0.1, jitter.y = FALSE, jitter.y.amt = 0.1, pchs = 1, ltys = 2, cols = 1, plotLegend = TRUE, legendPos = "topright", legendHoriz = FALSE, legendCex = 1, title = NULL ) } \arguments{ \item{tuneList}{a list of logical matrices returned by \link{slideWindowTune}.} \item{plotFiltered}{whether to plot the number of filtered sequences (as opposed to the number of remaining sequences). Default is \code{TRUE}.} \item{percentage}{whether to plot on the y-axis the percentage of filtered sequences (as opposed to the absolute number). Default is \code{FALSE}.} \item{jitter.x}{whether to jitter x-axis values. Default is \code{FALSE}.} \item{jitter.x.amt}{amount of jittering to be applied on x-axis values if \code{jitter.x=TRUE}. Default is 0.1.} \item{jitter.y}{whether to jitter y-axis values. Default is \code{FALSE}.} \item{jitter.y.amt}{amount of jittering to be applied on y-axis values if \code{jitter.y=TRUE}. Default is 0.1.} \item{pchs}{point types to pass on to \link{plot}.} \item{ltys}{line types to pass on to \link{plot}.} \item{cols}{colors to pass on to \link{plot}.} \item{plotLegend}{whether to plot legend. Default is \code{TRUE}.} \item{legendPos}{position of legend to pass on to \link{legend}. Can be either a numeric vector specifying x-y coordinates, or one of \code{"topright"}, \code{"center"}, etc. Default is \code{"topright"}.} \item{legendHoriz}{whether to make legend horizontal. Default is \code{FALSE}.} \item{legendCex}{numeric values by which legend should be magnified relative to 1.} \item{title}{plot main title. Default is NULL (no title)} } \description{ Visualize results from \link{slideWindowTune} } \details{ For each \code{windowSize}, the numbers of sequences filtered or remaining after applying the sliding window approach are plotted on the y-axis against thresholds on the number of mutations in a window on the x-axis. When plotting, a user-defined \code{amount} of jittering can be applied on values plotted on either axis or both axes via adjusting \code{jitter.x}, \code{jitter.y}, \code{jitter.x.amt} and \code{jitter.y.amt}. This may be help with visually distinguishing lines for different window sizes in case they are very close or identical to each other. If plotting percentages (\code{percentage=TRUE}) and using jittering on the y-axis values (\code{jitter.y=TRUE}), it is strongly recommended that \code{jitter.y.amt} be set very small (e.g. 0.01). \code{NA} for a combination of \code{mutThresh} and \code{windowSize} where \code{mutThresh} is greater than \code{windowSize} will not be plotted. } \examples{ # Use an entry in the example data for input and germline sequence data(ExampleDb, package="alakazam") # Try out thresholds of 2-4 mutations in window sizes of 3-5 nucleotides # on a subset of ExampleDb tuneList <- slideWindowTune(db = ExampleDb[1:10, ], mutThreshRange = 2:4, windowSizeRange = 3:5, verbose = FALSE) # Visualize # Plot numbers of sequences filtered without jittering y-axis values slideWindowTunePlot(tuneList, pchs=1:3, ltys=1:3, cols=1:3, plotFiltered=TRUE, jitter.y=FALSE) # Notice that some of the lines overlap # Jittering could help slideWindowTunePlot(tuneList, pchs=1:3, ltys=1:3, cols=1:3, plotFiltered=TRUE, jitter.y=TRUE) # Plot numbers of sequences remaining instead of filtered slideWindowTunePlot(tuneList, pchs=1:3, ltys=1:3, cols=1:3, plotFiltered=FALSE, jitter.y=TRUE, legendPos="bottomright") # Plot percentages of sequences filtered with a tiny amount of jittering slideWindowTunePlot(tuneList, pchs=1:3, ltys=1:3, cols=1:3, plotFiltered=TRUE, percentage=TRUE, jitter.y=TRUE, jitter.y.amt=0.01) } \seealso{ See \link{slideWindowTune} for how to get \code{tuneList}. See \link{jitter} for use of \code{amount} of jittering. } shazam/man/createMutabilityMatrix.Rd0000644000176200001440000001050313575260615017304 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \name{createMutabilityMatrix} \alias{createMutabilityMatrix} \title{Builds a mutability model} \usage{ createMutabilityMatrix( db, substitutionModel, model = c("S", "RS"), sequenceColumn = "SEQUENCE_IMGT", germlineColumn = "GERMLINE_IMGT_D_MASK", vCallColumn = "V_CALL", multipleMutation = c("independent", "ignore"), minNumSeqMutations = 500, numSeqMutationsOnly = FALSE, returnSource = FALSE ) } \arguments{ \item{db}{data.frame containing sequence data.} \item{substitutionModel}{matrix of 5-mer substitution rates built by \link{createSubstitutionMatrix}. Note, this model will only impact mutability scores when \code{model="S"} (using only silent mutations).} \item{model}{type of model to create. The default model, "S", builds a model by counting only silent mutations. \code{model="S"} should be used for data that includes functional sequences. Setting \code{model="RS"} creates a model by counting both replacement and silent mutations and may be used on fully non-functional sequence data sets.} \item{sequenceColumn}{name of the column containing IMGT-gapped sample sequences.} \item{germlineColumn}{name of the column containing IMGT-gapped germline sequences.} \item{vCallColumn}{name of the column containing the V-segment allele call.} \item{multipleMutation}{string specifying how to handle multiple mutations occuring within the same 5-mer. If \code{"independent"} then multiple mutations within the same 5-mer are counted indepedently. If \code{"ignore"} then 5-mers with multiple mutations are excluded from the total mutation tally.} \item{minNumSeqMutations}{minimum number of mutations in sequences containing each 5-mer to compute the mutability rates. If the number is smaller than this threshold, the mutability for the 5-mer will be inferred. Default is 500. Not required if \code{numSeqMutationsOnly=TRUE}.} \item{numSeqMutationsOnly}{when \code{TRUE}, return only a vector counting the number of observed mutations in sequences containing each 5-mer. This option can be used for parameter tuning for \code{minNumSeqMutations} during preliminary analysis using \link{minNumSeqMutationsTune}. Default is \code{FALSE}.} \item{returnSource}{return the sources of 5-mer mutabilities (measured vs. inferred). Default is \code{FALSE}.} } \value{ When \code{numSeqMutationsOnly} is \code{FALSE}, a named numeric vector of 1024 normalized mutability rates for each 5-mer motif with names defining the 5-mer nucleotide sequence. When \code{numSeqMutationsOnly} is \code{TRUE}, a named numeric vector of length 1024 counting the number of observed mutations in sequences containing each 5-mer. } \description{ \code{createMutabilityMatrix} builds a 5-mer nucleotide mutability model by counting the number of mutations occuring in the center position for all 5-mer motifs. } \details{ \strong{Caution: The targeting model functions do NOT support ambiguous characters in their inputs. You MUST make sure that your input and germline sequences do NOT contain ambiguous characters (especially if they are clonal consensuses returned from \code{collapseClones}).} } \examples{ \donttest{ # Subset example data to one isotype and sample as a demo data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") # Create model using only silent mutations sub_model <- createSubstitutionMatrix(db, model="S") mut_model <- createMutabilityMatrix(db, sub_model, model="S", minNumSeqMutations=200, numSeqMutationsOnly=FALSE) # Count the number of mutations in sequences containing each 5-mer mut_count <- createMutabilityMatrix(db, sub_model, model="S", numSeqMutationsOnly=TRUE) } } \references{ \enumerate{ \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based on synonymous mutations from high-throughput immunoglobulin sequencing data. Front Immunol. 2013 4(November):358. } } \seealso{ \link{extendMutabilityMatrix}, \link{createSubstitutionMatrix}, \link{createTargetingMatrix}, \link{createTargetingModel}, \link{minNumSeqMutationsTune} } shazam/man/summarizeBaseline.Rd0000644000176200001440000000547513575260615016303 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Baseline.R \name{summarizeBaseline} \alias{summarizeBaseline} \title{Calculate BASELINe summary statistics} \usage{ summarizeBaseline(baseline, returnType = c("baseline", "df"), nproc = 1) } \arguments{ \item{baseline}{\code{Baseline} object returned by \link{calcBaseline} containing annotations and BASELINe posterior probability density functions (PDFs) for each sequence.} \item{returnType}{One of \code{c("baseline", "df")} defining whether to return a \code{Baseline} object ("baseline") with an updated \code{stats} slot or a data.frame ("df") of summary statistics.} \item{nproc}{number of cores to distribute the operation over. If \code{nproc} = 0 then the \code{cluster} has already been set and will not be reset.} } \value{ Either a modified \code{Baseline} object or data.frame containing the mean BASELINe selection strength, its 95\% confidence intervals, and a p-value for the presence of selection. } \description{ \code{summarizeBaseline} calculates BASELINe statistics such as the mean selection strength (mean Sigma), the 95\% confidence intervals and p-values for the presence of selection. } \details{ The returned p-value can be either positive or negative. Its magnitude (without the sign) should be interpreted as per normal. Its sign indicates the direction of the selection detected. A positive p-value indicates positive selection, whereas a negative p-value indicates negative selection. } \examples{ \donttest{ # Subset example data data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE == "IgG") # Collapse clones db <- collapseClones(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", method="thresholdedFreq", minimumFrequency=0.6, includeAmbiguous=FALSE, breakTiesStochastic=FALSE) # Calculate BASELINe baseline <- calcBaseline(db, sequenceColumn="CLONAL_SEQUENCE", germlineColumn="CLONAL_GERMLINE", testStatistic="focused", regionDefinition=IMGT_V, targetingModel=HH_S5F, nproc = 1) # Grouping the PDFs by the sample annotation grouped <- groupBaseline(baseline, groupBy="SAMPLE") # Get a data.frame of the summary statistics stats <- summarizeBaseline(grouped, returnType="df") } } \references{ \enumerate{ \item Uduman M, et al. Detecting selection in immunoglobulin sequences. Nucleic Acids Res. 2011 39(Web Server issue):W499-504. } } \seealso{ See \link{calcBaseline} for generating \code{Baseline} objects and \link{groupBaseline} for convolving groups of BASELINe PDFs. } shazam/man/writeTargetingDistance.Rd0000644000176200001440000000210613445225760017260 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \name{writeTargetingDistance} \alias{writeTargetingDistance} \title{Write targeting model distances to a file} \usage{ writeTargetingDistance(model, file) } \arguments{ \item{model}{\link{TargetingModel} object with mutation likelihood information.} \item{file}{name of file to write.} } \description{ \code{writeTargetingDistance} writes a 5-mer targeting distance matrix to a tab-delimited file. } \details{ The targeting distance write as a tab-delimited 5x3125 matrix. Rows define the mutated nucleotide at the center of each 5-mer, one of \code{c("A", "C", "G", "T", "N")}, and columns define the complete 5-mer of the unmutated nucleotide sequence. \code{NA} values in the distance matrix are replaced with distance 0. } \examples{ \dontrun{ # Write HS5F targeting model to working directory as hs5f.tab writeTargetingDistance(HH_S5F, "hh_s5f.tsv") } } \seealso{ Takes as input a \link{TargetingModel} object and calculates distances using \link{calcTargetingDistance}. } shazam/man/findThreshold.Rd0000644000176200001440000001326613575260615015416 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DistToNearest.R \name{findThreshold} \alias{findThreshold} \title{Find distance threshold} \usage{ findThreshold( distances, method = c("density", "gmm"), edge = 0.9, cross = NULL, subsample = NULL, model = c("gamma-gamma", "gamma-norm", "norm-gamma", "norm-norm"), cutoff = c("optimal", "intersect", "user"), sen = NULL, spc = NULL, progress = FALSE ) } \arguments{ \item{distances}{numeric vector containing nearest neighbor distances.} \item{method}{string defining the method to use for determining the optimal threshold. One of \code{"gmm"} or \code{"density"}. See Details for methodological descriptions.} \item{edge}{upper range as a fraction of the data density to rule initialization of Gaussian fit parameters. Default value is 90% of the entries (0.9). Applies only when \code{method="density"}. .} \item{cross}{supplementary nearest neighbor distance vector output from \link{distToNearest} for initialization of the Gaussian fit parameters. Applies only when \code{method="gmm"}.} \item{subsample}{maximum number of distances to subsample to before threshold detection.} \item{model}{allows the user to choose among four possible combinations of fitting curves: \code{"norm-norm"}, \code{"norm-gamma"}, \code{"gamma-norm"}, and \code{"gamma-gamma"}. Applies only when \code{method="gmm"}.} \item{cutoff}{method to use for threshold selection: the optimal threshold \code{"opt"}, the intersection point of the two fitted curves \code{"intersect"}, or a value defined by user for one of the sensitivity or specificity \code{"user"}. Applies only when \code{method="gmm"}.} \item{sen}{sensitivity required. Applies only when \code{method="gmm"} and \code{cutoff="user"}.} \item{spc}{specificity required. Applies only when \code{method="gmm"} and \code{cutoff="user"}.} \item{progress}{if \code{TRUE} print a progress bar.} } \value{ \itemize{ \item \code{"gmm"} method: Returns a \link{GmmThreshold} object including the \code{threshold} and the function fit parameters, i.e. mixing weight, mean, and standard deviation of a Normal distribution, or mixing weight, shape and scale of a Gamma distribution. \item \code{"density"} method: Returns a \link{DensityThreshold} object including the optimum \code{threshold} and the density fit parameters. } } \description{ \code{findThreshold} automtically determines an optimal threshold for clonal assignment of Ig sequences using a vector of nearest neighbor distances. It provides two alternative methods using either a Gamma/Guassian Mixture Model fit (\code{method="gmm"}) or kernel density fit (\code{method="density"}). } \details{ \itemize{ \item \code{"gmm"}: Performs a maximum-likelihood fitting procedure, for learning the parameters of two mixture univariate, either Gamma or Gaussian, distributions which fit the bimodal distribution entries. Retrieving the fit parameters, it then calculates the optimum threshold \code{method="optimal"}, where the average of the sensitivity plus specificity reaches its maximum. In addition, the \code{findThreshold} function is also able to calculate the intersection point (\code{method="intersect"}) of the two fitted curves and allows the user to invoke its value as the cut-off point, instead of optimal point. \item \code{"density"}: Fits a binned approximation to the ordinary kernel density estimate to the nearest neighbor distances after determining the optimal bandwidth for the density estimate via least-squares cross-validation of the 4th derivative of the kernel density estimator. The optimal threshold is set as the minimum value in the valley in the density estimate between the two modes of the distribution. } } \note{ Visually inspecting the resulting distribution fits is strongly recommended when using either fitting method. Empirical observations imply that the bimodality of the distance-to-nearest distribution is detectable for a minimum of 1,000 distances. Larger numbers of distances will improve the fitting procedure, although this can come at the expense of higher computational demands. } \examples{ \donttest{ # Subset example data to one sample as a demo data(ExampleDb, package="alakazam") db <- subset(ExampleDb, SAMPLE == "-1h") # Use nucleotide Hamming distance and normalize by junction length db <- distToNearest(db, model="ham", normalize="len", nproc=1) # Find threshold using the "gmm" method with optimal threshold output <- findThreshold(db$DIST_NEAREST, method="gmm", model="gamma-gamma", cutoff="opt") plot(output, binwidth=0.02, title=paste0(output@model, " loglk=", output@loglk)) print(output) # Find threshold using the "gmm" method with user defined specificity output <- findThreshold(db$DIST_NEAREST, method="gmm", model="gamma-gamma", cutoff="user", spc=0.99) plot(output, binwidth=0.02, title=paste0(output@model, " loglk=", output@loglk)) print(output) # Find threshold using the "density" method and plot the results output <- findThreshold(db$DIST_NEAREST, method="density") plot(output) print(output) } } \seealso{ See \link{distToNearest} for generating the nearest neighbor distance vectors. See \link{plotGmmThreshold} and \link{plotDensityThreshold} for plotting output. } shazam/man/shmulateTree.Rd0000644000176200001440000000617413575260615015263 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Shmulate.R \name{shmulateTree} \alias{shmulateTree} \title{Simulate mutations in a lineage tree} \usage{ shmulateTree( sequence, graph, targetingModel = HH_S5F, field = NULL, exclude = NULL, junctionWeight = NULL, start = 1, end = nchar(sequence) ) } \arguments{ \item{sequence}{string defining the MRCA sequence to seed mutations from.} \item{graph}{\code{igraph} object defining the seed lineage tree, with vertex annotations, whose edges are to be recreated.} \item{targetingModel}{5-mer \link{TargetingModel} object to be used for computing probabilities of mutations at each position. Defaults to \link{HH_S5F}.} \item{field}{annotation to use for both unweighted path length exclusion and consideration as the MRCA node. If \code{NULL} do not exclude any nodes.} \item{exclude}{vector of annotation values in \code{field} to exclude from potential MRCA set. If \code{NULL} do not exclude any nodes. Has no effect if \code{field=NULL}.} \item{junctionWeight}{fraction of the nucleotide sequence that is within the junction region. When specified this adds a proportional number of mutations to the immediate offspring nodes of the MRCA. Requires a value between 0 and 1. If \code{NULL} then edge weights are unmodified from the input \code{graph}.} \item{start}{Initial position in \code{sequence} where mutations can be introduced. Default: 1} \item{end}{Last position in \code{sequence} where mutations can be introduced. Default: last position (sequence length).} } \value{ A \code{data.frame} of simulated sequences with columns: \itemize{ \item \code{NAME}: name of the corresponding node in the input \code{graph}. \item \code{SEQUENCE}: mutated sequence. \item \code{DISTANCE}: Hamming distance of the mutated sequence from the seed \code{sequence}. } } \description{ \code{shmulateTree} returns a set of simulated sequences generated from an input sequence and a lineage tree. The input sequence is used to replace the most recent common ancestor (MRCA) node of the \code{igraph} object defining the lineage tree. Sequences are then simulated with mutations corresponding to edge weights in the tree. Sequences will not be generated for groups of nodes that are specified to be excluded. } \examples{ # Load example lineage and define example MRCA data(ExampleTrees, package="alakazam") graph <- ExampleTrees[[17]] sequence <- "NGATCTGACGACACGGCCGTGTATTACTGTGCGAGAGATAGTTTA" # Simulate using the default human 5-mer targeting model shmulateTree(sequence, graph) # Simulate using the mouse 5-mer targeting model # Exclude nodes without a sample identifier # Add 20\% mutation rate to the immediate offsprings of the MRCA shmulateTree(sequence, graph, targetingModel=MK_RS5NF, field="SAMPLE", exclude=NA, junctionWeight=0.2) } \seealso{ See \link{shmulateSeq} for imposing mutations on a single sequence. See \link{HH_S5F} and \link{MK_RS5NF} for predefined \link{TargetingModel} objects. } shazam/man/minNumSeqMutationsTune.Rd0000644000176200001440000000545713575255270017301 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \name{minNumSeqMutationsTune} \alias{minNumSeqMutationsTune} \title{Parameter tuning for minNumSeqMutations} \usage{ minNumSeqMutationsTune(mutCount, minNumSeqMutationsRange) } \arguments{ \item{mutCount}{a \code{vector} of length 1024 returned by \link{createMutabilityMatrix} with \code{numSeqMutationsOnly=TRUE}.} \item{minNumSeqMutationsRange}{a number or a vector indicating the value or the range of values of \code{minNumSeqMutations} to try.} } \value{ A 2xn \code{matrix}, where n is the number of trial values of \code{minNumSeqMutations} supplied in \code{minNumSeqMutationsRange}. Each column corresponds to a value in \code{minNumSeqMutationsRange}. The rows correspond to the number of 5-mers for which mutability would be computed directly (\code{"measured"}) and inferred (\code{"inferred"}), respectively. } \description{ \code{minNumSeqMutationsTune} helps with picking a threshold value for \code{minNumSeqMutations} in \link{createMutabilityMatrix} by tabulating the number of 5-mers for which mutability would be computed directly or inferred at various threshold values. } \details{ At a given threshold value of \code{minNumSeqMutations}, for a given 5-mer, if the total number of mutations is greater than the threshold, mutability is computed directly. Otherwise, mutability is inferred. } \examples{ \donttest{ # Subset example data to one isotype and sample as a demo data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") # Create model using only silent mutations sub <- createSubstitutionMatrix(db, model="S", multipleMutation="independent", returnModel="5mer", numMutationsOnly=FALSE, minNumMutations=20) # Count the number of mutations in sequences containing each 5-mer mutCount <- createMutabilityMatrix(db, substitutionModel = sub, model="S", multipleMutation="independent", numSeqMutationsOnly=TRUE) # Tune minNumSeqMutations minNumSeqMutationsTune(mutCount, seq(from=100, to=300, by=50)) } } \references{ \enumerate{ \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based on synonymous mutations from high-throughput immunoglobulin sequencing data. Front Immunol. 2013 4(November):358. } } \seealso{ See argument \code{numSeqMutationsOnly} in \link{createMutabilityMatrix} for generating the required input \code{vector} \code{mutCount}. See argument \code{minNumSeqMutations} in \link{createMutabilityMatrix} for what it does. } shazam/man/HH_S1F.Rd0000644000176200001440000000203013445225760013552 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \docType{data} \name{HH_S1F} \alias{HH_S1F} \title{Human heavy chain, silent, 1-mer, functional substitution model.} \format{A 4x4 matrix of nucleotide substitution rates. The rates are normalized, therefore each row sums up to 1.} \usage{ HH_S1F } \description{ 1-mer substitution model of somatic hypermutation based on analysis of silent mutations in functional heavy chain Ig sequences from Homo sapiens. } \note{ \code{HH_S1F} replaces \code{HS1FDistance} in versions of SHazaM prior to 0.1.5. } \references{ \enumerate{ \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based on synonymous mutations from high-throughput immunoglobulin sequencing data. Front Immunol. 2013 4(November):358. } } \seealso{ See \link{HKL_S1F} for the human light chain 1-mer substitution model and \link{MK_RS1NF} for the mouse light chain 1-mer substitution model. } \keyword{datasets} shazam/man/MK_RS1NF.Rd0000644000176200001440000000222513445225760014030 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \docType{data} \name{MK_RS1NF} \alias{MK_RS1NF} \title{Mouse kappa chain, replacement and silent, 1-mer, non-functional substitution model.} \format{A 4x4 matrix of nucleotide substitution rates. The rates are normalized, therefore each row sums up to 1.} \usage{ MK_RS1NF } \description{ 1-mer substitution model of somatic hypermutation based on analysis of replacement and silent mutations in non-functional kappa light chain Ig sequences from NP-immunized Mus musculus. } \note{ \code{MK_RS1NF} replaces \code{M1NDistance} from versions of SHazaM prior to 0.1.5. } \references{ \enumerate{ \item Cui A, Di Niro R, Vander Heiden J, Briggs A, Adams K, Gilbert T, O'Connor K, Vigneault F, Shlomchik M and Kleinstein S (2016). A Model of Somatic Hypermutation Targeting in Mice Based on High-Throughput Ig Sequencing Data. The Journal of Immunology, 197(9), 3566-3574. } } \seealso{ See \link{HH_S1F} for the human heavy chain 1-mer substitution model and \link{HKL_S1F} for the human light chain 1-mer substitution model. } \keyword{datasets} shazam/man/createSubstitutionMatrix.Rd0000644000176200001440000001256413575260615017706 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \name{createSubstitutionMatrix} \alias{createSubstitutionMatrix} \title{Builds a substitution model} \usage{ createSubstitutionMatrix( db, model = c("S", "RS"), sequenceColumn = "SEQUENCE_IMGT", germlineColumn = "GERMLINE_IMGT_D_MASK", vCallColumn = "V_CALL", multipleMutation = c("independent", "ignore"), returnModel = c("5mer", "1mer", "1mer_raw"), minNumMutations = 50, numMutationsOnly = FALSE ) } \arguments{ \item{db}{data.frame containing sequence data.} \item{model}{type of model to create. The default model, "S", builds a model by counting only silent mutations. \code{model="S"} should be used for data that includes functional sequences. Setting \code{model="RS"} creates a model by counting both replacement and silent mutations and may be used on fully non-functional sequence data sets.} \item{sequenceColumn}{name of the column containing IMGT-gapped sample sequences.} \item{germlineColumn}{name of the column containing IMGT-gapped germline sequences.} \item{vCallColumn}{name of the column containing the V-segment allele call.} \item{multipleMutation}{string specifying how to handle multiple mutations occuring within the same 5-mer. If \code{"independent"} then multiple mutations within the same 5-mer are counted indepedently. If \code{"ignore"} then 5-mers with multiple mutations are excluded from the total mutation tally.} \item{returnModel}{string specifying what type of model to return; one of \code{c("5mer", "1mer", "1mer_raw")}. If \code{"5mer"} (the default) then a 5-mer nucleotide context model is returned. If \code{"1mer"} or \code{"1mer_raw"} then a single nucleotide substitution matrix (no context) is returned; where \code{"1mer_raw"} is the unnormalized version of the \code{"1mer"} model. Note, neither 1-mer model may be used as input to \link{createMutabilityMatrix}.} \item{minNumMutations}{minimum number of mutations required to compute the 5-mer substitution rates. If the number of mutations for a 5-mer is below this threshold, its substitution rates will be estimated from neighboring 5-mers. Default is 50. Not required if \code{numMutationsOnly=TRUE}.} \item{numMutationsOnly}{when \code{TRUE}, return counting information on the number of mutations for each 5-mer, instead of building a substitution matrix. This option can be used for parameter tuning for \code{minNumMutations} during preliminary analysis. Default is \code{FALSE}. Only applies when \code{returnModel} is set to \code{"5mer"}. The \code{data.frame} returned when this argument is \code{TRUE} can serve as the input for \link{minNumMutationsTune}.} } \value{ For \code{returnModel = "5mer"}: When \code{numMutationsOnly} is \code{FALSE}, a 4x1024 matrix of column normalized substitution rates for each 5-mer motif with row names defining the center nucleotide, one of \code{c("A", "C", "G", "T")}, and column names defining the 5-mer nucleotide sequence. When \code{numMutationsOnly} is \code{TRUE}, a 1024x4 data frame with each row providing information on counting the number of mutations for a 5-mer. Columns are named \code{fivemer.total}, \code{fivemer.every}, \code{inner3.total}, and \code{inner3.every}, corresponding to, respectively, the total number of mutations when counted as a 5-mer, whether there is mutation to every other base when counted as a 5-mer, the total number of mutations when counted as an inner 3-mer, and whether there is mutation to every other base when counted as an inner 3-mer. For \code{returnModel = "1mer"} or \code{"1mer_raw"}: a 4x4 normalized or un-normalized 1-mer substitution matrix respectively. } \description{ \code{createSubstitutionMatrix} builds a 5-mer nucleotide substitution model by counting the number of substitution mutations occuring in the center position for all 5-mer motifs. } \details{ \strong{Caution: The targeting model functions do NOT support ambiguous characters in their inputs. You MUST make sure that your input and germline sequences do NOT contain ambiguous characters (especially if they are clonal consensuses returned from \code{collapseClones}).} } \examples{ \donttest{ # Subset example data to one isotype and sample as a demo data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") # Count the number of mutations per 5-mer subCount <- createSubstitutionMatrix(db, model="S", multipleMutation="independent", returnModel="5mer", numMutationsOnly=TRUE) # Create model using only silent mutations sub <- createSubstitutionMatrix(db, model="S", multipleMutation="independent", returnModel="5mer", numMutationsOnly=FALSE, minNumMutations=20) } } \references{ \enumerate{ \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based on synonymous mutations from high-throughput immunoglobulin sequencing data. Front Immunol. 2013 4(November):358. } } \seealso{ \link{extendSubstitutionMatrix}, \link{createMutabilityMatrix}, \link{createTargetingMatrix}, \link{createTargetingModel}, \link{minNumMutationsTune}. } shazam/man/HKL_S5F.Rd0000644000176200001440000000200613445225760013700 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \docType{data} \name{HKL_S5F} \alias{HKL_S5F} \title{Human kappa and lambda light chain, silent, 5-mer, functional targeting model.} \format{A \link{TargetingModel} object.} \usage{ HKL_S5F } \description{ 5-mer model of somatic hypermutation targeting based on analysis of silent mutations in functional kappa and lambda light chain Ig sequences from Homo sapiens. } \references{ \enumerate{ \item Cui A, Di Niro R, Vander Heiden J, Briggs A, Adams K, Gilbert T, O'Connor K, Vigneault F, Shlomchik M and Kleinstein S (2016). A Model of Somatic Hypermutation Targeting in Mice Based on High-Throughput Ig Sequencing Data. The Journal of Immunology, 197(9), 3566-3574. } } \seealso{ See \link{HH_S5F} for the human heavy chain 5-mer targeting model; \link{MK_RS5NF} for the mouse kappa light chain 5-mer targeting model; and \link{U5N} for the uniform 5-mer null targeting model. } \keyword{datasets} shazam/man/createMutationDefinition.Rd0000644000176200001440000000261413575260615017611 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MutationDefinitions.R \name{createMutationDefinition} \alias{createMutationDefinition} \title{Creates a MutationDefinition} \usage{ createMutationDefinition(name, classes, description = "", citation = "") } \arguments{ \item{name}{name of the mutation definition.} \item{classes}{named character vectors with single-letter amino acid codes as names and amino acid classes as values, with \code{NA} assigned to set of characters \code{c("X", "*", "-", ".")}. Replacement (R) is be defined as a change in amino acid class and silent (S) as no change in class.} \item{description}{description of the mutation definition and its source data.} \item{citation}{publication source.} } \value{ A \code{MutationDefinition} object. } \description{ \code{createMutationDefinition} creates a \code{MutationDefinition}. } \examples{ # Define hydropathy classes library(alakazam) hydropathy <- list(hydrophobic=c("A", "I", "L", "M", "F", "W", "V"), hydrophilic=c("R", "N", "D", "C", "Q", "E", "K"), neutral=c("G", "H", "P", "S", "T", "Y")) chars <- unlist(hydropathy, use.names=FALSE) classes <- setNames(translateStrings(chars, hydropathy), chars) # Create hydropathy mutation definition md <- createMutationDefinition("Hydropathy", classes) } \seealso{ See \link{MutationDefinition} for the return object. } shazam/man/Baseline-class.Rd0000644000176200001440000000642413445225760015442 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Baseline.R \docType{class} \name{Baseline-class} \alias{Baseline-class} \alias{Baseline} \alias{plot,Baseline,character-method} \alias{Baseline-method} \alias{summary,Baseline-method} \title{S4 class defining a BASELINe (selection) object} \usage{ \S4method{plot}{Baseline,character}(x, y, ...) \S4method{summary}{Baseline}(object, nproc = 1) } \arguments{ \item{x}{\code{Baseline} object.} \item{y}{name of the column in the \code{db} slot of \code{baseline} containing primary identifiers.} \item{...}{arguments to pass to \link{plotBaselineDensity}.} \item{object}{\code{Baseline} object.} \item{nproc}{number of cores to distribute the operation over.} } \description{ \code{Baseline} defines a common data structure the results of selection analysis using the BASELINe method. } \section{Slots}{ \describe{ \item{\code{description}}{\code{character} providing general information regarding the sequences, selection analysis and/or object.} \item{\code{db}}{\code{data.frame} containing annotation information about the sequences and selection results.} \item{\code{regionDefinition}}{\link{RegionDefinition} object defining the regions and boundaries of the Ig sequences.} \item{\code{testStatistic}}{\code{character} indicating the statistical framework used to test for selection. For example, \code{"local"} or \code{"focused"}.} \item{\code{regions}}{\code{character} vector defining the regions the BASELINe analysis was carried out on. For \code{"CDR"} and \code{"FWR"} or \code{"CDR1"}, \code{"CDR2"}, \code{"CDR3"}, etc.} \item{\code{numbOfSeqs}}{\code{matrix} of dimensions \code{r x c} containing the number of sequences or PDFs in each region, where:\cr \code{r} = number of rows = number of groups or sequences.\cr \code{c} = number of columns = number of regions.} \item{\code{binomK}}{\code{matrix} of dimensions \code{r x c} containing the number of successes in the binomial trials in each region, where:\cr \code{r} = number of rows = number of groups or sequences.\cr \code{c} = number of columns = number of regions.} \item{\code{binomN}}{\code{matrix} of dimensions \code{r x c} containing the total number of trials in the binomial in each region, where:\cr \code{r} = number of rows = number of groups or sequences.\cr \code{c} = number of columns = number of regions.} \item{\code{binomP}}{\code{matrix} of dimensions \code{r x c} containing the probability of success in one binomial trial in each region, where:\cr \code{r} = number of rows = number of groups or sequences.\cr \code{c} = number of columns = number of regions.} \item{\code{pdfs}}{\code{list} of matrices containing PDFs with one item for each defined region (e.g. "CDR" and "FWR"). Matrices have dimensions \code{r x c} dementions, where:\cr \code{r} = number of rows = number of sequences or groups. \cr \code{c} = number of columns = length of the PDF (default 4001).} \item{\code{stats}}{\code{data.frame} of BASELINe statistics, including: mean selection strength (mean Sigma), 95\% confidence intervals, and p-values with positive signs for the presence of positive selection and/or p-values with negative signs for the presence of negative selection.} }} \seealso{ See \link{summarizeBaseline} for more information on \code{@stats}. } shazam/man/calcBaseline.Rd0000644000176200001440000001220613575260615015157 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Baseline.R \name{calcBaseline} \alias{calcBaseline} \title{Calculate the BASELINe PDFs} \usage{ calcBaseline( db, sequenceColumn = "CLONAL_SEQUENCE", germlineColumn = "CLONAL_GERMLINE", testStatistic = c("local", "focused", "imbalanced"), regionDefinition = NULL, targetingModel = HH_S5F, mutationDefinition = NULL, calcStats = FALSE, nproc = 1 ) } \arguments{ \item{db}{\code{data.frame} containing sequence data and annotations.} \item{sequenceColumn}{\code{character} name of the column in \code{db} containing input sequences.} \item{germlineColumn}{\code{character} name of the column in \code{db} containing germline sequences.} \item{testStatistic}{\code{character} indicating the statistical framework used to test for selection. One of \code{c("local", "focused", "imbalanced")}.} \item{regionDefinition}{\link{RegionDefinition} object defining the regions and boundaries of the Ig sequences.} \item{targetingModel}{\link{TargetingModel} object. Default is \link{HH_S5F}.} \item{mutationDefinition}{\link{MutationDefinition} object defining replacement and silent mutation criteria. If \code{NULL} then replacement and silent are determined by exact amino acid identity. Note, if the input data.frame already contains observed and expected mutation frequency columns then mutations will not be recalculated and this argument will be ignored.} \item{calcStats}{\code{logical} indicating whether or not to calculate the summary statistics \code{data.frame} stored in the \code{stats} slot of a \link{Baseline} object.} \item{nproc}{number of cores to distribute the operation over. If \code{nproc=0} then the \code{cluster} has already been set and will not be reset.} } \value{ A \link{Baseline} object containing the modified \code{db} and BASELINe posterior probability density functions (PDF) for each of the sequences. } \description{ \code{calcBaseline} calculates the BASELINe posterior probability density functions (PDFs) for sequences in the given Change-O \code{data.frame}. } \details{ Calculates the BASELINe posterior probability density function (PDF) for sequences in the provided \code{db}. \strong{Note}: Individual sequences within clonal groups are not, strictly speaking, independent events and it is generally appropriate to only analyze selection pressures on an effective sequence for each clonal group. For this reason, it is strongly recommended that the input \code{db} contains one effective sequence per clone. Effective clonal sequences can be obtained by calling the \link{collapseClones} function. If the \code{db} does not contain the required columns to calculate the PDFs (namely MU_COUNT & MU_EXPECTED) then the function will: \enumerate{ \item Calculate the numbers of observed mutations. \item Calculate the expected frequencies of mutations and modify the provided \code{db}. The modified \code{db} will be included as part of the returned \code{Baseline} object. } The \code{testStatistic} indicates the statistical framework used to test for selection. E.g. \itemize{ \item \code{local} = CDR_R / (CDR_R + CDR_S). \item \code{focused} = CDR_R / (CDR_R + CDR_S + FWR_S). \item \code{imbalanced} = CDR_R + CDR_S / (CDR_R + CDR_S + FWR_S + FRW_R). } For \code{focused} the \code{regionDefinition} must only contain two regions. If more than two regions are defined the \code{local} test statistic will be used. For further information on the frame of these tests see Uduman et al. (2011). } \examples{ # Load and subset example data data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE == "IgG" & SAMPLE == "+7d") # Collapse clones db <- collapseClones(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", method="thresholdedFreq", minimumFrequency=0.6, includeAmbiguous=FALSE, breakTiesStochastic=FALSE) # Calculate BASELINe baseline <- calcBaseline(db, sequenceColumn="CLONAL_SEQUENCE", germlineColumn="CLONAL_GERMLINE", testStatistic="focused", regionDefinition=IMGT_V, targetingModel=HH_S5F, nproc=1) } \references{ \enumerate{ \item Hershberg U, et al. Improved methods for detecting selection by mutation analysis of Ig V region sequences. Int Immunol. 2008 20(5):683-94. \item Uduman M, et al. Detecting selection in immunoglobulin sequences. Nucleic Acids Res. 2011 39(Web Server issue):W499-504. \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based on synonymous mutations from high-throughput immunoglobulin sequencing data. Front Immunol. 2013 4(November):358. } } \seealso{ See \link{Baseline} for the return object. See \link{groupBaseline} and \link{summarizeBaseline} for further processing. See \link{plotBaselineSummary} and \link{plotBaselineDensity} for plotting results. } shazam/man/createRegionDefinition.Rd0000644000176200001440000000163713575260615017240 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/RegionDefinitions.R \name{createRegionDefinition} \alias{createRegionDefinition} \title{Creates a RegionDefinition} \usage{ createRegionDefinition( name = "", boundaries = factor(), description = "", citation = "" ) } \arguments{ \item{name}{name of the region definition.} \item{boundaries}{\code{factor} defining the region boundaries of the sequence. The levels and values of \code{boundaries} determine the number of regions (e.g. CDR and FWR).} \item{description}{description of the region definition and its source data.} \item{citation}{publication source.} } \value{ A \code{RegionDefinition} object. } \description{ \code{createRegionDefinition} creates a \code{RegionDefinition}. } \examples{ # Creates an empty RegionDefinition object createRegionDefinition() } \seealso{ See \link{RegionDefinition} for the return object. } shazam/man/editBaseline.Rd0000644000176200001440000000237113575255270015205 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Baseline.R \name{editBaseline} \alias{editBaseline} \title{Edit the Baseline object} \usage{ editBaseline(baseline, field, value) } \arguments{ \item{baseline}{\code{Baseline} object to be edited.} \item{field}{name of the field in the \code{Baseline} object to be edited.} \item{value}{value to set the \code{field}.} } \value{ A \code{Baseline} object with the field of choice updated. } \description{ \code{editBaseline} edits a field in a \code{Baseline} object. } \examples{ \donttest{ # Subset example data data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE == "IgG" & SAMPLE == "+7d") # Make Baseline object baseline <- calcBaseline(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", testStatistic="focused", regionDefinition=IMGT_V, targetingModel=HH_S5F, nproc=1) # Edit the field "description" baseline <- editBaseline(baseline, field="description", value="+7d IgG") } } \seealso{ See \link{Baseline} for the input and return object. } shazam/man/createTargetingMatrix.Rd0000644000176200001440000000424413575255270017113 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TargetingModels.R \name{createTargetingMatrix} \alias{createTargetingMatrix} \title{Calculates a targeting rate matrix} \usage{ createTargetingMatrix(substitutionModel, mutabilityModel) } \arguments{ \item{substitutionModel}{matrix of 5-mers substitution rates built by \link{createSubstitutionMatrix} or \link{extendSubstitutionMatrix}.} \item{mutabilityModel}{vector of 5-mers mutability rates built by \link{createMutabilityMatrix} or \link{extendMutabilityMatrix}.} } \value{ A matrix with the same dimensions as the input \code{substitutionModel} containing normalized targeting probabilities for each 5-mer motif with row names defining the center nucleotide and column names defining the 5-mer nucleotide sequence. } \description{ \code{createTargetingMatrix} calculates the targeting model matrix as the combined probability of mutability and substitution. } \details{ Targeting rates are calculated by multiplying the normalized mutability rate by the normalized substitution rates for each individual 5-mer. } \examples{ \donttest{ # Subset example data to one isotype and sample as a demo data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") # Create 4x1024 models using only silent mutations sub_model <- createSubstitutionMatrix(db, model="S") mut_model <- createMutabilityMatrix(db, sub_model, model="S") # Extend substitution and mutability to including Ns (5x3125 model) sub_model <- extendSubstitutionMatrix(sub_model) mut_model <- extendMutabilityMatrix(mut_model) # Create targeting model from substitution and mutability tar_model <- createTargetingMatrix(sub_model, mut_model) } } \references{ \enumerate{ \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based on synonymous mutations from high-throughput immunoglobulin sequencing data. Front Immunol. 2013 4(November):358. } } \seealso{ \link{createSubstitutionMatrix}, \link{extendSubstitutionMatrix}, \link{createMutabilityMatrix}, \link{extendMutabilityMatrix}, \link{createTargetingModel} } shazam/man/shmulateSeq.Rd0000644000176200001440000000343313575260615015107 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Shmulate.R \name{shmulateSeq} \alias{shmulateSeq} \title{Simulate mutations in a single sequence} \usage{ shmulateSeq( sequence, numMutations, targetingModel = HH_S5F, start = 1, end = nchar(sequence) ) } \arguments{ \item{sequence}{sequence string in which mutations are to be introduced. Accepted alphabet: \code{\{A, T, G, C, N, .\}}. Note that \code{-} is not accepted.} \item{numMutations}{number of mutations to be introduced into \code{sequence}.} \item{targetingModel}{5-mer \link{TargetingModel} object to be used for computing probabilities of mutations at each position. Defaults to \link{HH_S5F}.} \item{start}{Initial position in \code{sequence} where mutations can be introduced. Default: 1} \item{end}{Last position in \code{sequence} where mutations can be introduced. Default: last position (sequence length).} } \value{ A string defining the mutated sequence. } \description{ Generates random mutations in a sequence iteratively using a targeting model. Targeting probabilities at each position are updated after each iteration. } \details{ If the input \code{sequence} has a non-triplet overhang at the end, it will be trimmed to the last codon. For example, \code{ATGCATGC} will be trimmed to \code{ATGCAT}. Mutations are not introduced to positions in the input \code{sequence} that contain \code{.} or \code{N}. } \examples{ # Define example input sequence sequence <- "NGATCTGACGACACGGCCGTGTATTACTGTGCGAGAGATA.TTTA" # Simulate using the default human 5-mer targeting model shmulateSeq(sequence, numMutations=6) } \seealso{ See \link{shmulateTree} for imposing mutations on a lineage tree. See \link{HH_S5F} and \link{MK_RS5NF} for predefined \link{TargetingModel} objects. } shazam/man/consensusSequence.Rd0000644000176200001440000001007213575260615016322 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MutationProfiling.R \name{consensusSequence} \alias{consensusSequence} \title{Construct a consensus sequence} \usage{ consensusSequence( sequences, db = NULL, method = c("mostCommon", "thresholdedFreq", "catchAll", "mostMutated", "leastMutated"), minFreq = NULL, muFreqColumn = NULL, lenLimit = NULL, includeAmbiguous = FALSE, breakTiesStochastic = FALSE, breakTiesByColumns = NULL ) } \arguments{ \item{sequences}{character vector of sequences.} \item{db}{\code{data.frame} containing sequence data for a single clone. Applicable to and required for the \code{"mostMutated"} and \code{"leastMutated"} methods. Default is \code{NULL}.} \item{method}{method to calculate consensus sequence. One of \code{"thresholdedFreq"}, \code{"mostCommon"}, \code{"catchAll"}, \code{"mostMutated"}, or \code{"leastMutated"}. See "Methods" under \link{collapseClones} for details.} \item{minFreq}{frequency threshold for calculating input consensus sequence. Applicable to and required for the \code{"thresholdedFreq"} method. A canonical choice is 0.6. Default is \code{NULL}.} \item{muFreqColumn}{\code{character} name of the column in db containing mutation frequency. Applicable to and required for the \code{"mostMutated"} and \code{"leastMutated"} methods. Default is \code{NULL}.} \item{lenLimit}{limit on consensus length. if \code{NULL} then no length limit is set.} \item{includeAmbiguous}{whether to use ambiguous characters to represent positions at which there are multiple characters with frequencies that are at least \code{minimumFrequency} or that are maximal (i.e. ties). Applicable to and required for the \code{"thresholdedFreq"} and \code{"mostCommon"} methods. Default is \code{FALSE}. See "Choosing ambiguous characters" under \link{collapseClones} for rules on choosing ambiguous characters.} \item{breakTiesStochastic}{In case of ties, whether to randomly pick a sequence from sequences that fulfill the criteria as consensus. Applicable to and required for all methods except for \code{"catchAll"}. Default is \code{FALSE}. See "Methods" under \link{collapseClones} for details.} \item{breakTiesByColumns}{A list of the form \code{list(c(col_1, col_2, ...), c(fun_1, fun_2, ...))}, where \code{col_i} is a \code{character} name of a column in \code{db}, and \code{fun_i} is a function to be applied on that column. Currently, only \code{max} and \code{min} are supported. Note that the two \code{c()}'s in \code{list()} are essential (i.e. if there is only 1 column, the list should be of the form \code{list(c(col_1), c(func_1))}. Applicable to and optional for the \code{"mostMutated"} and \code{"leastMutated"} methods. If supplied, \code{fun_i}'s are applied on \code{col_i}'s to help break ties. Default is \code{NULL}. See "Methods" under \link{collapseClones} for details.} } \value{ A list containing \code{cons}, which is a character string that is the consensus sequence for \code{sequences}; and \code{muFreq}, which is the maximal/minimal mutation frequency of the consensus sequence for the \code{"mostMutated"} and \code{"leastMutated"} methods, or \code{NULL} for all other methods. } \description{ Construct a consensus sequence } \details{ See \link{collapseClones} for detailed documentation on methods and additional parameters. } \examples{ # Subset example data data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE \%in\% c("IgA", "IgG") & SAMPLE == "+7d") clone <- subset(db, CLONE == "3192") # First compute mutation frequency for most/leastMutated methods clone <- observedMutations(clone, frequency=TRUE, combine=TRUE) # Manually create a tie clone <- rbind(clone, clone[which.max(clone$MU_FREQ), ]) # ThresholdedFreq method. # Resolve ties deterministically without using ambiguous characters cons1 <- consensusSequence(clone$SEQUENCE_IMGT, method="thresholdedFreq", minFreq=0.3, includeAmbiguous=FALSE, breakTiesStochastic=FALSE) cons1$cons } shazam/DESCRIPTION0000644000176200001440000000552013616730026013251 0ustar liggesusersPackage: shazam Type: Package Version: 0.2.3 Date: 2020-02-05 Authors@R: c(person("Mohamed", "Uduman", role=c("aut"), email="mohamed.uduman@yale.edu"), person("Gur", "Yaari", role=c("aut"), email="gur.yaari@biu.ac.il"), person("Namita", "Gupta", role=c("aut"), email="namita.gupta@yale.edu"), person("Jason", "Vander Heiden", role=c("aut", "cre"), email="jason.vanderheiden@yale.edu"), person("Ang", "Cui", role=c("ctb"), email="angcui@mit.edu"), person("Susanna", "Marquez", role=c("ctb"), email="susanna.marquez@yale.edu"), person("Julian", "Zhou", role=c("ctb"), email="julian.zhou@yale.edu"), person("Nima", "Nouri", role=c("ctb"), email="nima.nouri@yale.edu"), person("Steven", "Kleinstein", role=c("aut", "cph"), email="steven.kleinstein@yale.edu")) Title: Immunoglobulin Somatic Hypermutation Analysis Description: Provides a computational framework for analyzing mutations in immunoglobulin (Ig) sequences. Includes methods for Bayesian estimation of antigen-driven selection pressure, mutational load quantification, building of somatic hypermutation (SHM) models, and model-dependent distance calculations. Also includes empirically derived models of SHM for both mice and humans. Citations: Gupta and Vander Heiden, et al (2015) , Yaari, et al (2012) , Yaari, et al (2013) , Cui, et al (2016) . License: CC BY-SA 4.0 URL: http://shazam.readthedocs.io BugReports: https://bitbucket.org/kleinstein/shazam/issues LazyData: true BuildVignettes: true VignetteBuilder: knitr Encoding: UTF-8 Depends: R (>= 3.1.2), ggplot2 (>= 2.0.0), stringi (>= 1.1.3) Imports: alakazam (>= 0.3.0), ape, diptest, doParallel, dplyr (>= 0.8.1), foreach, graphics, grid, igraph, iterators, kedd, KernSmooth, lazyeval, MASS, methods, parallel, progress, rlang, scales, seqinr, stats, tidyr, utils Suggests: knitr, rmarkdown, testthat Collate: 'Shazam.R' 'RegionDefinitions.R' 'Baseline.R' 'Core.R' 'DistToNearest.R' 'MutationDefinitions.R' 'MutationProfiling.R' 'Shmulate.R' 'TargetingModels.R' RoxygenNote: 7.0.2 NeedsCompilation: no Packaged: 2020-02-05 21:41:36 UTC; vandej27 Author: Mohamed Uduman [aut], Gur Yaari [aut], Namita Gupta [aut], Jason Vander Heiden [aut, cre], Ang Cui [ctb], Susanna Marquez [ctb], Julian Zhou [ctb], Nima Nouri [ctb], Steven Kleinstein [aut, cph] Maintainer: Jason Vander Heiden Repository: CRAN Date/Publication: 2020-02-06 06:20:06 UTC shazam/build/0000755000176200001440000000000013616633217012644 5ustar liggesusersshazam/build/vignette.rds0000644000176200001440000000054413616633217015206 0ustar liggesusersSJ0n̉B~}!D_c{dkRovjdܜs>!Mn vqlGgi\$"eD#Wdu=_V EV %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Mutation analysis} %\usepackage[utf8]{inputenc} --- Basic mutational load calculations are provided by the `observedMutations` function. `observedMutations` provides multiple options to control how mutations are calculated. Mutations can be calculated as either counts or frequencies, may be divided into replacement (R) and silent (S) mutations, and subset into FWR and CDR specific mutations. Additionally, alternative mutational definitions may be considered based on the physicochemical properties of translated codons. ## Example data A small example Change-O database is included in the `alakazam` package. Analyzing mutations requires the following fields (columns) to be present in the Change-O database: * `SEQUENCE_IMGT` * `GERMLINE_IMGT_D_MASK` ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Import required packages library(alakazam) library(shazam) library(dplyr) library(ggplot2) # Load and subset example data data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE %in% c("IgA", "IgG") & SAMPLE == "+7d") ``` ## Calculate the counts and frequencies of mutations over the entire sequence When calling `observedMutations` with `regionDefinition=NULL`, the entire input sequence (`sequenceColumn`) is compared to the germline sequence (`germlineColumn`) to identify R and S mutations. If `frequency=TRUE`, the number of mutations is expressed as the frequency of mutations over the total number of positions that are non-N in both the input and the germline sequences. In the example below, the counts (`frequency=FALSE` ) and frequencies (`frequency=TRUE`) of R and S mutations are calculated separately. New columns containing mutation counts are appended to the input data.frame with names in the form `MU_COUNT__`. Mutation frequencies appear in new columns named `MU_FREQ__`. ```{r, eval=TRUE} # Calculate R and S mutation counts db_obs <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=NULL, frequency=FALSE, nproc=1) # Show new mutation count columns db_obs %>% select(SEQUENCE_ID, starts_with("MU_COUNT_")) %>% head(n=4) # Calculate R and S mutation frequencies db_obs <- observedMutations(db_obs, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=NULL, frequency=TRUE, nproc=1) # Show new mutation frequency columns db_obs %>% select(SEQUENCE_ID, starts_with("MU_FREQ_")) %>% head(n=4) ``` Specifying the `combine=TRUE` argument will aggregate all mutation columns into a single value. ```{r, eval=TRUE} # Calculate combined R and S mutation frequencies db_obs <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=NULL, frequency=TRUE, combine=TRUE, nproc=1) # Show new mutation frequency columns db_obs %>% select(SEQUENCE_ID, starts_with("MU_FREQ_")) %>% head(n=4) ``` We can plot the mutation frequencies a explore differences between samples or isotypes. ```{r, eval=TRUE, warning=FALSE} g1 <- ggplot(db_obs, aes(x=ISOTYPE, y=MU_FREQ, fill=ISOTYPE)) + theme_bw() + ggtitle("Total mutations") + xlab("Isotype") + ylab("Mutation frequency") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot() plot(g1) ``` ## Calculate mutations within subregions of the V-segment To restrict the mutational analysis to a particular area in the sequence, the `regionDefinition` argument needs to be assigned a `RegionDefinition` object, which simply defines the subregion boundaries of the Ig sequence. For convenience, `shazam` provides a set of such objects, for which an overview is provided via `?IMGT_SCHEMES`. Each of these objects cover the IMGT numbered V segment up to nucleotide position 312. Different objects treat regions within the V segment with varying granularity: * `IMGT_V_BY_CODONS`: treats each codon, from codon 1 to codon 104, as a distinct region; * `IMGT_V_BY_REGIONS`: defines regions to be CDR1, CDR2, FWR1, FWR2 and FWR3; * `IMGT_V`: defines regions to be either CDR or FWR; * `IMGT_V_BY_SEGMENTS`: provides no subdivisons and treats the entire V segment as a single region. When supplying one of these objects to `regionDefinition`, and with `combined=FALSE`, the resultant mutation counts/frequencies will be tabulated in a way consistent with the granularity of the object's region definition. For example, * With `IMGT_V_BY_REGIONS`, mutation frequencies will be reported in columns `MU_FREQ_CDR1_R`, `MU_FREQ_CDR1_S`, `MU_FREQ_CDR2_R`, `MU_FREQ_CDR2_S`, `MU_FREQ_FWR1_R`, `MU_FREQ_FWR1_S`, `MU_FREQ_FWR2_R`, `MU_FREQ_FWR2_S`, `MU_FREQ_FWR3_R`, and `MU_FREQ_FWR3_S`. * With `IMGT_V`, mutation frequencies will be reported in columns `MU_FREQ_CDR_R`, `MU_FREQ_CDR_S`, `MU_FREQ_FWR_R`, and `MU_FREQ_FWR_S`. * With `IMGT_V_BY_SEGMENTS`, mutation frequencies will be reported in columns `MU_FREQ_V_R`, and `MU_FREQ_V_S`. In the following example, we will explore the mutation frequency in the V-segment using two of the region definitions. ```{r, eval=TRUE} # Calculate R and S mutation counts for individual CDRs and FWRs db_obs_v <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=IMGT_V_BY_REGIONS, frequency=FALSE, nproc=1) # Show new FWR mutation columns db_obs_v %>% select(SEQUENCE_ID, starts_with("MU_COUNT_FWR")) %>% head(n=4) # Calculate aggregate CDR and FWR V-segment R and S mutation frequencies db_obs_v <- observedMutations(db_obs_v, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=IMGT_V, frequency=TRUE, nproc=1) # Show new CDR and FWR mutation frequency columns db_obs_v %>% select(SEQUENCE_ID, starts_with("MU_FREQ_")) %>% head(n=4) ``` Plot a comparison between CDR silent and replacement mutations. ```{r, eval=TRUE, warning=FALSE} g2 <- ggplot(db_obs_v, aes(x=ISOTYPE, y=MU_FREQ_CDR_S, fill=ISOTYPE)) + theme_bw() + ggtitle("CDR silent mutations") + xlab("Isotype") + ylab("Mutation frequency") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot() g3 <- ggplot(db_obs_v, aes(x=ISOTYPE, y=MU_FREQ_CDR_R, fill=ISOTYPE)) + theme_bw() + ggtitle("CDR replacement mutations") + xlab("Isotype") + ylab("Mutation frequency") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot() alakazam::gridPlot(g2, g3, ncol=2) ``` ## Use amino acid physicochemical properties to define mutations By default, replacement and silent are determined by exact amino acid identity. But this can be changed by setting the `mutationDefinition` argument. For convenience, `shazam` provides a set of `MutationDefinition` objects defining changes in amino acid charge, hydrophobicity, polarity and volume. In the following example, replacement mutation are defined as amino acid changes that lead to a change in charge (`mutationDefinition=CHARGE_MUTATIONS`). Mutations that do not alter the charge classification of a translated codon will be considered silent mutations. ```{r, eval=TRUE} # Calculate charge mutation frequency for the full sequence db_obs_ch <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=NULL, mutationDefinition=CHARGE_MUTATIONS, frequency=TRUE, nproc=1) # Show new charge mutation frequency columns db_obs_ch %>% select(SEQUENCE_ID, starts_with("MU_FREQ_")) %>% head(n=4) ``` We can make a plot to visualize if mutations that change the sequence charge are more frequent in one isotype. ```{r, eval=TRUE, warning=FALSE} g4 <- ggplot(db_obs_ch, aes(x=ISOTYPE, y=MU_FREQ_SEQ_R, fill=ISOTYPE)) + theme_bw() + ggtitle("Charge replacement mutations") + xlab("Isotype") + ylab("Mutation frequency") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot() plot(g4) ``` shazam/vignettes/Baseline-Vignette.Rmd0000644000176200001440000003523513575255254017543 0ustar liggesusers--- title: 'Shazam: Quantification of selection pressure' author: "Namita Gupta & Jason Anthony Vander Heiden & Julian Q. Zhou" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4 fig_width: 7.5 highlight: pygments toc: yes html_document: fig_height: 4 fig_width: 7.5 highlight: pygments theme: readable toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteIndexEntry{Selection quantification} %\VignetteEngine{knitr::rmarkdown} %\usepackage[utf8]{inputenc} --- BASELINe quantifies selection pressure by calculating the posterior probability density function (PDF) based on observed mutations compared to expected mutation rates derived from an underlying SHM targeting model. Selection is quantified via the following steps: 1. Calculate the selection scores for individual sequences. 2. Group by relevant fields for comparison and convolve individual selection PDFs. 4. Plot and compare selection scores of different groups of sequences. ## Example data A small example Change-O database is included in the `alakazam` package. The example dataset consists of a subset of Ig sequencing data from an influenza vaccination study (Laserson and Vigneault et al., PNAS, 2014). The data include sequences from multiple time-points before and after the subject received an influenza vaccination. Quantifying selection requires the following fields (columns) to be present in the Change-O database: * `SEQUENCE_ID` * `SEQUENCE_IMGT` * `GERMLINE_IMGT_D_MASK` ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load example data library(shazam) data(ExampleDb, package="alakazam") ``` ## Calculate selection PDFs for individual sequences Selection scores are calculated with the `calcBaseline` function. This can be performed with a single call to `calcBaseline`, which performs all required steps. Alternatively, one can perform each step separately for greater control over the analysis parameters. ### Constructing clonal consensus sequences Individual sequences within clonal groups are not, strictly speaking, independent events and it is generally appropriate to only analyze selection pressures on an effective sequence for each clonal group. The `collapseClones` function provides one strategy for generating an effective sequences for each clone. It reduces the input database to one row per clone and appends `CLONAL_SEQUENCE` and `CLONAL_GERMLINE` columns which contain the consensus sequences for each clone. ```{r, eval=TRUE, warning=FALSE, results="hide"} # Collapse clonal groups into single sequences clones <- collapseClones(ExampleDb, regionDefinition=IMGT_V, method="thresholdedFreq", minimumFrequency=0.6, includeAmbiguous=FALSE, breakTiesStochastic=FALSE, nproc=1) ``` ### Calculating selection in multiple steps Following construction of an effective sequence for each clone, the observed and expected mutation counts are calculated for each sequence in the `CLONAL_SEQUENCE` column relative to the `CLONAL_GERMLINE`. `observedMutations` is used to calculate the number of observed mutations and `expectedMutations` calculates the expected frequency of mutations. The underlying targeting model for calculating expectations can be specified using the `targetingModel` parameter. In the example below, the default `HH_S5F` is used. Column names for sequence and germline sequence may also be passed in as parameters if they differ from the Change-O defaults. Mutations are counted by these functions separately for complementarity determining (CDR) and framework (FWR) regions. The `regionDefinition` argument defines whether these regions are handled separately, and where the boundaries lie. There are two built-in region definitions in the `shazam` package, both dependent upon the V segment being IMGT-gapped: * `IMGT_V`: All regions in the V segment, excluding CDR3, grouped as either CDR or FWR. * `IMGT_V_BY_REGIONS`: The CDR1, CDR2, CDR3, FWR1, FWR and FWR3 regions in the V segment (no CDR3) treated as individual regions. Users may define other region sets and boundaries by creating a custom `RegionDefinition` object. ```{r, eval=TRUE, warning=FALSE, results="hide"} # Count observed mutations and append MU_COUNT columns to the output observed <- observedMutations(clones, sequenceColumn="CLONAL_SEQUENCE", germlineColumn="CLONAL_GERMLINE", regionDefinition=IMGT_V, nproc=1) # Count expected mutations and append MU_EXPECTED columns to the output expected <- expectedMutations(observed, sequenceColumn="CLONAL_SEQUENCE", germlineColumn="CLONAL_GERMLINE", targetingModel=HH_S5F, regionDefinition=IMGT_V, nproc=1) ``` The counts of observed and expected mutations can be combined to test for selection using `calcBaseline`. The statistical framework used to test for selection based on mutation counts can be specified using the `testStatistic` parameter. ```{r, eval=TRUE, warning=FALSE, results="hide"} # Calculate selection scores using the output from expectedMutations baseline <- calcBaseline(expected, testStatistic="focused", regionDefinition=IMGT_V, nproc=1) ``` ### Calculating selection in one step It is not required for `observedMutation` and `expectedMutations` to be run prior to `calcBaseline`. If the output of these two steps does not appear in the input data.frame, then `calcBaseline` will call the appropriate functions prior to calculating selection scores. ```{r, eval=TRUE, warning=FALSE, results="hide"} # Calculate selection scores from scratch baseline <- calcBaseline(clones, testStatistic="focused", regionDefinition=IMGT_V, nproc=1) ``` ### Using alternative mutation definitions and models The default behavior of `observedMutations` and `expectedMutations`, and by extension `calcBaseline`, is to define a replacement mutation in the usual way - any change in the amino acid of a codon is considered a replacement mutation. However, these functions have a `mutationDefinition` argument which allows these definitions to be changed by providing a `MutationDefinition` object that contains alternative replacement and silent criteria. `shazam` provides the following built-in MutationDefinitions: * `CHARGE_MUTATIONS`: Amino acid mutations are defined by changes in side chain charge class. * `HYDROPATHY_MUTATIONS`: Amino acid mutations are defined by changes in side chain hydrophobicitity class. * `POLARITY_MUTATIONS`: Amino acid mutations are defined by changes in side chain polarity class. * `VOLUME_MUTATIONS`: Amino acid mutations are defined by changes in side chain volume class. The default behavior of `expectedMutations` is to use the human 5-mer mutation model, `HH_S5F`. Alternative SHM targeting models can be provided using the `targetingModel` argument. ```{r, eval=FALSE, warning=FALSE, results="hide"} # Calculate selection on charge class with the mouse 5-mer model baseline <- calcBaseline(clones, testStatistic="focused", regionDefinition=IMGT_V, targetingModel=MK_RS5NF, mutationDefinition=CHARGE_MUTATIONS, nproc=1) ``` ## Group and convolve individual selection distributions To compare the selection scores of groups of sequences, the sequences must be convolved into a single PDF representing each group. In the example dataset, the `SAMPLE` field corresponds to samples taken at different time points before and after an influenza vaccination and the `ISOTYPE` field specifies the isotype of the sequence. The `groupBaseline` function convolves the BASELINe PDFs of individual sequences/clones to get a combined PDF. The field(s) by which to group the sequences are specified with the `groupBy` parameter. The `groupBaseline` function automatically calls `summarizeBaseline` to generate summary statistics based on the requested groupings, and populates the `stats` slot of the input `Baseline` object with the number of sequences with observed mutations for each region, mean selection scores, 95% confidence intervals, and p-values with positive signs indicating the presence of positive selection and/or p-values with negative signs indicating the presence of negative selection. The magnitudes of the p-values (without the signs) should be interpreted as analagous to a t-test. ### Grouping by a single annotation The following example generates a single selection PDF for each unique annotation in the `SAMPLE` column. ```{r, eval=TRUE, warning=FALSE, results="hide"} # Combine selection scores by time-point grouped_1 <- groupBaseline(baseline, groupBy="SAMPLE") ``` ### Subsetting and grouping by multiple annotations Grouping by multiple annotations follows the sample proceedure as a single annotation by simply adding columns to the `groupBy` argument. Subsetting the data can be performed before or after generating selection PDFs via `calcBaseline`. However, note that subsetting may impact the clonal representative sequences generated by `collapseClones`. In the following example subsetting precedes the collapsing of clonal groups. ```{r, eval=TRUE, warning=FALSE, results="hide"} # Subset the original data to switched isotypes db_sub <- subset(ExampleDb, ISOTYPE %in% c("IgM", "IgG")) # Collapse clonal groups into single sequence clones_sub <- collapseClones(db_sub, regionDefinition=IMGT_V, method="thresholdedFreq", minimumFrequency=0.6, includeAmbiguous=FALSE, breakTiesStochastic=FALSE, nproc=1) # Calculate selection scores from scratch baseline_sub <- calcBaseline(clones_sub, testStatistic="focused", regionDefinition=IMGT_V, nproc=1) # Combine selection scores by time-point and isotype grouped_2 <- groupBaseline(baseline_sub, groupBy=c("SAMPLE", "ISOTYPE")) ``` ### Convolving variables at multiple levels To make selection comparisons using two levels of variables, you would need two iterations of groupings, where the first iteration of `groupBaseline` groups on both variables, and the second iteration groups on the "outer" variable. For example, if a data set has both case and control subjects, annotated in `STATUS` and `SUBJECT` columns, then generating convolved PDFs for each status would be performed as: ```{r, eval=FALSE, warning=FALSE, results="hide"} # First group by subject and status subject_grouped <- groupBaseline(baseline, groupBy=c("STATUS", "SUBJECT")) # Then group the output by status status_grouped <- groupBaseline(subject_grouped, groupBy="STATUS") ``` ### Testing the difference in selection PDFs between groups The `testBaseline` function will perform signifance testing between two grouped BASELINe PDFs, by region, and return a data.frame with the following information: * `REGION`: The sequence region, such as "CDR" and "FWR". * `TEST`: The name of the two groups compared. * `PVALUE`: Two-sided p-value for the comparison. * `FDR`: FDR corrected p-value. ```{r, eval=TRUE} testBaseline(grouped_1, groupBy="SAMPLE") ``` ## Plot and compare selection scores for groups `plotBaselineSummary` plots the mean and confidence interval of selection scores for the given groups. The `idColumn` argument specifies the field that contains identifiers of the groups of sequences. If there is a secondary field by which the sequences are grouped, this can be specified using the `groupColumn`. This secondary grouping can have a user-defined color palette passed into `groupColors` or can be separated into facets by setting the `facetBy="group"`. The `subsetRegions` argument can be used to visualize selection of specific regions. Several examples utilizing these different parameters are provided below. ```{r, eval=TRUE, warning=FALSE} # Set sample and isotype colors sample_colors <- c("-1h"="seagreen", "+7d"="steelblue") isotype_colors <- c("IgM"="darkorchid", "IgD"="firebrick", "IgG"="seagreen", "IgA"="steelblue") # Plot mean and confidence interval by time-point plotBaselineSummary(grouped_1, "SAMPLE") # Plot selection scores by time-point and isotype for only CDR plotBaselineSummary(grouped_2, "SAMPLE", "ISOTYPE", groupColors=isotype_colors, subsetRegions="CDR") # Group by CDR/FWR and facet by isotype plotBaselineSummary(grouped_2, "SAMPLE", "ISOTYPE", facetBy="group") ``` `plotBaselineDensity` plots the full `Baseline` PDF of selection scores for the given groups. The parameters are the same as those for `plotBaselineSummary`. However, rather than plotting the mean and confidence interval, the full density function is shown. ```{r, eval=TRUE, warning=FALSE} # Plot selection PDFs for a subset of the data plotBaselineDensity(grouped_2, "ISOTYPE", groupColumn="SAMPLE", colorElement="group", colorValues=sample_colors, sigmaLimits=c(-1, 1)) ``` ## Editing a field in a Baseline object If, for any reason, one needs to edit the existing values in a field in a `Baseline` object, one can do so via `editBaseline`. In the following example, we remove results related to IgA in the relevant fields from `grouped_2`. When the input data is large and it takes a long time for `calcBaseline` to run, `editBaseline` could become useful when, for instance, one would like to exclude a certain sample or isotype, but would rather not re-run `calcBaseline` after removing that sample or isotype from the original input data. ```{r, eval=FALSE, warning=FALSE, results="hide"} # Get indices of rows corresponding to IgA in the field "db" # These are the same indices also in the matrices in the fileds "numbOfSeqs", # "binomK", "binomN", "binomP", and "pdfs" # In this example, there is one row of IgA for each sample dbIgMIndex <- which(grouped_2@db$ISOTYPE == "IgA") grouped_2 <- editBaseline(grouped_2, "db", grouped_2@db[-dbIgMIndex, ]) grouped_2 <- editBaseline(grouped_2, "numbOfSeqs", grouped_2@numbOfSeqs[-dbIgMIndex, ]) grouped_2 <- editBaseline(grouped_2, "binomK", grouped_2@binomK[-dbIgMIndex, ]) grouped_2 <- editBaseline(grouped_2, "binomN", grouped_2@binomN[-dbIgMIndex, ]) grouped_2 <- editBaseline(grouped_2, "binomP", grouped_2@binomP[-dbIgMIndex, ]) grouped_2 <- editBaseline(grouped_2, "pdfs", lapply(grouped_2@pdfs, function(pdfs) {pdfs[-dbIgMIndex, ]} )) # The indices corresponding to IgA are slightly different in the field "stats" # In this example, there is one row of IgA for each sample and for each region grouped_2 <- editBaseline(grouped_2, "stats", grouped_2@stats[grouped_2@stats$ISOTYPE!="IgA", ]) ``` shazam/vignettes/Targeting-Vignette.Rmd0000644000176200001440000001443013575255254017737 0ustar liggesusers--- title: 'Shazam: Inferring SHM targeting models' author: "Namita Gupta" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4.5 fig_width: 7.5 highlight: pygments toc: yes html_document: fig_height: 4.5 fig_width: 7.5 highlight: pygments theme: readable toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{SHM targeting models} %\usepackage[utf8]{inputenc} --- The targeting model is the background likelihood of a particular mutation, based on the surrounding sequence context as well as the mutation itself. The model is inferred from observed mutations in the data. The model can then be transformed into a distance function to compare Ig sequences of a given dataset based on the likelihood of the observed mutations. This is done via the following steps: 1. Infer a substitution model, which is the likelihood of a base mutating to each other base given the microsequence context. 2. Infer a mutability model, which is likelihood of a given base being mutated given the microsequence context and substitution model. 3. Visualize the mutability model to identify hot and cold spots. 4. Calculate a nucleotide distance matrix based on the underlying SHM models. ## Example data A small example Change-O database is included in the `shazam` package. Inferring a targeting model requires the following fields (columns) to be present in the Change-O database: * `SEQUENCE_ID` * `SEQUENCE_IMGT` * `GERMLINE_IMGT_D_MASK` * `V_CALL` ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load example data library(shazam) data(ExampleDb, package="alakazam") ``` ## Infer targeting model (substitution and mutability) The function for inferring substitution rates (`createSubstitutionMatrix`) counts the number of mutations from a given base to all others occurring in the center position for all 5-mer motifs in the dataset. The `model` argument of `createSubstitutionMatrix` allows the user to specify whether to count all mutations, or just silent mutations to infer the model. Column names for the sample sequence, germline sequence, and V call can also be passed in as parameters if they differ from Change-O defaults. Additionally, the `multipleMutation` parameter determines handling of multiple mutations in a single 5-mer: `independent` treats each mutation independently and `ignore` entirely disregards 5-mers with multiple mutations. The function for inferring a mutability model (`createMutabilityMatrix`) counts the number of mutations in all 5-mer motifs of the dataset, and depends upon the inferred substitution rates. Furthermore, the same parameters available for inferring the substitution rates are also available to adjust this function. The inferred substitution and mutability matrices returned by the above functions only account for unambiguous 5-mers. However, there may be cases in which the user may need the likelihood of a mutation in a 5-mer with ambiguous characters. Each of the above functions has a corresponding function (`extendSubstitutionMatrix` and `extendMutabilityMatrix`) to extend the matrix to infer 5-mers with Ns by averaging over all corresponding unambiguous 5-mers. These extended substitution and mutability matrices can be used to create an overall SHM targeting matrix (`createTargetingMatrix`), which is the combined probability of mutability and substitution. ```{r, eval=FALSE} # Create substitution model using silent mutations sub_matrix <- createSubstitutionMatrix(ExampleDb, model="S") # Create mutability model using silent mutations mut_matrix <- createMutabilityMatrix(ExampleDb, sub_matrix, model="S") # Extend models to include ambiguous 5-mers sub_matrix <- extendSubstitutionMatrix(sub_matrix) mut_matrix <- extendMutabilityMatrix(mut_matrix) # Create targeting model matrix from substitution and mutability matrices tar_matrix <- createTargetingMatrix(sub_matrix, mut_matrix) ``` All of the above steps can be combined by using the single function `createTargetingModel` to infer a `TargetingModel` object directly from the dataset. Additionally, it is generally appropriate to consider the mutations within a clone only once. Consensus sequences for each clone can be generated using the `collapseClones` function. ```{r, eval=TRUE, warning=FALSE} # Collapse sequences into clonal consensus clone_db <- collapseClones(ExampleDb, nproc=1) # Create targeting model in one step using only silent mutations # Use consensus sequence input and germline columns model <- createTargetingModel(clone_db, model="S", sequenceColumn="CLONAL_SEQUENCE", germlineColumn="CLONAL_GERMLINE") ``` ## Visualize targeting model The visualization of a dataset's underlying SHM mutability model can be used to investigate hot and cold spot motifs. The length of the bars on the plot of mutability rates corresponds to the likelihood of a given base in the given 5-mer being mutated. The plotting function `plotMutability` has an argument `style` to specify either a hedgehog plot (circlular) or barplot diplay of 5-mer mutability rates. If the mutability for only specific bases is required, this can be specified via the `nucleotides` argument. ```{r, eval=TRUE, warning=FALSE, fig.width=7, fig.height=7.5} # Generate hedgehog plot of mutability model plotMutability(model, nucleotides="A", style="hedgehog") plotMutability(model, nucleotides="C", style="hedgehog") ``` ```{r, eval=TRUE, warning=FALSE, fig.width=7, fig.height=4.5} # Generate bar plot of mutability model plotMutability(model, nucleotides="G", style="bar") plotMutability(model, nucleotides="T", style="bar") ``` ## Calculate targeting distance matrix In the Change-O pipeline, the `hs5f` cloning method rely on an inferred targeting model. If users wish to use a targeting model inferred from their data to assign distance between sequences for clonal grouping, then the observed SHM targeting rates must be transformed into distances. The `calcTargetingDistance` function returns a matrix of distances between each 5-mer and each corresponding mutation of the center base. This matrix can also be generated and written directly to a file using the function `writeTargetingDistance`. ```{r, eval=TRUE, warning=FALSE} # Calculate distance matrix dist <- calcTargetingDistance(model) ``` shazam/vignettes/Shmulate-Vignette.Rmd0000644000176200001440000001336613575255254017604 0ustar liggesusers--- title: 'Shazam: Simulating sequence mutations' author: "Julian Q. Zhou" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 5 fig_width: 7.5 highlight: pygments toc: yes html_document: fig_height: 5 fig_width: 7.5 highlight: pygments theme: readable toc: yes md_document: fig_height: 5 fig_width: 7.5 preserve_yaml: no toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Simulating sequence mutations} %\usepackage[utf8]{inputenc} --- `SHazaM` provides two functions for simulating mutated sequences, one at the sequence level (`shmulateSeq`), and the other at the lineage level (`shmulateTree`). Both functions rely on a 5-mer targeting model for computing the probabilities of mutations at each position along the input sequence. The 5-mer targeting models currently availbale in `SHazaM` are: * `HH_S5F`: Human Heavy chain, Silent, 5-mer, Functional targeting model * `HKL_S5F`: Human Kappa and Lambda light chain, Silent, 5-mer, Functional targeting model * `MK_RS5NF`: Mouse Kappa light chain, Replacement and Silent, 5-mer, Non-Functional targeting model * `U5N`: Uniform 5-mer Null targeting model ## Simulate mutations in a single sequence `shmulateSeq` generates random mutations in an input sequence. This sequence is provided by the user as a string, with the acceptable alphabet being `{A, T, G, C, N, .}`. Note that `-` is not accepted as part of the input sequence. If the input sequence has a non-triplet overhang at the end, it will be trimmed to the last codon. For example, `ATGCATGC` will be trimmed to `ATGCAT` before mutations are introduced. The total number of mutations to be introduced is user-specified. Mutations are not introduced to positions in the input sequence that contain `.` or `N`. Mutations are introduced iteratively using a targeting model. Targeting probabilities at each position are updated after each iteration. ```{r, eval=TRUE, warning=FALSE, message=FALSE} library(shazam) # Input sequence sequence <- "NGATCTGACGACACGGCCGTGTATTACTGTGCGAGAGATA.TTTA" # Simulate introduction of 6 mutations using the default HH_S5F targeting model shmulateSeq(sequence, numMutations=6) # Simulate introduction of 4 mutations using the MK_RS5NF targeting model shmulateSeq(sequence, numMutations=4, targetingModel=MK_RS5NF) ``` ## Simulate mutations in a lineage tree `shmulateTree` generates a set of simulated sequences based on an input sequence and a lineage tree. The input sequence will act as the most recent common ancestor (MRCA) of the lineage tree, and sequences in the offspring nodes will be simulated with the numbers of mutations corresponding to the edge weights of the tree. The lineage tree is supplied by the user as an `igraph` object, such as that returned by `buildPhylipLineage` of the `alakazam` package. For details, see the `Reconstruction of Ig lineage trees` vignette of `alakazam`. It is assumed that the `name` vertex attribute of the root node is `Germline`, as is the case with the trees built by `buildPhylipLineage`. ```{r, eval=TRUE, warning=FALSE, message=FALSE} library(alakazam) library(shazam) library(igraph) # Load example lineage data(ExampleTrees, package="alakazam") graph <- ExampleTrees[[17]] # Input sequence to be used as MRCA of the lineage tree sequence <- "NGATCTGACGACACGGCCGTGTATTACTGTGCGAGAGATAGTTTA" # Simulate using the default HH_S5F targeting model shmulateTree(sequence, graph) ``` It is possible to exclude certain specified nodes from being considered as the MRCA and from being included as part of the simulation. To specify such nodes, use the `field` argument to indicate which annotation field in `vertex_attr(graph)` contains information relevant to deciding which nodes to exclude, and the `exclude` argument to indicate the value in the annotation field that nodes to be excluded carry. Note that when excluding some nodes, additional nodes that have not been explicitly specified by the user to be excluded may also get excluded. For example, suppose that node B is an offspring of node A; and node A has been specified by the user to be excluded. As a corollary of node A being excluded, its offspring node B will also become excluded, despite not being specified explicitly. ```{r, eval=TRUE, warning=FALSE} # The annotation field called "SAMPLE" vertex_attr(graph)$SAMPLE # notice that node "GN5SHBT01AKANC" is an offspring of "Inferred1" par(mar=c(0, 0, 0, 0) + 0.1) plot(graph, layout=layout_as_tree, edge.arrow.mode=0, vertex.label.cex=0.75) # Exclude nodes without a sample identifier # The nodes "Germline" and "Inferred1" are thus excluded # As a corollary, "GN5SHBT01AKANC", the offspring of "Inferred1", is also excluded # In this case, "GN5SHBT07JDYW5" is then taken to be the MRCA shmulateTree(sequence, graph, field="SAMPLE", exclude=NA) ``` It is also possible to add a proportional number of mutations to the immediate offsprings of the MRCA based on the fraction of the nucleotide sequence that is within the junction region. This is achieved via the optional `junctionWeight` argument, to be supplied as a numeric value between `0` and `1`. As an exmample, suppose that the MRCA has two immediate offsprings, each containing 2 and 4 mutations respectively compared to the MRCA. With `junctionWeight=0.2`, the number of mutations to be introduced to these two offsprings will become `round(2*(1+0.2))` (2) and `round(4*(1+0.2))` (5) respectively. ```{r, eval=TRUE, warning=FALSE} # The "Inferred1" node is taken to be the MRCA and has 2 immediate offsprings par(mar=c(0, 0, 0, 0) + 0.1) plot(graph, layout=layout_as_tree, edge.arrow.mode=0, vertex.label.cex=0.75) # Add 20% mutation rate to the immediate offsprings of the MRCA shmulateTree(sequence, graph, junctionWeight=0.2) ``` shazam/vignettes/DistToNearest-Vignette.Rmd0000644000176200001440000003174113575255254020547 0ustar liggesusers--- title: 'Shazam: Tuning clonal assignment thresholds with nearest neighbor distances' author: "Namita Gupta, Susanna Marquez and Nima Nouri" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4 fig_width: 7.5 highlight: pygments toc: yes html_document: fig_height: 4 fig_width: 7.5 highlight: pygments theme: readable toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Distance to nearest neighbor} %\usepackage[utf8]{inputenc} --- Estimating the optimal distance threshold for partitioning clonally related sequences is accomplished by calculating the distance from each sequence in the data set to its nearest neighbor and finding the break point in the resulting bi-modal distribution that separates clonally related from unrelated sequences. This is done via the following steps: 1. Calculating of the nearest neighbor distances for each sequence. 2. Generating a histogram of the nearest neighbor distances followed by either manual inspect for the threshold separating the two modes or automated threshold detection. ## Example data A small example Change-O database is included in the `alakazam` package. Calculating the nearest neighbor distances requires the following fields (columns) to be present in the Change-O database: * `SEQUENCE_ID` * `V_CALL` * `J_CALL` * `JUNCTION` * `JUNCTION_LENGTH` ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Subset example data to one sample library(shazam) data(ExampleDb, package="alakazam") ``` ## Calculating nearest neighbor distances The function for calculating distance between every sequence and its nearest neighbor takes a few parameters to adjust how the distance is measured. If a genotype has been inferred using the methods in the `tigger` package, and a `V_CALL_GENOTYPED` field has been added to the database, then this column may be used instead of the default `V_CALL` column by specifying the `vCallColumn` argument. This will allows the more accurate V call from `tigger` to be used for grouping of the sequences. Furthermore, for more leniency toward ambiguous V(D)J segment calls, the parameter `first` can be set to `FALSE`. Setting `first=FALSE` will use the union of all possible genes to group sequences, rather than the first gene in the field. The `model` parameter determines which underlying SHM model is used to calculate the distance. The default model is single nucleotide Hamming distance with gaps considered as a match to any nucleotide (`ham`). Other options include a human Ig-specific single nucleotide model similar to a transition/transversion model (`hh_s1f`) and the corresponding 5-mer context model from Yaari et al, 2013 (`hh_s5f`), an analogous pair of mouse specific models from Cui et al, 2016 (`mk_rs1nf` and `mk_rs5nf`), and amino acid Hamming distance (`aa`). **Note:** Human and mouse distance measures that are backward compatible with SHazaM v0.1.4 and Change-O v0.3.3 are also provide as `hs1f_compat` and `m1n_compat`, respectively. For models that are not symmetric (e.g., distance from A to B is not equal to the distance from B to A), there is a `symmetry` parameter that allows the user to specify whether the average or minimum of the two distances is used to determine the overall distance. ```{r, eval=TRUE, warning=FALSE} # Use nucleotide Hamming distance and normalize by junction length dist_ham <- distToNearest(ExampleDb, vCallColumn="V_CALL_GENOTYPED", model="ham", normalize="len", nproc=1) # Use genotyped V assignments, a 5-mer model and no normalization dist_s5f <- distToNearest(ExampleDb, vCallColumn="V_CALL_GENOTYPED", model="hh_s5f", normalize="none", nproc=1) ``` ## Using nearest neighbor distances to determine clonal assignment thresholds The primary use of the distance to nearest calculation in SHazaM is to determine the optimal threshold for clonal assignment using the `DefineClones` tool in Change-O. Defining a threshold relies on distinguishing clonally related sequences (represented by sequences with close neighbors) from singletons (sequences without close neighbors), which show up as two modes in a nearest neighbor distance histogram. Thresholds may be manually determined by inspection of the nearest neighbor histograms or by using one of the automated threshold detection algorithms provided by the `findThreshold` function. The available methods are `density` (smoothed density) and `gmm` (gamma/Guassian mixture model), and are chosen via the `method` parameter of `findThreshold`. ### Threshold determination by manual inspection Manual threshold detection simply involves generating a histrogram for the values in the `DIST_NEAREST` column of the `distToNearest` output and selecting a suitable value within the valley between the two modes. ```{r, eval=TRUE, warning=FALSE, fig.width=7} # Generate Hamming distance histogram library(ggplot2) p1 <- ggplot(subset(dist_ham, !is.na(DIST_NEAREST)), aes(x=DIST_NEAREST)) + theme_bw() + xlab("Hamming distance") + ylab("Count") + scale_x_continuous(breaks=seq(0, 1, 0.1)) + geom_histogram(color="white", binwidth=0.02) + geom_vline(xintercept=0.12, color="firebrick", linetype=2) plot(p1) ``` By manual inspection, the length normalized `ham` model distance threshold would be set to a value near 0.12 in the above example. ```{r, eval=TRUE, warning=FALSE, fig.width=7} # Generate HH_S5F distance histogram p2 <- ggplot(subset(dist_s5f, !is.na(DIST_NEAREST)), aes(x=DIST_NEAREST)) + theme_bw() + xlab("HH_S5F distance") + ylab("Count") + scale_x_continuous(breaks=seq(0, 50, 5)) + geom_histogram(color="white", binwidth=1) + geom_vline(xintercept=7, color="firebrick", linetype=2) plot(p2) ``` In this example, the unnormalized `hh_s5f` model distance threshold would be set to a value near 7. ### Automated threshold detection via smoothed density The `density` method will look for the minimum in the valley between two modes of a smoothed distribution based on the input vector (`distances`), which will generally be the `DIST_NEAREST` column from the `distToNearest` output. Below is an example of using the `density` method for threshold detection. ```{r, eval=TRUE, warning=FALSE, fig.width=7} # Find threshold using density method output <- findThreshold(dist_ham$DIST_NEAREST, method="density") threshold <- output@threshold # Plot distance histogram, density estimate and optimum threshold plot(output, title="Density Method") # Print threshold print(output) ``` ### Automated threshold detection via a mixture model The `findThreshold` function includes approaches for automatically determining a clonal assignment threshold. The `"gmm"` method (gamma/Gaussian mixture method) of `findThreshold` (`method="gmm"`) performs a maximum-likelihood fitting procedure over the distance-to-nearest distribution using one of four combinations of univariate density distribution functions: `"norm-norm"` (two Gaussian distributions), `"norm-gamma"` (lower Guassian and upper gamma distribution), `"gamma-norm"` (lower gamm and upper Guassian distribution), and `"gamma-gamma"` (two gamma distributions). By default, the threshold will be selected by calculating the distance at which the average of sensitivity and specificity reaches its maximum (`cutoff="optimal"`). Alternative threshold selection criteria are also providing, including the curve intersection (`cutoff="intersect"`), user defined sensitivity (`cutoff="user", sen=x`), or user defined specificity (`cutoff="user", spc=x`) In the example below the mixture model method (`method="gmm"`) is used to find the optimal threshold for separating clonally related sequences by fitting two gamma distributions (`model="gamma-gamma"`). The red dashed-line shown in figure below defines the distance where the average of the sensitivity and specificity reaches its maximum. ```{r, eval=TRUE, warning=FALSE, fig.width=7} # Find threshold using gmm method output <- findThreshold(dist_ham$DIST_NEAREST, method="gmm", model="gamma-gamma") # Plot distance histogram, Gaussian fits, and optimum threshold plot(output, binwidth=0.02, title="GMM Method: gamma-gamma") # Print threshold print(output) ``` **Note:** The shape of histogram plotted by `plotGmmThreshold` is governed by the `binwidth` parameter. Meaning, any change in bin size will change the form of the distribution, while the `gmm` method is completely bin size independent and only engages the real input data. ## Calculating nearest neighbor distances independently for subsets of data The `fields` argument to `distToNearest` will split the input `data.frame` into groups based on values in the specified fields (columns) and will treat them independently. For example, if the input data has multiple samples, then `fields="SAMPLE"` would allow each sample to be analyzed separately. In the previous examples we used a subset of the original example data. In the following example, we will use the two available samples, `-1h` and `+7d`, and will set `fields="SAMPLE"`. This will reproduce previous results for sample `-1h` and add results for sample `+7d`. ```{r fields, eval=TRUE, warning=FALSE} dist_fields <- distToNearest(ExampleDb, model="ham", normalize="len", fields="SAMPLE", nproc=1) ``` We can plot the nearest neighbor distances for the two samples: ```{r, eval=TRUE, warning=FALSE, fig.width=7} # Generate grouped histograms p4 <- ggplot(subset(dist_fields, !is.na(DIST_NEAREST)), aes(x=DIST_NEAREST)) + theme_bw() + xlab("Grouped Hamming distance") + ylab("Count") + geom_histogram(color="white", binwidth=0.02) + geom_vline(xintercept=0.12, color="firebrick", linetype=2) + facet_grid(SAMPLE ~ ., scales="free_y") plot(p4) ``` In this case, the threshold selected for `-1h` seems to work well for `+7d` as well. ## Calculating nearest neighbor distances across groups rather than within a groups Specifying the `cross` argument to `distToNearest` forces distance calculations to be performed across groups, such that the nearest neighbor of each sequence will always be a sequence in a different group. In the following example we set `cross="SAMPLE"`, which will group the data into `-1h` and `+7d` sample subsets. Thus, nearest neighbor distances for sequences in sample `-1h` will be restricted to the closest sequence in sample `+7d` and vice versa. ```{r cross, eval=TRUE, warning=FALSE} dist_cross <- distToNearest(ExampleDb, model="ham", first=FALSE, normalize="len", cross="SAMPLE", nproc=1) ``` ```{r, eval=TRUE, warning=FALSE, fig.width=7} # Generate cross sample histograms p5 <- ggplot(subset(dist_cross, !is.na(CROSS_DIST_NEAREST)), aes(x=CROSS_DIST_NEAREST)) + theme_bw() + xlab("Cross-sample Hamming distance") + ylab("Count") + geom_histogram(color="white", binwidth=0.02) + geom_vline(xintercept=0.12, color="firebrick", linetype=2) + facet_grid(SAMPLE ~ ., scales="free_y") plot(p5) ``` This can provide a sense of overlap between samples or a way to compare within-sample variation to cross-sample variation. ## Speeding up pairwise-distance-matrix calculations with subsampling The `subsample` option in `distToNearest` allows to speed up calculations and reduce memory usage. If there are very large groups of sequences that share V call, J call and junction length, `distToNearest` will need a lot of memory and it will take a long time to calculate all the distances. Without subsampling, in a large group of n=70,000 sequences `distToNearest` calculates a n\*n distance matrix. With subsampling, e.g. to s=15,000, the distance matrix for the same group has size s\*n, and for each sequence in `db`, the distance value is calculated by comparing the sequence to the subsampled sequences from the same V-J-junction length group. ```{r subsample, eval=TRUE, warning=FALSE} # Explore V-J-junction length groups sizes to use subsample # Show the size of the largest groups library(dplyr) library(alakazam) top_10_sizes <- ExampleDb %>% group_by(JUNCTION_LENGTH) %>% # group by junction length do(alakazam::groupGenes(., first=TRUE)) %>% # group by V and J call mutate(GROUP_ID=paste(JUNCTION_LENGTH,VJ_GROUP, sep="_")) %>% # Create group ids based on junction length and VJ calls ungroup() %>% group_by(GROUP_ID) %>% # group by GROUP_ID distinct(JUNCTION) %>% # for each group, we want to count unique junctions, so keep distinct summarize(SIZE=n()) %>% # get the size of the group, the number of sequences arrange(desc(SIZE)) %>% # sort by decreasing size select(SIZE) %>% top_n(10) # show the top 10 top_10_sizes # Use 30 to subsample # NOTE. This is a toy example. To use 30 with real data # is probably not a good choice. dist <- distToNearest(ExampleDb, vCallColumn="V_CALL_GENOTYPED", model="ham", first=FALSE, normalize="len", subsample = 30) ``` shazam/R/0000755000176200001440000000000013616575575011762 5ustar liggesusersshazam/R/MutationDefinitions.R0000644000176200001440000001700113402556553016064 0ustar liggesusers# Class definitions for mutation classes #' @include Shazam.R NULL #### Classes #### #' S4 class defining replacement and silent mutation definitions #' #' \code{MutationDefinition} defines a common data structure for defining the whether #' a mutation is annotated as a replacement or silent mutation. #' #' @slot name name of the MutationDefinition. #' @slot description description of the model and its source. #' @slot classes named character vectors with single-letter amino acid codes as names #' and amino acid classes as values, with \code{NA} assigned to set of #' characters \code{c("X", "*", "-", ".")}. Replacement (R) is be #' defined as a change in amino acid class and silent (S) as no #' change in class. #' @slot codonTable matrix of codons (columns) and substitutions (rows). #' @slot citation publication source. #' #' @seealso #' See \link{MUTATION_SCHEMES} for a set of predefined \code{MutationDefinition} objects. #' #' @name MutationDefinition-class #' @rdname MutationDefinition-class #' @aliases MutationDefinition #' @exportClass MutationDefinition setClass("MutationDefinition", slots=c(name="character", description="character", classes="character", codonTable="matrix", citation="character")) #### Builder functions #### # Create all codons one mutation away from input codon. # # All codons one mutation away from the input codon are generated. # # @param codon starting codon to which mutations are added # @return a vector of codons. allCodonMuts <- function(codon) { codon_char <- seqinr::s2c(codon) matCodons <- t(array(codon_char, dim=c(3,12))) matCodons[1:4, 1] <- NUCLEOTIDES[1:4] matCodons[5:8, 2] <- NUCLEOTIDES[1:4] matCodons[9:12,3] <- NUCLEOTIDES[1:4] return(apply(matCodons, 1, seqinr::c2s)) } # Generate codon table # # First generates all informative codons and determines types of mutations. # Next generates uninformative codons (having either an N or a gap "-" # character) and sets the mutation type as NA. # # @param aminoAcidClasses vector of amino acid trait classes # if NULL then R or S is determined by amino acid identity # @return matrix with all codons as row and column names and the type of mutation as # the corresponding value in the matrix. # @examples # library(alakazam) # hydropathy <- list(hydrophobic=c("A", "I", "L", "M", "F", "W", "V"), # hydrophilic=c("R", "N", "D", "C", "Q", "E", "K"), # neutral=c("G", "H", "P", "S", "T", "Y")) # chars <- unlist(hydropathy, use.names=FALSE) # classes <- setNames(translateStrings(chars, hydropathy), chars) # computeCodonTable(aminoAcidClasses=classes) computeCodonTable <- function(aminoAcidClasses=NULL) { # Initialize empty data.frame codon_table <- as.data.frame(matrix(NA, ncol=64, nrow=12)) # Pre-compute every codon counter <- 1 for(pOne in NUCLEOTIDES[1:4]) { for(pTwo in NUCLEOTIDES[1:4]) { for(pThree in NUCLEOTIDES[1:4]) { codon <- paste0(pOne, pTwo, pThree) colnames(codon_table)[counter] <- codon counter <- counter + 1 all_muts <- allCodonMuts(codon) codon_table[, codon] <- sapply(all_muts, function(x) { mutType = mutationType(x, codon, aminoAcidClasses=aminoAcidClasses) mutType = names(mutType)[which(mutType>0)] # does not support ambiguous characters # assumes that only 1 entry (R/S/Stop/na) from mutationType is non-zero/1 stopifnot(length(mutType)==1) if (mutType=="na") {mutType=NA} return(mutType) }) } } } # Set codons with N or . to be NA chars <- c("N","A","C","G","T", ".") for(n1 in chars) { for(n2 in chars) { for(n3 in chars) { if(n1=="N" | n2=="N" | n3=="N" | n1=="." | n2=="." | n3==".") { codon_table[, paste0(n1, n2, n3)] <- rep(NA, 12) } } } } return(as.matrix(codon_table)) } #' Creates a MutationDefinition #' #' \code{createMutationDefinition} creates a \code{MutationDefinition}. #' #' @param name name of the mutation definition. #' @param classes named character vectors with single-letter amino acid codes as names #' and amino acid classes as values, with \code{NA} assigned to set of #' characters \code{c("X", "*", "-", ".")}. Replacement (R) is be #' defined as a change in amino acid class and silent (S) as no #' change in class. #' @param description description of the mutation definition and its source data. #' @param citation publication source. #' #' @return A \code{MutationDefinition} object. #' #' @seealso See \link{MutationDefinition} for the return object. #' #' @examples #' # Define hydropathy classes #' library(alakazam) #' hydropathy <- list(hydrophobic=c("A", "I", "L", "M", "F", "W", "V"), #' hydrophilic=c("R", "N", "D", "C", "Q", "E", "K"), #' neutral=c("G", "H", "P", "S", "T", "Y")) #' chars <- unlist(hydropathy, use.names=FALSE) #' classes <- setNames(translateStrings(chars, hydropathy), chars) #' #' # Create hydropathy mutation definition #' md <- createMutationDefinition("Hydropathy", classes) #' #' @export createMutationDefinition <- function(name, classes, description="", citation="") { # Build the codon table codonTable <- computeCodonTable(aminoAcidClasses=classes) # Define MutationDefinition object md <- new("MutationDefinition", name=name, description=description, classes=classes, codonTable=codonTable, citation=citation) return(md) } #### Data #### #' Amino acid mutation definitions #' #' Definitions of replacement (R) and silent (S) mutations for different amino acid #' physicochemical classes. #' #' @format A \link{MutationDefinition} object defining: #' \itemize{ #' \item \code{CHARGE_MUTATIONS}: Amino acid mutations are defined by changes #' in side chain charge class. #' \item \code{HYDROPATHY_MUTATIONS}: Amino acid mutations are defined by changes #' in side chain hydrophobicitity class. #' \item \code{POLARITY_MUTATIONS}: Amino acid mutations are defined by changes #' in side chain polarity class. #' \item \code{VOLUME_MUTATIONS}: Amino acid mutations are defined by changes #' in side chain volume class. #' } #' #' @references #' \enumerate{ #' \item \url{http://www.imgt.org/IMGTeducation/Aide-memoire/_UK/aminoacids/IMGTclasses.html} #' } #' #' @name MUTATION_SCHEMES NULL #' @name CHARGE_MUTATIONS #' @rdname MUTATION_SCHEMES NULL #' @name HYDROPATHY_MUTATIONS #' @rdname MUTATION_SCHEMES NULL #' @name POLARITY_MUTATIONS #' @rdname MUTATION_SCHEMES NULL #' @name VOLUME_MUTATIONS #' @rdname MUTATION_SCHEMES NULL shazam/R/Baseline.R0000644000176200001440000027031513575255254013630 0ustar liggesusers# Selection analysis using BASELINe #' @include RegionDefinitions.R #' @include Shazam.R NULL #### Classes #### #' S4 class defining a BASELINe (selection) object #' #' \code{Baseline} defines a common data structure the results of selection #' analysis using the BASELINe method. #' #' @slot description \code{character} providing general information regarding the #' sequences, selection analysis and/or object. #' @slot db \code{data.frame} containing annotation information about #' the sequences and selection results. #' @slot regionDefinition \link{RegionDefinition} object defining the regions #' and boundaries of the Ig sequences. #' @slot testStatistic \code{character} indicating the statistical framework #' used to test for selection. For example, \code{"local"} or #' \code{"focused"}. #' @slot regions \code{character} vector defining the regions the BASELINe #' analysis was carried out on. For \code{"CDR"} and \code{"FWR"} #' or \code{"CDR1"}, \code{"CDR2"}, \code{"CDR3"}, etc. #' @slot numbOfSeqs \code{matrix} of dimensions \code{r x c} containing the number of #' sequences or PDFs in each region, where:\cr #' \code{r} = number of rows = number of groups or sequences.\cr #' \code{c} = number of columns = number of regions. #' @slot binomK \code{matrix} of dimensions \code{r x c} containing the number of #' successes in the binomial trials in each region, where:\cr #' \code{r} = number of rows = number of groups or sequences.\cr #' \code{c} = number of columns = number of regions. #' @slot binomN \code{matrix} of dimensions \code{r x c} containing the total #' number of trials in the binomial in each region, where:\cr #' \code{r} = number of rows = number of groups or sequences.\cr #' \code{c} = number of columns = number of regions. #' @slot binomP \code{matrix} of dimensions \code{r x c} containing the probability #' of success in one binomial trial in each region, where:\cr #' \code{r} = number of rows = number of groups or sequences.\cr #' \code{c} = number of columns = number of regions. #' @slot pdfs \code{list} of matrices containing PDFs with one item for each #' defined region (e.g. "CDR" and "FWR"). Matrices have dimensions #' \code{r x c} dementions, where:\cr #' \code{r} = number of rows = number of sequences or groups. \cr #' \code{c} = number of columns = length of the PDF (default 4001). #' @slot stats \code{data.frame} of BASELINe statistics, #' including: mean selection strength (mean Sigma), 95\% confidence #' intervals, and p-values with positive signs for the presence of #' positive selection and/or p-values with negative signs for the #' presence of negative selection. #' #' @name Baseline-class #' @rdname Baseline-class #' @aliases Baseline #' @exportClass Baseline #' @seealso See \link{summarizeBaseline} for more information on \code{@stats}. setClass("Baseline", slots=c(description="character", db="data.frame", regionDefinition="RegionDefinition", testStatistic="character", regions="character", numbOfSeqs="matrix", binomK="matrix", binomN="matrix", binomP="matrix", pdfs="list", stats="data.frame")) #### Methods ##### #' @param x \code{Baseline} object. #' @param y name of the column in the \code{db} slot of \code{baseline} #' containing primary identifiers. #' @param ... arguments to pass to \link{plotBaselineDensity}. #' #' @rdname Baseline-class #' @aliases Baseline-method #' @export setMethod("plot", c(x="Baseline", y="character"), function(x, y, ...) { plotBaselineDensity(x, y, ...) }) #' @param object \code{Baseline} object. #' @param nproc number of cores to distribute the operation over. #' #' @rdname Baseline-class #' @aliases Baseline-method #' @export setMethod("summary", c(object="Baseline", nproc=integer()), function(object, nproc=1) { summarizeBaseline(object, returnType="df", nproc=nproc) }) #### Accessory functions ##### #' Creates a Baseline object #' #' \code{createBaseline} creates and initialize a \code{Baseline} object. #' #' @param description \code{character} providing general information regarding the #' sequences, selection analysis and/or object. #' @param db \code{data.frame} containing annotation information about #' the sequences and selection results. #' @param regionDefinition \link{RegionDefinition} object defining the regions #' and boundaries of the Ig sequences. #' @param testStatistic \code{character} indicating the statistical framework #' used to test for selection. For example, \code{"local"} or #' \code{"focused"} or \code{"imbalanced"}. #' @param regions \code{character} vector defining the regions the BASELINe #' analysis was carried out on. For \code{"CDR"} and \code{"FWR"} #' or \code{"CDR1"}, \code{"CDR2"}, \code{"CDR3"}, etc. If \code{NULL} #' then regions will be determined automatically from \code{regionDefinition}. #' @param numbOfSeqs \code{matrix} of dimensions \code{r x c} containing the number of #' sequences or PDFs in each region, where:\cr #' \code{r} = number of rows = number of groups or sequences.\cr #' \code{c} = number of columns = number of regions. #' @param binomK \code{matrix} of dimensions \code{r x c} containing the number of #' successes in the binomial trials in each region, where:\cr #' \code{r} = number of rows = number of groups or sequences.\cr #' \code{c} = number of columns = number of regions. #' @param binomN \code{matrix} of dimensions \code{r x c} containing the total #' number of trials in the binomial in each region, where:\cr #' \code{r} = number of rows = number of groups or sequences.\cr #' \code{c} = number of columns = number of regions. #' @param binomP \code{matrix} of dimensions \code{r x c} containing the probability #' of success in one binomial trial in each region, where:\cr #' \code{r} = number of rows = number of groups or sequences.\cr #' \code{c} = number of columns = number of regions. #' @param pdfs \code{list} of matrices containing PDFs with one item for each #' defined region (e.g. "CDR" and "FWR"). Matrices have dimensions #' \code{r x c} dementions, where:\cr #' \code{r} = number of rows = number of sequences or groups. \cr #' \code{c} = number of columns = length of the PDF (default 4001). #' @param stats \code{data.frame} of BASELINe statistics, #' including: mean selection strength (mean Sigma), 95\% confidence #' intervals, and p-values with positive signs for the presence of #' positive selection and/or p-values with negative signs for the #' presence of negative selection. #' #' @return A \code{Baseline} object. #' #' @details #' Create and initialize a \code{Baseline} object. #' #' The \code{testStatistic} indicates the statistical framework used to test for selection. #' For example, #' \itemize{ #' \item \code{local} = CDR_R / (CDR_R + CDR_S). #' \item \code{focused} = CDR_R / (CDR_R + CDR_S + FWR_S). #' \item \code{immbalance} = CDR_R + CDR_s / (CDR_R + CDR_S + FWR_S + FWR_R) #' } #' For \code{focused} the \code{regionDefinition} must only contain two regions. If more #' than two regions are defined, then the \code{local} test statistic will be used. #' For further information on the frame of these tests see Uduman et al. (2011). #' #' @seealso See \link{Baseline} for the return object. #' #' @references #' \enumerate{ #' \item Hershberg U, et al. Improved methods for detecting selection by mutation #' analysis of Ig V region sequences. #' Int Immunol. 2008 20(5):683-94. #' \item Uduman M, et al. Detecting selection in immunoglobulin sequences. #' Nucleic Acids Res. 2011 39(Web Server issue):W499-504. #' \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based #' on synonymous mutations from high-throughput immunoglobulin sequencing data. #' Front Immunol. 2013 4(November):358. #' } #' #' @examples #' # Creates an empty Baseline object #' createBaseline() #' #' @export createBaseline <- function(description="", db=data.frame(), regionDefinition=createRegionDefinition(), testStatistic="", regions=NULL, numbOfSeqs=matrix(), binomK=matrix(), binomN=matrix(), binomP=matrix(), pdfs=list(), stats=data.frame()) { if (is.null(regionDefinition)) { regionDefinition <- makeNullRegionDefinition() } # Get regions if not passing in if (is.null(regions)) { regions <- regionDefinition@regions } # Define empty stats data.frame if not passed in if (nrow(stats) == 0) { stats <- data.frame(GROUP=character(), REGION=character(), BASELINE_SIGMA=character(), BASELINE_CI_LOWER=character(), BASELINE_CI_UPPER=character(), BASELINE_CI_PVALUE=character(), stringsAsFactors=FALSE) } # Define RegionDefinition object baseline <- new("Baseline", description=description, db=as.data.frame(db), regionDefinition=regionDefinition, testStatistic=testStatistic, regions=regionDefinition@regions, numbOfSeqs=numbOfSeqs, binomK=binomK, binomN=binomN, binomP=binomP, pdfs=pdfs, stats=as.data.frame(stats)) return(baseline) } #' Edit the Baseline object #' #' \code{editBaseline} edits a field in a \code{Baseline} object. #' #' @param baseline \code{Baseline} object to be edited. #' @param field name of the field in the \code{Baseline} object to be edited. #' @param value value to set the \code{field}. #' #' @return A \code{Baseline} object with the field of choice updated. #' #' @seealso See \link{Baseline} for the input and return object. #' #' @examples #' \donttest{ #' # Subset example data #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE == "IgG" & SAMPLE == "+7d") #' #' # Make Baseline object #' baseline <- calcBaseline(db, #' sequenceColumn="SEQUENCE_IMGT", #' germlineColumn="GERMLINE_IMGT_D_MASK", #' testStatistic="focused", #' regionDefinition=IMGT_V, #' targetingModel=HH_S5F, #' nproc=1) #' #' # Edit the field "description" #' baseline <- editBaseline(baseline, field="description", #' value="+7d IgG") #' } #' #' @export editBaseline <- function(baseline, field, value) { if (!match(field, slotNames(baseline))) { stop(field, " is not part of the Baseline object.") } slot(baseline, field) <- value return(baseline) } #### Calculation functions #### #' Calculate the BASELINe PDFs #' #' \code{calcBaseline} calculates the BASELINe posterior probability density #' functions (PDFs) for sequences in the given Change-O \code{data.frame}. #' #' @param db \code{data.frame} containing sequence data and annotations. #' @param sequenceColumn \code{character} name of the column in \code{db} #' containing input sequences. #' @param germlineColumn \code{character} name of the column in \code{db} #' containing germline sequences. #' @param testStatistic \code{character} indicating the statistical framework #' used to test for selection. One of #' \code{c("local", "focused", "imbalanced")}. #' @param regionDefinition \link{RegionDefinition} object defining the regions #' and boundaries of the Ig sequences. #' @param targetingModel \link{TargetingModel} object. Default is \link{HH_S5F}. #' @param mutationDefinition \link{MutationDefinition} object defining replacement #' and silent mutation criteria. If \code{NULL} then #' replacement and silent are determined by exact #' amino acid identity. Note, if the input data.frame #' already contains observed and expected mutation frequency #' columns then mutations will not be recalculated and this #' argument will be ignored. #' @param calcStats \code{logical} indicating whether or not to calculate the #' summary statistics \code{data.frame} stored in the #' \code{stats} slot of a \link{Baseline} object. #' @param nproc number of cores to distribute the operation over. If #' \code{nproc=0} then the \code{cluster} has already been #' set and will not be reset. #' #' @return A \link{Baseline} object containing the modified \code{db} and BASELINe #' posterior probability density functions (PDF) for each of the sequences. #' #' @details #' Calculates the BASELINe posterior probability density function (PDF) for #' sequences in the provided \code{db}. #' #' \strong{Note}: Individual sequences within clonal groups are not, strictly speaking, #' independent events and it is generally appropriate to only analyze selection #' pressures on an effective sequence for each clonal group. For this reason, #' it is strongly recommended that the input \code{db} contains one effective #' sequence per clone. Effective clonal sequences can be obtained by calling #' the \link{collapseClones} function. #' #' If the \code{db} does not contain the #' required columns to calculate the PDFs (namely MU_COUNT & MU_EXPECTED) #' then the function will: #' \enumerate{ #' \item Calculate the numbers of observed mutations. #' \item Calculate the expected frequencies of mutations and modify the provided #' \code{db}. The modified \code{db} will be included as part of the #' returned \code{Baseline} object. #' } #' #' The \code{testStatistic} indicates the statistical framework used to test for selection. #' E.g. #' \itemize{ #' \item \code{local} = CDR_R / (CDR_R + CDR_S). #' \item \code{focused} = CDR_R / (CDR_R + CDR_S + FWR_S). #' \item \code{imbalanced} = CDR_R + CDR_S / (CDR_R + CDR_S + FWR_S + FRW_R). #' } #' For \code{focused} the \code{regionDefinition} must only contain two regions. If more #' than two regions are defined the \code{local} test statistic will be used. #' For further information on the frame of these tests see Uduman et al. (2011). #' #' @references #' \enumerate{ #' \item Hershberg U, et al. Improved methods for detecting selection by mutation #' analysis of Ig V region sequences. #' Int Immunol. 2008 20(5):683-94. #' \item Uduman M, et al. Detecting selection in immunoglobulin sequences. #' Nucleic Acids Res. 2011 39(Web Server issue):W499-504. #' \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based #' on synonymous mutations from high-throughput immunoglobulin sequencing data. #' Front Immunol. 2013 4(November):358. #' } #' #' @seealso See \link{Baseline} for the return object. #' See \link{groupBaseline} and \link{summarizeBaseline} for further processing. #' See \link{plotBaselineSummary} and \link{plotBaselineDensity} for plotting results. #' #' @examples #' # Load and subset example data #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE == "IgG" & SAMPLE == "+7d") #' #' # Collapse clones #' db <- collapseClones(db, sequenceColumn="SEQUENCE_IMGT", #' germlineColumn="GERMLINE_IMGT_D_MASK", #' method="thresholdedFreq", minimumFrequency=0.6, #' includeAmbiguous=FALSE, breakTiesStochastic=FALSE) #' #' # Calculate BASELINe #' baseline <- calcBaseline(db, #' sequenceColumn="CLONAL_SEQUENCE", #' germlineColumn="CLONAL_GERMLINE", #' testStatistic="focused", #' regionDefinition=IMGT_V, #' targetingModel=HH_S5F, #' nproc=1) #' #' @export calcBaseline <- function(db, sequenceColumn="CLONAL_SEQUENCE", germlineColumn="CLONAL_GERMLINE", testStatistic=c("local", "focused", "imbalanced"), regionDefinition=NULL, targetingModel=HH_S5F, mutationDefinition=NULL, calcStats=FALSE, nproc=1) { # Hack for visibility of foreach index variable idx <- NULL # Evaluate argument choices testStatistic <- match.arg(testStatistic) # Check for valid columns check <- checkColumns(db, c(sequenceColumn, germlineColumn)) if (check != TRUE) { stop(check) } # Check region definition if (!is.null(regionDefinition) & !is(regionDefinition, "RegionDefinition")) { stop(deparse(substitute(regionDefinition)), " is not a valid RegionDefinition object") } # Check mutation definition if (!is.null(mutationDefinition) & !is(mutationDefinition, "MutationDefinition")) { stop(deparse(substitute(mutationDefinition)), " is not a valid MutationDefinition object") } # Check targeting model if (!is(targetingModel, "TargetingModel")) { stop(deparse(substitute(targetingModel)), " is not a valid TargetingModel object") } # Convert sequence columns to uppercase db <- toupperColumns(db, c(sequenceColumn, germlineColumn)) # Ensure that the nproc does not exceed the number of cores/CPUs available nproc <- min(nproc, cpuCount()) # nproc_arg will be passed to any function that has the nproc argument # If the cluster is already being set by the parent function then # this will be set to 'cluster', that way the child function does not close # the connections and reset the cluster. #nproc_arg <- nproc # If user wants to paralellize this function and specifies nproc > 1, then # initialize and register slave R processes/clusters & # export all nesseary environment variables, functions and packages. if (nproc > 1) { cluster <- parallel::makeCluster(nproc, type="PSOCK") parallel::clusterExport(cluster, list('db', 'sequenceColumn', 'germlineColumn', 'testStatistic', 'regionDefinition', 'targetingModel', 'mutationDefinition','calcStats', 'break2chunks', 'PowersOfTwo', 'convolutionPowersOfTwo', 'convolutionPowersOfTwoByTwos', 'weighted_conv', 'calculate_bayesGHelper', 'groupPosteriors', 'fastConv', 'calcBaselineHelper', 'c2s', 's2c', 'words', 'translate', 'calcBaselineBinomialPdf','CONST_I', 'BAYESIAN_FITTED', 'calcObservedMutations','NUCLEOTIDES', 'NUCLEOTIDES_AMBIGUOUS', 'IUPAC2nucs', 'makeNullRegionDefinition', 'getCodonPos','getContextInCodon', 'mutationType', 'AMINO_ACIDS','binMutationsByRegion', 'collapseMatrixToVector','calcExpectedMutations', 'calculateTargeting','HH_S5F','calculateMutationalPaths', 'CODON_TABLE'), envir=environment() ) registerDoParallel(cluster, cores=nproc) #nproc_arg <- cluster } else if (nproc == 1) { # If needed to run on a single core/cpu then, regsiter DoSEQ # (needed for 'foreach' in non-parallel mode) registerDoSEQ() } # If db does not contain the required columns to calculate the PDFs (namely MU_COUNT # & MU_EXPECTED mutations), then the function will: # 1. Calculate the numbers of observed mutations # 2. Calculate the expected frequencies of mutations # After that BASELINe prob. densities can be calcualted per sequence. if (is.null(regionDefinition)) { rd_labels <- makeNullRegionDefinition()@labels observedColumns <- paste0("MU_COUNT_", rd_labels) expectedColumns <- paste0("MU_EXPECTED_", rd_labels) } else { observedColumns <- paste0("MU_COUNT_", regionDefinition@labels) expectedColumns <- paste0("MU_EXPECTED_", regionDefinition@labels) } if (!all(c(observedColumns, expectedColumns) %in% colnames(db))) { # If the germlineColumn & sequenceColumn are not found in the db error and quit if (!all(c(sequenceColumn, germlineColumn) %in% colnames(db))) { stop(paste0("Both ", sequenceColumn, " & ", germlineColumn, " columns need to be present in the db")) } # Calculate the numbers of observed mutations db <- observedMutations(db, sequenceColumn=sequenceColumn, germlineColumn=germlineColumn, regionDefinition=regionDefinition, mutationDefinition=mutationDefinition, frequency=FALSE, combine=FALSE, nproc=0) # Calculate the expected frequencies of mutations db <- expectedMutations(db, sequenceColumn=sequenceColumn, germlineColumn=germlineColumn, regionDefinition=regionDefinition, targetingModel=targetingModel, mutationDefinition=mutationDefinition, nproc=0) } # Calculate PDFs for each sequence # Print status to console cat("Calculating BASELINe probability density functions...\n") # Number of sequences (used in foreach) totalNumbOfSequences <- nrow(db) # The column indexes of the MU_COUNT_ and MU_EXPECTED_ cols_observed <- grep( paste0("MU_COUNT_"), colnames(db) ) cols_expected <- grep( paste0("MU_EXPECTED_"), colnames(db) ) # Exporting additional environment variables and functions needed to run foreach if( nproc!=1 ) { parallel::clusterExport( cluster, list('cols_observed', 'cols_expected'), envir=environment() ) registerDoParallel(cluster) } list_pdfs <- list() list_numbOfSeqs <- list() list_k <- list() list_n <- list() list_p <- list() if (is.null(regionDefinition)) { regions <- makeNullRegionDefinition()@regions } else { regions <- regionDefinition@regions } # For every region (e.g. CDR, FWR etc.) for (region in regions) { # Foreach returns a list of PDFs list_region_pdfs <- foreach(idx=iterators::icount(totalNumbOfSequences)) %dopar% { calcBaselineHelper( observed = db[cols_observed][idx,], expected = db[cols_expected][idx,], region = region, testStatistic = testStatistic, regionDefinition = regionDefinition ) } # Count the number of non NA PDFs list_numbOfSeqs[[region]] <- rep(1,totalNumbOfSequences) #is.na(list_region_pdfs)] <- 0 # Convert the list of the region's PDFs into a matrix mat_pdfs_binom <- do.call( rbind, lapply( list_region_pdfs, function(x) { length(x) <- 4004 return(x) } ) ) #cat(class(mat_pdfs_binom), "\n") # for debugging #cat(dim(mat_pdfs_binom), "\n") # for debugging # IMPORTANT: if input has a single sequence, mat_pdfs_binom (1-row) gets coerced # into a numeric vector without matrix(..., nrow=nrow(mat_pdfs_binom)) list_pdfs[[region]] <- matrix(mat_pdfs_binom[, 1:4001], nrow=nrow(mat_pdfs_binom)) #cat(class(list_pdfs[[region]]), "\n") # for debugging stopifnot(is(list_pdfs[[region]], "matrix")) list_k[[region]] <- mat_pdfs_binom[, 4002] list_n[[region]] <- mat_pdfs_binom[, 4003] list_p[[region]] <- mat_pdfs_binom[, 4004] list_numbOfSeqs[[region]][is.na(list_k[[region]])] <- 0 } # Template for values for the regions mat_template <- matrix( NA, ncol=length(regions), nrow=totalNumbOfSequences, dimnames=list(1:totalNumbOfSequences, regions) ) # numbOfSeqs # This holds the number of non NA sequences numbOfSeqs <- mat_template for(region in regions){ numbOfSeqs[,region] <- list_numbOfSeqs[[region]] } # binomK # This holds the number of exact successin in the binomial trials binomK <- mat_template for(region in regions){ binomK[,region] <- list_k[[region]] } # binomN # This holds the total numbers trials in the binomial binomN <- mat_template for(region in regions){ binomN[,region] <- list_n[[region]] } # binomP # This holds the prob of successin in the binomial trials binomP <- mat_template for(region in regions){ binomP[,region] <- list_p[[region]] } # Create a Baseline object with the above results to return baseline <- createBaseline(description="", db=as.data.frame(db), regionDefinition=regionDefinition, testStatistic=testStatistic, regions=regions, numbOfSeqs=numbOfSeqs, binomK=binomK, binomN=binomN, binomP=binomP, pdfs=list_pdfs ) # Calculate BASELINe stats and update slot if (calcStats==TRUE) { baseline <- summarizeBaseline(baseline) } # Stop cluster if (nproc > 1) { parallel::stopCluster(cluster) } return(baseline) } # Helper function for calcBaseline # # @param observed # @param expected # @param region # @param testStatistic # @param regionDefinition # # @return A modified \link{Baseline} object with the BASELINe probability # density function calculated for the regions defined in the \code{regionDefinition}. calcBaselineHelper <- function(observed, expected, region, testStatistic="local", regionDefinition=NULL) { # Check region definition if (!is.null(regionDefinition) & !is(regionDefinition, "RegionDefinition")) { stop(deparse(substitute(regionDefinition)), " is not a valid RegionDefinition object") } if (is.null(regionDefinition)) { regions <- makeNullRegionDefinition()@regions } else { regions <- regionDefinition@regions } # Evaluate argument choices testStatistic <- match.arg(testStatistic, c("local", "focused", "imbalanced")) #If there are more than two regions (e.g. CDR and FWR then you cannot perform the focused test) if (testStatistic=="focused" & length(regions)!=2) { testStatistic="local" } # local test statistic if (testStatistic == "local") { obsX_Index <- grep( paste0("MU_COUNT_", region,"_R"), names(observed) ) # important to have "_" after region # otherwise this might happen (leading to bugs in results): # region = codon_1 # expect grep to find only codon_1_S and codon_1_R # in fact, however, codon_10_S, codon_10_R, codon_101_S, codon_101_R are matched obsN_Index <- grep( paste0("MU_COUNT_", region, "_"), names(observed) ) expX_Index <- grep( paste0("MU_EXPECTED_", region,"_R"), names(expected) ) # important to have "_" after region expN_Index <- grep( paste0("MU_EXPECTED_", region, "_"), names(expected) ) } # focused test statistic if (testStatistic == "focused") { obsX_Index <- grep( paste0("MU_COUNT_", region,"_R"), names(observed) ) obsN_Index <- grep( paste0( "MU_COUNT_", region, "|", "MU_COUNT_", regions[regions!=region], "_S" ), names(observed) ) expX_Index <- grep( paste0("MU_EXPECTED_", region,"_R"), names(expected) ) expN_Index <- grep( paste0( "MU_EXPECTED_", region, "|", "MU_EXPECTED_", regions[regions!=region], "_S" ), names(expected) ) } # imbalanced test statistic if (testStatistic == "imbalanced") { obsX_Index <- grep( paste0("MU_COUNT_", region), names(observed) ) obsN_Index <- grep( "MU_COUNT_",names(observed)) expX_Index <- grep( paste0("MU_EXPECTED_", region), names(expected) ) expN_Index <- grep( "MU_EXPECTED_",names(expected)) } obsX <- sum(as.numeric( observed[obsX_Index] )) obsN <- sum(as.numeric(observed[obsN_Index]), na.rm=T ) expP <- as.numeric( sum(expected[expX_Index]) / sum( expected[expN_Index], na.rm=T ) ) return( c( calcBaselineBinomialPdf( x=obsX, n=obsN, p=expP ), obsX, obsN, expP ) ) } # Calculate the BASELINe probability function in a binomial framework. calcBaselineBinomialPdf <- function (x=3, n=10, p=0.33, CONST_i=CONST_I, max_sigma=20, length_sigma=4001) { if(n!=0){ sigma_s<-seq(-max_sigma,max_sigma,length.out=length_sigma) sigma_1<-log({CONST_i/{1-CONST_i}}/{p/{1-p}}) index<-min(n,60) y <- dbeta(CONST_i, x+BAYESIAN_FITTED[index], n+BAYESIAN_FITTED[index]-x)*(1-p)*p*exp(sigma_1)/({1-p}^2+2*p*{1-p}*exp(sigma_1)+{p^2}*exp(2*sigma_1)) if (!sum(is.na(y))) { tmp <- approx(sigma_1, y, sigma_s)$y return(tmp / sum(tmp) / (2 * max_sigma / (length_sigma - 1))) } else { return(NA) } } else { return(NA) } } #' Group BASELINe PDFs #' #' \code{groupBaseline} convolves groups of BASELINe posterior probability density #' functions (PDFs) to get combined PDFs for each group. #' #' @param baseline \code{Baseline} object containing the \code{db} and the #' BASELINe posterior probability density functions #' (PDF) for each of the sequences, as returned by #' \link{calcBaseline}. #' @param groupBy The columns in the \code{db} slot of the \code{Baseline} #' object by which to group the sequence PDFs. #' @param nproc number of cores to distribute the operation over. If #' \code{nproc} = 0 then the \code{cluster} has already been #' set and will not be reset. #' #' @return A \link{Baseline} object, containing the modified \code{db} and the BASELINe #' posterior probability density functions (PDF) for each of the groups. #' #' @details #' While the selection strengths predicted by BASELINe perform well on average, #' the estimates for individual sequences can be highly variable, especially when the #' number of mutations is small. #' #' To overcome this, PDFs from sequences grouped by biological or experimental relevance, #' are convolved to from a single PDF for the selection strength. For example, sequences #' from each sample may be combined together, allowing you to compare selection across #' samples. This is accomplished through a fast numerical convolution technique. #' #' @seealso To generate the \link{Baseline} object see \link{calcBaseline}. #' To calculate BASELINe statistics, such as the mean selection strength #' and the 95\% confidence interval, see \link{summarizeBaseline}. #' #' @references #' \enumerate{ #' \item Yaari G, et al. Quantifying selection in high-throughput immunoglobulin #' sequencing data sets. #' Nucleic Acids Res. 2012 40(17):e134. #' (Corrections at http://selection.med.yale.edu/baseline/correction/) #' } #' #' @examples #' \donttest{ #' # Subset example data from alakazam #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE %in% c("IgM", "IgG")) #' #' # Collapse clones #' db <- collapseClones(db, sequenceColumn="SEQUENCE_IMGT", #' germlineColumn="GERMLINE_IMGT_D_MASK", #' method="thresholdedFreq", minimumFrequency=0.6, #' includeAmbiguous=FALSE, breakTiesStochastic=FALSE) #' #' # Calculate BASELINe #' baseline <- calcBaseline(db, #' sequenceColumn="CLONAL_SEQUENCE", #' germlineColumn="CLONAL_GERMLINE", #' testStatistic="focused", #' regionDefinition=IMGT_V, #' targetingModel=HH_S5F, #' nproc=1) #' #' # Group PDFs by sample #' grouped1 <- groupBaseline(baseline, groupBy="SAMPLE") #' sample_colors <- c("-1h"="steelblue", "+7d"="firebrick") #' plotBaselineDensity(grouped1, idColumn="SAMPLE", colorValues=sample_colors, #' sigmaLimits=c(-1, 1)) #' #' # Group PDFs by both sample (between variable) and isotype (within variable) #' grouped2 <- groupBaseline(baseline, groupBy=c("SAMPLE", "ISOTYPE")) #' isotype_colors <- c("IgM"="darkorchid", "IgD"="firebrick", #' "IgG"="seagreen", "IgA"="steelblue") #' plotBaselineDensity(grouped2, idColumn="SAMPLE", groupColumn="ISOTYPE", #' colorElement="group", colorValues=isotype_colors, #' sigmaLimits=c(-1, 1)) #' #' # Collapse previous isotype (within variable) grouped PDFs into sample PDFs #' grouped3 <- groupBaseline(grouped2, groupBy="SAMPLE") #' sample_colors <- c("-1h"="steelblue", "+7d"="firebrick") #' plotBaselineDensity(grouped3, idColumn="SAMPLE", colorValues=sample_colors, #' sigmaLimits=c(-1, 1)) #' } #' @export groupBaseline <- function(baseline, groupBy, nproc=1) { # Hack for visibility of foreach index variables i <- NULL # Ensure that the nproc does not exceed the number of cores/CPUs available nproc <- min(nproc, cpuCount()) # Get indices of unique combinations of field(s) specified by groupBy # unique groups # crucial to use data.frame and assign colnames (esp. when groupBy has length 1) uniqueGroups <- data.frame(unique(baseline@db[, groupBy])) colnames(uniqueGroups) <- groupBy rownames(uniqueGroups) <- NULL # indices # crucial to have simplify=FALSE # (otherwise won't return a list if uniqueClones has length 1) uniqueGroupsIdx <- sapply(1:nrow(uniqueGroups), function(i){ curGroup <- data.frame(uniqueGroups[i, ]) colnames(curGroup) <- groupBy # match for each field curIdx <- sapply(groupBy, function(coln){ baseline@db[, coln]==curGroup[, coln] }, simplify=FALSE) curIdx <- do.call(rbind, curIdx) # intersect to get match across fields curIdx <- which(colSums(curIdx)==length(groupBy)) }, simplify=FALSE) # If user wants to paralellize this function and specifies nproc > 1, then # initialize and register slave R processes/clusters & # export all nesseary environment variables, functions and packages. baseline@db <- data.frame() gc() if (nproc > 1){ cluster <- parallel::makeCluster(nproc, type = "PSOCK") parallel::clusterExport( cluster, list('baseline', 'uniqueGroupsIdx', 'break2chunks', 'PowersOfTwo', 'convolutionPowersOfTwo', 'convolutionPowersOfTwoByTwos', 'weighted_conv', 'calculate_bayesGHelper', 'groupPosteriors', 'fastConv'), envir=environment() ) registerDoParallel(cluster, cores=nproc) } else if (nproc == 1) { # If needed to run on a single core/cpu then, regsiter DoSEQ # (needed for 'foreach' in non-parallel mode) registerDoSEQ() } # Print status to console cat("Grouping BASELINe probability density functions...\n") # Number of total groups numbOfTotalGroups <- length(uniqueGroupsIdx) list_pdfs <- list() regions <- baseline@regions # Initialize numbOfSeqs # This holds the number of non NA sequences numbOfSeqs <- matrix(NA, ncol=length(baseline@regions), nrow=numbOfTotalGroups, dimnames=list(1:numbOfTotalGroups, regions)) templateBinom <- numbOfSeqs # For every region (e.g. CDR, FWR etc.) for (region in regions) { # Group (convolute) all the PDFS and get one single PDF list_region_pdfs <- foreach(i=1:numbOfTotalGroups) %dopar% { idx <- uniqueGroupsIdx[[i]] # Get a matrix (r=numb of sequences/groups * c=4001(i,e. the length of the PDFS)) # Care was taken to make sure that @pdfs[[region]] should be maintained # as a matrix regardless of the number of input sequences (even for a # single-sequence input) # Thus matrix_GroupPdfs should be expected to be maintained as a matrix as # opposed a numeric vector matrix_GroupPdfs <- (baseline@pdfs[[region]])[idx, , drop=FALSE] stopifnot(is(matrix_GroupPdfs, "matrix")) # A list version of list_GroupPdfs <- lapply( 1:nrow(matrix_GroupPdfs), function(rowIndex) { rowVals <- matrix_GroupPdfs[rowIndex, ] if( !all(is.na(rowVals)) ) { matrix_GroupPdfs[rowIndex, ] } }) rm(matrix_GroupPdfs) gc() # Determine the number of sequences that went into creating each of the PDFs # If running groupBaseline for the first time after calcBaseline, then # each PDF should have a numbOfSeqs=1. numbOfSeqs_region <- baseline@numbOfSeqs[idx, region] numbOfSeqs_region <- numbOfSeqs_region[numbOfSeqs_region > 0] if(any(numbOfSeqs_region>0)) { names(numbOfSeqs_region) <- 1:length(numbOfSeqs_region) } list_GroupPdfs <- list_GroupPdfs[!unlist(lapply(list_GroupPdfs, function(x) { any(is.na(x)) }))] list_GroupPdfs <- Filter(Negate(is.null), list_GroupPdfs) numbOfNonNASeqs <- length(list_GroupPdfs) # If all the PDFs in the group are NAs, return a PDF of NAs if (length(list_GroupPdfs) == 0) { return(c(rep(NA, 4001), 0)) } # If all the PDFs in the group have a numbOfSeqs=1 then # call groupPosteriors, which groups PDFs with equal weight if (sum(numbOfSeqs_region) == length(numbOfSeqs_region)) { return(c(groupPosteriors(list_GroupPdfs), numbOfNonNASeqs ) ) } # If all the PDFs in the group different numbOfSeqs then call # combineWeightedPosteriors, which groups PDFs weighted by the number of seqs/PDFs # that went into creating those PDFs if (sum(numbOfSeqs_region) > length(numbOfSeqs_region)) { # sort by number of items len_numbOfSeqs_region <- length(numbOfSeqs_region) sorted_numbOfSeqs_region <- sort(numbOfSeqs_region) rm(numbOfSeqs_region) gc() sorted_list_GroupPdfs <- list() for(newIndex in 1:len_numbOfSeqs_region){ sorted_list_GroupPdfs[[newIndex]] <- list_GroupPdfs[[ as.numeric(names(sorted_numbOfSeqs_region)[newIndex]) ]] } # Group all the PDFs that are created with the equal numbers of seqs/PDFs (i.e. of equal weight) repeat { # Count the numb of PDFs with the same weights table_sorted_numbOfSeqs_region <- table(sorted_numbOfSeqs_region) # Weight of interest (the first in the list) pdfWeight <- names(table_sorted_numbOfSeqs_region[table_sorted_numbOfSeqs_region>1])[1] if(is.na(pdfWeight)) { break } # The corresponding idexes of these PDFs with the same weight indexesOfWeight <- which(sorted_numbOfSeqs_region==pdfWeight) # Convolute these PDFs together list_sameWeightPdfs <- sorted_list_GroupPdfs[indexesOfWeight] updatedPdf <- groupPosteriors(list_sameWeightPdfs) rm(list_sameWeightPdfs) gc() # The new updated weights for this convoluted PDF updatedWeight <- as.numeric(pdfWeight) * length(indexesOfWeight) # remove these from sorted_numbOfSeqs_region & sorted_list_GroupPdfs sorted_numbOfSeqs_region <- sorted_numbOfSeqs_region[-indexesOfWeight] sorted_list_GroupPdfs <- sorted_list_GroupPdfs[-indexesOfWeight] rm(indexesOfWeight) gc() # add the convoluted PDF and its new weight newLength <- length(sorted_numbOfSeqs_region)+1 sorted_numbOfSeqs_region[newLength] <- updatedWeight sorted_list_GroupPdfs[[newLength]] <- updatedPdf rm(updatedWeight) rm(updatedPdf) gc() # sort by number of items len_sorted_numbOfSeqs_region <- length(sorted_numbOfSeqs_region) sorted_numbOfSeqs_region <- sort(sorted_numbOfSeqs_region) names(sorted_numbOfSeqs_region) <- as.character(1:len_sorted_numbOfSeqs_region) list_GroupPdfs <- sorted_list_GroupPdfs sorted_list_GroupPdfs <- list() for(newIndex in 1:len_numbOfSeqs_region){ sorted_list_GroupPdfs[[newIndex]] <- list_GroupPdfs[[ as.numeric(names(sorted_numbOfSeqs_region)[newIndex]) ]] } table_sorted_numbOfSeqs_region <- table(sorted_numbOfSeqs_region) if(sum(table_sorted_numbOfSeqs_region>1)>0){ break } } #return( c( groupPosteriors(sorted_list_GroupPdfs), 10 ) ) # Do pairwise grouping of PDFs based on weight # 1. sort by weights # 2. group the lowest two weighted PDFs # 3. resort, and repeat till you get one PDFs if(length(list_GroupPdfs)>1){ repeat{ updatedPdf <- combineWeightedPosteriors(list_GroupPdfs[[1]], sorted_numbOfSeqs_region[1], list_GroupPdfs[[2]], sorted_numbOfSeqs_region[2]) updatedWeight <- sorted_numbOfSeqs_region[1] + sorted_numbOfSeqs_region[2] # remove these from sorted_numbOfSeqs_region & sorted_list_GroupPdfs sorted_numbOfSeqs_region <- sorted_numbOfSeqs_region[-c(1,2)] sorted_list_GroupPdfs <- sorted_list_GroupPdfs[-c(1,2)] # add the convoluted PDF and its new weight newLength <- length(sorted_numbOfSeqs_region)+1 sorted_numbOfSeqs_region[newLength] <- updatedWeight rm(updatedWeight) sorted_list_GroupPdfs[[newLength]] <- updatedPdf rm(updatedPdf) gc() # sort by number of items len_sorted_numbOfSeqs_region <- length(sorted_numbOfSeqs_region) sorted_numbOfSeqs_region <- sort(sorted_numbOfSeqs_region) names(sorted_numbOfSeqs_region) <- as.character(1:len_sorted_numbOfSeqs_region) list_GroupPdfs <- sorted_list_GroupPdfs sorted_list_GroupPdfs <- list() for(newIndex in 1:len_numbOfSeqs_region){ sorted_list_GroupPdfs[[newIndex]] <- list_GroupPdfs[[ as.numeric(names(sorted_numbOfSeqs_region)[newIndex]) ]] } if(length(list_GroupPdfs)==1){ break } } } return( c( list_GroupPdfs[[1]], as.numeric(sorted_numbOfSeqs_region) ) ) } } # Convert the list of the region's PDFs into a matrix matrix_region_pdfs <- do.call(rbind, lapply(list_region_pdfs, function(x) { length(x) <- 4002 return(x) })) # Normalize and save PDF matrix # Hardcode normalization to max_sigma=20 and sigma_length=4001 pdf_norm <- 2*20 / 4000 pdf_mat <- matrix_region_pdfs[, 1:4001, drop=FALSE] list_pdfs[[region]] <- pdf_mat / rowSums(pdf_mat, na.rm=TRUE) / pdf_norm # Save regions numbOfSeqs[, region] <- matrix_region_pdfs[, 4002] } #colnames(numbOfSeqs) <- paste0("NUMB_SEQUENCES_", colnames(numbOfSeqs)) # Create the db, which will now contain the group information stopifnot(is.data.frame(uniqueGroups)) db <- uniqueGroups # Create a Baseline object with the above results to return baseline <- createBaseline(description="", db=as.data.frame(db), regionDefinition=baseline@regionDefinition, testStatistic=baseline@testStatistic, regions=regions, numbOfSeqs=numbOfSeqs, binomK=templateBinom, binomN=templateBinom, binomP=templateBinom, pdfs=list_pdfs) # Calculate BASELINe stats and update slot baseline <- summarizeBaseline(baseline) # Stop cluster if(nproc > 1) { parallel::stopCluster(cluster) } return(baseline) } #' Calculate BASELINe summary statistics #' #' \code{summarizeBaseline} calculates BASELINe statistics such as the mean selection #' strength (mean Sigma), the 95\% confidence intervals and p-values for the presence of #' selection. #' #' @param baseline \code{Baseline} object returned by \link{calcBaseline} containing #' annotations and BASELINe posterior probability density functions #' (PDFs) for each sequence. #' @param returnType One of \code{c("baseline", "df")} defining whether #' to return a \code{Baseline} object ("baseline") with an updated #' \code{stats} slot or a data.frame ("df") of summary statistics. #' @param nproc number of cores to distribute the operation over. If #' \code{nproc} = 0 then the \code{cluster} has already been #' set and will not be reset. #' #' @return Either a modified \code{Baseline} object or data.frame containing the #' mean BASELINe selection strength, its 95\% confidence intervals, and #' a p-value for the presence of selection. #' #' @details The returned p-value can be either positive or negative. Its magnitude #' (without the sign) should be interpreted as per normal. Its sign indicates #' the direction of the selection detected. A positive p-value indicates positive #' selection, whereas a negative p-value indicates negative selection. #' #' @seealso See \link{calcBaseline} for generating \code{Baseline} objects and #' \link{groupBaseline} for convolving groups of BASELINe PDFs. #' #' @references #' \enumerate{ #' \item Uduman M, et al. Detecting selection in immunoglobulin sequences. #' Nucleic Acids Res. 2011 39(Web Server issue):W499-504. #' } #' #' @examples #' \donttest{ #' # Subset example data #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE == "IgG") #' #' # Collapse clones #' db <- collapseClones(db, sequenceColumn="SEQUENCE_IMGT", #' germlineColumn="GERMLINE_IMGT_D_MASK", #' method="thresholdedFreq", minimumFrequency=0.6, #' includeAmbiguous=FALSE, breakTiesStochastic=FALSE) #' #' # Calculate BASELINe #' baseline <- calcBaseline(db, #' sequenceColumn="CLONAL_SEQUENCE", #' germlineColumn="CLONAL_GERMLINE", #' testStatistic="focused", #' regionDefinition=IMGT_V, #' targetingModel=HH_S5F, #' nproc = 1) #' #' # Grouping the PDFs by the sample annotation #' grouped <- groupBaseline(baseline, groupBy="SAMPLE") #' #' # Get a data.frame of the summary statistics #' stats <- summarizeBaseline(grouped, returnType="df") #' } #' @export summarizeBaseline <- function(baseline, returnType=c("baseline", "df"), nproc=1) { # Hack for visibility of foreach index variable idx <- NULL # Check arguments returnType <- match.arg(returnType) # Ensure that the nproc does not exceed the number of cores/CPUs available nproc <- min(nproc, cpuCount()) # If user wants to paralellize this function and specifies nproc > 1, then # initialize and register slave R processes/clusters & # export all nesseary environment variables, functions and packages. if (nproc > 1){ cluster <- parallel::makeCluster(nproc, type="PSOCK") parallel::clusterExport(cluster, list('baseline', 'baselineSigma', 'baselineCI', 'baselinePValue'), envir=environment()) registerDoParallel(cluster, cores=nproc) } else if (nproc == 1) { # If needed to run on a single core/cpu then, regsiter DoSEQ # (needed for 'foreach' in non-parallel mode) registerDoSEQ() } # Printing status to console cat("Calculating BASELINe statistics...\n") # Calculate stats for each sequence/group numbOfTotalSeqs <- nrow(baseline@db) regions <- baseline@regions db <- baseline@db if ("SEQUENCE_ID" %in% colnames(db)) { db <- subset(db, select="SEQUENCE_ID") } list_stats <- foreach(idx=iterators::icount(numbOfTotalSeqs)) %dopar% { df_baseline_seq <- data.frame() db_seq <- data.frame(db[idx, ]) names(db_seq) <- names(db) for (region in regions) { # care was taken to make sure that @pdfs[[region]] should be maintained # as a matrix regardless of the number of input sequences (even for a # single-sequence input) stopifnot(is(baseline@pdfs[[region]], "matrix")) baseline_pdf <- baseline@pdfs[[region]][idx, ] baseline_ci <- baselineCI(baseline_pdf) df_baseline_seq_region <- data.frame(db_seq, REGION=factor(region, levels=regions), BASELINE_SIGMA=baselineSigma(baseline_pdf), BASELINE_CI_LOWER=baseline_ci[1], BASELINE_CI_UPPER=baseline_ci[2], BASELINE_CI_PVALUE=baselinePValue(baseline_pdf)) df_baseline_seq <- dplyr::bind_rows(df_baseline_seq, df_baseline_seq_region) } df_baseline_seq[,1] <- as.vector(unlist(df_baseline_seq[,1])) df_baseline_seq[,2] <- as.vector(unlist(df_baseline_seq[,2])) return(df_baseline_seq) } # Stop cluster if (nproc > 1) { parallel::stopCluster(cluster) } # Convert list of BASELINe stats into a data.frame stats <- as.data.frame(dplyr::bind_rows(list_stats)) if (returnType == "df") { return(stats) } else if (returnType == "baseline") { # Append stats to baseline object return(editBaseline(baseline, field="stats", stats)) } else { return(NULL) } } #' Two-sided test of BASELINe PDFs #' #' \code{testBaseline} performs a two-sample signifance test of BASELINe #' posterior probability density functions (PDFs). #' #' @param baseline \code{Baseline} object containing the \code{db} and grouped #' BASELINe PDFs returned by \link{groupBaseline}. #' @param groupBy string defining the column in the \code{db} slot of the #' \code{Baseline} containing sequence or group identifiers. #' #' @return A data.frame with test results containing the following columns: #' \itemize{ #' \item \code{REGION}: sequence region, such as "CDR" and "FWR". #' \item \code{TEST}: string defining the groups be compared. The #' string is formated as the conclusion associated with the #' p-value in the form \code{GROUP1 != GROUP2}. Meaning, #' the p-value for rejection of the null hypothesis that #' GROUP1 and GROUP2 have equivalent distributions. #' \item \code{PVALUE}: two-sided p-value for the comparison. #' \item \code{FDR}: FDR corrected \code{PVALUE}. #' } #' #' @seealso To generate the \link{Baseline} input object see \link{groupBaseline}. #' #' @references #' \enumerate{ #' \item Yaari G, et al. Quantifying selection in high-throughput immunoglobulin #' sequencing data sets. #' Nucleic Acids Res. 2012 40(17):e134. #' (Corretions at http://selection.med.yale.edu/baseline/correction/) #' } #' #' @examples #' \donttest{ #' # Subset example data #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE %in% c("IgM", "IgG", "IgA")) #' #' # Collapse clones #' db <- collapseClones(db, sequenceColumn="SEQUENCE_IMGT", #' germlineColumn="GERMLINE_IMGT_D_MASK", #' method="thresholdedFreq", minimumFrequency=0.6, #' includeAmbiguous=FALSE, breakTiesStochastic=FALSE) #' #' # Calculate BASELINe #' baseline <- calcBaseline(db, #' sequenceColumn="CLONAL_SEQUENCE", #' germlineColumn="CLONAL_GERMLINE", #' testStatistic="focused", #' regionDefinition=IMGT_V, #' targetingModel=HH_S5F, #' nproc=1) #' #' # Group PDFs by the isotype #' grouped <- groupBaseline(baseline, groupBy="ISOTYPE") #' #' # Visualize isotype PDFs #' plot(grouped, "ISOTYPE") #' #' # Perform test on isotype PDFs #' testBaseline(grouped, groupBy="ISOTYPE") #' } #' @export testBaseline <- function(baseline, groupBy) { ## DEBUG # baseline=grouped; groupBy="SAMPLE" # Get test groups groups <- as.character(baseline@db[[groupBy]]) if (length(groups) < 2) { stop('The ', groupBy, ' column does not contain at least two groups.') } pair_indices <- combn(1:length(groups), 2, simplify=F) pair_names <- combn(groups, 2, simplify=F) test_names <- sapply(pair_names, paste, collapse=" != ") # Run tests test_list <- list() for (n in baseline@regions) { d <- baseline@pdfs[[n]] p <- sapply(pair_indices, function(x) { baseline2DistPValue(d[x[1], ], d[x[2], ])}) test_list[[n]] <- data.frame(TEST=test_names, PVALUE=p) } test_df <- bind_rows(test_list, .id="REGION") test_df$FDR <- p.adjust(test_df$PVALUE, method="fdr") return(test_df) } # Calculate mean sigma of a BASELINe PDF # # @param base BASLINe PDF vector. # @param max_sigma maximum sigma score. # @param length_sigma length of the PDF vector. # @return Mean sigma. baselineSigma <- function(base, max_sigma=20, length_sigma=4001) { # Return NA on bad input if (any(is.na(base))) { return(NA) } sigma_s <- seq(-max_sigma, max_sigma, length.out=length_sigma) norm <- sum(base, na.rm=TRUE) sigma_mean <- base %*% sigma_s / norm return(sigma_mean) } # Calculate confidence interval for BASELINe PDF # # @param base BASLINe PDF vector. # @param low lower CI percentile. # @param up upper CI percentile. # @param max_sigma maximum sigma score. # @param length_sigma length of the PDF vector. # @return A vector of \code{c(lower, upper)} confidence bounds. baselineCI <- function (base, low=0.025, up=0.975, max_sigma=20, length_sigma=4001){ # Return NA on bad input if (any(is.na(base))) { return(c(NA, NA)) } sigma_s <- seq(-max_sigma, max_sigma, length.out=length_sigma) cdf <- cumsum(base) cdf <- cdf / cdf[length(cdf)] intervalLow <- findInterval(low, cdf) fractionLow <- (low - cdf[intervalLow])/(cdf[intervalLow + 1] - cdf[intervalLow]) intervalUp <- findInterval(up,cdf) fractionUp <- (up - cdf[intervalUp]) / (cdf[intervalUp] - cdf[intervalUp - 1]) sigmaLow <- sigma_s[intervalLow] + fractionLow*(sigma_s[intervalLow + 1] - sigma_s[intervalLow]) sigmaUp <- sigma_s[intervalUp] + fractionUp*(sigma_s[intervalUp + 1] - sigma_s[intervalUp]) return(c(sigmaLow, sigmaUp)) } # Calculate a p-value that the given BASELINe PDF differs from zero # # @param base BASLINe PDF vector. # @param max_sigma maximum sigma score. # @param length_sigma length of the PDF vector. # @return A p-value. The returned p-value can be either positive or negative. # Its magnitude (without the sign) should be interpreted as per normal. # Its sign indicate the direction of the selection detected. A positive # p-value indicates positive selection, whereas a negative p-value # indicates negative selection. baselinePValue <- function (base, length_sigma=4001, max_sigma=20){ # note: since there isn't a null distribution, this "p-value" isn't a p-value in the # conventional sense if (!any(is.na(base))) { # normalization factor #norm <- (length_sigma - 1) / 2 / max_sigma # sums up to 100 for default setting (sigma_s from -20 to 20 with length 4001) norm <- sum(base, na.rm=TRUE) # compute Pr(selection strength < 0): # sum up density for sigma from min_sigma up to and right before 0 (area under curve), plus # + binomial correction (density at sigma=0 divided by 2); # normalized pvalue <- ( sum(base[1:((length_sigma - 1) / 2)]) + base[((length_sigma + 1) / 2)] / 2 ) / norm # from Fig 4 caption of Detecting selection in immunoglobulin sequences by Uduman et al. 2011 # "Note that P values less than zero are indicative of negative selection." # 1) if Pr(selection strength < 0) <= 0.5, return Pr(selection strength < 0) # this will be positive, and serves as the "p-value" for positive selection # 2) if Pr(selection strength < 0) > 0.5, return -Pr(selection strength>0) # this will be negative, and serves as the "p-value" for negative selection # (negative sign highlights the fact that selection is negative) if (pvalue > 0.5) { pvalue <- -(1 - pvalue) } } else { pvalue <- NA } return(pvalue) } # Compute p-value of two BASELINe PDFs # # @param base1 first selection PDF; must be a numeric vector # @param base2 second selection PDF; must be a numeric vector # @return Two-sided p-value that base1 and base2 differ. baseline2DistPValue <-function(base1, base2) { # NOTE: make sure to supply 2 vectors (not 1-row data.frames) when # calling this function directly ## Debug # base1=grouped@pdfs[["CDR"]][1, ]; base2=grouped@pdfs[["FWR"]][1, ] # Get lengths len1 <- length(base1) len2 <- length(base2) # Check input if (len1 != len2) { stop("base1 and base2 must be the same length.") } # NA if all values in pdfs are NA if (sum(is.na(base1))==len1 | sum(is.na(base2))==len2) { return(NA) } # Determine p-value if (len1 > 1) { # Normalize base1 <- base1 / sum(base1, na.rm=TRUE) base2 <- base2 / sum(base2, na.rm=TRUE) # Calculate p-value cum2 <- cumsum(base2) - base2/2 pvalue <- sum(base1*cum2) if (pvalue > 0.5) { pvalue <- 1 - pvalue } } else { pvalue <- NA } return(pvalue) } #### Plotting functions #### #' Plots BASELINe probability density functions #' #' \code{plotBaselineDensity} plots the probability density functions resulting from selection #' analysis using the BASELINe method. #' #' @param baseline \code{Baseline} object containing selection probability #' density functions. #' @param idColumn name of the column in the \code{db} slot of \code{baseline} #' containing primary identifiers. #' @param groupColumn name of the column in the \code{db} slot of \code{baseline} #' containing secondary grouping identifiers. If \code{NULL}, #' organize the plot only on values in \code{idColumn}. #' @param colorElement one of \code{c("id", "group")} specifying whether the #' \code{idColumn} or \code{groupColumn} will be used for color coding. #' The other entry, if present, will be coded by line style. #' @param colorValues named vector of colors for entries in \code{colorElement}, with #' names defining unique values in the \code{colorElement} column and values #' being colors. Also controls the order in which values appear on the #' plot. If \code{NULL} alphabetical ordering and a default color palette #' will be used. #' @param facetBy one of \code{c("region", "group")} specifying which category to facet the #' plot by, either values in \code{groupColumn} ("group") or regions #' defined in the \code{regions} slot of the \code{baseline} object ("region"). #' If this is set to "group", then the region will behave as the \code{groupColumn} #' for purposes of the \code{colorElement} argument. #' @param title string defining the plot title. #' @param subsetRegions character vector defining a subset of regions to plot, correspoding #' to the regions for which the \code{baseline} data was calculated. If #' \code{NULL} all regions in \code{baseline} are plotted. #' @param sigmaLimits numeric vector containing two values defining the \code{c(lower, upper)} #' bounds of the selection scores to plot. #' @param style type of plot to draw. One of: #' \itemize{ #' \item \code{"density"}: plots a set of curves for each probability #' density function in \code{baseline}, #' with colors determined by values in the #' \code{colorElement} column. #' Faceting is determined by the #' \code{facetBy} argument. #' } #' @param sizeElement one of \code{c("none", "id", "group")} specifying whether the lines in the #' plot should be all of the same size (\code{none}) or have their sizes depend on #' the values in \code{id} or \code{code}. #' @param size numeric scaling factor for lines, points and text in the plot. #' @param silent if \code{TRUE} do not draw the plot and just return the ggplot2 #' object; if \code{FALSE} draw the plot. #' @param ... additional arguments to pass to ggplot2::theme. #' #' @return A ggplot object defining the plot. #' #' @seealso Takes as input a \link{Baseline} object returned from \link{groupBaseline}. #' #' @examples #' \donttest{ #' # Subset example data #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE %in% c("IgM", "IgG")) #' #' # Collapse clones #' db <- collapseClones(db, sequenceColumn="SEQUENCE_IMGT", #' germlineColumn="GERMLINE_IMGT_D_MASK", #' method="thresholdedFreq", minimumFrequency=0.6, #' includeAmbiguous=FALSE, breakTiesStochastic=FALSE) #' #' # Calculate BASELINe #' baseline <- calcBaseline(db, #' sequenceColumn="CLONAL_SEQUENCE", #' germlineColumn="CLONAL_GERMLINE", #' testStatistic="focused", #' regionDefinition=IMGT_V, #' targetingModel=HH_S5F, #' nproc=1) #' #' # Grouping the PDFs by the sample and isotype annotations #' grouped <- groupBaseline(baseline, groupBy=c("SAMPLE", "ISOTYPE")) #' #' # Plot density faceted by region with custom isotype colors #' isotype_colors <- c("IgM"="darkorchid", "IgD"="firebrick", #' "IgG"="seagreen", "IgA"="steelblue") #' plotBaselineDensity(grouped, "SAMPLE", "ISOTYPE", colorValues=isotype_colors, #' colorElement="group", sigmaLimits=c(-1, 1)) #' #' # Facet by isotype instead of region #' sample_colors <- c("-1h"="steelblue", "+7d"="firebrick") #' plotBaselineDensity(grouped, "SAMPLE", "ISOTYPE", facetBy="group", #' colorValues=sample_colors, sigmaLimits=c(-1, 1)) #' } #' #' @export plotBaselineDensity <- function(baseline, idColumn, groupColumn=NULL, colorElement=c("id", "group"), colorValues=NULL, title=NULL, subsetRegions=NULL, sigmaLimits=c(-5, 5), facetBy=c("region", "group"), style=c("density"), sizeElement=c("none", "id", "group"), size=1, silent=FALSE, ...) { ## DEBUG # baseline=grouped # idColumn="SAMPLE"; groupColumn="ISOTYPE"; subsetRegions=NULL; sigmaLimits=c(-5, 5) # facetBy="region"; style="density"; size=1; silent=FALSE # Check input colorElement <- match.arg(colorElement) style <- match.arg(style) facetBy <- match.arg(facetBy) sizeElement <- match.arg(sizeElement) # Set base plot settings base_theme <- theme_bw() + theme(panel.background=element_blank(), panel.grid.major=element_blank(), panel.grid.minor=element_blank(), panel.border=element_rect(color="black", size=0.5)) + theme(strip.background=element_rect(fill="white", color="black", size=0.5)) if (style == "density") { # Check for proper grouping if (any(duplicated(baseline@db[, c(idColumn, groupColumn)]))) { stop("More than one unique annotation set per summary statistic. Rerun groupBaseline to combine data.") } # Subset to regions of interest dens_names <- baseline@regions if (!is.null(subsetRegions)) { dens_names <- dens_names[dens_names %in% subsetRegions] } dens_list <- baseline@pdfs[dens_names] # Get row and column names for PDF matrices group_df <- subset(baseline@db, select=c(idColumn, groupColumn)) group_df$GROUP_COLLAPSE <- apply(subset(group_df, select=c(idColumn, groupColumn)), 1, paste, collapse=",") col_names <- seq(-20, 20, length.out=ncol(dens_list[[1]])) # Update column and rownames for PDF matrices and subset to Sigma in -5:5 for (i in 1:length(dens_list)) { rownames(dens_list[[i]]) <- group_df$GROUP_COLLAPSE colnames(dens_list[[i]]) <- col_names dens_list[[i]] <- dens_list[[i]][, col_names >= sigmaLimits[1] & col_names <= sigmaLimits[2], drop=FALSE] } # Melt density matrices melt_list <- list() for (n in dens_names) { tmp_df <- as.data.frame(dens_list[[n]]) tmp_df$GROUP_COLLAPSE <- rownames(dens_list[[n]]) gather_cols <- names(tmp_df)[names(tmp_df) != "GROUP_COLLAPSE"] melt_list[[n]] <- tidyr::gather(tmp_df, "SIGMA", "DENSITY", gather_cols, convert=TRUE) } dens_df <- dplyr::bind_rows(melt_list, .id="REGION") # Assign id and group columns to density data.frame dens_df[, idColumn] <- group_df[match(dens_df$GROUP_COLLAPSE, group_df$GROUP_COLLAPSE), idColumn] if (!is.null(groupColumn)) { dens_df[, groupColumn] <- group_df[match(dens_df$GROUP_COLLAPSE, group_df$GROUP_COLLAPSE), groupColumn] } # Set secondary grouping and faceting columns if (facetBy == "group") { secondaryColumn <- "REGION" facetColumn <- groupColumn } else if (facetBy == "region") { secondaryColumn <- groupColumn facetColumn <- "REGION" } # Apply color order if (!is.null(colorValues)) { if (colorElement == "id") { dens_df[, idColumn] <- factor(dens_df[, idColumn], levels=names(colorValues)) } else { dens_df[, groupColumn] <- factor(dens_df[, groupColumn], levels=names(colorValues)) } } # Apply line width dens_df[, "size"] <- factor(1) if (sizeElement=="id") { dens_df[, "size"] <- factor(dens_df[, idColumn]) } else if (sizeElement == "group" ) { dens_df[, "size"] <- factor(dens_df[, groupColumn]) } size_values <- 1:length(levels(dens_df[,"size"])) size_names <- levels(dens_df[, "size"]) size_values <- size*size_values/max(size_values) names(size_values) <- size_names # Plot probability density curve p1 <- ggplot(dens_df, aes_string(x="SIGMA", y="DENSITY")) + base_theme + xlab(expression(Sigma)) + ylab("Density") + geom_line(aes(size=size)) # Add line if (colorElement == "id" & is.null(secondaryColumn)) { p1 <- p1 + aes_string(color=idColumn) } else if (colorElement == "id" & !is.null(secondaryColumn)) { p1 <- p1 + aes_string(color=idColumn, linetype=secondaryColumn) } else if (colorElement == "group") { p1 <- p1 + aes_string(color=secondaryColumn, linetype=idColumn) } else { stop("Incompatible arguments for groupColumn, colorElement and facetBy") } # Add colors if (!is.null(colorValues)) { p1 <- p1 + scale_color_manual(values=colorValues) } # Add title if (!is.null(title)) { p1 <- p1 + ggtitle(title) } # Add facet if (is.null(facetColumn)) { stop("Cannot facet by group if groupColumn=NULL") } else { p1 <- p1 + facet_grid(paste(facetColumn, "~ .")) } } # Add additional theme elements p1 <- p1 + scale_size_manual(breaks=names(size_values), values=size_values) if (sizeElement == "none") { p1 <- p1 + guides( size=FALSE, colour = guide_legend(override.aes = list(size = size_values)) ) if (length(unique(c(groupColumn,idColumn)))>1) { p1 <- p1 + guides ( linetype = guide_legend(override.aes = list(size = size_values)) ) } } else if (sizeElement == colorElement) { p1 <- p1 + guides( size=FALSE, colour = guide_legend(override.aes = list(size = size_values))) } else { p1 <- p1 + guides( size=FALSE, linetype = guide_legend(override.aes = list(size = size_values)) ) } p1 <- p1 + do.call(theme, list(...)) # Plot if (!silent) { plot(p1) } invisible(p1) } #' Plots BASELINe summary statistics #' #' \code{plotBaselineSummary} plots a summary of the results of selection analysis #' using the BASELINe method. #' #' @param baseline either a data.frame returned from \link{summarizeBaseline} #' or a \code{Baseline} object returned from \link{groupBaseline} #' containing selection probability density functions and summary #' statistics. #' @param idColumn name of the column in \code{baseline} containing primary identifiers. #' If the input is a \code{Baseline} object, then this will be a column #' in the \code{stats} slot of \code{baseline}. #' @param groupColumn name of the column in \code{baseline} containing secondary grouping #' identifiers. If the input is a \code{Baseline} object, then this will #' be a column in the \code{stats} slot of \code{baseline}. #' @param groupColors named vector of colors for entries in \code{groupColumn}, with #' names defining unique values in the \code{groupColumn} and values #' being colors. Also controls the order in which groups appear on the #' plot. If \code{NULL} alphabetical ordering and a default color palette #' will be used. Has no effect if \code{facetBy="group"}. #' @param subsetRegions character vector defining a subset of regions to plot, correspoding #' to the regions for which the \code{baseline} data was calculated. If #' \code{NULL} all regions in \code{baseline} are plotted. #' @param facetBy one of c("group", "region") specifying which category to facet the #' plot by, either values in \code{groupColumn} ("group") or regions #' defined in \code{baseline} ("region"). The data that is not used #' for faceting will be color coded. #' @param title string defining the plot title. #' @param style type of plot to draw. One of: #' \itemize{ #' \item \code{"summary"}: plots the mean and confidence interval for #' the selection scores of each value in #' \code{idColumn}. Faceting and coloring #' are determine by values in \code{groupColumn} #' and regions defined in \code{baseline}, #' depending upon the \code{facetBy} argument. #' } #' @param size numeric scaling factor for lines, points and text in the plot. #' @param silent if \code{TRUE} do not draw the plot and just return the ggplot2 #' object; if \code{FALSE} draw the plot. #' @param ... additional arguments to pass to ggplot2::theme. #' #' @return A ggplot object defining the plot. #' #' @seealso Takes as input either a \link{Baseline} object returned by \link{groupBaseline} #' or a data.frame returned from \link{summarizeBaseline}. #' #' @examples #' \donttest{ #' # Subset example data #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE %in% c("IgM", "IgG")) #' #' # Collapse clones #' db <- collapseClones(db, sequenceColumn="SEQUENCE_IMGT", #' germlineColumn="GERMLINE_IMGT_D_MASK", #' method="thresholdedFreq", minimumFrequency=0.6, #' includeAmbiguous=FALSE, breakTiesStochastic=FALSE) #' #' # Calculate BASELINe #' baseline <- calcBaseline(db, #' sequenceColumn="CLONAL_SEQUENCE", #' germlineColumn="CLONAL_GERMLINE", #' testStatistic="focused", #' regionDefinition=IMGT_V, #' targetingModel=HH_S5F, #' nproc=1) #' #' # Grouping the PDFs by sample and isotype annotations #' grouped <- groupBaseline(baseline, groupBy=c("SAMPLE", "ISOTYPE")) #' #' # Plot mean and confidence interval by region with custom group colors #' isotype_colors <- c("IgM"="darkorchid", "IgD"="firebrick", #' "IgG"="seagreen", "IgA"="steelblue") #' plotBaselineSummary(grouped, "SAMPLE", "ISOTYPE", #' groupColors=isotype_colors) #' #' # Facet by group instead of region #' plotBaselineSummary(grouped, "SAMPLE", "ISOTYPE", facetBy="group") #' } #' #' @export plotBaselineSummary <- function(baseline, idColumn, groupColumn=NULL, groupColors=NULL, subsetRegions=NULL, facetBy=c("region", "group"), title=NULL, style=c("summary"), size=1, silent=FALSE, ...) { # Check arguments style <- match.arg(style) facetBy <- match.arg(facetBy) # Check input object if (is(baseline, "Baseline")) { stats_df <- baseline@stats } else if (is(baseline, "data.frame")) { stats_df <- baseline } else { stop("Input must be either a data.frame or Baseline object.") } # Check for required columns baseline_cols <- c("REGION", "BASELINE_SIGMA", "BASELINE_CI_LOWER", "BASELINE_CI_LOWER", "BASELINE_CI_LOWER", "BASELINE_CI_PVALUE") if (!(all(baseline_cols %in% names(stats_df)))) { stop("Input must contain columns defined by summarizeBaseline.") } # Check for proper grouping if (any(duplicated(stats_df[, c(idColumn, groupColumn, "REGION")]))) { stop("More than one unique annotation set per summary statistic. Rerun groupBaseline to combine data.") } # Subset to regions of interest if (!is.null(subsetRegions)) { stats_df <- stats_df[stats_df$REGION %in% subsetRegions, ] } # Set base plot settings base_theme <- theme_bw() + theme(panel.background=element_blank(), panel.grid.major=element_blank(), panel.grid.minor=element_blank(), panel.border=element_rect(color="black", size=0.5)) + theme(strip.background=element_rect(fill="white", color="black", size=0.5)) + theme(axis.title.x=element_blank(), axis.text.x=element_blank(), axis.ticks.x=element_blank()) + theme(legend.position="top") + theme(axis.text.x=element_text(angle=90, vjust=0.5, hjust=1)) if (style == "summary") { # Plot mean and confidence intervals stats_df <- stats_df[!is.na(stats_df$BASELINE_SIGMA), ] if (!is.null(groupColumn) & !is.null(groupColors)) { stats_df[,groupColumn] <- factor(stats_df[,groupColumn], levels=names(groupColors)) } p1 <- ggplot(stats_df, aes_string(x=idColumn, y="BASELINE_SIGMA", ymax=max("BASELINE_SIGMA"))) + base_theme + xlab("") + ylab(expression(Sigma)) + geom_hline(yintercept=0, size=1*size, linetype=2, color="grey") + geom_point(size=3*size, position=position_dodge(0.6)) + geom_errorbar(aes_string(ymin="BASELINE_CI_LOWER", ymax="BASELINE_CI_UPPER"), width=0.2, size=0.5*size, alpha=0.8, position=position_dodge(0.6)) if (!is.null(title)) { p1 <- p1 + ggtitle(title) } if (is.null(groupColumn) & facetBy == "region") { p1 <- p1 + facet_grid(REGION ~ .) } else if (!is.null(groupColumn) & !is.null(groupColors) & facetBy == "region") { #groupColors <- factor(groupColors, levels=groupColors) p1 <- p1 + scale_color_manual(name=groupColumn, values=groupColors) + aes_string(color=groupColumn) + facet_grid(REGION ~ .) } else if (!is.null(groupColumn) & is.null(groupColors) & facetBy == "region") { p1 <- p1 + aes_string(color=groupColumn) + facet_grid(REGION ~ .) } else if (!is.null(groupColumn) & facetBy == "group") { p1 <- p1 + scale_color_manual(name="Region", values=REGION_PALETTE) + aes_string(color="REGION") + facet_grid(paste(groupColumn, "~ .")) } else { stop("Cannot facet by group if groupColumn=NULL") } } # Add additional theme elements p1 <- p1 + do.call(theme, list(...)) # Plot if (!silent) { plot(p1) } else { invisible(p1) } } #### Original BASELINe functions #### ##Covolution break2chunks<-function(G=1000){ base<-2^round(log(sqrt(G),2),0) return(c(rep(base,floor(G/base)-1),base+G-(floor(G/base)*base))) } PowersOfTwo <- function(G=100){ exponents <- array() i = 0 while(G > 0){ i=i+1 exponents[i] <- floor( log2(G) ) G <- G-2^exponents[i] } return(exponents) } convolutionPowersOfTwo <- function( cons, length_sigma=4001 ){ G = ncol(cons) if(G>1){ for(gen in log(G,2):1){ ll<-seq(from=2,to=2^gen,by=2) sapply(ll,function(l){cons[,l/2]<<-weighted_conv(cons[,l],cons[,l-1],length_sigma=length_sigma)}) } } return( cons[,1] ) } convolutionPowersOfTwoByTwos <- function( cons, length_sigma=4001,G=1 ){ if(length(ncol(cons))) G<-ncol(cons) groups <- PowersOfTwo(G) matG <- matrix(NA, ncol=length(groups), nrow=length(cons)/G ) startIndex = 1 for( i in 1:length(groups) ){ stopIndex <- 2^groups[i] + startIndex - 1 if(stopIndex!=startIndex){ matG[,i] <- convolutionPowersOfTwo( cons[,startIndex:stopIndex], length_sigma=length_sigma ) startIndex = stopIndex + 1 } else { if(G>1) matG[,i] <- cons[,startIndex:stopIndex] else matG[,i] <- cons #startIndex = stopIndex + 1 } } return( list( matG, groups ) ) } weighted_conv <- function(x, y, w=1, m=100, length_sigma=4001){ lx<-length(x) ly<-length(y) if({lx1){ while( i1 & Length_Postrior<=Threshold){ cons = matrix(unlist(listPosteriors),length(listPosteriors[[1]]),length(listPosteriors)) listMatG <- convolutionPowersOfTwoByTwos(cons,length_sigma=length_sigma) y<-calculate_bayesGHelper(listMatG,length_sigma=length_sigma) return( y/sum(y)/(2*max_sigma/(length_sigma-1)) ) }else if(Length_Postrior==1) return(listPosteriors[[1]]) else if(Length_Postrior==0) return(NA) else { cons = matrix(unlist(listPosteriors),length(listPosteriors[[1]]),length(listPosteriors)) y = fastConv(cons,max_sigma=max_sigma, length_sigma=length_sigma ) return( y/sum(y)/(2*max_sigma/(length_sigma-1)) ) } } fastConv<-function(cons, max_sigma=20, length_sigma=4001){ chunks<-break2chunks(G=ncol(cons)) if(ncol(cons)==3) chunks<-2:1 index_chunks_end <- cumsum(chunks) index_chunks_start <- c(1,index_chunks_end[-length(index_chunks_end)]+1) index_chunks <- cbind(index_chunks_start,index_chunks_end) case <- sum(chunks!=chunks[1]) if(case==1) End <- max(1,((length(index_chunks)/2)-1)) else End <- max(1,((length(index_chunks)/2))) firsts <- sapply(1:End,function(i){ indexes<-index_chunks[i,1]:index_chunks[i,2] convolutionPowersOfTwoByTwos(cons[ ,indexes])[[1]] }) if(case==0){ result<-calculate_bayesGHelper( convolutionPowersOfTwoByTwos(firsts) ) }else if(case==1){ last<-list(calculate_bayesGHelper( convolutionPowersOfTwoByTwos( cons[ ,index_chunks[length(index_chunks)/2,1]:index_chunks[length(index_chunks)/2,2]] ) ),0) result_first<-calculate_bayesGHelper(convolutionPowersOfTwoByTwos(firsts)) result<-calculate_bayesGHelper( list( cbind( result_first,last[[1]]), c(log(index_chunks_end[length(index_chunks)/2-1],2),log(index_chunks[length(index_chunks)/2,2]-index_chunks[length(index_chunks)/2,1]+1,2)) ) ) } return(as.vector(result)) } shazam/R/sysdata.rda0000644000176200001440000014136513402556553014120 0ustar liggesusersBZh91AY&SYWkjB^ڀmXVC:Z\'(JTfN6uw٫mN !;@ B@(P 0l(6 Cat4GAfh2- &̓3@Hm` жdw 0)+ݻZ` {UNp قYmS=4dJ}-yC_w.l ` $(4Q Ҏwps A DGZS NM )14N-M9se622-DR1BsJ2t޽9뫟Dfo 6nќuoIƲ!5!946-unfh1R|V?|\KTh_P20ܦX؁+3vVƙIVHCU8ot_y&Q0+}+n[-ޗ[b3І^'yg~==/hh:<04/RCgL 0z6"ϴQa.m;h8&Ե{բYtf"֨[zf7kg[Gk*ϖ,r1\C入vRx[}лޗ|DuޒwJw!xBkNCZJ{^%:0&bKߒzmmnL{H+^ '7Ufo'#Ì˞K/-s1*VZ@-+skZN[)Iiu=gCr+2B_fP:]gnbQ_%vDg׍,oݧwڽuiO\zާϸz5owNMN&_է^ R̽q ~US8u GK֤B{ũ0H{M?~_ֆ}oT{,`Ъ/g[8MۋM5/{MQ^)&Z1F|X>TFLNJ SW}rՁYYh=TJcaݪJ0Nhlmbz\6].5=0/ Pm_Xj>:p%oQkO4Ulbh>=+HZ}-Sl!R, :aEYR N;Z61VR-1{NO55Dtxctqau5ƔUZQ:TiGu)chGּi TRĂ]a eq+\jvQǜxo:?6AI?k @Ds/k-~rq5]q*kiDBl}MaH yE{>KS53{S=zoǭ⏘czOZP<:0)XxJm~{ Js'T];򑟲w3YVt$- кSVB=4޺!&SV{/t7xbT e} vXHwwZK~[O]uJכޓt`z"prvJqթWC4=+?9kԟߏvIj&u~^wwM3_DQ-cDI#ǬfԀb5,rOw.gZNu̥oߝRw*'M1 *!zmPMK #+̻I.B~8Y DBYK4C4Mh~wD)Kn L^$U+JMQ J^]~ coݧV%SHlw}dD~Nc?V|ؼE~En]4!W(r~ ơ!@K Ppm&3#O]_$鏞F9r%k.|=z,u[ԈT}K5I{KGa*Ä{Ckz}tğpy^mFvwn݃ZWmb|x![% ^{ׯ^+[[h\WĬӮ|U Sw6V 'SH%>¢90YF=߇pY<h>򹍄ޘa#*+&vߓ9< Y/ߟnfm?2=;:f\pDO0U%`)iB҃r)! z_V\R˜N5h%.ipGЌ}'"1W 9{Q1ƕ/z6N䬑1ިДW8Uh+{kyd fW͠V{J^w􏖺{קUӋ:hhm{[ g 4^2q ΜmJdby[0kq\=:ff\iJ5̔=g/kL>kC52p/9J9 {Vu Ҕzνk ( )vOeZȯSS_!głLJZ}s}lThbeoSZVxGrYbYZ8sԈܻ_8(Y%BQv_-&6-ڞhD8Av!Lp#OZ =euNe}Df@=CIQ.?לf ~Mٲkv]^==4e\mSb/ۊu sN@}\/跰=ٴ/J1z=͓ J]Ijy(.{)92yhA.b`E0_%Cc<*So (+,S>v:-&lMVq1b]z ZY짷b}ֽzy"$>ᖪ2a5h+7ѣYyyqigbpQMxaw'7{ڞu]e[bOX=ZJḬi![2f#+{cV{H*eisC{U!v*yPD;gّ)?:B>ơ~/SxV[) wrRFJ#M8.RZ7%=RAMK7WN$eI[úVP[dY uIvy;P94j8ޠ>oc!%o>Up֧|<:۔ofy/x~_ݩc︉,4GG׹p%tW˻N13K5uz@6bVWί'7ͦ([OQ/[í !n3ճ筂;lƫV}huybyt;2YR< CۯJ$&Zu 0?ҩ >cԦ_|e6ҧ n{9v#W_S^̴gwνtqڿBO&m?45Ѿv??990OFښ4M;Fm 2SR +Hj! A qw,!i~%$}EjBoD}_eE{ىf my|xX"z)(ǷvazJo%ߔ|<4!;,g@QU %|^eM$հxb'ii+UU FN Ճ"hC$[s$$)c"5)}pv\Owq<ۮi"zO<MZ5|eg5HZλ]Zf/}UvFkKU0%ChxxΡSȎ'72~MJ/7XtImhG5} yܓQ]-|iT\yo1=g xZ= ,K&8jU^1Qa_i֯יLk 5mC 4n?5M!'j*J4b}Ri{mMfUczww.!)ix?C-%g7e~Fٓ F;Tors9$njM&u;eM>xxVK`N 4l(ۮknكg.)hbo*sFhӝ965!tJGrp My3DVU)rM;3Q*QmHJ3jaKGoެ~S5JM ڋ'c5X|]l gn,s8>ٟJSᆭיn1pcJo+E< [4gѲZO/xc'|W}0+iڕ!)aGRS}1Zά"%#+߿:1<-r_9AkSZ68"FFa\Nd/ӣ/[LiG˪Vj(ǖ A)u6{$y'Byd67Cw DB[_2^kuJ=)yp ]/NӑzV"hCta~COhH%Vi`a]M-ml7UΏGx+ZUJ-Hc}擎iڵ Dnf-ӆ΅_woos| L(| uYÉD׋ `-d!ԟ97{OwO:mi؃5+NVosOjʮ3_WJ?7ٯ]iZ5m)tM2s63K6j3zH=Yu'9JR1S:=ZǞOa^F",_CSMJj*3~*ounc,%5k;JǾ`3Ft(Dg4x oN*q@3+ҷ z骯ܲ?Rj.K]Ije U5éTdtko Ե|~eWf7{)u .׌KguoFk07wm9$tӗy&9rǔ~s7c_9$?3o_Tӛ8z%7 ToDBpOh?ZU'J߯\f?b0QR!UE?GQADҟC@*(R (* l!K8'@ <P_s! R!8@l`7L;TT S9UG}}/ؿ lwtwF Sq- ЃmכѶmmmMmmmUPmmmUUTmmUTmSm6jmEQ^--4 PִvzQIEQIEWX:Zw4EE%4QIMmj6mmmmFmmmMQEUUQTQUEQ@mmj6mm(mSTRQQmQQmFmFښ*6FmFښ4܊(mQFmFڊ(ڍQCTSTP-mmEm)(6j6QE Q@QFڊ h((R)(=> 8P:#0P(]R'sII/q@QOHq+խDD;̱U_QP +W b@Q#ׂ(dE~c( wX@{r{ 萢5v+dƇwQsǑ !(9#Cs. DA kr}V͛EiikFmV^O()ɭFvjF'jyp\QUUUUO AE1UA@Tr3Q31TDTܢ.tQh#G";m5XUVj"Ku@vt:BF=~ffffffffffffffffkE\G]VUUwXgX]*qWTwUZ]*W{9Ts\Z]*W{|zTxX]*qWQAW7VW{U=*"P$ $0$ $!&Fny\uY2]VKU%\uRo<,JDyyTG/DyyTI"F*|T.%̪ɒ궚UIZ6Rd2&Ko2MUj\ڪKɒ\ʬ.yުL*.oUrduY.eVLUeT̪ԹUʗU%dY2]W|ިy|Y-nVKr[u%=k%n[ܬtRSy{Un[ܬm-INinr۬d+%[w)޶W-nVKr[jynr۬d+%FJw"rʹz<=$U2 (PYYY?_Ɣ *"HUU$2UI URDT5Uj5wr]܆]܇]j5wr ]܆]܅܆CWw!wr.C.AUTʪHeU$2""*HUU$2UI "*HzUI URC*?~q/<1w;ίDZ${L$kVI _$|L$mvI \I5_a$\I$.j$I7 !KMVē1r&nI \I5[L$ &bIPI<^rB4#ʛBC̄9Q UM!!FD!M*]AںdUjWMTRVȏ*b!2%uPQ (#"QE(UtH*h!2%uPQ (#"|KB䢠³2@3\uF@H ̌8E@HB dT*@1\uF@H F^QPzī2@0Z20@E* %]ёTTb*$ 8J$EWE!d`>_1SE(UQTQ>kglK ̅l̤̮d(Y`ḫd(Ve$3ٕ̅LYmjTyW!֭JdZԚ3ZZyG|;=kǽtkǽfwHg+ 831,L̅d̤{755z;Qu|S1wvE3@sIUpp$ $->sek !B '[D널z$hԒ.u$mB넓dP]Rp>;n҇7vh巧=T;WjTPڪYPQCzڪYPjTPڷTjޫ UҪYP*U^ .( LJznˆ 黨By\@'H!2txsǦ Ǘ /JP@K&HpJT" ۾|K@%Xň XTW|{4wu(x==x=<;wXBez{uO{Qx===;!G8m^^ݻ1BG:O%%%'F*b <#ʗdu^+ڨ+\%Y-Ȯzw瓨$瑭Ԑ !UTʪHeU$2y{9x1c1cǯQܒjKKed,D$b&Y$JQNî-J֪QPڵUjT6U{{S"D+V !6s@y뻚/G=QĀ  dq 8bÿ::C{={A>=w{Su |;=+ sٕ̅py弗s)^1c1b8&vE2A`$UҮopW7UUwĨkw]*@| /% K2K#K2O-"!&fTJDyyTG/DyyTEURyNZI'[I ONERhm޺Pnp>[շ=,UmU,Wǟ@4o.cp0P;w% yp@^{7u^\70P=wrPxṂy~w7RcK81Uuqd(&̡̇ =x=Ehx==x=}=ȭe=m^^ݻ+۹*BDZ$|L$}JEL!!FDYX1T fUHA /}ʭ<İqq2ٔfW2wyo%o{0f׿^f5\qDZ"_ВeY$~*MED]jMECUV j~"^cp9*]!:ٶ@Hk;E=vEҞg^Ǻ=EfW2ٕ2s-仟9No1c/nI84Lu$x )bwt[@w s|( , , , ?/Q"Щ&V:.&Ks*dTUI;Uj\Rd2&K@'UOZd+%FKrbA *M\[K|XUGs\6ۃ>c 9$JPHUI UY ]܆֬uRRo\]2UI #u1c8u:*_ēUI3,]Y$)~UI3,|zvr*!~p5PwY.ymAڵU5URvsΫmժ? R(!Q+u9ojjC \f*$ 6sϘ\:(>j4љ\QƬHg+f©^uyG|;s!G|%u1c9YÝbIvd~RI2 CWM[w [{=^aF(@K˘9ý ܅T" W/<bHp>; ${4xu886ed(u>rc1c0f뎜qfsqÝ{bWHTTjUԽA .!/]^Ww}O}BU3(s!A^^^ϗ>~}lfftP=' z_XTJzw`4dhps`u[dGTwup  3+B9{'z1c1{nO(HIT (PYYY|bB^`LQTGDyR.ҽrzUn[ܬ秞^yuױӺӯ~Í`t;7҆ED e߾9hFPB8z>S{1cƤ^T(B!.|/~?0}ٙI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$OdI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I2I2I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$>\|dI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$O]d2I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I&I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$'ˏ:̒I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I2I2I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I'^d4$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$y>\|dI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$III$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$$$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I:I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I͝fI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$$$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$LLI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I4鈛("(""DE9o~~>W8>}u_L{PssDJ Pxg'񽂑ҁOd* ?|( h %i (`h%" f"H) )*)(* Z(")"h)&f&* "( & H $ J()"(ZV`fP @_v_m(65X4$415 VJvXB΢tX0`ZUhi TQ5" 5#DS lE4 ,V`"`Ւ ɫ5XѝXPHUEѐ5CŜ@F EVcQlѱj%_4"ūL[EłCV,`V&TcYI5:i4ѧDImaڈ*Z 6ųK+Yv1YCE$E gMFsEՍb LQmb&"6q:(9.R׍UĔ $ [I G*"~fT!&H*@l $ eG_Skð Tj D SywEAYmNҵ,@$ @|i_?럻l l QCF j12j2E#Ɋ(&&RZ&J96E4PUS4E%?sb6 [ 䆹!XHĎHfkIiiM0`ƈq60R lBbNT #3T[Q ((!"fHfhBb& & "%" H hj" !H&$J*Xf &%"(`d *X"j( jKW{%y:^ ~W NxIyPWUTd_aB4w2v̭vM0E/ $9 B @MLI63>5w@l:(H C;3ĀI;H>AV)JB?ߴ<?xQQQ4PI0RM1l)XS`yuq4 14iT$CDDAʓ BQP' % &bJJ(ZHbO}7_Dxm76Ji#Q%DMAQbLl`eJK R$,5 T@MJL0@SC@DTHx}'םݗhnMZMt3}ڝwt=eIh'*]+2G{|5rk2t#t^*_~<}dkkԏrwiȾWB2CI" D-D5T@E{l*+Ne"t#ͪ19*d& Z hh`&J h ) %PD~$j j$) H*"(#QUKHK>c hIہ Œ@hDFIx)ZNg&d%` [iB)幗AhC#BTEM!%02S0&Yin2:m*(Q o.$UF٤|Jfv߶E`[m-G!Wf47ǎ.K'zp2wW^hvO7;wM w^t65z2PJ|NLW B:1kb6"Nm.fF%M#U:d䵖MElb"hH~\Θ4 f(-IZM՞cGd&I)ZD)@~c}/>JLEO9TDbLC$ )&ZLPJT̡f@!&m Q8 `&jjKk&$ ]T6pcV [@P .@Ae~ƊE`?O|lfo6%-}2d^&ٷ2hz@u'ֵə?{~:uaЄ!@:!B!B ?'AOttߞ=6y&|2~H+t">u]g=;k~D_dO*!>ET4%̑D$Ff% A4$ġOFqiy2SX> m [ӻ0R[gThOcx1?դ:TC~|X>RC0f]OwTppfz mhR9w]sH!äApP䇑p!r\:wote^}}s=v9)6ISҖjRs.{Һ:"Sď+u:z CmG-Y[.`XPa} OI6-}}ȣ؃Y%]~<.t]\P E^yņlHϬm[54ѶMR8q'i 2sЂ\ΰA"|z9Z]̞+KX?+>#>3Q{gGYUjH \)?eݙO讒9:-u|m&CE|+Λ Goe{aH02+5F{[PK쨬%(zd ,P}a8Xr5yT!0D3jD5L:gSO0`=5\2M}oxOTP#_t}h~ϭ:(V@h<2 @ }z]y[HL"!К1 uTqX#RS]>bX}vV =Q x@oצ.ٲo/uw1+FXa|&O彠 <:ke͸y{85J(;NuAꮊOefs*aϐeL QT^PRS`J.$ P봧!RЛ8%3tFt)#*՗k\ƳW8>|@'5YO 5Mu[<ȡoTF'my[. g.!iR sٺ:/Cwp+_HX8<ވ$²H/g#!6,ʻ_t$W4u%Ur/|(2:Ԏ]sGejfM^6OP<Rӽ&⁐X6O<>}tFPX8cu,Nb|/f+~[V:f_ڮP>뵰5(4#ULvo\,?%9$7T05Z┧ݭdM ٗv 14!לVUh7_YcZYܹ֦sRz"Bsܥ*UZ>R 3\<ٵ` !Z^.Aaf?Z>Su Qp."DD}{:#8RKH}@\zo ($a^T/ gD:@bV)3GFP$Y>0$^G &.)g=>[m+e6=Ef0ʜN;j1ꏬeVvof8h[b(@$'#C|8zs>%̴R;şԬ(^@xd*8NoZDI24.*D rt A02$iG K6d L@,{Sk=|1jģw|^yfߚmrO+_ ^jīҐ@vZN:(%G$XO9?.ifM;ulŭ.Zo s /w)崻={4 ovFETZ{ˊHGK<IJ@BQUDjQ8~>l:S80&![S{0xG=J{xqʈ!a{'zG0&ū3f29ީIZt()Wjb@Ōh.9 `1 >a-3w)D(tKw @ 3;Oy֌Ei(~SBE\1vɟ(8"9yz%_G3Fǀ3>f/#RDž^VTyq@ETUܩ:^sV]L*=7mRߛd#=!(y 9 X d8ώd.vbߛu?'VtagVmdt^6󖓫"Fڌ{e E ;YHXA#-e;c5A G$V/zLL/"TUoOsU$d>ȱl8;ΰxv,>IcT}HPsѥRF0P DrЌZF {r"_:ܯVGfHA\YC2"D$], 4b Ai6/ch^iz/%"TpSpK,{s.*EXu`|2,~x$H,>>Z5H}*mTVPȺ6i] (4YKM+B]z#Yt rWttYםWGW7z#_Ǹ:%@B2^xBo+ '**K~ަ5.kgD5&c't}!+3\St)=4b~ȠLmO=r)I$t$ ! \PbDP+⌅ | e:x)F YԌ Aq 8O"L'^'41'&-T|~Z~AH˯9u -N se_ 4>6˗OUrDwTRٵ%='͞dw42qlBw"D[*yxKBP5_k>DWHz@Ur{^ԣ@/j)߂62tF}I?Vr_?c|CV6҇S8ϋLO3f~ y:NrrLjT$! ϶JuMg8'|0. " ?*V&]~1}%11q8zY׭7!dZ`LW-#QL%wہx6ny8HlFMWO/~auˀ#C#׳ pEGue߶|aCgp5?u,r`qşKѫ(iG5i,F>r!FW'_ꮂ(AhSQ%Z(I5,ҊD$^yۃb" BP'/gDZZvC8v{ cհDlAZ5 SԽj;iE}Z~_]^`4V"KL&L9Vhd%\Jc$| Y'$.*=!:Gxx>-~ \}TSk+_g9dcȬP\V>4}(>jUу~֔>7fQEZM!5S 2igduI\ӿHw Z뚪ZEvЫ420BRj& p T,">I|EiVZ,Ҕ4AdJdwwJU#@P2㗗|}!!*`עaoO ŌOD$E=3^9/݄",]Q'906N }_Ϩ^yL/Y ɼ"Nsܡy|B5[]j27-fko7fSZ^[gqm.,M}P_K@q>_ⴳ8{/f/׭p^}N#u5K%G Tb4퇗G{24̌e⥰kCE߲=lX6@A@@>btJS''%hL fa&9 %9s6/ ˂ճ0ds::M{vǽ֠ aKY E{G:KI ¶ޕQbrX$ihOL> Gx ' A|'X1+r} kPNbG7rQr se= y;vwWڀxHeXE1l+$\ƍI=jrp1X=FX9;2^X5Qـs {%cTZKd$"< Ŋu@;kOpsFpa5!֑2T?Y0N!$߳ulK}`qn,qi*4ASQDT%+ArUiVH$ =^! d!uA"7 eiOJb Dq$PFx<#H]v:pIٟwJ!>;߈a"]l_sO}- y5Ά~ 1v/͂`]>D śd]HKESヤ~'ދ+,\kړ=h@{+,A߿TZbiEu Rm+%>vIP]eJm)0%MAl儺V:SVIkJ{1% =ӒIJ<#PЄcYRHKvROy^Y΀sn]CPO7/֑4$O̥ 4$]h2@D3{3ϓΓ}0!#ڇϨ4X4GutjcaZpX`. mn`{D`Kuo{QۺG% dCq;F0'W Z], wsbXFE g(h7A5ck# Ns1^i"1ffkA,%ecuRi/[EF pwA$H"ǶS C4JT%8םM|/7<rrWWFOLFBP @p@Zv)pb# >Fl՜:r?<]RߒlǫTnIs86{&i5s&A(5L SX% F0Y, Ʋ9!$Aח X4iL/P(Y@ax# _qt΃C@R Pz᱃|/EŨ]W@}ѿ+)+:ID`m>xE^Ѹ!Hwk(4QÆWO ݹV-'?H^A`P*dn-?+L㳵Y;#Nu"U=ʒQkbU=wDқ+ށ0Yhs)*=Ʊ) ĊMdVrGI_ =f5OMDsk-! !Zhq4rLN.p.}\XP_ߣ2Yی>D8:E `?C!;Օ8T7~n 3pG+yO=xKFoG]7x ް~kHJۦDAWQR1YWQ=$AϠF0FR dAbйAFUM& EUޛnǷ~ddthZM @M4'# e c#!D:MϚ=/r_d,Cs &U)D.|`Kd"z  YY%5v,z]~QK4>^_)\({(~{Vf)7`V(ch$WaH ) BBRey/z!RAr!>}8̴)t/6BdfRB! _{נ>.xvR|yD7_>8-4erG Zt2*;  =w{Ҁ3sfN@WWp#vIQ0FOeiH6k T, K3'OH-'x}"ICKꯝ^rPMpoi 0l0ZĨw|I) &"dSLJHK;Uj2 \CGQ>|⟳z (zoX>u}hTR '6tڬbѭ"1䤡V:c=.sY=HΛv*A9=E"@Ѓ1* 1ouYB"O D ^UB*ۥ`ĊKq"7} U=>.H)I4& g"̓ܟeL P$z#$!sأiɝ"Vֿ9>½"q-/~Mw \j#,V_Jso+O@OH2/~\I ŏ;)(Si| aJ;2@ BNW.P't֋MJ|'>\.ŞZf[Y\=b?*RRT+f< XEvk %^$+*S[Ny!V' ުg[y݇`HI{zAIIj'fUq^iHW Y!0q⺒ͽ{AeZ_'t\~'YB-/O.sଐ^F>Y3h (y6ܨKFCEElfH41TI| ޴b> z FXI U(=!ؘR 8d=n{矖B9O "9 "A 8=G4Cb@a77Ε]?lr1'_/7-g7xMS E^J fs 5"UC0 k((*P9M&f_3Y&YM?C&ՙ{yDzb1ǃ'!|'ޚo{eHp#=,Aui ڪ+6{4^µ@qMP-+LPTD-*@!D!tdWfTA~+' xB85qSu 8-J#a,\KK.#861XߒՋmE\2 (zu:gCʊ:H(;ڸ{)pW-M)97=>;| =*GD? !l}ڸpJ /GsK͹lAޅR;!òK! j ;N;[Xu_WG-]/H{YiY@IǢT~${ir_.u_;QdLEZ;H  |G8:G>^{J`yԹX|Kpv!pDA TYW^^/j']4j{zxj]8T9bK>Yn&5` {߾YG:`t̋|&`"\ӧH۬R.Cz@؈9xd$K՚?XhG;}'./p=U1QD}I/ŗStꪘt~=ޗ^zׯ{yn6z6c9ݹnsQ=xwimTmSڍ5E%ji))'obcmmmmmm, ,@, ,@, ,@, A &s9Üp8s9 c1`0c6clmn&"ab*Iji&"ab*Y }Wg86ӘmDqm1ډNb*91T;j&scm9vLsP1"yYo~xk3Zg<3YݝͶ l`m Yd!pYYeeYwrw9rs P 0$z9s8`0c6c׻3m'1 C $T5 ;lP9jru~S6},h0ndS9cm9vLsPg>I$I$N$I$I$뮺I$I$N$I$I$뮺I$I$Hx 1qmmmuI HI$$I8fgI$I$I$ffafff8q$I$I$I<333 330=Ì$I$I$I<333 330=9I$I$I'ffafc888<۞}9P=}$I$I$I>ffafffǞyI$I$I$330333 8:qwטgyͶUPchDd@>&"b$D%bض,łJBD艅\p;`dHXYeJH"P X{c}汶؊"D2& ˗,!ae8qϷyI$I$I$I$I$I$I$I$I$I$I$I$I$I$I'332I$I$I$}љfffffayك:cm0mcm0mcm0mc,,!,,!,,!,>$p8s9s`0c1 c)&"J$b$J)&"J$b$J)&"J$b$J)&"J$u{=CyyyQg8'1mQ3c6m1Dj6L"Mj&sbs&ڍ919mFډIk^WxfNxgƳ;;mm, ,@, ,@BAR(TP*Ju8s9c1`3Rs%Tmk4"Nb$J)&"J$fhDIU$:!q(qX]ݵE c9s͸;PxImDqNb$96aC9bskqf< fk313gsm Yd YeB$JA@(Iף0c=yu) DRI@9I2uq©;ؕE s"N86;35;kΙƸk*< g<3YݮwkA'SGJIHM0q!UR4QDi\kן23fy 8Dd(EPG{Cl (Nb$$J088:oEwvTRmQaqǙ>I$I$I$uRI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$uRI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$uRI$I$I$ddI$I$I$I$I$I$I$I$I$I$I']uԒI$I$I$I$I$I$I$$$I$I$I$I$I$I$I]u$I$I$I$I$I$I$I$I$I$I$IW>>cm5*7U!#:t Yd ]Z[mmYwrhh-bذX 6Tq6DȘDp/b+)&"b*D!aeRU%RH _$a}Q3cl86"dL. 9$H_sϽy|$I$I$I$뮺I$I$I$I$I$I$I$I$I$I$I$c$I$I$I 333 330Îyy$I$I$I<333 330?}]{giyۻ{ͶUDڊ5smTURl`mhh"bض-,-҂%"PBи((ffD!adj"A8dI eǍBiJd((E9s2&Dд,ib$Db `'6yI$I$I$I$I$I$I$I$I$I$I$I$I$I$}s33$I$I$I'ffafff8q<$I$I$I'ffafffs<$I$I$Iᙙfffffayy$I$I$I<333 330=|ss333 3308<$I$I$IᙙfffffaqǞyI$I$I$330333 <$I$I$Iᙙfffffayy$I$I$I<333 330=?oGognݷ۷ns23'߭wB[=s׽mU0uMvQLY6mUARchDd@>Mq1JűlX,fDЉ_1PLP, (332(SHX/~"oIFf* 1T$0\,!ae9q}o9I$I$I$Fffafffs<$I$I$Iᙙfffffa3[~}{UUUYUUUUUUUYUUUU|k3ׯ^zׯ^z3=<}{̪ʪ̪5UU窬hn\pc::wsc]sӽ6ty3<tc1wwלsmglTM3ч9p9m#9s+m*G9NmTgcmQFmQL sQclsj(Z`sQG'ws(6QAmmUURmURmMv(twgM<ڍmFmEmj()MmmQEj6Q(i 6QM%4QILvf90mcm0mcm0mcm0>҂yss9Üp8s?&H"hfj"h&f*f"hfj"hffffff~~ԩ?SF1Q31[b&s9+lQDg3m(vcE9ڌc(g3QbLs>Mk+~gfk5=9gfO@+lQD0186qm&DȐ$"󳳳ӧN2I$I$I$I$I$I$I]u$I$I$I$I$I$I$I'8q̒I$I$I$ 3303338yI$I$I$330333 9yI$I$I$333 330<I:뮤I$I$I$I$I:뮤I$I$I$I$I:뮤I>cp㙝fI$I$I'fffffax<eUUUVfUUUUfd<{ݍ;nsmPSx'^f>u=ޑ435S8:F1Q3;}~_̒I$I$I$afffffaqǞyI$I$I$330333 <$I$I$I'ffafffǞyI$I$I$330333 8c\kZ{vfUUUUfeUUUVfUUUU{{feUUUVfUUUUfeUUUVfz5?~g?o?m| }_='6VmլLLJ~ W<<<<̪ʪ̪ʪ̪ʪj*3*3{yUUUUUUUYUUUUUUUYUUUU:>3>O??ʏ/7W29ظYW;pWUUUUUUUUU{~[?eUUUVqUUUVfUUUUfeUUUVf|{{fZ3>_[{yUUUUUUUYUUUUUUUYUUUUUUUYUUUWo3>c?}|s9'_/7M8[w-j+׮z۽ݩmUAU;j(mSTRQh!`2AbmlύSaF|_;xj6mQ HDB~|LG+c3| !PPǯ˗1ؠ6"L2vrSRT8TrGT$*9Pc1%gA.pH#3R ()Y.L)MfMe^wzziݭ^~3jӎ*<'k5:qpC7TJ:5u(3Zy@}/_GI$I$I$I$I$I$I$I$I$I$I$I$I$I$I]u$I$I$I$$$I$I$I$I$I$I$I$I$I$I$u]I$I$I$I$I$I$I$I2I2I$I$I$I$I$I$I$uRI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$uRI$I$I$I$I$I$I$I$I$I$I$I$I$I$I&H}vGׯ^u!#&:c,/}Du6Rb*X^g86ӟ>\|\}9}ϣ$I$I$I$I$I$I$I$I$I$I$I]u$I$I$I$̒I$I$I$ 330333s<u:q}I1UI'SG|Q3MQa<󳳳ӧN:t$I$I$I$I$I$I$I$I$I$N$I$I$I'לqI$I$I$333 330=8AuQ2D #mmS ~/׬ףM DTSO7y (J$$#cLwO\뮺뮺뮺 :I $HIԇfgI$I$뮺I'ffaqqqqvg׾8~UߵkZֵkZրvVleG"qs9PuI$I$I$I$I$I$I$I$I$I$I$uRI$I$I$O833$I$I$I'ffafffyy$I$I$I<333 330=8kzH!S2:0,9il:3yh>mWŭdI [EXږ5ӱ ӧb51 F4b&HR(1(QThMC,?%ySR- @'xUDPT02V#BiJi1bӡ4:])C %(Szv􊠉~u|{ Zϛo9ֳyyyy̪ʪ̪gx{vfUUUUfeUUUVfUUUUfeUUUVfUUUUfeUUU_@3{{ٙUUUUUUUYUUUUw~k5|onfY_~_ x/W{^Wz^WeUUUVfUUUUfeUUUVfUUUUfeUUUVf{{{y{{̪ʪ̪ʪ3*23>W}f~~szu着޺~o\|׽8:`;Mzuzx=y\1\:랼[=sn8sm흳Q4=BC9p9Üڱ6EGFsw9smb9j mUAz98;j6D60j Bz!psDZ (.!Ú'99DO +xsD&D&mmmmUUUUBmmmUUTmڪ gb 3 Acl*\ H Nmv'mFmmڍ5Q5EUMQ@'mvmQ&hiLmDhDmQFڊ(&$h1LAFڊ("X " (" JQ<;=z=PC۸sT33D-L0EKS34LRD-L0EKS34LRϷoyyr5Tj36PDPmsXlEAA9cmEڌ5Tj36PDPmsXlI #c1e2rA32 PL3 PL3 y  fv,Ai&jfgm,T` Tcq§m{x;plEA1 s9plEA b!r5T9]""  #s G1c=}+aHL$«  mBg9vK3,TB`Ux?$I$I$I$I$I$I$I$I$I$I$I$I$I$I$u]I$I$I$I2I2I$I$I$I$I$I$I$I$I$I$I$uRI$I$I$I$I$I$I$ddI$I$I$I$I$I$I']uԒI$I$I$I$I$I$I$I$I$I$I$$$I$I$I]u$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I>' {{{gi^c6mUAvQCR{u"B m0llll`l,,, @,!m0l!Bmlȃ(8880 1luA'1ɐC 0DEwHC 0DELT"T"AO S`C}db* 8sÇ 3g91C 0DELa h|tӧN:t$I$I$I$I$I$I$I$I$I$I$I$I$I$9$$I$I$I?LffafffOˎs|>I$I$I$fffffax<I$I$I$I$I$I$I$I$I$I$I$I$I$I$I>$$I$I$IFffafffyI$I$I$O 330333s< $I$I']uffafffǞyI$I$Nᙙfff88삉@gggfu]u]u]uI$HI$$ouׯ^fUUUUfeUUUKXm#%}dgރ胅5d1qqqnqqoqp~{^ׯ^zׯ^~'3*23*23*23?!{{UUUYUUUUUUUYUUUUUUUYUUUUUUUYyyyy/9yyy^fUUUUfeUUUVfUUUUfeUUUVfUUUUfeUUUVfUUUUfeUUUVfUUUUfg{{eUUUVfUUUUfeUUUV,,,,Iy[Mqi=F#dEÇow}w}w@}'<<<>3*23*2UUUYUUUUUUUYUUUUUUUYUUUUUUUYUUUUUUUYUUUUU,,,IiMj/IqT@6DuFKZM!ERim09'T$R:%D:\M ij`bi[\9PДPQ2T_TTa?s) bІ&& ѧIF'[:6TK&sF@P)(_zP ?~B'!H/}Mrk.h^73y|VY@TŀXsyHH>O}exfc&կK͇/'?|g=^-u[eA EA U~;3EDPQ΍rqh*tshm61fhI)neLS5%1CQU$MQ"P% CLISQ354P05DT%= >1E:?2@7.5B@1&  Aؙ0IFICC@C2PM#@3 @Q! !BB!`z4{_L3M(/|V?Ťr:[o{4_۪V{+Dnr_Yֿ+[<#(+`bkU]Y@++ b()  9P-:cqgBR45P(RPRQ$T2r̄hh" 4hC8BIJRAUIK0T% - J#ߥOGb:D"5H63#Q66 "J#5D0pɐIH`fSm)1 ,HI$s:(*`mxaUqibWP@u90s}|ƫwa:WL2O? 0۷9]ky}}F>v^RW8%tp㺬o}@? " _F/ZHpZF3$-e$`41IZ(rSLIdʼn*Z (*ZjM[mUAѠ3j&* (J BN߫;𢾆D%!D& .ag8%K#h145 )#,%2ͦC <ژBVmDR0ͦ(bhB x-cAn w _a h ";KhD&gicWt獿Zq7ߜ7T/q ~@bo7Y m9iۦQot3|A$3 B?q&isj)" X(Q|~6xJ@# #TPM1 @P "Nw{bHrH:~B\U1A0y<]ZwT\  K6cH֒kأ3;l\ehm$q G]~f$(*"ba"Z& *fe) A>,fGg~O pH%J@ 'gӳARDTQDRQ  Qwq2K<+h]W~mZQSv+TCc1- ea1vxaJ.ETmߩ_l'=Wf:C-/P?v ?HyFO") *HH?SA0DQ #BNQHU>@ "("b d ?}!"iH(HVbit&~P_wKD^8sX^+}ٻY)qq_8{ڟ'e i_.3呗y}r?V4JlDL0d2:u˂V~>~?@Ϙ0y~$[󒠿rO6JM%n83 lbb3aZ!)YBe )bJ *&EZF&*i**b**ZG?[({i(?YrS@gZ 044N͋ANZ6c&W`bVd!h =8MPLS)B$A3$@)scIg#7//PQo^Fɢ:Rm{8r[{[^ߋϫ?QPwx&CGֻ? F-͍bp'K?A[3<$SJ *a"d>֧@K6$4bM SM30DEUR0S1IA4JSK@PtP( R  )biZ*iiE4⺧flzvX-"PҘS)bc2 !!& @d&$bh(F)e19TE?}~#zQܹ$ dڄvFxiY1jM3ptךǑ?'_e)Ne%ƃ˺IjzL}b^9-NZWE[ix*q $@snMtm9IQQ1 i>ē$9& $̀5"&db"F@4Pꑡ 8)Q!T@V4-SJ4B~ZrF @kA5!spiI\㠐`b e! "TbR!!TS "(--8بEzDA_ t;.nnZv#Cih(dٚAH"_7b{YSg|7]sGgˉaSɼx ed\c椾=g2 \$~J !Ci"*bfJԔ҄-0|c 4i !J4 HP!$zrh(T@OgDz׍Ezh؇(frӣJL{x}+O/꣜tR ube\xfֶzE-0ιZwOҷIJ]|;Y,I*z u vPIAQ_b2f" ""&tQ0TD0Ѓ"I־"S&@@*!"&T\cxQEB~(AzE̠ l= %. cob@HrB%p$ А@A4 @/"'~}@~W!(e`AIGc%$Z(46#Pi**]"iP}7SL)D410L1 Ryp1 @-q!B(\G+D~(nrl̥װ#l|/fѨ9::kˊg@Ŋڐ|~`߀fe@ɂ0sS;gdıBw@گ+ݭLkK RaB5BQ$n}MGx}豿Ɗ(EN4QEQEQEQEQEQEQH UUUUUUUUUUUUUUUUUUUU@ "(H+shazam/R/Core.R0000644000176200001440000000245713476055037012773 0ustar liggesusers#### Transformation functions #### # Converts a matrix to a vector # # \code{clearConsole} clears the console. # # @examples # # Generate a sampel mutations_array # sample_matrix <- matrix(sample(20,4),nrow=2, dimnames=list( c("CDR","FWR"), c("R","S") )) # collapseMatrixToVector(sample_matrix) # collapseMatrixToVector <- function(mat, byrow = FALSE){ # Get the row and column names rnames <- rownames(mat) cnames <- colnames(mat) if (is.null(rnames)) { rnames <- paste0("Row", 1:nrow(mat)) } if (is.null(cnames)) { cnames <- paste0("Column", 1:ncol(mat)) } # Combine the row and columns names cobminedNames <- outer(rnames, cnames, paste, sep = "_") # Collapse the matrix to a vector if (byrow) { collapsed_mat <- c(t(mat)) names(collapsed_mat) <- c(t(cobminedNames)) } else{ collapsed_mat <- c(mat) names(collapsed_mat) <- c(cobminedNames) } return(collapsed_mat) } # Convert columns to uppercase # # @param data data.frame to modify. # @param columns vector of column names to transform to uppercase. # @return The input data.frame with all entries in \code{columns} transformed # to uppercase. toupperColumns <- function(data, columns) { data <- mutate_at(data, columns, toupper) return(data) } shazam/R/RegionDefinitions.R0000644000176200001440000001574613423625773015531 0ustar liggesusers# Class definitions for sequence regions #' @include Shazam.R NULL #### Constants #### # Region color palette REGION_PALETTE <- c("CDR"="#377eb8", "FWR"="#e41a1c", "CDR1"="#ff7f00", "CDR2"="#a65628", "FWR1"="#4daf4a", "FWR2"="#984ea3", "FWR3"="#e41a1c") #### Classes #### #' S4 class defining a region definition #' #' \code{RegionDefinition} defines a common data structure for defining the region #' boundaries of an Ig sequence. #' #' @slot name name of the RegionDefinition. #' @slot description description of the model and its source. #' @slot boundaries \code{factor} defining the region boundaries of the #' sequence. The levels and values of \code{boundaries} #' determine the number of regions. #' @slot seqLength length of the sequence. #' @slot regions levels of the boundaries; e.g, \code{c("CDR", "FWR")}. #' @slot labels labels for the boundary and mutations combinations; #' e.g., \code{c("CDR_R", "CDR_S", "FWR_R", "FWR_S")}. #' @slot citation publication source. #' #' @seealso #' See \link{IMGT_SCHEMES} for a set of predefined \code{RegionDefinition} objects. #' #' @name RegionDefinition-class #' @rdname RegionDefinition-class #' @aliases RegionDefinition #' @exportClass RegionDefinition setClass("RegionDefinition", slots=c(name="character", description="character", boundaries="factor", seqLength="numeric", regions="character", labels="character", citation="character"), prototype=list(name="IMGT_V", description="IMGT_Numbering scheme defining the V gene up to, but not including, CDR3.", boundaries=factor(c(rep("FWR", 78), rep("CDR", 36), rep("FWR", 51), rep("CDR", 30), rep("FWR", 117)), levels=c("CDR","FWR")), seqLength=312, regions=c("CDR", "FWR"), labels=c("CDR_R", "CDR_S", "FWR_R", "FWR_S"), citation="Lefranc MP et al. (2003)")) #### RegionDefinition building functions ##### #' Creates a RegionDefinition #' #' \code{createRegionDefinition} creates a \code{RegionDefinition}. #' #' @param name name of the region definition. #' @param boundaries \code{factor} defining the region boundaries of the sequence. #' The levels and values of \code{boundaries} determine the #' number of regions (e.g. CDR and FWR). #' @param description description of the region definition and its source data. #' @param citation publication source. #' #' @return A \code{RegionDefinition} object. #' #' @seealso See \link{RegionDefinition} for the return object. #' #' @examples #' # Creates an empty RegionDefinition object #' createRegionDefinition() #' #' @export createRegionDefinition <- function(name="", boundaries=factor(), description="", citation="") { #Extract information from 'boundaries' # Determine the number of levels (e.g. CDR, FWR) regions <- levels(boundaries) # Determine the length of the boundaries seqLength <- length(boundaries) # Determine the combinations of levels_regionDefinition and R/S # e.g. CDR_R CDR_S FWR_R, FWR_S labels <- paste(rep(regions, each=2), rep(c("R", "S"), length(regions)), sep="_") # Define RegionDefinition object regionDefinition <- new("RegionDefinition", name=name, description=description, boundaries=boundaries, seqLength=seqLength, regions=regions, labels=labels, citation=citation) return(regionDefinition) } # Create an empty RegionDefinition object # # \code{makeNullRegionDefinition} takes an array of observed mutations # and makes an empty RegionDefinition object. # # @param regionLength Length of the empty # # @return A \code{RegionDefinition} object makeNullRegionDefinition <- function(regionLength) { rd <- createRegionDefinition(name="", boundaries=factor(c(rep("SEQ", regionLength)), levels = c("SEQ")), description="", citation="") return(rd) } #### Data #### #' IMGT unique numbering schemes #' #' Sequence region definitions according to the IMGT unique numbering scheme. #' #' @format A \link{RegionDefinition} object defining: #' \itemize{ #' \item \code{IMGT_V}: The IMGT numbered V segment up to position nucleotide 312. #' This definition combines the CDR1 and CDR2 into a single CDR region, #' and FWR1, FWR2 and FWR3 into a single FWR region. CDR3 and FWR4 are #' excluded as they are downstream of nucleotide 312. #' \item \code{IMGT_V_BY_CODONS}: The IMGT numbered V segment up to position nucleotide 312. #' This definition treats each codon, from codon 1 to codon 104, as a #' distinct region. #' \item \code{IMGT_V_BY_REGIONS}: The IMGT numbered V segment up to position nucleotide 312. #' This defines separate regions for each of CDR1, CDR2, #' FWR1, FWR2 and FWR3. CDR3 and FWR4 are #' excluded as they are downstream of nucleotide 312. #' \item \code{IMGT_V_BY_SEGMENTS}: The IMGT numbered V segment up to position nucleotide 312. #' This definition has no subdivisons and treats the entire V segment #' as a single region. #' } #' #' @references #' \enumerate{ #' \item Lefranc MP, et al. IMGT unique numbering for immunoglobulin and T cell #' receptor variable domains and Ig superfamily V-like domains. #' Developmental and comparative immunology. 2003 27:55-77. #' } #' #' @name IMGT_SCHEMES NULL #' @name IMGT_V #' @rdname IMGT_SCHEMES NULL #' @name IMGT_V_BY_CODONS #' @rdname IMGT_SCHEMES NULL #' @name IMGT_V_BY_REGIONS #' @rdname IMGT_SCHEMES NULL #' @name IMGT_V_BY_SEGMENTS #' @rdname IMGT_SCHEMES NULL shazam/R/Shmulate.R0000644000176200001440000003644713575255254013676 0ustar liggesusers# SHMulate #' @include MutationProfiling.R #' @include Shazam.R NULL #### SHMulation #### #' Simulate mutations in a single sequence #' #' Generates random mutations in a sequence iteratively using a targeting model. #' Targeting probabilities at each position are updated after each iteration. #' #' @param sequence sequence string in which mutations are to be introduced. #' Accepted alphabet: \code{\{A, T, G, C, N, .\}}. Note #' that \code{-} is not accepted. #' @param numMutations number of mutations to be introduced into \code{sequence}. #' @param targetingModel 5-mer \link{TargetingModel} object to be used for computing #' probabilities of mutations at each position. Defaults to #' \link{HH_S5F}. #' @param start Initial position in \code{sequence} where mutations can #' be introduced. Default: 1 #' @param end Last position in \code{sequence} where mutations can #' be introduced. Default: last position (sequence length). #' @return A string defining the mutated sequence. #' #' @details #' If the input \code{sequence} has a non-triplet overhang at the end, it will be trimmed #' to the last codon. For example, \code{ATGCATGC} will be trimmed to \code{ATGCAT}. #' #' Mutations are not introduced to positions in the input \code{sequence} that contain #' \code{.} or \code{N}. #' #' @seealso See \link{shmulateTree} for imposing mutations on a lineage tree. #' See \link{HH_S5F} and \link{MK_RS5NF} for predefined #' \link{TargetingModel} objects. #' #' @examples #' # Define example input sequence #' sequence <- "NGATCTGACGACACGGCCGTGTATTACTGTGCGAGAGATA.TTTA" #' #' # Simulate using the default human 5-mer targeting model #' shmulateSeq(sequence, numMutations=6) #' #' @export shmulateSeq <- function(sequence, numMutations, targetingModel=HH_S5F, start=1, end=nchar(sequence) ) { #* counts on constant variables CODON_TABLE, NUCLEOTIDES (ACTGN-.) # check if numMutations is a whole number # is.wholenumber function borrowed from R's integer help is.wholenumber <- function(x, tol = .Machine$double.eps^0.5) abs(x - round(x)) < tol if (!is.wholenumber(numMutations)) { stop("`numMutations` must be a whole number.") } # Check targeting model if (!is(targetingModel, "TargetingModel")) { stop(deparse(substitute(targetingModel)), " is not a valid TargetingModel object") } # Trim sequence to consider only the interval start:end head_sequence <- "" tail_sequence <- "" seq_len <- stri_length(sequence) if (start<1 | end>seq_len ) { stop("`start` must be >= 1 and `end` must be <= sequence length") } else { head_sequence <- stri_sub(str=sequence, from=0, to=start-1) tail_sequence <- stri_sub(str=sequence, from=end+1, to=seq_len) sequence <- stri_sub(str=sequence, from=start, to=end) } # Trim sequence to last codon (getCodonPos from MutationProfiling.R) if(getCodonPos(stri_length(sequence))[3] > stri_length(sequence)) { warning("Trimming sequence to last codon") sim_seq <- stri_sub(str=sequence, from=1, to=getCodonPos(stri_length(sequence))[1]-1) # Add removed chars to tail_sequence tail_sequence <- paste0( stri_sub(str=sequence, from=getCodonPos(stri_length(sequence))[1], to=stri_length(sequence)), tail_sequence) } else { sim_seq <- sequence } sim_leng <- stri_length(sim_seq) stopifnot((sim_leng %% 3)==0) if (numMutations > sim_leng) { stop("`numMutations` is larger than the length of the sequence.") } # Calculate possible mutations (given codon table) mutation_types <- computeMutationTypes(sim_seq) # Calculate probabilities of mutations at each position given targeting # from MutationProfiling.R; includes a N row # Columns corresponding to "N" and "." positions will have NA across all rows # These get converted to a probability of 0, ensuring that sampleMut() will # never choose these positions targeting <- calculateTargeting(germlineSeq = sim_seq, targetingModel = targetingModel) # keep only ACGT rows targeting <- targeting[NUCLEOTIDES[1:4], ] # set NA to 0 targeting[is.na(targeting)] <- 0 # Make probability of stop codon 0 targeting[mutation_types=="Stop"] <- 0 # Initialize counters total_muts <- 0 positions <- numeric(numMutations) while (total_muts < numMutations) { # Get position to mutate and update counters mutpos <- sampleMut(sim_leng, targeting, positions) total_muts <- total_muts + 1 positions[total_muts] <- mutpos$pos # Implement mutation in simulation sequence mut_nuc <- 4 - (4*mutpos$pos - mutpos$mut) stri_sub(str=sim_seq, from=mutpos$pos, to=mutpos$pos) <- NUCLEOTIDES[mut_nuc] # Update targeting lower <- max(mutpos$pos-4, 1) upper <- min(mutpos$pos+4, sim_leng) targeting[, lower:upper] <- calculateTargeting(germlineSeq = stri_sub(str = sim_seq, from = lower, to = upper), targetingModel = targetingModel)[NUCLEOTIDES[1:4], ] targeting[is.na(targeting)] <- 0 # Update possible mutations lower <- getCodonPos(lower)[1] upper <- getCodonPos(upper)[3] mutation_types[, lower:upper] <- computeMutationTypes(stri_sub(str = sim_seq, from = lower, to = upper)) # Make probability of stop codon 0 if (any(mutation_types[, lower:upper]=="Stop", na.rm=T)) { targeting[, lower:upper][mutation_types[, lower:upper]=="Stop"] <- 0 } } # sanity check: length of sim_seq should remain unchanged after simulation stopifnot(sim_leng==stri_length(sim_seq)) # Add back head and tail sequences sim_seq <- paste0(head_sequence, sim_seq, tail_sequence) return(sim_seq) } #' Simulate mutations in a lineage tree #' #' \code{shmulateTree} returns a set of simulated sequences generated from an input #' sequence and a lineage tree. The input sequence is used to replace the most recent #' common ancestor (MRCA) node of the \code{igraph} object defining the lineage tree. #' Sequences are then simulated with mutations corresponding to edge weights in the tree. #' Sequences will not be generated for groups of nodes that are specified to be excluded. #' #' @param sequence string defining the MRCA sequence to seed mutations from. #' @param graph \code{igraph} object defining the seed lineage tree, with #' vertex annotations, whose edges are to be recreated. #' @param targetingModel 5-mer \link{TargetingModel} object to be used for computing #' probabilities of mutations at each position. Defaults to #' \link{HH_S5F}. #' @param field annotation to use for both unweighted path length exclusion #' and consideration as the MRCA node. If \code{NULL} do not #' exclude any nodes. #' @param exclude vector of annotation values in \code{field} to exclude from #' potential MRCA set. If \code{NULL} do not exclude any nodes. #' Has no effect if \code{field=NULL}. #' @param junctionWeight fraction of the nucleotide sequence that is within the #' junction region. When specified this adds a proportional #' number of mutations to the immediate offspring nodes of the #' MRCA. Requires a value between 0 and 1. If \code{NULL} then #' edge weights are unmodified from the input \code{graph}. #' @param start Initial position in \code{sequence} where mutations can #' be introduced. Default: 1 #' @param end Last position in \code{sequence} where mutations can #' be introduced. Default: last position (sequence length). #' @return A \code{data.frame} of simulated sequences with columns: #' \itemize{ #' \item \code{NAME}: name of the corresponding node in the input #' \code{graph}. #' \item \code{SEQUENCE}: mutated sequence. #' \item \code{DISTANCE}: Hamming distance of the mutated sequence from #' the seed \code{sequence}. #' } #' #' @seealso See \link{shmulateSeq} for imposing mutations on a single sequence. #' See \link{HH_S5F} and \link{MK_RS5NF} for predefined #' \link{TargetingModel} objects. #' #' @examples #' # Load example lineage and define example MRCA #' data(ExampleTrees, package="alakazam") #' graph <- ExampleTrees[[17]] #' sequence <- "NGATCTGACGACACGGCCGTGTATTACTGTGCGAGAGATAGTTTA" #' #' # Simulate using the default human 5-mer targeting model #' shmulateTree(sequence, graph) #' #' # Simulate using the mouse 5-mer targeting model #' # Exclude nodes without a sample identifier #' # Add 20% mutation rate to the immediate offsprings of the MRCA #' shmulateTree(sequence, graph, targetingModel=MK_RS5NF, #' field="SAMPLE", exclude=NA, junctionWeight=0.2) #' #' @export shmulateTree <- function(sequence, graph, targetingModel=HH_S5F, field=NULL, exclude=NULL, junctionWeight=NULL, start=1, end=nchar(sequence)) { ## DEBUG # targetingModel=HH_S5F; field=NULL; exclude=NULL; junctionWeight=NULL # Check targeting model if (!is(targetingModel, "TargetingModel")) { stop(deparse(substitute(targetingModel)), " is not a valid TargetingModel object") } # Determine MRCA of lineage tree mrca_df <- alakazam::getMRCA(graph, path="distance", root="Germline", field=field, exclude=exclude) # Get adjacency matrix adj <- as_adjacency_matrix(graph, attr="weight", sparse=FALSE) # Get names of nodes for which sequences are not to be returned skip_names <- c() if (!is.null(field)) { g <- vertex_attr(graph, name=field) g_names <- vertex_attr(graph, name="name") skip_names <- g_names[g %in% exclude] } # Create data.frame to hold simulated sequences # this will include a row for Germline sim_tree <- data.frame(matrix(NA, ncol=3, nrow=length(V(graph)), dimnames=list(NULL, c("NAME", "SEQUENCE", "DISTANCE")))) sim_tree$NAME <- vertex_attr(graph, name="name") # remove row for Germline sim_tree <- sim_tree[-which(sim_tree$NAME=="Germline"), ] parent_nodes <- mrca_df$NAME[1] nchild <- sum(adj[parent_nodes, ] > 0) sim_tree$SEQUENCE[which(sim_tree$NAME==parent_nodes)] <- sequence sim_tree$DISTANCE[which(sim_tree$NAME==parent_nodes)] <- 0 # Add mutations to the immediate offsprings of the MRCA # Number of mutations added is proportional to fraction of sequence in junction if (!is.null(junctionWeight)) { adj[parent_nodes, ] <- round(adj[parent_nodes, ] * (1 + junctionWeight)) } while (nchild > 0) { new_parents <- c() # Loop through parent-children combos for(p in parent_nodes) { children <- colnames(adj)[adj[p, ] > 0] for(ch in children) { # Add child to new parents new_parents <- union(new_parents, ch) # Simulate sequence for that edge seq <- shmulateSeq(sequence=sim_tree$SEQUENCE[sim_tree$NAME == p], numMutations=adj[p, ch], targetingModel=targetingModel, start=start, end=end) # Update output data.frame chRowIdx = which(sim_tree$NAME==ch) sim_tree$SEQUENCE[chRowIdx] <- seq sim_tree$DISTANCE[chRowIdx] <- adj[p, ch] } } # Re-calculate number of children parent_nodes <- new_parents nchild <- sum(adj[parent_nodes, ] > 0) } # Remove sequences that are to be excluded sim_tree <- sim_tree[!(sim_tree$NAME %in% skip_names), ] # Remove NAs # e.g. if node B is an offspring of node A, and node A has been excluded # then node B will have $SEQUENCE and $DISTANCE of NAs sim_tree <- sim_tree[!is.na(sim_tree$SEQUENCE), ] rownames(sim_tree) <- NULL return(sim_tree) } #### Helper functions #### # Compute the mutations types # # For each position in the input sequence, use \code{CODON_TABLE} to # determine what types of mutations are possible. Returns \code{matrix} # of all possible mutations and corresponding types. # # @param inputSeq sequence for which to compute mutation types # @return A \code{matrix} of mutation types for each position in the sequence. computeMutationTypes <- function(inputSeq){ #* counts on constant variable CODON_TABLE, NUCLEOTIDES (ACTGN-.) #* caution: this breaks down if length of seq is not a multiple of 3 leng_seq <- stri_length(inputSeq) try(if( (leng_seq %%3 !=0) ) stop("length of input sequence must be a multiple of 3")) codons <- sapply(seq(1, leng_seq, by=3), function(x) {substr(inputSeq,x,x+2)}) unrecognized_codons <- codons[!codons %in% colnames(CODON_TABLE)] if (length(unrecognized_codons)>0) { if (all(grepl("^[[:lower:]]+$", unrecognized_codons))) { warning("shazam is case sensitive") } stop("Unrecognized codons found :\n", paste(unrecognized_codons, collapse="\n")) } mut_types <- matrix(unlist(CODON_TABLE[, codons]), ncol=leng_seq, nrow=4, byrow=F) dimnames(mut_types) <- list(NUCLEOTIDES[1:4], 1:leng_seq) return(mut_types) } # Pick a position to mutate # # Sample positions in the sequence to mutate given targeting probability # until a new position is selected. This new position is then added to the # vector of mutated positions and returned. # # @param sim_leng length of sequence in which mutation is being simulated # @param targeting probabilities of each position in the sequence being mutated # @param positions vector of positions which have already been mutated # # @return A \code{list} of mutation and position being mutated. sampleMut <- function(sim_leng, targeting, positions) { if (length(positions) > sim_leng ) { stop("The vector of positions is longer than the length of the sequence.") } pos <- 0 # Sample mutations until new position is selected while (pos %in% positions) { # Randomly select a mutation mut <- sample(1:(4*sim_leng), 1, replace=F, prob=as.vector(targeting)) pos <- ceiling(mut/4) } return(list(mut=mut, pos=pos)) } shazam/R/Shazam.R0000644000176200001440000002362013616575575013333 0ustar liggesusers# shazam package documentation and import directives #' The shazam package #' #' Dramatic improvements in high-throughput sequencing technologies now enable #' large-scale characterization of Ig repertoires, defined as the collection of transmembrane #' antigen-receptor proteins located on the surface of T and B lymphocytes. The \code{shazam} #' package provides tools for advanced analysis of somatic hypermutation (SHM) in #' immunoglobulin (Ig) sequences. The key functions in \code{shazam}, broken down topic, are #' described below. #' #' @section Mutational profiling: #' \code{shazam} provides tools to quantify the extent and nature of SHM within #' full length V(D)J sequences as well as sub-regions (eg, FWR and CDR). #' Quantification of expected mutational loaded, under specific SHM targeting #' models, can also be performed along with model driven simulations of SHM. #' #' \itemize{ #' \item \link{collapseClones}: Build clonal consensus sequences. #' \item \link{consensusSequence}: Build a single consensus sequence. #' \item \link{observedMutations}: Compute observed mutation counts and frequencies. #' \item \link{expectedMutations}: Compute expected mutation frequencies. #' \item \link{shmulateSeq}: Simulate mutations in a single sequence. #' \item \link{shmulateTree}: Simulate mutations over a lineage tree. #' } #' #' @section SHM targeting models: #' Computational models and analyses of SHM have separated the process #' into two independent components: #' \enumerate{ #' \item A mutability model that defines where mutations occur. #' \item A nucleotide substitution model that defines the resulting mutation. #' } #' Collectively these are what form the targeting model of SHM. \code{shazam} #' provides empirically derived targeting models for both humans and mice, #' along with tools to build these mutability and substitution models from data. #' #' \itemize{ #' \item \link{createTargetingModel}: Build a 5-mer targeting model. #' \item \link{plotMutability}: Plot 5-mer mutability rates. #' \item \link{HH_S5F}: Human 5-mer SHM targeting model. #' \item \link{MK_RS5NF}: Mouse 5-mer SHM targeting model. #' } #' #' @section Quantification of selection pressure: #' Bayesian Estimation of Antigen-driven Selection in Ig Sequences is a #' novel method for quantifying antigen-driven selection in high-throughput #' Ig sequence data. Targeting models created using \code{shazam} can be used #' to estimate the null distribution of expected mutation frequencies used #' by BASELINe, providing measures of selection pressure informed by known #' AID targeting biases. #' #' \itemize{ #' \item \link{calcBaseline}: Calculate the BASELINe probability #' density functions (PDFs). #' \item \link{groupBaseline}: Combine PDFs from sequences grouped #' by biological or experimental relevance. #' \item \link{summarizeBaseline}: Compute summary statistics from BASELINe PDFs. #' \item \link{testBaseline}: Perform significance testing for the difference #' between BASELINe PDFs. #' \item \link{plotBaselineDensity}: Plot the probability density functions #' resulting from selection analysis. #' \item \link{plotBaselineSummary}: Plot summary stastistics resulting from #' selection analysis. #' } #' #' @section Mutational distance calculation: #' \code{shazam} provides tools to compute evolutionary distances between #' sequences or groups of sequences, which can leverage SHM targeting #' models. This information is particularly useful in understanding and #' defining clonal relationships. #' #' \itemize{ #' \item \link{findThreshold}: Identify clonal assignment threshold based on #' distances to nearest neighbors. #' \item \link{distToNearest}: Tune clonal assignment thresholds by calculating #' distances to nearest neighbors. #' \item \link{calcTargetingDistance}: Construct a nucleotide distance matrix from a #' 5-mer targeting model. #' } #' #' @name shazam #' @docType package #' @references #' \enumerate{ #' \item Hershberg U, et al. Improved methods for detecting selection by mutation #' analysis of Ig V region sequences. #' Int Immunol. 2008 20(5):683-94. #' \item Uduman M, et al. Detecting selection in immunoglobulin sequences. #' Nucleic Acids Res. 2011 39(Web Server issue):W499-504. (Corrections at #' http://selection.med.yale.edu/baseline/correction/) #' \item Yaari G, et al. Quantifying selection in high-throughput immunoglobulin #' sequencing data sets. #' Nucleic Acids Res. 2012 40(17):e134. #' \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based #' on synonymous mutations from high-throughput immunoglobulin sequencing data. #' Front Immunol. 2013 4:358. #' \item Cui A, Di Niro R, Vander Heiden J, Briggs A, Adams K, Gilbert T, O'Connor K, #' Vigneault F, Shlomchik M and Kleinstein S (2016). A Model of Somatic Hypermutation #' Targeting in Mice Based on High-Throughput Ig Sequencing Data. The Journal of #' Immunology, 197(9), 3566-3574. #' } #' #' @import ggplot2 #' @import graphics #' @import methods #' @import utils #' @importFrom alakazam getAllele getGene getFamily getSegment groupGenes #' getAAMatrix getDNAMatrix IUPAC_DNA #' pairwiseDist nonsquareDist pairwiseEqual #' seqDist seqEqual #' isValidAASeq translateStrings gridPlot #' getMRCA getPathLengths tableEdges #' progressBar baseTheme checkColumns cpuCount #' @importFrom ape mst #' @importFrom diptest dip.test #' @importFrom doParallel registerDoParallel #' @importFrom dplyr do n desc %>% #' bind_cols bind_rows combine #' filter select arrange #' group_by ungroup group_indices #' mutate summarize #' mutate_at summarize_at #' rename transmute #' @importFrom foreach foreach %dopar% registerDoSEQ #' @importFrom igraph V E as_adjacency_matrix graph_from_data_frame #' vertex_attr set_vertex_attr #' @importFrom iterators icount #' @importFrom kedd h.ucv #' @importFrom KernSmooth bkde #' @importFrom lazyeval interp #' @importFrom MASS fitdistr #' @importFrom progress progress_bar #' @importFrom rlang sym syms #' @importFrom scales log2_trans log10_trans trans_breaks trans_format #' math_format percent scientific pretty_breaks #' @importFrom seqinr c2s s2c words translate #' @importFrom stats na.omit setNames ecdf sd cor cov median mad #' approx convolve weighted.mean p.adjust #' dbeta pbeta qbeta rbeta optim optimize #' dnorm pnorm runif dgamma pgamma uniroot na.exclude #' as.dist cutree #' @importFrom stringi stri_dup stri_flatten stri_join stri_length #' stri_sub stri_sub<- stri_detect_regex #' stri_count_boundaries stri_count_regex #' stri_extract_all_regex stri_extract_first_regex #' stri_replace_all_regex stri_replace_first_regex #' @importFrom tidyr gather spread NULL #### Sysdata #### # Deprecated (v0.1.4) mouse single nucleotide distance matrix # # Single nucleotide distance matrix of somatic hypermutation targeting based on # Mus musculus Ig sequence data. # # @format A symmetric matrix of nucleotide substitution distance scores with # row names and column names definition the specific subsitution. # # @references # \enumerate{ # \item Smith DS, et al. Di- and trinucleotide target preferences of somatic # mutagenesis in normal and autoreactive B cells. # J Immunol. 1996 156:2642-52. # } # # M1N_Compat # Deprecated (v0.1.4) Human single nucleotide distance matrix. # # Single nucleotide distance matrix of somatic hypermutation targeting based on # human Ig sequence data. # # @format A symmetric matrix of nucleotide substitution distance scores with # row names and column names definition the specific subsitution. # # @references # \enumerate{ # \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based # on synonymous mutations from high-throughput immunoglobulin sequencing data. # Front Immunol. 2013 4(November):358. # } # # HS1F_Compat # Ordered nucleotide character set # NUCLEOTIDES <- c("A", "C", "G", "T", "N", "-", ".") # IMGT V segment length # VLENGTH <- 312 # 5x312 logical matrix of CDR positions # CDR_Nuc_Mat # 5x312 logical matrix of FWR positions # FWR_Nuc_Mat # 12x216 matrix of replacement and silent mutation permutations # CODON_TABLE # 1x24 vector of amino acid charge classes # AMINO_ACIDS_CHARGE # 1x24 vector of amino acid hydropathy classes # AMINO_ACIDS_HYDROPATHY # 1x24 vector of amino acid polarity classes # AMINO_ACIDS_POLARITY # TODO: What is this? # CONST_I # TODO: And what is this? # BAYESIAN_FITTED # Add built-in variables to global variables environment utils::globalVariables(c("HH_S1F", "HKL_S1F", "MK_RS1NF", "HH_S5F", "HKL_S5F", "MK_RS5NF", "U5N"), package="shazam")shazam/R/DistToNearest.R0000644000176200001440000025560313575255254014641 0ustar liggesusers# Generates distance to nearest neighbor #' @include Shazam.R NULL #### Classes #### #' Output of the \code{gmm} method of findThreshold #' #' \code{GmmThreshold} contains output from the \code{gmm} method \link{findThreshold}. #' It includes parameters of two Gaussian fits and threshold cut. #' #' @slot x input distance vector with NA or infinite values removed. #' @slot model first-second fit functions. #' @slot cutoff type of threshold cut. #' @slot a1 mixing weight of the first curve. #' @slot b1 second parameter of the first curve. Either the mean of a Normal #' distribution or shape of a Gamma distribution. #' @slot c1 third parameter of the first curve. Either the standard deviation of a #' Normal distribution or scale of a Gamma distribution. #' @slot a2 mixing weight of the second curve. #' @slot b2 second parameter of the second curve. Either the mean of a Normal #' distribution or shape of a Gamma distribution. #' @slot c2 third parameter of the second curve. Either the standard deviation #' of a Normal distribution or scale of a Gamma distribution. #' @slot loglk log-likelihood of the fit. #' @slot threshold threshold. #' @slot sensitivity sensitivity. #' @slot specificity specificity. #' @slot pvalue p-value from Hartigans' dip statistic (HDS) test. #' Values less than 0.05 indicate significant bimodality. #' #' @seealso \link{findThreshold} #' #' @name GmmThreshold-class #' @rdname GmmThreshold-class #' @aliases GmmThreshold #' @exportClass GmmThreshold setClass("GmmThreshold", slots=c(x="numeric", model = "character", cutoff = "character", a1="numeric", b1="numeric", c1="numeric", a2="numeric", b2="numeric", c2="numeric", loglk="numeric", threshold="numeric", sensitivity="numeric", specificity="numeric", pvalue="numeric")) #' Output of the \code{dens} method of findThreshold #' #' \code{DensityThreshold} contains output from the \code{dens} method \link{findThreshold}. #' #' @slot x input distance vector with NA or infinite values removed. #' @slot bandwidth bandwidth value fit during density estimation. #' @slot xdens x-axis (distance value) vector for smoothed density estimate. #' @slot ydens y-axis (density) vector for smoothed density estimate. #' @slot threshold distance threshold that separates two modes of the input distribution. #' #' @seealso \link{findThreshold} #' #' @name DensityThreshold-class #' @rdname DensityThreshold-class #' @aliases DensityThreshold #' @exportClass DensityThreshold setClass("DensityThreshold", slots=c(x="numeric", bandwidth="numeric", xdens="numeric", ydens="numeric", threshold="numeric")) #### Methods #### #' @param x GmmThreshold object #' #' @rdname GmmThreshold-class #' @aliases GmmThreshold-method #' @export setMethod("print", c(x="GmmThreshold"), function(x) { print(x@threshold) }) #' @param y ignored. #' @param ... arguments to pass to \link{plotGmmThreshold}. #' #' @rdname GmmThreshold-class #' @aliases GmmThreshold-method #' @export setMethod("plot", c(x="GmmThreshold", y="missing"), function(x, y, ...) { plotGmmThreshold(x, ...) }) #' @param x DensityThreshold object #' #' @rdname DensityThreshold-class #' @aliases DensityThreshold-method #' @export setMethod("print", c(x="DensityThreshold"), function(x) { print(x@threshold) }) #' @param y ignored. #' @param ... arguments to pass to \link{plotDensityThreshold}. #' #' @rdname DensityThreshold-class #' @aliases DensityThreshold-method #' @export setMethod("plot", c(x="DensityThreshold", y="missing"), function(x, y, ...) { plotDensityThreshold(x, ...) }) #### Distance to Nearest #### # Returns a 5-mer sliding window of given sequence # # @param sequence sequence string # @return An array of 5-mer sliding windows # # @examples # window5Mers("ACGTNACGTNACGTN") window5Mers <- function(sequence) { n <- stri_length(sequence) w <- substr(rep(sequence, n - 4), 1:(n - 4), 5:n) return(w) } # Get distance between two sequences of same length, broken by a sliding window of 5mers # # @param seq1 first nucleotide sequence, broken into 5mers. # @param seq2 second nucleotide sequence, broken into 5mers. # @param targetingDistance targeting distance obtained from a targeting model # with the function \code{calcTargetingDistance}. # @param symmetry if model is hs5f, distance between seq1 and seq2 is either # the average (avg) of seq1->seq2 and seq2->seq1 or the # minimum (min). # @return distance between two sequences. # # @examples # seq1 <- c("NNACG", "NACGT", "ACGTA", "CGTAC", "GTACG", "TACGT", "ACGTA", # "CGTAC", "GTACG", "TACGT", "ACGTN", "CGTNN") # seq2 <- c("NNACG", "NACGA", "ACGAA", "CGAAC", "GAACG", "AACGT", "ACGTA", # "CGTAC", "GTACG", "TACGT", "ACGTN", "CGTNN") # targeting_distance <- calcTargetingDistance(HH_S5F) # shazam:::dist5Mers(seq1, seq2, targeting_distance) dist5Mers <- function(seq1, seq2, targetingDistance, symmetry=c("avg", "min", "raw")) { # Evaluate choices symmetry <- match.arg(symmetry) # Get distance from targeting model #targeting_dist <- calcTargetingDistance(targetingModel) # Check all characters in seq1 and seq2 are valid, # found in the targetingModel distance matrix validChars <- rownames(targetingDistance) allChars <- unique(strsplit(paste(c(seq1, seq2), collapse=""), "")[[1]]) invalidChars <- allChars[allChars %in% validChars == F] if (length(invalidChars) > 0 ) { stop(paste0("Character not found in targeting_dist: ", paste(invalidChars, collapse=", "))) } # Compute distance only on fivemers that have mutations fivemersWithMu <- substr(seq1, 3, 3) != substr(seq2, 3, 3) #fivemersWithNonNuc <- (!is.na(match(substr(seq1,3,3),c("A","C","G","T"))) & # !is.na(match(substr(seq2,3,3),c("A","C","G","T")))) #fivemersWithMu <- fivemersWithMu & fivemersWithNonNuc seq1 <- seq1[fivemersWithMu] seq2 <- seq2[fivemersWithMu] # Number of mutations (for normalization, if specified) #numbOfMutation <- sum(fivemersWithMu) dist <- NA tryCatch({ if (length(seq1)==1){ seq1_to_seq2 <- targetingDistance[substr(seq2, 3, 3), seq1] seq2_to_seq1 <- targetingDistance[substr(seq1, 3, 3), seq2] } else { seq1_to_seq2 <- diag(targetingDistance[substr(seq2, 3, 3), seq1]) seq2_to_seq1 <- diag(targetingDistance[substr(seq1, 3, 3), seq2]) } if (symmetry == "avg") { dist <- sum(apply(cbind(seq1_to_seq2, seq2_to_seq1), 1, mean)) } else if (symmetry == "min") { dist <- sum(apply(cbind(seq1_to_seq2, seq2_to_seq1), 1, min)) } else if (symmetry == "raw") { dist <- c(seq1_to_seq2, seq2_to_seq1) } }, error = function(e) { warning(e) return(NA) }) return(dist) } # Given an array of nucleotide sequences, find the pairwise distances # # @param sequences character vector of nucleotide sequences. # @param targetingDistance targeting distance obtained from a targeting model # with the function `calcTargetingDistance` # @param symmetry if model is hs5f, distance between seq1 and seq2 is either the # average (avg) of seq1->seq2 and seq2->seq1 or the minimum (min). # # @return A matrix of pairwise distances between junction sequences. pairwise5MerDist <- function(sequences, targetingDistance, symmetry=c("avg", "min")) { # get names seq_names <- names(sequences) # Initial checks symmetry <- match.arg(symmetry) # Convert junctions to uppercase sequences <- toupper(sequences) # Convert gaps to Ns sequences <- gsub('[-.]', 'N', sequences, fixed=T) # Add 'NN' to front and end of each sequence for fivemers sequences <- as.vector(sapply(sequences, function(x){ paste("NN", x, "NN", sep="") })) n_seq <- length(sequences) #Junctions are broken in to 5-mers based on a sliding window (of one) and placed in matrix #Each column is a junction #E.g. junctions 1234567, ABCDEFG, JKLMNOP becomes: # 12345 ABCDE JKLMN # 23456 BCDEF KLMNO # 34567 CDEFG LMNOP .matSeqSlidingFiveMer <- sapply(sequences, function(x) { window5Mers(x) }, simplify="matrix") # Compute pairwise distance between all sequences' fivemers (by column) .dist <- function(i) { c(rep.int(0, i - 1), sapply(i:n_seq, function(j) { dist5Mers(.matSeqSlidingFiveMer[,i], .matSeqSlidingFiveMer[,j], targetingDistance, symmetry=symmetry) })) } dist_mat <- sapply(1:n_seq, .dist) # Make distance matrix symmetric dist_mat <- dist_mat + t(dist_mat) # assign names if (!is.null(seq_names)) { rownames(dist_mat) <- seq_names colnames(dist_mat) <- seq_names } return(dist_mat) } # Given an array of nucleotide sequences and a vector indices (a subset of array of nucleotide sequences), # find the pairwise distances # # @param sequences character vector of nucleotide sequences. # @paramindx numeric vector of subsamples indices # @param targetingDistance targeting distance obtained from a targeting model # with the function `calcTargetingDistance` # @param symmetry if model is hs5f, distance between seq1 and seq2 is either the # average (avg) of seq1->seq2 and seq2->seq1 or the minimum (min). # # @return A non-square matrix of pairwise distances between junction sequences. nonsquare5MerDist <- function(sequences, indx, targetingDistance, symmetry=c("avg", "min")) { # get names seq_names <- names(sequences) # Initial checks symmetry <- match.arg(symmetry) # Convert junctions to uppercase sequences <- toupper(sequences) # Convert gaps to Ns sequences <- gsub('[-.]', 'N', sequences, fixed=T) # Add 'NN' to front and end of each sequence for fivemers sequences <- as.vector(sapply(sequences, function(x){ paste("NN", x, "NN", sep="") })) n_seq <- length(sequences) #Junctions are broken in to 5-mers based on a sliding window (of one) and placed in matrix #Each column is a junction #E.g. junctions 1234567, ABCDEFG, JKLMNOP becomes: # 12345 ABCDE JKLMN # 23456 BCDEF KLMNO # 34567 CDEFG LMNOP .matSeqSlidingFiveMer <- sapply(sequences, function(x) { window5Mers(x) }, simplify="matrix") # # Compute pairwise distance between all sequences' fivemers (by column) # .dist <- function(i) { # d <- c(rep.int(0, i - 1), # sapply(i:n_seq, function(j) { dist5Mers(.matSeqSlidingFiveMer[,i], # .matSeqSlidingFiveMer[,j], # targetingDistance, # symmetry=symmetry) })) # } dist_mat <- matrix(NA, nrow=n_seq, ncol=n_seq) diag(dist_mat) <- 0 indx <- sort(indx) for (i in 1:n_seq) { if (!(i %in% indx)) next for (j in 1:n_seq) { if (!is.na(dist_mat[i,j])) next dist_mat[i,j] = dist5Mers(.matSeqSlidingFiveMer[,i], .matSeqSlidingFiveMer[,j], targetingDistance, symmetry=symmetry) dist_mat[j,i] = dist_mat[i,j] } } sub_dist_mat <- dist_mat[indx,] # assign names if (!is.null(seq_names)) { rownames(sub_dist_mat) <- seq_names[indx] colnames(sub_dist_mat) <- seq_names } return(sub_dist_mat) } # Subset to unique sequences # # @param sequences character vector of sequences # # @return Named vector of unique sequences, with names as the sequence itself. findUniqSeq <- function(sequences) { seq_uniq <- unique(sequences) names(seq_uniq) <- seq_uniq return(seq_uniq) } # Get chars in the distance model # # @param model # # @return vector of unique chars in the distance model # @examples # getCharsInModel("hh_s1f") getCharsInModel <- function(model) { if (model == "ham") { chars <- colnames(getDNAMatrix(gap=0)) } else if (model == "aa") { chars <- colnames(getAAMatrix()) } else if (model == "hh_s1f") { chars <- colnames(HH_S1F_Distance) } else if (model == "hh_s5f") { chars <-rownames(HH_S5F@targeting) } else if (model == "mk_rs1nf") { chars <- colnames(MK_RS1NF_Distance) } else if (model == "mk_rs5nf") { chars <-rownames(MK_RS1NF@targeting) } else if (model == "hs1f_compat") { chars <- colnames(HS1F_Compat) } else if (model == "m1n_compat") { chars <- colnames(M1N_Compat) } return(chars) } # Validate the sequence # # @param seq # @param validChars # # @return TRUE is all the character in the sequence are found in validChars; # FALSE otherwise # @examples # allValidChars("ATCG", getCharsInModel("hh_s1f")) # allValidChars("ATCG.", getCharsInModel("hh_s1f")) # allValidChars("ATCGJ", getCharsInModel("hh_s1f")) allValidChars <- function(seq, validChars) { all(unique(strsplit(seq, "")[[1]]) %in% validChars) } # Given an array of sequences, find the distance to the closest sequence # # @param sequences character vector of sequences. # @param model 5-mer or 1-mer distance model # @param normalize method of normalization. Default is "none". # "len" = normalize distance by length of junction. # "mut" = normalize distance by number of mutations in # junction. # @param symmetr if model is hs5f or mrs5nf, distance between seq1 and seq2 is either the # average (avg) of seq1->seq2 and seq2->seq1 or the minimum (min). # @param crossGroups column for grouping to calculate distances across groups # (self vs others). # @param mst if true, return comma-separated branch lengths from minimum # spanning tree. # # @return A vector of distances to the closest sequence. # # @examples # sequences <- c("ACGTACGTACGT", "ACGAACGTACGT", "ACGAACGTATGT", "ACGAACGTATGC", # "ACGAACGTATCC", "AAAAAAAAAAAA", "A-GAACGTATCC", "AAAAAA---AAA") # shazam:::nearestDist(sequences, model="ham", normalize="none") # shazam:::nearestDist(sequences, model="aa", normalize="none") # shazam:::nearestDist(sequences, model="ham", normalize="len") # shazam:::nearestDist(sequences, model="aa", normalize="len") nearestDist <- function(sequences, model=c("ham", "aa", "hh_s1f", "hh_s5f", "mk_rs1nf", "mk_rs5nf", "hs1f_compat", "m1n_compat"), normalize=c("none", "len", "mut"), symmetry=c("avg", "min"), crossGroups=NULL, mst=FALSE, subsample=NULL) { ## DEBUG # sequences <- c("ACGTACGTACGT", "ACGAACGTACGT", "AAAAAAAAAAAA", "A-AAAA---AAA") # model="aa"; normalize="len"; crossGroups=NULL; mst=FALSE # Initial checks model <- match.arg(model) normalize <- match.arg(normalize) ## If crossGroup requested, but only one group found, return NA if (!is.null(crossGroups) & length(unique(crossGroups)) < 2) { seq_dist <- rep(NA, length(sequences)) return (seq_dist) } # Find unique sequences seq_uniq <- findUniqSeq(sequences) n_uniq <- length(seq_uniq) # corresponding crossGroups values for seq_uniq if (!is.null(crossGroups)) { stopifnot( all.equal(sequences[match(seq_uniq, sequences)], seq_uniq, check.attributes=FALSE) ) crossGroups_uniq <- crossGroups[match(seq_uniq, sequences)] } # Initialize return vector and computation vector seq_dist <- setNames(rep(NA, length(sequences)), sequences) seq_uniq_dist <- rep(NA, n_uniq) # Compute distances between sequences if (n_uniq > 1) { # Check for length mismatches seq_length <- unique(stri_length(seq_uniq)) if (length(seq_length) > 1) { stop("Unexpected. Different sequence lengths found.") } # check subSampling subSampling <- all(!is.null(subsample), subsample < n_uniq) if (subSampling) indx <- sample(x=1:n_uniq, size=subsample, replace=FALSE, prob=NULL) # corresponding subsampling of crossGroups_uniq if (subSampling & !is.null(crossGroups)) { crossGroups_uniq_sub <- crossGroups_uniq[indx] } # Get distance matrix if (model == "ham") { if (subSampling) { dist_mat <- nonsquareDist(seq_uniq, indx, dist_mat=getDNAMatrix(gap=0)) } else { dist_mat <- pairwiseDist(seq_uniq, dist_mat=getDNAMatrix(gap=0)) } } else if (model == "aa") { seq_uniq <- setNames(alakazam::translateDNA(seq_uniq), seq_uniq) if (subSampling) { dist_mat <- nonsquareDist(seq_uniq, indx, dist_mat=getAAMatrix()) } else { dist_mat <- pairwiseDist(seq_uniq, dist_mat=getAAMatrix()) } } else if (model == "hh_s1f") { if (subSampling) { dist_mat <- nonsquareDist(seq_uniq, indx, dist_mat=HH_S1F_Distance) } else { dist_mat <- pairwiseDist(seq_uniq, dist_mat=HH_S1F_Distance) } } else if (model == "mk_rs1nf") { if (subSampling) { dist_mat <- nonsquareDist(seq_uniq, indx, dist_mat=MK_RS1NF_Distance) } else { dist_mat <- pairwiseDist(seq_uniq, dist_mat=MK_RS1NF_Distance) } } else if (model == "hh_s5f") { if (subSampling) { dist_mat <- nonsquare5MerDist(seq_uniq, indx, HH_S5F_Distance, symmetry=symmetry) } else { dist_mat <- pairwise5MerDist(seq_uniq, HH_S5F_Distance, symmetry=symmetry) } } else if (model == "mk_rs5nf") { if (subSampling) { dist_mat <- nonsquare5MerDist(seq_uniq, indx, MK_RS5NF_Distance, symmetry=symmetry) } else { dist_mat <- pairwise5MerDist(seq_uniq, MK_RS5NF_Distance, symmetry=symmetry) } } else if (model == "hs1f_compat") { if (subSampling) { dist_mat <- nonsquareDist(seq_uniq, indx, dist_mat=HS1F_Compat) } else { dist_mat <- pairwiseDist(seq_uniq, dist_mat=HS1F_Compat) } } else if (model == "m1n_compat") { if (subSampling) { dist_mat <- nonsquareDist(seq_uniq, indx, dist_mat=M1N_Compat) } else { dist_mat <- pairwiseDist(seq_uniq, dist_mat=M1N_Compat) } } ## DEBUG # cat("\n-> seq_uniq:\n") # print(seq_uniq) # cat("\n-> dist_mat (raw):\n") # print(dist_mat) # Normalize distances if (normalize == "len") { dist_mat <- dist_mat / seq_length } else if (normalize == "mut") { #dist <- dist/sum(strsplit(seq1,"")[[1]] != strsplit(seq2,"")[[1]]) stop('Sorry! nomalize="mut" is not available.') } ## DEBUG # cat("\n-> seq_length:\n") # print(seq_length) # cat("\n-> dist_mat (normalized):\n") # print(dist_mat) } else { return(seq_dist) } # Find minimum distance for each sequence if (is.null(crossGroups)) { if(!mst) { # Return smaller value greater than 0 # If all 0, return NA .dmin <- function(i) { x <- dist_mat[, i] gt0 <- which(x > 0) if (length(gt0) != 0) { min(x[gt0]) } else { NA } } ## TODO: Could be an apply over columns seq_uniq_dist <- setNames(sapply(1:n_uniq, .dmin), names(seq_uniq)) } else { # Get adjacency matrix of minimum spanning tree adj <- ape::mst(dist_mat) # TODO: This could be cleaner # Get value(s) from mst branches # If none (broken mst!), return NA # If multiple values, comma-join .dmst <- function(i) { gt0 <- which(adj[, i] == 1) if (length(gt0) != 0) { stri_join(round(dist_mat[, i][gt0], 4), collapse=",") } else { NA } } ## TODO: Could be an apply over columns seq_uniq_dist <- setNames(sapply(1:n_uniq, .dmst), names(seq_uniq)) } # Define return distance vector seq_dist <- seq_uniq_dist[match(names(seq_dist), names(seq_uniq_dist))] ## DEBUG # cat("\n-> seq_uniq_dist:\n") # print(seq_uniq_dist) # cat("\n-> seq_dist:\n") # print(seq_dist) } else { # Identify sequences to be considered when finding minimum # cross distance .dcross <- function(i) { #cat(i,"\n") this_group <- crossGroups[i] other_groups <- which(crossGroups != this_group) other_seq <- unique(sequences[other_groups]) other_idx <- match(other_seq, seq_uniq) this_idx <- match(sequences[i], seq_uniq) stopifnot( all.equal( other_seq, seq_uniq[other_idx] , check.attributes=FALSE ) ) stopifnot( all.equal( sequences[i], seq_uniq[this_idx] , check.attributes=FALSE ) ) # the next two checks may not always be true # this happens when all the out-group sequences are identical to the in-group sequences #stopifnot( all( crossGroups_uniq[other_idx] != this_group ) ) #stopifnot( crossGroups_uniq[this_idx] == this_group ) if (subSampling) { # When there is subsampling, nonsquareDist returns a non-n-by-n matrix # This matrix has fewers than n rows, and exactly n cols # For each unique sequence, look for its cross-group distances in its column, # NOT in its row (because there will be fewer than n rows) # dist_mat rows correspond to seq_uniq[indx] # (indx itself is wrt seq_uniq) # (other_idx is also wrt seq_uni) # which other_seq are included in the subsampled seqs represented by # the available rows in dist_mat? # wrt dist_mat other_avail_wrt_dist_mat <- which(indx %in% other_idx) if (length(other_avail_wrt_dist_mat)>0) { # the next two checks may not always be true # this happens when all the out-group sequences are identical to the in-group sequences #stopifnot(all( crossGroups_uniq_sub[other_avail_wrt_dist_mat] != this_group )) #stopifnot(all( crossGroups_uniq_sub[-other_avail_wrt_dist_mat] == this_group )) r <- dist_mat[other_avail_wrt_dist_mat, this_idx] } else { stopifnot(all( crossGroups_uniq_sub == this_group )) return(NA) } } else { # without subsampling # dist_mat is a n-by-n matrix stopifnot( all(other_idx <= nrow(dist_mat) ) ) r <- dist_mat[other_idx, this_idx] } gt0 <- which(r > 0) if (length(gt0) != 0) { return(min(r[gt0])) } else { return(NA) } } # Define return distance vector seq_dist <- setNames(sapply(1:length(sequences), .dcross), sequences) } return(round(seq_dist, 4)) } #' Distance to nearest neighbor #' #' Get non-zero distance of every heavy chain (\code{IGH}) sequence (as defined by #' \code{sequenceColumn}) to its nearest sequence in a partition of heavy chains sharing the same #' V gene, J gene, and junction length (VJL), or in a partition of single cells with heavy chains #' sharing the same heavy chain VJL combination, or of single cells with heavy and light chains #' sharing the same heavy chain VJL and light chain VJL combinations. #' #' @param db data.frame containing sequence data. #' @param sequenceColumn name of the column containing the junction for grouping and for calculating #' nearest neighbot distances. Note that while both heavy and light chain junctions #' may be used for VJL grouping, only the heavy chain junction is used to calculate #' distances. #' @param vCallColumn name of the column containing the V-segment allele calls. #' @param jCallColumn name of the column containing the J-segment allele calls. #' @param model underlying SHM model, which must be one of #' \code{c("ham", "aa", "hh_s1f", "hh_s5f", "mk_rs1nf", "hs1f_compat", "m1n_compat")}. #' See Details for further information. #' @param normalize method of normalization. The default is \code{"len"}, which #' divides the distance by the length of the sequence group. If #' \code{"none"} then no normalization if performed. #' @param symmetry if model is hs5f, distance between seq1 and seq2 is either the #' average (avg) of seq1->seq2 and seq2->seq1 or the minimum (min). #' @param first if \code{TRUE} only the first call of the gene assignments #' is used. if \code{FALSE} the union of ambiguous gene #' assignments is used to group all sequences with any #' overlapping gene calls. #' @param VJthenLen a Boolean value specifying whether to perform partitioning as a 2-stage #' process. If \code{TRUE}, partitions are made first based on V and J #' annotations, and then further split based on junction lengths corresponding #' to \code{sequenceColumn}. If \code{FALSE}, perform partition as a 1-stage #' process during which V annotation, J annotation, and junction length are used #' to create partitions simultaneously. Defaults to \code{TRUE}. #' @param nproc number of cores to distribute the function over. #' @param fields additional fields to use for grouping. #' @param cross character vector of column names to use for grouping to calculate #' distances across groups. Meaning the columns that define self versus others. #' @param mst if \code{TRUE}, return comma-separated branch lengths from minimum #' spanning tree. #' @param subsample number of sequences to subsample for speeding up pairwise-distance-matrix calculation. #' Subsampling is performed without replacement in each VJL group of heavy chain sequences. #' If \code{subsample} is larger than the unique number of heavy chain sequences in each #' VJL group, then the subsampling process is ignored for that group. For each heavy chain #' sequence in \code{db}, the reported \code{DIST_NEAREST} is the distance to the closest #' heavy chain sequence in the subsampled set for the VJL group. If \code{NULL} no #' subsampling is performed. #' @param progress if \code{TRUE} print a progress bar. #' @param cellIdColumn name of the column containing cell IDs. Only applicable and required for #' single-cell mode. #' @param locusColumn name of the column containing locus information. Only applicable and #' required for single-cell mode. #' @param groupUsingOnlyIGH use only heavy chain (\code{IGH}) sequences for VJL grouping, disregarding #' light chains. Only applicable and required for single-cell mode. #' Default is \code{TRUE}. Also see \link[alakazam]{groupGenes}. #' @param keepVJLgroup a Boolean value specifying whether to keep in the output the the column #' column indicating grouping based on VJL combinations. Only applicable for #' 1-stage partitioning (i.e. \code{VJthenLen=FALSE}). Also see #' \link[alakazam]{groupGenes}. #' #' @return Returns a modified \code{db} data.frame with nearest neighbor distances between heavy chain #' sequences in the \code{DIST_NEAREST} column if \code{cross=NULL}. If \code{cross} was #' specified, distances will be added as the \code{CROSS_DIST_NEAREST} column. #' #' Note that distances between light chain sequences are not calculated, even if light chains #' were used for VJL grouping via \code{groupUsingOnlyIGH=FALSE}. Light chain sequences, if any, #' will have \code{NA} in the \code{DIST_NEAREST} field. #' #' @details #' #' To invoke single-cell mode, both \code{cellIdColumn} and \code{locusColumn} must be supplied. #' Otherwise, the function will run under non-single-cell mode. #' #' Under single-cell mode, only heavy chain sequences will be used for calculating nearest neighbor #' distances. Under non-single-cell mode, all input sequences will be used for calculating nearest #' neighbor distances, regardless of the values in the \code{locusColumn} field (if present). #' #' For single-cell mode, the input format is the same as that for \link[alakazam]{groupGenes}. #' Namely, each row represents a sequence/chain. Sequences/chains from the same cell are linked #' by a cell ID in the \code{cellIdColumn} field. Under this mode, there is a choice of whether #' grouping should be done using only heavy chain (\code{IGH}) sequences only, or using both #' heavy chain (\code{IGH}) and light chain (\code{IGK}, \code{IGL}) sequences. This is governed #' by \code{groupUsingOnlyIGH}. #' #' If used, values in the \code{locusColumn} column must be one of \code{"IGH"}, \code{"IGK"}, and \code{"IGL"}. #' #' Note that for \code{distToNearest}, a cell with multiple heavy chains is not allowed. #' #' The distance to nearest (heavy chain) neighbor can be used to estimate a threshold for assigning #' Ig sequences to clonal groups. A histogram of the resulting vector is often bimodal, with the #' ideal threshold being a value that separates the two modes. #' #' The following distance measures are accepted by the \code{model} parameter. #' #' \itemize{ #' \item \code{"ham"}: Single nucleotide Hamming distance matrix from \link[alakazam]{getDNAMatrix} #' with gaps assigned zero distance. #' \item \code{"aa"}: Single amino acid Hamming distance matrix from \link[alakazam]{getAAMatrix}. #' \item \code{"hh_s1f"}: Human single nucleotide distance matrix derived from \link{HH_S1F} with #' \link{calcTargetingDistance}. #' \item \code{"hh_s5f"}: Human 5-mer nucleotide context distance matix derived from \link{HH_S5F} with #' \link{calcTargetingDistance}. #' \item \code{"mk_rs1nf"}: Mouse single nucleotide distance matrix derived from \link{MK_RS1NF} with #' \link{calcTargetingDistance}. #' \item \code{"mk_rs5nf"}: Mouse 5-mer nucleotide context distance matrix derived from \link{MK_RS1NF} with #' \link{calcTargetingDistance}. #' \item \code{"hs1f_compat"}: Backwards compatible human single nucleotide distance matrix used in #' SHazaM v0.1.4 and Change-O v0.3.3. #' \item \code{"m1n_compat"}: Backwards compatibley mouse single nucleotide distance matrix used in #' SHazaM v0.1.4 and Change-O v0.3.3. #' } #' #' Note on \code{NA}s: if, for a given combination of V gene, J gene, and sequence length, #' there is only 1 heavy chain sequence (as defined by \code{sequenceColumn}), \code{NA} is #' returned instead of a distance (since it has no heavy chain neighbor). If for a given combination #' there are multiple heavy chain sequences but only 1 unique one, (in which case every heavy cahin #' sequence in this group is the de facto nearest neighbor to each other, thus giving rise to distances #' of 0), \code{NA}s are returned instead of zero-distances. #' #' Note on \code{subsample}: Subsampling is performed independently in each VJL group for heavy chain #' sequences. If \code{subsample} is larger than number of heavy chain sequences in the group, it is #' ignored. In other words, subsampling is performed only on groups in which the number of heavy chain #' sequences is equal to or greater than \code{subsample}. \code{DIST_NEAREST} has values calculated #' using all heavy chain sequences in the group for groups with fewer than \code{subsample} heavy chain #' sequences, and values calculated using a subset of heavy chain sequences for the larger groups. #' To select a value of \code{subsample}, it can be useful to explore the group sizes in \code{db} #' (and the number of heavy chain sequences in those groups). #' #' @references #' \enumerate{ #' \item Smith DS, et al. Di- and trinucleotide target preferences of somatic #' mutagenesis in normal and autoreactive B cells. #' J Immunol. 1996 156:2642-52. #' \item Glanville J, Kuo TC, von Budingen H-C, et al. #' Naive antibody gene-segment frequencies are heritable and unaltered by #' chronic lymphocyte ablation. #' Proc Natl Acad Sci USA. 2011 108(50):20066-71. #' \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based #' on synonymous mutations from high-throughput immunoglobulin sequencing data. #' Front Immunol. 2013 4:358. #' } #' #' @seealso See \link{calcTargetingDistance} for generating nucleotide distance matrices #' from a \link{TargetingModel} object. See \link{HH_S5F}, \link{HH_S1F}, #' \link{MK_RS1NF}, \link[alakazam]{getDNAMatrix}, and \link[alakazam]{getAAMatrix} #' for individual model details. #' #' @examples #' # Subset example data to one sample as a demo #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, SAMPLE == "-1h") #' #' # Use genotyped V assignments, Hamming distance, and normalize by junction length #' # First partition based on V and J assignments, then by junction length #' # Take into consideration ambiguous V and J annotations #' dist <- distToNearest(db, vCallColumn="V_CALL_GENOTYPED", model="ham", #' first=FALSE, VJthenLen=TRUE, normalize="len") #' #' # Plot histogram of non-NA distances #' p1 <- ggplot(data=subset(dist, !is.na(DIST_NEAREST))) + #' theme_bw() + #' ggtitle("Distance to nearest: Hamming") + #' xlab("distance") + #' geom_histogram(aes(x=DIST_NEAREST), binwidth=0.025, #' fill="steelblue", color="white") #' plot(p1) #' #' @export distToNearest <- function(db, sequenceColumn="JUNCTION", vCallColumn="V_CALL", jCallColumn="J_CALL", model=c("ham", "aa", "hh_s1f", "hh_s5f", "mk_rs1nf", "mk_rs5nf", "m1n_compat", "hs1f_compat"), normalize=c("len", "none"), symmetry=c("avg", "min"), first=TRUE, VJthenLen=TRUE, nproc=1, fields=NULL, cross=NULL, mst=FALSE, subsample=NULL, progress=FALSE, cellIdColumn=NULL, locusColumn=NULL, groupUsingOnlyIGH=TRUE, keepVJLgroup=TRUE) { # Hack for visibility of foreach index variables i <- NULL # Initial checks model <- match.arg(model) normalize <- match.arg(normalize) symmetry <- match.arg(symmetry) if (!is.data.frame(db)) { stop('Must submit a data frame') } # single-cell mode? if ( !is.null(cellIdColumn) & !is.null(locusColumn) ) { singleCell <- TRUE if (!all(db[[locusColumn]] %in% c("IGH", "IGK", "IGL"))) { stop("The locus column must be one of {IGH, IGK, IGL}.") } } else { singleCell <- FALSE } columns <- c(sequenceColumn, vCallColumn, jCallColumn, fields, cross) columns <- columns[!is.null(columns)] check <- checkColumns(db, columns) if (check != TRUE) { stop(check) } # Convert sequence columns to uppercase db <- toupperColumns(db, c(sequenceColumn)) # Disallow multiple heavy chains per cell if (singleCell) { bool <- sapply(unique(db[[cellIdColumn]]), function(x) { return( sum( db[[locusColumn]][db[[cellIdColumn]]==x] == "IGH" )>1 ) } ) if (any(bool)) { stop("Detected multiple heavy chains in cell(s). Each cell must contain only 1 heavy chain.") } } # Check for invalid characters # heavy valid_seq <- sapply(db[[sequenceColumn]], allValidChars, getCharsInModel(model)) not_valid_seq <- which(!valid_seq) if (length(not_valid_seq) > 0) { warning("Invalid sequence characters in the ", sequenceColumn, " column. ", length(not_valid_seq), " sequence(s) removed") db <- db[valid_seq, ] } # junction length columns (prep for groupGenes) junc_len <- "JUNC_LEN" db[[junc_len]] <- stri_length(db[[sequenceColumn]]) # create V+J grouping, or V+J+L grouping if (VJthenLen) { # 2-stage partitioning using first V+J and then L # V+J only first # creates $VJ_GROUP db <- groupGenes(db, v_call=vCallColumn, j_call=jCallColumn, junc_len=NULL, cell_id=cellIdColumn, locus=locusColumn, only_igh=groupUsingOnlyIGH, first=first) # L (later) group_cols <- c("VJ_GROUP", junc_len) } else { # 1-stage partitioning using V+J+L simultaneously # creates $VJ_GROUP # note that despite the name (VJ), this is based on V+J+L db <- groupGenes(db, v_call=vCallColumn, j_call=jCallColumn, junc_len=junc_len, cell_id=cellIdColumn, locus=locusColumn, only_igh=groupUsingOnlyIGH, first=first) group_cols <- c("VJ_GROUP") } # groups to use if (!is.null(fields)) { group_cols <- append(group_cols,fields) } # unique groups # not necessary but good practice to force as df and assign colnames # (in case group_cols has length 1; which can happen in groupBaseline) uniqueGroups <- data.frame(unique(db[, group_cols]), stringsAsFactors=FALSE) colnames(uniqueGroups) <- group_cols rownames(uniqueGroups) <- NULL # indices # crucial to have simplify=FALSE # (otherwise won't return a list if uniqueClones has length 1) uniqueGroupsIdx <- sapply(1:nrow(uniqueGroups), function(i){ curGroup <- data.frame(uniqueGroups[i, ], stringsAsFactors=FALSE) colnames(curGroup) <- group_cols # match for each field curIdx <- sapply(group_cols, function(coln){ db[[coln]]==curGroup[, coln] }, simplify=FALSE) curIdx <- do.call(rbind, curIdx) # intersect to get match across fields curIdx <- which(colSums(curIdx)==length(group_cols)) # sanity check # no NA stopifnot( all(!is.na(curIdx)) ) # index within range of db stopifnot( max(curIdx) <= nrow(db) ) return(curIdx) }, simplify=FALSE) # Create new column for distance to nearest neighbor db$TMP_DIST_NEAREST <- rep(NA, nrow(db)) db$ROW_ID <- 1:nrow(db) # Create cluster of nproc size and export namespaces # If user wants to paralellize this function and specifies nproc > 1, then # initialize and register slave R processes/clusters & # export all nesseary environment variables, functions and packages. if( nproc==1 ) { # If needed to run on a single core/cpu then, register DoSEQ # (needed for 'foreach' in non-parallel mode) registerDoSEQ() } else if( nproc > 1 ) { cluster <- parallel::makeCluster(nproc, type="PSOCK") registerDoParallel(cluster) } else { stop('Nproc must be positive.') } # Export groups to the clusters if (nproc > 1) { export_functions <- list("db", "uniqueGroupsIdx", "cross", "mst", "subsample", "sequenceColumn", "model", "normalize", "symmetry", "nearestDist", "HH_S1F_Distance", "MK_RS1NF_Distance", "HH_S5F_Distance", "MK_RS5NF_Distance", "HS1F_Compat", "M1N_Compat", "calcTargetingDistance", "findUniqSeq", "pairwise5MerDist", "nonsquare5MerDist", "singleCell", "locusColumn") parallel::clusterExport(cluster, export_functions, envir=environment()) } n_groups <- length(uniqueGroupsIdx) if (progress) { pb <- progressBar(n_groups) } list_db <- foreach(i=1:n_groups, .errorhandling='stop') %dopar% { # wrt db idx <- uniqueGroupsIdx[[i]] if (singleCell) { # only use IGH # wrt idx idxBool <- db[[locusColumn]][idx] == "IGH" } else { idxBool <- rep(TRUE, length(idx)) } db_group <- db[idx, ] crossGroups <- NULL if (!is.null(cross)) { crossGroups <- db_group %>% dplyr::group_indices(!!!rlang::syms(cross)) } arrSeqs <- db[[sequenceColumn]][idx] db_group$TMP_DIST_NEAREST[idxBool] <- nearestDist(arrSeqs[idxBool], model=model, normalize=normalize, symmetry=symmetry, crossGroups=crossGroups[idxBool], mst=mst, subsample=subsample) # Update progress if (progress) { pb$tick() } return(db_group) } # Convert list from foreach into a db data.frame db <- do.call(rbind, list_db) db <- db[order(db$ROW_ID), ] # Stop the cluster if (nproc > 1) { parallel::stopCluster(cluster) } if (!is.null(cross)) { db$CROSS_DIST_NEAREST <- db$TMP_DIST_NEAREST } else { db$DIST_NEAREST <- db$TMP_DIST_NEAREST } # prepare db for return if ((!VJthenLen) && keepVJLgroup) { db$VJL_GROUP <- db[["VJ_GROUP"]] } db <- db[, !(names(db) %in% c(junc_len, "VJ_GROUP", "ROW_ID", "V1", "J1","TMP_DIST_NEAREST"))] return(db) } #### Distance Threshold Detection #### #' Find distance threshold #' #' \code{findThreshold} automtically determines an optimal threshold for clonal assignment of #' Ig sequences using a vector of nearest neighbor distances. It provides two alternative methods #' using either a Gamma/Guassian Mixture Model fit (\code{method="gmm"}) or kernel density #' fit (\code{method="density"}). #' #' @param distances numeric vector containing nearest neighbor distances. #' @param method string defining the method to use for determining the optimal threshold. #' One of \code{"gmm"} or \code{"density"}. See Details for methodological #' descriptions. #' @param edge upper range as a fraction of the data density to rule initialization of #' Gaussian fit parameters. Default value is 90% of the entries (0.9). #' Applies only when \code{method="density"}. . #' @param cross supplementary nearest neighbor distance vector output from \link{distToNearest} #' for initialization of the Gaussian fit parameters. #' Applies only when \code{method="gmm"}. #' @param subsample maximum number of distances to subsample to before threshold detection. #' @param model allows the user to choose among four possible combinations of fitting curves: #' \code{"norm-norm"}, \code{"norm-gamma"}, \code{"gamma-norm"}, #' and \code{"gamma-gamma"}. Applies only when \code{method="gmm"}. #' @param cutoff method to use for threshold selection: the optimal threshold \code{"opt"}, #' the intersection point of the two fitted curves \code{"intersect"}, or #' a value defined by user for one of the sensitivity or specificity \code{"user"}. #' Applies only when \code{method="gmm"}. #' @param sen sensitivity required. Applies only when \code{method="gmm"} and \code{cutoff="user"}. #' @param spc specificity required. Applies only when \code{method="gmm"} and \code{cutoff="user"}. #' #' @param progress if \code{TRUE} print a progress bar. #' @return #' \itemize{ #' \item \code{"gmm"} method: Returns a \link{GmmThreshold} object including the #' \code{threshold} and the function fit parameters, i.e. #' mixing weight, mean, and standard deviation of a Normal distribution, or #' mixing weight, shape and scale of a Gamma distribution. #' \item \code{"density"} method: Returns a \link{DensityThreshold} object including the optimum #' \code{threshold} and the density fit parameters. #' } #' #' @details #' \itemize{ #' \item \code{"gmm"}: Performs a maximum-likelihood fitting procedure, for learning #' the parameters of two mixture univariate, either Gamma or Gaussian, distributions #' which fit the bimodal distribution entries. Retrieving the fit parameters, #' it then calculates the optimum threshold \code{method="optimal"}, where the #' average of the sensitivity plus specificity reaches its maximum. In addition, #' the \code{findThreshold} function is also able #' to calculate the intersection point (\code{method="intersect"}) of the two fitted curves #' and allows the user to invoke its value as the cut-off point, instead of optimal point. #' \item \code{"density"}: Fits a binned approximation to the ordinary kernel density estimate #' to the nearest neighbor distances after determining the optimal #' bandwidth for the density estimate via least-squares cross-validation of #' the 4th derivative of the kernel density estimator. The optimal threshold #' is set as the minimum value in the valley in the density estimate #' between the two modes of the distribution. #' } #' #' @seealso See \link{distToNearest} for generating the nearest neighbor distance vectors. #' See \link{plotGmmThreshold} and \link{plotDensityThreshold} for plotting output. #' #' @note #' Visually inspecting the resulting distribution fits is strongly recommended when using #' either fitting method. Empirical observations imply that the bimodality #' of the distance-to-nearest distribution is detectable for a minimum of 1,000 distances. #' Larger numbers of distances will improve the fitting procedure, although this can come #' at the expense of higher computational demands. #' #' @examples #' \donttest{ #' # Subset example data to one sample as a demo #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, SAMPLE == "-1h") #' #' # Use nucleotide Hamming distance and normalize by junction length #' db <- distToNearest(db, model="ham", normalize="len", nproc=1) #' #' # Find threshold using the "gmm" method with optimal threshold #' output <- findThreshold(db$DIST_NEAREST, method="gmm", model="gamma-gamma", cutoff="opt") #' plot(output, binwidth=0.02, title=paste0(output@model, " loglk=", output@loglk)) #' print(output) #' #' # Find threshold using the "gmm" method with user defined specificity #' output <- findThreshold(db$DIST_NEAREST, method="gmm", model="gamma-gamma", #' cutoff="user", spc=0.99) #' plot(output, binwidth=0.02, title=paste0(output@model, " loglk=", output@loglk)) #' print(output) #' #' # Find threshold using the "density" method and plot the results #' output <- findThreshold(db$DIST_NEAREST, method="density") #' plot(output) #' print(output) #' } #' @export findThreshold <- function (distances, method=c("density", "gmm"), edge=0.9, cross=NULL, subsample=NULL, model=c("gamma-gamma", "gamma-norm", "norm-gamma", "norm-norm"), cutoff=c("optimal", "intersect", "user"), sen=NULL, spc=NULL, progress=FALSE){ # Check arguments method <- match.arg(method) model <- match.arg(model) cutoff <- match.arg(cutoff) # Subsample input distances if(!is.null(subsample)) { subsample <- min(length(distances), subsample) distances <- sample(distances, subsample, replace=FALSE) } if (method == "gmm") { if (cutoff == "user"){ if (is.null(sen) & is.null(spc)) { cat("Error: one of 'sen' or 'spc' values should be specified.") output <- NA } else if (!is.null(sen) & !is.null(spc)) { cat("Error: only one of 'sen' or 'spc' values can be specified.") output <- NA } else { output <- gmmFit(ent=distances, edge=edge, cross=cross, model=model, cutoff=cutoff, sen=sen, spc=spc, progress=progress) } } else { output <- gmmFit(ent=distances, edge=edge, cross=cross, model=model, cutoff=cutoff, sen=sen, spc=spc, progress=progress) } } else if (method == "density") { output <- smoothValley(distances) } else { cat("Error: assigned method has not been found.\n") output <- NA } return(output) } # Find distance threshold with \code{"density"} Method # # Infer value of the minimum between the two modes in a bimodal distribution. # # @param distances numeric vector of distances. # # @return Returns distance threshold that separates two modes of the input distribution. # # @details # The distance to nearest neighbor can be used to estimate a threshold for assigning Ig # sequences to clonal groups. A histogram of the resulting vector is often bimodal, # with the ideal threshold being a value that separates the two modes. This function takes # as input a vector of such distances and infers the ideal threshold. # # @seealso # \itemize{ # \item See \link{distToNearest} for details on generating the input distance vector. # \item See \link{gmmFit} for a different threshold inference methodology. # \item See \link{findThreshold} to switch between available methods. #} # # # @examples # # Subset example data to one sample as a demo # data(ExampleDb, package="alakazam") # db <- subset(ExampleDb, SAMPLE == "-1h") # # # Use genotyped V assignments, HS1F model, and normalize by junction length # dist_hs1f <- distToNearest(db, vCallColumn="V_CALL_GENOTYPED", # model="hs1f", first=FALSE, normalize="len") # # # using findThreshold switch # threshold <- findThreshold(dist_hs1f$DIST_NEAREST, method="density") # # or # threshold <- smoothValley(dist_hs1f$DIST_NEAREST) # # # Plot histogram of non-NA distances # p1 <- ggplot(data=subset(dist_hs1f, !is.na(DIST_NEAREST))) + theme_bw() + # ggtitle("Distance to nearest: hs1f") + xlab("distance") + # geom_histogram(aes(x=DIST_NEAREST), binwidth=0.025, # fill="steelblue", color="white") + # geom_vline(xintercept=threshold, linetype="dashed") # plot(p1) # # @export smoothValley <- function(distances) { # Remove NA, NaN, and infinite distances distances <- distances[!is.na(distances) & !is.nan(distances) & !is.infinite(distances)] # Guassian distribution bandwidth scale parameter #guassian_scaling <- (1/(4 * pi))^(1/10) # Ideal bandwidth bandwidth <- kedd::h.ucv(unique(distances), 4)$h #bandwidth <- kedd::h.ucv(distances, 4)$h #bandwidth <- ks::hucv(unique(distances), deriv.order=4) # Density estimate dens <- KernSmooth::bkde(distances, bandwidth=bandwidth, canonical=TRUE) #dens <- KernSmooth::bkde(distances, bandwidth=bandwidth) xdens <- dens$x ydens <- dens$y #dens <- ks::kde(distances, h=bandwidth*guassian_scaling, binned=TRUE) #xdens <- dens$eval.points #ydens <- dens$estimate # Find threshold tryCatch(threshold <- xdens[which(diff(sign(diff(ydens))) == 2)[1] + 1], error = function(e) { warning('No minimum was found between two modes.') return(NULL) }) results <- new("DensityThreshold", x=distances, bandwidth=bandwidth, xdens=xdens, ydens=ydens, threshold=threshold) return(results) } # Find distance threshold with Gaussian Mixture Method # # Fits a bimodal distribution with two Gaussian functions and calculates maximum of the average of the # Sensitivity plus Specificity corresponding to the Gaussian distributions. # # @param ent numeric vector of distances returned from \link{distToNearest} function. # @param edge upper range (a fraction of the data density) to rule initialization of # Gaussian fit parameters. Default value is equal to \eqn{90}\% of the entries. # @param cross a supplementary info (numeric vector) invoked from \link{distToNearest} # function, to support initialization of the Gaussian fit parameters. # @param progress if \code{TRUE} print progress. # # @return returns an object including optimum "\code{threshold}" cut and the Gaussian fit parameters, # such as mixing proportion ("\code{omega1}" and "\code{omega2}"), mean ("\code{mu1}" and "\code{mu2}"), # and standard deviation ("\code{sigma1}" and "\code{sigma2}"). Returns "\code{NULL}" if no fit has found. # # @seealso # \itemize{ # \item See \link{distToNearest} for details on generating the input distance vector. # \item See \link{smoothValley} for a different threshold inference methodology. # \item See \link{findThreshold} to switch between available methods. #} # # # @details This function follows a Gaussian Mixture Model (GMM) procedure, # including the Expectation Maximization (EM) algorithm, for learning the parameters # of two univariate Gaussians which fit the bimodal distribution entries. # Retrieving the fit parameters, it then calculates, analytically, the optimum threshold, # where the average of the Sensitivity plus Specificity reaches its maximum. This threshold # can be then invoked for assigning Ig sequences to clonal groups. # # @examples # # Subset example data to one sample as a demo # data(ExampleDb, package="alakazam") # db <- subset(ExampleDb, SAMPLE == "-1h") # # # Use nucleotide Hamming distance and normalize by junction length # db <- distToNearest(db, model="ham", first=FALSE, normalize="len", nproc=1) # # # To find the Threshold cut use either findThreshold-switch # output <- findThreshold(db$DIST_NEAREST, method="gmm", edge=0.9) # # or # output <- gmmFit(db$DIST_NEAREST, edge=0.9) gmmFit <- function(ent, edge=0.9, cross=NULL, model, cutoff, sen, spc, progress=FALSE) { #************* Filter Unknown Data *************# ent <- ent[!is.na(ent) & !is.nan(ent) & !is.infinite(ent)] if (is.null(cross)) { m <- FALSE } else { m <- mean(cross, na.rm = TRUE) } #************* Defult edge *************# cut <- edge*length(ent) #************* Define Scan Step For Initializing *************# if (ent[which.max(ent)] <= 5) { scan_step <- 0.1 } else { scan_step <- 1 } #************* Print some info *************# if (progress) { valley_loc <- 0 while (1) { valley_loc <- valley_loc + scan_step if ( length(ent[ent<=valley_loc]) > cut ) break } n_iter <- ceiling(valley_loc/scan_step)-1 cat(" STEP> ", "Parameter initialization\n", sep="") cat(" VALUES> ", length(ent), "\n", sep="") cat("ITERATIONS> ", n_iter, "\n", sep="") pb <- progressBar(n_iter) } #************* set rand seed *************# set.seed(NULL) #************* define Number of Gaussians *************# num_G <- 2 vec.omega1 <- 0; vec.omega2 <- 0 vec.mu1 <- 0; vec.mu2 <- 0 vec.sigma1 <- 0; vec.sigma2 <- 0 vec.lkhood <- 0 valley.itr <- 0 valley_loc <- 0 nEve <- length(ent) while (1) { #************* guess the valley loc *************# valley_loc <- valley_loc + scan_step if ( length(ent[ent<=valley_loc]) > cut ) break #************* Choosing Random Omega *************# omega <- runif(1) omega <- c(omega, 1.-omega) #************* Choosing Random Mean *************# mu_int <- mean(ent[ent<=valley_loc]) mu_int <- c(mu_int, mean(ent[ent>valley_loc])) #************* Choosing Random Sigma *************# sigma_int <- sd(ent[entvalley_loc])) #************* EM Algorithm *************# temp_lk <- 0 itr <- 0 while (1){ mu <- 0 sigma <- 0 for (j in 1:num_G){ mu[j] <- mu_int[j] sigma[j] <- sigma_int[j] } #************* E-step Expectation *************# resp <- array(0, dim=c(nEve,num_G)) for(i in 1:nEve){ for (j in 1:num_G) resp[i,j] <- omega[j]*dnorm(ent[i], mu[j], sigma[j]) resp[i,] <- resp[i,]/sum(resp[i,]) } #************* M-step Maximization *************# for (j in 1:num_G){ m_c <- sum(resp[,j]) omega[j] <- m_c / nEve mu[j] <- sum(resp[,j]*ent) mu[j] <- mu[j] / m_c sigma[j] <- sum(resp[,j]*(ent-mu[j])*(ent-mu[j])) sigma[j] <- sigma[j] / m_c sigma[j] <- sqrt(sigma[j]) } #************* Log-likelihood calculation *************# log_lk <- 0. for (i in 1:nEve){ s <- 0 for (j in 1:num_G) s <- s + omega[j]*dnorm(ent[i], mu[j], sigma[j]) log_lk <- log_lk + log(s, base = exp(1)) } log_lk_err <- abs(log_lk - temp_lk) itr = itr + 1 #print(paste0("scaned: ", valley_loc, " itr # ", itr, " -> ", log_lk_err)) if (is.na(log_lk_err) | is.nan(log_lk_err) | is.infinite(log_lk_err)) break if (log_lk_err < 1.e-7) break temp_lk <- log_lk; } #************************************************************# #************* JUST FOR VISUALIZATION PURPOSES *************# # print(paste0("scaned: ", valley_loc, " --------> Log-Likelihood: ", log_lk)) # if (ent[which.min(ent)] >= 0 & ent[which.max(ent)] <= 5) { # h_min <- 0.0 # h_max <- 1 # dh = 0.02 # } else { # h_min <- 0.0 # h_max <- ent[which.max(ent)] # dh = 1 # } # h <- hist(ent, plot = FALSE, breaks=seq(h_min, h_max, by=dh)) # plot(h, freq=FALSE, col="steelblue", border="white", xlim=c(h_min, h_max)) # curve(omega[1]*dnorm(x, mu[1], sigma[1]), add=TRUE, col="darkblue", lwd=2, xlim = c(h_min, h_max)) # curve(omega[2]*dnorm(x, mu[2], sigma[2]), add=TRUE, col="darkred", lwd=2, xlim = c(h_min, h_max)) #************************************************************# #************************************************************# if (!is.na(log_lk_err) & !is.nan(log_lk_err) & !is.infinite(log_lk_err)){ if (!as.logical(m)){ valley.itr <- valley.itr + 1 vec.omega1[valley.itr] <- omega[1] vec.omega2[valley.itr] <- omega[2] vec.mu1[valley.itr] <- mu[1] vec.mu2[valley.itr] <- mu[2] vec.sigma1[valley.itr] <- sigma[1] vec.sigma2[valley.itr] <- sigma[2] vec.lkhood[valley.itr] <- log_lk } else if ((mu[1]< m & m < mu[2]) | (mu[2]< m & m < mu[1]) | (mu[1]< m & mu[2]< m) ){ valley.itr <- valley.itr + 1 vec.omega1[valley.itr] <- omega[1] vec.omega2[valley.itr] <- omega[2] vec.mu1[valley.itr] <- mu[1] vec.mu2[valley.itr] <- mu[2] vec.sigma1[valley.itr] <- sigma[1] vec.sigma2[valley.itr] <- sigma[2] vec.lkhood[valley.itr] <- log_lk } } # Update progress if (progress) { pb$tick() } } if (valley.itr != 0) { # MaxLoc <- which.max(vec.lkhood) MaxLoc <- which.max(abs(vec.lkhood)) omega[1] <- vec.omega1[MaxLoc]; omega[2] <- vec.omega2[MaxLoc] mu[1] <- vec.mu1[MaxLoc]; mu[2] <- vec.mu2[MaxLoc] sigma[1] <- vec.sigma1[MaxLoc]; sigma[2] <- vec.sigma2[MaxLoc] # Invoke Gaussians parameters omega.gmm <- c(omega[1], omega[2]) mu.gmm <- c(mu[1], mu[2]) sigma.gmm <- c(sigma[1], sigma[2]) fit_results <- rocSpace(ent=ent, omega.gmm=omega.gmm , mu.gmm=mu.gmm, sigma.gmm=sigma.gmm, model=model, cutoff=cutoff, sen=sen, spc=spc, progress=progress) results <- new("GmmThreshold", x=ent, model=model, cutoff=cutoff, a1=fit_results@a1, b1=fit_results@b1, c1=fit_results@c1, a2=fit_results@a2, b2=fit_results@b2, c2=fit_results@c2, loglk=fit_results@loglk, threshold=fit_results@threshold, sensitivity=fit_results@sensitivity, specificity=fit_results@specificity, pvalue=fit_results@pvalue) } else { print("Error: No fit found") results <- NULL } return(results) } rocSpace <- function(ent, omega.gmm, mu.gmm, sigma.gmm, model, cutoff, sen, spc, progress=FALSE) { func <- model bits <- strsplit(func,'-')[[1]] # Define mixture Function properties if (bits[1] == "norm"){ func1.0 <- round(omega.gmm[1], digits = 3) # -> prob: omega func1.1 <- mu.gmm[1] # -> mean: mu func1.2 <- sigma.gmm[1] # -> sd: sigma } else if (bits[1] == "gamma"){ func1.0 <- round(omega.gmm[1], digits = 3) # -> prob: omega func1.1 <- (mu.gmm[1]/sigma.gmm[1])*(mu.gmm[1]/sigma.gmm[1]) # -> shape: k func1.2 <- sigma.gmm[1]*sigma.gmm[1]/mu.gmm[1] # -> scale: theta } if (bits[2] == "norm"){ func2.1 = mu.gmm[2] # -> mean: mu func2.2 = sigma.gmm[2] # -> sd: sigma } else if (bits[2] == "gamma"){ func2.1 <- (mu.gmm[2]/sigma.gmm[2])*(mu.gmm[2]/sigma.gmm[2]) # -> shape: k func2.2 <- sigma.gmm[2]*sigma.gmm[2]/mu.gmm[2] # -> scale: theta } # Save mixture Function properties gmmfunc1.1 <- func1.1 gmmfunc1.2 <- func1.2 gmmfunc2.1 <- func2.1 gmmfunc2.2 <- func2.2 set.seed(NULL) # options(warn=-1) LOG_LIK<-0 if (progress) { cat(" STEP> ", "Fitting ", func, "\n", sep="") pb <- progressBar(15) } for (i in 1:15) { #itr<-1 key<-FALSE while (!key){ # print(paste0(i,":",itr)) # Fit mixture Functions MixModel <- try(suppressWarnings(fitdistr(na.exclude(ent), mixFunction, first_curve = bits[1], second_curve = bits[2], start=list(omega = func1.0, func1.1 = func1.1, func1.2 = func1.2, func2.1 = func2.1, func2.2 = func2.2), lower = c(0.001, 0.001, 0.001, 0.001, 0.001), upper = c(0.999, +Inf, +Inf, +Inf, +Inf))), silent = TRUE) if (inherits(MixModel, "try-error")) { func1.0 <- runif(1) func1.1 <- abs(gmmfunc1.1 + sample(c(-1,1), 1)*runif(1)) func1.2 <- abs(gmmfunc1.2 + sample(c(-1,1), 1)*runif(1)) func2.1 <- abs(gmmfunc2.1 + sample(c(-1,1), 1)*runif(1)) func2.2 <- abs(gmmfunc2.2 + sample(c(-1,1), 1)*runif(1)) #itr<-itr+1 next } else if ( (bits[1] == "norm" & bits[2] == "gamma" & MixModel$estimate[[2]] > MixModel$estimate[[4]] * MixModel$estimate[[5]]) | (bits[1] == "gamma" & bits[2] == "norm" & MixModel$estimate[[2]] * MixModel$estimate[[3]] > MixModel$estimate[[4]]) | MixModel$estimate[[1]] == 0.001 | MixModel$estimate[[1]] == 0.999) { func1.0 <- runif(1) func1.1 <- abs(gmmfunc1.1 + sample(c(-1,1), 1)*runif(1)) func1.2 <- abs(gmmfunc1.2 + sample(c(-1,1), 1)*runif(1)) func2.1 <- abs(gmmfunc2.1 + sample(c(-1,1), 1)*runif(1)) func2.2 <- abs(gmmfunc2.2 + sample(c(-1,1), 1)*runif(1)) # print("here") #itr<-itr+1 next } else { key<-TRUE } } # print(paste0(func, " fit done. Loglik= ", round(MixModel$loglik, digits = 2))) # Invoke fit parameters # log_lik <- round(MixModel$loglik, digits = 2) log_lik <- round(abs(MixModel$loglik), digits = 2) if (log_lik > LOG_LIK){ LOG_LIK <- log_lik FUNC1.0 <- MixModel$estimate[[1]] FUNC1.1 <- MixModel$estimate[[2]] FUNC1.2 <- MixModel$estimate[[3]] FUNC2.0 <- 1. - MixModel$estimate[[1]] FUNC2.1 <- MixModel$estimate[[4]] FUNC2.2 <- MixModel$estimate[[5]] } # New fit parameters for next loop func1.0 <- runif(1) func1.1 <- abs(gmmfunc1.1 + sample(c(-1,1), 1)*runif(1)) func1.2 <- abs(gmmfunc1.2 + sample(c(-1,1), 1)*runif(1)) func2.1 <- abs(gmmfunc2.1 + sample(c(-1,1), 1)*runif(1)) func2.2 <- abs(gmmfunc2.2 + sample(c(-1,1), 1)*runif(1)) # if (i==1 & itr == 1) break if (progress) { pb$tick() } } # options(warn=0) # Invoke best fit parameters log_lik <- LOG_LIK func1.0 <- FUNC1.0 func1.1 <- FUNC1.1 func1.2 <- FUNC1.2 func2.0 <- FUNC2.0 func2.1 <- FUNC2.1 func2.2 <- FUNC2.2 # order fit parameters if (bits[1]=="norm" & bits[2]=="norm" & func1.1>func2.1) { FUNC0 <- func1.0 FUNC1 <- func1.1 FUNC2 <- func1.2 func1.0 <- func2.0 func1.1 <- func2.1 func1.2 <- func2.2 func2.0 <- FUNC0 func2.1 <- FUNC1 func2.2 <- FUNC2 } else if (bits[1]=="gamma" & bits[2]=="gamma" & func1.1*func1.2>func2.1*func2.2) { FUNC0 <- func1.0 FUNC1 <- func1.1 FUNC2 <- func1.2 func1.0 <- func2.0 func1.1 <- func2.1 func1.2 <- func2.2 func2.0 <- FUNC0 func2.1 <- FUNC1 func2.2 <- FUNC2 } # domain [t1,t2] under distribution t1<-min(ent) t2<-max(ent) # domain [minInt,maxInt] to search for opt and root if (bits[1] == "norm") { minInt<-func1.1 } else if (bits[1] == "gamma") { minInt<-func1.1*func1.2 } if (bits[2] == "norm") { maxInt<-func2.1 } else if (bits[2] == "gamma") { maxInt<-func2.1*func2.2 } if (cutoff == "optimal"){ # Calculate optimum opt <- optimize(avgSenSpc, interval = c(minInt, maxInt), tol=1e-8, maximum = TRUE, t1=t1, t2=t2, first_curve = bits[1], second_curve = bits[2], func1.0=func1.0, func1.1=func1.1, func1.2=func1.2, func2.0=func2.0, func2.1=func2.1, func2.2=func2.2) threshold <- opt$maximum } else if (cutoff == "intersect") { # Calculate intersection intxn <- uniroot(intersectPoint, interval = c(minInt, maxInt), tol=1e-8, extendInt="yes", first_curve = bits[1], second_curve = bits[2], func1.0=func1.0, func1.1=func1.1, func1.2=func1.2, func2.0=func2.0, func2.1=func2.1, func2.2=func2.2) threshold <- intxn$root } else if (cutoff == "user") { user <- uniroot(userDefineSenSpc, interval = c(t1, t2), tol=1e-8, extendInt="no", t1=t1, t2=t2, first_curve = bits[1], second_curve = bits[2], sen = sen, spc = spc, func1.0=func1.0, func1.1=func1.1, func1.2=func1.2, func2.0=func2.0, func2.1=func2.1, func2.2=func2.2) threshold <- user$root } # Calculate Sensitivity and Specificity if (bits[1]=="norm") { TP = normArea(t1=t1, t2=threshold, omega=func1.0, mu=func1.1, sigma=func1.2) } else if (bits[1]=="gamma") { TP = gammaArea(t1=t1, t2=threshold, omega=func1.0, k=func1.1, theta=func1.2) } if (bits[1]=="norm") { FN = normArea(t1=threshold, t2=t2, omega=func1.0, mu=func1.1, sigma=func1.2) } else if (bits[1]=="gamma") { FN = gammaArea(t1=threshold, t2=t2, omega=func1.0, k=func1.1, theta=func1.2) } if (bits[2]=="norm") { TN = normArea(t1=threshold, t2=t2, omega=func2.0, mu=func2.1, sigma=func2.2) } else if (bits[2]=="gamma") { TN = gammaArea(t1=threshold, t2=t2, omega=func2.0, k=func2.1, theta=func2.2) } if (bits[2]=="norm") { FP = normArea(t1=t1, t2=threshold, omega=func2.0, mu=func2.1, sigma=func2.2) } else if (bits[2]=="gamma") { FP = gammaArea(t1=t1, t2=threshold, omega=func2.0, k=func2.1, theta=func2.2) } sensitivity <- TP/(TP+FN) specificity <- TN/(TN+FP) # Hartigans dip statistic (HDS) test invisible(capture.output(pvalue <- dip.test(ent)$p.value[[1]], type="message")) fit_results <- new("GmmThreshold", x=numeric(), model=character(), cutoff=character(), a1=func1.0, b1=func1.1, c1=func1.2, a2=func2.0, b2=func2.1, c2=func2.2, loglk=log_lik, threshold=threshold, sensitivity=sensitivity, specificity=specificity, pvalue=pvalue) return(fit_results) } # Calculates the area (integral) bounded # in domain[t1,t2] under Gamma distribution gammaArea <- function (t1, t2, omega, k, theta){ trm1 <- pgamma(t1/theta, shape=k, lower.tail=FALSE) * gamma(k) trm2 <- pgamma(t2/theta, shape=k, lower.tail=FALSE) * gamma(k) area <- omega*(trm1 - trm2)/gamma(k) return(area) } # Calculates the area (integral) bounded # in domain[t1,t2] under Normal distribution normArea <- function (t1, t2, omega, mu, sigma){ erf1 <- (t1-mu)/(sqrt(2)*sigma) erf1 <- 2*pnorm(erf1*sqrt(2)) - 1 erf2 <- (t2-mu)/(sqrt(2)*sigma) erf2 <- 2*pnorm(erf2*sqrt(2)) - 1 area <- sigma * omega * (-erf1 + erf2) / (2*sigma) return(area) } # find the optimum threshold using # optimize function fit avgSenSpc <- function(t, t1=0, t2=0, first_curve=NULL, second_curve=NULL, func1.0 = 0, func1.1 = 0, func1.2 = 0, func2.0 = 0, func2.1 = 0, func2.2 = 0) { if (first_curve == "norm") { TP <- normArea(t1=t1, t2=t, omega=func1.0, mu=func1.1, sigma=func1.2) FN <- normArea(t1=t, t2=t2, omega=func1.0, mu=func1.1, sigma=func1.2) } else if (first_curve == "gamma") { TP <- gammaArea(t1=t1, t2=t, omega=func1.0, k=func1.1, theta=func1.2) FN <- gammaArea(t1=t, t2=t2, omega=func1.0, k=func1.1, theta=func1.2) } if (second_curve == "norm") { FP <- normArea(t1=t1, t2=t, omega=func2.0, mu=func2.1, sigma=func2.2) TN <- normArea(t1=t, t2=t2, omega=func2.0, mu=func2.1, sigma=func2.2) } else if (second_curve == "gamma") { FP <- gammaArea(t1=t1, t2=t, omega=func2.0, k=func2.1, theta=func2.2) TN <- gammaArea(t1=t, t2=t2, omega=func2.0, k=func2.1, theta=func2.2) } SEN <- TP/(TP + FN) SPC <- TN/(TN + FP) return((SEN + SPC)/2) } # Intersection Function intersectPoint <- function(t, first_curve=NULL, second_curve=NULL, func1.0 = 0, func1.1 = 0, func1.2 = 0, func2.0 = 0, func2.1 = 0, func2.2 = 0) { if (first_curve == "norm") { fit1 <- func1.0*dnorm(t, mean = func1.1, sd = func1.2) } else if (first_curve == "gamma") { fit1 <- func1.0*dgamma(t, shape = func1.1, scale = func1.2) } if (second_curve == "norm") { fit2 <- func2.0*dnorm(t, mean = func2.1, sd = func2.2) } else if (second_curve == "gamma") { fit2 <- func2.0*dgamma(t, shape = func2.1, scale = func2.2) } return(fit1 - fit2) } # useDefineSenSpc userDefineSenSpc <- function(t, t1=0, t2=0, first_curve=NULL, second_curve=NULL, sen=NULL, spc=NULL, func1.0=0, func1.1=0, func1.2=0, func2.0=0, func2.1=0, func2.2=0) { if (!is.null(sen)) { if (first_curve == "norm") { TP <- normArea(t1=t1, t2=t, omega=func1.0, mu=func1.1, sigma=func1.2) FN <- normArea(t1=t, t2=t2, omega=func1.0, mu=func1.1, sigma=func1.2) } else if (first_curve == "gamma") { TP <- gammaArea(t1=t1, t2=t, omega=func1.0, k=func1.1, theta=func1.2) FN <- gammaArea(t1=t, t2=t2, omega=func1.0, k=func1.1, theta=func1.2) } threshold <- (TP/(TP+FN)) - sen } else if (!is.null(spc)) { if (second_curve == "norm") { FP <- normArea(t1=t1, t2=t, omega=func2.0, mu=func2.1, sigma=func2.2) TN <- normArea(t1=t, t2=t2, omega=func2.0, mu=func2.1, sigma=func2.2) } else if (second_curve == "gamma") { FP <- gammaArea(t1=t1, t2=t, omega=func2.0, k=func2.1, theta=func2.2) TN <- gammaArea(t1=t, t2=t2, omega=func2.0, k=func2.1, theta=func2.2) } threshold <- (TN/(TN+FP)) - spc } return(threshold) } # Mixture Functions mixFunction <- function(t, first_curve=NULL, second_curve=NULL, omega = 0, func1.1 = 0, func1.2 = 0, func2.1 = 0, func2.2 = 0) { if (first_curve == "norm"){ r <- omega*dnorm(t, mean=func1.1, sd=func1.2) } else if (first_curve == "gamma") { r <- omega*dgamma(t, shape=func1.1, scale=func1.2) } if (second_curve == "norm"){ r <- r + (1-omega)*dnorm(t, mean=func2.1, sd=func2.2) } else if (second_curve == "gamma") { r <- r + (1-omega)*dgamma(t, shape=func2.1, scale=func2.2) } } #' Plot findThreshold results for the gmm method #' #' \code{plotGmmThreshold} plots the results from \code{"gmm"} method of #' \link{findThreshold}, including the Guassian distributions, input nearest neighbor #' distance histogram, and threshold selected. #' #' @param data \link{GmmThreshold} object output by the \code{"gmm"} method #' of \link{findThreshold}. #' @param cross numeric vector of distances from \link{distToNearest} to draw as a #' histogram below the \code{data} histogram for comparison purposes. #' @param xmin minimum limit for plotting the x-axis. If \code{NULL} the limit will #' be set automatically. #' @param xmax maximum limit for plotting the x-axis. If \code{NULL} the limit will #' be set automatically. #' @param breaks number of breaks to show on the x-axis. If \code{NULL} the breaks will #' be set automatically. #' @param binwidth binwidth for the histogram. If \code{NULL} the binwidth #' will be set automatically. #' @param title string defining the plot title. #' @param size numeric value for lines in the plot. #' @param silent if \code{TRUE} do not draw the plot and just return the ggplot2 #' object; if \code{FALSE} draw the plot. #' @param ... additional arguments to pass to ggplot2::theme. #' #' @return A ggplot object defining the plot. #' #' @seealso See \link{GmmThreshold} for the the input object definition and #' \link{findThreshold} for generating the input object. See #' \link{distToNearest} calculating nearest neighbor distances. #' #' @examples #' \donttest{ #' # Subset example data to one sample as a demo #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, SAMPLE == "-1h") #' #' # Use nucleotide Hamming distance and normalize by junction length #' db <- distToNearest(db, model="ham", normalize="len", nproc=1) #' #' # To find the threshold cut, call findThreshold function for "gmm" method. #' output <- findThreshold(db$DIST_NEAREST, method="gmm", model="norm-norm", cutoff="opt") #' print(output) #' #' # Plot results #' plotGmmThreshold(output, binwidth=0.02) #' } #' @export plotGmmThreshold <- function(data, cross=NULL, xmin=NULL, xmax=NULL, breaks=NULL, binwidth=NULL, title=NULL, size=1, silent=FALSE, ...) { # Define histogram data.frame and threshold xdf <- data.frame(x=data@x) # Generate curves gx <- seq(min(xdf$x), max(xdf$x), by=0.002) bits <- strsplit(data@model,'-')[[1]] if (bits[1] == "norm") { fit1 <- data.frame(x=gx, y=data@a1*dnorm(gx, mean=data@b1, sd=data@c1)) } else if (bits[1] == "gamma") { fit1 <- data.frame(x=gx, y=data@a1*dgamma(gx, shape=data@b1, scale=data@c1)) } if (bits[2] == "norm") { fit2 <- data.frame(x=gx, y=data@a2*dnorm(gx, mean = data@b2, sd=data@c2)) } else if (bits[2] == "gamma") { fit2 <- data.frame(x=gx, y=data@a2*dgamma(gx, shape = data@b2, scale=data@c2)) } # ggplot workaround if (is.null(xmin)) { xmin <- NA } if (is.null(xmax)) { xmax <- NA } # Plot distToNearest distribution plus Gaussian fits p <- ggplot(xdf, aes_string(x="x")) + baseTheme() + xlab("Distance") + ylab("Density") + geom_histogram(aes_string(y="..density.."), binwidth=binwidth, fill="gray40", color="white") + geom_line(data=fit1, aes_string(x="x", y="y"), color="darkslateblue", size=size) + geom_line(data=fit2, aes_string(x="x", y="y"), color="darkslateblue", size=size) + geom_vline(xintercept=data@threshold, color="firebrick", linetype="longdash", size=size) # Add cross histogram if (!is.null(cross)) { cdf <- data.frame(x=cross[is.finite(cross)]) p <- p + geom_histogram(data=cdf, aes_q(x=~x, y=~-(..density..)), binwidth=binwidth, fill="gray40", color="white", position="identity") + scale_y_continuous(labels=abs) } # Add x limits if (is.null(breaks) & (!is.na(xmin) | !is.na(xmax))) { p <- p + xlim(xmin, xmax) } # Set breaks if (!is.null(breaks)) { p <- p + scale_x_continuous(breaks=scales::pretty_breaks(n=breaks), limits=c(xmin, xmax)) } # Add Title if (!is.null(title)) { p <- p + ggtitle(title) } # Add additional theme elements p <- p + do.call(theme, list(...)) # Plot if (!silent) { plot(p) } else { return(p) } } #' Plot findThreshold results for the density method #' #' \code{plotDensityThreshold} plots the results from \code{"density"} method of #' \link{findThreshold}, including the smoothed density estimate, input nearest neighbor #' distance histogram, and threshold selected. #' #' @param data \link{DensityThreshold} object output by the \code{"density"} method #' of \link{findThreshold}. #' @param cross numeric vector of distances from \link{distToNearest} to draw as a #' histogram below the \code{data} histogram for comparison purposes. #' @param xmin minimum limit for plotting the x-axis. If \code{NULL} the limit will #' be set automatically. #' @param xmax maximum limit for plotting the x-axis. If \code{NULL} the limit will #' be set automatically. #' @param breaks number of breaks to show on the x-axis. If \code{NULL} the breaks will #' be set automatically. #' @param binwidth binwidth for the histogram. If \code{NULL} the binwidth #' will be set automatically to the bandwidth parameter determined by #' \link{findThreshold}. #' @param title string defining the plot title. #' @param size numeric value for the plot line sizes. #' @param silent if \code{TRUE} do not draw the plot and just return the ggplot2 #' object; if \code{FALSE} draw the plot. #' @param ... additional arguments to pass to ggplot2::theme. #' #' @return A ggplot object defining the plot. #' #' @seealso See \link{DensityThreshold} for the the input object definition and #' \link{findThreshold} for generating the input object. See #' \link{distToNearest} calculating nearest neighbor distances. #' #' @examples #' \donttest{ #' # Subset example data to one sample as a demo #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, SAMPLE == "-1h") #' #' # Use nucleotide Hamming distance and normalize by junction length #' db <- distToNearest(db, model="ham", normalize="len", nproc=1) #' #' # To find the threshold cut, call findThreshold function for "gmm" method. #' output <- findThreshold(db$DIST_NEAREST, method="density") #' print(output) #' #' # Plot #' plotDensityThreshold(output) #' } #' @export plotDensityThreshold <- function(data, cross=NULL, xmin=NULL, xmax=NULL, breaks=NULL, binwidth=NULL, title=NULL, size=1, silent=FALSE, ...) { # Define plot data.frames xdf <- data.frame(x=data@x) ddf <- data.frame(x=data@xdens, y=data@ydens) ddf <- ddf[ddf$x > 0, ] # Set binwidth if (is.null(binwidth)) { binwidth <- data@bandwidth } # ggplot workaround if (is.null(xmin)) { xmin <- NA } if (is.null(xmax)) { xmax <- NA } # Plot distToNearest distribution plus Gaussian fits p <- ggplot(xdf, aes_string(x="x")) + baseTheme() + xlab("Distance") + ylab("Density") + geom_histogram(aes_string(y="..density.."), binwidth=binwidth, fill="gray40", color="white") + geom_line(data=ddf, aes_string(x="x", y="y"), color="darkslateblue", size=size) + geom_vline(xintercept=data@threshold, color="firebrick", linetype="longdash", size=size) # Add cross histogram if (!is.null(cross)) { cdf <- data.frame(x=cross[is.finite(cross)]) p <- p + geom_histogram(data=cdf, aes_q(x=~x, y=~-(..density..)), binwidth=binwidth, fill="gray40", color="white", position="identity") + scale_y_continuous(labels=abs) } # Add x limits if (is.null(breaks) & (!is.na(xmin) | !is.na(xmax))) { p <- p + coord_cartesian(xlim = c(xmin, xmax)) } # Set breaks if (!is.null(breaks)) { p <- p + scale_x_continuous(breaks=scales::pretty_breaks(n=breaks), limits=c(xmin, xmax)) } # Add title if (!is.null(title)) { p <- p + ggtitle(title) } # Add additional theme elements p <- p + do.call(theme, list(...)) # Plot if (!silent) { plot(p) } else { return(p) } } shazam/R/TargetingModels.R0000644000176200001440000034315413575255254015200 0ustar liggesusers# Targeting models #' @include Shazam.R NULL #### Data #### #' Uniform 5-mer null targeting model. #' #' A null 5-mer model of somatic hypermutation targeting where all substitution, mutability #' and targeting rates are uniformly distributed. #' #' @format A \link{TargetingModel} object. #' #' @seealso See \link{HH_S5F} and \link{HKL_S5F} for the human 5-mer targeting models; and #' \link{MK_RS5NF} for the mouse 5-mer targeting model. "U5N" #' Human heavy chain, silent, 1-mer, functional substitution model. #' #' 1-mer substitution model of somatic hypermutation based on analysis of silent mutations #' in functional heavy chain Ig sequences from Homo sapiens. #' #' @format A 4x4 matrix of nucleotide substitution rates. The rates are normalized, #' therefore each row sums up to 1. #' #' @references #' \enumerate{ #' \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based #' on synonymous mutations from high-throughput immunoglobulin sequencing data. #' Front Immunol. 2013 4(November):358. #' } #' #' @seealso See \link{HKL_S1F} for the human light chain 1-mer substitution model and #' \link{MK_RS1NF} for the mouse light chain 1-mer substitution model. #' #' @note \code{HH_S1F} replaces \code{HS1FDistance} in versions of SHazaM prior to 0.1.5. "HH_S1F" #' Human kappa and lambda chain, silent, 1-mer, functional substitution model. #' #' 1-mer substitution model of somatic hypermutation based on analysis of silent mutations #' in functional kappa and lambda light chain Ig sequences from Homo sapiens. #' #' @format A 4x4 matrix of nucleotide substitution rates. The rates are normalized, #' therefore each row sums up to 1. #' #' @references #' \enumerate{ #' \item Cui A, Di Niro R, Vander Heiden J, Briggs A, Adams K, Gilbert T, O'Connor K, #' Vigneault F, Shlomchik M and Kleinstein S (2016). A Model of Somatic Hypermutation #' Targeting in Mice Based on High-Throughput Ig Sequencing Data. The Journal of #' Immunology, 197(9), 3566-3574. #' } #' #' @seealso See \link{HH_S1F} for the human heavy chain 1-mer substitution model and #' \link{MK_RS1NF} for the mouse light chain 1-mer substitution model. #' #' @note Reported in Table III in Cui et al, 2016. "HKL_S1F" #' Mouse kappa chain, replacement and silent, 1-mer, non-functional substitution model. #' #' 1-mer substitution model of somatic hypermutation based on analysis of replacement and #' silent mutations in non-functional kappa light chain Ig sequences from NP-immunized Mus #' musculus. #' #' @format A 4x4 matrix of nucleotide substitution rates. The rates are normalized, #' therefore each row sums up to 1. #' #' @references #' \enumerate{ #' \item Cui A, Di Niro R, Vander Heiden J, Briggs A, Adams K, Gilbert T, O'Connor K, #' Vigneault F, Shlomchik M and Kleinstein S (2016). A Model of Somatic Hypermutation #' Targeting in Mice Based on High-Throughput Ig Sequencing Data. The Journal of #' Immunology, 197(9), 3566-3574. #' } #' #' @seealso See \link{HH_S1F} for the human heavy chain 1-mer substitution model and #' \link{HKL_S1F} for the human light chain 1-mer substitution model. #' #' @note \code{MK_RS1NF} replaces \code{M1NDistance} from versions of SHazaM prior to 0.1.5. "MK_RS1NF" #' Human heavy chain, silent, 5-mer, functional targeting model. #' #' 5-mer model of somatic hypermutation targeting based on analysis of silent mutations #' in functional heavy chain Ig sequences from Homo sapiens. #' #' @format A \link{TargetingModel} object. #' #' @references #' \enumerate{ #' \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based #' on synonymous mutations from high-throughput immunoglobulin sequencing data. #' Front Immunol. 2013 4(November):358. #' } #' #' @seealso See \link{HH_S1F} for the 1-mer substitution matrix from the same #' publication; \link{HKL_S5F} for the human light chain 5-mer targeting model; #' \link{MK_RS5NF} for the mouse 5-mer targeting model; and \link{U5N} for the #' uniform 5-mer null targeting model. "HH_S5F" #' Human kappa and lambda light chain, silent, 5-mer, functional targeting model. #' #' 5-mer model of somatic hypermutation targeting based on analysis of silent mutations #' in functional kappa and lambda light chain Ig sequences from Homo sapiens. #' #' @format A \link{TargetingModel} object. #' #' @references #' \enumerate{ #' \item Cui A, Di Niro R, Vander Heiden J, Briggs A, Adams K, Gilbert T, O'Connor K, #' Vigneault F, Shlomchik M and Kleinstein S (2016). A Model of Somatic Hypermutation #' Targeting in Mice Based on High-Throughput Ig Sequencing Data. The Journal of #' Immunology, 197(9), 3566-3574. #' } #' #' @seealso See \link{HH_S5F} for the human heavy chain 5-mer targeting model; #' \link{MK_RS5NF} for the mouse kappa light chain 5-mer targeting model; #' and \link{U5N} for the uniform 5-mer null targeting model. "HKL_S5F" #' Mouse kappa light chain, replacement and silent, 5-mer, non-functional targeting model. #' #' 5-mer model of somatic hypermutation targeting based on analysis of replacement and #' silent mutations in non-functional kappa light chain Ig sequences from NP-immunized #' Mus musculus. #' #' @format \link{TargetingModel} object. #' #' @references #' \enumerate{ #' \item Cui A, Di Niro R, Vander Heiden J, Briggs A, Adams K, Gilbert T, O'Connor K, #' Vigneault F, Shlomchik M and Kleinstein S (2016). A Model of Somatic Hypermutation #' Targeting in Mice Based on High-Throughput Ig Sequencing Data. The Journal of #' Immunology, 197(9), 3566-3574. #' } #' #' @seealso See \link{MK_RS1NF} for the 1-mer substitution matrix from the same #' publication; \link{HH_S5F} for the human heavy chain silent 5-mer #' functional targeting model; \link{HKL_S5F} for the human light chain #' silent 5-mer functional targeting model; and \link{U5N} for the #' uniform 5-mer null targeting model. "MK_RS5NF" #### Classes #### #' S4 class defining a targeting model #' #' \code{TargetingModel} defines a common data structure for mutability, substitution and #' targeting of immunoglobulin (Ig) sequencing data in a 5-mer microsequence context. #' #' @slot name Name of the model. #' @slot description Description of the model and its source data. #' @slot species Genus and species of the source sequencing data. #' @slot date Date the model was built. #' @slot citation Publication source. #' @slot substitution Normalized rates of the center nucleotide of a given 5-mer #' mutating to a different nucleotide. The substitution model #' is stored as a 5x3125 matrix of rates. Rows define #' the mutated nucleotide at the center of each 5-mer, one of #' \code{c("A", "C", "G", "T", "N")}, and columns define the #' complete 5-mer of the unmutated nucleotide sequence. #' @slot mutability Normalized rates of a given 5-mer being mutated. The #' mutability model is stored as a numeric vector of length 3125 #' with mutability rates for each 5-mer. Note that "normalized" #' means that the mutability rates for the 1024 5-mers that #' contain no "N" at any position sums up to 1 (as opposed to #' the entire vector summing up to 1). #' @slot targeting Rate matrix of a given mutation ocurring, defined as #' \eqn{mutability * substitution}. The targeting model #' is stored as a 5x3125 matrix. Rows define #' the mutated nucleotide at the center of each 5-mer, one of #' \code{c("A", "C", "G", "T", "N")}, and columns define the complete 5-mer #' of the unmutated nucleotide sequence. #' #' @seealso See \link{createTargetingModel} building models from sequencing data. #' #' @name TargetingModel-class #' @rdname TargetingModel-class #' @aliases TargetingModel #' @exportClass TargetingModel setClass("TargetingModel", slots=c(name="character", description="character", species="character", date="character", citation="character", mutability="numeric", substitution="matrix", targeting="matrix"), prototype=list(name="name", description="description", species="species", date="2000-01-01", citation="citation", mutability=numeric(3125), substitution=matrix(0, 5, 3125), targeting=matrix(0, 5, 3125))) #### Methods #### #' @param x \code{TargetingModel} object. #' @param y ignored. #' @param ... arguments to pass to \link{plotMutability}. #' #' @rdname TargetingModel-class #' @aliases TargetingModel-method #' @export setMethod("plot", c(x="TargetingModel", y="missing"), function(x, y, ...) { plotMutability(x, ...) }) #### Model building functions ##### #' Builds a substitution model #' #' \code{createSubstitutionMatrix} builds a 5-mer nucleotide substitution model by counting #' the number of substitution mutations occuring in the center position for all 5-mer #' motifs. #' #' @param db data.frame containing sequence data. #' @param model type of model to create. The default model, "S", #' builds a model by counting only silent mutations. \code{model="S"} #' should be used for data that includes functional sequences. #' Setting \code{model="RS"} creates a model by counting both #' replacement and silent mutations and may be used on fully #' non-functional sequence data sets. #' @param sequenceColumn name of the column containing IMGT-gapped sample sequences. #' @param germlineColumn name of the column containing IMGT-gapped germline sequences. #' @param vCallColumn name of the column containing the V-segment allele call. #' @param multipleMutation string specifying how to handle multiple mutations occuring #' within the same 5-mer. If \code{"independent"} then multiple #' mutations within the same 5-mer are counted indepedently. #' If \code{"ignore"} then 5-mers with multiple mutations are #' excluded from the total mutation tally. #' @param returnModel string specifying what type of model to return; one of #' \code{c("5mer", "1mer", "1mer_raw")}. If \code{"5mer"} #' (the default) then a 5-mer nucleotide context model is #' returned. If \code{"1mer"} or \code{"1mer_raw"} then a single #' nucleotide substitution matrix (no context) is returned; #' where \code{"1mer_raw"} is the unnormalized version of the #' \code{"1mer"} model. Note, neither 1-mer model may be used #' as input to \link{createMutabilityMatrix}. #' @param minNumMutations minimum number of mutations required to compute the 5-mer #' substitution rates. If the number of mutations for a 5-mer #' is below this threshold, its substitution rates will be #' estimated from neighboring 5-mers. Default is 50. #' Not required if \code{numMutationsOnly=TRUE}. #' @param numMutationsOnly when \code{TRUE}, return counting information on the number #' of mutations for each 5-mer, instead of building a substitution #' matrix. This option can be used for parameter tuning for #' \code{minNumMutations} during preliminary analysis. #' Default is \code{FALSE}. Only applies when \code{returnModel} #' is set to \code{"5mer"}. The \code{data.frame} returned when #' this argument is \code{TRUE} can serve as the input for #' \link{minNumMutationsTune}. #' #' @return For \code{returnModel = "5mer"}: #' #' When \code{numMutationsOnly} is \code{FALSE}, a 4x1024 matrix of column #' normalized substitution rates for each 5-mer motif with row names defining #' the center nucleotide, one of \code{c("A", "C", "G", "T")}, and column names #' defining the 5-mer nucleotide sequence. #' #' When \code{numMutationsOnly} is #' \code{TRUE}, a 1024x4 data frame with each row providing information on #' counting the number of mutations for a 5-mer. Columns are named #' \code{fivemer.total}, \code{fivemer.every}, \code{inner3.total}, and #' \code{inner3.every}, corresponding to, respectively, #' the total number of mutations when counted as a 5-mer, #' whether there is mutation to every other base when counted as a 5-mer, #' the total number of mutations when counted as an inner 3-mer, and #' whether there is mutation to every other base when counted as an inner 3-mer. #' #' For \code{returnModel = "1mer"} or \code{"1mer_raw"}: #' a 4x4 normalized or un-normalized 1-mer substitution matrix respectively. #' #' @details \strong{Caution: The targeting model functions do NOT support ambiguous #' characters in their inputs. You MUST make sure that your input and germline #' sequences do NOT contain ambiguous characters (especially if they are #' clonal consensuses returned from \code{collapseClones}).} #' #' @references #' \enumerate{ #' \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based #' on synonymous mutations from high-throughput immunoglobulin sequencing data. #' Front Immunol. 2013 4(November):358. #' } #' #' @seealso \link{extendSubstitutionMatrix}, \link{createMutabilityMatrix}, #' \link{createTargetingMatrix}, \link{createTargetingModel}, #' \link{minNumMutationsTune}. #' #' @examples #' \donttest{ #' # Subset example data to one isotype and sample as a demo #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") #' #' # Count the number of mutations per 5-mer #' subCount <- createSubstitutionMatrix(db, model="S", multipleMutation="independent", #' returnModel="5mer", numMutationsOnly=TRUE) #' #' # Create model using only silent mutations #' sub <- createSubstitutionMatrix(db, model="S", multipleMutation="independent", #' returnModel="5mer", numMutationsOnly=FALSE, #' minNumMutations=20) #' } #' #' @export createSubstitutionMatrix <- function(db, model=c("S", "RS"), sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", vCallColumn="V_CALL", multipleMutation=c("independent", "ignore"), returnModel=c("5mer", "1mer", "1mer_raw"), minNumMutations=50, numMutationsOnly=FALSE) { # Evaluate argument choices model <- match.arg(model) multipleMutation <- match.arg(multipleMutation) returnModel <- match.arg(returnModel) # Check for valid columns check <- checkColumns(db, c(sequenceColumn, germlineColumn, vCallColumn)) if (check != TRUE) { stop(check) } # Convert sequence columns to uppercase db <- toupperColumns(db, c(sequenceColumn, germlineColumn)) # Check validity of input sequences # (MUST NOT CONTAIN AMBIGUOUS CHARACTERS -- not supported) bool_obsv <- checkAmbiguousExist(db[[sequenceColumn]]) bool_germ <- checkAmbiguousExist(db[[germlineColumn]]) if (any(bool_obsv | bool_germ)) { stop("Ambiguous characters are not supported in input sequences.") } # Setup nuc_chars <- NUCLEOTIDES[1:4] nuc_words <- seqinr::words(4, nuc_chars) # Define v_families (heavy or light chain) to only those found in the data v_families <- getFamily(db[[vCallColumn]]) # Define empty return list of lists substitutionMatrix <- matrix(0, ncol=4, nrow=4, dimnames=list(nuc_chars, nuc_chars)) substitutionList <- list() for(v_fam in unique(v_families)) { substitutionList[[v_fam]] <- list() for(word in nuc_words){ substitutionList[[v_fam]][[word]] <- substitutionMatrix } } # Remove IMGT gaps in the germline & input sequences matInputCollapsed <- removeCodonGaps(db[, c(sequenceColumn, germlineColumn)]) # TODO: Unnecessary conversion db[[sequenceColumn]] <- matInputCollapsed[, 1] db[[germlineColumn]] <- matInputCollapsed[, 2] # Get mutations mutations <- listObservedMutations(db, sequenceColumn=sequenceColumn, germlineColumn=germlineColumn, multipleMutation=multipleMutation, model=model) if (model == "S") { # Silent model for(index in 1:length(mutations)) { cSeq <- s2c(db[[sequenceColumn]][index]) cGL <- s2c(db[[germlineColumn]][index]) indexMutation <- mutations[[index]] v_fam <- v_families[index] positions <- as.numeric(names(indexMutation)) positions <- positions[positions<=VLENGTH] positions <- positions[!is.na(positions)] for( position in positions){ wrd <- c2s(c(cGL[(position-2):(position-1)],cGL[(position+1):(position+2)])) codonNucs <- getCodonPos(position) codonGL <- cGL[codonNucs] codonSeq <- cSeq[codonNucs] muCodonPos <- {position-1}%%3+1 seqAtMutation <- codonSeq[muCodonPos] glAtMutation <- codonGL[muCodonPos] if (!any(codonGL=="N") & !any(codonSeq=="N")) { codonPermutate <- matrix(rep(codonGL,3),ncol=3,byrow=T) codonPermutate[,muCodonPos] <- canMutateTo(glAtMutation)[-4] codonPermutate <- apply(codonPermutate,1,paste,collapse="") codonPermutate <- matrix( c( codonPermutate, rep(c2s(codonGL),3) ), ncol=2, byrow=F) # not intended to be used where input sequences have # ambiguous characters; it assumes that only 1 entry (R/S/Stop/na) from # mutationType is non-zero/1 muType <- mutationTypeOptimized(codonPermutate) if (!length(grep("N",wrd))) { if (sum(muType=="S") == length(muType) ){ substitutionList[[v_fam]][[wrd]][glAtMutation,seqAtMutation] <- (substitutionList[[v_fam]][[wrd]][glAtMutation,seqAtMutation] + 1) } } } } } } else if (model == "RS") { # RS model (All mutations) for (index in 1:length(mutations)) { cSeq <- s2c(db[[sequenceColumn]][index]) cGL <- s2c(db[[germlineColumn]][index]) indexMutation <- mutations[[index]] v_fam <- v_families[index] positions <- as.numeric(names(indexMutation)) positions <- positions[positions<=VLENGTH] positions <- positions[!is.na(positions)] for( position in positions){ wrd <- c2s(c(cGL[(position-2):(position-1)],cGL[(position+1):(position+2)])) codonNucs <- getCodonPos(position) codonGL <- cGL[codonNucs] codonSeq <- cSeq[codonNucs] muCodonPos <- {position-1}%%3+1 seqAtMutation <- codonSeq[muCodonPos] glAtMutation <- codonGL[muCodonPos] if( !any(codonGL=="N") & !any(codonSeq=="N") ){ if(!length(grep("N",wrd))){ substitutionList[[v_fam]][[wrd]][glAtMutation,seqAtMutation] <- substitutionList[[v_fam]][[wrd]][glAtMutation, seqAtMutation] + 1 } } } } } # Convert substitutionList to listSubstitution to facilitate the aggregation of mutations arrNames <- c(outer(unique(v_families), nuc_words, paste, sep = "_")) listSubstitution <- array(0, dim=c(length(arrNames), 4, 4), dimnames=list(arrNames, nuc_chars, nuc_chars)) for(v_fam in unique(v_families)){ listSubstitution[paste(v_fam, nuc_words, sep="_"), , ] <- t(sapply(nuc_words, function(word) { substitutionList[[v_fam]][[word]] })) } # Aggregate mutations from all V families M <- list() subMat1mer <- matrix(0, 4, 4) # a single substitution matrix for all fivemers listSubNames <- sapply(dimnames(listSubstitution)[[1]], function(x) { strsplit(x, "_", fixed=TRUE)[[1]] }) .sumSub <- function(i, n) { x <- listSubstitution[listSubNames[2, ] == n, i, ] if(is.null(dim(x))) { return (x) } else { return (colSums(x)) } } for (nuc_word in nuc_words) { # Sums mutations from all families M[[nuc_word]] <- t(sapply(1:4, .sumSub, n=nuc_word)) rownames(M[[nuc_word]]) <- nuc_chars subMat1mer <- subMat1mer + M[[nuc_word]] } # Return 1-mer substitution model; this output cannot be used for createMutabilityMatrix if (returnModel == "1mer") { subMat1merNorm <- t(apply(subMat1mer, 1, function(x){x/sum(x)})) return (subMat1merNorm) } else if (returnModel == "1mer_raw") { return (subMat1mer) } ##### for a given 5mer, count number of mutations # fivemer=M; FIVEMER="CCATT" .simplifivemer <- function(fivemer, FIVEMER, Thresh=50, count=F) { # center Nuc=substr(FIVEMER,3,3) # neighbors Nei=paste(substr(FIVEMER,1,2),substr(FIVEMER,4,5),collapse="",sep="") ### using 5mer # aggregate mutations FIVE.5 <- fivemer[[Nei]][Nuc,] # count total number of mutations for a given 5mer fivemer.total <- sum(FIVE.5) # are there mutations to every other base? fivemer.every <- ( sum(FIVE.5==0)==1 ) ### using inner 3mer # aggregate mutations from 5-mers with the same inner 3-mer FIVE.3 <- FIVE.5 for(i in 1:4){ for(j in 1:4){ MutatedNeighbor=paste(nuc_chars[i],substring(Nei,2,3),nuc_chars[j],collapse="",sep="") FIVE.3=FIVE.3+fivemer[[MutatedNeighbor]][Nuc,] } } # count total number of mutations for inner 3mer inner3.total <- sum(FIVE.3) # are there mutations to every other base? inner3.every <- ( sum(FIVE.3==0)==1 ) ### using 1mer FIVE.1 <- FIVE.5 MutatedNeighbors <- seqinr::words(4, nuc_chars) for (MutatedNeighbor in MutatedNeighbors) { FIVE.1=FIVE.1+fivemer[[MutatedNeighbor]][Nuc,] } if (!count) { # For a 5mer, if the total number of mutations is greater than Thresh, # and if there are mutations to every other base, compute for the 5mer if ( fivemer.total > Thresh & fivemer.every ){ return(FIVE.5) } else if ( inner3.total > Thresh & inner3.every ) { # Otherwise aggregate mutations from 5-mers with the same inner 3-mer return(FIVE.3) } else { # If the total number of mutations is still not enough, # aggregate mutations from all 5-mers (i.e., use 1-mer model) return(FIVE.1) } } return(data.frame(fivemer.total, fivemer.every, inner3.total, inner3.every, stringsAsFactors=F)) } # either construct 5mer substition matrix, and normalize (numMutationsOnly = F) if (!numMutationsOnly) { substitutionModel <- sapply(seqinr::words(5, nuc_chars), function(x) { .simplifivemer(M, x, Thresh = minNumMutations, count = numMutationsOnly) }, simplify=T) # Assign A->A, C->C, G->G, T->T to NA center_nuc <- gsub("..([ACGT])..", "\\1", colnames(substitutionModel)) for (i in 1:length(center_nuc)) { substitutionModel[center_nuc[i], i] <- NA } # Normalize by column substitutionModel <- apply(substitutionModel, 2, function(x) { x / sum(x, na.rm=TRUE) }) substitutionModel[!is.finite(substitutionModel)] <- NA } else { # or count number of mutations (numMutationsOnly = T), return data frame # need to set simplify to F in sapply() and then use bind_rows; otherwise # every entry in df would be a list substitutionModel <- sapply(seqinr::words(5, nuc_chars), function(x) { .simplifivemer(M, x, Thresh = minNumMutations, count = numMutationsOnly) }, simplify=F) substitutionModel <- dplyr::bind_rows(substitutionModel) rownames(substitutionModel) <- seqinr::words(5, nuc_chars) } return(substitutionModel) } #' Parameter tuning for minNumMutations #' #' \code{minNumMutationsTune} helps with picking a threshold value for \code{minNumMutations} #' in \link{createSubstitutionMatrix} by tabulating the number of 5-mers for which #' substitution rates would be computed directly or inferred at various threshold values. #' #' @param subCount \code{data.frame} returned by \link{createSubstitutionMatrix} #' with \code{numMutationsOnly=TRUE}. #' @param minNumMutationsRange a number or a vector indicating the value or range of values #' of \code{minNumMutations} to try. #' #' @return A 3xn \code{matrix}, where n is the number of trial values of \code{minNumMutations} #' supplied in \code{minNumMutationsRange}. Each column corresponds to a value #' in \code{minNumMutationsRange}. The rows correspond to the number of 5-mers #' for which substitution rates would be computed directly using the 5-mer itself #' (\code{"5mer"}), using its inner 3-mer (\code{"3mer"}), and using the central #' 1-mer (\code{"1mer"}), respectively. #' #' @details At a given threshold value of \code{minNumMutations}, for a given 5-mer, #' if the total number of mutations is greater than the threshold and there #' are mutations to every other base, substitution rates are computed directly #' for the 5-mer using its mutations. Otherwise, mutations from 5-mers with #' the same inner 3-mer as the 5-mer of interest are aggregated. If the number #' of such mutations is greater than the threshold and there are mutations to #' every other base, these mutations are used for inferring the substitution #' rates for the 5-mer of interest; if not, mutations from all 5-mers with the #' same center nucleotide are aggregated and used for inferring the substitution #' rates for the 5-mer of interest (i.e. the 1-mer model). #' #' @references #' \enumerate{ #' \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based #' on synonymous mutations from high-throughput immunoglobulin sequencing data. #' Front Immunol. 2013 4(November):358. #' } #' #' @seealso See argument \code{numMutationsOnly} in \link{createSubstitutionMatrix} #' for generating the required input \code{data.frame} \code{subCount}. #' See argument \code{minNumMutations} in \link{createSubstitutionMatrix} #' for what it does. #' #' @examples #' # Subset example data to one isotype and sample as a demo #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") #' #' # Count the number of mutations per 5-mer #' subCount <- createSubstitutionMatrix(db, model="S", multipleMutation="independent", #' returnModel="5mer", numMutationsOnly=TRUE) #' #' # Tune minNumMutations #' minNumMutationsTune(subCount, seq(from=10, to=100, by=10)) #' #' @export minNumMutationsTune <- function(subCount, minNumMutationsRange) { stopifnot( nrow(subCount)==1024 & ncol(subCount)==4 ) tuneMtx <- sapply(minNumMutationsRange, function(thresh) { method.count <- c(# as 5mer sum( subCount$fivemer.total > thresh & subCount$fivemer.every ), # as inner 3mer sum( !(subCount$fivemer.total > thresh & subCount$fivemer.every) & (subCount$inner3.total > thresh & subCount$inner3.every) ), # as 1mer sum( !(subCount$fivemer.total > thresh & subCount$fivemer.every) & !(subCount$inner3.total > thresh & subCount$inner3.every) ) ) names(method.count) <- c("5mer", "3mer", "1mer") stopifnot( sum(method.count)==1024 ) return(method.count) }) colnames(tuneMtx) <- minNumMutationsRange return(tuneMtx) } #' Builds a mutability model #' #' \code{createMutabilityMatrix} builds a 5-mer nucleotide mutability model by counting #' the number of mutations occuring in the center position for all 5-mer motifs. #' #' @param db data.frame containing sequence data. #' @param substitutionModel matrix of 5-mer substitution rates built by #' \link{createSubstitutionMatrix}. Note, this model will #' only impact mutability scores when \code{model="S"} #' (using only silent mutations). #' @param model type of model to create. The default model, "S", #' builds a model by counting only silent mutations. \code{model="S"} #' should be used for data that includes functional sequences. #' Setting \code{model="RS"} creates a model by counting both #' replacement and silent mutations and may be used on fully #' non-functional sequence data sets. #' @param sequenceColumn name of the column containing IMGT-gapped sample sequences. #' @param germlineColumn name of the column containing IMGT-gapped germline sequences. #' @param vCallColumn name of the column containing the V-segment allele call. #' @param multipleMutation string specifying how to handle multiple mutations occuring #' within the same 5-mer. If \code{"independent"} then multiple #' mutations within the same 5-mer are counted indepedently. #' If \code{"ignore"} then 5-mers with multiple mutations are #' excluded from the total mutation tally. #' @param minNumSeqMutations minimum number of mutations in sequences containing each 5-mer #' to compute the mutability rates. If the number is smaller #' than this threshold, the mutability for the 5-mer will be #' inferred. Default is 500. Not required if #' \code{numSeqMutationsOnly=TRUE}. #' @param numSeqMutationsOnly when \code{TRUE}, return only a vector counting the number of #' observed mutations in sequences containing each 5-mer. This #' option can be used for parameter tuning for \code{minNumSeqMutations} #' during preliminary analysis using \link{minNumSeqMutationsTune}. #' Default is \code{FALSE}. #' @param returnSource return the sources of 5-mer mutabilities (measured vs. #' inferred). Default is \code{FALSE}. #' #' @return When \code{numSeqMutationsOnly} is \code{FALSE}, a named numeric vector of 1024 #' normalized mutability rates for each 5-mer motif with names defining the 5-mer #' nucleotide sequence. #' #' When \code{numSeqMutationsOnly} is \code{TRUE}, a named numeric #' vector of length 1024 counting the number of observed mutations in sequences containing #' each 5-mer. #' #' @details \strong{Caution: The targeting model functions do NOT support ambiguous #' characters in their inputs. You MUST make sure that your input and germline #' sequences do NOT contain ambiguous characters (especially if they are #' clonal consensuses returned from \code{collapseClones}).} #' #' @references #' \enumerate{ #' \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based #' on synonymous mutations from high-throughput immunoglobulin sequencing data. #' Front Immunol. 2013 4(November):358. #' } #' #' @seealso \link{extendMutabilityMatrix}, \link{createSubstitutionMatrix}, #' \link{createTargetingMatrix}, \link{createTargetingModel}, #' \link{minNumSeqMutationsTune} #' #' @examples #' \donttest{ #' # Subset example data to one isotype and sample as a demo #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") #' #' # Create model using only silent mutations #' sub_model <- createSubstitutionMatrix(db, model="S") #' mut_model <- createMutabilityMatrix(db, sub_model, model="S", #' minNumSeqMutations=200, #' numSeqMutationsOnly=FALSE) #' #' # Count the number of mutations in sequences containing each 5-mer #' mut_count <- createMutabilityMatrix(db, sub_model, model="S", #' numSeqMutationsOnly=TRUE) #' } #' #' @export createMutabilityMatrix <- function(db, substitutionModel, model=c("S", "RS"), sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", vCallColumn="V_CALL", multipleMutation=c("independent", "ignore"), minNumSeqMutations=500, numSeqMutationsOnly=FALSE, returnSource=FALSE) { # substitutionModel=sub_model; model="S"; sequenceColumn="SEQUENCE_IMGT"; germlineColumn="GERMLINE_IMGT_D_MASK" # vCallColumn="V_CALL"; multipleMutation="ignore"; minNumSeqMutations=10; returnSource=FALSE # Evaluate argument choices model <- match.arg(model) multipleMutation <- match.arg(multipleMutation) # Check for valid columns check <- checkColumns(db, c(sequenceColumn, germlineColumn, vCallColumn)) if (check != TRUE) { stop(check) } # Convert sequence columns to uppercase db <- toupperColumns(db, c(sequenceColumn, germlineColumn)) # Check validity of input sequences # (MUST NOT CONTAIN AMBIGUOUS CHARACTERS -- not supported) bool_obsv <- checkAmbiguousExist(db[[sequenceColumn]]) bool_germ <- checkAmbiguousExist(db[[germlineColumn]]) if (any(bool_obsv | bool_germ)) { stop("Ambiguous characters are not supported in input sequences.") } # Check that the substitution model is valid if (any(dim(substitutionModel) != c(4, 1024))) { stop ("Please supply a valid 5-mer substitutionModel.") } # Set constants for function nuc_chars <- NUCLEOTIDES[1:4] # Remove IMGT gaps in the germline & input sequences matInputCollapsed <- removeCodonGaps(db[, c(sequenceColumn, germlineColumn)]) # TODO: Unnecessary conversion db[[sequenceColumn]] <- matInputCollapsed[, 1] db[[germlineColumn]] <- matInputCollapsed[, 2] # Count mutations # TODO: this could be listMutations() instead, and skip the conversion from matInputCollapsed back to a data.frame mutations <- listObservedMutations(db, sequenceColumn=sequenceColumn, germlineColumn=germlineColumn, multipleMutation=multipleMutation, model=model) # Foreground Count: Count the number of observed mutations for each 5-mer template <- rep(0, 1024) names(template) <- seqinr::words(5, nuc_chars) COUNT <- list() for(index in 1:length(mutations)){ COUNT[[index]] <- template indexMutation <- mutations[[index]] if(!sum(is.na(indexMutation))){ cSeq <- s2c(db[[sequenceColumn]][index]) cGL <- s2c(db[[germlineColumn]][index]) positions <- as.numeric(names(indexMutation)) positions <- positions[positions <= VLENGTH] positions <- positions[!is.na(positions)] for (position in positions){ wrd5 <- substr(db[[germlineColumn]][index], position - 2, position + 2) if(!grepl("[^ACGT]", wrd5) & nchar(wrd5) == 5){ codonNucs <- getCodonPos(position) codonGL <- cGL[codonNucs] codonSeq <- cSeq[codonNucs] muCodonPos <- {position - 1} %% 3 + 1 #seqAtMutation <- codonSeq[muCodonPos] glAtMutation <- codonGL[muCodonPos] if (!any(codonGL %in% c("N", "-", ".")) & !any(codonSeq %in% c("N", "-", "."))) { if (!length(grep("N", wrd5))) { COUNT[[index]][wrd5]<- COUNT[[index]][wrd5] + 1; } } } } } } # Define sum of rates for nucleotide sets from substitution model # Two character sets wrd2Index <- combn(1:4, 2) wrd2Sums <- t(apply(wrd2Index, 2, function(x) colSums(substitutionModel[x, ], na.rm=TRUE))) rownames(wrd2Sums) <- apply(wrd2Index, 2, function(x) paste(nuc_chars[x], collapse="")) # Three character sets wrd3Index <- combn(1:4, 3) wrd3Sums <- t(apply(wrd3Index, 2, function(x) colSums(substitutionModel[x, ], na.rm=TRUE))) rownames(wrd3Sums) <- apply(wrd3Index, 2, function(x) paste(nuc_chars[x], collapse="")) # Merge single character, two character and three character sets substitutionSums <- rbind(substitutionModel, wrd2Sums, wrd3Sums) # Replace dots with Ns sSeqVec <- gsub("\\.", "N", db[[sequenceColumn]]) sGermVec <- gsub("\\.", "N", db[[germlineColumn]]) # Define template for 5-mer sums by position countTemplate <- matrix(0, VLENGTH, 1024, dimnames=list(1:VLENGTH, names(template))) # Background Count: Count the number of occurrences of each 5-mer BG_COUNT <- list() for (index in 1:length(mutations)) { tmpCounts <- countTemplate sGL <- sGermVec[index] cSeq <- s2c(sSeqVec[index]) cGL <- s2c(sGL)[1:VLENGTH] positions <- 3:(length(cGL) - 2) for (pos in positions) { wrd5 <- substr(sGL, pos - 2, pos + 2) if (!grepl("[^ACGT]", wrd5) & nchar(wrd5) == 5) { codonNucs <- getCodonPos(pos) codonGL <- cGL[codonNucs] codonSeq <- cSeq[codonNucs] muCodonPos <- (pos - 1) %% 3 + 1 glAtMutation <- codonGL[muCodonPos] if (!any(codonGL %in% c("N", "-")) & !any(codonSeq %in% c("N", "-"))) { # Determine mutation types for NUCLEOTIDES[1:4] muType <- CODON_TABLE[1:4 + 4*(muCodonPos - 1), stri_flatten(codonGL)] # Set characters that meet mutation criteria if (model == "S") { muChars <- nuc_chars[1:4][nuc_chars[1:4] != glAtMutation & muType == "S"] } else { muChars <- nuc_chars[1:4][nuc_chars[1:4] != glAtMutation] } # Update counts if (length(muChars) > 0) { #cat(stri_flatten(muChars), substitutionSums[stri_flatten(muChars), wrd5], "\n") tmpCounts[pos, wrd5] <- substitutionSums[stri_flatten(muChars), wrd5] } } } } BG_COUNT[[index]] <- colSums(tmpCounts) BG_COUNT[[index]][BG_COUNT[[index]] == 0] <- NA } Mutability <- list() for(i in 1:length(mutations)) { mut_mat <- COUNT[[i]] / BG_COUNT[[i]] mut_mat <- mut_mat / sum(mut_mat, na.rm=TRUE) mut_mat[!is.finite(mut_mat)] <- NA wgt_mat <- length(mutations[[i]]) Mutability[[i]] <- list(mut_mat, wgt_mat) } # Aggregate mutability MutabilityMatrix <- sapply(Mutability, function(x) x[[1]]) MutabilityWeights <- sapply(Mutability, function(x) x[[2]]) Mutability_Mean <- apply(MutabilityMatrix, 1, weighted.mean, w=MutabilityWeights, na.rm=TRUE) Mutability_Mean[!is.finite(Mutability_Mean)] <- NA Mutability_Mean[Mutability_Mean == 0] <- NA # Filter out 5-mers with low number of observed mutations in the sequences NumSeqMutations <- sapply(1:1024,function(i)sum(MutabilityWeights[!is.na(MutabilityMatrix[i,])])) names(NumSeqMutations) <- names(Mutability_Mean) if (numSeqMutationsOnly) {return(NumSeqMutations)} Mutability_Mean[NumSeqMutations <= minNumSeqMutations] <- NA # Infer mutability for missing 5-mers .fillHot <-function(FIVEMER,mutability){ if(FIVEMER%in%names(mutability))if(!is.na(mutability[[FIVEMER]]))if(mutability[[FIVEMER]]>=0.0)return(mutability[[FIVEMER]]) Nuc=substr(FIVEMER,3,3) #Nei=paste(substr(FIVEMER,1,2),substr(FIVEMER,4,5),collapse="",sep="") FIVE=0 COUNT=0 # For A/T, infer mutability using the 3-mer model. if(Nuc%in%c("A","T")){ for(i in 1:3){ for(j in 1:3){ MutatedNeighbor=paste(canMutateTo(substr(FIVEMER,1,1))[i],substr(FIVEMER,2,4),canMutateTo(substr(FIVEMER,5,5))[j],collapse="",sep="") if(!is.na(mutability[[MutatedNeighbor]])){ FIVE=FIVE+mutability[[MutatedNeighbor]] COUNT=COUNT+1 } } } return(FIVE/COUNT) } # For G, infer using 5-mers with the same downstream nucleotides if(Nuc=="G"){ for(i in 1:3){ for(j in 1:3){ MutatedNeighbor=paste(canMutateTo(substr(FIVEMER,1,1))[i],canMutateTo(substr(FIVEMER,2,2))[j],substr(FIVEMER,3,5),collapse="",sep="") if(!is.na(mutability[[MutatedNeighbor]])){ FIVE=FIVE+mutability[[MutatedNeighbor]] COUNT=COUNT+1 } } } return(FIVE/COUNT) } # For C, infer using 5-mers with the same upstream nucleotides if(Nuc=="C"){ for(i in 1:3){ for(j in 1:3){ MutatedNeighbor=paste(substr(FIVEMER,1,3),canMutateTo(substr(FIVEMER,4,4))[i],canMutateTo(substr(FIVEMER,5,5))[j],collapse="",sep="") if(!is.na(mutability[[MutatedNeighbor]])){ FIVE=FIVE+mutability[[MutatedNeighbor]] COUNT=COUNT+1 } } } return(FIVE/COUNT) } } Mutability_Mean_Complete <-sapply(words(5, nuc_chars), .fillHot, mutability = Mutability_Mean) for(i in names(which(is.na(Mutability_Mean_Complete)))){ Mutability_Mean_Complete[i]<- .fillHot(i,mutability=Mutability_Mean_Complete) } for(i in names(which((Mutability_Mean_Complete)<1e-6))){ Mutability_Mean_Complete[i]<- .fillHot(i,mutability=Mutability_Mean_Complete) } # If the neighboring 5-mers still don't have enough mutations, use 0 instead. if (length(is.na(Mutability_Mean_Complete)) > 0) { warning("Insufficient number of mutations to infer some 5-mers. Filled with 0. ") Mutability_Mean_Complete[is.na(Mutability_Mean_Complete)] <- 0 } # Normalize Mutability_Mean_Complete <- Mutability_Mean_Complete / sum(Mutability_Mean_Complete, na.rm=TRUE) # Return whether the 5-mer mutability is measured or inferred if (returnSource) { Mutability_Mean_Complete_Source <- data.frame(Fivemer = names(Mutability_Mean_Complete), Mutability = Mutability_Mean_Complete) Mutability_Mean_Complete_Source$Source <- "Measured" Mutability_Mean_Complete_Source[Mutability_Mean_Complete_Source$Fivemer %in% names(which(is.na(Mutability_Mean))), "Source"] <- "Inferred" return(Mutability_Mean_Complete_Source) } return(Mutability_Mean_Complete) } #' Parameter tuning for minNumSeqMutations #' #' \code{minNumSeqMutationsTune} helps with picking a threshold value for \code{minNumSeqMutations} #' in \link{createMutabilityMatrix} by tabulating the number of 5-mers for which #' mutability would be computed directly or inferred at various threshold values. #' #' @param mutCount a \code{vector} of length 1024 returned by #' \link{createMutabilityMatrix} with \code{numSeqMutationsOnly=TRUE}. #' @param minNumSeqMutationsRange a number or a vector indicating the value or the range of values #' of \code{minNumSeqMutations} to try. #' #' @return A 2xn \code{matrix}, where n is the number of trial values of \code{minNumSeqMutations} #' supplied in \code{minNumSeqMutationsRange}. Each column corresponds to a value #' in \code{minNumSeqMutationsRange}. The rows correspond to the number of 5-mers #' for which mutability would be computed directly (\code{"measured"}) and inferred #' (\code{"inferred"}), respectively. #' #' @details At a given threshold value of \code{minNumSeqMutations}, for a given 5-mer, #' if the total number of mutations is greater than the threshold, mutability #' is computed directly. Otherwise, mutability is inferred. #' #' @references #' \enumerate{ #' \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based #' on synonymous mutations from high-throughput immunoglobulin sequencing data. #' Front Immunol. 2013 4(November):358. #' } #' #' @seealso See argument \code{numSeqMutationsOnly} in \link{createMutabilityMatrix} #' for generating the required input \code{vector} \code{mutCount}. #' See argument \code{minNumSeqMutations} in \link{createMutabilityMatrix} #' for what it does. #' #' @examples #' \donttest{ #' # Subset example data to one isotype and sample as a demo #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") #' #' # Create model using only silent mutations #' sub <- createSubstitutionMatrix(db, model="S", multipleMutation="independent", #' returnModel="5mer", numMutationsOnly=FALSE, #' minNumMutations=20) #' #' # Count the number of mutations in sequences containing each 5-mer #' mutCount <- createMutabilityMatrix(db, substitutionModel = sub, #' model="S", multipleMutation="independent", #' numSeqMutationsOnly=TRUE) #' #' # Tune minNumSeqMutations #' minNumSeqMutationsTune(mutCount, seq(from=100, to=300, by=50)) #' } #' @export minNumSeqMutationsTune <- function(mutCount, minNumSeqMutationsRange) { stopifnot( length(mutCount) == 1024 ) tuneMtx <- sapply(minNumSeqMutationsRange, function(thresh) { method.count <- c( sum(mutCount > thresh), sum(mutCount <= thresh) ) names(method.count) <- c("measured", "inferred") stopifnot( sum(method.count)==1024 ) return(method.count) }) colnames(tuneMtx) <- minNumSeqMutationsRange return(tuneMtx) } #' Extends a substitution model to include Ns. #' #' \code{extendSubstitutionMatrix} extends a 5-mer nucleotide substitution model #' with 5-mers that include Ns by averaging over all corresponding 5-mers without Ns. #' #' @param substitutionModel matrix of 5-mers substitution counts built by #' \link{createSubstitutionMatrix}. #' #' @return A 5x3125 matrix of normalized substitution rate for each 5-mer motif with #' rows names defining the center nucleotide, one of \code{c("A", "C", "G", "T", "N")}, #' and column names defining the 5-mer nucleotide sequence. #' #' @seealso \link{createSubstitutionMatrix}, \link{extendMutabilityMatrix} #' #' @examples #' # Subset example data to one isotype and sample as a demo #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") #' #' # Create model using only silent mutations #' sub_model <- createSubstitutionMatrix(db, model="S") #' ext_model <- extendSubstitutionMatrix(sub_model) #' #' @export extendSubstitutionMatrix <- function(substitutionModel) { # TODO: fix order so Ns are at the end? (c(input_names, words not in input_names)) # Define old and new column/row names input_names <- colnames(substitutionModel) nuc_chars <- NUCLEOTIDES[1:5] nuc_5mers <- seqinr::words(5, alphabet=nuc_chars) # Define empty extended matrix with Ns extend_mat <- matrix(NA, nrow=length(nuc_chars), ncol=length(nuc_5mers), dimnames=list(nuc_chars, nuc_5mers)) # Extend matrix with Ns for (mer in nuc_5mers) { if (mer %in% input_names) { extend_mat[, mer] <- c(substitutionModel[, mer], "N"=NA) } else { mer_char <- s2c(mer) n_index <- grep("N", mer_char) if (any(n_index == 3)) { extend_mat[, mer] <- NA } else { mer_char[n_index] <- "." mer_str <- c2s(mer_char) mer_index <- grep(mer_str, input_names) extend_mat[, mer] <- c(apply(substitutionModel[, mer_index], 1, mean, na.rm=TRUE), "N"=NA) } } } # Normalize #extend_mat <- apply(extend_mat, 2, function(x) { x/sum(x, na.rm=TRUE) }) extend_mat[!is.finite(extend_mat)] <- NA return (extend_mat) } #' Extends a mutability model to include Ns. #' #' \code{extendMutabilityMatrix} extends a 5-mer nucleotide mutability model #' with 5-mers that include Ns by averaging over all corresponding 5-mers without Ns. #' #' @param mutabilityModel vector of 5-mer mutability rates built by #' \link{createMutabilityMatrix}. #' #' @return A 3125 vector of normalized mutability rates for each 5-mer motif with #' names defining the 5-mer nucleotide sequence. Note that "normalized" means #' that the mutability rates for the 1024 5-mers that contain no "N" at any #' position sums up to 1 (as opposed to the entire vector summing up to 1). #' #' @seealso \link{createMutabilityMatrix}, \link{extendSubstitutionMatrix} #' #' @examples #' \donttest{ #' # Subset example data to one isotype and sample as a demo #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") #' #' # Create model using only silent mutations and ignore multiple mutations #' sub_model <- createSubstitutionMatrix(db, model="S") #' mut_model <- createMutabilityMatrix(db, sub_model, model="S") #' ext_model <- extendMutabilityMatrix(mut_model) #' } #' #' @export extendMutabilityMatrix <- function(mutabilityModel) { # TODO: fix order so Ns are at the end? (c(input_names, words not in input_names)) # Define old and new column/row names input_names <- names(mutabilityModel) nuc_chars <- NUCLEOTIDES[1:5] nuc_5mers <- seqinr::words(5, alphabet=nuc_chars) # Define empty extended matrix with Ns extend_mat <- array(NA, dim=length(nuc_5mers), dimnames=list(nuc_5mers)) # Extend matrix with Ns for(mer in nuc_5mers) { #cat(mer,"\n") if (mer %in% input_names) { extend_mat[mer] <- mutabilityModel[mer] } else { mer_char <- s2c(mer) n_index <- grep("N", mer_char) if (any(n_index == 3)) { extend_mat[mer] <- NA } else { mer_char[n_index] <- "." mer_str <- c2s(mer_char) mer_index <- grep(mer_str, input_names) extend_mat[mer] <- mean(mutabilityModel[mer_index], na.rm=TRUE) } } } # Normalize #extend_mat <- extend_mat / sum(extend_mat, na.rm=TRUE) extend_mat[!is.finite(extend_mat)] <- NA return(extend_mat) } #' Calculates a targeting rate matrix #' #' \code{createTargetingMatrix} calculates the targeting model matrix as the #' combined probability of mutability and substitution. #' #' @param substitutionModel matrix of 5-mers substitution rates built by #' \link{createSubstitutionMatrix} or #' \link{extendSubstitutionMatrix}. #' @param mutabilityModel vector of 5-mers mutability rates built by #' \link{createMutabilityMatrix} or #' \link{extendMutabilityMatrix}. #' #' @return A matrix with the same dimensions as the input \code{substitutionModel} #' containing normalized targeting probabilities for each 5-mer motif with #' row names defining the center nucleotide and column names defining the #' 5-mer nucleotide sequence. #' #' @details #' Targeting rates are calculated by multiplying the normalized mutability rate by the #' normalized substitution rates for each individual 5-mer. #' #' @references #' \enumerate{ #' \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based #' on synonymous mutations from high-throughput immunoglobulin sequencing data. #' Front Immunol. 2013 4(November):358. #' } #' #' @seealso \link{createSubstitutionMatrix}, \link{extendSubstitutionMatrix}, #' \link{createMutabilityMatrix}, \link{extendMutabilityMatrix}, #' \link{createTargetingModel} #' #' @examples #' \donttest{ #' # Subset example data to one isotype and sample as a demo #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") #' #' # Create 4x1024 models using only silent mutations #' sub_model <- createSubstitutionMatrix(db, model="S") #' mut_model <- createMutabilityMatrix(db, sub_model, model="S") #' #' # Extend substitution and mutability to including Ns (5x3125 model) #' sub_model <- extendSubstitutionMatrix(sub_model) #' mut_model <- extendMutabilityMatrix(mut_model) #' #' # Create targeting model from substitution and mutability #' tar_model <- createTargetingMatrix(sub_model, mut_model) #' } #' #' @export createTargetingMatrix <- function(substitutionModel, mutabilityModel) { # Calculate targeting tar_mat <- sweep(substitutionModel, 2, mutabilityModel, `*`) # Normalize #tar_mat <- tar_mat / sum(tar_mat, na.rm=TRUE) tar_mat[!is.finite(tar_mat)] <- NA return(tar_mat) } #' Creates a TargetingModel #' #' \code{createTargetingModel} creates a 5-mer \code{TargetingModel}. #' #' @param db data.frame containing sequence data. #' @param model type of model to create. The default model, "S", #' builds a model by counting only silent mutations. \code{model="S"} #' should be used for data that includes functional sequences. #' Setting \code{model="RS"} creates a model by counting both #' replacement and silent mutations and may be used on fully #' non-functional sequence data sets. #' @param sequenceColumn name of the column containing IMGT-gapped sample sequences. #' @param germlineColumn name of the column containing IMGT-gapped germline sequences. #' @param vCallColumn name of the column containing the V-segment allele calls. #' @param multipleMutation string specifying how to handle multiple mutations occuring #' within the same 5-mer. If \code{"independent"} then multiple #' mutations within the same 5-mer are counted indepedently. #' If \code{"ignore"} then 5-mers with multiple mutations are #' excluded from the otal mutation tally. #' @param minNumMutations minimum number of mutations required to compute the 5-mer #' substitution rates. If the number of mutations for a 5-mer #' is below this threshold, its substitution rates will be #' estimated from neighboring 5-mers. Default is 50. #' @param minNumSeqMutations minimum number of mutations in sequences containing each 5-mer #' to compute the mutability rates. If the number is smaller #' than this threshold, the mutability for the 5-mer will be #' inferred. Default is 500. #' @param modelName name of the model. #' @param modelDescription description of the model and its source data. #' @param modelSpecies genus and species of the source sequencing data. #' @param modelDate date the model was built. If \code{NULL} the current date #' will be used. #' @param modelCitation publication source. #' #' @return A \link{TargetingModel} object. #' #' @details \strong{Caution: The targeting model functions do NOT support ambiguous #' characters in their inputs. You MUST make sure that your input and germline #' sequences do NOT contain ambiguous characters (especially if they are #' clonal consensuses returned from \code{collapseClones}).} #' #' @references #' \enumerate{ #' \item Yaari G, et al. Models of somatic hypermutation targeting and substitution based #' on synonymous mutations from high-throughput immunoglobulin sequencing data. #' Front Immunol. 2013 4(November):358. #' } #' #' @seealso See \link{TargetingModel} for the return object. #' See \link{plotMutability} plotting a mutability model. #' See \link{createSubstitutionMatrix}, \link{extendSubstitutionMatrix}, #' \link{createMutabilityMatrix}, \link{extendMutabilityMatrix} and #' \link{createTargetingMatrix} for component steps in building a model. #' #' @examples #' \donttest{ #' # Subset example data to one isotype and sample as a demo #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") #' #' # Create model using only silent mutations and ignore multiple mutations #' model <- createTargetingModel(db, model="S", multipleMutation="ignore") #' } #' #' @export createTargetingModel <- function(db, model=c("S", "RS"), sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", vCallColumn="V_CALL", multipleMutation=c("independent", "ignore"), minNumMutations=50, minNumSeqMutations=500, modelName="", modelDescription="", modelSpecies="", modelCitation="", modelDate=NULL) { # Evaluate argument choices model <- match.arg(model) multipleMutation <- match.arg(multipleMutation) # Check for valid columns check <- checkColumns(db, c(sequenceColumn, germlineColumn, vCallColumn)) if (check != TRUE) { stop(check) } # Check validity of input sequences # (MUST NOT CONTAIN AMBIGUOUS CHARACTERS -- not supported) bool_obsv <- checkAmbiguousExist(db[[sequenceColumn]]) bool_germ <- checkAmbiguousExist(db[[germlineColumn]]) if (any(bool_obsv | bool_germ)) { stop("Ambiguous characters are not supported in input sequences.") } # Set date if (is.null(modelDate)) { modelDate <- format(Sys.time(), "%Y-%m-%d") } # Create models sub_mat<- createSubstitutionMatrix(db, model=model, sequenceColumn=sequenceColumn, germlineColumn=germlineColumn, vCallColumn=vCallColumn, multipleMutation=multipleMutation, minNumMutations=minNumMutations, returnModel="5mer") mut_mat <- createMutabilityMatrix(db, sub_mat, model=model, sequenceColumn=sequenceColumn, germlineColumn=germlineColumn, vCallColumn=vCallColumn, multipleMutation=multipleMutation, minNumSeqMutations=minNumSeqMutations, returnSource=FALSE) # Extend 5-mers with Ns sub_mat <- extendSubstitutionMatrix(sub_mat) mut_mat <- extendMutabilityMatrix(mut_mat) # Make targeting matrix tar_mat <- createTargetingMatrix(sub_mat, mut_mat) # Define TargetingModel object model_obj <- new("TargetingModel", name=modelName, description=modelDescription, species=modelSpecies, date=modelDate, citation=modelCitation, substitution=sub_mat, mutability=mut_mat, targeting=tar_mat) return(model_obj) } #' Calculate total mutability #' #' \code{calculateMutability} calculates the total (summed) mutability for a set of sequences #' based on a 5-mer nucleotide mutability model. #' #' @param sequences character vector of sequences. #' @param model \link{TargetingModel} object with mutation likelihood information. #' @param progress if \code{TRUE} print a progress bar. #' #' @return Numeric vector with a total mutability score for each sequence. #' #' @examples #' \donttest{ #' # Subset example data to one isotype and sample as a demo #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE == "IgA" & SAMPLE == "-1h") #' #' # Calculate mutability of germline sequences using \link{HH_S5F} model #' mutability <- calculateMutability(sequences=db$GERMLINE_IMGT_D_MASK, model=HH_S5F) #' } #' #' @export calculateMutability <- function(sequences, model=HH_S5F, progress=FALSE) { # Initialize variables alphb <- seqinr::s2c("ACGTN") model_kmer <- names(model@mutability) model_rates <- as.vector(model@mutability) sequences <- toupper(sequences) sequences <- gsub("\\.", "N", sequences) # Mutability calculation mutability <- vector(mode="numeric", length=length(sequences)) if (progress) { pb <- progressBar(length(sequences)) } for (s in 1:length(sequences)) { kmer <- seqinr::count(seqinr::s2c(sequences[s]), wordsize=5, alphabet=alphb) seq_kmer <- names(kmer) seq_counts <- as.vector(kmer) index <- match(seq_kmer, model_kmer) mutability[s] <- sum(seq_counts*model_rates[index], na.rm=TRUE) if (progress) { pb$tick() } } return(mutability) } # Create model and rescale mutabilities # model <- createTargetingModel(db, model="S", multipleMutation="ignore") # mut <- rescaleMutability(model) rescaleMutability <- function(model, mean=1.0) { if (is(model, "TargetingModel")) { model <- model@mutability } else if (!is(model, "vector")) { stop("Input must be either a mutability vector or TargetingModel object.") } # TODO: perhaps this is not so useful. or perhaps it should be relative to max(model). # Renormalize rescaled <- model / sum(model, na.rm=T) * sum(!is.na(model)) * mean rescaled[!is.finite(rescaled)] <- NA return(rescaled) } # Remove in-frame IMGT gaps # # @param matInput Nx2 matrix with input and germline sequences in each column # @return A two column matrix with "..." codons removed. removeCodonGaps <- function(matInput) { # Function to return valid codon sets # i = position, x = codon list 1, y = codon list 2 .f1 <- function(i, x, y) { xcod <- x[i] ycod <- y[i] if (xcod != "..." & ycod != "...") { c(xcod, ycod) } else { c("", "") } } # Function to parse sequences # z = vector of 2 sequences .f2 <- function(z) { # Split strings into 3-mers cods <- stri_extract_all_regex(c(z[1], z[2]), ".{3}") cmat <- sapply(1:length(cods[[1]]), .f1, x=cods[[1]], y=cods[[2]]) apply(cmat, 1, paste, collapse="") } matCollapsed <- t(apply(matInput, 1, .f2)) return(matCollapsed) } #' Make a degenerate 5-mer substitution model based on a 1-mer substitution model #' #' \code{makeDegenerate5merSub} populates substitution rates from a 1-mer substitution model #' into 5-mers with corresponding central 1-mers. #' #' @param sub1mer a 4x4 matrix containing (normalized) substitution rates. #' Row names should correspond to nucleotides to mutate from. #' Column names should correspond to nucleotides to mutate into. #' Nucleotides should include "A", "T", "G", and "C" #' (case-insensitive). #' @param extended whether to return the unextended (\code{extended=FALSE}) or #' extended (\code{extended=TRUE}) 5-mer substitution model. #' Default is \code{FALSE}. #' #' @return For \code{extended=FALSE}, a 4x1024 matrix. For \code{extended=TRUE}, a 5x3125 #' matrix. #' #' @details As a concrete example, consider a 1-mer substitution model in which substitution #' rates from "A" to "T", "G", and "C" are, respectively, 0.1, 0.6, and 0.3. In the #' resultant degenerate 5-mer substitution model, all the 5-mers (columns) that have #' an "A" as their central 1-mer would have substitution rates (rows) of 0.1, 0.6, and #' 0.3 to "T", "G", and "C" respectively. #' #' When \code{extended=TRUE}, \code{extendSubstitutionMatrix} is called to extend #' the 4x1024 substitution matrix. #' #' @seealso See \link{makeAverage1merSub} for making a 1-mer substitution model by taking #' the average of a 5-mer substitution model. See \link{extendSubstitutionMatrix} #' for extending the substitution matrix. #' #' @examples #' # Make a degenerate 5-mer model (4x1024) based on HKL_S1F (4x4) #' # Note: not to be confused with HKL_S5F@substitution, which is non-degenerate #' degenerate5merSub <- makeDegenerate5merSub(sub1mer = HKL_S1F) #' #' # Look at a few 5-mers #' degenerate5merSub[, c("AAAAT", "AACAT", "AAGAT", "AATAT")] #' #' @export makeDegenerate5merSub <- function(sub1mer, extended=FALSE) { # make sure that rownames and colnames of sub1mer are uppercase rownames(sub1mer) <- toupper(rownames(sub1mer)) colnames(sub1mer) <- toupper(colnames(sub1mer)) # create 5-mer labels using ATGC nuc_chars <- NUCLEOTIDES[1:4] nuc_words <- seqinr::words(5, nuc_chars) # get center positions of 5mers nuc_centers <- sapply(nuc_words, function(x){seqinr::s2c(x)[3]}) # initiate 5-mer substitution matrix (4x1024) sub5mer <- matrix(NA, nrow=4, ncol=length(nuc_words), dimnames=list(nuc_chars, nuc_words)) # assign values from 1-mer model to 5-mer model for (from in rownames(sub1mer)) { for (to in colnames(sub1mer)) { if (from != to) { # if statement keeps diagonals as NA colIndex <- which(nuc_centers == from) sub5mer[to, colIndex] <- sub1mer[from, to] } } } stopifnot(dim(sub5mer) == c(4, 1024)) # if extended=TRUE, extend if (extended) { sub5mer <- extendSubstitutionMatrix(sub5mer) stopifnot(dim(sub5mer) == c(5, 3125)) } return(sub5mer) } #' Make a degenerate 5-mer mutability model based on a 1-mer mutability model #' #' \code{makeDegenerate5merMut} populates mutability rates from a 1-mer mutability model #' into 5-mers with corresponding central 1-mers. #' #' @param mut1mer a named vector of length 4 containing (normalized) #' mutability rates. Names should correspond to nucleotides, #' which should include "A", "T", "G", and "C" #' (case-insensitive). #' @param extended whether to return the unextended (\code{extended=FALSE}) or #' extended (\code{extended=TRUE}) 5-mer mutability model. #' Default is \code{FALSE}. #' #' @return For \code{extended=FALSE}, a vector of length 1024. The vector returned is #' normalized. For \code{extended=TRUE}, a vector of length 3125. #' #' @details As a concrete example, consider a 1-mer mutability model in which mutability #' rates of "A", "T", "G", and "C" are, respectively, 0.14, 0.23, 0.31, and 0.32. #' In the resultant degenerate 5-mer mutability model, all the 5-mers that have #' an "A" as their central 1-mer would have mutability rate of 0.14/256, where 256 is #' the number of such 5-mers. #' #' When \code{extended=TRUE}, \code{extendMutabilityMatrix} is called to extend the #' mutability vector of length 1024 into a vector of length 3125. #' #' @seealso See \link{makeAverage1merMut} for making a 1-mer mutability model by #' taking the average of a 5-mer mutability model. See #' \link{extendMutabilityMatrix} for extending the mutability vector. #' #' @examples #' # Make a degenerate 5-mer model (length of 1024) based on a 1-mer model #' example1merMut <- c(A=0.2, T=0.1, C=0.4, G=0.3) #' degenerate5merMut <- makeDegenerate5merMut(mut1mer = example1merMut) #' #' # Look at a few 5-mers #' degenerate5merMut[c("AAAAT", "AACAT", "AAGAT", "AATAT")] #' #' # Normalized #' sum(degenerate5merMut) #' #' @export makeDegenerate5merMut <- function(mut1mer, extended=FALSE) { # make sure that names of mut1mer are uppercase names(mut1mer) <- toupper(names(mut1mer)) # create 5-mer labels using ATGCN nuc_chars <- NUCLEOTIDES[1:4] nuc_words <- seqinr::words(5, nuc_chars) # get center positions of 5mers nuc_centers <- sapply(nuc_words, function(x){seqinr::s2c(x)[3]}) # initiate 5-mer mutability vector (length of 3125) mut5mer <- rep(NA, length=length(nuc_words)) names(mut5mer) <- nuc_words # assign values from 1-mer model to 5-mer model for (center in names(mut1mer)) { index <- which(nuc_centers == center) mut5mer[index] <- mut1mer[center] } stopifnot(length(mut5mer) == 1024) # normalize mut5mer <- mut5mer / sum(mut5mer, na.rm=T) # if extended=TRUE, extend if (extended) { mut5mer <- extendMutabilityMatrix(mut5mer) stopifnot(length(mut5mer) == 3125) } return(mut5mer) } #' Make a 1-mer substitution model by averaging over a 5-mer substitution model #' #' \code{makeAverage1merSub} averages substitution rates in a 5-mer substitution model #' to derive a 1-mer substitution model. #' #' @param sub5mer a 4x1024 matrix such as that returned by #' \code{createSubstitutionMatrix} and that returned by #' \code{makeDegenerate5merSub} with \code{extended=FALSE}. #' Column names should correspond to 5-mers containing the #' central 1-mer to mutate from. Row names should correspond to #' nucleotides to mutate into. Nucleotides should include #' "A", "T", "G", and "C" (case-insensitive). #' #' @return A 4x4 matrix with row names representing nucleotides to mutate from and column #' names representing nucleotides to mutate into. Rates are normalized by row. #' #' @details For example, the substitution rate from "A" to "T" in the resultant 1-mer model #' is derived by averaging the substitution rates into a "T" of all the 5-mers that #' have an "A" as their central 1-mer. #' #' @seealso See \link{makeDegenerate5merSub} for making a degenerate 5-mer substitution #' model based on a 1-mer substitution model. #' #' @examples #' # Make a degenerate 5-mer model (4x1024) based on HKL_S1F (4x4) #' degenerate5merSub <- makeDegenerate5merSub(sub1mer = HKL_S1F) #' #' # Now make a 1-mer model by averaging over the degenerate 5-mer model #' # Expected to get back HKL_S1F #' makeAverage1merSub(sub5mer = degenerate5merSub) #' #' @export makeAverage1merSub <- function(sub5mer) { stopifnot(dim(sub5mer) == c(4, 1024)) # make sure that rownames and colnames of sub5mer are uppercase rownames(sub5mer) <- toupper(rownames(sub5mer)) colnames(sub5mer) <- toupper(colnames(sub5mer)) # get 5-mers and center positions of 5-mers nuc_words <- colnames(sub5mer) nuc_centers <- sapply(nuc_words, function(x){seqinr::s2c(x)[3]}) # create 1-mer labels using ATGC nuc_chars <- NUCLEOTIDES[1:4] # initiate 1-mer substitution matrix (4x4) sub1mer <- matrix(NA, nrow=length(nuc_chars), ncol=length(nuc_chars), dimnames=list(nuc_chars, nuc_chars)) # assign values from 5-mer model to 1-mer model for (from in rownames(sub1mer)) { for (to in colnames(sub1mer)) { if (from != to) { # if statement keeps diagonals as NA colIndex <- which(nuc_centers == from) sub1mer[from, to] <- mean(sub5mer[to, colIndex], na.rm=T) } } } stopifnot(dim(sub1mer) == c(4, 4)) # normalize # tricky: apply transposes result; use t() to transpose back sub1mer <- t(apply(sub1mer, 1, function(x){x/sum(x, na.rm=T)})) return(sub1mer) } #' Make a 1-mer mutability model by averaging over a 5-mer mutability model #' #' \code{makeAverage1merMut} averages mutability rates in a 5-mer mutability model #' to derive a 1-mer mutability model. #' #' @param mut5mer a named vector of length 1024 such as that returned by #' \code{createMutabilityMatrix} and that returned by #' \code{makeDegenerate5merMut} with \code{extended=FALSE}. #' Names should correspond to 5-mers made up of "A", "T", #' "G", and "C" (case-insensitive). \code{NA} values are #' allowed. #' #' @return A named vector of length 4 containing normalized mutability rates. #' #' @details For example, the mutability rate of "A" in the resultant 1-mer model #' is derived by averaging the mutability rates of all the 5-mers that #' have an "A" as their central 1-mer, followed by normalization. #' #' @seealso See \link{makeDegenerate5merMut} for making a degenerate 5-mer mutability #' model based on a 1-mer mutability model. #' #' @examples #' # Make a degenerate 5-mer model (length of 1024) based on a 1-mer model #' example1merMut <- c(A=0.2, T=0.1, C=0.4, G=0.3) #' degenerate5merMut <- makeDegenerate5merMut(mut1mer = example1merMut) #' #' # Now make a 1-mer model by averaging over the degenerate 5-mer model #' # Expected to get back example1merMut #' makeAverage1merMut(mut5mer = degenerate5merMut) #' #' @export makeAverage1merMut <- function(mut5mer) { stopifnot(length(mut5mer) == 1024) # make sure that names mut5mer are uppercase names(mut5mer) <- toupper(names(mut5mer)) # get 5-mers and center positions of 5-mers nuc_words <- names(mut5mer) nuc_centers <- sapply(nuc_words, function(x){seqinr::s2c(x)[3]}) # create 1-mer labels using ATGC nuc_chars <- NUCLEOTIDES[1:4] # initiate 1-mer mutability vector (length 4) mut1mer <- rep(NA, length=length(nuc_chars)) names(mut1mer) <- nuc_chars # assign values from 5-mer model to 1-mer model for (center in names(mut1mer)) { index <- which(nuc_centers == center) mut1mer[center] <- mean(mut5mer[index], na.rm=T) } stopifnot(length(mut1mer) == 4) # normalize mut1mer <- mut1mer / sum(mut1mer, na.rm=T) return(mut1mer) } #### Distance Functions #### #' Calculates a 5-mer distance matrix from a TargetingModel object #' #' \code{calcTargetingDistance} converts either the targeting rates in a \code{TargetingModel} #' model to a matrix of 5-mer to single-nucleotide mutation distances, or the substitution #' rates in a 1-mer substitution model to a symmetric distance matrix. #' #' @param model \link{TargetingModel} object with mutation likelihood information, or #' a 4x4 1-mer substitution matrix normalized by row with rownames and #' colnames consisting of "A", "T", "G", and "C". #' @param places decimal places to round distances to. #' #' @return For input of \link{TargetingModel}, a matrix of distances for each 5-mer motif with #' rows names defining the center nucleotide and column names defining the 5-mer #' nucleotide sequence. For input of 1-mer substitution matrix, a 4x4 symmetric distance #' matrix. #' #' @details #' The targeting model is transformed into a distance matrix by: #' \enumerate{ #' \item Converting the likelihood of being mutated \eqn{p=mutability*substitution} to #' distance \eqn{d=-log10(p)}. #' \item Dividing this distance by the mean of the distances. #' \item Converting all infinite, no change (e.g., A->A), and NA distances to #' zero. #' } #' #' The 1-mer substitution matrix is transformed into a distance matrix by: #' \enumerate{ #' \item Symmetrize the 1-mer substitution matrix. #' \item Converting the rates to distance \eqn{d=-log10(p)}. #' \item Dividing this distance by the mean of the distances. #' \item Converting all infinite, no change (e.g., A -> A), and NA distances to #' zero. #' } #' #' @seealso See \link{TargetingModel} for this class of objects and #' \link{createTargetingModel} for building one. #' #' @examples #' # Calculate targeting distance of HH_S5F #' dist <- calcTargetingDistance(HH_S5F) #' #' # Calculate targeting distance of HH_S1F #' dist <- calcTargetingDistance(HH_S1F) #' #' @export calcTargetingDistance <- function(model, places=2) { # if model is TargetingModel object, assume 5-mer targeting model # extract targeting matrix if (is(model, "TargetingModel")) { input <- "5mer" model <- model@targeting } else if (is(model, "matrix") & all(dim(model) == c(4, 4))) { # if model is a matrix, assume 1-mer substitution matrix and symmetrize input <- "1mer" model <- symmetrize(model) } else { # anything else: error stop("Input must be either a 4x4 targeting matrix or TargetingModel object.") } # Take negative log10 of all probabilities model_dist <- -log10(model) # Center distances on 1 (divide by mean) model_dist <- model_dist/mean(model_dist, na.rm=T) # Set infinite values to NA model_dist[!is.finite(model_dist)] <- NA # TODO: the indexing of A-->A etc positions can probably be done smarter/faster # Assign no-change entries to distance 0 if (input == "5mer") { center_nuc <- gsub("..([ACGTN])..", "\\1", colnames(model_dist)) for (i in 1:length(center_nuc)) { model_dist[center_nuc[i], i] <- 0 } # Assign 0 to N and 5mers with N in center position model_dist[,center_nuc=="N"] <- 0 model_dist["N",] <- 0 } else if (input == "1mer") { diag(model_dist) <- 0 model_dist <- rbind(model_dist, matrix(0, 3, 4)) model_dist <- cbind(model_dist, matrix(0, 7, 3)) colnames(model_dist)[5:7] <- rownames(model_dist)[5:7] <- c("N", "-", ".") } # Round model_dist <- round(model_dist, places) return(model_dist) } # (From G Yaari) # Symmetrize a non-symmetric, 1-mer substitution matrix # # \code{symmetrize} makes a 1-mer substitution matrix symmetric by minimizing the # rss between it and a symmetric matrix. # # @param sub1mer a 4x4 matrix normalized by row. Each row sums up to 1 and # reflects substitution probabilities for each nucleotide. # Rownames and colnames are "A","C","G", and "T". # # @return a 4x4 symmetrix matrix with \code{NA}s on the diagonal. # # @details The input 1-mer substitution matrix is approximated by a symmetric matrix # both with respect to time (e.g. C->T = T->C), and with respect to strand # (e.g. C->T = G->A). The symmetric matrix has three free parameters that # are estimated by minimizing the sum of squares between this matrix and # the input matrix. The fitted matrix was normalized to ensure that each # row sums up to 1. symmetrize <- function(sub1mer) { rownames(sub1mer) <- toupper(rownames(sub1mer)) colnames(sub1mer) <- toupper(colnames(sub1mer)) # check that rows sum up to 1 stopifnot(all.equal(rowSums(sub1mer), rep(1, 4), check.names=FALSE, tolerance=0.055)) .minDist <- function(Pars, subMtx) { (Pars[1] - subMtx["A", "C"])^2 + (Pars[1] - subMtx["C", "A"])^2 + (Pars[1] - subMtx["G", "T"])^2 + (Pars[1] - subMtx["T", "G"])^2 + (Pars[2] - subMtx["A", "G"])^2 + (Pars[2] - subMtx["G", "A"])^2 + (Pars[2] - subMtx["C", "T"])^2 + (Pars[2] - subMtx["T", "C"])^2 + (Pars[3] - subMtx["A", "T"])^2 + (Pars[3] - subMtx["T", "A"])^2 + (Pars[3] - subMtx["C", "G"])^2 + (Pars[3] - subMtx["G", "C"])^2 } pars <- optim(par=rep(0, 3), fn=.minDist, subMtx=sub1mer)$par pars <- pars/sum(pars) symmetric_substitution <- sub1mer symmetric_substitution["A", 2:4] <- pars symmetric_substitution["C", c(1, 4, 3)] <- pars symmetric_substitution["G", c(4, 1, 2)] <- pars symmetric_substitution["T", c(3, 2, 1)] <- pars # NAs on diagonal instead of 0 so that calcTargetingDistance works with 1-mer model diag(symmetric_substitution) <- NA return(symmetric_substitution) } #' Write targeting model distances to a file #' #' \code{writeTargetingDistance} writes a 5-mer targeting distance matrix #' to a tab-delimited file. #' #' @param model \link{TargetingModel} object with #' mutation likelihood information. #' @param file name of file to write. #' #' @return NULL #' #' @details #' The targeting distance write as a tab-delimited 5x3125 matrix. Rows define the mutated #' nucleotide at the center of each 5-mer, one of \code{c("A", "C", "G", "T", "N")}, #' and columns define the complete 5-mer of the unmutated nucleotide sequence. #' \code{NA} values in the distance matrix are replaced with distance 0. #' #' @seealso Takes as input a \link{TargetingModel} object and calculates #' distances using \link{calcTargetingDistance}. #' #' @examples #' \dontrun{ #' # Write HS5F targeting model to working directory as hs5f.tab #' writeTargetingDistance(HH_S5F, "hh_s5f.tsv") #' } #' #' @export writeTargetingDistance <- function(model, file) { to_write <- as.data.frame(calcTargetingDistance(model)) to_write[is.na(to_write)] <- 0 write.table(to_write, file, quote=FALSE, sep="\t", col.names=NA, row.names=TRUE) } #### Plotting functions #### #' Plot mutability probabilities #' #' \code{plotMutability} plots the mutability rates of a \code{TargetingModel}. #' #' @param model \link{TargetingModel} object or vector containing normalized #' mutability rates. #' @param nucleotides vector of center nucleotide characters to plot. #' @param mark vector of 5-mer motifs to highlight in the plot. If \code{NULL} #' only highlight classical hot and cold spot motifs. #' @param style type of plot to draw. One of: #' \itemize{ #' \item \code{"hedgehog"}: circular plot showing higher mutability #' scores further from the circle. The 5-mer #' is denoted by the values of the inner #' circle. The 5-mer is read from the most interior #' position of the 5-mer (5') to most exterior position #' (3'), with the center nucleotide in the center ring. #' Note, the order in which the 5-mers are plotted is #' different for nucleotides \code{c("A", "C")} and #' \code{c("G", "T")}. #' \item \code{"bar"}: bar plot of mutability similar to the #' \code{hedgehog} style with the most 5' positions #' of each 5-mer at the base of the plot. #' } #' @param size numeric scaling factor for lines and text in the plot. #' @param silent if \code{TRUE} do not draw the plot and just return the ggplot2 #' objects; if \code{FALSE} draw the plot. #' @param ... additional arguments to pass to ggplot2::theme. #' #' @return A named list of ggplot objects defining the plots, with names defined by the #' center nucleotide for the plot object. #' #' @seealso Takes as input a \link{TargetingModel} object. #' See \link{createTargetingModel} for model building. #' #' #' @examples #' # Plot one nucleotide in circular style #' plotMutability(HH_S5F, "C") #' #' # Plot two nucleotides in barchart style #' plotMutability(HH_S5F, c("G", "T"), style="bar") #' #' @export plotMutability <- function(model, nucleotides=c("A", "C", "G", "T"), mark=NULL, style=c("hedgehog", "bar"), size=1, silent=FALSE, ...) { # model=HH_S5F # nucleotides=c("C") # nucleotides=c("A", "C", "G", "T") # style="hedgehog" # size=1 # silent=FALSE # Check input nucleotides <- toupper(nucleotides) style <- match.arg(style) if (is(model, "TargetingModel")) { model <- model@mutability } else if (!is(model, "vector")) { stop("Input must be either a mutability vector or TargetingModel object.") } # Set base plot settings base_theme <- theme_bw() + theme(panel.spacing=grid::unit(0, "lines"), panel.background=element_blank()) + theme(axis.text=element_text(margin=grid::unit(0, "lines"))) + theme(text=element_text(size=10*size), title=element_text(size=10*size), legend.spacing=grid::unit(0, "lines"), legend.background=element_blank()) # Scaling and layout parameters score_offset <- 0 score_scale <- 15 text_offset <- -5.6 # Set guide colors motif_colors <- setNames(c("#000000", "#4daf4a", "#e41a1c", "#094d85", "#999999"), c("Marked", "WA/TW", "WRC/GYW", "SYC/GRS", "Neutral")) dna_colors <- setNames(c("#7bce77", "#ff9b39", "#f04949", "#5796ca", "#c4c4c4"), c("A", "C", "G", "T", "N")) # Build data.frame of mutability scores mut_scores <- model[!grepl("N", names(model))] mut_scores[!is.finite(mut_scores)] <- 0 mut_words <- names(mut_scores) mut_positions <- as.data.frame(t(sapply(mut_words, seqinr::s2c))) colnames(mut_positions) <- paste0("pos", 1:ncol(mut_positions)) mut_df <- data.frame(word=mut_words, score=mut_scores, mut_positions) # Add hot and cold-spot motif information mut_df$motif <- "Neutral" mut_df$motif[grepl("(.[AT]A..)|(..T[AT].)", mut_df$word, perl=TRUE)] <- "WA/TW" mut_df$motif[grepl("([AT][GA]C..)|(..G[CT][AT])", mut_df$word, perl=TRUE)] <- "WRC/GYW" mut_df$motif[grepl("([CG][CT]C..)|(..G[GA][CG])", mut_df$word, perl=TRUE)] <- "SYC/GRS" if (is.null(mark)) { mut_df$motif <- factor(mut_df$motif, levels=c("WA/TW", "WRC/GYW", "SYC/GRS", "Neutral")) } else { mut_df$motif[mut_df$word %in% mark] <- "Marked" mut_df$motif <- factor(mut_df$motif, levels=c("Marked", "WA/TW", "WRC/GYW", "SYC/GRS", "Neutral")) } # Subset to nucleotides of interest mut_df <- mut_df[mut_df$pos3 %in% nucleotides, ] # Functions to transform and revert score for plotting score_max <- max(mut_df$score, na.rm=TRUE) .transform_score <- function(x) { x / score_max * score_scale + score_offset } .invert_score <- function(x) { (x - score_offset) / score_scale * score_max } # Rescale scores for plotting mut_df$score <- .transform_score(mut_df$score) # Build plots for each center nucleotide plot_list <- list() for (center_nuc in nucleotides) { # center_nuc <- "C" # Subset data to center nucleotide sub_df <- mut_df[mut_df$pos3 == center_nuc, ] # Order 5-mers by positions, with reversed order if center nucleotide is G or T if (center_nuc %in% c("A", "C")) { sub_df <- dplyr::arrange(sub_df, !!!rlang::syms(c("pos1", "pos2", "pos4", "pos5"))) sub_df$x <- 1:nrow(sub_df) } else if (center_nuc %in% c("G", "T")) { sub_df <- dplyr::arrange(sub_df, !!!rlang::syms(c("pos5", "pos4", "pos2", "pos1"))) sub_df$x <- 1:nrow(sub_df) } else { stop("Invalid nucleotide choice") } # Melt 5-mer position data sub_melt <- sub_df %>% tidyr::gather("pos", "char", !!!rlang::syms(colnames(mut_positions))) %>% select("x", "pos", "char") #sub_melt$pos <- factor(sub_melt$pos, levels=mut_names) #sub_melt$pos <- as.numeric(sub_melt$pos) sub_melt$pos <- as.numeric(gsub("pos", "", sub_melt$pos)) # Define nucleotide text and rectangle position data sub_text <- list() for (i in 1:5) { nuc_rle <- rle(sub_melt$char[sub_melt$pos == i]) # Set rectangle x limits rect_max <- cumsum(nuc_rle$lengths) rect_min <- rect_max - diff(c(0, rect_max)) # Set text position if (length(rect_max) > 1) { text_x <- rect_max - diff(c(0, rect_max)) / 2 } else { text_x <- rect_max / 2 } tmp_df <- data.frame(text_x=text_x, text_y=i, text_label=factor(nuc_rle$values, levels=names(dna_colors)), rect_min=rect_min, rect_max=rect_max) sub_text[[i]] <- tmp_df } # Define text and rectangle positions for inner circle sub_melt$pos <- sub_melt$pos + text_offset sub_text <- lapply(sub_text, function(x) { dplyr::mutate(x, text_y=!!rlang::sym("text_y") + !!rlang::sym("text_offset")) }) sub_rect <- dplyr::bind_rows(sub_text) %>% mutate(rect_width=rect_max - rect_min, ymin=!!rlang::sym("text_y") - 0.5, ymax=!!rlang::sym("text_y") + 0.5) # Define base plot object p1 <- ggplot(sub_df) + base_theme + #ggtitle(paste0("NN", center_nuc, "NN")) + xlab("") + ylab("") + scale_color_manual(name="Motif", values=c(motif_colors, dna_colors), breaks=names(motif_colors)) + scale_fill_manual(name="", values=c(motif_colors, dna_colors), guide=FALSE) + geom_rect(data=sub_rect, mapping=aes_string(xmin="rect_min", xmax="rect_max", ymin="ymin", ymax="ymax", fill="text_label", color="text_label"), size=0.5*size, alpha=1, show.legend=FALSE) + #geom_tile(data=sub_rect, # mapping=aes_string(x="text_x", y="text_y", width="rect_width", fill="text_label"), # size=0, alpha=0.7, show.legend=FALSE) + #geom_tile(data=sub_melt, mapping=aes_string(x="x", y="pos", fill="char"), size=0, alpha=0.7, # show.legend=FALSE) + geom_text(data=sub_text[[3]], mapping=aes_string(x="text_x", y="text_y", label="text_label"), color="black", hjust=0.5, vjust=0.5, size=3*size, fontface=2) # Add 5-mer nucleotide labels if (center_nuc %in% c("A", "C")) { p1 <- p1 + geom_text(data=sub_text[[1]], mapping=aes_string(x="text_x", y="text_y", label="text_label"), color="black", hjust=0.5, vjust=0.5, size=2*size) + geom_text(data=sub_text[[2]], mapping=aes_string(x="text_x", y="text_y", label="text_label"), color="black", hjust=0.5, vjust=0.5, size=2*size) } else if (center_nuc %in% c("G", "T")) { p1 <- p1 + geom_text(data=sub_text[[4]], mapping=aes_string(x="text_x", y="text_y", label="text_label"), color="black", hjust=0.5, vjust=0.5, size=2*size) + geom_text(data=sub_text[[5]], mapping=aes_string(x="text_x", y="text_y", label="text_label"), color="black", hjust=0.5, vjust=0.5, size=2*size) } # Add style options and mutability scores if (style == "hedgehog") { y_limits <- c(text_offset - 1, score_scale + score_offset) #orient_x <- sub_text[[3]]$text_x[1] #orient_y <- text_offset - 1 p1 <- p1 + theme(plot.margin=grid::unit(c(0, 0, 0, 0), "lines"), panel.grid=element_blank(), panel.border=element_blank(), axis.title=element_blank(), axis.text=element_blank(), axis.ticks=element_blank(), legend.direction="horizontal", legend.justification=c(0.5, 1), legend.position=c(0.5, 1)) + guides(color=guide_legend(override.aes=list(linetype=1, size=2*size))) + scale_x_continuous(expand=c(0, 0)) + scale_y_continuous(limits=y_limits, expand=c(0, 0)) + coord_polar(theta="x") + geom_segment(data=sub_df, mapping=aes_string(x="x", xend="x", yend="score", color="motif"), y=score_offset, size=0.75*size) } else if (style == "bar") { y_breaks <- seq(score_offset, score_scale + score_offset, 1) y_limits <- c(text_offset + 0.5, score_scale + score_offset) sub_colors <- motif_colors[names(motif_colors) %in% sub_df$motif] p1 <- p1 + theme(plot.margin=grid::unit(c(1, 1, 1, 1), "lines"), panel.grid=element_blank(), panel.border=element_rect(color="black"), axis.text.x=element_blank(), axis.ticks.x=element_blank(), legend.position="top") + guides(color=guide_legend(override.aes=list(fill=sub_colors, linetype=0))) + ylab("Mutability") + scale_x_continuous(expand=c(0, 1)) + scale_y_continuous(limits=y_limits, breaks=y_breaks, expand=c(0, 0.5), labels=function(x) scales::scientific(.invert_score(x))) + geom_bar(data=sub_df, mapping=aes_string(x="x", y="score", fill="motif", color="motif"), stat="identity", position="identity", size=0, width=0.7) } # Add additional theme elements p1 <- p1 + do.call(theme, list(...)) # Add plot to list plot_list[[center_nuc]] <- p1 } # Plot if (!silent) { do.call(gridPlot, args=c(plot_list, ncol=length(plot_list))) } invisible(plot_list) } #' Visualize parameter tuning for minNumMutations and minNumSeqMutations #' #' Visualize results from \link{minNumMutationsTune} and \link{minNumSeqMutationsTune} #' #' @param tuneMtx a \code{matrix} or a \code{list} of matrices produced by either #' \link{minNumMutationsTune} or \link{minNumSeqMutationsTune}. #' In the case of a list, it is assumed that each matrix corresponds #' to a sample and that all matrices in the list were produced using #' the same set of trial values of \code{minNumMutations} or #' \code{minNumSeqMutations}. #' @param thresh a number or a vector of indicating the value or the range of values #' of \code{minNumMutations} or \code{minNumSeqMutations} to plot. #' Should correspond to the columns of \code{tuneMtx}. #' @param criterion one of \code{"5mer"}, \code{"3mer"}, \code{"1mer"}, or \code{"3mer+1mer"} #' (for \code{tuneMtx} produced by \link{minNumMutationsTune}), or either #' \code{"measured"} or \code{"inferred"} (for \code{tuneMtx} produced by #' \link{minNumSeqMutationsTune}). #' @param pchs point types to pass on to \link{plot}. #' @param ltys line types to pass on to \link{plot}. #' @param cols colors to pass on to \link{plot}. #' @param plotLegend whether to plot legend. Default is \code{TRUE}. Only applicable #' if \code{tuneMtx} is a named list with names of the matrices #' corresponding to the names of the samples. #' @param legendPos position of legend to pass on to \link{legend}. Can be either a #' numeric vector specifying x-y coordinates, or one of #' \code{"topright"}, \code{"center"}, etc. Default is \code{"topright"}. #' @param legendHoriz whether to make legend horizontal. Default is \code{FALSE}. #' @param legendCex numeric values by which legend should be magnified relative to 1. #' #' @details For \code{tuneMtx} produced by \link{minNumMutationsTune}, for each sample, depending on #' \code{criterion}, the numbers of 5-mers for which substitution rates are directly computed #' (\code{"5mer"}), inferred based on inner 3-mers (\code{"3mer"}), inferred based on #' central 1-mers (\code{"1mer"}), or inferred based on inner 3-mers and central 1-mers #' (\code{"3mer+1mer"}) are plotted on the y-axis against values of \code{minNumMutations} #' on the x-axis. #' #' For \code{tuneMtx} produced by \link{minNumSeqMutationsTune}, for each sample, depending on #' \code{criterion}, the numbers of 5-mers for which mutability rates are directly measured #' (\code{"measured"}) or inferred (\code{"inferred"}) are plotted on the y-axis against values #' of \code{minNumSeqMutations} on the x-axis. #' #' Note that legends will be plotted only if \code{tuneMtx} is a supplied as a named \code{list} #' of matrices, ideally with names of each \code{matrix} corresponding to those of the samples #' based on which the matrices were produced, even if \code{plotLegend=TRUE}. #' #' @seealso See \link{minNumMutationsTune} and \link{minNumSeqMutationsTune} for generating #' \code{tuneMtx}. #' #' @examples #' \donttest{ #' # Subset example data to one isotype and sample as demos #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE == "IgA") #' #' tuneMtx = list() #' for (i in 1:length(unique(db$SAMPLE))) { #' # Get data corresponding to current sample #' curDb = db[db$SAMPLE==unique(db$SAMPLE)[i], ] #' #' # Count the number of mutations per 5-mer #' subCount = createSubstitutionMatrix(db=curDb, model="S", multipleMutation="independent", #' returnModel="5mer", numMutationsOnly=TRUE) #' #' # Tune over minNumMutations = 5..50 #' subTune = minNumMutationsTune(subCount, seq(from=5, to=50, by=5)) #' #' tuneMtx = c(tuneMtx, list(subTune)) #' } #' #' # Name tuneMtx after sample names #' names(tuneMtx) = unique(db$SAMPLE) #' #' # plot with legend for both samples for a subset of minNumMutations values #' plotTune(tuneMtx, thresh=c(5, 15, 25, 40), criterion="3mer", #' pchs=16:17, ltys=1:2, cols=2:3, #' plotLegend=TRUE, legendPos=c(5, 100)) #' #' # plot for only 1 sample for all the minNumMutations values (no legend) #' plotTune(tuneMtx[[1]], thresh=seq(from=5, to=50, by=5), criterion="3mer") #' } #' #' @export plotTune <- function(tuneMtx, thresh, criterion=c("5mer", "3mer", "1mer", "3mer+1mer", "measured", "inferred"), pchs = 1, ltys = 2, cols = 1, plotLegend = TRUE, legendPos = "topright", legendHoriz = FALSE, legendCex = 1) { stopifnot(length(criterion)==1) stopifnot(is.matrix(tuneMtx) | is.list(tuneMtx)) ### extract plot data into plotMtx # if tuneMtx is just a matrix if (!is.list(tuneMtx)) { if (criterion!="3mer+1mer") { plotMtx <- matrix(tuneMtx[criterion, as.character(thresh)], nrow=1) } else { plotMtx <- matrix(colSums(tuneMtx[c("3mer", "1mer"), as.character(thresh)]), nrow=1) } } else { # if tuneMtx is a named list of matrices (e.g. corresponding to multiple samples) if (criterion!="3mer+1mer") { plotMtx <- do.call(base::rbind, lapply(tuneMtx, function(mtx){mtx[criterion, as.character(thresh)]})) } else { plotMtx <- do.call(base::rbind, lapply(tuneMtx, function(mtx){colSums(mtx[c("3mer", "1mer"), as.character(thresh)])})) } rownames(plotMtx) <- names(tuneMtx) } # sanity check: there should not be any NA stopifnot(!any(is.na(plotMtx))) ### if number of pchs/ltys/cols provided does not match number of samples expected # expand into vector with repeating values (otherwise legend would break) if (length(pchs)!=nrow(plotMtx)) {pchs <- rep(pchs, length.out=nrow(plotMtx))} if (length(ltys)!=nrow(plotMtx)) {ltys <- rep(ltys, length.out=nrow(plotMtx))} if (length(cols)!=nrow(plotMtx)) {cols <- rep(cols, length.out=nrow(plotMtx))} ### axis labels if (criterion %in% c("5mer", "3mer", "1mer", "3mer+1mer")) { xlab.name <- "Minimum # mutations per 5-mer to\ndirectly compute 5-mer substitution rates" # cannot use switch because variable names cannot start with number ylab.name <- "# 5-mers for which substitution rates are\n" if (criterion=="5mer") { ylab.name <- paste(ylab.name, "directly computed") } else if (criterion=="3mer") { ylab.name <- paste(ylab.name, "inferred based on inner 3-mers") } else if (criterion=="1mer") { ylab.name <- paste(ylab.name, "inferred based on central 1-mers") } else if (criterion=="3mer+1mer") { ylab.name <- paste(ylab.name, "inferred based on 3- and 1-mers") } } else if (criterion %in% c("measured", "inferred")) { xlab.name <- "Minimum # mutations in sequences containing each 5-mer\nto directly compute mutability" ylab.name <- paste("# 5-mers for which mutability is", criterion) } ### plot # bottom, left, top, right par(mar=c(6, 6, 4, 2) + 0.1) for (i in 1:nrow(plotMtx)) { if (i==1) { plot(x=thresh, y=plotMtx[i, ], ylim=range(plotMtx), xaxt="n", xlab="", ylab="", cex.axis=1.5, type="b", lwd=1.5, pch=pchs[i], lty=ltys[i], col=cols[i]) axis(side=1, at=thresh, cex.axis=1.5) mtext(side=1, text=xlab.name, line=4, cex=1.2) mtext(side=2, text=ylab.name, line=3, cex=1.2) } else { points(x=thresh, y=plotMtx[i, ], type="b", lwd=1.5, pch=pchs[i], lty=ltys[i], col=cols[i]) } } ### legend (even if plotLegend=T, only plotted if tuneMtx is a named list) if ( !is.null(rownames(plotMtx)) & plotLegend ) { # if legendPos specified as xy coordinates if (is.numeric(legendPos) & length(legendPos)==2) { legend(x=legendPos[1], y=legendPos[2], legend = c("Sample", rownames(plotMtx)), horiz = legendHoriz, cex = legendCex, pch=c(NA, pchs), lty=c(NA, ltys), col=c(NA, cols)) } else { # if legendPos specified as "center", "topright", etc. legend(legendPos, legend = c("Sample", rownames(plotMtx)), horiz = legendHoriz, cex = legendCex, pch=c(NA, pchs), lty=c(NA, ltys), col=c(NA, cols)) } } } #### Original BASELINe functions #### # Given a nuc, returns the other 3 nucs it can mutate to canMutateTo <- function(nuc) { NUCLEOTIDES[1:4][NUCLEOTIDES[1:4] != nuc] } # Compute the mutations types # matOfCodons: nx2; n=pairs of codons; 1st col=codonTo, 2nd col=codonFrom # NOTE: this function is not intended to be used where input sequences have # ambiguous characters; it assumes that only 1 entry (R/S/Stop/na) from # mutationType is non-zero/1 mutationTypeOptimized <- function(matOfCodons) { # mutType: 4xn; rows: R/S/Stop/na mutType <- apply(matOfCodons, 1, function(x) { mutationType(x[2], x[1]) }) idx <- apply(mutType, 2, function(y){which(y>0)[1]}) mutType <- rownames(mutType)[idx] mutType[which(mutType=="na")] <- NA return(mutType) } # row 1 = GL # row 2 = Seq # in_matrix <- matrix(c(c("A","A","A","C","C","C"), c("A","G","G","C","C","A")), 2 ,6, byrow=T) # analyzeMutations2NucUri(in_matrix) analyzeMutations2NucUri <- function(in_matrix) { if(ncol(in_matrix) > VLENGTH) { paramGL <- in_matrix[2,1:VLENGTH] paramSeq <- in_matrix[1,1:VLENGTH] } else { paramGL <- in_matrix[2,] paramSeq <- in_matrix[1,] } #mutations = apply(rbind(paramGL,paramSeq), 2, function(x){!x[1]==x[2]}) mutations_val <- paramGL != paramSeq if (any(mutations_val)) { mutationPos <- {1:length(mutations_val)}[mutations_val] #mutationPos = mutationPos[sapply(mutationPos, function(x){!any(paramSeq[getCodonPos(x)]=="N")})] length_mutations =length(mutationPos) mutationInfo <- rep(NA,length_mutations) if (any(mutationPos)) { pos<- mutationPos pos <- pos[!is.na(pos)] pos_array <- array(sapply(pos,getCodonPos)) codonGL <- paramGL[pos_array] codonGL[is.na(codonGL)] <- "N" codonSeq <- sapply(pos,function(x){ seqP <- paramGL[getCodonPos(x)] muCodonPos <- {x-1}%%3+1 seqP[muCodonPos] <- paramSeq[x] return(seqP) }) codonSeq[is.na(codonSeq)] <- "N" GLcodons <- apply(matrix(codonGL,length_mutations,3,byrow=TRUE),1,c2s) Seqcodons <- apply(codonSeq,2,c2s) mutationInfo <- apply(rbind(GLcodons , Seqcodons),2,function(x){ # not intended to be used where input sequences have # ambiguous characters; it assumes that only 1 entry (R/S/Stop/na) from # mutationType is non-zero/1 mutType <- mutationType(c2s(x[1]),c2s(x[2])) mutType <- names(mutType)[which(mutType>0)] if (mutType=="na") {mutType=NA} return(mutType) }) names(mutationInfo) <- mutationPos } if (any(!is.na(mutationInfo))) { return(mutationInfo[!is.na(mutationInfo)]) } else { return(NA) } } else { return (NA) } } # List mutations listMutations <- function(seqInput, seqGL, multipleMutation, model) { #if( is.na(c(seqInput, seqGL)) ) return(array(NA,4)) if (is.na(seqInput) | is.na(seqGL)) { return(NA) } seqI <- s2c(seqInput) seqG <- s2c(seqGL) matIGL <- matrix(c(seqI, seqG), ncol=length(seqI), nrow=2, byrow=T) mutations <- analyzeMutations2NucUri(matIGL) mutations <- mutations[!is.na(mutations)] #positions <- as.numeric(names(mutations)) # mutations <- mutations[positions <= VLENGTH] #remove the nucleotide mutations in the codons with multiple mutations if (multipleMutation == "ignore") { mutationCodons <- getCodonNumb(as.numeric(names(mutations))) tableMutationCodons <- table(mutationCodons) codonsWithMultipleMutations <- as.numeric(names(tableMutationCodons[tableMutationCodons>1])) mutations <- mutations[!(mutationCodons %in% codonsWithMultipleMutations)] } if (model == "S") { mutations <- mutations[mutations == "S"] } if (length(mutations) > 0) { return(mutations) } else { return(NA) } } # List the numbers of observed mutations # # This lists the observed number of mutation. # # @param db a data.frame of the DB file. # @param sequenceColumn The name of the sequence column. # @param germlineColumn The name of the germline column. # # @return list of mutations in each clone listObservedMutations <- function(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", multipleMutation=c("independent", "ignore"), model = c("RS", "S")) { # Make sure the columns specified exist if (!(sequenceColumn %in% names(db))) { stop("The sequence column", sequenceColumn, "was not found.") } if (!(germlineColumn %in% names(db))) { stop("The germline column", germlineColumn, "was not found.") } mutations <- mapply(listMutations, db[[sequenceColumn]], db[[germlineColumn]], multipleMutation, model, USE.NAMES=FALSE) return(mutations) } #### Testing functions #### # Function to make dummy data for testing targetting functions # # @param nseq number of sequences # @param nmut number of mutations per sequence # @param nmer number of 5-mers per sequence (sequence length = 5 * nmer) # # @return a data.frame with columns SEQUENCE_ID, SEQUENCE_IMGT, GERMLINE_IMGT_D_MASK, V_CALL. # # @examples # db <- makeTargetingTestDb(500) makeTargetingTestDb <- function(nseq=10, nmut=40, nmers=50) { nuc_chars <- c("A", "C", "G", "T") .mut <- function(x, n) { i <- sample(1:nchar(x), n) y <- seqinr::s2c(x) y[i] <- sapply(y[i], function(z) sample(nuc_chars[nuc_chars != z], 1)) return(seqinr::c2s(y)) } seq <- apply(replicate(nseq, sample(seqinr::words(5, nuc_chars), nmers)), 2, paste, collapse="") germ <- sapply(seq, .mut, n=nmut) db <- data.frame(SEQUENCE_ID=paste0("SEQ", 1:nseq), SEQUENCE_IMGT=seq, GERMLINE_IMGT_D_MASK=germ, V_CALL="Homsap IGHV3-66*02 F", stringsAsFactors=FALSE) rownames(db) <- NULL return(db) } shazam/R/MutationProfiling.R0000644000176200001440000051100013575255254015545 0ustar liggesusers# Mutation profiling #' @include Shazam.R NULL #### Clonal consensus building functions #### #' Constructs effective clonal sequences for all clones #' #' \code{collapseClones} creates effective input and germline sequences for each clonal #' group and appends columns containing the consensus sequences to the input #' \code{data.frame}. #' #' @param db \code{data.frame} containing sequence data. Required. #' @param cloneColumn \code{character} name of the column containing clonal #' identifiers. Required. #' @param sequenceColumn \code{character} name of the column containing input #' sequences. Required. The length of each input sequence should #' match that of its corresponding germline sequence. #' @param germlineColumn \code{character} name of the column containing germline #' sequences. Required. The length of each germline sequence #' should match that of its corresponding input sequence. #' @param muFreqColumn \code{character} name of the column containing mutation #' frequency. Optional. Applicable to the \code{"mostMutated"} #' and \code{"leastMutated"} methods. If not supplied, mutation #' frequency is computed by calling \code{observedMutations}. #' Default is \code{NULL}. See Cautions for note on usage. #' @param regionDefinition \link{RegionDefinition} object defining the regions #' and boundaries of the Ig sequences. Optional. Default is #' \code{NULL}. #' @param method method for calculating input consensus sequence. Required. #' One of \code{"thresholdedFreq"}, \code{"mostCommon"}, #' \code{"catchAll"}, \code{"mostMutated"}, or #' \code{"leastMutated"}. See "Methods" for details. #' @param minimumFrequency frequency threshold for calculating input consensus sequence. #' Applicable to and required for the \code{"thresholdedFreq"} #' method. A canonical choice is 0.6. Default is \code{NULL}. #' @param includeAmbiguous whether to use ambiguous characters to represent positions #' at which there are multiple characters with frequencies that #' are at least \code{minimumFrequency} or that are maximal #' (i.e. ties). Applicable to and required for the #' \code{"thresholdedFreq"} and \code{"mostCommon"} methods. #' Default is \code{FALSE}. See "Choosing ambiguous characters" #' for rules on choosing ambiguous characters. #' @param breakTiesStochastic In case of ties, whether to randomly pick a sequence from #' sequences that fulfill the criteria as consensus. Applicable #' to and required for all methods except for \code{"catchAll"}. #' Default is \code{FALSE}. See "Methods" for details. #' @param breakTiesByColumns A list of the form #' \code{list(c(col_1, col_2, ...), c(fun_1, fun_2, ...))}, #' where \code{col_i} is a \code{character} name of a column #' in \code{db}, and \code{fun_i} is a function to be applied #' on that column. Currently, only \code{max} and \code{min} #' are supported. Note that the two \code{c()}'s in \code{list()} #' are essential (i.e. if there is only 1 column, the list should #' be of the form \code{list(c(col_1), c(func_1))}. Applicable #' to and optional for the \code{"mostMutated"} and #' \code{"leastMutated"} methods. If supplied, \code{fun_i}'s #' are applied on \code{col_i}'s to help break ties. Default #' is \code{NULL}. See "Methods" for details. #' @param expandedDb \code{logical} indicating whether or not to return the #' expanded \code{db}, containing all the sequences (as opposed #' to returning just one sequence per clone). #' @param nproc Number of cores to distribute the operation over. If the #' \code{cluster} has already been set earlier, then pass the #' \code{cluster}. This will ensure that it is not reset. #' #' #' @return A modified \code{db} with the following additional columns: #' \itemize{ #' \item \code{CLONAL_SEQUENCE}: effective sequence for the clone. #' \item \code{CLONAL_GERMLINE}: germline sequence for the clone. #' \item \code{CLONAL_SEQUENCE_MUFREQ}: mutation frequency of #' \code{CLONAL_SEQUENCE}; only added for the \code{"mostMutated"} #' and \code{"leastMutated"} methods. #' } #' #' \code{CLONAL_SEQUENCE} is generated with the method of choice indicated #' by \code{method}, and \code{CLONAL_GERMLINE} is generated with the #' \code{"mostCommon"} method, along with, where applicable, user-defined #' parameters such as \code{minimumFrequency}, \code{includeAmbiguous}, #' \code{breakTiesStochastic}, and \code{breakTiesByColumns}. #' #' #' @section Consensus lengths: For each clone, \code{CLONAL_SEQUENCE} and #' \code{CLONAL_GERMLINE} have the same length. #' #' \itemize{ #' \item For the \code{"thresholdedFreq"}, \code{"mostCommon"}, and #' \code{"catchAll"} methods: #' #' The length of the consensus sequences is determined by the longest possible #' consensus sequence (baesd on \code{inputSeq} and \code{germlineSeq}) and #' \code{regionDefinition@seqLength} (if supplied), whichever is shorter. #' #' Given a set of sequences of potentially varying lengths, the longest possible #' length of their consensus sequence is taken to be the longest length along #' which there is information contained at every nucleotide position across #' majority of the sequences. Majority is defined to be greater than #' \code{floor(n/2)}, where \code{n} is the number of sequences. If the longest #' possible consensus length is 0, there will be a warning and an empty string #' (\code{""}) will be returned. #' #' If a length limit is defined by supplying a \code{regionDefinition} via #' \code{regionDefinition@seqLength}, the consensus length will be further #' restricted to the shorter of the longest possible length and #' \code{regionDefinition@seqLength}. #' #' \item For the \code{"mostMutated"} and \code{"leastMutated"} methods: #' #' The length of the consensus sequences depends on that of the most/least #' mutated input sequence, and, if supplied, the length limit defined by #' \code{regionDefinition@seqLength}, whichever is shorter. If the germline #' consensus computed using the \code{"mostCommon"} method is longer than #' the most/least mutated input sequence, the germline consensus is trimmed #' to be of the same length as the input consensus. #' #' } #' #' @section Methods: The descriptions below use "sequences" as a generalization of input #' sequences and germline sequences. #' #' \itemize{ #' #' \item \code{method="thresholdedFreq"} #' #' A threshold must be supplied to the argument \code{minimumFrequency}. At #' each position along the length of the consensus sequence, the frequency #' of each nucleotide/character across sequences is tabulated. The #' nucleotide/character whose frequency is at least (i.e. \code{>=}) #' \code{minimumFrequency} becomes the consensus; if there is none, the #' consensus nucleotide will be \code{"N"}. #' #' When there are ties (frequencies of multiple nucleotides/characters #' are at least \code{minimumFrequency}), this method can be deterministic #' or stochastic, depending on additional parameters. #' #' \itemize{ #' \item With \code{includeAmbiguous=TRUE}, ties are resolved #' deterministically by representing ties using ambiguous #' characters. See "Choosing ambiguous characters" for how #' ambiguous characters are chosen. #' \item With \code{breakTiesStochastic=TRUE}, ties are resolved #' stochastically by randomly picking a character amongst the #' ties. #' \item When both \code{TRUE}, \code{includeAmbiguous} takes #' precedence over \code{breakTiesStochastic}. #' \item When both \code{FALSE}, the first character from the ties is #' taken to be the consensus following the order of \code{"A"}, #' \code{"T"}, \code{"G"}, \code{"C"}, \code{"N"}, \code{"."}, #' and \code{"-"}. #' } #' #' Below are some examples looking at a single position based on 5 #' sequences with \code{minimumFrequency=0.6}, #' \code{includeAmbiguous=FALSE}, and \code{breakTiesStochastic=FALSE}: #' #' \itemize{ #' \item If the sequences have \code{"A"}, \code{"A"}, \code{"A"}, #' \code{"T"}, \code{"C"}, the consensus will be \code{"A"}, #' because \code{"A"} has frequency 0.6, which is at least #' \code{minimumFrequency}. #' \item If the sequences have \code{"A"}, \code{"A"}, \code{"T"}, #' \code{"T"}, \code{"C"}, the consensus will be \code{"N"}, #' because none of \code{"A"}, \code{"T"}, or \code{"C"} has #' frequency that is at least \code{minimumFrequency}. #' } #' #' \item \code{method="mostCommon"} #' #' The most frequent nucleotide/character across sequences at each #' position along the length of the consensus sequence makes up the consensus. #' #' When there are ties (multiple nucleotides/characters with equally #' maximal frequencies), this method can be deterministic or stochastic, #' depending on additional parameters. The same rules for breaking ties #' for \code{method="thresholdedFreq"} apply. #' #' Below are some examples looking at a single position based on 5 #' sequences with \code{includeAmbiguous=FALSE}, and #' \code{breakTiesStochastic=FALSE}: #' #' \itemize{ #' \item If the sequences have \code{"A"}, \code{"A"}, \code{"T"}, #' \code{"A"}, \code{"C"}, the consensus will be \code{"A"}. #' \item If the sequences have \code{"T"}, \code{"T"}, \code{"C"}, #' \code{"C"}, \code{"G"}, the consensus will be \code{"T"}, #' because \code{"T"} is before \code{"C"} in the order of #' \code{"A"}, \code{"T"}, \code{"G"}, \code{"C"}, \code{"N"}, #' \code{"."}, and \code{"-"}. #' } #' #' #' \item \code{method="catchAll"} #' #' This method returns a consensus sequence capturing most of the #' information contained in the sequences. Ambiguous characters are #' used where applicable. See "Choosing ambiguous characters" for how #' ambiguous characters are chosen. This method is deterministic and #' does not involve breaking ties. #' #' Below are some examples for \code{method="catchAll"} looking at a #' single position based on 5 sequences: #' #' \itemize{ #' \item If the sequences have \code{"N"}, \code{"N"}, \code{"N"}, #' \code{"N"}, \code{"N"}, the consensus will be \code{"N"}. #' \item If the sequences have \code{"N"}, \code{"A"}, \code{"A"}, #' \code{"A"}, \code{"A"}, the consensus will be \code{"A"}. #' \item If the sequences have \code{"N"}, \code{"A"}, \code{"G"}, #' \code{"A"}, \code{"A"}, the consensus will be \code{"R"}. #' \item If the sequences have \code{"-"}, \code{"-"}, \code{"."}, #' \code{"."}, \code{"."}, the consensus will be \code{"-"}. #' \item If the sequences have \code{"-"}, \code{"-"}, \code{"-"}, #' \code{"-"}, \code{"-"}, the consensus will be \code{"-"}. #' \item If the sequences have \code{"."}, \code{"."}, \code{"."}, #' \code{"."}, \code{"."}, the consensus will be \code{"."}. #' } #' #' \item \code{method="mostMutated"} and \code{method="leastMutated"} #' #' These methods return the most/least mutated sequence as the consensus #' sequence. #' #' When there are ties (multple sequences have the maximal/minimal mutation #' frequency), this method can be deterministic or stochastic, depending on #' additional parameters. #' #' \itemize{ #' \item With \code{breakTiesStochastic=TRUE}, ties are resolved #' stochastically by randomly picking a sequence out of #' sequences with the maximal/minimal mutation frequency. #' \item When \code{breakTiesByColumns} is supplied, ties are resolved #' deterministically. Column by column, a function is applied on #' the column and sequences with column value matching the #' functional value are retained, until ties are resolved or #' columns run out. In the latter case, the first remaining #' sequence is taken as the consensus. #' \item When \code{breakTiesStochastic=TRUE} and #' \code{breakTiesByColumns} is also supplied, #' \code{breakTiesStochastic} takes precedence over #' \code{breakTiesByColumns}. #' \item When \code{breakTiesStochastic=FALSE} and #' \code{breakTiesByColumns} is not supplied (i.e. \code{NULL}), #' the sequence that appears first amongst the ties is taken #' as the consensus. #' } #' #' } #' #' #' @section Choosing ambiguous characters: #' #' Ambiguous characters may be present in the returned consensuses when using the #' \code{"catchAll"} method and when using the \code{"thresholdedFreq"} or #' \code{"mostCommon"} methods with \code{includeAmbiguous=TRUE}. #' #' The rules on choosing ambiguous characters are as follows: #' #' \itemize{ #' \item If a position contains only \code{"N"} across sequences, the consensus #' at that position is \code{"N"}. #' \item If a position contains one or more of \code{"A"}, \code{"T"}, #' \code{"G"}, or \code{"C"}, the consensus will be an IUPAC character #' representing all of the characters present, regardless of whether #' \code{"N"}, \code{"-"}, or \code{"."} is present. #' \item If a position contains only \code{"-"} and \code{"."} across sequences, #' the consensus at thatp osition is taken to be \code{"-"}. #' \item If a position contains only one of \code{"-"} or \code{"."} across #' sequences, the consensus at that position is taken to be the character #' present. #' } #' #' @section Cautions: #' #' \itemize{ #' \item Note that this function does not perform multiple sequence alignment. #' As a prerequisite, it is assumed that the sequences in #' \code{sequenceColumn} and \code{germlineColumn} have been aligned #' somehow. In the case of immunoglobulin repertoire analysis, this #' usually means that the sequences are IMGT-gapped. #' \item When using the \code{"mostMutated"} and \code{"leastMutated"} methods, #' if you supply both \code{muFreqColumn} and \code{regionDefinition}, #' it is your responsibility to ensure that the mutation frequency in #' \code{muFreqColumn} was calculated with sequence lengths restricted #' to the \strong{same} \code{regionDefinition} you are supplying. #' Otherwise, the "most/least mutated" sequence you obtain might not #' be the most/least mutated given the \code{regionDefinition} supplied, #' because your mutation frequency was based on a #' \code{regionDefinition} different from the one supplied. #' \item If you intend to run \code{collapseClones} before #' building a 5-mer targeting model, you \strong{must} choose #' parameters such that your collapsed clonal consensuses do #' \strong{not} include ambiguous characters. This is because the #' targeting model functions do NOT support ambiguous characters #' in their inputs. #' } #' #' @seealso #' See \link{IMGT_SCHEMES} for a set of predefined \link{RegionDefinition} objects. #' #' @examples #' # Subset example data #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE %in% c("IgA", "IgG") & SAMPLE == "+7d" & #' CLONE %in% c("3100", "3141", "3184")) #' #' # thresholdedFreq method, resolving ties deterministically without using ambiguous characters #' clones <- collapseClones(db, method="thresholdedFreq", minimumFrequency=0.6, #' includeAmbiguous=FALSE, breakTiesStochastic=FALSE) #' #' # mostCommon method, resolving ties deterministically using ambiguous characters #' clones <- collapseClones(db, method="mostCommon", #' includeAmbiguous=TRUE, breakTiesStochastic=FALSE) #' #' # Make a copy of db that has a mutation frequency column #' db2 <- observedMutations(db, frequency=TRUE, combine=TRUE) #' #' # mostMutated method, resolving ties stochastically #' clones <- collapseClones(db2, method="mostMutated", muFreqColumn="MU_FREQ", #' breakTiesStochastic=TRUE, breakTiesByColumns=NULL) #' #' # mostMutated method, resolving ties deterministically using additional columns #' clones <- collapseClones(db2, method="mostMutated", muFreqColumn="MU_FREQ", #' breakTiesStochastic=FALSE, #' breakTiesByColumns=list(c("DUPCOUNT"), c(max))) #' #' # Build consensus for V segment only #' # Capture all nucleotide variations using ambiguous characters #' clones <- collapseClones(db, method="catchAll", regionDefinition=IMGT_V) #' #' # Return the same number of rows as the input #' clones <- collapseClones(db, method="mostCommon", expandedDb=TRUE) #' #' @export collapseClones <- function(db, cloneColumn="CLONE", sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", muFreqColumn=NULL, regionDefinition=NULL, method=c("mostCommon", "thresholdedFreq", "catchAll", "mostMutated", "leastMutated"), minimumFrequency=NULL, includeAmbiguous=FALSE, breakTiesStochastic=FALSE, breakTiesByColumns=NULL, expandedDb=FALSE, nproc=1) { # Hack for visibility of foreach index variables idx <- NULL ## DEBUG # cloneColumn="CLONE"; sequenceColumn="SEQUENCE_IMGT"; germlineColumn="GERMLINE_IMGT_D_MASK" # expandedDb=FALSE; regionDefinition=NULL; method="mostCommon"; nproc=1 #### parameter checks method <- match.arg(method) # check minimumFrequency for thresholdedFreq method if (method=="thresholdedFreq") { if (!is.numeric(minimumFrequency)) { stop("minimumFrequency must be a numeric value.") } else { if ( minimumFrequency<0 | minimumFrequency>1 ) { stop("minimumFrequency must be between 0 and 1.") } } } # check includeAmbiguous & breakTiesStochastic for methods other than catchAll if (method %in% c("thresholdedFreq", "mostCommon", "mostMutated", "leastMutated")) { if (!is(includeAmbiguous, "logical")) { stop ("includeAmbiguous must be TRUE or FALSE.") } if (!is(breakTiesStochastic, "logical")) { stop ("breakTiesStochastic must be TRUE or FALSE.") } } # check breakTiesByColumns and muFreqColumn for methods most/leastMutated if (method %in% c("mostMutated", "leastMutated")) { if (!is.null(breakTiesByColumns)) { if (!is(breakTiesByColumns, "list")) { stop ("breakTiesByColumns must be a list.") } if (length(breakTiesByColumns) != 2) { stop ("breakTiesByColumns must be a nested list of length 2.") } if (length(breakTiesByColumns[[1]]) != length(breakTiesByColumns[[2]])) { stop ("Nested vectors in breakTiesByColumns must have the same lengths.") } if (!all(is.character(breakTiesByColumns[[1]]))) { stop ("The first vector in breakTiesByColumns must contain column names.") } if (!all( unlist( lapply(breakTiesByColumns[[2]], is.function)))) { stop ("The second vector in breakTiesByColumns must contain functions.") } if (!all(breakTiesByColumns[[1]] %in% colnames(db))) { stop ("All column named included in breakTiesByColumns must be present in db.") } } if ( (!is.null(muFreqColumn)) && (!muFreqColumn %in% colnames(db)) ) { stop ("If specified, muFreqColumn must be a column present in db.") } } # check mutual exclusivitiy if (method %in% c("thresholdedFreq", "mostCommon")){ if (includeAmbiguous & breakTiesStochastic) { message("includeAmbiguous and breakTiesStochastic are mutually exclusive. When both TRUE, includeAmbiguous will take precedence.") } #if ( (!includeAmbiguous) & (!breakTiesStochastic) ) { # message("When both includeAmbiguous and breakTiesStochastic are FALSE, ties are broken in the order of 'A', 'T', 'G', 'C', 'N', '.', and '-'.") #} if (!is.null(breakTiesByColumns)) { message("breakTiesByColumns is ignored when method is thresholdedFreq or mostCommon.") } } if (method %in% c("mostMutated", "leastMutated")){ if (breakTiesStochastic & !is.null(breakTiesByColumns)) { message("breakTiesStochastic and breakTiesByColumns are mutually exclusive. When both set, breakTiesStochastic will take precedence.") } #if ( (!breakTiesStochastic) & is.null(breakTiesByColumns) ) { # message("When breakTiesStochastic is FALSE and breakTiesByColumns is NULL, ties are broken by taking the sequence that appears earlier in the data.frame.") #} if (includeAmbiguous) { message("includeAmbiguous is ignored when method is mostMutated or leastMutated.") } } # Check for valid columns check <- checkColumns(db, c(cloneColumn, sequenceColumn, germlineColumn)) if (check != TRUE) { stop(check) } # Check region definition if (!is.null(regionDefinition) & !is(regionDefinition, "RegionDefinition")) { stop(deparse(substitute(regionDefinition)), " is not a valid RegionDefinition object") } ### Convert sequence columns to uppercase db <- toupperColumns(db, c(sequenceColumn, germlineColumn)) # If the user has previously set the cluster and does not wish to reset it if(!is.numeric(nproc)){ cluster <- nproc nproc <- 0 } if (!is(expandedDb, "logical")) { stop ("expandedDb must be TRUE or FALSE.") } # Convert clone identifiers to strings db[[cloneColumn]] <- as.character(db[[cloneColumn]]) # get row indices in db for each unique clone uniqueClones <- unique(db[[cloneColumn]]) # crucial to have simplify=FALSE (otherwise won't return a list if uniqueClones has length 1) uniqueClonesIdx <- sapply(uniqueClones, function(i){which(db[[cloneColumn]]==i)}, simplify=FALSE) # if method is most/leastMutated and muFreqColumn not specified, # first calculate mutation frequency ($MU_FREQ) # IMPORTANT: do this OUTSIDE foreach loop for calcClonalConsensus # otherwise will get an error saying muFreqColumn not found in db # (something to do with parallelization/foreach) if ( (method %in% c("mostMutated", "leastMutated")) & is.null(muFreqColumn) ) { message("Calculating observed mutation frequency...") db <- observedMutations(db=db, sequenceColumn=sequenceColumn, germlineColumn=germlineColumn, regionDefinition=regionDefinition, frequency=TRUE, combine=TRUE, mutationDefinition=NULL, nproc=nproc) muFreqColumn <- "MU_FREQ" } # Ensure that the nproc does not exceed the number of cores/CPUs available nproc <- min(nproc, cpuCount()) # If user wants to paralellize this function and specifies nproc > 1, then # initialize and register slave R processes/clusters & # export all nesseary environment variables, functions and packages. if (nproc == 1) { # If needed to run on a single core/cpu then, regsiter DoSEQ # (needed for 'foreach' in non-parallel mode) registerDoSEQ() } else { if (nproc != 0) { #cluster <- makeCluster(nproc, type="SOCK") cluster <- parallel::makeCluster(nproc, type= "PSOCK") } parallel::clusterExport(cluster, list('db', 'cloneColumn', 'sequenceColumn', 'germlineColumn', 'muFreqColumn', 'regionDefinition', 'method', 'minimumFrequency','includeAmbiguous', 'breakTiesStochastic', 'breakTiesByColumns', 'calcClonalConsensus', 'consensusSequence', 'breakTiesHelper', 'chars2Ambiguous', 'nucs2IUPAC', 'IUPAC_DNA_2', 'NUCLEOTIDES_AMBIGUOUS', 'uniqueClonesIdx', 'c2s', 's2c'), envir=environment() ) registerDoParallel(cluster) } # Printing status to console #cat("Collapsing clonal sequences...\n") # avoid .combine="cbind"! # if there is only 1 unique clone, .combind="cbind" will result in a vector (as opposed to # a matrix) being returned, which will subsequently result a failure in # cons_db$CLONAL_SEQUENCE <- cons_mat[, 1] cons_mat <- foreach(idx=1:length(uniqueClonesIdx), .verbose=FALSE, .errorhandling='stop') %dopar% { cloneIdx <- uniqueClonesIdx[[idx]] cloneDb <- db[cloneIdx, ] # collapse clone calcClonalConsensus(db=cloneDb, sequenceColumn=sequenceColumn, germlineColumn=germlineColumn, muFreqColumn=muFreqColumn, regionDefinition=regionDefinition, method=method, minimumFrequency=minimumFrequency, includeAmbiguous=includeAmbiguous, breakTiesStochastic=breakTiesStochastic, breakTiesByColumns=breakTiesByColumns) } # using cbind below will give a matrix with columns being clones # use rbind to have rows be clones # cols: inputCons, germlineCons, inputMuFreq cons_mat <- do.call(rbind, cons_mat) # Stop cluster if(nproc > 1) { parallel::stopCluster(cluster) } # Build return data.frame if (expandedDb) { # Fill all rows with the consensus sequence clone_index <- match(db[[cloneColumn]], uniqueClones) cons_db <- db cons_db$CLONAL_SEQUENCE <- unlist(cons_mat[, 1])[clone_index] cons_db$CLONAL_GERMLINE <- unlist(cons_mat[, 2])[clone_index] # assign mutation frequency corresponding to consensus into CLONAL_SEQUENCE_MUFREQ if (method %in% c("mostMutated", "leastMutated")) { cons_db$CLONAL_SEQUENCE_MUFREQ <- unlist(cons_mat[, 3])[clone_index] } } else { # Return only the first row of each clone clone_index <- match(uniqueClones, db[[cloneColumn]]) cons_db <- db[clone_index, ] cons_db$CLONAL_SEQUENCE <- unlist(cons_mat[, 1]) cons_db$CLONAL_GERMLINE <- unlist(cons_mat[, 2]) # assign mutation frequency corresponding to consensus into CLONAL_SEQUENCE_MUFREQ if (method %in% c("mostMutated", "leastMutated")) { cons_db$CLONAL_SEQUENCE_MUFREQ <- unlist(cons_mat[, 3]) } } return(cons_db) } # Break ties given additional columns in db and functions to compute on them # # @param idx vector of indices. # @param cols character vector of colnames. Currently, only columns containing # numeric values are supported/expected. # @param funs list of functions. Currently, only \code{max} and \code{min} are # supported/expected. # @param db \code{data.frame} containing columns named after \code{cols} with # corresponding rows for \code{idx}. # # @return a single value from \code{idx}. # # @details Column by column, \code{breakTiesHelper} calls the corresponding function # from \code{funs} on a column in \code{db} and finds the index/indices in # \code{idx} that match(es) the returned value from the function. This stops # when only a single matching index is obtained, or columns run out. In the # latter case, the first remaining index is returned. # # testing # expect index 18 # test.idx = c(2,4,18,37,102,76) # test.db = data.frame(cbind(DUPCOUNT= c(3,5,5,4,5,1), # CONSCOUNT=c(6,6,6,2,3,4), # ERR=c(0.9, 0.14, 0.12, 0.07, 0.3, 0.5))) # test.cols = c("DUPCOUNT", "CONSCOUNT", "ERR") # test.funs = c(max, max, min) # stopifnot( breakTiesHelper(test.idx, test.cols, test.funs, test.db)==18 ) # # make index 4 and 18 tie for ERR # # index 4 is expected because it appears before 18 # test.db[3,"ERR"] = 0.14 # stopifnot( breakTiesHelper(test.idx, test.cols, test.funs, test.db)==4 ) # breakTiesHelper <- function(idx, cols, funs, db) { # debug # idx=test.idx; cols=test.cols; funs=test.funs; db=test.db counter <- 1 while (length(idx)>1 & counter<=length(cols)) { cur.col <- cols[counter] cur.fun <- funs[[counter]] cur.db <- db[[cur.col]] target <- cur.fun(cur.db) tol <- 1e-5 # tolerance target.idx <- which( abs(cur.db-target)<=tol ) # wrt idx & db idx <- idx[target.idx] db <- db[target.idx, ] counter <- counter+1 } if (length(idx)==1) { return(idx) } else if (length(idx)>1) { #print("Failed to resolve ties.") # for testing/debugging return(idx[1]) } else { stop("breakTieHelper failed unexpectedly.") } } #' Construct a consensus sequence #' #' @param sequences character vector of sequences. #' @param db \code{data.frame} containing sequence data for a single clone. #' Applicable to and required for the \code{"mostMutated"} and #' \code{"leastMutated"} methods. Default is \code{NULL}. #' @param method method to calculate consensus sequence. One of #' \code{"thresholdedFreq"}, \code{"mostCommon"}, \code{"catchAll"}, #' \code{"mostMutated"}, or \code{"leastMutated"}. See "Methods" under #' \link{collapseClones} for details. #' @param minFreq frequency threshold for calculating input consensus sequence. #' Applicable to and required for the \code{"thresholdedFreq"} method. #' A canonical choice is 0.6. Default is \code{NULL}. #' @param muFreqColumn \code{character} name of the column in db containing mutation #' frequency. Applicable to and required for the \code{"mostMutated"} #' and \code{"leastMutated"} methods. Default is \code{NULL}. #' @param lenLimit limit on consensus length. if \code{NULL} then no length limit is set. #' @param includeAmbiguous whether to use ambiguous characters to represent positions at #' which there are multiple characters with frequencies that are at least #' \code{minimumFrequency} or that are maximal (i.e. ties). Applicable to #' and required for the \code{"thresholdedFreq"} and \code{"mostCommon"} #' methods. Default is \code{FALSE}. See "Choosing ambiguous characters" #' under \link{collapseClones} for rules on choosing ambiguous characters. #' @param breakTiesStochastic In case of ties, whether to randomly pick a sequence from sequences that #' fulfill the criteria as consensus. Applicable to and required for all methods #' except for \code{"catchAll"}. Default is \code{FALSE}. See "Methods" #' under \link{collapseClones} for details. #' @param breakTiesByColumns A list of the form \code{list(c(col_1, col_2, ...), c(fun_1, fun_2, ...))}, #' where \code{col_i} is a \code{character} name of a column in \code{db}, #' and \code{fun_i} is a function to be applied on that column. Currently, #' only \code{max} and \code{min} are supported. Note that the two \code{c()}'s #' in \code{list()} are essential (i.e. if there is only 1 column, the list #' should be of the form \code{list(c(col_1), c(func_1))}. Applicable to and #' optional for the \code{"mostMutated"} and \code{"leastMutated"} methods. #' If supplied, \code{fun_i}'s are applied on \code{col_i}'s to help break #' ties. Default is \code{NULL}. See "Methods" under \link{collapseClones} #' for details. #' #' @return A list containing \code{cons}, which is a character string that is the consensus sequence #' for \code{sequences}; and \code{muFreq}, which is the maximal/minimal mutation frequency of #' the consensus sequence for the \code{"mostMutated"} and \code{"leastMutated"} methods, or #' \code{NULL} for all other methods. #' #' @details See \link{collapseClones} for detailed documentation on methods and additional parameters. #' #' @examples #' # Subset example data #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE %in% c("IgA", "IgG") & SAMPLE == "+7d") #' clone <- subset(db, CLONE == "3192") #' #' # First compute mutation frequency for most/leastMutated methods #' clone <- observedMutations(clone, frequency=TRUE, combine=TRUE) #' #' # Manually create a tie #' clone <- rbind(clone, clone[which.max(clone$MU_FREQ), ]) #' #' # ThresholdedFreq method. #' # Resolve ties deterministically without using ambiguous characters #' cons1 <- consensusSequence(clone$SEQUENCE_IMGT, #' method="thresholdedFreq", minFreq=0.3, #' includeAmbiguous=FALSE, #' breakTiesStochastic=FALSE) #' cons1$cons #' #' @export ## DEBUG # thresholdedFreq method, resolve ties deterministically using ambiguous characters # consInput2 <- consensusSequence(clone$SEQUENCE_IMGT, # muFreqColumn=NULL, lenLimit=NULL, # method="thresholdedFreq", minFreq=0.3, # includeAmbiguous=TRUE, # breakTiesStochastic=FALSE, # breakTiesByColumns=NULL, db=NULL)$cons # thresholdedFreq method, resolve ties stochastically # consInput3 <- consensusSequence(clone$SEQUENCE_IMGT, # muFreqColumn=NULL, lenLimit=NULL, # method="thresholdedFreq", minFreq=0.3, # includeAmbiguous=FALSE, # breakTiesStochastic=TRUE, # breakTiesByColumns=NULL, db=NULL)$cons # mostCommon method, resolve ties deterministically without using ambiguous characters # consInput4 <- consensusSequence(clone$SEQUENCE_IMGT, # muFreqColumn=NULL, lenLimit=NULL, # method="mostCommon", minFreq=NULL, # includeAmbiguous=FALSE, # breakTiesStochastic=FALSE, # breakTiesByColumns=NULL, db=NULL)$cons # mostCommon method, resolve ties deterministically using ambiguous characters # consInput5 <- consensusSequence(clone$SEQUENCE_IMGT, # muFreqColumn=NULL, lenLimit=NULL, # method="mostCommon", minFreq=NULL, # includeAmbiguous=TRUE, # breakTiesStochastic=FALSE, # breakTiesByColumns=NULL, db=NULL)$cons # mostCommon method, resolve ties stochastically # consInput6 <- consensusSequence(clone$SEQUENCE_IMGT, # muFreqColumn=NULL, lenLimit=NULL, # method="mostCommon", minFreq=NULL, # includeAmbiguous=FALSE, # breakTiesStochastic=TRUE, # breakTiesByColumns=NULL, db=NULL)$cons # catchAll method # consInput7 <- consensusSequence(clone$SEQUENCE_IMGT, # muFreqColumn=NULL, lenLimit=NULL, # method="catchAll", minFreq=NULL, # includeAmbiguous=FALSE, # breakTiesStochastic=FALSE, # breakTiesByColumns=NULL, db=NULL)$cons # mostMutated method, resolve ties stochastically # consInput8 <- consensusSequence(clone$SEQUENCE_IMGT, # muFreqColumn="MU_FREQ", lenLimit=NULL, # method="mostMutated", minFreq=NULL, # includeAmbiguous=FALSE, # breakTiesStochastic=TRUE, # breakTiesByColumns=NULL, db=clone)$cons # mostMutated method, resolve ties deterministically using additional columns # consInput9 <- consensusSequence(clone$SEQUENCE_IMGT, # muFreqColumn="MU_FREQ", lenLimit=NULL, # method="mostMutated", minFreq=NULL, # includeAmbiguous=FALSE, # breakTiesStochastic=FALSE, # breakTiesByColumns=list(c("JUNCTION_LENGTH","DUPCOUNT"), c(max, max)), # db=clone)$cons # consInput10 <- consensusSequence(clone$SEQUENCE_IMGT, # muFreqColumn="MU_FREQ", lenLimit=NULL, # method="mostMutated", minFreq=NULL, # includeAmbiguous=FALSE, # breakTiesStochastic=FALSE, # breakTiesByColumns=list(c("DUPCOUNT"), c(max)), # db=clone)$cons # mostMutated method, resolve ties deterministically withou using additional columns # consInput11 <- consensusSequence(clone$SEQUENCE_IMGT, # muFreqColumn="MU_FREQ", lenLimit=NULL, # method="mostMutated", minFreq=NULL, # includeAmbiguous=FALSE, # breakTiesStochastic=FALSE, # breakTiesByColumns=NULL, db=clone)$cons consensusSequence <- function(sequences, db=NULL, method=c("mostCommon", "thresholdedFreq", "catchAll", "mostMutated", "leastMutated"), minFreq=NULL, muFreqColumn=NULL, lenLimit=NULL,includeAmbiguous=FALSE, breakTiesStochastic=FALSE, breakTiesByColumns=NULL) { # Check arguments method <- match.arg(method) # check muFreqColumn and get muFreq for most/leastMutated if (method %in% c("mostMutated", "leastMutated")) { if ( is.null(muFreqColumn) ) { stop ("muFreqColumn must be specified when method is most/leastMutated.") } if ( is.null(db) ) { stop ("db containing muFreqColumn must be supplied when method is most/leastMutated.") } if (!muFreqColumn %in% colnames(db)) { print(c("Helper", muFreqColumn)) print(c("Helper", colnames(db))) stop ("muFreqColumn must be a column present in db.") } # get muFreq muFreq <- db[[muFreqColumn]] } numSeqs <- length(sequences) ##### if only one sequence in clone, return it if (numSeqs==1) { # restrict length if there is a lenLimit if (!is.null(lenLimit)) { consensus <- substr(sequences, 1, min(lenLimit, stri_length(sequences))) } else { # otherwise, return as is consensus <- sequences } # return with mutation frequency (if applicable) if (method %in% c("mostMutated", "leastMutated")) { return(list(cons=consensus, muFreq=db[[muFreqColumn]])) } else { return(list(cons=consensus, muFreq=NULL)) } } ##### if all sequences are the same, return now if (length(unique(sequences))==1) { # restrict length if there is a lenLimit if (!is.null(lenLimit)) { consensus <- substr(sequences[1], 1, min(lenLimit, stri_length(sequences))) } else { # otherwise, return as is consensus <- sequences[1] } # return with mutation frequency (if applicable) if (method %in% c("mostMutated", "leastMutated")) { return(list(cons=consensus, muFreq=db[[muFreqColumn]][1])) } else { return(list(cons=consensus, muFreq=NULL)) } } ##### length of longest sequence in sequences lenSeqs <- stri_length(sequences) lenMax <- max(lenSeqs, na.rm=T) ##### methods = thresholdedFreq, mostCommon, catchAll if (method %in% c("thresholdedFreq", "mostCommon", "catchAll")) { ##### convert sequences to a matrix # if there's no more nucleotide when a seq ends, fill position with NA seqsMtx <- matrix(NA, nrow=numSeqs, ncol=lenMax) for (i in 1:numSeqs) { seqsMtx[i, 1:lenSeqs[i]] <- s2c(sequences[i]) } ##### tabulation matrix # col: nucleotide position # row: A,T,G,C,N,.,-,na (to distinguish from NA) tabMtxRownames <- c("A","T","G","C","N",".","-","na") tabMtx <- matrix(0, ncol=lenMax, nrow=8, dimnames=list(tabMtxRownames, NULL)) ## across sequences, at each nuc position, how many A, T, G, C, N, ., -? # this does not capture NA for (j in 1:ncol(seqsMtx)) { tab <- table(seqsMtx[, j]) tabMtx[match(names(tab), tabMtxRownames), j] <- tab } ## across sequences, at each nuc position, how many NAs? numNAs <- colSums(is.na(seqsMtx)) tabMtx["na", ] <- numNAs # sanity check: counts at each nuc pos (colSum) should sum up to number of sequences stopifnot( sum( colSums(tabMtx)==numSeqs ) == ncol(tabMtx) ) ##### only keep positions at which majority of sequences contain information ### if there are odd number of n sequences, keep position if it has > floor(n/2) non-NAs # e.g. 5 input sequences, >2 non-NA; 2=floor(5/2) ### if there are even number of n sequences, keep position if it has > n/2 non-NAs # e.g. 6 input sequences, >3 non-NA; 3=6/2=floor(6/2) numNonNAs <- numSeqs - numNAs nonNA.keep <- numNonNAs > floor(numSeqs/2) # length of longest possible consensus seq lenConsensus <- sum(nonNA.keep) if (lenConsensus==0) { warning("Consensus cannot be produced. Empty string returned.") return("") } ##### if there is a lenLimit, restrict consensus length to # the shorter of longest possible length and lenLimit if (!is.null(lenLimit)) { lenConsensus <- min(lenConsensus, lenLimit) } # drop=FALSE so that it works even with lenConsensus of 1 tabMtx <- tabMtx[, 1:lenConsensus, drop=FALSE] ### convert absolute count to fraction tabMtx <- tabMtx/numSeqs # remove "na" row # drop=FALSE so that it works even with lenConsensus of 1 tabMtx <- tabMtx[-which(rownames(tabMtx)=="na"), , drop=FALSE] if (method=="thresholdedFreq") { #print(method) # for testing # use as.matrix so that apply won't break with ncol(tabMtx)=1 consensus <- apply(as.matrix(tabMtx), 2, function(x){ idx <- which(x >= minFreq) # if no character >= the threshold, assign an N if (length(idx)==0) { return("N") # if there is no tie } else if (length(idx)==1){ return(names(x)[idx]) # if there are ties (multiple characters >= the threhold) } else if (length(idx)>1) { # ambiguous character allowed if (includeAmbiguous) { return(chars2Ambiguous(tabMtxRownames[idx])) # ambiguous characters not allowed } else { # stochastic if (breakTiesStochastic) { return(names(x)[sample(x=idx, size=1)]) # first one is returned # the order is built-in from tabMtxRownames } else { return(names(x)[idx[1]]) } } } }) } else if (method=="mostCommon") { #print(method) # for testing # use as.matrix so that apply won't break with ncol(tabMtx)=1 consensus <- apply(as.matrix(tabMtx), 2, function(x){ max.freq <- max(x) tol <- 1e-5 # tolerance max.idx <- which( abs(x-max.freq)<=tol ) # if there is no tie if (length(max.idx)==1){ return(names(x)[max.idx]) # if there are ties (multiple characters with maximal frequency) } else if (length(max.idx)>1) { # ambiguous character allowed if (includeAmbiguous) { return(chars2Ambiguous(tabMtxRownames[max.idx])) # ambiguous characters not allowed } else { # stochastic if (breakTiesStochastic) { return(names(x)[sample(x=max.idx, size=1)]) # first one is returned # the order is built-in from tabMtxRownames } else { return(names(x)[max.idx[1]]) } } } }) } else if (method=="catchAll") { #print(method) # for testing # use as.matrix so that apply won't break with ncol(tabMtx)=1 consensus <- apply(as.matrix(tabMtx), 2, function(x){ # all characters that appear at a position across sequences nonZeroNucs <- rownames(tabMtx)[x>0] # convert characters to (ambiguous) characters return(chars2Ambiguous(nonZeroNucs)) }) } # check there is no ambiguous characters if includeAmbiguous if F if ( (method=="thresholdedFreq" | method=="mostCommon") & !includeAmbiguous ) { ambiguous <- NUCLEOTIDES_AMBIGUOUS[!NUCLEOTIDES_AMBIGUOUS %in% c("A","C","G","T","N","-",".")] stopifnot( !any(consensus %in% ambiguous) ) } # convert from character vector to string consensus <- c2s(consensus) # sanity check stopifnot( stri_length(consensus)==lenConsensus ) } ##### methods = mostMutated, leastMutated if (method %in% c("mostMutated", "leastMutated")) { # if there's a lenLimit # if a seq is longer than lenLimit, trim it; otherwise, leave it as is if (!is.null(lenLimit)) { idxLong <- which(lenSeqs > lenLimit) sequences[idxLong] <- substr(sequences[idxLong], 1, lenLimit) } ##### get index of sequences that fulfill the criterion # muFreq should have been calculated being on sequences with restricted lengths as defined by # regionDefinition (which gives rise to lenLimit) if (method=="mostMutated") { #print(method) # for testing targetMuFreq <- max(muFreq) } else if (method=="leastMutated") { #print(method) # for testing targetMuFreq <- min(muFreq) } tol <- 1e-5 # tolerance idx <- which( abs(muFreq-targetMuFreq)<=tol ) ##### if there are no ties if (length(idx)==1) { consensus <- sequences[idx] ##### if there are ties } else if (length(idx)>1) { ### stochastic: randomly pick one from idx if (breakTiesStochastic) { consensus <- sequences[sample(x=idx, size=1)] ### deterministic: pick one from idx based on breakTiesByColumns } else if (!is.null(breakTiesByColumns)) { idx <- breakTiesHelper(idx=idx, cols=breakTiesByColumns[[1]], funs=breakTiesByColumns[[2]], db=db[idx, ]) consensus <- sequences[idx] ### deterministic: pick first one from idx } else { consensus <- sequences[idx[1]] } } } # check length if (!is.null(lenLimit)) { stopifnot(stri_length(consensus) <= lenLimit) } if (method %in% c("mostMutated", "leastMutated")) { return(list(cons=consensus, muFreq=targetMuFreq)) } else { return(list(cons=consensus, muFreq=NULL)) } } # Calculate clonal consensus for a single clone # # Given an aligned set of input/observed sequences and an aligned set of germline sequences, # generate an input/observed consensus and a germline consensus. # # @param db \code{data.frame} containing sequence data for a single clone. # Required. # @param sequenceColumn \code{character} name of the column containing input # sequences. Required. The length of each input sequence should # match that of its corresponding germline sequence. # @param germlineColumn \code{character} name of the column containing germline # sequences. Required. The length of each germline sequence should # match that of its corresponding input sequence. # @param muFreqColumn \code{character} name of the column containing mutation # frequency. Applicable to and required for the \code{"mostMutated"} # and \code{"leastMutated"} methods. Default is \code{NULL}. See # "Details" for a note of caution. # @param regionDefinition \link{RegionDefinition} object defining the regions and boundaries # of the Ig sequences. Optional. Default is \code{NULL}. # @param method method for calculating input consensus sequence. Required. One of # \code{"thresholdedFreq"}, \code{"mostCommon"}, \code{"catchAll"}, # \code{"mostMutated"}, or \code{"leastMutated"}. See "Methods" under # \link{collapseClones} for details. # @param minimumFrequency frequency threshold for calculating input consensus sequence. # Applicable to and required for the \code{"thresholdedFreq"} method. # A canonical choice is 0.6. Default is \code{NULL}. # @param includeAmbiguous whether to use ambiguous characters to represent positions at # which there are multiple characters with frequencies that are at least # \code{minimumFrequency} or that are maximal (i.e. ties). Applicable to # and required for the \code{"thresholdedFreq"} and \code{"mostCommon"} # methods. Default is \code{FALSE}. See "Choosing ambiguous characters" # under \link{collapseClones} for rules on choosing ambiguous characters. # @param breakTiesStochastic In case of ties, whether to randomly pick a sequence from sequences that # fulfill the criteria as consensus. Applicable to and required for all methods # except for \code{"catchAll"}. Default is \code{FALSE}. See "Methods" # under \link{collapseClones} for details. # @param breakTiesByColumns A list of the form \code{list(c(col_1, col_2, ...), c(fun_1, fun_2, ...))}, # where \code{col_i} is a \code{character} name of a column in \code{db}, # and \code{fun_i} is a function to be applied on that column. Currently, # only \code{max} and \code{min} are supported. Applicable to and optional for # the \code{"mostMutated"} and \code{"leastMutated"} methods. If supplied, # \code{fun_i}'s are applied on \code{col_i}'s to help break ties. Default is # \code{NULL}. See "Methods" under \link{collapseClones} for details. # # @return A named list of length 3. "inputCons" and "germlineCons" are the consensus sequences. # The input and germline consensus sequences have the same length. "inputMuFreq" is the # maximal/minimal mutation frequency for the input consensus for the \code{"mostMutated"} # and \code{"leastMutated"} methods, and \code{NULL} for all other methods. # # @details See \link{collapseClones} for detailed documention on methods and additional parameters. # # Caution: when using the \code{"mostMutated"} and \code{"leastMutated"} methods, if you # supply a \code{regionDefinition}, it is your responsibility to ensure that the mutation # frequency in\code{muFreqColumn} was calculated with sequence lengths restricted to the # \strong{same} \code{regionDefinition} you are supplying. Otherwise, the # "most/least mutated" sequence you obtain might not be the most/least mutated given the # \code{regionDefinition} supplied, because your mutation frequency was based on a # \code{regionDefinition} different from the one supplied. # # @seealso # See \link{collapseClones} for constructing consensus for all clones. # # @examples # # Subset example data # data(ExampleDb, package="alakazam") # db <- subset(ExampleDb, ISOTYPE %in% c("IgA", "IgG") & SAMPLE == "+7d") # # # Data corresponding to a single clone # clone <- db[db$CLONE=="3192", ] # # Number of sequences in this clone # nrow(clone) # # compute mutation frequency for most/leastMutated methods # clone <- observedMutations(db=clone, frequency=TRUE, combine=TRUE) # # manually create a tie # clone <- rbind(clone, clone[which.max(clone$MU_FREQ), ]) # # # Get consensus input and germline sequences # # thresholdedFreq method, resolve ties deterministically without using ambiguous characters # cons1 <- calcClonalConsensus(db=clone, # muFreqColumn=NULL, regionDefinition=NULL, # method="thresholdedFreq", # minimumFrequency=0.3, includeAmbiguous=FALSE, # breakTiesStochastic=FALSE, breakTiesByColumns=NULL) # # thresholdedFreq method, resolve ties deterministically using ambiguous characters # cons2 <- calcClonalConsensus(db=clone, # muFreqColumn=NULL, regionDefinition=NULL, # method="thresholdedFreq", # minimumFrequency=0.3, includeAmbiguous=TRUE, # breakTiesStochastic=FALSE, breakTiesByColumns=NULL) # # thresholdedFreq method, resolve ties stochastically # cons3 <- calcClonalConsensus(db=clone, # muFreqColumn=NULL, regionDefinition=NULL, # method="thresholdedFreq", # minimumFrequency=0.3, includeAmbiguous=FALSE, # breakTiesStochastic=TRUE, breakTiesByColumns=NULL) # # mostCommon method, resolve ties deterministically without using ambiguous characters # cons4 <- calcClonalConsensus(db=clone, # muFreqColumn=NULL, regionDefinition=NULL, # method="mostCommon", # minimumFrequency=NULL, includeAmbiguous=FALSE, # breakTiesStochastic=FALSE, breakTiesByColumns=NULL) # # mostCommon method, resolve ties deterministically using ambiguous characters # cons5 <- calcClonalConsensus(db=clone, # muFreqColumn=NULL, regionDefinition=NULL, # method="mostCommon", # minimumFrequency=NULL, includeAmbiguous=TRUE, # breakTiesStochastic=FALSE, breakTiesByColumns=NULL) # # mostCommon method, resolve ties stochastically # cons6 <- calcClonalConsensus(db=clone, # muFreqColumn=NULL, regionDefinition=NULL, # method="mostCommon", # minimumFrequency=NULL, includeAmbiguous=FALSE, # breakTiesStochastic=TRUE, breakTiesByColumns=NULL) # # catchAll method # cons7 <- calcClonalConsensus(db=clone, # muFreqColumn=NULL, regionDefinition=NULL, # method="catchAll", # minimumFrequency=NULL, includeAmbiguous=FALSE, # breakTiesStochastic=FALSE, breakTiesByColumns=NULL) # # mostMutated method, resolve ties stochastically # cons8 <- calcClonalConsensus(db=clone, # muFreqColumn="MU_FREQ", regionDefinition=NULL, # method="mostMutated", # minimumFrequency=NULL, includeAmbiguous=FALSE, # breakTiesStochastic=TRUE, breakTiesByColumns=NULL) # # mostMutated method, resolve ties deterministically using additional columns # cons9 <- calcClonalConsensus(db=clone, # muFreqColumn="MU_FREQ", regionDefinition=NULL, # method="mostMutated", # minimumFrequency=NULL, includeAmbiguous=FALSE, # breakTiesStochastic=FALSE, # breakTiesByColumns=list(c("JUNCTION_LENGTH", "DUPCOUNT"), c(max, max))) # cons10 <- calcClonalConsensus(db=clone, # muFreqColumn="MU_FREQ", regionDefinition=NULL, # method="mostMutated", # minimumFrequency=NULL, includeAmbiguous=FALSE, # breakTiesStochastic=FALSE, # breakTiesByColumns=list(c("DUPCOUNT"), c(max))) # # mostMutated method, resolve ties deterministically without using additional columns # cons11 <- calcClonalConsensus(db=clone, # muFreqColumn="MU_FREQ", regionDefinition=NULL, # method="mostMutated", # minimumFrequency=NULL, includeAmbiguous=FALSE, # breakTiesStochastic=FALSE, breakTiesByColumns=NULL) # @export calcClonalConsensus <- function(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", muFreqColumn=NULL, regionDefinition=NULL, method=c("mostCommon", "thresholdedFreq", "catchAll", "mostMutated", "leastMutated"), minimumFrequency=NULL, includeAmbiguous=FALSE, breakTiesStochastic=FALSE, breakTiesByColumns=NULL) { method <- match.arg(method) inputSeq <- db[[sequenceColumn]] germlineSeq <- db[[germlineColumn]] # length of seqs in inputSeq and those in germlineSeq should match if ( sum(stri_length(inputSeq)==stri_length(germlineSeq)) != length(inputSeq) ) { stop("Sequences in inputSeq and germlineSeq have different lengths.") } # Check region definition if (!is.null(regionDefinition) & !is(regionDefinition, "RegionDefinition")) { stop(deparse(substitute(regionDefinition)), " is not a valid RegionDefinition object") } # length limit from regionDefinition if (!is.null(regionDefinition)) { lenRegion <- regionDefinition@seqLength } else { lenRegion <- NULL } ##### get consensus germline sequence (most common) # NULL for minFreq and muFreqColumn b/c mostCommon definitely doesn't need them germCons <- consensusSequence(germlineSeq, minFreq=NULL, lenLimit=lenRegion, method="mostCommon", includeAmbiguous=includeAmbiguous, breakTiesStochastic=breakTiesStochastic, breakTiesByColumns=NULL, muFreqColumn=NULL, db=NULL)$cons ##### get consensus observed sequence inputConsMuFreq <- consensusSequence(inputSeq, minFreq=minimumFrequency, lenLimit=lenRegion, method=method, includeAmbiguous=includeAmbiguous, breakTiesStochastic=breakTiesStochastic, breakTiesByColumns=breakTiesByColumns, muFreqColumn=muFreqColumn, db=db) inputCons <- inputConsMuFreq$cons inputMuFreq <- inputConsMuFreq$muFreq if (method %in% c("mostMutated", "leastMutated")) { # possible to have inputCons and germCons of varying lengths # germCons (mostCommon) length is "longest possible length" for mostCommon # inputCons length is min of length of most/least mutated and lenLimit # if different, trim the two to same length lenInput <- stri_length(inputCons) lenGerm <- stri_length(germCons) if (lenInput != lenGerm) { minLen <- min(lenInput, lenGerm) inputCons <- substr(inputCons, 1, minLen) germCons <- substr(germCons, 1, minLen) } } # sanity check: length of germCons and inputCons should be the same # all methods other than most/leastMutated should expect same lengths of inputCons & germCons stopifnot( stri_length(germCons)==stri_length(inputCons) ) return(list("inputCons"=inputCons, "germlineCons"=germCons, "inputMuFreq"=inputMuFreq)) } #### Mutation counting functions #### #' Calculate observed numbers of mutations #' #' \code{observedMutations} calculates the observed number of mutations for each #' sequence in the input \code{data.frame}. #' #' @param db \code{data.frame} containing sequence data. #' @param sequenceColumn \code{character} name of the column containing input #' sequences. IUPAC ambiguous characters for DNA are #' supported. #' @param germlineColumn \code{character} name of the column containing #' the germline or reference sequence. IUPAC ambiguous #' characters for DNA are supported. #' @param regionDefinition \link{RegionDefinition} object defining the regions #' and boundaries of the Ig sequences. If NULL, mutations #' are counted for entire sequence. #' @param mutationDefinition \link{MutationDefinition} object defining replacement #' and silent mutation criteria. If \code{NULL} then #' replacement and silent are determined by exact #' amino acid identity. #' @param ambiguousMode whether to consider ambiguous characters as #' \code{"either or"} or \code{"and"} when determining and #' counting the type(s) of mutations. Applicable only if #' \code{sequenceColumn} and/or \code{germlineColumn} #' contain(s) ambiguous characters. One of #' \code{c("eitherOr", "and")}. Default is \code{"eitherOr"}. #' @param frequency \code{logical} indicating whether or not to calculate #' mutation frequencies. Default is \code{FALSE}. #' @param combine \code{logical} indicating whether for each sequence should #' the mutation counts for the different regions (CDR, FWR) and #' mutation types be combined and return one value of #' count/frequency per sequence instead of #' multiple values. Default is \code{FALSE}. #' @param nproc number of cores to distribute the operation over. If the #' cluster has already been set the call function with #' \code{nproc} = 0 to not reset or reinitialize. Default is #' \code{nproc} = 1. #' #' @return A modified \code{db} \code{data.frame} with observed mutation counts for each #' sequence listed. The columns names are dynamically created based on the #' regions in the \code{regionDefinition}. For example, when using the #' \link{IMGT_V} definition, which defines positions for CDR and #' FWR, the following columns are added: #' \itemize{ #' \item \code{MU_COUNT_CDR_R}: number of replacement mutations in CDR1 and #' CDR2 of the V-segment. #' \item \code{MU_COUNT_CDR_S}: number of silent mutations in CDR1 and CDR2 #' of the V-segment. #' \item \code{MU_COUNT_FWR_R}: number of replacement mutations in FWR1, #' FWR2 and FWR3 of the V-segment. #' \item \code{MU_COUNT_FWR_S}: number of silent mutations in FWR1, FWR2 and #' FWR3 of the V-segment. #' } #' If \code{frequency=TRUE}, R and S mutation frequencies are #' calculated over the number of non-N positions in the speficied regions. #' \itemize{ #' \item \code{MU_FREQ_CDR_R}: frequency of replacement mutations in CDR1 and #' CDR2 of the V-segment. #' \item \code{MU_FREQ_CDR_S}: frequency of silent mutations in CDR1 and CDR2 #' of the V-segment. #' \item \code{MU_FREQ_FWR_R}: frequency of replacement mutations in FWR1, #' FWR2 and FWR3 of the V-segment. #' \item \code{MU_FREQ_FWR_S}: frequency of silent mutations in FWR1, FWR2 and #' FWR3 of the V-segment. #' } #' If \code{frequency=TRUE} and \code{combine=TRUE}, the mutations and non-N positions #' are aggregated and a single \code{MU_FREQ} value is returned #' \itemize{ #' \item \code{MU_FREQ}: frequency of replacement and silent mutations in the #' specified region #' } #' #' @details #' Mutation counts are determined by comparing the input sequences (in the column specified #' by \code{sequenceColumn}) to the germline sequence (in the column specified by #' \code{germlineColumn}). See \link{calcObservedMutations} for more technical details, #' \strong{including criteria for which sequence differences are included in the mutation #' counts and which are not}. #' #' The mutations are binned as either replacement (R) or silent (S) across the different #' regions of the sequences as defined by \code{regionDefinition}. Typically, this would #' be the framework (FWR) and complementarity determining (CDR) regions of IMGT-gapped #' nucleotide sequences. Mutation counts are appended to the input \code{db} as #' additional columns. #' #' #' @seealso #' \link{calcObservedMutations} is called by this function to get the number of mutations #' in each sequence grouped by the \link{RegionDefinition}. #' See \link{IMGT_SCHEMES} for a set of predefined \link{RegionDefinition} objects. #' See \link{expectedMutations} for calculating expected mutation frequencies. #' #' #' @examples #' # Subset example data #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE == "IgG" & SAMPLE == "+7d") #' #' # Calculate mutation frequency over the entire sequence #' db_obs <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", #' germlineColumn="GERMLINE_IMGT_D_MASK", #' frequency=TRUE, #' nproc=1) #' #' # Count of V-region mutations split by FWR and CDR #' # With mutations only considered replacement if charge changes #' db_obs <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", #' germlineColumn="GERMLINE_IMGT_D_MASK", #' regionDefinition=IMGT_V, #' mutationDefinition=CHARGE_MUTATIONS, #' nproc=1) #' #' @export observedMutations <- function(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=NULL, mutationDefinition=NULL, ambiguousMode=c("eitherOr", "and"), frequency=FALSE, combine=FALSE, nproc=1) { # Hack for visibility of foreach index variable idx <- NULL ambiguousMode <- match.arg(ambiguousMode) # Check for valid columns check <- checkColumns(db, c(sequenceColumn, germlineColumn)) if (check != TRUE) { stop(check) } # Check region definition if (!is.null(regionDefinition) & !is(regionDefinition, "RegionDefinition")) { stop(deparse(substitute(regionDefinition)), " is not a valid RegionDefinition object") } # Check if mutation count/freq columns already exist # and throw overwritting warning if (!is.null(regionDefinition)) { labels <- regionDefinition@labels } else { labels <- makeNullRegionDefinition()@labels } if (frequency == TRUE) { if (combine) { labels <- "MU_FREQ" } else { labels <- paste("MU_FREQ_", labels, sep="") } } else { if (combine) { labels <- "MU_COUNT" } else { labels <- paste("MU_COUNT_", labels, sep="") } } label_exists <- labels[labels %in% colnames(db)] if (length(label_exists)>0) { warning(paste0("Columns ", paste(label_exists, collapse=", "), " exist and will be overwritten") ) db[,label_exists] <- NULL } # Check mutation definition if (!is.null(mutationDefinition) & !is(mutationDefinition, "MutationDefinition")) { stop(deparse(substitute(mutationDefinition)), " is not a valid MutationDefinition object") } # Convert sequence columns to uppercase db <- toupperColumns(db, c(sequenceColumn, germlineColumn)) # If the user has previously set the cluster and does not wish to reset it if(!is.numeric(nproc)){ cluster <- nproc nproc <- 0 } # Ensure that the nproc does not exceed the number of cores/CPUs available nproc <- min(nproc, cpuCount()) # If user wants to paralellize this function and specifies nproc > 1, then # initialize and register slave R processes/clusters & # export all nesseary environment variables, functions and packages. if (nproc > 1) { cluster <- parallel::makeCluster(nproc, type = "PSOCK") parallel::clusterExport(cluster, list('db', 'sequenceColumn', 'germlineColumn', 'regionDefinition', 'frequency', 'combine', 'ambiguousMode', 'calcObservedMutations','s2c','c2s','NUCLEOTIDES', 'NUCLEOTIDES_AMBIGUOUS', 'IUPAC2nucs', 'EXPANDED_AMBIGUOUS_CODONS', 'makeNullRegionDefinition', 'mutationDefinition', 'getCodonPos','getContextInCodon','mutationType', 'AMINO_ACIDS', 'binMutationsByRegion', 'countNonNByRegion'), envir=environment()) registerDoParallel(cluster) } else if (nproc == 1) { # If needed to run on a single core/cpu then, regsiter DoSEQ # (needed for 'foreach' in non-parallel mode) registerDoSEQ() } # Printing status to console #cat("Calculating observed number of mutations...\n") # Identify all the mutations in the sequences numbOfSeqs <- nrow(db) observedMutations_list <- foreach(idx=iterators::icount(numbOfSeqs)) %dopar% { oM <- calcObservedMutations(db[[sequenceColumn]][idx], db[[germlineColumn]][idx], frequency=frequency & !combine, regionDefinition=regionDefinition, mutationDefinition=mutationDefinition, returnRaw=combine, ambiguousMode=ambiguousMode) if (combine) { num_mutations <- 0 if (!all(is.na(oM$pos))) { num_mutations <- sum(oM$pos$R, oM$pos$S) } if (!frequency) { num_mutations } else { num_nonN <- sum(oM$nonN) mu_freq <- num_mutations/num_nonN mu_freq } } else { oM } } # Convert list of mutations to data.frame if (combine) { labels_length <- 1 } else if (!is.null(regionDefinition)) { labels_length <- length(regionDefinition@labels) } else{ #labels_length=1 labels_length <- length(makeNullRegionDefinition()@labels) } # Convert mutation vector list to a matrix observed_mutations <- do.call(rbind, lapply(observedMutations_list, function(x) { length(x) <- labels_length return(x) })) #observed_mutations <- t(sapply(observedMutations_list, c)) sep <- "_" if (ncol(observed_mutations) > 1) sep <- "_" observed_mutations[is.na(observed_mutations)] <- 0 if (frequency == TRUE) { colnames(observed_mutations) <- gsub("_$","",paste("MU_FREQ", colnames(observed_mutations), sep=sep)) } else { colnames(observed_mutations) <- gsub("_$","",paste("MU_COUNT", colnames(observed_mutations), sep=sep)) } # Properly shutting down the cluster if (nproc > 1) { parallel::stopCluster(cluster) } # Bind the observed mutations to db db_new <- cbind(db, observed_mutations) return(db_new) } #' Count the number of observed mutations in a sequence. #' #' \code{calcObservedMutations} determines all the mutations in a given input sequence #' compared to its germline sequence. #' #' @param inputSeq input sequence. IUPAC ambiguous characters for DNA are #' supported. #' @param germlineSeq germline sequence. IUPAC ambiguous characters for DNA #' are supported. #' @param regionDefinition \link{RegionDefinition} object defining the regions #' and boundaries of the Ig sequences. Note, only the part of #' sequences defined in \code{regionDefinition} are analyzed. #' If NULL, mutations are counted for entire sequence. #' @param mutationDefinition \link{MutationDefinition} object defining replacement #' and silent mutation criteria. If \code{NULL} then #' replacement and silent are determined by exact #' amino acid identity. #' @param ambiguousMode whether to consider ambiguous characters as #' \code{"either or"} or \code{"and"} when determining and #' counting the type(s) of mutations. Applicable only if #' \code{inputSeq} and/or \code{germlineSeq} #' contain(s) ambiguous characters. One of #' \code{c("eitherOr", "and")}. Default is \code{"eitherOr"}. #' @param returnRaw return the positions of point mutations and their #' corresponding mutation types, as opposed to counts of #' mutations across positions. Also returns the number of #' bases used as the denominator when calculating frequency. #' Default is \code{FALSE}. #' @param frequency \code{logical} indicating whether or not to calculate #' mutation frequencies. The denominator used is the number #' of bases that are not one of "N", "-", or "." in either #' the input or the germline sequences. If set, this #' overwrites \code{returnRaw}. Default is \code{FALSE}. #' #' @return For \code{returnRaw=FALSE}, an \code{array} with the numbers of replacement (R) #' and silent (S) mutations. #' #' For \code{returnRaw=TRUE}, a list containing #' \itemize{ #' \item \code{$pos}: A data frame whose columns (\code{position}, \code{R}, #' \code{S}, and \code{region}) indicate, respecitively, the nucleotide #' position, the number of R mutations at that position, the number of S #' mutations at that position, and the region in which that nucleotide #' is in. #' \item \code{$nonN}: A vector indicating the number of bases in regions #' defined by \code{regionDefinition} (excluding non-triplet overhang, #' if any) that are not one of "N", "-", or "." in either the #' \code{inputSeq} or \code{germlineSeq}. #' } #' #' For \code{frequency=TRUE}, regardless of \code{returnRaw}, an \code{array} #' with the frequencies of replacement (R) and silent (S) mutations. #' #' @details #' \strong{Each mutation is considered independently in the germline context}. For illustration, #' consider the case where the germline is \code{TGG} and the observed is \code{TAC}. #' When determining the mutation type at position 2, which sees a change from \code{G} to #' \code{A}, we compare the codon \code{TGG} (germline) to \code{TAG} (mutation at position #' 2 independent of other mutations in the germline context). Similarly, when determining #' the mutation type at position 3, which sees a change from \code{G} to \code{C}, we #' compare the codon \code{TGG} (germline) to \code{TGC} (mutation at position 3 independent #' of other mutations in the germline context). #' #' If specified, only the part of \code{inputSeq} defined in \code{regionDefinition} is #' analyzed. For example, when using the default \link{IMGT_V} definition, then mutations #' in positions beyond 312 will be ignored. Additionally, non-triplet overhang at the #' sequence end is ignored. #' #' Only replacement (R) and silent (S) mutations are included in the results. \strong{Excluded} #' are: #' \itemize{ #' \item Stop mutations #' #' E.g.: the case where \code{TAGTGG} is observed for the germline \code{TGGTGG}. #' #' \item Mutations occurring in codons where one or both of the observed and the #' germline involve(s) one or more of "N", "-", or ".". #' #' E.g.: the case where \code{TTG} is observed for the germline being any one of #' \code{TNG}, \code{.TG}, or \code{-TG}. Similarly, the case where any one of #' \code{TTN}, \code{TT.}, or \code{TT-} is observed for the germline \code{TTG}. #' #' } #' In other words, a result that is \code{NA} or zero indicates absence of R and S mutations, #' not necessarily all types of mutations, such as the excluded ones mentioned above. #' #' \code{NA} is also returned if \code{inputSeq} or \code{germlineSeq} is shorter than 3 #' nucleotides. #' #' @section Ambiguous characters: #' When there are ambiguous characters present, the user could choose how mutations involving #' ambiguous characters are counted through \code{ambiguousMode}. The two available modes #' are \code{"eitherOr"} and \code{"and"}. #' \itemize{ #' \item With \code{"eitherOr"}, ambiguous characters are each expanded but only #' 1 mutation is recorded. When determining the type of mutation, the #' priority for different types of mutations, in decreasing order, is as follows: #' no mutation, replacement mutation, silent mutation, and stop mutation. #' #' When counting the number of non-N, non-dash, and non-dot positions, each #' position is counted only once, regardless of the presence of ambiguous #' characters. #' #' As an example, consider the case where \code{germlineSeq} is \code{"TST"} and #' \code{inputSeq} is \code{"THT"}. Expanding \code{"H"} at position 2 in #' \code{inputSeq} into \code{"A"}, \code{"C"}, and \code{"T"}, as well as #' expanding \code{"S"} at position 2 in \code{germlineSeq} into \code{"C"} and #' \code{"G"}, one gets: #' #' \itemize{ #' \item \code{"TCT"} (germline) to \code{"TAT"} (observed): replacement #' \item \code{"TCT"} (germline) to \code{"TCT"} (observed): no mutation #' \item \code{"TCT"} (germline) to \code{"TTT"} (observed): replacement #' \item \code{"TGT"} (germline) to \code{"TAT"} (observed): replacement #' \item \code{"TGT"} (germline) to \code{"TCT"} (observed): replacement #' \item \code{"TGT"} (germline) to \code{"TTT"} (observed): replacement #' } #' #' Because "no mutation" takes priority over replacement mutation, the final #' mutation count returned for this example is \code{NA} (recall that only R and #' S mutations are returned). The number of non-N, non-dash, and non-dot #' positions is 3. #' #' \item With \code{"and"}, ambiguous characters are each expanded and mutation(s) #' from all expansions are recorded. #' #' When counting the number of non-N, non-dash, and non-dot positions, if a #' position contains ambiguous character(s) in \code{inputSeq} and/or #' \code{germlineSeq}, the count at that position is taken to be the total #' number of combinations of germline and observed codons after expansion. #' #' Using the same example from above, the final result returned for this example #' is that there are 5 R mutations at position 2. The number of non-N, non-dash, #' and non-dot positions is 8, since there are 6 combinations stemming from #' position 2 after expanding the germline codon (\code{"TST"}) and the observed #' codon (\code{"THT"}). #' } #' #' @seealso See \link{observedMutations} for counting the number of observed mutations #' in a \code{data.frame}. #' #' @examples #' # Use an entry in the example data for input and germline sequence #' data(ExampleDb, package="alakazam") #' in_seq <- ExampleDb[["SEQUENCE_IMGT"]][100] #' germ_seq <- ExampleDb[["GERMLINE_IMGT_D_MASK"]][100] #' #' # Identify all mutations in the sequence #' ex1_raw <- calcObservedMutations(in_seq, germ_seq, returnRaw=TRUE) #' # Count all mutations in the sequence #' ex1_count <- calcObservedMutations(in_seq, germ_seq, returnRaw=FALSE) #' ex1_freq <- calcObservedMutations(in_seq, germ_seq, returnRaw=FALSE, frequency=TRUE) #' # Compare this with ex1_count #' table(ex1_raw$pos$region, ex1_raw$pos$R)[, "1"] #' table(ex1_raw$pos$region, ex1_raw$pos$S)[, "1"] #' # Compare this with ex1_freq #' table(ex1_raw$pos$region, ex1_raw$pos$R)[, "1"]/ex1_raw$nonN #' table(ex1_raw$pos$region, ex1_raw$pos$S)[, "1"]/ex1_raw$nonN #' #' # Identify only mutations the V segment minus CDR3 #' ex2_raw <- calcObservedMutations(in_seq, germ_seq, #' regionDefinition=IMGT_V, returnRaw=TRUE) #' # Count only mutations the V segment minus CDR3 #' ex2_count <- calcObservedMutations(in_seq, germ_seq, #' regionDefinition=IMGT_V, returnRaw=FALSE) #' ex2_freq <- calcObservedMutations(in_seq, germ_seq, #' regionDefinition=IMGT_V, returnRaw=FALSE, #' frequency=TRUE) #' # Compare this with ex2_count #' table(ex2_raw$pos$region, ex2_raw$pos$R)[, "1"] #' table(ex2_raw$pos$region, ex2_raw$pos$S)[, "1"] #' # Compare this with ex2_freq #' table(ex2_raw$pos$region, ex2_raw$pos$R)[, "1"]/ex2_raw$nonN #' table(ex2_raw$pos$region, ex2_raw$pos$S)[, "1"]/ex2_raw$nonN #' #' # Identify mutations by change in hydropathy class #' ex3_raw <- calcObservedMutations(in_seq, germ_seq, regionDefinition=IMGT_V, #' mutationDefinition=HYDROPATHY_MUTATIONS, #' returnRaw=TRUE) #' # Count mutations by change in hydropathy class #' ex3_count <- calcObservedMutations(in_seq, germ_seq, regionDefinition=IMGT_V, #' mutationDefinition=HYDROPATHY_MUTATIONS, #' returnRaw=FALSE) #' ex3_freq <- calcObservedMutations(in_seq, germ_seq, regionDefinition=IMGT_V, #' mutationDefinition=HYDROPATHY_MUTATIONS, #' returnRaw=FALSE, frequency=TRUE) #' # Compre this with ex3_count #' table(ex3_raw$pos$region, ex3_raw$pos$R)[, "1"] #' table(ex3_raw$pos$region, ex3_raw$pos$S)[, "1"] #' # Compare this with ex3_freq #' table(ex3_raw$pos$region, ex3_raw$pos$R)[, "1"]/ex3_raw$nonN #' table(ex3_raw$pos$region, ex3_raw$pos$S)[, "1"]/ex3_raw$nonN #' #' @export calcObservedMutations <- function(inputSeq, germlineSeq, regionDefinition=NULL, mutationDefinition=NULL, ambiguousMode=c("eitherOr", "and"), returnRaw=FALSE, frequency=FALSE) { ambiguousMode <- match.arg(ambiguousMode) # Check region definition if (!is.null(regionDefinition) & !is(regionDefinition, "RegionDefinition")) { stop(deparse(substitute(regionDefinition)), " is not a valid RegionDefinition object") } # Check mutation definition if (!is.null(mutationDefinition) & !is(mutationDefinition, "MutationDefinition")) { stop(deparse(substitute(mutationDefinition)), " is not a valid MutationDefinition object") } # IMPORTANT: convert to uppercase # NUCLEOTIDES, NUCLEOTIDES_AMBIGUOUS are in uppercases only inputSeq <- toupper(inputSeq) germlineSeq <- toupper(germlineSeq) # Assign mutation definition aminoAcidClasses <- if (is.null(mutationDefinition)) { NULL } else { mutationDefinition@classes } # Removing IMGT gaps (they should come in threes) # After converting ... to ZZZ any other . is not an IMGT gap & will be treated like N germlineSeq <- gsub("\\.\\.\\.", "ZZZ", germlineSeq) #If there is a single gap left convert it to an N germlineSeq <- gsub("\\.", "N", germlineSeq) # Re-assigning s_germlineSeq (now has all "." that are not IMGT gaps converted to Ns) germlineSeq <- gsub("ZZZ", "...", germlineSeq) # Removing IMGT gaps (they should come in threes) # After converting ... to ZZZ any other . is not an IMGT gap & will be treated like N inputSeq <- gsub("\\.\\.\\.", "ZZZ", inputSeq) #If there is a single gap left convert it to an N inputSeq <- gsub("\\.", "N", inputSeq) # Re-assigning s_germlineSeq (now has all "." that are not IMGT gaps converted to Ns) inputSeq <- gsub("ZZZ", "...", inputSeq) # Trim the input and germline sequence to the shortest len_inputSeq <- stri_length(inputSeq) len_germlineSeq <- stri_length(germlineSeq) # If a regionDefinition is passed, # then only analyze till the end of the defined length if(!is.null(regionDefinition)) { rdLength <- regionDefinition@seqLength } else { rdLength <- max(len_inputSeq, len_germlineSeq, na.rm=TRUE) # Create full sequence RegionDefinition object regionDefinition <- makeNullRegionDefinition(rdLength) } len_shortest <- min(c(len_inputSeq, len_germlineSeq, rdLength), na.rm=TRUE) c_inputSeq <- s2c(inputSeq)[1:len_shortest] c_germlineSeq <- s2c(germlineSeq)[1:len_shortest] # If the sequence and germline (which now should be the same length) is shorter # than the rdLength, pad it with Ns if(len_shortest 0) { # The nucleotide positions of the mutations mutations_pos <- which(mutations==TRUE) # For every mutations_pos, extract the entire codon from germline mutations_pos_codons <- array(sapply(mutations_pos, getCodonPos)) c_germlineSeq_codons <- c_germlineSeq[mutations_pos_codons] # For every mutations_pos, extract the codon from input (without other mutations # at the same codon, if any). c_inputSeq_codons <- array(sapply(mutations_pos, function(x) { seqP <- c_germlineSeq[getCodonPos(x)] seqP[getContextInCodon(x)] <- c_inputSeq[x] return(seqP) })) # split the string of codons into vector of codons c_germlineSeq_codons <- strsplit(gsub("([[:alnum:]]{3})", "\\1 ", c2s(c_germlineSeq_codons)), " ")[[1]] c_inputSeq_codons <- strsplit(gsub("([[:alnum:]]{3})", "\\1 ", c2s(c_inputSeq_codons)), " ")[[1]] # Determine whether the mutations are R or S # a table where rows are R/S/Stop/na, cols are codon positions # Count ambiguous characters as "eithe-or" or "and" based on user setting # Makes use of the fact that c_germlineSeq_codons and c_inputSeqCodons have # the same length mutations_array_raw <- sapply(1:length(c_germlineSeq_codons), function(i){ mutationType(codonFrom=c_germlineSeq_codons[i], codonTo=c_inputSeq_codons[i], ambiguousMode=ambiguousMode, aminoAcidClasses) }) # check dimension before assigning nucleotide positions to colnames stopifnot(ncol(mutations_array_raw)==length(mutations_pos)) colnames(mutations_array_raw) <- mutations_pos # keep only columns in which there are R or S mutations; and keep only R and S rows # use drop=FALSE so that matrix won't be collapsed into a vector if there is only 1 TRUE in keep.idx keep.idx <- apply(mutations_array_raw, 2, function(x) { any(x[c("R", "S")]>0) } ) keep.pos <- colnames(mutations_array_raw)[keep.idx] mutations_array_raw <- mutations_array_raw[c("R", "S"), keep.idx, drop=FALSE] colnames(mutations_array_raw) <- keep.pos # if none of columns have R or S > 1, dim will be 2x0 if ( ncol(mutations_array_raw)==0 ) { # NA if mutations_array_raw contains all NAs and they have all been removed mutations_array_raw <- NA mutations_array <- setNames(object=rep(NA, length(regionDefinition@labels)), nm=regionDefinition@labels) } else { # count each mutation type by region mutations_array <- binMutationsByRegion(mutations_array_raw, regionDefinition) } } } # frequency=TRUE overrides returnRaw=FALSE/TRUE if (frequency) { # avoid is.na(mutations_array_raw) to avoid warning in case mutations_array_raw is a vector if (length(mutations_array_raw) == sum(is.na(mutations_array_raw))) { return(mutations_array) } else { # Freq = numb of mutations / numb of non N bases (in both seq and gl) denoms <- countNonNByRegion(regDef=regionDefinition, ambiMode=ambiguousMode, inputChars=c_inputSeq, germChars=c_germlineSeq, inputCodons=c_inputSeq_codons, germCodons=c_germlineSeq_codons, mutPos=mutations_pos) mutations_array <- mutations_array/rep(denoms, each=2) return(mutations_array) } } # return positions of point mutations and their mutation types ("raw") if (returnRaw){ if (length(mutations_array_raw) == sum(is.na(mutations_array_raw))) { # if mutations_array_raw is NA, or # if mutations_array_raw is empty due to all mutations being "Stop" and hence removed # avoid is.na(mutations_array_raw) to avoid warning in case mutations_array_raw is a vector if (!tooShort) { # when input and germline are >=3 nucleotides but there's no mutation # c_inputSeq_codons, c_germlineSeq_codons, and mutations_pos won't exist # this won't be a problem if ambiguousMode="eitherOr", but would for "and" # set inputCodons, germCodons, and mutPos to NULL to work around that nonN.denoms <- countNonNByRegion(regDef=regionDefinition, ambiMode=ambiguousMode, inputChars=c_inputSeq, germChars=c_germlineSeq, inputCodons=NULL, germCodons=NULL, mutPos=NULL) } else { nonN.denoms <- setNames(object=rep(NA, length(regionDefinition@regions)), nm=regionDefinition@regions) } return(list(pos=mutations_array_raw, nonN=nonN.denoms)) } else { nonN.denoms <- countNonNByRegion(regDef=regionDefinition, ambiMode=ambiguousMode, inputChars=c_inputSeq, germChars=c_germlineSeq, inputCodons=c_inputSeq_codons, germCodons=c_germlineSeq_codons, mutPos=mutations_pos) # df indicating position, mutation type (R or S), and region of each mutation rawDf <- data.frame(as.numeric(colnames(mutations_array_raw))) rawDf <- cbind(rawDf, mutations_array_raw["R", ], mutations_array_raw["S", ], as.character(regionDefinition@boundaries[as.numeric(colnames(mutations_array_raw))]), stringsAsFactors=F) colnames(rawDf) <- c("position", "R", "S", "region") return(list(pos=rawDf, nonN=nonN.denoms)) } } else { # return counts of each mutation type return(mutations_array) } } # Aggregate mutations by region # # \code{binMutationsByRegion} takes an array of observed mutations (e.g. from # \code{calcObservedMutations}) and bins them by the different regions defined in the # \code{regionDefinition}. # # @param mutationsArray \code{array} containing the number of R and S mutations # at the nucleotide positions where there are mutations. # @param regionDefinition \link{RegionDefinition} object defining the regions # and boundaries of the Ig sequences. # # @return An \code{array} of R/S mutations binned across all the unique regions defined # by \code{regionDefinition}. # # @details # Note, only the part of sequences defined in \code{regionDefinition} are analyzed. # For example, if the default \link{IMGT_V} definition is used, then mutations # in positions beyond 312 will be ignored. # # @seealso # See \link{observedMutations} for identifying and counting the # number of observed mutations. # This function is also used in \link{calcObservedMutations}. # # @examples # # Generate a random mutation array # numbOfMutPos <- sample(3:10, 1) # posOfMutations <- sort(sample(330, numbOfMutPos)) # mutations_array <- matrix(0, nrow=2, ncol=numbOfMutPos, dimnames=list(c("R", "S"), posOfMutations)) # mutations_array["R", ] = sample(x=0:10, size=numbOfMutPos, replace=TRUE) # mutations_array["S", ] = sample(x=0:10, size=numbOfMutPos, replace=TRUE) # # Random mutations # binMutationsByRegion(mutations_array, regionDefinition=NULL) # binMutationsByRegion(mutations_array, regionDefinition=IMGT_V) binMutationsByRegion <- function(mutationsArray, regionDefinition=NULL) { # Check region definition if (!is.null(regionDefinition) & !is(regionDefinition, "RegionDefinition")) { stop(deparse(substitute(regionDefinition)), " is not a valid RegionDefinition object") } # Create full sequence RegionDefinition object # The seqLength will be the largest index of a mutation if (is.null(regionDefinition)) { regionDefinition <- makeNullRegionDefinition(max(as.numeric(colnames(mutationsArray)))) } # get 2 vectors, 1 for R, 1 for S, along length of 1:regionDefinition@seqLength # each vector records the number of R/S at each position mutatedPositions <- as.numeric(colnames(mutationsArray)) mutations_R <- array(NA, dim=regionDefinition@seqLength) mutations_S <- array(NA, dim=regionDefinition@seqLength) mutations_R[mutatedPositions] <- mutationsArray["R", ] mutations_S[mutatedPositions] <- mutationsArray["S", ] mutations_R <- mutations_R[1:regionDefinition@seqLength] mutations_S <- mutations_S[1:regionDefinition@seqLength] # count number of R/S in each region mutations_region_counts <- rep(0, length(regionDefinition@labels)) names(mutations_region_counts) <- regionDefinition@labels for (reg in regionDefinition@regions) { mutations_region_counts[paste0(reg, "_R")] <- sum(mutations_R[regionDefinition@boundaries==reg], na.rm=T) mutations_region_counts[paste0(reg, "_S")] <- sum(mutations_S[regionDefinition@boundaries==reg], na.rm=T) } return(mutations_region_counts) } # Count the number of non-N, non-dash, and non-dot positions # # @param regDef regionDefinition # @param ambiMode ambiguousMode # @param inputChars c_inputSeq # @param germChars c_germlineSeq # @param inputCodons c_inputSeq_codons # @param germCodons c_germlineSeq_codons # @param mutPos mutations_pos # # @return The number of non-N, non-dash, and non-dot characters. Calculation method # differs depending on ambiMode being "eitherOr" or "and". By design, when # there is no ambiguous character in the input or germline, the result should be # the same regardless of ambiMode. # # @details This is a helper function for calcObservedMutations() and is not intended to # be called directly. All input arguments are, by design, expected to be # generated as intermediate products during a call to calcObservedMutations(). # countNonNByRegion <- function(regDef, ambiMode, inputChars, germChars, inputCodons, germCodons, mutPos) { regionNames <- unique(sapply(regDef@labels, function(x) { substr(x, 1, stri_length(x)-2) })) if (ambiMode=="eitherOr") { # Subset boundaries to only non-N & non-dash & non-dot bases (in both seq and gl) # "which" in next line is ESSENTIAL; otherwise @boundaries won't be truncated # e.g. (1:6)[c(T,T,T)] returns 1:6, not 1:3 boundaries <- regDef@boundaries[ which(inputChars %in% NUCLEOTIDES_AMBIGUOUS[1:14] & germChars %in% NUCLEOTIDES_AMBIGUOUS[1:14])] # number of non-N & non-dash & non-dot bases (in both seq and gl) nonN <- sapply(regionNames, function(x) { sum(boundaries==x) }) } else if (ambiMode=="and") { ### positions where there's no mutation: # simply count the positions where both input and germline are # non-N, non-dash, and non-dot boundaries.1 <- regDef@boundaries[ which(inputChars %in% NUCLEOTIDES_AMBIGUOUS[1:14] & germChars %in% NUCLEOTIDES_AMBIGUOUS[1:14] & (germChars == inputChars))] nonN.1 <- sapply(regionNames, function(x) { sum(boundaries.1==x) }) ### positions where there's mutation: if ( (!is.null(inputCodons)) & (!is.null(germCodons)) & (!is.null(mutPos)) ) { # expand codon with ambiguous character(s) into codons with unambiguous characters # calculate the number of possible combinations between input and germline codons # this makes use of the important fact that each mutation is considered # independently in the germline context inputNumExpanded <- sapply(inputCodons, function(codon){ length(EXPANDED_AMBIGUOUS_CODONS[[codon]]) }) germlineNumExpanded <- sapply(germCodons, function(codon){ length(EXPANDED_AMBIGUOUS_CODONS[[codon]]) }) totalNumExpanded <- inputNumExpanded * germlineNumExpanded # use mutations_pos to capture positions at which R/S is absent (Stop or na instead) # such positions would have been omitted from mutations_array_raw or mutations_array boundaries.2 <- regDef@boundaries[mutPos] # makes use of the fact that inputCodons, germCodons, and # mutPos align exactly nonN.2 <- sapply(regionNames, function(x){ sum(totalNumExpanded[boundaries.2==x]) }) } else { nonN.2 <- setNames(object=rep(0, length(regionNames)), nm=regionNames) } nonN <- nonN.1 + nonN.2 } return(nonN) } #### Sliding window approach #### #' Sliding window approach towards filtering a single sequence #' #' \code{slideWindowSeq} determines whether an input sequence contains equal to or more than #' a given number of mutations in a given length of consecutive nucleotides (a "window") #' when compared to a germline sequence. #' #' @param inputSeq input sequence. #' @param germlineSeq germline sequence. #' @param mutThresh threshold on the number of mutations in \code{windowSize} #' consecutive nucleotides. Must be between 1 and \code{windowSize} #' inclusive. #' @param windowSize length of consecutive nucleotides. Must be at least 2. #' #' @return \code{TRUE} if there are equal to or more than \code{mutThresh} number of mutations #' in any window of \code{windowSize} consecutive nucleotides (i.e. the sequence should #' be filtered); \code{FALSE} if otherwise. #' #' @seealso \link{calcObservedMutations} is called by \code{slideWindowSeq} to identify observed #' mutations. See \link{slideWindowDb} for applying the sliding window approach on a #' \code{data.frame}. See \link{slideWindowTune} for parameter tuning for \code{mutThresh} #' and \code{windowSize}. #' #' @examples #' # Use an entry in the example data for input and germline sequence #' data(ExampleDb, package="alakazam") #' in_seq <- ExampleDb[100, "SEQUENCE_IMGT"] #' germ_seq <- ExampleDb[100, "GERMLINE_IMGT_D_MASK"] #' #' # Determine if in_seq has 6 or more mutations in 10 consecutive nucleotides #' slideWindowSeq(inputSeq=in_seq, germlineSeq=germ_seq, mutThresh=6, windowSize=10) #' #' @export slideWindowSeq <- function(inputSeq, germlineSeq, mutThresh, windowSize){ # identify all R and S mutations in input sequence inputMut <- calcObservedMutations(inputSeq=inputSeq, germlineSeq=germlineSeq, returnRaw=T) # call helper return(slideWindowSeqHelper(mutPos=inputMut$pos, mutThresh=mutThresh, windowSize=windowSize)) } # NOTE: DO NOT MERGE slideWindowSeqHelper with slideWindowSeq (very different input formats) # slideWindowTune needs to call slideWindowSeqHelper directly for efficiency # Helper for sliding window approach towards filtering sequences # # @param mutPos a \code{data.frame} containing positions and types of point # mutations as returned in \code{$pos} by # \code{calcObserverdMutations()} with \code{returnRaw=TRUE}. # Can be \code{NA}, in which case the returned value will be # \code{FALSE}. # @param mutThresh threshold on the number of mutations in \code{windowSize} # consecutive nucleotides. Must be between 1 and \code{windowSize} # inclusive. # @param windowSize length of consecutive nucleotides. Must be at least 2. # # @return \code{TRUE} if there are equal to or more than \code{mutThresh} number of mutations # in any window of \code{windowSize} consecutive nucleotides; \code{FALSE} if otherwise. # slideWindowSeqHelper <- function(mutPos, mutThresh, windowSize){ # check preconditions stopifnot(mutThresh >= 1 & mutThresh <= windowSize & windowSize>=2) if (length(mutPos) == 1 && is.na(mutPos)) { # use && instead of & to short-circuit in case length(mutPos)!=1 (otherwise warning) return(FALSE) } else { # general idea: # only need to check windows containing mutations (as opposed to every possible window) for (i in 1:nrow(mutPos)){ # get window limits lower <- mutPos$position[i] upper <- lower + windowSize - 1 # how many mutations fall within current window windowCount <- sum(mutPos[mutPos$position>=lower & mutPos$position<=upper, c("R","S")]) # return as soon as a window has >= mutThresh mutations if (windowCount >= mutThresh) { return(TRUE) } } return(FALSE) } } #' Sliding window approach towards filtering sequences in a \code{data.frame} #' #' \code{slideWindowDb} determines whether each input sequence in a \code{data.frame} #' contains equal to or more than a given number of mutations in a given length of #' consecutive nucleotides (a "window") when compared to their respective germline #' sequence. #' #' @param db \code{data.frame} containing sequence data. #' @param sequenceColumn name of the column containing IMGT-gapped sample sequences. #' @param germlineColumn name of the column containing IMGT-gapped germline sequences. #' @param mutThresh threshold on the number of mutations in \code{windowSize} #' consecutive nucleotides. Must be between 1 and \code{windowSize} #' inclusive. #' @param windowSize length of consecutive nucleotides. Must be at least 2. #' #' @return a logical vector. The length of the vector matches the number of input sequences in #' \code{db}. Each entry in the vector indicates whether the corresponding input sequence #' should be filtered based on the given parameters. #' #' @seealso See \link{slideWindowSeq} for applying the sliding window approach on a single sequence. #' See \link{slideWindowTune} for parameter tuning for \code{mutThresh} and \code{windowSize}. #' #' @examples #' # Use an entry in the example data for input and germline sequence #' data(ExampleDb, package="alakazam") #' #' # Apply the sliding window approach on a subset of ExampleDb #' slideWindowDb(db = ExampleDb[1:10, ], mutThresh=6, windowSize=10) #' #' @export slideWindowDb <- function(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", mutThresh, windowSize){ db_filter <- sapply(1:nrow(db), function(i) { slideWindowSeq(inputSeq = db[i, sequenceColumn], germlineSeq = db[i, germlineColumn], mutThresh = mutThresh, windowSize = windowSize)}) return(db_filter) } #' Parameter tuning for sliding window approach #' #' Apply \link{slideWindowDb} over a search grid made of combinations of \code{mutThresh} and #' \code{windowSize} to help with picking a pair of values for these parameters. Parameter #' tuning can be performed by choosing a combination that gives a reasonable number of #' filtered/remaining sequences. #' #' @param db \code{data.frame} containing sequence data. #' @param sequenceColumn name of the column containing IMGT-gapped sample sequences. #' @param germlineColumn name of the column containing IMGT-gapped germline sequences. #' @param dbMutList if supplied, this should be a list consisting of \code{data.frame}s #' returned as \code{$pos} in the nested list produced by #' \link{calcObservedMutations} with \code{returnRaw=TRUE}; otherwise, #' \link{calcObservedMutations} is called on columns \code{sequenceColumn} #' and \code{germlineColumn} of \code{db}. Default is \code{NULL}. #' @param mutThreshRange range of threshold on the number of mutations in \code{windowSize} #' consecutive nucleotides to try. Must be between 1 and #' maximum \code{windowSizeRange} inclusive. #' @param windowSizeRange range of length of consecutive nucleotides to try. The lower end #' must be at least 2. #' @param verbose whether to print out messages indicating current progress. Default #' is \code{TRUE}. #' #' @return a list of logical matrices. Each matrix corresponds to a \code{windowSize} in #' \code{windowSizeRange}. Each column in a matrix corresponds to a \code{mutThresh} in #' \code{mutThreshRange}. #' #' @details If, in a given combination of \code{mutThresh} and \code{windowSize}, \code{mutThresh} #' is greater than \code{windowSize}, \code{NA}s will be returned for that particular #' combination. A message indicating that the combination has been "skipped" will be #' printed if \code{verbose=TRUE}. #' #' If \link{calcObservedMutations} was previously run on \code{db} and saved, supplying #' \code{$pos} from the saved result as \code{dbMutList} could save time by skipping a #' second call of \link{calcObservedMutations}. This could be helpful especially when #' \code{db} is large. #' #' @seealso \link{slideWindowDb} is called on \code{db} for tuning. See \link{slideWindowTunePlot} #' for visualization. See \link{calcObservedMutations} for generating \code{dbMutList}. #' #' @examples #' # Load and subset example data #' data(ExampleDb, package="alakazam") #' db <- ExampleDb[1:5, ] #' #' # Try out thresholds of 2-4 mutations in window sizes of 7-9 nucleotides. #' # In this case, all combinations are legal. #' slideWindowTune(db, mutThreshRange=2:4, windowSizeRange=7:9) #' #' # Illegal combinations are skipped, returning NAs. #' slideWindowTune(db, mutThreshRange=2:4, windowSizeRange=2:4, #' verbose=FALSE) #' #' # Run calcObservedMutations separately #' exDbMutList <- sapply(1:5, function(i) { #' calcObservedMutations(inputSeq=db[i, "SEQUENCE_IMGT"], #' germlineSeq=db[i, "GERMLINE_IMGT_D_MASK"], #' returnRaw=TRUE)$pos }) #' slideWindowTune(db, dbMutList=exDbMutList, #' mutThreshRange=2:4, windowSizeRange=2:4) #' #' @export slideWindowTune <- function(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", dbMutList=NULL, mutThreshRange, windowSizeRange, verbose=TRUE){ # check preconditions stopifnot(!is.null(db)) stopifnot(min(mutThreshRange) >= 1 & max(mutThreshRange) <= max(windowSizeRange) & min(windowSizeRange) >= 2) # get positions of R/S mutations for sequences in db # do this here and then call slideWindowSeqHelper (so it's done only once) # instead of calling slideWindowDb which does this every time it is called if (is.null(dbMutList)) { inputMutList <- sapply(1:nrow(db), function(i){ calcObservedMutations(inputSeq=db[i, sequenceColumn], germlineSeq=db[i, germlineColumn], returnRaw=T)$pos}) } else { if (verbose) {cat("dbMutList supplied; skipped calling calcObservedMutations()\n")} inputMutList <- dbMutList } # apply slideWindow on combinations of windowSize and mutThresh for (size in windowSizeRange) { if (verbose) {cat(paste0("now computing for windowSize = ", size, "\n"))} for (thresh in mutThreshRange) { if (thresh <= size){ if (verbose) {cat(paste0(">>> mutThresh = ", thresh, "\n"))} # apply slideWindow using current pair of parameters cur.logical <- unlist(lapply(inputMutList, slideWindowSeqHelper, mutThresh = thresh, windowSize = size)) } else { if (verbose) {cat(paste0(">>> mutThresh = ", thresh, " > windowSize = ", size, " (skipped)\n"))} # NA if skipped cur.logical <- rep(NA, nrow(db)) } # store results for each thresh as a column in a logical matrix if (thresh == mutThreshRange[1]) { cur.mtx <- matrix(data=cur.logical, nrow=length(cur.logical)) } else { cur.mtx <- cbind(cur.mtx, cur.logical) } } colnames(cur.mtx) <- as.character(mutThreshRange) # store results for each size (and threshes under that size) as a logical matrix in a list if (size == windowSizeRange[1]) { cur.list <- list(cur.mtx) } else { cur.list <- c(cur.list, list(cur.mtx)) } } names(cur.list) <- as.character(windowSizeRange) return(cur.list) } #' Visualize parameter tuning for sliding window approach #' #' Visualize results from \link{slideWindowTune} #' #' @param tuneList a list of logical matrices returned by \link{slideWindowTune}. #' @param plotFiltered whether to plot the number of filtered sequences (as opposed to #' the number of remaining sequences). Default is \code{TRUE}. #' @param percentage whether to plot on the y-axis the percentage of filtered sequences #' (as opposed to the absolute number). Default is \code{FALSE}. #' @param jitter.x whether to jitter x-axis values. Default is \code{FALSE}. #' @param jitter.x.amt amount of jittering to be applied on x-axis values if #' \code{jitter.x=TRUE}. Default is 0.1. #' @param jitter.y whether to jitter y-axis values. Default is \code{FALSE}. #' @param jitter.y.amt amount of jittering to be applied on y-axis values if #' \code{jitter.y=TRUE}. Default is 0.1. #' @param pchs point types to pass on to \link{plot}. #' @param ltys line types to pass on to \link{plot}. #' @param cols colors to pass on to \link{plot}. #' @param plotLegend whether to plot legend. Default is \code{TRUE}. #' @param legendPos position of legend to pass on to \link{legend}. Can be either a #' numeric vector specifying x-y coordinates, or one of #' \code{"topright"}, \code{"center"}, etc. Default is \code{"topright"}. #' @param legendHoriz whether to make legend horizontal. Default is \code{FALSE}. #' @param legendCex numeric values by which legend should be magnified relative to 1. #' @param title plot main title. Default is NULL (no title) #' #' @details For each \code{windowSize}, the numbers of sequences filtered or remaining after applying #' the sliding window approach are plotted on the y-axis against thresholds on the number of #' mutations in a window on the x-axis. #' #' When plotting, a user-defined \code{amount} of jittering can be applied on values plotted #' on either axis or both axes via adjusting \code{jitter.x}, \code{jitter.y}, #' \code{jitter.x.amt} and \code{jitter.y.amt}. This may be help with visually distinguishing #' lines for different window sizes in case they are very close or identical to each other. #' If plotting percentages (\code{percentage=TRUE}) and using jittering on the y-axis values #' (\code{jitter.y=TRUE}), it is strongly recommended that \code{jitter.y.amt} be set very #' small (e.g. 0.01). #' #' \code{NA} for a combination of \code{mutThresh} and \code{windowSize} where #' \code{mutThresh} is greater than \code{windowSize} will not be plotted. #' #' @seealso See \link{slideWindowTune} for how to get \code{tuneList}. See \link{jitter} for #' use of \code{amount} of jittering. #' #' @examples #' # Use an entry in the example data for input and germline sequence #' data(ExampleDb, package="alakazam") #' #' # Try out thresholds of 2-4 mutations in window sizes of 3-5 nucleotides #' # on a subset of ExampleDb #' tuneList <- slideWindowTune(db = ExampleDb[1:10, ], #' mutThreshRange = 2:4, windowSizeRange = 3:5, #' verbose = FALSE) #' #' # Visualize #' # Plot numbers of sequences filtered without jittering y-axis values #' slideWindowTunePlot(tuneList, pchs=1:3, ltys=1:3, cols=1:3, #' plotFiltered=TRUE, jitter.y=FALSE) #' #' # Notice that some of the lines overlap #' # Jittering could help #' slideWindowTunePlot(tuneList, pchs=1:3, ltys=1:3, cols=1:3, #' plotFiltered=TRUE, jitter.y=TRUE) #' #' # Plot numbers of sequences remaining instead of filtered #' slideWindowTunePlot(tuneList, pchs=1:3, ltys=1:3, cols=1:3, #' plotFiltered=FALSE, jitter.y=TRUE, #' legendPos="bottomright") #' #' # Plot percentages of sequences filtered with a tiny amount of jittering #' slideWindowTunePlot(tuneList, pchs=1:3, ltys=1:3, cols=1:3, #' plotFiltered=TRUE, percentage=TRUE, #' jitter.y=TRUE, jitter.y.amt=0.01) #' #' @export slideWindowTunePlot <- function(tuneList, plotFiltered = TRUE, percentage = FALSE, jitter.x = FALSE, jitter.x.amt = 0.1, jitter.y = FALSE, jitter.y.amt = 0.1, pchs = 1, ltys = 2, cols = 1, plotLegend = TRUE, legendPos = "topright", legendHoriz = FALSE, legendCex = 1, title=NULL){ # invert (!) tuneList if plotting retained sequences ylab.part.2 <- "filtered" if (!plotFiltered) { tuneList <- lapply(tuneList, function(x){!x}) ylab.part.2 <- "remaining"} # if number of pchs/ltys/cols provided does not match number of lines expected # expand into vector with repeating values (otherwise legend would break) if (length(pchs)!=length(tuneList)) {pchs <- rep(pchs, length.out=length(tuneList))} if (length(ltys)!=length(tuneList)) {ltys <- rep(ltys, length.out=length(tuneList))} if (length(cols)!=length(tuneList)) {cols <- rep(cols, length.out=length(tuneList))} # tabulate tuneList (and if applicable convert to percentage) plotList <- lapply(tuneList, colSums) if (percentage) {plotList <- lapply(plotList, function(x){x/nrow(tuneList[[1]])})} # get x-axis values (i.e. mutThreshRange; colnames of matrix in tuneList with most columns) #threshes = as.numeric(colnames(tuneList[[which.max(lapply(lapply(tuneList, colnames), length))]])) threshes <- as.numeric(colnames(tuneList[[1]])) # plot for first window size x1 <- threshes if (jitter.x) {x1 <- jitter(x1, amount=jitter.x.amt)} y1 <- plotList[[1]] if (jitter.y) {y1 <- jitter(y1, amount=jitter.y.amt)} if (percentage) { ylab.part.1 <- "Percentage of sequences" # ylim ylim.padding <- abs(diff(range(plotList, na.rm=T)))*0.01 ylims <- c(max(0, min(range(plotList, na.rm=T)) - ylim.padding), min(1, max(range(plotList, na.rm=T)) + ylim.padding) ) } else { ylab.part.1 <- "Number of sequences" # ylim: non-negative lower limit; upper limit slight above max tabulated sum ylims <- c( max(0, min(range(plotList, na.rm=T)) - max(1, jitter.y.amt) ), max(range(plotList, na.rm=T)) + max(1, jitter.y.amt) ) } plot(x1, # mutThreshRange on x-axis y1, # tabulated sums in plotList on y-axis ylim = ylims, # xlim: +/- jitter.x.amt*2 to accommodate for amount of jittering on x-axis xlim = c(min(threshes)-jitter.x.amt*2, max(threshes+jitter.x.amt*2)), xaxt="n", xlab="Threshold on number of mutations", ylab=paste(ylab.part.1, ylab.part.2), cex.lab=1.5, cex.axis=1.5, type="b", lwd=1.5, pch=pchs[1], lty=ltys[1], col=cols[1]) axis(side=1, at=threshes, cex.axis=1.5) # add title if (!is.null(title)) { title(main=title) } # plot for the rest of the window sizes for (i in 1:length(plotList)){ if (i>=2) { xi <- threshes if (jitter.x) {xi <- jitter(xi, amount=jitter.x.amt)} yi <- plotList[[i]] if (jitter.y) {yi <- jitter(yi, amount=jitter.y.amt)} points(xi, yi, type='b', lwd=1.5, pch=pchs[i], lty=ltys[i], col=cols[i]) } } # add legend if (plotLegend) { # if legendPos specified as xy coordinates if (is.numeric(legendPos) & length(legendPos)==2) { legend(x=legendPos[1], y=legendPos[2], legend = c("Window Size", names(tuneList)), horiz = legendHoriz, cex = legendCex, pch=c(NA, pchs), lty=c(NA, ltys), col=c(NA, cols)) } else { # if legendPos specified as "center", "topright", etc. legend(legendPos, legend = c("Window Size", names(tuneList)), horiz = legendHoriz, cex = legendCex, pch=c(NA, pchs), lty=c(NA, ltys), col=c(NA, cols)) } } } #### Expected frequencies calculating functions #### #' Calculate expected mutation frequencies #' #' \code{expectedMutations} calculates the expected mutation frequencies for each #' sequence in the input \code{data.frame}. #' #' @param db \code{data.frame} containing sequence data. #' @param sequenceColumn \code{character} name of the column containing input #' sequences. #' @param germlineColumn \code{character} name of the column containing #' the germline or reference sequence. #' @param targetingModel \link{TargetingModel} object. Default is \link{HH_S5F}. #' @param regionDefinition \link{RegionDefinition} object defining the regions #' and boundaries of the Ig sequences. #' @param mutationDefinition \link{MutationDefinition} object defining replacement #' and silent mutation criteria. If \code{NULL} then #' replacement and silent are determined by exact #' amino acid identity. #' @param nproc \code{numeric} number of cores to distribute the operation #' over. If the cluster has already been set the call function with #' \code{nproc} = 0 to not reset or reinitialize. Default is #' \code{nproc} = 1. #' #' @return A modified \code{db} \code{data.frame} with expected mutation frequencies #' for each region defined in \code{regionDefinition}. #' #' The columns names are dynamically created based on the regions in #' \code{regionDefinition}. For example, when using the \link{IMGT_V} #' definition, which defines positions for CDR and FWR, the following columns are #' added: #' \itemize{ #' \item \code{MU_EXPECTED_CDR_R}: number of replacement mutations in CDR1 and #' CDR2 of the V-segment. #' \item \code{MU_EXPECTED_CDR_S}: number of silent mutations in CDR1 and CDR2 #' of the V-segment. #' \item \code{MU_EXPECTED_FWR_R}: number of replacement mutations in FWR1, #' FWR2 and FWR3 of the V-segment. #' \item \code{MU_EXPECTED_FWR_S}: number of silent mutations in FWR1, FWR2 and #' FWR3 of the V-segment. #' } #' #' @details #' Only the part of the sequences defined in \code{regionDefinition} are analyzed. #' For example, when using the \link{IMGT_V} definition, mutations in #' positions beyond 312 will be ignored. #' #' @seealso #' \link{calcExpectedMutations} is called by this function to calculate the expected #' mutation frequencies. See \link{observedMutations} for getting observed #' mutation counts. See \link{IMGT_SCHEMES} for a set of predefined #' \link{RegionDefinition} objects. #' #' @examples #' # Subset example data #' data(ExampleDb, package="alakazam") #' db <- subset(ExampleDb, ISOTYPE %in% c("IgA", "IgG") & SAMPLE == "+7d") #' #' # Calculate expected mutations over V region #' db_exp <- expectedMutations(db, #' sequenceColumn="SEQUENCE_IMGT", #' germlineColumn="GERMLINE_IMGT_D_MASK", #' regionDefinition=IMGT_V, #' nproc=1) #' #' # Calculate hydropathy expected mutations over V region #' db_exp <- expectedMutations(db, #' sequenceColumn="SEQUENCE_IMGT", #' germlineColumn="GERMLINE_IMGT_D_MASK", #' regionDefinition=IMGT_V, #' mutationDefinition=HYDROPATHY_MUTATIONS, #' nproc=1) #' #' @export expectedMutations <- function(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", targetingModel=HH_S5F, regionDefinition=NULL, mutationDefinition=NULL, nproc=1) { # Hack for visibility of foreach index variable idx <- NULL # Check for valid columns check <- checkColumns(db, c(sequenceColumn, germlineColumn)) if (check != TRUE) { stop(check) } # Check region definition if (!is.null(regionDefinition) & !is(regionDefinition, "RegionDefinition")) { stop(deparse(substitute(regionDefinition)), " is not a valid RegionDefinition object") } # Check mutation definition if (!is.null(mutationDefinition) & !is(mutationDefinition, "MutationDefinition")) { stop(deparse(substitute(mutationDefinition)), " is not a valid MutationDefinition object") } # Check if mutation count/freq columns already exist # and throw overwritting warning if (!is.null(regionDefinition)) { labels <- regionDefinition@labels } else { labels <- makeNullRegionDefinition()@labels } labels <- paste("MU_EXPECTED_", labels, sep="") label_exists <- labels[labels %in% colnames(db)] if (length(label_exists)>0) { warning(paste0("Columns ", paste(label_exists, collapse=", "), " exist and will be overwritten") ) db[label_exists] <- NULL } # Check targeting model if (!is(targetingModel, "TargetingModel")) { stop(deparse(substitute(targetingModel)), " is not a valid TargetingModel object") } # Convert sequence columns to uppercase db <- toupperColumns(db, c(sequenceColumn, germlineColumn)) # If the user has previously set the cluster and does not wish to reset it if(!is.numeric(nproc)){ cluster = nproc nproc = 0 } # Ensure that the nproc does not exceed the number of cores/CPUs available nproc <- min(nproc, cpuCount(), na.rm=T) # If user wants to paralellize this function and specifies nproc > 1, then # initialize and register slave R processes/clusters & # export all nesseary environment variables, functions and packages. if (nproc > 1) { cluster <- parallel::makeCluster(nproc, type = "PSOCK") parallel::clusterExport(cluster, list('db', 'sequenceColumn', 'germlineColumn', 'regionDefinition','targetingModel', 'calcExpectedMutations','calculateTargeting', 's2c','c2s','NUCLEOTIDES','HH_S5F', 'calculateMutationalPaths','CODON_TABLE'), envir=environment() ) registerDoParallel(cluster) } else if (nproc == 1) { # If needed to run on a single core/cpu then, regsiter DoSEQ # (needed for 'foreach' in non-parallel mode) registerDoSEQ() } # Printing status to console cat("Calculating the expected frequencies of mutations...\n") # Calculate targeting for each sequence (based on the germline) # Should be a 5 x N matrix where N in the number of nucleotides defined by # the regionDefinition numbOfSeqs <- nrow(db) targeting_list <- foreach (idx=iterators::icount(numbOfSeqs)) %dopar% { calcExpectedMutations(germlineSeq=db[[germlineColumn]][idx], inputSeq=db[[sequenceColumn]][idx], targetingModel=targetingModel, regionDefinition=regionDefinition, mutationDefinition=mutationDefinition) } # Convert list of expected mutation freq to data.frame if (is.null(regionDefinition)) { labels_length <- length(makeNullRegionDefinition()@labels) } else { labels_length <- length(regionDefinition@labels) } expectedMutationFrequencies <- do.call(rbind, lapply(targeting_list, function(x) { length(x) <- labels_length return(x) })) expectedMutationFrequencies[is.na(expectedMutationFrequencies)] <- 0 colnames(expectedMutationFrequencies) <- paste0("MU_EXPECTED_", colnames(expectedMutationFrequencies)) # Properly shutting down the cluster if(nproc>1){ parallel::stopCluster(cluster) } # Bind the observed mutations to db db_new <- cbind(db, expectedMutationFrequencies) return(db_new) } #' Calculate expected mutation frequencies of a sequence #' #' \code{calcExpectedMutations} calculates the expected mutation #' frequencies of a given sequence. This is primarily a helper function for #' \link{expectedMutations}. #' #' @param germlineSeq germline (reference) sequence. #' @param inputSeq input (observed) sequence. If this is not \code{NULL}, #' then \code{germlineSeq} will be processed to be the same #' same length as \code{inputSeq} and positions in #' \code{germlineSeq} corresponding to positions with Ns in #' \code{inputSeq} will also be assigned an N. #' @param targetingModel \link{TargetingModel} object. Default is \link{HH_S5F}. #' @param regionDefinition \link{RegionDefinition} object defining the regions #' and boundaries of the Ig sequences. #' @param mutationDefinition \link{MutationDefinition} object defining replacement #' and silent mutation criteria. If \code{NULL} then #' replacement and silent are determined by exact #' amino acid identity. #' #' @return A \code{numeric} vector of the expected frequencies of mutations in the #' regions in the \code{regionDefinition}. For example, when using the default #' \link{IMGT_V} definition, which defines positions for CDR and #' FWR, the following columns are calculated: #' \itemize{ #' \item \code{MU_EXPECTED_CDR_R}: number of replacement mutations in CDR1 and #' CDR2 of the V-segment. #' \item \code{MU_EXPECTED_CDR_S}: number of silent mutations in CDR1 and CDR2 #' of the V-segment. #' \item \code{MU_EXPECTED_FWR_R}: number of replacement mutations in FWR1, #' FWR2 and FWR3 of the V-segment. #' \item \code{MU_EXPECTED_FWR_S}: number of silent mutations in FWR1, FWR2 and #' FWR3 of the V-segment. #' } #' #' @details #' \code{calcExpectedMutations} calculates the expected mutation frequencies of a #' given sequence and its germline. #' #' Note, only the part of the sequences defined in \code{regionDefinition} are analyzed. #' For example, when using the default \link{IMGT_V} definition, mutations in #' positions beyond 312 will be ignored. #' #' @seealso \link{expectedMutations} calls this function. #' To create a custom \code{targetingModel} see \link{createTargetingModel}. #' See \link{calcObservedMutations} for getting observed mutation counts. #' #' @examples #' # Load example data #' data(ExampleDb, package="alakazam") #' #' # Use first entry in the exampled data for input and germline sequence #' in_seq <- ExampleDb[["SEQUENCE_IMGT"]][1] #' germ_seq <- ExampleDb[["GERMLINE_IMGT_D_MASK"]][1] #' #' # Identify all mutations in the sequence #' calcExpectedMutations(in_seq, germ_seq) #' #' # Identify only mutations the V segment minus CDR3 #' calcExpectedMutations(in_seq, germ_seq, regionDefinition=IMGT_V) #' #' # Define mutations based on hydropathy #' calcExpectedMutations(in_seq, germ_seq, regionDefinition=IMGT_V, #' mutationDefinition=HYDROPATHY_MUTATIONS) #' #' @export calcExpectedMutations <- function(germlineSeq, inputSeq=NULL, targetingModel=HH_S5F, regionDefinition=NULL, mutationDefinition=NULL) { # Check region definition if (!is.null(regionDefinition) & !is(regionDefinition, "RegionDefinition")) { stop(deparse(substitute(regionDefinition)), " is not a valid RegionDefinition object") } # Check mutation definition if (!is.null(mutationDefinition) & !is(mutationDefinition, "MutationDefinition")) { stop(deparse(substitute(mutationDefinition)), " is not a valid MutationDefinition object") } # Check targeting model if (!is(targetingModel, "TargetingModel")) { stop(deparse(substitute(targetingModel)), " is not a valid TargetingModel object") } # Mask ambiguous nucleotide characters germlineSeq <- gsub("[MRWSYKVHDB]", "N", germlineSeq) # Assign codon table codonTable <- if (is.null(mutationDefinition)) { CODON_TABLE } else { mutationDefinition@codonTable } # Get targeting targeting <- calculateTargeting(germlineSeq=germlineSeq, inputSeq=inputSeq, targetingModel=targetingModel, regionDefinition=regionDefinition) # Determine the mutations paths (i.e. determine R and S mutation frequencies) mutationalPaths <- calculateMutationalPaths(germlineSeq=c2s(colnames(targeting)), regionDefinition=regionDefinition, codonTable=codonTable) typesOfMutations <- c("R", "S") mutationalPaths[!(mutationalPaths %in% typesOfMutations)] <- NA if (is.null(regionDefinition)) { rdLength <- max(stri_length(inputSeq), stri_length(germlineSeq), na.rm=TRUE) regionDefinition <- makeNullRegionDefinition(rdLength) } listExpectedMutationFrequencies <- list() for(region in regionDefinition@regions){ for(typeOfMutation in typesOfMutations){ region_mutation <- paste(region, typeOfMutation, sep="_") targeting_region <- targeting[1:4, regionDefinition@boundaries %in% region] mutationalPaths_region <- mutationalPaths[, regionDefinition@boundaries[1:ncol(mutationalPaths)] %in% region] targeting_typeOfMutation_region <- sum(targeting_region[mutationalPaths_region == typeOfMutation], na.rm=TRUE) listExpectedMutationFrequencies[[region_mutation]] <- targeting_typeOfMutation_region } } expectedMutationFrequencies <- unlist(listExpectedMutationFrequencies) expectedMutationFrequencies[!is.finite(expectedMutationFrequencies)] <- NA expectedMutationFrequencies <- expectedMutationFrequencies / sum(expectedMutationFrequencies, na.rm=TRUE) return(expectedMutationFrequencies) } calculateTargeting <- function(germlineSeq, inputSeq=NULL, targetingModel=HH_S5F, regionDefinition=NULL) { # Check region definition if (!is.null(regionDefinition) & !is(regionDefinition, "RegionDefinition")) { stop(deparse(substitute(regionDefinition)), " is not a valid RegionDefinition object") } # Check targeting model if (!is(targetingModel, "TargetingModel")) { stop(deparse(substitute(targetingModel)), " is not a valid TargetingModel object") } # If an inputSequence is passed then process the germlineSequence # to be the same legth, mask germlineSequence with Ns where inputSequence is also N # If not needed then you may skip this step by passing in inputSequence=NULL # (which is default). if(!is.null(inputSeq)){ # Trim the input and germline sequence to the shortest len_inputSeq <- stri_length(inputSeq) len_germlineSeq <- stri_length(germlineSeq) # If a regionDefinition is passed, # then only analyze till the end of the defined length if(!is.null(regionDefinition)){ length_regionDefinition <- regionDefinition@seqLength } else{ length_regionDefinition <- max(len_inputSeq, len_germlineSeq, na.rm=TRUE) } len_shortest <- min( c(len_inputSeq,len_germlineSeq,length_regionDefinition), na.rm=TRUE) c_inputSeq <- s2c(inputSeq)[1:len_shortest] c_germlineSeq <- s2c(germlineSeq)[1:len_shortest] # If the sequence and germline (which now should be the same length) is shorter # than the length_regionDefinition, pad it with Ns if(len_shortest < length_regionDefinition){ fillWithNs <- array("N", length_regionDefinition - len_shortest) c_inputSeq <- c(c_inputSeq, fillWithNs) c_germlineSeq <- c( c_germlineSeq, fillWithNs) } # Mask germline with Ns where input sequence has Ns c_germlineSeq[c_inputSeq == "N" | !c_inputSeq %in% c(NUCLEOTIDES[1:5], ".") ] <- "N" s_germlineSeq <- c2s(c_germlineSeq) } else { s_germlineSeq <- germlineSeq } # Removing IMGT gaps (they should come in threes) # After converting ... to ZZZ any other . is not an IMGT gap & will be treated like N gaplessSeq <- gsub("\\.\\.\\.", "ZZZ", s_germlineSeq) #If there is a single gap left convert it to an N gaplessSeq <- gsub("\\.", "N", gaplessSeq) # Re-assigning s_germlineSeq (now has all "." that are not IMGT gaps converted to Ns) gaplessSeq <- gsub("ZZZ", "...", gaplessSeq) # Vector of seq c_germlineSeq <- s2c(gaplessSeq) # Matrix to hold targeting values for each position in c_germlineSeq germlineSeqTargeting <- matrix(NA, ncol=stri_length(gaplessSeq), nrow=length(NUCLEOTIDES[1:5]), dimnames=list(NUCLEOTIDES[1:5], c_germlineSeq)) # Now remove the IMGT gaps so that the correct 5mers can be made to calculate # targeting. e.g. # GAGAAA......TAG yields: "GAGAA" "AGAAA" "GAAAT" "AAATA" "AATAG" # (because the IMGT gaps are NOT real gaps in sequence!!!) gaplessSeq <- gsub("\\.\\.\\.", "", gaplessSeq) gaplessSeqLen <- stri_length(gaplessSeq) #Slide through 5-mers and look up targeting gaplessSeq <- paste("NN", gaplessSeq, "NN", sep="") gaplessSeqLen <- stri_length(gaplessSeq) pos <- 3:(gaplessSeqLen - 2) subSeq <- substr(rep(gaplessSeq, gaplessSeqLen - 4), (pos - 2), (pos + 2)) germlineSeqTargeting_gapless <- targetingModel@targeting[, subSeq] # germlineSeqTargeting_gapless <- sapply(subSeq, function(x) { # targetingModel@targeting[, x] }) germlineSeqTargeting[, c_germlineSeq != "."] <- germlineSeqTargeting_gapless # Set self-mutating targeting values to be NA mutatingToSelf <- colnames(germlineSeqTargeting) mutatingToSelf[!(mutatingToSelf %in% NUCLEOTIDES[1:5])] <- "N" # # TODO: What's with this <<- business? # # TODO: I think this is assigning NA to all self-mutations, which are already NA # sapply(1:ncol(germlineSeqTargeting), function(pos) { germlineSeqTargeting[mutatingToSelf[pos], pos] <<- NA }) germlineSeqTargeting[!is.finite(germlineSeqTargeting)] <- NA return(germlineSeqTargeting) } calculateMutationalPaths <- function(germlineSeq, inputSeq=NULL, regionDefinition=NULL, codonTable=NULL) { # Check region definition if (!is.null(regionDefinition) & !is(regionDefinition, "RegionDefinition")) { stop(deparse(substitute(regionDefinition)), " is not a valid RegionDefinition object") } # Set codon table if required if (is.null(codonTable)) { codonTable <- CODON_TABLE } # If an inputSequence is passed then process the germlineSequence # to be the same length, mask germlineSequence with Ns where inputSequence is also N # If this function is being called after running calculateTargeting you may skip # this step by passing in inputSequence=NULL (which is default). This way you save # some processing time. if(!is.null(inputSeq)){ # Trim the input and germline sequence to the shortest len_inputSeq <- stri_length(inputSeq) len_germlineSeq <- stri_length(germlineSeq) # If a regionDefinition is passed, # then only analyze till the end of the defined length if(!is.null(regionDefinition)){ length_regionDefinition <- regionDefinition@seqLength } else{ length_regionDefinition <- max(len_inputSeq, len_germlineSeq, na.rm=TRUE) } len_shortest <- min( c(len_inputSeq,len_germlineSeq,length_regionDefinition), na.rm=TRUE) c_inputSeq <- s2c(inputSeq)[1:len_shortest] c_germlineSeq <- s2c(germlineSeq)[1:len_shortest] # If the sequence and germline (which now should be the same length) is shorter # than the length_regionDefinition, pad it with Ns if(len_shortest0) { stop("Input nucleotides must be one of A, C, G, or T.") } # sort by alphabetical order (important) nucs <- sort(unique(nucs)) # concatenate nucs <- c2s(nucs) # convert return(IUPAC_DNA_2[nucs]) } # Convert one or more characters including dash and dots to ambiguous characters # # @param chars a character vector of nucleotides. One or more of # \code{c("A", "C", "G", "T", "N", "-", ".")}. # # @return a single IUPAC character or "-" or "." # chars2Ambiguous <- function(chars) { # chars must all be unique stopifnot(length(unique(chars)) == length(chars)) # input characters must be one of the characters allowed legal <- c("A", "C", "G", "T", "N", "-", ".") if (sum(! chars %in% legal) > 0) { stop("Input characters must be one of A, C, G, T, N, - (dash), or . (dot)") } # if any of A, T, G, C, N appears if (any(chars %in% c("A", "C", "G", "T", "N"))) { # ignore - and . idx.dash.dot <- which(chars == "-" | chars == ".") if (length(idx.dash.dot)>0) { chars <- chars[-idx.dash.dot] } # if only N appears if (sum(chars=="N") == length(chars)) { return("N") } else { # otherwise, if there are any of A, T, G, C # remove N # e.g. AGN would be treated as AG (R) # e.g. ATGN would be treated as AGT (D) # e.g. ATGCN would be treated as ACGT (N) idx.N <- which(chars == "N") if (length(idx.N) > 0) { chars <- chars[-idx.N] } return(nucs2IUPAC(chars)) } } else { # otherwise, if only one or both of - and . appear(s) # if both - and . appear, return - if (sum(chars %in% c("-", ".")) == 2) { return("-") } else { # if only - or . appears, return that return(chars) } } } # Convert IUPAC incomplete nucleic acid to one or more characters # # @param code a single IUPAC character. # @param excludeN if \code{TRUE}, do not translate when \code{code} # is \code{N}. Default is \code{TRUE}. # @return a character vector of nucleotides. One or more of # \code{c("A", "C", "G", "T")}. # IUPAC2nucs <- function(code, excludeN=TRUE) { # input character must be one of IUPAC codes if (! code %in% names(IUPAC_DNA) ) { stop("Input character must be one of IUPAC DNA codes.") } # convert if (code == "N" & excludeN) { return(code) } else { return(IUPAC_DNA[[code]]) } } # Given a nuclotide position, returns the codon number # e.g. nuc 86 = codon 29 getCodonNumb <- function(nucPos){ return( ceiling(nucPos/3) ) } # Given a codon, returns all the nuc positions that make the codon getCodonNucs <- function(codonNumb){ getCodonPos(codonNumb*3) } # Given a nucleotide postions return the position in the codon getContextInCodon <- function(nucPos){ return((nucPos - 1)%%3 + 1 ) } # Given a nuclotide position, returns the pos of the 3 nucs that made the codon # e.g. nuc 86 is part of nucs 85,86,87 getCodonPos <- function(nucPos) { codonNum <- (ceiling(nucPos / 3)) * 3 return ((codonNum - 2):codonNum) } # Given two codons, tells you if the mutation is R or S (based on your definition) # # @param codonFrom starting codon. IUPAC ambiguous characters are allowed. # @param codonTo ending codon. IUPAC ambiguous characters are allowed. # @param ambiguousMode whether to consider ambiguous characters as "either or" # or "and" when determining (and counting) the type(s) of # mutations. Applicable only if \code{codonFrom} and/or # \code{codonTo} contains ambiguous characters. One of # \code{c("eitherOr", "and")}. Default is \code{"eitherOr"}. # @param aminoAcidClasses vector of amino acid trait classes. # if NULL then R or S is determined by amino acid identity # @return A vector with entries named by mutation type, including "R" (replacement), # "S" (silent), "Stop" (stop) or "na" (input codons are identical or include NA). # Each entry indicates the count of its corresponding type of mutation. # # @details When there are ambiguous characters in \code{codonFrom} and/or \code{codonTo}: # \itemize{ # \item If \code{ambiguousMode="eitherOr"}, ambiguous characters will each # be expanded but only 1 mutation will be recorded. The priority for # different types of mutations, in decreasing order, is as follows: # no mutation ("na"), replacement mutation ("R"), silent mutation ("S"), # and stop mutation ("Stop"). The returned vector will have exactly one # entry with a count of 1 and 0 in all other entries. # \item If \code{ambiguousMode="and"}, ambiguous characters will each be # expanded and mutation(s) from each expansion will be recorded. # Each entry in the returned vector could potentially be greater than 1. # } # # @examples # # Without classes # mutationType("TTT", "TTC") # mutationType("TTT", "TTA") # mutationType("TTT", "TGA") # mutationType("TGG", "TWG") # # # With classes # classes <- HYDROPATHY_MUTATIONS@classes # mutationType("TTT", "TTC", aminoAcidClasses=classes) # mutationType("TTT", "TTA", aminoAcidClasses=classes) # mutationType("TTT", "TCT", aminoAcidClasses=classes) # mutationType("TTT", "TGA", aminoAcidClasses=classes) # mutationType <- function(codonFrom, codonTo, ambiguousMode=c("eitherOr", "and"), aminoAcidClasses=NULL) { # codonFrom="TTT"; codonTo="TTA" # codonFrom="TTT"; codonTo="TGA" ambiguousMode <- match.arg(ambiguousMode) # placeholder for tabulation tab <- setNames(object=rep(0, 4), nm=c("R", "S", "Stop", "na")) if (grepl(pattern="[-.]", x=codonFrom) | grepl(pattern="[-.]", x=codonTo)) { # "na" tab[4] <- 1 } else { codonFrom.all <- EXPANDED_AMBIGUOUS_CODONS[[codonFrom]] codonTo.all <- EXPANDED_AMBIGUOUS_CODONS[[codonTo]] for (cur.codonFrom in codonFrom.all) { for (cur.codonTo in codonTo.all) { # if codons are the same, there is no mutation; count as NA if (cur.codonFrom == cur.codonTo) { # "na" tab[4] <- tab[4] + 1 } else { # Translate codons cur.aaFrom <- AMINO_ACIDS[cur.codonFrom] cur.aaTo <- AMINO_ACIDS[cur.codonTo] # If any codon is NA then return NA if (any(is.na(c(codonFrom, codonTo, cur.aaFrom, cur.aaTo)))) { # "na" tab[4] <- tab[4] + 1 } else if (any(c(cur.aaFrom, cur.aaTo) == "*")) { # If any amino acid is Stop then return "Stop" tab[3] <- tab[3] + 1 } else if (is.null(aminoAcidClasses)) { # Check for exact identity if no amino acid classes are specified mutation <- if (cur.aaFrom == cur.aaTo) { "S" } else { "R" } tab[mutation] <- tab[mutation]+1 } else { # Check for amino acid class identity if classes are specified mutation <- if (aminoAcidClasses[cur.aaFrom] == aminoAcidClasses[cur.aaTo]) { "S" } else { "R" } tab[mutation] <- tab[mutation]+1 } } } } # if there's ambiguous char in observed or germline if ((length(codonFrom.all) > 1) | (length(codonTo.all) > 1)) { if (ambiguousMode=="eitherOr") { if (tab[4] > 0) { # "na" tab <- setNames(object=c(0, 0, 0, 1), nm=c("R", "S", "Stop", "na")) } else if (tab[2] > 0) { # "S" tab <- setNames(object=c(0, 1, 0, 0), nm=c("R", "S", "Stop", "na")) } else if (tab[1] > 0) { # "R" tab <- setNames(object=c(1, 0, 0, 0), nm=c("R", "S", "Stop", "na")) } else { tab <- setNames(object=c(0, 0, 1, 0), nm=c("R", "S", "Stop", "na")) } stopifnot(sum(tab) == 1) } else { stopifnot(sum(tab) >= 1) } } else { # no need to do anything if there isn't ambiguous char in observed or germline # there should be only 1 mutation stopifnot(sum(tab) == 1) } } return(tab) } # returns a boolean vector indicating whether ambiguous characters # exist in each entry of input character vector # input: # - seqs: a character vector # output: # - a boolean vector, where a TRUE indicates presence of ambiguous # character(s) checkAmbiguousExist <- function(seqs) { # ^ within brackets negates the character class bool <- stri_detect_regex(str=seqs, pattern="[^atgcnATGCN\\-\\.]") return(bool) } shazam/NEWS.md0000644000176200001440000005331613616575763012666 0ustar liggesusersVersion 0.2.3 February 5, 2020 ------------------------------------------------------------------------------- General: + Removed SDMTools dependency. Version 0.2.2 December 15, 2019 ------------------------------------------------------------------------------- General: + Fixed an incompatibility with R 4.0 matrix changes. Version 0.2.1 July 19, 2019 ------------------------------------------------------------------------------- Distance Calculation: + Fixed a bug in `distToNearest` that could potentially cause sequences from different partitions to be used for distance calculation. Version 0.2.0 July 18, 2019 ------------------------------------------------------------------------------- General: + Upgraded to alakazam >= 0.3.0 and dplyr >= 0.8.1. Distance Calculation: + Fixed a bug in `plotDensityThreshold` for negative densities. + Fixed a bug in `distToNearest` for performing subsampling while calculating cross-group nearest neighbor distances. + For partitioning sequences, `distToNearest` now supports, via a new argument `VJthenLen`, either a 2-stage partitioning (first by V gene and J gene, then by junction length), or a 1-stage partitioning (simultaneously by V gene, J gene, and junction length). For 1-stage partitioning, `distToNearest` supports export of the partitioning information as a new column via `keepVJLgroup`. + `distToNearest` now supports single-cell input data with the addition of new arguments `cellIdColumn`, `locusColumn`, and `groupUsingOnlyIGH`. Mutation Profiling: + `shmulateTree` has new arguments, `start` and `end`, to specify the region in the sequence where mutations can be introduced. Selection Analysis + Added the function `consensusSequence` which can be used to build a consensus sequence using a variety of methods. Version 0.1.11: January 27, 2019 ------------------------------------------------------------------------------- General: + Fixed a bug in the prototype declarations for the `TargetingModel` and `RegionDefinition` S4 classes. Version 0.1.10: September 19, 2018 ------------------------------------------------------------------------------- General: + Added `subsample` argument to `distToNearest` function. + Removed some internal utility functions in favor of importing them from `alakazam`. Specifically, `progressBar`, `getBaseTheme` and `checkColumns`. + Removed `clearConsole`, `getnproc`, and `getPlatform` functions. Distance Calculation: + Changed default `findThreshold` method to `density`. + Significantly reduced run time of the `density` method by retuning the bandwidth detection process. The `density` method should now also yield more consistent thresholds, on average. + The `subsample` argument to `findThreshold` now applies to both the `density` and `gmm` methods. Subsampling of distance is not performed by default. + Fixed a bug in `plotDensityThreshold` and `plotGmmThreshold` wherein the `breaks` argument was ignored when specifying `xmax` and/or `xmin`. Selection Analsis: + Fixed a plotting bug in `plotBaselineDensity` arising when the `groupColumn` and `idColumn` arguments were set to the same column. + Added the `sizeElement` argument to `plotBaselineDensity` to control line size + Renamed the `field_name` argument to `field` in `editBaseline`. Version 0.1.9: March 30, 2018 ------------------------------------------------------------------------------- Selection Analysis: + Fixed a bug in `plotBaselineDensity` which caused an empty plot to be generated if there was only a single value in the `idColumn`. + Fixed a bug in `calcBaseline` which caused a crash in `summarizeBaseline` and `groupBaseline` when input `baseline` is based on only 1 sequence (i.e. when `nrow(baseline@db)` is 1). + Set default `plot` call on a `Baseline` object to `plotBaselineDensity`. + Removed `getBaselineStats` function. + Added a `summary` method for `Baseline` objects that calls `summarizeBaseline` and returns a data.frame. Mutation Profiling: + Fixed a bug in `shmulateSeq` which caused a crash when the input sequence contains gaps (`.`). + Renamed the argument `mutations` in `shmulateSeq` to `numMutations`. + Improved help documentation for `shmulateSeq` and `shmulateTree`. + Added vignette for simulating mutated sequences. + `calcExpectedMutations` will now treat non-ACTG characters as Ns rather than produce an error. + Added two new `RegionDefinition` objects for the full V segment as single region (`IMGT_V_BY_SEGMENTS`) and the V segment with each codon as a separate region (`IMGT_V_BY_CODONS`). Targeting Models: + Added the `calculateMutability` function which computes the aggregate mutability for sequences. + Fixed a bug that caused `createSubstitutionMatrix` to fail for data containing only a single V family. + Changed the default model to silent mutations only (`model="S"`) in `createSubstitutionMatrix`, `createSubstitutionMatrix` and `createTargetingModel` + Set default `plot` call on a `TargetingModel` object to `plotMutability`. Version 0.1.8: June 30, 2017 ------------------------------------------------------------------------------- General: + Corrected several functions so that they accept both tibbles and data.frames. Distance Calculation: + Adding new fitting procedures to the `"gmm"` method of `findThreshold()` that allows users to choose a mixture of two univariate density distribution functions among four available combinations: `"norm-norm"`, `"norm-gamma"`, `"gamma-norm"`, or `"gamma-gamma"`. + Added the ability to choose the threshold selection criteria in the `"gmm"` method of `findThreshold()` from the best average sensitivity and specificity, the curve intersection or user defined sensitivity or specificity. + Renamed the `cutEdge` argument of `findThreshold()` to `edge`. Mutation Profiling: + Redesigned `collapseClones()`, adding various deterministic and stochastic methods to obtain effective clonal sequences, support for including ambiguous IUPAC characters in output, as well as extensive documentation. Removed `calcClonalConsensus()` from exported functions. + Added support for including ambiguous IUPAC characters in input for `observedMutations()` and `calcObservedMutations()`. + Fixed a minor bug in calculating the denominator for mutation frequency in `calcObservedMutations()` for sequences with non-triplet overhang at the tail. + Renamed column names of observed mutations (previously `OBSERVED`) and expected mutations (previously `EXPECTED`) returned by `observedMutations()` and `expectedMutations()` to `MU_COUNT` and `MU_EXPECTED` respectively. Selection Analysis: + `calcBaseline()` no longer calls `collapseClones()` automatically if a `CLONE` column is present. As indicated by the documentation for `calcBaseline()` users are advised to obtain effective clonal sequences (for example, calling `collapseClones()`) before running `calcBaseline()`. + Updated vignette to reflect changes in `calcBaseline()`. Version 0.1.7: May 14, 2017 ------------------------------------------------------------------------------- Mutation Profiling: + Fixed a bug in `collapseClones()` that prevented it from running when `nproc` is greater than 1. Version 0.1.6: May 12, 2017 ------------------------------------------------------------------------------- General: + Internal changes for compatibility with dplyr v0.6.0. + Removed data.table dependency. Mutation Profiling: + Fixed a bug in `collapseClones()` that resulted in erroneous `CLONAL_SEQUENCE` and `CLONAL_GERMLINE` being returned. + Added a vignette describing basic mutational analysis. + Remove console notification that `observedMutations` was running. Version 0.1.5: March 23, 2017 ------------------------------------------------------------------------------- General: + License changed to Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0). Selection Analysis: + Fixed a bug in p-value calculation in `summarizeBaseline()`. The returned p-value can now be either positive or negative. Its magnitude (without the sign) should be interpreted as per normal. Its sign indicates the direction of the seLicense chalection detected. A positive p-value indicates positive selection, whereas a negative p-value indicates negative selection. + Added `editBaseline()` to exported functions, and a corresponding section in the vignette. + Fixed a bug in counting the total number of observed mutations when performing a local test for codon-by-codon selection analysis in `calcBaseline()`. Targeting Models: + Added `numMutationsOnly` argument to `createSubstitutionMatrix()`, enabling parameter tuning for `minNumMutations`. + Added functions `minNumMutationsTune()` and `minNumSeqMutationsTune()` to tune for parameters `minNumMutations` and `minNumSeqMutations` in functions `createSubstitutionMatrix()` and `createMutabilityMatrix()` respectively. Also added function `plotTune()` which helps visualize parameter tuning using the abovementioned two new functions. + Added human kappa and lambda light chain, silent, 5-mer, functional targeting model (`HKL_S5F`). + Renamed `HS5FModel` as `HH_S5F`, `MRS5NFModel` as `MK_RS5NF`, and `U5NModel` as `U5N`. + Added human heavy chain, silent, 1-mer, functional substitution model (`HH_S1F`), human kappa and lambda light chain, silent, 1-mer, functional substitution model (`HKL_S1F`), and mouse kappa light chain, replacement and silent, 1-mer, non-functional substitution model (`MK_RS1NF`). + Added `makeDegenerate5merSub` and `makeDegenerate5merMut` which make degenerate 5-mer substitution and mutability models respectively based on the 1-mer models. Also added `makeAverage1merSub` and `makeAverage1merMut` which make 1-mer substitution and mutability models respectively by averaging over the 5-mer models. Mutation Profiling: + Added `returnRaw` argument to `calcObservedMutations()`, which if true returns the positions of point mutations and their corresponding mutation types, as opposed to counts of mutations (hence "raw"). + Added new functions `slideWindowSeq()` and `slideWindowDb()` which implement a sliding window approach towards filtering a single sequence or sequences in a data.frame which contain(s) equal to or more than a given number of mutations in a given number of consecutive nucleotides. + Added new function `slideWindowTune()` which allows for parameter tuning for using `slideWindowSeq()` and `slideWindowDb()`. + Added new function `slideWindowTunePlot()` which visualizes parameter tuning by `slideWindowTune()`. Distance Calculation: + Fixed a bug in `distToNearest` wherein `normalize="length"` for 5-mer models was resulting in distances normalized by junction length squared instead of raw junction length. + Fixed a bug in `distToNearest` wherein `symmetry="min"` was calculating the minimum of the total distance between two sequences instead of the minimum distance at each mutated position. + Added `findThreshold` function to infer clonal distance threshold from nearest neighbor distances returned by `distToNearest`. + Renamed the `length` option for the `normalize` argument of `distToNearest` to `len` so it matches Change-O. + Deprecated the `HS1FDistance` and `M1NDistance` distance models, which have been renamed to `hs1f_compat` and `m1n_compat` in the `model` argument of `distToNearest`. These deprecated models should be used for compatibility with DefineClones in Change-O v0.3.3. These models have been replaced by replaced by `hh_s1f` and `mk_rs1nf`, which are supported by Change-O v0.3.4. + Renamed the `hs5f` model in `distToNearest` to `hh_s5f`. + Added support for `MK_RS5NF` models to `distToNearest`. + Updated `calcTargetingDistance()` to enable calculation of a symmetric distance matrix given a 1-mer substitution matrix normalized by row, such as `HH_S1F`. + Added a Gaussian mixture model (GMM) approach for threshold determination to `findThreshold`. The previous smoothed density method is available via the `method="density"` argument and the new GMM method is available via `method="gmm"`. + Added the functions `plotGmmThreshold` and `plotDensityThreshold` to plot the threshold detection results from `findThreshold` for the `"gmm"` and `"density"` methods, respectively. Region Definition: + Deleted `IMGT_V_NO_CDR3` and `IMGT_V_BY_REGIONS_NO_CDR3`. Updated `IMGT_V` and `IMGT_V_BY_REGIONS` so that neither includes CDR3 now. Version 0.1.4: August 5, 2016 ------------------------------------------------------------------------------- Selection Analysis: + Fixed a bug in calcBaseline wherein the germline column was incorrected hardcoded, leading to erroneous mutation counts for some clonal consensus sequences. Targeting Models: + Added `numSeqMutationsOnly` argument to `createMutabilityMatrix()`, enabling parameter tuning for `minNumSeqMutations`. Version 0.1.3: July 31, 2016 ------------------------------------------------------------------------------- General: + Added ape and igraph dependency + Removed the `InfluenzaDb` data object, in favor of the updated `ExampleDb` provided in alakazam 0.2.4. + Added conversion of sequence to uppercase for several functions to support data that was not generated via Change-O. Distance Calculation: + Added the `cross` argument to `distToNearest()` which allows restriction of distances to only distances across samples (ie, excludes within-sample distances). + Added `mst` flag to `distToNearest()`, which will return all distances to neighboring nodes in a minimum spanning tree. + Updated single nucleotide distance models to use the new C++ distance methods in alakazam 0.2.4 for better performance. + Fixed a bug leading to failed distance calculations for the `aa` model of `distToNearest()`. + Fixed a bug wherein gap characters where being translated into Ns (Asn) rather than Xs within the `aa` model of `distToNearest()`. Mutation Profiling: + Added the `MutationDefinition` `VOLUME_MUTATIONS`. + Added the functions `shmulateSeq()` and `shmulateTree()` to simulate mutations on sequences and lineage trees, respectively, using a 5-mer targeting model. + Renamed `collapseByClone`, `calcDbExpectedMutations` and `calcDbObservedMutations` to `collapseClones`, `expectedMutations`, and `observedMutations`, respectively. Selection Analysis: + Fixed a bug wherein passing a `Baseline` object through `groupBaseline()` multiple times resulted in incorrect normalization. + Added `title` options to `plotBaselineSummary()` and `plotBaselineDensity()`. + Added more control over colors and group ordering to `plotBaselineSummary()` and `plotBaselineDensity()`. + Added the `testBaseline()` function to test the significance of differences between two selection distributions. + Improved selection analysis vignette. Version 0.1.2: February 20, 2016 ------------------------------------------------------------------------------- General: + Renamed package from shm to shazam. + Internal changes to conform to CRAN policies. + Compressed and moved example database to the data object `InfluenzaDb`. + Fixed several bugs where functions would not work properly when passed a `dplyr::tbl_df` object instead of a `data.frame`. + Changed R dependency to R >= 3.1.2. + Added stringi dependency. Distance Calculation: + Fixed a bug wherein `distToNearest()` did not return the nearest neighbor with a non-zero distance. Targeting Models: + Performance improvements to `createSubstitutionMatrix()`, `createMutabilityMatrix()`, and `plotMutability()`. + Modified color scheme in `plotMutability()`. + Fixed errors in the targeting models vignette. Mutation Profiling: + Added the `MutationDefinition` objects `MUTATIONS_CHARGE`, `MUTATIONS_HYDROPATHY`, `MUTATIONS_POLARITY` providing alternate approaches to defining replacement and silent annotations to mutations when calling `calcDBObservedMutations()` and `calcDBExpectedMutations()`. + Fixed a few bugs where column names, region definitions or mutation models were not being recognized properly when non-default values were used. + Made the behavior of `regionDefinition=NULL` consistent for all mutation profiling functions. Now the entire sequence is used as the region and calculations are made accordingly. + `calcDBObservedMutations()` returns R and S mutations also when `regionDefinition=NULL`. Older versions reported the sum of R and S mutations. The function will add the columns `OBSERVED_SEQ_R` and `OBSERVED_SEQ_S` when `frequency=FALSE`, and `MU_FREQ_SEQ_R` and `MU_FREQ_SEQ_R` when `frequency=TRUE`. Version 0.1.1: December 18, 2015 ------------------------------------------------------------------------------- General: + Swapped dependency on doSNOW for doParallel. + Swapped dependency on plyr for dplyr. + Swapped dependency on reshape2 for tidyr. + Documentation clean up. Distance Calculation: + Changed underlying method of calcTargetingDistance to be negative log10 of the probability that is then centered at one by dividing by the mean distance. + Added `symmetry` parameter to distToNearest to change behavior of how asymmetric distances (A->B != B->A) are combined to get distance between A and B. + Updated error handling in distToNearest to issue warning when unrecognized character is in the sequence and return an NA. + Fixed bug in 'aa' model in distToNearest that was calculating distance incorrectly when normalizing by length. + Changed behavior to return nearest nonzero distance neighbor. Mutation Profiling: + Renamed calcDBClonalConsensus to collapseByClone Also, renamed argument collapseByClone to expandedDb. + Fixed a (major) bug in calcExpectedMutations. Previously, the targeting calculation was incorrect and resulted in incorrect expected mutation frequencies. Note, that this also resulted in incorrect BASELINe Selection (Sigma) values. + Changed denominator in calcObservedMutations to be based on informative (unambiguous) positions only. + Added nonTerminalOnly parameter to calcDBClonalConsensus indicating whether to consider mutations at leaves or not (defaults to false). Selection Analysis: + Updated groupBaseline. Now when regrouping a Baseline object (i.e. grouping previously grouped PDFs) weighted convolution is performed. + Added "imbalance" test statistic to the Baseline selection calculation. + Extended the Baseline Object to include binomK, binomN and binomP Similar to numbOfSeqs, each of these are a matrix. They contain binomial inputs for each sequence and region. Targeting Models: + Added `minNumMutations` parameter to createSubstitutionMatrix. This is the minimum number of observed 5-mers required for the substituion model. The substitution rate of 5-mers with fewer number of observed mutations will be inferred from other 5-mers. + Added `minNumSeqMutations` parameter to createMutabilityMatrix. This is the minimum number of mutations required in sequences containing the 5-mers of interest. The mutability of 5-mers with fewer number of observed mutations in the sequences will be inferred. + Added `returnModel` parameter to createSubstitutionMatrix. This gives user the option to return 1-mer or 5-mer model. + Added `returnSource` parameter to createMutabilityMatrix. If TRUE, the code will return a data frame indicating whether each 5-mer mutability is observed or inferred. + In createSubstitutionMatrix and createMutabilityMatrix, fixed a bug when multipleMutation is set to "ignore". + Changed inference procedure for the 5-mer substitution model. + Added inference procedure for 5-mers without enough observed mutations in the mutability model. + Fixed a bug in background 5-mer count for the RS model. + Fixed a bug in IMGT gap handling in createMutabilityMatrix. + Fixed a bug that occurs when sequences are in lower cases. Version 0.1.0: June 18, 2015 ------------------------------------------------------------------------------- Initial public release. General: + Restructured the S4 class documentation. + Fixed bug wherein example `Influenza.tab` file did not load on Mac OS X. + Added citations for `citation("shazam")` command. + Added dependency on data.table >= 1.9.4 to fix bug that occured with earlier versions of data.table. Distance Calculation: + Added a human 1-mer substitution matrix, `HS1FDistance`, based on the Yaari et al, 2013 data. + Set the `hs1f` as the default distance model for `distToNearest()`. + Added conversion of sequences to uppercase in `distToNearest()`. + Fixed a bug wherein unrecongized (including lowercase) characters would lead to silenting returning a distance of 0 to the neared neighbor. Unrecognized characters will now raise an error. Mutation Profiling: + Fixed bug in `calcDBClonalConsensus()` so that the function now works correctly when called with the argument `collapseByClone=FALSE`. + Added the `frequency` argument to `calcObservedMutations()` and `calcDBObservedMutations()`, which enables return of mutation frequencies rather the default of mutation counts. Targeting Models: + Removed `M3NModel` and all options for using said model. + Fixed bug in `createSubstitutionMatrix()` and `createMutabilityMatrix()` where IMGT gaps were not being handled. Version 0.1.0.beta-2015-05-30: May 30, 2015 ------------------------------------------------------------------------------- General: + Added more error checking. Targeting Models: + Updated the targeting model workflow to include a clonal consensus step. Version 0.1.0.beta-2015-05-11: May 11, 2015 ------------------------------------------------------------------------------- Targeting Models: + Added the `U5NModel`, which is a uniform 5-mer model. + Improvements to `plotMutability()` output. Version 0.1.0.beta-2015-05-05: May 05, 2015 ------------------------------------------------------------------------------- Prerelease for review. shazam/MD50000644000176200001440000001433413616730026012056 0ustar liggesusers3644ba14e4c21565aa01067f2011d3fe *DESCRIPTION 02784592b294479769959b620c28eb3b *NAMESPACE 914b611859dfda308e375c78d0530d3a *NEWS.md d0796f0ea2228d7871661d52c1c1d60e *R/Baseline.R 78d71681689686b54d140c6285b33e19 *R/Core.R 09ead9cb1b38cc86a9cd465c8b100b12 *R/DistToNearest.R 499c3e8d2f4bc7efb2b8dcd6b6ff3922 *R/MutationDefinitions.R 9cae772006747e5bc783f99c3102f947 *R/MutationProfiling.R 2d34ed089cde26f3156a6acfae3f1e22 *R/RegionDefinitions.R 682a31377b44e04827581a98e303c4ba *R/Shazam.R 70c8a531a5d1137a9e5cc444804ce131 *R/Shmulate.R 92b51b6717480b721ec97f43dec9860f *R/TargetingModels.R 1d821cc64741432266cc41d5995e2393 *R/sysdata.rda 4196e2b5e0222b5929c5c8be002289e1 *README.md b6a6696c335e97404b2ff45b8fa7be8a *build/vignette.rds a6d8e4bb225163a04252376b3b2fe3b5 *data/CHARGE_MUTATIONS.rda 13597652e61fec4478f242e85d1f3ba5 *data/HH_S1F.rda 649dc69d8463511dd447c5dc48e72b8b *data/HH_S5F.rda 90e5eaa6a08ef93e8b15b32df55c48f8 *data/HKL_S1F.rda 2399ca27a028ca901131d4da09b4196b *data/HKL_S5F.rda 27d7bdb4a59fb7e157790b5df263a24e *data/HYDROPATHY_MUTATIONS.rda 0f9173b818adc04ebb9bb7fbf05f1f7e *data/IMGT_V.rda ee256d4b39c91cf9a4ad1bc0734f94f5 *data/IMGT_V_BY_CODONS.rda e52a16496673bd88d91e6c8ec03c8760 *data/IMGT_V_BY_REGIONS.rda 5be4fece58471da92c7e7b1594056034 *data/IMGT_V_BY_SEGMENTS.rda 914fe6b6ac51d564ef2ba1f85bb85800 *data/MK_RS1NF.rda 3b6e2193e8ff4730e65aae52ddb77d03 *data/MK_RS5NF.rda c9c22320df42880769b793bea91ded36 *data/POLARITY_MUTATIONS.rda ffaafe98d3c5d5c9b31228c6fe6cca47 *data/U5N.rda ae6ab7434ee43157d8e8b2921f223c85 *data/VOLUME_MUTATIONS.rda f3b50c606aaca388ab4155ea3428f454 *inst/CITATION 3f47b3cdf74a5658f9a917387f0798c2 *inst/doc/Baseline-Vignette.R 717899918407b576072e293cb82b68b0 *inst/doc/Baseline-Vignette.Rmd 1e8d8c5010dcc42a048ce0ff47b1dc71 *inst/doc/Baseline-Vignette.pdf ed9d2f51349208e40a2abf2638e5e2ec *inst/doc/DistToNearest-Vignette.R 1a2e55bd24e6a776c7e29bbb9289f747 *inst/doc/DistToNearest-Vignette.Rmd 3ae1f54f6dcd49463010e819cba908b5 *inst/doc/DistToNearest-Vignette.pdf ef921b08e885fb34f2c9502390691bc8 *inst/doc/Mutation-Vignette.R 0a49fdc063c71c9c06d1b66742f3d532 *inst/doc/Mutation-Vignette.Rmd f02aa1817f2dc25fb94c7204a1a383be *inst/doc/Mutation-Vignette.pdf e379bbc65665235bc41fc4001230a750 *inst/doc/Shmulate-Vignette.R ae8dfa57bfcd91c6ccfc731d4264f248 *inst/doc/Shmulate-Vignette.Rmd 29fdedf97c71ef6037727c050b4af4d2 *inst/doc/Shmulate-Vignette.pdf e5726cb3abfecfdb3a34c667931ff630 *inst/doc/Targeting-Vignette.R 1785012971a135beb456f26bb9d1c144 *inst/doc/Targeting-Vignette.Rmd d5312d336daeb7fd55549547d9b75347 *inst/doc/Targeting-Vignette.pdf 2f3cd7938f21d16f822d1a4b3785c2e1 *man/Baseline-class.Rd 4c9241edade6d91e3a06f28de4694078 *man/DensityThreshold-class.Rd b32b0ad8b0c85610fc217a14f1db81b2 *man/GmmThreshold-class.Rd 98f6d6aeaadf58389960f586c02b3882 *man/HH_S1F.Rd d7cad825b7d37ca0c856b785bf892b5f *man/HH_S5F.Rd a138d04fc9b94bda4d43f77c0c34f64f *man/HKL_S1F.Rd 9ea9a7a7240150a9f983975ce17348f5 *man/HKL_S5F.Rd 3bed0f6c41fc0993eadc80bb61b17750 *man/IMGT_SCHEMES.Rd d1cf9c4e6bcd13ac03bee4022cca7dda *man/MK_RS1NF.Rd 5a0b0b68f073d362ed921d7ce2b6d302 *man/MK_RS5NF.Rd b52702a03ac31b18ced1ff1a8236b367 *man/MUTATION_SCHEMES.Rd 13787752e7a8c6d36e4580366cb8be82 *man/MutationDefinition-class.Rd 37bdc51c60fd3366a48546265720756e *man/RegionDefinition-class.Rd fe986f4d822323fe47c96dd07391be2d *man/TargetingModel-class.Rd 9bbb541c44b6ca3ee17d2ae8e1b03d31 *man/U5N.Rd c8190a8b12eecd89380c83473adf09b4 *man/calcBaseline.Rd 3c87ae7b0ce94cac367485861486196c *man/calcExpectedMutations.Rd 409b89dea44510972c71d5ca6b147c5d *man/calcObservedMutations.Rd e360c5f55ef91279e0c90ace525c57d0 *man/calcTargetingDistance.Rd 69fe893c6603906aaaa5f1dceb532a5e *man/calculateMutability.Rd 3b46f448710eb9e23fe67bca7cc3b4e1 *man/collapseClones.Rd e0279514aa45a2f2baaafeef1d3f56eb *man/consensusSequence.Rd 41a5bcabfb5abc12c063255a98744ab8 *man/createBaseline.Rd 2758befe1b23d5a4e39eb76ad24a52a6 *man/createMutabilityMatrix.Rd 291078043a96c53414245a7e245510d4 *man/createMutationDefinition.Rd 492ef3e940bf53f731ef9e5cba3a8653 *man/createRegionDefinition.Rd ed614da32197d586199faf6216a96bb4 *man/createSubstitutionMatrix.Rd 55e9db243c04b84f7119d5320ce01148 *man/createTargetingMatrix.Rd d1b5d40e8f300b5b2619d53917b2d7c6 *man/createTargetingModel.Rd ed5e5eeebbe9512fdf0492dbd4a97105 *man/distToNearest.Rd 28f8d664d0e879b01b0c3a680506653a *man/editBaseline.Rd 5882b0f7dbde750513a14126f3df7fa9 *man/expectedMutations.Rd 9e56bc899a938d5c0000c274e20c37ee *man/extendMutabilityMatrix.Rd 92510a9afa61258fb8ec6fce367678eb *man/extendSubstitutionMatrix.Rd d1f266773b544f4d18463cc3e847cf4a *man/findThreshold.Rd c4a08927235f63aa67a88f6bf690f4e2 *man/groupBaseline.Rd a64599327530e7dd2e26c79dc2bf27ae *man/makeAverage1merMut.Rd d3ad96cd8466448271e018d0774ebb44 *man/makeAverage1merSub.Rd a421abd5d1b8546f15e2926a3d3d601d *man/makeDegenerate5merMut.Rd f1e35fb60180aa5226b1ca07fab136c2 *man/makeDegenerate5merSub.Rd 5c137ef63008e49040fb72e0d5a928ae *man/minNumMutationsTune.Rd ad2ab10e1ca9d6fdfd3f46d4919f55a9 *man/minNumSeqMutationsTune.Rd a1cec572eaa4a1ff0bddbab2fb2484a1 *man/observedMutations.Rd 9ce414855b9b98619d71e23849c25e5a *man/plotBaselineDensity.Rd 547f76a261b033fbdc7f2d20ca2eb66e *man/plotBaselineSummary.Rd 5be7c5b619d81c1809935f4bd7c49b98 *man/plotDensityThreshold.Rd 596fb1cc20116e3bf6b6e320fd5c0587 *man/plotGmmThreshold.Rd dd51d0355510732690a33bea5186ace5 *man/plotMutability.Rd 45aa62c283592929678b8796822f2ffb *man/plotTune.Rd c270d1d156e11fc8d41c84698bc27efb *man/shazam.Rd 9c0257b68090dd22be54563d9a0d1526 *man/shmulateSeq.Rd 1381bdf00829740807efe8aa9321d892 *man/shmulateTree.Rd 9458572c3ff6f7db5b04373fdb4e2207 *man/slideWindowDb.Rd f0aa8aae1bb4f145b69190e2d11bb9fb *man/slideWindowSeq.Rd dd22f562db6540807c4b42a403cf52f6 *man/slideWindowTune.Rd 0a6e9a63813d58f2383d52fe98230a0b *man/slideWindowTunePlot.Rd 7673e512a37a3781db8f43385394c4ad *man/summarizeBaseline.Rd 3da13d2062a0fd14891c787e2507f2a4 *man/testBaseline.Rd eb562fee7fda5169a426ea340a6a0dc3 *man/writeTargetingDistance.Rd 717899918407b576072e293cb82b68b0 *vignettes/Baseline-Vignette.Rmd 1a2e55bd24e6a776c7e29bbb9289f747 *vignettes/DistToNearest-Vignette.Rmd 0a49fdc063c71c9c06d1b66742f3d532 *vignettes/Mutation-Vignette.Rmd ae8dfa57bfcd91c6ccfc731d4264f248 *vignettes/Shmulate-Vignette.Rmd 1785012971a135beb456f26bb9d1c144 *vignettes/Targeting-Vignette.Rmd shazam/inst/0000755000176200001440000000000013616633217012522 5ustar liggesusersshazam/inst/doc/0000755000176200001440000000000013616633217013267 5ustar liggesusersshazam/inst/doc/Targeting-Vignette.pdf0000644000176200001440000067411313616633217017505 0ustar liggesusers%PDF-1.5 % 25 0 obj << /Length 2158 /Filter /FlateDecode >> stream xYY6~`%/TʃwTp%e  .V똱nS< hy5ʂ5Q4*:{SROƧpŬ7PP}q7eUf|?>_Wo~̫⌾$+C}A e}wVU(TE^m*Ϋ܋劇 y}u>tG 񷄂SE0^(2XG p,yx\נ[Pig*5S=˞| w7];7Uyg֋+ky7ưQ%0ؤX`]" ~쀉fg7 c,JR/7l.8D(C|`"UKqdG+sTJ]ƻE6e;Q1F m쑇‚} dy͒6ojpicwC7b71-i(qӑ@9gQȔPL)͠ E`|oԈNy,0L~`55 )=NM_tH渳Ѯ4ڵ& ̽;pVUkn0L4OšʏlGp [I,N_H2Pq)SfgMK~f3?1)E= i服b}0PYHh'n$#ᇣ#3t'd :0hsE:J*]{R U|ue#Ӆ5 )B뚴 :RnW4Ӡ"1Zԧ]gpLjDmh >yG}{α0<ɋ&Y. %8ns@=mlۊ0? }teuEѓ㕖v^Mr9;.@,~*szdcv#cptٖps~5C)E !?fa_6rVX͛bo俜Vf[;h3ïFf0o/ %Pm ) E:]< Z7U]2 xC=/<2+H0CʮXV'V2L+[&UQc> ҭnzÎ~._ R 0fAsfʍiڗ$!8ME Ot&~-g0g^<=}ww07.x# %AW.1 R ).E6he3q1Ǡj,z+H7ї*7]?([5wr 6PcM1D%'BЧI Iˁ[y cFENHoŞȫΨE NNX6$T 3Dl7ρSF ton56!0kx,g ڷKa"4R(<]7{˜Qȅ4# BhMLvj~A @P+pa/XzS((i>1 ݎ8ᖪ*dX|;Kg 6Qa}?\o4+fRsp^Mu&K&2`wC>oOGP$x!FzT9L([0O@>C푝6cZ擝-TM{4jjZh`ES?&=m˪N9<|VLm5 ~l;d ԩ2hrɰMUi٢&A^F$s!ˇa}:b4 rhz1PZq0HXށX Bnz Y~š}㟪JPn.AW8th 0a }eWы'IF@.G@Hu endstream endobj 46 0 obj << /Length 2605 /Filter /FlateDecode >> stream xr_<Gn pqx|}{p$8k$Xz&Ϟf!D.o05,\0"E+w~bk6f KM>jZ_j5C2|%b?Kr2St4~h?4fzet(}޵\vad|gw绲B?ʷu"Bۼ]Zo-َC識Yh# ϧ+|-ҏYDQt- #+7̴x7UMyy5H>S{ ޳΋WhmZcp oB5Ei8woҶ?cPzIlD6i1)؀8btC ݁+X"jE80AI|?0Ũ*BCam8Y`210FQL1VHel$ #p&`{m}nog!s_ǞI蛑Qv=;7ux:HDkPdNXp5syN.f./<hLLjjM7‡`cu+:j 8QE t+(:tx[iHc}X%S5™}esJvU//}&fg.2XI- }pF ^1y D%o2n( "ydXXİ˱Hw' C:W=T[_0:" ,B n_&=pWᅳssdh*#* pKQcz('ǎ32&w/\e,aT_8J(74y)-+T!~rhsIS|@ " tHTrZ`cODŴ7tuR\ݑ +EϞdϔ$Za`/l.9S`\p*lhJhML<[QӉr5ZrY }}v{ L)%s[; Y+p@ѐAA<+tU'g 0쯖 e( *٦%,y c6 ԂZ[+c͑PL-9C~UYi  >9B;Pʏ*AY6+rͼQ;Uѐ Ch5q0vM b"ͬ&损 t"gR?eHx@P*U=gWB2PqĄ[b1}zo*?FM<Y o P^쨧 nH"phC^ Ku[OLC܀Yp{; ZNmKFSCSG6i,]%%V7<$5a)r~$3%%zFy= IǾ,lkSLXBG:f0 C5W?лSP#]l!ߘ@kڻ"{]+9=h M~sG3Yf]v[U F芴 Oz{5cVf%Ie)H3~P!Xz)CҽW8 -3%gSC"i{nt M9aav781Ox[e)2p^ǠF1@F!47ݯ&{[Q endstream endobj 53 0 obj << /Length 345 /Filter /FlateDecode >> stream xՒ=O0wSYZg;n⁁$PPCJhӡNY d{|>9 d ەa2!>/ProcSet [ /PDF ] >> /Length 37 /Filter /FlateDecode >> stream x+2T0BC]3#] \.}\C|@.`kP endstream endobj 56 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Targeting-Vignette_files/figure-latex/unnamed-chunk-4-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 57 0 R /BBox [ 0 0 504 540] /Resources << /ProcSet [/PDF/Text] /Font << /F2 58 0 R /F3 59 0 R >> /ExtGState << >> /ColorSpace << /sRGB 60 0 R >> >> /Length 15847 /Filter /FlateDecode >> stream x}ˎ-q|E I)f-m@ X~--7+ǾItXAtpo}\*MWowۏ7~؞?ٯůo?so7'DE,_7]gώշWm\V_} |;~354w6.kɸx_~qƒT/{|Ckx۟g>$<o_|u9~kT>K6"Eوg&4~<4}Mjϻk^6[l<ۓ juϟ-hŌhÍ_"pE]Yc>k|Mll KuO4_m_i5}%W+MDھRf?؞wRW»Rm&Oߨ׿? /Y!w}˶.k^ۅZަܕd|@ ZzpO>lhPߞjZxB=BmxM3_оwRk^6ZVY_wxfE{WQ~Yt@}k+5j1b4 /]2xfC{Z^3|wVَfC{_ !jۻSj]h6|_ w93%fC߻*g~<ЬhPzuG}|w6D=8cT ~^}^@O?@1gʏ1NPE㦐~z>O7tOL~U^'Q^,0>C{oU}߷E&)qw :1sr+>|_}_x:w31ϲ o0&(rJ={OD[&}dbEW緽(|21_ez'Oߗ4^;a?۲^8߃iI󽰟m=zSB<|&7oqWozW>GOU<}w3ZzuEU;7Zeֿ?>ijwڲP;u<4+ÓfmOo[jK4Sr%w؀w>@=hvr~6 5ة+ʱPqZe4+SOLKlq5L=ch6|_}e ~.aieG=ԾN.%fC{}3wθTlhO=C3Fsf} ,u&v4C/@UMlhPk/.N2"w4C/@"]w~gw4C/@=lw6И]fG=B cP͆ 5P8.9;fC{ި#h/h6|o/۷wŎfC{{Lw͎fCnc۬tuՎfC{^;v4Lzt[JnlhO>SriUvfCvZFJ ?ЬhPD[S[ jОu3 LPyBhVou/C-qE/͊Tu}~A؎fC>?q _$o͌ ~~XޜfE=naqx}hV?zh?<4OyO Iƌ@hcDd@ǿ?@=Gc&ߍOi$LK,#^id~FhVvsf+)gjWC~3}tўfj_Z2q$IQS,Zb2nh6|zk:PtU$6*j; )gj򺸦1UJih6|MRs[UTK4+S__[U̍#hVuKW%ƏhO*gjh.SHF慔͎4rƸJÒzS)y\Ƙ淘 ͎35ʎ D6_Ōhi5POci+)gj.g|/PhxfG{3z5Ϳў}x *Kݿ@=L .*ֶfG{WzuVeQr`5SaE=L o2v4;SH]2R4CTRa4xfE{Z+÷\J]2*'!j.o"r<\_}qZ?9!4C/Hk[uRK}B=B7U3DP&R+4S@KbլgI/Eg͆35RO&3fC{ᒣHwB=L \RY2RKX*yh6|:bH )gj.G[.=lhO>S#,ꔚL )gjh 95{Z%XО}P#udQ͆|S?."h6|֣߳}oh6ƚgэʲV#xО}P=oyy {Ԇˁ&]r|_lh> 98dm/lhߓ6θt;Ug͆|4#eϺ|оwmV`1m"_5>lhAmu)3z4)TʯlhHm) K-+4SԆ>2k͆=}]&yx ͆3qK~V9͆{;lTۣ۷]+4LmcUf?Ѭh߻ڰ],d;}661m)D}nCjfJ y%)gj^V|dhvH*&aDW͎3nEy*92M[h߲*n 4Ziu+yAXfG}^u߄M]^ў9Ժ_v92w~fG_FuIzZ /hO>S8۪0lhvoZEJ˿@=Ժ Uu՗hVoaZA#!L>h*hV~ؙZ#LF~͊-R('o?V=d4+SzbVD:`UiцfCV܅R1'HQ^О9z 22w4ڷmZ5t(Rc>\ʜ; )gj= Z%- ; [qVJǘϨ.^Yўz|ToxYѾ_zlԯ.;6ZV;#~ݎfEV\R1HcJ͊3OƐv64ڷiZ%FcHy; )gj=id䲔lhߊVj=c)Ȳ%y]Aϣt1^fEVRSwa>$i/ѬhOgj=o֬L)x~D}+oBҀ$e͊3/iE͊|s0Si߅ ͆4Oj|ea,[gG}+OJ1kĬ,PO%iLa̪ ^;[qJ=J}yfE{ZϋvD hfoE*1cJK͌3qajO43ڷaZ[4vzўAzwcK4+ڷZǘٸ̺%iLmԯx)3hVկ#5P`۽" )gj~}0͊35=ôp*Ѭh jκ}$}%5:ɺ{7Ki™ڗtqIo%͊L64qgO)gj_RḣYў}Ŏim8͊ՠ*+zMCzY}%5\|tZ"LО֫z6}~Оַ}I]&Hq{xYўַ{@=LKe ﰁ]fE{ڗTMu?hV|"xZZ@=g5SIi۰x˰h6fj_R- ;fBhG=g5S+nh6|_}I&[Y:ОwԾ|NN<7͊3/V'u##2 ?ЬhO>SC:)1{ik7f; i}ڙk0e lhOԾ*"4OʳBh6u gj_[NhG ͆35٘?/QfߎfCF]N}ún|h6|}샆; )gjYTrxhV|N-Ѻ=*fE{Zt*9OqmUi4U_}U-5Y屣}tx2fC{q5r:+ )gj OrR"pYh6|:c$loĘh6|&Fkoh6|i5{-lԡ5͆7*~MlhO>Sk)mNSLfC{k)X6-v@s=bJO>SׂKܤIchVg|_zeWFў}F-XTȲkDmhvg|_z~ֈG ͎+5Rbx[fG{g5Z&h ;)gjYgў}b()gjP~͎35PkG8E$?uF=LcYW.4+kG=L`g)gjl;Pl͎35RVoў}FҴ,K+)gj Gד ͎35RZPidhv|HY,z[;95RVͪad]hv|Ԕzq͎v˦4~G=6nlfG߭"`̪,hv|~/[ߠ2͎n.LzX .V]cG=6U1Z>Ѿ'ΉV5Nў}PUyXh;߭i V-Ǵ ў}6:dUh묮iV%ɴHў}6ynѾ[=+Xu,=X͎3q`vsa;{8cfBfFў}6VWlC}n`Zkmhv| M[^pC}ncu k6lhO>S^r趡Ѿgzj::ku>ЬhO3nuJ2>Ьh߲:j5Z*k>ЬhO3niv4+ڷ>ZGm^zFm͆O2.1=!.fC_%V/ϨL/ШɼО}qpG}QwooTlhO>S~QQ{G};ӫ;j;h6|u?lhj4+ӸZ}0*?Ьhߊ}1z.0ct9xYў]z7ܹYѾo3M0zg`tnО}FF6; [qVFFu&; )gj=n{h6o׍2u7h6q3W9 1qtyYѾW9 1JsTbb@=xOjV@}+vbtѽfE{Z}<:w=Ьhߊ},:z1j{t-lhO>SܣOfCVh;[͊4ob&F@ҍN}4+ڷ&F@fa] hVy3/3EhVoˌ~̾23S>ЬhO>SyRO(CFg[yRO(FTfe4+ZϏahfoǍ̶q7>ЬhOfj=/rf&͌Y'20Gh}j=v~t%Ѿ;A3vf>͌3=؁:o@3}+z. iLώ;F<ep?Wfۋ1 O__o'7ySJ Kd!i`㦘O4<ӿ*~6rݦ[D =֢n&}+ITo-bFHOZX?Iٷ F[Sf _9V8/֦04S֏iߊU?3g$~6uRzx_ݘ}omSM׿Yg"N_PB?oY&bkRdJbfCfS%p% ?:b7EhYo;$YJѠը 3i@[U| Bi#~!j-ՋTxsq JԠesvK4v6 2*(PԦ E*I o(J2H-P5͗AyN}1Gw(P1 f!w ov69o&7{+9lL'H;nF*M;Ɔ@OMؗ1\38M>\|"IsoGe'24"DK91H e֠ g3q$&䉝3as(Len*QEUu5 M ҹnמi 74AAOOC`{-b19YQUP*MPc[!~{.rO~Dz9 [ކNl1 +Zk4mZ G w)Cn^Ee_s7`-N|#)[T /r!ǽ]M>[]s`q_wVːsk"+0Gi4m\?aMrۺWObȏ.1-_Z䏈kɺHM&5$lk$F-ߢM=b&5.bJn [x4ICƌj;wh `R@ p; rkfjnU/7Bmb!0DXkx kkVyl9òE }o,(IrIo6Mf8t 6r .W51b{QmaNϲо7Z*g ʶkTmhR:Dɮ[ClF5[sK6.Q mbxz6q?҄If.Bm ,ۛ$8؅q\R"F><6%+]&*^ <3.Ah;["B Rj33pa:ҠڮuA$c :8]55hxhxo#ʮW\w.mrtJb 4=+N-֋1hs/rcFCA2o0p`upo(0\m:=pd1EvF``$hX1S$'qĶ "BgqrM6ީfe'e1F QP*c' q^P14rKp/Xb:]u K?METڋg-Bқ e3b"&g*Ѯ0@{ 6<r ,*1YNLts}~nQФ/p4|YV2!9j޴Cu/O8 /U쭶o "UXzU^I⛍1#Dd]*@%QV pWDየ/b ʦHw-aC h|5l8/`fq OBU;˞ԅUrA:ٰQ춖̈́M*K'ު;Ǚ_t3':r&"bk/A!b 11)( D4BMR*s:_n|"a2[ݲ#Eǘ7C l}OE'IA*؞Ht{b i'ܢwȷóy#lU2E74bd]6@KZ[/&V\;pG5ansSUHq=tX咣eNaT`:m]nHWǪL#<ǔQ۪F=as]bT4iZ^R|b͒MڮoUKPNةdbA"ެa$a1],k'x}gBFy)1ƓmHLٗx/ 2{G:mTG_کy`҄v/Df.r{չD ZrLyܗfla3`O6>efy< %.֨_xWB7yGLUߡ;1,vS9<pUB@aidӞ2]mZKQۙU&|_I}ɫiiAkvj9TvC6s)-6szIeUjvs\0vpu6m8A_7n}9T'S!QWV>'!8┾Gk_]ҳU<&9ʓ׶ByzxJ[=cZOA[@|Y(Q^<Ƙ@Z\Q\5.k( "@*4YOL\V/02E.YGuӢUn.^]1NFəS+A[ K[Z*k)1 WA{)2.]4V9NnnRh쏴dwob9^w:4#4MX6KW:RU+  \rGwW=8,سy<É7|"w1!o`\c>w2v cȕ;iRoբ_4a)7wJb{q٢G0B}zd++X҃Kn&QxQXcARƈ"\:P\#LZJS7QIVhqu<{t ]g㶋]IX6 c( H6;c9lo̼hZEA tN+\D)p!\u7=D}m˂e'O[oX6dv-.D$4w 7OD wtŹ4 ~#皥aܗr3NhUJsˋy5yJh\͝)k8% X`%M D"Vq$37RPRwKiE װILWjx],.D0MݥdٝN.CӛM4 m֫۾V EmOU~`:+:paPw2 d"'{;VV_.d؈ĥLoƶ~06$~Dbu}vB˭>n|f6.k%ZB̪so[Z%ELzL5kȫ T:rT Ьja`u|R: Vo݁&]Cea:new6^PI\[C#Τj"۪.@m^rǝٳ-ueVt]J=܋l5]5_<.Ji=}4HP vAllX|­ve'._f+Ya,c>Q⭜MDXo7˙˫1 M%63[#s{v {%[?6;68m|m^ˬNx%/ bNƋtW pS-ivvD㪾ۆZHY{Y"..^0R̭Ϥ&B0)zZl/QvkHQ?/no',8=$CqY,Kǁ+SҘTjEr8Gukԫ*b6Mr3sRM"tĠhq@, 97# )bŒ1 _$sjs,Xʶu/c/ } 41Dz 4VTgͤ'J\"Q*mUq1ikj v>*o*6ٗ\ڜ*LJ{kCjDĬeٺ͑/ټB=;6'7LS8˺ASBSaclYQ&df!iT]MF9w7lҥ/j$V'? WG:OLqw?qs 0w)&Mޢ#֊PZc%LXE50GweNQ/&엠 ZÜƯdR7cf1LהPb3HHAc)}/,RNk#n)bˮES!bkRqp]w-KN[^XO;cV6@`ѧ̉zrJh3%V_Y-vϲ,-z2EU%+Fj(`nj]o6B'Y%4ț}{/g |sʴz-L[Š1UE)]Q{Od]-WFȦzW f^FSu/U=vPMNu>c F\{f>O|~ӝtb欄SAo݃SlE'+tNɥ1JTb'柨.:1)eed'gO5mDLCY73@2{rɋ$3DNs`yL3іZhDhdzKի hѩLK[r|5\f.X4k f.JYY[CfNQǻJ6%D,ydz.JNu/QX9|wwW d$g 0;90os)g~ʥ^f Xx~.Gu,wiX޾RI *<eyfe;]ҳ@2! d.Um swsn3FX_sǪ>^M댹ŋ&5dzA#5(hRs$b0 ~I&i ]Tu.oqOf^_+xUY>սTj". {@`=c1ofb.e_HЫډ))yKf[yw)z]HM;d;,t2b" H3a/+]-b2}9n{0T.`eHҘ 6a.`(OTIEuw& =iqOƏ8'LO\Ǔ'tԓBů%i8w\2ոM1;Rk[?0?{P V=yU5T*W ˷~KR "5E{2$u<z: |=wOF‘0'CH:X nqr$._7g6Q #9&i_}h4 NV"D.XRIw5%&HHwZ Fp$3UjiI뮐Js&y!bLG<-!%U,}nf|1ʏ}' y?\b y@( ⴠC4du&BL!AO޻7:,FO0Ka|r b :*AX{22أ22`P; fྏV)HiHֹTB>R2'9|\V,# y%5am$Bzya{/2K:т$l C*G@fgM_AB ̫} ,`#g^\r]^3d r6Ȃs,7 ցEnz,-.\c-T!QhiwG)8z(Lv1fbdU6g30H\K"Mt (Z_T`j'_T]! ;FbZV02n)Ez;)  9j՟!Ja Xb(jAUZ:R|UV|UnYJbbE$S״b-Le2"xx ؛ )O~GП~WC}?_ҮZ>э҉ǢtN@ſ?Պ(δ:!!O,"yl)[~HN>7bk6 MXlWwl[ܬ+3սmr)]I ïmO?|("Kf/?m}/iH  endstream endobj 62 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 66 0 obj << /Length 341 /Filter /FlateDecode >> stream xڝR=O0+ʒJ}JH l!m]T)m M{^l8 w>@EgN#<68C jI>/ProcSet [ /PDF ] >> /Length 38 /Filter /FlateDecode >> stream x+2T0BC]33]CKc\.}\C|@.f endstream endobj 69 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Targeting-Vignette_files/figure-latex/unnamed-chunk-4-2.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 70 0 R /BBox [ 0 0 504 540] /Resources << /ProcSet [/PDF/Text] /Font << /F2 71 0 R /F3 72 0 R >> /ExtGState << >> /ColorSpace << /sRGB 73 0 R >> >> /Length 15009 /Filter /FlateDecode >> stream x}K&q~]J+\2` CxDY懙,nތC}}߾8>8ۯoǿzo?q|7_9!o?E 3ӟ׊?g} !+~3U4W?WO'|Ig<'sć|v,_s}?!%lx۟)>$cѼ3~cMʟ9 M~Ha6M,4&0J/XfϕW}'FwW݄.VG. &DOmpxF8𡎮~V꣩F2[]q.Mh^ m[i:umlJѴm+ue+z8gՕR\&hN+}bu|=p׹dfAn'jzU+#r溚z~wO,h7>QcON@Nx,h7>Q|;4LyOhښUVϯ+5Ы{0O Gxq>Q7xDI }X`}·,]'ʹ|$՞=V<ӯOD[&}3fo)u>9>^zU'eyu8ǃiI㽰IﺞzSL<9&7ЯsWzYsGOU߻}I^bώPڮ@mq1`C]BjspؤN)uC3ݔJ5P[*hymhZH%>[my饺 ͌v:N}r yfAkd gj=pByF`;<,hwo#5PÑΙ=fA{UPr|=+F͂v$d!PǠh|J椧u`yA9'4 MO^0b_dU gj)O"U>hV{|Ⱁ(Sc'fEG 1"d;-Lgj^EeUܟg4+]e0G4+]:OӍt ջˌfEIT4TfEZ[°ê{Yzt??9?R<`n8YMfF9OjMpR^UƭhfHwM>R[]5F9G&p;mfFkU5wgaW'43ڷ:tZO՘Eₙ&'jMS>5j>x]hfoJepN槩3hwH#v) oNj{B3}t[# ͌vMrghyH e(hfބeȄ=&>+x'jiʾnhf^Kv% =dҾV4 MO^bEOuJeE&^bCD;wN͂v5q2ȸIh^Z|&QW4 MO@=3] ĊfA®׹B[iR+&'ji݉յ͂v5PgTI]͂v5PR],4vY,h7>Qx!9/=nED =E:'v],hw>R#0+uD.Gj}y{]h|u7t۬h6JWYYh|uÚnE}oNfӥYW4 ]9z6fA9촔FRYohf|5"~C3}Kw<6ѽ+^7Rkz]'fF^2OZdhwZ?thoAEнhF|{\=743ڷq4o{C3ݍZ|ЋG񾡹6OUUNh o3cJRfF>R{e.9+f+{$ČfFխό?י>"Vڋ^[IeveڊfAkZXO9Ly=AOhq#5׍gޤn1(+&'j/Fk)3743]h%Fla]es\hf|ho:"ђ#.GjK@uYhw#5z-*4 xK|kAzOh#5^KxBˌԘ |=n}FTIz'JdR#~UI[pK xC3H C"ڲ8ȟY苄vKE-h~ؑ{0$A_GfAө$&5\lf!|>YaGjAz[ҙEhuai;fAڋN̯{ m=}؃xk%G43]^!S"[ ͌v7bbBY支SfAcNb ,h*;s8.9M4BMh6#k aLOh|)Zb2.h|zg:uU$6*j+.Gj:1Uz$մV4 ]@p*\͌v#5WW(~|]F#V4Wiɺ}.F4+ݸʑ;Z#9$R#u;{(D.Gj,[4fEg\ @T PY͊v#5RG&8Y.Gj^KY,/ 3.Gj.&->e&hV|dh6{hfFZ^ ͇R̄By~G3Dk#XO9'4 MO@]6.^='fAcMlNoq'4 MOHqS外jGryBH ԽD.͐TTxFm,hw>R#.~ܳqnh|:wQ,ufA8 e 0,hw>R#udWj2p&4 ]H]2\ %Y}FYX)5ץY74 ]H Snh|Ԕ:i0'͂v~2nh|ϋyvyC{~j ͂=Z_,W٩ nh|~?s{YwF&r ͂vZ?O3Nq֟G4 yR2TI3^fA/;.ߓfY74 ;u&i&΃|Ժ^NF& S{zu6%"Q2=Y}L74 yRw~'4 ]=.9Y"o74 qQmvkc;'4 HcU7gh߻Z]ē?f-HYV43Hmb2;-%ul)>Ѿg!ni%B5=fFZEo3{:RkJeIXQ=Y}(e>'ZFck3[vZlԒF+11nFݯwѩ5<KXЬh߲+曐ܿ~Nem["3{hVoeZIIA5wӮ͊v#C` ÂfE?N5_dY?P?vHP5/O<ѾUj<[aGjCxD3ݍ::^pC3}+NB_-3.+6ZR;#~݊fFV\Rk1HcJfFZųƐv4 ڷiZ%Fcl&y+.Gj-id䲔OhoQ+Cg)e#~]Nϣ1ZfFVRkxh}9>ϏZY] RxD3}+oBQ{IM g]On‘K:?NnmiqgӤ ͌v#@Ũ&o5W43]^&JMh_uj蝦5&'j/ˠӢoa͂v^H m+n}K~2A W ͌vH}8h7.Gj/+Pv`j.Gj/p-]hw>RCM'1uE𴐙fF[j^Ki۰xKhFj/fB!JYֳzn9׊ &'j/SvVlVh:ϩishw>R{B5ب+UfFIn_khw׍^DkhiGj'dEݭ[8R{IUDDi6gZ,hw^҇Nh[͂v#5x~t_d~޿͂čڋ=Gún|h|!pA+.GjՙP{ohf|N%Ѻ-*fF[t*9]UR#u-I^1[,hw>RcMf5d_,hw>Rj[XCkl+~=N ٛU,QWY}SZ󕆘͂vSgڴxڵ q)H]=&y%}] ,CfE`Qr=j{EL 3F,hV{|:tI EhV|)FDu-SaEH5,Ѳ4V4+]@]L -bAH}jϖY}Qu-RDcJ#.Gj˺uYY+.Gj8XЬhw>R ۲@V4+]H][utS&fE#JӲ,FMhV|z2Lo]O4+]HeׂZL=vE{FbJ<^ѬhީjVP=zE{;hV|-Ql͊vZUJ+{|2YS=/}G4+ջêgb5V4+}wj!vahVVĤUM1bUUV4+}wj][Ř[͊=nmL[j9MX5͊v#Y ӤЊfE^guLK*IEZ͊v#[[w͊=}YcghV|{UU[Ѭh߻Y3ZU45Zմ͊v#~pb {w_ggւVoAHmZB {vVVQDffEZ׵zkG͊={իT_թVfFk5;mSVfF)UoѪVVfFk5|O{륷Ѿeoikkh}B;u uW4 ڷ2.zyzMfzzM͂v#.+[VZ{7fAZ:|+[~^^^^^|EH{fAן7ާW]ZE;H^fFVE;(sQ ͌v7bmz[͌xo;{zw͂v#g0wX,hߊ}F{0w5Y,hw>Rku3uE}+a^hfEݍW ͌WQ8{n\H~Rk[񴽟s{/-FU743]Zu#޹fFVu#`CQ۽kيfAZn}4 ڷ{8Fynhfy#72w껡Ѿ72 LdFRxC3͛|/r|C3}+_dMޝfFZ˓}B;shʓ}Bu{2+w%ǍZ~\{}G3}+?e]lލfF7Rky/03{'4#ڷ"{_`fY]ФOZ>l}J~G3}+fvm}͈v#=?؁:o?Ѿ=LGfA>RkﭣfFo4?W>!h\,x{0FAaㇿ|?_=_G)q,DubG5?UaZ5SicEY"/?֪NJ7k-?:ntmйb \}K_PBq|w,ckRdJ<&XƤLNlRZuK&$6XVqW1џU,*#.}U9ftfP!5.4RhbY"rGљ"ZI_i7+"hHHVE :|5䠡HP-qJP}rz1\]LI4}DtGfV(`OEg)0}skJQ8r)! ^7(NU` +Tه`0a IRZ0 3T:'`̉X/]('/_B1PT^ԩtdKV49 \Jj`\_޾w Ջ+Qv!:Ϟϖ|T.gG{ -zK E R3%#D34sdʑ/{^4gsfU nؤuU`aQ'1Wr$Z:GҡFd f䊹nӐ[IŽ/- pau֌(g A*r4E]fbbbinF,9P,t̳0b,E J9Dp:5XWuu} 1ҫ VZhN:@9NV֘jeE^Ñ B)c dʡh'wBd/Եd:F?tTlc;X:/qM{.|A$A#Sx)d`H؜x:nJLz<ƤL'i-6C5m$IFv kB/CpҮ =Ƌ'TgX(,If-*mr0Dq22Hy6?ЛWF?\O"C5%m$]pȾ8h)V)ghRb.ܧ|>X Ky^}ɾsGo$(\lU//:]ms)INqalYU 09jla?Vq\ ~$Q:ĹaP]/jBՓ(3W)q%"zȝ@[#Mǥ|ްXu9ptA6p5r?yN%CHM^ hwYM˂Է !xIJ n"条2_lg8 VMD cq]iS.)kpH]-Ms*o[iD,`5$5#2F- 2VdqsN ^g yI*#˲2mJuv|V[d3%g/DA #goIO$*dQVk=fBOB C-Ӥ &Hj 1rUv91ڧK4g~Ju7M>" -0KO^T.>g5gJY$$˙ #%Lb`gZפ5VR}?mq6RТoNoK \7|BL*! ΏqoC &ekĒMEpAGb`>&]*]"@F]XTݩ~{"yF"E /KnfTR^⋘8;zdr&~ѱ`kDFJRbQeGJL?R#`0¤jYp3)tyI ]df@l|]pQSNLj_=S˳5MNdYћEt~/⤈G7[2A bChN$^*x() љ^lwrJ6vvJk)yK-&ۻK51&H;&qkƓ`O [b%orh2gr%:ӫ4,si#Cz,x5;R_vg=HiEHw{8d~eB[|Po 8 >;ؐ6ŇbJVErӃSlT''&lꓝj kR.Y^n d.M\bШ$,f2u_Yh#%/2EQFD,d5t&0^nfuhmAt#OFJEگ[y9AFI/c<9^ڪa<H v98cdtlv:;1FQ`qrǼjۇ7ʓReģؚhDiiOܓ[,RS"%C D{9Bԃ[-Itȗ~% ziD G'0߈6fdq#tXmEDoG{VFo^_AV#/;P d8Qp\%m]Fo8!rN[$;v;xCKa 7$o~в0Kӄހ5mӛ/:: hCSa3ӊ#1Ƥ ȥkrza_ս|uEۖ+mboRh0 8.Ϧ=+7!zP]I7*vKn'ݐ<#8 1*[+l׆˫koHY0_y3:݁'%.Z-c~)w=澎?-#/VHHFno!sD7 +j]H}ꂱ-B]WԪ7̺Vtɚ,ZKLCYWMxqЊ;+}]Q٬meo-Nog;**sJ5yJȖ6fYN~lWd]}.;Z>/0#0F󗨭T V QBPQdU6r`|JyY7K(}BBE^9ϤŜACV4>%qqIP<ѳpnG.:,U+3ybS yU$Q@Q]¦1kB=.j/z6.񴺬o< %pWgnMvsgAC\|0z>n妹#.[n7rN̢J>dqTTZFmE&_qK}h]8hj|[\vN9sJ:*PȓJ@QϢXGhu;Y"aY/MCX! :,<+'(%P,x ;y.0WaIf:E6 / ؓ?\EuhehR"J-a8cvjWٓYIVՕP̋9w0M&c q?O&.k|H,etI"$x;IdI’A%nX%J\-7!t}P#n0G$ǂA׺N{(1}Y9rXDR8OtB/cf2ֈQ\F&jRf^Q+R95|Y!%;% 4Y G,m8[sՒ>>C&E6G%1 6q*),G|]NPf߲E}g"C ? ~2&Xt ?%ݫ~*2nUVXU۵ :*RTq<ϳHPJ9؍b5fGל*Qq74h`هiyh1H;zEdYhiidLe3lp0Al1ԇ2]<sL9 4jr;(DΟ=YZ=BJ%Bahlµ낭bQfE.y<^ Di*Vji| v7K\1kѳf)uWf%c)m1;bF;_fQlD2fee=a<,%ZA[b{}@!Y`Q }4X G<;XgT OGO:Jhx+ʓGkr:?WZzh"j]#ͯ4f/_/??}/), endstream endobj 75 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 63 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Targeting-Vignette_files/figure-latex/unnamed-chunk-5-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 76 0 R /BBox [0 0 476 276] /Resources << /XObject << /Im1 77 0 R >>/ProcSet [ /PDF ] >> /Length 37 /Filter /FlateDecode >> stream x+2T0BC]C]#K\.}\C|@.`TP endstream endobj 77 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Targeting-Vignette_files/figure-latex/unnamed-chunk-5-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 78 0 R /BBox [ 0 0 504 324] /Resources << /ProcSet [/PDF/Text] /Font << /F2 79 0 R /F3 80 0 R >> /ExtGState << >> /ColorSpace << /sRGB 81 0 R >> >> /Length 4609 /Filter /FlateDecode >> stream x]]$5}A+23Z@ !˂]V׮vtmݦl]'Uɝ~>kG?:/?y}i|Y 7ӯߧo=ӿS;i3R46HNq P_?C pvaJ&f\U 'Lmm֤C@8{+豦GoI%)"|  |IU.|j0I#DaXw>D,f/Y=^Ì4B82%U4,g~FxaT#M/(\_^i"dxaDS80;`TSG/Ay_*GyK0;`TLUG/("7U%HFy)*(2Fxa*(FxK0;`TLVG gʛ_Qr0JV(E Fi*(RVˎ~Fٛr6Fi QԷS8EoJ<*h*`v/PGq/¨z[L茸v/j)`/7V# &kF&5bF<[M58%k`.V# h#pxpi#j`@2V%A6Y%Ay#KVGL`_#M荀;`p*(~F!B6A7_QD*(~F1b6^7_Q"%0ya*(e4z#e[ iF {EhJ%ӟ8@#ԟ8D1 g (`6+`v+`Զv+`?+`6 +`v*`Զ*`d*`6.*`v=Q8F}Tcw)`Զ(`(`6x(`vA(`Զ (` 5ҹFQ/+`8 5"uuJuurFQy)`ԸP 5FUQ(` 5FNFvFc>>QE8F>FfF펈FFQk@+`Ժ VFߧQk=>9cnfX*DwkmFk= Vk?I\+ԫHzSHp 8[5NJI~=SϺ 8ܤS 8Q3 1ux0J8yUqp^{}5Ocrw?鿷+m脖~=}ɇw??{1#|F@t_zCoq8͋#_ I9=r; Uw̘ήt@Γ8a\7͔ Vـ-m<=ke,\* [Kr1sD1qUo;FGY dY6#ˋFY`v[VQݖbQ2gdn 0AkxP >f8,6e_e,/6e*2Ù[aϭ+8Y,/6e:e5PmjɷeLEq]o8.+!;X'g6e=ўI7?G宸;}~~BatvES45ZoO*hIPf>@i<K"H߬'w֝yB T<_H]ܡ) P%]AG4w([;+(3bF4= Ō\*f'Tnܡ.f Xܡ_̈e= ŌXpߣ ]H=Q9j- 84\?G2#;) Yڷ_vucE޾r2CAE޾r*U޾r_ A^u}u^_]GM_׿0qZ_:Ӵ&I69μtb ٟۙ|ϟ~_0a"{ǤO?ޚeƋ?i zC'j:uЏϵܾjaB/*jSJܞ .V9B-w7c2o{1ͫOjw>:f=.01~c~/(i:7|ß!z~ӻO]D/ endstream endobj 83 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 87 0 obj << /Length 969 /Filter /FlateDecode >> stream xڝVI6WEFZҤI@P4-큖h[G;G>ʖ)[G?4DJ0L]s>ܿU*aTb<)hEI>nt/NۮuO?w\#)_ PE1c#YqN1S\åV)jN )8Gjjeo`Sg_`nÀI+-yAd)|ڐh_=Ùkv0w7e=Ys3gaNV˂\8`74< › =!1Tt3Mӑm&E>ŚzHND(ŢDd=INS)t/BBCLP:LcOhסq@b @~-|ǘ%|гhv9MZ.Cwu8Mx9C2wHzq+lPQ,'i~4skgcRVg rXHJ}`}\9Ýp̵}~v`UA8W~vJ)e:w 񀢹wK=}BJe]4|v DLxPqhb1 wă80j@J]4B+1\[e!xNs8spԮ{ ūabaBQH}3Ⱥؘ=7+/jޛ!lD~%"TVai˥<8(sۆ-x^|$c(YWogW근g>HEJVEzAMxo Bj:o\2?&c endstream endobj 84 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Targeting-Vignette_files/figure-latex/unnamed-chunk-5-2.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 90 0 R /BBox [0 0 476 276] /Resources << /XObject << /Im1 91 0 R >>/ProcSet [ /PDF ] >> /Length 37 /Filter /FlateDecode >> stream x+2T0BC]C]#K\.}\C|@.`TP endstream endobj 91 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Targeting-Vignette_files/figure-latex/unnamed-chunk-5-2.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 92 0 R /BBox [ 0 0 504 324] /Resources << /ProcSet [/PDF/Text] /Font << /F2 93 0 R /F3 94 0 R >> /ExtGState << >> /ColorSpace << /sRGB 95 0 R >> >> /Length 4558 /Filter /FlateDecode >> stream x]ϯ# ,h%R?IX ] 4MId7(ߗmi>ymsG3("I7p뿓w#ǏoN|zo_|zS/i|}Y⷟}ߖӿOx 7Sn֟^/' |$O1=wW}טϟ 9\O]+ԫO!{/[{qo.:Z k_n4nAj+R;{;oB[0FdO>%-.HzW\E|*]&TtAѕlO.JzWSI\nPһkie 2a|4,OQdſAx B"bpAg$0*+`\BU^Q䚬~ Feeh fPe+0_M+HJaTV֯`⏐SF0&?䊬~ Feek&(7E_QDLQL Z`TV֯juS(0J [ \կ_QuezRY r_QFL0+`T]2G(dWaT%T,0+`T:纝F5֯¨CTV 5(_Qu`js͢,Z_QCzoQZTFB+`T]0G`>֯<:oGW,j#C :o7-j#@ס?e BZ` j 4,j# Y hQΛ#(#h+W`eEm Uaraqɢ6V֯(3.YF FU䪉?EĶ~F5G ZF EU䲉?JšEmR]YM[`Em2֯('LQ..XF ו+0*.XFl*JrhJqޢ6_Q+֒\@EU$teW-j#P5/sTEm֯¨}IQvŢ6+1Bdʢ#([#[kQQ]Y&Tu +WD&F!EFueڊȤL_Ta([ #+#+~ FM&20°"1*0BXQ "#2QQYY"2)0bοEm#֯(QQ+~ FM&20J~EcT``EdR`Ȥ(%ƨèD&FmEdR`LcTaA&20qEcT`ӊƨLLdRaTƨȤȤ$u'tIQ+W`TA&201*0iEc`TVD& FU&20j~e L L Z_QL:*_8FLd`=h/(1j0+"*T~Ft݂Ȥ( _gQH02IQ]_Y#2Iƨƨ(LLcaV֯ÊȤQ10&DWaY&20+~F1D&FW4FF1h b^4ƨè_Q +"2QQ0JyEc`TV4F Fme rL*2h r\"2i0*2QQ[YWD&Fd eWaTҊƨhU/TUXո1*0iEdz9FȒ9)~$v4svGl-Hhby~dz<~'D<~F|ung&aNZvSLE1ڷ=ѾOqTc82o1]1o00o0 0s:3N_6s| 0D1٢cS*h>N33 04/:N2j 0:?Nb0`ԗ 0kƏc/>Ѿ8FXF}^[7 0UZz)^3n7ԫAicRnՕv~7d^p`T\S-)ҹ͋-s^=2i2 p83VyN}`I pNW6{'򄙚MKM6'o\nJCƁԧޛ+s<ӻN#p"9wN~y;nЯG)򅟼@pg/=,W~+SBw6| Y|i9{ Od>=dr-{ö~F[pO?yi9m(<3t]ʗ|p奟0PlS($gT2>AV:eSۑOS'(Nbo@Q2`EYCS1KfP-g} ђO,& %a9 ' <(b, IIq;bEYq"))fpu,a^@" cY !Plp@A 9dgۉ1 +ӲG!yRS7(!pFھ؅v^L=opfh(.5Q(ͧ!%|/Vb2lOa1: nÁ(b#^-JĐߎ@s$I^Q_eU %2 (.If5Brz 0WΧM"̄0I2rȒ c|'Iʉ& msic|Ꚙ*#L1Wf*J)`0)R̥Y02RLC0b,#/%|W)fJ2Ĥdd 81[xj(a9δ9&^Z.2I6Ԥ9]*ăBp 2^\94˄Yjga=dH(()3X@RlY"\R!@ BpLKE8RSm\$̇bU{/gWȖp~vR@J#&!0I2d9RĜk .y@myt-[l)`>˖yjt]PYXy!]"f>wzej)fKGz/*%1[l9RL€bދ=gCtP<8C 1t`uPA}(c< A{c.|9Ref%#*鞫A$V<".Hꖬ˒q8_HSa$@eO_~WOO? ku^,>Q3DY_._|8 ]>*I7@IEjM 9=7@Aj GL7 ͥrrQ#L@EL75]@6.j ;9CtQ#h _Ȝ𱁳.㳷2`kܓݓF_>!Dק4x8öM"9!] ǍUqr1«eq׹ؿ6KJC>NiMYQH_X?< zH>ӭܨW]yB*"acW3sQm+³iWճJl_ 獊G߼:Q'}ӻ7yx~h>OU„ endstream endobj 97 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 108 0 obj << /Length1 2008 /Length2 22667 /Length3 0 /Length 23904 /Filter /FlateDecode >> stream xڴyst۶uAbضttm۶ٱձӱysx~Fa.[{]"%W05821pem lhmLt ,B@'s[a'  g`b`%mNc;@dndPmh ?@Ss Gӟ̴*HYں:Z lt2tY[9`432ؚ%E%%Ga%g;;[EHIYE , ,T<*m>7*|IQP֐as F F߭}8ZE0sr㢧wuu3uvtu0?e3sG%hk06t2]ϒ͍6?I;?FawWcpSp#4fJK m66FNNΎlw1 B8d/m]ʴ< \{ lc6yF6NWḼwf6dd%DEi?gC+c1:'7p09Y "1?dN_uoɟ;ѫؘ;%'o) nFfR3b >+ӿc[e;~t1ߐo\{?_{bw%P!2NnZ qW:A@قn,lZ&N#+;0{G_j9@vyֈERcPHT)$)'i9WuԩvLm" __oY8wM:w4coo,U:4%N"#ɬ\"֘V|رg{c$;U"viZkcvT#jtA2լ~n$]O5q 1rEREgw%qOO1y#ZE<'vugՆ ,iKYJXiwDpLʣr7FO$ง =13BpJJ'^C ! 0ɰUk]Q/B2 ew,N$ ( -Ks(@n0d>7KL˙m{Yp7lyhC?hG0 \J+]M.%=&"uOfaAdr93k GTkVΧg )|u; 2jc9ZО ֜RY㟆o낢39+Ń?iRTzPM#䤢 7 2J2غXɥse e?hE=L)qtg$) MV[ H[aftkNUd"xI;"L#^E7y"4ʯT;JG] y൛aϦ͈ĨqPiyЦdKt_*,7g浥Yia)Eȅ VquyZE[>s*iw3DL)l#d ηt88xY1Q+#(  ϟ7Dِh~ ;sS1H2Zc}FFusDvCƷd"4iW^\wC8C<.dڷBQU@z㌀[GC^Z48҂whREr\S1><{p$p5|mڸ9dwBUv"Dͼ vavOW"!yK Q3erS id}'T`?ʃ+qQ3$I;ۑR|sŌnɉynI.Nu)uOvKS"w!g,*-כ(U2f=Hh<Dgר?[PoQ9U wA`B2z٧6yJw{('o`S'2dEuSΥMV!ǂì^JWe-^oa{TYlh  >UCnqFbZmz"ڲ62w706`Dn&,?MXcPPqd=|u]&'h:R ~Q~} ECG3dܦJ3^pmY}`GY] 6(4s/YQ|B%d<B zdF^]n3StV$` RIWf: )IRG\)YhB4O'S#mE0U_ɑ C+fOBӁVIC_ i` pV59S}mdSjD6˫Ť{#P] 6G  ᓴ-ۘ@-wj$z0$l.1jk977P@&ˆRhF49Oz?|I2 ⬄f BTZk G^z86:,YwKDz^<;(hm KN6DRLbQ䭿ίNf50~Q#U";1ZUMj{~Z #(P|2׋.ٖVy+Z: :~q)zY!lz6-Ё5W6.-c|oT1s&_FJHGwchs N$fY!-Fg` ٻ+L;;=lHA/yqʅgI]l9Bh!ӯv!Oڷtq" ++=~\zU^ܑ2nxl\^/_$o;P-.x`%[kW pe$S0p˅i% AoY | l DEg۪R\۔aA'|V{/dž8GT-|E p0NMEۥӖ$tprXh TrBF+LtlZ -$*%)J!:o?xUװ+[e?#s\:/Jn6$q4S\ëNo0DH~۔A=Qf7] 7~K`YH&>"0yyG[Bo>|۵w!^QŴ @If‚} 4x2e֚S <0p*!'Uv(ҬH+3bp;^k>^.Ys 0.V!Zp*}G￳x[KWnvV0ւ5]T$rpL^ ^{4fh;QW lVu <NEvj pfRn<*MAͥN䄿_}IY ? \4*>FtVn՜)УD%^.M6/"MWH394br4 P8 +35l;WAIQMuL;_QGgT9w_'BrD彐|w!M}Rݻ9j8>_4ߡ:ySF%Y9T4TE˫Nn 7υt@Y :=./A/1t~T\~Icjܨ Y⇭  nP/ XaV,-{y5GֽvCK_\i;?g '7 N*'z&%Y9FQOM#X\)z :yhī h'(ܺvy?8׌!z-={;.@yOD0%>=Y,щΝ(gjq;ԒI'p`17Qoޟ~01m?Fi .9G?RI{;ceLٗXX#V0X_tN YWVzi{mR8 C9ʑSR{"޹Gt8Kc[\I@8=9_e$Lv/roŴ"si@z ])Q.%QzTBh4(4 ؊Hz$TWb0y䜥<' gAʣ{R,{0lČcDPa7wXګN?i?o9Μ̇Z($مD4k6&Yt/󜞮x v_dz]@iŖ[^"I a}Vg,u%sfB)8$JQO:k[^y`4Pwx &94܍Sy|v֏q Z:hBJ_؏}7F_SǷ_~XMZgLp}$8rxX)0)G?H3acRlU9cbhGf6Wf}D<$$:ucplG`ŭs.<*nOhҊImh1,c|5qlQxG| ~Q4725ef. ZCRv-8F'~]J7ߋX9$-^j3C̓.{T^&B^śocZbP'!b'$5l갑RXޛ4hahum*p>tzuA Ru!!¶{ C[@G~˻]Nk2;-|~"J="'\W(9Uw+*pP]2J/%.·#b1xk?TXL)>G.0}m+m‹pplḏa&ԠI:90;/z$:(o{&Z4*p1@A+ux|.@|m JzFu)wd/-q>@ӋFV&`?y#KVYK0˲jIW?;'Jɫ$΃0i_In"LSK7pa}gz^)44>|,AYn#qdeX s|hYKTz0S/yKXĽyc=2ޒ5KYzQ\[-smN $d^ִ2IU*_idrLU%$1Nm:㱦MPǕiQ#Bu_M2LsW=xGc~M@!{ n f?o'є\Ko(dƠe~}zz yPئVXZJ^8%]s2F#Yeͺ> sQ.LlFp{R<+Bo.4(M.n# +KJse$fB|Зs7kRvnSvd9v 都t9H/c~,R`H< 5 ƩȮ"xkh@:ըc[2!`A//G-6B6ʋaF"ʻA%aBO`IإHN$H{G,Va%JmÛ9F4icy(L]focr~GOGc`?GC=[nWچ!l1Mpy<K㍲w1OpքO/IĉBTNB,/{]`^4킳4:aMk~*8upqQ#5pTyȳC@v⻺1زVN7:usvИ4355Hp6{RG!X@lr&8 &_eȻ^ry^ vH3G{I({X DzI}@^~ri$; &ޱdU$HlZZq S՝ O_+2ʰr}7S@ V?9ġ-{9LA%Et>_ǮhxUsR-0\mD Nj(qN5Vt݄< R ~#_=Uef_ȶYXRE_#XL@ bj㙗[%<#0=br(LTGg2X`WtVV!u|c}ÍG|F>{^-Ak/jE-^ S[3FJV^WNEVY*M 8e^dϙs-xΝ f,jp`.s, V5J}OE<:5G p+T_0<>W'bI4U.BQ,Z҆FpODkhtp9lKXy" 4f=#}Ѩ E \sB _p0]θsq(n% ߳j %9 y1z Q{}cX^~!8y~k}DDyI 7/FB~eGiL !o#Ʈ.(Td2ۡ9OᏡnO;ʘǁ딇#):#5'*T<R Lq$-` _q1IC'o&V=mJ W jD^L@FY̾rFe[p SP`ՖvafV [eaJ8MF|QBmmr|%rm_qʰćn9Qƻ®9!J+(H sr,ڗe^3g~5]n)s _[SO[רx(24$f<7 U/7RAlchO<:p r<+GqHvA MR س S oP?bg-t@_#"OHs0(.l`<"{ʢa H]:ӐAoڨTkVHA.^@Hkկ~ yXgn2(z6a<ߤ*uyI`W2|8F) DKOڨ *! fj@jVx277+ھDgRG(R)^_VBo0!}.WTuHz˄hWp:n_ͲnY /=*>b$AˑT  ,5^?nuL&z*g B+ M b^_T̊ uWXDw.Cu \WSSE m%aAc!QٔFPqj01\&TzF[l0'pasZql:sA#H+O'6fcD #k(I/gY({₧ Fᦢ~>8d^S-f4ަ:X?p~%KI6r )?]hHR(PEdxaWS ITݨa&7Mɔle8p-[Lj,v87I_>{Ku7['4ͫ= Y<^N}Sء{&P0t)\m^l^ɸxc\Q8 '-nZǯӒMG]R6Y1 牲[rj%se@U冇*Mxp. Zdmnw,Ow>(ߪ{GgTqT`wEKfsrW5zFqID)̧ UfL|gݞތ \ a^n;0[P LPtszض[@d:f7c{.ӗQ/ohM~E@s9 _\uvTٻdYceN=n@u(-ȝծCc>?[y5P(lgJAN+@a)TMkךsԍ9Gz<Ϛ;uIlMcSdM MSfޤ76Ö+A~-wPsDnb͇#Ә06~6!3ŧPj gˮ [H+pZ+..۳.n4!m_M~Izۊs:oOA8!H;"zIWYZ5TЀf*qi ny-=i.9iJ7wNWhD[DݔK<+a{?iy ?Dѫuv'~bJҡ8 HL*CS`ԖBk8L뤕"Qa륨j!T҉^WIf9#>MCA`}4ף\8vLKJR7} -߲V Dz7U6-٫ƟՔA!Η[la]Mv 8A;%R_L%u*orkwbXGju7&Gy>Rխ+n(cCc^Te:ہWZJe{ ,y>8Fg3~wNۗ:"Z:Skv&9u+8 f 7+ӢacbëqL8"VI`cp]M߲ԏ݉JM^L$2'.mkA^麗A˽n-Ʒ!ȇ|I!ӏyD XГkfKYL3zABY3#>n-L>aj\&)΅am{5+;b!FeG#d$fNaIG@Bb=S (,Ѹ)1j? גC'ӽ4)17Sq@CW$i͝;ػ&d|Wϫ.'?Z\D(o?}j2lk͒M@bʯ@ߡj(He&C:(YQ1O4CKt.F 1{ [Sk>SJ 軻Y>1ɕZODXFN3Ӫ1*ܹ.kGmDu7bȞ޾rPLSqT !~*O3VsnAEdꀕ7kJ9j_DjkA+n }ԄS!鰐@ihCpE b1)æh#{mq<{AU8GAgAͯn L(N]qK G9{w5PzBZyKZZ",K(DN'TE tW\Œ:RM;X|Lr KrY4BcJ@ڛ ϑAmqk} >k@`l<\Z4$"rUCRy7^W,Ab- 6U7\_WyVLgzBWlKH_Mc/đ[t#2m3B{Rr=a#ӮU u 'LFDMGne9==A!_N2$Zm^Sgo}\nuauFhJ+=ݍ3_PeTWKzv{BQw­OqZ'>0b曚Xu$>? n||~0~!Y~6*Ҋh"59*h/ROyϐ'ڞv3cմl3"&䵙T-3$3 츷5F?E҇]9?q p_/36W䩩-#lo#N:!r:)+%gƨ'M@eg2v'%Y=Bݤ Xw3O0cI&r/ 7PoĻz8xPCT79) }d%D|*FOǠc #Gt1°3/[$zh4f\ݥ&w!repe#L:-2JA%h>gi2f~v3Ht*ɤ#|cnF54E> \[wkIg2XOϰƝj7a.3i]V R*'NN%tϯh "SsI2\)ƃ\S (stkpp-6W*IB$q?53prԪ(c\@Bm/n*!|C=+o%׌H0߰],cė!_-{\찫 GrRO 턅_YzL _?My e6:!A̝Fèu|Dĕs㛾'@?n]`r4;ֻPJ=qQ8oWn-ɟX+- +eAԲ׃*&;Q7m'Ò yY~ٮPF: K_1r3J;zq? zDJ?L#. XSXq ;V+dçp:X]n|(nCe RJP2X $ ۢ#;^WŁaH21QmP o/C9MLG,nh?*>OhJtGpJÔyqر]VyyiR,% Uy5;Z` ܗHT_JA<`G/.]o@|W2n\ DGްUM_ЖRar;fow^iu+4.Ӊ{qD4 z>uH2dxd,jI=+פjT*GPs\"*<> Kq^j+<9 :8lGpeBXgmrۣ!SR @iy}|y:Ogw)SجXtK`n_m 8hgAfYp(łXnNvM8`OsWVFDKǯ}~N{/c~JwkuK_Dd@mJ,C[SB]>n8 Y[N:,s/xzwcW`V"+|ǼU2#s1WȜyB%w<~ :BIh4}CF<m iÕkH0meViQ%H87%WuzW,j}RJU=`ՐqʚԬ 1 W\C-2~:oV =4κ6z@B KG*^ b| ,^e*̻.3^\HeT nr#}h¿]I$DgI;?O~͗H=M8ʷ s~[~׾z:; .^A.aߓcZ}20` ПO1*-B%WhRqy[IZk?`ߙ<(RhP`j~cW'5IeH ְ v_x{+VWFQ " @-HXg*b#ӕAŞQ[NG9Zpצߔ#p⅌£09JV'oiTK`\P0dbY3Bݳgb E4Ьq` v,O}2_(Ht\K;*WuG"4i6m>K&m4KP4ؔci~{=S2,?2d`DJ)B mqaHr-PYcWx3uʸ2 d2mWk涚yKMK(F @$ *˜eKyQ@r iW5^ξ@[=ݽsoO5#4kթ .-EXpF]:`1!C([5Ҵ%5,k`ZsNEBHm-l;K˨A(}?X> - QK'"kUu]6lvM(!!(O0d)[nLLպS-۟ӱS|Mך"Cz駟~G-L8A\T@0V9QEO篢Qh^iK[Fc(+7|s)иyS0}'y;@E<|&cp2aWI\Fڅ*RO7WUo < e CH&u81RPѯkGl˩Wacom*MiVz&{ Ѕ)ik!9q i5qb a&͓tlE3 SNݐ Z2Ӟ})$>QƎ5 B]=qՓ4 g5XQ_`S.;s b-&3̉DMЕ峬p랞R4`'0s,连.4b6|vZBEp7 LLhM(,r-aGhq>^7(F L+)hV¤X*EB~prRPKltѱ!Y=Dz,hprOkG v>fa9lwUyq/G6rymZ!EǤX88.}%Gɴx-se8,,Xk:K}[ŏ@ wUd7Mn3)M\X8[*A٣D\y&Ο[x;jP8 |! R2 ,tL` >׍ěOT؀AIfwd1*1s2z|kX-Ey:*] ˲k^T{̙ ЖY0Fn0-DЬ? pxi@@1 ʜ5ReM ȁ!yÿIX|1BGb (rqxL5U޺mSPց>9~9oZ mBS-k9|\9Pl dqD+)_J&⍞X6֭y`RLWs1E@zG}}&I媠W'i_jlZz1mg^e ͛ԖקrB|隸mԸaFZJRrٻ㡸 2K*6F\=^>[.1]v~uLeG(WbHm:i1fMiVmWXɋ-sh X &i?cnJ_fJu`s503jyRpj&A X@;LdMWPq32=-B-fɈ\6B8EDp h99X]@+cF.1P@?`a[vZz sY?]F?;s{~悈="](σC\.nj O7AMI+ȇc4B1Fs :9JUɞ>p=6r4_5*4R2iSN 3@7T' lNO7g)5r܄K{EUⲹܥ ~5%%?3rl_zBD,.6dH8/Չx=E 6GnX߃`р0&&_U!T9M8g!°o}\0چ I!g6uSj cڌ5bYJkz)^9G묥CرjRr'ޟaGP%ldA'YBSoBg<er0P&yĔ$y7(i'mt`/Oup#PQG70E+1rO׫!CqC(kڳ51k;I=" G\krx?r1j0s#R@[svx}=Pe`u /ܙWJ!E~KuvdE~Fp''LYQlb"ܲ"-BPA T1fElHdk'UW`zj՚Ç\'͘H>a"c-p%Pnf`3F*Oy?qX'dh"-đE~S/ʌC2a: s{5<[DO;R-n%7%`Ϣ7w2V~7;.X"]AAʉi"z񬘊#Ǹbv"t6Z[ה:Oȼ{J^10)<kqhOmݷ%!_U5&V $ +5Dc?3?qy?ػYqTU`GW5όYNd-x]N]G*S.x^`wq+.g z> m<'.[0UK!#yHᓒV9M싨nNZvS;_b:DD7alۨNJraChS3V 4#?3-.chCt1V$.:|h#tB*%Gjdp@ 0NRj#V73~\q7q-wti:y_\إ%զR|07[m\ 8>D^8@r [ 5Fr;~ŁF5.:\6 M+qbM3%'u yI|דgNN84uAAcH)]IUFX^ aùHCf`13B%: :e` L7L*ceNl-oZ[`Ө3ib΂ Bȏd.'A$iϩT(vsiZ\qv. 8j9K"Pi p]{MQҬ5â197ܺ V/2 4>+1CPQ|$? [Zg/YчP#U @_*x xg g;+=JnfU=}`lrUwC3\ߞ$M t-f`xzS14*|JxKА'Z0uY ҳYKgluA%ND@:ƜtG(}GugV>ьg7`KJڄ6'6v@&a@XȐ#{ e#jG2o(.g).aG&$iK$*aU!'W*z -55&' :U{qr@.![k;J|!,6ڊK$:1[ýV"}eP"I8\>㏁ i[IֻdCN$8&: 8(| U&e8&=i+_SZ&3M@ϓt:F4fwoPh uM<^!Vv,ZT-ң:cV+N 3F0fpCz]No2p#a<̷^Orb*vJp\Ej/(9I3S2҄s'nCc\dFYP~ j4f><])T|׎߼/FJoZTm%'İhѪz7%lh@6=&_Riҏ8䐼b+ɶɨ}2ձwyh5/R,nG>3zi_whZ',M)@BpY'EMpcy HyAK K=:KY餗SC8]wrx?N4<4iQn e].%n &;Z.!<++U"i'ľ#t9+ڢ9= ɻ6 Elx yrJx7+[_C1檳ˮ!K \ІNfPu|5R9 W[ p~dV]+P^Q*w{vЊX/JQ6Q4_kUWFe[Gf: s/8&4=_I=PJRey4>Sx$'-5`[Ϛc>U{"g5{~n Y[P2j6uϨkMcXtJ4kJOFbojd0bG3S> ǩRf*vtU Һ< ?G?(wB(,b%{?CZxGfotXglRf?ЊҙIeT[ƄK'f? y7}>/ v_u7%_u^ U'nkSߔe{i H*>Ggp g6U6|HQDo`GdcR{EOQ1pKɵGrV\ yR(ݩ(DeSQG<5>[(&u U> stream xڴzuX6%H !1] 4HҍH4|9s^7s65(rrqTT@NΜZ@[G 7 lr`; Dn5 [9 ;:; . 7{[;ܬ#b(YX9%6U6 "0@; G4jjiu5 =\\@nS+, R+D;𷻪,'OU=2?A\m@N%0ځ.B^^^l`6-_ٻ@nȫ1:v @ $[]܁Hcg  tp-do5nnsK4*] /'f7ٶwD z3wK*('êYi_&2ܜ,Kg.g ְ[MrEd%m%}! __VNA !*^^d@ζ.^> dxy~Ŷz,v6gpl@n( `-إAv#~? R?DQ AF?]`7ĴAbZq@ZBVr mYB@aK[OLNH@N;iocO{ ?@Ll)2;;Ǜ? ? C? < '?"sBZb rUNH.!.{h<#[ )fHNH bӓBtqBwB1d۹R% ? ? g? B!|j~Lursf֐.Z콍9 ''Do{o))+7Kry BFV?J!˿Z,/dFVʖT (%-t}| Υ/(83 w|hO֔رT $Ő/c U] f:T*,1)@wHZ>kgIbx96<7G%,.ҥ.h=^bE2WHq%qb 2޻n"GwAђURMPrT aNc@'w{(H3]z7Y ͔=Y?tvʍoENg$+5= L澺zj:0r2Gyta)&9 f4Pz(T--,*$X#3J"TB[=nHv)k] nA_`;S`̧50{QˁrB/D|*F0;MS՞>tr۱F㛙~VJZZef># Q*$W:[#'KFEz$cI5^L0>l6-r\+ ן!]*)aZ`NfېBKJ}pJt㹖1RB|C&8% yecFȲ&ݍ/Pm†!yW{x6sǡưCkdWrhD nr;53z,$a lY2g4||m#f%isڮ< %xQ׷ cЗS f\mbyLUJKBcYc'k\Y-YUWʂܝ!5d_,>-x,X}O7 wƜˉX9bX?z:wt87)CO+&~ g 9GFiYm8#ۭ\^ շq"w:%ca/epE#!hFdj ?JeX;r3E]. ]Q.? astf\qZ)69YqKi%iy/|v% `oԽG;e;]ccfN 6va<N-ZM bFBga"r$P!J׫Ł$$+bFH"bz$vb7lo0- >E(7 IiI HMn|L&άfRS8+,̻j{s~'vيm3+$f)^?I B<&8qbuwLBag0sT3_+)*6{@-W^0ltzFLͧ%]\\T.ħơDJ;a^CU@alܛki[(0d7D{ayUj>Ю-`d͍;C[sr1|.T>8J%Ouc 82eٙl`@8xewEmvMx}^Z10C:R_slt}fYBXƃZ Խ_-WGW<TY{HUelh8/܌a M'XU|BcFuATCjBL}2OKJm !+<1ΥS]{$"i"ƆrK Gv'+g_j3ۚkk}C"L5_ݥkO _ȪLxu%8ŭ~_R:[Tpm7_5:/g oup |۹-de !Zi2P2+u@mN*i: @")lE'F|2ۉ]TpZԬ]?])Ho I+7NR3̧DrTv蝰.D+S*W _z x>>B| }:d&J)W snĊvR"^c28A jutBs(*xɗ/Y+w0N #F?)ɰӄۜ\=♸ۢ$ZX,]~ w@NscFDf^Epxݞ =+U l9-ݓK)qGtxw/Lxs'2'g-'UEB*Ώޤ9k=y/,$LFd6wuj YflNL9 Ko Rl缯mgCFEPqxGn?!a"Є3$K!f,Ch}8FQ1Istm]ZÏy?6X.9m?)CWQo¦I & a;jwA탱*R:-/tcSr^/oF|//E,/jĚuqDB4 ^usbLO_wZq`Ω2*/z0zjӀ1_F.?cDk2\> 0AO)=#!JI&~=%)>4c楤d/'SA5?jDRu^Il.QR>M8sII7LPNGI{>'?7F%5A5˭&DGX;WHgX{-%\[$>Lۭdb,U;:78sCXb7*5\@>uXt?AP7#2bV;/@_bܝ![6_sl~59t%s$__{(&F֝_U0IȊAls^ۛh΁fs4vӟ,g`ҘPN֓nA]"u]D4Up dRʄjf׹9:.?MIu#|{w] 7ݨ 3%ܠEa rʏX^w(]$n+Z^dAIz!*^y7~(18<|"*gvܡ?\thx*ߊz¶%;YitGqr<3ݖSnM¶Y:exTAB&ɥHhܶ&G;-z%lL/Jh&% ^HX`qf,m{* XkO5,=y[R9 a'KaoAxZ6:AZ?)'\7& sĤ5vh0&Ti7ݬ RNr/HYPoj#/2KY-H}4-IR@C:3 gfq<'1K׾Xz҆Aҋg*9'TVdvK8'fo|h=Qs+zȂbʆlzjq>r qx-AYRYEh_*Y{ЩmpzWʶwXmVK脚Ҟy}޷ tZ%"z18Tm6$``oXBݙB沏5HFƽH4l ȶ~dKByD:lc n9-syh3 064%L`kk~HV+-~Sp. a;T1PTCD8|4'\ϕIDiPХ)M@_{(eqaN!rpZ"<'z0G};C;J{Ztk0ȉv <RK5q\´.Aǽ,^6~ڑ1m/v[y_"˅;b\%OuHÙMej홮ӣR{ c_fG#"wŻv AmEY9NxJ.8Hܟ>l+:=u%Åw*Y7Fb๞f[Ty`tP0&IxK}Ni91 樉9&j&B (!%^ZaapCyb#WQu #f5.o ;;E{4\j4qo]ֻY#{\>+掜ЊPE$_W;$DB8`Gq=Gy15cD#zH-QŖ9 ReGn7.3ߟȁ,V >mn *NLȹZET$=ntwb|W lkVi7 fehEe)[~v ~Vm \au}rKq #Fؔ+.H-;^fYVT 6b\vh7 (:؆7K3!0.Y^l8zͲ# n^Oɭٱ>o.-+7Uc_xd }(MCTiK~]PRNgߕ!\Lm]|n4H"Uiti)YʠlX$jǕUT|w{Sj2C2cOfBn1+0 I:J8$z, X{+XV$yvYĈ5X,׽a]"? :_dɪO.&"̕+.*I7\rrIR|J[E-^}/·:.ڕTX{ hԕ{){zځ#+ey9rE|NyW/WFſ=Wj O ;18?L|-!qyj@;FD9ƴ<5A96F DJs`U @rw\5FZ}aݬW)xbB.ﰨfɤwXfȵk,tg4TK$Iҋ^[&] q~hUCL*{W Io%jd@׫L`5)4o/y, s+ {z7+z8N[V`UhUxBz&)Qe?qp [氎n 3uObf rPb(CiG!*H,/q"8rQgP2#껠=3['[}>4OЬ+ۋrX F{^W6OC|*A! v@B=ˮγz8u׌p̤rL+)}&x3;7rC #8z֯_Z}s5SzG Ȩͽqw%X|%'K(7x">lRWMr|6F_,TzUar˦TWghV[)eU6O62YO*kU Bv ~Ĭ;yBA+4{9jƵ~GT3xil9m*P>Ч=RuojmŁ;-U T\mM6U;>lb`ȍ9P6):;šVE+GZiD/9Y"j9La]k+wUac6@Glf-3AXb|A=V*ItHP9oЧG`4^yH_&[mD1$1.}%kZr%E'85J=B__ZY2nEz?#ݨ:Lksؘ8ͽ sv&}.a6^"}m&M& /Z?ld*ȞrU ]'?Ήa_Qo1"GfG::1m}<d6^ä>~[AZH9'}z9 UFaV}C[ėvV GؾxmRӭG l㫨bmꨉyz RS>4UnX.JYԥENŃlGpo:+:8RjL9Ҹoؐa#LJx*[k[Gg~J+KZ{/l~'L[ߴXI}lYp-g41nɩ`59O0tQ;8VǓKdHKiT4O )ݹRp!7LWlgtգ~Y&m9ȨqW +j6儔͍uG8>,`m\u8wn; .˞Y/CHA^z.Z,|BoV91;h Q _"-H[ۉP+Q׽o~̈n'=< D,^ mXg4,=/;މY~n<38dBo/CgBl9r.&#{΍2KLc2^2׏q;WD]A_e:Uv ԸDƖ2g+h07w1.2P[9S,7Ud#ʘة9;ii]#&oޛt4a!O:UWZoq,N|a UL^2&n8Y\RԷ,jHhqDa̡7I^A9Gsrg lτWq5t0bWԧxIK4g*'b?Nv{VQ<>12f[=Q)4 $><[c#h@.n6y)29,MCo\ yĞɪDŽ~`xǺ!o3[\jֺz+N~t9әzaT_Q(л%llX|]z`/R-f K/q+w]KaB+gQ2L2+񷩤IwZ# h TNQ) r f*vዒˈUٲcFX3oAC1t"&o%ү=ӢTRN캷o8vrY,(MqIl yEiJ$9K6" b -/C"x*άg/-9dLDC HQk &nc?S|1z4j~0j[d\CnŖVDx5*2d=>uFh.hyWexy9\V3Cۃe0~l8<ۛBjXI!/k&8y{K>ۑ\v)hTR/JSǟgB6Itn-{]vGΨdu(OƽXQ)YneU솩1(Ϗ{$Z֜<^Nropy, ~2eˆ49;qJK]rG#@OZ KvZwJNƂ%HF5k4y8Vj-佅鯲!/;%p.1{T {\1lᣠ{oV)mAaM h". KEo:'`Zg`sm61VJ$y.79cUîTCo5QU),~GSAEeխ2?iMy#DF]}܃+ 2 4?Oьo UVݲ /.!u{z #M8|Y/6BF$nb6Znk@Koj%LB f mn0nw ,K[LYy-E6;`fp3kKdRdKbtQrT͘2:̌,\%K`KMɭZMvɱXzOb1g  ܩwk!~N6^SuՄYgHƊA2w Ms]@js,wZSMȢ0% B|X0@Ȳg.˯݉s"F6s/YLU{pG:iÝgWtŰsL fj,vv&]x⎢ }:Ijaj8m"8uRL*H )b"Py[N֦~Gx@D3IѾZ$?6iCCqm~i$vI_JZh#s(}82 P!/'>^(tjIN Wl sL"B\_ܣ|LkE,{TũsncJI(R8 PSAM#<Z͢"a˿ueApߏE}OLGhTr:6|YIጚVv#tSbkhW%ZQО 7@cK.NBqkb(ҁ_B:6 yP-i޷u1{ LGF#( $ j w۔LiYl%E4}qeo2r=xa^htQ``a, ;>Dy`Gy#-VrGRu0C__M[ 1&pUsd% sf9oh, DF7PCE/g]Oi*[bK%i>]PZ\⫅kOQBQ3a:|laGV)2 JrF]Ěpҷ iw6'_vnߎSSiZ%loκߟ QzPk5;X%tm̬e#r[z@*ş\3'IKAǧ}'4 ?[70Ik\9^3=<92SƉ+& zM4xQ:t6ڼ<qDQ*!-V9཭*#hfS [i3QWpjJ0ym35kDxg~=[T "2?T##t0^ϧkBכļܓĘvHREB`<5Ҍ^OFNoI3^W;J!MW <$o4)pLEj}x"u )1K%E'+PtX `'Ji U~! -c Q,71ɗ4hy WrB,ã6-/ԂBoڙ.ڝh-C{BX!?r,~CA RqR TiDkaHgZFdFݻگd{,!'ZY|*+Mףyl$ طASڦ%3ZTPPԢ);G99vxڹJG=N\#\K(AҢ_3c+l⾁ ΐv(4,*u}|iļ_ʊTj@VIgmO G|1Q L=8;ndB/m3-t.&<5CZT `;lwZWt u}LO_ ˟M}%jv̖rZNgm w|o_#rA)|Due~ss aV=~WVVTo5g|9*QVa~3v/~;- Ŗ%.mT#AFkK>|`S`U3m'FqSUlj熧2s9<;\f ؚ~Vή"cOv$>dƖxVN/G樮y>!U>:] 0V ڛHړ՘oIع`3:Mn _^)=QS=YIxB~M87 $Nۚ»}c*%H]לVnw,xxJnY>ͦ,_VBB&]_US`.뷧l&`XR+4_#fo*lG Uy*PѶ.V?;:paLr(^A``nF"V!U_DY=`54k<>˼Ŏ˄淲= <׾*Wj r9RlQs9-w/Qd`O&ߐwQpC"SZ U=qJXEC?`(AEׅ1&4mm,X{Kf+= D,fHn"wII'W,e_iI3f4fk2?5k,Pl@-֖*tZK~kt;G,ɻvd˓xN?*3<ԁL=aMXIq^$+tw~ 7y_؇_D6&6!f7IC"Ǐ]FoFp'!o79Lō3t_G ly/Չin2}gʣ_Bd/x1BNh[Ajf~dyԑAEts"Ԩ'{|#s^x?)8 G"ܻD.%fv?pղ{ bBoUAe,lim;qj)TmSGg1E ,'<⎯4m4 *cןsZ[40-Is^'לJ㜐OaO Hsi ?* 6 "x;jǖāźFX-%$[5uGjveܼղJcz=Hg60 <[}Z#^ XhYFB_?>Rg)!H,[26(MUb#fK&֗;a_Y1OرH?W: MX]>M O/`nr"EχKu6aig1&h-MYm7 Ʌʭ|,[TbW`p8K(0Խ'ep~s\҆eؒ-C}_&4"G~(mk(y/_ZlN^-zEQ*9b9 "5V40ob7~>})MtRKߑFuĺ^0eJs_jϏo4XW!$*0"&,C HJ8U(و2>}'𡂆1}+5 ܭRl _4zjW3xjFjɓPKf.wi>Ҕ#ۭ!#)2l4v/M k%0Hct<OZ05=^bXE4.0xz,.L wWNechc rB9W>째R^RըPQ 5O()TlBimsχ$|]W) ./ 7&2<+x}/o%ߒ]cz$Sxgy^=wo̱ٴc3jV-ͳbF#GA&DQõq_?cu[/]/3c,/mMµp:MqX r//:!c;ttض ,&5^汮/lJ96fNPa By_e;r&\cȦq=sWFQia۾%)\nd[[YwQ(._+$6GbLg/~1~ tW+BYD5,?צ᝞ǝV>ibxӫ8[l믍ҏPbwIx[M<4;<+4pTTRaWm2Ydx>7ޒ| ̟ۗYaQMgIHN^ń4S"}Y2tubF8IrNfB9R *eL~>̎o*oQ*T;湢Nڛpi?\Ңuf xqYǛި {xTm>EEga;Ce)}PDTٲe'Ŷ,oFt&#EURJ"U͗s)gH3feE.C ^mnawS1`jIrOiNap6je%7_= U/@_8ܐ+Y2*i2Cgl{uPLPBDగFF-͞Qa.ƹ[xSǓG*ۉ_.-渣_Z-8XddUw/>t=` 5?t&"צ"vL\&,˼Osd(qP*QLMVD/T*:|%_̐%W9%KG$ -m@npCҲ/ [073#^ie|}oj| 8cRV+dT-MgZvjuzXÃ!a l x;VABw!(z̎g\DNhϋC-5؀\b6WosY_$}]pCҭ2yŊxC x~ܟF1́bڭ[Bf 3-h J6%;`U1]5e;^UK&`m.i6w.dʛHE.(Rw`m5 PJHz+j$eA}sk+R 2FTNArd0cfXHh^z{cegyڻ4b3ם!9_gɁ~'g]TwR'XT?q)m>9b%cw!fZS8 W (Ik5e¾,?{<]͈8^&n$M>O HT"  \&egf;Ûq_vc[kFX8dh5cOM(kH]@eL,ADfO'>2NۍE?/% @NbY}3(߂Bd@YlJ{hSTBdv1͐@i YcDeewSQb=M?j8 IwڊA-)Zk,( %WR .^Lȇk_#sS.&ϟgZaݞ?jG6tH*Q*9PQMLDp]]L=QzLTCӶsv+Hʢ˧+Xb4lY?6{h6[{<ĝ |jOv;?T0Ԩ0b`"p5{-C&S߯ vTs$9JQ X9wMlqj;jO7®SÝ;@hK1k-gG!3Pq-VL3j3y]l%\Iy{Ve@ҍ5&^о{ye< r,*A!ҀeJ i]>BIꩄr}"ҿdqV3]y*ԻJ{O{MGGmcl%HU^=fvtmH͌-P)\ǡť)Qmo&XAj)+Ȕ}HhGzHhYۀeBŕ|hD<Qԭx;΢ئ69xKH i{=mM$ ^&[+F' u4ܫ1z#܍ '95oj?}5{&IG]47*Ty6aZ!A/A=Uwd^ #.CM=ѩ^C5>m+$>ɧϭS|@TZH4A>9\ip&p2-8}q7ץZw}0DmL}A .>k"t?l#߀ͱaꕐϢ ‚B ,v( 2U/`Ib:K[ȮLVeʗ5mh4JyZ/;oVܺ uZ 46'$]:"boQ辸@*.9C:VfXB?Zw/h^n4pd"HFRF9Z}sron 1B XM{Vy)@;z!V5!ECr٪AY(=5PtSQ1rr̆eqޮJ4,asҸIJU뫕4B{BjJ0b!7T ,r,>EC~k@0$@9%nB!c'Pu#204|bi.?y,Bl /YG3/ur5CF*bu9ލ S[8Q"FNo,Gӈ05H_Cg-]\Gɱz.vר-$|x;\1 ڒ]`pzp?;HJ!HQ,atLwLl~6Ǥ$Dmc7Cl07\) {I⬂Į7I]!-e`Yq3Y;}KsGFˡ T-YZMT٢x7NN,\ SG%Ŵw-sA).NѥQu zU6̚I ܄LkIHX9ҮHOtR;g.rjIW7b( V)@I&%oV́w|h=!iaG%   ".MsdbvYefGBʪܬQSՏd`KҜg $5gwF` t\gGqsCE`bY)!G=( [t j;k{6N\J82<ΘJc5AS ߁Q½ϵ?mA?m--ffcQB4_~WM4癞P VS?}޾/Pl#TM弿}DN'xu uAX :XLӕ>vEaMN JE?ﯧ3Ġ2/lD(YMS $ s%8v$% P_ 6ᖝλ]@b!3Ҫ @?{|mNy.ڞQkb¨z%WCkO._]pxg Fj޸=6ɻBtx`Xn"v+]à(qҞwm_ESm$hĒ H;44m 0:h@HKfTC?"knMզ._&v%!q*rYeFb:,4nCؕ ؂mNrE!Ţto!oq#I&>N6WT yϯ!WçM:N u k캷Jɬ@h˪۠vuk q|-Mx;_b7 rX }y50%L^WD\M~}޻u0DDtqT40O%<{heX >{\7PȅIk/:hwASVTk\&{4>73^j WJ8BmV X*oWϢ[I':C3؟"OSr6D?M$Lgbtib}%z\},/ޔ4ޞNmgdؕh "J<¢*%o9+ 7]XuAݗ/M0K.CR`"FnBQ=Ȣ*bjV<3ѧ-"o99 Hr\ ɂkVJk0z]6_hF \ܔ07N&},N!)#`cq%*#8d1 g1J޴pR҃g+_D4PLjz =I02# ,O%Ut:;kl{=Sݽj܈M+ L6}ٖW. "^0ǚ`1FXi7;iЍA7Fl [_YR~/۟;h[t7Rw3-` @lhhrGGPƺ*;ڲp\}ȾsUI`*;w}vΦhne&^ jy@2-9x$ޖH \;4Tq<f7 !'l+eOY:z"(w;i),E+D*NKgؼ:=B4vq]6**NDMMR"4mRzL\Ţg9sarؽY|pz ]y8[)l' ~?3hVc)o"G5?CHhXiҘ= m߬)e&IcqL0\(\4@^qG)v- Dw Gs3fd߉a+'fq)'k-@* rMo(R4pR_rq-$ *.}FhunдL5uI%79x/`5/v^X(vvzj0ۢ~f=`U6]ٶA(71!llΒT-M.O'{{ԆN_ Gz7g]$KStw505dkFtqx؛\9$|ϊJyN9Sv=|/@}j|"iKЋH z91ы3NP[ihKL酸t-NY4shʑ&+ȱ3(񣄵 J'x8)RM2G< q؝,th~}}]~a:DZ_Nu@ *nR2mUeI_ZX"CXO{"u}QǢrK{O8F3Vҥ 6r=v2!UHi@#:U<Z~tN0yrMr_KNOYa=vϻjxLunlPBdzPoh{=bi.*!sjJڗxZoMzp%srw.Bsr; 46I)@)qWp#\#_$(:<uF|VLOdXJsCAu !SBћ7"ۼW fKKݛqx$8y^Uexϥ/o3 ?hbiiWp@U#/̜^jg$%|3x`GjjN?}އ'W!"NmĤ^RG-X5Ed.!+i'GT󔞍.oqeiWٹ՚lVKትoAe65r~yS5a@+<=sZaiHh*1_9-p2\.?C"NV'黳7} ~sPt\K҄\Ev_|PmQM7P.Oc1LՁ(|DQ+᫋u\D~& f%A]^@Ch4iyUٔi*i[ݐ('.CWx%W*pc,QiLmPG",p /"RNLq[b+ya<$/tN^47#gю[j:bu9 >R>jYChIF)O|s ԣPwoz uH&{A UwSΜ~lַصTu00e7.8FlR0މuN4sQ ,]ϼiBLBvIM^/LV$*c\V{eOv, 5a%Pw>T1tvF"sIgд_ ƹazAFjafM Ю!(?y4{r'-F*avmo2)\HVzO<+}hVb{Aq?1~&|Z"$ VԹx"ۙT#Χ rF庣uo;ےĸ2/} dX(;!msrjN3l[Eh/E?.BxPu،{3oQ{ՊqUpOWyUlMAQCXSǟF0ئaF)zJU L*,6#}weC(8XXH4(sxp =:lPlLbwc pOnW'0Z?XO_`ɠ[ pZiU/^i[gI18 =:S!Ol?F&,@ i_= rXFDTd ;LNYHPz[ZkXyӄ#Yueccҡ]Hn>{p'PsW ƪSTz -ezXWZEY6z_lbKEs)wB7Fp7hr> q0TVS2U-ʞ1%ۏK7oi}$S{Qݿ9i,䯖=Ջee>ߝjZGթ+9f>RM75|ns@_*+S(,cWR6mâR y 1^%<ݤ,nN {ua^pT+a´mCz曚1ý$yIr OcT]Ęvj2NssHBmUա{ [IF=H>Udw@DY&m2qK9FQfDV Jxak+boZNMG';ZБRU䃖^'蟉vƴ9F_R@ ov_g(˨15Wl}@2<1 hZڛ y^}L?'_U}_v4W.dU)㵳`wgz1J'IF0\Ha,)d7X<rb 7hx`efΓ@{bSĖbF)q!^+UX.*4pHTB%dY*BMM?Qwb/^ *:B*,֬gJOȕQ `6dR/#;0Y&mou11̶GU|clݟ3γZ! "4J٠js;|?{hIG%ו3?8ڈ(yf6k# oq5G"H'DNխliZ=a"+\N5n[tz Q>W5v%.fED<ɎLg1Pè٨_ʹƆU9 B u^d~=?+7$PyDɲ4}1|S(_z ( febi_0j$~B8xLʌY ΄q=E1 ]˹IDd|pqW up<&Xό'M@p_:k'wօ=[X 9YiE1 8Y{',7HRwdwU4\CE*XfD`GT"L^3v{X|dn5jI_0HK@Wɹ/, }!^GMsp/ ITe ~Z oF:APͧe$v =twJ^-E̫r"7o =]oy{~.:t_Q1bB84ڴn:1p@^y$z@yb;"6Q L QKboCrtפ( 'iw!bo$j D-0UwgN=:& A \vؖ< G Ҷ-uI\,_*aN/L*sFbS~I'>C9eР/~Uo>//z ߰.Ƈk@ 7ck`aGz%Z;cXv=b8S׳g"֌\:6phƊd8!@#"^*zjF[n',|@w1a9J8]Ol1lfW4Ve{FpI, Z:w xmTńuȏf +#sȳGFɒ%X{Aө$-HOEfE ԋQelxYfo}(aӗH!e"D^' 1۴V:0ċ k7BrowIOmв3ąpEMGNcLE-G#;{3Q/.jZ (zg⁆hX |hF;T-27e4(QqL%<9? m(]u[c6:Fc`XAl5BM#}{w ()-'>YuplQ)V#=c!yf_Tpd\g'u3ysZz^dD.~-a+FQ.cj[86ʒp@k3oo;X#gf/N pf [b)}8p*iYDЯ.}Xb機;ii'xĮwr< O9y{WKsߩ{VkwY$F.L1AËKh??w;#gUd05<[#&- 풰s_\5rQerv[9tcepZ>w!@⽼%Ed: W45Pz~D{*Dj,<KG챒.p{>A,H -!g>aG{p:1b6pcf.3y b`X9KF%1n2n;G'w<)b,:~nj>i^"+-ej7%77MZU 2h')1a9|C5a[I()}`L/SI<;Cw:ʳ%Xr*s(W4M۝oE~>o1K[{A8a;ʚ5U gmj`[p4rW_^4XY%CyoHK3x袢 ?ɮێ_+H D[)IxÍtڿ=T[Y|t~[.Y QHsZ~ i΋-{Xt =3Ɂm-=%jԀYGl7ԗ'lL7Sߞ oM`#{挼J|GP`J5 C}oh6en@}٭0ߗ,{^JiBNVNk/oÊ\C:-8?>l<謯cD5.:U z% E)gWjgYנV)΃Eےj_).VUe^*8~OA1" [m`Ft&&(*SuC{}Q~KdKIw QW ԒYs=\P1Ka!UdT[ᰵT%_=X=7R|KR^6hegڗݒ&X5]aL}TAt#*gi]PK&T@{y)1:.Qz j܉ ,Ƹ[39SUz؁]}OÒ E t)&>M{7ryJ} =j^YyEG Z몫а&uEB-b#hLifOcF}^#A endstream endobj 112 0 obj << /Length1 1925 /Length2 23122 /Length3 0 /Length 24293 /Filter /FlateDecode >> stream xڴuX[۶>^]Cpww. /VN?=s~ɓC9s%TYQd 922>*MXUnv&6&JJqg5Av(["P@w9 t5QrhL WFSw5H"rrrO?bL93[5 ǤPy 4 )jjiU% e5Zjn "!UT5j>Ձ-?y +H(K2YtvQ3ڻ3+WWG>ff&K7W&%_ԭ] g[h0ntϮ>Z\@+K.w_bpos iL\`ob t0q0{7t5qus%{ͩ&9;ɡ/u1|L<{L\Q\@{?{fLATQVJRM{90*ޫx<,V^N{J:Y ){\A^oc:<|şڛ92k8X;e%]o%:fV/Ĭq9,L\~ ;?+7 w&RO5sjr-A-AϤW.)7;;E{ S64O2aKr7/'\-u5yQK;%3Rv~X9ll{oK3[ o7{!{0ki(~ԡ/;I3% `l l6z,f& `rFlf?;Y߈]]g򿈓l{_$,,f@V3=?{l@? '=? /ߐ=?hGv|`v7d{'ϭQs<5w,ޫ9j [=& &֞z,C.$[L ^WF6.+;;;c6N5k`ߛ_=f+ 3POӕДL_p咠V;$ vɀ%AJ@e ӂʴ)C6[SnUDL Q$E54+hOt9fےڈcݏqlѯ+ =JY[0<: ;]?b%Ě8vhbfhoMR+ Nw X8+(e|)&[RS,M`gO.5;!kOtC(Z6nEGR% "{嗮;jv(>+x`:|fEB̮a-d!?fAa8HtSde3N`C~sE k/ d2eK@!Wt*Q]OSXscw;]Yk؅o7uʏ:dw/ꦄ@l+G4p#VqݣD_U:wGЛq4Q7e7de _s=JWp =2iь2|KC4O&J PXל꺰EыLsHRY[\l9Veg)ol*I3孽4l=pDU>9/V?š,hSZnKW3Y Vx/l7\BYk{Ҕ gnތNdBtiZL( )B!ßЌͥb.BlţyK5r[`qYw&WQ pAg}Xy2 =̚TA+l֑^B}g͡xoڬ]PG_xtws3H/AZ_/K:M c`+W晎p+-)|OA1M̹@d_FќZɕ}AׂazePOB[`qF!&Kݻ"^wB+ZMΥ%Vn!p:Z-n h)"o11=`w-6=/<?n hEϾ)UHoӏNO`VB7^ifqx%g׿۔9w2 ػCX=ۯFjM.Wߥǵ7f)dWT Y37Ee6ȶ[-?԰q 6Zfz5a&]>/~6+:$=dk/Pu^h_rb~^K/q)x8|!tvyv{{ä4Fp-GLsG7!l;StN>u 5UT6e6{'eX'$!coJ[@qΗ-V ut|"(v/U8or拆0NvuI[63u):iC[̴gR"k wؙO ))/32FG̒Zx;'DҪ@E_P`xsĺ t vH=dg$XV] #-Kw3]?yo}Hsg4p$7Tj ce*vR38䨐  MrNSS FYdO0M1(H760aB醔ݺ$/Rzq"OfmjN_ g0Or]Vv) lma9 l!Tb|2 1p|owLFL-Cp'9>IQhbNUJBd HҒIl'i{S~226Gy{k7C_`SI|> |1oKHhhxWseG<21f斵9ؗii`6OUyH}V:+NY'3텷o ϳ70Ox?R]aX4Y|~;OĞgQ=&TBW h YwOl_b5b 'ܵd9S1+AdL=A۬,p3nL٧te\J<^\%DI64&̜ l{V^- 8WǜzK",_pbb@(87&}o?fi=4J>=n.j7ym7J$62>I' MmKnv{0 '-sJSU+ۧ7>0IW -.TЁ,M5gOS#X b$KaJ_~Oe*k}"bDžR.+RuDUЫ?pʪ_g>7Ms=ARwiV%P|*ڛ$Rϧ1aqx5/B1O%U%%Se!ūS [v83 BiaOCeWf=] [m]>5viA)$0*n.z"W_Ͱؒap 0\CÀ21Jյ7QʭjɤU~d:%ֻLhm 3%$ 2-T's ¼>U`/,}m*W8@l;3 x@@eDdNH3Ur*ܜsiQJV4 oѝkCZxGb8UlA YFHiۤ >SS׮ *z#Xqa֭8XylxZիi[Sߋu4^e.'Qu^qeT\F[9;`kUaKڃJ+zit$ β|lJepyap.{X~8`fMر_)[al|3Z-1JkMU`7`,ul:\[YJdL  = =p( o/L^Q>H\KzzJTCC;Lp"cP>NJ. E_a8u֙E S$.eXd.xld U ?͡q08`-uRCO5K)(O;iKSҐHu!n>o?y[jUσy&j [:p0fUC7X뵸EHw7Hy'6ڰ@IO)b'}8)}ރBµ(t Q$DC2(~L*")p]rF:ʈPR쾍E_HG9i(ΌdM(VEɞmK1>CbTRfGgߛK\Dn#5::0Lt;jA|b%lwN6y* .GWo޷i௩1\GN*Au_Me)u37k>u:g*?Q-$}5sH٣a2CuoF'*KKVN>Cлxn(>k~$_{D]+/lC"6spAZ˗3! )CB(4q졹"Q- :|2,ڃ"y*tRo9s42Bh~;۟hֶdMqdփwRּ=\ghfW\EIGSGل-O-?O]1uv]p(4}JQ~d38vlk[],hr.x@uk8'ŪWySr4~c+%sy#fm3̤vy=H3'\ CEkh&PM3-=:[ςaB]?6׉\6\ƝڲcOI,GKH zdZe[M|qEB"@^8rU/B00IǯR x0S#ba1 WxWQijo)'VpmQ!"<$+@znjO`Dϔ} yWZ=[HA ZɯIzܟ:"OIKMX>*r&DǪejWy&ڷpKUճ((6v$J[ukm3|7БWu<"sGXvY0zi"+N+N\Qn$5^P0Zܪf[Ȕ< pRR#L _1ھbo:}JDz&+az2Z(C:G.TFiQUYTXp$ذm53݇ڥvlWbǃgѤu+-1ŷR^7]V8MY !] UE^$)? DF]~;rb5y)IcU:`[y կ(@sovK$ud)eOI!S;pb卵Am'T4V\q~ۓ*ⵃyTr<85zZ Lpd* GlXU{Ae&MjFNG; ;e!xxFF Mu3FT˘8"U:,ox'SݔG,LϨ .`Ik%yEЙ ihyǽk6uuG='p]Ѭ(BS"杩2+ IZjC(ӣX{"Z&XάYK!M:vu).*'qZvG[&oG+zlc5se=o906ʠϱ2"Y@RliCI s0 FEHq~&>0踎ĄWIRO+lGXOH0k}M8ՉUiu a7 nLPMq5z5nߙIL䪒%d陣.pO6ڄĮ'Gx~] d:!ik}/ݬC{BO4j2*{iN-fiNB,ҹ9=;Ju|qbq?8γq-՝JϞ~*reH}1| v6xsp҈ W5WM7^  }]rI=p0pJu4i#6t v|T!?QnM>Scv˦s ڵ#[ʛ۴pZN`ip'%h*3|5b;I9fh D>&uMXm_olˆ"RHq}~8\lqW|i]nKOYHùzDX^up@U;RncR7l!e@/"pħٯKݛJDj iǔj~>`LNehRejMötq";]1ۤgmo<a=*{\MM4B3XtRUrJW&]P[ % 9Dؗ0Q޶tQڟ[?X3ţ !$Hkgٵyg}npiSa ]oViyuD3V }%SǡXKrPQdKk+yD0|D' jvjQn-"̚+Ī(YFR=sWnQoDBIJ~,/t) Iob;,w$.< }M2_*Ǖcr|*pvuMPhڧ 筟OY04qIA(I,B({K:$rJǐHJUW6'I31zM2(KOF˾Lit쥢o^z%ZG8]0V9P/r,<İءC8D 5 /8hkn1ۈx,/4!=l%n~5WAZsh-p"Y?wIUb>z En2a75󍈈N%/&J-G^t/<~%+tR? lD1mR sZfW6iad"&8Cv뵡s&ZC<W|cʪ#ec "*E{c|JdUP`c<86+I˴lfX.3zK:.DAVIrUNCuuKC NO'/zdm ;WsU  ;@H]ۀډ,#ay_P OԯY<۠Oyq!_ۊ&qީ$#uF*)S u2Mr2%'RO)^ ,NbRةwΗX3qC+[0K 9n#M)ܠqZilN#M! sHc}m%ODle䖕/L(0D=U9֌qPXB"%7 ֬J&Ӱg,(Vk\>\vYMq2VT4ٯpV#zK+!\vُhїcƙK0FFd9Rp3Snl!ȺlY7Л,fۋkJ('Nc]q1:`XϷKT BUАEgÍ:-;U[~HB2ޜH*?*ajr_w ^bHa9ƹ:>> qͺSm f~EPmŠ.ZxP ـ go>M,_ POƉYZƱDlCE^BKi.k:is!Pɇ>8:{:ۃ4$?Bṕn Ќgdm$ NB՚K~RZ0^UuEVHFtQHc>sG 䰴˸?)W̷5d; 18 BSښe{fCEoh\ՙq6@ߩչ4+㖮Ǥ Мq @5i"{E!SѹK>.XPJr3޸|z֌)h5+S0 =1+Gxƹ"?y^`R o1F)1Fv]Z)G}`R҆`x[U)5 $:1&9׶,uw8بRk7c!^7(ᖕp`d؏1E&zG&>jTLj'ˡm2 WUOg?OTߜiȽh0-aEhզ5s$p8tjuvvvM Ga|n~vS ts[5U, ݔDmA٭ UC*d.޻7Y^@Z' Z> @i  ̄n v7Sg( fqV"2g%Άyw [\~p&!-MDmiO盄 9 EaS2 fPSvB ٬g= ΰqR *.Zrmʿ'lpEap"Ouc59mu=ǽxre^{/k?bQNBN ,G#tuj)krml5 6Jp7:goUpsca<]á7#gH" kh'[]1?C--h^krylOHȟ3Vu9Ȑńhfl( 3'nKk/jxֺG uuk _YL&\ϭbt2ܩ.2$LuN>ankШ;/v^Tu+71e31p bAj0 |I{#̯A].j$Pnl\dOu`lr8 7YV*Yc,'2ӆz_\o#kMhʔ/mbׁ^0`&fnrw[ɒ㩃ҭjta!WwW l2\5~OKm ?Ee;{*x&Bpɲg;aDºkjASy.h cR(~7OCઔy߃}WR8Le+X:?W,4|b-.F>[IeW1GC8] }L,' kjc"dB_UQi`>Ri3Br&3!'lPG!$e>XDi5d00?H1igK[|9ʵ y2F9iMm\: th+y_"}20+FޚJle=ŷ'r(I ͭC _p(g}`ִeM7a 7ڧ*󗉲Z鶠xG728;D$nԺJ'#7k4id ILO ԳW6f<}⒌B _Lbk>lvuU㋸rNj9YNuF'sx\6R v+4P"=97|3EinM-0_!O`1Ҽ]F$cl9npY !$0ιAXmTO6pXBs;t'h͓!^>6 c.HL~dGW0cBc0jt3W ٓ/ : o ?{#~J$+!ao=yJF1 ٦_$T+`˸y;Ӈ9dȇ\'ׁF`E'֬r0*C+G9 odsq; dR˔693N-D~65$Eߡ창M^<8hСD:+)Q$x}h, ;VNNYaO{g#fwKbϤ+h[&^s27X> ta g >Ӹ8tLo a.,UŸ@iu-3h$aߜ_BbjT"to{|jYգgt?邡n59> nlQEm=XUO,Sݰ2ߛpD`pAWQGT 1 ,;]YQ 20 3Ta]YǮ2W[vwt7% f9E ,pv6#;WߢM7EK(dQʲ9cҪ _ѓhCC5}G+tyl?q ǕRSʶ˂4zD198kB0YJyjab8%}.P^Tj.SZ1/35 vxث(tݞ=FyRiF?ȒUVI,T~kٟ(Z;&@==CSLD^wdW[jG8֥;;"`CGs}_ -ً 6bYy9()Wk3n͚?B "W0()/8w;L*PD7o̦рS=S4 @Ʃ-.B?̭x0gxKv->@!8,X\j!ڷ`:<}bunyb}brRWUvJ'02A| v8u[ .h#GТmG aylN_|S}ImWILT!IuTK0+R$Q _rvjئz>}5M7;M0rLPD\;/^hDƸxifv\oI+ԡi%&_AkHd`&QZ!ǃ]S>hp5oö/o;lg_x;QÒ]!kQ"QxS 45O1:M)?+xMͰ-[RSD5:x?:G];`&V*/O-YMMocq/OԭSJ%2ӚYiC TԌ)'hi E#1\yXSypMG 1 ,-"EؐUAI|[X21*)fqrRJY8f~ζV]ȑ30҃jeSP"$)$B3nT@횁1cw:K?]]`\ǤPLI`41KAb|5oArK, l .u%?Fe((ypKI~zSw' 6G ݱTg4ZC8/$Uql4hmr*d jk']ȥa6f :jUwqRd1Q,vCĐ1&E_)Zqw :`o__Dp`jxd+%6aN[f!8tDxHq{pMUq(L߬ӄc^tffX`kT[agIthY WOL Yd1\p^d<8fpˡ'ecff+ln5+- \ņPɶ'b Ϣxx-,zUb %p32^'& gܜnFdMA <#lcU8[J+mZ5VU}[/BWү\Pup0?M"-a_%}upIUX,AOHDO"]M%JHKW+UqKwFOd.%Dk[ T#dV?ע$āM7GV+>e}mm B8ľ~0@8t AO5BFO={cέzηB&kxd' /:ߝ-„Z46O6{Pvߡpz Ƥ[t#j1L2pؿ=}]{{eb? nyQܼ##ð>QNrQ*$4Sd|xWuԥiNt"%~b+h atڥaV ˏ[8^Wf?=n8AEun_viCא`qQ+Dy!;䔽/*C0DQy;3:zoTŋJ$Vchћӆfe-R)eک%[MiIfnu; t9=I~YN21t&pfjdÃR 1y}mSjC:^Ze G|lE$Ex$f:T^rV :ƶr2 8⎚4IY=QK,_ug$BzMJu qN0[s?!\;=KoRi5;_ Q,FVsdqP x076ܗPhB.vWF8~BØ: 0%I XBӜuհΐw[TeUkLM*`歽vT;tENkv/~';4W~ڭ3za=íqɪ"az}W(]0EN7VDnzv6w JހaC;/,JH++׷=9ⓞZ1K>|_fB(6RPPϺD.ızP[CƖ |'j@g wY]>͊t AMä\LNujQp+0K ]x$Z)ߵxs&y=:jxihGXݱ78`q>0;exWȝcw"DiDErT ;nV0E>6<!}BuљeiUD]ރ?YnVsIj,'未.__a#|Rx؋Ao_9YSK{nClb1\X]et'v2BV'WTݡ `KPITZTf pm d0!2mn߫`Ѣ7Iߓxj~)WaF$фUXQ72^rML e5쟂 Y,Sk*8nof9NLW\}.N:/i s*%So> Ҙp m>u0»[/ųJDx,J63Y}aa˲xPl J#& ݫ\eBv m rS{-VօjW6 OBcRc/YL`vRn &L^L aksυN)Y,U<%+H%A0v.B$ȾD80cO"M:8_n!#ϡ{_p* siA\[i*0ao8GVw4~kw[a64jR$+-X;"$&QJ}'|T \X"du.⸑*=\@2mAiBKe)L3~l6z2qԅˆtG=R// TWI$nAX%Ȉ{j^W|nϔi bpE?f ,: 3_|QPJ \><sr_kȧk}%42~QD'1~t,^qX3ƿ K|Ib.Q&p_ 8͡y޷L4/l2$lჼDiZdFG"XJľH 9dQ aNwL gD8?E /lA(S4#6,iUBwx]EpB,g. -UR; 8ĮHG1k,%N!q3 EG\= #2γޖ86 ,.64U+~~W~YGU2=jT i p#sEE fyL:Pz_y<"q' b=JkhH_h'uEG2yl̙ .PDދ _=rvcyKx0};uk–+xSrYyOeb[RvCqD}.#O"sC ԬVp@K4ak#P{Vt>Mnmv{a]yI:Cd[@qEq6u,"߾Njogr7]@,}ƈw͟ǹ|(FĬ6"vh.2DPycxҹ;c phFk+f^:<p•͖J/$ثiDk֩ 36Aծ`,tQ3FHL*g.)z.B{࡛t = ԙð: {2CPՒkF+Fvf{y>#٢cMg4$?6%[ŜwOQF"(&&:p1b~Tv٧>.NzԴn2<ȜKup?ST KJ 46l5h;HI{ۣ;qO]Tb!'5opc5}vƵΈ]DwgZ@a7bZ6ɶV{NK Jު Yel xTc*D ~?9bѼN|$9qtyEY8vÒfQfn6Ph*UKHV>tuoڷ&FNskL99(#Z> 7<?"~TL٭ \WhStYf$EC蛚9LVLRQ90`-T7`,R:}5-i6T^MP|UQ&9|8)[<ؕ9 x[p`X8t0  e}y@R3%gv6!.ѥ; c|cxnyoef|WK](ko- RRZ_L\K fKNH`i{%\ropğr( P> >4q5[+s w\᠀\)y ֋2D6PJ[|ż4蝂[;NwvǽܫruiMҲ|.\vxP#K.A"h) 5I!7ݽ{p{~ʕ-ƅvC:Row{ VXFMkݍU0V˂YdX1vuȹ9g AC~e#dDks|):ՄY*Mn)pXoC^F|}&'U^*,XR'7uЧ5h,W~&bmepx&t<,y2GMϻF$բFc-|r4gYKZW zH@hoHpk:5;͛"jz9Τ(q [J9eiVIy;E#˥3W/Ӽ');G]:gIn4=i=ll!h*~mnOd3D_ # T,nLil" fCIH!X9(qO?ЍwVXjx.}"%݅7F8 sGC٠Zw7#HyuEN%9Q_Xjx:ϒ'@۳j*ĥ*jId,DgIt A^Ohl,;^(KwBX'VF5cܓdE8 "I"5v^'IfF邆[Ũ1׽äsYWf('+ ihxWz4ʽK gJg1</K/027Ҫ{Le8~oekzc@0[SFW:Sh:sʱ^dKS 1;@#iսƍQ-z" ;\آc6Na7h&io4`!E_ZS @$S]lZ7M~&%L9&2"Ro &עJ+.S" zȨ saEe'7NJƂ:"UFɉϣV!ڞD n'D6H4ʟ-.uR0d[ͣY,v?uV/ Oee5mCNA_YCR0a|dzm[\VҙސxځN{wZm#H"'\$=GPWO$qLT?*\xŰ>ETxsz`ݺu 'o?ҭ&z96vJA/Q`Uⲹܥ ~5%%?ԐUl\#!mq*r'to/L|-f'r.KdlN{ aK7Ib 5|thjcu2e4fVqڠBI(,^-'3“cby$uCT_c(e,zlo= sZ/wdB~E"u!1H8 l$P00X u-L Djt^O֥e҂f}Le[`p>yg"#(?Uy6¡쬙!n$,{^* 7m;Àz0Z M´1Acuj[z% ɋss{IAz@ m@΍\m~PWx-?LiDD\uL'`%b~hyLf~hUS}iLS^l͙Ivm0aQ;0>Xe/z"J(b66}? mp _olR Iɪ0W ӗ- "YzB ͊.r|& ߅M u6'j\`.jdEEJ A޺z}qB](<*Gu'yO֗^L+̩㗆x퍨8KZP dzR被؆S<|Ou#NJ(\妁z@a, fͽgc~؏hQ "ym8LT@VL|"ߠkPz<9РP:?a,Jht鑳+c 8 퉶Xi֥K ~Pן5A|bͧn5B XBf'1.w (+QBYFi{lxw4 GD십_~,S!oyhkأ A7 =FλO4b5ptU E(iRMlqGB͏_gP:P\?\Ys푞U%{ Tl5wzޓjj'x8nVDy|~?;;@WC"7##o_3<$054MlLz e1)Sɕ9-ۡO`ub>ؾDw;{珍q0b wDSN!Of̺;,VrONfƮǒ=~eO/s |0 sPk{Q%yQ^>(w Z[IzrkNamBj[66࢓J 7L@06G*!f:QZ*%RD;3硓?#=w@+28ZX0=&BCn™٧J3 8ӄJ5'y7 a<@^`oX{f(\%2ǜ*ΐ\Q#r|3{ffqߐO6Q%9uz*\])6`~uS,Y.wFBl3iT>6 <*uӂ63;_zڭXLRR2INTE4LӦq@u$c))n߀?eu9͈_IN17 Qǖ‘p"+yI^n h9n( !ՀGx!>40N\CIYE ޣKgrT]1v:c6^ F =C 6n,rxF.)>ϖ0x0> Sxݪ N~92LpGR{ 0%Ȳ+I[P/Q5ݛ_>ZJ؝6Id鄙g.c)_Nq%'_Cm=nH(TT׋0Oiڡ ǹlzR9xrNvkpM<y7. wR&9_AX\ Ivxoos(b(g^ T\uhFNKig$N '/Qmن5,bI](~*jfꦇƿ!xiiXCEzJ}mi{ceEf0h%ߪ+%C`?+ZN1_bL}hm'g;ˏ:Ϯ6~ޢ.hί*Ҝk9pa &ay"n Bvkic4 0/#Vր*v2Є}d(ϧRw5v_D Z*{9Hd'kj ;^{;{]c9f;~E>yrLZ6|/I$SYl2 *I 廍]F=GeTH(jK.!y7mXGhTaWGMmÁ.XMPPI댞Pf 3:O ZkVOEkLZgfͬlb9佊F/poחzx_E~vh?¢GZWQ! ћ46c ȪX5 |[=.xE=R t J,/'RTaD?mdg߫~Vа~tOO0iH y,ʁ,e=&gPvmᑮiB%ÈvOHS>tO9`Cz^Ny؈ʻ%>qUu>XuC*~dIjbvFv @O lFB3Ǹir"reh Gsg#6/u~`Bvtλ)Dv5ַw'mN:Hr%N*!hi9tяծ%W. =X aqrj=nDSہxP>*= ǒGz{]7us];̕9 ?aԖfShY]o2^r5o%K=I-of$s}yo8ᦜd ia*cgT2gGgaTb$ؗIײ(ħ$"`!&q%"@HL eJIM\@JwKۄi~gq7=;ӚZ7$h(ua__SM償 rEW2P!lN1Nwep$Z`"p6/g2>'ݝ#(,y|238t`>_4'H endstream endobj 114 0 obj << /Length1 1815 /Length2 12363 /Length3 0 /Length 13562 /Filter /FlateDecode >> stream xڵweX[-epgpw,A\r3SlUɕ՘LAR`Wf ?@^A dgjbgm`gacDwZ;%L\AW+뛫3 ߔS/DЙ%(;2A`Kk0EO f?xgȚ:xZLYh sLAV&v :H&VUPVgy .jL 1EuIH W~oPTf]AR]L]GYg b'pyc77W g\]YY=<o 06s}kaA+o?UhmJv^s[C%fghbߒ[Y:Eg{YHY{̕]ͬ߹v 3oƟ{߷3[kقA..NοTr=C -!z/3I5 0qv6Bb{kv..Au ptsX88#U U `U`5`~k\V+/G+_ jo`uloһ;5oa`wq%:;؂n#a`l7C;x0sry@.?+/_Om)9R ' i}LMzKXd\,5El"z\1D>H(-0A^?5\Me=z聉?1d&FpZ`ElnN)BVGb)@cL!}G~Ef>Gs xm'>d@laѸ oRα K$qЅ&nI6;M[خ#UXx1.;wOt&qj\F l%JAY>X hTIaŞM7Smbbkz3QX)1<k`Դ!x2]:t"J+I1Ʒ k/m;^ZCe'%4_.o^9`WEY}kqEGX賡9E &%y賹\;̻rȤ~7F Xc9x_-fZ< s>2rʑ)RƸCXQ$hD5?мyʞ#2ZI{Εkї#1cIczTrLv2lxqF`qi8\q"%q&dE:uz9F$-ns86OB{Mȍd'ly'ʪDIy,WT Ԓ:$F)Z>x>j")Y3HWʬ;i(;?_TX-]r.ψIځ:7 ;OrpbfKݵXbw'|_ag5]=~9|Y=d+<8p;)F:ƅ{l[Js[N«jG@%a0Fˆc]›)rV)߄igKJ6yu-qs; /HEE0IzTsWԯ\#xv =~p>C3_Jptg[Ё;ծjE_`6yqhETgu%RW2i}}:`JI6D9)+ه4Aj".FڧXKQEӏ1B??Ad G%Yq Ѧ9+ h !z/D#AG/ۋG IW>يI88 EfBiPJS/h*)ۗRoPTKlbnשmt;#MV aضǕyz$'ym"iӆgٍ!h7qɹ$Wə>c`c^v\iܯ-CAIwRC8H*|Oh F4tK"Dd _d?EfSL+=QkH+QK|"vf{$'"D89Lhpl[hGv≡8# ni$SR͈ӣՒOƘ rƫeâ |@b:S % (kXfZ9f!&ޤn1m?s XY}Rj(4.-k`0|EPDM+-k''Aд+ V!ZJ<4*zH+ڳ.Bx}\=fE&T8TX"^=`#+QϮe?o?iۯ+##/_}${Q`FbEk I i)\Sp9PmqՖV.$|Ԍ(o@ݷk!RΟ2bٮc6 :Y;p^M>cOhOCMڏFAY!3LQ(uεԜِѷV: P '>}8[mu|H#jT.u{H)@VI̕ZQ@D59dߝ~oc ѷNGfS3xr ߚ&=+2w3.XGkB ~EtZVkb5xcq9SӠbqL;np&c7kpnD͟ɦ-.WAj#wXDt~IB1>S=BiL8d=R';f|Km_W`HLP`՞?"<:L1".Ư2Q~qW}98EXplMaMPH%yᩩ gKJ#t]_ 4FDtcտw5%Əj5*/Y4-ESzP6! Fc~}O) g$G>~"Τ}1/?r|\hp =X={Pq Oxe}E0(}~l޴mEӎ~y8Zq5>)62b:ɣ2_>UCɷǸˡon>. Ytf6P84R8.e "H5=KL+S4U4ީS|I2R7%φR+ ۬nn.ۚǃp ba/ 8/w>.z+ג?L=BX,J c7v-h*jv);Ӫ0qI/ly,@g,N9 9}?zh5^5dl˧.K/+$E?}fm^x:!/xn.nE6x $.#!94,VFϰJUȪk?َs0,;j,Fa4O=Ma4Y4H5vrY2Ț\zln_UHUꮫd&5novjcRsHG75 xK=$2VvflrLڊh8ٺʰ3ST;Z{ R=hN".KZ[Z?7PJM EYk",TTYMHb[uoUi=̣c Și>tHZOEqhY9tjg1FD`G |-"9'Ly#ί]@4֡oD* ܪE7Q%*PfI>Qa ҧO02n:YCw9< @ o2WO4JL9جm]ʐ&O&ܻ_5{c9(tgWk*H#\']yNkE,,ܼ1[)5GZ9AE(tcS(%^ '0 ZVz% |T2S{T/Nrg{V $q?dH%ߦ%-A OUvCˤ0ʇ %j;9eb nZ9kBǕ(7.RP╼j5M~CZUV"K'I gve##; j8I+?4HmH #>1;,$wj>?>x"3kw=İΗ/Skr9Q e5+P,[HBeܥ>UB۬H@-X>t .}Fڏ0(5`5BFP|. e5$I%Jגʦ s&;/tcxo!Dv]-.zc}ڴ 2[ ]{5'| #"j_~=_3R]mk2LBThAڿŦRsvLBFWK鋑-*^N*!_Dv_"UTJX&ga%/ע]SdbN6)׭c(RX}oee#ӥHjv)-?8 ?^aa|nqA&B\PGjܷ-mW21nzzgJA U1D~j`ـm1+ϯ[E=ᡧr}g/l]K&!أFo7@(," 뀆SDOV{Ien+-5x{q,٨:ޮu$=`CeE|-?lhVo;x9> X"=Sۧ:_|Mle>hZ_y~wGr"Ε!`oRR J`Sw]/;VGfhvd0easY5}fPTD7iG?8f%ï L:R)Hhr%&,7O)db5BxX%k2F &; t߯qtTj&s\s+-0T]; ,!IW'fTdxtRGe|oSCi%] ԶoV)Qp|(RL"rY|w5^ۓ+UBl6$7gHşffWE4R/@Ȓs(<32:8uQa[I5|hBI^5v7-.:,;f|,(?M-ʸ( j Oi.@fӲr9 l*Xۻ0 .v#l7a ޓ܇/Sbl4`} D¦ـeBG:w.C30Eh <4oJ:/hs:W2WRV}Pۨ mEv~C2 ^t>>{ ;r[I~-'g3Q@`h-<4[MxM4-_>L0,s DYq*/׈ x_&j 3SWe!jsAc =H3^r*`g+cӵi8X&Kb* Kpx%g&i̢&ջlJ.[ nC\H ; dg_;Gw17 ×$zYrH֊JC:fu'кa_,0~ފ¡ي4[cҢ7=ʰ DQmB Jg惱M= ɵb_SC~ʜڿ(ZqR*XwZo3 H~M9g7Rύb2RUע _yЮEqv"OE(0QDfQ&IU zPD 8kEߡlBy"[*t]^Qće Wԥ옪^˧,X0.SMGSXiUq cF//4&)54e:Wkak۸p0hrhɘ~&M}ӄM1qՖDHl։^F2w8>=p m9ՄX`CֺA`WCs EAg䃇UlYgЂ˓{mOdڙ$5!;*LiWs$i/*/m9F;GPWc~NAb↿ʡ8RMSב>;|MRY!7*`w$r2sSşAqf`.:Z1 trႾkXG]O)TlS-` +ydo"MnJkSurAtcO}~8u.3V>vӫ 9J#6OLHff9a{{{kԏH| ΰqJ{bQP ͵(-󇼥vri-4fvڋi'&)N0 .W^(!RWlX1WgJV 뉓` QDJ&3q c8,p*̱jjT _H]L'Nw"C ꯳/\bt~t;@\5V#Ju;f.y!!,?1FRYLwo<5lOf_ IcZpTxMq#n^"i2BǓ$6r+6?hѣBk·8u#ē04AWMTA+,!ߟ}V֪N|c@-+&$M[[E51 ΗLe/ʼnPֆS/1TM=ڰMV)O_iTߛMBBw׾:L'~”9iJswg\[ܼrgyDؘ-tprWKeYQ޴)Ӟt \4;p'M&Isl)r="*8А,M5ag~> b7V:T?cq(pP7Gor`=:-q$68ܨKF%?RYR&PhJ˵6#O^Vf}-g1+"aqӯccˠk"5nn UnR $3rDM3OVM'K")>i5ik3ߑ$t͎1:^&2\`OW8hզ6sT)2qZ2i=}O=yK?WH4M}Hs+*FHCn^d^d !^yA[`)r{=a=$IM@ND5)җmmf5MX]pDԝU;yIvqBn GWyt܋AzڙLa2\?ji rIkzQ_ȻX :hjI-nS֌r*[bX2s $ K?Px {l@]JzmvF1Nq'HmOo0xc# ~,M,$)TrT^e2bYCΊ66❕=źS/O w8ȟ8#sKD'%HٽD knDR\M!E9TDcV&d=R7/]ȅzFiKy~j5k|͔AA1z)A}XZ8?ؙFeU;|$ oR-tx8䴽*>hJDZ:oSV>3o 0: ri/i'ƅmTrMXTĵМl1^! GPsO^Hu q^  쫅S{⇒ I0dh7 n6432WƏXe"s Fב7tqNxe&63G 2ˈ!J'R-~H=W(u|#xoԅ]Al|9-1Pu:WG׉ vhP+Z=&=9P:4Mu?vHِ~;<4rcV/#欄٫16Rc=\1(ԍ !B^ykLKXE ;厑$ޱUDz ]>njL4~jb!vz*Сt'=NoOwvS9^gma.HqXGOIQ5\':u$'R55vIVݛ9FD ?g!#[C#᩵x$},'Z)N@"4!l#FzWu1\5U5 Qᓴt(B\}2r TH*v}0oУJbL'&0qozl=>u Ci8ooM-եJ4Q 8 `EAtxgr˘)&]&Z!mnX]ll9 sVr, yry]o`Q:eH ||gJbJZaRvd )-:բK%<T[}Ӌ>c;TM?[Y đ;.~ wolk1ɂx!Aa$0@Y$Ɋ3{\a=<lFu֍'$W\ʼ &n kXLe2 '[߷2qh/$W]--(@E$ 9r–jnQ Šɕo .[OE ̿`b؏! 4bN=3!}˨oV۟i㸊G@_ĨN1h.ν8@}a/*Wf *40cenkL?ᙁFQ҂S&%(\O‹.qQqJB _N |2L.?ԠJML1],szgacH^D0TBGbxR{k>:՘svJlyMHXڇY'vԻO,XW˪.,XJ;7^5NEJ;'`SD3)Y%)Slפ<JGCvn:xHS״y_{l`,4jSrW ajjػ)>>$1gS+ ZyDpt^S>9.li3]db?WJ:Jj! I4ۜ<ľHi E`jއ\&ٖ0,8;#g)΢kިH-F^oM+΋/9,Ӈ>j I,,3c>xN @ܑ̕RwC5rtm`Ew89AaSfU1Hv"ݐYD0{kopiĜc |U[իa= wOpWnU~phU1(v6wG ($ }n0d͏5&C3ˌeOLn銁cʮ?6Jr endstream endobj 116 0 obj << /Length1 1930 /Length2 23899 /Length3 0 /Length 25071 /Filter /FlateDecode >> stream xڴeT۾=( Nnš{qCqO}{##y2k})P WPp9Ȼ03:ؙX((Ĝ& qW / SOD6 (;2 Kk=E^O?٢Y3[w[k  ˨Ptp7Z@ShIT4h 9::8,bjRqEu P S2:[IWPQQ`a OF>?Z8;@mhlh|V.wg[h79jW?6\$=މpS_ X+,7A& @WW7_7М_bnz(mwtQysL@n.^濗mrvquWE gz?{f ˦ (#) .9;; FW׿pqXY89ۿO>qw\=)h[;c[͑Idwl@W3zY1iVYIvtpXع}-oO@F,\sk3wˀ,<2O_t;<@ &Ew9PsKNHFfbomh Kd[HZ{͕]ͬ"_fWw݋,[IQ{c0p.G3[ N?}gϴ&qMmIE ( 5 0qv6D`~W+]@d`b9\} $/߈ݧo`Rb0GW1003YL&&v,@YL; Wv0 ?{#Ͽoꯓ[/` Բ6w{1by5 lQQovv;A\lhTݧw/s@_MZSXDT4iGAmD̩8yۤ@,"yi^@P6Ezs??| \MF,NR#R6"X։7TR|h9fLgKhxKSo1&"˴aGea{t u2u{t`Ujv-Ҏ6W fM]< H:;c$澦>#6-W ="5;Hv)4a kwL1nUֳDw˸-Vѭ:5Zq+~ʘFjL5%.CCz~4wyYAe$u7UR稏`݈d*?Ȋ ]y zz|yaf;7.V>\rΣ+W$~hN53SPm P@"zemw'{c3魙(Lډc7BƬ rZb=z_+KT)AN>X꫞Hj^L {4OB'|]X80$*h&>d6hW\@hb: NL"^;0):F@#vMgfY)U#&YW97-MO4𰾷 ޖ1|xLż&er"V:dž{5rSZD} ]/Q>Q7S5[Ǘ7&+PLħ2ZliZv&< FՍ ydǷ'G/6ٲ=>Ԗ2ŌV eF1,yM*뽩Yز<C/ E($!lҀPb 5V+?& V7Zsq٨61sY :I>\f tC"Nmqb(~!w ى=JlCTk^ÂGܧ#`E4">UypR6tK1mxowVҭ[ENf CVDXL;tk]\\+jEXō}oDbvwipDVZT]ɒѯ"} hF?0pi:IP(!qabН8*'ŋs܏7\V7{/ÙUVutCy[jT4bzy`4_eNÊErmHq Vc n4vo3 Wb^/9L/K-C,wUeZُ)}D9ܭ\JhӅr,o]u̺TSOBH;x6zAFRG 1tl+{QB1MeEpe]Aq$dSa͖рG]sО)X;<%w0 ~=@wߔB㈟X.~U% 5*6S؉5y8XOk!bltU?wvt0/ΚoMګ!caw7O}n(A5-ӽ֙_4k2?X@T as#%LPg+1Gbj8+`=ڶj)02kcCw}K({g-E Ix1Ϳ2\_0zF;U2=F\vww~9n_8vșYvBxT{^֙}ftUjEݷ1Ox?#A+xQj+$t7Ԑ>"-TIw:'-_mvxX۳ԟU8x5ZLdә40 rg*B= V[Bޢs4QxbL|Oe7K$w@nWa rZ "W U*9m}P(beX']'dz6$[pvW 5t~ _Gz50iz|v[};~WIW|M`$b$٫8g/_3^)Ni;*eO}2S1fK@ R7UxνW F.kA6'PE:a%byQ3DiEOҗߞU;koH[?UuVGE[_";ovkp4:Dҷ/.OύR ܩ=-~ {,ٸ Wz8>)<@7|™0t'GaҰ~FׇW @"tcH& ]E$6 ɯ|mmawe6F ~sBBk6t0s2J`#(Zfy/Y@ސaI6Bvy3X57'I_g&&՚OdzU]xc"^m ʈp@Xq׷yLUɬl$ _Y6Ƭ4Axf̏d3bp:Z>34h +5pIM|zl;ρfJ,=VT32s%-L}IQ|^[FZ\KWi_fՓR=,o܎tVH FHhY|4JKzɲpZUL<91p;qG$ƽiË.G0u>MB-8 #M,xd>VKQD;D%~~MY95}m nnGfgy S:p2<$Xmt\rM@ ɨd[;8mO r wwQ{/sKuoxΫ̼> | ZmćI"5د;qC 8>u"b(u'VG3(9%1T!}Tthb$Ǎ`"M8w3rϱZsQ!i$Mv1 mБ+M-r>JOJJR Slr1r.nI+m#퐣^Y+#)˚lнvYU01d,i 8G3ӀĞ=vIȂv-3՜;6:}f ijTn%2+> TL+H&M*E̷M#b(*s0cUc.OȫRyG gZ nՖ =hbq u&_F޶^C9 v.7 {ﻢǩʇ1CU}ZL_tP[9,3!BJu2.y2id<9U]ǮDE0߳酼r;u?ȵ,X2bx!#`<{[-."ט+ar Rb{/?Ɩ;㜂@ #Ɔ ap%= Vxa=u䰱 0d`>1XbG&S=9Fϥ9Xv6&{,dCl,^E^ަdڛ|UJj9JD_zWrԓ.Y"./X }(`<n4X^{=_g{u5|Gv+ Uo ,_,AD=tj]W+cJ'qR?wE&p 󼋔,KEq}17oNN=<Dr'sP8]4߸-vﯠ9*u\2C5?AbeXl5f(]J*=f. Ita6i+6*02q5ζǡΑ%UT0l|j KbNjFt,@ne[۷%1\v0ͽ8BȚR,UB;ڕg>@w\ŬUtzL18^xZyd^uM' wx qm|x}ˆ9L6-Sk[ŵx rLgO)8";bDg.: Po^g'5 PZʹ;[yQ<'eǯ$Tq7JOO]a|SU=.a2TS{DB֘t[e"$gMcCBݰoH4-<~@EXXuSeǯ|̇IgC6Yutc L2giۖ~FsJCev-c`w EV&-b]9S^Yf;f&5IDPUU5F-TyͽAZ< !֕퐝+}<5~BH6O[ <a `8]i_F;je,p} _|(iO*5qCɲRxXp1./m %bl+Z@c]u 0yIʹU O!*P,8Bz4Qle)_X fn82J|VM+E.47 $+* F"F[ë$DxgXM͂ɽcŕ' ,Ko6iQt|-1E&$l6B1'\~;1m֪:=Y4b^xѯ|[n:CG#!@L)P&_֍5^y!NhSJCt%¾&Ӽ³M-к} ;!c rNvqÜ᜝.V"TW*ȐY[{U'4l▉o|D' s2CjzyjL2yb-gq H2G?49x f֝eV-8!VH"v7z.! (F#ܴ\fIZl±b⑖1#W_$E0q$r!S{>"la0Qw'X]X;-2~!2W[(hrBHb7%w*Nts bx"M¯,Dޔ0V=RD-t7yheO>HB%*10$(kMMnѤN,Br:ҏlhOPs  UA)<شUE_Y'H8,`NIm9yeYxEuD; U6/xubʴaO8rBI?_!-tH8z7/\:md᧤i'LWs``Lid @ d㶀 6ʾi}^3J)pͬ8ҦKR0(pbC*Lq/lq{"ΛD 8Dr;q|!`XG^JДQE61vVXKTkD֬NݗoNȢ_}= t"RupȸoQ'KdlJgae7= ߎ],קd ܒJ/:z7śi XrcE{]6(cuVjxa _! ] )NևǨA LY$lVAGu'[;ZPS߸rF&egR8}YEK ֔duR[Ct#i7+htZSU3[J$;5Z͕Q"Yά|Ou;/1J޼ڇcwس1|ј9RjL`%rKg-d-Sv2TQ'q|e6z_ D̚Hb3b?.4NrlAU6g*_.[Ҧ>!2.Adqqҷ]KXTX6*HS}TzE*I:$d0'' :2ӷri2Ȱ@Œ2SYL%S9EUJG.+SM4{h;qm |ƫ҂λR>Tat < 57'Vۢ5ʫG^m򔬯a15'VP6ӱZIsiƄv%楏??hR()HD>[3ķz=2 TMh #lsZf΄>*AG#vO)#Zy+++&5})
rg%&3$zzB^燈\dbԳdSsO|EaH!Nԙ;r F ĥD"J,g#})G*OǎCS(_$cX|}DF3#zW1C\-ְ:􏽣yZ?ZɃ8_fhfZbKE)\z)#!$iiӪgjfy.a2 +؝YQ.{ĐcxIQN$a)Fk+ Mr1??>;qL'C@UJ_'fWu):wJ2Q|b| "n=`~+ Ys%FS|BCp0L~#i  K?69Y:\T{-2.~ԴkoԫE 5^hn®pv^?.}yʤG斜#Ӫ@qš>]{',&TR*e{px.kt/o_i:A`a2waD9Kf؛b қzW$n2[?,ɫ0敜SzPULQ+ ^R7< tw! _N.."+Ӝ>Gu9F'QgNUbxEtSZvMtIq'XB3LLߺ8JiHlس_̖|%'NmTRq.*o EN\I8,~,筁Ep5TZq+I?ЬEv-OuDdF `%a[D 5`(ep>8d1&^Ci<} QMGp:=u> /^N>M>`4P}DLO5Ck|:3hL!5ڍmLiag|-t?Pʑ2  :"Kò΄ENڮ6aћ6sb{!kFp/۟[5R4][,-) G=yLA60a< 1Ou|&lM 3c't%Ә|擠N8KaʩBnQ om[C]OKvKFOxF. 3qؓbEAJ{ZҳǖY!Bx[uC2?D0t)Ij.4s䯢,vkWa!)<.XJ&r5۾bfpձX'J-k}{VD]Ut`Mk5$#*XUp!'"Z樎e7#+:q ;zY!.KZEkq:#3&d7^q­LppDKZ|AH}eC\DX{g`[,L9z}VRD~N(k~U7g7BrLzNܸ-Lţ2.I}%0L1-%M3ЂP{`7>gN ||\WXD׎NpӖ)xa{iK8>K\pQNjNj򰒉ƾUU#:ѡBMt9FXk%r Ɓ&mp|oQw\>!Z;6`A̟?t@H7/ѐ|KWF2u#8{7IkbdB =Cj)P?+ {R<-Pz|,6av…A n_~X9%ămďւUTV17A NSٶ' ^H ͺ/6c9JYi&Fzw "9k#zkD?dsuu Ch)4&P:BFa},)pɪE~˱8-C߅!Sq^Ye]Ғ[whm:!Z8(S۲7J1 ȣ:jX!G:ڻ]feh+_9Ue\[ŅGSwA!K.vV滤h3Z|=yd:d-䱗8-K9Uч!V*$j%8: e~i|y4㖩-U (WGWaJFFQ㘰z`61^F #Q/5KDBwP9E }dS"@3=Cs gdKB#V-ΓvqOquڰsM YB3%ۄgϸ_:ޡq')E-e 3_c2[V  B7LXBtxP§̈́`m? Bwʬx-z Dp.W5a5}d HX bVgVv!;dlohUClJ|ba /|O, ~il8 .4 Y)>.90ưKJ."偲heVM%tn+k˩#f1Ҥy4bsu<ƎfcL;Tˆ{WmTEXs,N I(PąbAi:>8Y"ݫIJZh|z͵e18aRt[͑x!~&ZXVu晅0q<!{pͰoƞ>Mș1,zPɈOK |5EIUCC)TGsi@(+/i}њf^C%܀.H0ۇ7Ln5PщgN6Jb$,û)(e<%H\*ۡ _x't(S6(6^ORߋ߲LbM$ SWoI ?^^^2 ,s= N)-[g\І,*ca$;x:pF.R/fC{Lc|4&HykQd2'~=PDM0a䌈 fڄ{0C>n=5A5GUg5Hg/-?.ZHEx*F| _8ú- 9ȏ$V2Dki`Is;:Ul'0tx}Ա)zY$+[h547?g1ח;Z_+J$FHX8OQPF$أoZC`[r]f3\]HZBB(!Pszpδ9B¤ͬJ'{TEPdpt]n4M}~(TaX0 R3[ ZﳁhEwq:Jeza X.턯B``z|6%[;aĊ/ИRty۫4Olѹ3"CoSk.Tp x@9&,+i{]v <<)Õ]HLYJA_L?K>d.zBUB!v+B%P zd@  r<^`}kg!3Xȫ0p6R>"*h^bQgU ;1=wİIyӠ fyɗC )6>K [*Hh]p#%8n -[-1"Ԟ`,>]o.|?E HK)j٥Q&?6Pz"¯Ku+yP?:522d VΩD17QoYaR&`Ic]cLe'y38A:8RUnOZ)qVFJwF4n/'*$NTz LKN"#+qcpģ34W-ezfFP\T.YYBL7}$eBu6M< a / g5jMB[$[ f[ÀA2bie.>sS y7 8&jV Ir=xVh<}PJ ὖnC/v֘*^v12!jto ιdEa_y&Z:KLp:٨ `8J)p/ RDsh9w 6 "O~`p#w!;OӦ'|-2@|*Dxn?箣SA^lN U[Åe5<9q!{Jx@찠-!9'm2JAT>fRz5Yz]V:zFyr/_܊k?. 7?_2̖}0@ )8&b|_y &rHڎ6G>?q0*]$]KJ9\WA6n[*56E wb˹f2/.ЁLmG|z%|yPQ'[aH@lA}, Z7ژjBR;UɌg)$e~ѯ9;\@i|d-ќWYlʁ_N̅4.'cfm`^b-xV$Sj6[RR,&L0lzEVz [TSڼlnǩk1ĐT v)c}1t*i r\Θ06&'ni[JX1؅vd: /0]LHWx F<,>Gd!V8tv"J*Q)'@s!z‘AtHQ0PZkB>Lf2/ @+s^ZxV}߼Pٿf-cq['۾-W؉ ::-f)#Tn]#Gu*uDg9k3I#}7h)C 6wuޝ -U)V[-PMߙ}bi+~P~1|9BuG(~l;n1=0Q SoKod18a*u ,?RIGM< +څ:)MCX>1C(1_5%\ێQ&YS9gQ-i:;汧RwAtT 8L90†;K6mB}wmNvp NAo2kRQa|I[X) ztxG%5AF,OQ}LS_!Ԛ,\r9fI?\JPmE}ɟ9%/kљU 3LY^r^V97 Q jv2uSKjmeʊtL}cD`(B)& jORKW,p*cLNq8]\ Itjx ծjN3Q%O``Oj?Ʈ$Ilnzqb؝gXMľn䶧FLfnϢYKl*q9*ohDsq7 1{]FAX @N9̎-"Qc9g5,uZ"u߻>r|A^}H|Tb;p-! <rLJD9c;ó^?ĵϊgczv"}{4\ -Y- j9z-թlOcLƖ"XU{nz}2;FriۯQ,^(kxUFrTT5qZ>\uVite)c/^vŲ/spNg"^ڕ \; )!Z֌ro蛡bխf7!%XZ,u?:/^3T3T-<6U'șVɪc ]8'L]GV3"圓`$wَSR)i<2"h s(7Oŵ{Y,E,n^o hso\K^b.!N™1%!Zѱ;N}8' Vvxj_B8kXk;15=IV,$`L΁r?q3αHd@FS|xgVMll*g$ C4-OKxV5,3?&2: 4 ƶG"pѭdb4K0"-3o{:߮ ޙ|2G\ A6fڢ߫ e%SO,hSuƣu<|ngSt>-'h[2OK kӁRO$mV݄Meå/0_תspS=څg M5[ŘR$tO$܌RPɶ`QJyKǯc%jX˘M*RojponiK]B|Mmܼ!ȫ2P-IP %'VrP8_.ކ["!k["1v_8yCMIp u}ó?]i>'ccc%A+ uSـWfS'^;,YIG%J HNѫThOxYb1kfƬ7;QN( & )5|,$$k݆ۓmG͍Z"$q5.3nKh~'`غ0׈4Խ=CԲe9!Еk11jn[Z#|S!vz_eZ+f\Ip8bb,˻fJu/0Kp9f_KuՕf+ ֳܳ&wZi?zhH<7Jΐtx{]#3V➝)1E8v9+o|>s61};AVKfwH`XTQoi gw世[gmw5F 7KԠ' 9qͪG2 YVmU(2cEҶԿ~ȤTKa2Ycާ{e8;ǀodNԅ6iP ⮓-,D1D )Rn[b̸l36z&BڲSv?s=bR !o |{  w>FibfAjtosf\I˃~G_)W9p8#Y1b2 4 sZlP4}:FkR{S8b BEz !z%s6Z_@s%"z d+]" zf<HCcVL4@=E?F ~9Aɴj~y˪f蒲:.&}b e (-Ǟ0#PʜJmu0!! {K8N%H9gqF)Ю_M"} IA˴Ez^ R&{IdN=|;OG ޠfRk1nVMJqcٷ;UT~Z0x&3d;I7Ll$mJZ|;LJϘ 貲-d%"=E'45ME2q r#Mt {V<䧈ԍƟwe#xlO ѽ{e ӭ?>mb`*"E]O .r}1eD<#2Gbf K^)NSiJg{+׋}51H+#c {c'T(3KZeKWHNrGj=@Ќ%ar(zYH"_HRoVV g{vԌ/T'KD9[fT8CQ*`%(҅SS!2Rō9QNC_9'yqJI&tn׊ 1*O Uh{LI a46 G*JRB>^Wvl L2h̐h31OkF#,y {J>W!c&tDu?!]Ahs^_#Tp%v<^TA~9;}meuTb])SDk.]BMS-v)!lB5"lZϲh0Lk0C[&kq?,f?Vh4l*1?,S&ϝ!HzR}$C_֍mym'wCL6o}t LJkFPi""~h SUW! gx2iZ>^#W̻Ֆ6,6iZ;W꙳DY翂Y6nw_+ػװη1ij"C j Rcϋb,p~+mFطjX.F&Gl[}3YG s3n@MV("<+۷@]%85pS͜.r3/߂ÏWj8Á$]^Y1B;mYŕz+\sya-Ъq>4թ_uĭehYƺyORLO4fVqվɑ1y񋢽 |ث@ *׬Ђ~ir"qJ_}<ެǤ"^3b3UYC(6o9Y:'~ۿ~;(X Jv-1\p7cֳZH6qz@)x-!#&n*82Oݒ$`kޝ2VvO_$47mr.֭w +^N9ё 39c}s$𣞽B\/Nӣ>F'^#[% "7p< !ll_zݺ"￞DPC^ޮFg_Zg7e @Z)7w/\֎+nyM|Y{60U66ӧG߀7ZÅ)TqKʅ-FD 8;۪!_\̾%Gz_bOf)h9(ey4BO4VCk^n*(F(ʴ8B` 0@9X"!S2d")FQ`}z3lui3Ys[1q/˘/93Lfӏdr%}  69H,>NY|>9 ]U?'S#W?7@+nʁ3U;B.se)gN/0 F >lw~#Zle2ıy7v[xAGo{LW 8(YXEvnX8yy0yx{ji{n~qˆ"~*taeEty^lJt)21tHJ1wkox`F  2?a,WQHfL` -IDh܎ C>[KB;Sw \ ﲚ( >q,1F+5 ղBϷYF=6w~)dե!fDl̲[+npNx vĤșb 5> stream xڴeTJ5{4;4kp  8?rK' Kw_]mmo{Iiy۷gDXo]o&".OF0q;9`h6,/淑65(F;[ `rDFߦ'Q0AF Nf `)qe7?AzcPzcPX`T7v 7v?zc7b{[Hffb0obd7fo,]Y-UaaoGějs=_ooXM?[,Zj~˵7zmf}V 5G߬oC:&s][_/ jpY4|/߇PTq 8;o#D]nd~}7"s#[DE g}qxW_o@y oURcHxd)47q9t bd;X)P0߿/2$+ţoWIm_1qm$m#C".<Π&WIJ} U6J P=n2~H[ںV0܄hᾀA0zŨWxf07gTƾ M6)WU+lغ6B:+_AP)Aq*QNDf6SnuB$7* KJ DTQE}NtHlJzYu'>QU)w%~U]&U%G89ͬ-$.ŧY:IFv2l9`)ې1Q~dj]0|&C(Mxx`{HX#XJcFCRxӯ${aqzT!LedלJZt`~b9ѮgF^ʧkly1Ryb+g'? H[ND.Ǯ)z/Șij)~Ԅ8NiX)zk!`>ܩNcĵe;$j #N8]#?vF$3I\&+W\R>UKJ[y.N/T԰`qAca֜͐w!f+WDU{pRީ+s^l13l$$h~Yل[1-O_8t#(pe B^ԁ{fhT^lYklro E9"/ pj?"$Q€T.\k3(LEMR*zmg "rА9:B_c1d,Umw+OBj txI *fe U!­ahfkOZ1!(BN"ހ*o(E@ aA1Y$b̥S)gLg[j<"jF1JD1Ժ<5<)`{!l͢ǹN ވH-7E`>jƇ~=_MRv* h8C\OT G+;ޭEk\Qtj!Tꍛ~ ;e]|Wi] 1IoESwnTJm"q>NoغPoH|舱)At"*T QhC1O$IA-09I|rCQ/ʃr=Z[4[R,eZeK/H4 ?,@z.T$p˰x򇠕n~V}ޘ5AoR򸙑0c3 <Ocgٟ ŐYv2BQ Bf~qS#M& }_)YȦzCS; O6it 0jHq26#eQ?*M; 5vO f5y "ST@ѬA.]cG9pevN/yiw۶MȦA/'IE}vG)] @H9t ]X|Ͳ. {iGmk`+ Hn]T)P #/";B1Iׂ8YT]+8 Krh6Z1h27z=*B4BZYeF&/oXڠ Qj/)V}jpK,O^eohDˉY!xTԈݖc6T^*Bv@x\L` -į)Ċ¶2?=X}W ύbfT uXZ_W^$ce%y]1C;mԘaA;lC,6 M"Y)}R&^`c)˾7` h!*ߜ b1~Ί~o;j#g~XUEkk4=v9J>"?KOZyvm#AYa09̻Dwj/Tң5؊\ζY`OrDMB G!|dw) O8:VGY84ũR4@܎i/lq,W+jћ撋%;}eG&DADꭃYU|V>((mo"c FJ髯88 h{DğDDOb%2P)s86\?6sJ":/8~~0 ʻZ'u(P=wRࡀ 5)dhϹ}_BC*o"*%C{*0vKq|N)=Zn-dߏ[E8 *+in~3 bu/ue*FГ{{̅\;n "yu>IU[ ):]Y[4y0**}Xz'PoF [\g[jHsEcԀ^G V-GքZ+iUʫ^{wUݢp)s jH+k娃S!Z-hQwx{sߝElO^pCukfgf-@7R'y\L4磔;(zEg`cg98t8ATqnSX¡ a-w3Q/;I/ mCS/teUs<ƷP0sp"풧 ~[/VPPGz,]Кn$`w::5#HIW$q%b_6/}_N Œpi^r #TQkYH^^jڻqgCrQQ(恦e^Vfƫi]wHZ{]YXa^9o▷ՏG G AlGvz:lVC>K"L W*0ȢҺQndeqlJEC搋 i"&*0Թu'Q}O"=k<#d_Z<"nď{O]8iWkҦD kQS/y% ^bϓ+Bڻ|DNATw?kDLIr7FBdxzsV1Hs:7>^2N#l{C;iLlyG7}C$O(mV>nW7EXToW֝=JHWi L= R.ݓ?sq{w$:5q[67ϡ=UR% sl+ۺ~DHNYGqs~iyz_Z\r)jt(TC6N%<#,:hݧ׍œ(e7xӾA\ E(* JP< 2kk:o$h^=L$ٽ?Ф鐆#o*KUATr#57oU&h5|MNQ48?Zd"v_tRd$G˕_u@w87d|mRJLDŽqsp/M#~ڑc0'5G_r-؈eצsDԦ ,(+C4bz+FL&`FEg9Ȑ/9R'|LR x3/!:-AҿJtԈghb萙Iq]̇\d(N\ ^Kz֑(or3Kˉkgv:"l,^uh0-G cpF6T)9|:m_-VX+,)PVxts+|[ET؀jS<,.fVINp{=_W3Ng .i#Yq܊ft+]/ͪ ?mRr3<)]"1UY(!>? noJff_4d<~b,֖tYc..CM+YWvS?;8A k є88O9&[ccgCgPHf*R*ؤO@^|$zs 8;U@GcBnb$;O`!ަ^!vF rKͪT2ŀcL-t]01o |#b[+ UWP, A7K }~F`mf(1e~[uX0n1ߍ٧b^>`[u0JAӧK(UrVf ?\(|!/|i쵚j⊎J5v1>)қbm:^҉7 A9rt5󨬄}%o;:ZIg餯υZ9B.Y 73xgH>`n;`x6 i'CAshs|UFZP膺c~,zc)4^ۚtJ 6Cb^`K^U!`C&^ۓ$)"kI/LW3.G!Qni06 țf/0褞۸fd'SBFkr|9@ Bk6x3Zݕ6.*y[g/q| iDY@+.b\Qt~ytE`&r˕!YbNSTՇ2D R P"D9MGN\cW(Zx)NVSf,.#+? X7V.Bq/gMM%?4' ]LafB´#^ ! =jDmڠ\g惺hCs 1zM5vj+WFP j~oźSNCx+I!/Ϛ.yL-B&3N8 q~v_+ڨB˺SH%Q*hZNm;}\"D&ܓj!ӊ lǛq`7G:UaT+' -|zM(b =C~jT_ȏcCqǡ[;l@PX攖Y]{˄N:[4RN@B+V\ۃ)vŐ)]0O LzdZtbprVMT«@fW<~; NW\3h? ?{J " }@tWRg2X. Kb Qp23,**ڽdj=F-~hi:Fl4-Itkyɒ!Hk0  u`NH?v *Si"uM|taǪJE+B52)-;; 7Z\}ڙŜ{ P& ̼E@ h)_%汸I]o>YaƣmXt hf[:ێЀWP:â.b%Gwe8yG#ksؕ+?N:gZlf*ڇ-MlLƉv-'m=ROZv<4z-,3o4DeY.uEaaMs,TNoL$T?4kbut#sOZ$ ZGlܕ,LEb^bui^TGG4#(;?OǪ/׷TpI(/E:L/p*:VL1_Ya6y>.h娤Ӆ9Rk![_.zHQ3 zK1$rKl%Q\^H9X٪uY-6kѪ[  ${pNO>9d2(q+xZv> ڈT}gi};J}1J!>鐘K5"+*I\3 ,-IhEOEukZ\'>H{IKxx]Z/?LzK HaPzB6\w7vTߞk\h_#L᭵ `+QÅRa$ý|R,U½[ja땫$~ j?\2zgǵ E#91s`-/&avx DpEjFM~qhy/xE42?:DȊ6mt, D4m`: [`!7rM|qs/USFčUa }HN^$Eį-KHIeoF? oA,\xmL@ge~RnXBtT"N]= ])vځɭ ^gǭ]1[_y|woKͅ]t]2&{8:z!|78oԍX7k&4{t+;(z]f)I8A?HX঍ٙR[QQ8S,jkT҆PvouGYC)y1|ɋe]1s%B@2ɉaGٴW[ 5AAM-%$&h[LD;|]L CpF/-â_ں,ݭ_n݆ ]uMLS J\T$F<ŗMXȍoutA%tXE)ڄ$rGaKP#4 $M!?G1>B2ZOf=+بՕM %xC R n9FQd6g4 7:JFU*&:eWDزfN—[! DZpO Y*o/OZ#V{Sys.'ZxA]b̈X+ F K9DrVN3HjFUQRv,&vOdt2(3]a~j x}:Ϝ8 t'>1|d~aSDQϐHu3%>v6c~/7^qJFiɕg\)~ ss¼i _^"H W4[6㤥P- ^}bpqXDPBƇ4#H60īY胵.Oӯ#aH 3^ -]LEd{qe(dX>~+~ x3KKmY㯠Z@w6\R=j^ӷA굹 *^86K Ol'yK._5w 4K`5X"Ӊ J!G w_:\e7$>#wՏ,n UgMu)U|Y/ٷgBP'ZE$QHƗNw5VUwh#glѴ2+f5lǏ"/sdZ˄)L})%ѝ=~ݐam[q+a9zѣ!Wɜ:jXę=H ڳK*lUv&R^ޙX_=zA-{mE)h:'2AR]}DJf~$ fX`^͑//&Af^ؖjԡ]8^FYR/J!&U43)L$5?vHr8Ot⎬`H}[ z׆X82o]k} T"SضYJB.]3 g>b j;62@+8Ke?%f#|0nL,tl]Gt$XxhGn:$q(M(Z&sĈbs Dm?Z T]FIhvO:R!Wf\0oT/e h s}7aBK[s-kܪѤhD¯vJ rgk9W~iH|*O&z#E#= _o{߈S ͪi8F;)j?L: ۘMîp#הC,h82{聪zߍhbɨ֕vaʑiwcqsL̇,hJ܃ !Hܭ jQOBþ" q|ƣ*}@8^iص x" 6b,pfOMNnbƟ LiXˑ*Ip{?C+Õ p!zj'Ս|5\IY`OO3*f dz*P8"~}ܣm}(5C/H.5 DU!mF%/H)t=f2P/=PsҺ_M} ^aٕGJ*.~crާ:ѳ1ݎ;WǶT%I$RhF>秭N.4ZOy݇Δ7*3ty~y+ګ QE%M>+-gȄhJ(/'ޛzP ABiXtG(!}ߕ~ ưϻcfg,V]TD"3g"]]|mMjZI /4^0F@:{_O* 6l*Ze_1dkރU_zC lM&^0)9De(l2;2/;ߏPrI A|E>J pnU COFi|]y1/G ]<6?GbQ{lh| ne9i!lo'$~;6Ң:)F!!Yڭp*V2|Eq0oǐ\O!pX320_-LC]s`["n0J߉~sv vV'  34VcW[n/ r焫X_X=3 YjC EŖ _3`Uh)E }˺2tGk*ÞæTyHc}==4~x1ʐ,̔djchUҗBOHAY[1@Cv ϕdo,OكE'25հM},hl<1(x%w/ʬ{-`q?7Ӷ=c76.s+3w4Qi(\x ͉e[][ PTuw!\:%+ +̪ _8nŗTlm -Tǧ"5/F=?OhҴF^#wH(303Q/;* ا1ů W>R-7\#0AARl9ljp) h|^J hUe+{x(I崞&JZ&>Sq.Q' Apfv΄sS$mTuuOg ~X|NXvy(:$l5 -||5b48 $b"X1E8(J <ٮk&F&[ _N)c^ug -':"̍=Q(Ds Bs-HC1!T2Wf}Y0=~De%I׻5=BKuk>e6Nu-[k ~) كOƃ uF;كY7SQG8>F$?"g٢ Ia}%h 0vD `^Թ69 TR̍y$NtaVqDAksu&Ie`6z7EwTWEaT׎(@X̔y>Edes+ ޼%-R =@aEV*Й('g.|5?[5i>2 gz! eE`|QSŁ&>qX [j*X➣Cdpѥ*T脊}/HրMcƐaVa}`ONŊjᨮTB\Q< FKΆg/0EI؝]2 ?u&c]Z p)b o# #NM72^zu go.>lnw6 "jwC=\jZ}m0ߘ@(ptm$d[0=sKpɓ1wAZr9[ Gpza@G3;| Y),r:UY\.! q2"-.vi*} V!1g>aNCHp"qnj|EZ* \;XXDR%)m5^2Vވ1fd}W_֢ѷT"Ke]6 UW+-xxRE"I^}wöp<0)6^x }?p^QUF>s$ԤrrsPLmZZ'uEԺ+5>пKp(U[&d:^4p2<"?8~ǏZ?:9PP1•1gq LuZ/z[ު̐p3 nLWɘKp[C0/ mA3iSOa Y{Nx=z)# !wgsu9#EXEG]3$zsϜN_ yg4,D^K;"׈948Rj啲j5P2&K ASYe217S#JL dDzeH_0*ks hCp1 @k\gW홉'?TIoݒv`mc֨EYs3QYg#Ng+g-F| ͇a!OM fE%Mq2 %^Yj:1&-^Y.#,B (jdGO'w=iƣ{h6.Ѵ `:{Bb+)c0**|ei?)wܡW_Y/,l>WO蚪< L>/ALGyېw-edG*{ŦJT&2" SlodtSMxDUTfׯkvZƈյI9'Y7כ|*=ܞ"O^V5byq)(/6Cne#>)X`9eLe* I ӑ]쫧Rx뢭^n F̴Wqd˥† I[5Cq<.F̪4Y7pL2XP씡_ܖ =}(\麟{y'-pxRq^J$ (0gRzb蹠!x%?]%6W%Y+Eolx5cb>)z>SM9)R@0G u9ןx>zњ؟a2~**HK'M7zNwΰ,>)7fows=ϺPD~W41YF9_A:jlK-{Fm2#3IJQv0 Ш}MCo?+i-XTL/|OTv1׵Bm 4HXHN$}i/U*A6}Y1 #aUL:Hz3i3}*/7]jN[̴π1ߩmOea(°;7O69 WL$do˫+$>1ĉā\8죮I.F}oF,)#!b|xMlBJ=矯WgE=%%ܿ°; λΎ/@1Y=`갴}槖^(dGSʖս8JVjja>2m R кFGOD6-e6Mԥe#'5}iLyHiW?j]L4~օtEdv*2 GoU:ƃ6 7/IxOIpHNzՂsASY{+ĀBt^0Ikd`yٱ!{Fn=; xΞ֔ ]zDd _J44^a#Pt<[U0m QHC pb^;z_2$*N?X^R7߹QiƈL[c7 k. QfOm}C فE b;mrߟ̿y>+:!|87 4*_<$S]t$\z6Cxm~v.Q8ai+hiX4Vh]^)jLK+h*.ȧ}A[gN![0N$B@m\BqI5[CLvD'uVSIfxbz)%%=?(6. &՛/+ ?$z=]H&ݝr j,Ґ_LEO6JDd5a~rCWAewsI|8i|;jqgQ-͢U?,^n*#W:%O1kQXy֏\2!FEj),hs Ğ.gRh>"4x xA |r"]k݊'Mx2ԭ<6; ;):?iNpje)#]ʋ() T;'[`1m~r2!HL:LzڤLB1v6ΣƢٹ`$:)3Z졗#xm!t O=uZ4ڦ14UI eO̼;"AOm:@לJZg|t %so^Z Cr RX2qfKvBQ9I)P^"mb.rQ[Qx(.V4֯ek,MWgм9!sGXoˌ- jk>A** ٕ]b:3R4"cmnrXde^4.#+n2SvZGN_mRkHB6{,TeH`_G=qpc(ѧFO<3/jqv̞fKzD%Ab\Ƚ#:cKMo8GܮV } AWh&lkTb̀bHv;SJ$C)=4!ü}w!,Xty'\T`9YI!cQLfcgh.#l$ϔ0ZFL:R՝FuC-0,QhCYȬC h]X It Qp#!T oSGB)/ Ro6F]TĨީtˮ+ cstBMj5-!ENϬvqpȜTleRÛp!s RR"a(E};\2xcx|)b^_58X};8tH}J{+BԞk 9ɍ>G+1,Vņ>[1*[־ u6rdPJUgl[u!^"Ȋ.0<8ekCkrYޭCUUڰ?Kg<N3C!I,eğ!1KJ `J`M+f"0kVC[ 7 C&ݍ{ڶU| R:/,#6TlT;MygAYX\c]M5w3'X[v{ ;aU(i&>'{ZxC oH/vE4A' G,'/fA?cG'PoA_-".nDljՓ젚ɩყM`tQ%KY ̫mx)\FتE.Ƴ"pÿSķuJtަ̤n,D{.M'Fy1Z4Kgn`vt/z./0Xh_ZN2_ Pή 4 LmtH}otj>Ty;ѱPDhn ٲKQqp5G^_^D$gH`P_'eP}P~[y?0뒏H OȬ($ V(MoPܓYӖȥuGj'+\ګIza{!練gAY"k{Wezn/~nR*e-"z7X;WMM 9Mv65.V13kr'B IS7uIE{DhOg'fE2Z({WꥐrD3R{`GE$#'ZCgl%:r-%W^47z؄MDHƕ?-׏鄁6}Km)vސ}.aKs~@QJгUUuc4*N ˛Gp'oӁaxQ%Ɛ33a$ #w/$^&*Ӗ5t.5lvp wD3M>Qv۽IJo'g/Aa w@VM=(_P5mf-`3U/UΎЩ<X,x|&'2WM1Ϲߪ-B\vn""I*@Z32'j@tN h?Zʭ`gpƘe`cr]A-A)(cDua =#"Ŕ1#2|eK~ G2|%o qVFvt% F.o^+!3n,S'鬠Jy2(.#?+ @X#.`ra+ǁMā(="^3Z8n8Yu{9ēdbndƟpntTQO"Fm%F}[ 2  DI !gV?>R "(zl?mऴGg|WoMq+<'z:R(hgP1ɇH oB2+ڃkh(k ~\q<C_pkڔ.$(7 aY>}HRz `f7ȫ)k(Ӝ;5 8e]paXa/?W1E;Gap&Oʲ )%d|"jFI# -7Yzt󥲭~t}U,KA nĶhl@Ea󫌬'"&<7Ra ;E$\ NFPFp-u%P+X3' DQܔ 7ȹp3ٿ@j{WoPjI3|؎YO $3aX`2L}TE.͉Jtg5{a~yd(H򢬔*'m8ş=P@OYX<{B1xPus]ta9s rb)}xO4Om`Mzf~HzN]~b# :yo?e.[xkA [gɭ*1~"ECdG-7|sN947{!R7eRHrR.%7RS"j /$>3,r9x=y P_S]y+ S2PIgf51{8m5G#8Y\8{K4݅\? {F[ΕcSmA{L_*s4^O'3$;} oX ~k {A$ipE͐ɞoE-c>ÈRe'?^9[2lم~J#Q,eJo!)eQSBg/Ksg#]!wra -Mvp8B7 cSgUǐx1u~>'c6_Bj:eFAHwk|AOǻ>z̗cAቻ rG%ne~5b4k48Y1%]JZ:ɭD& _Зv`f*u$".>qFil<8E#ɿ~!WoX(T"BUۿQvV?]0bޥ(yT#]ضvWs3;Jm!@6!O9&wycj^ami +{L8.~MYi 7>QYFfmTBHSǽeIMњQg|"Zn} ?G',O=լPU Y [L޳SDgfٰn [{Gm2R0cNȝ,YgYHo*6Ph[Jx1!߽KT*hn>|QC#`4#-1e);wy̛^0H98JX+Z$}"_1Y) FM좎: CbEœ@ ;f.W5\*wawo1&s,&!d`dhv+?2"DQʂ-rdsz5(GfpݫI}jouӈ=h(\p/޿%VssGo-KGn& /9zUo [h6bWoǍTH&ޕGXnVi}UjL$#(+GX-,Z={ӿAGFצVL5>Dm1I^FWscϬʹѣ\UGw,֊HoT3'̙Ӱw#K5ā4dLhx1Ӄc8Q33ginB` -jdH4uUwp"di.@ۆW6\w ƥk{Í-^5O|gM:exwgppTR9{[iFJ!Fqp.]:-Fc;+H\JB m&D7Ms{]F`C1~H`HYEZoV%3(=AK_msc;_%L^̹͈^%eRvyv1J}لjuB5zf`:*H#Ok S>eE.09ybQ'ѻ-ΙO"+ZZԁDžݳ8Ν/˨.M8lsE <)ZJq8!?YPWcOqeM6x6gԩez&-khVn-,K%ҌYWF?K$kl!uEkr%ȹPȌ#̮%&,Ki9{}dJm1A˦\8X!P̶*EE:L눡zwV\pg\cփP+4%2e,!P0 fC +ItӨXzn+@7Yϰ~Il^s><\oB[QN݆j)_@*Wׯ+4i@uT@LЕn2rA 7n}DMw29b#b|$!X~ڊFG]O$-%^w?7ϣ~h_A_LwK[ YO[M ^WWkuie6x>tΠA(3 (WIR>GYs"nYЅ\=-q1hvZLĒki VՓ_ Ew wYcAf2Aa^ՠiywlbAW-mLh}(--藴1IZ(VoNA5vp76 yե76b vq^Żpv<#b^*);-u,߲z`PGkAj9NPr= #.٣n.}/eȇ/V<3oƒ7h@j]eWݦ(͇)R>dF=`Vs࣌,-*vKxK q5U}A/~˳edQ^OA,¯#׻c|$n] q$E@Bbzլc^FJDE@2 iW1&sX] ]j.ugc_QըJSzgFVMBZwٵ3_rP_u=x: 3/O-PR(TqQHh^D鈰cǚO endstream endobj 120 0 obj << /Length1 2062 /Length2 14876 /Length3 0 /Length 16142 /Filter /FlateDecode >> stream xڵyeX-NNpww ŝ݊SCqҽ}ν1us5#Td*Lbf`4abcf((*A`6V&9)Jh $!@~l yt!Sd `PB5lZ㿀 db,@@ %O &?d3MmN6Vc@Yv}5Zh 6huRj5eMu:`")SҐ25W%W>44>Hydq~e7TsG_ =? +hlo? K+'+5g8! 9)$ i:פW;_^Spm,UPQQ[ @15b qve{MpvtC]jOgm'f rvlM '+'s+[N MQLINZJ]IUx &Et@7_I*J`}Llg $^;m@`We6=&('?&,+ZiV_i:́ȞN.@O"d6)UWr s0o+uhtw u͑YW9eKVH_0c;+[mJ`G;cY9I[T  oߝ@@'3+7?7UzsU6 /uE(}Rdo%2Y,\cGGcwdW1sq<^UmtK-fwxN߈"/`7( rX4^XL^k X_{,\W? '_󕓥%W?+5Wnvl r3#vd{ |l?kMיB_oJ_?ugUX- C6@m+(CtY_/1۫Gd<8L0#mx?MA֩M!e>RST|Ǖ8:pSxy@B~ԅ`Y~}dPUZKR䕙薱[)\-f̀LNrK8g2[[I|]w/땷ûͲ5c9b-t.Lu@C^b{}GBĐYCX?I 3.uh|e[?YP'ٹ K#GL9\tr1n)CiH깇A1uSy[feot" Zc<T&eq߇$unJ}ﵒte2v/<0#e>:1Sփ,/Clo6weHӖnQ+!I0gUEʈ+NNĠ"QaO4VV~~JH3c(7R;mBߗVz#fd3 9 07?U ,TVZByɚ^ՎxpPy1D z`B? %oA㌷S Ll]fxS&ظV~X֐[EL2q ɄWX(VW t6wNVn6zOv: y#(['>3Hes{wIQȍttd(vڠ8XcͦEQ$>`b]~Y@ 0.'o;n\W'oy؇O)GJF7^oRa?$DO2W,yf:6]#o:bP'vS1U[y"kD4nΆ4Q"֣D<`'%.z1?skHJ?{vkг[3 A Ў[QMF]ƅ/>q.b%a靐⤌SO(Ԅ

=|vpVn?Ƨy2Q|pHwkHq"l=?bRUWuv&obE%5f!t2PܸI58!ʚ ¿C1ͳtvu"cx`?-y?B8Tjsx7+:Dvl;N{Jd2?]5ȁo݄+ڿS-o9l-7*([:fLί[x<֕@5Mt>^CŤduh\CF/U$sfaD#Z -qH 7eъSߩ3? aĺ$4.SCk  l2S7a>M h <閻`_[Q;"!N(X D=|Gh(U+ݚ ~"[`ӜB x X_;n'<3L Xʺ2 I^5%[C H\ih t̷&#Aj Ѳ01Ql}#6M{,T 6 AK]:al\ʲ8gbRьOc-P9L0C?W+{b-m*u{:a+ٝW(DퟂLz jD1U>ڼv &EhP3V)4쉢tEW.cQϽx2xsⲿ\H90ez8̱s+5a~11LvLUé4u\0>BҲtQDf['gj,k"o WS.:^=R}ݒhlkFb0n6iF-Y+tﴨxs +JE$dԼ;:,y-o1c4  (5F5&16bEr'\P,5ocEJ}1ʂI 6}엙ߚqf S{Cۅ+l>n`Щ~{>,.JQA64uBߴ;S}aMJJdAQЏKo}$坒 z9hn#U?Ly$=xj\\_@[7AfX?Nuq04dnbن9W)qԠލvD.|wfh9}IRe}ՈfZUifI2䟢 O0}ZmsɒK&KԹ`1Qci lu{`|jqy/cB9<ˆF@'˒;Akv 4>UN: 8{%b>DCҳ6|1JD4z7J9=Yl ۠D $୥zi2e Frsde:DnM-r lxvI ?H=g[iicP[L˜Rʤ7d0s#)[xKYlzտ ]Dˮ+5” >Uv*8xnT>$MB.mB'͚=̌cާm&D5Sܾ{o"Aq D,gn+0kuSdxt֒Z`=9ϩw2HbXk&05Tq yD %ԙDqb~;};Q]w21=AZ<.HRI9̰ZN!zTQUvPZWA[Ucʖa?`-76I!ARGMl`uk88JC&,xy J {,e;F" ?qdZ<=ӤpL;{}LWΊuCC0> kuʱU|*akyݗXe,tat E%E=ӋQvD}aO)v7bBvڥ?%8Ca<0<K:9!E”1M^z+ِqa爇W)CcDfx\]P{zn0(\mv~PV]I˫ /q)uǍ07o0y~|q0WI=& 181h0P>JFSM<;><,FT:R/MBOi%\䠾sImi~,wj&Fc^%K%8 $ yϴ>n^"/H9@b9&5;+fy8wvYph 8"#%F׹ ^$Z]U%3HM ]h>$t}WH[ʂKb",1p[ƒ6H@<ҫxx\(]Rdv//0hЊ5\eg8J?D;<RS hPzz'`ocs77=;4#)rQb]7G]~ jf_^Eή\دMɋ U7=nWiA>TL`BKxֱ[1(|LGNkӘͱA/fke4 |)8{#Nc&dt<B"mϯEu6\Gog<\c-4m|wL}1.}U60b13T}gp]̀%ebs2+ѠVzRJi*j{%ز ]za3qCf4iK,IwLϪWE ?+0Ž84O_Wy vmMzn0KK$24ǞSϙ㕠Bta{]O蛊m~M\_jlyb5q8Y Q'Ӿ:DDL&+G_]6 V LW}XXwv&;OK@ĝ+sCW\ 2Z%iekL=#/V:[k6~k (E4|^H=j#^yVvp OJ]$2fw 8%IA(FUͧFSLˋʣ  8[0c::rWRr+Zzv,-o`:_:LC4PM^(UEqNbs xkB>3"U ^}N6(hLYdw`)#Rp4IJ)}F&|Wkln )m]BKh|7~}CiT;,~Uqz?t$E~yGgnA}"]Mܙf֝jfs%dY<ޓVwb? *w~ 2El<і ء#Թ:aME5W&,-Bf'[ LOUpjcL,g[6ٜN8&wXȁY<',5M_XSYlka)c_"Gh3ִM䛞SNi?FmK u |0CGJ?5r>)};1[B=;|2Ndpܲמ;mK)*}r`@YCVseo2`@#֓ĤFn` wc^hgr!hJLӇ2M֩G/ NܨNI=k'\KZrjY+&8sِ4̏l+V 3=&=(p5[aH>㭆Ѵ'J' @I}6W8은L3{\-g3jJ jDO_d*G#]JŎ +bFbP6lVwwl]zBP{1}ۄE UCE^Eh>A ^zŋDמ؟nq1 ^.+ǒjoxZ0f2hJ݆X{2щ] g%5kG(gkrbz.A~ *@w϶$7ƾYIj5Fg-L!)K 9ҽ<&ylRyDO]8 >0N=Z9:xx_QZ5>䪬Z12~4 ٥'ҁÖoˤtewX*е^U uy`r[_+yj/ɖ.Xs$X^︄U:H\RӾXcl~ e(E=~z8_D]t>qNSer!p<&*=yّ;9=YzWQ`Bc6)j:F\!}%>"y:{@c ZHFOKE<Dy izwĦ&JTHHF\X϶+llۑB#I~sV'u=+0Oz{=40&KoMʗ"۪X*?ءCd&7,C` > ^#˕l>0 [b ko/h7@H$*i>;z Rx"k벾~>?9R!J~žJތj1@J HK#k7lmmU:;~8Ntj#BiIek`gXA$r%}g监)U6$K=DL88,y.ў7qi}A_y(='X =Ow|a"@]l OO+mQn_1|COL2$|C0`IFu$H2κ^`G'򃺝 j.pJNVѸJkhtd=-W4w6? %Gյ߯b?%Ͳ}p A7SkEyY A&GP(M늚蚭nm]Ә۹RT|+c-fӲ$J&>|>>]骡XRVJ ~5f ,IG'GEgSzQG:[s,cDSP]+FR=|Pg':e=IZА3pc-5{,UL+>.*n *@5cɵ^N\`PMwdM}VwV7rۄuK8%sv]I3 W ox7ě%$V4+_r8BεH-`zwImL+Nsy&C+j܆wTZP8M 'ڄ OI3/WdݒV|5',P)oŋ>R¼!vBUpt;Q.sk%s9~G-0paߡt1^9T[i.LJQZP΢bN"3Qm5ax|kc}ۓN_ øBl놨 p+}c[.6SMF34u{!h,^&lzD֎rkdӛHi M}ėt<;C`V6^SAJZ8֣m|N2:^Zl>Q9CrzF>iԧR(!%nh;Qp#tfDlB uO鳿CP` Aĕ(0bA$,W[%fI]z8( AL(ar?I {.HyuE<= $Oc3[G<2t:k8܄rnD r(\AZ}t4ɻaЙ;' =-efǡ)DvA}IXt|PvD А«[f\~dKʙ ~ȑ<|G$%p (*,=9B,r?*.Qmݟb)9겼#IGhЛYEn.d->bե-vBZ ήӼ%͔k]ӡ |V|YYa+)A.4KfFLy 諷x=}lmg<"p7KWS06>-w-D .0kGV>t=J  v:xisf]GhoARSS8Oaqw Y" N 2HGH6g$^'„ɨopsW(z)#clt_,@kr5L˳ɽzᄁ~W|$XnSK(L77uƇy'I-\U'5lR#=jqRG1 5 d' W;N#Wotk!+\^.+k!;L\y!r|E>:KPOY 垥(FlkE^ IS_k155 ψV8nV\i=Oi?k&vsV;zlo'"E@ޥl|wJ5oqcȩ)oJ}y"X| slXtÑg f|TH\?Bz9)BW 0(r8s =pud8X<ɗEC0eY̧.ڕO^힛)*2uה6TE71gt8p MAK|u؞!Y_޶o |zA-sް&m) PMߗ_2ou]^5eMJW,:Fk5MVtCq _?Áܬ9\RJ;G➀c|pi{RT5oڅFh-PD #0L#=On49tN4@,( F}= y˩GI_4TB^ϛ xm;E2I^6CZˤгe[N x!v'/.?kh?V&k3TLQPK.|)ߢ:c4VCuo~R4SG%KȪp(tVo\|TeSG'>ݽ|(q-="]?rɪ/fA~^qTI6m3 NƧX,{f.16}γn{"'K,#|GRT/tJ\_ףyփn,5\'k1M 䶶2yqө@c[0xf=J%x$ ݚ2ZTbS]ԜI<;Wɻ/Q54B8G%L >ũ~I`}^cERY8'µHo~,x<^Sv=s NHK!eMU[K)\4[ 75ȠgFr1ۜ{fF^D1QĨg;Wj9d>e9cc(|l,,4_h?>FG`2Q .td9FRKސU (tOh# ;ܯiGF2=98%2>=`0LjMNzvsqtR=:-B9=gW޾1zN@ FsEq7R/2w} Q*x%گwmK1 Eo7M!O](K5Xp \ #N2mGb_ I׃㠽En/v5Qoa [Z7p#K{$9qGdkx(F1g}ac(HAx]:Ɇex MP'i:CL<1ޣ}Zs{uld A5 #]4SxHӈ1 /TZ Yg sWќ!aH>R 㓐L["hզ>9Ezv o:pdbXLe+-Z6]"4cOξ4)83m韪TV]QKq~6+Y˸T$ PK)U#R뭷tܾa@vV05ń'l/[gm~ﰍъ)mh[_>)Ofg{v.x9Yfc=T_Nb i=d.Voh'۫Xr|<1ybFڭu~6:$So~#5wgWNR;-9fu0Jᗗ עuEy{h Xd&1+&M,F;_/3+GJÓX:\\No&'YGB18R]4-%'.[MmL.ճ-Asm_bie$Ez㶨/[i\ SVzVE9Yf*Daw3ڮ &M}3]yD`(c#i "48 r$/Jǂn4"E Cw&WiƶdrI?@0$xƅ{jüCUu6d VR9ZW?Yj1x ]bIDm|ByHt'@˓4KX& ) Jy1pa F J{m@DS4gr@NAȪ(XpnZ-L21 S,ttr]Yr:gд/ ?L$Ӈ+?-|5)Q;"pR|ojXend FSȹ|&ӝ0]XMl7=Y6GtpfΈ]6R> stream x[kw_j%9d%j%ǕǍ IhPHе{g %r$msb1;{.J&eZ2Ǥ,2ƌҨ2c وFϜLb2`MO cJ2)Q ]RB7FgdZ4;qyP^b>BiOZVS"f$=H8 *jJG, PY{@G"@U Y e0D+@0&<=̃7 CW#fM|dT/2 O(u(A  Pu,*fPL!쑉!6]!Y 8F8܍1XPꢣJI34±k OXEaLYh2F#%Ph@MOR0$P_ A T$-Li XKIS%%AF XqK) eH|<ٖb 2U08u hQ *)ִԡf}bz>e=N=׿CP߿B<9c*nQQPNAVJS1<몯ZJ7ʶuS;m-;>T,l/Wmڎԕ-;&\jF|l@3w{jYÞڻ` Zģ`T^d`vp·H1~TVdgۂuIUL9ü`b6(Si1,ϧ[죺A =i'd =oX!v҇?aH}zJ'|:4_c~V 73M;,Кgl+Dfb>ۑ=7GdHwNQGd4*)3$k Ӄ0!S!yژa}~Kk> Nb4&Dqp;5糈x%fD0kvIyeK.1q 23rCFrGCd22Q˦mVMKy[iPU(C:,1ļ Kⰸ3Q6,&l1勊O;>I6ݹoLx77_]c~<ƹ-TdPg~Tw{*xTϒ Vj;R*x)avO 2%CfJLΔ7::K٦X`SV7W`K~RI Bp:~)fL;ń͌1[̖IJ6)M8$Ce=&,Rt6M4ԥ)^\ֵ䫥DYlJX:{wJU- yJN 9H"'9d&i9$|DM[h׎z$~$Gj;"+CZъ. y%k\J4֭jEG .]K(a&3KtL###) O{PMO) %S׬@M$b-Eo8XyIN%9rJM6ō] Ut]`8h`)Bպt 0ҴGjOIFgaZHe_+[768ITW3TכRTS”{LWviMWʥ RA4qr^V&SӞ ]RTޥht'MSz9Z]nX٧y#7˺륭to֐d8ˆ' UM=*SO(d «IHxhF Ի#AqFhLeW-L{Ru-1WK-zk٬fXXi8Sm*%Է3h(Һ޽[SכF8ևg_l:'R5Q~=g<md===yB (oKeq'9#SU_ӻN@7c&і?1s~| ~ůyG|'|o-)͟}gZl)~<ݝP]Yb|I߼^xT$-*_/؂ܰjp7SRHQ!iq"qJ,&n()E84xz!^$vݘ֮/ol'n6.qZv(v|W oۂlz-<=l8*gۼ?ɛ IAM9n$9<7w@Ф܄Vh =E؄7ٰhMd?mQ-2ȶ&0M pm_6ݙl~ _n[6;!DbF? {9/6/>6@5{1iE5*')acM^ d35ccz},YjƖۮG z\}KjR{@*mܯ$u\ ڱgAUϪ=%L/Vj~{˰յu  @Uч뢂r^X㼚OɍG4oGEWN-)'XV;ja1O/QY}ܣߴN"B50s "\7m[cAj{밤}ݝ!6#M7/K q9vW, endstream endobj 131 0 obj << /Author(\376\377\000N\000a\000m\000i\000t\000a\000\040\000G\000u\000p\000t\000a)/Title(\376\377\000S\000h\000a\000z\000a\000m\000:\000\040\000I\000n\000f\000e\000r\000r\000i\000n\000g\000\040\000S\000H\000M\000\040\000t\000a\000r\000g\000e\000t\000i\000n\000g\000\040\000m\000o\000d\000e\000l\000s)/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.19)/Keywords() /CreationDate (D:20200205134135-08'00') /ModDate (D:20200205134135-08'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) kpathsea version 6.3.0) >> endobj 127 0 obj << /Type /ObjStm /N 4 /First 30 /Length 204 /Filter /FlateDecode >> stream xڍ 0EYĤ(؝O|C(; uuι3#d =rBCB{ esU]bYYsȫFojUm1V%SSdyfŃ(BƁKS%O?5+}&_5q^+hƗJI;㋳$]g(ovzA(l endstream endobj 132 0 obj << /Type /XRef /Index [0 133] /Size 133 /W [1 3 1] /Root 130 0 R /Info 131 0 R /ID [<3BC17D9AFD7AF1D1EA73DE1826D004F7> <3BC17D9AFD7AF1D1EA73DE1826D004F7>] /Length 336 /Filter /FlateDecode >> stream x%ҧRQr9-9’s@( x4j `pHߘNwD:"{),8r\B؇Ha؃hXxHDUd{2 a !V`R! !2aa 6 vTb|(P;b􀕕PbJ ʡBeѻF:ZpQ YY uP Шro&{fhVhv[FFKOaU_za@#κK0 c 0)V3K3KR-ͩ~mi^/K _YZ]8cz3bBYUk\ N3 endstream endobj startxref 226811 %%EOF shazam/inst/doc/Shmulate-Vignette.pdf0000644000176200001440000056425013616633162017342 0ustar liggesusers%PDF-1.5 % 15 0 obj << /Length 2160 /Filter /FlateDecode >> stream xYKoFW΅h:&ZJ X !!'3{[|42rX`aYdWc=^|Z@rEC TRm(A ޅwbyޕSeX*.cǩ>.~~Mt Kv3͓` R&?2aÿ1z}ۜp@pv$M\%KnI 4S:{PbK-1͹la[i'b 婰ELE,f^F*R3D*,kʩyx½ő:i'- ![ #PR,bFχ*"tKu# 'sG'8U5ϛXf\:<p$ I0s3f!C) ?⯆zd ɏx{ؐ[m-$AQQpfĘt`f&2d{n8Yh+C*R@XM\PbҪykOP{;)E3T }Nǚ `D$#rA*"{RI518&Y¥zh , DmX`Op^ *C EͅIǹhعC,LT 5p=e 6a ƌ32:`}:ƭ7և1a^Vy;}UҍūirH䠕b^ ~6@Nuw"PS򊌻>r 6/w鮬f#/hEC;6T|0ŕ_7< ߞMKnS=WǭET4gjxiק&X[C t h"XLP}\N"*#j5D2 #pe$/y"|4|Zz 9,Dqh2j>MKT~Xc{_J endstream endobj 32 0 obj << /Length 2447 /Filter /FlateDecode >> stream xYYsH~ϯP9@Ɯx>(Gq&IecȤhCʱ~(YN\yJ h4Ѐd5#ߧ食x"7HM"IO{Wf(eSuemq4-f1^Unapժ%]S鋟h"D"K19WÄ8Kw@#&r"֓0~ Яm=$c-:7<i-%Qu3-smbxH(C`$ c_*M2k$6CF0*jeK^46ugM,(rG˖fcBRU[\:A[ҨUָ)8ȇA'y/hI? 9TɂtÏWu{۔l9ʉ"N4lO6v io07L7vZMSv}99\[@h#}Xhf"_?!\4}6?6%Hȁ"> v4Qplno멊/6][441܁#WOr!&]Y4\NP"?Ų #ļDkT:j5Ek$St0|0]Yo_%+4n ?#w<@1`dzDU=|jwQ gXzxO^tYY Ө7Az[,Btn7Q#{zm ϥ~oͺOX'A,WۢA)OYľG|e)P #xncMIRvu_ >3"5\MW|fD]ה׻l Ehx1q4płyQ48" X')E/CD;%av쾵/nGIXs赼 c~e' ܑ x\3HJ'Ɛ@ɚ/+Ƹ"ݛ C'4qh}?'!41GT$1yuSmn+vfX }J~9`= oq8#cފAFrGΈz:QBxETD/~?=y!e]VeZ Uz7+}J,_@=EJ'TpxS1/}k~Lt>5-^)^+~]j/tb^~i)^+o!e,xn+cM+TBOab!-C3[|^Vl:\(BC J8ҳog4pj.'xe^4c84BOoycB;ڀYrk4I{5t7 8[V ږd M3F{S&!eZnb,(`Pc¼DܗFݔEsF*B`Lr_C,@%ci]2p ۚX.YrNNtd}2cHǥOBnVfEMlx*>NO}ӐVÁ\(4خ[7h-& <|ljب& ϗNw{2}=1B*k,iqrX#kPCk}Tpq@&d!:s)H"ݧ4o3 | >,2j &JԚBo`> stream xXr6}WpijFfԞf&IXbˋBR]ig:sdk4[D=Dh@:\FԶ l".1\Go&遲1=  !ۏul7GOsaM|w")'keٚiϨdr/ώfq˚ݡ"fJh ~xiAlXJ}ZUl}d~^ޥNgU2wp̲ir[yƪ.Y3څowH$<$1XSyŦBdkiN-fҲǣ`3Һ"imGުv4*E[7*McIvg/{oj4'wk62 Zn]t,Dr09޸ ӎUyBN\*8rÉHv<^mFgCcpA bEp/j"\ʍ}ZA,aIEa!# ( _D1 a!]^{0 կgWXǧxxG&ZgE%XAѣ)2v nA.Pesmj>ۛMURHq5?2(b/C.!Ȫ\I^,!LJeii Np֞_΁%d[WйiRZ0 9`Ku Y::jr{b>/ProcSet [ /PDF ] >> /Length 37 /Filter /FlateDecode >> stream x+2T0BC]sS]C\.}\C|@.`Q endstream endobj 40 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Shmulate-Vignette_files/figure-latex/unnamed-chunk-3-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 41 0 R /BBox [ 0 0 540 360] /Resources << /ProcSet [/PDF/Text] /Font << /F7 42 0 R >> /ExtGState << >> /ColorSpace << /sRGB 43 0 R >> >> /Length 1048 /Filter /FlateDecode >> stream xVKo7 ϯѾm#m5bKZ b,Ew=sSG!:zwv t솴5/_]pp{X ܇c%OSܣR<w $#S=bA 5xw/ ();*;Z2Ri $c{Xwq]}H38L]zApy^q%p61zUبQ-`_:oC2dbj#[%?yX}Es!{44N-؛Goa`M52){,#JmkgMw)LIPݚTqIҢxN Z*z S0A/&zuҧcMD'^ꉹ=?'zueM޶=Fz/5 =|kҠW(E:Vc6eM6* avDh\^|K6ۥA/(M {zf՜ Iy3%Q8: *zo.iB̪`844#gdaDju3SF*i *.û]߱]]0VӠZg-lVpu dm @fLQfjFBnG؆i4jy [ج6)6{ _PZ|qd;??{j-O }&rtqo/Ow^zxG~_x&wBЌz4<-?;4-~\??7662'7g§ ޾85330.?}nWC_k٤rupuZa)Nɜ endstream endobj 45 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 49 0 obj << /Length 1049 /Filter /FlateDecode >> stream xV[SF~$;"0!m[n-rH}^dX^Ξ=w.{عuyc8GSf!a8u!apY=/Xԯa?o9YKa\wYOb],דI "B FxhSkK2vVbDp "ʻtc]Hz7[+Q9 RhpxDMJi+S2WuU*d=a 6YZK6f[UJK 'ʹ*gaF-&D~WHm{ʔڬeI%C|ߍ˂#&y0ƶlHZa+39DNGĖ\pZl{_՗eUUޣsyyq][^wn_F|Ek<|~iDθ ;uu;4PZm=K/zR~6=:ܹWb ʪWuC5*v/ֽeA7qr<>\E_?^ ϓht)bxv _R ;7w->Oc4N4IRX"q*@4p9Xm8랞{'N~ijXb+b6?$OJ-,uaq WX1L`y<kC7P B(' oc'WWd6O?.4HVhcO}0:OY3 Vߜ[nmLj endstream endobj 46 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Shmulate-Vignette_files/figure-latex/unnamed-chunk-4-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 51 0 R /BBox [0 0 385 332] /Resources << /XObject << /Im1 52 0 R >>/ProcSet [ /PDF ] >> /Length 37 /Filter /FlateDecode >> stream x+2T0BC]sS]C\.}\C|@.`Q endstream endobj 52 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Shmulate-Vignette_files/figure-latex/unnamed-chunk-4-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 53 0 R /BBox [ 0 0 540 360] /Resources << /ProcSet [/PDF/Text] /Font << /F7 54 0 R >> /ExtGState << >> /ColorSpace << /sRGB 55 0 R >> >> /Length 1048 /Filter /FlateDecode >> stream xVKo7 ϯѾm#m5bKZ b,Ew=sSG!:zwv t솴5/_]pp{X ܇c%OSܣR<w $#S=bA 5xw/ ();*;Z2Ri $c{Xwq]}H38L]zApy^q%p61zUبQ-`_:oC2dbj#[%?yX}Es!{44N-؛Goa`M52){,#JmkgMw)LIPݚTqIҢxN Z*z S0A/&zuҧcMD'^ꉹ=?'zueM޶=Fz/5 =|kҠW(E:Vc6eM6* avDh\^|K6ۥA/(M {zf՜ Iy3%Q8: *zo.iB̪`844#gdaDju3SF*i *.û]߱]]0VӠZg-lVpu dm @fLQfjFBnG؆i4jy [ج6)6{ _PZ|qd;??{j-O }&rtqo/Ow^zxG~_x&wBЌz4<-?;4-~\??7662'7g§ ޾85330.?}nWC_k٤rupuZa)Nɜ endstream endobj 57 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 68 0 obj << /Length1 1846 /Length2 21220 /Length3 0 /Length 22397 /Filter /FlateDecode >> stream xڴyePZ.wwk57Mpw {\#g9s}-^kuW5%9( rpadeb+MXEAv6&vxJJ1'5A r(;:XXx)R@ӻ` P{:Y4&e `i}w9z:Y[ZO?ޢLY3[5 ˤP 4 )jj)U% e5Zj ELM]C ..j24d(y7 ., VOF^?Z8Jrqqefvwwgtuva9Y29U3d xw"N+I/;Nr-?1ep+_{kٻ3/hN1W'?9r4.]~2};o_ޘ߸c]ϝY;%SQPSgo<F;;L..Y'". fXޛT\ do^3ĭyr9y2m@ZX;[aՑY+PFlEY],'̊O:变_oG#km|v6q\\W7g[7]iR 59ý̊ f3c%jghboBiebomv0)pv+[Ye\Lޛ^~#4̑{þ/?; {/:wT `VPWQGe$`2vqpLL{S̙yU7hw Ή1yZHÏM<?[A͢?,a)@4ai_(޴vDs12<|VNxq X[}~@8]"qh#@(c|`%r$TMC^99V [wWב X!R&s(-nD24Qӡ+9+K,r<YbI&1$pljAҹ c}}yoeQu#6w%.r&7|3wb"՝rb 9hP౤6<,CRTCE'7!9(=gB-<ЯQO߿X 1줌" H}`/֧ז.CƱ@,y$G;䥨WT#GL{I]}V;]9RhsUN`n.:-wgt~4nnzD "lԩIL Vhsza'idBɖ&=Wðk(gj纣F9N#Eu6Cު_ۊ o HʿƏqɎw+*ry94RShfIXrݝwhf) "!⳾U-aP)3QXnTiC%oj};&%A!.ulDw$+lIa8f"u$+[k' [CX!egP<WaG4&2/Cr&'ϼ-OzYQYu XJ ql︿:4Adg Wa/TqEpߢm*bf?͚FԌ]ʏ oVWx;̠C<@A9zKʑ7Z~v#N颭LB@ mS [3ۏq?@e΋n|F,De\D&,pg7{dTfW>߾z5qR$%IF9=i' o*Djpe$Gd+;xEq04IKz]N*ٛ a/gTtgGdLZB_V"ąئ%ͭu>q^𠞙ԟJ`<;}ƵN{p.pB,cI"JFthUͩa% uv%gƬw.Q|z6jKa<6i)9l"k-׬l*̀ejͷ]ԼmaƤշd2&ي u1ᝤgIG!閿hP>8VwP)$ja On's+1א,\4C.IGѬ*t=DrL#>`Q`#I9A¸0IdEs MYRd\QFr t]51{cXŤ;P~Nݕ |CǨЊN/cduj}p1t!Ov׸ĊLj%LN4АYk|fRvz1ŠL5wfY=ZQ(MѺ(㷁 N qyOm>;8,wt*rInP>1VuڟR*M⌑afm*\؆Ww~dAR!эncBZa>t{{k]F%WI}^.o_T29z>jCL0#hTSф<1[ "),!rf[%{9O :YtGYF8^')U_mY\!UC{)BKJ`_T\ ;?* j| F/Zkb=mqze UFЄ1[_)ךA$J:i_3]wԽ>@ o7QߠvA" /:t^MǦ$UY2KLlC*B8x_)tSۻ |Gݐs6Bxp_<0_QHi& ŐoK ='OLM0Dէp2z g;8΄\ o~}6͜@loA0RqЮ2$y;+V<[gğ #cfnE˨kQT@a|WLri2- ʞ58Ia`4K‡iReF#kנ0%F')y_W0>x)-lY(׻^T)W':%G'Z_h?ZYkNf2#hkS hu_@⳰!4jA;S 1;W?3M"nfS5MFopfQ, uP555N5R$nE2Ҋ8N5SN"BD:!,@1C3 l&J%ޏX=q :RpT~>8џʫiוGbC8/c*'\lØ!)i ;Q~bT3̥#$um.wN.+c?O.3`_~pAauCXKAF![RY(Im#J0JR?~-ⓥ"@`@whB /J@j+{ ȿ ^KfxL(5C#+BfSY_z%?/ܽ6V'4L8"K}`*4^zA %vE2B^PaWz]ye EѴníAu7A ;3U䃩/ĝ8N;~%[~J[VN' ϖTpYgeD9eJt3dݿ&`ٲ;KW  [Ϋ0lx6ju5د5˳o JW( 3+f>E s142$06cyy:!Zӎ:ӎ>J¨[U }A lcȾ[=)/9[&YJ6zryKm#5F:UwI-tzt\$՗ |ޗG$ⲑ%0`f3n^ 0eJ1 be.JN=ۣgrɝrxQŜB+2`w>G$d\]bj3[m *y|| n@QeQΔLCT]yq5#5"hhAuH8eΡK^ zcQә#3.-mliҡLفU^w}tnl&ɭ{1']TxVD  i:B\LĊ ?U#Ic yiBqcM%L H N9{{KK\`x:T, +mֶ.xku~ 0x̒y3B'pQwg339^mh]$`Z=^FloL_:MIHvx;7t+'XV6 3YO/3,ȯ+N`e.ǗsvvxѤD ~n!>yݑ/c)mUWi,!ǀ Hpr4W2WLX+(dm U8oOzLO: E4=Fexq8c5A"t$9S>kbp(-(vi "ITms.!^f (li.A͆EAQdu]^D\D *[]8yt/ΟiDۡ uE핓)g#4]2kS)V{`J7縌+`s.K:] f7c6C`I(GXpr(+A'ݫ"~_ #N$ T[o{ 54_l{WB97 N$.ss5U>J!۷&1xi?3|2ط[4I^[kst䔘v{͚2,[fuB\)ZZNG:eF=)(^:'RqCksnk.斧͗Mr{;ɾ} L5S`ڸDX9 5983-YNMW#),ףW2eU#1x`ttuHG'vVXZ3HIu_MCdHru&HٝkRSuZQ/Q=FkO)9qPØ[ D.&[B>IHhٜMo˭*>TgjqZ\ϟ89[hxGk]LNόLfg>x㖉wq5fCu6~ tј8_x(s5I{l |ZĖBdI*_ ,y?켓܈ayss @ܾ;x㦿S5c`)GY>r|M|U8LnGa ̣)] Q$o^":auɕж]hO{ȌӢͥŹNZf0'1|?5Ip)QN[d詒TK2l-택7!bU}Mԝ/nb'?iMrobvP%=ՕR\_QT=K^>B{˗K/ >Aiҗ!8jY 1 MûʪYi0(} 5J 7CAnaH]48c R\jGx ?7`B*\pPڛ$_!C=ڡƧ،<^ɓָN+Vv+ ,-?3«2=;!VGE ]<^w+LHzRaE%e˲,eaOk5j;= +>0eףh4ƫ)ȡnU QsS[{5@-#ٗLOI[(Tm0013L~7F퀱ѭl'wgdnF}:+rݾ ނR4m%Zo١y);71^&c}懷kێ{vuP$f5S7o+Ȣ1 C95ȋoT_XQb((_{r=}!e& L6"qRX9Iʃ<֦ó%mb9'Ʀ*=}2Z[>َf&,#ƾ};ɫ.Z>êmS<˂؎oR#$?+ lU/?ajtAX#q; wg-w1X`C ɺt#yA2?)0m"LӁõR8GU[Gzw<|ќ~4gcW.f>dlmd*Q$)}QJL&vI9L\?~ BM(K%R&lAU]ӡvjĈToL۳5AC[[s ɝwG?IΩ! r6+N;a%>G@k_[- 1@qJy%T)h$CǕY6329RRkx<-e_7`W u"Ĉ5͏kB?ee"|~ 7oͯXLX{c䊊_#ژU v-.RֳQ֒-I7 j0aZM{m8 :Uևsx*OO8Oh`Ƣ: wTsA,3oNIgfEE[ٌf&%3E&}! k RtOjLАf{;b1.궠cƁ^ hr>O?9:]Ce?Z)m YK;J~k}?S%|p(gzpn4Y` R~6Jv7Գ(=1EXU  =me^O^^LwIA=^0G9|omh0^qdYSZZ(ۇep YHՒ \FA|%0}zONj[Kq?bk(=зkM)ܒ OvQZ\c`ӣ-e,fݵٶ}ʑo %ÙYC^)UJBuY^0?}ڢ-K;b,8L_MTq ˴\OFkdyޏѫA M)H#bdZhg 4͹{$o¬,;߁ u3ͼ  V]a[S|9H#ZS82ѣm\,8&^ób.S4-lڨrH^ȉrs+eR,%QPQ~Ama6rgE60aۑUo2 \2\Tx_+6Il5g<;r!}clM3;;]mv=-6?&T '2yɆ>ď1 .bR@/:/&5wEŬ״9>8Gֹ!G&pY⎺gĕXy$ĖK3G;a>RS˵ɏPn;ǭ73KV ֖Ú*Z“ZOu$1g^%H0Q*)\35ϳZg79\uTXJjJf皞g,֜$;v^\b)3G>Kk/hjֺ u=i?~a]^CI!w3tF0TN.kJ]{N]&ˢR -&umydl~寂nA7?c}d[BF:15PLF+Ը/1:~ U|wsl?ŹWL'eOU^Y [5 H;$H<։NuurD 58kCBI:.pKa+4H\ծ$ ]هl{{ d^?R@U%Tvpd wGT1Vd&FͯY\r+Ô2'Z%}-dD߾TRi.epSv&VwEl_T-D(5~eX^\ά8Ŀ!W@ Q j}AcKKۺXB@8cΆnR!<!r*@NXbl\io# \.%>|t׼Ql3g+RClro Gsbhj$gɠVc:y* }S;~ NO%8??ÁMu&ddwH++^ f9zGӇ[TȐ6T6"(k]`F艎Dtј)n@^94[NК<͊ @Z8g2 u2ai(﵂<6{ѯ{~ {Ikn…~ʋaV#X 9D7vSlޛj+\/c9蔽 cb#WB g/3;4ؠvJgw10F^Jy.6u1CeDBew2,v||if{t+r,T8&÷ߴ05! { wc1WY8[cOYC7^GaX7_78WK  N y*5ZPg e ETD<eA -F>R =@ @_3X:lqJVg 0&YNcw'>LjF3WS`0+E Igg=7w_߸' kD,$i8zSF˳Adwd6uLRㆍn+,qԒ| l2X2?%#vjx}C9qL>=VCa0hsHfNk" ֈs85ah~(<AަAxp+p~k2.tc+9@YRb[  Yr)֞._!&Z=m@hJOB !ڴV=ORw>-)Q& GG2աyU2vf٭C^C΁7EI FA\5 M2*:.EK;˗j@)ϒ]{]cqRsWPW*psS$G Bx83'ht*wSs! Kj@ɡ & )˻.äs%X-RrѠ^.hCEN&z V*ΏWf͵ؤ"T˹"tL0o(.jdFrP~l?7+R9۱^ mڎUiڶ=[<%אv,z&gbQw3ς>^(A$s%v]6f4fFW} ssU>yaO[Wj:C.ʭM,Ypʐ:٨QX-$U,`ËӺ`8NA#f3Y2!{аؑ*3u,*>gگ5kɢ6z*_ܟYIT#ύ I5>Trr(M}NN< vĔ와}rJHb.&.&7O{ƎS, #|JDpCܺSź3Ei(GTYFՄHFw<0esk.<;lP-9F/ C# 21|ȥ-MLV$GxgS<;Yie" *ҶOs$br.27aCriaea\::g>4CPٴh_rg8e o~VhJy9CBqM,<"%ERo"F6"LNo 4E'ފe8j5Y]*YzL4ǫ]5l"bkX JHOHѕ6꩹ Vno3Eq,'1'p/ݼ .EKJ 5]U4FĿ2NVDѝYibldhX({PN4N[(^S`DD~\BCE0!a|y.͇.f}dC#3sZ["!B$!h[`o3Y?Q=Jٟ7-k7%'T22A^ΔGhKMhFVX5v3 O1tNC:3@9; a{Q:ޫ {E;AB9iٮI7i|d[Peí"`bcRHPxi}g` uxdmAժuR7|C8<v3iiNJvDlw}t.PrS#!]Bl<ʰ۹^f7G QuA)E*W G>`Og@}4Ȏ'7l^  ?>Ȗ;h{4R/B}}0 GNnQw ֳ:R1^K˸F2@gY((<6q)%o8}L[2'ͦ9`Yb.q\?̢&M&ثMΣ+1V_^2$|v/ )[|m9 d^new9Tq׶A|'^7 }iAv#gAܰ#3ȽdlWw!$&?41-K N}%1kE3 K~¡zM2y_Nay"0|5QN؜t蛦=ݛ׀}1NQ`~|ϠC蒜Z'0Զ-EZ}?LrHG~ֲqYzETQ(OW#~hhT2mp w@b!a8߫l#Ț%N+Dpԝ21|QjM/{ z}b52|VN:Tץ:?H2ǣfgўڤn emߎZb=(~3v{hq5cƇJ6pU{tو&[sMTIeDϛ즯T~U 09_gůPOL5,AfY\?3K.9(@ŧ[u0 ۏןGWsإJ^ͦz$z?A;D¦~4zv^SJX;^Rw,Vn^ѝ?lD*J9*j5/{<5I&!)[v$om~ F'::ֶV x1fKڞ,z)}|[,ʧwUjs__uaůDF Nc7*-3Di hs:M,FDƖN%*޲^cƸS!*wӡe[ѫq /.=U)QUzFF-A9z21 olm|_R!Xԃc^3_7 1qݰv~| g=̋P܌-^;:7׏ChR?g { rN'$ESw!57`l{oYVQzd4.m)h3WOD/}׼?nZAMD<&E=:<lz5!"@~fsk"rL7L8XԈ}WK *R\,]10uΧ*AҐULXppL"nʣMe sFIf$=҂:d FFQņMwx3¯K24xk.c_ۄTy/}99Q6#C~maZnn21ܶM@؞]ye<+ p0:qq1>QX[G]~Gd4*D?"Q(fv @WhV'd+$O\NvЁJ):.3ms)AtAєt,8}j*52PhaJ=`כ}x?tLj=:Y&҂-D E@лElJ_ ݚ`0v}{!EيuQ?gVBh%qS^|mp.#JvŎ+B3"xftvmߛZsNs,%DjȴwLc.j;`_RGTik#KZi`I a㗌>Jr*)3uCBg{L0e-UâNE.QEDA|dfTŘ9,Yo6幰\Rr;2@O>cJF=G׽| JC)ɲE.d}Ko eOvR Oo, Q^L$Bɇ~&q> TMVB,Qxf-^h~Х,lljB  mf|<9)z& zO8eCE=FY hz7@(n\g$Ԓ;?|x5#&|t0N;=gVؽPͥuxn+o#@=jd޷/XO.S Κ(a@#Hs J]NR&Ed~jv61u`D;#V S}B4M;l pCIVB[nb40D7#D%4JMNS7LavZMF-GlIۘ"abt@tnSKGsU?w'ʵ+>$G.6 kNIx!Rï_0rqJA+f!=7cܠr~j$d(gDZ6سT-^FN?,t|%hL;4 #b1c-63 i3 $WT_di>ZmW?PPޤV t{_D]L)e5RjQO+M l[Cg9!T,`$ө8MVvEM/ `s*#SȔ`(`2]eY`|N쨔H4[bV~*\NF1+*~p :k8@0q9w_IZW'@q3+Kˑھϴm탑E#J_%R#DY !'Fhq5pkqBZ rI+?T,027Ҧ+oZ]`'g(kO- 뽦wdł5u̝Kf 1(ưw<u $e5hWYޗ y0Gy^h1zp"`v\Ÿ:0JưMl.y'.#sTex$dҾBw~y4 )=ZXӗsHsoZw>Qi1m(~օ],BvTpyޚOkR glCnL -[ݲQ.lJ?"I \|0\ ҒޜjVo qVlXk<#qv)6$Uv[#z^!Iy6~~Pa[95eU"p ™W`DNf9yuu0ݟOu(Q )3JUdt܉W2W亄IX[rf^rsB/I=)}cܕ,/_|ˎ/hGĝN >,k5 5l9coٖ1t>*Lq,M~gٺ":AVrk q.m!,]3Ӣ"9il 4eܺ[{3eU+֤KiXQ"̗3Gԑblq⶜ʫ-^Dx2ۧ HkGE;oRϓ--'Ա(MH] I F __R?R3D7ٺf yߠM6%%(ʪyhkأ A7 33&(FB#1#Rd{5tɌmbTwn*eĠhõ />4*uܥJqI^Se\4 (J \CIV{=?jz4aͲG4=,<- Kh&Vu-DĐL7Zmڈ>'?[Z:S_I/8eVCp(ܛ;8-;&ZZ޼h_^)7[P|c1GdVO1ْSѭq DŽ/.7w8[Qf̫+(~; |1S7P l9&{=ѣ 9A뎬 OϘ?n/uˮM0ߝ!hXm6-WX K^l# ΞO4.Z#j%000+ۥ}qjj*;LiP6o/7ˤ*O+)Ayɲt( -> ? 0P˾zR!пf&8YM/M#2<;\J:2sfٴ%Ǻ=1R/"8`r֠\RO5yi.͌i[OҚ#$8s=#x <rY7ɮىdnC˙D. TuKdtcON4g>F+=h؏ [Ly"(P|}i + IpW/ '?d[\d IOY7_Wp#[b&&-&\7h%0\E24gWO0QTu7ãӤcyG|KMFeF߻{ -hpy-@j(ߑJ^Ӂ@).Ҵ{w/o mS‡+Q))}_؁gp ^T" L -62A3qb0Ƨdl t]|=f7[%={_m__':aUjq@9e4#Q=3V5_Lt\$b |F*4sժT;cgvm޾2/@fixT{(UzK={)qK}K!qJºRWIlǺNo8ҷ Sc'c*%$R˒R/a_y;pn]X3kQCT+,GCO~]S˷)+I!.E[#I.i1C;{3$#M18J}NYАS~-x+*_fǚ`jq.j&7OQpOz0/Mf0"p \oC:v2wj/p!a endstream endobj 70 0 obj << /Length1 2470 /Length2 29794 /Length3 0 /Length 31237 /Filter /FlateDecode >> stream xڴeT\[5 ]CNݝ.-  xpw*vwn^{3FQ+1;@L,|EUG{VFU Rhvt0 +{38‹D :]S/"ddИ]A&e"bmiwbL93[GW[k9@I 6Zh@+; @ PTUHPVe'Vssrrtq5u i$PSWoPRv(.,+jp3pq rcf`ts19X29Ob  `d;](X\^K A!;W X7vL +/hN7A @w /̿9;ӷ53qps6ݶ+@7{{fMQTIVJRMQ@Rm\+s-?E?b4Iё݌qaވS_/6dLS4v$ͽڲ>^k72 ; Kiu>Gf"~*tdbk[`8una3/A%~|h/^[5+̲SSك?NUp(3pvܰk3p׼dBu5R|,$ɗR:-%!4" o.yթ^'X\\:.k;T^}_ipmg\W!AWO&68y?Ҍ|@$uHّFB~n&$64 y9@%l%XU0G(k?BQaP4cXU̓3$!`, A+ TetMw erBG%eԽ1M=cP  /ݫ9#\{t.b:f"o_,qkE \$=s!4LR%CEKF~DĄT );} D}|Uӌ/ \+zH5ͪL37r>Ac8TsBӲX<8:L6{͖UR @Shx?}`g{rd7)jYme"=[xDoPvyS O=I=XXqӁ峅Bڧxz0rVff/V6(y5e JzU ,^Laae}dZ& ly>f)XB9YSuN%hd|97ks"Nu 6tHESzk]b"EsH4'QȻuY!K'y< r.,bf[r&ZvA^ BR)fc&q _*U|_ycTn!;Ҿ(z)u G8ƩیD;e;A|`=<֖ˋ㸕K WFlg=;?\|-2#t&mrRt2ͻI=ٹvl:m., Zj@\YZ'oJ5*Y|'bo$rm@l" =Mg*=]C5M/}G9p:AyG RQ1Qc@2Q;5B0[=Ճk6&6Gfaԍ#]%Q)nBЬ>E̛. $)-0%_0n{\6}G&x$S;{NAq5E23NJm"pytxCCޘbƝ8rΈأԌ\o' I= OCVTO^bW;<7SM-KSjJ&pWԫ@|"ɒaDh0VC*'pR4MG4Y)gH\a q<5?-4*qҚAdu:8JkX/u$Iof7}2l% >gasE=IQo\<i3I#>K }_,9:QSt~ސm(Ωu\Z0%-.6iw 3W Cg2/0ݛj~ `^_a&/"3QlRʼND IYë5\|Vh Tт2H8h>ې Y2aY(E W!L =s8lM-?-v G7@5ZXv\IÓ1(PS=NlC0w:fۯ\SטخGýþFTtEv{}r.q.ilkoyP|p.RHA܊תrU8a[b%-4[j !˩u/ۈ0Lݞ;&bīr([Yb{VBHO X/Nh;94!?6@t,(.B(rq~3BXFZ(BܪUd]f-;/;(Z!"P a_{f<ܠ} e)=Uj':wʳc{]C䈼K,󉛼pLU˶  -] }Lv`z033Dꕼu cp 䉬m~U1jB*WXhc«wpA_]q 39EiA[x>KsΆs]*nkWꭤUaєCf^-$v3ٻ%O83l-&L"(` ]M(6ALl*)j1PVc *JYgBLf{7:hP5Pju/ 7+8!s.~|ong* j D:~ uT?=40<$4A!%6 sQ}gJtjN/j]rezzE8Y RGLLn+ǴhCg(CԯiYIBA`<'ŝVcG?eSa"Z'j^ vT< YozccB"y“m˜ Wd!'FS_N%um̛=Y}r_^G1Nβ?Kx䔍?\at7 RȔi %Nl1TrQsm̮[s^v528'& h \h -M7YmᬣNs)PR/ljԻ]נ[B1 7I$]r}D!y񆯏n_ {2\{)K6-a?XG0.!oH;&u66~ws(͒|~u+=ōo!iv/=4Qx8SwW?AP,IT"'Lrj–:/*vD9iA@" cP‹@e|:dFL5$\"a*̓x~Y0v&vIֹ%]L6m1/5nޅoEprL̆)AamIwB~`Q n-?>ra!@{׎d1 |gGps/*\I+BGw>:ɜ2d xJ(&,[AXcJ4󕷝D_NxFF#!¨Ip)IGsRvcˀoH݅WW 'c0VQ9bw$>ęGh۞+hHsWꤼxoS-dJS4Cai3n{%t2_MtM׸Lm Ȓ5)1"8_lp΅t?Dbc檽y-ej"@Ոĝ FǦwWڢOuғ TvT5ʄ(>r {VTH$V*M?qK,uzQVKFl8aI$QYiIC#%-Sf ;EUW3a1i5eԟU.VBد*ĽMG}V!k)T#h\uƣY!y>M"݇lc\ mʰDh\x{Q2c|Vudvr$c`8q UiLWRwgDTlH嚉 I5RFpiQ&|:'YW?K>_o~5EiKx=!֛҂a0Ub!`tn2/=:\eQ!}'^bg]RMۓ\؃C"z.|=O-gEE3c #}lO\0䬊YѤ& xˆNrYE[^G>vC3t:h\0H˨tcZK[:sBxRmu%zQ:+mcˮ'ܛMZo ߿MVHPNKР"XE2H=l҄'M<-Z"0L(Q Sm}0 9x [7aظ@ HtCV-/e< Mc|Bnn1,&{W!瑸X-ԓAu'09"LڔNa9[fɔ?oOz?!qnd$;P=)ARtBaԠ<,?MciP-<B_uBMk/7H̓NeGOJH*f)(氥9YЏ}~u`ݷ҄HBGٸeimv]|-b0\w\ӓ_L{ԧh[Mu{X>cl R8Ht!dI*)Q.l6z/Ez*bD{SIɽa ZYukdދEte\Ѡv;Y*?pꑤw, `P/(:٫\߄R $V;a _O4T">>bUC֏ܸa`w7غܼ ?KI/.AeEC0s*S )-#YhQ^&d͜ |$JJaMe}@,XJ mhzjP/q]kB;I[u!>L@|gb&k5_!Vj:WNvf۰ڂc墨?ڄJjXC%F UVnļ•5=ɛ"iqS6$MQ~̵g:Oc5Y}(MϓDtg4?ƕ~յ>kg<ތґtF{? I\3E ||0~Ljm^t{):}M ;C_KZB?+khInl)VEMB_x7PH\`ynuy`+=8[ f9S!kg]|ߤcbů]HwȐ@m *dŌ|@!$/RrNu A"IeR-҉¸~vv1jS͌ Χo,'3n\%ӧlP'CV nx>7avӈ.P efqe/BI^ȞpPdULSA!yUKbS;-!^#:*7'oc`9M>og>l&=ּGiW!D0ah쳂 &UdtPZ~U&p}lZ"wSo g[㳟{N-;J /L E"_OyA9C 'ߛ}L0^kc/ʩd4 *b)rؾvcEH:GEtt$#6'3ZLs%i H&Ͷkv&0&_ Ѵym <0BaQVW53t'b}+ ⓣ:p3 (` 9_j? ۝I&6!6 qz&7WD^]Uz8ؓ;shcrK]eY)cL4~S]Á[sg8,҆x+~Єdy~d6Z܅nȧQUr`m,DD&c)7TKYkb(./i9ꣵs&ܭc. 6?5vY1;:9o .Q[k1A_yH[a\` (?#H88EVA$l3 Vee|cpkR]?/vq4WkA.O60겉 4lSϪ 4k%[vu|Ud78w' ON,ʅl^V/^':kh^GwRY(2%d.L!DB}s9SA9;WǶ?!uV|f6d2\{T +@~m3 2xt5Q{!K:>f1L<>Fހ`0d=gZ(9VY:=褮~U7:B o[7 ulGäEm ̰o?|鐹FTuH̓1 Sg]* k=}猛,>TFl)"݉)ç8kͲaZ+jI nA~ttُ&ݺqÂ2{읅LhKj^~Z)+ޝyO:llitCQ0hgŞ(pR/rЗ _Cw0:蚾[r7|*o9O0,0y43ƀ lFn D:`Ow<.S8xc0ðK'Gx:.'5xfv`$`vZɡo$$* Vt% Co݀J u?ՓKrk_Xnq%"rkzA¾cSu*_ ݝcXB{meE/$g3Ç^u|i=J%WT6Ļ-ː+m!KW~Zu' ݆fV@AsoUy-E~ |i2flW]M'YWy; OhCFեB[7WҞ.8DzHʪψok}$ylfUW <]-]SOH0E^p)p/^N˲c̗4 S`O suhVDDɧQ;] jc)ɬ~)Kա"1 ZoDSoԳ-ŋ=žeLQTuͷMnehR?/84Tv^ü3AۭtRPNCH6f"7j: p&j&jXoIS^:޸4Մ27_묏rz`_m̵08 @pi8Q:/ՍuwEmZtRs"!myq$9~ p^j~&lco$Ns!gg;el&I .I.R~1Ӳ.jOqQ%d8=O;yvUnW诚z.Pkv&L:O\~UZQ>])Ug\\~d*?SPU }_*}Z}c2a+"K7?2wSKD wr!W{Q%Ip*ƋĕH[HuIAXrXJ>}cD&3Ɯ|M1kaӴ:t< _quX?;uhg0_ce:'1fYt(5U[l]1[]=O;ai޶%+wuwP 0é.[/?rGRp J("x[5N՗|1fI90 *Q _!UdSy tynVǍTm|k 'OќT:?\hYuCjSqԒT9#N Ϙ ˺^<^:!狼>d)V|\}F%sGJԊHqgNǘ%SdyT>ҙ{N3cW4H>84?FH§z[Nx7F۟ $JծֹA<$06jX HB#nQr +fC)*o>}DLS86<,!wN-iS@e'C,5- mw&>^[+%M?`$f*}@Aa+M;HKZOӞoguAr%G_af޳uU.Gؔώgnh' sp*je &5f5P @(M@w2)hOa6-$OUpWm/?mz9Sn#>>ANMW'ռ%gYIT [A\GI:B45 R M| -@EȔU[f_D*a's 䵾$"͑v%Ңng,_C%wbTЏcKZ߈VT#k)ߦ\Xwuۧ^,@1FB^=/ Q; JhY[CUķ"ӛBM.ܺ~`hy<#3sw}*1&cz&n)mP+ J(mJgVOg C>MFh!RRm#P{+ܤ!:^MUb|<rOjZˇ ;z2i ! = S{jU}E[h t>zv^-{ Qf50td(wKlq(ueDn38Kc5 pQDA'")pdbs"na\x^/;-d&VxSa,f±*>wI[/UUARDֳf.w.DB?~6uSLL(Cٷ³PxD?F֬0kk܋>ɬagaѝa*r)B &TBcL%AV|GJ%0舤kf%8c-_@\ŷr0٘۷|teRut|?TH6^o)|F@KR.Dh1Ae+ߝj,.IkmG]u`b]֏j؅8tN;wR3;켨40#9~m-QuWfQ=)~yV/HTLsɣ2rndOѷ6mxAa %Aioζl_x&B/9o3;P.dV9^s6h/#Pˎ(Pti] ɣ832r,J(ױl p^!'0P@e-#6#tYO]= ý/# =H|fв5?Dkӵ׳]56VAe{ hD[y~EC%S۵ z篽"bPI(~g]q@  Te2 D/ Z],7ёt۪)r ~1+?ްb`g~& c؝<ߙ {sɚNm.&B- CǔGvX#Eu)c[';^Ʌ J pz(\s!TiNҵl\NiS-5Ĝ=6f+d՛}zu07OY떾@:ZU5 }.8[l?4t}}6t9j"`vMVsa o-|$JSǑ>V: עw ZZx(8V6+_AeMo1d؇͊qy8֚C0PleT ;2v6n&)QK#{Eˣ?j~iӶ=6iE,8[G4N4-Z~42#_{}(u!v;,/I tH(Xofۤgĺ󅽷g.L&%Ww]59FO%hy >5E NK.z)+|)L=4Q@J5W ;9/K8!^PpoJ"GyfF|Nz ѧv*?,t60jZQ82& !Ͼ= [>i~સD%:jW2 ɱxbKZgS_ѡ?ZCUm2Gx*VKH0EӲ0A Te&p2W#)mW*\&oА^~R2j3ĕ 7n|%٠'[)՜9ʰ&ׅnMeimm562 =,p Y\s\8@NjvW6mh/f3X(y059[s ?8G}VUoאu|`\6z<}2V;H*[jnzkOZbM/cBγ0ɺ1UO0'(Xdv9& "vl66z4(DڣX[To hVM=S@Y!v#:oX B{VHIbu&vl#C+<:=JoQ,l?}\9xC[#)H}hާF&sYO~1Qp4ZIAjL&IH5|C% Ú3>[R Zf,Mq<̕g9K_]qbHVP֌QELsD(  F3cŞس[ 7Uݶ% _ˬ!PsW#)XqycSsڗ'R{j#lg _%w̑E6&/E)UO)&Ӧs[ "ضTU^bhb7'@+\ƍ]>|A:C͍/d7Lxg牼cUh&WҎh`ӊ1 )!lB$S`>'ħwÖ8[*ױ-3j2W@mJ0ߜ-Rͱ&fr g zN=w^$,c57+¸h6! '-.`p8]՛[E;73[ɀ92*Y?:L3׌D8$XYF3J[8_|Ww >AA M?KS =-n"4 4v[n[ ݊{F}-wp|@X^w#TI+RmYޢ;Lx0QiB =d!eoFg(UDԄ|{.Yu]p@m<,R$7˛&v#OS&\{Aq-,iLIHV ;FZb̓EX7"48; h x6R`\GpRxxťD2rNVDB-Pj_n]H4ӘZڀ6US{]AF4Յb5sD@!;Ɖ[¿(64ewxD|״/-,CxjfpWX:\-NUEe~<}V,s."}2P7i)4ؘ"[%#Ʊ9F_Rlbr';DYG)7^0Yq[OeUU?- fpbxHV_9s9s-3dpy@0oLw0m/jji+f)J80L= (7:D[{u+G4:AI/v2ΆO\?Ld҅vϯz>M_9 /p/z`Z$8.' b7ꄈgX& Z0DS k7GZb mxk>'S#<暽jFU$]%Td7AKZ; 3̱8Fi %,d2)kTOzV`$QIX~4BH\䗾_x72s 6ᏃMhA4Bz/E? :$=%)73t(  9ɜL8FG\u @WQ9^ΊC-^XǐXJ`j~ȱߪױs%PlvU&0 *}bB;!CLZO܈e WgD9Jvy @Rÿ8%yj?Y7grY6 &ѱ?ؖ`V D_Al[ "B/ yPzj'YEdm*C9H}}9^ w}Wx#k; ~(^QhaHt~0AiXz𰝉"^rSk]IvQWQ8gl̯~hy$z=d ̗`(JI^jiVG~}(TT|jwVy%wdhà yH{x` ^U6erc[maJC2}dt-etV*⩸nA2䊀݂> 7 _HrTe ᐓy(#7G`#C[)ں֋JAa 2Oߗl!)%l5Gό1(aq7ݘjs ɲ Ƥ͙%? .Ci0{~ӱtm@e){9Tcc $" |hJQvB'~N"8CڜЕBiC\r5v@){yMTj)9Z[a Ij[(Q+8u'R)-r4;!%(NRJms h)P[p G|Qv^F,A)*ޟ8(-4^QVWWnF#'X4C)?w;fZZe1eWcU_YL56}1j''d/Il st7m+8D~2t hdŀm? iBVk&LAuwE뷝`xWQ>%bj\ []ٕO%Kwn DL;:l ۔c|59Xԥq;e2NM!6kq"͑+'.v~PBAO&s}Z(&w}ڃ? |J3TQ-EGF,eronp;KY[v w8`r3&`wMlwa6oBN ^T޿<)AK)?m4`{`  V&-CR 4Y쬋3p"Љ]#cc7YDwYs[$T1ŴyFeng&@x,(`?F^6qǶU2mB0HJַ֯X4f5X'?x{5YY_9U!ax7E~kx}UT0%%J֐P@ioMU7i;Ꮅ)?zaHw (ۋ.z/x"/mqnLJ "1'=C]^>I8N T5gM2w*a)FGa>e@Kd}_o[rz=I$Ơ+=iϦMgl+(hO40z11EoݩJl,VRx2Y\1]w#8SLlTRJ9[wϲ2/^]ЉWy4Yzkj}`ʨ؅8Hzǫ?6L}-SZ%CrV5 %)R%Q<_Uh+ֈjFFS ]PX\t0l5OSxnLV'@b.J;nDGd6렻8@qI3L4mhr9ЄύyT/N2kEit_|X3ntNt0e2#D> 3Kv=!S #",BXl=Q;Q\9QB,4cS 7(h= z67b-NNm_ŌwOڷ*(Ɋ|Yq.>*-~E 0/zƐ6V6MawT|O'efR7C'PwXn9XmSM4@kzmQ w.&+D@UTL t+s<_|"|_Jx1C&N _|dZ\3XbPwHDr ^F8?5>@ u}ENuNJR @B4UOPdr8(`d◵,>[#F+b)-dJE![.d ;xQl` jQ_}O}Ss“dn W *Fyk1>;raҺp#(6mxqA 33af:擱fETN~b6Eɔ<N8f<<{nb2J^nAck"X#nw%Ʀw}]@qh'P< "~]tb05+Fm {O,@9kٗX66|Y=#Qڻܜk٩,Ou;~r]TA LL_ Εf\˒$R,m+jylrLql+&<<U jۨ?LfEv/ R3EJ1;;=Q]<^]i4{˩*d-CHOCcBȽ9L-ΨSާ/;";.B hiV 0㊮FHk' '͔uP a#badhH2rWپCbewyu淦 1P  Ktѽݘ ]`"nJZC Q dPn,Cs$طHMQ+W*\qpé1ig&k5ê=VrX$u㘜;jkHǽf#7dв<ȷb{;#s !1\1n/KbQ`FaCw@ 51 Wpo s1DRTi^9"K6GM¶X#ꔗBYA:hg<-%`S>>%[^s _ȘRy8t[9)mH]'(bM0{DSϺ(_R7wZz5Yܥ/^a >ubxe ,Vj5d$S20j & SC>cFON)Sx4ެG~i_T͝/G^-eߵ i@8mh쓬^¿4O]gm31p:C#1@آ4-B%Ci%2l$H@[)A&Vx'rܣقOCXmKM 8^qz|7*Uղ^At5$ռնZ (|N̨5P8*b'JvƕF Q¥|) @O3gI|b4zg9LYDs% o]6 R,FKXS {NH2'dH2jG M鍤5I~1ɖ#; Pb,uO*גs] 0Vs(~$҉}55_ޝFbg,ڻVẓNx({r\)H`-[JKXy!;'G{<KKj`@.*Q*%g>+`E` n׾)E6|^r h;k&7-İx/Qj`rC~=%G26 P!8kca>8K0 B I*]Tu[gb(#C2`gor/J/sE榆Ti_XMil07-gb *ʼP֜% 0M\ps(*YO%'"=\ 8vHG>[ xJ7-Zx'5SVv6gIRΓ[͘jtXZۖ#5TJhd)0V_]XLB4:#ZNy7e5팄jQ]JKu@88BeX'Tym1Áy=UtZOȘԨY=+5ձ^ _ibBU(;.-Z] dk{^C^|\:OGj lI&ъj_i"fS/̍RWfm82XqXؓG&}$#BiLcqE@H|XWi^2;QB-?%+$71qZv8 b'à-Ul~ǸƼ٤8?19 +sA)WG=i!Ҥ ZYO$5{5Tu { yw?M/Xǩ`h9 2/IJ?յBOR5L.[u~i1>6 CJ&y|;f(z&vo]:P:Mp-(*Cbx A*`m3sHUR%I=_e{|FJ|վI4!k%@ A1;}tL]-M&IAFw*%3 ,Ríd)ېlC9'(/U)ƏWv0cԡe^eף!eW-ɦ\]@HE?j G^$Eg&Q^E%i#pP6TmIBel~Yw4fAKV_a9}83RۃD;n (ʟ糩ቐirQLf4,{?=۽Ω/N#"_ ů _b&]KgO#lNJa##/)X 彔< t}>zneisBG^nޜm _b AK8COR=@F?} ő421esX #91iQ|S]iJG+R_J_WD/eȊj>X6&Tw)T_O?-gY"nK|}\8@⸻ 2MJb5,<O? 㺓h앖G-9L3GӜ}r584O |h؛6RL/V $p#"̱U r9A-JebOO\V!/q [zvF!ˮǰl&7~d 2C`BpHp5j՚Z;6ixͯ-3ڼF|cBz/d.d[s8W&۽ ,i+# Z^lK7$:f {⡨%-JCZcxW6c}=.ej+ӗ4VlLCh<{a_N?yO!ת$rW~)fI;fXξXW·ri9U>~ wӨj^?],jY];lfb;g96N T UqY}3hUa AՏ̲8χy^D-bd[3xi!Ueofgx f>'O+ u=z(nXmڛ5t9T>J"NR fpGkE }] xpڷxe1oLGFǓ _JT !Dתy{|{np&wK0LJnt ބNrqBGi;[^4òqEPTc[k6ʊGE*Ȇ -4vx籏>!jFHٚ/E*R=0OhLr9(SܩHlC2@K[eAwJ}3 ;pZ0GGA fi pU I&+3/ sr6,hVJ#PӔo'[>C8tdme|7 g&/kc<68kw+㬕众V95Zn&5ґ߿;[ciA'sY)21|iEw0 ,k%X]/ s53|㮥Itc4ULwt"٪m#`Y b2 s.#K)y8$<uf[6g6fV\P|M;?jtu%zƶ(g. znF@p~?̽Y ;׌):@\ $^wY7zyHI#Nţx0R֨.d(EIGצF6.CA7l<+iHN c$*FcefX(1OPR۽IoF9J0qXoPk㤴3`*Ҿ8 ľQFYJ}.$(}H8Lei#V܍i0CDn<i]VjOAlbSKhOex[t+۹h-,OMg]I#]"Vպ @n:v:9ES(wưVP|=^81+M 2OMZ\I/<NeS5D3ܡy^oݻ%'o򞛰\2gF8Q[AD)$@锁94%_ix0{a 98DG4VW\dMYKnSfVIBT OX,yJ]&ti;)'Hm'3lq%o%+D.ȟƠ:ZLJw6uJ&G۴[@ü;<Yi6W -h]LQQ~Hm@?jTDW1ArUG/=]uݦ$y^\(x*s Jn+3kSɃ c9[–X'* .Edf0n_pDXhS7 +'sD ab>,z L zB+4ɶ,hr#*"yaLtRtz21SZ{od${)3T4eE[= o7<2WW6┌GW(}UkYj\q8=d5M!Oj4lZz)_\L*ZY.(x#[0fuOD1M(uqؗ$<4l,ݴG&\AP{I=ԏ0f1b1$+E)-2!TCƴ`XeNbvq#7[ps 3#Ls>!Ҡ1r_8 0abȀ.ŭAo˛I]З x%d7v{^ KPatٞWެ*Fxba\Qs\;ykhd ^y+4/}z6V-Q[+JAI:aqF%Tlg79ý|?pgە@:TЮgIo &U_]zq>9;PUlP< )QVJ~:nsgA%!+mɤDJ%_¢l]e5UR7GsG+<9;,P"vJ㦜fDcl%\ཨm5܋6XF9$gఆ2U m\並4RݧZK4s8-r\*K 8CUf^s׉Mq:0UsKلO ivހ-vt?Č0QUk|sӠˆM &(@(|ԷbĪ kKZH¨IUqMD&&D^_rpPP:y,a\݀̃JPzlrBQ, p0iDZ[1'FSUNNT˒gK)dlHPg{L#IzMLUf6v?0!:h|~np~J 5e-`V"(nMq?M+4MgVbLA[7eqC u Q6ԒF P5t@<]_Nd)PRa/z{DG@f=uݤ. BnZ@ w~!' endstream endobj 72 0 obj << /Length1 1882 /Length2 22538 /Length3 0 /Length 23754 /Filter /FlateDecode >> stream xڴeT[5wB[Npwwsn> FQ5g60JtFVtLiEkK}+&:E\`fm%p8 >r?"`b@+݇` :+yk{:}7 H"lmjgfb ݟJf}+#$ =@hM-e:@EITQ ("DEQX+)DeE@UZ@&Y>eD5E< 7Q|0G_ 6 &v&6S658[ۙ>he1NS @heo(?>KcjZ_K}3+G=@/ ho@ݟ2roQx2m wO}>1}+G{?@{?gffMFPV⫨2d?cEWz"NF6CVF֖aOcNv WVV90X:%D'o . ?f?AxX-쁞f7Xw{}' O"X&Ç?VLPT{jdme 02Z;|HM^_-,d-goifÖRR|f_\FfoL,IJY|h1s}٘!KCs+=4 0Hɨ~R+Nзwe3CF@`vH8:x`(' A/`70/b@/ #Q``0(gߐFL?~Td08~Jv@53Dw3sb׿>G/?]X?T`ba`ߋmR\J h`m=1K4o_]2b9m[${%߷'"ZZ[+תP<m%bHA`WK QTp4K^/]fɧX2+Wu&52z"1y&Du-ҹ` e oi=:BGpzV/7sTMOdU 99=q)ڮ/cw:v2rӕ:y$ן(dkd YLl0c nNKX2N&,IXSTkѷMtK :*dZ^I&L~jg 5r˃鉛j-gEhy#: DEh>M8@\H`Y-ZQE[#W 3^xFxØi{eR3n6HX=7SV^F'x#IpJ ~pr`Kgg'1ߦ%u`˜9ST b\@33/5ssF:!w`H2M: m@7/k3?zj.yOlx.IbEjt?_SҍFʜsDЊ-q?d>=4uuĕZC:}_cxAmG 8HVHӨ!֬*`Ш^(SCsxqF<+$Fp@0z ]$~etL!vayE9ixDsDk ) %X۪S+?~Y п"3cTQS' ޒuUN9"8"o#X UNKR.rɝZ܍j@-9C%=l+v&p ^U #U&lyV"ZE3<5͠zFRw!@[;c4W=8ISy}gYߢ|҇qd .p;ͦ %^Ln]`đzӴwJlZ̧ yނ FT-"-^Ey2[Iv*J/p~GA{[ЍkT[[[]'|s\Bh6If ;נ%a`2ZO NLBmgUq/3'n۩.5 h"/ 6G<: ;Ud45uJ ,'gq]EHyI;89lV5:1;Zfb1 ܧ_ÿJWR\&zWlFu۲d VxKzgz3ũVkbTQzo X! o9;Zt`U#vç; s-K=~QgT~,D0w-J}"48 X0_1=z%)֬lzI' %U%i%$O|?>5?#}tb(ڒKSSVaҸmy4ZzD 2xmB~0}5jxQnmu؟2S-t]PLWnc4`}2YؼJ'ohiк KU|#xxJ1CHs,ٞzi[UܬcƳYч׭6omz҉lPM../ rvAT:vV_'Nc`a98֬Tc&Ԇfqi'@',1~=R')6Q,g5_ c\GXX1~DR~oֲD|c3"Fw4[p?f; 8S{k[#SQUTΕq.RJd6Qƻ`C ۺuEhn:q[eGr;SNj3/X`$<lYdFu<ה˚q6]n}4s}gee(yټ}LCzkwG ܇1'wsjFNKe1gc ~2ke^qCzwxE%q> UjCMl~潍EGoe@Y3mSU{Mٮ2M#Yf?#ejL1=pD!oAoTD!΁Z)aj_Lyv4Sb 7*f`!(OU;Hh-Ob=$wjl\o`, Q#ΦU.FJU$ĸ+>ݟj]ACXx'3"T\Դ;*6U06"<&zj8)[>5x$`Wrk7J< n#̯_۠jUF8W654MeFͅ PK#w!J,5Ĭj2˞fB8RmDFH;[HJ}!L_tB:Nx_Rc4˖dkMYYHktSyc=~rJ8DX\0D4ŌY*F\Xc5c4ezo'#K~||:l%S 5 ;hBP.\u,(2'?U* ^o't l2eh^Z#ƣRfXė1=>ذ;x yGȗ }Xi%GFIc4Sn@ I4"Lӗ}U" sgf8spNiuPVWa6xe@^xp#jZgWYB z$} tc ,&`)Sv?oPsɖ&ͪZ])w w oCqdbgDNB,G1̄⣨8xZ <憐-rC0hgrDnOeߺWQDPNZ@wٴpsV{ZeC~rD?* nuB T|g`a&Uh9v/c?IrP[UY_POwW?%],3Z}c9r+tl'Q$YskeS iz!.3^  .k_=K<Vf*gX#9rFLsi5XG?l΋8lM.dG99k|3Uۆ=7Ww%YpO][̺{-JfW#y%:Id{74 u/pȃ@tL֒81er''e~^nWQQS{*IRBi׺"@e}[9&!Y zyNd(Iy pkU.3"ɷjYTK_/"=9?EE1$WRU4IdP u3cTzT:Jϸ ri?thoz\Dr+6)-ZTC6] &'Ɍkݝm_6P+Ϡ($*wǛ]=j猎Q䣀F<-q-J(:OSX43-׵pi>iɏDF('p8jZ.ͺ.Xf֣Aޙ(nlmWTz/V/Rآ)饑>otI ydXޫķ4 ǶqXЃ j't,e'oGc&h 9)or6J胫} F/y]fX:eu&J~29]wشJ|l~kCUŭ@[W=X>:wؚbvY^[e@͆&Bvfg W)N+/E&&bs-9Y3wBƍ'kqSi4Q"R8δ^mcCJΒbL{ϣ!L| BMӒ6Ϯ1Nߩ_i[/[H;~CqS ¨. o\ m>)ybO)-`7˛+!C!m'Y\Z t(6kVYf콃 5_|\y-+D* CZu9*m!K5O.ۛgn5<^>WKC˄X(Vg3KR8Q?mɟ +Ғ Li}(”: WDT&)ra_P|H3K0%{뼸7TZկ1rhM͖ –Rs^`/)I H!{`5W2U-73m^ojC'P ɩ#sI/9 &í&6]En 1GVU9.$̎Fxz])85Y<)$B3nt/qxe2%,\GhŞmj7qbAHJ$-.Wg!ZO]ҹ< hYD?ƇK&rݘ^dYm)N9T]9U|oE~XBOp/YJi\.G!P Th|J[R M<5uR37,\GJT8},le$pB^|<H/J:DK$;}|~\pZ,[5.}(EKThUjt@h= >dv1PF:ffW ';:k\=~B7m6]Izљ6J286Uy0)NR^C7 !s0N{tAx"fp΃OgwcRsK=R}aTQcgҤSSgbVgooV,PH՗/H7@(rf`ꩉxLگ[ _bSz?Pes Ju>e$x~~AIܭ6֫׫TV3,ctK9:wz9X\U!mLҏ&8/_y} lg42@;X}|IbMP۲w8àUPs/įǕ5@WO5mЙKMQ^QT&U+vH!3ٷW~$lA ;6SH(Hb%UУ}\eņ/{{s< I$dqƒ!VJ\7Nͩ:"C -OCgB)9w#B0'0Y=Z0}( Xbj-mP*Ut`C"r*S22~7vĄO$ A!飆(6۪o1;My)F""tekRpؓJ8,l=pUFSdZsžV!@ R+O8ݕ(]cHS4!/*Aoh@ p>kuu6s|.GGge;+Щ^=@4,1o\u&^hWN_#q}a4(+wX=Em>8.z+؄N[Wɠk/zJWzQѯBZ~ 5`9 мU"sfyik#O4*#(2F1u'>7jT"䜐 nt-(TSOgFJecn L:3.$ ƥHr;St}'U6d$|N2'Qn5s UyQR (l"w,!oc#VeeYoCFӍ}ۀĸu?\8[ S$vu "N%XBnqVнH4ASRdGx-pT_%Dۗދ߫F!%:Oc((I-.Jڟ51nJBBrwz Wa/+g{FEdXu(Q,YmhυʗHT0/ )R0M9*AŒɸ7vb0EKCv;$d @Nl nZSE=6i@$}v[Hġ2Z>3yLeqV8 ,&٦#oMcY\Fp+5XKH ore }z[Am#WDVAq!_sQTE }(:I n d@ ějq TNxf1i*:̇UB{*#(ss?g'gˤ9 < =V4g)Rtw1<:`cUfΡȏڹoh_D+t}D:S΋j>X9GOH2KK<4'}IMtEgY }1FVbE;ұw+.AK&W-Za$S#;OԉЫc#E" hn3]: (ڤ4QfpKz܃4U2a`l"V>eV1Y]#^ڇsQsf6wKB$];֒u5cA Zfiu MP9b8S)5Q -GxSCE#sQ+qj#w12S=\C0 L92/&h#2dAU6GnQ2+*SӦgtmYBCA!Se >ߵNP擟t6<~?K+ͽ:xD⟍ZU_^\a&=c,m/v4JܙEJЮ=ATi !Jv*yƇFԢ[:?[PE;_[ګrXbj=1 Uu>Δ?Q <`JiHJs-=`ⷭS lD rF\`C+mrb}:am+}V%9Ҵ6chہ}%gikp=(q=)(Q8$_*r}>R'^5}=>/Р׳]FΝ;SFG4r[N.xҰmj@,ƺ0ox/BMy68FX,&DM2EV笲zN|E꩔GRcbE+wbk%ɬ}iAyiwiS6*8=Ll4BDg^D F3FrZz` yLba# u 3.iC{ vy& \"i:HdNTTAG 抁cթٷS;zdudmҫ(8_bAhnJ5C[wVr\4tPF939sj = _E?bɩ^co7L:qINB iq!7Q6ePѰ,r(NK Тr2+C;*!M₋Vg׌P(Q&4w$zvX2kx4΅-Y_aT6wO4l(8)a/ m؋2y yӨw%%#8{CKBLyuںmk([A Uu r(caG[=ũ}6͗Q%Y>Fy5ٯ`g0F;ak,jP6iEp,Qk[_H\l 0#!Nfw$հm=w2}$U|y* }ڝ+ |D,a\'^3f7AMyѪ/@gMSj$Ma`QKHa7_&Sƒd@ל=Y꭛ ݑEr$ng2Fqy7ኑҟla<;+hR1JӍMҜt0@x3P dԹUz Z]t-Tug0bg41vƿ7%qGjxgS NM]l6Z]07$,TƄiqxbƟ8,beΐxGJTlsH7[^C Fĉ.Ɓ1)= wRDc_ $= HălaƜK}{+2ubq-I>Â;* d 䩘|WgD$q7촁}v>3e,N =LfGZ63݁r.Y:^bBDs=ֶp~a=C}X 6SMgӼBpWYD1 RvٚYd*+tٯ#h ?M`mWe <#sսaH)ˈz;Ѷ<,|Dc xUwuzp݌i"ɺjگ6Tz!8)}(iX~,0lpSݛyKd+Hun}a.AFz/<Q%z%M 2d~̊okX K2M3 qnR_WHB̠͢Y,KugK!~TfIFM_룐=o;sw?fLabo8LZLu2 qD+9j/iʗ]hNp欖z&ޫqؙY{!3)ʜ¤t^~âa݆Q74g7큋ܷN-߂99"b uY-Sp.>+5ռ$K4A sd,@T;MX2gߧOS#E2BXm?V8+JN#37&Щ,A}3K12Dǀrp@]&NN=+ж.5= A^xEd=_pQׯtYQlo3 )[5cs pKlIۨki@eRe(hR1k奌v>< l]nTm4Cǥ j1\M W6,8TH?%Pxwt#|7̸a7:#vW!e6!ρlU.{V#@JAruh#,!> Wݗ gFo$'ה(%Wu^<E!'-P[-ѷif[2tOh1@ݞ~*[v3\`ՃnL9Q_U^.?hWy= e|NT~NQj4 hJbxT 1sh?xVq2f#W֢sL*T|ftk.*/eP#ßWE6(q*A/:+528]zI"gF\ ^ȁ5R\c-L߇\d9 SC?_Vxշ]#!>kɬ5,VbF_)Iq%NPZŨa圕ĩ lG7%]W(K+0dz-ćP>8(@t*zH/2 h%L-M7\5>j*'0qD&5'0'*/#\&,G`)Їȏ?tw|I"ٷQ$۵"?VDj삛 ti E= Vcڽ:{~\;%ٴm}sWNϊڝ"#T7b`?p!9nW!ߐߏU r'A=}Ru]NW?`:wZ$Byʫw{p9wڵF$i6lɣFTSA:0&m:e5y$:]i~bՋXZz=x<^C䵶l˪; jhZ#b&O>4 :@7wԹ\?cF̔eO Efж:򾌍~R:+yq U~L+K2 f*Ju~r.?|/'vMM֢[kP4 Dž/S $X$PbmskǛ|Ǹwof2{A%q|+T~M^I]U"DL:Piߍn9 )[ov6A']0X9 l-[Shj &oښlg -AW0*{>ԥU3= YխުY|"7#n>%O\7mxY]U".Ƀ>|h3]3uXHqz'ȜmHW7(BZTT(ti87A<}sT.$(7uh4sbS:y5#TqMCbhȢZJB0=XpAS\6oV'BndU#"g!rNfEFaw6k(R5 B@M&|mWY*"eu_ԹQC{Лn##חZX!vkH~+ar;\[oW{xV[oeяwo1(x2t9`oq"6Yj-WQŘRsLҽǕ# :ܕjFs_+xՏ)ja{~PABA;Z7{ 9a+(bG~:3TK-nь RWrXO?:GAHnt_tb@fD^_XYa(F~OaIeYnU򌠦%I(SW62H>*GF4Aྒྷ]#K`%75y 4ZGLRapeR7hkw~+zG˸inGDA>N+4y@nA% L8YSꂬjAh@?㖠(ׄ1y9-,'g?U}.V7B5^E VyǘފyHw<m zUΜ*EHnR#c}]g ÈWڐ6*'ݲ*K4 ;sIq ھI RTo;vg;eXܔ6J8|M9wixb;ju$;4z~X2۵xf9zM)Lѻ5eHo`1 Rf"kIOGDqe}=9~e\]Xzc ܹSl!ŪӹN]\+Yn!5G*P4aAH% )/L@Uzo:Gqe`y#]PArmϒµDtGCx??YWoOD,eޫ&0ʧiˁ!^/-?WBÜ>ư@x糗Kbusk3n/jr$6ţw?FGr`fs690mV'$Wr!8qaaSjD(,섍um[Vt{(TȾڹ1+ u[ncizȑȲag@KvsΎ:]Y5g3\vζ`JB9 aJ?]ޛVfIܗ2Pѽxb9p^{$Bb 9^sj$!yuϏR!!9P[ 專L7 \GH1+_fL' [ g6R+ȶ+ u!{`W2H>%5v$4}J"WbnBW:-6Џepv'?GzTNSpxmLfcOVwoR_z4 p݄ d'ThȋG^@r! $n7[*Kv:lԦ+ fwC7`yqkpL?Rjx6tQP6.q p^! xF!%/Qxԗ|o{L_cÅN.ȿ9Lmj{_ߺ H =gs^Ǝ5 C L Gް &wwB= yruu0zRV0cdlou]p^+޲̿c˜`*Z(xR؍RU ;R]qDJy]Lu ].TҔv!n|nsR@Pldo&z* {IePgg'ޭ,ǖ}J{W\HLqqOe/ͼAw&Mmq"߭ : cӐg@fۭ<kـڲ۸C7$btS߉Pq-@4eGX:.%7IJ`ZrNuL2ҽ>' C'M Drt. ЛC x"u;|Xb>stBp {G/(bm8^g$ 8P^ӿlHxs_d?"~'8V:Q2ezvjk|8Q)q6 /f/uLG7q^^Lup(moS"om.n|nsPzB;@k'AݡR'XPM ѪÛIBW\NZHn}G#PLtmkL (H'2B>"Eϒ֍ghЌB|Worr6hon_7~l4mXID*GjQg@Y{ GHIQp.eO{;OM(SM /80$V<gs]fh\Ɍ~V"e }u`3)=ِiWMTʹn$k t;LPoOJZ7e*c'uj[z% ɋ-9Ck qQb^c)n2^,1{/5qV; 6N)aQamt_EG09@uBoz2PfHb`7a7,.^8--Rx-ʧөX BQ GHBCFQYhvbN^*rRKĔ 0Yk Nkt v~jڇ 8j ¶XXwc5+,IYxr+GGhBH,. b6u`dPlnܓgF^D w/I`D3M"+#bFVDZzVM&Ij] z+Aڊjmg!=HuD!DKU.tAU,0^IuSSQjh$X Ȍ^îy .jŤzLae3y<:eTx oAktݍ 獘թ)$(6綒onHcǧ\)CxM[|8c~-Mɴ D捩J4%b_rMIדNP[shda-јHBR8Ic9N L]%gĊAc fWP&haF=@fAѫ/x]Bg. {tZ%]dX'~W鑛]wSlOuOYqٗ,e\VX+glv誗&.5`r'C+llq&i\$N!n?B>+}]FѤ? @݄SʵCKqJ:$I൚a?C<15 i,>wnK} soyi)mTMOIxg~o`0]0R " X?SS-)#?l{|1{mJb-4,K"d1Vble'~*.i{E'ډ/,pcC2pTj[x˴l.H]|$(r. fXfT8"U4)0QJb+0:IK2]<~u +&@'}?N7;0Vӌh66_,wWY$JfF1  MY|X,R3`]F:'OQ%CR0f{ NiRC3604 i $'Z73'jqA7RxSq5ۺ@z@\x5k&9}Q+ȍ+Rx'nu0L3k'{t*1W듢8u?fp["f8-u:pڢ]rF#\0cWN`O&pAe XeWXi|5ۖEazNF(Qj{n(xy-duǔ0hAEgPL1v\|wd1r8qͯzvym!r8Ee?“7 ӎi1 ?I*8*87aIC`~i9L1J!^fUbW,"h7o?W^#h-` m\ATc[ }6rjt'_Twjmg2|EfGD R=;?k!yϼp32=-B-fɈ\\x=ɛǣ.3-v4@<0`>_<ӧf2I}◬1 Wۄ<_ͪ@ɥb;|zViʶVR"I00ezaA/r:[ #X}[m}J7NW*B Χ$Ȼe <22{h*K+sER, @+r>.[ 3n7MM1^ܓA/=Ubɕ%(P+QZL !(1UcYr苵 Eqmzn uz66ˆcB'Nd.B"c׳S (.BC*G?1 !.Jt9TY}JC~^3w*kӫO(䙵_PkK6MNuPD*QRQ( . WL .7z(P (:oo8l1SU>9.j hV㑣2.W#< T'd 51v`jfvOOl-ŹB9*d O6UmȡGNF9%`N[0Y YN)f`>PHbI9Bx1N@aTz[PБZt0Sf,~˻cʊxfU/a_دt|QFoDE[kYy^yH;͚匹cri CX%>k$̔~70&Pl!3_U<pہ3xrp*ǛfHl@aY!35t`i.\Α4 \|pK68bA|HX!Q1 4Q3x˼0P>a ߰VFW*w6 0¬[Q{O4.Ѐz1[֔ gҎU,/̂zT[Btcrw]JW=2A]{ٖ"9ɠ/9IGlώHȇGN+a3G ?+,sGI ] 借\9 S^23YOLm)EI-{Vzokד٩<]kB3Җg m1'61:Sn}e[ }돘ڨ_=^~?/C`Z8ws6˛&v#O>b^a;j/dΡ DLBjؾP;ٓꏪrwoeM , R t)`ɿ@ RiAZV8"Z+_=Dfqk-mr"x<=-&/d~sr^>;c$&Ku`󰚸0nozljI X!H>tT 󽪎ۯ,L,eSτڀR&.GT h5XcFUSvȢ8yTUr>E2Bt+= kiGv 1vG%?DCFߠeU>i?Vf-YtHhxNКį)_hK}Y&kbEd$"Vˡ^ZzL#zJ i:40 {>g巖ifNsInwSKVh6saZк@r텱'r穭Zc0Ei/V;H*7Bjv9N|KRoc#:+RbpP?R4jT7{ o>%xT3i׈йC-D2!(aN ^5-쯜5,GE$L6ʉMkEs'@aD"twX$u)Vq˖X 3d0:Nklύ["c>ak -ħcL%oqΫ"ܫiPQ۠Hhg'y +hMAƙIŮ. 6I.qxkQsUF"Wل-u ~o>ydum,~gOx#݊ hw^Qn<z Pl_4H{ endstream endobj 74 0 obj << /Length1 1863 /Length2 12911 /Length3 0 /Length 14126 /Filter /FlateDecode >> stream xڵweX[[mq $@p(Bq ]-RPs^~'O3ǴkeB]E( vg`e(h:;Y98Y-AVNVvvnd) p jV';2 @B^K BPwvsgp{u 05EsSO?ْE +g/7l PdUa:{ 3` p8-M-ka-g?Hii1%Te@]fOm -3@Uktm mu?x!n?m+3@jswwdcbpsguز8Or8^#x_nE(`7$Y翝N|MzEuj:p_' [[{^@k Rȟ*tA%_/W۶r؀ػY3/LEBUAVFKEUx`YݽSOBZY Tl- Asrw];~mLÅM r*H#B7f t۟v~C ^,<w0?m!sAVB,UW8_ Q^w3` AfSuv}?d=U-;p9wWu8Y8& Zܭ߽$@ 7+;/?Ug߫4@777_.8 `Sԑf?+Lll 8yx2 8yx~ڶz+5q YU>n//Kfof/ fz?Jv2y^-; ?"^16#㕊\ƻ{9G+AgVBd0mG_;~ wۈULͿ7dKJ:{ps X8\<9y+S]  B^^p l )`=WL]~?IL ]E +yC[,/h\OޖV;ui!mH.#1˪\@1Ƞ[N{r;@g엔@g]< yqUj!WG {-QtNbE2yQޘ"nS;,\DB7"؄qbMIH" V:%?`ŹmE&vmT$p8MOˁ9~#X3еS"vJB5Az}o}KhW*=G*^`2 lk80=ݨFe6îю! xk١ZO4dڹ0{:?۟.[ӎcft+ĹYViP>@N> zjr 8VH=a|%w~;U>Tg ug:h5r#e, &zbLCyBR W[I5sun t8{|_5q??3 IuD#t >;@/-@4T4:[)14 +v,03Nc{ܥB=|.P.3uwBHLw;+.qIwLDi8Gh[ڮN{iS//.,,B NMę##32|ٹ6i^toUg<)6QnM0- "6> ؎Fy !B ijWr]*ioQ'nLSP&[R4oH`^ޫٟF bQTHz-u4MpWSCO*LɇGr?-:bHC[C&Ef D]`P$vR08W~;DZe 1#VMB7y孺1IڙѝK%ǔe5lO<_cg} ^Kbm:y)sъP]un7:荶ew9 S5,% `)⌠r-ӁrqS7VAJnqH~[As6lDM"LUier !s'TnwA?+w UEmWIsU?0xƼ]I!x8n8)C6W8ΞfaA\/ b+sE4*3m}7L5Q>t {XPj˧2XX '(#b9SijMڻQ14a[s|!<";sAتPQjŻ^FX#A jwG9Yೖ5)~>oIwI4NV#R7Y|!5&Ba9ٝ+Ls(E|acb 4V_Bcb*u  /7h" %!e!)utz~:6<HTO MSjk0#U:BlXv|\p+;;tkE%fJ9wk47 Bkפ>7Tq:dl!p+ 8]*xB<k60?~:9rpo#gU~m.v#rx,%fA =R 4]~8 tIQYAc  䅾7 >X48 G.~Bk^p[ӹ>ºʴSUͤ8#}k9kDaFpAaso- (R%H/j1FIC|?LwW>l"ߞPڼ-XMm/"-gYP@EMj8ST 9$|4Lw2@C Q{S~!9?jOMQ!g=B6SRdO%Afi056$4ۼj@Os3 aIu >byb'K!/ BzF䝄SVɑhd@ñtv|x#LYl *]7GO׆ j9a2v@a!n2Y _ UccUZJ.8+]J2Y(ӆH qr27'ݽO.s,5- ~͓o>[9:g+mt cJBm X@dtN'vP(i,gxH>0;An[-|rOTN1,,6"?Mqe]V ώM.Kj,RS:Lpep?Hsyt;QޑÉ283~nR( n\cs7zV.39*4ǂU}PGE Tt9 lL484~Ů4 iD( h/M"Kݣx`RPN| Amv<)̖ʛv n~}6f~NKv{bD UhZe[+]XeAIeYִw֞xڹIN UԌW˾ \߸Xw6kP b*L7"~4OPHw.c$A_V\TyJDxHB}jew nѻk_@z4 f7{wh1SX]|؟-.aċqG=<@őWPM9Py4Iu,buD,Œr}\PcjQO/ƯнY=0F >ǺsFo C"e~X~!%=^.~rwyz[@L8n5_a/-=04]Saj=9}tGyV,=d{ؠvǑa6u9k02Z=]h>(!ᝠB<OT E:D4~L;O>7ad7UgvB˟b})B=X狿r'B rGc;K+ 0>9MNR }GCT9z"UlU@OadI ?6߄ s t@c7ΊY;n$֟l7|*e=/rȳb֜,+3S)߸5c P9qoo>s^@(:**;WZ.r,8MLvyh0 iכֿ@oMLڻI Ji 1zG7FH" M)vQ9Fv:J.h5·3.=Pe H2Ǵ]d$ޒD' jBeE}6^øDhk:e$I@;g|h@B+<.T/[yfg;9pӄ1m Ew*cPVo)c$_[ =|1(-\E=+_xD)x*^I"t0zOch]vQ\I渽^)?l”ͮ;* N6Mfk2.ZzSVLLJ!zɆ3'LkM&*is8z}=vJW"g}rV֘oui禡}^=QCAװ)P#O'm݃n]\d@ ȏ2""ߨO clթ2u%C09O=T6^6̓/MQ]l Ǥq,6En)o4$#̄Zw˲x(cfSri`vq]-ИJ1"^K+ԓW?w @J,⮬r/!}]li{d >|GA LT4Xl h1u7jT'x}^!bNB6-MT7o @?XSmO=@!؛r+]ճ.N4Ë"~#@/!݉^[w-3=a|TxWPnc2SbWE uA5 +ΰFa-5[b/C O=8忑 I,lp~3!yXW5껏0Il8|?%A%&wB%T>1;hxI1йz~txC YWC\? mRiꂞؕቝ?/,qNг{0<;ݦ_`bGjoBHބΆ $فCޗc']'# zG~||L j@ TR 7ȃH@*I($jWNfgbV]= l?Ɩ1?v}Ƌ_)wvS-訫t$"kc> ;ti* ՄsH&Y$zeʁDNG"r+=?s8pZvX"Tf rׅroR4%ͷ+k`ͥpz>{wzt7jn>j/]jznOGgɏq@5s`ɢ&v 7tx2i?7߬ *CDԧOΧO5=Ԭd.ONԉ\D.ƛwņo>ZX=N>&.S{h`}Y}%+u&n+v^)0q`\z2Qd<D2ꄭ]ޒѶ*0'B{rf$(bۺsp]Q/D.#(!11 nK6:Mʘ"^]JR rHDsO#mZEǻwv?!v&f sdQEaAִ$B~|:M."R\@[Tzjz9:C@eQl|>j8G$cdoWihh*zҥmӏxlmm ⨲>fs$o@3(??,E%ŇPo:xA%?txNQl/WCux~Ƈ]iZ{܄\mF $(;/fjt2qWQ,zԯb\Ǡ5DOm˱9E٩º"NQ!GiyIDX[&3ls2']۪. hq3/>vSp̩X͇=i4<&6;SOoh"Y24ƴOE-e+8H7" B >b|\Cȗ ֊@:g[d;8AjόU8s^V,T6#^zu9O=Ɔ3e}RH gؗ{~f7>q?B2l&QE+CO\Go]OIjO<Iju/jT*XoؙyLeֺv8aլ L!Dꚮ[+;R3X1hqB~)2UB]U>aZ_\&-@%J>BQetܸ"j Z31 ^&W@+kTU! _j R]`X8\\oVkvA30QiwxWA}803­7sRIB>L+}67wrq +S~E\ix,|,w+N9j]@QCE,(D[]>3 >Fu܅%$.TIWP`o2[݋uLY1(< [qPo>g|\ekB/t]5Y^-e3;k Lys %mc{37'} |9,hkS[`OUvtԅ%eGfCJw[az+r5idˏ|cb)9 +)^Еt֑1v%&zZK2>3BKml^&ȉ`01B˟ϩ~N/+,5NV]@o,dXD~t߼G |ቬ o\:p)3og꒴+`!/YCoDW%'ybjxE<МW ~x *Aa懂3/o]f'KkaްB4-6|2|OI=3WBt}ȵ mȷ԰D<|&#u{!7׬R-l/K!g 1uaQyfX':]&k4р%.5r1D&dyA]MZfEtH3 fq-[ZI`OK7Zs Oޟ=VO4Wڿ4|nGCوt$!u!۱1DwDDD"wD lcph>CE':8A΀|BܽǍn-nFz R?Mṭ~Bfw8*2XדtsT7 >љPuR3-]G5F12az=rע'賈 sh6_C?Y_(p/vɩlIuK3NA 3+-W b\*S]'%׺cd[)ƅٳ dT JxךM|JoWVPFž/oy>7$rxHO;՗)[HWsV-x'HOǯ-ح&>g:a;oFy-NdrN3w qf=͵k{OAM/-չLT8ɥ|4!esvzS_cB)amVצghM`tI,ro-1UYn4Gd(F0&llNm<8|V0eG=Jz0G$jgq0 9Uw~4DV֞v|[1D$n2nelֶK*|~9-&px8;]QoP`>Kxhۮ 9qM),^FH=)6!5%!Ơ<}gI]7<3[C 4rY\H8B~̡iby-|[L#b.)01)NVΉl:Tx:t]Qa^Ζ6 *M3\F=uiFTf_WDh3Q>%rla0u |kɗyqUJ;F%gSק5St](2j hicJ*ݗ`I4C1pH/&Gy` endstream endobj 76 0 obj << /Length1 1941 /Length2 23898 /Length3 0 /Length 25076 /Filter /FlateDecode >> stream xڴuP۲>k epwwwwwww' N`!;>ܳ_MͼjyVU5Jf&@ {=3@N^AD/`k`a`bbC 'uŌA@3 79@ht~L<@#@ePrpћ/-&V Vz?X0dMm]lfy @`0Zۚj@-*@REQ]IݱpUUS +tIuU?j@{@A}Ow?jjJ̌`]7wfP{75wv+radtwwgpu188[08Olx:m% YiL.?FZ{Oѻ_ Xe+$3MA W_7Ќ_QWg?1aM]}gz޾<1c{W濷m`brG ˟3K&/ -!F/^rٱgyOXL`a0;k?zٓmcn[ٛɻ#+PZEYA& 0dZ#f#~O#ke| x gW!0s̬LAe*y7wpKKST5({w9z̀ rKVHS!KX[HXy͔@%_bi{ [ߏ/V}cg`9X^6@_K${0*kj`7u0s=ޫ^f@`z78|G/`T_ `40qM131wFwǶ]9 ; r|7` o?zk:8;;;@z )[5%_X`Դ2Y]ElQ׿W Y8xxӳY߳NVn25hߋ\@S9SưR?2hrnZ2Pmxb9[$@ 9)}@"-Ok-IfB~~x A e$ԇ2ylSߢm,co)$ze+3Mζh q&AoQ?i0e`;?Цi/kv *WXŋn\v/)BLx_u)Oy>E5)WnspLzN9T[6B,>tX]4UHS,^fs fvWj`%EbnfQ7^{HgDz9x5YM>/_~t_S`s3:Jk~x\28V K"Bd:M >NwL_^.] 8xm,oyUX&syAb1aVWno{\2,;8؄+bCDpBQ@F-mPT=c%9|.#C].&W|}O,h{BפYbB\Yd/NuSHqA"܍I=AS57A;L콥+ɤp*.`Ŧj?~i;DTSIEqg{ڬQф![.QϤ#yt+vxP`?ֆ!tpD٬:yb, V5J U+7bMsT$T- kxt.n_'+@)S%bW J-(oh&0WjF5lK&gx̚Px}% iC=-6iJJ b>x!fXij)"3!Z]*ؔt&3%0y2˥1]Ys7"opH KOr<"z)\++98~ ?1p6SlnbuEΑ[Su1hekW;ݻ?Q(/sHFb<*BKAzif>KsF6f&b=sV KVX^8affVe& >yުwqA Җf;G *uH%F]و IKm;̶42FHHM=O؊t5[W8q]ոԩ][/[ G!gHLP"Rݿ)%R$m;Q=Lz$`W̟,~?c|P}ق=Ƕz /c/: iL#if@tg)>UU@F=JCtnڌ`%ʵLҲH0wKFS: xK!$e#Dxldcݑ#lO;C'6sj!ιTQ >4e`췆y{} u_gcE;ְUa^XujxU}x 5zK4Ms-yV$ ĉԧer-fW^5&dE;,n%2n=2D ،9^@Ε]?}ڢwƽڎE8ᆄ!$ c۶Ff&*݁WzBBV_b{glymuB68>V.Og+@i""ǯϪί_6=G8H*`)r)3V78$?+M?xmWۢ"d| -|TQk95#hdg/mSW:#sk-.d hUF}o$|QQِ[*l$b画`ʦgpA_NSY==wMY8ҪI#vNmb,.66~(_ЂtJfϛ %#Ϙx~`)q졼A8]O8^t޾G.{sĻ2bKvB,~c_*Iz"+Ԩׄmu /$$]ZFNv7Ϳs b]ݗ.hlet_[Yjd} 6(/|r 'bi "LQ̍) J/+ T{x< wu ^DBp_>O9`&{0v~pćcJ(5X`--Mx9bB\`Yy~+SKwʂqlh 83t]<6G \إ'w5Jl lQ'^ST J :^Hu5~v <8kjm8k9xuSuFcP΄k4Y. Aw- @<-p-mͧbj+Kʦ`]5H"3i4DiJuX]&Hǧ$4V>O1r.mF3aڕˆ<~u^;N 211|ap[ΐuR&{n:b{6 #!R\pXg(AkJ#l|tăfwFo7\޸a,֯N睞VZI9EUg1ҟNiBț,v bk^s50žRb̗[es X%Y!8\}.Hʈ %wV G4u(3c7_B5ƌ I^M.DarZk/5qlפw[]5w7c3_'LMi:q CT֫6/ $5N>gz0Q}퐀z#"ǞS+TA!\ɡf:~WEh?0ϼ~[dY(ȜYp M`H}<qqvҶ& 5 A= l LPFAYԔlnYMҵ k]T(k55uSa༗З@EY0FN,UD! _l~jĀ }]uח$b7Ux3j|zwop&jon~E|1cuKxMW 7.,g&a&KNE!T1<6 m$|uH 3Ėc i|`-͡2i1Ŗ rȗQT>IHlRPfACU;F"yG]r1+Ҋ&҄jj“ϥaLAn|W@jJ T.u0 sYElu0kwҧ3V>ж.; `B7ߋZyPE\^ b/#REY2k];j5I5r_Ϊ=s_\A`֍݄7ٓ?λCW: 1T^l$?ehOcLl!xTSݣ"H frU3ߪE/otaâ9IqLUg.i}RF#D$:a8z⳨! *3] `)SɃheLJ]QmBrJiϓlQ&\ԗѴ t]po]j[>CA, ?ѷ%n6D-zS7 Wzn0e':P YY;w@B<]\+f<*|7[IO۔܏C8l4 wէyhzKjf6^xb٣ =*Rj b5}TY_xH!2n4pBؤ|k*.C"!>-B!v}g"p>z9XΒl ǹ_P޼C(%7 Di1SC1,E~U?zm=Bf4§S__7 Z*4--B-prH>W#R,e<+~]FP_7\P1ڿ2W})| ?2CxkM:dfKx7*rL_A/'3ś(ޑ:ĈoH_͗Kij)Bw}@M=`v/EŅtuQז 0"n'"n!t\3w<㴜zz(5W+o=h( b"lHR_u=cEݲ6,H~l. yaz`"72Fx0#YQᗥK }"vXoM*h5t3~lkv&O %W[!D ʡ#fb'| |^fldĭԊu-V|=ȶAtҒ \8;ҏ_5c$ ]?D 싨Osf.)P|8c>])d&^hpKg6ݿb4v((ᦩ i߁QbҲ xL~ qnV 0k۱X^^aѝ@e8ZbSd]i̊OcWrwfaSn5Hn':60eĽx6ND)&c)7`?6o| 0~6eO|ئ% _w^ui\2|mU4)$<{J#3s-+`ycDUJU[.u#i8hd@~6g2U`4΋ZK٧HF;02eMZA|[xvźv!5T Z"mYЀZ>2{sh@>@ՆH 9UΨ3V }hACMW.tLՖ?R30 ԯ ?aM4cHޟ6I|yremgQ"$"rrnU8d7f[fJ#%(/2 3_6ookͅ}tWdMuj9i__G1'xx]MMDUzK*l><[oLS=m'CHZ/WKm:MtZEwKėd1vA5p|aCC̀@e>zo%pѤ틃m9ci_8 `j?Uݿ0<.:cHbTqċICPÓf݇\[ 2,N{^cۉaZxU[ #V6P0B iUkͮZCR~8MH; A7HOo6!5֋-}˹) =1c#. I;k]e̴XdUܮn@h2N%̐E=),W 99FL;vM&WtMk#T3?)u!ƈ֜*9!z.UˌHiϦ=Cr'uk*o3 tZV.3 Zz"809R1ɸ.8Nr_MOzmj2Sdy"'RXHeAg#L5K3~OT]qp}R?g^c@Z`krOD!nUfڠP\=d[TFB(|=lQZ[doArcS|FHVN^ij>TC 3D5WmjCHJ[B:֛a#k?ZZ>t$ߝhХKu,9Ԗ#W?'9L]%r|4bd=& Y9NT/?Q^VHovl1AU?]HVuj' /SBL',Ig- Е_c=y L_7_H"&\C{PRSZZ;9Ⴣ4(j˼FλLvea}&#"GOٓT [ of_n#ybCL\#bo[/w%ktX:'ʟN7(΄vV9~XUw}qXp\UWxilN8wլ_Z?DPL#`8dZ~ dO#@j29c}F!; ,]kyVx1( An mb4;u ktݺl e{F›LMEZv  Ǵ/sWkJsӛqKse$hv;yFeh4;0]b6B͂iuPE 8ebҬ5_u;7_@ANMI Lp ruX&#mQ&G)0ETY҃tcB[m=qSi/j/MMw|E Rw/ kԽ)P)Q)I+NJ(52I6hɹoF#*Þي?S, ɺ`MO le~txV;rpC |BkmBho ZEV!744"Q=P(oy#.4q[SG5 Y}waȭvy6qT9C, 2㕺OSp-TX,}JHHW좥V{m1,Yh0n 'J.JQoܚZ}T"ʨ$6 5Fp$` YAX\B;C=_9P!k ops̽ h*w+ԅµUgVAt2fgmC+CdAXoeTjƔ Izx#Fq xw]20"*H%XqfiF /U6Z㰻Q`LiR˃,-n`nՏ.xfFs?,-]hqёRY.X'R5^jP=,|2a[*9!6% |K3C;b`@m!0ief% zNSo~T&ض>?Ί]jXex*27w*Wl"k9TÇO/MRH|'#-ޘCVǓlɏb"@]ݯfuSM.#"&r1r(ZɼV95^eڮ|J HqL'8f8aۓgnq.6ϫ/o.)VەcvJUdjb=m؎t썬r^* .gw5@a?&%v+Xln#ib~Ak`v-S߾zygj9&VYrhs1"Kkh Cpo4T+ڷ_h 6vb@XKXVe_g̩df-iWtw#^[pxx>0bޛأ[Jni[(:fQ<tZ Ex4z^ <q=w /]' V+sPWjyG|#ww)"˲T RhRBEؽȢOuwf=?ҿQnf_:Eq]dIm o"A"h!-wȭDa !(WV})-+}x̵A~MҜiy&Ԛ8t?K<e0rIfd8UX2\FvEA&ae'n^9H4ca_"OˋZE' O's+mYW 9.OzYΔbjbFnI9ZyB:nmDGvͶSC:ԢpT9dK/A_ ͥ%Z>4")3EkB 5xZ 7ѸM7hpNKE:(Ȍ N+i0)TզZ@sn`L2 =Yߒ3RДu 䐉_=!,@CmS.W9 )_.;wn4".J5oWX`QNE ]6RHB;o #l"*v[J=Tyi=IѶ"%RJe_L0"gX#e:zDSE#KBUYBaؘv33X1 ?f/юzqO,~ͳܧJn4cl98 4O|Fۉ\ɁJ~@ ?Ok6yLm~%:vl924˅ט9{G LpzcȂUN7^IE/bvxV4XLOlL%m쭾v A Brg jdQ3f mX ֍ԋ"r=?5s(Q<]GI奐5!,jTۤYꖬjO%^{<53۔i6[وilƠy:]jg;-TK'wo17 C GZ㩦3/D&53on”yF$¡W:H)hW|5%S]8>f]:MJoTΌH]rG$ɳ;@z-x,Mh܀. 8Xn/px+:K#c"HEN3)/)cs҈/\TѶņPmϚ |J+W7nnJW[}tO?%Ad`$sMƃkC`6YpM*2*3mĸz?b%-"b4/̃ \AeyAA[EMX=.L~s<j$6}SB]ǎRB52q\X>@5cmiSU=8@%xIݧM'Yd*O4or" l 1u( ieM bw>f-0Ǖvw<7]4ENaƈQ[8f{Taޙun妬ؙ ?k}5dLuYm4QwX Ny k̾pw *t~Y anGv) (ПJj{g*ܚiJלh^DȤgM}<|θ0ѡK^k5~j3OJa N@1!߀J3Ru%zPP:=8m4%V*եRr҆@9q|5 'MddG)p gzܣ.fӹ = ImxqSk <;)%~YEBA"ph|kH4V3Y;ʌ% fV9t>; 2lA2ӓڳs5`>UDmvb ¦x8cAD:kmtrETݓ&Kb^M0ii3DF ,vQpwM>&²ܺRD1Ҥ l#(˒ rTUh}b,&ڎ+%)H:'042l*5.9mTHH fB/+1IoݼYq؊:2;#ܶ)"6x: ݤ2!D+']qWIt˭UƺƆ'^"*L,[ɻ愈By?Ж'LGm 5(B6Vc8.OJ^b:iz?,gd2n}ÝdlĊ/S#u`HZatV乮X40]CZV"}3k~n )NU:k06abP'iv rɧz8/7m$%E_Ԧ7al@Ka lڪp]M6U_b$TH^N̶ǪG/4{'4QWs؋`{p?)ż9 ߬9͌B߇!Ʈ_ϱuaWiFjEtBmxes(>GS,%v%UƁCQAtR$)F: 'You+gmc_Q\4 e7oTa dD?w1}Z"־Mn"$W~Nz@8bX&G -죎;l#=/4QɶW^'ڔVԼI9j1΍,Bލ U/!q8)܇]QMމW.Rā"N[Ȝx +) -WJvn؊%^%.|p|oNRĉHPZ'STa-E6ᛃJtZDKȶbHҥ\m!5B=48AI[a7ߡƩ *|aTG,tko`UsԌ]Y9>}T85] j\/Rn$4q'":|Xc\M;AFO ]1 ,s2B]J!즲M)A[Ĭvy\#N"ȼ_6O5 VK*3*XbOO)7:C1!u-"0[܇9QD\ K4D/.GC0&ؗ4yb+f3Cƙe>l$(@'ӳGEEn9Flj}KdQ\#gZvü3†IjNAxbee|'{le$N16 9uƄ@ɬ|6XUVbEdkKB MxXbGq1]]}1H`#rݦ:#2vړz9Dh9[KᮈX=]E9tiL,`BY`kBʃt&;[1 .n$Lv8s⤒"gth00 * ɩ LyWD~\pk*hk C}*1`>{Y(^*CY>n0ܘrP_-4HLIYK(EsELIq@v$7} 4HfSJU=iO-'{9($'>yUb̀VďoRP}0(L|`0.sXEزf(MFq0ZivU_]~T;ޥ4`%{"N5RcuV?go#EX-N~;$DԌ=ԃ5<7wYJlQn5>H#tKK&gE۫4hR¿2ma؇kV@38jy u]Q3eEy^*89%Mh?4z0mI;u0qR!K}9&-{2+q?hqfmA6Uײ3|, Tصf%L#Nw3tcD*Tj~zhނ4De'OY3L~_>p4 9(*4;r%C9pҴ>x^WW/S Lν1ev # )U5oYh,;|&ݶSR,K/0&bXaL92OL{c6j{7xA^]d)rl^Lٱ7MO;9VT{3PؓK7ZU`a߼nvp>p%zd,Kрmuw3]~L̆LAo v |mhGC0.+\=ϱTKL(kF7愦EubkJ‘^4MAJ/28-FkL-<*5aNb~ŜyϻwYlFu,O)[:Jk"m;H-Fvu\ mSC5J*'Kn8.\Dqn>i, RM&)?`4ǬR'6ܦfsm}~.( pA&l(%gOZm8EkLwWXCZʊP\e,L+oL51<_ TIp03[~*q|vڱC+>1_Ea%6! ԱK B}>ߕ!WP0}pELL7LK0̳X~q ;~x&-6SJ1&)䑳\y*PxK>YOq=oMSzK}sV F.Gi`^T* J쳕Sc7  I+]V<,FHu+t) kO$-nȇ+ZM*Q3 C M'w0)Gl|,iw狀zczr5F Ts_ <֥ҚyrIQnNXEЦ{&VnMyMK$ 6(VC,ps#chB2|eV2ui3e%RP 6PxWSRK @d\D,\ R ɹ-yUF' eEY֢FwMXl{bېٞ1\P0[A.forl Xp)H->1p?+kE \FjE1b`}#AiCyfc m[XK%m?ЖcbK>~xE'_kULR}rAA=+0^* 7,)Rbi컽uȦ&*Q#+0'HhHƻ2ߛ)Yۖf#xb.c#a؊dF<kzgSp7:+(y4}b{&; #>tܛ$\*Z32/B"v)>/3ݰ.1O(|$^ ,1 hUk,c*^2 Q 2˖3+E Ԍ~^.s{` U>3μT|fgRvj|COJjηVzJ(?\I6|6nA}[9@>l5B{@$-TD'x`*H|G\SF>AJۆQW2%LlK>\<}g3 |2T:BQ"Mm"gMFJ܂=#Ҙ낟_]bΝk6 r?q>p-|%Egc'?6kM MƄ>;)&$.է=LD+acUnzxoa2cc@yi]~_nҬ?lP @S"/ ,A'g宅B~fo ^vczg%/:@E}%ycP9 REp)LbnGS% @jK2 +{)Ii͸dOWXR;gٓ=ML <6\+Qу|CYBK;UD9KӊY7 JFƷ-)=GKs`! z(YӸ(oZ'r >4- _L23`FjkXK Kh2<(N8m=`,gb`,<$DO(^ڡs@pq|V6D5 0fV.?ɉ"&~GEE^ EWcBWlڪmt10L>)ܛN`?QZl|0}^}k2߳y^Gؔ7K>AG.Ѥ-92\xif.#Uj(=]JNuy p6Rw[:_23%YBժP,}|[VLՔd}_%/pdgU\mr{'>) ?3dw$7ޡ`_xboV;rdtșfԢț0tx=C7]P2M;c[`3}FBJmՈłSzUoIH4G [iP@ (R`6 яi#ƻѡso ,+*ŜHCH?۟Xɂʧ:iH*:q K5͇:aNKsLka h2AO<9T8eGjʅy|8N?>ߒt~G3@ \ C}އn MO-B^`:>՘FFj9 7XıGCOa3|!Ǔ䌰A W|>^N4J"f0hӖMPOd|XuYɱGrGT<] [)dg 2 _6nP4uSD?N%%,CyEdt0)os7H"K(dh=̀d7ߢ s @>"AsϦE?|;wT>w"klWh݇E0^B[]N3Gfr'8ylfxGw"xGyo͈N>\t,pd>qc*XWmP xչF.Y܈EJg4#o m MfcsXnXQv>HE&  bn^\ BE*"@WHnI i?U-m(m R~:^ciIZO>#DsR4l+r+عZarFP ۭiŲ!g3 j5>ϠT?k2.Wމ@iecDCAjN64B|ED9 @;æ$Y/H )b8G[A[?Ԯ?i?B_ ̰0e9vj.͉Y8Ec9$A\(<4 3#aW@bܖ}E@X2^0݆w 7ZZS׺`Bsj; D{s kF ~:c,mΏ.8dB vI,o哋Q&u kȉ^)fcR@d&Cɛ7Irm8L4DO~mvHשN`a|O]%?c:]eDJPȽ5q^Le"oaQCoDaG{/*6O圹`O^p%Ƞs`,Y0ڏw^-dRgC@c2Cv9[MJ2gʷC7)p7 4z0;^ϟDUip;jR5+TfH^ɫ;Y<|Mr?fHfn.}Ur(&lZCQs%UYK LJN۫ciuݫWkCvbzCqDiKVx;yS;GFپ ߏwf+Zlݰd03_vYiL`cRVu ]X6'oTGM5.bR"x\[@jcB="dJ30jYwN_5M4e]< gYq(Ex.IOcԕT2Eymd6ygRjAPyi,p!Ŕ[j, ҬJRY_-VKx$ҲlR[G\8n-<1ʘZ9zpɯRǘlp$ݩ6G}7ǚUPJ1 u;Tʼn[[-%;b,^aq+ uySKWaW~eXR3Zź֝9>U2-Y f&Rs؆Y --ˁebEy8T6 ;}C#F !X\Ba`H@gW;͓T/kǍ'Zc]`|g6p+5Vp8`.ݗDL6eν˧l4ќ"Ҿ]vCry}ώD2K8_'躨pZ^N4К#=[<9w7oIHktf]_J]xɅHpbЀ}.#K\ֿ]qy+ imWFExO=3na~ Nt(UmΪӿP k^o;θbې놝^/CɹnrDA1[E^&}z(}&C7NHz 5U8/u@S1f4\@Ft2M XȢ'h/ {߼o!,m2ŮQlɇ)66m]gϤV 찦_zM7I<"aӃTv3Ou2J|ipng{uB5FƎwЇhJԛHa 9tC^kxteDx|bIm%LFn+tvZIdpqעFZ:$ЀjNhxhvy+)5VŅ~P'EL㭆D#u\ݬj*rVri/cGBnÌuV~7([ Wl}A\6+",As9q XSXPX;x0زF $^S0\lOm)zֆ{+؝@kzSdk_a',@C Kn2XJ10zKj0&32t/P!+e_$v 6Sqqg/BP0*G9Z>dv2}nqa{#[ڧl,,yd !֦ҜWk><^_*;Hq.s$M$7>[Б#8$إ#sW1NF|}e [i6ȋ[Ӻ M7C]B*{ Z$hrRAnrwC)/7bP# Q?KP_ e3X6d&_!Β3 (7_a5]B.cx",~g$]zu鿻ZAو.Z=5Pdq;2^+ݦ sV$ 5 MwO1ݿ Sě) ykt|yKpdx+pa$~\M2"YPcV *)]vP 4,RhȄ[l@ 6C$x{ՠqĜtB ҚaO%Pe&WY@Qv6<@$ni߫Ӻ?KD_+IvcUu?[7z PSԕxz!~sCm%c9NghS=!?(Wis)T4dc[=^l~:2)(3"}_Z"W!ю"囟EntD M8A Api [PZiCfD|qԳt=@0LڐHru|0dhrw4܅lsFn@ȺU~=%TS|P a&cr!I-S7*q3`gr M)|M(bwfb*ʹf#_:@ wUzR{~t2Jlrybz;߼8o)VmfٲkONH;6 g4Z Wnm|!1ux"#e!uGIQq+$ϻ:z%$>b^U'hL_*-Vxv(ش<(0n~ OYj\:c06a2?vL5t-zD''H*4[=L#M8"2:Wc]ml} fylX3/ƷE<XHY[lxw`.6{/ewnh1ikRJ7~.CBMc-RWb` qhw5g@j1nmu1R kWw +ӁIujVr@\0A8?\KyVgJ4Рs=KyÃZm}YI<\`2]%⁡IP~s٨qؽSеdnkµ㲵_! 2i\U߳Y>Zaz3^C^}8g]ˉkQd%qi7#))Zcm,7@PO4> stream xڴeT\]5,H\ wwwp(]BNpwwV~ (ҹ^{+  ['zf&<D 4s6t001!: ,@bN@9ࣱ8č@N;@dndPANF`7H Nٹ;X;JOl`hkag(\F `476L@M @R 5IĄT@u:@[03:*8w835.@Gm5p*s'';FFWWW3gG'?T- +h Gg[N)9 c#w_N$?B8ip#_m ɕSTZ:m mNNΎlo {6.Lw/m{ [G G'UL-;3 l *rձeprs'w=a19(rrXXXL!5؀Y;"Ok+[k7513PZ&?63 ݌gZ~2x{ځ֎@o S prpz{o 00v: S]߮*5l&@SFx 9gKZHoEO7W*,%,܀&N/!xmͬ=Ǥ4Y|XO- V%-A?a  [3 ; <,OfH#- sv~o&;Q_(qE . `d0JAF?( 6"A`.+A*iA~xZA8? |8X8Z 3bfs2r04ƦNdN$!^1C ? xnj_-8~ J/O _5~A<kang+l YY`Kxֿ?X$?+/eprh .ig~׮1 ;ƃ X;k83-HwcFm3]hWZ`N*'W_ `ݝ?/ o_,_.pW XV?+yO߯<\^VqrY5,LO ۧj@W͓ ,=+X=NVR|~n@cy1oeRCHxT) 97iL@8FXX[%O-VC1{|XVW&0xP!D{s(wkIlCWgylŪ;:ʎR3Qߗ-uG)3#ҫk~ nV064Nh=iĂ_PUYZI"C\| ;b8X VD \6$,ãLW qPsDGX7KLep4x[. [~gkOK(ӣӫވ`!QɈJ?/W=2Z__^HG<@d[mC9}ꇚ86?5^ 2]ay vY\ 1LMDE6Zc#3{#?@8h ^ KH(Z:8-=[xf߼@/׊*TrHlS')39(=^H.8zye-7k+#ީ3\YP%|S<1jV~-pgq =F313E_9qa2]0BN_*Ʌnj Ժ|JKi4B!A[7E5omõ)qQf"ToA6sI]2 4V\AN˳)LkxOa%*qc2Wp{81tJ$q)In, \/Cj:B.%o1')p,t~J~ȩzEWҙ>tcܞUm6$iI_Ѱf,E^T_x lBڑ޳`<" \#37O޲Oؓȴ?ړJĽ3" IrFU,{)aoDΟE s Nn%GğeiIm~2 ɡ*/x#4/V7)כNģ&VF]z6viN>ذg8t6m-Y޶DQ+;c(?)5LA&3@^G1f͓O۝X)yujHfΏ@vtycFMx=g4U 0 &7^ RakRKA>An%K k+nb0ʻ/lu?==ߒy!>$AlK>p ݬ1%ObX&Hm8ܫ]U;jfai ѻpwg 3c" Kr [mʒAPQv~?Tq]:ͬg02&/сcnx\.S7ջo{|& ^@zaVB,IK;;1C=ph}><~ *b :Q,d6.>Wkeӌ,I]d6!{(<(Pѣw-]2ٱ- h31L6_=:\Y*3!^N^ݥr/oؿX2A!#ʚ˕ۦy&.$*lifq3"j,/]ah8kǐϽ/\$6SpqH~UdQ},O AN ţ̏^5"j5;sh}sjH!G{.r1zPVYTacqk?Lu߲&LPvN%S3r#wepoq\=;TA4. U͙h3iWOBJS ta|߲Z"[V1`(6 A1]:;4'mM%nd!iA1z";Mܕ!'Uַa_WՖ6H ʹ?lS0hW MG.e>Kd$ a縆b\3g3*X9rOR]8{`heoBE"jە};i6 SۏߛUYLeA$a]&4Jq_ڗ'֣CňJߗnghmBIk +,g%ј$I 4pP1(5wqow]vu "3ϼЫ"&NS*v~j9wo QϒɮSaPBsʻq-'Н990 "RGO0pW#4 sDf@J,V㢍<_LJαKװw=`8?=G4]IH gL쨊_nW+[r>`Oz?,^TDŒz?%(}I|)4 d䥄}*~ G vw;Z%cˢ6 eH\Iᝡ|?m Q]>!j}Ң?u}ė=i7Tm8"L4NPi.waw4egw·K'%8loʍaq8wrn3E]+%t!td O [ Rv /ȥ]CdZ}N 8Cq McY ]]~ބ.Ѡ]pUdQPw{‡]C~̒I9v.HcXSCj_H],ӹ_1γ\5.qv͊zR zθq!`Q߰nl~Zuecd\7+(#cTm$.7z\`+?d#ڥ6]52u>~O@ F`!-FT`GFeHPs{}}Q|Y$jR0T,A)ibʕLJR r=-@u_S5HI2^|Ä6d]ϫm1F*_43S  &뻌m͚]_WhR'! ~6=$.A1Ŧph,7nRВ$g]j"7f6"XD)8!4 ЀHw)D.Yu ?\l)1S ½J^}N~O/iGFT'7ŻT(g^˶6 Ȋ+,^'YՅՃO"x kW {'p!"Z=\HͲ%Um}V|~HVm. .w1;nS?v^lQF}BP[r%IkTZ' zwwn|\}\.86ZC&%s үf+'yb=}e7J RF}R}d*]#Z4G.仮Cnw 9"О$2:B4zּEx欙P"ARVЍfTi[:HgfyҐ1oF)8ȭ (өquO5}s  T=oDd|qkY,;Lf|oZ$EDͻm4?%hSV;Y0ȇhl <+7BhMRL1*R׷087fӭzNfX'и仗/?t쪋 /Rdє 5Gx|Me+j$Oސ}gCmx%[7`;AO\bYhodn5:=!nM-=q[Rmviki"ԭfswlS, S)('MOBiw~c1{k°c s Q!Yol.9b"u=QD/[N1S\KƨO.zQy+'HPǚ2ӣO D Z2v{w\/L:mjZGUJ1s\O~1ǿ(~j\ wMIƌE`=."Uu bD.fvy`dZKb."6ѦyゼR-iNⳟfZZDޏZTTp(j4 櫐 d,_t#'PZz%$q`h7'ʽ ! +6AA_J]ġ;,ԃ|q[X.]ThzwLXE_C7ؘo>h"w^C^ ҳȬH)?yRFeB…ޠ>-('HqgǨ3mfߌ 8$R>޷4͖&=^s.{#+tΪ (=Į_t5g*uX EwCGhT {+fSDAYA%R:ǖ*Mg'"Sx]Ʌ8aٶQ*-p%gJX)!UsYZ S| gX5?gvS'gǑQͣOT@]k%&i\<`&bX+ CbLI)u+-E`u+.]0Sƥ;S9dat)Z:bwR:LŒ01ܳ *ṭG~\e?ܬܹS%) #I]U w )5amZf6*]$h)lB(xJR#t~a󙚆\>,6)޻Iw|Xdu'}##lbۨF lw2$gu{b Qֳ?Fm¦>[UvbI,6R ǀ$:VLn&!mTB7㌗>HYqd^nbњb?];f Vϝbw9F#AhB qW÷uXd$)AYS%Aۋ\F~K7oXbO`ㇽ&\{Н+A9a bmh,"/x%F#͋xauxTCA6ׇ7g& T4G_PxzmU9{mqBCC)1m7`|aiR:Sc&23$3CEfgb\a )ٱ-a B5k {閱.(SFHRíD:rLo*MtRࠂHCyletWX.\"0JWvKafDM+{k;{|*R!=gSo CtDt~pl"1ZU+<5 {sp_4oPk s,zix)d#U|ܚaL PB%SPaQ7ۼ)u:I&GLa䊔q[3CVd9h}rbCnK'ja:2xh]$["/P|l)T$\,W =AbKrkwh7aY穉 R"b=ku,MHꉋZ9\yn;sng3~"6d壙ps}i7S4C^V]1(]|uSQC(ULq4i›=L#pEɜ¨ g ؕs1pR9?" ]o@㶮6j(qr} z|t򚮩xι*wn9_C1wf3bKjGG+j\R@s:&ZVU( ©|?'"TYTNO ZuS<$!/#gͤ mndp<؀3DLv31{"j읧J$;.TXE8DLuo~'M/J sɵxtSr_$y~$hsCJc lJ\9ka ۾D.G$M?p_hobV&opk຤WkiEQiDE ϐr)R( օsD'h+S,V #R=~'w zOmX'&.R +uBbG4¾F Xj?G31yUyo(15Ef{EʫSYI+=a"i;E 716bgUM#zO}gվ- _SQ]H ă7NCAhY?f;>S<=)b{-4억 .bâR4B֧K^+;~Ə,֜( :}ϊeaT5|9J񿺢&H}*5TN*#3iq]K@?LZ {hr' >+aC:}] ꣛ +]تq.kOz,8g~Cr+B\.vk>RLeDWDA08a2Pr 32|Eje+Yg׎[(Yg)z`S@ z “NM 8i~|3FNDCqd T"ٱ??ϓfj+t/&/]T/c-Ⱦ˯f <ٕ,͌}D~jcnkf] x=RBO3ch%"l\K;G;U :LHV fBmD'a>I8T ;Np&O%̒\p@)GlAiA?,ٛ$~;ø~p*TW 'q3,(E!qyoԇ(Mj4:Y)N)k{V&7Wg<OƕʿZP*ẚhEw}F?̈́v@^D5l"g}|+ƫ(H'7׾ v02o[?ԡ 5={owNy59ԓS\[KiURBs|_5qJV:avۚcEաKB*ݢ tZk;`i9>[ƱR&h̙޹兡]Iʲ[;Cǯ3}4:^O] jNy)s!d>ta2i60T-ҕ ]eU"qu=Toy5 ܛd.>J _DUmBJhao. jCQP>Xp0-++QA hZ2mɋz[d=Z6!j- a"EpVh"}"$0o$ 'A1>km-C Q~{R`0b\-J0 .F@O9%qzMށ`'pGptolg~_>A)ߙ'vzBKj,8&ZJKNYQoU'j`}ZQ*9vY0h1:#JU%7e7ſ%o<$[ Ub8֩@d<+E\B++v` {uq+Up9˩Z@H'#ӷWD ZG=1r8;\c{ܲ)ľ1)جB*TqU:A5y͢<$9S*qjԾ-70vU.`b֛#>!H_sW8DILv CVD3~jJk 3bj}9Ba:[NV]>͗3 ?ݴ~qtG/GY=s 5^1~e8PKȞl F\k^ίke6ӇDzĠO_Ǹ%2Eq8 dOq:~wO0Ssa m7:I=d'#mAWY4ʺm u'Y)}2~ZPE ~&Vy{> _겞v CH)%Q-\kMs;cૐ?OH`Dgo4xkh"4!kkT^BL̯YVw'&Bat)] ,kSċjآvwз:${˛tA( [aE[-0rC|s\ZrIwe8߮`fasC% Ng,ݯs*;[oMSf'3~{S5gp{ HnZDK13}T#l=ٲ{ߘ;}W̬1󱀂ܲjkG_>ukgHX4PE [>?Jx)ϴ^r{94sY0YPEJpA3(1iA$1 q6KDgZKtj+l cNC1-+`|Xkω~Meڞ{9z4EٳTqFX1DPDg_`G\N,tޜ9Y):>M͇rlٚ-bp:ٖ#ԍ FdC`BŐHAP[K#w~!"Թp3(mYkZv؅JecBLaU}LzI&?kf-)Xݹ輵2- m}IX4+q]$ /֊h)Im32˔'wT}d S|Y Dރ{Wk@I^k^Y/!ȵ~{4,( Z_ӿ6tr)|G0e,=Y:̚{6)ۂg?ɎT^,];7ZRϙ=A)Q$-_M/__MXN/^){߯=c 0>^nz|Yj$2ۊGZfc7c1@__T7;{3(pڷɇ˚v5MsJ]L8ZA})m>Q2b<ќY9 p?%OMX>D+_ guV R`J09!}8JSp؋q4EbB w)x F![%Iё 9b]-s p&GԊvEä߼>_ hŽ)w9gBqT=d\@kx2^{3?E~Z@͒tz~_oΜUQ wȴ Iu;!_=WⱰKId&R0([Nc}dϯfB/BzF+Jrr졸G_ȯ ۘM|\[8P?#i\{$ϙS[Wh سP"2'Gou&< Zvқ|\}zyxnD&>Ψo /* C˚'Bh¸*$#6»C^dܔ≁0/0ׅaM>F<F}錳ZzҞffD Ib>})1O,οZP3DVH4U'_{#v`f~_f>řDmt8R n eĺʷX$ec :[lhag U$d()3o~#H]hW%<|Y'?L,ID\^M S|TbXmO * wYvw#tP)ƍ{S ҟqvYڐtDw_!ZA\TP.( 8C1N+xR(oXeNL`~3Gֱ9#KBa|6󁢂m*8LqVaj$ ےR ̈AY;ω9[R@p>ȡG,!WzVJ9L(E]ailwÎ _IfBŵR}6QwAZwoM")!P䪣_ x^+-o.)܁N]qjHW!Y2QNoCXfȳ}5[CKz/*5PJ6JVI}̫cIWo4&xZo҉RPzlR&r^ڢCbc +Ԇ[KUdU˹E >fr'8_ 6Ct,dg,i0[1Ac2hࠢWQ(_q=U2}[^"!%}1f .@lE3p9rIJn9hUDf[C*qgP/dG(8Dxpw#l$8 lnN& ͷ)*rz,B|m{*t(:_>^FH(ۖlTΒZ"wb}<HI>|d|( @Q<^A]TYn`e(ZE#n8^F;kϬ=qO7FCt;粯۴|8jOGsUZxo&}X-ԴFx$nJEyyÑ!ع5c<~YN#njrI[-~8?C ^\XE[ =mfLg6R)aX,;Jx.xBN|I;Q-vtgݵ=ilmɧ$0qR6gw'qgLW-%*Ơ >#|m\G(%-J\7K럨x{sծm2濓7[2up/}7Ĉ`˶m۶m۶}۶m۶m۶mf~Ym夒Jq1o@s}X#2 61e0\qMѕ s˸[>*q\˾Q薮PyjħyefJPf8jlbR@OJXG"ٽ²$#> дq{[9:ӨS-y9'.h]a,N#ʄ%5~^|X>;VB[퓪P[6" @hzig[Cscg OԪ hQ G};̓z!VMS'39mqG_Bin 0xc*9?(셁Z8 ~2!ꭕ~M3w|́:v|F3‰)h&&{4M6EE 0b01ӁkjYt{C[?Q& ː:ܶD.e* -vZ{)mL7nQ8PǛ˲1x\yYNw:qKMu ;fBL=zH%&E@"&ޅWw ; X04)P駦dlΎX.OC4'qwX|8.h1|Q dCTf*;v~$@(YJ:Uk=y5DɟFn18U=>\j]E 5SYW:Osz0/$Ԋ&]E Ċ<"Hp8%Ae;CZalD~c W@";7a:w{im5.銎zy'5P s{7WS< lW0r05Ae+ucΦwI>\oq HdSK\XcsyiR"j@M똇Ib>W>(50UZJgZ,G9+v|} I{xNԏSiu|t|o>B^g>"ktjl'__Y,p$TvM.ƀqV#]۹ѵhA9G&:ٖh{&r\fqD񛗍8<v*} j]BW"zO幑uO F;rd&Ƞ(9A= NC1\zTMߢMߟE8:hm]wJGRKiŀը;V|B9LsB'!Tyip#K>8vѮPkHd$Apy0(V2Tv0%Ǘ/* @+2hm79gNn|1ZE qWtQdL ;&E4K4`o򚊓D^)رgʓB,)O7NOd{Gw^R^Asٸ֋TiJ0Ą!X A:ZPVB};M#S(,(_̥v BBqG04o u@ J]"+{`8%YZ^)]Ut ^ d'"+\E]ȇ5s<-e<ւ0R_ρ(IԺ#yy_rB ۖ!ԭiB7R{Xo^s !xnytm5.MS>+b T!nSQ[&lo&{%,Sý\m*2PCQA+ 3*ﲾ7z\Ӱaƴӊd-{ ;3˴+)~_h Mw{Yn RH2dK$iFBLVT?P-0ő};ա$dAY|OGNѱhr~ߥ`ɐ3I+ _ ZM>ag8a(dYc=(2Ϟcy#x# pjlwCRV90g8c aM}9P#<pK0&"yXA,}'&QzG6Tx3{|(OxCxg0g3m 4ߒ& Nq1;:}+Цw+1y :|0tΆ amT r7M\G>%C'`Lռ#'zcoC4TK湖eݺgY˝#U;keG!w4Ye-Ĩ!{ZG i0G)gistp g-eeݵˎ Ձ-D+ףIk b:bƺtqWYhj?iʂO8>;JDO"fZ)o)4 OrY!6~ٺ'+s%3t*Kyf>D6[g)Qыs9J cZT 9yJ z 5|^bKjm轤#XܠgݗE\\b Qv,TKKaޕ$=S\8hGCu~H qWX;mq&txs8rxܘ#CP^0b!+ߎ-H kv;#h?g;AGrd^S)*. oJ'Bjt+zlv\fzhH;zIG%x:Q:XKDv~2]纗BF%h8I)-.{NM؉87}C{,w;Ø_孱PKm\Q7c1TpaY("f-H{iXpdM8CG_ C8lFlc?/|p?+bWw0 R@$fZ6C& UuEGnRLӅ:Mp[s.JHjmaĂòWV( 굋u(lԖHbx{7h)fR:'Pdw ȻV+7 aZPQe|C ѬzX^V|Mx|'G5}ua nXo qE6hpÇ3 Bp>u 'y-X~Z^Q .LTp&[ʯi4=Ljjm~9hȫy)쥄j6uW_rƥƌ^lس:#vLkY",]7b"m\VCƵMdi~I};=ei&wbhǠ6^݄6L$Ϭ+c^U21}+0o]jG t[5KRE<΃uaU~wZr6bS € J),FAwk 7suJaHx!2jdB,;|e,6醌eT+\n]ǥU` @b ϊݟ콠EJzx;]URM!c{?kn XQƜDWt>}x͌yi+8O`6-‘D ޢbI>t0:'Ce!?R]8AщD Ejg9=D翺3TrêUdp [ hTD?{' `Uk,q4t>o|l'UE_?,H/GWToB>@tm!ZXQ_NftY؝PbzG~#3斨<7< ;L#E\HF/&usS" wA md/=0 >XHe6! 3 0éJ%0^H1u, $L׽H= t^k,~f\7эz{1e;t&oJh 5V B# -hd:Up @ [, C{#}04`\ %t)&6g-y5͛0~C#殠vy9VE0ءiubWvPZ!TVڀ[?V x&qZeyK0֨ly2ցA116kPX0 vpf=_}thֹ*dIpS`SdX 㯔ao br&|W/N$}EacP# wi+%!t߀/GL($cR6IŊSK*H?QKi5T8dX[*oG𤹧(.<.y6d1*#D^ZV̓햦19FY=!.'}$SƲj`y\< ~$fKI8|邍ќ<)8 z16<c^@e.BZ50('Se—OV&7 MB%gu?7RUhڼѪs5ֿ2,`;C[l Z?MD4(&L%2l:,:t<5\=m(lbk68)hd:gRv, 2q|MR٢i* Ϧ,˕Ĉ)f.bf\jX*Iѷ/`'tF!.:0x#ӛ52, ڢ)%"<`lBD],#% !8Nq LϏ_Xo;Pٰ4$FDzm ^aFaA,qJ7muTi?˷y(fϷ*CNFPذ1~HaO#%ta*-ĉ]ք3Kťa|1vFT*m58g~Rs=2G:`jvͶE>_2@ٱu }2O7vCMp{Oo ~]=ڸߦ|9;GwGPQp`cmgWO zI:T6ph$Ns.lh<$Uz_컐 +Eں.7N|o"$Q(uAٞWfu[(^sٲՒ 1]MQ;8ŶvSTx( [sgy>eh7z;\F?u㴡y;@;F͒zLy`|"߹>^ēFF c ^Sw*tECkÎ7xvUL6Hw||x]2# #iM%Ei[A=/Y 3d|Gv̝=T2E0\Xib#о:čn\.f]J~`?vR*:4ڻ> 6+0\˄pwo)rkZjtz[㟸[ƶlw܄6 pd6כ-o @A$ݩ=ooR&wRMuX'6@*( r!{0mxc޳oQL<4KnJ9HrG$޲c(f3Hu<{;1&|6 Ve1NF\ = ohs96PkK⿬]m>% YW+QUyKJ`pfo.!e(7νcnYnm&FϨn7qDi"dK0ncI4˫H#E}L,"~Lj|~& niS@ uB7G#MGUga _ɹi폧:/HSP="QM| BUQ,fPӏM|OY0d^*9ەXH UH7}}AȎ[Ջ9;ޮʮߋ'FXx]ܐ)1g5XTTe^GC>!$ช#IUuRO H>rhbk4m8Oq|8,ϼh#6( rb Eh^V5ll"J( royDQ^9 4%fbP@ hZj Z y=0:ԛ%Pc%5Xަ^LkD k֔~\Avz[w2UIi\v O~0e\=zX볖f_[8ÊL`9/3źCJ2Į?G2t{_e.{!A^oAηA*&)ƨٳ$p75ġ,&q i9]cU-$(pUԨ5 Wǜ}҉t໺hVsŹ\)wW2V.MD2+b@.nP܄Bn )ۼT7EOCN^,WaĞiZ1,ϥ],NP⩲-;b#ٍ$ָ$g$- =<,B񐚲GJvўƎDeG)`-v\D bssZ;x'F2(9=]G6q*m$άG00VAn=pU;gw&%))]\#yF`6S_bW<hn;C|GV-#g_;ȒwP'*M6xOWlКwҹԿeҾVU a%u̟A۴^6:3ڝ4UO$g= 5gNԁkSϬGx+E&̽|+^ݓ*ݭ.=}^ fݤ8aTOx$3733]ڪq*Jj*E(K'`wt_o#Kt~<݀W6K2DIM`}U%89&OAj7A}%r;W)g=GB{!R!Tx_bs`k[ lFsAؒqzs@ r;cΕ%Ρ̤&~SqaLB Ϥ޹^?SBQ?$_ꨃ 'q=TўFu4ϣ)tmF܎P2 k[<_|qa. DXTE:H4[c~ [#xa+!><䵱aBt${"T1豉W# Pn齝ouE :7-t훶W_o~Bo!π;sihUH_XNbk (ayQVTJlƺ=;&(aXTo^J\[gI 90uyA+9ajHw1l'Swg5(J[Q2<H0i&FѮǞmEF3+CX=dfcq7WsNǁ'*`3is^Ӓ0p8v𥨾~aA0Ȁ$mbMm<%`E},3"+pM/GVy#j9]%Q#פyʡfҖPS 9 s :;[.=nI]뜷;zYܽ;ɊY+ick#:&"w7}Wn8t6CzGZMœ0@Z3BJ5 @<{*8 Nr]}erhP p%ns<+2p 'j0Ri`5%?ҙ@жx:f^428kDusse6ze%01auO.R{F,]C!_zj s&S/|pD/ct ݟ+Ef/ K=T8(AGas=!]w5}c6o"O mܤ3#)U^Srt#BNs5AJg:Č;NFi$|*ʙKrhђGIE+2\0JCyb"79irO(՗bd/hQ74,w:"ޚUDbc_- r>RN-\uޓ8n{FǾJ(_ŇQ!p7!΁OGIPP-݅pͥrq^u-|cYf$FGZɍ2sӒh+L؇MBe̓D-H#<P쭤xz Ou55D'X=vi;Gp4֣jPp\dyܔHr$) ֻ_Z5\!>(8 "xeA\6"gHyUٝ0RƁ.+Ӯ`>(VJ {YQɘs"9x3:Vˀ;GbH2,3 @VYaֳ&/2>3"71n"_a&xȹ]ki]=2RF,:>u1-D|cw=_Wۃcmvg* ʪhܽm=nZa[.JHTă]3;fÑ g#`2>xahE6+]S!#aK \Ci^>Z1jf:_1EÕ >\eiqs4t51fN췠bH\{Rgpw3*[`_"Լ3a E3Fc|ƨ^<^?f8^'&mP"K4GLgwlN E(nYC"STuЄɢ,(=x[^H,aODrُSk$4"v>N$gt?Tu|򤖛%"ncx$0-#ʟde6M2>F׍x*]uQ7vj[ -W8>\JVz 4 ]sH/;88YеԒ=tJ!_U%ń&l %Ae&4o[(` qxR}%p ;Ȩ[&n{Ϡ7xETc t]´zsw+)G:cpH?K&,WdCelPds-,ٵc3'OU~s4z?Դ1`jdw&Y(qՙ"ph ag7Qa2@~ 悿ՈЇJjlϸQhf'?n*ϩ0BxRHC2OF |heuWoMZRħ^U*[m[F)/@v*yAT.2q:~pDż3Rf[B-}Y:IJgW}UK~>>겭6,1}Ҵ ð%fm6[j> stream xڴeX5w ݽwww %8%hp ׏̼df]wS+2 M`;gFV&><(ll21p QQ:A`;1cg h`caEH퀎J3@ladNΌ&NjH" pYX:;oo&50303nBl0Zۘ5@]U\E JX\DU%b j@R]U_5+ ګwWjjJ̿k\NiōWWsG_ |nnnL.NL`G &{Yn`Gk#Wc\^l ;3ȁLvNN࿕|uz;k#ǴOKc|唔 ;g髡//Ќo@Q97_+ӳ1v۹8y7[) wD d +HK1ʽ<;vLY',&:<666됊ۙmm_Y;!nO`G#6ٙ=(-Ư"?2 3tM-'kV~Y_e8}@$/'cW O"$Vnu_Wv`W&Qt;j͑ί@ϖ+-_- e MVhkl/I4S9ZĿgY9Xع֨(}~@oW=tSijmtrp__7i/+q;S0vt4@by6NNT3`0;">Q.No߈ ,qE  `/f0KAf? , Ez"r^(fW^AT|jkL?""Wz4/xiYY^ J9Wׄ]|enJd}%j_v[?O!v 큎=L^+pcZ 55W?f}%)竹'%ken_y9x|N`Z)^:WWgY :; ׯ407vv벼ޫן? < {1r_Wӿؿ;?݁H+`S`OTLxZ2 0+byEE`9)>}ߔ-`\獶䪩K3ec_y_b4q\ &Le. #R IcǢw1l/?S)?úϳ8`/cu/OwB:E 3*СO+P:DvM|yh|mSJ7UX/ֵM'zAx/#ZؘQsG!CfI,4n]t<=3Ʋ/&51®], ƓelMerZqVe:!՗4 䥘"4 )"5XQ?ڇHiCo >}mDTzƫQ4gm=1 ث"^iDy i/ZtP J㚉M_܅[?Cqr EFME@l6ŕ\p5lᗢ%򓝔ye+;?ch`'.0 wo~fxm*Qm >7%v6JUP8:?56dQ?S2iσ3a喋*A..c)-F4XQƜD2"BQ>.>Ҽxl%_om>'+Gc JpCuf(uYH:0[aΧGSĦ^=Ib=O]t27J<6چ )S;N?{;<5K`V+Xj>ȜnvhIg!QWk1"AA)~SDM񒞑!(\܋T)]P '8,I"/GF&6s22\v߹ =dՓ!3MRi`rjAMxChcxvW!#jYW&gHG翂4O袶LT h3,}p#!$' ve4=&w 3:#J-+%( &di26ivod!U/չw:L\C̽:_PirR$)bi)..>spPL!ABh* N#tncK0Cmy^;'{ 1G&"=Df=o/Pg$֣d/ʢZ Yl]*78֟Bt~)U;x$X|ʢ߭ K"hz!8F`hpU9dMMw!pfHeH:K].š&~ Ef}A K /ܠ VɅ+k,پ @`ޠt V9DTrzCIDR=4)W.2ĕU#}<@Uap޺m/|D?"kMLyݗ <ᑽo5>CQ)/Da>ˆ;}E39,$4A銟ЛΑ A{%]t\x%Q@p+ p2=@hO]-80#lz 8"p`|N~bwe *ֺ z(w׍ +J2ArzܳGߢe߸uG8;b萗S&6Vc+揪9::mWoyHΞN>R~$AjB܊ ]u =%Ɛ/[;KYO٫G#ʂUP8HH59_<\p}V%Eo\Y(7}<`BRa6UUI.:MM("8y aux8T,SkH2~UƥbL{9]ueF%-'Pxe< vpiBJ6ɈdZcN^ތ(`W1)WBlݔꐺr̟(3|XÖr`Gx6G%y.s$@&1מ՘FKnf0$ !?12O!~G:T0v{1-Б700"/77G=o~1X:7{2,0R]}_' *e 9ACMH#Xx2k7V>h?=] V'ݐmN<)!ʟH"9dYy]*T2 #RWi*aΔ4-9 X.pKƟ{r~]_} ioakV6E!zU U\I[+ opb!pKX}z $!Bst$ IM4^ 痼iXd88ziACV%9RFRJ8uˊw8g ,T_,X)Î3/C:NdXkF>ªE1j,ZЗKMdM_Ug^3F]ƛM&K-hS;yzh0&>F칭l|*YnY[ Ks^_2o:l{t"/؞M*ADr#n$5"(]ë;AXN`ţ,&`k8ĭJ^Xt[/AR?JH1̷ψWh/G&*5V&.\=eL/N_6][IP>L$W|BDdleW1bu*$kS3f-f< E|shߙ6BjoOayl1/M6lʅ0pEA78^7sRz@j,{"CqG.> ZՍX;%y_@g&G);]IP zUpPn=JΘɑ_C:p=w[LAgq.cpAY!ȻMxo*T\'HGli1-#B#$7SE+ݓmuL5IT0{`#`n3i9(Ҕ" }nB{\bB>5SVĞQOՌ똆y GAO6rA1Džva9C6j 3U)Q'#bȋ}Wi@|/uO0Nʒ]/&IP+1doO{HLt10Mt:c1[1aC# +Ks azikk? jO[9;?{ 펇91}ECok6_p>ͥ #|[v%s^jO"dhzM<ɾےRxF+&A1 l<$J͒2eg=QW #YJjzƯ+)T}, Qɗ*|ڔf-~ ;f|Ќml,U, 4j<9BCNpFnR4&OU8;+2f9-R& d7Vp#oz#[A;vX[LSkC [fS]fjWI# Tx.y9 I9.s:Cl4uEV8JyKD¤ItY,c7>WZ u9dkBUTo,fҒLkZGv!"Z{30xMm7SzQxrO"y*Z 7$ HmiLm^;eN>LRn:-?xՋ$ᡥy-?ݷ JP^@\Ym7TI&C% e?^\LϴS达 Ζ}ߕm`&Z2!Lxb]f{N C)!ڑ$ pvg 5C4]8E>snsוf:["o`w>= y4$X\~ gZUYl& I/ b- } \%~N O.gkPȌʒZ?Ÿ/*0!Q* ~zOtE$@HLj1]<~,rwd3Q9DŽs'+0A@EFяY}St6<ΫƝRMsé )@ˊd*<h‰ .RMcTkz#|A;gs~7R9:XP!&bJN̝jާ-1#w bp'!U-]RSeWG"!]aʴfp\v [YB&L1S!{i dZf?. 3*ncu ‰fBU,l8͓<+"Ui9ov4MR]b1T\#jBremSsd>xgI.& e8S)$9Iҡ ` &~4fsҀk g]d]f2r)lLryJIixH_ϊ/~Kĩc)YraZ&sKW2yWI²wgTD )=oۤz0/B1P.VCЗ?K|C g4؈@"vh&fNWY; sn1FP#ìFmq_!*9;) i|p򺰦[D{4`xݽJ8K1|ԃ _D-*wGw3ZH/t.Kjn~8(훌@̇l&8S()(B$̊_s_|T]W'`Z ~hKvD *>VEp̐"C;W@9J$~{_ŝܡD%Z)Fp τD?Li& އ28ݽbCj5SR_ $cB,BrHX&Nľ'^2:EXlWvt+FY+̋^grG02Yo|MM!-?hi[<_<"NUG#ښ{˓*Ca@ 9Lr;#>Ay҈-M)9sbtc+ؒØlҡŚ>0E*K ($>ѭuԾnhԋU~p5ewȲT?ܸ5: ׯu{i9e*q/uNrPJon vQ1qN%*>#E7 mRǐKT7,E?I? &$(?z A%M:uDGR;b/nsY+Nbw{Iථ{@KI&iLI Iȉ ҥ5i-VxAz ~o%[)ئލ ]3IkpGJkdyIC7T/=8?D8^ɥ}r^4OX*jL{}[¤ۻuu^onttR^XpU29q:J('Pfa64a&I4%$e]TެVثTvBzg(*Od߸F0'-plV7oFL' N?yiz>FK$1n԰ptGgFv 4CJ.Q9}.2X03쫡CpaFpyݹA#{Do/tXeOtusQ1$e; %h`# Z`Qs\-o HF{wr ۠;7h_>Bɴi[AKBYQe;ƹìq7Zڀq'bcUZ*GzXXueKlVuPqGU|("#7ƭ(0 NYϔvlP1Q;%~ׁd yv'waX4U(`T+ѴL lCH_+{[Eg`vS|mRQ˾E϶-$ iZe *uM׌x>^[ @ CuKp Dm5]54RsOBXIA~p~{\zpsP:HX" "ΰA%t$ "` K9^ī8yNosՕUUYOMq{)k ZUD=+.\x_Dp|ʸT\1V Ŀ2<[.ed)05?0;>KT<`~Ѻ9Ky:P) Q֛h_j;Z±T. : .[q+7n=mZ͝.#w$h:jLK' 0>%Rg|a' s-QU_|Y:$,|i7B(`;2s†v@ 6UW/#̉J;4K$6JJ 0J$ qt*%3.5 %nhY !7J_^0C̾y,x767t9N@^'hDt1 !5{^0АXV6$C WgpQjaš`M'fnsFݭiG6W*:ywBN\ Ti+ZtJF0nX>WH)MAë b_sƐ˹XOC>1+CI6 =?]+'8j-9~4:`Z46!QJ:$}}%5#weIGU&YQaV5r]i]ysSi-۬'oa%h6OfuFPk& B",)dMfBkE amKpJ`?p%U6ITBz.,9BHe&0;,jvEE_wf5e=K_¶Hl7[hs?JX4FcO <&]DEXpW ڷ謯yc~HB'xy4whj:r,ɪ|NCYؘOYA&9yH/:z^B G>Oᔟd*Օݼ/*p{%TzU nPciӽʯZejM >H|iSHc9o1 y "u[KA4 r1u6uɲ C;@^cd *IxŽ00L,4m1JP!Coy]{u5lC ѨeRҶ dr`ZPgd#ih.HԹIq)6ÕƧ\9-u g5 -7DqH;j<ey 6'89Hqs/`P` Rۏa~.ѵnj)fM7o7g8Emx[QVcS]6}`χ[IXV}W"]*z4KYKoedw 8m4ЉfKhLΪhlK?iDpXP~M뒹Y;L`V/ c"f65ذmHNҐm1B:g1eDcJA*> ־+z_(DX0*UwErWi鶣F(C&j LZ7ې뢠=g* \1jMtoϛKxul ߼YZel?V+e"%"(VnuUv! ;hWbM &hyFA(y[QݏwH_2F1=:Y).FO&* #Kxf9/F.yI}ϖ i TZĿG~7wS+ N8ꁊO')I&g8TX^B0tӔZ7;;{2D{djbX~9'Lㇴ.f  JE<QCf]]w/m-ۜGiLje\)PWo*a[cX\syBy,>t'lp Lx:Uy?͓3:ߓG Ԝ9{4wJI#y[~\"C;n:0sMQKm gK 5 v%rYQoz$)|y+h;틎Nr |!! >@$SQ$[b5 @'gX*KAgjİ_kBRc+y搓^O9̦/U) m1L@cz&4y2'U&$'ˮ1#sQCF2m ^qXqVO0f Q({2&zͫ.\YxvB [s!\ 73~au&ОrMYbm÷`( R$ϨP=:%hWڦsBB7C6CP!l[:* pD+1Grg*☗(nE涢B=]Zmu*";l.d5d#CMBߜv f:ը϶qCu iBiS&W{!w|*!{ATczx"KE1 PәC!`0hk!i]ߍ%g~YcHt^YL"f5e3|Ŀ@suAmpBa} 6X-<8S9FCWa/L=d+'$FmGgBB#[.lO@ `@.Cԯ N n _¸@RtkYq(6ݣ7G{SSrhp6¶o{ސzt/0X!\ k}@7n_@hHX.:DD~@`S/窴 ^{brGļaL𣥝\~qFj &`O:4ɐkJEܡR&b1g@}wH\,V&s3GP{xv3o@*BȰz^}3-֑D,Ê>MQHH^0sJfnؗ3g߭=qBH0YP:X-DVivE$d7 3 N3)A9,4PQNMZnxN wAOBnn4 c7_.qWƒi2]ۘEY [ _H{MeD95]Klt1%#Ṡ¶,su2jM$-9~n  qD< +`uK8 u:m<~DlRm3Z,1;籣{by1r+# f:(rGfyQ"Зը.Г ZU9Zc`HWhs4UuwH`\_8i?8Pd m6=6)gDy0))' pFאY籡rnI;ZIA1-X *_IB!ILϛ ыTyup\**f0mJ)[ ;+f|!u)84oBRMYYj4ΰ:ثvޚ\DQ\S#l1xB T!VlY8'%fVLi;v`ƚU9%oh%:v+$ iuiRq4bwB~&:׹!Qv }qj@EH_}X Mݬ2%^OP?0d5D яN?ג+`?^v%"ZFߛ9^4.Pnb+m}ہ/&|" H0gQ* $+ín74 g;^wm!DJCFVq5G1^O3o"Z=3ոNxF[4W*Wy1+ CUrXo[K92Y}*DppJce |ûeەnfmyH]Ć/[. vwW* HdDktƘ8y {cP/s1 SO@-F+iӍ![PPtsRNk)6Z@(/SKk~rVE M‹Mދ\P#?xE=7Z|hbgFHb]2B⽪Bn;hܱOFs 4Bq͋dq{xEfZcdKxpds0`LRP[a |[Ơ%KӄT%ZѩSL *zd+#5"/v7>k2SFg,yzz[BJS]plI #'nSXڃ#nOǬn*g<2`rʠe.aSulsQGpNKJzft@m\"7 [̚vs&Arl% I.$HK;p͹XHS'ASmӡl4"Me@-Z]ϡ|lҊzT<>SOբS` ^GF ? G~a;ߢ.U2lj5h(#=N- =ΜӨGRsNڥ+>HqV:rSQ?ˎ $ 3[25C>}:sT}cżYW!HE8?PT^̎+p!%I%Qey=j:D^C}T)vwN|we4=~?7Cz[<֙T3?'Llbx " =,)'f w5L4^J]zf;t'B`OZ}qTV2G(xH*hk,i1!O!-6_B=7&K#NBgڋK$M ?V%h̽I KX6#}^NU" a/뙺x50U1s;@:=/3czQ3 X{o=,=";n$5A"[:k[zLeW4Negwu.ogQhh4_(@$_Dg9bCvLvg'XU5'aW糣ʯS+΍Ku!QxC HS1j_HiQ%7H Y IVim\/=8x $q"#ױ3 [ v[Yܠt^ S 3~VJ5@sy_`$4>G扬lhD/C[2$C͌TwoǢ*Ol c= ͍n}2&L'.]ED̙ܗo^ 5ѿ>pVI~60˄~V!y6~_Ч;& ?$ @w $³?=ΩnwIj=0`ؔbWiO.N{ /O\wJIм=P,Y"Y.͵{@gh:Y3YI?d/4^`6n%]4<ٗYrbΒIF(,pca~Hhj)[4<}1}x(TUN'7 dB#2mJPf 8C mV469T? Nn!!}0W(pJjW#E"ԣa`D&CF{w3)ScF6E=g~KBƫbh|% ;v׏ s,]֓NH: :3zhż5GZ( 0)؞P%}N>*#@ &nmWGC_zRB_W%Ȱ5>R#Bu4'% ڳa&x$Enމo>E`%WYHw,+zMae$X&VM3ۨk./pY7jUcd@W/<Mc(=zN2eӔBܷF$9˳egH՜>Ifrxmn,%iX~!>w)ttbV%ưlk+yYQ/&6 ?XxKBdIč_Y.u*&nho۸X;'QfF= }L+cdrflX=%<%{XrPrL{No 5&XԼ68|%;x_ 5U wNm䖧ȷoDf4S A Oԥjh9if:ol7^ ě8$&IMjiL3'pȎbR ,@_!Ҵmӽqq[d4p,FGX1d5>=*Q3[/tQQH!(d`D1m\xu_NV-Z|hOTn~qH tU᷊)dBi֨Ȁ>c>uFEvxd̘1A.xotRMݔj`e^.$y]:"~̸d5 ,P_k4֘w$md($C,]_*zҾcf8{(\oՉ`!Yc.F'َE2<$z^;@(`Ɨp&Ukp]6jEA~r`z2 3]LUuRL#q o.>^'n v1;` ;\%AJSB֪q6ԅ.!_ް(IwqKTÙ}rn-\}Y樜'_zY<~`^ypLw w;ri!DU%{ :Ȋ,~(Oc_/OpOz:⻓*V?h%rR+ye%YCgb#%_^;m׵VP@yedN@pMC|͗wH"~6|;!JfZiA-2 vSp=(P{z< @D:qC~nK:fGJDzhq&y_L4k ynyACQ-/(M8F!3I&HP?a.W?CGN Qmms4*4 X* Ovk9Y7Kn+Y:]9z&vpr߾dHqȾiƯpO;) z-wwhk;U BE=)> GMCiV3!Պ(K '%p7L[H vЌ$(BdCؗxczxWqur#"bb I"O/Pgv8qxJifEĹ=-sǵK!0$TI<Z_1 "23ձY 3bJk-,׆iPC[az&O2 Z }1ksj*eE‰;S du4*d@s ;:='j`V8D ?Vb&YЁIab\%5Sd]B#\GtO䔽2aJhnF\@ꧺy)XE P\ָ endstream endobj 88 0 obj << /Author(\376\377\000J\000u\000l\000i\000a\000n\000\040\000Q\000.\000\040\000Z\000h\000o\000u)/Title(\376\377\000S\000h\000a\000z\000a\000m\000:\000\040\000S\000i\000m\000u\000l\000a\000t\000i\000n\000g\000\040\000s\000e\000q\000u\000e\000n\000c\000e\000\040\000m\000u\000t\000a\000t\000i\000o\000n\000s)/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.19)/Keywords() /CreationDate (D:20200205134106-08'00') /ModDate (D:20200205134106-08'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) kpathsea version 6.3.0) >> endobj 2 0 obj << /Type /ObjStm /N 69 /First 535 /Length 3124 /Filter /FlateDecode >> stream xZ[s6~ׯ[ݕJd:q6v.Zm6TwJ$eˎig3|d3LE2i$Kq¢H2ps,1KHXb(ƀkB>N3~e-sUlYd$VL<5`, V&TF `ʤN,3cfi46@a53* L$VZ[f d*11bV,DT:f,X.bY(Y.ycN s 9;q!"Bx&OiDH%J@/G*( f3@  Ę,f zhJ0HD0OLV8d70-U<|?{A뼘c$w|P>!ȩQbJEJEMEFESys*|ݼjI7Ub-Cvʷ|Zːv_Si&[\\OU*{o>%m>/Ӌl:"0e9*vrMtN,҇K JDHGy>'_hJzz?ZY>8E9J_S$7$иf')8KF"VNP=bJH!ȑTv[P]1:y{4θQL5_N=2-$Vtr CҾ*ңH.H[=}c2#?U1P$eS>'6uZ :-vUה/˲ezoKz+qoP_gIiI9J*oìM.N<0d9J`19? (TezмEhu[ )3XƆ"N@wPLn#9."tZAOލY:,Ǘy 2 S35oiPJVDdX;"/,evFbgͺܤISe>؋eX;]4!E]w%$5jy:>Vw08˪a1Kd>.&c!OǏ|´w4+p=Uv\|,/+meQg켦 #пr~Q3uy9^Χ^Ig,@!x STyGH윗in\/r9˚<)8녩=0mîׇ,gbBßΰMd3j悔ߨ55,ju|ݶٸ>F-E+ ?K# 霃_j1fd2VJ#'Nky(pL(z}:ԩk])#j1Q$VA hd$XS6E +(h <6MpWFx|D$zzCb*@#6PW›bMZe Gc ӧ*JH /q$8@cT1@rK" p8'Pߺ5A *A/b ՞.Ea Pؑ^5HҴhKAo 2h5P7 %QhiC6"_5g?|͇I,`--e#IOjhzxBt)Dj|ɮfnڵ U]~+Kcϣk\' :(!|]+ZlBFS (DԑTh@!p:T 34s21Fv EjȬ{u({4 &ݧ'}c<=|8"4ԻAPoJtcwU2_`ao}ޫ|v7ԑ Qrן%A1+G*_>N?fesKR0JpN~l*AȐq|#1/yk g)6~wk0XNrJ@^Dh-:VcE]VE]m]h̟cg  bR><?.q`e6rkpv /`B$y"+b[eq׾deCAWob^<}7$DJ^Ş]c #$[P0Z)/瓬E!6_z~d"aUW"-&mq[dOG?KxI_ϤU >R*ӱ6j!PcVQuShܽHsw=wZ}޼}hY i vw7>-¤ WLMľA~g<B;mGٰރ֞}(xep.쿼^WR#8GcD U͂Ӯޯ}`G|M@7"qZXe'p E6hq\d|-C71t_eHf;s5Ogvh/WjrogYD<'eiyK0$ ʾ`.LQ+6S'ls І\fS.mYރ\[w'bMhcq=}!W'iR ֵ/V"V IxDfJFw+d6*V9TD/7UF{XxXH hx8mky72,ϬMjXt ?maЃb<<ӲޡO&I >vK^בڡ{C-B!E?gy1atSNj1&odΆe_}V|>L=Xw{V k5k;]qZ=q#7brWވ0U~"Apm+lC=";(&]eXdG?`> endstream endobj 89 0 obj << /Type /XRef /Index [0 90] /Size 90 /W [1 3 1] /Root 87 0 R /Info 88 0 R /ID [<92433738FED75A878435BDD231E41759> <92433738FED75A878435BDD231E41759>] /Length 238 /Filter /FlateDecode >> stream x.aLm ՚ZTTi Yt3+p6܁XI\-6ON޳y%796(1t@'tA7|@v`r6!@?AV-Z4jSew1(Aɪd5r  LZ+0UҟXl,",2`jijujzT~|j:ɶ֝>Gm@ N.|׋Ai endstream endobj startxref 190143 %%EOF shazam/inst/doc/Mutation-Vignette.pdf0000644000176200001440000061435613616633160017361 0ustar liggesusers%PDF-1.5 % 25 0 obj << /Length 2205 /Filter /FlateDecode >> stream xYmsF_ij_s:N=me:wMf-]X,%8XY @̛{{-'XE"7"H"ZrozW ,ڬ%)Mq8t dN1|c!McM"7%ECHQ "*`c&,tl$WTe fG񀫘>N{in) Bwf*2`JJ?5kE2d9Pު똇B?ʼ1A(S6Y; Pl}P1ˑH)S3Prgnۍ4OVw3:!]!q Cwzuws-[5n /Q_a!4*< eyYf4Z Tf0v2­PzIUűX>\( /7]F`4NBV ѡ_T&ٙ3388;Թ&_GPR7ii=7YOo=iAV؎ gKڔBtYmh0 axlc 8% ֢c< [`S.”l# ĊzyCrVlRG= րS0~D Al]ofC 1rNRdoHм!iMU6hs4Τʊ=hu3pne8D*a!>YBp dgv[=%Xl3 j;pS<ؤPr˓goӾ^`ޜN..__v2 QhG&H9d=vD 5k%D-WUz:6Mi0Ў@t|oZ_צ?`6`ux:'cG>fey8骸*竢Z;-;L'==)Oc_B|Dr"WGp0{72A}_daqdW|5Hj^w5aӞTr7y_A>/Ա,DzفM^~d#:W2xf!MR.͏?R'P7*Sav/~:;"J> GHF[C@æST{}*ѯ\w;¡lR ۪գAxp)/ 68m:Y@zδo ث&/muH{oy*\mִ +H"a,€iTfY>V@@<<#(%rre(Q(i ̳z 7s (``=Z$!Zn!! MmA^ .!Chs^IfNvsPe$[Lk/nC'I%x. v0qd<&a7+k-P nkiպX6]WT2S^/KM[/r|ImH*peρdG;}6 kP -z(ƶH$XwGRcǬG@'w1/H'pS?'(H֖n | `evZoմHO˾Js]6mY 6W"Oş" endstream endobj 42 0 obj << /Length 1135 /Filter /FlateDecode >> stream xYmoH_RU . RM7=ۗ[w$Sk.6PKR3ϼh F 6=`#@675y5dD$2u%1ZɃ؉`m/VƳx|qCʥfX'\$E0p/FPbU,14$ *5~_h:VYN0 PB~fPi㣦[$(L:i4F'P۰9U02L[Ae?C+&ğp L&uSp]1xHL\1LWnMEvUc`F\~KK AYRZ鮓;X[ZV" {ݏ^ďa[op=hp<f%m~\ ҨUA:+@Hj DPQ>Cm<{x6uWA@ PvaJdqfK1jOE5=4sɠVwۃw/\Ӳs?NB@5k]<; 6/N惌S.{8- ps+t n烣FG ThSfؖ”WR &n*3nXs3U.odbhvc׿mM&hBp~UrR>n< "e'ں;D"hvM&UpѳQ{& oRjNr(]8]ۯ)ݖTӺ.kyRbutVELVK.F O1㬰p eӲld2slGPL6)ʴ#vjK\٨ FdڕІ 8M*?`UEKOS?@W"Z ԰o2/{=S^T#\]da1 t?Sb/И OL!$ڇ3Kj]wD tD=%5y|_;63(dDz,4zgV80 endstream endobj 47 0 obj << /Length 1564 /Filter /FlateDecode >> stream xXmo6_!_d,V7w+4SK7]lӎKr%9wQ$6 &u<;$"i<Ӿ4{n`QIZ0+ m5߼i8}{~;Ϳa~rs>y6ܻ~@ޗ?&0s e}g w?Qbጣ͐ G)v=.oXd,2RRX4] -Bfr=s'Xf5[,Eل{)Xr%yŖH PV ̅֙q3[rB86ׅ[9ĈIECH5B5AGp> g F ߉G&a6*Q'֧CCV__/ @Ԃja ;C8Poݣ(I:2]u?,iϩQe Jd_ y?;ZʇFn}~;] iXw\gʸVP=/ϊ_#浅>h'vC"^-++$L8JAza|3h.2(]^d;>9a(wW|E()ÓOWׯg"KaoNgΔ(CU7٫8ۜACĢg^y`Ə>`)pOjVMLТi{ӗ 'jvyT7iU3H8~b˦b V!f |a+6 5H@A3dv&E;E DVA<%-ު ͪD,&BU5f=q!ҟ+]7TsD#qtf9Q>[JDiکi]~DER1AhCsū9$:CR"mtϺ{@c!wv` ppn5ɥФCx:am# JŐbRuyeM% >] ^7(-ttf#\a<Y p"ma]9e*lYMH81QeTTI W:7ؘ:kft[Pd9!һCZ AfyԓY7Ƈe5w|Q-avfT9'#Jz[|QHw|\,=B4dTCoee30q-L⢌Suo;jQ9^Ui9:X52msצ(sEeB闸t&} @E 7/)'.7;:+k8z([MS`h;/?>!~ endstream endobj 44 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Mutation-Vignette_files/figure-latex/unnamed-chunk-4-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 50 0 R /BBox [0 0 528 314] /Resources << /XObject << /Im1 51 0 R >>/ProcSet [ /PDF ] >> /Length 34 /Filter /FlateDecode >> stream x+2T0BC] 2UH5Tp T endstream endobj 51 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Mutation-Vignette_files/figure-latex/unnamed-chunk-4-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 52 0 R /BBox [ 0 0 540 324] /Resources << /ProcSet [/PDF/Text] /Font << /F2 53 0 R >> /ExtGState << >> /ColorSpace << /sRGB 54 0 R >> >> /Length 2448 /Filter /FlateDecode >> stream xZˎ߯襴Hf/##1, ᅣHA)dԛEj<%@bd;*x"l7?=S??ھ^~_>^D( }R_~y-l9{sח{~f@s-[euKgy {_P-"<>R"全c{*C/UtX}TU8^2VGGE'=eW=9";<1aò#Pe p=RdL ehw⨀hq^_q9rZ/B󱕶st,Ī fLRm{ j'y\N7$PUiS<֗gqTWlj#& ?Nfl_<~Z'?zq=~𓇟VÏe:gc ? LiK$GARmU"ߎE<=HNg.̮:q;#Z{,9.b\}&\{7INg.=M\zޏ6么^JsqKfpasQb ~" V`,8eb'yu$`}=lnպwZ,8e4lNSXΗ#D*XԁKBRmUMK~a GIrDL/v=sNc" ww< VU|O\x)64qg  m\~ I+zU|{.h6$y.\l;^%p{ o;9zwU|Oi-6"M˰m{@ …KŬɸ4! IvBѓ<2mwOsL!-lc1ReKتD=x갅x KN+,9] {yYYWr9؉.,8%4b3~KgiV' Ul^IIh yKrr.;z<ݞ.ONDQpۺ64%'v½$r$u%iu^$#iJ[V%=%-{uI#IS(zKfs_p/\*w3X?Hh zC%fLw_!,.'¦8pF -ӗ|cbԾڪ̎o/%\b?l=;:)l`2pec1\f< Юxpn^o=D!ka۞vr˶gCmlcU#;-'add-k׾_9^>>v>C?NoOK?tb}VߌLO<ϝ5 $c~yˉG~o:M w&6C>Wkh9k̫n_ӫ/%Dˤd2-EB5zo"ðTz_'>^EwTG' yX/|NI w^ -[j-hǮ#3#r K6:47$h|`oH)]_@.][jֵB]~`uGkPls.bUdixK,RW@OnBɻnw ez.- endstream endobj 56 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 59 0 obj << /Length 1848 /Filter /FlateDecode >> stream xY[oH~@27VەImvҭڕ$aeCp{f0]K<\q8ֵXǏѣGԷcѕ1bqǷ 33s FNћC>x44Og8Gl BvMܒH#uny.b./=uf]Ƒ^D35Ȓ`&P ²0ZTpKZJ.M<^f߷1'3Xar8ٔRF~}=:m:DMQW |J9{0X<2lhWWaf0OB=fxڹ-̸&CD)d/.(8zvo1Ì 3 ]γ $ӇdV3-E|uxхP.AHLf$cDPO݇!\.,袎;8gЉ0Zb4 rNPɼ¯'aVG pYU5l&3 8*sh'N:NYJ a&ndyK sSWG vmy 'Ά-˜؜!Sĵ/w"WX0a0ZV>ITELrMQA0ӴѠa|p8@AsxZLty@>Q6eԔШyݨ׻Y~waR_l*i1X]p +pAay?Dv&1”WA[;Nߞ)Ƈӗ_ n9^TEUD5ȃ6)W)g!jM5=$^3ӌ3( bFr*#HˍU=@o;7C`5P"Z)֖f$KGƘ5 H4PZB?ݣ!{M05M~=tۼL:^L@73AV2UF_eNs:%r.gR|OU{36|j_?y88k )9}A b ^ӷo#rhՠCgj8kbL겡?[4~ Wnhmg>O(^oO}w:;E+^:L[hp@7M=|}:U-=tzKl #`,IcM1ѣ= endstream endobj 64 0 obj << /Length 1286 /Filter /FlateDecode >> stream xkOH{~~qtdٗ_ P zgI|Gj;!\C:30q?q?gaOcnWG7Gg'ݞCf]?Ǡ6#* y t,eJBogǃko~w{@SW?q3@6mΧӋi! l"&+Vp%U#iOZ)F2-"+P޸,,24xb|[T]~!2M 9I8jNXSbH[T砬]Ug%jjrĄמ$`D #2oCWQcmAvtsmOfKJa _ǣa>*w{FX EQ:iS긚 ߷\Tt8n$yJ9?Ó+gق,y҉#mj p}c@|77]3U\%bVyE?NU*N禪Y͛א,C8#> GH\OʼZ+tUo~:5"2VkRj;Ll&xg6Mnԭ0rtDU6ck^{55_%xlׁ:],L¿aOwVg"_Џ ؊a1ui;~v^hբ\Ԭ>{t#*f~ܥBR*Rk>8P/M@PyP5^\kE>/ProcSet [ /PDF ] >> /Length 34 /Filter /FlateDecode >> stream x+2T0BC] 2UH5Tp T endstream endobj 68 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Mutation-Vignette_files/figure-latex/unnamed-chunk-6-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 69 0 R /BBox [ 0 0 540 324] /Resources << /ProcSet [/PDF/Text] /Font << /F2 70 0 R >> /ExtGState << >> /ColorSpace << /sRGB 71 0 R >> >> /Length 1886 /Filter /FlateDecode >> stream xˎ7_#v$A )J2"Ev3\ʣS;?R1!ƥ8~xD.: JߋΠOZ{J(wS{YGI)9Daн G9-:dƈPꀚ8QmgN W< 'q6t.6n067@thA8D|`nRU V%MM]ۊzZ_/CYv답Ҙkrregl쾿>ɗ֧H-+aCK;B%I1cU*1̠(QiWA.mSv"f;_".yi5j|zL}䬖9F pgoPA \Wl+$Cq,:.MbG2 {֬l`@h4mf+\ψ-Qsy|T-Rο\Fz|Sgߚx ܑOAa%Gc`lQ$#kDX`|yrˇTz?5:6A:kzͧ՗9;%W>k1O{M/`hZ5ChCl'Yԃ h;y2}[dN9 Kۀs EpRo"6+"IbK {x`G[3 4m/ ehmyU kzĈ[ >uMz&5}\K ߱3Nfn(K}ѯRl(*u8{ztBz}U^_Z mA|0Dt P0,JAC/G0yctV#F37x¯]:B=#> iNlŧXQ{L $hm> 2ޥ%e#5FlRn“]ڍOn-0P䅼>Z_2/B(F8XZϲj}a> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 77 0 obj << /Length 1410 /Filter /FlateDecode >> stream xX[o6~ϯRZo6qwqYa~HE9qbe O(@G [?;dc=WИ&hx=ea*T8M:\a~ɀ+X!L,/_ ,؅(/ks(7U?ªۤz`AG,=0 Q /&'ӱ`( Z`TCA.+O,RGͪT8.FbG2!=<y *\,cIEM.´rĒ&hZNT[03xA3-#ENElY=rgLBe,UɨҝuZUkMK (Xr1xiKw1Ġ<"dɍ\<4bp2vK\ v00v*iV3@U$'&lZ``hvMgfkZOlN&زDP"Q$ MqA-䃲Sg;{_.z=o0OlzHİeA8 gFÓzÏߟSf3PMI^<Q{`Sy(lu.[>];Ó, M.IRIK~RPxFzc c?f]2_i"YW[{لU4A37+tVY;M8R~VMX\ng ɷ /h hߗ}X%\&þ鶧\wzҪ0 Ck]L 8 N=k&rE66E%Om7?%O>ÈMӬI鄪Nyx> 5%qj:eAm:9'N:uXv]'QU&!zMFnE90t$%`-=K.mwЖ ~mP)u\݁䔛WyƺӲ_ˢ@v &bbm*id{I3)7Ȋϗ W6l$N93Q+L[}XkEZ2^H%lXNI\RnV *7Mvw9k2b兯%vW-;ԛlB)gh{ˌR-5\U7ڼxFy;<]W诒0* ի3h5+ #1Bv`ԝk?Z|{g'g+A#W{Q5 (̣ 6o4EM Mdj]Ώ@񲥼ӛ : endstream endobj 81 0 obj << /Length 122 /Filter /FlateDecode >> stream x]= P E;4yy4k݄lTQ ${ 8,W(>/ProcSet [ /PDF ] >> /Length 34 /Filter /FlateDecode >> stream x+2T0BC] 2UH5Tp T endstream endobj 85 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Mutation-Vignette_files/figure-latex/unnamed-chunk-8-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 86 0 R /BBox [ 0 0 540 324] /Resources << /ProcSet [/PDF/Text] /Font << /F2 87 0 R >> /ExtGState << >> /ColorSpace << /sRGB 88 0 R >> >> /Length 1243 /Filter /FlateDecode >> stream xXKo7>q6h- WΐCzHpz.&gJKŭ2qO(T}xW^8|o[q7竕< χMc_\-.~(޽J|7׫prVˬNZ/LH2##<3&bvL@:ࢗMƍ|@4(`e(@4A:*I$G)iLiXDx1J38R&tlI!Ռ,xK 4rh'zQO T@:Q Ak[1cI. JAKn*M+J:uUwە*);{3X>%xLυ+6uhP<Ƨ$i.)`&,TUB|tUl\R,;M)J\լ)T 圚!#vE e4]Q^l V^?No|m}/i<}|@pPVtR~e>ql1-0DisI2*wHvJDDtxۣ۱%粕60*r5]܈2f̍xn9-g0q/6廅*0 1wk X&-ɱݪҀ=c~fCC?h8bڹvֹ&zIwכ~{(pY3V`dxw endstream endobj 90 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 101 0 obj << /Length1 2043 /Length2 23293 /Length3 0 /Length 24515 /Filter /FlateDecode >> stream xڴzst]ulm۶6NڠAcllv_^߿8#gg>{g}NFȈUL퍁v.tLY9e{[#;&f:a{S3=##+N p(|$:@;Ӈ` z:FE{g:c#7H"bdin ݟJF&֖#;S4=@h -lfU&@MELY BEQX\DTT$hBb:-@BMEϻ*9-@^Gt91U!U-E1&?`-njdoW7; 9_T-,Nր0vrXQϒd-Mv?Ip~Haw7!\ԴG86F**l,\vFv&.F.ÿl?@SD\mE]tm}wŌ\߶?*f6?_69!y)q1U:ُPǎ?De&.Vǐٙ~v#N.N 3vvk535+PJ&́.F0`Icfc`fd 4~\༝܀'W8&.CQ.egfɿ\\~ʿ6)5]>^66F@l-m<;B4Rɖ@SEK ٙ?V/ڟ}d13 @?Y4:;r?4a `Pq+H0rr2cf667(=G `fg!9 "L@\#N6;A߈#?`Q߈`7` 2?r,f0 , Y?Zx:Xa{3LAoǿ*N}?ro+io_CϹ׶gϼVqqjX~<,"gdg>_ s-[XÛ@`b# ?'-/؛|Jk -+*$?+הNXΜjC ( l"/K Im%bTIpOILh4O^-(Kn)X:/_u&5@mDw ;M*nY7H9& '4%PqFBԳXP=](Z$ $+}}:'E*1M{zJ. 0+jI5&RT5]yVBd9*8y1uށ4Z{ ļs[PA ʃ+n+է5՗(_Uuga= H06/CUI>W_\9Evy%msbŴ$m0m~Ke(WzJvQ} %}}ndZ6))ʝ|}uc}J(,uB|H %٧f:aF፽ s{(JݰDЫTw D\Y* # O{$n4d9?KLUaq$`:Bv'eI E,N;.Dܚ4e(O$/yX؂׼oi 2>;h_sV3E0Waz@ G0XԺ[f OJ^훭 ^䦯<լWӟ*@?;5י(SWNp@r9_BfK*`Sjof* ޭعmd,j wEnKG镤_6o[`Î a/ pQg x,n@ru$L{JmAp A,Ἄr@yORף=A@>5Ah^dq]89w J>M;a>.mLXw$8Hu uXIZO%Of"/N1t/XϴU9!$IAM\"?^UjyӔx=qN|ly;10i=1@Z?pԗ] Rc a#n-ʢ fWg#`FdGXK{*< Y2ɺcy-HߓreLf?,𽲽S:n[cF~ژj 3~F(gGPH,_wgsFdM_fۺr3Д$JS*ntN$Dv˩DP7δO>`'PL.ʒb^k*zLbwߧ=()گb`4-sQ=TSnԡiWIM6'8xVG m$1o@1nIHc&:mbD1[dvrw1|>vp`ęFʚfQfl]h6r (kt%7ɡEE!D/!={XB(`L;S=n5ㅺX+JM T<$We˟VjYHC:dNg03ˆj uBe ׸?HǾj_`ԥ/*qdƣ s7$ Xj>z M(V}p>7`7Ĥߘ̷pj^|-KVW@g*WD0aBRLRFGQ*ho~UA|~E4(@t NV$$n` HtufN@>F܁X:@M+6ʰ\F_ˉ*+Hrm{[# ՗r LJ~3Qjo\L<|!$:9wlpLQo^%aC G@z/eT,ho OOnLmwRl<ӊ@+;2ZLb<=ΐ+% W5=ܵ*>d͎5\ɥS\kYLJr 7 >ʔ8|8HМv<? |E逍Pr j  ˙V}iݯ1;f/{F;rW_VNEK3|tib ,r\8%]7 9dJ{ `nPs 54r0[(R8ܸc*B@tWùgh+ <*?9d\;3$H0I>Vۦ8>L#5tOOķG;EdN^%@vX*WKm̻kbȇwL+h/7zPn1Fl9uVcDh,h5ߏ[M$Vh'w#4`?HVtT 9T7Gy&[QFiE]6Sv BpPTy{hN(F5c =9#tiwe!QokNDX S+xڢsVgPWLst_|]VV"!cu&`qxUΗuI[n:W_y (ﴌ S_B_{&#y  b PTPub1nU*pG[ eeݧSD8+8U?0 \賖mwlA VXaRNT:nޞkteYAQ?UiytdO0Ź7&rI t*2t d|HS++b7lnWЎ2EyI' jΥ -UW-N`Ų͟3>V]]]ï8y>D89,6%߸p*dAԇFx B=+a PVTYފFA|MM[M/U:]//Y1kfORL㜁H݃}y=15i=U@-o&@FZ'vB_5_(p/q+z%_nGfAyW,R@=_d]H%KUP  ;< gPf ǭ2iiT]_Jطd)BbɲicKx 1Tvx]"Hͳ urɩ<þr)݊ ՄH aɩtHa:*^6A$rBnvRSY?Ba g%R}UpƂiZq+XOZm^Iz_i8Z{V=PdUyI_ A*PdLvPŠ;(' Rʣ F뛹 JLgqFGnD̕290 Xwg gZqO ]Yf/_eZ}x2Υ12J@D@y6NJlyׁQLxV>)BL2]_CL֦I?LژP{{haۙ`z[jp-"ҫO+ײ`a=$' åcxע"7"p%%ŵS5 DC!x! eZ:$KDJ|1YK~P Cr1-/IwۏraK $PWwAz$Jߣm+{3JFwTIy(h{*p0 Dufƻ؄4|d:s#hUƯuI<l(i Rc]FLd:~6{[nO=wV6Ф)5C(/KEoV+kM *k*IYڤ/+6~y hCnVvS F颭Gu͌)e6;8M׊}{l5ǚE_bt#IW \ω%Ǯ'.L_ygIN/X= 7Su^\%IO r+[`߶8Zj&*X@lEIfqj+uHr 1O"W E& K(qƚK^G7g&X<#h(k,ntf̟_9P(hYdaoc A-/U̓?>;涘)My޺SYi^7L'AhIFs3CAnMI; |FqZZ[k3[/KPJ6N)]-쵻гY%!~uG<.e0tdȄS˲S<C f.I/|cJ^Z-5R>c)E0ndҪU GMf#P[:F級Ez |??t-iAStBUVW'`rUwM@ +7rbŷJ$Usͣϖoq+)!zl^@s1:UF_^cPnV젟1^UIu @0]=Ƌ^x*-u; ^O8JxCҿ[!\֩Zfi;JWp7X|=6,T't;8TKKk]$ E"Za=H -Pw A/&V [:O<)`V|9iMgFc= !l8}|7JP @NnJCȮJ2F"\gdF*dnXzǁ\9vXᯊ"۱&Jv,d%_g/YH^z$*6&ν~raNIg鏙گRo. 9 IKg;q悺;Dg~9t֐҃kk (W"|g0#Bs:F'U E"e~P8'N?_ n9,$I*)]a.2K2?[q{WU- Ir7q ShM:,VřsCɺuW u[XB;siPOF*KĆp9 ,}tDR5کHYR*@ 2UB8UM<^2.VYu 5CsVtF ƶY<vn!ӎ;.TEZ*w#Hu3Q!n Nrr> wQ}',k]IMz7Jkv0TJ@<2Tȁ qӫ'ICظ$soY.h(D!Y{ϑskO'Y3lz_O(`3h%Ci-K1ɠڇzNfos=`:W+![W//!HNe{ Yޝeb߶5ۇh*OKj,/Ђ-af;B^9S H.GrD1RTX,-[)CtW[O}Bqs~7[~k@ۘ:fdz)@)(0j0*4%Yx2YI_\򋗥,=ȖSmÀ괔RQk\SܜCP~u$5}6(E=ga!fҤvYvГ=N7QUDzT^cPVvT26zrg-MrpΜ YdCF3=}@~6}f ,ƒ-JAy6{?]9I3:8p!,+ﵜ?IcV?Fh.n ٣g={`]woƖ 6KK3.qsg[`K-+_gXwIr++3񙗙@y~ 풮mh15 UX8媶ną$oв.lR[r@ [g-;y}eKeqamfeZ4m=bB.ǶI&Pʪ{ʹ5aLrK!Q` -ד h̖k>U9W*W?i.dg|۹K_xZH^ZƺqoIV4փwg4H2OZ>Az5*jVv/?զPFmY7}y鯁_\_扎[KiyM \W[]ߢAOXt: q Io8#QUD)ϓu4GiƖVp]҃B 2v){29q#uy}Wq 3ג(|jd 9{k$&(WՊ2E=$:mqN/p]I ]Љ˯"C-$RhQB{]OcNcҋl22SS,ٝKTFA H~1^|St퐅@hc}C(}L͆x&8?\^SP31}ACamiD{T޳vwgBe5֬ɌMiڦʷ_;Q+kI+`$X!=u`!ޑf v|)1Wކ~Ĭf<ǨrSJç4L{{vi_RXa4$RP:{wgL>U]jCNr;8w揿? Ll-rbLP 5cRĸ 3-_Dej"$E؟I '~sӍ#$U֫,~DVRU B0ũk:zvNnG TBDpyak[d.<؀;޴'0u\A 4&¡lgk!ʼn)b$H(7~1 Ve-)%8ŹkzA'yu |%`%F$Ji=`e$ҷe38AN;12AuYo$EE7aaaҘK9~3Hm"BخB?MH(>ʻTqKzH{,h|GG>Եj ~EYXLCLywpJ_$n{~>#3dg7 MHxɴA[:\pخ3E/~(G6)UPg,G.H)Pbd,j`bF_df yp.- BСТ{Rq r31`9g? }նnKnE=#5Aiwt,͵~*lU GrHv݌ȱJ(rK)ej+'0j T[tvZCڮ3|RiJyD"48W|'c/*JƌOsA_aZbOZPE;H&Z))b Čжp;Ij7<[~]=|Z̯[o6nSN'M>jG3:H[|C߾~Yw]Zf@w?HsMڏgn`x,DQdcF^ӡǹ˰\6PTu؆q,m-Jӡ a}˯e}ć~>$Lqj~[NG_eI=58Z7N!c@;=Jg=~|!y&Uu;iHY{=B^fk9ed{rPt+bar[‡x@w_YV6ʔvx.8+[d&bbLDy#N(z?>{ .ru)H?{\8 k"v3^owRƣ.NxΙW X2vI;DͽңN_8p*"&S)*ʱbq]#,tg(\7Vtv_z. Gɘ~YRXBl5Ã֮5[mZ7zXb&daşT{")8XSf2n[5,#B ~8Z<6]f b O*[䐟eL lsBAbTaT^c`P 柎PDXxs@uპ\#Cm:=j]I8BY41~K挻oٳSxR-A~W4;I墊Cψ/y,*5j'6.&`,|hX (G.~xt4˒ )ᆻ3s'9*R{6xu>(wn=QWدR<&f Q0ޗ6i`\\)%iL}gN6(D0˃].V3 _k#b$gɕx eT^Jskx 5TC׍ϝo؇uW)BO ` ]!8q=%ӓ,.J cS !5{'uٙI!Iyp5a<1A,U ݳ,|\%yǸ~w@nu7RV7ɤr aq=d}'2065+Η jOtlËEظ]vՆj6NȰ1$5ĚH]sE瀌B#҂2ע @W:6IE Ja\u8YQ2><pnf]#gx /n־0},ba^8*>"2oIw.F{ uSUpqy' mcϛĚKbgxFRryVZi<Pdg×fQplm}Okoz1; sㅄ$im_`7<ѷ,Qy Ъ65Ö7V d̾{mf(繚 die"prU&B㢧5G]Q1saQ-;?8Z>.DwC4^m R.xo2Svdtv xa!z)im\)0?''iiz#! 0 $bVVv^ \e:LEECH@7jJKyqNEb\X M}ъy *c+B{ѱ\}/Iu'I3!]"-ӎ._hy.ɝēpqDگޟ:'QgA(ct i`=͠ u/(A\ְXx ''(r~I꟪ZbKPv7[d*dw ߠF~yZ|PΌ(0D P}m:&ٲ2iLTGF:/q!ĒE1rQ&|_J`WUc@L?zV/W+H)yj.N4HЛ7 7cZZAwwd ?2>OADc-pJPnߎ#6b3thʻQZȉ=vrD֌r -=*Ⱥ*&?]﩯=fh`° ]NN%qx%Lӯ(RmMD&#P c0~|VAjǿdχOlo(U[NujǻkyxYKbcO]90ZpADbʎ!LnHU|fEw!J.BO ;P'=7xipZ*:&QCLXwEAcRSnWJ<'2!`mvXf@4ryjsT56=p9%'7?MW4c:ĿfӿXr 1[Lc31q:o]KqHPh m8jUy>A&&tAfŸq\ Cu~8`Ssʳ[9F|V#\=k3 %NܾZUIb9,$;s.tI7ac;}9cY]H@wڤ?Xa?m Ԗ‰3@lq3r#Dx^y4$&k!R^IHO| "`e|us)_9 sNjǹO9+q?QJ*W,1[pC.X2UՉF}͠852Y-b^Bp%/;N;A/_`j}`q Rv-RvR>8iJtץ< N`0#BDT`V4]ˌ6L"D9#XrAXG/|OFBhmך;:`, ? U(^S+\/:FeH;$"E1_4 Y4(T:ƠQhP+2R2V".~X1/&ѵRCWlwKݽdNF ,SU)k4FY3/=]]ɋ"ʵ!+;5`H b$nmq jd`h; p}^rO i5P"㘷edUfՍA0hjKNwVͶH`<ɰAα)o/eyˠ8odc/b-,50הܨun8tqU% Yѝ:˒ND')'?v2@IY x7!Bҏtǝ ls;FP@"X ŔmsnCN(Q1( PjsѽnMPhGcA 4xxXS$%l cv|0G۴\0L!uM2ಙW55Z[!#$_̀䭻:*3J{sAʒ%߉f&+6x+;nK}ݒ"](Vv"T޳@dKh6T]ߞcp,-| *Jvi qwm{ӏ}tu]K#4X ۶32Cyf@oA,෱b++'U@5$j͓p$.YU(˕929A\s? =kՌۡzTc ۣQ< tׂ.b'4>{_/UM0VbkakAfh}FicϜi ɖ[< 17bb`dSEaFNTE H |1 SKľ^3VLMf#"C"& ,/:Pjg-Ʋ+v׶cL'%vZx㿥hp.ωqϲ>±C\{ʇnolV1OiN4QvP9„VڼZ1P/#55Rw[3ʟMX^X5}1Z)ܼ sV;8"c1@-tF_/8RJBYVl / E7h:CtfT.FPVM{`UP%9؅ ?S]A^u8C3]ʕ_}1d@Kލԩ鿒[}w7zy=9(hxY(G@vBAUiikdb:"3?]R(Y@S5ug r fya烑gI#&b AL;)?`)1"K|'Ao7#R~ XpN"YW+{8p]'o!Cӏ\kb PuKp7W)-1rb/3^K3@>#nVW>uBL:~"Qz65WgV b*ls2"ϧzB+6oW?K -LU֩.9 u0aUuP$ڴ p^(Z|+aRyoruPÄswtF";.e~;aЋ}8 bM!)7braFdγbZTzܹ&>x @y`)Uu1煩aE'='ƥq_+I[>3Itq",KZ-P8%f& TH&m:Ө.6S1¨a<7{4~nJ-PR-+兪7]k5mOy%̇Hqa}g[ Nn˅.s5EmΡ v*g6_h G٠N1{׽/X;ѳI^MY@}h!&jVPރY$鎻ªe|B)+~yëM8լ^ؓwEo82pH|'[8fjT7Oũ*oKCǖML Jp#!ʛ)*bla.X'քsž7 HH}k">}¦ ؖ}i5!bUK$:|%b/(9w#F{ϡ?bBՕ66J/2_ ft[; nj֘f|y3]am6 t"&e|RUS.-W#NlbP)۶FET_i uYQNΩ𠽆5/쯶vj\Aőþn2řte\xKIk.O=ё<,rM?m [9-\ϓY?2 TԹk/v~OA`(f3$'_ u2`Oi%Ruu-i!.pRМ9?6O)JVᚹD+XyS_J $gl8;z)e=^5 c .ʘS%W2 sb@?ƗQ6,ɦTƾ޴Omq2..j;FI6~)(U{veBt]iG929c{;#tQ?gŢ+kniᾳiEܲQt}W;H~V(-? 7ⓣa4$Pcҧ\4^T|q4ЮLc5g҅e}y5ZmrkZIB/}!9t4e7p/52O ϻ<=vn#ijЉ %jGu<:+1п@hK}*{AܦwV q寧Ёpƃ, W{7`!/iEyYUN50v@4\r"|o|nx\z凁G0^aư(&W:w=6cI(Yq}Rs7wn}&4^emW0ni\ 4Wɴ"I]ADw8raas8L''oZcyvM Kl@*{7줤! (v=<}`c^bhin~1i3yV?IKX\ȼoE]yb7O>P*1 O'eeENXt"Tu*A_KRFs6t @ ۿU \&UN"1:>Ϸ*h%*/yB %cY|<X~tgcd,IY˜ѴR-9&y#jȧS$3Qʞ4J'SSmU b(LbÇW i?(=1۴* nv pR/[ь[d8L:_c{~uЊX D a~ uhhZq0@OﮨѮ6[s/s4"]^F ~N8\A!d+,uSԾ@.^&ߍ&1IFr={om~U;+(Yl3f^e;8/P=l24$xU9mD=os +d{/0✣#&|cLQ"{B^ Qn.ńR&$W֠賖_Ll=+^\N̓.oB7X fL3_)Taq|FG6|Dw\<8q(Jo:d:MA"isffhHPY'C1qJ }6 >OǛpnu ժgx_+!LƄYp\ ˊ .]-0Al}&(z\HMpjbd)5Z5;Ae 5ˠ_[ *D6 qR]Y%>dhiX91\Ho=q](.nI *|_SC&qSמ|@"̑DO'e3qmJ'C8%>Nnfl;6Bx?D}E"Z{xUrʀןj ^n#SvBzdXM!*,rP>xtڽ1- P\ l+Eyܬb\M>s^'t_` 3⏉!4 Q=dڈ``Cr> pl`F{ }o(={!6=ϱc`;s(X[AOuRmDd*$q+V٤:b7]:5֙ƟPeH4^L T|=Ff}W|5ߗrSzr0²$7n`Tsۀe~ G|T8ZEuRxO05UKDZeյU@^-AYٖ_S,# tdhg =ŪX(D0dzR5s)o kid*5TC"h阳mYpg*mSg;IP/S}l%*ZK~_<g[g< |f+]BLa֏4S` > stream xڴeTͶ5 Ak ָ@N @pw Ipww4sՒfT5MҎ &6fV~+:ʉ@E%4Y;:H@ {!Pd@9hz:&UGW+x`iH8:yX[Z~`bw83@``gVb(;zZG)h452*ZtnNN.EBCSK ))j3d44:[25+IiiSbc tq]QPZ8S@k9xxx0[],ie pt_]vqs0 +](Z\hM ,wN\(ceO"t0q0;L@nl_9Ϳn..k(˿/uqGpgv>&c&n^im9:Z\f{Ϭ))IKih2)ρI3$6>N+xH%]~'i `a`n[{s7'-kg7Ml@t?Y.ϼ66vrtXع}-oWw {? uOv9 G߿`&?C@ϣJ~N<@ eGx$hy=hߎ&v_.:li]MkU\df/ie_ޖLZ);ciftup+ 'NKV?~Rfv.n'+xعl6~gX, p ptA\ߦ!n`x,E߈"Xd Ωs*A*F;E8,#?ܑoF&')xOֿ=&#.xbo''+ X_ܔoaoǟ뷻_ .A0?tBXy:Y۬`ul`Al`z 2[sSWl`NN&hG_NL blƝ,#ll`A ܽ9]\}NjJv&V%S ΁y8+3k.A^ȁ3y]U?O߷?#n5@.@ks[\L@.Yg= ՟khqqL&v> n< <>k{|/}@39G3`O %R0T|Ge8º Ћ'$sȁ"Mԅ)_t^֚ǯDM|| QĆs3K;ssNe$$:c^/R J[V`,.LC^Mz駍Cqa;1w Dhw20hזG#AQZh p<>*@@&vMHdףO.0Bocs 1 d'k axX5Z&wU cMH)!0~Th (C=#"V2kқovrCPEYF+}ocLfEmϼ܏U>a=z=-wft<2/(bcXxAn`Z[颁]2EwJ?^ asIv+#x` b$̽r2J?~w>Am0PqBݰPߏ^zf&;Tcon$`@,XM,,J7ұM5f9+1J?x.#jv$hҿ- d+MQBMG F%R/|׹8P2vXx83iCa=8A65w,7EᏴ{Ʀ8-Hau V|u3ɪDٹbY٢X#HM bJұ)[O!R3s dM&2_K9~9G|zi y1"ĸ E{2JozOvڇnE0 <ޫ_2`Q,i V*@VKh݀y C xqǧ=P8Oq[:Rat#@Yq*^$$Yf/g~p1n{e s_"r|MJ7}UvN)dl|1=cs*A} V&d`d[ri>!ҹ$}|NnGrkF:+9gBz[2f:~>q|bizc: Go;j>/|;c1j7-A;Tx)y#4Q ?ƪڊ@9c?Fx`>:͉֕㼕OS5moBEwr.qӤɩ!#=,^a$l2QSWbZ%X\3(OQR!}oqzL=)"Jt$ٌ-c+ U4+Kyas, ggF(=aiKruug7 ? R>+za2 Mֿ `YWX'- 3Pl=OD X0qHZѯ4nyMP;5,Qzs>^BNw4;yHЉb)[l9H3委{n{]'oq M&V Ը(+j-pT<ʆ+z|[1'Т\ʏs Y/=i$|=Q‡3cZD?0Gd0o)zq!xV! ]Sk#W2_kq bH =ղ P>Y L ?Z"0U]f)ioNw;iL T"8TjBK6-A€GɻKSrkrKe@qfAk폏+'S|bMXM{__i]0'+J}s\6@^4vsOUj 7q\!XNW>\7Y c bmQLλ^9_:t&[" 6$E1Z,- ې6x`5@ _)bI]k]x~FSQ :GOzeɭaS Ќ-vx2jz&Ԋ)G1%C]it.}ެn{RoGg4p;ν. .%fm+oxqC/S~x&˰rC?2P&[jkVp`P 5B/ڈS|A{T=ڡ8vvɓ"G]_-Zh{@ٯɈ>Y-鷣}b i42+7sjU<-e3JT:c7פ0xxџjX ԿV Lq{;*㷎#|%{el1T`ʍBURP R4u ݜȬGR+[zT'j󟥹:R@1B9*!C U|RT l߭|%ro4@NtM^ dGZ1g/:M Ǭ˫ZX+,hŸ]%뇥7PD4Ē9?Tԫ[_ kYܰ6z,b_9$2j6R}5:b_HIn8tO.p}K#9ŔO<z!Ʋ /f^Cqk[쵠514O#ewFTz.Hx#0mx0M.YD 8 -T,pzdH~n7zv؅"`;-w0V(1 FY7'\oh g6:gAEHZnU1 j9qvqKDzbcAL:H,Vj$|f.ٮ-Gav}ξ 7%:|f=+-RJ*F&6#x}$V9ĊHewD e)HSn:rL4MbZhئ;YXRlV.X`:bə]ȟhH^dHuE$M]!*u (kOAjy^;3GOIo{tGX k7= - pI Ibާh~Q'ڱ'َ1 6eP(v=\ 1ϼEvkuqv:rV1[ "bk4mgu WJu0B LFûgUqA*#AT-VW|4ֶRr/ڄ˕iL ?q~A٭J x$;-]t_=:KM!ea$;1Vfw|.ĄB7Phތoe>/IjSQUzs4 5TqZ$/&G$~OBQ W2eya%RUc@/ NVcg b#^έD9vSr\aydh]4ELh^saڟbQ  ~; MscIJsؕ 5jA(UK;Mjz|+#mE.;wLj2 ;ʧc67QL4}npn2|('q'3^j DZT[IH㤏 ˗=Eu~}i҄R1 r,YP@//mmٖb?zL70i@6&ևu*؜4T٥BTrx@3r]͗N&Pc%uŕ1^E ~M 7M=gD4 !ܠ}tV[>.\P, FI 6Yis6mf0~f0 ڝ̣z($CḴEN+*[m=]@ɀz:qWuϕ[2W`oSǼСP]ͨZ[H&#QHZZ{e'.y E5w ~7!*dϯ-0EL'0mU$OY@ ޲2 Vdz,׎\xGi!cۋܓmuVS ¡,Րuc`'z\FdɩO*?aDIyDta,ۦͩ}r BŒ-'Vq4MntH (X?d쉭bi_}q*I܉o>_85h|E&VH7!FѾA%dxꔿjxQAMۍ6(He) πIDțXNh_|yi17}b!f$}Fi(:!>ccTƿGƸ'QE>&9\~qr2x+ HY8Ss$d6QFTayJV.)V[*`Xݭl0wj}\M%Hc8qyJ -Qf)\yE3 .򰵠 h9DD8ڈ@h!Yo1c^֡tD5*g ֻ}tӍAU4L儑 H~O ' ! o^=n[e.!L8 _C6.Y `mjw]ruXEsl02Xo E<)Vt~~8wkS(j/wB*(n.𼩼dS kRu?ANJanIrH45?!LVc&d4n5^vs. 1T=ԊתΆ{;a6 =8IgEňMC5rYVP'5`' Z`--dtEɌ,FJYJ#pމ/afN^K#"-A,s6/o/>T#/9uO,"޹5jO~3}EI N%-яzOuϪ`oKkkKe*CUҧ F4dm}\&2&goʊb %b}tI=Q-=ޓF:a>͹ }kݩ4gr{/*5:1#3 R6'-ח3\ H"mK]MyscOCj/8FO),7$qEXMȞ^ۉ4 _[jUb|1wtK׻bMT'Xqeܟ r1UM'VJ7H3o޺t._G.>u~bc'9=@ǖrC|m أ PP&"wABp,:[Kw4Y8Ѫ( )QBz 1P#BoXuW5V{hFȍ[l/g}-9-? 7j&O\&]ϫ= w!"nR$1kV<*ICȷ_B/ZGJqīE:Գ E֐Ȉ/*,l <0ɏ"6xrBI*8!Og7"s[Y'r%BPRXIY\Ҵ<gky[&95DZE~]xOǪєb*.  -E}nsH"ѷ\T|,fTTc❇ɣN4};/JaKtjXCެ | +p2GmAZM5ZRIo_,SɎtHYmІ?HLҵ>Bl7{C]ϕ4F.moR^r,L܌ns S6'ɏt<L+[ p:*\ЭV9x> *DlµP,؈W~wyb` O&7j[&[|6s5/ kQ,@oHҞUBzD6BhN[ڣno>cxU^}^:@qysV @E♈Gw,K]D':v׹U1^Eli /OsKZ5㵱b0okxN6+pm̘ ڴ{,9* _FQ=\?S#ސ(E }: ^v>="x%Ȩxk[ aQ.SUp w- *7!XD2GhG ;^Pcm>oR~Si)Y\E}/4ffQS*9ńA dlf#z4}( xZS]AEaPQHg OkMn݂K/-ej'7+D uTdF\'+ukO HD%|0!Aa)}>KcZC\ƀ5Yڴq|$hQ9h$nIپw D돖j$pV뺡v9/z}֫_(e~G{̹AJXOƮ泪! Nu?E! \HT9xNllUܭGOfqQ#*d>z18Cd\ȂJ$>ƛA x:< ~D60%!+Տ#!MZ+q;?" f-N BpO5/VVY~zL'bG8&>|!Ue^"vw$:U܉ pmd^\hG'IfL77E:&QDɇV9Mw?u>/Q07y5EN*k>8{ wR#1OsÀ.z H# W,}khm^uM64Q$e߷^͇0e# Ԟ'W4 Ĝ3zub7v ("y-ѹ}LuɔHR=udFg_gPlJh/M^/9иy2[3pyörޕ#}+ssS߷ǁӿXIc2XI~a]Y \WB:Xl])l~O,B@QN6WCl$# 8F}T/p+50C1ٙR4Q~%v}D+8KGGx 9^hO4z8iwD'̨>CqDozi_oЄ35ɤwʠ +}~z'!Y5V(9{y@;$(\/]"moyS9.JіX0rlO=t~z?g6Ԑ Ƹ4HzH˜pש>yoH8t^L]A]|qvhV//&x H/~TE1LRTzE"J+9,vXRe=3]p|q鞼}X1W5A3P:;M ٷvL3vqvôIUfu~x7D-pSo,Lt ;ݠQxo?;Љ; 0)n0Jpf KtO2Y"m))1ґE&na\[Ay$A.kxGj×c_Zj]^KAN>&x#O&  ҇vdy:vx=IsٌZZ\ȟBeۦB!fRM~E*O) hJsbzZqůG499>L& G}7-t<{GVJ_50}H:t2~ $bE1H2p(ՖOzN%Qsɀ_6ʄd< l<:JZ+Bٴ+Mb7h+[pmobkc=m{o&XF(s m¼gqDFq}&#]xa->6+mKMC:\[].dIPE}̜܎!SЖ$7&$<+ <K>-@S-h?)Q^"X - DFS*^ie8{8]`>^M<,{2VWHGlNQۅIcA1! x/\F:0./D /x?'xgbH82Qu9ܝضW4'd{DB +U~fEFQT kc4^P7MCwbZE`CðsgJ<7msB}U7O6WOQdtM SkCو1!܁CcTx󈊔I5S侚{"i#r^sG!B[n2O54͖ !/ERܻ+ֱ.G1g|\$۷y|dd LMbXiOߙ,O} hNMz-$)w3,k[6'kRkHjwc.Ҩ՗==wšTHrsqJ~]. ZSG;ol=lISVC?^%hإfLs幪њxE.BY_aS8oeH]FBnw/7APG'W| 5Wo+$%vgqikçlF,k|KV^4/"##Dl .>Kbڄ6Vtx# y1mY^#O#yA&E M!IM!BXe*G=l;3:B'18a SsP%Z|MVăRSMړxӍud2_R`kpR_m[n BT3o7P|xN qiLqR5 ^IaZڷR)Z6f>tPMsmjsh@pŶm۶m6&m۶mv&Nf }dU#8p8-kTdr+wmB9e`Q:aJᒰȢU($t[_"W.".gJ؇`NmSa$ʞRQʿZHByG7.<\EmR|)oℑgG 9`PN֒hG,7VtM e|*k;%[[xzX-bF4&(̲ ii<B V@gYI`9⏮ ,Nd.G[.~Ŝ@*_A!ON@H ?`\Pqt&۹R: $v*W!;*N{}F96aj(4ÅeқTňZw]98UvC`cWh/WMHOCNO2 D0}Q8ܱ# 7"^ehKኍn7@(!h]J{,^0bY ZJDb=13;PUˆ BF|׍sMRCwM MOs"gEh$J)[pUQWdjLCt:}Heq/(A^ TЁ}Q!m6flUgvlg׹]tAqC(!9k>&a:۪.Q̈FKZSA,{5O&0GY(+P)_)x~#-e6abDk֪8FGL@wGp/ł!^[K:ZZ :_]Dìf [̽LO r0_WJ24~(=5 :LΦI=Y0w Y5-+^ĻiS,XZoL6n<Ǔ >=PV5[) lk_fWi_*1:{\YfƏʘ_A#PG~VZ>&@2bdTMRbBk.u}_nA0ܥʐƐ.}'J4rM >"zvH H$1h>ӛݐd餺DT.AA/o?<(Yޘg?먣rZ siTb <Ƿ2 [{P'#ht^}vMmn]/~-2iYe/) 46)s4hb Zيc\d-3ڹhy^w#׫n!oafER[+CWqqjO5փ2(; ߆  w$L4a1sJqZ(i*` )Qڶi1c[s)vVФ7;|ypCWi^9h wI$?X|@ ĥ_gIIUL% GnS MK\K$0Zy]I@Y K.cbVo_:9dq*`$ PUdlA_ɩUG OΎ-ϘlW _"έkv]̮ z(R0&T_yyGM{_rdQ!ΟHJؘUc/s#Qp&>:dM|AX-@OKZf`0dL|#n{pX}T e$DMOQx#2 YyB4-O}.jRMKUNۯЖ%DmakDd@Ob]_1r[C%-ɡŌv+w7Dיh>C1%`^*r`j M '˲ӡ"8zy- QSFeT \&9on .VFtP_"#h`P'$ ň%/T@^lq83˸[vtsTWM*LnW<⇒@ܞ=>YCE|gj2d kjqIl^2'`rq "t3<,;Txe:+3=5.gAgq/'|A^ (f\> Wcw9K V(jtr>m .=?4dHoxpqtَV{ 8F[U$P BJ)1 DܤK!E|oόmJx,c2^#xҟMW<~i sI nɋs6~WOhg^t&caȕ2k[~J+ !&Rp;o[ټWqY26]S#En wN3%fO&իD5B0ԛ__0'$SJr =Ȃ]bG\f)MhIV7rwOa:nK iq|kDk]*KdQH8ߡ-Չ(9<#1ֿt/& mS$#B>Z$J]_vW /ǬhQ" P*9XނkgtXa,g8] U bmi?$/˶M:I}"R̐ Q%ؽύס<'S^&$cu/`klXrmVM)CZoׇ@/CgTrv+_?]6ػD B %o w ҃œRQF]0_ bQ sa[!_@Y?lG} O&!cv8e~چ)x i6S$N-f&[w? \lKda")@hs..׬F+ףjhWTK.9.^90KHY D-'7-8Z-L K6]%ba|.ғt2hCAN+[L 4)1<{0Z\2 +_[ǻ~" NS S @@ˎN!7Y_ ZwRu,oNϛz#w 7d&YxF@V *rnQqMqهze^Zڝ'כρ\֣*PvlxB|Z??0\^;r7:@1Oۢ%M] C k민 vZβǤD;@ ^+e=sBm ;oDW󥟙c0J":\n*v4T|, gi:G^̰ʠVQأ*saͰAx%IF:;ka7$g-y ^⇻b-$}Z XaJd){CH!*z8G=|-Nأyd[6I$.;|}nn!@fS0]e~hܶVVwM# ͊%;k_\ڢ9/4q{(x/ a0U1xt74ꍘ`*QeդMh0(;:lOe2:!,:EL2v\P4t=Qjcn\_SXivYptbw!ax'6t ?_W7ojO^a3}2O'|c+gG6>wdL 4xG8MܬG55CBQuGܚGExc{3' _,gy!ԯt7A=a0dQ+ ZW ,utF3Ҕd2QT5Ukxv S[U>}S߈uA4X6:(ѓ\ UO|.|59zJx'x@n@x}|犆xFO<,Qk8m6D ,~~ˆ@rYaSO+F~.8#;R~8 @y+c.vMM5$u$}Rzj)1CKe^I,@l ԯS)Ŷԏ," /A7lyMzHp<+/,- $W{_/՟5'db33k5cbU/$Ru'UMYZH|!CFtA/#btOKģhH6JkCZ>'#Zxhc-v ݛXw*i¥恱a<$s4xx9BZ$*&θf*^iܞS4XF;ikwW:BcvD@{4 @fJj[F5'DVHXO~J3kwr,Np5d b,J ~Nt}J 3;^$ 2_Nz.BVV2탬2ϡl >3HPEXYʀnOۓy,,j0I?~~ W:T 0Vl6%!R1[>^M8-bxMIIظמU[9Kn)#hᴕ=;>}//&BE( ܨ,(. #ޯgѰ F#|Dl;"slBE "%w `+cJa6?A[k!&+CsBz,(l4' 2dWf_E桊7ǐ†"cffu84c")-[РXu>5u\%I9ȑZ󣛡}ȩ.䵻("(R3ŢO߻ƕ6TKYgK.,اO0&aviIMGZQSQm{ gѦm+ypG"~{~>f"rdȄ}6c3/99b].H5X[؅w&܅*6#2_>(A} u&naFt$P@N 5sH,=FwLGDbHIR#-G%BȤUm*ԛ>갻hQwh3}[XB}mBM!j5ap8-ȡ!hְEOa6tSnX'Q!y2ڛƕS\j>C^әcw!Udjc5idąכu\l+)o. 6۝ auvpzs]kQ<_o-sg͇8ݼTU^#@nXKe $6JsJ'x&oѪY.Yd=KðLZ3֟$2e0ș,rP\&]G) /Ą r;ѳ?m>0G`CZg!.WRVeuk"}=oMfe+]w%eQ^X!ǩtsy"neP!w %}N*w]gya4MJ0; ;1w|m1(_f JH$G(:nÄ92&R.Nn#كVGz+ )hZ"MyG.( A;Tq,xS<-~!Ԉ T$T|/^,lLPj5JZ|Ro^ruWp!wQ0p_Wo!-JVT00>]b@QZ!` ʒԽr ɤ{-{U6_E@HS9-;np?MS (KRBG-R-kzFz 2ٶg>v`t" O&aJq[b HI_r=y/*s3TόhiD<'%x/cjbEźHL>Ob*>A`;:iN#0-,xw˺I<⻷yTJ<&+ İ0qsb_N ̚9 *!zlN_=zX+KP6VzErI)Ft:5Ceu|IY}z;CfD {Xit7fE oVrK^KVI ryE2qUZĬ$&z7m!FpK#X'yX}hT E9.v{$xu<]iDdX r DKk^ߟ3ǏA0c=\}%O4 C̺c *Jt[@F/qb+*%yUo1r#pc[t Ow=PSǞQ F6 )3uCM#]=XRJGYȅuZ Y>}uRp wto ~P/q*j5)~eI#l掠Ճ_0[T{gC&#gz~efv2U򘡹QFHA),dn T|moH7 R-6>x=YeCxG*E/ESW[4R!YKb _0pe{>uȇenrZ#aߡԫ)~I  ,?Wbkqv4dhLXI_RNj-] \E߀/sc*9sZK;]2br/1E|?~i^)z~U+j=3mwJmDsǼh.{6T/jAμD=/ɉ*l!Y>pf@E/4F=|^% Z{TJ`.Qffw8I"=|G8sgIOn7qxC Jڬ`8 5o|KRP}~? ͨut{5:A&`OAyr{H2{U!)ʊn{ W!}܆Zlw aƃjyEY$$䆦2|.+Qr2S&ʱ$`ʠ\3 e輺WԃH +GB{|?Ak:EUJ_M! UY㭷"Ɛ]qLp=$G; N!w4-kQ]ZԦ,QVÛ7R;jU%!W0VbQbyec3F!~q"ZiWy*%FcIe(?ɳz"Sv]Bd%i+(Ͼ)- 1{VaaMP1vw Y!]ayH)a$ <( k]88n?$Y9@v`FidX(qD _o Bl{/i?}7ìJ0y4ѫLkq< \ Pc/-y1My }B <-0}!|Nk>'˙ޱ9 .` j# oWf,@BA^C ?hX)L1pp:q;7<U5ld չ_A'\BMմΚո(9w@to,v…zJmaJr8I, H/;|]gi,Hw[J?Ge«Tޱ! Lpn5a1Oġb. RC[T Ff}x0XLAJ#ЖaZ;H#ΎD!thT&l\k绻:"w|a~Ga2 B㞸PSq%fG 6+c|aV@(!  +SL+TYK$Y=,(c +Z!!td*.S.PJ(=O7k{ZɷJ]5ڂ63Ќ83qSO8- 7V+V.zd | D~(RB$,ٹVϜGՈYKdE8dR/l?t.z>>ophIX-e=;*o8_4@NzGȇ9yP+<:l~M-GO{)O/ښ% "we* ix?4z0 QjO>DW.%q 9qRű4-KOQ}=|R4Y2 T{qRqfTMtxO}z=Q k(n5)7d/3bKYg6ޒ?VX_O#e"I ܳ_ubxL ז]vތ%{Y_MYe*(+))?ɉ'K3jJˮR4 /R^*+Hž)gZ'я4GJ$F ʒ,ziZ,p/[4tN…yB$,mE-x[ Ƹ.{|ozKfD.N)J6 ^/ẀfZj̔SKOx;QEs[?t*-Fz7; egb/hΛ >spc =a]B+xzɀޓyq{+TU,<^H꽛ij0:Ou[xpYknxE2~fP}Wt^VGh`xTFJSKkqvj#0VqgM*0ySv)6.4[&_є&m‰g_/f=jQTʆT; ۇUtB!U:چ+hemrnBa}w욑}A :N`W3b p/AĝQt7Zp@[Y끅`!z vuMh&큢cY{_N e5b/]®V o*VGoÕMq*l௱B*Tq _ANlY'?jM9t$ ۺOtN*)/,7ZWHϜQ0A[8iúNO=SPR{|'igoܰT0h^,+m1’|Kro_+v.?B^4C xXV|`sSԷ"5JFC6ݤ *.ٯ.Stv0h*;0G$e{ɷtaQ)AtVME6KLEbG_(W*UB,튃:ȃu*ljSykL\#Mt|_^7n1qmyx$F!f¡a' z'.gf=iA"Bɰ ;j2vaFF;n&/+p֤M^ĘbPڷ[DhERfhqP1#Yh,CrbspY(e2Sҧs1}K3mvN.ピxA521lI2 {}#i~Zz&#\]'HswAPӣZ&]vU|#/366 Ro).#;Z٥0 RƼMfQq9oqNG8Dy8zM?8$[?l]o#vuyfΞN[G1<{iU%QF 9!em|% \b.DN WBA"^^S _vM;RT(Z t4T_/E4x b1oA=rKJ@T/j@n\ww|aq^M[!XBB~ܛ}7&`! Nt;û伂@{FKr;(؁}-dy_6Lg:RVVtj{٭&/v'+ӹqFTrPHb%?w쯞)lst Q`ꂻZXA %~*?;nFG5=UJ3$[%['HK(p|1[fLo:a:kؚ ގHH{5ג5Q8Ŕ )ho `*._Qy@pm Mءx𲇛M\5+:f##;jbFzIQpu\(ו+2D{)* W&P*G/Vިǘ87LtꞄuNzǭjZQ5!cwP:dҌeB-fݮd)1>YK?z^}D IT4T N_l[ SPwhz&-i/Oz,9r|m8w(KjE៿<>LfɎ,ڟ|"(-G+BbFdw=9۳cUM<9?!"G?PuutprwKew[o}K[ӡi~>-Mַ2r}+㢱M .1CUMGF0Pn8 >VzBp\ 8REBp Yu#鏬CV{C]pu2b>C͐qSqucaK0&DOf>ylƁt~WfxK E ỳEoT EuxM|k;n@Hю &;1g!"oHIG),bM̲M:'CkK }+8}@>4 !(Ы4 +ƇǾB']ؑKTeEhV~A&6Yf)6G} d҂h <)"FfcǺ"kvÆr@ʭߌB_E C2y*Xş_BoÙti4D>hF>s7Ki%,7 Ĵ۠H1(c07X}ce)WxO>YiG`G Z]bŃoRKDOfD!+ٔ=RaMc0p^>.Ș68e*Ԩkڲj_FANjn$ZP_yx͋iJiHag2m[1Qnܭ-@ IR'f]@b}.&^2ʾi>-*NR2K+&dSB<`QԋX:ySwI$ XNC]sRƑi֌qY(I9g6uӰagD_g-Epb xP2[fXp^20 ]eMlO6dM`?&e lvVC 8#|d=r#m6AGV!4J}.j#0w[c0'qv ;4 3#xh!DN}W^(RՓ݆3qL*8ܓ:?{v2kDQC%{VuO\%G%T̃Ŕ i;դJd"9ߎ?BWyܬ) acc q+vLquo{˞j5K^Wfk}ꁕBE%Ӭob%fOG< |ႌR'C$\Dw> stream xڴeTʶ5;NC!и[pww'gs7zj&%S03raHI+X[h -vFZzzf8RRA;C`w#Z}( ziC!w M )?\m\LM`7ZP2HJd? k+ `mP2T(+ +(Dd)i?+:XO-Jʢ!%a 5@TYQϫG<ܥp27j# >\-J0qpᤣsvv5vw3>%S{98Z|v eoheoIoG+?>[G#Ĵ`ohiLJI,VV@+C=@/Ѐ vvrHKeiU7돕iY{{ǀVn.[#S ?3Sd2"ŠJ4Rij_ IqY , [Z[Z~Tm}B}rs6vrPZ齁 -36t m.&tŗ?b?FxXFop@'C?T[Y8T/QSk+ W%(%ha!4?=oCj)d,31u143u720ؖDF⃻ @_Z[Xv3hU?DU$/mҷ6020vv@W8.0>m`YtV.GOܟ ecIؙt8>tE,:}kK@ 3dЙ~8Xr, te s(ߐ@ώ9UۿW?Lv.\g✵>WYrcPRHRړr ^5XŴv\,-bC|ft|k)1NmD_B5tym.h _Oi'1Dvztzkl+@yH1qUViJ.so&4; d܅PG`ݼ Q (.dmq߲vx$akk~hI˦OUrk "ƪ)Hd書Dab&>5&nIL{+P80fBKX&nM%ZsHRպmG/ܽIZ% mV蟧(߹0T\x&_>c)ʩW3f:=OP5;[V^EM>a٥+qy-3/ fɹur|r3%TȞ2? QuMg8rz?;@; H]<]и#D#gL0gTt=P X'&_TE< ޽=q+dsj'.LnO MSDG$&s{X/7}1<;$ji۰v]F9)hf.I2E4Hu`t+~CɴȺ"ҧlQԢs'O\;hyq$#ܬE:x+/hQ=~_vT"n6zk֊SԆ`7IhT+LݿP"n1HCDe9@4Y4KoUPNk{^־x+I/&Br#sSelP|u=SRZ*yæk5I'n䊓 rsR\&%\ 1y[Qk*[ͯ-TQgz#UrK,|g0U87> ɟtJ}P_]Irm5{<7뺵v֠F)%Ivj?o.N1~(-9wozW chN޴{އ0@jӔwϽrlJ T}}U_ 5=z ζ"MnٶYc2[ V'UZ|g~9A;0+npT6Pm}%P1"NC[W2yyJZe&AGWF= wlK4QN~/YPj9@oGġ,BQC}XuSIQvW65v˴$$gS7EБ7X|O->hdil>3 5+n`=45rA]cyNmf|Sk9鵛4ұ^llѮ"m&[/1 v 5X*MPkmSfO{./.0U1 ]o +QeQGv+Ma-$s{+-g3S;HutUϞ#kBr^`i(LII6!~l[͉%C71bTl$裐gƄƈڊ'%3Yvna߸W&Gv,ZEM}N7I gܢ,/,I8XӉ&tV?+.{`N f]c |{;9<*B|l$*Boz|7M.WkWK N{NzJf(I4/6J߳J I6EݩݮâAI4M=7&0 MC?:_ȏ: aBa=-:ߓ0JnG8&fIS_ڌ+W\Xsf,%ƨtiF;shZ3w܆r#o$frW H ҝ̺?I'(Yãr/ AWNZ;bA >ڣe5Zլ5x3D4sGк1f 4N=S3lrA!4L PCw6lm"5/#+z 蔊Ş W]qrZ,@Q䅁>iOFf~ЎW3AXNVtQ _l;G 4billn.׉y^fTֈ0q ՙ*o {. }$X,)~r)6mmd,>rcb3*gј nx-[PꢤY!S ^hlhSC2QDpm_`T:[jd|[;?}f\*AFO @r9u󹜙` g^$,KկKq +9gmH ގlL_ XT:o'' ۅ㮴BC()*RՈ`,\@RP:zTx=AC(1.)GER⃔xh滯2YC1o Nma/^dlqpMkBEA *3z<9C,~`] 2K&^s p JݏaY{hr<^3fK6]#JD#r/bm/-q?y+w ^I jPaqJ|шoBEzҶ-fM'y'I@b.J![К8.b4b9RɾeԴbd!g8|-hn-pɬ5XNjyCzjAg.&@n]瞱}99(jClS;mJe W)c{6_Y~| z]ULUl~Q"c~,`!Z&[{?!"6.}|a!1&)n*h(hKu:8c~>+$=)vy*w+Mzy]^Q=Ȑ?Ym"H8T 9(n >QYy6bOU 4oIJ+Q7jwzx8-E6TGBݟr%F_̊*!"Emiv@z/3#glm0!DWqebvU󺎒c}q61wJetA {~OmLûH4cX{vrkMy1d݋yh~M;X3'1YrfeYqGg rRzKwQ8фI-4iBI4 \*ff(Y}X}\ףr"a3f`RF%E}TT6T5dnVID:\yN JÝk2ұ< 8Y.fj_XVHm>숙{z1w3uJ14aQHY<+?I# +-Quϴ־bg˘vs Cf10R[SDIS6S=K̛kR8G+J+bh Z2Ié fNcS?!Hn !Wul'݋K_7|" FWmc<1tѻOzt'R\9!1k~>6?qH?V wT:1ڽ`oigr~4_R\ l\H} "~,heِ 4zL^NT@H}WсHM =P ɕ;)hJH}wt̐wоג gױC)U^l{H&םd38DN*657}߹x#{uLܬS.V"A45)!٪/M.$?k;ZZ_ƞ)-͘5 /k:tr=(s+TC#/ԡQ ; `J!;dZyԊ{[&)xA[Mc~9Yy* ^z﫹v\pw5% g~ϻi(:9x i)zًAh>Dr"*z,TXIE #ydCNՆ.5`0yʡ@3tݝ]qxCql~Iש!r[3=;N'ua9}UJ"cĂ J c*$X:8HcPZ[ \I8&:kA6͟HB7s 2-Oav;vY'ɖS/Szϊyt,@)?j+b<(ʗ±BWQCb#ǧsq6z(N+oaxu"K0Z/*G1yC Q/q8G}tZFu+dg/uSYK ě76xCZFH%Fa>~X\ns<2j(n|<16 ,S{]~V,3U}{F zEx-#rg3ڼgMRO=b~´֛.9UmFD~Un2z7Gj0bEc`}1pz#ojׇḾ]B7y\T#jsa@ ~,S?gG%xܗ!uýd<bp_aӉyl6U38(w2Jgs_ |1D\4S0b1_åsN7"l|!kج_*IKߊr rš0lQ-Q3Iv28*1iMh5j|nE;5ieR[k1(רF ʲ/g{qDFZJXtVu.=1HΫkV_:Rh;"јYPP ƄgPk UC PИDӯMh=PϸeY;lͯ.i{B ^,'hKu#ĂqؖNntzg!R/DdL|q21{M X%@W(`#nfREWIc:+ zy` FY_ Xr`3=a-{Ug'12tG]aU3*]`#5H#}a j0@>m(D R(#vKdIJPEI w<&3gO$GL&YxpkP& )`քceE3n/+yqHZm@`w/BcCV`Zkx<ꦗ`YFxkt0Բf^֙btO`* M%w<3<! #KIV]+:nђ.9˕w񜎼wS5Lĵl'&ft[ '.x]wn6v1a~- +4O5 h OOAοӿfֶyy\P'<8h#Y"oGp4鮈Vdآ|nm@bYݓw\rXFI~Y-׿m[NsчHKVFj1|Y(bggܺH{4oXK" RFLe4tGz)c /g)B?ӧ:}wW)mۿg?Vz*8@R9CXL^eeGE_b CcPhVH1f i]-^5x;pZT+-UZGߵȂ׹e/<@RGY'^e4mu=%]7HpzzZ7a"nNEE#jwx$um)/J/WȌ)m{QQ|?OzW!YȆfcF9^ˉߩF'DhWL<G%=ގSJk|@`/7[kB׈ 7McҒ0V7p}sk3Z'Uo .oI$Ve,jXuWQT]%2WR}>%W.얤k'}<1l0RPeptG=`8q_G"B.W)p-yK߱v1  tkj*ѵrpK/sYx@>(u%k{F Z/^L΅n)bI<7j;B;{wq\$lu{8}V"&&bCF T,_Lё}倵RͺU<IHsA'y J%u3˨[zQl_v ֖Ks ݑUůZt{,S~,:OrKҀM&GѳÙl!8\M]nOvU[y.OoLj:P&nRU3=۲ ;;\/|f`f$zKZ|Z%~+usX"hG XVQEKh `S1K>#%30D nX!LԲԫ@ŸM懦(xW0@uOѼ3;]U-zAX<8j! g$ŘrUq{x_ Jp0ޜXA*UIhb.1J&4NfA9O6o%^'{xV~6 m!r# (HnIl.*~ٴ> iT\) +0V:,3%CPN[fsLϠ'VeY$ϩI$RZށ.uI7ӄ",QҧtJ{Z %p9(ǔ%%-HDl7B[B:Bjl[q`8r[q͠4, [l'> _U]&J *4Top\ӾWngc[RsZ07$|Kz/NY:Ń̇ :k\N,iL)^[ 7BO vT Lr 즔gP1y.n]W98UxJoM?6Dj l 7p.kω]MϠʟDfJtrM'W"uK·nIOr5Pnm,0 oL*~-8ύ0m[ =v},Ŵ0V]=CSarL ^25o\m U<-M !#he?@BlF(w9Q-Z'7kˈU{{C5DT|i#m^3ɨ$$&sS|/cN;3 1z~Rw8R_WY{>pʚ귢e4L bu%I?'+W,pJIX-Jg-ZM< { uq2PV#4 Wuv&QqT!.K]Re˪ƫgfx`PW"@:-9Gڷr$t9Mh* E /^_EI!/${*R! +*1&L9~$i2>ieU>jnz͌ {g9=ON5)ߋ_^Tnw$}]&y?TW][t鼑Ǵ0hI{Qc[ږ^ު2aL Ci-"Ջ3\ך:kW}ӍXS9"{/wA7[ Nx XGr&XnCD`U(|HC'mu.e(Ϛx,A7pSJx;c>0FiΘ0jQXAZ#8yhP5ogNi3_@_D_9`yM_lE!}c6N_=R:$~Czo1Xi6Fˁ9TS 80kc!t' K ^pߝ7 tS-LLEaˉ9H/X k:5Ğ MMacs,T Jʆ(;M@䬔HU_s &CD%kro=2-|΋P.g+hFy>>x՜ s”F~&]RFj-{Qil2!n5#kU6 N%J%'$R7.˦ SzAp(LM 5ReC@[˰1T6Ppd.=PBYrfQEQ:yג˯4~A8bםmVOtrK 7H1s<-&}mކ{.N3DE%VQ@XŃs^gח"Z"1BotXKԨ0q,XlgUT;(ϓP :oWʱ؛mRvWyfTBYR@lS(Ƴ3AUe9FFwՀio7|ɵj8RUQaVX| ;j;T aZNDV5:PLN,t;<5{Y|#:rN՗V ]J|=Dz V=Up$_/',g?JBOZF<;RڲoA$vm$Rw4!iI*+Ӳ_oĘBd2yaZ"NT ,IU IRlP[>'3'oUx+ET8y<)BRkpK}o;4M{l?lwE|%bе/SK-|4Sh;1L˔\Q= 뭃<HQ02sd 2YX}>4b-a01&2Nѱ]"%أ|  YK*`8Y K0D YF!_^]=uf*a21{);l@,iD_@FtXt{`1"-^T?闒&NPcw)unQlf_vuC)ko;Ë4scH J~((\q mϓRo+~0N{'gc`RT@ ::u!~䬮І_"DȎ{fyp؄aؤR*s ilxd6)g=:$ sў[Kx^tl D+o(Te\%kT Ip>IŢ˜[k>S:!!DhA:N̳kTቸykx_*ۑ2gdC>E"B_ƽv2FyN6[W\Сc-4IO:wxe|Ⱥ괖)$*,Oh-ē6-VU>oDŠgacYdЛ83g4 u{aU7&c.b|Sy)kbq6߼zkdi҅Zrl|{M$8k*xeKcEHk)uu=195p=zLm|Urr%$RK2HNXƎh1`Bk'a' pA*-gl& mzš2[ xs_΅1s!3KR+U|zI\2i$?bXVF6x[tp?StƲZcQ@`X0rrThb8֡{|MQ|!Wºkg5d8i[;ˡQv!v(TE1qTnGOer(uTo:SwhM;6yn)2< Wf9z(B#ul9Մ:j)Wky7F5'Ad-n*bN}q3J;h;/"]:Om%}yS$li ]6ǟ~~W 85Rw_+|)QA_NzQ8M" $rjК8;jzucp}SQՆ^m_`}l򛴮l?zaHJAJEv(2[l1 V|ɪT،%4ey,A]3CdMFm>_hqnsB0EX"m3=J_=u],f8'C"zKҳuI;&ją=u'ZWK1GYy_ve<Yz b)ssءENFޔUi xpt0fopB leI֤ŋO '4Նe}FoJ@>1"OQh1  Yͳ * rt-PSvPxLWί?d,8ְա ̧S@j\!oJ[ؚf $v.u6-֓l g}&8Vt4<~!?WΞ/914&5J"-Hyw6(ihX:0_[<<ƴ`C{~m[ÇXrKm-:gٶd۶l[Xߛo}]C(C=NerU2` Zm௟oNr'CGc7_2BڤwjG6Ԟ'! 6?Lˡ 쇅\̶5^5 &XfhqJQ+WL4l *}4óbãi\{cAn=fUI@?S|Lf2[Ku`?5GpeDsc?#Er8ޏl-Gc@aJ޴A"̛& O(/+=M/Pgv+}!@|+ƗfgĘ473Н#RTti^-Ț+3+}ƬndR͛O+rEz8ȅE9_].{Vv0~B&ƶ:fEw]@`"+fx@0|~{aPt`|)!nDkֵի4(%^R oӤuM 8+3x ` W?.e0k ' #F=߿k` sLs9ήWHܪ *1~Dk Ok9Tz!^^W.UkMaZiݕ$2pPFapfamx٧GSxx72zRqE%D'I݈9Af܈S{-֥Zy*ŞKӻؑ{%UAԎaNruW|Strt/z/}Cz<'\)`j.2%@_i0My߿ZKh"W/ŇC@ ] ^;γB%`o6M߬ס7n^ ި[/77֜du)kF}ld2W0%t9oqsACl|: ؑxUn!Y=T SnX1Bq" #3ju<@SZ&"W.\&wVGXF@n Z^KD9@ 5sk iN;pF_ӿl!7#vU/rҾDmZwv갆Ʈ!lT` vH >Zc'[Rs/*^MAbE|*^=\-RW |CTa'"L$9֨\VIn"H a8izFIJ~.N[O_ u;ܳb#Pew+ \bI5/{ӡS#]^ZudcE){}F-d "$󏠰}RZi|.IK1G?B:8ˬ I/IoBgRH"lxj\]媏N/(,Lѫf8ر,lX"eՎ=[j|዗j 浵Mb$| {;YsӞn(4Q20-o(o yaUeԖ#NQZT2NYm>,fac-KbH'cMHĨ^Ӄ9S|E}b7%Z=7x>8E7`_mp^4i*@9ZM[ȫ'fDlΨ:N [&ۯa n+է]S4su/`Ų|r-͗ :=- >jA" ԰I2G]JGE J7SUzG=6ׂv8ռg̤lZK ĨݧS[75h ?a3c`mr۱,IYOϙD0Y.D7UeBlS3.ˎ(ـ 7 ̓$ܻR#xpq#^~aC>XZ׫ Qq>LxkFZ꺝~͙OY,^^1@rP/#GoQ3ͲlM;CxJR4RkGp= 6/-"3Xf$z& ĹTPV%aR%W;az,&x8b\k1tF7"9G3hFC7<3_MUAG`6мdF-Os k(ng0X0 'est"0v(axA;ɷīF` g{¯-q.N}߰c|: eeSyޭ VH 7ڵ7h"ׄTu yҖe7?Z%Q9?v^fLOt@W}^e@ONsK˩AF2qio-pϦAJo1٣_i3pRB}[|,[8uR}8p荟V٩qSMUɉ^-->W^SVw=M,@'dmH%\f&i _)g +^S m,.ʤuxǡg[zQ; 仐KO3<˓N"񡛈-k YtdD3?le̐K.#mOˎA~kys-%D$ʪf l*n;X@!ƿi#+0fFn2z<>o=k(qذ, =0{@ ˆ\.g-6U8x5U)hr!.wȵ&&Zb C[ArEQswu3==ulj 5bT2%D ͷm#~8ZL'556EPEY;$NmJpD$OBAoSwg4OL`OGTv 2 XuD<>(R5z҆R;(Ŷ d׿oF+[UB逡_F`$\p8`4x}N"Dbf¬e|t*BI 6,bfТ (,2ݤft#,-Rxjw~S''iE @'=g;Kb39娑ks}ײh@m)ځi-\(^$MyY c4-`iӸxO۸D6W?<:"2CuM&֠0 $N+HU<;6.Ej_²MJ*st誳[< dt|-}E<܆1[8@dJUJ|D5D,knVczRJh_tJl?NƶG `%!VV2yV[5)+;.mFơMmЫd؍BX ㍁^ʥt<9U$kϮpBw2[ܪf$ Z ITd!ߊ=STcA/? iqzprJ,;sOa5JxTu~_M*/r_Ă*jL)~`ڗd[tQ<@g۾u& 楌moQq]$BH[2RSB7F/M?|eӴ dv*, dʼLq,O qLE7us[l3%6l;%K8p_ǯ㸨wdZqsA@VrŸPi_@! I 8[K$]C&$Ḕ|~G@`; A*JHK^&!o! uh>wCA_.zy-, (={lH6b- (>`݅VNTҶ?5Bɝ=7o"$ڃ/9S"%¢Hu䁱93 jhfl$LN2h` &)o0BRdF q-Rs1u ~*C~UAxSJ c#%$kFenʵ׸߀&Nn9 ;0 Z<0M{u# "Uw휥v5F,H,lGa{jj#EӪdڏw.eЌT ss%uNŽD΅6Ϳh$QۋY}zEqptEM'+p:}(1/T'OU"p!Atk>daD 8V>LD$ʮf~}ľ|øo}9=,S JnD]_ZócnE̾A,,'L;͟+#RX!2Z̼P\J+@GM 7\NW>aM=[VzS% "6qQn ]}61k9*cRM4RLir뷛v0\KiAZq*-p^QO:5ZO3 /m7~Hlÿ([m;Z``Q U͊C0\:n$p6f.&BܸbIAwhANe~BC[U#ٛ[}w55a8\Y]ȕLkK_s 7޸;gZv!v.X> stream xڵeXj6ŭh(n݊S(ZBqw;w=twf\"Y$$UQc57J932?۱1:XؘXX8()ŝΖv@>@ ‹@ ޕf"X 1 ؃MAjgK; g ?1D-36wY[rLL%{w%`01؛ԁ 5ɏj*jL\4@BTI]dHkyUڽPRn]QR]T]GEWOF jN%X8;;131}v93;}fr%fd xw*{9-)$eNr{/6@@0嫠5sۙ:;Fޟ@3 .NNr(K4.f~2}/c혱 cہ,AΠ#6?AzfiLQTIVJRMQ}߫cx |.+/}H%mmYONN\[ٻyrsK;3?7sq`ְttJ?@g Z0I״`nlX@Ʈ@ 럊F3KSA_ڙx3FE}R3{;Y} hٳ%bcdl ߒ[Y%{'[cY,݁f*ΦWo߹D>L,\lk4Aw=7G88R?{6YC\RF[$L,>8NN, b}m3_`fw~w88t,G70+UjF,fw?#vwd>(/)+{8!{8sKW?T, 98ߑ2<6a?,A?{~d}f]̞Uw՜쭁Zfy0Q4vvtcy_;w_ +nxٻ{1rpxxTS9M10 xc*nE}E{NX;xh .Cxe/FR`733brJ?Q,.JZWO;)ad+C-Z%}`ET+[C7%oKP [N"޿ "DR鳠|nshIV`fg'U+%Obt}޽ׇ=B3jQ }Db?|TDC'G`#E@1eX{go /!Zϓ3nLo]n ٷ %ʍGj|5p|-FEexdw,hhRm%YFXDu`J"$Cr ns1(+QSt1[sGf'8n[pTo}F ,0yhEfN)̚P|cXJن&;>hE|Pu+mZo.b)~-]DEJ-p˓<;h)CG5hnEF)ˋzih@+/q5L*%VB:n?)ajR@"Wy`NXP=n }*J }݅i*`pp0 ]YJn> 0D8@)x`UF7fYJ0Y͋"vLU^̝үILÃ΍Lr_o){BSaɡĺ&#.`+1ڏ+T海( c x"I1ܵO•7>@rda~a)]ٌe^jIvρ0$cJQgN0D5j,1`E>Fi !+d%/ #\+] !(<_vK b_L]Y&fGMTCl͇IsfuXDPиS]LjO8ωzk5ES>'T9յ k$#mAp'3>DSG"47l\4~6 9ZܔԣъPYZ.mTgvlo}5)35Dz/(_#"j^=-CYN5gKUմ[>~ƬvbU9 *㓃m6aYRU߁Qa_F1 ߍv0*hx (H/~zBB);b; Q4pQVɘ-le q2{Hnb+б7KTRhyZwєh&HBH:|̄Ⳙ<4ڨ`[M"P:k.%4.r=!o{1(˩f:lV]1+Њ(J{@VXVCrQ0hu3Yі]ܳ3+%U'W aK/h$,%!O͊A#(4+R݇EQ HdwryeyKwE0Cuf[Lx<ޝ=E˷'|/++Vl@NhY+Hґ gq# sbBcRzAUXXɂG1 ѨO/du@wQ a=&9QO0W=lFlbذbk䀻Y"4y -Bq4ZZv8398|mꃅ;&_4;I< O o o!t.'fv ]fQ, JVCųG;XlΒ-N]'k| cLx)y"~p%- >8a; fLHW`ؘ7}^8ww#(!aI: FB?SX^CwoU&r"D P7z\ܮDUe.A\1fq3?ZZT-m8rv>ªo[}RZj[t0G]@EyǨKh|D*5|TpIݚRG{2a̱-Wj wT!kyjo쌏 > |qFP,;r]"T d >dd01y zDsm<)XXO~ %r8}aW2` >- ~O8@$yN8=}ȁb"qH^iNįnzuw:8 ="a%=2xb2"x"nP?]\_b= ciN}Z/]!cI ն؋3e_"um#m@`Μ.h* B^Pp|>V'ǃPpLq+)x`žXZPa,&[_Rtx< B"fvܐq"nRtEhnvQ@~(԰:ۚAdо8, uД*IJAɾ뽪$j&*7ʫH]]%H g Wwx$uM1c~8e Eq}5jY;!.Y?1(]h^xu:b$QLU%%*%g{gڡU0 .ַ +n,/NbMuC1_'qޮ 2FU9ՔT쭘d"Z7.}*od(A3tr ZQYoVDNr9~S6M;,pfuk෮xbijS|Ꙩ(y )Lxr 8ct@#a,7傞ui*L8ŕLއkmM|#‰Q])*7knp dv62DvCT`zҖ[ r|rw֭vjAɖo ZL籺Df-Q)"RBPeSP"9r}+ j:ztU3 |#u;+|419 KY 'Ap=C֯gN'1پbeo34 u5}h~w1Ϟ|0na|KP\?jl 6D [L{Մ|YAu(4f2EzR^=Ԅ$HY6E"`&nXO>3<޴j.c ^#$Eo ;YǴ1"؜d>0kXtw#&,lٵnZBu;͓LT FzGQC{.fjaVU^ h{Bڙu<cB ! QÌG FT t PW3]ӥE;8K]2Y3U$Μy>lZ˹~PH^8[$A®!0H?Pؘ# qktUb$hŒBxum^]qtk RCqC ǝX6}@Swo$NZz;LG1(65;eCH;CFvиߜ~8ғ'CuN/rM> hWJv7V Xlk?SG "aաo.IS֟ |ر+d"! _s$%,8Bwè஡UWw !snrXc5n+91y]Q0Ha^:6i.(F_y-4q]2G9^M$ĬKKjX>1\Rˮ`kH u)JvA;fǵEP˩IZKᗥhxJKCQ"pdʆ94,HO1:h2tYq+zXwNqZ5 [6Z:JdxH']Og5oVތ/:̷a) `/O@Uvkvu[{O )gN u_mZFWRD%+֮We~-N*Kak nz_g[iȒ{;'CPi.?}]NܯCE9ώF/%LW#٘Fe8K:  )j u8C#' ߮ū\o:`G`9˥%,#11L $*c}!}<]+]M恠8z,4oeCތ~VLѶ!Q c)QUr*t*%r_yX(WƯG'n!j6;q OJc?c>,A"4I^^}W4{2BЕ>+MyΝ|]Bܪk]X,k\wr;U#RhKQ$8$Aqg|VITaMj+q2Ho7:F_79>{9U$4>^ԯY9P)m)J  k;\^JJ]f8y Ӕ$>cjD+N膉o&#=!B Ei5p`5<gS[Gyyz黐QBIpLK?Im/ ĠD=~d0BuLzdOfIÜ*XAY~[]XgiTM/ 6 {Uf_(ufMTbDsNxEЏ|7B Lܙ:9fLoj5qT.Hh.BNԘFͺ)Yf!kۆV + 'HHs/]zoUȹ\,=غjb%lJ!9;h$ZSォ)Mٲ8:o>+ޜn|ct|Dy˟0J^n xtĬ槺j'7G9h)K06CGuWF )Y1Yq&-Zp|irZyb3{^7^p<ՎVV\OYIއa;)(!g0 f4N(aHٗWhz-N]N 0zз={6{}'[5.|\#VCj/ܕ1ˠUo G.t>%deSpꉃ! ȚhWG7O+3ͣa-h^3X ̨#]#O@s2&^nBm|`$TxVUoY:N4>-\ R@%m6E,bOUs`TgFZA\;d\0} MZC56 ,$~5@[d_f૥e]OT+ }[0y^tI>aOXHJUqΪ RNߔ$v+P_/bEϔ2x4ü|T)T:B0/\=H2btɤa/wH‚=`0B5-a:ٯEuҪ9̽YHz@V!(Z{JeC$3 )"oؓLf@A [0ǜnt*;i2J7ǍZWڰ =o<quk'?ז5hwƃM9yߍ 7ySdl;;!0 tKe8"Y8tM1dWt;ItE)d/U&\SJuϗ=n1u6e +%OASQV 0й*ƪ$Hf} K"{-l^ބzg@=@@M3(e|ј= _u_N2U$(; M֝K Ҿ 7\Nl۴Z*ĭ/2zBp,1,n"cy]# >2 l5fC cFKNQ-x|5>,W.8OG~v蜟TlD]k_qtp9i?ʍ Ρ/'y&?Pu2]ZC ؄yYߙ ed2NվY, 6mlV&K{ bxѮ>tly o= Xv܈r=FEm\#-5Oh)Y;G"$ְXQUob~0py!aJky_N3tU6J/xs:4}l.$\7.831RڦDi"*$(չe碗*3{8oi`^ˆorʍ)}B]x(`Yl}:^qރzWB0k0f5*^8`XWB;If5|b=ƌ|2с R8 dʠQ~AA4P[-Y+\ hˤQH*#&=&<$JmZNl6&^sSs(qmtk*1xA 8'T7} MWټ 5PG~ngFzt2At75x[r Y~-kMv3T[C@uOҸ`Qu$a~~* tޯ8]/$ t@a`oY-~7v8oziѮ-|ߤWlz@-/7f]/dJd^B Eh^57 Ωe=|!K\P ;Hm60 Ib`xS)Uc"pFA2PH<SigԢV[gґ]AZ7q~w8=d"GA6ݶ*% `KHfQ"h e"LW27Q TCdKM>߰#vj$rM<;"fbL\a XB^!/<܂W}=gnPVIΫ0n栽gW_Nwq7^xHkv]"e,{Q`ޮvbc3vceR&.WdOt#a+n~xE'S 9$0ȿ|t j 58'=z,DXFQih}-GѦp@AȹHnazM%SeW^i;u+hΐ'\;WoWawf^VqvWԪ!*pZ p%Q7,P7WO;|$jS~㭺tEsꆬI? ^FxC"jsY#?UaU!^^7l*k>BCGv i.D?S3B6Cc¾/'džt~=be:NJ6Wfx 80qmZPbd&ifJc5$<_ s(%pgKOf`p~5/TP ;#g5桥착ss .#ks`]EnFZ]#vL:5q"Qsܢ zSy!˼4g[砊7e,CyA1]/*qY{xA5^7R(D;u}KIimn'ab[XbdUkd.#P!Z]H-pEElx PǮḃiKwg[l *Oq~ppw7/b'BpU,(J9 J7[^~%;H6)rgbY\mGka4FDnbVbgpg?eFHœuJ)Ǩ;,&_yfJ \%O ?cpS0pM~L͉2?)޺Tc'5I@-^ (g8Lp9&I7Qaff%;iCrLwdDw+sLdzԃ.wgGA*A!ĄH}YkHIycHC"0ԮNx/l<mN2Fd?aJFDa\)tcߟ-5{+A+ wX[;+/%5?ɓǴeAvgޫ։ 5lL6 b9;B+6Eg ~(V,X@_:Sq>= FOU_>VpK$5?Jꕝ> Twh>FP5CE J0l?h34`f7fkm2dTOWdJ|EHSFfÏk}Sm@%U`>OZ6\ IJ.D&fLZdVZ-=iIތqcDcP%ä8 y GjQВC=ӉŢq >0n".~c5YzRc ;Aw[" F&O=s]3ࢲ]2Gcp,_:$ϥ{}*fv˅URik;4lF-nZ8vJJӟCe[Qy@,5# oaR$qW9f&[5QA/UI}q SXɊ؈Rӽ2 =U?<2=>8h\chE*7q \PY _հ\0dh`RpdKRPTL 6gިj4)T|v3V-y $@6v 0x 5.{.$R:[ü[ˑY&HHΧcئsVU*d2y߯u‰Cg&rݺ'U í;]su"딻S wfє}oM e-q؄C _:fQ+^_VtHp~笤g,BN;E).{7ZH v P~¬ԑn +.V,vܧEBa`4hW4LJ|qGN=_1{WD0IIafj^SlBI3^90`/!S㏸y]&GNI+:0x: ){%IXd4Hwݘ&U7=''Լdz=c5: H-a/B*r`.C׮Q\\ ¬nMGT>4o}_ 'hGuٞxzbR@&7Ii /MKiY!LJY W0#E 9 Oao֞"{5ФdbS^gS$HwO{S W=hcWzu8VI"`Kn=&)~:%M]F(r/myY!aeBeD_)xyD=x}6ϖ ^M]l4>o-MZ\UL-W@l7UgWSQ<*/C!o{Yb5Ɣ'KbǦgUjVef Jw +lϣġ55:]Gަ}HZdP"j[a:Jq9{5Lˇr%kAJv)'=<h(3@UX}Z#m [̻9 r#{yl)TdFv,K* D̙;<B5nj?[Ncn 3_ħ͝~cVlzӗ}r_ZJPFj_*Պ=X"2ip&ś<[5tL?\_"gSѾbMNXPM[weoŪ_=lI{ ~r+,rɵh5Gۨ<ތw~hs@^k1rPꌢ)g9?g64sXy 0AC+Ңu>ݳO{Iq &k{Oݣt*j[ߊׯޡ\(F"&JKV/|]PK+L7t5Ԋv}?>R6 $ 6V:?O2M%V8a]a٧;I]vAH# qꎺcV;|b珺f&%5.XuUR,oCF\~!Jm+o,jO ;Vr)5UCW{0"Ri[TҞR =7un;`%~NȀ[ryOU 2Ac9}E!.lVF*Xf)&> R1?h0^E#,m`j5Q_jrxDMW;q:8/g?Lg Z!6O([(Gؒ`ϫt>'w\ 孞(Zgq^"UcLbce땓qIlK̝ )XI] 8铴БQ Ƙ<2>JIczn!@9JY~@FӂW@P#vsVdGe["&dF6cL-0y6{$jdpE Wչ'K{(&U(8Eo^ר`u-Ȍ'Uo` endstream endobj 109 0 obj << /Length1 1986 /Length2 24432 /Length3 0 /Length 25674 /Filter /FlateDecode >> stream xڴ{eP-`pwwdpgp- {p Ge2+J~:m=f@sfE89erU4 3G?b?\6@_.{t?s`7u0qr=Xާ>f@dzO8|Z `Vc x&AfE,ff ol7`0[  : : 9  rAwvc"]L3wuny w\r`tnee{1Cd_9-&`d/27;ǟWN@ae?:)Op GH[6j%cO"o (\IU /9оD2u%ԍOc??BIѱ\M&L倊N2#RVbر8o{c4U ~Ez>{!9,Wv 8~M~,iAmVl9UZiګѪBC8]Y ^CQbn9,5H{!˙gTFZqsLd^ R\gb  4= 649+uj>;<$mX2.ǣ',g:dQt L 08Jߋ=} e7H#a̪0n+(MksKR=,⥒*?eWbJ>.l8ξz\#RZR)#uwI2cRl,rܘBoSRנTZ۠]-CrAudr8U:RSumvڟ SbCj䋴Yz6?#U k$*92Xt%^#NRDN{-bm2GUJiXWMf=Ze#Y z@.\vYIj/#k1If|Vr h CSZ|yFポ :.&bQueF{˟nxAȪu -I8Pƫ>ڗb|$')CHy$(b昏{#6ꮊG`yډ2?TSP(RFDž=?c1="ixL;)#⢟7n ?Ǧ^PmnDۘz(L]B=x:"lZZ[eaA޶(dfȓR1̈^~F.‚WY&Vytn$fj ygŬikUMZZO͡#]Fo;Vʯw>/; [."A:'pSAI(Z{Ǫ]M8`kx*8_jO`4-LGh{~Xްu5ӛۼ˽ SK3RBsFwo?I@⠷@9UJ/B0铂-]q D91 {{7u`gENj~r/f&jGvb-.\"v̪(SL^y3fTr/Mh 05.q=xdj _ MZRGW{gɨ"?_k%*=j2N3YUZ xP$ҘʗVB+)*X,HޔGd(|4ɾ$NFQ;Bg3yxf/=-R:\H,5fOVr^N|܁u2*^;pF`kgA::V'lY#S~ʤ"Ԗ( 9h ^" %qꖸTk_TJ%x~㽑:bfkQ21q ;m-9etMǿ-}8'P@?I!L!~ )4Jvn>RމB8r$l1b$f磌F4ڄgWhDmҗtzb$R`uNH[=}D/s-4v3EƏݸu1ڐNu}}h(H 2gA EBHle}Է}\GC"Tc+;?oE+^] ?ϹiumLr%U?1kVk6gX檆a}롂`(N17KC\mTo:->;g3kF{b77öN"GY l ?KӶ5,S-%maR^-&l黂h۔`666fy+brְRˤNcij{ j e)Kog:HO`.bڔ(t{}IoH񾾰ѫHڔD?/ fn w. J;J+VYX&N:(~6bKt \)uvNr" 1j0@Kq]h"AD :QrTq =j(!uX`mmxERbb`Y5y8A+K'1keϕЭ ?>oqîN?Cl@^}Ãt9X]^DK8ozFjSMa|S|_rZLWseJ5YS"iʏsMfTcP(k¢ E> I`# @#x#fmç:lw.'(U&,L xr(2!jyS jD.]ϩnwFM1G-m݅.(K7auS[SXhaL#JFL\߭gdvVobU fhLp*"~RlvhπKcV roُJtD]= R& /d~_.1^}nGkO `29ᑙ*Pli8qLzH6;ׯܷ_)pz  D0M?D*fgyJgL_$u !X@w_@}|-|.^ 4QQc!_.!.O 3T^FK$D1P_ˬU߇޻ @8D L֟ӮzH6fr~V `m(fFɼ !{ I5ScPVR *5X'|hn@a'{ym)H,u Dr \MhfwE5Q6TA]:߭*\6T$Qhz'V_'L~)earRhnQI,lZ3qFm?] <,}nJ*9eXmaBCsL{5!$`^5E$ gCE|{aȬyrv*aӞ 8鈝I: 1m{9QKuN'/Z[NV˂nxg+ÑUJF_o8EFe#zŸy&⮗䐎-Y(_drMg0!,QIWΒ.qO:V^ըI vN Di81V0 if,!Z@zn KN>NC =-b{%hXJ S'o)vLDh4rn.8&M/H$jIN[A6WK+Fo3qOة.IWq$# Erݦ̠]Yn~ȉE}ҏ7CzO"ȓ$nmčV$PEO_r D+N~bM:o6.>!<LJ`./Kg Ӓ{ [TsUPF=Vxϫ'PiDnd|fS@[oqX!rA] e|L)l,$WYߏM7lQ%W3<`0+Ѻ!7) -me?SF[ !\ĊH_T 9`% ^k>sHޯIu&<*p*$Wb}iF(CnnoUtl]Er),7¹ ,ٷ Ty~#n}21d)f>ِ4e/tߪe;yݞ,xW[o!I\@- PUhVu .Y!{ZOJS^N٤HP•$F[@L'Mȓ'9WپUhܢ4c|i]1)$}")rڍ$hjƞYbᩧwvWmq=ڥF9oX3 ,Q ޅI€}[kr"2sq\&$Ûj> i&ش~Pj ȬSLL@Hc::eE&a&]'?UWSɘ(on.J PQ"b\<7]D`\{^F4yS|n`ud`o]Eh yXTԢh(*OЯڡ]oa-[LN/xt#GzdX;ᨇ0YExߐ hj ! _ch=Jt*i$я%j.(7-oSNi.^tm@KP'0 C4X!Ǡ3LSm2Y>WY PShx<ҝ3ku,Oq:*dBH}X~k1;zږ=ΰ;T2to¿Tz.s5XY~vuU΀?:&(R0< zAV)5:<ZnZNo I89is.ma*f 4.>ZqvU欭1,t *{Kv-ikqwF$cbMOq/{ /d5fKot#\]}Q{Kʷ^hhmY~`{K "{J'0^8ExtY~Kؔ@b`[!+uzs{5+7;Zs=a e¿ ^VOjRDB9ѽZyR-E4IG-t_uW1B>0W{  R-i-/y'$mZB8P#*1 dgL/Sϐ|EW5;%ŊV>ZGiWsQ`\h9{4yV}p6 @&yqFM0Ohp췌%0Uh\gYggآd8BEEd+: Gby/ `ŖFbiOj/|jP>X6Ic݆][jζS,80&4ɮ%+2* lӐۣԣ<9쉀i(MyTa(k8ost 9QT'a76z"nYM;z'1 ̋]Htza_ 2;e;89[ Y!59kݯ֋z8&mKn7"WoŸV꧜Ւ3vi\~pl#$ a2yJ2?.{sA6 Ev BN(CsO= Pn! sl}M>J4y7h6f)$+(49/az<#e,(Q\[0UIޜ#0 [p{q.ZNH@PY Z+7W[ uapeGAfJUF4&$󬩵C7gBH{7.A-`#5>LאZ3v-<0OȲB5j0 P?2Ī}ȕ!$1 zu?Se\լQ,4MrܟC?jx\q"것1VǕ߭A,IL͹Ȉ*yK7ѳw4c0|OaV|jV4kf"CL|\L&[?>5$ص +;WsG w-?rx^\άdohs-hm_,u#xU/9#~Ai9t&afveXЌ#*VK}_J&h"BhmK4ulY;G};#b_v ̏s13@SM`Tt@]Wyi ↞M {AWa/v9-or/F{rvț!ZV@h_ZğY 4@ڃLJN5ϭBx(^57kY)3V<V1Ԍy+ o!;+ނO6|#u5e_`P(F.KCHShALwU?,S[yavt9ChkK𹓨@hkkqɯ@)ߪm;-t>>̎K?)N'jP~ч0cq6CցӣEVR O<Wug2(]pu"uDFܵ{;lԤFYѻrl H]Wֽ?-ૅJo%u%$CֶXǴKg"gDG:D\S3ޱpY4TT`%uوFDpk)"¥}|K1Q.]=08+`YǴDLY&5rUFy}vkG( =L|+ <qp;5sH0KPe8iA lwn`eޝieplU'XvŎ<P =jUjc&?8(BYEl-P5#caR~aOl 6]x/yP"\%}e,$j eW)U!y׏ʈTSq+Q!va)D?PU3a5E C6N0zin?}l]/!c]YK9G.暝Dե|9"{=f[^:)~b؇&SX3VK@7ITH漗qEVEn\>^;6Լٻ De1`NA_TO ;ԩ9i6;BSrÉ;ćJepdqEI[沯9TUwÀp~U؍9iHKŏ a.B48tdbhG-/Ʈ21ł_'b1xӷ#:6ŷX44`@fzɕ Ф'n R%2o!\@S9[ ?vwؾaovb['폤c._0zsEgV2F }晿' N ?;IS0$3Q&GCN$lɕtVSq>n S/gBpZȒY@bIM? (7|0l*c1$^oh Bhk>uTrBWN¶V=WGTcJn5KQn\W5ZG" NeA܌4|I^pG9V/Nҋ0"gu+_NR+neKT;d~h;%&t''!6! gxߕj*Q&-xGlHe?eAk"q,sWI3U莣qU rYp_&ΐ`cd9z!QN*a[tB?6SKx:7U^J>}\Q!K̗,,niQu&7&ĴCsaKe瑝EHe9Иȍԅbwd<-</ ͜&#{G8A)|Wށܴj4Gf4.T9_xlx7x*iw6?56^GԉmYmHLaa3ˆ%ln쥳 ЅC3֟x?!DeNw˫D9> ܭ丆RH~u(]0rcqa|r?%B2nzL$2.h7bl1'jNֳj[w~ep]t{TR*!|Mhܘw~ֽX,*{}/) œ eX[OE"g`j'MΪMϙ ivj߬ @T:hbב|w}a/t+&Es_ߠ ⮐$ ;sF;~ۊorP(|7׆oŧGϊfdQl^28/c!}dzt6 _Jz*ICiԘoz󈟺F|4 K~wbFFت BA1, c#GfA8_ĞW dcwﮨs >ٻ-a9S(t._ScI1 :ls~AozTWU<"G= E0߉awq7P? [G&J4KW$P%IRC5AVAoܚv~=[/uI ڷn]QN'œK/2E(Č>Z%C\ bWTgp;ǘLΰY;9An&$#y0=:Ή9< 3QBE/RᬰH6)8,WY>sX^y玳NT  (BRO<]ѴGʯ#E]L^dqnDM\jԽ4O͛B^2[6"[I?lĶ'Bɷ_| 1}b@/ǣ֯{L/$XID %)]$"Ys[F.a=<`Ҽ"2ES܅q4U]tySDP2Rۃ-wlxr_?|?>E;*1ʉO8 Ѕ# orogk?Qo *4.>^Z#`m ESzफ़^-dC$2e'T7DJ *rr̨{8'5m̕o 藏ڽf/ӷ*cLZBQZ>Psq/.!exwq2k }BQ7Pt8ᙊĒbnQpUh%OW>;d;VР8-K4t;;^vP4ļa9S.)d-oU.ѣʇFA8DIzpL%U]0Oi9#)xw4,ca덶Q] 2U8iOKN9AT𐩍ї?pY1 v=xMR!:Fwr \X(7Kbhh `@C% X\I椬.Km^)S{JĄI[$Ҩ# 큌/Dc/3ai[-P4}[yA+ PrbH؜8xDDOcpPݶgdW^fZWm8VrC7[b@[lV}WJ6o!B 3 f$gx"KD'/OFA?K1446#/bn" | T4<%Jjlõ3AKFxak۔\ʤ_1zPcZs)vZoؠcJ v*G2:߁LwNJ#-nW7"n O6~)K1͕evUQo٫bϾ)!}3 I@O2:$IC}%l@'۳1Z"<{c圢!/o{Jv;{:Q KᖺAMX E^X S s=zG'/?bى\e9('64}qG%E [vbwO[+Hs~];/9JrV!N]|nMu )KtCgDDNI .5Ӵp̂LNtH%5b>9d=Ѩhχ<+P@(+xv`{t%0~BJ9uT%YN1ړ䗮Ip.UPy هƩbY`dvBm7aV4,:徜Zް}֭šgW= #A%odXa`k7+B9:%I[ #N0 + g7it;v|LDM&^\uyIo\JE&`fG\]w][/XasB.mp2(_,' S77:(!PʼKJ{#eR;~73}M,KFO0"R"蘿 0rKKOrw_Sٔ0j悩o^T{{G+~A4AqH K(%1Y*=%*Fg_D@PCkl6KxOLhZҖ#JM_?Y6f,z֊~:ʯCөGѩڷo0&ÊWSMآǰ>'=epXdpJH& :⦝|j<rZa3& {cŴ,x\Vzf4:Joyvڜ"ej)O|;g kEAEC1Qun,*r C!^>+6{ڋ=;O7m8gXBE U&teE*&i<( ~kHtNڴ!G|Eψd^VI-HU'JH<ʼnK Db}TLGDInJQyʰ߭ O9ZS*V[Ti1O(}PXHV\DYzwai{+9-nȧ9&!ЅЌ6<<=eԧp3 g%ڥ9G΄]!]](j"NV=2:@{Y WJ᯸NpnbӌA)qƨzCԨTxkgY!6#Qx>Ƿdf gB+e+(q{$yuD6PdڿdWauN0.-c`֤Н̥q%$9Qi5zs4]\-+A g/6 qJ(Liŋ{_+wI-Ja*+ tY?s5'if2Q92zR~3BR2I0!Wy?6}þ"OJr9RVZ%w-}1_{ ^_P0{56(LyCU`ex< 9Et`,X"eY%g4G99p^,(7P_eIʙ|PG}+>x)W^r~V|J?XMs%h# KϘJ)'.F⫥IOmÀ` -S.aO jPےs]Gf`7 m(eśHԪ#t;qR$!5J=6rЖd\}Mk_ ඌXP!n26ȱVXJCx@]7SަdpVG(g)xpa1(HCp,՝q/vӬ;[(N?DsȢ .HBK2ց=(g\"Yk^ܰ"40#ޓ|rly+:x᏾^ņC^dR٢>I ysNL/ĥ?+$NDvw L%"Wy~7gl_- F?g@3jiNLuCP F9ʑ|| 3U"7ScE VO 7xz4cuJuJ|7uC+tn }F (()'RE,6"=Luj GS>y39&YmjS0*T o%!Ml΍Mi5ͥߎiD l l`ɢ)rvs٢ &/OrvU  [ )جƓO]‘*msҙ*]5k(H 57)r{n7z_;o9pIkc<|u/: +`i}BG!q.A W!2+@KfBo t̔q¥–/~0N´JV[SUĘ-],LZH,;4O5;VeaW0$*e:r׳3tPlb-Kuh>oq0\"Z}ЈOUyyyɐ Z?MP#8f/8L7Kcv+"N\:lKew1\0o]-T?=01fyMz.$*UCP&+}ۇZo?|67'~ֿp.P$R1sȨ[0RC4x%H<g` Q> B*8N`Z{%Y6Ӄ(vֳzE> =mRA%1=(> x_Otk(c>_c}uX98دǰfŮ#,;/6MBHmm߬i>~?=2Ȯ׏~ $ Sf9KgU搀qaOBZA+&#/$>`)ssFZiEQv!ˤ/Q FpV|<~*SS %n:5$͊r5o<<[ӘSv~"?j[=/I[@OLLtbV fћRUU)Ja&D+ 7ǮⵥͮrX/qS,}u,\_+]R;LtU^>H\wQc(o'"y͟lh]Vϛ3aCi %EztgVۘf rƮL81d<(" "kk5tf6HӦߧd#)Ap5Uj︑|^rY]ēoc=]8uɯ`b9OV<6aHVj7.}1T?e3/%JE(cSut}F y#ycHX{Ok#zYf|V14 pv]n%J)ḧ&zi hعvnO@+^d$~RuSf-ce vFe=jC<(06K|X ˌh$D7zFTП<~lMࡶ,bY>om^?YtS ?-*Y9ryNX&t RsH1T_9D͡g#9f-Mޟ]DR[aGs Ӱ-$O=@3µ(::N=wYu4 VahLPs%@[?| 0F QLG^K4&g]lVp:dmν}FW"iH=Tq w˘M r$­AXgmᙔ˝g,ջEK:åW A`ݏMX`]#_@ʟ\3VG.9ͽGʍJJ@քW d}3%IY Enz TuJ3Ou%[_xYTEd⍵g2;[PjbTCxĔV肓B(NheGT:ST ؿSĽ~IbOKD6 ոC씋TޑA}\J;qœX7B^kRw=oF386%k}̠P:PpB/~u+dVHɼ,YiG.ώA<mb O\i] ;| }l}gRVe;j'nh"QX/]􊲔  f|hJ23&|ؓ9s#-)ҮLw8s{)@i`ȣV$8L /F+-4u×V[+N&9ϧgd9liLiak qḔI*{VO-"۪BFݎxE6Ķ?^_N]}#NU6vqVD a6;1aZZ]&۶xmU]) %ZÍrI09UDf;Ȇ|l^" Yf$ʂiKTA bFf g%,nV[Y?٫׾r(!N:k)ĵYQsyCk(߷/X6]K?~jE7e1BGg4MP}`r}ڝƀnWHD>dIP7Tu%އNuJFbBv#jfX]_?^-DY_Jш#;p&ScEyq뷠]IAhFӫ;R;*UeL6zuCk=}3+b.ǝ3ɳ$鞭WlXʀc]PՓvW;M_5ݾaĎa.v#B`թnEc.!wbĕc|h-rQ@Rn'#E\Gq[+sD̤ `r0+XUmHoߕrsULRHV#Ԇxb,#S%pwfQP)[4$ؐrv ! VAM>8*J*vHO%}%2Z-iurc߸+.!Sq^q9CTRcR]m>LٽbC̄wj2/2\ Sճ,1(QM/4FHRVkr ~y= Vu*1gy1N޾eY78 %8`(`2]eY`|w7Od kxp?Ž`<]_ ob+lhհ@~4p?Ød'˧s@{E2S)Y^Ux/sA%煲@\c~SOlnLQ\n~WNB+`İn"W1Aਪ;plv4u{ c|HM6)[I *.S𛞉+Cw--1j":H/[2Q81A][\* dLBapc>j[g!*2,43*:?*BzN,vI FLɊ0%D@5;> lV~1-ả*::4]{뼞qrzgȇev33Yn>,3fptʍqIL@tyqTyOl@|>! ]_ -߆ۂj:;ͣ`ZarJ/fV9uov>\' ZoJ(87A^lJQZǥ%Ûۓ7Ɨq71!L쉂$xXQ/[_8/r%.fDY*8>=gTjp2vŘ o\tأ]0b,΃G⡙[ pvғH{m GS|J?ǽfH=C05+u; B b^ÏlqkjVVvgр$iܼ,7{]8Yw+R.>74w =QlUBd2wxUy 7n]-A(OҔ2gXb zѡҲq;:|΄yf仃^S^ xe|i^[k"0& 4w ψ'wjXY  *O P1U;}L;[ߑzYXеvL&S ~HJHzZUOjXK|d@Pm/Ŧzܜu!a[Vh3N&0CC9S{>u[@4uQ%=N[O?\鸏m) |̘Je&&g#q޹apDN5s}/oad t'oj^2 6%K::l[1kIC3ȓ f# bًUΤ]@FFҽ ؗ+_@mO DmG εOv T+`;G9}NI]W{7%ᘚK eZc+yKZ=Vy'y1V)wxO=eGnezMt否pEjPt5de!WS6DVhT RoEgDӠ #mKvF>bPt A~X lAr!cA"_ 8]KZ_`CoCOnor]Q.|um:v“>Gy#}Y5Va@c΋wh@XcdL\NFxsmXBONź39WXDʉu eCAB} A[UV20dl.pZC&ظ1[@ @%#\#2ՒB1`GsۋRRJIJ|\82]A@6HJ9kZF~*Rbq?jqL;q^Enin4BZѿ-%-v,|!s{t`ZjO' _ l\66^PrX$u㘜;jkެN E \أGk筎Pz⢌{s9Kn ]8'L]GV3"Stf 8 2еB^zi&xKF1tHPa'YDV+CLP'8`G=+9UGL;U'Bۭel2 i41ž &^ߕ2W7y9q `I/_2) nɋb Cg[JLrp`3mJYMd`5=t_l'J6/WK1bלD%XL^Q3p2 {N{}7Dj_Si*15 ;_A>6KPc-] $& _,n.;,H`u;dYG-JV*F SպƼ٤88R* TS?Wb;Ve :;uWY߿ /k͏Ш:"Z!$.cQ;KGp^2[h-; W(Mw4u #Ya8>*qإdb)''6WL2LX-Q}ڨ)=(I*|%@&+ioMU7i;Ꮅ)1|3UIrf~G=W3<l&ۺxn^zq\>j7RQa$'KoeN >>W$D9NF 4]VPoTqr{YK zdԢku^4 lÆ8OO}-S(H8}_n]H4Ӗ!kwƬu f,5ݬ-~/!chWM$Q>?3 # ӧsd/eW uUv`yxҀ.2 ̣Xɣwr] r0p^rڽo m=h*T w6KT62 (H܂q~J?a! Wq-#e' =<"s[xg)[VrKg pI,U?MiE0a?$[/p7A0cy5yH.~^V_y.!_z'pb5)sL o~nF+k۔BؘvJ!d/ ѶKĨ%a0HAk dz'2[IVMQl%'i1m!@9f/ Ō-Kl =Ƭ cC ~ʌ]tEɎ,sB7pA-"\=bOOEBD@{( ;l V'J'z39 T8G׼OML_?y>"Ӏ|9(_4vna %W؇H3FcbєutŠ\[΀r9}'j uH 7'rAֳbjRBen+jJ&[HiY*(gFkt4V^,2x(Sjnu+o=벐Ghc:.: Y9bW-}vl'ӫXc+7hlɎ Bd bp݃plǸM8K%Pyx*yhLʦiJi,f;*a+ v =`?Q7lC'ؿd*Um$2yмLRV3py܆NO89W6[ެ!!ˤ>OZçb߀q7Z <5p&<5Yp: f\ bt2Okb;!|ggE)-Ta `WW5mLԜ}p`}`x H-eD R ܃sfPҼQwǩ 򄤁@p/h&$^ #2B)Ro3].~_{pbl~<] 9n5Ŧ3d<;[2 *v{'狼yZ2E9j avg(YVSDu+ l2/ s\K\Gp݅VH(;^ʙS)-5Ɣj{'dx}}G]3Y+ %mh L_ۣ*m$sKt-\\h !#25{UԻN/51k1%R ͓03n0@Z~&TRXx8rf3ٱbG-*ԺX$r"2 Euf WŽV@nm*7aIAdM>"< 8m6fbC?D0ƙjI t@}@i RCWY# ƦI aڕP]^H?]̍J@քW+dוb 8`؀ie< e<Ȓ6rbyqzxuې8Iw6MUß}9.w _Aw̄fN>l endstream endobj 111 0 obj << /Length1 2835 /Length2 30179 /Length3 0 /Length 31813 /Filter /FlateDecode >> stream xڴeT\]5; .S8=hn  $An%v~b.{>T5,A@i;3+?@QI bceRZ{8ؙYY9$\f 'I3w ?bNG!QdN@W`Pi8f*͝ :Y:) gW[k58~W- 7y̜,Jeh 9́6fV@ ҐRȨhj1 kx8;\ #@RLYS fhih tf(k+IiiJ^ tuQRZ4ڸ;xyy1[{3\Ӵux\OW0N`9m*{S@'7$iп`)I`p]_7 ؘUTUU8:̜,fn?67В_ W=rOSWf`;fm{ '7[7wUlٻ3[?6%1e9i) M&E91)81{]OLR<<vvv+xH,%@`nH哴ra ڭl,~+o̢dh `]@o Lo3o3X?g3 `k y:!,m->,H9Y|2#@ҁO%` BbQs?=+ƙ9:WDsU:9MhjnaG/d[ ?>DZ;|\@ ,o-MME])gdI9Y,m\3WW3$Vsq#m 3(f';8"Ln.oӿ7E/HEɿ" `,2;E/EE/sQ\"0E?E/sQ\"0E/s\"0E/sGq#'l5A\`:a]d^B<ɢ=rHYHWp.uHQ(0=ĩB*;K5}@@B4)Bmf\~rSJnԙ_w쳯75[Ű^lخ}}?͆6LK"q2K4u>eu} Yω!X(Z< -[I}ּz 4˄_ FZ;'vubG 4} cӎ0KC;2G`3{y). #Ft Μ!H;ܜeabxDc .ɀ%BjyU-f{x`n+< -j1 N Fg=V4 $QVZ~.hd-pe S~' zcf⧻4g3|m7Fz)@+<57Y(."*}9*bhu[5p-jK١n7ߕ X5c)>W& LKL-n|4yTgxaWlQ%gDլe:[IFHl'V?\Ѝ_Ll9L(w`%`1?sшf?!{qaXhh[,4Əb=V@ mB0uR]ub#_s{B@A'^^O(C#+wkw:s3>j;r)LkĄ_:QƟrP?eD#ɗ9b3#cGÄՃ #ӫ}Pfmtbo>N:¶v1s3ĭ8nx͵[ #zLi {:|V2I0<c5٥O':$_$FϋsbЉ["2*@9b u HE7&9i6bTV2_kfY \O.}I,AJXuI=d%z̹~vIЙz]֣_IDCk !̯4ǢR>"\#l}~=w()? k!]F˜I53Q{;Z#R?Xxowƫ0f2Z$@:?_I7w҆x_-x+\(bF񋬨= KA4)6YU(1F_2ݿ~Р)jr'_XQ/($|ЕQq-9=Q2 AN FݕXס^3Vf݀]fbxQ:?wifwLXتObE^M^0" F$A"J pcje; x]I^WdT=q#!M5?7$h ߿wtNllX"̓ZBDU bxˎ,01MwŶ @S|EW5VȼDŽK%_#l vz|l6/ a~g׍^>,VNS>-0/EƊU=pA7-O$c>Y"a_ž9@ : w6 2ce"9B 5-ȝ@4u ]هY:U,th'-G[I2-GcI(G|]".a#hz.,Zxs?^]Fp!-:ӡ>TVUw,'[a)dN族F'6_^ _O !k :2<1PI@h+;f6gv? 9D0nߐ$qr>8&ű5«$B8z,qGݮq133taLSÞ[a,}u)9pzџ'3)6S4LUzW}12i˕aڈ׉a/UpFܕNjN=N!yPuawvúA~,v?]I2HJ?7;LQ&ue'y8CuBeR[Y`ž~xo(wK>/ZZ aOT0S[=U177.H~hBYsO<{9$p.<0퉯'tDԬ{ fo 4]W ҪYub]k ]Xu|*C~~r(ÞY@3{lsaN>p=[)k(#B)1|bW[K#BzlW@!]bfa%2d/k:Һ/Swzc'&6W p $qoܘ7T#Rի;D%1:.կ r"L3Wr7)-M-CO.]zzr:q o)K REn >bE@RK.^Qzju9hMC\d6uXw=zTAh/gU]*ӓ.dk+y)1r'|W  /7NO vgqtj+(")ir`͊Y}R,7gݛjg'}YW" rvKZlP2xI澪xt<>*D@piGv9m|+u<v˲o$QG{<HVV's 䯡'q!oG{'@x74{V:|o{Z;[:HaZv.s֮x|_  ql܌iK/ލ?mWRYMc1oڿ[;yh{ZG*.o@v]QɁ>s0Po>[UoAqB~roiLO> E,⃔oI*bxn-A|:>Mt+?aCo6WpU{ S _%t]PY鴁s(-N bSR efaF E=޾ u2:3Fuxo<էl\v w)^JpGpB̳5EzE0IOi(h+ژItdBH@==I1`U|"fTumFL@;뼛 gmáHf(y/#o5}tqJlSsD5.a@GBx@hc7 H(nYOwwB|c7|VjQSRr=1 8,k1q o\Rc 뉨<ٍvRDjiҨ E+(GZUxJ'Z¤AM\OI9=t &GpV3,1#e+.5\i{jl3ǫ\W|`&VP/iUZj 8T,)$\a,Gv:pOJ" Q͓R;p{$8c8u?ti2k$/@%_M+9jx8%3/V,5 㖟dTڀ Van_lnP¿q蒩#M: %.x@Hz٘D^AML6*Z8-R_,x= /"ֻ'"HER~4üTY:$Z h)Fw !R{sJE4n7te\5I4sSD GR@i[Riζy,X^ dix_@"3; 8ؤPԈ!_ԕp(Wd/[ pؚ[ʞU 2$q,$t#O_jungp 㘕z;|2;ezJjC2b1̅@_|GI9˥__/+a)'\H#uZ#`t?o0$H,b5r wпݚ2/ɍ~u5So (B['go_[ZFƘ"ɸ-w 8}g:TۖdGH,=F08^VV>ڜE^HVrBVVK-R,笙NSR.s1MLsL'7%cG)ē).{2D+TgoP%7J\]ćg7w0HI.ǿ]H,;׷R4lf;GJ 9h,Nayy rMD\ N,rEGx,*0KPi?r1-U[&:8Jdȡg3< mTsڞ%vQY'ExANl=ɫv ff5ُ=1}%&y8O|z틞-/n V/Kvc5,P ]/D$~J0*`%+bH ah Ψ)$ t9tN2 %bD}}YszPM(ׇwŸκz[tz? SrY|Zs褬 ~'_mTeUrV:?TL);0>\צvಋ磅PM}Nܣ`q7z?YMi}ZW"xOhM /,ڟc2UװiCtYR8'lLć<;"7Z_#sMo%`k:FM#q *{m9J1Nhomc2bc=/do? ;` pJH/kh[젥rLpLPoAgJI"$bZ5L]ׄWh1EQ>;)>|}ǯ1ϊ G)1A!/'p)!]@rկĆ!,"ds +,/s7+Y3SS˵G"T| ^t%Kà ί_A1K'3|'AbZ}VruƦX.Kf9υ؛$@+9wKqND/1ciaT KN`>2WbWu&u"젅=&U[:-f`|/@VGT}gƤ$7ao+bxtzw`B9BIXvXg Ch'Ci0xgy[L.~cYjDTwѰ$zmG(ZCtKZa+/+@65_9Cm"~F5̦$ #$<0?:sKYɰ?^鋺?d^wQQe[Fܢ|r_^sJ^ K9U$Vr?xUژ0aWOR#8CRg1gzF: k>~{#- ;I)qbS5y1FU:m8=Q KOtu6\Bؽd25Ua硞Xs/&r#MgDvSsE"6L ->K31ա)1Sπ "(ڴZ̬4V vMh:կ~Bp.5i;Ut1_+_&cŵ6ܒ _uU)Ul \w}@rzƮ֍Lq͇"s#{dFzz@2)lk%2>z DB0wt"*U^V0`Q"oRkk2-"ݡ(VSې4GءL!FLn%Bzʈ1*EG $c nߒIŖ)Yoi3%ϙo 3| حcNd *$*ۼ' d{Z Zsyx7,3g^(M!{)6p+vCh%폥`/GF7ǟ.?>ZH$4fdzEk?1Ⱟ̉\ o Tަ3XIR85ⓠ=k*Y{6kT; MX6ϒ/eC`ܮX̹.hVLkt޴+43}vaۉRG.ӏ(>LtqH+j O`Z+AQD紉=)xn:]~ЋT]O|vvb]vj~ۘQk,Ld[^c5Ÿ9g$7%L^-4JDžSpuY6G(B6~ٕʲ%OREbMiYpK1;7xgUr: |ҷU#m==]T yKxdZ%5.R&Y?J'Pnrהsl G5{WJylHj5E_:ijn-ɮMVyiqW/b_ZK Y+fW| D`hyCN.$lWny?t1QEuF-*#lY\/g'+yneWFg0cXV9.7W(|Z̉jj9Vybxsn&иۿJQPj9/uz Vfؗj"/TD;nvS.#oF sG7ml[; +mGW /6Kу߶iүD7<+]" Z;5LSlO>= G6{. {ʽ#t5ݑ{J S4!7=UQB Vd.)mCS6t-PL௃ ɑ*dwּ߹lP;pƶHX\ RM?G|j)Hק=ڠK8|ɯ<]%$Ԯ|?t\4`P A|VI+:9l:Cɼ) m a,}_>;1@]{߲u~d 6rx9|hsՈ2j{w42O+}} )67k^}fϊp{^vS_$s ^p 1l\qZRk݂Zh'ܧݛF ;RL=`Vo>-ќS&VcLHS2{:Q1X'id8wVs/5[=*#[<} Bg#_iL_v&3UFzgFu|@t)2H-O~ߊilo$) =j+ptc,#֦dڥ=9C-#qJ SVTpl_ǩ$:c~`:ΨP!h)Oo CR ?o`[LQ/}{b -ZyAnIKPFjŒ@S=Coz(pr|)MZap^?aK( Ѵ[,U#YUg1a#h!nc7Er2==³Vډ;Z\ln|zDy3JfvLddS7ܐ_Z|tT'3%1Ow$a~֫in[aU(HN+Ciyjk٫MVkE5.bYm\%zĿ]uTԷ$ǿV~pб;%):OAs-IS}O9v,RQ:=>*9te"X'zXqGg]d=w\Xǹ.y Hګ${HLʧm.m;hJJz<$.Ox\șLVHOsc ϚjY"|Z=Hs4=y]gۈXf]xiN=I*e]]8zJK\A }K%8/r" 0(<5ސ}Q}W]xjD]IRX_#BIV"|.8v]B`urw=K;T\[^g8ZΞ[:qx#攛*gcaZ"?P:Sc`M{QmӖ>Tۖ7 tevzs7#U6 zػ7\^_Q.}UJ(9"I)K'iH[#=\=֫B%ל8u.e䊨=AK.|^Qd7:HK7a\Z}[6"l~jѾ;y#שN|do]dhQ2%zrv^ek L@M]? /[{^d{t)գ7߇cs{Х;SC:TtPPp&+2]eh? &W{kÔd| |T^k[듛 }3B,ĭ6BHR*WÝ8o(^c. CXR:IS5HCk+17o.RrW ^? ޢ,ef\90Giq-R[bެI(@0{lI#:zY!9_‘QSN=.ͫ{L񤌓|x4ී콘UZjGb *}&r\~Sr|nB+ :AWPvm@;^GZL&}FZZ"qd:Eҷ8&ՐjVSX._MR*!-a ݍHfnkT(xNYXXGE_ܰ'(ʻƄ<3H/v)Zv^cg TlAJ|p!:|;q8oEJۚ<|͹9Ak(f(\*&H1A#zw0yYR+Ytؠ,D.W3)i4Csf/$-緲Q?1M׶ :u[}Vb^sW- Mt0'tV /?/KҲogܙ:]I)ĔK1A|BkNP~{,NS'p5igf#laqkݯvfs9g}OÝ wn/8W} YW$ƺ Uj+"s(9m&`?}.j H=mծSrԧ#\.~nU^G~LJFR$<8uFگ /(`Vҍn YX`<ElGeWn}`#z(qo!(3\B$_e.$yѱ?+h2پ 3k$/MgD|m gZAtwE'- |KS?iEzF Ɖu<Ϝ2d"sa%15 Ŀ4e]7ܮ%I:򡩸!Y ś"ʐOUd8bm?OZ'kh~B90a܍<(jSyuM:JL+/=D4t gt`*@n7f ۻYl/SQ}ؓ49ِxBD>4EfbuH |TF5a9hu:yOQ:-E8Jn܋JSD+~OTeE/7JrP2{$)i( qjf):Їѕl޽6y2@?E`I|Cz-ֿ"ZLS/jڧtҏsqK4ҧ![XXߜvn^$jR%?uQ4ِ. ODLȜ@:NƖ㢺qDŽbY|nsv*gm+ <{#xn1[iWRwbH\.o;Iw j;%QBGWV˛64)GB4atݎ7F8yP * vdQ +qvxCT0=QJA0AcRj$ާ [a.I7DU Bf`tKJe+)ns,.xuo[q#K0R&&=$$6t/1eS:J?ɶ_M`G"h3X풊l]ʝXF{-DJ/[߰'R0L+tBrm  0Fw D!v IXօiYUWΔ[u!1i!ikai2⭀td;h)`1:_ :!_,0ɒS+v -u[R2YỏH81wLI^~LqF8߰Eď15hdY*6CEIKwxmP4[$j*; Z?&MQp$,. áMJ>Txs%}*>p wB9ai$Gx)mS?mO<$OG;TL 3-A~pͮҸ[(;t:ޭg|gI`9aF0;z1cickÎKLKBKKh{,%!>-cJ`pˏ.x Nu'tlgaEfB-wpSͻo+̃J6>]ߞݦץiHw,6$[SM(Ԓ\mw "+.&(#Wbd3N|gH,cQDJCe'[Ԗ>V^}Wqga$^%dn d]bA:NH06.«fx9Ka夣 ,?Vk;?#U\2H'[+dr~F x2|k:N]k" ɜ2T֮K}ɣkPda |3L,b3g`7l7Qv%`K@Z{W(ǚqo^)]0r`F_f}Q T>N^'*ΐ,' uxz޽?yyˏI%h)ܝTyxx9J P (9NW8vQJ)V C'-# YTy`[俄 }%iϑgiu/[Ha~K?LA- НDd5"®)+]l/UTaJfԊY6FU(=4_!+|aiGOOljViΑ/5/a%S_F+ ] :5M\o qO=rIqseoZpW^d=iNl1H?pU07fnu8wT^R_bk1F癳r*"hՅaҡī鵆`A9)).epa,=0Ŧ$Qnw}le8aRlQU" Z cziZ|&/\&# OQ"1 :e} /i7UNDVųsbh2_Q4rbS÷J1d? !U٬Rj%"`Df|MMUYHނ:\\<'Rs+v70"jM"jveǡ π!Ï'RzJ:"r( P> >4q5P%¿yʴ4PgR`Av{3WhQO.Uh薣h۾s=Vxh償y2i7"L%YQ] ݤv:i!&@͍g-@a7ߝ,OxUF) G Z 4 ؚZq*,Yv9'Ϸ l6GY$H;Wkgln-f0޸ĩ BCпj7(~j~Tc;L&U}< ~UOLrR߽llHHqbIŒ7R2a|%Z4۫\Q'ŵY\3`ݰh:e1#W >MC^df I5pؠrdTԔwMFܹX`aHW19*b$ &l )9X5}^6;@a(IX/cJ6[ޫ7PϜ> _@bҾ1(cNH[i6ʤnA')Xq{ᆮ72܀{3}7 HԾ|1%6d+^Y{"Ldjt_!@&Ԁ_]jl x[x< xYsM:7zjXFjzHgCp`gW|*e5i\g a~n}>8 д UcH ̭2:U)n IkKFy [*VRa|l1ɀqyDn4QCK +kI%g.{cD20nil!HqY'4j,8>{%Ux.L2 ij[xfmweAP7q2jK՛ZFsN(݀U AwٹL,J - (r2bﲸ{:3`-l 5/ԎvsrS]*UR!)IB>Zi}7Ӳ#ovV"~0 R=F| S#rzV-n&p@Lך3ן8)0n~Ehor; ZhAab;z$xAM/3j(Ħw~9l1L/h_'Ȏͅ- d3ezno~+hK,B/}wM}Ѵ7ަP"S.w$c(w D3s)aMu">#Y0F$| R#O Fzut-0Nw>~ m@}&)m@S\u߶0/zmHar*(J z+e5Z孉7nܩ`ӂ,#z%f,DbПeN_ & }/d̺[xVQ>@wX'@ h)[a_79X':+k!EA*/mhRHEYFD)qc]bïL ŭGĿJZVy'y1V)wxN F~:GlRQa}f?J)g>;V7Q|J=/u#M&@ٍ"Xu6nާumf|Crt 5Hpw90Y#s7WV3jLx7w "確`c'?ɩL|J͔^o%J yG\Ip븆b1 L28—0lhUʩ *2 eNIG<5O|HYd9rE+n*BjcY M4P9 izOGH'v;/K:6?Q _A:*5zmiITlgѥl(D%o\?݉s0Ss8_WcO ~QXJ7n}0Ү$PO.%Pcޚt"kn`#F ȣ锩q{nq)'uT^V Xe*$v# A)| ܿn[Xޫ,$FAap,}L՛]iK\Cu*Xd'Zem>6ڳ5\>1p >mB8LTk~/{JD`5yB&[ ꙅ* tFTøi J:i$e8I(`!HP ij.7@$?<(L~,g Is֢rv_[vNT8Ҭ{aŐ@=i\;n-lmb|IS,k~iq? N@.t}jku{+G~Oe/ͽu Tչ2@&kƽkԢa҉LJ׻F`苉QpwG<_+"I)E_n8#i`C8g1B9"8HBV~U=ZYi8Q@D|zx4OtVV8ur쫚,Р Bfȥ>DN`&&;,?&pEUgVZ#1&ZX@^r\L:)zp.줩w_G[=w=Pdcw xX`5ZzGc|Y)2!)ҏtLN) ^.C4 GH5 䏏fG ^&B"VkBdjxx?6srNvm_B'Q; ^vJ!{ˉqL[_ɋ_.0 Q_kP\,GAr>4$Gt[j T߾sZc8n- -dr|jpXéf@yPZժ6;v"@/'`= 4|(\zhduCSym^.i T/bdo3 k*vaKO l8|t 0QiTNHͽKcaR'#}:+ӈ+^67}a`שԐ>Cg o.0{~ӱtm@e){9ޡ3C@>-%V<$xq(>e&s;6%,jMED &"U6z̐qýNVQJ9{ANQ3109wiV(yI MpbkgaO"ݷK| ?[z$/#,BM:!ʮAqcy^kTmsFNҥ:~2b[H={mǯ0r'"]Q GJ dˉ=~pkVJnTq4LێE4 /p>;O]2 IuԤc F5uotz }gz @ZޗJ/aYomSEc_NN$C1$mM z`Ɇx_9B́;U.QPrQPfF5I5qw$=$tr3bFXG"SADXڟ i j n#tB婽6B{ r~Jp-r69n?b^z|>):%Uɿvr#LT $K"}TE!l$ ŝ41揨;c8·$O1{zOM!*0_ڵG>4A䘔` 7'V3$i$oo*\z2ipIxr&yM>]{n0Ǖǣ `{ANL%&K.vޖbb=BL^VU޴qI 43i"OvWS.U턪DSCR_ZB|[֡0Gjvڋo~KEq2gsFmd.}=yV7mY;QE ~PTg6e4sf7Ǹ*4!-TPt_= Ue r>fh= XTBu1Dy]nAOڢ76*;bOEn+\o//AZ\W_< *AՀ#fw8P}GTI[h>OA 79(?;A8FbۓئlW/]hT}b8Ys--`L3bPL1w6NO ,U_ϲCk O!`We>L;#*+X*{S0OkG$|*O׳Tː}i9lUeh2}V/ڶb7>&keoFϻGB:rT1 ` {C9¯'\L䲝ʈxh?[4SCQAOZ^e!9MѠTl@3@0!]Q%gVaD ,k̨7VY$a`堑̏M:V[$K_U(ڞ@bf8{( 6nL2K"Mbidn(Wgk@4Xw&F -m}ξ$Z2C&H%\Y0ix|`2\hG*#PzydPl_Vg{xLyt\~rH;h;Z |s&LCK3K}tfH~Cf/,J(8*Fgªq)qdzJi&to4^fH=wVD!BRW Ѽҟ~&Mi_</ȟ>SMU%2[--!]Z080X֞cX{e蜱uNuLƾzPJ' BfZ`|)%$jC`Hal\5 1OiH~%^hKw䥌CT.@luNWN0ksFa0b]*PB T6 `bw>"o?p2)Ww0@1f%- ""VbK~ w :Ƃ|T9<OJq&uC!snu)R^M9VuQ< [yLYgbCiQuej~@1"M/ _-7WzbAI߸Lb7 ;y~^DkrHh5G^-z)t  p]*0{(*uTY\bp=t{>[&ד֛,ģ4 Ƣ]1(3NG̀:/BT] m@Le4v.{'e *w]gh=y^ GUנTꂿSNUxUܝ;*_ cg1TjXP6D _O1j<KE9cV=N^`eSMFY7 0|5N0sZā,վrK}۽|TTt/ T~_̃U3P#zh ]FQaΞ4}yV=J hN;YrhK9U/+HTbBͅɠESۇKI4 L,y!e"{=b@*R.̨pT7Oe^'[N2S_sI_GjyV!WBmo|?M&(Rl.9&}|K҄]]NۖT'C!9f7VӝD\M[٢R+/t`]Yc9).ɑO[aT~47#WNP0_=?XiLi`+IUkS*SVhUVG#"HVJɌEM1bǝ2ihUX6!<(@78uĽ,c+3eܼFۄ Tq6 Y[sZ%[첁WC,HBoȰ/qDU BD*r vq7|saNps=[3d#bXL;$}vRLIE̮M( zsm3S:z}Dk9TGHAq=B#S6!z('R7>2ɗ˄~H?MXT!Ύ8P'%rg>lo DLq3~ţbvo=͞Ov(ҹL4w1mq(Fsz#ۮgq{n9ZUYT9iٍІab. WPjJx)͝L@di%&`ġ+-+ͨDQZNv70@ w١9@T^S$9g,n)Ukb9K*|-FRgRĐok¥2(*=3DQ2CΧ.1_F0&7c`lӸ%OK \4yf{t2ܨCbj*=8KU;B:(CNQhcX!Lǻ?$u?hP)д"`42&kx{*.dI7]{SC.*H(ME:HU/0_ z`upv vA^ǧ 5, *d8SL5U0 r:NS=Cw_Nqi0&rc$&!lg^|ύW;_,1d95|k#\y^ I>rf<'Sr,XъeVi*]g5IV'gJ,S^L(c/UBU ܃sfHk'1%اW3KH<~@+ o $RrNlC֍ ӽVs3sp4O f&K)'AOr8v7H 9 '7ڈt4:orbg~wբn9*T1~>i d+4.+` endstream endobj 113 0 obj << /Length1 2146 /Length2 16057 /Length3 0 /Length 17385 /Filter /FlateDecode >> stream xڴeX[Ҷw@%7ww nB/=hΪZU]ֺ4 )(sf`adɁ@, F6&VFffvx QG%N r(8t23S$v@w) t6RE3ӻhgniy_" p4pO?E2F& 7'kK)@Q r{7ZAvcdPjTĕU j*4U\AETEUM &,*$TTUڽ7ȫy\N\UXUKQ3X@G'?eG2ޗ9l*pvebrssc4wqrf93O r:m5%'YK" п|_nwF8ip_e,Z+( 5sٙ:98 M%uqtSC.txٹ8y7& ;'K'ge,m;3Klr* g z_ ɾ"7>v [wN'f'gc635wS{&5;Knb_/{= ci|r2r]>^t7pL-M] ]ɿ]7S3j A@)Z.66F@ZxWDhH9IhhlbWeW%a;s _?'}t߯?׻|Sibmtrpdo& -UEL@vVN<0rpXާ״@K.>3#}$/0LIo0YL{7^o0XŘYL ;?N@D,ﺬllFweb{dbk爘˻`?]?]?]?=?w.wwn#X*gO0{/VqvY5,M3rvta~X?O P}c݋l6翖 ם~hg4_[[V@S0Ua j$@ev(ARz)vX6ړgnL> O3fɭWj}aH Mta~CJ%խ,v+YditAw_E&Xw~m4 F`X=!U.PUL/ N #6c4:k5'ڦە+w,Ag :^'w)|i@2QFG){(CsO!SfEWhօq)eKEΡ{V@LRcc]YX6 MlUMfIvy*`DAf&JLRv*ST%.v|XN(*_}s TX#3 x1-7hѯ0\*BN'S۾XK.TgplnJy.x) )4r2Kݱ9VȚMs<5_]I6 ~-]+ I(ԍyQx3F~BAF ۵[qj =ՎIξSnp_)2"{ LyS^c69+9ӈ"9 Hv޽b3!:jFr8 +$U%2Lm{r?^$=ѝ)?;a(d~O[w"Ue:kLRyh}0G"9LSpb{Y+QiZӖtl V<`vAE%CTFlKT:F2^aWMx)KzNb8kQzgp?&|Qy].P38,I"7[.62S<<"*l #x&3M6bIčtYLf~7uCSJJ:[c8^_rSǓAt4Q;&;K*VYz>XpvI#E=/HT'=FL:؏'di>y8"% <&(3`FM>bC ޣ*EGTB(s-*׆ܐwA%B#+i"z ֓?7 |w 5jsهXl/;4-SL[kLEx4\K ep)>:"gӾ-2F(y{1 7eح ^[._y q@l&i_+8x`v%L0ϐ̦^.@Aaq!8A`dx[5bGAwA87<".;š*~Ml}A M4$Ҩ N~z7b^c_e`d"S f1 MYTR-$!>P)]xC|_Rʢv̞>"h޺xpZp>J>">@m FL;<:v[,}>9e6~- ?gMNww˵xc-W*(]ce`6":j nRfعuOݘmΥyΤG+_[ ;(fhH>(+Za[{i\<|Ii-YM–|nG^Иl3Gw\ j47i'CJ\|Q>Yu7?%&>7#Ga {r@Έѧ_@chpjp1Izep+/n~ ԈڔN0e fQ#]Sޥ>Ԛi'1q*$Ij[_0w1i97{Etj-a\޲%HPu׸TYc۞H\ݰ$ MgZ0\1|Mb7pIƣ +hM^F*tYr~iUfWӽt6߯L|Inz7W#J ܚTL;U}BX_SvaLfӾP>B}hg08\e+Cd*}t`>rZ#o`jm/,nY#qǎ%z7GbRlĠ0/6:z꧞jytʨGe ExP%z:A&h#D8qYuԅ_ /FHW~DO39x=y&55&UF4p r||3_\)yX)Jů' +{؟ B]mH3/*ٞQ*K+BD8 7mY!B+#~x@ B) u}[31NU/żS>q˻+M{EsNJy0?}屪e@\UQhyLrX5m1>||*аM)T-F/[oL.>V'9{U&d J;Uu#vp;J *`fFzS. rR( F5o Mo9Mʹj xZ+\VG }ƣ;DOrsf\8 r & kjg(XNI7_0Ō(tJ"mOEHdav )XUW!?>qigW(@{\dpQ9g7G5 rS#pcf׿>ZiS; [2?, `%p>f <{<q0B߆ڷJGwaBR9[p4xfE85t!$TmNWvQˬXw,ݥMq7:Uj(4r6B_ْ}K "Ր40uLKIe~s)cHWFcwA=Bi.p('$ ܩ;fGA+tXF<$LXE賛xв?ƣw?:>鐚HvhtS~?gw1V h,YTsH˘<!Az*BR9fܾ CiF>5uڒ(Ǔ[2Vlyy*[+1ʖIԣ.>L䶸Β!аӔr*y-O`R]my a9׽9(t1Ag[z$B't >La8VHPyEn},p~r~xShmН` MP2eFLWG$#{Fg_(a(@U2$t̲8LwUEc?g?"+)ڿI֪,~`FxT fo@X:^Dݫq8ѧ4L˞~nhrF{T uQ=&LW箳xR*WhzQ=R,71bς嘁vʄ~A'ZP0\+oi96'@\[^Jlط۵[,UXՅցoHWՎ-n˺Vyj5+ Ũi[2zZivm@d&K7ٞ: 桽3;9srb֨?jsD959+Ah Ɗ4@F}Escu3d93Ɠiw5ysةE^E{j ^rnHhbj@v~E>o[va.-O2ܣLH}/m6Ghl.E3ю/,*2e8.i纏V\1çɧڅ|88W%[ }]#\5OfڄMZ?J40t+`Ox8LFJ%/E»v_.#rw5 rGܨEt m5.c V})`=P ȳE-1 VO_G&m0c;t/OZ̈cv/f98ڕ]jpAq45gX+M8Aϡ i}\fQFsj:2< 8T>Xwhα0V]P!CQZ1{!@W)j*y%5R'YqT qf񅸔O@w}/mHǺ6OQL"?ZX)oLUfȤ~CȜ_.+̓ZRçl֓7뗝Sݟb.F0cPK>,RloUqs7 ~˝ V7c "m^{ʲXd&/8RZtM }RUk4m1DɆhS..*)T"lgvԵTU˟Đjȯ iNU4(%N㯏lmr E<0VU.3xQSAU Ϻ<[ŵ3p)e4n7`. }xt=bǻ3ɐ&mN>D0uXp鿩{֚`Dfjaqx\Bq2ςc1O #)la,1W laRV5-l7#@w 0RzFmUZ?~4I$$is'إk3,#8tEۅ y"+tzXhJx$~Z#[r}@ ?`XvhσBTg"dB>fl%΃ ٳsBa:N}vp[*+blf;ܕ{aC@_m_x.fIMJ.UN3<3Pӈ  _Ff9M2jvɂg L]JTAJnS9jC>E:JAp/k.t `eb`}5AQx.nR0?@֩Sc+z}nDs'p"|nG.C7%n?~u{ R햮U:Ў-na X|H&=?k-h nz-ʺ bӋ>WzU71mR!Ҿ7N.ɧnO> '1(;ٛQ}ޔb׹; aWUC @d xpF [6|mv)CRq3H2fNjvzj&CS>_\D$ <0{89rKCthW:Wr5m})^<*x!B#Q1RغXRΈZ;2E%츈6\C$r4jrnkQdDa+]p4JEqsPl9 v V Z\1Jx7 O\g7ϭ?lU?qƌt$[T/ՄxTkD8 \Pu^$χ]d/oi?`*5=_~d^噚1~tORy#9muV\)'ǜnC S>T!pnocޙ1cd|ԒV`dc0BFtY,]Ț>LMוqA{\R49 #犃cm & D3I,`qHUdjsGh(SS tTƮt~,=u}f.5iv4uC}>h,<<,ٱ,DMim7T|$Zmk3rĕTT֧0ٌ&aXS"s73l@E]DH:2lᗎ87ZGKȲ7ӸCeʧJHˉ\.ՉRM#.m1hEDg<c8kar9x/4FMcrжQ9lJᒾv[?BU` nJKT9 [ x!.-6>'&P5}}Qzp2p Pð0+n{+YK2Ro>Ӏ?8PZyJح %ʬ-!0Yyb{* ]?漯^-p  VoԿ@ʎ"oڡ ڏ4UOd2 Md0$Z(u+eC(<;`|-{JEm/JzN]qT [0/*{L J!?DПJ ׆)=~%h"M i }|,5|JzؤKWhqڏ)sVRjכ"4m湁kYwISiNaMoُctp buZ_{Ȟ)NnewxRaĽ"۱n\wpiYMSie}g#-ܿI+]C'Ħ%  3ych;!٫wPgtk;0ȱRʥ3azBTDAM'GLb&WIw>-Տy}7lng.р?;={F"^o-/;Eг}\S zPbɥ+^;[VnnO]Ê~n!xz"cwJ: 24FP^:Hj}cQ$px#藺Sf!h)$bi 1x^{M830;w9q_wf_P_+ !O"=3|%AL8+nZɘQ⯱-*Ro=& 3݁/n׵+2#Lq5tȣPqX0yvJ7(ePL9̗ee А#SoD:.Ҧd)~G(6}hYsWj,тGw'.|m_3s.Q.>7E`d|>Iȓvn#ڕSZF(.;lf G{'z@YYXb`Mwi #o\Tj|eD%FqyٮFi=ퟓ6  >25qˈJܯJwkb{Lh$kjW)2=.l%'# ׫XyT|oMT$M>.jE|"8#3?38Zܷ@6!uH|BQG>wqz-I\5S"yw8uZ/]I ԓC(Y3t&2Q{BS EJL0?7L`@_w] }ZiV )64ⷸ K;!Z/`4!\Y)뒁Lhw}&IFRoaJŏ#Qw-_PHP][ɥ┐3~*1@HQ_kEVg),%ly=.8yX˝c5gk F;nm87)qw ЕGz3}Bٴ^I@~0.$[US6bn8  ?Oh&C',mI]lsx`3MI>ц@J)eѱ/P$Dhk\b:|HstULLy,p*4BxE3$T$M q6c)JbQxZjU>`wy=};[[GB[p,c~`Pː7eJ kk041c!vl2w熠`SBa7gGb qnAL[RQKJyV>hA:nVVب~&Qb*lpj/E ԃYI &h!aq`3*h|?F&`fnpeW7#PZyl$],c̃_oBdz=uxL {מv]eVi*@|۩I+34l ^ogNLHz`{3sS^MXvU(}Y7-iƫmLm$/zEQ h_t k4b9xj~ۃ"u~UX.颣vmHl6Q+ I S&`^P?:a!̦"\.[Fxf<f+҈0~Gd.pfQ`|uD"~ON#j:i X3Z(% ~IEAcڰ/Si_X㲭HO.5VB}0rj/vzHir`Of4rFx d"D`o:043XViL:oPIJ&EFT+0v%)9G[Wo6 Ŏe,thd=NdB>k3g Ro\ adȢOo.+d$^1 l$]{7iO6E[XHoq Wތ@C+z5>Ȥ"37a8zTİSsE[pʧעGK?Ghg"r6SzyyI-lIC*bsKGBUT+Xx-$e٧ݡbμhDX`tZC?x\I?Cnzb\!u_yD5IQ,?"Q"fgM1r 2&,;`>kS|Fsq\ZႥ"jkoFbX|bZ9k1yКH%|ofTP,gВ61n-$&y)C]rfL .FmZ¦ò6žOQn[1L1'˥ +;u_GYJ={jlZ>p]\'b*hY}bC9u{uDa{֞qLN4#ZFݍ&-qeH|E4$W(asV~ۏgT? Ob{j)Lbi=`|E!9@5y孜sDoL\cw>JftK隿uc绶fw+^ D=TW42&j1+=i~utzV u;-8 Bt9d)xĬfC4rʗG>_b6sI,$wb~Nb&Π/u?-A=$xg̓9ȶ$ p46)ʷ4qPJ+&>kHaكqDBVS+!\'l3ȭUZW.n<F?vqP}B[-J=2#6[d?xt~)Y3;DYpVZ!mi +1YExwOۄkH:ܮnӶCmg/&tQiU$pX7+x7[!'m @]m}vQ~;ٞGXX~p$ K-s_n>NMcΚiys|ĶCE_)^|촶YYu80C?rDG0e3DAjm4l1AjY)kwk1,}? v(9›{n[[`0Āڶ#lԓ Cq* k<4ty2s"|ʅ㱺L `/hrD9`^>Ǻ۰wV.x6;#r OB|oIBIjlO-3'wN3*4d{pG7&3g ~'u$;]W^8wNdoBYI2KQ)fgrC=G9 ENq:5 2LѺb)D01R"=aWlXTo Qc4_[8=?(t GILBڎzUpPGI ݺqs(Qp9:Gb!49d;*`gZ44q]]cK}Ml-]]2fZ]V?>s\ȕ*$8К=$Tl qEɿ܇RKA`yP )譂Hg2׵CXʟOBPE P#0Uyi2sEVq 8!ٞnFKHqPjЬ*Pέr,s쇧Ҧ[ , )+0\^AG7M8b!=t*8P|Q>c?O.'I [&|7eMq7S߰ALzit>~~ qמDnVL{sH[hQ~rko"@6DY#*vlH̪OrYvsOeKoFCaۈTU^0#<0=mS ]O=)$͑qN+qK%dnA+ekxEY$CBdgڏAD[z%ՍJBNpQՐ`:J?ddh5@QO1'^Y3$H|bl[#hx+;Fđ= .g18w$IqO!~N퍯:v#Otȳԭ!rG΃Jճ.3~N#):WR7oξX|ߣ7D3"Lh/kT%h[c%F.R,4Jg/NZw2Tֈވl%pOgfN9Ȧ|^ ( DŗgՌo}}3>Ń0@=uo`6H+!!bwܢ ’s&MG. \|I?k^wF%RͲ7+n\'77 [P>chXŴ1Vj |ا`kE"2ЖM[{Yq[d&[_ Gx㵂&y_- ub{Q$9@ |[߰Ꭺ=m l ~)Ԭ;l$SOVna0z&#u*vO"W,lza=hFhDҎ s$6OC On(i~r&;f/?oKGnC#Ob3f=}5Oj44 i}h| E|5m'?7w9NzmfU½oCJ L 5' K@~kGS4'% JqwТs^E6j]ޗQL!e]"ҽwiHb,7 oc тF,qS'&U([?JsH ,a*I/oi)I/ gjK1qܧ!d}?;MF{Vd˩$k%Aq`"JokH1bzc("jbTPU%vUBHTߌǛ~Z@n{yY ?slL9SXH8 |¯鳄^Z #z8Q28!0!5rH \U3 T<},j58⃳6l#< uA־-h4 c%[;g1 u[R$lj8M K H!nN:)Y6@CgnB`=ۑ %2gl5RVێ`z \݀ 695 $eԆ YioUv5tR/Ån3\8"/ħ0n@ԏ#bPzryDj*ٸ-R8O9EIĚ߹:Y4x>E܌mh)HuS9|3aX^.Iမs p\Id4?Rd ѐx>O?Xɣo)zh :Hzx~UV&4K |Y=O^i~yw5rȞKB8$X\'"bܞe5i&8ե($:H =ATS|JKd:r$S -ޯs|ɵp-d-\uK|#*[4cɍH$^a$ K8Q:sc嬠o{mWԞ_ч'ud(^9jmS|9 7srq궻H=$N]28bMϟA2v55vf3h0,3$h7F_];XFت6ftzHĭU !P)8qfrwLflfs:}o <}Lȓh@~$$kۜjrb]sœ^ևxп9>]lu7+ j]~c `R3S Hyw~fX)$ 77C;ϳTq#f.~+0-a&~O_R]'_.QvޯzhZWok4?+lI^-qTL%Mh"95uDݤgjL2۝jSe*<2ssY,M`/ZǴ@f;K x]mp᧲Őz9XJɞWf@PQ:amm eY|NjĺtFﶶ" _ "|]y֎d[_D^-}I`*4A̺K9F$?SG^l2VLGw5I#'=_V2oH!:> endobj 2 0 obj << /Type /ObjStm /N 98 /First 807 /Length 3851 /Filter /FlateDecode >> stream x[[wF~1wh 3ز;cǖ I0UąI$gj2Ô`a E5fE3YlѲ̅hԆ JkG2ALLD%H`윎c8LaY\,m@F1[ǒCc%3hGfF2HlI![L)i,C&pq f0a~lbbE"ކ hXͅ hB!2MEB-i5P! Y C~qd ?D+v(,; C9rXJW #uDv|P: ȄBFAɑL*sPQIՠchaT'hVvzCAN !j$`/\FPIʰ8wif*~1Q񉊄+*TT| uHYKUxBBGlyJźmvlKk~rrXe*ifs*o-o5oylz-jJ/ofs.QBtk6cCU,c9}G*P~o :tg}6V7TLp^j IsCG] ͯtN9pU{6$ӡ!IgˢzigsTDC[11d/UwߍU"|Y˪L#2-u1MK:}ϳt%OCHI%OG`P`&tOvr$"t4Wʷ# /fiW O}AM+!+86\ vTف RX(hu^H2q@G*w/ ]؈b=}=%e FZ\移$ҁ9!A*-!&{Q{,}UodSSfVב)ԑ*;J:RldMYu,_U C"0<|Iޭ[C툡/Z6x.EV9{M9azjv~@pc,UIcݛ&äJٽ+7mCc&a0C$'EZ3K(1yɾٴdj\KР0@FbJ4&Ӓ2NşʦɈ?ZNY@ژztD3X<-ٵ/̺y !O_l.q/[U:O+{k>ˡ}YfHRLUʧY1]/'^eYɴȗHA)t KYYz ͧp '^S1^P_%'ivq4iA*g :*4IA=~ OO9?]䗟Wg||s񂗼k~q- PoyaѻO~h1 '/Ӌ<)vBu3zG,a$܁GԇC>@<?/Kx~P'4i/=9y.P‰.@ 趯$_E)2]d%Pfx9OKؤ,ҔWuȇFR_b_|ǓHB2R1Eydjjf}[}[=M=76_GOmZjklYej}[v"Fq#w:Pg(' J, ߵ_[׻MnaW޽x<˗qͻ'&mIz=/TN8غق#:;yeXki^7G2ErrrQ@f8| PD |7;8pFoamXyw:!ex:r\Zb_fw~*8/YGô8;7Aq_(XzGL_tpɋ:s v݋ {M~ +{nfƛoC'ۦI\b[#w;nr [B폍.'z"~{-{ܜ;lR7~bpB]MNo+x u {(+;&q@'MCH0%U%lIݎ]O=Iddv $w ٞh[h[2^vv'/ےے]9wL\2y<J,v5r]s~evےFhf[4}]4z>[5%V(O1˒kkD͛4uۼ=Mw4xku5 T6*†>h񍚝n' `ʹEzńWOUp&0D䚁,D iEQP=̧WURTc7MS`N?u.'ge"=L'W2X`1}5{9AN29/ xR?_'HӥcL?!YR%c(ӷq][+7#8[dՖm(|7n7=oٺӷi];7h]ێ2n߱*ܖhZH7W̵[]N/xFuNE'4MVKdjKJؒdUH+NOf9vTg1}C_oުDzc/g;ZE0ŨN]D^݊|eڅty߃D/ endstream endobj 124 0 obj << /Type /XRef /Index [0 125] /Size 125 /W [1 3 1] /Root 122 0 R /Info 123 0 R /ID [<0FABD57990DCDFEBC6CF978D4D3F54FA> <0FABD57990DCDFEBC6CF978D4D3F54FA>] /Length 316 /Filter /FlateDecode >> stream x%9NBQs(8<#"#8℅0q5;`eg&L;ɽxODqD]B\&8<ȇ>8x ! ؓ~lB :lC)d [P;P a]Z U*UB@-AJ-ڠE%R`cJR?Dom^PI$.膈ʜ_T21Fa@eAJҺ΍u0qU~baVa`f`T.rv,`i^5嵔R}2 IYZR5mi`N rp.~_g($ endstream endobj startxref 202418 %%EOF shazam/inst/doc/Mutation-Vignette.R0000644000176200001440000001122113616633156016774 0ustar liggesusers## ---- eval=TRUE, warning=FALSE, message=FALSE--------------------------------- # Import required packages library(alakazam) library(shazam) library(dplyr) library(ggplot2) # Load and subset example data data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE %in% c("IgA", "IgG") & SAMPLE == "+7d") ## ---- eval=TRUE--------------------------------------------------------------- # Calculate R and S mutation counts db_obs <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=NULL, frequency=FALSE, nproc=1) # Show new mutation count columns db_obs %>% select(SEQUENCE_ID, starts_with("MU_COUNT_")) %>% head(n=4) # Calculate R and S mutation frequencies db_obs <- observedMutations(db_obs, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=NULL, frequency=TRUE, nproc=1) # Show new mutation frequency columns db_obs %>% select(SEQUENCE_ID, starts_with("MU_FREQ_")) %>% head(n=4) ## ---- eval=TRUE--------------------------------------------------------------- # Calculate combined R and S mutation frequencies db_obs <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=NULL, frequency=TRUE, combine=TRUE, nproc=1) # Show new mutation frequency columns db_obs %>% select(SEQUENCE_ID, starts_with("MU_FREQ_")) %>% head(n=4) ## ---- eval=TRUE, warning=FALSE------------------------------------------------ g1 <- ggplot(db_obs, aes(x=ISOTYPE, y=MU_FREQ, fill=ISOTYPE)) + theme_bw() + ggtitle("Total mutations") + xlab("Isotype") + ylab("Mutation frequency") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot() plot(g1) ## ---- eval=TRUE--------------------------------------------------------------- # Calculate R and S mutation counts for individual CDRs and FWRs db_obs_v <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=IMGT_V_BY_REGIONS, frequency=FALSE, nproc=1) # Show new FWR mutation columns db_obs_v %>% select(SEQUENCE_ID, starts_with("MU_COUNT_FWR")) %>% head(n=4) # Calculate aggregate CDR and FWR V-segment R and S mutation frequencies db_obs_v <- observedMutations(db_obs_v, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=IMGT_V, frequency=TRUE, nproc=1) # Show new CDR and FWR mutation frequency columns db_obs_v %>% select(SEQUENCE_ID, starts_with("MU_FREQ_")) %>% head(n=4) ## ---- eval=TRUE, warning=FALSE------------------------------------------------ g2 <- ggplot(db_obs_v, aes(x=ISOTYPE, y=MU_FREQ_CDR_S, fill=ISOTYPE)) + theme_bw() + ggtitle("CDR silent mutations") + xlab("Isotype") + ylab("Mutation frequency") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot() g3 <- ggplot(db_obs_v, aes(x=ISOTYPE, y=MU_FREQ_CDR_R, fill=ISOTYPE)) + theme_bw() + ggtitle("CDR replacement mutations") + xlab("Isotype") + ylab("Mutation frequency") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot() alakazam::gridPlot(g2, g3, ncol=2) ## ---- eval=TRUE--------------------------------------------------------------- # Calculate charge mutation frequency for the full sequence db_obs_ch <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=NULL, mutationDefinition=CHARGE_MUTATIONS, frequency=TRUE, nproc=1) # Show new charge mutation frequency columns db_obs_ch %>% select(SEQUENCE_ID, starts_with("MU_FREQ_")) %>% head(n=4) ## ---- eval=TRUE, warning=FALSE------------------------------------------------ g4 <- ggplot(db_obs_ch, aes(x=ISOTYPE, y=MU_FREQ_SEQ_R, fill=ISOTYPE)) + theme_bw() + ggtitle("Charge replacement mutations") + xlab("Isotype") + ylab("Mutation frequency") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot() plot(g4) shazam/inst/doc/Targeting-Vignette.R0000644000176200001440000000345213616633216017124 0ustar liggesusers## ---- eval=TRUE, warning=FALSE, message=FALSE--------------------------------- # Load example data library(shazam) data(ExampleDb, package="alakazam") ## ---- eval=FALSE-------------------------------------------------------------- # # Create substitution model using silent mutations # sub_matrix <- createSubstitutionMatrix(ExampleDb, model="S") # # Create mutability model using silent mutations # mut_matrix <- createMutabilityMatrix(ExampleDb, sub_matrix, model="S") # # # Extend models to include ambiguous 5-mers # sub_matrix <- extendSubstitutionMatrix(sub_matrix) # mut_matrix <- extendMutabilityMatrix(mut_matrix) # # # Create targeting model matrix from substitution and mutability matrices # tar_matrix <- createTargetingMatrix(sub_matrix, mut_matrix) ## ---- eval=TRUE, warning=FALSE------------------------------------------------ # Collapse sequences into clonal consensus clone_db <- collapseClones(ExampleDb, nproc=1) # Create targeting model in one step using only silent mutations # Use consensus sequence input and germline columns model <- createTargetingModel(clone_db, model="S", sequenceColumn="CLONAL_SEQUENCE", germlineColumn="CLONAL_GERMLINE") ## ---- eval=TRUE, warning=FALSE, fig.width=7, fig.height=7.5------------------- # Generate hedgehog plot of mutability model plotMutability(model, nucleotides="A", style="hedgehog") plotMutability(model, nucleotides="C", style="hedgehog") ## ---- eval=TRUE, warning=FALSE, fig.width=7, fig.height=4.5------------------- # Generate bar plot of mutability model plotMutability(model, nucleotides="G", style="bar") plotMutability(model, nucleotides="T", style="bar") ## ---- eval=TRUE, warning=FALSE------------------------------------------------ # Calculate distance matrix dist <- calcTargetingDistance(model) shazam/inst/doc/Mutation-Vignette.Rmd0000644000176200001440000002165113575255254017330 0ustar liggesusers--- title: 'Shazam: Mutation analysis' author: "Susanna Marquez & Julian Q. Zhou" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4.5 fig_width: 7.5 highlight: pygments toc: yes html_document: fig_height: 4.5 fig_width: 7.5 highlight: pygments theme: readable toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Mutation analysis} %\usepackage[utf8]{inputenc} --- Basic mutational load calculations are provided by the `observedMutations` function. `observedMutations` provides multiple options to control how mutations are calculated. Mutations can be calculated as either counts or frequencies, may be divided into replacement (R) and silent (S) mutations, and subset into FWR and CDR specific mutations. Additionally, alternative mutational definitions may be considered based on the physicochemical properties of translated codons. ## Example data A small example Change-O database is included in the `alakazam` package. Analyzing mutations requires the following fields (columns) to be present in the Change-O database: * `SEQUENCE_IMGT` * `GERMLINE_IMGT_D_MASK` ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Import required packages library(alakazam) library(shazam) library(dplyr) library(ggplot2) # Load and subset example data data(ExampleDb, package="alakazam") db <- subset(ExampleDb, ISOTYPE %in% c("IgA", "IgG") & SAMPLE == "+7d") ``` ## Calculate the counts and frequencies of mutations over the entire sequence When calling `observedMutations` with `regionDefinition=NULL`, the entire input sequence (`sequenceColumn`) is compared to the germline sequence (`germlineColumn`) to identify R and S mutations. If `frequency=TRUE`, the number of mutations is expressed as the frequency of mutations over the total number of positions that are non-N in both the input and the germline sequences. In the example below, the counts (`frequency=FALSE` ) and frequencies (`frequency=TRUE`) of R and S mutations are calculated separately. New columns containing mutation counts are appended to the input data.frame with names in the form `MU_COUNT__`. Mutation frequencies appear in new columns named `MU_FREQ__`. ```{r, eval=TRUE} # Calculate R and S mutation counts db_obs <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=NULL, frequency=FALSE, nproc=1) # Show new mutation count columns db_obs %>% select(SEQUENCE_ID, starts_with("MU_COUNT_")) %>% head(n=4) # Calculate R and S mutation frequencies db_obs <- observedMutations(db_obs, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=NULL, frequency=TRUE, nproc=1) # Show new mutation frequency columns db_obs %>% select(SEQUENCE_ID, starts_with("MU_FREQ_")) %>% head(n=4) ``` Specifying the `combine=TRUE` argument will aggregate all mutation columns into a single value. ```{r, eval=TRUE} # Calculate combined R and S mutation frequencies db_obs <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=NULL, frequency=TRUE, combine=TRUE, nproc=1) # Show new mutation frequency columns db_obs %>% select(SEQUENCE_ID, starts_with("MU_FREQ_")) %>% head(n=4) ``` We can plot the mutation frequencies a explore differences between samples or isotypes. ```{r, eval=TRUE, warning=FALSE} g1 <- ggplot(db_obs, aes(x=ISOTYPE, y=MU_FREQ, fill=ISOTYPE)) + theme_bw() + ggtitle("Total mutations") + xlab("Isotype") + ylab("Mutation frequency") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot() plot(g1) ``` ## Calculate mutations within subregions of the V-segment To restrict the mutational analysis to a particular area in the sequence, the `regionDefinition` argument needs to be assigned a `RegionDefinition` object, which simply defines the subregion boundaries of the Ig sequence. For convenience, `shazam` provides a set of such objects, for which an overview is provided via `?IMGT_SCHEMES`. Each of these objects cover the IMGT numbered V segment up to nucleotide position 312. Different objects treat regions within the V segment with varying granularity: * `IMGT_V_BY_CODONS`: treats each codon, from codon 1 to codon 104, as a distinct region; * `IMGT_V_BY_REGIONS`: defines regions to be CDR1, CDR2, FWR1, FWR2 and FWR3; * `IMGT_V`: defines regions to be either CDR or FWR; * `IMGT_V_BY_SEGMENTS`: provides no subdivisons and treats the entire V segment as a single region. When supplying one of these objects to `regionDefinition`, and with `combined=FALSE`, the resultant mutation counts/frequencies will be tabulated in a way consistent with the granularity of the object's region definition. For example, * With `IMGT_V_BY_REGIONS`, mutation frequencies will be reported in columns `MU_FREQ_CDR1_R`, `MU_FREQ_CDR1_S`, `MU_FREQ_CDR2_R`, `MU_FREQ_CDR2_S`, `MU_FREQ_FWR1_R`, `MU_FREQ_FWR1_S`, `MU_FREQ_FWR2_R`, `MU_FREQ_FWR2_S`, `MU_FREQ_FWR3_R`, and `MU_FREQ_FWR3_S`. * With `IMGT_V`, mutation frequencies will be reported in columns `MU_FREQ_CDR_R`, `MU_FREQ_CDR_S`, `MU_FREQ_FWR_R`, and `MU_FREQ_FWR_S`. * With `IMGT_V_BY_SEGMENTS`, mutation frequencies will be reported in columns `MU_FREQ_V_R`, and `MU_FREQ_V_S`. In the following example, we will explore the mutation frequency in the V-segment using two of the region definitions. ```{r, eval=TRUE} # Calculate R and S mutation counts for individual CDRs and FWRs db_obs_v <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=IMGT_V_BY_REGIONS, frequency=FALSE, nproc=1) # Show new FWR mutation columns db_obs_v %>% select(SEQUENCE_ID, starts_with("MU_COUNT_FWR")) %>% head(n=4) # Calculate aggregate CDR and FWR V-segment R and S mutation frequencies db_obs_v <- observedMutations(db_obs_v, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=IMGT_V, frequency=TRUE, nproc=1) # Show new CDR and FWR mutation frequency columns db_obs_v %>% select(SEQUENCE_ID, starts_with("MU_FREQ_")) %>% head(n=4) ``` Plot a comparison between CDR silent and replacement mutations. ```{r, eval=TRUE, warning=FALSE} g2 <- ggplot(db_obs_v, aes(x=ISOTYPE, y=MU_FREQ_CDR_S, fill=ISOTYPE)) + theme_bw() + ggtitle("CDR silent mutations") + xlab("Isotype") + ylab("Mutation frequency") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot() g3 <- ggplot(db_obs_v, aes(x=ISOTYPE, y=MU_FREQ_CDR_R, fill=ISOTYPE)) + theme_bw() + ggtitle("CDR replacement mutations") + xlab("Isotype") + ylab("Mutation frequency") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot() alakazam::gridPlot(g2, g3, ncol=2) ``` ## Use amino acid physicochemical properties to define mutations By default, replacement and silent are determined by exact amino acid identity. But this can be changed by setting the `mutationDefinition` argument. For convenience, `shazam` provides a set of `MutationDefinition` objects defining changes in amino acid charge, hydrophobicity, polarity and volume. In the following example, replacement mutation are defined as amino acid changes that lead to a change in charge (`mutationDefinition=CHARGE_MUTATIONS`). Mutations that do not alter the charge classification of a translated codon will be considered silent mutations. ```{r, eval=TRUE} # Calculate charge mutation frequency for the full sequence db_obs_ch <- observedMutations(db, sequenceColumn="SEQUENCE_IMGT", germlineColumn="GERMLINE_IMGT_D_MASK", regionDefinition=NULL, mutationDefinition=CHARGE_MUTATIONS, frequency=TRUE, nproc=1) # Show new charge mutation frequency columns db_obs_ch %>% select(SEQUENCE_ID, starts_with("MU_FREQ_")) %>% head(n=4) ``` We can make a plot to visualize if mutations that change the sequence charge are more frequent in one isotype. ```{r, eval=TRUE, warning=FALSE} g4 <- ggplot(db_obs_ch, aes(x=ISOTYPE, y=MU_FREQ_SEQ_R, fill=ISOTYPE)) + theme_bw() + ggtitle("Charge replacement mutations") + xlab("Isotype") + ylab("Mutation frequency") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot() plot(g4) ``` shazam/inst/doc/Baseline-Vignette.pdf0000644000176200001440000075270613616633067017313 0ustar liggesusers%PDF-1.5 % 30 0 obj << /Length 1919 /Filter /FlateDecode >> stream xX[6~ϯZ`!ʫ.aLI4LMжf,9LCj$yvi`_LP͂gk]<``Q \\\IgiI\l_lvKMoîxϤZR2֗Զyo&o۾^<u*<ʴVtY,DHZ³~i=YOm@wD ȋM^MeaMDu\(ʙ#[2d9wTu>UQ’`xUBk]NMK+ypfܺG2F]vN7}YR+Ԍ}IOhpr}$)k3$ J?__6z{G72%sirC@}mKL)-cvw0nm,k ǧۇLJHŒe&fBE żj{rB6) vy5PnjD[C*C:]HgjOv.c?ѝ)o H~S7nD<-^}{o O&p[VFL;#ŁL2hr;Sbf ES]˟HjVպ7t 1 H17EE d{Li~=LDp'KfYU6'o(1dGLqBM!D=a7zvt-=6 B0! mtj>ڭvu4u@]pVM'1\ϲBHe|W\UˎX#(t#W'+WtQvx&wKH}H᤺bX xe9 [1o|ʹf.;^3Ё;Q&_4= C6Ύ!?eF,@ =ܹƏ}A26GB1c4)t$3zxwUKKP,DFp;``?|rYDŽ ffՇϧ~xNMKZ5U˳XۗP,O><9VG( 5戉9"D2vB/jހ~841X")0N$W,ViwAQl\69ގub͑sSGOV9StL: ֔-U N $B*7> stream xZs|gD3~eqƒIvۉ;8A#wv/S8t_no_ݥz^>q'7;]Bw:x~ˢnvdzVyY$9=k_UQ5}կ*VOD8,lGH֙ %r *,m5_70үY G@_We9IhPsilsa1a7_ |mxRV ɡ`TaN극jRMHyYO+*t "[t[BUI1ݮ*wU4MIϲ覀wϡ K'l]꺭Tm֚,{GJO*nʊ&9<6#N"({zZޞ/<ZE⑿y-UɮVǰb6wg7m#{$6zmCv 5|Hq407biЬ ֫hJ[ qxi6YkyB4uR> PI1\Uj )bq9EZVFHoΞXvyv1@W/\i[ng3WخC C_.O_:=o@BNZl+`ڥI4b#r20='{Dzq nY :D+z3Ȇcl8 t=j֜gBC7Vt4,X)j{顕Q±|*?lNn}_:'\ `.xiX؞H %+nbB}-~P@I+v XG[Vd`Mry nCtXr!5.$,N:.:(*[͂΂`U h.0] y~HQg/|D\oߓ>`ANYZ opi?h[w}ލ,nאGkźk?L]afzvL],|=0{2HgynQ&(v@]].d_tc8 h`Zfp69FWyu|}p[LE[E@G QGLSaHPEi =aFRq+ҁxq?IƢ- ԂnɆ}x){ 5yG pm\oԘ G}{u%M_LQǚ6؇~Doq,D:v"j{!(I# &\˺:k1T+HgJ(oROh}\#ƟНlS?d/şs"}ým[qM]dzP\؁!|?bI}ŽL ;3v*nG] cS!xnS gZd }kyLODIh`KT~n7obp]KO{J?^PMSm\mJ¥.xd ;8uLquzje'E\;3jNܗ][qPu;`MY^>1 endstream endobj 59 0 obj << /Length 2593 /Filter /FlateDecode >> stream xYmo8_a}qZ$jq!ݾ${M[$P(Nܗ7!eQqw1933Q8B= Hdէ\|t g, 0ajY&A(~dVٶJ]QY_6fM[tve}Cֲ7~j5/X/}ku'_2LƂ:n $5rl0t#zKA bt#B6y8$?CBc+hO#ţ(ȤE_~v&vE7 2x7pϊUYx?M?x7m_QǠNQG!ET0,l*P*O4X-,o}В nX8Q)FR QoeU9wT P)#Qݶ0GV:#G3]jHwG0(98pqsM>P/Dì}PB! U_5 ` {kl cC($F3;ɁaĉgR@10n;)b'sP 5AN^_HUxs5GQE5dW2F/n+8HT|ow1"NٍcQP/Ż*@ )eMmM+jhZ{#Z۴) 2|d%j{ekgeN- Rᾦ5-shF vMl `?ט$lMb6ȹ5j.>-^j \b(q7.zN*!J k{T; R>N[m5ږRZrxny<jvƏ$)^ Z .C{l -H4vbcWilqUڹdZ08aG0{va_fz&bxjE<Ί<֊HX \#C"5r!I2 h,d"+Xh@@knOYxOz,f"l.3pzo#zI ͫ`<4 ŃX'م҃B:/ѸyB{vqPX=m*mь>cF%m0o^x~ԫqpLpu}Eh.8D"=Ȗ"" (We`>|sq x rq[mra\h_) $7VHi*k BHl_^5ub]Xǧ`)6+LJ "-|I>^ǔS('J~R$uJq:T0B:] dM$E,k: m-x </GE_[!郌 2 !!eM˸FL{Ae;ın[aӺQ5,/xy^xNo;LSRzX(T!nm%X"4]$7,WC F:/Lx%]58{[^oS ">0 ޒ%aZ0M&ޠfZW- FJ|K>^4Ӻ&ȎChމh# 9͞Q%wUhEl},Sj; 5(,#tqg }# * tP^^}XUMʀx31*clVZz0}bp?`F4)GjsDq[mbw-o.Z5Kt՛D跬aGJ`t!0O(> ( {BKz^@13XmwmLN{>ɠ=Xwr9Q)#s&#3JkuP;8qQRx,ϗf endstream endobj 68 0 obj << /Length 2429 /Filter /FlateDecode >> stream xZY6~_ad1 5H]ad0,Ymm$щSdW2ؗ6WźXjoyg}|D3⹉r=V sތ"^4LV^~%]DoI|7`eӈ~:myYz#Id|INTiWdiYqH6sz&U6(D@^&8Fv 8؟IGj+@Ǝd@jp>B}i'vpj]_@x(`S"dD燓4 EsP\c6.ȠaqAbo+HgoEU7A"b&kIzGN_́፜@V^KIIˮ"ZbFnW&G*EKjxYX7˘T4 z}7Pˏ2Kby*E}˜ F\? *̐ s>y'}gL\’2)tF7-ΧuZSxE e Nf a/L%zSrlu-H}j e!P)kQb4/:ڕz~ÍzFcK(KsF)K;-`Ĉ^%A8 ܐ6oׯTR~A(Db-L}UKzAR'5# 'h`ߤ|1_~JzeIFuoj]QNu@t2ܳ@` 5az1&kծ 3ycfʊGe`8~d[ >i+x X#N7y u뫉HXvl[!u`O7'v`Mm$#C fǶ }i1j4viA I3Q26# h˼Xǵ<XBֱ 2˝EMT ( fW# r}ci"l.e핊FiV `H/B_  yn i 򆉹Br(JCM}Fǡ}<>s X AjQ; )TYO#3RP!^M;HƲ_r;Hi֙-|xuБȥ " I D!Rid<7 IRw[CZaҵAT;顗ZmLխ)6:Xc2V^;]8gKFSx_5Q/,b\qkz] )d~ .}JvhoGwPP*WG:8ˀЈ\/'(R Bi,@bLXѝ=$͔F{"'ᫍdh( xB={E[qxZ-ĭ(s_6ד|o+x2};Ob;ߢ>͵5>tZW__W5ɍOi:,H]Zd}󧸑#'UHUa%$(;:QFzD&KؼLD,&ja~ׇU {jN}FPI"])]U `).Ț#]aX d*ERLT;)m+.ODD$^>-q:{Ro[sG戢SqC֧fU4\Uxʚ '+!K|{(0h5bĚP_zK5,k ?"%$:f:9h:f B{ 84F!#*:{^h?|r*ĘD~o5dc#cz̗\ZW.LVb%l4p(^/_-`J?kgsRDИMNwowVQjo5b8j<ˢNKTUI)*G(I \`x62[ w {}"eUΕYk.M endstream endobj 79 0 obj << /Length 1952 /Filter /FlateDecode >> stream xYKs6W΅Fivb{IҌ$Hb+*q_Hٲi;X`>허8$' J)OFO(0J`4 44MЛOCUxUyY4kl[5ďSnoȤ LDma<ȂpK弋v=ʹE($f ʼnpVfV Zd#Ut=wuB8az&uڣVh[0bt8pqϾ~p5N =ûzפ<Ѡ Mh {05ESzm[[ F㛏e2,8 B (4UPY"f4StVH~2pp z?ρP40i$?hF"0Q0ZY!σ% 0u-Y>YE^f˥m%!xCSΊrcU6ϳYjF08~/FZR3)GoyV1 xMJDr-+BgZ f"(Mݔ9NL4Mte VY\NrQv UIjuÎ);6 <`QqӳtBaepl9;AVXTnZ!#s0?jώ#  y(D{0/F7!6!7gY[C[,p =IZMD$χo>8LPaMYd~(LMkKQ`ȿ: ӄ|`L{0/W$Kn7HŻxە 6cXl_=/÷͗[~)HLi!8d<vkЂE×-a~׾8M(NM?Dto o Hjʈ$ޅTBmn``̹VZU<5l֚EZվfX!@LiT|zW&ͱ6ΤȡSLv&=A)=5'8kt[r9ĽmgWQv—FBs_idlX6.IF8Yfe8ȪxXebE AV`Plv1ձJ/x$dWVikmźl4ה TBXV,R ٦ֲu :c[E6vQ>hldAv,[҃5g|0VIh(ky OTk7q/;P"mAt;)ئn\-Ÿ/ ¶E::DW@Jƕ%&ơsKcUc< Եi;UsX*nITQxw@&׷yt,RpB#_Wg(SW8-5,ˇ0ή1`qB IgaO&w&b ms32[B ϡ.Z7b&:GbXoN4UM6f3biMQu$-Å$ ]K6B5us]- 2ZXEIO} p>κtWۢۢ|sE#]LT9;OPWkOlH'|?JtRr3bψP]+W_|ʤҘ"P|011\cpqWzK/{[>>P`(">y_=PYVqMx4Ӟ9h8~s'~$>ď6+O/2C6eErl  >O3о~ѥG?Z9ΰ.]_Uo?F endstream endobj 88 0 obj << /Length 472 /Filter /FlateDecode >> stream xS]O0}߯hWڮeۃb4(d [q{/%Q,no{ǹ=AWV(>ǂ Λ#\L}TuJхr# mo(BJ9`hnGǮ`ٛX˸LTVmcI*݅J 2&H Ul*7|0E01&0LozzÂAI&4++E 7kpJP_ \-r248Ć\Bdy$1+ 8Nh]~۫7\4gw]HmHgIq*/NwUoϬX Y ^NlK/̒jeT  ;X_k̒՚}[heQtҾKk믵Y5vԷ0Lq3$ endstream endobj 76 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Baseline-Vignette_files/figure-latex/unnamed-chunk-11-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 90 0 R /BBox [0 0 530 278] /Resources << /XObject << /Im1 91 0 R >>/ProcSet [ /PDF ] >> /Length 33 /Filter /FlateDecode >> stream x+2T0BC]SJ5Tp T endstream endobj 91 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Baseline-Vignette_files/figure-latex/unnamed-chunk-11-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 92 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 93 0 R /F6 94 0 R >> /ExtGState << /GS1 95 0 R /GS2 96 0 R /GS257 97 0 R >> /ColorSpace << /sRGB 98 0 R >> >> /Length 959 /Filter /FlateDecode >> stream xWKo1zXZH%z@RZ$聿όǯM6!lĵq/7O(Φ$nŷBI%i]zsQ(q7~'o8G?֏yz>LSHӉ~C9 Mg6@#Q< ^(A,RT_?RlRtt F/aiⱟDbj7J'Ik9&Rj[PyFɠRQαŶM0| "' !'-!\T[:icXj[P Du o]WZί v'%R4VQhD^ݪkd<|4 3:k8԰*&0N1 *v\nwӆ́OaV:8q0$jĝl޿"{Xm<Փ9+$vv :Fi"l y%Qlg[2踜9syDJ$B%;#&1Kَ{l홽2[^r}wG-kc13q#mO4h[qa"9y7q|F5 |=Lke;?Y Ugq?<.v9j,"QxXoV']}Je9&D:NBqNlljiU1ևc qI(\^䤍;&pnBaWAJ,IͰ[L3o_ q#XOq}#kWqm6mtz]b61h~NQ`N_G!-phK̾/H';K'7Db endstream endobj 100 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 84 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Baseline-Vignette_files/figure-latex/unnamed-chunk-11-2.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 101 0 R /BBox [0 0 530 268] /Resources << /XObject << /Im1 102 0 R >>/ProcSet [ /PDF ] >> /Length 33 /Filter /FlateDecode >> stream x+2T0BC]SJ5Tp T endstream endobj 102 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Baseline-Vignette_files/figure-latex/unnamed-chunk-11-2.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 103 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 104 0 R /F6 105 0 R >> /ExtGState << /GS1 106 0 R /GS2 107 0 R /GS257 108 0 R >> /ColorSpace << /sRGB 109 0 R >> >> /Length 1222 /Filter /FlateDecode >> stream xInG>裄J,YLF`D1@CZz#9Ǒa]U]ۀSo'׏o7j86ƨo τM'e '0ȠMG9?ԦN|:$ea5@AO2jpd:x~1Ęr:$j#a4d;9GKR8R0:y&À1^r%H*GnkQe]0Ii9`n[LeO. KNc):&1h)ࢶh[ emm6FSnb]0Ad&61w9ҋ]"{d>hAOBD(LܮBdX nn]0.HwVu J/.`.#&R@]:A.О#jb]0ҽŬvvh7v R79+X.c1%dQ~SQ*1QtL1pt6QXPpBK0W lեJkru#dYӆ-p"LJ . ZtMѳ{nu7ןxrl=ɚH#YxiN y: |9긍f˯ SVDGHt wD qŀt $rvKh7rCaE`.W6c f j+p&`d!}'qLKté\Ca[J83'@%VY઻'@=ҋEv r[; pn)Չ~gʵ@_f~}wѾ۵-~7t endstream endobj 111 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 115 0 obj << /Length 797 /Filter /FlateDecode >> stream xڭ[o0)Jk.{`t! CSh.R.%I7s|ɖt&'9?}5lD""d,!Z#ǂJ3mS7;M'uM zN棣L$ CM B9G%7y՞γROtdєEaP,,D!N4@m`C+J(@s6Ll#?5w;3c,6u;6 0Ix7&P*D>ã1_RE+/WTa q|і>ѝǎZ8:;=x* ViydT(w|p?,Os]7;(]bK%ͷ9ލ Mld"=ϊm_\֜÷[n&vq*[ -gF[Enf:$`$D"X $v'@ыkïpHNh@  endstream endobj 85 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Baseline-Vignette_files/figure-latex/unnamed-chunk-11-3.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 119 0 R /BBox [0 0 530 268] /Resources << /XObject << /Im1 120 0 R >>/ProcSet [ /PDF ] >> /Length 33 /Filter /FlateDecode >> stream x+2T0BC]SJ5Tp T endstream endobj 120 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Baseline-Vignette_files/figure-latex/unnamed-chunk-11-3.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 121 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 122 0 R /F6 123 0 R >> /ExtGState << /GS1 124 0 R /GS2 125 0 R /GS257 126 0 R >> /ColorSpace << /sRGB 127 0 R >> >> /Length 1675 /Filter /FlateDecode >> stream xXn7W 0ΫXGANĐ$>S Z9G,Fz uu/Uj"޿Zwʨ;Po *;Ocs>BI \OQ$ ޫ) jR VTG1HGZ]Svڏ0:=;:(MPwsKa0-#!-4t qȣNqVľE8mʰHkbe׻ ΢3ya+f鼎IP(yIM eQlStݶ!-ڵj-kM^Eܒ Pʣ Cλ3=kb3)]n1mbߢ][@c4hoF.~|DE+)s޽Po.XrlqB^g5k〛!ڛa[w <[hKM^㪶sܔ=}X2luB2~V^ר8*&CZ1Z Uв{h+iTFNQ}H14N"B{&V]b{[CZqzq8:\8}! :,}LL%]Ӵ??\>aYY珶΂3 bD(y$/Dc2b.\L8) `! v鐛WJC-&9$9SJO%M%`"*ޫv׉ 0&ӽ2(I%c=Lwhf,^ΏJG;V_Sk"HE҉QċM*ш9f %,.ǂm<&`&elvď1NVW96DSXÌ8`'V<3cG74tCI/MXDCCpp{mhggNP3%JC0Bmd&x"ġQ 2kf>A]46=59u[A[kKmC-H*o"nPM#!SyЕq^>N= Lyn{/Z3xkZL3} vdp`]tݶQ'7ߣZU"E+(xGk he׫ߝ_ֳ^C{~dv_ endstream endobj 129 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 112 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Baseline-Vignette_files/figure-latex/unnamed-chunk-12-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 130 0 R /BBox [0 0 524 276] /Resources << /XObject << /Im1 131 0 R >>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC]S]s\.}\C|@.T endstream endobj 131 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Baseline-Vignette_files/figure-latex/unnamed-chunk-12-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 132 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 133 0 R /F6 134 0 R >> /ExtGState << >> /ColorSpace << /sRGB 135 0 R >> >> /Length 6916 /Filter /FlateDecode >> stream xK%q+RrUsiR ´%!hMHl0DfTk8$E0z&̬|/"z|_㗿Ǐ}t<痿˟y7q>~t=>x>?q<(+CG#_-1CuP摏e=zG U : d>U# Jj8)/)mעC%r2-7C垪jy:5t/R]~W;u1=OOҙPjO1Q!QnIҒWF/1M[nV܏tTwdK:G]QLw~;q4dJ{J}dcV:fע {|{US'CHWrI}Z`9YVIZN3~~th:Tˬ!jK ZEOL3 ۿ[ǸWvku'>)ȥ:yʰ9_:OdO! %ӞLnIYhIQ:O2U"%kvpmU=TMЂ[{'?}3vVLK{+Z=u"H:lLKit>e1~Wչ@o_]_ w[˃Tm>)gJiRM7kp|%Y3]#|ڪ1NݖʟAhDZ| hX1:Oϙm4~=&ӰˢcoU惎"ɲӠ/k?Ywj/烂|, 󝍗Ԯ#asaCy?δ竤O W*˞ Vjk҆}IL ws='?\Ymac惭KKljk(.IVZ6l=o+l>c_=AfY2/A'}An6->9:|tZ3G֣#шt|t׎Z֣S[WR_oe=>XYZ,GN[zTb}d=ʱM@s0c1]1,1,=m]zDt|@mMۥe=>X{,GG0~*2G]d==rEO4EOtf>测GlY|Pd=RFE֣hGq>(|Pd\7=obUTNH#:M#N'I#nH#"m"/HO5Јӧ~iD3ЈtB[=I#"m!ڪ_EiV4Vgz҈;Yl]!64;Ј4"K1a[427UЈ,3~42 iDM+p JwHE mvQwjn4"O %sävFРE4!"NV҈j|hD5h4>O6(7͍F|VX6@#>^FiDQwyA#ޤ5!> E#6b &kш~lN ~w:1N -h44 nn9ЈMDV^ЈS@#mFt-FTÝFT̓FA#Su#Ј 0Q 7B:4Җӈ ipV@#JV~H[ti?N#-&h43idiuN#JI#98/iE#4X447g4r7biid>ԦF@cF@WFPM# thti>ΦM#xF hfhHyF#M#6^6`l1hV@#FWFm4bCE#ԋFX 4Bh܂FP/4BJ#4J#/fLٓ.o&y'󊋚ouE4:'y1Isq2i;&t̜L .HLZcd:$u I 9/2IpnL6K ']'14gF25w2yF ')1O)$F'CgLyΓC$k< tL͉2^d'y͓IL~yfE[FviX5F,w4HÌ4Ґpi,nqi;;4,NN# QGF:Vf4ұn:pwXF:69tDFpu: ,hN#Cid 42[42Gvk;L"H;F82iD^̓vH# כ(Ft1HqahD4K#Ѹ4ҙDrQw<h34n@#4iDy5]5N#niDqV^҈g֮-ƭ׮-'9=Or<<{$y{$1/$eG=#h'<@#FD#oDIGy@ȘpN#j"id<LpעϓLs0O$6'6'LzDvmzd 1'By]kVw஭N][][̣zdQ7`Dw<4tQ MH_N#K4#Iid 4ٿFח4ҹz8H7sF4e hD\<i':h4ҝH#%.N4md^idzރ4`warE# F:4}ik梑h4D/0hV`âL\_4bSF,hĞG@#6X{)h֗@#ֿ|h4bu{^F4<ԦE#CmAi6P/^4<ЦE#ԋFP+D9\K3.?іl:٢h,D{ $5p<Hܘ/QH@ǖ9g"ǖ> IƖ)gƖ>Hc D-S-3q82GزLrƅ|eÙte {īDE;L*u0~&^Y0L|fbxUīll 0n &^ `3LmsG &^T?D}#{Œw<륶&L|kxQaE}#O*<ad0&^dljr3e*ėv)MzYD0fE`eu ij4)̫4n/_i/Ga⋃Lb xd3;Lj&xY 32:LtfL|`+7W'+й{`u,_yb&32Wķ0{0-8 L|lvo9x )3"g8W*&q4 Ne!M|w}&^#j&M|+ k &4/9Kpx0/ =LzppC E{! 5O_auZ7"c~FOQFzkH,B C4D5{}f>D=B_n' JW1Bb^[~D#!jF'__Y=xīl*_& D_c, 4tn& x:ķC0ho+o=ۙ`5L|%33BGo~z? =_unz*FF5#-}f'F3;#en~x܂E_0CM|WW M| 3BGɨ|?"r0ero8L^$cs˅3-M|yiWh&p4MycdD}=#^_F@I~:{D/uGa_i=Oxdi'*4)&7|!x&AO@,M> /uzJf:e^mߺ^ePMZKIO{+7xc]=h!@iW7E:/ɿOH6?H&Q?_B H윺Gm7%w)nB 'ҩ_1J67 4V{~3pߨZ` i.t7/wUCEWٛaފNؙiϿ<ʴm$ÛsB~ xBpw3}{YWtnoG9?zo>~ ^گE /W+?hse}Rgvp ?Ͼp^n+_, endstream endobj 137 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 811 /Length 1939 /Filter /FlateDecode >> stream xZnH}WċMA0@bǙs1lc'hv8EHSEQ%*H꺜*1L0˴dIaYdR34+lxd  ¨D)&LiA3ep2ic \>l*NH%cRCً6M"gD$hgg#&=i`SYr6&KYBJ XpGmBF6SL L 3qhs f=fX0[h`ys0 Ѓ>灂Z,zc< %0HcD5P@ DB@L5L"=P!581@@5z'12 &p5Slxp> Cq.VJ6Q D #blJ :9GKDLnpsJ1,[. Zqqx{A1A+5"X&awp@[ZZY0S@%VY-AzN+u7e5W{;B4ѐpCØ!  -U3{,H?ߞqiK+"veNޒ4T4h8ػjLedо޶OVץ5*ZnyZoA+pGnUrgy:~yd֫B\wM!!嗞hVN+zvGϿiW[[jc5|WcU9.Xz]I_b(DE]M'yQS%\ MuΈIQ]$`0IT9Ѩ3H$.擟O3bv2;'fS9oɠ̄}&g/eް9j2*V(hV0QAϪ\i5 5$Gӣ~~5䞚clW"<&p P yٮ w$52kN=zPpx IDzr2Ar+ȜQ ,Ȍ9G{ysD|I K9M6s!׋k2Y<%w OǚYK(,~/4K&U~R pk/|ÊqQq^* K Kևv*qg럈s 簚>r߇}d}d(.L/|k52%$*T/7Ƌѻϭx ͮe6>.{ڹy2DK&kd=ޘ>%$bݒׯg%%R/V<GfL"-y~6)~u<.{tҴ(.fX o̳$};ʫA9ω7u9ysY WOkޝ4:fh6mˍy6m4/'jXܥM9MOQz9)@#Y#'A uYnU:4G" Yq:&ӛa6m`-Y^\|˩<דTRꀾ!WnuVeu*cM(̗k)z٥\K^_-*|EwSYIe|-I "*]~W_e~n@Z5 vQ ڡj)@ endstream endobj 140 0 obj << /Length 1441 /Filter /FlateDecode >> stream xYmo6_y *[6pAk`b%*$')_d8YdAGsQa\kn7ӣWBȉ}߳zVƎK5M3m7y9qT5]LXA^soh͊djg"O4/ޡB1A/C\ s9%;FB6-^dSњz ǹ]2jAU~5,]{k%S5b5$w Єq~/98Bp" NNh,K5ܚ䖭=!rBXA9j|/(v MțPŐ81=1#AƋؾPq!0sICdĪAobSJȗ\\*VnmXJq2Y 5݂)JH5JYPK"um}V*8r 2u_X˭aS[Ei@arn, ZI Z:ZzNnWZk .&_jL ;p>Zun847!5=H#9Lɲ &|-ƶFpeB/LV%Z&LUµ}ka)X )֩R$"UC%ya\`m⃃!눴*vYJW Hg"ioWxUKTl o/D|ӄ5c2m@b:UI<ٿ ka'ͯv>y^RhM),S{PCOlUp˚pEۅl=X%h)p{}4ODT[ -Ixna V8HD'&t6P@6||Zޙ-j~KTۅ;@(r!3%_v')4ͥ \C"P{Fv,/$&k6InF&L?}{=d`^s3[.D^| _ݻSH(m&V]z 1!ozL݆miPtHG0d=,:#ֶ>k꯳'G@eޣqr=>Q򝾐YFgۻXтVŷS^8㰋$[Ir/x_q0A bxYj)mBs@&z4~sc]E42V9nh}3 w&b/1+*Wg|u j˦CMa59 ӣQ( endstream endobj 154 0 obj << /Length1 2050 /Length2 24659 /Length3 0 /Length 25827 /Filter /FlateDecode >> stream xڴct5;بضmNFǶ:mc;v:ssxFa.[{]UXI^(aoBW5cf1001:]Č]<NKG :}8&y@ePwv71vp,)NV.j'[ cljmlm0303?V*{; `oPjUUT*J U]O$@LXAMԠHyT}跠(}|IWVVgfs fhP[G_*KFFwww Wg{' YZ9희N@_q3h%_, @h $a/G+?>.?5mp\9%%9 #`4@ @]Nt+ӳ5v3suGoM휭]U0Qgͬ +HK} Gw\<\SOXL`f0} jg?蓋'LZͭtՁQ(-&m@zZ2kR?Z`07qZ?༝݀'W?9fV.CQ.mgnCɿ]TmRjfog 01*ػ| ?{$\mlmT2 JHr)YZK cE2G6qX9lESk;3_iޏQ `SQ֢q+H0vr2cvv7(=#G `ng!98LB\F N&߈(SUFlF;Q?og7013}P~,VpH`!6lv,F^^^@?G3\?T~r (9LoU]쭁Vf7vqeغۿ_ߧ?ED=ٸ8,f&?`\o@Se{Sސi-a~ⅳ gUZ2 k]xby$@,"{9)}@- [3e=c?y?<$qቯ AY=$'2_ K::]cXQSI*:~C/2;٠z"vvF6^Y0*ÜrE֡M+P3lY>6dzUCPZ&dKtAd qb -˒{ѷXh%:_Sds x*PoC5ۛ'W QѬ!B$[ׯNuqi4('_5ab!T= YhƣO#0EEDzO|*o{ئ吪8?8!; FhBI}\ H-]UdcEM 3PTFiݵ?h)*:L]0YO jJN+6r5 !CU0טEER!yQS47 mG"%\^~눧ՠ ѰZW'9k }ڇkk.K9G퇽u]8kHfdprЅQ^iz?tfWfT=饝i?oZb~O.׬LԱ76%]: a!mwDhFaA;7B#܁(#P'T gK|gn·q6*ENК^@ېN{I ~$5!0̵j벧vgk+16k@"ʼnd V<ϯZ&>so#S,He.mTȡ[Ɗ2a- fJI EK)Q_w"fz;VZE|Wy^H/s;n1X!&0arnt0*ߛvd4JYcsΩ`]R bsK vHh0lpMrvY|RL!t.r=y#C޿vs5n!ȾDH oVm˺O:hrsZ( ھe%~WUlҺi6iyW|'yIBqwᵧ;iFr[&jy̢ XwXU|-Պ0fuuS&7Kva\s*LU8ٓf_w!>Ӽ{Uw@T =)M45 b;y b܈*-'/FDgv2*~fO_Z&ګSgό~`SC a~K.>?qg5}~H}!ЃODI1ކZa"æjmu & (";cTByDܭ}Vfߗnd(Gq[V`2 Uko%ڷ[5s:F;l޻b~E0M]"ƍ>Rmh!2g?w^)qRzr8cb[sK.uJ9AFY7Q5paeʡk99/4wV|Y:|=lҩ-D#qW99@;Krʖ)/DE/ g"pV&e\j=|M!y#x<P/LvrVKdGs%zqۣvC⫶"o=QM>Q_ +{jR3H̚ V{+pׁGd&Ȑy}wq_[}_KIƢ ܑFd&r즃?ňGO !+IUz:P};HL7>Z .gU#K\U 9bן~eS!%j\jrDb^ښ5WFقq >&q>yraUp8mN6j^?|a(6E=lir3UoxB Qq ?nHL4&%O 6|ߠx?TmQ=>c=?KkwZйP=(3o?3 ͋Ak%ޏC>1ӵ_{.oM^r D4+[PR‰>"7v{'_vI Sl$; f>Wb(p-ak<? !PZJ`[Ŋ+/gnNFjvf\P&+ҩF kd8g 4OB}?;9{|Ǿ|!)2{GAЙ Xm@f$_Ӛ (b*5|':JzE_4$,ee[Jvpɸc.vAF)T'@%6jS]̀KëbqD;*Nײ—#lgoE,=LSqS(Tã>n~p(LH!tZ@ K*)@J ף6clg7 Z$p7 mZ@[jvҩ^.Z-B;M3à#T/_ LNHENƫJ揔 ' ߤ Qo<:Ɩvʚ1p"A%&ћn߆7(^k@}ՒpߖUtfd9A쉰D?n=zx ; CC"dh_%δ'#$GHF}c|7O6u!ҵ<NzoӛU!%WJՓvds{oU(.qY7l]2{R'`NrtM%]IQdz ]:'(LW]#ӞrD:umUwp1@.&kuT fAD4QVg7%Fh^`AȰ2C}, .H׭Qєf&yB&Z[s]XB7è_?7`5jh(˛OSMtNRZ>y@<:1C},V$#qy}>=a5f!':Ӝܲ[S k$K!zaf&g[\+xk.?s9#3TB`ge^bqԽxkF9|a#7sHa7,`*>_sJ02YIJQSTqE՜37WԌ|yUL­:&8a*6 { ,y:D@AX8J{*p-UZbo;\0eu2Һ=)KHv;ZȓC+p,9z5/?0ʥC uˑSתMn>Hu(JŰIʐN˕/ngCOT Y>u{ +$uo.i=[/Uo gУ0p+Mӥ# Y u2z#E{jYɊ 4!>|-0 #TJ3x>WH-Qj#׬|Iq(k0l<}Vr = t2XaY߯"8_V˯df0&H|W㶊RLI9ɒW8U1<\P"F2zxI$%ETvvpa'"ذM\+dsmKP|J&2hNx:CYˢ)NK ֣~Z80Ǹ_Q!ɐ'>; ^˲Vp]ܜ!XtV(l9|jxahN϶eVf=vR R+@ kL_l'+Xu&b=#-qV\?*lT 8@ėu%XqϛeulL<AodZ{Cv]b SG Oy-/ye`Y9lTuap%p5a7@{ >,-@PM@ʞ0TgWG`"T-HLle e참b>n(T#k,66l <`v}%Ӻvȭ(qw/@أ*_ ׋X҂ӷOA>Q(לL/ NCk[H9PExܶ?/݄'ᝄm%gϯ$cˌc-ˊf,Ї67}yxqh,1ՉzF[@<7>zŐ/S ?bg73$7ƺΓ]Tpk(oN.y6m+2Y.kʚtNB6fpqWo Ձni^N;yyagz:NA̶"<ײdu< a?_CJ\$:t#7L!*3-g6; #`pEbp'e@7 U8U]Q r5ۛ ogֆvi Y4,d'zcڋ .'!BO՘i٘=C {p23[#,HI,gc 6vA c|1baIYmHletP!۟͆? DBskT]LC6 1N Vj6-Wj\ (_~z؋7{~PqH|ƾ6Qؑĝ1_t2?Ƴk R9PtkujM!,'ݹDRٽ!<)(wN8鍿dBl"|!G𒧯.HuU\T.{_)[2l\̚jPTZ ,vœݜnȻ~TT-6\/@$7p!~zmCvyP^^uH* .V=Bt^V|]{ꝙPUK 'i?MOaNZ!R\6U9Q-ـlc8x8QӲdp?'V"0L ]Md:-r~d$ 2I[uP +өc=MţuEzNk}!/.0gfm4 h@`2jzt"MhҀ.+6CoVG@ᘠƐy̬ &R{V_<]Bf! D\(N>o >Vb0S1ӑ\_+R}Hl픋] .;ZL? 4U/ҎL+AXleI*(=|VRfti'ZyrjOk1lz |v;vLpY7־wv/7Y}K u ;YlKʈDzh6xXK[Bkc3:/Me{)msUkI&U;,e6zwz9DK b R>ù/ᾡh qsAv%:'y)(UwI+WkFh!Qw JhmuS>ulu^ "-1 + gSavСʗ9N`e*+23A.P Ҩ!i+"M7 [XKO@yqO+;P$X1hMb#CDgH ֭5qT㑝.RS ԛ^UEF QsRkB8x)"uVXOEr$m0{,זҍ]iM)4jE^S^rr.wcӱB6 6 BZ$ p fb%HQCTK j4 Яt4&duR sZ>$1xE{F; wGtuNmЦ0%49Ư>p`9l0$AGT'Q뛛YYZ/7T=T@( /(w7:4HQs#M1w?ȼ9=h]}a\-5`-1D!1b".GC T!2M/=& BHH7IKLcfGER'U8=/\)`Veu&/(j^RFf-mv n j#'4x} ƀS t= 7+rrf>SkӚ e{d?ϒP " c2ۻm2!PT&K-"%q3 ?a6z+v^:'6!':EO߈N*A)F$oe—'ɫgM鸎 Twξv},x7UIQW,ZEa_0vaϻ[kmԏD[gXh8cI7jKG#K4ުWTzXYMrz`c&d[</)P :BKG@zjwSf+03vrE4K`?YߨO$.sPU\хL{9`*pуfHW=P봦eֹ9]8&#A+z{>/^ތG!w fD&_[q%t[CN5oFy_uuL P]T \BD(2#2KT+52TawdG)FkUOWs6SqBi+z t`MPj%[኿cH^B4D]PYg͝[W&w)d;&VovҒ]ǘ,3C|>#! 㮜ӜwlС |5=67a#AY5'B]n$ ,G ZއR_MP샖cHMht]{ˌ笇lѹv ,P7rXpՏ37D 9ڃ{x%D$(Rklyu=rlHaEDq'vΑos|j­5R{! Uk"d\0e2!>nAK}HCsA*t^o)xi[oK/D̥S|^r$1SXPūzOA/̽c%ʆPQգ;T4qHW}/8K,3E9S r#%4;K#|E660CY0r? Q$ UPrX!Le7fB}~ 9In}F$GkS9/?=k$VZR]sEKJ *>v&ezwNmu`"&Qjoe8՞\&} :{/KUEZbw!$PE=,޸`XAgTjsN= ]-56о %=?qIO/QKմZ0{v _AY+ʹ1&t 7]0? m~|Yho7@/mX,u%JrGXb+ʁmGOo>a۸V}B5V6USjs|G/<&N8аP$ 뫎┠r:bOK"j)C*xK*ir}6ղ?eVƈ3Щ9ys^a-ƅ[Ǽ*?dUf/&L2~_?&ӪVsX/_eĦN=yJ0*g`#3QvUK;"|'+gȀ;^,  U~[ JQq౑Q뛢Y-;lDzCOY hԽ)X&/A= ((UB)KqhWo$>h7 >ii.{gF-R޹W}yi@A$I,'|՗K$]s)=L'bR {M_ PsIZU®H!.e~f3읎ܭEkrGg|n;3/4ag*@u=VĪ[>Qgt=Hx@S4jyA.;*TE?`%kN">j 2ǎrd3,TwhT]I.<=9E^PA[aѱdYi ȓ sC_E͹?{nEUƳvj7#J2؞ JLq$iH(I, KC_a# z'<=8E}X%«5\#Qi_fKElmKHLiFؿz_9V= aXkt2VC !\3Ya>2ZLr݆{qdҴLIA5hRY^R箋4n)Z=(Fr`,k7Sdۑr1.<٘en+V3mx>}·> 5a\)Ї^IpZFA[ݑmf9N/#;7RE) A9 5&Z +JO:ȒZ_˄2;uPee n ^ӐʎםlH /<28/$Br5nĨGY ]W.S!Pd DDb(ח׿፴n$K SaN s;AٚbFkaf唦`'m|~}SG:D_ -zysqFQͻƗK>̃I0+HL#a)bA;G/pe`@X,[jWJ0-`!jKps*l83{tF9#eD;Ӗəût\)*d_=wBfp[Ijc er 5R͇)߽A-YCgC$!0jݛ<0ki dsmJ%nE&*J٤^.01eR;}燰 Ln] icްeL ݏ8+4xZs7wӻS K:Hp%7%!]7$A{\=Q"ӝjA;?b`&fXC8FKkۜ+,tұmcF:m[ضmIc۶/aZU{oW,r: /r8Rp_z$ӎi^ãk{kmEss6rUupp=knn˙aǏH0HK$p@~{)Oǀ5$8E;xP‘ aLݵ#5VM";qȩ>V:gAkrLvRUk#R|[iȮ1 oLt]lPI^$"=Lp'N=@&A=m-H2sԊ21yL7*WK* Ԁ1?O3Tn5?(sb28ӑwO$@ĵ#gn,fg5S=}t~UXle@MDm¬r8<"s8XDC7 d_{ҖhqIgqtq馏{}؄عHc`)oP1-*2'Sirg,TGX:[M)Ff~Fu )DUs8b-C*wX F!Z+pZXL1D>#1ӹzEOPlPBu[k0bߕ~䷇{zi|EdF/1Eer9(aGr}z0g<_E:YRd6uՏ/xMVF$bB}]d@yds` j;OpyX/ 1\_5z5/ OK |q d@;U,KR+LwPѺI}:% Q~ 1Row\/ezQ!$/*gӂa; :v`x `Us-1#O$Nh:\!S!%qW '--%ɔ9#W|)l"иS݁A`\k~ܸٛJ^;|]^V/F)2QA̋5$UB-P7bdϊHϩ;HZ6r ,г(4v2!=4jb כ{XW siP\"]W5H4R~yi=iŭd k8R/! 6J}<:uV^yM%!}(f7b77VRז|Wa%*zCKȏ曦&ƥ~ǃgD˨B]5"I:Fx6sŽ"['ZXȣxa~Hxnrt}"+tNX,AM6-Ss:S}7a,f[XE$Ida)Ae3s2) Hb {,QYBJy ]u&fꄰ$>J#_U#YyWe5fXVyZ'C%vv6WuX}ȁam`Ѥoim W7ߌIF_.⇔m/]ܢjD7\_)!՝%%8OC-xї*R1oED- ʶ650FE[ 1w4; >`wOO~\"h>i4|_S}PFUEviWƹa@毦\ M ۚhQbg4p4R%zT'BrZV7 pB!EXV~:XckHg^RVݪҮ#?;C}óiiÀ$?@]3e)ӿ⧜Q6IVHo)73R,R#%cZCNcQ"xt M۸S1 i bOL5hMb¡(YcIp6B؟Xb^L!bhoJgAwWhIr ? x2d{<#wTƽ$xDfw)K/}r0MH`鏧P w@#UZE`Y9U]yHk፤ /`yuUDrRY :*(.+"2uo6|urYfkSr#vc<KfD^?n7t;һ$GxwHJnC"ry0q.\C 4P5,rߕYMV57BсXP.FOJ@_3mW }RkH)0cTv׊OQlZGvW pHa7Rhqƕ8]dǚuu6=ArZ<|o<{]?k?6 yp\3Zѭ:#:x=jloK=iA3L"rnR9lO9!ƊW7s7NB?" ժ d&Y ^Cam'Gv62ozc7P 9 Lz].Ov<\>E 2  ԓ>< (]P F+ 8.\1f?R m;'(` W%3wGƵ =dڌf]3|N}B<k(Aa?E3@.ɥw E3Yp=mN,@y#~?2`:'Rn⽁S>M*DPE^ҫ%[ob% 4]waPNjHpŀm)xqxNiXIHK4J Q5p ފ QW-%xb !hšn 6o1fR:WͿa{?)-?,wzN`JP8PsL,pϘ}2"ISMABb_P:J(c!@>i]SVo;t{Q8s_jO[hl|di^чw'74A!@zs5%xwe/ _e÷&K,ڨS17SpۼUock? =Z 0{@(%*珫W쫙bWpc֜ B`I=/ތ S,dsHu{# Yi4۫lkᶒ YpלԆ3ZA3ݨOxs#Dqc$Q=0)kg/`F#%O쩁[`o[ÁY̮ g%T^nc;/:(-^\3Kqi:9~߰ݾ@MC!rnn ,,y,iogKw o#+Af1u~v_4Hau@PȨk-6*(d+~<C3JExÚ>X,IAeBJh*8<4Xd>!d_lR_vѴ%,%'Do`X)e'#-K㵭fH쯕΃AZ.PMZq[ Uv:CvU:L7o}o~R9Tr;Sw7>q'T|Lak22Q"%$!_MDٞ _5zʳ6qâHf(MOnZS yL=7/m<$@\?LцSW 8vDuJ>.4U7}8`Zw>Ic۳j1 ߎI6]=XcKOM{/n6Hjnt)FcAIs)}K'q)VyRRya1HbQOShmŰ&ǡMV,: ۝? Yz۪xkoMחz[V?{&7Ôʘ a:03!!Q9z2haVx_4["q75?^YU\7*i{~[RD(LxCJ(]T!Wi&R&ϖCOZ ;fb$lzD.-R^=- @uQJPH C{v nG.QMxRC>W1f3ˑ+ T㉌.vr.=ebBzbF27H>G ̄%RÍ%~ͱY(5N' xةΑ(*xŚ4!xϚGuCD!V\_joN601ʚ"n%!3{;)sͱ ߇eRnM4ep'L,?$x)0\킞u'$Rq+"ȟ,T@&q첳J(m> 6gH"oug 4te*bο.vQ<nbi?~;S1C[P!xm 8K΄$-/2|x;7|3b .XAP^Πе}{evPh0Nws~&Y.Ղ3Z̼E9f( K[|*An.DŽCL-i-DX ¢{K\=wQ0}\Gh|pSlnNE,ynn  `J3e&<kCfΣ6flD}.>t Ŏev^΂~{;xRLQp%ܳf~z- nƈ;\?+&9Z}ʽd܌UiB;^%֋ccb ۞ 5t+f:2C݄ܹ]#zVU7k}s= 2ø|Ohe~wkԔ+o^v/U֎? 2&@*|xꐜS}L^@qdJ-*`[ee@hx %"Xq~hP71#ny zaeCD׳)E5@+:3>|WvK auA[5"FOqeHVX;B5p d)+•>G4"_wdy>FؑSeEJK2zyn~+u,}?Kc[ndђFPt* _&D^1P?^K)Pp q`(s;J*ä9=7 [Wu0{yzO;xε@;N(,3,׼H@,hSHȸ['΁9q(d2Z?Lšo2K648o 1ÿ 0f7*/+4S<¸s6g.^p J>qmRt Xp7A3Wa\༢ZǷU65]~ endstream endobj 156 0 obj << /Length1 2036 /Length2 23317 /Length3 0 /Length 24523 /Filter /FlateDecode >> stream xڴzuT[]6ŚRݝݵ+)-R\;}73̚<[>ޕj " S$ 7q`aeٙXّ()@k bP2sysXy(R@ Mi0(]L=,2مM tvҾ=֖V.b10[ kbf rw8d 750ZY@u6@CMBU FX?.bjR"GOuˏE7DT~5}}eLg-F Z )y _]tmjdqP^:;d?6("xU~.ch.lH8="zBPYG? ;&Qr]mWKAļkJHP(&x[vĐt4#ӵ|Syu8i'wQl8s͊K)^Fb|;-**1* Bl=6K'|Hġ)?,#_8o #zo"|(J&pNJѹ RE<䷲vHM "_ 睡xoc^9WhՈVN*4  <*NE*4fz5D܊kN{b.hp'S{0҈=ߵXB=M_9۱QTXx6 nl4SqC&2\Z3ZtS8˓6FZl/sQr5+mCH\dJ;z}f)"N8G ЈcepmMW`!4mNaQ6'y`P+ϑgae^,dOCN~̆^ ΍siA 8SsDv"X5rE6M 8qikUm46atAleOݘsø{7G[8Ҡhk!W&Y:CM\>DG GB >FXáEՀtTj\U"x,\A.1}\;430S9dͲ#W/ eZF#}3ƙkV/tER sTU2PYz1XiT?&b)bdus||՜ FA}|X7*Bt cЛ2R#xQ,n@shgG;l&``xvΗ'0ѿ8R=uJ2-V0rBv+8_ !-KI&pi? yrYBA_nߣroqc^?K#V1?d%@gɇ;X__,1~zqH4fnbіV \ڕ`s_#u=<Ztwۦw=;xB,Ay}0eq8|fo3)qB25: Х=-0zpE|/z?!~ekl4?5> '9`9l*X,$#gBYVp7}jctU]u"+ 3/ɇ_'yݞCǽ4hY܆TQ@nNrn[W@p)FXUc^j<8#J0K>d>"[5ԥc$V0ݳҾ8߃ƌq-}|Q۱wޕnu|<Дi&ؾ@愬ҵKK]6~nvhV ] q\($yo"1t|W0Dd8dj Qί;W/lɐ4ܵ*VT3q9oجKmCsE-EY[(օzgZξv@WY3)_S_v Ni'Mf6*[CN&8F;OZlaB;ͲLl6eyʥ~=(~ƻaܧRF|jJ#*x(z꿱rȤ`?%J0M$f֌-cz했 FDU]"kypGJڢ@}fqW n>a0٨|i?N!~n FL;T&1"|لp/ޣFmfT/+|mE6 )Z賒m=IUYѬK[W9hݜmlq샊gYBal1 XY[ U8iO2e&zXE9@uu% 3ȍ\Wt*V%qWB0aJ`Z}U6)n 8uC11K Yj[ D2]@Ũ')c%ǚݙG`kMmLWF@ W$č bv9KW͙S.I7٥FO-1K<7:ƒV?CRs6E$ޅf4n !X糚Z~R bVl&Ј&>]0ӀYzW%PL ), Hg& *#|nPa7OU\ǛmyK(?) Z !I+z6gPf5RrxjL]A:1aG!ù蚱٤:v*䭊B-st*1g6zҮˇNfb6,x3&-eT E ZM_ fΡJ]J'%l4"*eP퍿/hA}U„hvz##)f g"b͊cCwHْW>N&&QjHٻphj3l}y+O1?g꒐6(^H+@k|iAB/>HZcM:<+;T"7pء:Wf.^*08 wSw"i/O(J#yI6jQowq+n%K§Rx͡zCnGORl{qD- tR%iә/?,)^ge/AcɾNUxa`[[(yF,,O+㠟?H-SB  Ez Π~e@[Ҩ8aVa})Up3cI]ԗxh;Slf+xpȬ句Kk \vreZyИ)G0rd'J z=p!if7FUC .|U=Y,FeU5N >`_>lqV>d5W^s77'2n-FJ˺m.q>sJ{w/昩ѥXי@xǮ4'u 1Ij&XV|b(f? k:Q0y/2]ne)7ZX 﩯 -ss:PvnV A UaJ,_i!bTfƑݷ3_ۮTwP,1]s?bNb43|6K([kCO3OϘ3;XsH=J5X-^S37OGNx3Fk숚!yV(G៩T@6^sNfئe^}pm&ݗBVpw+W^QVf:jR' 1 ]52Ex'VvKsQ`SczPEZm(rMӭ LQgmÃg'ЕfR {Y Ne=vk F`u-@!i(4". & ;1;h{'PMLܼ2j/Y{ 1 b7rL4e5cnM=w]t}SdM&2TOG@eR!줱'K%ӋiNI/j|GnWO?|QBn4O)Yz(cByNtO(+K~k<ۋn/KO^?U1aTn(Fpe;dyhgl.2V&L,(0q*]Ϊ{Ѣ1 aC BD쌀Ls8&u=4YyOlܕˬ0YHچVF Ũ3ǣr= -4"鲣QcJ;y k IHe*h QUhu2Ȥ4z)`T>g\%r]!McXr:˖z'z\G1\\XrEE[^CԵ|BmO*g~Q:@6 m&}l%:\~Q$"6\rbP;L,R 5%YK*yzH w ۦFg/ZwVĻ /Fg9}6G%)13"Z{W4ժ Xe<De0SY3[,F"XWhDROH/N)UD(䁓R(kkP*4m5{)E[gofk'/[١#ȈX #2?s(P1[MesO^4e, B{*E;OBޔvY(ٶ%ͷm{_S6&JGfOj aͼ<XOFd~֪R :suƥvZzc05ƳP:c'j᭷va[4x;q5J2Z>5Qcʩ>Y=tRtSNa ݨ\֬a&F#)cYp1tEXOχivtXNd_ i.K"CgzXHS"C}򶖭eRuHȜVX7[mB:G "k&yK=Ȋy `k7L-a7AaB|8msc{giZ\w\fTn*- H%W~zGdڥk+tl=d7-T[4s`D4Ͽ~(BCWE>*ҐWnL0P<:h~ɝ*zԁ[侊wVn2kyg0D;qO9*M#Ic `g'[@oS 2-cTʖښ#3 T0Ti2x#!ތguf];_ 16ɤ@j, "!A`ld`.0J̪f kxҐr^`b}FV~<{|08p" ͖ J,kؔFGj FǪ2qRM^ӔZv# 0_:P#+;!%>tu)o(&2ԡV[~aڜd˽ ޱ?5 #_mĮH`e˭K4+{V%?.@)Kb1L4W^7 ߔhED{>].ܓy@ZSZD'>liP76}xRRG#6u D9~Ǡ= q>i!C`dv7R\gّXL" d̍1Э`vD2><;p~- %ٍnF,`3)n,W}IQp?{qX:3-ku|T" }D\i IDy KZ[TkWtHgl|qp6&Q IkVVE[(iu#,ZnOid`c]n)!,|8ӦuVYXlHo׀# `w\[{K dFEFGI[6xk_I{{ޏ5qهCj?@Vבbj=sD [`u6_N,͘l:+l-f\~Nic aK:szY0 FޠWIN9ݚv]!tP$iH΍dq9yC4" =v\g)5qZ[9T+{Ht)jf]ܙi.O}_ݯ \RفXv,UҘ$"[偲FFӸ?ˡ`dϙ}8ٱVNwS1Űh'B)g79hMllƑ}\}ڜx1׮sțLwL6TM>m+%]1iS[Oy2rCx?YVoN2,nT?iF[&w rhV[M5p, dG^^`β&;B-}4cϏK Vӧ曊@Y3H{3[Tޣ9d~[=Pz2=t:@=S酏7? }(37*lgn g@V}k~ɏߊU$ɯIn5dT,Ko/;j5#(L:;<܅QI5vY;AidDew%p %PM1s4>~K'?] \Kp{tnwO[C4%_0ޝv_ #;3s<>f8W $ X|?g˜Z(xAӏg]1W`uC7$9jfq'ExNO}.AeTM>Q[a'Y_S8;in Wō$*Y9({\V*݅t48E1i);A-U^έvn6kB;"z߉2l•2>t贅l"vШRԟ:L.^B. ml,-^ O*6^E vBsEF6t{yb\ǭeJvE'O="(ӆ64&i͏Nq撰3$ u/'y3[[ʛދ7{}OW!JR$%MoBjΉoPvr=-^YzaA 8yqM2owdDZu4W&'Y=,me^2%KV/-+Ȃ]vXtV'?["O].ƕ喩RܾauY986PDH}gu^gG+6_qǕ2zj7֐ے~_|o @`G%~hPee/]Lܫ”nK~*ŘWCTs(Ё轌rltߖj{$ u]Y}C߈t1@`x,`h9j= m.s^(>[Ui~e`뼌΀Y`riiTi5 uz+hE%8R~]3P_0W& @YZ5(qdSV2{2~j{bՈC>$FKzpyaig߇lΘa?#;8O`0zLg؞v*a(ZlTr|hUϜmfa@ KH|v>i=0 ݤ<WE=/%ә X?s| ͮPXI B73\^EP P"^7d]7bTOX$^uBrJ[VU3s J>`HB:UT@F{xǞJN1M;F:71kpi]^U!oP8־zG*/x؁@صNEFkzS <`ܔbԘ0, b[O+g?d$< OOMZy+MQZ-[p+#1j ;? RrNv:NLѢa2VR.`*cD Ŷ*vW5X3bݹ6󢥰mc]~4U2^dTLՅO|ħ55*~#V hEZ_E'G5xE\D3 +߅$CfkGəWc>sH-!B)Nc^'zE2!y\f kJioXSa?kή8"泋QLI LO=,pSh/QT?"tנby~Dd}yIV~87q'S&j9}~Tgv}<%̙<.AIe(t! "8ŔdPOXqq$R*ݹVmyvN Yzt&pSy Z=~ONo癲ګv$櫠(˺s/ sR:LX \\læ؀bYsI{DUV َBDD^-k |I kχ>r,ₕޅwp e ֟hGX U˰')v,m0񇧻FGrm z:NsQ@^Ę6xX?omoTb-?&k}SItN3}6=QwW񵴢;# >vSe%kWCwsalw !WikɷFk{c 3RcZ*LK*W]$ޓhTky){#Y \s1-h vb -:o0ȅ!X-LPW .`[Z C[9IxF'|*3M<*XEcfʳ+}굏+4FÛz'^nA#|xz{ DŸjW-l,؍ &amsݱ;saZs taGk>9-.RSV)S#Nh( VD 7JLnRܧ|jW#>MBj߾&jϪ0u:o(7?39^;eAgtع R K|HkC|jySq8;ۆG"M~22}^OY;O{@v蝍r.NtF3?۹y8MWyE 3jf![gi:ʩ1]V Ո)yK'4г<~r'3?x\qd-;cgh}b9l8fǑ#'Sr-yhU)3\fNg+>>w.r*dq6?$#Ej3Cn`uឪ<(KUF˕?DI#l,0 H)[8կ ;ZO'|yIpsv^Yt?8\)U)_:O0iY»w[[0ϦeB4jqShO1a)RrSe{Hb xFpw0{6ȏle;:w=e׹ c!Fck+kOuT^nZɆ|nQ:D>u҃sctn(@HeoOcV/fzQe ?=$Xqz; #$OKNblfJ?5Y 3n F&蓀Hg+uRg>KN;abkZ"ړGS8mC*zM4sޮ0:Q _=N.3&Gxr+ mWϝNBZK0`ꃟ?:O# }B>b3g vHB7'MlG>d}w?X`74$izj-wM0$> X 7 Щ0.!'@=+QTf-:>τq=eBHTqOrIal:?J#c)A^YyC߉?, 9&G4@"v#J$ޞݶrd))Bo0'Wǿ6:J@>&Vq&WCR0lJ|Ӕhrf̂ҹ"qR? U:a|  m+ʺ>ZPɛ_1i,ј L+Zp i;EZ"f4`Kkw,%;@`LgB@>?GO$o ZÅAdb,DݎC v8 ?b0ְZҍGk%3cxPX('WJ"sޯ\]P7фyyӷ%fY4Nq*'#'0 bBg\VHi4٧ѶK~к@̮rfB~sLBF˼M}V*G9tyXY2Fo90h"J\-{(F =2}ي=5*i֩tֺ!Ē;{*]tS0&;q!g"rIrбsx\8LkL`s;k$ʒpo̼zt::'461ƿr*U[щV$wϪPo,PJe>YC@DiÕkz >e,SSQ9V?Jm^H@T`adW:/M C.~=K~c~,uG$2 X/0_ z߬T}nBx(AKfKzRSk[gQU1:P\v-wzmPN5i$!E#'}F}<1 ѯb&NkY!nXldww]Ǥ}qGeƉ$p"jwBK?'f]$EgOF+O{fтAf I/G_o%ORoQbC_y4@* $cz91 ߀{ s 2誉g-q-f^X4pkKF/Zla>Չ"х GC:tqr|Z=bS?T_v[q:TB<{.9 D5\INbf \_kW;Gbs J|V<s%Lb?3Q*Eo,/}K{q:QGdb#]`.(_X'hI J O'A'53%}9 4XZqˉ{F璓5 mL"{fqzsxAX7ոz~?+kUા-Q6 |XIlmq**wMg830[@ʷ(eY)}Hd(S! Ƭ6K}&#|XIm:F8ka=yxwRZAS{cHX{Ok#i6yT1{dX]yNtXՊjTmrб2gS?+UMd.n՚)53"Aj.4(I9zF RLGl^ h “Qz8AH݈-h1ck ;%0 i:_oʮK`Ui0~q!p0/(ᜮKh {W&Mj j q]=O@%tLyՌ+& vuM̧b+כe5{ xˋ4,Ԗ4Oq=V|r&͋GgP'ٞםn/O&B0])-Pp:R=o;nvWs SԴmΛHJn/QL{m ™" &keL±(ӹP\Gq+1̒Q!^5B\Y>X@~VŇˆ~wTߗ . %uye 7~w?Ew^rc?drO *D#{GX$5%hwL +YaߚZL-ƺ 9ʦi'V((e'+3,B: a[N5춡Aϸbʅ433>h n瓊69ޔ˪n Eh4pcܐ!n3GXTY5 Х 3#JUvXVObNZ5[ڡ#Hs J]NR&Ed%< cl$m(1ɫV(tG'3Q M*$ ثث!đkLa\xJRZxvn(2PXڸ{ [?K)@1"! FS[֥[ifG^<Wx{Vc]ܧ:WL@*S~&'sa_{-zWD6:z};Mr^33 "" 3x?ZQ۹p(aPpJB™z2%+$71qZ] ǯds½Б=p7ݠA/s9tl$< m Ci0nY2)D&pͭ@$R7~-ʂ,nƐGp})'䇥XD{*Fi;F+07 j,<2F?ZSLP>.7)}*z AK|P_yb3ghYfb熠GKn91:"+]-ad yoEވֹO:([%t$ޥR.UT5d*Ha"p[ZK;: xbZHzot̽Hwpjx ծjN3Q$4J!k<eਖ9oR[6 XHܣ7t= NnhU+fD-2c?n(A%04(d>}r"xK^GBU'ud)Wgֈdq~W~YscػK"`m~;LPE7Y%HƏ/+ 2J-XAs{ג +g>:UnNk. 2'/,%^XY&u $d\)+vA ,znP# R@aIЎ|jb^`F{P:)ɥv2z V55n()*B"a +@L@M#fX6}!H[*}VWFEEA GrZÏCaTM m5O `a)4q8,h\mӟ f5"|,f>A!xvYz{1v1dbƸz6Rz%hKNWP}IU~MOܺSORpFRtuAvRO?lO-st䔪tObL$7KP1uT>JKv(Y<_jM,xߣ(< sk܍x"n8:Y)k֚,׉pTKr{2^T$ayM!'182Fi/qe,$g|:(ʼnI>핮B|whiU̞{SU5QCCb)"w'JM&C!HĦԕnT1Jlr,zIV8K7U3ݥ q2a^yfɰ(|k ԑ{kl_7}1}ܟdUNUpFE8%iĕ7þ3ioqj)d4\PSU6& 3Q Dnxyy|ٱ oVpU[ HX.]$-J{t&tޡIА#teP )Og?PƊ5!jc~"' kAȖ6#e!P6&m&8 apKhϸI-*,:eψXAx73vAU (Ae9O7uvh/5nl</wج9Hurtx5&mu cQlV;J?V@Xa\ffGc`ì)/ Zm_$-AiF9s^OϬFK8b W r8ZnŒ٭15~ojBoL+1ꀑ1j(< c{K=֞6wZ tL^F'Yb-mB;c]?ryEsJpuHZJ(wxA(bCy"L3h:"@m,GxT 55RJ WY1)pC6_I,谂<Ňь8a`y:)%'xQ XY=[*\+{XA;$7!.%^"s҆ي1 #?  `b=ɕ Nmj!d6LgYT+$%Uեs}kaz;Ry _Fp> stream xڴuT=Ltwo4lb - %ҩt#-!)>}~~y\s]^7c@M,nʀ,l%e 3; ƅDM-4ہ@/j B"@gi(Z>.@v?@ f0w6v@zH$'3J%X  /w;@Et ghښY Um5MzHaMpҖeHhI:LYmM?6L-wHtei-q-}5ivkHlYC ϰXYA`H !PnoӿUJA|V?*oXe  ` H??OS7S H??OjAkA.:?AfF\jAG@LFܐxK#d&;dIVAȚ*@3@ir@:ZI =T`Էv;WAH_BaT>.@" 6 _"__BdS 9%!j$ Y79"qZn#' ퟫߡ<@;D׿ц?[C$Kpv~=n_% L4,lkn R@%@jx!d=a)H_R/9H%_ۿZLm5?9`Mkgy+Dfmc!vf \eKH cy"rAހȵ?uHK K"*OUQT)$Zʞ &*ܢДB:>~i.mH&->Zâ\EIPPk&- =z$}1yNiTΫg7G,E NũNhNByìYqިknR[li;׵eCxw$PAT$6#$<~e4بI4.b)I#f{~+}1 铕 *,'Y_v^i ҀĜc{ekۍ'Q-%3T2nO H76&<g2o %^EfΪvI 4BW]o@_`:ͥ1x }I Xo}v@o 2xNui˸kbL%0!#kh+;#G ^Bp<⸁ZYbɱކ#jtfPV4/*6uT4; }ċ"Ht\Չ|vDqEhLd[F j^8CV6dp*|7vr&CY!3?{֭q{ nRvmsU^דg'뒢l Y{$\z3&Q#89uW S3iWl0M|Մ3YA_(g|o iYqaHop҃'wCl;ew_`QGgpJJElTlx׉\);KOI\W$e|;љ 4]Qcj~"ox#ً؇;=b"s yegi>=0|5]=QD(]2DgǩaF8@~e:oNJ<}E$smO&[)f2 >cot*A3JM! :8]HZW mF*yUX<:h#ԂEKom T\Z 8婊Y 2*NO.+)4ͧʆfߞ'p @#S<`Cw7,yQ a#!$7b/7q<=uvxilɣfo"*7u%7=;mHB4 8:Kh-2w"T0eUa{3D" f9YI /KUsXS"KlZ oWn7B)ӯ-dl7 a q9N99?vth9q\s'bey?Gz&> vEzgVpF<8PP5dXkyy~FUDŽZ^_{}׌2{s1ɬ 04d>t![Z4XM/$F[:dgCњc6X쮎I%;p튳ꂽ 6x3DL$;=b&at1]yla*uBO=ׅvK2LKTN1#*έȳےiXsqxiW>as@ ]eY\oh FeH:)s3\-C}X<QR=I9~P>Jۀ2)pthkMx)]e䍚1zבR]Bl,*3ncJcXل ; @o;tGԓ~vRՀyv^AKNʴ=n70tVD$ )[FPQِ+k0'\TdיC>if+Q2fz尋4]k.hX7ߌYHVx~x/=^8~JgX)r/#@iʓo;ӹ@^J:|{1"3avqeZldkI~%מ/Ø.K8ljs =퇓B;iWڭX>uwmmWX.Q{(pڨE 괙xA3?ˀM)^ n6̝kx&A498"0j␆4RU6 8?/,+R)X_Gj댒Е=^Tœ`_LXP3Lճ/#nc*:kYN Wh|:򄉇C+e+ \ĐέUy ZŪ8%mؓGJNĞA&khWE/yK )N԰s#\S6'_+ эq}d!;,M(J4Xbr RSi7r9TW*6;AάSBX} |R xSӴB,qUR<l]GVt]twp&,N K? v/$ cv0fUȓ֣7";[#ρƆw|ZPhz~8#hG;=DA&Ot>aiGlҸBGeDj0Z/NQ ܒUw_P'yzPKTX#>#@fM} Ԩ;XtJq&eo栾qLh8ɼghaXFz'<:f2Wc %S{6wP "6u7Ìb]20]Fhq9-J'emRfᜣn<]2'bZPagiw{aL_+u(Z Pjw0+!\vfeC}r[cmbQQNzOi='  PcU!;?_CFnG\p4e" 'yءKX* ܇pGsb2 }ѷP1̨4֖A{ZWoxHP8x0eb+[~޾O980LYbEW u 1c ׆EJ qy#l?LDK"^X}kw'zSށ{tP"ڛAk  ѕw3 nE{Ft΢~3~FQASvO_ٶL50K`~v瓑= q@=_qO+sX`ikg+yp0FTLO0 "Mfr.hc\HC՟tUv} U4AD"dКَJ [s^j͙ZG&;l,S:ңETR7t~(a1NʍyOP)m2U$ o|>'R6FdV_ɉԔn j6(0{cڝki&*fwC,͹hzaeغg[MaB]fM5(w+dz[#c㙁u辇{iXG9Y6Z ]7ÐzKjM㪶a/I0>!swN^܅]NrmX&uP`ix*B_r,Q(%)o-Fڦ Z"x;ṱuJ+QZ1=Ag_$0\cqVa Q,] ֊ۓMӽY[E~[׹B;g"6 zGQw'%`Qk#I}=m*~SV%:`?fV(ul]=*AA:ΐQMa"ˏ0T#MIޙ3goEe-}74t Wd^Ѥ.VwsVz,T.K&eVYӐ:R.S_ui:A@6VО+JkżU(IQ H֯ xzX#$iAs>JӤ[bFio~6zWt-l a%-uwy3^`†L/xet%L [`a}hU]`=X]SZ5Q:jx5f8ʡ{-;Ht,7U])?h&V<{k* 7D.1joJ֑|ZC* /Ut۵ TGŭ66E i1}`"ِVÊaIp0kv[5p=3b=vUƧIkmp} =V`Bq pVO$$' $k^( 2N;!}C yfN[fՈ]N]|7tMw_¼FFH9ڔ C^-][OI;^c7!,HJ :h!Pk >ߊԮ\_Av2GjwႱM&^GDߜ9:i*(QZY,kI{ UIb qK~o*њ'ufT9iδ-mz{K6e)] ŔtG=7W\߰NHE1`O#T^xV9#zԞ1ǚ8q>oVa|eۋn_n>@v}O%9 a@oLlC>=+Qr3Im6컏p. z-o.,(&VгYÃC?'\zˠǂE+[9FdyX^HxSo6̎0CQ_fQ>CY/[SCm/1HFA31&|EBiw>Bs(N:sr"oD$ k :^L>M_Hq4T-f?as'L3+1yVَlQ_Ȓɚ?=U;^yΫZ@ĉ1_0,Jú| KЊ8ʔ +"`4'CY- }ؼ%s ;)lwҍA P|#^`tbzz1S:kj;H㯋Co$gnp%?H]M-ՙ&us/0W$KyЛkN7 Ѵ"E7S_[^1=)Une;&kn+F!52]KZC763gvNX{H"ЀQJ 5]ZkMu9]o;zHL O-~jqf X%JB%H=?W`y0ȕJ "-jD_rQRAin OYmkA>ŽL"# RG=MbTrѵ6wEЎ3U͑Z1R XKR " iCJDւ +梾Újkv*PT:Пf PU×6}h?wu6UU)^.5|VL|uq+BPZKYeI&M3QYBcXl}oYˆxbݎ K$Rn| JcZ>* 53 7P/ܬ&`La@#?U$0Z sm* {΀VYVjyqp4-zϑbm:ұ3@t^xW*ꭃuQYl˹ xAp}PNb7Ȁ 6&fL>OiM]Jb-lؾ}M,_GC WBGPW$UX.M?1R+ըQFRx`Wч( FefP,*8ʫtWE2Ɔk(Kкza6["ȏ OcMے s?npС;1~JO[;H8.QXt!vh6;2Q=>{;F2P #~DR/e1 cKULOoOoD/umT)| NzpAQMoXd9CQC#-_י`Eye0 ۈUnܛ5)7Ѐ2)  [Ucr-i7_M-Iv\cDSuf޼7׵l-(?D>!l$zDQUvx'z h;nOd_uݲ *0HԣpC?QNYӑ,F59`Pc&hȱw5uw&oa[4DzB\~#KG-dLQWfaР/OM(uLxť&"BcH(QPvW͚kJiIVl-&wN|Y":c?ձ ^KD96$k7Ogf{Ku\ "9u]7e\(:NoFYn5dU)qd/ vlbfdTIJF,9CR|s7.hn8?hXbYVpκrԫZ P.Q%Ѱ1B)I >=dn⢷!/\, ϏH,oߦͱL!i-hV' ޺-¾^<͑{\cjcI.Q=dj֗\| ?-ο'@bK?ū}x;7]51Mj='xoRfj凟M=m>N<یc@LrK10vS2 Ro`Q݌bK``Boْw@x33r3 iH*)uƁں[$Ḓ}lbi3BgύO8HR½CnI"5ܺo4&}—q>|/J N+M06*"[_O@ԩߓ!Q"}oҧޓ֣!$hN)0;y^hC:F2tX/h225.\e+9/ލcGP}7dB_ 'R4! D^Ԅ%Gzrn:EØ:i52̵/)Hfɕw땖ءR9{ 0ف}$@E6咙 C& ^:[(2Qfs_!@үhڡ.47hdgzr&NB?}#hs(&kLrTژU/WǙ:'UYͲ`$7PwA܌ 'mA.R%W)܀YlUZm{_# /tf]x (U_ tqOZ)Ϙ@W5\_rwiƗzAܔp<t;5=_kv?(ٴ-9f-"O`h9͆1FKIoe`S% cM0Up;י]o3~ ؉|q$)(!P.Ġ2[Wh-`ӢȸdK1M82cH=[`sңJE}aԌ\mS|hTS`zTX( J\lz G 9|+7 H19M9"I[>}⤌>giSv?uWFk޶50laf~@]L~=Y~?F\_޷(tmYq|"h@E|VҐd#/X\?ރ޲LRLR(̉LR@"tS*$R [w`ELKwvGGf*1E`T +u|;yC'1s!ݧZleAbTDNn׍ϑ'RЭS*O*D#2A9"k# c;bl# ¦}-s1u/H%_~2'OYgV詨p|޶5K"d _Q:jBoyqpFB>f>u?K)\\ǢS9*"B86a@M*O]B"):,0 o6Y|Ѐ&']ZAYJ 3*pQ'OL{j3tsiޗC"%qcs`!РD8!`}d6I;]+D9EĬV ZUL%vEPl2c{'|W~kiXw`/yWyqNLOِ}mn &V+/ZrAmBqH>|_1ƠŌ hdv8_-;$EIr }sy >aJu/+75}<eec}&h@WKd 44xSb+Bq́Oѧ5"z^:t8?^}/kagBns=w+u0fT bw_d_F;UdO6 #4etf`(JSUk&iY̴VUZnBϾ'"*"K77VFl\{hRųV7G`T \*se(M?30:e6ioX@1rjxGR}ѐ鮜JB\9[uL[Ic"Nbd$ң3Q dl YfAJ&3VR(ڷ}·:Z8xMmaCh8J0Z vªxPWԂ`A‰ɇNsXMyH`>{*6,(RoF!EL K]uBIqM91<1qB}?`a /`0@e)y-`]eh#X?yjHxԷŲtjך!]3bt=nܻfP@|۟>-GX(OdGUy*m?˘NѨr'$AR&/+9wݤH,ͺ>+FZP(4~?pBF}IЧf熖+W~FP(WUG>?`76]g-}a=+ZؑrSwpNqCQszϧ16wTD*D)[Un(x$CMuDop|-129@eg[^~ΖzE͋|S]@Sk G" ķկ8`IU>֋ \л {0?xGT~NS$z~U-s{xo\a}x6#sʥ#8MIy~QzI(qdvp*6Qst5ŶAP0(8UO.$SG4"/]y%Gzկk-e!7f; X|iVc qO;ش2Cڜt ՎpZ>:Tq괹\ 8/6kc4|q2#Qd=MÉr"ջR:r ݏFyk<<@U7a${2%PXeÐyac_4I١?%. o펬YDxd3_r ?Id8؉?vsD䏲C,OdS( X"YoV"r;z/|UL ;Dp 4܂}`w0Zi#LVJDD/o{m>$ A"e`Q Îz1tI@\ْH?~LaF5te<q"Cūq fG&Cm /ǀ!XPѕ:K@NBWVpB22[)캻@Y-)Щ.,` =5@`Xs(sZx&اsf32#@jtİJ(54A`Y9?xfX$k2i pJfTgZHg% ڱ 㤳O|<#QEktKmL!z=poPx5,Ap3Ɇ90j'W0~ܑ&0PmZO!}Eo) bC -"BĬ74(U~ތ_SCJKW0:^GtZJdЁP?.TWqm#'_[x5tg^P=:)h:Y4b&y/:wH::qSW3hmmOVhU{m dO$WGVNSXf4ߩ ̸#~}X6n,[cik<T& 5 <>VnBLLʿVqbиvj镵1|RL{Xl`2f(֊Fl#ڊÉnNGc՜M'ӏ>$_B/b&46*TZ:*j0Gov-bVּY_WR- Ϣ @To^ÆC ^(aU* a%aa~w$.rt| \DWlUDv!5NbL FݐO$ ͬ,a+*[cLrҎ_],|З8j$k/%MIYoi@sd\;aCv<69^^XngM7iFsF HKk"pJиFf!ۓ(-ܩxnHutXی#LedN_ `'W1Ǔ.|o⋥] H\Z V!wYL4rhri%?⒠ڝ~KWcV'N䋁ޓ~8:<&3v_ z><8A *&Z;eqIMX?ҩ}=g H8@0^[FuS*vmK7~ˊ#<7Y.քUA>0$i($xmmDQ"0>yh)HF5=jBX䙬?;8e&6L2;T?a wwPX"Knuy9o r }e{aᕡx^O4ƠF9LR~ Hq*3颉Qwߥ2*n|fɸ@Lڏ/ZZ.U_)3\yA(<ӇMFHgM5b2^,|G=TOLPC1jѷNŧfm(ICg\/ ]ߙ􉏫-ȼo,WWL%OP5o!ȧ0R2RU`Dz[gY[Cle<ݳxM0/j*>{3}ȌF3  +)eT=/^DqhEzhs=-ҝL,_2_WXZ&`ceqX ^i|5O,U>s*3g*>ic7bn1O^/DM~ a=FT['vhı]X{ըoW1Xũ& l\ E7\-QegQÒc[dLdߏZ5>VmeXK6Nˍנv7L.c>SAGUhT25٬txLRB4߆vOHՆ( 9`ݎu=Ӣ /8D(ZQ,rs;]A=^6tQ,p^??$[AK_ bcl7ѨRf\mLb@j Zx@Cr/[vR 5-fU)̾ztKg跺D✗B7Xk1B3D>Hs4ծ^wU2E92΋eEJ Am:i s~jV !Gqѹ5o-eWo[IRw;/'">nkAIo?Ox٧75MW 1Xbr){؀6+³<Ȯ"bk\ϴ"?GbKT7i6 V2Ͳ:)D#:3cNVU%ØX^5 "37# ^ȗ=\%ӾL ƒDWi dza')E5 hlV. \~ُVdԾ8} &GW,9MDGXO R=PMqVmu4p=LdH lv3R<'_4- l Њ+H$|f p:=*kES$67 bX?J9O 8!D\'`.a99"g&%1|oζ%9e`~ ډ()r\G;da1+q?Mbˍнyo= ȥk~qtͷA_kt&0fj| 56c1>"~/C(Bm^Qh%ɿ9SU>TK'5`RKaVeK ܠcn9aLģiͳ3oS +r#`Y; OeeFr3{7x-ݺ\=Quڿ ml%MJ!R^BA_n9|!Q<`[-ws4j6^ȫv$REߜ~aխ6r@lYYg>6=|> 5 s# I6*)ry@ $Bzaᰎ+Y#?ս{GWAzMu[3O`v/͂Ss`{$kpj& ռ]GWOLh'4rbYXd[۵d-Dmq˜UMfGHI䌘6Il۪y\64[Z]p1 {LnUbC{_oPr)r8<*pn* 'ߏwx&C5rkTaHx뮩ʶ8PCv<8#~&=Wdq|O0<̳C˿(^Om 1"L^r4l 9WW1\jik@ͷ#n@[>}^_m%a ̥oyܸN*S< >}3*%2`7QRf[韢V,Z[}2e{Bt^4'\r6yF@ uP^R"|}/{9O4y.d040ËLRjp|@φWnbR6RDOW+cܻ4MP@I>I9%Ыap ǖ W$ Mb8, ? ;c1JlL&e;L[(R.st,hŔA- Zɼ[ìvj-cUNVQ?*4in #7 zdTHpwVl]PONj |'ws|_/ hZ:a6goWoqfx]pQÖh6 IpiJA=x, t3Pq\u̥~s _IˊIy҆k.vJ8P{Rhn&iFJ.cښ: &wvaH'# iمi+ b/IgAFOBWa ^.LތrPĸW3rt&^z?[Ͼ7Nnr#^Nn1|ɬ$XN$w4m@MpjTZG9׾ͽ80l3f[) +CwJ>O x'k--&v`iRvi"nU ^ޖ氱BG58RqP`"=Ct5OadSMϤ n=&Q~Tq&TY!;g"uLWt}YӀcHt_ԞT QKhHgjܵxna`e"LV}H.K+,RuM35.R=sMdGՕ1KaOK/6Go ]_kGOezCb͍Ю|>ǟ&C ;k/xDmNRGI{ I7Aq1bq{ ŸU߄tFk oխdu#O>ߤJYiG60}QQL,#ƣ09-$5hg :;֕``425,ưJh`*)s^% I1txf1]})0?Ydb 4ˤo-, èX1 ~rL;JyMO4jC1)*eZg$xED-i* a&[3P3ގ&j[>~)<{xk =.(X 2Y\ bܱu$TRrc*oνqu Y&M i@91P+RX˛]LVII@U:]'z _ux,=_@fQ*M LuL>/9:etk@GWN"4Ϻ̚ONII@J=>iHssK!Q/ ^%&9G1):A\3 m~:eRE7c AjḛY:)|5FfR_Kd2N8?UT[Vդ95Ƃ$3(bBC%%;}(R јDwնonU R8#9; \f THj *eYmd@j$uuO$& D5_" lE [@' qe j$]E9~f(嫑N!(滚\"yRPXtMicTqѷ˪~Pj*~,jUCy(3`;p{P#]Vwlw=+Khl<B3 -|SN 38p1 vA,!ޕ&Bnyi3\%?ػ'j}D?F~scI\|)3׮`,'dn ܮPt I) [F#d9[cEnז80,2'wŌ1<o!݃:eyG<=/75 fK!ئx^sBqsjC'{(2NrVOB{VW0kΏTއ t[j;C-(Mw%_-Y3%cTna\, ^Y®0A 7tdYOA?`^nt ɢΈ٤Uf`Ufaޟr߶MFO%Q,xYU$>{@v%>_pbyĠAw k B:&y %~v[r^%DE[TWEz_ FVRR|W6@'|&WHO rqlqcSM_ ^OJ,+=^操|{hqr麙׊g$WAd{Z\-*0唉ꛃYTN_݄BK^yiYC)%Rb-#L5E?\uPuvo%,`8,ܮPs ߋZC1ĺ"[yGgG .kFmB̠l> u79 *?^nc. {77X8h}ۂ{v| >ʾ47'DT،:)Tw&GMuƭ*biUMJsa3ȼ }FwL!4-;?,\| o°MTF{}ަA p4]t6cyPVe.xƎeo'ǖUKU"(OGĮg1cx%@D_Y88ӵG7FHdj{KB¼‡6GN~Fé}@Ӄ %-ϼۯFuHNH.*Qy-Qݶ\3R]XX=} 4 (@f[]4$γ$aF 8wlNJbmMYxCMBHc3_PoEΎ&;<'I2GuXU~IVTTtܒס5 â O-m;W2S+Joznx>Oj#/:H?䫽%UEiOn%~ o&wQ'ȍ#c҆s:r~>긠wyv0*/9M TDzW0JV9t""lxʐ~ _&S[Hx{XYm$fb_88-9*'0I('lS*gI$8#E*MNY2ůկ-Űi2$'Q$ PQj x>& 6..XaPX8^r3U8 Aun5J H\47ȍ>)^ M0^jITTC R72ca 3剿HoIEreByϐIB2̈́;䙑T]a0b=/2=j4^9#BL裌a^Eٻ 0Tf_6STة=pD4C@ b&ޅ XaXa 5]`Y!8>"'O[jշD!2  }q}q? %R'LSՆNou;TCuA{Oi]yZmn4U-Z)^&xnZl?Ps*{ؿkZ H7iAmK=ul @BDhg nKgށz0UCestݧ|"P0||hÜˮC„q.ּGv➠Aq{7XOGG`uZa|Ms4`Z)<M#R,`p#+>t-+/czYkΧ d3ԩ(A yZ71O8yoG}svÝw^K{zi?z,RA^2=ǃl__ J_ ' JwU+|2=Txu pO]8C;Zzo(״+ {~uD6)viA.QWJ%́.˱=]R~7-6#r}̯ᴅV,etWK-r1 4SDUf9,w9!Y5 ^=b4_ASͺ Jnx?hy\MyO 5ܕ09RYt2Q<޼JYXʹL?;$w-5d@>CϘjO+b]o ,A,?pkbEr%Kũ!U϶;yPfPc^<ݏ$[rͭZ-o &A@S`-G+iKpf5 cwq'`qԑ[U g}'s ҹ(tS2'7}ȅ}кʵ6/is tq5j P!vЗ̦尃]iDSD̐-84 {!HWO,]~tO"̶/ QlY1-YGgWųqco>JL,x 4yK,ڭWذ%٘؞AҠh\. puHA3S.gR#w^MkX` e*72[q[j1ITX*lEZo] _S=:)2 s4t_=-rCM^j )O4-$anP\+}t`ED(%ciUɆz} ^V6Ϫ7L+ G\u!66Jve߻PLe/K\wA'm#'pN 0ƥ0F C%a 6795NIX'* USu;Im8o*.a+3YMU# OöQxBjZ2wYeY|a y4uly,ڄh ;(S8/r//iV)/ {dӗ'('o+H;༈U>cȒ-ij W"0&?/aU# !k6m nl}Vwі-bo^o28ֆ8Rp: F%F6Dy(pȾe' g5[O>[`mƔMƼ+PD#5wv# AWZR]+R%u;2$ua6rXהb1ʥC0.``[Q3U!)(fZa6@ne q e+j&uq“ĠnvxK/E,:m~L{ju> zI=5u|bo VA:3u{ɬW< ?]Fmn~gRY dD79$8,ַ֬wX"+!w-m~TqC3Q澣ue]J_m$`;u=X&EF(^%?(BXmc hIFJ\_:K_"z 2* `Q%hPr$Κx*g ]\ n]LX-K(n4l>_u#yYDO5Xqd/x{K-ߑꞃX<ܟGq3Ma0,‘nkF"ʚװ/b ex@у(Ifq;9sU ΩՑ9?.te!߾ESȚQX#p-ݒlM8tfo TX4|pcpW۬4 #ew} ˆ8_׭%ᄑ첏MHRXf>V[7C`n6g]Z2 6vLQ@Zd5J伸G1zKѯDO+u/+靡@YDj0$S8[6U06 u3Q6ͻ>Qokp# ?r=YF+6S)BibV{sТ,_K-u?!1T2m BI <"m:k.HpϠ'wQId dwҌ(Ξ*bvv5wW}ڱ]G0+ǭPؿn^D#' _E+@)vZSY~'bޓ{eZ:8şzZߩ=fV,ᩀePSSٗCoh3N@w':Zބi}z x#"A{`+H㈄)Ma! m.Gu';Vz Q;R뱻uNg'pc-v`p #yU*ujE]!FM]@^Jc_cκ#zF? w5jmG?w%fҏyn(>X퐌lY/'//áMb|P''yo&,ёZ$.(^#s=0ָ `_>L/_*k/( @(a_c Xă9 `+IP@E!ȹAҷ_]Q&Y=L0yfh)yĉ=%'U");G3S@ޝ%}bS7>uT~yC/'Spկ%ğinY'"(,u3 _i!:oT`"&"&4Q]-G`qFvgHR?m8RI!r_`E˘sDeHVJD!H-T+BȉT{&϶ى+Ntً\4p3_d;"ˇ ]=vĔU  M{4[ʟ;>'ؚBұZ7y@yxAeڱd^Zl"SR 4]S^AI*@h7;$fvu!r" D*CRR.OF}cN>q0@!>YAH]=*#dWkR,9Djr0KzF :rWc(B|dƉRkb #1|[N_Yev^,/jeEa\E^#a[Cu7֚t 2^ zGxbo44]XEj";^6R5j.֘zt& gOhAk"BM =>Hghi=b@tYLAd9"ӈc5EWDZHnI;Ω6h7*jP.yՄ!0ZUl|d4k==2r]C9"WYj5(FvRSI&mVtT'a|.$=%"M:p`"s+nR6~edr5X[36=2 YDs% ^ `(5hW/2 zi@tcͥofa.Nv4Mg=fNY)?!Y h6T,0 @׻b;*6p RK 8#HD$p !:T8;EK!_{{Ix}F #Dmmi+>,>k&S> stream xڴuT۶>[[qECqwwmq{s>wFF\1 EezaPdDS2s+͜ , LLl@C' dP0vz}`bFHmJ;@dndPANFj-Ed`af'+=HE҆V WG+ @A r}ZA#)d PjTŕJ 4 @ETYEU &,"$UU<mUqWVTgf3h'q|g7wWS_ NNv< fΎN 3;[8\AVWamMd;]Zm$@+mK.w_bpos#i UTZ:m m @ rKiE]2kOoC1C[gG?m uptr;"`ja ϞY%WV}o<[z9{ulܜOXL`f07(杵#ŸY 6-PZؚ3PJEL=fl'_GG^oO;ma | x:N@o*!0sL,[}\.ek p-~g/4_J>& [kw QLp7R?5oCC k4/u CY8JXM-.r)'5o_"?#e޻ş @_4::8vW_06ىL,l,CCw^`agx27 f02؂]vNSŸ b0~#qs ع}y03M YM-f0}olo`GbĠv9rߗ<9&߻?'_XdT0y60oz (=yҳ11jٽC}o?'t#,/y-K|J)q4cӦ pŲwH~ <>֯- &_v }|PąGTJ;Iir5f[c['],oI:k9ЮsMXnKhKSNoX˟f rqFazt0ST6'(DekkǮuMҧ+tHP$ N^ncclޜR!e&g.LXh3%.JST0MH=#[# *)kTRZ~]9QR0ZrS!^ވ%)i]_A;*)pzķ0p̣g)lIX& 9^zAxŞiG|a4հY$y"-Wlx5#l䣚4 Q^}=aó{vvv?- T•6M8]BE q?8|~71jDS *[h֑Fn 3D?ovcc!:qGwp›jl7.3u_ Fj.$E=4;kے-IRH>.QKdd4t VQt g{Xlq|ЩNE21~+tWP4jJ.6)jBAhmߙ'4j$h^ ЊQdJb'@Â06$X芥ߍ8DuvyQb2Q~3TP,!pgnJMqpeJ<#ڨC 1)Ƣ3U R|J޽"$诜Zs1GqM[ˤ!Rl&؊TNKӘ.#p+^]`AIb.&mכ*S%t ]GP6|%S&jy/ߢfT)4Vjlzp)mӷӐ}

42c:pيjiBGq$6kiڷN56Fe-&h±x1`8ws CkHOamތ^~䬊ZG0q1`5(x>pojqfkkͰ${-CDm3WR­8v5[ixSb( )Pۧ8,T Cv 梘׹ȉW7d*0Ƌ-By?adl?b;U#/{ꅆל)^zM-Mӑ2.-bT9m[ gBH4? ][œX$QtiI?KhG =*ۗMcAe:%.oW# @|ڷySX"؜?dzA1vip+SrǢD%_QѺLw LzV +u߄bP&_=~WՈtD/t sv{r=Gw[͗nTxv1v%`[nLP_FcLc>@ϫIF^דH&>T=U,Z=m8#8Un#ޘr/>*4%i)|\Fs]=t?OŹ̴9*oN\l TOfGKrG\#,P_lX'W= àbջ+dbȝ䁙vG3x~%YbxI|X=@cy$ًc!06TOv$y0[e?F^D=ѤSUg&cO/Q.^}%1.!/2ZHJ#t4ht9}j.7Z0g%X@ӆRp%k2\Ϋ=T>iݥu2-=ϢӬ4G"gMy[kizҟ.[٩o+5[*L^.lY&X>F\R_g]뷘짍ű_ ȉ"KS,]`c(˥ yH473Cg;]ZHe(Cɺ贈EUY؛~OE;{^.gҠ1$x]f%{wbRTGw',\U|8QA=jUp-7m39Ζv6q;JB:w7*xz@*^\!m" fSLmfM ތ7wkkWrHMD2)dFQ#D*5ιݵ̨3) ʯiAFt_:͢8Ґy{Uۢ]7%cb]~4d舌EqU.9+QFH/^D/d!WLn!,o")4"ssuH(kk7+MhdhB_yT|)׋),|Tv.*e)e6(Ԡ `bV}*- -8AD7nLIjglu!ٓr:A|Ͽ_ P}{֌uLψT]&nGG=)gza[mK(a_>;Cx. (rM ?%58?=KJQYL{v޸q0i;]^S;ʀo#yn6*X{,_Ƚ~ jHӫudPfI~MEImC!w 2K^ zGVBRJ7?}@EʹjTF)z4 ҕkEVبt>HQ7΍m[ɡ'QsR0c{5ҳ*4X"}o՝.(H+M~W_ZwBQE*/ )9 +Żz`l\Ic&s>f(HXXBA"۱AI<:۹1]KaA9Kw`ye2kФTK]Ϝ}Nxñ&V7p3-X.iu=;YmKM5F"ڑEn(XB;v;U):i}&EܤU`3iErBƌIE{A&^~s*Aj^"G{ M*)= 3Q, %FalgRǔ/7ƃ(qt%gu W!tA.8g)"(2S8aiWn\SxkBrY!,koy%4WrvWv/ x3}ݧt%y`JiwQO[5AcI w8]~2/ dkٽ?ӯ0D)35QZ4%oW%% Zmd*ʒC55 8-<֛(A1QH52Bqy6LIKn9MA2ȾB43HXؑ>MB!ڶDv^hl 6傦sNQ'2D";xiuH6EcMUAd Eܒ/u3F?t?p}0Xkls ZYL1jxI.f/嗖 ѯ$8DJuO/ nIسGP_%&[5}[( f[+ !AUՄ)r!+'zOuz6ȵRhZKĂgJ4 kx^v*YRi\9^Ēɇ ;;@LẈTurɽ߶}&K\/33§v▚P#8FЋ9[es.9W9ӱOz;3rԾϴ?N6{?6RgC)"Ҕ-QktMRl1(bbUf<$l+lYʖ=nфfd2%.m.69TR>8n(ӨL l|7泧P[]ږWZP";NY^Uh"90<'Wn'PrD A1*P;5UBզ/Mn/B7.?Ǜ"z2{aLC,zmorO4Ȏ;Zu ɻ+nYX¹9i)'|:N)W7H|YAvcy6Ai86~ Ő`[h?~]FC1aZqwrsĿxNn~UkAEt0H' B(.:Ң *<~wWBQG:TlNm-m@uOMZYl[Y(diooj'}GmIz8xu 0pv3"KO`FpSK1}(x1Ζ<KO%뎨•jy˩s'%se( nm/|SxKMV0A͋wbH-8]Idae8x¡96G)ܠٜb sT唩 1Eofo&@qd-Qc4,҉'hy+Sш '؁TC[Nt᠁™ ތ WGsٽP.O nyA 8Bp#/'YB+YwWqVPIOmZyy*1oSFp?L5Ҕʉ{H|() \5 {V *zi2/ j}*ѶӜK /9yϞ$( [Gi2D@98c\jTo]>ʋ#'}[rM bdah1JzF2ag³y"mR3Մe[8 AYi=Z/ɟtP C_@Wi(uuEKL6C5ƫ:(rK@C,Ih~~-t+{*@?fYxE"6(έUbP Uƅ{!^P-LPAӟ9M!M>9e"r O~mu[xxPԓ8C^˙&H"M_h {P3 9?QTg:c#sfkl-6#o-PEWC>Q袎: laVicfdni)dž6>K53r.-i᧏9R+s>L\+YEJ06DsԓZGWG"d:*~p>{i jDZ&F6+5grhMecؑ74q{CZߧBs \eL K.|j%)]͓8C^I&kLlRjAy/)e탵JL‡s-h40.4K5S:ޡ3 Q“v1}u@oɷ F ~7O" `X"kJ .FMAO ;oa[)cA@(@B1S!qG|edy@Ge;G`Ԩ71^Pd0Nt.OIGJ[{~:pmJuq]-ǮEB<=R)kPD*{0pfT5`ѤNS3r.Gc{> ruO~^.άR K[uS*qmޒRMJƷ>B{7ɖأl/(aI1^xdZ>&1+ >)[9̭1b߶cs!< ?[Y7W(6cLR0[cK< Kz1/CU̇Ψ{G|򳘞 *SR9x6z}AjKTO=* WCX\y*K?n`bNҿhKo|8j}ᤩq~i(0bL+"2"g܅;܆LV=12p*7SE|ݯ"{wjyKvC9DD*DkΪpvA%e;wI1vVnxXdB!vi.ae6ObO3u=ѸuFg%uب,K4b֚{Fry8ƇۗeEvX0Nje~FȨ!y;IwE1Q,$?MWaZPBqaY)&AlVNo׏x"T~ +۫Xu .kU~*m]|{z:n9?N^DtQ,67HTcf]ݑ! \&p'cNuɁ; b ̘ u5:PL㾺(UKTӲ+$_8u;QVBKp?-a=DVy$sn/}h2a][SqD][қ61 AN=ɫ]0zV2&y´s.0caˤg)Z98S_9!%,_\S+yؠҾ>,=3hT9r8/":N q/[e&0;9-( vF:'nXnNc<+KR%EWD=3UXgà+?-YJȬYC|ţHT܅CEQW .qMo&c~ hv%I^4%Bg !J&2 ֣gY*듴s<ϪcˏgSdP&U 2ڶa0Ʊh5so"?49 N =d߾>T|W`ɩ ". p697)}\ơR:͢IwuD2l9eYEp0^Flk=TQP!0Sgz7눁A&)䃕a+Dmذꎑ;Þ3_9QLV'zZ0^xg׵2H6 Wd6)QC1_j<~o2k;Y|\<崊IYf* fo'E-.dC&E* ~ڤº^]mw홁_c.^ - %`bP&cb,G?JmF27 =hap.Hv rYö ^"P|%cCNBW)]{B>)xt-9(-3 I ,#AOkN%cIy5/ZӸmqk~lJ|8op̑ iܺ][P_8_L,܍sB;hdi*C[N)=܏r{ AϒHn#ydBPWdݢ=FW[XVh]b :܈o"Wʨ_z 83oJ&x? d8.;,u0+/)?Lvo}0wm XD o<0+@NF$S$W~ӷ)N[6 jXlgʸ3fҗ,\(jF&&j!Z֝?a[īB=GN2 "DjYP-&gLM{x !dCaZ*k10c_û <1dMB!^a|ʏgQP=aqҾm uWnM2ΞY L|)1PD.p6*UpX"pفM<59G͌K.)E6ULn+%}·G8ZMQ-J"S\kz½@&!Ga`OI9\,&iI!#2>0ݸaX\`X֥>%h3Ƿ'ʬʱ#7vr:U~J[˱GeJ{߂{ƪCinUF7 Gzun8S;G;`͡n%?@s("%4:_/\HJG?z=#yeSz@=R%M`>wϩNȣ0bSf?r{ЇEPApD5'8:Q|w/9J*CAf~sNqdCzlÒ߷#ľegRWY&IkUmd-Ik\U7ORCulIoõc%t7Ӏ uy2M KC囯ǪƄv*~$\>SeB/:oZ? O(Ia0DWOkM TU3Kp݂Oa3r~A"0q+,v+N_t9x{|=q1z9C=q  YT,J`f"-˗o\}7).$I]X VR1-MZU5E5x^y٤0ngO {62\ul=ӛjdif:Dn TH ēKkQ}Avi<Q)+8o* }XO\m2%)ypӋҒϘb saXw/Mbq8]w.AB  гu1л4$W+tƉ*e  뚐.BA։.WLJjlh6GtL2.W^MCI{%# ENyڝ^W, tҾwϒ2$|'¹uFr7i#Rќ{l]8m32gC4ʐz'Ue?t49ײlraG8uP]*˗w`cZrW֊ےrC, f eVSNW䟩5ŠyXQ7I ˢ5_Q=l(3[B0|5Ѡ>EtvEMO]5)Pv6V <6.2RH\fA"tTOvĠIv1lx|h`gS}ڱP՟1g@P{X *UT;hW<;ѫE&\cpٸb`U7 wX h4k|IMyIZZ7c!-$2EsSxhp0;'-9 /l.;>.ۦ?TVX?GYWJ!hxB!hez5…CN{_ 9N6ۺBTzf2Hf &s6t@-A"i Mr@$J!&D~OMZGv*fO$1hCx% ;p4ٲLW+ Ԥ{ᩌCqi[ ۞nea|Gf-.( %i=;RiVvJ؝[DM@5_ڸs)RAEx o|4C.gd;^|SKtL*4>:vPֶFuqϼ+Wzv`)"fA;8<+yYXJUù"|-I3㶽re}ZzŗKRlm snB[a]֢ω2Amg8*B0kgdYY'I0Nj\gd(5iZqq#Z,8 2d1Z/i} cىj%=B/Eo4ΗI7sA}iy&K[&C7A#όg.v>6* k۰(~bFh2~ѿڌvZf߾^=q1&9&R@5riV!94&!I^|ќQ٨*;H, lJqF% 5=֌]Lr| iZViYpdS@e01v-ո'kmɞ7q;뇸"GNOx?6}Kw"w^?vl|9<nk!7t:KS 'a³t$7/%lRb5( -2؞i)E;4O˦3\1{wYLfGJf˚/$MN"[Ef y?w/-.#3[3.]%tɖ?\ ߇ZNVjNB<͕v VouwVE(`DJOe-?RY#w7sX۱K`LQl~4=M/7 0=>n~t|t1+yY<Vmu\Znt^g0R:yJZ'Ol=.;x*$ȘV2E*VkryȋX%R|KB?m_sD)"1@]bScܱك~^)vц't) ]4H!/)GGsS)E#}C=d`. KntrSіI:6iҹcHE5V+W=/?>As<75/)UQ\^U'h\!ݰdr\bzP,?@o8[qTh!ORXਰW, dáJ pH45)Յ- l>.iUˠvȑ±P<Nm1JJ>=*M*kNGĀ7l2b939H$>+`|k$C=hf~L~![s`_R})ngA: z?.sio~橦I2@Ԉ^;?Zy_\9 (ZU<pہ3tؗm2-5hLS4rG#P"0_\{jYn5>'1Q,CZu@=U5XW)jS恝@^9oT9Ds-DMKq_EA$8.lr}P#.)Y<ָ'?ⴚk%uDG6j&S=)-%[Xm״]$UmO8pzSr6b~+PVBhb.%e8~=Mo&seEpx`18^ O1PZӌ$|!?֒?eښ>s:sV iXpXwY#d${͢suDrwLc)YH{ËKj)m: IN'mSD[^KOr#J5[HI- C-Jxq/F`}2M% $h B5X)q)3{7nӷFgmڞ"e >25?b||F :db)''6WL<;AukEeAx4ybW$y!:lLC:Edy!|ż vt GnM? 7V,8trCKt+51񟯱XX4=d]v:u*J0\6aP߬2u<%/ܣ#4v;ᏬWj6aڑCFm.60;m 8H=LaZ!@/ 3emM/8:y.EX8b~׹Ϥ_H_'R`,(&&; @C"Sp(yӰE> #TiSPz8C3F. %a}9E;"e"8Wԗ '+18&; #qQ}cFZmoOژG7oB+<2:re XINHt` RniaH}w4_Yir·akzX?̓XKmK#gtBUTwQL:7O>Ь{~.g[ #6PBHy<FSe@`Ä0jA5tk [HzsMYl(?7pCyJʾ?fIOaB::QĄ8x[]vExaKu%"Fh?ҁ ]lvTJGd=$P00X u-L nVO1ْSѭp/2L:pD8(Uy=#N!n tj6C g6m3*箖wh ! Y|+BXĝ$f+=wh;v-3j2W@mJ0ߜ-RͶ ~縧?16\\:z8$qʇ*},:4}`Cto _ЩwqsEJ0;$OK N6=[[eʷU>Z*nZ o)f{H73]D˚\."wۓޫn; 0<^~bw-! :)Ua<7Ms&zUgfmC&O :OJ vM=.2O4#LtY!e2# f޺^v4:U7Ɂ#((H9tu=揰oXV3r r|4kΡ73{0rĊHlj(9EMʕ,4,mDOTo <8(Uwd/pew`VۨwʛG@\*蘘ƅho$e2# fV3Fsb9Ƈ`{!ihrq+.=|'5q&;|<ȬHzKMx6~; dY93}xmϮr)=3'[N GGwM%1ZEQq6q318O&+*n: CR]@%7cJ>ga;g}{\)RA/-DE B=ݑZ($bjSvv-_DG zgVDM0-5$wT_csHIk/yGꪵ[EGp[Bks揍Ľ3?UWQG潋D~P@DK ~'y/NwEhU/ۑvxA .<Cr"qUdd!UD!Vϱ]Rha݉r鉸 eenp"bt s1G;78\TUkhA%Glf5> ,w^N'_.߫ȑ. 漞eUU?%y\ Jf0CVf@%\,ck{XA{ Ӯn&%Mu]z?=Rت5]I| W^I1s~VfX +RC6w7B6kT,IcCfͿ<EGC 6mW#[Y?Voe>򒊲u|5rLdK.=e=:jY,Lڪ6S2 rj&ƥ`seg(E@:M̉-( vD+XP (s}y ٨H^  +P=1`yd1{wܲwI ESFW6.?B-S~ 7 ROvekP\,*PWwm6?h, ez'5b򄖮,m*4 /Y7mĊ'k}P/Zgvv\n n!%GXxGCL.vQ$DDLXZ^Fښ$,wWdl;3!!nfI@l"@bN벜BW/rzú WdRw.$5F4n aqwXѓ|8 ^ p xnOnpcoXݱ]eQs<3mzom@a1Yu-bL_5A)ҞD !L2m0etz|Izgl|QmYz/P? =jB{?|W8NoQF$Ġy:qOy{&gvߍ<. խ\ cVO%ۮ~aKbF,Zjbo(cslN@,)^ր* .xEb7<9XHy wݮr* 1u+с0Vn%Y4򱺪ΦHAm7+Q0ӷO?uFJz%&+Y,u?:/^3[KOnd^rhx KbM]Ms 6X(D4o,l~aٓ?0_ ZMxeP$v.h m ]-*ҲJvH KyKTn$؇ iWY0CW&eۨ-O}qkq)aKPh8,vdD"7bF~k2bN-cAAQdghmy{k9Cg| y#M9kFq]߷llZAM#> BF.ľEN*QUO-}FQ1ֆ_&ݏ8NxZpvN9Zf5}pa۪T%=C#/~@6!~O  IUê71/OMsMu_ʏ5rƷClD\p!s*Eh>=A@g2z9t;cEɖ7(&tςuF/3Dϭԫ"$؃f"rզ 7zxwqN)=iFd`痢#< djp/|B@"<HÂ`1ɳ@1)pUM0l|#d=nU@ lVÜrĄN9aQ+fZ%!*6p7 9ּbAB_+֟HI NU@ruX+.6|#X)Fv*Q37J#0d-`wt|D-Hij0+~v~ާB[~iS2I^7ym1#jOYkLXr9/qUn8 cg s'{2On8^Q&|!5bc>7]q=m)|tbMdX9?ÊQ^c;8:pc}񩁇j\yx#]To{Lȅ~"C R/7w;r{poݍ6(cpRK(ͳoDNxF|VKPt[`ă%YŒW0}tmdnKxM_CY{( 8a1&* ʻoH] x*\13([jѤf|ɡҙ{Fo-9o؄=O>$b~( shgS.hHo~עLX Ă iƛodPlU,Y):}JZцȷ'E~:T=PS2DBt8+"UBS"XuHJ0{NA1^0ת yި c򏨱#tZb:S`Un&EpUz4vN5΄iйxI4qHUđ qxUjR|]?o`x x VT yg4TelL/I_i1 endstream endobj 162 0 obj << /Length1 2075 /Length2 15997 /Length3 0 /Length 17320 /Filter /FlateDecode >> stream xڴeT[5 ww)%Hpw)$@Npww\r>}tEI(jfg932TlAlmLlL,,@cg+;3l P4u~OuS `P:yY4%;'gFcw7daҾ{8ZYX:ҟl1&deR`|s{7Zh@9JUՕTi 9qU5ui'5IP ߂I{tI5Q5m%IV?k\NV7wf;@clddhdo?5K+'5hk0. q:[UϦL '$)9mGnwA8ip_m,ʕWR[ c{//Ќ_qG?=rOS{_1eځU0agϬ@D?}TUcQ}: &gw翢pXy9,"ھv3> 999z0?ٹ_\AV.nft%v叙} >^vsc'9pvtx`fe.W s;L? uPiO`4gd.rdl ߑoGO&YOv6rr)Y9Zk(`d`babGϱyd {ss] /}C}0K(KKH+?+Ldjgfqr=Y b}׶/@v){g#]01Y#6߈,70ySq5xY:#n{c[wIÿ,)Ձfs+W?,9Wdao #fl7d}\vCR[.;N/潗?˿on= o(5XUVfoQ0vvrey?ͬ_ (-&f `dsf&ykML?6JNCQ2Tb iC.eLJm3e}@ZX6k-IU7f"ƾ ȒLꁙ d%ә#qhohW)dz孫Pn_gY0mQ;';0c{Ef BGe{0+ ,х`x cxzujrVo~TcG9_v?h.`Ѓ>Qҷ)fzנO~DV[H` ^z=֌a&*k*=Wv0vsKCUDn)i0R? 'BXn^(Ԍ/;8jWLrU:|[j.Y:( ޿swn@dy* C@+h‡w3ߪw]3(ղ?>\?Q wנt(2F9!X &+',ۅ&WL7)~~oX9r̖-3"T}@yҙsƛ-1G ևA!ٟg=[ sT%((O@M8f$>(^4>YiW$Iܼxt *.5cRCYk,QmKJ-#Zn"y]l\960gְ$I3 [OU 67S) (拳{yfAea7/21'v-%mku'9XzwCњGSهtĻ^#3YkW^5,j%"}qo*anUxUjSɜ\E X=n?4VԸ ițîpp(1 ]YI(n> @3D8 =*`!=𛈿}YI~clV:/n@Wˡ*Wydac3V/H[opu3Toty=3!q )l2=FuGr'4qFT$Ɓ<6)*4:ޮb"NkZ_/[,#r iuq&VͪL#v'ihd^n0ȀR6|enS1&}5_w:?~=p_ m-uCA|)eUF c?u5Iᮭx9L&CC KP|Zݪّ>f/ D)6;=p:>kՄYbdyUm?+(9xY8ҩޮV=\|5~1uEgi>?1*`Du~1=Y{k`N癈" w4+)7#Dj 5|ّ%*J1:K&@2oqc61_|h (Yp-Vf`vn`͏U41>+T e Z`[&:=rvvD$\ ֫Gh1 Bc,S)~sD3+do'zQZx*s0>n 3ΒrF[o"*|96NA PJȈ/Z~ѺBB)a;b;Q4~dLƖ6O+dbg; Va&)5)UMxPvn_Ԇk~r$ziD>8IsP Ų+ܬTxW`9˹!L9iIf9{ނ mT@}u.#~ҥ&nbyT GNb2C͎nAF.im=uRS+U}.o b`Gxߛ*z~φJZ->:Jv[VR|Ԑߓ*,{~| $9+AKy50ަo^6ŷ3b>"Rbڲ{DTW#HFI2M$Tr3A "pG#F] S$#rwO4UcBf!Z eR[J\j0Nss)[xy`]cXդ''Å.Oӡ=nԹ_c>.`Öin\ e&2網c-[Qqbdq6$PW $S9o<|Eq{Eޔ=P1Q_dcV<:,> oc dhm9:4o>r-Up|Cι7ec5$"W~Em|DXe8Wb惕P9w=21WrN 3(Y&g~aLpZ昞NN) 9l}{{+sC/g$:n`ezohpQ)(aaMO5!ֹ aKgd:6b9A~j}~y${[+q lȠR> <CI0sUK7]c OңQч Cl3yBWFax9O~|g,{ 8heqЙhhl\Kb[2sSߢy028,Y9n/(5SJuRrOF. ֶ#`wlU{gR+S:n?ٔ+)2WjS+z0zMOՙt 䝿-1H2{4E``on9WG(e8O_!?)@"e`OS+gl2\^C9 >xtR^_Jw'eSxi9SZ}gmyH]+6i`zFiR*Z-!1hkQߑ}1|XW4˩CR='ӕ`C?@: {kS̅^wLݻrqk#`Q^~ @3y1KcL/;hNCO>%\Ÿ?i>NCCGN_Ycs 5tɦZ5\6PF}CO͓%sW[jjGء' V"%vggsaةJ$X)ڞҊSw%Kr`g* `uo$AkR8Ni\Ƨ̹@r4u|1A8>Yee?7u<{]EԠZ>]R9`;PO7\w0co΂ڡ}j>"[Ӗnioo n+F21Gʓ$[R;Q[ô8kz,`к2<++Ct?ho2: "~Lbq? $vk|;y֙$0?4E os݇6@fՓ6O{-1QV- vQg7fxM ƈ *keI`%֫%M?SOptz](kyVloJ_f|7PD\M%%xD_#OKR;HXZԛHq:69~KȯDs_V\ :x*D՗|6Mij}NR\j^_ZڷRMQ63zdU`Frbk\[V%%E~a}ZBC" cAώXKS[]>n#ܑ[9HQ>}^U d} ;(h[YnkͣnG}^d2D!21'|ta#C܃0Rս'kCYnTE4YY9ŜCZGR78@LGl5ABG8 {Aê@Q^As5ncueLн Cf2Ƃ<6Xaz(Vs|#GNl„P B}y An⟓o:(&Suvyԕ7xg誟M~#KV:&r+R 8g WBR/OSA:kmMSp޴R5.Pf:ʙphfF_Q̾u yMOGDѬ+]rQ~`{&`@˚;zp)-[]F10ēJ̣EsD0.znjExw(;iep7mڙ7U{ƻԍbpf(`cϤ}SG Lmη",9%i\f}dRVے*Xfg TԄY)\`)C2F+_ X> ԛpސ̈B3E[6(u-Ȑ'zC<uf2 5gV yuj~!UJVi߳.5DgI -~2撂Fh'ȐtzŅ¢ƖA n([gw|Z7I[wڲvl to[c?! u>CNVZi>sgT\5*x`jnJ,c?U"JXࣧH'o@xAA@ -p2>J|nτtx C,QC<ӫ™̏aej.Q lfXærU֟P-mm#tPMz33VlgXr1ҪB͓k7hI! xJn>>!.1ןk]c1ƌ 6B.C4.W&.N[MW{oچTǐ!G)0xiAa Y;Lq+a)_pP&/J|1JW1l*g0vA5 QstkZ2~c}R[yoM5%fLiޒ&AF wu+j XHu"=m-tH BB, }ڪ{ I\TH`ז 3rk_WNrz hʶ 8Il(hm,j\²,=Z {dT_rfIcFy/ӳoCT5A5ԤFyًPEMIC%ʝ׎Bh`rgn {&T1K$1{,s7Gn}橯=u"!/:Kݖd&{M$aƪޘyisx`uТI44[OMz=*n7 >iw G1ǹ@rUoWT³52 8GNi8z5>@G)A+.WNHU$ɑ/oJt76sН>rJ2}5EqTLOF=ͭ@K)8#%ـ7 =α~[yC+* 򤀨[ٱgta(N8mғ_.w]Bq6HCPB#ӱ 6qˠeٸ16tfԺ0jZJLeS39@eC.ET6dӇ1qx7ieDMyY2/ uxz5oɓTu8OSw"-K[0²S<~<(믷|+eNKM;.+(70UʄK =-: yXjvh* 9 \׌m+C=]n.x0)99B,GNE_0zReMѕHlE b߿jQ}*P!൛#cͥYܔs(|yE=sAN gifTw_qy"c"ؓЇxLC1QAT*MrjOmLmtgGwËLj}D+{fFث!M&s{g*gvxTA.nS@w `ӏyXuD^6={ YDe^ Diw=LB:'b)@I9ߍcEBlX?~a8M_JPPAN1cXm&дH_\BoF*3Ԟܾ 2b\f\$`LJ :=#c)?882QR(Lm||2:LԮI^PWqNlA-CI!UVܢoE3d90 s~ڌ[oD0?wcĪJ=s&hrg*IZL Geq1{ ^HǪϻ ?=!5icK.Y-EP? ain(\=tZi\К}CVSR BrsUQpSn(MA;q_!]af] pX HRjK ]o-G4P_RK50RrM 攠)U) LQܖ9=!kݰhyxL34d|+y-s}b#țeh!vXz vɤ2#?3{4x2~RA[R8Nu)fq e2ҩdEW/%8 trfbebbGXJ]r7ꯦ_3ܩϣ5ڀ~fȝGÜd~C]?.K%HgpL*ȗ~$"r+.$6[\n( {<'dUb=6fUd J]wWyŗb\ѐ2+o,ў)ݟ@mV!J0 Q-5>ٮN|Pʶ> }5B_(l$JlWNy*e`w!r}Y_{ԡSoDV{ZpM_;ԒC܁Nq1_bYù'i3h~3䊏 8(Pɘj!tf#rl\bThR "K\(2"+C<fɐ}UbMVsDi_a C9Q#TQ4h-{pU5.1Նה$vhHp5a -]/&{Envw#}> k.^GOMyU k 7dUT׳ +"DPPuX:Ϟygû^>oɧ<9,N' pt w8?Nq|7[9(e2)jc{s6\6ZTC b&Oy~ f}QeP/r0&a}ʀ ҋ4G#ǔ,F<2{!ݹLq\TٯG@ߛ ȶi* o(e3@y1rO+IJmh̊!{-;ER₃0{јew:7S sv7zQF `E8PJd*2._h{__R"~N8~0h 0)#'I1PɺEO)9ϑbR4 揩VŴi5p\5S5 XļӤOk1_ j?q4Ubd[ZI{6ϟdM*./?~D ׍ ,P t$ȥ½i(ڔܛrYVc\*pQcHH{oŸ{1ևANIg?~\lߴK -ι5k⁀uYx6GT!/2=$yAOި9ket>ey܆:L^R r.P_^ m741F:"2-iqh8ɤg9]S,t+A3gCNZͷiq. (Ul,C> ޮۑJU ZK'\<¨]>x + cR,}31;4.IQi! p٫ cvw?1^Hr!GNm[we`'h:d#^kz"G#[[ 杕(#@Qnz0+wvàqS.`#,ݪWEHg\v:UK^!İ5P {݂&sP 柑VnIoߥcc]SɘۀE/1*TgrI>ZOiFQW1Zۮ[%D_oLme9ZܓO}`)~kIᲖ`bf7_Po=lwG0E~ܟ\ Hp4Oy 6)CNG8 UCnsc(8緗vh(P%VG\5m:ȭp4+9-rm^1&ISIr,SP$!h4H BbD`;Rdktj_B|?7J(uh?'oFTZoIE_k9M6@UXS)\:]$ӗ=O;؏DəhaN|ydd&C;]]>;8B 13(yAW2?:GO?XI 4_]lUKu$F߹T7^Le%PBd+w~\_2!oX EyȘ\ r{Nn+?ƅ[.<}wuz7zEIeJyfW lfSUW(Ci`5M6y^rO1 aXTAV橂.!o6Y>~;8?P>wyf~ fFH3R㘢9: }@6 ϥbUPwh%00jlXAʹ g@Ma|3 50Rp̈/@wi OSvMgLEUqCL W4q]62Xﮑl 8ε-  Ge֒)~$RtV+@-PL?}@ Wbێm"3 t@l= ZmM%>;;}b)i@2/ bBZhm9\^uM1;Kp=Ά_ѠVyD%"RVkhTB 3[l,ˈѠ\Vg2_Mx,帟.b8 0Ӧz")v6A-wjn,"BzCɍ XHg\ܽek?r=SnLB .BfS r)7n>*E <B?li-9 /8`f!n'#l;$ rH\,MOMz&g/3JWEG)Dg8Tb" (84QD61 zH L9 n4*LP{5SDʯ9tidKUB˸\DDzEM:D(-P^5Gz^>4)}˾:t3d"ש{E>cE˪uN"Z򄓽2dס#L|`j(Ptt-] ~HKo6DX; ѱoف-=FDy_璇+I}&35QDt5@MkE?[Q"|B1I.X@Gy:^O $ ca2[tMj׸鸝t7z3"$!VϦ/DO7ԝ\/hne%NB36z6iGo7?߈,d8ocF^,:ZO0ŏψn {z- Pgoح/a`N\K+NvH@Ŀ TХ-Į ,?NC&xA3 hEDoW5f*2N~dSb elEfrUC9.)38⨊ï`ƦIP=z2*DĚ<4(Rb#pQBX92bW2ٯuSBq#=e6Yܺ鄤- - &GHaO^ͲZ|}<г{CcQ 56#A- 2RLV}j+ݯQ+HvGJ5JЖ+HH g/$8nv ‚/S-85kQ> y[1P*}ʷ2~v| v4΄Bk%C`caUˍsygU7+?dMKզ'T8x, Piex1cμ ޠ>@²wt}x,Yqf5.kk қ۠Cې, LR7Ѝ)2z/,; C. ֺHM Ow[.IМ9oVR@220Y?_+$rg6ic~ܧUcF.A$)+Ik(IٱQ,!j᳉ݭ6Acs&=LQsA􋚃[8T=dŕTZ%Yn!wXz3.Iݵ^JN(aRDB's!C"kgz&e] G}A;\م 77`ct-(>t`DiJRYZ ֐O:ݒ6= m*蔘ו3V_imV4c~-skO:'0d"g9i҆W\A/mL@^49INdQjrk\ϯAvɼs&O|w<Oec<7^zY/1 ۥ[oLӸP:źHC& V-xf>wy-G.SY8:#T7۱eC3G?7Z52JYc4:+4q#c^ jIzƶgQY}jTy&~`m'an9x0t)N³g Eʨ-ڠ`Cs(=JeRq{FƹMLAFΨ9q/bNSqU"Td# "zKѰlG_`fdX_ĒoXs TMZͪ+)Z!)/Ppo? ЊvQ3t|W'X,k3g g^}]1.}T 2虬aڨ?tY5:Kh?y) |9' ss{eXb˭x3~d1,zL 2g.jNyT(-E`<*k4m:a&1smK:yGr$ٜυ3]=)9TAPSwiߚWkpea2veyL7{XmO1EhƨW.3zb^F>a]˱=d,p &ρ,*%;+VL0 -\$b2^.bdO2HɂSVg47CY|:;%_Qy00`\);<2;f*)(YFs <{h0r$ڭ꜋`x8D\lsm`gS whC-SQ=3JVljX΃ Ŵ&1pSC9*s~AydO}.lYNCwhBnIxP#Bw1)2(`Lh+ylX{$|t?H"f,C"U06>Nwĺ aN˕![̾Ewo4!<@9iDL6dx&0m0[- KT{뽫9ʚdbRλ=4Y%@J/ϿuU6cB VƊ8 Ɋz;)0P"Q=F[;}|ܪ1ty؇_4M<Ŭw!"P\Vl1b $)܊*XKn?HF5\ZClI^Oe=\ E_>*֛3ɑ3U8}Q>URx⍠gXɐk?yDTm']0;ݹ endstream endobj 164 0 obj << /Length1 2005 /Length2 24915 /Length3 0 /Length 26103 /Filter /FlateDecode >> stream xڴeT[5Cp)  ww;%[pGN}o\kj`ҟlaz M/Ks0Z(lF@sCkS)@PUSRH(ɫ*(S,booZDUT%hBr*b-@BUY_ь ']VLEHESALWF oiv6(͝\ҧbnps|:p6c?0:$iQʏ}Ϛ8AcnW hkhkl0 4@ @?]taX{ں8y6mc;[' 'gZXwsfdŔUd>ZΖN:EYOHT `fb0~͇j'?7ljakb&. .@) 0ft09z叙>^vSCk')pvtx`baWեlM\0( Jq;Ml=&@S89;v *a6_1?b)G;D",lBf#ˤ*Yܱ3tL,hGc+[/DȈ|+J 0tt4cf66G;jG `j( L@#!' A_gogo`0bbd0 2ӿAV ooߐooooofw7!ߐC Ÿץfw3_X nalYCgG wmƏaA@alaa;w/:V6VG59XXc45 >\@c;c 䦐R_2H2. L~ 8崩xآ9;$@v2ܺEdA6ZWNޚ( ! eѫ.}-$:,fIok#pzfxGN")k[˅t+cjpFs_B[u~ˆ2Z5 BѢISL[|((тV3ӉI>޺z\10r%<+Oz=G7*~Tag'9*-+X`ɿؿn ;`^2qUY-&r ;ydfp F VԜ3w8G;xV.mXH|Ӟ޼Ͼ-yf_Son5޽ '$ DmGvtO-Bq7.^tebKU%o 2<1ɋ ROz$ {G̴B-v,"Q: \کs&`9&Pk)e nFMcZ=38svQ%D2q!-RNX>|eNP=<"/{bgV *Uŏ#e Xc?lRuU/&,JCP=Y2j_.({')}}V#mV#&?ןUT3PQ{cl 3hm-nǥ|K~/46i22ii_9[JSҎYA>,Pz~#֠]G nKk)-U .HJvx۷(궛N`b|ArRJ)t#4Of-  ,dR+e0Ec;|]Ԥ ^ k9 ӣF|U+Gmdw 3SFQڏ8{p5{ի+FGԆ>H˺}1٪-/D'fTc~Y KΣ2J-TfJq$,R?fS>Np_קZǗ8ň?k',+ eUYQr=7]A_!ĪGl[Me#Ajg{f($L>fWX77ݑa%Rv4ݺae{quߕj`QQ<}-0>8| <R#XWQc'}ܡt r@ dvЅw4Q®3_L*YqKB|m4e#9  Bۦ4SVP(3KBҹ'ӊ!p5Ytʓs_(ٷW ˰>B~'Znő8d͹g XVS,Kyx+6WٹĻmmOl3YU66cGl.G,JA 2PneFO*yy4< w)dG!_4бQC@oL Ư Vn}Gʗoj c\C=eb"xvQx(Dv Qrׇȿ2j9r;:h~tn&y OtKp2 4zp\&g<kڣg2\l)1)\v` 5( 8iW(bdLmC?~c1ېmFGkZ'/хUܪCjG J\sdIukۘo=:% (rij8Ы&ClrHfVnA<@KfU.萴| {trF#FO}Kk+ƐpuEbmDL--twEa_z-E"e6H2hmMU+{y)& '4QAU;HOaƅLI,G#dFzSx?" 6PZ_ jهe[av4Ǡ4oH6[Ӂ͐0o5ަǷ@oJœ5[*26Eϛ!e"A!T7OGTP0 =p׶{ #"~8H4ʒI7(yG>tX6u#W0Dk7 Y!} ЀioI<ͧg3 MuC~ Tu#qxQ+\O?uX=jg ~Le U1ܱFNI~{^hbSز"YW-da`P p0RsP纬tVTy hfXa``,)b/JQ汙]-˵1sj?W|t)sLj!hĐ }6ib%L~Mn&S2Khv(ѦoFjM(kc>L1ނga24ˮqӾzjz]$P3*d0%WĎ6-% )zFP(}ı6"%.ݫqnUK:)Ɖu(á&#RO qU콣aEt{pBo̳/Sn.mZ"/եɮ/;qG*Y@p`6G0} z6rE~%W8=nQkP\$$g<veȯ윾DH#(sCؠWѴP~}=8뽜4LQ",GeL[_} _v #YO,pU\1p@t]kQhev 8($^ghRTO21K?W!/}(j.w6]h)'mn !̺]sjYMf'V)+Ok"ybxԡ`7UaQEfncB71ɵrQ=Y5Y|]}3npFХXl-94(vH(j fݏ*C$Y gzlW,=Pdϫf*8[3:aLV蜗h:t|,19gKЏJq9)eL]zƖaz=Z yא0zC,T(D5t j 8Q7<}0Y âo4Kz/[1m{yNZKð} !ccؖjE89Z4%v KQGD$ߓ|nWi`IT b W 0Rpny_p0B*" x 0.M,F%Qׯuo-ڜ>mcWmxn, (\JhMz. K rhV -Iu|?i6−EYV97"Cgrp (œ @ efߐa19of|8N3Pu+Z%.D)ʵGdX? 9=*P㛱L+hd:l>ں{"_P.XQT v6OZ.LWDp AϨu`hYp`vͼropR}\Vuqi⬌HYܶn Ӣ6vkLTpwI8YQ1V$/:@qEuz 1fOsҢY{8 ϋGz*J&jW!,bh6"mkvF#qD{|ش&kcXqۑV݋v1C-θ7^y Npp^pԒ7Axn#',`LJ:}C.b_-{ugy`2x6]3fdƴ͠pX32wCkA}aݚh=8^Q %e%k>rq tב KlƫRxp]{`̥ƭ]_y_櫍i^H~6vXR@veOCi ~#eSCg#9 qj#JC_+Oyd,(YAN@Dyfk/M^ Ѯ(㸩h/)&Gt2Vb%zݟ$ih0}˚y4QG}C4IȋZvq(3+=p 'k'Ђɒ\y6ϴahA^ym.| {74c%jYA)]+"}SXU_`~s\ss>籪/nS+O{l^@-ahR&bŦK, ,ve A]\qrT|CC;Dx{1c*/E3R1&L"=F!^m C<_Ƴ,ݒջq}z; nNKa= f9V Fyrch^Txy"Z 3ͱqgshmTdzGGՠɇ^V3o-9ab=r-ӓmG|6c{60tywdF:V`DHَel߫U*i$Nw#}gHʂ[Ӟ1Hmc>pLFg;aZWa pws{Пg)ޑ%tVRH"IwB.v'̍h[ޢ`k$ yݳ*mmtY ASy)F:ȵPJ@XHKY>ܗRwrr O$o]%PҳctᇤA yVA~|ltq?a*ō AJ!|۲wQ^ 326-*+7He%pHQ7ݙC7:쀏 Y~\7@j$96ZvX2Bu(~5~^j,0;זWN՚n@(=|^$T4Qe:(KNp3(Ȣ2q m(FoJeL:LXp3 ) &W2c#kdױƲd~h}2c!"a=y%kn V7!%>)^Mܔt|}qqĭF*@ݮUO֣ny,b#=yQZ̲Lm  Y]H8buJs@c)m<9ɮ +# Bo.P$~[D A4!oI糄yaGbaϛwrGPѐތ رMa*]1UJxE\gu=U-%?L[$ WBk/آ߾:{H{kb%J~5x5#hɇ%㽐Ēö!lȅ'?N]6| 0d4p-@T!X.cA5Kΐ[<$w$ݳMJK1mT[ìL.WD$`UU?M$9y@%g MbKMqƀUC+3^B7ʢ-mwUݙ!KyO<#x+A Apr#\ ~RޖtB3aŗ4~$qta%zF:yAEIF*z2ȍ, _?Q]QZ8 x{wԗ݌LNɲ,o/4㖩u - n]Vr jع|GbYx&Ǖ$-1hMjxc[Ͼk:Ar`⏣mALxxB#1:TTC#POz\̍J{bD)MG ȼz.6J $W2򿔬!X?5j̯aAZ,ۺXym^͈MIY ԣ r+m[x)""ٿoXTЊ~>,>:JTvCZ{%"N{rI1 _Ld ӛaU(ەZKft7*|.m9eQ7Vts! {w&ּ zjYgЃli4579m3,I ꫱aӋpA~ԷxoCK'r)X4aSSKgU%ڈT!&^z#įM'D]9N"!ԗ >ڰqẂ :`mcB#N퀥@Y7{)MzlNc|s]ACy3/=B!Eο0DrD*)z|g0.V?zF1a IȃB*Z.QT \ p#MVơs/Mf48*X'OUQʕr++l)[شM#ȊDZu'/Ϊy}IEWL:G6Q/o ͽz%ߵeFtmf3 c] E#P_|j"qڮ~Eǚu!n|yQ]]ich >݃ bf[^hQsxLm;׳wSGB] jrkEL2jjWT6ԭgo&LhXm: uᯟvx uY zZ9ˇFK \F*7{C8M1:RZJ?*0AvaVBy൘QzJJ8*O1l%mݏs &G\0l^)MZ2~͉0eMH'#XiSdAtG ѼsTپ*voFD;=Z`J\*ެXF\7m~xsiDfM4-1i!,fatŘ5Zƀez{g6[HI#XA}D{#]3o1%&/G0ز;#KlФ-yX%ٲcCaT-'9^p^!P2EOgQ"d4j1Ǝ?3t kelajF*;U!lLL 4 &cq %w;f~mHߓѶ- ?(LZ@VNHI'h;+r*/n/%YBZH$ 3G~.I8!_P|a4@-;]v(I/6b6MH&0,HܕiFlSEw.bX*,vktZEVfw5Roub-1Mwt${Mp S`عjRyGy\bŠx8y#~elj~iS}4͌Zu"#MˋP:sHhP;WE`9C&/ibV\2F۹mSNg?~KR[Ŀ!`;:ll@+Ţ60t9{5:Yxk˙{0N-zuXGDJڊU7}gS9{cZ04|tF:0se)selD)Z`^mcǟi,M~{ zȶd[rM3OR'䡽a5|[ !,0v&ILed!o(;g1xfAH7%ɷHuw"y%*2IKNҜ_ë*9^[~ Lk?;4ZX/R1 źܫ"45߷-LnO,Z}]ڝtXl 1G'P+Ar% G R#srb rLP =+F"/[NYFX,ݞWwcL5j>q5{6TKYP72`u3ECd<QMQ,R .r&řeU3[Rtn7^3^EBui83Q8Ό͋PyE&dV]ڥf<$Q4{*ƀ+)akPv]o1?+0jy5q42z?K|aC_x?: >Bl`=.JZ> G֐#:&5lRj7N5zʠcO'։k?Nޜ-cR0Vml ,1@ $qس~zα hZVi`֦nT%,j+"wq7kI%*ȯd7u +l7u87Rcd*!΋%UUw)V\CngTCK q|, 8er,[r碫$̒7nc}tįߛ|$RB(鉪(b $ǻ$boC cFE;[!ڈM#A .CNT2)r?+Xe]h@~iC\@ RIiN1΁NX)I)bXD$*gYhsY!3Эv~ΞDFRX]x5镟drcpxesi|ziZYs%|Hz o?>1΃y.!,r37QdY q fX>ݧtp-5| :A!ؙoUK_BiӮ1>YIa\4m #~H"|U MG%)Y`pTAJNչ VXd3%.L9QuRD׷)v`o=\=54BE}@Q]:{/;pH Weܾ9%˕nTҋ Uذ>H$|}<.ͤ45k#zRA 61EH,-el{$L^-f!êԞ #EGZ) Aױ1EDzISl}nOYIS\ʱD1yYMsGizoo˾eMߩI6`ʹsu=(gLaɨJ;M g%?j< &H:[*C|?N#w;=`eq̚8XۀF;l2&En - ) H? n=  ޏ^d5Jm|x?u&mw_[ s]9Tv|ê ._X WTN!ZZ2bK@G &V &,O!=~h1Uߝp cix{ 8ת}4ґyYX%U}%Y7Y'0 9n6{X@ԱeR5NE^lh,? g&!jɨCm§=ƝsVw_-Q:%4$㓓}r֋(,kqܴwkj%*LowW%6o9` %  ,'\|o RL eNz$veh"!ٲJ?@zCY3!%=X! ȹnBX_m{ xtG-]׋iR?NaLTn\`-oU1m '[Gv̽Q`6_Y{6.T_xD9%}+xZ O"{ȱ.dɠ48#:Y &ܣE<{.UD3jr`3(8M,k4H;G}R'B*VW94g*U4ʁR5D^w N4|^'ȕljK$ʻ%+jD_(t N;A"wY5\. 0+ GtW[T؋{ؖ,qw[zn0 "V 7ԙT.":0<ijaqC h;2ʜtESBv Zw,}|+[SRߦ{L]c-S7V+<ݒu޺49csÕ\qq.niB3*en9gkf쳗1W7Ј"̦NF)Ssֆu-cQvyua&BO0a4lehoX{ø7o=a4Υcac~fNa }w'zЛ[抇֐I򱙞ɘXر hu-n}`bjXgh㱾d˗ |B4a #\Bjkɐ. ;v݆tR/hAn.bnhg YD9ʅ&D<0 8:\, 2䍶^dQ4xXH'H^jrzq4, qg}詚\ӾNe6I86 OtfDJÛN"l fN/`7䒹 g-p,'ߝq*k-#kэ9jS J `?Z4z7jM`āws,,'eWD`K_j_<3V*#K#mKcS,خ$A~ְ|ɒGd`O;8[27SʠPiE:nw%lc1KBu$\Ohi=o4ě~̀q|*픡5ϥKcvړ^܎ [c\P 錺(ܬSڄFk Հn0~<`4cj|+ֶ-1ks5UjK!㵂di殤Ξ,;|8ڊk+t=NU*ׅi54aZũf[ )3FH XtRԁ),0أh[/옻LmPxX8oFš9kŃl⫫d#;9yӉ uf׈21GݯgO)obdzzpoŢfxs+?Wb7/$`ہC@- vOY̯s-dY Q&nn].7N 4.8k5d ?QbmeSNAӌ­?֨r}K {js~}i.{oljBk髡ݺi7>FH>KEg fKg#ﶌ hZ aDtRfä]pD˙j$Kz6GDI'y 4" t.u{yʋRZ2թ 8@6dRG5Dzłf/ #pr(yfQG@|NDnM EPur{ѧN/9!%ކ_Vj~*a L;xm]k>֡GQ?~ʿ; 7e Y擤T)#|s{RBD*`0(2S@HQkϿ@A).(XD:8 ǂ,:yp)d%buI=9@VrPZR ʝkٲkdUty#&[5⡘i77n$kc`(JE*Ky<>d!I_{,fn#Ǽ\̃ayԞrv+ǡg׻v\=K#YV~=u,$ _įϥrPof`;. Xn߄V GawB򞫡vA1HƝ`2Q֑4Wc * E-Q߹@[(@Š\6dgoPt)T*&f0iu=N"}Z {"gίv$עGL6$Ye4w^ci 򶭻W8}3ڡ tyVX! $dc$O?$ӺPդ†D]8nmO϶lm~rm6۶mdOvmgΧߜs]6XlFh 540 2iZ6zMkL|0'AvY?6?*cy"R݆,vyF#uRqdMWq2P2"m ǻ&}⟵t'X ,bjΔY pNnfGlb-<fgCQI"$̶,كmƙ]L͈`i_4^Bۤ=ζf uRi i Rk^3UMa"N:Խ"oƅC>auCxD+: F.I>$bl,@d9=+h"٪ti0ԈwT>Q`dIJ|pK (n[eۅ.~_DF.Κ\I,<+/DՂk?RkW+K7LQOj%3S yjݵ ϩ))x=p`ƈمYs+qw8 ;QYQyg5%9gJ-bJy YW'[q17حQ3 rCxښBkjcx JxqƒѝNAy\kР<8{z 柤i S=K1/''bPs~"OUmʀ.tK>Y7Ņ,J/Rn9Wp[Oueר['iydCǠ/UѼ_OkNBc-'Nu R4vE^β2xrQ>L|1x p|qIX**cuWi}jtT" AiN&†}piޙ-Kprxg pa'"4,jhO%!&zۭ5?PphvKƀ)iu^ow Js-+^Bs=O<1w(; ߔTd o  L=q\}Db28rrT%Oa7NSp\ +)=}8m)8 M ta^yzhS-šQ3Y峃[K~-8AU1%D⫤/yӀk.͑Sgf"VH埜*p ˅9Nd:f柉[,Ժ!L I}> ";3ҜkopiS㸙q핚<2pKG-=3:HX m^:!|SG~KH$:G uy魒qaIؘ Nc,ρ~{+$ {(Daw\H[=Uv;ɜ 3aм D+*}$չ<w(="@b,w#J[E&0{y7lh9+"Ke)5:}Xޥ̈"d=eYq}a240}<>g *zp y3Y]̉^ W8~jJgV !) t+D1}P\䍉`Cw$BnL31ӣ'?..#?6n<8S&mc i뱓Xޫd@Ȕ$c!% gCS{:F2~lU"$ـx*1ބ dW ܿMp/`V%HkU1^$Zs &(Sm>NF0&E9s c{z>h,{=l  fȕ\zqq&I[ՔZ=ރ͢Ut:Օ4 2·LBxSħ& 9sG/pfڿ[;8fe\>k&.g b]"%=Uk8_L>1KrGN?q6ׯt}0f3u gKrOFgOm":Gܓܖѻa,o垝5H$f)/On݁8B߱ ?![q:~*qa}AC$;k=F4RzlUiж-=IoVov޿ӝgĥo+#,QSX׶{T.Y˦DY:a0~Wn M")݋-l$^K҄w $粣" #@v[~Uv4NlG9t4 YǮ(M튨Q2- T^6<͝>elq^ȋV:lTFaogWf9Mȶ?!?3b™_{XIUcȡ=MR⫍gAHlZn&<.)jzNl+Bӑ iKYjtkhK}hscYGH44 UC ߡ<|{Ky%P}?(*y>cAL`*C]M`T{Ghg܆%^4+2gt!2:/ {eR sGZ4V|{wbb(Pf٠7y3}T{*B:Qhy?-hl6b5t0zB-hөfhs c G@~ %(A4uAByubuN1ag~,p0>Ur5M 5BFkfbzAF&:M}&9k6MQgB6s 懹7π9^,+ fgbp֖xX+K4i:C\9s>axlWۭfTZ9^~):mhwfU "s9~rfTzWP=VV ]n_}DcE %b]ckݠKI>N JR*\=ꃞj:N6\G*߸yR@9gC[ҕݘש8Z.d_ikRd9q4̕މG {}"ӊz`<-h V<%>X?hY`lvR~SB95r>j9 Dc] ~lK+cD[~?՝e̕ A?C*F͍&j"1' GJξn+>jU{cwluY^iG0 KmZoWD1"_(صߌ7&PXL*_|f "L=܊_!6#bz`xw  n@89u /l>VKda!vfV&W46jʾϻ.k{0g>fac#(4/vVefo^,] IZVy$yr|+=9V8'wc:/붲 ˷Խ ]Nk9i,T)+6qAmoEG1}`}m3E7@ xC7k2.niF!:Ok1/9O=UxTW*zFH̦Zb P!|  C|yL!͈~FC(ߏt{|gcKEjX˺Jo9;Rڷs`ZV藋"BAS[ĨL6✫xNd1V]{ bC[ͫ& `Бף@8,&-U#^AQZ׈әy^1~QDEշ'=BEWbZX.&@҂W/AYm1SØPo  cu6uBk=2]X_FS+ߐ+^vzP`Nv^jd#;DVW?Ԓ ۙҩ F%?mܳ ݾ E/9B_[ak*o&1`r4@+CgL2>5q3.~tu4I!t]& ڴxE5ОhdzP>;Yۯ2+AbBdZ9 g/!W3N3$Q:#u8G'-<8Ee/ff#[OP3^x +b])bK.w~:&]OR(A8V6fmu ɳee5?I JsCYebn@oz{q˗`[Z(tԼ G|۔C [!۴&vaݲW/OEg$-ƥ a1X)L ^Oja8۠+V.-e"(|(/%bYdO噭uU?~4H ɠ'I'ۧgH־ݠcr_R=n$ab(o'#tF0$PX#PoV)8ƺ>dۧND}M,c"6Bi ]u[$q_XMT' 2D_=͉mƵ WRl`ϓEEiIy!;a _X+n?'Ʀ ,kKT9YY=QYi'!y;3]]eLT:6,J <,eDb8%n$XwH]PGh.ڡ/'?)Vwt_!nuI( >K.aE'B.8`ox*L%qa}N0c1ev c3P$*(=I:C˒g8V Fpz=KGYo*n=׼neM d$ X 5 #%R6;*x-[F&i j]0nMXKiЫCOvXMKh<Y,q gpeQBO~̉e1ԖJʷ=31[m16?xa79x;/c' Q؟8V# k.^y)p ïMO-P]k/x{3l}24vN9I$ CDʎDL"VΎٻp-l!9&x-~l t5|BͦNnԇnFդXa57q40e(B 6!hΥ1& )T1y勝DO+ݑg,~!+/#7lNX >MH<6 k5߫S2ޮm;O2O 8w.!΁Yesf#|4/CSNz+ohF=)o CyH%94Gkuִ(7l#zrDzifZ!>N˿B p $^f.>=)!#}6r9ӈMXr_ |߱ə+ bD]#"?JyZ ՏrB FIU(Bfb3J}.y=S֮jr? Lhjbt-gTd6:5JH"5ݾS& A8J^S&CU#(;߉0rV{4 `*en|妧E~9a,ZXȕkIR?we pERSrUaο{dWT9=s3ZIl.ң'I*6|mr>mxV.L[lSc(.g6>1pN~q*I0Q\z0`gjβ:GA3ww a~%Li5Z=cP 7Rb ~AA9:ƐXrz(Hɯ|h}z&PQStex,.^:8>FpƒꤰC86]O:#gnrRZցɹDZ)bD\V,|VL bw5TuלdyQ;mP&Vd+7[ u{O;;ƕa=%sG.VnRy2ժWx +]`g"?l%a lm,FcZeOzA?Yr+ O~iyYA}[131XSɠRr5Y6P$!k@U:ȟ ``  5X£!DcΠھ쳒E;ζmE ݄KdiKi9]{R'?:qu;4H@}T3g$_ba]KަAJX>b' O``ס{i:"\`&qJ])*~kͧK(Y&KK=8 %85boAڼm'&JҸA=e4_{?7O1uɧ܉MX}Z#aoFmN*-pMhZpSḮT92<3 ,_K y ]2c@bJ`@!*YRH*-d P'4Dl(:i|^z&\{}wF(bq^'/LfgV K)q@=K:y,4HlTA( jqhO!2:&<=JI n[kW{ # [;+B?|-a>UMIIR);=;n:0LDxP#eNo]Wu͟BPS$Xql0]|y(Z݈I~; M& (aͲ܆h2t#gʋe| _zzOi꜕i';)-g DmBX3{[X / ݐUedPsO3H 52C(lZ'9')zY^@Z k,|oJKFj$IG =Y8PZz0ՕNbjŖ*_7W3c(PK6b*)C" b@%P e>}K8ZB4"U rA'ֿUe^Eץd*yc 70bAFRL%HvEm*_Yxkf,eg ;uk=!n]@% W7K<,y҈doNxY.=|ha;J _y0Q(U&/;1n)< Lm=/*z2 Fݔ. UF$#ȋkJrל[|vdv WT,iQ$.ͻT cZPKwOZPuDO75YY #P,U 0œ2.S,vSZrHQc'ޟ9|#( q|}#iR mݍ{ S lrWmƫ!lz 8 endstream endobj 166 0 obj << /Length1 2869 /Length2 30125 /Length3 0 /Length 31741 /Filter /FlateDecode >> stream xڴuTߺ=LJIMwt7Rҍt# {=z|rg@FL+hbguec12*\ Lt ,ddŽ@Cg ;[Cg  o JE00p“ā@G`:x;'gZ#C'hkfa {8Z;LKl!: E'Ks-v#)**)ĕU)@]8 @DPNET*Wh oFSNUTTe#dq#1J5u͍ٞəь~*N7;G+#0.& 9́*{S2@['$19m@R@v N@17t'WFAA`cha 55::8 M>   فVcc;fh6lc;[' 'gUL-;3 lrb*2cKOz"2Qd011@C*jk"lgcb[> Nvgll&..@Ìt76imfmeog05vXA?ཛྷ ]gGߎD cgР ?%mM2F⟃J :&v)<3h (9gKZHߒwDW:7W 9;GCY8YM,Q_fIgC ښYA{Ii-}shHc+[I-^NBYSJ?av&f&V6<hXY^63(z:[;gP `j{3XMBlz?@/qE N;^bЋALz?@/ ?Eq@\ #?EqQ@\ ?EqQ@\ Pw#NJ FFLFƠ{/3ut/?9m1#c#H)CfM֟PO!hтOиYU*S W_~/bj7H s{s_ _/ H?@k}A2E+-Y/J %մ+$7!dan#3=gߡl,l HD{k8)RYߌ]RdWZ8;JJψ:dl\=sDՔ /TOZ獪⟷?_Z`egG;+ +YCrf=t ;O?yseiC bT}Ƃſ?8@;~iΘeJCphd)4'I9TRdmb _:yomLĊEC_Y_\$Qojt鲋~ĔGRr5X[Z#œmQLoW:-9nh(8?p';=bDv .QcH@ѢNU8Jm," b`)R:-0J/֎w J4YI?UJXOXoL%Y!TǒȆ؊Yg'dUR#I3KPⷎ`K26@o٧#iIBS(:~e>Պ5x9f6ڰ"m!~3>0j_5d O`lCK I;,#Ym~<*RS6=Q{&.R{Ts Nd_M:- ^~tV,IFWEU,|VEKNF ɧ7a{l o.Q^p`nFI~9Kl*DUe'|4s0C%MI6U-[E Ϻ"87h#Q"`^ Ĩ5/j .ckuNߊH~@fn5Rڒ1V?n;\q ;c/ORPLq~J9 jx sŰR`zоJUNpQ3({('\^uݫ*=T2xO Gɽv*`!Dr/7X,ǍH3AUASƨ_+䓬[>B%#K=A )LmC'! =ҽ~MC@ cNu5z#ܬ$QoJF+Tb# ݔV'zWcSrlፏ#Y񓧓\t2?NY73΋QENS+!YV2:RﲬdJ@B#Y 6z%FqegHxkY#-h?`t.|2ZpL#vGA^/oʹeq G 4E6t+ē|$s\z62OG=Ku]ص;,WB&M3H@uCz}~ⰀH.t9H۶h\hF |S-4 'Syr2_5IA. 02N׮ ͖$Z!y߲*կ*g_|O1s[$O0ló^R_v=х N sX ?K_ A>yl"42ӎ\Vؽs"lJZWs*?ÈR~nf9;3}O < +P`OQd;@+1x9w̧yHkn:+5E8K8zR֯̉^@k|,/j$Ei:9Bk\PqШ ۞aX0B|`N2e*MRs4'DF<)FօLV )pV8*ۦ!;$=w:f%wPawl!ׇ>:C΢s o ZتVEQfNJD黫l~)h;zSśCw'u@]N2? ~#IeSA+qP*0c)2y&BŐs:ДMcV$by S2wRzȷopϵH&Nư&^G}C&LHS%8!aZ}r SE"rs'޾[?7o Vb[KF=JwШן%DY}nA?$.38K!~=̣!uڊ]Vr撺4hh# 1 .j +S!l3SE&m&{AI5Qr)?H| QgeeX~7o-|QO%D3|97D>^YnǨ{v'1;lYَt Hձ=ZMWqղI@nw_iDd"]nD8Cn 7S Ig3ޢ*c#`n6iM)a R=mYcy5 .l WI?)?/E7׷~Zƨˬ#A"tΏg>.(H[DzӋQ}5 4tR9DŽ7&Z{ =d.x%;*n.*+)RKHNp`[ݘ1ľ%]pJ69R8.Ny23Qْ+}xW4<;o)n!&Ej_S ʙ R&QNq6O<.J 6Ɠ6i+:ᮖ=P_il#eiaWtِB}7f_ bNcs%ٛqE.~~M@Tϲk.ؘo'98hiu$ ϓZ0L\E $%vo~!aۈ9{S Љs)& x kgnNڧeUʞ(+}UJy4I%w/ 7=*Ꭱj2RQ.K%8s3蒀Y]?/S6OJQeF:4Fʟd$3KNfhL΂)P5'JUG G.EBFbb!y$2qVҽ^HJTnčs!wkh~j#\. nW5mڔϱhٟǣgN;y׫a/SI[^Cl t;K 4kD=͎m\Oˏ$avPhQ;UbBӒpcMKhICj>SzEH˚=H7b?3B%Aɴ&S 'hHޮT)y/yu]79$ɌK"W=Yp#btٲ$3^ ˃rFsKM ~eiU j3L.X#Xˈ sZ3]o/zOh[-,1Q'1~l2vV}wCcc/ĻYڀiZROʥw 2ܟ\;̓@tA}HeȎxXzTWƔrOϹo b#ru BoOLK}oWH38ERM {p]LIl'jHN_cj#TMVÛD (o3e b#"[<KCLDEw պǮ PucG7|XfRX˵y!iG VOG9FB.kW> i5mwӌL5"8aM`VNDzԈ(awYJlM61kAΞ,)ߧ̊TD_c:].D}/km:؁C0PH;a{[&86ٟ w {p _u?g;)>% MԮ_h d ƹ%!㦯\t/VEP|B)tWz./n;-V|]黲۱_jY=oH^584#N}<:3})Z橶vKAtE8"신bzZ""g"Rȍ61b\=Bt.eH )a!`f*)빛4X!7% l +i+=55h8DٵBCIgL^v:;$]] H^b]SG$.'ٶ#9[2%i풊{ɏqw _cs뤢}>+Ǜ)=豀iOC+o.jzQȧLuE.OB`=-Wy9{ol+y{ j6~\̃ɢ~Zk7O|"~AU,pT˜KAV~;MiIGlm1|հaf9D2bC_.%殺R, $hC+T [3ڤ5MKȀr *0aL !XX{YPU'zV n] 1BAQ+-}/|'uR=5 im/+!4rc_i_jwi>$.Q? S@Ξ>0*Zor0i:RŅ99 o2͹TvbW]Q6B͍/Uz*FM4[#Yx&} 3:m.:_oߠ +uH\=J^V BHЬNޯFE@}so !nyٕeH GmEn`; \i݄3b2q8C1 XR)/0+O?il|%[Qkmux%)`G$r̪{zh"FHD;XPgou ܸ6bW„/zgV4|L0{dx3UxXJIs$0|>ouC^+D_F%_ :(ߕ}֩N|uP>R-bwK݌+&Q(37&۠d.bN0u; -jM}|\>ȟDž$xO R&b/Ons*phh<"&ݺLkTY]OD"fF(. $%mFNqi~Nwl/1m{{ӑRHT%wJu՚lŵZfP?Z'yuCÏ9v8ʮy8˘-5l!NȚ,.MÙNd3G&U>|l2aou9hjIC_҈bKRC5p wd=<穿&] \ZʁAˉb3|AWEmOۃm6iHX?)w;69If ^~d짋P?\q>H}G+8݌_%yW IM3,q-wҼd24LJϻݟ*,f YtgRXB_4R]}@.õoajaz1Ts%Z Da^zE]$̫ S9떠ORu"+_%I=Ǖs$TA|Zzhc/cI$jiJ%ɓǘZ^.q-PNDQm/Y")0*tqK9] S"DZt^m@ W#eĵtpPu|pUu&idߝwm&1nE^7eD&| ?itV*}`)T1Oc/7|°˕Gd FmE[4D"bo1N(A:۵p !G*sыn/*lBn Yw7+|:.__\WKAݑL>hMqt]|}ri];.u}Z'MF3V /qh}й/q(|7u!- |I\3?A:+fo0.eݭ&f25E6L 8:i#`D4%uKyb3G8 tg1!X߬h(#Bȭ U`nAݒm`Ykx~tCQt9w0?bЕ5/4Wߟp϶nxlPC qqUabj:,'|Xւ+%h%cz44~[qd};^HepuWf Lڪ읳$+n$}Ò2yLs"X?┈irN5E=KusVy(FUa#K[WV&0T|MKIW!6#޼DfCM>Q#],_*=#eC]A ?EJjSf|v!OV4o=;T]97|!9=+9gvhgπvۉhtfMDs$*-q^bk=ySI,^d /ի^OUk+. ؔkXJï&Fb5S ^sN'{od=.XK DtP&QBVPi1E:Dg4s:x7S:U$dr !&z1!2ac$"\!w]*zgykt ݘB.%am}КMc2/S(\ʱvFs =# ~mtcP=ܮw؀R{.KauaS-/ZRzJ&O! #'Ȏu7_I&u(KKyTU'q2 2h濵[bޑe?`it]x/hb ϥOI-+$̊Ŋ gІ|GAQt&w.˱#gB%"?K8/+^-;QJ j|X?d% -ŁPoWv8ow{M˶ g{,Gi%AWT[ޏnp*X&MbD)~K_׊Ǜ&O`7PPYKxNk"nw KCšBvI!L KU;9|ć-( S,i͓O3Ò{zj(BӞեQtuYDԴEɺچ<X סM)\G&`mOM~-h)0$0U+~!2 qQ+ƐD]t$G2.QxcГB/\ԣn A8ޓ2]H;]j͟"kp.XP>HՍaMcߝ"^i0`O}f㴑qy7Q) B:PƇ3iُɠtpm17^d;6{rgX> &)3B?vg 'ŲujeEz+J1}'=.c8d*Ј EE٘V58AӪIQǭ%+Bj^VKⱗ- K<.ԗ%9$ m_@~tT ޏ)K%;y8-UdOistqÃ2c7CQpn&[>/<|7wP2LhA3O¤R%$}@ x" yzk3.~C<+ J;7I&&!V|OmT*|?3[i+I>%xǥ#~ae(amDЮPZZ36A 9C4e[e x;<ڜ7O3+$~CIfO"orsU\(>;Dj|>&)?VqHar4xGdƯ&#M=c(B(6uS(0眆#2Eb 3v?VZOP7I6IUPCP,6̊m)^l 4?/74%3w6SѰSg"ط⥾B9eWϽo3]dzܿ֎JopY& p06D(gmN> ViaEXq=^?^0=JFǖhQEM|\0u( "VhUBpR72v^BwճbIo,^0&GcWenECqFت6$.3Y٩!hk;zIm>W|K^V9d̅2[.ݹEI`U[5Ԫ&oEt/X`È4L ]p߲4 *쾸 {VcܧU}&iAt-y^a2D͇T'D~Mbx LTd0SuJ{ᘼkXTbF͕p~i7_s iqDWqt%F -xp@VP'e#8RޏƋ Mr=6J"̀ny v#.7.z K}؇Uۈ3jq# 앑Z25 Yص> _rET :%?>[ =ڷX@gSOhw[ݺzHi|ёvHթ&:[D7N|S[20UVGa?Ʒ9)MΙk l=n-fX%lT1TD uՕhw<쩁ʹb7yGۮp>Wj{q3t3U>MJElPsKȕX&{"B7?>Z8ʮEztʳ&Gw{yLHҙITly+ 8^:A.."ӯhBTN$nzQ~䊤$?/(YZ+>n2Ru݀#rY&h}\ңP].. 3\׸`){ȟEMњl灈Auvf1)4i;VOմ;o {ELT?Il k * \іskہ +h^aU "oߪT,|Ep֤S{i `\ 3ȕJV"n/d4ilF71,ӢX~֒_S8RF^}]6oו[fkF77"@ʙV\g̝2I-ilFpY~#QC ?a=֧/enՍO`e+Ͽ/jro\es$cIor֪ÜN׃c$V%Z:,1-bM丮%<}Ckᮎz,9@b)&O7 z2D.j +9V^Rm{PO7FiCH^^?I<'1@-ۼЍv33sbZY`]R V.ubmM4[s2s:ՠZPZ`I%LБKIn㹂"gV#H3ダ@F{E&!ɛFFPL1JثgK>|8iД?,[<5 @V/5{!Pk=*v$^:&AcWp*﫨/3SllKkjVu0EWbUטFգRjh¬$M!HT W()73dR1EZtpxNW^CT + rZ޻p%̭[Qn6(29/  lBX|B;r,,JݣxߜE@y}k'+jϫV`lp\nۀN:'Uq' a(&SG]z8;|.8%ҲUfJjYIkJ))a#ј *tG:vF05!OIf cK8g mAƙZ[9V8UU۸T XCUVL1Ok?ֶZ'JE"KB /:~_gi\an;I8-mJ{rY TׄʌR21 K>.Ɋ.aVgڽiFcY-TD}97SAra2T6X*SzwVĒ<@_bX'?XKPn2 >[T oD! , ͠{H?FW:xMLm 4#jjC_7Sm{.<ɷ2w8TiC ]pC85&*  !A:g 7Ŷ_]zS(S8ݙ*4a<Xb](Jp=cz1;e ]iřW*xV[sc2mn(B$,%!ʍ9oFg1-} #tb~+PVj.V4Ֆ-v =ɏm 0tZn!(0:eG]%|оn=kW9p^ä%@xxgЂpGR6H{S7>&)vkG CGL-Aibr~42|4{쒷q*{:AcO8S¦Qհ.dr=Zzb4pj+b2{2+jGܱ o_XV1AzA'Hdc=JkȸtI@5][mI_ WS@mjvz6-?$VLO~l(q3Y+m-vF?5"/uؐOVk!JEJcчH}x3aĤWpHDaVOoR__DVLH.ip_[RFeUO{'\}̳=|pH#< + n?!JtО Iɿn@C`98 ,gtŖh^2~'Fc>ȗ FG6).pRtg~Շ\Y%nbVT4?wqM_׶PǍjo]f*b(Wr /G@aΕ-|t =V~>I<#Ev|9f9oֆ_t^R[:4\Ou9As]݄ٻQ.'ghIF`jW.8)М!Os]X 2̠aX0q@W#&Zy"M;STB~6%TC W/)`ZDBDew 8P  jǺU'xuEv $hr2# &fХ,ANPSE&⧆|e U n[y*aꙈ݆,#E$| 9Zu 4Rc0v3gAoe9Yk P'Jr#VƔ -Ua=n|יdlUC"Hhz] Ncpw2(`HV@z]mEi)ǕrWbyyg^0D ]+a) Ye\>q84G}̘N0hsJ[_+w4Sq?R ?<{ƻ.'A0pt^"Qg0']m:+?} y3׻ ܰC/QFJ`լU.ghjA | ή}R'XPM ѪÛO:-s*.TZU\">pDJ:? edM`Bɑ` kL'uK=i%NP}ȥI< XWڕ(Ы\ի5zlCpThgc qdf%MI]P$T%.30r'￲X!ijx}rE{SuS'|\h^8M`{*ب~ů 9g_Q{ !,!;Gf ӊ>=l8*R;i])jyYDg̒ _F3ꗞ =;xQhp xS[mٟ.ČX=ϭ>S_b)dc2҂۶_//ȾcfKGb[bzHFcVUz0+fI*&6jNݣ 3(R[2@\*2lM&&\֏műiPoAMwޭ8B=PT7Q3aF/gRGuFP 񜭶Mܕ_L4* QۅX[R*]e iEMfCP5Gްn \(:~cڼ_#0-SڅH`G߇c/6/d'dS,eQfsߏ9.O߸Drb,ɀc>t~`.X\ F;amF4Aޏjg]jЫ҂ /N{v՗=E{散\D8~2~Z:cBf_@k!촃9\Ű˨1)OIi[PyJY:Vb&-$]o8 &QgE˙'1$n!39iHx;dOQk6!NM8Z^";];ehwrhg-=٪N!Щ_P^gZbzp`}ҁ ;ITS,/E6|꼹 &vkyps7%yӵ7 s]5 1e@jr4 ¬Sʼz=^AOJobҥۗ9 UqƁ`Jnzڂc-颐w_)':nckg+Вj%+Vu@_Ѡ|ط.F_;qF;-撍O.+$VMF \EK=HnҜZ6|%MC;}); 1Aq͙mS!@7{_UaҺp#`^k'Is8L4=s:kO|̲duC#V}/j^[OctSkEaFpQDE0 w44 c"nNJ gSI/>S\E::? vi6^-Z!*h$jjmgwm w]s /!S+ I ÞAe@{?w&&mZ6iqob*R%{%I H=>Jbt0V6іWϨY963/y TDc x㊄iU&}& ?{4UQVFb#irkľ[+J/ʲ5.6e6 19]B=>Ei.&C>b6̈!p5s.*S|AJ_ RV\' +xi%XM;^y|q1k>V\Vs88C\-)*5֡6qddr5/L|jig#hFhQ!-jU &1}jK(t_R ãB[F d*]6\>㏁ &ǡ ictRF E;IE,BS~ +-LKNQ^Wnš|}D)Dl @pϿq022 貲r4X9-(um<''wۼs}dӵ8%Ab_'zI~%Sd3WBPWf#'qr_)8>vcғir1Pչ!Mdm`M+K3Io#sAxo&6YZ>y=\2K_><]$p[u2ŝ)|M;4Q^6J e;({C:av.z4rbSzqe6QVR^&i^h8UFw8E6Ѱ4[bi억MQ1 9߆˳i,9"cU9!]cp1Ǘ!F1x)Ny3W%EhwOꡓ ?FL*l%ɒ Ĩ3k87XO+,Qًnrc\(j2gĨ8Ь`͓zOOMWe -Qʛ568솂 pT!V-8Sp]j^JF+zKUAe-@Щu6'?4{^s&!הsQ|ۑ܃vymTJ@6 X߸ʦ]:5O9k8`$'٠JW4ġ/$ ɱ=3HGie/оEPK/5 1q~;[%7 ;1]V$=?b,ĝ&\P?Ҕz٥kK2кU\؂#C?k%hHf^gXZB옓[aNZ&|'pZn*Ă16ԛkfuXWH^dA%L>?w{F҆qQͳ_ `He ֲ@.WEfJGmWH7TM9fx&=J&B+@+D`4P :gA#}鉮oLV\K.n8B\}ۨY+܂:bu93ݒh@e~St,ڹEe-2za/эd\=f@r?k|RL{O@Sct 0YaC=4hrM"Bޑ>*Q!~en :zwRx`9d=Q tu^X ] ԄV=08]IM?k *l+ooq.I&`G_N(haCPzfZr3h'Ackp&^qhs5 &7h͡q:lHt > ƽ8f蠶{\ҽ>ӅS]ꇧA3XԜ^ b2cYS闰Gkd:έ6&Kl,+]rO'HH̓ЋDo51i !҉GVƩzAF]gfKl L+߭ds=c*9 mVtEPhf(ho^P".s@6C/ Cltal5u+qqCrFI#=9ie}/ZHa?㽼LP 4^߈=7ON?!lj#L?1$,tk\? L c8~@ ^)`Phc-v+&'z,폽S=y-ooۧߨH EH4̝n S5]G qt~p^X~"戬Nء dx[$xtTku~R~{f)% voIdI}L)]N__EAD|BhTM&"ontdAcIKQ[Mǚ[YtD ~N5:w)J|]U2KBgᤘV`IŔ;0B9\P>[~ôWK]77yh՞ }s08G? #]FN;〲EZAWm`{E?jY]rZ u,Mb M᧍ :hf`ޒFv;{%a@d$aZҚh >58qf$הj8sFGv,{ȣ2t|@ޓ=H.-mSj)'=g+~q4_5 u Y1H tbf9ȡ^jnL1\r :O+<;R0A"|( ,VB^t)'tkg }pŶdw jdלjrTO\o-3 UJOzP",jщLe< +@&,i[͗|'0rUϋu|r%966%AJa28ڰ?}.)v$AC4RSY˜ߏݯɓv .nN if=6r (s`TA8WRlt=L}l,9m7Xq4'j9zY]'@F' Ee܄:gjL>&^XvF>{Ĝ$5ċXYF˷W1 l8LMm풙h_ x ~} @D 9[M 1E_}RLp>pe_̲?D,F 򶧥 z#+}3W)ǿ!L9oh< m`utM ^ w lMm/3AI{(x$Y~1G˸+;rj=p$ qnqzZ&&Sd7q29rƤ#[ |n$`f_,Eސ]ż$EaG,WՈĜ ۘ#IAn2)hSDY[y<ј|"B?ne!n8߰r%pc 5YSÍC(CW _$0(ј,?LQLo^GwZiTý^)B]Jkx$J+9UOskSVɚ%㜱BD*Sviv&Y:_S͡m@~6XQ1X 揗0/ J7 (<%(wӬ[ڬnjNyfdCn% jl!BĚ30n m_3S`\,2~p"KW`9#"_0o(~ o'D*uzec|RpʫJ2 b[\Q!%q*~`,Hh LHpfxUmtu >> C /l8){)oZ:'|Kx.^z\q8/H#G!WB_QlPI&JegڤNƥU0V˂01pY0~Xh3˯Gf{NoeȄ`l Z3zB=V'!vkqgU^1 bXqR ^/ܪ-3ۛ-JŻOcc; JUQW(i!f~ƕ;9@Y#2yx[hMs:sIL;΅'{0m"Ѓ;=!s-=u {jCxf03p${%,NH\<-S!7F:ԉ[*f y@-!NEJ XON+!Oqvu ?zC0Ŀ7qSt"JECMSl`ѡL[?Q.~$" !֫p[Uakx9K̷EhwFK! (3%;zHz^kKygLoE& n&e8?I'Ü-!\pz#Ic-qj{雥B-8GYٓ>C59>bC/@k;ȹR_T|#X'7< M& wB5S73P+81ճ[k}P#hDF, "1uŤ.#^:[GS/٣BRԹx`%u$0]qUh :3CjUIiA<.#z=άGHW${&b__ amjx"|XFQb~J5E#6o5 ~p|Eo g;m!A3$yDb&75g ĝ;H2;&ZMJI5tͣzZ1̜vҊ4%]Ql&gXݝ]~50]~{ЛUЏX 5YYM{`rd ٞ :8TKAJ*2dPUuSǝH(ԯz~M ^("2i&$ƨIaA·@]/ti39y 4$TPC@](,inpcωMW endstream endobj 168 0 obj << /Length1 2383 /Length2 18248 /Length3 0 /Length 19679 /Filter /FlateDecode >> stream xڴeT\]5";o ww]A'%̪Z5gժ URe6JA ,̼9yy0 hh 4223#PPڛ: 1CGS^@m= i 2s򦎆jn,jm 2Liޖmr10g#@ `L2˛Ff@T * TQTWRa|Kdk ZDU%b jS zڟo5SЛ~szڛ[jjJ,LjMhK2_ioK6-my\\\͝挶S:\V_{Sk2yk`g?NV-z;F8ip0tgr4 LM# doC\K?EoZ{x՛[1tptOFSz?{cVWUc{<<; FGW{E.n+++mHA&`7'|#ލ vỳ ?}7qeRL_  0[0!gVYߚa Z;zL~< MN^v_0;QA'4 MPsLiΨ d015C`R;NqI8Y[+ژRWG;h+BTj@WS%?M?L skS ;#3'<N]??כ|oSil2upp2}~ۀ?L Z2*t=7D&@9`hoo6 61ugZL  lgG99LLA\&ѿ$q1$"_`d"N_')Eo|"V_Ƨ7vO/z_3|FћEo o'o4 <~ 5_& o_-_ ,l-LAxߚj/_M_&o*L '?'_ ,o*|l7Ǜ^;'-j/Z7ߢޚ`m`񯀷""nT`uTR]BַR]jr߃YE?Xle 4y{W=Udy}?C@j; v. Yj? ?ϳ`jjj86 Ln .ϟ,a<%n1mX`7twH"e%rDYh[ޛE\GoY'͡Lvv1Vb#QHW_Ide+0.3,X h X_ {i q~t}KS:KRaG:fjx5{!uAs3]{LpD~X*4uNlldޣ̷|\ņ̎T2Qnq]ֳYpꅻaesYkzEod<1r},T&aY:Ѕ:s%(vc*d4Xͥ`D}KܛۂOhAx y4\( +4~ЂP=.pT=={D?)esADRMs[mKH^KuLIë`e17C}Tc3ə?9lJQa$eDp]3F>2vB8Em,y D3kAU s>UMRkqX!>#GAcZ2JSѡDftZ <Eqr=J߉{z4ڈKڎ:XBEMP?/=Ց IҎg&<ח":*1"Ye}g6_Zkʋۋ;?.׵}O܎(aU:@J09"V**#sޮm"@ WʀeR.+j}aq$`W7T[[ΫMânq^rO4P<̨!1%x&0v8z~9tLAa6OYiIa-oz<ߙVOGui#oϫx@]t%Sx!c 1̴QdO6hmњm'ձ4DXM:[ Phs *bh4(,c""S@.TBk,M&-=\5KS[юJߏRNМ"#2^%W@i+&¿!{Qy s͏Uh+5՗؂WJUvQ{΄Zt;աb1~P4 ԤZޢ>y #?52(*fE4:+ "ܽW@tTSd 3KOT=[ )~<\9HXbz3z[c]z qȁkd'xoyT`Ctu&%]a3{ʨU S}a5`Ogw~SeՖt2i8(Cû^ q)z1cQ!^ _lk|Ev.1U-K* EulVdIÉSk1nj Tbض 揗[m΢p Qo<ѣ蕦d,Nuy.S4y}%Zj0}0":+ XtF ӵqUFȥ <#:q!q~b^fr+_DᚐI:LɄA'BF$E]A 1DL NM.&1nTnY]˾V<8a{W ,ê$paNE YlCȬֽ6%9(¿[WU%xx16" {#y=Z"V:x,,#Ī%‘ *ՀH6A튀JGي̕W#Bt1!/G qs7zTw /’iNzqwߧsepmQuJڣNhDf}ufigo³gڋaR,˽jʐJ?roe27],|֫ $6uO=<ܸ3/^/tAt&[6~b33/ LcDeFgx `\'ac\O95㺿 sƩ8(eJd)=hQ<2oSyP/vU'?¨o߼:@{֬^e=ȡ8(./ڝ瓯σx퉁nY^As@0D۾mcsKǦ 4;1)yO3^d@ɚf\#I+GKن8 ia gޱf\ ,κ_I<]37aM02 G;Eݪ#55߶-8aV+>?Dlnt]N} 8fV_>?,k2jR!{ѓdAm '#F.uB!Q ݶQpՙ%z=pq0]~:mh.XY7hei$)H=#tڑ1*^V)U*3lI-S0S1rDdY PPE8kaŹ'XBuW 'FL&ކk@`3hdɳ}׻bnHu>a[л b%A^d\ǝV[> +Z+&pSw4xݥ3VՔ"%[Яs%+QS?oߢXQ~T7u ЫS_+2deaCRyXDNˏSw 8F3HDR*pq;) $9/E¾. W_D.i1rFdTig}/Z|@:Q4lϷy [$Y> XTY,p.iPR?:P ͪ %iΊnNDH}&9`>vF~kT1ʟ#/0sB&>[I܈ MW>LgZL JhОpǖ4ƣc=W]0Pi ?nJ Mℓ9BcM8M;OH)e(9BYgژ! +N a YE_bM_f~v1=t:JRMy8w`1F^۩^bZ a0ȆY,PEf_8#;Jҡa/]YZqk (TN3Q򟱆 bzmL1z&%)4w{# s6ňY(sRkHiE9f9@ye |ӻ*ө9.! qam҆`*qviT-jȎL7A|lRЂc5$gD*,qd).< I33b\۟،I} e5{O=D@H,p6"9v|(k;~efgO[]ߤ 0H1cE%5 5ASy\[8o[KY SIݒ3pgӷy[_Ixk`}c{8Z&[{eS+D6N_*+SsǨSmז%}+*s"xRO>sʶjFl2鹦Jj6)1.lU p H7 ˩`ApI"$q8#u ]5m$@'%vL2^{Woh&9awl.@ &/ec . Nuڐz@͂qį/d͸I>QԨ-'j%R9I`È^)o>H]RÓ|O_*OayF!H'~NKT )zf#k5}0]kr'$Sm +ñ)m-f-5Aʢ,r5}W_i?9T 0z%~(1F!}' u0Z}Ӥb)bhA-9G'%W@zS}}mj.Awv Ǟ٫nS&GZQtD 5hCԅ"ۉ]S z ^{ F•Kśu]0zsU8z1>w\hwE(6b@y:(F( >۰iZԎ$j ($w4h#Hݤv#+lB=sMh|)q)21Z C7|;_iPxDHmtV4R.DC~O77 jdA/gti3ߡ¤Qj\ȧs`}M|j3a+#ah*ۂп )o>Km|hgjYk<,(fрOVh{u߽j `#tEH+ k 79UkFv;؇$%`*8+K=VktqW ){,'b1>PZ?~F0$ԕYxkOd]|o/#::8"*482W+VƮtyê=M*ܥ u,;ߔ-j|9a >uAXԃrJG+Cjn8!ҮA8nRT"DޜWCyo#VuBn.إR!Zk|ՅWR )U /7w V9J8ͯ{fkK-%/61(4qlau2DC6{*Kz;b$BhsMf_6)(mލt;׏ݨ}.[>nMj4Yt. Q}X) +]!ݽ m/V &+a!d_Ż[uE0EݹZpDYnz;:H8ɪ&~*$ Luef_Jo Y6(aGWUT#(XCrdtXj?`"2\(|.GLpm}m%UR6|KUjwN KfD'[1_2 ]E`5jdfj-~|=a_fpUQk}z.6sT|:o`7q XcFLa&')e[N#Ĉ6Rh;y\uǴP h*4 ΨvH?'.18$Ԗ5}$+GxzSB>R3럿qhaGjkp5ge½60u ۸ɪ!qsQ'XCLFJ9DɆAm;2ŀ=㋘y4V$U+inklY`'^ϾЧ`Wغs>kiAd5CC);*EdİXZw75 :!lBdSMQtFM}(_Gݭ>  _Ժfk8 W7[_'}dF㖙w-m Ta>d%Hkrua̷܀.W"wЊU}+;}v%Ԍ?~vCH9v: P4Ѡʋ'U$5O:/gjݏb]Z, _F4(@~C[4"d\WWY̞Aތ^r K.<eAd7Q;ub&SoTC;PtV1E35{)3,Vǻq{t'aQXJV'YbҴ-Lt94쵱}u]5/%1ct)^Veܿ cGGC?Mm6+RҲ'OEO=dpo(o ԻsFߑ_ڡLH*z_Țy٪p}0D9U2$!qYUt F.e&K;X3X-oI/k Սƶ%,~9 r~Uy@rըgs+apiN&T- : t w-أ>)EdР Fӯ=bk[ik֍e{,Pmom}lo#T* ]C}e3 M 9~h 7"anGQ9AMonЁЅ 7KJ\2)lԑ'FA0NVxVo^Y-i[,=)|c.X;l0 ,&`@erO/WQyHx:ax0& f[-wfH'wcB1韀GaR˙xwx룦^[f`.)t$1|؎t+VQ"Yej1V4'"=_ o VNi3-IsJa؋%]E[S:P>.f7ss HB> q$NOPEB;_ vwp p ,k 1МX@2AjYo׾BZy}lh&liyﲉgD Xϥ }6m5஑rαhNSA Jgv!NY(?Z&w%Cͅ0S./ 񴧸ui\F옾0 mY訉.Db8궑s+WK?Z)ΫO0j{yDzwE`8W0GaEdb=:+<V -e}ZNG J5X .|norqś#al_XLܘw<|bpܩQ~ 銑! ;'\?]`5<)^B )7n0)8;W ^LRmv_OC%C}E%sEMS=a}A?72L+/IS WW,e>TAwlea њuk0WJi#DNלΞvqxKشW;((qD)Egk7D(M9ܙr:e9+Io6"sXv6Y4C%%41T`"n%z!hNpy xXR%mG63JtGrM>N.PN :x3fxam.-Ue%|j]mO/k+洎N@54-˲|uEq?DS~-

]a_lBOJ=qQu}0ƼUiIaosp⨷CG 'w5O6X)XhqųۃOQd3ƨ<)sd}i>[U [૖s3$~B-`2X`z`r)6/#Q.psxM=fI5JgbA2<ё9WIVwob 2[e(ST֑r2}'5H5Wf2t^aD6-}Bq}{oȾTֺ2RA8U`H422Xe9 9dVLߋ6ߵ444 Vqo6KzBkj2qVm:@D4 ;- Hr"3g6^8 /7= !^U"oan}4ig$hy`⟼GZ:NkyCc)hXC]ȏiM&u8 aAz7yiL#,Ae^knljG 6.iUvJ5T_6 ~;'Z:}$s-Z)1 ] )&ǣ0^ hMiMC!Ha}޳z@PX7\E>xK#uoZ08WnIQ*#0+m"&kEyb_;f61\T`a^E;䇍Rr'3t",.%gZCrt+yAŕ}4%77-w h6Z7B4.'SC,y^ߐnmn[Y:5SG󼸕g )V-$OQΕiAFHXt)=.^nTX'2H۟jEm4mUfpVnyd~b`~)Hc6lFּJQd SVt,5^ĺ&@UI 6dBsQٝ|}?(tܚt.wl`OC/G&,i`FOMךOVAn%v>rExsڃ1@D2]rtWAʐ@=P!A{w/PVr$$z1,zG]#$g=oZ {NfJdRJ+n! _!qr8bU < -> r0w&h# ý|L._Ϳu)ں>y pmg"lg,Q-8ҡƤ˰ VYQ'"w/}f8aZ~4ŵ҇Jk``?Z &kO`ɻ֝"Ij!oĎAS#jYXe43Wl"ٞӲ{e{ _>sגD.5!w:X]=`JPB1R^U[^A-?&\N?m_221rc,BQl ΫXkaYdBVC7n#bmC`qMV/sK#aH C&_,a;AMMPť9>sЁ/wm7S L- uM=k°,\G߷ &b9acma!DyO+ :&.W7 \غ 2?'k ZV~i9a=(9ֈ5l?= oQ0K7pwKXHdVgA8*Ȑ > o}& )Ewռ9!Xa׭0-sAȄҸ [ӪצrU^Ezy1 afc!Z_3sqsA|O m-Ö!}`Jr.XV1M ?i%x{)O\85?Gt;$mx_s`(`C.%Nd\ڹ'BJH^鎙u-#-8Zqxšl9zرl1܏{{Atu*cxB$:}8ukrWT/2lEuhun`&y ^Mv'PDw +KVn%M8~NZaE>3}tÙPz!{;Nl_E^ jȶd3~0rÖhҟHo l(2~pJc|%&/E͸XΓ ip74t+3ޥLAc$:u /m8 !m~s|F^M&"Ub$*or*~YΰvMP-'4'ȗ y`S26O-X_[)Gy_GR& P3ؠY #8yD^ĝ7Hܯ +M o1Y_JOgWrQfd~Dݽވƹ6]݃c9h3coA+dJ́42/IuFMFnxOy¯g=*ځ4.-RKUHe|SS<9ЋRZ{^$`>:ـ)ְNG@LhPgUwFPX8P9f65ںĊuZ_ڪwI -.?7gK2 [_QrY:& y>L$JJ| Dd"zޯg/Itlf}=9|)B2fJa}F $){Xk:QiҞ_?CB橉뇵Cfrަ }_.w2sg)UK--9Gk/Yصde ?}wL{d} c+)cX({I'/bOzĥC[.)w)c铄$JKːVш]iռ2I& zy6X-s~j>R$ISh] bϦu|GϮ2\uc֠۰`L /[W/~e :ݑjC JwHx0㠆R-!0kM~WCnȘ'4Orp =Q|xXwxz^kh⬑=7y "~28T 8MFDBx@ ܠ`NS;M^|3W; 8SmsaɔKTgbFisAKdk^BNNZ~b>zCF"y;gۡOwV7ڕTY |M o둉Ã*w[.E~|zY );YOLmDH3&9;w: d`֓`yxK]s% %jfG4~-'rH?}w¿iTJsjzADڲ]19) B$ڣ*ykՔm:)4KU9^ ʞ}MRB샱{xϯ?q& , q@]^l0Ꜻ۔hiE47\4P^HB0NO?4 񩌸0(mӇGM9R} y %}H(ey^*v[e:rg5-lkU*>4Rk|A+ִJǗm&~n#H &@XAS%sKɱS ù><^XMzΪKjO=h5pGj!ONvqgLg]Z>qK۪x;i5bB"z ! 5 3{) 7=[ 9We k|02<|ZT)\_VicPsM+",haz s/݁RzG$vR+ieI.g9a%W)?G&&L䬅|Bk}RˍitߵHZ}Hz}d } &5c X~i $r6BY:nT2q9.|@ Kx;z?mF{D@,xV?]yF(CY6-~Zq2r"J"yTd ^2xŀ_D^OTP`fE4_2cg픧 ^Ug$1#v_3 ;h Eh?$ 6rHSzu%l ª3  H&7uʇ E20ˆG=>05I~$L(:ϠZNԏmUgQ~5{3P;z")_S|nb#{J9Oւt%Vv;= ikڶE`1v`b:=oqx@^/ay7r4Q˯[rXЀj"U6:9b{e.QP]>ikVv+|jȇà ĹX:q!-R-1Xh:Trb~O5|sPT-@De>hy_j!6LQhWL<''ˠu $#>K=3rʹ0?ǿ77{jA?E/L{SLWkHG3k¾ovV L.;Q}E`{bF%C$*Yͣ`sjF,i9 !,Ve˄CE`zvQ sm70[8^(͎JI10e‡:7|vq1+&EmӥĒeǗS"fb Zϫ@۫caC(qϛy&7T~- tGy*M%  &f.+5aTkwSţkCMd~jmz'2tꚎ!/"q' Y/eꏗkBZISą>(Ī6#a;Ѩ1ơ|Bx&M7PZl3eAk}.׻`Iz ߰Vd%uC#i"Bdq6Ԓ;lYF*d Xu@en>ZS74=p\ǧn&wl#1bJ6"~,cC6G`F[2κ8vJaGVU]r(嫫Qq[@Wo G;%t-#14ÖhVpbI{,aJW  Gݎ3ÕVa;>׾eΛń^K|Mܸ],8Wv{lY|`T !BWB?`qc)z3PxzGHsqY/Bѡ⚱WR}c4+j h%YJΟcgPe|~^c^KTpWr>;QH S Q\TV\Y`AwO M<[%(ߧΔN~X?K Mn$2t,0uS=Z9Q8P:Pӭ؞MAUd*uOLsVj-/m=ͲtIytypqF`[W}7 =UWB@`Vv{KP5A*Y &~^]ff+$to h- ~[PA뭎DLXȄ3K!hg0j0e0&F-K:ESX۷.?ཱི4uR$#9ngڭ+vlҔTMNZNk0gn~.Y)85ŴL=_k9ܰ+Cs g`BZPg3 dT@Bi.0*eBT(8Hf|Cm3@YjqZ$h(Sq i}Qܼj*z"9 ۗC;v*|Cel9ӽ=k1pfDf&5L53p3}WZǾ6wHƯzdTw9HssovI"l/|]s35='j7 e$+@5 ]̒+;G&uI*FI% k7J:׊oX=C".)@r -wp;0 yqǫ˦ z$I|dvK?sq ތ [#F|Io#2Ť!.8j5w=9գR !b9_?8>@S=O5,C2p5TrlmV0/BY]Tx%PHbW %s9 Ok| h#t?GR!+fĖUMɠ>]A ;6 } 8OE< laIfvY5i2?v77 34=L~&qN;mTd6ɂvŽP=:c?J h<-J$0j{Z孿ΊC/FK<;CɪU.2J"*DH$_*%VtDd";\da endstream endobj 184 0 obj << /Author(\376\377\000N\000a\000m\000i\000t\000a\000\040\000G\000u\000p\000t\000a\000\040\000\046\000\040\000J\000a\000s\000o\000n\000\040\000A\000n\000t\000h\000o\000n\000y\000\040\000V\000a\000n\000d\000e\000r\000\040\000H\000e\000i\000d\000e\000n\000\040\000\046\000\040\000J\000u\000l\000i\000a\000n\000\040\000Q\000.\000\040\000Z\000h\000o\000u)/Title(\376\377\000S\000h\000a\000z\000a\000m\000:\000\040\000Q\000u\000a\000n\000t\000i\000f\000i\000c\000a\000t\000i\000o\000n\000\040\000o\000f\000\040\000s\000e\000l\000e\000c\000t\000i\000o\000n\000\040\000p\000r\000e\000s\000s\000u\000r\000e)/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.19)/Keywords() /CreationDate (D:20200205134006-08'00') /ModDate (D:20200205134006-08'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) kpathsea version 6.3.0) >> endobj 142 0 obj << /Type /ObjStm /N 53 /First 458 /Length 3280 /Filter /FlateDecode >> stream xZ[o~c|$.\ (7q8i&ZZۮv&gfȽIZ(r8pZR0K ) gL:߆Te"A& !WxIp9F0Lɤ7($08<)h&`' *f aFY`J2K*hŬIPkl% 6M,s8s2 pP9xp,qpp>GKiA%.aޠN@DJ X8;!yATy@O=bX*R4K-Mz$N v8yC@DON<Tx9ISG&ܿ|^挿.}hESL u^,LȎOXȳ}>Sfθ-eyJ9M}:;Kƣ¡C `H0X+4&Af}?hm.x|z.4B ! ֺ>Y:dG4s`fn`l8@臖vB mkSZB!==o84~Nu0W(xwQb*X{Exa5܂xC㍈8rx>( ԏL3S/](QJZМtkÍ/tCk6=`vIh+e[PEQ@ Vuo&%O~Es!c.@Z)~(#MﻄgCP뤥 I,T1) \I},y1֓|7&B-|*Ɩmwtm§gű'=6 r,TjG<jxjTPFV4("=ԅ1*I gC?6 m3ZŦ 8N VSIND XC b4؇.`$qOjSvHgܤ;e#!JA/!gO$ ڡLi}sl8Ow?g*qC=i=X\9K&~ B`]\ȸV\zc99(%/5_/G5oàq _OG'/^v}8҅q`~ &I#BQeH{8߼yd"V;Q z D!IF ;DB!FX??.igB|]y`ͪZ@{}p$#/zEuyy/"bKEz+Wx*.9jyI O. ,\7Wљ?Gfw1woO=`aьfjjfc55_<џ#lrzA`=w kme;7M0 O_߾..wJr]Fb;̪U;y&4:P0{]w'#㷦_z[+^oC -@̷-WӣŬK8vqqw Tn)[@蟭t[ HD E!7E NFG69arp aVc-ZAF%<ŏY6[a_l!2\z䃳:ێ%yCC$euN?_| IAo8ϳ8\̛~w%VU ߧخS1) Son&H79-),7t uSBߦjjS5wD]֦f[Q`(0B%Ϧj[qH53P-&75ۊwfU#So)綕j|a5w.Ct,Gl\y.wI"i_c'÷kw&6nJSqwJhna%1<`]^8r(C ipRoi'քLn:99~ 6uV#Dm!Sv!pTa ֹM^7٪9d*Rr Sc?K:dvo3&Ph̚ZLzrQ&b^s(` XjKz]6ŲMNJyq]4\!9dB=Eݬ3A 'BZl[pS7~I:PY M.Ȥ:;@OPydkTrU'q|lNSq:-|?ٖH sN\tRU @(z2 y33_8!iBvKy[9ám@(&v*Ce|:٤% <6C7435F61F29738C1A50FA31FD5B6055>] /Length 479 /Filter /FlateDecode >> stream xӹOTasEd``pcPA\Y]AE@\m,0vʄD;+B!R ;t~o{wy_bۻFuDrHkǩR(S\pkǨ2PABdj f9<@;h&h~8Y(@+@3 q(2?"Nhs˿לC/בNBt5|p,@[/]~j`ybY[pɭY,\vW;0W`*\su Up&`&LÌ6֪tS6Z* %\VignetteIndexEntry{Selection quantification} %\VignetteEngine{knitr::rmarkdown} %\usepackage[utf8]{inputenc} --- BASELINe quantifies selection pressure by calculating the posterior probability density function (PDF) based on observed mutations compared to expected mutation rates derived from an underlying SHM targeting model. Selection is quantified via the following steps: 1. Calculate the selection scores for individual sequences. 2. Group by relevant fields for comparison and convolve individual selection PDFs. 4. Plot and compare selection scores of different groups of sequences. ## Example data A small example Change-O database is included in the `alakazam` package. The example dataset consists of a subset of Ig sequencing data from an influenza vaccination study (Laserson and Vigneault et al., PNAS, 2014). The data include sequences from multiple time-points before and after the subject received an influenza vaccination. Quantifying selection requires the following fields (columns) to be present in the Change-O database: * `SEQUENCE_ID` * `SEQUENCE_IMGT` * `GERMLINE_IMGT_D_MASK` ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load example data library(shazam) data(ExampleDb, package="alakazam") ``` ## Calculate selection PDFs for individual sequences Selection scores are calculated with the `calcBaseline` function. This can be performed with a single call to `calcBaseline`, which performs all required steps. Alternatively, one can perform each step separately for greater control over the analysis parameters. ### Constructing clonal consensus sequences Individual sequences within clonal groups are not, strictly speaking, independent events and it is generally appropriate to only analyze selection pressures on an effective sequence for each clonal group. The `collapseClones` function provides one strategy for generating an effective sequences for each clone. It reduces the input database to one row per clone and appends `CLONAL_SEQUENCE` and `CLONAL_GERMLINE` columns which contain the consensus sequences for each clone. ```{r, eval=TRUE, warning=FALSE, results="hide"} # Collapse clonal groups into single sequences clones <- collapseClones(ExampleDb, regionDefinition=IMGT_V, method="thresholdedFreq", minimumFrequency=0.6, includeAmbiguous=FALSE, breakTiesStochastic=FALSE, nproc=1) ``` ### Calculating selection in multiple steps Following construction of an effective sequence for each clone, the observed and expected mutation counts are calculated for each sequence in the `CLONAL_SEQUENCE` column relative to the `CLONAL_GERMLINE`. `observedMutations` is used to calculate the number of observed mutations and `expectedMutations` calculates the expected frequency of mutations. The underlying targeting model for calculating expectations can be specified using the `targetingModel` parameter. In the example below, the default `HH_S5F` is used. Column names for sequence and germline sequence may also be passed in as parameters if they differ from the Change-O defaults. Mutations are counted by these functions separately for complementarity determining (CDR) and framework (FWR) regions. The `regionDefinition` argument defines whether these regions are handled separately, and where the boundaries lie. There are two built-in region definitions in the `shazam` package, both dependent upon the V segment being IMGT-gapped: * `IMGT_V`: All regions in the V segment, excluding CDR3, grouped as either CDR or FWR. * `IMGT_V_BY_REGIONS`: The CDR1, CDR2, CDR3, FWR1, FWR and FWR3 regions in the V segment (no CDR3) treated as individual regions. Users may define other region sets and boundaries by creating a custom `RegionDefinition` object. ```{r, eval=TRUE, warning=FALSE, results="hide"} # Count observed mutations and append MU_COUNT columns to the output observed <- observedMutations(clones, sequenceColumn="CLONAL_SEQUENCE", germlineColumn="CLONAL_GERMLINE", regionDefinition=IMGT_V, nproc=1) # Count expected mutations and append MU_EXPECTED columns to the output expected <- expectedMutations(observed, sequenceColumn="CLONAL_SEQUENCE", germlineColumn="CLONAL_GERMLINE", targetingModel=HH_S5F, regionDefinition=IMGT_V, nproc=1) ``` The counts of observed and expected mutations can be combined to test for selection using `calcBaseline`. The statistical framework used to test for selection based on mutation counts can be specified using the `testStatistic` parameter. ```{r, eval=TRUE, warning=FALSE, results="hide"} # Calculate selection scores using the output from expectedMutations baseline <- calcBaseline(expected, testStatistic="focused", regionDefinition=IMGT_V, nproc=1) ``` ### Calculating selection in one step It is not required for `observedMutation` and `expectedMutations` to be run prior to `calcBaseline`. If the output of these two steps does not appear in the input data.frame, then `calcBaseline` will call the appropriate functions prior to calculating selection scores. ```{r, eval=TRUE, warning=FALSE, results="hide"} # Calculate selection scores from scratch baseline <- calcBaseline(clones, testStatistic="focused", regionDefinition=IMGT_V, nproc=1) ``` ### Using alternative mutation definitions and models The default behavior of `observedMutations` and `expectedMutations`, and by extension `calcBaseline`, is to define a replacement mutation in the usual way - any change in the amino acid of a codon is considered a replacement mutation. However, these functions have a `mutationDefinition` argument which allows these definitions to be changed by providing a `MutationDefinition` object that contains alternative replacement and silent criteria. `shazam` provides the following built-in MutationDefinitions: * `CHARGE_MUTATIONS`: Amino acid mutations are defined by changes in side chain charge class. * `HYDROPATHY_MUTATIONS`: Amino acid mutations are defined by changes in side chain hydrophobicitity class. * `POLARITY_MUTATIONS`: Amino acid mutations are defined by changes in side chain polarity class. * `VOLUME_MUTATIONS`: Amino acid mutations are defined by changes in side chain volume class. The default behavior of `expectedMutations` is to use the human 5-mer mutation model, `HH_S5F`. Alternative SHM targeting models can be provided using the `targetingModel` argument. ```{r, eval=FALSE, warning=FALSE, results="hide"} # Calculate selection on charge class with the mouse 5-mer model baseline <- calcBaseline(clones, testStatistic="focused", regionDefinition=IMGT_V, targetingModel=MK_RS5NF, mutationDefinition=CHARGE_MUTATIONS, nproc=1) ``` ## Group and convolve individual selection distributions To compare the selection scores of groups of sequences, the sequences must be convolved into a single PDF representing each group. In the example dataset, the `SAMPLE` field corresponds to samples taken at different time points before and after an influenza vaccination and the `ISOTYPE` field specifies the isotype of the sequence. The `groupBaseline` function convolves the BASELINe PDFs of individual sequences/clones to get a combined PDF. The field(s) by which to group the sequences are specified with the `groupBy` parameter. The `groupBaseline` function automatically calls `summarizeBaseline` to generate summary statistics based on the requested groupings, and populates the `stats` slot of the input `Baseline` object with the number of sequences with observed mutations for each region, mean selection scores, 95% confidence intervals, and p-values with positive signs indicating the presence of positive selection and/or p-values with negative signs indicating the presence of negative selection. The magnitudes of the p-values (without the signs) should be interpreted as analagous to a t-test. ### Grouping by a single annotation The following example generates a single selection PDF for each unique annotation in the `SAMPLE` column. ```{r, eval=TRUE, warning=FALSE, results="hide"} # Combine selection scores by time-point grouped_1 <- groupBaseline(baseline, groupBy="SAMPLE") ``` ### Subsetting and grouping by multiple annotations Grouping by multiple annotations follows the sample proceedure as a single annotation by simply adding columns to the `groupBy` argument. Subsetting the data can be performed before or after generating selection PDFs via `calcBaseline`. However, note that subsetting may impact the clonal representative sequences generated by `collapseClones`. In the following example subsetting precedes the collapsing of clonal groups. ```{r, eval=TRUE, warning=FALSE, results="hide"} # Subset the original data to switched isotypes db_sub <- subset(ExampleDb, ISOTYPE %in% c("IgM", "IgG")) # Collapse clonal groups into single sequence clones_sub <- collapseClones(db_sub, regionDefinition=IMGT_V, method="thresholdedFreq", minimumFrequency=0.6, includeAmbiguous=FALSE, breakTiesStochastic=FALSE, nproc=1) # Calculate selection scores from scratch baseline_sub <- calcBaseline(clones_sub, testStatistic="focused", regionDefinition=IMGT_V, nproc=1) # Combine selection scores by time-point and isotype grouped_2 <- groupBaseline(baseline_sub, groupBy=c("SAMPLE", "ISOTYPE")) ``` ### Convolving variables at multiple levels To make selection comparisons using two levels of variables, you would need two iterations of groupings, where the first iteration of `groupBaseline` groups on both variables, and the second iteration groups on the "outer" variable. For example, if a data set has both case and control subjects, annotated in `STATUS` and `SUBJECT` columns, then generating convolved PDFs for each status would be performed as: ```{r, eval=FALSE, warning=FALSE, results="hide"} # First group by subject and status subject_grouped <- groupBaseline(baseline, groupBy=c("STATUS", "SUBJECT")) # Then group the output by status status_grouped <- groupBaseline(subject_grouped, groupBy="STATUS") ``` ### Testing the difference in selection PDFs between groups The `testBaseline` function will perform signifance testing between two grouped BASELINe PDFs, by region, and return a data.frame with the following information: * `REGION`: The sequence region, such as "CDR" and "FWR". * `TEST`: The name of the two groups compared. * `PVALUE`: Two-sided p-value for the comparison. * `FDR`: FDR corrected p-value. ```{r, eval=TRUE} testBaseline(grouped_1, groupBy="SAMPLE") ``` ## Plot and compare selection scores for groups `plotBaselineSummary` plots the mean and confidence interval of selection scores for the given groups. The `idColumn` argument specifies the field that contains identifiers of the groups of sequences. If there is a secondary field by which the sequences are grouped, this can be specified using the `groupColumn`. This secondary grouping can have a user-defined color palette passed into `groupColors` or can be separated into facets by setting the `facetBy="group"`. The `subsetRegions` argument can be used to visualize selection of specific regions. Several examples utilizing these different parameters are provided below. ```{r, eval=TRUE, warning=FALSE} # Set sample and isotype colors sample_colors <- c("-1h"="seagreen", "+7d"="steelblue") isotype_colors <- c("IgM"="darkorchid", "IgD"="firebrick", "IgG"="seagreen", "IgA"="steelblue") # Plot mean and confidence interval by time-point plotBaselineSummary(grouped_1, "SAMPLE") # Plot selection scores by time-point and isotype for only CDR plotBaselineSummary(grouped_2, "SAMPLE", "ISOTYPE", groupColors=isotype_colors, subsetRegions="CDR") # Group by CDR/FWR and facet by isotype plotBaselineSummary(grouped_2, "SAMPLE", "ISOTYPE", facetBy="group") ``` `plotBaselineDensity` plots the full `Baseline` PDF of selection scores for the given groups. The parameters are the same as those for `plotBaselineSummary`. However, rather than plotting the mean and confidence interval, the full density function is shown. ```{r, eval=TRUE, warning=FALSE} # Plot selection PDFs for a subset of the data plotBaselineDensity(grouped_2, "ISOTYPE", groupColumn="SAMPLE", colorElement="group", colorValues=sample_colors, sigmaLimits=c(-1, 1)) ``` ## Editing a field in a Baseline object If, for any reason, one needs to edit the existing values in a field in a `Baseline` object, one can do so via `editBaseline`. In the following example, we remove results related to IgA in the relevant fields from `grouped_2`. When the input data is large and it takes a long time for `calcBaseline` to run, `editBaseline` could become useful when, for instance, one would like to exclude a certain sample or isotype, but would rather not re-run `calcBaseline` after removing that sample or isotype from the original input data. ```{r, eval=FALSE, warning=FALSE, results="hide"} # Get indices of rows corresponding to IgA in the field "db" # These are the same indices also in the matrices in the fileds "numbOfSeqs", # "binomK", "binomN", "binomP", and "pdfs" # In this example, there is one row of IgA for each sample dbIgMIndex <- which(grouped_2@db$ISOTYPE == "IgA") grouped_2 <- editBaseline(grouped_2, "db", grouped_2@db[-dbIgMIndex, ]) grouped_2 <- editBaseline(grouped_2, "numbOfSeqs", grouped_2@numbOfSeqs[-dbIgMIndex, ]) grouped_2 <- editBaseline(grouped_2, "binomK", grouped_2@binomK[-dbIgMIndex, ]) grouped_2 <- editBaseline(grouped_2, "binomN", grouped_2@binomN[-dbIgMIndex, ]) grouped_2 <- editBaseline(grouped_2, "binomP", grouped_2@binomP[-dbIgMIndex, ]) grouped_2 <- editBaseline(grouped_2, "pdfs", lapply(grouped_2@pdfs, function(pdfs) {pdfs[-dbIgMIndex, ]} )) # The indices corresponding to IgA are slightly different in the field "stats" # In this example, there is one row of IgA for each sample and for each region grouped_2 <- editBaseline(grouped_2, "stats", grouped_2@stats[grouped_2@stats$ISOTYPE!="IgA", ]) ``` shazam/inst/doc/Targeting-Vignette.Rmd0000644000176200001440000001443013575255254017451 0ustar liggesusers--- title: 'Shazam: Inferring SHM targeting models' author: "Namita Gupta" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4.5 fig_width: 7.5 highlight: pygments toc: yes html_document: fig_height: 4.5 fig_width: 7.5 highlight: pygments theme: readable toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{SHM targeting models} %\usepackage[utf8]{inputenc} --- The targeting model is the background likelihood of a particular mutation, based on the surrounding sequence context as well as the mutation itself. The model is inferred from observed mutations in the data. The model can then be transformed into a distance function to compare Ig sequences of a given dataset based on the likelihood of the observed mutations. This is done via the following steps: 1. Infer a substitution model, which is the likelihood of a base mutating to each other base given the microsequence context. 2. Infer a mutability model, which is likelihood of a given base being mutated given the microsequence context and substitution model. 3. Visualize the mutability model to identify hot and cold spots. 4. Calculate a nucleotide distance matrix based on the underlying SHM models. ## Example data A small example Change-O database is included in the `shazam` package. Inferring a targeting model requires the following fields (columns) to be present in the Change-O database: * `SEQUENCE_ID` * `SEQUENCE_IMGT` * `GERMLINE_IMGT_D_MASK` * `V_CALL` ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load example data library(shazam) data(ExampleDb, package="alakazam") ``` ## Infer targeting model (substitution and mutability) The function for inferring substitution rates (`createSubstitutionMatrix`) counts the number of mutations from a given base to all others occurring in the center position for all 5-mer motifs in the dataset. The `model` argument of `createSubstitutionMatrix` allows the user to specify whether to count all mutations, or just silent mutations to infer the model. Column names for the sample sequence, germline sequence, and V call can also be passed in as parameters if they differ from Change-O defaults. Additionally, the `multipleMutation` parameter determines handling of multiple mutations in a single 5-mer: `independent` treats each mutation independently and `ignore` entirely disregards 5-mers with multiple mutations. The function for inferring a mutability model (`createMutabilityMatrix`) counts the number of mutations in all 5-mer motifs of the dataset, and depends upon the inferred substitution rates. Furthermore, the same parameters available for inferring the substitution rates are also available to adjust this function. The inferred substitution and mutability matrices returned by the above functions only account for unambiguous 5-mers. However, there may be cases in which the user may need the likelihood of a mutation in a 5-mer with ambiguous characters. Each of the above functions has a corresponding function (`extendSubstitutionMatrix` and `extendMutabilityMatrix`) to extend the matrix to infer 5-mers with Ns by averaging over all corresponding unambiguous 5-mers. These extended substitution and mutability matrices can be used to create an overall SHM targeting matrix (`createTargetingMatrix`), which is the combined probability of mutability and substitution. ```{r, eval=FALSE} # Create substitution model using silent mutations sub_matrix <- createSubstitutionMatrix(ExampleDb, model="S") # Create mutability model using silent mutations mut_matrix <- createMutabilityMatrix(ExampleDb, sub_matrix, model="S") # Extend models to include ambiguous 5-mers sub_matrix <- extendSubstitutionMatrix(sub_matrix) mut_matrix <- extendMutabilityMatrix(mut_matrix) # Create targeting model matrix from substitution and mutability matrices tar_matrix <- createTargetingMatrix(sub_matrix, mut_matrix) ``` All of the above steps can be combined by using the single function `createTargetingModel` to infer a `TargetingModel` object directly from the dataset. Additionally, it is generally appropriate to consider the mutations within a clone only once. Consensus sequences for each clone can be generated using the `collapseClones` function. ```{r, eval=TRUE, warning=FALSE} # Collapse sequences into clonal consensus clone_db <- collapseClones(ExampleDb, nproc=1) # Create targeting model in one step using only silent mutations # Use consensus sequence input and germline columns model <- createTargetingModel(clone_db, model="S", sequenceColumn="CLONAL_SEQUENCE", germlineColumn="CLONAL_GERMLINE") ``` ## Visualize targeting model The visualization of a dataset's underlying SHM mutability model can be used to investigate hot and cold spot motifs. The length of the bars on the plot of mutability rates corresponds to the likelihood of a given base in the given 5-mer being mutated. The plotting function `plotMutability` has an argument `style` to specify either a hedgehog plot (circlular) or barplot diplay of 5-mer mutability rates. If the mutability for only specific bases is required, this can be specified via the `nucleotides` argument. ```{r, eval=TRUE, warning=FALSE, fig.width=7, fig.height=7.5} # Generate hedgehog plot of mutability model plotMutability(model, nucleotides="A", style="hedgehog") plotMutability(model, nucleotides="C", style="hedgehog") ``` ```{r, eval=TRUE, warning=FALSE, fig.width=7, fig.height=4.5} # Generate bar plot of mutability model plotMutability(model, nucleotides="G", style="bar") plotMutability(model, nucleotides="T", style="bar") ``` ## Calculate targeting distance matrix In the Change-O pipeline, the `hs5f` cloning method rely on an inferred targeting model. If users wish to use a targeting model inferred from their data to assign distance between sequences for clonal grouping, then the observed SHM targeting rates must be transformed into distances. The `calcTargetingDistance` function returns a matrix of distances between each 5-mer and each corresponding mutation of the center base. This matrix can also be generated and written directly to a file using the function `writeTargetingDistance`. ```{r, eval=TRUE, warning=FALSE} # Calculate distance matrix dist <- calcTargetingDistance(model) ``` shazam/inst/doc/DistToNearest-Vignette.R0000644000176200001440000001134113616633136017725 0ustar liggesusers## ---- eval=TRUE, warning=FALSE, message=FALSE--------------------------------- # Subset example data to one sample library(shazam) data(ExampleDb, package="alakazam") ## ---- eval=TRUE, warning=FALSE------------------------------------------------ # Use nucleotide Hamming distance and normalize by junction length dist_ham <- distToNearest(ExampleDb, vCallColumn="V_CALL_GENOTYPED", model="ham", normalize="len", nproc=1) # Use genotyped V assignments, a 5-mer model and no normalization dist_s5f <- distToNearest(ExampleDb, vCallColumn="V_CALL_GENOTYPED", model="hh_s5f", normalize="none", nproc=1) ## ---- eval=TRUE, warning=FALSE, fig.width=7----------------------------------- # Generate Hamming distance histogram library(ggplot2) p1 <- ggplot(subset(dist_ham, !is.na(DIST_NEAREST)), aes(x=DIST_NEAREST)) + theme_bw() + xlab("Hamming distance") + ylab("Count") + scale_x_continuous(breaks=seq(0, 1, 0.1)) + geom_histogram(color="white", binwidth=0.02) + geom_vline(xintercept=0.12, color="firebrick", linetype=2) plot(p1) ## ---- eval=TRUE, warning=FALSE, fig.width=7----------------------------------- # Generate HH_S5F distance histogram p2 <- ggplot(subset(dist_s5f, !is.na(DIST_NEAREST)), aes(x=DIST_NEAREST)) + theme_bw() + xlab("HH_S5F distance") + ylab("Count") + scale_x_continuous(breaks=seq(0, 50, 5)) + geom_histogram(color="white", binwidth=1) + geom_vline(xintercept=7, color="firebrick", linetype=2) plot(p2) ## ---- eval=TRUE, warning=FALSE, fig.width=7----------------------------------- # Find threshold using density method output <- findThreshold(dist_ham$DIST_NEAREST, method="density") threshold <- output@threshold # Plot distance histogram, density estimate and optimum threshold plot(output, title="Density Method") # Print threshold print(output) ## ---- eval=TRUE, warning=FALSE, fig.width=7----------------------------------- # Find threshold using gmm method output <- findThreshold(dist_ham$DIST_NEAREST, method="gmm", model="gamma-gamma") # Plot distance histogram, Gaussian fits, and optimum threshold plot(output, binwidth=0.02, title="GMM Method: gamma-gamma") # Print threshold print(output) ## ----fields, eval=TRUE, warning=FALSE----------------------------------------- dist_fields <- distToNearest(ExampleDb, model="ham", normalize="len", fields="SAMPLE", nproc=1) ## ---- eval=TRUE, warning=FALSE, fig.width=7----------------------------------- # Generate grouped histograms p4 <- ggplot(subset(dist_fields, !is.na(DIST_NEAREST)), aes(x=DIST_NEAREST)) + theme_bw() + xlab("Grouped Hamming distance") + ylab("Count") + geom_histogram(color="white", binwidth=0.02) + geom_vline(xintercept=0.12, color="firebrick", linetype=2) + facet_grid(SAMPLE ~ ., scales="free_y") plot(p4) ## ----cross, eval=TRUE, warning=FALSE------------------------------------------ dist_cross <- distToNearest(ExampleDb, model="ham", first=FALSE, normalize="len", cross="SAMPLE", nproc=1) ## ---- eval=TRUE, warning=FALSE, fig.width=7----------------------------------- # Generate cross sample histograms p5 <- ggplot(subset(dist_cross, !is.na(CROSS_DIST_NEAREST)), aes(x=CROSS_DIST_NEAREST)) + theme_bw() + xlab("Cross-sample Hamming distance") + ylab("Count") + geom_histogram(color="white", binwidth=0.02) + geom_vline(xintercept=0.12, color="firebrick", linetype=2) + facet_grid(SAMPLE ~ ., scales="free_y") plot(p5) ## ----subsample, eval=TRUE, warning=FALSE-------------------------------------- # Explore V-J-junction length groups sizes to use subsample # Show the size of the largest groups library(dplyr) library(alakazam) top_10_sizes <- ExampleDb %>% group_by(JUNCTION_LENGTH) %>% # group by junction length do(alakazam::groupGenes(., first=TRUE)) %>% # group by V and J call mutate(GROUP_ID=paste(JUNCTION_LENGTH,VJ_GROUP, sep="_")) %>% # Create group ids based on junction length and VJ calls ungroup() %>% group_by(GROUP_ID) %>% # group by GROUP_ID distinct(JUNCTION) %>% # for each group, we want to count unique junctions, so keep distinct summarize(SIZE=n()) %>% # get the size of the group, the number of sequences arrange(desc(SIZE)) %>% # sort by decreasing size select(SIZE) %>% top_n(10) # show the top 10 top_10_sizes # Use 30 to subsample # NOTE. This is a toy example. To use 30 with real data # is probably not a good choice. dist <- distToNearest(ExampleDb, vCallColumn="V_CALL_GENOTYPED", model="ham", first=FALSE, normalize="len", subsample = 30) shazam/inst/doc/Shmulate-Vignette.R0000644000176200001440000000350713616633161016762 0ustar liggesusers## ---- eval=TRUE, warning=FALSE, message=FALSE--------------------------------- library(shazam) # Input sequence sequence <- "NGATCTGACGACACGGCCGTGTATTACTGTGCGAGAGATA.TTTA" # Simulate introduction of 6 mutations using the default HH_S5F targeting model shmulateSeq(sequence, numMutations=6) # Simulate introduction of 4 mutations using the MK_RS5NF targeting model shmulateSeq(sequence, numMutations=4, targetingModel=MK_RS5NF) ## ---- eval=TRUE, warning=FALSE, message=FALSE--------------------------------- library(alakazam) library(shazam) library(igraph) # Load example lineage data(ExampleTrees, package="alakazam") graph <- ExampleTrees[[17]] # Input sequence to be used as MRCA of the lineage tree sequence <- "NGATCTGACGACACGGCCGTGTATTACTGTGCGAGAGATAGTTTA" # Simulate using the default HH_S5F targeting model shmulateTree(sequence, graph) ## ---- eval=TRUE, warning=FALSE------------------------------------------------ # The annotation field called "SAMPLE" vertex_attr(graph)$SAMPLE # notice that node "GN5SHBT01AKANC" is an offspring of "Inferred1" par(mar=c(0, 0, 0, 0) + 0.1) plot(graph, layout=layout_as_tree, edge.arrow.mode=0, vertex.label.cex=0.75) # Exclude nodes without a sample identifier # The nodes "Germline" and "Inferred1" are thus excluded # As a corollary, "GN5SHBT01AKANC", the offspring of "Inferred1", is also excluded # In this case, "GN5SHBT07JDYW5" is then taken to be the MRCA shmulateTree(sequence, graph, field="SAMPLE", exclude=NA) ## ---- eval=TRUE, warning=FALSE------------------------------------------------ # The "Inferred1" node is taken to be the MRCA and has 2 immediate offsprings par(mar=c(0, 0, 0, 0) + 0.1) plot(graph, layout=layout_as_tree, edge.arrow.mode=0, vertex.label.cex=0.75) # Add 20% mutation rate to the immediate offsprings of the MRCA shmulateTree(sequence, graph, junctionWeight=0.2) shazam/inst/doc/Shmulate-Vignette.Rmd0000644000176200001440000001336613575255254017316 0ustar liggesusers--- title: 'Shazam: Simulating sequence mutations' author: "Julian Q. Zhou" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 5 fig_width: 7.5 highlight: pygments toc: yes html_document: fig_height: 5 fig_width: 7.5 highlight: pygments theme: readable toc: yes md_document: fig_height: 5 fig_width: 7.5 preserve_yaml: no toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Simulating sequence mutations} %\usepackage[utf8]{inputenc} --- `SHazaM` provides two functions for simulating mutated sequences, one at the sequence level (`shmulateSeq`), and the other at the lineage level (`shmulateTree`). Both functions rely on a 5-mer targeting model for computing the probabilities of mutations at each position along the input sequence. The 5-mer targeting models currently availbale in `SHazaM` are: * `HH_S5F`: Human Heavy chain, Silent, 5-mer, Functional targeting model * `HKL_S5F`: Human Kappa and Lambda light chain, Silent, 5-mer, Functional targeting model * `MK_RS5NF`: Mouse Kappa light chain, Replacement and Silent, 5-mer, Non-Functional targeting model * `U5N`: Uniform 5-mer Null targeting model ## Simulate mutations in a single sequence `shmulateSeq` generates random mutations in an input sequence. This sequence is provided by the user as a string, with the acceptable alphabet being `{A, T, G, C, N, .}`. Note that `-` is not accepted as part of the input sequence. If the input sequence has a non-triplet overhang at the end, it will be trimmed to the last codon. For example, `ATGCATGC` will be trimmed to `ATGCAT` before mutations are introduced. The total number of mutations to be introduced is user-specified. Mutations are not introduced to positions in the input sequence that contain `.` or `N`. Mutations are introduced iteratively using a targeting model. Targeting probabilities at each position are updated after each iteration. ```{r, eval=TRUE, warning=FALSE, message=FALSE} library(shazam) # Input sequence sequence <- "NGATCTGACGACACGGCCGTGTATTACTGTGCGAGAGATA.TTTA" # Simulate introduction of 6 mutations using the default HH_S5F targeting model shmulateSeq(sequence, numMutations=6) # Simulate introduction of 4 mutations using the MK_RS5NF targeting model shmulateSeq(sequence, numMutations=4, targetingModel=MK_RS5NF) ``` ## Simulate mutations in a lineage tree `shmulateTree` generates a set of simulated sequences based on an input sequence and a lineage tree. The input sequence will act as the most recent common ancestor (MRCA) of the lineage tree, and sequences in the offspring nodes will be simulated with the numbers of mutations corresponding to the edge weights of the tree. The lineage tree is supplied by the user as an `igraph` object, such as that returned by `buildPhylipLineage` of the `alakazam` package. For details, see the `Reconstruction of Ig lineage trees` vignette of `alakazam`. It is assumed that the `name` vertex attribute of the root node is `Germline`, as is the case with the trees built by `buildPhylipLineage`. ```{r, eval=TRUE, warning=FALSE, message=FALSE} library(alakazam) library(shazam) library(igraph) # Load example lineage data(ExampleTrees, package="alakazam") graph <- ExampleTrees[[17]] # Input sequence to be used as MRCA of the lineage tree sequence <- "NGATCTGACGACACGGCCGTGTATTACTGTGCGAGAGATAGTTTA" # Simulate using the default HH_S5F targeting model shmulateTree(sequence, graph) ``` It is possible to exclude certain specified nodes from being considered as the MRCA and from being included as part of the simulation. To specify such nodes, use the `field` argument to indicate which annotation field in `vertex_attr(graph)` contains information relevant to deciding which nodes to exclude, and the `exclude` argument to indicate the value in the annotation field that nodes to be excluded carry. Note that when excluding some nodes, additional nodes that have not been explicitly specified by the user to be excluded may also get excluded. For example, suppose that node B is an offspring of node A; and node A has been specified by the user to be excluded. As a corollary of node A being excluded, its offspring node B will also become excluded, despite not being specified explicitly. ```{r, eval=TRUE, warning=FALSE} # The annotation field called "SAMPLE" vertex_attr(graph)$SAMPLE # notice that node "GN5SHBT01AKANC" is an offspring of "Inferred1" par(mar=c(0, 0, 0, 0) + 0.1) plot(graph, layout=layout_as_tree, edge.arrow.mode=0, vertex.label.cex=0.75) # Exclude nodes without a sample identifier # The nodes "Germline" and "Inferred1" are thus excluded # As a corollary, "GN5SHBT01AKANC", the offspring of "Inferred1", is also excluded # In this case, "GN5SHBT07JDYW5" is then taken to be the MRCA shmulateTree(sequence, graph, field="SAMPLE", exclude=NA) ``` It is also possible to add a proportional number of mutations to the immediate offsprings of the MRCA based on the fraction of the nucleotide sequence that is within the junction region. This is achieved via the optional `junctionWeight` argument, to be supplied as a numeric value between `0` and `1`. As an exmample, suppose that the MRCA has two immediate offsprings, each containing 2 and 4 mutations respectively compared to the MRCA. With `junctionWeight=0.2`, the number of mutations to be introduced to these two offsprings will become `round(2*(1+0.2))` (2) and `round(4*(1+0.2))` (5) respectively. ```{r, eval=TRUE, warning=FALSE} # The "Inferred1" node is taken to be the MRCA and has 2 immediate offsprings par(mar=c(0, 0, 0, 0) + 0.1) plot(graph, layout=layout_as_tree, edge.arrow.mode=0, vertex.label.cex=0.75) # Add 20% mutation rate to the immediate offsprings of the MRCA shmulateTree(sequence, graph, junctionWeight=0.2) ``` shazam/inst/doc/DistToNearest-Vignette.pdf0000644000176200001440000076150713616633140020310 0ustar liggesusers%PDF-1.5 % 35 0 obj << /Length 2100 /Filter /FlateDecode >> stream xX[6~ϯ/2kyե>t')q ,"m-d:{)Ki(b4yx;d&b\<KThq:a"O ɣ:!~5bieyWe%jWWfGcӶ3joH㎖mcm[4/g"RGset[e lG+[nHj9ol;Sld@qZ a.x"S_dB[/;5oCgUߚ43_iTkܖ{sϒ\K{lĜiZqHz֘J2txUJgj&yYxx7Z 'yebtv2^Od6׌*O@O hy9עtEs. o([;ӑҏ*UjN|uӿu.4u{Ӯkf_Vc=!d.QI )UZ: NjmnQQ g~ڮntm]tj immj*ځ!- -(+oDt}yg7]S=5h<hGLdOD̤a"e"RY0egEIrcKh?J-8~0MWJ:xQ8IU9CIOqIz6Tly)|ܥڳ~tv֔gNS.{[8l|L &kjP;0~.y*gǑh2E#Ax-}(}dK4!aqWv5j~r!;I^R%burde9+g4)~rr=ThɿeQ$" yc+ 3J,v1{PCP벩P,>q+aHf,eH,Wzr; TfW?LpP>g zHQ98g?[>t,8V&+B"$ O(w>"/NK04ͼPM0B.b>НeXR"7H?b<#q$X8gWW )z[h*GqV{kھk(Nw}6;<dsrD;4pb=yb"jj `3@#6I:!5v#gia<ݹ"Nc?AY”˱7Uy@{/e 6g ͦO\.UN=uc3تV6|?"y kh&bo YD;\w_#ݳTHQ;nbzQN׋' endstream endobj 54 0 obj << /Length 3134 /Filter /FlateDecode >> stream xZY6~f_4 [ILRJ0Gↇch"5V6" Ot7V3o\=zB3{Lx/ҟYb?|7yg"ks)$MΚngaobNc**-O яn:o8ENJHJhߓRDf~॒YA͏!~bii]J= !u+npjzJb[--b} uduu$5LFJhBH}C:ѿm[?%\&箻Yt_x N1'L#/[H+]+ɳ뼙:PwFZ&#Z7 MĭS $.T%@_VTjG@8j40Dr8p:}`)h.v!mem:7j:4J$#<3|ߋd2l$Ւ5Ixႝ~Lx9/pPOǞ-R]Hx_ǶbEI<'H93 GgN rOW4u]~"{`+~ãyrd"/Na~f89 lhzƹo\#j4Ɯĉc xDb3Fa{&k^ө6ތ&[ǣ;CG" :&5i੏a"nhY}80"0 ѩdXO8vJRDj1wkj~eH:s18GG7*eAm7KV(chS4~K\te6:(ޮIh2#8T6G?A>%vTcXMw?F5 Ш?4z5uS"ݎlZt&8Rda`۪¾@`vMYsKqCXk4OF-|0s'#5` .m)cFJn-.7E">Հ0`&#3ِ.zrӿׯ_^}w?/58ҏ"S)%ɊZH!b>o׶X 0ꎣ_WswWl n eۃk\' %&E֙}ְ4٤*mhµB}w4~ޱGj~h\%ƶ`5ͼ$I+hYF Ϝcj }UntDž41"&:Q Q^FQAe' "h+=/.N%a|aR\|ad< OGD"4s/K;nkzC751BHڬ o8?>mQ|ܥ+? v^1L(#*ef/_tt|Suݵ>xS9Lb/YNkt/%$|P7 7"\jjS]0uv8݈?"%Rec,O?[mC':y*.QDc0LFv_X!U*}|@ZUJ 7g hQqvp@SrzjpO>ys?V q_D$c>p]Cs0`rգR endstream endobj 64 0 obj << /Length 954 /Filter /FlateDecode >> stream xXO0_Dk?đ0äA߶JZF$)- $kI CRqwAmA[V%~lڤy!fP۠^gR ABiK͵@@KP/}zNu!T! S/xdS}d^cEj-GmPZSCI;E3@-W!w@Mq>X y$qdAC쨭vH{r*;XvX0*+2~h o(fn ifòx{1l,܈'Q,2T2JhP6H$=hA0{v[.x R#F g0JoS`ly<I!o-"2H:pXr[FC&a')WDpr6S@I?vt~j;mCN(1bul o G^l`W&ҽ9zgLĶ5=R`Y.n6psUM"R.m՗.gu)B :u1-nEEں'TD~z<[_o\Fe[zG*Pl%wI;C`gol,IƮkp_>w֠F%z-F4]C64wBͷ;!d"*d1%L2ǽ?Jw endstream endobj 60 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./DistToNearest-Vignette_files/figure-latex/unnamed-chunk-3-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 66 0 R /BBox [0 0 498 279] /Resources << /XObject << /Im1 67 0 R >>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC]S]\.}\C|@.T endstream endobj 67 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./DistToNearest-Vignette_files/figure-latex/unnamed-chunk-3-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 68 0 R /BBox [ 0 0 504 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 69 0 R >> /ExtGState << >> /ColorSpace << /sRGB 70 0 R >> >> /Length 1027 /Filter /FlateDecode >> stream xWKo7 ϯб9F"@ ^I /)iFֻ#јC/}vq|Z~۫s8>ޟ|{|w Ϳk.μaqK{%/,_ߙuxՙH;ck;j~BE4rX~;[pP D݀zvC 9CBSi^x2+9Ya 8C ) Q*ezPG.(u!JNCPUcb$#ђ!EE[:ʎ/%uSܢΟ<;皊(/1Q:]i#(kJooOkp0\(@xX2әe5fv f-$;*{ns[Z`QeÃ*E=7DhYfsm\Gh=h=m|g_о{͐j\=9:LS2kT7m# l杷?^?*. AnAo@@7`ډ$$"$l##~b#}l$#|"{l"2ؒ!qOͷ?!i{mVz~-ߝv ^@=ݶm>$[WUi]Fb5̑f?9?2o?<~yswg8^Ή zBDƠzY+6 endstream endobj 72 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 76 0 obj << /Length 1017 /Filter /FlateDecode >> stream xڝVmo6 _aU lvz 81b]G`Q(>$ҦmD WOHH*ELFvςR +N/[Zu}$9MRΜ EDmG|%K!x=Jտe{T'Ba:k˦Z'N/p 2p^jVGƵƲ5ɒgjź[U]oMCG8mo4Ѿ>Qi\6 dɦ]UPa`!"ω OPY0f"PKz)Hף]_R FR#9tP (܁2H)Ctx4 MjR%uӠ` ߸ݘ Y4nn0[T ("5#o'(<죪&K2@=v{ڥ Uɔї/WMٻj8#5 0eRESo.菔JpFCcȠ%ö^\mHUW >LAbI #"yv|Kqːt bv+ӌͭ쌥b@0\&|֮ ng 8@IT4?T@l?MOX)JG:XǾn_^ԟ2K 24 6tt]0B`N}o# F}p kp(<ڭϕEFDQ@| ˆ?-=~( @4WOomJ(alXҮ(@!0!kKmz9%1~'&"z)иf 9%|3 +0=&f+R>!y ͳ5S3l0=y0jirsj (,IFw!rn9y1fPM6cw7 $u+F H6rX endstream endobj 61 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./DistToNearest-Vignette_files/figure-latex/unnamed-chunk-4-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 80 0 R /BBox [0 0 494 279] /Resources << /XObject << /Im1 81 0 R >>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC]S]\.}\C|@.T endstream endobj 81 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./DistToNearest-Vignette_files/figure-latex/unnamed-chunk-4-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 82 0 R /BBox [ 0 0 504 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 83 0 R >> /ExtGState << >> /ColorSpace << /sRGB 84 0 R >> >> /Length 1330 /Filter /FlateDecode >> stream xW͏\5 _#0}H*жX`_gfF=LfRl\QavzgA|FνAa<; ϽAɥpF#,א#mM5[V )r>'mp1q 4/+O.W4ٙXZK}z2_ٯi 5 20bAgoFH_,rsv`,v0d>~򘋣>Mz#NӀ>u sy|O_dk{;jP_+5w|մzW_F5꯸դz„ syzS$pӎJqݯDCwkE)SԢ"h9n0Dn>%*~4ir^oVV*U<̰ׯ;W/~x}J7J[h^u׿?wϋ3?; endstream endobj 86 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 90 0 obj << /Length 1907 /Filter /FlateDecode >> stream xڵَ6}BAbx(),R E-ƒm:\ۿ Eﮝ( !9"`DU9|NqbJdb'g8ͻZ?W/b2 "KdA<|̇#%\xyU#EV+LDʃoK-tKW6î+][?W?Xm]__)0HdԵ3#fşvan="9U .b(K&F,\1[(9b+|~<,N:[pQ_mzcʿ*YWͥr2) {KMMe?f],v9&-QYNY*3tŋL±wbaM;vYVOecpk6l_84] )7%XGaC(ߝ$Un,ΥD@~UG0TtN*c,->GoxuN>;-R hbf9S)։ :QG349~oüp,kEm X,yYkMso Y {;j(s#ΞA1dLCj}p824n$iҠT#"j7%yUV=UE'/*(E>M,tdʸD ]!>fp vl7_6W-R iYtf;"M#A6=f +r.zn%&1\WŖu@fij0&]Cs^MRtUե'q8Hyz׶ZN (), ] l#c+UOd_"w:Zv'ԝn`Ϲ^bŗ|"DrTt>CdgP Xsl3wT4ݥ6g U$FdN~R9_>> Z} ZWŭs*K.˶K쬨9QWL,cvP5}F7)& !hhIG<t&!pRŤ2mQ@Gc]Cݸ0ռ!@C*eE1wSL>슉a5T뤫uU+z')j j!j!x9}N*(-ݍ-tPl}I9yzg{݃ptb|.!>(99V7 ;S;e>Vo=o?yoWIza,oO.o0I$wpdp09ad#=jG;Ԯ_I4xл 3Ńc?Mj4}>}ⓄKCgZ>愡Z?PUut={߹Yv0_D¥VKY:%Emy:" endstream endobj 73 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./DistToNearest-Vignette_files/figure-latex/unnamed-chunk-5-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 94 0 R /BBox [0 0 494 276] /Resources << /XObject << /Im1 95 0 R >>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC]S]s\.}\C|@.T endstream endobj 95 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./DistToNearest-Vignette_files/figure-latex/unnamed-chunk-5-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 96 0 R /BBox [ 0 0 504 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 97 0 R >> /ExtGState << >> /ColorSpace << /sRGB 98 0 R >> >> /Length 2594 /Filter /FlateDecode >> stream xXK]G_q0=mC`K, 8"QlTU $y,|骮s//>r<uYjgon?_r|fg)x}VΊ_Ng~_<էo(W7?>ۛj?N#9\gc<=\{ӟ?y_ gqhG"G[svN{6sq$#ih9G݃g' Nn4ه7Xmg1@x F=ood3 ]J#D$ۀCI56A1^8;UMktu J8a#v,:sBq܆Qd0QD/pO *,ɉ/e8H!w M؄Mv^y^q/K?<>Mzr"_!~[>$ G~G~ Ԟ|OP/p/ů\!T u;J~Oy T }𪶋z7lBy~eώ@iD~Qy mc# rXoY#ݑOգ#Q߲D__| 4@d?!~^'RaIz_WqpuRfoהb5IySÚj)xċDӏ??~H~ Kߢ0.~Zbwa-IK?`17x!/[OqX!EL \{! v`Zj u^YK֮^A ycwG*W#`9U`.Ypܺ`p>0 >UF@dWvՏNvJ]m"=Ў3A";4LmgLN@;C9Z9kn6!D*uqoǀ0;0Ȯ7A@I-Y-2ρGl!7pWt Ҵ T/g xh.j ,^p9AFng>6Dp) %mDu_MACvzEzugA_2N2Xw<,;:N{!^0v`u %ѕ0 + @= V'] k٩CP׋`J{dC-86[/鼖z)L```0VVhr,v5䃀3N2826`1uirH+:.XWSp4k(`_EB #T0k(X/4\  m-WWKRp;]Z٨@F&t &X`?4d0VvUU5meW]2a >dpþpl7\A)!m7u3ӧ}3 n8y @W2m7tw fpڼñpnfܡm77;l `AaL.a_v~u

9_=쇿O>>]Www_aUGyO0oْ&M>ܐ3f%™qͼI%\_>OҨ'ݴ哣PQ_>4>Vi|C]m_xʹW7w >Ǵ|?οHMӓ/瓽t2ߚ>Xxe6<^rp9G~4|gv \߼|?oz,z7},P~㟏OVL~ endstream endobj 100 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 103 0 obj << /Length 1822 /Filter /FlateDecode >> stream xX[oH~v_ FjA,D@I%_C_gO:xXUs9;3U'{R(`Q{BR]ꏸǯJͿ(vs?ԭnJdd;\Z|r`y10ń$E\Q!cֵD 1q p.rSNViW )Ζ97;ܜUKRWxÖU-;YeeedI@)I!Z]tr r*?b-  +wKZO8 =ja(PtVAs'U ('7@Fu*`)>Ia$T ee{j Ofj[(k4z;MOlVq\vSG"0jLp@zɥ G 89Ph[[6-gM{ZW1UD(~Hpbk=Jej/fkbEz@*cc[ǔE]l˪unhp.Noѵ.qIՇb,dŒ_n53AiI@F/wzy!z!L\FfD!38Uۢ7碰3|hyA7xzbb.Ii\v6\"(jpVa=c`nJv]_KL2ƑwM 5!1ΈT)nU̚DAǤig:ve*eDLPe4*L6ˎ*.aBI 5Z&Y5!]6)R@1fV65Ndf b"/yķ kE1i̼S&G{3I$>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC]S]s\.}\C|@.T endstream endobj 107 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./DistToNearest-Vignette_files/figure-latex/unnamed-chunk-6-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 108 0 R /BBox [ 0 0 504 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 109 0 R >> /ExtGState << >> /ColorSpace << /sRGB 110 0 R >> >> /Length 3717 /Filter /FlateDecode >> stream xM&7%,Ҵm ) b%H4wL$ĿTua>q>.;_ˏwr -913oox?=~u]뷏uf\MΗVu|.\pxzxqtt^?}qJCgM,ml+ba/g+v~ٓY!7HaajIgrYW,v|٤ִ+/g,W:3Y$:(43>dXig|Vks,zm>3yuYrUټ#K\U\Yx˜L ps#!T31.TB(3[h$j= J%VP}",{ XrM#^ӐESJRR#3|(C\p}8<8GA 1@jD{*"9K;!Ev3'+R[ƙ)Aۜ5rkrkrKY&ÝENcM|ii.-ǽA"]NcM.c)XJ~/I"eKe,e>IbXJe,%d\7YgSvخsdE "]zc7/͒t~H.{Kgl (]:cew錍36Fgls]:cctsl2yc.?Mfo,RPݥ76{c·b "]zc7)MNڥ7xce]ߥ7)w鍭Xlr.HAcE "Mvo,rεKol"\"]zc7vxc7{Ko,RPۥ36]؄TwM]:cM36]؄vM]:cSp&l{. )hl2:cRP٥36EglB ʻt&9n2yc7)hTvŶ'9.HAu썕s.rڥ7VYov鍕s.[wE ʛlŶ'4vmX9l+ǭ]zc7VN\X9s+]zc7vt;tfKglvl1]:c698cvrڥ36gl.YN^tf9y36#M&o,rεKol&ol"]zcKolkX9y[ڥ7VN^o]zckڏ-:c_j]9>}9Dk9ʝrP: HAUAUAc9|kU-{Sͩ')S =MƩ6״8%cq*w:7N&>Zpiq9UaTSokT`jZ:d}s83^L79rST&S~iT0nyql8dzK x8UƩ i;9d6S /9U6Hj Rq*lkVc!zENVSB ] !/uVEcũ$i3ȩ r*r*H+CSa5S|.9UJ:@NpSAvJ5VZ39yiȩnB>xq*H39Uiv19r*HMnƩ &Tj.S9T]LN%·UƩDj#ɩ*}.9H 9UgJI8E%zq^70Nt2N%ȩm8 6 C8$9U98f~TN[ENգ[4N%Q dS5Ʃ8LNq* ~ MT^*BK@fޫ'Sf R3q*8xecq*9_TU WƩ$Y RӦq* AT:Ʃf2Nlj^8UTb03N`7N%)WKNUŭq*y{ؙSU{kJ\ro\eqZxkV8ON%T 9db5p.P1N)8ʋXH `T rb^TH&.GTۡSiWƩ68U%8>T rb8U!JNyb5dSA&9ll6N~8Ʃ ub jl@NIɩ৾6N%)hɩ Ki8$\<*[ƩS58UƩCAN%!="T{5 T8UMq8CSgX*WNITZ9ʕ^S8|ҠUSF]DNs8$!ʶ<!x/8UkJZ39d8UmJ46qM1N%9ۍSɡF/& %-q*9iɩ}bJNO*r*Uh@N#W:T9ڠS1B(il4cɩ$a }.9vr1N%:v1N)8> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 116 0 obj << /Length 1539 /Filter /FlateDecode >> stream xYo6ݿB^4fEYvn-ӶP$"9RkAQwki9ˁSE.D)x*`}qlvVϓYAbkB*ȡ2o>;{k6* G0GvUɪ4Tm~ΊB3d.t=1j"Oe^8pybAYj$/,TvW/=m PH}Pm f體Ya o3& zRhO!+(]rD툗^*OH)Ub7y!U¬!^S]~\8B!kZs7^U3$z> 'a¼l ?r c2*g C0IIxgv&8('ruN=dsxROyT/|6ゃ Hmc0Q1[sC2IA(^(I(Swic?󺀼XnRIW|GݥE"u9sA 6o}$e I6EmlSgZuz"YT(U{@vb "s7>Q]fGzz[Hn6B&gXD9>?7F<kqq+^y" i@d]eFJF:&9uq.IK;aI\t}Uǃ);<;i"0袸0Zj$e#֜W\b^dsI0 =ClP{rg&PM:pec".73L,ړwS^ƕ av&]AS<:P-w[RB.'zi# P2'@]ޞZhY@ӧ7%.vM4z!3- Ѕ `fXkBb(9Gdh|oTF&EV{S m| 66m}kEr\ۺ#iwH|=@!ה Oq IDvBtn?~B.*Ð>BYA;'p?})2]8՚Y\/[eo@9]7X/ kip:{yyq5~o5;q2 ^~Ɠx"]V8ۿݍ~')W}HcЎb:jv!is_Fd/>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC]S]\.}\C|@.T endstream endobj 121 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./DistToNearest-Vignette_files/figure-latex/unnamed-chunk-7-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 122 0 R /BBox [ 0 0 504 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 123 0 R >> /ExtGState << >> /ColorSpace << /sRGB 124 0 R >> >> /Length 1472 /Filter /FlateDecode >> stream xXKo7 бEaUc$]m)@k9=:mPrfg ;=l.I/|SFCC0)?WiQ||m뫟ʯQ7ekv0/җ>O ByR[ku'x|w. uuj F$ 4p  0Fۄ>Yºf.D4ӈLB&F=tLh8E8L   !@tVDHR"p͓\y J3 R(hCS.XmQ@{K{)bDM͂牙 [wVr]sB^Yeࠤikf?[aB5& i"ٮ\k*TXem^Yt=r% neUиӴ*\^ܤm:c)c^ڜkJ%.nP.r:ֳXY嵭r[Y5ŰjTKqenj7feȑV1]WVu=1- O%nXD˜#?J`<,ʆvJcGc;Ð}@H:3zCEp:u rˠHU=ÑJ3g&D3&}c:bwMv:^wCbD&'ֶ9J:H޳T !@@L qgO#\=\ K2Ŵq˄ɜi4 i09&9(.ꗻL1Ϋ~ow?]2ӤrkLH٫w_w7/E)'1ݶË?7Ѐ;8gf٪gEf~.^hlrE: G70,nE&FMFˠ)m}IrZT 4/tuNNt~ό x6gh铃ʭHFc韧k+?ڳu},躳u_]?t_d5{'2#x'=?o/|/ZMΗ]tV1a;̻ZiTSy>Eu:W;DâD($(n)+vSoQq/=k($a!ŀ0S???}zx{ .KsrNW>?~:<^}P, endstream endobj 126 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 130 0 obj << /Length 1358 /Filter /FlateDecode >> stream xڽWK6WȡrWZ4 C&F{h{mVVQr([tR,` gf8h팎_BiDD7|x;y1%(QNKB%џqW]@8$_4] mz1kX A҂G2NH'x}~Qdbei` =9g$y$ <-B]*3OJ5q׷s^_FBэvs_k!s9O,c죓io٨}WkNSٟG- VSw|]$hY_iRC6h(K\O֘ imd'Ë1R)8())+ ulSUN֕T^ }+UccSB.(k҅"+qWؙ#pOdA8pvo@Ug\-8W 5 аU׮MFư׮, $*^Vz~Q[M哮b}W"vvie$=9G\ժzm:0ACўP@00:CyAGUA Kbv=U/ D_)x-ʆ$D7X왗4SխqgAfΆJh Yx뵪_z`V(r#k:+CF(H)f`+ %S$ ?tGeUN(ة(8aYbMR%.0p7/)0ξ-x8qBJC,G-N|yRk_~қ29O`S`B#IOؼlNh2yM_-\== }sa@LЁha T5kelj8Ltqr{=~,Wh7M;rVkӷ{7K'epzՕ 2aJ|&xxWx п-}@ۮmb=o%e'!᭖2=z_;}L"7vr|<YՒM~Oodzpw-.AvSN#X~v\S|p^ (WhD.-' Ʈ*_&b^e۴9rij-+`O`Oҵ$+L\K",=۠+>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC]S]\.}\C|@.T endstream endobj 135 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./DistToNearest-Vignette_files/figure-latex/unnamed-chunk-8-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 136 0 R /BBox [ 0 0 504 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 137 0 R >> /ExtGState << >> /ColorSpace << /sRGB 138 0 R >> >> /Length 1423 /Filter /FlateDecode >> stream xX[od5 ~_Gj\^[qJ A+va.,Ĺ8' 0i}>;q_PR)jeB^?w);JpW Ջw*x ;;2ei%脵Z#@k]<>%ւi J.OAP:V:/;@uQ8H0U6J54 3"3 Qd1L-)<}$y)#f")`BL!(iS 9),Z:}#G.Dȑ㢼<.$3 i՝4.&i ҵإZa]hx@%'q 3 #jя(/ 0tO ǰiz\Sm3 efҳ\V;f)yzI+6be٦PZs m72"$Reҙ`{zE&!bL~ ;WXv#c3UY4MnI&;FUqvS(\e7BU1vSbh\6I34DZܹZJTUuqFRL!+LEickVXH1A =d1 %O,',>Ƚyo%nR麈Zcً/o7on^46XSNh0~33yj">ǀ\}i?**>E^ `792ïZ6,_Ki@!|Sm֞j:CcKºOZ1[?ִ϶ClkhotÛdD7}Y3nl:pdi 3Qϳ:(YuIgu_T_Gm:.{,og[v6AuWn.)W?ěwOw1:yRtJd_NnO~)( endstream endobj 140 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 143 0 obj << /Length 1257 /Filter /FlateDecode >> stream xYmo6_!(FYz p[7ZeGE%eG̅4}<>wxԀ6>ЀnYZJFՑWAjރ :ȷ~]U ϱflƟ(D7>,j}.Ӈn[C&'S6 ŪDe7ۆ{חuQ+S%FcI9u/|nT22&yFAfO=8ƀ(qT'.ӤX{7h2~ڟ@2YeYoF@f!.qm.y$1x>t!uEuٲZwrR=8&۫ rc ]|'Cfikd=oz7焒ʇAg5wS5(^k( l6m9*rFzn:L荧7wgJ5vঙmHW3 53>m7աR 4@F>XG|kvWwǽ=ӶI&"fn+:V#bvݝM{>L[>,X#lTu0@#O>(Y/OxH 1T' 2.c9Aϊ(B)5opз8"*fZ<K ,+/{$Sǩ:#ÄgfKn1R"4E lk\=xN,~/C@ڼ;74wxw_P/i[;mIPq<֒1ujۺ}~ɕ4, _2}i/̀j1Sț3C|R_WYJé$Ӆ @z8$$!4\tL!<JYBjTf 1Q11Wb.f4Z0RSD(%N[V.;j~FkmF( [hldDiUXZg6{ ك*N| 9!C~\etHpU@G~!I`_& `N7ey'HCK-fdQ#ݵh% Z/-*9 $,z6qtDdnV(zGݟ?]ߎ|ݜ=qRl[!( D.y6t< l߇P*sFtt endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 820 /Length 2236 /Filter /FlateDecode >> stream xZ[s~ǯطXjKǓG$V[ PS$C "KQggm!!`i²Ȥf{& A1Y L*uLV\LY b1%= *S)$T[|Dka=NF3El-"2 -`<`vПЉŲ5Y ΃eXk#UL/1bȨ fx,,3p 9DyYtc{U1ɋs55wdR3f@MN͹0~̓55qIfHÆ:if&hPsIͨޒhBI;6EZT5Zdf-oιmr^cQX}ʚ˶XÆ~Jshww7{(Be:lGgDj #-Eσq٘G9+wÿC :d8 .Ң8hI`2NN >ai~Wõmz2Z9]0*Pw\ u{. uP0[L 1NO{NeC~ l A@cBc 􌇺B0z8'jak+gs]ԳNsžKƓ֭~6 endstream endobj 158 0 obj << /Length1 1952 /Length2 22802 /Length3 0 /Length 23965 /Filter /FlateDecode >> stream xڴyeT]6n P]'@pw(P݊wⅢgޙyfVVrz9IPj0Y8ALl̬E%uGS+J 4uqI<s7G0 oJ @ jdКT]\L]@ H"vO?ySs;G;) Ϭ PvxhA3% hiHkdUT5k999 #@RLYS fhihy[15qWSbcvQ1ڛ%ZkWW'~f+7WfG_4m\`; U7[9]%Es IJR9]EbGkS|UU6 W dfj0KZ  ɡO_iI]me>~1Sj6wظ#"`icOl@ɔĔ夥44ĤV_I*xYl|ַ!YH8:8vAS>I::Xk@ Zڀ,,T͉E d?7ҿeV@W+ z[Iפ `ij]|\L݁WDHl< s׷!(HEY:!~cOMJC-A^ %0cK^Ho+S{/EhjjnC.j6b +{[GiGov9Ll{Es;7[ [iHj(3׸e$2wYع` sq|FאXAo.'7W?#O#,bD!^/'E_bofio`1zә;ڿ6VV 7o[8\lo- ;o-o- 7omno4 z gU^M7N+cc7%SWb{=?PL'/7 5צ~?#.9 ڦ7WKTR1U '¬ftKQEZeS@T[m)57jLФ󴙵V+) 8IZ'|=S1( +7 `=JZpX+]D+3]pcLVM z0 5?4.Y9hЂPMw \<A+6xR %[c/[FzXEH Z "8RUD pMEbku`oeׅJ !Uny؅x• Xi:_$ x+}wG61k.DNlDQ-my%m,jV\=e(t/'Ny;p$8wӥ0?u r9}4KLƦ_UA˚.O/{S5ijp%w?:lJ#:_e7jcw1hvtNľ콓;ȇp1xhsLįR$橘/Aq,3kN~uzNRCc na.s`R.Qȳr 3vJy0i,wvA׸Z zl+EI3T{H!|Fd̊ ?$7M2iHDo\ۑk_h 펌4 EO-feZ`iɊO\}nv5hM09cEn$iiQ"ҷŴ"|\LU~MfɵqY׳bfM N8} T,TpfPHF5RXhBaV֔^?L\~8Q[^RPbehvDT'4vRcl;ÏL7T-#@x!š/u)UxLHmrgN|6A?ʍ<9X>Nl_Ğ0`47 UͷZjn)պ $a=トts].s9Bt {7rB|;G~y^jBV] Si[g[tI/|7أa챋RtD;5&M[VkB}}8ʾCjt/CN/^uK<Ca|6x/uC7vu{y)[(_boo<4 aF2feq"9E2HAɞ52"XH<:ΌrWu""|(1z}Ag (}2^i4La5V{ahaJO>do%z"Z4 RnoѴ0Xk?Z:>4tSh 85[Dϒ6 MAgA\姮ɝ #]e7n5W4ႍ{.!U\'}$/;ޤQ1XP;$&ٶ{):~AaY=!d`zcv,l]W+yѺ^+TCCLX{IIj`aߢi_# a(JsBnzeMl`n5E[gޥ&a ̌> $V[mgn:-NQu!q[}9Fz_E?mzY׍Ad'U }YAFiA>!Ε+!cGjT,<[1Bf{/B6x+U;3Q' tvntsc T!aǤ@gG=CNV\]^ UJh>]pǦ[9$xHCa;{}W@[:}Еj |=IȜHwR:gJ SɕմVc?xfFJϛ]]stx1'izdٔ b9?'DHa a¸,H{ʾV=B`(v!|ɵP)xWLbԤa1{S9E-xNY蕄18T: x)|K@(uOsxz`Ŏ"+i0ZY70sxMC:JKcJ MU#p=1 Evѩ@K€Jhtpʆ2i45G[? y9A׿~ZG~.>xS6Dv *z z͗9E\i$1l|򝾪t'٣b;--3Bk9w=ĭŪN ZZ k},QR,c],ڄj0u9|_Sc \ZE0|PeE%+%IiIdP[%snA;pdn|8xgtc;)$|bZͮ,.Z'ǪDNZjnϞz]~G׸.Y(l OL搱fBW26_&m n->tkNm`)\Q)ѰXZ? |'pJ(ZR!k%tY_l0@y6_ ܭ XcU"/)IoHg1g ta7r:ucsJ~ovn/H:nS: E_2 ~@`<ʊxHܭ$#zUD'mFb+瀤xd_퀾ʗ'x ιqS%VR 4, ibDq}riRM!5XKcύ{Jm@$Im˴}*y4VAzTW U vVpsV3ֵ<ّ] A\=C7l/EZn!ÚIYv4b 0) PPmNF.Um6 fLٱ X܅u=-kialeB:2d T @Ue4,?fRݻkaIk+kWw~.lS"'S"z0SFhࣕ]kFpg nXaPaopGw4uJ?U?vqLegؒ;NݩTH][<]F +1k[Ė4~r <3ij*#%:$ a5u{9" 'D omqp۔wck:?(eaL JZ;Ea1xL藏|~?Q'nwRc{ N(J;A~.ѡbfK)Wfa*8F[ΪB<5quuO *Ny)`np~D Ux<̿7Zܱ8~T9LTVaZ!q &,Ef[=P8C׫·(?աec~Av>4E ?)ﯞ5(޼PI\ϙmNQȯl>NYx/~⹶}f U m5cT>4 V)vϲ#᧲(t1DvB$3y8Npڭcmc/릉ؼ_0*?lUQ!5x;~w}QE,;jI?7PB黣~tmHBȜ>ȥL~ g74oHg;wnEUy0jݮ}je5Ow%DRtzN IhJD={mVnG1/^.Yr B0Gme:d-Z ^;^ьiXp.hsE>]f  /?} JҚLbq7KhF[%V?8ۋwVrQlw,;,z"mRk T?b"X P?EC/njffeopRVYZlV1`GWS@H4N'Ѻ5~frz9<8 Rd95A}a/6lHNT-:1aKB1pxw-يplQ<~^N_1?.rx]di1ay*!!gwyԏcF9+Fs_)znz- Þoxr-ç(>S.w{1av^W=߾n`tDlADBDHKI^a 5e򨤲pj;#פC:tY+2CW,w6k^U2y(a+>b ,ÕzL4-$ À;ܹYR2ϏBw! UsqVK5_v|H?[A-u4)2*"-2P#WI,9KtZ_~,Wl$qgđ 9/Y \=xm7x5NGU&m;狻.E db%)8zYO|Y`INP aI\n :{pi/;'gu2K}1JS>SexDXU|8 5hR CanBi&OR.n Hs@4 6%>BZ$xJ>*d߰v~b/.짙qt Ůa6XJؖlu杻FIK~N:f8'8r";[']3Go0jieX55 X*"hsђݯ< &)F*"S<.NUi<DlڥU[a\+ߝ!踄(SN阓mhem2r-qj+_K~[8TLJ|+fB9]mif  `~ZpMTvPˈ[N-3A^֜FP<< RA x||Oڋ#EfRčKo8ketiÌ,/4>7J*[n[1!^V`J#DK̰8Ru,~DLSU!ٰ̼cn^`;@;UH/]Ea]a t62W>;a;хuӈR<ܗU{V2%4{^{-f` 0+y3F Tɢ(6}7<\-bu8# AHTutyg@.TnkV q.P`np">=7V ndC7.2+ݼhwE?E /?,}s]T3/ɣomCHӁ˔I$߾@EU#& 8`<'zi"5f%U0$~?2>ͷw`f˨DfO7(ûԳҊ"eѪ5V:}z[37!'jf&GiVmس%TzX4<#6&[BGs\>/SZDю. pMEh5&[-* Zvϩ-1œm+k`?Qإ zKFnMOi2hn.9qmboJ=“3$xƻ31HC^M⯽>oي=a;ͮ`)y]?ƴ!ZTU(*#;leZ[,/0jܠ8~G&5^J_J4ml߇mG $5vu#̕vO<7ff[JJ@H^w[,4( WJ6yiՒfPڮ-^V7m_%݀'JG;FY;;RD,A|Rɫ>%3m]z(2খϮoH> _-Vx6ZKQ.{yXZ<;seo!odA c1BJW ?Dah4K_v$J6u%B {Q jUQP,IbE"))a+'}mw+ Wk.AoD~ޓ^P'hF10A݂HeaB)<Y1">=fmNuQ). )~JO%gJnuڜ%%V$0+^O376<k\G k+W.,J4}+]=-nr!jR8!EgldH*͐;+*U-ȸȚkܵ.6T~xp8ڼ}\#7-,A?.Xs򐤾Fiv LsC 55G }-<5@% )248QQJԗl=̲kO٩;:BdO0ہ)1*Y?+kFdZxJz }8; MԪ[tMN'7V8dECL\VgވXzÔ !/&Chvaʫ@ZƸ12%bt^eUQ4cQ Y=fʼ, V&6vQM璀u6?q+G"WXAa沞j1IIIkFP jS/,cMXw=.Pl;=m#V}fk'թ4xmɬ6뭩wt=+BӉL&™bd̉YK9fG&%FĶGY{DF$uOGTSFɵ/>~RZ"f" Y{gjc 6Ru Ril"¨SL weHWj!k+EB1Ymuۥ -+(>fQH Mspp m̌8:؛CĞgy=RJradnlJ|'upq[_2Ɋ^9ʡ;\U:3WJYaU(%Pjjˆv*`ym#q)Jü&A[MDHE/i"4>Ozo^wGx͗dNguci 6Aaҥ˹IQmb9Bk&z+Mx!33q"~a@OP7UGNI<>Zچ_yc8"-<=|d8 (O je)U pT+^O٩Y. ,:Aftz%n(JIXIQsDSp;Ll֖ƪ2:>H#].~F&kУrz}+w`znu(FxxW%FwR"-}u,=v$AѤ~#.&+%T(>7bA!ITH /\r6h 07lNSXfߏxkd@ͮWc2J*̥̇LoK`,ogBj܋{]SݧS4S#!mMDy[jS#eşyd/ǐFHbw1+rOΪ, B80zT>*RZq@PGt3jy_c 'lDzΚR82f;c|hgHB=!bq;Dwl+;~LyK =тPmwVE9 dct%$8b%Y,.D:_  R}R0?}I-@8UM/~VGEΜ4zwGJ^![2TiJ;2QA"$N2OdݐϜ̀.ffyvpt~9՞轤َ}6Y> ihˌ~r gYP{U:!lZW m`n`V#ѧ&.XVHojyԋs k*e{DRQ@(;gdDr,&${KҖ:гԱm)!3znMS▒"J-e _ho9IϹ*i*z\4ŐK9K$1M{/4Wg~4(nl^4#ka_j%|0›SrOܘ} ն`G u{Yp|Ry:[$5y/X=oY+΃lJq* h)F}4U]fh7>ڊ/1,$~n:L D.']lIogF31c45Y<Q}aAy:I~fW_Y-gPW^]v-Ԩ N*ޞ{u()M,?~bXg~p%scf[<\/q &1cR8jW(@~/>i[ R^8Oh{;aSni&*쪦}"4^{CƊ(^FsDVһ.8~WEx4,[`22 1cm֐d~SZ:(Ry{r"a}}la.7eK&k$T~~qgZ"(1|%pXm.)*V,zPqn2ȵ*q";W{z|D 7)#-~$qMe:4+U; k$ we:Ŏdf9*&j1Gqf?AY?^!飐OfgT߉ 3fx[I mĄvxU-Qeqٔ)Rc;Fj058T sH!v2'ǖE?j Bߵ1ePN;ì8Ut%'q`L N83Y9ҼG泍z dlU>Ԗ ^"x`MFK)<ۘl+\:Ԩ$/ &1=N%Yt5P"S}4QܩxwuӢLyk<o:^ QH4+J;za['MjժGeNJu󯼶p&0V8 K0EE%2.H Ish[+'?ixƞ`~  BHΏO{#j 򕓗t RYy(D=*0Vޮ;Cy%x{884gLYlWAb+"gs 9m~:yS6 J{: a'JM` ~6aΣohnUMgz:;AE2%2˗_y6a-*rÉv5VOP0<{Ѕ.%ٷ1D֑;K$͹a:MU&ڥ4֯ LKPGO?\NQw9%'P:F|y[/ۓDdhV6Q6OMc>/kVNVpiսU`anG8N d U1"Sݘv+K+N˵8[%SloY&]{\#UBY, |z5J&3GxJK˨^^Y)*B=6< '3ٖmWQ(ObP hx:2BI>Ѽ`JlzYՕ^kAv B+hVHԪR5@{I [m-Uժ݅V"+\=INW67v&7gݏI^]!Š'?GP/JkStPт,nGƁ㾰LZׁ/`DY.cLٝ ~a b.Y6fy4:VhKŗ_187YGW6;xl}&7:.LYx1b TݿAt;|U}xm\'yu0w=y_Պm?,74àr–*)b9Ib{|ė @$ސdH CW}F~(P?X 3O$)j:HK)B3>4ɝD2Y #La:aeL)EUJQ*=;)TɓĶn$he;5T=i \;b^'&'߿ll|b`[U$|m3q+7\Nؽƣj7_)_, dPc8FfNVˌvH*@OjUc8+D+AfNͪH)#?nV[ZSֻ) d~q]3уs<h-Vb  P:?~#YBnm؀>u&႖]KHEa٤SSi19b49!c 4pkQh_ LVhS =հ㜳htd'o9\ GUOl6d9Q O9M y"bZC_H\2u|E9S|#6;ѽ-2ޓpk XVD#ǣJ{96V?WgĄmAy絩{PQk H~)Lu'o@W9*O3z.5;K/v rʲlA*b-\{ !Κ }Cflf-ˌy}`Y؂Ҫ)FBvw Nk&0zNyVo8M*l L_>eb "x創G}.!ȸt#8*yR_jn9ԫ2ܿJQ8XABj!"Am ua9x%4b/[{N$N yÎs*ג5n 訧 u6!Y%h6d;%TC ̞ťTv`^oa==f`3G7U7*.FGC]l_pB\D8yQ̹s#wD l+AC WKƙ0.D0دy=Qq)x( GbI%ר;[%8GY١}4PF*u:Aخg<H'7ydJ<+ })oibBqՁ^daDKm( L|>SOs +@w؄jg$ !cB#T@Fy3!l ?Gv zlZR/U_7 ZaqMWT*! *ڣ<.T|K,+k\nRVw(FjsWS|&7 8B4w>,ps-zVgN2F$Iߧl;U$N #|Iю`+oc|F􁄠?* Oz#siʏӰ/21z֩m,; zf5H'aC6_HrBPc}|)$BLDKoV&RK?.f'’(( aCsmqnOzݩjr !g)8Re2u| {XbNP%ޮK@DG5t 'd6n u][wbK%x8.ֹ>^t9-A" ftͫн}ކ; Cj} ςJJI~m _afK5+Iboĸ D_ᓓh@t"+P,fy_ Mhl\:3}#G)&/TI_ 01]r"p~z+]2lD,,7-I4Y{+#AbJbLیH=67L0&yܻ5&ׅnMei̠ybk&pU& M16d5yb3Lj\>HYcGgwsZ,F*h,eׄC(]43GE)H3q87a_aÆYm+g0lw%nA{ً{CzX6lSYjZ\U <NU=s_yR*15dWQA9d-=ou?m~ įB`n7&[ LETDumQB8}q7N-Y'Yꙡ?eF3^HΒ cѼ*$F?#3HTY D5> uˁ( цg~`P,$_+}mU:%qMւܼ!\LrbY`/8@t?6֩{%rJYLW\0[]p*%[5u_k1-2$9eb7dx0{Pj?}*D*X[_YmÑЧ-]C?]]i'Ϻ#v]HsȯX^|>浀@ƕ"G(_&ޯ" ?*z&j^sI_GĚх/xs._J?kEI?N Cbpr;OyAӒ9ϡT?en4r\ PWo A7 wx ;Xا]GqZ#;n/VQŗ>t]d`F"Qnw}le;ǥK FI_Go{ΦaRM|_젃[ezI > )[P(b1Ǖ;w:5̦ЮPeu.i%.ߕrV7j<;lѮ;$%m6UˣtY!{fbİ:.{P ziY)&`BАm֯Xɝ"X1'>z]]5aߛNq'׆[ l:KAz!ֆmRW^YSmU:(.]o; 1F;z ߰VDq:{.'+/q{,Ywd0) / ɛPArNW HFëQWRl2y*6Ƽ*aɁLoU FFq4`v!n؂`d$ Y ʖ*{ #@țKeI$G]GaDMoԟ5vM SC=0C$_m3&ĜHv'w(mC[1 /Ĕ|ϗmAspSLbj)#i 9/D X8ud (߉sZYK]1[~Lloڙ2WyNO81m?A֥BR#Йoc!PkNn7j,7/ı1ۗ{GrTp 0H`#:mu)([Β7$LzMzt<ܷ[Wz{`K[vriCh=A%Ɗ؊euSsi(Q gs%We`v W\x1F(BthW(>"Eϒ֍g bM{}fH#y1A\XeNbm$f O؁E12 ,]$YEfe1VRKmH˖-T\`K;3`@fu%!Y n 1UA7ŵ-[_Grx,$m:/;7_4}!J0V5kƯ{88SbqjA:oѾOXEӔʫzLlZ6Ta}kmWRXschKƎwP ?yTbf ;r2F?G_g~:F0@yҍA"HMAyiS0t6_^քvՊ[Eʤ#N;fšB:dĨ0@:Z*h=>h󪤓^HgJsgs3g vv?i>SU犜~ :6?lѽO%-UDȋي- Wy_q]Z7@)M{\fTK3MYʉCw![x췬֥=ۓe%⹋f5bn8}6Q5v %> (|BEYDjmweAP7q2V %7ʒ%l7pf.HI|0YD^+WNgt* \V'Yhioۇ7qq^CGZրݠhptv-0$A?R0i3@8t 2пpz?rlUm\դɴ>w+u5n^fV;^][HzsMYl(> P-I3I+"?;lЧ`A4loX"t 5 rXqv.vLFR^iA8Ӱp=G*[ʑֱ2++&2iC! AMf6h񿤒;ءq H~_]7d(:/m:_<2Jb&*Xd]G23i7'@/;7P?]jg79q,Bv 6P o3tscxupHde9#TmeƝ3MFt@qaY2phߞb8[O.WQ [C~'5 85` 82 fyԭ1+vHVhiOB8 ]4Lxr8.(fT~qUJDw4ń8 ݰhGF(T*6]Qۤ=K?k5BM羓ۅsfvuhn83R]I (nK':c閈"|La$ur(oJsOȓp 9Ao&)0P[.A4Y17qhdX,e˳5f,.s*Y61$lOבJ?FM[(=_H!AĨ\E}1{_t`ַمlޞHڟ1T#{rTtтz1<@ga%t"ظ.wyHZ,q@+x4%*_"UuyoHwKu`5O*Q/5!LArFdнsYiPDA}{^3႖DЫj뗧`wv,"T̋)Xo>kʭX0T_:#JkLRcpv6Հ,oTwqY9N.y/bW 3/i֧E z tt%RM,2 a{Sڇlf\.rNIr™|t^zeKnv%yZ2ϱ,SX+;H5g)4q8,?q꺓3z!sAUedraUeRz H@x|bzvoVʋV̹2HFoXIy4R6ՂGn2P:C$%)~6(.D8gK[Sc[J`\vKv} +CfILɁA@e nY+ }KMVĠ̳-EYU|sn_A-K3u8 3YD{v/~HP,2vej1:ugl>a*16upQf!Ao oBØ(4\mK.F`8{.V&')Ja͚MF{RCɰ|5H4>¦N#0 ٤ap2Mlu|+&ڐ>kn2)oڒ*=_tsC0^pƤ.]w~ʤcrlww { 躩Д^cy [?yGJu@;-s-s&zĥd'E/ %q.*Ki`|F|'2LzZ*dWrvH{A)5LanxaQ/F/O- _.6;AA|#Hgz5KxĴef_'MKDOS}4G2jljSgpxgQW݇- endstream endobj 160 0 obj << /Length1 1997 /Length2 22880 /Length3 0 /Length 24086 /Filter /FlateDecode >> stream xڴzctdmv:vFŶm۶Y1:I6:vcv~杙gfoժ:um^gZEFB'd 46ڻ13rd唁vFLt@[S3=##+,^Ōb P0qpt032r$͜>cO/tv36rP[XٛQ}<,,]`鏷0=@lc07HB+%`lfidkT4j*b* e5E**@"&A W$TT|ȫ~0.'*(L73'g?i3};Jtqqf`pwwpuv:Y;Ot|l*G9],ϒdL8(Ӈ_> '?ff/_YEEYɇ3/̔"NNrS4. 83][/#^1#{W/ Vf;Y3+drBRb*tgO'=_ r8L\Ə&7}vS>Q:<m^-575SuSW5{+GW3)[fa`9^W'eZ|4F+9o)ڤT;ho 053e|4=_]mm(medgevea*pr03Ur1GU!r1hz!{ [Kg~4б3tLlE{3gg;_*ߏa `ВvHhjeo`fc99y2~3飕M?8 ~vH7`pG^C揼y=&_L79#'+Ə]!x$ 0Ë@`b854k|?Q0303]^[k -+* ?הN_N&6( h /Jr&k۾~5U1EQW ̐[/ILu$U:іFP=<|B[޶^4Ԍdⱄwi'hqF=BԳҐݝHZ7$ $U|.[N~G7.eh3@S$ՀLVY^tyZm Α!玆nF B4I έh-˝lci?8AR;(h'ai<9ZFc ns:`rZn4i)g',/215]c'P8-7{Fۤq{cBM\K.6KMÓ0B5'qk\fDRn0oh{-I?9̡ûѠU?,UK3-S>WJ.~q$h:Rv;yQ Y,NRFSFv"nMd2mA@/"YrvyF؂ל^p U ^?˕K4s_ 65G]c0sj;+x`QSXdytXIje#> _/ݯߍoʈipzM!3R HNrôԖjZn:!$!κ:5x]{D\ 9L(.WiG981Dv@obʜ]m!f#/P@c$iYZ=YQ>,;}~Qx &Il:Y}TFOSk'ֱnn̦#NֽcIV7=8]} H|_t,hPB_3yccYm0y:cy m]=|);*UZSٽVlȒN`I1=)[\ KW$8ޜVyQ[X-p$~aƁܨg9qv$:VBb1gt-?=lkxlztVG1^$ Tiх;WWw"&#'2L_N$#06H~#X=`rQ$ly{f-  I;#>;"X2OY`+,{=@2 )jѻBY]DvuFȣw稊dGc͇?8 &=UyL@a`lki(f6I>m#rxτe$U ! +ݞ eS 1 Y;erKKߢw2'd@ʣ;&7 ܘ%/7I{ֻu;LMR&onY.i֣n{r¬tXZ"-G~KYIq-Ilt t-F UYN_m#Y<wYH- c,߀ݒL$tڣ ňb6udU oc>ixSxW)kGZ%v]!5x3#[NzN"ѕ^^A]Bڏҽ1!DۀԘi:stюSܭkP^Sc@ bT㽗䪬b5bqqW6HM Ot F:#S~l!Y+ Ҡ\2:L2%ΐxdaD~Ug/BgW3pNb WY5JwJi`LuH&TʴI(HJ%\?p8;ڷ'3!"`{g_6 > }'L.#V$$jDBtke$C<8l1'R!cz3Y,O`ys&ieX./&+Hr i{-N`dTԫjfJW63_Dsۖ U+ 8#(B6AW˒zɀ>؜!b]vG˷"*i&1ZK厄@ީςXWvf.\d).Q.4L%=(ߦf)u?4Żܟ Ueh>Jtd?-Tm!E@0i!xh[GIs]dD d8rlN Po?Q}>su}^ }K );Zj9\ .3%)2 \;ǡ4l>Fl5uVeo,h؋[I$Vh'w'O!l3~1SM 7G Gz&[QiE^6Sr wKSTy{hN(F` =9t @4q=AQooIX!d Ʋ笤H`˘a.dB+UcIkN߽򑺌V3N_ԭ7>MǖUŴ ]0Se/S2O`2q`(Ɣ{`7U ,^ɬFl πp?%odzX id#r9(Dh>`N9 %J`QE)*^W,DCl ~_G0eMW ]A9itzNӈO OEk )ST%mLE6:22X0H@lo}doјt |G&a t" h.BR fIH)X֫#Hfbl=8/mWⰔҩzT[ RY:HRWPjA$nua1 5# Ir.\> .+d~:Ck _) %9} pR$YgsL҉ }xwPs+ۓ\te%b/(5{[ך/n!OKf=0hjv1]X^҉'tP !ZMFlo+`u[:c Q00KseN1*uO`Sb;Dvt`"vʁ>LrtXjnL#W钣BIsedu=; /۝l9 _6Nrhh3K=Rt=C>*~y䃒xro])ϋSnl~KݰO"jPw@$~niaG nECl&49w|ng` oN  $I ^lDJ*}#ySQI<ŧyԆT_b85ϏY<]ueAsx!~>!a痂rl[YJ[FR~ B<[.L)KZzI湜hxXx'//X+?}ڍ[X{V, q-N%FPW7^\Eu5G0&;4ј&Z %)}'D[@cp ہxcVR3CFk:BF-((ˏ%:taD 1/(*@׿%͒LK3a/ߟ9D|;Aؾ!.ߟG=tL_Fc>Yi_)U"֛"K Mmw!l74r6p#brSIRݳz<us} P;>H1HߜԌ3vtL /_:TQ.p$,@[m5kU~ShT΁1%,ZQѪ8Ңn*S) !AX)_TC8fĉK z ᢳkZ1jgj^.gۈKFj(ؾ m%o &A.-6PKܲ0DZGuP:7V ]c"!o+(Y]}?c*`%:@ʼnZȈ=KfuT Şc[T^pǷ*ݦ üB#CTKbDMZ'M j>ģFU K;p-؉-xg~՛{_pCJU)Z{:;8KǢR;mlRy^ b@ )SB$R^D㞮6abKU} 45ؠrMSݽ|WYkwcufY_ S)i ڕA)QL楯~e('$e˿(/#,Yu!\T*-ezp'ˋ\]LgƵYHbr,b)j۬H0~"*MXjw34| m<s2u|c V;N%0,NC7{0^؆ H!JM2Rƴ;GB,ìua ι_QIN[,} B?ԝ"=#n&!@& - x  }F5Aɞ2Uh\^6ŖFJr`z-_/\}gҞndwXqXnbENelrr[Ohs2y'˫gr.u(҂ZsI 6^Z!4Z7L;_'2=:[īdzq.&UD3pGDC)R)XvXWrQ[WdJLqY/oӕLOɓzxǎ~BHZc<('\ػx^B[;N^/E3 >3`,IHgXjChky\G!Q(Tc,"HU5˼d5maQ`7Bň!TlN2ű#oĵ9PhZ}u fH vpѧ?T@,` v u / |Ľy4akj-S&xZ>mS}R)#]D-cuNNRi11,OSG=nܡ|畢O34_c~F@FGI^L (mKAf6^n7  R9cHz@XH#U$e{? Q3 *%( zEY\Ac=Ο'גzQҞeŸ3 ywl3`|jNbiC5L2:9d[+؄g B3xg <`# 3z`N)~ϧY(+|ΘSp?DMK8xŒmh4H;u3 j z|xR}ö7wݤ1w[0v]z pmqH/Fl7~,/,rC¶wAs*<7Xg L5㩐,zYO5C~#"{E ,? ^oAf;!ҧҲHyVTA[P+]{@M1A`f;ekdW:eݴ4K@мgN! A"':4x*dˆURa*d;(b, AkWgZɌjAdb { S,rSx/heM]f$1̔r@XS9EKVzD3=u*"uN7M(BMGTrNjq:ߵqS߅I!vw>[jKs,))gd2l{Q^aJ]erZuS60Ak?7#&Ӻ0N9"wBpi|Q LST<)$qieT?[*dX8 !8b.n a^uEU ѩlL{r+|74*]- Yݛ,@3UI8im܇{d@r~0,xg_[%?d{pÓQrma-~ɒI7QеƷqp^)['WjH: ) zi@V~+!u΅3FSs`-?o#޳Vuŀgj F(NFAǖ7cfs,=nEܐ2!/f/ YTBA+ߋs=;ŵ1A¸Jk,,H!@f2 X|@xy/_BLtflUgG{m |!7nDN.z%>>{-`7v4&X f TFĝ:VPv.^TE/\U?qDZ.MobRf`_E,ytcP;RC i*_E6NO`3F8 n=}hl-:aLʭ\_G֟¯ 1>Z25u}K)r>4ws9זO&_~,^PYDna+$ o3=JQm/5cmN{INB}Ąg!3GF823*)Xvws{(O KE,E*l (CX԰3EҮviݑF*c+6̯jDD[k2wfq#WC!-\ˣVb+|]<#cL{CZ&.G1^o Fl8+{2><nI, )|y ҁ%KIzP8usRDnX9Wfl[biowx&~|ֹ\Gl\l'tv~rD[s8Y)9*-_4/0'G7zmR, XK`r&V؆m-Fd78$9*Cքf^ky}]]sb2/;5M~v$k;:[o0~넑-|j͌7T4ZyIOMf"m|WEٳN ]3t%hTHϏ3z{lxtU_ֻk Qmҙ4@̳"R D wΝPr9 ϕ'}՚:RAH񌏎5'ADRɗMW=LfXʼnX9 \RXJ* tqtf]?5-PB'*ɰ&SAOg֦6 f!u"*52I]c8]~ Q%ap5pXDkH$z9i9rrP@I5unٓ|Zj`%&/6~PJWӌmxҽ<֘* ҷ_&6۟Ll KYL3)$+<ۄ3ѿ6ZKkRؘݩ"NʰL i{|Ar|6%Q [ijHND36=7U,x_#޳ke1`4Pq;E Kw@Iмح`tfo@{6 D +&_("Tg%VHٸxz~7>%zu8pA*LkG6n/L3)4pf*' ^$ f69Ix䜵YF&g]z~پoS:+&M85YRos;9Az3q9?p9 ߟ6~夨g-o.Q5k M#AHvтA(!-n=۔wEh.%S@V\hҶEK'Ҁ:Mf-?j4:.ePoD0߿ Ȅƚu"ŵVK3wÃ0nF9ͻ9OEm~d-]۵m!U*Â0"Ճ\ׯrY2(rBZ m)g0u-wpxqf瀌!:J%bA}FN\u2Ge,`:NfpIMu sE^u:I]u$jxs WVNcʎF8l=핖9>?36fݳ,8Z1ǯ;H3BfpT1xoKPehG4$PWs^ R7ePz!qzxq}o{$@Jē|[H6ۦX7hҞ0`8Gwtnܗi񍫽!\kQ(.._)ElX ]ߠ1;5,0bi9ܚdٯ&^X[P[$vVۄr}g>@_oBLc ̸:<"xewT긐D U}>Hvw:1*޶]KGI]IMxnz n_Y`.pFP^/IG`0T2v9]B&/8/Y*Ժ!:59)0|g0` X*_oh"JӇ`\~2]5FabBR>e]"K|_ok:j˪`A4޼ʙs9`C Ͷз>aN|BO{Bah#ErMu(* .94ǫ r&{bIHP! ֻ}&$ ڹ1r:[8y1~lnj8V:A󼒱26G?xʶcfFpuekYdcbc FzA]αɿrGF >&q`>&<;3&ffɌ$}UYf a*OyeLz6+|+,QQtX_\VLpaͨi'$-wN%j[ ]u}K8Rz*!vf0^9XR4I={@L2˫rCt+ZP<%N?{k6CI+7/I+ 8huRk63Tq.7hJ W'-oԳ_uK px6jmsn}Þg`a/X$h-V>HRp䠉hPꭚ׬;3DZ:#CE#nUs9NΏc+0[ojb#35)`qRW?VQE`ѻRZ]G@f_R@nlV7˿KE!ي&%B 8᳟ K 2 m70 mDCjfsD] hU IN7l"XO'7h+sŬ[FO=yGzBmRϺF/頽}3]U-K׼d &5sq1]F0Ͽ%rc|]c%:ahsNDQ˥%4DұM3V#W{ƂIwWq'16NIݰ3B@rWжnY񆛘; Wo{/N_ܽxe[Р)F)aG"#?x!wm4LQ`o"UF&Ls U[ a։A"3xl׻}ۛ|m"Y3fomuݒ3L QL2ɮꀤ lǎ2U& 3;{ kmhPtQ鎎_Ay'P]>G6F %>eD(wrc`MšRS"Qx,C',\}y!SLa_))an7IӉ$FBfb"̶-uܝS+IFU W vd3~lsoԤ8ψ%$rfvn=\veCwcȺd$=7zuк!I?n:e+aP5E8^$M,GaqAglV} {m*/{x΃~M0Ӈj+p>Wbe讔lQR+#M-f*U H Q JMω!xvfB0-Kwh[+Fh /y,Z3<˾gㇲGq+7gEL u SFR#52C$Qd)M0D `\-*fD$zƹG"7(s96") u%4",T ʦf IaRT@9އi!1x(Vp"֌B 㝩(\,Wˆ 6^ DgX$ްa#RW07@yК+?dmp^ vbGՓڌG:SL(B:f?C(ƂI>X] s(H/y A}. .aڇ/#$pTDhAq Prkf }&ĖqS~w`c}$znH1~QXATĒȎpu'g+I~#INMhMMgyhb\֪1[߶l]zшWxP_d(_ޞLnas hx(RaV ^>a";ڮ?Y\ w{F{~OϵJ%w&T% n\Ftї[̬V.rn8%齿a $ۤo|Ъ  .+^ݯY.BK$sFLG9TbU@H?s^#R{*M{33o/i屎%>ִAݏ218>3. Ը%L*uֺjlû>zikݖeB#M<c%NjΓlqFٯI:/9jKgBA}`WH%AAߺ✫ܶܺ!/6 :7iR1aH)s>6ʷMՍbuc^lg,zJR_o[`BpX+S Av'Q9lRIZ++L8ljCs@kHb7 {)Y={'F;rɉhimȷw"/{] GafF-Oj8P0.$]KT~v~#7kbO^y0AkeM |WT.T!$W/tAl`FPM(:/3P Gb߮;N\Z]{xIہLxnn"hnvrPB0--9%.=oK29ݗ2xzǬq%R:eq=W&t2Ѣ 5RZ I^Vb?!gfh[߻+>*VP!H,6\ l Gѕcm&[~q:悩 :VЛU`/$)0V&v?&zg-2(%Hb0l!5glg^a:8%.o֜c#7yLQ!))z*z ԇ P!V}*V.]2Iv;3QߦOOUe8st~s6 v窍dBO8P\x$/Pk_#^bVz|%6 RNqo-; o[}~ٰΰ UJ X4*g,Ѳ0x.YR$R\exN,l"-c U7OZ.pzʙB`ۘ` %hZR 퇟a'Q|Nmqa2T脱2D h.9YVDF(iRbПVO){Dp$tod(#{AZ33y-$pdg'L֋0ɞːc;ȅQ]b}g!Zg4Nx#2p)Kp4ϯ>Y>9,1%xnˍץ~5Zϳ1ĕIJŽ養vy[И#;ʽ: Agh --BQL fOhR7VN52^:Q Eؾcԯ|X1"Ik5x̽PϤoX|w8W rMD;)F*90@Y,)ĚE*[*3>h뛁&wry0՚0}o_[BvkK]kLt_O_BO%9XHyZ]I\njl ī@"/w̢"y/Μ.޼;ad|] "C!T!ޟ`0lV]( 6 ^~B{U ~{+$C ([{fG*C}TzƛԐDJvaˊ5ykFWdAUwBXLכi ~M}w}d[tORu,"L[,^dw$hD[Ϛ-{,$mп^MvۜQIW*'N i6&-έ,l͵7-$͐5Óxʞ+^btClD[A44^lc|IdZ3m+SxD]ֈz.:/ZΐL+܊uRt!+9(QTY$`9k?)8-?Y :WGx:P*d/s5GtTpJ@5 $ lQM#D1a;$~ud)}<;gp ξ$v$>$BЫ~Ś,h_Ը)yU!Cq급dN6BhtSnr8ؤt: ?%;r2"\}Ne{81vW PPpޘoڼo0_346kZCI &ȁ.^R,FE)a8yl>TSfgpmr,[렇ֶp#J4'N@59C.fWowM`VaYPZfVǻ fLNΦES6OIgJ׈7U#žSTB~6%TEGwݮVpY-wKq-dl;>) (hTMRkfxnr$á,T~~nv4 qiC\YbY n0TX+;.T|K,+j$m"/ #TZ.;a.ݦ ʢ195)Cb\Ob89>ƫ&MwA{ sIIZhu҇J+3؉)UCAxl=_7I7f5"G)hBS/WK4}~C> FiQ) 3+vMHF-s W `7X5mV*[!+H;mB=ݼ0)kLVba{Ҧ(9#h֌(` ?T 6OuwE}lIۺ2i2 =qsƗ4c_ \`DQɝ2.BqE?G}u?HNDDfQ&04I\$,M߉? T~d=cg1eUKm1ܱ-.a~\D,.;n3@QJ_E̛ A\NmNZ((i R9*XMXX;rː/Y#ʪcĞf^"A3 $U]Tfi\i=6bb(Kj^7`C8!f"ܖ<=*jNbM )z vbo$1T$V`D(cv="&rYϰ;dgIEOlE~CB8J*fWԃ)Nϐ}JGUX-(nafIHZt5fxiŮ )ꕕlQ9qc} 8an.XT2~\z] `_9Q>Wu/9/K^x[N~4 ٧ krL8 /+/9Kϙ!8(տ9^ }pi{sU"ģ~MWQ>B{ur(n p.+z`bԌ!!EvpX?WUUsViؾ+iKYb*.cӗjxٖmǫY?x. +Iј#ms[-)SUq/.\Z B,nPWg}B;1'c~Cu^2Q油uk1x0uAH(p\Iܘ__ؑ{,ڪlDPp^쾀0z67cTHZ GZmfʟ !ٚ_籔S?11z fCHǨD癁(klܲ쳆{[©_ZS m^>P/a #T3@ IU")tYtY?2 t8#-w{z\)EWv\Hva/2}X$Rb?x?(x>jEXn,ŔM}l/'zģB_+Ze%m .?AfM>N@FAkn:g*Q{LT )X=}q񾏤T*jDC.MO=z{aHWi\ S+Dぎs,hZLM8FK|5o4f|y)7dtd(ת?@~ V!U "EH\nqTҮiHQ?1(X!hNʂV~'gPTFG&-,R]vؽ(+T @$=#Mtt{eb1͔LY),nRoYQp&,uElKX=a;*p|<r /ზ¸W yyJ͌ѱ1 uB7ɐQxgC:sif3L׵FRjXF%Ih'&dzD fsJBH2,U$<~dTe.$6qG%*UD8Ue3xw5: ""&FR8pXR tf0Xl`Gumf|Crt 5MQoM HgO Ҿx>VH01ŻWel9 Iӯ~nhuW|8Ok @hݲ[фy|[su8Q](m}PgTuGH!mDwiYo{ZTq|u"0N!";ˠ~QE(r,=OGJGMl륷ZU HKT;A)vw:2 b7NO""[҇JJl%8O.V5M:ۓݫxKB0e ҮBQy~֔׽ÁqG|,BɱTt>n3ISEN~5w`Op%Ǻ6Ň <OFL[V`"F;u84GmJ@VZ=q8zn[zz$:G:s FBJ6kfƬ7;QN( & ,1k yWz$Ȗ%Y:l0oG<. @l9H.Dw;Y<@fL' [ g6SK Y3d{V}N E@L]uHEsof4Tw)D. #?B@#ysGfNHi_$?Q^R34qq |{gǬLͫWK?_F7];瓱J$6[c=> 3nޝ1ˆ(T _AqMA_D o Fo)H'6 BsQW\~qj3GϣnO۴-g,x 5!8RdXoLjyf--/}C+.p˹oI';,PU$I0Lm3#@*|{'bnLeb˴2V3T&wrN* d;ϓe <22 ^%q㖖Ò552yr{l3MQfفNJ< *7 Y(7G Mtt0 F9J5CSB|KG ů%܅Bf?Ød'˧r𢌌3%*KŽAq4R6ܱ Qer2T!B:+- Ăc3Sv4u{ iT5Ech6&hMKCSVc+I7]3X7(nU>YbI#mM E.i C<5f&@ 7oPrr2aM+uSsEDpEI,(N |5]|p p {f}$[ˈnVkQu@N3|ihbnb+ ]j#PʻibQ^S.a-ֽw)}Qݕ+$K>"(Hl4#3U~7d}'M ]4@lzCc\=ǰ3{h\z"2ED f4AOeZv)4u44.w Io/(;p# "{BljcP s].W j p-sBI:Ob+IaY%6/yX`nE*i8 ڤe6g+K_ =7+^ܼt,KEhH:) _R:.x%ꅊ%jX 3L;Dl(c+/t}韺G>U(Ne$x[ ~7s jh1u}#Nb{eJ7QϹǥU k+߭3JǙ pR,5*dF&]E{N|U4l!:*Q\'ɲD)Y4OfQXw]Ƥ +"e@J YK#wLdk3>8i)^@ WPa q9nNqgbhb]urwiT=[g_X=Pq]1ױ50 Nl.}ÀNI?qs%'Z*Q.ךsrI7! nNKVA}nΪؗ;]]a8~-8~B[Jy"2::GOfKPh8,vdDS"fm_H 9p~TXӖЄ.Ję>uoav7ڋ9:0sBGR{6c;lF '_FC `yU} i%<ǵ6M3TVPP/#DV 3csqsWW EL"i:#6 i}uz3{0WFZn#`}0oz|$9qtJ9tÎ2.x!gSƔx_M ҩr[P|O|xIq?{[;01uOk9k,O'SPd]\oɩ\Gcq{A&}l'$4^5Pgq4Ssx`+mrhd#:O ,Q\4gn]ێ13mC#{-՗\JӓM%Cׯz<Zb*Ň$vNKa _zFPb`*QͬAj$r|Zޱ4A#8j󸈤ݠmx=hQ`'*M6wa ojͽe+ g 5Kq#|%q\D+/0_`@{<Uy_CJPi.!(p +9>kbbvv3fA}9UE{_AT%5Gvy([u);*^&is(k4fe6YV_ 1_&}^Ņ^uXo嗓]>?,\Yi[ބ endstream endobj 162 0 obj << /Length1 2648 /Length2 31479 /Length3 0 /Length 32965 /Filter /FlateDecode >> stream xڴeT\ͺ5;ww qwwkpww'X CHy9;|`@35Z1$UVc1s0J:ػ22TYYUn6&JJ1g+j P2u"XXx(R@{3i0(]ս+ ҂R,,]`gd]w(@ `loeR`(:xV{ `Pj4$TRJjLjnELM]C ..j24Tڃ[0A}@$EԵ%X p:Xn_ܨ@R͝ituucf`psqerp`r t $%_~ @h$/HJPob !\״W86.++쌭]@WcW7?67Ќ_17g=6K]2=[?c1c{7￴e:ػX"`ne YcSQPSg =H{&WOpXy9,!7svA-H'Wg/;6>o5쭜܀22!Y],ij? `nl2>|\݁Wg7ߎD3+SWШ ?e2柣J :f^39+h$h9iKVH4@c;+[ limg"i 4Sr5˸_ږL-hvA _>X]\J/ 0ITcO `l6NN+h̀ pts;8#P.NoӿY0A<f?,o`XRYb0AA~ ҿ(OA5hA5hA PM#^߈t8[ -߈o9qwdo 7uriR/ ?G~'7cۿR@\@6s?%Cjwps(/"i2HOK/GK_ _/R/Ro zv +h*sRAG/?hȀ Z71a 4#XCI9dvm_곂p K'Vв]p w[c˿J bj ks@+pp+T//㯭e{A U:6ʿ^5sc[ O%E1pNhi'N.kk8DUl߮\~^H[y~N| sM81SBSKu^/#Xu{ &,qzPyup)pUXJμe\^B/X,[O;"i.m=ab]™?KχWYEj'=ֽ7e3nHKW!@V^&6؋(-e4c!kt%ȱO9B@|i&$0|X6~;mOQ0Lك`11SU2w5N&/{gP!ʼrJ2F%/k#|4;ƒŰs5l2) s^,WPO;t !]dp1?I=3j1ƼνO8[+x֖7@U7Ԩ`YId %j{aڙqܝ@d.nJ*ҷec"F4LɳoF yJ8Ta;I1<&A5zO4svt ֈ]\ڟDOhckwKxLIHsCk86׾!še*S&}Oi=s<@Vp~ת[2FA`Tx`pKmkI)`ScX<'BhS?DM! 5ӂXL6#HW"6;fZ';<t5ʓ8ڰZ\_x'$jٝ_v vs;Т4{ YoHsqǧ` '?:L'Q#GӦ,JowspVl lѺo6Ճ}3B`<YqQt >Kl{dd!3NV]-aIcd4f^3zrT I:;">HrpE6nY)|d8f0%c}h ߇x{ z(.F{Y.l<\焹1>u<9Q{yH-rrG= ZfzW7kKc:ZRM BS tF$w0[{3)p誶jχcÌo¥d<X__u pɡM"bU3"u!f hDE+.ބosWmVD0x8߯PϾOj&6D5>PvIF+6-Qv9Is~IBtÐK[e\?-2W0zmVYYƊƎhj݋FCY˵%U󅂮kAb\/8t (T<(u4/~UDqk鑴[#HV~慱UɯVnHI[&m|ev$R:KSPޯt )"dݜ(^VE2IU$|2m1-/$½dH{%9P0%B`Af|L9^zcL;yHGbZ5bՏ/aQB 0({Wau6|;yW07X>+&_ $Bn%bgߢ!A6>%\"]ZSAy# _5t`8Pakof%K; < ^m]]8 }{g9Uѡ휺땙?YC&r@g*'ɇ_+,fx`h69Ks/njAQDw m_j9qfB=v>-Tl9P\1׆GuJ#ߑU:V!1M#6\Z$ Urʂ3FYy21 |T l اGoT>s?~6qA}#3Rvu3@#bmDBVyُ _PfnWamL)b_#"k|1|Ď5FcW;x ^d_*]sv&QdFޟ#5?PFO򹡤,W.sv9L g-u)7r9ꦆNّ W ? |E+oQ-iO}>.K<STrwwv\1Vb뼇ٸ,n,[_YϚԨSXNU q|Rǯ|B4"=ڃB}l:\|E ܺs-Mj.eLʟl qO/]Ms)z'kaz!+&:֡'5 $VAB5>fF.iM>dc Y=k=EQ82R>6srE;n[@̽5 '7 ( E{‾5o8(x'RY(Ƭ,zAO~r˙{ &Ptd1 y`l`S^YH_Q"%+ %TYkxa)=\/R340 ț.iCṊᨉmze%=8@)5q%I?a7_aHݛRӸz^ );a/Jy0FOV>* -qx<7ɛmz#~;h*&ѭ׍w_QA]Y3^c)J|Rh%D(\WzȤz{?d,|44<;DZLk~ ֍t |WOuUhEᖮ]qG.\ 苕+m+QPd׻l4ۈ(q #TfBIajtpd?ز7*lWnz*܇\:Ү_(L3dQoW6,I0jdH8~glͮK?S2 V:ubPx'EVҦC %] s,̇tRG<,𾗎_%^mx]v"VrI\FlAS5ah¸GqRs~~!?@ÝFPEכ<f2fBqC yAyCWC w<\IH.09 !N8MCiǓ O>s?Q:WN1v ?$!gP h6/ZeجbQP4wgȘ4sb +;ςYVD43/p]/ʠΘ֘^%yZ8`^x}/B!5Zz&&",XE,҆ qGKGZuL$+gd1]: ܫ8<#)w)>.c O1u:%MGnw F+z^ؒxNf+N)z@ y*f@%+z_)M etl"'*FM$=ʼn<7'"B}UP{rH*Vf '*0$;OaB1yhs9z(\ _֪ύZMܭq[% E!v F0eHw&&%}pҵe獵)x`y1F9iⱢq/e Iz>nfnc8?ݞUmT$al;ޓX]Ce@_#)6f|6\vbtXH)SwsB)Dr #ŤGLDv {]&5亝\0M0Y:& ~HCZaZuPO)l@j%>4*v ųt ,Q@]( gef&-}_7ozs+HiԩfFJ Pِ1862qzC9FsC`k@6 }|])8^HKXl1Z/JꓴMX,S6A_cD;f Vу8OZZ 13SKkq)vxY{"q2zY^݇vSY| N[mi[v{JAd ޝl]^+DWFI&'&a2;8>1zr ~ 7,X[wcL4)LP*zEYG[#p~lCqK}e9)/[Bn"Ftz9!xqvgr" "p*X& ?dy.:%Y!iX6_,P;*/+wX)>Ӂ!,kז'.C1`iaC~?jQu[= yh^h]FӓoJuڟ \9oՍd#$Ϳb4juXdպ9[v Hp9E +Upy{Ν#D}~=5H"AOTvLk| +̇rh Eú|2,m;}4[wSS9~u8́=msYO*Ti@hw˝;l\>:-jsncٙW=kzȣfL+毗ƗUcGh%ow~ 1lgTA!Ne8X =s 6m*_βv#wvrޓR!`27R%CnvE ,sҴ[8OjL]ФNēb 'ac)!B^/McM3!/=lSlI>]iAٺE{ DE5~~^tE{QVޯa}٬Zҡ8U~X )Q5wǓ )Ꞧ/.Hixt+Z.<CL^V\+3 O͈q%1i\'|AEW0zFjԒo:,SρW8B<}iyY46VIL#UyP]aLT;-/'.hQcWAɑն1\ݳ(` *jjK>)Z16s'mr߶0bՇՉ;ҶL39vC4 Hd$ŗS˼f4iMܟDŽ hVhoae֏_7&E~ډ^TәD:X}dK9LfnH #J[h`*g OT,)i|kW)1֩1֖_fb/FgelvAw{JT}=\uяULr2C\.⯯6 MM'x\3}f\/-4gQiv >T)E@emj*;L/MK i$#tY/ZY _ynz4nߓփ]^5r sO{,8W]')UgSY2I9˥q6C(Itrn Bgiø)'Vy|6Sϛ2N&_͗šƴo7Gx^.kg a±%[lB]\<)*f.5/SviDeƖq Q6&#GSÁ@r7_+iޒm#vW?O= `Y(][l0@W>p [`AڠxKLR>ړu66'U?Sp7BP?[2:K9pjhWB==}9% 1ƚgObs8ZrfAUV "r56PŴ هG+C骞n<&@frXy_l-tM2>Ofr~\[#갞MqY[G;Q]覧uTtpB#vN+q.~tVԣlPE#O;#!6ms7fd)e\~sL{ZRz51r2u3+zBͶ7Ϸ@1ZRY,)k]͌kWd /y x+Ni{# KZ=l5|HicWU!TГw~x~ma \4#$nFD'WO-B3Z}yOjP )>6g#ZXя~J.l,"``m݉Sqذ ܰME>7FnܮHR7뗀jgE̘h*[ɼ#R^l0)reyW@B-d鸓ajn$할ove=*_W"v::R.QB0VRm+RT6 8,bUؔPF;;` OM=RfLؽhO_?{BД[&$B,M3Sd99Oɚ'Ek-z`&mbv[xZQ6u@twh~0N˽`z>m`OG,^r-DI]$,]5]x+=*BN | ɐG-pBt~MKNPXapZhRm 䒽.Y扇wsOl[ZgGQ)go FqpXk/H`;_kp{k> U?J.uA>1!)/v0ŠlIbVӾ&ț}o\`&;^Կx<(+UFfv"o8M#5 AA bouv*Ƥ멯* [y?;Tl^t)lԹR()ln#~'%fC9wiSmNWCN"oc38ުYEaX+#F :,pqѮb:`zmԪr51H&J Jg .oO0R $%u{nʉ)+!@vi4qh9>6 AgE4ܩաMߕ$L }|jiv.xRʇ$͛1 ЫQi aAUuwg|0k*0N|9"5HO# eE1^T<3x.^]cٗp[UN"nTI2׍<` %DtGҾZp?["R3𘑲,:,&##T͢VT,4scv</  ZI{tAWcNэLAїU lי=BŁcsߙ,,&o)_ZUWSsW JB>8d T3)ѯYƖ>Of2GAYp y_."xO*ްXɣrGZ8KH$&}-r3„64Cj?೚w+|~/IsC&EbvnK!%'3WDXU;vSI__z@Lf{ȮY {"rC^OrwB8+uݘa~r]mdeTFM=Tlv¸p=?5*o"߿o? xɻF$7{r^!wV:b3q{0(;j /7֚LIdiÌBEЗfv`Nނ=D6z_M#t ̅247ԢyO풣G qand??ySo_E`f; zN#` dHBE,0K"*w~Sgfjx`9{ ?B=Ƶ!(vW2BV * P+OG7:Wt`fSFW&tTf٭[cXi~!1B9;TS5NMAJfI>XDAА#AlR@ȤLn 4ʞee~5Ș؟x769XppFZIV(~Sv)_! *F߬ގ/+qD4ptNLQ/*gbC 7"^D-  a *2X}P;x2'-*A^py/:+[a2帥{9ז4~Uig P:eXK?j2{^s$NO͹XgaaEQVI*3pelE|*i3ZvO!j^* &;}Նn^jDMs+=9Eu-HO+'r4ͯS:5 cB\LGDyZl6n$i9]Ÿ◽: cN/sk߰[W<=7-R0%ϟCW)dX A ]pssx8lJ.//:cq^Յ> :=]&7}y T#1veRݧ=k?B/i\fz?'55|XiR֮E۲ F*^: % <06Ұf5̋)3Z5NID_"DcKo]|}8$|c0"u˕!W{+=WW _ۅtXDF$+Ec&n̤[\^a~< qs+8r~R嗰̭ؐgLy "|3R],-za|̆KU`+vTiu׊i}nlBNH &_NOsHItwF 9V"[nGA7:=D?-L zF4=a8l?Ƣ$:+&桄~Ag%7MTb&SeYıN2ǯRVKj>= Ѳ%=-3=swi2Q@Hejyיaᆟ? C,Z(jlO9^L1Z1m}2:!\q)M궍?EkWkݵQ"mH7۳cU! !e!=bJ2)*τ/A:%h 0ƅ-g(PpmaYqFB8d*6k {~£ϑ!% v " qYXx=JGNh&ĭne7H,M>zh -6YzC4gӃbeBBqI< t[i V؂%8$2/};k}>>H߻1 #Cg(Qi OIM"DOP(mLqRgX õgJ#nCܜ b,F7W99 )>1r҆wt H 7^tq( ;11>P;AcnkLr\(DW.Hx|.MT CCH\Zk&9Pg"4:Ѿƺ7]_ )ROyqFm>Z $!J?aljH<ݘz\h,7RA/Nz- -oǂ(wNJw`1'g%wُDF4S)Qibs$KM#"َ{T_nlR+e1UM%~C-$>qy W}}1gUN_ҠUeS!-O`ca|rUvWP y>ڃ"3JɃ#Gj9,48 Ӕ fTNc5BhnQMI!盓N{J<=<ʘoK9y\3㦻k 8rtB#On<k)s(9:Թ4>yƊ \r ‡͖!ZDrU`Yy{J!X`)4ex!zTh?1U}Z+WZc=A}ÞN⦐OTsrJ87LA"ʼklAkAJp/ >d ?tBPwp@#@@Vj17 ΁ٱT8u8/쮎HG U) sh4Ut1+3~d[CpMd!łF:tpP/Mg"U>XramMV~-;>qê*ި%75؅I{ՏUd`QW d4 &BĈEqHryJbA(.-m6欗c/1--0؈?t s|>q)P5߲xD $,^KߌLѦ6ȗozx9#ތakqvdԭ<4Z &jGߡo`.:DV``tcl XphS+ ̡vctj9 7x*>&{edt~M!Mo0k89)gYMbw i>^-%m|d}ɼ@ ׳tEg_{{M²+wu̍eS!]'qGwcgUz[͢iN6J4Su8X+;[O`1r!'z"o *?.$@nx7G"g}&^Y"}I(F /ڐ}+l}b=Bɼ5A +*-Mqnu5kbDZ9?[2L(5A1n MC?kY((i% RlxzC(v];E늦0:/i>ЮEӐKzGaGJFFr ԔdgR fi\A/_Cy.bħcٗDZ\⊲X hι`Cn]J I2_NUD&K^4,CAIS@tW[X JL򑛗%fCf'DeblZp#|a{#q ;8֊dyz\ig4y$__Mŀ~GUA+{(`xA I*OVS%N?]BB%Mժů"v".kDřTS@27LYJYAO'?Ըx?U-lXĪj l^0G(הUQ$ J#-{C萣߼ԫR@ɩ^7d;dbK,wJWkjg.haUn4ɔR0TC8Xf@T({e/gZre)q/`[tZnbǻ&c@|Ӡx%+3|})>K52 h dHxc˲XBsh}Rӧ '&D#PR%)?rAו훛ۑNE.faM٣  Q#~yzydؐUǻ1-+^XwVRZВJ{XD ,|Oڿ*%!@Dk7m j=K)2ck\Jì4JMM+dtѨ 5dmc۶m۶m۶m۶mt;dH ΗR).FDrĜ!8.wPӸl$6wQH)ٽL k5O&F MǐAX`~*ӡF z.V Z/CC 6O>bLR88akRWo%\FO6o췢䰬X aJ`DɕÑ"F'{_18VZX@[^Wðk83:X,ٓZ5To.~#Sգ߁"w- dj,X>Ur`Y\hZTo!GSGL=LCb3Cg_ AЄG)Z"|E -L2B';{ȚIaT,Qu}Y(&3M/ԝ"ًthĘ|^WJC;=+"z׬0p.?)˩HY[Zr: jw죙OSj4k77f;9brGkoJX1aĠw'|8ĤVU&tC6~jhMDh(>9_$zgͅ.nnjl8X=[n*S%|_l><,; dWbUAEGڜc!: se@Dab!GYu+3*m9.j 2 ? e]M Rbl"sl `"z=oOe6{. Xu䆢ܗ$Gž#9AK-GoN@)ϴ%5tpb;TVs1Q匕;tګpQbh كE?=6:Q2A19xbHjP9-":]qVbei䆟 RXu_12"50yFʄ[$u^R} <|drf,")* !WŁ#u\>kDvA-R~r/)K0Eĵɰoյ)#/'8>Htx<ȡ9J5}O@bˡɽN%x @Vt`uyS'vV"}yk3da@֖RBGifJdg xe)cM"x' K>/"DR01199U p#!P8Y^uu*rOV9;l XwXԽt=.@hٛ1pЀ =D)u XM[o<rG,W56kzF1}cn #;><})ʄDwdbV:T .RʘP<7BWmO1\_3,}. }q]q띘|h7䖐ˌU^XrDuX2P1>5/`c$ 3f\V5>;\_!D9,WU+NBpW6e^CSs>4rvUG.f1 غa} 9Fvf,r#*≪xkk]R,tCmSGKzCslCAS&TՅzmV{͜ !Yp f/pP-{h9x8>·Sg8xN4o𯯊|X3DP[H[KT4LIeLʍ fW %?,l$WG`\mپ(tlC|j,W!\N"A1LEp[Ie[F|0xyvc3ђEޛAҹ9Ҍ$#4UU/=2Sw9ku)Rj9GM;CN4ܹPuv$f&jY5V&c#gJf;'Zvwdcl(Y,ڮ3/9}^T /Cv#}KJG{Ƹ*n( -ʶrwv^@@tz^_,;IT7s[|=l{LJH㖫 =slh~!iE!,;{,6pޤ84Mk5af8y][!7?ں]Ywrǟ (E6MlóaD:j-_\ɐlxkH9#Ij1̕]IP~kbߛ?ಀXEh ѨN ]+Z& RdENWYʖ=TDs @q miim(ME5fyҢZ2La8Vz40~ Fh<83UܤNӕpvmjs%^zq faG@:JqvgB))j„, %oj]{Q_SUlghࢋEp^~@س|{uQEb9>PS?%q81<:PwӠx$6REyj/ 6z&б YԞnpFm */;9#7< b&>f;*۱5p7h$Ƚh~R"esc$DH]ƚy.*m׮?SO:!puf3\mί KE`-P@%bnfϗqWr*:iοS}0tC\0C/Щ|w7?qwL bly87c 'U6f&ИwDŽџ}8Th3L6 |Oшo Z)?MQ 0% 5N[dXT2 -n\ⴌuNslXB_(Uh:̩8h3\TҵPS-!DWGYM¦7~B:z+JC[mԊ#pz6 [jT$}wt߀TȚK8[JeoҵaX38w:HA|;s>IqiR Z#/DN1 >#Mz*TnIQ.*wn/ĭa^8/ R381UwfdmM>j&Gc@pf%NLD ݬ#{xGv{} ,r2Cٷ78jU<sM:.pIt+U3!|$z8^fSE_M8݅΃/ta1 )eW 6iădY۩G!)]ΕӡTpwy$&tP样#%*H7\u<m9zUA%EyKx- Tt-*u"@UG9@} e0p3-%$⅃(1P^r. 'fg0E:a]0DێbPaPvĔn*(b~>J~-΢Q(?TʪPX|S/2xh>ͪτ}س#刿mWJ1k$E3BV[~u9x_de%ufYQ&%yGWf'1;Fjcx!0i31}CS=c8&h01%dX"mCrє͈gG78|k``3Lr-d;CF9 6s@=漍{X&|9 &R7,֏Pwkr^͵渚U z x%fU؈$~_ѿc]i]n"'?}}lۀ Z=m6GD\..`zwҪGF:+c>&S渆r: L( 1 җڦ—|#Y*:;-n2CXʛ_V<)>YQ蔂a>Gsw4}r0K}rC_HMX؝i)` ='֏ s1?2v5y܁K`qk`rƐmJ_zM;߻M|DP'yBW:Yr; 5.9L 9#N-e;7/g Aq3lu7ӼAQNk{4Y/n!YC sj^eyxmmY mhIxqf꒞TI#%4TΝWwof\(=7W1FzYcQ=&TבЊA_Gg8Of!&) 2>S{jBlbumƧXƜvIpҠ;m_8TiZ!#7qUG㩦gTx_^ Rq'ZUOˡ4E?lX`34c$"z{|D-u@ y D`,ߊeY)~\{*Bۥ띟/;O67 fdaŏ9L/zXt^Xۏ\"e1Ya80j xzA2)yvK&:י?i58[F5/LXv4 Kv oo:3ڌH-}lЬ4)X)e-PȥLƝ:8N [yqj7W %:ItIY+0^vTw*sc P9,g4T7'= JL`rH$7y-LV;Q[\G 5HŽ ʿ, 6BJr]" ؼXi edt)@GVAp=9J1KՆ6`rc ^P@ڨQ)L1Q,)'35N~|r 4P|uQo-O7?Sj>ad N_"WF'im&2Kõ?AwZ:tEdB7+G9L !gs‚y}i$yJUq3-xdD /~'vI6h&e/mhn"*Y.$PL']5WW"z,XYyC0LK҅wA NU{AsaZ&S[ˀgQ=6>tL5j6_*Shl+)g RXhHCԑXp_BS/hؾ29dmI|1a]\+,4sl*[j4=S"o!O]L eXF=2? p~$\ EDthb, 4ҴJ6e .ےb'W7("3en 6%'yhD SGcK $8Oѡk.Adfr_i,&`Ӓ폳޻R4$o[G+szz%/5 k4c_.+h`szRܥ@Lb)IB46&dFc5drwf 5 yEn5)8:yC-M):m Z[?OF##B$+G69ntŹ+SH VbۭeMdžlJI tSH"4ԩد>Ë9hqYqpߜnh (~^]@m) j/0s8/J0QꙜ#*XA`tGmoiAexpW&ZjWB\-"QV;ɡsp{6yͦS{ {ch"`.ŭ=K1A&O|܇>bÞ%РcbZo0tE7]C^ pl6W0uF H=.0ܽY3°֑Jqqvaմ91Ed@VBvԐBheW|ocйO?LkzNT+&*@ac> AêRH1L$M1emPQ~'ek1NFǡj3̟7HRCz R,zaAƣw=H$_w(S\Bvc_?."3=2mo?*Gm2;c,J&|Klc{Q h t[q&e\Pҁz(s6)h0M|*UO98 PlS_OM 6 l!kz-5t`#'$p $clgY{2F$\s,f{$JPyH+ScOn4ժt”&M7͑|b>H$O{ݶV ءc, *}8 m 716"S5>:[L-^HbCYukȇ}EonpyC߄ +d}`c.Y§CnC! m:& }iK&BD俦Wãi7'1t98 EB3l `#G3 Qrmu ѕ)F* |UNξR8֙P.9uJ7jKٗ'%zWw3hCq>mS$ZQc[;V*?o /pЋ?ܺRl2Tz8ǯ`}ࢹi Xz(sx|~vʢ~\V9dXAH)weAPe=)<9!+3; ~l.zJzڞG-y `C~I55ڄ;'4@"4(/'ޯ7q]d<e+D L}.1ůDC1[d .t9}0j%b,}3XSnwOˈ*oQ:4wOwۯ/FM.PEdР8'|To6F b(zy9w2 jO#B>J_~p% :]Hs܇=*rrRPjVNOdN9J+%R6if U/qTY̸3R2֒J,!$E 3ݮEDV < zI-mo{"Q:MXhWwe! $/g{tFίOx:gRO~kT3M={f˒0a%} kD,$DVwTHT5$4c5t&S^6SMD[+fx,D7Ɣp*4ý5uQ;wC mmzS׎#s WiJw_ü,ˬ -idh ~%Y*Od7:uIa?pzCi EP3`}ob?٭&lao.I<ѩ@`> ~׆VCeLsc-d$-5l9QY&,@/ddF΂VN842Q.9Ww⟻őV`پvg !$ ʍFR R/a?ʧػ1:Zm~@-d߬ȥAҀ֚=OɃ]TAYѭٺ #*Qѽ >>x1w)ǎ'}6}gC\8_v/׍I[UR8~"CشmZ^r@W]#NZ<XF!`z#qƎ`=;tg8'@2nu `Ohl0?uw N+%> =%G_{Wceti a!=!شf0(˺rHn"˙x.ܖx!vz`V.UnR>Ih䚿<;ٯvd! o jn,+S;,a@?*m*[A`{x+^HΚEy$~G!`Js @J/U3؀2ᆅd\jIs\оՆL-&KCO:(FIxݨ $)q&eq34` k!>;X h}ߌBh` crT`B6pqr)pH):?|$DɗJjҸ])Ac ŘvlUEo{Qă%pdNEN݊|bZ7M*LۘZ?Miɷ%%}[Ip~]Wv[mqc{[-g4j0K2tn;1j a2uQOzqihdSEb&$rF@,{ 6G-gԜ,ZjLffy>kXۨ=ɸ ki❿C2\%g;յ$ 1lՠDf J:Ppnؐp}!qL'bm)⟈elPI0&H9zaܹ tZ?vpK^ձ_|S)Balv?QuVopdW^Q 6I'|0VN:,/GnG#!&b\7wPOBP?(ٮoT"gCe2}3gkd뭃!ӎ 4 l*\ endstream endobj 164 0 obj << /Length1 1940 /Length2 23359 /Length3 0 /Length 24522 /Filter /FlateDecode >> stream xڴeX۲5wNNp84N][p uk4t̚Uo )(sf`ad+lX.6FVFffvx QG%N r|6q~}`f恧H퀎JS@ladPAN FNjEdhin'ßHE2F& 7'kK)@Qr{ZAvcdPjTĕUʟUhۃ$=@LXAUTH {oNPP}n]^\UXUKQ,W埴ō]A%P[8;211893mjap9Z_6 bg^Ng  @h$[i^ww{/6Hcahgdgnl0K 4  'T_E@'ӵ1r3sqGm& ;'K'g#f6?ܙ_2yai qUƳcWǎ/?x{ۙlmY;){ALoc[ہٟڛ3Y:]o9 :&L/,̌l>fx/'#W O"x.{ _ѥ@L&kTidg03)[I\.66 F@mhdkieÖZhkd_:K' Kwߥ[.lv6kKgl{}XY_Vҽ 5U%%߶Ndjig`9:y3+影M5 wq\(7Io`R_`270LqL@6d`5|k`|nߐ=?'Gv| `r|??{"CVV_?oJ϶k }u*Ύ k[?L䍜-ug]#ſ"" w/23rsXظr}? M@&RCJMBS0c hA-Meo)ArRz_ 5)l^$VLޘ* },.<]Q- ]~ɯP{VLzK\ @mH1u *Tg[K *^;T;#fLQ2an }w':7 ʹ"pm]5c7zfӧ+H/a(qj 'XZ7ԶǥmIoY 'Z-(zˤA/$k)T0NtK?#=X#*ޫXkVR퀵.}9E僗lJ J3Wq""U5 $2 9nT(W~ʭD\ 1=Ъˤ1DGSZʻLCtz֍.W5ӆk+ɫe(X7i9HT;?SVV#jNI G5i۩W@Z)Ƌ3 3-1Q\S]8+w*r4@/OuFD֙\\^P4ͭu& м=ܘ'C2w!oG<[[KI{ 9dޘo>g ,ٵnM7'˖,#h K}=g֛XNTi;p GNloH[Vɒ oE u L/?!SQ M%"O{%D?e<=~j޵dϵl/!Nu.2 ɞ߆콟6wb'QKrY7^僎&½Ebf| M\ L?5@X}Dа : m?2&bigO Ʊ엌K<[S+ܙB/tqfD$;}S?]-PsV3inHv"24f- kAa7c`PKnT֨/q5B^TZg^{ Jk6醧FbT{aiJMd y{R| =ځ5X*A$2ځw8zY!l'GfLP-or 6Tzy.֚}bUO8;ETn쭓3ko);ηΛӕ9p2TQ F!,f ݴmInt?dz!%akX!Ý \Əcb(K1P+IU&* })n{vWpTijؐ8%WCIX܌eLc<;q 2t|O31BpwgzN I&Ìm B#nAL9R.gɝX%:agj(|WȊ?Wqum4cHD{4Ijxa}ja [govGd_p+yQY?E:W#[ `0^fgTAG;*Ghl?9ܼ< r|G`$Fk%}VQW$)ϕ,,N;E|7⟚yK`89܀ma shwzO Iv.!ӂda}N;ft~J kgp ?_rNW&J "x%ﳋd?XPMJ3wԱAeJ1;v$",,ڼs `h#`w5c=tcp[>MD EUbuZ"/dy{(y F@|ߐZSs3P>̗(ުLկg>moEnɓؗ J*nþ$J_r0L>0mLX Gd4]Xh](>`tYnXȾ9L`vոJ n*FMx%WHsUYÇn1t)$:9 ~Çfpls),?yȵՀIsGԗz|wh3W $+7R7Uw.eԸ*&*$F 󼛿Ԭ>Z c^b8+Vu2K]>+SK7}J׺BGtJ&/65XY򀯮ِ=rƵbL#Ȧgbp5-u?.~t!CgF:TY-D. ˦%0pXpk@֏\^.̲ ꨱQ&:a yq'u~kh"s{Yg]Wa6Q^ Iu:>u$)=)Fˊz(Ph4\?w;M}.CV4[w\~5Nv&α#%c5;'ԙyДO6C~~՛+ty͞+-W`+WhMʯ sL&7J4A P܆~8<= ]c hQ~Ek]ثyZdH ^س}$]YvDeܧjh&ږ`aJ009g|_Z 1ڝʺ},떶bow >a' Ys/.4FԠ:A~"l} 3EI 2\,~!eqhbBws<=E^7;ǥw@argrta9?aCdʛlֆӥ@c|HbUS2۪nkᖾ5VLj32j0т.N̓|V.Dz(oD̝ڮ> NLn0l>ż5g@,v87 Q0AAH,9u"ҫ]B=^̄\4ulr=M0gKO\%fW+wސ.h%[ǽ<Oej?mg˵? v B+Yp14 ATT"ve||+,0%HQn.&MJ7UT:Fʾju!S;Xcp_ݯg<;*O2'ji%A^|E'}Bpy5),B?ӳe9OT?&VIP?<_oݣ@pB}I]..&׷4f<ݪ2AJS=GHD4[s@ kFDVJ 2+$+F!\0JLذ(M>Ǚc4H= y{k1knj{2ˍq*w>_7$޴*VN^W_-|*ʯeZgv>!7Vo֙]=J"GFeOz'KƉ'bʶofps\{\[Q\SF},<&]U Da.8拜`Ш_BX મ&1R/A~5Q )zHVst!IK1w>EzKn)Nf̤EaJv%RoDԌ*r+ثM{Q57=7v@ } a9oU=o`* :%wS5$^WgPK1Pz}JnOVgj7៵6u-]?F)wUۣ!J!W ~5EWj:~Dto88X\.ǎ`Y oje|ڔ,DsB-i¸SJz?9å[Q̦6n'OȀJuM}3+z9ʭୱS\35ʨ37AqL6LtNc`!/1nӴ^|[6P(΋ǟ\Oy{EwKFhͮ,xEk4fcu]P>WM1!(똻T@ggӲe/.dx}[5"gxk,[KrIU]d^kB6]蠔77t//1UCqoHCΙewx|eCZ']zXPQ2H|n,#}:ES~sRo @]G$XQǷ=_ %To N?ӊ7O oXb9'#H7Y|mO^yǚ׶?J}N::r4ޝ$y)7bET̲&sz bƛkװ3!塼Q+ћ ,xqFqGۭh0QZL?? ί8!zDeriMz{ vCyM?,7޶eq eP[f%S\zeQL'6emŲ=׋Aՙ yn)LTj``č !ocCCKXtG Z]B%ptfS57=Qܦ]9},F<%BRcJ=9[ LŽ㎅Ռ`诨!F~bg(rMc13\So( ~kD ۦbb*Y]1O6ygnփqys Mp2Ce^ #ER v5xllrԶzGHҹ7bMƕPiKx8_u7GI|MG~fAm6<U)QzLժ(Nq%BNGmKNBBL{|D P,.o 3q5tjrAxW@rHQMpb1^F?.mڄ8Yr&03 b~HxpU^xL=/VHl0's+Y#0/_oBV#v4Zܻ $sI2ѡ q1\x.Z"'(v4s23\.ӧe~I\קOiGD,:^X$"ubXUZ2г m %T3le Gkma{`N;tjMh}Z*CB$Y~sC, J+ץYl T]ԓ28 ѐ>n5On5/`!V V]sXA|$=s$6Afk@ !B ZXGfیZi8V]*w'pFXXp"L-e,=]MzCdv M_7jbzO!r4مI2d4C@3/'87َgDk<:&{C,knım2}݃'{)VIR]p }dL]$!ٞ90]*53;Mqֽ`prY%#Ȳq⺪'Sk]ʴM;sq-=#ۍNlpF?0,S>E jp#О*m#GlU#C4X`I9{{ziIvA>tBbHjЩ*Ϩ4 -LXxM#w Ts5?Ɵ[Ep5Dbl5V|Wۺ|WpHe >HzJ<#c"i|Zݗ嗘^59XT)~w2 ~$sֵc&0btpւ} ?g&pUVZ˴8Z ث8 ߿Lٔ-7ThF_ޖ)AE.)>#$^ntg\TV0TDB zXLk͆u 9d6%YAjltq{;po;3G RgZk'FO@bΐKC:7]1GM$Mti|5h Do‡v~ʗ(o5zDS52j>$JBX 38F:sLi7/X\ġАsօ9(_!6!?ެIh }FZPK#Z>|4tʄR|C.v6J)( ^I92׀(UO:sZ 0Y1GU wddkmuwpsDŽ uPFsY& "jWcP!JESv?395iW˞]fbݴ{-Qs0W;0 _Wts ܺ4r6}# Nx,ҕ7dGWh!k4"ppB=~ʰ}ӥ]n_O[W24J_ D6+FKꛁe9 S^-::*e*Y87W"}e7:4z])X+F8`"Pfdx;v}76'H*J)"ۧ1)`$UyFH?Nmjqf|X/8q?B,~2d?aT:~ e9JPv"UYãs=gz\Ro2֒o'`=.FdO0kڂwq˺q:-AcUX-^?¼P۩H1ĵl.fk!*E>`\xP\++A >XƯE2dLMФȸq]LGYy.&q=hXz=e RK~Ux1 ?>QSI0cpuDf򤡗Nŗ7GH,HMWI?ۙz@Jd@KâUTKTCbUDkNVmHq%G;s5ajdM#4[ȱLԖ-4q"ATݡsE=O~%DZM:iufm1j%J]!T&rLYW'ҼtZJ=mb跏U_]BC?vS+B8eؾ1di9\T/S~P[goGM%:ٺ5vvϡ5lv#73q1答Dj%"4U ~4n?.Y5 4b˭1>LgqQ醡$HFϣϴӚ#Z-hA=`!!V2e>CșqÍLL[` }JBlaY:e9J7@(RrFo]:OVЁ H`2;߉g=w"gظ#va -dt]쌏Y$7,퓗򚴡͡+hs4=bG~V]N!goKBxkdMNyʓ#j\u_ftvsM~Z|@LjX\W@/cMCI) #̣>n\iXo䮷:"sµ8*D+\>#mX* f9rdTڐk/v X97m9 5~Lb{DjG5-]/7dv๬q(qQܯ?=¼eQ0)Bjm*+[3r ۃ+8kcԗb{4 n{xX<#ڽ@KR^Cܛ n^-VBpvFDƾ_XնmsBqGvCQH+Mmlz7XÊ!nNNkPݍb je͕&ih/lHnf Js'6[8Ld*,ۇg_Nwd% /spɄ}ۦU(6IŬxDvzzǾ ɟȊKg 5UJ~aɘ!6d!(:/|c`*CS$=n*$ӣUy$gG]4tfoU@$Ǥx4@MP(a>hhW,//lIⲇ~JGQd%D FKIaP"𪥳̴ˠ'/mџgnȏS֮W3;+װG 5/N4O14^'=IaJ~g) p I5)?ʪ5 Bƚ6?^Z܋rQiX͍&8[pt/>8ˆy(%xj@1&\D}\Xnw1@0rHpF'ӴAs |.]6ӻJ &^ ePV)s%`6jyS1pg랱^*OO)$1k0k-[O iUrx@E@=}>ke'M;pK*ZEC2P 143OxG%d-A:iփwoԾL-*df-g6˟FRbES7age]VX )"vKP0FDH=F8VW }~BwV #W ]߬ӻi,UO3N>h|!\K{4,N5gӊwOP=S9\/_t2% Z!>{<ԙ{[-y,>^3oeENX* -5`_uȜGpi*elI?Bnø}$}Qsγ'}f^`g*5 laFl312| & }^hd58:$&39?_$ebf7NtWBԜzJΙBt26@uƕVjvannޚ20C kCט5WPQUZEHN{E9*'R*Ϭ(5!3PCuz)׸~G3Q&2ȏ&o̶-oޥe H_~3$bgga+xLyaaXrhd[Z/V^V,g㧗$ţ9ZMޒȫ²S<:R;&Wom%C$a.ǯ`p>Hۂz=|#5Tb;&o?N#LK{a{b_O;7~&w6,xk21옂 mdF$tF؋~|9ݸJfa)b8^?|ޑ%Tؔc#EP&;_Iu]"2KzkνݔMp3⋌CX&Dp8&,OՕp15?,t?CQ.|d''>cP:\+?-˛OCO#gޘVz48^ưƼ@O(\Iavn]v*QxBt.[3(ݎ MRLn"[ǴF٦JgTB犫9ٗ/?_%?tYrbc`1dn$73I#D#W{TWGOˠ>K.lUg>Usۯ0 cRp7N (q>}QKVX"yxqVH~rd.9(Y"/sA_XdF.;Iɿ2ؚҌ4;<=œ+.CJ##G/wR߯˺5ƿIFEzU_j :o=p:?@;G*Y~\G>(kyYȾTc0G[ v14Y콃&aU-m9oL e?jf--fAtr,;Ęܞ&q#s\?03 "1)o1巎1Gb\ cѐ/`8\R}SقLXJ$Zu H(tekx@ Zbە7I⟇vYҠ&vu͗/^?gH O@=powyMTN *id =\;1lB1>`H~N-(QxQJՔ+\XP M[G~r )jq4ηrE$_N ?h+.yߊ,Kej1FgN\s#jɞڗN~]>Àe$%jC&_E"1.Ͳ־|lq͍ޛ.+?_QLd LR&7'>L㧾X#"c6 4U7H,>|!6&_81 M\&dӫ=ZP|lZ.z4Uw喰[s$5y7M"#W&6 ,݌b\%+-ũW93e;êR}EQ'A- KʪVs,Qm$VʧZ2(.#enɸǟGMҊ8Fcɋ<<3= ZrX5۵[r0}8tH[]vOex>7xFz!@9u3J~~$e.i˨YE}Ƹy-XvĔHʼn?6;/\ϥiևewUkJXٓgi^sCa Ko~T[A漦bgMe;VVi2Z_DdOGq-m/xĀ1 ^9rxB]N!Ndy+N,[isa(pu{]>!؁vK6 b4,ѩpf x]_q!u'Aq>Ir 1y- ̪AI%kNt+4&}e<ib^E}O^aAzKdj[3:$oDo<Љ??gTԛ C=MxC9S<>T: -mMQyVLtsפ!Lωݝ>G8(|RJ CɏGLSJYE/c.Uӛ/,1hyt)MGՇB˿uBɪi D&ʞ30'?]>~$4"D `Ze?bq{T[7vq,]{s!>"(]>tbɒͻn%`*8:kNofg*dhjɖ\Q$ %*5y"$>ָМuD} ࣚʨGUC^ )kƦqHͣI[>RMdBz&nipy+ gj3ѸW7vR󳱩BV.s*դvg,%.\X6F)x/ͮ戺1O:瞩;CE.*VYCDPsfC:|C%K`.nPj]]|Z=0HIՏW<W itgTcܚXibod38QJf.-)}o,-&;H}鐛<*F% 8ܻ.%VPIҴ"f45!1KéV92PΈ0s"% L:'$-z=PĠT)fEgII,Tq;.]{ \ 5b/Df >uTnJJLSBV:bد0KGHP%зk}rviH:Kꋗt-OgG-KT$~ȐQ,ϲў*΁j^<4V k{̐NǼǮ)'XVa&l/=g)u!62 K'v?4rBqlbQGŸ:.pvSyGg'tEquo&V>l`RK|"0t,bHm5^X QiC} 2v'yؗ]$FޏOg{ỨНۊI;Ro?(8"⨋374uNs6-6dh z i43> )܆ FBFcW67Igwgdh%"퀝ljܘfg(& Qj65 SSj72܈i-aA ՚Ajn鲖 q]t彏XRlс9N&2'Ay4.Ϝ{ԋ(yα^cEk?qk_PB7-Cf˙H[-J_\P[;ЁSFh Jm؅g}֛^?) -iP{yG62):Œ]ص=V@cf1Њ5O_p ɺc͇r?I=z\ U%7`Iʂſe;9+WDd׏3'P|&’14~cr>aRQjzF_Ҧ3*;5=4Kjiщ}*yN=w6ga5sce2Q}^'Sz{ޢLs^.et I`xPQB`O:..R"h9Fg)Lu@t͗ QWy"*2ʤw: od?\ _-*:V%I%iT4^|H7㼧 MXgb1Q!|O^kJK9_3ϼc'>xZV\Vh*Cdu1eG VdrRQ?7Xw φvb"in4EKȄ+fH6<ɵ'5LCKLU5~:ҙHURLZL!"^]Q͔hfIpwb?$>K !R3*[;+-tuo;aPIEd4"r2!=Be1BIc9TV3߆GĶ?9a`Y) ]2[i؂Zɀz1?Ⓘ\l) ?.]g~l2/+5*Awce}(A* 1 {ImdQegUسS^Ri I0'^l/fn Aиd xӋUCكPvv,EǸT] Bpm%~mKyx"1N;|:Rj0;-i-=Mb۾wvCJ:͸{RB ~7Uƭw6w'@gSX-pf:U%=CMY"v;-&~ǴUuྭQ -3j2Q\@D=-4Ky@_ 8z+0~ї q2㯟hPZF@d!NiۘZSB=^(Բ٨MpvjGTs ǖi.ΜVY5x%w~Bo7NKNvq5xp 1A83V}P cv3  NTr0oP t(_qY$D6C'6in{jĨ 7:baz-޽Lq%ojgXNU*/bv l0~l+Xs$PdC0>[AB;%!ŏG>D X)Mh W]OamJw,~;[hmh0@ּnod2#JDtUvy] =&g$]v䷼?%6M]I $,֭kv߿DwklTdm!_\n |x_\vUy?`GWn_YBͻXFwtb"L ˂oDB{B5?y{yM>JipM`/I_!R=3wMtva37 K5k=kؖ ٩-F0bv} &<8|-6CCA%Xc"фA.30W;\GkF&{,Tbԉ]"]Y5uC6 s\}yK}P~{7 5zoAAWN\VG Y~wO3\?ךĪT)I Uk4?q?Knk4B,qF-J N;VVdFYӱן4NarYd@߭Ա :#߭r\H"`dž8Qtnc}餯#vUvmBTvBoc#[ETf/p`c_)4\Q-8=})^.bcBqEĮŧ]Gh> F_wΕcw8%U]reܻ_Pba>, j!NEK?~.g+#`Cj+W7:}"xAus ^{n@ʺ&NBG @_=ֽ|"hP-N*e{ֽ8H%mAB.)4YTE e2R/xΎ}ƽ6$Q׀qh;%D' ldxV:>X%1{CP@*^v,Nax CgdޖW@k(jO5N{1ZDE@9H3i>:%7/kc[(ܥC3bkLtTbA<BR5I^0Q>xwq}r(%X4DՂAOxވVv N 1BP\hrz);hH ^ GJA\GROG1dŊVI0<9Ο5{UX?@G;*sq|C_{{DY7?ݪjoN?4za i@z\h!8 ln`ZEa{č8ϘYQj;Ju*KsR16b͜zhPZP#X_DGPq(a%^|8N`e-WOU2vYEdS yug[ ĺ6#q~1sN 0!렫OVSS6&tuDD'1[@@eFwn‚~Ԩs -@Å=3}_n;k\gG.Dak()z.ʈU$!?*+ p&X0~؄֭m{ G$ޫ]Tj wpa_]i'Xu v ?Q73>Sej;ٿdvk-i F0Y_iǧ R͆E蘞2VH)i= ىR7]"vL !#)N܀W%ZI|B04?Hc>{1FcϭNccɇTC<&2 5.WVgq#ZiˁvNӌc}hV7ӖVÌOӒЎB/R`>t,8x&'U1w%NHq긫Ϻ&۵xm^c`-'y^oϻ$/ACޫCƑZ,z#Iv QRwP?,$4 (i6 NA8P4IDzJ~ۉb8E8uronAVdTj<]]|8SsP@Ro7AO jimϝiGZjg sZ0o$݊XQA Rk`mg~ #bdOoU1MEѹ薡A l dTǻ|øCP쉥ߪcQĹmN @9X%f?1#r}HNBsTR쩪O [Br5HE9b`WyJJ fĿ*իY*.$>oDQ n 8j3 GGMD#iGśˊb ]jt&k3N$gp&YX94!j/l֘;%`kc|gJ";YJvVVriP2}Ǧ~_&o|zhw^+d|f2C3FO;o9 63YIC:K)ٴt&ygoF|پ~Q8-*TIqp",S.IsWthvޓ\Ҏ yO6 Vݰx@?AJAhXq gBSﭶ݄Pd"yXWީ+#:'N4/}=KWiYe ou%j'9ITSIƵ_FJB~! Hkot$m1{rK3,@NHC.ԙA5p0Ɉf*2&"XYf Fܿ8/_ɮċG7m˸KC gx^QZݖx@b9GOIowMzl{:s>F*?;;l`BbUA+m2`Zr"31's ơ9'_{.g:a<i48J6A$( 'K>ڬAsQ6= *2PHPm_Qd:{7m.q endstream endobj 166 0 obj << /Length1 1981 /Length2 14420 /Length3 0 /Length 15645 /Filter /FlateDecode >> stream xڵeP\۶6 Bwww]wK|d{W]ݫsjU-J2%UaS{c 'bo caem,M숔N N E 9)MybJ`cdgni}swp4'oF 303ބ{;1hc7*IEu%UZƷ.NETUM] &&i$UqWVVga l'qzc77W3'{ۿh,`^&&777Fsg09_,,nNրWa\L Ϧ,M@vΠ?N+mJ&[!bmp#/_9%%9- ڙ`g_/Ȕo ӟrW.b2=/e9[:Yڀwgv%UώA:v`w_ 9,<&3}c|bou;y0wr3K;S?7uq`RttI2s 9@&L-,oerwmA>f 3;|O045۰ ]hTڷ)5o AϜW. -Kv@[K/M4 N@Y:KXL,&Wo߹m@vFf6Nֿ5 ?G؛toibmrv㿈&I 1M;ۙ؛ZڙX98@''"[CrpXzWo. Ϯr#qL Bl&!7K"L&ff?[п [,3K 9L ,yL,oa?["@NTm.oO?P;;:>k׬u?r .7 Ji )/*a<В^Jj'" |Ϡ*`U2e%rTYh+K*.<9C~ѿP&'_}&5=@}H>+e2^YJ[K3 ":aT$;6 +q(?wL֡ kS0a7:fA:.24w]q7yWhlށv& =n۬3РM1( xs:nUmaC[NX;:d7,v؎ p8Eg df,~\-:;}K߸=9\lM_fU[ Byx.s yu R&}C.e}'Neo!@OT=95\jKt0h-:(" )l3X{т3 P:W/WG_ ufL8861_+%S  z5H`٨O8+EWAb)cp/dmE0+{]R*HMh&NRX?>`$C^zѮqp0bw8 Csc(MZgw]v6<"w4iٖiwӕTIp|wAJP_j{fA^vt.julڽ>*|{d@n-RƗ? #tN,ny\TE3$С%u~ #+7s*yuK7yOyH *71CnϬVVb;mE bC_(Wv;WSC^>(pWmS3L8*9VX:"x˄ղjza"oَpz4w1ӢE}j{X*Wb?4a{JS;ynb=M9*V%VsXZC&>#jMHmuR6aK 6-(l#E!0(,zգϗR*4ll( zP#T LM 81{8*XA`jhhhg!^·QdwJ4b_NJ!Ps$fQ;vrLź:ZPeCVm2c|5_ϳ$$*E*:ƱVTQj: jZ̈xPd4/*vlsS( ui׊APxjʳԡYAY>of:Ѹ"@]uӝg[7?k)ۜSHv`ݤg݅m\bwSСϩzV)z.ѫ^ϓtY؅Z@K {qn8JJM_ad|Fy7_u8[˚Ǫ/,Lb\{_FJVק.,%, M;k!^e0uxĎg.&ʊ:h"2aV&#=VZdRQ\es'̈́[G;.hʻtNlv:epUXR6 Ye$c#x2i,mZ= l& |p(_iw>)+cHC(GMxay7qhJR rcQ#r4Am!&vO^iάau7rD^W/oO֦AlG@\+IhϠnoO-nW{iS6l7R++e 00!#!e3OQ1Qe1.= -ūJY<+t3lzS2p+e G&ȨCOMa!'dAd t-uƢjw M2Iy]&--3:89nC1+F+YQwyh:)gv|]䞀?rz^p@u aˇ<4rR79Bn(<͏yEO)X-ly5yj%( YK0xnXjhas|Eז4"\S̟t0XaV[qQa{{TZO:)޹Zs۶f&cuI=H{j.vkL>݋}x Eꬫ)B9&F !otJ(s+KE`PY(6ԪLV_|6s-ZnmyaiJm־cm,OAzPZisī377&a{ ߫]bd.R d~CöfL/Q@XMjcoC*<;])7EeATA ᄴS?HALR0/o'rMt/) g^@ۥ8.N TL 6lI+A"xxIgw4Ss{%f+{81O͈-|Ŭtp(ݘs1yV- 4Vw*/ӰڮO2#i4 Rc~4o$%)ҷ*<5f_udj}(InBCn*x q|FG \4x f{P =KPPwõlQUjH'z* nۓ1ru"7D_hGvRuFKkuƌUU[WZ:l*ƝX6e&ѷnM0JD9WUlwb/Q+[ S<Qcud],'4{(_3ݡ, 7O*L~B5(8z4ȃMF!CN5סȝ$MiFR+0AGq<KL'a@tDG|o17.-pИIdf}4hTa̞s"COp-\M9K1= ^fHx' [[rH& L]ȗU!^0R+aڮ˥ŜNrA w&4.'xuIc#|fg${ |> 97W8jکQ+cAJIj~"*iH")# v :tFf Ȼw-t$QRR3A)dEE$7|i1&$Dx1eˀy?75OC;?2V#"en!S-{ń'ˀ4|0-˭ \_\V5ƼaDh K`&֞PU韑cvmO%ޞYa>_vgnavUQס&H-i: Dz( a ,B~Bp+TƩZv@S.ڿ:NR􂜱V[5Զ^F6\l)*ҢcuTAF)%x9sf<,*vA#2&Ȱ`711~IR>` 8$V| gOI"mG7>;{ "*(9B\KUTf3!"0|rë[=zPlE-"\N.愵 t[Zl|NI"\hM gyT.mk3/Wp?k'P{C`F݊^1 \]3w*W )ag=[G`p~9:LHX$-0 nk^N4E}J,u#660Ic[wASDL\K8LP)o!4X{3T\ בV22LPj+ ^AO؋ER)G!df38QLYǠ[0$t$+amiW5!S9trhlPyؔ"=[lVBA}Xj(%FB)&b~^+M^`Q7CkHP-RhR k u b껜|(W8Ryx&/jAav_ƴp9I?Dp1g{HtϞ4577NQݬMlePsIv9PExO(Fʳ+7>" I17=jk^O jT N0H;j<-9`tK>wQ;`'pV٥.vV8ofk~`teoy#!ICvG @~p|u,ܓ`)WԏBw_=_ZIwٍ%q<,7Jvwc u<.$}Ϊ~f԰ȏeWU{̅]6wOU =@>a^nۼxeY;%"[Kìgbu3_P+x tMbIEZ5Er1[_hɹNmw0JA-Жwa\<3T?` P˓Ȧd3"~ר٘L)=c.f=v/49hd>S(?X!yy Lm5Nxdz^5 -a@Yd>=QsDofDzڐ,4"%i9oȫ=%tXbSKxnRH Axp4Qy2N 3ܯn|ՠ/:_HRt^Ĥp_sh[5ΔTc~@*N2 ي]RWw?mzb{$V 9Ob3}A3ځ"g{SnقJe[݁][M۬puؼ| F(al\dzu|Rg |>[pykLIDIժ:0(qtT*]ӱ:L9p=D3dq]PPurur[B_Tj̈́aC?NKB%vꆑQ&r&(a8Wj ރ;O&_zA-$ɯtiud]ޥPF$!)#d^A̮Q?Sp3^1ە"Blp=+ƮvXB e,[ ٢>iҗm jTR$y;˲5{1ldJ; Y0O!AgL_:x.~:8o}Z_CG}hEneOΡI0 \ ^lK@6AV5_/߭,'Gև N#L;0ƇQ"xe|ʦ-1 K,跧YPEN% 2-NJ}pj)}9w l/US vZydXsu]g`!U !4ZH :VgYIyY y ۘ aG0Q1|[ dLG,/]aY<OBVz%t/E$ĕ( ;{fD< :LjAXXײrxݶJCT[#XYG{3APD '3FONo<DP66d Oǖ`dՒW)q1MkCҫ25:5;- 5/+ ?thwFҲxG dlxĎA:⸑ W|H϶㈱W%Pz1h䑩d!pv22 l %B(|8p9־bX`>iLm:w;e(h'8*x֕SǝWQҞ2 }s_DE:ǣlCظ[K,!}m-XBۮHƤ -/'8F4Reuk!D4=_}haIXu2.(rDG݃ow6ٶTЍ7ھGrkm;tY{q#뵁#Z K{YLJ٧K%_9VQ}:d31wue]-tbhyv:4PdlӔ4˃5q"7HXq+LkķW,MJw-^CJ$ bg@&*lJ( oq.c}T 9ьf u`6fb $l_u|;{&8,"V .F&VvRd"lm'F磖nc-~7ˑ;6>a 1)@g_广@" ?˽YG𳟝$s=X-Aެ1UzG%՝I`Byf\8-%7ށW[my^ l񌸛[77ꋜ IV8GjM0?i]5::&Pv mv +(IM:[Xi~WYz*I1jt&QcU+- quKe D4 5ڑ˲JƜc7PʍMGjp*єAVv|\7׼< "GyeQ[7wjQC?OFV!aR#u$U͖ 5 VNC{:˺'MXSzdtv1[llލc brv=x -`&L|{~WCLJ֐:`KYZJ97 9>XcJ}֎Sk@[k\i*mԅ"4~C_cz}c TE~BS}#ny4i3Gc; MsTO<ނѻ=B+:ib?ٚ목xJ[Y/ Dg|.{Jggr^9?h 3RMdiO{`CRح1+c=ixpw#$#oHP$/5`sN< CEڃEGƸcvc.ؐ[|Z0 ߘxx'D(4m\܈L/BE*sW*:uy^y=WX_8116kL3R迍 hG?zwRL&xk6`]т} o&d_ .?X{u<հ!'S(yfMPv]!Eh;`}_m>JdVil Lj<5&Ք.7ZOe>І;lQrc78K@WW7H;o>#"#ZdUKz6oQAŶ&[ g`{B_tlgkb}ϳS )*F.F؅6Kj*zV*Þd#o7s[O%Z%8"?.!#aꨡa HbTb]օ=&֋%MD LM \~0Yk@WUP0&2Y7[>F0VD)D1-;^5JeDH:!e5aZȘi~#6ȅb60p㚹?:^gh֛O㖐 6p%{%>/ EXmKxQFY;Te}X)YKdo${BIߧC/>#x]v:!:>tb0el237 o)!#U.{ҖщI;~uvP_md1$.sy V7~bz#c7/%x-2 AtI.RpQ#xK{7IzlV~k!wׅI$!{SiԢʻ $x|=KH^}X\׺̚$̼;ՋjUv'Mж IWx}~UOQ(L~T4Y<yaC~~ZTG-TJt:&Í:\L'wrǡfJ$%1ϳ&5x?պHDJj}<Z3eYNՃCM/ --,f^yUs`f1uUe"zL"K[Keixt ;2DGV۬Q>} 8 fϗ⹢1lYGVF.U$bߋ3O;G΃ˑ2'F ZScvl ܳ骏=uF"k- >Ix i<  *BKI{țaA×Tu~ԃ6ās /…1'hMT.4l\Oqs45gi Drb/*H[[m"Gt&XМkcoOfzyv,OFjvS I]I\XfT+#\R}6M#J,p nd(m- .ap"Jc՞ss?R I[7;@?EQM\p+t7PqGJd\pOU/T?dG}ʾ:B#sg45Le0>M:tӠfmZ D[那/aK,?V)Ke9"=lNmѝƧw'In~㫎8DqYn!*n,>2P~9ɦ7zZ `8 {Q8f۔Bq-<2FͿ\ \&':qZ%?.*@A~Q{K OƌMV/ʶ']Xc1e;yX* ZMަ3{wGlͪ|ִ$3?b]}tIfb`ոe_>ULg;h emUߝoYQ/1(~%L薫>AnN^kTܐ7M8D>]mb&q״dYӻð̂YfіzSf]1g{z>0e@yb kMUF %/co>bh4/ZE[k;7 vyO4凓$69VLϷ굈5( 5Obgc:<\0! ɛc!ғ{G@ \9 {'/~@.g~}Upix0+R x椰!EN0a?{9A’?Ih;thDAV&dg {I!ADoҨc,>eďRrZG]-VUAiY>z:c9Y*ҚL$.$^:tq뗥X%*K9__7?tN/tnUI: W]AcZ)?Bx\rd˥2V;Ԛ26qeLF S\}EfQ.Ե+{WjhhC @2BD6J=S*R"`vgbX]@`*&=b 6˩O$4c|q"-$@m.blM<vĨEzkx/r3r ^~ڣT~"պdrӶM\zQM}ha,dF*og |,eǽ.UeAfQHXڦYH) -{M$ux?!๔ BwTИAB"z3rŎrVMA3GK:򭘜e2GV;  % yTqmK(ޜc2Q/ac[!w-w4^XK<9Qo^}w"~A #rWndS>:I4 pYͮ~uسP1#'ە2OdjZBI9Sn?) BBt#˲ 9!4ġ}S8L3pV(UhPӾ0S Xmb1r (= ?ƈx@tNY>$(̙&Cbr k}-PF胮Oܪ>uJ2J,l|\6+6J2R7t 5,naeH99n(Cg` KM:K%c=;y[ f$ͻj`Wls߹4R%HԁӺENx"gUԢ) J ]pN{y50`h?. qcZrٖ醉<Ķ:)]|]Ӵ]EvmK7MٺBe.v,zqeSn}:,0:sa]2^S-+EG9"` WSȀOD!֗X\$yL+6?L߇{%:;]Vgb [g!B75oШ_\-s`h I/3J%}bi5-%s$eƱ8:CE~[aΨ!{ ;b׫ IROnm=yWK„gy4Z1*}x6:r+A\ endstream endobj 168 0 obj << /Length1 2077 /Length2 25389 /Length3 0 /Length 26620 /Filter /FlateDecode >> stream xڴeT[5[\ www N¡݂{p n%$|ݧ;P̵̽ܫOAI(j2JL,|y=H(51p QR;V { c0‹D fldA`Fce=-Ddea `gdO@lc071)0AnoF+ `45@m@ZUICY-kH3$D%@M@{@QmO7? :ʒ`/nToj vcfvsscpq3,lni p9^bot-H4V@{g )?Zf[#r GKcb啕vV`# hF@ӟ \rWRLOom읭[wsfVDe$$gϨz=||n+Mf ;7H'a'0ɃmcrͭŁY(+o&,` Z2)VYߚr:}́o/H^Ʈ@DH3+S߮ _eAߘs@}f {[Y~?jI*iflge_CD[9KY͔5fYE-loGIU}ܱ3\&GS{3%[[0Ii`7Y[8NNH,o*`x LL [09!9J.^_,o`V7zTz>/7--_l7V7`6d0[ 0[ |koVo.oÿ :YF7*o oqwC|Φ C7o={SC_Áߢ7 dԲ2[EdvYo_? P{(-ZL `d;nv?G 7 h2Nk-,e:--9A+K. EU3M /Ѧ `{5jLEdWERt,WI#0KaٿX.@c6-1v"6#Lm=֭x} `ym'B7 {LΡM>@]'s9A硨W ^vB?A/ OyY]e,lLV3Di ԟЪ]=UxɋH}?G`}AfnV1~_D}!I_%LΓj{:dQt $L t78I8;{ħay0H%0fUY$|Ck7ǥjvGwRI%?e_b| ,&1:]pB}xgbRz)G回(K JKqc bUqiuwZ,GgST!1KMCOC S]bCji䋴'٤^Az6QZu9\zY,/xizgG }=Gl2GUJiXW'3_rpЏM~uYIj-#k2I4$f(p9pfȘ*Ñzb_Q'NccX T]hG7q}z_xejh$`:~ّ$(UnP$+%M@y,(l搏=CE=Wl>XMdG e~g\AgD 3A#{~NSFdRsLI +;Lx]'<WvG?{M&JaG9r P%cS7u)B!qB9[Qj+KpiwU}N4a}Gg@7r$Є۬/+f0\H:pUu{xg\QZh척gKc zp /BiC;p#,xSd͂ P߳9S!oepOP ;A"%V:s|bϘsF=)}\-K:y&bE(ׂ֬oB9zA >U êB`(I5JE4KC\mPo:+>ý`3AɎg ar6Ɋ)f--tA('mcp ]@W#-maVY-&hxj]; %llcX_IZL }2yU@W@V\"#Q̂e=:95@L0!CCag)T׿ npqb +!3c7}&{p+VXI~&:(㤾6;ˆ1j_Kt ](ڛau?^#" 00pD k Ot?B?Y"S'Hǃ%~ %8 Pè4' +iS(L& ."DoHTSƙ ~|f$lܛlR) IPȰ ~; 5~u j:G5.\}@\ Goip%՚He Ќ[t~b\W*_+Uiuoy.4V6.hQ]x.E&v 8?(rKppoƝ nzU ray*|)ZeT J N*S"Qg:I,. Is}0B,om>xJ\:3, B܆OQCjlNa͢2O<{)=1sXȥEX:t2GC'ya)iU΅ /*l jS}c&) yOep"U61rB`bfv֎[\ vx+܏.>QQPfߡ#ƟFujp2?v)+p>s 87";dǩ[-xznDbD׀0Rd:y0iZCTZ+6:k's-R<ۑMك?6gFI&gAlύMMq鎭}kC*ƂUjvjhT~I3j,7%ͅwg%cJDI;äT yGvw:(q>ZϏQ?ydX5/c} S& 86QJ- 3IOˈ,|`~} vg!a,@.@.F5MbU~L/ݘLB:s ;ᖶ[OxS$*D L&w*oBaZ0cCmYe$q"˰aYM%J9W罶b_o2w&5RC=Pd yS%V?0dB"6IFq\k7ΥoNv4S5&hoIohVoD{-w0&֐X1'XHax&RGf2v9*(3Z YI4+x| i.2; (;,/xm)q` RUhҒ7] " Z|vn0uJG޿k|\!sFR0ݞ"D@hex E5([O%y!zcJKTʶ281uOwi`_AwlҤvqˌ`mMuwK zR|fX[=w9)'_Mm⼩)i8\Ֆd~0 m# u0-t?1TXSa6sw" pwW+c9}Pfr4v4-1~kk]~6!C+]V]NeZ|Bc&O[Q7;(|<5ޫ bF{TFUWҋꭡ8H~h(FCcWv'סa\ҟ!yt\Q(Ct{~J!,߼e MF =VK V vQI1̢pF!}(悵-rYz Ag>(z-xPDIZ!QΊlVvQ;AK%iǸ4oS+XKfZLahXctkP_Z'\ibCoSu"/xp5=ĜR˃W%úuS" ybmd*} U[L3tֈljUi/+za=k3n)+6ӷ,X*3?Cɘsz&I'k^l$;@." نFZN=8겫~7J؅%u0CLd&Bc g; +~xj*$q;G*>w:1E2" Lڮ}K6N67$\︡3E!-cE،?M"iH&M1s@p9fʉl0R&EH·d‰w=ؑG63+bJU )+<}M&^bɜ0y;5Ŋ R,ڔ;#Ky5'{.S=/+Iݥsa‘cp h_NRZt1wxS]cG_YDʫG8jr(m_:P5A(ךR%W ˿W wnW)RwDTvXYtu7%и97UO6|5'y{BR7ڶ͍Pp἖&Ȅ!M-`)k3 Eshz쥐NaoL?fZ,@zj]Њhl_NyQ)bZFz;}(|z%`/#5ldcdz.y2h_:h3=Q"4?Ex_ηݢ=rW69qtz5Oi"cRozlyO W/p~|n()s(MXsO+,A!W qXYKֲH+F[. ؄bxϱZV(CdEYw'H~l# K5yĵӫc ΕL5?iC%/S-gL/.l~avVAhn> ocq=65d]/beݮld,u@? x3J[?ӟDSSht [(E$0~ֿ]*E1BpR703{G~ [AnY#Aowv}gO"vK_ؼL^X-#2Zwx0w#a#-0Y2Zk'2㜤!zrG Eߢ,nЙfkYC hq#${XD>9bK r meZvVh)ۚwJpɗNk>!ڡ ְCzBزøn>!~X8]v$LJiZ!"n6 QeCK!%sL:wQ|c ,tݯ|jszIr쩢j$DօJm<"o"t%<#pk+v.0Z%m9^?|ӀBPA9F fV|p5T 8Dxgc=3^Y7,l\fGx:b t;%HD̏^HMSN&F}¸U2ArQ;Bnw sXGA'Pbv;#+<tXa)z_^hI'[Qi>Ot"AπW&jp)r4.>]S!W2uY^$ь~΁ZBim:)qR .X.>:d_yW1s#y1s K= CcF(AI9tf]g,@%è"\OQn3ҴGL5Wߋ\tD> N %Ah} ibǨMy$`͗n DXu\">h?/RtV⛼A#v1n}Jb2}"e}_T"FdE8y%syF(UIU(,7_S͛CrXvA*wj!&7Pmb@L;Ʊ a0|X$Xl1[I6qDLhl3j_伝_H’,D5$L|yHҨ/O;Y?Ȧr}D|aE -AG[J;vj`iTd3oC|TDʅ&IcDQ 'ȕP y % M_$ٔ8ZZŞ_F&CYq'+-&)r;'Qf[м6*+=Fu-:ʞ0(T. #cǰdQt%8`=u+;YvJy .V[KTL_^Cpfy\{Q13s2ahpt aЖ+L)V~cubߏRQq=t>U%FDtRP~&I8t6 :Q7[|qt'=7oա<{ɩa"bd*{#~fOVtXb4 9ZB*WfV!x]1gι.w_SЙm? ~H(Äh,;][Aױ/7 DW0@WqeVܫ;aU}ƒnB{J߱S6 ejX% d&*U0C=ty:d$W,O2twFkdS?/œb℆X im-s[Z2tBWoϞ,lf0Zɞis} S|[~ @+sb2;I%fA%rʕako0z7Ptuc~i l0@YOiip5bvZ4֫>uw}FBOVūR =R"4f0O~,"R%l?cfhM3vϗO0+ExG GU,\; ۼ0y[) .VÌ` MMpԞCr&Eڣ7Iv#_"Oai\yO*rI!L&lOk.YEc7|/qxRk~_0|J6]*rC*l+j,#JoΕ,̄@gW`rZu$l8BX&gk1Y>S^Ji;9qGqMt.Ԕ>J:ȳ)7վ A/1L%klBg#@6YfG'!xQ/LPQ>lU:-:Sm8 OwOqE=|N0_dluǖR?욦opW5_KFVxf(rl>u\39sj퀇gb’opqd˃nVPރS& H^g:uW'o|YogFRk2Ы~N3(~HV>5DK ܕO{} /$}b9ع5n ipP;i' ?S=hjKE/B.meػS˫gOdPK/f!%.^rPA5%qtňTk!XSu[.ș׋yK^ݗsZJ"2 P릊.joU £VI.Gxw=/ʃܛtɈ:0i )v!No# &j_B76mUeG*hmhJ[+* &"s, oX\# 8+%[}ҧKܣ~ Teÿ~3YԎuV7Ga J-=i >73:@=޿4=`t.;r,YVn?k= n>NLEPyN/!"L_ pޟ9!ۊ#Wg+Vvi6QdGd=/6:FE-jdg5Q*}.ۅ+pS9,ۮ$s!mۦ ݵhNW؋JFC]lNPx'`ժ6{p۳ )z]+Ė {M$c&ٍ+cgkRYmp٠aEFAQr:܏8aTnEN25>Y<=+~&KrZIc+ISu8Е:RQݘ8Ny)J%R9[!R1"ϭ|^Rǿa@ _cw;  EnG> uTa;zL)@p: +YdC(.a6GBt3AZ+uG|~3s;wJ{l:}YnǂΖNNY3Zz㾮ۏ( IprfUPp=Qgc4w$r? 8gWSaIgϤa$ړ#OӝJo}I\?!0b}nD-&_F,w *ۏ% ƨ9afDLEӝYt5ۛy>IW}&P@!VE0jbh6P~Ц} TmQP.x k\]eٚP(SL W3W`^|86$o(ݚ.j \ eKJJ.䓣:q1A {ϛ ol|ڼۘkOBL|gh_}66աZi[w63ίr35&?w绳^ǎ?SkgTQ\E["9L8Q ipBq0>xg.aWGҦy6R䗝\Hݰ*izNtǩ%㫲BDRc.C!Eol \>"?J9Ib"Z4ȕN'>5GIqe3*Dq8g4p!*Ւ`H֢hYFW.یw[ RbI˗t};^ڧҤ U&evpj-cd4fZѝ:@#;@`AL'T *g- Z S!R8ŸyA'rTc>§UL|1w:Ʉx 'Ijs&O0Ȟtk<-bviٳ"m5: CV {U< P1ϼ-PG8ݵڟƠ';egBABT%3G4IX iyGfNҏ5y<)^@gj?[(Ŧ.:,igb0[`1\ Ԏqh D{֣Ҝ/,s L (C3A6S`uo&{ѾdHG|ْԞ]Dymnz'~ 5#upq!?3xDd|K;p=g{S c]* RqսHdQetݵNf`9'f!@+6C';屫)5V~]f'6XX> +#NO¹5`L7I3*ksw>@mi@E婭2G >kOr9Փ.Le4fxU¢|g)hz)8/W#*nF&T["Mq%aup!EPJA?Ռ:̸/=z­zR;ʘA?}a+׈$ #54_.2 Z~%%!~<@%zkJ;7aQ"/eo2CGEZ>0<'=;<|nז,jjj =0̿L%]]]YW'1o@;%xM>n̈i-] Zh~ՏgKòP•R]]W_`9!NFfcw[c#C\[맸[~"sH nZH~24 z*H zd0SPuʁ[((E5w9'DyrX>Wrhb }h)fu嗳:wȣT cǹOm:RUurP#]oKরΚYZ+{m'gJ=NB0 a%:{!qC#>xyh?_m]QyQ!uS{i#Ys9%bBC%%\3 u#!_/}.&>)x?n12LJ!z E-̯uAX~ՋUƠeu.cW1zDNdjÒ.U>oO wĊ@zi?! D'Yp[J{[dׅCMV[{4ӈQ6TԀ tDxbjЉyGjNVzFw 9[W|__.#~Gk _iaMjtFG}hN mTZǠt50t1fES k}ݙM-=,[}J!rxi.Q`Dnܐ k~|1@랲gI<Or&nb-P{M-ogwM_<}&'bhaųtgu@/Y_-6\fHf#H酭>5}Xc^_l\oYv Tܨn=+x (*ḶIN`E2r\!jo,C^V*Y ,d>=V];GQt%5V0h/7 zHqs9’Q,HO1#3eWM; :exe ?8תsԤ^ WjU4y!?U Ks+.J=,Arn1S2E m8&lhׁ6YFm5E &V[J_HA𯅡3(#`RW\\Xș2yD6>O1JJa;p@{'?Ze*M (- Դ40=dE㣲D/VENbkJb?ZǛ+~C[ڰ~ `zeU{` tٯ)qz'd^{h<ӚpJ K$_kWBc\>9(Pd{Sy-&zGvs/[ZmY@$-&kE8m|CAe )EHwm"LA?ri۾U.ÚMx8MasyN Aj^gow- ,B4~+| .$[5ֺC`卒qeK®:I0*ڽG 0Q򕿜 UhVq{_ը S.4A.Sl. g^0jly~{*axhd4igDExM'HHצވ~~ÕHE DZdBuՌP{S-cPD7Tى q<=o 7r3@BC#gWyG闽 `rO^ӏ1󧮑h~3DO}-0% jg "dr$؆MݶQ&Sc_?ZspPY)U>Rx7<{>\`&p8]G40Q-Jsp+rV@60|RBi;ywrk0{@_?V#ˎ&?e5}PIA |Vێ; S(Ke6|_2QWoYh2v_4H4SG(r89(zThod>+L/ |x|!//h4|b57\RIeNIwZ7}[R&9Ik}1`D%vP>ܿkux0e\ĎiV*twM" )4Ah,`* 3 [L-ꢅmB(f0{֨HY8{خ|*ls?>w9 5zPY0T[co&kѲ=rB{l]=RU2I{]d{yA. Ф`3{e60aTۄDH2XRi/(*u3J~j+lIehBNh錟1*=S:k 3Eiǂ!>18?e]ȷG? } m0A 7 ,#\(=p KͪD@}\zϐb#! a-1ESe OU祇aS㦜`=Q_:S% wx@_:|&+}(+zՓ=] Dn9XR91OyÊJcL?uX:yC"[+NbY]jy&YM;YU&2\32PSz'=V !Z91zv [YD{@䓥dkђXXn(wY pRӂڙ N,VRAWK)~C|c 7厁g!/=c? ;FriۯQ,F"yĚH0d%9b9dMjP͞al(_e]YDb, s*etvV]Kvdt>:qO/AMdG~J8axIDrEaѻȓ [z% ,S@`&+*>q'7y K7xtW fuEjq?{+T4UB+:7Ϋ$qЗ+0>׵ͺ|ݑup ifJrbZ)i!Yfxj7ƬEYE9ŽAfmweAP7q2ɷ-w/"2Q! KڍA̓mh[B S)GcW›Fsş[Q{^nF!Mbl|ԭx>XM#ʞPπvNe|F?8\hDA`8n !5B6_L 2o @׫eO<$鼗.K'g6%S+jtt|?υmeP=R/lȈ̹#N/xMTP5ABy5Kg}BT0P-7`|-;F6 .-Pp:R=o;nvVNsRl$7xt Ax+3Nb|Eakv|xQ-o4KLfG00O)uPZUU> ?Jtwl/0R>IUNRh~n{ljVkw]! ϋTlϐS/~MF :^T 8w]ZoWg6tVsL`EYsvvg_^(01@jpY=TJ!p\6Ĝ,GQá<]_ ob+nǃ>EJUexJqCDžS(`1*B"a"Úvbl--7.l\%rƳ*s8 lSZ'*ck M8dW 1ˏhlFTt~cD4Uғ; d']+8y y[퉎f4V@2.R>Q;٪("Tt:pڥm.$jGZ^qm?+5-q4w( 0$8lI`۷q È{sH!)Bq6Kc[VvK]4",t)|gBf]ᣤ*iб dv>PVͻۉeB;x^3n<@A]n}5s}'mSng%-RO߰=0FsG%O/ 5ei]ipߝoʄs0/;Aw]Q{6%xNК3kUD _|-i%Y󧞺uxu-a?X9DC9Q͖_Y 29.hGWDrb3uTҩƼ٤87M),rmoN)`[r)H.EdٮU <'_FC `r.6,-cRxg{G9zς&$-*l|K"f;TJoآ"0#Tvt?+ XdskOɍӔj9`Sjsw}ìE}) cwWC+xLwihxln͗UEN^yݕ4D|V >rڸw޹8@$D/:*n|rN9񇃇F`D?Cؼ/\lAH\e1uu'!ٿRH{_Y+fU>6R~&ʧe6J.@u# m0 7|Ƥ}~Ր`nDFr2=}LOUQßG?}*:⨱-(S?xCg $ׁs oǧ&W(QD_7n%(NI8hJ~4GWPs1Z!~<)cof 5˟3㉖dwT8/i$s.Wt&ъEi6QAV2b7\o>u0»[M> cl_'J|۷&[1kIC3ȓ f# a#Cuq1Dd]N5&E ٌcε0V\;mv/2NM QLl- CJ&y|;f(u/ScQ J7cYƼz@*Db}# )R5< bm`o ^4FN_M6v9!js~ 5o1Tuz!uVA)Gp0`!w+[ mҡ4XQvUK$?àGXbM{z O:nxIQb)EGRZlJB=ڑ#r7m?) ? 0YߠVjS_q"XV*S8yNIM"%4Ӣk~8= tZ!d4llL䵟úġ~,~>|}Wr&NR\T'WTKG'5f˜+C B5K Ӎsth09*b$  bጰģG:noqdrRjow\WNO vƅ Q{S#zkjm8}:+U3}=]tD#qP_iEe}.w AG#8B& Mhmfj>/Z_@>@'RAT|^rC^cwc P"?I= e'{`yu)"$oG0"ukq#q@>AY;I5,?zkBOJ_h*|PϏ ɺ6] /JN;UI;7=?ǿ#3y$mь5#e Y{3A ssjoFaCK֒P%KA!sX=`󉾗P@T?_cLJfrg-j47yb,UvF Y`z$%-V[7ֵ{;dؘ%L@ ^Wݦf i~+_u %`Ok ++CЈmk8r700҇0Ir׽ F*i@;F\ Au'˨f&doMm%ׇ:Ը^C3ɡn+cm8ۘ~ЫƸZ\^A-BZVUT|$`=A稸.o)04h BHYr;Ly͚Ȳ"J_ ]Ҷ~4,a !J o!j66 jEwڅzk VTiNA#uI4S 5Ut^wnR8,/Lv#XMԨ\ؕo+-Zy<ōnxzH ZxIÂ|dfZ^~:B gK}FKt@RWz]OHr0p$(Ɯ԰-cf-'H.(L%T?1ݢ51\ vҠsRtBR-3yZ(0i@NJ5RϙxesA1]sp@ȱ ڿnɟ4ִ˝I]w27k:MZ`OʯVVX܎ ?`h.,^x :u&^냴G=y|_gIPGԥAEdkKoc:+k03Uĥ?;E/# 7ܻdўtD7C)'B0aǾ1 pLT( ݾ)t&$8L t#Rrڄ1A H'g("Mytko=Eْ-[^VK7-ɻp(5EQ_QZP&R{.ނvϥ"<"[qoBXZlf5\t~_{q)2PƉ|,M=1hu'{BC)\aCE p-yE^LV+yS)4KHڞӥ\MY{~n'<鶞z]1rnÿٌ aKugs=u'`x*cTovd!^1Ak/6I"dk/G`Z}U*>َYW<%~eg WΘ"O4|P^}ek?swȧXKajCs:foҀՁ,ackjvK9+ YU.<srcBR2Xr}XjtcnGi3'?)V ïC)M %yghxb<6Q8E[]~us#XJ,R}5r=,7A>^.-Oj&uEΚ"xdX =c؟;!H>Hͥ*07u\{/ uo7 щR%Z:;DlI 09$ JȦp(SÝgg/ 2 ݼ7'P1Cyj^0{浨ndнQP\+xA+7@jpkњaWԞ:+۽fK]kɺKo)g HO^w}.壣(oXS;7oOSB`).oo|1OSF|32۲ةHBsOd4xz6r-5O5b8m"eLe-! 6AfBhb.t]- w9gmy_.^b3s!0P*J#o>cl<Iܙ<׮(ǼϤ d"-' 3_>HjL64)I6+ endstream endobj 170 0 obj << /Length1 2888 /Length2 30045 /Length3 0 /Length 31688 /Filter /FlateDecode >> stream xڴeT=ҝntw )--ҍtt=G=o su{0&W`t0J;]ؘYJJ`6V&u3Zh rK<6 WH*$ !NK@ jdЙT\\\ n CR$A6kp01;[ ofab -Jeś6fvV+&P!QWRՠgpsttp?.Z2obʚR[ﯚ@0[&$w5@gÍ $:WWG~fk7WfgkfGiڀ\ζwga9]m*{S ;I_N{$? Bip _ml\UTUU؛@j0Z  ҿ]ioy\濗mv"`f{@lJbrRL3)9@3z"dyxVȐJ-%!]' ̵-ڭ@`K[9hANn@9جV aimfm2so>.f@o#d6%2ÂOu9_fo9SjXY\!As?t+ƙك+"t);8ۛ" Z\-lQ_f9W3苁퀐=Ǥ4A~rظyH [0 QB%.)?aR` K 0sv6Bf; 2Җ@ vp\Vȿ7 "/`x,E?"Xd v`8,7EtW ݕ Hw ^Hw?]tW 5 Hw?v?E r|a]W imٛ@t|EY~# p.u(j+K5-3%bt)YZJYzES--d|mwc/X-9p3lv؞D߈'A~4[`6}]ޱSsAOJyL>'r`A4b/yx.@v)&,C>o4>,իjKC7 #[pB0;]zGIgPZVGweܜ/!DYUb$( n*ycFLⲝhT[hύ@c~ЊFĩne?Ey4vT0M>IR+K9&.F`q wd(;t}{rK@դ3{V//!STAml9B{Na_&U9>yiD_keq]G # U}PJDbpƮ@AX@1ҡ%%F5-W:h4|̈q"S.ԒՕV?~+ GKh?ZDNyU|~IɆ(M=WYb?NN].t$"XӻLʦ]`vekĽm/8U5*vXL$u2~f ' d wBB/{t˭@DRQӂtad_N$֜o^LOf0 0v2`HLGsЭqR%s":4LHUp?KJ/ yy_3XcE/oA2%: |"&>6j9z&s&ɖvc%OR3z 56rOC1*l"~U(I_Wr>Y$1`_K}WH0moZ=P}{CL=ϿI!JI =].P:$M=QY4WRvu}Xg}$ȧ zU2u;혦z?ؼe- =t|ޘgwnn=״v mM0Ui2̶@F@\zNXgV`D^r] |}eYtSŸX怙 u]`\ zPGEpBmVBo!Zu6Fd1zd[h4E5pҘmA1*B ]/&K<\g8[|-l 6Z`1~ZDR9U }JmW'T"8?2n6B$`ӴxbNaqV?}]h8X n1SZ}L=7 'C QJy"`53\"ߑW zTL 7Y@Jf M~8K95]ݖ AI|0b,CfzCH"ڸhCx*JV7%Z1u?LDW$fWxQurxO-)92H@r/mk3Ju̖*g10]܎^(DX+l- 4BJ0ٓx.Ty oJcQ -s4t;NJ\e?pu)/%24 f;7׋3DzNxw8ZDs BB9Vh=* M(%Dc++ H >bjjGLlu-Vb~9r> u%{W7fK3&63bPJ875'Z4fUvsY$BPHdJƖVr\P?2NܺbߑrM;5x@GWJԤImȁ#NԵ]WV|6_"-j6UJV:~D*(ذ?Tn<]4q{8?Iudrڐ(s^SՁ]#&,#>QIzGU9la JXrkORAaA%b2 VCa;XT" L$۱ .9hRIiz(`(f-iEd 2Oh-;iKPpTܿEN&93\tZDGo{ 4El.9.Ӕ. 5T<֙LcI3gdr .IĚ]rJ2ymI?<F8,.Ad褂Ӥa׫~s"gae6wcqU-dG-#e{pCq9M_KcFuF#D*FFm:o \%21DN1Hk BmAK(,FU0ˆ3!;=, ~(cp ɴ|m$z+[+ {R|0UU^HW}W67gc^D^Nj(7^AoyEaU@by*v+anZv]+OwݴLzDk*.vٸ؋a~yTFcȧ KPb+lr!9: :OWL7ޝDĠm#Uv̅ ,3Z~[OLsYWwSWi0O(Z@/űTeq]s'w_bTi1b?AeianSNnolpjIZ#HSC#p0]c#`}' X9-W5Zٛ?8y,3 VQ>_ Mtu'||Pѣ=eZiz|eB~;{TԞ:^{CI/,a_f[s?cݍPI e\b~1/m{Hd;QlJ@xbbrF6m^(G~^?O5^n&Ow'| ^Q%J>[Zٱp`]ʫH/NIX`w$ZiT*)w3ˉҞ.V=q[:u1$)sZjE%E~krfFNb8rag:4gbDAA䯤 6FSkB:SF$廯Rö_ ]0Tnv/^^` դ} r cX8\\<8-O"6w}**"o- [O||97 : ؈=Si?C IPF PV0{UCPε̗Fm(4Zɂ)s4aHмW{<"qXT]&p//(/[a QŝOA:*=`Dwy["rs}1lt:ZK|$1`xXCo&p3M:MX4䣃(|LQkLd>p2N S@0l<<5RKG _x^)}CX۩V]$ߐv}#mtWeqweNx8Mesu-R}]#iG v< fudnhXd c!b-%4&(lޞ}dy ,J=R5E9OpxB CfυݲR7cPog?{ sau-:_v!خv].D>ۥDQMSY8-/c'#3 "# w{Joh Hr"4gn)4u:" Tcb} X%6)SVFO)G@~l]r"p*,]`D7XbL10oq\){`IS6ONU\/1a%S;Ə뙫G$o/&9+#2b\bVec_bXz[dvp FnmlyPZK&FgBtB+ K,+j;j#"-QZPqjw4j 8p-n3K٪i).C 0|m[ .> mMyH7)}Nų/o%`pSJ"ezEmI+M%+`+-BIS*N `&\B+@^ԙCqs4Wz¬0m48˄l@ӷNJ/{%2qUMGxmTaViW5l;H 7?\:y^3V,tYLcqsæ$|%&Qp*v:vTJ-pѶfJ$e\&(}ߖ}ؔN.Mq.l4ML~ZYojKe!mZ{ǰpԎEW<pG?fR#Y2}V$<{>IgTeQ~ +PpAk-%bWDCϨEygSc7Ǿz.C˿B.a4N#ly/Ս#!)1G .qWD1IT7F[d T>ذ7F icE3h)VɀF5uc_ +վiO:Jgw,gL DZ9 %"0w94{~w? I׬̍7kwL#0cFeHOzZM^p k͇O{wC{_>*)z+ݕFoą}5[{۔1U/6 OWԺgӏIe@FB2<,c}RiE3lOtOngze10,QZS~V=*HAύ>_}{ȴN(uߏ8,,We[[8ZnJ=YhF0>D㹶ld$I0˪DtZgt7^)̧Q{oN0>) /Υv3Y5X&L]qktrpXF W"|}S<do2>pO0pVWR:X; Y^/}xu5Vް עhpĴk0ZG{i>Tt*&/!~q2ue u2"uf dM}jpbyOo-l4eO\s2gV*uh 6{CX~<$~߲7^}.|\I3-bG`ȮN62v>2rt3Ex8Р}>p`Y5Ús*SǬڠ$ꝺm yx廼olt-[7>EjO/BVo__ ;}uP_'GU}q)pXflkhǣFtS7I)ݨ"Fᑖ̈hxsEDG 2r2 +'U|><q'e+L |caC,ѮOknbJD$9,: [qݎĆv.И/:1k\F^ON!Gߓ-b^Y>o9(z27ZbSPj>H׋>S/Zẖ :Z-f(*R^lFN8 pb|N۾,R*ߟ 1õAs63Ɓ&RdHZVy~$.;~[ZK"^foM[lLU#K8x^KULe[+W9ě}ڲ^jzg?QXIK%T> 7t怪Ec0g0wwL63""cs0X_͏f/S\{0hWqiS}kUidhg KDjS^Vdw T5nJ T՚_ˢ,1Ѥ jL*x- :ȂWVߗSBkȶD0Wa_-0FG\/EFNBQc]ŬAɞ^j/q?u\MJ+gGg []T ڧ_sb~"3:&΅]k3ss ܛȟ1W}t&R \@YDH~1 ^LۺMz4,D;*kJG<bN$iAbWh;Qp 6y*Hɛ<)qױNֶFEhbY,`-5];" ΩC,svBn-8GlB$hݢc-UrhmTb*]]M.Z]ާJԢ]<_}x=ļ0 2S@TNYFP]2E'u ?2"'sDFLO'ymw@R %Ʒ;[mwg溘XG tvR* x}IWBC]zL0q2k+ 0Qj=1zr''( DEu1 u>,!/1TN2eElMf8uɬBL2VT[^\Z79"!1^yc%Y|C ZŒgIwƄfӉkgXabL8ZP-:z2MVеvdT(&{e᥆WYk.o-qg~LOU_A< <$!J]\Er=ƻim&IN::sr-\w 'R}xBu^%'oL7.BDxJݖÙrg?-/}ToQFъ{TE6Ŋ4R#Wv \6ۣfK#&G/ݞP4Cl ^8k2 r;يSкG]҈~z XNa/=P>5A\hEsNcG| W[Vy6 \Ȳy@V~nDYuCgzFbe5jfN `Z0t݀Q"%5XQێ~vΊ6Vg L4'@DZsi4"kP٣H4W=Gh?-՛Gv Z_M۝](4yQTҋPQL=hnrV}r\MBM]Z%\3$&VM=-%NF^*mx稉g8 "-.ѤƊx '8?E]?ˠ@(S{]$SEת r-p?.dJ>^TH<2bE9XѕuıN*qՁ}!Xvz5~IgjN/SI5 \%_+&.]&6U8qDdOZ'd`ilt[asYT.`5Wۦ-(@[tbЄsݙuA2GSD{ͻ i7"H*:]Ma)c&s1}z^`l3E5ժ7ϥ +y^¯D؟m[tK>*J֒d$b17Y[4PZ|]Hφ[휨U3D$ړDKcY˅ìT+h<(N)闒)uW~uA˨6ꐛs>K[{DCOfzg P?'B)q,x,|aBFx`~Ŭkƙr"*c-/i8浛k{Kއ ~T="0?٘|STԾ pz՞ZFQUEAcI @q Y̊Po8!mbtPеk%bQ(z+fv m1fx X39fku:1Yr{\c a 0E,V\e78+?L *@/ERxMc ;Zz) sm!#nzm1[D1{wiK6a t_NR<ľo=0uEV[ܐ/K {QE/sPv)[pk&%N4e8ra~Q-եYm#r`Ѥ& v3!t|Cob Zn%lxuW~*ZAw)/2H=P;uro^6pW_,+f3$HeEh/3}:?͐dLw0melH&8/zWAhF]׳bfۓN͛RWҘ:nhʣu 9Baa(1  _8cYD#U&SuTx]9;os:D[DwZF]ս)gL2DTJl(]l~n??*y&wcƕ)mJ. &Jcp%\`]3% 7_m!qݎh#sYIIG7~d >TïzƳj8џ%^AHTρi QV Q[S?!~]?c^/5I<[E&h'~anu0.j.0x_ø-N*ޚsqk+S7M̐DCq@/ԝ*0NRSJ͖Q*;p~Ħ;ɮp /x.:n&r) .J}POGtU@}̃F[a[ic-M^Bsۚ>߉%ԫdŇpg@T\#~7 UvBWl_1={!t!FXϼ^{Qa M2!ޒa*_R6EHo[p_|Yw;5 9'-Vh\zҊA Ob(`1p=fCq*3$13٧" e52bM#O>5|3I~wK1]ax$V &4K;0z8xȹUEn^_ŏ'+H Pm!=HӼzjDln/uj3HP{$(8%O^x?pӏ((wl{r'}X2)zR!_#6?:QظtŽIG50BiFiV#HfU]Ԗb ՉTGT5(嘮v6J("%ֈ%wGK7EŅV%W@d7@5z*w'5B-"W[Ӽ N;5_k㊨ ~ ٙcI|ؔqIIO'´Tz?9MxSTK!epI:P! j,M }O_[t\B]o~R*NJPjqݢ@vתW#E>AEDMRHt GH=\n@Fy>vym p~[PLGH}b NH!c)iT|WJ%&Z^Np=|a[uvR: B-EcwtI:WJ:%_ؗYH"0BY2e|3{hZ:CߘWCwA.wgNk/|4Q?q[t.-'Ř,+@Wu%Æ)9"bʘDQ[5c@+h=kk61\>˻.s瘃vV Ps!Þog|(jdpr&Hc ]3!>ʉQ*tvQt unSV^<:Zd`ZI|zs Y+ bQ jNP~Ga`U= Nu?rD薄]7GK;ʈӦaACn "yI~cvfs3/lRffLVSMDa#]. ѵh/Vĩg, I&̹:GGd4 v_&uP`gN)߷f4K#I$bN >O‰MҬ+Hh# z %$N_Mxh<W)$PgU+ok%L5I^AwFl2-0=qPpCjLq |M-Ҷyh y:lА3ҹ,NʀnhEη<)Ms[Xn|E:gwpS+0<ھq_U(UH-An"Dr̄i@M,9=|Ȥ Y,~]$.H6BtH䷾UvaRWcn8ʱ9ee1ayS&uFҬ$5f]َ&`lzH!KO~=RB,c4]c6rȹo t6+pRvT!'߁t5!]-jg7kI210zcȄߍ)e-pӷr"#q {YuXMTl=hWX=ON$lJc<[\)7 J;W⏻%/"UkM)f76 H^7>o .c)*.a0 ,(5f}岰} p uNC&&cAUK_iU=sV;yf]\Wky5YHf>@ Jwr0*@}yi^vva_eh H>b"g@n4{`}d=6|=^Ia MHf=Iv (Jy=G)F2"&E1w[jf>q7r-9it َ*љӜVp]h_ؘ.IlAn(GOyuIXlohD2s"WQc,թӄbD\*l 5L-Q^ݢe|˦cGva*C5S-ǩk:z x._[22[#`rv XW]xlbNUfw׹ ī"*hPpd4mi0c m;q@'|d2S 5i{)>GOb'!e B$^b0Rb;vu"L,i8o0F r$U>O` e> JVnLPU SAZ> vu+Cg,wn)_ X<Ջ#XzyV(T'xpejYݘ2*$1Ø \c1! pn[RN' *j*,I3\DixkS>kH92 lnJ26~E/4ΒhC>@핆  S[a.3ZZ"1&@Mgk ġ!Ï'RzJ:|2;Ox)urg=@K1\+@/-PKBG+tA9 hH* a:o==H)/U0?dj@1c,`dI&kfLSDzuE;U(О^xR Ū6Zɧl2 59ڸyaL5ST@ߺԾ^ ubpcvFx?"16r;N5ہWoҿR/ 03 MՈ s pIx^ =lh/mSqk'E3X2VPk CӋ4=o{.VYm}EQtX9O'쩆-kW٠8j>>rO$3OqP x7vyg! 9–I`ӿ`oϿ(=}@ _ֳȒ㾵=/ o"\_MMl 6'Ҏ[}?3TT@{P^ .A O7"n8:N#T2+UsљN^e~$+ lͶ9Ei>e"'>os=4T{>j@m]u]Vhz6y/A!FK'bE:BzLm*E#kc6.zpKyE& Ʀ4O@u2 =e 9O3?1tFBm#d:'ц)JYzI3\ 8f%hv'4ۗyK y`ʓrá}[&8]!KP e@veUoD=#"l@"D:ܑB`H.,|rԭ>]#^@utV0gI(,wqFzXTqFku܌_5}M3THZ3 u fBPMHd^F%IU*4u9GSՎ:/4+?uûa8⿝yI*hu$̫n= ~:M3IRFhY)RNGhQ+w8'-Dd,T ^ܽRfCyR+6fdJI ך4TH$m?j'Y }ۃh)hS~cOAơc١ GZsjZ[/ ?llSX9*RhE3K $n% .k_5ż@$B;&cdA( {V,4=W*@^eZ? 8<^Ag"!ML׾tFBJήfG2kc7 I'=T>S&*iqgI*A( ,9rSr~,JL 40dy*&LX||1σyAYl{KCZ)IG 2ll|4zbM~鴆!\5AWO|rK,u2 r%Isl_  ya1ogx;9Jġ v2~gIts j ;e:[#ČťV~BNC<2Cv:p DӊM)RZ >}GC=0c+sҜv(V(Ξ|K 6aqgR~\͓((< v:uZAB*wh>lG9vL˩iKä_;DHiVϦK _$[!^U}t$au!;m=8& 图Ww >JcZs݃&nҍʳ_?8]WVaczݱ}O9>S90.}YiX݁`MX-ogE/yUa$>D()!Ӫ%ߊ7X~^btn8^h[Iquf?ZjE|Bdꧥǹ:x~U )G@aΕ-|tJUd}I"D5pve|")KrN'R9Y6k'%pB=,XtaYUTdAl@hGägӻ4 $޵fxjo.9nXCūP  2-8Μ8.pr5q; `tMlޯIxfN0w*Iu+ZWѣǦHi}"Jٓ<oq;#zd&#|~}P۹ʔN^',!A i?F5boNRO~ ;c|3$Ig2ewU!q Ή;%bvs^/~?Q Bj"csi/!>+yJ%ƅQ+p_51E[ p\);n[}bJ2Tb" 8i+H@ր;bz|1DV >3k&=o.Rtp%n܄uշl>/N; h{<‚HˈL7tw3:AaGN2!߭2wd·qqYqf잞/Ŧzܜuؾf4{e;"B@ģ.H"Eo3ԗB*ZU8`;Y!P}O}TڽZe1,owVh2P/FPkL%ٲ[Mή {~ _>E:j)3UBj@OW[ϕ)_#*dЂSH)V4x+Ԋy#V!h Jp'#l,UYfiMk̫O[}pESUu^iN7bM )1!"$k2jɞWnGn?(x[ 7%s  9s,RwPU*͜ bJLq.cRgV ֨,; mrۅeJ5XXZёڬfƽeg& Bn7õaW8dV]me< pCjOɚՀXrN۫x| 6|+ W'`DNFG-!nTwlrE$w޹H#+)]h)DD>ca=P}uԅ#cO]|)l1Vr.ԱLCQ~I2\b;\2o)< Sy.!e6V I#Yfmʯ'AsQ XH7G>GWtSg&f;| uo=ZG"vLqx>jt?Tw ,v$)C눰JQ`WSYK\ɣG58'~t,9BIX(.冝ytLB{ϱ[YS,ڌIBy( nzg>F~֠5KV Xs?ͶdOKgu>2q_GW[MQi.թ& A*`m3soKel,$cn;lIrFnS4p :P8esqm4m W tKO.;MPb Վ,iPDATh5FE+{~jiaG{4S 0-SʊWWIg߸^d+1)'#{~_6@֊a/:/t'Z{(N^`gEK6a5aƥ_Ky5W|0zO]/:J!FV!.cB{ 6RWqU9ޔ˪nAtD4nqxi%^n 9~b\WXXB@'qۀ 7Qt OgCW \It̄xA]Z %H~#3+¡IEIT6S0 1D*V_6ޞޒ$jw |aE Q7  @PlD:z$'g vxvß}R2KFfoij(ȣ>u)DK3!#'-2u_M7,t-iFBmC| K!U7p+Faxk)H͋|a,0uمy(3VII۰5 !\a^4 ZF_ r9Y6ݘCMa6:OP$Ru-B_[I88M E S9խN$`[ÔʛxDw>wQ&>G*@ptqzv }cH Sٙ咎p!ALw ݄3ϫ $개:A>3qqZCmG('(V2jʛAwo ĶLJbr|$>o#W>C]/~;Wֶ֜yyl)eVC$4>vU2R;uJXl=p.) #ùaަ..α,䭬VKN9秛Q`bS=JH4j/gcLH?EowOt88%;jUʅ*#ŭ0?0IG` `32R'ӗFrlOkh4UIvEeÿiD)h:i-(4_@\$cfݼN&x&ȸ c <tJ "Αf:RS0j:_ x?{r O\Uf>SZgZv'"d $AH@GFPXLS03WHDK9ӑ43c:)QjKH =_m$Wsj7M -bg N$ }2$cdj?`[F VK[܄CHwOBl%) _3?V-zGw$YNO,R- wBr{B9b/jʞbp`јv1`$9:m5ATbKMl%c0K#bnҼWA(޳„@+.zjWmkQ>>I"=>BU׃ETYhMΚY#n}O   =ܹܲšk~ڣ_ >y]ՌnD8tzmV2H\>ZJNk >T+ s->slly|悞 6ْĥ قԀsuD:Yݹ33I}Z;\#S)x%a4_v1s&8Peb/1^dkg44ܢP/ "#ZsణK̔/?C/֨6m&֮-[#Q*34-tc\"tJv yrޕe97SCHq/j Ǟ|ʨYpMI0{|1Q؟Hxg`m힟fJێξ aq_rr*loLx'Ў;"ޮ0_&O&q(O{@g~gozo?9]?<8'{imzs5D`:&\TiʶVRfǖI5& :2⩩,!,i?>vYMy1MOm5€[BݿCxXwKbo`#'S$6WZceCd`B8lsB[.6j`H% b=zm'Aidvp#6@` [+A tbT> ,U^@ȎYC`7"ݺ^=^P4 g C ]7#8*Q&.%m|&5(Ik*xX+%j.0˼Ta;T,=?yTa?k}>Ugƕ&@+qZ ^aM5.0>4թ&m#ԐsȅX"TYe*iB4l@OKA;pBC|>Ł eIYmc4 Qcl5^2 E F菋dc0{RThiJVٟS9 ;Alx"Q[e_kHH%gϟZ~NxM_v0`0; ֘= ZML`*Y LEMk/ P\IC;F=#߇hp9ԇ6P,ԻBnjv?>zbzdY2@ʵIs1|HPjI%cI3;f5LE9peP08Z3 YԶ;Zdːf` y›NCUlZ[QZ  W}7ˌ\٩+Ɏ< "~|,61YfO&ŮD$`X]nDN/By«8QdM!02[O_K28#i0#od2/4JU%> J[z?Y:.|`!i3-jlmϱl'CT,Gȕ^ tfs!r?H\|#9:_~ #!{<ƥ6/^6JU7|3ǭtpYzS Jr8y8CMڡ$ܼTR̫S(d 97`I/^_TDY#pbQA+#&1)UV5$@u.|%W8,.ewbG5/O(,ES9NؓOF}#?&е5A̍wq \ő6$ƌсv>=hW֟UZgp4R]L=K@h"{#"1yJoi?Xy.jl {ܝӆ^PrʘOl^XRu@#8@ XeY xsALVF`_R46c7\_Cb:B#S;ѷϴbS^4٘+ 榗Z$l%UA^I׬8(=.&q''JO/E \E?8Y9\0`lW}npA";MYn;q]O:.dz]0 ި|PIp%U2-HWgȘ\?m"'z En49?T*Kp *>i`U"b8R4/ |iƩ hjM-6̎= "lk&,KN׉ Q #\y5xCJl4~X<vwc^吠^#` 6#~ݚSei)uA~BYxR ABLIyAgZ~_0P+_Qk<7}Q.9ʵ_f endstream endobj 172 0 obj << /Length1 2373 /Length2 18034 /Length3 0 /Length 19432 /Filter /FlateDecode >> stream xڴeT]spwww~pwwwwwHp -M~ 8Y>?6 P֙ +'ggk lhma `edffq:[ي:y\cwOG+33@h t|W<r@gCU{ /h`dښYi]D=-̝`c`鷷0#@`hkfc۹ -v#) )$Uh9U5 zNPSQWhߌ 𷻜 ,WF ڻ_ LLnnnf.NΌvfS5p9Z?bkNgs~ @h$n潕Nr{oIcn,hkhknl0K 4  ;TMvZ{ m]<ћ-@57{gfaLNH^J\LEA}l޻cxB `ee0;k'xӿ%651w{&5[ ̀ft76gY-f-~o= ca |r2t]>^T/cX;]T7)Z{LpLv@ϖ+ _B*tN@E gcLBf@ ;#3'e>׏]/T[<M%/MJ 0tt4c~VT `jD߉1LI쿈$$ V`L{L"{?=E0A&" E175 ;!*M 9 ZS.1|o';gs{s?,eXWb^?{-6 ;?ۺ^T$dy/v(@?w:@G tD:pӯ{{8r2s;M?R%x)g@ǿKRdo 8;Y5,L޿vD]cyOϵoaa;w/v{{O}?@;neΘ/29Wh tJt>h)P8e$'ߔRM`L׍䪩%]C_9_|$1JK-Vhϐ*uȔy;[?*lxcDG`ٶ]4E&Ѝ&{qvy:. E_D~f&RLRv$*Sdyo+EnZykp˜ŔWxu7hAMh. >㚉M_̅{* WLyYq67x;Sym%|FFNVF0Z$5֙)5f d33ן"&6%"E4u cD X*a:\xH1 =`nG %@v-i׭~@x :4-cͭ<*K,4O>a lav[e6 &R3Tb tz<#L+*)D[en&26itZy72>ڨ9|:L\C̵2]@ȁ;Hg'υC<2]~TeFRqnaw<5#1W&\cT٤{A" q^TzEyOG/}:uA/qqV` !׊̮ frt{5 DhI 9/kca YCVO;4qdO3CCR٪rVTclb hHx{~MV2Փ W Yd{uy/KF&225q m&R tbC[7ϱR79Hw%,j?Tf{ Ձz?GTCI3WSf*k,H}XH#5>R?Ӈ>EɤLOł,SEt-嘩DBBzCNжhb&< 'V)Ub5m-<}}CڸH+w.m-803d&=rϧL(<9҃Ů~/Z1;E˰/!y|HzNn(QĕdsLu Y]sΣhi)B.O0Mq14)KVҎڸj6-N>7=%L'Rz&kB܊ \OMD bVV^е[7"Ԉ.}͝ ջnbQ- Yz&rRbFjŴ铘 BtjlDRN{=Nrxa\wg0o HGh hg2{5tv%3 !M]0DJ/E;tFeqO/9-\׹=×ztf#Y|ҸV?Wˣ3SF9,O/5h+dl?aD̝UR.n|t1DwWE 8tcs:}Ljl$I|!@:wf>v+&<h-K?+{s?>,8~mb( d{FɄepsa؂0(iBW!h=`$辅v'ЀM! zz/;UxLY}wW85LNJ`z_6"졡#Uq%bW1>scFQܝL[rsFþުL: [1F^bEg[5Y3XN 7^bFpd:J%OEdRa˱ )zϘh_BH!+L} SFS2Rިr3nT?~eq"@VLM!.IOsI(zQʦ `0f:c4ϵ8~f ?\ײM(7s`P) *pfS]ݎ)27^$6w pv*HCuBJCTGşjo0Jޜh c`:e&ԇqo9% mvAulG&VNklm(XjMt{/:a,vEFߎ?Oo{a>wR>DAk` BRKV/ok%s-bwH3fD6Gyހ;z Hü1pxڊhhhۡޱv6#

Ǥ s&՟=kR<'(v\)}Z`G@b (%Gga> %70ij;&]A+p=I~U-T)='ƙ~Ha?:MQ2'7x}_̈́Us5 ŘE:8%XӅؙ}3P}n?.<8EG {XhʉI#>3ڨ73DDa-qR7)$ogq!@!,TਛB@|ڄ!F%n4%g ۇFN?_Dq>ڙp릭tۛϲiX]!K- /$&343L/ߥn~K}Uah6lbk+~_{QdaM^l}T7ߝ<;"td'B F2Uv+<E$|~r $) 4+UnI6 B)K|mþ{]}OwRI"X5sk #^h D &dLgŻ՜ ;nʗ9Z9V己F6 y; fy"h^Rt<ɷ.$|qHash5IB#&U>R|Qa[KIscy_mpě9ÙySt箛=@y4ODx)/EY NzdbEM'--Qy(V'vح `J:_PЯ:-#%X#oLG*ecEPY t\?d=L{(#@Hƭcq8:f  z2"P5tܭݳI|^ʱҷX%+bpJ1Q]F5Ji܀ 睱+Hqщھm)i$:S6MͿ<jLcֆSV{.25j/i!Ie(™),3\M̺SB/ r;MtJo Mq/P[ݕ٥N&{*a)IߐZ)ky- w[YY[+06hе^?\-0d8>3JZj9&(`#<*,rVzq :Z0ᗇ@nMaV-Vg0zڬ (VyVm|a!Ln{t pvFyU BgC+9!^7<&WNө;KPm+)لV:-Zλ =-=ʭ^R !ᒅLJ%`{X=9@"/f`CI0,l Z7LӸ5yW\|\33-PxX~Yy_'sbx 1CH ܥ*GNj!605mӱSzzk8Al}؍;r(wӅsD1ʉt8ԟ6őķYdw7V"A#}KNcvÎl(Lh:4}<^8T7bhRC?~2_:\*gYFsdf;!q=M@,Pk TU#X+ kFKL=U~cωOH(yQgt1MC!6ϸU$[S_ EBsu9- IIM6i#]+~9v/d+Vb0-*͝8R;[bYnP|2C4b=Qԕg{i$LBp jg<+Sq5e"m7j ZK|[9L% /~2 qF@v!AQ# _A 惻4c䳶/-?e0 q2+#T՜jeu%sc|ں;Ϫ<`^J7+MgmfGxphhFٸsC 1V Y5Mߚa簀l+9,D~7)OUX²n_IE <{ ~iXۼY xTy.51OD3^8 ~ނ]bx/E@|{*P-_4 wpe} "j jnuiçt0>{R]@׋E9lP, O:${sO MLTK>.xTL‡ &;֨&TKw?pmR}'D諄!K܄4Zz,s[M4UvTV7H>9ue#٭`0,tsOtUKxaɶ纩TK@%ZmJ1BC]/?n󝯪}D`:̇p^Ʀyi$k3tU9W+nq^Y:~25IU7=x LY@f.ævOg fZNI.!t830샠/a_`W ?.VĆZ-\ST:|L3R5% 6Gf!yм\LuK<"v^N̠azxGA&ӿBxYG~/ 1Z(hÌA4\mqL"&:6KshnZS#n{/em̬oAcϥ$GF|g D[SBgDsBB}CXt'w=[""i8{Y~/B6_Ǥ'yz^mknه*DM*P;% 6{ej40Wu詠) 'Bl%> jpM%4P̾IN/U}SvS|g&QVm&92)GcAe/ }h` #`pp+/dVX\IƲ0UnvBh̶ ˶h ZD$|r3+]bQ @+IZՇmb|Viޣpi_&<}-FI T|5_,IbcH;TX~4] 9PPuzt/r.XX09þRVϊ5]ݳYFBþ;hؚSJqr;jn8gm;X%WgӒXc%ӇR$1D%:8d%_2լ7-i I6m{Ä&gE~h泍EF3=A  A0E=Cv;ִ.iQ*Ćr6waн0s:bEEYߓIȩY55TJ -.ـyMЦϑ!P8F$FY$%&V\nPxD;VIˊє,xTGpʥ@Fٹ'WV2Y sZ-|TjBYOOAXK`.>5ˆ<[7L<%O[r-`h:͗6R1;O8] GSg(FH|wi#5tZʽP}j}hnJX!l`NRBGZ~^}ZsbT }ܲs? ˤ6KZ!L銬oV:8j8dVy4 M: A +U 5c^ȑ@i ~ÉC[ uhs.c"MVNg[~Zw2{8\7DzcL4k+cd D'.[ cUh55A.O{[l㣂o$ϾσhxM C%wg"UŞ>|x)K{-mD h/'ȃrBг HҖiƓ/d df&]YeϋjVG|j8 SI3#Wݣ"`x{1YԔ ovzB[|Lڬ덐k-,DC%RZs}<jnj~^d:*C"6mH& jC֌K)ٟ7DiH.l +B+_rZ-3̋#9`^776+ύS)߿0;?]06%Ko40T;h.w }3rɋJY;>.~NmU&]ap:Ja95 }C#2e4 {- cEֆ2eRqL/U0H>-ƕ=6zׂX@2*z݋^(WIzU|)=:E3јf>)nωYzGtD" ν6m؛{[?5KL PiOrR\Or <5B#Ǎ;L?o WFZtv:=Aym9jA O` Nh-Ob"q]˴Ї&?tGsW:D^ S03#yL6w=H|ZpJn8ua0P/4LgV3O []nڮm㠤FR##mkiqńͫpzC"9%"q$a 4^(,]aYDFWm󨎪SZ%[)父p^]bEN*s'v֛-K,&ygJ8vv@PtLeMB$_]8c*56%${N Gc\"{Ia?8j~;Z~^v|zVOPy偦A&lX3,2y3ש+/ڦKF?F_ԜX7 3qgw$ljezRR֓Pmi/7F"4]38Vvޏ܃)qCIiVIJ;tAy &|N{jz2j(tà )"e5۩{X)^!8ŷ Nd n_2@ +DQ*x1Y;E{M N4tD }[,6^4iBI7gN-Lx=Ic2_q"nVGa(Z+~Tߜ ZŔCqo:6@\Cw_;Y>7:u>|HZTD9$Ƞ +m&hiHI~X[ũ8g΅@,& "VBL4h`fq[ܼNB[-yiwƽa;a+ţVFؖgS#__ W5YǠy89NSJDm>Oc ~?-~KT *1IM)Zkuei' GXm8OsE7T<lz N^R[+쵂G(lJ _aOAɈ_*r(=*%]vͨ~."@23YȪ> Y!%ji܈8ׁl[;ZC䚠pNl4V=Ƚm.)>g<5lruڟ7 "4mkf?zh!1N&ѥe`Z+Ë <ػ~ی T6D2'G:i(Apc$󾭧ͷ4/͍td:} UEK'W7SD$na# 6_]G5#g`/g<^vTbi^ԾrV`&i U+^ݦ{~e)W8˒*?x[Rhwή1xvF\ZB:?; M _Ω&ql{-2}׷? SkʱNMMD_AG [9#Mayk\0#RgrKjt&!*ԐbA',4̮!mOH.q˧JK/0y7Xo2n|e&mŌ0[,㫽]7ѭaSWx[)z.vuďH]0Ui,.xmr? [ktJ](dMb/6AK>tz $@" 7HfF~hKEU+g@#7. KCǧ}WT-MKP>][3> rU3ُLTi@Kq~1 YRQEށĽ#=dpxok T|4$'.kL+xR"Q­  (rOe4&[1v^ 5`Z ܕ~ U~譿vSˉ:!,KQVk!#Fo`wK3X9_'s9`*ҼMv_D8Sy<- 0%sYQ, T|sӦ'ϋS>rjysf/7p"z)&.b>hGY" ْ Ǩq LyTVm{pT;~D%g-5sDjNx]  %j;$!f^Q -b[w lǨĞ0243a#v29%zÔ;ᳰ%PBq9\KOISzb)गvoNj{%3I(ˌƭ16 [||Q!ٖ~z;}P"2b'9сPQ5$q| Aܕ q%]BݶYO?fKޑCTCܫgN]g-8u 13maN\]ڙdp'tV̀I=|,seaY߾Asjl H= AR*y B"▤''tjBRy3N΃ݛz?ua!r@|mv$ҥin01KÂ<a0bS-X!ccZWW 6ws4̹ Ieր[c.asO/$Y^OUw3BBC;rtD˜$`pJ,TSQ"y1j |9pZ3mFLM܏x&Drr~|h͊0 T-e^Ԉb9I Ҟ@Wf5C!suZ 9a"ȹqVtAV3C^ݾafa׆`(%Dr*;[r[Ō_2RP_9)DPG~C"ۓ8TvϥwjWH2Wܛ;bWqb+%}6oج^63BluA4P!r 8; (% R0ݭX'fHZ+9q=q:-j}oٮ4Txn9f-ji5i4=!䞱Jcl;w(xH{DU~2E$hxL!q&@WkJ*Fympp5Q*8yT gc$0V>0kn^㨶--TЊˎsD9q<7D}ʹ}h_y^@9XڛDS$CdB?p)xeE }p麬I_Pa"+qt7.xc| {̪RnVjIcCEQI_(nj ٱm0ye]h5墤[hu%rbsn>ⓨvXن[%G ,OjʊbI6Ew'Ͱpe.d#4R`z^yCXjfu"a|B~usw0hGЦLUnIA;Ν,tc)Uq^G4 7OFMq%ҳ!<f{J~ɼ(7u H!u6E~}kVɒpw>rRHdZXzszbc,i="/:[ݜ*z!H @&UQ6ecG䴩opyhh Nq㪗;#MH62|RTWEFA ,_PuzD(0>6crH@h?l[g5Sqk՘? 0T塳 oçsvǴ[)g}H f [ > 0NUS'WDVfl(Go?^ze}mŘ } Ҥ0A1e.~%\dqZ#79e/+FWLjWߩwa =q}xן)XN]R+\$hQ[N\HRt  >{᷐. , ޗh-߂ǐoD*s&İ2΢4<p䚵%srڮwGNTqjN'.#T^ Eʨ[ LVfp"UBi#TQ-oΔnf RquVїy JЛ6dHHX.Tgf|H3?1Yᆎ&QJzR}`V~]URY67PK> 0;a]A/^#Sݾ~ӂ{ QvRV_0dOyExtO2>kǥ:MZ`ٳig}2'|RI)O |y`!!CLIYXvwe>s): p'gu=#R(L"H*BuI@BjATҠOɅ +/xIN10b4/$HȶY#A1{#Zsy̌bn B}67qǬ)>ZG7Vb۫Mo Rχhk,WE)*IuX6 ]1NwD&"Xmϴp)խ*#B%N@93wɾzI(40 lЮ/7B8}aJ-[$2GNBML$NړNCPNSBǰK<&֔߱c\CF - ZXѱRqnU PgႼ5~L *)J%[v9ܷruS-*l*ؠT%tN+zFt%I zo&ˁfйpy%:%oc6Z(y}jx0ec^~S endstream endobj 185 0 obj << /Author(\376\377\000N\000a\000m\000i\000t\000a\000\040\000G\000u\000p\000t\000a\000,\000\040\000S\000u\000s\000a\000n\000n\000a\000\040\000M\000a\000r\000q\000u\000e\000z\000\040\000a\000n\000d\000\040\000N\000i\000m\000a\000\040\000N\000o\000u\000r\000i)/Title(\376\377\000S\000h\000a\000z\000a\000m\000:\000\040\000T\000u\000n\000i\000n\000g\000\040\000c\000l\000o\000n\000a\000l\000\040\000a\000s\000s\000i\000g\000n\000m\000e\000n\000t\000\040\000t\000h\000r\000e\000s\000h\000o\000l\000d\000s\000\040\000w\000i\000t\000h\000\040\000n\000e\000a\000r\000e\000s\000t\000\040\000n\000e\000i\000g\000h\000b\000o\000r\000\040\000d\000i\000s\000t\000a\000n\000c\000e\000s)/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.19)/Keywords() /CreationDate (D:20200205134047-08'00') /ModDate (D:20200205134047-08'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) kpathsea version 6.3.0) >> endobj 150 0 obj << /Type /ObjStm /N 47 /First 399 /Length 2782 /Filter /FlateDecode >> stream xZ[s۶~c}P L3vM'ݸiD#mɁ\Rp4#Z=lDHđ|ʊ@&\8i~m,DGWx ^Xh.^*XqDUሦ0}r1Q pΠp_)!mke( XLC,b52 G/5/q ԺC6#Q| ]&I =m,Zf[.mɽd޿Ci5pF56Pr"ǚ7k{_5 of_S? Qq|HZiEX 1>`>59ox3_+ Pݧ? ^:yBAC ebGuPt4߉_" 7_g7N0l꧗u\}yxc ^] CvHhk,@.JX< _7-9:9-U\ea=?/X^_l#;%@qyՆ az?y34gh[ތfioe/Vo"'}KɇXѯg/^,a,E _z{yY`i`wu/|g ^NEw@lCOaP k_GOE?k+[G<>g@M=_,Q)M*`BWHvyDVF릲^0,r y><?9{sC/Jpw_%7UVQɋݼQ>)~HKoTqЍ4Xńa'^t;˦Y'br ToGfixu[.ǡTנmFϻa;`܃._?Z{,G|t ӫ; ?,s*#V?=wC|ml:G#]]]l҅)t;JE΂BngZލiq½KcㄓyٻX>Z肗`'͎h=wN⓶蠍;RڂˢSJ0!m'+\(*ߌ;\6Nۡg]\~HDxqє4Cq r7-83!^q $WAArJ{ŝ1O]bVl*.Ōy ٛMݤ&;mOeAmwŷ2ީ} v]mE4chPmŁR=l4z75ۊevSDUNua[ʙEj4XfAR/9]c_S57>Xb΋å_"H\v"_[SV\ h"`,Jxѯ~dfRMIiS_a1"x[\2-qe=OFUT2寫InR.6qߺIb$G4R7ЄCDփT(g%i;\aY\6e$U2* &,ol\F lg Ú:d\"_nku2p![:]KrwmɳN|_> oMKTDInI NiM tYwk p\!ZDfF(-ʒd1KfE5R5 x^&+Ǩ7wJr>$|RM+$M Ɔ^ D{-7WrdO], ֙rT1? 2p!f"fY= ,žlW( ߟmUOA(Yβ\xk>.*4vytz佄_I endstream endobj 186 0 obj << /Type /XRef /Index [0 187] /Size 187 /W [1 3 1] /Root 184 0 R /Info 185 0 R /ID [<67A78B690EC04CF34D1FFBBE2F03303D> <67A78B690EC04CF34D1FFBBE2F03303D>] /Length 490 /Filter /FlateDecode >> stream x9OQs :##n㾀;*(B !6513!ka0J?_A}Osܹ嘙Kfܾ3#I X@2cmV8k:E؜ӬZ`%հݬEl"6Jk:X#ަRu$ޖk~Wԋ:*g~ז-0VSY[Kal[/xn ʋ*wNU[av씻Eun9=n `?pRcFf><'aނ֎n ^L{ N=LI?q98Ovʻ6uoeTހ¿'M Gj܁n *g[M,I4G2Lv0<SLqԹ}}ygJ[  f(5zZ(5y.칧U `@20C\T=m4i}U endstream endobj startxref 254045 %%EOF shazam/inst/doc/DistToNearest-Vignette.Rmd0000644000176200001440000003174113575255254020261 0ustar liggesusers--- title: 'Shazam: Tuning clonal assignment thresholds with nearest neighbor distances' author: "Namita Gupta, Susanna Marquez and Nima Nouri" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4 fig_width: 7.5 highlight: pygments toc: yes html_document: fig_height: 4 fig_width: 7.5 highlight: pygments theme: readable toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Distance to nearest neighbor} %\usepackage[utf8]{inputenc} --- Estimating the optimal distance threshold for partitioning clonally related sequences is accomplished by calculating the distance from each sequence in the data set to its nearest neighbor and finding the break point in the resulting bi-modal distribution that separates clonally related from unrelated sequences. This is done via the following steps: 1. Calculating of the nearest neighbor distances for each sequence. 2. Generating a histogram of the nearest neighbor distances followed by either manual inspect for the threshold separating the two modes or automated threshold detection. ## Example data A small example Change-O database is included in the `alakazam` package. Calculating the nearest neighbor distances requires the following fields (columns) to be present in the Change-O database: * `SEQUENCE_ID` * `V_CALL` * `J_CALL` * `JUNCTION` * `JUNCTION_LENGTH` ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Subset example data to one sample library(shazam) data(ExampleDb, package="alakazam") ``` ## Calculating nearest neighbor distances The function for calculating distance between every sequence and its nearest neighbor takes a few parameters to adjust how the distance is measured. If a genotype has been inferred using the methods in the `tigger` package, and a `V_CALL_GENOTYPED` field has been added to the database, then this column may be used instead of the default `V_CALL` column by specifying the `vCallColumn` argument. This will allows the more accurate V call from `tigger` to be used for grouping of the sequences. Furthermore, for more leniency toward ambiguous V(D)J segment calls, the parameter `first` can be set to `FALSE`. Setting `first=FALSE` will use the union of all possible genes to group sequences, rather than the first gene in the field. The `model` parameter determines which underlying SHM model is used to calculate the distance. The default model is single nucleotide Hamming distance with gaps considered as a match to any nucleotide (`ham`). Other options include a human Ig-specific single nucleotide model similar to a transition/transversion model (`hh_s1f`) and the corresponding 5-mer context model from Yaari et al, 2013 (`hh_s5f`), an analogous pair of mouse specific models from Cui et al, 2016 (`mk_rs1nf` and `mk_rs5nf`), and amino acid Hamming distance (`aa`). **Note:** Human and mouse distance measures that are backward compatible with SHazaM v0.1.4 and Change-O v0.3.3 are also provide as `hs1f_compat` and `m1n_compat`, respectively. For models that are not symmetric (e.g., distance from A to B is not equal to the distance from B to A), there is a `symmetry` parameter that allows the user to specify whether the average or minimum of the two distances is used to determine the overall distance. ```{r, eval=TRUE, warning=FALSE} # Use nucleotide Hamming distance and normalize by junction length dist_ham <- distToNearest(ExampleDb, vCallColumn="V_CALL_GENOTYPED", model="ham", normalize="len", nproc=1) # Use genotyped V assignments, a 5-mer model and no normalization dist_s5f <- distToNearest(ExampleDb, vCallColumn="V_CALL_GENOTYPED", model="hh_s5f", normalize="none", nproc=1) ``` ## Using nearest neighbor distances to determine clonal assignment thresholds The primary use of the distance to nearest calculation in SHazaM is to determine the optimal threshold for clonal assignment using the `DefineClones` tool in Change-O. Defining a threshold relies on distinguishing clonally related sequences (represented by sequences with close neighbors) from singletons (sequences without close neighbors), which show up as two modes in a nearest neighbor distance histogram. Thresholds may be manually determined by inspection of the nearest neighbor histograms or by using one of the automated threshold detection algorithms provided by the `findThreshold` function. The available methods are `density` (smoothed density) and `gmm` (gamma/Guassian mixture model), and are chosen via the `method` parameter of `findThreshold`. ### Threshold determination by manual inspection Manual threshold detection simply involves generating a histrogram for the values in the `DIST_NEAREST` column of the `distToNearest` output and selecting a suitable value within the valley between the two modes. ```{r, eval=TRUE, warning=FALSE, fig.width=7} # Generate Hamming distance histogram library(ggplot2) p1 <- ggplot(subset(dist_ham, !is.na(DIST_NEAREST)), aes(x=DIST_NEAREST)) + theme_bw() + xlab("Hamming distance") + ylab("Count") + scale_x_continuous(breaks=seq(0, 1, 0.1)) + geom_histogram(color="white", binwidth=0.02) + geom_vline(xintercept=0.12, color="firebrick", linetype=2) plot(p1) ``` By manual inspection, the length normalized `ham` model distance threshold would be set to a value near 0.12 in the above example. ```{r, eval=TRUE, warning=FALSE, fig.width=7} # Generate HH_S5F distance histogram p2 <- ggplot(subset(dist_s5f, !is.na(DIST_NEAREST)), aes(x=DIST_NEAREST)) + theme_bw() + xlab("HH_S5F distance") + ylab("Count") + scale_x_continuous(breaks=seq(0, 50, 5)) + geom_histogram(color="white", binwidth=1) + geom_vline(xintercept=7, color="firebrick", linetype=2) plot(p2) ``` In this example, the unnormalized `hh_s5f` model distance threshold would be set to a value near 7. ### Automated threshold detection via smoothed density The `density` method will look for the minimum in the valley between two modes of a smoothed distribution based on the input vector (`distances`), which will generally be the `DIST_NEAREST` column from the `distToNearest` output. Below is an example of using the `density` method for threshold detection. ```{r, eval=TRUE, warning=FALSE, fig.width=7} # Find threshold using density method output <- findThreshold(dist_ham$DIST_NEAREST, method="density") threshold <- output@threshold # Plot distance histogram, density estimate and optimum threshold plot(output, title="Density Method") # Print threshold print(output) ``` ### Automated threshold detection via a mixture model The `findThreshold` function includes approaches for automatically determining a clonal assignment threshold. The `"gmm"` method (gamma/Gaussian mixture method) of `findThreshold` (`method="gmm"`) performs a maximum-likelihood fitting procedure over the distance-to-nearest distribution using one of four combinations of univariate density distribution functions: `"norm-norm"` (two Gaussian distributions), `"norm-gamma"` (lower Guassian and upper gamma distribution), `"gamma-norm"` (lower gamm and upper Guassian distribution), and `"gamma-gamma"` (two gamma distributions). By default, the threshold will be selected by calculating the distance at which the average of sensitivity and specificity reaches its maximum (`cutoff="optimal"`). Alternative threshold selection criteria are also providing, including the curve intersection (`cutoff="intersect"`), user defined sensitivity (`cutoff="user", sen=x`), or user defined specificity (`cutoff="user", spc=x`) In the example below the mixture model method (`method="gmm"`) is used to find the optimal threshold for separating clonally related sequences by fitting two gamma distributions (`model="gamma-gamma"`). The red dashed-line shown in figure below defines the distance where the average of the sensitivity and specificity reaches its maximum. ```{r, eval=TRUE, warning=FALSE, fig.width=7} # Find threshold using gmm method output <- findThreshold(dist_ham$DIST_NEAREST, method="gmm", model="gamma-gamma") # Plot distance histogram, Gaussian fits, and optimum threshold plot(output, binwidth=0.02, title="GMM Method: gamma-gamma") # Print threshold print(output) ``` **Note:** The shape of histogram plotted by `plotGmmThreshold` is governed by the `binwidth` parameter. Meaning, any change in bin size will change the form of the distribution, while the `gmm` method is completely bin size independent and only engages the real input data. ## Calculating nearest neighbor distances independently for subsets of data The `fields` argument to `distToNearest` will split the input `data.frame` into groups based on values in the specified fields (columns) and will treat them independently. For example, if the input data has multiple samples, then `fields="SAMPLE"` would allow each sample to be analyzed separately. In the previous examples we used a subset of the original example data. In the following example, we will use the two available samples, `-1h` and `+7d`, and will set `fields="SAMPLE"`. This will reproduce previous results for sample `-1h` and add results for sample `+7d`. ```{r fields, eval=TRUE, warning=FALSE} dist_fields <- distToNearest(ExampleDb, model="ham", normalize="len", fields="SAMPLE", nproc=1) ``` We can plot the nearest neighbor distances for the two samples: ```{r, eval=TRUE, warning=FALSE, fig.width=7} # Generate grouped histograms p4 <- ggplot(subset(dist_fields, !is.na(DIST_NEAREST)), aes(x=DIST_NEAREST)) + theme_bw() + xlab("Grouped Hamming distance") + ylab("Count") + geom_histogram(color="white", binwidth=0.02) + geom_vline(xintercept=0.12, color="firebrick", linetype=2) + facet_grid(SAMPLE ~ ., scales="free_y") plot(p4) ``` In this case, the threshold selected for `-1h` seems to work well for `+7d` as well. ## Calculating nearest neighbor distances across groups rather than within a groups Specifying the `cross` argument to `distToNearest` forces distance calculations to be performed across groups, such that the nearest neighbor of each sequence will always be a sequence in a different group. In the following example we set `cross="SAMPLE"`, which will group the data into `-1h` and `+7d` sample subsets. Thus, nearest neighbor distances for sequences in sample `-1h` will be restricted to the closest sequence in sample `+7d` and vice versa. ```{r cross, eval=TRUE, warning=FALSE} dist_cross <- distToNearest(ExampleDb, model="ham", first=FALSE, normalize="len", cross="SAMPLE", nproc=1) ``` ```{r, eval=TRUE, warning=FALSE, fig.width=7} # Generate cross sample histograms p5 <- ggplot(subset(dist_cross, !is.na(CROSS_DIST_NEAREST)), aes(x=CROSS_DIST_NEAREST)) + theme_bw() + xlab("Cross-sample Hamming distance") + ylab("Count") + geom_histogram(color="white", binwidth=0.02) + geom_vline(xintercept=0.12, color="firebrick", linetype=2) + facet_grid(SAMPLE ~ ., scales="free_y") plot(p5) ``` This can provide a sense of overlap between samples or a way to compare within-sample variation to cross-sample variation. ## Speeding up pairwise-distance-matrix calculations with subsampling The `subsample` option in `distToNearest` allows to speed up calculations and reduce memory usage. If there are very large groups of sequences that share V call, J call and junction length, `distToNearest` will need a lot of memory and it will take a long time to calculate all the distances. Without subsampling, in a large group of n=70,000 sequences `distToNearest` calculates a n\*n distance matrix. With subsampling, e.g. to s=15,000, the distance matrix for the same group has size s\*n, and for each sequence in `db`, the distance value is calculated by comparing the sequence to the subsampled sequences from the same V-J-junction length group. ```{r subsample, eval=TRUE, warning=FALSE} # Explore V-J-junction length groups sizes to use subsample # Show the size of the largest groups library(dplyr) library(alakazam) top_10_sizes <- ExampleDb %>% group_by(JUNCTION_LENGTH) %>% # group by junction length do(alakazam::groupGenes(., first=TRUE)) %>% # group by V and J call mutate(GROUP_ID=paste(JUNCTION_LENGTH,VJ_GROUP, sep="_")) %>% # Create group ids based on junction length and VJ calls ungroup() %>% group_by(GROUP_ID) %>% # group by GROUP_ID distinct(JUNCTION) %>% # for each group, we want to count unique junctions, so keep distinct summarize(SIZE=n()) %>% # get the size of the group, the number of sequences arrange(desc(SIZE)) %>% # sort by decreasing size select(SIZE) %>% top_n(10) # show the top 10 top_10_sizes # Use 30 to subsample # NOTE. This is a toy example. To use 30 with real data # is probably not a good choice. dist <- distToNearest(ExampleDb, vCallColumn="V_CALL_GENOTYPED", model="ham", first=FALSE, normalize="len", subsample = 30) ``` shazam/inst/CITATION0000644000176200001440000000656313402556553013671 0ustar liggesusersbibentry(bibtype = "Article", style = "citation", header = "To cite the SHazaM package in publications, please use:", title = "Change-O: a toolkit for analyzing large-scale B cell immunoglobulin repertoire sequencing data.", author = c(person("Namita T.", "Gupta"), person("Jason A.", "Vander Heiden"), person("Mohamed", "Uduman"), person("Daniel", "Gadala-Maria"), person("Gur", "Yaari"), person("Steven H.", "Kleinstein")), year = 2015, journal = "Bioinformatics", pages = "1-3", doi = "10.1093/bioinformatics/btv359") bibentry(bibtype = "Article", style = "citation", header = "To cite the selection analysis methods, please use:", title = "Quantifying selection in high-throughput Immunoglobulin sequencing data sets.", author = c(person("Gur", "Yaari"), person("Mohamed", "Uduman"), person("Steven H.", "Kleinstein")), year = 2012, journal = "Nucleic acids research", volume = 40, number = 17, pages = "e134", doi = "10.1093/nar/gks457") bibentry(bibtype = "Article", style = "citation", header = "To cite the HH_S5F model and the targeting model generation methods, please use:", title = "Models of somatic hypermutation targeting and substitution based on synonymous mutations from high-throughput immunoglobulin sequencing data.", author = c(person("Gur", "Yaari"), person("Jason A.", "Vander Heiden"), person("Mohamed", "Uduman"), person("Daniel", "Gadala-Maria"), person("Namita T.", "Gupta"), person("Joel N. H.", "Stern"), person("Kevin C.", "O'Connor"), person("David A.", "Hafler"), person("Uri", "Lasserson"), person("Francois", "Vigneault"), person("Steven H.", "Kleinstein")), year = 2013, journal = "Frontiers in Immunology", volume = 4, number = 358, pages = "1-11", doi = "10.3389/fimmu.2013.00358") bibentry(bibtype = "Article", style = "citation", header = "To cite the HKL_S1F, HKL_S5F, MK_RS1NF, and MK_RS5NF models, please use:", title = "A Model of Somatic Hypermutation Targeting in Mice Based on High-Throughput Ig Sequencing Data.", author = c(person("Ang", "Cui"), person("Roberto", "Di Niro"), person("Jason A.", "Vander Heiden"), person("Adrian W.", "Briggs"), person("Kris", "Adams"), person("Tamara", "Gilbert"), person("Kevin C.", "O'Connor"), person("Francois", "Vigneault"), person("Mark J.", "Shlomchik"), person("Steven H.", "Kleinstein")), year = 2016, journal = "The Journal of Immunology", volume = 197, number = 9, pages = "3566-3574", doi = "10.4049/jimmunol.1502263")