latte/0000755000176200001440000000000013446131133011362 5ustar liggesuserslatte/inst/0000755000176200001440000000000013437233233012343 5ustar liggesuserslatte/inst/CITATION0000644000176200001440000000246213423625302013501 0ustar liggesuserscitHeader("To cite latte in publications, please use:") citEntry(entry="Manual", author = "David Kahle and Luis Garcia-Puente and Ruriko Yoshida", title = "latte: {LattE} and {4ti2} in {R}", year = "2017", note = "R package version 0.2.0", url = "https://github.com/dkahle/latte", textVersion = "D. Kahle, L. Garcia-Puente, and R. Yoshida. latte: LattE and 4ti2 in R. R package version 0.2.0. https://github.com/dkahle/latte" ) citEntry(entry="Manual", author = "V. Baldoni and N. Berline and J.A. De Loera and B. Dutra and M. Koppe and S. Moreinis and G. Pinto and M. Vergne and J. Wu", title = "A User's Guide for {L}att{E} integrale v1.7.2", year = "2013", url = "http://www.math.ucdavis.edu/~latte/", textVersion = "V. Baldoni, N. Berline, J.A. De Loera, B. Dutra, M. Koppe, S. Moreinis, G. Pinto, M. Vergne, J. Wu, A User's Guide for LattE Integrale v1.7.2, 2013, software package LattE is available at http://www.math.ucdavis.edu/~latte/" ) citEntry(entry="Manual", author = "4ti2 Team", title = "4ti2---A software package for algebraic, geometric and combinatorial problems on linear spaces", year = "2013", url = "http://www.4ti2.de", textVersion = "4ti2 Team. 4ti2---A Software Package for Algebraic, Geometric and Combinatorial Problems on Linear Spaces. Available at www.4ti2.de" ) latte/inst/INSTALL.txt0000644000176200001440000001113513437561152014217 0ustar liggesusersThis file is intended to help you install LattE and 4ti2 for use in R through the latte package. On macOS or unix-alikes See the GitHub description of the install at https://github.com/latte-int/latte-distro. Essentially this will just require pulling down a tarball, extracting the files, navigating into the directory, and using the standard make sequence of ./configure, make, make install. Nevertheless, follow the very well-written instructions on that page. On Windows Windows is more challenging because both LattE and 4ti2 demand unix environments. In the future the Windows connection interface (Cygwin) will be changed to Docker containers to be significantly more extensible, lightweight, and easier to install. Nevertheless, the instructions below show how you can get up and running on a Windows machine. Feel free to contact david@kahle.io for more any questions/support! Step 1: Cygwin part. • Go to Cygwin website. • Click Install Cygwin on the left nav bar. • Click setup-x86.exe open the executable. • Install from Internet. • When the "Select Root Install Directory" page appears, click next. (C:\cygwin64 is assumed for this writeup.) • Click next until you get to the "Choose A Download Site" page. • Select any mirror (e.g. http://mirrors.kernel.org). • In the Select Packages screen, click the + next to All. Then * Click the icon to the right of Devel to change it from "Default" to "Install". * Click the icon to the right of Interpreters to change it from "Default" to "Install". * Click the icon to the right of Math to change it from "Default" to "Install". • Click next through everything to complete the download, and then install it; this last part takes a long time so be ready to wait. • Once you've installed Cygwin, open it from the start menu. Step 2: Unzip LattE. • Go to https://github.com/latte-int/latte/releases. • Click latte-integrale-1.7.5.tar.gz to download. • Move the downloaded file (latte-integrale-1.7.5.tar.gz) into your Cygwin home directory, for example, from C:\Users\david_kahle\Downloads to C:\cygwin64\home\david_kahle\ (Note that if you didn't open Cygwin, the user directory (\David_Kahle\) won't be there.) Step 3: In Cygwin. • Open Cygwin and type "pwd" and enter, the directory listed above should come up. (Now as /home/david_kahle, for example.) • Type "ls" and enter, you should see the latte-integrale-1.7.5.tar.gz that you put in from before. • Type tar -xf latte-integrale-1.7.5.tar.gz • Type mv latte-integrale-1.7.5 latte (this renames the directory to latte) • Type cd latte • Type ./configure --prefix=$HOME/latte --disable-lidia • Type make (this takes a very long time to work, so be ready to wait) • Type ls -al bin, you should see a relatively long list of stuff that includes count.exe (this is part of LattE) and markov.exe (this is part of 4ti2). If not, something went wrong. The executables are then made in the directory $HOME/latte/bin Step 4: Set the system path to include the new executables. • Edit the system path by the following: * Right click the My Computer icon on the desktop. Click "Advanced system settings" on the left nav bar, and then click Environment Variables under the Advanced tab (the window should be labeled System Properties). * Under System variables, click Path, then Edit... * Click New, then type "C:\cygwin64\bin", press Enter, click Move Up. * Click New, then type "C:\cygwin64\home\david_kahle\latte\bin", press Enter. and click OK. * Click Ok and Ok to get rid of all the windows. Step 5: Inside R. • Open R (the x64 version), and inside R type install.packages("latte") at the prompt and enter. If you want the dev version, see the instructions at https://github.com/dkahle/latte. • Type library(latte) • If you see a message saying that latte and/or 4ti2 are not found, use set_latte_path() and/or set_4ti2_path() to tell R where those files are. If you use one of those functions, navigate to where you created the executables. This is probably something like C:\cygwin64\home\david_kahle\latte\bin. If you're setting the LattE path, click count.exe and ok; if 4ti2, click markov and ok. • To check that the 4ti2 connection is made, type ?markov and run the first few examples; i.e. (A <- rbind( kprod(diag(3), ones(1,3)), kprod(ones(1,3), diag(3)) )) markov(A) You shouldn't get any errors. • To check that the LattE connection is made, type ?count and run the first few examples there; namely spec <- c("x + y <= 10", "x >= 1", "y >= 1") latte_count(spec) You shouldn't get any errors. latte/NAMESPACE0000644000176200001440000000323313445026547012615 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method(print,tableau) export(edit_r_environ) export(fgraver) export(fgroebner) export(fhilbert) export(fmarkov) export(format_latte) export(fzbasis) export(genmodel) export(get_4ti2_path) export(get_latte_path) export(graver) export(groebner) export(has_4ti2) export(has_latte) export(hilbert) export(kprod) export(latte_count) export(latte_fcount) export(latte_max) export(latte_min) export(markov) export(missing_4ti2_stop) export(missing_latte_stop) export(ones) export(plot_matrix) export(ppi) export(qsolve) export(read.latte) export(read_latte) export(set_4ti2_path) export(set_latte_path) export(tab2vec) export(tableau) export(vec2tab) export(write.latte) export(write_latte) export(zbasis) export(zsolve) import(mpoly) importFrom(dplyr,arrange) importFrom(dplyr,filter) importFrom(dplyr,mutate) importFrom(ggplot2,aes) importFrom(ggplot2,coord_equal) importFrom(ggplot2,element_blank) importFrom(ggplot2,geom_tile) importFrom(ggplot2,ggplot) importFrom(ggplot2,scale_fill_gradient) importFrom(ggplot2,scale_fill_gradient2) importFrom(ggplot2,scale_x_continuous) importFrom(ggplot2,scale_y_continuous) importFrom(ggplot2,theme) importFrom(ggplot2,theme_bw) importFrom(glue,glue) importFrom(magrittr,"%>%") importFrom(memoise,memoise) importFrom(stats,runif) importFrom(stringr,str_c) importFrom(stringr,str_detect) importFrom(stringr,str_extract) importFrom(stringr,str_extract_all) importFrom(stringr,str_replace) importFrom(stringr,str_replace_all) importFrom(stringr,str_split) importFrom(stringr,str_sub) importFrom(stringr,str_trim) importFrom(stringr,str_which) importFrom(usethis,edit_r_environ) importFrom(utils,download.file) latte/NEWS0000644000176200001440000000067413240157725012077 0ustar liggesusersVersion 0.1.2 ------------------------------------------------------------------------- CHANGES * Better citation. Version 0.1.1 ------------------------------------------------------------------------- NEWS * CRAN genesis Version 0.1.0 ------------------------------------------------------------------------- FIXES * The package can now be loaded on unix-alikes without a .bash_profile, .bashrc, or .profile (thanks @GrantInnerst) latte/R/0000755000176200001440000000000013445026654011575 5ustar liggesuserslatte/R/zsolve.R0000644000176200001440000001024213440624016013230 0ustar liggesusers#' Solve a linear system over the integers #' #' zsolve runs 4ti2's zsolve program to compute the configuration matrix A #' corresponding to graphical statistical models given by a simplicial complex #' and levels on the nodes. #' #' @param mat The A matrix (see the 4ti2 documentation or examples) #' @param rel A vector of "<" or ">" relations #' @param rhs The right hand side b #' @param sign The signs of the individual #' @param lat A lattice basis (instead of a matrix) #' @param lb Lower bounds on columns #' @param ub Upper bounds on columns #' @param dir Directory to place the files in, without an ending / #' @param quiet If FALSE, messages the 4ti2 output #' @param shell Messages the shell code used to do the computation #' @param ... Additional arguments to pass to the function #' @return The configuration matrix of the model provided #' @export #' @examples #' #' if (has_4ti2()) { #' #' mat <- rbind( #' c( 1, -1), #' c(-3, 1), #' c( 1, 1) #' ) #' rel <- c("<", "<", ">") #' rhs <- c(2, 1, 1) #' sign <- c(0, 1) #' #' zsolve(mat, rel, rhs, sign) #' zsolve(mat, rel, rhs, sign, quiet = FALSE) #' zsolve(mat, rel, rhs, sign, shell = TRUE) #' #' zsolve(mat, rel, rhs, sign, p = "gmp", quiet = FALSE) #' #' } #' #' zsolve <- function(mat, rel, rhs, sign, lat, lb, ub, dir = tempdir(), quiet = TRUE, shell = FALSE, ... ){ if (!has_4ti2()) missing_4ti2_stop() ## compute other args opts <- as.list(match.call(expand.dots = FALSE))[["..."]] if(is.null(opts)){ opts <- "" } else { opts <- paste0("-", names(opts), "", unlist(opts)) opts <- paste(opts, collapse = " ") } ## create and move to dir #################################### ## make dir to put 4ti2 files in (within the tempdir) timestamped dir.create(dir2 <- file.path(dir, timeStamp())) ## switch to temporary directory oldWd <- getwd() setwd(dir2); on.exit(setwd(oldWd), add = TRUE) ## arg check #################################### if(missing(mat) && missing(lat)) stop("Either mat or lat must be specified.", call. = FALSE) if(!missing(mat) && !all(is.wholenumber(mat))) stop("The entries of mat must all be integers.") if(!missing(lat) && !all(is.wholenumber(lat))) stop("The entries of lat must all be integers.") if(!missing(rhs) && !all(is.wholenumber(rhs))) stop("The entries of rhs must all be integers.") if(!all(rel %in% c("<", ">"))) stop("rel must be a vector of \"<\"'s or \">\"'s.") ## write files #################################### if(!missing(mat)) write.latte(mat, "system.mat") write.latte(t(rel), "system.rel") write.latte(t(rhs), "system.rhs") if(!missing(sign)) write.latte(t(sign), "system.sign") if(missing(mat) && !missing(lat)) write.latte(mat, "system.lat") if(!missing(lb)) write.latte(mat, "system.lb") if(!missing(ub)) write.latte(mat, "system.ub") ## move to dir and run 4it2 zsolve #################################### ## run 4ti2 if (is_mac() || is_unix()) { system2( file.path(get_4ti2_path(), "zsolve"), paste(opts, file.path(dir2, "system")), stdout = "zsolve_out", stderr = "zsolve_err" ) # generate shell code shell_code <- glue( "{file.path(get_4ti2_path(), 'zsolve')} {paste(opts, file.path(dir2, 'system'))} > zsolve_out 2> zsolve_err" ) if(shell) message(shell_code) } else if (is_win()) { matFile <- file.path(dir2, "system") matFile <- chartr("\\", "/", matFile) matFile <- str_c("/cygdrive/c", str_sub(matFile, 3)) system2( "cmd.exe", glue("/c env.exe {file.path(get_4ti2_path(), 'zsolve')} {opts} {matFile}"), stdout = "zsolve_out", stderr = "zsolve_err" ) # generate shell code shell_code <- glue( "cmd.exe /c env.exe {file.path(get_4ti2_path(), 'zsolve')} {opts} {matFile} > zsolve_out 2> zsolve_err" ) if(shell) message(shell_code) } ## print output, if desired if(!quiet) message(paste(readLines("zsolve_out"), "\n")) std_err <- readLines("zsolve_err") if(any(std_err != "")) warning(str_c(std_err, collapse = "\n"), call. = FALSE) ## read and return list( zinhom = read.latte("system.zinhom"), zhom = read.latte("system.zhom") ) } latte/R/tab2vec.R0000644000176200001440000000243613436637052013253 0ustar liggesusers#' Array to vector conversion #' #' Convert an array into a vector. #' #' This function converts an array (or a multi-way contingency table) into a #' vector, using a consistent ordering of the cells. The ordering of the cells #' is lexicographical and cannot be specified by the user. #' #' @param tab An array of counts #' @return a Named integer vector. The names correspond to the cell indices in #' the table. #' @export #' @seealso [vec2tab()] #' @examples #' #' a <- array(1:24, c(2,3,4)) #' tab2vec(a) #' #' data(Titanic) #' tab2vec(Titanic) #' Titanic[1,1,1,1] #' Titanic[1,1,1,2] #' #' tab2vec <- function(tab){ # if is a vector, return if(is.null(dim(tab))){ tab <- as.vector(tab) names(tab) <- 1:length(tab) return(tab) } # if it's a vector already, short-circuit if(length(dim(tab)) == 1){ tab <- as.vector(tab) names(tab) <- 1:length(tab) return(tab) } # otherwise, rotate and class u <- aperm(tab, length(dim(tab)):1) if(class(tab[1]) == "numeric") u <- as.vector(u) if(class(tab[1]) == "integer") u <- as.integer(u) # create cell indices tmpdf <- expand.grid( rev.default(lapply(dim(tab), function(x) 1:x)) )[,length(dim(tab)):1] # assign them as names to u names(u) <- apply(tmpdf, 1, paste, collapse = ',') # return u } latte/R/kprod.R0000644000176200001440000000155213437126720013036 0ustar liggesusers#' Iterated Kronecker product #' #' Compute the Kronecker product of several matrices. #' #' If kronecker is the function that computes A x B, kprod computes A x B x C #' and so on; it's a wrapper of Reduce and kronecker. #' #' @param ... A listing of matrices #' @param FUN A function to pass to [kronecker()] #' @return A matrix that is the kronecker product of the specified matrices #' (from left to right). #' @export #' @examples #' #' kprod(diag(2), t(ones(2))) #' kprod(t(ones(2)), diag(2)) #' #' #' kprod(diag(2), t(ones(2)), t(ones(2))) #' kprod(t(ones(2)), diag(2), t(ones(2))) #' kprod(t(ones(2)), t(ones(2)), diag(2)) #' #' #' # cf. aoki, hara, and takemura p.13 #' rbind( #' kprod(diag(2), t(ones(2))), #' kprod(t(ones(2)), diag(2)) #' ) #' #' kprod <- function(..., FUN = `*`) { Reduce( function(X, Y) kronecker(X, Y, FUN), list(...) ) } latte/R/helpers.R0000644000176200001440000000240513440572462013361 0ustar liggesusers rhash <- function(n) { paste( sample(c(letters, LETTERS, 0:9), n, replace = TRUE), collapse = "" ) } # rhash(10) timeStamp <- function(){ timeStamp <- as.character(Sys.time()) timeStamp <- chartr("-", "_", timeStamp) timeStamp <- chartr(" ", "_", timeStamp) timeStamp <- chartr(":", "_", timeStamp) timeStamp <- paste0(timeStamp, "_", rhash(10)) timeStamp } is.wholenumber <- function(x, tol = .Machine$double.eps^0.5) abs(x - round(x)) < tol file.path2 <- function(...){ dots <- list(...) if(.Platform$OS.type == "unix"){ sep <- "/" } else { sep <- "\\" } paste0(dots, collapse = sep) } is.formula <- function(x) inherits(x, "formula") is_mac <- function() grepl("darwin", R.version$platform) is_win <- function() .Platform$OS.type == "windows" is_linux <- function() (.Platform$OS.type == "unix") && (is_mac() == FALSE) is_unix <- function() .Platform$OS.type == "unix" is_solaris <- function() grepl("solaris", R.version$os) capitalize <- function(s){ if(length(s) > 1) return(vapply(s, capitalize, character(1))) str_c(toupper(str_sub(s, 1, 1)), str_sub(s, 2)) } `%notin%` <- function(elem, set){ if(length(elem) > 1) return(vapply(elem, `%notin%`, logical(1), set = set)) !(elem %in% set) } latte/R/ones.R0000644000176200001440000000061013437126720012655 0ustar liggesusers#' Ones #' #' Make an array of ones #' #' @param ... A sequence of dimensions separated by commas #' @return An integer array of ones #' @export #' @examples #' #' ones(5) #' ones(5, 1) #' ones(1, 5) #' ones(2, 3) #' ones(2, 3, 2) #' #' str(ones(5)) #' ones <- function(...){ dims <- as.integer(as.list(match.call(expand.dots = TRUE))[-1]) a <- rep(1L, prod(dims)) dim(a) <- dims a } latte/R/latte-optim.R0000644000176200001440000001520513442001070014140 0ustar liggesusers#' Solve an integer progam with LattE #' #' \code{latte_max} and \code{latte_min} use LattE's \code{latte-maximize} and #' \code{latte-minimize} functions to find the maximum or minimum of a linear #' objective function over the integers points in a polytope (i.e. satisfying #' linearity constraints). This makes use of the digging algorithm; see the #' LattE manual at \url{http://www.math.ucdavis.edu/~latte} for details. #' #' @param objective A linear polynomial to pass to [mp()], see examples #' @param constraints A collection of linear polynomial (in)equalities that #' define the feasibility region, the integers in the polytope #' @param method Method \code{"LP"} or \code{"cones"} #' @param dir Directory to place the files in, without an ending / #' @param opts Options; see the LattE manual at #' \url{http://www.math.ucdavis.edu/~latte} #' @param quiet Show latte output #' @param shell Messages the shell code used to do the computation #' @param type \code{"max"} or \code{"min"} #' @return A named list with components \code{par}, a named-vector of optimizing #' arguments, and \code{value}, the value of the objective function at the #' optimial point. #' @name latte-optim #' @examples #' #' #' if (has_latte()) { #' #' latte_max( #' "-2 x + 3 y", #' c("x + y <= 10", "x >= 0", "y >= 0") #' ) #' #' latte_max( #' "-2 x + 3 y", #' c("x + y <= 10", "x >= 0", "y >= 0"), #' quiet = FALSE #' ) #' #' #' df <- expand.grid("x" = 0:10, "y" = 0:10) #' df <- subset(df, x + y <= 10L) #' df$objective <- with(df, -2*x + 3*y) #' library("ggplot2") #' ggplot(df, aes(x, y, size = objective)) + #' geom_point() #' #' latte_min( #' "-2 x + 3 y", #' c("x + y <= 10", "x >= 0", "y >= 0"), #' method = "cones" #' ) #' #' #' #' latte_min("-2 x - 3 y - 4 z", c( #' "3 x + 2 y + z <= 10", #' "2 x + 5 y + 3 z <= 15", #' "x >= 0", "y >= 0", "z >= 0" #' ), "cones", quiet = FALSE) #' #' #' #' #' #' } #' latte_optim <- function( objective, constraints, type = c("max", "min"), method = c("lp","cones"), dir = tempdir(), opts = "", quiet = TRUE, shell = FALSE ){ if (!has_latte()) missing_latte_stop() type <- match.arg(type) method <- match.arg(method) ## set executable to use exec <- if(type == "max") "latte-maximize" else "latte-minimize" ## parse objective if(is.character(objective)) objective <- mp(objective) stopifnot(is.linear(objective)) ## parse constraints into the poly <= 0 format nConstraints <- length(constraints) if(is.character(constraints) && nConstraints > 1){ parsedCons <- as.list(rep(NA, nConstraints)) geqNdcs <- which(str_detect(constraints, " >= ")) leqNdcs <- which(str_detect(constraints, " <= ")) eeqNdcs <- which(str_detect(constraints, " == ")) eqNdcs <- which(str_detect(constraints, " = ")) if(length(geqNdcs) > 0){ tmp <- strsplit(constraints[geqNdcs], " >= ") parsedCons[geqNdcs] <- lapply(tmp, function(v) mp(v[2]) - mp(v[1])) } if(length(leqNdcs) > 0){ tmp <- strsplit(constraints[leqNdcs], " <= ") parsedCons[leqNdcs] <- lapply(tmp, function(v) mp(v[1]) - mp(v[2])) } if(length(eeqNdcs) > 0){ tmp <- strsplit(constraints[eeqNdcs], " == ") parsedCons[eeqNdcs] <- lapply(tmp, function(v) mp(v[1]) - mp(v[2])) } if(length(eqNdcs) > 0){ tmp <- strsplit(constraints[eqNdcs], " = ") parsedCons[eqNdcs] <- lapply(tmp, function(v) mp(v[1]) - mp(v[2])) } linearityNdcs <- sort(c(eeqNdcs, eqNdcs)) constraints <- parsedCons class(constraints) <- "mpolyList" if (!all(is.linear(constraints))) stop("all polynomials must be linear.", call. = FALSE) } ## mpoly_list_to_mat is in file count.r matFull <- mpoly_list_to_mat(c(list(objective), constraints)) ## make dir to put latte files in (within the tempdir) timestamped dir.create(dir2 <- file.path(dir, timeStamp())) ## switch to temporary directory oldWd <- getwd(); on.exit(setwd(oldWd), add = TRUE) setwd(dir2) ## convert constraints to latte hrep code and write file mat <- cbind( -matFull[-1,"coef",drop=FALSE], -matFull[-1,-ncol(matFull)] ) if(length(linearityNdcs) > 0) attr(mat, "linearity") <- linearityNdcs ## note: the nonnegative stuff is built into this write.latte(mat, "optim_code") ## convert objective to latte hrep code and write file mat <- cbind( matFull[1,"coef",drop=FALSE], matFull[1,-ncol(matFull),drop=FALSE] )[,-1, drop = FALSE] write.latte(mat, "optim_code.cost") ## run latte function if (is_mac() || is_unix()) { system2( file.path(get_latte_path(), exec), paste(opts, file.path(dir2, "optim_code")), stdout = glue("optim_out"), stderr = glue("optim_err") ) # generate shell code shell_code <- glue( "{file.path(get_latte_path(), exec)} {paste(opts, file.path(dir2, 'optim_code'))} > {exec}_out 2> {exec}_err" ) if(shell) message(shell_code) } else if(is_win()){ # windows matFile <- file.path(dir2, "optim_code 2> out.txt") matFile <- chartr("\\", "/", matFile) matFile <- str_c("/cygdrive/c", str_sub(matFile, 3)) system( paste( paste0("cmd.exe /c env.exe"), file.path(get_latte_path(), exec), opts, matFile ), intern = FALSE, ignore.stderr = FALSE ) } ## print count output when quiet = FALSE std_out <- readLines("optim_out") if(!quiet) cat(std_out, sep = "\n") # note: strangely, latte posts non-error info to stderr std_err <- readLines("optim_err") if(!quiet && any(std_err != "")) message(str_c(std_err, collapse = "\n")) ## parse output if (method == "cones") { optimal_solution_string <- std_err[str_which(std_err, "An optimal solution")] } else { optimal_solution_string <- std_err[str_which(std_err, "A vertex which we found")] } optimal_solution_string <- str_extract(optimal_solution_string, "\\[-?\\d+( -?\\d+)+\\].?$") par <- as.integer(str_extract_all(optimal_solution_string, "-?\\d+")[[1]]) names(par) <- colnames(matFull)[1:(ncol(matFull)-1)] val <- str_extract(std_err, "(?<=The optimal value is: )-?\\d+") val <- as.integer(val[!is.na(val)]) ## out list(par = par, value = val) } #' @rdname latte-optim #' @export latte_max <- function(objective, constraints, method = c("lp","cones"), dir = tempdir(), opts = "", quiet = TRUE ){ latte_optim(objective, constraints, "max", method, dir, opts, quiet) } #' @rdname latte-optim #' @export latte_min <- function(objective, constraints, method = c("lp","cones"), dir = tempdir(), opts = "", quiet = TRUE ){ latte_optim(objective, constraints, "min", method, dir, opts, quiet) } latte/R/plot-matrix.R0000644000176200001440000000261013442001070014155 0ustar liggesusers#' Plot a matrix #' #' plot_matrix is a R variant of Matlab's \code{spy} function. #' #' @param A A matrix #' @return a ggplot object #' @author David Kahle \email{david@@kahle.io} #' @name plot-matrix #' @examples #' #' # the no-three-way interaction configuration #' (A <- kprod(ones(1,3), diag(3), ones(3))) #' plot_matrix(A) #' #' #' if (has_4ti2()) { #' #' plot_matrix(markov(A)) #' #' (A <- genmodel(c(2L, 2L), list(1L, 2L))) #' plot_matrix(A) #' plot_matrix(markov(A)) #' #' (A <- genmodel(c(5L, 5L), list(1L, 2L))) #' plot_matrix(A) #' plot_matrix(markov(A)) #' #' } #' #' @rdname plot-matrix #' @export plot_matrix <- function(A){ x <- NULL; rm(x) y <- NULL; rm(y) low <- if(any(A < 0)){ low <- "blue"; high <- "red" fillScale <- scale_fill_gradient2( low = "blue", mid = "grey80", high = "red", midpoint = 0, guide = FALSE, space = "Lab" ) } else { fillScale <- scale_fill_gradient( low = "white", high = "black", guide = FALSE ) } df <- expand.grid(x = 1:ncol(A), y = 1:nrow(A)) B <- t(A) df$A <- as.integer(B[,ncol(B):1]) ggplot(df, aes(x, y, fill = A)) + geom_tile() + fillScale + theme_bw() + coord_equal() + scale_x_continuous(expand = c(0,0)) + scale_y_continuous(expand = c(0,0)) + theme( line = element_blank(), text = element_blank(), plot.margin = grid::unit(c(0, 0, 0, 0), "lines") ) } latte/R/latte-files.R0000644000176200001440000001037413442214162014124 0ustar liggesusers#' Format/read/write a matrix in latte's style #' #' [format_latte()] formats a matrix in latte's style. #' [write_latte()] writes a latte-formatted file to file. #' [read_latte()] reads a latte-formatted file from disk. #' #' @param mat A matrix #' @param file A filename #' @param format "mat" or "Ab" #' @return \itemize{ #' #' \item [format_latte()] -- A character string of the matrix in #' latte format. #' #' \item [write_latte()] -- An invisible character #' string of the formatted output. #' #' \item [read_latte()] -- An integer matrix. #' #' } #' @name latte-files #' @examples #' #' #' (mat <- matrix(sample(9), 3, 3)) #' #' format_latte(mat) #' cat(format_latte(mat)) #' #' (file <- file.path(tempdir(), "foo.hrep")) #' write_latte(mat, file) #' file.show(file) #' read_latte(file) #' read_latte(file, "Ab") #' #' attr(mat, "linearity") <- c(1, 3) #' attr(mat, "nonnegative") <- 2 #' mat #' format_latte(mat) #' cat(format_latte(mat)) #' write_latte(mat, file) #' file.show(file) #' read_latte(file) #' #' file.remove(file) #' #' #' #' @rdname latte-files #' @export format_latte <- function(mat, file){ ## construct file in latte format ## e.g. "3 3\n5 6 8\n7 3 4\n2 9 1" ## and cat("3 3\n5 6 8\n7 3 4\n2 9 1") r <- nrow(mat) c <- ncol(mat) a <- attributes(mat) mat <- apply(mat, 2, format, scientific = FALSE) attributes(mat) <- a out <- paste(r, c) out <- paste0(out, "\n") out <- paste0(out, paste( apply(unname(mat), 1, paste, collapse = " "), collapse = "\n" ) ) ## add linearity lines, if present if("linearity" %in% names(attributes(mat))){ linLines <- attr(mat, "linearity") linLineToAdd <- paste( "linearity", length(linLines), paste(linLines, collapse = " ") ) out <- paste(out, linLineToAdd, sep = "\n") } ## add nonnegative lines, if present if("nonnegative" %in% names(attributes(mat))){ nnegLines <- attr(mat, "nonnegative") nnegLineToAdd <- paste( "nonnegative", length(nnegLines), paste(nnegLines, collapse = " ") ) out <- paste(out, nnegLineToAdd, sep = "\n") } ## return out } #' @rdname latte-files #' @export write_latte <- function(mat, file){ ## arg check if(missing(file)) stop("file (a filename) must be provided.") ## format out <- format_latte(mat) ## save it to disk and return if(!missing(file)) writeLines(out, con = file) ## invisibly return code invisible(out) } #' @rdname latte-files #' @export write.latte <- write_latte #' @rdname latte-files #' @export read_latte <- function(file, format = c("mat", "Ab")){ ## check args format <- match.arg(format) ## read in file ## e.g. [1] "3 3" "7 2 1" "6 3 4" "9 8 5" contents <- readLines(file) ## eliminate dimensions ## e.g. [1] "7 2 1" "6 3 4" "9 8 5" dim <- as.integer(str_split(str_trim(contents[1]), " ")[[1]]) ## if only one line, return empty int matrix if(length(contents) == 1){ out <- integer(0) dim(out) <- dim return(out) } ## split and parse, result is list matRows <- lapply( str_split(str_trim(contents[2:(1+dim[1])]), " "), function(x) as.integer(x[nchar(x) > 0]) ) ## put into matrix mat <- t(simplify2array(matRows)) ## check for linearity or nonnegative lines if(length(contents) > 1 + dim[1]){ # isolate the added lines addedLines <- contents[-(1:(1 + dim[1]))] # look for linearity, assume only one such line linQ <- str_detect(addedLines, "linearity") if(any(linQ)){ linLine <- addedLines[linQ] linStuff <- str_replace(linLine, "linearity ", "") linNdcs <- as.integer(str_split(linStuff, " ")[[1]][-1]) attr(mat, "linearity") <- linNdcs } # look for nonnegative, assume only one such line nnegQ <- str_detect(addedLines, "nonnegative") if(any(nnegQ)){ nnegLine <- addedLines[nnegQ] nnegStuff <- str_replace(nnegLine, "nonnegative ", "") nnegNdcs <- as.integer(str_split(nnegStuff, " ")[[1]][-1]) attr(mat, "nonnegative") <- nnegNdcs } } ## format if(format == "mat"){ return(mat) } else if(format == "Ab"){ return(list(A = -mat[,-1,drop=FALSE], b = mat[,1])) } } #' @rdname latte-files #' @export read.latte <- read_latte latte/R/tableau.R0000644000176200001440000000441713216307376013342 0ustar liggesusers#' Tableau Notation for Markov #' #' Print the tableau notation for a Markov move. See the reference #' provided, p. 13. #' #' @param move a markov move matrix, where the columns are moves in #' vector form (e.g. the output of markov) #' @param dim the dimensions of the table form of the move, #' oftentimes a vector of the number of levels of each variable in #' order #' @return an object of class tableau #' @export tableau #' @references Drton, M., B. Sturmfels, and S. Sullivant (2009). #' \emph{Lectures on Algebraic Statistics}, Basel: Birkhauser #' Verlag AG. #' @examples #' #' vec <- matrix(c(1, -1, -1, 1), nrow = 4) #' varlvls <- c(2, 2) #' tableau(vec, varlvls) #' #' tableau <- function(move, dim){ if(is.vector(move) && (is.integer(move) || is.numeric(move))) move <- t(t(move)) if(ncol(move) == 1){ p <- length(dim) move <- t(t(tab2vec(vec2tab(move, dim)))) row.names(move) <- str_replace_all(row.names(move), ",", "") t1 <- row.names(move)[move > 0] t1 <- matrix( unlist(lapply(strsplit(t1, ''), as.numeric)), ncol = p, byrow = TRUE ) t2 <- row.names(move)[move < 0] t2 <- matrix( unlist(lapply(strsplit(t2, ''), as.numeric)), ncol = p, byrow = TRUE ) out <- list(t1, t2) } else { out <- list() for(k in 1:ncol(move)){ out[[k]] <- tableau(move[,k,drop = FALSE], dim = dim) } } class(out) <- 'tableau' out } #' Pretty printing of tableau output. #' #' Pretty printing of tableau output. #' #' @param x an object of class tableau #' @param ... ... #' @usage \method{print}{tableau}(x, ...) #' @return Invisible string of the printed object. #' @export #' @examples #' #' # see ?tableau #' #' print.tableau <- function(x, ...){ if((length(x) == 2) && all(sapply(x, is.matrix))){ plus <- x[[1]] minus <- x[[2]] p <- ncol(x[[1]]) changes <- nrow(x[[1]]) for(k in 1:changes){ if(k == floor(changes/2)){ sep <- ' - ' } else { sep <- ' ' } line2print <- paste( paste(plus[k,], collapse = ' '), sep, paste(minus[k,], collapse = ' '),'\n' ) cat(line2print) } } else { for(k in 1:length(x)){ print.tableau(x[[k]]) if(k < length(x)) cat('\n') } } } latte/R/lattice-bases.R0000644000176200001440000002415713445026503014442 0ustar liggesusers#' Compute a basis with 4ti2 #' #' 4ti2 provides several executables that can be used to generate bases for a #' configuration matrix A. See the references for details. #' #' @param A The configuration matrix #' @param format How the basis (moves) should be returned. if "mat", the moves #' are returned as the columns of a matrix. #' @param dim The dimension to be passed to [vec2tab()] if format = "tab" is #' used; a vector of the number of levels of each variable in order #' @param all If TRUE, all moves (+ and -) are given. if FALSE, only the + #' moves are given as returned by the executable. #' @param dir Directory to place the files in, without an ending / #' @param quiet If FALSE, messages the 4ti2 output #' @param shell Messages the shell code used to do the computation #' @param dbName The name of the model in the markov bases database, #' http://markov-bases.de, see examples #' @param ... Additional arguments to pass to the function, e.g. \code{p = #' "arb"} specifies the flag \code{-parb}; not setting this issues a common #' warning #' @return a matrix containing the Markov basis as its columns (for easy #' addition to tables) #' @name lattice-bases #' @references Drton, M., B. Sturmfels, and S. Sullivant (2009). \emph{Lectures #' on Algebraic Statistics}, Basel: Birkhauser Verlag AG. #' @examples #' #' #' if (has_4ti2()) { #' #' #' # basic input and output for the 3x3 independence example #' (A <- rbind( #' kprod(diag(3), ones(1,3)), #' kprod(ones(1,3), diag(3)) #' )) #' markov(A, p = "arb") #' #' #' #' # you can get the output formatted in different ways: #' markov(A, p = "arb", all = TRUE) #' markov(A, p = "arb", "vec") #' markov(A, p = "arb", "tab", c(3, 3)) #' tableau(markov(A, p = "arb"), dim = c(3, 3)) # tableau notation #' #' #' #' # you can add options by listing them off #' # to see the options available to you by function, #' # go to http://www.4ti2.de #' markov(A, p = "arb") #' #' #' #' # the basis functions are automatically cached for future use. #' # (note that it doesn't persist across sessions.) #' A <- rbind( #' kprod( diag(4), ones(1,4), ones(1,4)), #' kprod(ones(1,4), diag(4), ones(1,4)), #' kprod(ones(1,4), ones(1,4), diag(4)) #' ) #' system.time(markov(A, p = "arb")) #' system.time(markov(A, p = "arb")) #' #' # the un-cashed versions begin with an "f" #' # (think: "forgetful" markov) #' system.time(fmarkov(A, p = "arb")) #' system.time(fmarkov(A, p = "arb")) #' #' #' #' # you can see the command line code by typing shell = TRUE #' # and the standard output wiht quiet = FALSE #' # we illustrate these with fmarkov because otherwise it's cached #' (A <- rbind( #' kprod(diag(2), ones(1,4)), #' kprod(ones(1,4), diag(2)) #' )) #' fmarkov(A, p = "arb", shell = TRUE) #' fmarkov(A, p = "arb", quiet = FALSE) #' #' #' #' # compare the bases for the 3x3x3 no-three-way interaction model #' A <- rbind( #' kprod( diag(3), diag(3), ones(1,3)), #' kprod( diag(3), ones(1,3), diag(3)), #' kprod(ones(1,3), diag(3), diag(3)) #' ) #' str( zbasis(A, p = "arb")) # 8 elements = ncol(A) - qr(A)$rank #' str( markov(A, p = "arb")) # 81 elements #' str(groebner(A, p = "arb")) # 110 elements #' str( graver(A)) # 795 elements #' #' #' # the other bases are also cached #' A <- rbind( #' kprod( diag(3), ones(1,3), ones(1,2)), #' kprod(ones(1,3), diag(3), ones(1,2)), #' kprod(ones(1,3), ones(1,3), diag(2)) #' ) #' system.time( graver(A)) #' system.time( graver(A)) #' system.time(fgraver(A)) #' system.time(fgraver(A)) #' #' #' #' # LAS ex 1.2.1, p.12 : 2x3 independence #' (A <- rbind( #' kprod(diag(2), ones(1,3)), #' kprod(ones(1,2), diag(3)) #' )) #' #' markov(A, p = "arb", "tab", c(3, 3)) #' # Prop 1.2.2 says that there should be #' 2*choose(2, 2)*choose(3,2) # = 6 #' # moves (up to +-1) #' markov(A, p = "arb", "tab", c(3, 3), TRUE) #' #' #' #' # LAS example 1.2.12, p.17 (no 3-way interaction) #' (A <- rbind( #' kprod( diag(2), diag(2), ones(1,2)), #' kprod( diag(2), ones(1,2), diag(2)), #' kprod(ones(1,2), diag(2), diag(2)) #' )) #' plot_matrix(A) #' markov(A, p = "arb") #' groebner(A, p = "arb") #' graver(A) #' tableau(markov(A, p = "arb"), dim = c(2,2,2)) #' #' #' #' #' #' # using the markov bases database, must be connected to internet #' # commented out for predictable and fast cran checks time #' # A <- markov(dbName = "ind3-3") #' # B <- markov(rbind( #' # kprod(diag(3), ones(1,3)), #' # kprod(ones(1,3), diag(3)) #' # ), p = "arb") #' # all(A == B) #' #' #' #' #' #' # possible issues #' # markov(diag(1, 10)) #' # zbasis(diag(1, 10), "vec") #' # groebner(diag(1, 10), "vec", all = TRUE) #' # graver(diag(1, 10), "vec", all = TRUE) #' # graver(diag(1, 4), "tab", all = TRUE, dim = c(2,2)) #' #' #' #' } #' #' #' @param exec don't use this parameter #' @param memoise don't use this parameter basis <- function(exec, memoise = TRUE){ ## stuff in basis extension <- switch(exec, markov = ".mar", groebner = ".gro", hilbert = ".hil", graver = ".gra", zbasis = ".lat", zsolve = ".zfree" ) commonName <- switch(exec, markov = "markov", groebner = "grobner", hilbert = "hilbert", graver = "graver", zbasis = "lattice", zsolve = "solve" ) ## memoise or not mem_or_not <- if(memoise) memoise::memoise else (function(x) x) ## create the function to return mem_or_not(function(A, format = c("mat", "vec", "tab"), dim = NULL, all = FALSE, dir = tempdir(), quiet = TRUE, shell = FALSE, dbName = NULL, ... ){ if (!has_4ti2()) missing_4ti2_stop() ## check args format <- match.arg(format) if (format == "tab" && missing(dim)) { stop('If format = "tab" is specified, dim must be also.', call. = FALSE) } ## compute other args opts <- as.list(match.call(expand.dots = FALSE))[["..."]] if (is.null(opts)) { opts <- "" } else { opts <- str_c("-", names(opts), "", unlist(opts)) opts <- str_c(opts, collapse = " ") } ## make dir to put 4ti2 files in (within the tempdir) timestamped dir.create(dir2 <- file.path(dir, timeStamp())) ## make 4ti2 file if(!missing(A)) write.latte(A, file.path(dir2, "PROJECT.mat")) ## switch to temporary directory oldWd <- getwd() setwd(dir2); on.exit(setwd(oldWd), add = TRUE) ## create/retrieve markov basis if (is.null(dbName)) { ## run 4ti2 if needed if (is_mac() || is_unix()) { system2( file.path(get_4ti2_path(), exec), paste(opts, file.path(dir2, "PROJECT")), stdout = glue("{exec}_out"), stderr = glue("{exec}_err") ) # generate shell code shell_code <- glue( "{file.path(get_4ti2_path(), exec)} {paste(opts, file.path(dir2, 'PROJECT'))} > {exec}_out 2> {exec}_err" ) if(shell) message(shell_code) } else if (is_win()) { matFile <- file.path(dir2, "PROJECT") matFile <- chartr("\\", "/", matFile) matFile <- str_c("/cygdrive/c", str_sub(matFile, 3)) system2( "cmd.exe", glue("/c env.exe {file.path(get_4ti2_path(), exec)} {opts} {matFile}"), stdout = glue("{exec}_out"), stderr = glue("{exec}_err") ) # generate shell code shell_code <- glue( "cmd.exe /c env.exe {file.path(get_4ti2_path(), exec)} {opts} {matFile} > {exec}_out 2> {exec}_err" ) if(shell) message(shell_code) } if(!quiet) cat(readLines(glue("{exec}_out")), sep = "\n") std_err <- readLines(glue("{exec}_err")) if(any(std_err != "")) warning(str_c(std_err, collapse = "\n"), call. = FALSE) } else { # if the model name is specified download.file( paste0("http://markov-bases.de/data/", dbName, "/", dbName, extension), destfile = "PROJECT.mar" # already in tempdir ) } ## fix case of no graver basis if(exec == "graver"){ if(paste0("PROJECT", extension) %notin% list.files(dir2)){ warning(sprintf("%s basis empty, returning 0's.", capitalize(commonName)), call. = FALSE) return(fix_graver(A, format, dim)) } } ## figure out what files to keep them, and make 4ti2 object basis <- t(read.latte(paste0("PROJECT", extension))) ## fix case of no basis basisDim <- dim(basis) noBasisFlag <- FALSE if(any(basisDim == 0)){ noBasisFlag <- TRUE warning(sprintf("%s basis empty, returning 0's.", capitalize(commonName)), call. = FALSE) basisDim[basisDim == 0] <- 1L basis <- rep(0L, prod(basisDim)) dim(basis) <- basisDim } ## format if(all && !noBasisFlag) basis <- cbind(basis, -basis) # out if(format == "mat"){ return(basis) } else { lbasis <- as.list(rep(NA, ncol(basis))) for(k in 1:ncol(basis)) lbasis[[k]] <- basis[,k] if(format == "vec") return(lbasis) if(format == "tab") return(lapply(lbasis, vec2tab, dim = dim)) } }) } # #' @export # #' @rdname lattice-bases # zsolve <- basis("zsolve", memoise = TRUE) #' @export #' @rdname lattice-bases zbasis <- basis("zbasis", memoise = TRUE) #' @export #' @rdname lattice-bases markov <- basis("markov", memoise = TRUE) #' @export #' @rdname lattice-bases groebner <- basis("groebner", memoise = TRUE) #' @export #' @rdname lattice-bases hilbert <- basis("hilbert", memoise = TRUE) #' @export #' @rdname lattice-bases graver <- basis("graver", memoise = TRUE) # #' @export # #' @rdname lattice-bases # fzsolve <- basis("zsolve", memoise = FALSE) #' @export #' @rdname lattice-bases fzbasis <- basis("zbasis", memoise = FALSE) #' @export #' @rdname lattice-bases fmarkov <- basis("markov", memoise = FALSE) #' @export #' @rdname lattice-bases fgroebner <- basis("groebner", memoise = FALSE) #' @export #' @rdname lattice-bases fhilbert <- basis("hilbert", memoise = FALSE) #' @export #' @rdname lattice-bases fgraver <- basis("graver", memoise = FALSE) fix_graver <- function(A, format, dim){ if(format == "mat"){ return(matrix(0L, nrow = ncol(A))) } else { lbasis <- list(rep(0L, ncol(A))) if(format == "vec") return(lbasis) if(format == "tab") return(lapply(lbasis, vec2tab, dim = dim)) } } latte/R/ppi.R0000644000176200001440000000453613440624035012510 0ustar liggesusers#' Compute the primitive partition identities #' #' ppi runs 4ti2's ppi program to compute the primitive partition identities, #' that is, the Graver basis of 1:N. #' #' @param N A postive integer > 2 #' @param dir Directory to place the files in, without an ending / #' @param quiet If FALSE, messages the 4ti2 output #' @param shell Messages the shell code used to do the computation #' @param ... Additional arguments to pass to the function #' @return A matrix containing the basis as its columns (for easy addition to #' tables) #' @seealso [graver()] #' @export #' @examples #' #' if (has_4ti2()) { #' #' ppi(3) #' t(ppi(3)) %*% 1:3 #' plot_matrix(ppi(3)) #' #' graver(t(1:3)) #' plot_matrix(graver(t(1:3))) #' #' ppi(5, quiet = FALSE, shell = TRUE) #' #' } #' #' ppi <- function(N, dir = tempdir(), quiet = TRUE, shell = FALSE, ...){ if (!has_4ti2()) missing_4ti2_stop() ## arg checking stopifnot(is.wholenumber(N) && N > 2) ## compute other args opts <- as.list(match.call(expand.dots = FALSE))[["..."]] if(is.null(opts)){ opts <- "" } else { opts <- str_c("-", names(opts), "", unlist(opts)) opts <- str_c(opts, collapse = " ") } ## move to dir and run 4it2 ppi #################################### ## make dir to put 4ti2 files in (within the tempdir) timestamped dir.create(dir2 <- file.path(dir, timeStamp())) ## switch to temporary directory oldWd <- getwd() setwd(dir2); on.exit(setwd(oldWd), add = TRUE) ## run 4ti2 if (is_mac() || is_unix()) { system2( file.path(get_4ti2_path(), "ppi"), paste(opts, N), stdout = "ppi_out", stderr = "ppi_err" ) # generate shell code shell_code <- glue( "{file.path(get_4ti2_path(), 'ppi')} {paste(opts, file.path(dir2, 'system'))} > ppi_out 2> ppi_err" ) if(shell) message(shell_code) } else if (is_win()) { system2( "cmd.exe", glue("/c env.exe {file.path(get_4ti2_path(), 'ppi')} {opts} {N}"), stdout = "ppi_out", stderr = "ppi_err" ) # generate shell code shell_code <- glue( "cmd.exe /c env.exe {file.path(get_4ti2_path(), 'ppi')} {opts} {N} > ppi_out 2> ppi_err" ) if(shell) message(shell_code) } ## print output, if desired if(!quiet) cat(readLines("ppi_out"), sep = "\n") ## read and return t(read.latte(str_c("ppi", N, ".gra"))) } latte/R/genmodel.R0000644000176200001440000000677213440565540013523 0ustar liggesusers#' Generate a configuration matrix #' #' genmodel runs 4ti2's genmodel program to compute the configuration matrix A #' corresponding to graphical statistical models given by a simplicial complex #' and levels on the nodes. #' #' @param varlvls a vector containing the number of levels of each variable #' @param facets the facets generating the hierarchical model, a list of vectors #' of variable indices #' @param dir Directory to place the files in, without an ending / #' @param quiet If FALSE, messages the 4ti2 output #' @param shell Messages the shell code used to do the computation #' @param ... Additional arguments to pass to the function #' @return The configuration matrix of the model provided #' @export #' @examples #' #' if (has_4ti2()) { #' #' varlvls <- rep(2, 2) #' facets <- list(1, 2) #' genmodel(varlvls, facets) #' genmodel(varlvls, facets, quiet = FALSE) #' #' varlvls <- rep(3, 3) #' facets <- list(1:2, 2:3, c(3,1)) #' genmodel(varlvls, facets) #' #' # compare this to algstat's hmat function #' #' } #' genmodel <- function(varlvls, facets, dir = tempdir(), quiet = TRUE, shell = FALSE, ... ){ if (!has_4ti2()) missing_4ti2_stop() ## compute other args opts <- as.list(match.call(expand.dots = FALSE))[["..."]] if (is.null(opts)) { opts <- "" } else { opts <- str_c("-", names(opts), "", unlist(opts)) opts <- str_c(opts, collapse = " ") } ## compute/write 4ti2 code file #################################### ## format varlvls formatted_varlvls <- str_sub(format_latte(t(varlvls)), 3) ## format simplices formatted_facets <- vapply( facets, function(v) paste(length(v), paste(v, collapse = " ")), character(1) ) formatted_facets <- paste( length(facets), paste(formatted_facets, collapse = "\n"), sep = "\n" ) ## bring the two together code <- paste(formatted_varlvls, formatted_facets, sep = "\n") ## make dir to put 4ti2 files in (within the tempdir) timestamped dir.create(dir2 <- file.path(dir, timeStamp())) ## make 4ti2 file writeLines(code, con = file.path(dir2, "PROJECT.mod")) ## move to dir and run 4it2 genmodel #################################### ## switch to temporary directory oldWd <- getwd() setwd(dir2); on.exit(setwd(oldWd), add = TRUE) ## run 4ti2 if (is_mac() || is_unix()) { system2( file.path(get_4ti2_path(), "genmodel"), paste(opts, file.path(dir2, "PROJECT")), stdout = "genmodel_out", stderr = "genmodel_err" ) # generate shell code shell_code <- glue( "{file.path(get_4ti2_path(), 'genmodel')} {paste(opts, file.path(dir2, 'PROJECT'))} > genmodel_out 2> genmodel_err" ) if(shell) message(shell_code) } else if (is_win()) { matFile <- file.path(dir2, "PROJECT") matFile <- chartr("\\", "/", matFile) matFile <- str_c("/cygdrive/c", str_sub(matFile, 3)) system2( "cmd.exe", glue("/c env.exe {file.path(get_4ti2_path(), 'genmodel')} {opts} {matFile}"), stdout = "genmodel_out", stderr = "genmodel_err" ) # generate shell code shell_code <- glue( "cmd.exe /c env.exe {file.path(get_4ti2_path(), 'genmodel')} {opts} {matFile} > genmodel_out 2> genmodel_err" ) if(shell) message(shell_code) } ## print output, if desired if(!quiet) message(paste0(readLines("genmodel_out"), "\n")) std_err <- readLines("genmodel_err") if(any(std_err != "")) warning(str_c(std_err, collapse = "\n"), call. = FALSE) ## read and return read.latte(paste0("PROJECT", ".mat")) } latte/R/latte.R0000644000176200001440000000153713445026503013030 0ustar liggesusers#' R Interface to LattE and 4ti2 #' #' Back-end connections to LattE (\url{https://www.math.ucdavis.edu/~latte/}) #' and 4ti2 (\url{http://www.4ti2.de/}) executables and front-end tools #' facilitating their use in the R ecosystem. #' #' @docType package #' @import mpoly #' @importFrom ggplot2 ggplot scale_x_continuous scale_y_continuous theme #' element_blank theme_bw coord_equal scale_fill_gradient scale_fill_gradient2 #' aes geom_tile #' @importFrom magrittr %>% #' @importFrom stats runif #' @importFrom utils download.file #' @importFrom stringr str_detect str_sub str_c str_replace str_replace_all #' str_split str_trim str_extract str_extract_all str_which #' @importFrom dplyr filter mutate arrange #' @importFrom memoise memoise #' @importFrom usethis edit_r_environ #' @importFrom glue glue #' @name latte #' @aliases latte package-latte NULL latte/R/set-paths.R0000644000176200001440000001040613442000604013611 0ustar liggesusers#' Set paths to LattE and 4ti2 executables #' #' These functions set the path to external programs either by (1) passing them #' a character string or (2) using [file.choose()]. #' #' When latte is loaded it attempts to find LattE and 4ti2 executables #' (represented by count and markov, respectively). How it looks depends on #' your operating system. #' #' If you're using a Mac or Linux machine, it looks based on your system's path. #' Unfortunately, R changes the system path in such a way that the path that R #' sees is not the same as the path that you'd see if you were working in the #' terminal. (You can open the Terminal app on a Mac by going to #' /Applications/Utilities/Terminal.) Consequently, latte tries to guess the #' file in which your path is set. To do so, it first checks if your home #' directory (type echo ~/ in the terminal to figure out which directory this is #' if you don't know) for the file named .bash_profile. If this file is #' present, it runs it and then checks your system's path variable (echo $PATH). #' If it's not present, it does the same for .bashrc and then .profile. In any #' case, once it has its best guess at your path, it looks for "latte". #' #' On Windows, latte just uses [Sys.which()] on "whereis" to On Windows, latte #' just uses [Sys.which()] on "whereis" to determine where the executables count #' and markov are (for LattE and 4ti2, respectively). #' #' @param path A character string, the path to a 4ti2 function (e.g. markov) for #' setting 4ti2's path or a LattE function (e.g. count) for LattE's path #' @return An invisible character string, the path found. More importantly, the #' function has the side effect of setting the option "latte_path" or #' "4ti2_path" #' @name pathing #' @author David Kahle \email{david@@kahle.io} #' @examples #' #' #' has_4ti2() #' if (has_4ti2()) get_4ti2_path() #' #' has_latte() #' if (has_4ti2()) get_latte_path() #' #' # these are stored in your .Renviron file; that's where you should put the #' # path to LattE and 4ti2 executables. for example, you should have a lines #' # that look like #' # LATTE=/Applications/latte/bin #' # 4TI2=/Applications/latte/bin #' # you can set these with usethis::edit_r_environ() #' #' # you can change these in your current session with set_latte_path() and #' # set_4ti2_path(), for example set_4ti2_path("/path/to/4ti2") #' #' NULL #' @rdname pathing #' @export set_latte_path <- function(path){ if(missing(path) && interactive()){ latte_path <- dirname(file.choose()) if(is_win() && str_detect(latte_path,"C:/")){ latte_path <- str_replace(dirname(latte_path), "C:/", "/cygdrive/c/") } Sys.setenv("LATTE" = latte_path) return(invisible(latte_path)) } else if(!missing(path)){ Sys.setenv("LATTE" = path) return(invisible(path)) } else { stop( "If the session is not interactive, a path must be specified.", call. = FALSE ) } } #' @rdname pathing #' @export set_4ti2_path <- function(path){ if(missing(path) && interactive()){ `4ti2_path` <- dirname(file.choose()) if(is_win() && str_detect(`4ti2_path`,"C:/")){ `4ti2_path` <- str_replace(`4ti2_path`, "C:/", "/cygdrive/c/") } Sys.setenv("4TI2" = `4ti2_path`) return(invisible(`4ti2_path`)) } else if(!missing(path)){ Sys.setenv("4TI2" = path) return(invisible(path)) } else { stop( "If the session is not interactive, a path must be specified.", call. = FALSE ) } } #' @rdname pathing #' @export get_4ti2_path <- function() Sys.getenv("4TI2") #' @rdname pathing #' @export get_latte_path <- function() Sys.getenv("LATTE") #' @rdname pathing #' @export has_4ti2 <- function() get_4ti2_path() != "" #' @rdname pathing #' @export has_latte <- function() get_latte_path() != "" #' @rdname pathing #' @export missing_4ti2_stop <- function() { stop( "latte doesn't know where 4ti2 is.\n", "See ?set_4ti2_path to learn how to set it.", call. = FALSE ) } #' @rdname pathing #' @export missing_latte_stop <- function() { stop( "latte doesn't know where LattE is.\n", "See ?set_latte_path to learn how to set it.", call. = FALSE ) } #' @importFrom usethis edit_r_environ #' @export usethis::edit_r_environ latte/R/attach.R0000644000176200001440000000060413440553500013152 0ustar liggesusers.onAttach <- function(...) { packageStartupMessage(' Please cite latte! See citation("latte") for details.') if (!has_4ti2()) { packageStartupMessage(" - 4ti2 was not set in .Renviron. Use set_4ti2_path() to set it.") } if (!has_latte()) { packageStartupMessage(" - LattE was not in .Renviron. Use set_latte_path() to set it.") } invisible(TRUE) } latte/R/vec2tab.R0000644000176200001440000000161113436637052013245 0ustar liggesusers#' Vector to array conversion #' #' Convert a vector into an array given a set of dimensions; it therefore simply #' wraps [aperm()] and [array()]. #' #' This function converts an array (or a multi-way contingency table) into a #' vector, using a consistent ordering of the cells. The ordering of the cells #' is lexicographical and cannot be specified by the user. #' #' @param vec A vector #' @param dim The desired array dimensions, oftentimes a vector of the number of #' levels of each variable in order #' @return An array #' @export #' @seealso [tab2vec()], [aperm()], [array()] #' @examples #' #' data(Titanic) #' Titanic #' tab2vec(Titanic) #' vec2tab(tab2vec(Titanic), dim(Titanic)) #' vec2tab(tab2vec(Titanic), dim(Titanic)) == Titanic #' all(vec2tab(tab2vec(Titanic), dim(Titanic)) == Titanic) #' #' vec2tab <- function(vec, dim){ aperm( array(vec, rev(dim)), length(dim):1 ) } latte/R/qsolve.R0000644000176200001440000000720213440611255013222 0ustar liggesusers#' Solve a linear system over the rationals #' #' qsolve runs 4ti2's qsolve program to compute the #' configuration matrix A corresponding to graphical statistical #' models given by a simplicial complex and levels on the nodes. #' #' @param mat The A matrix (see the 4ti2 documentation or examples) #' @param rel A vector of "<" or ">" relations #' @param sign The signs of the individual #' @param dir Directory to place the files in, without an ending / #' @param quiet If FALSE, messages the 4ti2 output #' @param shell Messages the shell code used to do the computation #' @param ... Additional arguments to pass to the function #' @return The configuration matrix of the model provided #' @export #' @examples #' #' if (has_4ti2()) { #' #' # x + y > 0 #' # x + y < 0 #' #' mat <- rbind( #' c( 1, 1), #' c( 1, 1) #' ) #' rel <- c(">", "<") #' sign <- c(0, 0) #' #' qsolve(mat, rel, sign, p = "arb") #' qsolve(mat, rel, sign, p = "arb", quiet = FALSE) #' qsolve(mat, rel, sign, p = "arb", shell = TRUE) #' #' } #' #' qsolve <- function(mat, rel, sign, dir = tempdir(), quiet = TRUE, shell = FALSE, ... ){ if (!has_4ti2()) missing_4ti2_stop() ## compute other args opts <- as.list(match.call(expand.dots = FALSE))[["..."]] if("rhs" %in% names(opts)) stop("qsolve only solve homogeneous systems (b = 0).") if(is.null(opts)){ opts <- "" } else { opts <- paste0("-", names(opts), "", unlist(opts)) opts <- paste(opts, collapse = " ") } ## create and move to dir #################################### ## make dir to put 4ti2 files in (within the tempdir) timestamped dir.create(dir2 <- file.path(dir, timeStamp())) ## switch to temporary directory oldWd <- getwd() setwd(dir2); on.exit(setwd(oldWd), add = TRUE) ## arg check #################################### if(!missing(mat) && !all(is.wholenumber(mat))) stop("The entries of mat must all be integers.") if(!missing(sign) && !all(is.wholenumber(sign))) stop("The entries of sign must all be integers.") if(!all(rel %in% c("<", ">"))) stop("rel must be a vector of \"<\"'s or \">\"'s.") ## write files #################################### if(!missing(mat)) write.latte(mat, "system.mat") write.latte(t(rel), "system.rel") if(!missing(sign)) write.latte(t(sign), "system.sign") ## move to dir and run 4it2 qsolve #################################### ## run 4ti2 if (is_mac() || is_unix()) { system2( file.path(get_4ti2_path(), "qsolve"), paste(opts, file.path(dir2, "system")), stdout = "qsolve_out", stderr = "qsolve_err" ) # generate shell code shell_code <- glue( "{file.path(get_4ti2_path(), 'qsolve')} {paste(opts, file.path(dir2, 'system'))} > qsolve_out 2> qsolve_err" ) if(shell) message(shell_code) } else if (is_win()) { matFile <- file.path(dir2, "system") matFile <- chartr("\\", "/", matFile) matFile <- str_c("/cygdrive/c", str_sub(matFile, 3)) system2( "cmd.exe", glue("/c env.exe {file.path(get_4ti2_path(), 'qsolve')} {opts} {matFile}"), stdout = "qsolve_out", stderr = "qsolve_err" ) # generate shell code shell_code <- glue( "cmd.exe /c env.exe {file.path(get_4ti2_path(), 'qsolve')} {opts} {matFile} > qsolve_out 2> qsolve_err" ) if(shell) message(shell_code) } ## print output, if desired if(!quiet) message(paste(readLines("qsolve_out"), "\n")) std_err <- readLines("qsolve_err") if(any(std_err != "")) warning(str_c(std_err, collapse = "\n"), call. = FALSE) ## read and return list( qhom = read.latte("system.qhom"), qfree = read.latte("system.qfree") ) } latte/R/latte-count.R0000644000176200001440000002612613442000604014146 0ustar liggesusers#' Count integer points in a polytope #' #' \code{latte_count} uses LattE's count function to count the (integer) lattice #' points in a polytope and compute Ehrhart polynomials. #' #' The specification should be one of the following: (1) a character string or #' strings containing an inequality in the mpoly expression format (see #' examples), (2) a list of vertices, (3) a list of A and b for the equation Ax #' <= b (see examples), or (4) raw code for LattE's count program. If a #' character vector is supplied, (1) and (4) are distinguished by the number of #' strings. #' #' Behind the scenes, count works by writing a latte file and running count on #' it. If a specification other than a length one character is given to it #' (which is considered to be the code), count attempts to convert it into LattE #' code and then run count on it. #' #' @param spec Specification, see details and examples #' @param dir Directory to place the files in, without an ending / #' @param quiet Show latte output? #' @param mpoly When opts = "--ehrhart-polynomial", return the mpoly version of #' it #' @param ... Additional arguments to pass to the function, see count --help at #' the command line to see examples. Note that dashes - should be specified #' with underscores _ #' @return The count. If the count is a number has less than 10 digits, an #' integer is returned. If the number has 10 or more digits, an integer in a #' character string is returned. You may want to use the gmp package's as.bigz #' to parse it. #' @name latte-count #' @examples #' #' if (has_latte()) { #' #' spec <- c("x + y <= 10", "x >= 1", "y >= 1") #' latte_count(spec) # 45 #' latte_count(spec, quiet = FALSE) # 45 #' latte_count(spec, dilation = 10) # 3321 #' latte_count(spec, homog = TRUE) # 45 #' #' # by default, the output from LattE is in #' list.files(tempdir()) #' list.files(tempdir(), recursive = TRUE) #' #' # ehrhart polynomials #' latte_count(spec, ehrhart_polynomial = TRUE) #' latte_count(spec, ehrhart_polynomial = TRUE, mpoly = FALSE) #' #' # ehrhart series (raw since mpoly can't handle rational functions) #' latte_count(spec, ehrhart_series = TRUE) #' #' # simplified ehrhart series - not yet implemented #' #latte_count(spec, simplified_ehrhart_polynomial = TRUE) #' #' # first terms of the ehrhart series #' latte_count(spec, ehrhart_taylor = 1) #' latte_count(spec, ehrhart_taylor = 2) #' latte_count(spec, ehrhart_taylor = 3) #' latte_count(spec, ehrhart_taylor = 4) #' #' # multivariate generating function #' latte_count(spec, multivariate_generating_function = TRUE) #' #' #' # by vertices #' spec <- list(c(1,1), c(10,1), c(1,10), c(10,10)) #' latte_count(spec) #' latte_count(spec, vrep = TRUE) #' #' code <- " #' 5 3 #' 1 -1 0 #' 1 0 -1 #' 1 -1 -1 #' 0 1 0 #' 0 0 1 #' " #' latte_count(code) #' #' #' # for Ax <= b, see this example from the latte manual p.10 #' A <- matrix(c( #' 1, 0, #' 0, 1, #' 1, 1, #' -1, 0, #' 0, -1 #' ), nrow = 5, byrow = TRUE) #' b <- c(1, 1, 1, 0, 0) #' latte_count(list(A = A, b = b)) #' #' #' #' #' #' #' #' #' #' } #' #' count_core <- function(spec, dir = tempdir(), quiet = TRUE, mpoly = TRUE, ...){ if (!has_latte()) missing_latte_stop() ## initialize specification specification <- "unknown" ## compute other args opts <- as.list(match.call(expand.dots = FALSE))[["..."]] if(is.null(opts)){ opts <- "" } else { opts_names <- names(opts) opts_names <- str_replace_all(opts_names, "_", "-") opts <- str_c("--", opts_names, "=", unlist(opts)) opts <- str_replace_all(opts, "=TRUE", "") opts <- str_c(opts, collapse = " ") } ## look at opts if(str_detect(opts, "--ehrhart-series") && mpoly){ #stop("this option is not yet supported by algstat.", call. = FALSE) message("mpoly can't handle rational functions; reverting to raw output.") mpoly <- FALSE } if(str_detect(opts, "--simplified-ehrhart-polynomial")){ stop("This option is not yet supported by latte.", call. = FALSE) } ## if the specification is pure code if(is.character(spec) && length(spec) == 1){ specification <- "code" code <- spec } ## if the specification is A and b if(is.list(spec) && length(spec) == 2){ bNegA <- unname(cbind(spec$b, -spec$A)) spec <- paste(dim(bNegA), collapse = " ") bNegA <- paste(apply(bNegA, 1, paste, collapse = " "), collapse = "\n") spec <- paste(spec, bNegA, sep = "\n") spec <- str_c("\n", spec) specification <- "code" code <- spec } ## check for vertex specification if(str_detect(opts, "--vrep")) specification <- "vertex" if(is.list(spec) && !is.mpolyList(spec) && !str_detect(opts, "--vrep")){ specification <- "vertex" message("Undeclared vertex specification, setting vrep = TRUE.") opts <- str_c(opts, "--vrep") } ## if giving a character string of equations, parse ## each to the poly <= 0 format # this should transition to eq_to_mp if(is.character(spec) && length(spec) > 1){ parsedSpec <- as.list(rep(NA, length(spec))) geqNdcs <- which(str_detect(spec, " >= ")) leqNdcs <- which(str_detect(spec, " <= ")) eeqNdcs <- which(str_detect(spec, " == ")) eqNdcs <- which(str_detect(spec, " = ")) if(length(geqNdcs) > 0){ tmp <- strsplit(spec[geqNdcs], " >= ") parsedSpec[geqNdcs] <- lapply(tmp, function(v) mp(v[2]) - mp(v[1])) } if(length(leqNdcs) > 0){ tmp <- strsplit(spec[leqNdcs], " <= ") parsedSpec[leqNdcs] <- lapply(tmp, function(v) mp(v[1]) - mp(v[2])) } if(length(eeqNdcs) > 0){ tmp <- strsplit(spec[eeqNdcs], " == ") parsedSpec[eeqNdcs] <- lapply(tmp, function(v) mp(v[1]) - mp(v[2])) } if(length(eqNdcs) > 0){ tmp <- strsplit(spec[eqNdcs], " = ") parsedSpec[eqNdcs] <- lapply(tmp, function(v) mp(v[1]) - mp(v[2])) } linearityNdcs <- sort(c(eeqNdcs, eqNdcs)) spec <- parsedSpec class(spec) <- "mpolyList" } ## convert the mpoly specification into a matrix, see latte manual, p. 8 if(is.mpolyList(spec)){ specification <- "hyperplane" if(!all(is.linear(spec))){ stop("All polynomials must be linear.", call. = FALSE) } mat <- mpoly_list_to_mat(spec) mat <- cbind(-mat[,"coef",drop=FALSE], -mat[,-ncol(mat)]) # convert to code code <- paste(nrow(mat), ncol(mat)) code <- str_c(code, "\n") code <- str_c(code, paste(apply(unname(mat), 1, paste, collapse = " "), collapse = "\n") ) if(length(linearityNdcs) > 0){ code <- str_c(code, "\n") code <- str_c(code, str_c("linearity ", length(linearityNdcs), " ", paste(linearityNdcs, collapse = " ")) ) } } ## convert vertex specification into a matrix if(specification == "vertex"){ if(any(!sapply(spec, function(v) length(v) != 1))){ stop( "Unequal number of coordinates in vertex specification.", call. = FALSE ) } mat <- matrix(unlist(spec), ncol = 2, byrow = TRUE) # convert to code mat <- cbind(1, mat) code <- paste(nrow(mat), ncol(mat)) code <- str_c(code, "\n") code <- str_c(code, paste(apply(unname(mat), 1, paste, collapse = " "), collapse = "\n") ) } ## make dir to put latte files in (within the tempdir) timestamped dir.create(dir2 <- file.path(dir, timeStamp())) ## write code file writeLines(code, con = file.path(dir2, "count_code.latte")) ## switch to temporary directory oldWd <- getwd() setwd(dir2); on.exit(setwd(oldWd), add = TRUE) ## run count if (is_mac() || is_unix()) { system2( file.path(get_latte_path(), "count"), paste(opts, file.path(dir2, "count_code.latte")), stdout = "count_out", stderr = "count_err" ) } else if (is_win()) { matFile <- file.path(dir2, "count_code.latte") matFile <- chartr("\\", "/", matFile) matFile <- str_c("/cygdrive/c", str_sub(matFile, 3)) system2( "cmd.exe", paste( "/c env.exe", file.path(get_latte_path(), "count"), opts, matFile ), stdout = "count_out", stderr = "count_err" ) } ## print count output when quiet = FALSE if(!quiet) cat(readLines("count_out"), sep = "\n") # note: strangely, latte posts non-error info to stderr if(!quiet) std_err <- readLines("count_err") if(!quiet && any(std_err != "")) message(str_c(std_err, collapse = "\n")) ## parse ehrhart polynomial if(opts == "--ehrhart-polynomial"){ outPrint <- readLines("count_out") rawPoly <- rev(outPrint)[2] if(!mpoly) return(str_trim(rawPoly)) rawPoly <- str_replace_all(rawPoly, " \\* ", " ") if(str_sub(rawPoly, 1, 5) == " + 1 ") rawPoly <- str_sub(rawPoly, 6) return(mp(str_trim(rawPoly))) } ## parse ehrhart series if(opts == "--ehrhart-series"){ outPrint <- readLines("count_code.latte.rat") # take off initial "x := " and terminating ":" outPrint <- str_sub(outPrint, start = 6, end = nchar(outPrint)-1) # return return(outPrint) } ## parse multivariate generating function if(opts == "--multivariate-generating-function"){ outPrint <- readLines("count_code.latte.rat") # collapse outPrint <- paste(outPrint, collapse = "") # return if(!mpoly) return(outPrint) # change x[0] to vars[1], and so on indets <- vars(spec) for(k in 1:length(indets)){ outPrint <- str_replace_all(outPrint, str_c("x\\[",k-1,"\\]"), indets[k]) } return(outPrint) } ## parse truncated taylor series if(str_detect(opts, "--ehrhart-taylor=")){ outPrint <- readLines("count_out") # collapse outPrint <- paste(outPrint, collapse = " + ") outPrint <- str_replace_all(outPrint, "t", " t") # return if(!mpoly) return(outPrint) return(mp(outPrint)) } ## read in integer and parse if small enough out <- readLines("numOfLatticePoints") if(nchar(out) < 10) out <- as.integer(out) ## print out stats if(!quiet){ cat(readLines("latte_stats"), sep = "\n") cat("\n") } ## out out } #' @export #' @rdname latte-count latte_count <- memoise::memoise(count_core) #' @export #' @rdname latte-count latte_fcount <- count_core mpoly_list_to_mat <- function(mpolyList){ # this only works for linear mpolyList objects vars <- vars(mpolyList) varsC <- c(vars, "coef") vecMpolyList <- unclass(mpolyList) vecMpolyList <- lapply(vecMpolyList, unclass) vecMpolyList <- lapply(vecMpolyList, lapply, function(v){ if(names(v)[1] == "coef") return(v) o <- v["coef"] names(o) <- names(v)[1] o }) vecMpolyList <- lapply(vecMpolyList, unlist) vecMpolyList <- lapply(vecMpolyList, function(x){ varsNeeded <- setdiff(varsC, names(x)) if(length(varsNeeded) > 0){ tmp <- rep(0, length(varsNeeded)) names(tmp) <- varsNeeded x <- c(x, tmp) x <- x[varsC] } x }) vecMpolyList <- lapply(vecMpolyList, function(x){ df <- as.data.frame(t(x)) row.names(df) <- runif(1) # another way? df }) vecMpolyList <- unsplit(vecMpolyList, 1:length(vecMpolyList), drop = TRUE) row.names(vecMpolyList) <- 1:nrow(vecMpolyList) as.matrix(vecMpolyList) } latte/MD50000644000176200001440000000404013446131133011670 0ustar liggesusersb615190652ff02f555697369d0622727 *DESCRIPTION 9cffd53912d9ce41beae80172639d991 *NAMESPACE 99b8d224683609dec83d15237349f60d *NEWS a17eb6569801a18b9feaf0a59653de07 *R/attach.R f10863c512d13b813a01ffc8a32607f9 *R/genmodel.R 32ad71cfd6b192a7cd51ae076e39dab8 *R/helpers.R b818d2e7c42addc09360f1b194c353d1 *R/kprod.R 89c69a766cefbc5e5c1530582bed05ef *R/latte-count.R 6e760af2eddc2dffc239ed1273751224 *R/latte-files.R 1efecaeb5a48b196d089366f284ce641 *R/latte-optim.R 34a764f9c6e6a91287b164dd6e9f5bbb *R/latte.R 3b11ba450f36b3d771b02144cc096b97 *R/lattice-bases.R 30279d8f4d4659552c166341cab7ebd6 *R/ones.R b6c46e86620212e98499aed55923f0b5 *R/plot-matrix.R 329290f375d10b717d0e38876afb6a02 *R/ppi.R e6bcdc65c16dd9af4b0f68bf37f9e1a2 *R/qsolve.R 5ddd2707b89d5f749ef1dd3348b57980 *R/set-paths.R b5834a6742e8b577531befe51a15bd51 *R/tab2vec.R b8435067bbb9cd65a12885c28fc809cc *R/tableau.R fd071b35e9a926cdb584147cfd5c4734 *R/vec2tab.R a21fccbc3d0b1bd65546b20ca3e290ca *R/zsolve.R 6fce37260c11f8171984b9897aba52bf *inst/CITATION 620ca6100d9b94c167c6791db495b24a *inst/INSTALL.txt e442b7f49712143574a98e53b6c11201 *man/genmodel.Rd cb81c38516568138278b632d3991d9af *man/kprod.Rd 2281155735e828cd99e575119d8d9ef6 *man/latte-count.Rd 64c83cc21f5a3f3713313b2403b5f629 *man/latte-files.Rd d06783f67c6c9b38485f8d88d48440a2 *man/latte-optim.Rd b52d917bd5afd958341cf510630f0783 *man/latte.Rd eede256d53dd4cb0691096b59fc36e4d *man/lattice-bases.Rd cac090aa1766d05bd4092175f850fd75 *man/ones.Rd cdfc4f3bc5b9b67f26a119ce914269cf *man/pathing.Rd 0f0bba08d9dc44f1436cbbdbca8146c5 *man/plot-matrix.Rd 0b3f9f4f5de07aa5fef4dded810d7c0b *man/ppi.Rd 4670f9697efc47c094a7722ff2b38d31 *man/print.tableau.Rd 0211adc31583fbd3bf5490701c9bc3c5 *man/qsolve.Rd 6c3a674bf8bdc0034c74b42c09e4f6f2 *man/reexports.Rd 2b44ed1bcea9376ca69421108bbfb6f1 *man/tab2vec.Rd d9c241780816f9b5a2f37719fd58f3a1 *man/tableau.Rd 95c0a157585fd84a82f09ebb6bc267d7 *man/vec2tab.Rd 9c609b237751cbe0d08635eed676042d *man/zsolve.Rd c135e7309b37186504957f66ba3b7fd3 *tools/countExample-1.png e1e5cb41c03b50e17ccae5d18503821b *tools/ipCheck-1.png latte/DESCRIPTION0000644000176200001440000000254213446131133013073 0ustar liggesusersPackage: latte Type: Package Title: Interface to 'LattE' and '4ti2' Version: 0.2.1 Authors@R: c(person("David", "Kahle", email = "david@kahle.io", role = c("aut", "cph", "cre"), comment = c(ORCID = "0000-0002-9999-1558")), person("Luis", "Garcia",email = "lgarcia@shsu.edu", role = c("aut", "cph")), person("Ruriko", "Yoshida", email = "ryoshida@nps.edu", role = c("aut", "cph"))) Maintainer: David Kahle Description: Back-end connections to 'LattE' () for counting lattice points and integration inside convex polytopes and '4ti2' () for algebraic, geometric, and combinatorial problems on linear spaces and front-end tools facilitating their use in the 'R' ecosystem. License: GPL-2 URL: https://github.com/dkahle/latte BugReports: https://github.com/dkahle/latte/issues LazyData: TRUE SystemRequirements: LattE , 4ti2 Imports: magrittr, stringr, mpoly, ggplot2, memoise, dplyr, usethis, glue Suggests: knitr, rmarkdown RoxygenNote: 6.1.1 Encoding: UTF-8 NeedsCompilation: no Packaged: 2019-03-22 00:34:52 UTC; david_kahle Author: David Kahle [aut, cph, cre] (), Luis Garcia [aut, cph], Ruriko Yoshida [aut, cph] Repository: CRAN Date/Publication: 2019-03-25 10:50:03 UTC latte/man/0000755000176200001440000000000013445026503012140 5ustar liggesuserslatte/man/tab2vec.Rd0000644000176200001440000000135013436637052013763 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/tab2vec.R \name{tab2vec} \alias{tab2vec} \title{Array to vector conversion} \usage{ tab2vec(tab) } \arguments{ \item{tab}{An array of counts} } \value{ a Named integer vector. The names correspond to the cell indices in the table. } \description{ Convert an array into a vector. } \details{ This function converts an array (or a multi-way contingency table) into a vector, using a consistent ordering of the cells. The ordering of the cells is lexicographical and cannot be specified by the user. } \examples{ a <- array(1:24, c(2,3,4)) tab2vec(a) data(Titanic) tab2vec(Titanic) Titanic[1,1,1,1] Titanic[1,1,1,2] } \seealso{ \code{\link[=vec2tab]{vec2tab()}} } latte/man/plot-matrix.Rd0000644000176200001440000000127713442001070014703 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plot-matrix.R \name{plot-matrix} \alias{plot-matrix} \alias{plot_matrix} \title{Plot a matrix} \usage{ plot_matrix(A) } \arguments{ \item{A}{A matrix} } \value{ a ggplot object } \description{ plot_matrix is a R variant of Matlab's \code{spy} function. } \examples{ # the no-three-way interaction configuration (A <- kprod(ones(1,3), diag(3), ones(3))) plot_matrix(A) if (has_4ti2()) { plot_matrix(markov(A)) (A <- genmodel(c(2L, 2L), list(1L, 2L))) plot_matrix(A) plot_matrix(markov(A)) (A <- genmodel(c(5L, 5L), list(1L, 2L))) plot_matrix(A) plot_matrix(markov(A)) } } \author{ David Kahle \email{david@kahle.io} } latte/man/ones.Rd0000644000176200001440000000056313437126720013402 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ones.R \name{ones} \alias{ones} \title{Ones} \usage{ ones(...) } \arguments{ \item{...}{A sequence of dimensions separated by commas} } \value{ An integer array of ones } \description{ Make an array of ones } \examples{ ones(5) ones(5, 1) ones(1, 5) ones(2, 3) ones(2, 3, 2) str(ones(5)) } latte/man/qsolve.Rd0000644000176200001440000000223013440566705013745 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/qsolve.R \name{qsolve} \alias{qsolve} \title{Solve a linear system over the rationals} \usage{ qsolve(mat, rel, sign, dir = tempdir(), quiet = TRUE, shell = FALSE, ...) } \arguments{ \item{mat}{The A matrix (see the 4ti2 documentation or examples)} \item{rel}{A vector of "<" or ">" relations} \item{sign}{The signs of the individual} \item{dir}{Directory to place the files in, without an ending /} \item{quiet}{If FALSE, messages the 4ti2 output} \item{shell}{Messages the shell code used to do the computation} \item{...}{Additional arguments to pass to the function} } \value{ The configuration matrix of the model provided } \description{ qsolve runs 4ti2's qsolve program to compute the configuration matrix A corresponding to graphical statistical models given by a simplicial complex and levels on the nodes. } \examples{ if (has_4ti2()) { # x + y > 0 # x + y < 0 mat <- rbind( c( 1, 1), c( 1, 1) ) rel <- c(">", "<") sign <- c(0, 0) qsolve(mat, rel, sign, p = "arb") qsolve(mat, rel, sign, p = "arb", quiet = FALSE) qsolve(mat, rel, sign, p = "arb", shell = TRUE) } } latte/man/genmodel.Rd0000644000176200001440000000225713440561101014220 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/genmodel.R \name{genmodel} \alias{genmodel} \title{Generate a configuration matrix} \usage{ genmodel(varlvls, facets, dir = tempdir(), quiet = TRUE, shell = FALSE, ...) } \arguments{ \item{varlvls}{a vector containing the number of levels of each variable} \item{facets}{the facets generating the hierarchical model, a list of vectors of variable indices} \item{dir}{Directory to place the files in, without an ending /} \item{quiet}{If FALSE, messages the 4ti2 output} \item{shell}{Messages the shell code used to do the computation} \item{...}{Additional arguments to pass to the function} } \value{ The configuration matrix of the model provided } \description{ genmodel runs 4ti2's genmodel program to compute the configuration matrix A corresponding to graphical statistical models given by a simplicial complex and levels on the nodes. } \examples{ if (has_4ti2()) { varlvls <- rep(2, 2) facets <- list(1, 2) genmodel(varlvls, facets) genmodel(varlvls, facets, quiet = FALSE) varlvls <- rep(3, 3) facets <- list(1:2, 2:3, c(3,1)) genmodel(varlvls, facets) # compare this to algstat's hmat function } } latte/man/print.tableau.Rd0000644000176200001440000000064013104624164015176 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/tableau.R \name{print.tableau} \alias{print.tableau} \title{Pretty printing of tableau output.} \usage{ \method{print}{tableau}(x, ...) } \arguments{ \item{x}{an object of class tableau} \item{...}{...} } \value{ Invisible string of the printed object. } \description{ Pretty printing of tableau output. } \examples{ # see ?tableau } latte/man/ppi.Rd0000644000176200001440000000164413441334713013225 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ppi.R \name{ppi} \alias{ppi} \title{Compute the primitive partition identities} \usage{ ppi(N, dir = tempdir(), quiet = TRUE, shell = FALSE, ...) } \arguments{ \item{N}{A postive integer > 2} \item{dir}{Directory to place the files in, without an ending /} \item{quiet}{If FALSE, messages the 4ti2 output} \item{shell}{Messages the shell code used to do the computation} \item{...}{Additional arguments to pass to the function} } \value{ A matrix containing the basis as its columns (for easy addition to tables) } \description{ ppi runs 4ti2's ppi program to compute the primitive partition identities, that is, the Graver basis of 1:N. } \examples{ if (has_4ti2()) { ppi(3) t(ppi(3)) \%*\% 1:3 plot_matrix(ppi(3)) graver(t(1:3)) plot_matrix(graver(t(1:3))) ppi(5, quiet = FALSE, shell = TRUE) } } \seealso{ \code{\link[=graver]{graver()}} } latte/man/latte.Rd0000644000176200001440000000064013445026503013540 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/latte.R \docType{package} \name{latte} \alias{latte} \alias{package-latte} \alias{latte-package} \title{R Interface to LattE and 4ti2} \description{ Back-end connections to LattE (\url{https://www.math.ucdavis.edu/~latte/}) and 4ti2 (\url{http://www.4ti2.de/}) executables and front-end tools facilitating their use in the R ecosystem. } latte/man/latte-count.Rd0000644000176200001440000000630113442000604014655 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/latte-count.R \name{latte-count} \alias{latte-count} \alias{count_core} \alias{latte_count} \alias{latte_fcount} \title{Count integer points in a polytope} \usage{ count_core(spec, dir = tempdir(), quiet = TRUE, mpoly = TRUE, ...) latte_count(spec, dir = tempdir(), quiet = TRUE, mpoly = TRUE, ...) latte_fcount(spec, dir = tempdir(), quiet = TRUE, mpoly = TRUE, ...) } \arguments{ \item{spec}{Specification, see details and examples} \item{dir}{Directory to place the files in, without an ending /} \item{quiet}{Show latte output?} \item{mpoly}{When opts = "--ehrhart-polynomial", return the mpoly version of it} \item{...}{Additional arguments to pass to the function, see count --help at the command line to see examples. Note that dashes - should be specified with underscores _} } \value{ The count. If the count is a number has less than 10 digits, an integer is returned. If the number has 10 or more digits, an integer in a character string is returned. You may want to use the gmp package's as.bigz to parse it. } \description{ \code{latte_count} uses LattE's count function to count the (integer) lattice points in a polytope and compute Ehrhart polynomials. } \details{ The specification should be one of the following: (1) a character string or strings containing an inequality in the mpoly expression format (see examples), (2) a list of vertices, (3) a list of A and b for the equation Ax <= b (see examples), or (4) raw code for LattE's count program. If a character vector is supplied, (1) and (4) are distinguished by the number of strings. Behind the scenes, count works by writing a latte file and running count on it. If a specification other than a length one character is given to it (which is considered to be the code), count attempts to convert it into LattE code and then run count on it. } \examples{ if (has_latte()) { spec <- c("x + y <= 10", "x >= 1", "y >= 1") latte_count(spec) # 45 latte_count(spec, quiet = FALSE) # 45 latte_count(spec, dilation = 10) # 3321 latte_count(spec, homog = TRUE) # 45 # by default, the output from LattE is in list.files(tempdir()) list.files(tempdir(), recursive = TRUE) # ehrhart polynomials latte_count(spec, ehrhart_polynomial = TRUE) latte_count(spec, ehrhart_polynomial = TRUE, mpoly = FALSE) # ehrhart series (raw since mpoly can't handle rational functions) latte_count(spec, ehrhart_series = TRUE) # simplified ehrhart series - not yet implemented #latte_count(spec, simplified_ehrhart_polynomial = TRUE) # first terms of the ehrhart series latte_count(spec, ehrhart_taylor = 1) latte_count(spec, ehrhart_taylor = 2) latte_count(spec, ehrhart_taylor = 3) latte_count(spec, ehrhart_taylor = 4) # multivariate generating function latte_count(spec, multivariate_generating_function = TRUE) # by vertices spec <- list(c(1,1), c(10,1), c(1,10), c(10,10)) latte_count(spec) latte_count(spec, vrep = TRUE) code <- " 5 3 1 -1 0 1 0 -1 1 -1 -1 0 1 0 0 0 1 " latte_count(code) # for Ax <= b, see this example from the latte manual p.10 A <- matrix(c( 1, 0, 0, 1, 1, 1, -1, 0, 0, -1 ), nrow = 5, byrow = TRUE) b <- c(1, 1, 1, 0, 0) latte_count(list(A = A, b = b)) } } latte/man/reexports.Rd0000644000176200001440000000063613442000604014456 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/set-paths.R \docType{import} \name{reexports} \alias{reexports} \alias{edit_r_environ} \title{Objects exported from other packages} \keyword{internal} \description{ These objects are imported from other packages. Follow the links below to see their documentation. \describe{ \item{usethis}{\code{\link[usethis]{edit_r_environ}}} }} latte/man/lattice-bases.Rd0000644000176200001440000001412013445026503015145 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lattice-bases.R \name{lattice-bases} \alias{lattice-bases} \alias{basis} \alias{zbasis} \alias{markov} \alias{groebner} \alias{hilbert} \alias{graver} \alias{fzbasis} \alias{fmarkov} \alias{fgroebner} \alias{fhilbert} \alias{fgraver} \title{Compute a basis with 4ti2} \usage{ basis(exec, memoise = TRUE) zbasis(A, format = c("mat", "vec", "tab"), dim = NULL, all = FALSE, dir = tempdir(), quiet = TRUE, shell = FALSE, dbName = NULL, ...) markov(A, format = c("mat", "vec", "tab"), dim = NULL, all = FALSE, dir = tempdir(), quiet = TRUE, shell = FALSE, dbName = NULL, ...) groebner(A, format = c("mat", "vec", "tab"), dim = NULL, all = FALSE, dir = tempdir(), quiet = TRUE, shell = FALSE, dbName = NULL, ...) hilbert(A, format = c("mat", "vec", "tab"), dim = NULL, all = FALSE, dir = tempdir(), quiet = TRUE, shell = FALSE, dbName = NULL, ...) graver(A, format = c("mat", "vec", "tab"), dim = NULL, all = FALSE, dir = tempdir(), quiet = TRUE, shell = FALSE, dbName = NULL, ...) fzbasis(A, format = c("mat", "vec", "tab"), dim = NULL, all = FALSE, dir = tempdir(), quiet = TRUE, shell = FALSE, dbName = NULL, ...) fmarkov(A, format = c("mat", "vec", "tab"), dim = NULL, all = FALSE, dir = tempdir(), quiet = TRUE, shell = FALSE, dbName = NULL, ...) fgroebner(A, format = c("mat", "vec", "tab"), dim = NULL, all = FALSE, dir = tempdir(), quiet = TRUE, shell = FALSE, dbName = NULL, ...) fhilbert(A, format = c("mat", "vec", "tab"), dim = NULL, all = FALSE, dir = tempdir(), quiet = TRUE, shell = FALSE, dbName = NULL, ...) fgraver(A, format = c("mat", "vec", "tab"), dim = NULL, all = FALSE, dir = tempdir(), quiet = TRUE, shell = FALSE, dbName = NULL, ...) } \arguments{ \item{exec}{don't use this parameter} \item{memoise}{don't use this parameter} \item{A}{The configuration matrix} \item{format}{How the basis (moves) should be returned. if "mat", the moves are returned as the columns of a matrix.} \item{dim}{The dimension to be passed to \code{\link[=vec2tab]{vec2tab()}} if format = "tab" is used; a vector of the number of levels of each variable in order} \item{all}{If TRUE, all moves (+ and -) are given. if FALSE, only the + moves are given as returned by the executable.} \item{dir}{Directory to place the files in, without an ending /} \item{quiet}{If FALSE, messages the 4ti2 output} \item{shell}{Messages the shell code used to do the computation} \item{dbName}{The name of the model in the markov bases database, http://markov-bases.de, see examples} \item{...}{Additional arguments to pass to the function, e.g. \code{p = "arb"} specifies the flag \code{-parb}; not setting this issues a common warning} } \value{ a matrix containing the Markov basis as its columns (for easy addition to tables) } \description{ 4ti2 provides several executables that can be used to generate bases for a configuration matrix A. See the references for details. } \examples{ if (has_4ti2()) { # basic input and output for the 3x3 independence example (A <- rbind( kprod(diag(3), ones(1,3)), kprod(ones(1,3), diag(3)) )) markov(A, p = "arb") # you can get the output formatted in different ways: markov(A, p = "arb", all = TRUE) markov(A, p = "arb", "vec") markov(A, p = "arb", "tab", c(3, 3)) tableau(markov(A, p = "arb"), dim = c(3, 3)) # tableau notation # you can add options by listing them off # to see the options available to you by function, # go to http://www.4ti2.de markov(A, p = "arb") # the basis functions are automatically cached for future use. # (note that it doesn't persist across sessions.) A <- rbind( kprod( diag(4), ones(1,4), ones(1,4)), kprod(ones(1,4), diag(4), ones(1,4)), kprod(ones(1,4), ones(1,4), diag(4)) ) system.time(markov(A, p = "arb")) system.time(markov(A, p = "arb")) # the un-cashed versions begin with an "f" # (think: "forgetful" markov) system.time(fmarkov(A, p = "arb")) system.time(fmarkov(A, p = "arb")) # you can see the command line code by typing shell = TRUE # and the standard output wiht quiet = FALSE # we illustrate these with fmarkov because otherwise it's cached (A <- rbind( kprod(diag(2), ones(1,4)), kprod(ones(1,4), diag(2)) )) fmarkov(A, p = "arb", shell = TRUE) fmarkov(A, p = "arb", quiet = FALSE) # compare the bases for the 3x3x3 no-three-way interaction model A <- rbind( kprod( diag(3), diag(3), ones(1,3)), kprod( diag(3), ones(1,3), diag(3)), kprod(ones(1,3), diag(3), diag(3)) ) str( zbasis(A, p = "arb")) # 8 elements = ncol(A) - qr(A)$rank str( markov(A, p = "arb")) # 81 elements str(groebner(A, p = "arb")) # 110 elements str( graver(A)) # 795 elements # the other bases are also cached A <- rbind( kprod( diag(3), ones(1,3), ones(1,2)), kprod(ones(1,3), diag(3), ones(1,2)), kprod(ones(1,3), ones(1,3), diag(2)) ) system.time( graver(A)) system.time( graver(A)) system.time(fgraver(A)) system.time(fgraver(A)) # LAS ex 1.2.1, p.12 : 2x3 independence (A <- rbind( kprod(diag(2), ones(1,3)), kprod(ones(1,2), diag(3)) )) markov(A, p = "arb", "tab", c(3, 3)) # Prop 1.2.2 says that there should be 2*choose(2, 2)*choose(3,2) # = 6 # moves (up to +-1) markov(A, p = "arb", "tab", c(3, 3), TRUE) # LAS example 1.2.12, p.17 (no 3-way interaction) (A <- rbind( kprod( diag(2), diag(2), ones(1,2)), kprod( diag(2), ones(1,2), diag(2)), kprod(ones(1,2), diag(2), diag(2)) )) plot_matrix(A) markov(A, p = "arb") groebner(A, p = "arb") graver(A) tableau(markov(A, p = "arb"), dim = c(2,2,2)) # using the markov bases database, must be connected to internet # commented out for predictable and fast cran checks time # A <- markov(dbName = "ind3-3") # B <- markov(rbind( # kprod(diag(3), ones(1,3)), # kprod(ones(1,3), diag(3)) # ), p = "arb") # all(A == B) # possible issues # markov(diag(1, 10)) # zbasis(diag(1, 10), "vec") # groebner(diag(1, 10), "vec", all = TRUE) # graver(diag(1, 10), "vec", all = TRUE) # graver(diag(1, 4), "tab", all = TRUE, dim = c(2,2)) } } \references{ Drton, M., B. Sturmfels, and S. Sullivant (2009). \emph{Lectures on Algebraic Statistics}, Basel: Birkhauser Verlag AG. } latte/man/latte-optim.Rd0000644000176200001440000000447013442001070014660 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/latte-optim.R \name{latte-optim} \alias{latte-optim} \alias{latte_optim} \alias{latte_max} \alias{latte_min} \title{Solve an integer progam with LattE} \usage{ latte_optim(objective, constraints, type = c("max", "min"), method = c("lp", "cones"), dir = tempdir(), opts = "", quiet = TRUE, shell = FALSE) latte_max(objective, constraints, method = c("lp", "cones"), dir = tempdir(), opts = "", quiet = TRUE) latte_min(objective, constraints, method = c("lp", "cones"), dir = tempdir(), opts = "", quiet = TRUE) } \arguments{ \item{objective}{A linear polynomial to pass to \code{\link[=mp]{mp()}}, see examples} \item{constraints}{A collection of linear polynomial (in)equalities that define the feasibility region, the integers in the polytope} \item{type}{\code{"max"} or \code{"min"}} \item{method}{Method \code{"LP"} or \code{"cones"}} \item{dir}{Directory to place the files in, without an ending /} \item{opts}{Options; see the LattE manual at \url{http://www.math.ucdavis.edu/~latte}} \item{quiet}{Show latte output} \item{shell}{Messages the shell code used to do the computation} } \value{ A named list with components \code{par}, a named-vector of optimizing arguments, and \code{value}, the value of the objective function at the optimial point. } \description{ \code{latte_max} and \code{latte_min} use LattE's \code{latte-maximize} and \code{latte-minimize} functions to find the maximum or minimum of a linear objective function over the integers points in a polytope (i.e. satisfying linearity constraints). This makes use of the digging algorithm; see the LattE manual at \url{http://www.math.ucdavis.edu/~latte} for details. } \examples{ if (has_latte()) { latte_max( "-2 x + 3 y", c("x + y <= 10", "x >= 0", "y >= 0") ) latte_max( "-2 x + 3 y", c("x + y <= 10", "x >= 0", "y >= 0"), quiet = FALSE ) df <- expand.grid("x" = 0:10, "y" = 0:10) df <- subset(df, x + y <= 10L) df$objective <- with(df, -2*x + 3*y) library("ggplot2") ggplot(df, aes(x, y, size = objective)) + geom_point() latte_min( "-2 x + 3 y", c("x + y <= 10", "x >= 0", "y >= 0"), method = "cones" ) latte_min("-2 x - 3 y - 4 z", c( "3 x + 2 y + z <= 10", "2 x + 5 y + 3 z <= 15", "x >= 0", "y >= 0", "z >= 0" ), "cones", quiet = FALSE) } } latte/man/kprod.Rd0000644000176200001440000000160413437126720013552 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/kprod.R \name{kprod} \alias{kprod} \title{Iterated Kronecker product} \usage{ kprod(..., FUN = `*`) } \arguments{ \item{...}{A listing of matrices} \item{FUN}{A function to pass to \code{\link[=kronecker]{kronecker()}}} } \value{ A matrix that is the kronecker product of the specified matrices (from left to right). } \description{ Compute the Kronecker product of several matrices. } \details{ If kronecker is the function that computes A x B, kprod computes A x B x C and so on; it's a wrapper of Reduce and kronecker. } \examples{ kprod(diag(2), t(ones(2))) kprod(t(ones(2)), diag(2)) kprod(diag(2), t(ones(2)), t(ones(2))) kprod(t(ones(2)), diag(2), t(ones(2))) kprod(t(ones(2)), t(ones(2)), diag(2)) # cf. aoki, hara, and takemura p.13 rbind( kprod(diag(2), t(ones(2))), kprod(t(ones(2)), diag(2)) ) } latte/man/tableau.Rd0000644000176200001440000000144113436637052014053 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/tableau.R \name{tableau} \alias{tableau} \title{Tableau Notation for Markov} \usage{ tableau(move, dim) } \arguments{ \item{move}{a markov move matrix, where the columns are moves in vector form (e.g. the output of markov)} \item{dim}{the dimensions of the table form of the move, oftentimes a vector of the number of levels of each variable in order} } \value{ an object of class tableau } \description{ Print the tableau notation for a Markov move. See the reference provided, p. 13. } \examples{ vec <- matrix(c(1, -1, -1, 1), nrow = 4) varlvls <- c(2, 2) tableau(vec, varlvls) } \references{ Drton, M., B. Sturmfels, and S. Sullivant (2009). \emph{Lectures on Algebraic Statistics}, Basel: Birkhauser Verlag AG. } latte/man/latte-files.Rd0000644000176200001440000000273413442214165014646 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/latte-files.R \name{latte-files} \alias{latte-files} \alias{format_latte} \alias{write_latte} \alias{write.latte} \alias{read_latte} \alias{read.latte} \title{Format/read/write a matrix in latte's style} \usage{ format_latte(mat, file) write_latte(mat, file) write.latte(mat, file) read_latte(file, format = c("mat", "Ab")) read.latte(file, format = c("mat", "Ab")) } \arguments{ \item{mat}{A matrix} \item{file}{A filename} \item{format}{"mat" or "Ab"} } \value{ \itemize{ \item \code{\link[=format_latte]{format_latte()}} -- A character string of the matrix in latte format. \item \code{\link[=write_latte]{write_latte()}} -- An invisible character string of the formatted output. \item \code{\link[=read_latte]{read_latte()}} -- An integer matrix. } } \description{ \code{\link[=format_latte]{format_latte()}} formats a matrix in latte's style. \code{\link[=write_latte]{write_latte()}} writes a latte-formatted file to file. \code{\link[=read_latte]{read_latte()}} reads a latte-formatted file from disk. } \examples{ (mat <- matrix(sample(9), 3, 3)) format_latte(mat) cat(format_latte(mat)) (file <- file.path(tempdir(), "foo.hrep")) write_latte(mat, file) file.show(file) read_latte(file) read_latte(file, "Ab") attr(mat, "linearity") <- c(1, 3) attr(mat, "nonnegative") <- 2 mat format_latte(mat) cat(format_latte(mat)) write_latte(mat, file) file.show(file) read_latte(file) file.remove(file) } latte/man/pathing.Rd0000644000176200001440000000536713442000604014063 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/set-paths.R \name{pathing} \alias{pathing} \alias{set_latte_path} \alias{set_4ti2_path} \alias{get_4ti2_path} \alias{get_latte_path} \alias{has_4ti2} \alias{has_latte} \alias{missing_4ti2_stop} \alias{missing_latte_stop} \title{Set paths to LattE and 4ti2 executables} \usage{ set_latte_path(path) set_4ti2_path(path) get_4ti2_path() get_latte_path() has_4ti2() has_latte() missing_4ti2_stop() missing_latte_stop() } \arguments{ \item{path}{A character string, the path to a 4ti2 function (e.g. markov) for setting 4ti2's path or a LattE function (e.g. count) for LattE's path} } \value{ An invisible character string, the path found. More importantly, the function has the side effect of setting the option "latte_path" or "4ti2_path" } \description{ These functions set the path to external programs either by (1) passing them a character string or (2) using \code{\link[=file.choose]{file.choose()}}. } \details{ When latte is loaded it attempts to find LattE and 4ti2 executables (represented by count and markov, respectively). How it looks depends on your operating system. If you're using a Mac or Linux machine, it looks based on your system's path. Unfortunately, R changes the system path in such a way that the path that R sees is not the same as the path that you'd see if you were working in the terminal. (You can open the Terminal app on a Mac by going to /Applications/Utilities/Terminal.) Consequently, latte tries to guess the file in which your path is set. To do so, it first checks if your home directory (type echo ~/ in the terminal to figure out which directory this is if you don't know) for the file named .bash_profile. If this file is present, it runs it and then checks your system's path variable (echo $PATH). If it's not present, it does the same for .bashrc and then .profile. In any case, once it has its best guess at your path, it looks for "latte". On Windows, latte just uses \code{\link[=Sys.which]{Sys.which()}} on "whereis" to On Windows, latte just uses \code{\link[=Sys.which]{Sys.which()}} on "whereis" to determine where the executables count and markov are (for LattE and 4ti2, respectively). } \examples{ has_4ti2() if (has_4ti2()) get_4ti2_path() has_latte() if (has_4ti2()) get_latte_path() # these are stored in your .Renviron file; that's where you should put the # path to LattE and 4ti2 executables. for example, you should have a lines # that look like # LATTE=/Applications/latte/bin # 4TI2=/Applications/latte/bin # you can set these with usethis::edit_r_environ() # you can change these in your current session with set_latte_path() and # set_4ti2_path(), for example set_4ti2_path("/path/to/4ti2") } \author{ David Kahle \email{david@kahle.io} } latte/man/zsolve.Rd0000644000176200001440000000256713441334713013764 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/zsolve.R \name{zsolve} \alias{zsolve} \title{Solve a linear system over the integers} \usage{ zsolve(mat, rel, rhs, sign, lat, lb, ub, dir = tempdir(), quiet = TRUE, shell = FALSE, ...) } \arguments{ \item{mat}{The A matrix (see the 4ti2 documentation or examples)} \item{rel}{A vector of "<" or ">" relations} \item{rhs}{The right hand side b} \item{sign}{The signs of the individual} \item{lat}{A lattice basis (instead of a matrix)} \item{lb}{Lower bounds on columns} \item{ub}{Upper bounds on columns} \item{dir}{Directory to place the files in, without an ending /} \item{quiet}{If FALSE, messages the 4ti2 output} \item{shell}{Messages the shell code used to do the computation} \item{...}{Additional arguments to pass to the function} } \value{ The configuration matrix of the model provided } \description{ zsolve runs 4ti2's zsolve program to compute the configuration matrix A corresponding to graphical statistical models given by a simplicial complex and levels on the nodes. } \examples{ if (has_4ti2()) { mat <- rbind( c( 1, -1), c(-3, 1), c( 1, 1) ) rel <- c("<", "<", ">") rhs <- c(2, 1, 1) sign <- c(0, 1) zsolve(mat, rel, rhs, sign) zsolve(mat, rel, rhs, sign, quiet = FALSE) zsolve(mat, rel, rhs, sign, shell = TRUE) zsolve(mat, rel, rhs, sign, p = "gmp", quiet = FALSE) } } latte/man/vec2tab.Rd0000644000176200001440000000202213436637052013760 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/vec2tab.R \name{vec2tab} \alias{vec2tab} \title{Vector to array conversion} \usage{ vec2tab(vec, dim) } \arguments{ \item{vec}{A vector} \item{dim}{The desired array dimensions, oftentimes a vector of the number of levels of each variable in order} } \value{ An array } \description{ Convert a vector into an array given a set of dimensions; it therefore simply wraps \code{\link[=aperm]{aperm()}} and \code{\link[=array]{array()}}. } \details{ This function converts an array (or a multi-way contingency table) into a vector, using a consistent ordering of the cells. The ordering of the cells is lexicographical and cannot be specified by the user. } \examples{ data(Titanic) Titanic tab2vec(Titanic) vec2tab(tab2vec(Titanic), dim(Titanic)) vec2tab(tab2vec(Titanic), dim(Titanic)) == Titanic all(vec2tab(tab2vec(Titanic), dim(Titanic)) == Titanic) } \seealso{ \code{\link[=tab2vec]{tab2vec()}}, \code{\link[=aperm]{aperm()}}, \code{\link[=array]{array()}} } latte/tools/0000755000176200001440000000000013442213441012521 5ustar liggesuserslatte/tools/ipCheck-1.png0000644000176200001440000030270213442213441014737 0ustar liggesusersPNG  IHDRx  iCCPkCGColorSpaceGenericRGB8U]hU>sg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|U\ @IDATx L/..}Neɞ !)k/**K(!!T"RY*E%?on;sgsf99~f<,$$@@@@@u=     ^     @ ҉     ^     @ ҉     ^     @ ҉     ^     @ ҉     ^     @ ҉     ^     @ ҉     ^     @ Ei6 e˖-鞳`rr\pl"k֬%K;=~ٲe=ϧ4_ E7ԏl\)=Y=_ K7<~i8*PN7n?z:ul3;wnGۏƎ9b*+Cq¾}6Cf/ \rW9{iS }-Z4..y*~_p`R`Ass̙3B8^f @T oTNF@@@@-@@@@@@N9o@@@@`/@@@@@ ZX3G@@@@@x]@@@@UoF@@@@ uC@@@@V:s@@@@\/z@<(K,իWˆ d׮]r1ɖ-ϟ_ʕ+'UTFIf$w!B@@@@^>ERΜ9#L:U.]r<|Mٳˍ7(}1gɒ%7@@@@ECf(HJJcǚr QܹsCRfM3gN,G@@@B @-ԩSGyٷo_n:֭iFvܙ@@@-@@/lAY… vڲ`>@@@p^M6CE.\ >i~q֬Ydɒ    @tEG7%X)pY`u}իWgeWZekT   / ? իg[N j̧2)R$2e˖5P7lbIEr=-    @ xQ"Q.#5Çu;_)o޼)7de}v>ԋ%%%ѣG}>zߍ;vx:(ɮoDQ3O# .O:%$._nYF࿽?33sz9H s֓_y~# -@[ ` WM3ܙ3g;}1+USN~;˗}i\z;8vȑΛM\ЦUjqo)B{7/t;ipܼQuf| t ^dM_yW;ϖ-[()5+@@@XQ/ QMT*VXz/:fu}U;UTd 7jjF@@@`E^\"Pxqѽi+۶mKwk׮5W^=ϻnԨQfnGAB@@@ 9\*_ylѢ9/2¡Cd 9?3j3:(%JQ5u"   @ d(X)p-}oT=~uԑU .3g/:j}UbZ۶mm9sUv-sP@@@\!E\1 t6m_|!=4mT-*+V۷F 9sȺuW^yePKwq̟?Z/ѻw @@@\)@וΠL+WNO./N)Tvm3[lٔcܰ@ $OΝK/͛7<]v+    @ 9d-0`џg%i^dΝrA)U+Vg_PY'rCg婧 w7h@@@D=xd&֭[n}@gϞ\ wzf͚#   @ `[oe-lKPF >|x'9   #@7!;t)S0v:E{=ɝ;M   D(< ^{5+Sc9?jժ)@@@@ ޴&A bqY'2_ϕ>iH8   ~ ]wϊ+dԩʞ={\tkJzp\Vle4țEs(a^2    {=)иqcџ.V7ʎ;Òq)/T-_Aլ) 1%4@@@p^M9FV*ѣr[$$$H|||a%o @@@`ޘb,<{@@@oL  @f   Ĵޘ^"@7Vfq    `^k= M mT   @ ک Fnuƌ   om8DAވ:   @XF@ ͜@@@2\'@uS΀@@@H#@7 @ =sEO@@@Cԉ8(@AlB@@@ F؄@ Q@@@ s@S /@@@'@}sΈ@ 24@@@  @h ͳG@@@Nop^FB oTLD@@@ x3MH @d yW   X)@JMB"L oMA@@@bR iy#mF    Β@ SC@@@ȔLQ3W@@@@*E>@ $2@@@zappA^72cD@@p^4Dzap@@@(u@ ,.\Q/^,+W 6ݻĉ͝[ʖ,)Uʕ/k4*ˇ oPl;z,_\֭['[ncǎٳg%!!A-*+WzI:u$kV>KL   X @D@w۷O^{5:ul߾$&#Gd2f:Uȝ:Jߎ%W|ϲN&ȫA3feŊaw ( :uo]7oa~2    @p, ΋ B'O?.ʕg}opO*#(ߛPpW]Vh]Gʖ-+ o61SL-ZH dx[=C@@@x:XdT1Vߎ3FΜ9P>,-n-ws3?|pstJh׮tYTEY@@@[/@u[l)v#ú}C=KCA?,-%ta+Ӈ~(kז4v+G]   8)@ImBnˠT+8}J:|Tc^ 馛_|to֭@@@@ p- }ba+wq|G!Ѹ]O>-@@@@ V2.I`̙:4{ې!v&'MGǎy_9;j@[n믿Q=u"   xc~ *m6ׯ_-wXzOșg-7>\2`XW/^קO9u%Q    n f W'Nc ޷ߞbg>>~;jvؼyKv7C   ĜޘR,^XϟJQKˌ2E:x:칷ޒ=ն<&L۷V?#   xcqV-0bĈQ@jxvT#Ǐ˸ٳ|wĹsdN5G;   ĄޘFشi HIo~4O%9֝~*#d۷~[NE@@@@ 09 bX`ƌ5G+V8֧ >u ͝;7lG@@@P@ |gTѣïF?쳈A@@@ F7]̙3?N ,]:"!槟B*ggKY=u#   Sxcj: +yf9|lϿavp۶6m`Νrܸ @@@2 9@ nr9{V<`?wF( l۶-bA@@@ux]7 ;}7n=q8F(8j LB@@@flDaJHMIl٤DW(c    v S@ "yr޷\mo#J1    :rEQ(`{h#A-Z4bA@@@ux]7 *W}7bn-XP'䵽?Uʗ`Ȟ=/_>bG@@@x]9 <KB yF:U8җ`.rɖ-[0Eȋ   kv8@,YyѢ~}GTZuIYh‘    @7f1 @:v옩vp5vTθ8Ν;yF@@@ FtYCK.;V^QTXю[7ޘpˤiӦh6@@@JQ9mtHHH*3U÷ݖnӸԺ`ْK   ĪXYƅA h`1W\A#s{6vTN݇xX˖-+wq~r@@@ Mkp%\"O=TG$[lsr]&ȑ#%Gއ    G}T5jEZIyJ KZni@@@h ͳG@Rٳ̙3p–HeuTyRŊɌ#% 4ѣGD@@@H%@7w@=p,X sv BRW%>gNPƍaDu"U5.6؉   V Z@ tE_~) },*Têa_v2QXlgZ5zD)zP7   1-ӣcp :dIJJGfjիW J޽eݺuWE^rȓGN8+[X5V~kr={,Cv\Frp!I.R$fyG#B}{S[~{N:%n%/xRln笖D7}gΜ8J.mnþfԨ Ð>}̭~j?AFM}[#KX)^\0@kgv,:o%J=x$mS~{s0d i99L ՒS[Yy} ^ Sٌ Kq#hU0aw}O˜9s. F|ҿM2FҖ Ơ0H2j[2l++G{;;tCtqIڷ_ M~o>>#.AK:p63#Gm3>|PhѢvq sV  =p(P|\iwpi@Y'! K/#^5jԐٳg֭[eڴif_ʑM}1ިfMuruIaMU4ʖO yD_X>[Yz;t(kT(-;h! hWk$ț+@@@H-@7@?СC]9rJٰal߾]<(ُKRjҠz I0d?!ٱc:dumn9z$&3ƚKAJƊq] o @@@ @ f20@@@P@i1= @@p^?@b_ o1#D@@*@׭3ϸ@ uل3\@@@%x]2 @@ /@@@X k3x@ I@@@(]@ .\ G{H΃x,qCh7-Q⟃B@@@ Feɓ'O?E/6lӧO_ԩ RBviݸ\۠d˖<|g֭dJmVٺO9z$&9a?gΜR@TԬYS .S   %@7 3f̜9S4/isڵϋӧAϾ;C=zHтs@t#XHʚ5\۰iAjqA`ǎ{OfϞ-˖-KOQV-СKT4@@@D=x-aeƶ Uɓ3 g!y77ĤECGʽFI;$''+ǐ'M]dG3ړ2x`)]u]_dA5#F07۷UVE   @ 9d `4;i$ѽv3N=+0^y߶-^}c*]:˄9Iҹsjo6=g. ;Rree?r|4h@9\@@@H%@7w@ / ]w8psȲ߿m" z˗[VG^zQ=4VZ4-s?[Ym5}={Z6ĉ~0    `a#G :sF:<*HJϟ=D^1ön7=h{".Ac6I۶meʔ)_/׬Y3Y}[M    ്@ Z^y>|#?oi\H{4r2ؚt&1Qn40V5[dɒ%ȑ#fy͚5C   /@7"@|<#A|V۶'"b_Wf+o~Q` lO))VXVO+跧A#4x`IJJ W   xx:X'0n89}uXo[ȂC,zQS^آv/9z⸌ ؐs2c jJ@@@X 3@ C]1;u 9a';Ք;þz3t/O<ٱ1   @d$ O?$[n >YLE_Z?k\+jL|̘*f    F f遞9{VV])[-G[ dzPTFQ(v:@@@ k'!@ ^\@1Pտ4k\.uXYgr61g#(؞P@@@1QDƍ#kn99,G;%BFصN9g4f 6xn@@@D&eG9H:H;4s}wP0]=}lo@@@bKol'AN<B){8uӎL#N'"/   B^ Ggӡ>Ȟ=drEsqA@@@"[odC@+5/O ;BB%+d k@B9! "    u@ 2*VqX#}*Sds@Tڙkl+WT)lA@@@ Eo 7@իWרL9[lR|9kFX@VZ5t@@@ FCYk૿n XWXҞbND"R\9{B͛7E@@@,@ͳ@o|||hԩRE.X]̱2jHLp:3#/WϹ#@@@NL  ƅ:w1y};GҺQ#G׳c׾]r\Ϟ=%kV[v @@@dL$@ w}yr;ڷ}xﻹ{`m̕3{vM6~յ.LZAp#1NF@@^of@hڴl2#Эʟ~f)/z7x 74h6~I2eRs@@@@*E>y_~Yt5kR c!w KʨKh޽~ڵ]9l#=|p]~#   ޠȌ,PV-+7^uEu佈;   A   >Jۍ7ʠA$O:y'H5xHϞ˅%p @@@ @2p@#9f2dWW.[LΞ=뗦 er ͮH܎>?!$'Nͣ]tiuޡA $i܍D@@@@S/@  ~?_[%RnV,SZ+UW01t3+4nbdٵo=qB%IB-!9\ɒrgǎZ@@@ s@&9sJcu=zTN?qȪV/VXqZ&ս!G@@@؃qrD@{,   ?x #@7b   -@7!Y g#   o`NBU-[4,YHʻϸΝ;KE/dFB`O^    .Xf 6,EΞ=[f͚71cI&~p uی3^@@@ p[˗OTw[n$)S|'7md-]ɓTm_S2p u3l@@@ q7 4h@WZt 2Dr-#F-qOwȑRB49,   F.YgdB`׮]ZMO>+W./9~Kٲe*C&H+A^ٻ7   R+A#?/'OJ暀+޽$[l## țք#   @{Bux=*ǎK{„ u ?s@w E#ŋeժU+W.y衇* ޾˗.Roݺuٳr y… ryy8mz=mGo ǼE;%91I$? nFlpnyyoFSK}?ܙy{$C#9f`Ɋ:Bm;rSN{L.\(jպ~=D$@[wG7Qƍ3vM+*5k䣏>2/]QFKѢEȰa(_  "+:uJÇ/W%x>s4h]%Jh}/tm۝;wy!i@84Y|饗GO06!tHXbF*k֬ұcǠ nٲE4[~})P[N>czKrt@Y* @@| |… 3]ݻh]5KEH 3C0y=j֬YЫw%_|޽~t=etm۶nA  ;wZR~RΧ'OKRN%Kկ=II x6[f5oO7KɒUꧏ=c/7i Ns{V9U=笧Wy$ӿw%.yjp1gϗW_}}N{ѝs `^ۉiؿ ^M]t z@9rɓ',|2}tꫯx;t +tM `U_z@( Ǐv*T  g[}p"%JQW[ͽݭ9"O6 >2ږ(c9/NJJx>gϜ9cҿyNip7?zMhXf;?pt=hέ;v+SLT}ٱF!Y%f!Q|*rW\ak׮m֫/$h-T v낑2D@F={H߾}E jժ#tݮM$'J*IqRJuꢑ[jժ?w<_|jIW0[dr-7|S7nl~Y U_{Ŧ=yI>)uAS{oayX?dM [k={'cOR"#xaW@_|':wl@&mkp5HĨAX @ 74ة?3e4V+HZd)һ"瞻(u{GziÆ ?$uնd--Zdx9xyL=tC5NZFǦ[ލ5*唖> {O-JY@IDAT?czO>xYQ޺ukkq KjO?yɊ{mp^洈@T 苊lٲeH}_f裏4Cowyy_ѕzl)һ+5ȫ?7J/6myJ[.f/; ^iK (   za4[W?OK &HM!ycyv #['7{JÇKÆ EpUWĉ͋-twAWj W3`.&3gYN$Фh jN:4.b5Iڴicy饗.Z=g͚%Ł͛ˏ?h֡Gho6sz^7zhi᳧eB@.bŊW?M9sE{K]veSZ~ԩS)u4{ʕ/L$F 5Ԃ  L:܂Ak\sMK:n H_(HɣKϾBvڵS~8\2eJo?\%Ad-Iڿb kҭteofYKL/O>ebUް(#BhW?57n!(ʿ>ya]_CO5__}15x`OI `A^, @?r~H}^z>Ěo)Sr^o5hEp,EMM4W̭/Ŋ-9s4_i]ey4e=3bqd=u+i"]@TBLuU_{ҫ._܏J+=b  2g #@͢g-LD@lX~Y %j|[Z5Ot_z)7nܘr icǎQti=5رT+Wmʿ/Ӝ۾}{oޝ9sy?O<ҭ[4U[14r" ް(DݻeٲpB璢E媺u:J7V/b!MLeƋ%VZ*[U Gz<~xR|9ih\aUFRo-#G#aסCr'.gR !\jVre mٕO6/(r1 D޼yE$@@#PV-M?~<)S\(Lk.iEZ@鞟8qy\+}P+V[+^O/v4>z[ѭ'-kx]'|"yN9}3_SdqC/Ȯ]̽]JBBBRV=M@ ;"@4 |2rH̀VFcm|}l_?{Nzpg^Po}]OՈ3J -Z75kf=, ,X 3߸x`7e:u}@B@ s=2vXٳgoO7 '}]J_}hgϞ_~mjf zz0 &{6 {;bsZg஧ߢ[<$4=i$ϩߺYܚbquI9_CI2XVNo{OVS@ |l>{ZF(k|GҸqc3'gzo@E|59&/cϴ; j]o׍{ C5J*th/S>PpW]8ux~yW j?m9ۥ;cHLmנ+t%\";vɓ'எO1c>pz%l}s! S@3fszQ/]U\f>na|0l{;Zn颫Uׯ_o+8Сy_KxX`hի\yf>L5k&ܹsW_n)X 4t"͛77ݻ˶mAmڴCXWj; 4x`{9oE.֤w_Ɋ ^i P@_4V_zVdvI QSޒ{:_>X JjPӀj%{>g@t,͚enAjG^J3r:s:jl++;wec ]r 9;y⋢c6*F@[_}=H^AO*]]mZ֓Օj^ogt5n+xuƶhpՕzVovje˖YGz'4hܴiS~sAxmٲhYϟ*7|,\˗Ϭ[ۡI-N骫J j/_\n6[D &^{ B (KV_CoL  &L0fW:ip?Z]e{8 s]*5*Zl\L>ml7tƀQI!O!cEU>h m3Éb(C/C_Hȃ xgU 64Z- e˖ɣ>귣|7_-Bk]@իS.6淢T'um_x֤<%hjxڵĸFzI+gjv5PBt3JѠ0.ʰWEA;}GfL^ci+zkBlm3ʓ%OÌ+3%t2+_n+V7?ٷ﬿؇O/^9Sq:%&&O?t .-"r3gya70Lp^L4Doʕ39pV"4i61qp-CG /3=,zalqp$/>c *;m" @l ԭ[W.\(o}TNb{Ќ\)@וΠ@ yA/ukWCu/|^c[o[T o8'˖-ձ;:m" @ ,XPZj%}6mW gxX'#?)O{mh)&,_q&s|ݷlqW7eļ_[PKI     ͍R Clڴ)bFl{.]l{UuɱsYN_ZtiXA}49   ތȁ1.~F}xm1?j\x緭[mWcg mݵi[l=LްaC0Eȋ   ^  z۷G{vcHJNؽ;bgIc!ۄD̃     l Ǐ;y±>;qұiɱk;=5cyx@@@ T E DR''_H}ȶ199vmǚsq>|.~$>ÆA   @x"+Ħ@޼y#n`yvO k+A99v3ț;Ӗ˗':C0r   xԦ-HK.$Uh1Tsm2('Ǯ)],r\)^<)q$O2eiF@@@X k3x@ hU] BEuW-_3+Y.TP|55kVLY_m9 RwF0@@p.D@r$V6rGm]5ָV-@YN6糭իNW׫tiګ]wC4   ξb(-ЪU`FKTlSЦcWM:Mӏ^Ko׮cm   kxcmF$УGY]([l- mZ= G?.5~mXfHm_oeuk%>GۑW^vTK   +b$d$+x+D^F.Qw-?߿KǷFH=6Iݻ{nuMee3| ҷS']_wuRZ5ۥA@@@ VL2Ȕ}'2UN+ JȭF-[\'Õ?\M>~+ jO?tXN   @  `Fpqp^7 o%EǜSH9`Mmq{vehu!7+l(.2;vl(E)   %@  &5jYfw ;^N^+TwsR@pl#JcVq玏9cH|"bƬFIҥmO?y   .@7g!@{'rrmÆ䧆J+6%K̳ruz! s!_u饡VPsAw*~Ȱpx)%5ӧKmk@@@7 ul3VX`ܸqy59rWˉ9gy/͛֜1{hަmmZq7&x.`Zx|m4.ZBRoIÚ5-o:x٤ؚB~*D@@(@׍Θ@ C6a„ ۲'>z%|pgϙS7V_4meաkҺt~?AǂUI/fƻg c_e&>wJE{RAV3CWhv®y0A@@W XՌ bU@kX|\nJ_yrUW[U-h`sh۷ޒUflF}!?;3&Hopzѽ_~:-C7ߔr%K\]F{WhѬN]џf{ůkeCfWvt]4 )^p7Muk9~m.9fNN y@~Y#Ha8D7-"   ؃{ _ݶufjM6$n>)Z\j8 [_4#={?sΙAĤ$պIW6_qnРF K Os   om8d(Ptiџ ȩG%n *V$ݫ6na  ΋   q #@7b  gk<,\P6n(J*Iznݺ~{gOe֭RѸBӦMq b 랹f DAި&:  |ZSnW^\W_'xBN:uQٳ]‹ p @"\@b\ IJo6;vYfu~hѢ{I.]1L>]xѕ=|g2n8s,_}2U)Vt2@bG3@+4zj3YztWZٞu {k4ղeKڵԮ][;y7_~gʠA'NL9:w,M4%KCf>A`ol/C@ XG@T 99YFil+k%KAͽQ͟]vɺuLgy&UٲeW^o&9s/:B YIq4a.v8p!8% $$'{pKpw '˲~<3]UoTWlqGvs z%Jqp@G@ף΀Cl3,A8qnx TTw7G4vO|yܖbŒm?O@|M*e<@z%&zlWo&ܝ;wxwMRu\s(|g.='N hԨQ#=]tD3mxA#Q``%x(x=tbxyi+XkٱfӦMAڟufׅ֭[ӏ?HׯgϞ}VgY/g>C@<"<U   82iӆZh!Vq WYJzt"uls̑[>G'[9>p@@2yi+7So2k,5Kǎ|/}Cw?o>찿7 _A@@@@<:p Ǐ^5gϞ Җ-[ĉ>KʢEJEr椪ŊS*U(yĖݹiter {\b#zt w4 9sQyk ݹCN7n'\GF T'K*=gꦢT? & Ei(eҤMm-I"%;cq*~~2 3qmi>5v]siw= hQ??IUZ57V,rC@R$C\rvMǎWғ'OիWS82d R2e(uF   `@ m۶ԳgO{Mq@@K AS ԫWO OxOzEk֬QDKÆmSdASВ["enxhTU#-/<<޽{Gcǎ8gOihuV 1ݺS9\ngaqfK` d/!fk]:ԫE J 3]5i+&JDMʢN\t)M:?nEnݺt2[jnu=&2!`~ڊ'Rb\"a܋_sO܈*VA'BV),z㛇۷=z8n4Zxxj,x>S`cjܸ1=zH"̘V2{,J0Z_aJuo܄~ q%HCqCi~Eґx"pQڮN x_*X!=Otܹ:wL.\3OK .\ؙno8{%~R6g~C'Ǿ9Ύ[Mb5Jq-Xeqgf4ō:P7-A@v醳 XhU\9Ǥ3}=#zk݊;gn'-ZH5z|hp[7G;}:Xpuxjߎ?(zM}'MZAA\(d Z}GʕTpbƨQk ڀK K`ժUԬYxjJ]:YQh2~| ?^5͹JZr7q?҈gb3g7)3ppA4n<["6&ܵ)+0 yy\eر !!/Ulp      8q5iDlPQXnP s_\y|63q+]õ}9zNuVgŋU@tMi_SUeN%oGd[3v|>G\Kn7AصkFn +ϟ/mmi 6tT\SQFZeܧv#Fÿ̖˷nףGiϞGi5S ۏe*aԯ+VW)11:D(S'ۦ"'/<2oLׯR%tx(x=tbs8rܹuR5ldTnWzMtSLl,n/_nVv>;ʼn[BU>Jsp9 {͏rzN^s<[ psE     I^7X  0c"{(rMyuZRx9KU=w ZU ~YG)Й3zp􂾯: A@@@@@~O@%ɔQҭ[rczⅦ:)|[[َK7i]K-ngŋu     O^Cx `FQf'֡}S[KZ:9=tZrH/;kQHSMi3uÇOq      N@id ^ze^ԖW(O ;-Z}5|_WϏz̻_F쑙@@@@@ ^kAT"3fLFv~X1Zeϻlӆѣ(tyE/x_q`D+8kϖEz?-4X';$H%N$:hI$5,8   `B͛7aڼy3?~޽K޽ Rl٨lٲԠAJ4I/w@w3C SLvZhw9s)/qcT5eSk;ۑ%Mkhz^yK )Sq,Y4   N>|@gϦSz~#GН;wtyZr%u֍RJE=zbaxxi+UzM fZ%YFٳknF IÅrʇ> ̩>KʊφB:L+V)A@@L-\LJ,h~qTasl|A^euï *䃋   n޼I={8 X_⿱ .t:&}ŋ5޽{4sL4h?~ @<5@EEt]nJX:lְbE|pu hlRf+үB¤W(QPJÕABD\Hb)g,gͳuF   a^xAj"*߿VZ]B~m۶onӆɓ'Sƌ]v4zh1XTvm A<5@EEغuk{+׭M H\l}2He3ZM>~r(^< ;֯/YlHtmH/z5džp   ޽{өS;lhذ!qFȑ#iѢEv]`u] r/o>7uTVujժAnw@;^8@7fs:Mrd@5JTgpFԶi5mZV:;0_ԫE Z*߄NĈl×: +M,U Kie]lܢʕ˜Wg\xf̘Lmy3'lclg͚5iȐ!vy5Gj7}t3fsδw^J#66l;xx=c cCIuP 0EWߙyPf!eJOWw=4lnj~T2`fZӦM   Ǝx);xaݟ3gȑ֯_OI$v>/_Nߧ R˖-?+YdR> w3p/oUZ cp'TǯjlD-%ѣEÆo|t)P@+u6  d H\Zd|6i!#3W.  X‘N ;v8G *s>y>}z5Vh+˾$' eyⅵ&8 AɄ+ [T+y,F˟-=reʤJ ء^="6fHGWt)SΙK\үU+)ØJNyL׼α+k1(]t40х;sΜ9Rr)#PPf|sA8P&%H#yø86Έ+\n%@(|b#(.6>h61kr Q4k%dzQ*U\B~VNӖ-W_dCB$#,tIy$:g."HycF+~Xp6x-(AܸN5Bb#c,bSI2LJʉ6j%JXA^@=$x ԩS敚c[2rJKkZkɤb)44Oy6[AZ@ 3AT'ϟO;w" qӦMN%-WmPgD"r!Իy `>-ٲ|Iҥb߶P IرG)9Ƚ`F:{]7Cr]:TPuvW9%{ƴy)عt=.%ϥ#\Lb;w9KnݿG[Oś7ؑ~"(X%MZ*;U7'"vȓ'E}޾}W-ڵkK:gϞ/0oppsx- fp\p.aC'o$PhQig[<(=޽7zE_J?7: NfIV Nݛ:L;SW.ӕ۷)3z #.iU镊wI,6 G)p㆔+iôqRT(јuyHTߨTSlXz;@IDATnĦO_<>gḬ.+ҮN]*Ex?]B .%TW*27-I@$W% >DdM! O^ϟcx 0Ӑ!C] .m(pfgypF&gg?oNo8"n%':_uf`wx(ekC25̞=;ܹS)X!rNB#q<002x I-ɁK 'Kȸ~ߝZ2UK9k3=1k 8Kﻧ@@$\V).M >\ 1N֭ׯgb%,\P:9{ 9   n@A^7$  _~;~xJ2&vk$k֬T]J ҥ >B99sEi5w@;^y``"2 .]ӎ;JP Aaä 8oOlpۧO/ WB׮]TaJt%@@@>% < @@; To۶ڹCiӦy,q4n8ZbEFI&MXPs&8    Ec$w (H cǎQiѢEƛqY;=ɔ)>|ԩSRF/3 aa w@@@<2y=c@NxӰǏSN(mڴ 'NU-YN<Ϝs+.Y$ʕ ]x x"dz' L^F8  Rti){(~|lJ˗[3&ŌC+ pz  k= 'pA?>mܸnܸaޜ3Rҥ5(S6ۺG!!jNq0kw#̏;6eMMUr _x΂?٫WituxGF ƕ@TRX(mN%J$ 1VX'?Μ9C퓒+zC@ ԯ__ 6@(QfWX!L֠fid-jHCCĉ4oHK D-WlgϞ[Q!a„]S_荰)'/MۗrgJw}8spIxlKbY]6Z2Y?[xaMZk'YD`Q)[ +"2.>),eh~e˖ݻwmG5kFm۶=L߷K88k3{$nEJOYNMky{{~φz,z :Pݽj"o04h=rcǓ O'9kf=}.9BP"j͟G%ڶ{#UTqӤIK;v(5_ 6cs4l 8] ^o8KoVVuRp͛7O=p@܎n7e0@@+;v젲eQcVi9*7sUo&SJڸtV*u)J5gZ*+e~;}:ۇ܁W^];ED:zҀ)]r%Tj$2sC$׬)-%^,Aޅ R֬Yi(K}zZnUZ+\KI1{u3a%.]jwcRѢE27L/nc#F iIpBLOr8{,j (.6>|ڪ_Uq}Yo#KϰA?  *dJ@A+NfժUq7UebI2%eɒXbY9r58)S&8p 3jԨ!ׯ,=39pmN=3g]C!"ਇ S~V=uw̖5{y"z~PўCaϟӔK5S:ʖg٫Wim)v}ĈTR& h"Yxfy* dɒI5KSh,J^]C7ڵk['O.-9v[.xNn_\\ATR/HŊ#woL˧]&DWpzz3 ԊgX+vltIsΜ&\Ok ]&Z\zK6A+klݺUSP  `l\&M+8oD޽{%=[h>٤I] :Nuځ&MJqđzs.?~ .n7w S2df>QF3fL/[gt|h?MY:yyR![UMZU_k˪_3ȺRڵ^U/߮]֬5xnpk-K ־CoѩS>='O=zT:Ր$C +է2pC?p@ٲee9Xʕ)J(RӧOS^(ׄ2ٻ\NAUn;w+VlѣSɒ%Z޽75ڲϦ>s*%}{N=[߬LQ/٭󊆷bTʬwO~#gxCƐu   /5.u- uoZow k% q@l@\pjӦMSy9иq ^K_K:L]v%NR]Gvfb5׬:d… ڗ9Kٸ^`Rq֭|gqh(=׮6BgpX}|z zwE>7\5e}%ӧP9 E  x.jk-/Dy.-[$JȪ:ˢMV &xpC]K͛G .|59rVZQ) @sO/s׬Yq &Nخm!"?~|m2baE[{l@B[W_̩h) |ϕ1˪!|zyqsBm6[vFY>| U;0Z sWPlٴv=B7">帎q6)~:Jm>>3'pQA$q*;=+y}ZrI8Wj!kGcIiR{GA@Esرc s Uތk0ӇOժUvX^z%8p8[@)@{9Zn:t={6$/7U5{?8؞e˖Y'mڴ쯜 XGvphNm=02',MbZ[َg/ FwW5mIXh}7ϙc=2M Q`Ms8Sg(ZwZ14p \# k^z/grI8qh@\~ 0]VX+. P}{BST)Cƍ?)c_t8Zvmr K.UsW%#UJٳ'M>]Mp=ofڏ7Yc&=$u94/h;a!NM?MnzNc^szͻg7A@C7˜9eϞ]}ɓ'JMk"_/&8 v ."4u p HcL>M4R.osLcsaÆ;w[mSklybŊIg>$3f̠Q,a]7$ILcԜDҐ}g⋛t6$Ms\?%~< u>GD_󬗳zME$6jS8UTNVacoʫWu2gϞI sny+q7J.ٞۄi!]D^I!  *x]%~  L?/^d$dWnݚʕ+ݳguM;j(RڵOyW^nLɀ%;k<dΜ9/9#Z;Yf5?sQߍLiR⯹Ҭӑu2/ROɖ.Ӿs4 ;/c&wzI Hof2FwWX5]:kT=7$8{ʕ׬i48#4<êi*Pro{{9bx3zLO֯__Z%u֭K=-9ݿg8@AAA;x\?  (}:jځ7\ڠD!C2dw)B+ݻwO /_/%Km۶EdmذAW:r u -3x $IXlb##|q"ZwnLolf>hR~[e8kԆ:H"ŋMSϜD:-̔:5tzJd03gN̡9x1Nlɘ1&kMN#nP*ͶY.UW *9 pN:,Y2ԩ۷OK\߾}H|WCdg˗O| -piСZ̙,l \kfklIN>-֪ \o85^&u󐯘#=A/)W^% ꫿|BK]Bu.+N)>!ZKJV }  &ռyV«Y'o ٥KOcvAw#W *9 pt͚5$o4˺x MƌCΔ9AS#qm1_:nܸq`ƍSG.[Ԟͅ;&.c7[j) UYzJ ݮ̛$Lz|t+ꦿQE} +ÿIʺq7Uܬj5ӧ7kL=P  >ZhAjQ-.'NTkx6LJ?ӧO//M1@"CC_p@^@4iݽ{/_.AVgexΝlWg?Hrgȵwys8ޠm۶%q֭xb)SBƍ+WgF\?(mv'O(t_*,ӐB,3M-E&xNbZTT\"RJ8\X ^6jbFR,J;ۣIS$ꠅyZwvxشq>H ,׼ܶ9B>0 s&qԣi3~,{M?f!   `Fx?y#YK=Z\z '>|ԩSRF/fz@)<2b&Zg&>yVZ%e^|8Xw+:{Ծ}{i.d);wn5[x MZ8(ݡpmlo47!CʔFK( A>-%p}ZȨlRJ_(^Ca](6i!Uj2eP導AmPz^T[ډ (@@(,V6ڵx 'j.C)ҟ[2rBpW@@&#[@,Ѹ^weM#?vx<HJ 7ҩS<$@N^Bce>RҽU,(5q:eݎ]8ݾY`.z=H9@Y~"$O&σ.HX 2iVL رcS1?PfM驨$MN,ZD|Ch¯mڨH1Ѹao+Y `f=:p=9Ύ[ǏSϟy {6<<\?͘w>~]%oҧOO{^ . N  &&3A@OIgwq.%V2#4Vss;F mJSǺk/jCCH4QWz;HdW-nɑ a_B`D%`ф3XWxQEH akɐ]7Ѳ17TMU,&Y͛nR=?~ѳck  @/0#nfpV[{ƩljCL$*gӶQTTA?Obɧv W dNk&LP%YC5\ySn|a pv[<%yM}㚢ڟ&*:EվSJ>9g\2_t%)p[Olʉ'j_l˙*T~ۥp={Dg  I,n۶`Ze-gGT/I,*-Ji]U8gR ˇԓѨKvqso3kC+%|`턟Ʃk7w,3cF:4wqcw*bL.?[HZfS,wݿ11wM8pb :s ݻwO*rUںu+ Va+Wz k= '}04^޵gVv~Ӥ)7b*%ThQņ.6e@;,ď Qҥ1NA͚)2ڃpp3#+0庳|S]$guph!KRk*%nۦ%?E@@@@@5uO M֯_OSDɂqFzܴI?Oz2sA hXV>[l:M8+ٻ"Ǘ}tEd8|9Οߕ!t@y9ǁng}k>u:jڍ]Gc:vo@۵#+W*qCI*6?KG=6Mmx- NGf  "P_#ԩS7w j/ݼ[bDT_4f]C3V#Cd>.Si҄e˳gϤݽ9nT?7qhUSybsSJW_UC޿O7 w#Z}8rN\H7Hӯ\"0C*[ K$*q;ݻw*1Gvg_ϊeN 7nÐ`zZMK%EjH\L!s0x%C1uI|`;_'8tb.o~~-=~$Hgs{vk~φKN/00:t@ݻwl@@eAH@/_n#f"LNg?x-)w|6<{Jo~~L/@W QoT|ǁ!k:<ߗnޤ7]lxꕴ?ax)u*)ۗ?g/_J8bXOfxMz1g_>,-1 /^ !kڢc*|7{L Hrr\p̓޸I؜)J(fJZ2S;óHYio5ΛA@U\;{i&@@@@L kJ  BZD,y f @@*\`50ZZd1.7@f> k y    %aw@׻ނ(C^e8b ȫD     U醳    `|`!q k%    @/pqB+ ȫ1ppKhz߸q#}7fW֭[iر4|pڲe q 5?     8 @ѣ˗wQ֭)zee'N H>ۗŋgцwRzСC\+\*Uy<n    qqS @<@pp0͚5Ks߿O .\/mk׮m7+Z͛7/͙3֯_Oڵ/^H7oެP `\wn`u.]Jo޼Pϟ ΝKt-f̘AN,Yݻe˖TzuF 88h =    U醳 nHk%={Lu-\JjժP!ȋWOVVs_-%j~)yXXtl+ ^A^f8  ;vЀw]`VCn5m:!5G͜I+vl>X53yOߴeK) ?5kJ4t磐d ]N nZѢSe&MD7憿; v^y38zXYܥ姆+R/=~$1Ap0 ^DQ|Fɒ? ܵ%KX@gwxd|-+@@@H*q̙3֦"A%X|ϰ&xb@xϟ?.]мy촴}yݴo n׎i6e ^~?L,_FpV?y,,SJ9;_ocΡ1sЫ9bP״?D&޽)CTt5Tk҈gM6Cyinhڔ8]e߉ٴy~77Em|Xd=g:|Cg@6?[6wu;n1cJ)ڵ7[֨I+WƟsGիW^qw\>&Ҋ}a9;MódB@@QJ/i*Qn $.\Dc#`u <g&}<݋фrUv`9ٵKd}R51ٳ"0|K=pVe[Id!jJ f06y`?Uԑ .mQJdsdR["m];Xm?ی10=pɓv._S֭ c  Ȕ)%vxQW^iSwF.$Q:j2eH+ kxnz{ Af rjѣ4i /ˮ+jwe>-o@g4/jk !mm`FԸܯӳ'qa5ba19Y L&'F7̥TRrUعtH);y}7Qy+o^ٱ:!hyCpGߊZKN:ZuT_y*]/_7nLk֬DtQ  2xex ̘1ErY30q9Ȁ)SD& %ETt=ʥje3,#Ւ>PAb4eߙo_ wb>gƏl[QoŃlyQϼgD-~Oe˖(VlR3&MJÆ LxQFI3/O0΋Ć\A@@@&L  hʂ3{Nk8nTH+M8V+uvXZKD ?^ U똰jR 7`-StfʹGk~^՛.3׬?{[ Baat}̘1{nxI&QUwLJϟOS]5~~~ O "E k͈maoY.Qk 5c'KZ LPMEN\\0yKuRYkECp@ H\z@xqs6&@/g.]RLiكI F f6gKf^jIZai Sg_]3WhnƔK4iIY8E.k~~ 4 q}Kk-?ZZΟugE}U;΁Qҟ[ T1iȑ@&3 !pBl.t%Y-vlnoN\2AYwjz9͛mh;߰A>qǻ@-̟38dkn=xP39{H+(FMD-,… ){*̘1iܹ4hРs8O#(p]DGJ ۏv 1 p QByg[xóŦZ ;C\"DeAU=2}Em\-˒Z괥k)d3@@:YQ«gϞ%J e <_}@ܗ;w@@aǏWxD;cs`:fO? ["গ9/b^rP6W ONOY ?9cFa ;@@Y='nݚbĈŋboLcx:_Ow.2t1d߹T;.߾ҭtS_>6\w pSM/^5.Цea獯}ˆ' ZˣuZx%Sp@@qYTN@IDATRfͤr3^;=|  ک l^mW9Т}gzn zϻ?ȍ ojo=lY@B5x2@@wc߆~/.zM;%z[GߙyXzآƞ[Nzylj>>>SMĉ(z\S;'OnS$I ŎCzX٤κS% $eҤfũtԯnz}?M2}~ˏiɇ=M-;4ɴ?mڴq" w3p@lhniө駛ʜ: Խ!eJ*6KrϠjIo`FfȨ<0Cz]lșά M,Y4[&$_ׯo׺6jx?~ot5?|Fϐ7ٳ.gE7ռTǸbQeG9UZSMŋGm#["O^MKpljU5숒իQZ6Zm2ƭjڌčkb/.3Rl<CjJ.](M4j    ^J^/x  `@q|R*!&p5W׭KņcZʀm(^l}꿚9jGvB~1b6O՛62>Ș֯$l}V9Hگ?$0G&,-Ibvm:#\1 }@@@@@.m~5 @@8&OL1b̠t)R@4p]jfJΌgf鳧(bnKKbp@H7kVܶ&57QꋚF%KQ/-0M*;\i]5JԒ_ )S5|ISjTR1 X|; 8/%E%AiI )iIiQFJY:e]؅-ӷaٝx9̼ws]K596x1@8k,Z8_5}jXJOUvH5*}(Re[WU3KG+F,ZgvH*VtCu?4ء6ZV޷/k@Yj4s5VυCRՒ%Ocq\iH[A '9jyÒ%GjڃMxm O&о}{oTGxp*?8:RUI0!2fiqEEKӊ͚M-l)VG5˔Q<=ED'0 Npu'U4 .5ʐſqtjRaϧрv_8݇ 鷉G.9dAE pQlq05kP2ϵN:.^zuz)9rbv"ڂR:Fǜ~Jt#:u钽ǑO*KD׏7oPf?^|!pU˗3)W,{<ńoRDDdϙRf5c?~"sT)Sss%&,y^N&Fw f(l3?ӈO/2;w֬B,bt9ϵʖ#QPHHlsE4+Jh(yy7;~q 00ώk=ϱ^<6f_z%99sP1کJ+L2^o>ڴimٲoN]zUzH6-%P@@׌yA@ ,M68eC!μtR9 &D$_GH˕,F8;*7/}3u*E ;߅CQE|K[O`$s ZeR Ns)EqݻK/\qc~֍VBLz.MSfrszeִcd1-\##8sϩKψ#bZjŵ?O$ltR{v-*w,.@l}wΝ?KǏc.˗-ZPf͐ŏvѺGcq>Gǵӧhx <mlSSʕ}TmU3/hyQ7ޣR6e OʖK0|* g& XD>s.޼Ax&bnFq!,#%'N,Er5#_?qMeq,H{c=mW@ԩS'ѣöp4rH)jwys"s?*]ڍ ALJI'fX'аaCqtalƌt1府ϴ7K|vF -|!U Ŗ"PX"WG'/M,D#^۞ݴ!:|I`i3 <r"WqjV!oT9-3W'Dq=l<畄]Rfȅsc kt- ?ISi(_l3sf#m̍6cG)f;J^Iyl俑^ 12?NKc{c#om~1?.z+'w}![xvu0kqi.w +: <@ (ݢEҒ%KhƍԡCգ[@<"x={= ׀@#w^zbњ5kzta- [ldɒ)[luYoN:ݻwq3gP޼yi߾}RJ>YNʞ=; < DjՊn; M=@@@@kЉY .P3jQvho߾]_#P˅߸qC>L3gΔs.,{q^Ç[}&׃'D^cp'kBׯSpp =*TڴiC5kִ?o(Q"k·N$Iׯ/^jUx  C'n5c`%._le jPR{yQSʁK)C 8us< J:p@@@@<k q0J]Gw5 8.UtÇm4i[kx6.@^<@@@@@ ``"@X ^xpX#lݹsF"O:uwdWcڂ  +@@@@@ NyD 'w(z{{kjO&M ղg=~ddt?j9ڗ;D^MLJ EVuP+{^~M]tC ݳf͢/O>}gϞIc->&k?@@@@>+{p@ ʕ\FpQp:f͚ѦMŋS˖-3lƌcAAA9'Ͻ{!܂x8Dz"y9o@PB2eJʔ)pݸqBBBիWL| yҥKS x0p@@ǎ>} 4El1UD4Y2P߽K.e7ӫׯm_&e׏mK62ud0ۯ@o޴|"aѴz Ӻ˖]>lNϛ6ӶӝVDp߲V-][aaw$~~""'Iʔ6ȕ*+FKv[q?2*U ŏGҥsK+>/px oN`m,  x忇q@Iq'ٳg+Kz`РA4ydr-35o_ "zR^ v4zBbqah0*Y %J0bY(D3gH(/2{Psyyn:G-~Ϥ"bƑ)JFvJjpfu9ꇣ9'|DۛExxq4~J߶iCҤ+0_w殮6Ҟ)"2Ҫ,׫X:6lH ZǬD"j#9?0(^ .|!'+??}R/duƯߔ+pȎt bϞ=K7.~LLxOW'&~.>zH:̩Ҧ5+j>?b{S͟= ìa7 ݃hK@iQ9x9SF4g@G7 qoiu(aRϚӝQާBh3;ڸ;: "VGq6j ],\a=XlYiHbH%.Y,Z ^ݳEK2kd{vS_{jJ~^\u$!ӀvMIelk~"߮]E^k\oժ!RɭUQ^0Bu^١%6+)60 `ѱjժovP#՜ ε[c]7t9F ǏB}uVkb 偈*.C.|yf)q4l\]}LBzyd'ZllX\qTv9BEZ4YWoX6 q?&tF]np}9bnV/g[N@1ҮٳGm"lylۉ'FYELj}    `4x6#@=j[А9sޥ~y vm sQ]+'GMqfArN]%q0S1u~v'[\S8z6f*bvo`_NgRL.UX_xC^BPxCmQ@@@@yxg nL`m6=1# &Or8ߪX9xjmbn6pq^W#NK۾p\g 1Â^^6>v<}ֿ##SWOb{*W~0Ŭ>iY8 x.q4Y Z~z*W\tp;A@@@ u`7jbVر67-q8.Ppt_#ˑ9Hr0n2n"Ww]1iS86pL:z*p%U[N{OLϜQ~F/\*z0-%Y~L1.f(|qʕzF<6mjxEC'    `0x 6!0@@Ç5נr~y']ASvfg\D~KTl1#rp^~~diz_Ύ reek\ް˨bߟ'O:˘цNS)]kk>"Rs+F/R(iΝ;i    .E &#pWDYXBs'/[f,pȥe-uZGɓ.R;'r{:TӴΰysUF -/{?C݋t F,)oV9pbQ f6~*M8筊@@@LN'(K` <,H{Dj"7Qrm:|V%䥋 ㍥ndbGpNdSsȾ e8r&Z^F+ ׯj_@1ju.Un,s^{P@#[|~|@<^O} uLEb惇trPx,Ǔg|WmBp { ,*sfF^l<{Zu=\;E*Կqt\Y~vZT/ssԿX"K$I"f̘|}}LJ)B_|-]U#(  I zlWX DM*Okhib s~<>ֽ'w℮.v!j]jY/.ߴ]w}7ooEv84G9~̡6Vfqw߾}6C}'pӧ[fM0a߿_܍&<{S?'^sF)៖UmNj7| 9q={('/]b@/5HqLl, xuޝrASNu*Wmذ>cP>}ڞQ@LKi(MJwP/DAF"5=zh&Ǟ Cu0PmaUqi#yOk[n=ۖ)qO:X7n3=5&8 [Rs{mLZړ!M8cڴ$5}yY;ʱ/J=}T)A1&! p/=KL(A'=c&݅YK7ejvǘ {v[T9x9&EJM/pk/2iQ ̥0Q066*T!P@3,XLΝf͚b/͝ǀ nI[N+p@rM/_>g*Ҧdl'%>cAoߙYBER7t|"1qŢi:\%VGڲ˯$"u@㪦*ŋ+ҏ4yy'{$p޽!Mo߾&L @"/yA  "ի؃k.|cZ&OaUD ت'PJBUs0%λF Fׯ_<  `JxM9m0@@-ZRXM"AiIXToR21Z,f}}LijK,Y\aDr$Vi)JyuH!ϵ*_j6Rp!Śϖ>],ݚ4=-:5jDT̃5Q@@ڵk7<ӻDFFR6 RJQ ITMuj֛u1mҫEKa^-[R dÀv_hfK4˹!;UEC:W%;}]/s ^0 z4o ZjTA!0zh{iR_%xMO? <֬YC߷k;vH$FIV"$$Įv Y z|[;'-Vk6JDur6t]ltUӦؐ9}z!d,{ܨ RjKy]zjp-jR} }ʕIt,t3*N|_۶\tw?w`C\ij7>Z+GK,9x8ӧ C۷Aϟ?'^%XD=W_ј1c 2_|z,.]j4Be$j֬)a@, @൤  "OÆ 5c]ǎ/f5Pf|4+WZ]5E+V{"EQΝiӦMԧOJ'cE Л7o&<<>Î9BEg(۸q#u-^xAą[@<^Ϟx `5#&1FBG>m3СvBNRmyz{zlxjQX5¡CPjtHg@&OQ_t醻ZY$;L9ϵ _1{b9JtnFw;ھҟ?. J{ͣY ڂ)͛7γǏk׮]sΕL,>ih9ײ9 /[f$.rph|Θy2 Ѿ?RR],-'~mȕ.XV84n.)rs"'"Q=_8y~:ݹsǐٳGq8.2bSݲe˾B ұѸ3gΔsn#{:u>Nx  zs8rm۶QJR˖v0|,rm=[9ruw\j)+d !]o9ď}"#Z]-,!.tlծ4k_xq:l9CƬT\~\2‰,Fv.)~dRޒPQf+,n_fpNpvYm/7rK wN-Xv,2 ܂0gĹsmƌB,XV)a„ѧիc$חZ*i<P_+AA&M(N Tlf E?ĩұ]"lp4Tv&*̥l9:Mw97YbLMx(c䇳N1Eː&= U#Z4f"@$"ڱ]P>9bL*+#E$g t)ۻ"Œ oOT:mlqWWtkڌo@k_v?OgbrҮS>̑~({/ <<'L$ܴRʕ%J"P *@a<]rŰ-hլ5_"`7 휺lnAE ւ@@=zTvR+gH-Ēq{З; f)9/Q"˴'Es7-Xc4vZ:_4ԻUK!59}--sN}>ZӌU+i-0(Ȳsj&իSM9ň΍ >m9tH};iȓwۊ؛#sf,"vTFK6ͅ KMWK!B'c7(84Esy[e vƚ_,bG(z)v=Ȯeh jԯ\YU'y" '-l\ Faaa4n8*hÇNgwC{٪ FM8ppkҥ M2~ =%}:5j$-Ur"{V\_5i*E޾m,EE|isiRU)@d)sb߼OôvB+6bjܻMًEQurU  oߊ|Ɉ%H۝ oVbEz.~="_xd!_#̬"" TRd8GzJ6CqD^Ǚ/^%-l6l͙3'AϞ=яNHH8ذV^-le^c08bI&IWO{Œe^F<{≈Tb9U.Zn\& !?-_ܪ ǎ@\bŤ[ΫۤI+ӎ޽[:^z$3^a@5TP@VT>SU6,kӦd ׯǬ[nQ۶mc7yF7c={69r$xTTuܙ^~M+WŋG&݇     F "F 6(O^z.]:z;cǎl{uR=hƌ԰aCb *D7oޔ_͕+͟?8uִl2Z*q?2eR=\xRNMs} x6=$IǏ;wгgϤ/y!s8'_pllp@@ܗD^[x2ĉG_>-5jP͆iӦIyx @6lx0ooo۷/1&M.]J۸qh+VH3g|'7$x,;p&o>jUT={JWk֬yˉv&L2eX;c   @"L2\xݺuYfǫ:}R:Np58s*nРA4p@ PΜ9)s̶8A 6gΜCқ7o| 9ʕ+&{쑖Uq^ؾXmSm;   nO"O1pP4h+-[J)0"^x={vϑX9zi Ag3 L8Qw9WT>}&m׮?6mD)=Exnj{G!}5ח6 7oӪ˖-q x|PGkyf͚qo"fjOp,uNZPK;HB1B`E `n.Zɭ:# z>A9z7wvtxH4iVhQ{ϟSlׯ^?*qb}Ǘ6-3{-98;s.kyv׬nݦDI A~:G·"y'?~λk{JxV͒*U*)\ҥ} j :u;&9R\9^n~zz;J*EiӾs<?|𘇣s.(4z0? <}Fh!~ܓYɭO&-^2ӛt$Rz-7TCc6cǟ@o6^˛9o߾ D&MCX]z59D AB9x2S B4l0`vY& ׮]>uFRA$H9B={$N    {HJ #0aB⍞GWdɒɓiw@FF&S޽ )۵kWZ j۶-5k,]ZN:W_ѝ;whҥԱc19s<#Ec- GU xxprTJiunl{Juז_|cE׬c,\eX^s{cOŏk=TXiʕ4~x:wS_Z%h "%>dM@f|2}6J@IDAT3(eʔ9oQ#?~,==>fr-Vk~ N:Q=d$4iRDs`5D^L p6Ys 1U     D7     #xs@@@%WY @@@@@` lB` *D^# lP6YS"Ho߾3gΐ?]x<6U*ʗ=;ʙ9۳ g!2|P)(^<\?t  `B,z~~&&uxsQIԩS4|Zf ٬'eH-kբ΍S71<,~۽6<@Ϟ;16I(ϑ/NUJ O?Fg\a8QBJ~lTH*'[ Q/_{w%q7"/Ȝz'1f"׃&! 7A\'p5ݻ7vwv}hM'ذ+Jnp):v,"n` Z._. }ZPn?ΚEo*ZˌeЄ=M/E6U+͛Z_(wnݪ %H_޹C֯?iu(aB*S}V*]Vxw;*E?)y^zE}|(W,T`!iB!{y4B_wD.e*Ӿ?"LBWPdϻn*[;K?Hq`24BpBѢfxJ:b.E%~^E'PXDSvv}'"`@T\H,y8AG}O,p:Z E ~hSt$O۶`ѳ_۶6¯ WmFS"j=,iRvЮ])yBĊ~LigCimn^w_DcH(.`*Oʖu4-ϩqG~r|L)~^2ƚ=~wÇk!mڴT`A*Q%Ps7[yfC6A~iͯ@ԩS'ѣcLkI PZҥ ͛7~9o`)mM4#ҍ[2sU*V,_# #h)9qŏ]?̥3dQñj 쿒~Uh1"WqY,%Ny)1na6C֭vh&vNL&OJf)vZ DGΝu$Ә-Zlgls$%K(BԵ_dj'4GOE/dY'f/gM +1ƈKJ^K-[!CPfc;_Y1 `sc 0S&{2j9kX^OoɆM%]ݻTWbcgzfJ<ຽ{RԢ]\B+w=XJ7]w٭.|E*޺q?OvXe?9/sɓa=XE *;`q}/?oD[4Cs5Ŧ'N" q#m@s#FęV?8    =p[gΜ~n5d0<8t㯿ikO /rXu8Ri)bmIyH| kþ}4T6z.TLY6Cr$Jsںz,,#vB/~w"8ra9LyDwLEJy#DbsLˆ1}Ç s~ǴA@@܋^Ox n"r]0R@8k;Gu7v;{*MYfF6n~8Sq"Vgކ7㜻j9=1\_WgхNVR'r6lk>'P{[4?+,> ti8˗]GmEիW;="Of4A4p^g [عs'8p@3PϢ TZd"={ 5Ӑ̃fϢt^n¶q537@̻WNQQ8/;:EAO\/?1>&.nߔ(1c~R4*a}L'ZcSw8Z EY4#f%F)V~Rx7Wgak]Eǵ;w]_M+4,Yw.94Gn:ߡ6V^&9LNG6֘E -sS(]8zLc 3МCW)ˍRÚ?~D#oS8םjF    (C}&;oR=Vn3r.ղ,ߺEbkK*K7mj(yf͖+]Qiuqp467o{vQ\RD{׮ֿOygn|Ǝ^8XR(    ZP !j{7& "ʇ.: 5yZpCvlnKMX>{TOq1s&xjIkzKbԚOҎԋ W ^Yek͚5j7%8kܹe :8y3KoFsEW4ڀG5Γ+>֪p4w.q? @<ǎqZ#>i!/UXsI%:rrE( M$p   j6a `*W\@v3}sy=}ǜ["W1ܹn4NMu*^u3*ga?X1Zp&]:qbB mgP^ Sxn!MANKIy5 ok52g'=(D׾~{c|]Y9Ԯvo0H=5Z`d @@@@}xg@LDU[Y/޼яo仚uت(vŮطt_މ[R~PTQhLK|~V\Z]+o)  PJ@l F@<c>Gqfˠ;JinCZ-!< .jrV `oojZRE駟Rʔw@@@<^ %"Z57KK_pagouE굨YK~qՏ.JZh5]|^]ԦN]%Q/?h:kWS[t=ީQ#UMWWu W:i3WڶdTc>[bB&MT;RBqT|#FP;   +D]v"k 5`MmVxR~@q?u.U*j<"GhU"%8*~՝ɨHyNJj>[4j-"Q'د6vU)^UX;d@vJtzJ.Q@(    ZP "P~}2ozt֤t eHiElp. n%%KTQ?u6SgMrZ;cw'ǫfһ##F{Rk;h%N|b~m*fZ-;Hc%K7qьS3C*y9W'xuQ] (+.L:4~PP&ٳ5R&ONcn(,nȥvh)SV2IǛ-Y;[7gٮsTM\qon( ~pNCSD~[?eOuƎU,?4 S|9K"%m2x\)9:w`#]Z[hn͸qq 2 )~c   Eg7G bb%3VԦQ_}&SYONj֌/ޟ\IrI@Z)T.]JesjdIкSDmrZ;ed,8xYԻU+YώsQHb@@@@@Yx@܈oXXSESgկ?qNJ /_1f7Z4lխPAQ9Y)Sttg,TkTkw:Q4*`G2KWEנ/1cۅ(\Y_?d(Nfù.ZL샣%xcAN-gAOK{ĩ-w|(?Y9jRz 8JԊ@{!*5!@@@ N^oE*I 'XP䨨(j%Dk*]t#t:t~l;Q/_Rhնmqnw7 bTB5Ry4*0sQmF2~%d,*)͏"]ΝKo޼qzj|L]>HdBvN6~=#&dNb }x}옽M$1Us~XNwVo5X_}C;v"Nu[ !~4 v ֭u{٫Wc.X.W^0SMx`5YXՊ_}'OЙ+WaP0{#) +/k.yLI|1au/9c<ݍ4Y!Y;}:u=zЛ^g(J@icakȑҟĒ%IJ Q42RQ6:j% 9#ŲS'KyiAlowSG!o9bGؕĆhwg1*-PCuqE>n"ה>} ,&O˗kB&ؽYsݡ"q~ %qz"A-Sh# `!G.P~vnPi&גpqI|C4CkmRd}x@uZhC61 Fxeӏ=*ra*4o(_?Њ-[ќ, ˕;7j, ^9,"wkns7k^&k֩etfVzݽKg.Sŋ AY^S$Fy!L8W : @@#W; @@j [nbMqkb&ժMGC!-"x sU.V\vr0A˜Uyl.hrbs8l٩|"Ҳ]7Zdσ۷(8$TrO+6L2f$k"E fI+5oD?9N̸fxfE^< qC+$n( AVZϟ?X|%zD ı4)RR٨XdqfqT*e8y: UD2Lln9dGbnϓ ?Y'|0xMf)LGysA"Qk5k֔={Fa/KnؤІ7MCD,s9 @@@@@@%"//(    JD?      `v@B @*2 *Aų@@@@@t W@@ܐ^7T     `y1O@@Lg=n?p@@T%WU@@@@@&7nF   `^\p@@@@@4%WS @@܆^J8     `vy>@@'W{@@@@@lk NX! = @Փ>sk     B"L4 @u Z E>s O@@@@@ܐD^7T    Lt     jȫU   A{#psy|8I @@@@@&Wk@@O@4(p@@@@D^M @U.@U,sk      M"o4 %c0@@'yvh       #@@@@xuAA@@@@@@Yy@@@, e`'A"op@@ܐ^7T      zs$3^1n

