iterators/0000755000176200001440000000000013516701632012272 5ustar liggesusersiterators/NAMESPACE0000644000176200001440000000114213514435434013511 0ustar liggesusersexport(iter, nextElem, isplit) export(irnorm, irunif, irbinom, irnbinom, irpois) export(icount, idiv, ireadLines, iread.table) export(makeIwrapper, isample) export(icountn, iapply) S3method("iter", "default") S3method("iter", "iter") S3method("iter", "matrix") S3method("iter", "data.frame") S3method("iter", "function") S3method("nextElem", "containeriter") S3method("nextElem", "matrixiter") S3method("nextElem", "dataframeiter") S3method("nextElem", "funiter") S3method("nextElem", "abstractiter") S3method("as.list", "iter") S3method("isplit", "default") S3method("isplit", "data.frame") iterators/man/0000755000176200001440000000000013516640502013043 5ustar liggesusersiterators/man/isplit.Rd0000644000176200001440000000144713513447415014651 0ustar liggesusers\name{isplit} \alias{isplit} \title{Split Iterator} \description{ Returns an iterator that divides the data in the vector \code{x} into the groups defined by \code{f}. } \usage{ isplit(x, f, drop=FALSE, \dots) } \arguments{ \item{x}{vector or data frame of values to be split into groups.} \item{f}{a factor or list of factors used to categorize \code{x}.} \item{drop}{logical indicating if levels that do not occur should be dropped.} \item{\dots}{current ignored.} } \value{ The split iterator. } \seealso{ \code{\link{split}} } \examples{ x <- rnorm(200) f <- factor(sample(1:10, length(x), replace=TRUE)) it <- isplit(x, f) expected <- split(x, f) for (i in expected) { actual <- nextElem(it) stopifnot(actual$value == i) } } \keyword{utilities} iterators/man/iterators-package.Rd0000644000176200001440000000205313513447415016744 0ustar liggesusers\name{iterators-package} \alias{iterators-package} \alias{iterators} \docType{package} \title{ The Iterators Package } \description{ The iterators package provides tools for iterating over various R data structures. Iterators are available for vectors, lists, matrices, data frames, and files. By following very simple conventions, new iterators can be written to support any type of data source, such as database queries or dynamically generated data. } \details{ Further information is available in the following help topics: \tabular{ll}{ \code{iter} \tab Generic function used to create iterator objects.\cr \code{nextElem} \tab Generic function used to get the next element of a iterator.\cr \code{icount} \tab A function used to create a counting iterator.\cr \code{idiv} \tab A function used to create a number dividing iterator.\cr \code{ireadLines} \tab A function used to create a file reading iterator.\cr } For a complete list of functions with individual help pages, use \code{library(help="iterators")}. } \keyword{package} iterators/man/icount.Rd0000644000176200001440000000111513513447415014636 0ustar liggesusers\name{icount} \alias{icount} \alias{icountn} \title{Counting Iterators} \description{ Returns an iterator that counts starting from one. } \usage{ icount(count) icountn(vn) } \arguments{ \item{count}{number of times that the iterator will fire. If not specified, it will count forever.} \item{vn}{vector of counts.} } \value{ The counting iterator. } \examples{ # create an iterator that counts from 1 to 3. it <- icount(3) nextElem(it) nextElem(it) nextElem(it) try(nextElem(it)) # expect a StopIteration exception } \keyword{utilities} iterators/man/iter.Rd0000644000176200001440000000363413513447415014310 0ustar liggesusers\name{iter} \alias{iter} \alias{iter.default} \alias{iter.iter} \alias{iter.matrix} \alias{iter.data.frame} \alias{iter.function} \title{Iterator Factory Functions} \description{ \code{iter} is a generic function used to create iterator objects. } \usage{ iter(obj, \dots) \method{iter}{default}(obj, checkFunc=function(...) TRUE, recycle=FALSE, \dots) \method{iter}{iter}(obj, \dots) \method{iter}{matrix}(obj, by=c('column', 'cell', 'row'), chunksize=1L, checkFunc=function(...) TRUE, recycle=FALSE, \dots) \method{iter}{data.frame}(obj, by=c('column', 'row'), checkFunc=function(...) TRUE, recycle=FALSE, \dots) \method{iter}{function}(obj, checkFunc=function(...) TRUE, recycle=FALSE, \dots) } \arguments{ \item{obj}{an object from which to generate an iterator.} \item{by}{how to iterate.} \item{chunksize}{the number of elements of \code{by} to return with each call to \code{nextElem}.} \item{checkFunc}{a function which, when passed an iterator value, return \code{TRUE} or \code{FALSE}. If \code{FALSE}, the value is skipped in the iteration.} \item{recycle}{a boolean describing whether the iterator should reset after running through all it's values.} \item{\dots}{additional arguments affecting the iterator.} } \value{ The iterator. } \examples{ # a vector iterator i1 <- iter(1:3) nextElem(i1) nextElem(i1) nextElem(i1) # a vector iterator with a checkFunc i1 <- iter(1:3, checkFunc=function(i) i \%\% 2 == 0) nextElem(i1) # a data frame iterator by column i2 <- iter(data.frame(x=1:3, y=10, z=c('a', 'b', 'c'))) nextElem(i2) nextElem(i2) nextElem(i2) # a data frame iterator by row i3 <- iter(data.frame(x=1:3, y=10), by='row') nextElem(i3) nextElem(i3) nextElem(i3) # a function iterator i4 <- iter(function() rnorm(1)) nextElem(i4) nextElem(i4) nextElem(i4) } \keyword{methods} iterators/man/iapply.Rd0000644000176200001440000000150613513447415014637 0ustar liggesusers\name{iapply} \alias{iapply} \title{Array/Apply Iterator} \description{ Returns an iterator over an array, which iterates over the array in much the same manner as the \code{apply} function. } \usage{ iapply(X, MARGIN) } \arguments{ \item{X}{the array to iterate over.} \item{MARGIN}{a vector of subscripts. \code{1} indicates the first dimension (rows), \code{2} indicates the second dimension (columns), etc.} } \value{ The apply iterator. } \seealso{ \code{\link{apply}} } \examples{ a <- array(1:8, c(2, 2, 2)) # iterate over all the matrices it <- iapply(a, 3) as.list(it) # iterate over all the columns of all the matrices it <- iapply(a, c(2, 3)) as.list(it) # iterate over all the rows of all the matrices it <- iapply(a, c(1, 3)) as.list(it) } \keyword{utilities} iterators/man/irnorm.Rd0000644000176200001440000000171413513447415014650 0ustar liggesusers\name{irnorm} \alias{irnorm} \alias{irunif} \alias{irbinom} \alias{irnbinom} \alias{irpois} \title{Random Number Iterators} \description{ These function returns an iterators that return random numbers of various distributions. Each one is a wrapper around a standard \code{R} function. } \usage{ irnorm(..., count) irunif(..., count) irbinom(..., count) irnbinom(..., count) irpois(..., count) } \arguments{ \item{count}{number of times that the iterator will fire. If not specified, it will fire values forever.} \item{\dots}{arguments to pass to the underlying \code{rnorm} function.} } \value{ An iterator that is a wrapper around the corresponding random number generator function. } \examples{ # create an iterator that returns three random numbers it <- irnorm(1, count=3) nextElem(it) nextElem(it) nextElem(it) try(nextElem(it)) # expect a StopIteration exception } \keyword{utilities} iterators/man/nextElem.Rd0000644000176200001440000000155313513447415015124 0ustar liggesusers\name{nextElem} \alias{nextElem} \alias{nextElem.containeriter} \alias{nextElem.funiter} \title{Get Next Element of Iterator} \description{ \code{nextElem} is a generic function used to produce values. If a \code{checkFunc} was specified to the constructor, the potential iterated values will be passed to the \code{checkFunc} until the \code{checkFunc} returns \code{TRUE}. When the iterator has no more values, it calls stop with the message 'StopIteration'. } \usage{ nextElem(obj, \dots) \method{nextElem}{containeriter}(obj, \dots) \method{nextElem}{funiter}(obj, \dots) } \arguments{ \item{obj}{an iterator object.} \item{\dots}{additional arguments that are ignored.} } \value{ The value. } \examples{ it <- iter(c('a', 'b', 'c')) print(nextElem(it)) print(nextElem(it)) print(nextElem(it)) } \keyword{methods} iterators/man/ireadLines.Rd0000644000176200001440000000156013513447415015420 0ustar liggesusers\name{ireadLines} \alias{ireadLines} \title{Iterator over Lines of Text from a Connection} \description{ Returns an iterator over the lines of text from a connection. It is a wrapper around the standard \code{readLines} function. } \usage{ ireadLines(con, n=1, ...) } \arguments{ \item{con}{a connection object or a character string.} \item{n}{integer. The maximum number of lines to read. Negative values indicate that one should read up to the end of the connection. The default value is 1.} \item{\dots}{passed on to the \code{readLines} function.} } \value{ The line reading iterator. } \seealso{ \code{\link[base]{readLines}} } \examples{ # create an iterator over the lines of COPYING it <- ireadLines(file.path(R.home(), 'COPYING')) nextElem(it) nextElem(it) nextElem(it) } \keyword{utilities} iterators/man/makeIwrapper.Rd0000644000176200001440000000271113516640471015767 0ustar liggesusers\name{makeIwrapper} \alias{makeIwrapper} \alias{isample} \title{Iterator Maker Generator} \description{ The \code{makeIwrapper} function makes iterator makers. The resulting iterator makers all take an optional \code{count} argument which specifies the number of times the resulting iterator should fire. The iterators are wrappers around functions that return different values each time they are called. The \code{isample} function is an example of one such iterator maker (as are \code{irnorm}, \code{irunif}, etc.). } \usage{ makeIwrapper(FUN) isample(..., count) } \arguments{ \item{FUN}{a character string naming a function that generates different values each time it is called; typically one of the standard random number generator functions.} \item{count}{number of times that the iterator will fire. If not specified, it will fire values forever.} \item{\dots}{arguments to pass to the underlying \code{FUN} function.} } \value{ An iterator that is a wrapper around the corresponding function. } \examples{ # create an iterator maker for the sample function mysample <- makeIwrapper('sample') # use this iterator maker to generate an iterator # that will generate three five member samples from the # sequence 1:100 it <- mysample(1:100, 5, count=3) nextElem(it) nextElem(it) nextElem(it) try(nextElem(it)) # expect a StopIteration exception } \keyword{utilities} iterators/man/iread.table.Rd0000644000176200001440000000236013513447415015512 0ustar liggesusers\name{iread.table} \alias{iread.table} \title{Iterator over Rows of a Data Frame Stored in a File} \description{ Returns an iterator over the rows of a data frame stored in a file in table format. It is a wrapper around the standard \code{read.table} function. } \usage{ iread.table(file, ..., verbose=FALSE) } \arguments{ \item{file}{the name of the file to read the data from.} \item{\dots}{all additional arguments are passed on to the \code{read.table} function. See the documentation for \code{read.table} for more information.} \item{verbose}{logical value indicating whether or not to print the calls to \code{read.table}.} } \value{ The file reading iterator. } \note{ In this version of \code{iread.table}, both the \code{read.table} arguments \code{header} and \code{row.names} must be specified. This is because the default values of these arguments depend on the contents of the beginning of the file. In order to make the subsequent calls to \code{read.table} work consistently, the user must specify those arguments explicitly. A future version of \code{iread.table} may remove this requirement. } \seealso{ \code{\link[utils]{read.table}} } \keyword{utilities} iterators/man/idiv.Rd0000644000176200001440000000233213513447415014272 0ustar liggesusers\name{idiv} \alias{idiv} \title{Dividing Iterator} \description{ Returns an iterator that returns pieces of numeric value. } \usage{ idiv(n, ..., chunks, chunkSize) } \arguments{ \item{n}{number of times that the iterator will fire. If not specified, it will count forever.} \item{\dots}{unused.} \item{chunks}{the number of pieces that \code{n} should be divided into. This is useful when you know the number of pieces that you want. If specified, then \code{chunkSize} should not be.} \item{chunkSize}{the maximum size of the pieces that \code{n} should be divided into. This is useful when you know the size of the pieces that you want. If specified, then \code{chunks} should not be.} } \value{ The dividing iterator. } \examples{ # divide the value 10 into 3 pieces it <- idiv(10, chunks=3) nextElem(it) nextElem(it) nextElem(it) try(nextElem(it)) # expect a StopIteration exception # divide the value 10 into pieces no larger than 3 it <- idiv(10, chunkSize=3) nextElem(it) nextElem(it) nextElem(it) nextElem(it) try(nextElem(it)) # expect a StopIteration exception } \keyword{utilities} iterators/DESCRIPTION0000644000176200001440000000140613516701632014001 0ustar liggesusersPackage: iterators Type: Package Title: Provides Iterator Construct Version: 1.0.12 Authors@R: c(person("Hong", "Ooi", role="cre", email="hongooi@microsoft.com"), person("Revolution", "Analytics", role=c("aut", "cph")), person("Steve", "Weston", role="aut")) Description: Support for iterators, which allow a programmer to traverse through all the elements of a vector, list, or other collection of data. Depends: R (>= 2.5.0), utils Suggests: RUnit, foreach License: Apache License (== 2.0) NeedsCompilation: no Packaged: 2019-07-26 18:07:06 UTC; richcala Author: Hong Ooi [cre], Revolution Analytics [aut, cph], Steve Weston [aut] Maintainer: Hong Ooi Repository: CRAN Date/Publication: 2019-07-26 22:50:02 UTC iterators/build/0000755000176200001440000000000013516640512013370 5ustar liggesusersiterators/build/vignette.rds0000644000176200001440000000034713516640512015733 0ustar liggesusersuOQ 0, G""^G،m!˵/LG=lv!aA./`a[C3 2Ja%bRCG[DT5Zoj{4t,Z^{zn0J+&LuT);NLj8GU à@UlffOؚFH_ӌ(RKYiterators/tests/0000755000176200001440000000000013513447415013437 5ustar liggesusersiterators/tests/doRUnit.R0000644000176200001440000000533313513447415015152 0ustar liggesusers## unit tests will not be done if RUnit is not available if(require("RUnit", quietly=TRUE)) { ## --- Setup --- pkg <- "iterators" # <-- Change to package name! if(Sys.getenv("RCMDCHECK") == "FALSE") { ## Path to unit tests for standalone running under Makefile (not R CMD check) ## PKG/tests/../inst/unitTests path <- file.path(getwd(), "..", "inst", "unitTests") } else { ## Path to unit tests for R CMD check ## PKG.Rcheck/tests/../PKG/unitTests path <- system.file(package=pkg, "unitTests") } cat("\nRunning unit tests\n") print(list(pkg=pkg, getwd=getwd(), pathToUnitTests=path)) library(package=pkg, character.only=TRUE) ################################################################ ## BEGIN PACKAGE SPECIFIC CONFIGURATION # ################################################################ ################################################################ ## END PACKAGE SPECIFIC CONFIGURATION # ################################################################ ## If desired, load the name space to allow testing of private functions ## if (is.element(pkg, loadedNamespaces())) ## attach(loadNamespace(pkg), name=paste("namespace", pkg, sep=":"), pos=3) ## ## or simply call PKG:::myPrivateFunction() in tests ## --- Testing --- ## Define tests testSuite <- defineTestSuite(name=paste(pkg, "unit testing"), dirs=path, testFileRegexp = "^.+Test\\.R$") ## Run tests <- runTestSuite(testSuite) ## Default report name pathReport <- file.path(tempdir(), "report") ## Report to stdout and text files cat("------------------- UNIT TEST SUMMARY ---------------------\n\n") printTextProtocol(tests, showDetails=FALSE) printTextProtocol(tests, showDetails=FALSE, fileName=paste(pathReport, "Summary.txt", sep="")) printTextProtocol(tests, showDetails=TRUE, fileName=paste(pathReport, ".txt", sep="")) ## Report to HTML file printHTMLProtocol(tests, fileName=paste(pathReport, ".html", sep="")) # printHTMLProtocol(tests, fileName=file.path(dirname(dirname(getwd())),pkg,"gsDesign-RUnit-Test-Summary.html")) #paste(pathReport, ".html", sep="")) ## Return stop() to cause R CMD check stop in case of ## - failures i.e. FALSE to unit tests or ## - errors i.e. R errors tmp <- getErrors(tests) if(tmp$nFail > 0 | tmp$nErr > 0) { stop(paste("\n\nunit testing failed (#test failures: ", tmp$nFail, ", #R errors: ", tmp$nErr, ")\n\n", sep="")) } } else { warning("cannot run unit tests -- package RUnit is not available") } iterators/vignettes/0000755000176200001440000000000013516640512014301 5ustar liggesusersiterators/vignettes/iterators.Rnw0000644000176200001440000001437413513447415017022 0ustar liggesusers% \VignetteIndexEntry{iterators Manual} % \VignetteDepends{iterators} % \VignettePackage{iterators} \documentclass[12pt]{article} \usepackage{amsmath} \usepackage[pdftex]{graphicx} \usepackage{color} \usepackage{xspace} \usepackage{fancyvrb} \usepackage{fancyhdr} \usepackage[ colorlinks=true, linkcolor=blue, citecolor=blue, urlcolor=blue] {hyperref} \usepackage{lscape} \usepackage{Sweave} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % define new colors for use \definecolor{darkgreen}{rgb}{0,0.6,0} \definecolor{darkred}{rgb}{0.6,0.0,0} \definecolor{lightbrown}{rgb}{1,0.9,0.8} \definecolor{brown}{rgb}{0.6,0.3,0.3} \definecolor{darkblue}{rgb}{0,0,0.8} \definecolor{darkmagenta}{rgb}{0.5,0,0.5} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\bld}[1]{\mbox{\boldmath $#1$}} \newcommand{\shell}[1]{\mbox{$#1$}} \renewcommand{\vec}[1]{\mbox{\bf {#1}}} \newcommand{\ReallySmallSpacing}{\renewcommand{\baselinestretch}{.6}\Large\normalsize} \newcommand{\SmallSpacing}{\renewcommand{\baselinestretch}{1.1}\Large\normalsize} \newcommand{\halfs}{\frac{1}{2}} \setlength{\oddsidemargin}{-.25 truein} \setlength{\evensidemargin}{0truein} \setlength{\topmargin}{-0.2truein} \setlength{\textwidth}{7 truein} \setlength{\textheight}{8.5 truein} \setlength{\parindent}{0.20truein} \setlength{\parskip}{0.10truein} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \pagestyle{fancy} \lhead{} \chead{Using The {\tt iterators} Package} \rhead{} \lfoot{} \cfoot{} \rfoot{\thepage} \renewcommand{\headrulewidth}{1pt} \renewcommand{\footrulewidth}{1pt} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \title{Using The {\tt iterators} Package} \author{Rich Calaway} \begin{document} \maketitle \thispagestyle{empty} \section{Introduction} An {\em iterator} is a special type of object that generalizes the notion of a looping variable. When passed as an argument to a function that knows what to do with it, the iterator supplies a sequence of values. The iterator also maintains information about its state, in particular its current index. The \texttt{iterators} package includes a number of functions for creating iterators, the simplest of which is \texttt{iter}, which takes virtually any R object and turns it into an iterator object. The simplest function that operates on iterators is the \texttt{nextElem} function, which when given an iterator, returns the next value of the iterator. For example, here we create an iterator object from the sequence 1 to 10, and then use \texttt{nextElem} to iterate through the values: <>= library(iterators) i1 <- iter(1:10) nextElem(i1) nextElem(i1) @ You can create iterators from matrices and data frames, using the \texttt{by} argument to specify whether to iterate by row or column: <>= istate <- iter(state.x77, by='row') nextElem(istate) nextElem(istate) @ Iterators can also be created from functions, in which case the iterator can be an endless source of values: <>= ifun <- iter(function() sample(0:9, 4, replace=TRUE)) nextElem(ifun) nextElem(ifun) @ For practical applications, iterators can be paired with \texttt{foreach} to obtain parallel results quite easily: \begin{Schunk} \begin{Sinput} > library(foreach) \end{Sinput} \begin{Soutput} foreach: simple, scalable parallel programming from Revolution Analytics Use Revolution R for scalability, fault tolerance and more. http://www.revolutionanalytics.com \end{Soutput} \begin{Sinput} > x <- matrix(rnorm(1e+06), ncol = 10000) > itx <- iter(x, by = "row") > foreach(i = itx, .combine = c) %dopar% mean(i) \end{Sinput} \begin{Soutput} [1] -0.0069652059 0.0161112989 0.0080068074 -0.0120020610 0.0017168149 [6] 0.0139835943 -0.0078172106 -0.0024762273 -0.0031558268 -0.0072662893 [11] -0.0055142639 0.0015717907 -0.0100842965 -0.0123601527 0.0136420084 [16] -0.0242922105 -0.0126416949 -0.0052951152 0.0216329326 -0.0262476648 [21] 0.0041937609 0.0121253368 -0.0110165729 0.0044267635 0.0080241894 [26] 0.0042995539 -0.0102826632 0.0051185628 -0.0013970812 -0.0172380786 [31] 0.0096079613 0.0046837729 -0.0080726970 0.0083781727 -0.0234620163 [36] -0.0099883966 0.0026883628 0.0029367320 0.0205825899 0.0035303940 [41] 0.0204990426 -0.0010804987 -0.0033665481 -0.0127492019 -0.0147443195 [46] 0.0027046346 0.0016449793 0.0155575490 -0.0003488394 -0.0079238019 [51] 0.0086390030 -0.0039033309 0.0168593825 -0.0067189572 -0.0009925288 [56] -0.0162907048 -0.0059171838 0.0093806072 0.0100886929 -0.0111677408 [61] 0.0021754963 -0.0056770907 0.0081200698 -0.0029828717 -0.0163704350 [66] 0.0057266267 -0.0017156156 0.0214172738 -0.0141379874 -0.0126593342 [71] 0.0087124575 0.0040231519 0.0038515673 0.0066066908 0.0023586046 [76] -0.0044167901 -0.0090543553 0.0010806096 0.0102288061 0.0039881702 [81] -0.0054549319 -0.0127997275 -0.0031697122 -0.0016100996 -0.0143468118 [86] 0.0035904125 -0.0059399479 0.0085565480 -0.0159064868 0.0054120554 [91] -0.0084420572 0.0194448129 -0.0103192553 -0.0062924628 0.0215069258 [96] 0.0015749065 0.0109657488 0.0152237842 -0.0057181022 0.0035530715 \end{Soutput} \end{Schunk} \section{Some Special Iterators} The notion of an iterator is new to R, but should be familiar to users of languages such as Python. The \texttt{iterators} package includes a number of special functions that generate iterators for some common scenarios. For example, the \texttt{irnorm} function creates an iterator for which each value is drawn from a specified random normal distribution: <>= library(iterators) itrn <- irnorm(10) nextElem(itrn) nextElem(itrn) @ Similarly, the \texttt{irunif}, \texttt{irbinom}, and \texttt{irpois} functions create iterators which drawn their values from uniform, binomial, and Poisson distributions, respectively. We can then use these functions just as we used \texttt{irnorm}: <>= itru <- irunif(10) nextElem(itru) nextElem(itru) @ The \texttt{icount} function returns an iterator that counts starting from one: <>= it <- icount(3) nextElem(it) nextElem(it) nextElem(it) @ \end{document} iterators/vignettes/writing.Rnw0000644000176200001440000005115113513447415016463 0ustar liggesusers% \VignetteIndexEntry{Writing Custom Iterators} % \VignetteDepends{iterators} % \VignettePackage{iterators} \documentclass[12pt]{article} \usepackage{amsmath} \usepackage[pdftex]{graphicx} \usepackage{color} \usepackage{xspace} \usepackage{fancyvrb} \usepackage{fancyhdr} \usepackage[ colorlinks=true, linkcolor=blue, citecolor=blue, urlcolor=blue] {hyperref} \usepackage{lscape} \usepackage{Sweave} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % define new colors for use \definecolor{darkgreen}{rgb}{0,0.6,0} \definecolor{darkred}{rgb}{0.6,0.0,0} \definecolor{lightbrown}{rgb}{1,0.9,0.8} \definecolor{brown}{rgb}{0.6,0.3,0.3} \definecolor{darkblue}{rgb}{0,0,0.8} \definecolor{darkmagenta}{rgb}{0.5,0,0.5} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\bld}[1]{\mbox{\boldmath $#1$}} \newcommand{\shell}[1]{\mbox{$#1$}} \renewcommand{\vec}[1]{\mbox{\bf {#1}}} \newcommand{\ReallySmallSpacing}{\renewcommand{\baselinestretch}{.6}\Large\normalsize} \newcommand{\SmallSpacing}{\renewcommand{\baselinestretch}{1.1}\Large\normalsize} \newcommand{\halfs}{\frac{1}{2}} \setlength{\oddsidemargin}{-.25 truein} \setlength{\evensidemargin}{0truein} \setlength{\topmargin}{-0.2truein} \setlength{\textwidth}{7 truein} \setlength{\textheight}{8.5 truein} \setlength{\parindent}{0.20truein} \setlength{\parskip}{0.10truein} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \pagestyle{fancy} \lhead{} \chead{Writing Custom Iterators} \rhead{} \lfoot{} \cfoot{} \rfoot{\thepage} \renewcommand{\headrulewidth}{1pt} \renewcommand{\footrulewidth}{1pt} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \title{Writing Custom Iterators} \author{Steve Weston} \begin{document} \maketitle \thispagestyle{empty} \section{Introduction} <>= library(iterators) @ An {\em iterator} is a special type of object that supplies data on demand, one element\footnote{An ``element'' in this case can be basically any object. I don't mean to suggest that the data is necessarily returned as scalar values, for example.} at a time. This is a nice abstraction that can help simplify many programs. Iterators are particularly useful in parallel computing, since they facilitate splitting a problem into smaller pieces that can then be executed in parallel. Iterators can also be used to reduce the total memory that is needed at any one time. For example, if you want to process the lines of text in a file, it is common to write a loop that reads the file one line at a time, rather than reading the entire file in order to avoid running out of memory on huge files. That's the basic idea of iterators. Iterators provide a standard method for getting the next element, which allows us to write functions that take an iterator as an argument to provide a source of data. The function doesn't need to know what kind of iterator it is. It just needs to know how to get another piece of data. The data could be coming from a file, a database, a vector, or it could be dynamically generated. There are a number of iterators that come in the \texttt{iterators} package. The \texttt{iapply} function allows you to iterate over arrays, in much the same way as the standard \texttt{apply} function. \texttt{apply} has fixed rules on how the results are returned, which may require you to reshape the results, which can be inefficient, as well as inconvenient. But since \texttt{iapply} doesn't process any data or combine the results, it is more flexible. You can use \texttt{iapply} with the \texttt{foreach} package to perform a parallel \texttt{apply} operation, and combine the results any way you want via the \texttt{.combine} argument to \texttt{foreach}. Another iterator that comes in the \texttt{iterators} package is the \texttt{isplit} function, which works much like the standard \texttt{split} function. \texttt{split} returns a list containing all of the data divided into groups. \texttt{isplit} only generates one group at a time, as they are needed, which can reduce the amount memory that is needed. But of course, there will be times when you need an iterator that isn't provided by the \texttt{iterators} package. That is when you need to write your own custom iterator. Fortunately, that is fairly easy to do. \section{What methods are needed for an iterator?} Basically, an iterator is an S3 object whose base class is \texttt{iter}, and has \texttt{iter} and \texttt{nextElem} methods. The purpose of the \texttt{iter} method is to return an iterator for the specified object. For iterators, that usually just means returning itself, which seems odd at first. But the \texttt{iter} method can be defined for other objects that don't define a \texttt{nextElem} method. We call those objects {\em iterables}, meaning that you can iterate over them. The \texttt{iterators} package defines \texttt{iter} methods for vectors, lists, matrices, and data frames, making those objects iterables. By defining an \texttt{iter} method for iterators, they can be used in the same context as an iterable, which can be convenient. For example, the \texttt{foreach} function takes iterables as arguments. It calls the \texttt{iter} method on those arguments in order to create iterators for them. By defining the \texttt{iter} method for all iterators, we can pass iterators to \texttt{foreach} that we created using any method we choose. Thus, we can pass vectors, lists, or iterators to \texttt{foreach}, and they are all processed by \texttt{foreach} in exactly the same way. The \texttt{iterators} package comes with an \texttt{iter} method defined for the \texttt{iter} class that simply returns itself. That is usually all that is needed for an iterator. However, if you want to create an iterator for some existing class, you can do that by writing an \texttt{iter} method that returns an appropriate iterator. That will allow you to pass an instance of your class to \texttt{foreach}, which will automatically convert it into an iterator. The alternative is to write your own function that takes arbitrary arguments, and returns an iterator. You can choose whichever method is most natural. The most important method required for iterators is \texttt{nextElem}. This simply returns the next value, or throws an error. Calling the \texttt{stop} function with the string \texttt{'StopIteration'} indicates that there are no more values available in the iterator. Now before we write our own iterator, let's try calling the \texttt{iter} and \texttt{nextElem} methods on an existing one. Since a list is an iterable, we can create an iterator for that list by calling \texttt{iter} on it: <>= it <- iter(list(1:2, 3:4)) @ We can now call \texttt{nextElem} on the resulting iterator to get the values from the list: <>= nextElem(it) nextElem(it) tryCatch(nextElem(it), error=function(e) e) @ As you can see, it is possible to call these methods manually, but it's somewhat awkward, since you have to handle the \texttt{'StopIteration'} error. Later on, we'll see one solution to this difficulty, although, in general, you don't call these method explicitly. \section{A simple iterator} It's time to show the implementation of a very simple iterator. Although I've made it sound like you have to write your own \texttt{iter} and \texttt{nextElem} methods, you can inherit them. In fact, that's what all of the following examples do. I do that by inheriting from the \texttt{abstractiter} class. The \texttt{abstractiter} class uses the standard \texttt{iter} method which returns itself, and defines a \texttt{nextElem} method that calls the \texttt{nextElem} element of the object. Let's take a look at the implementation of these two methods: <>= iterators:::iter.iter iterators:::nextElem.abstractiter @ Now here's a function that creates a very simple iterator that uses these two methods: <>= iforever <- function(x) { nextEl <- function() x obj <- list(nextElem=nextEl) class(obj) <- c('iforever', 'abstractiter', 'iter') obj } @ Note that I called the internal function \texttt{nextEl} rather than \texttt{nextElem}. I do that by convention to avoid masking the standard \texttt{nextElem} generic function. That causes problems when you want your iterator to call the \texttt{nextElem} method of another iterator, which can be quite useful, as we'll see in a later example. We create an instance of this iterator by calling the \texttt{iforever} function, and then use it by calling the \texttt{nextElem} method on the resulting object: <>= it <- iforever(42) nextElem(it) nextElem(it) @ You can also get values from an iterator using \texttt{as.list}. But since this is an infinite iterator, you need to use the \texttt{n} argument to avoid using up a lot of memory and time: <>= unlist(as.list(it, n=6)) @ Notice that it doesn't make sense to implement this iterator by defining a new \texttt{iter} method, since there is no natural iterable on which to dispatch. The only argument that we need is the object for the iterator to return, which can be of any type. Instead, we implement this iterator by defining a normal function that returns the iterator. This iterator is quite simple to implement, and possibly even useful.\footnote{Be careful how you use this iterator! If you pass it to \texttt{foreach}, it will result in an infinite loop unless you pair it with a non-infinite iterator. Also, {\em never} pass this to the \texttt{as.list} function without the \texttt{n} argument.} The iterator returned by \texttt{iforever} is a list that has a single element named \texttt{nextElem}, whose value is a function that returns the value of \texttt{x}. Because we are subclassing \texttt{abstractiter}, we inherit a \texttt{nextElem} method that will call this function, and because we are subclassing \texttt{iter}, we inherit an \texttt{iter} method that will return itself. Of course, the reason this iterator is so simple is because it doesn't contain any state. Most iterators need to contain some state, or it will be difficult to make it return different values and eventually stop. Managing the state is usually the real trick to writing iterators. \section{A stateful iterator} Let's modify the previous iterator to put a limit on the number of values that it returns. I'll call the new function \texttt{irep}, and give it another argument called \texttt{times}: <>= irep <- function(x, times) { nextEl <- function() { if (times > 0) times <<- times - 1 else stop('StopIteration') x } obj <- list(nextElem=nextEl) class(obj) <- c('irep', 'abstractiter', 'iter') obj } @ Now let's try it out: <>= it <- irep(7, 6) unlist(as.list(it)) @ The real difference between \texttt{iforever} and \texttt{irep} is in the function that gets called by the \texttt{nextElem} method. This function not only accesses the values of the variables \texttt{x} and \texttt{times}, but it also modifies the value of \texttt{times}. This is accomplished by means of the ``\verb=<<-='' \footnote{It's commonly believed that ``$<<-$'' is only used to set variables in the global environment, but that isn't true. I think of it as an {\em inheriting} assignment operator.} operator, and the magic of lexical scoping. Technically, this kind of function is called a {\em closure}, and is a somewhat advanced feature of \texttt{R}. The important thing to remember is that \texttt{nextEl} is able to get the value of variables that were passed as arguments to \texttt{irep}, and it can modify those values using the ``\verb=<<-='' operator. These are {\em not} global variables: they are defined in the enclosing environment of the \texttt{nextEl} function. You can create as many iterators as you want using the \texttt{irep} function, and they will all work as expected without conflicts. Note that this iterator only uses the arguments to \texttt{irep} to store its state. If any other state variables are needed, they can be defined anywhere inside the \texttt{irep} function. \section{Using an iterator inside an iterator} The previous section described a general way of writing custom iterators. Almost any iterator can be written using those basic techniques. At times, it may be simpler to make use of an existing iterator to implement a new iterator. Let's say that you need an iterator that splits a vector into subvectors. That can allow you to process the vector in parallel, but still use vector operations, which is essential to getting good sequential performance in R. The following function returns just such an iterator: <>= ivector <- function(x, ...) { i <- 1 it <- idiv(length(x), ...) nextEl <- function() { n <- nextElem(it) ix <- seq(i, length=n) i <<- i + n x[ix] } obj <- list(nextElem=nextEl) class(obj) <- c('ivector', 'abstractiter', 'iter') obj } @ \texttt{ivector} uses \texttt{...} to pass options on to \texttt{idiv}. \texttt{idiv} supports the \texttt{chunks} argument to split its argument into a specified number of pieces, and the \texttt{chunkSize} argument to split it into pieces of a specified maximum size. Let's create an \texttt{ivector} iterator to split a vector into three pieces using the \texttt{chunks} argument: <>= it <- ivector(1:25, chunks=3) as.list(it) @ Note that the \texttt{nextEl} function doesn't seem to throw a \texttt{StopIteration} exception. It is actually throwing it indirectly, by calling \texttt{nextElem} on the iterator created via the \texttt{idiv} function. This function is fairly simple, because most of the tricky stuff is handled by \texttt{idiv}. \texttt{ivector} focuses on operating on the vector. It should be clear that only minor modification need to be made to this function to create an iterator over the blocks of rows or columns of a matrix or data frame. But I'll leave that as an exercise for the reader. \section{Adding a \texttt{hasNext} method to an iterator} At times it would be nice to write a loop that explicitly gets the values of an iterator. Although that is certainly possible with a standard iterator, it requires some rather awkward error handling. One solution to this problem is to add a method that indicates whether there is another value available in the iterator. Then you can write a simple while loop that stops when there are no more values. One way to do that would be to define a new S3 method called \texttt{hasNext}. Here's the definition of a \texttt{hasNext} generic function: <>= hasNext <- function(obj, ...) { UseMethod('hasNext') } @ We also need to define \texttt{hasNext} method for a iterator class that we'll call \texttt{ihasNext}: <>= hasNext.ihasNext <- function(obj, ...) { obj$hasNext() } @ As you can see, an \texttt{ihasNext} object must be a list with a \texttt{hasNext} element that is a function. That's the same technique that the \texttt{abstractiter} class uses to implement the \texttt{nextElem} method. Now we'll define a function, called \texttt{ihasNext}, that takes an arbitrary iterator and returns returns an \texttt{ihasNext} iterator that wraps the specified iterator. That allows us to turn any iterator into an \texttt{ihasNext} iterator, thus providing it with a \texttt{hasNext} method:\footnote{Thanks to Hadley Wickham for contributing this function, which I only hacked up a little. You can also find this function, along with \texttt{hasNext} and \texttt{hasNext.ihasNext} in the examples directory of the iterators packages.} <>= ihasNext <- function(it) { if (!is.null(it$hasNext)) return(it) cache <- NULL has_next <- NA nextEl <- function() { if (!hasNx()) stop('StopIteration', call.=FALSE) has_next <<- NA cache } hasNx <- function() { if (!is.na(has_next)) return(has_next) tryCatch({ cache <<- nextElem(it) has_next <<- TRUE }, error=function(e) { if (identical(conditionMessage(e), 'StopIteration')) { has_next <<- FALSE } else { stop(e) } }) has_next } obj <- list(nextElem=nextEl, hasNext=hasNx) class(obj) <- c('ihasNext', 'abstractiter', 'iter') obj } @ When the \texttt{hasNext} method is called, it calls the \texttt{nextElem} method on the underlying iterator, and the resulting value is saved. That value is then passed to the user when \texttt{nextElem} is called. Of course, it also does the right thing if you don't call \texttt{hasNext}, or if you call it multiple times before calling \texttt{nextElem}. So now we can easily create an \texttt{icount} iterator, and get its values in a while loop, without having to do any messy error handling: <>= it <- ihasNext(icount(3)) while (hasNext(it)) { print(nextElem(it)) } @ \section{A recycling iterator} The \texttt{ihasNext} function from the previous section is an interesting example of a function that takes an iterator and returns an iterator that wraps the specified iterator. In that case, we wanted to add another method to the iterator. In this example, we'll return an iterator that recycles the values of the wrapped iterator:\footnote{ Actually, some of the standard \texttt{iter} methods support a \texttt{recycle} argument. But this is a nice example, and a more general solution, since it works on any iterator.} <>= irecycle <- function(it) { values <- as.list(iter(it)) i <- length(values) nextEl <- function() { i <<- i + 1 if (i > length(values)) i <<- 1 values[[i]] } obj <- list(nextElem=nextEl) class(obj) <- c('irecycle', 'abstractiter', 'iter') obj } @ This is fairly nice, but note that this is another one of those infinite iterators that we need to be careful about. Also, make sure that you don't pass an infinite iterator to \texttt{irecycle}. That would be pointless of course, since there's no reason to recycle an iterator that never ends. It would be possible to write this to avoid that problem by not grabbing all of the values right up front, but you would still end up saving values that will never be recycled, so I've opted to keep this simple. Let's try it out: <>= it <- irecycle(icount(3)) unlist(as.list(it, n=9)) @ \section{Limiting infinite iterators} I was tempted to add an argument to the \texttt{irecycle} function to limit the number of values that it returns, because sometimes you want to recycle for awhile, but not forever. I didn't do that, because rather than make \texttt{irecycle} more complicated, I decided to write yet another function that takes an iterator and returns a modified iterator to handle that task: <>= ilimit <- function(it, times) { it <- iter(it) nextEl <- function() { if (times > 0) times <<- times - 1 else stop('StopIteration') nextElem(it) } obj <- list(nextElem=nextEl) class(obj) <- c('ilimit', 'abstractiter', 'iter') obj } @ Note that this looks an awful lot like the \texttt{irep} function that we implemented previously. In fact, using \texttt{ilimit}, we can implement \texttt{irep} using \texttt{iforever} much more simply, and without duplication of code: <>= irep2 <- function(x, times) ilimit(iforever(x), times) @ To demonstrate \texttt{irep2}, I'll use \texttt{ihasNext} and a while loop: <>= it <- ihasNext(irep2('foo', 3)) while (hasNext(it)) { print(nextElem(it)) } @ Here's one last example. Let's recycle a vector three times using \texttt{ilimit}, and convert it back into a vector using \texttt{as.list} and \texttt{unlist}: <>= iterable <- 1:3 n <- 3 it <- ilimit(irecycle(iterable), n * length(iterable)) unlist(as.list(it)) @ Sort of a complicated version of: <>= rep(iterable, n) @ Aren't iterators fun? \section{Conclusion} Writing your own iterators can be quite simple, and yet is very useful and powerful. It provides a very effective way to extend the capabilities of other packages that use iterators, such as the \texttt{foreach} package. By writing iterators that wrap other iterators, it is possible to put together a powerful and flexible set of tools that work well together, and that can solve many of the complex problems that come up in parallel computing. \end{document} iterators/NEWS0000644000176200001440000000030713514450773012776 0ustar liggesusersNEWS/ChangeLog for iterators -------------------------- 1.0.12 2019-07-19 o Exported makeIwrapper function; request of Bill Venables. o Exported isample iterator maker function. iterators/R/0000755000176200001440000000000013513447415012476 5ustar liggesusersiterators/R/aslist.R0000644000176200001440000000204213513447415014116 0ustar liggesusers# # Copyright (c) 2008-2010 Revolution Analytics # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # as.list.iter <- function(x, n=as.integer(2^31-1), ...) { size <- 64 a <- vector('list', length=size) i <- 0 tryCatch({ while (i < n) { if (i >= size) { size <- min(2 * size, n) length(a) <- size } a[i + 1] <- list(nextElem(x)) i <- i + 1 } }, error=function(e) { if (!identical(conditionMessage(e), 'StopIteration')) stop(e) }) length(a) <- i a } iterators/R/isplit.R0000644000176200001440000000542713513447415014135 0ustar liggesusers# # Copyright (c) 2008-2010 Revolution Analytics # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # icountn <- function(vn) { n <- length(vn) if (n == 0) stop('illegal zero length vector') icar <- icount(vn[n]) if (n > 1) { icdr <- icountn(vn[-n]) hasVal <- FALSE nextVal <- NULL } nextEl <- if (n == 1) { function() nextElem(icar) } else { function() { repeat { if (!hasVal) { nextVal <<- nextElem(icar) hasVal <<- TRUE } tryCatch({ return(c(nextElem(icdr), nextVal)) }, error=function(e) { if (identical(conditionMessage(e), 'StopIteration')) { icdr <<- icountn(vn[-n]) hasVal <<- FALSE } else { stop(e) } }) } } } structure(list(nextElem=nextEl), class=c('abstractiter', 'iter')) } iwhich <- function(nf, ind) { n <- length(ind) if (n == 0) stop('illegal zero length vector') x <- rep(TRUE, length(nf[[1]])) for (i in seq_len(n)) x <- x & nf[[i]] == ind[i] which(x) } # define the generic function isplit <- function(x, f, drop=FALSE, ...) { UseMethod('isplit') } # define the default method isplit.default <- function(x, f, drop=FALSE, ...) { if (!is.list(f)) f <- list(f) cf <- lapply(f, function(a) if (is.factor(a)) a else as.factor(a)) nf <- lapply(cf, as.integer) flevels <- lapply(f, function(a) if (is.factor(a)) levels(a) else sort(unique.default(a))) it <- icountn(unlist(lapply(cf, nlevels))) nextEl <- function() { repeat { i <- nextElem(it) j <- iwhich(nf, i) if (!drop || length(j) > 0) break } k <- seq_along(i) names(k) <- names(cf) key <- lapply(k, function(x) flevels[[x]][i[x]]) list(value=x[j], key=key) } structure(list(nextElem=nextEl), class=c('abstractiter', 'iter')) } # define the data frame method which uses the default method isplit.data.frame <- function(x, f, drop=FALSE, ...) { it <- isplit(seq_len(nrow(x)), f, drop=drop, ...) nextEl <- function() { i <- nextElem(it) list(value=x[i$value,, drop=FALSE], key=i$key) } structure(list(nextElem=nextEl), class=c('abstractiter', 'iter')) } iterators/R/iapply.R0000644000176200001440000000173013513447415014120 0ustar liggesusers# # Copyright (c) 2008-2010 Revolution Analytics # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # iapply <- function(X, MARGIN) { xit <- icountn(dim(X)[MARGIN]) nextEl <- function() { i <- nextElem(xit) j <- rep('', length(dim(X))) j[MARGIN] <- as.character(i) s <- paste('X[', paste(j, collapse=','), ']', sep='') x <- parse(text=s) eval(x) } it <- list(nextElem=nextEl) class(it) <- c('abstractiter', 'iter') it } iterators/R/iterators.R0000644000176200001440000001640413513447415014642 0ustar liggesusers# # Copyright (c) 2008-2010 Revolution Analytics # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # generic function for creating an iterator object iter <- function(obj, ...) { UseMethod('iter') } # calling iter on an iter object returns itself iter.iter <- function(obj, ...) { obj } # default method creates an iterator from a vector or list iter.default <- function(obj, checkFunc=function(...) TRUE, recycle=FALSE, ...) { state <- new.env() state$i <- 0L state$obj <- obj n <- length(obj) it <- list(state=state, length=n, checkFunc=checkFunc, recycle=recycle) class(it) <- c('containeriter', 'iter') it } # allow a matrix to be iterated over in different ways iter.matrix <- function(obj, by=c('column', 'cell', 'row'), chunksize=1L, checkFunc=function(...) TRUE, recycle=FALSE, ...) { by <- match.arg(by) if ((chunksize > 1L) && (by=='cell')) { warning("Chunksize greater than 1 not allowed when using by='cell'\n Setting chunksize=1") chunksize <- 1L } state <- new.env() state$i <- 0L state$obj <- obj n <- switch(by, column=ncol(obj), row=nrow(obj), length(obj)) it <- list(state=state, by=by, length=n, checkFunc=checkFunc, recycle=recycle, chunksize=chunksize) class(it) <- c('matrixiter', 'iter') it } # allow a data frame to be iterated over in different ways iter.data.frame <- function(obj, by=c('column', 'row'), checkFunc=function(...) TRUE, recycle=FALSE, ...) { by <- match.arg(by) state <- new.env() state$i <- 0L state$obj <- obj n <- switch(by, column=length(obj), nrow(obj)) it <- list(state=state, by=by, length=n, checkFunc=checkFunc, recycle=recycle) class(it) <- c('dataframeiter', 'iter') it } # allow a closure to be turned into an iterator object iter.function <- function(obj, checkFunc=function(...) TRUE, recycle=FALSE, ...) { state <- new.env() state$i <- 0L state$fun <- obj args <- !is.null(formals(obj)) it <- list(state=state, args=args, checkFunc=checkFunc, recycle=recycle) class(it) <- c('funiter', 'iter') it } getIterVal <- function(obj, plus, ...) { UseMethod('getIterVal') } getIterVal.containeriter <- function(obj, plus=0L, ...) { i <- obj$state$i + plus if (i > obj$length) stop('SubscriptOutOfBounds', call.=FALSE) obj$state$obj[[i]] } getIterVal.matrixiter <- function(obj, plus=0L, ...) { i <- obj$state$i + plus n <- obj$length if (i > n) stop('SubscriptOutOfBounds', call.=FALSE) j <- i + obj$chunksize - 1L switch(obj$by, column=obj$state$obj[, i:min(j, n), drop=FALSE], row=obj$state$obj[i:min(j, n), , drop=FALSE], obj$state$obj[[i]]) } getIterVal.dataframeiter <- function(obj, plus=0L, check=TRUE, ...) { i <- obj$state$i + plus n <- obj$length if (i > n) stop('StopIteration', call.=FALSE) switch(obj$by, column=obj$state$obj[, i], obj$state$obj[i, ]) } nextElem <- function(obj, ...) { UseMethod('nextElem') } nextElem.containeriter <- function(obj, ...) { repeat { tryCatch({ if (obj$checkFunc(getIterVal(obj,1L))) { obj$state$i <- obj$state$i + 1L return(getIterVal(obj)) } obj$state$i <- obj$state$i + 1L }, error=function(e) { if (any(nzchar(e$message))) { if (identical(e$message, "SubscriptOutOfBounds")) { if (obj$recycle) { obj$state$i <- 0L } else { stop('StopIteration', call.=FALSE) } } else { stop(e$message, call.=FALSE) } } else { stop('Abort', call.=e) } }) } } nextElem.matrixiter <- function(obj, ...) { repeat { tryCatch({ if (obj$checkFunc(getIterVal(obj,1L))) { obj$state$i <- obj$state$i + obj$chunksize return(getIterVal(obj,plus=(1L-obj$chunksize))) } obj$state$i <- obj$state$i + obj$chunksize }, error=function(e) { if (any(nzchar(e$message))) { if (identical(e$message, "SubscriptOutOfBounds") || identical(e$message, "attempt to select more than one element")) { if (obj$recycle) { obj$state$i <- 0L } else { stop('StopIteration', call.=FALSE) } } else { stop(e$message, call.=FALSE) } } else { stop('Abort', call.=e) } }) } } nextElem.dataframeiter <- function(obj, ...) { repeat { tryCatch({ if (obj$checkFunc(getIterVal(obj,1L))) { obj$state$i <- obj$state$i + 1L return(getIterVal(obj)) } obj$state$i <- obj$state$i + 1L }, error=function(e) { if (any(nzchar(e$message))) { if (identical(e$message, "StopIteration")) { if (obj$recycle) { obj$state$i <- 0L } else { stop('StopIteration', call.=FALSE) } } else { stop(e$message, call.=FALSE) } } else { stop('Abort', call.=e) } }) } } nextElem.funiter <- function(obj, ...) { repeat { tryCatch({ if (obj$args) { val <- obj$state$fun(obj$state$i+1L) } else { val <- obj$state$fun() } if (obj$checkFunc(val)) { if (obj$args) obj$state$i <- obj$state$i + 1L return(val) } if (obj$args) obj$state$i <- obj$state$i + 1L }, error=function(e) { if (any(nzchar(e$message))) { if (identical(e$message, "StopIteration")) { if (obj$recycle) { if (obj$args) obj$state$i <- 0L } else { stop('StopIteration', call.=FALSE) } } else { stop(e$message, call.=FALSE) } } else { stop('Abort', call.=e) } }) } } nextElem.abstractiter <- function(obj, ...) { obj$nextElem() } #print.containeriter <- function(x, ...) { # repr <- sprintf('<%s iterator, current value %d\n', # class(x$state$obj)[1], getIterVal(x)) # cat(repr) #} #print.matrixiter <- function(x, ...) { # repr <- sprintf('<%s iterator, current value %d\n', # class(x$state$obj)[1], getIterVal(x)) # cat(repr) #} #print.dataframeiter <- function(x, ...) { # repr <- sprintf('<%s iterator, current value %d\n', # class(x$state$obj)[1], getIterVal(x, check=FALSE)) # cat(repr) #} #print.funiter <- function(x, ...) { # cat('function iterator\n') #} #print.abstractiter <- function(x, ...) { # cat(x$toString()) #} iterators/R/extra.R0000644000176200001440000001767113514435471013760 0ustar liggesusers# # Copyright (c) 2008-2010 Revolution Analytics # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This function makes iterator makers. The resulting iterator makers all take # an optional "count" argument which specifies the number of times the # resulting iterator should fire. The iterators are wrappers around functions # that return different values each time they are called. All this is done to # avoid cutting and pasting the same code repeatedly. makeIwrapper <- function(FUN) { function(..., count) { if (!missing(count) && (!is.numeric(count) || length(count) != 1)) stop('count must be a numeric value') # construct the call object to put into the nextElem function m <- as.call(c(as.name(FUN), list(...))) # construct the body of the nextElem function fbody <- if (missing(count)) { m } else { substitute({ if (count > 0) { count <<- count - 1L REPLACETHIS } else { stop('StopIteration', call.=FALSE) } }, list(REPLACETHIS=m)) } # create the nextElem function using fbody nextEl <- function() NULL body(nextEl) <- fbody # create and return the iterator object it <- list(nextElem=nextEl) class(it) <- c('abstractiter', 'iter') it } } # define some iterator makers using makeIwrapper irunif <- makeIwrapper('runif') irnorm <- makeIwrapper('rnorm') irbinom <- makeIwrapper('rbinom') irnbinom <- makeIwrapper('rnbinom') irpois <- makeIwrapper('rpois') isample <- makeIwrapper('sample') # a counting iterator icount <- function(count) { if (missing(count)) count <- NULL else if (!is.numeric(count) || length(count) != 1) stop('count must be a numeric value') i <- 0L nextEl <- function() { if (is.null(count) || i < count) (i <<- i + 1L) else stop('StopIteration', call.=FALSE) } it <- list(nextElem=nextEl) class(it) <- c('abstractiter', 'iter') it } # an iterator over pieces of a number idiv <- function(n, ..., chunks, chunkSize) { if (!is.numeric(n) || length(n) != 1) stop('n must be a numeric value') if (length(list(...)) > 0) stop('chunks and chunkSize must be specified as named arguments') if ((missing(chunkSize) && missing(chunks)) || (!missing(chunkSize) && !missing(chunks))) stop('either chunks or chunkSize must be specified, but not both') if (missing(chunks)) { if (!is.numeric(chunkSize) || length(chunkSize) != 1 || chunkSize < 1) stop('chunkSize must be a numeric value >= 1') chunks <- ceiling(n / chunkSize) } nextEl <- function() { if (chunks <= 0 || n <= 0) stop('StopIteration', call.=FALSE) m <- ceiling(n / chunks) n <<- n - m chunks <<- chunks - 1 m } it <- list(nextElem=nextEl) class(it) <- c('abstractiter', 'iter') it } # an iterator over text lines from a connection ireadLines <- function(con, n=1, ...) { if (!is.numeric(n) || length(n) != 1 || n < 1) stop('n must be a numeric value >= 1') if (is.character(con)) { con <- file(con, open='r') doClose <- TRUE } else { doClose <- FALSE } nextEl <- function() { if (is.null(con)) stop('StopIteration', call.=FALSE) r <- readLines(con, n=n, ...) if (length(r) == 0) { if (doClose) close(con) con <<- NULL stop('StopIteration', call.=FALSE) } r } it <- list(nextElem=nextEl) class(it) <- c('abstractiter', 'iter') it } # an iterator over rows of a data frame read from a file iread.table <- function(file, ..., verbose=FALSE) { args <- list(...) argnames <- names(args) # need to do this (at least for now) because the default values for # header and row.names depend on the first few lines of the file, # which could cause a different number of columns to be returned from # the first versus the subsequent calls to read.table if (!all(c('header', 'row.names') %in% argnames)) stop('both header and row.names must be specified in this implementation') nrows <- if ('nrows' %in% argnames) args$nrows else 1 row.names <- args$row.names # it doesn't seem to make sense to allow nrows < 1 for the "iterator" # version of read.table if (!is.numeric(nrows) || length(nrows) != 1 || nrows < 1) stop('nrows must be a numeric value >= 1') # open the file if necessary and remember to close it if (is.character(file)) { file <- file(file, open='r') doClose <- TRUE } else { doClose <- FALSE } # create the call object that we'll use to call read.table m <- as.call(c(as.name('read.table'), file='', list(...))) m$file <- file m$nrows <- nrows # needed since we use a different default than read.table env <- sys.frame(sys.nframe()) # compute these once rather than repeatedly rnlen <- length(row.names) gotrownames <- is.character(row.names) && rnlen > 1 # initialize a few state variables first.time <- TRUE irow <- 1 errmsg <- NULL nextEl <- function() { if (!is.null(errmsg)) stop(paste('iterator failed previously:', errmsg), call.=FALSE) if (is.null(file)) stop('StopIteration', call.=FALSE) if (gotrownames) { rem <- rnlen - irow + 1 # remaining strings in row.names nrows <<- min(nrows, rem) # possibly decrease nrows to match row.names # there is a problem if nrows is one: we would have to set row.names # to a character vector of length one, which is interpreted # incorrectly by read.table if (nrows > 1) m$row.names <<- row.names[seq(irow, length=nrows)] else m['row.names'] <<- list(NULL) # we'll fix the row names later m$nrows <<- nrows } # call read.table to actually read the file r <- tryCatch({ # handle the case where we've run out of row names if (nrows > 0) { if (verbose) print(m) eval(m, env) } else { NULL } }, error=function(e) { # this error is thrown at the end of input sometimes # but other times a data frame with no rows is returned # (for instance when col.names is specified) if (!identical(conditionMessage(e), 'no lines available in input')) { if (doClose) close(file) file <<- NULL errmsg <<- conditionMessage(e) stop(e) } NULL }) # set header to FALSE, skip to 0, and col.names to names(r) # after the first call to read.table if (first.time) { first.time <<- FALSE m$header <<- FALSE m$skip <<- 0 nms <- names(r) if (is.numeric(row.names)) { nms <- if (row.names == 1) c('', nms) else if (row.names >= length(nms)) c(nms, '') else c(nms[1:(row.names-1)], '', nms[row.names:length(nms)]) } m$col.names <<- nms } # check if we're done reading if (is.null(r) || nrow(r) == 0) { if (doClose) close(file) file <<- NULL stop('StopIteration', call.=FALSE) } if (gotrownames) { # fix the row names for this particular case if (nrows == 1) rownames(r) <- row.names[irow] # update the index into row.names irow <<- irow + nrows } r } it <- list(nextElem=nextEl) class(it) <- c('abstractiter', 'iter') it } iterators/MD50000644000176200001440000000474313516701632012612 0ustar liggesusers435e2f3f8f2e6cc655925a951a86206b *DESCRIPTION 9fcb4ed44313bc97aa6a971ee7dc472b *NAMESPACE 45c2988f0ec76eb01cc8eb7646447164 *NEWS 4fd84a19cf3aa8dbc3665112c9f75ec7 *R/aslist.R ec563d021c042be164a86091bb086602 *R/extra.R 42fbe2852e018465f8fe0d26baf69834 *R/iapply.R 92d087eee22703a2565a772f193e8410 *R/isplit.R 909991db199076869b227cc035d67416 *R/iterators.R 7b981315d2826120a7aaab0d0713b3bb *build/vignette.rds 4c0f573905aca92492cbac96b491ebcc *inst/doc/iterators.R 8507ad93e19e3e451cdafff548a6c5e4 *inst/doc/iterators.Rnw 0a54633aaf249cf83ec851f8ca318bcf *inst/doc/iterators.pdf 75b7fbbcef4441ace23dbc77f4013b53 *inst/doc/writing.R 7aa6bad7c3c4ad922660f259f0486186 *inst/doc/writing.Rnw 4d12616dcc2865f20684f05410b3ccaf *inst/doc/writing.pdf 93d2e377fad53c21a6d7340b84b423a9 *inst/examples/ifilter.R b88c57441f4a4f554b6f8053122d60e8 *inst/examples/iforever.R 8565d2859eb0029bcc28d50351d48ac9 *inst/examples/ihasNext.R f3f5dda7586b67c6bf225f185400d8b0 *inst/examples/ilimit.R d6030cb641b439aede05f6144e58ea04 *inst/examples/ipermn.R 238c73349c6170ab7b02dbdc5b96cb83 *inst/examples/irecycle.R e26ebcd550559591e6a34da836af88f8 *inst/examples/irep.R 27ea6b0481177e7358f2ed00a23b813c *inst/examples/iseq.R 722955aab6224c1572ab6b9af934fdd5 *inst/examples/itimer.R b0b37d1ea5e7d4784910dbb058c550d3 *inst/examples/ivector.R 2f454535709b77182316e9ee93d7ddb9 *inst/examples/ivector2.R 40b567d4d84f82a2d34a524e6e609646 *inst/unitTests/basicTest.R 7fd4ba73fd9516cee508514718b71a2d *inst/unitTests/chunksizeTest.R 72010d7ccfb6fcf89098124b88a68aa7 *inst/unitTests/iapplyTest.R 280f88ea0e00644a1ea3b2f2f31fefd3 *inst/unitTests/icountnTest.R ef5f3094c2d45fdfea704312fc16a128 *inst/unitTests/isplitTest.R dd6272fa7ae4e305f035d6c6086b25d1 *inst/unitTests/recycleTest.R 4e3dcb6484914e854417d6d01f6d3634 *inst/unitTests/runTestSuite.sh 2f1e54b4ba9ab21f62b53b26946445a2 *man/iapply.Rd 0b4183099d4dc7928a2ba8cb94a0303d *man/icount.Rd 5d908498f697543429b0dd496b03c2d2 *man/idiv.Rd aa33fdb830dfb611918a065b90e29f8b *man/iread.table.Rd de1e820b20e7bf84238fff7c5e52da25 *man/ireadLines.Rd 03afb2b83e31be725482d9647fc267f8 *man/irnorm.Rd 845cbccfb0140aae8df7558ab63e16da *man/isplit.Rd d12aaf5c4173441a8ea4ec9afcd326e5 *man/iter.Rd 4dddf1762f99ecd5895d967e1d403269 *man/iterators-package.Rd 410ded1d3a9a74677a00fbba02dcb213 *man/makeIwrapper.Rd 7f452e912c064d6fd7633be849568477 *man/nextElem.Rd 0d6cdfbe259eca9d473fa6cb41a6e963 *tests/doRUnit.R 8507ad93e19e3e451cdafff548a6c5e4 *vignettes/iterators.Rnw 7aa6bad7c3c4ad922660f259f0486186 *vignettes/writing.Rnw iterators/inst/0000755000176200001440000000000013516640512013246 5ustar liggesusersiterators/inst/examples/0000755000176200001440000000000013513447415015070 5ustar liggesusersiterators/inst/examples/iforever.R0000644000176200001440000000055713513447415017043 0ustar liggesuserslibrary(iterators) # return an iterator that returns the specified value forever iforever <- function(x) { nextEl <- function() x obj <- list(nextElem=nextEl) class(obj) <- c('iforever', 'abstractiter', 'iter') obj } # create an iterator that returns 42 forever it <- iforever(42) # call it three times for (i in 1:3) print(nextElem(it)) iterators/inst/examples/ivector2.R0000644000176200001440000000241413513447415016751 0ustar liggesuserslibrary(iterators) # return an iterator that returns subvectors of a vector. # can specify either "chunks" or "chunkSize" arguments # since that is what the "idiv" function supports. ivector <- function(x, ...) { # don't evaluate x if is specified using the ':' operator q <- substitute(x) if (identical(q[[1]], as.name(':'))) { rm(list='x') # being paranoid: don't want to evaluate promise lower <- as.integer(eval.parent(q[[2]])) upper <- as.integer(eval.parent(q[[3]])) inc <- if (upper >= lower) 1L else -1L len <- abs(upper - lower) + 1L it <- idiv(len, ...) nextEl <- function() { n <- nextElem(it) y <- seq(lower, by=inc, length=n) lower <<- lower + (inc * n) y } } else { i <- 1 it <- idiv(length(x), ...) nextEl <- function() { n <- nextElem(it) ix <- seq(i, length=n) i <<- i + n x[ix] } } obj <- list(nextElem=nextEl) class(obj) <- c('ivector', 'abstractiter', 'iter') obj } # create a vector iterator that returns three subvectors it <- ivector(1:25, chunks=3) print(as.list(it)) # create a vector iterator that returns subvectors # with a maximum length of 10 it <- ivector(25:1, chunkSize=10) print(as.list(it)) iterators/inst/examples/iseq.R0000644000176200001440000000131013513447415016147 0ustar liggesuserslibrary(iterators) # return an iterator that returns subvectors of a sequence # of a specified length. # can specify either "chunks" or "chunkSize" arguments # since that is what the "idiv" function supports. iseq <- function(n, ...) { i <- 1 it <- idiv(n, ...) nextEl <- function() { n <- nextElem(it) x <- seq(i, length=n) i <<- i + n x } obj <- list(nextElem=nextEl) class(obj) <- c('iseq', 'abstractiter', 'iter') obj } # create a sequence iterator that returns three subvectors it <- iseq(25, chunks=3) print(as.list(it)) # create a sequence iterator that returns subvectors # with a maximum length of 10 it <- iseq(25, chunkSize=10) print(as.list(it)) iterators/inst/examples/itimer.R0000644000176200001440000000113213513447415016501 0ustar liggesuserslibrary(iterators) # Returns an iterator that limits another iterator based on time itimer <- function(it, time) { it <- iter(it) start <- proc.time()[[3]] nextEl <- function() { current <- proc.time()[[3]] if (current - start >= time) stop('StopIteration') nextElem(it) } obj <- list(nextElem=nextEl) class(obj) <- c('itimer', 'abstractiter', 'iter') obj } # Create a iterator that counts for one second it <- itimer(icount(Inf), 1) tryCatch({ repeat { print(nextElem(it)) } }, error=function(e) { cat('timer expired\n') }) iterators/inst/examples/irep.R0000644000176200001440000000102013513447415016143 0ustar liggesuserslibrary(iterators) # return an iterator that returns the specified value # a limited number of times irep <- function(x, times) { nextEl <- function() { if (times > 0) times <<- times - 1 else stop('StopIteration') x } obj <- list(nextElem=nextEl) class(obj) <- c('irep', 'abstractiter', 'iter') obj } # create an iterator that returns a 7 exactly 6 times it <- irep(7, 6) # convert the iterator into a list, which gets all of its values print(unlist(as.list(it))) iterators/inst/examples/ilimit.R0000644000176200001440000000071013513447415016500 0ustar liggesuserslibrary(iterators) ilimit <- function(it, times) { it <- iter(it) nextEl <- function() { if (times > 0) times <<- times - 1 else stop('StopIteration') nextElem(it) } obj <- list(nextElem=nextEl) class(obj) <- c('ilimit', 'abstractiter', 'iter') obj } it <- ilimit(icount(Inf), 3) print(nextElem(it)) print(nextElem(it)) print(nextElem(it)) print(tryCatch(nextElem(it), error=function(e) e)) iterators/inst/examples/ihasNext.R0000644000176200001440000000331513513447415017000 0ustar liggesuserslibrary(iterators) # This example was originally written and contributed # by Hadley Wickham, with minor modifications by # Revolution Analytics # Define a hasNext generic function hasNext <- function(obj, ...) { UseMethod('hasNext') } # Define a hasNext method for the "ihasNext" class hasNext.ihasNext <- function(obj, ...) { obj$hasNext() } # This function takes an iterator and returns an iterator that supports # the "hasNext" method. This simplifies manually calling the "nextElem" # method of the iterator, since you don't have to worry about catching # the "StopIteration" exception. ihasNext <- function(it) { it <- iter(it) # If "it" already has a hasNext function, return it unchanged if (!is.null(it$hasNext)) return(it) cache <- NULL has_next <- NA nextEl <- function() { if (!hasNx()) stop('StopIteration', call.=FALSE) # Reset the "has_next" flag and return the value has_next <<- NA cache } hasNx <- function() { # Check if you already know the answer if (!is.na(has_next)) return(has_next) # Try to get the next element tryCatch({ cache <<- nextElem(it) has_next <<- TRUE }, error=function(e) { if (identical(conditionMessage(e), 'StopIteration')) { has_next <<- FALSE } else { stop(e) } }) has_next } obj <- list(nextElem=nextEl, hasNext=hasNx) class(obj) <- c('ihasNext', 'abstractiter', 'iter') obj } # Create a "counting" iterator that has a hasNext method it <- ihasNext(icount(3)) # Print the values of the iterator without the need for error handling while (hasNext(it)) print(nextElem(it)) iterators/inst/examples/ifilter.R0000644000176200001440000000116613513447415016655 0ustar liggesuserslibrary(iterators) # Returns a filtering iterator ifilter <- function(it, FUN, ...) { it <- iter(it) nextEl <- function() { repeat { x <- nextElem(it) if (FUN(x, ...)) break } x } obj <- list(nextElem=nextEl) class(obj) <- c('ifilter', 'abstractiter', 'iter') obj } # Simple example use it <- irnorm(1, count=10) is.positive <- function(x) x > 0 print(as.list(ifilter(it, is.positive))) # Example using a function with an additional argument it <- irnorm(1, count=10) greater.than <- function(x, y) x > y print(as.list(ifilter(it, greater.than, 1.0))) iterators/inst/examples/ivector.R0000644000176200001440000000130613513447415016666 0ustar liggesuserslibrary(iterators) # return an iterator that returns subvectors of a vector. # can specify either "chunks" or "chunkSize" arguments # since that is what the "idiv" function supports. ivector <- function(x, ...) { i <- 1 it <- idiv(length(x), ...) nextEl <- function() { n <- nextElem(it) ix <- seq(i, length=n) i <<- i + n x[ix] } obj <- list(nextElem=nextEl) class(obj) <- c('ivector', 'abstractiter', 'iter') obj } # create a vector iterator that returns three subvectors it <- ivector(1:25, chunks=3) print(as.list(it)) # create a vector iterator that returns subvectors # with a maximum length of 10 it <- ivector(1:25, chunkSize=10) print(as.list(it)) iterators/inst/examples/irecycle.R0000644000176200001440000000102713513447415017012 0ustar liggesuserslibrary(iterators) # This functions returns an iterator that recycles the values of # the specified iterator irecycle <- function(it) { values <- as.list(iter(it)) i <- length(values) if (i == 0) stop('iterator must have at least one value') nextEl <- function() { i <<- i + 1 if (i > length(values)) i <<- 1 values[[i]] } obj <- list(nextElem=nextEl) class(obj) <- c('irecycle', 'abstractiter', 'iter') obj } it <- irecycle(icount(3)) for (i in 1:9) print(nextElem(it)) iterators/inst/examples/ipermn.R0000644000176200001440000000715513513447415016515 0ustar liggesuserslibrary(iterators) permn <- function(x) { n <- length(x) if (n == 1 && is.numeric(x) && x >= 0) { n <- x x <- seq(length=n) } if (n == 0) list() else permn.internal(x, n) } permn.internal <- function(x, n) { if (n == 1) { list(unlist(x, recursive=FALSE)) } else { fun <- function(i) lapply(permn.internal(x[-i], n - 1), function(v) c(x[[i]], v)) unlist(lapply(seq(along=x), fun), recursive=FALSE) } } ipermn <- function(x) { n <- length(x) if (n == 1 && is.numeric(x) && x >= 0) { n <- x x <- seq(length=n) } ipermn.internal(x, n) } ipermn.internal <- function(x, n) { icar <- icount(n) if (n > 1) { icdr <- NULL hasVal <- FALSE nextVal <- NULL } nextEl <- if (n <= 1) { function() x[[nextElem(icar)]] } else { function() { repeat { if (!hasVal) { nextVal <<- nextElem(icar) icdr <<- ipermn.internal(x[-nextVal], n - 1) hasVal <<- TRUE } tryCatch({ return(c(x[[nextVal]], nextElem(icdr))) }, error=function(e) { if (identical(conditionMessage(e), 'StopIteration')) { hasVal <<- FALSE } else { stop(e) } }) } } } obj <- list(nextElem=nextEl) class(obj) <- c('ipermn', 'abstractiter', 'iter') obj } icombn <- function(x, m) { n <- length(x) if (n == 1 && is.numeric(x) && x >= 0) { n <- x x <- seq(length=n) } if (m > n) stop('m cannot be larger than the length of x') if (m < 0) stop('m cannot be negative') icombn.internal(x, n, m) } icombn.internal <- function(x, n, m) { icar <- icount(n - m + 1) if (n > 1) { icdr <- NULL hasVal <- FALSE nextVal <- NULL } nextEl <- if (m <= 1) { function() x[[nextElem(icar)]] } else { function() { repeat { if (!hasVal) { nextVal <<- nextElem(icar) nn <- n - nextVal icdr <<- icombn.internal(x[seq(nextVal+1, length=nn)], nn, m - 1) hasVal <<- TRUE } tryCatch({ return(c(x[[nextVal]], nextElem(icdr))) }, error=function(e) { if (identical(conditionMessage(e), 'StopIteration')) { hasVal <<- FALSE } else { stop(e) } }) } } } obj <- list(nextElem=nextEl) class(obj) <- c('icombn', 'abstractiter', 'iter') obj } tostr <- function(x) paste(x, collapse=', ') failures <- 0 # test ipermn using permn for (x in list(list(1,2,3), 1:3, 1, 'bar', 3, c(), letters[1:6])) { cat(sprintf('testing ipermn on: %s\n', tostr(x))) actual <- as.list(ipermn(x)) expect <- permn(x) status <- identical(actual, expect) if (!status) { cat('test failed\n') cat(' expected:\n') print(expect) cat(' actual:\n') print(actual) failures <- failures + 1 } } # test icombn using combn for (m in 1:8) { for (x in list(1:2, 'foo', 1, 7, 1:8, letters[1:6], rep('foo', 3))) { m <- min(m, length(x)) cat(sprintf('testing icombn on: %s\n', tostr(x))) actual <- as.list(icombn(x, m)) expect <- combn(x, m, simplify=FALSE) status <- identical(actual, expect) if (!status) { cat('test failed\n') cat(' expected:\n') print(expect) cat(' actual:\n') print(actual) failures <- failures + 1 } } } if (failures > 0) { cat(sprintf('%d test(s) failed\n', failures)) } else { cat('All tests passed\n') } iterators/inst/doc/0000755000176200001440000000000013516640512014013 5ustar liggesusersiterators/inst/doc/iterators.pdf0000644000176200001440000024072113516640510016526 0ustar liggesusers%PDF-1.5 % 1 0 obj << /S /GoTo /D (section.1) >> endobj 4 0 obj (Introduction) endobj 5 0 obj << /S /GoTo /D (section.2) >> endobj 8 0 obj (Some Special Iterators) endobj 9 0 obj << /S /GoTo /D [10 0 R /Fit] >> endobj 12 0 obj << /Length 1493 /Filter /FlateDecode >> stream xڵXKo6WV X"(mͩ(4ZDq}E=ln+fNvN~~/<\=EQ$V>YmSJeReno}f~vY^h0n7_m:)@lh[NYUkTl/m'Z WZ͍1U;ʺakP{'48y?04ejW_E W26ӰS~)k^VE{&ˍ.ԎY "'0hқ1:hmvs  5:+zr_{8hyrI"qF|*bHHde7ng^{ ؉;lZ28]8׵ĹUYM߳ZXc 1%9\)[IFwlxuУl'3׏^|XVdOh^v$4ӛi$䞗a#5/g x égY#u B`r td# hGME+ '#rc4u Ȥ ;3s`6JC yIDyQr&t7R 1GYJqt^H w2[ N8T6cIt\D5Dž3 n݊$a@&(mu%JY…@3.?(Dɷ9UC>.C:IŦ5njjd-Q="Hl;}lpE^^މN}#D+f B6ՕLˋ;-uX Yxz& @]Daެ0_OS錜.ٱsi8Q,S5RǐphNZU5&h]:*X8~,C$yZqʾS]^IL&Քo ta?]JJዬ#P\? ٿ.5|_=fEfI"s&<$.wOҷyǞ ӆ gt3XG|=ӵ&@W~l C[{uk.ҝMXEumUFZ)˵bmPyv 3iTbQ w@53SgliR召6rn $ lv>SQMHqŔ/ĮI}73P2mM-*jkbl Pk-K10;|P)a~s2]Gs I:,l|^[DlA(&UR?6 jgzeA?V*a']zz޲EZ endstream endobj 10 0 obj << /Type /Page /Contents 12 0 R /Resources 11 0 R /MediaBox [0 0 612 792] /Parent 22 0 R >> endobj 13 0 obj << /D [10 0 R /XYZ 53 735.4 null] >> endobj 14 0 obj << /D [10 0 R /XYZ 54 697.538 null] >> endobj 2 0 obj << /D [10 0 R /XYZ 54 525.694 null] >> endobj 11 0 obj << /Font << /F33 15 0 R /F38 16 0 R /F21 17 0 R /F42 18 0 R /F51 19 0 R /F55 20 0 R /F31 21 0 R >> /ProcSet [ /PDF /Text ] >> endobj 25 0 obj << /Length 1613 /Filter /FlateDecode >> stream xXK6WZ!)@ d-&)݃>?6>>DrAC%r8|3C*TvxLvd̘p*c B6eOWJU|_!]|Q+BXv;ۖVv-0?a 'btf<:QVe:s6t]XrLe8>SE]S6.*_Ю|p ono x^ GN;Atqn <0s!6w74X3  ~nŒ FZ9 pe#[S#m k=92 Pt% JW^Ǜy㋉ =yɺ7%FHu4X(rc:ΥlTW%3%#C<hnḆH} lBi۵Ys?; qegHx9t{ o w-#;(0PLBOZazR&/t}*>|lry5Jy 3pϛrm{B׭+^uEeAL|fE"تv| e!w霨į1 c_]sPX"xߩ@Ia GۦNdY#jŰ:(pޮ% _eAMo*bZGe!Ee8/Ԉ7+_hGPϒ6[;cM0p=tZ\ =4ҍr_BӠ̏#|"}iI4%)E1N+b/' C*&gᘻm& v̍J|XFnD:~ Kプ,0ʔunOPϰ5&q)><?Rc&(pOI>XZT kѩ3 9Wx.}oul endstream endobj 24 0 obj << /Type /Page /Contents 25 0 R /Resources 23 0 R /MediaBox [0 0 612 792] /Parent 22 0 R >> endobj 26 0 obj << /D [24 0 R /XYZ 71 735.4 null] >> endobj 23 0 obj << /Font << /F21 17 0 R /F38 16 0 R /F55 20 0 R >> /ProcSet [ /PDF /Text ] >> endobj 29 0 obj << /Length 2063 /Filter /FlateDecode >> stream xYKs#WqXĢF*Cd{aDK-htc0$FvrH~~P9|}뫷 "ZA)/WFq)}>Z>oWyNvu"JƼy.MK!]e\BI;])?M7畵3 +HrCƺG9ܦ Rz4axݕlcQ]>$j RQ{>2DtqN#%iRDEڂy2$3 f5 ?gH|s:/پ#q}g.DIbF4d!v KR&'Յ*_l jļfE[dPqxبb:tf|{ts0u\ $6*2C b/Ӹ%*O,Da}ؙ}6[vhQTG U(PJ\2.& Qg{YmPDs"Dw hҡ>h`Aw~cuyЦ*4mtD|VNĠ`Yg\dN1©"GO9:e&^$CIp! 0V<ëhs/L4 WLDul$bm,a1IX/.2"rH1aEiD2rf9aELEeR $C*I\%ضᒮ[هj"sWj ;BAt҄v8(f~3Z{;ӯAE(_$q;V:MB);)rcSfIX۲<% [2L 5ϴ[ g R5+*5|FQ_+WMRlHFR ,[zZ=DͶ|B'2HHW /aZ]Z `*-Ú_x`6Yipď>T/Η5_biٶ<Vvm)UCE\\H@Y-5 o,eޭ! š"Яqj#vTӳRs;UZ 0osJE*#ۅ%MYD S,a"͞q?k-{]f#6T3կVؖv:[xbqJ(ͤI#յ}=ߧb)Kv19QYit`Վۜnb0y85\t @o__%8muEg}.W% endstream endobj 28 0 obj << /Type /Page /Contents 29 0 R /Resources 27 0 R /MediaBox [0 0 612 792] /Parent 22 0 R >> endobj 30 0 obj << /D [28 0 R /XYZ 53 735.4 null] >> endobj 6 0 obj << /D [28 0 R /XYZ 54 476.807 null] >> endobj 27 0 obj << /Font << /F21 17 0 R /F38 16 0 R /F42 18 0 R /F55 20 0 R >> /ProcSet [ /PDF /Text ] >> endobj 33 0 obj << /Length 661 /Filter /FlateDecode >> stream xUKo1qsk=~ E D84-M#T{gH`wy?lQVgDP[5bTF]_gu7;~¥V&vdݒO;ڞe g{Z _ FEkUUY{ j鮮!2:~ F}POi??m=6/Wd^h]o4 -hˮh@+o,tּS-fڌ<fj.zXB SFέއCLÉ⑭!l`֛BMcC^aYK ٟy9Oߑp}Ij#z Y}͞ Nik((3 H̩31RRƌC’:pL z#;`J7pVt6*s548&)m.(N57*sCY QOp7 ]DFYmR  p\վVrqUvr5 C;S4 }/~vH?nKoYvS~[wdYL:q~jC"iq̈́[ԼӳfBgsf"32> endobj 34 0 obj << /D [32 0 R /XYZ 71 735.4 null] >> endobj 31 0 obj << /Font << /F21 17 0 R /F38 16 0 R /F55 20 0 R >> /ProcSet [ /PDF /Text ] >> endobj 35 0 obj << /Length 123 /Filter /FlateDecode >> stream x3532Q0P0P06R01P03RH1*24(äs< =\ %E\N @QhX.OfAcՓ+ ^) endstream endobj 21 0 obj << /Type /Font /Subtype /Type3 /Name /F31 /FontMatrix [0.01004 0 0 0.01004 0 0] /FontBBox [ 28 32 40 62 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 39 /LastChar 39 /Widths 36 0 R /Encoding 37 0 R /CharProcs 38 0 R >> endobj 36 0 obj [51.24 ] endobj 37 0 obj << /Type /Encoding /Differences [39/a39] >> endobj 38 0 obj << /a39 35 0 R >> endobj 39 0 obj [525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525] endobj 40 0 obj [500 450 450 500 450 300 450 500 300 300 450 250 800 550 500 500 450 412.5 400 325] endobj 41 0 obj [562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 312.5 312.5 342.6 875 531.3 531.3 875 849.5 799.8 812.5 862.3 738.4 707.2 884.3 879.6 419 581 880.8 675.9 1067.1 879.6 844.9 768.5 844.9 839.1 625 782.4 864.6 849.5 1162 849.5 849.5 687.5 312.5 581 312.5 562.5 312.5 312.5 546.9 625 500 625 513.3 343.7 562.5 625 312.5 343.7 593.8 312.5 937.5 625 562.5 625 593.8 459.5 443.8 437.5 625] endobj 42 0 obj [544 544 816 816 272 299.2 489.6 489.6 489.6 489.6 489.6 734 435.2 489.6 707.2 761.6 489.6 883.8 992.6 761.6 272 272 489.6 816 489.6 816 761.6 272 380.8 380.8 489.6 761.6 272 326.4 272 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 272 272 272 761.6 462.4 462.4 761.6 734 693.4 707.2 747.8 666.2 639 768.3 734 353.2 503 761.2 611.8 897.2 734 761.6 666.2 761.6 720.6 544 707.2 734 734 1006 734 734 598.4 272 489.6 272 489.6 272 272 489.6 544 435.2 544 435.2 299.2 489.6 544 272 299.2 516.8 272 816 544 489.6 544 516.8 380.8 386.2 380.8 544 516.8 707.2 516.8 516.8 435.2] endobj 43 0 obj [514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6] endobj 44 0 obj [628.2 719.8 680.5 510.9 667.6 693.3 693.3 954.5 693.3 693.3 563.1 249.6 458.6 249.6 458.6 249.6 249.6 458.6 510.9 406.4 510.9 406.4 275.8 458.6 510.9 249.6 275.8 484.7 249.6 772.1 510.9 458.6 510.9 484.7 354.1 359.4] endobj 45 0 obj << /Length1 1645 /Length2 8616 /Length3 0 /Length 9675 /Filter /FlateDecode >> stream xڍT7 ft -5R@p%HHt4% ȃ<9sQKWnQÐ|y 9CA?? +iKêA8A0Y# `L3Ԁ!$??@_/C8BvZ4p U莀Z HHv:@P 0 F@2Zp (R6H$vp#9yP @A@,(@`ȟpXz6P?p++ ӝ3e誨4!?0Y ;8aP5 jh*!ݐ<0! ~vCw(jw d:"8+"R!p~OXgs`pW_ E} QQNJ /7 zJ_;ޞpG 7 rvgE8K`p~'XO݄Yan1P HV'忕rrp7'WPD $x7o$ qW9 '@y8"w_KoEHwnw@Xh9T Y]F bEZ1Du.=т;A]8^~휅ݥt׫*J7"nkED`7`""O%mG޹y_U~~#;7 o@A/(B@P@PPݽ/ /( "; ȿ]HWw p~]¿o7 b33 xd1\֕w}udN^DDβ_粉}DggncU񷾏ͳ`7{bG0wƧzFPl3b{g]Jrk'J[5zOvjm'ݎE̬x^;M[CFSm%UajŴƯw>˙ k>²iBO.%F ^~,U)~bJh¬p ^$d70rҪG!:U:N/GѷT-.K[ dN5m?N~ӵh纊%vsdO>Chc.Nc\Vތȩ@#D%J=y|x3ctJol91ɩ٦ z"`Wah&]k<4ϛmg7)M'ڒ&&^[5RP)H 2 NQODqMܜŏxV.9UFgJ!_%?1ip[c_V (˂Z!KywIJ/ >=u=0VF53v@k`@|q?t95 fw͌^8&00ϟHTF{5Sc|OPumIk}#޲ҔqY$2캚,=I͝Jbt>461Z?a$#)LEf+a-Y׮6歾O A sv=.u/Y\+f {w9z #6SبNpI(X7mLKw{}AV>#;zߕ[e1Wz}#Rc5.{MaeHt>^=C99'F16I#b@{ً1Nhf4smO2NdӴ̪>Qf\!&犯CɿB~~ٟ PX5grJ}UuעR.8| q"0Ҧ5UmL=gsVlzd;mzF>@EFJ(W)jYEƴ_a ;/hk! ^./8t) el$$RlOi~LM[pLWl\sۡ_7`QU$\XWvTD:T9Hh" q*NM 5\S*X}J8[ے盅D\S$Ѐ}շ*XN[͓s JBt#=k8H >֊W5*>gv`mU"Pg2aN!(bR}ZJSpe z[[mFfD;ջGSH7/}|oQb45+ 6gn2*˳5ouN zƒ.C42a rr`_Ji'2N44`d̜_Fyu\)X1o \M tF( ڛY'eㄙ"!9b5=i%Z* |㨶}JZU8}~jA=V^;a<+OVX[M Q{oω潂YJv?ˇ ~4.O&WI TTQZ>ʸzYͫҳ&NkzcV{O3 Ɓ|4O_\؈kd oؒ\\p9K:fƗ6s;n\5hЯYו^RX~:,B8i-]d wgzQ M&c41J+^ת۔'`_ 8gi3=w Mݬ;>QAAD X0V&]0]d6E+Q0<޴fh 7ʹ/ܮBEf)oTxjsg_~{jSRsQ/{^RL#LsF.Ik^%HO<`}JܮSJ: <{B?dĈz%AF&0"t6KNc`€9x}⾝/f•E:,)-}zɤ8uK?rxH)S!pԘ)؍ x73 t/ oO~Uߧ7|uK`hiG1yvgPzH9 `y^zdb5' h/9C|xk@Nj`ш!F)ۡcb$N+x®o݈z30*fa@Opsۇ,\"샃jxI x/)Q&- ?_ 慙Z?Ho{cN7lUjK\̥Iνz>[-moS.!?+C#hCcaTd<Գ^O> x^ oxU҅ }zqYbjp[*5F>~7X"óDhQX뺡[\>ˬEW*Aϒ^#MYSO!|TPsNǏR]Jy:S {?M^BЩSֶ`|++&cmܢì&߅4 WXob?c|< vltGPxyF (56q/SC6WӚ-'? +Lg.cQ <PPP͍U-ӌs9QM׽dg(o7 $f[7Px~Te,xʵυ+Ţ6B`DgbId#a7ڣT:ZD ٴ2+[. fߣݡELÞNoo*IŎSlQzq!vl)r@WB9_C= >ynx,GC£Ƨ۶i;Q'H gEb}$1`mTͿR>SG3VxgkUIgRJ%#t#)jlt(6f]oR@+QŋfDML/^ t6':sH=^a:CJf+ ֻE$Q<  i¹iE!QhS7ܻAkcUwK^qv-(G`Y>t4t {jܮaݒsѪ* kUradKaWhFǘe:](GjKq<0v> ^N- EK? `a c)~dEP 3dTOfHh1(M>bo[fgt;Hjyʨ<ȗ_g#vUoJ+#Ux9I$r0L,٘4l>/q{Y1G7YJQΠtyq6?%{QJ'9E5RDε~ëD2JIuZ 9}l懙TW{nW&6q%k̸Т}mڮc }x ;YnhV'+bNqmd݋1qecI4 u=^7vK?zhT~mN}0iT!tM ӻD^$o'ռ;XC@37i?%%f$M1U= "ީ#*Kp&2rBVo%t\Ĝg]$SA[hP}\$ <# ƮL"y 0o6U Ys sg\\J~RRX&TR}ĉ=sG'ASy7'yEk B"cZϽL68bCsȥ7bCq3ր 0n'\& )~tWM>Z.b+dC"r}%nEΔrY\?e/X4O W=u X:C#7uFҖ#D(j7E ]ej?qg'_¡>dxl| 3Ԥh;t8l=9yMVK."Բ.[ŷa )pe\5QPp:ۍN<azݫ ;C{_ ^HXn>{ R6^X-< u򍦝}`#f%1[!FR&npЁCw b2lT'kN(i{zI&/"nP;Ek{"k{e6Dy6 XlYKi&< ϘgvImϾ գ4'Kv)T i5a ŦQ,Ŋi xΟhemqB-P;.t(}tƒ@ {ILYqc_Y 5f=ՠ~.]APP*~y}v@VzVpxmlȳG8O?dIK͵;I񷩿ARF1qT`R[6NkiP8VrW`Jv:WvcpZ"5[ \(DP,e}#k~_xF{ r|.Zgy‘eE)O>'$!q^ϻ Q:G:|qp}!N'[]Z\/j'77E:28q";/k"#^n>w|3L5?5W0=lݑyiP9u$ir ]#.\*φ$?/*!2T73`V9x{:J ~+S"l+W˧Dof>Ոݥ+uzG/pF= p1sAF.g,M'(ğ'ǬY*nw 5r"} ]9qS7~}L=)Fcu4ACExk;7JYKnya؂sZ|.Sq j}GC.o{0cTjxj{Pܞ{f")-q:|MWl\“#=N^|>qnc'=HkZ7<X>i%g^ds"}b:iH^O`}D!8܀d"1%Űq!cbш!xѠHEcTԭʪ endstream endobj 46 0 obj << /Type /FontDescriptor /FontName /JHNAAN+CMBX12 /Flags 4 /FontBBox [-53 -251 1139 750] /Ascent 694 /CapHeight 686 /Descent -194 /ItalicAngle 0 /StemV 109 /XHeight 444 /CharSet (/I/S/a/c/d/e/i/l/m/n/o/one/p/r/s/t/two/u) /FontFile 45 0 R >> endobj 47 0 obj << /Length1 2112 /Length2 14975 /Length3 0 /Length 16238 /Filter /FlateDecode >> stream xڍP\ wwN4Nn={B8J꽢 z1m5]( %l@ L<Q9ef+ <9fxru @w㻟  d`f0s0s01Xhc3p671m@@xrQ[7{sS3220sssڛrf@FV#s3stadtqqa0v`7;@{g1/yk࿔1TeW1qt1 VF@{hx/P(Arg`f`oGwd 01$d]  l ̭  !0xoyF涎 VId+)Em G3nd701%ɖQ dn˻ `gbbf@W#3ƿҫ&2+򰵱z{88N@/FC9Ow3_]L `翟tdeԒSTB/DDl\lzvf7 Y?*7? @&6Ix?pTP{c[A}?;moCNVVT?ۿ'}+lw]r@cs'J9o0h a 4V4w42[6=kLL{7#]MKl;v[ðeKoJ]r:)ě)Xqֳ+#pnpQV&\]ÕZ6&"dg KrzGl-dG:4*8Ke:L| e*"(VZY ru0^yeh=$<!et[YOvL)?^)5N~u"i(8@A` .1׀{ uo\3/yY,N~ 2eO @-o=jUe)ȸBl[Ȏ&⦋?hυ9JW^9)2cd UYA<\CJD51uHs✙/)ށFA{ĝSM/,m5ZG'lkrjWǽ }[E30컩珰QP/rS_a+/jJf]g5gFE2=(')뽂J( S^ h¬)ѹ9v8a (2 f>k0_=29IƘE7-6pk-\T7\sÍpbD]ڵ'p}귦єw㉕#;Ie ֽg Ud`t;"*2k5| _VosO:+^8:k[yv?L{FZX (LlKt!Xd:.G7aW|uSbeHϾ*`=`Զ}OIV*fXL0T9p\|[! E?l$bpZgHV!w'\!DItlxMTm#X$p̚q@kñl5Ngkm;]Zu(zS [-gStU`]KG9| #OvYPϋoMIᴐÃRo\LM A ULXRJW|0)OΞ|8`%W4#vFbl+k4F9ʅeV|9 Q?$'$|M{ܮL9ͺoIDUUՇLC%^y*,M ?Z6, ?i`4]v :w!Bъ-X^*ܨjvffn[p%$:KBK McdW>TڙW3<6V$OpTJv͙~19mm*7Yx*'&X?4/OXQ002TrRCX6heJ12,ID9N6d7FQcEUS5{ݰrnף'MOIvE.ncUI="^6wtHTm!g)=ηBSj$>Y: =q$(nc`% w/jFE]MA4&qAG t\ [H@r.Zo%Js8 "S|haHݬ궀V 40s,I\{lv&^v3׺Isuƈ{t B:Mqk(7 T&S.H:|⚯xy̲"5ShuW}-L I i48N-YOI&R%}#\]}RIQ]al0j:qDQ /c rrAUW9o YD9XšAoJ 2 NpAQD&ڰ mA !@Juw^WjZ8g߼`p$b0 6@ҘbzQQq{mqZD5=\䳯F㿅uw@lB~o[WEgV6+g5b9@Bd?t AC fM y1%s2{[W=>#b"z^uJqkߥG] /\%3!Kf$T.5Lf@o:~1zGP=i:s!j*\JFbeo\}HWPWİߘic|g|Ki+=[VR s62;Qjwǡo} 'JijJeShLo-MKD6FUmbtQ!s9mYd9 luzWlIO]S\m/ӛ?H:ɋ|F<?PRI1LhbrwLE{a[h?̝t5QP$[lKij?nk0r|.شP]=㗜9h"L77oѕpΊ{8(u&:1 ~>1{8V&–h#A;^MBzSu{oХW_0(JI&|k"hsFbYRKE2ݝ~舞 D6@>4V3v.}~$^nS/+T_Y4M9`}y6QqҷWzj8˞fuKY!}dSɌH ;2n5'5@_an/t$ \_+Y9fzHjR^CGρ>SK;MSv%M̼)^8ʩKBsKb ojF1F^$B+! te*|"RAK "> o1͌[1ؾiZGճƉ)}\Ml|/`2!?p>8X8Q"sٲqD3d&U&X'{<34lR*o rŪF/VI~3!EPq=fN7`Dd#*"~8[rs =݃4= 2;S¾/~ jK@U(fϮỚ('u#}*0=u9v<ܮ@#9wZȐ6A76ECmURgO?A˸ Kt ݺc\e~԰d{S JCEcBh9\eiZZF:^~qn/ B5e֝GaZ㟟v$8o3Ni`F{ F0S+(OAAn`gòm 5iA-wh$8l. *Q#[i]o)a[Cguԃi2 i?¡J]%uQ{t Qxղ!S ]ۙN7bS6ۍ>K5el2朙fO6P :޳T^ ocM\h!4 imҏx)h IMyS̗nK~к'_. g>86C-e^`*ꄴ[Μ;SW#oF.eέu!v bu"-2Uf'7j$lic`'0昜bZ q`h3Uf:-0oHb8c1vquW[&we֛vRMkIY 2瞚KghҸ+ǒ71 Raqaߒ =y˾gDC[eL0'5 W 2߿D KU kI8+d6. P#@MC֩6U4d!`E1$7 >( ڡc"EwNH+X3=(1#֯+ 2>M~nR-=&5F"^gi'dez/ת>oH{>cc咡+m!(?@ST6сV UZ3; [2Ы" LN)xvAۻ}@HaN?}\X^)j@E@OY^&c>ތށCww喟O+|._@X%VPwLאا{)*9Zaa$ՉMO7Fe  oK t9XãN@w×F/-n~kPPQ/$0&n2rMb[?Qxu5 c(;bCbU/jpϋ=;QpO͋,R7=H2 HahM\H!@Q} .M00UY!NbӠa>DAk.~fB<ϳoN'x0q`SPj'K4hfG Nwv$Ijsb/l1h-sq» ΒA}~k>cޢ<9y^5jQ!V8D*ɓIM* ޾ Nh/%YG g N_WU?A=&eB/I ~Õy`ICHZjGm4xEOII=Cy ۱tz B E5*4ѫd+unO _{"U3BvJ~ڗ 8bw7Rʌ[FiqF iyشҕdPYַnD/H L=%5, Rz0<=KEP0-l@72N~sPe7G7`OS/*Y{wҽz `8\ʼ'Ӹ矚D\9>sF}? %Wf[7RbFXzMu >\\zg<"&jvZpLBOvG?F6ۧԑx ;!&5*V T,M^Ԯ=`f 77=LGىZO{U&;;v-;v¥-K~rռ]1,P"1*E`Xa#.a?`[d֗O6݀%ѿu24OCR> %V^)` *)x뫨\l 70M!'0+o>Oa0]A9ipva]fU[e'B52s>2Z~w:$ YH-%9E2a$Ү(i 3!T!rw sc.jC~ Umt]-lM KMiSݎ8 YZMh/ϓI6*Ófͻr&(Ol4EF%:KT^,;W+Zh[ _/~׬ /ڒQ8lYm".؁׃^Ǐ-yG}NC#V`OZA*vH;2Vn_sDP6Vx&_f`3IX1PTbi1BivVʷBHĚěW=݇e ~ Y/nSekު@FJU!KvH1S u^ߦ~$:XipK.SLÏ$r+.ue(5 s g0Y֟j XcOX?Q<9,CAs0jI#"uo+v {Ztg+NQJ8˯ vԿ_œ<-ҫڑ9=Ru>}@M4i4X3 b6#S[\Wpu)JDEJߓ3qb8obBNCEUQg2fn ҫ5)NRx2ͥiNI= );qe]{p[0 lwr[.wt-%> "$mD3*඀q=E)fgaA#=qzH*wB9$lhPGC}BcIv -c!*T:W.7cЦT`@!WQ) q,Jz޷ʻf\wٜghM ȜG' ,nGP2&kյ PάڌpEjb\М])GQT{U&)vwb;J+VE( ؟܏m|QLMP=ӞI<`ڕ'&S zFq%?K\XY3ΒYϧ@9$ձR$4c +31jA|dFe+q>V` ,-Z;[]YW[7]8+b,>9r djMPcG7W kTLR}b%_r%lRmGەO3?Av.!"ytlŕ%pj~nuZM?mEc}Ň=nNbƕzzt 2^޳#,~ʾj/vĤ5- IEiBNwzH̢ve5{O:=%tqJMI|.)!8!95H1Ɍ1WRga'{m{2έ7~u\Pxzʼٌwٺq(C>e>W{AL B^_8Q3me캊6pt22>7SV/ɢ=UzoOf?uH0~`xW͏iT憒ʬm$pY (q d:L"@/3q%JVKIIS](Vp}з&4 `a:'*QH | C=bz3 ".u22镟b{wmA*L)|BFt[4S,(fUe}_NJ,˻DilN}ڰҤ3@ĆAE {7N)'dIdn6~]9SL ]4]Fk:c7@AT>.!Ϊ"1P(W~L#>ΧNbC|݂S6H?bBg])r%R˩@7"|\~x#Gi'EEMcе}q N\s+c)y.I@ ?&IyB[iFܖu','K LUJ.Ll&HzE,=_r>kj殢eM&o_ESc#sʒo~1d5 s.R e܍v[u!~V? TC7ȳB5̃6[XRejܧ'j2>i!vV< z. -^;b{:Cpq=Rl.e#_R]ܘk7YA`)2 ٶSĮ\C?:PaĎR.Rc7E_nXWO : ƼBS1 1v)*[ ,[$G,W =EE I>p2b5_Cַ(/y;G4kN -"PL~B_A9-al%QGh=*9Gk$b,h]7o-W p=9f < %pT2 WS=~d%\/?\݋ZsvnG}*'ΒkJUO=&-sG>xdpкxC9C$G͗ĩ1p;b>Fҕ]Vm{vEت=BUe)ȰϬ2m˓rcHWH۠U挠Bw @` !z(Sx2‘\Wpя>JڠiKBxbRN{nAbqCȜd^QE3da$Tw"5 FɔS'LW &~BK 67%9k $Hϥv9j[Z-IYDwc\Y4+B.ፁ]1bmSUڑ˪Q:OZ2[B%ʗt+;0f0t'Y{z/q!gCHRW[M݅(]g6L"gϷV9UQ]"Ert>;-9;C(Di iL5f-UOu㢥f,wd}&r.n2~BDѨKOԶT[X`񈮔׽a Voغf~2ƒP_}aݴ\'Sˌ疉2 H}8+vR3-H2* n2/xIp ?j۽^/OwIڑ݊w|Xunjv?f1IavI:O.'syIes!Af}.@>A?k I$XR5Bi"cGCwٺ>?_v:D1g"Sa~p .2M'(h%YZ|1 ]<4`uzT}lG. Wי;±^gP)'XlxZe^Zpnk"<AciNY[v([%SH] zuCSÈHmXBOt[Vc@%<~9xN}]]G7 ~2w/yyCT> endobj 49 0 obj << /Length1 1545 /Length2 8171 /Length3 0 /Length 9185 /Filter /FlateDecode >> stream xڍT-L t P]03twwJ74HtwIH^[5kͼsssޡVQg3aPgvV ?@BQrg[ftz-W#&i\lW<@ +4uYr0( ^fr~\G; fvLESg+ S[: ;{=?+Rq`s/%S;XV?0 g7SG0` N.Ps#qq@ #Xf]_ ɦ Z, `33j+ oj 55{ sS*@{g'V'/l6/ YH غ:R̍e{Th~[;k -njUK]8KR T^jQÚU& { jz(hx?8xk ~oqpRÿvq)2:<}$KfA@4}Y 1 3 7w)챟Tr /}c8{qx.p ##@x%NhΫ0 u#A.0}^h|'ZswphΕ 7OZ]N&;UrX.+GzHn(b9 l[1_K/4އ]}eTOg:q]\]U)2y98_TRyڰ;wMѾ4` ^GJk(n܍i/V|N57'Ӛ:֨YOq|GtIpU&~-|rtCW%d*WX;{7Yt9\&*d)YCaՆҟWۢN5jfLVX5,P^2ߒ˪ 2`&PN}mi:vL(N?я|jC*~G)]D;˪-NjRqI>ytXĀO̺]8Q:  6<]V0F߀B%T3g "e#o\X0|EQ@8#rCBOsN (_c]q*u^H[EE9gH㌱xyUm"Hڴ#Ǧw[{ߺMaBX-gp_ng߯^09Ntaly+܉Q'7걤xL|4U=ŒE>q5lΤYI.bJ>϶BJ xM>W/p"K dnt jx Œ]<=OQ[I6ZM)p9 T%8OE_ N;tjfeXp(JaIQ .b;x.J&,q°xnhqOm\gTŒX1vBnEں]+A߽G_21Od6qY f$^TJ5 Q/O}\7T.~{9!47/Kpv|$Zk"͖4#+cE!m~ts/XGJ2Ԫ`μOA_n5"5 VeՄ>ˎsҴ;*rfII *몚ǒgTؒ(d`Q!ԃI=p6v/Q4O#mG{*ৌ9ZOPz<н~*\bf -Ye=_ѐHuxQ5VMJF9q5]_3UvlS(֝xma>o)mdPD/~L~ S Gkx/5]sGdE=3j lZc v47NUl[ᇠoxj2ӷ.p!͙kH%i~5_"Qz3Ua\>%yRv~Ood<6T]>[4rDzAIdoH^!0i=^d!:zְjB 4|K)׬kBÃ$4q49h`_!u$=r@iB~sQM9O{j'WFf=b =R`,^/2b޹8;؟|(}ȏLy.Kt!ǽ2-}@n5U$REy=9"XpL2ڳ4~ָP fŎ]E=dd2ʚ\-5*Ά2 d~\+˲Ҟrj*[wMT'"3s^uʍhž?O wٯ73?񵎀P, g&21U1B$M_mt>U '+eOH}ZS} EUg.-(ثw݂2ha]i,Yt%S5ip㲌DN7m~'f[V=z%.\C-12Ӎ Uad9O,*Koܿ h!qjc&e0NhꐞŸ1ӞD*['.םbNs_p/Ss>*|F5}S'лf#SGwr^%OC%NW;z_]=dTa0N6K:=|+ ZBgU$\W3 l=DmlE>s^_}7ydm)o~U/(Gz/Tf 32GYo9Inﳵ #&nZK4ޔ2ň@:6?e6KkbW!2Sԭ˾")H4)GN(*w] _=X*Jz99;H$6:rI\GƂ!\ /V!i^1tZP g4H#}gk] Ct$j˩]@;m]đ bvl5wӒoM~EN:\s08rj~[?# e=smWR}s;fe~.RzwuА}\ZpP%ւn]oM(庰N{@huѭa#SėJ!|%~_2&߂)7g@S eo̩%ϥSbBӘ/3gr*ȝ#t[VM.ǐKi7Ay8+a >:HVn&afI[^ɏ$j/ J`Gj6T+QQNyn,7RUcz6'׋S)Ѳ7eۑrKy3S((= ;KҮLOB VkX_ n;8a!>8fyI(re?Gc>3>I*fXdAZIn}D .7R.ϨC)m& *pc9Wv2ɦL8^3mãX mo[jJBs0v>㮴^w%#1ޙT)QmHAX }"HZz|* *UPIEbv+NKє-mP` t$oZd[iuDzao}N~F6@@vקSёM8wRLɤ /MXk^wJke>jZE+!HFZDhY Ț;.H\ l#dH>ie5 T0f\{\}-_:}਎6xѿ,dT91@lh1OIƆ»ՠʂmv>ŇYa'oH:hhᔇ.25`Ϻd"'-ylDH ?qau+H:֒9_љOu) -횟@o(8/Zf}XP{|qfPI8[ϑ%fd 1A!0|ÆܹۡY$ٹjқJA ̟koOW}$<ژW,qS2L*ۼdtN+㉒!̾m4eE00Tzr{NS,b^լT!%y!HApƠay!;?CŃ-r`AbKZ#ER-VaFA5=4qv^#KT wb<1^0gY%(aV>״!;gI- # 6<6hc~ id#sevM Kܵsq.;I#z޳m;!A;5 oR &  yc:LN ^ d U/rY##INzeN|;jUgQ_.̋rdg`7]a׉ۅqu{dǂG/ݖP Wv%Z gq #"zm1e`z0&nM<ٰ0 []/{Iן!?N 'VuLv '1o7<-YU)=Am~]I/bCÂvN/Si U3V-I+&^_zZi 6$֌3nQ0F{&k=UyY*g |סS}YUxb:4w-32H:/Qr6ɷNT=Ƴbts!$U=w%(/tvJ1$A -VjLa{bWul~9wWhZ;#Ɣ> c *|6"/R蕿4pmT{zlGa TM]%#YGO!I "XR=EHG1~1}¢pbSidFoB-%.R>^_ ^]R9aELz* UgnK\"cph aҝIby¨]emrXC?Qr$rɂڣ %I=Z k#WwJj@+vs{ /_kVV^ Ov㖢tF=B[,؄nT =]l;ZEv=ŝS֫ -O4 anu'䎘k $ iF}}S0⯓mtm]ʛ6\Euv9c(JAn?zR՜ Rٓ+AE^}'J*K,{5 nT~V67)w=a+Bm;}!{.9whaۙAM2(Q%wJT2J~Yȶ&waXʓTR#5_/”)4Us( ūU0#&#-QmEbN 煎h72WrFݏHʑF -#7\K dO}8喖-S倰)5j,Ip"d5xd.lп \?rCA YDў27\H<926]{}MśGIR/jA#\-nKoSy9uh-Xbr'n`#` kdoJh @~ l1dT&%^sg5\'NFK*zt*aa~eZ.eb@Oi寺X3"> o*+⃟|N5zun$&Եq8>^)F03RsNa$31͚0w$f_y=R];"#˯T:)xr^1\={/ x;F!LNŠQ-G}1_%7!wvK3xIdnݼjRu` z: k̷h<rMÇ_\Zmt>Rؒ 9@0Nx2 Y/!3;b#:P{AMIESv1 Cۺ|*k3v{ 2E%.P;hDS4ŋ9A QNnX MBF'+_u/UH~U:Y7m_2N-^W75Ơ~N;jX/ ٶJ npL!&I^Y&vQ |9& v(m7[RnP~=6*.;єm6_{Itr<֫]Eroƒe 4/UTUpzPJ츦~Óy(Kuq0gSpsjo endstream endobj 50 0 obj << /Type /FontDescriptor /FontName /KDBYZG+CMR17 /Flags 4 /FontBBox [-33 -250 945 749] /Ascent 694 /CapHeight 683 /Descent -195 /ItalicAngle 0 /StemV 53 /XHeight 430 /CharSet (/P/T/U/a/c/e/g/h/i/k/n/s) /FontFile 49 0 R >> endobj 51 0 obj << /Length1 2101 /Length2 12166 /Length3 0 /Length 13443 /Filter /FlateDecode >> stream xڍeTh-SA w ݂; nkpKz;=w>| PSPWWgcr0#PQ[l4T@g+{و9Ao2qcЛ=@`ccem7v2(0d.TbVLКxyyrL K[FSc[?!h[@|,,v.tw+%@tv~(!nj@PrJn  lL.oNf@g[~<@hc03?;_ƦvVs+[ @IRbۛ64uqx7v356y3xc :[9\]ldfbvv@{ ĭodg6o*f,VN@Z, ++뻷@SKI=)~xx;:8ߨ}́o]݀+ߊEll3+Shae'hV=ַ%d۞9z1k,"2Rb G-*fbg0spxܼ O T+?,7s\oo/ $]mmcalge_v۩ߦZܶʀߎEmx9#r)[L-Zb0=tohjȸ /7Kd;;{";d̀m9xc0wpF=Zn^o_ۚA? A,&[LכN;? X@mIj'oM`:-"Xz:Ze&|ONmv,q5mҿpo5;Qs|{m?RJs^9r9r%rVN7oqruL[7֔?.\_]z3wy{8eS,fV['g_=Px?mC0uu~ 7J= sAֵAw"L;c=7Ѷ[݊x6eyĕ-A*@JD1b`c@H3׽WCG;qCs /}FFJPlC-ۏNwoI KA%/C੒ `8u`h*lǷ{Y]oǷmFs\~3!R_&:e<|mrE4{E <*8#Is'-2J3A|sHiGEҧ1^ğ,IVAT!40ANa"{$O'mD_D@C~ eP`7}3ōy%*+F0l5U.o?1o"Dϵq+W8-?9dW}yZ*S@2i53>ٌyʴ N֗32/ta!L;^\g  =7~;_aJ!6?H%Ҩ?)zdA)}qʋ+wmAi! S`F1S0Mm qFQmGDOԥ7gO#}+||+(;M?' 7,i6^Ԭ<:\ ͭ?(fxlrWP.d_KËY & SmZL=(l*NG{Ul bZ7듒KŶVLo/]\paQ.i,ymv#(zf+?PG0/kYxOI eR \anT.&o ;l6T ab|ODGuk#UPX+b.dPc,u! ET E59+$RIDP iy v}MB5gӺ"_{Fq*$mw\m?X}YHSZ^ ITI7}TVSr3LqK,x%ӉX8]XwF EY]JdUz!smw>l"h 4FG=ڞs)H&-.c߄Wq^"lS "Yb 2܏zkO ),!.5 PдKIW 2#(泅?sL(;Q2~* Ca4S#O(Gd樧$\@=|n6͈QTp:EjL=Y?;dƓ3,$kVjc|zP]z&2 z؁>ҶѬ}>nmK,3՚O֖lq!8}7}ZFP }m젙_{hFǩ<.?2BHwmH/ zi vr27|3}&eF\̒HVEG<>`ʺFԲ} m9 G-<ᰇ1kC}'/)͒IW+qۃq貰Rdȋe_MTٯt5e1sf/E̮衳Y~QGe(|W6U!B [p hqCZ #]M H~I O9X%/0\*LI!׺s1̵*E]gNi v%Q]@XVZ3̀9tD[8Xn!Gx(|:@X9~IwZqdRffa'3G.Z7UFi,Il5Ȗh`(n@l*=5gF/$GX[A>,k^.nHy:\LWwZy9Zlh⡾{XAP&p+NhDɋu;!7Ug6cǃ}鎖'4):" F$([B!uÃGQ+_yɾω'gz(? <堓U2?OPy4(Gb4f˷xM# !@O]m2;Ip/?Cn Rl-oˬzSM3,B8Ȃ|") t@t̃-g*cbu˗N (Wf@ln?߱>pCE坶v#tp񨠤R I |K>n++5@QV=E/=^1QӹD%p1%$Һ\P rIՆZ(nq>QfgJ t29.iyRaya[f2ͶuS%h5>?Ӳ!KP&(°pG >Tg(BIkp4Q ƛ.v~V49R%o+ۀ#h++ ԍ-wVUX<ھrG~IA|I Z+ņa^iZM;1b¤nq>Y➶Nlj _O\e^Kc&mvnyOσ)aM1YпW0%,V mjK.L˘XپXp'+};­r`/ө[$0O1Red*z F~Ev\Z(fu}W5&IYāeD.mZd2WOB]\o}zs^Pe>lC 'vUsyG], AB.c/z9wpls#GI$ hD&T.v?hWх+{dJy?נZRp|`Z?sz7]T<4LEցvYt龾Өk[I?[vG^$:|v}| dc#ӿ"Le[~"8 Z25(9 fQ]TFxd.`#7h ZwAº]Ma(S 4}9n}wcxeMgߗwi] |Y6 Lf89Lmcޖ"2U ҿxmeݦrDXvh~6xV&⼱7+^+$wAGLQ-c$q. DJ<RY,q (f坃ftL*!gد]rE{}&^(s*?ZJ`Ql)w^zj"Gĭ\6+J0NVd)`5/t"wmH_W/XqjhjE]qbxHMw/1U0d= ,]ɻ$s}cWx> l9id}IewT WLpvO;gc .nP\3fr/"mFU25WD$6İwR* ;BwR~ls#vT6MF3cy"*t" UmSȳ%a}4y*nvm\\)K1iWz}&5V.901බ빗QuAfOZZHMGx"ITV^A,ۻk>'KC2ܰ3fl囱و C '\}"j=e5cNdu/xgg|_%w!I/c-GN7 $/MV]f*hxü7ZO{aWCk UpvRm]B8GJ(I7DsFMx2ۊŋ HH%]cD_&}x838 hjy䙴g7O ޺ av쨝 TUتUEõآ;hBKF%DԨէ'>COd{3͵M䯺f[?/a8C@ ./]w%^4Yϩ 1/'oȤh} ˚ \X4|7;,%u\%N7jN|uP^+#sK5'j$J,Nc]<ᅧ."*wytu=e8OpXs]RSyYH}bB6sᐮֆvTD cMy>P_pLFAQE{SD5}AAft`} yi򲱣>+S?9@+SS:a |4NnW֊2wE[q/ 8#3X&L>AK!ǦsCϱ (`s2 /g P@KPeʭ ;xWp/^Zv-oj9m oqXq RދX< &tqŏn('p`&wd#C)sW.ʧh /0WpB&Ҙ'ziN>Ћ2m l6K'8(2I;R!%6c޺=zsď9)SngY: C,0s/k: ,ePRѤ{Zq10cb\NΖ]`ql.P[9ȰyVsBrB9!#䇁:8̥2.Nwgpq<ʫMNqD7 k~g~=0A<RP|TDQN/2 ]L»c'Kc[ͯCc2y NНh>jZ҂4tpٟs?Ac5';qN|Gf(P\ h#5{M!ˊޗ2,R^)##3ip%%#e(.pɐ'vnaCNRfHPڼXf\&7 )pǧ{(Pj~aP={ssY=4cf(,&+~p=bZF< QZA$B.m9#ѕ/wÂG eyp/VQ^Ra“ed:Bդ>cP¾ꐫ[(d, %w>:5)&V߱ht`w;?-` &^|@3T7?'&.%W.%j T~~l|JP,׃xFx+A7guu &3 \0]:]$]WD].@li C_3|K  ֮!tdQ-;ٕ>Z|H܆UZp/` M֫cMBv~| ]%O¬Lga'C8Tp\(\[̆Txagth3fl_fiE|3E'Nl:A'tv?qdCQc榸H|{ƞAE.`XbO4qU*K& )n $M{&Ur1l?HlΉH쨣|l/\nz*T+XV L)={$4w&^y}g@2ZMXCU#{ݒ>{Iέw ugKa}W/Zj3+ݕqi3|4]*IDէÓ /Gc.7aE$uF/G2?y$ŌXMWoN?϶f~z] o#7֪Um4/3P;sl67,Kͨ]*2ݍ&q:r4U(N@8g ռ,qƆy(l$^2PH!N:nV0jz S{ <1խQIn/HM"ݟ]Y #~S~:-Y X0’w\6cOa{а l*83ROݩ¶5f6PFtcl޷8ðN#=#{ɮD5PvK!Pe^xVIoh]AR"Q̏y!Ԫ}*^-#X (R3m% JwaPosb(&B2{*5fSU4zVc ybT}",Z2;Rz'|v'|)W:z^SfYR<,N,VlڔUo;O(Hd^ń\f \ ,%csdD0F]D]6jV'T3.?!Ej|2Thʦ 4UIcIh-e2L=UԂvC_M~/ȼF>dȈ'i$ T_6SSay(= .q!-!M2t3حdKrć\^9JhP&_D: Ѥj|::rw\@grAPU܏z̒%+F,( m~jW:uhYAMŠјUʏ* ;F} $qt(gyFzࢦ doP_KG1,7CG>xOu3S0D) өif9vPgP luQIWf_h|wuOf!>S%wHb8y캦^fZ&SzI(*'tޛFnhmٛMj'=!*1c2lͽg9*f?uYDZ6  s> `Y[X_kPI_]h'`f0 {Vjq@="8 _rs'F0V"x&c*E`#?B|).(֊*?B\%L42%Œ] 4A' N>eAa*[G"ASPUP^;}1ۏ[[b)#S:h[M%(Qh̋kӮSznF>\Klp Cjz.鹽Ώ {bnrd[<j#I¢a1ufy|rZ GsW[IN\vL.v5a;7,8+Iz's9m=,*4::h05zKm}󅡿:b\ې}Fq; BڮF cC1Qk]҃~bŊ>6xXQ~} րiՋo֢A.|55d`wNjB>ַ빣(e nB2 x$CHf[/kEkJ]3D5Y{F+͍f~@lr$=EiKg.È_Jn,3c;:t-"pNla⪨#$𫩹»6(AADP\V!|tX{Kd2+S=mm>&GhV>lf1|hSE*.WWA<Oj49Y)4(ϥ~? -lpKgfiش=a*u)A԰.))KY})4m )Q;HNH,TDO  x4+JIH+U_+ {OU/[p/+M#ymCc6T8;?58Nb{G9nb%D׽hht#컴dcZIu~ {bnDHA_ʣւP3r:cxxw|NzTЎor \Ga&Vï/P:G>wMbq I7pErࢸ iMgP_/S30-R9)g3dGJJ_,!a>*,9O`Rą+\AwMƬo_H@N-\a-P!z&)ކ:O ߿eڐ`.^YKaPa(bFi ާO9Lq 6曇 ?ijˏ?W5~]cR?eCV A.&€la:O>9eSo_&? {;"ҸR@9|MU(N{K,L<:gϷ#EP7227^((ObN}PL$RIgbiϭWՏT'2NwܤzTtKIWqBKF@R#5;#c2-rdhy#PC'q8N8c0ړV 땟 ~J8;_+oudi-AJRXX#/Y 3t"$\3a92gEzx:"3leN/sr$tQRB [~zd!n}I&\6h,[P}E]mVLz)5Lі~(Hpꇤ #Fq1e֖eQ")R7*Št%CTgRlZ:a@֭OI%{]n?ևOelҘ4SF 3I`z>H0ë.9˞YTz\oNv5)L:[nHrG[PCʱZA8дd ת'?<7{f#p5EވX01Hy,[.ل\GmoNoz!`> endobj 53 0 obj << /Length1 1473 /Length2 6794 /Length3 0 /Length 7787 /Filter /FlateDecode >> stream xڍTk6 HII#H4Hww 1C !t#4Hw4~Ykٽ{_~塮="y$Z@~  ! [쁀!Q:%=]~ ~Q >>ߎ0  bà`" qtB`rȻ= v (@ t*ځ\0;RNH$\ۛy8pp!H'>~Ah 07 @)\!v`( {P@M Y/.'ݟ_ ;;@W0@GEA*lQ[T ?v8+ ꘕ0770՟l:w_?u¼K/p^#( TRs#|||b;c/K(yHOp-!vH-';J vKF0Cя'KaPWWEI_W`>nA0?O *wkuA?u:xa6 g0[ ١we;RtumgcA\}xD !u5Z`{ZHjG䡎(s T >`{]/.= T W C@~;(>Vu P#m6uv0_+( ,yx|P<v^( 0`x+. RQ( #h /Q_[Wv%M%T˿o 0l7? w o>ͽ9" DsskLE/TQX0?vN}j+b@FJ>O2b%(뛱l׹J_~Ehz liB)yMrPqnNgJ =0*AhT5Ƴu16m 1+Xp<7I9ag֘s4Ղů6+T[[pc7ǿ@81jgaoP0pg`FPU ߔ@)*tҫJ_iQ4f Ed8O淈57KP38vOyјJCىM ҼW喚ҴBx 6dי|";|WV 4ϒ#J?ϛ5@M5/_H d.)w\?=l]dq0%e]՘T֊q;ۯlN/oLl;'6>.&SnQ qttDdfhM~l]DVvQZ%y{?$h (W'۪mhE|%OIKj$Kƚ;}WsψhF׻YL=ۧ7ڻ3\y pi/ńߋ־HhӤ;^sޒ!sf-x:?څ7DWS \S0ON/ VO,\G0ݏY~B 86"rP_j*i0ĮRkO+GSv4/*ZJeq^c" Vrb_ ݨ|/Y(!xkeaRgy|dUl/qI# -Uf^cn5/藭. aYFKWE,ql+=~%P*q8r̸55r-MJ<:1Žt SSmo hmf?80xc H !ύ#V&j6*kqëyZEFGny:yl8q2 KJVpz\nh0h Ulq @fl*AGwf 6zE'/hUA>6H@#M tf|eTZxBNہ^J)2=_!bCWSʕ4ŸY=Dbс+FoHkǂXNļ~Jes.j\7)YLL(\_Ƥr>jߺbB>H $4= +TQ)޾(rs^?.svc2yH'.*9McM?R"I 0ٵ6dRUi#{I klG%MqHDGR>_'K}d~;9K]s!yʖ^pCӫyp#UVui5[U,'4:Ң9j V@n>SkM7O~2*yy ]l2gM=WF[Pp=~GԋEkes4)wT(jk^i=m p\U~Rͨ} w;2 4\Pwv,'p^D CSuY{oLꅪWYq??7 $jTSOJEq\m9fh*'ƃLdSCi#/<n&Ze{߼pүq_I9zP.]Ǟ]6&S"V@;/K!pkܼ5B+XMч69un&ںq?%_GcF8sw47%'MРvqfH;l+NL$;鬱;tg6Y`j]7XrXc# )Z=%=``s]W%oIXf{o]yJ_|)PT8r-gg)5EzsMI;z|> |:cP$`D7E 7VbB|Pmfޟg1<2qH־8*|LΊ^)KLRZL6%ֿt4$F;-ONiauK%eJ3mU z/fzYڳuwTCh}EVRfwԳY1ZhSWT^~"*Nѻ.{|Đ,\8&sg"/~j}7;%f|@qp;B,oBx~ hoyyNB߇.wZ䌑b1@f vɍ^7Y%:'л 9,6ꫡ6a:p-|$$tk|R2RGy>,ޛRԹ0cÆ^Q.ըOeRRoN?Y7L0c7lws|h[?~g4ΆGX&!mc$mm_'..N)6؊.p!\FpV<[m%lF"sl㷩 }i&̟^~^!]˰޺1Y-6.;YZYz5hz5'᯼gK/(S( go9j2vt"O9J^40ZHh`3'Cwu]5<)kG%*<, WޤBe|4tΡgz86dG#U!4CVz酗8S.I.4o\JD:Y_|$L|R{ShCe'(dTV.焼9}e>{vx! m O*c>pf;ݪ ]ʾ8$jOk3ʑ͸K\~rG/st2jzDHh2e!:D{ %xM{Ɉ֩*4ڏhmZl;L:nH26~BJutۿGcBf'ۇsZv𡢩 ]/M![ӧnQ,3jZ{oR %d^7 UX/(6uKȕ`Qd>Lj=ۜnI|$UQ}KXFY1ZsotkB7%&OcڀYc䛽)8;߰YPT+bQUmQ?@#b]4",YIdGJ%vQ{o7!hK.[<Ch ٷ J3 y=.I2ϪrʨL5[89sVvZ=A?j-dҾ_kF` endstream endobj 54 0 obj << /Type /FontDescriptor /FontName /FDRPFI+CMTI12 /Flags 4 /FontBBox [-36 -251 1103 750] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 63 /XHeight 431 /CharSet (/a/e/i/o/r/t) /FontFile 53 0 R >> endobj 55 0 obj << /Length1 2197 /Length2 8485 /Length3 0 /Length 9774 /Filter /FlateDecode >> stream xڍT\5 "0tJwIJ* 0C3tHw H t#ҍJtJ-ւ'9sL-k +aHn>8@^S_ P;.c  !!Q6 \|>aq>q w(ܠMF2Ý<]6HT>ج|bb"\`!mV  FzMtuww9"x.6R\w( F]րZ GxpP_=8rP@¬.TuW_\/?_ ++ P0pT> uY~(@(CX@Fޟ4cVY0$g P=y\{@a֐2]x `PgW1(o  3ae d}07 ]\:pP+$lfG0]S j?~z0k8w+562T[N99/  |jͧ bI@?2  Zp4l (B^_):ۑ/?_?wj]ЄYl uu_*Yÿ E(A=PPPX|o|@P+gezS6aVp럫/$ +Wӯ_߂` wzn%lW|^!Kν:/x0"ۺNő@~Ԕl絨EmFd@ >iQd5X˯\>Do#4\[[M,`6d }2ɹV36%YJmYvxb DaS ~/LRU&ġn"EZ rL1:t)zk랓qƖTF0(J"e<[qsp%v| D~CpKnՊH[uwD9lLVyg45-݉fk4V ):-f4Fz OL  [=??8˫ ^:>=I&SM+䐱m`) Ge,KT dAY^\. GNQ٧IH ả@gG%#uITw,%05s\>S.&h{.0{0[r2h>'{^sǷmQ8S?mݏ[yPU6mߢ \nTN6B1Į8۬Z޵ XM[EB8XrìR&um/efLQIOYr y?iEl_5cV $8-kǯ̭ޙ3 p~ˆRp\&qsEc͚UbTQ T$J͛-pI9O uyɭP'IZv(ǩ{9'Alw- , B*v˥*wnu2"Hۚr[gJҳfOJV*;Lf'm}]T:t9`PR>̖gD(&_ڪnBWx~+ZRy? qnJn ]~g'Ǖ 9?I+?kX /%+VbljNrbN2jxZŪh:JG-Fpo$aM{)'ycƩi){ћOJXX+FfGm~ؚ9J4Eh}Bwa|dLxE is mR`w=X MJ(Q@aT~Ջ-ؽN7y*m(VD|b_vh pe+6G?춵$RJӵDׇ'd˖} *̐` t[*$׻.WAO4|s8jb%m`pD'iBܞn/[W0<{1(W1 gaP/Ǔ͠N"pۏ^LztoTeX ':1ŸWvM>lq7V՚^")Ï؏4oW79-t(SVB@:u]O*8:Kk졲<|ƹ:\%kXvck'ʔQҰ)(b(}#N˪ 2R*-zXQbͩ{p#q| $B}m꩷էGc6ͤYp\jRk4Xo[)غ$y>~V\+] q+š\*ܼ%,yC)^P#=˲y$S+5"$T92¸޻G`Rxz[r\ 9we >+s|W[Sa1vj)Zpame֓┭vM+%5䒕&?Wm`2hg2qTJ)(G1b. /nw 줚BZcٛNp 6nAJWL'\~)=ǕmaI-/c[ QM-u!o$]{ǼZ G0S:( V|_n0vwm֘J8Ć.DT{74Ƚ)}~E~ykt#]򠮯o7%{>HD@ acrbx}=>-з&8ى HC^Euu'6^HZ 2w -,-Y_ՐjGf:ek_LJDxƕ-(ݵ$`ULO̊(cẑvuC+=.L VǺΫ 5~A KLQ"W,ڈ_7ڤ, -lsv5_NV:Kh"7_?~;4`\ԧL/Go֤`[e$?}rI\߇bp=\6G}MrZ_;#uw5.mX}j{s$ŕY17M'T}"WyE8#Dư$[S(;i'pl1B`lszV(1hS+PG$Ы a!5.9nkTW5//ֵ3+ %p\r҅8ANM9}ñ$KNzc]W{WȰo(> 5DU/8G[JCZ}[JzVF{z;<ƒ%hć`%ݧ"5QEa3]Lngku&:V%C#Yngc-i{:w6rI7UX`ްݭrAaKD]!^dݸ*2wi\DMᥘt_I+G 74׈y Wv=f^Kvc7L7+!i3!'.nha{pSqcqnʭcNAaG]?Ω8ۢa)r6YlkA0}4IM=7և 8J'oCV3G Us'"B1x `v_:,GR,T?VJ}~Klz"Gz"q#ЌYX-e!gk~RiXzz>|!eۉcKeZgU5[Sh^ Պ,Ox(mgWJԸ}7ǑT,g53{NRm?U$I<^\Dx6ZJ~q]3M>~jCUKsBy ,yuqmˁ[$Т޲`u ]?`86E /;HvV2;ܘ@.xe4k$+Utǽ"x_(vd5߻?AkuYЉvNK)Y]Gy^pL<3Qmw+tBU)wN+pr[@{:wyx{F$$\hL8ߑ)6K\WJxN@ZuZf+c;L|Rnz̭q {eMJ`wFۣC3Xٸ|Tq(Et1RdjzO<`903/1"Nb$o%+~.1p1VB}]t6 gy9O`V;Tlؾ&+t]u&Kmntƨ#X R+H Y0{/(+ՖzO0 Յ[wq7Vfprg~%ڥc#xɤII ^KSt%4B#ڮ(>ޯ$!CT-s!P!GEf5Y(q^tyElbhcu+YsDuEySeWKbSoqcYn=u q1#|Jg-cC#ׄ~]9ȷK|1V[.ߗ.< `DB1MM T]r'$@ N9t_ML&& LQFAQ1$,f8~_҄K exRbQ%,tכ\~ a"3-PKpaYƭwyr^CmE袒8!2^9;gI87ʉ 0n}arS-yRoWIo>ߕR0(P=q Gv;{DUM =y 5Lp[Л{ݙfrHN4mn`i2zJ&;O7)m⟊khrou|%JjZw ѳ(uUjE ,LrD"X$6k~Fd]|P&ŤqW٭A.w0#DS~lm. Ir*,0x{QxV4ҩZ6ohM?~aIw4wq k@:֎Xwߋ|r_ޢ/t$ӖE8KWV1f55oBo^Ҟ1+tؙ ./k༓7T% y:2@{i] i=gyx)穻<{gΟ̂dhf(>B; E; %@e gW#Y+## U߱-gt`wH4db+S`dc=W|ݩ]Ë8|1~cj.j`JAquo&yy4ejr怰Ṭ˽͋%Ƈ/$1ve='=F[$ X\%XL &Z~EITSBz;>?-c*ɅEek J2E8oy1^Ջf_$U{l5qgmc-?$|̩Ӣ|x$avy"enInow֒#kMD`T1QkPբ2>-,1ֻMGFLk\u M~( 5c#Yñ](z8ɫj)DDi[/*oo84D/۰ȹ\ýߎu̟-h\뵞ĉ1;HKRrCN*3f_i_MMt?_߅Cm-Ya6M_Ոkey)~3l/h<9-$p9}Oxos{7 Mֶ]j.\VQxtjgySeM cG3B< YdsQYc>oPerv=r.Ӻ.W3,qq:9+Q1BHJBws%s0ơC^{@*bO2ո~?bqf@3ɪcV^>Ӎ漴cա/$t{~/ނ.jQZ-öY'R2v6Lr 0es Q΂Q/w$1357L. z V;$qxČ / 5Mε22z{b@Ou.udǧ)"?19ݹ['bokwK\"ֈL}+M/_I< Sg~v;Q@ߩS jt6.,7}w 3r f}>G5ܞ:ߢsdHOQ8]/U#̲ki)&דt=x o Bwu-\jh._;KQ▘,f_U(w>OƖc76ėª'C?[AVl>{GXj$ M1L=ѵz31Ί;3/T >OT[ endstream endobj 56 0 obj << /Type /FontDescriptor /FontName /YXUBMJ+CMTT12 /Flags 4 /FontBBox [-1 -234 524 695] /Ascent 611 /CapHeight 611 /Descent -222 /ItalicAngle 0 /StemV 65 /XHeight 431 /CharSet (/A/E/F/G/H/I/L/M/P/R/S/U/a/b/bracketleft/bracketright/c/colon/comma/d/e/eight/f/five/four/g/h/hyphen/i/k/l/m/n/nine/o/one/p/period/r/s/seven/six/slash/t/three/two/u/v/w/x/y/zero) /FontFile 55 0 R >> endobj 18 0 obj << /Type /Font /Subtype /Type1 /BaseFont /JHNAAN+CMBX12 /FontDescriptor 46 0 R /FirstChar 49 /LastChar 117 /Widths 41 0 R >> endobj 17 0 obj << /Type /Font /Subtype /Type1 /BaseFont /YZMPTW+CMR12 /FontDescriptor 48 0 R /FirstChar 12 /LastChar 122 /Widths 42 0 R >> endobj 15 0 obj << /Type /Font /Subtype /Type1 /BaseFont /KDBYZG+CMR17 /FontDescriptor 50 0 R /FirstChar 80 /LastChar 115 /Widths 44 0 R >> endobj 20 0 obj << /Type /Font /Subtype /Type1 /BaseFont /RAIGNC+CMSLTT10 /FontDescriptor 52 0 R /FirstChar 34 /LastChar 121 /Widths 39 0 R >> endobj 19 0 obj << /Type /Font /Subtype /Type1 /BaseFont /FDRPFI+CMTI12 /FontDescriptor 54 0 R /FirstChar 97 /LastChar 116 /Widths 40 0 R >> endobj 16 0 obj << /Type /Font /Subtype /Type1 /BaseFont /YXUBMJ+CMTT12 /FontDescriptor 56 0 R /FirstChar 44 /LastChar 121 /Widths 43 0 R >> endobj 22 0 obj << /Type /Pages /Count 4 /Kids [10 0 R 24 0 R 28 0 R 32 0 R] >> endobj 57 0 obj << /Type /Outlines /First 3 0 R /Last 7 0 R /Count 2 >> endobj 7 0 obj << /Title 8 0 R /A 5 0 R /Parent 57 0 R /Prev 3 0 R >> endobj 3 0 obj << /Title 4 0 R /A 1 0 R /Parent 57 0 R /Next 7 0 R >> endobj 58 0 obj << /Names [(Doc-Start) 14 0 R (page.1) 13 0 R (page.2) 26 0 R (page.3) 30 0 R (page.4) 34 0 R (section.1) 2 0 R] /Limits [(Doc-Start) (section.1)] >> endobj 59 0 obj << /Names [(section.2) 6 0 R] /Limits [(section.2) (section.2)] >> endobj 60 0 obj << /Kids [58 0 R 59 0 R] /Limits [(Doc-Start) (section.2)] >> endobj 61 0 obj << /Dests 60 0 R >> endobj 62 0 obj << /Type /Catalog /Pages 22 0 R /Outlines 57 0 R /Names 61 0 R /PageMode/UseOutlines /OpenAction 9 0 R >> endobj 63 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.14)/Keywords() /CreationDate (D:20190726110704-07'00') /ModDate (D:20190726110704-07'00') /Trapped /False /PTEX.Fullbanner (This is MiKTeX-pdfTeX 2.9.4902 (1.40.14)) >> endobj xref 0 64 0000000000 65535 f 0000000015 00000 n 0000002011 00000 n 0000080119 00000 n 0000000060 00000 n 0000000090 00000 n 0000006459 00000 n 0000080049 00000 n 0000000135 00000 n 0000000175 00000 n 0000001795 00000 n 0000002065 00000 n 0000000222 00000 n 0000001903 00000 n 0000001956 00000 n 0000079332 00000 n 0000079756 00000 n 0000079192 00000 n 0000079051 00000 n 0000079615 00000 n 0000079472 00000 n 0000007818 00000 n 0000079897 00000 n 0000004061 00000 n 0000003900 00000 n 0000002207 00000 n 0000004008 00000 n 0000006513 00000 n 0000006298 00000 n 0000004155 00000 n 0000006406 00000 n 0000007521 00000 n 0000007360 00000 n 0000006619 00000 n 0000007468 00000 n 0000007615 00000 n 0000008063 00000 n 0000008088 00000 n 0000008148 00000 n 0000008182 00000 n 0000008552 00000 n 0000008652 00000 n 0000009058 00000 n 0000009663 00000 n 0000010149 00000 n 0000010383 00000 n 0000020177 00000 n 0000020434 00000 n 0000036792 00000 n 0000037137 00000 n 0000046441 00000 n 0000046679 00000 n 0000060242 00000 n 0000060631 00000 n 0000068537 00000 n 0000068767 00000 n 0000078660 00000 n 0000079977 00000 n 0000080189 00000 n 0000080355 00000 n 0000080438 00000 n 0000080516 00000 n 0000080552 00000 n 0000080674 00000 n trailer << /Size 64 /Root 62 0 R /Info 63 0 R /ID [ ] >> startxref 80948 %%EOF iterators/inst/doc/iterators.Rnw0000644000176200001440000001437413513447415016534 0ustar liggesusers% \VignetteIndexEntry{iterators Manual} % \VignetteDepends{iterators} % \VignettePackage{iterators} \documentclass[12pt]{article} \usepackage{amsmath} \usepackage[pdftex]{graphicx} \usepackage{color} \usepackage{xspace} \usepackage{fancyvrb} \usepackage{fancyhdr} \usepackage[ colorlinks=true, linkcolor=blue, citecolor=blue, urlcolor=blue] {hyperref} \usepackage{lscape} \usepackage{Sweave} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % define new colors for use \definecolor{darkgreen}{rgb}{0,0.6,0} \definecolor{darkred}{rgb}{0.6,0.0,0} \definecolor{lightbrown}{rgb}{1,0.9,0.8} \definecolor{brown}{rgb}{0.6,0.3,0.3} \definecolor{darkblue}{rgb}{0,0,0.8} \definecolor{darkmagenta}{rgb}{0.5,0,0.5} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\bld}[1]{\mbox{\boldmath $#1$}} \newcommand{\shell}[1]{\mbox{$#1$}} \renewcommand{\vec}[1]{\mbox{\bf {#1}}} \newcommand{\ReallySmallSpacing}{\renewcommand{\baselinestretch}{.6}\Large\normalsize} \newcommand{\SmallSpacing}{\renewcommand{\baselinestretch}{1.1}\Large\normalsize} \newcommand{\halfs}{\frac{1}{2}} \setlength{\oddsidemargin}{-.25 truein} \setlength{\evensidemargin}{0truein} \setlength{\topmargin}{-0.2truein} \setlength{\textwidth}{7 truein} \setlength{\textheight}{8.5 truein} \setlength{\parindent}{0.20truein} \setlength{\parskip}{0.10truein} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \pagestyle{fancy} \lhead{} \chead{Using The {\tt iterators} Package} \rhead{} \lfoot{} \cfoot{} \rfoot{\thepage} \renewcommand{\headrulewidth}{1pt} \renewcommand{\footrulewidth}{1pt} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \title{Using The {\tt iterators} Package} \author{Rich Calaway} \begin{document} \maketitle \thispagestyle{empty} \section{Introduction} An {\em iterator} is a special type of object that generalizes the notion of a looping variable. When passed as an argument to a function that knows what to do with it, the iterator supplies a sequence of values. The iterator also maintains information about its state, in particular its current index. The \texttt{iterators} package includes a number of functions for creating iterators, the simplest of which is \texttt{iter}, which takes virtually any R object and turns it into an iterator object. The simplest function that operates on iterators is the \texttt{nextElem} function, which when given an iterator, returns the next value of the iterator. For example, here we create an iterator object from the sequence 1 to 10, and then use \texttt{nextElem} to iterate through the values: <>= library(iterators) i1 <- iter(1:10) nextElem(i1) nextElem(i1) @ You can create iterators from matrices and data frames, using the \texttt{by} argument to specify whether to iterate by row or column: <>= istate <- iter(state.x77, by='row') nextElem(istate) nextElem(istate) @ Iterators can also be created from functions, in which case the iterator can be an endless source of values: <>= ifun <- iter(function() sample(0:9, 4, replace=TRUE)) nextElem(ifun) nextElem(ifun) @ For practical applications, iterators can be paired with \texttt{foreach} to obtain parallel results quite easily: \begin{Schunk} \begin{Sinput} > library(foreach) \end{Sinput} \begin{Soutput} foreach: simple, scalable parallel programming from Revolution Analytics Use Revolution R for scalability, fault tolerance and more. http://www.revolutionanalytics.com \end{Soutput} \begin{Sinput} > x <- matrix(rnorm(1e+06), ncol = 10000) > itx <- iter(x, by = "row") > foreach(i = itx, .combine = c) %dopar% mean(i) \end{Sinput} \begin{Soutput} [1] -0.0069652059 0.0161112989 0.0080068074 -0.0120020610 0.0017168149 [6] 0.0139835943 -0.0078172106 -0.0024762273 -0.0031558268 -0.0072662893 [11] -0.0055142639 0.0015717907 -0.0100842965 -0.0123601527 0.0136420084 [16] -0.0242922105 -0.0126416949 -0.0052951152 0.0216329326 -0.0262476648 [21] 0.0041937609 0.0121253368 -0.0110165729 0.0044267635 0.0080241894 [26] 0.0042995539 -0.0102826632 0.0051185628 -0.0013970812 -0.0172380786 [31] 0.0096079613 0.0046837729 -0.0080726970 0.0083781727 -0.0234620163 [36] -0.0099883966 0.0026883628 0.0029367320 0.0205825899 0.0035303940 [41] 0.0204990426 -0.0010804987 -0.0033665481 -0.0127492019 -0.0147443195 [46] 0.0027046346 0.0016449793 0.0155575490 -0.0003488394 -0.0079238019 [51] 0.0086390030 -0.0039033309 0.0168593825 -0.0067189572 -0.0009925288 [56] -0.0162907048 -0.0059171838 0.0093806072 0.0100886929 -0.0111677408 [61] 0.0021754963 -0.0056770907 0.0081200698 -0.0029828717 -0.0163704350 [66] 0.0057266267 -0.0017156156 0.0214172738 -0.0141379874 -0.0126593342 [71] 0.0087124575 0.0040231519 0.0038515673 0.0066066908 0.0023586046 [76] -0.0044167901 -0.0090543553 0.0010806096 0.0102288061 0.0039881702 [81] -0.0054549319 -0.0127997275 -0.0031697122 -0.0016100996 -0.0143468118 [86] 0.0035904125 -0.0059399479 0.0085565480 -0.0159064868 0.0054120554 [91] -0.0084420572 0.0194448129 -0.0103192553 -0.0062924628 0.0215069258 [96] 0.0015749065 0.0109657488 0.0152237842 -0.0057181022 0.0035530715 \end{Soutput} \end{Schunk} \section{Some Special Iterators} The notion of an iterator is new to R, but should be familiar to users of languages such as Python. The \texttt{iterators} package includes a number of special functions that generate iterators for some common scenarios. For example, the \texttt{irnorm} function creates an iterator for which each value is drawn from a specified random normal distribution: <>= library(iterators) itrn <- irnorm(10) nextElem(itrn) nextElem(itrn) @ Similarly, the \texttt{irunif}, \texttt{irbinom}, and \texttt{irpois} functions create iterators which drawn their values from uniform, binomial, and Poisson distributions, respectively. We can then use these functions just as we used \texttt{irnorm}: <>= itru <- irunif(10) nextElem(itru) nextElem(itru) @ The \texttt{icount} function returns an iterator that counts starting from one: <>= it <- icount(3) nextElem(it) nextElem(it) nextElem(it) @ \end{document} iterators/inst/doc/writing.R0000644000176200001440000001363713516640512015633 0ustar liggesusers### R code from vignette source 'writing.Rnw' ################################################### ### code chunk number 1: loadLibs ################################################### library(iterators) ################################################### ### code chunk number 2: iterable1 ################################################### it <- iter(list(1:2, 3:4)) ################################################### ### code chunk number 3: iterable2 ################################################### nextElem(it) nextElem(it) tryCatch(nextElem(it), error=function(e) e) ################################################### ### code chunk number 4: nextElem.abstractiter ################################################### iterators:::iter.iter iterators:::nextElem.abstractiter ################################################### ### code chunk number 5: iter1 ################################################### iforever <- function(x) { nextEl <- function() x obj <- list(nextElem=nextEl) class(obj) <- c('iforever', 'abstractiter', 'iter') obj } ################################################### ### code chunk number 6: runiter1 ################################################### it <- iforever(42) nextElem(it) nextElem(it) ################################################### ### code chunk number 7: runiter1.part2 ################################################### unlist(as.list(it, n=6)) ################################################### ### code chunk number 8: iter2 ################################################### irep <- function(x, times) { nextEl <- function() { if (times > 0) times <<- times - 1 else stop('StopIteration') x } obj <- list(nextElem=nextEl) class(obj) <- c('irep', 'abstractiter', 'iter') obj } ################################################### ### code chunk number 9: runiter2 ################################################### it <- irep(7, 6) unlist(as.list(it)) ################################################### ### code chunk number 10: iter3 ################################################### ivector <- function(x, ...) { i <- 1 it <- idiv(length(x), ...) nextEl <- function() { n <- nextElem(it) ix <- seq(i, length=n) i <<- i + n x[ix] } obj <- list(nextElem=nextEl) class(obj) <- c('ivector', 'abstractiter', 'iter') obj } ################################################### ### code chunk number 11: runiter3 ################################################### it <- ivector(1:25, chunks=3) as.list(it) ################################################### ### code chunk number 12: generichasnext ################################################### hasNext <- function(obj, ...) { UseMethod('hasNext') } ################################################### ### code chunk number 13: hasnextmethod ################################################### hasNext.ihasNext <- function(obj, ...) { obj$hasNext() } ################################################### ### code chunk number 14: ihasnext ################################################### ihasNext <- function(it) { if (!is.null(it$hasNext)) return(it) cache <- NULL has_next <- NA nextEl <- function() { if (!hasNx()) stop('StopIteration', call.=FALSE) has_next <<- NA cache } hasNx <- function() { if (!is.na(has_next)) return(has_next) tryCatch({ cache <<- nextElem(it) has_next <<- TRUE }, error=function(e) { if (identical(conditionMessage(e), 'StopIteration')) { has_next <<- FALSE } else { stop(e) } }) has_next } obj <- list(nextElem=nextEl, hasNext=hasNx) class(obj) <- c('ihasNext', 'abstractiter', 'iter') obj } ################################################### ### code chunk number 15: hasnextexample ################################################### it <- ihasNext(icount(3)) while (hasNext(it)) { print(nextElem(it)) } ################################################### ### code chunk number 16: recyle ################################################### irecycle <- function(it) { values <- as.list(iter(it)) i <- length(values) nextEl <- function() { i <<- i + 1 if (i > length(values)) i <<- 1 values[[i]] } obj <- list(nextElem=nextEl) class(obj) <- c('irecycle', 'abstractiter', 'iter') obj } ################################################### ### code chunk number 17: recyleexample ################################################### it <- irecycle(icount(3)) unlist(as.list(it, n=9)) ################################################### ### code chunk number 18: ilimit ################################################### ilimit <- function(it, times) { it <- iter(it) nextEl <- function() { if (times > 0) times <<- times - 1 else stop('StopIteration') nextElem(it) } obj <- list(nextElem=nextEl) class(obj) <- c('ilimit', 'abstractiter', 'iter') obj } ################################################### ### code chunk number 19: irep2 ################################################### irep2 <- function(x, times) ilimit(iforever(x), times) ################################################### ### code chunk number 20: testirep2 ################################################### it <- ihasNext(irep2('foo', 3)) while (hasNext(it)) { print(nextElem(it)) } ################################################### ### code chunk number 21: testirecycle ################################################### iterable <- 1:3 n <- 3 it <- ilimit(irecycle(iterable), n * length(iterable)) unlist(as.list(it)) ################################################### ### code chunk number 22: rep ################################################### rep(iterable, n) iterators/inst/doc/writing.pdf0000644000176200001440000056336213516640512016210 0ustar liggesusers%PDF-1.5 % 1 0 obj << /S /GoTo /D (section.1) >> endobj 4 0 obj (Introduction) endobj 5 0 obj << /S /GoTo /D (section.2) >> endobj 8 0 obj (What methods are needed for an iterator?) endobj 9 0 obj << /S /GoTo /D (section.3) >> endobj 12 0 obj (A simple iterator) endobj 13 0 obj << /S /GoTo /D (section.4) >> endobj 16 0 obj (A stateful iterator) endobj 17 0 obj << /S /GoTo /D (section.5) >> endobj 20 0 obj (Using an iterator inside an iterator) endobj 21 0 obj << /S /GoTo /D (section.6) >> endobj 24 0 obj (Adding a hasNext method to an iterator) endobj 25 0 obj << /S /GoTo /D (section.7) >> endobj 28 0 obj (A recycling iterator) endobj 29 0 obj << /S /GoTo /D (section.8) >> endobj 32 0 obj (Limiting infinite iterators) endobj 33 0 obj << /S /GoTo /D (section.9) >> endobj 36 0 obj (Conclusion) endobj 37 0 obj << /S /GoTo /D [38 0 R /Fit] >> endobj 41 0 obj << /Length 2829 /Filter /FlateDecode >> stream xڝ˒۸>_e& $q*ޒTjw3-c} e}n4&_<-w7\(s}Y-m6oouvݲȎ{Zl^d <O_޼+Euc5m+Wߴ|ʯ~ed=lWz8:6[rV_=*+=.mhi\@]Q9DeU)&Gpb*9ǥN 5 1ui7k!@U -<ܮa2~*:3>gq_q<v~IE\U6Ecw g^B|8NGٰ\#L{ P>#@W *,63l,jП@X P.ۨx%k%T/'tv;Rj@,W{J|#MTIVS63=ՠugz 9?,Y3SįgT6_8ǞIQ8!EF{CEX%Dt}0"thx4 #C.ҖnemO_)CBh`Rh#t %`}4Gw]HB%#]>3b|0o]FP w!#[HZ к;r#$5w\&W9vg9LPۓJ\x]|[gkb[Wd }?1,cw8~+ÉPݲO abSe4y[6eƜ '\KYtSA@8u eYGt<(fA"JD{$ ]ڲtyfOGn:&_Oy||HMg><!B~t`(Qmyg4= Q>?EX ̕S|S?.y`F`7SdAI )vzd׈ /PG&~JAJ6R2F@MvMrD`LBAF;NxQc=ȋ=9}Z&|`9 N)% Sf96O r]pn^+11S ykOtL5Nly0_G/xlvӏ51d+nn#2$JJ:"{*& O/jc@k=w.Nŵ>8ɶbI+ELe ywbmxm?QhP}u(;4i]PFrl 0u$()+/-XwoY3&D/ʫ5\d`pB(2hmb2 ߈p&ap%fO*v:HxYXQ!gDt[.OFRjne[V|6~<[(,45BB!w睂+njTJ!ujmz%,}mI'wy +5m^\V@5\obPV]OV/|3)ʫiL6vi6іRTS 5KQ4? .;[[^y}.Ÿ/r ZMk%Q31}L|bQUnԵkMٔD ۴!Kvo\cNok4.ya")HZRq9DvUt?e(T7\_!drƯ7Qk}^xS x$$U7!s=V-irzlWl`ݮކ7}]wyHV aҌ:&|zHq yۢ2p#m1l^FJ=Arj74-~.@[Zs̆X{ U}O.sXcB uΞM]ߊ_c5:@D pLr"Aqy3|=ZS灳C蔺c,LxTWk5Y:LJc#M(&!5$ԫHwy\kSħ8VA4Syr`LӔa1C2PY%g; ,`O?L& ;Ϣ-L^?%mQ\F6.  4&~;!H1F)mzjW9M(};KK׎Iaf>V4mQn|[ַ?9Ⱥ8)4㉥re&LK@~1TZ.c9,mq]eHl1}d3X\zZ, :*VxRfʪ<>I`ko]Jz*YEV"n%5ST$$89( '*\y0 R NNxRBt,4RW]__wv]E7mo 3ضYaQ慩G^x=\ Wkة-J߼k-8#a|Cx) E%2ChԗQfE =``] endstream endobj 38 0 obj << /Type /Page /Contents 41 0 R /Resources 40 0 R /MediaBox [0 0 612 792] /Parent 53 0 R /Annots [ 39 0 R ] >> endobj 39 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [461.158 462.574 467.881 476.293] /A << /S /GoTo /D (Hfootnote.1) >> >> endobj 42 0 obj << /D [38 0 R /XYZ 53 735.4 null] >> endobj 43 0 obj << /D [38 0 R /XYZ 54 697.538 null] >> endobj 2 0 obj << /D [38 0 R /XYZ 54 525.694 null] >> endobj 51 0 obj << /D [38 0 R /XYZ 71.933 109.787 null] >> endobj 40 0 obj << /Font << /F45 44 0 R /F20 45 0 R /F52 46 0 R /F59 47 0 R /F28 48 0 R /F63 49 0 R /F7 50 0 R /F8 52 0 R >> /ProcSet [ /PDF /Text ] >> endobj 56 0 obj << /Length 2864 /Filter /FlateDecode >> stream xڥZYoG~ׯ) L_bp&,~X$Y~c<ȞꪯYϾ?/__|A3]fUk[鶝]>l|w7f|8?W-dvG>_r gμ ulB/ =Ӭ}E=lִra_v~}{ Yibg6PK}u<ؒ:3(b# ?\;5H/Y1j!N;_PQ +e+kf~KHH_J+?hY_)ūR#*;$=w.v"9ݒb 4◺bBrv`zVSY'BX/Ŧ}эT 6Q8oᮏes{sywdfiϢmqǍlK!gjಶ ^#bH#" |sl*P&tI;Ͷ|彍s)cL:M IЭp2.Zh[̳'Str2|y$"ӉB2p tv{,sc[U5/wcV_X6Qvp+:d]:' Flp h4XßCQd!1}9y1F 7jcbbWÀ F.h8l9^**㫍+G} S̃1Ce~iWΡ)lFçO$SRUT| />)dRPp; rJ^^kb8(&ﵻaަėna21Ðm v/4z9?* &ZU>' {W SK ͐^.6&0>҄CF!Uř6'+Y@щrC򌧘[G4(5e/ܘJwhsϛ貔l6^8_vO)Lq ɃsO? W+kRE kou|Tr :[ ir3)~QPBV717mV*AbBy *6fMƸ@SF}4~di@*[[(:onxJ4Og,a XOx 4 T%|($Xz<|G$|Y2M8_I>n\7KZjs* ~NUpl!D0I"v&¦e!_\-&.LVseżfژV,JN)!ax.K.LmF1l~,MN % CF|qTʕJ^y& 9{5uL⤑ rK]dxanӓbq9ߚ3g=JilĪI}Džj)aN =hдkrtqjBacmt{b#R e6Է-F>r_mN \eӺr͟(rsޱ,?xǂU/te-&ɘS%aVV0*M]L1`=P\-^+GAk*GEe}:H3t /:."`4,taul/I\o&&]Ty ^'xPiZﵐ9VXAV&oRu5VWAf'ٯpa\Wfhhkd|7 8KRžP6풣Lҏ쉧j/xseʬ`˄M8-#]KG7Fv@S5xp <ҬBc2!{,w!A NbO,riL9_o^obuon}rd2Rx3ԌAŸ)['wa *?'WvT:7?>g%Dt Ae*thzP(zXUvokś+Zຘ?m Z$(n _1ykv=hq[P΂-4D%D}_7@Y05ҏ~Wܟa#_?} endstream endobj 55 0 obj << /Type /Page /Contents 56 0 R /Resources 54 0 R /MediaBox [0 0 612 792] /Parent 53 0 R >> endobj 57 0 obj << /D [55 0 R /XYZ 71 735.4 null] >> endobj 6 0 obj << /D [55 0 R /XYZ 54 653.145 null] >> endobj 54 0 obj << /Font << /F20 45 0 R /F52 46 0 R /F63 49 0 R /F59 47 0 R /F70 58 0 R >> /ProcSet [ /PDF /Text ] >> endobj 61 0 obj << /Length 1609 /Filter /FlateDecode >> stream xXIoFWP4MfC )!́X$(&yɇD'?N~<~eub&׉uZ':e2'_KޝtVk>O3[/vn+ \ZvwoB$w7ryVwu2׉VUU${ZJrLN~EWeteYwӼ?&K3|ԡ_:f3,R ~չ[4p}p-el- OG̣xkvB|3|+cB #1" *e76rE9neQ3q |i-vRz/adY0^PِW4͢^Qފ,D4a%}VAL@(-Kn(%R<ݴ+MF֧O8oXt)Yv|MlJMٙФE:Iy^2,fZb:q`tqaAAy6U\e&F:DXVo%)E&D%/H!ژ}ie01Bdle);Evr Q7sG\1".Dxȸ ;e>'_ %J]`w$42<Ӽ'V^BzXĪa"us7Ұ/@5r6q`d#m{H!zZr?C,A+ s $0J pG=.|xŽ(tZ2bǢ#1`+"`j. yXJ D7V)#Sa3á&YB +vyQ:^϶.sZ0^e5ܾ[<*>|tP~!6-VR' 7 e_ ba5U@8 ̨s*|tg 阥'O7#B|$CT W(D/uYh0Icl $]Xy֝mԠX䪼D \6ף(zV:UP5u0]֯sG>erp;e&G;$@8s~lovO]φ]報hjˣxPi˚)|-JeaniBD'SHIKN+qwWGct]QWX!> VZxL)az; B Q by^i)5n 4 ްu90mCrpgZ5[AG"S]1hA³+q~q% SoW _S'mHXć,xi`uv ^ gCFi=TK>l7PEfbξȟJx(lN` m?Yf endstream endobj 60 0 obj << /Type /Page /Contents 61 0 R /Resources 59 0 R /MediaBox [0 0 612 792] /Parent 53 0 R >> endobj 62 0 obj << /D [60 0 R /XYZ 53 735.4 null] >> endobj 10 0 obj << /D [60 0 R /XYZ 54 531.211 null] >> endobj 59 0 obj << /Font << /F20 45 0 R /F63 49 0 R /F70 58 0 R /F52 46 0 R >> /ProcSet [ /PDF /Text ] >> endobj 66 0 obj << /Length 2224 /Filter /FlateDecode >> stream xYK#WtNA,G`>H2@l\zB@e+nCY@OE)ڶ*p֮o2=@=9lV5Z"޿ZY['=Дoyg$g}߿K[7jJZw2`k%0"ZI[Ӫ/q}ҍ4дSnG|Bg< oI s ykOvd#v7<}TRYZ)<dzq33)j^K^x YWK<~)TiW3,ju-l +ZOhM̓(;/Qza;lޖ7njBHEq[7Z/oO=DhuG9Ah:g˒hs]j "@eIk7x@<G'g,OWF;"N*Pp‰GO6=o{:1l=2 `00`0zld%ARu|UTНg+y@/GFD8)6k@[<:Wd 8tOqYшQJV”zmh⨮(ԎIǑ)2ckr ?NNȪm%B2أ;vd HZnv6(˹I@Mʑ2%XG~=B%vʷq@L67vP)i ]GY86הmT OC(ɵc |TRT9恰1N 4awy^ɲt"cָ/kO8qt߬MJ $)@tΦm SM "ȭ !z$T ҄EKC܂t7/{j28 4K#g(NE{2Q~Ô*h$Gcf GO1Yg084w?HQᦅǰWš*z++v/X"AdD9Uу/?l dc{-cklg;ݛ89/N~L!ٺ&+qoѪ`1qi #\v3c51@SбtsrUЕF%@]!,)IJj>/{1&%lݘI+ t7$uc$pxLrj>8g:L 9 1a%0\YαZiY$s{jX,g jm&"lJ \; @ {fzFDt \` v+SrOjM١C!K{ŒdG`xrYɷЅyJ}G7|H=)y<_|2ƒ~^ҳ* SP!#+h)N͖[n#- OÝu)j(K0 M #nI>ʯLrи%Y(0΄ɌAZHHZ&iѱ&x>Ӏ]3st]! k$rܢVOMseޝ~rW?oVm$|,"ocnF2*vyH?bT)Ea= H7xY SEۈJ6~CSTILH!h>wDS8!B ?*_55w0aާ69ҍp ˊY%̯ "Е1Gi"E|zUN_?| . \>w9cŷ眏}*η*{%p^=V` گ8Ft10.y^\~CQAu/3MU%5iX1"nb5I=}ɩdj@x> endobj 63 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [419.276 127.453 425.999 141.172] /A << /S /GoTo /D (Hfootnote.2) >> >> endobj 67 0 obj << /D [65 0 R /XYZ 71 735.4 null] >> endobj 69 0 obj << /D [65 0 R /XYZ 71.933 106.958 null] >> endobj 64 0 obj << /Font << /F20 45 0 R /F70 58 0 R /F72 68 0 R /F63 49 0 R /F28 48 0 R /F7 50 0 R /F8 52 0 R /F75 70 0 R /F77 71 0 R >> /ProcSet [ /PDF /Text ] >> endobj 75 0 obj << /Length 2172 /Filter /FlateDecode >> stream xڭYݏbїP^~/$@SI6Z:V;CNKg3 /D]qΜ֢_UBլB14Cryg9@;{/0ymqPU-7 Ҫ1M޼|]W0CU3LSm+]+T?󦾼`fj'(-jZq9{?+8P/j@1" JG 6_(f"eKBa.lG/Kҭq]{d{!}}0GNn%2m 5o7`N ,g&pi|GSzh\E!ۨuM7ȸZ(0aU)ee|~hu.#{|{ ׇ@f]Nd=$U{zΝ- U -=] mJT;W+Iwf~ uol;<]pVBcu1b (f>_D'= @H"|$ q3$pFMD1J"ۦD23lZ)?C ݑN@Oƥ<4dyGg^)DKDU4FLc T 'NJG{s>Qcڬٹ^2E+1]BtH_y&^) :p Ï ?{계Cpg"|nmms4؊rc+.դj(&)3mOkD *4ewRM(JZ>ChpCLimy\@;d%هiϵt;k uE&}i8l⿲Xh+lL[dy8sTVD"wy+ .5U{qm34pIμH`hTNN2YT;*7BD6 )>LU‘2 0Ӥ(!4,y*ViM6<o=5QK@ArЦsnw4c#ۖSLWؽHj})c2O_wdR?/y\ 0^˧~{K-2>û] endstream endobj 74 0 obj << /Type /Page /Contents 75 0 R /Resources 73 0 R /MediaBox [0 0 612 792] /Parent 53 0 R /Annots [ 72 0 R ] >> endobj 72 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [378.384 112.58 385.106 126.299] /A << /S /GoTo /D (Hfootnote.3) >> >> endobj 76 0 obj << /D [74 0 R /XYZ 53 735.4 null] >> endobj 14 0 obj << /D [74 0 R /XYZ 54 583.637 null] >> endobj 77 0 obj << /D [74 0 R /XYZ 71.933 106.958 null] >> endobj 73 0 obj << /Font << /F20 45 0 R /F63 49 0 R /F52 46 0 R /F70 58 0 R /F72 68 0 R /F28 48 0 R /F7 50 0 R /F8 52 0 R /F11 78 0 R /F14 79 0 R /F77 71 0 R >> /ProcSet [ /PDF /Text ] >> endobj 82 0 obj << /Length 2398 /Filter /FlateDecode >> stream xڥY[~_!eed͐KHHH2EQזgf-;Is)Y'Ì%^Ν]oNQs6]'6תeR\٪JnWɛ߳ʤI7w7gH~Z.6kw;Zono>`O\V+͛w:YVu]$GZ86}^ VTҵe޻%4`ڤj6k*6˙-{?= S^~QCyAȮ=K5~|)4@~. 9Dߺz)K[n9ū8dXYLWg4eXO^m`ϿΜAdָ~2ab'gF+kdnr'"5r`nݟ$*ɝڲBx4@ꞃY=3m+wjf,-?'z`4鑋)BYS yƣO7 s, Ab"'5$HwYY[?R2wS@4Hi'O@2y;y;,Ӕq@0҅a5 ab/Lo+fe-4]yX? !u oE0FGISNպx`RyCjYOb2fwnLW8̳ڪʆN'9Uɝ7-ZHlhȒ/ Pz]aCï6m 3 ; R[Q[< hav[ eΪ,KL3p{`l*d]TzQ\< 9}d9-M- 99;Yz띹Wp|҈a#C.CG &\{Fza ڥRReXwڹ}+2JE:{bR#Hg?VRʗ] #@2z9ra )lDm @%j[=rPdTY&#q6K@aB8ˤatZAN 8sSId*vh* 8#6FipTS@6 '` mA$\k"PW Xh\˦x<εZOIRR ŮarSH{ Ƃmփiq\hΣT 9)e҂ְ6Y܄8F &k}А>o"q֢b_i'а'ſUK[Nē[GALa<E d/_p+Orʵ+{.z%q9?=:j[$PPf wʈ>B@稇r)D6ٶ7j#ƉOr25aџɟu1OscyI y=*x3 ]R=ַ۳]-5|ua_vglOKYWж^MBgnb:LP3U׉d*gDdtszojKpֱ :< tqɟ;L&X;>mCL]o\"M܆ b^[eᗥDBƞAn3;))N__qm jrՏ?CH1`/?Y+qS endstream endobj 81 0 obj << /Type /Page /Contents 82 0 R /Resources 80 0 R /MediaBox [0 0 612 792] /Parent 53 0 R >> endobj 83 0 obj << /D [81 0 R /XYZ 71 735.4 null] >> endobj 18 0 obj << /D [81 0 R /XYZ 54 554.125 null] >> endobj 80 0 obj << /Font << /F20 45 0 R /F59 47 0 R /F63 49 0 R /F52 46 0 R /F70 58 0 R /F72 68 0 R >> /ProcSet [ /PDF /Text ] >> endobj 86 0 obj << /Length 1976 /Filter /FlateDecode >> stream xYKo6WP 2eD-IMQE6fJa'(;/Z8Y98MVd?=8{֪qdBgXe:Xdkoug/kxޜJS?gD?ljjeUi/Ξ^?ӠϜͼnuU6ߜ,_dj*YٯgEj̪TEcXgΔ9~"Մgҧ5¡xa2$`sќ+IT<)Cfem/8QB@N&`g: I_H"K …|'z#Dnt}*`rs:=gZ4CM#3[0Fmq|:ouU.lP;i`i>gM~q5%ex:]embIJlvBK;^\6gG0ls̬Ag?I3B%.(L2k" /QCItügN.beO8 iŒ=?p No5<0hUz@dAܼ`u(-V IMu4HE)Ρq5EQ$dAϐZ5V L+e,%B+Acg[݁yv1#0Xe8ޜ8.%RP7b_2GX<5ljC&Y ]-ɟdc  2G۸jCQ1*@drn Q[eRPjSC̽$T.DZZ?^`\cynq֥2̀2dˎ\MjU6>,"7͠a{y+ j|8 :3]CiCc8+KeEBjn&o=|A.6o\ѩpGԿk虜oc21@6׌y!_pL%gZFF'+ihr*Y\Swir8d4=q1x)<^rV"ە endstream endobj 85 0 obj << /Type /Page /Contents 86 0 R /Resources 84 0 R /MediaBox [0 0 612 792] /Parent 88 0 R >> endobj 87 0 obj << /D [85 0 R /XYZ 53 735.4 null] >> endobj 22 0 obj << /D [85 0 R /XYZ 54 386.537 null] >> endobj 84 0 obj << /Font << /F20 45 0 R /F70 58 0 R /F63 49 0 R /F52 46 0 R /F72 68 0 R >> /ProcSet [ /PDF /Text ] >> endobj 92 0 obj << /Length 1840 /Filter /FlateDecode >> stream xڭYYoF~ׯ`Pkͽɢ.q EP$AHDwwv\R$%~cvof$9K"JI&%..#&2i&KbS468S[sϖgno%,W-W@ˀ%HHӌ|CMQBLE@5d",z3stR"'IƜOF!wCVNqp'V81:eVsC4$5<պ`jׯrs|ݸeu}$'RSʊ8I*'~n C`Z8swo^4>Sw,2"§6W.0hXh" + iaw_Z:K{E)R B('b 25>" wn5 n_<bnMA[WӕmUDWlZɗiς u7ώ1ȃ$C+Cd{Z$a'@_&&11]HDdYF-m ?:ӝ.LW\q,m{>IK&Z4MF\DT/G O$I8ld |߶4 O-y?%~; v[$AwNNj/o41Qwo,DNA\KŞ QE`"pzFSDC $ ҋrkps={m٧0h^|Ħ wJ^WҡjƷSC-3i*spˉ#> h$ÑJaMZ)Ox'%d:Lakkge=KK+ HA B,z8m`zjַ4REJy@`ps,ͬo j\NEsh]Kj0*70RU&tJ[C|ѓPʄMv*H?z}Q endstream endobj 91 0 obj << /Type /Page /Contents 92 0 R /Resources 90 0 R /MediaBox [0 0 612 792] /Parent 88 0 R /Annots [ 89 0 R ] >> endobj 89 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [365.987 614.793 372.71 628.512] /A << /S /GoTo /D (Hfootnote.4) >> >> endobj 93 0 obj << /D [91 0 R /XYZ 71 735.4 null] >> endobj 94 0 obj << /D [91 0 R /XYZ 71.933 106.958 null] >> endobj 90 0 obj << /Font << /F20 45 0 R /F63 49 0 R /F28 48 0 R /F70 58 0 R /F72 68 0 R /F7 50 0 R /F8 52 0 R /F75 70 0 R >> /ProcSet [ /PDF /Text ] >> endobj 98 0 obj << /Length 1797 /Filter /FlateDecode >> stream xڥXKs6WiZ!HDLI2ɡ6A(ۍ([t߻/ MIN{E~@\%ivbI$*Kɕ)b\z wWifw\Éɪ펦}x?z}1{(Ol8Und]~L|"9Ьub~Wɇo (3zguRqՐQUWIߵ oR& *c5 47I{F*Lg?^4A??Sds+; Y}A_ jz>5eX69\E%<7*y2չA7ɘo  .3^(RkV<#dfhsfe8Z8Ր[M+ :bcIjY.lw=Z <˜¾yM*mLڠZhƟا˰=+Z:M)A K)m9r|XqmѪ}P-~oCx >'^߈<'CylphTf-)9T z$qRBWф5>.Gu;o#CHUkJHm]8ѧcHrwwvPUh Cxh-x9fYHqlvrx<͕$/&SkAGx_ک狸Ԧp.pƏ:WҮ;!*D,rdSG"d Enzz)a0_gAYsnBAvh1 5w mK,g0+r'S[t`g= /C|2yMQnB?l˶-,CC~`˝Cn,GD9\`] Ilz{!*%Cief?qgY fNb?#PBnbdSPm-%H-]+-,Am++ .o nhc\x^wJMOkD=bJ?H2)ٸ|&v1B96,7݃˂G9# P7k^HLbI1NZK֐ЍmrORyQtش&ۆfYIDzOT+9ZHelΥL '-%2`VVVa4+ϊGu'lNĊueFy+s݋sJOw*pĨonUsR,?ڇ BŢa]Kl_v"F$_V էl;&RG;F 'k0rĜs6tBu9;sΙXe#ҳ!N_0&Pk̀|,||x$'xEf@J^9?YPԖOd0eԿ|{Y~H46zS0Фꐮ .+ .LEuo+_:X|9{˫5vt2߸k+ \]]F5]P0 uSP-+c- {>PZHd2xuIH|1~uS>=r)ù8RHa" 70L-I ]3~0[W 'uYnή'y+3LKIgtnxҬi.?;n:l iԻ;s8sftG.}/} endstream endobj 97 0 obj << /Type /Page /Contents 98 0 R /Resources 96 0 R /MediaBox [0 0 612 792] /Parent 88 0 R /Annots [ 95 0 R ] >> endobj 95 0 obj << /Type /Annot /Subtype /Link /Border[0 0 0]/H/I/C[1 0 0] /Rect [162.416 349.451 169.139 363.17] /A << /S /GoTo /D (Hfootnote.5) >> >> endobj 99 0 obj << /D [97 0 R /XYZ 53 735.4 null] >> endobj 26 0 obj << /D [97 0 R /XYZ 54 457.699 null] >> endobj 100 0 obj << /D [97 0 R /XYZ 71.933 122.207 null] >> endobj 96 0 obj << /Font << /F20 45 0 R /F63 49 0 R /F70 58 0 R /F52 46 0 R /F28 48 0 R /F72 68 0 R /F7 50 0 R /F8 52 0 R /F75 70 0 R >> /ProcSet [ /PDF /Text ] >> endobj 103 0 obj << /Length 1926 /Filter /FlateDecode >> stream xڭYKoFW 6%)i (P@IDn,#Qwfg\R+N{7̮*J_'?]L^bHkUYkedD )S"1-u~;~w5&Cym-|JԿUUytz"dO~$K#UIeHkx %/.knBn@k7gXQƗwjt-kPӔx|ڟ ,nؾbuêmO?&:/S0SSNfA n _Ng`thgl{,-Qmtf*abB]yjJ'H{BطǂAB_5`7ﺟ# w<E$^> 2S@RXzа!yJ\1@>`Mg#[)4UUacH Hmmw4`L.2al9O/Yаf@5b5#5*qꮩx*hѬB8 &3<p밸(wv' G(^L$;LKYQ% k9|%]w-o֒9}ZK5\gc;*.Qضoj~[C0NPP$CەEw eF%-4^g,NKK}wҰB([lN0ؑr5%V[F\};^GUyk;ső ͔.9Τ2 ⬯00s$ED0=m7T Ј^jRǻ^> qEq$?,:5Wz2ʴtPFCEdJlAә&9N87]`sꕪ;=mɩ)v #w Ϊ5k%o-S4kq0"Ep7j>7TeœxbYǚUGʒ$uL)cCmUAUw.sfR%I9C89NY־)Xq4{zEf#P`ĖOr)̫SoAPsxdq 1c1VvѽJpj_vwAިn^MAz:$ӻTZ=6Ȏum+oa# endstream endobj 102 0 obj << /Type /Page /Contents 103 0 R /Resources 101 0 R /MediaBox [0 0 612 792] /Parent 88 0 R >> endobj 104 0 obj << /D [102 0 R /XYZ 71 735.4 null] >> endobj 30 0 obj << /D [102 0 R /XYZ 54 501.923 null] >> endobj 101 0 obj << /Font << /F20 45 0 R /F63 49 0 R /F70 58 0 R /F52 46 0 R /F72 68 0 R >> /ProcSet [ /PDF /Text ] >> endobj 107 0 obj << /Length 1459 /Filter /FlateDecode >> stream xXKoFWXl-WQh)[$:"e(;;3Kr)ʖO=H$oy}dQ|/* y` D UF, 70](+5|6iLἶ*xXڧ ~ᴫɇD X/t{6şf3 w:9AI|mr־N)'ri%_ISu7x ~r5PUQk*TE)D5DD8M=gƲ͏߿u~Fkí9hKq5]WBIB|ЪhϡK>"pƵwͩ~ߐQ bz W~ Ý{ Pmk)٣Lx-ɱk#=6wi|bqêȽ()ԑѩO#i `ꁖ[H\wi4ꂽj/ͪei #{Zq[\}kv8Hu;F63X)Awҽ7.ns* u6}s8Y tOvYe} endstream endobj 106 0 obj << /Type /Page /Contents 107 0 R /Resources 105 0 R /MediaBox [0 0 612 792] /Parent 88 0 R >> endobj 108 0 obj << /D [106 0 R /XYZ 53 735.4 null] >> endobj 34 0 obj << /D [106 0 R /XYZ 54 205.738 null] >> endobj 105 0 obj << /Font << /F20 45 0 R /F70 58 0 R /F63 49 0 R /F72 68 0 R /F52 46 0 R >> /ProcSet [ /PDF /Text ] >> endobj 109 0 obj [777.8] endobj 110 0 obj [777.8] endobj 111 0 obj [460 306.7 460 511.1 306.7 306.7 460 255.6 817.8 562.2 511.1 511.1 460 421.7 408.9 332.2 536.7 460] endobj 112 0 obj [525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525] endobj 113 0 obj << /Length 123 /Filter /FlateDecode >> stream x3532Q0P0P06R01P03RH1*24(äs< =\ %E\N @QhX.OfAcՓ+ ^) endstream endobj 68 0 obj << /Type /Font /Subtype /Type3 /Name /F72 /FontMatrix [0.01004 0 0 0.01004 0 0] /FontBBox [ 28 32 40 62 ] /Resources << /ProcSet [ /PDF /ImageB ] >> /FirstChar 39 /LastChar 39 /Widths 114 0 R /Encoding 115 0 R /CharProcs 116 0 R >> endobj 114 0 obj [51.24 ] endobj 115 0 obj << /Type /Encoding /Differences [39/a39] >> endobj 116 0 obj << /a39 113 0 R >> endobj 117 0 obj [525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525] endobj 118 0 obj [555.6 555.6 833.3 833.3 277.8 305.6 500 500 500 500 500 750 444.4 500 722.2 777.8 500 902.8 1013.9 777.8 277.8 277.8 500 833.3 500 833.3 777.8 277.8 388.9 388.9 500 777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 277.8 777.8 472.2 472.2 777.8 750 708.3 722.2 763.9 680.6 652.8 784.7 750 361.1 513.9 777.8 625 916.7 750 777.8 680.6 777.8 736.1 555.6 722.2 750 750 1027.8 750 750 611.1 277.8 500 277.8 500 277.8 277.8 500 555.6 444.4 555.6 444.4 305.6 500 555.6 277.8 305.6 527.8 277.8 833.3 555.6 500 555.6 527.8 391.7 394.4 388.9 555.6 527.8 722.2 527.8 527.8] endobj 119 0 obj [569.5 569.5 569.5 569.5 569.5] endobj 120 0 obj [514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6] endobj 121 0 obj [531.3 531.3 531.3 531.3 531.3] endobj 122 0 obj [500 450 450 500 450 300 450 500 300 300 450 250 800 550 500 500 450 412.5 400 325 525] endobj 123 0 obj [625 625 937.5 937.5 312.5 343.7 562.5 562.5 562.5 562.5 562.5 849.5 500 574.1 812.5 875 562.5 1018.5 1143.5 875 312.5 342.6 581 937.5 562.5 937.5 875 312.5 437.5 437.5 562.5 875 312.5 375 312.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 312.5 312.5 342.6 875 531.3 531.3 875 849.5 799.8 812.5 862.3 738.4 707.2 884.3 879.6 419 581 880.8 675.9 1067.1 879.6 844.9 768.5 844.9 839.1 625 782.4 864.6 849.5 1162 849.5 849.5 687.5 312.5 581 312.5 562.5 312.5 312.5 546.9 625 500 625 513.3 343.7 562.5 625 312.5 343.7 593.8 312.5 937.5 625 562.5 625 593.8 459.5 443.8 437.5 625 593.8 812.5 593.8 593.8] endobj 124 0 obj [571.2 544 544 816 816 272 299.2 489.6 489.6 489.6 489.6 489.6 734 435.2 489.6 707.2 761.6 489.6 883.8 992.6 761.6 272 272 489.6 816 489.6 816 761.6 272 380.8 380.8 489.6 761.6 272 326.4 272 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 272 272 272 761.6 462.4 462.4 761.6 734 693.4 707.2 747.8 666.2 639 768.3 734 353.2 503 761.2 611.8 897.2 734 761.6 666.2 761.6 720.6 544 707.2 734 734 1006 734 734 598.4 272 489.6 272 489.6 272 272 489.6 544 435.2 544 435.2 299.2 489.6 544 272 299.2 516.8 272 816 544 489.6 544 516.8 380.8 386.2 380.8 544 516.8 707.2 516.8 516.8 435.2] endobj 125 0 obj [667.6 706.6 628.2 602.1 726.3 693.3 327.6 471.5 719.4 576 850 693.3 719.8 628.2 719.8 680.5 510.9 667.6 693.3 693.3 954.5 693.3 693.3 563.1 249.6 458.6 249.6 458.6 249.6 249.6 458.6 510.9 406.4 510.9 406.4 275.8 458.6 510.9 249.6 275.8 484.7 249.6 772.1 510.9 458.6 510.9 484.7 354.1 359.4 354.1 510.9] endobj 126 0 obj << /Length1 1918 /Length2 12017 /Length3 0 /Length 13197 /Filter /FlateDecode >> stream xڍT-wиCp 4 4w=-;w'Gf̽굺{WSNա"SQg35IڀؘYlVVfVVvD** ?vD*M  & mmrNV67??++?D[~$ 9"RIڹ9X__1p5hPA֯' 4YX\\\֎̶ft 9@ rp~K(AIcFh[8P5@W15x=.PIV96f;@cc[k; PV`@Dk<ha4z%Q: - *KؑFi^,ec"akm ;"Odw7.? ';6N Yɿ8&lf 0\Y~f`*ea zAp:`'ǿ&`f,\`넙XCYTuS\`bbqxX^GV_ձQG_A%yh=V.V/%#ogV$deOr:NP}j\hq[+ɂ"fcfw--\A&*`c??bh0u-_׻z]>Rsq@7Dcx. 0؂_Co "'Hx8, n߈5?5No >FA6 o*C`#:9+b/ `1|a/ `|-Z?Gy_ 9_mZ?~u 8x979U+'ു4uXU_*?M ;:< +qqX Su`m Θ4ՎV ǢC=*\"]EõX`7QS-\Hsj˃aN nxXwb& ]'{OM?K&9l{'^T\[^ך?FvTw+K"GPeÂH1\]Ocf2 zGrx謳Gͺ|`w$$'OÛ(. /4%1knCsVu, o ImMGnRXgcfM=!:=ẇpY mO^ =ES#nC{DXcx8fN%@_9拥0$QI$5wԗ/G"KwP;N &ɨOr]6o(s+uga|U (BsiC.nTHj'K>#TyNʖN3pV^6n3AYPwA{ o Uo7|xI2YL؆ 3!췭1iwclU%Ǘ߅uNGVEƣFy7Ut c`)A*işb ̥: ibnShLsW9KaZȢ"kKVJ*ko@[oNz[[hE83BIn:QAKwM0TQ~{#v?b۲WdO8>M@{jܑLy]& )=n/)D#X]O,K:$*ts vچ$h5JAlU6_*bX .F>8,t opn)Iu9=zXPZ0u sF=]"x9 V'7$mԥ;?&\8k(W S(AZPR7Lrm HF$cy!y:&?KCbã{]NJrW 3d| ̅/m#/3 ;!~1Y#JNusx ;{@HOчy:'1\~c#Yns}˛">XKO2;Q!k9| -$u& oҺ:Y]G@avUP>=Ϡr또Ϩ“ ׯ$ dwǢ/'I <_ۧOoZηWxݔ1v3Ks,&S&`#9|ӒV{2%Z֧^B 5P}G؏c$k1-Tlt0)2x IZt 0^K+^`@\mӔMP:gBdf[p/٨*A(4 %j"bK:\I[L$d)E{~!DU U^s7B- 6z;SX7UfG[)\*Ծ`9dE;!5EhXZ 7ӬW;F^gJxpBtb5;ht/1Vp ǽՐ6b%^F?_|]MPcIu??U/NHv8qDt/tP)0A}G7( _*Ѐ$أI[ʉ0ʞfJo|,}S!(2J\{צp^I[6pN%dqxqB8k7@>y]x Z6}L(\mY I7c6ٕflOTUjN[܍˫|WMɗY8z+xrYx 2Q$ˉBptwbIUfi!{R\ 4 yV|ԹW@tL# YfsV:No~g/ ""{xEÍ@rU#xC r% /U般arZd":qJ%ܧ䟴aZ*j3gɎM ߋƎA!3p`vn$ x] }ޢzxBLt* 7md_YS+h5Ky N7*RHx%n%h9d _~KMZS$$ڢ&q`3-:jb(|ak h]y{V- nVwʳ8wٛrx2I{> FrZN׃݅NF-!ٛE&=wdVX}_li 3mhYn?*t$rz/tq +N|a<_oDs撎T!}jS)K~O\b\M$Mp33Hj/[S?~Jcy4Q e$kՔS`e^(2"|j>Ha0qoV*q|Ƒs,'ϰ1Kz5^> #\fYkrṉ\ `5:WkGGH,'_7MbD8҆ƖWJ3ᷤ6sqfmSRpMz=[;8_\FQel޴+4f!T^sMxJ*3^r9 lyʚj0Uɳm8Pf0aLA=6da0:x6:v8iFkD.i18l~;lcBj{ڔ9%]8Š'/ q$u1}o4&'upUXaaTpi6{ V6 ^`B̡J %Tl0sΰlf"{5<~cqȞ/.>n*sa/7EBswkv~Qy\27"24m"mY0}R2EF*V!x[ [ ⼗Ly0~"|qxJ"r8ag{4bז*";,F[Tj~6doryHМ 52IOa@JENWw /s%uHH1&xp?uswR&!y~$$#G6Kʊ zsJ|;OSP5j23An1ڗך);z|y>{( Z AY ?}0 a`ϞƆvaFjW2nq: ŋd4ԣ( &PVjZ[&ˣ w`E"'V s%rD-AEV镍FQIA: %6 {\Z5g?\=7A\wlwɹ)}E $oY-MOّ֯NhAij]kgGc4 jdcmZR]<)*$yoaהM'7/Uc< ;$]Bo.uMNTSWMkC&\WV(Qc7 dLɪʯڭ2muU֒dt2ђ.vc3*Æ愑)=erEG$AKX$M `^)s1rh= { bN#JZoebK9#r+d0Y1򽝬VGv]A͟ tg}rg ˪f팺&k։#,{ZevˈKt}PGp7ht FV~iV8qA=m7y^,?]XC˽`h՝ 4ŬK;TgMLLJAsg1(Z|vf= O_kO f9}/ emZ:DF1cz7:˩6bw-Dr?UP_N+3 (ᑜs Y凰RG)EfŻ/EkDL͓eB 3H;Wmb'r{{k@6^ُd#o{t (nxٽ4o[e!}8֤FIy i31]GFeƴv u7|DNς-ms:ۇ C sEA@yU&HlѸ5n;\rKIƺ&@ر* n^N`k'Wmp f.Q k^MÄJgh$-nѥCk9Qq6nb҉APz|-+dX2 Zw J3j<6s{KS;m%.bmˢ/kKmcni.|'&!1d^oFOhT ;Y#[Y,j^*dt䣚ӷB?-X&Gvpr;:![vgi#'SJKrlRwICr^qL2j[`Roc3 JwI,I#Q%!ےJ/ގ+̑fQh)#$H -'*1rm3,#L?Oyd-,=[*qVo" wGGK.W&DC#ax!3M gsҎLE+. &PA$R7V뷪8|,#fpk8P<߅rdę@ѫ6Zͮ¥' FEK`AX+НZea )<8`w4:@"c&i7Ee"cz TKюA mPu!a%u7LC6A쭭9G_K-6 g^:9n(Q #} >yDڀ%0TceO᝝nsIg]Q ӊYcnˊYNXz~x29\TOvuj;@U[f1NPQn<3:O˳փǪXO\Xmah>h[A$=8P|OV%)]("oyT;? k\EK&j$-xLt 杘ٯ>´OP&snǓz~}@.Ǝ?`P r\FJv'Z"Je/"t́-LXhɶ ;@tr";mٿbtYb"Te '=VAv'u$0ƙF"h'&v & =k~WNvmA.(wdL??ƇH:B xrhf#fR~j1_X덑iev vAnG)H`lZ_q_9LEmK'ަE9*mؚLq.;va9@ 8l1_**Lp0\U_@>kT ,#N{ @Gg @b& ȅ7PtV, 40 S4ߐ$ 5IPU-PN{HvT"}YMcДSqp\˹.'W/[dtOh @b~p;:\>*-Qa"پ\<3y]̏k"ճMCZ?j3uºB812C/r$x!M1sJi[ӝkI^*8_OH 4չ9+@ۋOf㶜Ov|n}jNjT4OV680A@vhQ>+:n;ԟ;ĥWt?qeOn'ϜrŸ$ʑ6WzA;|#eHᙏ'lWϓE+"^C Xs49RYG%R0r"[a*`k(^SID,J5Gv՞1bAGe.v1V  bn@~&,3`|(JaG8 Uey;Li@${4ME:^zerUo;j-b#%aA z?j[!p~rώ'e P|*5>^LGn JCFA =^N3K AR7B~G i%j>ްU 0K?4D'+vJsڡ>R ޕ$^ƽwBTgXCL 8k]yղ# dȆ\+*)irxZS^f%9A*Kghswm H"l6m'w}xŭa1<8ܼ;84U OC#1s纰K*qߓS-zɾq$AE o{5zKK懢GP Fj[¹ZzjZ* k;ͷdQH9?.#`6=+;4r>w5&zaٶ'/<\l4 Z]7/ qp#Y> #~ 4#?M}ov@'ݵIAikfJwaha%i'm=b_҇.:(6TI KlފT#}1$]hQqa8[zE}Gڕd5n&h^;gee>9by:mgp`D^e䐢8&)ER;FfK#yQ+-i F }CGN-"aAe뀉,;rb1/q5wH{|ڗ 5R$*SXB=A8sMu|E%0 BTA_Ko ؉yN[ jFpYaBIM|aC9JCs䴣*vU55nNY`. ,or; >!|鮹Y^I9]W^T^Dbjz\sM<[cx[rTBv Wbde5%i;#E:Ԛ$ʑ(&݈7ڐ=0  h9|>@V}aF|Ʈbr?;-L`[sn.[ڍ=qJz&.GTJWu':O2k!S)F Bw4l-x[kBF5z35R݋PGD>~g=ˏM.~xݝ)=<<[w H0$c*xW<-1ꉙI:GT:ltʴ:}.E9-~oܰ?:pDuOeSAw)X0]v=):왫Ǔ}8"~ݞD#ЉeHHb[ZF."{IL=фGBр||DE; śѷ^_M0)yunwUJ")iDZDw 5VwQaWk=5jbnvžS1~ bVpQORoRtvfDt+1uw2J|7RCe?vRF`L \jblCt9V~RFŁa. $󒫧T8c[ꌆ]a\>tp֛ |Ceb}5.(fKn\bwYQLsd endstream endobj 127 0 obj << /Type /FontDescriptor /FontName /SRPSZA+CMBX12 /Flags 4 /FontBBox [-53 -251 1139 750] /Ascent 694 /CapHeight 686 /Descent -194 /ItalicAngle 0 /StemV 109 /XHeight 444 /CharSet (/A/C/I/L/U/W/a/c/d/e/eight/f/fi/five/four/g/h/i/l/m/n/nine/o/one/p/question/r/s/seven/six/t/three/two/u/y) /FontFile 126 0 R >> endobj 128 0 obj << /Length1 1418 /Length2 5940 /Length3 0 /Length 6901 /Filter /FlateDecode >> stream xڍwT6҄RD8tޫ@$!t7&]wTQ(H"EAE{oedgfwm"l!4(X$T 0$ 񮈿n3DdE@OQ@{@,)%EA 鿁h P ꁴ u(xcNxB@^8,-}KW8P E¡(>p#TC]&h8G ^9'<##") u |@O$ h!{O@5a7vP,H0"re Ձ&z@C  s9@0_DLD h7 D90 /84!EBaCF@(~88qHןE~!\:^@qSCbp½{i {D;a#bBChLxHꖘDxD~xcf_ t @#/p<pDN0#~ " @ϿV٣Qj\9UT^@_!1QKo/m(#6 Y' 4x % A#ֿH'|S+'YW4?~ {xp #o9D#۫DHX\$ێi xo1 B W$ qC|@fBx=ޟ{ayums&E%$P, H ky0 ' h,g%A@ן V?2aҿ$A(#^8`r q i=RfZ#J;#*4\hCQ]H0Κ}1 ְq0Pq?̙}TQ-/ġ8߿0{zcy L 6[4M'c 7_5]=yK5n鄶wVf1J}doC%v(x1*2 ㆮ\ foEtǃo\axZu~V5fW~xld4*mC4B(%C%j'y^~@o(Uy~97oeR a'6vYwpXrѶ׾>ذm~+RCvy0/${^t3yž7=WZUV;^!ڛtBڝbK`^xZo-y@Ij>t\Msb2i !O9]wBO&l=,>fk;(6XRe-?_J|9RQza_zJ9؛G\mb` |)T*WOz[#Sc׈`Yj'Y"Iڽk[rXC_8gGP--13hf\|L'`jvs388e Eԓ27ẏ'd|\x' z؜gԽ& >n֥ UD}w/ Y1.&Yn]7.ktE.PGi7o2ӣ"јAچZ>}+ ɖ^(?>جSP :TЏ4[g""۔-l/O6] ǯLnq+p2pI2W&EjbI\큦DtI\;HzQzj<his%$VF{mpL*1iK#C]Wl1[}~D. ͳdrHK}?c$OO 6IMӊC^+1L9:]->V~\=~}#L_DaX… ぼg-7Yd 2VnZbB7˗wiޕ.͵=淝٨570tƼ6(k{`oВe}A%cB `3Omc@OXM)v&{]y,]h~AeGe陛(?I^:z3qTċ*5 9 +ӗ4"c!fdP0:LtT\'ptg1TbZ|ϤT'dB'uŲ의ݩG 6of4s_U !jzZUyO!ED9I<޵{9,c%(H{a͖/nθ-F r)\k >/=iQ O{ Sf9z<BLMd}DN>}3$wk56ӱ0v}GIi㗽+A>m)ˏd\E*OE>40'fjIqvAdDjܹ޵o*5B.ϛszS\vOWE(*nX' 1m\͒<30[$DS)7eɽY7GJ1sךT5&ͭz=' Խ)Iө%^Ku{@ma|^NR&}ͩKaTxU!aAo }U4׬Mw0\@4:. ZnD|sg sLW. jLga.z#J<)m:Kef3R 6~y.FAhxq7zӹrQ2 t+c1![ XO>2GB}=-ZvzvAfx)c?#v -X/o+*ީ_#~2lN q!W᝴_bzOKMIC?gT>0u[oyR &𯳠A(̣6oN%XUh[3!MuqUk,vًJќih+%D($Oڧ/faB#ˡاƎmI ϾzuͿŗgŽ1*_QWlIi)!VnԎV|{8Ku݌uҴ]؇Kf4rnۘ]tϨZQ%ܣ#i(V1-xzPmqEB'n"%ZVQW[:#]tˉ(.? , KN>u9Y#_IBg] ydK&7m$fFowcK.IӄPrԧ)PΔ%5ʱR?ޮ;ڬW;~ˏ Q/*],o,7}㻕o&x2R\8ˋTSw5 [ϕp7yX&QŽc(=ڀYKlp9rC[fkHDz_il'Fз9 I_P UhHCv >Y,zaƋ5vTEu7Q An= w3mt5ǵ&'yαe~y?| |4Drmܪ{3k$*&߆2}ۤ?& !eN$Sz<2QݭEǧz 1ĺ3/+41z\#Z,Ҹ1{d %yy//0IO"7\KyL\":5^䰂70#5 By Eǔ_E%"ZWZ%3]p0T#5%kmJgCU#($4_k^ <{7p05G"9#jSۗ6ޠx7S֩t6pu)1 i1;VЫݼ%y(x y{69xA+l^97;X3|{5#ưpfL)Q4-Q(7Ez(bWi [cE֗t2-Q[^_Z1TZYI=$rp0zFa-ݯBScVT*ISlX0 \BO9QyB9".}V3@aW+|*'-x{x;W WDu̼- =\d%~zi[L3CĽ3iC\Gzw}MZY~&㢁ebP@n30Zu*CapZ+O97e⽆ܬQ%b1KYw:B>md g)Jg}>j^i{MfUIΗJ@> endobj 130 0 obj << /Length1 1990 /Length2 15439 /Length3 0 /Length 16653 /Filter /FlateDecode >> stream xڍP\ 46n!-h8r9>s QR67J۹330D?33XX((T-]l(ԁNΖv<2u|Č\>26fV33'?N<1#7KS<@ G!jdin?j377'ݟa[@hbob t|..< F N4twK g3 h 0@38 _r{3w#' C`cisp3:>T@23G K?LLm<-f6@ C#g#7#K#?+7H+>Mř貸-,&mddfvf0uu`TttJm!Gft311qrU=*0vw}Z?~༝܀'W&.c??@;Yzt>fOzejog˨(%%.FDD=lLzv&CaۀSddwq(mgfGﱠ{ehAcF_o6 W?F6|Z,5@SKWv1Xa;sYhdbb >X-lt gbq8՟*>oJq;{?`d q@?G`g 0wD9BF"N?(_`Tq5AF"? h4/bqcGGMB֏>f_h-Ňf/_ܿ*TE?*u<awGW{ .k[bfm_ۿG ǿG?̬e19@ oUCHC0;$ŞF: St MmvІӝphڎ8 &$>/ g-Mc M 7Ы yuQ-CʅT> 8X:Cr>F-Z7l8gʅڅZ;L-I k&Kz*s.96!- A O򒵡%o|%ytik( ,YZƗwS!TCIN ]Y]f"wfVi+ܳyD-〶^&ѱ!ֱ^_2AAswO:kK'e~T8؇u杻{|CpH6˄yK5`Nͳ{g|S]ѶŻ) .G9ٚ|c]fu~S^{GQL_[,zWAiȮ"gP)3c׍ro;O Mc쐼zay rpbQ/*#K +ĺ%9ɥ,(l8”8,1u60MiPm^A!#I+spE! Kȸ[,gpBiצ%Z-4Ri*Dv_2m>%[?[s4d(D pY ʻUbV| X#o eg=ܹY2QT0TbstS9iR^s`{5؟2t^'v3w8(N5ӊ#BrɈpr+Y0B>z(% ;ZoysСEn=R< Ohz댥ɺ)}*,U.cwEa* q03OtJ^FnOK%QKZJO7pj'os= RT B˛.E=:4]/v9ZTF}-TNvv)2rX0ԩBp ?3᪛e%7V/a~~@s>Xk]ȖtÜNd+~朂7t}e);}w"< (q7 v9o&l;McPsgtSrݻ,J9>n6dto~YM\O -f^n[ "^5cya7,n0P`G?5AHpmRWqݗI`8$`g#cFZ9< eV1#cW#7?3Zn.2L>; ]TF%Q<"]\?Ep)d)n-KeEX^.5*MA9Fb_.Po!QiH @KqmB@MCBB9+^h\*o<.2VBG_ũ$x'1Wb+U];-ȉ2'i'~8Ζ FM{1)1GTX&YʤʯP_5Gme9A5^>4K"R7ղƨvߔCafH~j<̃JkR׶=g,K@1ȮQ-u,*T<JZ ӼD1z3Z XQB3xp 9bRV(;ΘNAkpVkk jVlx)SkW2뮀4f3^Yí;& B*R|g@7;. JkjaOώ9Z\" )/[fY?JwH%+RQg55^}_[۴cRXM HuG)JÌNpX0,k s*u:ıӏu]o! I%%U~b*uP1PBq K`s^'br+874KJ["NmqkGgH'Ev[ +?N`-Lk=O)@W YnTö hT*;}bǗm<_q8 nEm[j%] $K]6cƷ/6پ3WE< :@64 '|*:4\ҟ&){};Įp9pІkU@nU,!O\̊)u@ *1}e<vQeh|;>l"nꀪl&hRb6Gpp'4u{ \YtIQy6T_w*mlfe`0D 1ZAS c̳EZbNd$l׸xnQ;^/>Bo+9l4_Q=A-{vαLvjm+RТNf(Ge M}gݣΕn?|FWGҀgkni͛DgZRMT-~O2*H=+ZD0V2_GtPG֠lF.ml_0 d_T]RnvJxS±b"zQ+DEw $$`Eçaa+!po y.&ޮ;S&9=:"QT!Bj(!kw/<` ܟ|uI0aYV.G]w%ǗCo6h#^Jij.#`:lZ|]Ìv/pG&' .CZ<i}[4 ФY`V`Q'zx2hں"ֈETMperåˊyf(Kx-g w\ƭN)t*EW||6\KrH/>^MUA;zSk"*a1ٍ0P PU4I; $NZ^%|%aNi¦ҢpVP/6W㯑ٲlx&eqk)EMWJR` =a7Nώ,MK)qbjj7H'GwBop -:aaoRB'#b{n 5o;*zJ;X_Uʪ% u"_59*LH`׬R/~gBۦыӆ^@㶅{Nek*HFĿ엓դ\mq&~ jf}5{Xn{q2ʿTlg!*'d'a74?krtHኵe+?"RSՓ y ċ*fX80c"}WCk`a &ckX'q"cƇeEVK?~O:/[iPxJcMn)E_;w4|#ZF, JyD*A-d>yEf{Y6Gֈd5 oh|~daQ lӟ}~+< ϣX>Bqt %ET/anP7M?L'<9+ H{wxv849]1TxLn&EWgvz[`;0o$`^6[)+4#9aI86bouEy kllVl3\aՂ=CZ=GnÐJ%'R7yRtO?n9º&jΆ!I+GƲT0]2LuRECUt mָ17\~~ 02.]+?2IR@Q 4m?>3#`)%Id'CI]w:gIX ~ƻ0SǢF}?k`/c`N=Nw6P[FLjtMh4y-nz'9#. p[ڮQZO~cyH,[C$ M =#Zx~#X+0EkFgULiZ8XS oPF G21_`q$-6v|_ˋ4 Q7~]WdۮX=?T*pPU"h9 /e&ZU·Z&% ^?^Գ MucE T*<\TZgf48/.x`R 2ּ-RNl ?f?əįz/9!NE FgIrii32{7qˉ,yy4˨Ow$_'#k(_ren[Etrxŗ#s$_tccچg\X,p;1I!Cuq|fh"f2 %Rh%K`Vз.[DK^4aq*%lꦟ˟G5)MW8d:M_F&Xw[50#2C]2$*D9ú.Kt0 ˲b@k$tt][Q~%QUzGveUfla3%ZSeX[=d*#nD$eT r!E[W _YϸQ+Ju}iTrv*&dPGbZAZv)JZIt!jE.S']㕓9.w R }DT־Z݁[{X>YTiկ7hBT!o U]zPҳUGߪg>5 -]qQÓVM~ÆE Bo|vֶ)Ǽsi W4CzVk稑뉕~iek5k('w1)Bi, %t&q=_E$(uݏ^ڭ4w#]":,]tZ'`nD\VZK>mPqYƖRN܆ko"A&AbM{Ŏp_SKƯ %Yqk#8Tᑪwz usl[^sz&T1&,*R\ 8VE'g k?:[b>ީMtw1\=Fߒq_r2tz)5FzƮguޅraAҬpcݛGm|U1_>;h{Kvbxc- 6݅ybx\}SQL/&6.Bj&hV:s Lg+vE.Z">=sn{[AoЌoO>4eؤt0y$)!)GFC",ʖݘBߜfitrJ26(J[̅aCbKzsAQkEY0:UJ ^宦+;L֛0 W8wf:,y8xz11ٕ4bjs#;XiC%VO\30dF~Ob+xoe wV=?l2e~9ew3*E]=tФYJ7R~n:22Rnq2I|hq%ET`y*e{kA(ֳ+qq'\@?r/.n_T.nF'fGtssQ`=B,@CY˵@ZiDfw*͡-8( <W-w[6i֘,<AI(M AfMU4^M ,e%䛏2uXL T$z+t5>D\א<G8(lY- ISMfl1yD|Dd+|4j?$+=ǗZz-A)Ey~ Lv+[=Uuwm`Ay,ю|fzu'BfC+vcN[x-\ȗ)J*TC$!C$'kjoFEA¤n7ą\|bC0L|=7coڜѰG˾4)LVyR/-1a.wY2Y?JBd!{MtkA" mX}^ ^lɢ{g% 4/s ey 0!|Vd{[]ȍ9ѓ8FvDILc)␳7UC:"d; vbHCFvyN."bG }ٷ7ڭYu *P#I ;epT9zRQo.-y+\4K8Na㕈pO~GWd7\Ru:ҫed ){1! T*uquc>_ uY0/z\Z&`nע1v#~zIӐJv-…h1a/aЗ< BE|ry(4-17c-=[%z 'BU2v Wv"'GyY"ŧYEɒT/-: bvH ٕMk*lފzNk tOUx=$jŤVjY?\6p2d\pk-D+R%#qLZޏ}H<jcX~a=oUqciJ.5\6qQzv7^758"vD6w!7~VTfK{ 'FN a8@<h)k=otobpW`©rZG$CWKSP|YȈ;^W.6tYM֏ p6o4+]+k!Tr55qVR~HYp 4&8/_aZ:IEIK@q{}]9AYubeEg33Q?' Uᣭ%,ﻌtZHY=k"dk^= V-L猟NKo@3"S#W g ch;1yA;g"t8'B*c:j,:SvW]Sw1ڒg;WȘ!%QFM&WQK'j:w䵌U@;o`5LK!*\r J=UMAKZ d@sԀF50D9LYq]0 4j7v؜\{G&iZ0*U-s`XSARc1w/D5NgdP*_$u₴k)<8{XT}.Q=[dM6f[kᘩ fz&ɜxG+x:- )gC4^S U2Ez<b/HHoXC4efM)b4'j5Lh/Eg X\^zQ%:r}zWX&V]m- QEKT"W~rR̈́\ nMoɘؙe6f3GI + ^xfb֌6l %U˟6\vȞ;oc,D`9(ޛCnq[j wI{]V eAO@-i=6 /!(eC2<_E+]c\0&̣A羚Aya,"!)nFWB|.Ebٗ?!2 lczpGPZQald;1c/t.oAd@{ńn+#ssj¼9ub"uZuj0߀*\Adl'V`h8po/bM([%)2}4-8OI><{\ACax< t޴n HXewT$ޏ`>Fخ@M uUGuiXģCG_8 &:86] U{mAقcRcd:0Ƙ.ޡ!ufPh 2N=!bItwXr L0y@; #n LfD# {Oz_0} 8vf-GHs@FM0_sva.&En/N3!DE{uNCp7YW}+ ?:iRZWv̩4CQU/"2{)cX; DtiW67 7oeB jM,o)$ y6){p0U$kS9REMG?# GcUfs^lOppkv[iAG$ؘPNX"ĤUԢ}RCշ{WXԷ]>/<̙w,;R>GoŚ'5ܡÔ@vYkZկ$_kvK)8.6%鉃p6b/w*?(!KkԈ\~5y)dgy|VֲS?B*mrA L5>ߌQ%@ endstream endobj 131 0 obj << /Type /FontDescriptor /FontName /OJYHED+CMR10 /Flags 4 /FontBBox [-40 -250 1009 750] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle 0 /StemV 69 /XHeight 431 /CharSet (/A/B/H/I/T/W/Y/a/b/c/comma/d/e/exclam/f/fi/g/h/hyphen/i/j/k/l/m/n/o/p/period/quotedblleft/quotedblright/quoteright/r/s/t/u/v/w/x/y) /FontFile 130 0 R >> endobj 132 0 obj << /Length1 2362 /Length2 17670 /Length3 0 /Length 19044 /Filter /FlateDecode >> stream xڌP Awwww'H 4n\;Dp ܛWWTAgiITMl@6N L<Qyf+ "9 \Wb:d VfV33'?<13 9"ڹ9̝^#ʘIW:@6N 뗎@+1?%̝x]\\֎ ft9@rp~(A3c@$ښ:@d19^Tv  ]lW2h1@E 9'W':w % [^:9 ! ɑl"2/*ۘZ[lO 2~ݍZغxL6&I@m?!/&?63 \Wsdm~aagk0}!^ z8A'ߎEdAS 2  ez=f~{Y/[+?͗QXD[RDoغ{jZj!϶p*b޺K -)Wq"=G-'1X{DO+۬gZD:[,w j,d:xįގPx&~(.tOZضg:rSPu8:ק c|%9|U*ֺ4-tMfUȑN1hYǮĽsU~@]EbPGbL UGg6qx}tPYzѺȚlq`5>tyCaukB-g b5w !Ać%!ڽoHiUm.!;XU\o"`' 8;Ќ}+(;"BnI?sOS?.XUgPM`dq|"' sdvWsk DOgWiw9>!Cs% u*HSOG9s| %n };?p,VinbsNdY+QRDQpxڙ.L=#DaΈ˦>) _H-uM4&"%q *'SऱS'=Z+Sbrsl/Is(afޓh1坍6O%b͢ŚO kgwJ ᣮqR 2pU<=ykS'^*SfC{ܟIK( ҘlzF/\P_J v !cX}r?X Sؑ ΢ΜL. VJv~mڬ~|I1ZGHVR˅0$,J3GMfF OGWGwAR3LU@~8F8ojW758Ze\ *t\,GHuo-{ Q6=D)ގ5O}ò0DgY2U'9P3i뗲 o)ځ82}y㵱)pn*~I"IQ7>,Iu@Ї"rd!N6$g(c6Xv~蟀 YsJZ -ZbD`1 eL,_j%E uǣ8nx#05 =Y_& y|LP-F8ی GZ9o>闳'y]!{p(;i jwZ ^VeU+>$ziSjb. 8/(MZҨ!7RUeq,PW|!eu#<;+̄[O10 ̝ (wS&V}oqIF -6פ_NxEIe6vxgD5)R|FA(BwmOrMA~d7U(RйS[aV&ip s"{گh>$n__ZT3& A]Rasg dHچpwϿǭQAt !@t~19~N`c#d4TxNIrJvuƷL|JFx(%]@-s\ !S\%‡$x9}kvi i t|wHjY6o.~6j倘 RAYPPS"9;(fCJ!ġ_BN r{ *$( 19HAo+ͨZk=6&R&N77ŤzU_ք04a#g7pX;7+b|pP~h6QDPnrܕ=/hm yu*'Ad*'60$7WX^( <&?& 6VCCA蠕80шsFQ {4J=sw5<8hZ7btqf7 +J4>*9.deJb/< aIEF&Œc};3`[&Ωm0Y71I\gЉn | P$b($s?$ntSzhaI_~oY"i `Z~تtۮ{vj!^&5`8z< .5t\`x1|W= 'X]9"$H0X;,'R]6n-tiSY3.. jR+P-F,{`^¥4s1༅S#UtdN Rj^F^eaF,z@H@0uDnQndDcU~Q7 O7GQ*}ؓB*pP#ru/F~9$TQgxb7cDzM8K,BrqcF#z8,w>di Mė9ݔGc+O֖Ţ\CA((jv:BQワvMe, ~reuv(M8&B*z=+ցv%1 ںם5 QB]w;YN1Jj`ruHA{q99{P8'1W\*ڗbZ>v'{ !#pW9hyv\k4OwyoRcJV=)ᑣ՚G):zGY ["|y+0@(b0T WrEqPL nOuj/\h}AJH3!ѐ1Lxk@=]CO>7Hn9m3A8wZpoK:-+(1- Vn$R;#yP^( ˗Mʪ+Waۄ*9nIshiRz -ԸN/^:K4!Q~"Zfcb@ca`L0DRePbU LJFn]5zL EO9 0tz_<}$G%T7=^5mJEr% J}C،_U*,%j!Yr%F56ZZlc4}j8|Yh]m=+nnW1ʜhͫVA7VE}-o-c-Y(kUgM1Bo,(]DLv g#HrdHcjh*kUka{aǹuWUXYhM %F*V-grNGAOx;<ϓgv*{9Z Z6b i$Woʉ 0Bc&bH =KT48ޘaXDܔTZ+"~P32\8u! {d^G0lgVA*[>lw6a\z]!4 CPa)y=R\,#Sg_.s|USiq(:b>ugin*l-c~2ŚF[E۴!E !:U_cWFۅ9:@ ]RoNnef[ zOWl$|:{b\SReRI-P?R,N*<NI1g1QAӯrdzc#M5OII큍Pob:4?t祱0";Wta0F61])q;ā*Er*ɕ"2D,'.ɯUBcf"Wt\Sgܝ'N)ҝFvlOvtO1/xC-XevOt0@^15ڍc̵1rJdlt== v7˕RU+Q 0@uT],oVPn0O$uC5}AQXDs)$t~#+-u7M" 2A1` |@|bs QdM@9D52k >xp|KJ,{g}[u8m7&>FϦ遆o-{%HTD 95$IJĖ)"!<̽kR_9曤0"qD;˧N៯80#gug֯ș#Yź3œa ' 2@n<v^!&Ջseu#U%c;`1|IJSh/TxZ}xzO i}XB+iR̘?9̬pQVyx&ñQ&.?^;U"q{?}\ ]/!{zxXJ-W}CITSt,}Y#jlӖO.L_hP:I]iE9ߣ LDQ%͈x)r }w|O-a;rKfp6”p=in $5Ԃb@wEuC|߅?M2ah]ۂNM( 6 /r[g9N5&R 6ݐv3r%+Cm:Z0:/C8tX=x&")u՟MQ/ӡ~GnzyDǡ+nc Сe&nB&j' MHƛ5hO#$m?w|㋚y C6YT7˒ښ~M\}7[ʱ<9^/APA)+6{C!-2Z^v?jcC7OsRu9n{?:K!~梅{Q qAvx.&e,2$@) ̚p !@)GXpw(נaŸ#enH8Z%)reXwD Udx'}*d)ʭg]Q^ub,Άcʓ % )jэueG7.@NxZyqOl>zWU{y\\\5hHms8ԡDh}𖶥ݚRK6J wfoL?ǯv9{òwLJM*tVG-b6`dG3ER|C\DބGwۨ,VbuK\ꔟ95+yOLf_>$-"s"'"YuOYB3W}Mathl,Uùp{)8vę/CSg%U`z.P 'x&3ɉtJ_KOT 4zltA] bi9<n Gh٦+YFs%x2dli~!r+5hg+Bg{kbT 5bM%b_r/t*Z !g0o;P ZFASUoٷ3ݺNӆuN sW `UIFGp_pa$" t}&Y{_{G?MZ:sp];AV1ɘqUocMF{8;7> >SsEO" Z t:4C[ѽN%Ўǒ((;ʰ(( I:t2Endĸk?aSȔ*mz!C cҏ2΁[8xN@+L-IrgB0$ JzBwn9l䕢6O1ߚVzNݏSr!.Lk.X Wa:lHB> TfS[vW&WzVI%ӵ2sŏ6CA?/S I U= 9:*o uE}7#8Roa-9XYq,ɸtmbSQ FGCfWQgYlf2Ji) T1 +y0,P̊!Xi3_?LF^"ӂ<Ƕq͢Uj @R1r}*l ٟ: t3W\r|I0Iw|]?*1u3 ;ru'¼ r۹=[$2 s2gO.nI2Ԟ,zm8|;xsRQȹ: q7*ͨVFuGx┿瑧oqW,BH1/$Sݮ{,:`4}b_@wk [š<Sb;yc"c#/`pGlI§t+E_uEq9uvz#vҊ wwe ;+7z\lbVa/jոq4At~ a @I#~޳rH /̪L>oY0Nl ;VV`(';ʾ{ b\yR&ʈlЍ}&scKßyK}Y9O)FA\`\)"|lJu`o<ӱ/{fG}YRf6/һOuޡ,s&Y|PB;8 W[zJE8<^PdQ7z8xGW 6iYL ^&]F7JXw~ D=؁>/ـ1PUd'~1Ii|kloloc=ikNv'|^jf&u:<.W6 #G e~@;FhQse/ˉNٻ-<";I~[ NsG^ʐGs~㒈US.Ut`-FqP͘B73QbrO]@};cV{kL aNUG:+=( B{m5]~pJ-={{rt yg^:VΓU9,ϹiC,ty@0J, w<=v!-\) "R-ðFR_vM,xC[ BU${ y%l"I C ,ЂC1{})n(S"AjQM AwڽU~܆ĥ꺺ek&SVOJRշP퓿u= NX %ddwB%$!FR+.l0=ZIP(FQdIO7:L͋B&`"u4٨5dGbyt/\ĩ0nch<-wiQ2\ƻ{wU* $sIA9({?*OWBۉDuګAbBP!m#(iNsb6*G*=RC_r!>KӣYmE81$CGĬA}Y?Tnۤ)im㽥sA8#bWߌ6~.^:=ag<4v l׵ue^ɋR1.˧fT9X*4Ң+|7;﹌v' @V,a6C;84'X,P_'gY(ɇv'g"LG ʮ' @e/ۧA9C%g C%atO] ;o)0/ٻe=Z. H~AK;_ xc%(c۱mNYɈ縺y|)=9ҒhqbVj[\brf#>w3,k 9Xg>-W/J]QT D>$@D 8ꄍUT)C,:by }6^C/MfgJi hy8oblOKn0i̇/ -r8i3CU|^M gw:NNE"+nZ+*bJBFqX6 m RU_j"<9NU'ƋFN4>Ì~Ȣ/E k9{6ȧ$9b6Ï4$Ġut1dnF{s\Unn5!t4JjZY6~|JMxٯɂI}3&by-Ɔϐx~,p #Ӫ35lhbNw&/>wG*e9 {z-4l[6I.[eB? m2B2. (k:tK- ރHlTdi.U'VVlUnCR$)ZSd[?jW$OUt; OD!ӧ!6~'#>ʩ}zlUJ#@GU`t8Xed,`j-!T5eXZyFN:Ue/eM|F!*E 8RiԘpi3Ȏş7m+ɻWstZ\}֎C$ 3|Q̢lKHѠW`HhQ" >mԋM |7DbؠdBK VsIOAI.rm {.tu FPd+h z,F G/2e@ڛ4id[Rs Tr\A i8Չb,FP G j@%辩=e&Wj:i% @,R%=NN53dՈ7Pi!VICBߣw w[wM.~O懬Nn~4uG5[iw֍,YkxObM{%fojHɞߔT,E҇d+=V&k`DyP?[) k Nu .qԹ.ݙȮ,xO`!B,).kӠ`:/甌IT=UyӡOB>+7?6N}1j"[nY>S$.^ s yE{ЗȾzE&+VÀ3h̷Sb(a8)xԋi4DE6=#ge $ԑ[/q CƃxzKC)%x τf>UH+`o Lb@v!w[$ؘ:4ͳ$8|:{6YcJ=pFhtلxco:H&cC6p!y̼;]W*lIwj L"!ÑGxQ$f 葉fcMim5G {p^Qxfi4ݦ^[G$Yw[:f)~Ǯ?l0 8,~.V֎Wy]\ 2&5֥lt7|CL$ |oƪ_q83Ҏ-L/tҼwjG꽣,^Z;SdO8QQee zӎ_X_9{䡽T[ғLX>z#q:NXMړCE;f~/mTed.Gn s}D"kF.S~7\vVRFjd*<|F. 1*|Hx/uլ~vQ}sm!Жg+CIX75#’CЬ֪S2@0S~I A1CTlF<9tQ,Šeu.|⊻bnd# Ҙ!}艓\hHL65&n7hg+ N _P. J#slOv蓪5"Wn#̄ ߡ**!ʙTҤ6QIJ(^eŕͮe}W!ꔮg7Ɛo#;S̍HyǯEu]сPU_o3bd탐G:6$.$᯺]Ru,<2h~2"ay ;8|sV'&Tg‹v# {E[1X#h'ȭ,"ɂ1:K Taύr@@:N 8B-yy*4Lg=cO*BZ_`:U FnWMx.'5rtok̵.ڔǁκǦ_W??@ JaD?[ AįO`Xɓr3Jf$*``a83?H[>xvgCQֺ"vas*/QH ނkz >}@ן"B|.ÞK :̓`Yv"pG<9$lZjW4O>WbBvT|QvՂ( IΕ繃lR8CpXY~zNX0A󱣔<һ'Iyȗ̲z@ISCr M+h$QwNq;Qx+W5ZE\/eo?W^V8eT_{t dZw]D'~Z2qr,a}N8*k|`./ɢp,涔nX: *FÐcڹ6$2#]mr6y45|")0&fFQ̘~Z= *}hyχ6C_[[zDC ']93J1;ګ Ydh01k X&a[׏S'^Bj1No_Ft:V|:Vg%*=}$NʂQ&;a( Ē8dŊWln9o [Sn?a!i RL}lz{xSFd=SC kbhjƈ&6.=;ܳ-b.]?ku +T3AB5op0AbrQyI}DKcIY26G%bp(J2/H]ʒU}{ QZQa(:÷f_?,s E76N15X'R$sY2>C}[XO]ʲe%(6X/C~2q?k֚Ī55KU \}:+ 9:% Bٱ3@6MQXTJ4F5>mWhl$ҹ{%ْN<' d״3 nXDЊS7* DB(gGAv{kϱ Xf$ @xk…:1e70ar޶9ʛoKWt>eJ&\;$p2EzՄ9ﺣN-HǞ6~t]`JΡOTν#kT-Nw ؚYJ%#AX%(z5ƗdܜK~鎌Gs |Zzlȅej֠.:X>SC;Ln/-Qck9JJӃxe8eɁLf tUҟ+"ې`.^d8|@JF0Qá( L@_ϕ 9z()W=ݡXm"qzch>Ȉ3#ilC _)nxB O hԨWyB=լol5>!WPIhAoJ!3bːRHc&KS)FJR1?y`9N]4O=[26IvА5zm4`LPlXpL>i K,C6v endstream endobj 133 0 obj << /Type /FontDescriptor /FontName /ABYGBP+CMR12 /Flags 4 /FontBBox [-34 -251 988 750] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle 0 /StemV 65 /XHeight 431 /CharSet (/A/B/C/F/H/I/J/L/M/N/O/R/S/T/W/Y/a/b/c/colon/comma/d/e/eight/f/ff/ffi/fi/five/fl/four/g/h/i/j/k/l/m/n/nine/o/one/p/period/q/question/quotedblleft/quotedblright/quoteright/r/s/seven/six/t/three/two/u/v/w/x/y/z/zero) /FontFile 132 0 R >> endobj 134 0 obj << /Length1 1576 /Length2 8497 /Length3 0 /Length 9525 /Filter /FlateDecode >> stream xڍT6!-!5t%9 0 ҭtJIKw#%)!Jw+_֬sݵu롧f[0Wv.0@ZUKp:Wf W`g&igM1N(9x\\@ W Y cr0 4bc̿^L f۟t$ Y` 6zW œP3j V߄jP_80:pkW g0a.n0+3qq @ +X6߽pqpٿ A`-@ 8!` +f;onq| s &\@GWo ?)]ݐ7m8xd7ǩP?CM* _tHlFlq%cy wk\@ dx<q{IYn{^Gyq| GN1H` w}bmxF>#GdoPN?c? (rR@^?c)@~?j #Ǟ `O0ca i$`KefYpnwFMb ZuL܃)t!Hg5fYv+=> trvo?|_#6?T&Gp+YWu$lv[[%2}$i\ˬWv 4cO)*xV 7<>koofu]HH I(/G&|'+me1DdnLUfr->*[M-^gh Tz@i(blرs !+8?67Oc<پHORxػSIyqj t,gtK36C;mk%# zy3+q7XU:܄|{"$ZJ=I(KxQOONIk0ЃM ,mɎφ^f">0"%}=rnܧ݁6*4!k2[<&[rE-!̥BȻc]ԱX-jҼ{y b~M>^LϳRBa!k:Yw1#l?\ՎMK<ˣnVcglX| 4drëL7~${vf]c2x%]bBUSl O8 M^O U}5*EEHkۺ۹l~ѩz~+V62zҷp= Ȯr}-8Ω?C\]+DӍZ;_oUt5%V{Z Τ)6A9)ء\HuRudqx~T?xd 1F聖 Ÿ${ql<^ Q .F^"b\)b]({5RQRHVCӞ A 7E$wy62.EP^ۏp\m|`,JLN[kizmf߷ <ٛY^ hunܽ0dFs o7AD6 r$[IۻH{[הP垗x *\^FovkՂMd}|u3МS̻R`!'ݎ") [$dnbcqjYB"QMl3^d(l1!(*\¬`o#P2pv3іi@ࠩ7 @qe (mZ2'֠ĎCr3jq UHx\?%݃8USi$&$=c" xK~A>E;vφm&p}M.\DN9`DSAb; Njg٢5:n>fτ$ /!$ʳKq+x!ȽfpY={pPwB?vT-=iTO+6RۨV9}b^&^݊rb`CݫPO__zYnJ t^Vé#IF4ԧQM?- dL咿\7n&yL_]'@z=$%mckccRyڴyFo YyOU8C,1ŰɉoڹTE0ljWd:CFׯ-OoPsM(=u0FZ<A.DFxd pM[|0)MRH]=l͝w7|'f"g9jdLV,⚠2 Ƴn,gs i55@&Yz+/U׿_a Y[GY6F?hH\~K䐟(T}~1LI4W3z FW՜L3 [Xy)SB]`zx[U=&+Iz$='gl3Q*Zk19Bng1?eznxizo2f'y5֙^CUpJpF%U{Ы5B^ |&6QbR p/U;Ig6VۛΣ/EMi:`܋tK<\iAd|Q˳R>bt@OUVt%X} KkeWX}yV V*m>폾h{AR% _M7824_PJ-_6)u(Vce'Qز-E,/HIbj;`hF?6wi1+KȖi{[ފɭ ɔ?ߗǓOäzWzYkEBrpkrara.?W f5W \H =wH )EΟx^U^0Z7cԍNfg{x^Ē~_S{J[bnE<\='MVv22ySƼIú1]kM)- FD/=R'p3Ⱥ)aES3@1lhq~mZFm|^7}L5yrT=Gқߋd <唺4h6Y8m]bBE/ZKD"bZhH^Eˑr\/0ph3DQo, B8%nܫNk+Y⎥4ɘdg}b@wQuB 0AkpH,aΚڡ̽#Vx\C\cX) 㬵㞖Ip4ulz'{"uFVm% 'g5/lv\bR4#>D8&H($~'m3Z EW-%&v-InfN~CPZ;R-Tĉ` k}5"KЁv#W' . eʄA[dG=SdT3֬\擏^ݣ'8t[Ș-nh! y+& qtN2UҨ6~S72$72T)Yu-pͪrŨ#G_o.4 yN"AVF1fے .z҉{ ,O'JtvD,5a&g#e_$ބ@jR~-;կ4v%b3s*7$~)x7(@Zڱ:ݺP^ε͎ͱ>ƝA!EfFg~CNr}T@>,LMjzxڋ۞שµU<͵zҗVE$,wm|O{}7n殺!^RV̤=.{MoR@$.eeMc2+euTvJ8ʃĦ~M\& htȧҎ9AՎ)W0yig*W@I6p04`g0e-@ceWf%&5PwSUi0yx)/󺙪+Vu^(8ɜ64#*VJXjР!3m2fG(WQq cb6>?[(;FKs K*Y$" 2S6,zN?-_z%t!J08E\<ˇĒ S5T)$Ntݑd۰n~'\鶚~"c;ҝ!Zj#}uBnmS-f &+5v8^Jq[L|;bl. nTQJmJT_As%VJ.7^>)HF駴A1G+MMOo^QֱRwUj!(l=mYP ^;>AĹ1J+e!]PbL:U2jL$mïtCVi{l&E^rxa\E 4ܰt( `+w3Î^_g8M*vz; 1n)ֺqJ^eSe vC#ImUlIs<[=\_OO[9񲷧ŴC߼Ks^K  U]yoߎ^6GP\B"6T &dmy ybRZ7)' c|z+JhAXVZ?[Lq%>ϩ7XF? ! ظiϨN‰=Fط}NU&<(Rsw[iF2&y*fD ך_m% _45U-PYvJ;T"MpC8sMEEPrYR_qec.:!و,2?O*5sӟ9aSKCp+TalNɰa{1}bщȗjAL?Oye,3q5MkQW`VW7/Y ;翯"'VF[r=@Yx4)/e}I"䈷eiXh)*s,[* #I\o) Po/ 4V^am-5XozqJޟ mvMm$:K犩yԷ(Q\7nd "/ѷ-# WZb8DaST-WO\y~'Aw)(2G grYs'<~'ܒ.^v uV$Z{YS,NؒnyaPםٴn"|I14]-1WjQIk0C:PNɠ @ ΍ xn'F6\6]Ȃ;ZoNV֊lh'].aC[b}3s?OBQ1ZDG@E+27eb!R&;[cs<)LWŅH ^M~j(n-GRbǐhNHCrDىx8W\e3`M}\mϯGK" K0 NUkk')c~!ATfEnacS[#a z z K _: QWsfCuc({`GDLA!KxNy"|;UMQ.5ACiZ+Mw#ۛo fZHղܜOee٧#QP_D}N)z1F{V_u94Ѭi.Crr#WϪ*rc^!cq)N{ xxA>(^&!s!c{@<&%]ޘ"D3}X<>R}U/x͒z=ڪًL#-ǀ<k}NL變erI]Ƈ{Y3b&ʳOV$6|t ZΫ hOm?h9r# _~Mݤk֌ȍu169q'9E[r`N9[hR]h4և5ߛ&=KcHX~*HnpT#ЅQ.fQj>Hw}ˌvv!v!f! b/Ħ(ؓXک(Ϋ=f(X Q>C=;}כhUK~K[d= TZܙA  J5ϧr6Pm*V$.]Q瀎 K69_f[!h[t8Ҕޞewu۰zfsiO:i:M-vRS%M/θRrj(#R@ %b1 endstream endobj 135 0 obj << /Type /FontDescriptor /FontName /CSTHYD+CMR17 /Flags 4 /FontBBox [-33 -250 945 749] /Ascent 694 /CapHeight 683 /Descent -195 /ItalicAngle 0 /StemV 53 /XHeight 430 /CharSet (/C/I/W/a/e/g/i/m/n/o/r/s/t/u) /FontFile 134 0 R >> endobj 136 0 obj << /Length1 1447 /Length2 6643 /Length3 0 /Length 7616 /Filter /FlateDecode >> stream xڍvT>%1FZ&4 ))5ƀ#H(% H("% R]J*!7}sy;z~xn);!aHF, KA 1aHc x@<07*05禇D}<`1 XR,% EA hYj#0o*bpB`)@eO z+w"4AB0LRʹb0(Y???a0'c\0oE&& ½M?p( A8@@-] YAW NgDp`DAp h c1@#BG!@ e# OvP4{b(+ NHOO U n=@w[H?3J i遃`.0 PIɀ0/ *+i Ƣ(3, _c :#Ü:pA>lqrB"<q\K}5s5߄6 X!Q)pg_ɨpFeh ?Dž8À$giWE]o+/cx=TM7v1z0'[0d(#\Y:+!o& xQk@'TN3)IPۮ+3m]. p3?+ُJhwעa7iM]I.z9I|I9ZX Ʀ8l=~].oB{c+\}TnD?S'ΧxL[Y!J=mgtw١%UČIbMEaTKMai8q]g=WW{|Ԝ#0[8Sg- ]dŁY?/X.H1ke*𰞭ߚZ1M+ abU!G4nO߹402zN[5t⤼d\'bYfo,=dsαOߖJYr5|duƓ;r~|v Ңԯ`nJQ+3N(THH+l5oaibysg2Ns3Z6Ǣ &٘jS]}e#ǺO>_ c|gdv_k|+H Mb_-j-e=Y/IOF'Uۊ7$"wn }M8x5K?$.(k0\G(bX ՚FQ iPNv!6`k bȆV# yeh@t-.-Sv(UNo"<[4L;W?t+ ?( {sVx6WH"bDWPKEOUzjl?=I.-l#3 4YS4&QjrGuGJ[#ZClS;*gl3! Uݒ'5Ia+nf/)Ow(lYu|F. _LsY6IyY 4G)l.挭^̻gUpTd4(c3pΩ6s5MrgcM̗b)IJ^y۟r\B!~TS&H22[זϔ8TE=]{ HTa\oTN2S+b^+4faoC{7AqNfQ^OD_(?X3o# [F~&<,<هNUcXtc--?Q$C["[HnwJ(.l k39 M1cO}q:U^z!+we94UCeipSYmDY?dNS( mdyN ȗw!6tJLqֿj2sZ}2s'E8FcS0z**$;=de(CwQ Mydž;jx4.(C h{ 9Wz&v+KlMUMp f{3ODw=Cwz5,EC 2oO'6%A78`lm.*' }Ћq/5L>LqT*)!Gl #c3~bt3Yi|ƖT\5ǹ2ſ[pr\#fB"5B_-m;=d;eb:*oeM *N4Ps>ZXcQVڋ†#,X|FF9WʶcA7R;W%Y3Hw;Ǟq1Ի+Wl*vG*zPqzR }3:q? *{}/! W])P[/q1@ol݈Iu}YF880LF[xZhq8뱐bXn~jL`n; )K|w֥ѝ7UEuۓ>(:t~$إX*TEs'i}:wdA$pVZu#kt ZLӲS }!GEk5Gc UWU5;]3+Cָ,?H v̍ʫ{+V\.|#zkC\z*Vs>l"5jg4a)8s$FF1oYx1}JLjrnFw2 Loj$;Q{UkO = }zSFAi*|K÷S]e~1[:<G|e-} ՙޟ1Vw橓47':F *t® hL Lo^~:ka}"fD{:j>?a%8%pFaqw[cX[M:6YF l D֘Qgu|}nGTjgT'qŭi|+7݃9y>ߒAzt+ɐSu!ɿAv,z=ZK\Nްjtm¯K3A0 XO5Ͻ1D^޿L](l;l3^Je 88r$6jMmmr̋ݎn2poG~N@g7,<>%/һvmoxB̵nFϛ֮a$I*+kJ(Vqtv^n'</HPnoߺmzCGx]J 8H#)N?I-͝t[]9X%Y]1+bcۅD:{U$SjBWGX k̑CxlL u$p7Ꭲc%-0a#ݵ+C Ƕ$ ?KFQ}-ᬿ{'W϶PYJN e>ĻbI9w%EVw8/FD4ēַ#k%Ko K,cwOJhY)/ЛCbƵ>% >lCXBSǁP{2Hdx-5-k-ِ٫;EZFcgr\N][*Q Ub헮;J4mf>[ N :Z֯7xUύT婙Z̀ڐU$Or`P&Q"/.zkT,0 31 (^YU) $HmBS:Pe5q2B1:{ޭdJz'=fe)OXkg{|'~LR,tϹ1AJJ݈X%6=+/|}=g?&Zn#t膵ŕӗ8 =S %lT9iΏ= M?4[#=7W68;+@$T$k=\SwDr鞲-qͳ_x.:qT$rӂ`cRYYU^m?h6K3>پJ J\7œg?rj$ҨsW]kK8e2k9a /K X 7ekXRi!@ STh<匥x2Z̸"lܘ%Q 5~yܗgkmkBTäynӞw'_$ EDBJ=ًjH*Z WCN3e3~:x J}։q+(|҆ȟL]!c{%c~7CX4Pz3\h)yc8yOLR(ΣdD1lw"(~>-atDFOrdr:׏SNPwrpQ)XڎIpLpnB%L-yBO6,9ƠO%xoI)caQuÑn}|\DZP;x!LЋ]r Rz.q rvFx34L `Qts- d]wZ9sE_\+FWt]ՔƆN4ΊZ4$]~ÛIwp}oY3M0%mwUv3d LkܲjO B@J‚lMuYN)$9n]Iy M R&',qUʃiMQ@Sf2% mWJ0j)Ofӟ4< 7ސݾ))i:` >ZC,x=?0DJ5\ckKH}H.NǕc.hǛ-oJwX|uJw"l:6%fQv;;eAm19=^5z:⫽]'fC4N>Ɲ3iō|9\@iPnό@R9 w!骨B6E#TsLVlʏ~?CA6Ǫ MOW}7iMֵ"ש${. WVc2pΖMV#W7˸bMZ7X뱏 UYHRy5>j-GK62<~Xb] ,=75Nv;ؑ{8=|&jTGf.5lҟ =-Y=|2`̱TP/qcco3^Qw[VLhBe"ml/$0^3N2Ѐ)an#:Co.yPe󛊜6ҕ_> f rRUv\Sp#!'\9~cz+uAץ$?uQ 3W̟/]֣y endstream endobj 137 0 obj << /Type /FontDescriptor /FontName /XNDOVD+CMR7 /Flags 4 /FontBBox [-27 -250 1122 750] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle 0 /StemV 79 /XHeight 431 /CharSet (/five/four/one/three/two) /FontFile 136 0 R >> endobj 138 0 obj << /Length1 1447 /Length2 6638 /Length3 0 /Length 7612 /Filter /FlateDecode >> stream xڍtT]6]%)Cw ) ) 30 "%" ]t H77Z߷f{ιv}}ʨ+k )^ @^S!@@@O@@~xF <d@b V& PsBPLB@ ( # .P4j0( U ; ppb< 8 дB8'XA00 ~~OOO>+g7>1'p@p-']31>Das}t5LmA `,@ s6;¡4>nc\6/ rzZ҇x/(|D5>L{`Hi7hP_謽H4󃂕y MvaHux=#ܲ`u$ƞS-85+:Cc9/cKmLK"׶菐o?p jS8c/8V)f~]s!H3Bi[_ȔN:qI;]P$J@I ]|A!QaB׸4H~ vKb2#Qn9@ot*^.A6y@֝4=JZQkp)NfiVM9rvx0OS9^xAYLCDVW1;C jģvQ9" QvۜN9pcqh+% +n6L!~hu~)ۻW at %Zq-͛xU}U'vXa-eqЇ_J*#LP<QJ.ڙ>B$>_3B~ Σ!)lp!= $93DvxG'b1.up[qR6%#֔v&y<òTk"{gII)6#tDF< \lM N] A1^;XhL^a%䜫W]g; H 9xdk;yA߸90/෬{vJg^O~ƶh+BMo2Cqi=YFwLbBY=90 ,xc |͘L[^us-\n{lmUs[Gn1]xh9&|NA]m |#V!"-!&cċv D7[b]URk@}ǴGp>e;aP¥ d{]ԁ}͖nw" ?إחqoA;]?N0[9]N&*۱zpfAEa w}Jj>RBoaE,79B֜,-jAo_u8([?J6ge{0 19;J)܊JgS{rPDN45ȳaQߜ#p_ulka8+.\ oBjB[Ŏ.a oaRQ8CF,<'/qg/ŇtYɤ󿕵i#C)2Ԛb;xs!rZѩQ5'h$w=zEO~:: /!uMRԷ8zI.-/ra1s<ŸYY}˽"dk{׈wg`ȭRlg}LYV '_Ysi>/n%0Y~MoP.pޅv&ɽ_λaF e32=[f߽' 机$vPA`MDEY瘳{<55R7jD!O*}z>ЋwѲ-圏m^1OFiPSLӲ /#`)nlh֣rblSv!86i7bNE&<'VtzfOpz .K<:Ojnl&I>YUe9"e5q",(a3UX#glݠ)ۣƕZM+xv٫?Zfa8˛y_W[Pj /\9y랑eGٻՠch~jyg|QruŢFQǩb*a4iTm XiA|3%{v9m]yL r3 c5yzm gvh #17~lW{QX ^F]YlZ<905 Q0* ;f.} ʠ)MeQ5r#4kfbl}i'GQ/Bʃ3 IKBҳ}ؘ3ddn =FYbIW?=Fqn/:~.Aみ@J釬s_gJcȉ ^5΂y%:ߌ_^N*orK'NE&[\ Pв/(4o' 0ѻ^UF1&<*-3 TҵbD~ݓyߚ̀6AWoAH1V{N'rh:=@p|ՋV!yOI gLߜܘЅLۇvO94m3$\da, _(*z}Gd/R:?a>Jhy7جIJ["UpU[SgՃ0gY?<9fcㄲ{79M1סò"(ع@zD|ȋ%c4>Tz`8wREykjt_KDp'AY`궀+Ȕ..ac`fS'sa'#J}QS53&~C_ZLؔ?n161#Ԯ08d3~64G6r%q֦GMj[RĸQFFI/bX*_K?. d$jƾ1;!Q'Ԁ9DkƲMVjn˹ڎvDuz[CΡő3}U0tc4 @F*iv5 fĵ$m fxj:83/[t#۩ wR=`ڭٍ U"|Pͺ+K"`Um7 -tJQ]L5u,l&h}];ĭï~I>Z Rr$v'EVocDe3Tբ}ye!5,_+t0 и q2LGO;z%Ws "T7G/r$gֶ%,]QLIw9F\6a!E/?gw>x+%3{ lJ:(JԀ%z\g.`x\d*fֆ`>NQ pr[W_Y$HB̜G*iKZFQgEdf筷'!wڐU*EON G'Y1Wb1_RYutwA*Nw,c==.e%U&_tӠg{pC&4^J' "57n*^ v~kr,(Y;m;R"7>}֏*wG,(Fo"-9j^GKQrr#X; lC 9|*9Vo.qIdyt\s&EVce3=Kk׶E)/MQ{3l̳wbIrݕ_?Ap4kp++Ld@i'^$ 7~:~.jX*_=^!]7V6ӯ2 /a`Sa>2]19ic\8EKOr:P|WcOٓ}+)C ~ԫ7jd., 7k$07| n&l1=xE!"UMey:b7#^yN$W=iKf:"bxN2A+T`t@o1#Gqf>TQkTnU믧WkGB48T_3E>\pd{4h"OJM9ۍ+4J%h}&#>CB LcF :  `q>␮]$8e4W]`;p΢ A԰su  cG*\Lkc[-me.SF 8/Էp%gȝA 裘 6Hγ溔CL#C!}&jC"3v]ņ;.Gv^p5ޙN92w]2k[rguʹQfCED_ek +>ً<ȗ 9Y173Vr0^ ;&H.>dp}T"' QU)J|.UDY2j|~J!r_{C=T"&B2P|itEvy7tfA%;e~E yU~Rq^<Ӡ=wEN慚2,c*)53_5i3x T<($I Rj'O<(7zsc/%,O,nŰ:n^R;zT :Q*&LĄ" _47hi,,?~Fa}EB= endstream endobj 139 0 obj << /Type /FontDescriptor /FontName /JZKXYQ+CMR8 /Flags 4 /FontBBox [-36 -250 1070 750] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle 0 /StemV 76 /XHeight 431 /CharSet (/five/four/one/three/two) /FontFile 138 0 R >> endobj 140 0 obj << /Length1 2458 /Length2 15438 /Length3 0 /Length 16878 /Filter /FlateDecode >> stream xڌeT]׋!ݝ@p܂ ^'1]^9B& #8։ ",`bbe`bbATp P-@<؈8 dNor [5`ab!ȁ jbacHl" ;w 3sL@mI;@`alh 3t2ڼe46(-N#+# tpj oh9J?*e&0:99ۚoR;?ƲCp+Ά ;C[w [35 .D05obhamhfwq!%[ɑ. FhW}@7-7651g;FU[ {gDef@';`9_IT+i0At4tޞ*!03L,F@3 [@8XޖϿ ߃fTUP 7'=  xo)oK -SlMAx￝g=s=A@+abg2~v:[5YXXmގDv*TmM,mVXlD82X[A=ʿ 4z{8 o71Kda:8#0 ;;dMno9x` r@kFD No `q2#Vo`ޢF\F oE7b0Fobޢ: ["3[l#Cc51lNc8c/bm ~%%]_e4qf6t oBo[5oô6 ߅YZg7Ifڀo7́X,oXߦe|cwo4Xӿo\۳w*XoޜA~-ۛf6{LlolY;Q۷?c~#1_sooo9Wdt2w1\A8{2bw49.7\wo@R3_ o?@71<Ș7в>V~w3 B56Wy\2,QsjmH9HX(NW+nNXwAa' y'/E<#դPak+WT+P(DZM'w:1 }g%ύ48yƺY~wv߿+[!sTn8M,?ciRеs埘 GJ7u?.2Yv<1#I}1m1=j@ #;8O"DdA=|P2H:nW#NO^i.qiaOEZbH ;c c]@xE;I>r 9#&j薸~`ǸoEW뼷r=aBn6LdїeUPK;_<>l>nR4,/[TOϐg$[z^˅F;S*hLS/hc>ipO0i-1͡F-گ3c{;]/<˛CF€ 7HŋM'{#Ig=Mˡ^hh((C<}acHw"D#"qxF ~*g{RyK3®:[# 6 ]+jי(RG $4FݙA4sՂ_TRjEJWc50V['QtGȽrc`%cD6m2c#_]fjzq~jXDf!B@:G^iTީ\. v<( NW f=&ꙠW0o~0L%ęJH1Ns7x4$kzJsQN-޹F򎮲IB˶Hl٠wt!Q!÷&jf?J}O4[ JK/:Hb[mؒKne=l _) ,Iס=qeIu'}By@<u3Iu`kжsB/6V 9POgK0&fmcި;UүCMv1&7ku(H[yyKoҕ|Y I␄c̤m@RoQ.dHvyvƋk4{& dxWh;!>nPJW^NQBx S 60._Z+|V"4$z|<<ܘn{"H@Qd$F'eIǶ-R+ad`(rsUA+@uت-9?;߀o,-"|(+5E[c <,r"ުtrq asձ 5¡__(ACqmHۏzDn/H's} ˦fL7WQOnA##Elj ֈАgj?%Ρ8c>; BUur@K w "uo#p%dV_A\%ZN l×4>^*Z^!> j|Ur[k .܏TzхQ4UrqS  6Û5#^83Y;OI3p0wzx'(9gO}s2x.(<̫V'}ĥzuJ:1'}2T7)4Le!V"Y:t過_ аFstR$<|ysrD5L8SIm\ y]AʎϜ||V^y)]F4|_53K0 s67Lxd0[E"b26a]}Z1Gyc:7+4Ϩ umF4xZ͙\+ [l>/\s3D}_iפBVx^uMs;=ͅjFy$)/\f$ 3A)i3zeb<7բp8Ch.ΊSYT2geN_~5 C\ uI$ b"_q,za}ڢnbo:o͓^ m)?NX?·>۝:<&\$'8íHv^knmPAyAO$Wu7Uld2~*+.xjɜ&l=jd@\PP9$db ¤R壂=D GGw8tt<@7@KeA%떫22#IwOM3!td3WΊ> xݸD<""^Jl W~c+99,"8Di aS#Ht+6i~|=^p "C3Bwї Bӿ3V;qS;/\Nk'5A y^Zs؍Cʉ:z+gV/w q4 \Gb єB0KTOA"VDj|Ӊ` K[ տI]o(heE_z5~;0.'/>n\N9PBpLZ+\6 ; jꮗv `R%A]ϦTI⼲Ů$.G-m(/[L e 1k hk;JB}PrP&kh'.G'L\wj ;(G;3Ymwۅuv̿Z}t z6f:-U~^z3>F E7mKy8 0Л{cЪBqc)sQpQ|.a.\$q*k"%^[ U$qYjz[|&\+QAr]]#,ut秄_ئю ':ʽ!4|3'.925peYIBmZ{0 ϟ/i6yH`/M 1Z#%4hEN6mU˪`eB|J]-d^gv4b\|Jſ%-ڑ )| s~Kbl+O" ɳ? Zda0x+u_$ˈSinȕuc*hS(O,Bwd؝P$:ٝ]v:Ʒ-,bF73+¬3jxY B ~M&twI97Z֞ؾ I翵^o ձ`Q|~N]U#9GJKukmgȝׂV{ :%悏1"#pfY{kOUi sRTx*=:U<8[]Y͡r!,SChބ c$y\8uS|gzJŮ[?!LƜ3"mJ@?-'r=TÄ 5xS Ԭ]OJG:݈", f -K_Sw+B%K籉 gYDýtg׿ nBv6>5Eӫ%c\:1N 蛶WsnZCj7Wwnʅzjm Ir%UZzÐs\?yotFx)\a V݀ӈi'SJIl=p{Rm;Vg,6Q9 tl8ȸ~|ұkylp kӽqzUxh#ۿN_ݦC KPi6H25z{֏ٗT얆4oo6Y.BF^rx?h]!`'3WrΥW'7āCg̐d9-`ٵ6ɼ`q1d ]o#Q5;H"$ } Ի W}}l54Zbi6!|12"fPrhUD-D]N2TKz4 ٗ%7zj؋[μt7f  s4]-~Pbt~(T6c4k{F4QW_bY=CQ Ev ۯ(LYcnE;jl+' _ ~$^EP]6k݋ng[koV<$wzwuZ(*Bv^C#V驓@~d,{5ĀqmSA Njd%4U\~n4o@f\hiB! pSS>_ .ӣSFӪ8Q $gGڑY<O=x;cRVY:;l`GtZAfyaw{@kgɺqu#+ciMM/lN+]᪩#GȃXgղd x5M󄜸.EQԏ}U|58B]B hKlj ı?'+2<'R.a.w`6Y]1x"IKA^u[BDFAq9}p+*1 p*7ve N|44~F _L--w@yo\C@0~0ꔥ h,l (}[8r_ԙR9ˎ#+q_ytdG"&K}hGDWgv}f>\yzb0MɽuLr fNz@ 7\Ģ%^9G\muAKH[ϣ&Zn[9Ԡٵ!at\5'DlV#QMxsZH^=uxroJE)|6S16#(ni}C;Qe8}?gSp0 iUͿhO.yn;A >P-T̫-=z͘$Î~&Fa53NXt6* N|<5~jZ Ƥe%3LH$c:pi]Eq5F\unBBPw:sJ?^. Y\2 6%1P!z"G$&ۮsP$ӻL_#ǃ¬Y ~ulߎ3B|c%~C*8S7!JEe`S LgBzXC@x%si|e͙偳,6g0OҍAj(xũP 6yVo%KˋiU~mܭl&Hp<') 8Tvx P$#AhN"\AܨOoOO5AqH;g5İ>)kK?,O&xߍDzLf}3hyddmaDeHO m@4Dn*QoM "lh28De[@ڄk>dtڬ>),/@vA]ڐ>CgA'VAL!7j1ҥ^^]FCvלixR!31ު%-$0W8CE_WJFu/^UJ_?s -Ňɫ^B(|j.saYG=W8m>)H58ʏ 3?u VI쫢x!, jX‚)~Ẏ~RWL{*k[\ p'AQ`ʃ~iRR)2\COKFeI~{S&ϔT$ČJnWƇ|g,EUu3?6=,-ʦHC'Ĵ8`xL>MjȫtuBؖYC_$G_; ڬ |K1 Py")tuM q41yhz\};q|n I0_ (QڡeMVp0ƹ>t"7>STމHθ}JiSj5cO3qP}r;|\ϽXQQ`#,Xu#Cف] d\Ð|zߤn8$fohWs7>BTR(> *ԪVwPA!#GWQ& ռ#PX&H*ᝧdj6Z08e Θ".ݸuNU8L6;I8^}xw  "[lsvɁphxXrWG [=,Y.*"ѩB'Ry6{V&\j*H)`ӐeQ.!>%H[ [Dg(m;8|'鋹*J~Y)e5M)K_[誹>5CTMfla{?0;lM%& eJVKO:c֑x_ßv:R`֍IQL*)uռDszyoݼuWu *G)G:kj&Zqר|rs8_7+ T*S)’Ik'wD /´ڬ|kŸ F_ QۙnK;&v0=p6v3jK"\\Dg ff/D425Z3Rp*`#O^Br3S,Iwx1UGQfP:*Z yTf u|ϤS&!ތDRxAc( ,f9~-T54ڝhg3NPf04zQ#!9 QwN?E\ D%CM~16/%rHsnдkD=4j/; OAԛ-"ru_g'׬h^8Syp`xo8J ˰X+H~nfe3l鐴XpB{ Na{Y>&Z^{]%-sن GEy6GV%Dȅ3[S`}p$[Z&Ya^,{g+l]W ~k4/ؗ3az{7$ ROW.@3v9ea]it7K%T EBB= >=,Ea]#+Bfx aXWi|"Uo5(41BC{Al2x (uƈdA̲Er$ၫp@3/hj(YC{HRu[Zy{) j7#P&]ABfW!"Z g^m޾6™i*V61L\q?H&/].sa/Gk<&n}GQpf{l[P(\oF_ԔMLJQlr~FJ_6F4K҆vJ>"hhE6mSLLైpEakY0enz^X#g6V: /#l]s}0L6kb z}J8?ēͧ+K(,,֩%r.rTTҢO`Όdbdr(6 $;y@O~Z?N%3o 6g3r<1C(anx J`Ž{ a?صn1m.k^"J aIMp-H7P^:[k/H##Mіh<m(Bp{tƭcS?7`'zrT7xַ 'IV>OEn:4iUʸҮ@} O!|T[D_1 fdijz| lj>(uOC,C!*EsyM?*r'0#VYZJ-cs;*ǧi^4Vݚ\gGљ:Q-xm9\Ik"#2`HG4Ti*K H"{Ps!ğK'/{6bc4e$/NuBL}7SiA0m=Dⳳ=Ykt9le^_! MH 1/x]d]y,|5"2oM!!͋J䜓ҠeO mz~c8kQO/re7rhĮ^dzrŲy/(L9Le]K]+OWƗqNJ"!Q-yN?OX/UdN@8ng)?vqd3-\<?y}KC8J$GNE`)C& D% St-O1hEd6 'D8<ԣ}ATQR#DSu`La@=r74>3c]rj$Pu7 #Rv g`8?ș (,zqY2A.p(Kǥ 32$vwJ@yAo?O[.@ݮ6WѶC,XM&}ΤGC1\H m *Pcvżi 鉌6MؤVܗwyc1E1 eOXdc͐S4Ȫ2̧wR4^*i:yKfY.e¥gNe8\&f< %v=X4w!J ->^7I[pЦb/6mT6:h'|e&ыvxʐ=Hx57vfUtN^*ILGRy1]#>f@nT:ړSS}VjqiG["O#4{ݦ69LƩBG/(}̏r׸&W-y-ԮhR"Yf:sb=Vw.kFaۯ> I-L8i g,a8sDK;&5},6\WC}JZCt `+>"9L"ċBk35nf=,y8}]Ldi~0u}Kw|Y Th6u#?\-8 NVTlV;-TtŴabi15m?81IB.b#nؗK&n+zXUB0T3\dGd qf|_Ykrl.pdleLx 1xDakˣ0B{4mMcw"%r뗃w*=;|QmD9OZBQ endstream endobj 141 0 obj << /Type /FontDescriptor /FontName /QAJLOO+CMSLTT10 /Flags 4 /FontBBox [-20 -233 617 696] /Ascent 611 /CapHeight 611 /Descent -222 /ItalicAngle -9 /StemV 69 /XHeight 431 /CharSet (/A/C/E/F/I/L/M/N/R/S/T/U/a/asterisk/b/braceleft/braceright/bracketleft/bracketright/c/colon/comma/d/dollar/e/equal/exclam/f/five/four/g/greater/h/hyphen/i/j/k/l/less/m/n/nine/o/one/p/parenleft/parenright/period/plus/q/r/s/seven/six/t/three/two/u/underscore/v/w/x/y/zero) /FontFile 140 0 R >> endobj 142 0 obj << /Length1 1401 /Length2 5902 /Length3 0 /Length 6856 /Filter /FlateDecode >> stream xڍxTS6"wkEjH $*IG^#Eқt)J/"={ߙgfgv6;1#Re]cK! M(o;> EGm*(4PhyB"!1)!q)  J DxHT콠]F+#}=N(to\ n8p tQ`7tE= `A(qFܥݐ'9n>7 0#^`G/={7jg(/1#!pG]`w9п l!Pj:( hC"^P{5EC=~H@Ba8 J>fU2 G!OWOs]o+E]} TAms@I11Q!rUیp@4PP@ts/$pPh3 ;kp[,faajJJ?$_R _'7V{GFM8&G\Ɔ z!PB_C;_YWH`|=ətu}L0.5^jNmW0@cj5`q֊3 i>F du!}3fI{#%1BFn0?6AY W 2BɦP93&DUg5Jy{=֠$TM⻗bo}ѫD[_-;l%-L-0P=ֹްn[VH x <2cf4VM;)=jK<Α cVI0HYZ×Қ@(5d / 2L07^@<+Ѭ56AF՟+"7IAµ+X4ƽy}[ԌtVAO{(2򙻦r6~5 VJ:-Fh+ԬK7,L Tn3C4<]jOiHcN˭y/>QV[sz6m/#\Cg|Z[A\NW2xlKQ!{1QsHϕ t!=)v(dx@=^1 8(<z8aU}U]Pa/K#,2Lfŀ3ArW,[#iYÞZ;\<첁2pC8UX/EX$=S=@kX֦HX  TPv|C$jge|a{!U<[ GܧkR Xzf #<` w6ɧ`{S̵Ɇ5NcBkO |Eѓ,1%Y"/r^MVbDkE PBLl(ѭ ;|hyq%^E(Ƒ3;[q>m~M*tS`X}Eٶ,L"S?ګǶ hgA2`epb~qMEE钆^ L TM)t*CTIcp9~%,cb#%Fl[ڤ~vLP]Y0 }?KB`b7}{jt}E:DA#MEwN3>_Y*)ȹOn;wcǯЀ $3ù<˝<@;& p3o|} ؐڰ܋jt4;a#NTw 7N p C̼ݯOk&7< 5qɋqRqS_j(E݁ysF=Bֵ8;r@qKpU],t ߺIP:u\oVfXjx6ޜoţ@:?gH ]@)W7Moz}Eim1*[7=0j=U\ƋnxFЪ׸)0 A1F4>+K!]ޮKQ4LBxPޣP6 ƪ^3yh7Y@@wO_&3Oh:)&&-nϾ%w'h >eFqO .>.wp.y^~!́> h6#:N:9e&-;WqBDq!q<:F})F$d[+WʱR2ю1s%ĉDbӇx\!rPzgo^_R )XK^Uؾ0l2m>O`E` X%b1LȤQHȵj4CPU=G]qQLK}_ ˶b/̽~{Ōa*T߅תT_:ПqNcA$xj-vm vdK0B0){%S8S\y)_pO.)8iXh`.5s->8Ud\?<0kґFڛ3Jwtc-*=BoaBbuq盨Yd4vAHtϸlQ^md2O#v*qh=\΂[:˰8'봙e;W2zi%G(ƒhKVWEM(njKf?-3Mt88Y<6 ɜ  uk]LStud?w+y@D52}92Y;!,]eK_79Krngavn$Xi/]Ft2?vc]~54Z+rXx>!LT^o.&Os|毚B9\;dv-Tlm˙{f}i-%ymp2r]$;3̰YlrJA[MLRuMI`U$MY䦝'-3۝vaj}E- J~6DOB؍;drV{^t{k֎}ɿÐ)Wȁ\i;l)UVz<9R]=BM-9k3>gb{)KA1t>W~QAMb-RIA;0ΣKS/|-{'mM)Iw4(ɈJ?PXW~΍]}#ז9~*鮮n;~SC8/ O"z: &TȎK'y5O֫}54`}=[1m'VqAu\q%ߐqYj'^|=8!ٚPj+AVA#˩lZ">glj24TOOp}Qɾ P9_-JQk1OQ{#AEf# դ%-5cL/*|> )^{8%F=Kl{ArsA".aa-קU.jTY*DAu!9MB2]@;FV]ԓ={~pnuՐ/d&>xZ'˟GDn?ȺϤ]ѿ]SELkR?ge3XvS%275(#OBRfՖ7HW`H4&yff 7 w:%%߃J[H16 +Y| q5r-) {yXJKL#cZr^oYB貌'!#ȺGO%c iH)ɫ*^'o}֖'E{w IG:/'8?g;Y,Y}yj>b֜7NJyq gJ6"ߺy4y_aj,{Ϝz.4_Pn88_~t]-&}M,R;7;vlwe.2xIQ =uVѴZ?*u5CWvQM ^8a6zOt(?y]5? KA2+Z$}g"檟.e (gtb 0,(⮔?Rj<8C"}J4eԴI76n8m{ 6IƷ2lo,k\bX|ާ{XT ۥfwd*0E{E$fr7G?$.iwVм@:`Vyd/d#/{vdxe)b7XuynU߱04sVtJ}cW)cZJmǬᛪrcv^/jM@s8G`XVt.U8ᾱ(/Y)OGd*/MYS+;nя^|>xLҭͤK& m )5 z'mɆXQī~t-C-/|O&+W#snYN̲a]gE:)qG('5>ޔJUt +^ AƱx'BEԻt<~BN݇=cY3.8=(YE{;̾HoOlӟ&1*i$ym؏w4qc|*?up|'V;PuwrW]0g"陰>vƐmAw˕ו4MK޾:dكN:< _ҝ \It~^$+ȵQƆo]o\Pm̈́Ieu!ZARtSrCBoSY ۟|Jϣ]zJ^}0A+'NfIx~xOQ>.+=FhmhziL9,/k4MumTtG剗=T&3J^Emy϶L;ޝEsytp f|Uyvgp_oðwS0r:߼Wdi|IYZҀ?בψV~rKXqR96@T$Iۚ ?Y6َNnj[U/(n4R.I9ϤD*Cd= ʮ> endobj 144 0 obj << /Length1 1504 /Length2 8145 /Length3 0 /Length 9143 /Filter /FlateDecode >> stream xڍT]6  2(]%5C3tw H4Htt7ҝ>Z߷f{{k&:ugps|-VVpsqqs21iCLgBFd{*Prx rs ; dPK*@  pPk}V 6 ?gP#m --W V$Qtss; bl7( A@]!ߔj`_Ըp6Pğ- ;>f qwh)^:B`Up:G2y@a+=RN a`{> ڃl a uD"P,R!'uXܟ˵`^[VPo.@(ޅ_5 qss N wmGA{>^pG=  rBHg?pyxP $b b}Pw+{2W%f_W QTSURRpw3>/xqw𪃡aVp$Oo")a^o ⶸ?)]*ݑq?8j^.POz?Zb uqߨ"|?#0{?EA!P͟Z2{Cau8ݹYݿ-+#Y- /9 WxϪ%\08>p`w}<B~2@?LyA =sSt gCixP w B8ض*B۳o#zT"G|$ۧG]>-mg%h|{BŅr['nlNߦӷE?}bɅ`$: R@ApdzKTT"#PbWԞA^ޅbNTZmGm?:S+&6:e)ް7#3775?)I_ő|nDM1r>I;ϓRYR"O**=#73=Jex6")c25s0N]kgg0*9)dO3%3vt9pYEDGypt!P7 4!Y[W%ðh!%~MO'w~ndO+~xp}q*jVc_#k;p:G*`{AĄ.:[w̔p3$ӎ գ KL@Ӿ|بkE 8Vz cm>^ړ[Ejǵ|_`N4ٲYGKW3mЏ6x̆!+q*hd6]EuT _΢Yar\M@|Qfl<^-ȀaxэGvjY4f\VWPlu4M0:>ЦN ,bx/O۰$_'s.1_5=|h4^ OGR|[V0?<t$y)C5z*-wߚ&)Rد$J՟c]26+ǴᯁfX,l -!@-tI i.T5Zk8[Fpcu5z65(s-rsm?xKVH}Oi*.cv星9^.Йq[{xw5*(.z6߰XBl>Bic)J3QɈ)NMR>b^G;e7tحƛ?opPqi*1U} >8dWv7 #IUT y4QjkT\Q4QIU$6^81Sa`r PT4y| A90gͥvp' Petx9Fhd(>YM#A̼;9 FoT5GڍvGOGDGVMU$BΊݺ&>a-Y c7 DE}ajZtesvi͟)s:})" &0@Dž S!#CYܢ7KMHsUy𺃫ȵ'IDTl5K Vix7wۭtU5,V]NnMt+ 3,No9=^xFEc`}/gKE˪գwt$:5y W֝+H%XL2 ukw&Qȇ{^mDRW+g{2Vt+QEhB m8"| IOmRJiցբ3DGoLuPfu$yn&kq2 .?#}m]/@Oj8 O9].lxpJטUZc/+(CPL`GR@M3xKXQ9""[kg|IWqĬ qvQ{W/P{W}2j1eڟ(cfQ"O? ԻmѺHF~XFg,|"r#"jM Ŷ '05;/ZRtxŞrs5)[3qЃQx[ѱMHLx Ĭ3՟)"Vw{V4E~sdmO6ڲ]g xBlڌ"w4j¼I:ww3>p9Bb7AâVڏ] i+k6۔یVD3LGTR#uʉ~ac@x 'LYW&ah]WϲWP@+@ИW^msɖF"LӇ΀pʎM<t~ˆWӤe(a"ռ*&mh&d|!%oxԻX~֮fuA8l?mYŜ,[`zMg6oC^v&˭ҥͽռC1]mhh#o:8.dϴ+td߂C\_6p3˞}2k7zG#Et"1􂷦s`*d2⹯8^{.SI|av8C/b͍ޯ'z]'_|<1clv`IE7GaOwctw8NJLy>OƮхwڗ_<(SM?c[3-9cJKxjգBRBl_@y;6|.HϋI/./_fN$~&E8 f+r30Vp%]j֡{K{Zc a>aZ22faOpeћs@&sSkO"Sk\f8| J-Sz<}JBMYQҳeŭFGսI}:=+*zIfiqŗgJ l4h("}6,8/VQU?j}˵K&}9=I/zWmb۰@zR\vkqy+Z{eیf^8ӼKgqR4KMӳNX'a7^|)'ܔyxĦ2-+@ܹ4G5F4)6z- :G|9i:CKW[QYJf[A18JÔ-reiWO瞲MtbJ&\(p*S#:CIyW Y>Ԅ_m\߼te}PgK&5^ʚ{-5AO]rLnoۆwh Idc]66y2{czʡL'ۊkՅfowB_+ѳdZ+l%&zmKH#y7 _:ذUj/m E0mx*-Ƕ/) d].5N3c{"%vhVnP/DUªʡ"*<~fISh15JQ)w+ۊ_k;})}oU1·[.xYߝ°0t ë,0|0ΈPGh}۠2f B/O]LO; 쳾PӼ(4 fIޒ%xS~ )WR)Ä s6D{VX9L" Gy^ւVqi|˾y*^u 1}F5XMMxYhB1MPnޠ@g(Q} qQEo}$ڼw!i^m@&~; ݃-r^RlBU,C1v"Ț B84;t1b'bY84N笟t'huȃSScH$ .jѯ^wĄŠnOkqZN>N}]$:# : 7}'rk6$m.i*`/?}a1^ }Q=F0jL#=[iNaRF4|`S@,=Ř8=+`2RYM b@Qg"A{0aijyGՐ.z#@`@Ba+VGl/b;"vd|yL~ee;xo@PqK ]b#rfR;ZS.-` qt ??yt<(kj:*_xC|?mG5y5XLUV~)Nˆ3HB}wjQv9ii31X SQ'ҡ $1JX``B؀SrG~Ƿ M%͙ߔrᄲ'v{v)CgsXž O L*۱I\tc賺N?jƻ:͵'=:D)94>g?fH*v?XI=3s}Rs2낼@+u )`Ӂ~ Ac֠zڲ8TB,94=[/tVFf7ȷۉeaM3Jxt^׽7B9W?^,{H`_sPvl3ےSCR'W)B-Lq2Xg6DS~ʙhH80I56AqƩsUL!Y ƛBw^$vwԙ9Z%S`(UY(qkE<<9;&nz݀&FolSy'vXN*{!rs2o*qv# z ru|11ۅ>5[sArb@K_=6ا{ۏxB樭O0X#"Cͭ2km)Kd%O1⎰+9ߡ52!( Ju ~ڇ| p%Ϙ~vC3_4r֢  1)(4 8+ Mc!^w% hrH ј< ͍\ k'DtΊ޵!)ͷ+Ek;e-<Z?EUOZ ;8֭qxQvGv49Y/zۜh 8qi3"3]lEK‥zP9=)wi16d-3G׌-B:|O0ϥ-,Mozυ#6B-qFʌRNf#|cGv,:بZ3cZ(hHDߗSa"@I5#L k]x0t!mܥ/EξoAq^O71T̚]/$s976FG endstream endobj 145 0 obj << /Type /FontDescriptor /FontName /DINKEP+CMTI10 /Flags 4 /FontBBox [-35 -250 1124 750] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 68 /XHeight 431 /CharSet (/e/g/h/i/n/r/t/v) /FontFile 144 0 R >> endobj 146 0 obj << /Length1 1561 /Length2 7844 /Length3 0 /Length 8870 /Filter /FlateDecode >> stream xڍT[6 Ht!1t# C=33tRҠ ]! " ݍo=k\wkƤk+oH^>$@Q$ @A\66C A%A۔lZ0(@ @߁0IPA\6E脼'ӎ !!G:@ lN`v6NH$\ۛ pxCN}0 жqE `A09 m<{+ EܧxB&@g _ٿ A$6P_qtT4>H w+voeqc6y==ÿ!< p$q͑wmV+P$ `}p]0owMo{AJܛp9 (.(>vN8~9ap= p|GxHOpp;$S vߟ`ϗŽaPW8b~S=#}GQSA B1 gfUTA`?IDR_cڰ{=(?RU"OW?6nW߿"쉼 -@7)ρC< Bψ<^|@? l A9㾇+ օ! , |gr ~2f{ED66{ g|P>p1}b~ߦ?8$'?_POu \ؿ0__P_yzx_H~[D`wzf'\r^-Oͻ>$(L{2צ^űPAw%]Fc I Ug#$2MO vSk!#'r\<߲U?TU8cq4 `Q ᣅgV*ȏOXGrC?U/2{EVzgJyP!˙;;pٌ.Q 8Z2KГN[W |A;ށkp5!GIfa6+Cym\U"i ڱ|S-׎(eNY+m"nڢ[?.cŦ C'/\1Q}~@}7?`P-K$5 =`.lVj%GZl‘K4'Jz&2v4¾%`~}M9@ =su:\8S1Iv|Y>49)0G@izc~DIHFOWX''o_6VAe) YؿC&^>~2>(x?*6|FJ{! wcYӞ `sqw9KVn|*88BR 0vL'7KH~br%7S4B{1- 㩝ڇ8 oyo_!N3ixLN4n(QhF,aށ~X (ק`Duyv'F2ů^H|sAŢO@ ys,ۆy~⛝ 5՝d^MT%Z0<|%! VbjO`di>z4dгwɥ):taԖG ''8@&-ْ;e^ܙVxQM1(v{M_d?m_ĥzul>8.*f>G _t8AON~$ݠ`6ScJu z^ҟW&o=i+ZJc+)dgG}Z~(ˍ]֓*$[iq6sr\4;b}6`f+4-P <{63D*wlFe یrQ/ȬqD8ް8F^iͣK 68p*$98s >*{Y)z#J7PK> Ŋ䇯=_/ s c:B+ J)׆\΢ά Bhx~TV.Kf_.GVO40$RX߾x&-o??Brդp{6m-0p}"Ѯ}rp1~(4J-H gwZFU3uBfw˃*`{sMXA8VSi~R7gV#pe ЀJ3X߱>t_KBZ)`LnGa8"K97-Fi`]OLPBboA`G;Xktأo/oUb^r;³wn\ƛqiۃH`N*ɊQ`g4aJ(h%2z>Nj韧zpDV)'a{,hE~RÅ҆sY0^V(>k^((PU_<jŌHGCE#[ݸ8}F45Я )F1hK͜/EM]%M,Dͧb)?18X)rlBg+GnO>"ҹD450i,bd#`FszbjU1.[ab tTֳ˹dK$xN"C#hx Z^}A+%.#ov\r|N^] s p<-v(q_=-] +V-9B~~mn,V K%!JWKCF4:broKQ턱LQa}gḲ:ڦyQ6["P=rVߵmLD<LICcѠlљY;F#J^gu⟓234whkTĹth)4QgF%y)xh}CD߭|?KOqֳ,=5kQt9PԮ1g{9mRȏ5nޚJ&_'{tn{xd͵y~ 1"](x!C(mP h3ȘfCXzU+̌6k`A^ sK$&ӿ%Bq*eoB􇷥r_D┟I(ζPDBα81ld$?d!zVKH7Vu+׍ ohtfR\yJE|&t]J6ݒ",]2l&|&jF+Kn VWn3*wBpN}3:#P6ҹD`V 7b- .P؄-;|&XY$[z+֎.ֆ.lBIYKe  FQ`B[曄h7tIɭ쮾~!_mIؽ7UiYDUP%VRz7pkMm>P>dHo#ѩ:Mk@=%~2(>eu/ _%wlQU%%Aew]N!iHdMbw"⦟hx2jسIDp; h |FwGؓS>5>Zfw:/ \ܴNW9T"x]YC|KZ .CN}< %5Zl7 ·3OB7F!#Y/UzeY'_eߔ*|{{7Cu*|w~Kx)تpa*L~p5nMCl8Sǩ$el+g8Za=*moeƪp璮d[vYcѹ##v^;6벀{{I_jt/m~"^jv f.|kO#%!ΊՒ0{|ctr+ y$gzx`H*S_v[牒[DKdc Vbꁔ rf?<g(3ޖd̓%e1? Ie꽖0I wLȟ蜱e,㧗X p13+膤W(Td|2bIi-avS+s 1n>T)tUe3cCf!{in9E1n֝/ur G$\X24}0&>) 'I2A*#{ !d?lt`u4UpZ1U9 R gU;5?[ h;guhQ`yn%۱Ã^[)X[Np~tl[WqY}2X]>F]fB[M\)ŏ|~u9Y=FOZ@jsV>_¼Ap vO"*} * Σf56? Ƌw.:{!Z14>_ 5Ҷ7fQQ$=C} L+ڪhG*+=E ͩku8ts3c^iXTTD#0*Ml ;WT݄ˏSPx2}xǖ%~X$"{c{G{O؏h >ὐ[q+7"VT/Et.lTٍ E`p9f$H_2:$9V޼IQ7&eue2iA ,/6,ӿċe\a ӟ&-m zv:jSb)}6jX0c_d=fED4) U-V#R_sC͸j_i)tPΟ%].j)HΚnpBLr Ex{reRTu:zW'e'xn6:mxq|jKsʆ>#(LTRv maymz0c0#hy@#.0Zب@o'}G?->BhycaR&?㄄j:wbLBȋH"f endstream endobj 147 0 obj << /Type /FontDescriptor /FontName /ZQYURG+CMTI12 /Flags 4 /FontBBox [-36 -251 1103 750] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 63 /XHeight 431 /CharSet (/a/b/c/e/i/l/n/o/r/s/t/u) /FontFile 146 0 R >> endobj 148 0 obj << /Length1 1617 /Length2 9569 /Length3 0 /Length 10615 /Filter /FlateDecode >> stream xڍT6LwKJ HХtt 50tHJ)H7(( ‡s=Z߷fyϻwӨkKXBPGWv 0@JEK Ơׂڃca.?"``Mu(< 0P@ %w & C,*E#^ X۸>/ɂ`p  G dЄZ@^UIIÃYbfx@\m`0l M rEeqCjO{) #+onNڎg7_1O&ج>...An@ m~uX=AO?>. w0XGT2r=?'YB9uueYo$ `~]ǪuSpEivpKL- 3;B 0GF\|\O_Uɺ3+9@xRf@CuZg% p !.O:bG:rvOoeq6;8Z@-7?0>%Pק;?JM$7> p8!OmDTotzOaO]2\{>Ukrn0ӣGOcy`OB$sHuiTfvE[$5إD`ʖ Ӆ/Z԰-wq;- }G5Z⻾}u鳝qs]{y,ޭW¼/b֎2 *10KJNBp;sq9M5HNJw`;f{Lۥ̀`dGr?Ydާ jG.f^jvaCe.{آ_K g^7z掦g#yRV+Y\Ƃ݁0p{,"҅хqC!CMtMU_a~*(绂t>ݶNӞ_Je`'=O~k^)bnl8H$|{3b*tAQe8^gN@mkwb@T ?7XT-|B\qٲB|E~T%lӴ$5ۣ "f >Rt)"T/#9D >&ˌ~2cȎVݟĎFI%qjW5,Ϥ'Q)%fT\cnzpc#nl٧%# U/SG ; <*>U2HMe04ϊ QUk[k]r^[u܍69Vifth%կH!yuyVʇK×_t/!geu*DLKݕ@~_=WR~Mi'_My/@I@XK@bENM'C$f}+$T도z2nԭy|-N%Z 6r"4NDrY˧c{NNubjp(y)/6S<-owʹQQ11~(}g0 J? OopuQ]ɖJAN LfPyȘ<^gR6]7h#Cw z\o53_Abf5[g~{u(/>Â:ԌD #KyUVaYFF')$J_B/%N6X%V? 22!=Hʕ`GrBf!H!lvJeh3Zo;Ÿ41eJ*fDqHTbUڜf|)&#ǭ#o.~:kB Klڍ|O>TR1Z4ZhV^~"TmJh=eA545W.݁h<(LchI0{/FBb2[1AҊU(u߮2#;ی`rn+(5r~XDTش{Y.[}XY ތ'TWC2$)}S~Ӕ*|'6{>"c=3[%@-j_w]UʠG2(UCJ"By%'"*ğK2FsP;z7P ) -J31>Ǻa?2<_pE&SKLwKv,x 4:H?uܞ@!5zCS>&AԵ$T gi/1>+'f ,=}C92 B-¥- F磉 T*;}aFo7&8M /6P#6x)ɚpZzn%sn ?L|i%D=_&֡w6 i%g.s+r6 ցNIRNU J/&Drʓ!g/h(hW)z m=2GEʁ=pHXgb6̂ #D <7 4$\ux *z\_kttD ~wAk@Ȧ/6j0|Um `Xy},G>Ix3?:"-͡Q.WfL;7/~)|;k"րoHOjV@dKte.5>6p?/軲,7w#fy, Ǿ  JOj1l :~S ub1ɫ$vwzx`h͆9V і-ZHϱZ[{q7葽ZU32cG ,v>Z6PPtG[3yaoIƘ Zv,81:7fRpDM ;9"({erɶc?ja V45] |-sOZ5>HRp 2#jl *ð}^Zuԗ1d{X.߰DܖܺZgHz[Է,t5~#)g,K)#]wA%ixIY1~!𹭽Tq[ N/X@lb羚=㔟qkQngMϐ!Q89u]9AOgx[.Ycp"uC_ٲve1kٶ|y^Z ~>;R2\rsDL_l8C 2XJ3 ‘ם8ۚ,&`_*1EW* 93>4E囕wYX!;9bCk+'r#}DMeZY8{$o/vK('yΗ[ŵɹ鎫Z[Yɽ}Ț>M[ة-`pTwu_zo)Lӄ`ki(fD\t̙/  "Y}y̛Ö)7[kb/F;4|o&^i+5!J%mhU\vme*NJk5GFA 23"oĀ̡F >Et٥ mΘy֔x2kD1 Y=UErI38|r!`A<1LrjStVR-Z*;LGm87 J^Vp͛5k4ϖ*ɓimnR_pW@U2 gkH>BnՂI~d:ޗn?{bĥ9JE? Y +1ʼnA6Q{t"He(;0+NvcVҙ^GXp؜&ꑶ`mxAxt)]֋|Hpp L_)T>1Δ-L說khGm/<-٫h-ùL~*ɏC|{ N&eRGJ *G"ʘ*hy8+0euMp3K]߲x3_WZz8Es^cǒz^d!`X1!7BDR 5RO/9^׸Yob1*"l >s-9Kc9J>GrR ?(%4C}&)wC/CP/ZΤƿS$Pi I[D:B15?xm~}&&[結l[P c{j"d CH2Ppbet[1Njp 1>}9E{wyO9D>.&PFfGBBsv|5^, ~r<1ڏ;" ߢ,#n]|^K0{Be6'b[J& 48mrM^\B ki'F2z,MAIjt;w{:r1מp04wﳽ73XpUjXc% ec??ReGJ<]E-,%cLSbeה֝݌( {O9 >Dop0Bb߾ZǬ[Hó:Zk軥#6YZ@{EY5oCIN^/eenY #>kCLZ0r9mpsCn]љ8 {ķ|E A0Y F6V885w)JVS8<Ģ1OӮrU}/ü=@E,cUPu6{ZShs?-e-݅׼*.C洬" M LmC)*+U=pUQYeݣ0"hCKl$ &x[g4P0͆ʣVo3 z{CĐPXˠ@@x yɄ;-lH;}54i\`^~xo5mH=-2igI(@KSC2E^;"SF:kk]5Heݑ3[ 5֗ A?Fi9;Zx2X61pHT.(*/l;d"b1 4y߶K&;r|j<(e-$@8I0"8**Fe'ޯ /hx\Uפ'M։U)TZOuG"vqQp B빭Z,҄T8$8߻jFb^x [q+ڕvTi +8XO^"4gb̯KYlв:^pE>Ĕ9k! Y0!ЌcMz_m`_D,fG6O?ޢ)/yJ$ۉw҂u=?0c9Mh* *8VS|!6}eՂM=+]M6SJ='ų xEHjzܥ81&²D.4J\a]tݕZ/׽etoq@^Ts2;Q2C@;*S~c/5f)1gsaxLNV$ﹴrP6C2"#T9.ؾ3\ Ѝ$= Z'"d=brL\J|h}=oMnRX sE3?H'D&yPs> 6ӷ3Ar YcDErSF|͎?l| Rm`3xnt 277Mjd%ӌ|ɸW|W8iUPgʼi|f99˃![gB0*UHaf7矅c6nJpD2(^{O<3<<wL9k z~ga?91?{&.iƍUrQGNf*/ma5iJٮ#[RW9E2FVƋJA[2YO+XwJ./Iwl1:RR@=Upn5ˇZ$]ZD U_x;(( Z]Ɵ.R p.RDR.[ vItEף7ϵ4듓&#c% *X4!-)ڞ33 !^Z'Gip %Ԕ6Z?<_)b콿 XBIkcwf2F;5Gg`Ƀ$?RWLxuVRj{^ S@H6>]^oh!XW7}S2 0lf6JZ(|F:=7T=c(gDxњcu58@S(LU7xO$]ٽ#BemāieB3#Bz2΢/Nx]TfreW= g~ԣUH)``Bx\'ų EV&_hrR ĐnH8+9(5JQR N3Y=d!<<4.5*pey,#-20KJ5ұGj< T̾#4Fѡdq)3= ybS%4hڻa*'36w+yIVwjxI=b\S=6P^k?ǽT^B{d/?-IAkFP &##%xHN]dmB&"щ&yGYx {]BZ&~UV/wS+n XlZDxO<7hl69I$M".T7qJ>% 2~*!& 3L)B 6)C YI ^"a'QEG]|4+2!ITYR{S͋n~ u'K:V!Q:ͻrGy *": 74}ar6vh3B[# ՜ +#g_ӡ&0z7πzA+ ;L.#MYov9yo9?_DFOעm"gәFpKsCO ]͘KS3T'׋)rx,Ӓrab7),m"mNh( Zp'MʤLƦ|%R|-"xs6 I?/A xd}]R\P]}x~:o~kO2d1E6N~Ԭgj)[cKH?:l%br1YF相mő (Ǽ}t$zhr@J5Lk%ͪd?~4X!1q xWUNI}M",(H r/77Re=߫&Twe#@dFk-U֏} (gߒTΤfLnӽVQzϻL8|>5. K$3#twF'9=9WsѦnϛ{& \hzN`1kJ~86&N׾ㇵvSe<"aв\7 4x`@+Qh7ՙA_q=_4[Z'e%ҟY.xD?70aU>\Tb?"1<-T|(wS,ykqɼ #JNk,-odydł >{ $_p]nû}ܷB 7udbIۉmj-nⵄ۵ saO ϫ fQQ(b3F>OB [h*jYᑩďbz-{J_ G AE{ K{X8jc.Uc Ay@d;8HF/ƎPe>zG~[Y{BSax endstream endobj 149 0 obj << /Type /FontDescriptor /FontName /DCUWWF+CMTT10 /Flags 4 /FontBBox [-4 -233 537 696] /Ascent 611 /CapHeight 611 /Descent -222 /ItalicAngle 0 /StemV 69 /XHeight 431 /CharSet (/N/a/c/e/f/h/i/l/n/o/period/r/s/t/x/y) /FontFile 148 0 R >> endobj 150 0 obj << /Length1 2273 /Length2 8458 /Length3 0 /Length 9779 /Filter /FlateDecode >> stream xڍTӍ7NH!kt+]"=`%!"%) )8$DxOy߳s{?7>7_&z-].ik%Xsrzz| eb҃q nT+G@p$P;xBbb@ sȁ< un ve9{Bl<ZxEE9+ہ@] OV ;8Yӓ s} :`72@7.@AfH# uCCdv@ wsܼg 3 zC# s@P@ AAHAimo~nVg'GamZœP `+d߽y G@m~ҰvwчB\rc*:[0 E`ʎg=og/#O53`؀?n 0_ ` ,(H5/9W\?^ AHYY ߔ5\.>~ @HT(/wm60_{ѰAf0V/?_+Rpwteg #G^: y>u`kZ HCmm$Mւ~m?c@Fw@Z07 7~ȋoFy @ o\ r{Zm7G60Wܟ#T<ʿ%ƿG緄D+ x@%/j ;mV":vW?HVJV0Gd;89gyYwP$@d7l~@|N{3';AGଊ{)Dj1 `蔧j6X,@ewڸ_tvCi =Pv[Mny5w| ؉Z$rGV~VTa ˃QV6~ޠ:SVt'jصӫYgچ_ӳSˬ^OӁ6t 煅)c@hƟiVCk;~A<ؚކyELMgE&]Qk酎ɏwٛHDGpp8Ȇ@a}ZVV͝L09T4ėMS>R:llkQ<9jJBKVc$H BG%?x[wDhέ\4Xz΂~1 L॔/F"FK߽8 ʂK3.ff.;BhqJ&SG7U*%rs0ߘ.).5IIsع/0Ni!]fOtSbò+[k]_hP?O!QoyaCriN^3.&G WwN) ջII˄O٥7$J}tVpx?$~!Pm7]M -͈;#!*G 't|!ˁz33g8< ~a];"~vJngI2J~J8}ۜ:Yٔ3]t\94׸D&X(O,Z R~W\N@pbvZP=gϩɒBj[PBR`#5JkOhv1&1mVn ;ҋɸ?w!`EU:4\xYНq9_*Aҍ y6vG Z#wZCO^J/1, Y6$4.kwʌ)=e:#ud^J6 ?q\<*"O໢{'fpZҙoYm<#ɺ< = l@.-FH\J1Z+hu>.Dx~٩rZ Ɍs/1~FX 1?c2?0F87v25:Y<% Rtv>2;7#efOGdMK0cpJn b;VFXLDgܾSb^\[،bI[S(4"SxfvLu (s#!OL/)=v@c^c ~xe9KZmݩTVc4fzszakߎ\}*gQ awPE!D,riδ88G^QryS7X CKF&q U9oz)@y`5csl|T{FG90t!%t9[%=)EuxRa7sY]^>#t^K(NSv& j׻G/Z;UN 5VBXnޤwgY[~,WTKLqVR1Ff}S(Go 唋p1RlOښJꚾIYZf(>6IJP\}A`6܇x/5 -WqX?1,<`?Q'- uSmi5%ִ7p^P?scwUU?[N`IیQ,S=3ܚ#;˱.=x'dPg-yMPe4kBsfO >׆|Jcn,> x;wbSQY)1ޒ9qY,]" S5fS0Pv 6Tm!Tn-zŧ5r] \K;SN]ρZ:_: KtwL6"%&'rxش[_kh't O /#:'vt%"aß>ɍQ܍ox ]k~!+0FA#k͗oWPd~uˋU`?A>pW$$3c-}Q~E4u•U]>I:06-+I-Nm|zMgbob>qrzimϵ'e6^fM.$T^p1DE=bA= :y~]dkXQ6V:7Ӵ R3!Sgb˺<ϡkgBdx gm%Y;P=}=I]bR5\-hza,VhÞWzH{2QҢA DY h"cXS?v-*oԄ^RAxɲ?% {m|Fjz-Z #lzF'YÒ~f{idW]WzitB[۱l{M}!|Qu|{qhgE1s{6>şZJ3m?pCXe.57c?7eoCx,G"`!\=.Jw]JT1-&I4Ղ|}w CEwpsܹoEB-QĞʿLf:q8} [\[鵁Q*hٻbvr.=Q1 ӴxSKgmDk92j/ϖ9u>}RiÅ&(Zw?|K\MՔľV( =-"V@c3 ET.Mf>)ْ'f, c$PIG.ht1#ˉGL^'H7&;`l~?=Կ[wL桴mSg SMҝ"9[>Pb~:;@aJ* (ϫ v^YE8I?PBF DBޟU={WS? V/U\^ʻ']DgOwpDс֟7⎕W1?ZZflWq4X-$#cX o#| | KEϐJǷ^׸w7$PũY _^%=Ma,+/!XPs|-%Cl|7i|N;+<|G0b9N'8XuГ*{.j.4ء?bhHؔO҈O@~2TC{7l朲ƧMODLUJ j=$Z>bnT1@h/HoyɏY=~T2h4Mrl A2 ,:A&H} IF[IYV-a7\p]`~*)wFQun$]}x>JB3粄fH><2 –J}gs/ڽ5ؼ"Mh_B|;++Gkr,ϮKB܊в=j~lGw"xTz9AtxUW 4|e*2fL"E|ﳱ`u.:)e暔oƾ}rcRK425߂Ý,"440L'|_=PG9<NdHxZܻ6wCkW6x3t6vFi8YLek\T.)wWRTye[wceD.1B?Fur}r>i'weUUk@GnNwE Wrf˺'*Ai!#dr[*D3ᆱM_~w[Z{R=f*;QO߬,\3ErQf?kQk@@̧{ ;m+x \=cB%tۥdLu:b65Gݩm劜{QDc"+BqLl'a=5Qyd62^S]z;Fp)F;{esf"vY{.x S?^8 fnyeD_߶BJ\~\Rǻvr%4Ⱥ`R&(z ܇_LZe,kw?%;3b PUe3ӘW;o%'++c\ZL< #&Gy-ln>JP c*VWdtBW@:+ҙ:["#2̪@!. =N^JY6`B ?]C怰x%|航o!=Xnw[DRh'ŞڷxH|}b6*cNF,7s {2xo@kwz0{=Mڛ+:QBʧdt1P+VmORȽ%V.Z))"/O-"h[ǫN&ui!MxI z_?(PڃG'[xQ掌3VAuB#N{y; Y#eFg /5jH8{c4fGy67 Kf{;y:Ey4؜NSх-(1V`,ږZ^Z4]ƦG8J%5;_gM%8mFݙc}\֨!ƇGS*)3vg {8[̺u2A {:}QsȲg cgăE 7szH6zb'|ji.⨉+fS8'y@<[B+=ea>5* rZKMsV(lSm0ېɷߟ,ʰ"\:ޡ"/.~/b.܊%l7jb,:Z~Hq \ -WI{4{T0}r}5ᑻj]4:Bx=//,Ms >~/bw6 IOn^Rp)f}\ϣ#RmCg"Y5~8 mXy -d,6_y´iSt񲇸%k{*O_񯓰s`ggꪂJP}f =Y3'_ã|c26tGr0k1h^#0_[Q8 endstream endobj 151 0 obj << /Type /FontDescriptor /FontName /ZIITZW+CMTT12 /Flags 4 /FontBBox [-1 -234 524 695] /Ascent 611 /CapHeight 611 /Descent -222 /ItalicAngle 0 /StemV 65 /XHeight 431 /CharSet (/E/I/N/R/S/a/b/braceleft/braceright/bracketleft/bracketright/c/colon/comma/d/dollar/e/eight/f/five/four/greater/h/hyphen/i/j/k/l/less/m/n/nine/o/one/p/parenleft/parenright/period/quotedbl/quoteright/r/s/seven/six/t/three/two/u/v/x/y/z/zero) /FontFile 150 0 R >> endobj 46 0 obj << /Type /Font /Subtype /Type1 /BaseFont /SRPSZA+CMBX12 /FontDescriptor 127 0 R /FirstChar 12 /LastChar 121 /Widths 123 0 R >> endobj 78 0 obj << /Type /Font /Subtype /Type1 /BaseFont /RLYTRW+CMMI10 /FontDescriptor 129 0 R /FirstChar 60 /LastChar 60 /Widths 110 0 R >> endobj 52 0 obj << /Type /Font /Subtype /Type1 /BaseFont /OJYHED+CMR10 /FontDescriptor 131 0 R /FirstChar 12 /LastChar 121 /Widths 118 0 R >> endobj 45 0 obj << /Type /Font /Subtype /Type1 /BaseFont /ABYGBP+CMR12 /FontDescriptor 133 0 R /FirstChar 11 /LastChar 122 /Widths 124 0 R >> endobj 44 0 obj << /Type /Font /Subtype /Type1 /BaseFont /CSTHYD+CMR17 /FontDescriptor 135 0 R /FirstChar 67 /LastChar 117 /Widths 125 0 R >> endobj 50 0 obj << /Type /Font /Subtype /Type1 /BaseFont /XNDOVD+CMR7 /FontDescriptor 137 0 R /FirstChar 49 /LastChar 53 /Widths 119 0 R >> endobj 48 0 obj << /Type /Font /Subtype /Type1 /BaseFont /JZKXYQ+CMR8 /FontDescriptor 139 0 R /FirstChar 49 /LastChar 53 /Widths 121 0 R >> endobj 58 0 obj << /Type /Font /Subtype /Type1 /BaseFont /QAJLOO+CMSLTT10 /FontDescriptor 141 0 R /FirstChar 33 /LastChar 125 /Widths 117 0 R >> endobj 79 0 obj << /Type /Font /Subtype /Type1 /BaseFont /FXXUVH+CMSY10 /FontDescriptor 143 0 R /FirstChar 0 /LastChar 0 /Widths 109 0 R >> endobj 71 0 obj << /Type /Font /Subtype /Type1 /BaseFont /DINKEP+CMTI10 /FontDescriptor 145 0 R /FirstChar 101 /LastChar 118 /Widths 111 0 R >> endobj 47 0 obj << /Type /Font /Subtype /Type1 /BaseFont /ZQYURG+CMTI12 /FontDescriptor 147 0 R /FirstChar 97 /LastChar 117 /Widths 122 0 R >> endobj 70 0 obj << /Type /Font /Subtype /Type1 /BaseFont /DCUWWF+CMTT10 /FontDescriptor 149 0 R /FirstChar 46 /LastChar 121 /Widths 112 0 R >> endobj 49 0 obj << /Type /Font /Subtype /Type1 /BaseFont /ZIITZW+CMTT12 /FontDescriptor 151 0 R /FirstChar 34 /LastChar 125 /Widths 120 0 R >> endobj 53 0 obj << /Type /Pages /Count 6 /Parent 152 0 R /Kids [38 0 R 55 0 R 60 0 R 65 0 R 74 0 R 81 0 R] >> endobj 88 0 obj << /Type /Pages /Count 5 /Parent 152 0 R /Kids [85 0 R 91 0 R 97 0 R 102 0 R 106 0 R] >> endobj 152 0 obj << /Type /Pages /Count 11 /Kids [53 0 R 88 0 R] >> endobj 153 0 obj << /Type /Outlines /First 3 0 R /Last 35 0 R /Count 9 >> endobj 35 0 obj << /Title 36 0 R /A 33 0 R /Parent 153 0 R /Prev 31 0 R >> endobj 31 0 obj << /Title 32 0 R /A 29 0 R /Parent 153 0 R /Prev 27 0 R /Next 35 0 R >> endobj 27 0 obj << /Title 28 0 R /A 25 0 R /Parent 153 0 R /Prev 23 0 R /Next 31 0 R >> endobj 23 0 obj << /Title 24 0 R /A 21 0 R /Parent 153 0 R /Prev 19 0 R /Next 27 0 R >> endobj 19 0 obj << /Title 20 0 R /A 17 0 R /Parent 153 0 R /Prev 15 0 R /Next 23 0 R >> endobj 15 0 obj << /Title 16 0 R /A 13 0 R /Parent 153 0 R /Prev 11 0 R /Next 19 0 R >> endobj 11 0 obj << /Title 12 0 R /A 9 0 R /Parent 153 0 R /Prev 7 0 R /Next 15 0 R >> endobj 7 0 obj << /Title 8 0 R /A 5 0 R /Parent 153 0 R /Prev 3 0 R /Next 11 0 R >> endobj 3 0 obj << /Title 4 0 R /A 1 0 R /Parent 153 0 R /Next 7 0 R >> endobj 154 0 obj << /Names [(Doc-Start) 43 0 R (Hfootnote.1) 51 0 R (Hfootnote.2) 69 0 R (Hfootnote.3) 77 0 R (Hfootnote.4) 94 0 R (Hfootnote.5) 100 0 R] /Limits [(Doc-Start) (Hfootnote.5)] >> endobj 155 0 obj << /Names [(page.1) 42 0 R (page.10) 104 0 R (page.11) 108 0 R (page.2) 57 0 R (page.3) 62 0 R (page.4) 67 0 R] /Limits [(page.1) (page.4)] >> endobj 156 0 obj << /Names [(page.5) 76 0 R (page.6) 83 0 R (page.7) 87 0 R (page.8) 93 0 R (page.9) 99 0 R (section.1) 2 0 R] /Limits [(page.5) (section.1)] >> endobj 157 0 obj << /Names [(section.2) 6 0 R (section.3) 10 0 R (section.4) 14 0 R (section.5) 18 0 R (section.6) 22 0 R (section.7) 26 0 R] /Limits [(section.2) (section.7)] >> endobj 158 0 obj << /Names [(section.8) 30 0 R (section.9) 34 0 R] /Limits [(section.8) (section.9)] >> endobj 159 0 obj << /Kids [154 0 R 155 0 R 156 0 R 157 0 R 158 0 R] /Limits [(Doc-Start) (section.9)] >> endobj 160 0 obj << /Dests 159 0 R >> endobj 161 0 obj << /Type /Catalog /Pages 152 0 R /Outlines 153 0 R /Names 160 0 R /PageMode/UseOutlines /OpenAction 37 0 R >> endobj 162 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.14)/Keywords() /CreationDate (D:20190726110706-07'00') /ModDate (D:20190726110706-07'00') /Trapped /False /PTEX.Fullbanner (This is MiKTeX-pdfTeX 2.9.4902 (1.40.14)) >> endobj xref 0 163 0000000000 65535 f 0000000015 00000 n 0000004159 00000 n 0000185359 00000 n 0000000060 00000 n 0000000090 00000 n 0000007529 00000 n 0000185275 00000 n 0000000135 00000 n 0000000193 00000 n 0000009551 00000 n 0000185189 00000 n 0000000238 00000 n 0000000274 00000 n 0000015156 00000 n 0000185101 00000 n 0000000320 00000 n 0000000358 00000 n 0000018097 00000 n 0000185013 00000 n 0000000404 00000 n 0000000459 00000 n 0000020499 00000 n 0000184925 00000 n 0000000505 00000 n 0000000562 00000 n 0000025344 00000 n 0000184837 00000 n 0000000608 00000 n 0000000647 00000 n 0000027796 00000 n 0000184749 00000 n 0000000693 00000 n 0000000739 00000 n 0000029677 00000 n 0000184674 00000 n 0000000785 00000 n 0000000814 00000 n 0000003771 00000 n 0000003898 00000 n 0000004272 00000 n 0000000862 00000 n 0000004051 00000 n 0000004104 00000 n 0000183037 00000 n 0000182895 00000 n 0000182468 00000 n 0000183888 00000 n 0000183319 00000 n 0000184174 00000 n 0000183179 00000 n 0000004213 00000 n 0000182753 00000 n 0000184317 00000 n 0000007583 00000 n 0000007368 00000 n 0000004424 00000 n 0000007476 00000 n 0000183459 00000 n 0000009606 00000 n 0000009390 00000 n 0000007701 00000 n 0000009498 00000 n 0000012143 00000 n 0000012408 00000 n 0000012016 00000 n 0000009712 00000 n 0000012296 00000 n 0000030546 00000 n 0000012349 00000 n 0000184031 00000 n 0000183744 00000 n 0000014951 00000 n 0000015270 00000 n 0000014824 00000 n 0000012572 00000 n 0000015103 00000 n 0000015211 00000 n 0000182611 00000 n 0000183604 00000 n 0000018152 00000 n 0000017936 00000 n 0000015458 00000 n 0000018044 00000 n 0000020554 00000 n 0000020338 00000 n 0000018282 00000 n 0000020446 00000 n 0000184427 00000 n 0000022719 00000 n 0000022983 00000 n 0000022592 00000 n 0000020672 00000 n 0000022871 00000 n 0000022924 00000 n 0000025139 00000 n 0000025459 00000 n 0000025012 00000 n 0000023135 00000 n 0000025291 00000 n 0000025399 00000 n 0000027852 00000 n 0000027630 00000 n 0000025623 00000 n 0000027741 00000 n 0000029733 00000 n 0000029511 00000 n 0000027971 00000 n 0000029622 00000 n 0000029852 00000 n 0000029877 00000 n 0000029902 00000 n 0000030019 00000 n 0000030342 00000 n 0000030794 00000 n 0000030820 00000 n 0000030881 00000 n 0000030917 00000 n 0000031308 00000 n 0000031919 00000 n 0000031968 00000 n 0000032539 00000 n 0000032588 00000 n 0000032693 00000 n 0000033330 00000 n 0000033942 00000 n 0000034263 00000 n 0000047581 00000 n 0000047905 00000 n 0000054926 00000 n 0000055151 00000 n 0000071925 00000 n 0000072272 00000 n 0000091437 00000 n 0000091866 00000 n 0000101511 00000 n 0000101755 00000 n 0000109491 00000 n 0000109731 00000 n 0000117463 00000 n 0000117703 00000 n 0000134702 00000 n 0000135191 00000 n 0000142167 00000 n 0000142393 00000 n 0000151656 00000 n 0000151892 00000 n 0000160882 00000 n 0000161126 00000 n 0000171861 00000 n 0000172114 00000 n 0000182013 00000 n 0000184532 00000 n 0000184600 00000 n 0000185430 00000 n 0000185623 00000 n 0000185783 00000 n 0000185944 00000 n 0000186123 00000 n 0000186227 00000 n 0000186332 00000 n 0000186370 00000 n 0000186497 00000 n trailer << /Size 163 /Root 161 0 R /Info 162 0 R /ID [<0467C4AF085C00713F357C6D56D85E95> <0467C4AF085C00713F357C6D56D85E95>] >> startxref 186772 %%EOF iterators/inst/doc/writing.Rnw0000644000176200001440000005115113513447415016175 0ustar liggesusers% \VignetteIndexEntry{Writing Custom Iterators} % \VignetteDepends{iterators} % \VignettePackage{iterators} \documentclass[12pt]{article} \usepackage{amsmath} \usepackage[pdftex]{graphicx} \usepackage{color} \usepackage{xspace} \usepackage{fancyvrb} \usepackage{fancyhdr} \usepackage[ colorlinks=true, linkcolor=blue, citecolor=blue, urlcolor=blue] {hyperref} \usepackage{lscape} \usepackage{Sweave} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % define new colors for use \definecolor{darkgreen}{rgb}{0,0.6,0} \definecolor{darkred}{rgb}{0.6,0.0,0} \definecolor{lightbrown}{rgb}{1,0.9,0.8} \definecolor{brown}{rgb}{0.6,0.3,0.3} \definecolor{darkblue}{rgb}{0,0,0.8} \definecolor{darkmagenta}{rgb}{0.5,0,0.5} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\bld}[1]{\mbox{\boldmath $#1$}} \newcommand{\shell}[1]{\mbox{$#1$}} \renewcommand{\vec}[1]{\mbox{\bf {#1}}} \newcommand{\ReallySmallSpacing}{\renewcommand{\baselinestretch}{.6}\Large\normalsize} \newcommand{\SmallSpacing}{\renewcommand{\baselinestretch}{1.1}\Large\normalsize} \newcommand{\halfs}{\frac{1}{2}} \setlength{\oddsidemargin}{-.25 truein} \setlength{\evensidemargin}{0truein} \setlength{\topmargin}{-0.2truein} \setlength{\textwidth}{7 truein} \setlength{\textheight}{8.5 truein} \setlength{\parindent}{0.20truein} \setlength{\parskip}{0.10truein} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \pagestyle{fancy} \lhead{} \chead{Writing Custom Iterators} \rhead{} \lfoot{} \cfoot{} \rfoot{\thepage} \renewcommand{\headrulewidth}{1pt} \renewcommand{\footrulewidth}{1pt} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \title{Writing Custom Iterators} \author{Steve Weston} \begin{document} \maketitle \thispagestyle{empty} \section{Introduction} <>= library(iterators) @ An {\em iterator} is a special type of object that supplies data on demand, one element\footnote{An ``element'' in this case can be basically any object. I don't mean to suggest that the data is necessarily returned as scalar values, for example.} at a time. This is a nice abstraction that can help simplify many programs. Iterators are particularly useful in parallel computing, since they facilitate splitting a problem into smaller pieces that can then be executed in parallel. Iterators can also be used to reduce the total memory that is needed at any one time. For example, if you want to process the lines of text in a file, it is common to write a loop that reads the file one line at a time, rather than reading the entire file in order to avoid running out of memory on huge files. That's the basic idea of iterators. Iterators provide a standard method for getting the next element, which allows us to write functions that take an iterator as an argument to provide a source of data. The function doesn't need to know what kind of iterator it is. It just needs to know how to get another piece of data. The data could be coming from a file, a database, a vector, or it could be dynamically generated. There are a number of iterators that come in the \texttt{iterators} package. The \texttt{iapply} function allows you to iterate over arrays, in much the same way as the standard \texttt{apply} function. \texttt{apply} has fixed rules on how the results are returned, which may require you to reshape the results, which can be inefficient, as well as inconvenient. But since \texttt{iapply} doesn't process any data or combine the results, it is more flexible. You can use \texttt{iapply} with the \texttt{foreach} package to perform a parallel \texttt{apply} operation, and combine the results any way you want via the \texttt{.combine} argument to \texttt{foreach}. Another iterator that comes in the \texttt{iterators} package is the \texttt{isplit} function, which works much like the standard \texttt{split} function. \texttt{split} returns a list containing all of the data divided into groups. \texttt{isplit} only generates one group at a time, as they are needed, which can reduce the amount memory that is needed. But of course, there will be times when you need an iterator that isn't provided by the \texttt{iterators} package. That is when you need to write your own custom iterator. Fortunately, that is fairly easy to do. \section{What methods are needed for an iterator?} Basically, an iterator is an S3 object whose base class is \texttt{iter}, and has \texttt{iter} and \texttt{nextElem} methods. The purpose of the \texttt{iter} method is to return an iterator for the specified object. For iterators, that usually just means returning itself, which seems odd at first. But the \texttt{iter} method can be defined for other objects that don't define a \texttt{nextElem} method. We call those objects {\em iterables}, meaning that you can iterate over them. The \texttt{iterators} package defines \texttt{iter} methods for vectors, lists, matrices, and data frames, making those objects iterables. By defining an \texttt{iter} method for iterators, they can be used in the same context as an iterable, which can be convenient. For example, the \texttt{foreach} function takes iterables as arguments. It calls the \texttt{iter} method on those arguments in order to create iterators for them. By defining the \texttt{iter} method for all iterators, we can pass iterators to \texttt{foreach} that we created using any method we choose. Thus, we can pass vectors, lists, or iterators to \texttt{foreach}, and they are all processed by \texttt{foreach} in exactly the same way. The \texttt{iterators} package comes with an \texttt{iter} method defined for the \texttt{iter} class that simply returns itself. That is usually all that is needed for an iterator. However, if you want to create an iterator for some existing class, you can do that by writing an \texttt{iter} method that returns an appropriate iterator. That will allow you to pass an instance of your class to \texttt{foreach}, which will automatically convert it into an iterator. The alternative is to write your own function that takes arbitrary arguments, and returns an iterator. You can choose whichever method is most natural. The most important method required for iterators is \texttt{nextElem}. This simply returns the next value, or throws an error. Calling the \texttt{stop} function with the string \texttt{'StopIteration'} indicates that there are no more values available in the iterator. Now before we write our own iterator, let's try calling the \texttt{iter} and \texttt{nextElem} methods on an existing one. Since a list is an iterable, we can create an iterator for that list by calling \texttt{iter} on it: <>= it <- iter(list(1:2, 3:4)) @ We can now call \texttt{nextElem} on the resulting iterator to get the values from the list: <>= nextElem(it) nextElem(it) tryCatch(nextElem(it), error=function(e) e) @ As you can see, it is possible to call these methods manually, but it's somewhat awkward, since you have to handle the \texttt{'StopIteration'} error. Later on, we'll see one solution to this difficulty, although, in general, you don't call these method explicitly. \section{A simple iterator} It's time to show the implementation of a very simple iterator. Although I've made it sound like you have to write your own \texttt{iter} and \texttt{nextElem} methods, you can inherit them. In fact, that's what all of the following examples do. I do that by inheriting from the \texttt{abstractiter} class. The \texttt{abstractiter} class uses the standard \texttt{iter} method which returns itself, and defines a \texttt{nextElem} method that calls the \texttt{nextElem} element of the object. Let's take a look at the implementation of these two methods: <>= iterators:::iter.iter iterators:::nextElem.abstractiter @ Now here's a function that creates a very simple iterator that uses these two methods: <>= iforever <- function(x) { nextEl <- function() x obj <- list(nextElem=nextEl) class(obj) <- c('iforever', 'abstractiter', 'iter') obj } @ Note that I called the internal function \texttt{nextEl} rather than \texttt{nextElem}. I do that by convention to avoid masking the standard \texttt{nextElem} generic function. That causes problems when you want your iterator to call the \texttt{nextElem} method of another iterator, which can be quite useful, as we'll see in a later example. We create an instance of this iterator by calling the \texttt{iforever} function, and then use it by calling the \texttt{nextElem} method on the resulting object: <>= it <- iforever(42) nextElem(it) nextElem(it) @ You can also get values from an iterator using \texttt{as.list}. But since this is an infinite iterator, you need to use the \texttt{n} argument to avoid using up a lot of memory and time: <>= unlist(as.list(it, n=6)) @ Notice that it doesn't make sense to implement this iterator by defining a new \texttt{iter} method, since there is no natural iterable on which to dispatch. The only argument that we need is the object for the iterator to return, which can be of any type. Instead, we implement this iterator by defining a normal function that returns the iterator. This iterator is quite simple to implement, and possibly even useful.\footnote{Be careful how you use this iterator! If you pass it to \texttt{foreach}, it will result in an infinite loop unless you pair it with a non-infinite iterator. Also, {\em never} pass this to the \texttt{as.list} function without the \texttt{n} argument.} The iterator returned by \texttt{iforever} is a list that has a single element named \texttt{nextElem}, whose value is a function that returns the value of \texttt{x}. Because we are subclassing \texttt{abstractiter}, we inherit a \texttt{nextElem} method that will call this function, and because we are subclassing \texttt{iter}, we inherit an \texttt{iter} method that will return itself. Of course, the reason this iterator is so simple is because it doesn't contain any state. Most iterators need to contain some state, or it will be difficult to make it return different values and eventually stop. Managing the state is usually the real trick to writing iterators. \section{A stateful iterator} Let's modify the previous iterator to put a limit on the number of values that it returns. I'll call the new function \texttt{irep}, and give it another argument called \texttt{times}: <>= irep <- function(x, times) { nextEl <- function() { if (times > 0) times <<- times - 1 else stop('StopIteration') x } obj <- list(nextElem=nextEl) class(obj) <- c('irep', 'abstractiter', 'iter') obj } @ Now let's try it out: <>= it <- irep(7, 6) unlist(as.list(it)) @ The real difference between \texttt{iforever} and \texttt{irep} is in the function that gets called by the \texttt{nextElem} method. This function not only accesses the values of the variables \texttt{x} and \texttt{times}, but it also modifies the value of \texttt{times}. This is accomplished by means of the ``\verb=<<-='' \footnote{It's commonly believed that ``$<<-$'' is only used to set variables in the global environment, but that isn't true. I think of it as an {\em inheriting} assignment operator.} operator, and the magic of lexical scoping. Technically, this kind of function is called a {\em closure}, and is a somewhat advanced feature of \texttt{R}. The important thing to remember is that \texttt{nextEl} is able to get the value of variables that were passed as arguments to \texttt{irep}, and it can modify those values using the ``\verb=<<-='' operator. These are {\em not} global variables: they are defined in the enclosing environment of the \texttt{nextEl} function. You can create as many iterators as you want using the \texttt{irep} function, and they will all work as expected without conflicts. Note that this iterator only uses the arguments to \texttt{irep} to store its state. If any other state variables are needed, they can be defined anywhere inside the \texttt{irep} function. \section{Using an iterator inside an iterator} The previous section described a general way of writing custom iterators. Almost any iterator can be written using those basic techniques. At times, it may be simpler to make use of an existing iterator to implement a new iterator. Let's say that you need an iterator that splits a vector into subvectors. That can allow you to process the vector in parallel, but still use vector operations, which is essential to getting good sequential performance in R. The following function returns just such an iterator: <>= ivector <- function(x, ...) { i <- 1 it <- idiv(length(x), ...) nextEl <- function() { n <- nextElem(it) ix <- seq(i, length=n) i <<- i + n x[ix] } obj <- list(nextElem=nextEl) class(obj) <- c('ivector', 'abstractiter', 'iter') obj } @ \texttt{ivector} uses \texttt{...} to pass options on to \texttt{idiv}. \texttt{idiv} supports the \texttt{chunks} argument to split its argument into a specified number of pieces, and the \texttt{chunkSize} argument to split it into pieces of a specified maximum size. Let's create an \texttt{ivector} iterator to split a vector into three pieces using the \texttt{chunks} argument: <>= it <- ivector(1:25, chunks=3) as.list(it) @ Note that the \texttt{nextEl} function doesn't seem to throw a \texttt{StopIteration} exception. It is actually throwing it indirectly, by calling \texttt{nextElem} on the iterator created via the \texttt{idiv} function. This function is fairly simple, because most of the tricky stuff is handled by \texttt{idiv}. \texttt{ivector} focuses on operating on the vector. It should be clear that only minor modification need to be made to this function to create an iterator over the blocks of rows or columns of a matrix or data frame. But I'll leave that as an exercise for the reader. \section{Adding a \texttt{hasNext} method to an iterator} At times it would be nice to write a loop that explicitly gets the values of an iterator. Although that is certainly possible with a standard iterator, it requires some rather awkward error handling. One solution to this problem is to add a method that indicates whether there is another value available in the iterator. Then you can write a simple while loop that stops when there are no more values. One way to do that would be to define a new S3 method called \texttt{hasNext}. Here's the definition of a \texttt{hasNext} generic function: <>= hasNext <- function(obj, ...) { UseMethod('hasNext') } @ We also need to define \texttt{hasNext} method for a iterator class that we'll call \texttt{ihasNext}: <>= hasNext.ihasNext <- function(obj, ...) { obj$hasNext() } @ As you can see, an \texttt{ihasNext} object must be a list with a \texttt{hasNext} element that is a function. That's the same technique that the \texttt{abstractiter} class uses to implement the \texttt{nextElem} method. Now we'll define a function, called \texttt{ihasNext}, that takes an arbitrary iterator and returns returns an \texttt{ihasNext} iterator that wraps the specified iterator. That allows us to turn any iterator into an \texttt{ihasNext} iterator, thus providing it with a \texttt{hasNext} method:\footnote{Thanks to Hadley Wickham for contributing this function, which I only hacked up a little. You can also find this function, along with \texttt{hasNext} and \texttt{hasNext.ihasNext} in the examples directory of the iterators packages.} <>= ihasNext <- function(it) { if (!is.null(it$hasNext)) return(it) cache <- NULL has_next <- NA nextEl <- function() { if (!hasNx()) stop('StopIteration', call.=FALSE) has_next <<- NA cache } hasNx <- function() { if (!is.na(has_next)) return(has_next) tryCatch({ cache <<- nextElem(it) has_next <<- TRUE }, error=function(e) { if (identical(conditionMessage(e), 'StopIteration')) { has_next <<- FALSE } else { stop(e) } }) has_next } obj <- list(nextElem=nextEl, hasNext=hasNx) class(obj) <- c('ihasNext', 'abstractiter', 'iter') obj } @ When the \texttt{hasNext} method is called, it calls the \texttt{nextElem} method on the underlying iterator, and the resulting value is saved. That value is then passed to the user when \texttt{nextElem} is called. Of course, it also does the right thing if you don't call \texttt{hasNext}, or if you call it multiple times before calling \texttt{nextElem}. So now we can easily create an \texttt{icount} iterator, and get its values in a while loop, without having to do any messy error handling: <>= it <- ihasNext(icount(3)) while (hasNext(it)) { print(nextElem(it)) } @ \section{A recycling iterator} The \texttt{ihasNext} function from the previous section is an interesting example of a function that takes an iterator and returns an iterator that wraps the specified iterator. In that case, we wanted to add another method to the iterator. In this example, we'll return an iterator that recycles the values of the wrapped iterator:\footnote{ Actually, some of the standard \texttt{iter} methods support a \texttt{recycle} argument. But this is a nice example, and a more general solution, since it works on any iterator.} <>= irecycle <- function(it) { values <- as.list(iter(it)) i <- length(values) nextEl <- function() { i <<- i + 1 if (i > length(values)) i <<- 1 values[[i]] } obj <- list(nextElem=nextEl) class(obj) <- c('irecycle', 'abstractiter', 'iter') obj } @ This is fairly nice, but note that this is another one of those infinite iterators that we need to be careful about. Also, make sure that you don't pass an infinite iterator to \texttt{irecycle}. That would be pointless of course, since there's no reason to recycle an iterator that never ends. It would be possible to write this to avoid that problem by not grabbing all of the values right up front, but you would still end up saving values that will never be recycled, so I've opted to keep this simple. Let's try it out: <>= it <- irecycle(icount(3)) unlist(as.list(it, n=9)) @ \section{Limiting infinite iterators} I was tempted to add an argument to the \texttt{irecycle} function to limit the number of values that it returns, because sometimes you want to recycle for awhile, but not forever. I didn't do that, because rather than make \texttt{irecycle} more complicated, I decided to write yet another function that takes an iterator and returns a modified iterator to handle that task: <>= ilimit <- function(it, times) { it <- iter(it) nextEl <- function() { if (times > 0) times <<- times - 1 else stop('StopIteration') nextElem(it) } obj <- list(nextElem=nextEl) class(obj) <- c('ilimit', 'abstractiter', 'iter') obj } @ Note that this looks an awful lot like the \texttt{irep} function that we implemented previously. In fact, using \texttt{ilimit}, we can implement \texttt{irep} using \texttt{iforever} much more simply, and without duplication of code: <>= irep2 <- function(x, times) ilimit(iforever(x), times) @ To demonstrate \texttt{irep2}, I'll use \texttt{ihasNext} and a while loop: <>= it <- ihasNext(irep2('foo', 3)) while (hasNext(it)) { print(nextElem(it)) } @ Here's one last example. Let's recycle a vector three times using \texttt{ilimit}, and convert it back into a vector using \texttt{as.list} and \texttt{unlist}: <>= iterable <- 1:3 n <- 3 it <- ilimit(irecycle(iterable), n * length(iterable)) unlist(as.list(it)) @ Sort of a complicated version of: <>= rep(iterable, n) @ Aren't iterators fun? \section{Conclusion} Writing your own iterators can be quite simple, and yet is very useful and powerful. It provides a very effective way to extend the capabilities of other packages that use iterators, such as the \texttt{foreach} package. By writing iterators that wrap other iterators, it is possible to put together a powerful and flexible set of tools that work well together, and that can solve many of the complex problems that come up in parallel computing. \end{document} iterators/inst/doc/iterators.R0000644000176200001440000000242413516640510016152 0ustar liggesusers### R code from vignette source 'iterators.Rnw' ################################################### ### code chunk number 1: ex1 ################################################### library(iterators) i1 <- iter(1:10) nextElem(i1) nextElem(i1) ################################################### ### code chunk number 2: ex2 ################################################### istate <- iter(state.x77, by='row') nextElem(istate) nextElem(istate) ################################################### ### code chunk number 3: ex3 ################################################### ifun <- iter(function() sample(0:9, 4, replace=TRUE)) nextElem(ifun) nextElem(ifun) ################################################### ### code chunk number 4: ex5 ################################################### library(iterators) itrn <- irnorm(10) nextElem(itrn) nextElem(itrn) ################################################### ### code chunk number 5: ex6 ################################################### itru <- irunif(10) nextElem(itru) nextElem(itru) ################################################### ### code chunk number 6: ex7 ################################################### it <- icount(3) nextElem(it) nextElem(it) nextElem(it) iterators/inst/unitTests/0000755000176200001440000000000013513447415015254 5ustar liggesusersiterators/inst/unitTests/runTestSuite.sh0000644000176200001440000000141413513447415020266 0ustar liggesusers#!/bin/sh LOGFILE=test.log R --vanilla --slave > ${LOGFILE} 2>&1 <<'EOF' library(iterators) library(RUnit) options(warn=1) options(showWarnCalls=TRUE) cat('Starting test at', date(), '\n') tests <- c('basicTest.R', 'iapplyTest.R', 'isplitTest.R', 'icountnTest.R', 'chunksizeTest.R', 'recycleTest.R') errcase <- list() for (f in tests) { cat('\nRunning test file:', f, '\n') t <- runTestFile(f) e <- getErrors(t) if (e$nErr + e$nFail > 0) { errcase <- c(errcase, t) print(t) } } if (length(errcase) == 0) { cat('*** Ran all tests successfully ***\n') } else { cat('!!! Encountered', length(errcase), 'problems !!!\n') for (t in errcase) { print(t) } } cat('Finished test at', date(), '\n') EOF iterators/inst/unitTests/iapplyTest.R0000644000176200001440000000175213513447415017542 0ustar liggesuserslibrary(iterators) # test iapply on 3D arrays test01 <- function() { test <- function(actual, it) { expected <- nextElem(it) checkEquals(expected, actual) NULL } a <- array(1:24, c(2,3,4)) margins <- list(1, 2, 3, c(1, 2), c(1, 3), c(2, 1), c(2, 3), c(3, 1), c(3, 2), c(1, 2, 3), c(1, 3, 2), c(2, 1, 3), c(2, 3, 1), c(3, 1, 2), c(3, 2, 1)) for(MARGIN in margins) { # cat(sprintf('testing %s\n', paste(MARGIN, collapse=', '))) it <- iapply(a, MARGIN) apply(a, MARGIN, test, it) } } # test iapply on matrices test02 <- function() { test <- function(actual, it) { expected <- nextElem(it) checkEquals(expected, actual) NULL } m <- matrix(1:24, c(6,4)) margins <- list(1, 2, c(1, 2), c(2, 1)) for(MARGIN in margins) { # cat(sprintf('testing %s\n', paste(MARGIN, collapse=', '))) it <- iapply(m, MARGIN) apply(m, MARGIN, test, it) } } iterators/inst/unitTests/chunksizeTest.R0000644000176200001440000000134113513447415020241 0ustar liggesuserslibrary(iterators) # test that various values of chunksize test01 <- function() { nr <- 13 nc <- 21 mat <- matrix(rnorm(nr * nc), nr) for (n in 1:(nc+2)) { it <- iter(mat, by='col', chunksize=n) bcols <- as.list(it) for (bcol in bcols) { checkTrue(nrow(bcol) == nr) checkTrue(ncol(bcol) <= n && ncol(bcol) >= 1) } actual <- do.call('cbind', bcols) checkEquals(mat, actual) } for (n in 1:(nr+2)) { it <- iter(mat, by='row', chunksize=n) brows <- as.list(it) for (brow in brows) { checkTrue(ncol(bcol) == nc) checkTrue(nrow(brow) <= n && nrow(brow) >= 1) } actual <- do.call('rbind', brows) checkEquals(mat, actual) } } iterators/inst/unitTests/isplitTest.R0000644000176200001440000000172613513447415017551 0ustar liggesuserslibrary(iterators) # test isplit with a single factor test01 <- function() { x <- rnorm(200) f <- factor(sample(1:10, length(x), replace=TRUE)) it <- isplit(x, f) expected <- split(x, f) for (i in expected) { actual <- nextElem(it) checkEquals(actual$value, i) } it <- isplit(x, f, drop=TRUE) expected <- split(x, f, drop=TRUE) for (i in expected) { actual <- nextElem(it) checkEquals(actual$value, i) } } # test isplit with two factors test02 <- function() { x <- rnorm(200) f <- list(factor(sample(1:10, length(x), replace=TRUE)), factor(sample(1:10, length(x), replace=TRUE))) it <- isplit(x, f) expected <- split(x, f) for (i in expected) { actual <- nextElem(it) checkEquals(actual$value, i) } it <- isplit(x, f, drop=TRUE) expected <- split(x, f, drop=TRUE) for (i in expected) { actual <- nextElem(it) checkEquals(actual$value, i) } } iterators/inst/unitTests/recycleTest.R0000644000176200001440000000053113513447415017664 0ustar liggesusers# simple test of recycle test01 <- function() { if (require(foreach, quietly=TRUE)) { nr <- 21 nc <- 17 x <- rnorm(nr) it <- iter(x, recycle=TRUE) actual <- foreach(y=it, icount(nr*nc), .combine='c') %do% y dim(actual) <- c(nr, nc) expected <- matrix(x, nr, nc) checkEquals(actual, expected) } } iterators/inst/unitTests/basicTest.R0000644000176200001440000000716213513447415017326 0ustar liggesuserslibrary(iterators) test00 <- function() {} # test vector iterator creation test01 <- function() { x <- iter(1:10) } # test hasNext, nextElem test02 <- function() { x <- iter(1:10) checkEquals(nextElem(x), 1) for(i in 1:9) nextElem(x) checkException(nextElem(x)) } # check checkFunc test03 <- function() { x <- iter(1:100, checkFunc=function(i) i%%10==0) checkEquals(nextElem(x), 10) for(i in 1:9) nextElem(x) checkException(nextElem(x)) } # test matrix iterator creation test04 <- function() { x <- matrix(1:10,ncol=2) } # test hasNext, nextElem test05 <- function() { x <- matrix(1:10,ncol=2) # by cell y <- iter(x,by='cell') checkEquals(nextElem(y), 1) for(i in 1:9) nextElem(y) checkException(nextElem(y)) # by col y <- iter(x,by='column') checkEquals(nextElem(y), matrix(1:5, ncol=1)) nextElem(y) checkException(nextElem(y)) # by row y <- iter(x,by='row') checkEquals(nextElem(y), matrix(c(1,6),nrow=1)) for(i in 1:4) nextElem(y) checkException(nextElem(y)) } # test checkFunc test06 <- function() { # create a larger matrix x <- matrix(1:100, ncol=20) # by cell y <- iter(x, by='cell', checkFunc=function(i) i%%10==0) checkEquals(nextElem(y), 10) for(i in 1:9) nextElem(y) checkException(nextElem(y)) # by col y <- iter(x, by='column', checkFunc=function(i) i[5]%%10==0) checkEquals(nextElem(y), as.matrix(x[,2])) for(i in 1:9) nextElem(y) checkException(nextElem(y)) # by row # create an easier matrix to deal with x <- matrix(1:100, nrow=20, byrow=TRUE) y <- iter(x, by='row', checkFunc=function(i) i[5]%%10==0) checkEquals(as.vector(nextElem(y)), x[2,]) for(i in 1:9) nextElem(y) checkException(nextElem(y)) } # test data frame iterator creation test07 <- function() { x <- data.frame(1:10, 11:20) y <- iter(x) } # test hasNext, nextElem test08 <- function() { x <- data.frame(1:10, 11:20) # by row y <- iter(x, by='row') checkEquals(nextElem(y), x[1,]) for(i in 1:9) nextElem(y) checkException(nextElem(y)) # by col y <- iter(x, by='column') checkEquals(nextElem(y), x[,1]) nextElem(y) checkException(nextElem(y)) } # test checkFunc test09 <- function() { x <- data.frame(1:10, 11:20) # by row y <- iter(x, by='row', checkFunc=function(i) i[[1]][1]%%2==0) checkEquals(nextElem(y),x[2,]) for(i in 1:4) nextElem(y) checkException(nextElem(y)) # by col y <- iter(x, by='column', checkFunc=function(i) i[[1]][1]%%11==0) checkEquals(nextElem(y), x[,2]) checkException(nextElem(y)) } # test function iterator creation # we need to test a function that takes no arguement as # well as one that takes the index test10 <- function() { noArgFunc <- function() 1 needArgFunc <- function(i) if(i>100) stop('too high') else i } # test hasNext, nextElem test11 <- function() { noArgFunc <- function() 1 needArgFunc <- function(i) if(i>100) stop('too high') else i y <- iter(noArgFunc) checkEquals(nextElem(y), 1) nextElem(y) y <- iter(needArgFunc) checkEquals(nextElem(y), 1) for (i in 1:99) nextElem(y) checkException(nextElem(y)) } # test checkFunc test12 <- function() { noArgFunc <- function() 1 needArgFunc <- function(i) if(i>100) stop('too high') else i y <- iter(noArgFunc, checkFunc=function(i) i==1) checkEquals(nextElem(y), 1) nextElem(y) y <- iter(needArgFunc, checkFunc=function(i) i%%10==0) checkEquals(nextElem(y), 10) for(i in 1:9) nextElem(y) checkException(nextElem(y)) } iterators/inst/unitTests/icountnTest.R0000644000176200001440000000131413513447415017715 0ustar liggesuserstest01 <- function() { if (require(foreach, quietly=TRUE)) { xcountn <- function(x) { iter(do.call('expand.grid', lapply(x, seq_len)), by='row') } vv <- list(0, 1, 2, 10, 100, c(0, 1), c(0, 2), c(3, 0), c(1, 1), c(1, 2), c(1, 3), c(2, 1), c(2, 2), c(2, 3), c(10, 10, 0, 10), c(1, 1, 2, 1, 1, 3, 1, 1, 1, 2, 1, 1, 1), c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), c(10, 10, 10, 10)) for (v in vv) { ait <- icountn(v) xit <- xcountn(v) foreach(actual=ait, expected=xit) %do% { checkEquals(actual, unname(unlist(expected))) } } } }