ObY5evd*=~V5_~y(s6$J#>o&ײ|Ӌ?Q@@@8) (zn8Nӧ7B ? x:Mn~2 ou܂7iy+>c;u!!x -QO&דg?>%LRHw׮]#|2=}S))S?RibP!hG a7iRNas"""hdɒ9֓0/^HǓq8; D,Nz{{SJ@5mre~,5;5˭;-{HI$Y8ށڗ/_Ju5.ac<01lV8 >yNjZΝ;?ʕ+͛S8OvР%w |  5$#U, ! D…H$"XhNKɄoKYeqWkvfdV~K؏J~y;g,g b/'<9_ p6_D^=  `^+Pp@ॠ}͝;7ZذV@ӐWd1qu4nbIԴ#żoiJ4KW*;e5S繜|k{rEPƍyE 'ۻ>EʗJ(Htzg"4z `>A5bB(8 1 8p5kFߏyʮ!bi_i͎z8ʞ)]Rj`!j]vؤ O4W06:FAAgZuK3<}o…ATX1ە ~֮1у'mZ(ҔۻG=yjيmCIՋi'.\N~^JI/moQ}Ӻ5>K9tnIu"%.+U-YZԬEf' Q#=|H/E8Gy?+͛c}!?g{   `v^ ;4,~hEĤF={v1W^>y) ̜Iծ4ipj)[01u䥡%44Tʀ9Ymҿ¦+V:t;[=A^E4^kwP䥋N3VC% px2Gsg[m9 ŷkNm(;"Q^*)*m*҆T_DZ$BH)Iْ'd_B!;,sΙ3sy<,{=yyƼc=R=[LM|4gesIQ{dE$h@wߕ GJE2۴h֠A,ٶ"M[>CҟJ}iY<^R%3j(iR+X]f"=?=o)v~%̍BYS5ĹzwNӠIh3YݥW^I -@7/C 0awynbj#Ț5,ƛG;T _ &8ޠx?1C'7]\/Z(:ysn)SirA}H;-4ϽSrm[ƍeGO ?gƇp35KI Is'zhl0ht3ΐ榈ݹ{<ƛȫXAhLkgШV1ʉ|~x`קfΛ'M!MeJ&߱uqie _63^WoּL+޼-on9KqrXg^jpn4pt:K;\/m. Lp[u+ijWr<٣G]-[q|dF%~weWd֭am;vȩ_TpW s~}]foм̷ީo߄Q,-$:EӜEN= >"M$u?_Fx'9uާ Fҟut\.5sn$&އ~;b|?^tzO,D&2yGj`Igt=Խi~|`nzitvz~֔5ȫ7;8+Aޝ$kdWYTcǎ#! @Ϟ@ |cez^Ohg}Df/i RG|i1.3xծ7o _Cv=n7YdnYYz`t+~QWn'^9^|7svvfi”tn-\ K Su=ޢ &>ik {>is3t-'Ij֬hP  wjE O}^0,&=ǣ[o CK=fJkf{+OosB'y޽{dB@r) 9Əc/5W_{[Ikٯ|]#h)S(2QRAC?܏Amu{_mnK{{dV>Դknk0ŷRWQ=:rOQ:c~_gN#I֤mnLQ,Sxt~Ҡ?ٍӧe*{~65(97'Z 9N:dGoj  כ@ ?i2T a,qq`7ڼ`7q\|8kHwjϋfM)E޾HV5mv_ϝVQl⫹?zC: **G}'ⵝ UoXFOvk۶mXݸ!n;Qg4-zh\߮#Y~c/Mm]_vd;bd{N3ņ-w# ~d/,2bZmn¸-ZF1  M MGґmAH{3vknK:c`?C?jSλmk?~a'ѯ2oU΋{9IymcLyAB@gMM EŊIK9+-Vv-\8g3~] j_E/X'%ŋxx@~ŻJ-/KKs̄Rŋ;?[a{`3@\ %!@&臒2eޕHVP!fOU9:uZbe{ϺbVxӬ)~?$*%zHkT fߵ#5+UN?NY%fOKUzRWz5j]ԫQ2*Pp) }QGyLE@(xr@ ||Z^g ˗.-tTZ~VגyذN{uVGWN59HYSפ?$iNj6˷7lY]}geUVQl J/Rn؅SD|NpۻR  s>:o9@ n[7n{*i(B }׫'9Sw5>JOHp B)U*wf˖A& pV';S<)BT&qEZSw^N9յsR+))tksd@rWN@p_!ԩ=yOo:cUvmcvu_ec\-3sx-Z7D;j@Lke{mF8x8l:+<@s"ڝMלw;yTk=x?D JsOkR-"Wwhm ~]JAL5 ]{m~ioӏ;.zoY3fxl#9Yuee]Fnmj"m[M7]kG%t~^z/#C|Do&o&s(  @xSpL{ǗH:w.(vs=|eͣ=.8:TrUWyUUѵkvD_E󈺗.({G<+.->qp)RHPB;@Uxs馳 TCr Dynŗ9O>JUGnrj1awHjidu;騰qX:_F>`Fq_ݱc]Im{ҠVpS׉/|slq|ˣ=,珛7H&'LzM`wA&uR`c HQ&^ Oi=/DTسWdt5z@xs K`ĈR>ckkf#eg uZH_#ՑQn'nym)=hҏF_"f#6!ёn6׍|+CtbԆ7T @PyJ$'~fu^Z({ %:ھ|x2Y{ GS-2 '=h>Wٞt>LO߽R9zuёٚGo?kn=0տM N@\/gI^] bŊ2dW4sL9Ik.Wʳ yxswVթ͛ˤ!xg)c>P)}pFٴm+ubW 3۷O6olAI~YR0_B*]L|IL)ݻwlٲE GX~ʥɤ/g;.:%p(,\P"&fT}/ OBmқ#ysf<2_uC·W_{]o3)[Dc›}(_|Q~]*jSi_": ?]?=OϞ-\fΛ'k6luXY@:n-0R+aW$ޓbNb{]y*WYݡۮkw^w~gx٩SUݻw^.Oe)@_zSx,vW;m4ion$}lw򐡁!Rf-X 6m;m"VA j~^\:W.]P_f.lF1#"2Sj[7h _|Tӏ;hyRr夎 ;-uk`_ ?Su..R?,g̈[^d=PCCs1aL5KvA,wRXY1d/VʶEoV0֍Xf<n=~xC&y &zɏ ^ũ<" ^x\lRj3gySG4)۸Qyyzr#):gwY<7^Di-Z3Qߺ5j$r~xL47:t$EM1n^bE:'e^1 p൫߰e =Z^Yo惾39M`}c~*_E˖˖۬F+-+Gשc=MwsyeEבGT&8a")DU^gV'WW[)A^_o ^(^@IDAT <*)z)8plڴ)hk`,I`3W2`fwks+\M=^kͣύ#oGc4ݡUkk4U3kAg5qVqe tթZMoxoJ4i;$k_1ZW[+hNΫGU<,k֌^fw$k~@&%3fqgW A^/2!M \@f>}uf7xCz-aYL}tgcѧFÞ8&H-fnCqg}d#Z}?礓Wm_G S   J@@]zR   @q؍ @x"+   ;yq@r   E oZة@ f ;   @lV@  YM   @. țN6]Ep]   ADȏ J@@@A@ 2!;a4@@d|v xPL@@@&Mǁ Po.; @@@@r  ]ot   D o@N@   I o$!v    @dT@_L%   n uKr@2Ao&E  2]@xҰ@@@ y|vh _x@@@NJ ! Fs@@@ +@%@7woz  dAތ1#b37o&E?KCJ_"}BJ+0mܹ{ oDhQԦ/]Z.n{jբ 5O糿-7?gLɒRz 9Q#9Svժa잣6g,\TVY#;wbEHʕ5%~rH&@ yӈO )V ELذa\ve2y䤺hr9ǍrÅ"Ht>O>!Cy'Hm۲}<0+;{ͨޖbk&YЌ4ϳomy]syp^RxxzV=='L砶nںU~]ʺq3OK㎗oA֯Pްn6ƍ)3gʮ:v-Ok;/4k~oЛ\̟'Sg͒[H>dB 9g+ۿo>ɗ/dD`  5  M͏@ \RN;4_RwF+\hzM61v={ýzI]-&-ٻGnN}aX3uLx hnjޏ=*:ribkݤpW?9zDŽavCdoEl 6o.{̨vL1~"}|;Zκ٥A.~ϖiLNto7*lW|[|ȁ <ȓG&ЩS'nFE2dHɾhYmٲ,67SN~AOU,YZ5sWf+og )S&tБzϿ.tS>'M<2tGniܘw*ھU+y롇wSc7ZJ,nFW.\8bFO,W͵h*i%5piCšV]+~[v]kދ7tO+쇾~룏!#>Mr9fR|#}Le?t.aH>*&y糎^>wr zH#hjyO?Ȥϯ^yaT>PUJ[JGX6eLk5]LɣIh3⋣:Jw.̍r 2gşHc"0<oȑ#o?3r./9sήwJöԞa?wjpW{tȄ/Ho֮6ju,x͢s؆%3)wM+'=`H_rIw{9o2s$]DY+jE:r43r{ t7m̗'NƗ]*_cPR;-_&ǛrL~5ks:+δ jcR쳤5v#L+yxa͌-IĤ#y"! VFn|yguA9Q  QDEtt:w7ޔuDJڷtՋTT)qR|^12o|ukFZ7L,{4[Ӿ(fe)Ҩ^Tx X53#۴1:uO>):tzsC/L O̜'(a7nTDD_wݭ[mf?F?^z=2ZL1V ,({$=/$V7i-cNnS1뮻N1jpWSLyD$S҅_1qM̵#/i{NTg~fmgџDgfJey23mK/ >1SKzg|io Y5HGmjdnt57֤fy 4 zz7NxŊKۓ'7VW^ $U}|O\ ?w%(~N֤?f:ag&W_sl2EJ:7u+3W?̉-TMנs7UC! +L'H\`?Qb-jV Ϛ.bk/"jN932IG^$qv~&,熺6_ tj07$RI:jNss8IG-#I7OF s:Ӥ'_;ȫ[?piݺL6?$@$@7Hg M6jRO?V}'tS]A ryE&V*¥KS+~5aNgGoFji#mNfq(yUӼ*>r^0^$ 57Ƃ3S܋Կ7?ȵiڦ7ޟ 0rv9ύcW}?LJڝ\CaNεH_!ϻ{riۦ߬t3ϙyI EoP@ @-Z#w˕+eժU/ut rq D+h9uXʱ^.m9ϽGcW=iߌm_ rPt3Oi 9},O NGSgr})f$}^p+FV;X{׬S֤s~8#:˔)M93jwziU5;@Q+X)U!@t`MrHԆ ̚;2s֎1HGjp֮3jb;wnGY2+_x%.p}:s ȗP+˧;-4sO~]RR.d'PjyZ_dvvߓjZHgFڦN^ H(7 3rg{p뗕+e\@cFGkaY atiVdNw:M5HF,7Z~:@q]-KG~cj`1{ҟ,Z_)} pǭ @4d؎@.R%K`s؄08O4)jjԨa +Z!:i?ٴϴwhٲV?nZ?;䯔Ϲf:\7czt;o/ț ^MwZ*78{a74y+_*.Tލw붺;=f!MWy|"Ϳ~ɺVm,=ԍ+_y9 _)9ڵk,6t7l*E*s*;>dF@@r A9W˚H"K/]^Rݟ? #nԪ%8"զr|^?~7JR,$OmoFg%[T֗|Lľkgy&Ծk{^β:ꨜz}Gzz{?S}^$@ &vrZ}ŋ+fy|TFT?~נOPS5:{*- UTr4hrNHpO?z9Wښj; mרQTyo3cv6k̳7o+|ӦM~.\@ǭv-iƺI/~:z~m[ossB5'TGjWohEN3s&k$+ߟ{=SRcǎQ7ڨQLb^AaD78@CM R{ĭč IG!KnT'JN86_[h!~MS#ZjK'Μ|ɉpSN9%c:@;^%pk۶mIA*TֵrQ:tp}^ 374Xt饗.,2U>ѣGRr-Iԃg>  @ w ]"H@?(X]mY>R7o~vgvy E=*bޢ5G:&:tr6 /̹)m/G)SƵ`iE:3)JxOQnaHܺ]kN!pWVu]Ts뭷2ѕf)sΑTn(K.$KV#\@o^]qlkzܹru׉:3dpBIu:8U@&EfrΫkOM￷ūύ]vue_7蜔~Kvzڵkg4|~i}wqӬ ܄ "Xsph,T_o]'O<(ӛaJLuk 3z>}lm}WWU6x79ѳzcbĉtNnw }& >C2j(9rӚ^*Z~# PNB `>yweZ=#N:WgzoLbvju иV׸qcXwm35\<Ʈ^;M4)vX(>:\Gi4r3 Cmڗ}IF4lذGS ԯaM@ڤI^CI?tjg̨Nw 7|L6-t72S  &a:[1e]+}[^yg媫/Zo߾h̘12d㏳Kl⩧4YbE g!hk)I(1bn'EvjP7tu.RY.9>Ð4Hp /FQ~GC950Fhk>s/ }DIth/Ȉ 5k}qyuQoVk&[7;/^lMKS0[[b<\P.}A@^'JA hk>N:U~myO|ngW #y^$ kV܋(S!8pEe+CGDi0I<|AX >fFM nڳ]>KJR*ZGq4;vt)M'xݗT8Hk E.ѧX65CNrmެ^sΙ3?r:Մ^3gδFT$ޠէ\Q}DnӬMW_}z?ߍ7pev]  oRrr}XjlܸQttΡR./kc44Vrt57O?!n 軑4PCrִeS<5IH#o>?vi%՟Hԛ;ڼysq|Ç/)uy1ˮ]hOo :CaH۷o,Л}.R5W5Z]f"?aVlmذp" ݻ- Zo?:{ҫW/N Fda#Ut\pjQmS-uѥ{GR':2:g rW۪timg2IaL~xK,+Қ%ׯ_ߺ9`Q["O? 4 닎՟0?|eʕnjZ ;F rN< MO)#< f'2ow\gjx'}^[ A 3C@ )/vC^z%k$ioJk*UiڴiqAɬ#ˋ-JIݺu@Zyݺuү_?5$ik9+} ܟ}YzSDk r ڝћ5Q'/k$@v9*urKZAN=lBZ u33 ԉo|h9Fa; @PLpE6pւstZnIn6)V+LW!ZŇ曘о^x*ha~t?PfϞ-:N:BWGuį.&e3>},\К@ȪNիg`oLѶϬ=]A*~x;ϬM7qCG% TAmB(sH^gqԨQGYlvYEزeKk$M7@ݹsg>z,X`nǕu~YɨsQjp9vzU ?Mz5[P!k> xY} ʮP5/o Fnɩ@@rK@.f ]؋]hSG5jժG5}e9<ʕGB@@@ xӡN q%K<0ר,NB@@@Ȍ@@@@@ `xvBh     TS)!     Bs@@@@@xJ@@@@ހ    8 T|     @@@@@@^RC@@@@&@7`'     N:"     0;!4@@@@p*@ש@@@@@  9     SN3ԩScV_k="H;L &/N0tP8СÁ>jJ:D<%矋w5K/Yך-ЦMZ:vܸq_`C=$5k֌ Sy %x !{o SN9%jޜ;ܼsp |3ψ40@,"kA>; |;vUgwF\|VN?@Ο?6m$%Jve[\9z4"w 蜀>l][sַ: Ipv֭[g}թEt_ܾNxϋ̶DC^n]ݻCݾWL@ lܸQnVmݺuv7`\"2 XoOMC4 [i4שΓ{I'Y?SkΝke9䓥@e?ӬmJʝjՒ38#:B͛!#tpD+3}+/#:?Z7<+}{3Zen_a{8Zқ:pwl8a' @!'&"?-**ZH tHfi3}ɲecə׹@ .KͶw^Ѡ]$+Ϙ1ú׶nkԨbȓn_'ea?nЩS'}*ܾ.Чג~{߻0&;@,@7'!C9$j:ՂG͓u]fRneef;/ V?4isavcΜ92~xy--ZX/_>fen_' N4IN+sW'\r @ 4oܵ9x/"g}fok.:=/]D.uW*԰aC]v¥zq-'x@#@W^Xm۶mQM}`۷[E9-I ]; &Hw^o_^>f@ yq셾M2Ūҋ:/^q|N޻0w\ S4np]a;{衇F}жxĨ*aClܸZLWրqƞϞKPA1LB @ yK`ԩs֭[ʚҾD* 7`N F!@7/@ TPAg}\lԬY yYׯоH;0k "{.r1#6m$={fRF:g7nɓG IrNXC+u{^h/5/nժB2 ZN^ ﹣ / \  :䓭W|A.͚5;h guyƌV8g&M$6g宻}j+&:[|yDW^{)u{^R}O/ÁoP6 Eo E. w=0V7>~JzaYFFeۺu}իW-[g{~Zyz7J@ G"E]0Ho޽l]wu9 4hP L~モ H׮]7K DoN{޼ʚx˪֮]+7o9 O%7 s, [L$ @Fԭ[Wڶm+'O޽{[̙3eŊs\R bmoѢ*U@Z~G_Rk+4j@~]z矷: u-&ODtjx@wn/Rǟu*~A-ZdY);3R d̘1pB멇N8!y8xC@4EZ|B ٿy?lP& @x#?dQh:QqAjժٛ} Æ -Y:Nܹ\q!Sf h^hT#GgyesjyNxT"ׅ%5W"h5r>w7`8D@T*     @Xd-MT    *@7UAG@@@@$@7MT    *@7UAG@@@@$@7MT    *@7UAG@@@@$@7MT    *@7UAG@@@@$@7MT    *@7UAG@@@@$@7MT    *@7UAG@@@@$@7MT    *@7UAG@@@@$@7MT    *@7UAG@@@@$@7MT    *@7UAG@2T`ҴiSWoڴi{gi׮݁|'O   ^M)@˵^+?k׮k׮W>#+O&Mm۶a  x#gIM   бcG0aՕ[oU}SOGjժ%s̑%J7   ^o})@NpG˺u$_|W_IeҰaCߤ`2c kJw   "hɢ  @:t#GZU۷Oٻw\VpWw 8n:Nu" zFK@@@=dȐ!Vfg^LΒ_ r!  kx] @@ tƍˢEtRJ?Jrl@@O)&@@ EW^y%[yDx  x6@@ &M~A%!  @zǝZ@@ ̜9S `hѢׯZ`-t  d 9t@R`ǎr[u *$ӧOzYU_f͚e  QFa3  z-K,6w}bk#Fy޽{Ν;w!  /x}a@@ ƍÇ[h֬㏗n~r-@@ oRHN@@<Xv}ѲaѩfϞ- 48P]aÆ믿Z&N(s΁|   0[_JG@B-pUWY]Ľޛ-ۊ)":UC v-b>6"  L)%"    0f*A@@@@ )%"    J@@@@@oJ     /x}a@@@@@}R"     ^_@@@@p_    "@f*A@@@@ )%"    J@@@@@oJ JU|IDAT    /x}a@@@@@}R"     ^_@@@@p_    "@f*A@@@@ )%"    J@@@@@oJ     /L9IENDB`latte/tools/countExample-1.png0000644000176200001440000033450313442213440016040 0ustar liggesusersPNG  IHDRx  iCCPkCGColorSpaceGenericRGB8U]hU>sg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|U\ @IDATxxT7@ @ziҫtRU*"M ~((+z)*M*wށn손d')sΙBțw.[E(     `@@@@@#@7     P8    =    8TCf#    xy      Ё     ^     C:th6     @     P8    =    8TCf#    xy     vl@7n̘1#[yE33ff#iuː!%]FҥKreo 5S;noƿi[T7L~R| 7&nl߯RJү_?  008E`ݲzj]v5Y:y9s4{t9ɔ)7?… bpͪfj%K/ w._{~]/qqqFB`LLMKZ-_\f_C8L"NȞ=1"͚ 4{?h۷OEnj[ĉrIS1**J"##}_D cv `iCOO7^\ryEhW_$>| /r ~^p!/`C;r䈜={Tֿ]xju:܅[ )gs\h     SO"*     )@70DžV!    >$     xs\h     SO"*     )@70DžV!    >$     xs\h     SO"*     )@70DžV!    >$     xs\h     SO"*     )@70DžV!    >$     xs\h     SO"*     )@70DžV!    >2A@@`2yd+WJ޼ybŊҽ{w)[~ײpB?RLiРtY2eۡO@*   ?(@w9sH6mL`eԨQ2`ի)ɓ'/uL7VZ%_} 6L;)\p    R48ah# &M&MnjdСb 馛$..N^|E1cF" .HڵMp7K,ҵkW`ŋ套^3ի4It     y @( \tI+ZT)QQQr&[dIٽ{G7nkĉ&{=y'\oV)P<Ӳh"9sw}l    f:ah# SN7J̙Eg]#""BufvuV]Sre9t萩?_%aaaz6{ᅴ:111p@@@@ ȣC@FaÆ^%"##J*ŋ].]j5CR2eʸa@@@ uڈ^@ Dcrjwuq5M0{lw…+W.QtI-HEBl ,m۶]w%=   8QG6#! O7GұcG7n\Ϙ1C*ÇO}ԪUKZj% ˗ѣGu& Cݺu]:{5+W4.]$f͚rA_~1}e޼yk@@@@)x2R1;łn=ߖ 2mJ.]Dڵ,[̥dxΝ+7˻?3ҫW/sϟYƌcf *   쀆D@rubŊ2x`Wp>Qti4hݰah~]kvy=7{QFyE@@@1x3T4-… :|Kxxk}e˖ݵk׺ ,h5Ń{WkC٬Y3sh͚5F@@@x1L4=oŽL_{M6p f[_d:pdɒ=tP#   xzxh  ru~ݺuxڱc\rN^]ĉ 79bin脧G@@@ 8@ ttfn ŋBhϛyvo6sLK,zU̹RJyMbN    xyx< w޽{ .iӦy8p@s<[l|zQFRresO>rY ꫯ̡֭[b@@@Gu0HfEСCɓ>3Q'L G?CN:*oe&h9l0\ZtmeԨQ&BZ|K+hP>2u5pܢE uu֕]MZڵkΥ.6fBg=jw ,\5QBtڵktR3ӷL24E    0f:lh.8[СCҳgOy7Lp;!{͛E=d͚U4_ه|âAƍǫ7o^h:ujs)40۬Y3Qh~8Qp7a['\^= &Db@@@x9l4*y_uq4] LsڋybweN7l0Q,YH:u1yOV\ikzDU4h`iZefq8K/,O@@@ @'mD.M[Μִ :S)Z9eOi_4֭[J* }M3M%5s"q;vY5RҥKL 7Gvȧ$O@._B:pw?3e Kk7gbj" q $r藿ȑ#jΜ9^8pk=s~8޶ѣIs۶mҴix׹h .ZELKN?<ɹ$!@>}%::ksf7+}|3g$iDGe@@@A׀% @Z i4Eiр?Ů{j"Ex}d̙͹Ԛ)͕+36Did>C~m[gTyvK?-8?:3R[7染]K=ӿv-ͤXZ鿟>l#@0  Ѥ/ ty1}Jc0s={$Q|YX1oo{РAfwz4jH&M-5k!VQڷohjٳX9'Np|E-]|!774ŀ"RH-,taW-_[@h*-u_۟OEDD:հ'\q@ PAc@jǏm>oɟ{jFtkNn,XPڴiw}*"   N%ڈ!+`ൃ `3e}xuXr]iqo}|~>g9!@@@24$?~3VFۺu*j*sB '<3Y^:xŋX'k2d,`aR|@j6mA@@@.HqZ~}ssOn5_ҥKyOiҤpBq2w\sF)3R?qF`w-T"-֕/M|#wr=r=LA@@@ hJ֭[~M:5ެ۸8y뭷;UVrj'N(u/8.0Ȼ++ٳMuv"E_˷#Gʧ}-[J4 ?l!  3f5@MlٲҨQ#g1Y]I}Ktt քeʔ)f3;wSNb 3glڴItkvEL෥VZkfGVg®~@@@ N@i}y OWRhзhѢclhxԨQ&ud2M Ѿ}{i׮?qn;Z   Oo<v@_~C\;vȡCPB#Fx='4yO 5 F8.C@@WRC@Z^   )zTC@ ]o.'OXYr͛W*V(ݻwe&mqˮ.]Yɺ>ٕ5k]V`/~Ϝ9S~kӦTTg=*   Z &0g@Çݎ̟?_F% ^z;Necǒz]C7%1bL>gVJק@@@ cC@,I&KZjұcGWlڴI/V_|Q*T 7i`R2vzR!AYf|rshѢ?Dy7yE@@p^MFBE@}}-Ue_reiҤ,YRv-}=vW._ք T& ;v6L7odgy@@@g Ț3ǍV#!!0uTٸqdΜ䵃v#""[nfwŊk.n{Qf͚^ @@@ u@ h bֹsg^~"kܹs(Pc=8w8^zk4;D7E   hޱg .\  6ڗHR9EvXvx sW^<9rx=k~'lQԙ3g$..N]@@@p^!=@R` iٳg< .\r0;u$hJ?9v<_.ǭ) ףv|[oȑ#e˖-Ƴxrw%&&&`h   67BHe|9;vq{3dС2|py衇❳wl̷fo=}8^݂)ٳgeݺu+Hnwx֭_j7~x{S"  8P&# `:3f(۷ӧKZUV&׮RѣGuf6jݺu,_^|=>{}d|@\ ^Kׯ_%.=zM΂Iwߕ?,k֬yE@@p^ EBE`ݦWW|%C+냶mVt"kڵ,[syyOo<\\nXA]k&+W,Y4n:uA ܹsv\H})   S3N@X **ջVpVs]DҥMS7l ,OIQ#e5cU;=:QnoU ]Oe˖Ҹqcsj֬Y8xc   )@70DžV!!/Ppa/} Veٯ/FFD^L1Kߚf!Npi!S@@@ 0o`x @4p/^Suo|i&So̙X֞_oץfO${[841W.v ONX'֢svٷoDFFڻ"  8H"$PP!Ww׭[Nq%9v9C@|\\Kk_rxcP떯{HX+V۷sO;v7TRwW@@@[TTDHKZzuYt,R.x+{˛>*n 5'qYfWҨV-Beuz;*{vV,ڋW^Ӱs ~k[Z'Ol=Z:5=n'OKA@@p9x7f޽{.\PMԒ-[6i֬.[ԭVM_wZc?2fhNW{Q+˴] Z3y݋{7o:հaC}q\74`W_CO=)@@@&@aFs@PE*V(G9sm5c &CMח VZSF<ҧY\ڹˤkzHJ.mLw.ӧO7sΕܻ瞳O   @R48ph2 *aaa2i$iժ_^4ZhY;k&;w6t+'lBHܹIe iyؚe/\lYYa-$A/ݹs>}Ztq:MPvm9qℴhBY)JXc5ܼyu/J S@@@) ^gFBF@g.YD:Xr57] zi^[4o?,Zm$KŒ%eɸJ;yy9"s m{O<+frȑO]v!CEf͚enk&Dڌ   3x` @ @t1cѣeƍ iz >|Xn6Yre/]V~%`9dt^td\36Q@;1_ѯ۷ˆK=}JT"wl;o<կ_?9y1Lx   h>.(SҞř27[brw~1ۦ 2֗GH6mdIAS8*THq\ru9   LR48sh5 %Kl3q;q۶5(^+kw^cǎٻ"   Pرc.CrE0{8zL>TD@@p^gEpXl۞e5v'9#7NN@@@@a  .g&~ V>uLuԩd_    q  2edKp8b &y '/ZrJ%"  8C3ƉV"xhҤ5'r&:2RjW6m4Y   +Z @^G=/^\Zu;~ERreS@@@Yx5^@Mdɒ2rH#7sX^4X2f蹂Î6UK^V/ZT>c   \;Z ` tQM&7pG[*UcJE+L'a =vY:O%@@@ x2o @{ҨQ#oe޼yrb)%'uWZo,ogϊ.$״vmZ~# X`.h!  ) <.EY< u֕ ;vHc%w܁TjIhؼH$@7 N!   EǏ# y@@@ \Io@.@׻ g@@@ ul@I 5q   xudh %@7d/   xӜ" y`h   rL)w@@G hW?#O@@@D.@H˗MP.]*tӄJ隐?s\pA&1̿wڸgf[髾F#`YB%jN|o15@gu8J@q/^4A}KÇ˳P),~IIɓ'E( ߿t 8p͆o>tYOܹs^߻5A;GqPkGMƜ?^2f̘a @Z M+i@  4u@̖-[=-,^fmנ%K,+iH8/]YgR| o+q$ӧML':pKzŷ%k֬TCLjO\'Ln'w͞={uHgkxo \9sHX/ jfx3g,i>w2*5^HivWv)p^ Gs/#3;WZf秊4A` @zL@U@^۳'P[G@@@M. !/@7   s:gh) i'@7y   )R@Z oP/C@@ H/@H]@@@$@:Ar@V o-C@@ u@R_ o@@@^  yCr4  Z @`  5   xC-  țL0#  '@7l3 +@7xǖ!  :jh, $@7   @  Ց \C{   ,@@A^   @ M7z @  +   $N-ڊ @  ѡm   xt` "@7]y(  {z @MW  x C  B)r@@@?LU +}v4Mpgt0雷5;YU?,bLT*U0_2Z˻}f^L)Zn nv=$#]CJ{ȑ&د}jԨhXgN:UXzŋG    a .]$:#S_KYAMeV\~K,)w>}{Ykn#ͽ< c-Y9Jgҥn-d~GI:u]i15w˗TJ+EW_?M,O>NLwf\m>u7m4^|&[jUٴi2 xS@@@``o0"}@T@g^nfΜYtfܵ!ݺu3:w׮])˗I[ːcMp|s1dӎ)L ]YH4w)iϹ F-`ƚ4Lޔ>}u' ԩ9>w\GN    C !0dӐΝ;K=6JYZ|СC4-A:KfM}ūh;Cƍ5M|R\yaiZYt@<:km,V@C^m@@@x=|4^;1cFӧOZjIVDs._v=*[+lݺukӇ 2H~}eVJ7Iy e)rIy$&w._f3;f~Ϟ&OpMr5{-]~$ꫯ Krn0mLA@@Ao0"}@P`\WW=z~[4m۶Z@M{]ʲe/]5L63=w&ҥe+βZPoʉjIu^L3TksOcؼER9+Ȼjʕ+%K,۩vIIk19}/}7͚530O$S&   (+?%;4@ \ų r'J.- 2 ,O95*?s+(!wOo+𠧞2}ܸ},X4:sFZ6Ӵc٭TEr=[g{˒%K'4T}8^@@@G ux@ x .omt!,Pӎ,]-]uk;^kѶ;ڴt{A0`h@*xP?ٺ-[T:   @  ! @h x/Ag˗ϜߴizN9Q8o(N=͙޴cGf֭RcYnz!ь`A~ߘ+קdu {o۶MN>9@@@"@9DBLP֭{U{1s>WA7]g!ok5-UӚ0eɜYƽfp ^ha &jdժUmY<Éqqqa^@@@ 0ױCG@ЙիW7\xjϛ˗Z)'tfnrLs[Koe%j7Ɵ3wd7#:}Lok5 &,Yh駟][Yb9Uo#Go8  8Fc"'лwoViWK0p@s([lҬY߻c W,i?؇|bgu\|Y:9~\Y~>BjTu>7C}7oN#k8-?u}?YfCs?6   X:.VbEя?#2g=c &CJdddPj}OfN=J{N"]F,Z춸NY6r^gtL^_M7dO{~tvoA+àAO  8V:I4ijJ֯_/sHժUE?jo>_sra_夕kj[oLᎃ2~sloiS/\lYYaoS˫]J}ɊٳҰ\h+)cRU\i=޺P+װmK.-SLZjɑ#G{E9p7uظq6wyM~ @@@ 5.FH,Y"OYAίZ/o4 ng{օUF_6n.ZX};9s?d奝0`dȐtF&MH%~eԷRXhEgvQXi-NXcn:ٱce   &@7F A,/SnRXD.=۶7\,AOuK[4)_e˙Xr-HΨ(o9xfͥ=Ȃd͖-rE)SԯY=riAA@@Yo0.}CBLRJi2!ܹsRuSeu`xp`B+ '@@@ xHdu5;jԨ$p K@@2R ::Zʖ-d߶l"qqqRH$빟ܴiٍbŊrm{; @7F>"  h>.p7~y+ ,޽{Kldު%:qFsVZ':p &  ڈ@O]voaj^gz%Ǯ'!A@{x8!@@@ }?OGY୷ͥ[N;u;+CnJe] o0C@@hphu~Ibcc%k֬3$… uVsMҥeѢEn:9w,YRW.yI=@\M !e:  -@7LJ!.^(~9[bbbImD3g~Z6o޽4m4;/"a}r ױ޸t3)t?^ }_56ns䱾 CTn{Lɓ'&+-,,,I[{_ Jjel ߯2-gΜ1C}_A BiU2!9 x֛!)Xx߿{M h9zjJ*T s犞4h "4i55jWzrCVZ;B\ΟPo.٤w! Alj5 ^K֠%nsk={LW; &! @ McpTo5]vg HE˗$\~ >0-Џp j]Aތ%s!,.aL?*:NӀfZK2fhrUYO-3BO>mԍ[@g~ӢﳴtgQ)w!gF5kɑZX1QDfbl3{t9fyЀDZAX#럼.i5$[\Vx-{ivW?yAH4_j`7I=Yd_iUMAU : N@p3f0YYYؽG.GE   Wד!&yfٻw]wu:tܹӤx.k)-:S~ hתL^?  Eua& @ ^<$gΜ)Zl5PG=xW\i1*U~x$@7F   &ɉן2w\9t)RD%׿d…2o0).D E=ך>hh2)N{| mڴ֢me2j(0`܏>7.޹%K/X &EU`@@BoP #@PٸZ/j|fk/-{ܬ>],_EWC0_pBf ު.^4}tywDsI={el#  @  [3SFᵺ@n-d@gZ+W?#]vy RΝ5p+xp|2m<id\Lnՠn߾}E_KYmQQQmoҤ,YR4J>}xZ({=SWoOuԑU#<"}],l   284@ ES:c0ڹe˖>֬Y3E}Mx \)>` -j-Yc.`=t5=g*kh kk_﷞~Ƥg͆=۴yXЩSF+Or̙Eg]nDDtXBvY)sه]AZ>Cq6@@@ xX@ 4ԨQѣұ׼YZ9J~oJ#9|\2C5f6:v49Oպ)-[Lۊ*$wXV=֬Z7dN{ҳ=]cIy bnݹsg^"k:}Ν~?͓'ku5-|8pc"  s:wh9 [݉'L?ҏ_kя9~\2[KzTnˮrZN{#>}͵Ӽ&c~Rs(53n5ńפ~JZHMKo4(apoR帇 $66k]]dVJ@*). 7%e,/*y̩3gdK,=q5,4sнh֞>}C޶:ZK[ky.]nݺw^ڵ\RX5 ZOs&U2Y>s(   \ 7 @P 9RVY~x]f-EWsKa?fۮISe 2OY5KH{pnA~>%\mk,}I&McxXy]{SO?3gM[SGnȗϤ"x |kp+o4<>eRbElK.- 2 ,0 9+WsREsXkreAR9   뜱 nfv=_yq.v6;"d^+;V00Տy}>j꫒#ٿZIS z)뵼1S?[ۯ'VN$:7sxҁ#Gc'?o:{׀09Nz5t˖-]X3*Tud&Dh_   )k<  r+R[N}mf=^zN9amemaWW\[\9t^=YzNYnoo)qd͖bkViWCޥpWnCVtm>kv+֢3x:;;wX);(   \xk<  4GK|ފ.S9y| D`S;'d麵rQSI9+'RV.'jc#3#YRm//}~C(}<^ 'n gy#8Er] g,5;Yׯs:㝂  %@Ozn+w-[Ϭ|jkꩫfUPc5],j{(w[O`ov-@@@ B@ $4Xk=z9s%wjBYmڴIx/ʬMݩT,_ %Jf펞Mؔ燾o"l4n:]Mf[sN{q#Ǐ[-V.@HU~Wb|s/,qk7;RwZX.~4ue&͛77GϞ= ?u8lOnǎü"  @  + @ tImV4Xe]TC2{lsH]دKceh>u6mǎ&:O7sL抎vҪسx+̉7uҼ3Aٻ=u])wҥ"kڇ'):Ysj9m-Ԑ2n ?j pk{s&v23y55Ce„ CHkֵ]jԨ!36iD]'wu:tH40쳁3vyE@@ Y?L\'  $SN?uZ6ڷo/Ǐ7BSкxϫti~W^XR({gv4/_?{g&ф8\wwKAK, nAI,!hhA;Wϳ33]o}S]}|wm8h\;WKпM[׺5R6a)$}m$ @\.5Ϗ&Mmk"E{_V6XZ5u!fsgm싷\[z%3Y$最,){j|5z蔐g:9Mx 7sxыIw(jH`ٳC8 q@Hs!Lݻ7]aV!L]O*)R 65w~Ŋt˕1zsKPߓ,L1$sUnjkׂV5j(Qs5ȍ{Xm{toV{`I6چÜVx]an˒6U#'/לy(Zt7I7!o噼|c_5M6y\Z"x3@ E "xEI-Z4"Dyf%2QD9˒^=N]|YQ,t)uv.|LL79ի,QeK.Dz#EZ;d/Ǎq Zo-_u_QT)]!,̕8pZe'VҔ|7tazi=2sڊtԩPܕoޤz_/6eJ*+JJͫQ+-T$L{eʔd     ; XS0.]PttUbEB]'Jڵ81cz-(i@F4kWzltn.so;uuYI0rH]uQ @@@@@<d ĊV^Mɓ'wU|hZ~xSa)hɨNS54TjM9k|ǯv*l׎U\TآZ5լ.q>Q!5@LG gΜtj8ŧNj-J͝KUJ !xJ^|s5j֟Qyoc'o+y``@@@@O=%7|yj     CS0-Z8    `.x5@@@BDc3@F`qZ0F8    `^x; @@@BDሳ@PqJ0R8    `x1@@@žDްg+  A@@@ @    #xc @5w    >EO 7P"7@4     Ck]y}w9a@5P#     zᠡ    f"L _@@@@ "@&(~  F&K0`.&Ivjޙ˗i겥t/\FSt|"T|m"Whv#IԽqcN^H./9sRf+WŋitJ({K.5kVmp@@@@DF ?~F3r /0_޼y;+VЏKRdE ' Өٳ=Kڴ6~?L?Lo߾4kJJ0!~"˖Rf OGՁ"⽇mUcIPwEwԩj*ț7Mw$c֭4m4:t(+Hv@@@@@l mD!b(_|vKBgp/4v-ۼe>ۧ9}FsDgԥDBD!-Ӳe4l վ|Ѣ%GNN]H~=K۵&Qܶ"o[}v.ViҤIN@@@.wwCͩtt9m=J}#GRJ8    f!,# ?@@4HgݻסѪ7x:~߫}1-1"Esg"*$eAAhc4ebRg3>ȜΙO?/ƎQ+(AO͞>=U(!mPs |k0M-NZm<|Gmtsw/Oچ"{ի aCժUuwGD~)q7SL$qQ廢rʔ1cFqn    Ț7  >Dۂ v}a=,IWFY۲ouQo<^-=K}T_PmFvm1e={pQ9뷭vdQʭ[JԶUncI0e "͛v/= ~qYD-I$&j;Ç׵"@5ݐ!0qF@.9v^Oĉ)%/frr,DfS~y@.u+3ԩ^=| ~=O/}Obr臯 ^l}Om@p jorN3"/WlԨQz֭)6"krk,Y2up@@@@@)0@LJ… c坵7_#NٯU+׳'=y!IU !eJ³k~[ ?x@9[D]{®v-*s&tw#'~[*Gvv:4s̺h۞Ip`']&Zsׯ_SܸqvOLܿ}}֋;600;s  `x$Ӱ_p$+Pbh3% U^(GN»@[4+*/,Kڭ%-_*IZ4'PuD7mOTh->6_E&w]*~XUL^=iڈ>9J}єM(+ 2P-Ν;!y>h%dEb^v-ݛJpiE֮p? @@@@|"x}a#D`DxyA =#VL"DOҮ]kѢEO?|Z3ѻ᪏qcŢ&*97 Rm;S-{bGxWI'»y=a,X n ǵQ*5yxoքd֔q~"7  `rXpfzlHmJԮDJnoΝ;G˗/W9<2^9_#hv)>9i8<}J]E=]:j[&5*:{͚Eg^[6Sĉ{5lLsNԩ)a8!"-KKpӠ( 98Ss+%=ϩ'z'miX^"ҫhhˆThӦ +WrEWJL:ݻG͛7[RҤIչ$uhiٲ%mO?Uɜ9sÇm,l/^\\A= ׮f}n0 77 @H >lnj'# Z;i+).]Jrdɒo>%ݻRHAY {$H숨ԁ6'!CCԋ ]dhE$"e6Uz ͝Gydъ˯&N Rͻo,Ij &?)v8aAڇ'~K*MIߦ- {GGELi;s@jVI)Gb1bĠRJ~x'mt)̊y؏?}Bƍ˗/ӈ#A!l2]:.Q/V~ڵ~7Na"Q9%ʷTRtmȑ#Iې4"Tw몡#ڣC7 IuF~1i+2>?@^0O|͚5SC@"x6@ B@-䟂ɓ'S"E=Mk?eqn޴nU^ 4{`Mo?aRTy3zfj0i%h/Ǝɜb5T GvTmpfpWn9//gGm R[Aɣsz'm=4ڕJ=)yrQNYnz 7`=jԨYYȑ#۷oE ^ g{os ,WK$ڶQp1r@Ț=p@PB*Tl{vs~~5qcݺ4F;.Bfhc/6fIVE׼l~Np!`s!lfo>zV5ܪgc)S:$QW,GkVfM[תU˲{"p1El@5`EsʊTf[&%:҅&r7OuV~'Kܽm_זEJ9Y͛$ y{6/%~=hW,2R&bwO꽆iҤZ-Y ӧ߈'%NX\00+󅸘u&IEɳ+u,$1cUq^;Cg3x0)W>D=c%D*/l*/T%)P흼Qr>_؞Y}͋DyWP#^FX=iQxI,FhOxDYV-}ʔ)Zʔ)ջ8uVVZC>Q+00R8  p ㏕3KW^6;~8ɂWb9rRG"w+vqҚ h1 u蠺5s H~?y#}KK|Y.[BkZر"1D'~K^5j/z/TPڎaE<ۓvaS3i6R~qO"yE^mƀtO"sϯ޽nϰ, eϞn=@oA@LJ@Z-Ro֬Yt={*װaC l=d0=xHTË2XvgZX9aړHFf~6r/s \htA"jmB>b1P<_%Jp{νaNyg[+5xtRUֹs oWXL6lڌ3&UZU;w0R8 !зo_Lnܸq('rGchU1k= iב#G˗hц?~۲E5H;}5חN3cOxf;w.I]N֬6G= iHȬm=Tg%3м'~{64}p\8\K-ehZmS6l-j'ON=zr Y\-'/4(qFh=e[LH9J    f%pq0U#Fe˖޽{=:oӦMiܹ25GJU+d+hʕi&z ټ\YDKD{6{lܴ?}dcl@,S߾}joӖ:խK+nN iY oCHrIh:a|e:X]2j)XH byX<]>FwjhŖtEz-eNj.MYӥ qG0 ~Y,5y4{ZTDwrh嶭j%m i{1Gʀmœ~z?\8r,h9uO}z5uY]ɽ?WS-[ӧU$IP޼y0d9i#I&!,5j v/_ZF5 &6"޽{p9'z|KhXaU(og}I Zrnd94Nc׆po=gDytۧҒ    J<E\;t!>|Dr~/{k^MamسG-"-9\geqEmoW @uDJN^WL/okпfܺ'#VvLJ7kU>ixO    'c [QdPL+F ]p N0vӻ;m\X7pLJXbqpz0& @@@ _ٲ[&x]Y޸\uuDd}WN*%I[C?A@@@@ T @ U8@xh֬ETTw}Vɧuw/AܸTd)Z1YDIb+S&*=FX<)ujݫG?NZV;fLs@IQ@@@@^/(t@@ $VZQ…C8ҽQcʒ6;MV*IR]ե+ō[W]WEw3u? {2;'^(RHN#tqZ*ďO>飼ӧ^    J<<˗ϡ7ͪTo;urXǛ EZNE;P55}B޲ߑ,ZԨA;+~X~/k$R{1h_{2W-Z:N)i#A@$%KF;w#FDY[\iɨ4k@HH3 8ԣISJ`qMDEiӨo֖fߎ,\H-U "ƈ+OB*Oa-\D7o>,SGf鶤ch[YJo9na;~2  '}OYcƢo4@@@@\&_6[8! eh޽Nj^۷oɓ)J5兗|W{wً"Qb޽S,#Km#7oݻ"qbObrXyz߹CQ9]Nozx3W?Гvšw)6ߣP#D)RML}mϨXR^dQÜ#NH ʨA/_TEt~`0aBPAիWt=KxW,ί`}6!  D8J& =|3 DJ®Hܾf"dKj_1/8w&IԂE^_k      A@@@J@D^k0_    aDoiA@@@"DKD$I}yC)    `Xx ;4  A@@@^/@@@@@/zIŃ8! x;>?cyA)WÇ΃"W&T>xocw@uڀ^     "L @@@@ a#7XJ    aNo#@@@@ G"p^#0 @@@@|D^{x   &!$ 7@@@@$Mph    `x0 @qu @uD^S '_!WF~8'9#0t@@@@ @!@@@@@j 2@@@^B8    & V@@@@ t @ ]8@5h0%V8    j J@@@@ @ }8#@5ۈ0 J8     )^@@@@=xV    H"/:|CkA@@@@ G"_&חGG"{ @@@@ @ u8!O 'A@@@A@@lX|9 :RHAVU%ȱ7юÇi߉t#ʒ& +\ZרA~~P:cHVGyJ:~BiQ!ʜm[w҄ґgU MZAU o,ӡ3/Jʚ6V>.\ذ~s;m?xi~RmٷXA/_H"Qw*5ߏv=ĝ'O/ E?#GRXag*jBg,YC޽\KMLia-jTvQ:uSyu*yZlI'y 98+@@Ԝ#NEuf"|hREr#ь/vlmV5g6pM[M~ 9봝rJܵSEΜ: ̑QzўNVu%JD/B~K:I-"RѐS,Y[4Jϔ>EJj[VDz~9Оܺ۲zu[<%8@JEe۷f?twd(i„v=zEWHѣEU۶ӘysiGg? sA=tRI(B7 a_zE͚5#.;@ hÆѸYJܕq_~IjױT-+7%K@ݾNE>OQhqݭ:}&~ިbQ*A^~"+ntW,OOe!yCͫV Na^N"NB;KD b1(v۪;zJEN1~o~c]2_~ʛ5 5ۗڥƼLBQE"{*G]M4n2 ^gH X6,A@;vCѢE2$rUm-jZUye;Æ{t}&NK?*]G[m=[cBTs\[5R"jInVI :LjzbD\"A]ͷlS@QW>(EJ REgh~\O 9{+/M^Ⱥ(Eyu]PЍ3J޽;+VL!C vk1  ` /9´QF$ "M6;LfX1bОs4[Wu"Kݨ7kԾ=DL64b؞s\[䗘eIKp?D1Wx:nRS}T)[9 d181N΋bۻWU"csRAw jor^M^ڸqH^"p(̢dɒA@@@LD |Ϗ9B%J^z9uuS3S=MK9fq3"*|3e6-΂vM'꫈pG5][|*[4ټX\/YtR~=ˁ@_s~^IɋU2"` ȩ꼵9ġ]hG XszğM=&$IB#y}|Ν[O301&\ f!i&;v,ٜ^ rd翾n[/k6~Mxmތ F 9GmG!7$xA_ǏUqfIm~7҆ݻiA9LQN 羫~Ǎ⃤g>ݹΑ+R4HѼa)vGZUj1p ݱkWIDNDyC( /ܦ˗}!joiєBw[<^HNR-hтܹcuԡ,p˃,{@@jY%^5y=W@xkW9N[[K3 hExHfeHʣ~ 1]'}ɋn<[&ZD}L.,o-iKZ6-¨fN"Bnc}Qb[RKhc͵ڵ.ݸAZv;x}f5{䩶PM7?[}CD^h$NS.3fL/nzj;w.}ºYf6(@$О^vUFZݓGΞr:s:ׯO 1_ty۷S>u7*>s_RU]V5ѥ~k'GG ƞp-Uõ۷i]D%JPmO`tѹo޼A?MtaqcKͺ5lH@w;k"%otRڇxS|"xn<FB2&}qFwJгgOu޽{4h@7,֦     OT .D-ZH囜6mKnbDl=;fL?o>Mѓ|)}m}ٸu~yJms׬7i}yܥY+WHAЕE#~Kʍ\үN)9G7@`Gs*eѽ-[ptdC!=!O{YN%OmY~@"C?Z4C.\!KjN0oPKpaJi dFq#U_E© 4{;m?ێSo87X}vZ- W$L 9O5jΓcڥK%     zᠡ L2Q)9s&=ȩbXԩS]YTmrG<"E:die;"Mw^qqz)-fBUmRS}xWPߨ2 1~00Ըree+l* ϽF0O._(I9˴kKqJ6gڴaD`|htyj`# SlYKj;vX$ H$^zm|:'VL}duB9%BזժUaڵk-~۪c      >)^yjLOdM6%YK[ǧwQ&MԪ2FUK8j"yWE(eQR%U Du+ORթGK$YDD1m2NCqWBX N1 aDT(gNY33Ǘ #\E$S*K8"~.N'NLGٟ7Ieɳg꘭߼Cg$lY;V{]0pD92Xj?~̙Cϧׯ%dڬD"s2V29iy,%ΟE=<[nj;EQ~"Fw0-]r4pqNOU9~HCp< no`aQU,)'9xU?mdcND 9ȟ-JԦK"(]!.BzXl Ϛeʒܿ"y?YCLѿyB)Rwo&YrKWo߻OS&߱߸v$ /}y-E9x"x5x99oȑ**)E:t(IoIS=2ƪ>3@}5/-ϨD]keRWGBe"ٳ"I7vĉ}'+'K>5^[-ڤɻD7e:T\9B~? ,UvJJ5qWw;jV"o^vDn j6}Nݸz׊P*Ul2} u\nb8\sQɶ%/ew8 :u%D<'ыݽ{vM78Gk)(W\6m V^%=VWzXE^|JD,e1xӏy?ztU8u"-eT~{hS9w?pV:r3W) ~͕~w`!G׫P!8֪xa䗨툴۴~.zQޓ<cHk@+D[W g{#4AOzM^yQ0G₿ͫT 6"wʋ,;+J3獆3CsF >G 9DSZ`\I AS Tj{ Eܲ_ؒ%K~*]O>*+2b]nQj6`%EjA" ̘$S%Y`,ktfs/?>L rI~Jxȱ׮R/-~!S~]{5 \;e2.Ӯ-|Rskъ"ϞR.t$]m`Ɨ_C8v&M@QX.`.nr ѻ76g^ LװaQy zw @@@@@3B(Y_pRm/ Ӈ+UZr@e]9'xagߧHӫ|gxz6O0AE06lؐϯ[p!䜘"*?DSg%J̕J=j[q,Qʯ^g(qW}$'s5,p/_PZ>eU(OnVup么f2\%Կ<̙9M͚4~5>dyϟW*}^ Q|ӿmB9kȏ?2f  `9,&D 0y iGZ\ջAY9lN"s/bYxF#wݎt-_ U)nh_E\ؗE-ߒNa)y`>n#Y?g̘AkyE 34J.M-[ $F>8&1,ʵn:V2Md 7,='NH,I_gζ&>ҧO),m^q4!ZF*UڷoORu%,팼е^dM h4ͫYi G,KnRo3:|;N/I!ӧ)Lh\8WKUٟ3,d"isJ}Rp&Ie/qzYXoꘈ8/oQ+FS^b ƥŋS5T$%N#cmK=jU:]dEt,} e~ TF3~U֥O>߿QwAB v@@@@"A׭h ^L@TEԕ,y4hB w4j(U.h QkVÿsQOjog8jٳgI|;v.;Yn޽nCOïZ J$'*i ޲H(QFɯ:{YrjǃljvϞCٝ<T$F$8p*8Y?'OT$kDCcoOYBneDܕϬRv&9%W" E?]{p>yL- t*J[e     sIz,l:t(IVK+$N9x5Wr2JDiҤI`:xSV[MHx*9Je! 6f\ni+N2q=%*^?-QINcV)s 0t>XHqƙm    !?ۣ9x0)ڵ+͚5KW7D+o[ȚEծ&j}7b[f1*Gst(s[woÊ;~K;NEcd1ZP Wjw>j[ԗϪ+&9;֕~.7:Z/vxss  OK4˫Kd, Q^=Keu?8ќ9sM6r{ZEe駶Еdoxn<-ŋcahN²MX9s׾= A@@@E EF3xa){&yy֭K8͛u ҳ,$WgZ#8}k.{ɓ'9Ρ$Iu<-6nܨ4eIUke vDR{ЪWE޸^^aa`ApfCоEMQ@xFXQl\J*D3Vݳ,&CbiW X1`Ż[B78Aˋ2S最6Hx 7sr&&ѣ;oJ50F0$t @ȓ'xsIʉ%Rg?V|LrXlku־}{o Y*a{,Bx>S:mdɨ2@A"9rdt]0*%WH֮uRSΓVfk1,ޅr椿J*U(Q޺N [3 ~eP 7EEڵ {~ji?7oUw϶n%/7֜M3{5Ûz   +[}0I &".+fOh#>czܵҕ'ҷA7h؈r3d~n]Pgni=oW_D:IPNb|o Mשk)]4}]4hЀ*U.*^s/rӀz"b":J@[츝@DKf͚v)"NUb X;{*+ ˰Ibvx[@SD7'ͪTCJ}᧷HƂ3iZ~T2_>3!U*\>^D2̘.\H͛?[v"J:[+E3<ʧ>{9[t?"K ݻӡ_~%yf>d)u]GE48/] jp讍1B {u.wܡWGs|r7'j0{)ɂab9'zl G*+ >=.yVK"%OvH.\$H:\qy}   f"L _@@@@@@/zI^C:    aH"oũA@@@ |@ θ D^c z   : @ @@@@@ vh @5CpN"sF   $׀.@!qQ^O-D^(09&`    .224"7     `dy<:X@ൠ@y^#     F!(#~MxmbA kA@@@@@ qT'  @@@@@ȫj@8 kR   7oдihӦMtiJ4)/^J*Ee˖uzΓ/Ҝ5t&IJGjצ7R73(EĴjx]{1MWy]uOO䥪-s4}4mr޷/Z4x[y*vr=}8G Աn]J87鳞=ӠvJRAwӗ/S҄ =^*>*[pFqo[Wlu(R.7 k>ׯӠAJ*5kmYlذ!}և    'C A@ [F :uőGƍ~i9rI)/z$zꕥKh4Y4gC$4,x2EJj?|-HS.Rt靝2]V'+چ17Eއ,7mTgT]zUuwWZ5TYjТrk֬DkժňCa?1!+H"(AܸtŃYVjE{?Ƒ}&N,9_]|h\E՜;.޳Z][RUw߹Sעj sL4},Agi+bu=ȱׯE7ew8?zt1ʌʽm];e+V贙+ |ցSgP@@@€0SxN@ۗzM"2Z'*dSrYO2%県,>-;*ڸ}N["nz  |ydqme)^PΜ$ĦsU5pD,2&~?r8+]ɳgʯ¹r/g2kD[~=:J(W;hUͺ!fLUvG+~{%x0wA]`͟?RHA?hor^M^09G/h  DiԨCϜ9CwQu*T+fK.;XΑFoLVsEմX͋t2Eߞ̑3;I`Dso_xqwX||d8AJwyvkFxQ2s |ێL}7T쨊J _1wp\W }$BTfΜIzrjo!?NW\_'^_?x)[V-TRQmmqb{۲,$qFMk4uT@IDAT=p7TL:4yyOwT7[9sḧ́I]o3w5*˞M_\IX/2wO?7.ρa}|̼u~̟ݺ}ӜEhK uX $ʲQ V =;PN$,eDc/!ݩSTUi/"]Zz5?blO@O 3sغu+9VZe3[tErRN-¶lt*wDR(T-UZհgV_5;-;0'&z"ISHDTiTT^W  4AJ ~3݆\HM.&}wߖ\;Z]3E.=4~K{) f!E<$‚!CI ¹k[Wlۦ]N%_Na6oo+^ad+QW=6G/ #s$C,{iۥKڸq#]炒{ݻsڵk{E\A@@@ @ >(Aމ'kq9*wĈT#vR~jCfLWk`qjPJ(eGZhbڵl3W--1upfYT8m=}yowQr/:NjnǪxSӤ'S1؉&A-j"IG1rl*԰7O6zܿ7D#z7)JTipD-Y-}) Gy0!nZ1XԩUQ\|ș=zX-3&GNƧG8kezi{Ͷn$E]?a:׽[9~<a"i[۰^zٲ$/ͺ4jLڴ&ySGw:oM!p?mbt#soE,JjW^yc "nݺ:7T{;:n A@@@ 7  LCQ ˖-#_%԰JK7oR)Sj&+ѷMGW._>?z>dLF5B0\Rf=F6˩'(qW-_M҅ {C'.]r>{p87[vK%R,kXO;y:IK'v*•mm→Ye_~v_??ܤIT3M=µ,'(?TKe?뷿=[;HW7]C%6Îu-/1${voQjȗ$jIc~G'J-ufvW믿(˪UpsL^zI;!q$)ӰaDtDqujTXbŊY̅pƍW"ea 98>Z׶>gN6Ntw9 M(]T\8kjk)cRDם{hѣ])EGߒYwԨA3"c}wt}}Ԡ!Gr߲5"B~STDz"qU9eDPwߵCNZr˛n_aKjɩaC8WG|~+=V={*RG,Ad0;0O9J/Rvrѽ+.F1   ABoH F '̑#:u*jՊs10[0 @,` ۴gGD<1|,Q4rf7JtkmScQuZ}}1]w׋(bӝzyat.ze7b"8x8bpyf% ՗I Dxxx.٬Y(î]hŊj/    DD%0x`y.?%Ww*wMd^AQv4+BCbFѫ }:rux#ź5i\ag9e28-BjSI"X9?$JèQ  8 ?8|I`m*7r1f-h&E [ rȼAUa\Hq.qW rʥuԉV^e \@6GF]Rt-r|P P8@@c.sN4i-ׯŋ\bק^zY\%#Fҫ͚L\p*=enN; U<3jL$+i?+ Sk2 8C7T"|58PM;3[w) ge߬m~˖}8a㊇oPf}G# "o'AR4-[V%C޼yǏ)ɓVZe0b& xe%'NTCvvJrMV3>zh%icÑS#Gh޽ץK%abEjǍ$U#l5XԦ>4޼I#SJѵ ЀVkO=YI"8"Z2g<]w(Qd@H%2u ~$FVضĸ_w۷Wל>9uh5=A菻Pʕ-mٳ4~baNr%O-Jmգ׋>7h~ߋ̒zS8v>7tbŊ*rw֬YpB:vzɊzA0E1aDIP>xHVWrݻmR%(| Ttպuk7oĎݺ+q?}B/ql28eiwC&ymz YZ]L"B.N ۇ8M1fQ<)'Y !Eiis\+9}n2MG߰_syzӤ0Ç.2kyy$HcgErQaf4֝<ڒ~$ke2]tiZ;/~w]결a &opUvd\y%s:f/bv="'r%3L 5݋#=k m49(qs">v#߬dѯvsOT G}O> LJ… ;j    rPd-9! ֜֞~< z^NOXة%v!9/SmV@K gҊiN]7I0`Tc@?hVC:w5GW}} 986퉾v:w駟NxNs0'Oc)B5Zp2kR]67m;OJ:@OA톈~ypm[˺ݘtfn8o鑁g^`fG0̜9o    sx};.RLjm3 ٮ/^z]n?xP{36}Ij # ~Ar8~&S5귤@7(C a۶mfu)$AAG ]}˰ o7n I9v2 +ssmx Û7 $~h      遅[  :z 6Kʐ8]α VO*/iSy+Ke쾖6m`p>@m(!_X]V,QP{36+_솺 ~R%ߐ7ތ+7v&O^Νیsx|$Q"C0cc~W,QҌnSƮU~    ` CwA@㏟p1*Y2z.Z5¹rQP}0~xԦ^={_2eJNw{6̕% U/[Vw7h@cެ ~rgͪ{F C5ߦ^F.;ňC׆&LH-[@@@@ T@ # ?A@  +W:u˳Sĉu5{kզj沛 X3pŌ_[9s;C44[7^(OSD깃Q\Np$jojSqڙמ͚QIlQ[ɓ)}ڢ *G ~@/^,91%ngS ^X7Pg+'gVFQԩr< !?NJ h: ,ÔORs*E?LD 03W bXsoӢauG_oVJ jb?uk޾;o?־=ŎˮeրA*vc&22  #G+Wݻ>|f̘A۶m;ׯSXTljUIT\ڎi5tqze <_z_X@M A@Zu+-{:z ?$ VD ëP,Qt:v}zڤ ٳghzZOt9QrV7˔e< ybVyGN._D|˛լI"]kr7wL'OÍkSlقm:m7n"HrSҧNw0:gvb)tD;N,{菔APɓ't^ ͛7"&g|>lڴܹs;@0LGZE1ϝط!^y?^9 #{ܕGZl7g-ym|C@z葝eKz!=~ u)&f17 n7 '|~:=NާANzdEڵ)} ݀x^oA@@@@I"9 z   `^C@@@@@ @ g@@@  @ ţA@@@@@@@ހ;d0@HA  @5B@@@k f(!z6.{so &@Xl@@@@@ @ @hZނ%W/)#~]D^ t@@@/pF"3:X   g@@\xM>6mDǏtQ2e\rTR%6:cM_ ۏK]lo={R)L\T+.yיrZ*yrʛ-*5r}5g%Kșt-z@2QX4r~=vlDCgΤ cm泻'4`T~MvnZ?tmHR] GNsQ:mȝO[0^wcyq0ݫHCO.]Dƍ~N>M2dSVp†   I l'#Gʕ+iuCڵkӱcnm۶4i$3&?tyž}R jkJ]5z ]mS|>~, ɻ=kSMKm\ڻK/V‚r\D 3p eIF/ݸq%JD $g<[:od9g:Núh޼ >=|P0aB'߶p*j؀n޹CYY:zm|~+UT#F cG6w֬tlJhFׯ^ΟQ>#v4GԣiSE~lo?Jn٢}~Ք4~|I&յFtFaԾ}{ײݺu#F.2{@V/O &Fn0n޼I=R SHAZ5/Ν;W~@@g3QVZ*j7YdԿ+?DWZEGSWK.uRΝ.Wa;Q-5$7iԿe+-I>U?D+۴tz6v"m^+R4jLfoJuڻEg̴+Q0XOX˜.=;{}rЦ5}?q"*d7O=4"68g֟==^Pݏ+͓ǡ+"p<{?}_fլI`kWɓkxʟ#;z9Ӹ߹2g̞0P,}Ԕ/Lg$aSz饗hȐ!TX5Jjٳg֭[{]l@@@   D'p֭[GKx ȏ6mвeTo\,˭'}>?_EZ/3"JDjB=CFj;|-"^͖˗#3%RRKD,h1h>t&/_F4Ts4m1 ˖5cYIRޥSB##zIq_/b5|q u{|9iG-+"~LhW) Gދ Ꜻ&gkwd!u">SLnxSy~]гgO%C]vwu|(<<*WDޮ]Rf(nܸ   Pd-:\@!E֩S'?X~6; {p<GD3-ݸAuNŊQ]rTsȡY%_SY,6nj`YͷYewlF#|GqMl,߶>DDoNPB0E:Y"N317H]2p&j>}}S֘<ۙnUwi3[w5jYh]a{y +&&$=߭c@@@  78@! \߾}Տ *D&IDB= WmEmɏުA8YMW$/mN<ۺRtq>sЁp^eIaFxI'"R4h@1wyǖP{TZzQz[vo=u.(H*(Im[rɫm$#EL j&y`a   Ko{x & "fƍ x^3@@@O9֭sQVtl7G9txv+ ǑI#G 8jfziI1i߫x^3S=Ua=IE1w z 9^Z5IU 59O.UO%D[]+/߸rJgɫA[J)$%[p,LᓞN6>L3V}lڌ Ifu7툼v;QFJ >\ËM6р]{@@kgϦ#,NJѵgkV \R! qN?1{tiZ9wR Ͽ?}ڏġSHܖ>{+hѣi:˱Y EZՉx0`4R葼9G u1D(>\̻8VnD 䬎$}!ڕ9n3OPCsZߎ8t HR|v wmgEM"hтCSN\$DTRyg*>!v.2:jԨ(.H~^ f۲O1IW!B'6OT^AӿK׮Y͖2ImlV3w[bZ5y&/튷u02Ӓ3GV(QʼnK{Oy1~0|Fʞ!\GA~$^-XQҧJMO˗}ڛҦL1;뷽\zn߮I<29yL$UâEܹs#r6XB(GOj*6e*Rf+,,]רڛ4];\D|ù,b->]y$Dqߺw~zzU{)2r1a܌-fͤ4nD }sbǏ9 &%9CEv맽1o`Ηh=R&Mٲ!EHZ+ AZCz͓uN:KF$ɹ,))*MTe,jy'Gxh&",ŋIҒH*#FPx^h&4F<;^h3#gH1" ;jw9sfz_d ӯPNRuI}Jbk8^R͚MK͚t8u<ϑ2s׬O٢b4!{~Kd=.99ϰC&[ҤIm72Q w)ktR+(Lݛ>s5koҤ}dHܵg2V"d t ?rnMMzS0RDP+O#sZ7{N\ǹu sZ1Ӵ~KO,n$OjfW-Iar$;KhC7oEy?wZMnSG=ߝ¸fR@Α={jq ';~;Wqzrʕڽ_&_58ZIg$7f2==Nw'71<$pΆ Kn؎;qWL"ݤػWQ,Qw$CE"b&U;W"{0RU}XIMzznBu~ǯiO:2lL5_Αm뙞wסߵI*RN˴'^v5X)ߏ|rEϗυU~^-5CVi@֦l4z^N;98*[]|)eN GDllwF~*y2>mּJO^~rO֟&E4%CTB"sI/rk׮eOQ8qhĉԚsO1fb"Lғ̺ͅr fn0$Qȋ|ϣ |eRAlܹ% >#>CC@~VTvJsj%K=z">#U^JM>ȡz>gOV_Do޻, Ufͤy|y@w9εɗ_LBu*V'N"9}ApQZ zAȔVDKRWwrgJV^;=^PNO8Zu%eی DN!)e>"=ժPtH-f`v}%v^jv͞C͛Mڰk3%?ڸ1}À?}jhb"z}eҨ1] 挈7v:tݫ)j~hZ][K6=Go[]dώ^{j7moٲў FԵ[eLX?ab> յ q/v]fxm;)E4%Zwm]fi߾fn/:ƹA5 k14B0#yw9AԌ~iWMǣbmhR$WqQ{v+G#Gweej$L:S(c=z|=MMFY@W?%-òu`Fn٢K&.YB776ab]lW^*%@(JG@|zZ. uN9W\mfmxMH?vTެ~9tHۿ7ҝ{67m;-Yfo3wjk\߷zݬo٫{|]/[c=xH`݆Ct%ҹ9QHo{3 ~A;!Nfllo)D(3݌ޣr2+I@{ .jy^lzh     1  >}qF}!!}>8;owYw m Z](v#|6~/˩K`    `^{T0@@ĉCҥ3Li7q5Θ6=ߙҹBoj̘1),uj/ o}/!{5$OAR҈eʔHs!xC`U6ժU3R^3ތS$MJ,hkUK6ތKO)%ݵرb%_ެ _-E1bݽ iP/noֆFrŊQ~Gm#>nh燏ѵ,{<]A# 7(#$н{w===cFjn\w+,I% ެ c`۽׺n=C MzK^{6mfHֽa7,_8.\X^\7ꇆMW'9zLb|z K@IDATǍQqu3MZښQ!F*U   '~s-8#P1c8k%Aq9C0X m.]I*0e@i bVW_u¹rȎ] _~ ͖ewzujߠv`!JGvW>/K Swԫ̔eaa4>.+a)ID.B׋O[pb{ԟ/Ӿb~Ք"٪N]c?H}Nkϲ)S 5-3Q{8 y9O9k6Gbh!FI+Wݻw Cݼy,YB?ݹt[[e_'r8~>~L"([*?ҍ7(G%H P;{mHGNreLu*Vߧ}%d1Y^݇7?mSϓD3̙ީg=ǃH^8\onaWu/hݎK)r%JXj} <6SO[ _"W+wĉ#._[+6HPڔ)~VjWhhޟ4@Q9K7l=G=F2qj_#OlV2Q {0ǣ^RL6}6X     ȁB7A@@8ƙa )~O/-[)Yd… iJ4iŊKWN<ŏfjwG6Lkc  / |JܭSuղŋD6k֌>Lk׮~۲لbJ!C8ke   D"o0M  Dz*={Ve˖/4]tTjU5_"}&"Ǯ^bh  AD@Dދ!  M}= <|$rW %Mno'O߼yr{357O<c@@$oa  B G K,Q2@͕+/{9sF͗uvIǎS"rΜ9Xb  "/LE/A@@k f@`8pٳGuL2:-)D7.uܙN:e RNFQ~x\J XeL/^<%jz8n8q`؁pH7jo}GTR hL"qõ-h /N-` XXi3erZ9䞆O}'Ҿ?#C'<'z  ~gAp .R)$I$Z$MrAGc0:uEjyؿ?m]ݮ\/'Ka9%qǏO $xS |>T˅,7 $w>MLADMi" 3kpTKguJƣ{b<9&ר/{e2LK%;W"^P>A@ V/RE=TT )h1D   |.\$y7-<Nx+ #tR0aߧ֭[6n8:<խ[WصVfjo1;~@D']vYΝ;S=rT 6e(Q~M 2 H"@@@ T@ # ?A@?>@p AzTjUU̞R: T^̙3S2e,6vA7oV/Bi.\QFoeɒŲ?'$9sh֭c9`|ؚsiS<lץlFw(|}ȑ:.ܬfKsFo{d*]v-Z<$Nԥ`Vs{k Y=iOO\_>)JӧӦMTtҩGʕ+Gjʕݾ}dԑ˧֯Y&0bpц a @@$/^L&M3k,K6,dI4pl/Rmڵj^R(w$"JEҰaTѐ(+ Xr%޽Z/6BmM4QTG^-Eb;Goߡ)RPqci4A%T:Rum?[YBTvfӝ8ѵkצcǎJ}n۶Q_~jԨTn@懟˗]Z5)("k[Y|Ydiܹsu@@  7  z~w8ݣG 3c AR6%HZj"nqԩ #oE@ٳ'UPAUE_iȐ!tE,tJD9[0`Ҩ1Κ._A+7oi+VO{R^hu.֍tB_8ACI$r>StMXX6s',eN=CJEUhӚ8J*l_=^LCS?\h<0yYs?)2݌:9x~5@$F._wXI>ˢ#>)S(Uy+{ XdIݛcaG$ST#w-9ꅡsVK-XT;^G#GI_X,7_GTlYZ3v\ueKX nNY0K'~Gq2{w1D33Fzw?S8$"{߂|"xuRZn_rWW"_t_/Qrb*4^9&S̝s%H8<` we9UTI^޿9ulR5-Dܕ\y`7ޔ:msΊA~m'NAܫ]?1HG\g&)ȴ:u :"JW1{^}?y>{_FX2O"U[#d_0$xh  BDw(^yaI$f' KqU!ij_x/9Y dh=L{sl&E4;ryeH.]CÆޓsB1[z<ևO֯briJ޶MS%z)s@cgzt}~6ore:vB=k::J|roݗ͜EHUEsF7'O~)=X2Rt[iNxzmk3R_K*me6^@䕇}U)Dȵg+yt$IX/LI &`   D@@H@fJ4$fٳg&{wXjY`3! rh3X.8re$3-m.#aW޶d)%GCpw~[_1\͚CSf5O>y9n-$~;O&9o-}w<>ǥ`ȇ9^u*I!Bj&"`8={9,_6Ot XnvNðz5k[[W$gyQSG3'`   xq@\ufZ+…$?$QYG{slƪobW!w_D}P-n?->~0LnWZ5c(eg[+&䝭Ǵ~5[JYd}jUg2wOɫ-'^cmٿvpI-8ma~َ:=a2\;;ke݈ j 5SËM{vӀiS_u+VT9ݽ&ȧ+i'<9 >5;"KT)*&QYby3ªbR    @hʕʃN:Q<λ$_eQ#8$iTyݕ"t|ys,޹A?m (yO%OOٓZՉjfY .#9H,taǏM=aѯ:Z]\u^^+7oyNrte~hڵQ6v6~~ڇDFihvǎ+֥Qc.QSwwjo*Awd9rN#9wEߪ5kҴ>똳k;Hl!L=h%p޺{W\/s!;{l'ݺu$QKVZ.^w8u+7Udڕ[s   @a 9ϬXԭGZ,>~[e?oGz5#?J8pu3O{?P%S5YdF]F3HN2-ӧ-ZЏڛe7=׶DObw4dté'Ws׬ncǪƏ ADusϟ?FAӦM5k֨h^mSZN id$fr@@@ u@@ ȏA"gq΂B"ݵ \J9-?lJZ<U&<:/))($lϼԾA k|Mu^{GGϜQnQS7wﯸZKҏSFwJ=z"gm^I=ϫ,Z>V)I1_uD.mmK7lP9:oNum[<qW"-]#>"?k}לԭfl뽶~էe~@.2%-:u`TTL⢤,{bnTcգGj߾=I|=J 7nPUӫu%*יiHvB'm@@@ @ _@@ LevtH}J?=&) ʷjERILDN !2ܼ6G񖯦S…Bzӵ+Iz/9٬wL,=cج>^lKH4\;tz7#g,ݯĶ_nJvGΜLiˆ=b@ bFrB-׷;WE~쯛0o"*jr*̍=^EҖͰaM)Qj "d樸㜋2G̙͌^ҥ=Cda5!y85z?ysL۶GNfK@1~gX޼*=?%6s:ϵc'vd#8S:r CyeqRSuӘt Z$W|4om\0T,-쀁@9  `r2y4o<7xVpdWIکK2\}Np={@pcГkqRU>)[Uf:W5'Ojv%WQD;~ߺ{;JWoޢ׋UCs.K3;j\<t#RtJ,ɢυKLͺ*.6gw%{udͻw(qx`εm`^]KQ63qn:mӷ"yg[[S&O{}JdnQkbReNnr*3;׶[FOXp*ƍ{/Q۸hXbԻܺw7b'\Rيxȱ)SPүY/lUH2Iq"3~w*HrvG?>K[*]R\M}C۸o_ZK_-ȐӧHvq|\nZR8~#7sdȔݏԫG3V}R4ߏD,~reKD)RM  < E@J"5.$K .sx?{g/Etwwwww*Ht7ҝ%$%EAͲ<6f̼|ݙ;w=܅~Q8Z,6MjijNy3o?ũ%1GXw>}/t?#ẦMo 0NP*o>GRNc eP o̊D-[ѠVB<)FtMz=xZ(1ZȼT*:w*}޳cSIҏK92š-Z>OPL^!%sㄉjq|$=X͚5i?$! ^Iv9fH[ (@UE+F[lH&meN#(OH2vnI")8b};81i[xz  `lC~yկ_?_+!cwTzS5SGw"$pD9ʟyA%‰YM45m;*iZ=%R\}G.ܔ'vM1!ST{'GjW(Ok}M̧wP:2]L5h@}5W{>];Dme@C3G7 ~9\$mЖ<( QX "zl,{)V4No<ڠrlftjL$9B6EHN}˗y^ޗkor+&"jIR<0h6h'^D@@ P4Wo#Nsny^LnX0}BP$ErU6y\.$]~CBS Li^Ww[+,S~5eD۹ IT[PZ`Em0c8sɈ՘;c&BEhk+O&esym1YLpɔ/K:u"jyQ,l[#,>E itU_KDwԴ~w> _[Uܮt;o?̃z9U΍ou+VB[PʾfosVaae0+~-oFEt;F~KpIaČ~eA@@. ڥ'2^YW ~nQ1A}f}yomWP7z2mH/ ޛ/>> c_4yBGޠj/kB;A@#.\8J+4I)nʲ&i&3*1O/7zs3|`o֞vǎMQ#Gz߾\iҤ@@@ 4{ T^ݐK2TތEBe7ԴK*o9ҧn'F9< V(TDkS>媕(it:ƌޣ*eF7 zIc]i}}R!Vv;9sęo̭\(  @l@GO=/K?elEa„u*~V7wH6ٸ8ݕc1bPuqF+ "}Z3P6EK]e^fٲ5mZ]͌5*u@WYTk]F~p:gd F9 2}!;t@ $0Oh 4!8?%KFK,!dƥF-z Ic;wz޻rV)^[X1۴rV) hdj+os΀IĔ=)wL^BIjX+J򲑣(A8Ye d3"yVrǎ-}#b̾~6ϺCZ;jԫI,HFZ@@@ *4O?oNY8BוŔ*IW-[Æ,$D6VvϙK1E`7|ӯ}ݵIT}556]fz-bֆSˆXp0#V4W/ؽĉ̛6Z3yD=uۚ|.3U!eJu*9\Yth$vs+֗ʗ/\;*lq'LtU|y7I^;iVMej spx    @\l&Yz5߿?@=]v֭[+8j4V4eNZo,'+ocƇNϟH*.BP #:* .]ѓ'i:v,O-JqD>V;={4!zS76N_ެiR…Ir3[>}J_JׯsH7sfAyw=ӧ針;I=&֔.®&?M9By|T|ǛͻwT*I0yf?w._NΝSYh\ThJ/R+Gr iݚ>)^S/i73 vְr!]`94{4*_\~VlJNxΚ&-u[2*wШE(L0]ʗ% թ`{7~6MZWPeIZ~VrO\5'^p::|vR$JDs妶5k3߼yC~>x>yBS,Pڵ)I|ϟC?I~K{}9ujVD UO+"/$LĆN?~g:Rz>}?;zE9k>G  `k_f͚qs"EzLH-#9~=|YC3Wfc? C)RĈ^O9`t?0処f9C~ĉCY Ν)˴Fv3ijם\16#~} YR4!gً^}ڼw׏l?mG=7vezŃ4,6/>5`^ѣxFhd.>yogĥKﴩ$9[{/[519{:rAR42=JrUb%I? ]<{F]vW)VM(*[+*Lե3Ze#)Jtlꧾ} LQ߿psո+y8ۤD+߮Y):Gb¡JѢz5SOnʴF?qG_B jy6PD4a#L-m5ywŋGXЕ4;brO+_kV'B~33޾vA88 V#(ǎ{{!-)\cwei7y2evK^*kYi{̦;,J=G9%:^$o׎pٕo }C۷wex7ɓ'IrZjQUto* ٮ~qO@@B5C58  `O>nݺQ"Eԏ"Iː&Mр2LCu>Ijꇳly3HӦGp(uҤ^%=ʍQ#Gfի[X4-AEAW]5="2mv ߇8/4C$ZD[UnxRwc%h+Lߞ|\2A1s"5I| bO'Qf2_ےVKG1w~܅bst;whޏ?M{4XgqWk`Hi8bSe_nU8]ؘѢӴ^݇qv!6mڤv5mgqW+/QÇW/o k_h@@ tރ L0OYdTxq> (*Owo ,Df&dE/\HsDunԡN|P&[cC~o͛i馍\<ѧݦ{r}ymEəA7 *͋K" hђ~m~R@:$"o҆(n\=[_sG%*6_Ds:% &B5a8yp O|}oKZ1+џL兲gWU`&AXlYݞ_BLU^h+8ľ_~}}ἶjnD^l (IYx}ՇGM)Bw{0=@_Rǎ)2GY"i eA1LRGwϮ oϭ[L2| B"nwdt y0&Grz2Hr}G  @LO@rI苉$Qq?˻ws(ƹ4e*k`DAO[V1wQu>_  D&Y*.BM슋~k ImZ&jjw$D֭XiC|DaWW3vq~兌bGA"v7)%TUoO藛5]ͥ9ahߑ#oնB\Ҹ /ʜ=mIY^y>mQX̓lܨV̓K9Wg/^Щ{M65?sfWSݺ^Z݁ߵʖoLSHrW#I[@ONEʔ2mۨW/8?m)B<'G*j&iY\]ʈ#n:ui4%Α9ouYl:.Zr搇GO~;8/-X{L؜))ܹocVlJM &TOʹN}1eH.ݸNkwR3>֕z5n9˱"ɽ>z_zzEc[ T-ڰzO"-j?o]g_Dݧ~ AMrgA'|ʀĢ(/Eʽ̓/X,*/$%MHv&E6Wvg4lP{ߢE(I$~Ml}烂 7OwII%lE"Ph/Y^ypPqNizS&tmNVqtlP1DL%ױs鮯$Ϭf"nڅ‡ mRYXթ5zӦMTpar}Gw&, $HDpuuP?783ZeK+nKXD4ϋeHRU9aɒ:ټwM]"sD9!(XDo-MZݒ%Hp3^T˿Q;xn'_[ G' iG'pDk{!`8[sO=_fAײj0RoݻG)m1a)WEhf33/T\fͦ.]iDh=&V/\{m:!I`לrϜ9>~q71 8܈kKxb梑   `srtuuhS]C V`Ae*o{Ƒa9꾍Fvz5rdwEm]G8K[2wY$IK-J;K4XjDhCCʁ/Ed_fGWe?fUVtAWKGGyj//64?ϒ'LD8?)˗&Mvy/YRnȓTv3!rʢxs pNŹ"vC eϮ=y׹K{w%b`2=]Ζ6]rG?9kWg @2xW\9GD˗A$ it]jsOrL$%ZU맼Z//@^@4JȦpQ"o;垕DغcdLc7jDMv6_i,jr2Ke7ߨZǎoncÃ8B  Ao`PD   pE89{MX?O& 2Jv N%[$Z\R%IU Ωb=1>ydAq$׿>Er*#C0cM9_gY1|p%*Wr|cma?o̊D-[Q  !RZ?q.ݸƓE졮kEɕ1#I~)Gi;> 6I%2u# 8^,N=PHJqm)9Gt#}CJ7MՋjM7ܡRk f˦Г=z2 f.^Tْw89/(7o`*ݦ5|6kʋ%R &, -wz ]ځqJ7l3^1dj:xz_F_~i%%'܆HիiKd5آ\fd }K7o2w.](GJ A`m8N  `xmӕp@B/'NPΝindAN(BIT۴lKR߭Gq>2Ͽ߱OH\y ƥ,{bwiȬYJr)=.ɲ-?,A["DѮeE6g6MX!Vk3~TLb܍~c(3:.Kɭ 4N=puzݹ]\݊)|ذ-=yB2A3YdP<*J>NүU ֫XN_L9'E~˟X)i@bAĝȵkl $" sqr wgYtbLS LiE֢U#c;$V[ըA3X&;3UM/L5<ȱ`U`pT 3fRѮʇ'qY'Tc"R+~.9,E( %{L⏫&$_qgǠӦQ,YNE|0HIibO/.lM2=d@+V0mɑ9; yfƥ7.Yr5+C|1.W1RV뙾;G*ײP_ѕ7(GJ~ВbZ|" ͺ̜AX?6l2V) >XlH'=1/*`:% FoƉ@@ tW~˴[<כcNVejކ HYh" dVxuǾ) $8s]l>4_ܫ,2Gl{9<c%[(jkm\Ey`&)8֪E pj{ {5~?,{*Uh! * NW"Ku'hXvԯyr;xB͆ uΕs?mGk^O f xþfmUƏK(?K;^j}3S+~ɴ~`LDuWB3)fBrD]FWxaJC,,!]gtzcEݧqY9[e:{mֿIܶP-o`*,h`rid<R,=a{ӱ@f1zCKo{x & iNqF#&9nCFW`}O^5/>#i^ܵV7~r}Q?NzOlF\΃t/筫䪎v{EH,  %r  'mQ'+8aX3m ~{j/\cmvۨ6xk̨V6v_;   `gxܻ @lL@VϘ1!eu[D(RܰS4Δ*cv/>|~2ԤXx cF߫\;0Ԧ1c1ׇll/>"0K^R(  `:xq#V\9#MY6RĈTD m 6,}Zf-(@u7/A8T"OnZl+zt+=;%KPwyQ ^t ׺=hy1GrvYϤ˔]Y ƏJͫyѢD .oւs䠤 n `c`   ozkD9&]vDѪ>)^Σ iӚx#jgz Uiݩ3hמ‡ Y Fny"ꨟJCPdɩuu=j4eK]e^b"T&~]L0uSGWYN,fə, k֜$\5VI|վ=93E -}@ձbcƌq<CJ(  `JbŢkRld8fXjL^<|EYXq١|Xt쩈שn=j^Y@Ǻuŧyl{e{ bu x[:E&XJ;jW!/~0Dܶ̄'P8q=>E Z1z)+ ѹrX)Vϝ屌vʞf5JSF_X5mmP lc9gOƂ> @@kʂ@8ǐְ!2w.ŎtmHd 9sI*ѮkǏpmcI_7~$hn'v>oտ??elѦ)S}m{Dsj}ۍа\F94=SbŴCl(S_G˖S lD_u*T@ 65ko { v-,H/p9! lE[Ϡ^D`A q}\y;̲ATI| `|?k]`?6'acT@@@FիW}9ܧc\B?=:FB({Dyr%:|$=}R&NLsd7wRT*B:Eϝ7SP,Y-ɓ'3-QX0ߏM/]>GYӤiǩO>%W?$W^|ȕ@(4Q%ݻ?c4r S",& h_G*"5:M_i2B{_Ǐӣ'O)yT$GNగ/_Çթ쐘1ci9>~izJQ kV~,pA e;Ib ßv{s"&3"Ec  +WX:@@ T|*UX aw%_6E׌,f>DZ`A"YK˧mʉ]1⁡Ŋmh1I0I(1_h̩S&3?~_FeG׭  3h " "/5\T  "^ o@@@@@@B"]z~@xQ9Dá  :@  /A@@@@@J"U{`!7X0$       y @w;k   *NT      AH"oE  `Mxoh5@h%7< Ă       `byM9h/g!7p88@4@@@@@@ ;[xq% @r  `x@Ӄ@rqf<y%j kBSA@@@@@@#`'ؑ^;*| ޾ Pp@@@@@@ ں{8LA@@@@@@. ڥ'x$# kCA@@8XD^kZ  : @ @@@@@@@ ZpF7B      v @@x?@       `Symڱp @ 4{>yC_c[ks       D^P @I5 0~8@LBI:`'7ؑ   6Q      V"J ~@@@@@@@ :؉@8;9_@@@@ܺ{jjMi' ʛ7oh?χS/'O(}%uj_6%ߖ?w._NΝSYh\ThJϞ>W_=zЕ[hHIYz_vCPReʑ>rV*p5Zu+=|k>N3CF\eLJxlU~',Yⱌd:*l+nBr{eNZ‡ oi5^|]~>q_F)%rSۚ5)nXT*I]Iv8@s֬S0auP4gNti 6l/"/%L:i4g*_n޼IJT|۰acQ@B+7ؔׯ+8u"E٦^qj4`$n޻G>|GМkhxvԳqY__/^d_|m޻ޭӧ7mۿ=GNlVҲ#){&.]J}M/_:\9q>$͆طH#ztCӢ+w1RlYZ2|EA""nl2dϞ=3DŬY3:~8Eб(  @lF%Pر#mWy;=ݻ)2BO(FԨ穓4e^LnjረT=";g^M#U0*D_6lH&hȬYשSTu+yRmLΑ} Ywgqctrۗ}ID\3R-|U"Q=e2eIQQ&Gx޺wO˖6jp%JfZ^J5rdں77jO"-Vmc:c rxU"Y„4eKʗ9L}Zz򑣨frj2^QAiGf^';fիS )bϻ ȪmӧqT="?VFf?h=( @lH~MK$LbnL ?7j9tuf O8Uu'9| \%2lH ?/P oPM6J"$J]ݴɒѮYu4ivŊOt[R =G^] :a#O-WNzvQmϙ!{{6K֯ys~>vA881s9EADZc^bDf9w;zqc\ K48ϝ{2PT:_~ }b@}Ӹqޛe}=GeqXd83  `"O9[nTH%F))8ϝmӞ=ʽU'j>GD,tԎ7㣤"x?FwA%M"ĶDF+_Dm;+>n>'b^xY>jE|g)ޒ_[L"֯pJ䚮ݻ7/9}v~oG}r+T|sv0ŋM!jIߎ܅bswмvYgԍ#Ȁ3FR'M9:_xd0 3^hQUϴZ_#=/=Z}f=N]Iː`  @5 A@LF`„ $(sj1Br,S4 d{UYӼ,yyn2%ݨC:Xѣ+7%oǏ/ۼnȋţ},cOP$b_CycM\Nu6lDqڥ1bH!fohNw=~67Tu~V-5ɝUc瑈E|V˽Pʯ,U/K/\Hsꃖ EHW*E-m;)udbkD/p#`FPO@~D%HKjQ8?-~ts6~LRhFGV֬"v6>tH=|qlUOzANyg5x+4u$/c)ۚeaXBhQL &G/\mIU*7ܮ3OΜA_`(~jobcbRRi[+gD>%HGD=/#mk֢v6-EDVYd,1 a)'/ԉxX|J|$&;c&|#/V}bFFZ]-h%|mkg]ctgH.P3Η4Xfj6T)i)kZ?4,FԷtqw.5 `8~7-˗xb=,/6 f]y%6OW"wymA@ @o(x   `?"Vԑ<{FѣF%G8~ [l&KNWoEgvҟK.]UDHZY`_s*+7]~FuH*Ur"ej,Tg%t;V(c'rI:uwt{\ʖNTVj~-e]i!yL%=GTkW},G"wki(d>sYDO[z0 3?{J}4U gׂu?Rgأ'o#[#EFz_u-xO͛w8'."y 8;}@@@JjI()SfY4\6ԙZըA[.kdZ+`='ORۯYsk4:ZY|b !!A6̕+/$Y&f`5v3?0&wb{Bl’%Qmֱy|Z}aHlڊ?wJ`W%KqJ;^;?Qsgdo,?7^qz)nR]LR7"ܶͱO$DK4`-T1[m3f:R -fe==iݲ;{~Z6 ]a;+hV8g`T~4o2R$Jx'PM"/XPH5Y:_u}/e%Ob0j 1پF]qݱ9]V|4;ݺ }mQ1b-gZTQUGNqYtgDrű𚻲V.s93dQ۴E>(` Ŭ ڜpgg\bqbxq t3!ʢbs p;ۂ}SW\|yÕ0(&Y2ˋ<]ٝ=ywvlܘ**MVK+nUl6=oG*W%0AE͝)-WUxA-'2;E<*kmyX5; ÞgOα{_RHH˖1e\FOYj&Mvy/?"\xC_c;? Fjբ<y*W^4rH*7=[{yIS/_N{Q8q˩z2-[hG5 $T\a|YU/m7<&uAZGcPt#nCWIN%Çs*fv]ᨨuޗkͿo|ƈVpkތ:Tk3LIk6ʉȵ|(gX\s>|?i;>3{7n7ǜpr&JGY?zߓ+/ߑDn&XA‹$v1Ew/|+ڬ)$I-s-/x ]w֍"ʽ\R^DoI )~^q%n$q$/ $M|+VYĒ@ P^:E{> @@ `  'Oq79O:u*EM1M̫KϞ=[X+ӧ:D8Vz.Jt6,{bŊ9lC\64w >>?tUvw|*s'l#Y"?(9yo8ӿm⁙f^^K/P- ݼ{#"8ЧIʔ*{ۭ"+&XHԱY$R'-윭p|/hʃqbƠQz5}>YiTZ$}V}y&dt ɽ\v$7Jλ,\3gNL׮M9╅E5\$zfu<3*8z]-Z"rM<fth鷖wS%I|KIKxق >woNڢE 8g:僁#W'! _z%uX?hLo+^.Qz/,Vs=Cʕ+ɂnyŋԘKnJO&BQ,z)3UEa{j8l9bs|O֯Ƃ]LÇ -ݴk9h⭖S0~)v0{<{%ҳeS`wX׷Kٿf^9clG).\F_8_ʛ}i/~;zzp:)ؘ h/#베%FS'M8x=Ф$o_֐paÆT[awx3B 1E*JZue)RP%ԎLR!6lXYrdJs=vN3mCg]V`@D t$zm/&S|n_xe7˚,:G6Gafo9^W?{JylҲoy#y[ x ϝ6*Or$;ؐYS ; dȌIáԵ9V3/z=o7n8 @=<9ݙZ/ZP;:sD:oܸAG<U|k֬1tjr.7cV;ym#E.uy=DիW^˅D?92_szM۵-C$R3Y=0a(ZQ<t-~ Y?B1zz*+~ڷnq4k5۶jڝ;Ӧ1ca΍ZLȌ u&o/xU[R4io3\~T$snYo4_J)o~Sl4,[I,ȚU!,'׬_պ7(L X @H{>؆`+3mjux=)zͫ^Ou8s{ya0z9èszD|'[=xʝ_ZtFwwMۙ4wt?fSJ|zG/AeR ^xvΈ]6Ra{;ׇ{9J]kFeo޻yzWTGsfzqOD0i#Fd"#ί"կp~ŨETMV;Fݦ`ìRYD w$@@k`#7n\u~i< iox8}sm:iӦi|𸕧iYT *˖-:})y h GI! DH}2X`V 4@6\Ϟ=sL JnȤH[\ոIOQTŋ,fOus~k1+tZtiڡ3WgdɒA&9GXTʗ/oHR %!WD -˓[NݻCDv  o̾I&4c ʹ=M6"Jyo9[9ݰ`F諯Uܟׯd8%GiPqzWNV &}-?]PHi{j RʠQΑDΒ%.gQΝպzZvm5/ej8@*a*=vJZ1V"7X>M[ۻ(㿄ЂQ!$ؠXB}Cb*bO j ET[J롧R+r"RkSQ@!"`P ?nfg'<{q;wl7u.|ֽ+ь:_ڏ6>i$IJm;O=h7gu YhgqICW+H% t՚pUt]5SH<`M;;h ъn T||\qP#~x #~i<]y׻&O쪙::}ĉR @& h^9w@رö]֭3nGzh0Dӆ k|ҶmbO}6lhiӦ9UUCw /FUߜ?ώ?utN#tꫯ.?{DZ9zԇ=Z+PGױza_7;VI;w\رc{%/c?t;o:6[G,?裎uTwXvKHcQ~S[z)**2Ӌ/fJxtSஞӂré! .Y֋@@6z[&66߿_>CڹIVkҥ&p̢ELV.]| %pBE^^^Tך5k&cǎ5& F-:j{ٲe&#ucqqq]d=?撿ʇE&D/j͚5KvkN?njYx9#=𾰰ۧO}voFyEa ZQz1#v>}=] z,~'!^ Te, n͛7СCHgMIsK,13fD5Ef4D=z!CZ`(9%IgּӧOO*p UҹV\iQ:3 ѣvVOQ5I:-GII .kںuTTT@X>d/z ނh$:jvtDtnb3^䜟n,tp} WGͺ\G3?u?Om=uM_@uy^Hvu}8[t.;/U^^&;&բޥ[ӈ|m~R/9xXA۶m3^[&y[l1>t[c]m u&ouFɆ@\r%һwoy뭷I;w4?ƌSms̑7^#t4ѿٛ    }D @s+x[v@ѥKo|A^To۞5:nB@@@H޴r@ z۪֭]Vm\F@@@@ "     A|6    $#@7=E@@@@2(@7l@@@@HF 'Y@'2ԩS:ujYYYUy,`adZ^g, W /gRLpq~oaYjin2 /gLgGnݺE6 @`fW@[ݻwi;&ׯ7lР\zu}?oBr'ݻW\i޼%]M؟|ش[3=H  Mސ5     `@F(      Y     ag     @x7d      @Fr2U6 K/RVX!$;O.riݺdee\CjlٲE;&]vרQ ѣGeժUk.)++\Ϳ ]VN8wQ=ڷo` |s]vqNUqNFڌuɑ#G\_swMJױfޓB9S::vB@'Y*OJ3@B&0go~#|L2qD7(;vlܸ1n ]F!L>]4:9r}ٱEq?:tH\ 4[TTX v??X^lܹҬY3N '#x}h6 tb6m{wȕW^)w6e˖ѣgz깢 .m6袋dfܿoy7䡇'xBjWR0>#?~G@?p =H) cg@xi? @:a̙g馛zYPP Ç5kֈ"A97_7]A#N;4nٲM/u:SL1[oU~UK.wɆ dQaUE7V D/L4ɦYa_WҶmۤ8%؅9Ǐxj^\;uQ*zJ`…2c ыRO^#~!k~c?Oٿq}/sx&Oo tܵ̈'~z+׀ ۷O>KU965o\cudBc׭X8ꕔnժUҝ朖4aV7%\"FrT7LEO< zaJ={LخT0a'LvE `teuwW+`NIoM:wxb>T믿ۯ_?93m{٤I׶. j%`:E۩eec_9Ŋ9>Q/fgg˘1cl[G*x ߻zajq966T/t O;f#Aشi^Qno TTTȎ;cǎt䮎KֶonWL^tGN`EGܤ'NcR2::^h撮l:d-]\xsuuG8b:u~`حv  ].z#G86,'kw{a|F @7{> FK6n8ntJ6DZ5ӮO-O^V^-:J\S=\uP| 7 9r9rAӟTXA2=ϟ/:jd֭yc'GD:^A zTVNv*mJZg @? ޢ @H>lz|$"k}n:Vi}R#<-"W\q[} ^O^z--vo~H) nL@;v*!dTzZyyyvhL>#Qr>k[n֗h{S`ٲeČ`̙3S>VGq }@ KzXݻC|Wiv* |fj0`@lq>MFYgq~rΚ|/, C`$X@ =ȟyԩQ+냩* /1ʢʬsέѫSL1wIڷo+S$ c>}:]GÇGA;t4,}pۯkS_Zje \tE}ɓ'G]:u̞=[VZ%ח(58Ej>V?7kosZ2nlڞj0<|3 xQ`Ȑ!vZ)..[˗/7_}`LΝ駟?ou&7*ק[z-5j 7ǩܹscƌϛ -tդ'v= K/TUXӑ ꫯ/ֈt=n^._@GO4L*u5kȦM̜?X"[*s̑7zae * K+MKdYiֺy @mOw*Xᓧ fa8(**'ǶmLkֿ]wU֏7{Vi+eD%WkTo}[\@)45iDnf+Xݽ6mȬY̔  t~p=&}IVp---5^YA@:ڶ#S:G"*o ;5@ȜE:\`F%ӷk.r&:EV@3zWGeh¶)?t i׮q]BpΕ;CE@x=sh     $C֜t(C@@@@<,@;!    Nxt(C@@@@<,@;!    Nxt(C@@@@<,@;!    Nxt(C@@@@<,@;!    Nxt(C@@@@<,@;!    Nxt(C@@@@<,@;!    Nxt(C@@@@<,@;!    Nxt(C@@@@<,@;!    Nxt(C@@@@<,@;! C'ۛv[Nϛ7ޭ*qR  S)]  xSСCҹsgMdСQݳgtAJKKArJ9@@B'r:  5Fٳ%''4mѲ{fꘌf>wtx [o?G@@׮]e5eee2|i@wdĈUeA@S4{{@@ 蜺l2ӪW^y̹{UWɱcǤUVfiڴZMS@@2)@7l@@۷KNҲeK9efw}Wc#  @!{# xN //OOnڵw^&L 빽E@@ 07   PM_~pB߾}{ٰadg3>  @# xODVZUհM6Iqqqg   ` $xE@@#o>ӚN;ͼ2DKf  xEW@@@R^ ;SfΜi2l0@@`(>   9͛7˕W^)-[yw6m*СC3H  )4@@ Ǐwϟ/7t.r9eҮ]Ro@@h-  0aBUpwРAU]m/O=i宻'Ndl@@CΠ)  XtS***Efj: 7 oGGV @@p    8ptQvaZ6o